From 987b0145d94eecf292d8b301228356f44611ab7c Mon Sep 17 00:00:00 2001 From: Marc Fiuczynski Date: Mon, 2 Apr 2007 22:44:18 +0000 Subject: [PATCH] linux 2.6.16.38 w/ vs2.0.3-rc1 --- .gitignore | 3 - CREDITS | 47 +- Documentation/BUG-HUNTING | 113 - Documentation/COPYING.modules | 708 - Documentation/Changes | 18 + Documentation/DMA-API.txt | 49 +- Documentation/DMA-mapping.txt | 28 +- Documentation/DocBook/Makefile | 12 +- Documentation/DocBook/deviceiobook.tmpl | 19 + Documentation/DocBook/kernel-api.tmpl | 1 + Documentation/DocBook/libata.tmpl | 49 +- Documentation/DocBook/sis900.tmpl | 585 + Documentation/HOWTO | 3 +- Documentation/RCU/whatisRCU.txt | 6 +- Documentation/acpi-hotkey.txt | 2 +- Documentation/arm/Booting | 2 +- Documentation/arm/README | 2 +- Documentation/arm/SA1100/Assabet | 2 +- Documentation/arm/SA1100/LART | 2 +- .../arm/Samsung-S3C24XX/Overview.txt | 42 +- Documentation/arm/Setup | 2 +- Documentation/block/biodoc.txt | 14 +- Documentation/block/switching-sched.txt | 22 - Documentation/cachetlb.txt | 21 - Documentation/connector/connector.txt | 5 +- Documentation/cpu-freq/index.txt | 2 +- Documentation/cpu-hotplug.txt | 4 +- Documentation/cpusets.txt | 76 +- Documentation/cputopology.txt | 4 +- Documentation/devices.txt | 5 + Documentation/drivers/edac/edac.txt | 34 +- Documentation/dvb/avermedia.txt | 10 +- Documentation/dvb/bt8xx.txt | 140 +- Documentation/dvb/get_dvb_firmware | 2 +- Documentation/dvb/readme.txt | 32 +- Documentation/feature-removal-schedule.txt | 250 - Documentation/filesystems/00-INDEX | 54 +- Documentation/filesystems/9p.txt | 100 - Documentation/filesystems/isofs.txt | 4 +- Documentation/filesystems/jfs.txt | 2 +- Documentation/filesystems/ntfs.txt | 5 - Documentation/filesystems/proc.txt | 6 +- Documentation/filesystems/sysfs.txt | 5 - Documentation/filesystems/udf.txt | 14 - Documentation/filesystems/vfat.txt | 6 +- Documentation/filesystems/vfs.txt | 229 +- Documentation/firmware_class/README | 17 + .../firmware_class/firmware_sample_driver.c | 14 +- .../firmware_sample_firmware_class.c | 1 + Documentation/fujitsu/frv/kernel-ABI.txt | 192 +- Documentation/hwmon/w83627hf | 4 - Documentation/hwmon/w83781d | 24 - Documentation/i2c/busses/i2c-parport | 1 + Documentation/i2c/busses/i2c-piix4 | 2 +- Documentation/i2c/busses/i2c-viapro | 34 +- Documentation/i2c/busses/scx200_acb | 5 +- Documentation/input/joystick-parport.txt | 11 +- Documentation/ioctl-number.txt | 2 + Documentation/isdn/README.gigaset | 286 - Documentation/kbuild/makefiles.txt | 172 +- Documentation/kbuild/modules.txt | 100 +- Documentation/kernel-parameters.txt | 62 +- Documentation/laptop-mode.txt | 10 +- Documentation/leds-class.txt | 71 - Documentation/m68k/README.buddha | 2 +- Documentation/memory-barriers.txt | 2133 -- Documentation/mtrr.txt | 23 +- Documentation/networking/00-INDEX | 2 + Documentation/networking/README.ipw2100 | 229 +- Documentation/networking/README.ipw2200 | 44 +- Documentation/networking/TODO | 18 + Documentation/networking/bcm43xx.txt | 36 - Documentation/networking/e100.txt | 158 +- Documentation/networking/e1000.txt | 620 +- Documentation/networking/ifenslave.c | 2 +- Documentation/networking/ip-sysctl.txt | 49 +- Documentation/networking/netdevices.txt | 8 +- Documentation/networking/operstates.txt | 161 - Documentation/networking/packet_mmap.txt | 10 +- Documentation/networking/pktgen.txt | 20 +- Documentation/networking/ray_cs.txt | 2 +- Documentation/networking/sis900.txt | 257 + Documentation/networking/tuntap.txt | 2 +- Documentation/networking/vortex.txt | 81 +- Documentation/networking/xfrm_sync.txt | 166 - Documentation/nfsroot.txt | 17 +- Documentation/pci.txt | 12 +- Documentation/pcmcia/driver-changes.txt | 6 - Documentation/pnp.txt | 3 - Documentation/power/swsusp.txt | 51 +- Documentation/power/userland-swsusp.txt | 149 - Documentation/power/video.txt | 76 +- Documentation/powerpc/booting-without-of.txt | 77 - .../powerpc/eeh-pci-error-recovery.txt | 33 +- Documentation/robust-futex-ABI.txt | 182 - Documentation/robust-futexes.txt | 218 - Documentation/rpc-cache.txt | 121 +- Documentation/s390/driver-model.txt | 15 +- Documentation/scsi/ChangeLog.megaraid | 25 - Documentation/scsi/hptiop.txt | 92 + Documentation/scsi/scsi_eh.txt | 14 +- Documentation/scsi/scsi_mid_low_api.txt | 19 + Documentation/serial-console.txt | 11 +- Documentation/serial/driver | 31 +- Documentation/smart-config.txt | 4 + .../sound/alsa/ALSA-Configuration.txt | 236 +- Documentation/sound/alsa/Audiophile-Usb.txt | 360 - .../alsa/DocBook/writing-an-alsa-driver.tmpl | 28 +- Documentation/sound/oss/Introduction | 2 +- Documentation/sound/oss/cs46xx | 16 +- Documentation/spi/pxa2xx | 234 - Documentation/spi/spi-summary | 34 +- Documentation/spinlocks.txt | 2 +- Documentation/{video4linux => usb}/ibmcam.txt | 2 +- Documentation/{video4linux => usb}/ov511.txt | 11 +- Documentation/{video4linux => usb}/se401.txt | 0 .../{video4linux => usb}/sn9c102.txt | 27 +- Documentation/{video4linux => usb}/stv680.txt | 26 +- .../{video4linux => usb}/w9968cf.txt | 36 +- Documentation/video4linux/CARDLIST.cx88 | 2 - Documentation/video4linux/CARDLIST.em28xx | 1 - Documentation/video4linux/CARDLIST.tuner | 6 +- Documentation/video4linux/CQcam.txt | 182 +- Documentation/video4linux/README.cpia | 4 +- Documentation/video4linux/README.cpia2 | 130 - Documentation/video4linux/Zoran | 108 +- Documentation/video4linux/bttv/ICs | 4 +- Documentation/video4linux/bttv/PROBLEMS | 16 +- Documentation/video4linux/bttv/README.quirks | 4 +- Documentation/video4linux/bttv/THANKS | 4 +- Documentation/video4linux/cpia2_overview.txt | 38 - Documentation/video4linux/et61x251.txt | 314 - Documentation/video4linux/radiotrack.txt | 16 +- Documentation/video4linux/w9966.txt | 2 +- Documentation/video4linux/zc0301.txt | 254 - Documentation/video4linux/zr36120.txt | 4 +- Documentation/vm/hugetlbpage.txt | 31 +- Documentation/w1/masters/ds2482 | 31 - Documentation/watchdog/watchdog-api.txt | 3 - Documentation/x86_64/boot-options.txt | 5 - Kbuild | 2 +- MAINTAINERS | 271 +- Makefile | 230 +- README | 25 +- arch/alpha/Kconfig | 15 +- arch/alpha/kernel/alpha_ksyms.c | 4 + arch/alpha/kernel/core_marvel.c | 2 +- arch/alpha/kernel/osf_sys.c | 3 +- arch/alpha/kernel/process.c | 6 +- arch/alpha/kernel/setup.c | 32 +- arch/alpha/kernel/smp.c | 14 +- arch/alpha/kernel/sys_titan.c | 2 +- arch/alpha/kernel/systbls.S | 8 - arch/alpha/kernel/time.c | 3 +- arch/alpha/lib/ev6-memchr.S | 2 +- arch/alpha/lib/fpreg.c | 8 +- arch/alpha/mm/init.c | 2 +- arch/alpha/mm/numa.c | 4 +- arch/arm/Kconfig | 52 +- arch/arm/Kconfig-nommu | 44 - arch/arm/Kconfig.debug | 2 +- arch/arm/Makefile | 19 +- arch/arm/boot/Makefile | 5 +- arch/arm/boot/bootp/Makefile | 5 +- arch/arm/boot/compressed/Makefile | 4 + arch/arm/boot/compressed/head.S | 188 +- arch/arm/boot/compressed/ice-dcc.S | 17 + arch/arm/boot/compressed/misc.c | 41 +- arch/arm/boot/compressed/vmlinux.lds.in | 1 - arch/arm/common/Makefile | 1 - arch/arm/common/dmabounce.c | 2 +- arch/arm/common/locomo.c | 51 +- arch/arm/common/rtctime.c | 108 +- arch/arm/common/sa1111.c | 48 +- arch/arm/common/scoop.c | 65 +- arch/arm/common/sharpsl_pm.c | 10 +- arch/arm/common/uengine.c | 473 - arch/arm/common/vic.c | 49 +- arch/arm/configs/at91rm9200dk_defconfig | 2 +- arch/arm/configs/at91rm9200ek_defconfig | 2 +- arch/arm/configs/collie_defconfig | 430 +- .../{ixp23xx_defconfig => enp2611_defconfig} | 426 +- .../{ixp2000_defconfig => ixdp2400_defconfig} | 112 +- .../{ep93xx_defconfig => ixdp2401_defconfig} | 608 +- arch/arm/configs/ixdp2800_defconfig | 975 + arch/arm/configs/ixdp2801_defconfig | 976 + arch/arm/configs/s3c2410_defconfig | 147 +- arch/arm/configs/versatile_defconfig | 390 +- arch/arm/kernel/Makefile | 2 +- arch/arm/kernel/apm.c | 4 +- arch/arm/kernel/armksyms.c | 14 + arch/arm/kernel/asm-offsets.c | 8 - arch/arm/kernel/bios32.c | 4 +- arch/arm/kernel/debug.S | 1 + arch/arm/kernel/dma-isa.c | 23 +- arch/arm/kernel/ecard.c | 4 +- arch/arm/kernel/entry-armv.S | 4 +- arch/arm/kernel/entry-header.S | 18 + arch/arm/kernel/head-common.S | 217 - arch/arm/kernel/head-nommu.S | 83 - arch/arm/kernel/head.S | 217 +- arch/arm/kernel/irq.c | 11 +- arch/arm/kernel/process.c | 38 +- arch/arm/kernel/setup.c | 21 +- arch/arm/kernel/signal.h | 2 +- arch/arm/kernel/smp.c | 3 + arch/arm/kernel/sys_arm.c | 5 - arch/arm/kernel/traps.c | 11 +- arch/arm/lib/Makefile | 2 +- arch/arm/lib/backtrace.S | 6 +- arch/arm/lib/copy_template.S | 2 +- arch/arm/lib/delay.S | 20 +- arch/arm/lib/div64.S | 4 +- arch/arm/lib/io-acorn.S | 1 + arch/arm/mach-aaec2000/aaed2000.c | 7 +- arch/arm/mach-aaec2000/core.c | 5 +- arch/arm/mach-aaec2000/core.h | 1 - arch/arm/mach-at91rm9200/Makefile | 9 +- arch/arm/mach-at91rm9200/board-csb337.c | 3 - arch/arm/mach-at91rm9200/board-csb637.c | 3 - arch/arm/mach-at91rm9200/board-dk.c | 10 +- arch/arm/mach-at91rm9200/board-ek.c | 10 +- arch/arm/mach-at91rm9200/clock.c | 85 +- arch/arm/mach-at91rm9200/devices.c | 166 +- arch/arm/mach-at91rm9200/gpio.c | 4 +- arch/arm/mach-at91rm9200/leds.c | 100 - arch/arm/mach-at91rm9200/time.c | 4 +- arch/arm/mach-ep93xx/Kconfig | 21 - arch/arm/mach-ep93xx/Makefile | 10 - arch/arm/mach-ep93xx/Makefile.boot | 2 - arch/arm/mach-ep93xx/core.c | 452 - arch/arm/mach-ep93xx/gesbc9312.c | 40 - arch/arm/mach-ep93xx/ts72xx.c | 157 - arch/arm/mach-footbridge/dc21285.c | 4 +- arch/arm/mach-imx/dma.c | 511 +- arch/arm/mach-imx/generic.c | 63 +- arch/arm/mach-imx/irq.c | 2 +- arch/arm/mach-imx/mx1ads.c | 94 +- arch/arm/mach-integrator/core.c | 46 - arch/arm/mach-integrator/impd1.c | 7 +- arch/arm/mach-integrator/integrator_ap.c | 4 +- arch/arm/mach-integrator/integrator_cp.c | 5 +- arch/arm/mach-integrator/time.c | 16 +- arch/arm/mach-iop3xx/iop331-setup.c | 4 +- arch/arm/mach-iop3xx/iq31244-pci.c | 4 +- arch/arm/mach-iop3xx/iq80321-pci.c | 4 +- arch/arm/mach-iop3xx/iq80331-pci.c | 4 +- arch/arm/mach-iop3xx/iq80332-pci.c | 2 + arch/arm/mach-ixp2000/Kconfig | 9 +- arch/arm/mach-ixp2000/Makefile | 2 +- arch/arm/mach-ixp2000/core.c | 13 +- arch/arm/mach-ixp2000/ixdp2x01.c | 98 +- arch/arm/mach-ixp23xx/Kconfig | 25 - arch/arm/mach-ixp23xx/Makefile | 11 - arch/arm/mach-ixp23xx/Makefile.boot | 2 - arch/arm/mach-ixp23xx/core.c | 443 - arch/arm/mach-ixp23xx/espresso.c | 78 - arch/arm/mach-ixp23xx/ixdp2351.c | 325 - arch/arm/mach-ixp23xx/pci.c | 291 - arch/arm/mach-ixp23xx/roadrunner.c | 164 - arch/arm/mach-ixp4xx/Kconfig | 17 +- arch/arm/mach-ixp4xx/Makefile | 3 +- arch/arm/mach-ixp4xx/common-pci.c | 3 +- arch/arm/mach-ixp4xx/common.c | 5 +- arch/arm/mach-lh7a40x/common.h | 1 - arch/arm/mach-lh7a40x/irq-kev7a400.c | 1 - arch/arm/mach-lh7a40x/irq-lh7a400.c | 2 +- arch/arm/mach-lh7a40x/irq-lh7a404.c | 3 +- arch/arm/mach-lh7a40x/irq-lpd7a40x.c | 1 - arch/arm/mach-omap1/Kconfig | 20 +- arch/arm/mach-omap1/Makefile | 11 +- arch/arm/mach-omap1/board-ams-delta.c | 116 - arch/arm/mach-omap1/board-generic.c | 2 +- arch/arm/mach-omap1/board-h2.c | 200 +- arch/arm/mach-omap1/board-h3.c | 277 +- arch/arm/mach-omap1/board-innovator.c | 56 +- arch/arm/mach-omap1/board-nokia770.c | 268 - arch/arm/mach-omap1/board-osk.c | 95 +- arch/arm/mach-omap1/board-palmte.c | 12 +- arch/arm/mach-omap1/board-perseus2.c | 123 +- arch/arm/mach-omap1/board-voiceblue.c | 6 +- arch/arm/mach-omap1/clock.c | 9 +- arch/arm/mach-omap1/clock.h | 91 +- arch/arm/mach-omap1/devices.c | 45 +- arch/arm/mach-omap1/io.c | 4 +- arch/arm/mach-omap1/irq.c | 18 +- arch/arm/mach-omap1/mux.c | 30 +- arch/arm/mach-omap1/pm.c | 770 - arch/arm/mach-omap1/serial.c | 6 +- arch/arm/mach-omap1/sleep.S | 525 - arch/arm/mach-omap1/time.c | 197 + arch/arm/mach-omap2/Kconfig | 3 - arch/arm/mach-omap2/Makefile | 6 +- arch/arm/mach-omap2/board-apollon.c | 285 - arch/arm/mach-omap2/board-h4.c | 174 +- arch/arm/mach-omap2/clock.c | 79 +- arch/arm/mach-omap2/clock.h | 37 +- arch/arm/mach-omap2/devices.c | 46 +- arch/arm/mach-omap2/io.c | 21 +- arch/arm/mach-omap2/memory.c | 102 - arch/arm/mach-omap2/memory.h | 34 - arch/arm/mach-omap2/mux.c | 45 - arch/arm/mach-omap2/pm.c | 149 - arch/arm/mach-omap2/prcm-regs.h | 483 - arch/arm/mach-omap2/prcm.c | 40 - arch/arm/mach-omap2/serial.c | 2 +- arch/arm/mach-omap2/sleep.S | 144 - arch/arm/mach-omap2/sram-fn.S | 4 +- arch/arm/mach-pxa/Kconfig | 5 - arch/arm/mach-pxa/Makefile | 3 +- arch/arm/mach-pxa/clock.c | 124 - arch/arm/mach-pxa/corgi.c | 12 +- arch/arm/mach-pxa/corgi_ssp.c | 9 +- arch/arm/mach-pxa/dma.c | 17 +- arch/arm/mach-pxa/generic.c | 6 - arch/arm/mach-pxa/leds-mainstone.c | 6 +- arch/arm/mach-pxa/lpd270.c | 393 - arch/arm/mach-pxa/mainstone.c | 10 +- arch/arm/mach-pxa/poodle.c | 5 +- arch/arm/mach-pxa/spitz.c | 15 +- arch/arm/mach-pxa/tosa.c | 10 +- arch/arm/mach-realview/core.c | 28 +- arch/arm/mach-realview/realview_eb.c | 5 +- arch/arm/mach-s3c2410/Kconfig | 16 +- arch/arm/mach-s3c2410/Makefile | 3 - arch/arm/mach-s3c2410/clock.c | 182 +- arch/arm/mach-s3c2410/clock.h | 8 - arch/arm/mach-s3c2410/common-smdk.c | 135 - arch/arm/mach-s3c2410/common-smdk.h | 15 - arch/arm/mach-s3c2410/cpu.c | 2 +- arch/arm/mach-s3c2410/mach-anubis.c | 4 +- arch/arm/mach-s3c2410/mach-osiris.c | 294 - arch/arm/mach-s3c2410/mach-rx3715.c | 35 - arch/arm/mach-s3c2410/mach-smdk2410.c | 13 +- arch/arm/mach-s3c2410/mach-smdk2440.c | 17 +- arch/arm/mach-s3c2410/s3c2440-clock.c | 89 +- arch/arm/mach-s3c2410/sleep.S | 6 +- arch/arm/mach-s3c2410/time.c | 8 +- arch/arm/mach-sa1100/Kconfig | 2 +- arch/arm/mach-sa1100/Makefile | 2 +- arch/arm/mach-sa1100/assabet.c | 1 - arch/arm/mach-sa1100/clock.c | 132 - arch/arm/mach-sa1100/collie.c | 102 +- arch/arm/mach-sa1100/collie_pm.c | 278 - arch/arm/mach-sa1100/cpu-sa1100.c | 2 +- arch/arm/mach-sa1100/generic.c | 6 - arch/arm/mach-sa1100/irq.c | 16 - arch/arm/mach-sa1100/neponset.c | 8 - arch/arm/mach-versatile/core.c | 5 +- arch/arm/mm/Kconfig | 29 +- arch/arm/mm/Makefile | 2 - arch/arm/mm/cache-v4wb.S | 26 +- arch/arm/mm/consistent.c | 21 +- arch/arm/mm/copypage-xsc3.S | 97 - arch/arm/mm/init.c | 10 +- arch/arm/mm/ioremap.c | 5 +- arch/arm/mm/mm-armv.c | 18 +- arch/arm/mm/proc-arm1020.S | 2 +- arch/arm/mm/proc-arm1020e.S | 2 +- arch/arm/mm/proc-arm1022.S | 1 - arch/arm/mm/proc-arm1026.S | 1 - arch/arm/mm/proc-arm6_7.S | 1 - arch/arm/mm/proc-arm720.S | 2 +- arch/arm/mm/proc-arm920.S | 2 +- arch/arm/mm/proc-arm922.S | 2 +- arch/arm/mm/proc-arm925.S | 2 +- arch/arm/mm/proc-arm926.S | 2 +- arch/arm/mm/proc-sa110.S | 26 +- arch/arm/mm/proc-sa1100.S | 38 +- arch/arm/mm/proc-v6.S | 17 +- arch/arm/mm/proc-xsc3.S | 500 - arch/arm/mm/proc-xscale.S | 2 +- arch/arm/oprofile/common.c | 34 +- arch/arm/oprofile/op_counter.h | 2 +- arch/arm/plat-omap/Kconfig | 4 +- arch/arm/plat-omap/Makefile | 6 +- arch/arm/plat-omap/clock.c | 68 +- arch/arm/plat-omap/devices.c | 159 +- arch/arm/plat-omap/dma.c | 6 - arch/arm/plat-omap/dmtimer.c | 26 - arch/arm/plat-omap/fb.c | 80 - arch/arm/plat-omap/gpio.c | 86 +- arch/arm/plat-omap/mcbsp.c | 345 +- arch/arm/plat-omap/ocpi.c | 3 + arch/arm/plat-omap/pm.c | 1 - arch/arm/plat-omap/sram.c | 143 +- arch/arm/plat-omap/timer32k.c | 325 - arch/arm/tools/mach-types | 89 +- arch/arm/vfp/entry.S | 2 +- arch/arm/vfp/vfpdouble.c | 31 +- arch/arm/vfp/vfphw.S | 10 +- arch/arm/vfp/vfpmodule.c | 4 +- arch/arm/vfp/vfpsingle.c | 11 +- arch/arm26/Kconfig | 4 - arch/arm26/Makefile | 7 +- arch/arm26/boot/Makefile | 5 +- arch/arm26/kernel/armksyms.c | 3 + arch/arm26/kernel/traps.c | 12 +- arch/arm26/mm/init.c | 9 +- arch/cris/Kconfig | 8 - arch/cris/arch-v32/drivers/cryptocop.c | 2 +- arch/cris/kernel/crisksyms.c | 1 + arch/cris/kernel/irq.c | 10 +- arch/cris/kernel/process.c | 3 +- arch/cris/kernel/setup.c | 5 +- arch/cris/mm/init.c | 2 +- arch/frv/Kconfig | 4 - arch/frv/kernel/entry.S | 26 +- arch/frv/kernel/frv_ksyms.c | 2 + arch/frv/kernel/gdb-stub.c | 2 +- arch/frv/kernel/irq.c | 10 +- arch/frv/mm/dma-alloc.c | 4 +- arch/frv/mm/init.c | 6 +- arch/frv/mm/mmu-context.c | 6 +- arch/h8300/Kconfig | 8 - arch/h8300/kernel/h8300_ksyms.c | 2 + arch/h8300/kernel/process.c | 4 +- arch/h8300/mm/init.c | 4 +- arch/i386/Kconfig | 246 +- arch/i386/Kconfig.cpu | 7 +- arch/i386/Kconfig.debug | 23 +- arch/i386/Makefile | 40 +- arch/i386/Makefile.cpu | 6 +- arch/i386/boot-xen/Makefile | 21 - arch/i386/boot/Makefile | 36 +- arch/i386/boot/compressed/misc.c | 6 +- arch/i386/boot/edd.S | 2 - arch/i386/boot/video.S | 25 +- arch/i386/defconfig | 119 +- arch/i386/kernel/Makefile | 26 +- arch/i386/kernel/acpi/Makefile | 4 - arch/i386/kernel/acpi/boot-xen.c | 1168 - arch/i386/kernel/acpi/boot.c | 14 +- arch/i386/kernel/acpi/earlyquirk.c | 23 +- arch/i386/kernel/alternative.c | 327 - arch/i386/kernel/apic-xen.c | 160 - arch/i386/kernel/apic.c | 58 +- arch/i386/kernel/apm.c | 2 + arch/i386/kernel/asm-offsets.c | 10 +- arch/i386/kernel/cpu/Makefile | 5 - arch/i386/kernel/cpu/amd.c | 2 + arch/i386/kernel/cpu/centaur.c | 1 - arch/i386/kernel/cpu/common-xen.c | 732 - arch/i386/kernel/cpu/common.c | 64 +- arch/i386/kernel/cpu/cpufreq/Kconfig | 23 +- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 1 - .../i386/kernel/cpu/cpufreq/cpufreq-nforce2.c | 64 +- arch/i386/kernel/cpu/cpufreq/elanfreq.c | 109 +- arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | 183 +- arch/i386/kernel/cpu/cpufreq/longhaul.h | 4 +- arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 24 +- arch/i386/kernel/cpu/cpufreq/powernow-k6.c | 16 +- arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 10 +- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 71 +- arch/i386/kernel/cpu/cpufreq/powernow-k8.h | 8 +- .../kernel/cpu/cpufreq/speedstep-centrino.c | 4 +- arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | 42 +- arch/i386/kernel/cpu/cpufreq/speedstep-lib.h | 20 +- arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | 49 +- arch/i386/kernel/cpu/intel.c | 12 +- arch/i386/kernel/cpu/intel_cacheinfo.c | 85 +- arch/i386/kernel/cpu/mcheck/mce.c | 4 +- arch/i386/kernel/cpu/mtrr/Makefile | 7 - arch/i386/kernel/cpu/mtrr/main-xen.c | 197 - arch/i386/kernel/cpu/mtrr/main.c | 13 +- arch/i386/kernel/cpu/proc.c | 4 +- arch/i386/kernel/cpuid.c | 2 +- arch/i386/kernel/crash.c | 4 +- .../firmware => arch/i386/kernel}/dmi_scan.c | 133 +- arch/i386/kernel/early_printk-xen.c | 2 - arch/i386/kernel/efi.c | 27 +- arch/i386/kernel/entry-xen.S | 907 - arch/i386/kernel/entry.S | 24 +- arch/i386/kernel/fixup.c | 86 - arch/i386/kernel/head-xen.S | 181 - arch/i386/kernel/head.S | 5 +- arch/i386/kernel/i386_ksyms.c | 1 + arch/i386/kernel/init_task-xen.c | 51 - arch/i386/kernel/io_apic-xen.c | 2751 -- arch/i386/kernel/io_apic.c | 32 +- arch/i386/kernel/ioport-xen.c | 121 - arch/i386/kernel/irq-xen.c | 306 - arch/i386/kernel/irq.c | 4 +- arch/i386/kernel/kprobes.c | 292 +- arch/i386/kernel/ldt-xen.c | 270 - arch/i386/kernel/microcode-xen.c | 148 - arch/i386/kernel/microcode.c | 28 +- arch/i386/kernel/module.c | 36 +- arch/i386/kernel/mpparse-xen.c | 1186 - arch/i386/kernel/mpparse.c | 62 +- arch/i386/kernel/msr.c | 2 +- arch/i386/kernel/nmi.c | 11 +- arch/i386/kernel/pci-dma-xen.c | 344 - arch/i386/kernel/process-xen.c | 870 - arch/i386/kernel/process.c | 70 +- arch/i386/kernel/ptrace.c | 11 +- arch/i386/kernel/quirks-xen.c | 48 - arch/i386/kernel/reboot_fixups.c | 5 +- arch/i386/kernel/semaphore.c | 8 +- arch/i386/kernel/setup-xen.c | 1827 -- arch/i386/kernel/setup.c | 212 +- arch/i386/kernel/signal.c | 11 +- arch/i386/kernel/smp-xen.c | 617 - arch/i386/kernel/smp.c | 29 +- arch/i386/kernel/smpboot.c | 64 +- arch/i386/kernel/swiotlb.c | 672 - arch/i386/kernel/sys_i386.c | 25 +- arch/i386/kernel/syscall_table.S | 16 +- arch/i386/kernel/sysenter.c | 111 +- arch/i386/kernel/time-xen.c | 1116 - arch/i386/kernel/timers/timer_hpet.c | 2 +- arch/i386/kernel/timers/timer_pm.c | 104 +- arch/i386/kernel/timers/timer_tsc.c | 6 +- arch/i386/kernel/topology.c | 9 - arch/i386/kernel/traps-xen.c | 1222 - arch/i386/kernel/traps.c | 213 +- arch/i386/kernel/vm86.c | 14 +- arch/i386/kernel/vmlinux.lds.S | 23 +- arch/i386/kernel/vsyscall-note-xen.S | 32 - arch/i386/kernel/vsyscall-sigreturn.S | 2 +- arch/i386/kernel/vsyscall-sysenter.S | 9 +- arch/i386/kernel/vsyscall.lds.S | 4 +- arch/i386/mach-es7000/es7000.h | 5 +- arch/i386/mach-es7000/es7000plat.c | 54 +- arch/i386/mach-generic/probe.c | 16 +- arch/i386/mach-visws/reboot.c | 1 + arch/i386/mach-voyager/voyager_cat.c | 11 +- arch/i386/mach-voyager/voyager_smp.c | 2 +- arch/i386/mach-xen/Makefile | 5 - arch/i386/mach-xen/setup.c | 49 - arch/i386/mm/Makefile | 8 - arch/i386/mm/discontig.c | 12 +- arch/i386/mm/fault-xen.c | 734 - arch/i386/mm/fault.c | 210 +- arch/i386/mm/highmem-xen.c | 133 - arch/i386/mm/hugetlbpage.c | 12 + arch/i386/mm/hypervisor.c | 458 - arch/i386/mm/init-xen.c | 865 - arch/i386/mm/init.c | 76 +- arch/i386/mm/ioremap-xen.c | 478 - arch/i386/mm/mmap.c | 6 +- arch/i386/mm/pageattr.c | 22 +- arch/i386/mm/pgtable-xen.c | 701 - arch/i386/mm/pgtable.c | 14 +- arch/i386/oprofile/Makefile | 4 - arch/i386/oprofile/nmi_int.c | 14 +- arch/i386/oprofile/xenoprof.c | 554 - arch/i386/pci/Makefile | 11 +- arch/i386/pci/common.c | 32 - arch/i386/pci/direct.c | 28 +- arch/i386/pci/init.c | 25 - arch/i386/pci/irq-xen.c | 1204 - arch/i386/pci/irq.c | 12 +- arch/i386/pci/mmconfig.c | 81 +- arch/i386/pci/pcbios.c | 4 +- arch/i386/pci/pci.h | 3 - arch/i386/pci/pcifront.c | 55 - arch/i386/power/Makefile | 4 +- arch/i386/power/cpu.c | 2 +- arch/ia64/Kconfig | 39 - arch/ia64/Makefile | 5 +- arch/ia64/configs/gensparse_defconfig | 1 - arch/ia64/configs/sn2_defconfig | 77 +- arch/ia64/configs/tiger_defconfig | 2 - arch/ia64/defconfig | 1 - arch/ia64/dig/setup.c | 5 + arch/ia64/hp/sim/simserial.c | 7 +- arch/ia64/ia32/binfmt_elf32.c | 5 +- arch/ia64/ia32/ia32_entry.S | 2 +- arch/ia64/ia32/ia32priv.h | 4 +- arch/ia64/ia32/sys_ia32.c | 89 +- arch/ia64/kernel/acpi-ext.c | 143 +- arch/ia64/kernel/acpi.c | 55 +- arch/ia64/kernel/efi.c | 62 +- arch/ia64/kernel/entry.S | 28 +- arch/ia64/kernel/gate.lds.S | 1 - arch/ia64/kernel/ia64_ksyms.c | 8 - arch/ia64/kernel/iosapic.c | 275 +- arch/ia64/kernel/irq.c | 14 +- arch/ia64/kernel/ivt.S | 1 - arch/ia64/kernel/kprobes.c | 61 +- arch/ia64/kernel/machvec.c | 19 +- arch/ia64/kernel/mca.c | 238 +- arch/ia64/kernel/mca_asm.S | 10 +- arch/ia64/kernel/mca_drv.c | 76 +- arch/ia64/kernel/mca_drv.h | 7 - arch/ia64/kernel/mca_drv_asm.S | 13 +- arch/ia64/kernel/module.c | 2 +- arch/ia64/kernel/numa.c | 2 +- arch/ia64/kernel/palinfo.c | 10 +- arch/ia64/kernel/patch.c | 8 +- arch/ia64/kernel/perfmon.c | 9 +- arch/ia64/kernel/process.c | 8 + arch/ia64/kernel/ptrace.c | 12 +- arch/ia64/kernel/salinfo.c | 2 +- arch/ia64/kernel/setup.c | 71 +- arch/ia64/kernel/signal.c | 102 + arch/ia64/kernel/smpboot.c | 221 +- arch/ia64/kernel/sys_ia64.c | 2 +- arch/ia64/kernel/time.c | 11 +- arch/ia64/kernel/topology.c | 366 +- arch/ia64/kernel/traps.c | 6 +- arch/ia64/kernel/vmlinux.lds.S | 54 +- arch/ia64/lib/Makefile | 2 +- arch/ia64/lib/bitop.c | 88 + arch/ia64/lib/memcpy_mck.S | 9 +- arch/ia64/mm/Makefile | 2 +- arch/ia64/mm/contig.c | 12 +- arch/ia64/mm/discontig.c | 110 +- arch/ia64/mm/fault.c | 3 - arch/ia64/mm/hugetlbpage.c | 12 +- arch/ia64/mm/init.c | 39 +- arch/ia64/mm/ioremap.c | 43 - arch/ia64/mm/tlb.c | 12 +- arch/ia64/pci/pci.c | 3 +- arch/ia64/sn/kernel/Makefile | 3 +- arch/ia64/sn/kernel/bte.c | 11 +- arch/ia64/sn/kernel/io_init.c | 29 - arch/ia64/sn/kernel/irq.c | 21 +- arch/ia64/sn/kernel/pio_phys.S | 71 - arch/ia64/sn/kernel/setup.c | 11 +- arch/ia64/sn/kernel/sn2/sn2_smp.c | 21 - arch/ia64/sn/kernel/sn2/sn_hwperf.c | 16 +- arch/ia64/sn/kernel/sn2/sn_proc_fs.c | 39 +- arch/ia64/sn/kernel/tiocx.c | 148 +- arch/ia64/sn/kernel/xpc_channel.c | 104 +- arch/ia64/sn/kernel/xpc_main.c | 1 + arch/ia64/sn/kernel/xpc_partition.c | 36 +- arch/ia64/sn/pci/pcibr/pcibr_ate.c | 45 +- arch/ia64/sn/pci/pcibr/pcibr_dma.c | 2 +- arch/ia64/sn/pci/pcibr/pcibr_provider.c | 17 - arch/ia64/sn/pci/tioca_provider.c | 2 +- arch/ia64/sn/pci/tioce_provider.c | 326 +- arch/m32r/Kconfig | 13 - arch/m32r/Kconfig.debug | 2 +- arch/m32r/Makefile | 5 +- arch/m32r/kernel/entry.S | 55 +- arch/m32r/kernel/irq.c | 10 +- arch/m32r/kernel/m32r_ksyms.c | 25 + arch/m32r/kernel/process.c | 4 - arch/m32r/kernel/setup.c | 1 - arch/m32r/kernel/signal.c | 4 - arch/m32r/mm/discontig.c | 7 +- arch/m32r/mm/init.c | 7 +- arch/m68k/Kconfig | 4 - arch/m68k/bvme6000/config.c | 2 +- arch/m68k/bvme6000/rtc.c | 4 +- arch/m68k/kernel/m68k_ksyms.c | 2 + arch/m68k/kernel/process.c | 2 +- arch/m68k/mm/init.c | 2 +- arch/m68k/mm/memory.c | 2 +- arch/m68k/mm/motorola.c | 2 +- arch/m68k/mvme16x/rtc.c | 4 +- arch/m68knommu/Kconfig | 8 - arch/m68knommu/kernel/m68k_ksyms.c | 2 + arch/m68knommu/kernel/process.c | 2 +- arch/m68knommu/kernel/vmlinux.lds.S | 10 - arch/m68knommu/mm/init.c | 4 +- arch/mips/Kconfig | 192 +- arch/mips/Kconfig.debug | 8 +- arch/mips/Makefile | 234 +- arch/mips/arc/memory.c | 2 +- arch/mips/au1000/common/Makefile | 2 +- arch/mips/au1000/common/cputable.c | 3 +- arch/mips/au1000/common/dbdma.c | 4 +- arch/mips/au1000/common/dma.c | 2 +- arch/mips/au1000/common/int-handler.S | 68 + arch/mips/au1000/common/irq.c | 21 +- arch/mips/au1000/common/platform.c | 8 +- arch/mips/au1000/common/prom.c | 24 +- arch/mips/au1000/common/setup.c | 4 +- arch/mips/au1000/common/sleeper.S | 5 - arch/mips/au1000/common/time.c | 3 +- arch/mips/cobalt/Kconfig | 7 - arch/mips/cobalt/Makefile | 4 +- arch/mips/cobalt/console.c | 43 - arch/mips/cobalt/int-handler.S | 25 + arch/mips/cobalt/irq.c | 6 +- arch/mips/cobalt/setup.c | 13 +- arch/mips/configs/atlas_defconfig | 164 +- arch/mips/configs/bigsur_defconfig | 83 +- arch/mips/configs/capcella_defconfig | 149 +- arch/mips/configs/cobalt_defconfig | 130 +- arch/mips/configs/db1000_defconfig | 108 +- arch/mips/configs/db1100_defconfig | 109 +- arch/mips/configs/db1200_defconfig | 105 +- arch/mips/configs/db1500_defconfig | 188 +- arch/mips/configs/db1550_defconfig | 113 +- arch/mips/configs/ddb5476_defconfig | 88 +- arch/mips/configs/ddb5477_defconfig | 85 +- arch/mips/configs/decstation_defconfig | 88 +- arch/mips/configs/e55_defconfig | 288 +- arch/mips/configs/ev64120_defconfig | 85 +- arch/mips/configs/ev96100_defconfig | 80 +- arch/mips/configs/ip22_defconfig | 139 +- arch/mips/configs/ip27_defconfig | 96 +- arch/mips/configs/ip32_defconfig | 95 +- arch/mips/configs/it8172_defconfig | 84 +- arch/mips/configs/ivr_defconfig | 85 +- arch/mips/configs/jaguar-atx_defconfig | 76 +- arch/mips/configs/jmr3927_defconfig | 91 +- arch/mips/configs/lasat200_defconfig | 88 +- arch/mips/configs/malta_defconfig | 161 +- arch/mips/configs/mipssim_defconfig | 77 +- arch/mips/configs/mpc30x_defconfig | 110 +- arch/mips/configs/ocelot_3_defconfig | 120 +- arch/mips/configs/ocelot_c_defconfig | 83 +- arch/mips/configs/ocelot_defconfig | 80 +- arch/mips/configs/ocelot_g_defconfig | 83 +- arch/mips/configs/pb1100_defconfig | 108 +- arch/mips/configs/pb1500_defconfig | 113 +- arch/mips/configs/pb1550_defconfig | 113 +- arch/mips/configs/pnx8550-jbs_defconfig | 108 +- arch/mips/configs/pnx8550-v2pci_defconfig | 137 +- arch/mips/configs/qemu_defconfig | 62 +- arch/mips/configs/rbhma4500_defconfig | 137 +- arch/mips/configs/rm200_defconfig | 204 +- arch/mips/configs/sb1250-swarm_defconfig | 82 +- arch/mips/configs/sead_defconfig | 68 +- arch/mips/configs/tb0226_defconfig | 234 +- arch/mips/configs/tb0229_defconfig | 288 +- arch/mips/configs/tb0287_defconfig | 283 +- arch/mips/configs/workpad_defconfig | 189 +- arch/mips/configs/yosemite_defconfig | 77 +- arch/mips/ddb5xxx/common/rtc_ds1386.c | 4 +- arch/mips/ddb5xxx/ddb5074/Makefile | 2 +- arch/mips/ddb5xxx/ddb5074/int-handler.S | 120 + arch/mips/ddb5xxx/ddb5074/irq.c | 26 +- arch/mips/ddb5xxx/ddb5476/Makefile | 2 +- arch/mips/ddb5xxx/ddb5476/dbg_io.c | 2 +- arch/mips/ddb5xxx/ddb5476/int-handler.S | 112 + arch/mips/ddb5xxx/ddb5476/irq.c | 30 +- arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c | 6 +- arch/mips/ddb5xxx/ddb5477/Makefile | 2 +- arch/mips/ddb5xxx/ddb5477/int-handler.S | 75 + arch/mips/ddb5xxx/ddb5477/irq.c | 24 +- arch/mips/ddb5xxx/ddb5477/kgdb_io.c | 2 +- arch/mips/dec/boot/decstation.c | 3 +- arch/mips/dec/int-handler.S | 14 +- arch/mips/dec/prom/memory.c | 4 +- arch/mips/dec/setup.c | 3 + arch/mips/dec/time.c | 51 +- arch/mips/defconfig | 139 +- arch/mips/galileo-boards/ev96100/Makefile | 2 +- .../mips/galileo-boards/ev96100/int-handler.S | 33 + arch/mips/galileo-boards/ev96100/irq.c | 19 +- arch/mips/gt64120/ev64120/Makefile | 2 +- arch/mips/gt64120/ev64120/int-handler.S | 113 + arch/mips/gt64120/ev64120/irq.c | 27 +- arch/mips/gt64120/ev64120/serialGT.c | 2 +- arch/mips/gt64120/momenco_ocelot/Makefile | 2 +- arch/mips/gt64120/momenco_ocelot/dbg_io.c | 2 +- .../mips/gt64120/momenco_ocelot/int-handler.S | 131 + arch/mips/gt64120/momenco_ocelot/irq.c | 36 +- arch/mips/ite-boards/generic/Makefile | 2 +- arch/mips/ite-boards/generic/dbg_io.c | 2 +- arch/mips/ite-boards/generic/int-handler.S | 63 + arch/mips/ite-boards/generic/irq.c | 18 +- arch/mips/ite-boards/generic/time.c | 5 +- arch/mips/ite-boards/ivr/init.c | 5 +- arch/mips/ite-boards/qed-4n-s01b/init.c | 5 +- arch/mips/jazz/Makefile | 2 +- arch/mips/jazz/int-handler.S | 282 + arch/mips/jazz/irq.c | 78 +- arch/mips/jmr3927/common/rtc_ds1742.c | 64 +- arch/mips/jmr3927/rbhma3100/Makefile | 2 +- arch/mips/jmr3927/rbhma3100/int-handler.S | 74 + arch/mips/jmr3927/rbhma3100/irq.c | 6 +- arch/mips/kernel/Makefile | 7 +- arch/mips/kernel/asm-offsets.c | 7 +- arch/mips/kernel/cpu-bugs64.c | 8 +- arch/mips/kernel/cpu-probe.c | 21 +- arch/mips/kernel/entry.S | 69 +- arch/mips/kernel/gdb-low.S | 34 +- arch/mips/kernel/gdb-stub.c | 61 +- arch/mips/kernel/genex.S | 43 - arch/mips/kernel/head.S | 57 - arch/mips/kernel/i8253.c | 28 - arch/mips/kernel/i8259.c | 4 - arch/mips/kernel/irixsig.c | 4 +- arch/mips/kernel/irq-msc01.c | 9 - arch/mips/kernel/irq.c | 28 +- arch/mips/kernel/kspd.c | 398 - arch/mips/kernel/linux32.c | 322 +- arch/mips/kernel/mips-mt.c | 450 - arch/mips/kernel/mips_ksyms.c | 16 + arch/mips/kernel/module.c | 336 + arch/mips/kernel/proc.c | 3 - arch/mips/kernel/process.c | 38 +- arch/mips/kernel/ptrace.c | 18 +- arch/mips/kernel/ptrace32.c | 14 - arch/mips/kernel/r4k_switch.S | 34 +- arch/mips/kernel/rtlx.c | 518 +- arch/mips/kernel/scall32-o32.S | 13 - arch/mips/kernel/scall64-64.S | 2 - arch/mips/kernel/scall64-n32.S | 4 +- arch/mips/kernel/scall64-o32.S | 6 +- arch/mips/kernel/setup.c | 43 +- arch/mips/kernel/signal-common.h | 40 +- arch/mips/kernel/signal.c | 6 +- arch/mips/kernel/signal32.c | 46 +- arch/mips/kernel/signal_n32.c | 5 +- arch/mips/kernel/smp-mt.c | 360 - arch/mips/kernel/smp.c | 21 +- arch/mips/kernel/smtc-asm.S | 130 - arch/mips/kernel/smtc-proc.c | 93 - arch/mips/kernel/smtc.c | 1322 - arch/mips/kernel/syscall.c | 34 +- arch/mips/kernel/sysirix.c | 22 +- arch/mips/kernel/time.c | 25 +- arch/mips/kernel/traps.c | 234 +- arch/mips/kernel/vmlinux.lds.S | 22 +- arch/mips/kernel/vpe.c | 665 +- arch/mips/lasat/Makefile | 2 +- arch/mips/lasat/image/romscript.normal | 5 +- arch/mips/lasat/interrupt.c | 14 +- arch/mips/lasat/lasatIRQ.S | 69 + arch/mips/lasat/setup.c | 7 +- arch/mips/lasat/sysctl.c | 63 +- arch/mips/math-emu/dp_fint.c | 4 +- arch/mips/math-emu/dp_flong.c | 4 +- arch/mips/math-emu/sp_fint.c | 4 +- arch/mips/math-emu/sp_flong.c | 4 +- arch/mips/mips-boards/atlas/atlas_int.c | 92 +- arch/mips/mips-boards/atlas/atlas_setup.c | 2 +- arch/mips/mips-boards/generic/Makefile | 4 +- arch/mips/mips-boards/generic/gdb_hook.c | 2 +- arch/mips/mips-boards/generic/init.c | 2 +- arch/mips/mips-boards/generic/memory.c | 12 +- arch/mips/mips-boards/generic/mipsIRQ.S | 155 + arch/mips/mips-boards/generic/pci.c | 1 - arch/mips/mips-boards/generic/time.c | 68 +- arch/mips/mips-boards/malta/Makefile | 1 - arch/mips/mips-boards/malta/malta_int.c | 105 +- arch/mips/mips-boards/malta/malta_setup.c | 2 +- arch/mips/mips-boards/malta/malta_smp.c | 128 - arch/mips/mips-boards/sead/sead_int.c | 86 +- arch/mips/mips-boards/sim/sim_IRQ.c | 2 +- arch/mips/mips-boards/sim/sim_cmdline.c | 6 +- arch/mips/mips-boards/sim/sim_int.c | 64 +- arch/mips/mips-boards/sim/sim_irq.S | 6 +- arch/mips/mips-boards/sim/sim_mem.c | 10 +- arch/mips/mips-boards/sim/sim_smp.c | 16 +- arch/mips/mm/Makefile | 2 +- arch/mips/mm/c-r3k.c | 23 +- arch/mips/mm/c-r4k.c | 96 +- arch/mips/mm/c-sb1.c | 1 - arch/mips/mm/c-tx39.c | 7 - arch/mips/mm/cache.c | 1 - arch/mips/mm/dma-ip32.c | 4 +- arch/mips/mm/fault.c | 13 +- arch/mips/mm/highmem.c | 2 - arch/mips/mm/init.c | 61 +- arch/mips/mm/pg-r4k.c | 11 +- arch/mips/mm/sc-rm7k.c | 25 +- arch/mips/mm/tlb-andes.c | 259 + arch/mips/mm/tlb-r4k.c | 90 +- arch/mips/mm/tlbex.c | 102 +- arch/mips/momentum/jaguar_atx/Makefile | 2 +- arch/mips/momentum/jaguar_atx/dbg_io.c | 2 +- arch/mips/momentum/jaguar_atx/int-handler.S | 128 + arch/mips/momentum/jaguar_atx/irq.c | 35 +- arch/mips/momentum/jaguar_atx/reset.c | 2 +- arch/mips/momentum/jaguar_atx/setup.c | 42 +- arch/mips/momentum/ocelot_3/Makefile | 2 +- arch/mips/momentum/ocelot_3/int-handler.S | 137 + arch/mips/momentum/ocelot_3/irq.c | 38 +- arch/mips/momentum/ocelot_3/reset.c | 2 +- arch/mips/momentum/ocelot_3/setup.c | 62 +- arch/mips/momentum/ocelot_c/Makefile | 2 +- arch/mips/momentum/ocelot_c/dbg_io.c | 2 +- arch/mips/momentum/ocelot_c/int-handler.S | 102 + arch/mips/momentum/ocelot_c/irq.c | 30 +- arch/mips/momentum/ocelot_c/reset.c | 2 +- arch/mips/momentum/ocelot_c/setup.c | 4 +- arch/mips/momentum/ocelot_g/Makefile | 2 +- arch/mips/momentum/ocelot_g/dbg_io.c | 2 +- arch/mips/momentum/ocelot_g/int-handler.S | 131 + arch/mips/momentum/ocelot_g/irq.c | 38 +- arch/mips/oprofile/common.c | 14 +- arch/mips/oprofile/op_model_mipsxx.c | 34 +- arch/mips/oprofile/op_model_rm9000.c | 3 +- arch/mips/pci/fixup-vr4133.c | 2 +- arch/mips/pci/ops-ddb5477.c | 4 +- arch/mips/pci/ops-tx4938.c | 16 +- arch/mips/pci/pci-bcm1480.c | 2 +- arch/mips/pci/pci-bcm1480ht.c | 2 +- arch/mips/pci/pci-ip27.c | 12 +- arch/mips/philips/pnx8550/common/Makefile | 2 +- arch/mips/philips/pnx8550/common/int.c | 25 +- arch/mips/philips/pnx8550/common/platform.c | 1 - arch/mips/pmc-sierra/yosemite/Makefile | 2 +- arch/mips/pmc-sierra/yosemite/irq-handler.S | 93 + arch/mips/pmc-sierra/yosemite/irq.c | 33 +- arch/mips/pmc-sierra/yosemite/setup.c | 4 +- arch/mips/qemu/Makefile | 4 +- arch/mips/qemu/q-irq.c | 3 +- arch/mips/qemu/q-smp.c | 48 - arch/mips/sgi-ip22/Makefile | 2 +- arch/mips/sgi-ip22/ip22-int.c | 59 +- arch/mips/sgi-ip22/ip22-irq.S | 118 + arch/mips/sgi-ip22/ip22-reset.c | 2 +- arch/mips/sgi-ip22/ip22-time.c | 4 +- arch/mips/sgi-ip27/Makefile | 2 +- arch/mips/sgi-ip27/TODO | 4 + arch/mips/sgi-ip27/ip27-irq-glue.S | 45 + arch/mips/sgi-ip27/ip27-irq.c | 32 +- arch/mips/sgi-ip27/ip27-memory.c | 9 +- arch/mips/sgi-ip27/ip27-timer.c | 2 +- arch/mips/sgi-ip32/Makefile | 2 +- arch/mips/sgi-ip32/ip32-irq-glue.S | 86 + arch/mips/sgi-ip32/ip32-irq.c | 44 +- arch/mips/sgi-ip32/ip32-reset.c | 2 +- arch/mips/sgi-ip32/ip32-setup.c | 6 +- arch/mips/sibyte/bcm1480/Makefile | 2 +- arch/mips/sibyte/bcm1480/irq.c | 77 +- arch/mips/sibyte/sb1250/Makefile | 2 +- arch/mips/sibyte/sb1250/irq.c | 78 +- arch/mips/sibyte/sb1250/irq_handler.S | 147 + arch/mips/sibyte/swarm/setup.c | 8 +- arch/mips/sni/Makefile | 2 +- arch/mips/sni/int-handler.S | 106 + arch/mips/sni/irq.c | 37 +- arch/mips/sni/setup.c | 4 +- arch/mips/tx4927/common/Makefile | 2 +- arch/mips/tx4927/common/tx4927_irq.c | 30 +- arch/mips/tx4927/common/tx4927_irq_handler.S | 103 + .../toshiba_rbtx4927/toshiba_rbtx4927_prom.c | 4 +- .../toshiba_rbtx4927/toshiba_rbtx4927_setup.c | 4 +- arch/mips/tx4938/common/Makefile | 2 +- arch/mips/tx4938/common/irq.c | 21 +- arch/mips/tx4938/common/rtc_rx5c348.c | 16 +- arch/mips/tx4938/toshiba_rbtx4938/setup.c | 2 +- arch/mips/vr41xx/Kconfig | 13 - arch/mips/vr41xx/common/Makefile | 2 +- arch/mips/vr41xx/common/bcu.c | 6 +- arch/mips/vr41xx/common/int-handler.S | 114 + arch/mips/vr41xx/common/irq.c | 29 +- arch/parisc/Kconfig | 50 +- arch/parisc/configs/712_defconfig | 160 +- arch/parisc/configs/a500_defconfig | 4 +- arch/parisc/configs/b180_defconfig | 12 +- arch/parisc/configs/c3000_defconfig | 252 +- arch/parisc/defconfig | 641 +- arch/parisc/kernel/asm-offsets.c | 3 - arch/parisc/kernel/cache.c | 10 +- arch/parisc/kernel/entry.S | 75 +- arch/parisc/kernel/firmware.c | 7 +- arch/parisc/kernel/head.S | 15 +- arch/parisc/kernel/init_task.c | 10 +- arch/parisc/kernel/pacache.S | 29 +- arch/parisc/kernel/parisc_ksyms.c | 20 + arch/parisc/kernel/pdc_chassis.c | 8 +- arch/parisc/kernel/perf.c | 2 +- arch/parisc/kernel/process.c | 5 + arch/parisc/kernel/smp.c | 25 +- arch/parisc/kernel/sys_parisc.c | 8 - arch/parisc/kernel/sys_parisc32.c | 58 + arch/parisc/kernel/syscall.S | 10 +- arch/parisc/kernel/syscall_table.S | 12 +- arch/parisc/kernel/vmlinux.lds.S | 54 +- arch/parisc/mm/fault.c | 2 +- arch/parisc/mm/init.c | 39 +- arch/parisc/mm/ioremap.c | 57 +- arch/powerpc/Kconfig | 78 +- arch/powerpc/Kconfig.debug | 5 + arch/powerpc/Makefile | 15 +- arch/powerpc/boot/install.sh | 2 + arch/powerpc/boot/main.c | 7 +- arch/powerpc/configs/cell_defconfig | 171 +- arch/powerpc/configs/g5_defconfig | 58 +- arch/powerpc/configs/iseries_defconfig | 43 +- arch/powerpc/configs/mpc8540_ads_defconfig | 728 - arch/powerpc/configs/pseries_defconfig | 54 +- arch/powerpc/kernel/Makefile | 13 +- arch/powerpc/kernel/asm-offsets.c | 6 +- arch/powerpc/kernel/cputable.c | 28 +- arch/powerpc/kernel/crash.c | 13 - arch/powerpc/kernel/crash_dump.c | 4 +- arch/powerpc/kernel/entry_32.S | 35 +- arch/powerpc/kernel/entry_64.S | 17 +- arch/powerpc/kernel/firmware.c | 29 +- arch/powerpc/kernel/head_44x.S | 2 + arch/powerpc/kernel/head_64.S | 92 +- arch/powerpc/kernel/head_8xx.S | 2 + arch/powerpc/kernel/head_booke.h | 363 - arch/powerpc/kernel/head_fsl_booke.S | 6 +- arch/powerpc/kernel/idle.c | 122 - arch/powerpc/kernel/idle_6xx.S | 81 +- arch/powerpc/kernel/idle_power4.S | 48 +- arch/powerpc/kernel/iomap.c | 2 + arch/powerpc/kernel/iommu.c | 37 +- arch/powerpc/kernel/irq.c | 75 +- arch/powerpc/kernel/kprobes.c | 99 +- arch/powerpc/kernel/legacy_serial.c | 42 +- arch/powerpc/kernel/lparcfg.c | 35 +- arch/powerpc/kernel/module_64.c | 16 +- arch/powerpc/kernel/nvram_64.c | 7 +- arch/powerpc/kernel/of_device.c | 5 +- arch/powerpc/kernel/paca.c | 21 +- arch/powerpc/kernel/pci_32.c | 4 +- arch/powerpc/kernel/pci_iommu.c | 41 +- arch/powerpc/kernel/ppc_ksyms.c | 2 +- arch/powerpc/kernel/proc_ppc64.c | 3 +- arch/powerpc/kernel/process.c | 23 +- arch/powerpc/kernel/prom.c | 228 +- arch/powerpc/kernel/prom_init.c | 237 +- arch/powerpc/kernel/ptrace-common.h | 2 + arch/powerpc/kernel/ptrace.c | 5 +- arch/powerpc/kernel/rtas-proc.c | 7 +- arch/powerpc/kernel/rtas.c | 20 +- arch/powerpc/kernel/rtas_pci.c | 2 + arch/powerpc/kernel/setup-common.c | 107 +- arch/powerpc/kernel/setup_32.c | 76 +- arch/powerpc/kernel/setup_64.c | 91 +- arch/powerpc/kernel/signal_32.c | 1 - arch/powerpc/kernel/signal_64.c | 3 +- arch/powerpc/kernel/smp.c | 6 +- arch/powerpc/kernel/sys_ppc32.c | 73 + arch/powerpc/kernel/syscalls.c | 1 - arch/powerpc/kernel/sysfs.c | 34 +- arch/powerpc/kernel/systbl.S | 23 - arch/powerpc/kernel/time.c | 243 +- arch/powerpc/kernel/traps.c | 78 +- arch/powerpc/kernel/vdso.c | 14 +- arch/powerpc/kernel/vdso32/sigtramp.S | 2 +- arch/powerpc/kernel/vdso64/sigtramp.S | 2 +- arch/powerpc/kernel/vio.c | 6 +- arch/powerpc/kernel/vmlinux.lds.S | 381 +- arch/powerpc/lib/copypage_64.S | 2 + arch/powerpc/lib/copyuser_64.S | 2 + arch/powerpc/lib/e2a.c | 14 +- arch/powerpc/lib/memcpy_64.S | 13 +- arch/powerpc/lib/rheap.c | 2 + arch/powerpc/lib/sstep.c | 2 +- arch/powerpc/lib/strcase.c | 4 +- arch/powerpc/mm/fault.c | 38 +- arch/powerpc/mm/hash_low_32.S | 2 + arch/powerpc/mm/hash_native_64.c | 4 +- arch/powerpc/mm/hash_utils_64.c | 39 +- arch/powerpc/mm/hugetlbpage.c | 310 +- arch/powerpc/mm/imalloc.c | 18 +- arch/powerpc/mm/init_32.c | 4 +- arch/powerpc/mm/init_64.c | 59 +- arch/powerpc/mm/lmb.c | 16 - arch/powerpc/mm/mem.c | 29 +- arch/powerpc/mm/mmap.c | 2 + arch/powerpc/mm/numa.c | 182 +- arch/powerpc/mm/pgtable_32.c | 6 +- arch/powerpc/mm/slb_low.S | 2 + arch/powerpc/mm/stab.c | 6 +- arch/powerpc/mm/tlb_64.c | 2 +- arch/powerpc/oprofile/Makefile | 2 +- arch/powerpc/oprofile/backtrace.c | 126 - arch/powerpc/oprofile/common.c | 9 +- arch/powerpc/oprofile/op_model_7450.c | 4 +- arch/powerpc/oprofile/op_model_fsl_booke.c | 4 +- arch/powerpc/oprofile/op_model_power4.c | 46 +- arch/powerpc/oprofile/op_model_rs64.c | 5 +- arch/powerpc/platforms/83xx/Makefile | 4 +- arch/powerpc/platforms/83xx/misc.c | 55 - arch/powerpc/platforms/83xx/mpc834x_sys.c | 125 +- arch/powerpc/platforms/83xx/mpc834x_sys.h | 2 +- arch/powerpc/platforms/83xx/mpc83xx.h | 5 +- arch/powerpc/platforms/83xx/pci.c | 21 +- arch/powerpc/platforms/85xx/Kconfig | 75 +- arch/powerpc/platforms/85xx/Makefile | 6 +- arch/powerpc/platforms/85xx/misc.c | 31 - arch/powerpc/platforms/85xx/mpc8540_ads.h | 36 - arch/powerpc/platforms/85xx/mpc85xx.h | 18 - arch/powerpc/platforms/85xx/mpc85xx_ads.c | 244 - arch/powerpc/platforms/85xx/pci.c | 96 - arch/powerpc/platforms/Makefile | 2 +- arch/powerpc/platforms/cell/Kconfig | 6 - arch/powerpc/platforms/cell/Makefile | 10 +- arch/powerpc/platforms/cell/interrupt.c | 133 +- arch/powerpc/platforms/cell/interrupt.h | 2 +- arch/powerpc/platforms/cell/iommu.c | 16 +- arch/powerpc/platforms/cell/pervasive.c | 4 +- arch/powerpc/platforms/cell/setup.c | 92 +- arch/powerpc/platforms/cell/spider-pic.c | 108 +- arch/powerpc/platforms/cell/spu_base.c | 138 +- arch/powerpc/platforms/cell/spu_callbacks.c | 362 - .../platforms/cell/spufs/backing_ops.c | 47 - arch/powerpc/platforms/cell/spufs/context.c | 24 +- arch/powerpc/platforms/cell/spufs/file.c | 523 +- arch/powerpc/platforms/cell/spufs/hw_ops.c | 57 - arch/powerpc/platforms/cell/spufs/inode.c | 8 +- arch/powerpc/platforms/cell/spufs/run.c | 92 - arch/powerpc/platforms/cell/spufs/sched.c | 2 - arch/powerpc/platforms/cell/spufs/spufs.h | 28 +- arch/powerpc/platforms/cell/spufs/switch.c | 5 +- arch/powerpc/platforms/chrp/chrp.h | 3 +- arch/powerpc/platforms/chrp/pci.c | 6 +- arch/powerpc/platforms/chrp/pegasos_eth.c | 2 + arch/powerpc/platforms/chrp/setup.c | 123 +- arch/powerpc/platforms/chrp/time.c | 24 +- arch/powerpc/platforms/iseries/mf.c | 112 +- arch/powerpc/platforms/iseries/setup.c | 86 +- arch/powerpc/platforms/maple/setup.c | 10 +- arch/powerpc/platforms/maple/time.c | 26 +- arch/powerpc/platforms/powermac/bootx_init.c | 6 +- arch/powerpc/platforms/powermac/cpufreq_32.c | 2 + arch/powerpc/platforms/powermac/cpufreq_64.c | 7 +- arch/powerpc/platforms/powermac/feature.c | 4 +- arch/powerpc/platforms/powermac/low_i2c.c | 93 +- arch/powerpc/platforms/powermac/nvram.c | 16 +- arch/powerpc/platforms/powermac/pci.c | 7 +- arch/powerpc/platforms/powermac/pfunc_base.c | 2 - arch/powerpc/platforms/powermac/pfunc_core.c | 18 +- arch/powerpc/platforms/powermac/setup.c | 82 +- arch/powerpc/platforms/powermac/smp.c | 4 +- arch/powerpc/platforms/powermac/time.c | 4 +- arch/powerpc/platforms/powermac/udbg_scc.c | 2 +- arch/powerpc/platforms/pseries/Makefile | 3 +- arch/powerpc/platforms/pseries/eeh.c | 70 +- arch/powerpc/platforms/pseries/eeh_driver.c | 29 +- arch/powerpc/platforms/pseries/eeh_event.c | 38 +- arch/powerpc/platforms/pseries/firmware.c | 103 - arch/powerpc/platforms/pseries/firmware.h | 17 - arch/powerpc/platforms/pseries/hvCall.S | 102 +- arch/powerpc/platforms/pseries/hvconsole.c | 11 +- arch/powerpc/platforms/pseries/hvcserver.c | 22 +- arch/powerpc/platforms/pseries/iommu.c | 4 +- arch/powerpc/platforms/pseries/lpar.c | 31 +- arch/powerpc/platforms/pseries/pci.c | 4 +- arch/powerpc/platforms/pseries/pci_dlpar.c | 11 +- arch/powerpc/platforms/pseries/ras.c | 2 +- arch/powerpc/platforms/pseries/reconfig.c | 15 +- arch/powerpc/platforms/pseries/rtasd.c | 5 +- arch/powerpc/platforms/pseries/setup.c | 302 +- arch/powerpc/platforms/pseries/smp.c | 2 +- arch/powerpc/platforms/pseries/vio.c | 4 +- arch/powerpc/platforms/pseries/xics.c | 40 +- arch/powerpc/sysdev/dart_iommu.c | 14 +- arch/powerpc/sysdev/dcr.S | 2 + arch/powerpc/sysdev/fsl_soc.c | 292 +- arch/powerpc/sysdev/ipic.h | 2 + arch/powerpc/xmon/xmon.c | 30 - arch/ppc/4xx_io/serial_sicc.c | 5 +- arch/ppc/8xx_io/commproc.c | 6 +- arch/ppc/8xx_io/cs4218_tdm.c | 10 +- arch/ppc/Kconfig | 144 +- arch/ppc/Kconfig.debug | 9 +- arch/ppc/Makefile | 8 +- arch/ppc/amiga/amiints.c | 2 +- arch/ppc/amiga/bootinfo.c | 2 + arch/ppc/amiga/cia.c | 2 + arch/ppc/amiga/config.c | 2 + arch/ppc/amiga/ints.c | 2 + arch/ppc/boot/Makefile | 12 +- arch/ppc/boot/common/Makefile | 3 + arch/ppc/boot/common/bootinfo.c | 2 + arch/ppc/boot/common/misc-common.c | 2 + arch/ppc/boot/common/ns16550.c | 3 - arch/ppc/boot/common/serial_stub.c | 2 + arch/ppc/boot/common/util.S | 2 + arch/ppc/boot/include/mpc10x.h | 2 + arch/ppc/boot/lib/Makefile | 2 +- arch/ppc/boot/openfirmware/Makefile | 106 + arch/ppc/boot/openfirmware/chrpmain.c | 101 + arch/ppc/boot/openfirmware/common.c | 146 + arch/ppc/boot/openfirmware/dummy.c | 4 + arch/ppc/boot/openfirmware/misc.S | 67 + arch/ppc/boot/openfirmware/start.c | 172 + arch/ppc/boot/simple/Makefile | 1 - arch/ppc/boot/simple/cpc700_memory.c | 2 + arch/ppc/boot/simple/embed_config.c | 7 +- arch/ppc/boot/simple/head.S | 9 +- arch/ppc/boot/simple/misc-chestnut.c | 2 + arch/ppc/boot/simple/misc-cpci690.c | 42 +- arch/ppc/boot/simple/misc-ev64260.c | 2 + arch/ppc/boot/simple/misc-ev64360.c | 1 + arch/ppc/boot/simple/misc-katana.c | 2 + arch/ppc/boot/simple/misc-mv64x60.c | 2 + arch/ppc/boot/simple/misc-prep.c | 2 + arch/ppc/boot/simple/misc-spruce.c | 2 + arch/ppc/boot/simple/misc.c | 2 + arch/ppc/boot/simple/mpc10x_memory.c | 6 +- arch/ppc/boot/simple/mpc52xx_tty.c | 2 + arch/ppc/boot/simple/mv64x60_tty.c | 2 + arch/ppc/boot/simple/openbios.c | 2 + arch/ppc/boot/simple/relocate.S | 4 +- arch/ppc/boot/utils/addnote.c | 175 + arch/ppc/boot/utils/hack-coff.c | 84 + arch/ppc/boot/utils/mkbugboot.c | 2 + arch/ppc/boot/utils/mknote.c | 44 + .../{prep_defconfig => common_defconfig} | 0 arch/ppc/configs/ibmchrp_defconfig | 875 + arch/ppc/configs/ml300_defconfig | 739 - arch/ppc/configs/ml403_defconfig | 740 - arch/ppc/configs/pmac_defconfig | 1591 ++ arch/ppc/configs/power3_defconfig | 1035 + arch/ppc/kernel/Makefile | 28 +- arch/ppc/kernel/asm-offsets.c | 1 - arch/{powerpc => ppc}/kernel/cpu_setup_6xx.S | 0 arch/ppc/kernel/dma-mapping.c | 4 +- arch/ppc/kernel/entry.S | 87 +- arch/ppc/kernel/head.S | 183 +- arch/ppc/kernel/head_44x.S | 2 + arch/ppc/kernel/head_8xx.S | 6 + arch/ppc/kernel/head_fsl_booke.S | 6 +- arch/ppc/kernel/idle.c | 112 + arch/ppc/kernel/idle_6xx.S | 233 + arch/ppc/kernel/idle_power4.S | 91 + .../kernel/l2cr_6xx.S => ppc/kernel/l2cr.S} | 0 .../module_32.c => ppc/kernel/module.c} | 0 arch/ppc/kernel/pci.c | 396 + .../kernel/perfmon_fsl_booke.c | 0 arch/ppc/kernel/ppc_htab.c | 10 +- arch/ppc/kernel/ppc_ksyms.c | 27 +- arch/ppc/kernel/setup.c | 264 +- arch/ppc/kernel/smp-tbsync.c | 3 +- arch/ppc/kernel/smp.c | 2 +- .../swsusp_32.S => ppc/kernel/swsusp.S} | 0 .../kernel/tau_6xx.c => ppc/kernel/temp.c} | 0 arch/ppc/kernel/traps.c | 20 +- arch/ppc/lib/strcase.c | 3 +- arch/{powerpc => ppc}/math-emu/Makefile | 0 arch/{powerpc => ppc}/math-emu/double.h | 0 arch/{powerpc => ppc}/math-emu/fabs.c | 0 arch/{powerpc => ppc}/math-emu/fadd.c | 0 arch/{powerpc => ppc}/math-emu/fadds.c | 0 arch/{powerpc => ppc}/math-emu/fcmpo.c | 0 arch/{powerpc => ppc}/math-emu/fcmpu.c | 0 arch/{powerpc => ppc}/math-emu/fctiw.c | 0 arch/{powerpc => ppc}/math-emu/fctiwz.c | 0 arch/{powerpc => ppc}/math-emu/fdiv.c | 0 arch/{powerpc => ppc}/math-emu/fdivs.c | 0 arch/{powerpc => ppc}/math-emu/fmadd.c | 0 arch/{powerpc => ppc}/math-emu/fmadds.c | 0 arch/{powerpc => ppc}/math-emu/fmr.c | 0 arch/{powerpc => ppc}/math-emu/fmsub.c | 0 arch/{powerpc => ppc}/math-emu/fmsubs.c | 0 arch/{powerpc => ppc}/math-emu/fmul.c | 0 arch/{powerpc => ppc}/math-emu/fmuls.c | 0 arch/{powerpc => ppc}/math-emu/fnabs.c | 0 arch/{powerpc => ppc}/math-emu/fneg.c | 0 arch/{powerpc => ppc}/math-emu/fnmadd.c | 0 arch/{powerpc => ppc}/math-emu/fnmadds.c | 0 arch/{powerpc => ppc}/math-emu/fnmsub.c | 0 arch/{powerpc => ppc}/math-emu/fnmsubs.c | 0 arch/{powerpc => ppc}/math-emu/fres.c | 0 arch/{powerpc => ppc}/math-emu/frsp.c | 0 arch/{powerpc => ppc}/math-emu/frsqrte.c | 0 arch/{powerpc => ppc}/math-emu/fsel.c | 0 arch/{powerpc => ppc}/math-emu/fsqrt.c | 0 arch/{powerpc => ppc}/math-emu/fsqrts.c | 0 arch/{powerpc => ppc}/math-emu/fsub.c | 0 arch/{powerpc => ppc}/math-emu/fsubs.c | 0 arch/{powerpc => ppc}/math-emu/lfd.c | 0 arch/{powerpc => ppc}/math-emu/lfs.c | 0 arch/{powerpc => ppc}/math-emu/math.c | 2 + arch/{powerpc => ppc}/math-emu/mcrfs.c | 0 arch/{powerpc => ppc}/math-emu/mffs.c | 0 arch/{powerpc => ppc}/math-emu/mtfsb0.c | 0 arch/{powerpc => ppc}/math-emu/mtfsb1.c | 0 arch/{powerpc => ppc}/math-emu/mtfsf.c | 0 arch/{powerpc => ppc}/math-emu/mtfsfi.c | 0 arch/{powerpc => ppc}/math-emu/op-1.h | 0 arch/{powerpc => ppc}/math-emu/op-2.h | 0 arch/{powerpc => ppc}/math-emu/op-4.h | 0 arch/{powerpc => ppc}/math-emu/op-common.h | 0 arch/{powerpc => ppc}/math-emu/sfp-machine.h | 0 arch/{powerpc => ppc}/math-emu/single.h | 0 arch/{powerpc => ppc}/math-emu/soft-fp.h | 0 arch/{powerpc => ppc}/math-emu/stfd.c | 0 arch/{powerpc => ppc}/math-emu/stfiwx.c | 0 arch/{powerpc => ppc}/math-emu/stfs.c | 0 arch/{powerpc => ppc}/math-emu/types.c | 0 arch/{powerpc => ppc}/math-emu/udivmodti4.c | 0 arch/ppc/mm/44x_mmu.c | 4 +- arch/ppc/mm/fault.c | 32 +- arch/ppc/mm/hashtable.S | 36 + arch/ppc/mm/init.c | 19 +- arch/ppc/mm/mmu_context.c | 2 +- arch/ppc/mm/pgtable.c | 8 +- arch/ppc/mm/ppc_mmu.c | 28 +- arch/ppc/platforms/4xx/Kconfig | 23 +- arch/ppc/platforms/4xx/Makefile | 4 +- arch/ppc/platforms/4xx/bamboo.c | 2 + arch/ppc/platforms/4xx/bamboo.h | 2 + arch/ppc/platforms/4xx/bubinga.h | 2 + arch/ppc/platforms/4xx/cpci405.c | 2 + arch/ppc/platforms/4xx/ebony.c | 2 + arch/ppc/platforms/4xx/ebony.h | 2 + arch/ppc/platforms/4xx/ep405.c | 2 + arch/ppc/platforms/4xx/ep405.h | 2 + arch/ppc/platforms/4xx/ibm405ep.c | 2 + arch/ppc/platforms/4xx/ibm405ep.h | 2 + arch/ppc/platforms/4xx/ibm405gp.h | 2 + arch/ppc/platforms/4xx/ibm405gpr.c | 2 + arch/ppc/platforms/4xx/ibm405gpr.h | 2 + arch/ppc/platforms/4xx/ibm440ep.c | 2 + arch/ppc/platforms/4xx/ibm440ep.h | 2 + arch/ppc/platforms/4xx/ibm440gp.c | 2 + arch/ppc/platforms/4xx/ibm440gp.h | 2 + arch/ppc/platforms/4xx/ibm440gx.c | 2 + arch/ppc/platforms/4xx/ibm440gx.h | 2 + arch/ppc/platforms/4xx/ibm440sp.c | 6 +- arch/ppc/platforms/4xx/ibm440sp.h | 2 + arch/ppc/platforms/4xx/ibmnp405h.c | 2 + arch/ppc/platforms/4xx/ibmnp405h.h | 2 + arch/ppc/platforms/4xx/ibmstb4.c | 2 + arch/ppc/platforms/4xx/ibmstb4.h | 2 + arch/ppc/platforms/4xx/ibmstbx25.c | 2 + arch/ppc/platforms/4xx/ibmstbx25.h | 2 + arch/ppc/platforms/4xx/luan.c | 2 + arch/ppc/platforms/4xx/luan.h | 2 + arch/ppc/platforms/4xx/ocotea.c | 4 +- arch/ppc/platforms/4xx/ocotea.h | 2 + arch/ppc/platforms/4xx/ppc440spe.c | 2 + arch/ppc/platforms/4xx/ppc440spe.h | 2 + arch/ppc/platforms/4xx/redwood5.c | 2 + arch/ppc/platforms/4xx/redwood5.h | 2 + arch/ppc/platforms/4xx/redwood6.c | 2 + arch/ppc/platforms/4xx/redwood6.h | 2 + arch/ppc/platforms/4xx/sycamore.c | 2 + arch/ppc/platforms/4xx/sycamore.h | 2 + arch/ppc/platforms/4xx/virtex-ii_pro.c | 60 + arch/ppc/platforms/4xx/virtex-ii_pro.h | 99 + arch/ppc/platforms/4xx/virtex.c | 56 - arch/ppc/platforms/4xx/virtex.h | 35 - arch/ppc/platforms/4xx/walnut.c | 2 + arch/ppc/platforms/4xx/walnut.h | 2 + arch/ppc/platforms/4xx/xilinx_ml300.c | 76 +- arch/ppc/platforms/4xx/xilinx_ml300.h | 6 +- arch/ppc/platforms/4xx/xilinx_ml403.c | 177 - arch/ppc/platforms/4xx/xilinx_ml403.h | 49 - .../platforms/4xx/xparameters/xparameters.h | 37 - .../4xx/xparameters/xparameters_ml403.h | 243 - arch/ppc/platforms/4xx/yucca.c | 2 + arch/ppc/platforms/4xx/yucca.h | 2 + arch/ppc/platforms/83xx/mpc834x_sys.c | 2 + arch/ppc/platforms/83xx/mpc834x_sys.h | 4 +- arch/ppc/platforms/85xx/mpc8540_ads.c | 2 + arch/ppc/platforms/85xx/mpc8540_ads.h | 2 + arch/ppc/platforms/85xx/mpc8555_cds.h | 2 + arch/ppc/platforms/85xx/mpc8560_ads.c | 2 + arch/ppc/platforms/85xx/mpc8560_ads.h | 2 + arch/ppc/platforms/85xx/mpc85xx_ads_common.c | 2 + arch/ppc/platforms/85xx/mpc85xx_ads_common.h | 2 + arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 2 + arch/ppc/platforms/85xx/mpc85xx_cds_common.h | 2 + arch/ppc/platforms/85xx/sbc8560.c | 2 + arch/ppc/platforms/85xx/sbc8560.h | 2 + arch/ppc/platforms/85xx/sbc85xx.c | 2 + arch/ppc/platforms/85xx/sbc85xx.h | 2 + arch/ppc/platforms/85xx/stx_gp3.c | 2 + arch/ppc/platforms/85xx/stx_gp3.h | 2 + arch/ppc/platforms/85xx/tqm85xx.c | 2 + arch/ppc/platforms/85xx/tqm85xx.h | 2 + arch/ppc/platforms/Makefile | 15 +- arch/ppc/platforms/apus_setup.c | 2 + arch/ppc/platforms/chestnut.c | 2 + arch/ppc/platforms/chrp_pci.c | 309 + arch/ppc/platforms/chrp_pegasos_eth.c | 213 + arch/ppc/platforms/chrp_setup.c | 671 + arch/ppc/platforms/chrp_smp.c | 99 + arch/ppc/platforms/chrp_time.c | 253 + arch/ppc/platforms/cpci690.c | 4 +- arch/ppc/platforms/cpci690.h | 2 - arch/ppc/platforms/ev64260.c | 4 +- arch/ppc/platforms/ev64260.h | 2 + arch/ppc/platforms/ev64360.c | 4 +- arch/ppc/platforms/ev64360.h | 2 + arch/ppc/platforms/fads.h | 2 +- arch/ppc/platforms/gemini.h | 3 + arch/ppc/platforms/gemini_prom.S | 2 + arch/ppc/platforms/gemini_setup.c | 2 + arch/ppc/platforms/hdpu.c | 10 +- arch/ppc/platforms/katana.c | 7 +- arch/ppc/platforms/katana.h | 16 +- arch/ppc/platforms/lite5200.c | 73 +- arch/ppc/platforms/lopec.c | 2 + arch/ppc/platforms/mpc8272ads_setup.c | 350 - arch/ppc/platforms/mpc866ads_setup.c | 413 - arch/ppc/platforms/mpc885ads_setup.c | 520 - arch/ppc/platforms/mvme5100.c | 2 + arch/ppc/platforms/pal4.h | 2 + arch/ppc/platforms/pal4_pci.c | 2 + arch/ppc/platforms/pal4_serial.h | 2 + arch/ppc/platforms/pal4_setup.c | 2 + arch/ppc/platforms/powerpmc250.c | 2 + arch/ppc/platforms/pplus.c | 2 + arch/ppc/platforms/pplus.h | 2 + arch/ppc/platforms/pq2ads.c | 33 +- arch/ppc/platforms/pq2ads.h | 4 - arch/ppc/platforms/pq2ads_pd.h | 114 - arch/ppc/platforms/prep_setup.c | 16 +- arch/ppc/platforms/prpmc750.c | 2 + arch/ppc/platforms/prpmc800.c | 2 + arch/ppc/platforms/radstone_ppc7d.c | 7 +- arch/ppc/platforms/sandpoint.c | 2 + arch/ppc/platforms/sandpoint.h | 2 + arch/ppc/platforms/sbc82xx.c | 2 + arch/ppc/platforms/spruce.c | 2 + arch/ppc/platforms/tqm8260_setup.c | 2 + arch/ppc/syslib/Makefile | 6 +- arch/ppc/syslib/cpc700.h | 2 + arch/ppc/syslib/cpc700_pic.c | 2 + arch/ppc/syslib/cpc710.h | 2 + arch/ppc/syslib/gen550.h | 2 + arch/ppc/syslib/gen550_dbg.c | 2 + arch/ppc/syslib/gen550_kgdb.c | 2 + arch/ppc/syslib/gt64260_pic.c | 2 + arch/ppc/syslib/harrier.c | 2 + arch/ppc/syslib/hawk_common.c | 2 + arch/ppc/syslib/ibm440gp_common.c | 2 + arch/ppc/syslib/ibm440gp_common.h | 2 + arch/ppc/syslib/ibm440gx_common.c | 15 +- arch/ppc/syslib/ibm440gx_common.h | 6 +- arch/ppc/syslib/ibm440sp_common.c | 2 + arch/ppc/syslib/ibm44x_common.c | 2 + arch/ppc/syslib/ibm44x_common.h | 7 +- arch/ppc/syslib/m8260_pci_erratum9.c | 2 + arch/ppc/syslib/m8260_setup.c | 2 + arch/ppc/syslib/m8xx_setup.c | 65 +- arch/ppc/syslib/m8xx_wdt.c | 3 +- arch/ppc/syslib/mpc10x_common.c | 2 + arch/ppc/syslib/mpc52xx_devices.c | 1 + arch/ppc/syslib/mpc52xx_pci.c | 5 +- arch/ppc/syslib/mpc52xx_pic.c | 2 + arch/ppc/syslib/mpc52xx_setup.c | 50 +- arch/ppc/syslib/mpc83xx_devices.c | 2 + arch/ppc/syslib/mpc83xx_sys.c | 54 +- arch/ppc/syslib/mpc85xx_devices.c | 2 + arch/ppc/syslib/mpc85xx_sys.c | 135 +- arch/ppc/syslib/mpc8xx_devices.c | 27 +- arch/ppc/syslib/mpc8xx_sys.c | 2 + arch/ppc/syslib/mv64360_pic.c | 2 + arch/ppc/syslib/mv64x60.c | 2 + arch/ppc/syslib/mv64x60_dbg.c | 2 + arch/ppc/syslib/mv64x60_win.c | 1 - arch/ppc/syslib/ocp.c | 3 +- arch/ppc/syslib/open_pic.c | 4 +- arch/ppc/syslib/open_pic2.c | 2 + arch/ppc/syslib/open_pic_defs.h | 2 + arch/ppc/syslib/pci_auto.c | 2 + arch/ppc/syslib/ppc4xx_dma.c | 2 + arch/ppc/syslib/ppc4xx_pic.c | 2 + arch/ppc/syslib/ppc4xx_pm.c | 47 + arch/ppc/syslib/ppc4xx_sgdma.c | 2 + arch/ppc/syslib/ppc83xx_setup.c | 2 + arch/ppc/syslib/ppc83xx_setup.h | 2 + arch/ppc/syslib/ppc85xx_common.c | 2 + arch/ppc/syslib/ppc85xx_common.h | 2 + arch/ppc/syslib/ppc85xx_setup.c | 4 +- arch/ppc/syslib/ppc85xx_setup.h | 2 + arch/ppc/syslib/ppc_sys.c | 58 +- arch/ppc/syslib/pq2_devices.c | 18 +- arch/ppc/syslib/pq2_sys.c | 18 +- arch/ppc/syslib/prep_nvram.c | 2 + arch/ppc/syslib/prom.c | 1429 ++ arch/ppc/syslib/prom_init.c | 1011 + arch/ppc/syslib/todc_time.c | 2 + arch/ppc/syslib/xilinx_pic.c | 4 +- arch/ppc/xmon/start.c | 2 +- arch/s390/Kconfig | 6 - arch/s390/Makefile | 1 + arch/s390/appldata/appldata_base.c | 5 +- arch/s390/crypto/crypt_s390_query.c | 2 +- arch/s390/defconfig | 48 +- arch/s390/kernel/compat_linux.c | 74 + arch/s390/kernel/compat_signal.c | 2 +- arch/s390/kernel/compat_wrapper.S | 58 +- arch/s390/kernel/debug.c | 11 +- arch/s390/kernel/process.c | 13 +- arch/s390/kernel/ptrace.c | 5 +- arch/s390/kernel/setup.c | 108 +- arch/s390/kernel/signal.c | 5 +- arch/s390/kernel/smp.c | 12 +- arch/s390/kernel/syscalls.S | 8 +- arch/s390/kernel/time.c | 9 +- arch/s390/kernel/vmlinux.lds.S | 4 +- arch/s390/lib/uaccess.S | 12 +- arch/s390/lib/uaccess64.S | 12 +- arch/s390/mm/cmm.c | 6 +- arch/s390/mm/extmem.c | 19 +- arch/s390/mm/init.c | 9 +- arch/sh/Kconfig | 13 - arch/sh/Makefile | 2 +- arch/sh/boards/mpc1211/rtc.c | 50 +- arch/sh/boards/sh03/rtc.c | 13 +- arch/sh/kernel/cpu/init.c | 2 +- arch/sh/kernel/cpu/rtc.c | 10 +- arch/sh/kernel/irq.c | 5 +- arch/sh/kernel/process.c | 1 + arch/sh/kernel/setup.c | 10 +- arch/sh/kernel/sh_ksyms.c | 1 + arch/sh/mm/consistent.c | 3 +- arch/sh/mm/hugetlbpage.c | 12 + arch/sh/mm/init.c | 4 +- arch/sh64/Kconfig | 12 +- arch/sh64/kernel/irq.c | 5 +- arch/sh64/kernel/setup.c | 1 - arch/sh64/kernel/sh_ksyms.c | 1 + arch/sh64/kernel/time.c | 9 +- arch/sh64/mm/hugetlbpage.c | 12 + arch/sparc/Kconfig | 9 +- arch/sparc/kernel/ioport.c | 45 +- arch/sparc/kernel/irq.c | 71 +- arch/sparc/kernel/module.c | 1 - arch/sparc/kernel/smp.c | 119 +- arch/sparc/kernel/sparc_ksyms.c | 18 + arch/sparc/kernel/sun4d_irq.c | 10 +- arch/sparc/kernel/sun4d_smp.c | 22 +- arch/sparc/kernel/sun4m_smp.c | 189 +- arch/sparc/kernel/systbls.S | 11 +- arch/sparc/math-emu/Makefile | 2 +- arch/sparc/mm/generic.c | 1 + arch/sparc/mm/init.c | 6 +- arch/sparc/mm/loadmmu.c | 2 + arch/sparc/mm/srmmu.c | 15 +- arch/sparc/mm/sun4c.c | 15 +- arch/sparc64/Kconfig | 33 +- arch/sparc64/Kconfig.debug | 2 +- arch/sparc64/defconfig | 89 +- arch/sparc64/kernel/Makefile | 8 +- arch/sparc64/kernel/binfmt_aout32.c | 14 +- arch/sparc64/kernel/binfmt_elf32.c | 4 +- arch/sparc64/kernel/cpu.c | 7 - arch/sparc64/kernel/devices.c | 189 +- arch/sparc64/kernel/dtlb_backend.S | 170 + arch/sparc64/kernel/dtlb_base.S | 109 + arch/sparc64/kernel/dtlb_miss.S | 39 - arch/sparc64/kernel/ebus.c | 3 +- arch/sparc64/kernel/entry.S | 331 +- arch/sparc64/kernel/etrap.S | 170 +- arch/sparc64/kernel/head.S | 284 +- arch/sparc64/kernel/irq.c | 345 +- arch/sparc64/kernel/itlb_base.S | 79 + arch/sparc64/kernel/itlb_miss.S | 39 - arch/sparc64/kernel/kprobes.c | 81 +- arch/sparc64/kernel/ktlb.S | 363 +- arch/sparc64/kernel/module.c | 5 - arch/sparc64/kernel/pci.c | 16 +- arch/sparc64/kernel/pci_common.c | 301 +- arch/sparc64/kernel/pci_iommu.c | 36 +- arch/sparc64/kernel/pci_psycho.c | 23 +- arch/sparc64/kernel/pci_sabre.c | 23 +- arch/sparc64/kernel/pci_schizo.c | 24 +- arch/sparc64/kernel/pci_sun4v.c | 1259 - arch/sparc64/kernel/pci_sun4v.h | 31 - arch/sparc64/kernel/pci_sun4v_asm.S | 95 - arch/sparc64/kernel/process.c | 133 +- arch/sparc64/kernel/ptrace.c | 31 +- arch/sparc64/kernel/rtrap.S | 115 +- arch/sparc64/kernel/sbus.c | 10 +- arch/sparc64/kernel/setup.c | 414 +- arch/sparc64/kernel/smp.c | 528 +- arch/sparc64/kernel/sparc64_ksyms.c | 45 +- arch/sparc64/kernel/sun4v_ivec.S | 334 - arch/sparc64/kernel/sun4v_tlb_miss.S | 426 - arch/sparc64/kernel/sys32.S | 4 - arch/sparc64/kernel/sys_sparc.c | 303 +- arch/sparc64/kernel/sys_sparc32.c | 91 +- arch/sparc64/kernel/systbls.S | 26 +- arch/sparc64/kernel/time.c | 391 +- arch/sparc64/kernel/trampoline.S | 238 +- arch/sparc64/kernel/traps.c | 448 +- arch/sparc64/kernel/tsb.S | 552 - arch/sparc64/kernel/ttable.S | 63 +- arch/sparc64/kernel/unaligned.c | 45 +- arch/sparc64/kernel/us2e_cpufreq.c | 11 +- arch/sparc64/kernel/us3_cpufreq.c | 11 +- arch/sparc64/kernel/visemul.c | 894 - arch/sparc64/kernel/vmlinux.lds.S | 16 - arch/sparc64/kernel/winfixup.S | 480 +- arch/sparc64/lib/Makefile | 4 +- arch/sparc64/lib/NGbzero.S | 163 - arch/sparc64/lib/NGcopy_from_user.S | 37 - arch/sparc64/lib/NGcopy_to_user.S | 40 - arch/sparc64/lib/NGmemcpy.S | 368 - arch/sparc64/lib/NGpage.S | 96 - arch/sparc64/lib/NGpatch.S | 33 - arch/sparc64/lib/U3patch.S | 3 +- arch/sparc64/lib/bzero.S | 2 +- arch/sparc64/lib/clear_page.S | 12 +- arch/sparc64/lib/copy_page.S | 7 +- arch/sparc64/lib/delay.c | 19 +- arch/sparc64/lib/find_bit.c | 127 + arch/sparc64/lib/xor.S | 300 +- arch/sparc64/math-emu/math.c | 24 +- arch/sparc64/mm/Makefile | 2 +- arch/sparc64/mm/fault.c | 30 +- arch/sparc64/mm/generic.c | 43 +- arch/sparc64/mm/hugetlbpage.c | 226 +- arch/sparc64/mm/init.c | 1467 +- arch/sparc64/mm/tlb.c | 69 +- arch/sparc64/mm/tsb.c | 500 - arch/sparc64/mm/ultra.S | 374 +- arch/sparc64/prom/console.c | 6 - arch/sparc64/prom/init.c | 60 +- arch/sparc64/prom/misc.c | 44 +- arch/sparc64/prom/p1275.c | 11 + arch/sparc64/prom/tree.c | 9 +- arch/sparc64/solaris/misc.c | 4 +- arch/um/Kconfig | 17 +- arch/um/Kconfig.i386 | 24 +- arch/um/Kconfig.x86_64 | 5 - arch/um/Makefile | 36 +- arch/um/Makefile-i386 | 4 - arch/um/Makefile-x86_64 | 2 +- arch/um/defconfig | 240 +- arch/um/drivers/cow.h | 2 +- arch/um/drivers/cow_sys.h | 2 +- arch/um/drivers/cow_user.c | 94 +- arch/um/drivers/daemon_kern.c | 13 +- arch/um/drivers/harddog_kern.c | 8 +- arch/um/drivers/hostaudio_kern.c | 10 +- arch/um/drivers/mcast_kern.c | 13 +- arch/um/drivers/mconsole_kern.c | 147 +- arch/um/drivers/net_user.c | 4 +- arch/um/drivers/pcap_kern.c | 13 +- arch/um/drivers/slip_kern.c | 13 +- arch/um/drivers/slirp_kern.c | 15 +- arch/um/drivers/slirp_user.c | 2 +- arch/um/drivers/ubd_kern.c | 78 +- arch/um/include/irq_user.h | 15 +- arch/um/include/kern.h | 2 +- arch/um/include/kern_util.h | 15 +- arch/um/include/line.h | 18 +- arch/um/include/longjmp.h | 4 +- arch/um/include/mem_user.h | 1 + arch/um/include/misc_constants.h | 6 - arch/um/include/os.h | 46 +- arch/um/include/sigio.h | 3 + arch/um/include/skas/mode-skas.h | 1 + arch/um/include/skas/skas.h | 1 + arch/um/include/sysdep-i386/checksum.h | 5 +- arch/um/include/sysdep-i386/kernel-offsets.h | 2 - arch/um/include/sysdep-i386/ptrace.h | 5 - arch/um/include/sysdep-i386/tls.h | 32 - .../um/include/sysdep-x86_64/kernel-offsets.h | 2 - arch/um/include/sysdep-x86_64/tls.h | 29 - arch/um/include/tt/tt.h | 3 +- arch/um/include/user.h | 6 +- arch/um/include/user_util.h | 9 +- arch/um/kernel/Makefile | 9 +- arch/um/kernel/exec_kern.c | 18 +- arch/um/kernel/irq.c | 315 +- arch/um/kernel/irq_user.c | 412 + arch/um/kernel/ksyms.c | 5 +- arch/um/kernel/mem.c | 6 +- arch/um/kernel/physmem.c | 11 +- arch/um/kernel/process_kern.c | 26 +- arch/um/kernel/ptrace.c | 50 +- arch/um/kernel/sigio_kern.c | 10 +- .../{os-Linux/sigio.c => kernel/sigio_user.c} | 231 +- arch/um/kernel/skas/Makefile | 10 +- arch/um/kernel/skas/process_kern.c | 11 - arch/um/kernel/smp.c | 15 +- arch/um/kernel/syscall_kern.c | 4 +- arch/um/kernel/time_kern.c | 12 +- arch/um/kernel/trap_kern.c | 8 +- arch/um/kernel/tt/process_kern.c | 10 +- arch/um/{os-Linux => kernel}/tty_log.c | 18 +- arch/um/kernel/um_arch.c | 24 +- arch/um/os-Linux/Makefile | 16 +- arch/um/os-Linux/drivers/ethertap_kern.c | 13 +- arch/um/os-Linux/drivers/ethertap_user.c | 2 +- arch/um/os-Linux/drivers/tuntap_kern.c | 13 +- arch/um/os-Linux/file.c | 2 +- arch/um/os-Linux/helper.c | 10 +- arch/um/os-Linux/irq.c | 159 - arch/um/os-Linux/main.c | 32 +- arch/um/os-Linux/mem.c | 168 +- arch/um/os-Linux/process.c | 60 +- arch/um/os-Linux/skas/mem.c | 4 +- arch/um/os-Linux/skas/process.c | 47 +- arch/um/os-Linux/start_up.c | 170 +- arch/um/os-Linux/sys-i386/registers.c | 27 +- arch/um/os-Linux/sys-i386/tls.c | 34 - arch/um/os-Linux/sys-x86_64/registers.c | 27 +- arch/um/os-Linux/time.c | 10 +- arch/um/os-Linux/tls.c | 76 - arch/um/os-Linux/trap.c | 4 +- arch/um/os-Linux/tt.c | 10 - arch/um/os-Linux/uaccess.c | 4 +- arch/um/os-Linux/umid.c | 52 +- arch/um/os-Linux/user_syms.c | 16 +- arch/um/os-Linux/util.c | 2 +- arch/um/scripts/Makefile.rules | 44 +- arch/um/sys-i386/Makefile | 28 +- arch/um/sys-i386/ksyms.c | 4 + arch/um/sys-i386/ptrace.c | 60 +- arch/um/sys-i386/ptrace_user.c | 12 +- arch/um/sys-i386/signal.c | 5 +- arch/um/sys-i386/stub_segv.c | 4 +- arch/um/sys-i386/sys_call_table.S | 2 + arch/um/sys-i386/syscalls.c | 25 +- arch/um/sys-i386/tls.c | 384 - arch/um/sys-i386/user-offsets.c | 71 +- arch/um/sys-x86_64/Makefile | 19 +- arch/um/sys-x86_64/signal.c | 43 +- arch/um/sys-x86_64/stub_segv.c | 10 +- arch/um/sys-x86_64/syscalls.c | 2 +- arch/um/sys-x86_64/tls.c | 14 - arch/um/sys-x86_64/user-offsets.c | 117 +- arch/v850/Kconfig | 6 - arch/v850/kernel/memcons.c | 2 +- arch/v850/kernel/process.c | 2 +- arch/v850/kernel/rte_cb_leds.c | 2 +- arch/v850/kernel/rte_mb_a_pci.c | 12 +- arch/v850/kernel/v850_ksyms.c | 1 + arch/v850/kernel/vmlinux.lds.S | 8 - arch/x86_64/Kconfig | 125 +- arch/x86_64/Makefile | 65 +- arch/x86_64/boot/Makefile | 36 +- arch/x86_64/boot/video.S | 5 - arch/x86_64/crypto/aes.c | 7 +- arch/x86_64/defconfig | 81 +- arch/x86_64/ia32/Makefile | 20 +- arch/x86_64/ia32/ia32_binfmt.c | 12 +- arch/x86_64/ia32/ia32entry-xen.S | 726 - arch/x86_64/ia32/ia32entry.S | 39 +- arch/x86_64/ia32/sys_ia32.c | 108 +- arch/x86_64/ia32/syscall32-xen.c | 128 - arch/x86_64/ia32/syscall32.c | 4 +- arch/x86_64/ia32/syscall32_syscall-xen.S | 28 - arch/x86_64/ia32/vsyscall-int80.S | 58 - arch/x86_64/ia32/vsyscall-sigreturn.S | 25 +- arch/x86_64/kernel/Makefile | 21 +- arch/x86_64/kernel/acpi/Makefile | 2 +- arch/x86_64/kernel/acpi/processor.c | 72 - arch/x86_64/kernel/aperture.c | 6 +- arch/x86_64/kernel/apic-xen.c | 198 - arch/x86_64/kernel/apic.c | 37 +- arch/x86_64/kernel/asm-offsets.c | 2 - arch/x86_64/kernel/e820-xen.c | 753 - arch/x86_64/kernel/e820.c | 44 +- arch/x86_64/kernel/early_printk-xen.c | 304 - arch/x86_64/kernel/early_printk.c | 118 +- arch/x86_64/kernel/entry-xen.S | 1141 - arch/x86_64/kernel/entry.S | 8 +- arch/x86_64/kernel/functionlist | 1286 - arch/x86_64/kernel/genapic-xen.c | 144 - arch/x86_64/kernel/genapic_xen.c | 162 - arch/x86_64/kernel/head-xen.S | 176 - arch/x86_64/kernel/head.S | 26 +- arch/x86_64/kernel/head64-xen.c | 159 - arch/x86_64/kernel/init_task.c | 3 - arch/x86_64/kernel/io_apic-xen.c | 2232 -- arch/x86_64/kernel/io_apic.c | 45 +- arch/x86_64/kernel/ioport-xen.c | 99 - arch/x86_64/kernel/irq-xen.c | 163 - arch/x86_64/kernel/irq.c | 25 +- arch/x86_64/kernel/kprobes.c | 85 +- arch/x86_64/kernel/ldt-xen.c | 282 - arch/x86_64/kernel/mce.c | 17 +- arch/x86_64/kernel/mce_amd.c | 2 +- arch/x86_64/kernel/mpparse-xen.c | 1012 - arch/x86_64/kernel/mpparse.c | 31 +- arch/x86_64/kernel/nmi.c | 12 +- arch/x86_64/kernel/pci-dma.c | 9 - arch/x86_64/kernel/pci-gart.c | 25 +- arch/x86_64/kernel/pci-nommu.c | 7 +- arch/x86_64/kernel/pci-swiotlb-xen.c | 54 - arch/x86_64/kernel/pmtimer.c | 9 +- arch/x86_64/kernel/process-xen.c | 785 - arch/x86_64/kernel/process.c | 53 +- arch/x86_64/kernel/ptrace.c | 17 +- arch/x86_64/kernel/setup-xen.c | 1710 -- arch/x86_64/kernel/setup.c | 144 +- arch/x86_64/kernel/setup64-xen.c | 339 - arch/x86_64/kernel/setup64.c | 43 +- arch/x86_64/kernel/signal.c | 4 + arch/x86_64/kernel/smp-xen.c | 596 - arch/x86_64/kernel/smp.c | 10 +- arch/x86_64/kernel/smpboot.c | 31 +- arch/x86_64/kernel/time.c | 174 +- arch/x86_64/kernel/traps-xen.c | 1035 - arch/x86_64/kernel/traps.c | 79 +- arch/x86_64/kernel/vmlinux.lds.S | 8 +- arch/x86_64/kernel/vsyscall-xen.c | 239 - arch/x86_64/kernel/x8664_ksyms-xen.c | 155 - arch/x86_64/kernel/x8664_ksyms.c | 8 + arch/x86_64/kernel/xen_entry.S | 40 - arch/x86_64/lib/thunk.S | 1 + arch/x86_64/mm/Makefile | 10 - arch/x86_64/mm/fault-xen.c | 690 - arch/x86_64/mm/fault.c | 83 +- arch/x86_64/mm/init-xen.c | 1229 - arch/x86_64/mm/init.c | 126 +- arch/x86_64/mm/k8topology.c | 2 +- arch/x86_64/mm/mmap.c | 101 +- arch/x86_64/mm/numa.c | 87 +- arch/x86_64/mm/pageattr-xen.c | 397 - arch/x86_64/mm/pageattr.c | 63 +- arch/x86_64/mm/srat.c | 189 +- arch/x86_64/oprofile/Makefile | 5 +- arch/x86_64/pci/Makefile | 15 +- arch/x86_64/pci/mmconfig.c | 76 +- arch/xtensa/Kconfig | 8 - arch/xtensa/kernel/irq.c | 15 +- arch/xtensa/kernel/xtensa_ksyms.c | 3 + arch/xtensa/mm/init.c | 2 +- arch/xtensa/mm/pgtable.c | 24 +- arch/xtensa/platform-iss/console.c | 4 + arch/xtensa/platform-iss/setup.c | 2 +- block/Kconfig | 22 - block/Makefile | 2 - block/as-iosched.c | 158 +- block/blktrace.c | 538 - block/cfq-iosched.c | 718 +- block/deadline-iosched.c | 129 +- block/elevator.c | 228 +- block/genhd.c | 31 +- block/ioctl.c | 28 +- block/ll_rw_blk.c | 203 +- block/noop-iosched.c | 7 +- block/scsi_ioctl.c | 106 +- configs/kernel-2.6.17-i586-smp.config | 2896 --- configs/kernel-2.6.17-i586.config | 3015 --- configs/kernel-2.6.17-i686-kdump.config | 3245 --- configs/kernel-2.6.17-i686-smp.config | 3238 --- configs/kernel-2.6.17-i686-xen.config | 3085 --- configs/kernel-2.6.17-i686-xen0.config | 3083 --- configs/kernel-2.6.17-i686-xenU.config | 1531 -- configs/kernel-2.6.17-i686.config | 3234 --- crypto/Kconfig | 19 - crypto/Makefile | 3 - crypto/aes.c | 7 +- crypto/api.c | 22 +- crypto/deflate.c | 3 +- crypto/des.c | 1 - crypto/digest.c | 8 - crypto/mpi/Makefile | 30 - crypto/mpi/generic_mpi-asm-defs.h | 10 - crypto/mpi/generic_mpih-add1.c | 62 - crypto/mpi/generic_mpih-lshift.c | 66 - crypto/mpi/generic_mpih-mul1.c | 58 - crypto/mpi/generic_mpih-mul2.c | 63 - crypto/mpi/generic_mpih-mul3.c | 64 - crypto/mpi/generic_mpih-rshift.c | 65 - crypto/mpi/generic_mpih-sub1.c | 62 - crypto/mpi/generic_udiv-w-sdiv.c | 130 - crypto/mpi/longlong.h | 1502 -- crypto/mpi/mpi-add.c | 258 - crypto/mpi/mpi-bit.c | 245 - crypto/mpi/mpi-cmp.c | 71 - crypto/mpi/mpi-div.c | 345 - crypto/mpi/mpi-gcd.c | 60 - crypto/mpi/mpi-inline.c | 33 - crypto/mpi/mpi-inline.h | 128 - crypto/mpi/mpi-internal.h | 265 - crypto/mpi/mpi-inv.c | 148 - crypto/mpi/mpi-mpow.c | 113 - crypto/mpi/mpi-mul.c | 202 - crypto/mpi/mpi-pow.c | 312 - crypto/mpi/mpi-scan.c | 129 - crypto/mpi/mpicoder.c | 359 - crypto/mpi/mpih-cmp.c | 58 - crypto/mpi/mpih-div.c | 534 - crypto/mpi/mpih-mul.c | 547 - crypto/mpi/mpiutil.c | 214 - crypto/serpent.c | 1 - crypto/sha512.c | 2 +- crypto/signature/Makefile | 10 - crypto/signature/dsa.c | 98 - crypto/signature/key.h | 7 - crypto/signature/ksign-keyring.c | 112 - crypto/signature/ksign-parse.c | 609 - crypto/signature/ksign-publickey.c | 19 - crypto/signature/ksign.c | 179 - crypto/signature/local.h | 163 - crypto/tcrypt.h | 25 +- crypto/twofish.c | 21 +- drivers/Kconfig | 6 +- drivers/Makefile | 8 +- drivers/acpi/Kconfig | 20 +- drivers/acpi/blacklist.c | 27 +- drivers/acpi/ec.c | 20 +- drivers/acpi/ibm_acpi.c | 13 +- drivers/acpi/osl.c | 75 +- drivers/acpi/parser/psutils.c | 8 +- drivers/acpi/processor_core.c | 12 +- drivers/acpi/processor_idle.c | 25 +- drivers/acpi/scan.c | 5 +- drivers/acpi/tables.c | 3 +- drivers/acpi/utils.c | 6 +- drivers/atm/.gitignore | 5 - drivers/atm/lanai.c | 2 +- drivers/atm/suni.c | 2 +- drivers/base/bus.c | 27 - drivers/base/class.c | 45 +- drivers/base/cpu.c | 9 +- drivers/base/dd.c | 2 +- drivers/base/firmware_class.c | 41 +- drivers/base/map.c | 21 +- drivers/base/memory.c | 8 +- drivers/base/platform.c | 6 +- drivers/base/power/suspend.c | 12 - drivers/base/topology.c | 2 +- drivers/block/DAC960.c | 42 +- drivers/block/Kconfig | 19 +- drivers/block/Makefile | 2 +- drivers/block/acsi_slm.c | 2 + drivers/block/amiflop.c | 1 - drivers/block/aoe/aoe.h | 12 +- drivers/block/aoe/aoeblk.c | 26 +- drivers/block/aoe/aoechr.c | 37 - drivers/block/aoe/aoecmd.c | 28 +- drivers/block/aoe/aoedev.c | 2 +- drivers/block/aoe/aoenet.c | 21 +- drivers/block/ataflop.c | 4 +- drivers/block/cciss.c | 29 +- drivers/block/cciss_scsi.c | 5 +- drivers/block/cpqarray.c | 17 +- drivers/block/floppy.c | 53 +- drivers/block/loop.c | 26 +- drivers/block/mambo_bd.c | 291 - drivers/block/nbd.c | 21 +- drivers/block/paride/bpck6.c | 3 +- drivers/block/paride/comm.c | 16 +- drivers/block/paride/on26.c | 2 +- drivers/block/paride/pd.c | 3 +- drivers/block/paride/pg.c | 8 +- drivers/block/paride/pt.c | 8 +- drivers/block/pktcdvd.c | 57 +- drivers/block/rd.c | 7 +- drivers/block/ub.c | 245 +- drivers/block/umem.c | 7 +- drivers/bluetooth/bluecard_cs.c | 119 +- drivers/bluetooth/bt3c_cs.c | 130 +- drivers/bluetooth/btuart_cs.c | 130 +- drivers/bluetooth/dtl1_cs.c | 120 +- drivers/cdrom/aztcd.c | 2 +- drivers/cdrom/cdrom.c | 880 +- drivers/cdrom/cdu31a.c | 8 +- drivers/cdrom/cm206.c | 52 +- drivers/cdrom/sbpcd.c | 2190 +- drivers/cdrom/viocd.c | 2 +- drivers/char/Kconfig | 27 +- drivers/char/Makefile | 93 +- drivers/char/agp/Kconfig | 6 +- drivers/char/agp/agp.h | 11 +- drivers/char/agp/ali-agp.c | 2 +- drivers/char/agp/alpha-agp.c | 14 +- drivers/char/agp/amd64-agp.c | 4 +- drivers/char/agp/ati-agp.c | 6 +- drivers/char/agp/backend.c | 2 +- drivers/char/agp/efficeon-agp.c | 16 +- drivers/char/agp/frontend.c | 2 +- drivers/char/agp/generic.c | 4 +- drivers/char/agp/hp-agp.c | 6 +- drivers/char/agp/i460-agp.c | 16 +- drivers/char/agp/intel-agp.c | 47 +- drivers/char/agp/isoch.c | 20 +- drivers/char/agp/nvidia-agp.c | 50 +- drivers/char/agp/sgi-agp.c | 2 +- drivers/char/agp/sis-agp.c | 8 +- drivers/char/agp/sworks-agp.c | 15 +- drivers/char/agp/uninorth-agp.c | 12 +- drivers/char/amiserial.c | 18 +- drivers/char/applicom.c | 2 +- drivers/char/crash.c | 129 - drivers/char/drm/Kconfig | 4 +- drivers/char/drm/drmP.h | 21 +- drivers/char/drm/drm_agpsupport.c | 344 +- drivers/char/drm/drm_bufs.c | 1472 +- drivers/char/drm/drm_dma.c | 87 +- drivers/char/drm/drm_drv.c | 463 +- drivers/char/drm/drm_fops.c | 523 +- drivers/char/drm/drm_memory.c | 173 +- drivers/char/drm/drm_memory.h | 128 +- drivers/char/drm/drm_memory_debug.h | 72 +- drivers/char/drm/drm_pci.c | 57 +- drivers/char/drm/drm_pciids.h | 76 +- drivers/char/drm/drm_stub.c | 239 +- drivers/char/drm/drm_vm.c | 478 +- drivers/char/drm/i810_dma.c | 2 +- drivers/char/drm/i830_dma.c | 2 +- drivers/char/drm/i915_dma.c | 2 + drivers/char/drm/i915_irq.c | 2 - drivers/char/drm/r300_cmdbuf.c | 86 +- drivers/char/drm/r300_reg.h | 39 +- drivers/char/drm/radeon_cp.c | 151 +- drivers/char/drm/radeon_drm.h | 5 - drivers/char/drm/radeon_drv.h | 25 +- drivers/char/drm/radeon_state.c | 105 +- drivers/char/drm/sis_mm.c | 2 +- drivers/char/drm/via_irq.c | 12 +- drivers/char/ds1286.c | 15 +- drivers/char/dtlk.c | 2 +- drivers/char/epca.c | 3 +- drivers/char/ftape/lowlevel/fdc-io.c | 2 +- drivers/char/generic_nvram.c | 5 +- drivers/char/generic_serial.c | 14 +- drivers/char/genrtc.c | 8 +- drivers/char/hvc_console.c | 102 +- drivers/char/hvc_console.h | 63 - drivers/char/hvc_rtas.c | 138 - drivers/char/hvc_vio.c | 11 - drivers/char/hvcs.c | 12 +- drivers/char/{ip2/ip2base.c => ip2.c} | 6 +- drivers/char/ip2/Makefile | 8 - drivers/char/{ip2 => }/ip2main.c | 20 +- drivers/char/ipmi/ipmi_devintf.c | 66 +- drivers/char/ipmi/ipmi_kcs_sm.c | 8 +- drivers/char/ipmi/ipmi_msghandler.c | 650 +- drivers/char/ipmi/ipmi_poweroff.c | 8 +- drivers/char/ipmi/ipmi_si_intf.c | 1151 +- drivers/char/ipmi/ipmi_si_sm.h | 3 +- drivers/char/ipmi/ipmi_watchdog.c | 69 +- drivers/char/isicom.c | 3 +- drivers/char/istallion.c | 41 +- drivers/char/keyboard.c | 138 +- drivers/char/mem.c | 199 +- drivers/char/misc.c | 2 +- drivers/char/mwave/mwavedd.c | 2 +- drivers/char/mxser.c | 8 +- drivers/char/mxser.h | 2 +- drivers/char/n_tty.c | 14 +- drivers/char/nwflash.c | 11 +- drivers/char/pcmcia/cm4000_cs.c | 121 +- drivers/char/pcmcia/cm4040_cs.c | 133 +- drivers/char/pcmcia/synclink_cs.c | 118 +- drivers/char/ppdev.c | 3 +- drivers/char/random.c | 8 +- drivers/char/raw.c | 23 +- drivers/char/rio/Makefile | 2 +- drivers/char/rio/board.h | 58 +- drivers/char/rio/bootpkt.h | 61 + drivers/char/rio/cirrus.h | 110 +- drivers/char/rio/cmdblk.h | 4 +- drivers/char/rio/cmdpkt.h | 94 +- drivers/char/rio/control.h | 61 + drivers/char/rio/daemon.h | 67 +- drivers/char/rio/defaults.h | 51 + drivers/char/rio/error.h | 82 + drivers/char/rio/func.h | 52 +- drivers/char/rio/host.h | 65 +- drivers/char/rio/link.h | 124 +- drivers/char/rio/linux_compat.h | 45 +- drivers/char/rio/list.h | 56 + drivers/char/rio/map.h | 12 +- drivers/char/rio/param.h | 24 +- drivers/char/rio/parmmap.h | 68 +- drivers/char/rio/phb.h | 39 +- drivers/char/rio/pkt.h | 24 +- drivers/char/rio/port.h | 250 +- drivers/char/rio/qbuf.h | 62 + drivers/char/rio/rio.h | 173 +- drivers/char/rio/rio_linux.c | 141 +- drivers/char/rio/rioboot.c | 1689 +- drivers/char/rio/riocmd.c | 176 +- drivers/char/rio/rioctrl.c | 424 +- drivers/char/rio/riodrvr.h | 48 +- drivers/char/rio/rioinit.c | 199 +- drivers/char/rio/riointr.c | 320 +- drivers/char/rio/rioioctl.h | 56 +- drivers/char/rio/rioparam.c | 129 +- drivers/char/rio/riopcicopy.c | 8 + drivers/char/rio/rioroute.c | 166 +- drivers/char/rio/riotable.c | 123 +- drivers/char/rio/riotty.c | 198 +- drivers/char/rio/riotypes.h | 68 + drivers/char/rio/rom.h | 62 + drivers/char/rio/rup.h | 25 +- drivers/char/rio/sam.h | 67 + drivers/char/rio/space.h | 45 + drivers/char/rio/top.h | 48 + drivers/char/rio/typdef.h | 82 + drivers/char/rio/unixrup.h | 6 +- drivers/char/riscom8.c | 8 +- drivers/char/rtc.c | 5 +- drivers/char/s3c2410-rtc.c | 4 +- drivers/char/ser_a2232.c | 4 +- drivers/char/snsc.c | 8 +- drivers/char/snsc.h | 5 +- drivers/char/snsc_event.c | 37 +- drivers/char/stallion.c | 47 +- drivers/char/sx.c | 2 +- drivers/char/synclink.c | 35 +- drivers/char/synclink_gt.c | 266 +- drivers/char/synclinkmp.c | 2 +- drivers/char/sysrq.c | 250 +- drivers/char/tb0219.c | 24 +- drivers/char/toshiba.c | 38 +- drivers/char/tpm/Kconfig | 16 +- drivers/char/tpm/Makefile | 5 +- drivers/char/tpm/tpm.c | 786 +- drivers/char/tpm/tpm.h | 73 +- drivers/char/tpm/tpm_atmel.c | 58 +- drivers/char/tpm/tpm_atmel.h | 25 +- drivers/char/tpm/tpm_bios.c | 137 +- drivers/char/tpm/tpm_infineon.c | 61 +- drivers/char/tpm/tpm_nsc.c | 49 +- drivers/char/tpm/tpm_tis.c | 666 - drivers/char/tty_io.c | 120 +- drivers/char/vme_scc.c | 2 +- drivers/char/vr41xx_giu.c | 19 +- .../{rtc/rtc-vr41xx.c => char/vr41xx_rtc.c} | 432 +- drivers/char/vt.c | 20 +- drivers/char/watchdog/Kconfig | 17 - drivers/char/watchdog/Makefile | 2 - drivers/char/watchdog/at91_wdt.c | 228 - drivers/char/watchdog/ep93xx_wdt.c | 257 - drivers/char/watchdog/i8xx_tco.c | 16 +- drivers/char/watchdog/machzwd.c | 3 +- drivers/char/watchdog/mpcore_wdt.c | 4 - drivers/char/watchdog/mv64x60_wdt.c | 20 +- drivers/char/watchdog/pcwd.c | 137 +- drivers/char/watchdog/pcwd_usb.c | 10 +- drivers/char/watchdog/s3c2410_wdt.c | 6 - drivers/char/watchdog/sc1200wdt.c | 9 +- drivers/connector/connector.c | 22 +- drivers/cpufreq/Kconfig | 2 +- drivers/cpufreq/cpufreq.c | 191 +- drivers/cpufreq/cpufreq_conservative.c | 157 +- drivers/cpufreq/cpufreq_ondemand.c | 123 +- drivers/cpufreq/cpufreq_performance.c | 2 +- drivers/cpufreq/cpufreq_powersave.c | 2 +- drivers/cpufreq/cpufreq_stats.c | 8 +- drivers/cpufreq/cpufreq_userspace.c | 12 +- drivers/cpufreq/freq_table.c | 12 +- drivers/crypto/padlock-aes.c | 6 +- drivers/dio/dio-driver.c | 9 +- drivers/edac/Kconfig | 10 +- drivers/edac/amd76x_edac.c | 126 +- drivers/edac/e752x_edac.c | 371 +- drivers/edac/e7xxx_edac.c | 228 +- drivers/edac/edac_mc.c | 810 +- drivers/edac/edac_mc.h | 133 +- drivers/edac/i82860_edac.c | 127 +- drivers/edac/i82875p_edac.c | 208 +- drivers/edac/r82600_edac.c | 140 +- drivers/eisa/.gitignore | 1 - drivers/eisa/eisa-bus.c | 7 +- drivers/firmware/Kconfig | 2 +- drivers/firmware/Makefile | 3 +- drivers/firmware/dcdbas.c | 152 +- drivers/firmware/efivars.c | 28 +- drivers/firmware/pcdp.c | 19 +- drivers/hwmon/Kconfig | 7 +- drivers/hwmon/adm1021.c | 13 +- drivers/hwmon/adm1025.c | 25 +- drivers/hwmon/adm1026.c | 92 +- drivers/hwmon/adm1031.c | 49 +- drivers/hwmon/adm9240.c | 29 +- drivers/hwmon/asb100.c | 45 +- drivers/hwmon/atxp1.c | 9 +- drivers/hwmon/ds1621.c | 13 +- drivers/hwmon/f71805f.c | 275 +- drivers/hwmon/fscher.c | 41 +- drivers/hwmon/fscpos.c | 33 +- drivers/hwmon/gl518sm.c | 25 +- drivers/hwmon/gl520sm.c | 47 +- drivers/hwmon/hdaps.c | 14 +- drivers/hwmon/hwmon-vid.c | 9 +- drivers/hwmon/hwmon.c | 26 +- drivers/hwmon/it87.c | 66 +- drivers/hwmon/lm63.c | 29 +- drivers/hwmon/lm75.c | 13 +- drivers/hwmon/lm77.c | 21 +- drivers/hwmon/lm78.c | 51 +- drivers/hwmon/lm80.c | 27 +- drivers/hwmon/lm83.c | 13 +- drivers/hwmon/lm85.c | 71 +- drivers/hwmon/lm87.c | 39 +- drivers/hwmon/lm90.c | 21 +- drivers/hwmon/lm92.c | 17 +- drivers/hwmon/max1619.c | 13 +- drivers/hwmon/pc87360.c | 469 +- drivers/hwmon/sis5595.c | 51 +- drivers/hwmon/smsc47b397.c | 17 +- drivers/hwmon/smsc47m1.c | 41 +- drivers/hwmon/via686a.c | 33 +- drivers/hwmon/vt8231.c | 51 +- drivers/hwmon/w83627ehf.c | 239 +- drivers/hwmon/w83627hf.c | 134 +- drivers/hwmon/w83781d.c | 82 +- drivers/hwmon/w83792d.c | 539 +- drivers/hwmon/w83l785ts.c | 9 +- drivers/i2c/algos/i2c-algo-bit.c | 3 +- drivers/i2c/algos/i2c-algo-ite.c | 4 +- drivers/i2c/algos/i2c-algo-pca.c | 6 +- drivers/i2c/algos/i2c-algo-pcf.c | 8 +- drivers/i2c/algos/i2c-algo-sibyte.c | 4 +- drivers/i2c/busses/Kconfig | 35 +- drivers/i2c/busses/i2c-ali1535.c | 4 + drivers/i2c/busses/i2c-amd756-s4882.c | 13 +- drivers/i2c/busses/i2c-frodo.c | 85 + drivers/i2c/busses/i2c-i801.c | 2 + drivers/i2c/busses/i2c-iop3xx.c | 9 +- drivers/i2c/busses/i2c-isa.c | 2 +- drivers/i2c/busses/i2c-ite.c | 6 +- drivers/i2c/busses/i2c-ixp4xx.c | 41 +- drivers/i2c/busses/i2c-mpc.c | 5 - drivers/i2c/busses/i2c-mv64xxx.c | 90 +- drivers/i2c/busses/i2c-parport-light.c | 9 +- drivers/i2c/busses/i2c-parport.c | 9 +- drivers/i2c/busses/i2c-parport.h | 2 +- drivers/i2c/busses/i2c-piix4.c | 4 +- drivers/i2c/busses/i2c-pxa.c | 2 +- drivers/i2c/busses/i2c-sis96x.c | 8 + drivers/i2c/busses/i2c-viapro.c | 8 + drivers/i2c/busses/scx200_acb.c | 285 +- drivers/i2c/chips/Kconfig | 18 + drivers/i2c/chips/Makefile | 2 + drivers/i2c/chips/ds1337.c | 160 +- drivers/i2c/chips/ds1374.c | 27 +- drivers/i2c/chips/eeprom.c | 9 +- drivers/i2c/chips/isp1301_omap.c | 2 + drivers/i2c/chips/m41t00.c | 27 +- drivers/i2c/chips/max6875.c | 10 +- drivers/i2c/chips/pcf8591.c | 13 +- drivers/i2c/chips/rtc8564.c | 385 + drivers/i2c/chips/rtc8564.h | 78 + drivers/i2c/chips/tps65010.c | 45 +- drivers/i2c/i2c-core.c | 81 +- drivers/ide/ide-cd.c | 111 +- drivers/ide/ide-disk.c | 16 +- drivers/ide/ide-dma.c | 2 +- drivers/ide/ide-floppy.c | 11 +- drivers/ide/ide-iops.c | 4 + drivers/ide/ide-lib.c | 8 +- drivers/ide/ide-probe.c | 9 - drivers/ide/ide-tape.c | 24 +- drivers/ide/ide-taskfile.c | 8 +- drivers/ide/ide.c | 2 +- drivers/ide/legacy/ide-cs.c | 128 +- drivers/ide/mips/au1xxx-ide.c | 5 - drivers/ide/pci/alim15x3.c | 2 +- drivers/ide/pci/amd74xx.c | 21 +- drivers/ide/pci/atiixp.c | 1 - drivers/ide/pci/generic.c | 3 +- drivers/ide/pci/pdc202xx_old.c | 2 + drivers/ide/pci/piix.c | 11 +- drivers/ide/pci/sgiioc4.c | 23 +- drivers/ide/pci/sis5513.c | 2 - drivers/ide/pci/via82cxxx.c | 2 +- drivers/ide/ppc/pmac.c | 4 +- drivers/ide/setup-pci.c | 13 + drivers/ieee1394/dv1394.c | 41 +- drivers/ieee1394/highlevel.c | 3 +- drivers/ieee1394/ieee1394_core.c | 16 +- drivers/ieee1394/ieee1394_core.h | 3 + drivers/ieee1394/ohci1394.c | 53 +- drivers/ieee1394/raw1394.c | 102 +- drivers/ieee1394/sbp2.c | 338 +- drivers/ieee1394/sbp2.h | 18 +- drivers/ieee1394/video1394.c | 16 +- drivers/infiniband/Kconfig | 1 - drivers/infiniband/Makefile | 1 - drivers/infiniband/core/agent.c | 320 +- drivers/infiniband/core/cache.c | 2 +- drivers/infiniband/core/cm.c | 54 +- drivers/infiniband/core/fmr_pool.c | 6 +- drivers/infiniband/core/mad.c | 353 +- drivers/infiniband/core/mad_priv.h | 24 +- drivers/infiniband/core/mad_rmpp.c | 218 +- drivers/infiniband/core/smi.h | 2 + drivers/infiniband/core/sysfs.c | 209 +- drivers/infiniband/core/ucm.c | 12 +- drivers/infiniband/core/user_mad.c | 219 +- drivers/infiniband/core/uverbs.h | 5 +- drivers/infiniband/core/uverbs_cmd.c | 202 +- drivers/infiniband/core/uverbs_main.c | 6 +- drivers/infiniband/core/uverbs_mem.c | 4 +- drivers/infiniband/core/verbs.c | 293 +- drivers/infiniband/hw/ipath/Kconfig | 16 - drivers/infiniband/hw/ipath/Makefile | 36 - drivers/infiniband/hw/ipath/ipath_common.h | 616 - drivers/infiniband/hw/ipath/ipath_cq.c | 295 - drivers/infiniband/hw/ipath/ipath_debug.h | 97 - drivers/infiniband/hw/ipath/ipath_diag.c | 368 - drivers/infiniband/hw/ipath/ipath_driver.c | 1992 -- drivers/infiniband/hw/ipath/ipath_eeprom.c | 612 - drivers/infiniband/hw/ipath/ipath_file_ops.c | 1914 -- drivers/infiniband/hw/ipath/ipath_fs.c | 605 - drivers/infiniband/hw/ipath/ipath_ht400.c | 1603 -- drivers/infiniband/hw/ipath/ipath_init_chip.c | 958 - drivers/infiniband/hw/ipath/ipath_intr.c | 854 - drivers/infiniband/hw/ipath/ipath_kernel.h | 883 - drivers/infiniband/hw/ipath/ipath_keys.c | 230 - drivers/infiniband/hw/ipath/ipath_layer.c | 1521 -- drivers/infiniband/hw/ipath/ipath_layer.h | 181 - drivers/infiniband/hw/ipath/ipath_mad.c | 1352 - drivers/infiniband/hw/ipath/ipath_mr.c | 383 - drivers/infiniband/hw/ipath/ipath_pe800.c | 1253 - drivers/infiniband/hw/ipath/ipath_qp.c | 913 - drivers/infiniband/hw/ipath/ipath_rc.c | 1856 -- drivers/infiniband/hw/ipath/ipath_registers.h | 453 - drivers/infiniband/hw/ipath/ipath_ruc.c | 545 - drivers/infiniband/hw/ipath/ipath_srq.c | 273 - drivers/infiniband/hw/ipath/ipath_stats.c | 303 - drivers/infiniband/hw/ipath/ipath_sysfs.c | 790 - drivers/infiniband/hw/ipath/ipath_uc.c | 645 - drivers/infiniband/hw/ipath/ipath_ud.c | 623 - .../infiniband/hw/ipath/ipath_user_pages.c | 209 - drivers/infiniband/hw/ipath/ipath_verbs.c | 1204 - drivers/infiniband/hw/ipath/ipath_verbs.h | 693 - .../infiniband/hw/ipath/ipath_verbs_mcast.c | 333 - drivers/infiniband/hw/ipath/ipath_wc_x86_64.c | 157 - drivers/infiniband/hw/ipath/ips_common.h | 263 - drivers/infiniband/hw/ipath/verbs_debug.h | 107 - drivers/infiniband/hw/mthca/Makefile | 5 +- drivers/infiniband/hw/mthca/mthca_av.c | 135 +- drivers/infiniband/hw/mthca/mthca_cmd.c | 327 +- drivers/infiniband/hw/mthca/mthca_cmd.h | 68 +- drivers/infiniband/hw/mthca/mthca_cq.c | 204 +- drivers/infiniband/hw/mthca/mthca_dev.h | 108 +- drivers/infiniband/hw/mthca/mthca_eq.c | 12 +- drivers/infiniband/hw/mthca/mthca_mad.c | 61 +- drivers/infiniband/hw/mthca/mthca_main.c | 51 +- drivers/infiniband/hw/mthca/mthca_mcg.c | 166 +- drivers/infiniband/hw/mthca/mthca_memfree.c | 213 +- drivers/infiniband/hw/mthca/mthca_memfree.h | 29 +- drivers/infiniband/hw/mthca/mthca_mr.c | 400 +- drivers/infiniband/hw/mthca/mthca_pd.c | 25 +- drivers/infiniband/hw/mthca/mthca_profile.c | 8 +- drivers/infiniband/hw/mthca/mthca_provider.c | 174 +- drivers/infiniband/hw/mthca/mthca_provider.h | 76 +- drivers/infiniband/hw/mthca/mthca_qp.c | 607 +- drivers/infiniband/hw/mthca/mthca_srq.c | 142 +- drivers/infiniband/hw/mthca/mthca_user.h | 7 +- drivers/infiniband/ulp/ipoib/Kconfig | 3 +- drivers/infiniband/ulp/ipoib/ipoib.h | 34 +- drivers/infiniband/ulp/ipoib/ipoib_fs.c | 2 +- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 77 +- drivers/infiniband/ulp/ipoib/ipoib_main.c | 118 +- .../infiniband/ulp/ipoib/ipoib_multicast.c | 73 +- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 14 +- drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 18 +- drivers/infiniband/ulp/srp/ib_srp.c | 394 +- drivers/infiniband/ulp/srp/ib_srp.h | 11 +- drivers/input/Kconfig | 2 +- drivers/input/evbug.c | 3 +- drivers/input/evdev.c | 27 +- drivers/input/gameport/gameport.c | 30 +- drivers/input/gameport/ns558.c | 13 +- drivers/input/input.c | 435 +- drivers/input/joydev.c | 6 +- drivers/input/joystick/amijoy.c | 11 +- drivers/input/joystick/db9.c | 13 +- drivers/input/joystick/gamecon.c | 96 +- drivers/input/joystick/iforce/iforce-ff.c | 24 +- drivers/input/joystick/iforce/iforce-main.c | 2 +- drivers/input/joystick/iforce/iforce.h | 5 +- drivers/input/joystick/sidewinder.c | 11 +- drivers/input/joystick/turbografx.c | 13 +- drivers/input/keyboard/Kconfig | 2 +- drivers/input/keyboard/atkbd.c | 30 +- drivers/input/keyboard/corgikbd.c | 43 +- drivers/input/keyboard/hil_kbd.c | 28 +- drivers/input/keyboard/hilkbd.c | 53 +- drivers/input/keyboard/spitzkbd.c | 22 +- drivers/input/keyboard/sunkbd.c | 2 +- drivers/input/misc/pcspkr.c | 27 +- drivers/input/misc/uinput.c | 14 +- drivers/input/misc/wistron_btns.c | 49 - drivers/input/mouse/alps.c | 4 +- drivers/input/mouse/hil_ptr.c | 33 +- drivers/input/mouse/lifebook.c | 24 - drivers/input/mouse/logips2pp.c | 3 +- drivers/input/mouse/psmouse-base.c | 38 +- drivers/input/mouse/synaptics.c | 18 +- drivers/input/mousedev.c | 6 +- drivers/input/power.c | 3 +- drivers/input/serio/gscps2.c | 4 +- drivers/input/serio/hil_mlc.c | 14 +- drivers/input/serio/hp_sdc_mlc.c | 1 + drivers/input/serio/i8042-io.h | 4 +- drivers/input/serio/i8042-x86ia64io.h | 108 +- drivers/input/serio/libps2.c | 10 +- drivers/input/serio/parkbd.c | 3 +- drivers/input/serio/rpckbd.c | 3 +- drivers/input/serio/serio.c | 48 +- drivers/input/serio/serio_raw.c | 29 +- drivers/input/touchscreen/ads7846.c | 446 +- drivers/input/touchscreen/corgi_ts.c | 2 +- drivers/input/tsdev.c | 6 +- drivers/isdn/Makefile | 1 - drivers/isdn/capi/capi.c | 7 +- drivers/isdn/capi/kcapi.c | 17 +- drivers/isdn/capi/kcapi_proc.c | 2 +- drivers/isdn/gigaset/Kconfig | 42 - drivers/isdn/gigaset/Makefile | 6 - drivers/isdn/gigaset/asyncdata.c | 587 - drivers/isdn/gigaset/bas-gigaset.c | 2370 -- drivers/isdn/gigaset/common.c | 1233 - drivers/isdn/gigaset/ev-layer.c | 1985 -- drivers/isdn/gigaset/gigaset.h | 905 - drivers/isdn/gigaset/i4l.c | 574 - drivers/isdn/gigaset/interface.c | 725 - drivers/isdn/gigaset/isocdata.c | 1010 - drivers/isdn/gigaset/proc.c | 82 - drivers/isdn/gigaset/usb-gigaset.c | 961 - drivers/isdn/hardware/avm/avm_cs.c | 185 +- drivers/isdn/hardware/avm/avmcard.h | 4 +- drivers/isdn/hardware/avm/b1dma.c | 2 +- drivers/isdn/hardware/avm/b1isa.c | 4 +- drivers/isdn/hardware/avm/c4.c | 2 +- drivers/isdn/hardware/avm/t1isa.c | 6 +- drivers/isdn/hardware/eicon/divasync.h | 1 - drivers/isdn/hisax/avma1_cs.c | 182 +- drivers/isdn/hisax/config.c | 1 + drivers/isdn/hisax/elsa.c | 1 + drivers/isdn/hisax/elsa_cs.c | 112 +- drivers/isdn/hisax/hisax_fcpcipnp.c | 7 +- drivers/isdn/hisax/hisax_isac.c | 9 +- drivers/isdn/hisax/sedlbauer_cs.c | 143 +- drivers/isdn/hisax/st5481_b.c | 4 +- drivers/isdn/hisax/st5481_d.c | 4 +- drivers/isdn/hisax/teles_cs.c | 121 +- drivers/isdn/hysdn/boardergo.c | 31 +- drivers/isdn/hysdn/boardergo.h | 46 +- drivers/isdn/hysdn/hycapi.c | 4 +- drivers/isdn/hysdn/hysdn_boot.c | 28 +- drivers/isdn/hysdn/hysdn_defs.h | 71 +- drivers/isdn/hysdn/hysdn_init.c | 4 +- drivers/isdn/hysdn/hysdn_net.c | 8 +- drivers/isdn/hysdn/hysdn_pof.h | 12 +- drivers/isdn/hysdn/hysdn_procconf.c | 14 +- drivers/isdn/hysdn/hysdn_proclog.c | 10 +- drivers/isdn/hysdn/hysdn_sched.c | 11 +- drivers/isdn/hysdn/ince1pc.h | 18 +- drivers/isdn/i4l/Kconfig | 1 - drivers/isdn/i4l/isdn_common.c | 9 +- drivers/isdn/i4l/isdn_ppp.c | 30 +- drivers/isdn/i4l/isdn_tty.c | 7 +- drivers/isdn/i4l/isdn_x25iface.c | 2 +- drivers/isdn/isdnloop/isdnloop.c | 2 +- drivers/isdn/sc/ioctl.c | 9 +- drivers/leds/Kconfig | 91 - drivers/leds/Makefile | 17 - drivers/leds/led-class.c | 172 - drivers/leds/led-core.c | 25 - drivers/leds/led-triggers.c | 239 - drivers/leds/leds-corgi.c | 121 - drivers/leds/leds-ixp4xx-gpio.c | 215 - drivers/leds/leds-locomo.c | 95 - drivers/leds/leds-s3c24xx.c | 163 - drivers/leds/leds-spitz.c | 125 - drivers/leds/leds-tosa.c | 131 - drivers/leds/leds.h | 44 - drivers/leds/ledtrig-ide-disk.c | 62 - drivers/leds/ledtrig-timer.c | 179 - drivers/macintosh/adb.c | 14 +- drivers/macintosh/adbhid.c | 7 +- drivers/macintosh/macio_asic.c | 5 +- drivers/macintosh/mediabay.c | 4 +- drivers/macintosh/smu.c | 13 +- drivers/macintosh/therm_pm72.c | 2 + drivers/macintosh/via-pmu.c | 7 +- drivers/macintosh/via-pmu68k.c | 7 +- drivers/macintosh/windfarm_core.c | 8 +- drivers/macintosh/windfarm_lm75_sensor.c | 1 + drivers/macintosh/windfarm_max6690_sensor.c | 1 + drivers/macintosh/windfarm_smu_sat.c | 1 + drivers/md/Kconfig | 27 - drivers/md/bitmap.c | 18 +- drivers/md/dm-crypt.c | 37 +- drivers/md/dm-exception-store.c | 20 +- drivers/md/dm-io.c | 8 +- drivers/md/dm-ioctl.c | 128 +- drivers/md/dm-linear.c | 8 +- drivers/md/dm-mpath.c | 3 +- drivers/md/dm-raid1.c | 43 +- drivers/md/dm-snap.c | 406 +- drivers/md/dm-stripe.c | 13 +- drivers/md/dm-table.c | 59 +- drivers/md/dm-target.c | 3 +- drivers/md/dm.c | 183 +- drivers/md/dm.h | 23 +- drivers/md/kcopyd.c | 30 +- drivers/md/md.c | 280 +- drivers/md/multipath.c | 17 +- drivers/md/raid0.c | 5 +- drivers/md/raid1.c | 75 +- drivers/md/raid10.c | 50 +- drivers/md/raid5.c | 753 +- drivers/md/raid6main.c | 45 +- drivers/media/Kconfig | 59 +- drivers/media/common/Kconfig | 3 +- drivers/media/common/Makefile | 1 - drivers/media/common/ir-common.c | 519 + drivers/media/common/ir-functions.c | 272 - drivers/media/common/ir-keymaps.c | 1415 -- drivers/media/common/saa7146_core.c | 9 +- drivers/media/common/saa7146_fops.c | 29 +- drivers/media/common/saa7146_i2c.c | 4 +- drivers/media/common/saa7146_vbi.c | 10 +- drivers/media/common/saa7146_video.c | 38 +- drivers/media/dvb/Kconfig | 10 +- drivers/media/dvb/b2c2/Kconfig | 6 +- drivers/media/dvb/b2c2/flexcop-common.h | 4 +- drivers/media/dvb/b2c2/flexcop-i2c.c | 3 - drivers/media/dvb/b2c2/flexcop-usb.c | 1 - drivers/media/dvb/bt8xx/Kconfig | 4 +- drivers/media/dvb/bt8xx/Makefile | 2 +- drivers/media/dvb/bt8xx/bt878.c | 4 +- drivers/media/dvb/bt8xx/bt878.h | 4 +- drivers/media/dvb/bt8xx/dst.c | 14 +- drivers/media/dvb/bt8xx/dst_ca.c | 6 +- drivers/media/dvb/bt8xx/dst_common.h | 3 +- drivers/media/dvb/bt8xx/dvb-bt8xx.c | 61 +- drivers/media/dvb/bt8xx/dvb-bt8xx.h | 4 +- drivers/media/dvb/cinergyT2/cinergyT2.c | 56 +- drivers/media/dvb/dvb-core/dmxdev.c | 801 +- drivers/media/dvb/dvb-core/dmxdev.h | 36 +- drivers/media/dvb/dvb-core/dvb_demux.c | 104 +- drivers/media/dvb/dvb-core/dvb_demux.h | 4 +- drivers/media/dvb/dvb-core/dvb_frontend.c | 59 +- drivers/media/dvb/dvb-core/dvb_frontend.h | 3 - drivers/media/dvb/dvb-core/dvb_net.c | 21 +- drivers/media/dvb/dvb-core/dvb_ringbuffer.c | 2 - drivers/media/dvb/dvb-core/dvb_ringbuffer.h | 1 - drivers/media/dvb/dvb-core/dvbdev.c | 6 +- drivers/media/dvb/dvb-usb/Kconfig | 2 +- drivers/media/dvb/dvb-usb/cxusb.c | 82 +- drivers/media/dvb/dvb-usb/cxusb.h | 2 - drivers/media/dvb/dvb-usb/dibusb-common.c | 4 +- drivers/media/dvb/dvb-usb/digitv.c | 4 +- drivers/media/dvb/dvb-usb/dtt200u.c | 47 +- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 - drivers/media/dvb/dvb-usb/dvb-usb-init.c | 4 +- drivers/media/dvb/dvb-usb/dvb-usb-urb.c | 4 +- drivers/media/dvb/dvb-usb/dvb-usb.h | 9 +- drivers/media/dvb/dvb-usb/vp702x-fe.c | 5 +- drivers/media/dvb/dvb-usb/vp702x.c | 4 +- drivers/media/dvb/dvb-usb/vp7045.c | 4 +- drivers/media/dvb/frontends/Kconfig | 24 +- drivers/media/dvb/frontends/Makefile | 1 - drivers/media/dvb/frontends/bcm3510.c | 9 +- drivers/media/dvb/frontends/bsbe1.h | 123 - drivers/media/dvb/frontends/bsru6.h | 140 - drivers/media/dvb/frontends/cx24110.c | 13 - drivers/media/dvb/frontends/cx24110.h | 1 - drivers/media/dvb/frontends/cx24123.c | 565 +- drivers/media/dvb/frontends/dvb-pll.c | 23 +- drivers/media/dvb/frontends/dvb-pll.h | 6 +- drivers/media/dvb/frontends/lgdt330x.c | 6 - drivers/media/dvb/frontends/lnbp21.h | 139 - drivers/media/dvb/frontends/tda1004x.c | 12 + drivers/media/dvb/frontends/zl10353.c | 311 - drivers/media/dvb/frontends/zl10353.h | 43 - drivers/media/dvb/frontends/zl10353_priv.h | 42 - drivers/media/dvb/pluto2/Kconfig | 3 +- drivers/media/dvb/pluto2/Makefile | 2 +- drivers/media/dvb/ttpci/Kconfig | 12 +- drivers/media/dvb/ttpci/av7110.c | 270 +- drivers/media/dvb/ttpci/av7110.h | 7 +- drivers/media/dvb/ttpci/av7110_av.c | 2 + drivers/media/dvb/ttpci/av7110_hw.c | 40 +- drivers/media/dvb/ttpci/av7110_v4l.c | 16 +- drivers/media/dvb/ttpci/budget-av.c | 30 +- drivers/media/dvb/ttpci/budget-ci.c | 243 +- drivers/media/dvb/ttpci/budget-core.c | 78 +- drivers/media/dvb/ttpci/budget-patch.c | 125 +- drivers/media/dvb/ttpci/budget.c | 252 +- drivers/media/dvb/ttpci/budget.h | 17 +- .../media/dvb/ttusb-budget/dvb-ttusb-budget.c | 41 +- drivers/media/dvb/ttusb-dec/ttusb_dec.c | 31 +- drivers/media/radio/Kconfig | 30 +- drivers/media/radio/miropcm20-rds-core.c | 11 +- drivers/media/radio/radio-aimslab.c | 20 +- drivers/media/radio/radio-aztech.c | 12 +- drivers/media/radio/radio-maestro.c | 11 +- drivers/media/radio/radio-maxiradio.c | 11 +- drivers/media/radio/radio-sf16fmi.c | 22 +- drivers/media/radio/radio-sf16fmr2.c | 22 +- drivers/media/radio/radio-typhoon.c | 12 +- drivers/media/radio/radio-zoltrix.c | 26 +- drivers/media/video/Kconfig | 261 +- drivers/media/video/Makefile | 51 +- drivers/media/video/adv7170.c | 28 +- drivers/media/video/adv7175.c | 58 +- drivers/media/video/arv.c | 70 +- drivers/media/video/bt819.c | 28 +- drivers/media/video/{bt8xx => }/bt832.c | 3 +- drivers/media/video/{bt8xx => }/bt832.h | 0 drivers/media/video/{bt8xx => }/bt848.h | 0 drivers/media/video/bt856.c | 18 +- drivers/media/video/bt8xx/Kconfig | 25 - drivers/media/video/bt8xx/Makefile | 12 - drivers/media/video/bt8xx/bttv-input.c | 450 - drivers/media/video/{bt8xx => }/bttv-cards.c | 335 +- drivers/media/video/{bt8xx => }/bttv-driver.c | 351 +- drivers/media/video/{bt8xx => }/bttv-gpio.c | 0 drivers/media/video/{bt8xx => }/bttv-i2c.c | 4 - drivers/media/video/{bt8xx => }/bttv-if.c | 0 drivers/media/video/{bt8xx => }/bttv-risc.c | 31 +- drivers/media/video/{bt8xx => }/bttv-vbi.c | 8 +- drivers/media/video/{bt8xx => }/bttv.h | 23 +- drivers/media/video/{bt8xx => }/bttvp.h | 7 +- drivers/media/video/bw-qcam.c | 122 +- drivers/media/video/bw-qcam.h | 2 +- drivers/media/video/c-qcam.c | 85 +- drivers/media/video/cpia.c | 763 +- drivers/media/video/cpia.h | 55 +- drivers/media/video/cpia2/Kconfig | 9 - drivers/media/video/cpia2/Makefile | 3 - drivers/media/video/cpia2/cpia2.h | 497 - drivers/media/video/cpia2/cpia2_core.c | 2525 -- drivers/media/video/cpia2/cpia2_registers.h | 476 - drivers/media/video/cpia2/cpia2_usb.c | 907 - drivers/media/video/cpia2/cpia2_v4l.c | 2080 -- drivers/media/video/cpia2/cpia2dev.h | 50 - drivers/media/video/cpia2/cpia2patch.h | 233 - drivers/media/video/cpia_pp.c | 108 +- drivers/media/video/cpia_usb.c | 40 +- drivers/media/video/cs53l32a.c | 20 +- drivers/media/video/cs8420.h | 2 +- drivers/media/video/cx25840/Kconfig | 9 - drivers/media/video/cx25840/Makefile | 4 +- drivers/media/video/cx25840/cx25840-audio.c | 4 +- drivers/media/video/cx25840/cx25840-core.c | 113 +- drivers/media/video/cx25840/cx25840-core.h | 67 - .../media/video/cx25840/cx25840-firmware.c | 64 +- drivers/media/video/cx25840/cx25840-vbi.c | 3 +- drivers/media/video/cx88/Kconfig | 31 +- drivers/media/video/cx88/Makefile | 7 +- drivers/media/video/cx88/cx88-alsa.c | 70 +- drivers/media/video/cx88/cx88-blackbird.c | 5 +- drivers/media/video/cx88/cx88-cards.c | 115 +- drivers/media/video/cx88/cx88-core.c | 31 +- drivers/media/video/cx88/cx88-dvb.c | 115 +- drivers/media/video/cx88/cx88-input.c | 339 +- drivers/media/video/cx88/cx88-mpeg.c | 28 +- drivers/media/video/cx88/cx88-tvaudio.c | 3 - drivers/media/video/cx88/cx88-vbi.c | 7 +- drivers/media/video/cx88/cx88-video.c | 92 +- drivers/media/video/cx88/cx88.h | 15 +- drivers/media/video/dpc7146.c | 58 +- drivers/media/video/em28xx/Kconfig | 3 +- drivers/media/video/em28xx/Makefile | 2 +- drivers/media/video/em28xx/em28xx-cards.c | 81 +- drivers/media/video/em28xx/em28xx-i2c.c | 1 + drivers/media/video/em28xx/em28xx-input.c | 85 + drivers/media/video/em28xx/em28xx-video.c | 1604 +- drivers/media/video/em28xx/em28xx.h | 9 +- drivers/media/video/et61x251/Kconfig | 14 - drivers/media/video/et61x251/Makefile | 4 - drivers/media/video/et61x251/et61x251.h | 234 - drivers/media/video/et61x251/et61x251_core.c | 2630 -- .../media/video/et61x251/et61x251_sensor.h | 116 - .../video/et61x251/et61x251_tas5130d1b.c | 141 - drivers/media/video/font.h | 407 - drivers/media/video/hexium_gemini.c | 10 +- drivers/media/video/hexium_orion.c | 18 +- drivers/media/video/ir-kbd-i2c.c | 53 +- drivers/media/video/meye.c | 112 +- drivers/media/video/meye.h | 4 +- drivers/media/video/msp3400-driver.c | 384 +- drivers/media/video/msp3400-kthreads.c | 663 +- .../video/{msp3400-driver.h => msp3400.h} | 44 +- drivers/media/video/mxb.c | 158 +- drivers/media/video/mxb.h | 2 +- .../media/video/ovcamchip/ovcamchip_core.c | 23 +- drivers/media/video/planb.c | 138 +- drivers/media/video/planb.h | 8 +- drivers/media/video/pms.c | 164 +- drivers/media/video/pwc/Kconfig | 28 - drivers/media/video/pwc/Makefile | 3 - drivers/media/video/pwc/pwc-kiara.c | 318 - drivers/media/video/pwc/pwc-timon.c | 316 - drivers/media/video/saa5246a.c | 10 +- drivers/media/video/saa5249.c | 122 +- drivers/media/video/saa6588.c | 2 +- drivers/media/video/saa7110.c | 24 +- drivers/media/video/saa7111.c | 31 +- drivers/media/video/saa7114.c | 36 +- drivers/media/video/saa7115.c | 143 +- drivers/media/video/saa711x.c | 1 + drivers/media/video/saa7121.h | 6 +- drivers/media/video/saa7127.c | 43 +- drivers/media/video/saa7134/Makefile | 6 +- drivers/media/video/saa7134/saa7134-alsa.c | 94 +- drivers/media/video/saa7134/saa7134-cards.c | 26 +- drivers/media/video/saa7134/saa7134-core.c | 60 +- drivers/media/video/saa7134/saa7134-dvb.c | 41 +- drivers/media/video/saa7134/saa7134-empress.c | 8 +- drivers/media/video/saa7134/saa7134-input.c | 542 +- drivers/media/video/saa7134/saa7134-oss.c | 62 +- drivers/media/video/saa7134/saa7134-ts.c | 9 +- drivers/media/video/saa7134/saa7134-tvaudio.c | 16 - drivers/media/video/saa7134/saa7134-vbi.c | 10 +- drivers/media/video/saa7134/saa7134-video.c | 81 +- drivers/media/video/saa7134/saa7134.h | 16 +- drivers/media/video/saa7146.h | 10 +- drivers/media/video/saa7146reg.h | 4 +- drivers/media/video/saa7185.c | 22 +- drivers/media/video/saa7196.h | 4 +- drivers/media/video/sn9c102/Kconfig | 11 - drivers/media/video/sn9c102/Makefile | 7 - drivers/media/video/sn9c102/sn9c102_ov7630.c | 401 - .../media/video/sn9c102/sn9c102_pas202bca.c | 238 - drivers/media/video/stradis.c | 11 +- drivers/media/video/tda7432.c | 5 +- drivers/media/video/tda8290.c | 687 +- drivers/media/video/tda9840.c | 7 +- drivers/media/video/tda9840.h | 2 +- drivers/media/video/tda9875.c | 9 +- drivers/media/video/tea6415c.c | 7 +- drivers/media/video/tea6420.c | 9 +- drivers/media/video/tea6420.h | 4 +- drivers/media/video/tuner-3036.c | 50 +- drivers/media/video/tuner-core.c | 82 +- drivers/media/video/tuner-simple.c | 168 +- drivers/media/video/tuner-types.c | 600 +- drivers/media/video/tvaudio.c | 165 +- drivers/media/video/tvaudio.h | 14 + drivers/media/video/tveeprom.c | 38 +- drivers/media/video/tvp5150.c | 819 +- drivers/media/video/tvp5150_reg.h | 125 +- drivers/media/video/upd64031a.c | 286 - drivers/media/video/upd64083.c | 262 - drivers/media/video/usbvideo/Kconfig | 38 - drivers/media/video/usbvideo/Makefile | 4 - drivers/media/video/v4l2-common.c | 564 +- drivers/media/video/video-buf-dvb.c | 10 +- drivers/media/video/video-buf.c | 315 +- drivers/media/video/videocodec.h | 52 +- drivers/media/video/videodev.c | 24 +- drivers/media/video/vino.c | 37 +- drivers/media/video/vivi.c | 1459 -- drivers/media/video/vpx3220.c | 21 +- drivers/media/video/w9966.c | 102 +- drivers/media/video/wm8739.c | 355 - drivers/media/video/wm8775.c | 20 +- drivers/media/video/zc0301/Kconfig | 11 - drivers/media/video/zc0301/Makefile | 3 - drivers/media/video/zc0301/zc0301.h | 192 - drivers/media/video/zc0301/zc0301_core.c | 2055 -- drivers/media/video/zc0301/zc0301_pas202bcb.c | 361 - drivers/media/video/zc0301/zc0301_sensor.h | 103 - drivers/media/video/zoran.h | 4 +- drivers/media/video/zoran_card.c | 51 +- drivers/media/video/zoran_card.h | 2 +- drivers/media/video/zoran_device.c | 16 +- drivers/media/video/zoran_device.h | 2 +- drivers/media/video/zoran_driver.c | 243 +- drivers/media/video/zoran_procfs.c | 2 +- drivers/media/video/zoran_procfs.h | 2 +- drivers/media/video/zr36016.c | 22 +- drivers/media/video/zr36050.c | 16 +- drivers/media/video/zr36057.h | 10 +- drivers/media/video/zr36060.c | 20 +- drivers/media/video/zr36120.c | 54 +- drivers/media/video/zr36120.h | 6 +- drivers/message/fusion/Kconfig | 1 - drivers/message/fusion/Makefile | 1 - drivers/message/fusion/lsi/mpi_log_sas.h | 105 +- drivers/message/fusion/mptbase.c | 258 +- drivers/message/fusion/mptbase.h | 42 +- drivers/message/fusion/mptctl.c | 8 +- drivers/message/fusion/mptfc.c | 171 +- drivers/message/fusion/mptlan.c | 5 +- drivers/message/fusion/mptsas.c | 925 +- drivers/message/fusion/mptscsih.c | 2542 +- drivers/message/fusion/mptscsih.h | 12 +- drivers/message/fusion/mptspi.c | 805 +- drivers/message/i2o/debug.c | 31 +- drivers/message/i2o/exec-osm.c | 21 +- drivers/message/i2o/i2o_block.c | 7 +- drivers/message/i2o/i2o_proc.c | 2 +- drivers/mfd/Kconfig | 1 - drivers/misc/ibmasm/heartbeat.c | 5 +- drivers/misc/ibmasm/ibmasmfs.c | 2 +- drivers/mmc/Kconfig | 42 +- drivers/mmc/Makefile | 8 - drivers/mmc/at91_mci.c | 985 - drivers/mmc/au1xmmc.c | 29 +- drivers/mmc/imxmmc.c | 1128 - drivers/mmc/imxmmc.h | 67 - drivers/mmc/mmc.c | 70 +- drivers/mmc/mmc_block.c | 56 +- drivers/mmc/mmci.c | 7 + drivers/mmc/omap.c | 1226 - drivers/mmc/omap.h | 55 - drivers/mmc/pxamci.c | 39 +- drivers/mmc/sdhci.c | 1257 - drivers/mmc/sdhci.h | 185 - drivers/mmc/wbsd.c | 21 +- drivers/mtd/chips/Kconfig | 26 +- drivers/mtd/chips/amd_flash.c | 4 +- drivers/mtd/chips/jedec_probe.c | 19 +- drivers/mtd/chips/sharp.c | 7 +- drivers/mtd/cmdlinepart.c | 7 +- drivers/mtd/devices/Kconfig | 13 +- drivers/mtd/devices/Makefile | 1 + drivers/mtd/devices/blkmtd.c | 820 + drivers/mtd/devices/block2mtd.c | 13 +- drivers/mtd/devices/doc2000.c | 37 +- drivers/mtd/devices/lart.c | 10 +- drivers/mtd/devices/m25p80.c | 2 +- drivers/mtd/devices/ms02-nv.c | 2 +- drivers/mtd/devices/mtd_dataflash.c | 2 +- drivers/mtd/inftlcore.c | 7 +- drivers/mtd/maps/alchemy-flash.c | 4 +- drivers/mtd/maps/cfi_flagadm.c | 2 +- drivers/mtd/maps/dbox2-flash.c | 2 +- drivers/mtd/maps/dilnetpc.c | 12 +- drivers/mtd/maps/dmv182.c | 2 +- drivers/mtd/maps/h720x-flash.c | 2 +- drivers/mtd/maps/netsc520.c | 4 +- drivers/mtd/maps/nettel.c | 3 +- drivers/mtd/maps/ocotea.c | 6 +- drivers/mtd/maps/pci.c | 3 + drivers/mtd/maps/pcmciamtd.c | 131 +- drivers/mtd/maps/redwood.c | 3 +- drivers/mtd/maps/sbc8240.c | 8 +- drivers/mtd/maps/sc520cdp.c | 2 +- drivers/mtd/maps/scx200_docflash.c | 2 +- drivers/mtd/maps/sharpsl-flash.c | 35 +- drivers/mtd/maps/ts5500_flash.c | 2 +- drivers/mtd/maps/uclinux.c | 2 +- drivers/mtd/maps/vmax301.c | 2 +- drivers/mtd/mtd_blkdevs.c | 35 +- drivers/mtd/mtdblock.c | 14 +- drivers/mtd/mtdconcat.c | 6 +- drivers/mtd/mtdcore.c | 45 +- drivers/mtd/nand/au1550nd.c | 4 +- drivers/mtd/nand/nand_base.c | 26 +- drivers/mtd/redboot.c | 6 +- drivers/net/3c509.c | 70 +- drivers/net/3c523.c | 9 +- drivers/net/3c59x.c | 273 +- drivers/net/7990.c | 2 +- drivers/net/8139cp.c | 16 +- drivers/net/8139too.c | 8 +- drivers/net/82596.c | 2 +- drivers/net/8390.h | 2 +- drivers/net/Kconfig | 34 +- drivers/net/Makefile | 5 +- drivers/net/a2065.c | 2 +- drivers/net/acenic_firmware.h | 10 +- drivers/net/apne.c | 7 +- drivers/net/arcnet/Kconfig | 4 +- drivers/net/arcnet/arc-rawmode.c | 2 +- drivers/net/arcnet/arc-rimi.c | 68 +- drivers/net/arcnet/arcnet.c | 23 +- drivers/net/arcnet/com90xx.c | 132 +- drivers/net/arcnet/rfc1051.c | 2 +- drivers/net/arcnet/rfc1201.c | 2 +- drivers/net/ariadne.c | 2 +- drivers/net/arm/Kconfig | 8 - drivers/net/arm/Makefile | 1 - drivers/net/arm/am79c961a.c | 4 +- drivers/net/arm/at91_ether.c | 1110 - drivers/net/arm/at91_ether.h | 101 - drivers/net/arm/etherh.c | 3 +- drivers/net/atari_bionet.c | 2 +- drivers/net/atari_pamsnet.c | 2 +- drivers/net/atarilance.c | 2 +- drivers/net/au1000_eth.c | 36 +- drivers/net/b44.c | 106 +- drivers/net/bnx2.c | 615 +- drivers/net/bnx2.h | 97 +- drivers/net/bnx2_fw.h | 84 +- drivers/net/bonding/bond_3ad.c | 28 - drivers/net/bonding/bond_3ad.h | 1 - drivers/net/bonding/bond_alb.c | 2 +- drivers/net/bonding/bond_main.c | 153 +- drivers/net/bonding/bond_sysfs.c | 6 - drivers/net/bonding/bonding.h | 33 +- drivers/net/cassini.c | 51 +- drivers/net/cassini.h | 2 +- drivers/net/chelsio/Makefile | 2 +- drivers/net/chelsio/cxgb2.c | 2 +- drivers/net/chelsio/espi.c | 14 +- drivers/net/chelsio/sge.c | 7 +- drivers/net/chelsio/subr.c | 2 +- drivers/net/depca.c | 2 +- drivers/net/dgrs.c | 16 +- drivers/net/dgrs_firmware.c | 4 +- drivers/net/dl2k.c | 17 +- drivers/net/e100.c | 6 +- drivers/net/e1000/e1000.h | 68 +- drivers/net/e1000/e1000_ethtool.c | 115 +- drivers/net/e1000/e1000_hw.c | 735 +- drivers/net/e1000/e1000_hw.h | 320 +- drivers/net/e1000/e1000_main.c | 635 +- drivers/net/e1000/e1000_param.c | 2 +- drivers/net/eepro100.c | 4 +- drivers/net/epic100.c | 4 +- drivers/net/eql.c | 3 +- drivers/net/eth16i.c | 11 +- drivers/net/fealnx.c | 2 +- drivers/net/fec_8xx/fec_main.c | 4 +- drivers/net/forcedeth.c | 781 +- drivers/net/fs_enet/fs_enet-main.c | 4 +- drivers/net/fs_enet/mac-fcc.c | 2 - drivers/net/fs_enet/mac-fec.c | 2 - drivers/net/fs_enet/mac-scc.c | 2 - drivers/net/gianfar.c | 60 +- drivers/net/gianfar.h | 67 +- drivers/net/gianfar_ethtool.c | 20 +- drivers/net/gianfar_sysfs.c | 24 +- drivers/net/gt96100eth.c | 4 +- drivers/net/hamachi.c | 2 +- drivers/net/hamradio/6pack.c | 10 +- drivers/net/hamradio/baycom_epp.c | 2 +- drivers/net/hamradio/dmascc.c | 3 +- drivers/net/hamradio/mkiss.c | 10 +- drivers/net/hamradio/scc.c | 1 + drivers/net/hamradio/yam.c | 1 + drivers/net/hp-plus.c | 17 +- drivers/net/hp100.c | 35 +- drivers/net/hplance.c | 2 +- drivers/net/hydra.c | 2 +- drivers/net/hydra.h | 177 + drivers/net/ibm_emac/ibm_emac_core.c | 40 +- drivers/net/ibm_emac/ibm_emac_core.h | 2 +- drivers/net/ibm_emac/ibm_emac_debug.c | 2 +- drivers/net/ibm_emac/ibm_emac_rgmii.h | 2 +- drivers/net/ibm_emac/ibm_emac_zmii.c | 7 +- drivers/net/ibm_emac/ibm_emac_zmii.h | 2 +- drivers/net/ibmveth.c | 30 +- drivers/net/ifb.c | 10 +- drivers/net/ioc3-eth.c | 7 +- drivers/net/irda/Kconfig | 30 +- drivers/net/irda/Makefile | 3 +- drivers/net/irda/donauboe.c | 2 +- drivers/net/irda/ep7211_ir.c | 11 +- drivers/net/irda/irda-usb.c | 365 +- drivers/net/irda/irda-usb.h | 43 +- drivers/net/irda/irport.c | 4 +- drivers/net/irda/irtty-sir.c | 19 +- drivers/net/irda/nsc-ircc.c | 322 +- drivers/net/irda/nsc-ircc.h | 2 +- drivers/net/irda/sa1100_ir.c | 3 +- drivers/net/irda/sir-dev.h | 13 +- drivers/net/irda/sir_dev.c | 315 +- drivers/net/irda/sir_dongle.c | 19 +- drivers/net/irda/sir_kthread.c | 508 + drivers/net/irda/smsc-ircc2.c | 537 +- drivers/net/irda/toim3232-sir.c | 375 - drivers/net/irda/vlsi_ir.c | 4 +- drivers/net/ixgb/ixgb_main.c | 17 +- drivers/net/ixp2000/enp2611.c | 15 +- drivers/net/ixp2000/ixpdev.c | 7 +- drivers/net/ixp2000/pm3386.c | 30 +- drivers/net/ixp2000/pm3386.h | 1 - drivers/net/lance.c | 9 +- drivers/net/lasi_82596.c | 6 +- drivers/net/loopback.c | 8 +- drivers/net/mac89x0.c | 2 +- drivers/net/mace.c | 2 +- drivers/net/macsonic.c | 2 +- drivers/net/mambonet.c | 392 - drivers/net/meth.c | 2 +- drivers/net/mv643xx_eth.c | 1571 +- drivers/net/mv643xx_eth.h | 256 +- drivers/net/natsemi.c | 216 +- drivers/net/ne-h8300.c | 19 +- drivers/net/ne.c | 40 +- drivers/net/ne2.c | 7 +- drivers/net/ne2k-pci.c | 4 +- drivers/net/netconsole.c | 5 +- drivers/net/ni5010.c | 4 +- drivers/net/ns83820.c | 17 +- drivers/net/oaknet.c | 3 +- drivers/net/pcmcia/3c574_cs.c | 117 +- drivers/net/pcmcia/3c589_cs.c | 127 +- drivers/net/pcmcia/axnet_cs.c | 180 +- drivers/net/pcmcia/com20020_cs.c | 127 +- drivers/net/pcmcia/fmvj18x_cs.c | 168 +- drivers/net/pcmcia/ibmtr_cs.c | 121 +- drivers/net/pcmcia/nmclan_cs.c | 130 +- drivers/net/pcmcia/pcnet_cs.c | 165 +- drivers/net/pcmcia/smc91c92_cs.c | 239 +- drivers/net/pcmcia/xirc2ps_cs.c | 207 +- drivers/net/pcnet32.c | 4143 ++- drivers/net/phy/mdio_bus.c | 4 +- drivers/net/phy/phy.c | 2 +- drivers/net/plip.c | 4 +- drivers/net/ppp_async.c | 3 +- drivers/net/ppp_generic.c | 29 +- drivers/net/ppp_synctty.c | 2 +- drivers/net/pppoe.c | 7 +- drivers/net/r8169.c | 42 +- drivers/net/s2io.c | 635 +- drivers/net/s2io.h | 55 +- drivers/net/sb1000.c | 2 +- drivers/net/sb1250-mac.c | 109 +- drivers/net/seeq8005.c | 5 +- drivers/net/sgiseeq.c | 17 +- drivers/net/shaper.c | 3 +- drivers/net/sis190.c | 2 +- drivers/net/sis900.c | 16 +- drivers/net/sk98lin/h/skaddr.h | 48 + drivers/net/sk98lin/h/skcsum.h | 6 + drivers/net/sk98lin/h/skgeinit.h | 56 + drivers/net/sk98lin/h/skgepnmi.h | 4 + drivers/net/sk98lin/h/skgesirq.h | 1 + drivers/net/sk98lin/h/ski2c.h | 3 + drivers/net/sk98lin/h/skvpd.h | 15 + drivers/net/sk98lin/skaddr.c | 35 +- drivers/net/sk98lin/skge.c | 2 +- drivers/net/sk98lin/skgeinit.c | 148 +- drivers/net/sk98lin/skgemib.c | 7 + drivers/net/sk98lin/skgepnmi.c | 153 +- drivers/net/sk98lin/skgesirq.c | 24 +- drivers/net/sk98lin/ski2c.c | 6 +- drivers/net/sk98lin/sklm80.c | 72 + drivers/net/sk98lin/skrlmt.c | 1 + drivers/net/sk98lin/skvpd.c | 108 +- drivers/net/sk98lin/skxmac2.c | 461 +- drivers/net/skfp/fplustm.c | 26 +- drivers/net/skfp/pcmplc.c | 4 +- drivers/net/skfp/skfddi.c | 2 +- drivers/net/skge.c | 348 +- drivers/net/skge.h | 2 + drivers/net/sky2.c | 814 +- drivers/net/sky2.h | 103 +- drivers/net/smc91x.c | 57 +- drivers/net/smc91x.h | 474 +- drivers/net/spider_net.c | 16 +- drivers/net/spider_net.h | 2 - drivers/net/starfire.c | 45 +- drivers/net/sun3lance.c | 2 +- drivers/net/sundance.c | 14 +- drivers/net/sungem.c | 37 +- drivers/net/sungem.h | 6 +- drivers/net/sungem_phy.c | 58 +- drivers/net/sungem_phy.h | 1 - drivers/net/tg3.c | 1120 +- drivers/net/tg3.h | 34 +- drivers/net/tokenring/Kconfig | 2 +- drivers/net/tokenring/abyss.c | 3 +- drivers/net/tokenring/ibmtr.c | 13 +- drivers/net/tokenring/lanstreamer.c | 3 +- drivers/net/tokenring/madgemc.c | 3 +- drivers/net/tokenring/olympic.c | 9 +- drivers/net/tulip/de2104x.c | 20 +- drivers/net/tulip/de4x5.c | 4 +- drivers/net/tulip/pnic.c | 3 +- drivers/net/tulip/pnic2.c | 2 +- drivers/net/tulip/winbond-840.c | 15 +- drivers/net/tulip/xircom_cb.c | 9 +- drivers/net/typhoon.c | 14 +- drivers/net/via-rhine.c | 54 +- drivers/net/via-velocity.c | 27 +- drivers/net/wan/Kconfig | 97 + drivers/net/wan/Makefile | 13 + drivers/net/wan/dscc4.c | 7 +- drivers/net/wan/hostess_sv11.c | 1 - drivers/net/wan/sbni.c | 3 +- drivers/net/wan/sdla_chdlc.c | 4428 ++++ drivers/net/wan/sdla_fr.c | 5061 ++++ drivers/net/wan/sdla_ft1.c | 345 + drivers/net/wan/sdla_ppp.c | 3430 +++ drivers/net/wan/sdla_x25.c | 5497 ++++ drivers/net/wan/sdladrv.c | 2314 ++ drivers/net/wan/sdlamain.c | 1346 + drivers/net/wan/sealevel.c | 1 - drivers/net/wan/wanpipe_multppp.c | 2358 ++ drivers/net/wan/wanxl.c | 4 +- drivers/net/wireless/Kconfig | 53 +- drivers/net/wireless/Makefile | 1 - drivers/net/wireless/airo.c | 819 +- drivers/net/wireless/airo_cs.c | 158 +- drivers/net/wireless/arlan-main.c | 4 +- drivers/net/wireless/atmel.c | 121 +- drivers/net/wireless/atmel_cs.c | 162 +- drivers/net/wireless/bcm43xx/Kconfig | 65 - drivers/net/wireless/bcm43xx/Makefile | 12 - drivers/net/wireless/bcm43xx/bcm43xx.h | 937 - .../net/wireless/bcm43xx/bcm43xx_debugfs.c | 499 - .../net/wireless/bcm43xx/bcm43xx_debugfs.h | 117 - drivers/net/wireless/bcm43xx/bcm43xx_dma.c | 982 - drivers/net/wireless/bcm43xx/bcm43xx_dma.h | 226 - .../net/wireless/bcm43xx/bcm43xx_ethtool.c | 50 - .../net/wireless/bcm43xx/bcm43xx_ethtool.h | 8 - drivers/net/wireless/bcm43xx/bcm43xx_ilt.c | 337 - drivers/net/wireless/bcm43xx/bcm43xx_ilt.h | 32 - drivers/net/wireless/bcm43xx/bcm43xx_leds.c | 293 - drivers/net/wireless/bcm43xx/bcm43xx_leds.h | 56 - drivers/net/wireless/bcm43xx/bcm43xx_main.c | 3984 --- drivers/net/wireless/bcm43xx/bcm43xx_main.h | 170 - drivers/net/wireless/bcm43xx/bcm43xx_phy.c | 2346 -- drivers/net/wireless/bcm43xx/bcm43xx_phy.h | 74 - drivers/net/wireless/bcm43xx/bcm43xx_pio.c | 638 - drivers/net/wireless/bcm43xx/bcm43xx_pio.h | 150 - drivers/net/wireless/bcm43xx/bcm43xx_power.c | 379 - drivers/net/wireless/bcm43xx/bcm43xx_power.h | 56 - drivers/net/wireless/bcm43xx/bcm43xx_radio.c | 2026 -- drivers/net/wireless/bcm43xx/bcm43xx_radio.h | 99 - drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 341 - drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h | 9 - drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 1005 - drivers/net/wireless/bcm43xx/bcm43xx_wx.h | 36 - drivers/net/wireless/bcm43xx/bcm43xx_xmit.c | 582 - drivers/net/wireless/bcm43xx/bcm43xx_xmit.h | 156 - drivers/net/wireless/hostap/hostap_80211.h | 2 + drivers/net/wireless/hostap/hostap_80211_tx.c | 7 +- drivers/net/wireless/hostap/hostap_ap.c | 2 +- drivers/net/wireless/hostap/hostap_cs.c | 200 +- drivers/net/wireless/hostap/hostap_hw.c | 8 +- drivers/net/wireless/hostap/hostap_ioctl.c | 8 +- drivers/net/wireless/hostap/hostap_pci.c | 4 +- drivers/net/wireless/hostap/hostap_plx.c | 13 +- drivers/net/wireless/ipw2100.c | 266 +- drivers/net/wireless/ipw2100.h | 17 +- drivers/net/wireless/ipw2200.c | 1227 +- drivers/net/wireless/ipw2200.h | 103 +- drivers/net/wireless/netwave_cs.c | 129 +- drivers/net/wireless/orinoco.c | 12 +- drivers/net/wireless/orinoco_cs.c | 187 +- drivers/net/wireless/prism54/isl_ioctl.c | 2 +- drivers/net/wireless/prism54/islpci_hotplug.c | 3 +- drivers/net/wireless/prism54/oid_mgt.c | 4 +- drivers/net/wireless/ray_cs.c | 279 +- drivers/net/wireless/ray_cs.h | 2 +- drivers/net/wireless/spectrum_cs.c | 175 +- drivers/net/wireless/strip.c | 4 +- drivers/net/wireless/wavelan.c | 2 +- drivers/net/wireless/wavelan.p.h | 6 +- drivers/net/wireless/wavelan_cs.c | 189 +- drivers/net/wireless/wavelan_cs.p.h | 15 +- drivers/net/wireless/wl3501.h | 1 - drivers/net/wireless/wl3501_cs.c | 178 +- drivers/net/yellowfin.c | 9 +- drivers/net/zorro8390.c | 9 +- drivers/oprofile/buffer_sync.c | 66 +- drivers/oprofile/cpu_buffer.c | 67 +- drivers/oprofile/cpu_buffer.h | 9 +- drivers/oprofile/event_buffer.h | 7 +- drivers/oprofile/oprof.c | 34 +- drivers/oprofile/oprof.h | 7 +- drivers/oprofile/oprofile_files.c | 205 +- drivers/oprofile/oprofile_stats.c | 4 +- drivers/oprofile/oprofilefs.c | 6 +- drivers/parisc/ccio-dma.c | 2 +- drivers/parisc/dino.c | 5 +- drivers/parisc/eisa.c | 2 +- drivers/parisc/iosapic.c | 2 +- drivers/parisc/lba_pci.c | 8 +- drivers/parisc/led.c | 14 +- drivers/parisc/pdc_stable.c | 7 +- drivers/parisc/power.c | 6 +- drivers/parisc/sba_iommu.c | 61 +- drivers/parisc/superio.c | 59 +- drivers/parport/Kconfig | 2 +- drivers/parport/parport_cs.c | 129 +- drivers/parport/parport_pc.c | 51 +- drivers/parport/parport_serial.c | 77 +- drivers/parport/share.c | 19 +- drivers/pci/Kconfig | 22 +- drivers/pci/hotplug/Makefile | 20 +- drivers/pci/hotplug/acpiphp.h | 62 +- drivers/pci/hotplug/acpiphp_core.c | 134 +- drivers/pci/hotplug/acpiphp_dock.c | 438 - drivers/pci/hotplug/acpiphp_glue.c | 356 +- drivers/pci/hotplug/cpci_hotplug_core.c | 9 +- drivers/pci/hotplug/cpqphp.h | 3 +- drivers/pci/hotplug/cpqphp_core.c | 27 +- drivers/pci/hotplug/cpqphp_ctrl.c | 124 +- drivers/pci/hotplug/fakephp.c | 9 +- drivers/pci/hotplug/ibmphp.h | 2 + drivers/pci/hotplug/ibmphp_core.c | 10 +- drivers/pci/hotplug/ibmphp_ebda.c | 59 +- drivers/pci/hotplug/ibmphp_hpc.c | 64 +- drivers/pci/hotplug/ibmphp_pci.c | 121 +- drivers/pci/hotplug/ibmphp_res.c | 81 +- drivers/pci/hotplug/pci_hotplug.h | 16 - drivers/pci/hotplug/pciehp.h | 27 +- drivers/pci/hotplug/pciehp_core.c | 19 +- drivers/pci/hotplug/pciehp_ctrl.c | 68 +- drivers/pci/hotplug/pciehp_hpc.c | 77 +- drivers/pci/hotplug/pciehprm_acpi.c | 257 + drivers/pci/hotplug/pciehprm_nonacpi.c | 47 + drivers/pci/hotplug/pcihp_skeleton.c | 33 +- drivers/pci/hotplug/rpadlpar_core.c | 12 +- drivers/pci/hotplug/rpaphp_core.c | 3 + drivers/pci/hotplug/rpaphp_slot.c | 9 +- drivers/pci/hotplug/sgi_hotplug.c | 35 +- drivers/pci/hotplug/shpchp.h | 108 +- drivers/pci/hotplug/shpchp_core.c | 331 +- drivers/pci/hotplug/shpchp_ctrl.c | 808 +- drivers/pci/hotplug/shpchp_hpc.c | 518 +- drivers/pci/hotplug/shpchp_pci.c | 10 +- .../hotplug/{acpi_pcihp.c => shpchprm_acpi.c} | 145 +- drivers/pci/hotplug/shpchprm_legacy.c | 54 + drivers/pci/hotplug/shpchprm_nonacpi.c | 57 + drivers/pci/msi.c | 334 +- drivers/pci/pci-driver.c | 31 +- drivers/pci/pci-sysfs.c | 3 +- drivers/pci/pci.c | 52 +- drivers/pci/pci.h | 13 - drivers/pci/pcie/portdrv.h | 5 + drivers/pci/pcie/portdrv_core.c | 155 +- drivers/pci/pcie/portdrv_pci.c | 66 +- drivers/pci/probe.c | 34 +- drivers/pci/proc.c | 126 + drivers/pci/quirks.c | 199 +- drivers/pci/search.c | 4 +- drivers/pcmcia/Kconfig | 9 +- drivers/pcmcia/Makefile | 3 +- drivers/pcmcia/at91_cf.c | 376 - drivers/pcmcia/cistpl.c | 1 + drivers/pcmcia/cs.c | 43 +- drivers/pcmcia/cs_internal.h | 19 +- drivers/pcmcia/ds.c | 265 +- drivers/pcmcia/ds_internal.h | 4 +- drivers/pcmcia/i82092.c | 1 + drivers/pcmcia/i82365.c | 8 +- drivers/pcmcia/omap_cf.c | 2 +- drivers/pcmcia/pcmcia_compat.c | 65 + drivers/pcmcia/pcmcia_ioctl.c | 92 +- drivers/pcmcia/pcmcia_resource.c | 232 +- drivers/pcmcia/pd6729.c | 3 +- drivers/pcmcia/pxa2xx_sharpsl.c | 227 +- drivers/pcmcia/rsrc_mgr.c | 5 +- drivers/pcmcia/rsrc_nonstatic.c | 41 +- drivers/pcmcia/sa1100_cerf.c | 1 + drivers/pcmcia/socket_sysfs.c | 224 +- drivers/pcmcia/ti113x.h | 1 + drivers/pcmcia/vrc4171_card.c | 12 +- drivers/pcmcia/vrc4173_cardu.c | 8 +- drivers/pnp/card.c | 16 +- drivers/pnp/driver.c | 19 +- drivers/pnp/isapnp/core.c | 11 +- drivers/pnp/manager.c | 4 +- drivers/pnp/pnpbios/rsparser.c | 6 +- drivers/pnp/resource.c | 3 +- drivers/rtc/Kconfig | 175 - drivers/rtc/Makefile | 22 - drivers/rtc/class.c | 147 - drivers/rtc/hctosys.c | 69 - drivers/rtc/interface.c | 277 - drivers/rtc/rtc-dev.c | 387 - drivers/rtc/rtc-ds1672.c | 277 - drivers/rtc/rtc-ep93xx.c | 160 - drivers/rtc/rtc-lib.c | 101 - drivers/rtc/rtc-m48t86.c | 204 - drivers/rtc/rtc-pcf8563.c | 342 - drivers/rtc/rtc-proc.c | 164 - drivers/rtc/rtc-rs5c372.c | 290 - drivers/rtc/rtc-sa1100.c | 384 - drivers/rtc/rtc-sysfs.c | 124 - drivers/rtc/rtc-test.c | 201 - drivers/rtc/rtc-x1205.c | 614 - drivers/s390/Kconfig | 8 +- drivers/s390/block/Kconfig | 14 +- drivers/s390/block/Makefile | 4 +- drivers/s390/block/dasd.c | 102 +- drivers/s390/block/dasd_3990_erp.c | 3 - drivers/s390/block/dasd_cmb.c | 128 + drivers/s390/block/dasd_devmap.c | 152 +- drivers/s390/block/dasd_eckd.c | 193 +- drivers/s390/block/dasd_eckd.h | 47 +- drivers/s390/block/dasd_eer.c | 682 - drivers/s390/block/dasd_erp.c | 8 +- drivers/s390/block/dasd_int.h | 72 +- drivers/s390/block/dasd_ioctl.c | 322 +- drivers/s390/block/dasd_proc.c | 17 - drivers/s390/block/dcssblk.c | 11 +- drivers/s390/char/Makefile | 1 - drivers/s390/char/fs3270.c | 3 +- drivers/s390/char/keyboard.c | 14 +- drivers/s390/char/monreader.c | 6 +- drivers/s390/char/raw3270.c | 42 +- drivers/s390/char/sclp_rw.c | 2 +- drivers/s390/char/tape.h | 1 - drivers/s390/char/tape_34xx.c | 8 +- drivers/s390/char/tape_3590.c | 1301 - drivers/s390/char/tape_3590.h | 124 - drivers/s390/char/tape_block.c | 17 +- drivers/s390/char/tape_class.c | 3 +- drivers/s390/char/tape_core.c | 67 +- drivers/s390/char/tape_std.c | 15 +- drivers/s390/char/tape_std.h | 13 +- drivers/s390/char/tty3270.c | 9 +- drivers/s390/char/vmlogrdr.c | 3 +- drivers/s390/cio/blacklist.c | 4 +- drivers/s390/cio/ccwgroup.c | 3 +- drivers/s390/cio/chsc.c | 487 +- drivers/s390/cio/chsc.h | 22 +- drivers/s390/cio/cio.c | 2 +- drivers/s390/cio/cio_debug.h | 22 +- drivers/s390/cio/css.c | 44 +- drivers/s390/cio/css.h | 10 +- drivers/s390/cio/device.c | 6 +- drivers/s390/cio/device_fsm.c | 14 +- drivers/s390/cio/device_ops.c | 9 +- drivers/s390/cio/qdio.c | 54 +- drivers/s390/crypto/z90hardware.c | 10 +- drivers/s390/crypto/z90main.c | 15 +- drivers/s390/net/claw.c | 5 +- drivers/s390/net/ctcmain.c | 26 +- drivers/s390/net/ctctty.c | 10 +- drivers/s390/net/cu3088.c | 10 +- drivers/s390/net/fsm.c | 10 +- drivers/s390/net/iucv.c | 47 +- drivers/s390/net/iucv.h | 622 +- drivers/s390/net/lcs.c | 345 +- drivers/s390/net/lcs.h | 14 +- drivers/s390/net/netiucv.c | 43 +- drivers/s390/net/qeth.h | 18 +- drivers/s390/net/qeth_eddp.c | 43 +- drivers/s390/net/qeth_fs.h | 2 +- drivers/s390/net/qeth_main.c | 185 +- drivers/s390/net/qeth_mpc.h | 4 +- drivers/s390/net/qeth_proc.c | 64 +- drivers/s390/net/qeth_sys.c | 11 +- drivers/s390/net/qeth_tso.h | 6 +- drivers/s390/s390_rdev.c | 3 +- drivers/s390/s390mach.c | 34 +- drivers/s390/scsi/zfcp_aux.c | 60 +- drivers/sbus/char/bbc_i2c.c | 4 +- drivers/sbus/char/flash.c | 3 +- drivers/sbus/char/openprom.c | 15 +- drivers/scsi/3w-9xxx.c | 139 +- drivers/scsi/3w-9xxx.h | 19 +- drivers/scsi/53c700.c | 18 +- drivers/scsi/BusLogic.c | 10 +- drivers/scsi/FlashPoint.c | 9815 ++++---- drivers/scsi/Kconfig | 46 +- drivers/scsi/Makefile | 8 +- drivers/scsi/NCR_D700.c | 2 +- drivers/scsi/a100u2w.c | 3 +- drivers/scsi/aacraid/aachba.c | 95 +- drivers/scsi/aacraid/aacraid.h | 16 +- drivers/scsi/aacraid/commctrl.c | 12 - drivers/scsi/aacraid/comminit.c | 1 + drivers/scsi/aacraid/commsup.c | 55 +- drivers/scsi/aacraid/linit.c | 83 +- drivers/scsi/aacraid/rkt.c | 4 +- drivers/scsi/aacraid/rx.c | 4 +- drivers/scsi/aacraid/sa.c | 2 +- drivers/scsi/advansys.c | 14 +- drivers/scsi/aha152x.c | 7 +- drivers/scsi/ahci.c | 831 +- drivers/scsi/aic7xxx/Kconfig.aic7xxx | 2 +- drivers/scsi/aic7xxx/aic79xx.h | 4 +- drivers/scsi/aic7xxx/aic79xx_core.c | 199 +- drivers/scsi/aic7xxx/aic79xx_osm.c | 530 +- drivers/scsi/aic7xxx/aic79xx_osm.h | 7 +- drivers/scsi/aic7xxx/aic7xxx_core.c | 24 +- drivers/scsi/aic7xxx/aic7xxx_osm.c | 45 +- drivers/scsi/aic7xxx/aic7xxx_osm.h | 5 +- drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 1 - drivers/scsi/aic7xxx/aic7xxx_pci.c | 12 +- drivers/scsi/arm/cumana_2.c | 2 +- drivers/scsi/arm/eesox.c | 2 +- drivers/scsi/arm/powertec.c | 2 +- drivers/scsi/ata_piix.c | 398 +- drivers/scsi/atari_scsi.c | 10 +- drivers/scsi/atp870u.c | 3 +- drivers/scsi/ch.c | 1 - drivers/scsi/dmx3191d.c | 2 +- drivers/scsi/dpt_i2o.c | 5 +- drivers/scsi/eata.c | 3 +- drivers/scsi/g_NCR5380.c | 28 +- drivers/scsi/g_NCR5380.h | 23 +- drivers/scsi/gdth.c | 21 +- drivers/scsi/hosts.c | 15 +- drivers/scsi/hptiop.c | 943 + drivers/scsi/hptiop.h | 465 + drivers/scsi/ibmmca.c | 5 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 281 +- drivers/scsi/ibmvscsi/ibmvscsi.h | 2 +- drivers/scsi/ibmvscsi/rpa_vscsi.c | 11 +- drivers/scsi/ibmvscsi/srp.h | 227 + drivers/scsi/ibmvscsi/viosrp.h | 17 +- drivers/scsi/ide-scsi.c | 11 +- drivers/scsi/in2000.c | 24 +- drivers/scsi/initio.c | 3 +- drivers/scsi/ipr.c | 231 +- drivers/scsi/ipr.h | 250 +- drivers/scsi/ips.c | 7 +- drivers/scsi/iscsi_tcp.c | 6 +- drivers/scsi/jazz_esp.c | 19 +- drivers/scsi/lasi700.c | 2 +- drivers/scsi/libata-bmdma.c | 994 - drivers/scsi/libata-core.c | 3727 +-- drivers/scsi/libata-scsi.c | 454 +- drivers/scsi/libata.h | 6 +- drivers/scsi/lpfc/lpfc.h | 43 +- drivers/scsi/lpfc/lpfc_attr.c | 164 +- drivers/scsi/lpfc/lpfc_crtn.h | 38 +- drivers/scsi/lpfc/lpfc_ct.c | 74 +- drivers/scsi/lpfc/lpfc_disc.h | 20 +- drivers/scsi/lpfc/lpfc_els.c | 1069 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 591 +- drivers/scsi/lpfc/lpfc_hw.h | 68 +- drivers/scsi/lpfc/lpfc_init.c | 285 +- drivers/scsi/lpfc/lpfc_mbox.c | 56 +- drivers/scsi/lpfc/lpfc_mem.c | 22 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 513 +- drivers/scsi/lpfc/lpfc_scsi.c | 93 +- drivers/scsi/lpfc/lpfc_scsi.h | 5 +- drivers/scsi/lpfc/lpfc_sli.c | 470 +- drivers/scsi/lpfc/lpfc_sli.h | 5 +- drivers/scsi/lpfc/lpfc_version.h | 6 +- drivers/scsi/megaraid.c | 8 +- drivers/scsi/megaraid/megaraid_mbox.c | 61 +- drivers/scsi/megaraid/megaraid_mbox.h | 7 +- drivers/scsi/megaraid/megaraid_mm.c | 6 +- drivers/scsi/megaraid/megaraid_sas.c | 28 +- drivers/scsi/mesh.c | 2 +- drivers/scsi/ncr53c8xx.c | 127 +- drivers/scsi/ncr53c8xx.h | 37 +- drivers/scsi/nsp32.c | 3 +- drivers/scsi/osst.c | 533 +- drivers/scsi/osst.h | 12 +- drivers/scsi/pcmcia/aha152x_stub.c | 112 +- drivers/scsi/pcmcia/fdomain_stub.c | 155 +- drivers/scsi/pcmcia/nsp_cs.c | 136 +- drivers/scsi/pcmcia/nsp_cs.h | 8 +- drivers/scsi/pcmcia/qlogic_stub.c | 127 +- drivers/scsi/pcmcia/sym53c500_cs.c | 124 +- drivers/scsi/pdc_adma.c | 8 +- drivers/scsi/ppa.c | 10 +- drivers/scsi/psi240i.c | 2 +- drivers/scsi/qla1280.c | 5 +- drivers/scsi/qla2xxx/Kconfig | 31 +- drivers/scsi/qla2xxx/Makefile | 2 + drivers/scsi/qla2xxx/ql2300.c | 12 - drivers/scsi/qla2xxx/ql2300_fw.c | 14624 ++++++----- drivers/scsi/qla2xxx/ql2322.c | 12 - drivers/scsi/qla2xxx/ql2322_fw.c | 14135 ++++++----- drivers/scsi/qla2xxx/ql2400.c | 27 - drivers/scsi/qla2xxx/ql2400_fw.c | 20826 ++++++++-------- drivers/scsi/qla2xxx/ql6312.c | 101 + drivers/scsi/qla2xxx/ql6312_fw.c | 7078 ++++++ drivers/scsi/qla2xxx/qla_attr.c | 82 +- drivers/scsi/qla2xxx/qla_def.h | 126 +- drivers/scsi/qla2xxx/qla_devtbl.h | 219 +- drivers/scsi/qla2xxx/qla_fw.h | 2 +- drivers/scsi/qla2xxx/qla_gbl.h | 7 +- drivers/scsi/qla2xxx/qla_gs.c | 10 +- drivers/scsi/qla2xxx/qla_init.c | 39 +- drivers/scsi/qla2xxx/qla_inline.h | 2 +- drivers/scsi/qla2xxx/qla_iocb.c | 6 +- drivers/scsi/qla2xxx/qla_isr.c | 23 +- drivers/scsi/qla2xxx/qla_mbx.c | 63 +- drivers/scsi/qla2xxx/qla_os.c | 187 +- drivers/scsi/qla2xxx/qla_sup.c | 9 +- drivers/scsi/qlogicfc.c | 2226 ++ drivers/scsi/qlogicfc_asm.c | 9751 ++++++++ drivers/scsi/qlogicpti.c | 3 +- drivers/scsi/sata_mv.c | 408 +- drivers/scsi/sata_nv.c | 193 +- drivers/scsi/sata_promise.c | 179 +- drivers/scsi/sata_qstor.c | 10 +- drivers/scsi/sata_sil.c | 128 +- drivers/scsi/sata_sil24.c | 132 +- drivers/scsi/sata_sis.c | 2 + drivers/scsi/sata_svw.c | 58 +- drivers/scsi/sata_sx4.c | 25 +- drivers/scsi/sata_uli.c | 39 +- drivers/scsi/sata_via.c | 2 + drivers/scsi/sata_vsc.c | 126 +- drivers/scsi/scsi.c | 11 +- drivers/scsi/scsi_debug.c | 9 +- drivers/scsi/scsi_devinfo.c | 7 +- drivers/scsi/scsi_error.c | 20 +- drivers/scsi/scsi_ioctl.c | 182 +- drivers/scsi/scsi_lib.c | 205 +- drivers/scsi/scsi_sas_internal.h | 38 - drivers/scsi/scsi_scan.c | 125 +- drivers/scsi/scsi_sysfs.c | 6 +- drivers/scsi/scsi_transport_fc.c | 512 +- drivers/scsi/scsi_transport_iscsi.c | 3 +- drivers/scsi/scsi_transport_sas.c | 439 +- drivers/scsi/scsi_transport_spi.c | 109 +- drivers/scsi/sd.c | 172 +- drivers/scsi/sg.c | 62 +- drivers/scsi/sgiwd93.c | 4 +- drivers/scsi/sim710.c | 4 +- drivers/scsi/sr.c | 46 +- drivers/scsi/sr.h | 1 + drivers/scsi/sr_ioctl.c | 19 + drivers/scsi/st.c | 34 +- drivers/scsi/sym53c8xx_2/sym_defs.h | 2 +- drivers/scsi/sym53c8xx_2/sym_glue.c | 205 +- drivers/scsi/sym53c8xx_2/sym_glue.h | 2 +- drivers/scsi/sym53c8xx_2/sym_hipd.c | 166 +- drivers/scsi/sym53c8xx_2/sym_hipd.h | 2 - drivers/scsi/wd33c93.c | 2 +- drivers/scsi/zalon.c | 2 +- drivers/serial/21285.c | 19 +- drivers/serial/68328serial.c | 9 +- drivers/serial/8250.c | 142 +- drivers/serial/8250_acpi.c | 183 + drivers/serial/8250_au1x00.c | 7 +- drivers/serial/8250_early.c | 9 +- drivers/serial/8250_gsc.c | 15 +- drivers/serial/8250_hp300.c | 10 +- drivers/serial/Kconfig | 62 +- drivers/serial/Makefile | 15 +- drivers/serial/amba-pl010.c | 290 +- drivers/serial/amba-pl011.c | 20 +- drivers/serial/at91_serial.c | 24 +- drivers/serial/au1x00_uart.c | 1296 + drivers/serial/clps711x.c | 24 +- drivers/serial/cpm_uart/cpm_uart.h | 58 +- drivers/serial/cpm_uart/cpm_uart_core.c | 309 +- drivers/serial/cpm_uart/cpm_uart_cpm1.c | 56 +- drivers/serial/cpm_uart/cpm_uart_cpm2.c | 16 +- drivers/serial/crisv10.c | 68 +- drivers/serial/dz.c | 12 +- drivers/serial/imx.c | 66 +- drivers/serial/ioc4_serial.c | 387 +- drivers/serial/ip22zilog.c | 11 +- drivers/serial/jsm/jsm.h | 4 +- drivers/serial/jsm/jsm_driver.c | 2 +- drivers/serial/jsm/jsm_neo.c | 115 +- drivers/serial/jsm/jsm_tty.c | 29 +- drivers/serial/m32r_sio.c | 42 +- drivers/serial/mpc52xx_uart.c | 13 +- drivers/serial/mpsc.c | 260 +- drivers/serial/mpsc.h | 289 + drivers/serial/mux.c | 4 +- drivers/serial/pmac_zilog.c | 23 +- drivers/serial/pxa.c | 26 +- drivers/serial/s3c2410.c | 28 +- drivers/serial/sa1100.c | 26 +- drivers/serial/serial_core.c | 144 +- drivers/serial/serial_cs.c | 229 +- drivers/serial/serial_lh7a40x.c | 17 +- drivers/serial/serial_txx9.c | 105 +- drivers/serial/sunhv.c | 550 - drivers/serial/sunsab.c | 29 +- drivers/serial/sunsu.c | 68 +- drivers/serial/sunzilog.c | 48 +- drivers/serial/vr41xx_siu.c | 40 +- drivers/sn/ioc3.c | 5 +- drivers/sn/ioc4.c | 41 +- drivers/spi/Kconfig | 34 - drivers/spi/Makefile | 4 - drivers/spi/pxa2xx_spi.c | 1486 -- drivers/spi/spi.c | 13 +- drivers/spi/spi_bitbang.c | 104 +- drivers/spi/spi_butterfly.c | 1 - drivers/spi/spi_mpc83xx.c | 483 - drivers/spi/spi_s3c24xx.c | 453 - drivers/spi/spi_s3c24xx_gpio.c | 188 - drivers/tc/zs.c | 9 +- drivers/telephony/ixj.h | 2 +- drivers/telephony/ixj_pcmcia.c | 119 +- drivers/telephony/phonedev.c | 23 +- drivers/usb/Kconfig | 11 +- drivers/usb/Makefile | 16 +- drivers/usb/atm/speedtch.c | 1198 +- drivers/usb/atm/ueagle-atm.c | 52 +- drivers/usb/atm/usbatm.c | 8 +- drivers/usb/class/Kconfig | 47 + drivers/usb/class/Makefile | 2 + drivers/usb/class/audio.c | 3869 +++ drivers/usb/class/audio.h | 110 + drivers/usb/class/cdc-acm.c | 23 +- drivers/usb/class/usb-midi.c | 2153 ++ drivers/usb/class/usb-midi.h | 164 + drivers/usb/class/usblp.c | 16 +- drivers/usb/core/Kconfig | 7 - drivers/usb/core/devices.c | 7 +- drivers/usb/core/devio.c | 24 +- drivers/usb/core/driver.c | 6 +- drivers/usb/core/file.c | 6 +- drivers/usb/core/hcd-pci.c | 22 +- drivers/usb/core/hcd.c | 155 +- drivers/usb/core/hcd.h | 4 +- drivers/usb/core/hub.c | 76 +- drivers/usb/core/message.c | 5 +- drivers/usb/core/notify.c | 66 +- drivers/usb/core/usb.c | 7 +- drivers/usb/gadget/Kconfig | 21 +- drivers/usb/gadget/Makefile | 1 - drivers/usb/gadget/at91_udc.c | 1773 -- drivers/usb/gadget/at91_udc.h | 181 - drivers/usb/gadget/dummy_hcd.c | 3 +- drivers/usb/gadget/ether.c | 59 +- drivers/usb/gadget/file_storage.c | 42 +- drivers/usb/gadget/gadget_chips.h | 30 +- drivers/usb/gadget/goku_udc.c | 3 +- drivers/usb/gadget/inode.c | 37 +- drivers/usb/gadget/lh7a40x_udc.c | 3 +- drivers/usb/gadget/net2280.c | 111 +- drivers/usb/gadget/net2280.h | 415 +- drivers/usb/gadget/omap_udc.c | 6 +- drivers/usb/gadget/pxa2xx_udc.c | 3 +- drivers/usb/gadget/serial.c | 9 +- drivers/usb/gadget/zero.c | 22 +- drivers/usb/host/Kconfig | 2 +- drivers/usb/host/ehci-au1xxx.c | 297 - drivers/usb/host/ehci-fsl.c | 366 - drivers/usb/host/ehci-fsl.h | 37 - drivers/usb/host/ehci-hcd.c | 13 +- drivers/usb/host/ehci-hub.c | 4 - drivers/usb/host/ehci-mem.c | 11 +- drivers/usb/host/ehci-pci.c | 27 +- drivers/usb/host/ehci-q.c | 17 +- drivers/usb/host/ehci-sched.c | 9 +- drivers/usb/host/ehci.h | 18 +- drivers/usb/host/hc_crisv10.c | 12 +- drivers/usb/host/isp116x-hcd.c | 5 +- drivers/usb/host/ohci-at91.c | 305 - drivers/usb/host/ohci-au1xxx.c | 102 +- drivers/usb/host/ohci-hcd.c | 56 +- drivers/usb/host/ohci-hub.c | 12 +- drivers/usb/host/ohci-omap.c | 9 +- drivers/usb/host/ohci-pci.c | 17 +- drivers/usb/host/ohci-pxa27x.c | 3 - drivers/usb/host/ohci-s3c2410.c | 43 +- drivers/usb/host/pci-quirks.c | 1 - drivers/usb/host/pci-quirks.h | 7 - drivers/usb/host/sl811-hcd.c | 3 +- drivers/usb/host/sl811_cs.c | 119 +- drivers/usb/host/uhci-debug.c | 356 +- drivers/usb/host/uhci-hcd.c | 136 +- drivers/usb/host/uhci-hcd.h | 189 +- drivers/usb/host/uhci-hub.c | 18 +- drivers/usb/host/uhci-q.c | 1296 +- drivers/usb/image/mdc800.c | 67 +- drivers/usb/image/microtek.c | 2 +- drivers/usb/input/Kconfig | 56 +- drivers/usb/input/Makefile | 1 - drivers/usb/input/ati_remote.c | 4 +- drivers/usb/input/hid-core.c | 197 +- drivers/usb/input/hid-ff.c | 6 + drivers/usb/input/hid-input.c | 2 +- drivers/usb/input/hid-lgff.c | 6 +- drivers/usb/input/hid-tmff.c | 3 +- drivers/usb/input/hid.h | 15 - drivers/usb/input/hiddev.c | 7 +- drivers/usb/input/keyspan_remote.c | 2 - drivers/usb/input/usbtouchscreen.c | 605 - drivers/usb/input/wacom.c | 136 +- drivers/usb/input/yealink.c | 12 +- drivers/usb/media/Kconfig | 226 + drivers/usb/media/Makefile | 19 + .../{media/video => usb/media}/dabfirmware.h | 0 drivers/{media/video => usb/media}/dabusb.c | 54 +- drivers/{media/video => usb/media}/dabusb.h | 6 +- drivers/{media/video => usb/media}/dsbr100.c | 44 +- .../video/usbvideo => usb/media}/ibmcam.c | 10 +- .../video/usbvideo => usb/media}/konicawc.c | 48 +- drivers/{media/video => usb/media}/ov511.c | 189 +- drivers/{media/video => usb/media}/ov511.h | 19 +- drivers/usb/media/pwc/Makefile | 20 + .../video => usb/media}/pwc/philips.txt | 66 +- .../{media/video => usb/media}/pwc/pwc-ctrl.c | 375 +- .../{media/video => usb/media}/pwc/pwc-if.c | 311 +- .../video => usb/media}/pwc/pwc-ioctl.h | 40 +- drivers/usb/media/pwc/pwc-kiara.c | 318 + .../video => usb/media}/pwc/pwc-kiara.h | 0 .../{media/video => usb/media}/pwc/pwc-misc.c | 26 +- .../{media/video => usb/media}/pwc/pwc-nala.h | 2 +- drivers/usb/media/pwc/pwc-timon.c | 316 + .../video => usb/media}/pwc/pwc-timon.h | 0 .../video => usb/media}/pwc/pwc-uncompress.c | 6 +- .../video => usb/media}/pwc/pwc-uncompress.h | 2 +- drivers/{media/video => usb/media}/pwc/pwc.h | 4 +- drivers/{media/video => usb/media}/se401.c | 230 +- drivers/{media/video => usb/media}/se401.h | 9 +- .../video/sn9c102 => usb/media}/sn9c102.h | 34 +- .../sn9c102 => usb/media}/sn9c102_core.c | 546 +- .../sn9c102 => usb/media}/sn9c102_hv7131d.c | 16 +- .../sn9c102 => usb/media}/sn9c102_mi0343.c | 106 +- .../sn9c102 => usb/media}/sn9c102_pas106b.c | 16 +- .../sn9c102 => usb/media}/sn9c102_pas202bcb.c | 20 +- .../sn9c102 => usb/media}/sn9c102_sensor.h | 85 +- .../media}/sn9c102_tas5110c1b.c | 26 +- .../media}/sn9c102_tas5130d1b.c | 24 +- drivers/{media/video => usb/media}/stv680.c | 68 +- drivers/{media/video => usb/media}/stv680.h | 144 +- .../video/usbvideo => usb/media}/ultracam.c | 2 +- .../video/usbvideo => usb/media}/usbvideo.c | 73 +- .../video/usbvideo => usb/media}/usbvideo.h | 15 +- .../video/usbvideo => usb/media}/vicam.c | 50 +- drivers/{media/video => usb/media}/w9968cf.c | 1016 +- drivers/{media/video => usb/media}/w9968cf.h | 24 +- .../video => usb/media}/w9968cf_decoder.h | 8 +- .../{media/video => usb/media}/w9968cf_vpp.h | 2 +- drivers/usb/misc/auerswald.c | 6 +- drivers/usb/misc/cytherm.c | 3 +- drivers/usb/misc/emi26.c | 4 - drivers/usb/misc/emi62.c | 4 - drivers/usb/misc/idmouse.c | 28 +- drivers/usb/misc/ldusb.c | 14 +- drivers/usb/misc/legousbtower.c | 11 +- drivers/usb/misc/phidgetkit.c | 9 +- drivers/usb/misc/phidgetservo.c | 3 +- drivers/usb/misc/sisusbvga/sisusb.c | 5 +- drivers/usb/misc/sisusbvga/sisusb.h | 8 + drivers/usb/misc/usblcd.c | 3 +- drivers/usb/misc/usbled.c | 3 +- drivers/usb/misc/usbtest.c | 22 +- drivers/usb/mon/mon_main.c | 22 +- drivers/usb/mon/mon_text.c | 24 +- drivers/usb/mon/usb_mon.h | 2 +- drivers/usb/net/Kconfig | 1 + drivers/usb/net/asix.c | 327 +- drivers/usb/net/pegasus.c | 23 +- drivers/usb/net/pegasus.h | 26 +- drivers/usb/net/rndis_host.c | 28 +- drivers/usb/net/rtl8150.c | 4 +- drivers/usb/net/zaurus.c | 2 +- drivers/usb/net/zd1201.c | 11 +- drivers/usb/serial/Kconfig | 26 - drivers/usb/serial/Makefile | 3 - drivers/usb/serial/airprime.c | 1 - drivers/usb/serial/ark3116.c | 465 - drivers/usb/serial/cp2101.c | 7 +- drivers/usb/serial/cypress_m8.c | 73 +- drivers/usb/serial/cypress_m8.h | 5 - drivers/usb/serial/ftdi_sio.c | 11 +- drivers/usb/serial/ftdi_sio.h | 44 - drivers/usb/serial/funsoft.c | 65 - drivers/usb/serial/garmin_gps.c | 3 +- drivers/usb/serial/generic.c | 1 - drivers/usb/serial/io_edgeport.c | 3 +- drivers/usb/serial/io_ti.c | 6 +- drivers/usb/serial/ir-usb.c | 3 +- drivers/usb/serial/keyspan.c | 6 +- drivers/usb/serial/kobil_sct.c | 16 +- drivers/usb/serial/mct_u232.c | 3 +- drivers/usb/serial/navman.c | 157 - drivers/usb/serial/omninet.c | 22 +- drivers/usb/serial/option.c | 6 +- drivers/usb/serial/pl2303.c | 10 +- drivers/usb/serial/pl2303.h | 9 - drivers/usb/serial/ti_usb_3410_5052.c | 3 +- drivers/usb/serial/usb-serial.c | 37 +- drivers/usb/serial/usb-serial.h | 6 +- drivers/usb/serial/visor.c | 3 +- drivers/usb/serial/whiteheat.c | 1 - drivers/usb/storage/datafab.c | 3 +- drivers/usb/storage/isd200.c | 10 +- drivers/usb/storage/jumpshot.c | 3 +- drivers/usb/storage/scsiglue.c | 9 +- drivers/usb/storage/sddr55.c | 3 +- drivers/usb/storage/shuttle_usbat.c | 3 +- drivers/usb/storage/unusual_devs.h | 47 +- drivers/usb/storage/usb.c | 43 +- drivers/usb/storage/usb.h | 5 +- drivers/video/Kconfig | 47 +- drivers/video/Makefile | 2 +- drivers/video/acornfb.c | 10 +- drivers/video/asiliantfb.c | 14 +- drivers/video/aty/aty128fb.c | 11 +- drivers/video/aty/atyfb_base.c | 23 +- drivers/video/aty/mach64_gx.c | 3 +- drivers/video/aty/radeon_base.c | 19 +- drivers/video/aty/radeon_pm.c | 57 +- drivers/video/aty/radeon_pm_whitelist.h | 78 - drivers/video/au1100fb.c | 21 +- drivers/video/au1200fb.c | 1922 -- drivers/video/au1200fb.h | 572 - drivers/video/backlight/Kconfig | 4 +- drivers/video/backlight/backlight.c | 4 +- drivers/video/backlight/corgi_bl.c | 67 +- drivers/video/backlight/hp680_bl.c | 139 +- drivers/video/backlight/lcd.c | 4 +- drivers/video/backlight/locomolcd.c | 23 +- drivers/video/bw2.c | 3 +- drivers/video/chipsfb.c | 14 +- drivers/video/cirrusfb.c | 6 +- drivers/video/console/Kconfig | 24 - drivers/video/console/fbcon.c | 15 +- drivers/video/console/fonts.c | 2 +- drivers/video/console/newport_con.c | 4 +- drivers/video/console/softcursor.c | 19 +- drivers/video/console/sticore.c | 22 +- drivers/video/console/vgacon.c | 271 +- drivers/video/epson1355fb.c | 1 - drivers/video/fbcmap.c | 4 +- drivers/video/fbmem.c | 49 +- drivers/video/fbmon.c | 6 +- drivers/video/fbsysfs.c | 92 +- drivers/video/ffb.c | 3 +- drivers/video/geode/Kconfig | 11 +- drivers/video/geode/display_gx.c | 156 - drivers/video/geode/display_gx.h | 96 - drivers/video/geode/gxfb_core.c | 423 - drivers/video/geode/video_gx.c | 262 - drivers/video/geode/video_gx.h | 47 - drivers/video/hpfb.c | 4 +- drivers/video/i810/i810-i2c.c | 3 +- drivers/video/i810/i810_main.c | 4 +- drivers/video/imsttfb.c | 32 +- drivers/video/logo/Makefile | 2 +- drivers/video/macmodes.c | 2 +- drivers/video/matrox/g450_pll.c | 23 +- drivers/video/matrox/matroxfb_DAC1064.c | 1 + drivers/video/matrox/matroxfb_DAC1064.h | 3 +- drivers/video/matrox/matroxfb_Ti3026.c | 1 + drivers/video/matrox/matroxfb_Ti3026.h | 1 + drivers/video/matrox/matroxfb_base.c | 4 +- drivers/video/matrox/matroxfb_base.h | 2 - drivers/video/matrox/matroxfb_g450.c | 2 +- drivers/video/matrox/matroxfb_maven.c | 78 +- drivers/video/matrox/matroxfb_misc.c | 1 + drivers/video/maxinefb.c | 4 +- drivers/video/modedb.c | 2 +- drivers/video/neofb.c | 8 +- drivers/video/nvidia/nv_hw.c | 22 +- drivers/video/nvidia/nv_i2c.c | 3 +- drivers/video/nvidia/nv_setup.c | 20 +- drivers/video/nvidia/nv_type.h | 2 +- drivers/video/nvidia/nvidia.c | 155 +- drivers/video/offb.c | 107 +- drivers/video/pm2fb.c | 4 +- drivers/video/pm3fb.c | 18 +- drivers/video/pmagb-b-fb.c | 2 +- drivers/video/pxafb.c | 8 +- drivers/video/radeonfb.c | 3167 +++ drivers/video/riva/fbdev.c | 11 +- drivers/video/sa1100fb.c | 2 +- drivers/video/savage/savagefb-i2c.c | 3 +- drivers/video/savage/savagefb_driver.c | 8 +- drivers/video/sbuslib.c | 2 - drivers/video/sis/init301.c | 11 +- drivers/video/sstfb.c | 13 +- drivers/video/sticore.h | 37 +- drivers/video/stifb.c | 95 +- drivers/video/vesafb.c | 27 +- drivers/video/vfb.c | 1 - drivers/video/virgefb.c | 3 +- drivers/video/w100fb.c | 1967 +- drivers/video/w100fb.h | 777 +- drivers/w1/Kconfig | 60 +- drivers/w1/Makefile | 10 +- drivers/w1/{masters => }/ds_w1_bridge.c | 38 +- drivers/w1/{masters => }/dscore.c | 4 +- drivers/w1/{masters => }/dscore.h | 0 drivers/w1/masters/Kconfig | 48 - drivers/w1/masters/Makefile | 13 - drivers/w1/masters/ds2482.c | 564 - drivers/w1/{masters => }/matrox_w1.c | 24 +- drivers/w1/slaves/Kconfig | 38 - drivers/w1/slaves/Makefile | 12 - drivers/w1/slaves/w1_ds2433.c | 329 - drivers/w1/w1.c | 79 +- drivers/w1/w1.h | 37 +- drivers/w1/w1_family.c | 2 +- drivers/w1/w1_int.c | 49 +- drivers/w1/w1_io.c | 2 +- drivers/w1/{slaves => }/w1_smem.c | 10 +- drivers/w1/{slaves => }/w1_therm.c | 14 +- drivers/xen/Kconfig | 260 - drivers/xen/Makefile | 17 - drivers/xen/balloon/Makefile | 2 - drivers/xen/balloon/balloon.c | 617 - drivers/xen/blkback/Makefile | 3 - drivers/xen/blkback/blkback.c | 566 - drivers/xen/blkback/common.h | 134 - drivers/xen/blkback/interface.c | 171 - drivers/xen/blkback/vbd.c | 119 - drivers/xen/blkback/xenbus.c | 460 - drivers/xen/blkfront/Kconfig | 6 - drivers/xen/blkfront/Makefile | 5 - drivers/xen/blkfront/blkfront.c | 841 - drivers/xen/blkfront/block.h | 156 - drivers/xen/blkfront/vbd.c | 318 - drivers/xen/blktap/Makefile | 3 - drivers/xen/blktap/blktap.c | 1450 -- drivers/xen/blktap/common.h | 120 - drivers/xen/blktap/interface.c | 159 - drivers/xen/blktap/xenbus.c | 354 - drivers/xen/char/Makefile | 2 - drivers/xen/char/mem.c | 182 - drivers/xen/console/Makefile | 2 - drivers/xen/console/console.c | 644 - drivers/xen/console/xencons_ring.c | 141 - drivers/xen/core/Makefile | 13 - drivers/xen/core/cpu_hotplug.c | 188 - drivers/xen/core/evtchn.c | 853 - drivers/xen/core/features.c | 30 - drivers/xen/core/gnttab.c | 442 - drivers/xen/core/hypervisor_sysfs.c | 60 - drivers/xen/core/reboot.c | 383 - drivers/xen/core/skbuff.c | 141 - drivers/xen/core/smpboot.c | 433 - drivers/xen/core/xen_proc.c | 19 - drivers/xen/core/xen_sysfs.c | 379 - drivers/xen/evtchn/Makefile | 2 - drivers/xen/evtchn/evtchn.c | 458 - drivers/xen/netback/Makefile | 5 - drivers/xen/netback/common.h | 138 - drivers/xen/netback/interface.c | 339 - drivers/xen/netback/loopback.c | 261 - drivers/xen/netback/netback.c | 1345 - drivers/xen/netback/xenbus.c | 428 - drivers/xen/netfront/Kconfig | 6 - drivers/xen/netfront/Makefile | 4 - drivers/xen/netfront/netfront.c | 1841 -- drivers/xen/pciback/Makefile | 15 - drivers/xen/pciback/conf_space.c | 425 - drivers/xen/pciback/conf_space.h | 126 - drivers/xen/pciback/conf_space_capability.c | 71 - drivers/xen/pciback/conf_space_capability.h | 23 - .../xen/pciback/conf_space_capability_pm.c | 113 - .../xen/pciback/conf_space_capability_vpd.c | 42 - drivers/xen/pciback/conf_space_header.c | 299 - drivers/xen/pciback/conf_space_quirks.c | 128 - drivers/xen/pciback/conf_space_quirks.h | 35 - drivers/xen/pciback/passthrough.c | 157 - drivers/xen/pciback/pci_stub.c | 916 - drivers/xen/pciback/pciback.h | 93 - drivers/xen/pciback/pciback_ops.c | 95 - drivers/xen/pciback/slot.c | 151 - drivers/xen/pciback/vpci.c | 204 - drivers/xen/pciback/xenbus.c | 457 - drivers/xen/pcifront/Makefile | 7 - drivers/xen/pcifront/pci.c | 46 - drivers/xen/pcifront/pci_op.c | 273 - drivers/xen/pcifront/pcifront.h | 40 - drivers/xen/pcifront/xenbus.c | 294 - drivers/xen/privcmd/Makefile | 2 - drivers/xen/privcmd/privcmd.c | 286 - drivers/xen/tpmback/Makefile | 4 - drivers/xen/tpmback/common.h | 85 - drivers/xen/tpmback/interface.c | 177 - drivers/xen/tpmback/tpmback.c | 944 - drivers/xen/tpmback/xenbus.c | 291 - drivers/xen/util.c | 70 - drivers/xen/xenbus/Makefile | 12 - drivers/xen/xenbus/xenbus_backend_client.c | 135 - drivers/xen/xenbus/xenbus_client.c | 281 - drivers/xen/xenbus/xenbus_comms.c | 208 - drivers/xen/xenbus/xenbus_comms.h | 43 - drivers/xen/xenbus/xenbus_dev.c | 359 - drivers/xen/xenbus/xenbus_probe.c | 1142 - drivers/xen/xenbus/xenbus_xs.c | 846 - drivers/zorro/zorro-driver.c | 9 +- fs/9p/9p.h | 11 +- fs/9p/Makefile | 10 +- fs/9p/conv.c | 15 +- fs/9p/conv.h | 9 +- fs/9p/debug.h | 6 +- fs/9p/error.c | 5 +- fs/9p/error.h | 5 +- fs/9p/fcall.c | 427 - fs/9p/fcprint.c | 346 - fs/9p/fid.c | 5 +- fs/9p/fid.h | 5 +- fs/9p/mux.c | 270 +- fs/9p/mux.h | 11 +- fs/9p/trans_fd.c | 301 +- fs/9p/transport.h | 5 +- fs/9p/v9fs.c | 15 +- fs/9p/v9fs.h | 8 +- fs/9p/v9fs_vfs.h | 9 +- fs/9p/vfs_addr.c | 5 +- fs/9p/vfs_dentry.c | 7 +- fs/9p/vfs_dir.c | 7 +- fs/9p/vfs_file.c | 50 +- fs/9p/vfs_inode.c | 73 +- fs/9p/vfs_super.c | 20 +- fs/Kconfig | 86 +- fs/Makefile | 6 +- fs/adfs/adfs.h | 4 +- fs/adfs/dir.c | 2 +- fs/adfs/file.c | 6 +- fs/adfs/super.c | 3 +- fs/affs/affs.h | 6 +- fs/affs/dir.c | 2 +- fs/affs/file.c | 2 +- fs/affs/namei.c | 3 +- fs/affs/super.c | 3 +- fs/afs/cmservice.c | 2 +- fs/afs/dir.c | 2 +- fs/afs/file.c | 6 +- fs/afs/internal.h | 4 +- fs/afs/mntpt.c | 2 +- fs/afs/proc.c | 10 +- fs/afs/super.c | 2 +- fs/aio.c | 3 +- fs/autofs/autofs_i.h | 2 +- fs/autofs/dirhash.c | 2 +- fs/autofs/root.c | 2 +- fs/autofs4/autofs_i.h | 60 +- fs/autofs4/expire.c | 298 +- fs/autofs4/inode.c | 105 +- fs/autofs4/root.c | 324 +- fs/autofs4/waitq.c | 188 +- fs/bad_inode.c | 2 +- fs/befs/datastream.c | 2 +- fs/befs/linuxvfs.c | 7 +- fs/bfs/bfs.h | 4 +- fs/bfs/dir.c | 2 +- fs/bfs/file.c | 2 +- fs/bfs/inode.c | 3 +- fs/binfmt_elf.c | 169 +- fs/binfmt_elf_fdpic.c | 3 +- fs/binfmt_flat.c | 62 +- fs/binfmt_misc.c | 6 +- fs/bio.c | 44 +- fs/block_dev.c | 345 +- fs/buffer.c | 230 +- fs/char_dev.c | 30 +- fs/cifs/CHANGES | 31 +- fs/cifs/Makefile | 2 +- fs/cifs/README | 15 - fs/cifs/cifsencrypt.c | 8 +- fs/cifs/cifsfs.c | 137 +- fs/cifs/cifsfs.h | 12 +- fs/cifs/cifsglob.h | 11 +- fs/cifs/cifspdu.h | 13 +- fs/cifs/cifsproto.h | 15 +- fs/cifs/cifssmb.c | 169 +- fs/cifs/connect.c | 203 +- fs/cifs/dir.c | 8 +- fs/cifs/fcntl.c | 2 + fs/cifs/file.c | 140 +- fs/cifs/inode.c | 37 +- fs/cifs/link.c | 12 +- fs/cifs/misc.c | 46 +- fs/cifs/ntlmssp.c | 143 - fs/cifs/ntlmssp.h | 2 +- fs/cifs/readdir.c | 60 +- fs/cifs/transport.c | 22 +- fs/cifs/xattr.c | 8 + fs/coda/cache.c | 2 +- fs/coda/cnode.c | 3 +- fs/coda/coda_int.h | 13 - fs/coda/dir.c | 5 +- fs/coda/file.c | 4 +- fs/coda/inode.c | 4 +- fs/coda/pioctl.c | 2 +- fs/coda/psdev.c | 11 +- fs/compat.c | 220 +- fs/compat_ioctl.c | 6 +- fs/configfs/configfs_internal.h | 6 +- fs/configfs/dir.c | 141 +- fs/configfs/file.c | 2 +- fs/cramfs/inode.c | 37 +- fs/dcache.c | 128 +- fs/dcookies.c | 25 +- fs/debugfs/file.c | 50 +- fs/debugfs/inode.c | 2 +- fs/devfs/base.c | 12 +- fs/devpts/inode.c | 77 +- fs/direct-io.c | 43 +- fs/dnotify.c | 4 +- fs/dquot.c | 176 +- fs/efs/dir.c | 2 +- fs/efs/super.c | 2 +- fs/eventpoll.c | 40 +- fs/exec.c | 81 +- fs/exportfs/expfs.c | 2 +- fs/ext2/dir.c | 16 +- fs/ext2/ext2.h | 9 +- fs/ext2/file.c | 6 +- fs/ext2/inode.c | 16 +- fs/ext2/namei.c | 54 +- fs/ext2/super.c | 6 +- fs/ext3/balloc.c | 149 +- fs/ext3/bitmap.c | 6 +- fs/ext3/dir.c | 58 +- fs/ext3/file.c | 8 +- fs/ext3/inode.c | 591 +- fs/ext3/ioctl.c | 22 +- fs/ext3/namei.c | 9 + fs/ext3/super.c | 22 +- fs/fat/cache.c | 2 +- fs/fat/dir.c | 4 +- fs/fat/fatent.c | 10 +- fs/fat/file.c | 2 +- fs/fat/inode.c | 13 +- fs/fcntl.c | 20 +- fs/fifo.c | 67 +- fs/file.c | 36 +- fs/file_table.c | 10 +- fs/freevxfs/vxfs_extern.h | 2 +- fs/freevxfs/vxfs_lookup.c | 4 +- fs/freevxfs/vxfs_olt.c | 9 +- fs/freevxfs/vxfs_super.c | 2 +- fs/fs-writeback.c | 2 +- fs/fuse/dev.c | 281 +- fs/fuse/dir.c | 149 +- fs/fuse/file.c | 76 +- fs/fuse/fuse_i.h | 66 +- fs/fuse/inode.c | 142 +- fs/hfs/bnode.c | 9 +- fs/hfs/btree.c | 3 +- fs/hfs/dir.c | 2 +- fs/hfs/hfs_fs.h | 2 +- fs/hfs/inode.c | 17 +- fs/hfs/super.c | 2 + fs/hfsplus/bnode.c | 6 +- fs/hfsplus/btree.c | 3 +- fs/hfsplus/dir.c | 2 +- fs/hfsplus/inode.c | 15 +- fs/hostfs/hostfs_kern.c | 4 +- fs/hostfs/hostfs_user.c | 1 + fs/hpfs/dir.c | 2 +- fs/hpfs/file.c | 2 +- fs/hpfs/hpfs_fn.h | 9 +- fs/hpfs/inode.c | 10 +- fs/hpfs/namei.c | 60 +- fs/hpfs/super.c | 7 +- fs/hppfs/hppfs_kern.c | 18 +- fs/hugetlbfs/inode.c | 96 +- fs/inode.c | 52 +- fs/inotify.c | 226 +- fs/isofs/dir.c | 2 +- fs/isofs/inode.c | 3 +- fs/isofs/isofs.h | 14 +- fs/isofs/joliet.c | 2 +- fs/jbd/checkpoint.c | 4 +- fs/jbd/journal.c | 31 +- fs/jbd/transaction.c | 21 +- fs/jffs/inode-v23.c | 104 +- fs/jffs/intrep.c | 6 +- fs/jffs/jffs_fm.c | 2 +- fs/jffs/jffs_fm.h | 5 +- fs/jffs2/background.c | 3 +- fs/jffs2/compr_zlib.c | 19 +- fs/jffs2/dir.c | 2 +- fs/jffs2/file.c | 2 +- fs/jffs2/nodelist.c | 6 +- fs/jffs2/os-linux.h | 4 +- fs/jffs2/super.c | 7 +- fs/jfs/Makefile | 3 +- fs/jfs/acl.c | 7 +- fs/jfs/file.c | 4 +- fs/jfs/inode.c | 20 +- fs/jfs/ioctl.c | 109 - fs/jfs/jfs_debug.c | 2 +- fs/jfs/jfs_dinode.h | 34 +- fs/jfs/jfs_dmap.c | 8 +- fs/jfs/jfs_dmap.h | 2 +- fs/jfs/jfs_dtree.c | 13 +- fs/jfs/jfs_extent.c | 22 +- fs/jfs/jfs_imap.c | 76 +- fs/jfs/jfs_imap.h | 4 +- fs/jfs/jfs_incore.h | 10 +- fs/jfs/jfs_inode.c | 86 +- fs/jfs/jfs_inode.h | 8 +- fs/jfs/jfs_lock.h | 1 - fs/jfs/jfs_logmgr.c | 62 +- fs/jfs/jfs_logmgr.h | 2 +- fs/jfs/jfs_metapage.c | 14 +- fs/jfs/jfs_superblock.h | 9 +- fs/jfs/jfs_txnmgr.c | 36 +- fs/jfs/namei.c | 102 +- fs/jfs/super.c | 103 +- fs/jfs/xattr.c | 8 +- fs/libfs.c | 16 +- fs/lockd/clntlock.c | 112 +- fs/lockd/clntproc.c | 321 +- fs/lockd/host.c | 31 +- fs/lockd/mon.c | 17 +- fs/lockd/svc.c | 21 +- fs/lockd/svc4proc.c | 157 +- fs/lockd/svclock.c | 349 +- fs/lockd/svcproc.c | 151 +- fs/lockd/svcshare.c | 4 +- fs/lockd/svcsubs.c | 24 +- fs/lockd/xdr.c | 19 +- fs/lockd/xdr4.c | 21 +- fs/locks.c | 159 +- fs/mbcache.c | 4 +- fs/minix/bitmap.c | 10 +- fs/minix/dir.c | 2 +- fs/minix/file.c | 2 +- fs/minix/inode.c | 29 +- fs/minix/itree_v1.c | 4 +- fs/minix/itree_v2.c | 4 +- fs/minix/minix.h | 4 +- fs/minix/namei.c | 48 +- fs/mpage.c | 104 +- fs/msdos/namei.c | 15 +- fs/namei.c | 101 +- fs/namespace.c | 62 +- fs/ncpfs/dir.c | 2 +- fs/ncpfs/file.c | 6 +- fs/ncpfs/inode.c | 9 +- fs/ncpfs/ncplib_kernel.c | 4 +- fs/ncpfs/sock.c | 34 +- fs/nfs/callback.c | 31 +- fs/nfs/callback_xdr.c | 28 +- fs/nfs/delegation.c | 19 - fs/nfs/delegation.h | 1 - fs/nfs/dir.c | 135 +- fs/nfs/direct.c | 950 +- fs/nfs/file.c | 55 +- fs/nfs/idmap.c | 47 +- fs/nfs/inode.c | 237 +- fs/nfs/iostat.h | 164 - fs/nfs/mount_clnt.c | 19 +- fs/nfs/nfs2xdr.c | 6 +- fs/nfs/nfs3acl.c | 16 +- fs/nfs/nfs3proc.c | 246 +- fs/nfs/nfs3xdr.c | 8 +- fs/nfs/nfs4proc.c | 190 +- fs/nfs/nfs4state.c | 1 - fs/nfs/nfs4xdr.c | 4 +- fs/nfs/pagelist.c | 16 +- fs/nfs/proc.c | 156 +- fs/nfs/read.c | 108 +- fs/nfs/unlink.c | 3 +- fs/nfs/write.c | 300 +- fs/nfsctl.c | 2 +- fs/nfsd/auth.c | 49 +- fs/nfsd/export.c | 373 +- fs/nfsd/nfs4acl.c | 12 +- fs/nfsd/nfs4callback.c | 12 +- fs/nfsd/nfs4idmap.c | 146 +- fs/nfsd/nfs4proc.c | 2 + fs/nfsd/nfs4state.c | 209 +- fs/nfsd/nfs4xdr.c | 64 +- fs/nfsd/nfsctl.c | 65 +- fs/nfsd/nfsfh.c | 2 +- fs/nfsd/nfssvc.c | 14 +- fs/nfsd/stats.c | 2 +- fs/nfsd/vfs.c | 15 +- fs/nls/Kconfig | 2 +- fs/nls/nls_euc-jp.c | 6 +- fs/ntfs/ChangeLog | 30 +- fs/ntfs/Makefile | 2 +- fs/ntfs/aops.c | 14 +- fs/ntfs/attrib.c | 35 +- fs/ntfs/compress.c | 4 +- fs/ntfs/dir.c | 4 +- fs/ntfs/file.c | 20 +- fs/ntfs/inode.c | 111 +- fs/ntfs/inode.h | 13 +- fs/ntfs/layout.h | 44 +- fs/ntfs/logfile.c | 4 +- fs/ntfs/mft.c | 70 +- fs/ntfs/mft.h | 5 +- fs/ntfs/namei.c | 9 +- fs/ntfs/ntfs.h | 37 +- fs/ntfs/runlist.c | 12 +- fs/ntfs/super.c | 88 +- fs/ntfs/unistr.c | 51 +- fs/ocfs2/alloc.c | 88 +- fs/ocfs2/aops.c | 66 +- fs/ocfs2/aops.h | 4 +- fs/ocfs2/buffer_head_io.c | 11 +- fs/ocfs2/cluster/heartbeat.c | 78 +- fs/ocfs2/cluster/masklog.h | 10 + fs/ocfs2/dcache.c | 9 +- fs/ocfs2/dir.c | 42 +- fs/ocfs2/dlm/dlmast.c | 22 +- fs/ocfs2/dlm/dlmcommon.h | 21 - fs/ocfs2/dlm/dlmconvert.c | 11 +- fs/ocfs2/dlm/dlmdebug.c | 18 +- fs/ocfs2/dlm/dlmfs.c | 3 +- fs/ocfs2/dlm/dlmlock.c | 14 +- fs/ocfs2/dlm/dlmmaster.c | 227 +- fs/ocfs2/dlm/dlmrecovery.c | 50 +- fs/ocfs2/dlm/dlmunlock.c | 11 +- fs/ocfs2/dlm/userdlm.c | 74 +- fs/ocfs2/dlmglue.c | 103 +- fs/ocfs2/export.c | 24 +- fs/ocfs2/extent_map.c | 40 +- fs/ocfs2/file.c | 151 +- fs/ocfs2/file.h | 4 +- fs/ocfs2/inode.c | 116 +- fs/ocfs2/journal.c | 45 +- fs/ocfs2/localalloc.c | 17 +- fs/ocfs2/namei.c | 84 +- fs/ocfs2/ocfs2.h | 12 +- fs/ocfs2/suballoc.c | 72 +- fs/ocfs2/super.c | 24 +- fs/ocfs2/super.h | 8 +- fs/ocfs2/uptodate.c | 44 +- fs/ocfs2/vote.c | 69 +- fs/open.c | 27 +- fs/openpromfs/inode.c | 6 +- fs/partitions/check.c | 68 +- fs/partitions/devfs.c | 12 +- fs/partitions/ibm.c | 29 +- fs/partitions/mac.c | 3 +- fs/partitions/sun.c | 2 +- fs/pipe.c | 487 +- fs/pnode.c | 2 +- fs/proc/array.c | 13 +- fs/proc/base.c | 86 +- fs/proc/generic.c | 34 +- fs/proc/inode.c | 3 +- fs/proc/internal.h | 4 +- fs/proc/kcore.c | 4 +- fs/proc/kmsg.c | 2 +- fs/proc/proc_devtree.c | 101 +- fs/proc/proc_misc.c | 41 +- fs/proc/task_mmu.c | 37 +- fs/proc/vmcore.c | 2 +- fs/qnx4/dir.c | 2 +- fs/qnx4/file.c | 5 +- fs/qnx4/inode.c | 3 +- fs/quota.c | 6 +- fs/quota_v2.c | 2 +- fs/ramfs/file-mmu.c | 13 +- fs/ramfs/file-nommu.c | 5 +- fs/ramfs/internal.h | 2 +- fs/read_write.c | 8 +- fs/reiserfs/dir.c | 2 +- fs/reiserfs/file.c | 14 +- fs/reiserfs/fix_node.c | 4 +- fs/reiserfs/inode.c | 9 +- fs/reiserfs/item_ops.c | 2 +- fs/reiserfs/journal.c | 21 +- fs/reiserfs/prints.c | 11 +- fs/reiserfs/procfs.c | 2 +- fs/reiserfs/stree.c | 210 +- fs/reiserfs/super.c | 11 +- fs/reiserfs/xattr_acl.c | 665 +- fs/relayfs/Makefile | 4 + fs/relayfs/inode.c | 581 + fs/relayfs/relay.c | 482 + fs/romfs/inode.c | 5 +- fs/select.c | 146 +- fs/seq_file.c | 10 +- fs/smbfs/dir.c | 2 +- fs/smbfs/file.c | 8 +- fs/smbfs/inode.c | 5 +- fs/smbfs/proto.h | 4 +- fs/splice.c | 1518 -- fs/squashfs/Makefile | 7 - fs/squashfs/inode.c | 1803 -- fs/stat.c | 2 +- fs/super.c | 26 +- fs/sync.c | 164 - fs/sysfs/bin.c | 2 +- fs/sysfs/dir.c | 39 +- fs/sysfs/file.c | 99 +- fs/sysfs/inode.c | 6 +- fs/sysfs/symlink.c | 5 +- fs/sysfs/sysfs.h | 8 +- fs/sysv/dir.c | 8 +- fs/sysv/file.c | 2 +- fs/sysv/inode.c | 2 +- fs/sysv/namei.c | 48 +- fs/sysv/super.c | 4 +- fs/sysv/sysv.h | 4 +- fs/udf/balloc.c | 36 +- fs/udf/dir.c | 2 +- fs/udf/file.c | 2 +- fs/udf/ialloc.c | 8 +- fs/udf/inode.c | 12 +- fs/udf/super.c | 24 +- fs/udf/udfdecl.h | 4 +- fs/ufs/dir.c | 2 +- fs/ufs/file.c | 12 +- fs/ufs/namei.c | 48 +- fs/ufs/super.c | 5 +- fs/vfat/namei.c | 18 + fs/xattr.c | 11 +- fs/xfs/Makefile-linux-2.6 | 40 +- fs/xfs/linux-2.6/kmem.h | 91 +- fs/xfs/linux-2.6/mrlock.h | 2 +- fs/xfs/linux-2.6/xfs_aops.c | 556 +- fs/xfs/linux-2.6/xfs_aops.h | 4 +- fs/xfs/linux-2.6/xfs_buf.c | 10 +- fs/xfs/linux-2.6/xfs_export.c | 37 +- fs/xfs/linux-2.6/xfs_export.h | 36 +- fs/xfs/linux-2.6/xfs_file.c | 296 +- fs/xfs/linux-2.6/xfs_fs_subr.c | 6 +- fs/xfs/linux-2.6/xfs_ioctl.c | 138 +- fs/xfs/linux-2.6/xfs_ioctl32.c | 26 +- fs/xfs/linux-2.6/xfs_ioctl32.h | 4 +- fs/xfs/linux-2.6/xfs_iops.c | 395 +- fs/xfs/linux-2.6/xfs_iops.h | 45 +- fs/xfs/linux-2.6/xfs_linux.h | 13 +- fs/xfs/linux-2.6/xfs_lrw.c | 175 +- fs/xfs/linux-2.6/xfs_lrw.h | 11 +- fs/xfs/linux-2.6/xfs_stats.c | 9 +- fs/xfs/linux-2.6/xfs_super.c | 225 +- fs/xfs/linux-2.6/xfs_super.h | 7 +- fs/xfs/linux-2.6/xfs_sysctl.c | 3 +- fs/xfs/linux-2.6/xfs_vfs.c | 19 +- fs/xfs/linux-2.6/xfs_vfs.h | 5 +- fs/xfs/linux-2.6/xfs_vnode.c | 35 +- fs/xfs/linux-2.6/xfs_vnode.h | 45 +- fs/xfs/quota/xfs_dquot_item.c | 4 +- fs/xfs/quota/xfs_qm.c | 44 +- fs/xfs/quota/xfs_qm_bhv.c | 4 +- fs/xfs/quota/xfs_qm_syscalls.c | 2 +- fs/xfs/quota/xfs_trans_dquot.c | 70 +- fs/xfs/support/ktrace.c | 4 +- fs/xfs/support/uuid.c | 15 +- fs/xfs/xfs_acl.c | 2 +- fs/xfs/xfs_acl.h | 4 +- fs/xfs/xfs_ag.h | 2 +- fs/xfs/xfs_alloc.c | 11 +- fs/xfs/xfs_alloc.h | 2 +- fs/xfs/xfs_attr.c | 65 +- fs/xfs/xfs_attr_leaf.c | 733 +- fs/xfs/xfs_attr_leaf.h | 47 +- fs/xfs/xfs_attr_sf.h | 8 +- fs/xfs/xfs_behavior.c | 4 +- fs/xfs/xfs_behavior.h | 4 +- fs/xfs/xfs_bmap.c | 1371 +- fs/xfs/xfs_bmap.h | 15 +- fs/xfs/xfs_bmap_btree.c | 10 +- fs/xfs/xfs_bmap_btree.h | 8 + fs/xfs/xfs_buf_item.c | 4 +- fs/xfs/xfs_cap.h | 2 +- fs/xfs/xfs_clnt.h | 3 +- fs/xfs/xfs_da_btree.c | 411 +- fs/xfs/xfs_da_btree.h | 16 +- fs/xfs/xfs_dfrag.c | 4 +- fs/xfs/xfs_dir.c | 32 +- fs/xfs/xfs_dir2.h | 27 +- fs/xfs/xfs_dir2_block.c | 195 +- fs/xfs/xfs_dir2_block.h | 7 +- fs/xfs/xfs_dir2_data.c | 240 +- fs/xfs/xfs_dir2_data.h | 26 +- fs/xfs/xfs_dir2_leaf.c | 287 +- fs/xfs/xfs_dir2_leaf.h | 15 +- fs/xfs/xfs_dir2_node.c | 305 +- fs/xfs/xfs_dir2_node.h | 10 +- fs/xfs/xfs_dir2_sf.c | 8 +- fs/xfs/xfs_dir_leaf.c | 84 +- fs/xfs/xfs_dir_sf.h | 24 +- fs/xfs/xfs_dmapi.h | 10 + fs/xfs/xfs_error.h | 3 - fs/xfs/xfs_fsops.c | 3 +- fs/xfs/xfs_ialloc.c | 124 +- fs/xfs/xfs_iget.c | 37 +- fs/xfs/xfs_inode.c | 1334 +- fs/xfs/xfs_inode.h | 79 +- fs/xfs/xfs_inode_item.c | 2 +- fs/xfs/xfs_iomap.c | 2 +- fs/xfs/xfs_itable.c | 9 +- fs/xfs/xfs_itable.h | 2 +- fs/xfs/xfs_log.c | 22 +- fs/xfs/xfs_log.h | 2 +- fs/xfs/xfs_log_recover.c | 6 +- fs/xfs/xfs_mount.c | 719 +- fs/xfs/xfs_mount.h | 51 +- fs/xfs/xfs_quota.h | 9 +- fs/xfs/xfs_rename.c | 12 - fs/xfs/xfs_rw.h | 1 - fs/xfs/xfs_trans.c | 193 +- fs/xfs/xfs_trans.h | 4 +- fs/xfs/xfs_trans_inode.c | 2 +- fs/xfs/xfs_vfsops.c | 127 +- fs/xfs/xfs_vnodeops.c | 35 +- include/acpi/acpi_bus.h | 3 +- include/asm-alpha/bitops.h | 133 +- include/asm-alpha/fcntl.h | 1 - include/asm-alpha/fpu.h | 4 +- include/asm-alpha/io.h | 84 + include/asm-alpha/mmu_context.h | 5 +- include/asm-alpha/mmzone.h | 19 +- include/asm-alpha/module.h | 3 - include/asm-alpha/numnodes.h | 7 + include/asm-alpha/page.h | 5 +- include/asm-alpha/poll.h | 4 +- include/asm-alpha/smp.h | 4 +- include/asm-alpha/termbits.h | 1 - include/asm-alpha/topology.h | 4 +- include/asm-arm/arch-aaec2000/debug-macro.S | 1 - include/asm-arm/arch-aaec2000/entry-macro.S | 1 - include/asm-arm/arch-aaec2000/uncompress.h | 23 +- .../asm-arm/arch-at91rm9200/at91rm9200_emac.h | 138 - .../asm-arm/arch-at91rm9200/at91rm9200_mci.h | 104 - .../asm-arm/arch-at91rm9200/at91rm9200_sys.h | 100 +- include/asm-arm/arch-at91rm9200/board.h | 24 - include/asm-arm/arch-at91rm9200/hardware.h | 3 - include/asm-arm/arch-at91rm9200/uncompress.h | 23 +- include/asm-arm/arch-cl7500/hardware.h | 4 + include/asm-arm/arch-cl7500/memory.h | 6 - include/asm-arm/arch-cl7500/param.h | 5 + include/asm-arm/arch-cl7500/uncompress.h | 18 +- .../arch-clps711x/param.h} | 30 +- include/asm-arm/arch-clps711x/uncompress.h | 21 +- include/asm-arm/arch-ebsa110/hardware.h | 3 + include/asm-arm/arch-ebsa110/memory.h | 6 - include/asm-arm/arch-ebsa110/param.h | 4 + include/asm-arm/arch-ebsa110/uncompress.h | 47 +- include/asm-arm/arch-ebsa285/hardware.h | 7 + include/asm-arm/arch-ebsa285/memory.h | 12 - include/asm-arm/arch-ebsa285/param.h | 3 + include/asm-arm/arch-ebsa285/uncompress.h | 16 +- include/asm-arm/arch-ep93xx/debug-macro.S | 22 - include/asm-arm/arch-ep93xx/dma.h | 3 - include/asm-arm/arch-ep93xx/entry-macro.S | 53 - include/asm-arm/arch-ep93xx/ep93xx-regs.h | 125 - include/asm-arm/arch-ep93xx/gesbc9312.h | 3 - include/asm-arm/arch-ep93xx/gpio.h | 107 - include/asm-arm/arch-ep93xx/hardware.h | 12 - include/asm-arm/arch-ep93xx/io.h | 8 - include/asm-arm/arch-ep93xx/irqs.h | 80 - include/asm-arm/arch-ep93xx/memory.h | 14 - include/asm-arm/arch-ep93xx/platform.h | 14 - include/asm-arm/arch-ep93xx/system.h | 26 - include/asm-arm/arch-ep93xx/timex.h | 5 - include/asm-arm/arch-ep93xx/ts72xx.h | 101 - include/asm-arm/arch-ep93xx/uncompress.h | 85 - include/asm-arm/arch-ep93xx/vmalloc.h | 5 - include/asm-arm/arch-h720x/irq.h | 14 + include/asm-arm/arch-h720x/param.h | 10 + include/asm-arm/arch-h720x/uncompress.h | 24 +- include/asm-arm/arch-imx/dma.h | 17 +- include/asm-arm/arch-imx/imx-dma.h | 90 - include/asm-arm/arch-imx/imx-uart.h | 10 - include/asm-arm/arch-imx/irq.h | 20 + include/asm-arm/arch-imx/mmc.h | 12 - include/asm-arm/arch-imx/param.h | 19 + include/asm-arm/arch-imx/uncompress.h | 21 +- include/asm-arm/arch-integrator/debug-macro.S | 2 +- include/asm-arm/arch-integrator/param.h | 19 + include/asm-arm/arch-integrator/uncompress.h | 21 +- include/asm-arm/arch-iop3xx/param.h | 3 + include/asm-arm/arch-iop3xx/uncompress.h | 16 +- include/asm-arm/arch-ixp2000/irq.h | 13 + include/asm-arm/arch-ixp2000/ixdp2x00.h | 5 +- include/asm-arm/arch-ixp2000/ixp2000-regs.h | 4 +- include/asm-arm/arch-ixp2000/param.h | 3 + include/asm-arm/arch-ixp2000/system.h | 2 +- include/asm-arm/arch-ixp2000/uncompress.h | 15 +- include/asm-arm/arch-ixp23xx/debug-macro.S | 26 - include/asm-arm/arch-ixp23xx/dma.h | 3 - include/asm-arm/arch-ixp23xx/entry-macro.S | 31 - include/asm-arm/arch-ixp23xx/hardware.h | 37 - include/asm-arm/arch-ixp23xx/io.h | 54 - include/asm-arm/arch-ixp23xx/irqs.h | 223 - include/asm-arm/arch-ixp23xx/ixdp2351.h | 89 - include/asm-arm/arch-ixp23xx/ixp23xx.h | 306 - include/asm-arm/arch-ixp23xx/memory.h | 63 - include/asm-arm/arch-ixp23xx/platform.h | 32 - include/asm-arm/arch-ixp23xx/system.h | 33 - include/asm-arm/arch-ixp23xx/time.h | 3 - include/asm-arm/arch-ixp23xx/timex.h | 7 - include/asm-arm/arch-ixp23xx/uncompress.h | 40 - include/asm-arm/arch-ixp23xx/vmalloc.h | 10 - include/asm-arm/arch-ixp4xx/debug-macro.S | 1 + include/asm-arm/arch-ixp4xx/io.h | 7 - include/asm-arm/arch-ixp4xx/irq.h | 13 + include/asm-arm/arch-ixp4xx/memory.h | 27 +- include/asm-arm/arch-ixp4xx/param.h | 3 + include/asm-arm/arch-ixp4xx/platform.h | 43 +- include/asm-arm/arch-l7200/hardware.h | 3 + include/asm-arm/arch-l7200/memory.h | 6 - include/asm-arm/arch-l7200/param.h | 19 + include/asm-arm/arch-l7200/serial_l7200.h | 2 +- include/asm-arm/arch-l7200/uncompress.h | 17 +- include/asm-arm/arch-lh7a40x/irq.h | 11 + include/asm-arm/arch-lh7a40x/memory.h | 2 + include/asm-arm/arch-lh7a40x/param.h | 9 + include/asm-arm/arch-lh7a40x/uncompress.h | 11 +- include/asm-arm/arch-omap/board-ams-delta.h | 65 - include/asm-arm/arch-omap/board-apollon.h | 45 - include/asm-arm/arch-omap/board-h2.h | 4 + include/asm-arm/arch-omap/board-h3.h | 4 + include/asm-arm/arch-omap/board-h4.h | 8 +- include/asm-arm/arch-omap/board-netstar.h | 19 + include/asm-arm/arch-omap/board-nokia.h | 54 - include/asm-arm/arch-omap/board-perseus2.h | 4 + include/asm-arm/arch-omap/board.h | 30 +- include/asm-arm/arch-omap/clock.h | 13 +- include/asm-arm/arch-omap/dma.h | 1 - include/asm-arm/arch-omap/dmtimer.h | 1 - include/asm-arm/arch-omap/dsp.h | 6 - include/asm-arm/arch-omap/dsp_common.h | 13 +- include/asm-arm/arch-omap/gpioexpander.h | 24 - include/asm-arm/arch-omap/hardware.h | 8 +- include/asm-arm/arch-omap/irda.h | 36 - include/asm-arm/arch-omap/irqs.h | 5 - include/asm-arm/arch-omap/keypad.h | 36 - include/asm-arm/arch-omap/lcd_lph8923.h | 14 - include/asm-arm/arch-omap/mcbsp.h | 65 - include/asm-arm/arch-omap/mcspi.h | 16 - include/asm-arm/arch-omap/menelaus.h | 2 +- include/asm-arm/arch-omap/mux.h | 54 +- include/asm-arm/arch-omap/omap-alsa.h | 124 - include/asm-arm/arch-omap/omapfb.h | 98 +- include/asm-arm/arch-omap/pm.h | 81 +- include/asm-arm/arch-omap/prcm.h | 404 +- include/asm-arm/arch-omap/sram.h | 2 - include/asm-arm/arch-omap/system.h | 17 +- include/asm-arm/arch-omap/uncompress.h | 20 +- include/asm-arm/arch-pxa/debug-macro.S | 2 + include/asm-arm/arch-pxa/dma.h | 26 +- include/asm-arm/arch-pxa/irq.h | 14 + include/asm-arm/arch-pxa/irqs.h | 6 - include/asm-arm/arch-pxa/lpd270.h | 38 - include/asm-arm/arch-pxa/ohci.h | 2 - include/asm-arm/arch-pxa/param.h | 3 + include/asm-arm/arch-pxa/pxa-regs.h | 2 +- include/asm-arm/arch-pxa/pxa2xx_spi.h | 71 - include/asm-arm/arch-pxa/sharpsl.h | 2 - include/asm-arm/arch-pxa/uncompress.h | 13 +- include/asm-arm/arch-realview/debug-macro.S | 18 +- include/asm-arm/arch-realview/uncompress.h | 20 +- include/asm-arm/arch-rpc/hardware.h | 3 + include/asm-arm/arch-rpc/memory.h | 6 - include/asm-arm/arch-rpc/param.h | 3 + include/asm-arm/arch-rpc/uncompress.h | 27 +- include/asm-arm/arch-s3c2410/entry-macro.S | 167 +- include/asm-arm/arch-s3c2410/leds-gpio.h | 28 - include/asm-arm/arch-s3c2410/osiris-cpld.h | 25 - include/asm-arm/arch-s3c2410/osiris-map.h | 41 - include/asm-arm/arch-s3c2410/param.h | 27 + include/asm-arm/arch-s3c2410/regs-gpio.h | 2 - include/asm-arm/arch-s3c2410/spi-gpio.h | 31 - include/asm-arm/arch-s3c2410/spi.h | 29 - include/asm-arm/arch-s3c2410/uncompress.h | 15 +- include/asm-arm/arch-sa1100/hardware.h | 4 + include/asm-arm/arch-sa1100/memory.h | 7 - include/asm-arm/arch-sa1100/param.h | 3 + include/asm-arm/arch-sa1100/uncompress.h | 21 +- include/asm-arm/arch-shark/hardware.h | 6 + include/asm-arm/arch-shark/memory.h | 6 - include/asm-arm/arch-shark/param.h | 5 + include/asm-arm/arch-shark/uncompress.h | 13 +- include/asm-arm/arch-versatile/debug-macro.S | 2 +- include/asm-arm/arch-versatile/param.h | 19 + include/asm-arm/arch-versatile/uncompress.h | 20 +- include/asm-arm/assembler.h | 27 +- include/asm-arm/bitops.h | 175 +- include/asm-arm/bug.h | 1 - include/asm-arm/cacheflush.h | 8 - include/asm-arm/delay.h | 12 +- include/asm-arm/dma-mapping.h | 22 +- include/asm-arm/domain.h | 18 - include/asm-arm/fpstate.h | 2 - include/asm-arm/hardware/debug-8250.S | 29 - include/asm-arm/hardware/debug-pl01x.S | 29 - include/asm-arm/hardware/uengine.h | 62 - include/asm-arm/hardware/vic.h | 2 +- include/asm-arm/io.h | 36 + include/asm-arm/irq.h | 2 +- include/asm-arm/mach/arch.h | 5 +- include/asm-arm/mach/irq.h | 7 +- include/asm-arm/memory.h | 25 +- include/asm-arm/module.h | 5 - include/asm-arm/numnodes.h | 26 + include/asm-arm/page.h | 11 - include/asm-arm/param.h | 7 +- include/asm-arm/pgalloc.h | 5 - include/asm-arm/pgtable-hwdef.h | 89 - include/asm-arm/pgtable.h | 81 +- include/asm-arm/poll.h | 1 - include/asm-arm/proc-fns.h | 8 - include/asm-arm/procinfo.h | 2 + include/asm-arm/rtc.h | 3 + include/asm-arm/spinlock.h | 6 - include/asm-arm/system.h | 25 - include/asm-arm/tlb.h | 9 - include/asm-arm/tlbflush.h | 9 - include/asm-arm/unistd.h | 50 +- include/asm-arm26/bitops.h | 146 +- include/asm-arm26/memory.h | 4 +- include/asm-arm26/page.h | 2 - include/asm-arm26/poll.h | 1 - include/asm-cris/bitops.h | 235 +- include/asm-cris/module.h | 5 - include/asm-cris/page.h | 6 +- include/asm-cris/poll.h | 1 - include/asm-cris/system.h | 3 +- include/asm-cris/unistd.h | 2 +- include/asm-frv/bitops.h | 174 +- include/asm-frv/futex.h | 6 - include/asm-frv/page.h | 7 +- include/asm-frv/system.h | 2 + include/asm-frv/unistd.h | 2 +- include/asm-generic/bitops.h | 76 +- include/asm-generic/bitops/__ffs.h | 43 - include/asm-generic/bitops/atomic.h | 191 - include/asm-generic/bitops/ext2-atomic.h | 22 - include/asm-generic/bitops/ext2-non-atomic.h | 18 - include/asm-generic/bitops/ffs.h | 41 - include/asm-generic/bitops/ffz.h | 12 - include/asm-generic/bitops/find.h | 13 - include/asm-generic/bitops/fls.h | 41 - include/asm-generic/bitops/fls64.h | 14 - include/asm-generic/bitops/hweight.h | 11 - include/asm-generic/bitops/le.h | 53 - include/asm-generic/bitops/minix-le.h | 17 - include/asm-generic/bitops/minix.h | 15 - include/asm-generic/bitops/non-atomic.h | 111 - include/asm-generic/bitops/sched.h | 36 - include/asm-generic/bug.h | 8 +- include/asm-generic/fcntl.h | 4 - include/asm-generic/futex.h | 6 - include/asm-generic/local.h | 91 +- include/asm-generic/memory_model.h | 77 - include/asm-generic/mman.h | 6 - include/asm-generic/mutex-dec.h | 30 +- include/asm-generic/mutex-xchg.h | 33 +- include/asm-generic/percpu.h | 7 +- include/asm-generic/vmlinux.lds.h | 14 - include/asm-h8300/bitops.h | 222 +- include/asm-h8300/module.h | 5 - include/asm-h8300/page.h | 6 +- include/asm-h8300/poll.h | 1 - include/asm-h8300/system.h | 2 + include/asm-h8300/types.h | 3 - include/asm-h8300/unistd.h | 2 +- include/asm-i386/a.out.h | 2 +- include/asm-i386/acpi.h | 10 +- include/asm-i386/alternative.h | 131 - include/asm-i386/apic.h | 4 - include/asm-i386/apicdef.h | 1 - include/asm-i386/arch_hooks.h | 3 - include/asm-i386/atomic.h | 41 +- include/asm-i386/bitops.h | 62 +- include/asm-i386/cache.h | 2 - include/asm-i386/cpufeature.h | 1 - include/asm-i386/crash.h | 75 - include/asm-i386/desc.h | 14 - include/asm-i386/dmi.h | 11 - include/asm-i386/e820.h | 4 - include/asm-i386/elf.h | 52 +- include/asm-i386/fixmap.h | 4 +- include/asm-i386/floppy.h | 34 + include/asm-i386/futex.h | 27 - include/asm-i386/hpet.h | 1 - include/asm-i386/io.h | 12 + include/asm-i386/io_apic.h | 1 - include/asm-i386/kdebug.h | 10 +- include/asm-i386/kprobes.h | 6 - include/asm-i386/local.h | 6 +- include/asm-i386/mach-default/do_timer.h | 2 +- include/asm-i386/mach-default/mach_time.h | 37 +- include/asm-i386/mach-default/mach_traps.h | 12 - include/asm-i386/mach-es7000/mach_mpparse.h | 10 +- include/asm-i386/mach-visws/do_timer.h | 2 +- include/asm-i386/mach-voyager/do_timer.h | 2 +- include/asm-i386/mach-xen/asm/agp.h | 37 - include/asm-i386/mach-xen/asm/desc.h | 178 - include/asm-i386/mach-xen/asm/dma-mapping.h | 152 - include/asm-i386/mach-xen/asm/fixmap.h | 165 - include/asm-i386/mach-xen/asm/floppy.h | 147 - include/asm-i386/mach-xen/asm/highmem.h | 81 - include/asm-i386/mach-xen/asm/hw_irq.h | 77 - include/asm-i386/mach-xen/asm/hypercall.h | 372 - include/asm-i386/mach-xen/asm/hypervisor.h | 220 - include/asm-i386/mach-xen/asm/io.h | 390 - include/asm-i386/mach-xen/asm/kmap_types.h | 32 - include/asm-i386/mach-xen/asm/mmu.h | 34 - include/asm-i386/mach-xen/asm/mmu_context.h | 109 - include/asm-i386/mach-xen/asm/page.h | 335 - include/asm-i386/mach-xen/asm/param.h | 24 - include/asm-i386/mach-xen/asm/pci.h | 154 - include/asm-i386/mach-xen/asm/pgalloc.h | 65 - .../mach-xen/asm/pgtable-2level-defs.h | 21 - .../asm-i386/mach-xen/asm/pgtable-2level.h | 88 - .../mach-xen/asm/pgtable-3level-defs.h | 25 - .../asm-i386/mach-xen/asm/pgtable-3level.h | 197 - include/asm-i386/mach-xen/asm/pgtable.h | 509 - include/asm-i386/mach-xen/asm/processor.h | 758 - include/asm-i386/mach-xen/asm/ptrace.h | 90 - include/asm-i386/mach-xen/asm/scatterlist.h | 22 - include/asm-i386/mach-xen/asm/segment.h | 117 - include/asm-i386/mach-xen/asm/setup.h | 64 - include/asm-i386/mach-xen/asm/smp.h | 104 - include/asm-i386/mach-xen/asm/spinlock.h | 200 - include/asm-i386/mach-xen/asm/swiotlb.h | 44 - include/asm-i386/mach-xen/asm/synch_bitops.h | 143 - include/asm-i386/mach-xen/asm/system.h | 578 - include/asm-i386/mach-xen/asm/tlbflush.h | 102 - include/asm-i386/mach-xen/asm/vga.h | 20 - include/asm-i386/mach-xen/irq_vectors.h | 125 - include/asm-i386/mach-xen/mach_traps.h | 33 - include/asm-i386/mach-xen/setup_arch_post.h | 101 - include/asm-i386/mach-xen/setup_arch_pre.h | 5 - include/asm-i386/mmu.h | 6 - include/asm-i386/mmzone.h | 17 + include/asm-i386/module.h | 5 - include/asm-i386/mpspec.h | 2 + include/asm-i386/mtrr.h | 1 - include/asm-i386/mutex.h | 6 +- include/asm-i386/numnodes.h | 18 + include/asm-i386/page.h | 22 +- include/asm-i386/pgalloc.h | 1 - include/asm-i386/pgtable-2level-defs.h | 2 - include/asm-i386/pgtable-2level.h | 2 - include/asm-i386/pgtable-3level-defs.h | 2 - include/asm-i386/pgtable-3level.h | 2 - include/asm-i386/pgtable.h | 5 +- include/asm-i386/poll.h | 1 - include/asm-i386/processor.h | 20 +- include/asm-i386/rwlock.h | 56 +- include/asm-i386/semaphore.h | 8 +- include/asm-i386/setup.h | 4 +- include/asm-i386/spinlock.h | 36 +- include/asm-i386/stat.h | 3 +- include/asm-i386/system.h | 72 +- include/asm-i386/thread_info.h | 1 - include/asm-i386/topology.h | 2 - include/asm-i386/types.h | 5 - include/asm-i386/uaccess.h | 12 +- include/asm-i386/unistd.h | 51 +- include/asm-ia64/acpi-ext.h | 11 +- include/asm-ia64/acpi.h | 5 +- include/asm-ia64/asmmacro.h | 15 - include/asm-ia64/atomic.h | 8 +- include/asm-ia64/bitops.h | 68 +- include/asm-ia64/cache.h | 2 - include/asm-ia64/compat.h | 6 - include/asm-ia64/crash.h | 90 - include/asm-ia64/dmi.h | 6 - include/asm-ia64/intel_intrin.h | 134 +- include/asm-ia64/io.h | 22 +- include/asm-ia64/kdebug.h | 6 +- include/asm-ia64/linkage.h | 8 - include/asm-ia64/machvec.h | 15 - include/asm-ia64/machvec_dig.h | 2 + include/asm-ia64/machvec_sn2.h | 4 +- include/asm-ia64/mca.h | 7 - include/asm-ia64/mman.h | 16 +- include/asm-ia64/module.h | 5 - include/asm-ia64/mutex.h | 93 +- include/asm-ia64/numa.h | 2 +- include/asm-ia64/numnodes.h | 15 + include/asm-ia64/page.h | 24 +- include/asm-ia64/pal.h | 37 +- include/asm-ia64/pgalloc.h | 4 - include/asm-ia64/pgtable.h | 5 +- include/asm-ia64/poll.h | 1 - include/asm-ia64/processor.h | 4 +- include/asm-ia64/signal.h | 2 + include/asm-ia64/sn/addrs.h | 8 - include/asm-ia64/sn/l1.h | 13 + include/asm-ia64/sn/pcibr_provider.h | 1 - include/asm-ia64/sn/pcidev.h | 38 +- include/asm-ia64/sn/rw_mmr.h | 56 +- include/asm-ia64/sn/sn2/sn_hwperf.h | 6 +- include/asm-ia64/sn/sn_feature_sets.h | 3 +- include/asm-ia64/sn/sn_sal.h | 47 +- include/asm-ia64/sn/tioce.h | 36 +- include/asm-ia64/sn/xpc.h | 23 +- include/asm-ia64/system.h | 9 - include/asm-ia64/thread_info.h | 14 +- include/asm-ia64/topology.h | 5 - include/asm-ia64/unistd.h | 10 +- include/asm-ia64/vga.h | 2 +- include/asm-m32r/assembler.h | 5 - include/asm-m32r/bitops.h | 457 +- include/asm-m32r/mappi3/mappi3_pld.h | 22 +- include/asm-m32r/mmzone.h | 14 + include/asm-m32r/module.h | 5 - include/asm-m32r/numnodes.h | 15 + include/asm-m32r/page.h | 5 +- include/asm-m32r/poll.h | 1 - include/asm-m32r/ptrace.h | 25 +- include/asm-m32r/semaphore.h | 64 +- include/asm-m32r/setup.h | 4 + include/asm-m32r/sigcontext.h | 2 - include/asm-m32r/system.h | 71 +- include/asm-m32r/unistd.h | 2 +- include/asm-m68k/atomic.h | 8 +- include/asm-m68k/bitops.h | 42 +- include/asm-m68k/module.h | 5 - include/asm-m68k/page.h | 2 - include/asm-m68k/poll.h | 1 - include/asm-m68k/stat.h | 3 +- include/asm-m68knommu/bitops.h | 221 +- include/asm-m68knommu/page.h | 2 - include/asm-mips/addrspace.h | 1 - include/asm-mips/asmmacro.h | 47 - include/asm-mips/bitops.h | 523 +- include/asm-mips/byteorder.h | 22 +- include/asm-mips/cacheflush.h | 1 - include/asm-mips/compat.h | 13 +- include/asm-mips/cpu-features.h | 2 +- include/asm-mips/cpu-info.h | 10 - include/asm-mips/cpu.h | 6 +- include/asm-mips/delay.h | 22 +- include/asm-mips/ds1742.h | 13 - include/asm-mips/elf.h | 45 +- include/asm-mips/fpu.h | 4 - include/asm-mips/futex.h | 145 +- include/asm-mips/hazards.h | 2 - include/asm-mips/inst.h | 33 +- include/asm-mips/interrupt.h | 73 +- include/asm-mips/io.h | 82 +- include/asm-mips/irq.h | 30 - include/asm-mips/kspd.h | 36 - include/asm-mips/linkage.h | 4 +- include/asm-mips/mach-cobalt/cobalt.h | 2 - include/asm-mips/mach-generic/ide.h | 46 +- include/asm-mips/mach-generic/mangle-port.h | 36 - include/asm-mips/mach-ip27/mangle-port.h | 9 - include/asm-mips/mach-ip32/mangle-port.h | 9 - include/asm-mips/mach-jmr3927/ds1742.h | 4 +- .../mach-mips/cpu-feature-overrides.h | 4 - include/asm-mips/mach-mips/param.h | 13 - include/asm-mips/mc146818-time.h | 33 +- include/asm-mips/mips-boards/atlas.h | 18 +- include/asm-mips/mips-boards/atlasint.h | 19 + include/asm-mips/mips-boards/generic.h | 1 - include/asm-mips/mips_mt.h | 15 - include/asm-mips/mipsmtregs.h | 16 +- include/asm-mips/mipsregs.h | 138 +- include/asm-mips/mmu_context.h | 119 +- include/asm-mips/mmzone.h | 14 + include/asm-mips/module.h | 12 +- include/asm-mips/numnodes.h | 7 + include/asm-mips/page.h | 7 +- include/asm-mips/pgtable-32.h | 61 +- include/asm-mips/pgtable-64.h | 13 +- include/asm-mips/pgtable.h | 93 +- include/asm-mips/poll.h | 1 - include/asm-mips/processor.h | 22 - include/asm-mips/ptrace.h | 4 - include/asm-mips/r4kcache.h | 129 - include/asm-mips/rtc.h | 4 +- include/asm-mips/rtlx.h | 38 +- include/asm-mips/serial.h | 97 +- include/asm-mips/sigcontext.h | 10 +- include/asm-mips/signal.h | 20 +- include/asm-mips/smp.h | 5 +- include/asm-mips/smtc.h | 55 - include/asm-mips/smtc_ipi.h | 118 - include/asm-mips/smtc_proc.h | 23 - include/asm-mips/sn/klconfig.h | 2 +- include/asm-mips/sn/mapped_kernel.h | 4 + include/asm-mips/sn/sn0/hubio.h | 12 +- include/asm-mips/sparsemem.h | 14 - include/asm-mips/stackframe.h | 205 +- include/asm-mips/system.h | 42 +- include/asm-mips/termbits.h | 2 +- include/asm-mips/thread_info.h | 2 +- include/asm-mips/time.h | 12 +- include/asm-mips/types.h | 5 - include/asm-mips/unistd.h | 18 +- include/asm-mips/vpe.h | 37 - include/asm-parisc/atomic.h | 3 - include/asm-parisc/bitops.h | 286 +- include/asm-parisc/cache.h | 4 +- include/asm-parisc/cacheflush.h | 17 +- include/asm-parisc/compat.h | 5 - include/asm-parisc/io.h | 130 +- include/asm-parisc/local.h | 16 +- include/asm-parisc/mmzone.h | 17 + include/asm-parisc/module.h | 8 - include/asm-parisc/numnodes.h | 7 + include/asm-parisc/page.h | 88 +- include/asm-parisc/pci.h | 5 - include/asm-parisc/pdc.h | 2 +- include/asm-parisc/pdc_chassis.h | 5 +- include/asm-parisc/pgtable.h | 63 +- include/asm-parisc/poll.h | 1 - include/asm-parisc/semaphore.h | 6 +- include/asm-parisc/spinlock.h | 16 +- include/asm-parisc/thread_info.h | 3 +- include/asm-parisc/unistd.h | 8 +- include/asm-powerpc/atomic.h | 38 +- include/asm-powerpc/bitops.h | 105 +- include/asm-powerpc/bug.h | 36 +- include/asm-powerpc/cputable.h | 341 +- include/asm-powerpc/cputime.h | 202 - include/asm-powerpc/eeh.h | 20 + include/asm-powerpc/elf.h | 3 +- include/asm-powerpc/firmware.h | 26 +- include/asm-powerpc/futex.h | 6 - include/asm-powerpc/hvcall.h | 184 +- include/asm-powerpc/hvconsole.h | 26 +- include/asm-powerpc/io.h | 6 +- include/asm-powerpc/iommu.h | 7 +- include/asm-powerpc/irq.h | 13 +- include/asm-powerpc/iseries/mf.h | 7 +- include/asm-powerpc/kdebug.h | 12 +- include/asm-powerpc/lmb.h | 19 +- include/asm-powerpc/machdep.h | 47 +- include/asm-powerpc/mmu.h | 1 + include/asm-powerpc/module.h | 10 - include/asm-powerpc/oprofile_impl.h | 17 +- include/asm-powerpc/paca.h | 9 +- include/asm-powerpc/page.h | 5 +- include/asm-powerpc/page_64.h | 1 - include/asm-powerpc/percpu.h | 7 +- include/asm-powerpc/pgalloc.h | 7 - include/asm-powerpc/pgtable-4k.h | 11 +- include/asm-powerpc/pgtable.h | 14 +- include/asm-powerpc/pmac_feature.h | 2 +- include/asm-powerpc/poll.h | 1 - include/asm-powerpc/ppc_asm.h | 42 - include/asm-powerpc/processor.h | 61 +- include/asm-powerpc/prom.h | 20 +- include/asm-powerpc/reg.h | 4 - include/asm-powerpc/rwsem.h | 2 +- include/asm-powerpc/smp.h | 2 +- include/asm-powerpc/spu.h | 12 +- include/asm-powerpc/string.h | 2 +- include/asm-powerpc/synch.h | 2 +- include/asm-powerpc/syscalls.h | 58 - include/asm-powerpc/system.h | 11 +- include/asm-powerpc/systemsim.h | 130 - include/asm-powerpc/termbits.h | 1 - include/asm-powerpc/thread_info.h | 8 - include/asm-powerpc/time.h | 15 - include/asm-powerpc/topology.h | 24 - include/asm-powerpc/types.h | 5 - include/asm-powerpc/uaccess.h | 19 +- include/asm-powerpc/unistd.h | 60 +- include/asm-powerpc/vdso_datapage.h | 3 - include/asm-ppc/commproc.h | 1 - include/asm-ppc/cpm2.h | 2 +- include/asm-ppc/harrier.h | 2 + include/asm-ppc/ibm44x.h | 2 +- include/asm-ppc/ibm4xx.h | 4 - include/asm-ppc/io.h | 7 - include/asm-ppc/machdep.h | 17 +- include/asm-ppc/mpc10x.h | 3 +- include/asm-ppc/mpc52xx.h | 13 +- include/asm-ppc/mpc8260.h | 1 - include/asm-ppc/mpc83xx.h | 1 - include/asm-ppc/mpc85xx.h | 1 - include/asm-ppc/mpc8xx.h | 3 - include/asm-ppc/page.h | 7 +- include/asm-ppc/pgalloc.h | 5 - include/asm-ppc/pgtable.h | 9 +- include/asm-ppc/ppc_sys.h | 13 +- include/asm-ppc/prom.h | 156 +- include/asm-ppc/reg_booke.h | 1 - include/asm-ppc/serial.h | 7 +- include/asm-ppc/time.h | 5 - include/asm-ppc/todc.h | 2 + include/asm-ppc/xparameters.h | 18 + include/asm-s390/atomic.h | 20 +- include/asm-s390/bitops.h | 48 +- include/asm-s390/bug.h | 5 +- include/asm-s390/cache.h | 2 - include/asm-s390/compat.h | 5 - include/asm-s390/ebcdic.h | 12 +- include/asm-s390/futex.h | 125 +- include/asm-s390/lowcore.h | 4 +- include/asm-s390/module.h | 3 - include/asm-s390/page.h | 5 +- include/asm-s390/percpu.h | 7 +- include/asm-s390/pgalloc.h | 11 +- include/asm-s390/poll.h | 1 - include/asm-s390/types.h | 5 - include/asm-s390/unistd.h | 8 +- include/asm-sh/addrspace.h | 2 +- include/asm-sh/bitops.h | 348 +- include/asm-sh/io.h | 14 + include/asm-sh/module.h | 5 - include/asm-sh/numnodes.h | 7 + include/asm-sh/page.h | 7 +- include/asm-sh/poll.h | 1 - include/asm-sh/stat.h | 8 +- include/asm-sh/thread_info.h | 2 +- include/asm-sh/types.h | 5 - include/asm-sh/unistd.h | 2 +- include/asm-sh64/bitops.h | 1 + include/asm-sh64/page.h | 7 +- include/asm-sh64/pgalloc.h | 14 +- include/asm-sh64/unistd.h | 2 +- include/asm-sparc/bitops.h | 388 +- include/asm-sparc/cpudata.h | 1 - include/asm-sparc/fcntl.h | 1 - include/asm-sparc/idprom.h | 26 +- include/asm-sparc/mman.h | 14 +- include/asm-sparc/module.h | 5 - include/asm-sparc/oplib.h | 2 - include/asm-sparc/page.h | 6 +- include/asm-sparc/pgalloc.h | 4 - include/asm-sparc/pgtable.h | 6 +- include/asm-sparc/poll.h | 1 - include/asm-sparc/smp.h | 9 +- include/asm-sparc/socket.h | 2 +- include/asm-sparc/spinlock.h | 25 +- include/asm-sparc/uaccess.h | 47 + include/asm-sparc/unistd.h | 18 +- include/asm-sparc/vga.h | 33 - include/asm-sparc64/a.out.h | 6 +- include/asm-sparc64/asi.h | 18 +- include/asm-sparc64/atomic.h | 10 +- include/asm-sparc64/bitops.h | 219 +- include/asm-sparc64/cache.h | 2 - include/asm-sparc64/cpudata.h | 206 +- include/asm-sparc64/dma-mapping.h | 2 +- include/asm-sparc64/elf.h | 22 +- include/asm-sparc64/fcntl.h | 1 - include/asm-sparc64/floppy.h | 2 +- include/asm-sparc64/futex.h | 24 - include/asm-sparc64/head.h | 15 - include/asm-sparc64/hypervisor.h | 2128 -- include/asm-sparc64/idprom.h | 12 +- include/asm-sparc64/intr_queue.h | 15 - include/asm-sparc64/irq.h | 4 - include/asm-sparc64/kdebug.h | 11 +- include/asm-sparc64/mman.h | 14 +- include/asm-sparc64/mmu.h | 57 +- include/asm-sparc64/mmu_context.h | 167 +- include/asm-sparc64/module.h | 5 - include/asm-sparc64/numnodes.h | 6 - include/asm-sparc64/oplib.h | 43 +- include/asm-sparc64/page.h | 49 +- include/asm-sparc64/pbm.h | 3 - include/asm-sparc64/pci.h | 58 +- include/asm-sparc64/percpu.h | 7 +- include/asm-sparc64/pgalloc.h | 168 +- include/asm-sparc64/pgtable.h | 708 +- include/asm-sparc64/pil.h | 4 +- include/asm-sparc64/poll.h | 1 - include/asm-sparc64/processor.h | 23 +- include/asm-sparc64/pstate.h | 9 +- include/asm-sparc64/scratchpad.h | 14 - include/asm-sparc64/smp.h | 30 +- include/asm-sparc64/sparsemem.h | 12 - include/asm-sparc64/spitfire.h | 1 - include/asm-sparc64/system.h | 7 +- include/asm-sparc64/thread_info.h | 9 +- include/asm-sparc64/timex.h | 6 - include/asm-sparc64/tlbflush.h | 25 +- include/asm-sparc64/tsb.h | 281 - include/asm-sparc64/ttable.h | 272 +- include/asm-sparc64/uaccess.h | 46 +- include/asm-sparc64/unistd.h | 16 +- include/asm-sparc64/vdev.h | 16 - include/asm-sparc64/xor.h | 34 +- include/asm-um/alternative.h | 6 - include/asm-um/desc.h | 12 +- include/asm-um/host_ldt-i386.h | 34 - include/asm-um/host_ldt-x86_64.h | 38 - include/asm-um/irqflags.h | 6 - include/asm-um/ldt.h | 41 - include/asm-um/module-i386.h | 4 - include/asm-um/page.h | 7 +- include/asm-um/processor-i386.h | 35 +- include/asm-um/processor-x86_64.h | 14 +- include/asm-um/ptrace-generic.h | 16 +- include/asm-um/ptrace-i386.h | 44 +- include/asm-um/segment.h | 6 - include/asm-um/thread_info.h | 16 +- include/asm-um/uaccess.h | 35 +- include/asm-v850/bitops.h | 220 +- include/asm-v850/linkage.h | 4 +- include/asm-v850/module.h | 5 - include/asm-v850/page.h | 6 +- include/asm-v850/poll.h | 1 - include/asm-v850/system.h | 2 + include/asm-x86_64/acpi.h | 2 + include/asm-x86_64/apic.h | 2 - include/asm-x86_64/apicdef.h | 1 - include/asm-x86_64/atomic.h | 8 +- include/asm-x86_64/bitops.h | 42 +- include/asm-x86_64/cache.h | 2 - include/asm-x86_64/crash.h | 75 - include/asm-x86_64/dmi.h | 27 - include/asm-x86_64/e820.h | 5 +- include/asm-x86_64/elf.h | 4 - include/asm-x86_64/floppy.h | 2 +- include/asm-x86_64/futex.h | 27 - include/asm-x86_64/hpet.h | 2 - include/asm-x86_64/hw_irq.h | 2 +- include/asm-x86_64/ia32_unistd.h | 2 + include/asm-x86_64/io.h | 40 +- include/asm-x86_64/io_apic.h | 1 - include/asm-x86_64/ipi.h | 2 - include/asm-x86_64/kdebug.h | 23 +- include/asm-x86_64/local.h | 18 +- include/asm-x86_64/mach-xen/asm/arch_hooks.h | 27 - include/asm-x86_64/mach-xen/asm/bootsetup.h | 42 - include/asm-x86_64/mach-xen/asm/desc.h | 263 - include/asm-x86_64/mach-xen/asm/dma-mapping.h | 191 - include/asm-x86_64/mach-xen/asm/dmi.h | 29 - include/asm-x86_64/mach-xen/asm/e820.h | 64 - include/asm-x86_64/mach-xen/asm/fixmap.h | 114 - include/asm-x86_64/mach-xen/asm/floppy.h | 206 - include/asm-x86_64/mach-xen/asm/hw_irq.h | 145 - include/asm-x86_64/mach-xen/asm/hypercall.h | 372 - include/asm-x86_64/mach-xen/asm/hypervisor.h | 2 - include/asm-x86_64/mach-xen/asm/io.h | 328 - include/asm-x86_64/mach-xen/asm/irq.h | 39 - include/asm-x86_64/mach-xen/asm/mmu.h | 38 - include/asm-x86_64/mach-xen/asm/mmu_context.h | 136 - include/asm-x86_64/mach-xen/asm/msr.h | 399 - include/asm-x86_64/mach-xen/asm/nmi.h | 75 - include/asm-x86_64/mach-xen/asm/page.h | 331 - include/asm-x86_64/mach-xen/asm/param.h | 23 - include/asm-x86_64/mach-xen/asm/pci.h | 174 - include/asm-x86_64/mach-xen/asm/pgalloc.h | 233 - include/asm-x86_64/mach-xen/asm/pgtable.h | 564 - include/asm-x86_64/mach-xen/asm/processor.h | 496 - include/asm-x86_64/mach-xen/asm/ptrace.h | 125 - include/asm-x86_64/mach-xen/asm/smp.h | 153 - .../asm-x86_64/mach-xen/asm/synch_bitops.h | 2 - include/asm-x86_64/mach-xen/asm/system.h | 428 - include/asm-x86_64/mach-xen/asm/timer.h | 67 - include/asm-x86_64/mach-xen/asm/tlbflush.h | 104 - include/asm-x86_64/mach-xen/asm/vga.h | 20 - include/asm-x86_64/mach-xen/asm/xor.h | 328 - include/asm-x86_64/mach-xen/irq_vectors.h | 123 - include/asm-x86_64/mach-xen/mach_time.h | 111 - include/asm-x86_64/mach-xen/mach_timer.h | 48 - include/asm-x86_64/mach-xen/setup_arch_post.h | 58 - include/asm-x86_64/mach-xen/setup_arch_pre.h | 5 - include/asm-x86_64/mce.h | 7 - include/asm-x86_64/mmu_context.h | 6 +- include/asm-x86_64/mmzone.h | 16 +- include/asm-x86_64/module.h | 5 - include/asm-x86_64/numa.h | 7 +- include/asm-x86_64/numnodes.h | 12 + include/asm-x86_64/page.h | 7 +- include/asm-x86_64/pda.h | 2 +- include/asm-x86_64/percpu.h | 7 +- include/asm-x86_64/pgalloc.h | 35 - include/asm-x86_64/pgtable.h | 16 +- include/asm-x86_64/poll.h | 1 - include/asm-x86_64/processor.h | 7 +- include/asm-x86_64/proto.h | 3 + include/asm-x86_64/smp.h | 1 - include/asm-x86_64/string.h | 17 +- include/asm-x86_64/suspend.h | 4 +- include/asm-x86_64/system.h | 28 +- include/asm-x86_64/timex.h | 2 +- include/asm-x86_64/topology.h | 2 - include/asm-x86_64/unistd.h | 26 +- include/asm-xtensa/bitops.h | 340 +- include/asm-xtensa/ioctls.h | 2 +- include/asm-xtensa/page.h | 6 +- include/asm-xtensa/poll.h | 1 - include/asm-xtensa/signal.h | 2 +- include/asm-xtensa/system.h | 2 + include/linux/adb.h | 2 +- include/linux/amba/clcd.h | 12 +- include/linux/amba/serial.h | 6 - include/linux/arcdevice.h | 9 + include/linux/ata.h | 29 +- include/linux/audit.h | 146 +- include/linux/auto_fs4.h | 51 +- include/linux/bitmap.h | 15 +- include/linux/bitops.h | 131 +- include/linux/blkdev.h | 37 +- include/linux/blktrace_api.h | 277 - include/linux/bootmem.h | 5 - include/linux/buffer_head.h | 27 +- include/linux/cache.h | 4 +- include/linux/capability.h | 3 +- include/linux/cdev.h | 4 +- include/linux/cdrom.h | 5 +- include/linux/clk.h | 4 +- include/linux/coda_linux.h | 6 +- include/linux/compat.h | 46 - include/linux/compat_ioctl.h | 6 - include/linux/config.h | 4 +- include/linux/cpu.h | 1 + include/linux/cpumask.h | 50 +- include/linux/cpuset.h | 54 +- include/linux/crash_dump.h | 2 +- include/linux/crypto.h | 24 +- include/linux/crypto/ksign.h | 22 - include/linux/crypto/mpi.h | 147 - include/linux/dcache.h | 11 +- include/linux/dccp.h | 132 +- include/linux/delay.h | 17 +- include/linux/device-mapper.h | 1 - include/linux/device.h | 7 +- include/linux/dio.h | 32 + include/linux/dm-ioctl.h | 17 +- include/linux/dma-mapping.h | 3 - include/linux/dmi.h | 2 - include/linux/dn.h | 44 +- include/linux/dvb/audio.h | 13 - include/linux/dvb/video.h | 13 - include/linux/efi.h | 20 +- include/linux/efs_fs.h | 2 +- include/linux/elevator.h | 12 +- include/linux/errno.h | 3 - include/linux/etherdevice.h | 5 +- include/linux/ethtool.h | 2 - include/linux/eventpoll.h | 8 +- include/linux/ext3_fs.h | 18 +- include/linux/ext3_fs_i.h | 7 +- include/linux/fb.h | 2 +- include/linux/file.h | 30 +- include/linux/firmware.h | 1 + include/linux/fs.h | 139 +- include/linux/fs_uart_pd.h | 60 - include/linux/fsl_devices.h | 19 +- include/linux/fsnotify.h | 33 +- include/linux/futex.h | 89 - include/linux/gameport.h | 11 +- include/linux/generic_serial.h | 4 +- include/linux/genhd.h | 30 +- include/linux/gfp.h | 10 +- include/linux/gigaset_dev.h | 32 - include/linux/highmem.h | 18 - include/linux/hrtimer.h | 57 +- include/linux/hugetlb.h | 47 +- include/linux/hwmon-sysfs.h | 24 +- include/linux/i2c-id.h | 6 +- include/linux/i2c.h | 6 +- include/linux/i2o.h | 4 +- include/linux/icmpv6.h | 11 +- include/linux/ide.h | 2 +- include/linux/idr.h | 1 - include/linux/if.h | 29 +- include/linux/if_ether.h | 1 - include/linux/igmp.h | 2 +- include/linux/in.h | 1 - include/linux/inetdevice.h | 1 - include/linux/init.h | 7 +- include/linux/init_task.h | 12 +- include/linux/inotify.h | 11 - include/linux/input.h | 129 +- include/linux/interrupt.h | 6 - include/linux/ipmi.h | 3 +- include/linux/ipmi_msgdefs.h | 1 - include/linux/ipmi_smi.h | 63 +- include/linux/ipv6.h | 14 - include/linux/ipv6_route.h | 10 - include/linux/irda.h | 1 - include/linux/irq.h | 49 +- include/linux/jbd.h | 13 +- include/linux/jiffies.h | 6 - include/linux/kbd_kern.h | 2 - include/linux/kernel.h | 13 +- include/linux/kernel_stat.h | 2 +- include/linux/keyboard.h | 13 - include/linux/kmod.h | 2 - include/linux/kobj_map.h | 4 +- include/linux/kobject.h | 7 +- include/linux/kprobes.h | 3 +- include/linux/ktime.h | 20 + include/linux/leds.h | 110 - include/linux/libata.h | 214 +- include/linux/libps2.h | 1 + include/linux/linkage.h | 16 +- include/linux/list.h | 48 +- include/linux/lockd/lockd.h | 27 +- include/linux/lockd/share.h | 2 +- include/linux/lockd/xdr.h | 1 - include/linux/loop.h | 3 +- include/linux/m48t86.h | 16 - include/linux/major.h | 1 - include/linux/memory.h | 1 + include/linux/memory_hotplug.h | 11 +- include/linux/mempolicy.h | 5 - include/linux/mempool.h | 38 - include/linux/migrate.h | 39 - include/linux/miscdevice.h | 2 +- include/linux/mm.h | 74 +- include/linux/mm_inline.h | 2 +- include/linux/mmc/card.h | 1 - include/linux/mmc/mmc.h | 1 - include/linux/mmzone.h | 93 +- include/linux/mod_devicetable.h | 48 - include/linux/module.h | 33 +- include/linux/moduleparam.h | 7 + include/linux/msdos_fs.h | 12 +- include/linux/mtd/blktrans.h | 4 +- include/linux/mtd/doc2000.h | 4 +- include/linux/mtd/inftl.h | 5 - include/linux/mv643xx.h | 29 +- include/linux/namei.h | 5 +- include/linux/nbd.h | 3 +- include/linux/ncp_fs.h | 4 +- include/linux/ncp_fs_i.h | 2 +- include/linux/ncp_fs_sb.h | 5 +- include/linux/net.h | 11 - include/linux/netdevice.h | 173 +- include/linux/netfilter.h | 51 +- include/linux/netfilter/nfnetlink.h | 1 - include/linux/netfilter/nfnetlink_log.h | 6 - include/linux/netfilter/x_tables.h | 180 +- include/linux/netfilter/xt_esp.h | 14 - include/linux/netfilter/xt_multiport.h | 30 - include/linux/netfilter/xt_policy.h | 58 - include/linux/netfilter_arp/arp_tables.h | 37 +- include/linux/netfilter_bridge.h | 28 + include/linux/netfilter_ipv4.h | 2 - include/linux/netfilter_ipv4/ip_conntrack.h | 19 +- .../linux/netfilter_ipv4/ip_conntrack_h323.h | 82 - .../ip_conntrack_helper_h323_asn1.h | 98 - .../ip_conntrack_helper_h323_types.h | 938 - include/linux/netfilter_ipv4/ip_nat.h | 2 +- include/linux/netfilter_ipv4/ip_tables.h | 88 +- include/linux/netfilter_ipv4/ipt_esp.h | 14 +- include/linux/netfilter_ipv4/ipt_multiport.h | 31 +- include/linux/netfilter_ipv4/ipt_policy.h | 69 +- include/linux/netfilter_ipv6.h | 3 - include/linux/netfilter_ipv6/ip6_tables.h | 69 +- include/linux/netfilter_ipv6/ip6t_esp.h | 12 +- include/linux/netfilter_ipv6/ip6t_multiport.h | 25 +- include/linux/netfilter_ipv6/ip6t_policy.h | 69 +- include/linux/netlink.h | 2 - include/linux/nfs_fs.h | 106 +- include/linux/nfs_fs_i.h | 8 +- include/linux/nfs_fs_sb.h | 6 - include/linux/nfs_xdr.h | 5 +- include/linux/nfsd/export.h | 29 +- include/linux/nfsd/syscall.h | 14 +- include/linux/nodemask.h | 4 - include/linux/notifier.h | 96 +- include/linux/numa.h | 8 +- include/linux/oprofile.h | 25 +- include/linux/page-flags.h | 40 +- include/linux/pagemap.h | 11 +- include/linux/pci-acpi.h | 5 +- include/linux/pci.h | 43 +- include/linux/pci_ids.h | 40 +- include/linux/pfn.h | 9 - include/linux/pid.h | 101 +- include/linux/pipe_fs_i.h | 77 +- include/linux/platform.h | 43 + include/linux/pm.h | 11 +- include/linux/pm_legacy.h | 7 + include/linux/poll.h | 17 - include/linux/ppdev.h | 2 + include/linux/proc_fs.h | 15 +- include/linux/profile.h | 2 +- include/linux/ptrace.h | 1 - include/linux/qnx4_fs.h | 4 +- include/linux/quota.h | 8 +- include/linux/radix-tree.h | 13 +- include/linux/raid/md.h | 3 - include/linux/raid/md_k.h | 21 +- include/linux/raid/md_p.h | 32 +- include/linux/raid/raid5.h | 25 +- include/linux/ramfs.h | 2 +- include/linux/rcupdate.h | 3 +- include/linux/reiserfs_fs.h | 9 +- include/linux/reiserfs_xattr.h | 6 +- include/linux/{relay.h => relayfs_fs.h} | 44 +- include/linux/resource.h | 5 +- include/linux/root_dev.h | 3 - include/linux/rtc.h | 92 - include/linux/rtnetlink.h | 27 +- include/linux/sched.h | 115 +- include/linux/screen_info.h | 3 +- include/linux/sdla_asy.h | 226 + include/linux/sdla_chdlc.h | 813 + include/linux/sdla_ppp.h | 575 + include/linux/sdla_x25.h | 772 + include/linux/sdladrv.h | 66 + include/linux/sdlapci.h | 72 + include/linux/sdlasfm.h | 104 + include/linux/security.h | 64 +- include/linux/selinux.h | 177 - include/linux/seq_file.h | 4 +- include/linux/seqlock.h | 4 +- include/linux/serial_8250.h | 1 - include/linux/serial_core.h | 7 - include/linux/serio.h | 15 +- include/linux/signal.h | 6 +- include/linux/skbuff.h | 158 +- include/linux/slab.h | 44 +- include/linux/smp.h | 29 +- include/linux/socket.h | 5 - include/linux/sound.h | 12 +- include/linux/spi/ads7846.h | 7 - include/linux/spi/spi.h | 45 +- include/linux/spi/spi_bitbang.h | 8 - include/linux/squashfs_fs.h | 519 - include/linux/squashfs_fs_i.h | 43 - include/linux/squashfs_fs_sb.h | 65 - include/linux/stat.h | 2 +- include/linux/statfs.h | 10 +- include/linux/string.h | 17 +- include/linux/sunrpc/cache.h | 145 +- include/linux/sunrpc/clnt.h | 20 +- include/linux/sunrpc/gss_krb5.h | 2 - include/linux/sunrpc/metrics.h | 89 - include/linux/sunrpc/rpc_pipe_fs.h | 2 - include/linux/sunrpc/sched.h | 9 +- include/linux/sunrpc/stats.h | 4 +- include/linux/sunrpc/svc.h | 9 +- include/linux/sunrpc/svcauth.h | 12 +- include/linux/sunrpc/svcsock.h | 2 +- include/linux/sunrpc/xprt.h | 14 - include/linux/swap.h | 46 +- include/linux/synclink.h | 11 +- include/linux/syscalls.h | 19 - include/linux/sysctl.h | 80 - include/linux/sysfs.h | 6 - include/linux/tcp.h | 6 - include/linux/threads.h | 3 +- include/linux/time.h | 19 +- include/linux/timer.h | 17 +- include/linux/timex.h | 43 +- include/linux/tiocl.h | 1 - include/linux/topology.h | 9 - include/linux/tty.h | 8 +- include/linux/tty_flip.h | 37 +- include/linux/types.h | 4 - include/linux/udf_fs_i.h | 21 + include/linux/udf_fs_sb.h | 4 +- include/linux/ufs_fs.h | 4 +- include/linux/uinput.h | 4 +- include/linux/usb.h | 4 +- include/linux/usb/net2280.h | 444 - include/linux/usb_gadget.h | 7 +- include/linux/vermagic.h | 7 +- include/linux/videodev2.h | 29 +- include/linux/vs_base.h | 2 + include/linux/vs_context.h | 1 + include/linux/vs_network.h | 4 + include/linux/vs_socket.h | 22 +- include/linux/vserver/cacct.h | 15 + include/linux/vserver/cvirt_def.h | 6 +- include/linux/wait.h | 8 +- include/linux/wanpipe.h | 483 + include/linux/wireless.h | 10 +- include/linux/workqueue.h | 6 - include/linux/writeback.h | 14 +- include/linux/x25.h | 26 - include/linux/xfrm.h | 30 - include/linux/zorro.h | 33 + include/media/audiochip.h | 14 + include/media/cs53l32a.h | 34 - include/media/cx25840.h | 64 - include/media/i2c-addr.h | 44 - include/media/ir-common.h | 40 +- include/media/msp3400.h | 226 - include/media/rds.h | 44 - include/media/saa7115.h | 37 - include/media/saa7127.h | 41 - include/media/saa7146.h | 21 +- include/media/saa7146_vv.h | 3 +- include/media/tuner-types.h | 3 +- include/media/tuner.h | 6 +- include/media/tvaudio.h | 30 - include/media/upd64031a.h | 40 - include/media/upd64083.h | 58 - include/media/v4l2-common.h | 65 +- include/media/video-buf-dvb.h | 2 +- include/media/video-buf.h | 58 +- include/media/wm8775.h | 35 - include/net/af_unix.h | 3 +- include/net/arp.h | 2 + include/net/ax25.h | 10 +- include/net/compat.h | 5 +- include/net/dn.h | 105 +- include/net/dn_dev.h | 88 +- include/net/dn_fib.h | 22 +- include/net/dn_neigh.h | 4 +- include/net/dn_nsp.h | 72 +- include/net/dn_route.h | 12 +- include/net/flow.h | 8 +- include/net/ieee80211.h | 183 +- include/net/ieee80211_crypt.h | 3 +- include/net/ieee80211softmac.h | 297 - include/net/ieee80211softmac_wx.h | 94 - include/net/if_inet6.h | 3 + include/net/inet6_hashtables.h | 70 +- include/net/inet_connection_sock.h | 26 - include/net/inet_timewait_sock.h | 2 +- include/net/ip.h | 4 - include/net/ip6_route.h | 24 +- include/net/ipv6.h | 24 +- include/net/ipx.h | 4 +- include/net/irda/irlmp.h | 2 +- include/net/iw_handler.h | 12 +- include/net/llc.h | 2 +- include/net/ndisc.h | 2 - include/net/neighbour.h | 3 +- include/net/netfilter/nf_conntrack.h | 77 +- include/net/netrom.h | 8 +- include/net/pkt_sched.h | 7 +- include/net/protocol.h | 3 - include/net/request_sock.h | 2 +- include/net/rose.h | 14 +- include/net/route.h | 4 +- include/net/scm.h | 10 +- include/net/sctp/command.h | 1 - include/net/sctp/structs.h | 10 - include/net/sock.h | 134 +- include/net/tc_act/tc_ipt.h | 4 +- include/net/tcp.h | 29 +- include/net/tux.h | 804 - include/net/tux_u.h | 163 - include/net/x25.h | 21 +- include/net/x25device.h | 1 - include/net/xfrm.h | 105 +- include/pcmcia/bulkmem.h | 4 +- include/pcmcia/ciscode.h | 5 +- include/pcmcia/cistpl.h | 21 +- include/pcmcia/cs.h | 34 +- include/pcmcia/ds.h | 80 +- include/pcmcia/ss.h | 11 +- include/rdma/ib_fmr_pool.h | 2 - include/rdma/ib_mad.h | 75 +- include/rdma/ib_sa.h | 28 + include/rdma/ib_user_verbs.h | 79 +- include/rdma/ib_verbs.h | 66 +- include/scsi/scsi.h | 2 + include/scsi/scsi_cmnd.h | 20 +- include/scsi/scsi_device.h | 26 +- include/scsi/scsi_devinfo.h | 1 - include/scsi/scsi_eh.h | 3 - include/scsi/scsi_host.h | 17 +- include/scsi/scsi_ioctl.h | 2 + include/scsi/scsi_transport.h | 16 - include/scsi/scsi_transport_fc.h | 41 +- include/scsi/scsi_transport_sas.h | 50 +- include/scsi/scsi_transport_spi.h | 4 - include/scsi/srp.h | 23 +- include/sound/ac97_codec.h | 15 +- include/sound/ad1848.h | 2 +- include/sound/ak4531_codec.h | 2 +- include/sound/core.h | 18 +- include/sound/cs4231.h | 4 +- include/sound/cs46xx.h | 2 +- include/sound/emu10k1.h | 4 +- include/sound/emux_synth.h | 2 +- include/sound/gus.h | 6 +- include/sound/hwdep.h | 2 +- include/sound/i2c.h | 10 +- include/sound/info.h | 2 +- include/sound/initval.h | 3 +- include/sound/mixer_oss.h | 2 +- include/sound/opl3.h | 4 +- include/sound/pcm.h | 26 +- include/sound/pcm_oss.h | 9 +- include/sound/rawmidi.h | 4 +- include/sound/sb16_csp.h | 2 +- include/sound/seq_instr.h | 2 +- include/sound/soundfont.h | 2 +- include/sound/util_mem.h | 4 +- include/sound/version.h | 4 +- include/sound/vx_core.h | 2 +- include/sound/ymfpci.h | 10 +- include/video/pm3fb.h | 3 + include/xen/balloon.h | 63 - include/xen/cpu_hotplug.h | 44 - include/xen/driver_util.h | 16 - include/xen/evtchn.h | 114 - include/xen/features.h | 20 - include/xen/foreign_page.h | 30 - include/xen/gnttab.h | 151 - include/xen/hypervisor_sysfs.h | 32 - include/xen/interface/acm.h | 188 - include/xen/interface/acm_ops.h | 103 - include/xen/interface/arch-powerpc.h | 120 - include/xen/interface/arch-x86_32.h | 234 - include/xen/interface/arch-x86_64.h | 300 - include/xen/interface/callback.h | 74 - include/xen/interface/dom0_ops.h | 605 - include/xen/interface/event_channel.h | 233 - include/xen/interface/features.h | 53 - include/xen/interface/grant_table.h | 362 - include/xen/interface/hvm/hvm_info_table.h | 22 - include/xen/interface/hvm/ioreq.h | 99 - include/xen/interface/hvm/params.h | 24 - include/xen/interface/hvm/vmx_assist.h | 98 - include/xen/interface/io/blkif.h | 87 - include/xen/interface/io/console.h | 33 - include/xen/interface/io/netif.h | 166 - include/xen/interface/io/pciif.h | 55 - include/xen/interface/io/ring.h | 273 - include/xen/interface/io/tpmif.h | 59 - include/xen/interface/io/xenbus.h | 45 - include/xen/interface/io/xs_wire.h | 97 - include/xen/interface/memory.h | 243 - include/xen/interface/nmi.h | 60 - include/xen/interface/physdev.h | 149 - include/xen/interface/sched.h | 103 - include/xen/interface/sched_ctl.h | 69 - include/xen/interface/trace.h | 87 - include/xen/interface/vcpu.h | 121 - include/xen/interface/version.h | 73 - include/xen/interface/xen-compat.h | 47 - include/xen/interface/xen.h | 512 - include/xen/interface/xenoprof.h | 103 - include/xen/pcifront.h | 77 - include/xen/public/evtchn.h | 91 - include/xen/public/privcmd.h | 79 - include/xen/xen_proc.h | 13 - include/xen/xenbus.h | 299 - include/xen/xencons.h | 14 - init/Kconfig | 73 +- init/calibrate.c | 2 +- init/do_mounts.c | 8 +- init/do_mounts_initrd.c | 1 - init/initramfs.c | 20 +- init/main.c | 106 +- ipc/compat.c | 2 +- ipc/mqueue.c | 6 +- ipc/msg.c | 36 +- ipc/sem.c | 55 +- ipc/shm.c | 64 +- ipc/util.c | 44 +- ipc/util.h | 4 +- kernel/Kconfig.preempt | 1 - kernel/Makefile | 9 +- kernel/acct.c | 12 +- kernel/audit.c | 333 +- kernel/audit.h | 92 - kernel/auditfilter.c | 857 - kernel/auditsc.c | 918 +- kernel/capability.c | 19 - kernel/compat.c | 82 +- kernel/cpu.c | 32 +- kernel/cpuset.c | 454 +- kernel/exit.c | 171 +- kernel/extable.c | 2 +- kernel/fork.c | 174 +- kernel/futex.c | 175 +- kernel/futex_compat.c | 145 - kernel/hrtimer.c | 205 +- kernel/irq/Makefile | 2 +- kernel/irq/migration.c | 62 - kernel/irq/spurious.c | 3 +- kernel/itimer.c | 117 +- kernel/kmod.c | 35 +- kernel/kprobes.c | 27 +- kernel/ksysfs.c | 7 +- kernel/kthread.c | 9 +- kernel/module-verify-sig.c | 442 - kernel/module-verify.c | 340 - kernel/module-verify.h | 15 - kernel/module.c | 492 +- kernel/panic.c | 103 +- kernel/params.c | 24 +- kernel/pid.c | 256 +- kernel/posix-cpu-timers.c | 30 +- kernel/posix-timers.c | 68 +- kernel/power/Kconfig | 14 +- kernel/power/Makefile | 2 +- kernel/power/console.c | 32 +- kernel/power/disk.c | 20 +- kernel/power/main.c | 4 +- kernel/power/pm.c | 37 +- kernel/power/power.h | 75 +- kernel/power/process.c | 61 +- kernel/power/smp.c | 4 +- kernel/power/snapshot.c | 340 +- kernel/power/swap.c | 545 - kernel/power/swsusp.c | 887 +- kernel/power/user.c | 333 - kernel/printk.c | 129 +- kernel/profile.c | 66 +- kernel/ptrace.c | 17 +- kernel/rcupdate.c | 48 +- kernel/rcutorture.c | 37 +- kernel/relay.c | 1012 - kernel/sched.c | 366 +- kernel/signal.c | 405 +- kernel/softirq.c | 26 +- kernel/softlockup.c | 61 +- kernel/spinlock.c | 9 +- kernel/sys.c | 521 +- kernel/sys_ni.c | 16 - kernel/sysctl.c | 76 +- kernel/time.c | 71 +- kernel/timer.c | 213 +- kernel/user.c | 10 +- kernel/vserver/context.c | 47 +- kernel/vserver/helper.c | 6 +- kernel/vserver/history.c | 8 +- kernel/vserver/legacy.c | 4 +- kernel/vserver/legacynet.c | 1 + kernel/vserver/limit.c | 71 +- kernel/vserver/network.c | 43 +- kernel/vserver/proc.c | 2 + kernel/vserver/switch.c | 4 +- kernel/wait.c | 26 +- kernel/workqueue.c | 31 +- lib/Kconfig.debug | 51 +- lib/Makefile | 6 - lib/bitmap.c | 182 +- lib/cpumask.c | 45 - lib/extable.c | 1 + lib/find_next_bit.c | 3 + lib/hweight.c | 53 - lib/idr.c | 59 +- lib/kobject.c | 66 +- lib/kobject_uevent.c | 10 +- lib/kref.c | 7 +- lib/radix-tree.c | 49 +- lib/reed_solomon/reed_solomon.c | 11 +- lib/spinlock_debug.c | 39 +- lib/string.c | 4 +- lib/swiotlb.c | 32 +- mm/Kconfig | 14 +- mm/Makefile | 4 +- mm/bootmem.c | 50 +- mm/fadvise.c | 26 +- mm/filemap.c | 121 +- mm/filemap.h | 4 +- mm/fremap.c | 20 +- mm/highmem.c | 52 +- mm/hugetlb.c | 285 +- mm/internal.h | 21 +- mm/memory.c | 143 +- mm/memory_hotplug.c | 14 +- mm/mempolicy.c | 151 +- mm/mempool.c | 50 +- mm/migrate.c | 662 - mm/mincore.c | 183 +- mm/mmap.c | 252 +- mm/mmzone.c | 50 - mm/mprotect.c | 17 +- mm/mremap.c | 4 +- mm/msync.c | 139 +- mm/nommu.c | 22 +- mm/oom_kill.c | 72 +- mm/page-writeback.c | 69 +- mm/page_alloc.c | 266 +- mm/readahead.c | 33 +- mm/rmap.c | 14 +- mm/shmem.c | 17 +- mm/slab.c | 1342 +- mm/slob.c | 20 +- mm/sparse.c | 16 +- mm/swap.c | 66 +- mm/swap_state.c | 4 +- mm/swapfile.c | 74 +- mm/truncate.c | 2 - mm/util.c | 47 +- mm/vmalloc.c | 3 +- mm/vmscan.c | 899 +- net/802/psnap.c | 4 +- net/802/tr.c | 1 + net/8021q/vlan.c | 47 +- net/8021q/vlan_dev.c | 6 +- net/Kconfig | 4 - net/Makefile | 1 - net/appletalk/ddp.c | 19 - net/atm/clip.c | 426 +- net/atm/common.c | 4 +- net/atm/ioctl.c | 15 +- net/atm/resources.c | 32 +- net/atm/resources.h | 3 +- net/ax25/af_ax25.c | 93 +- net/ax25/ax25_addr.c | 9 - net/ax25/ax25_ds_timer.c | 3 +- net/ax25/ax25_iface.c | 13 - net/ax25/ax25_ip.c | 3 - net/ax25/ax25_out.c | 3 - net/ax25/ax25_route.c | 2 +- net/ax25/ax25_timer.c | 3 - net/ax25/ax25_uid.c | 4 - net/ax25/sysctl_net_ax25.c | 10 +- net/bluetooth/af_bluetooth.c | 3 - net/bluetooth/bnep/core.c | 4 +- net/bluetooth/cmtp/capi.c | 39 +- net/bluetooth/hci_core.c | 8 +- net/bluetooth/rfcomm/core.c | 8 +- net/bluetooth/sco.c | 2 +- net/bridge/Kconfig | 1 - net/bridge/br.c | 13 - net/bridge/br_device.c | 11 +- net/bridge/br_fdb.c | 6 +- net/bridge/br_forward.c | 8 +- net/bridge/br_if.c | 60 +- net/bridge/br_input.c | 47 +- net/bridge/br_ioctl.c | 9 +- net/bridge/br_netfilter.c | 222 +- net/bridge/br_private.h | 6 +- net/bridge/br_stp_bpdu.c | 197 +- net/bridge/br_stp_timer.c | 47 +- net/bridge/br_sysfs_br.c | 1 + net/bridge/netfilter/ebt_802_3.c | 8 +- net/bridge/netfilter/ebt_among.c | 8 +- net/bridge/netfilter/ebt_arp.c | 8 +- net/bridge/netfilter/ebt_arpreply.c | 8 +- net/bridge/netfilter/ebt_dnat.c | 8 +- net/bridge/netfilter/ebt_ip.c | 8 +- net/bridge/netfilter/ebt_limit.c | 8 +- net/bridge/netfilter/ebt_log.c | 10 +- net/bridge/netfilter/ebt_mark.c | 8 +- net/bridge/netfilter/ebt_mark_m.c | 8 +- net/bridge/netfilter/ebt_pkttype.c | 8 +- net/bridge/netfilter/ebt_redirect.c | 8 +- net/bridge/netfilter/ebt_snat.c | 8 +- net/bridge/netfilter/ebt_stp.c | 8 +- net/bridge/netfilter/ebt_ulog.c | 8 +- net/bridge/netfilter/ebt_vlan.c | 8 +- net/bridge/netfilter/ebtable_broute.c | 8 +- net/bridge/netfilter/ebtable_filter.c | 8 +- net/bridge/netfilter/ebtable_nat.c | 8 +- net/bridge/netfilter/ebtables.c | 202 +- net/compat.c | 117 +- net/core/Makefile | 2 +- net/core/datagram.c | 2 - net/core/dev.c | 583 +- net/core/dev_mcast.c | 28 +- net/core/dv.c | 5 +- net/core/ethtool.c | 37 +- net/core/filter.c | 5 +- net/core/flow.c | 15 +- net/core/gen_estimator.c | 3 +- net/core/link_watch.c | 54 +- net/core/neighbour.c | 49 +- net/core/net-sysfs.c | 90 +- net/core/netpoll.c | 15 +- net/core/pktgen.c | 2992 +-- net/core/request_sock.c | 6 +- net/core/rtnetlink.c | 176 +- net/core/skbuff.c | 234 +- net/core/sock.c | 159 +- net/core/stream.c | 1 - net/core/sysctl_net_core.c | 23 - net/core/utils.c | 4 +- net/core/wireless.c | 919 +- net/dccp/Kconfig | 13 +- net/dccp/Makefile | 9 +- net/dccp/ackvec.c | 297 +- net/dccp/ackvec.h | 53 +- net/dccp/ccid.c | 189 +- net/dccp/ccid.h | 129 +- net/dccp/ccids/Kconfig | 43 +- net/dccp/ccids/Makefile | 4 - net/dccp/ccids/ccid2.c | 779 - net/dccp/ccids/ccid2.h | 85 - net/dccp/ccids/ccid3.c | 112 +- net/dccp/ccids/ccid3.h | 5 +- net/dccp/dccp.h | 133 +- net/dccp/diag.c | 2 +- net/dccp/feat.c | 586 - net/dccp/feat.h | 29 - net/dccp/input.c | 28 +- net/dccp/ipv4.c | 333 +- net/dccp/ipv6.c | 373 +- net/dccp/minisocks.c | 37 +- net/dccp/options.c | 291 +- net/dccp/output.c | 88 +- net/dccp/proto.c | 455 +- net/dccp/sysctl.c | 124 - net/dccp/timer.c | 14 +- net/decnet/af_decnet.c | 18 +- net/decnet/dn_dev.c | 46 +- net/decnet/dn_fib.c | 8 +- net/decnet/dn_neigh.c | 29 +- net/decnet/dn_nsp_in.c | 31 +- net/decnet/dn_nsp_out.c | 38 +- net/decnet/dn_route.c | 63 +- net/decnet/dn_rules.c | 118 +- net/decnet/dn_table.c | 12 +- net/decnet/netfilter/dn_rtmsg.c | 8 +- net/decnet/sysctl_net_decnet.c | 12 +- net/econet/af_econet.c | 124 +- net/ethernet/Makefile | 1 + net/ethernet/sysctl_net_ether.c | 14 + net/ieee80211/Kconfig | 1 - net/ieee80211/Makefile | 1 - net/ieee80211/ieee80211_crypt.c | 11 +- net/ieee80211/ieee80211_crypt_ccmp.c | 8 +- net/ieee80211/ieee80211_crypt_tkip.c | 56 +- net/ieee80211/ieee80211_crypt_wep.c | 5 +- net/ieee80211/ieee80211_geo.c | 48 +- net/ieee80211/ieee80211_module.c | 20 +- net/ieee80211/ieee80211_rx.c | 241 +- net/ieee80211/ieee80211_tx.c | 30 +- net/ieee80211/ieee80211_wx.c | 156 +- net/ieee80211/softmac/Kconfig | 11 - net/ieee80211/softmac/Makefile | 9 - .../softmac/ieee80211softmac_assoc.c | 424 - net/ieee80211/softmac/ieee80211softmac_auth.c | 376 - .../softmac/ieee80211softmac_event.c | 189 - net/ieee80211/softmac/ieee80211softmac_io.c | 486 - .../softmac/ieee80211softmac_module.c | 468 - net/ieee80211/softmac/ieee80211softmac_priv.h | 230 - net/ieee80211/softmac/ieee80211softmac_scan.c | 254 - net/ieee80211/softmac/ieee80211softmac_wx.c | 433 - net/ipv4/Kconfig | 17 +- net/ipv4/Makefile | 3 +- net/ipv4/af_inet.c | 209 +- net/ipv4/ah4.c | 3 +- net/ipv4/arp.c | 24 +- net/ipv4/devinet.c | 30 +- net/ipv4/esp4.c | 6 +- net/ipv4/fib_frontend.c | 1 + net/ipv4/fib_rules.c | 142 +- net/ipv4/fib_trie.c | 24 +- net/ipv4/icmp.c | 4 +- net/ipv4/igmp.c | 26 +- net/ipv4/inet_connection_sock.c | 49 - net/ipv4/inet_hashtables.c | 6 +- net/ipv4/ip_forward.c | 1 - net/ipv4/ip_gre.c | 2 +- net/ipv4/ip_input.c | 2 +- net/ipv4/ip_options.c | 2 +- net/ipv4/ip_output.c | 24 +- net/ipv4/ip_sockglue.c | 170 +- net/ipv4/ipcomp.c | 46 +- net/ipv4/ipconfig.c | 12 +- net/ipv4/ipip.c | 83 +- net/ipv4/ipmr.c | 4 +- net/ipv4/ipvs/ip_vs_app.c | 19 +- net/ipv4/ipvs/ip_vs_ctl.c | 11 +- net/ipv4/netfilter.c | 58 +- net/ipv4/netfilter/Kconfig | 57 +- net/ipv4/netfilter/Makefile | 9 +- net/ipv4/netfilter/arp_tables.c | 39 +- net/ipv4/netfilter/arpt_mangle.c | 31 +- net/ipv4/netfilter/arptable_filter.c | 27 +- net/ipv4/netfilter/ip_conntrack_amanda.c | 8 +- net/ipv4/netfilter/ip_conntrack_core.c | 12 +- net/ipv4/netfilter/ip_conntrack_ftp.c | 10 +- net/ipv4/netfilter/ip_conntrack_helper_h323.c | 1703 -- .../netfilter/ip_conntrack_helper_h323_asn1.c | 874 - .../ip_conntrack_helper_h323_types.c | 1926 -- net/ipv4/netfilter/ip_conntrack_helper_pptp.c | 12 +- net/ipv4/netfilter/ip_conntrack_irc.c | 12 +- net/ipv4/netfilter/ip_conntrack_netbios_ns.c | 8 +- net/ipv4/netfilter/ip_conntrack_netlink.c | 79 +- net/ipv4/netfilter/ip_conntrack_proto_icmp.c | 23 +- net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 8 +- net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 7 +- net/ipv4/netfilter/ip_conntrack_proto_udp.c | 7 +- net/ipv4/netfilter/ip_conntrack_standalone.c | 272 +- net/ipv4/netfilter/ip_conntrack_tftp.c | 10 +- net/ipv4/netfilter/ip_nat_amanda.c | 8 +- net/ipv4/netfilter/ip_nat_ftp.c | 8 +- net/ipv4/netfilter/ip_nat_helper_h323.c | 534 - net/ipv4/netfilter/ip_nat_helper_pptp.c | 16 +- net/ipv4/netfilter/ip_nat_irc.c | 8 +- net/ipv4/netfilter/ip_nat_proto_gre.c | 12 +- net/ipv4/netfilter/ip_nat_proto_tcp.c | 7 +- net/ipv4/netfilter/ip_nat_proto_udp.c | 10 +- net/ipv4/netfilter/ip_nat_rule.c | 45 +- net/ipv4/netfilter/ip_nat_snmp_basic.c | 14 +- net/ipv4/netfilter/ip_nat_standalone.c | 167 +- net/ipv4/netfilter/ip_nat_tftp.c | 8 +- net/ipv4/netfilter/ip_queue.c | 46 +- net/ipv4/netfilter/ip_tables.c | 1263 +- net/ipv4/netfilter/ipt_CLUSTERIP.c | 73 +- net/ipv4/netfilter/ipt_DSCP.c | 25 +- net/ipv4/netfilter/ipt_ECN.c | 26 +- net/ipv4/netfilter/ipt_LOG.c | 21 +- net/ipv4/netfilter/ipt_MASQUERADE.c | 26 +- net/ipv4/netfilter/ipt_NETMAP.c | 27 +- net/ipv4/netfilter/ipt_REDIRECT.c | 25 +- net/ipv4/netfilter/ipt_REJECT.c | 45 +- net/ipv4/netfilter/ipt_SAME.c | 27 +- net/ipv4/netfilter/ipt_TCPMSS.c | 24 +- net/ipv4/netfilter/ipt_TOS.c | 25 +- net/ipv4/netfilter/ipt_TTL.c | 33 +- net/ipv4/netfilter/ipt_ULOG.c | 20 +- net/ipv4/netfilter/ipt_addrtype.c | 6 +- net/ipv4/netfilter/ipt_ah.c | 33 +- net/ipv4/netfilter/ipt_dscp.c | 27 +- net/ipv4/netfilter/ipt_ecn.c | 22 +- .../xt_esp.c => ipv4/netfilter/ipt_esp.c} | 90 +- net/ipv4/netfilter/ipt_hashlimit.c | 38 +- net/ipv4/netfilter/ipt_iprange.c | 36 +- net/ipv4/netfilter/ipt_multiport.c | 214 + net/ipv4/netfilter/ipt_owner.c | 29 +- net/ipv4/netfilter/ipt_recent.c | 32 +- net/ipv4/netfilter/ipt_tos.c | 26 +- net/ipv4/netfilter/ipt_ttl.c | 27 +- net/ipv4/netfilter/iptable_filter.c | 29 +- net/ipv4/netfilter/iptable_mangle.c | 41 +- net/ipv4/netfilter/iptable_raw.c | 43 +- .../netfilter/nf_conntrack_l3proto_ipv4.c | 250 +- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 20 +- net/ipv4/proc.c | 4 +- net/ipv4/raw.c | 80 +- net/ipv4/route.c | 49 +- net/ipv4/sysctl_net_ipv4.c | 25 +- net/ipv4/tcp.c | 197 +- net/ipv4/tcp_cong.c | 2 +- net/ipv4/tcp_highspeed.c | 5 +- net/ipv4/tcp_htcp.c | 66 +- net/ipv4/tcp_input.c | 71 +- net/ipv4/tcp_ipv4.c | 63 +- net/ipv4/tcp_output.c | 331 +- net/ipv4/tcp_timer.c | 36 +- net/ipv4/tunnel4.c | 121 - net/ipv4/udp.c | 104 +- net/ipv4/xfrm4_input.c | 17 +- net/ipv4/xfrm4_output.c | 62 +- net/ipv4/xfrm4_policy.c | 4 +- net/ipv4/xfrm4_tunnel.c | 82 +- net/ipv6/Kconfig | 45 +- net/ipv6/Makefile | 3 +- net/ipv6/addrconf.c | 364 +- net/ipv6/af_inet6.c | 120 +- net/ipv6/ah6.c | 7 +- net/ipv6/anycast.c | 7 +- net/ipv6/esp6.c | 7 +- net/ipv6/exthdrs.c | 4 +- net/ipv6/icmp.c | 4 +- net/ipv6/inet6_connection_sock.c | 2 - net/ipv6/inet6_hashtables.c | 80 - net/ipv6/ip6_fib.c | 1 + net/ipv6/ip6_flowlabel.c | 8 +- net/ipv6/ip6_input.c | 3 +- net/ipv6/ip6_output.c | 54 +- net/ipv6/ip6_tunnel.c | 57 +- net/ipv6/ipcomp6.c | 50 +- net/ipv6/ipv6_sockglue.c | 163 +- net/ipv6/mcast.c | 23 +- net/ipv6/ndisc.c | 49 +- net/ipv6/netfilter.c | 52 +- net/ipv6/netfilter/Kconfig | 26 +- net/ipv6/netfilter/Makefile | 4 +- net/ipv6/netfilter/ip6_queue.c | 46 +- net/ipv6/netfilter/ip6_tables.c | 148 +- net/ipv6/netfilter/ip6t_HL.c | 27 +- net/ipv6/netfilter/ip6t_LOG.c | 21 +- net/ipv6/netfilter/ip6t_REJECT.c | 33 +- net/ipv6/netfilter/ip6t_ah.c | 27 +- net/ipv6/netfilter/ip6t_dst.c | 30 +- net/ipv6/netfilter/ip6t_esp.c | 117 + net/ipv6/netfilter/ip6t_eui64.c | 37 +- net/ipv6/netfilter/ip6t_frag.c | 28 +- net/ipv6/netfilter/ip6t_hbh.c | 30 +- net/ipv6/netfilter/ip6t_hl.c | 30 +- net/ipv6/netfilter/ip6t_ipv6header.c | 8 +- net/ipv6/netfilter/ip6t_multiport.c | 126 + net/ipv6/netfilter/ip6t_owner.c | 26 +- net/ipv6/netfilter/ip6t_rt.c | 27 +- net/ipv6/netfilter/ip6table_filter.c | 29 +- net/ipv6/netfilter/ip6table_mangle.c | 41 +- net/ipv6/netfilter/ip6table_raw.c | 23 +- .../netfilter/nf_conntrack_l3proto_ipv6.c | 223 +- .../netfilter/nf_conntrack_proto_icmpv6.c | 12 +- net/ipv6/netfilter/nf_conntrack_reasm.c | 8 +- net/ipv6/proc.c | 4 +- net/ipv6/raw.c | 145 +- net/ipv6/reassembly.c | 53 +- net/ipv6/route.c | 689 +- net/ipv6/sit.c | 2 +- net/ipv6/tcp_ipv6.c | 74 +- net/ipv6/tunnel6.c | 139 - net/ipv6/udp.c | 91 +- net/ipv6/xfrm6_input.c | 16 +- net/ipv6/xfrm6_output.c | 39 +- net/ipv6/xfrm6_tunnel.c | 84 +- net/ipx/af_ipx.c | 68 +- net/ipx/ipx_route.c | 6 +- net/irda/af_irda.c | 31 +- net/irda/iriap.c | 3 +- net/irda/irias_object.c | 3 + net/irda/irlap.c | 3 +- net/key/af_key.c | 6 +- net/llc/af_llc.c | 15 +- net/llc/llc_c_ac.c | 1 + net/llc/llc_core.c | 1 + net/llc/llc_input.c | 3 +- net/llc/llc_output.c | 3 +- net/llc/llc_output.h | 20 + net/llc/llc_s_ac.c | 2 +- net/netfilter/Kconfig | 35 +- net/netfilter/Makefile | 3 - net/netfilter/core.c | 51 - net/netfilter/nf_conntrack_core.c | 193 +- net/netfilter/nf_conntrack_ftp.c | 12 +- net/netfilter/nf_conntrack_l3proto_generic.c | 1 + net/netfilter/nf_conntrack_netlink.c | 134 +- net/netfilter/nf_conntrack_proto_sctp.c | 8 +- net/netfilter/nf_conntrack_proto_tcp.c | 50 +- net/netfilter/nf_conntrack_proto_udp.c | 50 +- net/netfilter/nf_conntrack_standalone.c | 126 +- net/netfilter/nf_queue.c | 49 +- net/netfilter/nf_sockopt.c | 94 +- net/netfilter/nfnetlink.c | 6 - net/netfilter/nfnetlink_log.c | 77 +- net/netfilter/nfnetlink_queue.c | 52 +- net/netfilter/x_tables.c | 263 +- net/netfilter/xt_CLASSIFY.c | 62 +- net/netfilter/xt_CONNMARK.c | 47 +- net/netfilter/xt_MARK.c | 66 +- net/netfilter/xt_NFQUEUE.c | 51 +- net/netfilter/xt_NOTRACK.c | 65 +- net/netfilter/xt_comment.c | 38 +- net/netfilter/xt_connbytes.c | 35 +- net/netfilter/xt_connmark.c | 65 +- net/netfilter/xt_conntrack.c | 49 +- net/netfilter/xt_dccp.c | 65 +- net/netfilter/xt_helper.c | 63 +- net/netfilter/xt_length.c | 44 +- net/netfilter/xt_limit.c | 27 +- net/netfilter/xt_mac.c | 54 +- net/netfilter/xt_mark.c | 36 +- net/netfilter/xt_multiport.c | 314 - net/netfilter/xt_physdev.c | 34 +- net/netfilter/xt_pkttype.c | 43 +- net/netfilter/xt_policy.c | 211 - net/netfilter/xt_realm.c | 40 +- net/netfilter/xt_sctp.c | 86 +- net/netfilter/xt_state.c | 52 +- net/netfilter/xt_string.c | 30 +- net/netfilter/xt_tcpmss.c | 72 +- net/netfilter/xt_tcpudp.c | 146 +- net/netlink/af_netlink.c | 65 +- net/netlink/genetlink.c | 9 +- net/netrom/af_netrom.c | 18 +- net/netrom/nr_dev.c | 1 + net/nonet.c | 2 +- net/rose/af_rose.c | 13 +- net/rose/rose_dev.c | 1 + net/rose/rose_link.c | 6 +- net/rose/rose_route.c | 7 + net/rxrpc/main.c | 2 +- net/sched/Kconfig | 1 + net/sched/act_api.c | 4 +- net/sched/act_gact.c | 4 +- net/sched/act_ipt.c | 15 +- net/sched/act_police.c | 34 +- net/sched/cls_api.c | 4 +- net/sched/cls_basic.c | 2 +- net/sched/cls_u32.c | 6 +- net/sched/sch_api.c | 16 +- net/sched/sch_atm.c | 1 - net/sched/sch_dsmark.c | 1 - net/sched/sch_generic.c | 140 +- net/sched/sch_hfsc.c | 6 +- net/sched/sch_netem.c | 6 +- net/sched/sch_prio.c | 2 +- net/sched/sch_red.c | 179 +- net/sched/sch_sfq.c | 5 - net/sched/sch_tbf.c | 9 +- net/sched/sch_teql.c | 9 +- net/sctp/input.c | 159 +- net/sctp/ipv6.c | 92 +- net/sctp/proc.c | 2 +- net/sctp/protocol.c | 94 +- net/sctp/sm_sideeffect.c | 16 +- net/sctp/sm_statefuns.c | 75 +- net/sctp/socket.c | 35 +- net/socket.c | 433 +- net/sunrpc/auth.c | 16 +- net/sunrpc/auth_gss/auth_gss.c | 3 +- net/sunrpc/auth_gss/gss_krb5_crypto.c | 11 +- net/sunrpc/auth_gss/gss_krb5_seal.c | 15 +- net/sunrpc/auth_gss/gss_krb5_unseal.c | 4 +- net/sunrpc/auth_gss/gss_krb5_wrap.c | 17 +- net/sunrpc/auth_gss/gss_spkm3_mech.c | 6 - net/sunrpc/auth_gss/gss_spkm3_seal.c | 5 +- net/sunrpc/auth_gss/gss_spkm3_unseal.c | 4 +- net/sunrpc/auth_gss/svcauth_gss.c | 196 +- net/sunrpc/cache.c | 185 +- net/sunrpc/clnt.c | 53 +- net/sunrpc/pmap_clnt.c | 41 +- net/sunrpc/rpc_pipe.c | 40 +- net/sunrpc/sched.c | 45 +- net/sunrpc/stats.c | 120 +- net/sunrpc/sunrpc_syms.c | 6 +- net/sunrpc/svcauth.c | 122 +- net/sunrpc/svcauth_unix.c | 229 +- net/sunrpc/svcsock.c | 10 +- net/sunrpc/xprt.c | 29 +- net/sunrpc/xprtsock.c | 49 - net/sysctl_net.c | 8 + net/tipc/bcast.c | 58 +- net/tipc/bearer.c | 20 +- net/tipc/cluster.c | 22 +- net/tipc/cluster.h | 2 +- net/tipc/config.c | 4 +- net/tipc/dbg.c | 4 +- net/tipc/discover.c | 8 +- net/tipc/eth_media.c | 4 +- net/tipc/link.c | 91 +- net/tipc/name_distr.c | 9 +- net/tipc/name_table.c | 62 +- net/tipc/net.c | 7 +- net/tipc/node.c | 20 +- net/tipc/node.h | 2 +- net/tipc/node_subscr.c | 2 +- net/tipc/port.c | 57 +- net/tipc/ref.c | 8 +- net/tipc/ref.h | 4 +- net/tipc/socket.c | 28 +- net/tipc/subscr.c | 30 +- net/tipc/user_reg.c | 4 +- net/tipc/zone.c | 12 +- net/tux/Kconfig | 25 - net/tux/Makefile | 12 - net/tux/abuf.c | 190 - net/tux/accept.c | 863 - net/tux/cachemiss.c | 265 - net/tux/cgi.c | 171 - net/tux/directory.c | 302 - net/tux/extcgi.c | 329 - net/tux/gzip.c | 40 - net/tux/input.c | 641 - net/tux/logger.c | 837 - net/tux/main.c | 1417 -- net/tux/mod.c | 262 - net/tux/output.c | 352 - net/tux/parser.h | 102 - net/tux/postpone.c | 77 - net/tux/proc.c | 1149 - net/tux/proto_ftp.c | 1555 -- net/tux/proto_http.c | 2197 -- net/tux/redirect.c | 172 - net/tux/times.c | 392 - net/tux/times.h | 26 - net/tux/userspace.c | 27 - net/unix/af_unix.c | 34 +- net/unix/garbage.c | 7 +- net/wanrouter/af_wanpipe.c | 2 + net/x25/af_x25.c | 173 +- net/x25/x25_facilities.c | 82 +- net/x25/x25_in.c | 3 +- net/x25/x25_subr.c | 6 +- net/x25/x25_timer.c | 4 +- net/xfrm/xfrm_input.c | 6 +- net/xfrm/xfrm_policy.c | 35 +- net/xfrm/xfrm_state.c | 129 +- net/xfrm/xfrm_user.c | 397 +- scripts/Kbuild.include | 70 +- scripts/Makefile.build | 27 +- scripts/Makefile.clean | 10 +- scripts/Makefile.lib | 5 + scripts/Makefile.modinst | 10 +- scripts/Makefile.modpost | 21 +- scripts/Makefile.xen | 14 - scripts/basic/fixdep.c | 14 +- scripts/checkconfig.pl | 65 + scripts/extract-ikconfig | 5 +- scripts/gen_initramfs_list.sh | 229 +- scripts/genksyms/genksyms.c | 843 +- scripts/genksyms/genksyms.h | 57 +- scripts/genksyms/keywords.c_shipped | 91 +- scripts/genksyms/keywords.gperf | 1 - scripts/kallsyms.c | 12 +- scripts/kconfig/Makefile | 9 +- scripts/kconfig/conf.c | 50 +- scripts/kconfig/confdata.c | 8 +- scripts/kconfig/lxdialog/Makefile | 6 +- scripts/kconfig/lxdialog/checklist.c | 19 +- scripts/kconfig/lxdialog/menubox.c | 19 +- scripts/mod/file2alias.c | 53 +- scripts/mod/mk_elfconfig.c | 4 +- scripts/mod/modpost.c | 753 +- scripts/mod/modpost.h | 48 +- scripts/mod/sumversion.c | 8 +- scripts/modsign/Makefile | 27 - scripts/modsign/mod-extract.c | 109 - scripts/modsign/modsign.sh | 35 - scripts/namespace.pl | 4 +- scripts/package/Makefile | 24 +- scripts/profile2linkerlist.pl | 21 - scripts/reference_discarded.pl | 112 + scripts/reference_init.pl | 108 + scripts/ver_linux | 4 +- security/commoncap.c | 4 +- security/dummy.c | 21 +- security/keys/key.c | 18 +- security/keys/keyctl.c | 155 +- security/keys/process_keys.c | 48 +- security/seclvl.c | 212 +- security/security.c | 26 + security/selinux/Makefile | 2 +- security/selinux/avc.c | 13 +- security/selinux/exports.c | 74 - security/selinux/hooks.c | 165 +- security/selinux/include/security.h | 5 + security/selinux/include/xfrm.h | 12 - security/selinux/nlmsgtab.c | 19 +- security/selinux/selinuxfs.c | 123 +- security/selinux/ss/mls.c | 30 +- security/selinux/ss/mls.h | 4 +- security/selinux/ss/services.c | 259 +- security/selinux/xfrm.c | 70 +- sound/arm/aaci.c | 10 +- sound/arm/aaci.h | 2 +- sound/arm/pxa2xx-ac97.c | 12 +- sound/core/Kconfig | 33 +- sound/core/control.c | 40 +- sound/core/control_compat.c | 95 +- sound/core/hwdep.c | 43 +- sound/core/info.c | 27 +- sound/core/info_oss.c | 13 +- sound/core/init.c | 56 +- sound/core/memalloc.c | 56 +- sound/core/oss/copy.c | 5 - sound/core/oss/io.c | 5 - sound/core/oss/linear.c | 7 +- sound/core/oss/mixer_oss.c | 14 +- sound/core/oss/mulaw.c | 24 - sound/core/oss/pcm_oss.c | 346 +- sound/core/oss/pcm_plugin.c | 272 +- sound/core/oss/pcm_plugin.h | 28 +- sound/core/oss/plugin_ops.h | 166 + sound/core/oss/rate.c | 85 +- sound/core/oss/route.c | 489 +- sound/core/pcm.c | 71 +- sound/core/pcm_lib.c | 55 +- sound/core/pcm_memory.c | 8 +- sound/core/pcm_native.c | 187 +- sound/core/rawmidi.c | 63 +- sound/core/rtctimer.c | 17 +- sound/core/seq/oss/seq_oss.c | 27 +- sound/core/seq/seq_clientmgr.c | 43 +- sound/core/seq/seq_clientmgr.h | 2 +- sound/core/seq/seq_device.c | 53 +- sound/core/seq/seq_instr.c | 6 +- sound/core/seq/seq_midi.c | 20 +- sound/core/seq/seq_ports.c | 18 +- sound/core/seq/seq_queue.c | 6 +- sound/core/seq/seq_queue.h | 2 +- sound/core/seq/seq_virmidi.c | 4 +- sound/core/sound.c | 27 +- sound/core/sound_oss.c | 25 +- sound/core/timer.c | 77 +- sound/drivers/dummy.c | 18 +- sound/drivers/mpu401/mpu401.c | 36 +- sound/drivers/mpu401/mpu401_uart.c | 42 +- sound/drivers/opl3/opl3_lib.c | 2 +- sound/drivers/opl3/opl3_seq.c | 10 +- sound/drivers/opl3/opl3_synth.c | 10 +- sound/drivers/opl4/opl4_lib.c | 2 +- sound/drivers/opl4/opl4_local.h | 2 +- sound/drivers/opl4/opl4_proc.c | 10 +- sound/drivers/opl4/opl4_seq.c | 12 +- sound/drivers/serial-u16550.c | 19 +- sound/drivers/virmidi.c | 18 +- sound/drivers/vx/vx_core.c | 2 +- sound/drivers/vx/vx_mixer.c | 72 +- sound/drivers/vx/vx_pcm.c | 13 +- sound/i2c/cs8427.c | 7 +- sound/i2c/i2c.c | 2 +- sound/isa/Kconfig | 23 - sound/isa/Makefile | 2 - sound/isa/ad1816a/ad1816a.c | 12 +- sound/isa/ad1816a/ad1816a_lib.c | 15 +- sound/isa/ad1848/ad1848.c | 20 +- sound/isa/ad1848/ad1848_lib.c | 14 +- sound/isa/adlib.c | 164 - sound/isa/als100.c | 14 +- sound/isa/azt2320.c | 12 +- sound/isa/cmi8330.c | 35 +- sound/isa/cs423x/Makefile | 1 - sound/isa/cs423x/cs4231.c | 20 +- sound/isa/cs423x/cs4231_lib.c | 30 +- sound/isa/cs423x/cs4236.c | 45 +- sound/isa/cs423x/cs4236_lib.c | 6 +- sound/isa/dt019x.c | 12 +- sound/isa/es1688/es1688.c | 20 +- sound/isa/es18xx.c | 253 +- sound/isa/gus/gus_dma.c | 10 +- sound/isa/gus/gus_main.c | 2 +- sound/isa/gus/gus_mem.c | 14 +- sound/isa/gus/gus_pcm.c | 2 + sound/isa/gus/gus_synth.c | 14 +- sound/isa/gus/gusclassic.c | 20 +- sound/isa/gus/gusextreme.c | 20 +- sound/isa/gus/gusmax.c | 20 +- sound/isa/gus/interwave.c | 32 +- sound/isa/opl3sa2.c | 37 +- sound/isa/opti9xx/Makefile | 2 - sound/isa/opti9xx/miro.c | 1455 -- sound/isa/opti9xx/miro.h | 73 - sound/isa/opti9xx/opti92x-ad1848.c | 7 +- sound/isa/sb/es968.c | 12 +- sound/isa/sb/sb16.c | 34 +- sound/isa/sb/sb16_csp.c | 12 +- sound/isa/sb/sb8.c | 20 +- sound/isa/sgalaxy.c | 20 +- sound/isa/sscape.c | 20 +- sound/isa/wavefront/wavefront.c | 30 +- sound/mips/au1x00.c | 42 +- sound/oss/.gitignore | 4 - sound/oss/Kconfig | 301 +- sound/oss/ac97_codec.c | 24 +- sound/oss/aci.c | 11 +- sound/oss/ad1848.c | 10 +- sound/oss/ad1889.c | 205 +- sound/oss/ad1889.h | 103 +- sound/oss/ali5455.c | 8 +- sound/oss/au1000.c | 46 +- sound/oss/au1550_ac97.c | 46 +- sound/oss/awe_wave.c | 6 +- sound/oss/btaudio.c | 36 +- sound/oss/cmpci.c | 22 +- sound/oss/cs4232.c | 15 +- sound/oss/cs4281/cs4281m.c | 54 +- sound/oss/cs46xx.c | 75 +- sound/oss/dmasound/dmasound_awacs.c | 16 +- sound/oss/dmasound/dmasound_core.c | 10 +- sound/oss/emu10k1/hwaccess.h | 2 +- sound/oss/emu10k1/main.c | 5 +- sound/oss/emu10k1/midi.c | 23 +- sound/oss/es1370.c | 71 +- sound/oss/es1371.c | 71 +- sound/oss/esssolo1.c | 52 +- sound/oss/forte.c | 11 +- sound/oss/hal2.c | 22 +- sound/oss/i810_audio.c | 8 +- sound/oss/ite8172.c | 24 +- sound/oss/maestro.c | 26 +- sound/oss/maestro3.c | 30 +- sound/oss/msnd.c | 6 +- sound/oss/nec_vrc5477.c | 20 +- sound/oss/nm256_audio.c | 6 +- sound/oss/rme96xx.c | 17 +- sound/oss/sb_card.c | 35 +- sound/oss/sb_mixer.c | 6 +- sound/oss/sequencer.c | 17 +- sound/oss/sh_dac_audio.c | 2 +- sound/oss/sonicvibes.c | 69 +- sound/oss/swarm_cs4297a.c | 45 +- sound/oss/trident.c | 62 +- sound/oss/via82cxxx_audio.c | 49 +- sound/oss/vwsnd.c | 101 +- sound/oss/waveartist.c | 8 +- sound/oss/ymfpci.c | 14 +- sound/oss/ymfpci.h | 3 +- sound/pci/Kconfig | 175 +- sound/pci/Makefile | 4 +- sound/pci/ac97/ac97_codec.c | 111 +- sound/pci/ac97/ac97_patch.c | 40 +- sound/pci/ac97/ac97_patch.h | 1 - sound/pci/ac97/ac97_pcm.c | 6 +- sound/pci/ac97/ac97_proc.c | 14 +- sound/pci/ac97/ak4531_codec.c | 28 +- sound/pci/ad1889.c | 9 +- sound/pci/ali5451/ali5451.c | 7 +- sound/pci/als300.c | 867 - sound/pci/als4000.c | 7 +- sound/pci/atiixp.c | 23 +- sound/pci/atiixp_modem.c | 15 +- sound/pci/au88x0/au8810.c | 2 +- sound/pci/au88x0/au8820.c | 2 +- sound/pci/au88x0/au8830.c | 2 +- sound/pci/au88x0/au88x0.c | 10 +- sound/pci/au88x0/au88x0.h | 25 +- sound/pci/au88x0/au88x0_core.c | 14 +- sound/pci/au88x0/au88x0_eq.c | 33 +- sound/pci/au88x0/au88x0_eq.h | 31 +- sound/pci/au88x0/au88x0_eqdata.c | 6 +- sound/pci/au88x0/au88x0_mpu401.c | 4 +- sound/pci/au88x0/au88x0_pcm.c | 2 +- sound/pci/au88x0/au88x0_synth.c | 10 +- sound/pci/au88x0/au88x0_wt.h | 10 +- sound/pci/au88x0/au88x0_xtalk.c | 16 +- sound/pci/au88x0/au88x0_xtalk.h | 12 +- sound/pci/azt3328.c | 7 +- sound/pci/bt87x.c | 17 +- sound/pci/ca0106/ca0106_main.c | 2 +- sound/pci/cmipci.c | 27 +- sound/pci/cs4281.c | 30 +- sound/pci/cs46xx/cs46xx.c | 2 +- sound/pci/cs46xx/cs46xx_lib.c | 52 +- sound/pci/cs46xx/dsp_spos.c | 58 +- sound/pci/cs46xx/dsp_spos_scb_lib.c | 6 +- sound/pci/cs5535audio/cs5535audio.c | 8 +- sound/pci/echoaudio/Makefile | 30 + sound/pci/echoaudio/darla20.c | 99 + sound/pci/echoaudio/darla20_dsp.c | 125 + sound/pci/echoaudio/darla24.c | 106 + sound/pci/echoaudio/darla24_dsp.c | 156 + sound/pci/echoaudio/echo3g.c | 118 + sound/pci/echoaudio/echo3g_dsp.c | 131 + sound/pci/echoaudio/echoaudio.c | 2196 ++ sound/pci/echoaudio/echoaudio.h | 590 + sound/pci/echoaudio/echoaudio_3g.c | 431 + sound/pci/echoaudio/echoaudio_dsp.c | 1125 + sound/pci/echoaudio/echoaudio_dsp.h | 694 + sound/pci/echoaudio/echoaudio_gml.c | 198 + sound/pci/echoaudio/gina20.c | 103 + sound/pci/echoaudio/gina20_dsp.c | 215 + sound/pci/echoaudio/gina24.c | 123 + sound/pci/echoaudio/gina24_dsp.c | 346 + sound/pci/echoaudio/indigo.c | 104 + sound/pci/echoaudio/indigo_dsp.c | 170 + sound/pci/echoaudio/indigodj.c | 104 + sound/pci/echoaudio/indigodj_dsp.c | 170 + sound/pci/echoaudio/indigoio.c | 105 + sound/pci/echoaudio/indigoio_dsp.c | 141 + sound/pci/echoaudio/layla20.c | 112 + sound/pci/echoaudio/layla20_dsp.c | 290 + sound/pci/echoaudio/layla24.c | 121 + sound/pci/echoaudio/layla24_dsp.c | 394 + sound/pci/echoaudio/mia.c | 117 + sound/pci/echoaudio/mia_dsp.c | 229 + sound/pci/echoaudio/midi.c | 327 + sound/pci/echoaudio/mona.c | 129 + sound/pci/echoaudio/mona_dsp.c | 428 + sound/pci/emu10k1/emu10k1.c | 2 +- sound/pci/emu10k1/emu10k1_main.c | 22 +- sound/pci/emu10k1/emu10k1_synth.c | 1 + sound/pci/emu10k1/emu10k1x.c | 15 +- sound/pci/emu10k1/emufx.c | 22 +- sound/pci/emu10k1/memory.c | 26 +- sound/pci/ens1370.c | 41 +- sound/pci/es1938.c | 7 +- sound/pci/es1968.c | 29 +- sound/pci/fm801.c | 2 +- sound/pci/hda/hda_codec.c | 142 +- sound/pci/hda/hda_codec.h | 69 +- sound/pci/hda/hda_generic.c | 64 +- sound/pci/hda/hda_intel.c | 126 +- sound/pci/hda/hda_local.h | 132 +- sound/pci/hda/patch_analog.c | 613 +- sound/pci/hda/patch_realtek.c | 1321 +- sound/pci/hda/patch_sigmatel.c | 283 +- sound/pci/ice1712/aureon.c | 293 +- sound/pci/ice1712/aureon.h | 8 +- sound/pci/ice1712/delta.c | 62 +- sound/pci/ice1712/hoontech.c | 26 +- sound/pci/ice1712/ice1712.c | 71 +- sound/pci/ice1712/ice1712.h | 12 +- sound/pci/ice1712/ice1724.c | 39 +- sound/pci/ice1712/phase.c | 738 +- sound/pci/ice1712/pontis.c | 86 +- sound/pci/intel8x0.c | 157 +- sound/pci/intel8x0m.c | 2 +- sound/pci/korg1212/korg1212.c | 19 +- sound/pci/maestro3.c | 64 +- sound/pci/mixart/mixart.c | 27 +- sound/pci/mixart/mixart.h | 7 +- sound/pci/mixart/mixart_core.c | 18 +- sound/pci/mixart/mixart_mixer.c | 52 +- sound/pci/nm256/nm256.c | 138 +- sound/pci/pcxhr/pcxhr.c | 41 +- sound/pci/pcxhr/pcxhr.h | 5 +- sound/pci/pcxhr/pcxhr_core.c | 11 +- sound/pci/pcxhr/pcxhr_hwdep.c | 4 +- sound/pci/pcxhr/pcxhr_mixer.c | 75 +- sound/pci/riptide/Makefile | 3 - sound/pci/riptide/riptide.c | 2223 -- sound/pci/rme32.c | 10 +- sound/pci/rme96.c | 10 +- sound/pci/rme9652/hdsp.c | 4 +- sound/pci/rme9652/hdspm.c | 4 +- sound/pci/rme9652/rme9652.c | 2 +- sound/pci/sonicvibes.c | 7 +- sound/pci/trident/trident.c | 2 +- sound/pci/trident/trident_main.c | 5 +- sound/pci/trident/trident_memory.c | 36 +- sound/pci/via82xx.c | 22 +- sound/pci/via82xx_modem.c | 2 +- sound/pci/vx222/vx222.c | 2 +- sound/pci/vx222/vx222_ops.c | 18 +- sound/pci/ymfpci/ymfpci.c | 7 +- sound/pci/ymfpci/ymfpci_main.c | 38 +- sound/pcmcia/Kconfig | 4 +- sound/pcmcia/pdaudiocf/pdaudiocf.c | 86 +- sound/pcmcia/pdaudiocf/pdaudiocf.h | 2 +- sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c | 7 +- sound/pcmcia/vx/vxp_mixer.c | 12 +- sound/pcmcia/vx/vxpocket.c | 94 +- sound/pcmcia/vx/vxpocket.h | 2 +- sound/ppc/daca.c | 1 + sound/ppc/keywest.c | 1 + sound/ppc/pmac.c | 2 +- sound/ppc/toonie.c | 7 +- sound/ppc/tumbler.c | 1 + sound/sound_core.c | 22 +- sound/sparc/cs4231.c | 66 +- sound/synth/emux/emux.c | 2 +- sound/synth/emux/emux_oss.c | 12 +- sound/synth/emux/emux_proc.c | 8 +- sound/synth/emux/emux_seq.c | 12 +- sound/synth/emux/soundfont.c | 6 +- sound/synth/util_mem.c | 15 +- sound/usb/usbaudio.c | 168 +- sound/usb/usbaudio.h | 4 +- sound/usb/usbmidi.c | 10 +- sound/usb/usbmixer.c | 38 +- sound/usb/usbmixer_maps.c | 20 - sound/usb/usbquirks.h | 112 +- sound/usb/usx2y/usbusx2y.c | 2 +- sound/usb/usx2y/usbusx2y.h | 2 +- sound/usb/usx2y/usbusx2yaudio.c | 8 +- sound/usb/usx2y/usx2yhwdeppcm.c | 14 +- usr/Makefile | 90 +- usr/gen_init_cpio.c | 4 +- 6638 files changed, 253024 insertions(+), 483433 deletions(-) delete mode 100644 Documentation/COPYING.modules create mode 100644 Documentation/DocBook/sis900.tmpl delete mode 100644 Documentation/block/switching-sched.txt delete mode 100644 Documentation/feature-removal-schedule.txt delete mode 100644 Documentation/filesystems/9p.txt delete mode 100644 Documentation/isdn/README.gigaset delete mode 100644 Documentation/leds-class.txt delete mode 100644 Documentation/memory-barriers.txt create mode 100644 Documentation/networking/TODO delete mode 100644 Documentation/networking/bcm43xx.txt delete mode 100644 Documentation/networking/operstates.txt create mode 100644 Documentation/networking/sis900.txt delete mode 100644 Documentation/networking/xfrm_sync.txt delete mode 100644 Documentation/power/userland-swsusp.txt delete mode 100644 Documentation/robust-futex-ABI.txt delete mode 100644 Documentation/robust-futexes.txt create mode 100644 Documentation/scsi/hptiop.txt delete mode 100644 Documentation/sound/alsa/Audiophile-Usb.txt delete mode 100644 Documentation/spi/pxa2xx rename Documentation/{video4linux => usb}/ibmcam.txt (99%) rename Documentation/{video4linux => usb}/ov511.txt (99%) rename Documentation/{video4linux => usb}/se401.txt (100%) rename Documentation/{video4linux => usb}/sn9c102.txt (96%) rename Documentation/{video4linux => usb}/stv680.txt (82%) rename Documentation/{video4linux => usb}/w9968cf.txt (97%) delete mode 100644 Documentation/video4linux/README.cpia2 delete mode 100644 Documentation/video4linux/cpia2_overview.txt delete mode 100644 Documentation/video4linux/et61x251.txt delete mode 100644 Documentation/video4linux/zc0301.txt delete mode 100644 Documentation/w1/masters/ds2482 delete mode 100644 arch/arm/Kconfig-nommu create mode 100644 arch/arm/boot/compressed/ice-dcc.S delete mode 100644 arch/arm/common/uengine.c rename arch/arm/configs/{ixp23xx_defconfig => enp2611_defconfig} (65%) rename arch/arm/configs/{ixp2000_defconfig => ixdp2400_defconfig} (92%) rename arch/arm/configs/{ep93xx_defconfig => ixdp2401_defconfig} (59%) create mode 100644 arch/arm/configs/ixdp2800_defconfig create mode 100644 arch/arm/configs/ixdp2801_defconfig delete mode 100644 arch/arm/kernel/head-common.S delete mode 100644 arch/arm/kernel/head-nommu.S delete mode 100644 arch/arm/mach-at91rm9200/leds.c delete mode 100644 arch/arm/mach-ep93xx/Kconfig delete mode 100644 arch/arm/mach-ep93xx/Makefile delete mode 100644 arch/arm/mach-ep93xx/Makefile.boot delete mode 100644 arch/arm/mach-ep93xx/core.c delete mode 100644 arch/arm/mach-ep93xx/gesbc9312.c delete mode 100644 arch/arm/mach-ep93xx/ts72xx.c delete mode 100644 arch/arm/mach-ixp23xx/Kconfig delete mode 100644 arch/arm/mach-ixp23xx/Makefile delete mode 100644 arch/arm/mach-ixp23xx/Makefile.boot delete mode 100644 arch/arm/mach-ixp23xx/core.c delete mode 100644 arch/arm/mach-ixp23xx/espresso.c delete mode 100644 arch/arm/mach-ixp23xx/ixdp2351.c delete mode 100644 arch/arm/mach-ixp23xx/pci.c delete mode 100644 arch/arm/mach-ixp23xx/roadrunner.c delete mode 100644 arch/arm/mach-omap1/board-ams-delta.c delete mode 100644 arch/arm/mach-omap1/board-nokia770.c delete mode 100644 arch/arm/mach-omap1/pm.c delete mode 100644 arch/arm/mach-omap1/sleep.S delete mode 100644 arch/arm/mach-omap2/board-apollon.c delete mode 100644 arch/arm/mach-omap2/memory.c delete mode 100644 arch/arm/mach-omap2/memory.h delete mode 100644 arch/arm/mach-omap2/pm.c delete mode 100644 arch/arm/mach-omap2/prcm-regs.h delete mode 100644 arch/arm/mach-omap2/prcm.c delete mode 100644 arch/arm/mach-omap2/sleep.S delete mode 100644 arch/arm/mach-pxa/clock.c delete mode 100644 arch/arm/mach-pxa/lpd270.c delete mode 100644 arch/arm/mach-s3c2410/common-smdk.c delete mode 100644 arch/arm/mach-s3c2410/common-smdk.h delete mode 100644 arch/arm/mach-s3c2410/mach-osiris.c delete mode 100644 arch/arm/mach-sa1100/clock.c delete mode 100644 arch/arm/mach-sa1100/collie_pm.c delete mode 100644 arch/arm/mm/copypage-xsc3.S delete mode 100644 arch/arm/mm/proc-xsc3.S delete mode 100644 arch/arm/plat-omap/fb.c delete mode 100644 arch/arm/plat-omap/timer32k.c delete mode 100644 arch/i386/boot-xen/Makefile delete mode 100644 arch/i386/kernel/acpi/boot-xen.c delete mode 100644 arch/i386/kernel/alternative.c delete mode 100644 arch/i386/kernel/apic-xen.c delete mode 100644 arch/i386/kernel/cpu/common-xen.c delete mode 100644 arch/i386/kernel/cpu/mtrr/main-xen.c rename {drivers/firmware => arch/i386/kernel}/dmi_scan.c (73%) delete mode 100644 arch/i386/kernel/early_printk-xen.c delete mode 100644 arch/i386/kernel/entry-xen.S delete mode 100644 arch/i386/kernel/fixup.c delete mode 100644 arch/i386/kernel/head-xen.S delete mode 100644 arch/i386/kernel/init_task-xen.c delete mode 100644 arch/i386/kernel/io_apic-xen.c delete mode 100644 arch/i386/kernel/ioport-xen.c delete mode 100644 arch/i386/kernel/irq-xen.c delete mode 100644 arch/i386/kernel/ldt-xen.c delete mode 100644 arch/i386/kernel/microcode-xen.c delete mode 100644 arch/i386/kernel/mpparse-xen.c delete mode 100644 arch/i386/kernel/pci-dma-xen.c delete mode 100644 arch/i386/kernel/process-xen.c delete mode 100644 arch/i386/kernel/quirks-xen.c delete mode 100644 arch/i386/kernel/setup-xen.c delete mode 100644 arch/i386/kernel/smp-xen.c delete mode 100644 arch/i386/kernel/swiotlb.c delete mode 100644 arch/i386/kernel/time-xen.c delete mode 100644 arch/i386/kernel/traps-xen.c delete mode 100644 arch/i386/kernel/vsyscall-note-xen.S delete mode 100644 arch/i386/mach-xen/Makefile delete mode 100644 arch/i386/mach-xen/setup.c delete mode 100644 arch/i386/mm/fault-xen.c delete mode 100644 arch/i386/mm/highmem-xen.c delete mode 100644 arch/i386/mm/hypervisor.c delete mode 100644 arch/i386/mm/init-xen.c delete mode 100644 arch/i386/mm/ioremap-xen.c delete mode 100644 arch/i386/mm/pgtable-xen.c delete mode 100644 arch/i386/oprofile/xenoprof.c delete mode 100644 arch/i386/pci/init.c delete mode 100644 arch/i386/pci/irq-xen.c delete mode 100644 arch/i386/pci/pcifront.c create mode 100644 arch/ia64/lib/bitop.c delete mode 100644 arch/ia64/mm/ioremap.c delete mode 100644 arch/ia64/sn/kernel/pio_phys.S create mode 100644 arch/mips/au1000/common/int-handler.S delete mode 100644 arch/mips/cobalt/Kconfig delete mode 100644 arch/mips/cobalt/console.c create mode 100644 arch/mips/cobalt/int-handler.S create mode 100644 arch/mips/ddb5xxx/ddb5074/int-handler.S create mode 100644 arch/mips/ddb5xxx/ddb5476/int-handler.S create mode 100644 arch/mips/ddb5xxx/ddb5477/int-handler.S create mode 100644 arch/mips/galileo-boards/ev96100/int-handler.S create mode 100644 arch/mips/gt64120/ev64120/int-handler.S create mode 100644 arch/mips/gt64120/momenco_ocelot/int-handler.S create mode 100644 arch/mips/ite-boards/generic/int-handler.S create mode 100644 arch/mips/jazz/int-handler.S create mode 100644 arch/mips/jmr3927/rbhma3100/int-handler.S delete mode 100644 arch/mips/kernel/i8253.c delete mode 100644 arch/mips/kernel/kspd.c delete mode 100644 arch/mips/kernel/mips-mt.c delete mode 100644 arch/mips/kernel/smp-mt.c delete mode 100644 arch/mips/kernel/smtc-asm.S delete mode 100644 arch/mips/kernel/smtc-proc.c delete mode 100644 arch/mips/kernel/smtc.c create mode 100644 arch/mips/lasat/lasatIRQ.S create mode 100644 arch/mips/mips-boards/generic/mipsIRQ.S delete mode 100644 arch/mips/mips-boards/malta/malta_smp.c create mode 100644 arch/mips/mm/tlb-andes.c create mode 100644 arch/mips/momentum/jaguar_atx/int-handler.S create mode 100644 arch/mips/momentum/ocelot_3/int-handler.S create mode 100644 arch/mips/momentum/ocelot_c/int-handler.S create mode 100644 arch/mips/momentum/ocelot_g/int-handler.S create mode 100644 arch/mips/pmc-sierra/yosemite/irq-handler.S delete mode 100644 arch/mips/qemu/q-smp.c create mode 100644 arch/mips/sgi-ip22/ip22-irq.S create mode 100644 arch/mips/sgi-ip27/ip27-irq-glue.S create mode 100644 arch/mips/sgi-ip32/ip32-irq-glue.S create mode 100644 arch/mips/sibyte/sb1250/irq_handler.S create mode 100644 arch/mips/sni/int-handler.S create mode 100644 arch/mips/tx4927/common/tx4927_irq_handler.S create mode 100644 arch/mips/vr41xx/common/int-handler.S delete mode 100644 arch/powerpc/configs/mpc8540_ads_defconfig delete mode 100644 arch/powerpc/kernel/head_booke.h delete mode 100644 arch/powerpc/kernel/idle.c delete mode 100644 arch/powerpc/oprofile/backtrace.c delete mode 100644 arch/powerpc/platforms/83xx/misc.c delete mode 100644 arch/powerpc/platforms/85xx/misc.c delete mode 100644 arch/powerpc/platforms/85xx/mpc8540_ads.h delete mode 100644 arch/powerpc/platforms/85xx/mpc85xx.h delete mode 100644 arch/powerpc/platforms/85xx/mpc85xx_ads.c delete mode 100644 arch/powerpc/platforms/85xx/pci.c delete mode 100644 arch/powerpc/platforms/cell/spu_callbacks.c delete mode 100644 arch/powerpc/platforms/pseries/firmware.c delete mode 100644 arch/powerpc/platforms/pseries/firmware.h create mode 100644 arch/ppc/boot/openfirmware/Makefile create mode 100644 arch/ppc/boot/openfirmware/chrpmain.c create mode 100644 arch/ppc/boot/openfirmware/common.c create mode 100644 arch/ppc/boot/openfirmware/dummy.c create mode 100644 arch/ppc/boot/openfirmware/misc.S create mode 100644 arch/ppc/boot/openfirmware/start.c create mode 100644 arch/ppc/boot/utils/addnote.c create mode 100644 arch/ppc/boot/utils/hack-coff.c create mode 100644 arch/ppc/boot/utils/mknote.c rename arch/ppc/configs/{prep_defconfig => common_defconfig} (100%) create mode 100644 arch/ppc/configs/ibmchrp_defconfig delete mode 100644 arch/ppc/configs/ml300_defconfig delete mode 100644 arch/ppc/configs/ml403_defconfig create mode 100644 arch/ppc/configs/pmac_defconfig create mode 100644 arch/ppc/configs/power3_defconfig rename arch/{powerpc => ppc}/kernel/cpu_setup_6xx.S (100%) create mode 100644 arch/ppc/kernel/idle.c create mode 100644 arch/ppc/kernel/idle_6xx.S create mode 100644 arch/ppc/kernel/idle_power4.S rename arch/{powerpc/kernel/l2cr_6xx.S => ppc/kernel/l2cr.S} (100%) rename arch/{powerpc/kernel/module_32.c => ppc/kernel/module.c} (100%) rename arch/{powerpc => ppc}/kernel/perfmon_fsl_booke.c (100%) rename arch/{powerpc/kernel/swsusp_32.S => ppc/kernel/swsusp.S} (100%) rename arch/{powerpc/kernel/tau_6xx.c => ppc/kernel/temp.c} (100%) rename arch/{powerpc => ppc}/math-emu/Makefile (100%) rename arch/{powerpc => ppc}/math-emu/double.h (100%) rename arch/{powerpc => ppc}/math-emu/fabs.c (100%) rename arch/{powerpc => ppc}/math-emu/fadd.c (100%) rename arch/{powerpc => ppc}/math-emu/fadds.c (100%) rename arch/{powerpc => ppc}/math-emu/fcmpo.c (100%) rename arch/{powerpc => ppc}/math-emu/fcmpu.c (100%) rename arch/{powerpc => ppc}/math-emu/fctiw.c (100%) rename arch/{powerpc => ppc}/math-emu/fctiwz.c (100%) rename arch/{powerpc => ppc}/math-emu/fdiv.c (100%) rename arch/{powerpc => ppc}/math-emu/fdivs.c (100%) rename arch/{powerpc => ppc}/math-emu/fmadd.c (100%) rename arch/{powerpc => ppc}/math-emu/fmadds.c (100%) rename arch/{powerpc => ppc}/math-emu/fmr.c (100%) rename arch/{powerpc => ppc}/math-emu/fmsub.c (100%) rename arch/{powerpc => ppc}/math-emu/fmsubs.c (100%) rename arch/{powerpc => ppc}/math-emu/fmul.c (100%) rename arch/{powerpc => ppc}/math-emu/fmuls.c (100%) rename arch/{powerpc => ppc}/math-emu/fnabs.c (100%) rename arch/{powerpc => ppc}/math-emu/fneg.c (100%) rename arch/{powerpc => ppc}/math-emu/fnmadd.c (100%) rename arch/{powerpc => ppc}/math-emu/fnmadds.c (100%) rename arch/{powerpc => ppc}/math-emu/fnmsub.c (100%) rename arch/{powerpc => ppc}/math-emu/fnmsubs.c (100%) rename arch/{powerpc => ppc}/math-emu/fres.c (100%) rename arch/{powerpc => ppc}/math-emu/frsp.c (100%) rename arch/{powerpc => ppc}/math-emu/frsqrte.c (100%) rename arch/{powerpc => ppc}/math-emu/fsel.c (100%) rename arch/{powerpc => ppc}/math-emu/fsqrt.c (100%) rename arch/{powerpc => ppc}/math-emu/fsqrts.c (100%) rename arch/{powerpc => ppc}/math-emu/fsub.c (100%) rename arch/{powerpc => ppc}/math-emu/fsubs.c (100%) rename arch/{powerpc => ppc}/math-emu/lfd.c (100%) rename arch/{powerpc => ppc}/math-emu/lfs.c (100%) rename arch/{powerpc => ppc}/math-emu/math.c (99%) rename arch/{powerpc => ppc}/math-emu/mcrfs.c (100%) rename arch/{powerpc => ppc}/math-emu/mffs.c (100%) rename arch/{powerpc => ppc}/math-emu/mtfsb0.c (100%) rename arch/{powerpc => ppc}/math-emu/mtfsb1.c (100%) rename arch/{powerpc => ppc}/math-emu/mtfsf.c (100%) rename arch/{powerpc => ppc}/math-emu/mtfsfi.c (100%) rename arch/{powerpc => ppc}/math-emu/op-1.h (100%) rename arch/{powerpc => ppc}/math-emu/op-2.h (100%) rename arch/{powerpc => ppc}/math-emu/op-4.h (100%) rename arch/{powerpc => ppc}/math-emu/op-common.h (100%) rename arch/{powerpc => ppc}/math-emu/sfp-machine.h (100%) rename arch/{powerpc => ppc}/math-emu/single.h (100%) rename arch/{powerpc => ppc}/math-emu/soft-fp.h (100%) rename arch/{powerpc => ppc}/math-emu/stfd.c (100%) rename arch/{powerpc => ppc}/math-emu/stfiwx.c (100%) rename arch/{powerpc => ppc}/math-emu/stfs.c (100%) rename arch/{powerpc => ppc}/math-emu/types.c (100%) rename arch/{powerpc => ppc}/math-emu/udivmodti4.c (100%) create mode 100644 arch/ppc/platforms/4xx/virtex-ii_pro.c create mode 100644 arch/ppc/platforms/4xx/virtex-ii_pro.h delete mode 100644 arch/ppc/platforms/4xx/virtex.c delete mode 100644 arch/ppc/platforms/4xx/virtex.h delete mode 100644 arch/ppc/platforms/4xx/xilinx_ml403.c delete mode 100644 arch/ppc/platforms/4xx/xilinx_ml403.h delete mode 100644 arch/ppc/platforms/4xx/xparameters/xparameters.h delete mode 100644 arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h create mode 100644 arch/ppc/platforms/chrp_pci.c create mode 100644 arch/ppc/platforms/chrp_pegasos_eth.c create mode 100644 arch/ppc/platforms/chrp_setup.c create mode 100644 arch/ppc/platforms/chrp_smp.c create mode 100644 arch/ppc/platforms/chrp_time.c delete mode 100644 arch/ppc/platforms/mpc8272ads_setup.c delete mode 100644 arch/ppc/platforms/mpc866ads_setup.c delete mode 100644 arch/ppc/platforms/mpc885ads_setup.c delete mode 100644 arch/ppc/platforms/pq2ads_pd.h create mode 100644 arch/ppc/syslib/ppc4xx_pm.c create mode 100644 arch/ppc/syslib/prom.c create mode 100644 arch/ppc/syslib/prom_init.c create mode 100644 arch/sparc64/kernel/dtlb_backend.S create mode 100644 arch/sparc64/kernel/dtlb_base.S delete mode 100644 arch/sparc64/kernel/dtlb_miss.S create mode 100644 arch/sparc64/kernel/itlb_base.S delete mode 100644 arch/sparc64/kernel/itlb_miss.S delete mode 100644 arch/sparc64/kernel/pci_sun4v.c delete mode 100644 arch/sparc64/kernel/pci_sun4v.h delete mode 100644 arch/sparc64/kernel/pci_sun4v_asm.S delete mode 100644 arch/sparc64/kernel/sun4v_ivec.S delete mode 100644 arch/sparc64/kernel/sun4v_tlb_miss.S delete mode 100644 arch/sparc64/kernel/tsb.S delete mode 100644 arch/sparc64/kernel/visemul.c delete mode 100644 arch/sparc64/lib/NGbzero.S delete mode 100644 arch/sparc64/lib/NGcopy_from_user.S delete mode 100644 arch/sparc64/lib/NGcopy_to_user.S delete mode 100644 arch/sparc64/lib/NGmemcpy.S delete mode 100644 arch/sparc64/lib/NGpage.S delete mode 100644 arch/sparc64/lib/NGpatch.S create mode 100644 arch/sparc64/lib/find_bit.c delete mode 100644 arch/sparc64/mm/tsb.c delete mode 100644 arch/um/include/misc_constants.h delete mode 100644 arch/um/include/sysdep-i386/tls.h delete mode 100644 arch/um/include/sysdep-x86_64/tls.h create mode 100644 arch/um/kernel/irq_user.c rename arch/um/{os-Linux/sigio.c => kernel/sigio_user.c} (60%) rename arch/um/{os-Linux => kernel}/tty_log.c (91%) delete mode 100644 arch/um/os-Linux/irq.c delete mode 100644 arch/um/os-Linux/sys-i386/tls.c delete mode 100644 arch/um/os-Linux/tls.c delete mode 100644 arch/um/sys-i386/tls.c delete mode 100644 arch/um/sys-x86_64/tls.c delete mode 100644 arch/x86_64/ia32/ia32entry-xen.S delete mode 100644 arch/x86_64/ia32/syscall32-xen.c delete mode 100644 arch/x86_64/ia32/syscall32_syscall-xen.S delete mode 100644 arch/x86_64/ia32/vsyscall-int80.S delete mode 100644 arch/x86_64/kernel/acpi/processor.c delete mode 100644 arch/x86_64/kernel/apic-xen.c delete mode 100644 arch/x86_64/kernel/e820-xen.c delete mode 100644 arch/x86_64/kernel/early_printk-xen.c delete mode 100644 arch/x86_64/kernel/entry-xen.S delete mode 100644 arch/x86_64/kernel/functionlist delete mode 100644 arch/x86_64/kernel/genapic-xen.c delete mode 100644 arch/x86_64/kernel/genapic_xen.c delete mode 100644 arch/x86_64/kernel/head-xen.S delete mode 100644 arch/x86_64/kernel/head64-xen.c delete mode 100644 arch/x86_64/kernel/io_apic-xen.c delete mode 100644 arch/x86_64/kernel/ioport-xen.c delete mode 100644 arch/x86_64/kernel/irq-xen.c delete mode 100644 arch/x86_64/kernel/ldt-xen.c delete mode 100644 arch/x86_64/kernel/mpparse-xen.c delete mode 100644 arch/x86_64/kernel/pci-swiotlb-xen.c delete mode 100644 arch/x86_64/kernel/process-xen.c delete mode 100644 arch/x86_64/kernel/setup-xen.c delete mode 100644 arch/x86_64/kernel/setup64-xen.c delete mode 100644 arch/x86_64/kernel/smp-xen.c delete mode 100644 arch/x86_64/kernel/traps-xen.c delete mode 100644 arch/x86_64/kernel/vsyscall-xen.c delete mode 100644 arch/x86_64/kernel/x8664_ksyms-xen.c delete mode 100644 arch/x86_64/kernel/xen_entry.S delete mode 100644 arch/x86_64/mm/fault-xen.c delete mode 100644 arch/x86_64/mm/init-xen.c delete mode 100644 arch/x86_64/mm/pageattr-xen.c delete mode 100644 block/blktrace.c delete mode 100644 configs/kernel-2.6.17-i586-smp.config delete mode 100644 configs/kernel-2.6.17-i586.config delete mode 100644 configs/kernel-2.6.17-i686-kdump.config delete mode 100644 configs/kernel-2.6.17-i686-smp.config delete mode 100644 configs/kernel-2.6.17-i686-xen.config delete mode 100644 configs/kernel-2.6.17-i686-xen0.config delete mode 100644 configs/kernel-2.6.17-i686-xenU.config delete mode 100644 configs/kernel-2.6.17-i686.config delete mode 100644 crypto/mpi/Makefile delete mode 100644 crypto/mpi/generic_mpi-asm-defs.h delete mode 100644 crypto/mpi/generic_mpih-add1.c delete mode 100644 crypto/mpi/generic_mpih-lshift.c delete mode 100644 crypto/mpi/generic_mpih-mul1.c delete mode 100644 crypto/mpi/generic_mpih-mul2.c delete mode 100644 crypto/mpi/generic_mpih-mul3.c delete mode 100644 crypto/mpi/generic_mpih-rshift.c delete mode 100644 crypto/mpi/generic_mpih-sub1.c delete mode 100644 crypto/mpi/generic_udiv-w-sdiv.c delete mode 100644 crypto/mpi/longlong.h delete mode 100644 crypto/mpi/mpi-add.c delete mode 100644 crypto/mpi/mpi-bit.c delete mode 100644 crypto/mpi/mpi-cmp.c delete mode 100644 crypto/mpi/mpi-div.c delete mode 100644 crypto/mpi/mpi-gcd.c delete mode 100644 crypto/mpi/mpi-inline.c delete mode 100644 crypto/mpi/mpi-inline.h delete mode 100644 crypto/mpi/mpi-internal.h delete mode 100644 crypto/mpi/mpi-inv.c delete mode 100644 crypto/mpi/mpi-mpow.c delete mode 100644 crypto/mpi/mpi-mul.c delete mode 100644 crypto/mpi/mpi-pow.c delete mode 100644 crypto/mpi/mpi-scan.c delete mode 100644 crypto/mpi/mpicoder.c delete mode 100644 crypto/mpi/mpih-cmp.c delete mode 100644 crypto/mpi/mpih-div.c delete mode 100644 crypto/mpi/mpih-mul.c delete mode 100644 crypto/mpi/mpiutil.c delete mode 100644 crypto/signature/Makefile delete mode 100644 crypto/signature/dsa.c delete mode 100644 crypto/signature/key.h delete mode 100644 crypto/signature/ksign-keyring.c delete mode 100644 crypto/signature/ksign-parse.c delete mode 100644 crypto/signature/ksign-publickey.c delete mode 100644 crypto/signature/ksign.c delete mode 100644 crypto/signature/local.h delete mode 100644 drivers/atm/.gitignore delete mode 100644 drivers/block/mambo_bd.c delete mode 100644 drivers/char/crash.c delete mode 100644 drivers/char/hvc_console.h delete mode 100644 drivers/char/hvc_rtas.c rename drivers/char/{ip2/ip2base.c => ip2.c} (95%) delete mode 100644 drivers/char/ip2/Makefile rename drivers/char/{ip2 => }/ip2main.c (99%) create mode 100644 drivers/char/rio/bootpkt.h create mode 100644 drivers/char/rio/control.h create mode 100644 drivers/char/rio/defaults.h create mode 100644 drivers/char/rio/error.h create mode 100644 drivers/char/rio/list.h create mode 100644 drivers/char/rio/qbuf.h create mode 100644 drivers/char/rio/riopcicopy.c create mode 100644 drivers/char/rio/riotypes.h create mode 100644 drivers/char/rio/rom.h create mode 100644 drivers/char/rio/sam.h create mode 100644 drivers/char/rio/space.h create mode 100644 drivers/char/rio/top.h create mode 100644 drivers/char/rio/typdef.h delete mode 100644 drivers/char/tpm/tpm_tis.c rename drivers/{rtc/rtc-vr41xx.c => char/vr41xx_rtc.c} (55%) delete mode 100644 drivers/char/watchdog/at91_wdt.c delete mode 100644 drivers/char/watchdog/ep93xx_wdt.c delete mode 100644 drivers/eisa/.gitignore create mode 100644 drivers/i2c/busses/i2c-frodo.c create mode 100644 drivers/i2c/chips/rtc8564.c create mode 100644 drivers/i2c/chips/rtc8564.h delete mode 100644 drivers/infiniband/hw/ipath/Kconfig delete mode 100644 drivers/infiniband/hw/ipath/Makefile delete mode 100644 drivers/infiniband/hw/ipath/ipath_common.h delete mode 100644 drivers/infiniband/hw/ipath/ipath_cq.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_debug.h delete mode 100644 drivers/infiniband/hw/ipath/ipath_diag.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_driver.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_eeprom.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_file_ops.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_fs.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_ht400.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_init_chip.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_intr.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_kernel.h delete mode 100644 drivers/infiniband/hw/ipath/ipath_keys.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_layer.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_layer.h delete mode 100644 drivers/infiniband/hw/ipath/ipath_mad.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_mr.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_pe800.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_qp.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_rc.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_registers.h delete mode 100644 drivers/infiniband/hw/ipath/ipath_ruc.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_srq.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_stats.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_sysfs.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_uc.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_ud.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_user_pages.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_verbs.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_verbs.h delete mode 100644 drivers/infiniband/hw/ipath/ipath_verbs_mcast.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_wc_x86_64.c delete mode 100644 drivers/infiniband/hw/ipath/ips_common.h delete mode 100644 drivers/infiniband/hw/ipath/verbs_debug.h delete mode 100644 drivers/isdn/gigaset/Kconfig delete mode 100644 drivers/isdn/gigaset/Makefile delete mode 100644 drivers/isdn/gigaset/asyncdata.c delete mode 100644 drivers/isdn/gigaset/bas-gigaset.c delete mode 100644 drivers/isdn/gigaset/common.c delete mode 100644 drivers/isdn/gigaset/ev-layer.c delete mode 100644 drivers/isdn/gigaset/gigaset.h delete mode 100644 drivers/isdn/gigaset/i4l.c delete mode 100644 drivers/isdn/gigaset/interface.c delete mode 100644 drivers/isdn/gigaset/isocdata.c delete mode 100644 drivers/isdn/gigaset/proc.c delete mode 100644 drivers/isdn/gigaset/usb-gigaset.c delete mode 100644 drivers/leds/Kconfig delete mode 100644 drivers/leds/Makefile delete mode 100644 drivers/leds/led-class.c delete mode 100644 drivers/leds/led-core.c delete mode 100644 drivers/leds/led-triggers.c delete mode 100644 drivers/leds/leds-corgi.c delete mode 100644 drivers/leds/leds-ixp4xx-gpio.c delete mode 100644 drivers/leds/leds-locomo.c delete mode 100644 drivers/leds/leds-s3c24xx.c delete mode 100644 drivers/leds/leds-spitz.c delete mode 100644 drivers/leds/leds-tosa.c delete mode 100644 drivers/leds/leds.h delete mode 100644 drivers/leds/ledtrig-ide-disk.c delete mode 100644 drivers/leds/ledtrig-timer.c create mode 100644 drivers/media/common/ir-common.c delete mode 100644 drivers/media/common/ir-functions.c delete mode 100644 drivers/media/common/ir-keymaps.c delete mode 100644 drivers/media/dvb/frontends/bsbe1.h delete mode 100644 drivers/media/dvb/frontends/bsru6.h delete mode 100644 drivers/media/dvb/frontends/lnbp21.h delete mode 100644 drivers/media/dvb/frontends/zl10353.c delete mode 100644 drivers/media/dvb/frontends/zl10353.h delete mode 100644 drivers/media/dvb/frontends/zl10353_priv.h rename drivers/media/video/{bt8xx => }/bt832.c (98%) rename drivers/media/video/{bt8xx => }/bt832.h (100%) rename drivers/media/video/{bt8xx => }/bt848.h (100%) delete mode 100644 drivers/media/video/bt8xx/Kconfig delete mode 100644 drivers/media/video/bt8xx/Makefile delete mode 100644 drivers/media/video/bt8xx/bttv-input.c rename drivers/media/video/{bt8xx => }/bttv-cards.c (95%) rename drivers/media/video/{bt8xx => }/bttv-driver.c (94%) rename drivers/media/video/{bt8xx => }/bttv-gpio.c (100%) rename drivers/media/video/{bt8xx => }/bttv-i2c.c (98%) rename drivers/media/video/{bt8xx => }/bttv-if.c (100%) rename drivers/media/video/{bt8xx => }/bttv-risc.c (96%) rename drivers/media/video/{bt8xx => }/bttv-vbi.c (97%) rename drivers/media/video/{bt8xx => }/bttv.h (95%) rename drivers/media/video/{bt8xx => }/bttvp.h (98%) delete mode 100644 drivers/media/video/cpia2/Kconfig delete mode 100644 drivers/media/video/cpia2/Makefile delete mode 100644 drivers/media/video/cpia2/cpia2.h delete mode 100644 drivers/media/video/cpia2/cpia2_core.c delete mode 100644 drivers/media/video/cpia2/cpia2_registers.h delete mode 100644 drivers/media/video/cpia2/cpia2_usb.c delete mode 100644 drivers/media/video/cpia2/cpia2_v4l.c delete mode 100644 drivers/media/video/cpia2/cpia2dev.h delete mode 100644 drivers/media/video/cpia2/cpia2patch.h delete mode 100644 drivers/media/video/cx25840/Kconfig delete mode 100644 drivers/media/video/cx25840/cx25840-core.h delete mode 100644 drivers/media/video/et61x251/Kconfig delete mode 100644 drivers/media/video/et61x251/Makefile delete mode 100644 drivers/media/video/et61x251/et61x251.h delete mode 100644 drivers/media/video/et61x251/et61x251_core.c delete mode 100644 drivers/media/video/et61x251/et61x251_sensor.h delete mode 100644 drivers/media/video/et61x251/et61x251_tas5130d1b.c delete mode 100644 drivers/media/video/font.h rename drivers/media/video/{msp3400-driver.h => msp3400.h} (74%) delete mode 100644 drivers/media/video/pwc/Kconfig delete mode 100644 drivers/media/video/pwc/Makefile delete mode 100644 drivers/media/video/pwc/pwc-kiara.c delete mode 100644 drivers/media/video/pwc/pwc-timon.c delete mode 100644 drivers/media/video/sn9c102/Kconfig delete mode 100644 drivers/media/video/sn9c102/Makefile delete mode 100644 drivers/media/video/sn9c102/sn9c102_ov7630.c delete mode 100644 drivers/media/video/sn9c102/sn9c102_pas202bca.c create mode 100644 drivers/media/video/tvaudio.h delete mode 100644 drivers/media/video/upd64031a.c delete mode 100644 drivers/media/video/upd64083.c delete mode 100644 drivers/media/video/usbvideo/Kconfig delete mode 100644 drivers/media/video/usbvideo/Makefile delete mode 100644 drivers/media/video/vivi.c delete mode 100644 drivers/media/video/wm8739.c delete mode 100644 drivers/media/video/zc0301/Kconfig delete mode 100644 drivers/media/video/zc0301/Makefile delete mode 100644 drivers/media/video/zc0301/zc0301.h delete mode 100644 drivers/media/video/zc0301/zc0301_core.c delete mode 100644 drivers/media/video/zc0301/zc0301_pas202bcb.c delete mode 100644 drivers/media/video/zc0301/zc0301_sensor.h delete mode 100644 drivers/mmc/at91_mci.c delete mode 100644 drivers/mmc/imxmmc.c delete mode 100644 drivers/mmc/imxmmc.h delete mode 100644 drivers/mmc/omap.c delete mode 100644 drivers/mmc/omap.h delete mode 100644 drivers/mmc/sdhci.c delete mode 100644 drivers/mmc/sdhci.h create mode 100644 drivers/mtd/devices/blkmtd.c delete mode 100644 drivers/net/arm/at91_ether.c delete mode 100644 drivers/net/arm/at91_ether.h create mode 100644 drivers/net/hydra.h create mode 100644 drivers/net/irda/sir_kthread.c delete mode 100644 drivers/net/irda/toim3232-sir.c delete mode 100644 drivers/net/mambonet.c create mode 100644 drivers/net/wan/sdla_chdlc.c create mode 100644 drivers/net/wan/sdla_fr.c create mode 100644 drivers/net/wan/sdla_ft1.c create mode 100644 drivers/net/wan/sdla_ppp.c create mode 100644 drivers/net/wan/sdla_x25.c create mode 100644 drivers/net/wan/sdladrv.c create mode 100644 drivers/net/wan/sdlamain.c create mode 100644 drivers/net/wan/wanpipe_multppp.c delete mode 100644 drivers/net/wireless/bcm43xx/Kconfig delete mode 100644 drivers/net/wireless/bcm43xx/Makefile delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_dma.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_dma.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_ilt.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_ilt.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_leds.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_leds.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_main.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_main.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_phy.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_phy.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_pio.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_pio.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_power.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_power.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_radio.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_radio.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_wx.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_wx.h delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_xmit.c delete mode 100644 drivers/net/wireless/bcm43xx/bcm43xx_xmit.h delete mode 100644 drivers/pci/hotplug/acpiphp_dock.c create mode 100644 drivers/pci/hotplug/pciehprm_acpi.c create mode 100644 drivers/pci/hotplug/pciehprm_nonacpi.c rename drivers/pci/hotplug/{acpi_pcihp.c => shpchprm_acpi.c} (55%) create mode 100644 drivers/pci/hotplug/shpchprm_legacy.c create mode 100644 drivers/pci/hotplug/shpchprm_nonacpi.c delete mode 100644 drivers/pcmcia/at91_cf.c create mode 100644 drivers/pcmcia/pcmcia_compat.c delete mode 100644 drivers/rtc/Kconfig delete mode 100644 drivers/rtc/Makefile delete mode 100644 drivers/rtc/class.c delete mode 100644 drivers/rtc/hctosys.c delete mode 100644 drivers/rtc/interface.c delete mode 100644 drivers/rtc/rtc-dev.c delete mode 100644 drivers/rtc/rtc-ds1672.c delete mode 100644 drivers/rtc/rtc-ep93xx.c delete mode 100644 drivers/rtc/rtc-lib.c delete mode 100644 drivers/rtc/rtc-m48t86.c delete mode 100644 drivers/rtc/rtc-pcf8563.c delete mode 100644 drivers/rtc/rtc-proc.c delete mode 100644 drivers/rtc/rtc-rs5c372.c delete mode 100644 drivers/rtc/rtc-sa1100.c delete mode 100644 drivers/rtc/rtc-sysfs.c delete mode 100644 drivers/rtc/rtc-test.c delete mode 100644 drivers/rtc/rtc-x1205.c create mode 100644 drivers/s390/block/dasd_cmb.c delete mode 100644 drivers/s390/block/dasd_eer.c delete mode 100644 drivers/s390/char/tape_3590.c delete mode 100644 drivers/s390/char/tape_3590.h create mode 100644 drivers/scsi/hptiop.c create mode 100644 drivers/scsi/hptiop.h create mode 100644 drivers/scsi/ibmvscsi/srp.h delete mode 100644 drivers/scsi/libata-bmdma.c create mode 100644 drivers/scsi/qla2xxx/ql6312.c create mode 100644 drivers/scsi/qla2xxx/ql6312_fw.c create mode 100644 drivers/scsi/qlogicfc.c create mode 100644 drivers/scsi/qlogicfc_asm.c delete mode 100644 drivers/scsi/scsi_sas_internal.h create mode 100644 drivers/serial/8250_acpi.c create mode 100644 drivers/serial/au1x00_uart.c create mode 100644 drivers/serial/mpsc.h delete mode 100644 drivers/serial/sunhv.c delete mode 100644 drivers/spi/pxa2xx_spi.c delete mode 100644 drivers/spi/spi_mpc83xx.c delete mode 100644 drivers/spi/spi_s3c24xx.c delete mode 100644 drivers/spi/spi_s3c24xx_gpio.c create mode 100644 drivers/usb/class/audio.c create mode 100644 drivers/usb/class/audio.h create mode 100644 drivers/usb/class/usb-midi.c create mode 100644 drivers/usb/class/usb-midi.h delete mode 100644 drivers/usb/gadget/at91_udc.c delete mode 100644 drivers/usb/gadget/at91_udc.h delete mode 100644 drivers/usb/host/ehci-au1xxx.c delete mode 100644 drivers/usb/host/ehci-fsl.c delete mode 100644 drivers/usb/host/ehci-fsl.h delete mode 100644 drivers/usb/host/ohci-at91.c delete mode 100644 drivers/usb/host/pci-quirks.h delete mode 100644 drivers/usb/input/usbtouchscreen.c create mode 100644 drivers/usb/media/Kconfig create mode 100644 drivers/usb/media/Makefile rename drivers/{media/video => usb/media}/dabfirmware.h (100%) rename drivers/{media/video => usb/media}/dabusb.c (97%) rename drivers/{media/video => usb/media}/dabusb.h (94%) rename drivers/{media/video => usb/media}/dsbr100.c (92%) rename drivers/{media/video/usbvideo => usb/media}/ibmcam.c (99%) rename drivers/{media/video/usbvideo => usb/media}/konicawc.c (97%) rename drivers/{media/video => usb/media}/ov511.c (98%) rename drivers/{media/video => usb/media}/ov511.h (97%) create mode 100644 drivers/usb/media/pwc/Makefile rename drivers/{media/video => usb/media}/pwc/philips.txt (90%) rename drivers/{media/video => usb/media}/pwc/pwc-ctrl.c (91%) rename drivers/{media/video => usb/media}/pwc/pwc-if.c (93%) rename drivers/{media/video => usb/media}/pwc/pwc-ioctl.h (94%) create mode 100644 drivers/usb/media/pwc/pwc-kiara.c rename drivers/{media/video => usb/media}/pwc/pwc-kiara.h (100%) rename drivers/{media/video => usb/media}/pwc/pwc-misc.c (87%) rename drivers/{media/video => usb/media}/pwc/pwc-nala.h (99%) create mode 100644 drivers/usb/media/pwc/pwc-timon.c rename drivers/{media/video => usb/media}/pwc/pwc-timon.h (100%) rename drivers/{media/video => usb/media}/pwc/pwc-uncompress.c (96%) rename drivers/{media/video => usb/media}/pwc/pwc-uncompress.h (96%) rename drivers/{media/video => usb/media}/pwc/pwc.h (99%) rename drivers/{media/video => usb/media}/se401.c (88%) rename drivers/{media/video => usb/media}/se401.h (98%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102.h (89%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102_core.c (84%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102_hv7131d.c (93%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102_mi0343.c (73%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102_pas106b.c (94%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102_pas202bcb.c (93%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102_sensor.h (90%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102_tas5110c1b.c (87%) rename drivers/{media/video/sn9c102 => usb/media}/sn9c102_tas5130d1b.c (89%) rename drivers/{media/video => usb/media}/stv680.c (98%) rename drivers/{media/video => usb/media}/stv680.h (54%) rename drivers/{media/video/usbvideo => usb/media}/ultracam.c (99%) rename drivers/{media/video/usbvideo => usb/media}/usbvideo.c (98%) rename drivers/{media/video/usbvideo => usb/media}/usbvideo.h (96%) rename drivers/{media/video/usbvideo => usb/media}/vicam.c (98%) rename drivers/{media/video => usb/media}/w9968cf.c (79%) rename drivers/{media/video => usb/media}/w9968cf.h (94%) rename drivers/{media/video => usb/media}/w9968cf_decoder.h (94%) rename drivers/{media/video => usb/media}/w9968cf_vpp.h (98%) delete mode 100644 drivers/usb/serial/ark3116.c delete mode 100644 drivers/usb/serial/funsoft.c delete mode 100644 drivers/usb/serial/navman.c delete mode 100644 drivers/video/aty/radeon_pm_whitelist.h delete mode 100644 drivers/video/au1200fb.c delete mode 100644 drivers/video/au1200fb.h delete mode 100644 drivers/video/geode/display_gx.c delete mode 100644 drivers/video/geode/display_gx.h delete mode 100644 drivers/video/geode/gxfb_core.c delete mode 100644 drivers/video/geode/video_gx.c delete mode 100644 drivers/video/geode/video_gx.h create mode 100644 drivers/video/radeonfb.c rename drivers/w1/{masters => }/ds_w1_bridge.c (75%) rename drivers/w1/{masters => }/dscore.c (99%) rename drivers/w1/{masters => }/dscore.h (100%) delete mode 100644 drivers/w1/masters/Kconfig delete mode 100644 drivers/w1/masters/Makefile delete mode 100644 drivers/w1/masters/ds2482.c rename drivers/w1/{masters => }/matrox_w1.c (91%) delete mode 100644 drivers/w1/slaves/Kconfig delete mode 100644 drivers/w1/slaves/Makefile delete mode 100644 drivers/w1/slaves/w1_ds2433.c rename drivers/w1/{slaves => }/w1_smem.c (94%) rename drivers/w1/{slaves => }/w1_therm.c (98%) delete mode 100644 drivers/xen/Kconfig delete mode 100644 drivers/xen/Makefile delete mode 100644 drivers/xen/balloon/Makefile delete mode 100644 drivers/xen/balloon/balloon.c delete mode 100644 drivers/xen/blkback/Makefile delete mode 100644 drivers/xen/blkback/blkback.c delete mode 100644 drivers/xen/blkback/common.h delete mode 100644 drivers/xen/blkback/interface.c delete mode 100644 drivers/xen/blkback/vbd.c delete mode 100644 drivers/xen/blkback/xenbus.c delete mode 100644 drivers/xen/blkfront/Kconfig delete mode 100644 drivers/xen/blkfront/Makefile delete mode 100644 drivers/xen/blkfront/blkfront.c delete mode 100644 drivers/xen/blkfront/block.h delete mode 100644 drivers/xen/blkfront/vbd.c delete mode 100644 drivers/xen/blktap/Makefile delete mode 100644 drivers/xen/blktap/blktap.c delete mode 100644 drivers/xen/blktap/common.h delete mode 100644 drivers/xen/blktap/interface.c delete mode 100644 drivers/xen/blktap/xenbus.c delete mode 100644 drivers/xen/char/Makefile delete mode 100644 drivers/xen/char/mem.c delete mode 100644 drivers/xen/console/Makefile delete mode 100644 drivers/xen/console/console.c delete mode 100644 drivers/xen/console/xencons_ring.c delete mode 100644 drivers/xen/core/Makefile delete mode 100644 drivers/xen/core/cpu_hotplug.c delete mode 100644 drivers/xen/core/evtchn.c delete mode 100644 drivers/xen/core/features.c delete mode 100644 drivers/xen/core/gnttab.c delete mode 100644 drivers/xen/core/hypervisor_sysfs.c delete mode 100644 drivers/xen/core/reboot.c delete mode 100644 drivers/xen/core/skbuff.c delete mode 100644 drivers/xen/core/smpboot.c delete mode 100644 drivers/xen/core/xen_proc.c delete mode 100644 drivers/xen/core/xen_sysfs.c delete mode 100644 drivers/xen/evtchn/Makefile delete mode 100644 drivers/xen/evtchn/evtchn.c delete mode 100644 drivers/xen/netback/Makefile delete mode 100644 drivers/xen/netback/common.h delete mode 100644 drivers/xen/netback/interface.c delete mode 100644 drivers/xen/netback/loopback.c delete mode 100644 drivers/xen/netback/netback.c delete mode 100644 drivers/xen/netback/xenbus.c delete mode 100644 drivers/xen/netfront/Kconfig delete mode 100644 drivers/xen/netfront/Makefile delete mode 100644 drivers/xen/netfront/netfront.c delete mode 100644 drivers/xen/pciback/Makefile delete mode 100644 drivers/xen/pciback/conf_space.c delete mode 100644 drivers/xen/pciback/conf_space.h delete mode 100644 drivers/xen/pciback/conf_space_capability.c delete mode 100644 drivers/xen/pciback/conf_space_capability.h delete mode 100644 drivers/xen/pciback/conf_space_capability_pm.c delete mode 100644 drivers/xen/pciback/conf_space_capability_vpd.c delete mode 100644 drivers/xen/pciback/conf_space_header.c delete mode 100644 drivers/xen/pciback/conf_space_quirks.c delete mode 100644 drivers/xen/pciback/conf_space_quirks.h delete mode 100644 drivers/xen/pciback/passthrough.c delete mode 100644 drivers/xen/pciback/pci_stub.c delete mode 100644 drivers/xen/pciback/pciback.h delete mode 100644 drivers/xen/pciback/pciback_ops.c delete mode 100644 drivers/xen/pciback/slot.c delete mode 100644 drivers/xen/pciback/vpci.c delete mode 100644 drivers/xen/pciback/xenbus.c delete mode 100644 drivers/xen/pcifront/Makefile delete mode 100644 drivers/xen/pcifront/pci.c delete mode 100644 drivers/xen/pcifront/pci_op.c delete mode 100644 drivers/xen/pcifront/pcifront.h delete mode 100644 drivers/xen/pcifront/xenbus.c delete mode 100644 drivers/xen/privcmd/Makefile delete mode 100644 drivers/xen/privcmd/privcmd.c delete mode 100644 drivers/xen/tpmback/Makefile delete mode 100644 drivers/xen/tpmback/common.h delete mode 100644 drivers/xen/tpmback/interface.c delete mode 100644 drivers/xen/tpmback/tpmback.c delete mode 100644 drivers/xen/tpmback/xenbus.c delete mode 100644 drivers/xen/util.c delete mode 100644 drivers/xen/xenbus/Makefile delete mode 100644 drivers/xen/xenbus/xenbus_backend_client.c delete mode 100644 drivers/xen/xenbus/xenbus_client.c delete mode 100644 drivers/xen/xenbus/xenbus_comms.c delete mode 100644 drivers/xen/xenbus/xenbus_comms.h delete mode 100644 drivers/xen/xenbus/xenbus_dev.c delete mode 100644 drivers/xen/xenbus/xenbus_probe.c delete mode 100644 drivers/xen/xenbus/xenbus_xs.c delete mode 100644 fs/9p/fcall.c delete mode 100644 fs/9p/fcprint.c delete mode 100644 fs/cifs/ntlmssp.c delete mode 100644 fs/coda/coda_int.h delete mode 100644 fs/jfs/ioctl.c delete mode 100644 fs/nfs/iostat.h create mode 100644 fs/relayfs/Makefile create mode 100644 fs/relayfs/inode.c create mode 100644 fs/relayfs/relay.c delete mode 100644 fs/splice.c delete mode 100644 fs/squashfs/Makefile delete mode 100644 fs/squashfs/inode.c delete mode 100644 fs/sync.c create mode 100644 include/asm-alpha/numnodes.h delete mode 100644 include/asm-arm/arch-at91rm9200/at91rm9200_emac.h delete mode 100644 include/asm-arm/arch-at91rm9200/at91rm9200_mci.h create mode 100644 include/asm-arm/arch-cl7500/param.h rename include/{xen/interface/xencomm.h => asm-arm/arch-clps711x/param.h} (51%) create mode 100644 include/asm-arm/arch-ebsa110/param.h create mode 100644 include/asm-arm/arch-ebsa285/param.h delete mode 100644 include/asm-arm/arch-ep93xx/debug-macro.S delete mode 100644 include/asm-arm/arch-ep93xx/dma.h delete mode 100644 include/asm-arm/arch-ep93xx/entry-macro.S delete mode 100644 include/asm-arm/arch-ep93xx/ep93xx-regs.h delete mode 100644 include/asm-arm/arch-ep93xx/gesbc9312.h delete mode 100644 include/asm-arm/arch-ep93xx/gpio.h delete mode 100644 include/asm-arm/arch-ep93xx/hardware.h delete mode 100644 include/asm-arm/arch-ep93xx/io.h delete mode 100644 include/asm-arm/arch-ep93xx/irqs.h delete mode 100644 include/asm-arm/arch-ep93xx/memory.h delete mode 100644 include/asm-arm/arch-ep93xx/platform.h delete mode 100644 include/asm-arm/arch-ep93xx/system.h delete mode 100644 include/asm-arm/arch-ep93xx/timex.h delete mode 100644 include/asm-arm/arch-ep93xx/ts72xx.h delete mode 100644 include/asm-arm/arch-ep93xx/uncompress.h delete mode 100644 include/asm-arm/arch-ep93xx/vmalloc.h create mode 100644 include/asm-arm/arch-h720x/irq.h create mode 100644 include/asm-arm/arch-h720x/param.h delete mode 100644 include/asm-arm/arch-imx/imx-dma.h delete mode 100644 include/asm-arm/arch-imx/imx-uart.h create mode 100644 include/asm-arm/arch-imx/irq.h delete mode 100644 include/asm-arm/arch-imx/mmc.h create mode 100644 include/asm-arm/arch-imx/param.h create mode 100644 include/asm-arm/arch-integrator/param.h create mode 100644 include/asm-arm/arch-iop3xx/param.h create mode 100644 include/asm-arm/arch-ixp2000/irq.h create mode 100644 include/asm-arm/arch-ixp2000/param.h delete mode 100644 include/asm-arm/arch-ixp23xx/debug-macro.S delete mode 100644 include/asm-arm/arch-ixp23xx/dma.h delete mode 100644 include/asm-arm/arch-ixp23xx/entry-macro.S delete mode 100644 include/asm-arm/arch-ixp23xx/hardware.h delete mode 100644 include/asm-arm/arch-ixp23xx/io.h delete mode 100644 include/asm-arm/arch-ixp23xx/irqs.h delete mode 100644 include/asm-arm/arch-ixp23xx/ixdp2351.h delete mode 100644 include/asm-arm/arch-ixp23xx/ixp23xx.h delete mode 100644 include/asm-arm/arch-ixp23xx/memory.h delete mode 100644 include/asm-arm/arch-ixp23xx/platform.h delete mode 100644 include/asm-arm/arch-ixp23xx/system.h delete mode 100644 include/asm-arm/arch-ixp23xx/time.h delete mode 100644 include/asm-arm/arch-ixp23xx/timex.h delete mode 100644 include/asm-arm/arch-ixp23xx/uncompress.h delete mode 100644 include/asm-arm/arch-ixp23xx/vmalloc.h create mode 100644 include/asm-arm/arch-ixp4xx/irq.h create mode 100644 include/asm-arm/arch-ixp4xx/param.h create mode 100644 include/asm-arm/arch-l7200/param.h create mode 100644 include/asm-arm/arch-lh7a40x/irq.h create mode 100644 include/asm-arm/arch-lh7a40x/param.h delete mode 100644 include/asm-arm/arch-omap/board-ams-delta.h delete mode 100644 include/asm-arm/arch-omap/board-apollon.h create mode 100644 include/asm-arm/arch-omap/board-netstar.h delete mode 100644 include/asm-arm/arch-omap/board-nokia.h delete mode 100644 include/asm-arm/arch-omap/gpioexpander.h delete mode 100644 include/asm-arm/arch-omap/irda.h delete mode 100644 include/asm-arm/arch-omap/keypad.h delete mode 100644 include/asm-arm/arch-omap/lcd_lph8923.h delete mode 100644 include/asm-arm/arch-omap/mcspi.h delete mode 100644 include/asm-arm/arch-omap/omap-alsa.h create mode 100644 include/asm-arm/arch-pxa/irq.h delete mode 100644 include/asm-arm/arch-pxa/lpd270.h create mode 100644 include/asm-arm/arch-pxa/param.h delete mode 100644 include/asm-arm/arch-pxa/pxa2xx_spi.h create mode 100644 include/asm-arm/arch-rpc/param.h delete mode 100644 include/asm-arm/arch-s3c2410/leds-gpio.h delete mode 100644 include/asm-arm/arch-s3c2410/osiris-cpld.h delete mode 100644 include/asm-arm/arch-s3c2410/osiris-map.h create mode 100644 include/asm-arm/arch-s3c2410/param.h delete mode 100644 include/asm-arm/arch-s3c2410/spi-gpio.h delete mode 100644 include/asm-arm/arch-s3c2410/spi.h create mode 100644 include/asm-arm/arch-sa1100/param.h create mode 100644 include/asm-arm/arch-shark/param.h create mode 100644 include/asm-arm/arch-versatile/param.h delete mode 100644 include/asm-arm/hardware/debug-8250.S delete mode 100644 include/asm-arm/hardware/debug-pl01x.S delete mode 100644 include/asm-arm/hardware/uengine.h create mode 100644 include/asm-arm/numnodes.h delete mode 100644 include/asm-arm/pgtable-hwdef.h delete mode 100644 include/asm-generic/bitops/__ffs.h delete mode 100644 include/asm-generic/bitops/atomic.h delete mode 100644 include/asm-generic/bitops/ext2-atomic.h delete mode 100644 include/asm-generic/bitops/ext2-non-atomic.h delete mode 100644 include/asm-generic/bitops/ffs.h delete mode 100644 include/asm-generic/bitops/ffz.h delete mode 100644 include/asm-generic/bitops/find.h delete mode 100644 include/asm-generic/bitops/fls.h delete mode 100644 include/asm-generic/bitops/fls64.h delete mode 100644 include/asm-generic/bitops/hweight.h delete mode 100644 include/asm-generic/bitops/le.h delete mode 100644 include/asm-generic/bitops/minix-le.h delete mode 100644 include/asm-generic/bitops/minix.h delete mode 100644 include/asm-generic/bitops/non-atomic.h delete mode 100644 include/asm-generic/bitops/sched.h delete mode 100644 include/asm-generic/memory_model.h delete mode 100644 include/asm-i386/alternative.h delete mode 100644 include/asm-i386/crash.h delete mode 100644 include/asm-i386/dmi.h delete mode 100644 include/asm-i386/mach-xen/asm/agp.h delete mode 100644 include/asm-i386/mach-xen/asm/desc.h delete mode 100644 include/asm-i386/mach-xen/asm/dma-mapping.h delete mode 100644 include/asm-i386/mach-xen/asm/fixmap.h delete mode 100644 include/asm-i386/mach-xen/asm/floppy.h delete mode 100644 include/asm-i386/mach-xen/asm/highmem.h delete mode 100644 include/asm-i386/mach-xen/asm/hw_irq.h delete mode 100644 include/asm-i386/mach-xen/asm/hypercall.h delete mode 100644 include/asm-i386/mach-xen/asm/hypervisor.h delete mode 100644 include/asm-i386/mach-xen/asm/io.h delete mode 100644 include/asm-i386/mach-xen/asm/kmap_types.h delete mode 100644 include/asm-i386/mach-xen/asm/mmu.h delete mode 100644 include/asm-i386/mach-xen/asm/mmu_context.h delete mode 100644 include/asm-i386/mach-xen/asm/page.h delete mode 100644 include/asm-i386/mach-xen/asm/param.h delete mode 100644 include/asm-i386/mach-xen/asm/pci.h delete mode 100644 include/asm-i386/mach-xen/asm/pgalloc.h delete mode 100644 include/asm-i386/mach-xen/asm/pgtable-2level-defs.h delete mode 100644 include/asm-i386/mach-xen/asm/pgtable-2level.h delete mode 100644 include/asm-i386/mach-xen/asm/pgtable-3level-defs.h delete mode 100644 include/asm-i386/mach-xen/asm/pgtable-3level.h delete mode 100644 include/asm-i386/mach-xen/asm/pgtable.h delete mode 100644 include/asm-i386/mach-xen/asm/processor.h delete mode 100644 include/asm-i386/mach-xen/asm/ptrace.h delete mode 100644 include/asm-i386/mach-xen/asm/scatterlist.h delete mode 100644 include/asm-i386/mach-xen/asm/segment.h delete mode 100644 include/asm-i386/mach-xen/asm/setup.h delete mode 100644 include/asm-i386/mach-xen/asm/smp.h delete mode 100644 include/asm-i386/mach-xen/asm/spinlock.h delete mode 100644 include/asm-i386/mach-xen/asm/swiotlb.h delete mode 100644 include/asm-i386/mach-xen/asm/synch_bitops.h delete mode 100644 include/asm-i386/mach-xen/asm/system.h delete mode 100644 include/asm-i386/mach-xen/asm/tlbflush.h delete mode 100644 include/asm-i386/mach-xen/asm/vga.h delete mode 100644 include/asm-i386/mach-xen/irq_vectors.h delete mode 100644 include/asm-i386/mach-xen/mach_traps.h delete mode 100644 include/asm-i386/mach-xen/setup_arch_post.h delete mode 100644 include/asm-i386/mach-xen/setup_arch_pre.h create mode 100644 include/asm-i386/numnodes.h delete mode 100644 include/asm-ia64/crash.h delete mode 100644 include/asm-ia64/dmi.h create mode 100644 include/asm-ia64/numnodes.h create mode 100644 include/asm-m32r/numnodes.h delete mode 100644 include/asm-mips/ds1742.h delete mode 100644 include/asm-mips/kspd.h delete mode 100644 include/asm-mips/mach-mips/param.h delete mode 100644 include/asm-mips/mips_mt.h create mode 100644 include/asm-mips/numnodes.h delete mode 100644 include/asm-mips/smtc.h delete mode 100644 include/asm-mips/smtc_ipi.h delete mode 100644 include/asm-mips/smtc_proc.h delete mode 100644 include/asm-mips/sparsemem.h delete mode 100644 include/asm-mips/vpe.h create mode 100644 include/asm-parisc/numnodes.h delete mode 100644 include/asm-powerpc/syscalls.h delete mode 100644 include/asm-powerpc/systemsim.h create mode 100644 include/asm-ppc/xparameters.h create mode 100644 include/asm-sh/numnodes.h delete mode 100644 include/asm-sparc/vga.h delete mode 100644 include/asm-sparc64/hypervisor.h delete mode 100644 include/asm-sparc64/intr_queue.h delete mode 100644 include/asm-sparc64/numnodes.h delete mode 100644 include/asm-sparc64/scratchpad.h delete mode 100644 include/asm-sparc64/sparsemem.h delete mode 100644 include/asm-sparc64/tsb.h delete mode 100644 include/asm-sparc64/vdev.h delete mode 100644 include/asm-um/alternative.h delete mode 100644 include/asm-um/host_ldt-i386.h delete mode 100644 include/asm-um/host_ldt-x86_64.h delete mode 100644 include/asm-um/irqflags.h delete mode 100644 include/asm-um/ldt.h delete mode 100644 include/asm-x86_64/crash.h delete mode 100644 include/asm-x86_64/dmi.h delete mode 100644 include/asm-x86_64/mach-xen/asm/arch_hooks.h delete mode 100644 include/asm-x86_64/mach-xen/asm/bootsetup.h delete mode 100644 include/asm-x86_64/mach-xen/asm/desc.h delete mode 100644 include/asm-x86_64/mach-xen/asm/dma-mapping.h delete mode 100644 include/asm-x86_64/mach-xen/asm/dmi.h delete mode 100644 include/asm-x86_64/mach-xen/asm/e820.h delete mode 100644 include/asm-x86_64/mach-xen/asm/fixmap.h delete mode 100644 include/asm-x86_64/mach-xen/asm/floppy.h delete mode 100644 include/asm-x86_64/mach-xen/asm/hw_irq.h delete mode 100644 include/asm-x86_64/mach-xen/asm/hypercall.h delete mode 100644 include/asm-x86_64/mach-xen/asm/hypervisor.h delete mode 100644 include/asm-x86_64/mach-xen/asm/io.h delete mode 100644 include/asm-x86_64/mach-xen/asm/irq.h delete mode 100644 include/asm-x86_64/mach-xen/asm/mmu.h delete mode 100644 include/asm-x86_64/mach-xen/asm/mmu_context.h delete mode 100644 include/asm-x86_64/mach-xen/asm/msr.h delete mode 100644 include/asm-x86_64/mach-xen/asm/nmi.h delete mode 100644 include/asm-x86_64/mach-xen/asm/page.h delete mode 100644 include/asm-x86_64/mach-xen/asm/param.h delete mode 100644 include/asm-x86_64/mach-xen/asm/pci.h delete mode 100644 include/asm-x86_64/mach-xen/asm/pgalloc.h delete mode 100644 include/asm-x86_64/mach-xen/asm/pgtable.h delete mode 100644 include/asm-x86_64/mach-xen/asm/processor.h delete mode 100644 include/asm-x86_64/mach-xen/asm/ptrace.h delete mode 100644 include/asm-x86_64/mach-xen/asm/smp.h delete mode 100644 include/asm-x86_64/mach-xen/asm/synch_bitops.h delete mode 100644 include/asm-x86_64/mach-xen/asm/system.h delete mode 100644 include/asm-x86_64/mach-xen/asm/timer.h delete mode 100644 include/asm-x86_64/mach-xen/asm/tlbflush.h delete mode 100644 include/asm-x86_64/mach-xen/asm/vga.h delete mode 100644 include/asm-x86_64/mach-xen/asm/xor.h delete mode 100644 include/asm-x86_64/mach-xen/irq_vectors.h delete mode 100644 include/asm-x86_64/mach-xen/mach_time.h delete mode 100644 include/asm-x86_64/mach-xen/mach_timer.h delete mode 100644 include/asm-x86_64/mach-xen/setup_arch_post.h delete mode 100644 include/asm-x86_64/mach-xen/setup_arch_pre.h create mode 100644 include/asm-x86_64/numnodes.h delete mode 100644 include/linux/blktrace_api.h delete mode 100644 include/linux/crypto/ksign.h delete mode 100644 include/linux/crypto/mpi.h delete mode 100644 include/linux/fs_uart_pd.h delete mode 100644 include/linux/gigaset_dev.h delete mode 100644 include/linux/leds.h delete mode 100644 include/linux/m48t86.h delete mode 100644 include/linux/migrate.h delete mode 100644 include/linux/netfilter/xt_esp.h delete mode 100644 include/linux/netfilter/xt_multiport.h delete mode 100644 include/linux/netfilter/xt_policy.h delete mode 100644 include/linux/netfilter_ipv4/ip_conntrack_h323.h delete mode 100644 include/linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h delete mode 100644 include/linux/netfilter_ipv4/ip_conntrack_helper_h323_types.h delete mode 100644 include/linux/pfn.h create mode 100644 include/linux/platform.h rename include/linux/{relay.h => relayfs_fs.h} (87%) create mode 100644 include/linux/sdla_asy.h create mode 100644 include/linux/sdla_chdlc.h create mode 100644 include/linux/sdla_ppp.h create mode 100644 include/linux/sdla_x25.h create mode 100644 include/linux/sdladrv.h create mode 100644 include/linux/sdlapci.h create mode 100644 include/linux/sdlasfm.h delete mode 100644 include/linux/selinux.h delete mode 100644 include/linux/squashfs_fs.h delete mode 100644 include/linux/squashfs_fs_i.h delete mode 100644 include/linux/squashfs_fs_sb.h delete mode 100644 include/linux/sunrpc/metrics.h delete mode 100644 include/linux/usb/net2280.h create mode 100644 include/linux/vserver/cacct.h create mode 100644 include/linux/wanpipe.h delete mode 100644 include/media/cs53l32a.h delete mode 100644 include/media/cx25840.h delete mode 100644 include/media/i2c-addr.h delete mode 100644 include/media/msp3400.h delete mode 100644 include/media/rds.h delete mode 100644 include/media/saa7115.h delete mode 100644 include/media/saa7127.h delete mode 100644 include/media/tvaudio.h delete mode 100644 include/media/upd64031a.h delete mode 100644 include/media/upd64083.h delete mode 100644 include/media/wm8775.h delete mode 100644 include/net/ieee80211softmac.h delete mode 100644 include/net/ieee80211softmac_wx.h delete mode 100644 include/net/tux.h delete mode 100644 include/net/tux_u.h delete mode 100644 include/xen/balloon.h delete mode 100644 include/xen/cpu_hotplug.h delete mode 100644 include/xen/driver_util.h delete mode 100644 include/xen/evtchn.h delete mode 100644 include/xen/features.h delete mode 100644 include/xen/foreign_page.h delete mode 100644 include/xen/gnttab.h delete mode 100644 include/xen/hypervisor_sysfs.h delete mode 100644 include/xen/interface/acm.h delete mode 100644 include/xen/interface/acm_ops.h delete mode 100644 include/xen/interface/arch-powerpc.h delete mode 100644 include/xen/interface/arch-x86_32.h delete mode 100644 include/xen/interface/arch-x86_64.h delete mode 100644 include/xen/interface/callback.h delete mode 100644 include/xen/interface/dom0_ops.h delete mode 100644 include/xen/interface/event_channel.h delete mode 100644 include/xen/interface/features.h delete mode 100644 include/xen/interface/grant_table.h delete mode 100644 include/xen/interface/hvm/hvm_info_table.h delete mode 100644 include/xen/interface/hvm/ioreq.h delete mode 100644 include/xen/interface/hvm/params.h delete mode 100644 include/xen/interface/hvm/vmx_assist.h delete mode 100644 include/xen/interface/io/blkif.h delete mode 100644 include/xen/interface/io/console.h delete mode 100644 include/xen/interface/io/netif.h delete mode 100644 include/xen/interface/io/pciif.h delete mode 100644 include/xen/interface/io/ring.h delete mode 100644 include/xen/interface/io/tpmif.h delete mode 100644 include/xen/interface/io/xenbus.h delete mode 100644 include/xen/interface/io/xs_wire.h delete mode 100644 include/xen/interface/memory.h delete mode 100644 include/xen/interface/nmi.h delete mode 100644 include/xen/interface/physdev.h delete mode 100644 include/xen/interface/sched.h delete mode 100644 include/xen/interface/sched_ctl.h delete mode 100644 include/xen/interface/trace.h delete mode 100644 include/xen/interface/vcpu.h delete mode 100644 include/xen/interface/version.h delete mode 100644 include/xen/interface/xen-compat.h delete mode 100644 include/xen/interface/xen.h delete mode 100644 include/xen/interface/xenoprof.h delete mode 100644 include/xen/pcifront.h delete mode 100644 include/xen/public/evtchn.h delete mode 100644 include/xen/public/privcmd.h delete mode 100644 include/xen/xen_proc.h delete mode 100644 include/xen/xenbus.h delete mode 100644 include/xen/xencons.h delete mode 100644 kernel/audit.h delete mode 100644 kernel/auditfilter.c delete mode 100644 kernel/futex_compat.c delete mode 100644 kernel/irq/migration.c delete mode 100644 kernel/module-verify-sig.c delete mode 100644 kernel/module-verify.c delete mode 100644 kernel/module-verify.h delete mode 100644 kernel/power/swap.c delete mode 100644 kernel/power/user.c delete mode 100644 kernel/relay.c delete mode 100644 lib/cpumask.c delete mode 100644 lib/hweight.c delete mode 100644 mm/migrate.c delete mode 100644 mm/mmzone.c delete mode 100644 net/dccp/ccids/ccid2.c delete mode 100644 net/dccp/ccids/ccid2.h delete mode 100644 net/dccp/feat.c delete mode 100644 net/dccp/feat.h delete mode 100644 net/dccp/sysctl.c create mode 100644 net/ethernet/sysctl_net_ether.c delete mode 100644 net/ieee80211/softmac/Kconfig delete mode 100644 net/ieee80211/softmac/Makefile delete mode 100644 net/ieee80211/softmac/ieee80211softmac_assoc.c delete mode 100644 net/ieee80211/softmac/ieee80211softmac_auth.c delete mode 100644 net/ieee80211/softmac/ieee80211softmac_event.c delete mode 100644 net/ieee80211/softmac/ieee80211softmac_io.c delete mode 100644 net/ieee80211/softmac/ieee80211softmac_module.c delete mode 100644 net/ieee80211/softmac/ieee80211softmac_priv.h delete mode 100644 net/ieee80211/softmac/ieee80211softmac_scan.c delete mode 100644 net/ieee80211/softmac/ieee80211softmac_wx.c delete mode 100644 net/ipv4/netfilter/ip_conntrack_helper_h323.c delete mode 100644 net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c delete mode 100644 net/ipv4/netfilter/ip_conntrack_helper_h323_types.c delete mode 100644 net/ipv4/netfilter/ip_nat_helper_h323.c rename net/{netfilter/xt_esp.c => ipv4/netfilter/ipt_esp.c} (50%) create mode 100644 net/ipv4/netfilter/ipt_multiport.c delete mode 100644 net/ipv4/tunnel4.c create mode 100644 net/ipv6/netfilter/ip6t_esp.c create mode 100644 net/ipv6/netfilter/ip6t_multiport.c delete mode 100644 net/ipv6/tunnel6.c create mode 100644 net/llc/llc_output.h delete mode 100644 net/netfilter/xt_multiport.c delete mode 100644 net/netfilter/xt_policy.c delete mode 100644 net/tux/Kconfig delete mode 100644 net/tux/Makefile delete mode 100644 net/tux/abuf.c delete mode 100644 net/tux/accept.c delete mode 100644 net/tux/cachemiss.c delete mode 100644 net/tux/cgi.c delete mode 100644 net/tux/directory.c delete mode 100644 net/tux/extcgi.c delete mode 100644 net/tux/gzip.c delete mode 100644 net/tux/input.c delete mode 100644 net/tux/logger.c delete mode 100644 net/tux/main.c delete mode 100644 net/tux/mod.c delete mode 100644 net/tux/output.c delete mode 100644 net/tux/parser.h delete mode 100644 net/tux/postpone.c delete mode 100644 net/tux/proc.c delete mode 100644 net/tux/proto_ftp.c delete mode 100644 net/tux/proto_http.c delete mode 100644 net/tux/redirect.c delete mode 100644 net/tux/times.c delete mode 100644 net/tux/times.h delete mode 100644 net/tux/userspace.c delete mode 100644 scripts/Makefile.xen create mode 100755 scripts/checkconfig.pl delete mode 100644 scripts/modsign/Makefile delete mode 100644 scripts/modsign/mod-extract.c delete mode 100644 scripts/modsign/modsign.sh delete mode 100644 scripts/profile2linkerlist.pl create mode 100644 scripts/reference_discarded.pl create mode 100644 scripts/reference_init.pl delete mode 100644 security/selinux/exports.c delete mode 100644 sound/isa/adlib.c delete mode 100644 sound/isa/opti9xx/miro.c delete mode 100644 sound/isa/opti9xx/miro.h delete mode 100644 sound/oss/.gitignore delete mode 100644 sound/pci/als300.c create mode 100644 sound/pci/echoaudio/Makefile create mode 100644 sound/pci/echoaudio/darla20.c create mode 100644 sound/pci/echoaudio/darla20_dsp.c create mode 100644 sound/pci/echoaudio/darla24.c create mode 100644 sound/pci/echoaudio/darla24_dsp.c create mode 100644 sound/pci/echoaudio/echo3g.c create mode 100644 sound/pci/echoaudio/echo3g_dsp.c create mode 100644 sound/pci/echoaudio/echoaudio.c create mode 100644 sound/pci/echoaudio/echoaudio.h create mode 100644 sound/pci/echoaudio/echoaudio_3g.c create mode 100644 sound/pci/echoaudio/echoaudio_dsp.c create mode 100644 sound/pci/echoaudio/echoaudio_dsp.h create mode 100644 sound/pci/echoaudio/echoaudio_gml.c create mode 100644 sound/pci/echoaudio/gina20.c create mode 100644 sound/pci/echoaudio/gina20_dsp.c create mode 100644 sound/pci/echoaudio/gina24.c create mode 100644 sound/pci/echoaudio/gina24_dsp.c create mode 100644 sound/pci/echoaudio/indigo.c create mode 100644 sound/pci/echoaudio/indigo_dsp.c create mode 100644 sound/pci/echoaudio/indigodj.c create mode 100644 sound/pci/echoaudio/indigodj_dsp.c create mode 100644 sound/pci/echoaudio/indigoio.c create mode 100644 sound/pci/echoaudio/indigoio_dsp.c create mode 100644 sound/pci/echoaudio/layla20.c create mode 100644 sound/pci/echoaudio/layla20_dsp.c create mode 100644 sound/pci/echoaudio/layla24.c create mode 100644 sound/pci/echoaudio/layla24_dsp.c create mode 100644 sound/pci/echoaudio/mia.c create mode 100644 sound/pci/echoaudio/mia_dsp.c create mode 100644 sound/pci/echoaudio/midi.c create mode 100644 sound/pci/echoaudio/mona.c create mode 100644 sound/pci/echoaudio/mona_dsp.c delete mode 100644 sound/pci/riptide/Makefile delete mode 100644 sound/pci/riptide/riptide.c diff --git a/.gitignore b/.gitignore index 27fd37621..3f8fb686b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ # # Top-level generic files # -tags vmlinux* System.map Module.symvers @@ -31,5 +30,3 @@ include/linux/autoconf.h include/linux/compile.h include/linux/version.h -# stgit generated dirs -patches-* diff --git a/CREDITS b/CREDITS index 9bf714a1c..1f171f103 100644 --- a/CREDITS +++ b/CREDITS @@ -1127,10 +1127,8 @@ S: Carnegie, Pennsylvania 15106-4304 S: USA N: Philip Gladstone -E: philip@gladstonefamily.net +E: philip@raptor.com D: Kernel / timekeeping stuff -S: Carlisle, MA 01741 -S: USA N: Jan-Benedict Glaw E: jbglaw@lug-owl.de @@ -1194,9 +1192,15 @@ S: Brecksville, OH 44141-1334 S: USA N: Tristan Greaves -E: tristan@extricate.org -W: http://www.extricate.org/ +E: Tristan.Greaves@icl.com +E: tmg296@ecs.soton.ac.uk +W: http://www.ecs.soton.ac.uk/~tmg296 D: Miscellaneous ipv4 sysctl patches +S: 15 Little Mead +S: Denmead +S: Hampshire +S: PO7 6HS +S: United Kingdom N: Michael A. Griffith E: grif@cs.ucr.edu @@ -2003,14 +2007,13 @@ S: University of Stuttgart, Germany and S: Ecole Nationale Superieure des Telecommunications, Paris N: Jamie Lokier -E: jamie@shareable.org -W: http://www.shareable.org/ +E: jamie@imbolc.ucc.ie D: Reboot-through-BIOS for broken 486 motherboards -D: Parport fixes, futex improvements -D: First instruction of x86 sysenter path :) -S: 51 Sunningwell Road +D: Some parport fixes +S: 11 Goodson Walk +S: Marston S: Oxford -S: OX1 4SZ +S: OX3 0HX S: United Kingdom N: Mark Lord @@ -2810,8 +2813,6 @@ E: luca.risolia@studio.unibo.it P: 1024D/FCE635A4 88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4 D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chips D: V4L2 driver for SN9C10x PC Camera Controllers -D: V4L2 driver for ET61X151 and ET61X251 PC Camera Controllers -D: V4L2 driver for ZC0301 Image Processor and Control Chip S: Via Liberta' 41/A S: Osio Sotto, 24046, Bergamo S: Italy @@ -3241,9 +3242,14 @@ S: 12725 SW Millikan Way, Suite 400 S: Beaverton, Oregon 97005 S: USA -N: Marcelo Tosatti -E: marcelo@kvack.org +N: Marcelo W. Tosatti +E: marcelo.tosatti@cyclades.com +D: Miscellaneous kernel hacker D: v2.4 kernel maintainer +D: Current pc300/cyclades maintainer +S: Cyclades Corporation +S: Av Cristovao Colombo, 462. Floresta. +S: Porto Alegre S: Brazil N: Stefan Traby @@ -3371,7 +3377,7 @@ S: Germany N: Geert Uytterhoeven E: geert@linux-m68k.org -W: http://users.telenet.be/geertu/ +W: http://home.tvd.be/cr26864/ P: 1024/862678A6 C51D 361C 0BD1 4C90 B275 C553 6EEA 11BA 8626 78A6 D: m68k/Amiga and PPC/CHRP Longtrail coordinator D: Frame buffer device and XF68_FBDev maintainer @@ -3381,8 +3387,8 @@ D: Amiga Buddha and Catweasel chipset IDE D: Atari Falcon chipset IDE D: Amiga Gayle chipset IDE D: mipsel NEC DDB Vrc-5074 -S: Haterbeekstraat 55B -S: B-3200 Aarschot +S: Emiel Vlieberghlaan 2A/21 +S: B-3010 Kessel-Lo S: Belgium N: Chris Vance @@ -3732,11 +3738,10 @@ D: Mylex DAC960 PCI RAID driver D: Miscellaneous kernel fixes N: Alessandro Zummo -E: a.zummo@towertech.it +E: azummo@ita.flashnet.it +W: http://freepage.logicom.it/azummo/ D: CMI8330 support is sb_card.c D: ISAPnP fixes in sb_card.c -D: ZyXEL omni.net lcd plus driver -D: RTC subsystem S: Italy N: Marc Zyngier diff --git a/Documentation/BUG-HUNTING b/Documentation/BUG-HUNTING index 65b97e1db..ca29242db 100644 --- a/Documentation/BUG-HUNTING +++ b/Documentation/BUG-HUNTING @@ -1,56 +1,3 @@ -Table of contents -================= - -Last updated: 20 December 2005 - -Contents -======== - -- Introduction -- Devices not appearing -- Finding patch that caused a bug --- Finding using git-bisect --- Finding it the old way -- Fixing the bug - -Introduction -============ - -Always try the latest kernel from kernel.org and build from source. If you are -not confident in doing that please report the bug to your distribution vendor -instead of to a kernel developer. - -Finding bugs is not always easy. Have a go though. If you can't find it don't -give up. Report as much as you have found to the relevant maintainer. See -MAINTAINERS for who that is for the subsystem you have worked on. - -Before you submit a bug report read REPORTING-BUGS. - -Devices not appearing -===================== - -Often this is caused by udev. Check that first before blaming it on the -kernel. - -Finding patch that caused a bug -=============================== - - - -Finding using git-bisect ------------------------- - -Using the provided tools with git makes finding bugs easy provided the bug is -reproducible. - -Steps to do it: -- start using git for the kernel source -- read the man page for git-bisect -- have fun - -Finding it the old way ----------------------- - [Sat Mar 2 10:32:33 PST 1996 KERNEL_BUG-HOWTO lm@sgi.com (Larry McVoy)] This is how to track down a bug if you know nothing about kernel hacking. @@ -143,63 +90,3 @@ it does work and it lets non-hackers help fix bugs. And it is cool because Linux snapshots will let you do this - something that you can't do with vendor supplied releases. -Fixing the bug -============== - -Nobody is going to tell you how to fix bugs. Seriously. You need to work it -out. But below are some hints on how to use the tools. - -To debug a kernel, use objdump and look for the hex offset from the crash -output to find the valid line of code/assembler. Without debug symbols, you -will see the assembler code for the routine shown, but if your kernel has -debug symbols the C code will also be available. (Debug symbols can be enabled -in the kernel hacking menu of the menu configuration.) For example: - - objdump -r -S -l --disassemble net/dccp/ipv4.o - -NB.: you need to be at the top level of the kernel tree for this to pick up -your C files. - -If you don't have access to the code you can also debug on some crash dumps -e.g. crash dump output as shown by Dave Miller. - -> EIP is at ip_queue_xmit+0x14/0x4c0 -> ... -> Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00 -> 00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08 -> <8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85 -> -> Put the bytes into a "foo.s" file like this: -> -> .text -> .globl foo -> foo: -> .byte .... /* bytes from Code: part of OOPS dump */ -> -> Compile it with "gcc -c -o foo.o foo.s" then look at the output of -> "objdump --disassemble foo.o". -> -> Output: -> -> ip_queue_xmit: -> push %ebp -> push %edi -> push %esi -> push %ebx -> sub $0xbc, %esp -> mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb) -> mov 0x8(%ebp), %ebx ! %ebx = skb->sk -> mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt - -Another very useful option of the Kernel Hacking section in menuconfig is -Debug memory allocations. This will help you see whether data has been -initialised and not set before use etc. To see the values that get assigned -with this look at mm/slab.c and search for POISON_INUSE. When using this an -Oops will often show the poisoned data instead of zero which is the default. - -Once you have worked out a fix please submit it upstream. After all open -source is about sharing what you do and don't you want to be recognised for -your genius? - -Please do read Documentation/SubmittingPatches though to help your code get -accepted. diff --git a/Documentation/COPYING.modules b/Documentation/COPYING.modules deleted file mode 100644 index da0266e78..000000000 --- a/Documentation/COPYING.modules +++ /dev/null @@ -1,708 +0,0 @@ -Date: Thu, 29 Apr 2004 14:10:41 -0700 (PDT) -From: Linus Torvalds -To: Giuliano Colla -cc: Linux Kernel Mailing List -Subject: Re: [hsflinux] [PATCH] Blacklist binary-only modules lying about - their license -Message-ID: - -On Thu, 29 Apr 2004, Giuliano Colla wrote: -> -> Let's try not to be ridiculous, please. - -It's not abotu being ridiculous. It's about honoring peoples copyrights. - -> As an end user, if I buy a full fledged modem, I get some amount of -> proprietary, non GPL, code which executes within the board or the -> PCMCIA card of the modem. The GPL driver may even support the -> functionality of downloading a new version of *proprietary* code into -> the flash Eprom of the device. The GPL linux driver interfaces with it, -> and all is kosher. - -Indeed. Everything is kosher, because the other piece of hardware and -software has _nothing_ to do with the kernel. It's not linked into it, it -cannot reasonably corrupt internal kernel data structures with random -pointer bugs, and in general you can think of firmware as part of the -_hardware_, not the software of the machine. - -> On the other hand, I have the misfortune of being stuck with a -> soft-modem, roughly the *same* proprietary code is provided as a binary -> file, and a linux driver (source provided) interfaces with it. In that -> case the kernel is flagged as "tainted". - -It is flagged as tainted, because your argument that it is "the same code" -is totally BOGUS AND UNTRUE! - -In the binary kernel module case, a bug in the code corrupts random data -structures, or accesses kernel internals without holding the proper locks, -or does a million other things wrong, BECAUSE A KERNEL MODULE IS VERY -INTIMATELY LINKED WITH THE KERNEL. - -A kernel module is _not_ a separate work, and can in _no_ way be seen as -"part of the hardware". It's very much a part of the _kernel_. And the -kernel developers require that such code be GPL'd so that it can be fixed, -or if there's a valid argument that it's not a derived work and not GPL'd, -then the kernel developers who have to support the end result mess most -definitely do need to know about the taint. - -You are not the first (and sadly, you likely won't be the last) person to -equate binary kernel modules with binary firmware. And I tell you that -such a comparison is ABSOLUTE CRAPOLA. There's a damn big difference -between running firmware on another chip behind a PCI bus, and linking -into the kernel directly. - -And if you don't see that difference, then you are either terminally -stupid, or you have some ulterior reason to claim that they are the same -case even though they clearly are NOT. - -> Can you honestly tell apart the two cases, if you don't make a it a case -> of "religion war"? - -It has absolutely nothing to do with religion. - - Linus - -Date: Fri, 5 Dec 2003 09:19:52 -0800 (PST) -From: Linus Torvalds -To: Peter Chubb -cc: linux-kernel@vger.kernel.org -Subject: Re: Linux GPL and binary module exception clause? -Message-ID: - -On Fri, 5 Dec 2003, Peter Chubb wrote: -> -> As I understand it, SCO is/was claiming that JFS and XFS are derived -> works of the UNIX source base, because they were developed to match -> the internal interfaces of UNIX, and with knowledge of the internals -> of UNIX -- and they hold the copyrights of and are the licensor of UNIX. - -Yes, and I'm not claiming anything like that. - -I claim that a "binary linux kernel module" is a derived work of the -kernel, and thus has to come with sources. - -But if you use those same sources (and _you_ wrote them) they do not -contain any Linux code, they are _clearly_ not derived from Linux, and you -can license and use your own code any way you want. - -You just can't make a binary module for Linux, and claim that that module -isn't derived from the kernel. Because it generally is - the binary -module not only included header files, but more importantly it clearly is -_not_ a standalone work any more. So even if you made your own prototypes -and tried hard to avoid kernel headers, it would _still_ be connected and -dependent on the kernel. - -And note that I'm very much talking about just the _binary_. Your source -code is still very much yours, and you have the right to distribute it -separately any which way you want. You wrote it, you own the copyrights to -it, and it is an independent work. - -But when you distribute it in a way that is CLEARLY tied to the GPL'd -kernel (and a binary module is just one such clear tie - a "patch" to -build it or otherwise tie it to the kernel is also such a tie, even if you -distribute it as source under some other license), you're BY DEFINITION -not an independent work any more. - -(But exactly because I'm not a black-and-white person, I reserve the right -to make a balanced decision on any particular case. I have several times -felt that the module author had a perfectly valid argument for why the -"default assumption" of being derived wasn't the case. That's why things -like the AFS module were accepted - but not liked - in the first place). - -This is why SCO's arguments are specious. IBM wrote their code, retained -their copyrights to their code AND THEY SEVERED THE CONNECTION TO SCO'S -CODE (and, arguably the connections didn't even exist in the first place, -since apparently things like JFS were written for OS/2 as well, and the -Linux port was based on that one - but that's a separate argument and -independent of my point). - -See the definition of "derivative" in USC 17.1.101: - - A "derivative work" is a work based upon one or more preexisting - works, such as a translation, musical arrangement, dramatization, - fictionalization, motion picture version, sound recording, art - reproduction, abridgment, condensation, or any other form in which - a work may be recast, transformed, or adapted. A work consisting - of editorial revisions, annotations, elaborations, or other - modifications which, as a whole, represent an original work of - authorship, is a "derivative work". - -And a binary module is an "elaboration" on the kernel. Sorry, but that is -how it IS. - -In short: your code is yours. The code you write is automatically -copyrighted by YOU, and as such you have the right to license and use it -any way you want (well, modulo _other_ laws, of course - in the US your -license can't be racist, for example, but that has nothing to do with -copyright laws, and would fall under a totally different legal framework). - -But when you use that code to create an "elaboration" to the kernel, that -makes it a derived work, and you cannot distribute it except as laid out -by the GPL. A binary module is one such case, but even just a source patch -is _also_ one such case. The lines you added are yours, but when you -distribute it as an elaboration, you are bound by the restriction on -derivative works. - -Or you had better have some other strong argument why it isn't. Which has -been my point all along. - - Linus - - -Date: Wed, 10 Dec 2003 09:10:18 -0800 (PST) -From: Linus Torvalds -To: Larry McVoy -Subject: Re: Linux GPL and binary module exception clause? - -On Wed, 10 Dec 2003, Larry McVoy wrote: -> -> Which is? How is it that you can spend a page of text saying a judge doesn't -> care about technicalities and then base the rest of your argument on the -> distinction between a "plugin" and a "kernel module"? - -I'll stop arguing, since you obviously do not get it. - -I explained the technicalities to _you_, and you are a technical person. - -But if you want to explain something to a judge, you get a real lawyer, -and you make sure that the lawyer tries to explain the issue in _non_ -technical terms. Because, quite frankly, the judge is not going to buy a -technical discussion he or she doesn't understand. - -Just as an example, how do you explain to a judge how much code the Linux -kernel contains? Do you say "it's 6 million lines of C code and header -files and documentation, for a total of about 175MB of data"? - -Yeah, maybe you'd _mention_ that, but to actually _illustrate_ the point -you'd say that if you printed it out, it would be a solid stack of papers -100 feet high. And you'd compare it to the height of the court building -you're in, or something. Maybe you'd print out _one_ file, bind it as a -book, and wave it around as one out of 15,000 files. - -But when _you_ ask me about how big the kernel is, I'd say "5 million -lines". See the difference? It would be silly for me to tell you how many -feet of paper the kernel would print out to, because we don't have those -kinds of associations. - -Similarly, if you want to explain the notion of a kernel module, you'd -compare it to maybe an extra chapter in a book. You'd make an analogy to -something that never _ever_ mentions "linking". - -Just imagine: distributing a compiled binary-only kernel module that can -be loaded into the kernel is not like distributing a new book: it's more -like distributing a extra chapter to a book that somebody else wrote, that -uses all the same characters and the plot, but more importantly it -literally can only be read _together_ with the original work. It doesn't -stand alone. - -In short, your honour, this extra chapter without any meaning on its own -is a derived work of the book. - -In contrast, maybe you can re-write your code and distribute it as a -short-story, which can be run on its own, and maybe the author has been -influenced by another book, but the short-story could be bound AS IS, and -a recipient would find it useful even without that other book. In that -case, the short story is not a derived work - it's only inspired. - -Notice? This is actually _exactly_ what I've been arguing all along, -except I've been arguing with a technical audience, so I've been using -technical examples and terminology. But my argument is that just the fact -that somebody compiled the code for Linux into a binary module that is -useless without a particular version of the kernel DOES MAKE IT A DERIVED -WORK. - -But also note how it's only the BINARY MODULE that is a derived work. Your -source code is _not_ necessarily a derived work, and if you compile it for -another operating system, I'd clearly not complain. - -This is the "stand-alone short story" vs "extra chapter without meaning -outside the book" argument. See? One is a work in its own right, the other -isn't. - - Linus - - -Please read the FAQ at http://www.tux.org/lkml/ -Date: Thu, 4 Dec 2003 22:43:42 -0800 (PST) -From: Linus Torvalds -To: David Schwartz -cc: linux-kernel@vger.kernel.org -Subject: RE: Linux GPL and binary module exception clause? - -On Thu, 4 Dec 2003, David Schwartz wrote: -> -> Yes, but they will cite the prohibition against *creating* derived -> works. - -So? - -The same prohibition exists with the GPL. You are not allowed to create -and distribute a derived work unless it is GPL'd. - -I don't see what you are arguing against. It is very clear: a kernel -module is a derived work of the kernel by default. End of story. - -You can then try to prove (through development history etc) that there -would be major reasons why it's not really derived. But your argument -seems to be that _nothing_ is derived, which is clearly totally false, as -you yourself admit when you replace "kernel" with "Harry Potter". - - Linus - -Date: Wed, 3 Dec 2003 16:00:21 -0800 (PST) -From: Linus Torvalds -To: Kendall Bennet -cc: linux-kernel@vger.kernel.org -Subject: Re: Linux GPL and binary module exception clause? - -On Wed, 3 Dec 2003, Kendall Bennett wrote: -> -> I have heard many people reference the fact that the although the Linux -> Kernel is under the GNU GPL license, that the code is licensed with an -> exception clause that says binary loadable modules do not have to be -> under the GPL. - -Nope. No such exception exists. - -There's a clarification that user-space programs that use the standard -system call interfaces aren't considered derived works, but even that -isn't an "exception" - it's just a statement of a border of what is -clearly considered a "derived work". User programs are _clearly_ not -derived works of the kernel, and as such whatever the kernel license is -just doesn't matter. - -And in fact, when it comes to modules, the GPL issue is exactly the same. -The kernel _is_ GPL. No ifs, buts and maybe's about it. As a result, -anything that is a derived work has to be GPL'd. It's that simple. - -Now, the "derived work" issue in copyright law is the only thing that -leads to any gray areas. There are areas that are not gray at all: user -space is clearly not a derived work, while kernel patches clearly _are_ -derived works. - -But one gray area in particular is something like a driver that was -originally written for another operating system (ie clearly not a derived -work of Linux in origin). At exactly what point does it become a derived -work of the kernel (and thus fall under the GPL)? - -THAT is a gray area, and _that_ is the area where I personally believe -that some modules may be considered to not be derived works simply because -they weren't designed for Linux and don't depend on any special Linux -behaviour. - -Basically: - - anything that was written with Linux in mind (whether it then _also_ - works on other operating systems or not) is clearly partially a derived - work. - - anything that has knowledge of and plays with fundamental internal - Linux behaviour is clearly a derived work. If you need to muck around - with core code, you're derived, no question about it. - -Historically, there's been things like the original Andrew filesystem -module: a standard filesystem that really wasn't written for Linux in the -first place, and just implements a UNIX filesystem. Is that derived just -because it got ported to Linux that had a reasonably similar VFS interface -to what other UNIXes did? Personally, I didn't feel that I could make that -judgment call. Maybe it was, maybe it wasn't, but it clearly is a gray -area. - -Personally, I think that case wasn't a derived work, and I was willing to -tell the AFS guys so. - -Does that mean that any kernel module is automatically not a derived work? -HELL NO! It has nothing to do with modules per se, except that non-modules -clearly are derived works (if they are so central to the kenrel that you -can't load them as a module, they are clearly derived works just by virtue -of being very intimate - and because the GPL expressly mentions linking). - -So being a module is not a sign of not being a derived work. It's just -one sign that _maybe_ it might have other arguments for why it isn't -derived. - - Linus - - -Date: Wed, 3 Dec 2003 16:23:33 -0800 (PST) -From: Linus Torvalds -To: Kendall Bennett -cc: linux-kernel@vger.kernel.org -Subject: Re: Linux GPL and binary module exception clause? - - -On Wed, 3 Dec 2003, Linus Torvalds wrote: -> -> So being a module is not a sign of not being a derived work. It's just -> one sign that _maybe_ it might have other arguments for why it isn't -> derived. - -Side note: historically, the Linux kernel module interfaces were really -quite weak, and only exported a few tens of entry-points, and really -mostly effectively only allowed character and block device drivers with -standard interfaces, and loadable filesystems. - -So historically, the fact that you could load a module using nothing but -these standard interfaces tended to be a much stronger argument for not -being very tightly coupled with the kernel. - -That has changed, and the kernel module interfaces we have today are MUCH -more extensive than they were back in '95 or so. These days modules are -used for pretty much everything, including stuff that is very much -"internal kernel" stuff and as a result the kind of historic "implied -barrier" part of modules really has weakened, and as a result there is not -avery strong argument for being an independent work from just the fact -that you're a module. - -Similarly, historically there was a much stronger argument for things like -AFS and some of the binary drivers (long forgotten now) for having been -developed totally independently of Linux: they literally were developed -before Linux even existed, by people who had zero knowledge of Linux. That -tends to strengthen the argument that they clearly aren't derived. - -In contrast, these days it would be hard to argue that a new driver or -filesystem was developed without any thought of Linux. I think the NVidia -people can probably reasonably honestly say that the code they ported had -_no_ Linux origin. But quite frankly, I'd be less inclined to believe that -for some other projects out there.. - - Linus - - - - -Date: Thu, 17 Oct 2002 10:08:19 -0700 (PDT) -From: Linus Torvalds -To: Christoph Hellwig -Cc: -Subject: Re: [PATCH] make LSM register functions GPLonly exports -In-Reply-To: <20021017175403.A32516@infradead.org> -Message-ID: - -Note that if this fight ends up being a major issue, I'm just going to -remove LSM and let the security vendors do their own thing. So far - - - I have not seen a lot of actual usage of the hooks - - seen a number of people who still worry that the hooks degrade - performance in critical areas - - the worry that people use it for non-GPL'd modules is apparently real, - considering Crispin's reply. - -I will re-iterate my stance on the GPL and kernel modules: - - There is NOTHING in the kernel license that allows modules to be - non-GPL'd. - - The _only_ thing that allows for non-GPL modules is copyright law, and - in particular the "derived work" issue. A vendor who distributes non-GPL - modules is _not_ protected by the module interface per se, and should - feel very confident that they can show in a court of law that the code - is not derived. - - The module interface has NEVER been documented or meant to be a GPL - barrier. The COPYING clearly states that the system call layer is such a - barrier, so if you do your work in user land you're not in any way - beholden to the GPL. The module interfaces are not system calls: there - are system calls used to _install_ them, but the actual interfaces are - not. - - The original binary-only modules were for things that were pre-existing - works of code, ie drivers and filesystems ported from other operating - systems, which thus could clearly be argued to not be derived works, and - the original limited export table also acted somewhat as a barrier to - show a level of distance. - -In short, Crispin: I'm going to apply the patch, and if you as a copyright -holder of that file disagree, I will simply remove all of he LSM code from -the kernel. I think it's very clear that a LSM module is a derived work, -and thus copyright law and the GPL are not in any way unclear about it. - -If people think they can avoid the GPL by using function pointers, they -are WRONG. And they have always been wrong. - - Linus - ------------------------------------------------------------------------- -Date: Fri, 19 Oct 2001 13:16:45 -0700 (PDT) -From: Linus Torvalds -To: Barnes -Subject: Re: GPL, Richard Stallman, and the Linux kernel - -[ This is not, of course, a legal document, but if you want to forward it - to anybody else, feel free to do so. And if you want to argue legal - points with me or point somehting out, I'm always interested. To a - point ;-] - -On Fri, 19 Oct 2001, Barnes wrote: -> -> I've been exchanging e-mail with Richard Stallman for a couple of -> weeks about the finer points of the GPL. - -I feel your pain. - -> I've have spent time pouring through mailing list archives, usenet, -> and web search engines to find out what's already been covered about -> your statement of allowing dynamically loaded kernel modules with -> proprietary code to co-exist with the Linux kernel. So far I've -> been unable to find anything beyond vague statements attributed to -> you. If these issues are addressed somewhere already, please refer -> me. - -Well, it really boils down to the equivalent of "_all_ derived modules -have to be GPL'd". An external module doesn't really change the GPL in -that respect. - -There are (mainly historical) examples of UNIX device drivers and some -UNIX filesystems that were pre-existing pieces of work, and which had -fairly well-defined and clear interfaces and that I personally could not -really consider any kind of "derived work" at all, and that were thus -acceptable. The clearest example of this is probably the AFS (the Andrew -Filesystem), but there have been various device drivers ported from SCO -too. - -> Issue #1 -> ======== -> Currently the GPL version 2 license is the only license covering the -> Linux kernel. I cannot find any alternative license explaining the -> loadable kernel module exception which makes your position difficult -> to legally analyze. -> -> There is a note at the top of www.kernel.org/pub/linux/kernel/COPYING, -> but that states "user programs" which would clearly not apply to -> kernel modules. -> -> Could you clarify in writing what the exception precisely states? - -Well, there really is no exception. However, copyright law obviously -hinges on the definition of "derived work", and as such anything can -always be argued on that point. - -I personally consider anything a "derived work" that needs special hooks -in the kernel to function with Linux (ie it is _not_ acceptable to make a -small piece of GPL-code as a hook for the larger piece), as that obviously -implies that the bigger module needs "help" from the main kernel. - -Similarly, I consider anything that has intimate knowledge about kernel -internals to be a derived work. - -What is left in the gray area tends to be clearly separate modules: code -that had a life outside Linux from the beginning, and that do something -self-containted that doesn't really have any impact on the rest of the -kernel. A device driver that was originally written for something else, -and that doesn't need any but the standard UNIX read/write kind of -interfaces, for example. - -> Issue #2 -> ======== -> I've found statements attributed to you that you think only 10% of -> the code in the current kernel was written by you. By not being the -> sole copyright holder of the Linux kernel, a stated exception to -> the GPL seems invalid unless all kernel copyright holders agreed on -> this exception. How does the exception cover GPL'd kernel code not -> written by you? Has everyone contributing to the kernel forfeited -> their copyright to you or agreed with the exception? - -Well, see above about the lack of exception, and about the fundamental -gray area in _any_ copyright issue. The "derived work" issue is obviously -a gray area, and I know lawyers don't like them. Crazy people (even -judges) have, as we know, claimed that even obvious spoofs of a work that -contain nothing of the original work itself, can be ruled to be "derived". - -I don't hold views that extreme, but at the same time I do consider a -module written for Linux and using kernel infrastructures to get its work -done, even if not actually copying any existing Linux code, to be a -derived work by default. You'd have to have a strong case to _not_ -consider your code a derived work.. - -> Issue #3 -> ======== -> This issue is related to issue #1. Exactly what is covered by the -> exception? For example, all code shipped with the Linux kernel -> archive and typically installed under /usr/src/linux, all code under -> /usr/src/linux except /usr/src/linux/drivers, or just the code in -> the /usr/src/linux/kernel directory? - -See above, and I think you'll see my point. - -The "user program" exception is not an exception at all, for example, it's -just a more clearly stated limitation on the "derived work" issue. If you -use standard UNIX system calls (with accepted Linux extensions), your -program obviously doesn't "derive" from the kernel itself. - -Whenever you link into the kernel, either directly or through a module, -the case is just a _lot_ more muddy. But as stated, by default it's -obviously derived - the very fact that you _need_ to do something as -fundamental as linking against the kernel very much argues that your -module is not a stand-alone thing, regardless of where the module source -code itself has come from. - -> Issue #4 -> ======== -> This last issue is not so much a issue for the Linux kernel -> exception, but a request for comment. -> -> Richard and I both agree that a "plug-in" and a "dynamically -> loaded kernel module" are effectively the same under the GPL. - -Agreed. - -The Linux kernel modules had (a long time ago), a more limited interface, -and not very many functions were actually exported. So five or six years -ago, we could believably claim that "if you only use these N interfaces -that are exported from the standard kernel, you've kind of implicitly -proven that you do not need the kernel infrastructure". - -That was never really documented either (more of a guideline for me and -others when we looked at the "derived work" issue), and as modules were -more-and-more used not for external stuff, but just for dynamic loading of -standard linux modules that were distributed as part of the kernel anyway, -the "limited interfaces" argument is no longer a very good guideline for -"derived work". - -So these days, we export many internal interfaces, not because we don't -think that they would "taint" the linker, but simply because it's useful -to do dynamic run-time loading of modules even with standard kernel -modules that _are_ supposed to know a lot about kernel internals, and are -obviously "derived works".. - -> However we disagree that a plug-in for a GPL'd program falls -> under the GPL as asserted in the GPL FAQ found in the answer: -> http://www.gnu.org/licenses/gpl-faq.html#GPLAndPlugins. - -I think you really just disagree on what is derived, and what is not. -Richard is very extreme: _anything_ that links is derived, regardless of -what the arguments against it are. I'm less extreme, and I bet you're even -less so (at least you would like to argue so for your company). - -> My assertion is that plug-ins are written to an interface, not a -> program. Since interfaces are not GPL'd, a plug-in cannot be GPL'd -> until the plug-in and program are placed together and run. That is -> done by the end user, not the plug-in creator. - -I agree, but also disrespectfully disagree ;) - -It's an issue of what a "plug-in" is - is it a way for the program to -internally load more modules as it needs them, or is it _meant_ to be a -public, published interface. - -For example, the "system call" interface could be considered a "plug-in -interface", and running a user mode program under Linux could easily be -construed as running a "plug-in" for the Linux kernel. No? - -And there, I obviously absolutely agree with you 100%: the interface is -published, and it's _meant_ for external and independent users. It's an -interface that we go to great lengths to preserve as well as we can, and -it's an interface that is designed to be independent of kernel versions. - -But maybe somebody wrote his program with the intention to dynamically -load "actors" as they were needed, as a way to maintain a good modularity, -and to try to keep the problem spaces well-defined. In that case, the -"plug-in" may technically follow all the same rules as the system call -interface, even though the author doesn't intend it that way. - -So I think it's to a large degree a matter of intent, but it could -arguably also be considered a matter of stability and documentation (ie -"require recompilation of the plug-in between version changes" would tend -to imply that it's an internal interface, while "documented binary -compatibility across many releases" implies a more stable external -interface, and less of a derived work) - -Does that make sense to you? - -> I asked Richard to comment on several scenarios involving plug-ins -> explain whether or not they were in violation of the GPL. So far he -> as only addressed one and has effectively admitted a hole. This is -> the one I asked that he's responded to: -> [A] non-GPL'd plug-in writer writes a plug-in for a non-GPL'd -> program. Another author writes a GPL'd program making the -> first author's plug-ins compatible with his program. Are now -> the plug-in author's plug-ins now retroactively required to be -> GPL'd? -> -> His response: -> No, because the plug-in was not written to extend this program. -> -> I find it suspicious that whether or not the GPL would apply to the -> plug-in depends on the mindset of the author. - -The above makes no sense if you think of it as a "plug in" issue, but it -makes sense if you think of it as a "derived work" issue, along with -taking "intent" into account. - -I know lawyers tend to not like the notion of "intent", because it brings -in another whole range of gray areas, but it's obviously a legal reality. - -Ok, enough blathering from me. I'd just like to finish off with a few -comments, just to clarify my personal stand: - - - I'm obviously not the only copyright holder of Linux, and I did so on - purpose for several reasons. One reason is just because I hate the - paperwork and other cr*p that goes along with copyright assignments. - - Another is that I don't much like copyright assignments at all: the - author is the author, and he may be bound by my requirement for GPL, - but that doesn't mean that he should give his copyright to me. - - A third reason, and the most relevant reason here, is that I want - people to _know_ that I cannot control the sources. I can write you a - note to say that "for use XXX, I do not consider module YYY to be a - derived work of my kernel", but that would not really matter that much. - Any other Linux copyright holder might still sue you. - - This third reason is what makes people who otherwise might not trust me - realize that I cannot screw people over. I am bound by the same - agreement that I require of everybody else, and the only special status - I really have is a totally non-legal issue: people trust me. - - (Yes, I realize that I probably would end up having more legal status - than most, even apart from the fact that I still am the largest single - copyright holder, if only because of appearances) - - - I don't really care about copyright law itself. What I care about is my - own morals. Whether I'd ever sue somebody or not (and quite frankly, - it's the last thing I ever want to do - if I never end up talking to - lawyers in a professional context, I'll be perfectly happy. No - disrespect intended) will be entirely up to whether I consider what - people do to me "moral" or not. Which is why intent matters to me a - lot - both the intent of the person/corporation doign the infringement, - _and_ the intent of me and others in issues like the module export - interface. - - Another way of putting this: I don't care about "legal loopholes" and - word-wrangling. - - - Finally: I don't trust the FSF. I like the GPL a lot - although not - necessarily as a legal piece of paper, but more as an intent. Which - explains why, if you've looked at the Linux COPYING file, you may have - noticed the explicit comment about "only _this_ particular version of - the GPL covers the kernel by default". - - That's because I agree with the GPL as-is, but I do not agree with the - FSF on many other matters. I don't like software patents much, for - example, but I do not want the code I write to be used as a weapon - against companies that have them. The FSF has long been discussing and - is drafting the "next generation" GPL, and they generally suggest that - people using the GPL should say "v2 or at your choice any later - version". - - Linux doesn't do that. The Linux kernel is v2 ONLY, apart from a few - files where the author put in the FSF extension (and see above about - copyright assignments why I would never remove such an extension). - -The "v2 only" issue might change some day, but only after all documented -copyright holders agree on it, and only after we've seen what the FSF -suggests. From what I've seen so far from the FSF drafts, we're not likely -to change our v2-only stance, but there might of course be legal reasons -why we'd have to do something like it (ie somebody challenging the GPLv2 -in court, and part of it to be found unenforceable or similar would -obviously mean that we'd have to reconsider the license). - - Linus - -PS. Historically, binary-only modules have not worked well under Linux, -quite regardless of any copyright issues. The kernel just develops too -quickly for binary modules to work well, and nobody really supports them. -Companies like Red Hat etc tend to refuse to have anything to do with -binary modules, because if something goes wrong there is nothing they can -do about it. So I just wanted to let you know that the _legal_ issue is -just the beginning. Even though you probably don't personally care ;) - - diff --git a/Documentation/Changes b/Documentation/Changes index b02f476c2..fe5ae0f55 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -15,6 +15,24 @@ and therefore owes credit to the same people as that file (Jared Mauch, Axel Boldt, Alessandro Sigala, and countless other users all over the 'net). +The latest revision of this document, in various formats, can always +be found at . + +Feel free to translate this document. If you do so, please send me a +URL to your translation for inclusion in future revisions of this +document. + +Smotrite file , yavlyaushisya +russkim perevodom dannogo documenta. + +Visite para obtener la traducción +al español de este documento en varios formatos. + +Eine deutsche Version dieser Datei finden Sie unter +. + +Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu). + Current Minimal Requirements ============================ diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 2ffb0d62f..1af0f2d50 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -33,9 +33,7 @@ pci_alloc_consistent(struct pci_dev *dev, size_t size, Consistent memory is memory for which a write by either the device or the processor can immediately be read by the processor or device -without having to worry about caching effects. (You may however need -to make sure to flush the processor's write buffers before telling -devices to read that memory.) +without having to worry about caching effects. This routine allocates a region of bytes of consistent memory. it also returns a which may be cast to an unsigned @@ -306,12 +304,12 @@ dma address with dma_mapping_error(). A non zero return value means the mapping could not be created and the driver should take appropriate action (eg reduce current DMA mapping usage or delay and try again later). - int - dma_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) - int - pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction) +int +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction) +int +pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction) Maps a scatter gather list from the block layer. @@ -329,33 +327,12 @@ critical that the driver do something, in the case of a block driver aborting the request or even oopsing is better than doing nothing and corrupting the filesystem. -With scatterlists, you use the resulting mapping like this: - - int i, count = dma_map_sg(dev, sglist, nents, direction); - struct scatterlist *sg; - - for (i = 0, sg = sglist; i < count; i++, sg++) { - hw_address[i] = sg_dma_address(sg); - hw_len[i] = sg_dma_len(sg); - } - -where nents is the number of entries in the sglist. - -The implementation is free to merge several consecutive sglist entries -into one (e.g. with an IOMMU, or if several pages just happen to be -physically contiguous) and returns the actual number of sg entries it -mapped them to. On failure 0, is returned. - -Then you should loop count times (note: this can be less than nents times) -and use sg_dma_address() and sg_dma_len() macros where you previously -accessed sg->address and sg->length as shown above. - - void - dma_unmap_sg(struct device *dev, struct scatterlist *sg, - int nhwentries, enum dma_data_direction direction) - void - pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction) +void +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) +void +pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction) unmap the previously mapped scatter/gather list. All the parameters must be the same as those and passed in to the scatter/gather mapping diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt index 7c7176990..684557474 100644 --- a/Documentation/DMA-mapping.txt +++ b/Documentation/DMA-mapping.txt @@ -58,15 +58,11 @@ translating each of those pages back to a kernel address using something like __va(). [ EDIT: Update this when we integrate Gerd Knorr's generic code which does this. ] -This rule also means that you may use neither kernel image addresses -(items in data/text/bss segments), nor module image addresses, nor -stack addresses for DMA. These could all be mapped somewhere entirely -different than the rest of physical memory. Even if those classes of -memory could physically work with DMA, you'd need to ensure the I/O -buffers were cacheline-aligned. Without that, you'd see cacheline -sharing problems (data corruption) on CPUs with DMA-incoherent caches. -(The CPU could write to one word, DMA would write to a different one -in the same cache line, and one of them could be overwritten.) +This rule also means that you may not use kernel image addresses +(ie. items in the kernel's data/text/bss segment, or your driver's) +nor may you use kernel stack addresses for DMA. Both of these items +might be mapped somewhere entirely different than the rest of physical +memory. Also, this means that you cannot take the return of a kmap() call and DMA to/from that. This is similar to vmalloc(). @@ -198,13 +194,11 @@ document for how to handle this case. 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, 0x00ffffff)) { printk(KERN_WARNING "mydev: 24-bit DMA addressing not available.\n"); goto ignore_this_device; } -[Better use DMA_24BIT_MASK instead of 0x00ffffff. -See linux/include/dma-mapping.h for reference.] When pci_set_dma_mask() is successful, and returns zero, the PCI layer saves away this mask you have provided. The PCI layer will use this @@ -216,7 +210,7 @@ functions (for example a sound card provides playback and record functions) and the various different functions have _different_ DMA addressing limitations, you may wish to probe each mask and only provide the functionality which the machine can handle. It -is important that the last call to pci_set_dma_mask() be for the +is important that the last call to pci_set_dma_mask() be for the most specific mask. Here is pseudo-code showing how this might be done: @@ -288,11 +282,6 @@ There are two types of DMA mappings: in order to get correct behavior on all platforms. - Also, on some platforms your driver may need to flush CPU write - buffers in much the same way as it needs to flush write buffers - found in PCI bridges (such as by reading a register's value - after writing it). - - Streaming DMA mappings which are usually mapped for one DMA transfer, unmapped right after it (unless you use pci_dma_sync_* below) and for which hardware can optimize for sequential accesses. @@ -312,9 +301,6 @@ There are two types of DMA mappings: Neither type of DMA mapping has alignment restrictions that come from PCI, although some devices may have such restrictions. -Also, systems with caches that aren't DMA-coherent will work better -when the underlying buffers don't share cache lines with other data. - Using Consistent DMA mappings. diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 5a2882d27..1c955883c 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -2,14 +2,14 @@ # This makefile is used to generate the kernel documentation, # primarily based on in-line comments in various source files. # See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how -# to document the SRC - and how to read it. +# to ducument the SRC - and how to read it. # To add a new book the only step required is to add the book to the # list of DOCBOOKS. DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml \ - kernel-api.xml journal-api.xml lsm.xml usb.xml \ + sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml ### @@ -28,7 +28,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 BOOKS := $(addprefix $(obj)/,$(DOCBOOKS)) xmldocs: $(BOOKS) @@ -211,9 +211,3 @@ clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) #man put files in man subdir - traverse down subdir- := man/ - - -# 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. - -.PHONY: $(PHONY) diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl index 90ed23df1..6f41f2f5c 100644 --- a/Documentation/DocBook/deviceiobook.tmpl +++ b/Documentation/DocBook/deviceiobook.tmpl @@ -270,6 +270,25 @@ CPU B: spin_unlock_irqrestore(&dev_lock, flags) + + ISA legacy functions + + On older kernels (2.2 and earlier) the ISA bus could be read or + written with these functions and without ioremap being used. This is + no longer true in Linux 2.4. A set of equivalent functions exist for + easy legacy driver porting. The functions available are prefixed + with 'isa_' and are isa_readb, + isa_writeb, isa_readw, + isa_writew, isa_readl, + isa_writel, isa_memcpy_fromio + and isa_memcpy_toio + + + These functions should not be used in new drivers, and will + eventually be going away. + + + diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index ca02e04a9..8c9c6704e 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -322,6 +322,7 @@ X!Earch/i386/kernel/mca.c The Filesystem for Exporting Kernel Objects !Efs/sysfs/file.c +!Efs/sysfs/dir.c !Efs/sysfs/symlink.c !Efs/sysfs/bin.c diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index f869b0392..d260d9208 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -120,27 +120,14 @@ void (*dev_config) (struct ata_port *, struct ata_device *); void (*set_piomode) (struct ata_port *, struct ata_device *); void (*set_dmamode) (struct ata_port *, struct ata_device *); -void (*post_set_mode) (struct ata_port *); -unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned int); +void (*post_set_mode) (struct ata_port *ap); Hooks called prior to the issue of SET FEATURES - XFER MODE - command. The optional ->mode_filter() hook is called when libata - has built a mask of the possible modes. This is passed to the - ->mode_filter() function which should return a mask of valid modes - after filtering those unsuitable due to hardware limits. It is not - valid to use this interface to add modes. - - - dev->pio_mode and dev->dma_mode are guaranteed to be valid when - ->set_piomode() and when ->set_dmamode() is called. The timings for - any other drive sharing the cable will also be valid at this point. - That is the library records the decisions for the modes of each - drive on a channel before it attempts to set any of them. - - - ->post_set_mode() is + command. dev->pio_mode is guaranteed to be valid when + ->set_piomode() is called, and dev->dma_mode is guaranteed to be + valid when ->set_dmamode() is called. ->post_set_mode() is called unconditionally, after the SET FEATURES - XFER MODE command completes successfully. @@ -243,32 +230,6 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); - Private tuning method - -void (*set_mode) (struct ata_port *ap); - - - - By default libata performs drive and controller tuning in - accordance with the ATA timing rules and also applies blacklists - and cable limits. Some controllers need special handling and have - custom tuning rules, typically raid controllers that use ATA - commands but do not actually do drive timing. - - - - - This hook should not be used to replace the standard controller - tuning logic when a controller has quirks. Replacing the default - tuning logic in that case would bypass handling for drive and - bridge quirks that may be important to data reliability. If a - controller needs to filter the mode selection it should use the - mode_filter hook instead. - - - - - Reset ATA bus void (*phy_reset) (struct ata_port *ap); @@ -705,7 +666,7 @@ and other resources, etc. ata_scsi_error() - ata_scsi_error() is the current transportt->eh_strategy_handler() + ata_scsi_error() is the current hostt->eh_strategy_handler() for libata. As discussed above, this will be entered in two cases - timeout and ATAPI error completion. This function calls low level libata driver's eng_timeout() callback, the diff --git a/Documentation/DocBook/sis900.tmpl b/Documentation/DocBook/sis900.tmpl new file mode 100644 index 000000000..6c2cbac93 --- /dev/null +++ b/Documentation/DocBook/sis900.tmpl @@ -0,0 +1,585 @@ + + + + + + + +SiS 900/7016 Fast Ethernet Device Driver + + + +Ollie +Lho + + + +Lei Chun +Chang + + + +Document Revision: 0.3 for SiS900 driver v1.06 & v1.07 +November 16, 2000 + + + 1999 + Silicon Integrated System 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. + + + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + + +This document gives some information on installation and usage of SiS 900/7016 +device driver under Linux. + + + + + + + + + Introduction + + +This document describes the revision 1.06 and 1.07 of SiS 900/7016 Fast Ethernet +device driver under Linux. The driver is developed by Silicon Integrated +System Corp. and distributed freely under the GNU General Public License (GPL). +The driver can be compiled as a loadable module and used under Linux kernel +version 2.2.x. (rev. 1.06) +With minimal changes, the driver can also be used under 2.3.x and 2.4.x kernel +(rev. 1.07), please see +. If you are intended to +use the driver for earlier kernels, you are on your own. + + + +The driver is tested with usual TCP/IP applications including +FTP, Telnet, Netscape etc. and is used constantly by the developers. + + + +Please send all comments/fixes/questions to +Lei-Chun Chang. + + + + + Changes + + +Changes made in Revision 1.07 + + + + +Separation of sis900.c and sis900.h in order to move most +constant definition to sis900.h (many of those constants were +corrected) + + + + + +Clean up PCI detection, the pci-scan from Donald Becker were not used, +just simple pci_find_*. + + + + + +MII detection is modified to support multiple mii transceiver. + + + + + +Bugs in read_eeprom, mdio_* were removed. + + + + + +Lot of sis900 irrelevant comments were removed/changed and +more comments were added to reflect the real situation. + + + + + +Clean up of physical/virtual address space mess in buffer +descriptors. + + + + + +Better transmit/receive error handling. + + + + + +The driver now uses zero-copy single buffer management +scheme to improve performance. + + + + + +Names of variables were changed to be more consistent. + + + + + +Clean up of auo-negotiation and timer code. + + + + + +Automatic detection and change of PHY on the fly. + + + + + +Bug in mac probing fixed. + + + + + +Fix 630E equalier problem by modifying the equalizer workaround rule. + + + + + +Support for ICS1893 10/100 Interated PHYceiver. + + + + + +Support for media select by ifconfig. + + + + + +Added kernel-doc extratable documentation. + + + + + + + + + Tested Environment + + +This driver is developed on the following hardware + + + + + +Intel Celeron 500 with SiS 630 (rev 02) chipset + + + + + +SiS 900 (rev 01) and SiS 7016/7014 Fast Ethernet Card + + + + + +and tested with these software environments + + + + + +Red Hat Linux version 6.2 + + + + + +Linux kernel version 2.4.0 + + + + + +Netscape version 4.6 + + + + + +NcFTP 3.0.0 beta 18 + + + + + +Samba version 2.0.3 + + + + + + + + + + +Files in This Package + + +In the package you can find these files: + + + + + + +sis900.c + + +Driver source file in C + + + + + +sis900.h + + +Header file for sis900.c + + + + + +sis900.sgml + + +DocBook SGML source of the document + + + + + +sis900.txt + + +Driver document in plain text + + + + + + + + + + Installation + + +Silicon Integrated System Corp. is cooperating closely with core Linux Kernel +developers. The revisions of SiS 900 driver are distributed by the usuall channels +for kernel tar files and patches. Those kernel tar files for official kernel and +patches for kernel pre-release can be download at +official kernel ftp site +and its mirrors. +The 1.06 revision can be found in kernel version later than 2.3.15 and pre-2.2.14, +and 1.07 revision can be found in kernel version 2.4.0. +If you have no prior experience in networking under Linux, please read +Ethernet HOWTO and +Networking HOWTO available from +Linux Documentation Project (LDP). + + + +The driver is bundled in release later than 2.2.11 and 2.3.15 so this +is the most easy case. +Be sure you have the appropriate packages for compiling kernel source. +Those packages are listed in Document/Changes in kernel source +distribution. If you have to install the driver other than those bundled +in kernel release, you should have your driver file +sis900.c and sis900.h +copied into /usr/src/linux/drivers/net/ first. +There are two alternative ways to install the driver + + + +Building the driver as loadable module + + +To build the driver as a loadable kernel module you have to reconfigure +the kernel to activate network support by + + + +make menuconfig + + + +Choose Loadable module support --->, +then select Enable loadable module support. + + + +Choose Network Device Support --->, select +Ethernet (10 or 100Mbit). +Then select EISA, VLB, PCI and on board controllers, +and choose SiS 900/7016 PCI Fast Ethernet Adapter support +to M. + + + +After reconfiguring the kernel, you can make the driver module by + + + +make modules + + + +The driver should be compiled with no errors. After compiling the driver, +the driver can be installed to proper place by + + + +make modules_install + + + +Load the driver into kernel by + + + +insmod sis900 + + + +When loading the driver into memory, some information message can be view by + + + + +dmesg + + +or + + +cat /var/log/message + + + + +If the driver is loaded properly you will have messages similar to this: + + + +sis900.c: v1.07.06 11/07/2000 +eth0: SiS 900 PCI Fast Ethernet at 0xd000, IRQ 10, 00:00:e8:83:7f:a4. +eth0: SiS 900 Internal MII PHY transceiver found at address 1. +eth0: Using SiS 900 Internal MII PHY as default + + + +showing the version of the driver and the results of probing routine. + + + +Once the driver is loaded, network can be brought up by + + + +/sbin/ifconfig eth0 IPADDR broadcast BROADCAST netmask NETMASK media TYPE + + + +where IPADDR, BROADCAST, NETMASK are your IP address, broadcast address and +netmask respectively. TYPE is used to set medium type used by the device. +Typical values are "10baseT"(twisted-pair 10Mbps Ethernet) or "100baseT" +(twisted-pair 100Mbps Ethernet). For more information on how to configure +network interface, please refer to +Networking HOWTO. + + + +The link status is also shown by kernel messages. For example, after the +network interface is activated, you may have the message: + + + +eth0: Media Link On 100mbps full-duplex + + + +If you try to unplug the twist pair (TP) cable you will get + + + +eth0: Media Link Off + + + +indicating that the link is failed. + + + + +Building the driver into kernel + + +If you want to make the driver into kernel, choose Y +rather than M on +SiS 900/7016 PCI Fast Ethernet Adapter support +when configuring the kernel. Build the kernel image in the usual way + + + +make clean + +make bzlilo + + + +Next time the system reboot, you have the driver in memory. + + + + + + + Known Problems and Bugs + + +There are some known problems and bugs. If you find any other bugs please +mail to lcchang@sis.com.tw + + + + + +AM79C901 HomePNA PHY is not thoroughly tested, there may be some +bugs in the on the fly change of transceiver. + + + + + +A bug is hidden somewhere in the receive buffer management code, +the bug causes NULL pointer reference in the kernel. This fault is +caught before bad things happen and reported with the message: + + +eth0: NULL pointer encountered in Rx ring, skipping + + +which can be viewed with dmesg or +cat /var/log/message. + + + + + +The media type change from 10Mbps to 100Mbps twisted-pair ethernet +by ifconfig causes the media link down. + + + + + + + + + Revision History + + + + + + +November 13, 2000, Revision 1.07, seventh release, 630E problem fixed +and further clean up. + + + + + +November 4, 1999, Revision 1.06, Second release, lots of clean up +and optimization. + + + + + +August 8, 1999, Revision 1.05, Initial Public Release + + + + + + + + + Acknowledgements + + +This driver was originally derived form +Donald Becker's +pci-skeleton and +rtl8139 drivers. Donald also provided various suggestion +regarded with improvements made in revision 1.06. + + + +The 1.05 revision was created by +Jim Huang, AMD 79c901 +support was added by Chin-Shan Li. + + + + +List of Functions +!Idrivers/net/sis900.c + + + diff --git a/Documentation/HOWTO b/Documentation/HOWTO index 915ae8c98..6c9e74626 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -603,8 +603,7 @@ start exactly where you are now. ---------- -Thanks to Paolo Ciarrocchi who allowed the "Development Process" -(http://linux.tar.bz/articles/2.6-development_process) section +Thanks to Paolo Ciarrocchi who allowed the "Development Process" section to be based on text he had written, and to Randy Dunlap and Gerrit Huizenga for some of the list of things you should and should not say. Also thanks to Pat Mochel, Hanna Linder, Randy Dunlap, Kay Sievers, diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 07cb93b82..5ed85af88 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -360,7 +360,7 @@ uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.txt. struct foo *new_fp; struct foo *old_fp; - new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL); + new_fp = kmalloc(sizeof(*fp), GFP_KERNEL); spin_lock(&foo_mutex); old_fp = gbl_foo; *new_fp = *old_fp; @@ -461,7 +461,7 @@ The foo_update_a() function might then be written as follows: struct foo *new_fp; struct foo *old_fp; - new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL); + new_fp = kmalloc(sizeof(*fp), GFP_KERNEL); spin_lock(&foo_mutex); old_fp = gbl_foo; *new_fp = *old_fp; @@ -605,7 +605,7 @@ are the same as those shown in the preceding section, so they are omitted. { int cpu; - for_each_possible_cpu(cpu) + for_each_cpu(cpu) run_on(cpu); } diff --git a/Documentation/acpi-hotkey.txt b/Documentation/acpi-hotkey.txt index 38040fa37..744f1aec6 100644 --- a/Documentation/acpi-hotkey.txt +++ b/Documentation/acpi-hotkey.txt @@ -30,7 +30,7 @@ specific hotkey(event)) echo "event_num:event_type:event_argument" > /proc/acpi/hotkey/action. The result of the execution of this aml method is -attached to /proc/acpi/hotkey/poll_method, which is dynamically +attached to /proc/acpi/hotkey/poll_method, which is dnyamically created. Please use command "cat /proc/acpi/hotkey/polling_method" to retrieve it. diff --git a/Documentation/arm/Booting b/Documentation/arm/Booting index 76850295a..fad566bb0 100644 --- a/Documentation/arm/Booting +++ b/Documentation/arm/Booting @@ -118,7 +118,7 @@ to store page tables. The recommended placement is 32KiB into RAM. In either case, the following conditions must be met: -- Quiesce all DMA capable devices so that memory does not get +- Quiesce all DMA capable devicess so that memory does not get corrupted by bogus network packets or disk data. This will save you many hours of debug. diff --git a/Documentation/arm/README b/Documentation/arm/README index 9b9c8226f..5ed6f3530 100644 --- a/Documentation/arm/README +++ b/Documentation/arm/README @@ -89,7 +89,7 @@ Modules Although modularisation is supported (and required for the FP emulator), each module on an ARM2/ARM250/ARM3 machine when is loaded will take memory up to the next 32k boundary due to the size of the pages. - Therefore, is modularisation on these machines really worth it? + Therefore, modularisation on these machines really worth it? However, ARM6 and up machines allow modules to take multiples of 4k, and as such Acorn RiscPCs and other architectures using these processors can diff --git a/Documentation/arm/SA1100/Assabet b/Documentation/arm/SA1100/Assabet index 78bc1c1b0..cbbe5587c 100644 --- a/Documentation/arm/SA1100/Assabet +++ b/Documentation/arm/SA1100/Assabet @@ -26,7 +26,7 @@ Installing a bootloader A couple of bootloaders able to boot Linux on Assabet are available: -BLOB (http://www.lartmaker.nl/lartware/blob/) +BLOB (http://www.lart.tudelft.nl/lartware/blob/) BLOB is a bootloader used within the LART project. Some contributed patches were merged into BLOB to add support for Assabet. diff --git a/Documentation/arm/SA1100/LART b/Documentation/arm/SA1100/LART index 6d412b685..2f73f513e 100644 --- a/Documentation/arm/SA1100/LART +++ b/Documentation/arm/SA1100/LART @@ -11,4 +11,4 @@ is under development, with plenty of others in different stages of planning. The hardware designs for this board have been released under an open license; -see the LART page at http://www.lartmaker.nl/ for more information. +see the LART page at http://www.lart.tudelft.nl/ for more information. diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt index 8c6ee6841..89aa89d52 100644 --- a/Documentation/arm/Samsung-S3C24XX/Overview.txt +++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt @@ -10,8 +10,6 @@ Introduction by the 's3c2410' architecture of ARM Linux. Currently the S3C2410 and the S3C2440 are supported CPUs. - Support for the S3C2400 series is in progress. - Configuration ------------- @@ -34,11 +32,6 @@ Machines A general purpose development board, see EB2410ITX.txt for further details - Simtec Electronics IM2440D20 (Osiris) - - CPU Module from Simtec Electronics, with a S3C2440A CPU, nand flash - and a PCMCIA controller. - Samsung SMDK2410 Samsung's own development board, geared for PDA work. @@ -92,26 +85,6 @@ Adding New Machines mailing list information. -I2C ---- - - The hardware I2C core in the CPU is supported in single master - mode, and can be configured via platform data. - - -RTC ---- - - Support for the onboard RTC unit, including alarm function. - - -Watchdog --------- - - The onchip watchdog is available via the standard watchdog - interface. - - NAND ---- @@ -148,15 +121,6 @@ Clock Management various clock units -Suspend to RAM --------------- - - For boards that provide support for suspend to RAM, the - system can be placed into low power suspend. - - See Suspend.txt for more information. - - Platform Data ------------- @@ -194,7 +158,6 @@ Platform Data exported outside arch/arm/mach-s3c2410/, or exported to modules via EXPORT_SYMBOL() and related functions. - Port Contributors ----------------- @@ -225,11 +188,8 @@ Document Changes 08 Mar 2005 - BJD - Added LCVR to list of people, updated introduction 08 Mar 2005 - BJD - Added section on adding machines 09 Sep 2005 - BJD - Added section on platform data - 11 Feb 2006 - BJD - Added I2C, RTC and Watchdog sections - 11 Feb 2006 - BJD - Added Osiris machine, and S3C2400 information - Document Author --------------- -Ben Dooks, (c) 2004-2005,2006 Simtec Electronics +Ben Dooks, (c) 2004-2005 Simtec Electronics diff --git a/Documentation/arm/Setup b/Documentation/arm/Setup index 0cb1e64bd..0abd0720d 100644 --- a/Documentation/arm/Setup +++ b/Documentation/arm/Setup @@ -58,7 +58,7 @@ below: video_y This describes the character position of cursor on VGA console, and - is otherwise unused. (should not be used for other console types, and + is otherwise unused. (should not used for other console types, and should not be used for other purposes). memc_control_reg diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt index f989a9e83..8e6383197 100644 --- a/Documentation/block/biodoc.txt +++ b/Documentation/block/biodoc.txt @@ -132,18 +132,8 @@ Some new queue property settings: limit. No highmem default. blk_queue_max_sectors(q, max_sectors) - Sets two variables that limit the size of the request. - - - The request queue's max_sectors, which is a soft size in - in units of 512 byte sectors, and could be dynamically varied - by the core kernel. - - - The request queue's max_hw_sectors, which is a hard limit - and reflects the maximum size request a driver can handle - in units of 512 byte sectors. - - The default for both max_sectors and max_hw_sectors is - 255. The upper limit of max_sectors is 1024. + Maximum size request you can handle in units of 512 byte + sectors. 255 default. blk_queue_max_phys_segments(q, max_segments) Maximum physical segments you can handle in a request. 128 diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt deleted file mode 100644 index 5fa130a67..000000000 --- a/Documentation/block/switching-sched.txt +++ /dev/null @@ -1,22 +0,0 @@ -As of the Linux 2.6.10 kernel, it is now possible to change the -IO scheduler for a given block device on the fly (thus making it possible, -for instance, to set the CFQ scheduler for the system default, but -set a specific device to use the anticipatory or noop schedulers - which -can improve that device's throughput). - -To set a specific scheduler, simply do this: - -echo SCHEDNAME > /sys/block/DEV/queue/scheduler - -where SCHEDNAME is the name of a defined IO scheduler, and DEV is the -device name (hda, hdb, sga, or whatever you happen to have). - -The list of defined schedulers can be found by simply doing -a "cat /sys/block/DEV/queue/scheduler" - the list of valid names -will be displayed, with the currently selected scheduler in brackets: - -# cat /sys/block/hda/queue/scheduler -noop anticipatory deadline [cfq] -# echo anticipatory > /sys/block/hda/queue/scheduler -# cat /sys/block/hda/queue/scheduler -noop [anticipatory] deadline cfq diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt index 53245c429..4ae418889 100644 --- a/Documentation/cachetlb.txt +++ b/Documentation/cachetlb.txt @@ -362,27 +362,6 @@ maps this page at its virtual address. likely that you will need to flush the instruction cache for copy_to_user_page(). - void flush_anon_page(struct page *page, unsigned long vmaddr) - When the kernel needs to access the contents of an anonymous - page, it calls this function (currently only - get_user_pages()). Note: flush_dcache_page() deliberately - doesn't work for an anonymous page. The default - implementation is a nop (and should remain so for all coherent - architectures). For incoherent architectures, it should flush - the cache of the page at vmaddr in the current user process. - - void flush_kernel_dcache_page(struct page *page) - When the kernel needs to modify a user page is has obtained - with kmap, it calls this function after all modifications are - complete (but before kunmapping it) to bring the underlying - page up to date. It is assumed here that the user has no - incoherent cached copies (i.e. the original page was obtained - from a mechanism like get_user_pages()). The default - implementation is a nop and should remain so on all coherent - architectures. On incoherent architectures, this should flush - the kernel cache for page (using page_address(page)). - - void flush_icache_range(unsigned long start, unsigned long end) When the kernel stores into addresses that it will execute out of (eg when loading modules), this function is called. diff --git a/Documentation/connector/connector.txt b/Documentation/connector/connector.txt index ad6e0ba7b..57a314b14 100644 --- a/Documentation/connector/connector.txt +++ b/Documentation/connector/connector.txt @@ -69,11 +69,10 @@ Unregisters new callback with connector core. struct cb_id *id - unique connector's user identifier. -int cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask); +void cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask); Sends message to the specified groups. It can be safely called from -softirq context, but may silently fail under strong memory pressure. -If there are no listeners for given group -ESRCH can be returned. +any context, but may silently fail under strong memory pressure. struct cn_msg * - message header(with attached data). u32 __group - destination group. diff --git a/Documentation/cpu-freq/index.txt b/Documentation/cpu-freq/index.txt index ffdb5323d..5009805f9 100644 --- a/Documentation/cpu-freq/index.txt +++ b/Documentation/cpu-freq/index.txt @@ -53,4 +53,4 @@ the CPUFreq Mailing list: * http://lists.linux.org.uk/mailman/listinfo/cpufreq Clock and voltage scaling for the SA-1100: -* http://www.lartmaker.nl/projects/scaling +* http://www.lart.tudelft.nl/projects/scaling diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 1bcf69996..57a09f99e 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -97,13 +97,13 @@ at which time hotplug is disabled. You really dont need to manipulate any of the system cpu maps. They should be read-only for most use. When setting up per-cpu resources almost always use -cpu_possible_map/for_each_possible_cpu() to iterate. +cpu_possible_map/for_each_cpu() to iterate. Never use anything other than cpumask_t to represent bitmap of CPUs. #include -for_each_possible_cpu - Iterate over cpu_possible_map +for_each_cpu - Iterate over cpu_possible_map for_each_online_cpu - Iterate over cpu_online_map for_each_present_cpu - Iterate over cpu_present_map for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask. diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt index 159e2a0c3..30c414599 100644 --- a/Documentation/cpusets.txt +++ b/Documentation/cpusets.txt @@ -18,8 +18,7 @@ CONTENTS: 1.4 What are exclusive cpusets ? 1.5 What does notify_on_release do ? 1.6 What is memory_pressure ? - 1.7 What is memory spread ? - 1.8 How do I use cpusets ? + 1.7 How do I use cpusets ? 2. Usage Examples and Syntax 2.1 Basic Usage 2.2 Adding/removing cpus @@ -318,78 +317,7 @@ the tasks in the cpuset, in units of reclaims attempted per second, times 1000. -1.7 What is memory spread ? ---------------------------- -There are two boolean flag files per cpuset that control where the -kernel allocates pages for the file system buffers and related in -kernel data structures. They are called 'memory_spread_page' and -'memory_spread_slab'. - -If the per-cpuset boolean flag file 'memory_spread_page' is set, then -the kernel will spread the file system buffers (page cache) evenly -over all the nodes that the faulting task is allowed to use, instead -of preferring to put those pages on the node where the task is running. - -If the per-cpuset boolean flag file 'memory_spread_slab' is set, -then the kernel will spread some file system related slab caches, -such as for inodes and dentries evenly over all the nodes that the -faulting task is allowed to use, instead of preferring to put those -pages on the node where the task is running. - -The setting of these flags does not affect anonymous data segment or -stack segment pages of a task. - -By default, both kinds of memory spreading are off, and memory -pages are allocated on the node local to where the task is running, -except perhaps as modified by the tasks NUMA mempolicy or cpuset -configuration, so long as sufficient free memory pages are available. - -When new cpusets are created, they inherit the memory spread settings -of their parent. - -Setting memory spreading causes allocations for the affected page -or slab caches to ignore the tasks NUMA mempolicy and be spread -instead. Tasks using mbind() or set_mempolicy() calls to set NUMA -mempolicies will not notice any change in these calls as a result of -their containing tasks memory spread settings. If memory spreading -is turned off, then the currently specified NUMA mempolicy once again -applies to memory page allocations. - -Both 'memory_spread_page' and 'memory_spread_slab' are boolean flag -files. By default they contain "0", meaning that the feature is off -for that cpuset. If a "1" is written to that file, then that turns -the named feature on. - -The implementation is simple. - -Setting the flag 'memory_spread_page' turns on a per-process flag -PF_SPREAD_PAGE for each task that is in that cpuset or subsequently -joins that cpuset. The page allocation calls for the page cache -is modified to perform an inline check for this PF_SPREAD_PAGE task -flag, and if set, a call to a new routine cpuset_mem_spread_node() -returns the node to prefer for the allocation. - -Similarly, setting 'memory_spread_cache' turns on the flag -PF_SPREAD_SLAB, and appropriately marked slab caches will allocate -pages from the node returned by cpuset_mem_spread_node(). - -The cpuset_mem_spread_node() routine is also simple. It uses the -value of a per-task rotor cpuset_mem_spread_rotor to select the next -node in the current tasks mems_allowed to prefer for the allocation. - -This memory placement policy is also known (in other contexts) as -round-robin or interleave. - -This policy can provide substantial improvements for jobs that need -to place thread local data on the corresponding node, but that need -to access large file system data sets that need to be spread across -the several nodes in the jobs cpuset in order to fit. Without this -policy, especially for jobs that might have one thread reading in the -data set, the memory allocation across the nodes in the jobs cpuset -can become very uneven. - - -1.8 How do I use cpusets ? +1.7 How do I use cpusets ? -------------------------- In order to minimize the impact of cpusets on critical kernel diff --git a/Documentation/cputopology.txt b/Documentation/cputopology.txt index 2b28e9ec4..ff280e2e1 100644 --- a/Documentation/cputopology.txt +++ b/Documentation/cputopology.txt @@ -1,5 +1,5 @@ -Export cpu topology info via sysfs. Items (attributes) are similar +Export cpu topology info by sysfs. Items (attributes) are similar to /proc/cpuinfo. 1) /sys/devices/system/cpu/cpuX/topology/physical_package_id: @@ -12,7 +12,7 @@ represent the thread siblings to cpu X in the same core; represent the thread siblings to cpu X in the same physical package; To implement it in an architecture-neutral way, a new source file, -drivers/base/topology.c, is to export the 4 attributes. +driver/base/topology.c, is to export the 5 attributes. If one architecture wants to support this feature, it just needs to implement 4 defines, typically in file include/asm-XXX/topology.h. diff --git a/Documentation/devices.txt b/Documentation/devices.txt index b369a8c46..3c406acd4 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -1721,6 +1721,11 @@ Your cooperation is appreciated. These devices support the same API as the generic SCSI devices. + 97 block Packet writing for CD/DVD devices + 0 = /dev/pktcdvd0 First packet-writing module + 1 = /dev/pktcdvd1 Second packet-writing module + ... + 98 char Control and Measurement Device (comedi) 0 = /dev/comedi0 First comedi device 1 = /dev/comedi1 Second comedi device diff --git a/Documentation/drivers/edac/edac.txt b/Documentation/drivers/edac/edac.txt index 70d96a62e..d37191fe5 100644 --- a/Documentation/drivers/edac/edac.txt +++ b/Documentation/drivers/edac/edac.txt @@ -21,7 +21,7 @@ within the computer system. In the initial release, memory Correctable Errors Detecting CE events, then harvesting those events and reporting them, CAN be a predictor of future UE events. With CE events, the system can -continue to operate, but with less safety. Preventive maintenance and +continue to operate, but with less safety. Preventive maintainence and proactive part replacement of memory DIMMs exhibiting CEs can reduce the likelihood of the dreaded UE events and system 'panics'. @@ -29,13 +29,13 @@ the likelihood of the dreaded UE events and system 'panics'. In addition, PCI Bus Parity and SERR Errors are scanned for on PCI devices in order to determine if errors are occurring on data transfers. The presence of PCI Parity errors must be examined with a grain of salt. -There are several add-in adapters that do NOT follow the PCI specification +There are several addin adapters that do NOT follow the PCI specification with regards to Parity generation and reporting. The specification says the vendor should tie the parity status bits to 0 if they do not intend to generate parity. Some vendors do not do this, and thus the parity bit can "float" giving false positives. -The PCI Parity EDAC device has the ability to "skip" known flaky +The PCI Parity EDAC device has the ability to "skip" known flakey cards during the parity scan. These are set by the parity "blacklist" interface in the sysfs for PCI Parity. (See the PCI section in the sysfs section below.) There is also a parity "whitelist" which is used as @@ -101,7 +101,7 @@ Memory Controller (mc) Model First a background on the memory controller's model abstracted in EDAC. Each mc device controls a set of DIMM memory modules. These modules are -laid out in a Chip-Select Row (csrowX) and Channel table (chX). There can +layed out in a Chip-Select Row (csrowX) and Channel table (chX). There can be multiple csrows and two channels. Memory controllers allow for several csrows, with 8 csrows being a typical value. @@ -131,7 +131,7 @@ for memory DIMMs: DIMM_B1 Labels for these slots are usually silk screened on the motherboard. Slots -labeled 'A' are channel 0 in this example. Slots labeled 'B' +labeled 'A' are channel 0 in this example. Slots labled 'B' are channel 1. Notice that there are two csrows possible on a physical DIMM. These csrows are allocated their csrow assignment based on the slot into which the memory DIMM is placed. Thus, when 1 DIMM @@ -140,7 +140,7 @@ is placed in each Channel, the csrows cross both DIMMs. Memory DIMMs come single or dual "ranked". A rank is a populated csrow. Thus, 2 single ranked DIMMs, placed in slots DIMM_A0 and DIMM_B0 above will have 1 csrow, csrow0. csrow1 will be empty. On the other hand, -when 2 dual ranked DIMMs are similarly placed, then both csrow0 and +when 2 dual ranked DIMMs are similiaryly placed, then both csrow0 and csrow1 will be populated. The pattern repeats itself for csrow2 and csrow3. @@ -246,7 +246,7 @@ Module Version read-only attribute file: 'mc_version' - The EDAC CORE module's version and compile date are shown here to + The EDAC CORE modules's version and compile date are shown here to indicate what EDAC is running. @@ -423,7 +423,7 @@ Total memory managed by this csrow attribute file: 'size_mb' This attribute file displays, in count of megabytes, of memory - that this csrow contains. + that this csrow contatins. Memory Type attribute file: @@ -557,7 +557,7 @@ On Header Type 00 devices the primary status is looked at for any parity error regardless of whether Parity is enabled on the device. (The spec indicates parity is generated in some cases). On Header Type 01 bridges, the secondary status register is also -looked at to see if parity occurred on the bus on the other side of +looked at to see if parity ocurred on the bus on the other side of the bridge. @@ -588,7 +588,7 @@ Panic on PCI PARITY Error: 'panic_on_pci_parity' - This control files enables or disables panicking when a parity + This control files enables or disables panic'ing when a parity error has been detected. @@ -616,12 +616,12 @@ PCI Device Whitelist: This control file allows for an explicit list of PCI devices to be scanned for parity errors. Only devices found on this list will - be examined. The list is a line of hexadecimal VENDOR and DEVICE + be examined. The list is a line of hexadecimel VENDOR and DEVICE ID tuples: 1022:7450,1434:16a6 - One or more can be inserted, separated by a comma. + One or more can be inserted, seperated by a comma. To write the above list doing the following as one command line: @@ -639,11 +639,11 @@ PCI Device Blacklist: This control file allows for a list of PCI devices to be skipped for scanning. - The list is a line of hexadecimal VENDOR and DEVICE ID tuples: + The list is a line of hexadecimel VENDOR and DEVICE ID tuples: 1022:7450,1434:16a6 - One or more can be inserted, separated by a comma. + One or more can be inserted, seperated by a comma. To write the above list doing the following as one command line: @@ -651,14 +651,14 @@ PCI Device Blacklist: > /sys/devices/system/edac/pci/pci_parity_blacklist - To display what the whitelist currently contains, + To display what the whitelist current contatins, simply 'cat' the same file. ======================================================================= PCI Vendor and Devices IDs can be obtained with the lspci command. Using the -n option lspci will display the vendor and device IDs. The system -administrator will have to determine which devices should be scanned or +adminstrator will have to determine which devices should be scanned or skipped. @@ -669,5 +669,5 @@ Turn OFF a whitelist by an empty echo command: echo > /sys/devices/system/edac/pci/pci_parity_whitelist -and any previous blacklist will be utilized. +and any previous blacklist will be utililzed. diff --git a/Documentation/dvb/avermedia.txt b/Documentation/dvb/avermedia.txt index 8bab8461a..068070ff1 100644 --- a/Documentation/dvb/avermedia.txt +++ b/Documentation/dvb/avermedia.txt @@ -1,3 +1,4 @@ + HOWTO: Get An Avermedia DVB-T working under Linux ______________________________________________ @@ -136,8 +137,11 @@ Getting the card going To power up the card, load the following modules in the following order: - * modprobe bttv (normally loaded automatically) - * modprobe dvb-bt8xx (or place dvb-bt8xx in /etc/modules) + * insmod dvb-core.o + * modprobe bttv.o + * insmod bt878.o + * insmod dvb-bt8xx.o + * insmod sp887x.o Insertion of these modules into the running kernel will activate the appropriate DVB device nodes. It is then possible @@ -298,4 +302,4 @@ Further Update Many thanks to Nigel Pearson for the updates to this document since the recent revision of the driver. - February 14th 2006 + January 29th 2004 diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt index 4e7614e60..52ed46206 100644 --- a/Documentation/dvb/bt8xx.txt +++ b/Documentation/dvb/bt8xx.txt @@ -1,78 +1,118 @@ -How to get the bt8xx cards working -================================== +How to get the Nebula, PCTV, FusionHDTV Lite and Twinhan DST cards working +========================================================================== -1) General information -====================== +This class of cards has a bt878a as the PCI interface, and +require the bttv driver. -This class of cards has a bt878a as the PCI interface, and require the bttv driver -for accessing the i2c bus and the gpio pins of the bt8xx chipset. -Please see Documentation/dvb/cards.txt => o Cards based on the Conexant Bt8xx PCI bridge: +Please pay close attention to the warning about the bttv module +options below for the DST card. -Compiling kernel please enable: -a.)"Device drivers" => "Multimedia devices" => "Video For Linux" => "BT848 Video For Linux" -b.)"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices" - => "DVB for Linux" "DVB Core Support" "Bt8xx based PCI Cards" +1) General informations +======================= + +These drivers require the bttv driver to provide the means to access +the i2c bus and the gpio pins of the bt8xx chipset. + +Because of this, you need to enable +"Device drivers" => "Multimedia devices" + => "Video For Linux" => "BT848 Video For Linux" + +Furthermore you need to enable +"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices" + => "DVB for Linux" "DVB Core Support" "BT8xx based PCI cards" 2) Loading Modules ================== -In default cases bttv is loaded automatically. -To load the backend either place dvb-bt8xx in etc/modules, or apply manually: +In general you need to load the bttv driver, which will handle the gpio and +i2c communication for us, plus the common dvb-bt8xx device driver. +The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110), TwinHan (dst), +FusionHDTV DVB-T Lite (mt352) and FusionHDTV5 Lite (lgdt330x) are loaded +automatically by the dvb-bt8xx device driver. + +3a) Nebula / Pinnacle PCTV / FusionHDTV Lite +--------------------------------------------- + + $ modprobe bttv (normally bttv is being loaded automatically by kmod) + $ modprobe dvb-bt8xx + +(or just place dvb-bt8xx in /etc/modules for automatic loading) + + +3b) TwinHan and Clones +-------------------------- - $ modprobe dvb-bt8xx + $ modprobe bttv card=0x71 + $ modprobe dvb-bt8xx + $ modprobe dst -All frontends will be loaded automatically. -People running udev please see Documentation/dvb/udev.txt. +The value 0x71 will override the PCI type detection for dvb-bt8xx, +which is necessary for TwinHan cards. Omission of this parameter might result +in a system lockup. -In the following cases overriding the PCI type detection for dvb-bt8xx might be necessary: +If you're having an older card (blue color PCB) and card=0x71 locks up +your machine, try using 0x68, too. If that does not work, ask on the +mailing list. -2a) Running TwinHan and Clones ------------------------------- +The DST module takes a couple of useful parameters. - $ modprobe bttv card=113 - $ modprobe dvb-bt8xx - $ modprobe dst +verbose takes values 0 to 4. These values control the verbosity level, +and can be used to debug also. -Useful parameters for verbosity level and debugging the dst module: +verbose=0 means complete disabling of messages + 1 only error messages are displayed + 2 notifications are also displayed + 3 informational messages are also displayed + 4 debug setting -verbose=0: messages are disabled - 1: only error messages are displayed - 2: notifications are displayed - 3: other useful messages are displayed - 4: debug setting -dst_addons=0: card is a free to air (FTA) card only - 0x20: card has a conditional access slot for scrambled channels +dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card. +0x20 means it has a Conditional Access slot. -The autodetected values are determined by the cards' "response string". -In your logs see f. ex.: dst_get_device_id: Recognize [DSTMCI]. -For bug reports please send in a complete log with verbose=4 activated. -Please also see Documentation/dvb/ci.txt. +The autodetected values are determined by the cards 'response string' +which you can see in your logs e.g. -2b) Running multiple cards +dst_get_device_id: Recognise [DSTMCI] + +If you need to sent in bug reports on the dst, please do send in a complete +log with the verbose=4 module parameter. For general usage, the default setting +of verbose=1 is ideal. + + +4) Multiple cards -------------------------- -Examples of card ID's: +If you happen to be running multiple cards, it would be advisable to load +the bttv module with the card id. This would help to solve any module loading +problems that you might face. + +For example, if you have a Twinhan and Clones card along with a FusionHDTV5 Lite -Pinnacle PCTV Sat: 94 -Nebula Electronics Digi TV: 104 -pcHDTV HD-2000 TV: 112 -Twinhan DST and clones: 113 -Avermedia AverTV DVB-T 771: 123 -Avermedia AverTV DVB-T 761: 124 -DViCO FusionHDTV DVB-T Lite: 128 -DViCO FusionHDTV 5 Lite: 135 + $ modprobe bttv card=0x71 card=0x87 + +Here the order of the card id is important and should be the same as that of the +physical order of the cards. Here card=0x71 represents the Twinhan and clones +and card=0x87 represents Fusion HDTV5 Lite. These arguments can also be +specified in decimal, rather than hex: -Notice: The order of the card ID should be uprising: -Example: $ modprobe bttv card=113 card=135 - $ modprobe dvb-bt8xx -For a full list of card ID's please see Documentation/video4linux/CARDLIST.bttv. -In case of further problems send questions to the mailing list: www.linuxdvb.org. +Some examples of card-id's + +Pinnacle Sat 0x5e (94) +Nebula Digi TV 0x68 (104) +PC HDTV 0x70 (112) +Twinhan 0x71 (113) +FusionHDTV DVB-T Lite 0x80 (128) +FusionHDTV5 Lite 0x87 (135) + +For a full list of card-id's, see the V4L Documentation within the kernel +source: linux/Documentation/video4linux/CARDLIST.bttv + +If you have problems with this please do ask on the mailing list. +-- Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, - Uwe Bugla, Michael Krufky diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware index 4820366b6..ee74eeb76 100644 --- a/Documentation/dvb/get_dvb_firmware +++ b/Documentation/dvb/get_dvb_firmware @@ -246,7 +246,7 @@ sub vp7041 { } sub dibusb { - my $url = "http://www.linuxtv.org/downloads/firmware/dvb-usb-dibusb-5.0.0.11.fw"; + my $url = "http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw"; my $outfile = "dvb-dibusb-5.0.0.11.fw"; my $hash = "fa490295a527360ca16dcdf3224ca243"; diff --git a/Documentation/dvb/readme.txt b/Documentation/dvb/readme.txt index 0b0380c91..f5c50b22d 100644 --- a/Documentation/dvb/readme.txt +++ b/Documentation/dvb/readme.txt @@ -20,23 +20,11 @@ http://linuxtv.org/downloads/ What's inside this directory: -"avermedia.txt" -contains detailed information about the -Avermedia DVB-T cards. See also "bt8xx.txt". - -"bt8xx.txt" -contains detailed information about the -various bt8xx based "budget" DVB cards. - "cards.txt" contains a list of supported hardware. -"ci.txt" -contains detailed information about the -CI module as part from TwinHan cards and Clones. - "contributors.txt" -is the who-is-who of DVB development. +is the who-is-who of DVB development "faq.txt" contains frequently asked questions and their answers. @@ -46,17 +34,19 @@ script to download and extract firmware for those devices that require it. "ttusb-dec.txt" -contains detailed information about the +contains detailed informations about the TT DEC2000/DEC3000 USB DVB hardware. -"udev.txt" -how to get DVB and udev up and running. +"bt8xx.txt" +contains detailed installation instructions for the +various bt8xx based "budget" DVB cards +(Nebula, Pinnacle PCTV, Twinhan DST) -"README.dvb-usb" -contains detailed information about the DVB USB cards. +"README.dibusb" +contains detailed information about adapters +based on DiBcom reference design. -"README.flexcop" -contains detailed information about the -Technisat- and Flexcop B2C2 drivers. +"udev.txt" +how to get DVB and udev up and running. Good luck and have fun! diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt deleted file mode 100644 index 43ab11996..000000000 --- a/Documentation/feature-removal-schedule.txt +++ /dev/null @@ -1,250 +0,0 @@ -The following is a list of files and features that are going to be -removed in the kernel source tree. Every entry should contain what -exactly is going away, why it is happening, and who is going to be doing -the work. When the feature is removed from the kernel, it should also -be removed from this file. - ---------------------------- - -What: devfs -When: July 2005 -Files: fs/devfs/*, include/linux/devfs_fs*.h and assorted devfs - function calls throughout the kernel tree -Why: It has been unmaintained for a number of years, has unfixable - races, contains a naming policy within the kernel that is - against the LSB, and can be replaced by using udev. -Who: Greg Kroah-Hartman - ---------------------------- - -What: RAW driver (CONFIG_RAW_DRIVER) -When: December 2005 -Why: declared obsolete since kernel 2.6.3 - O_DIRECT can be used instead -Who: Adrian Bunk - ---------------------------- - -What: drivers that were depending on OBSOLETE_OSS_DRIVER - (config options already removed) -When: before 2.6.19 -Why: OSS drivers with ALSA replacements -Who: Adrian Bunk - ---------------------------- - -What: RCU API moves to EXPORT_SYMBOL_GPL -When: April 2006 -Files: include/linux/rcupdate.h, kernel/rcupdate.c -Why: Outside of Linux, the only implementations of anything even - vaguely resembling RCU that I am aware of are in DYNIX/ptx, - VM/XA, Tornado, and K42. I do not expect anyone to port binary - drivers or kernel modules from any of these, since the first two - are owned by IBM and the last two are open-source research OSes. - So these will move to GPL after a grace period to allow - people, who might be using implementations that I am not aware - of, to adjust to this upcoming change. -Who: Paul E. McKenney - ---------------------------- - -What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN -When: November 2005 -Why: Deprecated in favour of the new ioctl-based rawiso interface, which is - more efficient. You should really be using libraw1394 for raw1394 - access anyway. -Who: Jody McIntyre - ---------------------------- - -What: sbp2: module parameter "force_inquiry_hack" -When: July 2006 -Why: Superceded by parameter "workarounds". Both parameters are meant to be - used ad-hoc and for single devices only, i.e. not in modprobe.conf, - therefore the impact of this feature replacement should be low. -Who: Stefan Richter - ---------------------------- - -What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. -When: July 2006 -Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6 - series. The old API have lots of drawbacks and don't provide enough - means to work with all video and audio standards. The newer API is - already available on the main drivers and should be used instead. - Newer drivers should use v4l_compat_translate_ioctl function to handle - old calls, replacing to newer ones. - Decoder iocts are using internally to allow video drivers to - communicate with video decoders. This should also be improved to allow - V4L2 calls being translated into compatible internal ioctls. -Who: Mauro Carvalho Chehab - ---------------------------- - -What: remove EXPORT_SYMBOL(insert_resource) -When: April 2006 -Files: kernel/resource.c -Why: No modular usage in the kernel. -Who: Adrian Bunk - ---------------------------- - -What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) -When: November 2005 -Files: drivers/pcmcia/: pcmcia_ioctl.c -Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a - normal hotpluggable bus, and with it using the default kernel - infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA - control ioctl needed by cardmgr and cardctl from pcmcia-cs is - unnecessary, and makes further cleanups and integration of the - PCMCIA subsystem into the Linux kernel device driver model more - difficult. The features provided by cardmgr and cardctl are either - handled by the kernel itself now or are available in the new - pcmciautils package available at - http://kernel.org/pub/linux/utils/kernel/pcmcia/ -Who: Dominik Brodowski - ---------------------------- - -What: ip_queue and ip6_queue (old ipv4-only and ipv6-only netfilter queue) -When: December 2005 -Why: This interface has been obsoleted by the new layer3-independent - "nfnetlink_queue". The Kernel interface is compatible, so the old - ip[6]tables "QUEUE" targets still work and will transparently handle - all packets into nfnetlink queue number 0. Userspace users will have - to link against API-compatible library on top of libnfnetlink_queue - instead of the current 'libipq'. -Who: Harald Welte - ---------------------------- - -What: remove EXPORT_SYMBOL(kernel_thread) -When: August 2006 -Files: arch/*/kernel/*_ksyms.c -Why: kernel_thread is a low-level implementation detail. Drivers should - use the API instead which shields them from - implementation details and provides a higherlevel interface that - prevents bugs and code duplication -Who: Christoph Hellwig - ---------------------------- - -What: CONFIG_FORCED_INLINING -When: June 2006 -Why: Config option is there to see if gcc is good enough. (in january - 2006). If it is, the behavior should just be the default. If it's not, - the option should just go away entirely. -Who: Arjan van de Ven - ---------------------------- - -What: START_ARRAY ioctl for md -When: July 2006 -Files: drivers/md/md.c -Why: Not reliable by design - can fail when most needed. - Alternatives exist -Who: NeilBrown - ---------------------------- - -What: au1x00_uart driver -When: January 2006 -Why: The 8250 serial driver now has the ability to deal with the differences - between the standard 8250 family of UARTs and their slightly strange - brother on Alchemy SOCs. The loss of features is not considered an - issue. -Who: Ralf Baechle - ---------------------------- - -What: eepro100 network driver -When: January 2007 -Why: replaced by the e100 driver -Who: Adrian Bunk - ---------------------------- - -What: pci_module_init(driver) -When: January 2007 -Why: Is replaced by pci_register_driver(pci_driver). -Who: Richard Knutsson and Greg Kroah-Hartman - ---------------------------- - -What: Usage of invalid timevals in setitimer -When: March 2007 -Why: POSIX requires to validate timevals in the setitimer call. This - was never done by Linux. The invalid (e.g. negative timevals) were - silently converted to more or less random timeouts and intervals. - Until the removal a per boot limited number of warnings is printed - and the timevals are sanitized. - -Who: Thomas Gleixner - ---------------------------- - -What: I2C interface of the it87 driver -When: January 2007 -Why: The ISA interface is faster and should be always available. The I2C - probing is also known to cause trouble in at least one case (see - bug #5889.) -Who: Jean Delvare - ---------------------------- - -What: remove EXPORT_SYMBOL(tasklist_lock) -When: August 2006 -Files: kernel/fork.c -Why: tasklist_lock protects the kernel internal task list. Modules have - no business looking at it, and all instances in drivers have been due - to use of too-lowlevel APIs. Having this symbol exported prevents - moving to more scalable locking schemes for the task list. -Who: Christoph Hellwig - ---------------------------- - -What: mount/umount uevents -When: February 2007 -Why: These events are not correct, and do not properly let userspace know - when a file system has been mounted or unmounted. Userspace should - poll the /proc/mounts file instead to detect this properly. -Who: Greg Kroah-Hartman - ---------------------------- - -What: Support for NEC DDB5074 and DDB5476 evaluation boards. -When: June 2006 -Why: Board specific code doesn't build anymore since ~2.6.0 and no - users have complained indicating there is no more need for these - boards. This should really be considered a last call. -Who: Ralf Baechle - ---------------------------- - -What: USB driver API moves to EXPORT_SYMBOL_GPL -When: Febuary 2008 -Files: include/linux/usb.h, drivers/usb/core/driver.c -Why: The USB subsystem has changed a lot over time, and it has been - possible to create userspace USB drivers using usbfs/libusb/gadgetfs - that operate as fast as the USB bus allows. Because of this, the USB - subsystem will not be allowing closed source kernel drivers to - register with it, after this grace period is over. If anyone needs - any help in converting their closed source drivers over to use the - userspace filesystems, please contact the - linux-usb-devel@lists.sourceforge.net mailing list, and the developers - there will be glad to help you out. -Who: Greg Kroah-Hartman - ---------------------------- - -What: find_trylock_page -When: January 2007 -Why: The interface no longer has any callers left in the kernel. It - is an odd interface (compared with other find_*_page functions), in - that it does not take a refcount to the page, only the page lock. - It should be replaced with find_get_page or find_lock_page if possible. - This feature removal can be reevaluated if users of the interface - cannot cleanly use something else. -Who: Nick Piggin - ---------------------------- diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX index 66fdc0744..74052d22d 100644 --- a/Documentation/filesystems/00-INDEX +++ b/Documentation/filesystems/00-INDEX @@ -1,47 +1,27 @@ 00-INDEX - this file (info on some of the filesystems supported by linux). -Exporting - - explanation of how to make filesystems exportable. Locking - info on locking rules as they pertain to Linux VFS. adfs.txt - info and mount options for the Acorn Advanced Disc Filing System. -afs.txt - - info and examples for the distributed AFS (Andrew File System) fs. affs.txt - info and mount options for the Amiga Fast File System. -automount-support.txt - - information about filesystem automount support. -befs.txt - - information about the BeOS filesystem for Linux. bfs.txt - info for the SCO UnixWare Boot Filesystem (BFS). cifs.txt - - description of the CIFS filesystem. + - description of the CIFS filesystem coda.txt - description of the CODA filesystem. configfs/ - directory containing configfs documentation and example code. cramfs.txt - - info on the cram filesystem for small storage (ROMs etc). -dentry-locking.txt - - info on the RCU-based dcache locking model. + - info on the cram filesystem for small storage (ROMs etc) devfs/ - directory containing devfs documentation. -directory-locking - - info about the locking scheme used for directory operations. dlmfs.txt - info on the userspace interface to the OCFS2 DLM. ext2.txt - info, mount options and specifications for the Ext2 filesystem. -ext3.txt - - info, mount options and specifications for the Ext3 filesystem. -files.txt - - info on file management in the Linux kernel. -fuse.txt - - info on the Filesystem in User SpacE including mount options. -hfs.txt - - info on the Macintosh HFS Filesystem for Linux. hpfs.txt - info and mount options for the OS/2 HPFS. isofs.txt @@ -52,43 +32,23 @@ ncpfs.txt - info on Novell Netware(tm) filesystem using NCP protocol. ntfs.txt - info and mount options for the NTFS filesystem (Windows NT). -ocfs2.txt - - info and mount options for the OCFS2 clustered filesystem. -porting - - various information on filesystem porting. proc.txt - info on Linux's /proc filesystem. -ramfs-rootfs-initramfs.txt - - info on the 'in memory' filesystems ramfs, rootfs and initramfs. -reiser4.txt - - info on the Reiser4 filesystem based on dancing tree algorithms. -relayfs.txt - - info on relayfs, for efficient streaming from kernel to user space. +ocfs2.txt + - info and mount options for the OCFS2 clustered filesystem. romfs.txt - - description of the ROMFS filesystem. + - Description of the ROMFS filesystem. smbfs.txt - - info on using filesystems with the SMB protocol (Win 3.11 and NT). -spufs.txt - - info and mount options for the SPU filesystem used on Cell. -sysfs-pci.txt - - info on accessing PCI device resources through sysfs. -sysfs.txt - - info on sysfs, a ram-based filesystem for exporting kernel objects. + - info on using filesystems with the SMB protocol (Windows 3.11 and NT) sysv-fs.txt - info on the SystemV/V7/Xenix/Coherent filesystem. -tmpfs.txt - - info on tmpfs, a filesystem that holds all files in virtual memory. udf.txt - info and mount options for the UDF filesystem. ufs.txt - info on the ufs filesystem. -v9fs.txt - - v9fs is a Unix implementation of the Plan 9 9p remote fs protocol. vfat.txt - info on using the VFAT filesystem used in Windows NT and Windows 95 vfs.txt - - overview of the Virtual File System + - Overview of the Virtual File System xfs.txt - info and mount options for the XFS filesystem. -xip.txt - - info on execute-in-place for file mappings. diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt deleted file mode 100644 index 43b89c214..000000000 --- a/Documentation/filesystems/9p.txt +++ /dev/null @@ -1,100 +0,0 @@ - v9fs: Plan 9 Resource Sharing for Linux - ======================================= - -ABOUT -===== - -v9fs is a Unix implementation of the Plan 9 9p remote filesystem protocol. - -This software was originally developed by Ron Minnich -and Maya Gokhale . Additional development by Greg Watson - and most recently Eric Van Hensbergen -, Latchesar Ionkov and Russ Cox -. - -USAGE -===== - -For remote file server: - - mount -t 9p 10.10.1.2 /mnt/9 - -For Plan 9 From User Space applications (http://swtch.com/plan9) - - mount -t 9p `namespace`/acme /mnt/9 -o proto=unix,uname=$USER - -OPTIONS -======= - - proto=name select an alternative transport. Valid options are - currently: - unix - specifying a named pipe mount point - tcp - specifying a normal TCP/IP connection - fd - used passed file descriptors for connection - (see rfdno and wfdno) - - uname=name user name to attempt mount as on the remote server. The - server may override or ignore this value. Certain user - names may require authentication. - - aname=name aname specifies the file tree to access when the server is - offering several exported file systems. - - debug=n specifies debug level. The debug level is a bitmask. - 0x01 = display verbose error messages - 0x02 = developer debug (DEBUG_CURRENT) - 0x04 = display 9p trace - 0x08 = display VFS trace - 0x10 = display Marshalling debug - 0x20 = display RPC debug - 0x40 = display transport debug - 0x80 = display allocation debug - - rfdno=n the file descriptor for reading with proto=fd - - wfdno=n the file descriptor for writing with proto=fd - - maxdata=n the number of bytes to use for 9p packet payload (msize) - - port=n port to connect to on the remote server - - noextend force legacy mode (no 9p2000.u semantics) - - uid attempt to mount as a particular uid - - gid attempt to mount with a particular gid - - afid security channel - used by Plan 9 authentication protocols - - nodevmap do not map special files - represent them as normal files. - This can be used to share devices/named pipes/sockets between - hosts. This functionality will be expanded in later versions. - -RESOURCES -========= - -The Linux version of the 9p server is now maintained under the npfs project -on sourceforge (http://sourceforge.net/projects/npfs). - -There are user and developer mailing lists available through the v9fs project -on sourceforge (http://sourceforge.net/projects/v9fs). - -News and other information is maintained on SWiK (http://swik.net/v9fs). - -Bug reports may be issued through the kernel.org bugzilla -(http://bugzilla.kernel.org) - -For more information on the Plan 9 Operating System check out -http://plan9.bell-labs.com/plan9 - -For information on Plan 9 from User Space (Plan 9 applications and libraries -ported to Linux/BSD/OSX/etc) check out http://swtch.com/plan9 - - -STATUS -====== - -The 2.6 kernel support is working on PPC and x86. - -PLEASE USE THE SOURCEFORGE BUG-TRACKER TO REPORT PROBLEMS. - diff --git a/Documentation/filesystems/isofs.txt b/Documentation/filesystems/isofs.txt index 758e50401..424585ff6 100644 --- a/Documentation/filesystems/isofs.txt +++ b/Documentation/filesystems/isofs.txt @@ -9,9 +9,9 @@ when using discs encoded using Microsoft's Joliet extensions. iocharset=name Character set to use for converting from Unicode to ASCII. Joliet filenames are stored in Unicode format, but Unix for the most part doesn't know how to deal with Unicode. - There is also an option of doing UTF-8 translations with the + There is also an option of doing UTF8 translations with the utf8 option. - utf8 Encode Unicode names in UTF-8 format. Default is no. + utf8 Encode Unicode names in UTF8 format. Default is no. Mount options unique to the isofs filesystem. block=512 Set the block size for the disk to 512 bytes diff --git a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt index bae128663..3e992daf9 100644 --- a/Documentation/filesystems/jfs.txt +++ b/Documentation/filesystems/jfs.txt @@ -6,7 +6,7 @@ The following mount options are supported: iocharset=name Character set to use for converting from Unicode to ASCII. The default is to do no conversion. Use - iocharset=utf8 for UTF-8 translations. This requires + iocharset=utf8 for UTF8 translations. This requires CONFIG_NLS_UTF8 to be set in the kernel .config file. iocharset=none specifies the default behavior explicitly. diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt index 638cbd3d2..251168587 100644 --- a/Documentation/filesystems/ntfs.txt +++ b/Documentation/filesystems/ntfs.txt @@ -457,11 +457,6 @@ ChangeLog Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. -2.1.27: - - Implement page migration support so the kernel can move memory used - by NTFS files and directories around for management purposes. - - Add support for writing to sparse files created with Windows XP SP2. - - Many minor improvements and bug fixes. 2.1.26: - Implement support for sector sizes above 512 bytes (up to the maximum supported by NTFS which is 4096 bytes). diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 99902ae68..944cf109a 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -121,7 +121,7 @@ Table 1-1: Process specific entries in /proc .............................................................................. File Content cmdline Command line arguments - cpu Current and last cpu in which it was executed (2.4)(smp) + cpu Current and last cpu in wich it was executed (2.4)(smp) cwd Link to the current working directory environ Values of environment variables exe Link to the executable of this process @@ -309,13 +309,13 @@ is the same by default: > cat /proc/irq/0/smp_affinity ffffffff -It's a bitmask, in which you can specify which CPUs can handle the IRQ, you can +It's a bitmask, in wich you can specify wich CPUs can handle the IRQ, you can set it by doing: > echo 1 > /proc/irq/prof_cpu_mask This means that only the first CPU will handle the IRQ, but you can also echo 5 -which means that only the first and fourth CPU can handle the IRQ. +wich means that only the first and fourth CPU can handle the IRQ. The way IRQs are routed is handled by the IO-APIC, and it's Round Robin between all the CPUs which are allowed to handle it. As usual the kernel has diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index 89b1d196c..c8bce82dd 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -246,7 +246,6 @@ class/ devices/ firmware/ net/ -fs/ devices/ contains a filesystem representation of the device tree. It maps directly to the internal kernel device tree, which is a hierarchy of @@ -265,10 +264,6 @@ drivers/ contains a directory for each device driver that is loaded for devices on that particular bus (this assumes that drivers do not span multiple bus types). -fs/ contains a directory for some filesystems. Currently each -filesystem wanting to export attributes must create its own hierarchy -below fs/ (see ./fuse.txt for an example). - More information can driver-model specific features can be found in Documentation/driver-model/. diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt index 511b4230c..e5213bc30 100644 --- a/Documentation/filesystems/udf.txt +++ b/Documentation/filesystems/udf.txt @@ -26,20 +26,6 @@ The following mount options are supported: nostrict Unset strict conformance iocharset= Set the NLS character set -The uid= and gid= options need a bit more explaining. They will accept a -decimal numeric value which will be used as the default ID for that mount. -They will also accept the string "ignore" and "forget". For files on the disk -that are owned by nobody ( -1 ), they will instead look as if they are owned -by the default ID. The ignore option causes the default ID to override all -IDs on the disk, not just -1. The forget option causes all IDs to be written -to disk as -1, so when the media is later remounted, they will appear to be -owned by whatever default ID it is mounted with at that time. - -For typical desktop use of removable media, you should set the ID to that -of the interactively logged on user, and also specify both the forget and -ignore options. This way the interactive user will always see the files -on the disk as belonging to him. - The remaining are for debugging and disaster recovery: novrs Skip volume sequence recognition diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt index 2001abbc6..5ead20c6c 100644 --- a/Documentation/filesystems/vfat.txt +++ b/Documentation/filesystems/vfat.txt @@ -28,16 +28,16 @@ iocharset=name -- Character set to use for converting between the know how to deal with Unicode. By default, FAT_DEFAULT_IOCHARSET setting is used. - There is also an option of doing UTF-8 translations + There is also an option of doing UTF8 translations with the utf8 option. NOTE: "iocharset=utf8" is not recommended. If unsure, you should consider the following option instead. -utf8= -- UTF-8 is the filesystem safe version of Unicode that +utf8= -- UTF8 is the filesystem safe version of Unicode that is used by the console. It can be be enabled for the filesystem with this option. If 'uni_xlate' gets set, - UTF-8 gets disabled. + UTF8 gets disabled. uni_xlate= -- Translate unhandled Unicode characters to special escaped sequences. This would let you backup and diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 3a2e5520c..e56e84284 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -230,15 +230,10 @@ only called from a process context (i.e. not from an interrupt handler or bottom half). alloc_inode: this method is called by inode_alloc() to allocate memory - for struct inode and initialize it. If this function is not - defined, a simple 'struct inode' is allocated. Normally - alloc_inode will be used to allocate a larger structure which - contains a 'struct inode' embedded within it. + for struct inode and initialize it. destroy_inode: this method is called by destroy_inode() to release - resources allocated for struct inode. It is only required if - ->alloc_inode was defined and simply undoes anything done by - ->alloc_inode. + resources allocated for struct inode. read_inode: this method is called to read a specific inode from the mounted filesystem. The i_ino member in the struct inode is @@ -448,81 +443,14 @@ otherwise noted. The Address Space Object ======================== -The address space object is used to group and manage pages in the page -cache. It can be used to keep track of the pages in a file (or -anything else) and also track the mapping of sections of the file into -process address spaces. - -There are a number of distinct yet related services that an -address-space can provide. These include communicating memory -pressure, page lookup by address, and keeping track of pages tagged as -Dirty or Writeback. - -The first can be used independently to the others. The VM can try to -either write dirty pages in order to clean them, or release clean -pages in order to reuse them. To do this it can call the ->writepage -method on dirty pages, and ->releasepage on clean pages with -PagePrivate set. Clean pages without PagePrivate and with no external -references will be released without notice being given to the -address_space. - -To achieve this functionality, pages need to be placed on an LRU with -lru_cache_add and mark_page_active needs to be called whenever the -page is used. - -Pages are normally kept in a radix tree index by ->index. This tree -maintains information about the PG_Dirty and PG_Writeback status of -each page, so that pages with either of these flags can be found -quickly. - -The Dirty tag is primarily used by mpage_writepages - the default -->writepages method. It uses the tag to find dirty pages to call -->writepage on. If mpage_writepages is not used (i.e. the address -provides its own ->writepages) , the PAGECACHE_TAG_DIRTY tag is -almost unused. write_inode_now and sync_inode do use it (through -__sync_single_inode) to check if ->writepages has been successful in -writing out the whole address_space. - -The Writeback tag is used by filemap*wait* and sync_page* functions, -via wait_on_page_writeback_range, to wait for all writeback to -complete. While waiting ->sync_page (if defined) will be called on -each page that is found to require writeback. - -An address_space handler may attach extra information to a page, -typically using the 'private' field in the 'struct page'. If such -information is attached, the PG_Private flag should be set. This will -cause various VM routines to make extra calls into the address_space -handler to deal with that data. - -An address space acts as an intermediate between storage and -application. Data is read into the address space a whole page at a -time, and provided to the application either by copying of the page, -or by memory-mapping the page. -Data is written into the address space by the application, and then -written-back to storage typically in whole pages, however the -address_space has finer control of write sizes. - -The read process essentially only requires 'readpage'. The write -process is more complicated and uses prepare_write/commit_write or -set_page_dirty to write data into the address_space, and writepage, -sync_page, and writepages to writeback data to storage. - -Adding and removing pages to/from an address_space is protected by the -inode's i_mutex. - -When data is written to a page, the PG_Dirty flag should be set. It -typically remains set until writepage asks for it to be written. This -should clear PG_Dirty and set PG_Writeback. It can be actually -written at any point after PG_Dirty is clear. Once it is known to be -safe, PG_Writeback is cleared. - -Writeback makes use of a writeback_control structure... +The address space object is used to identify pages in the page cache. + struct address_space_operations ------------------------------- This describes how the VFS can manipulate mapping of a file to page cache in -your filesystem. As of kernel 2.6.16, the following members are defined: +your filesystem. As of kernel 2.6.13, the following members are defined: struct address_space_operations { int (*writepage)(struct page *page, struct writeback_control *wbc); @@ -541,148 +469,47 @@ struct address_space_operations { loff_t offset, unsigned long nr_segs); struct page* (*get_xip_page)(struct address_space *, sector_t, int); - /* migrate the contents of a page to the specified target */ - int (*migratepage) (struct page *, struct page *); }; - writepage: called by the VM to write a dirty page to backing store. - This may happen for data integrity reasons (i.e. 'sync'), or - to free up memory (flush). The difference can be seen in - wbc->sync_mode. - The PG_Dirty flag has been cleared and PageLocked is true. - writepage should start writeout, should set PG_Writeback, - and should make sure the page is unlocked, either synchronously - or asynchronously when the write operation completes. - - If wbc->sync_mode is WB_SYNC_NONE, ->writepage doesn't have to - try too hard if there are problems, and may choose to write out - other pages from the mapping if that is easier (e.g. due to - internal dependencies). If it chooses not to start writeout, it - should return AOP_WRITEPAGE_ACTIVATE so that the VM will not keep - calling ->writepage on that page. - - See the file "Locking" for more details. + writepage: called by the VM write a dirty page to backing store. readpage: called by the VM to read a page from backing store. - The page will be Locked when readpage is called, and should be - unlocked and marked uptodate once the read completes. - If ->readpage discovers that it needs to unlock the page for - some reason, it can do so, and then return AOP_TRUNCATED_PAGE. - In this case, the page will be relocated, relocked and if - that all succeeds, ->readpage will be called again. sync_page: called by the VM to notify the backing store to perform all queued I/O operations for a page. I/O operations for other pages associated with this address_space object may also be performed. - This function is optional and is called only for pages with - PG_Writeback set while waiting for the writeback to complete. - writepages: called by the VM to write out pages associated with the - address_space object. If wbc->sync_mode is WBC_SYNC_ALL, then - the writeback_control will specify a range of pages that must be - written out. If it is WBC_SYNC_NONE, then a nr_to_write is given - and that many pages should be written if possible. - If no ->writepages is given, then mpage_writepages is used - instead. This will choose pages from the address space that are - tagged as DIRTY and will pass them to ->writepage. + address_space object. set_page_dirty: called by the VM to set a page dirty. - This is particularly needed if an address space attaches - private data to a page, and that data needs to be updated when - a page is dirtied. This is called, for example, when a memory - mapped page gets modified. - If defined, it should set the PageDirty flag, and the - PAGECACHE_TAG_DIRTY tag in the radix tree. readpages: called by the VM to read pages associated with the address_space - object. This is essentially just a vector version of - readpage. Instead of just one page, several pages are - requested. - readpages is only used for read-ahead, so read errors are - ignored. If anything goes wrong, feel free to give up. + object. prepare_write: called by the generic write path in VM to set up a write - request for a page. This indicates to the address space that - the given range of bytes is about to be written. The - address_space should check that the write will be able to - complete, by allocating space if necessary and doing any other - internal housekeeping. If the write will update parts of - any basic-blocks on storage, then those blocks should be - pre-read (if they haven't been read already) so that the - updated blocks can be written out properly. - The page will be locked. If prepare_write wants to unlock the - page it, like readpage, may do so and return - AOP_TRUNCATED_PAGE. - In this case the prepare_write will be retried one the lock is - regained. - - commit_write: If prepare_write succeeds, new data will be copied - into the page and then commit_write will be called. It will - typically update the size of the file (if appropriate) and - mark the inode as dirty, and do any other related housekeeping - operations. It should avoid returning an error if possible - - errors should have been handled by prepare_write. + request for a page. + + commit_write: called by the generic write path in VM to write page to + its backing store. bmap: called by the VFS to map a logical block offset within object to - physical block number. This method is used by the FIBMAP - ioctl and for working with swap-files. To be able to swap to - a file, the file must have a stable mapping to a block - device. The swap system does not go through the filesystem - but instead uses bmap to find out where the blocks in the file - are and uses those addresses directly. - - - invalidatepage: If a page has PagePrivate set, then invalidatepage - will be called when part or all of the page is to be removed - from the address space. This generally corresponds to either a - truncation or a complete invalidation of the address space - (in the latter case 'offset' will always be 0). - Any private data associated with the page should be updated - to reflect this truncation. If offset is 0, then - the private data should be released, because the page - must be able to be completely discarded. This may be done by - calling the ->releasepage function, but in this case the - release MUST succeed. - - releasepage: releasepage is called on PagePrivate pages to indicate - that the page should be freed if possible. ->releasepage - should remove any private data from the page and clear the - PagePrivate flag. It may also remove the page from the - address_space. If this fails for some reason, it may indicate - failure with a 0 return value. - This is used in two distinct though related cases. The first - is when the VM finds a clean page with no active users and - wants to make it a free page. If ->releasepage succeeds, the - page will be removed from the address_space and become free. - - The second case if when a request has been made to invalidate - some or all pages in an address_space. This can happen - through the fadvice(POSIX_FADV_DONTNEED) system call or by the - filesystem explicitly requesting it as nfs and 9fs do (when - they believe the cache may be out of date with storage) by - calling invalidate_inode_pages2(). - If the filesystem makes such a call, and needs to be certain - that all pages are invalidated, then its releasepage will - need to ensure this. Possibly it can clear the PageUptodate - bit if it cannot free private data yet. - - direct_IO: called by the generic read/write routines to perform - direct_IO - that is IO requests which bypass the page cache - and transfer data directly between the storage and the - application's address space. + physical block number. This method is use by for the legacy FIBMAP + ioctl. Other uses are discouraged. + + invalidatepage: called by the VM on truncate to disassociate a page from its + address_space mapping. + + releasepage: called by the VFS to release filesystem specific metadata from + a page. + + direct_IO: called by the VM for direct I/O writes and reads. get_xip_page: called by the VM to translate a block number to a page. The page is valid until the corresponding filesystem is unmounted. Filesystems that want to use execute-in-place (XIP) need to implement it. An example implementation can be found in fs/ext2/xip.c. - migrate_page: This is used to compact the physical memory usage. - If the VM wants to relocate a page (maybe off a memory card - that is signalling imminent failure) it will pass a new page - and an old page to this function. migrate_page should - transfer any private data across and update any references - that it has to the page. The File Object =============== @@ -694,7 +521,7 @@ struct file_operations ---------------------- This describes how the VFS can manipulate an open file. As of kernel -2.6.17, the following members are defined: +2.6.13, the following members are defined: struct file_operations { loff_t (*llseek) (struct file *, loff_t, int); @@ -723,10 +550,6 @@ struct file_operations { int (*check_flags)(int); int (*dir_notify)(struct file *filp, unsigned long arg); int (*flock) (struct file *, int, struct file_lock *); - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned -int); - ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned -int); }; Again, all methods are called without any locks being held, unless @@ -794,12 +617,6 @@ otherwise noted. flock: called by the flock(2) system call - splice_write: called by the VFS to splice data from a pipe to a file. This - method is used by the splice(2) system call - - splice_read: called by the VFS to splice data from file to a pipe. This - method is used by the splice(2) system call - Note that the file operations are implemented by the specific filesystem in which the inode resides. When opening a device node (character or block special) most filesystems will call special diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README index e9cc8bb26..43e836c07 100644 --- a/Documentation/firmware_class/README +++ b/Documentation/firmware_class/README @@ -105,3 +105,20 @@ on the setup, so I think that the choice on what firmware to make persistent should be left to userspace. + - Why register_firmware()+__init can be useful: + - For boot devices needing firmware. + - To make the transition easier: + The firmware can be declared __init and register_firmware() + called on module_init. Then the firmware is warranted to be + there even if "firmware hotplug userspace" is not there yet or + it doesn't yet provide the needed firmware. + Once the firmware is widely available in userspace, it can be + removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE). + + In either case, if firmware hotplug support is there, it can move the + firmware out of kernel memory into the real filesystem for later + usage. + + Note: If persistence is implemented on top of initramfs, + register_firmware() may not be appropriate. + diff --git a/Documentation/firmware_class/firmware_sample_driver.c b/Documentation/firmware_class/firmware_sample_driver.c index 87feccdb5..d3ad2c244 100644 --- a/Documentation/firmware_class/firmware_sample_driver.c +++ b/Documentation/firmware_class/firmware_sample_driver.c @@ -5,6 +5,8 @@ * * Sample code on how to use request_firmware() from drivers. * + * Note that register_firmware() is currently useless. + * */ #include @@ -15,7 +17,13 @@ #include "linux/firmware.h" +#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE +#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE +char __init inkernel_firmware[] = "let's say that this is firmware\n"; +#endif + static struct device ghost_device = { + .name = "Ghost Device", .bus_id = "ghost0", }; @@ -84,7 +92,7 @@ static void sample_probe_async(void) { /* Let's say that I can't sleep */ int error; - error = request_firmware_nowait (THIS_MODULE, FW_ACTION_NOHOTPLUG, + error = request_firmware_nowait (THIS_MODULE, "sample_driver_fw", &ghost_device, "my device pointer", sample_probe_async_cont); @@ -97,6 +105,10 @@ static void sample_probe_async(void) static int sample_init(void) { +#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE + register_firmware("sample_driver_fw", inkernel_firmware, + sizeof(inkernel_firmware)); +#endif device_initialize(&ghost_device); /* since there is no real hardware insertion I just call the * sample probe functions here */ diff --git a/Documentation/firmware_class/firmware_sample_firmware_class.c b/Documentation/firmware_class/firmware_sample_firmware_class.c index 9e1b0e405..57b956aec 100644 --- a/Documentation/firmware_class/firmware_sample_firmware_class.c +++ b/Documentation/firmware_class/firmware_sample_firmware_class.c @@ -172,6 +172,7 @@ static void fw_remove_class_device(struct class_device *class_dev) static struct class_device *class_dev; static struct device my_device = { + .name = "Sample Device", .bus_id = "my_dev0", }; diff --git a/Documentation/fujitsu/frv/kernel-ABI.txt b/Documentation/fujitsu/frv/kernel-ABI.txt index 8b0a5fc8b..0ed9b0a77 100644 --- a/Documentation/fujitsu/frv/kernel-ABI.txt +++ b/Documentation/fujitsu/frv/kernel-ABI.txt @@ -1,19 +1,17 @@ - ================================= - INTERNAL KERNEL ABI FOR FR-V ARCH - ================================= - -The internal FRV kernel ABI is not quite the same as the userspace ABI. A -number of the registers are used for special purposed, and the ABI is not -consistent between modules vs core, and MMU vs no-MMU. - -This partly stems from the fact that FRV CPUs do not have a separate -supervisor stack pointer, and most of them do not have any scratch -registers, thus requiring at least one general purpose register to be -clobbered in such an event. Also, within the kernel core, it is possible to -simply jump or call directly between functions using a relative offset. -This cannot be extended to modules for the displacement is likely to be too -far. Thus in modules the address of a function to call must be calculated -in a register and then used, requiring two extra instructions. + ================================= + INTERNAL KERNEL ABI FOR FR-V ARCH + ================================= + +The internal FRV kernel ABI is not quite the same as the userspace ABI. A number of the registers +are used for special purposed, and the ABI is not consistent between modules vs core, and MMU vs +no-MMU. + +This partly stems from the fact that FRV CPUs do not have a separate supervisor stack pointer, and +most of them do not have any scratch registers, thus requiring at least one general purpose +register to be clobbered in such an event. Also, within the kernel core, it is possible to simply +jump or call directly between functions using a relative offset. This cannot be extended to modules +for the displacement is likely to be too far. Thus in modules the address of a function to call +must be calculated in a register and then used, requiring two extra instructions. This document has the following sections: @@ -41,8 +39,7 @@ When a system call is made, the following registers are effective: CPU OPERATING MODES =================== -The FR-V CPU has three basic operating modes. In order of increasing -capability: +The FR-V CPU has three basic operating modes. In order of increasing capability: (1) User mode. @@ -50,46 +47,42 @@ capability: (2) Kernel mode. - Normal kernel mode. There are many additional control registers - available that may be accessed in this mode, in addition to all the - stuff available to user mode. This has two submodes: + Normal kernel mode. There are many additional control registers available that may be + accessed in this mode, in addition to all the stuff available to user mode. This has two + submodes: (a) Exceptions enabled (PSR.T == 1). - Exceptions will invoke the appropriate normal kernel mode - handler. On entry to the handler, the PSR.T bit will be cleared. + Exceptions will invoke the appropriate normal kernel mode handler. On entry to the + handler, the PSR.T bit will be cleared. (b) Exceptions disabled (PSR.T == 0). - No exceptions or interrupts may happen. Any mandatory exceptions - will cause the CPU to halt unless the CPU is told to jump into - debug mode instead. + No exceptions or interrupts may happen. Any mandatory exceptions will cause the CPU to + halt unless the CPU is told to jump into debug mode instead. (3) Debug mode. - No exceptions may happen in this mode. Memory protection and - management exceptions will be flagged for later consideration, but - the exception handler won't be invoked. Debugging traps such as - hardware breakpoints and watchpoints will be ignored. This mode is - entered only by debugging events obtained from the other two modes. + No exceptions may happen in this mode. Memory protection and management exceptions will be + flagged for later consideration, but the exception handler won't be invoked. Debugging traps + such as hardware breakpoints and watchpoints will be ignored. This mode is entered only by + debugging events obtained from the other two modes. - All kernel mode registers may be accessed, plus a few extra debugging - specific registers. + All kernel mode registers may be accessed, plus a few extra debugging specific registers. ================================= INTERNAL KERNEL-MODE REGISTER ABI ================================= -There are a number of permanent register assignments that are set up by -entry.S in the exception prologue. Note that there is a complete set of -exception prologues for each of user->kernel transition and kernel->kernel -transition. There are also user->debug and kernel->debug mode transition -prologues. +There are a number of permanent register assignments that are set up by entry.S in the exception +prologue. Note that there is a complete set of exception prologues for each of user->kernel +transition and kernel->kernel transition. There are also user->debug and kernel->debug mode +transition prologues. REGISTER FLAVOUR USE - =============== ======= ============================================== + =============== ======= ==================================================== GR1 Supervisor stack pointer GR15 Current thread info pointer GR16 GP-Rel base register for small data @@ -99,12 +92,10 @@ prologues. GR31 NOMMU Destroyed by debug mode entry GR31 MMU Destroyed by TLB miss kernel mode entry CCR.ICC2 Virtual interrupt disablement tracking - CCCR.CC3 Cleared by exception prologue - (atomic op emulation) + CCCR.CC3 Cleared by exception prologue (atomic op emulation) SCR0 MMU See mmu-layout.txt. SCR1 MMU See mmu-layout.txt. - SCR2 MMU Save for EAR0 (destroyed by icache insns - in debug mode) + SCR2 MMU Save for EAR0 (destroyed by icache insns in debug mode) SCR3 MMU Save for GR31 during debug exceptions DAMR/IAMR NOMMU Fixed memory protection layout. DAMR/IAMR MMU See mmu-layout.txt. @@ -113,21 +104,18 @@ prologues. Certain registers are also used or modified across function calls: REGISTER CALL RETURN - =============== =============================== ====================== + =============== =============================== =============================== GR0 Fixed Zero - GR2 Function call frame pointer GR3 Special Preserved GR3-GR7 - Clobbered - GR8 Function call arg #1 Return value - (or clobbered) - GR9 Function call arg #2 Return value MSW - (or clobbered) + GR8 Function call arg #1 Return value (or clobbered) + GR9 Function call arg #2 Return value MSW (or clobbered) GR10-GR13 Function call arg #3-#6 Clobbered GR14 - Clobbered GR15-GR16 Special Preserved GR17-GR27 - Preserved - GR28-GR31 Special Only accessed - explicitly + GR28-GR31 Special Only accessed explicitly LR Return address after CALL Clobbered CCR/CCCR - Mostly Clobbered @@ -136,53 +124,46 @@ Certain registers are also used or modified across function calls: INTERNAL DEBUG-MODE REGISTER ABI ================================ -This is the same as the kernel-mode register ABI for functions calls. The -difference is that in debug-mode there's a different stack and a different -exception frame. Almost all the global registers from kernel-mode -(including the stack pointer) may be changed. +This is the same as the kernel-mode register ABI for functions calls. The difference is that in +debug-mode there's a different stack and a different exception frame. Almost all the global +registers from kernel-mode (including the stack pointer) may be changed. REGISTER FLAVOUR USE - =============== ======= ============================================== + =============== ======= ==================================================== GR1 Debug stack pointer GR16 GP-Rel base register for small data - GR31 Current debug exception frame pointer - (__debug_frame) + GR31 Current debug exception frame pointer (__debug_frame) SCR3 MMU Saved value of GR31 -Note that debug mode is able to interfere with the kernel's emulated atomic -ops, so it must be exceedingly careful not to do any that would interact -with the main kernel in this regard. Hence the debug mode code (gdbstub) is -almost completely self-contained. The only external code used is the -sprintf family of functions. +Note that debug mode is able to interfere with the kernel's emulated atomic ops, so it must be +exceedingly careful not to do any that would interact with the main kernel in this regard. Hence +the debug mode code (gdbstub) is almost completely self-contained. The only external code used is +the sprintf family of functions. -Futhermore, break.S is so complicated because single-step mode does not -switch off on entry to an exception. That means unless manually disabled, -single-stepping will blithely go on stepping into things like interrupts. -See gdbstub.txt for more information. +Futhermore, break.S is so complicated because single-step mode does not switch off on entry to an +exception. That means unless manually disabled, single-stepping will blithely go on stepping into +things like interrupts. See gdbstub.txt for more information. ========================== VIRTUAL INTERRUPT HANDLING ========================== -Because accesses to the PSR is so slow, and to disable interrupts we have -to access it twice (once to read and once to write), we don't actually -disable interrupts at all if we don't have to. What we do instead is use -the ICC2 condition code flags to note virtual disablement, such that if we -then do take an interrupt, we note the flag, really disable interrupts, set -another flag and resume execution at the point the interrupt happened. -Setting condition flags as a side effect of an arithmetic or logical -instruction is really fast. This use of the ICC2 only occurs within the +Because accesses to the PSR is so slow, and to disable interrupts we have to access it twice (once +to read and once to write), we don't actually disable interrupts at all if we don't have to. What +we do instead is use the ICC2 condition code flags to note virtual disablement, such that if we +then do take an interrupt, we note the flag, really disable interrupts, set another flag and resume +execution at the point the interrupt happened. Setting condition flags as a side effect of an +arithmetic or logical instruction is really fast. This use of the ICC2 only occurs within the kernel - it does not affect userspace. The flags we use are: (*) CCR.ICC2.Z [Zero flag] - Set to virtually disable interrupts, clear when interrupts are - virtually enabled. Can be modified by logical instructions without - affecting the Carry flag. + Set to virtually disable interrupts, clear when interrupts are virtually enabled. Can be + modified by logical instructions without affecting the Carry flag. (*) CCR.ICC2.C [Carry flag] @@ -195,9 +176,8 @@ What happens is this: ICC2.Z is 0, ICC2.C is 1. - (2) An interrupt occurs. The exception prologue examines ICC2.Z and - determines that nothing needs doing. This is done simply with an - unlikely BEQ instruction. + (2) An interrupt occurs. The exception prologue examines ICC2.Z and determines that nothing needs + doing. This is done simply with an unlikely BEQ instruction. (3) The interrupts are disabled (local_irq_disable) @@ -207,56 +187,48 @@ What happens is this: ICC2.Z would be set to 0. - A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would - be used to trap if interrupts were now virtually enabled, but - physically disabled - which they're not, so the trap isn't taken. The - kernel would then be back to state (1). + A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would be used to trap if + interrupts were now virtually enabled, but physically disabled - which they're not, so the + trap isn't taken. The kernel would then be back to state (1). - (5) An interrupt occurs. The exception prologue examines ICC2.Z and - determines that the interrupt shouldn't actually have happened. It - jumps aside, and there disabled interrupts by setting PSR.PIL to 14 - and then it clears ICC2.C. + (5) An interrupt occurs. The exception prologue examines ICC2.Z and determines that the interrupt + shouldn't actually have happened. It jumps aside, and there disabled interrupts by setting + PSR.PIL to 14 and then it clears ICC2.C. (6) If interrupts were then saved and disabled again (local_irq_save): - ICC2.Z would be shifted into the save variable and masked off - (giving a 1). + ICC2.Z would be shifted into the save variable and masked off (giving a 1). - ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be - unaffected (ie: 0). + ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be unaffected (ie: 0). (7) If interrupts were then restored from state (6) (local_irq_restore): - ICC2.Z would be set to indicate the result of XOR'ing the saved - value (ie: 1) with 1, which gives a result of 0 - thus leaving - ICC2.Z set. + ICC2.Z would be set to indicate the result of XOR'ing the saved value (ie: 1) with 1, which + gives a result of 0 - thus leaving ICC2.Z set. ICC2.C would remain unaffected (ie: 0). - A TIHI #2 instruction would be used to again assay the current state, - but this would do nothing as Z==1. + A TIHI #2 instruction would be used to again assay the current state, but this would do + nothing as Z==1. (8) If interrupts were then enabled (local_irq_enable): - ICC2.Z would be cleared. ICC2.C would be left unaffected. Both - flags would now be 0. + ICC2.Z would be cleared. ICC2.C would be left unaffected. Both flags would now be 0. - A TIHI #2 instruction again issued to assay the current state would - then trap as both Z==0 [interrupts virtually enabled] and C==0 - [interrupts really disabled] would then be true. + A TIHI #2 instruction again issued to assay the current state would then trap as both Z==0 + [interrupts virtually enabled] and C==0 [interrupts really disabled] would then be true. - (9) The trap #2 handler would simply enable hardware interrupts - (set PSR.PIL to 0), set ICC2.C to 1 and return. + (9) The trap #2 handler would simply enable hardware interrupts (set PSR.PIL to 0), set ICC2.C to + 1 and return. (10) Immediately upon returning, the pending interrupt would be taken. -(11) The interrupt handler would take the path of actually processing the - interrupt (ICC2.Z is clear, BEQ fails as per step (2)). +(11) The interrupt handler would take the path of actually processing the interrupt (ICC2.Z is + clear, BEQ fails as per step (2)). -(12) The interrupt handler would then set ICC2.C to 1 since hardware - interrupts are definitely enabled - or else the kernel wouldn't be here. +(12) The interrupt handler would then set ICC2.C to 1 since hardware interrupts are definitely + enabled - or else the kernel wouldn't be here. (13) On return from the interrupt handler, things would be back to state (1). -This trap (#2) is only available in kernel mode. In user mode it will -result in SIGILL. +This trap (#2) is only available in kernel mode. In user mode it will result in SIGILL. diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf index 792231921..bbeaba680 100644 --- a/Documentation/hwmon/w83627hf +++ b/Documentation/hwmon/w83627hf @@ -18,10 +18,6 @@ Supported chips: Prefix: 'w83637hf' Addresses scanned: ISA address retrieved from Super I/O registers Datasheet: http://www.winbond.com/PDF/sheet/w83637hf.pdf - * Winbond W83687THF - Prefix: 'w83687thf' - Addresses scanned: ISA address retrieved from Super I/O registers - Datasheet: Provided by Winbond on request Authors: Frodo Looijaard , diff --git a/Documentation/hwmon/w83781d b/Documentation/hwmon/w83781d index b1e9f8009..e5459333b 100644 --- a/Documentation/hwmon/w83781d +++ b/Documentation/hwmon/w83781d @@ -36,11 +36,6 @@ Module parameters Use 'init=0' to bypass initializing the chip. Try this if your computer crashes when you load the module. -* reset int - (default 0) - The driver used to reset the chip on load, but does no more. Use - 'reset=1' to restore the old behavior. Report if you need to do this. - force_subclients=bus,caddr,saddr,saddr This is used to force the i2c addresses for subclients of a certain chip. Typical usage is `force_subclients=0,0x2d,0x4a,0x4b' @@ -128,25 +123,6 @@ When an alarm goes off, you can be warned by a beeping signal through your computer speaker. It is possible to enable all beeping globally, or only the beeping for some alarms. -Individual alarm and beep bits: - -0x000001: in0 -0x000002: in1 -0x000004: in2 -0x000008: in3 -0x000010: temp1 -0x000020: temp2 (+temp3 on W83781D) -0x000040: fan1 -0x000080: fan2 -0x000100: in4 -0x000200: in5 -0x000400: in6 -0x000800: fan3 -0x001000: chassis -0x002000: temp3 (W83782D and W83627HF only) -0x010000: in7 (W83782D and W83627HF only) -0x020000: in8 (W83782D and W83627HF only) - If an alarm triggers, it will remain triggered until the hardware register is read at least once. This means that the cause for the alarm may already have disappeared! Note that in the current implementation, all diff --git a/Documentation/i2c/busses/i2c-parport b/Documentation/i2c/busses/i2c-parport index 9f1d0082d..d9f23c076 100644 --- a/Documentation/i2c/busses/i2c-parport +++ b/Documentation/i2c/busses/i2c-parport @@ -17,6 +17,7 @@ It currently supports the following devices: * Velleman K8000 adapter * ELV adapter * Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032) + * Barco LPT->DVI (K5800236) adapter These devices use different pinout configurations, so you have to tell the driver what you have, using the type module parameter. There is no diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4 index a1c8f581a..856b4b8b9 100644 --- a/Documentation/i2c/busses/i2c-piix4 +++ b/Documentation/i2c/busses/i2c-piix4 @@ -4,7 +4,7 @@ Supported adapters: * Intel 82371AB PIIX4 and PIIX4E * Intel 82443MX (440MX) Datasheet: Publicly available at the Intel website - * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges + * ServerWorks OSB4, CSB5 and CSB6 southbridges Datasheet: Only available via NDA from ServerWorks * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge Datasheet: Publicly available at the SMSC website http://www.smsc.com diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro index 702f5ac68..25680346e 100644 --- a/Documentation/i2c/busses/i2c-viapro +++ b/Documentation/i2c/busses/i2c-viapro @@ -4,17 +4,19 @@ Supported adapters: * VIA Technologies, Inc. VT82C596A/B Datasheet: Sometimes available at the VIA website - * VIA Technologies, Inc. VT82C686A/B + * VIA Technologies, Inc. VT82C686A/B Datasheet: Sometimes available at the VIA website - * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237 - Datasheet: available on request from Via + * VIA Technologies, Inc. VT8231, VT8233, VT8233A + Datasheet: available on request from VIA + + * VIA Technologies, Inc. VT8235, VT8237R, VT8237A, VT8251 + Datasheet: available on request and under NDA from VIA Authors: - Frodo Looijaard , - Philip Edelbrock , - Kyösti Mälkki , - Mark D. Studebaker + Kyösti Mälkki , + Mark D. Studebaker , + Jean Delvare Module Parameters ----------------- @@ -28,20 +30,24 @@ Description ----------- i2c-viapro is a true SMBus host driver for motherboards with one of the -supported VIA southbridges. +supported VIA south bridges. Your lspci -n listing must show one of these : - device 1106:3050 (VT82C596 function 3) - device 1106:3051 (VT82C596 function 3) + device 1106:3050 (VT82C596A function 3) + device 1106:3051 (VT82C596B function 3) device 1106:3057 (VT82C686 function 4) device 1106:3074 (VT8233) device 1106:3147 (VT8233A) - device 1106:8235 (VT8231) - devide 1106:3177 (VT8235) - devide 1106:3227 (VT8237) + device 1106:8235 (VT8231 function 4) + device 1106:3177 (VT8235) + device 1106:3227 (VT8237R) + device 1106:3337 (VT8237A) + device 1106:3287 (VT8251) If none of these show up, you should look in the BIOS for settings like enable ACPI / SMBus or even USB. - +Except for the oldest chips (VT82C596A/B, VT82C686A and most probably +VT8231), this driver supports I2C block transactions. Such transactions +are mainly useful to read from and write to EEPROMs. diff --git a/Documentation/i2c/busses/scx200_acb b/Documentation/i2c/busses/scx200_acb index f50e69981..08c8cd1df 100644 --- a/Documentation/i2c/busses/scx200_acb +++ b/Documentation/i2c/busses/scx200_acb @@ -6,10 +6,9 @@ Module Parameters ----------------- * base: int - Base addresses for the ACCESS.bus controllers on SCx200 and SC1100 devices + Base addresses for the ACCESS.bus controllers Description ----------- -Enable the use of the ACCESS.bus controller on the Geode SCx200 and -SC1100 processors and the CS5535 and CS5536 Geode companion devices. +Enable the use of the ACCESS.bus controllers of a SCx200 processor. diff --git a/Documentation/input/joystick-parport.txt b/Documentation/input/joystick-parport.txt index d537c48cc..88a011c9f 100644 --- a/Documentation/input/joystick-parport.txt +++ b/Documentation/input/joystick-parport.txt @@ -36,12 +36,12 @@ with them. All NES and SNES use the same synchronous serial protocol, clocked from the computer's side (and thus timing insensitive). To allow up to 5 NES -and/or SNES gamepads and/or SNES mice connected to the parallel port at once, -the output lines of the parallel port are shared, while one of 5 available -input lines is assigned to each gamepad. +and/or SNES gamepads connected to the parallel port at once, the output +lines of the parallel port are shared, while one of 5 available input lines +is assigned to each gamepad. This protocol is handled by the gamecon.c driver, so that's the one -you'll use for NES, SNES gamepads and SNES mice. +you'll use for NES and SNES gamepads. The main problem with PC parallel ports is that they don't have +5V power source on any of their pins. So, if you want a reliable source of power @@ -106,7 +106,7 @@ A, Turbo B, Select and Start, and is connected through 5 wires, then it is either a NES or NES clone and will work with this connection. SNES gamepads also use 5 wires, but have more buttons. They will work as well, of course. -Pinout for NES gamepads Pinout for SNES gamepads and mice +Pinout for NES gamepads Pinout for SNES gamepads +----> Power +-----------------------\ | 7 | o o o o | x x o | 1 @@ -454,7 +454,6 @@ uses the following kernel/module command line: 6 | N64 pad 7 | Sony PSX controller 8 | Sony PSX DDR controller - 9 | SNES mouse The exact type of the PSX controller type is autoprobed when used so hot swapping should work (but is not recomended). diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt index 171a44ebd..aa7ba00ec 100644 --- a/Documentation/ioctl-number.txt +++ b/Documentation/ioctl-number.txt @@ -78,6 +78,8 @@ Code Seq# Include File Comments '#' 00-3F IEEE 1394 Subsystem Block for the entire subsystem '1' 00-1F PPS kit from Ulrich Windl +'6' 00-10 Intel IA32 microcode update driver + '8' all SNP8023 advanced NIC card 'A' 00-1F linux/apm_bios.h diff --git a/Documentation/isdn/README.gigaset b/Documentation/isdn/README.gigaset deleted file mode 100644 index 85a64defd..000000000 --- a/Documentation/isdn/README.gigaset +++ /dev/null @@ -1,286 +0,0 @@ -GigaSet 307x Device Driver -========================== - -1. Requirements - ------------ -1.1. Hardware - -------- - This release supports the connection of the Gigaset 307x/417x family of - ISDN DECT bases via Gigaset M101 Data, Gigaset M105 Data or direct USB - connection. The following devices are reported to be compatible: - 307x/417x: - Gigaset SX255isdn - Gigaset SX353isdn - Sinus 45 [AB] isdn (Deutsche Telekom) - Sinus 721X/XA - Vox Chicago 390 ISDN (KPN Telecom) - M101: - Sinus 45 Data 1 (Telekom) - M105: - Gigaset USB Adapter DECT - Sinus 45 Data 2 (Telekom) - Sinus 721 data - Chicago 390 USB (KPN) - See also http://www.erbze.info/sinus_gigaset.htm and - http://gigaset307x.sourceforge.net/ - - We had also reports from users of Gigaset M105 who could use the drivers - with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.4.) - If you have another device that works with our driver, please let us know. - For example, Gigaset SX205isdn/Sinus 721 X SE and Gigaset SX303isdn bases - are just versions without answering machine of models known to work, so - they should work just as well; but so far we are lacking positive reports - on these. - - Chances of getting an USB device to work are good if the output of - lsusb - at the command line contains one of the following: - ID 0681:0001 - ID 0681:0002 - ID 0681:0009 - ID 0681:0021 - ID 0681:0022 - -1.2. Software - -------- - The driver works with ISDN4linux and so can be used with any software - which is able to use ISDN4linux for ISDN connections (voice or data). - CAPI4Linux support is planned but not yet available. - - There are some user space tools available at - http://sourceforge.net/projects/gigaset307x/ - which provide access to additional device specific functions like SMS, - phonebook or call journal. - - -2. How to use the 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 usb_gigaset (M105) or bas_gigaset (direct USB - connection to the base). - -2.2. Device nodes for user space programs - ------------------------------------ - The device can be accessed from user space (eg. by the user space tools - mentioned in 1.2.) through the device nodes: - - - /dev/ttyGU0 for M105 (USB data boxes) - - /dev/ttyGB0 for the base driver (direct USB connection) - - You can also select a "default device" which is used by the frontends when - no device node is given as parameter, by creating a symlink /dev/ttyG to - one of them, eg.: - - ln -s /dev/ttyGB0 /dev/ttyG - -2.3. ISDN4linux - ---------- - This is the "normal" mode of operation. After loading the module you can - set up the ISDN system just as you'd do with any ISDN card. - Your distribution should provide some configuration utility. - If not, you can use some HOWTOs like - http://www.linuxhaven.de/dlhp/HOWTO/DE-ISDN-HOWTO-5.html - If this doesn't work, because you have some recent device like SX100 where - debug output (see section 3.2.) shows something like this when dialing - CMD Received: ERROR - Available Params: 0 - Connection State: 0, Response: -1 - gigaset_process_response: resp_code -1 in ConState 0 ! - Timeout occurred - you might need to use unimodem mode: - -2.4. Unimodem mode - ------------- - This is needed for some devices [e.g. SX100] as they have problems with - the "normal" commands. - - If you have installed the command line tool gigacontr, you can enter - unimodem mode using - gigacontr --mode unimodem - You can switch back using - gigacontr --mode isdn - - You can also load the driver using e.g. - modprobe usb_gigaset startmode=0 - to prevent the driver from starting in "isdn4linux mode". - - In this mode the device works like a modem connected to a serial port - (the /dev/ttyGU0, ... mentioned above) which understands the commands - ATZ init, reset - => OK or ERROR - ATD - ATDT dial - => OK, CONNECT, - BUSY, - NO DIAL TONE, - NO CARRIER, - NO ANSWER - +++ change to command mode when connected - ATH hangup - - You can use some configuration tool of your distribution to configure this - "modem" or configure pppd/wvdial manually. There are some example ppp - configuration files and chat scripts in the gigaset-VERSION/ppp directory. - Please note that the USB drivers are not able to change the state of the - control lines (the M105 driver can be configured to use some undocumented - control requests, if you really need the control lines, though). This means - you must use "Stupid Mode" if you are using wvdial or you should use the - nocrtscts option of pppd. - You must also assure that the ppp_async module is loaded with the parameter - flag_time=0. You can do this e.g. by adding a line like - - options ppp_async flag_time=0 - - to /etc/modprobe.conf. If your distribution has some local module - configuration file like /etc/modprobe.conf.local, - using that should be preferred. - -2.5. Call-ID (CID) mode - ------------------ - Call-IDs are numbers used to tag commands to, and responses from, the - Gigaset base in order to support the simultaneous handling of multiple - ISDN calls. Their use can be enabled ("CID mode") or disabled ("Unimodem - mode"). Without Call-IDs (in Unimodem mode), only a very limited set of - functions is available. It allows outgoing data connections only, but - does not signal incoming calls or other base events. - - DECT cordless data devices (M10x) permanently occupy the cordless - connection to the base while Call-IDs are activated. As the Gigaset - bases only support one DECT data connection at a time, this prevents - other DECT cordless data devices from accessing the base. - - During active operation, the driver switches to the necessary mode - automatically. However, for the reasons above, the mode chosen when - the device is not in use (idle) can be selected by the user. - - If you want to receive incoming calls, you can use the default - settings (CID mode). - - If you have several DECT data devices (M10x) which you want to use - in turn, select Unimodem mode by passing the parameter "cidmode=0" to - the driver ("modprobe usb_gigaset cidmode=0" or modprobe.conf). - - If you want both of these at once, you are out of luck. - - You can also use /sys/module//parameters/cidmode for changing - the CID mode setting ( is usb_gigaset or bas_gigaset). - - -3. Troubleshooting - --------------- -3.1. Solutions to frequently reported problems - ----------------------------------------- - Problem: - You have a slow provider and isdn4linux gives up dialing too early. - Solution: - Load the isdn module using the dialtimeout option. You can do this e.g. - by adding a line like - - options isdn dialtimeout=15 - - to /etc/modprobe.conf. If your distribution has some local module - configuration file like /etc/modprobe.conf.local, - using that should be preferred. - - Problem: - Your isdn script aborts with a message about isdnlog. - Solution: - Try deactivating (or commenting out) isdnlog. This driver does not - support it. - - Problem: - You have two or more DECT data adapters (M101/M105) and only the - first one you turn on works. - Solution: - Select Unimodem mode for all DECT data adapters. (see section 2.4.) - -3.2. Telling the driver to provide more information - ---------------------------------------------- - Building the driver with the "Gigaset debugging" kernel configuration - option (CONFIG_GIGASET_DEBUG) gives it the ability to produce additional - information useful for debugging. - - You can control the amount of debugging information the driver produces by - writing an appropriate value to /sys/module/gigaset/parameters/debug, e.g. - echo 0 > /sys/module/gigaset/parameters/debug - switches off debugging output completely, - echo 0x10a020 > /sys/module/gigaset/parameters/debug - enables the standard set of debugging output messages. These values are - bit patterns where every bit controls a certain type of debugging output. - See the constants DEBUG_* in the source file gigaset.h for details. - - The initial value can be set using the debug parameter when loading the - module "gigaset", e.g. by adding a line - options gigaset debug=0 - to /etc/modprobe.conf, ... - - Generated debugging information can be found - - as output of the command - dmesg - - in system log files written by your syslog daemon, usually - in /var/log/, e.g. /var/log/messages. - -3.3. Reporting problems and bugs - --------------------------- - If you can't solve problems with the driver on your own, feel free to - use one of the forums, bug trackers, or mailing lists on - http://sourceforge.net/projects/gigaset307x - or write an electronic mail to the maintainers. - - Try to provide as much information as possible, such as - - distribution - - kernel version (uname -r) - - gcc version (gcc --version) - - hardware architecture (uname -m, ...) - - type and firmware version of your device (base and wireless module, - if any) - - output of "lsusb -v" (if using an USB device) - - error messages - - relevant system log messages (it would help if you activate debug - output as described in 3.2.) - - For help with general configuration problems not specific to our driver, - such as isdn4linux and network configuration issues, please refer to the - appropriate forums and newsgroups. - -3.4. Reporting problem solutions - --------------------------- - If you solved a problem with our drivers, wrote startup scripts for your - distribution, ... feel free to contact us (using one of the places - mentioned in 3.3.). We'd like to add scripts, hints, documentation - to the driver and/or the project web page. - - -4. Links, other software - --------------------- - - Sourceforge project developing this driver and associated tools - http://sourceforge.net/projects/gigaset307x - - Yahoo! Group on the Siemens Gigaset family of devices - http://de.groups.yahoo.com/group/Siemens-Gigaset - - Siemens Gigaset/T-Sinus compatibility table - http://www.erbze.info/sinus_gigaset.htm - - -5. Credits - ------- - Thanks to - - Karsten Keil - for his help with isdn4linux - Deti Fliegl - for his base driver code - Dennis Dietrich - for his kernel 2.6 patches - Andreas Rummel - for his work and logs to get unimodem mode working - Andreas Degert - for his logs and patches to get cx 100 working - Dietrich Feist - for his generous donation of one M105 and two M101 cordless adapters - Christoph Schweers - for his generous donation of a M34 device - - and all the other people who sent logs and other information. - diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index a9c00facd..443230b43 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -17,7 +17,6 @@ This document describes the Linux kernel Makefiles. --- 3.8 Command line dependency --- 3.9 Dependency tracking --- 3.10 Special Rules - --- 3.11 $(CC) support functions === 4 Host Program support --- 4.1 Simple Host Program @@ -39,6 +38,7 @@ This document describes the Linux kernel Makefiles. --- 6.6 Commands useful for building a boot image --- 6.7 Custom kbuild commands --- 6.8 Preprocessing linker scripts + --- 6.9 $(CC) support functions === 7 Kbuild Variables === 8 Makefile language @@ -106,9 +106,9 @@ This document is aimed towards normal developers and arch developers. Most Makefiles within the kernel are kbuild Makefiles that use the kbuild infrastructure. This chapter introduce the syntax used in the kbuild makefiles. -The preferred name for the kbuild files are 'Makefile' but 'Kbuild' can -be used and if both a 'Makefile' and a 'Kbuild' file exists then the 'Kbuild' -file will be used. +The preferred name for the kbuild files is 'Kbuild' but 'Makefile' will +continue to be supported. All new developmen is expected to use the +Kbuild filename. Section 3.1 "Goal definitions" is a quick intro, further chapters provide more details, with real examples. @@ -385,102 +385,6 @@ more details, with real examples. to prerequisites are referenced with $(src) (because they are not generated files). ---- 3.11 $(CC) support functions - - The kernel may be build with several different versions of - $(CC), each supporting a unique set of features and options. - kbuild provide basic support to check for valid options for $(CC). - $(CC) is useally the gcc compiler, but other alternatives are - available. - - as-option - as-option is used to check if $(CC) when used to compile - assembler (*.S) files supports the given option. An optional - second option may be specified if first option are not supported. - - Example: - #arch/sh/Makefile - cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) - - In the above example cflags-y will be assinged the the option - -Wa$(comma)-isa=$(isa-y) if it is supported by $(CC). - The second argument is optional, and if supplied will be used - if first argument is not supported. - - cc-option - cc-option is used to check if $(CC) support a given option, and not - supported to use an optional second option. - - Example: - #arch/i386/Makefile - cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586) - - In the above example cflags-y will be assigned the option - -march=pentium-mmx if supported by $(CC), otherwise -march-i586. - The second argument to cc-option is optional, and if omitted - cflags-y will be assigned no value if first option is not supported. - - cc-option-yn - cc-option-yn is used to check if gcc supports a given option - and return 'y' if supported, otherwise 'n'. - - Example: - #arch/ppc/Makefile - biarch := $(call cc-option-yn, -m32) - aflags-$(biarch) += -a32 - cflags-$(biarch) += -m32 - - In the above example $(biarch) is set to y if $(CC) supports the -m32 - option. When $(biarch) equals to y the expanded variables $(aflags-y) - and $(cflags-y) will be assigned the values -a32 and -m32. - - cc-option-align - gcc version >= 3.0 shifted type of options used to speify - alignment of functions, loops etc. $(cc-option-align) whrn used - as prefix to the align options will select the right prefix: - gcc < 3.00 - cc-option-align = -malign - gcc >= 3.00 - cc-option-align = -falign - - Example: - CFLAGS += $(cc-option-align)-functions=4 - - In the above example the option -falign-functions=4 is used for - gcc >= 3.00. For gcc < 3.00 -malign-functions=4 is used. - - cc-version - cc-version return a numerical version of the $(CC) compiler version. - The format is where both are two digits. So for example - gcc 3.41 would return 0341. - cc-version is useful when a specific $(CC) version is faulty in one - area, for example the -mregparm=3 were broken in some gcc version - even though the option was accepted by gcc. - - Example: - #arch/i386/Makefile - cflags-y += $(shell \ - if [ $(call cc-version) -ge 0300 ] ; then \ - echo "-mregparm=3"; fi ;) - - In the above example -mregparm=3 is only used for gcc version greater - than or equal to gcc 3.0. - - cc-ifversion - cc-ifversion test the version of $(CC) and equals last argument if - version expression is true. - - Example: - #fs/reiserfs/Makefile - EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0402, -O1) - - In this example EXTRA_CFLAGS will be assigned the value -O1 if the - $(CC) version is less than 4.2. - cc-ifversion takes all the shell operators: - -eq, -ne, -lt, -le, -gt, and -ge - The third parameter may be a text as in this example, but it may also - be an expanded variable or a macro. - === 4 Host Program support @@ -1069,6 +973,74 @@ When kbuild executes the following steps are followed (roughly): architecture specific files. +--- 6.9 $(CC) support functions + + The kernel may be build with several different versions of + $(CC), each supporting a unique set of features and options. + kbuild provide basic support to check for valid options for $(CC). + $(CC) is useally the gcc compiler, but other alternatives are + available. + + cc-option + cc-option is used to check if $(CC) support a given option, and not + supported to use an optional second option. + + Example: + #arch/i386/Makefile + cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586) + + In the above example cflags-y will be assigned the option + -march=pentium-mmx if supported by $(CC), otherwise -march-i586. + The second argument to cc-option is optional, and if omitted + cflags-y will be assigned no value if first option is not supported. + + cc-option-yn + cc-option-yn is used to check if gcc supports a given option + and return 'y' if supported, otherwise 'n'. + + Example: + #arch/ppc/Makefile + biarch := $(call cc-option-yn, -m32) + aflags-$(biarch) += -a32 + cflags-$(biarch) += -m32 + + In the above example $(biarch) is set to y if $(CC) supports the -m32 + option. When $(biarch) equals to y the expanded variables $(aflags-y) + and $(cflags-y) will be assigned the values -a32 and -m32. + + cc-option-align + gcc version >= 3.0 shifted type of options used to speify + alignment of functions, loops etc. $(cc-option-align) whrn used + as prefix to the align options will select the right prefix: + gcc < 3.00 + cc-option-align = -malign + gcc >= 3.00 + cc-option-align = -falign + + Example: + CFLAGS += $(cc-option-align)-functions=4 + + In the above example the option -falign-functions=4 is used for + gcc >= 3.00. For gcc < 3.00 -malign-functions=4 is used. + + cc-version + cc-version return a numerical version of the $(CC) compiler version. + The format is where both are two digits. So for example + gcc 3.41 would return 0341. + cc-version is useful when a specific $(CC) version is faulty in one + area, for example the -mregparm=3 were broken in some gcc version + even though the option was accepted by gcc. + + Example: + #arch/i386/Makefile + cflags-y += $(shell \ + if [ $(call cc-version) -ge 0300 ] ; then \ + echo "-mregparm=3"; fi ;) + + In the above example -mregparm=3 is only used for gcc version greater + than or equal to gcc 3.0. + + === 7 Kbuild Variables The top Makefile exports the following variables: diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt index 61fc079eb..7e77f9363 100644 --- a/Documentation/kbuild/modules.txt +++ b/Documentation/kbuild/modules.txt @@ -13,7 +13,6 @@ In this document you will find information about: --- 2.2 Available targets --- 2.3 Available options --- 2.4 Preparing the kernel tree for module build - --- 2.5 Building separate files for a module === 3. Example commands === 4. Creating a kbuild file for an external module === 5. Include files @@ -23,10 +22,7 @@ In this document you will find information about: === 6. Module installation --- 6.1 INSTALL_MOD_PATH --- 6.2 INSTALL_MOD_DIR - === 7. Module versioning & Module.symvers - --- 7.1 Symbols fron the kernel (vmlinux + modules) - --- 7.2 Symbols and external modules - --- 7.3 Symbols from another external module + === 7. Module versioning === 8. Tips & Tricks --- 8.1 Testing for CONFIG_FOO_BAR @@ -44,7 +40,7 @@ What is covered within this file is mainly information to authors of modules. The author of an external modules should supply a makefile that hides most of the complexity so one only has to type 'make' to build the module. A complete example will be present in -chapter 4, "Creating a kbuild file for an external module". +chapter ¤. Creating a kbuild file for an external module". === 2. How to build external modules @@ -92,8 +88,7 @@ when building an external module. make -C $KDIR M=$PWD modules_install Install the external module(s). Installation default is in /lib/modules//extra, - but may be prefixed with INSTALL_MOD_PATH - see separate - chapter. + but may be prefixed with INSTALL_MOD_PATH - see separate chapter. make -C $KDIR M=$PWD clean Remove all generated files for the module - the kernel @@ -136,16 +131,6 @@ when building an external module. Therefore a full kernel build needs to be executed to make module versioning work. ---- 2.5 Building separate files for a module - It is possible to build single files which is part of a module. - This works equal for the kernel, a module and even for external - modules. - Examples (module foo.ko, consist of bar.o, baz.o): - make -C $KDIR M=`pwd` bar.lst - make -C $KDIR M=`pwd` bar.o - make -C $KDIR M=`pwd` foo.ko - make -C $KDIR M=`pwd` / - === 3. Example commands @@ -437,7 +422,7 @@ External modules are installed in the directory: => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf -=== 7. Module versioning & Module.symvers +=== 7. Module versioning Module versioning is enabled by the CONFIG_MODVERSIONS tag. @@ -447,80 +432,11 @@ when a module is loaded/used then the CRC values contained in the kernel are compared with similar values in the module. If they are not equal then the kernel refuses to load the module. -Module.symvers contains a list of all exported symbols from a kernel build. - ---- 7.1 Symbols fron the kernel (vmlinux + modules) - - During a kernel build a file named Module.symvers will be generated. - Module.symvers contains all exported symbols from the kernel and - compiled modules. For each symbols the corresponding CRC value - is stored too. - - The syntax of the Module.symvers file is: - - Sample: - 0x2d036834 scsi_remove_host drivers/scsi/scsi_mod +During a kernel build a file named Module.symvers will be generated. This +file includes the symbol version of all symbols within the kernel. If the +Module.symvers file is saved from the last full kernel compile one does not +have to do a full kernel compile to build a module version's compatible module. - For a kernel build without CONFIG_MODVERSIONING enabled the crc - would read: 0x00000000 - - Module.symvers serve two purposes. - 1) It list all exported symbols both from vmlinux and all modules - 2) It list CRC if CONFIG_MODVERSION is enabled - ---- 7.2 Symbols and external modules - - When building an external module the build system needs access to - the symbols from the kernel to check if all external symbols are - defined. This is done in the MODPOST step and to obtain all - symbols modpost reads Module.symvers from the kernel. - If a Module.symvers file is present in the directory where - the external module is being build this file will be read too. - During the MODPOST step a new Module.symvers file will be written - containing all exported symbols that was not defined in the kernel. - ---- 7.3 Symbols from another external module - - Sometimes one external module uses exported symbols from another - external module. Kbuild needs to have full knowledge on all symbols - to avoid spitting out warnings about undefined symbols. - Two solutions exist to let kbuild know all symbols of more than - one external module. - The method with a top-level kbuild file is recommended but may be - impractical in certain situations. - - Use a top-level Kbuild file - If you have two modules: 'foo', 'bar' and 'foo' needs symbols - from 'bar' then one can use a common top-level kbuild file so - both modules are compiled in same build. - - Consider following directory layout: - ./foo/ <= contains the foo module - ./bar/ <= contains the bar module - The top-level Kbuild file would then look like: - - #./Kbuild: (this file may also be named Makefile) - obj-y := foo/ bar/ - - Executing: - make -C $KDIR M=`pwd` - - will then do the expected and compile both modules with full - knowledge on symbols from both modules. - - Use an extra Module.symvers file - When an external module is build a Module.symvers file is - generated containing all exported symbols which are not - defined in the kernel. - To get access to symbols from module 'bar' one can copy the - Module.symvers file from the compilation of the 'bar' module - to the directory where the 'foo' module is build. - During the module build kbuild will read the Module.symvers - file in the directory of the external module and when the - build is finished a new Module.symvers file is created - containing the sum of all symbols defined and not part of the - kernel. - === 8. Tips & Tricks --- 8.1 Testing for CONFIG_FOO_BAR diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b3a6187e5..fc99075e0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1,4 +1,4 @@ - Kernel Parameters +February 2003 Kernel Parameters v2.5.59 ~~~~~~~~~~~~~~~~~ The following is a consolidated list of the kernel parameters as implemented @@ -17,17 +17,9 @@ are specified on the kernel command line with the module name plus usbcore.blinkenlights=1 -This document may not be entirely up to date and comprehensive. The command -"modinfo -p ${modulename}" shows a current list of all parameters of a loadable -module. Loadable modules, after being loaded into the running kernel, also -reveal their parameters in /sys/module/${modulename}/parameters/. Some of these -parameters may be changed at runtime by the command -"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}". - -The parameters listed below are only valid if certain kernel build options were -enabled and if respective hardware is present. The text in square brackets at -the beginning of each description states the restrictions within which a -parameter is applicable: +The text in square brackets at the beginning of the description states the +restrictions on the kernel for the said kernel parameter to be valid. The +restrictions referred to are that the relevant option is valid if: ACPI ACPI support is enabled. ALSA ALSA sound support is enabled. @@ -57,7 +49,6 @@ parameter is applicable: MCA MCA bus support is enabled. MDA MDA console support is enabled. MOUSE Appropriate mouse support is enabled. - MSI Message Signaled Interrupts (PCI). MTD MTD support is enabled. NET Appropriate network support is enabled. NUMA NUMA support is enabled. @@ -375,17 +366,12 @@ running once the system is up. tty Use the virtual console device . ttyS[,options] - ttyUSB0[,options] Use the specified serial port. The options are of - the form "bbbbpnf", where "bbbb" is the baud rate, - "p" is parity ("n", "o", or "e"), "n" is number of - bits, and "f" is flow control ("r" for RTS or - omit it). Default is "9600n8". + the form "bbbbpn", where "bbbb" is the baud rate, + "p" is parity ("n", "o", or "e"), and "n" is bits. + Default is "9600n8". - See Documentation/serial-console.txt for more - information. See - Documentation/networking/netconsole.txt for an - alternative. + See also Documentation/serial-console.txt. uart,io,[,options] uart,mmio,[,options] @@ -1022,9 +1008,7 @@ running once the system is up. noexec=on: enable non-executable mappings (default) noexec=off: disable nn-executable mappings - nofxsr [BUGS=IA-32] Disables x86 floating point extended - register save and restore. The kernel will only save - legacy floating-point registers on task switch. + nofxsr [BUGS=IA-32] nohlt [BUGS=ARM] @@ -1054,10 +1038,10 @@ running once the system is up. noltlbs [PPC] Do not use large page/tlb entries for kernel lowmem mapping on PPC40x. - nomca [IA-64] Disable machine check abort handling - nomce [IA-32] Machine Check Exception + nomca [IA-64] Disable machine check abort handling + noresidual [PPC] Don't use residual data on PReP machines. noresume [SWSUSP] Disables resume and restores original swap @@ -1069,8 +1053,6 @@ running once the system is up. nosbagart [IA-64] - nosep [BUGS=IA-32] Disables x86 SYSENTER/SYSEXIT support. - nosmp [SMP] Tells an SMP kernel to act as a UP kernel. nosync [HW,M68K] Disables sync negotiation for all devices. @@ -1140,11 +1122,6 @@ running once the system is up. pas16= [HW,SCSI] See header of drivers/scsi/pas16.c. - pause_on_oops= - Halt all CPUs after the first oops has been printed for - the specified number of seconds. This is to be used if - your oopses keep scrolling off the screen. - pcbit= [HW,ISDN] pcd. [PARIDE] @@ -1166,9 +1143,6 @@ running once the system is up. Mechanism 2. nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI Configuration - nomsi [MSI] If the PCI_MSI kernel config parameter is - enabled, this kernel boot option can be used to - disable the use of MSI interrupts system-wide. nosort [IA-32] Don't sort PCI devices according to order given by the PCI BIOS. This sorting is done to get a device order compatible with @@ -1690,6 +1664,20 @@ running once the system is up. ______________________________________________________________________ +Changelog: + +2000-06-?? Mr. Unknown + The last known update (for 2.4.0) - the changelog was not kept before. + +2002-11-24 Petr Baudis + Randy Dunlap + Update for 2.5.49, description for most of the options introduced, + references to other documentation (C files, READMEs, ..), added S390, + PPC, SPARC, MTD, ALSA and OSS category. Minor corrections and + reformatting. + +2005-10-19 Randy Dunlap + Lots of typos, whitespace, some reformatting. TODO: diff --git a/Documentation/laptop-mode.txt b/Documentation/laptop-mode.txt index 5696e8794..b18e21675 100644 --- a/Documentation/laptop-mode.txt +++ b/Documentation/laptop-mode.txt @@ -919,11 +919,11 @@ int main(int argc, char **argv) int settle_time = 60; /* Parse the simple command-line */ - if (argc == 2) - disk = argv[1]; - else if (argc == 4) { - settle_time = atoi(argv[2]); - disk = argv[3]; + if (ac == 2) + disk = av[1]; + else if (ac == 4) { + settle_time = atoi(av[2]); + disk = av[3]; } else usage(); diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt deleted file mode 100644 index 8c35c0426..000000000 --- a/Documentation/leds-class.txt +++ /dev/null @@ -1,71 +0,0 @@ -LED handling under Linux -======================== - -If you're reading this and thinking about keyboard leds, these are -handled by the input subsystem and the led class is *not* needed. - -In its simplest form, the LED class just allows control of LEDs from -userspace. LEDs appear in /sys/class/leds/. The brightness file will -set the brightness of the LED (taking a value 0-255). Most LEDs don't -have hardware brightness support so will just be turned on for non-zero -brightness settings. - -The class also introduces the optional concept of an LED trigger. A trigger -is a kernel based source of led events. Triggers can either be simple or -complex. A simple trigger isn't configurable and is designed to slot into -existing subsystems with minimal additional code. Examples are the ide-disk, -nand-disk and sharpsl-charge triggers. With led triggers disabled, the code -optimises away. - -Complex triggers whilst available to all LEDs have LED specific -parameters and work on a per LED basis. The timer trigger is an example. - -You can change triggers in a similar manner to the way an IO scheduler -is chosen (via /sys/class/leds//trigger). Trigger specific -parameters can appear in /sys/class/leds/ once a given trigger is -selected. - - -Design Philosophy -================= - -The underlying design philosophy is simplicity. LEDs are simple devices -and the aim is to keep a small amount of code giving as much functionality -as possible. Please keep this in mind when suggesting enhancements. - - -LED Device Naming -================= - -Is currently of the form: - -"devicename:colour" - -There have been calls for LED properties such as colour to be exported as -individual led class attributes. As a solution which doesn't incur as much -overhead, I suggest these become part of the device name. The naming scheme -above leaves scope for further attributes should they be needed. - - -Known Issues -============ - -The LED Trigger core cannot be a module as the simple trigger functions -would cause nightmare dependency issues. I see this as a minor issue -compared to the benefits the simple trigger functionality brings. The -rest of the LED subsystem can be modular. - -Some leds can be programmed to flash in hardware. As this isn't a generic -LED device property, this should be exported as a device specific sysfs -attribute rather than part of the class if this functionality is required. - - -Future Development -================== - -At the moment, a trigger can't be created specifically for a single LED. -There are a number of cases where a trigger might only be mappable to a -particular LED (ACPI?). The addition of triggers provided by the LED driver -should cover this option and be possible to add without breaking the -current interface. - diff --git a/Documentation/m68k/README.buddha b/Documentation/m68k/README.buddha index ef484a719..bf802ffc9 100644 --- a/Documentation/m68k/README.buddha +++ b/Documentation/m68k/README.buddha @@ -29,7 +29,7 @@ address is written to $4a, then the whole Byte is written to $48, while it doesn't matter how often you're writing to $4a as long as $48 is not touched. After $48 has been written, the whole card disappears from $e8 and is mapped to the new -address just written. Make sure $4a is written before $48, +address just written. Make shure $4a is written before $48, otherwise your chance is only 1:16 to find the board :-). The local memory-map is even active when mapped to $e8: diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt deleted file mode 100644 index 4710845db..000000000 --- a/Documentation/memory-barriers.txt +++ /dev/null @@ -1,2133 +0,0 @@ - ============================ - LINUX KERNEL MEMORY BARRIERS - ============================ - -By: David Howells - -Contents: - - (*) Abstract memory access model. - - - Device operations. - - Guarantees. - - (*) What are memory barriers? - - - Varieties of memory barrier. - - What may not be assumed about memory barriers? - - Data dependency barriers. - - Control dependencies. - - SMP barrier pairing. - - Examples of memory barrier sequences. - - Read memory barriers vs load speculation. - - (*) Explicit kernel barriers. - - - Compiler barrier. - - The CPU memory barriers. - - MMIO write barrier. - - (*) Implicit kernel memory barriers. - - - Locking functions. - - Interrupt disabling functions. - - Miscellaneous functions. - - (*) Inter-CPU locking barrier effects. - - - Locks vs memory accesses. - - Locks vs I/O accesses. - - (*) Where are memory barriers needed? - - - Interprocessor interaction. - - Atomic operations. - - Accessing devices. - - Interrupts. - - (*) Kernel I/O barrier effects. - - (*) Assumed minimum execution ordering model. - - (*) The effects of the cpu cache. - - - Cache coherency. - - Cache coherency vs DMA. - - Cache coherency vs MMIO. - - (*) The things CPUs get up to. - - - And then there's the Alpha. - - (*) References. - - -============================ -ABSTRACT MEMORY ACCESS MODEL -============================ - -Consider the following abstract model of the system: - - : : - : : - : : - +-------+ : +--------+ : +-------+ - | | : | | : | | - | | : | | : | | - | CPU 1 |<----->| Memory |<----->| CPU 2 | - | | : | | : | | - | | : | | : | | - +-------+ : +--------+ : +-------+ - ^ : ^ : ^ - | : | : | - | : | : | - | : v : | - | : +--------+ : | - | : | | : | - | : | | : | - +---------->| Device |<----------+ - : | | : - : | | : - : +--------+ : - : : - -Each CPU executes a program that generates memory access operations. In the -abstract CPU, memory operation ordering is very relaxed, and a CPU may actually -perform the memory operations in any order it likes, provided program causality -appears to be maintained. Similarly, the compiler may also arrange the -instructions it emits in any order it likes, provided it doesn't affect the -apparent operation of the program. - -So in the above diagram, the effects of the memory operations performed by a -CPU are perceived by the rest of the system as the operations cross the -interface between the CPU and rest of the system (the dotted lines). - - -For example, consider the following sequence of events: - - CPU 1 CPU 2 - =============== =============== - { A == 1; B == 2 } - A = 3; x = A; - B = 4; y = B; - -The set of accesses as seen by the memory system in the middle can be arranged -in 24 different combinations: - - STORE A=3, STORE B=4, x=LOAD A->3, y=LOAD B->4 - STORE A=3, STORE B=4, y=LOAD B->4, x=LOAD A->3 - STORE A=3, x=LOAD A->3, STORE B=4, y=LOAD B->4 - STORE A=3, x=LOAD A->3, y=LOAD B->2, STORE B=4 - STORE A=3, y=LOAD B->2, STORE B=4, x=LOAD A->3 - STORE A=3, y=LOAD B->2, x=LOAD A->3, STORE B=4 - STORE B=4, STORE A=3, x=LOAD A->3, y=LOAD B->4 - STORE B=4, ... - ... - -and can thus result in four different combinations of values: - - x == 1, y == 2 - x == 1, y == 4 - x == 3, y == 2 - x == 3, y == 4 - - -Furthermore, the stores committed by a CPU to the memory system may not be -perceived by the loads made by another CPU in the same order as the stores were -committed. - - -As a further example, consider this sequence of events: - - CPU 1 CPU 2 - =============== =============== - { A == 1, B == 2, C = 3, P == &A, Q == &C } - B = 4; Q = P; - P = &B D = *Q; - -There is an obvious data dependency here, as the value loaded into D depends on -the address retrieved from P by CPU 2. At the end of the sequence, any of the -following results are possible: - - (Q == &A) and (D == 1) - (Q == &B) and (D == 2) - (Q == &B) and (D == 4) - -Note that CPU 2 will never try and load C into D because the CPU will load P -into Q before issuing the load of *Q. - - -DEVICE OPERATIONS ------------------ - -Some devices present their control interfaces as collections of memory -locations, but the order in which the control registers are accessed is very -important. For instance, imagine an ethernet card with a set of internal -registers that are accessed through an address port register (A) and a data -port register (D). To read internal register 5, the following code might then -be used: - - *A = 5; - x = *D; - -but this might show up as either of the following two sequences: - - STORE *A = 5, x = LOAD *D - x = LOAD *D, STORE *A = 5 - -the second of which will almost certainly result in a malfunction, since it set -the address _after_ attempting to read the register. - - -GUARANTEES ----------- - -There are some minimal guarantees that may be expected of a CPU: - - (*) On any given CPU, dependent memory accesses will be issued in order, with - respect to itself. This means that for: - - Q = P; D = *Q; - - the CPU will issue the following memory operations: - - Q = LOAD P, D = LOAD *Q - - and always in that order. - - (*) Overlapping loads and stores within a particular CPU will appear to be - ordered within that CPU. This means that for: - - a = *X; *X = b; - - the CPU will only issue the following sequence of memory operations: - - a = LOAD *X, STORE *X = b - - And for: - - *X = c; d = *X; - - the CPU will only issue: - - STORE *X = c, d = LOAD *X - - (Loads and stores overlap if they are targetted at overlapping pieces of - memory). - -And there are a number of things that _must_ or _must_not_ be assumed: - - (*) It _must_not_ be assumed that independent loads and stores will be issued - in the order given. This means that for: - - X = *A; Y = *B; *D = Z; - - we may get any of the following sequences: - - X = LOAD *A, Y = LOAD *B, STORE *D = Z - X = LOAD *A, STORE *D = Z, Y = LOAD *B - Y = LOAD *B, X = LOAD *A, STORE *D = Z - Y = LOAD *B, STORE *D = Z, X = LOAD *A - STORE *D = Z, X = LOAD *A, Y = LOAD *B - STORE *D = Z, Y = LOAD *B, X = LOAD *A - - (*) It _must_ be assumed that overlapping memory accesses may be merged or - discarded. This means that for: - - X = *A; Y = *(A + 4); - - we may get any one of the following sequences: - - X = LOAD *A; Y = LOAD *(A + 4); - Y = LOAD *(A + 4); X = LOAD *A; - {X, Y} = LOAD {*A, *(A + 4) }; - - And for: - - *A = X; Y = *A; - - we may get either of: - - STORE *A = X; Y = LOAD *A; - STORE *A = Y = X; - - -========================= -WHAT ARE MEMORY BARRIERS? -========================= - -As can be seen above, independent memory operations are effectively performed -in random order, but this can be a problem for CPU-CPU interaction and for I/O. -What is required is some way of intervening to instruct the compiler and the -CPU to restrict the order. - -Memory barriers are such interventions. They impose a perceived partial -ordering between the memory operations specified on either side of the barrier. -They request that the sequence of memory events generated appears to other -parts of the system as if the barrier is effective on that CPU. - - -VARIETIES OF MEMORY BARRIER ---------------------------- - -Memory barriers come in four basic varieties: - - (1) Write (or store) memory barriers. - - A write memory barrier gives a guarantee that all the STORE operations - specified before the barrier will appear to happen before all the STORE - operations specified after the barrier with respect to the other - components of the system. - - A write barrier is a partial ordering on stores only; it is not required - to have any effect on loads. - - A CPU can be viewed as as commiting a sequence of store operations to the - memory system as time progresses. All stores before a write barrier will - occur in the sequence _before_ all the stores after the write barrier. - - [!] Note that write barriers should normally be paired with read or data - dependency barriers; see the "SMP barrier pairing" subsection. - - - (2) Data dependency barriers. - - A data dependency barrier is a weaker form of read barrier. In the case - where two loads are performed such that the second depends on the result - of the first (eg: the first load retrieves the address to which the second - load will be directed), a data dependency barrier would be required to - make sure that the target of the second load is updated before the address - obtained by the first load is accessed. - - A data dependency barrier is a partial ordering on interdependent loads - only; it is not required to have any effect on stores, independent loads - or overlapping loads. - - As mentioned in (1), the other CPUs in the system can be viewed as - committing sequences of stores to the memory system that the CPU being - considered can then perceive. A data dependency barrier issued by the CPU - under consideration guarantees that for any load preceding it, if that - load touches one of a sequence of stores from another CPU, then by the - time the barrier completes, the effects of all the stores prior to that - touched by the load will be perceptible to any loads issued after the data - dependency barrier. - - See the "Examples of memory barrier sequences" subsection for diagrams - showing the ordering constraints. - - [!] Note that the first load really has to have a _data_ dependency and - not a control dependency. If the address for the second load is dependent - on the first load, but the dependency is through a conditional rather than - actually loading the address itself, then it's a _control_ dependency and - a full read barrier or better is required. See the "Control dependencies" - subsection for more information. - - [!] Note that data dependency barriers should normally be paired with - write barriers; see the "SMP barrier pairing" subsection. - - - (3) Read (or load) memory barriers. - - A read barrier is a data dependency barrier plus a guarantee that all the - LOAD operations specified before the barrier will appear to happen before - all the LOAD operations specified after the barrier with respect to the - other components of the system. - - A read barrier is a partial ordering on loads only; it is not required to - have any effect on stores. - - Read memory barriers imply data dependency barriers, and so can substitute - for them. - - [!] Note that read barriers should normally be paired with write barriers; - see the "SMP barrier pairing" subsection. - - - (4) General memory barriers. - - A general memory barrier gives a guarantee that all the LOAD and STORE - operations specified before the barrier will appear to happen before all - the LOAD and STORE operations specified after the barrier with respect to - the other components of the system. - - A general memory barrier is a partial ordering over both loads and stores. - - General memory barriers imply both read and write memory barriers, and so - can substitute for either. - - -And a couple of implicit varieties: - - (5) LOCK operations. - - This acts as a one-way permeable barrier. It guarantees that all memory - operations after the LOCK operation will appear to happen after the LOCK - operation with respect to the other components of the system. - - Memory operations that occur before a LOCK operation may appear to happen - after it completes. - - A LOCK operation should almost always be paired with an UNLOCK operation. - - - (6) UNLOCK operations. - - This also acts as a one-way permeable barrier. It guarantees that all - memory operations before the UNLOCK operation will appear to happen before - the UNLOCK operation with respect to the other components of the system. - - Memory operations that occur after an UNLOCK operation may appear to - happen before it completes. - - LOCK and UNLOCK operations are guaranteed to appear with respect to each - other strictly in the order specified. - - The use of LOCK and UNLOCK operations generally precludes the need for - other sorts of memory barrier (but note the exceptions mentioned in the - subsection "MMIO write barrier"). - - -Memory barriers are only required where there's a possibility of interaction -between two CPUs or between a CPU and a device. If it can be guaranteed that -there won't be any such interaction in any particular piece of code, then -memory barriers are unnecessary in that piece of code. - - -Note that these are the _minimum_ guarantees. Different architectures may give -more substantial guarantees, but they may _not_ be relied upon outside of arch -specific code. - - -WHAT MAY NOT BE ASSUMED ABOUT MEMORY BARRIERS? ----------------------------------------------- - -There are certain things that the Linux kernel memory barriers do not guarantee: - - (*) There is no guarantee that any of the memory accesses specified before a - memory barrier will be _complete_ by the completion of a memory barrier - instruction; the barrier can be considered to draw a line in that CPU's - access queue that accesses of the appropriate type may not cross. - - (*) There is no guarantee that issuing a memory barrier on one CPU will have - any direct effect on another CPU or any other hardware in the system. The - indirect effect will be the order in which the second CPU sees the effects - of the first CPU's accesses occur, but see the next point: - - (*) There is no guarantee that the a CPU will see the correct order of effects - from a second CPU's accesses, even _if_ the second CPU uses a memory - barrier, unless the first CPU _also_ uses a matching memory barrier (see - the subsection on "SMP Barrier Pairing"). - - (*) There is no guarantee that some intervening piece of off-the-CPU - hardware[*] will not reorder the memory accesses. CPU cache coherency - mechanisms should propagate the indirect effects of a memory barrier - between CPUs, but might not do so in order. - - [*] For information on bus mastering DMA and coherency please read: - - Documentation/pci.txt - Documentation/DMA-mapping.txt - Documentation/DMA-API.txt - - -DATA DEPENDENCY BARRIERS ------------------------- - -The usage requirements of data dependency barriers are a little subtle, and -it's not always obvious that they're needed. To illustrate, consider the -following sequence of events: - - CPU 1 CPU 2 - =============== =============== - { A == 1, B == 2, C = 3, P == &A, Q == &C } - B = 4; - - P = &B - Q = P; - D = *Q; - -There's a clear data dependency here, and it would seem that by the end of the -sequence, Q must be either &A or &B, and that: - - (Q == &A) implies (D == 1) - (Q == &B) implies (D == 4) - -But! CPU 2's perception of P may be updated _before_ its perception of B, thus -leading to the following situation: - - (Q == &B) and (D == 2) ???? - -Whilst this may seem like a failure of coherency or causality maintenance, it -isn't, and this behaviour can be observed on certain real CPUs (such as the DEC -Alpha). - -To deal with this, a data dependency barrier must be inserted between the -address load and the data load: - - CPU 1 CPU 2 - =============== =============== - { A == 1, B == 2, C = 3, P == &A, Q == &C } - B = 4; - - P = &B - Q = P; - - D = *Q; - -This enforces the occurrence of one of the two implications, and prevents the -third possibility from arising. - -[!] Note that this extremely counterintuitive situation arises most easily on -machines with split caches, so that, for example, one cache bank processes -even-numbered cache lines and the other bank processes odd-numbered cache -lines. The pointer P might be stored in an odd-numbered cache line, and the -variable B might be stored in an even-numbered cache line. Then, if the -even-numbered bank of the reading CPU's cache is extremely busy while the -odd-numbered bank is idle, one can see the new value of the pointer P (&B), -but the old value of the variable B (1). - - -Another example of where data dependency barriers might by required is where a -number is read from memory and then used to calculate the index for an array -access: - - CPU 1 CPU 2 - =============== =============== - { M[0] == 1, M[1] == 2, M[3] = 3, P == 0, Q == 3 } - M[1] = 4; - - P = 1 - Q = P; - - D = M[Q]; - - -The data dependency barrier is very important to the RCU system, for example. -See rcu_dereference() in include/linux/rcupdate.h. This permits the current -target of an RCU'd pointer to be replaced with a new modified target, without -the replacement target appearing to be incompletely initialised. - -See also the subsection on "Cache Coherency" for a more thorough example. - - -CONTROL DEPENDENCIES --------------------- - -A control dependency requires a full read memory barrier, not simply a data -dependency barrier to make it work correctly. Consider the following bit of -code: - - q = &a; - if (p) - q = &b; - - x = *q; - -This will not have the desired effect because there is no actual data -dependency, but rather a control dependency that the CPU may short-circuit by -attempting to predict the outcome in advance. In such a case what's actually -required is: - - q = &a; - if (p) - q = &b; - - x = *q; - - -SMP BARRIER PAIRING -------------------- - -When dealing with CPU-CPU interactions, certain types of memory barrier should -always be paired. A lack of appropriate pairing is almost certainly an error. - -A write barrier should always be paired with a data dependency barrier or read -barrier, though a general barrier would also be viable. Similarly a read -barrier or a data dependency barrier should always be paired with at least an -write barrier, though, again, a general barrier is viable: - - CPU 1 CPU 2 - =============== =============== - a = 1; - - b = 2; x = b; - - y = a; - -Or: - - CPU 1 CPU 2 - =============== =============================== - a = 1; - - b = &a; x = b; - - y = *x; - -Basically, the read barrier always has to be there, even though it can be of -the "weaker" type. - -[!] Note that the stores before the write barrier would normally be expected to -match the loads after the read barrier or data dependency barrier, and vice -versa: - - CPU 1 CPU 2 - =============== =============== - a = 1; }---- --->{ v = c - b = 2; } \ / { w = d - \ - c = 3; } / \ { x = a; - d = 4; }---- --->{ y = b; - - -EXAMPLES OF MEMORY BARRIER SEQUENCES ------------------------------------- - -Firstly, write barriers act as a partial orderings on store operations. -Consider the following sequence of events: - - CPU 1 - ======================= - STORE A = 1 - STORE B = 2 - STORE C = 3 - - STORE D = 4 - STORE E = 5 - -This sequence of events is committed to the memory coherence system in an order -that the rest of the system might perceive as the unordered set of { STORE A, -STORE B, STORE C } all occuring before the unordered set of { STORE D, STORE E -}: - - +-------+ : : - | | +------+ - | |------>| C=3 | } /\ - | | : +------+ }----- \ -----> Events perceptible - | | : | A=1 | } \/ to rest of system - | | : +------+ } - | CPU 1 | : | B=2 | } - | | +------+ } - | | wwwwwwwwwwwwwwww } <--- At this point the write barrier - | | +------+ } requires all stores prior to the - | | : | E=5 | } barrier to be committed before - | | : +------+ } further stores may be take place. - | |------>| D=4 | } - | | +------+ - +-------+ : : - | - | Sequence in which stores are committed to the - | memory system by CPU 1 - V - - -Secondly, data dependency barriers act as a partial orderings on data-dependent -loads. Consider the following sequence of events: - - CPU 1 CPU 2 - ======================= ======================= - { B = 7; X = 9; Y = 8; C = &Y } - STORE A = 1 - STORE B = 2 - - STORE C = &B LOAD X - STORE D = 4 LOAD C (gets &B) - LOAD *C (reads B) - -Without intervention, CPU 2 may perceive the events on CPU 1 in some -effectively random order, despite the write barrier issued by CPU 1: - - +-------+ : : : : - | | +------+ +-------+ | Sequence of update - | |------>| B=2 |----- --->| Y->8 | | of perception on - | | : +------+ \ +-------+ | CPU 2 - | CPU 1 | : | A=1 | \ --->| C->&Y | V - | | +------+ | +-------+ - | | wwwwwwwwwwwwwwww | : : - | | +------+ | : : - | | : | C=&B |--- | : : +-------+ - | | : +------+ \ | +-------+ | | - | |------>| D=4 | ----------->| C->&B |------>| | - | | +------+ | +-------+ | | - +-------+ : : | : : | | - | : : | | - | : : | CPU 2 | - | +-------+ | | - Apparently incorrect ---> | | B->7 |------>| | - perception of B (!) | +-------+ | | - | : : | | - | +-------+ | | - The load of X holds ---> \ | X->9 |------>| | - up the maintenance \ +-------+ | | - of coherence of B ----->| B->2 | +-------+ - +-------+ - : : - - -In the above example, CPU 2 perceives that B is 7, despite the load of *C -(which would be B) coming after the the LOAD of C. - -If, however, a data dependency barrier were to be placed between the load of C -and the load of *C (ie: B) on CPU 2: - - CPU 1 CPU 2 - ======================= ======================= - { B = 7; X = 9; Y = 8; C = &Y } - STORE A = 1 - STORE B = 2 - - STORE C = &B LOAD X - STORE D = 4 LOAD C (gets &B) - - LOAD *C (reads B) - -then the following will occur: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| B=2 |----- --->| Y->8 | - | | : +------+ \ +-------+ - | CPU 1 | : | A=1 | \ --->| C->&Y | - | | +------+ | +-------+ - | | wwwwwwwwwwwwwwww | : : - | | +------+ | : : - | | : | C=&B |--- | : : +-------+ - | | : +------+ \ | +-------+ | | - | |------>| D=4 | ----------->| C->&B |------>| | - | | +------+ | +-------+ | | - +-------+ : : | : : | | - | : : | | - | : : | CPU 2 | - | +-------+ | | - | | X->9 |------>| | - | +-------+ | | - Makes sure all effects ---> \ ddddddddddddddddd | | - prior to the store of C \ +-------+ | | - are perceptible to ----->| B->2 |------>| | - subsequent loads +-------+ | | - : : +-------+ - - -And thirdly, a read barrier acts as a partial order on loads. Consider the -following sequence of events: - - CPU 1 CPU 2 - ======================= ======================= - { A = 0, B = 9 } - STORE A=1 - - STORE B=2 - LOAD B - LOAD A - -Without intervention, CPU 2 may then choose to perceive the events on CPU 1 in -some effectively random order, despite the write barrier issued by CPU 1: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| A=1 |------ --->| A->0 | - | | +------+ \ +-------+ - | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | - | | +------+ | +-------+ - | |------>| B=2 |--- | : : - | | +------+ \ | : : +-------+ - +-------+ : : \ | +-------+ | | - ---------->| B->2 |------>| | - | +-------+ | CPU 2 | - | | A->0 |------>| | - | +-------+ | | - | : : +-------+ - \ : : - \ +-------+ - ---->| A->1 | - +-------+ - : : - - -If, however, a read barrier were to be placed between the load of E and the -load of A on CPU 2: - - CPU 1 CPU 2 - ======================= ======================= - { A = 0, B = 9 } - STORE A=1 - - STORE B=2 - LOAD B - - LOAD A - -then the partial ordering imposed by CPU 1 will be perceived correctly by CPU -2: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| A=1 |------ --->| A->0 | - | | +------+ \ +-------+ - | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | - | | +------+ | +-------+ - | |------>| B=2 |--- | : : - | | +------+ \ | : : +-------+ - +-------+ : : \ | +-------+ | | - ---------->| B->2 |------>| | - | +-------+ | CPU 2 | - | : : | | - | : : | | - At this point the read ----> \ rrrrrrrrrrrrrrrrr | | - barrier causes all effects \ +-------+ | | - prior to the storage of B ---->| A->1 |------>| | - to be perceptible to CPU 2 +-------+ | | - : : +-------+ - - -To illustrate this more completely, consider what could happen if the code -contained a load of A either side of the read barrier: - - CPU 1 CPU 2 - ======================= ======================= - { A = 0, B = 9 } - STORE A=1 - - STORE B=2 - LOAD B - LOAD A [first load of A] - - LOAD A [second load of A] - -Even though the two loads of A both occur after the load of B, they may both -come up with different values: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| A=1 |------ --->| A->0 | - | | +------+ \ +-------+ - | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | - | | +------+ | +-------+ - | |------>| B=2 |--- | : : - | | +------+ \ | : : +-------+ - +-------+ : : \ | +-------+ | | - ---------->| B->2 |------>| | - | +-------+ | CPU 2 | - | : : | | - | : : | | - | +-------+ | | - | | A->0 |------>| 1st | - | +-------+ | | - At this point the read ----> \ rrrrrrrrrrrrrrrrr | | - barrier causes all effects \ +-------+ | | - prior to the storage of B ---->| A->1 |------>| 2nd | - to be perceptible to CPU 2 +-------+ | | - : : +-------+ - - -But it may be that the update to A from CPU 1 becomes perceptible to CPU 2 -before the read barrier completes anyway: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| A=1 |------ --->| A->0 | - | | +------+ \ +-------+ - | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | - | | +------+ | +-------+ - | |------>| B=2 |--- | : : - | | +------+ \ | : : +-------+ - +-------+ : : \ | +-------+ | | - ---------->| B->2 |------>| | - | +-------+ | CPU 2 | - | : : | | - \ : : | | - \ +-------+ | | - ---->| A->1 |------>| 1st | - +-------+ | | - rrrrrrrrrrrrrrrrr | | - +-------+ | | - | A->1 |------>| 2nd | - +-------+ | | - : : +-------+ - - -The guarantee is that the second load will always come up with A == 1 if the -load of B came up with B == 2. No such guarantee exists for the first load of -A; that may come up with either A == 0 or A == 1. - - -READ MEMORY BARRIERS VS LOAD SPECULATION ----------------------------------------- - -Many CPUs speculate with loads: that is they see that they will need to load an -item from memory, and they find a time where they're not using the bus for any -other loads, and so do the load in advance - even though they haven't actually -got to that point in the instruction execution flow yet. This permits the -actual load instruction to potentially complete immediately because the CPU -already has the value to hand. - -It may turn out that the CPU didn't actually need the value - perhaps because a -branch circumvented the load - in which case it can discard the value or just -cache it for later use. - -Consider: - - CPU 1 CPU 2 - ======================= ======================= - LOAD B - DIVIDE } Divide instructions generally - DIVIDE } take a long time to perform - LOAD A - -Which might appear as this: - - : : +-------+ - +-------+ | | - --->| B->2 |------>| | - +-------+ | CPU 2 | - : :DIVIDE | | - +-------+ | | - The CPU being busy doing a ---> --->| A->0 |~~~~ | | - division speculates on the +-------+ ~ | | - LOAD of A : : ~ | | - : :DIVIDE | | - : : ~ | | - Once the divisions are complete --> : : ~-->| | - the CPU can then perform the : : | | - LOAD with immediate effect : : +-------+ - - -Placing a read barrier or a data dependency barrier just before the second -load: - - CPU 1 CPU 2 - ======================= ======================= - LOAD B - DIVIDE - DIVIDE - - LOAD A - -will force any value speculatively obtained to be reconsidered to an extent -dependent on the type of barrier used. If there was no change made to the -speculated memory location, then the speculated value will just be used: - - : : +-------+ - +-------+ | | - --->| B->2 |------>| | - +-------+ | CPU 2 | - : :DIVIDE | | - +-------+ | | - The CPU being busy doing a ---> --->| A->0 |~~~~ | | - division speculates on the +-------+ ~ | | - LOAD of A : : ~ | | - : :DIVIDE | | - : : ~ | | - : : ~ | | - rrrrrrrrrrrrrrrr~ | | - : : ~ | | - : : ~-->| | - : : | | - : : +-------+ - - -but if there was an update or an invalidation from another CPU pending, then -the speculation will be cancelled and the value reloaded: - - : : +-------+ - +-------+ | | - --->| B->2 |------>| | - +-------+ | CPU 2 | - : :DIVIDE | | - +-------+ | | - The CPU being busy doing a ---> --->| A->0 |~~~~ | | - division speculates on the +-------+ ~ | | - LOAD of A : : ~ | | - : :DIVIDE | | - : : ~ | | - : : ~ | | - rrrrrrrrrrrrrrrrr | | - +-------+ | | - The speculation is discarded ---> --->| A->1 |------>| | - and an updated value is +-------+ | | - retrieved : : +-------+ - - -======================== -EXPLICIT KERNEL BARRIERS -======================== - -The Linux kernel has a variety of different barriers that act at different -levels: - - (*) Compiler barrier. - - (*) CPU memory barriers. - - (*) MMIO write barrier. - - -COMPILER BARRIER ----------------- - -The Linux kernel has an explicit compiler barrier function that prevents the -compiler from moving the memory accesses either side of it to the other side: - - barrier(); - -This a general barrier - lesser varieties of compiler barrier do not exist. - -The compiler barrier has no direct effect on the CPU, which may then reorder -things however it wishes. - - -CPU MEMORY BARRIERS -------------------- - -The Linux kernel has eight basic CPU memory barriers: - - TYPE MANDATORY SMP CONDITIONAL - =============== ======================= =========================== - GENERAL mb() smp_mb() - WRITE wmb() smp_wmb() - READ rmb() smp_rmb() - DATA DEPENDENCY read_barrier_depends() smp_read_barrier_depends() - - -All CPU memory barriers unconditionally imply compiler barriers. - -SMP memory barriers are reduced to compiler barriers on uniprocessor compiled -systems because it is assumed that a CPU will be appear to be self-consistent, -and will order overlapping accesses correctly with respect to itself. - -[!] Note that SMP memory barriers _must_ be used to control the ordering of -references to shared memory on SMP systems, though the use of locking instead -is sufficient. - -Mandatory barriers should not be used to control SMP effects, since mandatory -barriers unnecessarily impose overhead on UP systems. They may, however, be -used to control MMIO effects on accesses through relaxed memory I/O windows. -These are required even on non-SMP systems as they affect the order in which -memory operations appear to a device by prohibiting both the compiler and the -CPU from reordering them. - - -There are some more advanced barrier functions: - - (*) set_mb(var, value) - (*) set_wmb(var, value) - - These assign the value to the variable and then insert at least a write - barrier after it, depending on the function. They aren't guaranteed to - insert anything more than a compiler barrier in a UP compilation. - - - (*) smp_mb__before_atomic_dec(); - (*) smp_mb__after_atomic_dec(); - (*) smp_mb__before_atomic_inc(); - (*) smp_mb__after_atomic_inc(); - - These are for use with atomic add, subtract, increment and decrement - functions that don't return a value, especially when used for reference - counting. These functions do not imply memory barriers. - - As an example, consider a piece of code that marks an object as being dead - and then decrements the object's reference count: - - obj->dead = 1; - smp_mb__before_atomic_dec(); - atomic_dec(&obj->ref_count); - - This makes sure that the death mark on the object is perceived to be set - *before* the reference counter is decremented. - - See Documentation/atomic_ops.txt for more information. See the "Atomic - operations" subsection for information on where to use these. - - - (*) smp_mb__before_clear_bit(void); - (*) smp_mb__after_clear_bit(void); - - These are for use similar to the atomic inc/dec barriers. These are - typically used for bitwise unlocking operations, so care must be taken as - there are no implicit memory barriers here either. - - Consider implementing an unlock operation of some nature by clearing a - locking bit. The clear_bit() would then need to be barriered like this: - - smp_mb__before_clear_bit(); - clear_bit( ... ); - - This prevents memory operations before the clear leaking to after it. See - the subsection on "Locking Functions" with reference to UNLOCK operation - implications. - - See Documentation/atomic_ops.txt for more information. See the "Atomic - operations" subsection for information on where to use these. - - -MMIO WRITE BARRIER ------------------- - -The Linux kernel also has a special barrier for use with memory-mapped I/O -writes: - - mmiowb(); - -This is a variation on the mandatory write barrier that causes writes to weakly -ordered I/O regions to be partially ordered. Its effects may go beyond the -CPU->Hardware interface and actually affect the hardware at some level. - -See the subsection "Locks vs I/O accesses" for more information. - - -=============================== -IMPLICIT KERNEL MEMORY BARRIERS -=============================== - -Some of the other functions in the linux kernel imply memory barriers, amongst -which are locking and scheduling functions. - -This specification is a _minimum_ guarantee; any particular architecture may -provide more substantial guarantees, but these may not be relied upon outside -of arch specific code. - - -LOCKING FUNCTIONS ------------------ - -The Linux kernel has a number of locking constructs: - - (*) spin locks - (*) R/W spin locks - (*) mutexes - (*) semaphores - (*) R/W semaphores - (*) RCU - -In all cases there are variants on "LOCK" operations and "UNLOCK" operations -for each construct. These operations all imply certain barriers: - - (1) LOCK operation implication: - - Memory operations issued after the LOCK will be completed after the LOCK - operation has completed. - - Memory operations issued before the LOCK may be completed after the LOCK - operation has completed. - - (2) UNLOCK operation implication: - - Memory operations issued before the UNLOCK will be completed before the - UNLOCK operation has completed. - - Memory operations issued after the UNLOCK may be completed before the - UNLOCK operation has completed. - - (3) LOCK vs LOCK implication: - - All LOCK operations issued before another LOCK operation will be completed - before that LOCK operation. - - (4) LOCK vs UNLOCK implication: - - All LOCK operations issued before an UNLOCK operation will be completed - before the UNLOCK operation. - - All UNLOCK operations issued before a LOCK operation will be completed - before the LOCK operation. - - (5) Failed conditional LOCK implication: - - Certain variants of the LOCK operation may fail, either due to being - unable to get the lock immediately, or due to receiving an unblocked - signal whilst asleep waiting for the lock to become available. Failed - locks do not imply any sort of barrier. - -Therefore, from (1), (2) and (4) an UNLOCK followed by an unconditional LOCK is -equivalent to a full barrier, but a LOCK followed by an UNLOCK is not. - -[!] Note: one of the consequence of LOCKs and UNLOCKs being only one-way - barriers is that the effects instructions outside of a critical section may - seep into the inside of the critical section. - -A LOCK followed by an UNLOCK may not be assumed to be full memory barrier -because it is possible for an access preceding the LOCK to happen after the -LOCK, and an access following the UNLOCK to happen before the UNLOCK, and the -two accesses can themselves then cross: - - *A = a; - LOCK - UNLOCK - *B = b; - -may occur as: - - LOCK, STORE *B, STORE *A, UNLOCK - -Locks and semaphores may not provide any guarantee of ordering on UP compiled -systems, and so cannot be counted on in such a situation to actually achieve -anything at all - especially with respect to I/O accesses - unless combined -with interrupt disabling operations. - -See also the section on "Inter-CPU locking barrier effects". - - -As an example, consider the following: - - *A = a; - *B = b; - LOCK - *C = c; - *D = d; - UNLOCK - *E = e; - *F = f; - -The following sequence of events is acceptable: - - LOCK, {*F,*A}, *E, {*C,*D}, *B, UNLOCK - - [+] Note that {*F,*A} indicates a combined access. - -But none of the following are: - - {*F,*A}, *B, LOCK, *C, *D, UNLOCK, *E - *A, *B, *C, LOCK, *D, UNLOCK, *E, *F - *A, *B, LOCK, *C, UNLOCK, *D, *E, *F - *B, LOCK, *C, *D, UNLOCK, {*F,*A}, *E - - - -INTERRUPT DISABLING FUNCTIONS ------------------------------ - -Functions that disable interrupts (LOCK equivalent) and enable interrupts -(UNLOCK equivalent) will act as compiler barriers only. So if memory or I/O -barriers are required in such a situation, they must be provided from some -other means. - - -MISCELLANEOUS FUNCTIONS ------------------------ - -Other functions that imply barriers: - - (*) schedule() and similar imply full memory barriers. - - -================================= -INTER-CPU LOCKING BARRIER EFFECTS -================================= - -On SMP systems locking primitives give a more substantial form of barrier: one -that does affect memory access ordering on other CPUs, within the context of -conflict on any particular lock. - - -LOCKS VS MEMORY ACCESSES ------------------------- - -Consider the following: the system has a pair of spinlocks (M) and (Q), and -three CPUs; then should the following sequence of events occur: - - CPU 1 CPU 2 - =============================== =============================== - *A = a; *E = e; - LOCK M LOCK Q - *B = b; *F = f; - *C = c; *G = g; - UNLOCK M UNLOCK Q - *D = d; *H = h; - -Then there is no guarantee as to what order CPU #3 will see the accesses to *A -through *H occur in, other than the constraints imposed by the separate locks -on the separate CPUs. It might, for example, see: - - *E, LOCK M, LOCK Q, *G, *C, *F, *A, *B, UNLOCK Q, *D, *H, UNLOCK M - -But it won't see any of: - - *B, *C or *D preceding LOCK M - *A, *B or *C following UNLOCK M - *F, *G or *H preceding LOCK Q - *E, *F or *G following UNLOCK Q - - -However, if the following occurs: - - CPU 1 CPU 2 - =============================== =============================== - *A = a; - LOCK M [1] - *B = b; - *C = c; - UNLOCK M [1] - *D = d; *E = e; - LOCK M [2] - *F = f; - *G = g; - UNLOCK M [2] - *H = h; - -CPU #3 might see: - - *E, LOCK M [1], *C, *B, *A, UNLOCK M [1], - LOCK M [2], *H, *F, *G, UNLOCK M [2], *D - -But assuming CPU #1 gets the lock first, it won't see any of: - - *B, *C, *D, *F, *G or *H preceding LOCK M [1] - *A, *B or *C following UNLOCK M [1] - *F, *G or *H preceding LOCK M [2] - *A, *B, *C, *E, *F or *G following UNLOCK M [2] - - -LOCKS VS I/O ACCESSES ---------------------- - -Under certain circumstances (especially involving NUMA), I/O accesses within -two spinlocked sections on two different CPUs may be seen as interleaved by the -PCI bridge, because the PCI bridge does not necessarily participate in the -cache-coherence protocol, and is therefore incapable of issuing the required -read memory barriers. - -For example: - - CPU 1 CPU 2 - =============================== =============================== - spin_lock(Q) - writel(0, ADDR) - writel(1, DATA); - spin_unlock(Q); - spin_lock(Q); - writel(4, ADDR); - writel(5, DATA); - spin_unlock(Q); - -may be seen by the PCI bridge as follows: - - STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5 - -which would probably cause the hardware to malfunction. - - -What is necessary here is to intervene with an mmiowb() before dropping the -spinlock, for example: - - CPU 1 CPU 2 - =============================== =============================== - spin_lock(Q) - writel(0, ADDR) - writel(1, DATA); - mmiowb(); - spin_unlock(Q); - spin_lock(Q); - writel(4, ADDR); - writel(5, DATA); - mmiowb(); - spin_unlock(Q); - -this will ensure that the two stores issued on CPU #1 appear at the PCI bridge -before either of the stores issued on CPU #2. - - -Furthermore, following a store by a load to the same device obviates the need -for an mmiowb(), because the load forces the store to complete before the load -is performed: - - CPU 1 CPU 2 - =============================== =============================== - spin_lock(Q) - writel(0, ADDR) - a = readl(DATA); - spin_unlock(Q); - spin_lock(Q); - writel(4, ADDR); - b = readl(DATA); - spin_unlock(Q); - - -See Documentation/DocBook/deviceiobook.tmpl for more information. - - -================================= -WHERE ARE MEMORY BARRIERS NEEDED? -================================= - -Under normal operation, memory operation reordering is generally not going to -be a problem as a single-threaded linear piece of code will still appear to -work correctly, even if it's in an SMP kernel. There are, however, three -circumstances in which reordering definitely _could_ be a problem: - - (*) Interprocessor interaction. - - (*) Atomic operations. - - (*) Accessing devices (I/O). - - (*) Interrupts. - - -INTERPROCESSOR INTERACTION --------------------------- - -When there's a system with more than one processor, more than one CPU in the -system may be working on the same data set at the same time. This can cause -synchronisation problems, and the usual way of dealing with them is to use -locks. Locks, however, are quite expensive, and so it may be preferable to -operate without the use of a lock if at all possible. In such a case -operations that affect both CPUs may have to be carefully ordered to prevent -a malfunction. - -Consider, for example, the R/W semaphore slow path. Here a waiting process is -queued on the semaphore, by virtue of it having a piece of its stack linked to -the semaphore's list of waiting processes: - - struct rw_semaphore { - ... - spinlock_t lock; - struct list_head waiters; - }; - - struct rwsem_waiter { - struct list_head list; - struct task_struct *task; - }; - -To wake up a particular waiter, the up_read() or up_write() functions have to: - - (1) read the next pointer from this waiter's record to know as to where the - next waiter record is; - - (4) read the pointer to the waiter's task structure; - - (3) clear the task pointer to tell the waiter it has been given the semaphore; - - (4) call wake_up_process() on the task; and - - (5) release the reference held on the waiter's task struct. - -In otherwords, it has to perform this sequence of events: - - LOAD waiter->list.next; - LOAD waiter->task; - STORE waiter->task; - CALL wakeup - RELEASE task - -and if any of these steps occur out of order, then the whole thing may -malfunction. - -Once it has queued itself and dropped the semaphore lock, the waiter does not -get the lock again; it instead just waits for its task pointer to be cleared -before proceeding. Since the record is on the waiter's stack, this means that -if the task pointer is cleared _before_ the next pointer in the list is read, -another CPU might start processing the waiter and might clobber the waiter's -stack before the up*() function has a chance to read the next pointer. - -Consider then what might happen to the above sequence of events: - - CPU 1 CPU 2 - =============================== =============================== - down_xxx() - Queue waiter - Sleep - up_yyy() - LOAD waiter->task; - STORE waiter->task; - Woken up by other event - - Resume processing - down_xxx() returns - call foo() - foo() clobbers *waiter - - LOAD waiter->list.next; - --- OOPS --- - -This could be dealt with using the semaphore lock, but then the down_xxx() -function has to needlessly get the spinlock again after being woken up. - -The way to deal with this is to insert a general SMP memory barrier: - - LOAD waiter->list.next; - LOAD waiter->task; - smp_mb(); - STORE waiter->task; - CALL wakeup - RELEASE task - -In this case, the barrier makes a guarantee that all memory accesses before the -barrier will appear to happen before all the memory accesses after the barrier -with respect to the other CPUs on the system. It does _not_ guarantee that all -the memory accesses before the barrier will be complete by the time the barrier -instruction itself is complete. - -On a UP system - where this wouldn't be a problem - the smp_mb() is just a -compiler barrier, thus making sure the compiler emits the instructions in the -right order without actually intervening in the CPU. Since there there's only -one CPU, that CPU's dependency ordering logic will take care of everything -else. - - -ATOMIC OPERATIONS ------------------ - -Whilst they are technically interprocessor interaction considerations, atomic -operations are noted specially as some of them imply full memory barriers and -some don't, but they're very heavily relied on as a group throughout the -kernel. - -Any atomic operation that modifies some state in memory and returns information -about the state (old or new) implies an SMP-conditional general memory barrier -(smp_mb()) on each side of the actual operation. These include: - - xchg(); - cmpxchg(); - atomic_cmpxchg(); - atomic_inc_return(); - atomic_dec_return(); - atomic_add_return(); - atomic_sub_return(); - atomic_inc_and_test(); - atomic_dec_and_test(); - atomic_sub_and_test(); - atomic_add_negative(); - atomic_add_unless(); - test_and_set_bit(); - test_and_clear_bit(); - test_and_change_bit(); - -These are used for such things as implementing LOCK-class and UNLOCK-class -operations and adjusting reference counters towards object destruction, and as -such the implicit memory barrier effects are necessary. - - -The following operation are potential problems as they do _not_ imply memory -barriers, but might be used for implementing such things as UNLOCK-class -operations: - - atomic_set(); - set_bit(); - clear_bit(); - change_bit(); - -With these the appropriate explicit memory barrier should be used if necessary -(smp_mb__before_clear_bit() for instance). - - -The following also do _not_ imply memory barriers, and so may require explicit -memory barriers under some circumstances (smp_mb__before_atomic_dec() for -instance)): - - atomic_add(); - atomic_sub(); - atomic_inc(); - atomic_dec(); - -If they're used for statistics generation, then they probably don't need memory -barriers, unless there's a coupling between statistical data. - -If they're used for reference counting on an object to control its lifetime, -they probably don't need memory barriers because either the reference count -will be adjusted inside a locked section, or the caller will already hold -sufficient references to make the lock, and thus a memory barrier unnecessary. - -If they're used for constructing a lock of some description, then they probably -do need memory barriers as a lock primitive generally has to do things in a -specific order. - - -Basically, each usage case has to be carefully considered as to whether memory -barriers are needed or not. - -[!] Note that special memory barrier primitives are available for these -situations because on some CPUs the atomic instructions used imply full memory -barriers, and so barrier instructions are superfluous in conjunction with them, -and in such cases the special barrier primitives will be no-ops. - -See Documentation/atomic_ops.txt for more information. - - -ACCESSING DEVICES ------------------ - -Many devices can be memory mapped, and so appear to the CPU as if they're just -a set of memory locations. To control such a device, the driver usually has to -make the right memory accesses in exactly the right order. - -However, having a clever CPU or a clever compiler creates a potential problem -in that the carefully sequenced accesses in the driver code won't reach the -device in the requisite order if the CPU or the compiler thinks it is more -efficient to reorder, combine or merge accesses - something that would cause -the device to malfunction. - -Inside of the Linux kernel, I/O should be done through the appropriate accessor -routines - such as inb() or writel() - which know how to make such accesses -appropriately sequential. Whilst this, for the most part, renders the explicit -use of memory barriers unnecessary, there are a couple of situations where they -might be needed: - - (1) On some systems, I/O stores are not strongly ordered across all CPUs, and - so for _all_ general drivers locks should be used and mmiowb() must be - issued prior to unlocking the critical section. - - (2) If the accessor functions are used to refer to an I/O memory window with - relaxed memory access properties, then _mandatory_ memory barriers are - required to enforce ordering. - -See Documentation/DocBook/deviceiobook.tmpl for more information. - - -INTERRUPTS ----------- - -A driver may be interrupted by its own interrupt service routine, and thus the -two parts of the driver may interfere with each other's attempts to control or -access the device. - -This may be alleviated - at least in part - by disabling local interrupts (a -form of locking), such that the critical operations are all contained within -the interrupt-disabled section in the driver. Whilst the driver's interrupt -routine is executing, the driver's core may not run on the same CPU, and its -interrupt is not permitted to happen again until the current interrupt has been -handled, thus the interrupt handler does not need to lock against that. - -However, consider a driver that was talking to an ethernet card that sports an -address register and a data register. If that driver's core talks to the card -under interrupt-disablement and then the driver's interrupt handler is invoked: - - LOCAL IRQ DISABLE - writew(ADDR, 3); - writew(DATA, y); - LOCAL IRQ ENABLE - - writew(ADDR, 4); - q = readw(DATA); - - -The store to the data register might happen after the second store to the -address register if ordering rules are sufficiently relaxed: - - STORE *ADDR = 3, STORE *ADDR = 4, STORE *DATA = y, q = LOAD *DATA - - -If ordering rules are relaxed, it must be assumed that accesses done inside an -interrupt disabled section may leak outside of it and may interleave with -accesses performed in an interrupt - and vice versa - unless implicit or -explicit barriers are used. - -Normally this won't be a problem because the I/O accesses done inside such -sections will include synchronous load operations on strictly ordered I/O -registers that form implicit I/O barriers. If this isn't sufficient then an -mmiowb() may need to be used explicitly. - - -A similar situation may occur between an interrupt routine and two routines -running on separate CPUs that communicate with each other. If such a case is -likely, then interrupt-disabling locks should be used to guarantee ordering. - - -========================== -KERNEL I/O BARRIER EFFECTS -========================== - -When accessing I/O memory, drivers should use the appropriate accessor -functions: - - (*) inX(), outX(): - - These are intended to talk to I/O space rather than memory space, but - that's primarily a CPU-specific concept. The i386 and x86_64 processors do - indeed have special I/O space access cycles and instructions, but many - CPUs don't have such a concept. - - The PCI bus, amongst others, defines an I/O space concept - which on such - CPUs as i386 and x86_64 cpus readily maps to the CPU's concept of I/O - space. However, it may also mapped as a virtual I/O space in the CPU's - memory map, particularly on those CPUs that don't support alternate - I/O spaces. - - Accesses to this space may be fully synchronous (as on i386), but - intermediary bridges (such as the PCI host bridge) may not fully honour - that. - - They are guaranteed to be fully ordered with respect to each other. - - They are not guaranteed to be fully ordered with respect to other types of - memory and I/O operation. - - (*) readX(), writeX(): - - Whether these are guaranteed to be fully ordered and uncombined with - respect to each other on the issuing CPU depends on the characteristics - defined for the memory window through which they're accessing. On later - i386 architecture machines, for example, this is controlled by way of the - MTRR registers. - - Ordinarily, these will be guaranteed to be fully ordered and uncombined,, - provided they're not accessing a prefetchable device. - - However, intermediary hardware (such as a PCI bridge) may indulge in - deferral if it so wishes; to flush a store, a load from the same location - is preferred[*], but a load from the same device or from configuration - space should suffice for PCI. - - [*] NOTE! attempting to load from the same location as was written to may - cause a malfunction - consider the 16550 Rx/Tx serial registers for - example. - - Used with prefetchable I/O memory, an mmiowb() barrier may be required to - force stores to be ordered. - - Please refer to the PCI specification for more information on interactions - between PCI transactions. - - (*) readX_relaxed() - - These are similar to readX(), but are not guaranteed to be ordered in any - way. Be aware that there is no I/O read barrier available. - - (*) ioreadX(), iowriteX() - - These will perform as appropriate for the type of access they're actually - doing, be it inX()/outX() or readX()/writeX(). - - -======================================== -ASSUMED MINIMUM EXECUTION ORDERING MODEL -======================================== - -It has to be assumed that the conceptual CPU is weakly-ordered but that it will -maintain the appearance of program causality with respect to itself. Some CPUs -(such as i386 or x86_64) are more constrained than others (such as powerpc or -frv), and so the most relaxed case (namely DEC Alpha) must be assumed outside -of arch-specific code. - -This means that it must be considered that the CPU will execute its instruction -stream in any order it feels like - or even in parallel - provided that if an -instruction in the stream depends on the an earlier instruction, then that -earlier instruction must be sufficiently complete[*] before the later -instruction may proceed; in other words: provided that the appearance of -causality is maintained. - - [*] Some instructions have more than one effect - such as changing the - condition codes, changing registers or changing memory - and different - instructions may depend on different effects. - -A CPU may also discard any instruction sequence that winds up having no -ultimate effect. For example, if two adjacent instructions both load an -immediate value into the same register, the first may be discarded. - - -Similarly, it has to be assumed that compiler might reorder the instruction -stream in any way it sees fit, again provided the appearance of causality is -maintained. - - -============================ -THE EFFECTS OF THE CPU CACHE -============================ - -The way cached memory operations are perceived across the system is affected to -a certain extent by the caches that lie between CPUs and memory, and by the -memory coherence system that maintains the consistency of state in the system. - -As far as the way a CPU interacts with another part of the system through the -caches goes, the memory system has to include the CPU's caches, and memory -barriers for the most part act at the interface between the CPU and its cache -(memory barriers logically act on the dotted line in the following diagram): - - <--- CPU ---> : <----------- Memory -----------> - : - +--------+ +--------+ : +--------+ +-----------+ - | | | | : | | | | +--------+ - | CPU | | Memory | : | CPU | | | | | - | Core |--->| Access |----->| Cache |<-->| | | | - | | | Queue | : | | | |--->| Memory | - | | | | : | | | | | | - +--------+ +--------+ : +--------+ | | | | - : | Cache | +--------+ - : | Coherency | - : | Mechanism | +--------+ - +--------+ +--------+ : +--------+ | | | | - | | | | : | | | | | | - | CPU | | Memory | : | CPU | | |--->| Device | - | Core |--->| Access |----->| Cache |<-->| | | | - | | | Queue | : | | | | | | - | | | | : | | | | +--------+ - +--------+ +--------+ : +--------+ +-----------+ - : - : - -Although any particular load or store may not actually appear outside of the -CPU that issued it since it may have been satisfied within the CPU's own cache, -it will still appear as if the full memory access had taken place as far as the -other CPUs are concerned since the cache coherency mechanisms will migrate the -cacheline over to the accessing CPU and propagate the effects upon conflict. - -The CPU core may execute instructions in any order it deems fit, provided the -expected program causality appears to be maintained. Some of the instructions -generate load and store operations which then go into the queue of memory -accesses to be performed. The core may place these in the queue in any order -it wishes, and continue execution until it is forced to wait for an instruction -to complete. - -What memory barriers are concerned with is controlling the order in which -accesses cross from the CPU side of things to the memory side of things, and -the order in which the effects are perceived to happen by the other observers -in the system. - -[!] Memory barriers are _not_ needed within a given CPU, as CPUs always see -their own loads and stores as if they had happened in program order. - -[!] MMIO or other device accesses may bypass the cache system. This depends on -the properties of the memory window through which devices are accessed and/or -the use of any special device communication instructions the CPU may have. - - -CACHE COHERENCY ---------------- - -Life isn't quite as simple as it may appear above, however: for while the -caches are expected to be coherent, there's no guarantee that that coherency -will be ordered. This means that whilst changes made on one CPU will -eventually become visible on all CPUs, there's no guarantee that they will -become apparent in the same order on those other CPUs. - - -Consider dealing with a system that has pair of CPUs (1 & 2), each of which has -a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D): - - : - : +--------+ - : +---------+ | | - +--------+ : +--->| Cache A |<------->| | - | | : | +---------+ | | - | CPU 1 |<---+ | | - | | : | +---------+ | | - +--------+ : +--->| Cache B |<------->| | - : +---------+ | | - : | Memory | - : +---------+ | System | - +--------+ : +--->| Cache C |<------->| | - | | : | +---------+ | | - | CPU 2 |<---+ | | - | | : | +---------+ | | - +--------+ : +--->| Cache D |<------->| | - : +---------+ | | - : +--------+ - : - -Imagine the system has the following properties: - - (*) an odd-numbered cache line may be in cache A, cache C or it may still be - resident in memory; - - (*) an even-numbered cache line may be in cache B, cache D or it may still be - resident in memory; - - (*) whilst the CPU core is interrogating one cache, the other cache may be - making use of the bus to access the rest of the system - perhaps to - displace a dirty cacheline or to do a speculative load; - - (*) each cache has a queue of operations that need to be applied to that cache - to maintain coherency with the rest of the system; - - (*) the coherency queue is not flushed by normal loads to lines already - present in the cache, even though the contents of the queue may - potentially effect those loads. - -Imagine, then, that two writes are made on the first CPU, with a write barrier -between them to guarantee that they will appear to reach that CPU's caches in -the requisite order: - - CPU 1 CPU 2 COMMENT - =============== =============== ======================================= - u == 0, v == 1 and p == &u, q == &u - v = 2; - smp_wmb(); Make sure change to v visible before - change to p - v is now in cache A exclusively - p = &v; - p is now in cache B exclusively - -The write memory barrier forces the other CPUs in the system to perceive that -the local CPU's caches have apparently been updated in the correct order. But -now imagine that the second CPU that wants to read those values: - - CPU 1 CPU 2 COMMENT - =============== =============== ======================================= - ... - q = p; - x = *q; - -The above pair of reads may then fail to happen in expected order, as the -cacheline holding p may get updated in one of the second CPU's caches whilst -the update to the cacheline holding v is delayed in the other of the second -CPU's caches by some other cache event: - - CPU 1 CPU 2 COMMENT - =============== =============== ======================================= - u == 0, v == 1 and p == &u, q == &u - v = 2; - smp_wmb(); - - - p = &v; q = p; - - - - x = *q; - Reads from v before v updated in cache - - - -Basically, whilst both cachelines will be updated on CPU 2 eventually, there's -no guarantee that, without intervention, the order of update will be the same -as that committed on CPU 1. - - -To intervene, we need to interpolate a data dependency barrier or a read -barrier between the loads. This will force the cache to commit its coherency -queue before processing any further requests: - - CPU 1 CPU 2 COMMENT - =============== =============== ======================================= - u == 0, v == 1 and p == &u, q == &u - v = 2; - smp_wmb(); - - - p = &b; q = p; - - - - smp_read_barrier_depends() - - - x = *q; - Reads from v after v updated in cache - - -This sort of problem can be encountered on DEC Alpha processors as they have a -split cache that improves performance by making better use of the data bus. -Whilst most CPUs do imply a data dependency barrier on the read when a memory -access depends on a read, not all do, so it may not be relied on. - -Other CPUs may also have split caches, but must coordinate between the various -cachelets for normal memory accesss. The semantics of the Alpha removes the -need for coordination in absence of memory barriers. - - -CACHE COHERENCY VS DMA ----------------------- - -Not all systems maintain cache coherency with respect to devices doing DMA. In -such cases, a device attempting DMA may obtain stale data from RAM because -dirty cache lines may be resident in the caches of various CPUs, and may not -have been written back to RAM yet. To deal with this, the appropriate part of -the kernel must flush the overlapping bits of cache on each CPU (and maybe -invalidate them as well). - -In addition, the data DMA'd to RAM by a device may be overwritten by dirty -cache lines being written back to RAM from a CPU's cache after the device has -installed its own data, or cache lines simply present in a CPUs cache may -simply obscure the fact that RAM has been updated, until at such time as the -cacheline is discarded from the CPU's cache and reloaded. To deal with this, -the appropriate part of the kernel must invalidate the overlapping bits of the -cache on each CPU. - -See Documentation/cachetlb.txt for more information on cache management. - - -CACHE COHERENCY VS MMIO ------------------------ - -Memory mapped I/O usually takes place through memory locations that are part of -a window in the CPU's memory space that have different properties assigned than -the usual RAM directed window. - -Amongst these properties is usually the fact that such accesses bypass the -caching entirely and go directly to the device buses. This means MMIO accesses -may, in effect, overtake accesses to cached memory that were emitted earlier. -A memory barrier isn't sufficient in such a case, but rather the cache must be -flushed between the cached memory write and the MMIO access if the two are in -any way dependent. - - -========================= -THE THINGS CPUS GET UP TO -========================= - -A programmer might take it for granted that the CPU will perform memory -operations in exactly the order specified, so that if a CPU is, for example, -given the following piece of code to execute: - - a = *A; - *B = b; - c = *C; - d = *D; - *E = e; - -They would then expect that the CPU will complete the memory operation for each -instruction before moving on to the next one, leading to a definite sequence of -operations as seen by external observers in the system: - - LOAD *A, STORE *B, LOAD *C, LOAD *D, STORE *E. - - -Reality is, of course, much messier. With many CPUs and compilers, the above -assumption doesn't hold because: - - (*) loads are more likely to need to be completed immediately to permit - execution progress, whereas stores can often be deferred without a - problem; - - (*) loads may be done speculatively, and the result discarded should it prove - to have been unnecessary; - - (*) loads may be done speculatively, leading to the result having being - fetched at the wrong time in the expected sequence of events; - - (*) the order of the memory accesses may be rearranged to promote better use - of the CPU buses and caches; - - (*) loads and stores may be combined to improve performance when talking to - memory or I/O hardware that can do batched accesses of adjacent locations, - thus cutting down on transaction setup costs (memory and PCI devices may - both be able to do this); and - - (*) the CPU's data cache may affect the ordering, and whilst cache-coherency - mechanisms may alleviate this - once the store has actually hit the cache - - there's no guarantee that the coherency management will be propagated in - order to other CPUs. - -So what another CPU, say, might actually observe from the above piece of code -is: - - LOAD *A, ..., LOAD {*C,*D}, STORE *E, STORE *B - - (Where "LOAD {*C,*D}" is a combined load) - - -However, it is guaranteed that a CPU will be self-consistent: it will see its -_own_ accesses appear to be correctly ordered, without the need for a memory -barrier. For instance with the following code: - - U = *A; - *A = V; - *A = W; - X = *A; - *A = Y; - Z = *A; - -and assuming no intervention by an external influence, it can be assumed that -the final result will appear to be: - - U == the original value of *A - X == W - Z == Y - *A == Y - -The code above may cause the CPU to generate the full sequence of memory -accesses: - - U=LOAD *A, STORE *A=V, STORE *A=W, X=LOAD *A, STORE *A=Y, Z=LOAD *A - -in that order, but, without intervention, the sequence may have almost any -combination of elements combined or discarded, provided the program's view of -the world remains consistent. - -The compiler may also combine, discard or defer elements of the sequence before -the CPU even sees them. - -For instance: - - *A = V; - *A = W; - -may be reduced to: - - *A = W; - -since, without a write barrier, it can be assumed that the effect of the -storage of V to *A is lost. Similarly: - - *A = Y; - Z = *A; - -may, without a memory barrier, be reduced to: - - *A = Y; - Z = Y; - -and the LOAD operation never appear outside of the CPU. - - -AND THEN THERE'S THE ALPHA --------------------------- - -The DEC Alpha CPU is one of the most relaxed CPUs there is. Not only that, -some versions of the Alpha CPU have a split data cache, permitting them to have -two semantically related cache lines updating at separate times. This is where -the data dependency barrier really becomes necessary as this synchronises both -caches with the memory coherence system, thus making it seem like pointer -changes vs new data occur in the right order. - -The Alpha defines the Linux's kernel's memory barrier model. - -See the subsection on "Cache Coherency" above. - - -========== -REFERENCES -========== - -Alpha AXP Architecture Reference Manual, Second Edition (Sites & Witek, -Digital Press) - Chapter 5.2: Physical Address Space Characteristics - Chapter 5.4: Caches and Write Buffers - Chapter 5.5: Data Sharing - Chapter 5.6: Read/Write Ordering - -AMD64 Architecture Programmer's Manual Volume 2: System Programming - Chapter 7.1: Memory-Access Ordering - Chapter 7.4: Buffering and Combining Memory Writes - -IA-32 Intel Architecture Software Developer's Manual, Volume 3: -System Programming Guide - Chapter 7.1: Locked Atomic Operations - Chapter 7.2: Memory Ordering - Chapter 7.4: Serializing Instructions - -The SPARC Architecture Manual, Version 9 - Chapter 8: Memory Models - Appendix D: Formal Specification of the Memory Models - Appendix J: Programming with the Memory Models - -UltraSPARC Programmer Reference Manual - Chapter 5: Memory Accesses and Cacheability - Chapter 15: Sparc-V9 Memory Models - -UltraSPARC III Cu User's Manual - Chapter 9: Memory Models - -UltraSPARC IIIi Processor User's Manual - Chapter 8: Memory Models - -UltraSPARC Architecture 2005 - Chapter 9: Memory - Appendix D: Formal Specifications of the Memory Models - -UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005 - Chapter 8: Memory Models - Appendix F: Caches and Cache Coherency - -Solaris Internals, Core Kernel Architecture, p63-68: - Chapter 3.3: Hardware Considerations for Locks and - Synchronization - -Unix Systems for Modern Architectures, Symmetric Multiprocessing and Caching -for Kernel Programmers: - Chapter 13: Other Memory Models - -Intel Itanium Architecture Software Developer's Manual: Volume 1: - Section 2.6: Speculation - Section 4.4: Memory Access diff --git a/Documentation/mtrr.txt b/Documentation/mtrr.txt index c39ac3959..b78af1c32 100644 --- a/Documentation/mtrr.txt +++ b/Documentation/mtrr.txt @@ -138,29 +138,19 @@ Reading MTRRs from a C program using ioctl()'s: */ #include -#include #include #include #include #include #include #include +#define MTRR_NEED_STRINGS #include #define TRUE 1 #define FALSE 0 #define ERRSTRING strerror (errno) -static char *mtrr_strings[MTRR_NUM_TYPES] = -{ - "uncachable", /* 0 */ - "write-combining", /* 1 */ - "?", /* 2 */ - "?", /* 3 */ - "write-through", /* 4 */ - "write-protect", /* 5 */ - "write-back", /* 6 */ -}; int main () { @@ -242,22 +232,13 @@ Creating MTRRs from a C programme using ioctl()'s: #include #include #include +#define MTRR_NEED_STRINGS #include #define TRUE 1 #define FALSE 0 #define ERRSTRING strerror (errno) -static char *mtrr_strings[MTRR_NUM_TYPES] = -{ - "uncachable", /* 0 */ - "write-combining", /* 1 */ - "?", /* 2 */ - "?", /* 3 */ - "write-through", /* 4 */ - "write-protect", /* 5 */ - "write-back", /* 6 */ -}; int main (int argc, char **argv) { diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index b1181ce23..5b01d5cc4 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX @@ -92,6 +92,8 @@ routing.txt - the new routing mechanism shaper.txt - info on the module that can shape/limit transmitted traffic. +sis900.txt + - SiS 900/7016 Fast Ethernet device driver info. sk98lin.txt - Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit Ethernet Adapter family driver info diff --git a/Documentation/networking/README.ipw2100 b/Documentation/networking/README.ipw2100 index 93bba8b17..3ab40379d 100644 --- a/Documentation/networking/README.ipw2100 +++ b/Documentation/networking/README.ipw2100 @@ -1,32 +1,112 @@ -Intel PRO/Wireless 2100 802.11b Driver for Linux -README.ipw2100 +Intel(R) PRO/Wireless 2100 Driver for Linux in support of: -October 13, 2004 +Intel(R) PRO/Wireless 2100 Network Connection +Copyright (C) 2003-2005, Intel Corporation -Release 0.56 Current Features ------------- ----- ----- ---- --- -- - +README.ipw2100 -- IBSS and BSS modes -- 802.11 fragmentation +Version: 1.1.3 +Date : October 17, 2005 + +Index +----------------------------------------------- +0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER +1. Introduction +2. Release 1.1.3 Current Features +3. Command Line Parameters +4. Sysfs Helper Files +5. Radio Kill Switch +6. Dynamic Firmware +7. Power Management +8. Support +9. License + + +0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER +----------------------------------------------- + +Important Notice FOR ALL USERS OR DISTRIBUTORS!!!! + +Intel wireless LAN adapters are engineered, manufactured, tested, and +quality checked to ensure that they meet all necessary local and +governmental regulatory agency requirements for the regions that they +are designated and/or marked to ship into. Since wireless LANs are +generally unlicensed devices that share spectrum with radars, +satellites, and other licensed and unlicensed devices, it is sometimes +necessary to dynamically detect, avoid, and limit usage to avoid +interference with these devices. In many instances Intel is required to +provide test data to prove regional and local compliance to regional and +governmental regulations before certification or approval to use the +product is granted. Intel's wireless LAN's EEPROM, firmware, and +software driver are designed to carefully control parameters that affect +radio operation and to ensure electromagnetic compliance (EMC). These +parameters include, without limitation, RF power, spectrum usage, +channel scanning, and human exposure. + +For these reasons Intel cannot permit any manipulation by third parties +of the software provided in binary format with the wireless WLAN +adapters (e.g., the EEPROM and firmware). Furthermore, if you use any +patches, utilities, or code with the Intel wireless LAN adapters that +have been manipulated by an unauthorized party (i.e., patches, +utilities, or code (including open source code modifications) which have +not been validated by Intel), (i) you will be solely responsible for +ensuring the regulatory compliance of the products, (ii) Intel will bear +no liability, under any theory of liability for any issues associated +with the modified products, including without limitation, claims under +the warranty and/or issues arising from regulatory non-compliance, and +(iii) Intel will not provide or be required to assist in providing +support to any third parties for such modified products. + +Note: Many regulatory agencies consider Wireless LAN adapters to be +modules, and accordingly, condition system-level regulatory approval +upon receipt and review of test data documenting that the antennas and +system configuration do not cause the EMC and radio operation to be +non-compliant. + +The drivers available for download from SourceForge are provided as a +part of a development project. Conformance to local regulatory +requirements is the responsibility of the individual developer. As +such, if you are interested in deploying or shipping a driver as part of +solution intended to be used for purposes other than development, please +obtain a tested driver from Intel Customer Support at: + +http://support.intel.com/support/notebook/sb/CS-006408.htm + + +1. Introduction +----------------------------------------------- + +This document provides a brief overview of the features supported by the +IPW2100 driver project. The main project website, where the latest +development version of the driver can be found, is: + + http://ipw2100.sourceforge.net + +There you can find the not only the latest releases, but also information about +potential fixes and patches, as well as links to the development mailing list +for the driver project. + + +2. Release 1.1.3 Current Supported Features +----------------------------------------------- +- Managed (BSS) and Ad-Hoc (IBSS) - WEP (shared key and open) -- wireless extension support -- 802.1x EAP via xsupplicant +- Wireless Tools support +- 802.1x (tested with XSupplicant 1.0.1) + +Enabled (but not supported) features: - Monitor/RFMon mode -- transmit power control -- long/short preamble support -- power states support (ACPI) +- WPA/WPA2 -TODO ------------- ----- ----- ---- --- -- - -- Fix bugs... The biggies: - C3 corruption - Fragmentation +The distinction between officially supported and enabled is a reflection +on the amount of validation and interoperability testing that has been +performed on a given feature. -Command Line Parameters ------------- ----- ----- ---- --- -- - +3. Command Line Parameters +----------------------------------------------- If the driver is built as a module, the following optional parameters are used by entering them on the command line with the modprobe command using this @@ -34,54 +114,80 @@ syntax: modprobe ipw2100 [ @@ -1225,7 +1225,7 @@ allocating resources. Also, you need to set the proper PCI DMA mask to limit the accessed i/o range. In some cases, you might need to call pci_set_master() function, - too. + too. @@ -1236,8 +1236,8 @@ Now assume that this PCI device has an I/O port with 8 bytes and an interrupt. Then struct mychip will have the - following fields: + following fields: @@ -1565,7 +1565,7 @@ format); mychip_set_sample_rate(chip, runtime->rate); mychip_set_channels(chip, runtime->channels); - mychip_set_dma_setup(chip, runtime->dma_addr, + mychip_set_dma_setup(chip, runtime->dma_area, chip->buffer_size, chip->period_size); return 0; @@ -2836,7 +2836,7 @@ struct _snd_pcm_runtime { Note that this callback became non-atomic since the recent version. - You can use schedule-related functions safely in this callback now. + You can use schedule-related fucntions safely in this callback now. @@ -3388,7 +3388,7 @@ struct _snd_pcm_runtime { .name = "PCM Playback Switch", .index = 0, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .private_value = 0xffff, + .private_values = 0xffff, .info = my_control_info, .get = my_control_get, .put = my_control_put @@ -3449,7 +3449,7 @@ struct _snd_pcm_runtime { - The private_value field contains + The private_values field contains an arbitrary long integer value for this record. When using generic info, get and diff --git a/Documentation/sound/oss/Introduction b/Documentation/sound/oss/Introduction index f04ba6bb7..15d4fb975 100644 --- a/Documentation/sound/oss/Introduction +++ b/Documentation/sound/oss/Introduction @@ -69,7 +69,7 @@ are available, for example IRQ, address, DMA. Warning, the options for different cards sometime use different names for the same or a similar feature (dma1= versus dma16=). As a last -resort, inspect the code (search for module_param). +resort, inspect the code (search for MODULE_PARM). Notes: diff --git a/Documentation/sound/oss/cs46xx b/Documentation/sound/oss/cs46xx index b54432709..88d6cf8b3 100644 --- a/Documentation/sound/oss/cs46xx +++ b/Documentation/sound/oss/cs46xx @@ -88,7 +88,7 @@ parameters. for a copy email: twoller@crystal.cirrus.com MODULE_PARMS definitions ------------------------ -module_param(defaultorder, ulong, 0); +MODULE_PARM(defaultorder, "i"); defaultorder=N where N is a value from 1 to 12 The buffer order determines the size of the dma buffer for the driver. @@ -98,18 +98,18 @@ to not underrun the dma buffer as easily. As default, use 32k (order=3) rather than 64k as some of the games work more responsively. (2^N) * PAGE_SIZE = allocated buffer size -module_param(cs_debuglevel, ulong, 0644); -module_param(cs_debugmask, ulong, 0644); +MODULE_PARM(cs_debuglevel, "i"); +MODULE_PARM(cs_debugmask, "i"); cs_debuglevel=N cs_debugmask=0xMMMMMMMM where N is a value from 0 (no debug printfs), to 9 (maximum) 0xMMMMMMMM is a debug mask corresponding to the CS_xxx bits (see driver source). -module_param(hercules_egpio_disable, ulong, 0); +MODULE_PARM(hercules_egpio_disable, "i"); hercules_egpio_disable=N where N is a 0 (enable egpio), or a 1 (disable egpio support) -module_param(initdelay, ulong, 0); +MODULE_PARM(initdelay, "i"); initdelay=N This value is used to determine the millescond delay during the initialization code prior to powering up the PLL. On laptops this value can be used to @@ -118,19 +118,19 @@ system is booted under battery power then the mdelay()/udelay() functions fail t properly delay the required time. Also, if the system is booted under AC power and then the power removed, the mdelay()/udelay() functions will not delay properly. -module_param(powerdown, ulong, 0); +MODULE_PARM(powerdown, "i"); powerdown=N where N is 0 (disable any powerdown of the internal blocks) or 1 (enable powerdown) -module_param(external_amp, bool, 0); +MODULE_PARM(external_amp, "i"); external_amp=1 if N is set to 1, then force enabling the EAPD support in the primary AC97 codec. override the detection logic and force the external amp bit in the AC97 0x26 register to be reset (0). EAPD should be 0 for powerup, and 1 for powerdown. The VTB Santa Cruz card has inverted logic, so there is a special function for these cards. -module_param(thinkpad, bool, 0); +MODULE_PARM(thinkpad, "i"); thinkpad=1 if N is set to 1, then force enabling the clkrun functionality. Currently, when the part is being used, then clkrun is disabled for the entire system, diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx deleted file mode 100644 index 9c45f3df2..000000000 --- a/Documentation/spi/pxa2xx +++ /dev/null @@ -1,234 +0,0 @@ -PXA2xx SPI on SSP driver HOWTO -=================================================== -This a mini howto on the pxa2xx_spi driver. The driver turns a PXA2xx -synchronous serial port into a SPI master controller -(see Documentation/spi/spi_summary). The driver has the following features - -- Support for any PXA2xx SSP -- SSP PIO and SSP DMA data transfers. -- External and Internal (SSPFRM) chip selects. -- Per slave device (chip) configuration. -- Full suspend, freeze, resume support. - -The driver is built around a "spi_message" fifo serviced by workqueue and a -tasklet. The workqueue, "pump_messages", drives message fifo and the tasklet -(pump_transfer) is responsible for queuing SPI transactions and setting up and -launching the dma/interrupt driven transfers. - -Declaring PXA2xx Master Controllers ------------------------------------ -Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a -"platform device". The master configuration is passed to the driver via a table -found in include/asm-arm/arch-pxa/pxa2xx_spi.h: - -struct pxa2xx_spi_master { - enum pxa_ssp_type ssp_type; - u32 clock_enable; - u16 num_chipselect; - u8 enable_dma; -}; - -The "pxa2xx_spi_master.ssp_type" field must have a value between 1 and 3 and -informs the driver which features a particular SSP supports. - -The "pxa2xx_spi_master.clock_enable" field is used to enable/disable the -corresponding SSP peripheral block in the "Clock Enable Register (CKEN"). See -the "PXA2xx Developer Manual" section "Clocks and Power Management". - -The "pxa2xx_spi_master.num_chipselect" field is used to determine the number of -slave device (chips) attached to this SPI master. - -The "pxa2xx_spi_master.enable_dma" field informs the driver that SSP DMA should -be used. This caused the driver to acquire two DMA channels: rx_channel and -tx_channel. The rx_channel has a higher DMA service priority the tx_channel. -See the "PXA2xx Developer Manual" section "DMA Controller". - -NSSP MASTER SAMPLE ------------------- -Below is a sample configuration using the PXA255 NSSP. - -static struct resource pxa_spi_nssp_resources[] = { - [0] = { - .start = __PREG(SSCR0_P(2)), /* Start address of NSSP */ - .end = __PREG(SSCR0_P(2)) + 0x2c, /* Range of registers */ - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_NSSP, /* NSSP IRQ */ - .end = IRQ_NSSP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct pxa2xx_spi_master pxa_nssp_master_info = { - .ssp_type = PXA25x_NSSP, /* Type of SSP */ - .clock_enable = CKEN9_NSSP, /* NSSP Peripheral clock */ - .num_chipselect = 1, /* Matches the number of chips attached to NSSP */ - .enable_dma = 1, /* Enables NSSP DMA */ -}; - -static struct platform_device pxa_spi_nssp = { - .name = "pxa2xx-spi", /* MUST BE THIS VALUE, so device match driver */ - .id = 2, /* Bus number, MUST MATCH SSP number 1..n */ - .resource = pxa_spi_nssp_resources, - .num_resources = ARRAY_SIZE(pxa_spi_nssp_resources), - .dev = { - .platform_data = &pxa_nssp_master_info, /* Passed to driver */ - }, -}; - -static struct platform_device *devices[] __initdata = { - &pxa_spi_nssp, -}; - -static void __init board_init(void) -{ - (void)platform_add_device(devices, ARRAY_SIZE(devices)); -} - -Declaring Slave Devices ------------------------ -Typically each SPI slave (chip) is defined in the arch/.../mach-*/board-*.c -using the "spi_board_info" structure found in "linux/spi/spi.h". See -"Documentation/spi/spi_summary" for additional information. - -Each slave device attached to the PXA must provide slave specific configuration -information via the structure "pxa2xx_spi_chip" found in -"include/asm-arm/arch-pxa/pxa2xx_spi.h". The pxa2xx_spi master controller driver -will uses the configuration whenever the driver communicates with the slave -device. - -struct pxa2xx_spi_chip { - u8 tx_threshold; - u8 rx_threshold; - u8 dma_burst_size; - u32 timeout_microsecs; - u8 enable_loopback; - void (*cs_control)(u32 command); -}; - -The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are -used to configure the SSP hardware fifo. These fields are critical to the -performance of pxa2xx_spi driver and misconfiguration will result in rx -fifo overruns (especially in PIO mode transfers). Good default values are - - .tx_threshold = 12, - .rx_threshold = 4, - -The "pxa2xx_spi_chip.dma_burst_size" field is used to configure PXA2xx DMA -engine and is related the "spi_device.bits_per_word" field. Read and understand -the PXA2xx "Developer Manual" sections on the DMA controller and SSP Controllers -to determine the correct value. An SSP configured for byte-wide transfers would -use a value of 8. - -The "pxa2xx_spi_chip.timeout_microsecs" fields is used to efficiently handle -trailing bytes in the SSP receiver fifo. The correct value for this field is -dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific -slave device. Please note the the PXA2xx SSP 1 does not support trailing byte -timeouts and must busy-wait any trailing bytes. - -The "pxa2xx_spi_chip.enable_loopback" field is used to place the SSP porting -into internal loopback mode. In this mode the SSP controller internally -connects the SSPTX pin the the SSPRX pin. This is useful for initial setup -testing. - -The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific -function for asserting/deasserting a slave device chip select. If the field is -NULL, the pxa2xx_spi master controller driver assumes that the SSP port is -configured to use SSPFRM instead. - -NSSP SALVE SAMPLE ------------------ -The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the -"spi_board_info.controller_data" field. Below is a sample configuration using -the PXA255 NSSP. - -/* Chip Select control for the CS8415A SPI slave device */ -static void cs8415a_cs_control(u32 command) -{ - if (command & PXA2XX_CS_ASSERT) - GPCR(2) = GPIO_bit(2); - else - GPSR(2) = GPIO_bit(2); -} - -/* Chip Select control for the CS8405A SPI slave device */ -static void cs8405a_cs_control(u32 command) -{ - if (command & PXA2XX_CS_ASSERT) - GPCR(3) = GPIO_bit(3); - else - GPSR(3) = GPIO_bit(3); -} - -static struct pxa2xx_spi_chip cs8415a_chip_info = { - .tx_threshold = 12, /* SSP hardward FIFO threshold */ - .rx_threshold = 4, /* SSP hardward FIFO threshold */ - .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */ - .timeout_microsecs = 64, /* Wait at least 64usec to handle trailing */ - .cs_control = cs8415a_cs_control, /* Use external chip select */ -}; - -static struct pxa2xx_spi_chip cs8405a_chip_info = { - .tx_threshold = 12, /* SSP hardward FIFO threshold */ - .rx_threshold = 4, /* SSP hardward FIFO threshold */ - .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */ - .timeout_microsecs = 64, /* Wait at least 64usec to handle trailing */ - .cs_control = cs8405a_cs_control, /* Use external chip select */ -}; - -static struct spi_board_info streetracer_spi_board_info[] __initdata = { - { - .modalias = "cs8415a", /* Name of spi_driver for this device */ - .max_speed_hz = 3686400, /* Run SSP as fast a possbile */ - .bus_num = 2, /* Framework bus number */ - .chip_select = 0, /* Framework chip select */ - .platform_data = NULL; /* No spi_driver specific config */ - .controller_data = &cs8415a_chip_info, /* Master chip config */ - .irq = STREETRACER_APCI_IRQ, /* Slave device interrupt */ - }, - { - .modalias = "cs8405a", /* Name of spi_driver for this device */ - .max_speed_hz = 3686400, /* Run SSP as fast a possbile */ - .bus_num = 2, /* Framework bus number */ - .chip_select = 1, /* Framework chip select */ - .controller_data = &cs8405a_chip_info, /* Master chip config */ - .irq = STREETRACER_APCI_IRQ, /* Slave device interrupt */ - }, -}; - -static void __init streetracer_init(void) -{ - spi_register_board_info(streetracer_spi_board_info, - ARRAY_SIZE(streetracer_spi_board_info)); -} - - -DMA and PIO I/O Support ------------------------ -The pxa2xx_spi driver support both DMA and interrupt driven PIO message -transfers. The driver defaults to PIO mode and DMA transfers must enabled by -setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and and -ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero. The DMA -mode support both coherent and stream based DMA mappings. - -The following logic is used to determine the type of I/O to be used on -a per "spi_transfer" basis: - -if !enable_dma or dma_burst_size == 0 then - always use PIO transfers - -if spi_message.is_dma_mapped and rx_dma_buf != 0 and tx_dma_buf != 0 then - use coherent DMA mode - -if rx_buf and tx_buf are aligned on 8 byte boundary then - use streaming DMA mode - -otherwise - use PIO transfer - -THANKS TO ---------- - -David Brownell and others for mentoring the development of this driver. - diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index 068732d32..a5ffba33a 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -414,33 +414,7 @@ to get the driver-private data allocated for that device. The driver will initialize the fields of that spi_master, including the bus number (maybe the same as the platform device ID) and three methods used to interact with the SPI core and SPI protocol drivers. It will -also initialize its own internal state. (See below about bus numbering -and those methods.) - -After you initialize the spi_master, then use spi_register_master() to -publish it to the rest of the system. At that time, device nodes for -the controller and any predeclared spi devices will be made available, -and the driver model core will take care of binding them to drivers. - -If you need to remove your SPI controller driver, spi_unregister_master() -will reverse the effect of spi_register_master(). - - -BUS NUMBERING - -Bus numbering is important, since that's how Linux identifies a given -SPI bus (shared SCK, MOSI, MISO). Valid bus numbers start at zero. On -SOC systems, the bus numbers should match the numbers defined by the chip -manufacturer. For example, hardware controller SPI2 would be bus number 2, -and spi_board_info for devices connected to it would use that number. - -If you don't have such hardware-assigned bus number, and for some reason -you can't just assign them, then provide a negative bus number. That will -then be replaced by a dynamically assigned number. You'd then need to treat -this as a non-static configuration (see above). - - -SPI MASTER METHODS +also initialize its own internal state. master->setup(struct spi_device *spi) This sets up the device clock rate, SPI mode, and word sizes. @@ -457,9 +431,6 @@ SPI MASTER METHODS state it dynamically associates with that device. If you do that, be sure to provide the cleanup() method to free that state. - -SPI MESSAGE QUEUE - The bulk of the driver will be managing the I/O queue fed by transfer(). That queue could be purely conceptual. For example, a driver used only @@ -469,9 +440,6 @@ But the queue will probably be very real, using message->queue, PIO, often DMA (especially if the root filesystem is in SPI flash), and execution contexts like IRQ handlers, tasklets, or workqueues (such as keventd). Your driver can be as fancy, or as simple, as you need. -Such a transfer() method would normally just add the message to a -queue, and then start some asynchronous transfer engine (unless it's -already running). THANKS TO diff --git a/Documentation/spinlocks.txt b/Documentation/spinlocks.txt index a661d6847..c21229966 100644 --- a/Documentation/spinlocks.txt +++ b/Documentation/spinlocks.txt @@ -9,7 +9,7 @@ removed soon. So for any new code dynamic initialization should be used: static int __init xxx_init(void) { spin_lock_init(&xxx_lock); - rwlock_init(&xxx_rw_lock); + rw_lock_init(&xxx_rw_lock); ... } diff --git a/Documentation/video4linux/ibmcam.txt b/Documentation/usb/ibmcam.txt similarity index 99% rename from Documentation/video4linux/ibmcam.txt rename to Documentation/usb/ibmcam.txt index 4a40a2e99..c25003644 100644 --- a/Documentation/video4linux/ibmcam.txt +++ b/Documentation/usb/ibmcam.txt @@ -122,7 +122,7 @@ WHAT YOU NEED: - A Linux box with USB support (2.3/2.4; 2.2 w/backport may work) - A Video4Linux compatible frame grabber program such as xawtv. - + HOW TO COMPILE THE DRIVER: You need to compile the driver only if you are a developer diff --git a/Documentation/video4linux/ov511.txt b/Documentation/usb/ov511.txt similarity index 99% rename from Documentation/video4linux/ov511.txt rename to Documentation/usb/ov511.txt index 142741e3c..a7fc0432b 100644 --- a/Documentation/video4linux/ov511.txt +++ b/Documentation/usb/ov511.txt @@ -9,7 +9,7 @@ INTRODUCTION: This is a driver for the OV511, a USB-only chip used in many "webcam" devices. Any camera using the OV511/OV511+ and the OV6620/OV7610/20/20AE should work. -Video capture devices that use the Philips SAA7111A decoder also work. It +Video capture devices that use the Philips SAA7111A decoder also work. It supports streaming and capture of color or monochrome video via the Video4Linux API. Most V4L apps are compatible with it. Most resolutions with a width and height that are a multiple of 8 are supported. @@ -52,15 +52,15 @@ from it: chmod 666 /dev/video chmod 666 /dev/video0 (if necessary) - + Now you are ready to run a video app! Both vidcat and xawtv work well for me at 640x480. - + [Using vidcat:] vidcat -s 640x480 -p c > test.jpg xview test.jpg - + [Using xawtv:] From the main xawtv directory: @@ -70,7 +70,7 @@ From the main xawtv directory: make make install -Now you should be able to run xawtv. Right click for the options dialog. +Now you should be able to run xawtv. Right click for the options dialog. MODULE PARAMETERS: @@ -286,3 +286,4 @@ Randy Dunlap, and others. Big thanks to them for their pioneering work on that and the USB stack. Thanks to Bret Wallach for getting camera reg IO, ISOC, and image capture working. Thanks to Orion Sky Lawlor, Kevin Moore, and Claudio Matsuoka for their work as well. + diff --git a/Documentation/video4linux/se401.txt b/Documentation/usb/se401.txt similarity index 100% rename from Documentation/video4linux/se401.txt rename to Documentation/usb/se401.txt diff --git a/Documentation/video4linux/sn9c102.txt b/Documentation/usb/sn9c102.txt similarity index 96% rename from Documentation/video4linux/sn9c102.txt rename to Documentation/usb/sn9c102.txt index 142920bc0..c6b764141 100644 --- a/Documentation/video4linux/sn9c102.txt +++ b/Documentation/usb/sn9c102.txt @@ -174,7 +174,7 @@ Module parameters are listed below: ------------------------------------------------------------------------------- Name: video_nr Type: short array (min = 0, max = 64) -Syntax: <-1|n[,...]> +Syntax: <-1|n[,...]> Description: Specify V4L2 minor mode number: -1 = use next available n = use minor number n @@ -187,7 +187,7 @@ Default: -1 ------------------------------------------------------------------------------- Name: force_munmap Type: bool array (min = 0, max = 64) -Syntax: <0|1[,...]> +Syntax: <0|1[,...]> Description: Force the application to unmap previously mapped buffer memory before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not all the applications support this feature. This parameter is @@ -196,17 +196,9 @@ Description: Force the application to unmap previously mapped buffer memory 1 = force memory unmapping (save memory) Default: 0 ------------------------------------------------------------------------------- -Name: frame_timeout -Type: uint array (min = 0, max = 64) -Syntax: -Description: Timeout for a video frame in seconds. This parameter is - specific for each detected camera. This parameter can be - changed at runtime thanks to the /sys filesystem interface. -Default: 2 -------------------------------------------------------------------------------- Name: debug Type: ushort -Syntax: +Syntax: Description: Debugging information level, from 0 to 3: 0 = none (use carefully) 1 = critical errors @@ -267,7 +259,7 @@ The sysfs interface also provides the "frame_header" entry, which exports the frame header of the most recent requested and captured video frame. The header is always 18-bytes long and is appended to every video frame by the SN9C10x controllers. As an example, this additional information can be used by the user -application for implementing auto-exposure features via software. +application for implementing auto-exposure features via software. The following table describes the frame header: @@ -329,7 +321,6 @@ Vendor ID Product ID --------- ---------- 0x0c45 0x6001 0x0c45 0x6005 -0x0c45 0x6007 0x0c45 0x6009 0x0c45 0x600d 0x0c45 0x6024 @@ -379,7 +370,6 @@ HV7131D Hynix Semiconductor, Inc. MI-0343 Micron Technology, Inc. OV7630 OmniVision Technologies, Inc. PAS106B PixArt Imaging, Inc. -PAS202BCA PixArt Imaging, Inc. PAS202BCB PixArt Imaging, Inc. TAS5110C1B Taiwan Advanced Sensor Corporation TAS5130D1B Taiwan Advanced Sensor Corporation @@ -441,7 +431,7 @@ blue pixels in one video frame. Each pixel is associated with a 8-bit long value and is disposed in memory according to the pattern shown below: B[0] G[1] B[2] G[3] ... B[m-2] G[m-1] -G[m] R[m+1] G[m+2] R[m+2] ... G[2m-2] R[2m-1] +G[m] R[m+1] G[m+2] R[m+2] ... G[2m-2] R[2m-1] ... ... B[(n-1)(m-2)] G[(n-1)(m-1)] ... G[n(m-2)] R[n(m-1)] @@ -472,12 +462,12 @@ The pixel reference value is calculated as follows: The algorithm purely describes the conversion from compressed Bayer code used in the SN9C10x chips to uncompressed Bayer. Additional steps are required to convert this to a color image (i.e. a color interpolation algorithm). - + The following Huffman codes have been found: -0: +0 (relative to reference pixel value) +0: +0 (relative to reference pixel value) 100: +4 101: -4? -1110xxxx: set absolute value to xxxx.0000 +1110xxxx: set absolute value to xxxx.0000 1101: +11 1111: -11 11001: +20 @@ -503,7 +493,6 @@ Many thanks to following persons for their contribute (listed in alphabetical order): - Luca Capello for the donation of a webcam; -- Philippe Coval for having helped testing the PAS202BCA image sensor; - Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the donation of a webcam; - Jon Hollstrom for the donation of a webcam; diff --git a/Documentation/video4linux/stv680.txt b/Documentation/usb/stv680.txt similarity index 82% rename from Documentation/video4linux/stv680.txt rename to Documentation/usb/stv680.txt index 4f8946f32..6448041e7 100644 --- a/Documentation/video4linux/stv680.txt +++ b/Documentation/usb/stv680.txt @@ -5,15 +5,15 @@ Copyright, 2001, Kevin Sisson INTRODUCTION: -STMicroelectronics produces the STV0680B chip, which comes in two -types, -001 and -003. The -003 version allows the recording and downloading -of sound clips from the camera, and allows a flash attachment. Otherwise, -it uses the same commands as the -001 version. Both versions support a -variety of SDRAM sizes and sensors, allowing for a maximum of 26 VGA or 20 -CIF pictures. The STV0680 supports either a serial or a usb interface, and +STMicroelectronics produces the STV0680B chip, which comes in two +types, -001 and -003. The -003 version allows the recording and downloading +of sound clips from the camera, and allows a flash attachment. Otherwise, +it uses the same commands as the -001 version. Both versions support a +variety of SDRAM sizes and sensors, allowing for a maximum of 26 VGA or 20 +CIF pictures. The STV0680 supports either a serial or a usb interface, and video is possible through the usb interface. -The following cameras are known to work with this driver, although any +The following cameras are known to work with this driver, although any camera with Vendor/Product codes of 0553/0202 should work: Aiptek Pencam (various models) @@ -34,15 +34,15 @@ http://www.linux-usb.org MODULE OPTIONS: When the driver is compiled as a module, you can set a "swapRGB=1" -option, if necessary, for those applications that require it -(such as xawtv). However, the driver should detect and set this +option, if necessary, for those applications that require it +(such as xawtv). However, the driver should detect and set this automatically, so this option should not normally be used. KNOWN PROBLEMS: -The driver seems to work better with the usb-ohci than the usb-uhci host -controller driver. +The driver seems to work better with the usb-ohci than the usb-uhci host +controller driver. HELP: @@ -50,4 +50,6 @@ The latest info on this driver can be found at: http://personal.clt.bellsouth.net/~kjsisson or at http://stv0680-usb.sourceforge.net -Any questions to me can be send to: kjsisson@bellsouth.net \ No newline at end of file +Any questions to me can be send to: kjsisson@bellsouth.net + + diff --git a/Documentation/video4linux/w9968cf.txt b/Documentation/usb/w9968cf.txt similarity index 97% rename from Documentation/video4linux/w9968cf.txt rename to Documentation/usb/w9968cf.txt index 3b704f2aa..9d46cd0b1 100644 --- a/Documentation/video4linux/w9968cf.txt +++ b/Documentation/usb/w9968cf.txt @@ -1,5 +1,5 @@ - W996[87]CF JPEG USB Dual Mode Camera Chip + W996[87]CF JPEG USB Dual Mode Camera Chip Driver for Linux 2.6 (basic version) ========================================= @@ -115,7 +115,7 @@ additional testing and full support, would be much appreciated. ====================== For it to work properly, the driver needs kernel support for Video4Linux, USB and I2C, and the "ovcamchip" module for the image sensor. Make sure you are not -actually using any external "ovcamchip" module, given that the W996[87]CF +actually using any external "ovcamchip" module, given that the W996[87]CF driver depends on the version of the module present in the official kernels. The following options of the kernel configuration file must be enabled and @@ -197,16 +197,16 @@ Note: The kernel must be compiled with the CONFIG_KMOD option enabled for the 'ovcamchip' module to be loaded and for this parameter to be present. ------------------------------------------------------------------------------- -Name: simcams -Type: int -Syntax: +Name: simcams +Type: int +Syntax: Description: Number of cameras allowed to stream simultaneously. n may vary from 0 to 32. Default: 32 ------------------------------------------------------------------------------- Name: video_nr Type: int array (min = 0, max = 32) -Syntax: <-1|n[,...]> +Syntax: <-1|n[,...]> Description: Specify V4L minor mode number. -1 = use next available n = use minor number n @@ -219,7 +219,7 @@ Default: -1 ------------------------------------------------------------------------------- Name: packet_size Type: int array (min = 0, max = 32) -Syntax: +Syntax: Description: Specify the maximum data payload size in bytes for alternate settings, for each device. n is scaled between 63 and 1023. Default: 1023 @@ -234,7 +234,7 @@ Default: 2 ------------------------------------------------------------------------------- Name: double_buffer Type: bool array (min = 0, max = 32) -Syntax: <0|1[,...]> +Syntax: <0|1[,...]> Description: Hardware double buffering: 0 disabled, 1 enabled. It should be enabled if you want smooth video output: if you obtain out of sync. video, disable it, or try to @@ -243,13 +243,13 @@ Default: 1 for every device. ------------------------------------------------------------------------------- Name: clamping Type: bool array (min = 0, max = 32) -Syntax: <0|1[,...]> +Syntax: <0|1[,...]> Description: Video data clamping: 0 disabled, 1 enabled. Default: 0 for every device. ------------------------------------------------------------------------------- Name: filter_type Type: int array (min = 0, max = 32) -Syntax: <0|1|2[,...]> +Syntax: <0|1|2[,...]> Description: Video filter type. 0 none, 1 (1-2-1) 3-tap filter, 2 (2-3-6-3-2) 5-tap filter. The filter is used to reduce noise and aliasing artifacts @@ -258,13 +258,13 @@ Default: 0 for every device. ------------------------------------------------------------------------------- Name: largeview Type: bool array (min = 0, max = 32) -Syntax: <0|1[,...]> +Syntax: <0|1[,...]> Description: Large view: 0 disabled, 1 enabled. Default: 1 for every device. ------------------------------------------------------------------------------- Name: upscaling Type: bool array (min = 0, max = 32) -Syntax: <0|1[,...]> +Syntax: <0|1[,...]> Description: Software scaling (for non-compressed video only): 0 disabled, 1 enabled. Disable it if you have a slow CPU or you don't have enough @@ -341,8 +341,8 @@ Default: 50 for every device. ------------------------------------------------------------------------------- Name: bandingfilter Type: bool array (min = 0, max = 32) -Syntax: <0|1[,...]> -Description: Banding filter to reduce effects of fluorescent +Syntax: <0|1[,...]> +Description: Banding filter to reduce effects of fluorescent lighting: 0 disabled, 1 enabled. This filter tries to reduce the pattern of horizontal @@ -374,7 +374,7 @@ Default: 0 for every device. ------------------------------------------------------------------------------- Name: monochrome Type: bool array (min = 0, max = 32) -Syntax: <0|1[,...]> +Syntax: <0|1[,...]> Description: The image sensor is monochrome: 0 = no, 1 = yes Default: 0 for every device. @@ -400,19 +400,19 @@ Default: 32768 for every device. ------------------------------------------------------------------------------- Name: contrast Type: long array (min = 0, max = 32) -Syntax: +Syntax: Description: Set picture contrast (0-65535). Default: 50000 for every device. ------------------------------------------------------------------------------- Name: whiteness Type: long array (min = 0, max = 32) -Syntax: +Syntax: Description: Set picture whiteness (0-65535). Default: 32768 for every device. ------------------------------------------------------------------------------- Name: debug Type: int -Syntax: +Syntax: Description: Debugging information level, from 0 to 6: 0 = none (use carefully) 1 = critical errors diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index 3b39a91b2..8bea3fbd0 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 @@ -43,5 +43,3 @@ 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025] 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1] 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50,18ac:db54] - 45 -> KWorld HardwareMpegTV XPert [17de:0840] - 46 -> DViCO FusionHDTV DVB-T Hybrid [18ac:db40,18ac:db44] diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index a3026689b..a0c7cad20 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -8,4 +8,3 @@ 7 -> Leadtek Winfast USB II (em2800) 8 -> Kworld USB2800 (em2800) 9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207] - 12 -> Kworld PVR TV 2800 RF (em2820/em2840) diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index 1bcdac67d..f6d0cf7b7 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -64,10 +64,8 @@ tuner=62 - Philips TEA5767HN FM Radio tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner tuner=64 - LG TDVS-H062F/TUA6034 tuner=65 - Ymec TVF66T5-B/DFF -tuner=66 - LG TALN series +tuner=66 - LG NTSC (TALN mini series) tuner=67 - Philips TD1316 Hybrid Tuner tuner=68 - Philips TUV1236D ATSC/NTSC dual in -tuner=69 - Tena TNF 5335 and similar models +tuner=69 - Tena TNF 5335 MF tuner=70 - Samsung TCPN 2121P30A -tuner=71 - Xceive xc3028 -tuner=72 - Thomson FE6600 diff --git a/Documentation/video4linux/CQcam.txt b/Documentation/video4linux/CQcam.txt index 464e4cec9..e415e3604 100644 --- a/Documentation/video4linux/CQcam.txt +++ b/Documentation/video4linux/CQcam.txt @@ -1,7 +1,7 @@ c-qcam - Connectix Color QuickCam video4linux kernel driver Copyright (C) 1999 Dave Forrest - released under GNU GPL. + released under GNU GPL. 1999-12-08 Dave Forrest, written with kernel version 2.2.12 in mind @@ -45,21 +45,21 @@ configuration. The appropriate flags are: CONFIG_PNP_PARPORT M for autoprobe.o IEEE1284 readback module CONFIG_PRINTER_READBACK M for parport_probe.o IEEE1284 readback module CONFIG_VIDEO_DEV M for videodev.o video4linux module - CONFIG_VIDEO_CQCAM M for c-qcam.o Color Quickcam module + CONFIG_VIDEO_CQCAM M for c-qcam.o Color Quickcam module With these flags, the kernel should compile and install the modules. To record and monitor the compilation, I use: (make zlilo ; \ make modules; \ - make modules_install ; + make modules_install ; depmod -a ) &>log & less log # then a capital 'F' to watch the progress - + But that is my personal preference. 2.2 Configuration - + The configuration requires module configuration and device configuration. I like kmod or kerneld process with the /etc/modprobe.conf file so the modules can automatically load/unload as @@ -68,7 +68,7 @@ using MAKEDEV, or need to be created. The following sections detail these procedures. -2.1 Module Configuration +2.1 Module Configuration Using modules requires a bit of work to install and pass the parameters. Understand that entries in /etc/modprobe.conf of: @@ -128,9 +128,9 @@ system (CONFIG_PROC_FS), the parallel printer support (CONFIG_PRINTER), the IEEE 1284 system,(CONFIG_PRINTER_READBACK), you should be able to read some identification from your quickcam with - modprobe -v parport - modprobe -v parport_probe - cat /proc/parport/PORTNUMBER/autoprobe + modprobe -v parport + modprobe -v parport_probe + cat /proc/parport/PORTNUMBER/autoprobe Returns: CLASS:MEDIA; MODEL:Color QuickCam 2.0; @@ -140,7 +140,7 @@ Returns: and well. A common problem is that the current driver does not reliably detect a c-qcam, even though one is attached. In this case, - modprobe -v c-qcam + modprobe -v c-qcam or insmod -v c-qcam @@ -152,16 +152,16 @@ video4linux mailing list and archive for more current information. 3.1 Checklist: Can you get an image? - v4lgrab >qcam.ppm ; wc qcam.ppm ; xv qcam.ppm + v4lgrab >qcam.ppm ; wc qcam.ppm ; xv qcam.ppm - Is a working c-qcam connected to the port? - grep ^ /proc/parport/?/autoprobe + Is a working c-qcam connected to the port? + grep ^ /proc/parport/?/autoprobe - Do the /dev/video* files exist? - ls -lad /dev/video + Do the /dev/video* files exist? + ls -lad /dev/video - Is the c-qcam module loaded? - modprobe -v c-qcam ; lsmod + Is the c-qcam module loaded? + modprobe -v c-qcam ; lsmod Does the camera work with alternate programs? cqcam, etc? @@ -174,7 +174,7 @@ video4linux mailing list and archive for more current information. isn't, you might try patching the c-qcam module to add a parport=xxx option as in the bw-qcam module so you can specify the parallel port: - insmod -v c-qcam parport=0 + insmod -v c-qcam parport=0 And bypass the detection code, see ../../drivers/char/c-qcam.c and look for the 'qc_detect' code and call. @@ -183,12 +183,12 @@ look for the 'qc_detect' code and call. this work is documented at the video4linux2 site listed below. -9.0 --- A sample program using v4lgrabber, +9.0 --- A sample program using v4lgrabber, This program is a simple image grabber that will copy a frame from the first video device, /dev/video0 to standard output in portable pixmap format (.ppm) Using this like: 'v4lgrab | convert - c-qcam.jpg' -produced this picture of me at +produced this picture of me at http://mug.sys.virginia.edu/~drf5n/extras/c-qcam.jpg -------------------- 8< ---------------- 8< ----------------------------- @@ -202,8 +202,8 @@ produced this picture of me at * Use as: * v4lgrab >image.ppm * - * Copyright (C) 1998-05-03, Phil Blundell - * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c + * Copyright (C) 1998-05-03, Phil Blundell + * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c * with minor modifications (Dave Forrest, drf5n@virginia.edu). * */ @@ -225,55 +225,55 @@ produced this picture of me at #define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \ { \ - switch (format) \ - { \ - case VIDEO_PALETTE_GREY: \ - switch (depth) \ - { \ - case 4: \ - case 6: \ - case 8: \ - (r) = (g) = (b) = (*buf++ << 8);\ - break; \ - \ - case 16: \ - (r) = (g) = (b) = \ - *((unsigned short *) buf); \ - buf += 2; \ - break; \ - } \ - break; \ - \ - \ - case VIDEO_PALETTE_RGB565: \ - { \ - unsigned short tmp = *(unsigned short *)buf; \ - (r) = tmp&0xF800; \ - (g) = (tmp<<5)&0xFC00; \ - (b) = (tmp<<11)&0xF800; \ - buf += 2; \ - } \ - break; \ - \ - case VIDEO_PALETTE_RGB555: \ - (r) = (buf[0]&0xF8)<<8; \ - (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \ - (b) = ((buf[1] << 2 ) & 0xF8)<<8; \ - buf += 2; \ - break; \ - \ - case VIDEO_PALETTE_RGB24: \ - (r) = buf[0] << 8; (g) = buf[1] << 8; \ - (b) = buf[2] << 8; \ - buf += 3; \ - break; \ - \ - default: \ - fprintf(stderr, \ - "Format %d not yet supported\n", \ - format); \ - } \ -} + switch (format) \ + { \ + case VIDEO_PALETTE_GREY: \ + switch (depth) \ + { \ + case 4: \ + case 6: \ + case 8: \ + (r) = (g) = (b) = (*buf++ << 8);\ + break; \ + \ + case 16: \ + (r) = (g) = (b) = \ + *((unsigned short *) buf); \ + buf += 2; \ + break; \ + } \ + break; \ + \ + \ + case VIDEO_PALETTE_RGB565: \ + { \ + unsigned short tmp = *(unsigned short *)buf; \ + (r) = tmp&0xF800; \ + (g) = (tmp<<5)&0xFC00; \ + (b) = (tmp<<11)&0xF800; \ + buf += 2; \ + } \ + break; \ + \ + case VIDEO_PALETTE_RGB555: \ + (r) = (buf[0]&0xF8)<<8; \ + (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \ + (b) = ((buf[1] << 2 ) & 0xF8)<<8; \ + buf += 2; \ + break; \ + \ + case VIDEO_PALETTE_RGB24: \ + (r) = buf[0] << 8; (g) = buf[1] << 8; \ + (b) = buf[2] << 8; \ + buf += 3; \ + break; \ + \ + default: \ + fprintf(stderr, \ + "Format %d not yet supported\n", \ + format); \ + } \ +} int get_brightness_adj(unsigned char *image, long size, int *brightness) { long i, tot = 0; @@ -324,40 +324,40 @@ int main(int argc, char ** argv) if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { vpic.depth=6; if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { - vpic.depth=4; - if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { - fprintf(stderr, "Unable to find a supported capture format.\n"); - close(fd); - exit(1); - } + vpic.depth=4; + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + fprintf(stderr, "Unable to find a supported capture format.\n"); + close(fd); + exit(1); + } } } } else { vpic.depth=24; vpic.palette=VIDEO_PALETTE_RGB24; - + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { vpic.palette=VIDEO_PALETTE_RGB565; vpic.depth=16; - + if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { - vpic.palette=VIDEO_PALETTE_RGB555; - vpic.depth=15; - - if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { - fprintf(stderr, "Unable to find a supported capture format.\n"); - return -1; - } + vpic.palette=VIDEO_PALETTE_RGB555; + vpic.depth=15; + + if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { + fprintf(stderr, "Unable to find a supported capture format.\n"); + return -1; + } } } } - + buffer = malloc(win.width * win.height * bpp); if (!buffer) { fprintf(stderr, "Out of memory.\n"); exit(1); } - + do { int newbright; read(fd, buffer, win.width * win.height * bpp); @@ -365,8 +365,8 @@ int main(int argc, char ** argv) if (f) { vpic.brightness += (newbright << 8); if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { - perror("VIDIOSPICT"); - break; + perror("VIDIOSPICT"); + break; } } } while (f); @@ -381,7 +381,7 @@ int main(int argc, char ** argv) fputc(g>>8, stdout); fputc(b>>8, stdout); } - + close(fd); return 0; } diff --git a/Documentation/video4linux/README.cpia b/Documentation/video4linux/README.cpia index 19cd3bf24..c95e7bbc0 100644 --- a/Documentation/video4linux/README.cpia +++ b/Documentation/video4linux/README.cpia @@ -87,7 +87,7 @@ hardware configuration of the parport. You can give the boot-parameter at the LILO-prompt or specify it in lilo.conf. I use the following append-line in lilo.conf: - append="parport=0x378,7,3" + append="parport=0x378,7,3" See Documentation/parport.txt for more information about the configuration of the parport and the values given above. Do not simply @@ -175,7 +175,7 @@ THANKS (in no particular order): - Manuel J. Petit de Gabriel for providing help with Isabel (http://isabel.dit.upm.es/) - Bas Huisman for writing the initial parport code -- Jarl Totland for setting up the mailing list +- Jarl Totland for setting up the mailing list and maintaining the web-server[3] - Chris Whiteford for fixes related to the 1.02 firmware diff --git a/Documentation/video4linux/README.cpia2 b/Documentation/video4linux/README.cpia2 deleted file mode 100644 index ce8213d28..000000000 --- a/Documentation/video4linux/README.cpia2 +++ /dev/null @@ -1,130 +0,0 @@ -$Id: README,v 1.7 2005/08/29 23:39:57 sbertin Exp $ - -1. Introduction - - This is a driver for STMicroelectronics's CPiA2 (second generation -Colour Processor Interface ASIC) based cameras. This camera outputs an MJPEG -stream at up to vga size. It implements the Video4Linux interface as much as -possible. Since the V4L interface does not support compressed formats, only -an mjpeg enabled application can be used with the camera. We have modified the -gqcam application to view this stream. - - The driver is implemented as two kernel modules. The cpia2 module -contains the camera functions and the V4L interface. The cpia2_usb module -contains usb specific functions. The main reason for this was the size of the -module was getting out of hand, so I separted them. It is not likely that -there will be a parallel port version. - -FEATURES: - - Supports cameras with the Vision stv6410 (CIF) and stv6500 (VGA) cmos - sensors. I only have the vga sensor, so can't test the other. - - Image formats: VGA, QVGA, CIF, QCIF, and a number of sizes in between. - VGA and QVGA are the native image sizes for the VGA camera. CIF is done - in the coprocessor by scaling QVGA. All other sizes are done by clipping. - - Palette: YCrCb, compressed with MJPEG. - - Some compression parameters are settable. - - Sensor framerate is adjustable (up to 30 fps CIF, 15 fps VGA). - - Adjust brightness, color, contrast while streaming. - - Flicker control settable for 50 or 60 Hz mains frequency. - -2. Making and installing the stv672 driver modules: - - Requirements: - ------------- - This should work with 2.4 (2.4.23 and later) and 2.6 kernels, but has -only been tested on 2.6. Video4Linux must be either compiled into the kernel or -available as a module. Video4Linux2 is automatically detected and made -available at compile time. - - Compiling: - ---------- - As root, do a make install. This will compile and install the modules -into the media/video directory in the module tree. For 2.4 kernels, use -Makefile_2.4 (aka do make -f Makefile_2.4 install). - - Setup: - ------ - Use 'modprobe cpia2' to load and 'modprobe -r cpia2' to unload. This -may be done automatically by your distribution. - -3. Driver options - - Option Description - ------ ----------- - video_nr video device to register (0=/dev/video0, etc) - range -1 to 64. default is -1 (first available) - If you have more than 1 camera, this MUST be -1. - buffer_size Size for each frame buffer in bytes (default 68k) - num_buffers Number of frame buffers (1-32, default 3) - alternate USB Alternate (2-7, default 7) - flicker_freq Frequency for flicker reduction(50 or 60, default 60) - flicker_mode 0 to disable, or 1 to enable flicker reduction. - (default 0). This is only effective if the camera - uses a stv0672 coprocessor. - - Setting the options: - -------------------- - If you are using modules, edit /etc/modules.conf and add an options -line like this: - options cpia2 num_buffers=3 buffer_size=65535 - - If the driver is compiled into the kernel, at boot time specify them -like this: - cpia2.num_buffers=3 cpia2.buffer_size=65535 - - What buffer size should I use? - ------------------------------ - The maximum image size depends on the alternate you choose, and the -frame rate achieved by the camera. If the compression engine is able to -keep up with the frame rate, the maximum image size is given by the table -below. - The compression engine starts out at maximum compression, and will -increase image quality until it is close to the size in the table. As long -as the compression engine can keep up with the frame rate, after a short time -the images will all be about the size in the table, regardless of resolution. - At low alternate settings, the compression engine may not be able to -compress the image enough and will reduce the frame rate by producing larger -images. - The default of 68k should be good for most users. This will handle -any alternate at frame rates down to 15fps. For lower frame rates, it may -be necessary to increase the buffer size to avoid having frames dropped due -to insufficient space. - - Image size(bytes) - Alternate bytes/ms 15fps 30fps - 2 128 8533 4267 - 3 384 25600 12800 - 4 640 42667 21333 - 5 768 51200 25600 - 6 896 59733 29867 - 7 1023 68200 34100 - - How many buffers should I use? - ------------------------------ - For normal streaming, 3 should give the best results. With only 2, -it is possible for the camera to finish sending one image just after a -program has started reading the other. If this happens, the driver must drop -a frame. The exception to this is if you have a heavily loaded machine. In -this case use 2 buffers. You are probably not reading at the full frame rate. -If the camera can send multiple images before a read finishes, it could -overwrite the third buffer before the read finishes, leading to a corrupt -image. Single and double buffering have extra checks to avoid overwriting. - -4. Using the camera - - We are providing a modified gqcam application to view the output. In -order to avoid confusion, here it is called mview. There is also the qx5view -program which can also control the lights on the qx5 microscope. MJPEG Tools -(http://mjpeg.sourceforge.net) can also be used to record from the camera. - -5. Notes to developers: - - - This is a driver version stripped of the 2.4 back compatibility - and old MJPEG ioctl API. See cpia2.sf.net for 2.4 support. - -6. Thanks: - - - Peter Pregler , - Scott J. Bertin , and - Jarl Totland for the original cpia driver, which - this one was modelled from. diff --git a/Documentation/video4linux/Zoran b/Documentation/video4linux/Zoran index be9f21b84..52c94bd7d 100644 --- a/Documentation/video4linux/Zoran +++ b/Documentation/video4linux/Zoran @@ -28,7 +28,7 @@ Iomega Buz: * Philips saa7111 TV decoder * Philips saa7185 TV encoder Drivers to use: videodev, i2c-core, i2c-algo-bit, - videocodec, saa7111, saa7185, zr36060, zr36067 + videocodec, saa7111, saa7185, zr36060, zr36067 Inputs/outputs: Composite and S-video Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) Card number: 7 @@ -39,7 +39,7 @@ Linux Media Labs LML33: * Brooktree bt819 TV decoder * Brooktree bt856 TV encoder Drivers to use: videodev, i2c-core, i2c-algo-bit, - videocodec, bt819, bt856, zr36060, zr36067 + videocodec, bt819, bt856, zr36060, zr36067 Inputs/outputs: Composite and S-video Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) Card number: 5 @@ -50,7 +50,7 @@ Linux Media Labs LML33R10: * Philips saa7114 TV decoder * Analog Devices adv7170 TV encoder Drivers to use: videodev, i2c-core, i2c-algo-bit, - videocodec, saa7114, adv7170, zr36060, zr36067 + videocodec, saa7114, adv7170, zr36060, zr36067 Inputs/outputs: Composite and S-video Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) Card number: 6 @@ -61,7 +61,7 @@ Pinnacle/Miro DC10(new): * Philips saa7110a TV decoder * Analog Devices adv7176 TV encoder Drivers to use: videodev, i2c-core, i2c-algo-bit, - videocodec, saa7110, adv7175, zr36060, zr36067 + videocodec, saa7110, adv7175, zr36060, zr36067 Inputs/outputs: Composite, S-video and Internal Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps) Card number: 1 @@ -84,7 +84,7 @@ Pinnacle/Miro DC10(old): * * Micronas vpx3220a TV decoder * mse3000 TV encoder or Analog Devices adv7176 TV encoder * Drivers to use: videodev, i2c-core, i2c-algo-bit, - videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067 + videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067 Inputs/outputs: Composite, S-video and Internal Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps) Card number: 0 @@ -96,7 +96,7 @@ Pinnacle/Miro DC30: * * Micronas vpx3225d/vpx3220a/vpx3216b TV decoder * Analog Devices adv7176 TV encoder Drivers to use: videodev, i2c-core, i2c-algo-bit, - videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067 + videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067 Inputs/outputs: Composite, S-video and Internal Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps) Card number: 3 @@ -123,11 +123,11 @@ Note: use encoder=X or decoder=X for non-default i2c chips (see i2c-id.h) The best know TV standards are NTSC/PAL/SECAM. but for decoding a frame that information is not enough. There are several formats of the TV standards. -And not every TV decoder is able to handle every format. Also the every -combination is supported by the driver. There are currently 11 different -tv broadcast formats all aver the world. +And not every TV decoder is able to handle every format. Also the every +combination is supported by the driver. There are currently 11 different +tv broadcast formats all aver the world. -The CCIR defines parameters needed for broadcasting the signal. +The CCIR defines parameters needed for broadcasting the signal. The CCIR has defined different standards: A,B,D,E,F,G,D,H,I,K,K1,L,M,N,... The CCIR says not much about about the colorsystem used !!! And talking about a colorsystem says not to much about how it is broadcast. @@ -136,18 +136,18 @@ The CCIR standards A,E,F are not used any more. When you speak about NTSC, you usually mean the standard: CCIR - M using the NTSC colorsystem which is used in the USA, Japan, Mexico, Canada -and a few others. +and a few others. When you talk about PAL, you usually mean: CCIR - B/G using the PAL -colorsystem which is used in many Countries. +colorsystem which is used in many Countries. -When you talk about SECAM, you mean: CCIR - L using the SECAM Colorsystem +When you talk about SECAM, you mean: CCIR - L using the SECAM Colorsystem which is used in France, and a few others. There the other version of SECAM, CCIR - D/K is used in Bulgaria, China, -Slovakai, Hungary, Korea (Rep.), Poland, Rumania and a others. +Slovakai, Hungary, Korea (Rep.), Poland, Rumania and a others. -The CCIR - H uses the PAL colorsystem (sometimes SECAM) and is used in +The CCIR - H uses the PAL colorsystem (sometimes SECAM) and is used in Egypt, Libya, Sri Lanka, Syrain Arab. Rep. The CCIR - I uses the PAL colorsystem, and is used in Great Britain, Hong Kong, @@ -158,30 +158,30 @@ and is used in Argentinia, Uruguay, an a few others We do not talk about how the audio is broadcast ! -A rather good sites about the TV standards are: +A rather good sites about the TV standards are: http://www.sony.jp/ServiceArea/Voltage_map/ http://info.electronicwerkstatt.de/bereiche/fernsehtechnik/frequenzen_und_normen/Fernsehnormen/ and http://www.cabl.com/restaurant/channel.html Other weird things around: NTSC 4.43 is a modificated NTSC, which is mainly used in PAL VCR's that are able to play back NTSC. PAL 60 seems to be the same -as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would -be the same as NTSC 4.43. +as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would +be the same as NTSC 4.43. NTSC Combs seems to be a decoder mode where the decoder uses a comb filter to split coma and luma instead of a Delay line. But I did not defiantly find out what NTSC Comb is. Philips saa7111 TV decoder -was introduced in 1997, is used in the BUZ and -can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC N, NTSC 4.43 and SECAM +was introduced in 1997, is used in the BUZ and +can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC N, NTSC 4.43 and SECAM Philips saa7110a TV decoder was introduced in 1995, is used in the Pinnacle/Miro DC10(new), DC10+ and -can handle: PAL B/G, NTSC M and SECAM +can handle: PAL B/G, NTSC M and SECAM Philips saa7114 TV decoder -was introduced in 2000, is used in the LML33R10 and +was introduced in 2000, is used in the LML33R10 and can handle: PAL B/G/D/H/I/N, PAL N, PAL M, NTSC M, NTSC 4.43 and SECAM Brooktree bt819 TV decoder @@ -206,7 +206,7 @@ was introduced in 1996, is used in the BUZ can generate: PAL B/G, NTSC M Brooktree bt856 TV Encoder -was introduced in 1994, is used in the LML33 +was introduced in 1994, is used in the LML33 can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL-N (Argentina) Analog Devices adv7170 TV Encoder @@ -221,9 +221,9 @@ ITT mse3000 TV encoder was introduced in 1991, is used in the DC10 old can generate: PAL , NTSC , SECAM -The adv717x, should be able to produce PAL N. But you find nothing PAL N +The adv717x, should be able to produce PAL N. But you find nothing PAL N specific in the registers. Seem that you have to reuse a other standard -to generate PAL N, maybe it would work if you use the PAL M settings. +to generate PAL N, maybe it would work if you use the PAL M settings. ========================== @@ -261,7 +261,7 @@ Here's my experience of using LML33 and Buz on various motherboards: VIA MVP3 Forget it. Pointless. Doesn't work. -Intel 430FX (Pentium 200) +Intel 430FX (Pentium 200) LML33 perfect, Buz tolerable (3 or 4 frames dropped per movie) Intel 440BX (early stepping) LML33 tolerable. Buz starting to get annoying (6-10 frames/hour) @@ -438,52 +438,52 @@ importance of buffer sizes: > -q 25 -b 128 : 24.655.992 > -q 25 -b 256 : 25.859.820 -I woke up, and can't go to sleep again. I'll kill some time explaining why +I woke up, and can't go to sleep again. I'll kill some time explaining why this doesn't look strange to me. -Let's do some math using a width of 704 pixels. I'm not sure whether the Buz +Let's do some math using a width of 704 pixels. I'm not sure whether the Buz actually use that number or not, but that's not too important right now. -704x288 pixels, one field, is 202752 pixels. Divided by 64 pixels per block; -3168 blocks per field. Each pixel consist of two bytes; 128 bytes per block; -1024 bits per block. 100% in the new driver mean 1:2 compression; the maximum -output becomes 512 bits per block. Actually 510, but 512 is simpler to use +704x288 pixels, one field, is 202752 pixels. Divided by 64 pixels per block; +3168 blocks per field. Each pixel consist of two bytes; 128 bytes per block; +1024 bits per block. 100% in the new driver mean 1:2 compression; the maximum +output becomes 512 bits per block. Actually 510, but 512 is simpler to use for calculations. -Let's say that we specify d1q50. We thus want 256 bits per block; times 3168 -becomes 811008 bits; 101376 bytes per field. We're talking raw bits and bytes -here, so we don't need to do any fancy corrections for bits-per-pixel or such +Let's say that we specify d1q50. We thus want 256 bits per block; times 3168 +becomes 811008 bits; 101376 bytes per field. We're talking raw bits and bytes +here, so we don't need to do any fancy corrections for bits-per-pixel or such things. 101376 bytes per field. -d1 video contains two fields per frame. Those sum up to 202752 bytes per +d1 video contains two fields per frame. Those sum up to 202752 bytes per frame, and one of those frames goes into each buffer. -But wait a second! -b128 gives 128kB buffers! It's not possible to cram +But wait a second! -b128 gives 128kB buffers! It's not possible to cram 202752 bytes of JPEG data into 128kB! -This is what the driver notice and automatically compensate for in your +This is what the driver notice and automatically compensate for in your examples. Let's do some math using this information: -128kB is 131072 bytes. In this buffer, we want to store two fields, which -leaves 65536 bytes for each field. Using 3168 blocks per field, we get -20.68686868... available bytes per block; 165 bits. We can't allow the -request for 256 bits per block when there's only 165 bits available! The -q50 -option is silently overridden, and the -b128 option takes precedence, leaving +128kB is 131072 bytes. In this buffer, we want to store two fields, which +leaves 65536 bytes for each field. Using 3168 blocks per field, we get +20.68686868... available bytes per block; 165 bits. We can't allow the +request for 256 bits per block when there's only 165 bits available! The -q50 +option is silently overridden, and the -b128 option takes precedence, leaving us with the equivalence of -q32. -This gives us a data rate of 165 bits per block, which, times 3168, sums up -to 65340 bytes per field, out of the allowed 65536. The current driver has -another level of rate limiting; it won't accept -q values that fill more than -6/8 of the specified buffers. (I'm not sure why. "Playing it safe" seem to be -a safe bet. Personally, I think I would have lowered requested-bits-per-block -by one, or something like that.) We can't use 165 bits per block, but have to -lower it again, to 6/8 of the available buffer space: We end up with 124 bits -per block, the equivalence of -q24. With 128kB buffers, you can't use greater +This gives us a data rate of 165 bits per block, which, times 3168, sums up +to 65340 bytes per field, out of the allowed 65536. The current driver has +another level of rate limiting; it won't accept -q values that fill more than +6/8 of the specified buffers. (I'm not sure why. "Playing it safe" seem to be +a safe bet. Personally, I think I would have lowered requested-bits-per-block +by one, or something like that.) We can't use 165 bits per block, but have to +lower it again, to 6/8 of the available buffer space: We end up with 124 bits +per block, the equivalence of -q24. With 128kB buffers, you can't use greater than -q24 at -d1. (And PAL, and 704 pixels width...) -The third example is limited to -q24 through the same process. The second -example, using very similar calculations, is limited to -q48. The only -example that actually grab at the specified -q value is the last one, which +The third example is limited to -q24 through the same process. The second +example, using very similar calculations, is limited to -q48. The only +example that actually grab at the specified -q value is the last one, which is clearly visible, looking at the file size. -- diff --git a/Documentation/video4linux/bttv/ICs b/Documentation/video4linux/bttv/ICs index 611315f87..6b7491336 100644 --- a/Documentation/video4linux/bttv/ICs +++ b/Documentation/video4linux/bttv/ICs @@ -14,13 +14,13 @@ Hauppauge Win/TV pci (version 405): Microchip 24LC02B or Philips 8582E2Y: 256 Byte EEPROM with configuration information - I2C 0xa0-0xa1, (24LC02B also responds to 0xa2-0xaf) + I2C 0xa0-0xa1, (24LC02B also responds to 0xa2-0xaf) Philips SAA5246AGP/E: Videotext decoder chip, I2C 0x22-0x23 TDA9800: sound decoder Winbond W24257AS-35: 32Kx8 CMOS static RAM (Videotext buffer mem) 14052B: analog switch for selection of sound source -PAL: +PAL: TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3 diff --git a/Documentation/video4linux/bttv/PROBLEMS b/Documentation/video4linux/bttv/PROBLEMS index 2b8b0079f..8e31e9e36 100644 --- a/Documentation/video4linux/bttv/PROBLEMS +++ b/Documentation/video4linux/bttv/PROBLEMS @@ -3,7 +3,7 @@ - Start capturing by pressing "c" or by selecting it via a menu!!! - The memory of some S3 cards is not recognized right: - + First of all, if you are not using XFree-3.2 or newer, upgrade AT LEAST to XFree-3.2A! This solved the problem for most people. @@ -31,23 +31,23 @@ (mostly with Trio 64 but also with some others) Get the free demo version of Accelerated X from www.xinside.com and try bttv with it. bttv seems to work with most S3 cards with Accelerated X. - + Since I do not know much (better make that almost nothing) about VGA card programming I do not know the reason for this. Looks like XFree does something different when setting up the video memory? - Maybe somebody can enlighten me? - Would be nice if somebody could get this to work with XFree since - Accelerated X costs more than some of the grabber cards ... - + Maybe somebody can enlighten me? + Would be nice if somebody could get this to work with XFree since + Accelerated X costs more than some of the grabber cards ... + Better linear frame buffer support for S3 cards will probably be in XFree 4.0. - + - Grabbing is not switched off when changing consoles with XFree. That's because XFree and some AcceleratedX versions do not send unmap events. - Some popup windows (e.g. of the window manager) are not refreshed. - + Disable backing store by starting X with the option "-bs" - When using 32 bpp in XFree or 24+8bpp mode in AccelX 3.1 the system diff --git a/Documentation/video4linux/bttv/README.quirks b/Documentation/video4linux/bttv/README.quirks index 92e03929a..e8edb87df 100644 --- a/Documentation/video4linux/bttv/README.quirks +++ b/Documentation/video4linux/bttv/README.quirks @@ -38,9 +38,9 @@ tolerate. ------------------------ When using the 430FX PCI, the following rules will ensure -compatibility: +compatibility: - (1) Deassert REQ at the same time as asserting FRAME. + (1) Deassert REQ at the same time as asserting FRAME. (2) Do not reassert REQ to request another bus transaction until after finish-ing the previous transaction. diff --git a/Documentation/video4linux/bttv/THANKS b/Documentation/video4linux/bttv/THANKS index 950aa781c..2085399da 100644 --- a/Documentation/video4linux/bttv/THANKS +++ b/Documentation/video4linux/bttv/THANKS @@ -1,6 +1,6 @@ Many thanks to: -- Markus Schroeder for information on the Bt848 +- Markus Schroeder for information on the Bt848 and tuner programming and his control program xtvc. - Martin Buck for his great Videotext @@ -16,7 +16,7 @@ Many thanks to: - MIRO for providing a free PCTV card and detailed information about the components on their cards. (E.g. how the tuner type is detected) Without their card I could not have debugged the NTSC mode. - + - Hauppauge for telling how the sound input is selected and what components they do and will use on their radio cards. Also many thanks for faxing me the FM1216 data sheet. diff --git a/Documentation/video4linux/cpia2_overview.txt b/Documentation/video4linux/cpia2_overview.txt deleted file mode 100644 index a6e536652..000000000 --- a/Documentation/video4linux/cpia2_overview.txt +++ /dev/null @@ -1,38 +0,0 @@ - Programmer's View of Cpia2 - -Cpia2 is the second generation video coprocessor from VLSI Vision Ltd (now a -division of ST Microelectronics). There are two versions. The first is the -STV0672, which is capable of up to 30 frames per second (fps) in frame sizes -up to CIF, and 15 fps for VGA frames. The STV0676 is an improved version, -which can handle up to 30 fps VGA. Both coprocessors can be attached to two -CMOS sensors - the vvl6410 CIF sensor and the vvl6500 VGA sensor. These will -be referred to as the 410 and the 500 sensors, or the CIF and VGA sensors. - -The two chipsets operate almost identically. The core is an 8051 processor, -running two different versions of firmware. The 672 runs the VP4 video -processor code, the 676 runs VP5. There are a few differences in register -mappings for the two chips. In these cases, the symbols defined in the -header files are marked with VP4 or VP5 as part of the symbol name. - -The cameras appear externally as three sets of registers. Setting register -values is the only way to control the camera. Some settings are -interdependant, such as the sequence required to power up the camera. I will -try to make note of all of these cases. - -The register sets are called blocks. Block 0 is the system block. This -section is always powered on when the camera is plugged in. It contains -registers that control housekeeping functions such as powering up the video -processor. The video processor is the VP block. These registers control -how the video from the sensor is processed. Examples are timing registers, -user mode (vga, qvga), scaling, cropping, framerates, and so on. The last -block is the video compressor (VC). The video stream sent from the camera is -compressed as Motion JPEG (JPEGA). The VC controls all of the compression -parameters. Looking at the file cpia2_registers.h, you can get a full view -of these registers and the possible values for most of them. - -One or more registers can be set or read by sending a usb control message to -the camera. There are three modes for this. Block mode requests a number -of contiguous registers. Random mode reads or writes random registers with -a tuple structure containing address/value pairs. The repeat mode is only -used by VP4 to load a firmware patch. It contains a starting address and -a sequence of bytes to be written into a gpio port. \ No newline at end of file diff --git a/Documentation/video4linux/et61x251.txt b/Documentation/video4linux/et61x251.txt deleted file mode 100644 index 29340282a..000000000 --- a/Documentation/video4linux/et61x251.txt +++ /dev/null @@ -1,314 +0,0 @@ - - ET61X[12]51 PC Camera Controllers - Driver for Linux - ================================= - - - Documentation - - - -Index -===== -1. Copyright -2. Disclaimer -3. License -4. Overview and features -5. Module dependencies -6. Module loading -7. Module parameters -8. Optional device control through "sysfs" -9. Supported devices -10. Notes for V4L2 application developers -11. Contact information - - -1. Copyright -============ -Copyright (C) 2006 by Luca Risolia - - -2. Disclaimer -============= -Etoms is a trademark of Etoms Electronics Corp. -This software is not developed or sponsored by Etoms Electronics. - - -3. License -========== -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You 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. - - -4. Overview and features -======================== -This driver supports the video interface of the devices mounting the ET61X151 -or ET61X251 PC Camera Controllers. - -It's worth to note that Etoms Electronics has never collaborated with the -author during the development of this project; despite several requests, -Etoms Electronics also refused to release enough detailed specifications of -the video compression engine. - -The driver relies on the Video4Linux2 and USB core modules. It has been -designed to run properly on SMP systems as well. - -The latest version of the ET61X[12]51 driver can be found at the following URL: -http://www.linux-projects.org/ - -Some of the features of the driver are: - -- full compliance with the Video4Linux2 API (see also "Notes for V4L2 - application developers" paragraph); -- available mmap or read/poll methods for video streaming through isochronous - data transfers; -- automatic detection of image sensor; -- support for any window resolutions and optional panning within the maximum - pixel area of image sensor; -- image downscaling with arbitrary scaling factors from 1 and 2 in both - directions (see "Notes for V4L2 application developers" paragraph); -- two different video formats for uncompressed or compressed data in low or - high compression quality (see also "Notes for V4L2 application developers" - paragraph); -- full support for the capabilities of every possible image sensors that can - be connected to the ET61X[12]51 bridges, including, for istance, red, green, - blue and global gain adjustments and exposure control (see "Supported - devices" paragraph for details); -- use of default color settings for sunlight conditions; -- dynamic I/O interface for both ET61X[12]51 and image sensor control (see - "Optional device control through 'sysfs'" paragraph); -- dynamic driver control thanks to various module parameters (see "Module - parameters" paragraph); -- up to 64 cameras can be handled at the same time; they can be connected and - disconnected from the host many times without turning off the computer, if - the system supports hotplugging; -- no known bugs. - - -5. Module dependencies -====================== -For it to work properly, the driver needs kernel support for Video4Linux and -USB. - -The following options of the kernel configuration file must be enabled and -corresponding modules must be compiled: - - # Multimedia devices - # - CONFIG_VIDEO_DEV=m - -To enable advanced debugging functionality on the device through /sysfs: - - # Multimedia devices - # - CONFIG_VIDEO_ADV_DEBUG=y - - # USB support - # - CONFIG_USB=m - -In addition, depending on the hardware being used, the modules below are -necessary: - - # USB Host Controller Drivers - # - CONFIG_USB_EHCI_HCD=m - CONFIG_USB_UHCI_HCD=m - CONFIG_USB_OHCI_HCD=m - -And finally: - - # USB Multimedia devices - # - CONFIG_USB_ET61X251=m - - -6. Module loading -================= -To use the driver, it is necessary to load the "et61x251" module into memory -after every other module required: "videodev", "usbcore" and, depending on -the USB host controller you have, "ehci-hcd", "uhci-hcd" or "ohci-hcd". - -Loading can be done as shown below: - - [root@localhost home]# modprobe et61x251 - -At this point the devices should be recognized. You can invoke "dmesg" to -analyze kernel messages and verify that the loading process has gone well: - - [user@localhost home]$ dmesg - - -7. Module parameters -==================== -Module parameters are listed below: -------------------------------------------------------------------------------- -Name: video_nr -Type: short array (min = 0, max = 64) -Syntax: <-1|n[,...]> -Description: Specify V4L2 minor mode number: - -1 = use next available - n = use minor number n - You can specify up to 64 cameras this way. - For example: - video_nr=-1,2,-1 would assign minor number 2 to the second - registered camera and use auto for the first one and for every - other camera. -Default: -1 -------------------------------------------------------------------------------- -Name: force_munmap -Type: bool array (min = 0, max = 64) -Syntax: <0|1[,...]> -Description: Force the application to unmap previously mapped buffer memory - before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not - all the applications support this feature. This parameter is - specific for each detected camera. - 0 = do not force memory unmapping - 1 = force memory unmapping (save memory) -Default: 0 -------------------------------------------------------------------------------- -Name: frame_timeout -Type: uint array (min = 0, max = 64) -Syntax: -Description: Timeout for a video frame in seconds. This parameter is - specific for each detected camera. This parameter can be - changed at runtime thanks to the /sys filesystem interface. -Default: 2 -------------------------------------------------------------------------------- -Name: debug -Type: ushort -Syntax: -Description: Debugging information level, from 0 to 3: - 0 = none (use carefully) - 1 = critical errors - 2 = significant informations - 3 = more verbose messages - Level 3 is useful for testing only, when only one device - is used at the same time. It also shows some more informations - about the hardware being detected. This module parameter can be - changed at runtime thanks to the /sys filesystem interface. -Default: 2 -------------------------------------------------------------------------------- - - -8. Optional device control through "sysfs" -========================================== -If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled, -it is possible to read and write both the ET61X[12]51 and the image sensor -registers by using the "sysfs" filesystem interface. - -There are four files in the /sys/class/video4linux/videoX directory for each -registered camera: "reg", "val", "i2c_reg" and "i2c_val". The first two files -control the ET61X[12]51 bridge, while the other two control the sensor chip. -"reg" and "i2c_reg" hold the values of the current register index where the -following reading/writing operations are addressed at through "val" and -"i2c_val". Their use is not intended for end-users, unless you know what you -are doing. Remember that you must be logged in as root before writing to them. - -As an example, suppose we were to want to read the value contained in the -register number 1 of the sensor register table - which is usually the product -identifier - of the camera registered as "/dev/video0": - - [root@localhost #] cd /sys/class/video4linux/video0 - [root@localhost #] echo 1 > i2c_reg - [root@localhost #] cat i2c_val - -Note that if the sensor registers can not be read, "cat" will fail. -To avoid race conditions, all the I/O accesses to the files are serialized. - - -9. Supported devices -==================== -None of the names of the companies as well as their products will be mentioned -here. They have never collaborated with the author, so no advertising. - -From the point of view of a driver, what unambiguously identify a device are -its vendor and product USB identifiers. Below is a list of known identifiers of -devices mounting the ET61X[12]51 PC camera controllers: - -Vendor ID Product ID ---------- ---------- -0x102c 0x6151 -0x102c 0x6251 -0x102c 0x6253 -0x102c 0x6254 -0x102c 0x6255 -0x102c 0x6256 -0x102c 0x6257 -0x102c 0x6258 -0x102c 0x6259 -0x102c 0x625a -0x102c 0x625b -0x102c 0x625c -0x102c 0x625d -0x102c 0x625e -0x102c 0x625f -0x102c 0x6260 -0x102c 0x6261 -0x102c 0x6262 -0x102c 0x6263 -0x102c 0x6264 -0x102c 0x6265 -0x102c 0x6266 -0x102c 0x6267 -0x102c 0x6268 -0x102c 0x6269 - -The following image sensors are supported: - -Model Manufacturer ------ ------------ -TAS5130D1B Taiwan Advanced Sensor Corporation - -All the available control settings of each image sensor are supported through -the V4L2 interface. - - -10. Notes for V4L2 application developers -========================================= -This driver follows the V4L2 API specifications. In particular, it enforces two -rules: - -- exactly one I/O method, either "mmap" or "read", is associated with each -file descriptor. Once it is selected, the application must close and reopen the -device to switch to the other I/O method; - -- although it is not mandatory, previously mapped buffer memory should always -be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's. -The same number of buffers as before will be allocated again to match the size -of the new video frames, so you have to map the buffers again before any I/O -attempts on them. - -Consistently with the hardware limits, this driver also supports image -downscaling with arbitrary scaling factors from 1 and 2 in both directions. -However, the V4L2 API specifications don't correctly define how the scaling -factor can be chosen arbitrarily by the "negotiation" of the "source" and -"target" rectangles. To work around this flaw, we have added the convention -that, during the negotiation, whenever the "VIDIOC_S_CROP" ioctl is issued, the -scaling factor is restored to 1. - -This driver supports two different video formats: the first one is the "8-bit -Sequential Bayer" format and can be used to obtain uncompressed video data -from the device through the current I/O method, while the second one provides -"raw" compressed video data (without frame headers not related to the -compressed data). The current compression quality may vary from 0 to 1 and can -be selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP -V4L2 ioctl's. - - -11. Contact information -======================= -The author may be contacted by e-mail at . - -GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is -'FCE635A4'; the public 1024-bit key should be available at any keyserver; -the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. diff --git a/Documentation/video4linux/radiotrack.txt b/Documentation/video4linux/radiotrack.txt index d1f3ed199..2b75345f1 100644 --- a/Documentation/video4linux/radiotrack.txt +++ b/Documentation/video4linux/radiotrack.txt @@ -131,17 +131,17 @@ Check Stereo: BASE <-- 0xd8 (current volume, stereo detect, x=0xff ==> "not stereo", x=0xfd ==> "stereo detected" Set Frequency: code = (freq*40) + 10486188 - foreach of the 24 bits in code, - (from Least to Most Significant): - to write a "zero" bit, - BASE <-- 0x01 (audio mute, no stereo detect, radio + foreach of the 24 bits in code, + (from Least to Most Significant): + to write a "zero" bit, + BASE <-- 0x01 (audio mute, no stereo detect, radio disable, "zero" bit phase 1, tuner adjust) - BASE <-- 0x03 (audio mute, no stereo detect, radio + BASE <-- 0x03 (audio mute, no stereo detect, radio disable, "zero" bit phase 2, tuner adjust) - to write a "one" bit, - BASE <-- 0x05 (audio mute, no stereo detect, radio + to write a "one" bit, + BASE <-- 0x05 (audio mute, no stereo detect, radio disable, "one" bit phase 1, tuner adjust) - BASE <-- 0x07 (audio mute, no stereo detect, radio + BASE <-- 0x07 (audio mute, no stereo detect, radio disable, "one" bit phase 2, tuner adjust) ---------------------------------------------------------------------------- diff --git a/Documentation/video4linux/w9966.txt b/Documentation/video4linux/w9966.txt index 78a651254..e7ac33a7e 100644 --- a/Documentation/video4linux/w9966.txt +++ b/Documentation/video4linux/w9966.txt @@ -26,7 +26,7 @@ is called VIDEO_PALETTE_YUV422 (16 bpp). A minimal test application (with source) is available from: http://hem.fyristorg.com/mogul/w9966.html -The slow framerate is due to missing DMA ECP read support in the +The slow framerate is due to missing DMA ECP read support in the parport drivers. I might add working EPP support later. Good luck! diff --git a/Documentation/video4linux/zc0301.txt b/Documentation/video4linux/zc0301.txt deleted file mode 100644 index f55262c67..000000000 --- a/Documentation/video4linux/zc0301.txt +++ /dev/null @@ -1,254 +0,0 @@ - - ZC0301 Image Processor and Control Chip - Driver for Linux - ======================================= - - - Documentation - - - -Index -===== -1. Copyright -2. Disclaimer -3. License -4. Overview and features -5. Module dependencies -6. Module loading -7. Module parameters -8. Supported devices -9. Notes for V4L2 application developers -10. Contact information -11. Credits - - -1. Copyright -============ -Copyright (C) 2006 by Luca Risolia - - -2. Disclaimer -============= -This software is not developed or sponsored by Z-Star Microelectronics Corp. -Trademarks are property of their respective owner. - - -3. License -========== -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You 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. - - -4. Overview and features -======================== -This driver supports the video interface of the devices mounting the ZC0301 -Image Processor and Control Chip. - -The driver relies on the Video4Linux2 and USB core modules. It has been -designed to run properly on SMP systems as well. - -The latest version of the ZC0301 driver can be found at the following URL: -http://www.linux-projects.org/ - -Some of the features of the driver are: - -- full compliance with the Video4Linux2 API (see also "Notes for V4L2 - application developers" paragraph); -- available mmap or read/poll methods for video streaming through isochronous - data transfers; -- automatic detection of image sensor; -- video format is standard JPEG; -- dynamic driver control thanks to various module parameters (see "Module - parameters" paragraph); -- up to 64 cameras can be handled at the same time; they can be connected and - disconnected from the host many times without turning off the computer, if - the system supports hotplugging; - - -5. Module dependencies -====================== -For it to work properly, the driver needs kernel support for Video4Linux and -USB. - -The following options of the kernel configuration file must be enabled and -corresponding modules must be compiled: - - # Multimedia devices - # - CONFIG_VIDEO_DEV=m - - # USB support - # - CONFIG_USB=m - -In addition, depending on the hardware being used, the modules below are -necessary: - - # USB Host Controller Drivers - # - CONFIG_USB_EHCI_HCD=m - CONFIG_USB_UHCI_HCD=m - CONFIG_USB_OHCI_HCD=m - -The ZC0301 controller also provides a built-in microphone interface. It is -supported by the USB Audio driver thanks to the ALSA API: - - # Sound - # - CONFIG_SOUND=y - - # Advanced Linux Sound Architecture - # - CONFIG_SND=m - - # USB devices - # - CONFIG_SND_USB_AUDIO=m - -And finally: - - # USB Multimedia devices - # - CONFIG_USB_ZC0301=m - - -6. Module loading -================= -To use the driver, it is necessary to load the "zc0301" module into memory -after every other module required: "videodev", "usbcore" and, depending on -the USB host controller you have, "ehci-hcd", "uhci-hcd" or "ohci-hcd". - -Loading can be done as shown below: - - [root@localhost home]# modprobe zc0301 - -At this point the devices should be recognized. You can invoke "dmesg" to -analyze kernel messages and verify that the loading process has gone well: - - [user@localhost home]$ dmesg - - -7. Module parameters -==================== -Module parameters are listed below: -------------------------------------------------------------------------------- -Name: video_nr -Type: short array (min = 0, max = 64) -Syntax: <-1|n[,...]> -Description: Specify V4L2 minor mode number: - -1 = use next available - n = use minor number n - You can specify up to 64 cameras this way. - For example: - video_nr=-1,2,-1 would assign minor number 2 to the second - registered camera and use auto for the first one and for every - other camera. -Default: -1 -------------------------------------------------------------------------------- -Name: force_munmap -Type: bool array (min = 0, max = 64) -Syntax: <0|1[,...]> -Description: Force the application to unmap previously mapped buffer memory - before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not - all the applications support this feature. This parameter is - specific for each detected camera. - 0 = do not force memory unmapping - 1 = force memory unmapping (save memory) -Default: 0 -------------------------------------------------------------------------------- -Name: frame_timeout -Type: uint array (min = 0, max = 64) -Syntax: -Description: Timeout for a video frame in seconds. This parameter is - specific for each detected camera. This parameter can be - changed at runtime thanks to the /sys filesystem interface. -Default: 2 -------------------------------------------------------------------------------- -Name: debug -Type: ushort -Syntax: -Description: Debugging information level, from 0 to 3: - 0 = none (use carefully) - 1 = critical errors - 2 = significant informations - 3 = more verbose messages - Level 3 is useful for testing only, when only one device - is used at the same time. It also shows some more informations - about the hardware being detected. This module parameter can be - changed at runtime thanks to the /sys filesystem interface. -Default: 2 -------------------------------------------------------------------------------- - - -8. Supported devices -==================== -None of the names of the companies as well as their products will be mentioned -here. They have never collaborated with the author, so no advertising. - -From the point of view of a driver, what unambiguously identify a device are -its vendor and product USB identifiers. Below is a list of known identifiers of -devices mounting the ZC0301 Image Processor and Control Chips: - -Vendor ID Product ID ---------- ---------- -0x041e 0x4017 -0x041e 0x401c -0x041e 0x401e -0x041e 0x4034 -0x041e 0x4035 -0x046d 0x08ae -0x0ac8 0x0301 -0x10fd 0x8050 - -The list above does not imply that all those devices work with this driver: up -until now only the ones that mount the following image sensors are supported; -kernel messages will always tell you whether this is the case: - -Model Manufacturer ------ ------------ -PAS202BCB PixArt Imaging, Inc. - - -9. Notes for V4L2 application developers -======================================== -This driver follows the V4L2 API specifications. In particular, it enforces two -rules: - -- exactly one I/O method, either "mmap" or "read", is associated with each -file descriptor. Once it is selected, the application must close and reopen the -device to switch to the other I/O method; - -- although it is not mandatory, previously mapped buffer memory should always -be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's. -The same number of buffers as before will be allocated again to match the size -of the new video frames, so you have to map the buffers again before any I/O -attempts on them. - - -10. Contact information -======================= -The author may be contacted by e-mail at . - -GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is -'FCE635A4'; the public 1024-bit key should be available at any keyserver; -the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. - - -11. Credits -=========== -- Informations about the chip internals needed to enable the I2C protocol have - been taken from the documentation of the ZC030x Video4Linux1 driver written - by Andrew Birkett ; -- The initialization values of the ZC0301 controller connected to the PAS202BCB - image sensor have been taken from the SPCA5XX driver maintained by - Michel Xhaard . diff --git a/Documentation/video4linux/zr36120.txt b/Documentation/video4linux/zr36120.txt index ac6d92d01..5d6357eef 100644 --- a/Documentation/video4linux/zr36120.txt +++ b/Documentation/video4linux/zr36120.txt @@ -2,7 +2,7 @@ Driver for Trust Computer Products Framegrabber, version 0.6.1 ------ --- ----- -------- -------- ------------ ------- - - - - ZORAN ------------------------------------------------------ - Author: Pauline Middelink + Author: Pauline Middelink Date: 18 September 1999 Version: 0.6.1 @@ -115,7 +115,7 @@ After making/checking the devices do: is the cardtype of the card you have. The cardnumber can be found in the source of zr36120. Look for tvcards. If your card is not there, please try if any other card gives some -response, and mail me if you got a working tvcard addition. +response, and mail me if you got a working tvcard addition. PS. - - -Description ------------ - -The Maixm/Dallas Semiconductor DS2482 is a I2C device that provides -one (DS2482-100) or eight (DS2482-800) 1-wire busses. - - -General Remarks ---------------- - -Valid addresses are 0x18, 0x19, 0x1a, and 0x1b. -However, the device cannot be detected without writing to the i2c bus, so no -detection is done. -You should force the device address. - -$ modprobe ds2482 force=0,0x18 - diff --git a/Documentation/watchdog/watchdog-api.txt b/Documentation/watchdog/watchdog-api.txt index 21ed51173..c5beb548c 100644 --- a/Documentation/watchdog/watchdog-api.txt +++ b/Documentation/watchdog/watchdog-api.txt @@ -36,9 +36,6 @@ timeout or margin. The simplest way to ping the watchdog is to write some data to the device. So a very simple watchdog daemon would look like this: -#include -#include - int main(int argc, const char *argv[]) { int fd=open("/dev/watchdog",O_WRONLY); if (fd==-1) { diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index f2cd6ef53..192135325 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt @@ -151,11 +151,6 @@ NUMA numa=fake=X Fake X nodes and ignore NUMA setup of the actual machine. - numa=hotadd=percent - Only allow hotadd memory to preallocate page structures upto - percent of already available memory. - numa=hotadd=0 will disable hotadd memory. - ACPI acpi=off Don't enable ACPI diff --git a/Kbuild b/Kbuild index 2d4f95e4b..95d6a00ba 100644 --- a/Kbuild +++ b/Kbuild @@ -18,7 +18,7 @@ define sed-y "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}" endef # Override default regexp for specific architectures -sed-$(CONFIG_MIPS) := "/^@@@/{s/^@@@//; s/ \#.*\$$//; p;}" +sed-$(CONFIG_MIPS) := "/^@@@/s///p" quiet_cmd_offsets = GEN $@ define cmd_offsets diff --git a/MAINTAINERS b/MAINTAINERS index 6a1bb87d8..8079b8268 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -40,20 +40,11 @@ trivial patch so apply some common sense. PLEASE document known bugs. If it doesn't work for everything or does something very odd once a month document it. - PLEASE remember that submissions must be made under the terms - of the OSDL certificate of contribution - (http://www.osdl.org/newsroom/press_releases/2004/2004_05_24_dco.html) - and should include a Signed-off-by: line. - 6. Make sure you have the right to send any changes you make. If you do changes at work you may find your employer owns the patch not you. -7. When sending security related changes or reports to a maintainer - please Cc: security@kernel.org, especially if the maintainer - does not respond. - -8. Happy hacking. +7. Happy hacking. ----------------------------------- @@ -156,18 +147,6 @@ M: p_gortmaker@yahoo.com L: netdev@vger.kernel.org S: Maintained -9P FILE SYSTEM -P: Eric Van Hensbergen -M: ericvh@gmail.com -P: Ron Minnich -M: rminnich@lanl.gov -P: Latchesar Ionkov -M: lucho@ionkov.net -L: v9fs-developer@lists.sourceforge.net -W: http://v9fs.sf.net -T: git kernel.org:/pub/scm/linux/kernel/ericvh/v9fs.git -S: Maintained - A2232 SERIAL BOARD DRIVER P: Enver Haase M: ehaase@inf.fu-berlin.de @@ -420,7 +399,6 @@ AX.25 NETWORK LAYER P: Ralf Baechle M: ralf@linux-mips.org L: linux-hams@vger.kernel.org -W: http://www.linux-ax25.org/ S: Maintained BAYCOM/HDLCDRV DRIVERS FOR AX.25 @@ -430,14 +408,6 @@ L: linux-hams@vger.kernel.org W: http://www.baycom.org/~tom/ham/ham.html S: Maintained -BCM43XX WIRELESS DRIVER -P: Michael Buesch -M: mb@bu3sch.de -P: Stefano Brivio -M: st3@riseup.net -W: http://bcm43xx.berlios.de/ -S: Maintained - BEFS FILE SYSTEM P: Sergey S. Kostyliov M: rathamahata@php4.ru @@ -564,20 +534,8 @@ S: Supported BROADBAND PROCESSOR ARCHITECTURE P: Arnd Bergmann M: arnd@arndb.de -L: linuxppc-dev@ozlabs.org -W: http://www.penguinppc.org/ppc64/ -S: Supported - -BROADCOM BNX2 GIGABIT ETHERNET DRIVER -P: Michael Chan -M: mchan@broadcom.com -L: netdev@vger.kernel.org -S: Supported - -BROADCOM TG3 GIGABIT ETHERNET DRIVER -P: Michael Chan -M: mchan@broadcom.com -L: netdev@vger.kernel.org +L: linuxppc64-dev@ozlabs.org +W: http://linuxppc64.org S: Supported BTTV VIDEO4LINUX DRIVER @@ -912,34 +870,13 @@ W: http://ebtables.sourceforge.net/ S: Maintained EDAC-CORE -P: Doug Thompson -M: norsk5@xmission.com, dthompson@linuxnetworx.com -P: Dave Peterson -M: dsp@llnl.gov, dave_peterson@pobox.com -L: bluesmoke-devel@lists.sourceforge.net -W: bluesmoke.sourceforge.net -S: Maintained - -EDAC-E752X -P: Dave Peterson -M: dsp@llnl.gov, dave_peterson@pobox.com -L: bluesmoke-devel@lists.sourceforge.net -W: bluesmoke.sourceforge.net -S: Maintained - -EDAC-E7XXX -P: Dave Peterson -M: dsp@llnl.gov, dave_peterson@pobox.com -L: bluesmoke-devel@lists.sourceforge.net -W: bluesmoke.sourceforge.net -S: Maintained - -EDAC-R82600 -P: Tim Small -M: tim@buttersideup.com -L: bluesmoke-devel@lists.sourceforge.net -W: bluesmoke.sourceforge.net -S: Maintained +P: Doug Thompson +M: norsk5@xmission.com, dthompson@linuxnetworx.com +P: Dave Peterson +M: dsp@llnl.gov, dave_peterson@pobox.com +L: bluesmoke-devel@lists.sourceforge.net +W: bluesmoke.sourceforge.net +S: Maintained EEPRO100 NETWORK DRIVER P: Andrey V. Savochkin @@ -990,7 +927,7 @@ S: Maintained EXT3 FILE SYSTEM P: Stephen Tweedie, Andrew Morton M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com -L: ext2-devel@lists.sourceforge.net +L: ext3-users@redhat.com S: Maintained F71805F HARDWARE MONITORING DRIVER @@ -1090,15 +1027,6 @@ M: khc@pm.waw.pl W: http://www.kernel.org/pub/linux/utils/net/hdlc/ S: Maintained -GIGASET ISDN DRIVERS -P: Hansjoerg Lipp -M: hjlipp@web.de -P: Tilman Schmidt -M: tilman@imap.cc -L: gigaset307x-common@lists.sourceforge.net -W: http://gigaset307x.sourceforge.net/ -S: Maintained - HARDWARE MONITORING P: Jean Delvare M: khali@linux-fr.org @@ -1147,6 +1075,12 @@ L: linux-hams@vger.kernel.org W: http://www.nt.tuwien.ac.at/~kkudielk/Linux/ S: Maintained +HIGHPOINT ROCKETRAID 3xxx RAID DRIVER +P: HighPoint Linux Team +M: linux@highpoint-tech.com +W: http://www.highpoint-tech.com +S: Supported + HIPPI P: Jes Sorensen M: jes@trained-monkey.org @@ -1421,10 +1355,10 @@ S: Maintained INTEL PRO/100 ETHERNET SUPPORT P: John Ronciak M: john.ronciak@intel.com +P: Ganesh Venkatesan +M: ganesh.venkatesan@intel.com P: Jesse Brandeburg M: jesse.brandeburg@intel.com -P: Jeff Kirsher -M: jeffrey.t.kirsher@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported @@ -1433,22 +1367,18 @@ P: Jeb Cramer M: cramerj@intel.com P: John Ronciak M: john.ronciak@intel.com -P: Jesse Brandeburg -M: jesse.brandeburg@intel.com -P: Jeff Kirsher -M: jeffrey.t.kirsher@intel.com +P: Ganesh Venkatesan +M: ganesh.venkatesan@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported INTEL PRO/10GbE SUPPORT -P: Jeff Kirsher -M: jeffrey.t.kirsher@intel.com P: Ayyappan Veeraiyan M: ayyappan.veeraiyan@intel.com +P: Ganesh Venkatesan +M: ganesh.venkatesan@intel.com P: John Ronciak M: john.ronciak@intel.com -P: Jesse Brandeburg -M: jesse.brandeburg@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported @@ -1481,19 +1411,6 @@ P: Juanjo Ciarlante M: jjciarla@raiz.uncu.edu.ar S: Maintained -IPATH DRIVER: -P: Bryan O'Sullivan -M: support@pathscale.com -L: openib-general@openib.org -S: Supported - -IPMI SUBSYSTEM -P: Corey Minyard -M: minyard@acm.org -L: openipmi-developer@lists.sourceforge.net -W: http://openipmi.sourceforge.net/ -S: Supported - IPX NETWORK LAYER P: Arnaldo Carvalho de Melo M: acme@conectiva.com.br @@ -1501,11 +1418,10 @@ L: netdev@vger.kernel.org S: Maintained IRDA SUBSYSTEM -P: Samuel Ortiz -M: samuel@sortiz.org +P: Jean Tourrilhes L: irda-users@lists.sourceforge.net (subscribers-only) W: http://irda.sourceforge.net/ -S: Maintained +S: Odd Fixes ISAPNP P: Jaroslav Kysela @@ -1551,28 +1467,12 @@ W: http://jfs.sourceforge.net/ T: git kernel.org:/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git S: Supported -JOURNALLING LAYER FOR BLOCK DEVICS (JBD) -P: Stephen Tweedie, Andrew Morton -M: sct@redhat.com, akpm@osdl.org -L: ext2-devel@lists.sourceforge.net -S: Maintained - KCONFIG P: Roman Zippel M: zippel@linux-m68k.org L: kbuild-devel@lists.sourceforge.net S: Maintained -KDUMP -P: Vivek Goyal -M: vgoyal@in.ibm.com -P: Haren Myneni -M: hbabu@us.ibm.com -L: fastboot@lists.osdl.org -L: linux-kernel@vger.kernel.org -W: http://lse.sourceforge.net/kdump/ -S: Maintained - KERNEL AUTOMOUNTER (AUTOFS) P: H. Peter Anvin M: hpa@zytor.com @@ -1610,7 +1510,9 @@ S: Maintained KEXEC P: Eric Biederman +P: Randy Dunlap M: ebiederm@xmission.com +M: rdunlap@xenotime.net W: http://www.xmission.com/~ebiederm/files/kexec/ L: linux-kernel@vger.kernel.org L: fastboot@osdl.org @@ -1628,6 +1530,12 @@ M: davem@davemloft.net L: linux-kernel@vger.kernel.org S: Maintained +LANMEDIA WAN CARD DRIVER +P: Andrew Stanley-Jones +M: asj@lanmedia.com +W: http://www.lanmedia.com/ +S: Supported + LAPB module P: Henner Eisen M: eis@baty.hanse.de @@ -1640,11 +1548,6 @@ M: James.Bottomley@HansenPartnership.com L: linux-scsi@vger.kernel.org S: Maintained -LED SUBSYSTEM -P: Richard Purdie -M: rpurdie@rpsys.net -S: Maintained - LEGO USB Tower driver P: Juergen Stuber M: starblue@users.sourceforge.net @@ -1704,7 +1607,7 @@ S: Maintained LINUX FOR POWERPC EMBEDDED PPC8XX P: Marcelo Tosatti -M: marcelo@kvack.org +M: marcelo.tosatti@cyclades.com W: http://www.penguinppc.org/ L: linuxppc-embedded@ozlabs.org S: Maintained @@ -1728,8 +1631,8 @@ M: paulus@au.ibm.com P: Anton Blanchard M: anton@samba.org M: anton@au.ibm.com -W: http://www.penguinppc.org/ppc64/ -L: linuxppc-dev@ozlabs.org +W: http://linuxppc64.org +L: linuxppc64-dev@ozlabs.org S: Supported LINUX SECURITY MODULE (LSM) FRAMEWORK @@ -1889,11 +1792,6 @@ L: linux-kernel@vger.kernel.org W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html S: Maintained -MULTIMEDIA CARD SUBSYSTEM -P: Russell King -M: rmk+mmc@arm.linux.org.uk -S: Maintained - MULTISOUND SOUND DRIVER P: Andrew Veliath M: andrewtv@usa.net @@ -1916,12 +1814,6 @@ M: James.Bottomley@HansenPartnership.com L: linux-scsi@vger.kernel.org S: Maintained -NETEM NETWORK EMULATOR -P: Stephen Hemminger -M: shemminger@osdl.org -L: netem@osdl.org -S: Maintained - NETFILTER/IPTABLES/IPCHAINS P: Rusty Russell P: Marc Boucher @@ -1939,7 +1831,6 @@ NETROM NETWORK LAYER P: Ralf Baechle M: ralf@linux-mips.org L: linux-hams@vger.kernel.org -W: http://www.linux-ax25.org/ S: Maintained NETWORK BLOCK DEVICE @@ -1960,7 +1851,6 @@ NETWORKING [GENERAL] P: Networking Team M: netdev@vger.kernel.org L: netdev@vger.kernel.org -W: http://linux-net.osdl.org/ S: Maintained NETWORKING [IPv4/IPv6] @@ -2127,12 +2017,14 @@ P: Matthew Wilcox M: matthew@wil.cx P: Grant Grundler M: grundler@parisc-linux.org -P: Kyle McMartin -M: kyle@parisc-linux.org L: parisc-linux@parisc-linux.org W: http://www.parisc-linux.org/ -T: git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git -T: cvs cvs.parisc-linux.org:/var/cvs/linux-2.6 +S: Maintained + +PERSONALITY HANDLING +P: Christoph Hellwig +M: hch@infradead.org +L: linux-abi-devel@lists.sourceforge.net S: Maintained PCI ERROR RECOVERY @@ -2185,12 +2077,6 @@ M: tsbogend@alpha.franken.de L: netdev@vger.kernel.org S: Maintained -PERSONALITY HANDLING -P: Christoph Hellwig -M: hch@infradead.org -L: linux-abi-devel@lists.sourceforge.net -S: Maintained - PHRAM MTD DRIVER P: Jörn Engel M: joern@wh.fh-wedel.de @@ -2267,7 +2153,7 @@ S: Maintained QLOGIC QLA2XXX FC-SCSI DRIVER P: Andrew Vasquez -M: linux-driver@qlogic.com +M: andrew.vasquez@qlogic.com L: linux-scsi@vger.kernel.org S: Supported @@ -2313,12 +2199,6 @@ M: p_gortmaker@yahoo.com L: linux-kernel@vger.kernel.org S: Maintained -REAL TIME CLOCK (RTC) SUBSYSTEM -P: Alessandro Zummo -M: a.zummo@towertech.it -L: linux-kernel@vger.kernel.org -S: Maintained - REISERFS FILE SYSTEM P: Hans Reiser M: reiserfs-dev@namesys.com @@ -2335,12 +2215,18 @@ ROSE NETWORK LAYER P: Ralf Baechle M: ralf@linux-mips.org L: linux-hams@vger.kernel.org -W: http://www.linux-ax25.org/ S: Maintained RISCOM8 DRIVER S: Orphan +RTLINUX REALTIME LINUX +P: Victor Yodaiken +M: yodaiken@fsmlabs.com +L: rtl@rtlinux.org +W: www.rtlinux.org +S: Maintained + S3 SAVAGE FRAMEBUFFER DRIVER P: Antonino Daplas M: adaplas@pol.net @@ -2566,20 +2452,6 @@ M: perex@suse.cz L: alsa-devel@alsa-project.org S: Maintained -SPI SUBSYSTEM -P: David Brownell -M: dbrownell@users.sourceforge.net -L: spi-devel-general@lists.sourceforge.net -S: Maintained - -STABLE BRANCH: -P: Greg Kroah-Hartman -M: greg@kroah.com -P: Chris Wright -M: chrisw@sous-sol.org -L: stable@kernel.org -S: Maintained - TPM DEVICE DRIVER P: Kylene Hall M: kjhall@us.ibm.com @@ -2624,13 +2496,6 @@ M: kristen.c.accardi@intel.com L: pcihpd-discuss@lists.sourceforge.net S: Maintained -SECURE DIGITAL HOST CONTROLLER INTERFACE DRIVER -P: Pierre Ossman -M: drzeus-sdhci@drzeus.cx -L: sdhci-devel@list.drzeus.cx -W: http://mmc.drzeus.cx/wiki/Linux/Drivers/sdhci -S: Maintained - SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS P: Stephen Hemminger M: shemminger@osdl.org @@ -2667,6 +2532,7 @@ S: Unsupported ? STRADIS MPEG-2 DECODER DRIVER P: Nathan Laredo M: laredo@gnu.org +W: http://mpeg.openprojects.net/ W: http://www.stradis.com/ S: Maintained @@ -2709,6 +2575,12 @@ P: Christoph Hellwig M: hch@infradead.org S: Maintained +TC CLASSIFIER +P: Jamal Hadi Salim +M: hadi@cyberus.ca +L: netdev@vger.kernel.org +S: Maintained + TI PARALLEL LINK CABLE DRIVER P: Romain Lievin M: roms@lpg.ticalc.org @@ -2785,7 +2657,7 @@ S: Maintained TUN/TAP driver P: Maxim Krasnyansky -M: maxk@qualcomm.com +M: maxk@qualcomm.com, max_mk@yahoo.com L: vtun@office.satix.net W: http://vtun.sourceforge.net/tun S: Maintained @@ -3042,14 +2914,6 @@ L: video4linux-list@redhat.com W: http://www.linux-projects.org S: Maintained -USB ZC0301 DRIVER -P: Luca Risolia -M: luca.risolia@studio.unibo.it -L: linux-usb-devel@lists.sourceforge.net -L: video4linux-list@redhat.com -W: http://www.linux-projects.org -S: Maintained - USB ZD1201 DRIVER P: Jeroen Vreeken M: pe1rxq@amsat.org @@ -3114,6 +2978,18 @@ L: rio500-users@lists.sourceforge.net W: http://rio500.sourceforge.net S: Maintained +V9FS FILE SYSTEM +P: Eric Van Hensbergen +M: ericvh@gmail.com +P: Ron Minnich +M: rminnich@lanl.gov +P: Latchesar Ionkov +M: lucho@ionkov.net +L: v9fs-developer@lists.sourceforge.net +W: http://v9fs.sf.net +T: git kernel.org:/pub/scm/linux/kernel/ericvh/v9fs-devel.git +S: Maintained + VIDEO FOR LINUX P: Mauro Carvalho Chehab M: mchehab@infradead.org @@ -3148,6 +3024,13 @@ M: khali@linux-fr.org L: lm-sensors@lm-sensors.org S: Odd Fixes +WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC) +P: Nenad Corbic +M: ncorbic@sangoma.com +M: dm@sangoma.com +W: http://www.sangoma.com +S: Supported + WATCHDOG DEVICE DRIVERS P: Wim Van Sebroeck M: wim@iguana.be diff --git a/Makefile b/Makefile index 812535ce2..322656a7f 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 17 -EXTRAVERSION = -1.2187_FC5.10 -NAME=Crazed Snow-Weasel +SUBLEVEL = 16 +EXTRAVERSION = .38-vs2.0.3-rc1 +NAME=Stable Penguin # *DOCUMENTATION* # To see a list of typical targets execute "make help" @@ -95,7 +95,7 @@ ifdef O endif # That's our default target when none is given on the command line -PHONY := _all +.PHONY: _all _all: ifneq ($(KBUILD_OUTPUT),) @@ -106,7 +106,7 @@ KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd) $(if $(KBUILD_OUTPUT),, \ $(error output directory "$(saved-output)" does not exist)) -PHONY += $(MAKECMDGOALS) +.PHONY: $(MAKECMDGOALS) $(filter-out _all,$(MAKECMDGOALS)) _all: $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \ @@ -123,7 +123,7 @@ ifeq ($(skip-makefile),) # If building an external module we do not care about the all: rule # but instead _all depend on modules -PHONY += all +.PHONY: all ifeq ($(KBUILD_EXTMOD),) _all: all else @@ -137,7 +137,7 @@ objtree := $(CURDIR) src := $(srctree) obj := $(objtree) -VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD)) +VPATH := $(srctree) export srctree objtree VPATH TOPDIR @@ -151,7 +151,7 @@ export srctree objtree VPATH TOPDIR 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/ppc.*/powerpc/ ) # Cross compiling and selecting different set of gcc/bin-utils # --------------------------------------------------------------------------- @@ -258,6 +258,38 @@ endif export quiet Q KBUILD_VERBOSE +###### +# cc support functions to be used (only) in arch/$(ARCH)/Makefile +# See documentation in Documentation/kbuild/makefiles.txt + +# as-option +# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,) + +as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \ + -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \ + else echo "$(2)"; fi ;) + +# cc-option +# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) + +cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ + > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) + +# cc-option-yn +# Usage: flag := $(call cc-option-yn, -march=winchip-c6) +cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ + > /dev/null 2>&1; then echo "y"; else echo "n"; fi;) + +# cc-option-align +# Prefix align with either -falign or -malign +cc-option-align = $(subst -functions=0,,\ + $(call cc-option,-falign-functions=0,-malign-functions=0)) + +# cc-version +# Usage gcc-ver := $(call cc-version $(CC)) +cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \ + $(if $(1), $(1), $(CC))) + # Look for make include files relative to root of kernel src MAKEFLAGS += --include-dir=$(srctree) @@ -306,7 +338,8 @@ LINUXINCLUDE := -Iinclude \ CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ - -fno-strict-aliasing -fno-common -Wstrict-prototypes -Wundef -Werror-implicit-function-declaration + -fno-strict-aliasing -fno-common \ + -ffreestanding AFLAGS := -D__ASSEMBLY__ # Read KERNELRELEASE from .kernelrelease (if it exists) @@ -336,22 +369,24 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exc # Rules shared between *config targets and build targets # Basic helpers built in scripts/ -PHONY += scripts_basic +.PHONY: scripts_basic scripts_basic: $(Q)$(MAKE) $(build)=scripts/basic # To avoid any implicit rule to kick in, define an empty command. scripts/basic/%: scripts_basic ; -PHONY += outputmakefile -# outputmakefile generates a Makefile in the output directory, if using a -# separate output directory. This allows convenient use of make in the -# output directory. +.PHONY: outputmakefile +# outputmakefile generate a Makefile to be placed in output directory, if +# using a seperate output directory. This allows convinient use +# of make in output directory outputmakefile: -ifneq ($(KBUILD_SRC),) - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ - $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) -endif + $(Q)if test ! $(srctree) -ef $(objtree); then \ + $(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ + $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) \ + > $(objtree)/Makefile; \ + echo ' GEN $(objtree)/Makefile'; \ + fi # To make sure we do not include .config for any of the *config targets # catch them early, and hand them over to scripts/kconfig/Makefile @@ -417,7 +452,7 @@ ifeq ($(KBUILD_EXTMOD),) # Additional helpers built in scripts/ # Carefully list dependencies so we do not try to build scripts twice # in parrallel -PHONY += scripts +.PHONY: scripts scripts: scripts_basic include/config/MARKER $(Q)$(MAKE) $(build)=$(@) @@ -469,16 +504,19 @@ else CFLAGS += -O2 endif +#Add align options if CONFIG_CC_* is not equal to 0 +add-align = $(if $(filter-out 0,$($(1))),$(cc-option-align)$(2)=$($(1))) +CFLAGS += $(call add-align,CONFIG_CC_ALIGN_FUNCTIONS,-functions) +CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LABELS,-labels) +CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LOOPS,-loops) +CFLAGS += $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps) + ifdef CONFIG_FRAME_POINTER CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) else CFLAGS += -fomit-frame-pointer endif -ifdef CONFIG_UNWIND_INFO -CFLAGS += -fasynchronous-unwind-tables -endif - ifdef CONFIG_DEBUG_INFO CFLAGS += -g endif @@ -714,7 +752,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; # make menuconfig etc. # Error messages still appears in the original language -PHONY += $(vmlinux-dirs) +.PHONY: $(vmlinux-dirs) $(vmlinux-dirs): prepare scripts $(Q)$(MAKE) $(build)=$@ @@ -767,10 +805,10 @@ kernelrelease = $(KERNELVERSION)$(localver-full) # version.h and scripts_basic is processed / created. # Listed in dependency order -PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 +.PHONY: prepare archprepare prepare0 prepare1 prepare2 prepare3 # prepare-all is deprecated, use prepare as valid replacement -PHONY += prepare-all +.PHONY: prepare-all # prepare3 is used to check if we are building in a separate output directory, # and if so do: @@ -794,8 +832,8 @@ prepare2: prepare3 outputmakefile prepare1: prepare2 include/linux/version.h include/asm \ include/config/MARKER ifneq ($(KBUILD_MODULES),) + $(Q)rm -rf $(MODVERDIR) $(Q)mkdir -p $(MODVERDIR) - $(Q)rm -f $(MODVERDIR)/* endif archprepare: prepare1 scripts_basic @@ -811,6 +849,27 @@ prepare prepare-all: prepare0 export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) +# Single targets +# --------------------------------------------------------------------------- + +%.s: %.c scripts FORCE + $(Q)$(MAKE) $(build)=$(@D) $@ +%.i: %.c scripts FORCE + $(Q)$(MAKE) $(build)=$(@D) $@ +%.o: %.c scripts FORCE + $(Q)$(MAKE) $(build)=$(@D) $@ +%.ko: scripts FORCE + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) $(@:.ko=.o) + $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost +%/: scripts prepare FORCE + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) +%.lst: %.c scripts FORCE + $(Q)$(MAKE) $(build)=$(@D) $@ +%.s: %.S scripts FORCE + $(Q)$(MAKE) $(build)=$(@D) $@ +%.o: %.S scripts FORCE + $(Q)$(MAKE) $(build)=$(@D) $@ + # FIXME: The asm symlink changes when $(ARCH) changes. That's # hard to detect, but I suppose "make mrproper" is a good idea # before switching between archs anyway. @@ -851,7 +910,7 @@ include/linux/version.h: $(srctree)/Makefile .config .kernelrelease FORCE # --------------------------------------------------------------------------- -PHONY += depend dep +.PHONY: depend dep depend dep: @echo '*** Warning: make $@ is unnecessary now.' @@ -866,21 +925,21 @@ all: modules # Build modules -PHONY += modules +.PHONY: modules modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) @echo ' Building modules, stage 2.'; $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost # Target to prepare building external modules -PHONY += modules_prepare +.PHONY: modules_prepare modules_prepare: prepare scripts # Target to install modules -PHONY += modules_install +.PHONY: modules_install modules_install: _modinst_ _modinst_post -PHONY += _modinst_ +.PHONY: _modinst_ _modinst_: @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \ echo "Warning: you may need to install module-init-tools"; \ @@ -907,7 +966,7 @@ depmod_opts := else depmod_opts := -b $(INSTALL_MOD_PATH) -r endif -PHONY += _modinst_post +.PHONY: _modinst_post _modinst_post: _modinst_ if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi @@ -950,7 +1009,7 @@ clean: rm-dirs := $(CLEAN_DIRS) clean: rm-files := $(CLEAN_FILES) clean-dirs := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs)) -PHONY += $(clean-dirs) clean archclean +.PHONY: $(clean-dirs) clean archclean $(clean-dirs): $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) @@ -968,7 +1027,7 @@ mrproper: rm-dirs := $(wildcard $(MRPROPER_DIRS)) mrproper: rm-files := $(wildcard $(MRPROPER_FILES)) mrproper-dirs := $(addprefix _mrproper_,Documentation/DocBook scripts) -PHONY += $(mrproper-dirs) mrproper archmrproper +.PHONY: $(mrproper-dirs) mrproper archmrproper $(mrproper-dirs): $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@) @@ -978,7 +1037,7 @@ mrproper: clean archmrproper $(mrproper-dirs) # distclean # -PHONY += distclean +.PHONY: distclean distclean: mrproper @find $(srctree) $(RCS_FIND_IGNORE) \ @@ -994,10 +1053,12 @@ distclean: mrproper # rpm target kept for backward compatibility package-dir := $(srctree)/scripts/package +.PHONY: %-pkg rpm + %pkg: FORCE - $(Q)$(MAKE) $(build)=$(package-dir) $@ + $(Q)$(MAKE) -f $(package-dir)/Makefile $@ rpm: FORCE - $(Q)$(MAKE) $(build)=$(package-dir) $@ + $(Q)$(MAKE) -f $(package-dir)/Makefile $@ # Brief documentation of the typical targets used @@ -1029,11 +1090,13 @@ help: @echo ' kernelversion - Output the version stored in Makefile' @echo '' @echo 'Static analysers' + @echo ' buildcheck - List dangling references to vmlinux discarded sections' + @echo ' and init sections from non-init sections' @echo ' checkstack - Generate a list of stack hogs' @echo ' namespacecheck - Name space analysis on compiled kernel' @echo '' @echo 'Kernel packaging:' - @$(MAKE) $(build)=$(package-dir) help + @$(MAKE) -f $(package-dir)/Makefile help @echo '' @echo 'Documentation targets:' @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp @@ -1082,12 +1145,11 @@ else # KBUILD_EXTMOD # We are always building modules KBUILD_MODULES := 1 -PHONY += crmodverdir +.PHONY: crmodverdir crmodverdir: $(Q)mkdir -p $(MODVERDIR) - $(Q)rm -f $(MODVERDIR)/* -PHONY += $(objtree)/Module.symvers +.PHONY: $(objtree)/Module.symvers $(objtree)/Module.symvers: @test -e $(objtree)/Module.symvers || ( \ echo; \ @@ -1096,7 +1158,7 @@ $(objtree)/Module.symvers: echo ) module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD)) -PHONY += $(module-dirs) modules +.PHONY: $(module-dirs) modules $(module-dirs): crmodverdir $(objtree)/Module.symvers $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@) @@ -1104,31 +1166,13 @@ modules: $(module-dirs) @echo ' Building modules, stage 2.'; $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost -PHONY += modules_install -modules_install: _emodinst_ _emodinst_post - -install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra) -PHONY += _emodinst_ -_emodinst_: - $(Q)mkdir -p $(MODLIB)/$(install-dir) +.PHONY: modules_install +modules_install: $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst -# Run depmod only is we have System.map and depmod is executable -quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) - cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \ - $(DEPMOD) -ae -F System.map \ - $(if $(strip $(INSTALL_MOD_PATH)), \ - -b $(INSTALL_MOD_PATH) -r) \ - $(KERNELRELEASE); \ - fi - -PHONY += _emodinst_post -_emodinst_post: _emodinst_ - $(call cmd,depmod) - clean-dirs := $(addprefix _clean_,$(KBUILD_EXTMOD)) -PHONY += $(clean-dirs) clean +.PHONY: $(clean-dirs) clean $(clean-dirs): $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) @@ -1148,11 +1192,6 @@ help: @echo ' modules_install - install the module' @echo ' clean - remove generated files in module directory only' @echo '' - -# Dummies... -PHONY += prepare scripts -prepare: ; -scripts: ; endif # KBUILD_EXTMOD # Generate tags for editors @@ -1253,13 +1292,17 @@ versioncheck: -name '*.[hcS]' -type f -print | sort \ | xargs $(PERL) -w scripts/checkversion.pl +buildcheck: + $(PERL) $(srctree)/scripts/reference_discarded.pl + $(PERL) $(srctree)/scripts/reference_init.pl + namespacecheck: $(PERL) $(srctree)/scripts/namespace.pl endif #ifeq ($(config-targets),1) endif #ifeq ($(mixed-targets),1) -PHONY += checkstack +.PHONY: checkstack checkstack: $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ $(PERL) $(src)/scripts/checkstack.pl $(ARCH) @@ -1270,47 +1313,6 @@ kernelrelease: kernelversion: @echo $(KERNELVERSION) -# Single targets -# --------------------------------------------------------------------------- -# Single targets are compatible with: -# - build whith mixed source and output -# - build with separate output dir 'make O=...' -# - external modules -# -# target-dir => where to store outputfile -# build-dir => directory in kernel source tree to use - -ifeq ($(KBUILD_EXTMOD),) - build-dir = $(patsubst %/,%,$(dir $@)) - target-dir = $(dir $@) -else - zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@))) - build-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash)) - target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@)) -endif - -%.s: %.c prepare scripts FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.i: %.c prepare scripts FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.o: %.c prepare scripts FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.lst: %.c prepare scripts FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.s: %.S prepare scripts FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.o: %.S prepare scripts FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) - -# Modules -/ %/: prepare scripts FORCE - $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ - $(build)=$(build-dir) -%.ko: prepare scripts FORCE - $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ - $(build)=$(build-dir) $(@:.ko=.o) - $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost - # FIXME Should go into a make.lib or something # =========================================================================== @@ -1345,10 +1347,4 @@ clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj endif # skip-makefile -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. -.PHONY: $(PHONY) diff --git a/README b/README index 3e264723b..0d318abaf 100644 --- a/README +++ b/README @@ -74,7 +74,7 @@ INSTALLING the kernel: whatever the kernel-du-jour happens to be. - You can also upgrade between 2.6.xx releases by patching. Patches are - distributed in the traditional gzip and the newer bzip2 format. To + distributed in the traditional gzip and the new bzip2 format. To install by patching, get all the newer patch files, enter the top level directory of the kernel source (linux-2.6.xx) and execute: @@ -165,31 +165,10 @@ CONFIGURING the kernel: "make xconfig" X windows (Qt) based configuration tool. "make gconfig" X windows (Gtk) based configuration tool. "make oldconfig" Default all questions based on the contents of - your existing ./.config file and asking about - new config symbols. + your existing ./.config file. "make silentoldconfig" Like above, but avoids cluttering the screen with questions already answered. - "make defconfig" Create a ./.config file by using the default - symbol values from arch/$ARCH/defconfig. - "make allyesconfig" - Create a ./.config file by setting symbol - values to 'y' as much as possible. - "make allmodconfig" - Create a ./.config file by setting symbol - values to 'm' as much as possible. - "make allnoconfig" Create a ./.config file by setting symbol - values to 'n' as much as possible. - "make randconfig" Create a ./.config file by setting symbol - values to random values. - - The allyesconfig/allmodconfig/allnoconfig/randconfig variants can - also use the environment variable KCONFIG_ALLCONFIG to specify a - filename that contains config options that the user requires to be - set to a specific value. If KCONFIG_ALLCONFIG=filename is not used, - "make *config" checks for a file named "all{yes/mod/no/random}.config" - for symbol values that are to be forced. If this file is not found, - it checks for a file named "all.config" to contain forced values. NOTES on "make config": - having unnecessary drivers will make the kernel bigger, and can diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 875006799..3debe3263 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -25,10 +25,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default y -config GENERIC_FIND_NEXT_BIT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y @@ -381,7 +377,7 @@ config ALPHA_EV56 config ALPHA_EV56 prompt "EV56 CPU (speed >= 333MHz)?" - depends on ALPHA_NORITAKE && ALPHA_PRIMO + depends on ALPHA_NORITAKE || ALPHA_PRIMO config ALPHA_EV56 prompt "EV56 CPU (speed >= 400MHz)?" @@ -451,10 +447,6 @@ config ALPHA_IRONGATE depends on ALPHA_NAUTILUS default y -config GENERIC_HWEIGHT - bool - default y if !ALPHA_EV67 - config ALPHA_AVANTI bool depends on ALPHA_XL || ALPHA_AVANTI_CH @@ -549,11 +541,6 @@ config NUMA Access). This option is for configuring high-end multiprocessor server machines. If in doubt, say N. -config NODES_SHIFT - int - default "7" - depends on NEED_MULTIPLE_NODES - # LARGE_VMALLOC is racy, if you *really* need it then fix it first config ALPHA_LARGE_VMALLOC bool diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index 2b245ad73..1898ea79d 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -76,6 +76,7 @@ EXPORT_SYMBOL(strncpy); EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strncat); EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strchr); EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(memcmp); @@ -182,6 +183,7 @@ EXPORT_SYMBOL(smp_num_cpus); EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_call_function_on_cpu); EXPORT_SYMBOL(_atomic_dec_and_lock); +EXPORT_SYMBOL(cpu_present_mask); #endif /* CONFIG_SMP */ /* @@ -214,6 +216,8 @@ EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memchr); +EXPORT_SYMBOL(get_wchan); + #ifdef CONFIG_ALPHA_IRONGATE EXPORT_SYMBOL(irongate_ioremap); EXPORT_SYMBOL(irongate_iounmap); diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index 7f6a98455..44866cb26 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c @@ -435,7 +435,7 @@ marvel_specify_io7(char *str) str = pchar; } while(*str); - return 1; + return 0; } __setup("io7=", marvel_specify_io7); diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index a693bd29d..4fe254a03 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -617,7 +617,7 @@ osf_sysinfo(int command, char __user *buf, long count) long len, err = -EINVAL; offset = command-1; - if (offset >= 9) { + if (offset >= sizeof(sysinfo_table)/sizeof(char *)) { /* Digital UNIX has a few unpublished interfaces here */ printk("sysinfo(%d)", command); goto out; @@ -826,6 +826,7 @@ osf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes, affects all sorts of things, like timeval and itimerval. */ extern struct timezone sys_tz; +extern int do_adjtimex(struct timex *); struct timeval32 { diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index c760a831f..9924fd077 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -94,7 +94,7 @@ common_shutdown_1(void *generic_ptr) if (cpuid != boot_cpuid) { flags |= 0x00040000UL; /* "remain halted" */ *pflags = flags; - cpu_clear(cpuid, cpu_present_map); + clear_bit(cpuid, &cpu_present_mask); halt(); } #endif @@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - cpu_clear(boot_cpuid, cpu_present_map); - while (cpus_weight(cpu_present_map)) + cpu_clear(boot_cpuid, cpu_possible_map); + while (cpus_weight(cpu_possible_map)) barrier(); #endif diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 558b83368..45308bd3b 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -29,14 +29,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #ifdef CONFIG_MAGIC_SYSRQ #include #include @@ -45,7 +43,7 @@ #include #include -extern struct atomic_notifier_head panic_notifier_list; +extern struct notifier_block *panic_notifier_list; static int alpha_panic_event(struct notifier_block *, unsigned long, void *); static struct notifier_block alpha_panic_block = { alpha_panic_event, @@ -244,6 +242,9 @@ reserve_std_resources(void) request_resource(io, standard_io_resources+i); } +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) #define PFN_MAX PFN_DOWN(0x80000000) #define for_each_mem_cluster(memdesc, cluster, i) \ for ((cluster) = (memdesc)->cluster, (i) = 0; \ @@ -472,6 +473,11 @@ page_is_ram(unsigned long pfn) return 0; } +#undef PFN_UP +#undef PFN_DOWN +#undef PFN_PHYS +#undef PFN_MAX + static int __init register_cpus(void) { @@ -518,8 +524,7 @@ setup_arch(char **cmdline_p) } /* Register a call for panic conditions. */ - atomic_notifier_chain_register(&panic_notifier_list, - &alpha_panic_block); + notifier_chain_register(&panic_notifier_list, &alpha_panic_block); #ifdef CONFIG_ALPHA_GENERIC /* Assume that we've booted from SRM if we haven't booted from MILO. @@ -1496,20 +1501,3 @@ alpha_panic_event(struct notifier_block *this, unsigned long event, void *ptr) #endif return NOTIFY_DONE; } - -static __init int add_pcspkr(void) -{ - struct platform_device *pd; - int ret; - - pd = platform_device_alloc("pcspkr", -1); - if (!pd) - return -ENOMEM; - - ret = platform_device_add(pd); - if (ret) - platform_device_put(pd); - - return ret; -} -device_initcall(add_pcspkr); diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 4dc273e53..185255416 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -68,6 +68,7 @@ enum ipi_message_type { static int smp_secondary_alive __initdata = 0; /* Which cpus ids came online. */ +cpumask_t cpu_present_mask; cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); @@ -438,7 +439,7 @@ setup_smp(void) if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; /* Assume here that "whami" == index */ - cpu_set(i, cpu_present_map); + cpu_set(i, cpu_present_mask); cpu->pal_revision = boot_cpu_palrev; } @@ -449,10 +450,11 @@ setup_smp(void) } } else { smp_num_probed = 1; + cpu_set(boot_cpuid, cpu_present_mask); } - printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_map = %lx\n", - smp_num_probed, cpu_present_map.bits[0]); + printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", + smp_num_probed, cpu_possible_map.bits[0]); } /* @@ -471,7 +473,7 @@ smp_prepare_cpus(unsigned int max_cpus) /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - cpu_present_map = cpumask_of_cpu(boot_cpuid); + cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP mode deactivated.\n"); return; } @@ -484,6 +486,10 @@ smp_prepare_cpus(unsigned int max_cpus) void __devinit smp_prepare_boot_cpu(void) { + /* + * Mark the boot cpu (current cpu) as online + */ + cpu_set(smp_processor_id(), cpu_online_map); } int __devinit diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 2551fb49a..5f84417ee 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -66,7 +66,7 @@ titan_update_irq_hw(unsigned long mask) register int bcpu = boot_cpuid; #ifdef CONFIG_SMP - cpumask_t cpm = cpu_present_map; + cpumask_t cpm = cpu_present_mask; volatile unsigned long *dim0, *dim1, *dim2, *dim3; unsigned long mask0, mask1, mask2, mask3, dummy; diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 1c8da544d..1c5c9e32f 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -240,15 +240,7 @@ sys_call_table: .quad alpha_ni_syscall .quad alpha_ni_syscall /* 220 */ .quad alpha_ni_syscall -#ifdef CONFIG_TUX - .quad __sys_tux -#else -# ifdef CONFIG_TUX_MODULE - .quad sys_tux -# else .quad alpha_ni_syscall -# endif -#endif .quad alpha_ni_syscall .quad alpha_ni_syscall .quad alpha_ni_syscall /* 225 */ diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 385974981..6b2921be1 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -314,11 +314,10 @@ time_init(void) if (!est_cycle_freq) est_cycle_freq = validate_cc_value(calibrate_cc_with_pit()); - cc1 = rpcc(); + cc1 = rpcc_after_update_in_progress(); /* Calibrate CPU clock -- attempt #2. */ if (!est_cycle_freq) { - cc1 = rpcc_after_update_in_progress(); cc2 = rpcc_after_update_in_progress(); est_cycle_freq = validate_cc_value(cc2 - cc1); cc1 = cc2; diff --git a/arch/alpha/lib/ev6-memchr.S b/arch/alpha/lib/ev6-memchr.S index 1a5f71b9d..a8e843dbc 100644 --- a/arch/alpha/lib/ev6-memchr.S +++ b/arch/alpha/lib/ev6-memchr.S @@ -84,7 +84,7 @@ $last_quad: beq $2, $not_found # U : U L U L $found_it: -#ifdef CONFIG_ALPHA_EV67 +#if defined(__alpha_fix__) && defined(__alpha_cix__) /* * Since we are guaranteed to have set one of the bits, we don't * have to worry about coming back with a 0x40 out of cttz... diff --git a/arch/alpha/lib/fpreg.c b/arch/alpha/lib/fpreg.c index 05017ba34..97c4d9d7a 100644 --- a/arch/alpha/lib/fpreg.c +++ b/arch/alpha/lib/fpreg.c @@ -4,7 +4,7 @@ * (C) Copyright 1998 Linus Torvalds */ -#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) +#if defined(__alpha_cix__) || defined(__alpha_fix__) #define STT(reg,val) asm volatile ("ftoit $f"#reg",%0" : "=r"(val)); #else #define STT(reg,val) asm volatile ("stt $f"#reg",%0" : "=m"(val)); @@ -53,7 +53,7 @@ alpha_read_fp_reg (unsigned long reg) return val; } -#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) +#if defined(__alpha_cix__) || defined(__alpha_fix__) #define LDT(reg,val) asm volatile ("itoft %0,$f"#reg : : "r"(val)); #else #define LDT(reg,val) asm volatile ("ldt $f"#reg",%0" : : "m"(val)); @@ -98,7 +98,7 @@ alpha_write_fp_reg (unsigned long reg, unsigned long val) } } -#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) +#if defined(__alpha_cix__) || defined(__alpha_fix__) #define STS(reg,val) asm volatile ("ftois $f"#reg",%0" : "=r"(val)); #else #define STS(reg,val) asm volatile ("sts $f"#reg",%0" : "=m"(val)); @@ -147,7 +147,7 @@ alpha_read_fp_reg_s (unsigned long reg) return val; } -#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) +#if defined(__alpha_cix__) || defined(__alpha_fix__) #define LDS(reg,val) asm volatile ("itofs %0,$f"#reg : : "r"(val)); #else #define LDS(reg,val) asm volatile ("lds $f"#reg",%0" : : "m"(val)); diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index d513caec5..038f38e2b 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -358,7 +358,7 @@ free_reserved_mem(void *start, void *end) void *__start = start; for (; __start < end; __start += PAGE_SIZE) { ClearPageReserved(virt_to_page(__start)); - init_page_count(virt_to_page(__start)); + set_page_count(virt_to_page(__start), 1); free_page((long)__start); totalram_pages++; } diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index bf6b65c81..6d5251254 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -28,6 +27,9 @@ bootmem_data_t node_bdata[MAX_NUMNODES]; #define DBGDCONT(args...) #endif +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) #define for_each_mem_cluster(memdesc, cluster, i) \ for ((cluster) = (memdesc)->cluster, (i) = 0; \ (i) < (memdesc)->numclusters; (i)++, (cluster)++) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4c43ee0d9..7f139d1bd 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -8,7 +8,6 @@ mainmenu "Linux Kernel Configuration" config ARM bool default y - select RTC_LIB help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -54,10 +53,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config GENERIC_HWEIGHT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y @@ -77,14 +72,6 @@ config FIQ config ARCH_MTD_XIP bool -config VECTORS_BASE - hex - default 0xffff0000 if MMU - default DRAM_BASE if REMAP_VECTORS_TO_RAM - default 0x00000000 - help - The base address of exception vectors. - source "init/Kconfig" menu "System Type" @@ -121,13 +108,6 @@ config ARCH_EBSA110 Ethernet interface, two PCMCIA sockets, two serial ports and a parallel port. -config ARCH_EP93XX - bool "EP93xx-based" - select ARM_AMBA - select ARM_VIC - help - This enables support for the Cirrus EP93xx series of CPUs. - config ARCH_FOOTBRIDGE bool "FootBridge" select FOOTBRIDGE @@ -150,6 +130,8 @@ config ARCH_IOP3XX config ARCH_IXP4XX bool "IXP4xx-based" + select DMABOUNCE + select PCI help Support for Intel's IXP4XX (XScale) family of processors. @@ -159,12 +141,6 @@ config ARCH_IXP2000 help Support for Intel's IXP2400/2800 (XScale) family of processors. -config ARCH_IXP23XX - bool "IXP23XX-based" - select PCI - help - Support for Intel's IXP23xx (XScale) family of processors. - config ARCH_L7200 bool "LinkUp-L7200" select FIQ @@ -274,8 +250,6 @@ endchoice source "arch/arm/mach-clps711x/Kconfig" -source "arch/arm/mach-ep93xx/Kconfig" - source "arch/arm/mach-footbridge/Kconfig" source "arch/arm/mach-integrator/Kconfig" @@ -286,8 +260,6 @@ source "arch/arm/mach-ixp4xx/Kconfig" source "arch/arm/mach-ixp2000/Kconfig" -source "arch/arm/mach-ixp23xx/Kconfig" - source "arch/arm/mach-pxa/Kconfig" source "arch/arm/mach-sa1100/Kconfig" @@ -462,13 +434,6 @@ config NO_IDLE_HZ Currently at least OMAP, PXA2xx and SA11x0 platforms are known to have accurate timekeeping with dynamic tick. -config HZ - int - default 128 if ARCH_L7200 - default 200 if ARCH_EBSA110 || ARCH_S3C2410 - default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER - default 100 - config AEABI bool "Use the ARM EABI to compile the kernel" help @@ -510,12 +475,6 @@ config ARCH_DISCONTIGMEM_ENABLE or have huge holes in the physical address space for other reasons. See for more. -config NODES_SHIFT - int - default "4" if ARCH_LH7A40X - default "2" - depends on NEED_MULTIPLE_NODES - source "mm/Kconfig" config LEDS @@ -812,8 +771,7 @@ source "drivers/acorn/block/Kconfig" if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ - || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ - || ARCH_IXP23XX + || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE source "drivers/ide/Kconfig" endif @@ -851,8 +809,6 @@ source "drivers/misc/Kconfig" source "drivers/mfd/Kconfig" -source "drivers/leds/Kconfig" - source "drivers/media/Kconfig" source "drivers/video/Kconfig" @@ -863,8 +819,6 @@ source "drivers/usb/Kconfig" source "drivers/mmc/Kconfig" -source "drivers/rtc/Kconfig" - endmenu source "fs/Kconfig" diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu deleted file mode 100644 index e1574be2d..000000000 --- a/arch/arm/Kconfig-nommu +++ /dev/null @@ -1,44 +0,0 @@ -# -# Kconfig for uClinux(non-paged MM) depend configurations -# Hyok S. Choi -# - -config SET_MEM_PARAM - bool "Set flash/sdram size and base addr" - help - Say Y to manually set the base addresses and sizes. - otherwise, the default values are assigned. - -config DRAM_BASE - hex '(S)DRAM Base Address' if SET_MEM_PARAM - default 0x00800000 - -config DRAM_SIZE - hex '(S)DRAM SIZE' if SET_MEM_PARAM - default 0x00800000 - -config FLASH_MEM_BASE - hex 'FLASH Base Address' if SET_MEM_PARAM - default 0x00400000 - -config FLASH_SIZE - hex 'FLASH Size' if SET_MEM_PARAM - default 0x00400000 - -config REMAP_VECTORS_TO_RAM - bool 'Install vectors to the begining of RAM' if DRAM_BASE - depends on DRAM_BASE - help - The kernel needs to change the hardware exception vectors. - In nommu mode, the hardware exception vectors are normally - placed at address 0x00000000. However, this region may be - occupied by read-only memory depending on H/W design. - - If the region contains read-write memory, say 'n' here. - - If your CPU provides a remap facility which allows the exception - vectors to be mapped to writable memory, say 'n' here. - - Otherwise, say 'y' here. In this case, the kernel will require - external support to redirect the hardware exception vectors to - the writable versions located at DRAM_BASE. diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index d22f38b95..5d3acff8c 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -101,7 +101,7 @@ config DEBUG_S3C2410_UART help Choice for UART for kernel low-level using S3C2410 UARTS, should be between zero and two. The port must have been - initialised by the boot-loader before use. + initalised by the boot-loader before use. The uncompressor code port configuration is now handled by CONFIG_S3C2410_LOWLEVEL_UART_PORT. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6f8e84c1c..fbfc14a56 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -1,9 +1,6 @@ # # arch/arm/Makefile # -# This file is included by the global makefile so that you can add your own -# architecture-specific flags and dependencies. -# # 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. @@ -20,11 +17,6 @@ GZFLAGS :=-9 # Select a platform tht is kept up-to-date KBUILD_DEFCONFIG := versatile_defconfig -# defines filename extension depending memory manement type. -ifeq ($(CONFIG_MMU),) -MMUEXT := -nommu -endif - ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif @@ -62,11 +54,10 @@ tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale -tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) ifeq ($(CONFIG_AEABI),y) -CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork +CFLAGS_ABI :=-mabi=aapcs -mno-thumb-interwork else CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) endif @@ -78,7 +69,7 @@ AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float CHECKFLAGS += -D__arm__ #Default value -head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o +head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o textofs-y := 0x00008000 machine-$(CONFIG_ARCH_RPC) := rpc @@ -103,7 +94,6 @@ endif machine-$(CONFIG_ARCH_IOP3XX) := iop3xx machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 - machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx machine-$(CONFIG_ARCH_OMAP1) := omap1 machine-$(CONFIG_ARCH_OMAP2) := omap2 incdir-$(CONFIG_ARCH_OMAP) := omap @@ -115,7 +105,6 @@ endif machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 machine-$(CONFIG_ARCH_REALVIEW) := realview machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200 - machine-$(CONFIG_ARCH_EP93XX) := ep93xx ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. @@ -138,7 +127,7 @@ else MACHINE := endif -export TEXT_OFFSET GZFLAGS MMUEXT +export TEXT_OFFSET GZFLAGS # Do we have FASTFPE? FASTFPE :=arch/arm/fastfpe @@ -187,7 +176,7 @@ endif archprepare: maketools -PHONY += maketools FORCE +.PHONY: maketools FORCE maketools: include/linux/version.h include/asm-arm/.arch FORCE $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index ec9c400c7..a174d6339 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -1,9 +1,6 @@ # # arch/arm/boot/Makefile # -# This file is included by the global makefile so that you can add your own -# architecture-specific flags and dependencies. -# # 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. @@ -76,7 +73,7 @@ $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) @echo ' Kernel: $@ is ready' -PHONY += initrd FORCE +.PHONY: initrd FORCE initrd: @test "$(INITRD_PHYS)" != "" || \ (echo This machine does not support INITRD; exit -1) diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile index c394e3054..8e8879b6b 100644 --- a/arch/arm/boot/bootp/Makefile +++ b/arch/arm/boot/bootp/Makefile @@ -1,9 +1,6 @@ # # linux/arch/arm/boot/bootp/Makefile # -# This file is included by the global makefile so that you can add your own -# architecture-specific flags and dependencies. -# LDFLAGS_bootp :=-p --no-undefined -X \ --defsym initrd_phys=$(INITRD_PHYS) \ @@ -24,4 +21,4 @@ $(obj)/kernel.o: arch/arm/boot/zImage FORCE $(obj)/initrd.o: $(INITRD) FORCE -PHONY += $(INITRD) FORCE +.PHONY: $(INITRD) FORCE diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 2adc1527e..35ffe0f4e 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -50,6 +50,10 @@ ifeq ($(CONFIG_ARCH_AT91RM9200),y) OBJS += head-at91rm9200.o endif +ifeq ($(CONFIG_DEBUG_ICEDCC),y) +OBJS += ice-dcc.o +endif + ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) OBJS += big-endian.o endif diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index b56f5e691..db3389d8e 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -2,7 +2,6 @@ * linux/arch/arm/boot/compressed/head.S * * Copyright (C) 1996-2002 Russell King - * Copyright (C) 2004 Hyok S. Choi (MPU support) * * 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 @@ -321,62 +320,6 @@ params: ldr r0, =params_phys cache_on: mov r3, #8 @ cache_on function b call_cache_fn -/* - * Initialize the highest priority protection region, PR7 - * to cover all 32bit address and cacheable and bufferable. - */ -__armv4_mpu_cache_on: - mov r0, #0x3f @ 4G, the whole - mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting - mcr p15, 0, r0, c6, c7, 1 - - mov r0, #0x80 @ PR7 - mcr p15, 0, r0, c2, c0, 0 @ D-cache on - mcr p15, 0, r0, c2, c0, 1 @ I-cache on - mcr p15, 0, r0, c3, c0, 0 @ write-buffer on - - mov r0, #0xc000 - mcr p15, 0, r0, c5, c0, 1 @ I-access permission - mcr p15, 0, r0, c5, c0, 0 @ D-access permission - - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache - mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache - mrc p15, 0, r0, c1, c0, 0 @ read control reg - @ ...I .... ..D. WC.M - orr r0, r0, #0x002d @ .... .... ..1. 11.1 - orr r0, r0, #0x1000 @ ...1 .... .... .... - - mcr p15, 0, r0, c1, c0, 0 @ write control reg - - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache - mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache - mov pc, lr - -__armv3_mpu_cache_on: - mov r0, #0x3f @ 4G, the whole - mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting - - mov r0, #0x80 @ PR7 - mcr p15, 0, r0, c2, c0, 0 @ cache on - mcr p15, 0, r0, c3, c0, 0 @ write-buffer on - - mov r0, #0xc000 - mcr p15, 0, r0, c5, c0, 0 @ access permission - - mov r0, #0 - mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 - mrc p15, 0, r0, c1, c0, 0 @ read control reg - @ .... .... .... WC.M - orr r0, r0, #0x000d @ .... .... .... 11.1 - mov r0, #0 - mcr p15, 0, r0, c1, c0, 0 @ write control reg - - mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 - mov pc, lr - __setup_mmu: sub r3, r4, #16384 @ Page directory size bic r3, r3, #0xff @ Align the pointer bic r3, r3, #0x3f00 @@ -415,7 +358,7 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size str r1, [r0] mov pc, lr -__armv4_mmu_cache_on: +__armv4_cache_on: mov r12, lr bl __setup_mmu mov r0, #0 @@ -424,24 +367,24 @@ __armv4_mmu_cache_on: mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x0030 - bl __common_mmu_cache_on + bl __common_cache_on mov r0, #0 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs mov pc, r12 -__arm6_mmu_cache_on: +__arm6_cache_on: mov r12, lr bl __setup_mmu mov r0, #0 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 mov r0, #0x30 - bl __common_mmu_cache_on + bl __common_cache_on mov r0, #0 mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 mov pc, r12 -__common_mmu_cache_on: +__common_cache_on: #ifndef DEBUG orr r0, r0, #0x000d @ Write buffer, mmu #endif @@ -528,12 +471,12 @@ call_cache_fn: adr r12, proc_types proc_types: .word 0x41560600 @ ARM6/610 .word 0xffffffe0 - b __arm6_mmu_cache_off @ works, but slow - b __arm6_mmu_cache_off + b __arm6_cache_off @ works, but slow + b __arm6_cache_off mov pc, lr -@ b __arm6_mmu_cache_on @ untested -@ b __arm6_mmu_cache_off -@ b __armv3_mmu_cache_flush +@ b __arm6_cache_on @ untested +@ b __arm6_cache_off +@ b __armv3_cache_flush .word 0x00000000 @ old ARM ID .word 0x0000f000 @@ -543,28 +486,16 @@ proc_types: .word 0x41007000 @ ARM7/710 .word 0xfff8fe00 - b __arm7_mmu_cache_off - b __arm7_mmu_cache_off + b __arm7_cache_off + b __arm7_cache_off mov pc, lr .word 0x41807200 @ ARM720T (writethrough) .word 0xffffff00 - b __armv4_mmu_cache_on - b __armv4_mmu_cache_off + b __armv4_cache_on + b __armv4_cache_off mov pc, lr - .word 0x41007400 @ ARM74x - .word 0xff00ff00 - b __armv3_mpu_cache_on - b __armv3_mpu_cache_off - b __armv3_mpu_cache_flush - - .word 0x41009400 @ ARM94x - .word 0xff00ff00 - b __armv4_mpu_cache_on - b __armv4_mpu_cache_off - b __armv4_mpu_cache_flush - .word 0x00007000 @ ARM7 IDs .word 0x0000f000 mov pc, lr @@ -575,41 +506,41 @@ proc_types: .word 0x4401a100 @ sa110 / sa1100 .word 0xffffffe0 - b __armv4_mmu_cache_on - b __armv4_mmu_cache_off - b __armv4_mmu_cache_flush + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush .word 0x6901b110 @ sa1110 .word 0xfffffff0 - b __armv4_mmu_cache_on - b __armv4_mmu_cache_off - b __armv4_mmu_cache_flush + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush @ These match on the architecture ID .word 0x00020000 @ ARMv4T .word 0x000f0000 - b __armv4_mmu_cache_on - b __armv4_mmu_cache_off - b __armv4_mmu_cache_flush + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush .word 0x00050000 @ ARMv5TE .word 0x000f0000 - b __armv4_mmu_cache_on - b __armv4_mmu_cache_off - b __armv4_mmu_cache_flush + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush .word 0x00060000 @ ARMv5TEJ .word 0x000f0000 - b __armv4_mmu_cache_on - b __armv4_mmu_cache_off - b __armv4_mmu_cache_flush + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush .word 0x00070000 @ ARMv6 .word 0x000f0000 - b __armv4_mmu_cache_on - b __armv4_mmu_cache_off - b __armv6_mmu_cache_flush + b __armv4_cache_on + b __armv4_cache_off + b __armv6_cache_flush .word 0 @ unrecognised type .word 0 @@ -631,25 +562,7 @@ proc_types: cache_off: mov r3, #12 @ cache_off function b call_cache_fn -__armv4_mpu_cache_off: - mrc p15, 0, r0, c1, c0 - bic r0, r0, #0x000d - mcr p15, 0, r0, c1, c0 @ turn MPU and cache off - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache - mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache - mov pc, lr - -__armv3_mpu_cache_off: - mrc p15, 0, r0, c1, c0 - bic r0, r0, #0x000d - mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off - mov r0, #0 - mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 - mov pc, lr - -__armv4_mmu_cache_off: +__armv4_cache_off: mrc p15, 0, r0, c1, c0 bic r0, r0, #0x000d mcr p15, 0, r0, c1, c0 @ turn MMU and cache off @@ -658,15 +571,15 @@ __armv4_mmu_cache_off: mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 mov pc, lr -__arm6_mmu_cache_off: +__arm6_cache_off: mov r0, #0x00000030 @ ARM6 control reg. - b __armv3_mmu_cache_off + b __armv3_cache_off -__arm7_mmu_cache_off: +__arm7_cache_off: mov r0, #0x00000070 @ ARM7 control reg. - b __armv3_mmu_cache_off + b __armv3_cache_off -__armv3_mmu_cache_off: +__armv3_cache_off: mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off mov r0, #0 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 @@ -688,25 +601,7 @@ cache_clean_flush: mov r3, #16 b call_cache_fn -__armv4_mpu_cache_flush: - mov r2, #1 - mov r3, #0 - mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache - mov r1, #7 << 5 @ 8 segments -1: orr r3, r1, #63 << 26 @ 64 entries -2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index - subs r3, r3, #1 << 26 - bcs 2b @ entries 63 to 0 - subs r1, r1, #1 << 5 - bcs 1b @ segments 7 to 0 - - teq r2, #0 - mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - - -__armv6_mmu_cache_flush: +__armv6_cache_flush: mov r1, #0 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB @@ -714,7 +609,7 @@ __armv6_mmu_cache_flush: mcr p15, 0, r1, c7, c10, 4 @ drain WB mov pc, lr -__armv4_mmu_cache_flush: +__armv4_cache_flush: mov r2, #64*1024 @ default: 32K dcache size (*2) mov r11, #32 @ default: 32 byte line size mrc p15, 0, r3, c0, c0, 1 @ read cache type @@ -742,8 +637,7 @@ no_cache_id: mcr p15, 0, r1, c7, c10, 4 @ drain WB mov pc, lr -__armv3_mmu_cache_flush: -__armv3_mpu_cache_flush: +__armv3_cache_flush: mov r1, #0 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 mov pc, lr diff --git a/arch/arm/boot/compressed/ice-dcc.S b/arch/arm/boot/compressed/ice-dcc.S new file mode 100644 index 000000000..104377a19 --- /dev/null +++ b/arch/arm/boot/compressed/ice-dcc.S @@ -0,0 +1,17 @@ + + + .text + + .global icedcc_putc + +icedcc_putc: + mov r2, #0x4000000 +1: + subs r2, r2, #1 + movlt pc, r14 + mrc p14, 0, r1, c0, c0, 0 + tst r1, #2 + bne 1b + + mcr p14, 0, r0, c1, c0, 0 + mov pc, r14 diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index ace3fb583..5ab94584b 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -20,45 +20,24 @@ unsigned int __machine_arch_type; #include +#include + #ifdef STANDALONE_DEBUG #define putstr printf -#else - -static void putstr(const char *ptr); - -#include -#include +#endif #ifdef CONFIG_DEBUG_ICEDCC -static void icedcc_putc(int ch) -{ - int status, i = 0x4000000; +#define putstr icedcc_putstr +#define putc icedcc_putc - do { - if (--i < 0) - return; +extern void icedcc_putc(int ch); - asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status)); - } while (status & 2); - - asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch)); -} - -#define putc(ch) icedcc_putc(ch) -#define flush() do { } while (0) -#endif - -static void putstr(const char *ptr) +static void +icedcc_putstr(const char *ptr) { - char c; - - while ((c = *ptr++) != '\0') { - if (c == '\n') - putc('\r'); - putc(c); + for (; *ptr != '\0'; ptr++) { + icedcc_putc(*ptr); } - - flush(); } #endif diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index 153a07e72..eed616113 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in @@ -18,7 +18,6 @@ SECTIONS _start = .; *(.start) *(.text) - *(.text.*) *(.fixup) *(.gnu.warning) *(.rodata) diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 847e3e635..c81a2ff6b 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -15,4 +15,3 @@ obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o -obj-$(CONFIG_ARCH_IXP2000) += uengine.o diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index 7971d0dc6..ad6c89a55 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -5,7 +5,7 @@ * limited DMA windows. These functions utilize bounce buffers to * copy data to/from buffers located outside the DMA region. This * only works for systems in which DMA memory is at the bottom of - * RAM, the remainder of memory is at the top and the DMA memory + * RAM and the remainder of memory is at the top an the DMA memory * can be marked as ZONE_DMA. Anything beyond that such as discontigous * DMA windows will require custom implementations that reserve memory * areas at early bootup. diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index a7dc13706..d31b1cb7e 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -60,7 +60,7 @@ struct locomo { unsigned long phys; unsigned int irq; spinlock_t lock; - void __iomem *base; + void *base; }; struct locomo_dev_info { @@ -162,7 +162,7 @@ static void locomo_handler(unsigned int irq, struct irqdesc *desc, { int req, i; struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); /* Acknowledge the parent IRQ */ desc->chip->ack(irq); @@ -189,7 +189,7 @@ static void locomo_ack_irq(unsigned int irq) static void locomo_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_ICR); r &= ~(0x0010 << (irq - LOCOMO_IRQ_START)); @@ -198,7 +198,7 @@ static void locomo_mask_irq(unsigned int irq) static void locomo_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_ICR); r |= (0x0010 << (irq - LOCOMO_IRQ_START)); @@ -215,7 +215,7 @@ static void locomo_key_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { d = irq_desc + LOCOMO_IRQ_KEY_START; @@ -225,7 +225,7 @@ static void locomo_key_handler(unsigned int irq, struct irqdesc *desc, static void locomo_key_ack_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START)); @@ -234,7 +234,7 @@ static void locomo_key_ack_irq(unsigned int irq) static void locomo_key_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START)); @@ -243,7 +243,7 @@ static void locomo_key_mask_irq(unsigned int irq) static void locomo_key_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START)); @@ -261,7 +261,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc, { int req, i; struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); req = locomo_readl(mapbase + LOCOMO_GIR) & locomo_readl(mapbase + LOCOMO_GPD) & @@ -280,7 +280,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc, static void locomo_gpio_ack_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_GWE); r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); @@ -297,7 +297,7 @@ static void locomo_gpio_ack_irq(unsigned int irq) static void locomo_gpio_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_GIE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); @@ -306,7 +306,7 @@ static void locomo_gpio_mask_irq(unsigned int irq) static void locomo_gpio_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_GIE); r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); @@ -323,7 +323,7 @@ static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) { d = irq_desc + LOCOMO_IRQ_LT_START; @@ -333,7 +333,7 @@ static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc, static void locomo_lt_ack_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_LTINT); r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START)); @@ -342,7 +342,7 @@ static void locomo_lt_ack_irq(unsigned int irq) static void locomo_lt_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_LTINT); r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START)); @@ -351,7 +351,7 @@ static void locomo_lt_mask_irq(unsigned int irq) static void locomo_lt_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_LTINT); r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START)); @@ -369,7 +369,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc, { int req, i; struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); req = locomo_readl(mapbase + LOCOMO_SPIIR) & 0x000F; if (req) { @@ -386,7 +386,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc, static void locomo_spi_ack_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_SPIWE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); @@ -403,7 +403,7 @@ static void locomo_spi_ack_irq(unsigned int irq) static void locomo_spi_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_SPIIE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); @@ -412,7 +412,7 @@ static void locomo_spi_mask_irq(unsigned int irq) static void locomo_spi_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void *mapbase = get_irq_chipdata(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_SPIIE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); @@ -428,7 +428,7 @@ static struct irqchip locomo_spi_chip = { static void locomo_setup_irq(struct locomo *lchip) { int irq; - void __iomem *irqbase = lchip->base; + void *irqbase = lchip->base; /* * Install handler for IRQ_LOCOMO_HW. @@ -501,11 +501,12 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info) struct locomo_dev *dev; int ret; - dev = kzalloc(sizeof(struct locomo_dev), GFP_KERNEL); + dev = kmalloc(sizeof(struct locomo_dev), GFP_KERNEL); if (!dev) { ret = -ENOMEM; goto out; } + memset(dev, 0, sizeof(struct locomo_dev)); strncpy(dev->dev.bus_id,info->name,sizeof(dev->dev.bus_id)); /* @@ -663,10 +664,12 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) unsigned long r; int i, ret = -ENODEV; - lchip = kzalloc(sizeof(struct locomo), GFP_KERNEL); + lchip = kmalloc(sizeof(struct locomo), GFP_KERNEL); if (!lchip) return -ENOMEM; + memset(lchip, 0, sizeof(struct locomo)); + spin_lock_init(&lchip->lock); lchip->dev = me; @@ -785,8 +788,6 @@ static int locomo_probe(struct platform_device *dev) if (!mem) return -EINVAL; irq = platform_get_irq(dev, 0); - if (irq < 0) - return -ENXIO; return __locomo_probe(&dev->dev, mem, irq); } diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c index 35c9a64ac..e851d86c2 100644 --- a/arch/arm/common/rtctime.c +++ b/arch/arm/common/rtctime.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -43,6 +42,89 @@ static struct rtc_ops *rtc_ops; #define rtc_epoch 1900UL +static const unsigned char days_in_month[] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) +#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) + +static int month_days(unsigned int month, unsigned int year) +{ + return days_in_month[month] + (LEAP_YEAR(year) && month == 1); +} + +/* + * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. + */ +void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) +{ + int days, month, year; + + days = time / 86400; + time -= days * 86400; + + tm->tm_wday = (days + 4) % 7; + + year = 1970 + days / 365; + days -= (year - 1970) * 365 + + LEAPS_THRU_END_OF(year - 1) + - LEAPS_THRU_END_OF(1970 - 1); + if (days < 0) { + year -= 1; + days += 365 + LEAP_YEAR(year); + } + tm->tm_year = year - 1900; + tm->tm_yday = days + 1; + + for (month = 0; month < 11; month++) { + int newdays; + + newdays = days - month_days(month, year); + if (newdays < 0) + break; + days = newdays; + } + tm->tm_mon = month; + tm->tm_mday = days + 1; + + tm->tm_hour = time / 3600; + time -= tm->tm_hour * 3600; + tm->tm_min = time / 60; + tm->tm_sec = time - tm->tm_min * 60; +} +EXPORT_SYMBOL(rtc_time_to_tm); + +/* + * Does the rtc_time represent a valid date/time? + */ +int rtc_valid_tm(struct rtc_time *tm) +{ + if (tm->tm_year < 70 || + tm->tm_mon >= 12 || + tm->tm_mday < 1 || + tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) || + tm->tm_hour >= 24 || + tm->tm_min >= 60 || + tm->tm_sec >= 60) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL(rtc_valid_tm); + +/* + * Convert Gregorian date to seconds since 01-01-1970 00:00:00. + */ +int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) +{ + *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + + return 0; +} +EXPORT_SYMBOL(rtc_tm_to_time); + /* * Calculate the next alarm time given the requested alarm time mask * and the current time. @@ -69,13 +151,13 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc } } -static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) +static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) { memset(tm, 0, sizeof(struct rtc_time)); return ops->read_time(tm); } -static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) +static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) { int ret; @@ -86,7 +168,7 @@ static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) return ret; } -static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) +static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) { int ret = -EINVAL; if (ops->read_alarm) { @@ -96,7 +178,7 @@ static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alr return ret; } -static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) +static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) { int ret = -EINVAL; if (ops->set_alarm) @@ -184,7 +266,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, switch (cmd) { case RTC_ALM_READ: - ret = rtc_arm_read_alarm(ops, &alrm); + ret = rtc_read_alarm(ops, &alrm); if (ret) break; ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); @@ -206,11 +288,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, alrm.time.tm_wday = -1; alrm.time.tm_yday = -1; alrm.time.tm_isdst = -1; - ret = rtc_arm_set_alarm(ops, &alrm); + ret = rtc_set_alarm(ops, &alrm); break; case RTC_RD_TIME: - ret = rtc_arm_read_time(ops, &tm); + ret = rtc_read_time(ops, &tm); if (ret) break; ret = copy_to_user(uarg, &tm, sizeof(tm)); @@ -228,7 +310,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ret = -EFAULT; break; } - ret = rtc_arm_set_time(ops, &tm); + ret = rtc_set_time(ops, &tm); break; case RTC_EPOCH_SET: @@ -259,11 +341,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ret = -EFAULT; break; } - ret = rtc_arm_set_alarm(ops, &alrm); + ret = rtc_set_alarm(ops, &alrm); break; case RTC_WKALM_RD: - ret = rtc_arm_read_alarm(ops, &alrm); + ret = rtc_read_alarm(ops, &alrm); if (ret) break; ret = copy_to_user(uarg, &alrm, sizeof(alrm)); @@ -353,7 +435,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo struct rtc_time tm; char *p = page; - if (rtc_arm_read_time(ops, &tm) == 0) { + if (rtc_read_time(ops, &tm) == 0) { p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n" "rtc_date\t: %04d-%02d-%02d\n" @@ -363,7 +445,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo rtc_epoch); } - if (rtc_arm_read_alarm(ops, &alrm) == 0) { + if (rtc_read_alarm(ops, &alrm) == 0) { p += sprintf(p, "alrm_time\t: "); if ((unsigned int)alrm.time.tm_hour <= 24) p += sprintf(p, "%02d:", alrm.time.tm_hour); diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 3f68db84e..1475089f9 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -37,6 +36,10 @@ #include +#ifdef CONFIG_ARCH_PXA +#include +#endif + extern void __init sa1110_mb_enable(void); /* @@ -48,7 +51,6 @@ extern void __init sa1110_mb_enable(void); */ struct sa1111 { struct device *dev; - struct clk *clk; unsigned long phys; int irq; spinlock_t lock; @@ -449,7 +451,19 @@ static void sa1111_wake(struct sa1111 *sachip) spin_lock_irqsave(&sachip->lock, flags); - clk_enable(sachip->clk); +#ifdef CONFIG_ARCH_SA1100 + /* + * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: + * (SA-1110 Developer's Manual, section 9.1.2.1) + */ + GAFR |= GPIO_32_768kHz; + GPDR |= GPIO_32_768kHz; + TUCR = TUCR_3_6864MHz; +#elif CONFIG_ARCH_PXA + pxa_gpio_mode(GPIO11_3_6MHz_MD); +#else +#error missing clock setup +#endif /* * Turn VCO on, and disable PLL Bypass. @@ -541,11 +555,12 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, struct sa1111_dev *dev; int ret; - dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); + dev = kmalloc(sizeof(struct sa1111_dev), GFP_KERNEL); if (!dev) { ret = -ENOMEM; goto out; } + memset(dev, 0, sizeof(struct sa1111_dev)); snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "%4.4lx", info->offset); @@ -620,15 +635,11 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) unsigned int has_devs, val; int i, ret = -ENODEV; - sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); + sachip = kmalloc(sizeof(struct sa1111), GFP_KERNEL); if (!sachip) return -ENOMEM; - sachip->clk = clk_get(me, "GPIO27_CLK"); - if (!sachip->clk) { - ret = PTR_ERR(sachip->clk); - goto err_free; - } + memset(sachip, 0, sizeof(struct sa1111)); spin_lock_init(&sachip->lock); @@ -645,7 +656,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) sachip->base = ioremap(mem->start, PAGE_SIZE * 2); if (!sachip->base) { ret = -ENOMEM; - goto err_clkput; + goto out; } /* @@ -655,7 +666,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id); ret = -ENODEV; - goto err_unmap; + goto unmap; } printk(KERN_INFO "SA1111 Microprocessor Companion Chip: " @@ -715,11 +726,9 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) return 0; - err_unmap: + unmap: iounmap(sachip->base); - err_clkput: - clk_put(sachip->clk); - err_free: + out: kfree(sachip); return ret; } @@ -742,8 +751,6 @@ static void __sa1111_remove(struct sa1111 *sachip) sa1111_writel(0, irqbase + SA1111_WAKEEN0); sa1111_writel(0, irqbase + SA1111_WAKEEN1); - clk_disable(sachip->clk); - if (sachip->irq != NO_IRQ) { set_irq_chained_handler(sachip->irq, NULL); set_irq_data(sachip->irq, NULL); @@ -752,7 +759,6 @@ static void __sa1111_remove(struct sa1111 *sachip) } iounmap(sachip->base); - clk_put(sachip->clk); kfree(sachip); } @@ -851,8 +857,6 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) sa1111_writel(0, sachip->base + SA1111_SKPWM0); sa1111_writel(0, sachip->base + SA1111_SKPWM1); - clk_disable(sachip->clk); - spin_unlock_irqrestore(&sachip->lock, flags); return 0; @@ -939,8 +943,6 @@ static int sa1111_probe(struct platform_device *pdev) if (!mem) return -EINVAL; irq = platform_get_irq(pdev, 0); - if (irq < 0) - return -ENXIO; return __sa1111_probe(&pdev->dev, mem, irq); } diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index cfd0d3e55..a2dfe0b0f 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -12,6 +12,9 @@ */ #include +#include +#include +#include #include #include @@ -20,6 +23,8 @@ struct scoop_dev { void *base; spinlock_t scoop_lock; + unsigned short suspend_clr; + unsigned short suspend_set; u32 scoop_gpwr; }; @@ -29,7 +34,6 @@ void reset_scoop(struct device *dev) SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100; // 00 SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000; // 04 - SCOOP_REG(sdev->base,SCOOP_CPR) = 0x0000; // 0C SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000; // 10 SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000; // 18 SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF; // 14 @@ -84,25 +88,34 @@ EXPORT_SYMBOL(reset_scoop); EXPORT_SYMBOL(read_scoop_reg); EXPORT_SYMBOL(write_scoop_reg); +static void check_scoop_reg(struct scoop_dev *sdev) +{ + unsigned short mcr; + + mcr = SCOOP_REG(sdev->base, SCOOP_MCR); + if ((mcr & 0x100) == 0) + SCOOP_REG(sdev->base, SCOOP_MCR) = 0x0101; +} + #ifdef CONFIG_PM -static int scoop_suspend(struct device *dev, uint32_t state, uint32_t level) +static int scoop_suspend(struct platform_device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) { - struct scoop_dev *sdev = dev_get_drvdata(dev); + struct scoop_dev *sdev = platform_get_drvdata(dev); + + check_scoop_reg(sdev); + sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR); + SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set; - sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR); - SCOOP_REG(sdev->base,SCOOP_GPWR) = 0; - } return 0; } -static int scoop_resume(struct device *dev, uint32_t level) +static int scoop_resume(struct platform_device *dev) { - if (level == RESUME_POWER_ON) { - struct scoop_dev *sdev = dev_get_drvdata(dev); + struct scoop_dev *sdev = platform_get_drvdata(dev); + + check_scoop_reg(sdev); + SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; - SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; - } return 0; } #else @@ -110,11 +123,10 @@ static int scoop_resume(struct device *dev, uint32_t level) #define scoop_resume NULL #endif -int __init scoop_probe(struct device *dev) +int __init scoop_probe(struct platform_device *pdev) { struct scoop_dev *devptr; struct scoop_config *inf; - struct platform_device *pdev = to_platform_device(dev); struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) @@ -128,7 +140,7 @@ int __init scoop_probe(struct device *dev) memset(devptr, 0, sizeof(struct scoop_dev)); spin_lock_init(&devptr->scoop_lock); - inf = dev->platform_data; + inf = pdev->dev.platform_data; devptr->base = ioremap(mem->start, mem->end - mem->start + 1); if (!devptr->base) { @@ -136,41 +148,46 @@ int __init scoop_probe(struct device *dev) return -ENOMEM; } - dev_set_drvdata(dev, devptr); + platform_set_drvdata(pdev, devptr); printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base); SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140; - reset_scoop(dev); + reset_scoop(&pdev->dev); + SCOOP_REG(devptr->base, SCOOP_CPR) = 0x0000; SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; + devptr->suspend_clr = inf->suspend_clr; + devptr->suspend_set = inf->suspend_set; + return 0; } -static int scoop_remove(struct device *dev) +static int scoop_remove(struct platform_device *pdev) { - struct scoop_dev *sdev = dev_get_drvdata(dev); + struct scoop_dev *sdev = platform_get_drvdata(pdev); if (sdev) { iounmap(sdev->base); kfree(sdev); - dev_set_drvdata(dev, NULL); + platform_set_drvdata(pdev, NULL); } return 0; } -static struct device_driver scoop_driver = { - .name = "sharp-scoop", - .bus = &platform_bus_type, +static struct platform_driver scoop_driver = { .probe = scoop_probe, .remove = scoop_remove, .suspend = scoop_suspend, .resume = scoop_resume, + .driver = { + .name = "sharp-scoop", + }, }; int __init scoop_init(void) { - return driver_register(&scoop_driver); + return platform_driver_register(&scoop_driver); } subsys_initcall(scoop_init); diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 3cd8c9ee4..978d32e82 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -76,7 +75,6 @@ static void sharpsl_battery_thread(void *private_); struct sharpsl_pm_status sharpsl_pm; DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); -DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger); static int get_percentage(int voltage) @@ -192,10 +190,10 @@ void sharpsl_pm_led(int val) dev_err(sharpsl_pm.dev, "Charging Error!\n"); } else if (val == SHARPSL_LED_ON) { dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); - led_trigger_event(sharpsl_charge_led_trigger, LED_FULL); + } else { dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); - led_trigger_event(sharpsl_charge_led_trigger, LED_OFF); + } } @@ -788,8 +786,6 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev) init_timer(&sharpsl_pm.chrg_full_timer); sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; - led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger); - sharpsl_pm.machinfo->init(); device_create_file(&pdev->dev, &dev_attr_battery_percentage); @@ -811,8 +807,6 @@ static int sharpsl_pm_remove(struct platform_device *pdev) device_remove_file(&pdev->dev, &dev_attr_battery_percentage); device_remove_file(&pdev->dev, &dev_attr_battery_voltage); - led_trigger_unregister_simple(sharpsl_charge_led_trigger); - sharpsl_pm.machinfo->exit(); del_timer_sync(&sharpsl_pm.chrg_full_timer); diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c deleted file mode 100644 index a1310b710..000000000 --- a/arch/arm/common/uengine.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Generic library functions for the microengines found on the Intel - * IXP2000 series of network processors. - * - * Copyright (C) 2004, 2005 Lennert Buytenhek - * Dedicated to Marija Kulikova. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define USTORE_ADDRESS 0x000 -#define USTORE_DATA_LOWER 0x004 -#define USTORE_DATA_UPPER 0x008 -#define CTX_ENABLES 0x018 -#define CC_ENABLE 0x01c -#define CSR_CTX_POINTER 0x020 -#define INDIRECT_CTX_STS 0x040 -#define ACTIVE_CTX_STS 0x044 -#define INDIRECT_CTX_SIG_EVENTS 0x048 -#define INDIRECT_CTX_WAKEUP_EVENTS 0x050 -#define NN_PUT 0x080 -#define NN_GET 0x084 -#define TIMESTAMP_LOW 0x0c0 -#define TIMESTAMP_HIGH 0x0c4 -#define T_INDEX_BYTE_INDEX 0x0f4 -#define LOCAL_CSR_STATUS 0x180 - -u32 ixp2000_uengine_mask; - -static void *ixp2000_uengine_csr_area(int uengine) -{ - return ((void *)IXP2000_UENGINE_CSR_VIRT_BASE) + (uengine << 10); -} - -/* - * LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR - * space means that the microengine we tried to access was also trying - * to access its own CSR space on the same clock cycle as we did. When - * this happens, we lose the arbitration process by default, and the - * read or write we tried to do was not actually performed, so we try - * again until it succeeds. - */ -u32 ixp2000_uengine_csr_read(int uengine, int offset) -{ - void *uebase; - u32 *local_csr_status; - u32 *reg; - u32 value; - - uebase = ixp2000_uengine_csr_area(uengine); - - local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS); - reg = (u32 *)(uebase + offset); - do { - value = ixp2000_reg_read(reg); - } while (ixp2000_reg_read(local_csr_status) & 1); - - return value; -} -EXPORT_SYMBOL(ixp2000_uengine_csr_read); - -void ixp2000_uengine_csr_write(int uengine, int offset, u32 value) -{ - void *uebase; - u32 *local_csr_status; - u32 *reg; - - uebase = ixp2000_uengine_csr_area(uengine); - - local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS); - reg = (u32 *)(uebase + offset); - do { - ixp2000_reg_write(reg, value); - } while (ixp2000_reg_read(local_csr_status) & 1); -} -EXPORT_SYMBOL(ixp2000_uengine_csr_write); - -void ixp2000_uengine_reset(u32 uengine_mask) -{ - ixp2000_reg_wrb(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask); - ixp2000_reg_wrb(IXP2000_RESET1, 0); -} -EXPORT_SYMBOL(ixp2000_uengine_reset); - -void ixp2000_uengine_set_mode(int uengine, u32 mode) -{ - /* - * CTL_STR_PAR_EN: unconditionally enable parity checking on - * control store. - */ - mode |= 0x10000000; - ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode); - - /* - * Enable updating of condition codes. - */ - ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000); - - /* - * Initialise other per-microengine registers. - */ - ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00); - ixp2000_uengine_csr_write(uengine, NN_GET, 0x00); - ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0); -} -EXPORT_SYMBOL(ixp2000_uengine_set_mode); - -static int make_even_parity(u32 x) -{ - return hweight32(x) & 1; -} - -static void ustore_write(int uengine, u64 insn) -{ - /* - * Generate even parity for top and bottom 20 bits. - */ - insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41; - insn |= (u64)make_even_parity(insn & 0x000fffff) << 40; - - /* - * Write to microstore. The second write auto-increments - * the USTORE_ADDRESS index register. - */ - ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn); - ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32)); -} - -void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns) -{ - int i; - - /* - * Start writing to microstore at address 0. - */ - ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000); - for (i = 0; i < insns; i++) { - u64 insn; - - insn = (((u64)ucode[0]) << 32) | - (((u64)ucode[1]) << 24) | - (((u64)ucode[2]) << 16) | - (((u64)ucode[3]) << 8) | - ((u64)ucode[4]); - ucode += 5; - - ustore_write(uengine, insn); - } - - /* - * Pad with a few NOPs at the end (to avoid the microengine - * aborting as it prefetches beyond the last instruction), unless - * we run off the end of the instruction store first, at which - * point the address register will wrap back to zero. - */ - for (i = 0; i < 4; i++) { - u32 addr; - - addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS); - if (addr == 0x80000000) - break; - ustore_write(uengine, 0xf0000c0300ULL); - } - - /* - * End programming. - */ - ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000); -} -EXPORT_SYMBOL(ixp2000_uengine_load_microcode); - -void ixp2000_uengine_init_context(int uengine, int context, int pc) -{ - /* - * Select the right context for indirect access. - */ - ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context); - - /* - * Initialise signal masks to immediately go to Ready state. - */ - ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1); - ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1); - - /* - * Set program counter. - */ - ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc); -} -EXPORT_SYMBOL(ixp2000_uengine_init_context); - -void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask) -{ - u32 mask; - - /* - * Enable the specified context to go to Executing state. - */ - mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES); - mask |= ctx_mask << 8; - ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask); -} -EXPORT_SYMBOL(ixp2000_uengine_start_contexts); - -void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask) -{ - u32 mask; - - /* - * Disable the Ready->Executing transition. Note that this - * does not stop the context until it voluntarily yields. - */ - mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES); - mask &= ~(ctx_mask << 8); - ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask); -} -EXPORT_SYMBOL(ixp2000_uengine_stop_contexts); - -static int check_ixp_type(struct ixp2000_uengine_code *c) -{ - u32 product_id; - u32 rev; - - product_id = ixp2000_reg_read(IXP2000_PRODUCT_ID); - if (((product_id >> 16) & 0x1f) != 0) - return 0; - - switch ((product_id >> 8) & 0xff) { - case 0: /* IXP2800 */ - if (!(c->cpu_model_bitmask & 4)) - return 0; - break; - - case 1: /* IXP2850 */ - if (!(c->cpu_model_bitmask & 8)) - return 0; - break; - - case 2: /* IXP2400 */ - if (!(c->cpu_model_bitmask & 2)) - return 0; - break; - - default: - return 0; - } - - rev = product_id & 0xff; - if (rev < c->cpu_min_revision || rev > c->cpu_max_revision) - return 0; - - return 1; -} - -static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b) -{ - int offset; - int i; - - offset = 0; - - for (i = 0; i < 128; i++) { - u8 b3; - u8 b2; - u8 b1; - u8 b0; - - b3 = (gpr_a[i] >> 24) & 0xff; - b2 = (gpr_a[i] >> 16) & 0xff; - b1 = (gpr_a[i] >> 8) & 0xff; - b0 = gpr_a[i] & 0xff; - - // immed[@ai, (b1 << 8) | b0] - // 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII - ucode[offset++] = 0xf0; - ucode[offset++] = (b1 >> 4); - ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6); - ucode[offset++] = (b0 << 2); - ucode[offset++] = 0x80 | i; - - // immed_w1[@ai, (b3 << 8) | b2] - // 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII - ucode[offset++] = 0xf4; - ucode[offset++] = 0x40 | (b3 >> 4); - ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6); - ucode[offset++] = (b2 << 2); - ucode[offset++] = 0x80 | i; - } - - for (i = 0; i < 128; i++) { - u8 b3; - u8 b2; - u8 b1; - u8 b0; - - b3 = (gpr_b[i] >> 24) & 0xff; - b2 = (gpr_b[i] >> 16) & 0xff; - b1 = (gpr_b[i] >> 8) & 0xff; - b0 = gpr_b[i] & 0xff; - - // immed[@bi, (b1 << 8) | b0] - // 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV - ucode[offset++] = 0xf0; - ucode[offset++] = (b1 >> 4); - ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6); - ucode[offset++] = (i << 2) | 0x03; - ucode[offset++] = b0; - - // immed_w1[@bi, (b3 << 8) | b2] - // 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV - ucode[offset++] = 0xf4; - ucode[offset++] = 0x40 | (b3 >> 4); - ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6); - ucode[offset++] = (i << 2) | 0x03; - ucode[offset++] = b2; - } - - // ctx_arb[kill] - ucode[offset++] = 0xe0; - ucode[offset++] = 0x00; - ucode[offset++] = 0x01; - ucode[offset++] = 0x00; - ucode[offset++] = 0x00; -} - -static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c) -{ - int per_ctx_regs; - u32 *gpr_a; - u32 *gpr_b; - u8 *ucode; - int i; - - gpr_a = kmalloc(128 * sizeof(u32), GFP_KERNEL); - gpr_b = kmalloc(128 * sizeof(u32), GFP_KERNEL); - ucode = kmalloc(513 * 5, GFP_KERNEL); - if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) { - kfree(ucode); - kfree(gpr_b); - kfree(gpr_a); - return 1; - } - - per_ctx_regs = 16; - if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS) - per_ctx_regs = 32; - - memset(gpr_a, 0, sizeof(gpr_a)); - memset(gpr_b, 0, sizeof(gpr_b)); - for (i = 0; i < 256; i++) { - struct ixp2000_reg_value *r = c->initial_reg_values + i; - u32 *bank; - int inc; - int j; - - if (r->reg == -1) - break; - - bank = (r->reg & 0x400) ? gpr_b : gpr_a; - inc = (r->reg & 0x80) ? 128 : per_ctx_regs; - - j = r->reg & 0x7f; - while (j < 128) { - bank[j] = r->value; - j += inc; - } - } - - generate_ucode(ucode, gpr_a, gpr_b); - ixp2000_uengine_load_microcode(uengine, ucode, 513); - ixp2000_uengine_init_context(uengine, 0, 0); - ixp2000_uengine_start_contexts(uengine, 0x01); - for (i = 0; i < 100; i++) { - u32 status; - - status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS); - if (!(status & 0x80000000)) - break; - } - ixp2000_uengine_stop_contexts(uengine, 0x01); - - kfree(ucode); - kfree(gpr_b); - kfree(gpr_a); - - return !!(i == 100); -} - -int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c) -{ - int ctx; - - if (!check_ixp_type(c)) - return 1; - - if (!(ixp2000_uengine_mask & (1 << uengine))) - return 1; - - ixp2000_uengine_reset(1 << uengine); - ixp2000_uengine_set_mode(uengine, c->uengine_parameters); - if (set_initial_registers(uengine, c)) - return 1; - ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns); - - for (ctx = 0; ctx < 8; ctx++) - ixp2000_uengine_init_context(uengine, ctx, 0); - - return 0; -} -EXPORT_SYMBOL(ixp2000_uengine_load); - - -static int __init ixp2000_uengine_init(void) -{ - int uengine; - u32 value; - - /* - * Determine number of microengines present. - */ - switch ((ixp2000_reg_read(IXP2000_PRODUCT_ID) >> 8) & 0x1fff) { - case 0: /* IXP2800 */ - case 1: /* IXP2850 */ - ixp2000_uengine_mask = 0x00ff00ff; - break; - - case 2: /* IXP2400 */ - ixp2000_uengine_mask = 0x000f000f; - break; - - default: - printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n", - (unsigned int)ixp2000_reg_read(IXP2000_PRODUCT_ID)); - ixp2000_uengine_mask = 0x00000000; - break; - } - - /* - * Reset microengines. - */ - ixp2000_uengine_reset(ixp2000_uengine_mask); - - /* - * Synchronise timestamp counters across all microengines. - */ - value = ixp2000_reg_read(IXP2000_MISC_CONTROL); - ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value & ~0x80); - for (uengine = 0; uengine < 32; uengine++) { - if (ixp2000_uengine_mask & (1 << uengine)) { - ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0); - ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0); - } - } - ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value | 0x80); - - return 0; -} - -subsys_initcall(ixp2000_uengine_init); diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index a19bc4a61..a45ed1687 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -22,21 +22,22 @@ #include #include +#include #include #include +static void __iomem *vic_base; + static void vic_mask_irq(unsigned int irq) { - void __iomem *base = get_irq_chipdata(irq); - irq &= 31; - writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); + irq -= IRQ_VIC_START; + writel(1 << irq, vic_base + VIC_INT_ENABLE_CLEAR); } static void vic_unmask_irq(unsigned int irq) { - void __iomem *base = get_irq_chipdata(irq); - irq &= 31; - writel(1 << irq, base + VIC_INT_ENABLE); + irq -= IRQ_VIC_START; + writel(1 << irq, vic_base + VIC_INT_ENABLE); } static struct irqchip vic_chip = { @@ -45,49 +46,43 @@ static struct irqchip vic_chip = { .unmask = vic_unmask_irq, }; -/** - * vic_init - initialise a vectored interrupt controller - * @base: iomem base address - * @irq_start: starting interrupt number, must be muliple of 32 - * @vic_sources: bitmask of interrupt sources to allow - */ -void __init vic_init(void __iomem *base, unsigned int irq_start, - u32 vic_sources) +void __init vic_init(void __iomem *base, u32 vic_sources) { unsigned int i; + vic_base = base; + /* Disable all interrupts initially. */ - writel(0, base + VIC_INT_SELECT); - writel(0, base + VIC_INT_ENABLE); - writel(~0, base + VIC_INT_ENABLE_CLEAR); - writel(0, base + VIC_IRQ_STATUS); - writel(0, base + VIC_ITCR); - writel(~0, base + VIC_INT_SOFT_CLEAR); + writel(0, vic_base + VIC_INT_SELECT); + writel(0, vic_base + VIC_INT_ENABLE); + writel(~0, vic_base + VIC_INT_ENABLE_CLEAR); + writel(0, vic_base + VIC_IRQ_STATUS); + writel(0, vic_base + VIC_ITCR); + writel(~0, vic_base + VIC_INT_SOFT_CLEAR); /* * Make sure we clear all existing interrupts */ - writel(0, base + VIC_VECT_ADDR); + writel(0, vic_base + VIC_VECT_ADDR); for (i = 0; i < 19; i++) { unsigned int value; - value = readl(base + VIC_VECT_ADDR); - writel(value, base + VIC_VECT_ADDR); + value = readl(vic_base + VIC_VECT_ADDR); + writel(value, vic_base + VIC_VECT_ADDR); } for (i = 0; i < 16; i++) { - void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4); + void __iomem *reg = vic_base + VIC_VECT_CNTL0 + (i * 4); writel(VIC_VECT_CNTL_ENABLE | i, reg); } - writel(32, base + VIC_DEF_VECT_ADDR); + writel(32, vic_base + VIC_DEF_VECT_ADDR); for (i = 0; i < 32; i++) { - unsigned int irq = irq_start + i; + unsigned int irq = IRQ_VIC_START + i; set_irq_chip(irq, &vic_chip); - set_irq_chipdata(irq, base); if (vic_sources & (1 << i)) { set_irq_handler(irq, do_level_IRQ); diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index 9e1c1cceb..1fe73d198 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig @@ -379,7 +379,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set CONFIG_MTD_AT91_DATAFLASH=y -# CONFIG_MTD_AT91_DATAFLASH_CARD is not set +CONFIG_MTD_AT91_DATAFLASH_CARD=y # # NAND Flash Device Drivers diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index 6e0805a97..b7d934cdb 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig @@ -370,7 +370,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set CONFIG_MTD_AT91_DATAFLASH=y -# CONFIG_MTD_AT91_DATAFLASH_CARD is not set +CONFIG_MTD_AT91_DATAFLASH_CARD=y # # NAND Flash Device Drivers diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig index 074c47a4f..c9aa878e6 100644 --- a/arch/arm/configs/collie_defconfig +++ b/arch/arm/configs/collie_defconfig @@ -1,21 +1,21 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc1 -# Fri Apr 14 19:09:52 2006 +# Linux kernel version: 2.6.14-rc3 +# Sun Oct 9 16:55:14 2005 # CONFIG_ARM=y CONFIG_MMU=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_MTD_XIP=y -CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 # @@ -23,58 +23,45 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set +CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y -# CONFIG_BASE_FULL is not set +CONFIG_BASE_FULL=y CONFIG_FUTEX=y -# CONFIG_EPOLL is not set +CONFIG_EPOLL=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y -# CONFIG_SLAB is not set -CONFIG_DOUBLEFAULT=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 -CONFIG_SLOB=y -CONFIG_OBSOLETE_INTERMODULE=y +CONFIG_BASE_SMALL=0 # # Loadable module support # -# CONFIG_MODULES is not set - -# -# Block layer -# -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y # # System Type @@ -83,13 +70,11 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -99,11 +84,9 @@ CONFIG_ARCH_SA1100=y # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_AT91RM9200 is not set # # SA11x0 Implementations @@ -145,32 +128,20 @@ CONFIG_SHARP_SCOOP=y # Bus support # CONFIG_ISA=y +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support # -CONFIG_PCCARD=y -CONFIG_PCMCIA_DEBUG=y -CONFIG_PCMCIA=y -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y - -# -# PC-card bridges -# -# CONFIG_I82365 is not set -# CONFIG_TCIC is not set -CONFIG_PCMCIA_SA1100=y +# CONFIG_PCCARD is not set # # Kernel Features # -# CONFIG_PREEMPT is not set +# CONFIG_SMP is not set +CONFIG_PREEMPT=y # CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set CONFIG_ARCH_DISCONTIGMEM_ENABLE=y -CONFIG_NODES_SHIFT=2 CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_FLATMEM_MANUAL is not set CONFIG_DISCONTIGMEM_MANUAL=y @@ -179,7 +150,6 @@ CONFIG_DISCONTIGMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 # CONFIG_LEDS is not set CONFIG_ALIGNMENT_TRAP=y @@ -188,7 +158,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="noinitrd root=/dev/mtdblock2 rootfstype=jffs2 fbcon=rotate:1" +CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug" # CONFIG_XIP_KERNEL is not set # @@ -211,16 +181,14 @@ CONFIG_FPE_NWFPE=y # Userspace binary formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m # CONFIG_ARTHUR is not set # # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y -# CONFIG_PM_DEBUG is not set CONFIG_APM=y # @@ -231,7 +199,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -244,19 +211,16 @@ CONFIG_IP_FIB_HASH=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set +CONFIG_SYN_COOKIES=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set # @@ -268,11 +232,6 @@ CONFIG_TCP_CONG_BIC=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -285,11 +244,8 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -309,14 +265,9 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y +CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - # # Memory Technology Devices (MTD) # @@ -336,49 +287,32 @@ 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 # # RAM/ROM/Flash chip drivers # -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -# CONFIG_MTD_CFI_I1 is not set -# CONFIG_MTD_CFI_I2 is not set -CONFIG_MTD_CFI_I4=y +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_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set CONFIG_MTD_OBSOLETE_CHIPS=y CONFIG_MTD_SHARP=y -# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -CONFIG_MTD_SA1100=y -# CONFIG_MTD_IMPA7 is not set # CONFIG_MTD_PLATRAM is not set # @@ -387,6 +321,7 @@ CONFIG_MTD_SA1100=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -401,11 +336,6 @@ CONFIG_MTD_SA1100=y # # CONFIG_MTD_NAND is not set -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - # # Parallel port support # @@ -419,6 +349,7 @@ CONFIG_MTD_SA1100=y # # Block devices # +# CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set @@ -428,35 +359,20 @@ CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y # -# Please see Documentation/ide.txt for help/info on IDE drives +# IO Schedulers # -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -CONFIG_BLK_DEV_IDECS=y -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_ATA_OVER_ETH=m # -# IDE chipset support/bugfixes +# ATA/ATAPI/MFM/RLL support # -CONFIG_IDE_GENERIC=y -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set +# CONFIG_IDE is not set # # SCSI device support @@ -486,39 +402,6 @@ CONFIG_IDE_GENERIC=y # Network device support # # CONFIG_NETDEVICES is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_MPPE is not set -# CONFIG_PPPOE is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -541,7 +424,7 @@ CONFIG_INPUT_TSDEV=y CONFIG_INPUT_TSDEV_SCREEN_X=240 CONFIG_INPUT_TSDEV_SCREEN_Y=320 CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set +CONFIG_INPUT_EVBUG=y # # Input Device Drivers @@ -555,11 +438,7 @@ CONFIG_KEYBOARD_LOCOMO=y # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set # @@ -582,16 +461,7 @@ CONFIG_HW_CONSOLE=y # # Serial drivers # -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_CONSOLE is not set -CONFIG_SERIAL_8250_CS=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_SHARE_IRQ is not set -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support @@ -613,48 +483,94 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # # Ftape, the floppy tape device driver # - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=m +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set # -# SPI support +# I2C Hardware Bus support # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set # -# Dallas's 1-wire bus +# Miscellaneous I2C Chip support # -# CONFIG_W1 is not set +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # # Hardware Monitoring support # -# CONFIG_HWMON is not set +CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices @@ -663,33 +579,42 @@ CONFIG_UNIX98_PTYS=y # # Multimedia Capabilities Port drivers # -CONFIG_MCP=y -CONFIG_MCP_SA11X0=y -CONFIG_MCP_UCB1200=y -CONFIG_MCP_UCB1200_TS=y +# CONFIG_MCP_SA11X0 is not set # -# LED devices +# Multimedia devices # -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y +CONFIG_VIDEO_DEV=m # -# LED drivers +# Video For Linux # -CONFIG_LEDS_LOCOMO=y # -# LED Triggers +# Video Adapters # -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_IDE_DISK=y +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_OVCAMCHIP is not set # -# Multimedia devices +# Radio Adapters # -# CONFIG_VIDEO_DEV is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set # # Digital Video Broadcasting Devices @@ -703,8 +628,8 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MACMODES is not set -# CONFIG_FB_FIRMWARE_EDID is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set CONFIG_FB_SA1100=y @@ -718,15 +643,14 @@ CONFIG_FB_SA1100=y # CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y -# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x8=y # CONFIG_FONT_8x16 is not set # CONFIG_FONT_6x11 is not set # CONFIG_FONT_7x14 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set -CONFIG_FONT_MINI_4x6=y +# CONFIG_FONT_MINI_4x6 is not set # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set @@ -735,11 +659,7 @@ CONFIG_FONT_MINI_4x6=y # Logo configuration # # CONFIG_LOGO is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_DEVICE=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_LCD_DEVICE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -751,42 +671,44 @@ CONFIG_LCD_DEVICE=y # CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - # # USB Gadget Support # -# CONFIG_USB_GADGET is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set # # MMC/SD Card support # # CONFIG_MMC is not set -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - # # File systems # -# CONFIG_EXT2_FS is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set +CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y -# CONFIG_INOTIFY is not set +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set @@ -803,7 +725,7 @@ CONFIG_ROMFS_FS=y # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set +CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" @@ -817,7 +739,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -833,12 +755,11 @@ CONFIG_RAMFS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set +CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -868,7 +789,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" -CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -892,7 +813,7 @@ CONFIG_NLS_CODEPAGE_437=y # 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_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -905,7 +826,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +CONFIG_NLS_UTF8=m # # Profiling support @@ -916,23 +837,20 @@ CONFIG_NLS_ISO8859_1=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DETECT_SOFTLOCKUP is not set +CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y @@ -956,7 +874,7 @@ CONFIG_DEBUG_ERRORS=y # # Library routines # -CONFIG_CRC_CCITT=y +# CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/enp2611_defconfig similarity index 65% rename from arch/arm/configs/ixp23xx_defconfig rename to arch/arm/configs/enp2611_defconfig index 9ce898a6c..5fdaf3ce9 100644 --- a/arch/arm/configs/ixp23xx_defconfig +++ b/arch/arm/configs/enp2611_defconfig @@ -1,19 +1,19 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc2 -# Wed Apr 19 21:13:50 2006 +# Linux kernel version: 2.6.14-git13 +# Thu Nov 10 15:12:48 2005 # CONFIG_ARM=y CONFIG_MMU=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -29,28 +29,27 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_SLAB=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y # # Loadable module support @@ -58,6 +57,7 @@ CONFIG_OBSOLETE_INTERMODULE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -65,7 +65,6 @@ CONFIG_KMOD=y # # Block layer # -# CONFIG_BLK_DEV_IO_TRACE is not set # # IO Schedulers @@ -87,13 +86,11 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -CONFIG_ARCH_IXP23XX=y +CONFIG_ARCH_IXP2000=y # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -107,41 +104,45 @@ CONFIG_ARCH_IXP23XX=y # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_AT91RM9200 is not set CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y # -# Intel IXP23xx Implementation Options +# Intel IXP2400/2800 Implementation Options # # -# IXP23xx Platforms +# IXP2400/2800 Platforms # -CONFIG_MACH_ESPRESSO=y -CONFIG_MACH_IXDP2351=y -CONFIG_MACH_ROADRUNNER=y +CONFIG_ARCH_ENP2611=y +# CONFIG_ARCH_IXDP2400 is not set +# CONFIG_ARCH_IXDP2800 is not set +# CONFIG_ARCH_IXDP2401 is not set +# CONFIG_ARCH_IXDP2801 is not set +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set # # Processor Type # CONFIG_CPU_32=y -CONFIG_CPU_XSC3=y +CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WBI=y -CONFIG_IO_36=y # # Processor Features # # CONFIG_ARM_THUMB is not set CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y # # Bus support # +CONFIG_ISA_DMA_API=y CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_DEBUG is not set # @@ -154,8 +155,6 @@ CONFIG_PCI=y # # CONFIG_PREEMPT is not set # CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -172,7 +171,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp" +CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0" # CONFIG_XIP_KERNEL is not set # @@ -198,7 +197,6 @@ CONFIG_BINFMT_ELF=y # Power management options # # CONFIG_PM is not set -# CONFIG_APM is not set # # Networking @@ -208,7 +206,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -228,15 +225,12 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set # @@ -248,11 +242,6 @@ CONFIG_TCP_CONG_BIC=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -270,6 +259,7 @@ CONFIG_TCP_CONG_BIC=y # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -292,11 +282,6 @@ CONFIG_STANDALONE=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - # # Memory Technology Devices (MTD) # @@ -345,17 +330,15 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access # CONFIG_MTD_COMPLEX_MAPPINGS=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x0 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y # CONFIG_MTD_PCI is not set # CONFIG_MTD_PLATRAM is not set @@ -366,6 +349,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -406,7 +390,6 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 @@ -414,126 +397,11 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_SL82C105 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -CONFIG_BLK_DEV_SIIMAGE=y -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - # # SCSI device support # # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -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 - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI is not set # # Multi-device support (RAID and LVM) @@ -544,9 +412,6 @@ CONFIG_BLK_DEV_SD=y # Fusion MPT device support # # CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -600,10 +465,9 @@ CONFIG_NET_PCI=y # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set -# CONFIG_CS89x0 is not set # CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -CONFIG_E100=y +CONFIG_EEPRO100=y +# CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -620,16 +484,13 @@ CONFIG_E100=y # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -CONFIG_E1000=y -CONFIG_E1000_NAPI=y -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set # CONFIG_SIS190 is not set # CONFIG_SKGE is not set -# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set @@ -680,7 +541,6 @@ CONFIG_DLCI_MAX=8 # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -734,9 +594,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=2 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -764,18 +622,15 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP2000_WATCHDOG=y # # PCI-based Watchdog Cards # # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -816,10 +671,12 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set # CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_IXP2000=y # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -838,23 +695,14 @@ CONFIG_SENSORS_EEPROM=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - # # Hardware Monitoring support # @@ -868,7 +716,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -890,7 +737,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set @@ -903,16 +749,7 @@ CONFIG_HWMON=y # # -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers +# Multimedia Capabilities Port drivers # # @@ -924,7 +761,6 @@ CONFIG_HWMON=y # Digital Video Broadcasting Devices # # CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set # # Graphics support @@ -941,126 +777,12 @@ CONFIG_HWMON=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_UHCI_HCD=y -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_USB is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set - -# -# USB DSL modem support -# - # # USB Gadget Support # @@ -1071,12 +793,6 @@ CONFIG_USB_MON=y # # CONFIG_MMC is not set -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - # # File systems # @@ -1096,7 +812,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -1115,10 +830,8 @@ CONFIG_DNOTIFY=y # # DOS/FAT/NT Filesystems # -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +# CONFIG_MSDOS_FS is not set # CONFIG_VFAT_FS is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 # CONFIG_NTFS_FS is not set # @@ -1129,7 +842,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -1198,52 +911,12 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # # Native Language Support # -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +# CONFIG_NLS is not set # # Profiling support @@ -1254,13 +927,12 @@ CONFIG_NLS_CODEPAGE_437=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1269,8 +941,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixdp2400_defconfig similarity index 92% rename from arch/arm/configs/ixp2000_defconfig rename to arch/arm/configs/ixdp2400_defconfig index e6f3e4873..c67fc449a 100644 --- a/arch/arm/configs/ixp2000_defconfig +++ b/arch/arm/configs/ixdp2400_defconfig @@ -1,19 +1,19 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc2 -# Wed Apr 19 21:12:49 2006 +# Linux kernel version: 2.6.14-git13 +# Thu Nov 10 15:14:13 2005 # CONFIG_ARM=y CONFIG_MMU=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -29,28 +29,27 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_EMBEDDED=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_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_SLAB=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y # # Loadable module support @@ -58,6 +57,7 @@ CONFIG_OBSOLETE_INTERMODULE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -65,7 +65,6 @@ CONFIG_KMOD=y # # Block layer # -# CONFIG_BLK_DEV_IO_TRACE is not set # # IO Schedulers @@ -87,13 +86,11 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set CONFIG_ARCH_IXP2000=y -# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -107,7 +104,6 @@ CONFIG_ARCH_IXP2000=y # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_AT91RM9200 is not set CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y # @@ -117,14 +113,12 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y # # IXP2400/2800 Platforms # -CONFIG_ARCH_ENP2611=y +# CONFIG_ARCH_ENP2611 is not set CONFIG_ARCH_IXDP2400=y -CONFIG_ARCH_IXDP2800=y +# CONFIG_ARCH_IXDP2800 is not set CONFIG_ARCH_IXDP2X00=y -CONFIG_ARCH_IXDP2401=y -CONFIG_ARCH_IXDP2801=y -CONFIG_MACH_IXDP28X5=y -CONFIG_ARCH_IXDP2X01=y +# CONFIG_ARCH_IXDP2401 is not set +# CONFIG_ARCH_IXDP2801 is not set # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set # @@ -147,7 +141,9 @@ CONFIG_XSCALE_PMU=y # # Bus support # +CONFIG_ISA_DMA_API=y CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_DEBUG is not set # @@ -160,8 +156,6 @@ CONFIG_PCI=y # # CONFIG_PREEMPT is not set # CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -204,7 +198,6 @@ CONFIG_BINFMT_ELF=y # Power management options # # CONFIG_PM is not set -# CONFIG_APM is not set # # Networking @@ -214,7 +207,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -234,15 +226,12 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set # @@ -254,11 +243,6 @@ CONFIG_TCP_CONG_BIC=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -276,6 +260,7 @@ CONFIG_TCP_CONG_BIC=y # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -298,11 +283,6 @@ CONFIG_STANDALONE=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - # # Memory Technology Devices (MTD) # @@ -351,7 +331,7 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access @@ -370,6 +350,7 @@ CONFIG_MTD_IXP2000=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -485,7 +466,6 @@ CONFIG_NET_PCI=y # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set -CONFIG_CS89x0=y # CONFIG_DGRS is not set CONFIG_EEPRO100=y # CONFIG_E100 is not set @@ -506,14 +486,12 @@ CONFIG_EEPRO100=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set -CONFIG_ENP2611_MSF_NET=y # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set # CONFIG_SIS190 is not set # CONFIG_SKGE is not set -# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set @@ -617,9 +595,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=3 -CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_8250_NR_UARTS=1 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -655,6 +631,7 @@ CONFIG_IXP2000_WATCHDOG=y # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -700,6 +677,7 @@ CONFIG_I2C_IXP2000=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -718,23 +696,14 @@ CONFIG_SENSORS_EEPROM=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - # # Hardware Monitoring support # @@ -748,7 +717,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -770,7 +738,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set @@ -783,16 +750,7 @@ CONFIG_HWMON=y # # -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers +# Multimedia Capabilities Port drivers # # @@ -820,7 +778,6 @@ CONFIG_HWMON=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB is not set # @@ -837,12 +794,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # CONFIG_MMC is not set -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - # # File systems # @@ -862,7 +813,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -893,7 +843,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -962,7 +912,6 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -979,13 +928,12 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -994,8 +942,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ixdp2401_defconfig similarity index 59% rename from arch/arm/configs/ep93xx_defconfig rename to arch/arm/configs/ixdp2401_defconfig index b69e88bbc..60d66e82c 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ixdp2401_defconfig @@ -1,19 +1,19 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc2 -# Wed Apr 19 21:21:01 2006 +# Linux kernel version: 2.6.14-git13 +# Thu Nov 10 15:14:50 2005 # CONFIG_ARM=y CONFIG_MMU=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -25,39 +25,39 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_RELAY is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_SLAB=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y # # Loadable module support # CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -65,20 +65,19 @@ CONFIG_KMOD=y # # Block layer # -# CONFIG_BLK_DEV_IO_TRACE is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_DEFAULT_IOSCHED="anticipatory" # # System Type @@ -87,13 +86,11 @@ CONFIG_DEFAULT_IOSCHED="deadline" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -CONFIG_ARCH_EP93XX=y # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set +CONFIG_ARCH_IXP2000=y # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -107,43 +104,47 @@ CONFIG_ARCH_EP93XX=y # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_AT91RM9200 is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y # -# Cirrus EP93xx Implementation Options +# Intel IXP2400/2800 Implementation Options # # -# EP93xx Platforms +# IXP2400/2800 Platforms # -CONFIG_MACH_GESBC9312=y -CONFIG_MACH_TS72XX=y +# CONFIG_ARCH_ENP2611 is not set +# CONFIG_ARCH_IXDP2400 is not set +# CONFIG_ARCH_IXDP2800 is not set +CONFIG_ARCH_IXDP2401=y +# CONFIG_ARCH_IXDP2801 is not set +CONFIG_ARCH_IXDP2X01=y +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set # # Processor Type # CONFIG_CPU_32=y -CONFIG_CPU_ARM920T=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4T=y -CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_V4WB=y CONFIG_CPU_TLB_V4WBI=y # # Processor Features # -CONFIG_ARM_THUMB=y -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_WRITETHROUGH is not set -CONFIG_ARM_VIC=y +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y # # Bus support # -CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support @@ -155,8 +156,6 @@ CONFIG_ARM_AMBA=y # # CONFIG_PREEMPT is not set # CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -173,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyAM0,115200 root=/dev/nfs ip=bootp" +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0" # CONFIG_XIP_KERNEL is not set # @@ -199,7 +198,6 @@ CONFIG_BINFMT_ELF=y # Power management options # # CONFIG_PM is not set -# CONFIG_APM is not set # # Networking @@ -209,13 +207,10 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -CONFIG_NET_KEY=y +# CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set @@ -231,15 +226,12 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set # @@ -251,11 +243,6 @@ CONFIG_TCP_CONG_BIC=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -273,6 +260,7 @@ CONFIG_TCP_CONG_BIC=y # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -291,26 +279,21 @@ CONFIG_TCP_CONG_BIC=y # Generic Driver Options # CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - # # Memory Technology Devices (MTD) # CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y +# CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y # CONFIG_MTD_CMDLINE_PARTS is not set # CONFIG_MTD_AFS_PARTS is not set @@ -330,11 +313,7 @@ CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y # CONFIG_MTD_JEDECPROBE is not set CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_GEOMETRY is not set +# 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 @@ -345,33 +324,33 @@ 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_OTP is not set CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_STAA=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set -CONFIG_MTD_ROM=y +# CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access # -# 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=1 +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y +# CONFIG_MTD_PCI is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # +# CONFIG_MTD_PMC551 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -384,11 +363,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # # NAND Flash Device Drivers # -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_VERIFY_WRITE=y -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND is not set # # OneNAND Flash Device Drivers @@ -407,12 +382,19 @@ CONFIG_MTD_NAND_IDS=y # # Block devices # +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -420,40 +402,7 @@ CONFIG_MTD_NAND_IDS=y # SCSI device support # # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR 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 - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI is not set # # Multi-device support (RAID and LVM) @@ -468,20 +417,27 @@ CONFIG_BLK_DEV_SD=y # # IEEE 1394 (FireWire) support # +# CONFIG_IEEE1394 is not set # # I2O device support # +# CONFIG_I2O is not set # # Network device support # CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set +CONFIG_DUMMY=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + # # PHY device support # @@ -492,20 +448,67 @@ CONFIG_NETDEVICES=y # CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +CONFIG_CS89x0=y +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + # # Ethernet (1000 Mbit) # +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -515,7 +518,29 @@ CONFIG_MII=y # # Wan interfaces # -# CONFIG_WAN is not set +CONFIG_WAN=y +# CONFIG_DSCC4 is not set +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=y +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -531,7 +556,28 @@ CONFIG_MII=y # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports @@ -548,18 +594,20 @@ CONFIG_MII=y # # Serial drivers # -# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=3 +# CONFIG_SERIAL_8250_EXTENDED is not set # # Non-8250 serial port support # -CONFIG_SERIAL_AMBA_PL010=y -CONFIG_SERIAL_AMBA_PL010_CONSOLE=y -# CONFIG_SERIAL_AMBA_PL011 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # # IPMI @@ -576,19 +624,23 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_EP93XX_WATCHDOG=y +CONFIG_IXP2000_WATCHDOG=y # -# USB-based Watchdog Cards +# PCI-based Watchdog Cards # -# CONFIG_USBPCWATCHDOG is not set +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set # # Ftape, the floppy tape device driver # +# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # @@ -613,8 +665,27 @@ CONFIG_I2C_ALGOBIT=y # # I2C Hardware Bus support # +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_IXP2000=y +# CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set # CONFIG_I2C_PCA_ISA is not set # @@ -622,26 +693,17 @@ CONFIG_I2C_ALGOBIT=y # # CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set +CONFIG_SENSORS_EEPROM=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set -CONFIG_I2C_DEBUG_CORE=y -CONFIG_I2C_DEBUG_ALGO=y -CONFIG_I2C_DEBUG_BUS=y -CONFIG_I2C_DEBUG_CHIP=y - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set +# CONFIG_RTC_X1205_I2C 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 # # Hardware Monitoring support @@ -656,7 +718,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -674,8 +735,10 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set @@ -688,16 +751,7 @@ CONFIG_HWMON=y # # -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers +# Multimedia Capabilities Port drivers # # @@ -709,7 +763,6 @@ CONFIG_HWMON=y # Digital Video Broadcasting Devices # # CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set # # Graphics support @@ -725,137 +778,13 @@ CONFIG_HWMON=y # USB support # CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=y -CONFIG_USB_DEBUG=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -CONFIG_USB_DYNAMIC_MINORS=y -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=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_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -CONFIG_USB_RTL8150=y -# CONFIG_USB_USBNET is not set -# CONFIG_USB_MON is not set - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=y -CONFIG_USB_SERIAL_CONSOLE=y -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_ANYDATA is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP2101 is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_FUNSOFT is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -CONFIG_USB_SERIAL_PL2303=y -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE 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_OMNINET is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - # # USB Gadget Support # @@ -866,47 +795,25 @@ CONFIG_USB_SERIAL_PL2303=y # # CONFIG_MMC is not set -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y - -# -# RTC drivers -# -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -CONFIG_RTC_DRV_M48T86=y -CONFIG_RTC_DRV_EP93XX=y -# CONFIG_RTC_DRV_TEST is not set - # # File systems # CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set +CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -925,11 +832,8 @@ CONFIG_DNOTIFY=y # # DOS/FAT/NT Filesystems # -CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_VFAT_FS is not set # CONFIG_NTFS_FS is not set # @@ -940,7 +844,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set +# CONFIG_RELAYFS_FS is not set # # Miscellaneous filesystems @@ -1009,52 +913,12 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # # Native Language Support # -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +# CONFIG_NLS is not set # # Profiling support @@ -1065,15 +929,13 @@ CONFIG_NLS_ISO8859_1=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SLAB_LEAK is not set -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y @@ -1081,11 +943,9 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -CONFIG_DEBUG_WAITQ=y +# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set @@ -1111,6 +971,6 @@ CONFIG_DEBUG_LL=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y -CONFIG_LIBCRC32C=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig new file mode 100644 index 000000000..424812381 --- /dev/null +++ b/arch/arm/configs/ixdp2800_defconfig @@ -0,0 +1,975 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.14-git13 +# Thu Nov 10 15:14:56 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_IXP2000=y +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP2400/2800 Implementation Options +# + +# +# IXP2400/2800 Platforms +# +# CONFIG_ARCH_ENP2611 is not set +# CONFIG_ARCH_IXDP2400 is not set +CONFIG_ARCH_IXDP2800=y +CONFIG_ARCH_IXDP2X00=y +# CONFIG_ARCH_IXDP2401 is not set +# CONFIG_ARCH_IXDP2801 is not set +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_ISA_DMA_API=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=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 + +# +# 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 is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD 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 + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_DSCC4 is not set +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=y +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT 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=1 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP2000_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_IXP2000=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C 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 + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# 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_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig new file mode 100644 index 000000000..f54f3dcc5 --- /dev/null +++ b/arch/arm/configs/ixdp2801_defconfig @@ -0,0 +1,976 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.14-git13 +# Thu Nov 10 15:15:03 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_IXP2000=y +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP2400/2800 Implementation Options +# + +# +# IXP2400/2800 Platforms +# +# CONFIG_ARCH_ENP2611 is not set +# CONFIG_ARCH_IXDP2400 is not set +# CONFIG_ARCH_IXDP2800 is not set +# CONFIG_ARCH_IXDP2401 is not set +CONFIG_ARCH_IXDP2801=y +CONFIG_ARCH_IXDP2X01=y +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_ISA_DMA_API=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=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 + +# +# 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 is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD 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 + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +CONFIG_CS89x0=y +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_DSCC4 is not set +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=y +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT 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=3 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP2000_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_IXP2000=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C 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 + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# 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_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 3cec29d56..6695b07cf 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Mon Mar 20 20:36:02 2006 +# Linux kernel version: 2.6.16-rc2 +# Mon Feb 6 11:17:23 2006 # CONFIG_ARM=y CONFIG_MMU=y @@ -12,6 +12,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -86,7 +87,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set @@ -111,7 +111,6 @@ CONFIG_ARCH_S3C2410=y # S3C24XX Implementations # CONFIG_MACH_ANUBIS=y -CONFIG_MACH_OSIRIS=y CONFIG_ARCH_BAST=y CONFIG_BAST_PC104_IRQ=y CONFIG_ARCH_H1940=y @@ -176,7 +175,6 @@ CONFIG_ISA=y # # CONFIG_PREEMPT is not set # CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=200 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y @@ -232,7 +230,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set @@ -367,6 +364,7 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_ROM=y # CONFIG_MTD_ABSENT is not set # CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access @@ -433,7 +431,6 @@ CONFIG_PARPORT_1284=y CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 @@ -626,6 +623,7 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set @@ -688,11 +686,6 @@ CONFIG_S3C2410_WATCHDOG=y # CONFIG_PCWATCHDOG is not set # CONFIG_MIXCOMWD is not set # CONFIG_WDT is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set CONFIG_S3C2410_RTC=y @@ -757,11 +750,6 @@ CONFIG_SENSORS_EEPROM=m # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - # # Hardware Monitoring support # @@ -775,7 +763,6 @@ CONFIG_HWMON_VID=m # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -863,138 +850,16 @@ CONFIG_FONT_8x16=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_USB is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -# -# may also be needed; see USB_STORAGE Help for more information -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set - -# -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - # # USB Gadget Support # # CONFIG_USB_GADGET is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA2XX is not set -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -# CONFIG_USB_ZERO is not set -# CONFIG_USB_ETH is not set -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FILE_STORAGE is not set -# CONFIG_USB_G_SERIAL is not set # # MMC/SD Card support diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index 96b7a7762..2687a225a 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -1,55 +1,50 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc3 -# Mon May 8 20:15:57 2006 +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:20:50 2005 # CONFIG_ARM=y CONFIG_MMU=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_GENERIC_IOMAP=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_SLAB=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y # # Loadable module support @@ -57,28 +52,11 @@ CONFIG_OBSOLETE_INTERMODULE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y -# -# Block layer -# -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - # # System Type # @@ -86,13 +64,11 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -102,17 +78,14 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set CONFIG_ARCH_VERSATILE=y -# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_AT91RM9200 is not set # # Versatile platform type # CONFIG_ARCH_VERSATILE_PB=y -CONFIG_MACH_VERSATILE_AB=y +# CONFIG_MACH_VERSATILE_AB is not set # # Processor Type @@ -133,14 +106,12 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_DCACHE_WRITETHROUGH is not set # CONFIG_CPU_CACHE_ROUND_ROBIN is not set -CONFIG_ARM_VIC=y CONFIG_ICST307=y # # Bus support # CONFIG_ARM_AMBA=y -# CONFIG_PCI is not set # # PCCARD (PCMCIA/CardBus) support @@ -151,18 +122,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 CONFIG_LEDS=y CONFIG_LEDS_TIMER=y CONFIG_LEDS_CPU=y @@ -186,7 +145,7 @@ CONFIG_CMDLINE="root=1f03 mem=32M" CONFIG_FPE_NWFPE=y # CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set -CONFIG_VFP=y +# CONFIG_VFP is not set # # Userspace binary formats @@ -200,91 +159,8 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y -# CONFIG_PM_DEBUG is not set # CONFIG_APM is not set -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE 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_DIAG is not set -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_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_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - # # Device Drivers # @@ -297,11 +173,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - # # Memory Technology Devices (MTD) # @@ -321,7 +192,6 @@ 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 # # RAM/ROM/Flash chip drivers @@ -344,7 +214,6 @@ 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_OTP is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set @@ -352,7 +221,7 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access @@ -360,7 +229,7 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set CONFIG_MTD_ARM_INTEGRATOR=y -# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_EDB7312 is not set # # Self-contained MTD device drivers @@ -368,6 +237,7 @@ CONFIG_MTD_ARM_INTEGRATOR=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -382,11 +252,6 @@ CONFIG_MTD_ARM_INTEGRATOR=y # # CONFIG_MTD_NAND is not set -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - # # Parallel port support # @@ -399,6 +264,7 @@ CONFIG_MTD_ARM_INTEGRATOR=y # # Block devices # +# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -406,13 +272,21 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # # SCSI device support # -# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # @@ -423,7 +297,6 @@ CONFIG_BLK_DEV_INITRD=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -434,26 +307,83 @@ CONFIG_BLK_DEV_INITRD=y # # -# Network device support +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE 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_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing # +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# -# PHY device support -# -# CONFIG_PHYLIB is not set - # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y -# CONFIG_DM9000 is not set # # Ethernet (1000 Mbit) @@ -480,8 +410,6 @@ CONFIG_SMC91X=y # CONFIG_SLIP is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -531,6 +459,7 @@ CONFIG_SERIO_AMBAKMI=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -545,16 +474,17 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=m CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_MULTIPORT=y CONFIG_SERIAL_8250_RSA=y # # Non-8250 serial port support # +# CONFIG_SERIAL_AMBA_PL010 is not set CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_CORE=y @@ -573,19 +503,20 @@ CONFIG_LEGACY_PTY_COUNT=16 # # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # # Ftape, the floppy tape device driver # +# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -603,59 +534,59 @@ CONFIG_I2C_ALGOBIT=y # # I2C Hardware Bus support # +# CONFIG_I2C_ISA is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_STUB is not set # CONFIG_I2C_PCA_ISA is not set # -# Miscellaneous I2C Chip support +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set CONFIG_SENSORS_EEPROM=m # CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_RTC8564 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - # # Misc devices # -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - # # Multimedia devices # @@ -673,31 +604,27 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_FIRMWARE_EDID is not set +CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set CONFIG_FB_ARMCLCD=y -# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # +# CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set # CONFIG_FONT_8x16 is not set # CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set # CONFIG_FONT_PEARL_8x8 is not set CONFIG_FONT_ACORN_8x8=y # CONFIG_FONT_MINI_4x6 is not set # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set # # Logo configuration @@ -720,18 +647,12 @@ CONFIG_SND_PCM=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set # # Generic devices # -CONFIG_SND_AC97_CODEC=m -CONFIG_SND_AC97_BUS=m # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set @@ -740,7 +661,6 @@ CONFIG_SND_AC97_BUS=m # # ALSA ARM devices # -CONFIG_SND_ARMAACI=m # # Open Sound System @@ -752,13 +672,8 @@ CONFIG_SND_ARMAACI=m # CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - # # USB Gadget Support # @@ -772,32 +687,26 @@ CONFIG_MMC=y CONFIG_MMC_BLOCK=y CONFIG_MMC_ARMMMCI=m -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS 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_JBD is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set CONFIG_MINIX_FS=y CONFIG_ROMFS_FS=y -# CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -820,10 +729,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -838,8 +748,8 @@ CONFIG_RAMFS=y # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -856,19 +766,16 @@ CONFIG_CRAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -877,7 +784,6 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -897,7 +803,6 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -953,24 +858,18 @@ CONFIG_NLS_ISO8859_1=m # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y @@ -996,7 +895,6 @@ CONFIG_DEBUG_LL=y # Library routines # # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index a601b8b55..2ce0e3a27 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -29,7 +29,7 @@ ifneq ($(CONFIG_ARCH_EBSA110),y) obj-y += io.o endif -head-y := head$(MMUEXT).o +head-y := head.o obj-$(CONFIG_DEBUG_LL) += debug.o extra-y := $(head-y) init_task.o vmlinux.lds diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index 2bed290fe..766b6c05c 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c @@ -357,8 +357,10 @@ static int apm_open(struct inode * inode, struct file * filp) { struct apm_user *as; - as = (struct apm_user *)kzalloc(sizeof(*as), GFP_KERNEL); + as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL); if (as) { + memset(as, 0, sizeof(*as)); + /* * XXX - this is a tiny bit broken, when we consider BSD * process accounting. If the device is opened by root, we diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index c49b5d4d7..1574941eb 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -100,11 +100,23 @@ EXPORT_SYMBOL(__raw_writesl); #endif /* string / mem functions */ +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(__memzero); @@ -178,6 +190,8 @@ EXPORT_SYMBOL(_find_next_bit_be); /* syscalls */ EXPORT_SYMBOL(sys_write); +EXPORT_SYMBOL(sys_read); EXPORT_SYMBOL(sys_lseek); +EXPORT_SYMBOL(sys_open); EXPORT_SYMBOL(sys_exit); EXPORT_SYMBOL(sys_wait4); diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 396efba9b..b324dcac1 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -95,13 +95,5 @@ int main(void) DEFINE(SYS_ERROR0, 0x9f0000); BLANK(); DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); - DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr)); - DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name)); - DEFINE(MACHINFO_PHYSIO, offsetof(struct machine_desc, phys_io)); - DEFINE(MACHINFO_PGOFFIO, offsetof(struct machine_desc, io_pg_offst)); - BLANK(); - DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list)); - DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush)); - DEFINE(PROCINFO_MMUFLAGS, offsetof(struct proc_info_list, __cpu_mmu_flags)); return 0; } diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index de606dfa8..c4923fac8 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -540,10 +540,12 @@ static void __init pcibios_init_hw(struct hw_pci *hw) int nr, busnr; for (nr = busnr = 0; nr < hw->nr_controllers; nr++) { - sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL); + sys = kmalloc(sizeof(struct pci_sys_data), GFP_KERNEL); if (!sys) panic("PCI: unable to allocate sys data!"); + memset(sys, 0, sizeof(struct pci_sys_data)); + sys->hw = hw; sys->busnr = busnr; sys->swizzle = hw->swizzle; diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index da280bae3..caaa919ab 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -11,6 +11,7 @@ */ #include #include +#include .text diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c index 0a3e9ad29..03532769a 100644 --- a/arch/arm/kernel/dma-isa.c +++ b/arch/arm/kernel/dma-isa.c @@ -143,23 +143,12 @@ static struct dma_ops isa_dma_ops = { .residue = isa_get_dma_residue, }; -static struct resource dma_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x000f -}, { - .name = "dma low page", - .start = 0x0080, - .end = 0x008f -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df -}, { - .name = "dma high page", - .start = 0x0480, - .end = 0x048f -} }; +static struct resource dma_resources[] = { + { "dma1", 0x0000, 0x000f }, + { "dma low page", 0x0080, 0x008f }, + { "dma2", 0x00c0, 0x00df }, + { "dma high page", 0x0480, 0x048f } +}; void __init isa_init_dma(dma_t *dma) { diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 00aa225e8..74ea29c32 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -807,12 +807,14 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot) unsigned long base; int i; - ec = kzalloc(sizeof(ecard_t), GFP_KERNEL); + ec = kmalloc(sizeof(ecard_t), GFP_KERNEL); if (!ec) { ec = ERR_PTR(-ENOMEM); goto nomem; } + memset(ec, 0, sizeof(ecard_t)); + ec->slot_no = slot; ec->type = type; ec->irq = NO_IRQ; diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index ab8e600c1..ec48d70c6 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -484,6 +484,7 @@ call_fpe: movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) bcs iwmmxt_task_enable #endif + enable_irq add pc, pc, r8, lsr #6 mov r0, r0 @@ -510,7 +511,6 @@ call_fpe: mov pc, lr @ CP#15 (Control) do_fpe: - enable_irq ldr r4, .LCfp add r10, r10, #TI_FPSTATE @ r10 = workspace ldr pc, [r4] @ Call FP module USR entry point @@ -666,7 +666,7 @@ __kuser_helper_start: * * #define __kernel_dmb() \ * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ - * : : : "r0", "lr","cc" ) + * : : : "lr","cc" ) */ __kuser_memory_barrier: @ 0xffff0fa0 diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index f1c2fd5b6..55c99cdab 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -37,6 +37,24 @@ #endif .endm +#if __LINUX_ARM_ARCH__ >= 6 + .macro disable_irq + cpsid i + .endm + + .macro enable_irq + cpsie i + .endm +#else + .macro disable_irq + msr cpsr_c, #PSR_I_BIT | SVC_MODE + .endm + + .macro enable_irq + msr cpsr_c, #SVC_MODE + .endm +#endif + .macro get_thread_info, rd mov \rd, sp, lsr #13 mov \rd, \rd, lsl #13 diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S deleted file mode 100644 index a52da0ddb..000000000 --- a/arch/arm/kernel/head-common.S +++ /dev/null @@ -1,217 +0,0 @@ -/* - * linux/arch/arm/kernel/head-common.S - * - * Copyright (C) 1994-2002 Russell King - * Copyright (c) 2003 ARM Limited - * 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. - * - */ - - .type __switch_data, %object -__switch_data: - .long __mmap_switched - .long __data_loc @ r4 - .long __data_start @ r5 - .long __bss_start @ r6 - .long _end @ r7 - .long processor_id @ r4 - .long __machine_arch_type @ r5 - .long cr_alignment @ r6 - .long init_thread_union + THREAD_START_SP @ sp - -/* - * The following fragment of code is executed with the MMU on in MMU mode, - * and uses absolute addresses; this is not position independent. - * - * r0 = cp#15 control register - * r1 = machine ID - * r9 = processor ID - */ - .type __mmap_switched, %function -__mmap_switched: - adr r3, __switch_data + 4 - - ldmia r3!, {r4, r5, r6, r7} - cmp r4, r5 @ Copy data segment if needed -1: cmpne r5, r6 - ldrne fp, [r4], #4 - strne fp, [r5], #4 - bne 1b - - mov fp, #0 @ Clear BSS (and zero fp) -1: cmp r6, r7 - strcc fp, [r6],#4 - bcc 1b - - ldmia r3, {r4, r5, r6, sp} - str r9, [r4] @ Save processor ID - str r1, [r5] @ Save machine type - bic r4, r0, #CR_A @ Clear 'A' bit - stmia r6, {r0, r4} @ Save control register values - b start_kernel - -/* - * Exception handling. Something went wrong and we can't proceed. We - * ought to tell the user, but since we don't have any guarantee that - * we're even running on the right architecture, we do virtually nothing. - * - * If CONFIG_DEBUG_LL is set we try to print out something about the error - * and hope for the best (useful if bootloader fails to pass a proper - * machine ID for example). - */ - - .type __error_p, %function -__error_p: -#ifdef CONFIG_DEBUG_LL - adr r0, str_p1 - bl printascii - b __error -str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n" - .align -#endif - - .type __error_a, %function -__error_a: -#ifdef CONFIG_DEBUG_LL - mov r4, r1 @ preserve machine ID - adr r0, str_a1 - bl printascii - mov r0, r4 - bl printhex8 - adr r0, str_a2 - bl printascii - adr r3, 3f - ldmia r3, {r4, r5, r6} @ get machine desc list - sub r4, r3, r4 @ get offset between virt&phys - add r5, r5, r4 @ convert virt addresses to - add r6, r6, r4 @ physical address space -1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type - bl printhex8 - mov r0, #'\t' - bl printch - ldr r0, [r5, #MACHINFO_NAME] @ get machine name - add r0, r0, r4 - bl printascii - mov r0, #'\n' - bl printch - add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc - cmp r5, r6 - blo 1b - adr r0, str_a3 - bl printascii - b __error -str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" -str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" -str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" - .align -#endif - - .type __error, %function -__error: -#ifdef CONFIG_ARCH_RPC -/* - * Turn the screen red on a error - RiscPC only. - */ - mov r0, #0x02000000 - mov r3, #0x11 - orr r3, r3, r3, lsl #8 - orr r3, r3, r3, lsl #16 - str r3, [r0], #4 - str r3, [r0], #4 - str r3, [r0], #4 - str r3, [r0], #4 -#endif -1: mov r0, r0 - b 1b - - -/* - * Read processor ID register (CP#15, CR0), and look up in the linker-built - * supported processor list. Note that we can't use the absolute addresses - * for the __proc_info lists since we aren't running with the MMU on - * (and therefore, we are not in the correct address space). We have to - * calculate the offset. - * - * r9 = cpuid - * Returns: - * r3, r4, r6 corrupted - * r5 = proc_info pointer in physical address space - * r9 = cpuid (preserved) - */ - .type __lookup_processor_type, %function -__lookup_processor_type: - adr r3, 3f - ldmda r3, {r5 - r7} - sub r3, r3, r7 @ get offset between virt&phys - add r5, r5, r3 @ convert virt addresses to - add r6, r6, r3 @ physical address space -1: ldmia r5, {r3, r4} @ value, mask - and r4, r4, r9 @ mask wanted bits - teq r3, r4 - beq 2f - add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) - cmp r5, r6 - blo 1b - mov r5, #0 @ unknown processor -2: mov pc, lr - -/* - * This provides a C-API version of the above function. - */ -ENTRY(lookup_processor_type) - stmfd sp!, {r4 - r7, r9, lr} - mov r9, r0 - bl __lookup_processor_type - mov r0, r5 - ldmfd sp!, {r4 - r7, r9, pc} - -/* - * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for - * more information about the __proc_info and __arch_info structures. - */ - .long __proc_info_begin - .long __proc_info_end -3: .long . - .long __arch_info_begin - .long __arch_info_end - -/* - * Lookup machine architecture in the linker-build list of architectures. - * Note that we can't use the absolute addresses for the __arch_info - * lists since we aren't running with the MMU on (and therefore, we are - * not in the correct address space). We have to calculate the offset. - * - * r1 = machine architecture number - * Returns: - * r3, r4, r6 corrupted - * r5 = mach_info pointer in physical address space - */ - .type __lookup_machine_type, %function -__lookup_machine_type: - adr r3, 3b - ldmia r3, {r4, r5, r6} - sub r3, r3, r4 @ get offset between virt&phys - add r5, r5, r3 @ convert virt addresses to - add r6, r6, r3 @ physical address space -1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type - teq r3, r1 @ matches loader number? - beq 2f @ found - add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc - cmp r5, r6 - blo 1b - mov r5, #0 @ unknown machine -2: mov pc, lr - -/* - * This provides a C-API version of the above function. - */ -ENTRY(lookup_machine_type) - stmfd sp!, {r4 - r6, lr} - mov r1, r0 - bl __lookup_machine_type - mov r0, r5 - ldmfd sp!, {r4 - r6, pc} diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S deleted file mode 100644 index adf62e5ea..000000000 --- a/arch/arm/kernel/head-nommu.S +++ /dev/null @@ -1,83 +0,0 @@ -/* - * linux/arch/arm/kernel/head-nommu.S - * - * Copyright (C) 1994-2002 Russell King - * Copyright (C) 2003-2006 Hyok S. Choi - * - * 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. - * - * Common kernel startup code (non-paged MM) - * for 32-bit CPUs which has a process ID register(CP15). - * - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * Kernel startup entry point. - * --------------------------- - * - * This is normally called from the decompressor code. The requirements - * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, - * r1 = machine nr. - * - * See linux/arch/arm/tools/mach-types for the complete list of machine - * numbers for r1. - * - */ - __INIT - .type stext, %function -ENTRY(stext) - msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode - @ and irqs disabled - mrc p15, 0, r9, c0, c0 @ get processor id - bl __lookup_processor_type @ r5=procinfo r9=cpuid - movs r10, r5 @ invalid processor (r5=0)? - beq __error_p @ yes, error 'p' - bl __lookup_machine_type @ r5=machinfo - movs r8, r5 @ invalid machine (r5=0)? - beq __error_a @ yes, error 'a' - - ldr r13, __switch_data @ address to jump to after - @ the initialization is done - adr lr, __after_proc_init @ return (PIC) address - add pc, r10, #PROCINFO_INITFUNC - -/* - * Set the Control Register and Read the process ID. - */ - .type __after_proc_init, %function -__after_proc_init: - mrc p15, 0, r0, c1, c0, 0 @ read control reg -#ifdef CONFIG_ALIGNMENT_TRAP - orr r0, r0, #CR_A -#else - bic r0, r0, #CR_A -#endif -#ifdef CONFIG_CPU_DCACHE_DISABLE - bic r0, r0, #CR_C -#endif -#ifdef CONFIG_CPU_BPREDICT_DISABLE - bic r0, r0, #CR_Z -#endif -#ifdef CONFIG_CPU_ICACHE_DISABLE - bic r0, r0, #CR_I -#endif - mcr p15, 0, r0, c1, c0, 0 @ write control reg - - mov pc, r13 @ clear the BSS and jump - @ to start_kernel - .ltorg - -#include "head-common.S" diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 04f7344e3..1aca1775b 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -24,6 +24,15 @@ #include #include +#define PROCINFO_MMUFLAGS 8 +#define PROCINFO_INITFUNC 12 + +#define MACHINFO_TYPE 0 +#define MACHINFO_PHYSRAM 4 +#define MACHINFO_PHYSIO 8 +#define MACHINFO_PGOFFIO 12 +#define MACHINFO_NAME 16 + #define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET) /* @@ -73,7 +82,6 @@ ENTRY(stext) msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode @ and irqs disabled - mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? beq __error_p @ yes, error 'p' @@ -94,6 +102,49 @@ ENTRY(stext) adr lr, __enable_mmu @ return (PIC) address add pc, r10, #PROCINFO_INITFUNC + .type __switch_data, %object +__switch_data: + .long __mmap_switched + .long __data_loc @ r4 + .long __data_start @ r5 + .long __bss_start @ r6 + .long _end @ r7 + .long processor_id @ r4 + .long __machine_arch_type @ r5 + .long cr_alignment @ r6 + .long init_thread_union + THREAD_START_SP @ sp + +/* + * The following fragment of code is executed with the MMU on, and uses + * absolute addresses; this is not position independent. + * + * r0 = cp#15 control register + * r1 = machine ID + * r9 = processor ID + */ + .type __mmap_switched, %function +__mmap_switched: + adr r3, __switch_data + 4 + + ldmia r3!, {r4, r5, r6, r7} + cmp r4, r5 @ Copy data segment if needed +1: cmpne r5, r6 + ldrne fp, [r4], #4 + strne fp, [r5], #4 + bne 1b + + mov fp, #0 @ Clear BSS (and zero fp) +1: cmp r6, r7 + strcc fp, [r6],#4 + bcc 1b + + ldmia r3, {r4, r5, r6, sp} + str r9, [r4] @ Save processor ID + str r1, [r5] @ Save machine type + bic r4, r0, #CR_A @ Clear 'A' bit + stmia r6, {r0, r4} @ Save control register values + b start_kernel + #if defined(CONFIG_SMP) .type secondary_startup, #function ENTRY(secondary_startup) @@ -105,7 +156,6 @@ ENTRY(secondary_startup) * as it has already been validated by the primary processor. */ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC - mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type movs r10, r5 @ invalid processor? moveq r0, #'p' @ yes, error 'p' @@ -316,4 +366,165 @@ __create_page_tables: mov pc, lr .ltorg -#include "head-common.S" + + +/* + * Exception handling. Something went wrong and we can't proceed. We + * ought to tell the user, but since we don't have any guarantee that + * we're even running on the right architecture, we do virtually nothing. + * + * If CONFIG_DEBUG_LL is set we try to print out something about the error + * and hope for the best (useful if bootloader fails to pass a proper + * machine ID for example). + */ + + .type __error_p, %function +__error_p: +#ifdef CONFIG_DEBUG_LL + adr r0, str_p1 + bl printascii + b __error +str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n" + .align +#endif + + .type __error_a, %function +__error_a: +#ifdef CONFIG_DEBUG_LL + mov r4, r1 @ preserve machine ID + adr r0, str_a1 + bl printascii + mov r0, r4 + bl printhex8 + adr r0, str_a2 + bl printascii + adr r3, 3f + ldmia r3, {r4, r5, r6} @ get machine desc list + sub r4, r3, r4 @ get offset between virt&phys + add r5, r5, r4 @ convert virt addresses to + add r6, r6, r4 @ physical address space +1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type + bl printhex8 + mov r0, #'\t' + bl printch + ldr r0, [r5, #MACHINFO_NAME] @ get machine name + add r0, r0, r4 + bl printascii + mov r0, #'\n' + bl printch + add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc + cmp r5, r6 + blo 1b + adr r0, str_a3 + bl printascii + b __error +str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" +str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" +str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" + .align +#endif + + .type __error, %function +__error: +#ifdef CONFIG_ARCH_RPC +/* + * Turn the screen red on a error - RiscPC only. + */ + mov r0, #0x02000000 + mov r3, #0x11 + orr r3, r3, r3, lsl #8 + orr r3, r3, r3, lsl #16 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 +#endif +1: mov r0, r0 + b 1b + + +/* + * Read processor ID register (CP#15, CR0), and look up in the linker-built + * supported processor list. Note that we can't use the absolute addresses + * for the __proc_info lists since we aren't running with the MMU on + * (and therefore, we are not in the correct address space). We have to + * calculate the offset. + * + * Returns: + * r3, r4, r6 corrupted + * r5 = proc_info pointer in physical address space + * r9 = cpuid + */ + .type __lookup_processor_type, %function +__lookup_processor_type: + adr r3, 3f + ldmda r3, {r5, r6, r9} + sub r3, r3, r9 @ get offset between virt&phys + add r5, r5, r3 @ convert virt addresses to + add r6, r6, r3 @ physical address space + mrc p15, 0, r9, c0, c0 @ get processor id +1: ldmia r5, {r3, r4} @ value, mask + and r4, r4, r9 @ mask wanted bits + teq r3, r4 + beq 2f + add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) + cmp r5, r6 + blo 1b + mov r5, #0 @ unknown processor +2: mov pc, lr + +/* + * This provides a C-API version of the above function. + */ +ENTRY(lookup_processor_type) + stmfd sp!, {r4 - r6, r9, lr} + bl __lookup_processor_type + mov r0, r5 + ldmfd sp!, {r4 - r6, r9, pc} + +/* + * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for + * more information about the __proc_info and __arch_info structures. + */ + .long __proc_info_begin + .long __proc_info_end +3: .long . + .long __arch_info_begin + .long __arch_info_end + +/* + * Lookup machine architecture in the linker-build list of architectures. + * Note that we can't use the absolute addresses for the __arch_info + * lists since we aren't running with the MMU on (and therefore, we are + * not in the correct address space). We have to calculate the offset. + * + * r1 = machine architecture number + * Returns: + * r3, r4, r6 corrupted + * r5 = mach_info pointer in physical address space + */ + .type __lookup_machine_type, %function +__lookup_machine_type: + adr r3, 3b + ldmia r3, {r4, r5, r6} + sub r3, r3, r4 @ get offset between virt&phys + add r5, r5, r3 @ convert virt addresses to + add r6, r6, r3 @ physical address space +1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type + teq r3, r1 @ matches loader number? + beq 2f @ found + add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc + cmp r5, r6 + blo 1b + mov r5, #0 @ unknown machine +2: mov pc, lr + +/* + * This provides a C-API version of the above function. + */ +ENTRY(lookup_machine_type) + stmfd sp!, {r4 - r6, lr} + mov r1, r0 + bl __lookup_machine_type + mov r0, r5 + ldmfd sp!, {r4 - r6, pc} diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 2d5896b36..1d50d2b98 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -305,19 +305,14 @@ report_bad_irq(unsigned int irq, struct pt_regs *regs, struct irqdesc *desc, int static int count = 100; struct irqaction *action; - if (noirqdebug) + if (!count || noirqdebug) return; + count--; + if (ret != IRQ_HANDLED && ret != IRQ_NONE) { - if (!count) - return; - count--; printk("irq%u: bogus retval mask %x\n", irq, ret); } else { - desc->irqs_unhandled++; - if (desc->irqs_unhandled <= 99900) - return; - desc->irqs_unhandled = 0; printk("irq%u: nobody cared\n", irq); } show_regs(regs); diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 7df6e1aaa..489c069e5 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -264,12 +264,8 @@ void show_fpregs(struct user_fp *regs) /* * Task structure and kernel stack allocation. */ -struct thread_info_list { - unsigned long *head; - unsigned int nr; -}; - -static DEFINE_PER_CPU(struct thread_info_list, thread_info_list) = { NULL, 0 }; +static unsigned long *thread_info_head; +static unsigned int nr_thread_info; #define EXTRA_TASK_STRUCT 4 @@ -278,15 +274,12 @@ struct thread_info *alloc_thread_info(struct task_struct *task) struct thread_info *thread = NULL; if (EXTRA_TASK_STRUCT) { - struct thread_info_list *th = &get_cpu_var(thread_info_list); - unsigned long *p = th->head; + unsigned long *p = thread_info_head; if (p) { - th->head = (unsigned long *)p[0]; - th->nr -= 1; + thread_info_head = (unsigned long *)p[0]; + nr_thread_info -= 1; } - put_cpu_var(thread_info_list); - thread = (struct thread_info *)p; } @@ -307,19 +300,13 @@ struct thread_info *alloc_thread_info(struct task_struct *task) void free_thread_info(struct thread_info *thread) { - if (EXTRA_TASK_STRUCT) { - struct thread_info_list *th = &get_cpu_var(thread_info_list); - if (th->nr < EXTRA_TASK_STRUCT) { - unsigned long *p = (unsigned long *)thread; - p[0] = (unsigned long)th->head; - th->head = p; - th->nr += 1; - put_cpu_var(thread_info_list); - return; - } - put_cpu_var(thread_info_list); - } - free_pages((unsigned long)thread, THREAD_SIZE_ORDER); + if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) { + unsigned long *p = (unsigned long *)thread; + p[0] = (unsigned long)thread_info_head; + thread_info_head = p; + nr_thread_info += 1; + } else + free_pages((unsigned long)thread, THREAD_SIZE_ORDER); } /* @@ -487,3 +474,4 @@ unsigned long get_wchan(struct task_struct *p) } while (count ++ < 16); return 0; } +EXPORT_SYMBOL(get_wchan); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 9fc9af88c..08974cbe9 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -252,9 +252,6 @@ static void __init dump_cpu_info(int cpu) dump_cache("cache", cpu, CACHE_ISIZE(info)); } } - - if (arch_is_coherent()) - printk("Cache coherency enabled\n"); } int cpu_architecture(void) @@ -281,7 +278,7 @@ int cpu_architecture(void) * These functions re-use the assembly code in head.S, which * already provide the required functionality. */ -extern struct proc_info_list *lookup_processor_type(unsigned int); +extern struct proc_info_list *lookup_processor_type(void); extern struct machine_desc *lookup_machine_type(unsigned int); static void __init setup_processor(void) @@ -293,7 +290,7 @@ static void __init setup_processor(void) * types. The linker builds this table for us from the * entries in arch/arm/mm/proc-*.S */ - list = lookup_processor_type(processor_id); + list = lookup_processor_type(); if (!list) { printk("CPU configuration botched (ID %08x), unable " "to continue.\n", processor_id); @@ -322,12 +319,6 @@ static void __init setup_processor(void) sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; -#ifndef CONFIG_ARM_THUMB - elf_hwcap &= ~HWCAP_THUMB; -#endif -#ifndef CONFIG_VFP - elf_hwcap &= ~HWCAP_VFP; -#endif cpu_proc_init(); } @@ -407,7 +398,7 @@ static void __init early_initrd(char **p) } __early_param("initrd=", early_initrd); -static void __init arm_add_memory(unsigned long start, unsigned long size) +static void __init add_memory(unsigned long start, unsigned long size) { /* * Ensure that start/size are aligned to a page boundary. @@ -445,7 +436,7 @@ static void __init early_mem(char **p) if (**p == '@') start = memparse(*p + 1, p); - arm_add_memory(start, size); + add_memory(start, size); } __early_param("mem=", early_mem); @@ -587,7 +578,7 @@ static int __init parse_tag_mem32(const struct tag *tag) tag->u.mem.start, tag->u.mem.size / 1024); return -EINVAL; } - arm_add_memory(tag->u.mem.start, tag->u.mem.size); + add_memory(tag->u.mem.start, tag->u.mem.size); return 0; } @@ -807,7 +798,7 @@ static int __init topology_init(void) { int cpu; - for_each_possible_cpu(cpu) + for_each_cpu(cpu) register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); return 0; diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h index 27beece15..9991049c5 100644 --- a/arch/arm/kernel/signal.h +++ b/arch/arm/kernel/signal.h @@ -7,6 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) +#define KERN_SIGRETURN_CODE 0xffff0500 extern const unsigned long sigreturn_codes[7]; diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 1370d726d..02aa300c4 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -337,6 +337,9 @@ void __init smp_prepare_boot_cpu(void) unsigned int cpu = smp_processor_id(); per_cpu(cpu_data, cpu).idle = current; + + cpu_set(cpu, cpu_present_map); + cpu_set(cpu, cpu_online_map); } static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 8170af471..a491de2d9 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -234,12 +234,7 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third, */ asmlinkage int sys_fork(struct pt_regs *regs) { -#ifdef CONFIG_MMU return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL); -#else - /* can not support in nommu mode */ - return(-EINVAL); -#endif } /* Clone a task - this clones the calling program thread. diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 35230a060..03924bcc6 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -506,7 +506,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) if (!pmd_present(*pmd)) goto bad_access; pte = pte_offset_map_lock(mm, pmd, addr, &ptl); - if (!pte_present(*pte) || !pte_dirty(*pte)) { + if (!pte_present(*pte) || !pte_write(*pte)) { pte_unmap_unlock(pte, ptl); goto bad_access; } @@ -688,7 +688,6 @@ EXPORT_SYMBOL(abort); void __init trap_init(void) { - unsigned long vectors = CONFIG_VECTORS_BASE; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; extern char __kuser_helper_start[], __kuser_helper_end[]; @@ -699,9 +698,9 @@ void __init trap_init(void) * into the vector page, mapped at 0xffff0000, and ensure these * are visible to the instruction stream. */ - memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); - memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start); - memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); + memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); + memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); + memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); /* * Copy signal return handlers into the vector page, and @@ -710,6 +709,6 @@ void __init trap_init(void) memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, sizeof(sigreturn_codes)); - flush_icache_range(vectors, vectors + PAGE_SIZE); + flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); } diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 7b726b627..391f3ab3f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -18,7 +18,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ # the code in uaccess.S is not preemption safe and # probably faster on ARMv3 only -ifeq ($(CONFIG_PREEMPT),y) +ifeq ($CONFIG_PREEMPT,y) lib-y += copy_from_user.o copy_to_user.o else ifneq ($(CONFIG_CPU_32v3),y) diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index 16153c86c..68a21c0f3 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S @@ -29,7 +29,7 @@ ENTRY(__backtrace) ENTRY(c_backtrace) -#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK) +#ifndef CONFIG_FRAME_POINTER mov pc, lr #else @@ -122,7 +122,7 @@ ENTRY(c_backtrace) #define reg r5 #define stack r6 -.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr} +.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} mov stack, r0 mov instr, r1 mov reg, #9 @@ -145,7 +145,7 @@ ENTRY(c_backtrace) adrne r0, .Lcr blne printk mov r0, stack - LOADREGS(fd, sp!, {instr, reg, stack, r7, r8, pc}) + LOADREGS(fd, sp!, {instr, reg, stack, r7, pc}) .Lfp: .asciz " r%d = %08X%c" .Lcr: .asciz "\n" diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S index cab355c0c..838e435e4 100644 --- a/arch/arm/lib/copy_template.S +++ b/arch/arm/lib/copy_template.S @@ -236,7 +236,7 @@ /* - * Abort preamble and completion macros. + * Abort preanble and completion macros. * If a fixup handler is required then those macros must surround it. * It is assumed that the fixup code will handle the private part of * the exit macro. diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S index 9183b06c0..b3fb475b4 100644 --- a/arch/arm/lib/delay.S +++ b/arch/arm/lib/delay.S @@ -9,32 +9,28 @@ */ #include #include -#include .text .LC0: .word loops_per_jiffy -.LC1: .word (2199023*HZ)>>11 /* - * r0 <= 2000 - * lpj <= 0x01ffffff (max. 3355 bogomips) - * HZ <= 1000 + * 0 <= r0 <= 2000 */ - ENTRY(__udelay) - ldr r2, .LC1 + mov r2, #0x6800 + orr r2, r2, #0x00db mul r0, r2, r0 -ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 +ENTRY(__const_udelay) @ 0 <= r0 <= 0x01ffffff ldr r2, .LC0 - ldr r2, [r2] @ max = 0x01ffffff - mov r0, r0, lsr #14 @ max = 0x0001ffff - mov r2, r2, lsr #10 @ max = 0x00007fff + ldr r2, [r2] @ max = 0x0fffffff + mov r0, r0, lsr #11 @ max = 0x00003fff + mov r2, r2, lsr #11 @ max = 0x0003ffff mul r0, r2, r0 @ max = 2^32-1 movs r0, r0, lsr #6 RETINSTR(moveq,pc,lr) /* - * loops = r0 * HZ * loops_per_jiffy / 1000000 + * loops = (r0 * 0x10c6 * 100 * loops_per_jiffy) / 2^32 * * Oh, if only we had a cycle counter... */ diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S index 58eef6607..ec9a1cd61 100644 --- a/arch/arm/lib/div64.S +++ b/arch/arm/lib/div64.S @@ -189,12 +189,12 @@ ENTRY(__do_div64) moveq pc, lr @ Division by 0: - str lr, [sp, #-8]! + str lr, [sp, #-4]! bl __div0 @ as wrong as it could be... mov yl, #0 mov yh, #0 mov xh, #0 - ldr pc, [sp], #8 + ldr pc, [sp], #4 diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S index 1b197ea7a..b15352363 100644 --- a/arch/arm/lib/io-acorn.S +++ b/arch/arm/lib/io-acorn.S @@ -12,6 +12,7 @@ */ #include #include +#include .text .align diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index 83f57da31..dc5fa8e5e 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c @@ -79,12 +79,7 @@ static void __init aaed2000_init(void) } static struct map_desc aaed2000_io_desc[] __initdata = { - { - .virtual = EXT_GPIO_VBASE, - .pfn = __phys_to_pfn(EXT_GPIO_PBASE), - .length = EXT_GPIO_LENGTH, - .type = MT_DEVICE - }, + { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */ }; static void __init aaed2000_map_io(void) diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index 65be5efd6..dce4815cf 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -49,12 +50,12 @@ static struct map_desc standard_io_desc[] __initdata = { { .virtual = VIO_APB_BASE, - .pfn = __phys_to_pfn(PIO_APB_BASE), + .physical = __phys_to_pfn(PIO_APB_BASE), .length = IO_APB_LENGTH, .type = MT_DEVICE }, { .virtual = VIO_AHB_BASE, - .pfn = __phys_to_pfn(PIO_AHB_BASE), + .physical = __phys_to_pfn(PIO_AHB_BASE), .length = IO_AHB_LENGTH, .type = MT_DEVICE } diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h index 59501b573..b6029a95f 100644 --- a/arch/arm/mach-aaec2000/core.h +++ b/arch/arm/mach-aaec2000/core.h @@ -9,7 +9,6 @@ * */ -#include #include struct sys_timer; diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index ef88c4128..75e6ee318 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -16,12 +16,11 @@ obj-$(CONFIG_MACH_CSB637) += board-csb637.o #obj-$(CONFIG_MACH_KB9200) += board-kb9202.o # LEDs support -led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o -led-$(CONFIG_MACH_AT91RM9200EK) += leds.o -led-$(CONFIG_MACH_CSB337) += leds.o -led-$(CONFIG_MACH_CSB637) += leds.o +#led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o +#led-$(CONFIG_MACH_AT91RM9200EK) += leds.o +#led-$(CONFIG_MACH_CSB337) += leds.o +#led-$(CONFIG_MACH_CSB637) += leds.o #led-$(CONFIG_MACH_KB9200) += leds.o -#led-$(CONFIG_MACH_KAFA) += leds.o obj-$(CONFIG_LEDS) += $(led-y) # VGA support diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c index f45104cee..54022e58d 100644 --- a/arch/arm/mach-at91rm9200/board-csb337.c +++ b/arch/arm/mach-at91rm9200/board-csb337.c @@ -67,9 +67,6 @@ static void __init csb337_map_io(void) /* Initialize clocks: 3.6864 MHz crystal */ at91_clock_init(3686400); - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); - #ifdef CONFIG_SERIAL_AT91 at91_console_port = CSB337_SERIAL_CONSOLE; memcpy(at91_serial_map, serial, sizeof(serial)); diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c index f2c2d6e79..8195f9d91 100644 --- a/arch/arm/mach-at91rm9200/board-csb637.c +++ b/arch/arm/mach-at91rm9200/board-csb637.c @@ -67,9 +67,6 @@ static void __init csb637_map_io(void) /* Initialize clocks: 3.6864 MHz crystal */ at91_clock_init(3686400); - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); - #ifdef CONFIG_SERIAL_AT91 at91_console_port = CSB637_SERIAL_CONSOLE; memcpy(at91_serial_map, serial, sizeof(serial)); diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index 2d7200ed6..8a7833683 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c @@ -70,9 +70,6 @@ static void __init dk_map_io(void) /* Initialize clocks: 18.432 MHz crystal */ at91_clock_init(18432000); - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); - #ifdef CONFIG_SERIAL_AT91 at91_console_port = DK_SERIAL_CONSOLE; memcpy(at91_serial_map, serial, sizeof(serial)); @@ -121,14 +118,9 @@ static void __init dk_board_init(void) at91_add_device_udc(&dk_udc_data); /* Compact Flash */ at91_add_device_cf(&dk_cf_data); -#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD - /* DataFlash card */ - at91_set_gpio_output(AT91_PIN_PB7, 0); -#else /* MMC */ - at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ + at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */ at91_add_device_mmc(&dk_mmc_data); -#endif /* VGA */ // dk_add_device_video(); } diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index 80d90f513..fd0752eba 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c @@ -70,9 +70,6 @@ static void __init ek_map_io(void) /* Initialize clocks: 18.432 MHz crystal */ at91_clock_init(18432000); - /* Setup the LEDs */ - at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); - #ifdef CONFIG_SERIAL_AT91 at91_console_port = EK_SERIAL_CONSOLE; memcpy(at91_serial_map, serial, sizeof(serial)); @@ -114,14 +111,9 @@ static void __init ek_board_init(void) at91_add_device_usbh(&ek_usbh_data); /* USB Device */ at91_add_device_udc(&ek_udc_data); -#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD - /* DataFlash card */ - at91_set_gpio_output(AT91_PIN_PB22, 0); -#else /* MMC */ - at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ + at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */ at91_add_device_mmc(&ek_mmc_data); -#endif /* VGA */ // ek_add_device_video(); } diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c index 8b95467c6..ec8195a2a 100644 --- a/arch/arm/mach-at91rm9200/clock.c +++ b/arch/arm/mach-at91rm9200/clock.c @@ -201,54 +201,6 @@ static struct clk ohci_clk = { .pmc_mask = 1 << AT91_ID_UHP, .mode = pmc_periph_mode, }; -static struct clk ether_clk = { - .name = "ether_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_EMAC, - .mode = pmc_periph_mode, -}; -static struct clk mmc_clk = { - .name = "mci_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_MCI, - .mode = pmc_periph_mode, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_TWI, - .mode = pmc_periph_mode, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_US0, - .mode = pmc_periph_mode, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_US1, - .mode = pmc_periph_mode, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_US2, - .mode = pmc_periph_mode, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_US3, - .mode = pmc_periph_mode, -}; -static struct clk spi_clk = { - .name = "spi0_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_SPI, - .mode = pmc_periph_mode, -}; static struct clk *const clock_list[] = { /* four primary clocks -- MUST BE FIRST! */ @@ -271,18 +223,15 @@ static struct clk *const clock_list[] = { /* MCK and peripherals */ &mck, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &usart3_clk, - &mmc_clk, + // usart0..usart3 + // mmc &udc_clk, - &twi_clk, - &spi_clk, + // i2c + // spi // ssc0..ssc2 // tc0..tc5 &ohci_clk, - ðer_clk, + // ether }; @@ -411,7 +360,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) u32 pckr; pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); - pckr &= AT91_PMC_CSS_PLLB; /* clock selection */ + pckr &= 0x03; pckr |= prescale << 2; at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); clk->rate_hz = actual; @@ -491,7 +440,7 @@ static int at91_clk_show(struct seq_file *s, void *unused) else state = ""; - seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n", + seq_printf(s, "%-10s users=%d %-3s %9ld Hz %s\n", clk->name, clk->users, state, clk_get_rate(clk), clk->parent ? clk->parent->name : ""); } @@ -534,18 +483,11 @@ static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) freq *= mul + 1; } else freq = 0; - + if (pll == &pllb && (reg & (1 << 28))) + freq /= 2; return freq; } -static u32 __init at91_usb_rate(struct clk *pll, u32 freq, u32 reg) -{ - if (pll == &pllb && (reg & AT91_PMC_USB96M)) - return freq / 2; - else - return freq; -} - static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) { unsigned i, div = 0, mul = 0, diff = 1 << 30; @@ -608,8 +550,8 @@ int __init at91_clock_init(unsigned long main_clock) if (!main_clock) { do { tmp = at91_sys_read(AT91_CKGR_MCFR); - } while (!(tmp & AT91_PMC_MAINRDY)); - main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); + } while (!(tmp & 0x10000)); + main_clock = (tmp & 0xffff) * (AT91_SLOW_CLOCK / 16); } main_clk.rate_hz = main_clock; @@ -624,16 +566,13 @@ int __init at91_clock_init(unsigned long main_clock) * * REVISIT: assumes MCK doesn't derive from PLLB! */ - at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; + at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | 0x10000000; pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); at91_sys_write(AT91_PMC_PCDR, (1 << AT91_ID_UHP) | (1 << AT91_ID_UDP)); at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP | AT91_PMC_UDP); at91_sys_write(AT91_CKGR_PLLBR, 0); at91_sys_write(AT91_PMC_SCER, AT91_PMC_MCKUDP); - udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); - uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); - /* * MCK and CPU derive from one of those primary clocks. * For now, assume this parentage won't change. diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c index bfe47bd6e..57eedd5be 100644 --- a/arch/arm/mach-at91rm9200/devices.c +++ b/arch/arm/mach-at91rm9200/devices.c @@ -28,10 +28,10 @@ static u64 ohci_dmamask = 0xffffffffUL; static struct at91_usbh_data usbh_data; -static struct resource at91_usbh_resource[] = { +static struct resource at91rm9200_usbh_resource[] = { [0] = { .start = AT91_UHP_BASE, - .end = AT91_UHP_BASE + SZ_1M - 1, + .end = AT91_UHP_BASE + SZ_1M -1, .flags = IORESOURCE_MEM, }, [1] = { @@ -49,8 +49,8 @@ static struct platform_device at91rm9200_usbh_device = { .coherent_dma_mask = 0xffffffff, .platform_data = &usbh_data, }, - .resource = at91_usbh_resource, - .num_resources = ARRAY_SIZE(at91_usbh_resource), + .resource = at91rm9200_usbh_resource, + .num_resources = ARRAY_SIZE(at91rm9200_usbh_resource), }; void __init at91_add_device_usbh(struct at91_usbh_data *data) @@ -121,19 +121,6 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} static u64 eth_dmamask = 0xffffffffUL; static struct at91_eth_data eth_data; -static struct resource at91_eth_resources[] = { - [0] = { - .start = AT91_BASE_EMAC, - .end = AT91_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91_ID_EMAC, - .end = AT91_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - static struct platform_device at91rm9200_eth_device = { .name = "at91_ether", .id = -1, @@ -142,8 +129,7 @@ static struct platform_device at91rm9200_eth_device = { .coherent_dma_mask = 0xffffffff, .platform_data = ð_data, }, - .resource = at91_eth_resources, - .num_resources = ARRAY_SIZE(at91_eth_resources), + .num_resources = 0, }; void __init at91_add_device_eth(struct at91_eth_data *data) @@ -194,23 +180,13 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {} #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) static struct at91_cf_data cf_data; -static struct resource at91_cf_resources[] = { - [0] = { - .start = AT91_CF_BASE, - /* ties up CS4, CS5, and CS6 */ - .end = AT91_CF_BASE + (0x30000000 - 1), - .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, - }, -}; - static struct platform_device at91rm9200_cf_device = { .name = "at91_cf", .id = -1, .dev = { .platform_data = &cf_data, }, - .resource = at91_cf_resources, - .num_resources = ARRAY_SIZE(at91_cf_resources), + .num_resources = 0, }; void __init at91_add_device_cf(struct at91_cf_data *data) @@ -248,20 +224,15 @@ static u64 mmc_dmamask = 0xffffffffUL; static struct at91_mmc_data mmc_data; static struct resource at91_mmc_resources[] = { - [0] = { + { .start = AT91_BASE_MCI, .end = AT91_BASE_MCI + SZ_16K - 1, .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91_ID_MCI, - .end = AT91_ID_MCI, - .flags = IORESOURCE_IRQ, - }, + } }; static struct platform_device at91rm9200_mmc_device = { - .name = "at91_mci", + .name = "at91rm9200_mci", .id = -1, .dev = { .dma_mask = &mmc_dmamask, @@ -319,123 +290,4 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data) void __init at91_add_device_mmc(struct at91_mmc_data *data) {} #endif -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; - -static struct resource at91_nand_resources[] = { - { - .start = AT91_SMARTMEDIA_BASE, - .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91_nand_device = { - .name = "at91_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = at91_nand_resources, - .num_resources = ARRAY_SIZE(at91_nand_resources), -}; - -void __init at91_add_device_nand(struct at91_nand_data *data) -{ - if (!data) - return; - - /* enable pin */ - if (data->enable_pin) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (data->rdy_pin) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (data->det_pin) - at91_set_gpio_input(data->det_pin, 1); - - at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ - - nand_data = *data; - platform_device_register(&at91_nand_device); -} -#else -void __init at91_add_device_nand(struct at91_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) -static struct platform_device at91rm9200_twi_device = { - .name = "at91_i2c", - .id = -1, - .num_resources = 0, -}; - -void __init at91_add_device_i2c(void) -{ - /* pins used for TWI interface */ - at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PA25, 1); - - at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PA26, 1); - - platform_device_register(&at91rm9200_twi_device); -} -#else -void __init at91_add_device_i2c(void) {} -#endif - - -/* -------------------------------------------------------------------- - * RTC - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91_RTC) || defined(CONFIG_AT91_RTC_MODULE) -static struct platform_device at91rm9200_rtc_device = { - .name = "at91_rtc", - .id = -1, - .num_resources = 0, -}; - -void __init at91_add_device_rtc(void) -{ - platform_device_register(&at91rm9200_rtc_device); -} -#else -void __init at91_add_device_rtc(void) {} -#endif - - -/* -------------------------------------------------------------------- - * LEDs - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_LEDS) -u8 at91_leds_cpu; -u8 at91_leds_timer; - -void __init at91_init_leds(u8 cpu_led, u8 timer_led) -{ - at91_leds_cpu = cpu_led; - at91_leds_timer = timer_led; -} - -#else -void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} -#endif - - /* -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c index 5ab46274e..0e396feec 100644 --- a/arch/arm/mach-at91rm9200/gpio.c +++ b/arch/arm/mach-at91rm9200/gpio.c @@ -261,7 +261,7 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs void __iomem *pio; u32 isr; - pio = desc->base; + pio = (void __force __iomem *) desc->chipdata; /* temporarily mask (level sensitive) parent IRQ */ desc->chip->ack(irq); @@ -312,7 +312,7 @@ void __init at91_gpio_irq_setup(unsigned banks) __raw_writel(~0, controller + PIO_IDR); set_irq_data(id, (void *) pin); - set_irq_chipdata(id, controller); + set_irq_chipdata(id, (void __force *) controller); for (i = 0; i < 32; i++, pin++) { set_irq_chip(pin, &gpio_irqchip); diff --git a/arch/arm/mach-at91rm9200/leds.c b/arch/arm/mach-at91rm9200/leds.c deleted file mode 100644 index 28150e890..000000000 --- a/arch/arm/mach-at91rm9200/leds.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * LED driver for Atmel AT91-based boards. - * - * Copyright (C) SAN People (Pty) Ltd - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 -#include -#include -#include - -#include -#include -#include -#include - - -static inline void at91_led_on(unsigned int led) -{ - at91_set_gpio_value(led, 0); -} - -static inline void at91_led_off(unsigned int led) -{ - at91_set_gpio_value(led, 1); -} - -static inline void at91_led_toggle(unsigned int led) -{ - unsigned long is_off = at91_get_gpio_value(led); - if (is_off) - at91_led_on(led); - else - at91_led_off(led); -} - - -/* - * Handle LED events. - */ -static void at91_leds_event(led_event_t evt) -{ - unsigned long flags; - - local_irq_save(flags); - - switch(evt) { - case led_start: /* System startup */ - at91_led_on(at91_leds_cpu); - break; - - case led_stop: /* System stop / suspend */ - at91_led_off(at91_leds_cpu); - break; - -#ifdef CONFIG_LEDS_TIMER - case led_timer: /* Every 50 timer ticks */ - at91_led_toggle(at91_leds_timer); - break; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: /* Entering idle state */ - at91_led_off(at91_leds_cpu); - break; - - case led_idle_end: /* Exit idle state */ - at91_led_on(at91_leds_cpu); - break; -#endif - - default: - break; - } - - local_irq_restore(flags); -} - - -static int __init leds_init(void) -{ - if (!at91_leds_timer || !at91_leds_cpu) - return -ENODEV; - - /* Enable PIO to access the LEDs */ - at91_set_gpio_output(at91_leds_timer, 1); - at91_set_gpio_output(at91_leds_cpu, 1); - - leds_event = at91_leds_event; - - leds_event(led_start); - return 0; -} - -__initcall(leds_init); diff --git a/arch/arm/mach-at91rm9200/time.c b/arch/arm/mach-at91rm9200/time.c index 7ffcf443b..1b6dd2dee 100644 --- a/arch/arm/mach-at91rm9200/time.c +++ b/arch/arm/mach-at91rm9200/time.c @@ -71,11 +71,11 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_r if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */ write_seqlock(&xtime_lock); - while (((read_CRTR() - at91_sys_read(AT91_ST_RTAR)) & AT91_ST_ALMV) >= LATCH) { + do { timer_tick(regs); rtar = (at91_sys_read(AT91_ST_RTAR) + LATCH) & AT91_ST_ALMV; at91_sys_write(AT91_ST_RTAR, rtar); - } + } while (((read_CRTR() - at91_sys_read(AT91_ST_RTAR)) & AT91_ST_ALMV) >= LATCH); write_sequnlock(&xtime_lock); diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig deleted file mode 100644 index cec5a21ca..000000000 --- a/arch/arm/mach-ep93xx/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -if ARCH_EP93XX - -menu "Cirrus EP93xx Implementation Options" - -comment "EP93xx Platforms" - -config MACH_GESBC9312 - bool "Support Glomation GESBC-9312-sx" - help - Say 'Y' here if you want your kernel to support the Glomation - GESBC-9312-sx board. - -config MACH_TS72XX - bool "Support Technologic Systems TS-72xx SBC" - help - Say 'Y' here if you want your kernel to support the - Technologic Systems TS-72xx board. - -endmenu - -endif diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile deleted file mode 100644 index 5393af989..000000000 --- a/arch/arm/mach-ep93xx/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the linux kernel. -# -obj-y := core.o -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o -obj-$(CONFIG_MACH_TS72XX) += ts72xx.o diff --git a/arch/arm/mach-ep93xx/Makefile.boot b/arch/arm/mach-ep93xx/Makefile.boot deleted file mode 100644 index d5561ad15..000000000 --- a/arch/arm/mach-ep93xx/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y := 0x00008000 -params_phys-y := 0x00000100 diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c deleted file mode 100644 index dcd417625..000000000 --- a/arch/arm/mach-ep93xx/core.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * arch/arm/mach-ep93xx/core.c - * Core routines for Cirrus EP93xx chips. - * - * Copyright (C) 2006 Lennert Buytenhek - * - * Thanks go to Michael Burian and Ray Lehtiniemi for their key - * role in the ep93xx linux community. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - -/************************************************************************* - * Static I/O mappings that are needed for all EP93xx platforms - *************************************************************************/ -static struct map_desc ep93xx_io_desc[] __initdata = { - { - .virtual = EP93XX_AHB_VIRT_BASE, - .pfn = __phys_to_pfn(EP93XX_AHB_PHYS_BASE), - .length = EP93XX_AHB_SIZE, - .type = MT_DEVICE, - }, { - .virtual = EP93XX_APB_VIRT_BASE, - .pfn = __phys_to_pfn(EP93XX_APB_PHYS_BASE), - .length = EP93XX_APB_SIZE, - .type = MT_DEVICE, - }, -}; - -void __init ep93xx_map_io(void) -{ - iotable_init(ep93xx_io_desc, ARRAY_SIZE(ep93xx_io_desc)); -} - - -/************************************************************************* - * Timer handling for EP93xx - ************************************************************************* - * The ep93xx has four internal timers. Timers 1, 2 (both 16 bit) and - * 3 (32 bit) count down at 508 kHz, are self-reloading, and can generate - * an interrupt on underflow. Timer 4 (40 bit) counts down at 983.04 kHz, - * is free-running, and can't generate interrupts. - * - * The 508 kHz timers are ideal for use for the timer interrupt, as the - * most common values of HZ divide 508 kHz nicely. We pick one of the 16 - * bit timers (timer 1) since we don't need more than 16 bits of reload - * value as long as HZ >= 8. - * - * The higher clock rate of timer 4 makes it a better choice than the - * other timers for use in gettimeoffset(), while the fact that it can't - * generate interrupts means we don't have to worry about not being able - * to use this timer for something else. We also use timer 4 for keeping - * track of lost jiffies. - */ -static unsigned int last_jiffy_time; - -#define TIMER4_TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) - -static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - write_seqlock(&xtime_lock); - - __raw_writel(1, EP93XX_TIMER1_CLEAR); - while (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time - >= TIMER4_TICKS_PER_JIFFY) { - last_jiffy_time += TIMER4_TICKS_PER_JIFFY; - timer_tick(regs); - } - - write_sequnlock(&xtime_lock); - - return IRQ_HANDLED; -} - -static struct irqaction ep93xx_timer_irq = { - .name = "ep93xx timer", - .flags = SA_INTERRUPT | SA_TIMER, - .handler = ep93xx_timer_interrupt, -}; - -static void __init ep93xx_timer_init(void) -{ - /* Enable periodic HZ timer. */ - __raw_writel(0x48, EP93XX_TIMER1_CONTROL); - __raw_writel((508000 / HZ) - 1, EP93XX_TIMER1_LOAD); - __raw_writel(0xc8, EP93XX_TIMER1_CONTROL); - - /* Enable lost jiffy timer. */ - __raw_writel(0x100, EP93XX_TIMER4_VALUE_HIGH); - - setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq); -} - -static unsigned long ep93xx_gettimeoffset(void) -{ - int offset; - - offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time; - - /* Calculate (1000000 / 983040) * offset. */ - return offset + (53 * offset / 3072); -} - -struct sys_timer ep93xx_timer = { - .init = ep93xx_timer_init, - .offset = ep93xx_gettimeoffset, -}; - - -/************************************************************************* - * GPIO handling for EP93xx - *************************************************************************/ -static unsigned char gpio_int_enable[2]; -static unsigned char gpio_int_type1[2]; -static unsigned char gpio_int_type2[2]; - -static void update_gpio_ab_int_params(int port) -{ - if (port == 0) { - __raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE); - __raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2); - __raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1); - __raw_writeb(gpio_int_enable[0], EP93XX_GPIO_A_INT_ENABLE); - } else if (port == 1) { - __raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE); - __raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2); - __raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1); - __raw_writeb(gpio_int_enable[1], EP93XX_GPIO_B_INT_ENABLE); - } -} - - -static unsigned char data_register_offset[8] = { - 0x00, 0x04, 0x08, 0x0c, 0x20, 0x30, 0x38, 0x40, -}; - -static unsigned char data_direction_register_offset[8] = { - 0x10, 0x14, 0x18, 0x1c, 0x24, 0x34, 0x3c, 0x44, -}; - -void gpio_line_config(int line, int direction) -{ - unsigned int data_direction_register; - unsigned long flags; - unsigned char v; - - data_direction_register = - EP93XX_GPIO_REG(data_direction_register_offset[line >> 3]); - - local_irq_save(flags); - if (direction == GPIO_OUT) { - if (line >= 0 && line < 16) { - gpio_int_enable[line >> 3] &= ~(1 << (line & 7)); - update_gpio_ab_int_params(line >> 3); - } - - v = __raw_readb(data_direction_register); - v |= 1 << (line & 7); - __raw_writeb(v, data_direction_register); - } else if (direction == GPIO_IN) { - v = __raw_readb(data_direction_register); - v &= ~(1 << (line & 7)); - __raw_writeb(v, data_direction_register); - } - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_line_config); - -int gpio_line_get(int line) -{ - unsigned int data_register; - - data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]); - - return !!(__raw_readb(data_register) & (1 << (line & 7))); -} -EXPORT_SYMBOL(gpio_line_get); - -void gpio_line_set(int line, int value) -{ - unsigned int data_register; - unsigned long flags; - unsigned char v; - - data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]); - - local_irq_save(flags); - if (value == EP93XX_GPIO_HIGH) { - v = __raw_readb(data_register); - v |= 1 << (line & 7); - __raw_writeb(v, data_register); - } else if (value == EP93XX_GPIO_LOW) { - v = __raw_readb(data_register); - v &= ~(1 << (line & 7)); - __raw_writeb(v, data_register); - } - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_line_set); - - -/************************************************************************* - * EP93xx IRQ handling - *************************************************************************/ -static void ep93xx_gpio_ab_irq_handler(unsigned int irq, - struct irqdesc *desc, struct pt_regs *regs) -{ - unsigned char status; - int i; - - status = __raw_readb(EP93XX_GPIO_A_INT_STATUS); - for (i = 0; i < 8; i++) { - if (status & (1 << i)) { - desc = irq_desc + IRQ_EP93XX_GPIO(0) + i; - desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc, regs); - } - } - - status = __raw_readb(EP93XX_GPIO_B_INT_STATUS); - for (i = 0; i < 8; i++) { - if (status & (1 << i)) { - desc = irq_desc + IRQ_EP93XX_GPIO(8) + i; - desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc, regs); - } - } -} - -static void ep93xx_gpio_ab_irq_mask_ack(unsigned int irq) -{ - int line = irq - IRQ_EP93XX_GPIO(0); - int port = line >> 3; - - gpio_int_enable[port] &= ~(1 << (line & 7)); - update_gpio_ab_int_params(port); - - if (line >> 3) { - __raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK); - } else { - __raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK); - } -} - -static void ep93xx_gpio_ab_irq_mask(unsigned int irq) -{ - int line = irq - IRQ_EP93XX_GPIO(0); - int port = line >> 3; - - gpio_int_enable[port] &= ~(1 << (line & 7)); - update_gpio_ab_int_params(port); -} - -static void ep93xx_gpio_ab_irq_unmask(unsigned int irq) -{ - int line = irq - IRQ_EP93XX_GPIO(0); - int port = line >> 3; - - gpio_int_enable[port] |= 1 << (line & 7); - update_gpio_ab_int_params(port); -} - - -/* - * gpio_int_type1 controls whether the interrupt is level (0) or - * edge (1) triggered, while gpio_int_type2 controls whether it - * triggers on low/falling (0) or high/rising (1). - */ -static int ep93xx_gpio_ab_irq_type(unsigned int irq, unsigned int type) -{ - int port; - int line; - - line = irq - IRQ_EP93XX_GPIO(0); - gpio_line_config(line, GPIO_IN); - - port = line >> 3; - line &= 7; - - if (type & IRQT_RISING) { - gpio_int_type1[port] |= 1 << line; - gpio_int_type2[port] |= 1 << line; - } else if (type & IRQT_FALLING) { - gpio_int_type1[port] |= 1 << line; - gpio_int_type2[port] &= ~(1 << line); - } else if (type & IRQT_HIGH) { - gpio_int_type1[port] &= ~(1 << line); - gpio_int_type2[port] |= 1 << line; - } else if (type & IRQT_LOW) { - gpio_int_type1[port] &= ~(1 << line); - gpio_int_type2[port] &= ~(1 << line); - } - update_gpio_ab_int_params(port); - - return 0; -} - -static struct irqchip ep93xx_gpio_ab_irq_chip = { - .ack = ep93xx_gpio_ab_irq_mask_ack, - .mask = ep93xx_gpio_ab_irq_mask, - .unmask = ep93xx_gpio_ab_irq_unmask, - .set_type = ep93xx_gpio_ab_irq_type, -}; - - -void __init ep93xx_init_irq(void) -{ - int irq; - - vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK); - vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK); - - for (irq = IRQ_EP93XX_GPIO(0) ; irq <= IRQ_EP93XX_GPIO(15); irq++) { - set_irq_chip(irq, &ep93xx_gpio_ab_irq_chip); - set_irq_handler(irq, do_level_IRQ); - set_irq_flags(irq, IRQF_VALID); - } - set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); -} - - -/************************************************************************* - * EP93xx peripheral handling - *************************************************************************/ -#define EP93XX_UART_MCR_OFFSET (0x0100) - -static void ep93xx_uart_set_mctrl(struct amba_device *dev, - void __iomem *base, unsigned int mctrl) -{ - unsigned int mcr; - - mcr = 0; - if (!(mctrl & TIOCM_RTS)) - mcr |= 2; - if (!(mctrl & TIOCM_DTR)) - mcr |= 1; - - __raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET); -} - -static struct amba_pl010_data ep93xx_uart_data = { - .set_mctrl = ep93xx_uart_set_mctrl, -}; - -static struct amba_device uart1_device = { - .dev = { - .bus_id = "apb:uart1", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART1_PHYS_BASE, - .end = EP93XX_UART1_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART1, NO_IRQ }, - .periphid = 0x00041010, -}; - -static struct amba_device uart2_device = { - .dev = { - .bus_id = "apb:uart2", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART2_PHYS_BASE, - .end = EP93XX_UART2_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART2, NO_IRQ }, - .periphid = 0x00041010, -}; - -static struct amba_device uart3_device = { - .dev = { - .bus_id = "apb:uart3", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART3_PHYS_BASE, - .end = EP93XX_UART3_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART3, NO_IRQ }, - .periphid = 0x00041010, -}; - - -static struct platform_device ep93xx_rtc_device = { - .name = "ep93xx-rtc", - .id = -1, - .num_resources = 0, -}; - - -void __init ep93xx_init_devices(void) -{ - unsigned int v; - - /* - * Disallow access to MaverickCrunch initially. - */ - v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); - v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; - __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); - __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG); - - amba_device_register(&uart1_device, &iomem_resource); - amba_device_register(&uart2_device, &iomem_resource); - amba_device_register(&uart3_device, &iomem_resource); - - platform_device_register(&ep93xx_rtc_device); -} diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c deleted file mode 100644 index d18fcb1a2..000000000 --- a/arch/arm/mach-ep93xx/gesbc9312.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * arch/arm/mach-ep93xx/gesbc9312.c - * Glomation GESBC-9312-sx support. - * - * Copyright (C) 2006 Lennert Buytenhek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void __init gesbc9312_init_machine(void) -{ - ep93xx_init_devices(); - physmap_configure(0x60000000, 0x00800000, 4, NULL); -} - -MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx") - /* Maintainer: Lennert Buytenhek */ - .phys_io = EP93XX_APB_PHYS_BASE, - .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .map_io = ep93xx_map_io, - .init_irq = ep93xx_init_irq, - .timer = &ep93xx_timer, - .init_machine = gesbc9312_init_machine, -MACHINE_END diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c deleted file mode 100644 index e24566b88..000000000 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * arch/arm/mach-ep93xx/ts72xx.c - * Technologic Systems TS72xx SBC support. - * - * Copyright (C) 2006 Lennert Buytenhek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct map_desc ts72xx_io_desc[] __initdata = { - { - .virtual = TS72XX_MODEL_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_MODEL_PHYS_BASE), - .length = TS72XX_MODEL_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_OPTIONS_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE), - .length = TS72XX_OPTIONS_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_OPTIONS2_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE), - .length = TS72XX_OPTIONS2_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_RTC_INDEX_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE), - .length = TS72XX_RTC_INDEX_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_RTC_DATA_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE), - .length = TS72XX_RTC_DATA_SIZE, - .type = MT_DEVICE, - } -}; - -static struct map_desc ts72xx_nand_io_desc[] __initdata = { - { - .virtual = TS72XX_NAND_DATA_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE), - .length = TS72XX_NAND_DATA_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE), - .length = TS72XX_NAND_CONTROL_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE), - .length = TS72XX_NAND_BUSY_SIZE, - .type = MT_DEVICE, - } -}; - -static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = { - { - .virtual = TS72XX_NAND_DATA_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE), - .length = TS72XX_NAND_DATA_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE), - .length = TS72XX_NAND_CONTROL_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE), - .length = TS72XX_NAND_BUSY_SIZE, - .type = MT_DEVICE, - } -}; - -static void __init ts72xx_map_io(void) -{ - ep93xx_map_io(); - iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc)); - - /* - * The TS-7200 has NOR flash, the other models have NAND flash. - */ - if (!board_is_ts7200()) { - if (is_ts9420_installed()) { - iotable_init(ts72xx_alternate_nand_io_desc, - ARRAY_SIZE(ts72xx_alternate_nand_io_desc)); - } else { - iotable_init(ts72xx_nand_io_desc, - ARRAY_SIZE(ts72xx_nand_io_desc)); - } - } -} - -static unsigned char ts72xx_rtc_readbyte(unsigned long addr) -{ - __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); - return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE); -} - -static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr) -{ - __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); - __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE); -} - -static struct m48t86_ops ts72xx_rtc_ops = { - .readbyte = ts72xx_rtc_readbyte, - .writebyte = ts72xx_rtc_writebyte, -}; - -static struct platform_device ts72xx_rtc_device = { - .name = "rtc-m48t86", - .id = -1, - .dev = { - .platform_data = &ts72xx_rtc_ops, - }, - .num_resources = 0, -}; - -static void __init ts72xx_init_machine(void) -{ - ep93xx_init_devices(); - if (board_is_ts7200()) - physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL); - platform_device_register(&ts72xx_rtc_device); -} - -MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") - /* Maintainer: Lennert Buytenhek */ - .phys_io = EP93XX_APB_PHYS_BASE, - .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .map_io = ts72xx_map_io, - .init_irq = ep93xx_init_irq, - .timer = &ep93xx_timer, - .init_machine = ts72xx_init_machine, -MACHINE_END diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 5dace2597..e79884eea 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -255,12 +255,14 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys) if (nr || !footbridge_cfn_mode()) return 0; - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); if (!res) { printk("out of memory for root bus resources"); return 0; } + memset(res, 0, sizeof(struct resource) * 2); + res[0].flags = IORESOURCE_MEM; res[0].name = "Footbridge non-prefetch"; res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c index 4ca51dcf1..71a59e196 100644 --- a/arch/arm/mach-imx/dma.c +++ b/arch/arm/mach-imx/dma.c @@ -7,18 +7,11 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * 2004-03-03 Sascha Hauer + * 03/03/2004 Sascha Hauer * initial version heavily inspired by * linux/arch/arm/mach-pxa/dma.c - * - * 2005-04-17 Pavel Pisa - * Changed to support scatter gather DMA - * by taking Russell's code from RiscPC - * */ -#undef DEBUG - #include #include #include @@ -29,368 +22,69 @@ #include #include #include -#include - -struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS]; - -/* - * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation - * @dma_ch: i.MX DMA channel number - * @lastcount: number of bytes transferred during last transfer - * - * Functions prepares DMA controller for next sg data chunk transfer. - * The @lastcount argument informs function about number of bytes transferred - * during last block. Zero value can be used for @lastcount to setup DMA - * for the first chunk. - */ -static inline int imx_dma_sg_next(imx_dmach_t dma_ch, unsigned int lastcount) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; - unsigned int nextcount; - unsigned int nextaddr; - - if (!imxdma->name) { - printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __FUNCTION__, dma_ch); - return 0; - } - - imxdma->resbytes -= lastcount; - - if (!imxdma->sg) { - pr_debug("imxdma%d: no sg data\n", dma_ch); - return 0; - } - - imxdma->sgbc += lastcount; - if ((imxdma->sgbc >= imxdma->sg->length) || !imxdma->resbytes) { - if ((imxdma->sgcount <= 1) || !imxdma->resbytes) { - pr_debug("imxdma%d: sg transfer limit reached\n", - dma_ch); - imxdma->sgcount=0; - imxdma->sg = NULL; - return 0; - } else { - imxdma->sgcount--; - imxdma->sg++; - imxdma->sgbc = 0; - } - } - nextcount = imxdma->sg->length - imxdma->sgbc; - nextaddr = imxdma->sg->dma_address + imxdma->sgbc; - - if(imxdma->resbytes < nextcount) - nextcount = imxdma->resbytes; - - if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ) - DAR(dma_ch) = nextaddr; - else - SAR(dma_ch) = nextaddr; - - CNTR(dma_ch) = nextcount; - pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, size 0x%08x\n", - dma_ch, DAR(dma_ch), SAR(dma_ch), CNTR(dma_ch)); - - return nextcount; -} - -/* - * imx_dma_setup_sg_base - scatter-gather DMA emulation - * @dma_ch: i.MX DMA channel number - * @sg: pointer to the scatter-gather list/vector - * @sgcount: scatter-gather list hungs count - * - * Functions sets up i.MX DMA state for emulated scatter-gather transfer - * and sets up channel registers to be ready for the first chunk - */ -static int -imx_dma_setup_sg_base(imx_dmach_t dma_ch, - struct scatterlist *sg, unsigned int sgcount) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; - - imxdma->sg = sg; - imxdma->sgcount = sgcount; - imxdma->sgbc = 0; - return imx_dma_sg_next(dma_ch, 0); -} - -/** - * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from device transfer - * @dma_ch: i.MX DMA channel number - * @dma_address: the DMA/physical memory address of the linear data block - * to transfer - * @dma_length: length of the data block in bytes - * @dev_addr: physical device port address - * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory - * or %DMA_MODE_WRITE from memory to the device - * - * The function setups DMA channel source and destination addresses for transfer - * specified by provided parameters. The scatter-gather emulation is disabled, - * because linear data block - * form the physical address range is transfered. - * Return value: if incorrect parameters are provided -%EINVAL. - * Zero indicates success. - */ -int -imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address, - unsigned int dma_length, unsigned int dev_addr, - dmamode_t dmamode) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; - - imxdma->sg = NULL; - imxdma->sgcount = 0; - imxdma->dma_mode = dmamode; - imxdma->resbytes = dma_length; - - if (!dma_address) { - printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n", - dma_ch); - return -EINVAL; - } - - if (!dma_length) { - printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n", - dma_ch); - return -EINVAL; - } - - if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) { - pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for read\n", - dma_ch, (unsigned int)dma_address, dma_length, - dev_addr); - SAR(dma_ch) = dev_addr; - DAR(dma_ch) = (unsigned int)dma_address; - } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) { - pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for write\n", - dma_ch, (unsigned int)dma_address, dma_length, - dev_addr); - SAR(dma_ch) = (unsigned int)dma_address; - DAR(dma_ch) = dev_addr; - } else { - printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n", - dma_ch); - return -EINVAL; - } - - CNTR(dma_ch) = dma_length; - - return 0; -} - -/** - * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer - * @dma_ch: i.MX DMA channel number - * @sg: pointer to the scatter-gather list/vector - * @sgcount: scatter-gather list hungs count - * @dma_length: total length of the transfer request in bytes - * @dev_addr: physical device port address - * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory - * or %DMA_MODE_WRITE from memory to the device - * - * The function setups DMA channel state and registers to be ready for transfer - * specified by provided parameters. The scatter-gather emulation is set up - * according to the parameters. - * - * The full preparation of the transfer requires setup of more register - * by the caller before imx_dma_enable() can be called. - * - * %BLR(dma_ch) holds transfer burst length in bytes, 0 means 64 bytes - * - * %RSSR(dma_ch) has to be set to the DMA request line source %DMA_REQ_xxx - * - * %CCR(dma_ch) has to specify transfer parameters, the next settings is typical - * for linear or simple scatter-gather transfers if %DMA_MODE_READ is specified - * - * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x - * - * The typical setup for %DMA_MODE_WRITE is specified by next options combination - * - * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x - * - * Be carefull there and do not mistakenly mix source and target device - * port sizes constants, they are really different: - * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32, - * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32 - * - * Return value: if incorrect parameters are provided -%EINVAL. - * Zero indicates success. - */ -int -imx_dma_setup_sg(imx_dmach_t dma_ch, - struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length, - unsigned int dev_addr, dmamode_t dmamode) -{ - int res; - struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; - - imxdma->sg = NULL; - imxdma->sgcount = 0; - imxdma->dma_mode = dmamode; - imxdma->resbytes = dma_length; - - if (!sg || !sgcount) { - printk(KERN_ERR "imxdma%d: imx_dma_setup_sg epty sg list\n", - dma_ch); - return -EINVAL; - } - - if (!sg->length) { - printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n", - dma_ch); - return -EINVAL; - } - - if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) { - pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for read\n", - dma_ch, sg, sgcount, dma_length, dev_addr); - SAR(dma_ch) = dev_addr; - } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) { - pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for write\n", - dma_ch, sg, sgcount, dma_length, dev_addr); - DAR(dma_ch) = dev_addr; - } else { - printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n", - dma_ch); - return -EINVAL; - } - res = imx_dma_setup_sg_base(dma_ch, sg, sgcount); - if (res <= 0) { - printk(KERN_ERR "imxdma%d: no sg chunk ready\n", dma_ch); - return -EINVAL; - } +static struct dma_channel { + char *name; + void (*irq_handler) (int, void *, struct pt_regs *); + void (*err_handler) (int, void *, struct pt_regs *); + void *data; +} dma_channels[11]; - return 0; -} - -/** - * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification handlers - * @dma_ch: i.MX DMA channel number - * @irq_handler: the pointer to the function called if the transfer - * ends successfully - * @err_handler: the pointer to the function called if the premature - * end caused by error occurs - * @data: user specified value to be passed to the handlers - */ +/* set err_handler to NULL to have the standard info-only error handler */ int -imx_dma_setup_handlers(imx_dmach_t dma_ch, - void (*irq_handler) (int, void *, struct pt_regs *), - void (*err_handler) (int, void *, struct pt_regs *), - void *data) +imx_request_dma(char *name, imx_dma_prio prio, + void (*irq_handler) (int, void *, struct pt_regs *), + void (*err_handler) (int, void *, struct pt_regs *), void *data) { - struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; unsigned long flags; + int i, found = 0; - if (!imxdma->name) { - printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __FUNCTION__, dma_ch); - return -ENODEV; - } + /* basic sanity checks */ + if (!name || !irq_handler) + return -EINVAL; local_irq_save(flags); - DISR = (1 << dma_ch); - imxdma->irq_handler = irq_handler; - imxdma->err_handler = err_handler; - imxdma->data = data; - local_irq_restore(flags); - return 0; -} - -/** - * imx_dma_enable - function to start i.MX DMA channel operation - * @dma_ch: i.MX DMA channel number - * - * The channel has to be allocated by driver through imx_dma_request() - * or imx_dma_request_by_prio() function. - * The transfer parameters has to be set to the channel registers through - * call of the imx_dma_setup_single() or imx_dma_setup_sg() function - * and registers %BLR(dma_ch), %RSSR(dma_ch) and %CCR(dma_ch) has to - * be set prior this function call by the channel user. - */ -void imx_dma_enable(imx_dmach_t dma_ch) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; - unsigned long flags; - pr_debug("imxdma%d: imx_dma_enable\n", dma_ch); - - if (!imxdma->name) { - printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __FUNCTION__, dma_ch); - return; + /* try grabbing a DMA channel with the requested priority */ + for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) { + if (!dma_channels[i].name) { + found = 1; + break; + } } - local_irq_save(flags); - DISR = (1 << dma_ch); - DIMR &= ~(1 << dma_ch); - CCR(dma_ch) |= CCR_CEN; - local_irq_restore(flags); -} - -/** - * imx_dma_disable - stop, finish i.MX DMA channel operatin - * @dma_ch: i.MX DMA channel number - */ -void imx_dma_disable(imx_dmach_t dma_ch) -{ - unsigned long flags; - - pr_debug("imxdma%d: imx_dma_disable\n", dma_ch); - - local_irq_save(flags); - DIMR |= (1 << dma_ch); - CCR(dma_ch) &= ~CCR_CEN; - DISR = (1 << dma_ch); - local_irq_restore(flags); -} - -/** - * imx_dma_request - request/allocate specified channel number - * @dma_ch: i.MX DMA channel number - * @name: the driver/caller own non-%NULL identification - */ -int imx_dma_request(imx_dmach_t dma_ch, const char *name) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; - unsigned long flags; - - /* basic sanity checks */ - if (!name) - return -EINVAL; - - if (dma_ch >= IMX_DMA_CHANNELS) { - printk(KERN_CRIT "%s: called for non-existed channel %d\n", - __FUNCTION__, dma_ch); - return -EINVAL; + if (!found) { + /* requested prio group is full, try hier priorities */ + for (i = prio - 1; i >= 0; i--) { + if (!dma_channels[i].name) { + found = 1; + break; + } + } } - local_irq_save(flags); - if (imxdma->name) { - local_irq_restore(flags); - return -ENODEV; + if (found) { + DIMR &= ~(1 << i); + dma_channels[i].name = name; + dma_channels[i].irq_handler = irq_handler; + dma_channels[i].err_handler = err_handler; + dma_channels[i].data = data; + } else { + printk(KERN_WARNING "No more available DMA channels for %s\n", + name); + i = -ENODEV; } - imxdma->name = name; - imxdma->irq_handler = NULL; - imxdma->err_handler = NULL; - imxdma->data = NULL; - imxdma->sg = NULL; local_irq_restore(flags); - return 0; + return i; } -/** - * imx_dma_free - release previously acquired channel - * @dma_ch: i.MX DMA channel number - */ -void imx_dma_free(imx_dmach_t dma_ch) +void +imx_free_dma(int dma_ch) { unsigned long flags; - struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; - if (!imxdma->name) { + if (!dma_channels[dma_ch].name) { printk(KERN_CRIT "%s: trying to free channel %d which is already freed\n", __FUNCTION__, dma_ch); @@ -398,84 +92,27 @@ void imx_dma_free(imx_dmach_t dma_ch) } local_irq_save(flags); - /* Disable interrupts */ - DIMR |= (1 << dma_ch); - CCR(dma_ch) &= ~CCR_CEN; - imxdma->name = NULL; + DIMR &= ~(1 << dma_ch); + dma_channels[dma_ch].name = NULL; local_irq_restore(flags); } -/** - * imx_dma_request_by_prio - find and request some of free channels best suiting requested priority - * @dma_ch: i.MX DMA channel number - * @name: the driver/caller own non-%NULL identification - * @prio: one of the hardware distinguished priority level: - * %DMA_PRIO_HIGH, %DMA_PRIO_MEDIUM, %DMA_PRIO_LOW - * - * This function tries to find free channel in the specified priority group - * if the priority cannot be achieved it tries to look for free channel - * in the higher and then even lower priority groups. - * - * Return value: If there is no free channel to allocate, -%ENODEV is returned. - * Zero value indicates successful channel allocation. - */ -int -imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name, - imx_dma_prio prio) -{ - int i; - int best; - - switch (prio) { - case (DMA_PRIO_HIGH): - best = 8; - break; - case (DMA_PRIO_MEDIUM): - best = 4; - break; - case (DMA_PRIO_LOW): - default: - best = 0; - break; - } - - for (i = best; i < IMX_DMA_CHANNELS; i++) { - if (!imx_dma_request(i, name)) { - *pdma_ch = i; - return 0; - } - } - - for (i = best - 1; i >= 0; i--) { - if (!imx_dma_request(i, name)) { - *pdma_ch = i; - return 0; - } - } - - printk(KERN_ERR "%s: no free DMA channel found\n", __FUNCTION__); - - return -ENODEV; -} - -static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t +dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) { int i, disr = DISR; - struct imx_dma_channel *channel; + struct dma_channel *channel; unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR; DISR = disr; - for (i = 0; i < IMX_DMA_CHANNELS; i++) { - channel = &imx_dma_channels[i]; + for (i = 0; i < 11; i++) { + channel = &dma_channels[i]; - if ((err_mask & 1 << i) && channel->name - && channel->err_handler) { + if ( (err_mask & 1<name && channel->err_handler) { channel->err_handler(i, channel->data, regs); continue; } - imx_dma_channels[i].sg = NULL; - if (DBTOSR & (1 << i)) { printk(KERN_WARNING "Burst timeout on channel %d (%s)\n", @@ -504,27 +141,17 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t +dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { int i, disr = DISR; - pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n", - disr); - DISR = disr; - for (i = 0; i < IMX_DMA_CHANNELS; i++) { + for (i = 0; i < 11; i++) { if (disr & (1 << i)) { - struct imx_dma_channel *channel = &imx_dma_channels[i]; - if (channel->name) { - if (imx_dma_sg_next(i, CNTR(i))) { - CCR(i) &= ~CCR_CEN; - mb(); - CCR(i) |= CCR_CEN; - } else { - if (channel->irq_handler) - channel->irq_handler(i, - channel->data, regs); - } + struct dma_channel *channel = &dma_channels[i]; + if (channel->name && channel->irq_handler) { + channel->irq_handler(i, channel->data, regs); } else { /* * IRQ for an unregistered DMA channel: @@ -538,10 +165,10 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -static int __init imx_dma_init(void) +static int __init +imx_dma_init(void) { int ret; - int i; /* reset DMA module */ DCR = DCR_DRST; @@ -562,27 +189,15 @@ static int __init imx_dma_init(void) DCR = DCR_DEN; /* clear all interrupts */ - DISR = (1 << IMX_DMA_CHANNELS) - 1; + DISR = 0x3ff; /* enable interrupts */ - DIMR = (1 << IMX_DMA_CHANNELS) - 1; - - for (i = 0; i < IMX_DMA_CHANNELS; i++) { - imx_dma_channels[i].sg = NULL; - imx_dma_channels[i].dma_num = i; - } + DIMR = 0; return ret; } arch_initcall(imx_dma_init); -EXPORT_SYMBOL(imx_dma_setup_single); -EXPORT_SYMBOL(imx_dma_setup_sg); -EXPORT_SYMBOL(imx_dma_setup_handlers); -EXPORT_SYMBOL(imx_dma_enable); -EXPORT_SYMBOL(imx_dma_disable); -EXPORT_SYMBOL(imx_dma_request); -EXPORT_SYMBOL(imx_dma_free); -EXPORT_SYMBOL(imx_dma_request_by_prio); -EXPORT_SYMBOL(imx_dma_channels); +EXPORT_SYMBOL(imx_request_dma); +EXPORT_SYMBOL(imx_free_dma); diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 12ea58a3b..37613ad68 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c @@ -33,7 +33,6 @@ #include #include -#include void imx_gpio_mode(int gpio_mode) { @@ -176,24 +175,62 @@ static struct resource imx_mmc_resources[] = { }, }; -static u64 imxmmmc_dmamask = 0xffffffffUL; - static struct platform_device imx_mmc_device = { .name = "imx-mmc", .id = 0, - .dev = { - .dma_mask = &imxmmmc_dmamask, - .coherent_dma_mask = 0xffffffff, - }, .num_resources = ARRAY_SIZE(imx_mmc_resources), .resource = imx_mmc_resources, }; -void __init imx_set_mmc_info(struct imxmmc_platform_data *info) -{ - imx_mmc_device.dev.platform_data = info; -} -EXPORT_SYMBOL(imx_set_mmc_info); +static struct resource imx_uart1_resources[] = { + [0] = { + .start = 0x00206000, + .end = 0x002060FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = (UART1_MINT_RX), + .end = (UART1_MINT_RX), + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = (UART1_MINT_TX), + .end = (UART1_MINT_TX), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device imx_uart1_device = { + .name = "imx-uart", + .id = 0, + .num_resources = ARRAY_SIZE(imx_uart1_resources), + .resource = imx_uart1_resources, +}; + +static struct resource imx_uart2_resources[] = { + [0] = { + .start = 0x00207000, + .end = 0x002070FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = (UART2_MINT_RX), + .end = (UART2_MINT_RX), + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = (UART2_MINT_TX), + .end = (UART2_MINT_TX), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device imx_uart2_device = { + .name = "imx-uart", + .id = 1, + .num_resources = ARRAY_SIZE(imx_uart2_resources), + .resource = imx_uart2_resources, +}; static struct imxfb_mach_info imx_fb_info; @@ -233,6 +270,8 @@ static struct platform_device imxfb_device = { static struct platform_device *devices[] __initdata = { &imx_mmc_device, &imxfb_device, + &imx_uart1_device, + &imx_uart2_device, }; static struct map_desc imx_io_desc[] __initdata = { diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c index a5de5f1da..eeb8a6d4a 100644 --- a/arch/arm/mach-imx/irq.c +++ b/arch/arm/mach-imx/irq.c @@ -127,7 +127,7 @@ static void imx_gpio_ack_irq(unsigned int irq) { DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); - ISR(IRQ_TO_REG(irq)) = 1 << ((irq - IRQ_GPIOA(0)) % 32); + ISR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32); } static void diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index da893c80d..8ab1b0402 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -25,8 +25,6 @@ #include #include -#include -#include #include #include "generic.h" @@ -49,83 +47,9 @@ static struct platform_device cs89x0_device = { .resource = cs89x0_resources, }; -static struct imxuart_platform_data uart_pdata = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static struct resource imx_uart1_resources[] = { - [0] = { - .start = 0x00206000, - .end = 0x002060FF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = (UART1_MINT_RX), - .end = (UART1_MINT_RX), - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = (UART1_MINT_TX), - .end = (UART1_MINT_TX), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device imx_uart1_device = { - .name = "imx-uart", - .id = 0, - .num_resources = ARRAY_SIZE(imx_uart1_resources), - .resource = imx_uart1_resources, - .dev = { - .platform_data = &uart_pdata, - } -}; - -static struct resource imx_uart2_resources[] = { - [0] = { - .start = 0x00207000, - .end = 0x002070FF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = (UART2_MINT_RX), - .end = (UART2_MINT_RX), - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = (UART2_MINT_TX), - .end = (UART2_MINT_TX), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device imx_uart2_device = { - .name = "imx-uart", - .id = 1, - .num_resources = ARRAY_SIZE(imx_uart2_resources), - .resource = imx_uart2_resources, - .dev = { - .platform_data = &uart_pdata, - } -}; - static struct platform_device *devices[] __initdata = { &cs89x0_device, - &imx_uart1_device, - &imx_uart2_device, -}; - -#ifdef CONFIG_MMC_IMX -static int mx1ads_mmc_card_present(void) -{ - /* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */ - return (SSR(1) & (1 << 20) ? 0 : 1); -} - -static struct imxmmc_platform_data mx1ads_mmc_info = { - .card_present = mx1ads_mmc_card_present, }; -#endif static void __init mx1ads_init(void) @@ -133,22 +57,6 @@ mx1ads_init(void) #ifdef CONFIG_LEDS imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2); #endif -#ifdef CONFIG_MMC_IMX - /* SD/MMC card detect */ - imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20); - imx_set_mmc_info(&mx1ads_mmc_info); -#endif - - imx_gpio_mode(PC9_PF_UART1_CTS); - imx_gpio_mode(PC10_PF_UART1_RTS); - imx_gpio_mode(PC11_PF_UART1_TXD); - imx_gpio_mode(PC12_PF_UART1_RXD); - - imx_gpio_mode(PB28_PF_UART2_CTS); - imx_gpio_mode(PB29_PF_UART2_RTS); - imx_gpio_mode(PB30_PF_UART2_TXD); - imx_gpio_mode(PB31_PF_UART2_RXD); - platform_add_devices(devices, ARRAY_SIZE(devices)); } @@ -161,7 +69,7 @@ mx1ads_map_io(void) MACHINE_START(MX1ADS, "Motorola MX1ADS") /* Maintainer: Sascha Hauer, Pengutronix */ .phys_io = 0x00200000, - .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, .boot_params = 0x08000100, .map_io = mx1ads_map_io, .init_irq = imx_init_irq, diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 576a5e979..20071a276 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -15,9 +15,7 @@ #include #include #include -#include #include -#include #include #include @@ -30,8 +28,6 @@ #include "common.h" -static struct amba_pl010_data integrator_uart_data; - static struct amba_device rtc_device = { .dev = { .bus_id = "mb:15", @@ -48,7 +44,6 @@ static struct amba_device rtc_device = { static struct amba_device uart0_device = { .dev = { .bus_id = "mb:16", - .platform_data = &integrator_uart_data, }, .res = { .start = INTEGRATOR_UART0_BASE, @@ -62,7 +57,6 @@ static struct amba_device uart0_device = { static struct amba_device uart1_device = { .dev = { .bus_id = "mb:17", - .platform_data = &integrator_uart_data, }, .res = { .start = INTEGRATOR_UART1_BASE, @@ -121,46 +115,6 @@ static int __init integrator_init(void) arch_initcall(integrator_init); -/* - * On the Integrator platform, the port RTS and DTR are provided by - * bits in the following SC_CTRLS register bits: - * RTS DTR - * UART0 7 6 - * UART1 5 4 - */ -#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET) -#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET) - -static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl) -{ - unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask; - - if (dev == &uart0_device) { - rts_mask = 1 << 4; - dtr_mask = 1 << 5; - } else { - rts_mask = 1 << 6; - dtr_mask = 1 << 7; - } - - if (mctrl & TIOCM_RTS) - ctrlc |= rts_mask; - else - ctrls |= rts_mask; - - if (mctrl & TIOCM_DTR) - ctrlc |= dtr_mask; - else - ctrls |= dtr_mask; - - __raw_writel(ctrls, SC_CTRLS); - __raw_writel(ctrlc, SC_CTRLC); -} - -static struct amba_pl010_data integrator_uart_data = { - .set_mctrl = integrator_uart_set_mctrl, -}; - #define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET static DEFINE_SPINLOCK(cm_lock); diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 92d79fb39..a85d471c5 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -355,11 +355,12 @@ static int impd1_probe(struct lm_device *dev) if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers")) return -EBUSY; - impd1 = kzalloc(sizeof(struct impd1_module), GFP_KERNEL); + impd1 = kmalloc(sizeof(struct impd1_module), GFP_KERNEL); if (!impd1) { ret = -ENOMEM; goto release_lm; } + memset(impd1, 0, sizeof(struct impd1_module)); impd1->base = ioremap(dev->resource.start, SZ_4K); if (!impd1->base) { @@ -388,10 +389,12 @@ static int impd1_probe(struct lm_device *dev) pc_base = dev->resource.start + idev->offset; - d = kzalloc(sizeof(struct amba_device), GFP_KERNEL); + d = kmalloc(sizeof(struct amba_device), GFP_KERNEL); if (!d) continue; + memset(d, 0, sizeof(struct amba_device)); + snprintf(d->dev.bus_id, sizeof(d->dev.bus_id), "lm%x:%5.5lx", dev->id, idev->offset >> 12); diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 6d65c96eb..d8d3c2a5a 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -319,10 +319,12 @@ static void __init ap_init(void) if ((sc_dec & (16 << i)) == 0) continue; - lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); + lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL); if (!lmdev) continue; + memset(lmdev, 0, sizeof(struct lm_device)); + lmdev->resource.start = 0xc0000000 + 0x10000000 * i; lmdev->resource.end = lmdev->resource.start + 0x0fffffff; lmdev->resource.flags = IORESOURCE_MEM; diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 9f55f5ae1..a0724f2b2 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -232,6 +232,8 @@ static void __init intcp_init_irq(void) for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) { if (i == 11) i = 22; + if (i == IRQ_CP_CPPLDINT) + i++; if (i == 29) break; set_irq_chip(i, &pic_chip); @@ -257,7 +259,8 @@ static void __init intcp_init_irq(void) set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } - set_irq_chained_handler(IRQ_CP_CPPLDINT, sic_handle_irq); + set_irq_handler(IRQ_CP_CPPLDINT, sic_handle_irq); + pic_unmask_irq(IRQ_CP_CPPLDINT); } /* diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c index bc07f52a6..3c22c16b3 100644 --- a/arch/arm/mach-integrator/time.c +++ b/arch/arm/mach-integrator/time.c @@ -40,13 +40,13 @@ static int integrator_set_rtc(void) return 1; } -static int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm) +static int rtc_read_alarm(struct rtc_wkalrm *alrm) { rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); return 0; } -static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm) +static inline int rtc_set_alarm(struct rtc_wkalrm *alrm) { unsigned long time; int ret; @@ -62,7 +62,7 @@ static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm) return ret; } -static int integrator_rtc_read_time(struct rtc_time *tm) +static int rtc_read_time(struct rtc_time *tm) { rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); return 0; @@ -76,7 +76,7 @@ static int integrator_rtc_read_time(struct rtc_time *tm) * edge of the 1Hz clock, we must write the time one second * in advance. */ -static inline int integrator_rtc_set_time(struct rtc_time *tm) +static inline int rtc_set_time(struct rtc_time *tm) { unsigned long time; int ret; @@ -90,10 +90,10 @@ static inline int integrator_rtc_set_time(struct rtc_time *tm) static struct rtc_ops rtc_ops = { .owner = THIS_MODULE, - .read_time = integrator_rtc_read_time, - .set_time = integrator_rtc_set_time, - .read_alarm = integrator_rtc_read_alarm, - .set_alarm = integrator_rtc_set_alarm, + .read_time = rtc_read_time, + .set_time = rtc_set_time, + .read_alarm = rtc_read_alarm, + .set_alarm = rtc_set_alarm, }; static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id, diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index 7b7b6eea3..2d6abe5be 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -103,7 +103,7 @@ static struct plat_serial8250_port iop33x_uart1_data[] = { static struct platform_device iop33x_uart0 = { .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, + .id = 0, .dev.platform_data = iop33x_uart0_data, .num_resources = 2, .resource = iop33x_uart0_resources, @@ -111,7 +111,7 @@ static struct platform_device iop33x_uart0 = { static struct platform_device iop33x_uart1 = { .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM1, + .id = 1, .dev.platform_data = iop33x_uart1_data, .num_resources = 2, .resource = iop33x_uart1_resources, diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c index f3c6413fa..c6a973ba8 100644 --- a/arch/arm/mach-iop3xx/iq31244-pci.c +++ b/arch/arm/mach-iop3xx/iq31244-pci.c @@ -74,10 +74,12 @@ static int iq31244_setup(int nr, struct pci_sys_data *sys) if(nr != 0) return 0; - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); if (!res) panic("PCI: unable to alloc resources"); + memset(res, 0, sizeof(struct resource) * 2); + res[0].start = IOP321_PCI_LOWER_IO_VA; res[0].end = IOP321_PCI_UPPER_IO_VA; res[0].name = "IQ31244 PCI I/O Space"; diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c index d9758d3f6..802f6d091 100644 --- a/arch/arm/mach-iop3xx/iq80321-pci.c +++ b/arch/arm/mach-iop3xx/iq80321-pci.c @@ -68,10 +68,12 @@ static int iq80321_setup(int nr, struct pci_sys_data *sys) if(nr != 0) return 0; - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); if (!res) panic("PCI: unable to alloc resources"); + memset(res, 0, sizeof(struct resource) * 2); + res[0].start = IOP321_PCI_LOWER_IO_VA; res[0].end = IOP321_PCI_UPPER_IO_VA; res[0].name = "IQ80321 PCI I/O Space"; diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c index 40d861002..654e450a1 100644 --- a/arch/arm/mach-iop3xx/iq80331-pci.c +++ b/arch/arm/mach-iop3xx/iq80331-pci.c @@ -64,10 +64,12 @@ static int iq80331_setup(int nr, struct pci_sys_data *sys) if(nr != 0) return 0; - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); if (!res) panic("PCI: unable to alloc resources"); + memset(res, 0, sizeof(struct resource) * 2); + res[0].start = IOP331_PCI_LOWER_IO_VA; res[0].end = IOP331_PCI_UPPER_IO_VA; res[0].name = "IQ80331 PCI I/O Space"; diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c index b9807aa2a..65951ffe4 100644 --- a/arch/arm/mach-iop3xx/iq80332-pci.c +++ b/arch/arm/mach-iop3xx/iq80332-pci.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include diff --git a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig index 86f53f8cc..ecb58d834 100644 --- a/arch/arm/mach-ixp2000/Kconfig +++ b/arch/arm/mach-ixp2000/Kconfig @@ -43,17 +43,12 @@ config ARCH_IXDP2401 this platform, see . config ARCH_IXDP2801 - bool "Support Intel IXDP2801 and IXDP28x5" + bool "Support Intel IXDP2801" help Say 'Y' here if you want your kernel to support the Intel - IXDP2801/2805/2855 reference platforms. For more information on + IXDP2801 reference platform. For more information on this platform, see . -config MACH_IXDP28X5 - bool - depends on ARCH_IXDP2801 - default y - config ARCH_IXDP2X01 bool depends on ARCH_IXDP2401 || ARCH_IXDP2801 diff --git a/arch/arm/mach-ixp2000/Makefile b/arch/arm/mach-ixp2000/Makefile index 1e6139d42..9621aeb61 100644 --- a/arch/arm/mach-ixp2000/Makefile +++ b/arch/arm/mach-ixp2000/Makefile @@ -1,7 +1,7 @@ # # Makefile for the linux kernel. # -obj-y := core.o pci.o +obj-y := core.o pci.o uengine.o obj-m := obj-n := obj- := diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 6e8d504ac..cfd5bef31 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -288,6 +288,8 @@ void gpio_line_config(int line, int direction) local_irq_save(flags); if (direction == GPIO_OUT) { + irq_desc[line + IRQ_IXP2000_GPIO0].valid = 0; + /* if it's an output, it ain't an interrupt anymore */ GPIO_IRQ_falling_edge &= ~(1 << line); GPIO_IRQ_rising_edge &= ~(1 << line); @@ -349,6 +351,11 @@ static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type) GPIO_IRQ_level_high &= ~(1 << line); update_gpio_int_csrs(); + /* + * Finally, mark the corresponding IRQ as valid. + */ + irq_desc[irq].valid = 1; + return 0; } @@ -499,10 +506,14 @@ void __init ixp2000_init_irq(void) } set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler); + /* + * GPIO IRQs are invalid until someone sets the interrupt mode + * by calling set_irq_type(). + */ for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { set_irq_chip(irq, &ixp2000_GPIO_irq_chip); set_irq_handler(irq, do_level_IRQ); - set_irq_flags(irq, IRQF_VALID); + set_irq_flags(irq, 0); } set_irq_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler); diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 66915282a..150519fb3 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -133,7 +132,7 @@ void __init ixdp2x01_init_irq(void) /************************************************************************* - * IXDP2x01 memory map + * IXDP2x01 memory map and serial ports *************************************************************************/ static struct map_desc ixdp2x01_io_desc __initdata = { .virtual = IXDP2X01_VIRT_CPLD_BASE, @@ -142,78 +141,40 @@ static struct map_desc ixdp2x01_io_desc __initdata = { .type = MT_DEVICE }; -static void __init ixdp2x01_map_io(void) -{ - ixp2000_map_io(); - iotable_init(&ixdp2x01_io_desc, 1); -} - - -/************************************************************************* - * IXDP2x01 serial ports - *************************************************************************/ -static struct plat_serial8250_port ixdp2x01_serial_port1[] = { +static struct uart_port ixdp2x01_serial_ports[2] = { { + .membase = (char *)(IXDP2X01_UART1_VIRT_BASE), .mapbase = (unsigned long)IXDP2X01_UART1_PHYS_BASE, - .membase = (char *)IXDP2X01_UART1_VIRT_BASE, .irq = IRQ_IXDP2X01_UART1, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .flags = UPF_SKIP_TEST, .iotype = UPIO_MEM32, .regshift = 2, .uartclk = IXDP2X01_UART_CLK, - }, - { } -}; - -static struct resource ixdp2x01_uart_resource1 = { - .start = IXDP2X01_UART1_PHYS_BASE, - .end = IXDP2X01_UART1_PHYS_BASE + 0xffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ixdp2x01_serial_device1 = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM1, - .dev = { - .platform_data = ixdp2x01_serial_port1, - }, - .num_resources = 1, - .resource = &ixdp2x01_uart_resource1, -}; - -static struct plat_serial8250_port ixdp2x01_serial_port2[] = { - { + .line = 1, + .type = PORT_16550A, + .fifosize = 16 + }, { + .membase = (char *)(IXDP2X01_UART2_VIRT_BASE), .mapbase = (unsigned long)IXDP2X01_UART2_PHYS_BASE, - .membase = (char *)IXDP2X01_UART2_VIRT_BASE, .irq = IRQ_IXDP2X01_UART2, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .flags = UPF_SKIP_TEST, .iotype = UPIO_MEM32, .regshift = 2, .uartclk = IXDP2X01_UART_CLK, + .line = 2, + .type = PORT_16550A, + .fifosize = 16 }, - { } }; -static struct resource ixdp2x01_uart_resource2 = { - .start = IXDP2X01_UART2_PHYS_BASE, - .end = IXDP2X01_UART2_PHYS_BASE + 0xffff, - .flags = IORESOURCE_MEM, -}; +static void __init ixdp2x01_map_io(void) +{ + ixp2000_map_io(); -static struct platform_device ixdp2x01_serial_device2 = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM2, - .dev = { - .platform_data = ixdp2x01_serial_port2, - }, - .num_resources = 1, - .resource = &ixdp2x01_uart_resource2, -}; + iotable_init(&ixdp2x01_io_desc, 1); -static void ixdp2x01_uart_init(void) -{ - platform_device_register(&ixdp2x01_serial_device1); - platform_device_register(&ixdp2x01_serial_device2); + early_serial_setup(&ixdp2x01_serial_ports[0]); + early_serial_setup(&ixdp2x01_serial_ports[1]); } @@ -323,7 +284,7 @@ static int ixdp2x01_pci_setup(int nr, struct pci_sys_data *sys) { sys->mem_offset = 0xe0000000; - if (machine_is_ixdp2801() || machine_is_ixdp28x5()) + if (machine_is_ixdp2801()) sys->mem_offset -= ((*IXP2000_PCI_ADDR_EXT & 0xE000) << 16); return ixp2000_pci_setup(nr, sys); @@ -339,8 +300,7 @@ struct hw_pci ixdp2x01_pci __initdata = { int __init ixdp2x01_pci_init(void) { - if (machine_is_ixdp2401() || machine_is_ixdp2801() ||\ - machine_is_ixdp28x5()) + if (machine_is_ixdp2401() || machine_is_ixdp2801()) pci_common_init(&ixdp2x01_pci); return 0; @@ -413,7 +373,6 @@ static void __init ixdp2x01_init_machine(void) platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices)); ixp2000_uart_init(); - ixdp2x01_uart_init(); } @@ -441,21 +400,6 @@ MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") .timer = &ixdp2x01_timer, .init_machine = ixdp2x01_init_machine, MACHINE_END - -/* - * IXDP28x5 is basically an IXDP2801 with a different CPU but Intel - * changed the machine ID in the bootloader - */ -MACHINE_START(IXDP28X5, "Intel IXDP2805/2855 Development Platform") - /* Maintainer: MontaVista Software, Inc. */ - .phys_io = IXP2000_UART_PHYS_BASE, - .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .map_io = ixdp2x01_map_io, - .init_irq = ixdp2x01_init_irq, - .timer = &ixdp2x01_timer, - .init_machine = ixdp2x01_init_machine, -MACHINE_END #endif diff --git a/arch/arm/mach-ixp23xx/Kconfig b/arch/arm/mach-ixp23xx/Kconfig deleted file mode 100644 index 982670ec3..000000000 --- a/arch/arm/mach-ixp23xx/Kconfig +++ /dev/null @@ -1,25 +0,0 @@ -if ARCH_IXP23XX - -config ARCH_SUPPORTS_BIG_ENDIAN - bool - default y - -menu "Intel IXP23xx Implementation Options" - -comment "IXP23xx Platforms" - -config MACH_ESPRESSO - bool "Support IP Fabrics Double Espresso platform" - help - -config MACH_IXDP2351 - bool "Support Intel IXDP2351 platform" - help - -config MACH_ROADRUNNER - bool "Support ADI RoadRunner platform" - help - -endmenu - -endif diff --git a/arch/arm/mach-ixp23xx/Makefile b/arch/arm/mach-ixp23xx/Makefile deleted file mode 100644 index 288b371b6..000000000 --- a/arch/arm/mach-ixp23xx/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the linux kernel. -# -obj-y := core.o pci.o -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_MACH_ESPRESSO) += espresso.o -obj-$(CONFIG_MACH_IXDP2351) += ixdp2351.o -obj-$(CONFIG_MACH_ROADRUNNER) += roadrunner.o diff --git a/arch/arm/mach-ixp23xx/Makefile.boot b/arch/arm/mach-ixp23xx/Makefile.boot deleted file mode 100644 index d5561ad15..000000000 --- a/arch/arm/mach-ixp23xx/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y := 0x00008000 -params_phys-y := 0x00000100 diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c deleted file mode 100644 index affd1d5d7..000000000 --- a/arch/arm/mach-ixp23xx/core.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * arch/arm/mach-ixp23xx/core.c - * - * Core routines for IXP23xx chips - * - * Author: Deepak Saxena - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * Based on 2.4 code Copyright 2004 (c) Intel Corporation - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -/************************************************************************* - * Chip specific mappings shared by all IXP23xx systems - *************************************************************************/ -static struct map_desc ixp23xx_io_desc[] __initdata = { - { /* XSI-CPP CSRs */ - .virtual = IXP23XX_XSI2CPP_CSR_VIRT, - .pfn = __phys_to_pfn(IXP23XX_XSI2CPP_CSR_PHYS), - .length = IXP23XX_XSI2CPP_CSR_SIZE, - .type = MT_DEVICE, - }, { /* Expansion Bus Config */ - .virtual = IXP23XX_EXP_CFG_VIRT, - .pfn = __phys_to_pfn(IXP23XX_EXP_CFG_PHYS), - .length = IXP23XX_EXP_CFG_SIZE, - .type = MT_DEVICE, - }, { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACS,.... */ - .virtual = IXP23XX_PERIPHERAL_VIRT, - .pfn = __phys_to_pfn(IXP23XX_PERIPHERAL_PHYS), - .length = IXP23XX_PERIPHERAL_SIZE, - .type = MT_DEVICE, - }, { /* CAP CSRs */ - .virtual = IXP23XX_CAP_CSR_VIRT, - .pfn = __phys_to_pfn(IXP23XX_CAP_CSR_PHYS), - .length = IXP23XX_CAP_CSR_SIZE, - .type = MT_DEVICE, - }, { /* MSF CSRs */ - .virtual = IXP23XX_MSF_CSR_VIRT, - .pfn = __phys_to_pfn(IXP23XX_MSF_CSR_PHYS), - .length = IXP23XX_MSF_CSR_SIZE, - .type = MT_DEVICE, - }, { /* PCI I/O Space */ - .virtual = IXP23XX_PCI_IO_VIRT, - .pfn = __phys_to_pfn(IXP23XX_PCI_IO_PHYS), - .length = IXP23XX_PCI_IO_SIZE, - .type = MT_DEVICE, - }, { /* PCI Config Space */ - .virtual = IXP23XX_PCI_CFG_VIRT, - .pfn = __phys_to_pfn(IXP23XX_PCI_CFG_PHYS), - .length = IXP23XX_PCI_CFG_SIZE, - .type = MT_DEVICE, - }, { /* PCI local CFG CSRs */ - .virtual = IXP23XX_PCI_CREG_VIRT, - .pfn = __phys_to_pfn(IXP23XX_PCI_CREG_PHYS), - .length = IXP23XX_PCI_CREG_SIZE, - .type = MT_DEVICE, - }, { /* PCI MEM Space */ - .virtual = IXP23XX_PCI_MEM_VIRT, - .pfn = __phys_to_pfn(IXP23XX_PCI_MEM_PHYS), - .length = IXP23XX_PCI_MEM_SIZE, - .type = MT_DEVICE, - } -}; - -void __init ixp23xx_map_io(void) -{ - iotable_init(ixp23xx_io_desc, ARRAY_SIZE(ixp23xx_io_desc)); -} - - -/*************************************************************************** - * IXP23xx Interrupt Handling - ***************************************************************************/ -enum ixp23xx_irq_type { - IXP23XX_IRQ_LEVEL, IXP23XX_IRQ_EDGE -}; - -static void ixp23xx_config_irq(unsigned int, enum ixp23xx_irq_type); - -static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type) -{ - int line = irq - IRQ_IXP23XX_GPIO6 + 6; - u32 int_style; - enum ixp23xx_irq_type irq_type; - volatile u32 *int_reg; - - /* - * Only GPIOs 6-15 are wired to interrupts on IXP23xx - */ - if (line < 6 || line > 15) - return -EINVAL; - - switch (type) { - case IRQT_BOTHEDGE: - int_style = IXP23XX_GPIO_STYLE_TRANSITIONAL; - irq_type = IXP23XX_IRQ_EDGE; - break; - case IRQT_RISING: - int_style = IXP23XX_GPIO_STYLE_RISING_EDGE; - irq_type = IXP23XX_IRQ_EDGE; - break; - case IRQT_FALLING: - int_style = IXP23XX_GPIO_STYLE_FALLING_EDGE; - irq_type = IXP23XX_IRQ_EDGE; - break; - case IRQT_HIGH: - int_style = IXP23XX_GPIO_STYLE_ACTIVE_HIGH; - irq_type = IXP23XX_IRQ_LEVEL; - break; - case IRQT_LOW: - int_style = IXP23XX_GPIO_STYLE_ACTIVE_LOW; - irq_type = IXP23XX_IRQ_LEVEL; - break; - default: - return -EINVAL; - } - - ixp23xx_config_irq(irq, irq_type); - - if (line >= 8) { /* pins 8-15 */ - line -= 8; - int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT2R; - } else { /* pins 0-7 */ - int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT1R; - } - - /* - * Clear pending interrupts - */ - *IXP23XX_GPIO_GPISR = (1 << line); - - /* Clear the style for the appropriate pin */ - *int_reg &= ~(IXP23XX_GPIO_STYLE_MASK << - (line * IXP23XX_GPIO_STYLE_SIZE)); - - /* Set the new style */ - *int_reg |= (int_style << (line * IXP23XX_GPIO_STYLE_SIZE)); - - return 0; -} - -static void ixp23xx_irq_mask(unsigned int irq) -{ - volatile unsigned long *intr_reg; - - if (irq >= 56) - irq += 8; - - intr_reg = IXP23XX_INTR_EN1 + (irq / 32); - *intr_reg &= ~(1 << (irq % 32)); -} - -static void ixp23xx_irq_ack(unsigned int irq) -{ - int line = irq - IRQ_IXP23XX_GPIO6 + 6; - - if ((line < 6) || (line > 15)) - return; - - *IXP23XX_GPIO_GPISR = (1 << line); -} - -/* - * Level triggered interrupts on GPIO lines can only be cleared when the - * interrupt condition disappears. - */ -static void ixp23xx_irq_level_unmask(unsigned int irq) -{ - volatile unsigned long *intr_reg; - - ixp23xx_irq_ack(irq); - - if (irq >= 56) - irq += 8; - - intr_reg = IXP23XX_INTR_EN1 + (irq / 32); - *intr_reg |= (1 << (irq % 32)); -} - -static void ixp23xx_irq_edge_unmask(unsigned int irq) -{ - volatile unsigned long *intr_reg; - - if (irq >= 56) - irq += 8; - - intr_reg = IXP23XX_INTR_EN1 + (irq / 32); - *intr_reg |= (1 << (irq % 32)); -} - -static struct irqchip ixp23xx_irq_level_chip = { - .ack = ixp23xx_irq_mask, - .mask = ixp23xx_irq_mask, - .unmask = ixp23xx_irq_level_unmask, - .set_type = ixp23xx_irq_set_type -}; - -static struct irqchip ixp23xx_irq_edge_chip = { - .ack = ixp23xx_irq_ack, - .mask = ixp23xx_irq_mask, - .unmask = ixp23xx_irq_edge_unmask, - .set_type = ixp23xx_irq_set_type -}; - -static void ixp23xx_pci_irq_mask(unsigned int irq) -{ - *IXP23XX_PCI_XSCALE_INT_ENABLE &= ~(1 << (IRQ_IXP23XX_INTA + 27 - irq)); -} - -static void ixp23xx_pci_irq_unmask(unsigned int irq) -{ - *IXP23XX_PCI_XSCALE_INT_ENABLE |= (1 << (IRQ_IXP23XX_INTA + 27 - irq)); -} - -/* - * TODO: Should this just be done at ASM level? - */ -static void pci_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) -{ - u32 pci_interrupt; - unsigned int irqno; - struct irqdesc *int_desc; - - pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS; - - desc->chip->ack(irq); - - /* See which PCI_INTA, or PCI_INTB interrupted */ - if (pci_interrupt & (1 << 26)) { - irqno = IRQ_IXP23XX_INTB; - } else if (pci_interrupt & (1 << 27)) { - irqno = IRQ_IXP23XX_INTA; - } else { - BUG(); - } - - int_desc = irq_desc + irqno; - int_desc->handle(irqno, int_desc, regs); - - desc->chip->unmask(irq); -} - -static struct irqchip ixp23xx_pci_irq_chip = { - .ack = ixp23xx_pci_irq_mask, - .mask = ixp23xx_pci_irq_mask, - .unmask = ixp23xx_pci_irq_unmask -}; - -static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type) -{ - switch (type) { - case IXP23XX_IRQ_LEVEL: - set_irq_chip(irq, &ixp23xx_irq_level_chip); - set_irq_handler(irq, do_level_IRQ); - break; - case IXP23XX_IRQ_EDGE: - set_irq_chip(irq, &ixp23xx_irq_edge_chip); - set_irq_handler(irq, do_edge_IRQ); - break; - } - set_irq_flags(irq, IRQF_VALID); -} - -void __init ixp23xx_init_irq(void) -{ - int irq; - - /* Route everything to IRQ */ - *IXP23XX_INTR_SEL1 = 0x0; - *IXP23XX_INTR_SEL2 = 0x0; - *IXP23XX_INTR_SEL3 = 0x0; - *IXP23XX_INTR_SEL4 = 0x0; - - /* Mask all sources */ - *IXP23XX_INTR_EN1 = 0x0; - *IXP23XX_INTR_EN2 = 0x0; - *IXP23XX_INTR_EN3 = 0x0; - *IXP23XX_INTR_EN4 = 0x0; - - /* - * Configure all IRQs for level-sensitive operation - */ - for (irq = 0; irq <= NUM_IXP23XX_RAW_IRQS; irq++) { - ixp23xx_config_irq(irq, IXP23XX_IRQ_LEVEL); - } - - for (irq = IRQ_IXP23XX_INTA; irq <= IRQ_IXP23XX_INTB; irq++) { - set_irq_chip(irq, &ixp23xx_pci_irq_chip); - set_irq_handler(irq, do_level_IRQ); - set_irq_flags(irq, IRQF_VALID); - } - - set_irq_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler); -} - - -/************************************************************************* - * Timer-tick functions for IXP23xx - *************************************************************************/ -#define CLOCK_TICKS_PER_USEC CLOCK_TICK_RATE / (USEC_PER_SEC) - -static unsigned long next_jiffy_time; - -static unsigned long -ixp23xx_gettimeoffset(void) -{ - unsigned long elapsed; - - elapsed = *IXP23XX_TIMER_CONT - (next_jiffy_time - LATCH); - - return elapsed / CLOCK_TICKS_PER_USEC; -} - -static irqreturn_t -ixp23xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - /* Clear Pending Interrupt by writing '1' to it */ - *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND; - while ((*IXP23XX_TIMER_CONT - next_jiffy_time) > LATCH) { - timer_tick(regs); - next_jiffy_time += LATCH; - } - - return IRQ_HANDLED; -} - -static struct irqaction ixp23xx_timer_irq = { - .name = "IXP23xx Timer Tick", - .handler = ixp23xx_timer_interrupt, - .flags = SA_INTERRUPT | SA_TIMER, -}; - -void __init ixp23xx_init_timer(void) -{ - /* Clear Pending Interrupt by writing '1' to it */ - *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND; - - /* Setup the Timer counter value */ - *IXP23XX_TIMER1_RELOAD = - (LATCH & ~IXP23XX_TIMER_RELOAD_MASK) | IXP23XX_TIMER_ENABLE; - - *IXP23XX_TIMER_CONT = 0; - next_jiffy_time = LATCH; - - /* Connect the interrupt handler and enable the interrupt */ - setup_irq(IRQ_IXP23XX_TIMER1, &ixp23xx_timer_irq); -} - -struct sys_timer ixp23xx_timer = { - .init = ixp23xx_init_timer, - .offset = ixp23xx_gettimeoffset, -}; - - -/************************************************************************* - * IXP23xx Platform Initializaion - *************************************************************************/ -static struct resource ixp23xx_uart_resources[] = { - { - .start = IXP23XX_UART1_PHYS, - .end = IXP23XX_UART1_PHYS + 0x0fff, - .flags = IORESOURCE_MEM - }, { - .start = IXP23XX_UART2_PHYS, - .end = IXP23XX_UART2_PHYS + 0x0fff, - .flags = IORESOURCE_MEM - } -}; - -static struct plat_serial8250_port ixp23xx_uart_data[] = { - { - .mapbase = IXP23XX_UART1_PHYS, - .membase = (char *)(IXP23XX_UART1_VIRT + 3), - .irq = IRQ_IXP23XX_UART1, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IXP23XX_UART_XTAL, - }, { - .mapbase = IXP23XX_UART2_PHYS, - .membase = (char *)(IXP23XX_UART2_VIRT + 3), - .irq = IRQ_IXP23XX_UART2, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IXP23XX_UART_XTAL, - }, - { }, -}; - -static struct platform_device ixp23xx_uart = { - .name = "serial8250", - .id = 0, - .dev.platform_data = ixp23xx_uart_data, - .num_resources = 2, - .resource = ixp23xx_uart_resources, -}; - -static struct platform_device *ixp23xx_devices[] __initdata = { - &ixp23xx_uart, -}; - -void __init ixp23xx_sys_init(void) -{ - platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices)); -} diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c deleted file mode 100644 index bf688c128..000000000 --- a/arch/arm/mach-ixp23xx/espresso.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * arch/arm/mach-ixp23xx/espresso.c - * - * Double Espresso-specific routines - * - * Author: Lennert Buytenhek - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static int __init espresso_pci_init(void) -{ - if (machine_is_espresso()) - ixp23xx_pci_slave_init(); - - return 0; -}; -subsys_initcall(espresso_pci_init); - -static void __init espresso_init(void) -{ - physmap_configure(0x90000000, 0x02000000, 2, NULL); - - /* - * Mark flash as writeable. - */ - IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE; - IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE; - - ixp23xx_sys_init(); -} - -MACHINE_START(ESPRESSO, "IP Fabrics Double Espresso") - /* Maintainer: Lennert Buytenhek */ - .phys_io = IXP23XX_PERIPHERAL_PHYS, - .io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc, - .map_io = ixp23xx_map_io, - .init_irq = ixp23xx_init_irq, - .timer = &ixp23xx_timer, - .boot_params = 0x00000100, - .init_machine = espresso_init, -MACHINE_END diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c deleted file mode 100644 index 00146c35d..000000000 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * arch/arm/mach-ixp23xx/ixdp2351.c - * - * IXDP2351 board-specific routines - * - * Author: Deepak Saxena - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * Based on 2.4 code Copyright 2004 (c) Intel Corporation - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * IXDP2351 Interrupt Handling - */ -static void ixdp2351_inta_mask(unsigned int irq) -{ - *IXDP2351_CPLD_INTA_MASK_SET_REG = IXDP2351_INTA_IRQ_MASK(irq); -} - -static void ixdp2351_inta_unmask(unsigned int irq) -{ - *IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(irq); -} - -static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) -{ - u16 ex_interrupt = - *IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID; - int i; - - desc->chip->mask(irq); - - for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) { - if (ex_interrupt & (1 << i)) { - struct irqdesc *cpld_desc; - int cpld_irq = - IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i); - cpld_desc = irq_desc + cpld_irq; - cpld_desc->handle(cpld_irq, cpld_desc, regs); - } - } - - desc->chip->unmask(irq); -} - -static struct irqchip ixdp2351_inta_chip = { - .ack = ixdp2351_inta_mask, - .mask = ixdp2351_inta_mask, - .unmask = ixdp2351_inta_unmask -}; - -static void ixdp2351_intb_mask(unsigned int irq) -{ - *IXDP2351_CPLD_INTB_MASK_SET_REG = IXDP2351_INTB_IRQ_MASK(irq); -} - -static void ixdp2351_intb_unmask(unsigned int irq) -{ - *IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(irq); -} - -static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) -{ - u16 ex_interrupt = - *IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID; - int i; - - desc->chip->ack(irq); - - for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) { - if (ex_interrupt & (1 << i)) { - struct irqdesc *cpld_desc; - int cpld_irq = - IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i); - cpld_desc = irq_desc + cpld_irq; - cpld_desc->handle(cpld_irq, cpld_desc, regs); - } - } - - desc->chip->unmask(irq); -} - -static struct irqchip ixdp2351_intb_chip = { - .ack = ixdp2351_intb_mask, - .mask = ixdp2351_intb_mask, - .unmask = ixdp2351_intb_unmask -}; - -void ixdp2351_init_irq(void) -{ - int irq; - - /* Mask all interrupts from CPLD, disable simulation */ - *IXDP2351_CPLD_INTA_MASK_SET_REG = (u16) -1; - *IXDP2351_CPLD_INTB_MASK_SET_REG = (u16) -1; - *IXDP2351_CPLD_INTA_SIM_REG = 0; - *IXDP2351_CPLD_INTB_SIM_REG = 0; - - ixp23xx_init_irq(); - - for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE); - irq < - IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + IXDP2351_INTA_IRQ_NUM); - irq++) { - if (IXDP2351_INTA_IRQ_MASK(irq) & IXDP2351_INTA_IRQ_VALID) { - set_irq_flags(irq, IRQF_VALID); - set_irq_handler(irq, do_level_IRQ); - set_irq_chip(irq, &ixdp2351_inta_chip); - } - } - - for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE); - irq < - IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + IXDP2351_INTB_IRQ_NUM); - irq++) { - if (IXDP2351_INTB_IRQ_MASK(irq) & IXDP2351_INTB_IRQ_VALID) { - set_irq_flags(irq, IRQF_VALID); - set_irq_handler(irq, do_level_IRQ); - set_irq_chip(irq, &ixdp2351_intb_chip); - } - } - - set_irq_chained_handler(IRQ_IXP23XX_INTA, &ixdp2351_inta_handler); - set_irq_chained_handler(IRQ_IXP23XX_INTB, &ixdp2351_intb_handler); -} - -/* - * IXDP2351 PCI - */ - -/* - * This board does not do normal PCI IRQ routing, or any - * sort of swizzling, so we just need to check where on the - * bus the device is and figure out what CPLD pin it is - * being routed to. - */ -#define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) - -static int __init ixdp2351_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - u8 bus = dev->bus->number; - u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin); - struct pci_bus *tmp_bus = dev->bus; - - /* Primary bus, no interrupts here */ - if (!bus) - return -1; - - /* Lookup first leaf in bus tree */ - while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL)) - tmp_bus = tmp_bus->parent; - - /* Select between known bridges */ - switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) { - /* Device is located after first bridge */ - case 0x0008: - if (tmp_bus == dev->bus) { - /* Device is located directy after first bridge */ - switch (devpin) { - /* Onboard 82546 */ - case DEVPIN(1, 1): /* Onboard 82546 ch 0 */ - return IRQ_IXDP2351_INTA_82546; - case DEVPIN(1, 2): /* Onboard 82546 ch 1 */ - return IRQ_IXDP2351_INTB_82546; - /* PMC SLOT */ - case DEVPIN(0, 1): /* PMCP INTA# */ - case DEVPIN(2, 4): /* PMCS INTD# */ - return IRQ_IXDP2351_SPCI_PMC_INTA; - case DEVPIN(0, 2): /* PMCP INTB# */ - case DEVPIN(2, 1): /* PMCS INTA# */ - return IRQ_IXDP2351_SPCI_PMC_INTB; - case DEVPIN(0, 3): /* PMCP INTC# */ - case DEVPIN(2, 2): /* PMCS INTB# */ - return IRQ_IXDP2351_SPCI_PMC_INTC; - case DEVPIN(0, 4): /* PMCP INTD# */ - case DEVPIN(2, 3): /* PMCS INTC# */ - return IRQ_IXDP2351_SPCI_PMC_INTD; - } - } else { - /* Device is located indirectly after first bridge */ - /* Not supported now */ - return -1; - } - break; - case 0x0010: - if (tmp_bus == dev->bus) { - /* Device is located directy after second bridge */ - /* Secondary bus of second bridge */ - switch (devpin) { - case DEVPIN(0, 1): /* DB#0 */ - case DEVPIN(0, 2): - case DEVPIN(0, 3): - case DEVPIN(0, 4): - return IRQ_IXDP2351_SPCI_DB_0; - case DEVPIN(1, 1): /* DB#1 */ - case DEVPIN(1, 2): - case DEVPIN(1, 3): - case DEVPIN(1, 4): - return IRQ_IXDP2351_SPCI_DB_1; - case DEVPIN(2, 1): /* FIC1 */ - case DEVPIN(2, 2): - case DEVPIN(2, 3): - case DEVPIN(2, 4): - case DEVPIN(3, 1): /* FIC2 */ - case DEVPIN(3, 2): - case DEVPIN(3, 3): - case DEVPIN(3, 4): - return IRQ_IXDP2351_SPCI_FIC; - } - } else { - /* Device is located indirectly after second bridge */ - /* Not supported now */ - return -1; - } - break; - } - - return -1; -} - -struct hw_pci ixdp2351_pci __initdata = { - .nr_controllers = 1, - .preinit = ixp23xx_pci_preinit, - .setup = ixp23xx_pci_setup, - .scan = ixp23xx_pci_scan_bus, - .map_irq = ixdp2351_map_irq, -}; - -int __init ixdp2351_pci_init(void) -{ - if (machine_is_ixdp2351()) - pci_common_init(&ixdp2351_pci); - - return 0; -} - -subsys_initcall(ixdp2351_pci_init); - -/* - * IXDP2351 Static Mapped I/O - */ -static struct map_desc ixdp2351_io_desc[] __initdata = { - { - .virtual = IXDP2351_NP_VIRT_BASE, - .pfn = __phys_to_pfn((u64)IXDP2351_NP_PHYS_BASE), - .length = IXDP2351_NP_PHYS_SIZE, - .type = MT_DEVICE - }, { - .virtual = IXDP2351_BB_BASE_VIRT, - .pfn = __phys_to_pfn((u64)IXDP2351_BB_BASE_PHYS), - .length = IXDP2351_BB_SIZE, - .type = MT_DEVICE - } -}; - -static void __init ixdp2351_map_io(void) -{ - ixp23xx_map_io(); - iotable_init(ixdp2351_io_desc, ARRAY_SIZE(ixdp2351_io_desc)); -} - -static void __init ixdp2351_init(void) -{ - physmap_configure(0x90000000, 0x04000000, 1, NULL); - - /* - * Mark flash as writeable - */ - IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE; - IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE; - IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE; - IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE; - - ixp23xx_sys_init(); -} - -MACHINE_START(IXDP2351, "Intel IXDP2351 Development Platform") - /* Maintainer: MontaVista Software, Inc. */ - .phys_io = IXP23XX_PERIPHERAL_PHYS, - .io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc, - .map_io = ixdp2351_map_io, - .init_irq = ixdp2351_init_irq, - .timer = &ixp23xx_timer, - .boot_params = 0x00000100, - .init_machine = ixdp2351_init, -MACHINE_END diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c deleted file mode 100644 index ac72f94c5..000000000 --- a/arch/arm/mach-ixp23xx/pci.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * arch/arm/mach-ixp23xx/pci.c - * - * PCI routines for IXP23XX based systems - * - * Copyright (c) 2005 MontaVista Software, Inc. - * - * based on original code: - * - * Author: Naeem Afzal - * Copyright 2002-2005 Intel 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -extern int (*external_fault) (unsigned long, struct pt_regs *); - -static int pci_master_aborts = 0; - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -int clear_master_aborts(void); - -static u32 -*ixp23xx_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) -{ - u32 *paddress; - - /* - * Must be dword aligned - */ - where &= ~3; - - /* - * For top bus, generate type 0, else type 1 - */ - if (!bus_nr) { - if (PCI_SLOT(devfn) >= 8) - return 0; - - paddress = (u32 *) (IXP23XX_PCI_CFG0_VIRT - | (1 << (PCI_SLOT(devfn) + 16)) - | (PCI_FUNC(devfn) << 8) | where); - } else { - paddress = (u32 *) (IXP23XX_PCI_CFG1_VIRT - | (bus_nr << 16) - | (PCI_SLOT(devfn) << 11) - | (PCI_FUNC(devfn) << 8) | where); - } - - return paddress; -} - -/* - * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes. - * 0 and 3 are not valid indexes... - */ -static u32 bytemask[] = { - /*0*/ 0, - /*1*/ 0xff, - /*2*/ 0xffff, - /*3*/ 0, - /*4*/ 0xffffffff, -}; - -static int ixp23xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 *value) -{ - u32 n; - u32 *addr; - - n = where % 4; - - DBG("In config_read(%d) %d from dev %d:%d:%d\n", size, where, - bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); - - addr = ixp23xx_pci_config_addr(bus->number, devfn, where); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - - pci_master_aborts = 0; - *value = (*addr >> (8*n)) & bytemask[size]; - if (pci_master_aborts) { - pci_master_aborts = 0; - *value = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - - return PCIBIOS_SUCCESSFUL; -} - -/* - * We don't do error checking on the address for writes. - * It's assumed that the user checked for the device existing first - * by doing a read first. - */ -static int ixp23xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 value) -{ - u32 mask; - u32 *addr; - u32 temp; - - mask = ~(bytemask[size] << ((where % 0x4) * 8)); - addr = ixp23xx_pci_config_addr(bus->number, devfn, where); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - temp = (u32) (value) << ((where % 0x4) * 8); - *addr = (*addr & mask) | temp; - - clear_master_aborts(); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops ixp23xx_pci_ops = { - .read = ixp23xx_pci_read_config, - .write = ixp23xx_pci_write_config, -}; - -struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata) -{ - return pci_scan_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata); -} - -int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -{ - volatile unsigned long temp; - unsigned long flags; - - pci_master_aborts = 1; - - local_irq_save(flags); - temp = *IXP23XX_PCI_CONTROL; - - /* - * master abort and cmd tgt err - */ - if (temp & ((1 << 8) | (1 << 5))) - *IXP23XX_PCI_CONTROL = temp; - - temp = *IXP23XX_PCI_CMDSTAT; - - if (temp & (1 << 29)) - *IXP23XX_PCI_CMDSTAT = temp; - local_irq_restore(flags); - - /* - * If it was an imprecise abort, then we need to correct the - * return address to be _after_ the instruction. - */ - if (fsr & (1 << 10)) - regs->ARM_pc += 4; - - return 0; -} - -int clear_master_aborts(void) -{ - volatile u32 temp; - - temp = *IXP23XX_PCI_CONTROL; - - /* - * master abort and cmd tgt err - */ - if (temp & ((1 << 8) | (1 << 5))) - *IXP23XX_PCI_CONTROL = temp; - - temp = *IXP23XX_PCI_CMDSTAT; - - if (temp & (1 << 29)) - *IXP23XX_PCI_CMDSTAT = temp; - - return 0; -} - -static void __init ixp23xx_pci_common_init(void) -{ -#ifdef __ARMEB__ - *IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */ -#endif - /* - * ADDR_31 needs to be clear for PCI memory access to CPP memory - */ - *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_ADDR_31; - *IXP23XX_CPP2XSI_CURR_XFER_REG3 |= IXP23XX_CPP2XSI_PSH_OFF; - - /* - * Select correct memory for PCI inbound transactions - */ - if (ixp23xx_cpp_boot()) { - *IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1); - } else { - *IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1); - - /* - * Enable coherency on A2 silicon. - */ - if (arch_is_coherent()) - *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF; - } -} - -void __init ixp23xx_pci_preinit(void) -{ - ixp23xx_pci_common_init(); - - hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, - "PCI config cycle to non-existent device"); - - *IXP23XX_PCI_ADDR_EXT = 0x0000e000; -} - -/* - * Prevent PCI layer from seeing the inbound host-bridge resources - */ -static void __devinit pci_fixup_ixp23xx(struct pci_dev *dev) -{ - int i; - - dev->class &= 0xff; - dev->class |= PCI_CLASS_BRIDGE_HOST << 8; - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - dev->resource[i].start = 0; - dev->resource[i].end = 0; - dev->resource[i].flags = 0; - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9002, pci_fixup_ixp23xx); - -/* - * IXP2300 systems often have large resource requirements, so we just - * use our own resource space. - */ -static struct resource ixp23xx_pci_mem_space = { - .start = IXP23XX_PCI_MEM_START, - .end = IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM, - .name = "PCI Mem Space" -}; - -static struct resource ixp23xx_pci_io_space = { - .start = 0x00000100, - .end = 0x01ffffff, - .flags = IORESOURCE_IO, - .name = "PCI I/O Space" -}; - -int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys) -{ - if (nr >= 1) - return 0; - - sys->resource[0] = &ixp23xx_pci_io_space; - sys->resource[1] = &ixp23xx_pci_mem_space; - sys->resource[2] = NULL; - - return 1; -} - -void ixp23xx_pci_slave_init(void) -{ - ixp23xx_pci_common_init(); -} diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c deleted file mode 100644 index 43c14e740..000000000 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * arch/arm/mach-ixp23xx/roadrunner.c - * - * RoadRunner board-specific routines - * - * Author: Deepak Saxena - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * Based on 2.4 code Copyright 2005 (c) ADI Engineering Corporation - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * Interrupt mapping - */ -#define INTA IRQ_ROADRUNNER_PCI_INTA -#define INTB IRQ_ROADRUNNER_PCI_INTB -#define INTC IRQ_ROADRUNNER_PCI_INTC -#define INTD IRQ_ROADRUNNER_PCI_INTD - -#define INTC_PIN IXP23XX_GPIO_PIN_11 -#define INTD_PIN IXP23XX_GPIO_PIN_12 - -static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_card_slot_irq[] = {INTB, INTC, INTD, INTA}; - static int pmc_card_slot_irq[] = {INTA, INTB, INTC, INTD}; - static int usb_irq[] = {INTB, INTC, INTD, -1}; - static int mini_pci_1_irq[] = {INTB, INTC, -1, -1}; - static int mini_pci_2_irq[] = {INTC, INTD, -1, -1}; - - switch(dev->bus->number) { - case 0: - switch(dev->devfn) { - case 0x0: // PCI-PCI bridge - break; - case 0x8: // PCI Card Slot - return pci_card_slot_irq[pin - 1]; - case 0x10: // PMC Slot - return pmc_card_slot_irq[pin - 1]; - case 0x18: // PMC Slot Secondary Agent - break; - case 0x20: // IXP Processor - break; - default: - return NO_IRQ; - } - break; - - case 1: - switch(dev->devfn) { - case 0x0: // IDE Controller - return (pin == 1) ? INTC : -1; - case 0x8: // USB fun 0 - case 0x9: // USB fun 1 - case 0xa: // USB fun 2 - return usb_irq[pin - 1]; - case 0x10: // Mini PCI 1 - return mini_pci_1_irq[pin-1]; - case 0x18: // Mini PCI 2 - return mini_pci_2_irq[pin-1]; - case 0x20: // MEM slot - return (pin == 1) ? INTA : -1; - default: - return NO_IRQ; - } - break; - - default: - return NO_IRQ; - } - - return NO_IRQ; -} - -static void roadrunner_pci_preinit(void) -{ - set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW); - set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_LOW); - - ixp23xx_pci_preinit(); -} - -static struct hw_pci roadrunner_pci __initdata = { - .nr_controllers = 1, - .preinit = roadrunner_pci_preinit, - .setup = ixp23xx_pci_setup, - .scan = ixp23xx_pci_scan_bus, - .map_irq = roadrunner_map_irq, -}; - -static int __init roadrunner_pci_init(void) -{ - if (machine_is_roadrunner()) - pci_common_init(&roadrunner_pci); - - return 0; -}; - -subsys_initcall(roadrunner_pci_init); - -static void __init roadrunner_init(void) -{ - physmap_configure(0x90000000, 0x04000000, 2, NULL); - - /* - * Mark flash as writeable - */ - IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE; - IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE; - IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE; - IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE; - - ixp23xx_sys_init(); -} - -MACHINE_START(ROADRUNNER, "ADI Engineering RoadRunner Development Platform") - /* Maintainer: Deepak Saxena */ - .phys_io = IXP23XX_PERIPHERAL_PHYS, - .io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc, - .map_io = ixp23xx_map_io, - .init_irq = ixp23xx_init_irq, - .timer = &ixp23xx_timer, - .boot_params = 0x00000100, - .init_machine = roadrunner_init, -MACHINE_END diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 3b23f43cb..5bf50a2a7 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -11,7 +11,6 @@ comment "IXP4xx Platforms" config MACH_NSLU2 bool prompt "Linksys NSLU2" - select PCI help Say 'Y' here if you want your kernel to support Linksys's NSLU2 NAS device. For more information on this platform, @@ -19,7 +18,6 @@ config MACH_NSLU2 config ARCH_AVILA bool "Avila" - select PCI help Say 'Y' here if you want your kernel to support the Gateworks Avila Network Platform. For more information on this platform, @@ -27,7 +25,6 @@ config ARCH_AVILA config ARCH_ADI_COYOTE bool "Coyote" - select PCI help Say 'Y' here if you want your kernel to support the ADI Engineering Coyote Gateway Reference Platform. For more @@ -35,7 +32,6 @@ config ARCH_ADI_COYOTE config ARCH_IXDP425 bool "IXDP425" - select PCI help Say 'Y' here if you want your kernel to support Intel's IXDP425 Development Platform (Also known as Richfield). @@ -43,7 +39,6 @@ config ARCH_IXDP425 config MACH_IXDPG425 bool "IXDPG425" - select PCI help Say 'Y' here if you want your kernel to support Intel's IXDPG425 Development Platform (Also known as Montajade). @@ -51,7 +46,6 @@ config MACH_IXDPG425 config MACH_IXDP465 bool "IXDP465" - select PCI help Say 'Y' here if you want your kernel to support Intel's IXDP465 Development Platform (Also known as BMP). @@ -78,7 +72,6 @@ config ARCH_PRPMC1100 config MACH_NAS100D bool prompt "NAS100D" - select PCI help Say 'Y' here if you want your kernel to support Iomega's NAS 100d device. For more information on this platform, @@ -103,7 +96,6 @@ config CPU_IXP46X config MACH_GTWX5715 bool "Gemtek WX5715 (Linksys WRV54G)" depends on ARCH_IXP4XX - select PCI help This board is currently inside the Linksys WRV54G Gateways. @@ -118,16 +110,11 @@ config MACH_GTWX5715 "High Speed" UART is n/c (as far as I can tell) 20 Pin ARM/Xscale JTAG interface on J2 -comment "IXP4xx Options" -config DMABOUNCE - bool - default y - depends on PCI +comment "IXP4xx Options" config IXP4XX_INDIRECT_PCI bool "Use indirect PCI memory access" - depends on PCI help IXP4xx provides two methods of accessing PCI memory space: @@ -141,7 +128,7 @@ config IXP4XX_INDIRECT_PCI 2) If > 64MB of memory space is required, the IXP4xx can be configured to use indirect registers to access PCI This allows for up to 128MB (0x48000000 to 0x4fffffff) of memory on the bus. - The disadvantage of this is that every PCI access requires + The disadvantadge of this is that every PCI access requires three local register accesses plus a spinlock, but in some cases the performance hit is acceptable. In addition, you cannot mmap() PCI devices in this case due to the indirect nature diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index 5a4aaa0e0..0471044fa 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile @@ -2,9 +2,8 @@ # Makefile for the linux kernel. # -obj-y += common.o +obj-y += common.o common-pci.o -obj-$(CONFIG_PCI) += common-pci.o obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 2d40fe114..6e3462ed5 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -463,7 +463,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) if (nr >= 1) return 0; - res = kzalloc(sizeof(*res) * 2, GFP_KERNEL); + res = kmalloc(sizeof(*res) * 2, GFP_KERNEL); if (res == NULL) { /* * If we're out of memory this early, something is wrong, @@ -471,6 +471,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) */ panic("PCI: unable to allocate resources?\n"); } + memset(res, 0, sizeof(*res) * 2); local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 00b761ff0..fbadf3021 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -91,7 +91,7 @@ static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type); /* * IRQ -> GPIO mapping table */ -static signed char irq2gpio[32] = { +static int irq2gpio[32] = { -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, @@ -153,9 +153,6 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) /* Set the new style */ *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); - /* Configure the line as an input */ - gpio_line_config(line, IXP4XX_GPIO_IN); - return 0; } diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h index ea8de7e3a..578a52461 100644 --- a/arch/arm/mach-lh7a40x/common.h +++ b/arch/arm/mach-lh7a40x/common.h @@ -12,6 +12,5 @@ extern struct sys_timer lh7a40x_timer; extern void lh7a400_init_irq (void); extern void lh7a404_init_irq (void); -extern void lh7a40x_init_board_irq (void); #define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs) diff --git a/arch/arm/mach-lh7a40x/irq-kev7a400.c b/arch/arm/mach-lh7a40x/irq-kev7a400.c index 8535764d8..691bb0923 100644 --- a/arch/arm/mach-lh7a40x/irq-kev7a400.c +++ b/arch/arm/mach-lh7a40x/irq-kev7a400.c @@ -16,7 +16,6 @@ #include #include -#include "common.h" /* KEV7a400 CPLD IRQ handling */ diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c index f9fdefef6..f334d81c2 100644 --- a/arch/arm/mach-lh7a40x/irq-lh7a400.c +++ b/arch/arm/mach-lh7a40x/irq-lh7a400.c @@ -16,9 +16,9 @@ #include #include #include +#include #include -#include "common.h" /* CPU IRQ handling */ diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c index e902e3d87..122fadabc 100644 --- a/arch/arm/mach-lh7a40x/irq-lh7a404.c +++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c @@ -16,10 +16,9 @@ #include #include #include +#include #include -#include "common.h" - #define USE_PRIORITIES /* See Documentation/arm/Sharp-LH/VectoredInterruptController for more diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c index dcb4e17b9..6262d4491 100644 --- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c @@ -19,7 +19,6 @@ #include #include -#include "common.h" static void lh7a40x_ack_cpld_irq (u32 irq) { diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index f8d716ccc..86a0f0d14 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -69,6 +69,12 @@ config MACH_VOICEBLUE Support for Voiceblue GSM/VoIP gateway. Say Y here if you have such a board. +config MACH_NETSTAR + bool "NetStar" + depends on ARCH_OMAP1 && ARCH_OMAP15XX + help + Support for NetStar PBX. Say Y here if you have such a board. + config MACH_OMAP_PALMTE bool "Palm Tungsten E" depends on ARCH_OMAP1 && ARCH_OMAP15XX @@ -79,20 +85,6 @@ config MACH_OMAP_PALMTE informations. Say Y here if you have such a PDA, say NO otherwise. -config MACH_NOKIA770 - bool "Nokia 770" - depends on ARCH_OMAP1 && ARCH_OMAP16XX - help - Support for the Nokia 770 Internet Tablet. Say Y here if you - have such a device. - -config MACH_AMS_DELTA - bool "Amstrad E3 (Delta)" - depends on ARCH_OMAP1 && ARCH_OMAP15XX - help - Support for the Amstrad E3 (codename Delta) videophone. Say Y here - if you have such a device. - config MACH_OMAP_GENERIC bool "Generic OMAP board" depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index 9ea719550..b0b00156f 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -3,13 +3,7 @@ # # Common support -obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o - -obj-$(CONFIG_OMAP_MPU_TIMER) += time.o - -# Power Management -obj-$(CONFIG_PM) += pm.o sleep.o - +obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o led-y := leds.o # Specific board support @@ -20,9 +14,8 @@ obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o +obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o -obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o -obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o ifeq ($(CONFIG_ARCH_OMAP15XX),y) # Innovator-1510 FPGA diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c deleted file mode 100644 index 6178f046f..000000000 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * linux/arch/arm/mach-omap1/board-ams-delta.c - * - * Modified from board-generic.c - * - * Board specific inits for the Amstrad E3 (codename Delta) videophone - * - * Copyright (C) 2006 Jonathan McDowell - * - * 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 -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static u8 ams_delta_latch1_reg; -static u16 ams_delta_latch2_reg; - -void ams_delta_latch1_write(u8 mask, u8 value) -{ - ams_delta_latch1_reg &= ~mask; - ams_delta_latch1_reg |= value; - *(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg; -} - -void ams_delta_latch2_write(u16 mask, u16 value) -{ - ams_delta_latch2_reg &= ~mask; - ams_delta_latch2_reg |= value; - *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg; -} - -static void __init ams_delta_init_irq(void) -{ - omap1_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); -} - -static struct map_desc ams_delta_io_desc[] __initdata = { - // AMS_DELTA_LATCH1 - { - .virtual = AMS_DELTA_LATCH1_VIRT, - .pfn = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS), - .length = 0x01000000, - .type = MT_DEVICE - }, - // AMS_DELTA_LATCH2 - { - .virtual = AMS_DELTA_LATCH2_VIRT, - .pfn = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS), - .length = 0x01000000, - .type = MT_DEVICE - }, - // AMS_DELTA_MODEM - { - .virtual = AMS_DELTA_MODEM_VIRT, - .pfn = __phys_to_pfn(AMS_DELTA_MODEM_PHYS), - .length = 0x01000000, - .type = MT_DEVICE - } -}; - -static struct omap_uart_config ams_delta_uart_config __initdata = { - .enabled_uarts = 1, -}; - -static struct omap_board_config_kernel ams_delta_config[] = { - { OMAP_TAG_UART, &ams_delta_uart_config }, -}; - -static void __init ams_delta_init(void) -{ - iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc)); - - omap_board_config = ams_delta_config; - omap_board_config_size = ARRAY_SIZE(ams_delta_config); - omap_serial_init(); - - /* Clear latch2 (NAND, LCD, modem enable) */ - ams_delta_latch2_write(~0, 0); -} - -static void __init ams_delta_map_io(void) -{ - omap1_map_common_io(); -} - -MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") - /* Maintainer: Jonathan McDowell */ - .phys_io = 0xfff00000, - .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, - .boot_params = 0x10000100, - .map_io = ams_delta_map_io, - .init_irq = ams_delta_init_irq, - .init_machine = ams_delta_init, - .timer = &omap_timer, -MACHINE_END - -EXPORT_SYMBOL(ams_delta_latch1_write); -EXPORT_SYMBOL(ams_delta_latch2_write); diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index 33d01adab..a177e78b2 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c @@ -88,7 +88,7 @@ static struct omap_board_config_kernel generic_config[] = { static void __init omap_generic_init(void) { #ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap15xx()) { + if (cpu_is_omap1510()) { generic_config[0].data = &generic1510_usb_config; } #endif diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index cd3a06dfc..89f0cc74a 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -24,9 +24,7 @@ #include #include #include -#include #include -#include #include #include @@ -37,55 +35,12 @@ #include #include #include -#include #include -#include #include -#include -#include extern int omap_gpio_init(void); -static int h2_keymap[] = { - KEY(0, 0, KEY_LEFT), - KEY(0, 1, KEY_RIGHT), - KEY(0, 2, KEY_3), - KEY(0, 3, KEY_F10), - KEY(0, 4, KEY_F5), - KEY(0, 5, KEY_9), - KEY(1, 0, KEY_DOWN), - KEY(1, 1, KEY_UP), - KEY(1, 2, KEY_2), - KEY(1, 3, KEY_F9), - KEY(1, 4, KEY_F7), - KEY(1, 5, KEY_0), - KEY(2, 0, KEY_ENTER), - KEY(2, 1, KEY_6), - KEY(2, 2, KEY_1), - KEY(2, 3, KEY_F2), - KEY(2, 4, KEY_F6), - KEY(2, 5, KEY_HOME), - KEY(3, 0, KEY_8), - KEY(3, 1, KEY_5), - KEY(3, 2, KEY_F12), - KEY(3, 3, KEY_F3), - KEY(3, 4, KEY_F8), - KEY(3, 5, KEY_END), - KEY(4, 0, KEY_7), - KEY(4, 1, KEY_4), - KEY(4, 2, KEY_F11), - KEY(4, 3, KEY_F1), - KEY(4, 4, KEY_F4), - KEY(4, 5, KEY_ESC), - KEY(5, 0, KEY_F13), - KEY(5, 1, KEY_F14), - KEY(5, 2, KEY_F15), - KEY(5, 3, KEY_F16), - KEY(5, 4, KEY_SLEEP), - 0 -}; - -static struct mtd_partition h2_nor_partitions[] = { +static struct mtd_partition h2_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { .name = "bootloader", @@ -116,26 +71,26 @@ static struct mtd_partition h2_nor_partitions[] = { } }; -static struct flash_platform_data h2_nor_data = { +static struct flash_platform_data h2_flash_data = { .map_name = "cfi_probe", .width = 2, - .parts = h2_nor_partitions, - .nr_parts = ARRAY_SIZE(h2_nor_partitions), + .parts = h2_partitions, + .nr_parts = ARRAY_SIZE(h2_partitions), }; -static struct resource h2_nor_resource = { +static struct resource h2_flash_resource = { /* This is on CS3, wherever it's mapped */ .flags = IORESOURCE_MEM, }; -static struct platform_device h2_nor_device = { +static struct platform_device h2_flash_device = { .name = "omapflash", .id = 0, .dev = { - .platform_data = &h2_nor_data, + .platform_data = &h2_flash_data, }, .num_resources = 1, - .resource = &h2_nor_resource, + .resource = &h2_flash_resource, }; static struct resource h2_smc91x_resources[] = { @@ -158,119 +113,9 @@ static struct platform_device h2_smc91x_device = { .resource = h2_smc91x_resources, }; -static struct resource h2_kp_resources[] = { - [0] = { - .start = INT_KEYBOARD, - .end = INT_KEYBOARD, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct omap_kp_platform_data h2_kp_data = { - .rows = 8, - .cols = 8, - .keymap = h2_keymap, - .rep = 1, -}; - -static struct platform_device h2_kp_device = { - .name = "omap-keypad", - .id = -1, - .dev = { - .platform_data = &h2_kp_data, - }, - .num_resources = ARRAY_SIZE(h2_kp_resources), - .resource = h2_kp_resources, -}; - -#define H2_IRDA_FIRSEL_GPIO_PIN 17 - -#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) -static int h2_transceiver_mode(struct device *dev, int state) -{ - if (state & IR_SIRMODE) - omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 0); - else /* MIR/FIR */ - omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 1); - - return 0; -} -#endif - -static struct omap_irda_config h2_irda_data = { - .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, - .rx_channel = OMAP_DMA_UART3_RX, - .tx_channel = OMAP_DMA_UART3_TX, - .dest_start = UART3_THR, - .src_start = UART3_RHR, - .tx_trigger = 0, - .rx_trigger = 0, -}; - -static struct resource h2_irda_resources[] = { - [0] = { - .start = INT_UART3, - .end = INT_UART3, - .flags = IORESOURCE_IRQ, - }, -}; -static struct platform_device h2_irda_device = { - .name = "omapirda", - .id = 0, - .dev = { - .platform_data = &h2_irda_data, - }, - .num_resources = ARRAY_SIZE(h2_irda_resources), - .resource = h2_irda_resources, -}; - -static struct platform_device h2_lcd_device = { - .name = "lcd_h2", - .id = -1, -}; - -static struct omap_mcbsp_reg_cfg mcbsp_regs = { - .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), - .spcr1 = RINTM(3) | RRST, - .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | - RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1), - .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), - .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG, - .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), - .srgr1 = FWID(15), - .srgr2 = GSYNC | CLKSP | FSGM | FPER(31), - - .pcr0 = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP, - //.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ -}; - -static struct omap_alsa_codec_config alsa_config = { - .name = "H2 TSC2101", - .mcbsp_regs_alsa = &mcbsp_regs, - .codec_configure_dev = NULL, // tsc2101_configure, - .codec_set_samplerate = NULL, // tsc2101_set_samplerate, - .codec_clock_setup = NULL, // tsc2101_clock_setup, - .codec_clock_on = NULL, // tsc2101_clock_on, - .codec_clock_off = NULL, // tsc2101_clock_off, - .get_default_samplerate = NULL, // tsc2101_get_default_samplerate, -}; - -static struct platform_device h2_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &alsa_config, - }, -}; - static struct platform_device *h2_devices[] __initdata = { - &h2_nor_device, + &h2_flash_device, &h2_smc91x_device, - &h2_irda_device, - &h2_kp_device, - &h2_lcd_device, - &h2_mcbsp1_device, }; static void __init h2_init_smc91x(void) @@ -319,6 +164,7 @@ static struct omap_uart_config h2_uart_config __initdata = { }; static struct omap_lcd_config h2_lcd_config __initdata = { + .panel_name = "h2", .ctrl_name = "internal", }; @@ -331,34 +177,16 @@ static struct omap_board_config_kernel h2_config[] = { static void __init h2_init(void) { - /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped - * to address 0 by a dip switch), NAND on CS2B. The NAND driver will - * notice whether a NAND chip is enabled at probe time. - * - * FIXME revC boards (and H3) support NAND-boot, with a dip switch to - * put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try - * detecting that in code here, to avoid probing every possible flash - * configuration... + /* NOTE: revC boards support NAND-boot, which can put NOR on CS2B + * and NAND (either 16bit or 8bit) on CS3. */ - h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys(); - h2_nor_resource.end += SZ_32M - 1; - - omap_cfg_reg(L3_1610_FLASH_CS2B_OE); - omap_cfg_reg(M8_1610_FLASH_CS2B_WE); + h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys(); + h2_flash_resource.end += SZ_32M - 1; /* MMC: card detect and WP */ // omap_cfg_reg(U19_ARMIO1); /* CD */ omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */ - /* Irda */ -#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) - omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A); - if (!(omap_request_gpio(H2_IRDA_FIRSEL_GPIO_PIN))) { - omap_set_gpio_direction(H2_IRDA_FIRSEL_GPIO_PIN, 0); - h2_irda_data.transceiver_mode = h2_transceiver_mode; - } -#endif - platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); omap_board_config = h2_config; omap_board_config_size = ARRAY_SIZE(h2_config); diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 4b8d0ec73..d9f386265 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -21,11 +21,8 @@ #include #include #include -#include #include -#include #include -#include #include #include @@ -36,59 +33,15 @@ #include #include -#include #include #include #include -#include #include -#include -#include #include extern int omap_gpio_init(void); -static int h3_keymap[] = { - KEY(0, 0, KEY_LEFT), - KEY(0, 1, KEY_RIGHT), - KEY(0, 2, KEY_3), - KEY(0, 3, KEY_F10), - KEY(0, 4, KEY_F5), - KEY(0, 5, KEY_9), - KEY(1, 0, KEY_DOWN), - KEY(1, 1, KEY_UP), - KEY(1, 2, KEY_2), - KEY(1, 3, KEY_F9), - KEY(1, 4, KEY_F7), - KEY(1, 5, KEY_0), - KEY(2, 0, KEY_ENTER), - KEY(2, 1, KEY_6), - KEY(2, 2, KEY_1), - KEY(2, 3, KEY_F2), - KEY(2, 4, KEY_F6), - KEY(2, 5, KEY_HOME), - KEY(3, 0, KEY_8), - KEY(3, 1, KEY_5), - KEY(3, 2, KEY_F12), - KEY(3, 3, KEY_F3), - KEY(3, 4, KEY_F8), - KEY(3, 5, KEY_END), - KEY(4, 0, KEY_7), - KEY(4, 1, KEY_4), - KEY(4, 2, KEY_F11), - KEY(4, 3, KEY_F1), - KEY(4, 4, KEY_F4), - KEY(4, 5, KEY_ESC), - KEY(5, 0, KEY_F13), - KEY(5, 1, KEY_F14), - KEY(5, 2, KEY_F15), - KEY(5, 3, KEY_F16), - KEY(5, 4, KEY_SLEEP), - 0 -}; - - -static struct mtd_partition nor_partitions[] = { +static struct mtd_partition h3_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { .name = "bootloader", @@ -119,80 +72,26 @@ static struct mtd_partition nor_partitions[] = { } }; -static struct flash_platform_data nor_data = { +static struct flash_platform_data h3_flash_data = { .map_name = "cfi_probe", .width = 2, - .parts = nor_partitions, - .nr_parts = ARRAY_SIZE(nor_partitions), + .parts = h3_partitions, + .nr_parts = ARRAY_SIZE(h3_partitions), }; -static struct resource nor_resource = { +static struct resource h3_flash_resource = { /* This is on CS3, wherever it's mapped */ .flags = IORESOURCE_MEM, }; -static struct platform_device nor_device = { +static struct platform_device flash_device = { .name = "omapflash", .id = 0, .dev = { - .platform_data = &nor_data, - }, - .num_resources = 1, - .resource = &nor_resource, -}; - -static struct mtd_partition nand_partitions[] = { -#if 0 - /* REVISIT: enable these partitions if you make NAND BOOT work */ - { - .name = "xloader", - .offset = 0, - .size = 64 * 1024, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "bootloader", - .offset = MTDPART_OFS_APPEND, - .size = 256 * 1024, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "params", - .offset = MTDPART_OFS_APPEND, - .size = 192 * 1024, - }, - { - .name = "kernel", - .offset = MTDPART_OFS_APPEND, - .size = 2 * SZ_1M, - }, -#endif - { - .name = "filesystem", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - }, -}; - -/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */ -static struct nand_platform_data nand_data = { - .options = NAND_SAMSUNG_LP_OPTIONS, - .parts = nand_partitions, - .nr_parts = ARRAY_SIZE(nand_partitions), -}; - -static struct resource nand_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device nand_device = { - .name = "omapnand", - .id = 0, - .dev = { - .platform_data = &nand_data, + .platform_data = &h3_flash_data, }, .num_resources = 1, - .resource = &nand_resource, + .resource = &h3_flash_resource, }; static struct resource smc91x_resources[] = { @@ -239,136 +138,10 @@ static struct platform_device intlat_device = { .resource = intlat_resources, }; -static struct resource h3_kp_resources[] = { - [0] = { - .start = INT_KEYBOARD, - .end = INT_KEYBOARD, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct omap_kp_platform_data h3_kp_data = { - .rows = 8, - .cols = 8, - .keymap = h3_keymap, - .rep = 1, -}; - -static struct platform_device h3_kp_device = { - .name = "omap-keypad", - .id = -1, - .dev = { - .platform_data = &h3_kp_data, - }, - .num_resources = ARRAY_SIZE(h3_kp_resources), - .resource = h3_kp_resources, -}; - - -/* Select between the IrDA and aGPS module - */ -static int h3_select_irda(struct device *dev, int state) -{ - unsigned char expa; - int err = 0; - - if ((err = read_gpio_expa(&expa, 0x26))) { - printk(KERN_ERR "Error reading from I/O EXPANDER \n"); - return err; - } - - /* 'P6' enable/disable IRDA_TX and IRDA_RX */ - if (state & IR_SEL) { /* IrDA */ - if ((err = write_gpio_expa(expa | 0x40, 0x26))) { - printk(KERN_ERR "Error writing to I/O EXPANDER \n"); - return err; - } - } else { - if ((err = write_gpio_expa(expa & ~0x40, 0x26))) { - printk(KERN_ERR "Error writing to I/O EXPANDER \n"); - return err; - } - } - return err; -} - -static void set_trans_mode(void *data) -{ - int *mode = data; - unsigned char expa; - int err = 0; - - if ((err = read_gpio_expa(&expa, 0x27)) != 0) { - printk(KERN_ERR "Error reading from I/O expander\n"); - } - - expa &= ~0x03; - - if (*mode & IR_SIRMODE) { - expa |= 0x01; - } else { /* MIR/FIR */ - expa |= 0x03; - } - - if ((err = write_gpio_expa(expa, 0x27)) != 0) { - printk(KERN_ERR "Error writing to I/O expander\n"); - } -} - -static int h3_transceiver_mode(struct device *dev, int mode) -{ - struct omap_irda_config *irda_config = dev->platform_data; - - cancel_delayed_work(&irda_config->gpio_expa); - PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); - schedule_work(&irda_config->gpio_expa); - - return 0; -} - -static struct omap_irda_config h3_irda_data = { - .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, - .transceiver_mode = h3_transceiver_mode, - .select_irda = h3_select_irda, - .rx_channel = OMAP_DMA_UART3_RX, - .tx_channel = OMAP_DMA_UART3_TX, - .dest_start = UART3_THR, - .src_start = UART3_RHR, - .tx_trigger = 0, - .rx_trigger = 0, -}; - -static struct resource h3_irda_resources[] = { - [0] = { - .start = INT_UART3, - .end = INT_UART3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device h3_irda_device = { - .name = "omapirda", - .id = 0, - .dev = { - .platform_data = &h3_irda_data, - }, - .num_resources = ARRAY_SIZE(h3_irda_resources), - .resource = h3_irda_resources, -}; - -static struct platform_device h3_lcd_device = { - .name = "lcd_h3", - .id = -1, -}; - static struct platform_device *devices[] __initdata = { - &nor_device, - &nand_device, + &flash_device, &smc91x_device, &intlat_device, - &h3_irda_device, - &h3_kp_device, - &h3_lcd_device, }; static struct omap_usb_config h3_usb_config __initdata = { @@ -398,6 +171,7 @@ static struct omap_uart_config h3_uart_config __initdata = { }; static struct omap_lcd_config h3_lcd_config __initdata = { + .panel_name = "h3", .ctrl_name = "internal", }; @@ -408,36 +182,11 @@ static struct omap_board_config_kernel h3_config[] = { { OMAP_TAG_LCD, &h3_lcd_config }, }; -#define H3_NAND_RB_GPIO_PIN 10 - -static int nand_dev_ready(struct nand_platform_data *data) -{ - return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN); -} - static void __init h3_init(void) { - /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped - * to address 0 by a dip switch), NAND on CS2B. The NAND driver will - * notice whether a NAND chip is enabled at probe time. - * - * H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND - * (which on H2 may be 16bit) on CS3. Try detecting that in code here, - * to avoid probing every possible flash configuration... - */ - nor_resource.end = nor_resource.start = omap_cs3_phys(); - nor_resource.end += SZ_32M - 1; - - nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS; - nand_resource.end += SZ_4K - 1; - if (!(omap_request_gpio(H3_NAND_RB_GPIO_PIN))) - nand_data.dev_ready = nand_dev_ready; - - /* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */ - /* GPIO10 pullup/down register, Enable pullup on GPIO10 */ - omap_cfg_reg(V2_1710_GPIO10); - - platform_add_devices(devices, ARRAY_SIZE(devices)); + h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys(); + h3_flash_resource.end += OMAP_CS3_SIZE - 1; + (void) platform_add_devices(devices, ARRAY_SIZE(devices)); omap_board_config = h3_config; omap_board_config_size = ARRAY_SIZE(h3_config); omap_serial_init(); diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index e90c137a4..a04e43329 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -35,22 +34,8 @@ #include #include #include -#include #include -static int innovator_keymap[] = { - KEY(0, 0, KEY_F1), - KEY(0, 3, KEY_DOWN), - KEY(1, 1, KEY_F2), - KEY(1, 2, KEY_RIGHT), - KEY(2, 0, KEY_F3), - KEY(2, 1, KEY_F4), - KEY(2, 2, KEY_UP), - KEY(3, 2, KEY_ENTER), - KEY(3, 3, KEY_LEFT), - 0 -}; - static struct mtd_partition innovator_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { @@ -112,31 +97,6 @@ static struct platform_device innovator_flash_device = { .resource = &innovator_flash_resource, }; -static struct resource innovator_kp_resources[] = { - [0] = { - .start = INT_KEYBOARD, - .end = INT_KEYBOARD, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct omap_kp_platform_data innovator_kp_data = { - .rows = 8, - .cols = 8, - .keymap = innovator_keymap, -}; - -static struct platform_device innovator_kp_device = { - .name = "omap-keypad", - .id = -1, - .dev = { - .platform_data = &innovator_kp_data, - }, - .num_resources = ARRAY_SIZE(innovator_kp_resources), - .resource = innovator_kp_resources, -}; - - #ifdef CONFIG_ARCH_OMAP15XX /* Only FPGA needs to be mapped here. All others are done with ioremap */ @@ -169,16 +129,9 @@ static struct platform_device innovator1510_smc91x_device = { .resource = innovator1510_smc91x_resources, }; -static struct platform_device innovator1510_lcd_device = { - .name = "lcd_inn1510", - .id = -1, -}; - static struct platform_device *innovator1510_devices[] __initdata = { &innovator_flash_device, &innovator1510_smc91x_device, - &innovator_kp_device, - &innovator1510_lcd_device, }; #endif /* CONFIG_ARCH_OMAP15XX */ @@ -205,16 +158,9 @@ static struct platform_device innovator1610_smc91x_device = { .resource = innovator1610_smc91x_resources, }; -static struct platform_device innovator1610_lcd_device = { - .name = "inn1610_lcd", - .id = -1, -}; - static struct platform_device *innovator1610_devices[] __initdata = { &innovator_flash_device, &innovator1610_smc91x_device, - &innovator_kp_device, - &innovator1610_lcd_device, }; #endif /* CONFIG_ARCH_OMAP16XX */ @@ -260,6 +206,7 @@ static struct omap_usb_config innovator1510_usb_config __initdata = { }; static struct omap_lcd_config innovator1510_lcd_config __initdata = { + .panel_name = "inn1510", .ctrl_name = "internal", }; #endif @@ -281,6 +228,7 @@ static struct omap_usb_config h2_usb_config __initdata = { }; static struct omap_lcd_config innovator1610_lcd_config __initdata = { + .panel_name = "inn1610", .ctrl_name = "internal", }; #endif diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c deleted file mode 100644 index 02b980d77..000000000 --- a/arch/arm/mach-omap1/board-nokia770.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * linux/arch/arm/mach-omap1/board-nokia770.c - * - * Modified from board-generic.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void __init omap_nokia770_init_irq(void) -{ - /* On Nokia 770, the SleepX signal is masked with an - * MPUIO line by default. It has to be unmasked for it - * to become functional */ - - /* SleepX mask direction */ - omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); - /* Unmask SleepX signal */ - omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); - - omap1_init_common_hw(); - omap_init_irq(); -} - -static int nokia770_keymap[] = { - KEY(0, 1, GROUP_0 | KEY_UP), - KEY(0, 2, GROUP_1 | KEY_F5), - KEY(1, 0, GROUP_0 | KEY_LEFT), - KEY(1, 1, GROUP_0 | KEY_ENTER), - KEY(1, 2, GROUP_0 | KEY_RIGHT), - KEY(2, 0, GROUP_1 | KEY_ESC), - KEY(2, 1, GROUP_0 | KEY_DOWN), - KEY(2, 2, GROUP_1 | KEY_F4), - KEY(3, 0, GROUP_2 | KEY_F7), - KEY(3, 1, GROUP_2 | KEY_F8), - KEY(3, 2, GROUP_2 | KEY_F6), - 0 -}; - -static struct resource nokia770_kp_resources[] = { - [0] = { - .start = INT_KEYBOARD, - .end = INT_KEYBOARD, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct omap_kp_platform_data nokia770_kp_data = { - .rows = 8, - .cols = 8, - .keymap = nokia770_keymap -}; - -static struct platform_device nokia770_kp_device = { - .name = "omap-keypad", - .id = -1, - .dev = { - .platform_data = &nokia770_kp_data, - }, - .num_resources = ARRAY_SIZE(nokia770_kp_resources), - .resource = nokia770_kp_resources, -}; - -static struct platform_device *nokia770_devices[] __initdata = { - &nokia770_kp_device, -}; - -static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = { - .x_max = 0x0fff, - .y_max = 0x0fff, - .x_plate_ohms = 180, - .pressure_max = 255, - .debounce_max = 10, - .debounce_tol = 3, -}; - -static struct spi_board_info nokia770_spi_board_info[] __initdata = { - [0] = { - .modalias = "lcd_lph8923", - .bus_num = 2, - .chip_select = 3, - .max_speed_hz = 12000000, - }, - [1] = { - .modalias = "ads7846", - .bus_num = 2, - .chip_select = 0, - .max_speed_hz = 2500000, - .irq = OMAP_GPIO_IRQ(15), - .platform_data = &nokia770_ads7846_platform_data, - }, -}; - - -/* assume no Mini-AB port */ - -static struct omap_usb_config nokia770_usb_config __initdata = { - .otg = 1, - .register_host = 1, - .register_dev = 1, - .hmc_mode = 16, - .pins[0] = 6, -}; - -static struct omap_mmc_config nokia770_mmc_config __initdata = { - .mmc[0] = { - .enabled = 0, - .wire4 = 0, - .wp_pin = -1, - .power_pin = -1, - .switch_pin = -1, - }, - .mmc[1] = { - .enabled = 0, - .wire4 = 0, - .wp_pin = -1, - .power_pin = -1, - .switch_pin = -1, - }, -}; - -static struct omap_board_config_kernel nokia770_config[] = { - { OMAP_TAG_USB, NULL }, - { OMAP_TAG_MMC, &nokia770_mmc_config }, -}; - -/* - * audio power control - */ -#define HEADPHONE_GPIO 14 -#define AMPLIFIER_CTRL_GPIO 58 - -static struct clk *dspxor_ck; -static DECLARE_MUTEX(audio_pwr_sem); -/* - * audio_pwr_state - * +--+-------------------------+---------------------------------------+ - * |-1|down |power-up request -> 0 | - * +--+-------------------------+---------------------------------------+ - * | 0|up |power-down(1) request -> 1 | - * | | |power-down(2) request -> (ignore) | - * +--+-------------------------+---------------------------------------+ - * | 1|up, |power-up request -> 0 | - * | |received down(1) request |power-down(2) request -> -1 | - * +--+-------------------------+---------------------------------------+ - */ -static int audio_pwr_state = -1; - -/* - * audio_pwr_up / down should be called under audio_pwr_sem - */ -static void nokia770_audio_pwr_up(void) -{ - clk_enable(dspxor_ck); - - /* Turn on codec */ - tlv320aic23_power_up(); - - if (omap_get_gpio_datain(HEADPHONE_GPIO)) - /* HP not connected, turn on amplifier */ - omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1); - else - /* HP connected, do not turn on amplifier */ - printk("HP connected\n"); -} - -static void codec_delayed_power_down(void *arg) -{ - down(&audio_pwr_sem); - if (audio_pwr_state == -1) - tlv320aic23_power_down(); - clk_disable(dspxor_ck); - up(&audio_pwr_sem); -} - -static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL); - -static void nokia770_audio_pwr_down(void) -{ - /* Turn off amplifier */ - omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0); - - /* Turn off codec: schedule delayed work */ - schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */ -} - -void nokia770_audio_pwr_up_request(int stage) -{ - down(&audio_pwr_sem); - if (audio_pwr_state == -1) - nokia770_audio_pwr_up(); - /* force audio_pwr_state = 0, even if it was 1. */ - audio_pwr_state = 0; - up(&audio_pwr_sem); -} - -void nokia770_audio_pwr_down_request(int stage) -{ - down(&audio_pwr_sem); - switch (stage) { - case 1: - if (audio_pwr_state == 0) - audio_pwr_state = 1; - break; - case 2: - if (audio_pwr_state == 1) { - nokia770_audio_pwr_down(); - audio_pwr_state = -1; - } - break; - } - up(&audio_pwr_sem); -} - -static void __init omap_nokia770_init(void) -{ - nokia770_config[0].data = &nokia770_usb_config; - - platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); - spi_register_board_info(nokia770_spi_board_info, - ARRAY_SIZE(nokia770_spi_board_info)); - omap_board_config = nokia770_config; - omap_board_config_size = ARRAY_SIZE(nokia770_config); - omap_serial_init(); - omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request; - omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request; - dspxor_ck = clk_get(0, "dspxor_ck"); -} - -static void __init omap_nokia770_map_io(void) -{ - omap1_map_common_io(); -} - -MACHINE_START(NOKIA770, "Nokia 770") - .phys_io = 0xfff00000, - .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, - .boot_params = 0x10000100, - .map_io = omap_nokia770_map_io, - .init_irq = omap_nokia770_init_irq, - .init_machine = omap_nokia770_init, - .timer = &omap_timer, -MACHINE_END diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 1160093e8..543fa1361 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -45,24 +44,7 @@ #include #include #include -#include #include -#include -#include - -static int osk_keymap[] = { - KEY(0, 0, KEY_F1), - KEY(0, 3, KEY_UP), - KEY(1, 1, KEY_LEFTCTRL), - KEY(1, 2, KEY_LEFT), - KEY(2, 0, KEY_SPACE), - KEY(2, 1, KEY_ESC), - KEY(2, 2, KEY_DOWN), - KEY(3, 2, KEY_ENTER), - KEY(3, 3, KEY_RIGHT), - 0 -}; - static struct mtd_partition osk_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ @@ -151,69 +133,9 @@ static struct platform_device osk5912_cf_device = { .resource = osk5912_cf_resources, }; -#define DEFAULT_BITPERSAMPLE 16 - -static struct omap_mcbsp_reg_cfg mcbsp_regs = { - .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), - .spcr1 = RINTM(3) | RRST, - .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | - RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), - .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), - .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, - .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), - .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), - .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), - /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */ - .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ -}; - -static struct omap_alsa_codec_config alsa_config = { - .name = "OSK AIC23", - .mcbsp_regs_alsa = &mcbsp_regs, - .codec_configure_dev = NULL, // aic23_configure, - .codec_set_samplerate = NULL, // aic23_set_samplerate, - .codec_clock_setup = NULL, // aic23_clock_setup, - .codec_clock_on = NULL, // aic23_clock_on, - .codec_clock_off = NULL, // aic23_clock_off, - .get_default_samplerate = NULL, // aic23_get_default_samplerate, -}; - static struct platform_device osk5912_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &alsa_config, - }, -}; - -static struct resource osk5912_kp_resources[] = { - [0] = { - .start = INT_KEYBOARD, - .end = INT_KEYBOARD, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct omap_kp_platform_data osk_kp_data = { - .rows = 8, - .cols = 8, - .keymap = osk_keymap, -}; - -static struct platform_device osk5912_kp_device = { - .name = "omap-keypad", - .id = -1, - .dev = { - .platform_data = &osk_kp_data, - }, - .num_resources = ARRAY_SIZE(osk5912_kp_resources), - .resource = osk5912_kp_resources, -}; - -static struct platform_device osk5912_lcd_device = { - .name = "lcd_osk", - .id = -1, + .name = "omap_mcbsp", + .id = 1, }; static struct platform_device *osk5912_devices[] __initdata = { @@ -221,8 +143,6 @@ static struct platform_device *osk5912_devices[] __initdata = { &osk5912_smc91x_device, &osk5912_cf_device, &osk5912_mcbsp1_device, - &osk5912_kp_device, - &osk5912_lcd_device, }; static void __init osk_init_smc91x(void) @@ -277,6 +197,7 @@ static struct omap_uart_config osk_uart_config __initdata = { }; static struct omap_lcd_config osk_lcd_config __initdata = { + .panel_name = "osk", .ctrl_name = "internal", }; @@ -334,18 +255,8 @@ static void __init osk_mistral_init(void) static void __init osk_mistral_init(void) { } #endif -#define EMIFS_CS3_VAL (0x88013141) - static void __init osk_init(void) { - /* Workaround for wrong CS3 (NOR flash) timing - * There are some U-Boot versions out there which configure - * wrong CS3 memory timings. This mainly leads to CRC - * or similiar errors if you use NOR flash (e.g. with JFFS2) - */ - if (EMIFS_CCS(3) != EMIFS_CS3_VAL) - EMIFS_CCS(3) = EMIFS_CS3_VAL; - osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); osk_flash_resource.end += SZ_32M - 1; platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 4bc8a6290..e488f7236 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -38,15 +38,6 @@ static void __init omap_generic_init_irq(void) omap_init_irq(); } -static struct platform_device palmte_lcd_device = { - .name = "lcd_palmte", - .id = -1, -}; - -static struct platform_device *devices[] __initdata = { - &palmte_lcd_device, -}; - static struct omap_usb_config palmte_usb_config __initdata = { .register_dev = 1, .hmc_mode = 0, @@ -64,6 +55,7 @@ static struct omap_mmc_config palmte_mmc_config __initdata = { }; static struct omap_lcd_config palmte_lcd_config __initdata = { + .panel_name = "palmte", .ctrl_name = "internal", }; @@ -77,8 +69,6 @@ static void __init omap_generic_init(void) { omap_board_config = palmte_config; omap_board_config_size = ARRAY_SIZE(palmte_config); - - platform_add_devices(devices, ARRAY_SIZE(devices)); } static void __init omap_generic_map_io(void) diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 64b45d8ae..3913a3cc0 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -16,9 +16,7 @@ #include #include #include -#include #include -#include #include #include @@ -30,44 +28,9 @@ #include #include #include -#include #include #include -static int p2_keymap[] = { - KEY(0,0,KEY_UP), - KEY(0,1,KEY_RIGHT), - KEY(0,2,KEY_LEFT), - KEY(0,3,KEY_DOWN), - KEY(0,4,KEY_CENTER), - KEY(0,5,KEY_0_5), - KEY(1,0,KEY_SOFT2), - KEY(1,1,KEY_SEND), - KEY(1,2,KEY_END), - KEY(1,3,KEY_VOLUMEDOWN), - KEY(1,4,KEY_VOLUMEUP), - KEY(1,5,KEY_RECORD), - KEY(2,0,KEY_SOFT1), - KEY(2,1,KEY_3), - KEY(2,2,KEY_6), - KEY(2,3,KEY_9), - KEY(2,4,KEY_SHARP), - KEY(2,5,KEY_2_5), - KEY(3,0,KEY_BACK), - KEY(3,1,KEY_2), - KEY(3,2,KEY_5), - KEY(3,3,KEY_8), - KEY(3,4,KEY_0), - KEY(3,5,KEY_HEADSETHOOK), - KEY(4,0,KEY_HOME), - KEY(4,1,KEY_1), - KEY(4,2,KEY_4), - KEY(4,3,KEY_7), - KEY(4,4,KEY_STAR), - KEY(4,5,KEY_POWER), - 0 -}; - static struct resource smc91x_resources[] = { [0] = { .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */ @@ -81,7 +44,7 @@ static struct resource smc91x_resources[] = { }, }; -static struct mtd_partition nor_partitions[] = { +static struct mtd_partition p2_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { .name = "bootloader", @@ -112,47 +75,27 @@ static struct mtd_partition nor_partitions[] = { }, }; -static struct flash_platform_data nor_data = { +static struct flash_platform_data p2_flash_data = { .map_name = "cfi_probe", .width = 2, - .parts = nor_partitions, - .nr_parts = ARRAY_SIZE(nor_partitions), + .parts = p2_partitions, + .nr_parts = ARRAY_SIZE(p2_partitions), }; -static struct resource nor_resource = { +static struct resource p2_flash_resource = { .start = OMAP_CS0_PHYS, .end = OMAP_CS0_PHYS + SZ_32M - 1, .flags = IORESOURCE_MEM, }; -static struct platform_device nor_device = { +static struct platform_device p2_flash_device = { .name = "omapflash", .id = 0, .dev = { - .platform_data = &nor_data, - }, - .num_resources = 1, - .resource = &nor_resource, -}; - -static struct nand_platform_data nand_data = { - .options = NAND_SAMSUNG_LP_OPTIONS, -}; - -static struct resource nand_resource = { - .start = OMAP_CS3_PHYS, - .end = OMAP_CS3_PHYS + SZ_4K - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device nand_device = { - .name = "omapnand", - .id = 0, - .dev = { - .platform_data = &nand_data, + .platform_data = &p2_flash_data, }, .num_resources = 1, - .resource = &nand_resource, + .resource = &p2_flash_resource, }; static struct platform_device smc91x_device = { @@ -162,55 +105,17 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -static struct resource kp_resources[] = { - [0] = { - .start = INT_730_MPUIO_KEYPAD, - .end = INT_730_MPUIO_KEYPAD, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct omap_kp_platform_data kp_data = { - .rows = 8, - .cols = 8, - .keymap = p2_keymap, -}; - -static struct platform_device kp_device = { - .name = "omap-keypad", - .id = -1, - .dev = { - .platform_data = &kp_data, - }, - .num_resources = ARRAY_SIZE(kp_resources), - .resource = kp_resources, -}; - -static struct platform_device lcd_device = { - .name = "lcd_p2", - .id = -1, -}; - static struct platform_device *devices[] __initdata = { - &nor_device, - &nand_device, + &p2_flash_device, &smc91x_device, - &kp_device, - &lcd_device, }; -#define P2_NAND_RB_GPIO_PIN 62 - -static int nand_dev_ready(struct nand_platform_data *data) -{ - return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN); -} - static struct omap_uart_config perseus2_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1)), }; static struct omap_lcd_config perseus2_lcd_config __initdata = { + .panel_name = "p2", .ctrl_name = "internal", }; @@ -221,13 +126,7 @@ static struct omap_board_config_kernel perseus2_config[] = { static void __init omap_perseus2_init(void) { - if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN))) - nand_data.dev_ready = nand_dev_ready; - - omap_cfg_reg(L3_1610_FLASH_CS2B_OE); - omap_cfg_reg(M8_1610_FLASH_CS2B_WE); - - platform_add_devices(devices, ARRAY_SIZE(devices)); + (void) platform_add_devices(devices, ARRAY_SIZE(devices)); omap_board_config = perseus2_config; omap_board_config_size = ARRAY_SIZE(perseus2_config); diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 447a586eb..bfd5fdd1a 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -155,9 +155,9 @@ static struct omap_uart_config voiceblue_uart_config __initdata = { }; static struct omap_board_config_kernel voiceblue_config[] = { - { OMAP_TAG_USB, &voiceblue_usb_config }, - { OMAP_TAG_MMC, &voiceblue_mmc_config }, - { OMAP_TAG_UART, &voiceblue_uart_config }, + { OMAP_TAG_USB, &voiceblue_usb_config }, + { OMAP_TAG_MMC, &voiceblue_mmc_config }, + { OMAP_TAG_UART, &voiceblue_uart_config }, }; static void __init voiceblue_init_irq(void) diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 619db1814..75110ba10 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -345,7 +345,7 @@ static unsigned calc_ext_dsor(unsigned long rate) */ for (dsor = 2; dsor < 96; ++dsor) { if ((dsor & 1) && dsor > 8) - continue; + continue; if (rate >= 96000000 / dsor) break; } @@ -687,11 +687,6 @@ int __init omap1_clk_init(void) clk_register(*clkp); continue; } - - if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) { - clk_register(*clkp); - continue; - } } info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); @@ -789,7 +784,7 @@ int __init omap1_clk_init(void) clk_enable(&armxor_ck.clk); clk_enable(&armtim_ck.clk); /* This should be done by timer code */ - if (cpu_is_omap15xx()) + if (cpu_is_omap1510()) clk_enable(&arm_gpio_ck); return 0; diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index b7c68819c..4f18d1b94 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -151,7 +151,7 @@ static struct clk ck_ref = { .name = "ck_ref", .rate = 12000000, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | ALWAYS_ENABLED, + ALWAYS_ENABLED, .enable = &omap1_clk_enable_generic, .disable = &omap1_clk_disable_generic, }; @@ -160,7 +160,7 @@ static struct clk ck_dpll1 = { .name = "ck_dpll1", .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED, + RATE_PROPAGATES | ALWAYS_ENABLED, .enable = &omap1_clk_enable_generic, .disable = &omap1_clk_disable_generic, }; @@ -183,8 +183,7 @@ static struct clk arm_ck = { .name = "arm_ck", .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES | - ALWAYS_ENABLED, + RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, .rate_offset = CKCTL_ARMDIV_OFFSET, .recalc = &omap1_ckctl_recalc, .enable = &omap1_clk_enable_generic, @@ -196,8 +195,7 @@ static struct arm_idlect1_clk armper_ck = { .name = "armper_ck", .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | RATE_CKCTL | - CLOCK_IDLE_CONTROL, + RATE_CKCTL | CLOCK_IDLE_CONTROL, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_PERCK, .rate_offset = CKCTL_PERDIV_OFFSET, @@ -211,7 +209,7 @@ static struct arm_idlect1_clk armper_ck = { static struct clk arm_gpio_ck = { .name = "arm_gpio_ck", .parent = &ck_dpll1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, + .flags = CLOCK_IN_OMAP1510, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_GPIOCK, .recalc = &followparent_recalc, @@ -224,7 +222,7 @@ static struct arm_idlect1_clk armxor_ck = { .name = "armxor_ck", .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL, + CLOCK_IDLE_CONTROL, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_XORPCK, .recalc = &followparent_recalc, @@ -239,7 +237,7 @@ static struct arm_idlect1_clk armtim_ck = { .name = "armtim_ck", .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL, + CLOCK_IDLE_CONTROL, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_TIMCK, .recalc = &followparent_recalc, @@ -254,7 +252,7 @@ static struct arm_idlect1_clk armwdt_ck = { .name = "armwdt_ck", .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL, + CLOCK_IDLE_CONTROL, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_WDTCK, .recalc = &omap1_watchdog_recalc, @@ -346,9 +344,9 @@ static struct arm_idlect1_clk tc_ck = { .name = "tc_ck", .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 | - RATE_CKCTL | RATE_PROPAGATES | - ALWAYS_ENABLED | CLOCK_IDLE_CONTROL, + CLOCK_IN_OMAP730 | RATE_CKCTL | + RATE_PROPAGATES | ALWAYS_ENABLED | + CLOCK_IDLE_CONTROL, .rate_offset = CKCTL_TCDIV_OFFSET, .recalc = &omap1_ckctl_recalc, .enable = &omap1_clk_enable_generic, @@ -360,8 +358,7 @@ static struct arm_idlect1_clk tc_ck = { static struct clk arminth_ck1510 = { .name = "arminth_ck", .parent = &tc_ck.clk, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | - ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, .recalc = &followparent_recalc, /* Note: On 1510 the frequency follows TC_CK * @@ -375,8 +372,7 @@ static struct clk tipb_ck = { /* No-idle controlled by "tc_ck" */ .name = "tibp_ck", .parent = &tc_ck.clk, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | - ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, .recalc = &followparent_recalc, .enable = &omap1_clk_enable_generic, .disable = &omap1_clk_disable_generic, @@ -421,7 +417,7 @@ static struct clk dma_ck = { .name = "dma_ck", .parent = &tc_ck.clk, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | ALWAYS_ENABLED, + ALWAYS_ENABLED, .recalc = &followparent_recalc, .enable = &omap1_clk_enable_generic, .disable = &omap1_clk_disable_generic, @@ -441,7 +437,7 @@ static struct arm_idlect1_clk api_ck = { .name = "api_ck", .parent = &tc_ck.clk, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL, + CLOCK_IDLE_CONTROL, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_APICK, .recalc = &followparent_recalc, @@ -455,8 +451,7 @@ static struct arm_idlect1_clk lb_ck = { .clk = { .name = "lb_ck", .parent = &tc_ck.clk, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | - CLOCK_IDLE_CONTROL, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_LBCK, .recalc = &followparent_recalc, @@ -500,8 +495,8 @@ static struct arm_idlect1_clk lcd_ck_1510 = { .clk = { .name = "lcd_ck", .parent = &ck_dpll1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | - RATE_CKCTL | CLOCK_IDLE_CONTROL, + .flags = CLOCK_IN_OMAP1510 | RATE_CKCTL | + CLOCK_IDLE_CONTROL, .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_LCDCK, .rate_offset = CKCTL_LCDDIV_OFFSET, @@ -517,9 +512,8 @@ static struct clk uart1_1510 = { /* Direct from ULPD, no real parent */ .parent = &armper_ck.clk, .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | - ENABLE_REG_32BIT | ALWAYS_ENABLED | - CLOCK_NO_IDLE_PARENT, + .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | + ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ .set_rate = &omap1_set_uart_rate, @@ -550,8 +544,8 @@ static struct clk uart2_ck = { .parent = &armper_ck.clk, .rate = 12000000, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | ENABLE_REG_32BIT | - ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, + ENABLE_REG_32BIT | ALWAYS_ENABLED | + CLOCK_NO_IDLE_PARENT, .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ .set_rate = &omap1_set_uart_rate, @@ -565,9 +559,8 @@ static struct clk uart3_1510 = { /* Direct from ULPD, no real parent */ .parent = &armper_ck.clk, .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | - ENABLE_REG_32BIT | ALWAYS_ENABLED | - CLOCK_NO_IDLE_PARENT, + .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | + ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ .set_rate = &omap1_set_uart_rate, @@ -597,7 +590,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ /* Direct from ULPD, no parent */ .rate = 6000000, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT, + RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL, .enable_bit = USB_MCLK_EN_BIT, .enable = &omap1_clk_enable_generic, @@ -608,7 +601,7 @@ static struct clk usb_hhc_ck1510 = { .name = "usb_hhc_ck", /* Direct from ULPD, no parent */ .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | + .flags = CLOCK_IN_OMAP1510 | RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = USB_HOST_HHC_UHOST_EN, @@ -644,9 +637,7 @@ static struct clk mclk_1510 = { .name = "mclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED, - .enable_reg = (void __iomem *)SOFT_REQ_REG, - .enable_bit = 6, + .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, .enable = &omap1_clk_enable_generic, .disable = &omap1_clk_disable_generic, }; @@ -668,7 +659,7 @@ static struct clk bclk_1510 = { .name = "bclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED, + .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, .enable = &omap1_clk_enable_generic, .disable = &omap1_clk_disable_generic, }; @@ -687,14 +678,12 @@ static struct clk bclk_16xx = { }; static struct clk mmc1_ck = { - .name = "mmc_ck", - .id = 1, + .name = "mmc1_ck", /* Functional clock is direct from ULPD, interface clock is ARMPER */ .parent = &armper_ck.clk, .rate = 48000000, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT | - CLOCK_NO_IDLE_PARENT, + RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 23, .enable = &omap1_clk_enable_generic, @@ -702,8 +691,7 @@ static struct clk mmc1_ck = { }; static struct clk mmc2_ck = { - .name = "mmc_ck", - .id = 2, + .name = "mmc2_ck", /* Functional clock is direct from ULPD, interface clock is ARMPER */ .parent = &armper_ck.clk, .rate = 48000000, @@ -718,7 +706,7 @@ static struct clk mmc2_ck = { static struct clk virtual_ck_mpu = { .name = "mpu", .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED, + VIRTUAL_CLOCK | ALWAYS_ENABLED, .parent = &arm_ck, /* Is smarter alias for */ .recalc = &followparent_recalc, .set_rate = &omap1_select_table_rate, @@ -727,20 +715,6 @@ static struct clk virtual_ck_mpu = { .disable = &omap1_clk_disable_generic, }; -/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK -remains active during MPU idle whenever this is enabled */ -static struct clk i2c_fck = { - .name = "i2c_fck", - .id = 1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | - VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT | - ALWAYS_ENABLED, - .parent = &armxor_ck.clk, - .recalc = &followparent_recalc, - .enable = &omap1_clk_enable_generic, - .disable = &omap1_clk_disable_generic, -}; - static struct clk * onchip_clks[] = { /* non-ULPD clocks */ &ck_ref, @@ -789,7 +763,6 @@ static struct clk * onchip_clks[] = { &mmc2_ck, /* Virtual clocks */ &virtual_ck_mpu, - &i2c_fck, }; #endif diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 847329caf..ecbc47514 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -25,6 +25,10 @@ #include #include +extern void omap_nop_release(struct device *dev); + +/*-------------------------------------------------------------------------*/ + #if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE) static u64 irda_dmamask = 0xffffffff; @@ -33,6 +37,7 @@ static struct platform_device omap1610ir_device = { .name = "omap1610-ir", .id = -1, .dev = { + .release = omap_nop_release, .dma_mask = &irda_dmamask, }, }; @@ -79,6 +84,9 @@ static struct resource rtc_resources[] = { static struct platform_device omap_rtc_device = { .name = "omap_rtc", .id = -1, + .dev = { + .release = omap_nop_release, + }, .num_resources = ARRAY_SIZE(rtc_resources), .resource = rtc_resources, }; @@ -91,42 +99,6 @@ static void omap_init_rtc(void) static inline void omap_init_rtc(void) {} #endif -#if defined(CONFIG_OMAP_STI) - -#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000) -#define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400) - -static struct resource sti_resources[] = { - { - .start = OMAP1_STI_BASE, - .end = OMAP1_STI_BASE + SZ_1K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = OMAP1_STI_CHANNEL_BASE, - .end = OMAP1_STI_CHANNEL_BASE + SZ_1K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_1610_STI, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device sti_device = { - .name = "sti", - .id = -1, - .num_resources = ARRAY_SIZE(sti_resources), - .resource = sti_resources, -}; - -static inline void omap_init_sti(void) -{ - platform_device_register(&sti_device); -} -#else -static inline void omap_init_sti(void) {} -#endif /*-------------------------------------------------------------------------*/ @@ -157,7 +129,6 @@ static int __init omap1_init_devices(void) */ omap_init_irda(); omap_init_rtc(); - omap_init_sti(); return 0; } diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index be3a2a4ee..82d556be7 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -18,7 +18,6 @@ #include #include #include -#include extern int omap1_clk_init(void); extern void omap_check_revision(void); @@ -111,7 +110,7 @@ void __init omap1_map_common_io(void) } #endif #ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap15xx()) { + if (cpu_is_omap1510()) { iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); } #endif @@ -122,7 +121,6 @@ void __init omap1_map_common_io(void) #endif omap_sram_init(); - omapfb_reserve_mem(); } /* diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index a0431c00f..ed65a7d2e 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -60,7 +60,7 @@ struct omap_irq_bank { unsigned long wake_enable; }; -static unsigned int irq_bank_count; +static unsigned int irq_bank_count = 0; static struct omap_irq_bank *irq_banks; static inline unsigned int irq_bank_readl(int bank, int offset) @@ -142,28 +142,28 @@ static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger) #ifdef CONFIG_ARCH_OMAP730 static struct omap_irq_bank omap730_irq_banks[] = { - { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, - { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 }, }; #endif #ifdef CONFIG_ARCH_OMAP15XX static struct omap_irq_bank omap1510_irq_banks[] = { - { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, - { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, }; static struct omap_irq_bank omap310_irq_banks[] = { - { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, - { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, }; #endif #if defined(CONFIG_ARCH_OMAP16XX) static struct omap_irq_bank omap1610_irq_banks[] = { - { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, - { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff }, { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff }, }; diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 10fe0b3ef..d4b8d624e 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -35,20 +35,16 @@ #ifdef CONFIG_ARCH_OMAP730 struct pin_config __initdata_or_module omap730_pins[] = { -MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0) -MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0) -MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0) -MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 1, 0) -MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 4, 1, 0) -MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 8, 1, 0) -MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 12, 1, 0) -MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 16, 1, 0) -MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 20, 1, 0) -MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 24, 1, 0) - -MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0) -MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0) -MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0) +MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0) +MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0) +MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0) +MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0) +MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0) +MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0) +MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0) +MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0) +MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0) +MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0) }; #endif @@ -77,8 +73,8 @@ MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0) MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0) /* PWT & PWL, conflicts with UART3 */ -MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) -MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) +MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) +MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) /* USB internal master generic */ MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1) @@ -155,7 +151,7 @@ MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1) /* Misc ballouts */ MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1) -MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) +MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) /* OMAP-1610 MMC2 */ MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1) diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c deleted file mode 100644 index ddf6b07dc..000000000 --- a/arch/arm/mach-omap1/pm.c +++ /dev/null @@ -1,770 +0,0 @@ -/* - * linux/arch/arm/mach-omap1/pm.c - * - * OMAP Power Management Routines - * - * Original code for the SA11x0: - * Copyright (c) 2001 Cliff Brake - * - * Modified for the PXA250 by Nicolas Pitre: - * Copyright (c) 2002 Monta Vista Software, Inc. - * - * Modified for the OMAP1510 by David Singleton: - * Copyright (c) 2002 Monta Vista Software, Inc. - * - * Cleanup 2004 for OMAP1510/1610 by Dirk Behme - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; -static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE]; -static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; -static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE]; -static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; -static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; - -static unsigned short enable_dyn_sleep = 1; - -static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf) -{ - return sprintf(buf, "%hu\n", enable_dyn_sleep); -} - -static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys, - const char * buf, - size_t n) -{ - unsigned short value; - if (sscanf(buf, "%hu", &value) != 1 || - (value != 0 && value != 1)) { - printk(KERN_ERR "idle_sleep_store: Invalid value\n"); - return -EINVAL; - } - enable_dyn_sleep = value; - return n; -} - -static struct subsys_attribute sleep_while_idle_attr = { - .attr = { - .name = __stringify(sleep_while_idle), - .mode = 0644, - }, - .show = omap_pm_sleep_while_idle_show, - .store = omap_pm_sleep_while_idle_store, -}; - -extern struct subsystem power_subsys; -static void (*omap_sram_idle)(void) = NULL; -static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; - -/* - * Let's power down on idle, but only if we are really - * idle, because once we start down the path of - * going idle we continue to do idle even if we get - * a clock tick interrupt . . - */ -void omap_pm_idle(void) -{ - extern __u32 arm_idlect1_mask; - __u32 use_idlect1 = arm_idlect1_mask; -#ifndef CONFIG_OMAP_MPU_TIMER - int do_sleep; -#endif - - local_irq_disable(); - local_fiq_disable(); - if (need_resched()) { - local_fiq_enable(); - local_irq_enable(); - return; - } - - /* - * Since an interrupt may set up a timer, we don't want to - * reprogram the hardware timer with interrupts enabled. - * Re-enable interrupts only after returning from idle. - */ - timer_dyn_reprogram(); - -#ifdef CONFIG_OMAP_MPU_TIMER -#warning Enable 32kHz OS timer in order to allow sleep states in idle - use_idlect1 = use_idlect1 & ~(1 << 9); -#else - - do_sleep = 0; - while (enable_dyn_sleep) { - -#ifdef CONFIG_CBUS_TAHVO_USB - extern int vbus_active; - /* Clock requirements? */ - if (vbus_active) - break; -#endif - do_sleep = 1; - break; - } - -#ifdef CONFIG_OMAP_DM_TIMER - use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1); -#endif - - if (omap_dma_running()) { - use_idlect1 &= ~(1 << 6); - if (omap_lcd_dma_ext_running()) - use_idlect1 &= ~(1 << 12); - } - - /* We should be able to remove the do_sleep variable and multiple - * tests above as soon as drivers, timer and DMA code have been fixed. - * Even the sleep block count should become obsolete. */ - if ((use_idlect1 != ~0) || !do_sleep) { - - __u32 saved_idlect1 = omap_readl(ARM_IDLECT1); - if (cpu_is_omap15xx()) - use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST; - else - use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL; - omap_writel(use_idlect1, ARM_IDLECT1); - __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); - omap_writel(saved_idlect1, ARM_IDLECT1); - - local_fiq_enable(); - local_irq_enable(); - return; - } - omap_sram_suspend(omap_readl(ARM_IDLECT1), - omap_readl(ARM_IDLECT2)); -#endif - - local_fiq_enable(); - local_irq_enable(); -} - -/* - * Configuration of the wakeup event is board specific. For the - * moment we put it into this helper function. Later it may move - * to board specific files. - */ -static void omap_pm_wakeup_setup(void) -{ - u32 level1_wake = 0; - u32 level2_wake = OMAP_IRQ_BIT(INT_UART2); - - /* - * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, - * and the L2 wakeup interrupts: keypad and UART2. Note that the - * drivers must still separately call omap_set_gpio_wakeup() to - * wake up to a GPIO interrupt. - */ - if (cpu_is_omap730()) - level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) | - OMAP_IRQ_BIT(INT_730_IH2_IRQ); - else if (cpu_is_omap15xx()) - level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | - OMAP_IRQ_BIT(INT_1510_IH2_IRQ); - else if (cpu_is_omap16xx()) - level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | - OMAP_IRQ_BIT(INT_1610_IH2_IRQ); - - omap_writel(~level1_wake, OMAP_IH1_MIR); - - if (cpu_is_omap730()) { - omap_writel(~level2_wake, OMAP_IH2_0_MIR); - omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | - OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), - OMAP_IH2_1_MIR); - } else if (cpu_is_omap15xx()) { - level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); - omap_writel(~level2_wake, OMAP_IH2_MIR); - } else if (cpu_is_omap16xx()) { - level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); - omap_writel(~level2_wake, OMAP_IH2_0_MIR); - - /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ - omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), - OMAP_IH2_1_MIR); - omap_writel(~0x0, OMAP_IH2_2_MIR); - omap_writel(~0x0, OMAP_IH2_3_MIR); - } - - /* New IRQ agreement, recalculate in cascade order */ - omap_writel(1, OMAP_IH2_CONTROL); - omap_writel(1, OMAP_IH1_CONTROL); -} - -#define EN_DSPCK 13 /* ARM_CKCTL */ -#define EN_APICK 6 /* ARM_IDLECT2 */ -#define DSP_EN 1 /* ARM_RSTCT1 */ - -void omap_pm_suspend(void) -{ - unsigned long arg0 = 0, arg1 = 0; - - printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev); - - omap_serial_wake_trigger(1); - - if (machine_is_omap_osk()) { - /* Stop LED1 (D9) blink */ - tps65010_set_led(LED1, OFF); - } - - omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); - - /* - * Step 1: turn off interrupts (FIXME: NOTE: already disabled) - */ - - local_irq_disable(); - local_fiq_disable(); - - /* - * Step 2: save registers - * - * The omap is a strange/beautiful device. The caches, memory - * and register state are preserved across power saves. - * We have to save and restore very little register state to - * idle the omap. - * - * Save interrupt, MPUI, ARM and UPLD control registers. - */ - - if (cpu_is_omap730()) { - MPUI730_SAVE(OMAP_IH1_MIR); - MPUI730_SAVE(OMAP_IH2_0_MIR); - MPUI730_SAVE(OMAP_IH2_1_MIR); - MPUI730_SAVE(MPUI_CTRL); - MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI730_SAVE(MPUI_DSP_API_CONFIG); - MPUI730_SAVE(EMIFS_CONFIG); - MPUI730_SAVE(EMIFF_SDRAM_CONFIG); - - } else if (cpu_is_omap15xx()) { - MPUI1510_SAVE(OMAP_IH1_MIR); - MPUI1510_SAVE(OMAP_IH2_MIR); - MPUI1510_SAVE(MPUI_CTRL); - MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI1510_SAVE(MPUI_DSP_API_CONFIG); - MPUI1510_SAVE(EMIFS_CONFIG); - MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); - } else if (cpu_is_omap16xx()) { - MPUI1610_SAVE(OMAP_IH1_MIR); - MPUI1610_SAVE(OMAP_IH2_0_MIR); - MPUI1610_SAVE(OMAP_IH2_1_MIR); - MPUI1610_SAVE(OMAP_IH2_2_MIR); - MPUI1610_SAVE(OMAP_IH2_3_MIR); - MPUI1610_SAVE(MPUI_CTRL); - MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI1610_SAVE(MPUI_DSP_API_CONFIG); - MPUI1610_SAVE(EMIFS_CONFIG); - MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); - } - - ARM_SAVE(ARM_CKCTL); - ARM_SAVE(ARM_IDLECT1); - ARM_SAVE(ARM_IDLECT2); - if (!(cpu_is_omap15xx())) - ARM_SAVE(ARM_IDLECT3); - ARM_SAVE(ARM_EWUPCT); - ARM_SAVE(ARM_RSTCT1); - ARM_SAVE(ARM_RSTCT2); - ARM_SAVE(ARM_SYSST); - ULPD_SAVE(ULPD_CLOCK_CTRL); - ULPD_SAVE(ULPD_STATUS_REQ); - - /* (Step 3 removed - we now allow deep sleep by default) */ - - /* - * Step 4: OMAP DSP Shutdown - */ - - /* stop DSP */ - omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1); - - /* shut down dsp_ck */ - omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL); - - /* temporarily enabling api_ck to access DSP registers */ - omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2); - - /* save DSP registers */ - DSP_SAVE(DSP_IDLECT2); - - /* Stop all DSP domain clocks */ - __raw_writew(0, DSP_IDLECT2); - - /* - * Step 5: Wakeup Event Setup - */ - - omap_pm_wakeup_setup(); - - /* - * Step 6: ARM and Traffic controller shutdown - */ - - /* disable ARM watchdog */ - omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); - omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); - - /* - * Step 6b: ARM and Traffic controller shutdown - * - * Step 6 continues here. Prepare jump to power management - * assembly code in internal SRAM. - * - * Since the omap_cpu_suspend routine has been copied to - * SRAM, we'll do an indirect procedure call to it and pass the - * contents of arm_idlect1 and arm_idlect2 so it can restore - * them when it wakes up and it will return. - */ - - arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; - arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; - - /* - * Step 6c: ARM and Traffic controller shutdown - * - * Jump to assembly code. The processor will stay there - * until wake up. - */ - omap_sram_suspend(arg0, arg1); - - /* - * If we are here, processor is woken up! - */ - - /* - * Restore DSP clocks - */ - - /* again temporarily enabling api_ck to access DSP registers */ - omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2); - - /* Restore DSP domain clocks */ - DSP_RESTORE(DSP_IDLECT2); - - /* - * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did - */ - - if (!(cpu_is_omap15xx())) - ARM_RESTORE(ARM_IDLECT3); - ARM_RESTORE(ARM_CKCTL); - ARM_RESTORE(ARM_EWUPCT); - ARM_RESTORE(ARM_RSTCT1); - ARM_RESTORE(ARM_RSTCT2); - ARM_RESTORE(ARM_SYSST); - ULPD_RESTORE(ULPD_CLOCK_CTRL); - ULPD_RESTORE(ULPD_STATUS_REQ); - - if (cpu_is_omap730()) { - MPUI730_RESTORE(EMIFS_CONFIG); - MPUI730_RESTORE(EMIFF_SDRAM_CONFIG); - MPUI730_RESTORE(OMAP_IH1_MIR); - MPUI730_RESTORE(OMAP_IH2_0_MIR); - MPUI730_RESTORE(OMAP_IH2_1_MIR); - } else if (cpu_is_omap15xx()) { - MPUI1510_RESTORE(MPUI_CTRL); - MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); - MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); - MPUI1510_RESTORE(EMIFS_CONFIG); - MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG); - MPUI1510_RESTORE(OMAP_IH1_MIR); - MPUI1510_RESTORE(OMAP_IH2_MIR); - } else if (cpu_is_omap16xx()) { - MPUI1610_RESTORE(MPUI_CTRL); - MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG); - MPUI1610_RESTORE(MPUI_DSP_API_CONFIG); - MPUI1610_RESTORE(EMIFS_CONFIG); - MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG); - - MPUI1610_RESTORE(OMAP_IH1_MIR); - MPUI1610_RESTORE(OMAP_IH2_0_MIR); - MPUI1610_RESTORE(OMAP_IH2_1_MIR); - MPUI1610_RESTORE(OMAP_IH2_2_MIR); - MPUI1610_RESTORE(OMAP_IH2_3_MIR); - } - - omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); - - /* - * Reenable interrupts - */ - - local_irq_enable(); - local_fiq_enable(); - - omap_serial_wake_trigger(0); - - printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); - - if (machine_is_omap_osk()) { - /* Let LED1 (D9) blink again */ - tps65010_set_led(LED1, BLINK); - } -} - -#if defined(DEBUG) && defined(CONFIG_PROC_FS) -static int g_read_completed; - -/* - * Read system PM registers for debugging - */ -static int omap_pm_read_proc( - char *page_buffer, - char **my_first_byte, - off_t virtual_start, - int length, - int *eof, - void *data) -{ - int my_buffer_offset = 0; - char * const my_base = page_buffer; - - ARM_SAVE(ARM_CKCTL); - ARM_SAVE(ARM_IDLECT1); - ARM_SAVE(ARM_IDLECT2); - if (!(cpu_is_omap15xx())) - ARM_SAVE(ARM_IDLECT3); - ARM_SAVE(ARM_EWUPCT); - ARM_SAVE(ARM_RSTCT1); - ARM_SAVE(ARM_RSTCT2); - ARM_SAVE(ARM_SYSST); - - ULPD_SAVE(ULPD_IT_STATUS); - ULPD_SAVE(ULPD_CLOCK_CTRL); - ULPD_SAVE(ULPD_SOFT_REQ); - ULPD_SAVE(ULPD_STATUS_REQ); - ULPD_SAVE(ULPD_DPLL_CTRL); - ULPD_SAVE(ULPD_POWER_CTRL); - - if (cpu_is_omap730()) { - MPUI730_SAVE(MPUI_CTRL); - MPUI730_SAVE(MPUI_DSP_STATUS); - MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI730_SAVE(MPUI_DSP_API_CONFIG); - MPUI730_SAVE(EMIFF_SDRAM_CONFIG); - MPUI730_SAVE(EMIFS_CONFIG); - } else if (cpu_is_omap15xx()) { - MPUI1510_SAVE(MPUI_CTRL); - MPUI1510_SAVE(MPUI_DSP_STATUS); - MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI1510_SAVE(MPUI_DSP_API_CONFIG); - MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); - MPUI1510_SAVE(EMIFS_CONFIG); - } else if (cpu_is_omap16xx()) { - MPUI1610_SAVE(MPUI_CTRL); - MPUI1610_SAVE(MPUI_DSP_STATUS); - MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI1610_SAVE(MPUI_DSP_API_CONFIG); - MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); - MPUI1610_SAVE(EMIFS_CONFIG); - } - - if (virtual_start == 0) { - g_read_completed = 0; - - my_buffer_offset += sprintf(my_base + my_buffer_offset, - "ARM_CKCTL_REG: 0x%-8x \n" - "ARM_IDLECT1_REG: 0x%-8x \n" - "ARM_IDLECT2_REG: 0x%-8x \n" - "ARM_IDLECT3_REG: 0x%-8x \n" - "ARM_EWUPCT_REG: 0x%-8x \n" - "ARM_RSTCT1_REG: 0x%-8x \n" - "ARM_RSTCT2_REG: 0x%-8x \n" - "ARM_SYSST_REG: 0x%-8x \n" - "ULPD_IT_STATUS_REG: 0x%-4x \n" - "ULPD_CLOCK_CTRL_REG: 0x%-4x \n" - "ULPD_SOFT_REQ_REG: 0x%-4x \n" - "ULPD_DPLL_CTRL_REG: 0x%-4x \n" - "ULPD_STATUS_REQ_REG: 0x%-4x \n" - "ULPD_POWER_CTRL_REG: 0x%-4x \n", - ARM_SHOW(ARM_CKCTL), - ARM_SHOW(ARM_IDLECT1), - ARM_SHOW(ARM_IDLECT2), - ARM_SHOW(ARM_IDLECT3), - ARM_SHOW(ARM_EWUPCT), - ARM_SHOW(ARM_RSTCT1), - ARM_SHOW(ARM_RSTCT2), - ARM_SHOW(ARM_SYSST), - ULPD_SHOW(ULPD_IT_STATUS), - ULPD_SHOW(ULPD_CLOCK_CTRL), - ULPD_SHOW(ULPD_SOFT_REQ), - ULPD_SHOW(ULPD_DPLL_CTRL), - ULPD_SHOW(ULPD_STATUS_REQ), - ULPD_SHOW(ULPD_POWER_CTRL)); - - if (cpu_is_omap730()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, - "MPUI730_CTRL_REG 0x%-8x \n" - "MPUI730_DSP_STATUS_REG: 0x%-8x \n" - "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n" - "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n" - "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n" - "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n", - MPUI730_SHOW(MPUI_CTRL), - MPUI730_SHOW(MPUI_DSP_STATUS), - MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG), - MPUI730_SHOW(MPUI_DSP_API_CONFIG), - MPUI730_SHOW(EMIFF_SDRAM_CONFIG), - MPUI730_SHOW(EMIFS_CONFIG)); - } else if (cpu_is_omap15xx()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, - "MPUI1510_CTRL_REG 0x%-8x \n" - "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" - "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n" - "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n" - "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n" - "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n", - MPUI1510_SHOW(MPUI_CTRL), - MPUI1510_SHOW(MPUI_DSP_STATUS), - MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG), - MPUI1510_SHOW(MPUI_DSP_API_CONFIG), - MPUI1510_SHOW(EMIFF_SDRAM_CONFIG), - MPUI1510_SHOW(EMIFS_CONFIG)); - } else if (cpu_is_omap16xx()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, - "MPUI1610_CTRL_REG 0x%-8x \n" - "MPUI1610_DSP_STATUS_REG: 0x%-8x \n" - "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n" - "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n" - "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n" - "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n", - MPUI1610_SHOW(MPUI_CTRL), - MPUI1610_SHOW(MPUI_DSP_STATUS), - MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG), - MPUI1610_SHOW(MPUI_DSP_API_CONFIG), - MPUI1610_SHOW(EMIFF_SDRAM_CONFIG), - MPUI1610_SHOW(EMIFS_CONFIG)); - } - - g_read_completed++; - } else if (g_read_completed >= 1) { - *eof = 1; - return 0; - } - g_read_completed++; - - *my_first_byte = page_buffer; - return my_buffer_offset; -} - -static void omap_pm_init_proc(void) -{ - struct proc_dir_entry *entry; - - entry = create_proc_read_entry("driver/omap_pm", - S_IWUSR | S_IRUGO, NULL, - omap_pm_read_proc, NULL); -} - -#endif /* DEBUG && CONFIG_PROC_FS */ - -static void (*saved_idle)(void) = NULL; - -/* - * omap_pm_prepare - Do preliminary suspend work. - * @state: suspend state we're entering. - * - */ -static int omap_pm_prepare(suspend_state_t state) -{ - int error = 0; - - /* We cannot sleep in idle until we have resumed */ - saved_idle = pm_idle; - pm_idle = NULL; - - switch (state) - { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - break; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return error; -} - - -/* - * omap_pm_enter - Actually enter a sleep state. - * @state: State we're entering. - * - */ - -static int omap_pm_enter(suspend_state_t state) -{ - switch (state) - { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - omap_pm_suspend(); - break; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return 0; -} - - -/** - * omap_pm_finish - Finish up suspend sequence. - * @state: State we're coming out of. - * - * This is called after we wake back up (or if entering the sleep state - * failed). - */ - -static int omap_pm_finish(suspend_state_t state) -{ - pm_idle = saved_idle; - return 0; -} - - -static irqreturn_t omap_wakeup_interrupt(int irq, void * dev, - struct pt_regs * regs) -{ - return IRQ_HANDLED; -} - -static struct irqaction omap_wakeup_irq = { - .name = "peripheral wakeup", - .flags = SA_INTERRUPT, - .handler = omap_wakeup_interrupt -}; - - - -static struct pm_ops omap_pm_ops ={ - .pm_disk_mode = 0, - .prepare = omap_pm_prepare, - .enter = omap_pm_enter, - .finish = omap_pm_finish, -}; - -static int __init omap_pm_init(void) -{ - printk("Power Management for TI OMAP.\n"); - - /* - * We copy the assembler sleep/wakeup routines to SRAM. - * These routines need to be in SRAM as that's the only - * memory the MPU can see when it wakes up. - */ - if (cpu_is_omap730()) { - omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend, - omap730_idle_loop_suspend_sz); - omap_sram_suspend = omap_sram_push(omap730_cpu_suspend, - omap730_cpu_suspend_sz); - } else if (cpu_is_omap15xx()) { - omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, - omap1510_idle_loop_suspend_sz); - omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, - omap1510_cpu_suspend_sz); - } else if (cpu_is_omap16xx()) { - omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend, - omap1610_idle_loop_suspend_sz); - omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend, - omap1610_cpu_suspend_sz); - } - - if (omap_sram_idle == NULL || omap_sram_suspend == NULL) { - printk(KERN_ERR "PM not initialized: Missing SRAM support\n"); - return -ENODEV; - } - - pm_idle = omap_pm_idle; - - if (cpu_is_omap730()) - setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq); - else if (cpu_is_omap16xx()) - setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); - - /* Program new power ramp-up time - * (0 for most boards since we don't lower voltage when in deep sleep) - */ - omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3); - - /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */ - omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); - - /* Configure IDLECT3 */ - if (cpu_is_omap730()) - omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3); - else if (cpu_is_omap16xx()) - omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); - - pm_set_ops(&omap_pm_ops); - -#if defined(DEBUG) && defined(CONFIG_PROC_FS) - omap_pm_init_proc(); -#endif - - subsys_create_file(&power_subsys, &sleep_while_idle_attr); - - if (cpu_is_omap16xx()) { - /* configure LOW_PWR pin */ - omap_cfg_reg(T20_1610_LOW_PWR); - } - - return 0; -} -__initcall(omap_pm_init); diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c index 9b4cd698b..e924e0c6a 100644 --- a/arch/arm/mach-omap1/serial.c +++ b/arch/arm/mach-omap1/serial.c @@ -30,9 +30,9 @@ #include #endif -static struct clk * uart1_ck; -static struct clk * uart2_ck; -static struct clk * uart3_ck; +static struct clk * uart1_ck = NULL; +static struct clk * uart2_ck = NULL; +static struct clk * uart3_ck = NULL; static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, int offset) diff --git a/arch/arm/mach-omap1/sleep.S b/arch/arm/mach-omap1/sleep.S deleted file mode 100644 index e58295e2d..000000000 --- a/arch/arm/mach-omap1/sleep.S +++ /dev/null @@ -1,525 +0,0 @@ -/* - * linux/arch/arm/mach-omap1/sleep.S - * - * Low-level OMAP730/1510/1610 sleep/wakeUp support - * - * Initial SA1110 code: - * Copyright (c) 2001 Cliff Brake - * - * Adapted for PXA by Nicolas Pitre: - * Copyright (c) 2002 Monta Vista Software, Inc. - * - * Support for OMAP1510/1610 by Dirk Behme - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - - .text - -/* - * Forces OMAP into idle state - * - * omapXXXX_idle_loop_suspend() - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - * wakes up it continues execution at the point it went to sleep. - * - * Note: Because of slightly different configuration values we have - * processor specific functions here. - */ - -#if defined(CONFIG_ARCH_OMAP730) -ENTRY(omap730_idle_loop_suspend) - - stmfd sp!, {r0 - r12, lr} @ save registers on stack - - @ load base address of ARM_IDLECT1 and ARM_IDLECT2 - mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 - - @ turn off clock domains - @ get ARM_IDLECT2 into r2 - ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff - orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00 - strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - - @ request ARM idle - @ get ARM_IDLECT1 into r1 - ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - orr r3, r1, #OMAP730_IDLE_LOOP_REQUEST & 0xffff - strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - mov r5, #IDLE_WAIT_CYCLES & 0xff - orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 -l_730: subs r5, r5, #1 - bne l_730 -/* - * Let's wait for the next clock tick to wake us up. - */ - mov r0, #0 - mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt -/* - * omap730_idle_loop_suspend()'s resume point. - * - * It will just start executing here, so we'll restore stuff from the - * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. - */ - - @ restore ARM_IDLECT1 and ARM_IDLECT2 and return - @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2 - strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - ldmfd sp!, {r0 - r12, pc} @ restore regs and return - -ENTRY(omap730_idle_loop_suspend_sz) - .word . - omap730_idle_loop_suspend -#endif /* CONFIG_ARCH_OMAP730 */ - -#ifdef CONFIG_ARCH_OMAP15XX -ENTRY(omap1510_idle_loop_suspend) - - stmfd sp!, {r0 - r12, lr} @ save registers on stack - - @ load base address of ARM_IDLECT1 and ARM_IDLECT2 - mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 - - @ turn off clock domains - @ get ARM_IDLECT2 into r2 - ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff - orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 - strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - - @ request ARM idle - @ get ARM_IDLECT1 into r1 - ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - orr r3, r1, #OMAP1510_IDLE_LOOP_REQUEST & 0xffff - strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - mov r5, #IDLE_WAIT_CYCLES & 0xff - orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 -l_1510: subs r5, r5, #1 - bne l_1510 -/* - * Let's wait for the next clock tick to wake us up. - */ - mov r0, #0 - mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt -/* - * omap1510_idle_loop_suspend()'s resume point. - * - * It will just start executing here, so we'll restore stuff from the - * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. - */ - - @ restore ARM_IDLECT1 and ARM_IDLECT2 and return - @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2 - strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - ldmfd sp!, {r0 - r12, pc} @ restore regs and return - -ENTRY(omap1510_idle_loop_suspend_sz) - .word . - omap1510_idle_loop_suspend -#endif /* CONFIG_ARCH_OMAP15XX */ - -#if defined(CONFIG_ARCH_OMAP16XX) -ENTRY(omap1610_idle_loop_suspend) - - stmfd sp!, {r0 - r12, lr} @ save registers on stack - - @ load base address of ARM_IDLECT1 and ARM_IDLECT2 - mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 - - @ turn off clock domains - @ get ARM_IDLECT2 into r2 - ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff - orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 - strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - - @ request ARM idle - @ get ARM_IDLECT1 into r1 - ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - orr r3, r1, #OMAP1610_IDLE_LOOP_REQUEST & 0xffff - strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - mov r5, #IDLE_WAIT_CYCLES & 0xff - orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 -l_1610: subs r5, r5, #1 - bne l_1610 -/* - * Let's wait for the next clock tick to wake us up. - */ - mov r0, #0 - mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt -/* - * omap1610_idle_loop_suspend()'s resume point. - * - * It will just start executing here, so we'll restore stuff from the - * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. - */ - - @ restore ARM_IDLECT1 and ARM_IDLECT2 and return - @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2 - strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - ldmfd sp!, {r0 - r12, pc} @ restore regs and return - -ENTRY(omap1610_idle_loop_suspend_sz) - .word . - omap1610_idle_loop_suspend -#endif /* CONFIG_ARCH_OMAP16XX */ - -/* - * Forces OMAP into deep sleep state - * - * omapXXXX_cpu_suspend() - * - * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed - * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1 - * in register r1. - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - * wakes up it continues execution at the point it went to sleep. - * - * Note: Because of errata work arounds we have processor specific functions - * here. They are mostly the same, but slightly different. - * - */ - -#if defined(CONFIG_ARCH_OMAP730) -ENTRY(omap730_cpu_suspend) - - @ save registers on stack - stmfd sp!, {r0 - r12, lr} - - @ Drain write cache - mov r4, #0 - mcr p15, 0, r0, c7, c10, 4 - nop - - @ load base address of Traffic Controller - mov r6, #TCMIF_ASM_BASE & 0xff000000 - orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 - orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 - - @ prepare to put SDRAM into self-refresh manually - ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] - orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 - orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff - str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] - - @ prepare to put EMIFS to Sleep - ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff - str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - - @ load base address of ARM_IDLECT1 and ARM_IDLECT2 - mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 - - @ turn off clock domains - @ do not disable PERCK (0x04) - mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff - orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00 - strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - - @ request ARM idle - mov r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff - orr r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00 - strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - @ disable instruction cache - mrc p15, 0, r9, c1, c0, 0 - bic r2, r9, #0x1000 - mcr p15, 0, r2, c1, c0, 0 - nop - -/* - * Let's wait for the next wake up event to wake us up. r0 can't be - * used here because r0 holds ARM_IDLECT1 - */ - mov r2, #0 - mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt -/* - * omap730_cpu_suspend()'s resume point. - * - * It will just start executing here, so we'll restore stuff from the - * stack. - */ - @ re-enable Icache - mcr p15, 0, r9, c1, c0, 0 - - @ reset the ARM_IDLECT1 and ARM_IDLECT2. - strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - @ Restore EMIFF controls - str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] - str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - - @ restore regs and return - ldmfd sp!, {r0 - r12, pc} - -ENTRY(omap730_cpu_suspend_sz) - .word . - omap730_cpu_suspend -#endif /* CONFIG_ARCH_OMAP730 */ - -#ifdef CONFIG_ARCH_OMAP15XX -ENTRY(omap1510_cpu_suspend) - - @ save registers on stack - stmfd sp!, {r0 - r12, lr} - - @ load base address of Traffic Controller - mov r4, #TCMIF_ASM_BASE & 0xff000000 - orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000 - orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00 - - @ work around errata of OMAP1510 PDE bit for TC shut down - @ clear PDE bit - ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - bic r5, r5, #PDE_BIT & 0xff - str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - - @ set PWD_EN bit - and r5, r5, #PWD_EN_BIT & 0xff - str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - - @ prepare to put SDRAM into self-refresh manually - ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] - orr r5, r5, #SELF_REFRESH_MODE & 0xff000000 - orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff - str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] - - @ prepare to put EMIFS to Sleep - ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff - str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - - @ load base address of ARM_IDLECT1 and ARM_IDLECT2 - mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 - - @ turn off clock domains - mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff - orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 - strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - - @ request ARM idle - mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff - orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00 - strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - mov r5, #IDLE_WAIT_CYCLES & 0xff - orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 -l_1510_2: - subs r5, r5, #1 - bne l_1510_2 -/* - * Let's wait for the next wake up event to wake us up. r0 can't be - * used here because r0 holds ARM_IDLECT1 - */ - mov r2, #0 - mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt -/* - * omap1510_cpu_suspend()'s resume point. - * - * It will just start executing here, so we'll restore stuff from the - * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. - */ - strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - @ restore regs and return - ldmfd sp!, {r0 - r12, pc} - -ENTRY(omap1510_cpu_suspend_sz) - .word . - omap1510_cpu_suspend -#endif /* CONFIG_ARCH_OMAP15XX */ - -#if defined(CONFIG_ARCH_OMAP16XX) -ENTRY(omap1610_cpu_suspend) - - @ save registers on stack - stmfd sp!, {r0 - r12, lr} - - @ Drain write cache - mov r4, #0 - mcr p15, 0, r0, c7, c10, 4 - nop - - @ Load base address of Traffic Controller - mov r6, #TCMIF_ASM_BASE & 0xff000000 - orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 - orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 - - @ Prepare to put SDRAM into self-refresh manually - ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] - orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 - orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff - str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] - - @ Prepare to put EMIFS to Sleep - ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff - str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - - @ Load base address of ARM_IDLECT1 and ARM_IDLECT2 - mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 - orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 - - @ Turn off clock domains - @ Do not disable PERCK (0x04) - mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff - orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 - strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - - @ Request ARM idle - mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff - orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00 - strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - -/* - * Let's wait for the next wake up event to wake us up. r0 can't be - * used here because r0 holds ARM_IDLECT1 - */ - mov r2, #0 - mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt - - @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions - @ according to this formula: - @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV - @ Max DPLL_MULT = 18 - @ DPLL_DIV = 1 - @ ARMDIV = 1 - @ => 74 nop-instructions - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop @10 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop @20 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop @30 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop @40 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop @50 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop @60 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop @70 - nop - nop - nop - nop @74 -/* - * omap1610_cpu_suspend()'s resume point. - * - * It will just start executing here, so we'll restore stuff from the - * stack. - */ - @ Restore the ARM_IDLECT1 and ARM_IDLECT2. - strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] - strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] - - @ Restore EMIFF controls - str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] - str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] - - @ Restore regs and return - ldmfd sp!, {r0 - r12, pc} - -ENTRY(omap1610_cpu_suspend_sz) - .word . - omap1610_cpu_suspend -#endif /* CONFIG_ARCH_OMAP16XX */ diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index a85fe6066..cdbf4d762 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -51,6 +51,8 @@ struct sys_timer omap_timer; +#ifdef CONFIG_OMAP_MPU_TIMER + /* * --------------------------------------------------------------------------- * MPU timer @@ -220,6 +222,195 @@ unsigned long long sched_clock(void) return cycles_2_ns(ticks64); } +#endif /* CONFIG_OMAP_MPU_TIMER */ + +#ifdef CONFIG_OMAP_32K_TIMER + +#ifdef CONFIG_ARCH_OMAP15XX +#error OMAP 32KHz timer does not currently work on 15XX! +#endif + +/* + * --------------------------------------------------------------------------- + * 32KHz OS timer + * + * This currently works only on 16xx, as 1510 does not have the continuous + * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track + * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer + * on 1510 would be possible, but the timer would not be as accurate as + * with the 32KHz synchronized timer. + * --------------------------------------------------------------------------- + */ +#define OMAP_32K_TIMER_BASE 0xfffb9000 +#define OMAP_32K_TIMER_CR 0x08 +#define OMAP_32K_TIMER_TVR 0x00 +#define OMAP_32K_TIMER_TCR 0x04 + +#define OMAP_32K_TICKS_PER_HZ (32768 / HZ) + +/* + * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 + * so with HZ = 100, TVR = 327.68. + */ +#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) +#define TIMER_32K_SYNCHRONIZED 0xfffbc410 + +#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ + (((nr_jiffies) * (clock_rate)) / HZ) + +static inline void omap_32k_timer_write(int val, int reg) +{ + omap_writew(val, reg + OMAP_32K_TIMER_BASE); +} + +static inline unsigned long omap_32k_timer_read(int reg) +{ + return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff; +} + +/* + * The 32KHz synchronized timer is an additional timer on 16xx. + * It is always running. + */ +static inline unsigned long omap_32k_sync_timer_read(void) +{ + return omap_readl(TIMER_32K_SYNCHRONIZED); +} + +static inline void omap_32k_timer_start(unsigned long load_val) +{ + omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR); + omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR); +} + +static inline void omap_32k_timer_stop(void) +{ + omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR); +} + +/* + * Rounds down to nearest usec. Note that this will overflow for larger values. + */ +static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) +{ + return (ticks_32k * 5*5*5*5*5*5) >> 9; +} + +/* + * Rounds down to nearest nsec. + */ +static inline unsigned long long +omap_32k_ticks_to_nsecs(unsigned long ticks_32k) +{ + return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9; +} + +static unsigned long omap_32k_last_tick = 0; + +/* + * Returns elapsed usecs since last 32k timer interrupt + */ +static unsigned long omap_32k_timer_gettimeoffset(void) +{ + unsigned long now = omap_32k_sync_timer_read(); + return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); +} + +/* + * Returns current time from boot in nsecs. It's OK for this to wrap + * around for now, as it's just a relative time stamp. + */ +unsigned long long sched_clock(void) +{ + return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); +} + +/* + * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this + * function is also called from other interrupts to remove latency + * issues with dynamic tick. In the dynamic tick case, we need to lock + * with irqsave. + */ +static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long flags; + unsigned long now; + + write_seqlock_irqsave(&xtime_lock, flags); + now = omap_32k_sync_timer_read(); + + while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { + omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; + timer_tick(regs); + } + + /* Restart timer so we don't drift off due to modulo or dynamic tick. + * By default we program the next timer to be continuous to avoid + * latencies during high system load. During dynamic tick operation the + * continuous timer can be overridden from pm_idle to be longer. + */ + omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); + write_sequnlock_irqrestore(&xtime_lock, flags); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_NO_IDLE_HZ +/* + * Programs the next timer interrupt needed. Called when dynamic tick is + * enabled, and to reprogram the ticks to skip from pm_idle. Note that + * we can keep the timer continuous, and don't need to set it to run in + * one-shot mode. This is because the timer will get reprogrammed again + * after next interrupt. + */ +void omap_32k_timer_reprogram(unsigned long next_tick) +{ + omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); +} + +static struct irqaction omap_32k_timer_irq; +extern struct timer_update_handler timer_update; + +static int omap_32k_timer_enable_dyn_tick(void) +{ + /* No need to reprogram timer, just use the next interrupt */ + return 0; +} + +static int omap_32k_timer_disable_dyn_tick(void) +{ + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); + return 0; +} + +static struct dyn_tick_timer omap_dyn_tick_timer = { + .enable = omap_32k_timer_enable_dyn_tick, + .disable = omap_32k_timer_disable_dyn_tick, + .reprogram = omap_32k_timer_reprogram, + .handler = omap_32k_timer_interrupt, +}; +#endif /* CONFIG_NO_IDLE_HZ */ + +static struct irqaction omap_32k_timer_irq = { + .name = "32KHz timer", + .flags = SA_INTERRUPT | SA_TIMER, + .handler = omap_32k_timer_interrupt, +}; + +static __init void omap_init_32k_timer(void) +{ + +#ifdef CONFIG_NO_IDLE_HZ + omap_timer.dyn_tick = &omap_dyn_tick_timer; +#endif + + setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); + omap_timer.offset = omap_32k_timer_gettimeoffset; + omap_32k_last_tick = omap_32k_sync_timer_read(); + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); +} +#endif /* CONFIG_OMAP_32K_TIMER */ /* * --------------------------------------------------------------------------- @@ -228,7 +419,13 @@ unsigned long long sched_clock(void) */ static void __init omap_timer_init(void) { +#if defined(CONFIG_OMAP_MPU_TIMER) omap_init_mpu_timer(); +#elif defined(CONFIG_OMAP_32K_TIMER) + omap_init_32k_timer(); +#else +#error No system timer selected in Kconfig! +#endif } struct sys_timer omap_timer = { diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 537dd2e6d..578880943 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -20,6 +20,3 @@ config MACH_OMAP_H4 bool "OMAP 2420 H4 board" depends on ARCH_OMAP2 && ARCH_OMAP24XX -config MACH_OMAP_APOLLON - bool "OMAP 2420 Apollon board" - depends on ARCH_OMAP2 && ARCH_OMAP24XX diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 111eaa642..420411664 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -3,15 +3,11 @@ # # Common support -obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.o clock.o mux.o devices.o serial.o +obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o -# Power Management -obj-$(CONFIG_PM) += pm.o sleep.o - # Specific board support obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o -obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c deleted file mode 100644 index 6c6ba172c..000000000 --- a/arch/arm/mach-omap2/board-apollon.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * linux/arch/arm/mach-omap/omap2/board-apollon.c - * - * Copyright (C) 2005,2006 Samsung Electronics - * Author: Kyungmin Park - * - * Modified from mach-omap/omap2/board-h4.c - * - * Code for apollon OMAP2 board. Should work on many OMAP2 systems where - * the bootloader passes the board-specific data to the kernel. - * Do not put any board specific code to this file; create a new machine - * type if you need custom low-level initializations. - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "prcm-regs.h" - -/* LED & Switch macros */ -#define LED0_GPIO13 13 -#define LED1_GPIO14 14 -#define LED2_GPIO15 15 -#define SW_ENTER_GPIO16 16 -#define SW_UP_GPIO17 17 -#define SW_DOWN_GPIO58 58 - -static struct mtd_partition apollon_partitions[] = { - { - .name = "X-Loader + U-Boot", - .offset = 0, - .size = SZ_128K, - .mask_flags = MTD_WRITEABLE, - }, - { - .name = "params", - .offset = MTDPART_OFS_APPEND, - .size = SZ_128K, - }, - { - .name = "kernel", - .offset = MTDPART_OFS_APPEND, - .size = SZ_2M, - }, - { - .name = "rootfs", - .offset = MTDPART_OFS_APPEND, - .size = SZ_16M, - }, - { - .name = "filesystem00", - .offset = MTDPART_OFS_APPEND, - .size = SZ_32M, - }, - { - .name = "filesystem01", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct flash_platform_data apollon_flash_data = { - .parts = apollon_partitions, - .nr_parts = ARRAY_SIZE(apollon_partitions), -}; - -static struct resource apollon_flash_resource = { - .start = APOLLON_CS0_BASE, - .end = APOLLON_CS0_BASE + SZ_128K, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device apollon_onenand_device = { - .name = "onenand", - .id = -1, - .dev = { - .platform_data = &apollon_flash_data, - }, - .num_resources = ARRAY_SIZE(&apollon_flash_resource), - .resource = &apollon_flash_resource, -}; - -static struct resource apollon_smc91x_resources[] = { - [0] = { - .start = APOLLON_ETHR_START, /* Physical */ - .end = APOLLON_ETHR_START + 0xf, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), - .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device apollon_smc91x_device = { - .name = "smc91x", - .id = -1, - .num_resources = ARRAY_SIZE(apollon_smc91x_resources), - .resource = apollon_smc91x_resources, -}; - -static struct platform_device apollon_lcd_device = { - .name = "apollon_lcd", - .id = -1, -}; - -static struct platform_device *apollon_devices[] __initdata = { - &apollon_onenand_device, - &apollon_smc91x_device, - &apollon_lcd_device, -}; - -static inline void __init apollon_init_smc91x(void) -{ - /* Make sure CS1 timings are correct */ - GPMC_CONFIG1_1 = 0x00011203; - GPMC_CONFIG2_1 = 0x001f1f01; - GPMC_CONFIG3_1 = 0x00080803; - GPMC_CONFIG4_1 = 0x1c091c09; - GPMC_CONFIG5_1 = 0x041f1f1f; - GPMC_CONFIG6_1 = 0x000004c4; - GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24); - udelay(100); - - omap_cfg_reg(W4__24XX_GPIO74); - if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) { - printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", - APOLLON_ETHR_GPIO_IRQ); - return; - } - omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1); -} - -static void __init omap_apollon_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); - apollon_init_smc91x(); -} - -static struct omap_uart_config apollon_uart_config __initdata = { - .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), -}; - -static struct omap_mmc_config apollon_mmc_config __initdata = { - .mmc [0] = { - .enabled = 0, - .wire4 = 0, - .wp_pin = -1, - .power_pin = -1, - .switch_pin = -1, - }, -}; - -static struct omap_lcd_config apollon_lcd_config __initdata = { - .ctrl_name = "internal", -}; - -static struct omap_board_config_kernel apollon_config[] = { - { OMAP_TAG_UART, &apollon_uart_config }, - { OMAP_TAG_MMC, &apollon_mmc_config }, - { OMAP_TAG_LCD, &apollon_lcd_config }, -}; - -static void __init apollon_led_init(void) -{ - /* LED0 - AA10 */ - omap_cfg_reg(AA10_242X_GPIO13); - omap_request_gpio(LED0_GPIO13); - omap_set_gpio_direction(LED0_GPIO13, 0); - omap_set_gpio_dataout(LED0_GPIO13, 0); - /* LED1 - AA6 */ - omap_cfg_reg(AA6_242X_GPIO14); - omap_request_gpio(LED1_GPIO14); - omap_set_gpio_direction(LED1_GPIO14, 0); - omap_set_gpio_dataout(LED1_GPIO14, 0); - /* LED2 - AA4 */ - omap_cfg_reg(AA4_242X_GPIO15); - omap_request_gpio(LED2_GPIO15); - omap_set_gpio_direction(LED2_GPIO15, 0); - omap_set_gpio_dataout(LED2_GPIO15, 0); -} - -static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs) -{ - static unsigned int led0, led1, led2; - - if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16)) - omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1); - else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17)) - omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1); - else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58)) - omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1); - - return IRQ_HANDLED; -} - -static void __init apollon_sw_init(void) -{ - /* Enter SW - Y11 */ - omap_cfg_reg(Y11_242X_GPIO16); - omap_request_gpio(SW_ENTER_GPIO16); - omap_set_gpio_direction(SW_ENTER_GPIO16, 1); - /* Up SW - AA12 */ - omap_cfg_reg(AA12_242X_GPIO17); - omap_request_gpio(SW_UP_GPIO17); - omap_set_gpio_direction(SW_UP_GPIO17, 1); - /* Down SW - AA8 */ - omap_cfg_reg(AA8_242X_GPIO58); - omap_request_gpio(SW_DOWN_GPIO58); - omap_set_gpio_direction(SW_DOWN_GPIO58, 1); - - set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING); - if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt, - SA_SHIRQ, "enter sw", - &apollon_sw_interrupt)) - return; - set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING); - if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt, - SA_SHIRQ, "up sw", - &apollon_sw_interrupt)) - return; - set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING); - if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt, - SA_SHIRQ, "down sw", - &apollon_sw_interrupt)) - return; -} - -static void __init omap_apollon_init(void) -{ - apollon_led_init(); - apollon_sw_init(); - - /* REVISIT: where's the correct place */ - omap_cfg_reg(W19_24XX_SYS_NIRQ); - - /* - * Make sure the serial ports are muxed on at this point. - * You have to mux them off in device drivers later on - * if not needed. - */ - platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); - omap_board_config = apollon_config; - omap_board_config_size = ARRAY_SIZE(apollon_config); - omap_serial_init(); -} - -static void __init omap_apollon_map_io(void) -{ - omap2_map_common_io(); -} - -MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon") - /* Maintainer: Kyungmin Park */ - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap_apollon_map_io, - .init_irq = omap_apollon_init_irq, - .init_machine = omap_apollon_init, - .timer = &omap_timer, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 4933fce76..a300d634d 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -27,57 +25,15 @@ #include #include -#include #include #include -#include #include #include -#include -#include -#include -#include "prcm-regs.h" +#include #include #include -static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 }; -static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 }; - -static int h4_keymap[] = { - KEY(0, 0, KEY_LEFT), - KEY(0, 1, KEY_RIGHT), - KEY(0, 2, KEY_A), - KEY(0, 3, KEY_B), - KEY(0, 4, KEY_C), - KEY(1, 0, KEY_DOWN), - KEY(1, 1, KEY_UP), - KEY(1, 2, KEY_E), - KEY(1, 3, KEY_F), - KEY(1, 4, KEY_G), - KEY(2, 0, KEY_ENTER), - KEY(2, 1, KEY_I), - KEY(2, 2, KEY_J), - KEY(2, 3, KEY_K), - KEY(2, 4, KEY_3), - KEY(3, 0, KEY_M), - KEY(3, 1, KEY_N), - KEY(3, 2, KEY_O), - KEY(3, 3, KEY_P), - KEY(3, 4, KEY_Q), - KEY(4, 0, KEY_R), - KEY(4, 1, KEY_4), - KEY(4, 2, KEY_T), - KEY(4, 3, KEY_U), - KEY(4, 4, KEY_ENTER), - KEY(5, 0, KEY_V), - KEY(5, 1, KEY_W), - KEY(5, 2, KEY_L), - KEY(5, 3, KEY_S), - KEY(5, 4, KEY_ENTER), - 0 -}; - static struct mtd_partition h4_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { @@ -152,123 +108,9 @@ static struct platform_device h4_smc91x_device = { .resource = h4_smc91x_resources, }; -/* Select between the IrDA and aGPS module - */ -static int h4_select_irda(struct device *dev, int state) -{ - unsigned char expa; - int err = 0; - - if ((err = read_gpio_expa(&expa, 0x21))) { - printk(KERN_ERR "Error reading from I/O expander\n"); - return err; - } - - /* 'P6' enable/disable IRDA_TX and IRDA_RX */ - if (state & IR_SEL) { /* IrDa */ - if ((err = write_gpio_expa(expa | 0x01, 0x21))) { - printk(KERN_ERR "Error writing to I/O expander\n"); - return err; - } - } else { - if ((err = write_gpio_expa(expa & ~0x01, 0x21))) { - printk(KERN_ERR "Error writing to I/O expander\n"); - return err; - } - } - return err; -} - -static void set_trans_mode(void *data) -{ - int *mode = data; - unsigned char expa; - int err = 0; - - if ((err = read_gpio_expa(&expa, 0x20)) != 0) { - printk(KERN_ERR "Error reading from I/O expander\n"); - } - - expa &= ~0x01; - - if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */ - expa |= 0x01; - } - - if ((err = write_gpio_expa(expa, 0x20)) != 0) { - printk(KERN_ERR "Error writing to I/O expander\n"); - } -} - -static int h4_transceiver_mode(struct device *dev, int mode) -{ - struct omap_irda_config *irda_config = dev->platform_data; - - cancel_delayed_work(&irda_config->gpio_expa); - PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); - schedule_work(&irda_config->gpio_expa); - - return 0; -} - -static struct omap_irda_config h4_irda_data = { - .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, - .transceiver_mode = h4_transceiver_mode, - .select_irda = h4_select_irda, - .rx_channel = OMAP24XX_DMA_UART3_RX, - .tx_channel = OMAP24XX_DMA_UART3_TX, - .dest_start = OMAP_UART3_BASE, - .src_start = OMAP_UART3_BASE, - .tx_trigger = OMAP24XX_DMA_UART3_TX, - .rx_trigger = OMAP24XX_DMA_UART3_RX, -}; - -static struct resource h4_irda_resources[] = { - [0] = { - .start = INT_24XX_UART3_IRQ, - .end = INT_24XX_UART3_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device h4_irda_device = { - .name = "omapirda", - .id = -1, - .dev = { - .platform_data = &h4_irda_data, - }, - .num_resources = 1, - .resource = h4_irda_resources, -}; - -static struct omap_kp_platform_data h4_kp_data = { - .rows = 6, - .cols = 7, - .keymap = h4_keymap, - .rep = 1, - .row_gpios = row_gpios, - .col_gpios = col_gpios, -}; - -static struct platform_device h4_kp_device = { - .name = "omap-keypad", - .id = -1, - .dev = { - .platform_data = &h4_kp_data, - }, -}; - -static struct platform_device h4_lcd_device = { - .name = "lcd_h4", - .id = -1, -}; - static struct platform_device *h4_devices[] __initdata = { &h4_smc91x_device, &h4_flash_device, - &h4_irda_device, - &h4_kp_device, - &h4_lcd_device, }; static inline void __init h4_init_smc91x(void) @@ -315,6 +157,7 @@ static struct omap_mmc_config h4_mmc_config __initdata = { }; static struct omap_lcd_config h4_lcd_config __initdata = { + .panel_name = "h4", .ctrl_name = "internal", }; @@ -331,19 +174,6 @@ static void __init omap_h4_init(void) * You have to mux them off in device drivers later on * if not needed. */ -#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) - omap_cfg_reg(K15_24XX_UART3_TX); - omap_cfg_reg(K14_24XX_UART3_RX); -#endif - -#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) - if (omap_has_menelaus()) { - row_gpios[5] = 0; - col_gpios[2] = 15; - col_gpios[6] = 18; - } -#endif - platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); omap_board_config = h4_config; omap_board_config_size = ARRAY_SIZE(h4_config); diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 72eb4bf57..180f675c9 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -28,14 +28,14 @@ #include #include +#include -#include "prcm-regs.h" -#include "memory.h" #include "clock.h" //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ static struct prcm_config *curr_prcm_set; +static struct memory_timings mem_timings; static u32 curr_perf_level = PRCM_FULL_SPEED; /*------------------------------------------------------------------------- @@ -54,13 +54,11 @@ static void omap2_sys_clk_recalc(struct clk * clk) static u32 omap2_get_dpll_rate(struct clk * tclk) { - long long dpll_clk; - int dpll_mult, dpll_div, amult; + int dpll_clk, dpll_mult, dpll_div, amult; dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */ dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */ - dpll_clk = (long long)tclk->parent->rate * dpll_mult; - do_div(dpll_clk, dpll_div + 1); + dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1); amult = CM_CLKSEL2_PLL & 0x3; dpll_clk *= amult; @@ -387,23 +385,75 @@ static u32 omap2_dll_force_needed(void) return 0; } +static void omap2_init_memory_params(u32 force_lock_to_unlock_mode) +{ + unsigned long dll_cnt; + u32 fast_dll = 0; + + mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */ + + /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. + * In the case of 2422, its ok to use CS1 instead of CS0. + */ + +#if 0 /* FIXME: Enable after 24xx cpu detection works */ + ctype = get_cpu_type(); + if (cpu_is_omap2422()) + mem_timings.base_cs = 1; + else +#endif + mem_timings.base_cs = 0; + + if (mem_timings.m_type != M_DDR) + return; + + /* With DDR we need to determine the low frequency DLL value */ + if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL)) + mem_timings.dll_mode = M_UNLOCK; + else + mem_timings.dll_mode = M_LOCK; + + if (mem_timings.base_cs == 0) { + fast_dll = SDRC_DLLA_CTRL; + dll_cnt = SDRC_DLLA_STATUS & 0xff00; + } else { + fast_dll = SDRC_DLLB_CTRL; + dll_cnt = SDRC_DLLB_STATUS & 0xff00; + } + if (force_lock_to_unlock_mode) { + fast_dll &= ~0xff00; + fast_dll |= dll_cnt; /* Current lock mode */ + } + mem_timings.fast_dll_ctrl = fast_dll; + + /* No disruptions, DDR will be offline & C-ABI not followed */ + omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl, + mem_timings.fast_dll_ctrl, + mem_timings.base_cs, + force_lock_to_unlock_mode); + mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */ + + /* Turn status into unlock ctrl */ + mem_timings.slow_dll_ctrl |= + ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2)); + + /* 90 degree phase for anything below 133Mhz */ + mem_timings.slow_dll_ctrl |= (1 << 1); +} + static u32 omap2_reprogram_sdrc(u32 level, u32 force) { - u32 slow_dll_ctrl, fast_dll_ctrl, m_type; u32 prev = curr_perf_level, flags; if ((curr_perf_level == level) && !force) return prev; - m_type = omap2_memory_get_type(); - slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl(); - fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl(); - if (level == PRCM_HALF_SPEED) { local_irq_save(flags); PRCM_VOLTSETUP = 0xffff; omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED, - slow_dll_ctrl, m_type); + mem_timings.slow_dll_ctrl, + mem_timings.m_type); curr_perf_level = PRCM_HALF_SPEED; local_irq_restore(flags); } @@ -411,7 +461,8 @@ static u32 omap2_reprogram_sdrc(u32 level, u32 force) local_irq_save(flags); PRCM_VOLTSETUP = 0xffff; omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED, - fast_dll_ctrl, m_type); + mem_timings.fast_dll_ctrl, + mem_timings.m_type); curr_perf_level = PRCM_FULL_SPEED; local_irq_restore(flags); } @@ -599,7 +650,7 @@ static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask, case 13: /* dss2 */ mask = 0x1; break; case 25: /* usb */ - mask = 0x7; break; + mask = 0xf; break; } } diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 6c78d471f..6cab20b1d 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -33,6 +33,20 @@ static u32 omap2_clksel_get_divisor(struct clk *clk); #define RATE_IN_242X (1 << 0) #define RATE_IN_243X (1 << 1) +/* Memory timings */ +#define M_DDR 1 +#define M_LOCK_CTRL (1 << 2) +#define M_UNLOCK 0 +#define M_LOCK 1 + +struct memory_timings { + u32 m_type; /* ddr = 1, sdr = 0 */ + u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ + u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ + u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ + u32 base_cs; /* base chip select to use for calculations */ +}; + /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM @@ -717,16 +731,6 @@ static struct clk sys_clkout2 = { .recalc = &omap2_clksel_recalc, }; -static struct clk emul_ck = { - .name = "emul_ck", - .parent = &func_54m_ck, - .flags = CLOCK_IN_OMAP242X, - .enable_reg = (void __iomem *)&PRCM_CLKEMUL_CTRL, - .enable_bit = 0, - .recalc = &omap2_propagate_rate, - -}; - /* * MPU clock domain * Clocks: @@ -1698,8 +1702,7 @@ static struct clk hdq_fck = { }; static struct clk i2c2_ick = { - .name = "i2c_ick", - .id = 2, + .name = "i2c2_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1708,8 +1711,7 @@ static struct clk i2c2_ick = { }; static struct clk i2c2_fck = { - .name = "i2c_fck", - .id = 2, + .name = "i2c2_fck", .parent = &func_12m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1727,8 +1729,7 @@ static struct clk i2chs2_fck = { }; static struct clk i2c1_ick = { - .name = "i2c_ick", - .id = 1, + .name = "i2c1_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1737,8 +1738,7 @@ static struct clk i2c1_ick = { }; static struct clk i2c1_fck = { - .name = "i2c_fck", - .id = 1, + .name = "i2c1_fck", .parent = &func_12m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1971,7 +1971,6 @@ static struct clk *onchip_clks[] = { &wdt1_osc_ck, &sys_clkout, &sys_clkout2, - &emul_ck, /* mpu domain clocks */ &mpu_ck, /* dsp domain clocks */ diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index fb7f91da1..7181edb89 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -25,6 +25,10 @@ #include #include +extern void omap_nop_release(struct device *dev); + +/*-------------------------------------------------------------------------*/ + #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) #define OMAP2_I2C_BASE2 0x48072000 @@ -45,6 +49,9 @@ static struct resource i2c_resources2[] = { static struct platform_device omap_i2c_device2 = { .name = "i2c_omap", .id = 2, + .dev = { + .release = omap_nop_release, + }, .num_resources = ARRAY_SIZE(i2c_resources2), .resource = i2c_resources2, }; @@ -67,44 +74,6 @@ static void omap_init_i2c(void) {} #endif -#if defined(CONFIG_OMAP_STI) - -#define OMAP2_STI_BASE IO_ADDRESS(0x48068000) -#define OMAP2_STI_CHANNEL_BASE 0x54000000 -#define OMAP2_STI_IRQ 4 - -static struct resource sti_resources[] = { - { - .start = OMAP2_STI_BASE, - .end = OMAP2_STI_BASE + 0x7ff, - .flags = IORESOURCE_MEM, - }, - { - .start = OMAP2_STI_CHANNEL_BASE, - .end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = OMAP2_STI_IRQ, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device sti_device = { - .name = "sti", - .id = -1, - .num_resources = ARRAY_SIZE(sti_resources), - .resource = sti_resources, -}; - -static inline void omap_init_sti(void) -{ - platform_device_register(&sti_device); -} -#else -static inline void omap_init_sti(void) {} -#endif - /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -113,7 +82,6 @@ static int __init omap2_init_devices(void) * in alphabetical order so they're easier to sort through. */ omap_init_i2c(); - omap_init_sti(); return 0; } diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 7d5711611..8ea67bf19 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -16,13 +16,9 @@ #include #include -#include -#include - #include - +#include #include -#include extern void omap_sram_init(void); extern int omap2_clk_init(void); @@ -47,24 +43,11 @@ static struct map_desc omap2_io_desc[] __initdata = { } }; -void __init omap2_map_common_io(void) +void __init omap_map_common_io(void) { iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc)); - - /* Normally devicemaps_init() would flush caches and tlb after - * mdesc->map_io(), but we must also do it here because of the CPU - * revision check below. - */ - local_flush_tlb_all(); - flush_cache_all(); - omap2_check_revision(); omap_sram_init(); - omapfb_reserve_mem(); -} - -void __init omap2_init_common_hw(void) -{ omap2_mux_init(); omap2_clk_init(); } diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c deleted file mode 100644 index 1d925d69f..000000000 --- a/arch/arm/mach-omap2/memory.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/memory.c - * - * Memory timing related functions for OMAP24XX - * - * Copyright (C) 2005 Texas Instruments Inc. - * Richard Woodruff - * - * Copyright (C) 2005 Nokia Corporation - * Tony Lindgren - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "prcm-regs.h" -#include "memory.h" - -static struct memory_timings mem_timings; - -u32 omap2_memory_get_slow_dll_ctrl(void) -{ - return mem_timings.slow_dll_ctrl; -} - -u32 omap2_memory_get_fast_dll_ctrl(void) -{ - return mem_timings.fast_dll_ctrl; -} - -u32 omap2_memory_get_type(void) -{ - return mem_timings.m_type; -} - -void omap2_init_memory_params(u32 force_lock_to_unlock_mode) -{ - unsigned long dll_cnt; - u32 fast_dll = 0; - - mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */ - - /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. - * In the case of 2422, its ok to use CS1 instead of CS0. - */ - if (cpu_is_omap2422()) - mem_timings.base_cs = 1; - else - mem_timings.base_cs = 0; - - if (mem_timings.m_type != M_DDR) - return; - - /* With DDR we need to determine the low frequency DLL value */ - if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL)) - mem_timings.dll_mode = M_UNLOCK; - else - mem_timings.dll_mode = M_LOCK; - - if (mem_timings.base_cs == 0) { - fast_dll = SDRC_DLLA_CTRL; - dll_cnt = SDRC_DLLA_STATUS & 0xff00; - } else { - fast_dll = SDRC_DLLB_CTRL; - dll_cnt = SDRC_DLLB_STATUS & 0xff00; - } - if (force_lock_to_unlock_mode) { - fast_dll &= ~0xff00; - fast_dll |= dll_cnt; /* Current lock mode */ - } - /* set fast timings with DLL filter disabled */ - mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8)); - - /* No disruptions, DDR will be offline & C-ABI not followed */ - omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl, - mem_timings.fast_dll_ctrl, - mem_timings.base_cs, - force_lock_to_unlock_mode); - mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */ - - /* Turn status into unlock ctrl */ - mem_timings.slow_dll_ctrl |= - ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2)); - - /* 90 degree phase for anything below 133Mhz + disable DLL filter */ - mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); -} diff --git a/arch/arm/mach-omap2/memory.h b/arch/arm/mach-omap2/memory.h deleted file mode 100644 index d212eea83..000000000 --- a/arch/arm/mach-omap2/memory.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/memory.h - * - * Interface for memory timing related functions for OMAP24XX - * - * Copyright (C) 2005 Texas Instruments Inc. - * Richard Woodruff - * - * Copyright (C) 2005 Nokia Corporation - * Tony Lindgren - * - * 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. - */ - -/* Memory timings */ -#define M_DDR 1 -#define M_LOCK_CTRL (1 << 2) -#define M_UNLOCK 0 -#define M_LOCK 1 - -struct memory_timings { - u32 m_type; /* ddr = 1, sdr = 0 */ - u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ - u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ - u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ - u32 base_cs; /* base chip select to use for calculations */ -}; - -extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode); -extern u32 omap2_memory_get_slow_dll_ctrl(void); -extern u32 omap2_memory_get_fast_dll_ctrl(void); -extern u32 omap2_memory_get_type(void); diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 1197dc38c..ea4654815 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -50,54 +50,9 @@ MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1) /* Menelaus interrupt */ MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1) -/* 24xx clocks */ -MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1) - -/* 24xx McBSP */ -MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1) -MUX_CFG_24XX("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1) -MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1) -MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1) - /* 24xx GPIO */ -MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1) -MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1) -MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1) -MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1) -MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1) -MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1) -MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1) MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1) -MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1) MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1) -MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1) - -/* TSC IRQ */ -MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1) - -/* UART3 */ -MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) -MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) - -/* Keypad GPIO*/ -MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) -MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) -MUX_CFG_24XX("V18_24XX_KBR2", 0x139, 3, 1, 1, 1) -MUX_CFG_24XX("M21_24XX_KBR3", 0xc9, 3, 1, 1, 1) -MUX_CFG_24XX("E5__24XX_KBR4", 0x138, 3, 1, 1, 1) -MUX_CFG_24XX("M18_24XX_KBR5", 0x10e, 3, 1, 1, 1) -MUX_CFG_24XX("R20_24XX_KBC0", 0x108, 3, 0, 0, 1) -MUX_CFG_24XX("M14_24XX_KBC1", 0x109, 3, 0, 0, 1) -MUX_CFG_24XX("H19_24XX_KBC2", 0x114, 3, 0, 0, 1) -MUX_CFG_24XX("V17_24XX_KBC3", 0x135, 3, 0, 0, 1) -MUX_CFG_24XX("P21_24XX_KBC4", 0xca, 3, 0, 0, 1) -MUX_CFG_24XX("L14_24XX_KBC5", 0x10f, 3, 0, 0, 1) -MUX_CFG_24XX("N19_24XX_KBC6", 0x110, 3, 0, 0, 1) - -/* 24xx Menelaus Keypad GPIO */ -MUX_CFG_24XX("B3__24XX_KBR5", 0x30, 3, 1, 1, 1) -MUX_CFG_24XX("AA4_24XX_KBC2", 0xe7, 3, 0, 0, 1) -MUX_CFG_24XX("B13_24XX_KBC6", 0x110, 3, 0, 0, 1) }; diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c deleted file mode 100644 index 562168fa2..000000000 --- a/arch/arm/mach-omap2/pm.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/pm.c - * - * OMAP2 Power Management Routines - * - * Copyright (C) 2006 Nokia Corporation - * Tony Lindgren - * - * Copyright (C) 2005 Texas Instruments, Inc. - * Richard Woodruff - * - * Based on pm.c for omap1 - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static struct clk *vclk; -static void (*omap2_sram_idle)(void); -static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev); -static void (*saved_idle)(void); - -void omap2_pm_idle(void) -{ - local_irq_disable(); - local_fiq_disable(); - if (need_resched()) { - local_fiq_enable(); - local_irq_enable(); - return; - } - - /* - * Since an interrupt may set up a timer, we don't want to - * reprogram the hardware timer with interrupts enabled. - * Re-enable interrupts only after returning from idle. - */ - timer_dyn_reprogram(); - - omap2_sram_idle(); - local_fiq_enable(); - local_irq_enable(); -} - -static int omap2_pm_prepare(suspend_state_t state) -{ - int error = 0; - - /* We cannot sleep in idle until we have resumed */ - saved_idle = pm_idle; - pm_idle = NULL; - - switch (state) - { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - break; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return error; -} - -static int omap2_pm_enter(suspend_state_t state) -{ - switch (state) - { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - /* FIXME: Add suspend */ - break; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return 0; -} - -static int omap2_pm_finish(suspend_state_t state) -{ - pm_idle = saved_idle; - return 0; -} - -static struct pm_ops omap_pm_ops = { - .pm_disk_mode = 0, - .prepare = omap2_pm_prepare, - .enter = omap2_pm_enter, - .finish = omap2_pm_finish, -}; - -int __init omap2_pm_init(void) -{ - printk("Power Management for TI OMAP.\n"); - - vclk = clk_get(NULL, "virt_prcm_set"); - if (IS_ERR(vclk)) { - printk(KERN_ERR "Could not get PM vclk\n"); - return -ENODEV; - } - - /* - * We copy the assembler sleep/wakeup routines to SRAM. - * These routines need to be in SRAM as that's the only - * memory the MPU can see when it wakes up. - */ - omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend, - omap24xx_idle_loop_suspend_sz); - - omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, - omap24xx_cpu_suspend_sz); - - pm_set_ops(&omap_pm_ops); - pm_idle = omap2_pm_idle; - - return 0; -} - -__initcall(omap2_pm_init); diff --git a/arch/arm/mach-omap2/prcm-regs.h b/arch/arm/mach-omap2/prcm-regs.h deleted file mode 100644 index 22ac7be4f..000000000 --- a/arch/arm/mach-omap2/prcm-regs.h +++ /dev/null @@ -1,483 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/prcm-reg.h - * - * OMAP24XX Power Reset and Clock Management (PRCM) registers - * - * Copyright (C) 2005 Texas Instruments, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 __ARCH_ARM_MACH_OMAP2_PRCM_H -#define __ARCH_ARM_MACH_OMAP2_PRCM_H - -/* SET_PERFORMANCE_LEVEL PARAMETERS */ -#define PRCM_HALF_SPEED 1 -#define PRCM_FULL_SPEED 2 - -#ifndef __ASSEMBLER__ - -#define PRCM_REG32(offset) __REG32(OMAP24XX_PRCM_BASE + (offset)) - -#define PRCM_REVISION PRCM_REG32(0x000) -#define PRCM_SYSCONFIG PRCM_REG32(0x010) -#define PRCM_IRQSTATUS_MPU PRCM_REG32(0x018) -#define PRCM_IRQENABLE_MPU PRCM_REG32(0x01C) -#define PRCM_VOLTCTRL PRCM_REG32(0x050) -#define PRCM_VOLTST PRCM_REG32(0x054) -#define PRCM_CLKSRC_CTRL PRCM_REG32(0x060) -#define PRCM_CLKOUT_CTRL PRCM_REG32(0x070) -#define PRCM_CLKEMUL_CTRL PRCM_REG32(0x078) -#define PRCM_CLKCFG_CTRL PRCM_REG32(0x080) -#define PRCM_CLKCFG_STATUS PRCM_REG32(0x084) -#define PRCM_VOLTSETUP PRCM_REG32(0x090) -#define PRCM_CLKSSETUP PRCM_REG32(0x094) -#define PRCM_POLCTRL PRCM_REG32(0x098) - -/* GENERAL PURPOSE */ -#define GENERAL_PURPOSE1 PRCM_REG32(0x0B0) -#define GENERAL_PURPOSE2 PRCM_REG32(0x0B4) -#define GENERAL_PURPOSE3 PRCM_REG32(0x0B8) -#define GENERAL_PURPOSE4 PRCM_REG32(0x0BC) -#define GENERAL_PURPOSE5 PRCM_REG32(0x0C0) -#define GENERAL_PURPOSE6 PRCM_REG32(0x0C4) -#define GENERAL_PURPOSE7 PRCM_REG32(0x0C8) -#define GENERAL_PURPOSE8 PRCM_REG32(0x0CC) -#define GENERAL_PURPOSE9 PRCM_REG32(0x0D0) -#define GENERAL_PURPOSE10 PRCM_REG32(0x0D4) -#define GENERAL_PURPOSE11 PRCM_REG32(0x0D8) -#define GENERAL_PURPOSE12 PRCM_REG32(0x0DC) -#define GENERAL_PURPOSE13 PRCM_REG32(0x0E0) -#define GENERAL_PURPOSE14 PRCM_REG32(0x0E4) -#define GENERAL_PURPOSE15 PRCM_REG32(0x0E8) -#define GENERAL_PURPOSE16 PRCM_REG32(0x0EC) -#define GENERAL_PURPOSE17 PRCM_REG32(0x0F0) -#define GENERAL_PURPOSE18 PRCM_REG32(0x0F4) -#define GENERAL_PURPOSE19 PRCM_REG32(0x0F8) -#define GENERAL_PURPOSE20 PRCM_REG32(0x0FC) - -/* MPU */ -#define CM_CLKSEL_MPU PRCM_REG32(0x140) -#define CM_CLKSTCTRL_MPU PRCM_REG32(0x148) -#define RM_RSTST_MPU PRCM_REG32(0x158) -#define PM_WKDEP_MPU PRCM_REG32(0x1C8) -#define PM_EVGENCTRL_MPU PRCM_REG32(0x1D4) -#define PM_EVEGENONTIM_MPU PRCM_REG32(0x1D8) -#define PM_EVEGENOFFTIM_MPU PRCM_REG32(0x1DC) -#define PM_PWSTCTRL_MPU PRCM_REG32(0x1E0) -#define PM_PWSTST_MPU PRCM_REG32(0x1E4) - -/* CORE */ -#define CM_FCLKEN1_CORE PRCM_REG32(0x200) -#define CM_FCLKEN2_CORE PRCM_REG32(0x204) -#define CM_FCLKEN3_CORE PRCM_REG32(0x208) -#define CM_ICLKEN1_CORE PRCM_REG32(0x210) -#define CM_ICLKEN2_CORE PRCM_REG32(0x214) -#define CM_ICLKEN3_CORE PRCM_REG32(0x218) -#define CM_ICLKEN4_CORE PRCM_REG32(0x21C) -#define CM_IDLEST1_CORE PRCM_REG32(0x220) -#define CM_IDLEST2_CORE PRCM_REG32(0x224) -#define CM_IDLEST3_CORE PRCM_REG32(0x228) -#define CM_IDLEST4_CORE PRCM_REG32(0x22C) -#define CM_AUTOIDLE1_CORE PRCM_REG32(0x230) -#define CM_AUTOIDLE2_CORE PRCM_REG32(0x234) -#define CM_AUTOIDLE3_CORE PRCM_REG32(0x238) -#define CM_AUTOIDLE4_CORE PRCM_REG32(0x23C) -#define CM_CLKSEL1_CORE PRCM_REG32(0x240) -#define CM_CLKSEL2_CORE PRCM_REG32(0x244) -#define CM_CLKSTCTRL_CORE PRCM_REG32(0x248) -#define PM_WKEN1_CORE PRCM_REG32(0x2A0) -#define PM_WKEN2_CORE PRCM_REG32(0x2A4) -#define PM_WKST1_CORE PRCM_REG32(0x2B0) -#define PM_WKST2_CORE PRCM_REG32(0x2B4) -#define PM_WKDEP_CORE PRCM_REG32(0x2C8) -#define PM_PWSTCTRL_CORE PRCM_REG32(0x2E0) -#define PM_PWSTST_CORE PRCM_REG32(0x2E4) - -/* GFX */ -#define CM_FCLKEN_GFX PRCM_REG32(0x300) -#define CM_ICLKEN_GFX PRCM_REG32(0x310) -#define CM_IDLEST_GFX PRCM_REG32(0x320) -#define CM_CLKSEL_GFX PRCM_REG32(0x340) -#define CM_CLKSTCTRL_GFX PRCM_REG32(0x348) -#define RM_RSTCTRL_GFX PRCM_REG32(0x350) -#define RM_RSTST_GFX PRCM_REG32(0x358) -#define PM_WKDEP_GFX PRCM_REG32(0x3C8) -#define PM_PWSTCTRL_GFX PRCM_REG32(0x3E0) -#define PM_PWSTST_GFX PRCM_REG32(0x3E4) - -/* WAKE-UP */ -#define CM_FCLKEN_WKUP PRCM_REG32(0x400) -#define CM_ICLKEN_WKUP PRCM_REG32(0x410) -#define CM_IDLEST_WKUP PRCM_REG32(0x420) -#define CM_AUTOIDLE_WKUP PRCM_REG32(0x430) -#define CM_CLKSEL_WKUP PRCM_REG32(0x440) -#define RM_RSTCTRL_WKUP PRCM_REG32(0x450) -#define RM_RSTTIME_WKUP PRCM_REG32(0x454) -#define RM_RSTST_WKUP PRCM_REG32(0x458) -#define PM_WKEN_WKUP PRCM_REG32(0x4A0) -#define PM_WKST_WKUP PRCM_REG32(0x4B0) - -/* CLOCKS */ -#define CM_CLKEN_PLL PRCM_REG32(0x500) -#define CM_IDLEST_CKGEN PRCM_REG32(0x520) -#define CM_AUTOIDLE_PLL PRCM_REG32(0x530) -#define CM_CLKSEL1_PLL PRCM_REG32(0x540) -#define CM_CLKSEL2_PLL PRCM_REG32(0x544) - -/* DSP */ -#define CM_FCLKEN_DSP PRCM_REG32(0x800) -#define CM_ICLKEN_DSP PRCM_REG32(0x810) -#define CM_IDLEST_DSP PRCM_REG32(0x820) -#define CM_AUTOIDLE_DSP PRCM_REG32(0x830) -#define CM_CLKSEL_DSP PRCM_REG32(0x840) -#define CM_CLKSTCTRL_DSP PRCM_REG32(0x848) -#define RM_RSTCTRL_DSP PRCM_REG32(0x850) -#define RM_RSTST_DSP PRCM_REG32(0x858) -#define PM_WKEN_DSP PRCM_REG32(0x8A0) -#define PM_WKDEP_DSP PRCM_REG32(0x8C8) -#define PM_PWSTCTRL_DSP PRCM_REG32(0x8E0) -#define PM_PWSTST_DSP PRCM_REG32(0x8E4) -#define PRCM_IRQSTATUS_DSP PRCM_REG32(0x8F0) -#define PRCM_IRQENABLE_DSP PRCM_REG32(0x8F4) - -/* IVA */ -#define PRCM_IRQSTATUS_IVA PRCM_REG32(0x8F8) -#define PRCM_IRQENABLE_IVA PRCM_REG32(0x8FC) - -/* Modem on 2430 */ -#define CM_FCLKEN_MDM PRCM_REG32(0xC00) -#define CM_ICLKEN_MDM PRCM_REG32(0xC10) -#define CM_IDLEST_MDM PRCM_REG32(0xC20) -#define CM_AUTOIDLE_MDM PRCM_REG32(0xC30) -#define CM_CLKSEL_MDM PRCM_REG32(0xC40) -#define CM_CLKSTCTRL_MDM PRCM_REG32(0xC48) -#define RM_RSTCTRL_MDM PRCM_REG32(0xC50) -#define RM_RSTST_MDM PRCM_REG32(0xC58) -#define PM_WKEN_MDM PRCM_REG32(0xCA0) -#define PM_WKST_MDM PRCM_REG32(0xCB0) -#define PM_WKDEP_MDM PRCM_REG32(0xCC8) -#define PM_PWSTCTRL_MDM PRCM_REG32(0xCE0) -#define PM_PWSTST_MDM PRCM_REG32(0xCE4) - -#define OMAP24XX_L4_IO_BASE 0x48000000 - -#define DISP_BASE (OMAP24XX_L4_IO_BASE + 0x50000) -#define DISP_REG32(offset) __REG32(DISP_BASE + (offset)) - -#define OMAP24XX_GPMC_BASE (L3_24XX_BASE + 0xa000) -#define GPMC_REG32(offset) __REG32(OMAP24XX_GPMC_BASE + (offset)) - -/* FIXME: Move these to timer code */ -#define GPT1_BASE (0x48028000) -#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset)) - -/* Misc sysconfig */ -#define DISPC_SYSCONFIG DISP_REG32(0x410) -#define SPI_BASE (OMAP24XX_L4_IO_BASE + 0x98000) -#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10) -#define MCSPI2_SYSCONFIG __REG32(SPI_BASE + 0x2000 + 0x10) -#define MCSPI3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0xb8010) - -#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE + 0x2C10) -#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE + 0x282C) -#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE + 0x602C) -#define GPMC_SYSCONFIG GPMC_REG32(0x010) -#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x94010) -#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6A054) -#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6C054) -#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6E054) -#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE + 0x10) -#define OMAP24XX_SMS_BASE (L3_24XX_BASE + 0x8000) -#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE + 0x10) -#define SSI_SYSCONFIG __REG32(DISP_BASE + 0x8010) - -/* rkw - good cannidates for PM_ to start what nm was trying */ -#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE + 0x2A000) -#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE + 0x78000) -#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE + 0x7A000) -#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE + 0x7C000) -#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE + 0x7E000) -#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE + 0x80000) -#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE + 0x82000) -#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE + 0x84000) -#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE + 0x86000) -#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE + 0x88000) -#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE + 0x8A000) - -/* FIXME: Move these to timer code */ -#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010) -#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10) -#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10) -#define GPTIMER4_SYSCONFIG __REG32(OMAP24XX_GPT4 + 0x10) -#define GPTIMER5_SYSCONFIG __REG32(OMAP24XX_GPT5 + 0x10) -#define GPTIMER6_SYSCONFIG __REG32(OMAP24XX_GPT6 + 0x10) -#define GPTIMER7_SYSCONFIG __REG32(OMAP24XX_GPT7 + 0x10) -#define GPTIMER8_SYSCONFIG __REG32(OMAP24XX_GPT8 + 0x10) -#define GPTIMER9_SYSCONFIG __REG32(OMAP24XX_GPT9 + 0x10) -#define GPTIMER10_SYSCONFIG __REG32(OMAP24XX_GPT10 + 0x10) -#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10) -#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10) - -/* FIXME: Move these to gpio code */ -#define OMAP24XX_GPIO_BASE 0x48018000 -#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE + (0x2000 * ((X) - 1))) - -#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1) + 0x10)) -#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2) + 0x10)) -#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3) + 0x10)) -#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4) + 0x10)) - -#if defined(CONFIG_ARCH_OMAP243X) -#define GPIO5_SYSCONFIG __REG32((OMAP24XX_GPIO5_BASE + 0x10)) -#endif - -/* GP TIMER 1 */ -#define GPTIMER1_TISTAT GPT1_REG32(0x014) -#define GPTIMER1_TISR GPT1_REG32(0x018) -#define GPTIMER1_TIER GPT1_REG32(0x01C) -#define GPTIMER1_TWER GPT1_REG32(0x020) -#define GPTIMER1_TCLR GPT1_REG32(0x024) -#define GPTIMER1_TCRR GPT1_REG32(0x028) -#define GPTIMER1_TLDR GPT1_REG32(0x02C) -#define GPTIMER1_TTGR GPT1_REG32(0x030) -#define GPTIMER1_TWPS GPT1_REG32(0x034) -#define GPTIMER1_TMAR GPT1_REG32(0x038) -#define GPTIMER1_TCAR1 GPT1_REG32(0x03C) -#define GPTIMER1_TSICR GPT1_REG32(0x040) -#define GPTIMER1_TCAR2 GPT1_REG32(0x044) - -/* rkw -- base fix up please... */ -#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE + 0x78018) - -/* SDRC */ -#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x060) -#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x064) -#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x068) -#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x06C) -#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE + 0x070) -#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE + 0x084) - -/* GPIO 1 */ -#define GPIO1_BASE GPIOX_BASE(1) -#define GPIO1_REG32(offset) __REG32(GPIO1_BASE + (offset)) -#define GPIO1_IRQENABLE1 GPIO1_REG32(0x01C) -#define GPIO1_IRQSTATUS1 GPIO1_REG32(0x018) -#define GPIO1_IRQENABLE2 GPIO1_REG32(0x02C) -#define GPIO1_IRQSTATUS2 GPIO1_REG32(0x028) -#define GPIO1_WAKEUPENABLE GPIO1_REG32(0x020) -#define GPIO1_RISINGDETECT GPIO1_REG32(0x048) -#define GPIO1_DATAIN GPIO1_REG32(0x038) -#define GPIO1_OE GPIO1_REG32(0x034) -#define GPIO1_DATAOUT GPIO1_REG32(0x03C) - -/* GPIO2 */ -#define GPIO2_BASE GPIOX_BASE(2) -#define GPIO2_REG32(offset) __REG32(GPIO2_BASE + (offset)) -#define GPIO2_IRQENABLE1 GPIO2_REG32(0x01C) -#define GPIO2_IRQSTATUS1 GPIO2_REG32(0x018) -#define GPIO2_IRQENABLE2 GPIO2_REG32(0x02C) -#define GPIO2_IRQSTATUS2 GPIO2_REG32(0x028) -#define GPIO2_WAKEUPENABLE GPIO2_REG32(0x020) -#define GPIO2_RISINGDETECT GPIO2_REG32(0x048) -#define GPIO2_DATAIN GPIO2_REG32(0x038) -#define GPIO2_OE GPIO2_REG32(0x034) -#define GPIO2_DATAOUT GPIO2_REG32(0x03C) -#define GPIO2_DEBOUNCENABLE GPIO2_REG32(0x050) -#define GPIO2_DEBOUNCINGTIME GPIO2_REG32(0x054) - -/* GPIO 3 */ -#define GPIO3_BASE GPIOX_BASE(3) -#define GPIO3_REG32(offset) __REG32(GPIO3_BASE + (offset)) -#define GPIO3_IRQENABLE1 GPIO3_REG32(0x01C) -#define GPIO3_IRQSTATUS1 GPIO3_REG32(0x018) -#define GPIO3_IRQENABLE2 GPIO3_REG32(0x02C) -#define GPIO3_IRQSTATUS2 GPIO3_REG32(0x028) -#define GPIO3_WAKEUPENABLE GPIO3_REG32(0x020) -#define GPIO3_RISINGDETECT GPIO3_REG32(0x048) -#define GPIO3_FALLINGDETECT GPIO3_REG32(0x04C) -#define GPIO3_DATAIN GPIO3_REG32(0x038) -#define GPIO3_OE GPIO3_REG32(0x034) -#define GPIO3_DATAOUT GPIO3_REG32(0x03C) -#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050) -#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054) -#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050) -#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054) - -/* GPIO 4 */ -#define GPIO4_BASE GPIOX_BASE(4) -#define GPIO4_REG32(offset) __REG32(GPIO4_BASE + (offset)) -#define GPIO4_IRQENABLE1 GPIO4_REG32(0x01C) -#define GPIO4_IRQSTATUS1 GPIO4_REG32(0x018) -#define GPIO4_IRQENABLE2 GPIO4_REG32(0x02C) -#define GPIO4_IRQSTATUS2 GPIO4_REG32(0x028) -#define GPIO4_WAKEUPENABLE GPIO4_REG32(0x020) -#define GPIO4_RISINGDETECT GPIO4_REG32(0x048) -#define GPIO4_FALLINGDETECT GPIO4_REG32(0x04C) -#define GPIO4_DATAIN GPIO4_REG32(0x038) -#define GPIO4_OE GPIO4_REG32(0x034) -#define GPIO4_DATAOUT GPIO4_REG32(0x03C) -#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050) -#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054) - -#if defined(CONFIG_ARCH_OMAP243X) -/* GPIO 5 */ -#define GPIO5_REG32(offset) __REG32((OMAP24XX_GPIO5_BASE + (offset))) -#define GPIO5_IRQENABLE1 GPIO5_REG32(0x01C) -#define GPIO5_IRQSTATUS1 GPIO5_REG32(0x018) -#define GPIO5_IRQENABLE2 GPIO5_REG32(0x02C) -#define GPIO5_IRQSTATUS2 GPIO5_REG32(0x028) -#define GPIO5_WAKEUPENABLE GPIO5_REG32(0x020) -#define GPIO5_RISINGDETECT GPIO5_REG32(0x048) -#define GPIO5_FALLINGDETECT GPIO5_REG32(0x04C) -#define GPIO5_DATAIN GPIO5_REG32(0x038) -#define GPIO5_OE GPIO5_REG32(0x034) -#define GPIO5_DATAOUT GPIO5_REG32(0x03C) -#define GPIO5_DEBOUNCENABLE GPIO5_REG32(0x050) -#define GPIO5_DEBOUNCINGTIME GPIO5_REG32(0x054) -#endif - -/* IO CONFIG */ -#define OMAP24XX_CTRL_BASE (L4_24XX_BASE) -#define CONTROL_REG32(offset) __REG32(OMAP24XX_CTRL_BASE + (offset)) - -#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104) -#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134) -#define CONTROL_PADCONF_UART1_RX CONTROL_REG32(0x0C8) -#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C) -#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090) -#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8) -#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC) /* 2420 */ -#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0) -#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC) -#define CONTROL_PADCONF_SYS_NIRQW0 CONTROL_REG32(0x0BC) /* 2430 */ -#define CONTROL_PADCONF_SSI1_FLAG_TX CONTROL_REG32(0x108) /* 2430 */ - -/* CONTROL */ -#define CONTROL_DEVCONF CONTROL_REG32(0x274) -#define CONTROL_DEVCONF1 CONTROL_REG32(0x2E8) - -/* INTERRUPT CONTROLLER */ -#define INTC_BASE ((L4_24XX_BASE) + 0xfe000) -#define INTC_REG32(offset) __REG32(INTC_BASE + (offset)) - -#define INTC1_U_BASE INTC_REG32(0x000) -#define INTC_MIR0 INTC_REG32(0x084) -#define INTC_MIR_SET0 INTC_REG32(0x08C) -#define INTC_MIR_CLEAR0 INTC_REG32(0x088) -#define INTC_ISR_CLEAR0 INTC_REG32(0x094) -#define INTC_MIR1 INTC_REG32(0x0A4) -#define INTC_MIR_SET1 INTC_REG32(0x0AC) -#define INTC_MIR_CLEAR1 INTC_REG32(0x0A8) -#define INTC_ISR_CLEAR1 INTC_REG32(0x0B4) -#define INTC_MIR2 INTC_REG32(0x0C4) -#define INTC_MIR_SET2 INTC_REG32(0x0CC) -#define INTC_MIR_CLEAR2 INTC_REG32(0x0C8) -#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4) -#define INTC_SIR_IRQ INTC_REG32(0x040) -#define INTC_CONTROL INTC_REG32(0x048) -#define INTC_ILR11 INTC_REG32(0x12C) /* PRCM on MPU PIC */ -#define INTC_ILR30 INTC_REG32(0x178) -#define INTC_ILR31 INTC_REG32(0x17C) -#define INTC_ILR32 INTC_REG32(0x180) -#define INTC_ILR37 INTC_REG32(0x194) /* GPIO4 on MPU PIC */ -#define INTC_SYSCONFIG INTC_REG32(0x010) /* GPT1 on MPU PIC */ - -/* RAM FIREWALL */ -#define RAMFW_BASE (0x68005000) -#define RAMFW_REG32(offset) __REG32(RAMFW_BASE + (offset)) - -#define RAMFW_REQINFOPERM0 RAMFW_REG32(0x048) -#define RAMFW_READPERM0 RAMFW_REG32(0x050) -#define RAMFW_WRITEPERM0 RAMFW_REG32(0x058) - -/* GPMC CS1 FPGA ON USER INTERFACE MODULE */ -//#define DEBUG_BOARD_LED_REGISTER 0x04000014 - -/* GPMC CS0 */ -#define GPMC_CONFIG1_0 GPMC_REG32(0x060) -#define GPMC_CONFIG2_0 GPMC_REG32(0x064) -#define GPMC_CONFIG3_0 GPMC_REG32(0x068) -#define GPMC_CONFIG4_0 GPMC_REG32(0x06C) -#define GPMC_CONFIG5_0 GPMC_REG32(0x070) -#define GPMC_CONFIG6_0 GPMC_REG32(0x074) -#define GPMC_CONFIG7_0 GPMC_REG32(0x078) - -/* GPMC CS1 */ -#define GPMC_CONFIG1_1 GPMC_REG32(0x090) -#define GPMC_CONFIG2_1 GPMC_REG32(0x094) -#define GPMC_CONFIG3_1 GPMC_REG32(0x098) -#define GPMC_CONFIG4_1 GPMC_REG32(0x09C) -#define GPMC_CONFIG5_1 GPMC_REG32(0x0a0) -#define GPMC_CONFIG6_1 GPMC_REG32(0x0a4) -#define GPMC_CONFIG7_1 GPMC_REG32(0x0a8) - -/* GPMC CS3 */ -#define GPMC_CONFIG1_3 GPMC_REG32(0x0F0) -#define GPMC_CONFIG2_3 GPMC_REG32(0x0F4) -#define GPMC_CONFIG3_3 GPMC_REG32(0x0F8) -#define GPMC_CONFIG4_3 GPMC_REG32(0x0FC) -#define GPMC_CONFIG5_3 GPMC_REG32(0x100) -#define GPMC_CONFIG6_3 GPMC_REG32(0x104) -#define GPMC_CONFIG7_3 GPMC_REG32(0x108) - -/* DSS */ -#define DSS_CONTROL DISP_REG32(0x040) -#define DISPC_CONTROL DISP_REG32(0x440) -#define DISPC_SYSSTATUS DISP_REG32(0x414) -#define DISPC_IRQSTATUS DISP_REG32(0x418) -#define DISPC_IRQENABLE DISP_REG32(0x41C) -#define DISPC_CONFIG DISP_REG32(0x444) -#define DISPC_DEFAULT_COLOR0 DISP_REG32(0x44C) -#define DISPC_DEFAULT_COLOR1 DISP_REG32(0x450) -#define DISPC_TRANS_COLOR0 DISP_REG32(0x454) -#define DISPC_TRANS_COLOR1 DISP_REG32(0x458) -#define DISPC_LINE_NUMBER DISP_REG32(0x460) -#define DISPC_TIMING_H DISP_REG32(0x464) -#define DISPC_TIMING_V DISP_REG32(0x468) -#define DISPC_POL_FREQ DISP_REG32(0x46C) -#define DISPC_DIVISOR DISP_REG32(0x470) -#define DISPC_SIZE_DIG DISP_REG32(0x478) -#define DISPC_SIZE_LCD DISP_REG32(0x47C) -#define DISPC_GFX_BA0 DISP_REG32(0x480) -#define DISPC_GFX_BA1 DISP_REG32(0x484) -#define DISPC_GFX_POSITION DISP_REG32(0x488) -#define DISPC_GFX_SIZE DISP_REG32(0x48C) -#define DISPC_GFX_ATTRIBUTES DISP_REG32(0x4A0) -#define DISPC_GFX_FIFO_THRESHOLD DISP_REG32(0x4A4) -#define DISPC_GFX_ROW_INC DISP_REG32(0x4AC) -#define DISPC_GFX_PIXEL_INC DISP_REG32(0x4B0) -#define DISPC_GFX_WINDOW_SKIP DISP_REG32(0x4B4) -#define DISPC_GFX_TABLE_BA DISP_REG32(0x4B8) -#define DISPC_DATA_CYCLE1 DISP_REG32(0x5D4) -#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8) -#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC) - -/* HSUSB Suspend */ -#define HSUSB_CTRL __REG8(0x480AC001) -#define USBOTG_POWER __REG32(0x480AC000) - -/* HS MMC */ -#define MMCHS1_SYSCONFIG __REG32(0x4809C010) -#define MMCHS2_SYSCONFIG __REG32(0x480b4010) - -#endif /* __ASSEMBLER__ */ - -#endif - - - - - diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c deleted file mode 100644 index 8893479dc..000000000 --- a/arch/arm/mach-omap2/prcm.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/prcm.c - * - * OMAP 24xx Power Reset and Clock Management (PRCM) functions - * - * Copyright (C) 2005 Nokia Corporation - * - * Written by Tony Lindgren - * - * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include - -#include "prcm-regs.h" - -u32 omap_prcm_get_reset_sources(void) -{ - return RM_RSTST_WKUP & 0x7f; -} -EXPORT_SYMBOL(omap_prcm_get_reset_sources); - -/* Resets clock rates and reboots the system. Only called from system.h */ -void omap_prcm_arch_reset(char mode) -{ - u32 rate; - struct clk *vclk, *sclk; - - vclk = clk_get(NULL, "virt_prcm_set"); - sclk = clk_get(NULL, "sys_ck"); - rate = clk_get_rate(sclk); - clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */ - RM_RSTCTRL_WKUP |= 2; -} diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 0884bc7c2..24dd37422 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -167,7 +167,7 @@ void __init omap_serial_init() static struct platform_device serial_device = { .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, + .id = 0, .dev = { .platform_data = serial_platform_data, }, diff --git a/arch/arm/mach-omap2/sleep.S b/arch/arm/mach-omap2/sleep.S deleted file mode 100644 index 00299cbeb..000000000 --- a/arch/arm/mach-omap2/sleep.S +++ /dev/null @@ -1,144 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/sleep.S - * - * (C) Copyright 2004 - * Texas Instruments, - * Richard Woodruff - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include - -#define A_32KSYNC_CR_V IO_ADDRESS(OMAP_TIMER32K_BASE+0x10) -#define A_PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x50) -#define A_PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x80) -#define A_CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x500) -#define A_CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x520) -#define A_CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x540) -#define A_CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x544) - -#define A_SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x60) -#define A_SDRC_POWER_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x70) -#define A_SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA4) -#define A_SDRC0_V (0xC0000000) -#define A_SDRC_MANUAL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA8) - - .text - -/* - * Forces OMAP into idle state - * - * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI - * for normal idles. - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - * wakes up it continues execution at the point it went to sleep. - */ -ENTRY(omap24xx_idle_loop_suspend) - stmfd sp!, {r0, lr} @ save registers on stack - mov r0, #0 @ clear for mcr setup - mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt - ldmfd sp!, {r0, pc} @ restore regs and return - -ENTRY(omap24xx_idle_loop_suspend_sz) - .word . - omap24xx_idle_loop_suspend - -/* - * omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing - * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore - * SDRC. - * - * Input: - * R0 : DLL ctrl value pre-Sleep - * R1 : Processor+Revision - * 2420: 0x21 = 242xES1, 0x26 = 242xES2.2 - * 2430: 0x31 = 2430ES1, 0x32 = 2430ES2 - * - * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on - * when we get called, but the DLL probably isn't. We will wait a bit more in - * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even - * if in unlocked mode. - * - * For less than 242x-ES2.2 upon wake from a sleep mode where the external - * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz - * clock can pass into the PRCM can cause problems at DSP and IVA. - * To work around this the code will switch to the 32kHz source prior to sleep. - * Post sleep we will shift back to using the DPLL. Apparently, - * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait - * 3x12MHz + 3x32kHz clocks for a full switch. - * - * The DLL load value is not kept in RETENTION or OFF. It needs to be restored - * at wake - */ -ENTRY(omap24xx_cpu_suspend) - stmfd sp!, {r0 - r12, lr} @ save registers on stack - mov r3, #0x0 @ clear for mrc call - mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished - nop - nop - ldr r3, A_SDRC_POWER @ addr of sdrc power - ldr r4, [r3] @ value of sdrc power - orr r4, r4, #0x40 @ enable self refresh on idle req - mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) - str r4, [r3] @ make it so - mov r2, #0 - nop - mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt - nop -loop: - subs r5, r5, #0x1 @ awake, wait just a bit - bne loop - - /* The DPLL has on before we take the DDR out of self refresh */ - bic r4, r4, #0x40 @ now clear self refresh bit. - str r4, [r3] @ put vlaue back. - ldr r4, A_SDRC0 @ make a clock happen - ldr r4, [r4] - nop @ start auto refresh only after clk ok - movs r0, r0 @ see if DDR or SDR - ldrne r1, A_SDRC_DLLA_CTRL_S @ get addr of DLL ctrl - strne r0, [r1] @ rewrite DLLA to force DLL reload - addne r1, r1, #0x8 @ move to DLLB - strne r0, [r1] @ rewrite DLLB to force DLL reload - - mov r5, #0x1000 -loop2: - subs r5, r5, #0x1 - bne loop2 - /* resume*/ - ldmfd sp!, {r0 - r12, pc} @ restore regs and return - -A_SDRC_POWER: - .word A_SDRC_POWER_V -A_SDRC0: - .word A_SDRC0_V -A_CM_CLKSEL2_PLL_S: - .word A_CM_CLKSEL2_PLL_V -A_CM_CLKEN_PLL: - .word A_CM_CLKEN_PLL_V -A_SDRC_DLLA_CTRL_S: - .word A_SDRC_DLLA_CTRL_V -A_SDRC_MANUAL_S: - .word A_SDRC_MANUAL_V - -ENTRY(omap24xx_cpu_suspend_sz) - .word . - omap24xx_cpu_suspend - diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram-fn.S index d261e4ff4..2a869e203 100644 --- a/arch/arm/mach-omap2/sram-fn.S +++ b/arch/arm/mach-omap2/sram-fn.S @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap2/sram.S + * linux/arch/arm/mach-omap1/sram.S * * Omap2 specific functions that need to be run in internal SRAM * @@ -28,7 +28,7 @@ #include #include -#include "prcm-regs.h" +#include #define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010) diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 0104fd142..c1d77f5b3 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -10,11 +10,6 @@ config ARCH_LUBBOCK select PXA25x select SA1111 -config MACH_LOGICPD_PXA270 - bool "LogicPD PXA270 Card Engine Development Platform" - select PXA27x - select IWMMXT - config MACH_MAINSTONE bool "Intel HCDDBBVA0 Development Platform" select PXA27x diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 4e8a983e2..32526a0a6 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -3,13 +3,12 @@ # # Common support (must be linked before board specific support) -obj-y += clock.o generic.o irq.o dma.o time.o +obj-y += generic.o irq.o dma.o time.o obj-$(CONFIG_PXA25x) += pxa25x.o obj-$(CONFIG_PXA27x) += pxa27x.o # Specific board support obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o -obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o obj-$(CONFIG_ARCH_PXA_IDP) += idp.o obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c deleted file mode 100644 index 8f7c90a05..000000000 --- a/arch/arm/mach-pxa/clock.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * linux/arch/arm/mach-sa1100/clock.c - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -struct clk { - struct list_head node; - unsigned long rate; - struct module *owner; - const char *name; - unsigned int enabled; - void (*enable)(void); - void (*disable)(void); -}; - -static LIST_HEAD(clocks); -static DECLARE_MUTEX(clocks_sem); -static DEFINE_SPINLOCK(clocks_lock); - -struct clk *clk_get(struct device *dev, const char *id) -{ - struct clk *p, *clk = ERR_PTR(-ENOENT); - - down(&clocks_sem); - list_for_each_entry(p, &clocks, node) { - if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { - clk = p; - break; - } - } - up(&clocks_sem); - - return clk; -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ - module_put(clk->owner); -} -EXPORT_SYMBOL(clk_put); - -int clk_enable(struct clk *clk) -{ - unsigned long flags; - - spin_lock_irqsave(&clocks_lock, flags); - if (clk->enabled++ == 0) - clk->enable(); - spin_unlock_irqrestore(&clocks_lock, flags); - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ - unsigned long flags; - - WARN_ON(clk->enabled == 0); - - spin_lock_irqsave(&clocks_lock, flags); - if (--clk->enabled == 0) - clk->disable(); - spin_unlock_irqrestore(&clocks_lock, flags); -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - - -static void clk_gpio27_enable(void) -{ - pxa_gpio_mode(GPIO11_3_6MHz_MD); -} - -static void clk_gpio27_disable(void) -{ -} - -static struct clk clk_gpio27 = { - .name = "GPIO27_CLK", - .rate = 3686400, - .enable = clk_gpio27_enable, - .disable = clk_gpio27_disable, -}; - -int clk_register(struct clk *clk) -{ - down(&clocks_sem); - list_add(&clk->node, &clocks); - up(&clocks_sem); - return 0; -} -EXPORT_SYMBOL(clk_register); - -void clk_unregister(struct clk *clk) -{ - down(&clocks_sem); - list_del(&clk->node); - up(&clocks_sem); -} -EXPORT_SYMBOL(clk_unregister); - -static int __init clk_init(void) -{ - clk_register(&clk_gpio27); - return 0; -} -arch_initcall(clk_init); diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index d6d726036..7ffd2de8f 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -141,8 +142,6 @@ struct corgissp_machinfo corgi_ssp_machinfo = { */ static struct corgibl_machinfo corgi_bl_machinfo = { .max_intensity = 0x2f, - .default_intensity = 0x1f, - .limit_mask = 0x0b, .set_bl_intensity = corgi_bl_set_intensity, }; @@ -165,14 +164,6 @@ static struct platform_device corgikbd_device = { }; -/* - * Corgi LEDs - */ -static struct platform_device corgiled_device = { - .name = "corgi-led", - .id = -1, -}; - /* * Corgi Touch Screen Device */ @@ -307,7 +298,6 @@ static struct platform_device *devices[] __initdata = { &corgikbd_device, &corgibl_device, &corgits_device, - &corgiled_device, }; static void __init corgi_init(void) diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index 8a25a1c80..b371d7236 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c @@ -196,9 +196,12 @@ static int __init corgi_ssp_probe(struct platform_device *dev) int ret; /* Chip Select - Disable All */ - pxa_gpio_mode(ssp_machinfo->cs_lcdcon | GPIO_OUT | GPIO_DFLT_HIGH); - pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH); - pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH); + GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */ + GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ + GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */ + GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ + GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c index 7d8c85486..458112b21 100644 --- a/arch/arm/mach-pxa/dma.c +++ b/arch/arm/mach-pxa/dma.c @@ -45,16 +45,23 @@ int pxa_request_dma (char *name, pxa_dma_prio prio, local_irq_save(flags); - do { - /* try grabbing a DMA channel with the requested priority */ - pxa_for_each_dma_prio (i, prio) { + /* try grabbing a DMA channel with the requested priority */ + for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) { + if (!dma_channels[i].name) { + found = 1; + break; + } + } + + if (!found) { + /* requested prio group is full, try hier priorities */ + for (i = prio-1; i >= 0; i--) { if (!dma_channels[i].name) { found = 1; break; } } - /* if requested prio group is full, try a hier priority */ - } while (!found && prio--); + } if (found) { DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 5efa84749..9b48a90ae 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -319,11 +319,6 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) pxaficp_device.dev.platform_data = info; } -static struct platform_device pxartc_device = { - .name = "sa1100-rtc", - .id = -1, -}; - static struct platform_device *devices[] __initdata = { &pxamci_device, &udc_device, @@ -334,7 +329,6 @@ static struct platform_device *devices[] __initdata = { &pxaficp_device, &i2c_device, &i2s_device, - &pxartc_device, }; static int __init pxa_init(void) diff --git a/arch/arm/mach-pxa/leds-mainstone.c b/arch/arm/mach-pxa/leds-mainstone.c index c06d3d7a8..bbd3f87a9 100644 --- a/arch/arm/mach-pxa/leds-mainstone.c +++ b/arch/arm/mach-pxa/leds-mainstone.c @@ -85,7 +85,7 @@ void mainstone_leds_event(led_event_t evt) break; case led_green_on: - hw_led_state |= D21; + hw_led_state |= D21;; break; case led_green_off: @@ -93,7 +93,7 @@ void mainstone_leds_event(led_event_t evt) break; case led_amber_on: - hw_led_state |= D22; + hw_led_state |= D22;; break; case led_amber_off: @@ -101,7 +101,7 @@ void mainstone_leds_event(led_event_t evt) break; case led_red_on: - hw_led_state |= D23; + hw_led_state |= D23;; break; case led_red_off: diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c deleted file mode 100644 index ec0f43a10..000000000 --- a/arch/arm/mach-pxa/lpd270.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/lpd270.c - * - * Support for the LogicPD PXA270 Card Engine. - * Derived from the mainstone code, which carries these notices: - * - * Author: Nicolas Pitre - * Created: Nov 05, 2002 - * Copyright: MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "generic.h" - - -static unsigned int lpd270_irq_enabled; - -static void lpd270_mask_irq(unsigned int irq) -{ - int lpd270_irq = irq - LPD270_IRQ(0); - - __raw_writew(~(1 << lpd270_irq), LPD270_INT_STATUS); - - lpd270_irq_enabled &= ~(1 << lpd270_irq); - __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK); -} - -static void lpd270_unmask_irq(unsigned int irq) -{ - int lpd270_irq = irq - LPD270_IRQ(0); - - lpd270_irq_enabled |= 1 << lpd270_irq; - __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK); -} - -static struct irqchip lpd270_irq_chip = { - .ack = lpd270_mask_irq, - .mask = lpd270_mask_irq, - .unmask = lpd270_unmask_irq, -}; - -static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc, - struct pt_regs *regs) -{ - unsigned long pending; - - pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled; - do { - GEDR(0) = GPIO_bit(0); /* clear useless edge notification */ - if (likely(pending)) { - irq = LPD270_IRQ(0) + __ffs(pending); - desc = irq_desc + irq; - desc_handle_irq(irq, desc, regs); - - pending = __raw_readw(LPD270_INT_STATUS) & - lpd270_irq_enabled; - } - } while (pending); -} - -static void __init lpd270_init_irq(void) -{ - int irq; - - pxa_init_irq(); - - __raw_writew(0, LPD270_INT_MASK); - __raw_writew(0, LPD270_INT_STATUS); - - /* setup extra LogicPD PXA270 irqs */ - for (irq = LPD270_IRQ(2); irq <= LPD270_IRQ(4); irq++) { - set_irq_chip(irq, &lpd270_irq_chip); - set_irq_handler(irq, do_level_IRQ); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler); - set_irq_type(IRQ_GPIO(0), IRQT_FALLING); -} - - -#ifdef CONFIG_PM -static int lpd270_irq_resume(struct sys_device *dev) -{ - __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK); - return 0; -} - -static struct sysdev_class lpd270_irq_sysclass = { - set_kset_name("cpld_irq"), - .resume = lpd270_irq_resume, -}; - -static struct sys_device lpd270_irq_device = { - .cls = &lpd270_irq_sysclass, -}; - -static int __init lpd270_irq_device_init(void) -{ - int ret = sysdev_class_register(&lpd270_irq_sysclass); - if (ret == 0) - ret = sysdev_register(&lpd270_irq_device); - return ret; -} - -device_initcall(lpd270_irq_device_init); -#endif - - -static struct resource smc91x_resources[] = { - [0] = { - .start = LPD270_ETH_PHYS, - .end = (LPD270_ETH_PHYS + 0xfffff), - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = LPD270_ETHERNET_IRQ, - .end = LPD270_ETHERNET_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; - -static struct platform_device lpd270_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - -static struct resource lpd270_flash_resources[] = { - [0] = { - .start = PXA_CS0_PHYS, - .end = PXA_CS0_PHYS + SZ_64M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = PXA_CS1_PHYS, - .end = PXA_CS1_PHYS + SZ_64M - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct mtd_partition lpd270_flash0_partitions[] = { - { - .name = "Bootloader", - .size = 0x00040000, - .offset = 0, - .mask_flags = MTD_WRITEABLE /* force read-only */ - }, { - .name = "Kernel", - .size = 0x00400000, - .offset = 0x00040000, - }, { - .name = "Filesystem", - .size = MTDPART_SIZ_FULL, - .offset = 0x00440000 - }, -}; - -static struct flash_platform_data lpd270_flash_data[2] = { - { - .name = "processor-flash", - .map_name = "cfi_probe", - .parts = lpd270_flash0_partitions, - .nr_parts = ARRAY_SIZE(lpd270_flash0_partitions), - }, { - .name = "mainboard-flash", - .map_name = "cfi_probe", - .parts = NULL, - .nr_parts = 0, - } -}; - -static struct platform_device lpd270_flash_device[2] = { - { - .name = "pxa2xx-flash", - .id = 0, - .dev = { - .platform_data = &lpd270_flash_data[0], - }, - .resource = &lpd270_flash_resources[0], - .num_resources = 1, - }, { - .name = "pxa2xx-flash", - .id = 1, - .dev = { - .platform_data = &lpd270_flash_data[1], - }, - .resource = &lpd270_flash_resources[1], - .num_resources = 1, - }, -}; - -static void lpd270_backlight_power(int on) -{ - if (on) { - pxa_gpio_mode(GPIO16_PWM0_MD); - pxa_set_cken(CKEN0_PWM0, 1); - PWM_CTRL0 = 0; - PWM_PWDUTY0 = 0x3ff; - PWM_PERVAL0 = 0x3ff; - } else { - PWM_CTRL0 = 0; - PWM_PWDUTY0 = 0x0; - PWM_PERVAL0 = 0x3FF; - pxa_set_cken(CKEN0_PWM0, 0); - } -} - -/* 5.7" TFT QVGA (LoLo display number 1) */ -static struct pxafb_mach_info sharp_lq057q3dc02 __initdata = { - .pixclock = 100000, - .xres = 240, - .yres = 320, - .bpp = 16, - .hsync_len = 64, - .left_margin = 0x27, - .right_margin = 0x09, - .vsync_len = 0x04, - .upper_margin = 0x08, - .lower_margin = 0x14, - .sync = 0, - .lccr0 = 0x07800080, - .lccr3 = 0x04400007, - .pxafb_backlight_power = lpd270_backlight_power, -}; - -/* 6.4" TFT VGA (LoLo display number 5) */ -static struct pxafb_mach_info sharp_lq64d343 __initdata = { - .pixclock = 20000, - .xres = 640, - .yres = 480, - .bpp = 16, - .hsync_len = 49, - .left_margin = 0x89, - .right_margin = 0x19, - .vsync_len = 18, - .upper_margin = 0x22, - .lower_margin = 0, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .lccr0 = 0x07800080, - .lccr3 = 0x04400001, - .pxafb_backlight_power = lpd270_backlight_power, -}; - -/* 3.5" TFT QVGA (LoLo display number 8) */ -static struct pxafb_mach_info sharp_lq035q7db02_20 __initdata = { - .pixclock = 100000, - .xres = 240, - .yres = 320, - .bpp = 16, - .hsync_len = 0x34, - .left_margin = 0x09, - .right_margin = 0x09, - .vsync_len = 0x08, - .upper_margin = 0x05, - .lower_margin = 0x14, - .sync = 0, - .lccr0 = 0x07800080, - .lccr3 = 0x04400007, - .pxafb_backlight_power = lpd270_backlight_power, -}; - -static struct platform_device *platform_devices[] __initdata = { - &smc91x_device, - &lpd270_audio_device, - &lpd270_flash_device[0], - &lpd270_flash_device[1], -}; - -static int lpd270_ohci_init(struct device *dev) -{ - /* setup Port1 GPIO pin. */ - pxa_gpio_mode(88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ - pxa_gpio_mode(89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ - - /* Set the Power Control Polarity Low and Power Sense - Polarity Low to active low. */ - UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & - ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); - - return 0; -} - -static struct pxaohci_platform_data lpd270_ohci_platform_data = { - .port_mode = PMM_PERPORT_MODE, - .init = lpd270_ohci_init, -}; - -static void __init lpd270_init(void) -{ - lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4; - lpd270_flash_data[1].width = 4; - - /* - * System bus arbiter setting: - * - Core_Park - * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4 - */ - ARB_CNTRL = ARB_CORE_PARK | 0x234; - - /* - * On LogicPD PXA270, we route AC97_SYSCLK via GPIO45. - */ - pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); - - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); - - // set_pxa_fb_info(&sharp_lq057q3dc02); - set_pxa_fb_info(&sharp_lq64d343); - // set_pxa_fb_info(&sharp_lq035q7db02_20); - - pxa_set_ohci_info(&lpd270_ohci_platform_data); -} - - -static struct map_desc lpd270_io_desc[] __initdata = { - { - .virtual = LPD270_CPLD_VIRT, - .pfn = __phys_to_pfn(LPD270_CPLD_PHYS), - .length = LPD270_CPLD_SIZE, - .type = MT_DEVICE, - }, -}; - -static void __init lpd270_map_io(void) -{ - pxa_map_io(); - iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc)); - - /* initialize sleep mode regs (wake-up sources, etc) */ - PGSR0 = 0x00008800; - PGSR1 = 0x00000002; - PGSR2 = 0x0001FC00; - PGSR3 = 0x00001F81; - PWER = 0xC0000002; - PRER = 0x00000002; - PFER = 0x00000002; - - /* for use I SRAM as framebuffer. */ - PSLR |= 0x00000F04; - PCFR = 0x00000066; -} - -MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine") - /* Maintainer: Peter Barada */ - .phys_io = 0x40000000, - .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = lpd270_map_io, - .init_irq = lpd270_init_irq, - .timer = &pxa_timer, - .init_machine = lpd270_init, -MACHINE_END diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index b307f1195..d5bda6020 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -95,10 +95,7 @@ static void __init mainstone_init_irq(void) for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { set_irq_chip(irq, &mainstone_irq_chip); set_irq_handler(irq, do_level_IRQ); - if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14)) - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN); - else - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } set_irq_flags(MAINSTONE_IRQ(8), 0); set_irq_flags(MAINSTONE_IRQ(12), 0); @@ -160,14 +157,14 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv) +static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF; return 0; } -static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv) +static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; @@ -493,7 +490,6 @@ static void __init mainstone_map_io(void) MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") /* Maintainer: MontaVista Software Inc. */ .phys_io = 0x40000000, - .boot_params = 0xa0000100, /* BLOB boot parameter setting */ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = mainstone_map_io, .init_irq = mainstone_init_irq, diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index a042473de..911e6ff5a 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -307,10 +308,6 @@ static void __init fixup_poodle(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) { sharpsl_save_param(); - mi->nr_banks=1; - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; - mi->bank[0].size = (32*1024*1024); } MACHINE_START(POODLE, "SHARP Poodle") diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 44bcb8097..c094d99eb 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -220,8 +221,6 @@ struct corgissp_machinfo spitz_ssp_machinfo = { * Spitz Backlight Device */ static struct corgibl_machinfo spitz_bl_machinfo = { - .default_intensity = 0x1f, - .limit_mask = 0x0b, .max_intensity = 0x2f, }; @@ -243,14 +242,6 @@ static struct platform_device spitzkbd_device = { }; -/* - * Spitz LEDs - */ -static struct platform_device spitzled_device = { - .name = "spitz-led", - .id = -1, -}; - /* * Spitz Touch Screen Device */ @@ -371,7 +362,6 @@ static int spitz_ohci_init(struct device *dev) static struct pxaohci_platform_data spitz_ohci_platform_data = { .port_mode = PMM_NPS_MODE, .init = spitz_ohci_init, - .power_budget = 150, }; @@ -429,7 +419,6 @@ static struct platform_device *devices[] __initdata = { &spitzkbd_device, &spitzts_device, &spitzbl_device, - &spitzled_device, }; static void __init common_init(void) @@ -479,8 +468,6 @@ struct platform_device akitaioexp_device = { .id = -1, }; -EXPORT_SYMBOL_GPL(akitaioexp_device); - static void __init akita_init(void) { spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode; diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 76c0e7f0a..d168286ed 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -251,19 +252,10 @@ static struct platform_device tosakbd_device = { .id = -1, }; -/* - * Tosa LEDs - */ -static struct platform_device tosaled_device = { - .name = "tosa-led", - .id = -1, -}; - static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, &tosakbd_device, - &tosaled_device, }; static void __init tosa_init(void) diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index d13270c5d..4303d988c 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -202,6 +202,11 @@ struct clk realview_clcd_clk = { /* * CLCD support. */ +#define SYS_CLCD_MODE_MASK (3 << 0) +#define SYS_CLCD_MODE_888 (0 << 0) +#define SYS_CLCD_MODE_5551 (1 << 0) +#define SYS_CLCD_MODE_565_RLSB (2 << 0) +#define SYS_CLCD_MODE_565_BLSB (3 << 0) #define SYS_CLCD_NLCDIOON (1 << 2) #define SYS_CLCD_VDDPOSSWITCH (1 << 3) #define SYS_CLCD_PWR3V5SWITCH (1 << 4) @@ -355,10 +360,29 @@ static void realview_clcd_enable(struct clcd_fb *fb) void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET; u32 val; + val = readl(sys_clcd); + val &= ~SYS_CLCD_MODE_MASK; + + switch (fb->fb.var.green.length) { + case 5: + val |= SYS_CLCD_MODE_5551; + break; + case 6: + val |= SYS_CLCD_MODE_565_RLSB; + break; + case 8: + val |= SYS_CLCD_MODE_888; + break; + } + /* - * Enable the PSUs + * Set the MUX + */ + writel(val, sys_clcd); + + /* + * And now enable the PSUs */ - val = readl(sys_clcd); val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; writel(val, sys_clcd); } diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 693fb1e39..d4a586e38 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -137,11 +137,8 @@ static struct amba_device *amba_devs[] __initdata = { static void __init gic_init_irq(void) { #ifdef CONFIG_REALVIEW_MPCORE - unsigned int pldctrl; writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK)); - pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + 0xd8); - pldctrl |= 0x00800000; /* New irq mode */ - writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + 0xd8); + writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8); writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); #endif gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 970f98dad..0b9d7ca49 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -9,13 +9,6 @@ config MACH_ANUBIS Say Y gere if you are using the Simtec Electronics ANUBIS development system -config MACH_OSIRIS - bool "Simtec IM2440D20 (OSIRIS) module" - select CPU_S3C2440 - help - Say Y here if you are using the Simtec IM2440D20 module, also - known as the Osiris. - config ARCH_BAST bool "Simtec Electronics BAST (EB2410ITX)" select CPU_S3C2410 @@ -50,15 +43,9 @@ config MACH_N30 . -config MACH_SMDK - bool - help - Common machine code for SMDK2410 and SMDK2440 - config ARCH_SMDK2410 bool "SMDK2410/A9M2410" select CPU_S3C2410 - select MACH_SMDK help Say Y here if you are using the SMDK2410 or the derived module A9M2410 @@ -66,7 +53,6 @@ config ARCH_SMDK2410 config ARCH_S3C2440 bool "SMDK2440" select CPU_S3C2440 - select MACH_SMDK help Say Y here if you are using the SMDK2440. @@ -170,7 +156,7 @@ config S3C2410_PM_DEBUG depends on ARCH_S3C2410 && PM help Say Y here if you want verbose debugging from the PM Suspend and - Resume code. See + Resume code. See `Documentation/arm/Samsing-S3C24XX/Suspend.txt` for more information. config S3C2410_PM_CHECK diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 3e5712db6..1217bf003 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o # machine specific support obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o -obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o obj-$(CONFIG_ARCH_H1940) += mach-h1940.o obj-$(CONFIG_MACH_N30) += mach-n30.o @@ -48,5 +47,3 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o obj-$(CONFIG_MACH_OTOM) += mach-otom.o obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o - -obj-$(CONFIG_MACH_SMDK) += common-smdk.o \ No newline at end of file diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index 6de713ad3..08489efda 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c @@ -38,14 +38,12 @@ #include #include #include -#include #include #include #include #include -#include #include "clock.h" #include "cpu.h" @@ -53,8 +51,7 @@ /* clock information */ static LIST_HEAD(clocks); - -DEFINE_MUTEX(clocks_mutex); +static DEFINE_MUTEX(clocks_mutex); /* old functions */ @@ -181,24 +178,12 @@ unsigned long clk_get_rate(struct clk *clk) long clk_round_rate(struct clk *clk, unsigned long rate) { - if (!IS_ERR(clk) && clk->round_rate) - return (clk->round_rate)(clk, rate); - return rate; } int clk_set_rate(struct clk *clk, unsigned long rate) { - int ret; - - if (IS_ERR(clk)) - return -EINVAL; - - mutex_lock(&clocks_mutex); - ret = (clk->set_rate)(clk, rate); - mutex_unlock(&clocks_mutex); - - return ret; + return -EINVAL; } struct clk *clk_get_parent(struct clk *clk) @@ -206,23 +191,6 @@ struct clk *clk_get_parent(struct clk *clk) return clk->parent; } -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - int ret = 0; - - if (IS_ERR(clk)) - return -EINVAL; - - mutex_lock(&clocks_mutex); - - if (clk->set_parent) - ret = (clk->set_parent)(clk, parent); - - mutex_unlock(&clocks_mutex); - - return ret; -} - EXPORT_SYMBOL(clk_get); EXPORT_SYMBOL(clk_put); EXPORT_SYMBOL(clk_enable); @@ -231,29 +199,6 @@ EXPORT_SYMBOL(clk_get_rate); EXPORT_SYMBOL(clk_round_rate); EXPORT_SYMBOL(clk_set_rate); EXPORT_SYMBOL(clk_get_parent); -EXPORT_SYMBOL(clk_set_parent); - -/* base clock enable */ - -static int s3c24xx_upll_enable(struct clk *clk, int enable) -{ - unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW); - unsigned long orig = clkslow; - - if (enable) - clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF; - else - clkslow |= S3C2410_CLKSLOW_UCLK_OFF; - - __raw_writel(clkslow, S3C2410_CLKSLOW); - - /* if we started the UPLL, then allow to settle */ - - if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF)) - udelay(200); - - return 0; -} /* base clocks */ @@ -265,14 +210,6 @@ static struct clk clk_xtal = { .ctrlbit = 0, }; -static struct clk clk_upll = { - .name = "upll", - .id = -1, - .parent = NULL, - .enable = s3c24xx_upll_enable, - .ctrlbit = 0, -}; - static struct clk clk_f = { .name = "fclk", .id = -1, @@ -297,128 +234,26 @@ static struct clk clk_p = { .ctrlbit = 0, }; -struct clk clk_usb_bus = { - .name = "usb-bus", - .id = -1, - .rate = 0, - .parent = &clk_upll, -}; - /* clocks that could be registered by external code */ -static int s3c24xx_dclk_enable(struct clk *clk, int enable) -{ - unsigned long dclkcon = __raw_readl(S3C2410_DCLKCON); - - if (enable) - dclkcon |= clk->ctrlbit; - else - dclkcon &= ~clk->ctrlbit; - - __raw_writel(dclkcon, S3C2410_DCLKCON); - - return 0; -} - -static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent) -{ - unsigned long dclkcon; - unsigned int uclk; - - if (parent == &clk_upll) - uclk = 1; - else if (parent == &clk_p) - uclk = 0; - else - return -EINVAL; - - clk->parent = parent; - - dclkcon = __raw_readl(S3C2410_DCLKCON); - - if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) { - if (uclk) - dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK; - else - dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK; - } else { - if (uclk) - dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK; - else - dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK; - } - - __raw_writel(dclkcon, S3C2410_DCLKCON); - - return 0; -} - - -static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) -{ - unsigned long mask; - unsigned long source; - - /* calculate the MISCCR setting for the clock */ - - if (parent == &clk_xtal) - source = S3C2410_MISCCR_CLK0_MPLL; - else if (parent == &clk_upll) - source = S3C2410_MISCCR_CLK0_UPLL; - else if (parent == &clk_f) - source = S3C2410_MISCCR_CLK0_FCLK; - else if (parent == &clk_h) - source = S3C2410_MISCCR_CLK0_HCLK; - else if (parent == &clk_p) - source = S3C2410_MISCCR_CLK0_PCLK; - else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0) - source = S3C2410_MISCCR_CLK0_DCLK0; - else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1) - source = S3C2410_MISCCR_CLK0_DCLK0; - else - return -EINVAL; - - clk->parent = parent; - - if (clk == &s3c24xx_dclk0) - mask = S3C2410_MISCCR_CLK0_MASK; - else { - source <<= 4; - mask = S3C2410_MISCCR_CLK1_MASK; - } - - s3c2410_modify_misccr(mask, source); - return 0; -} - -/* external clock definitions */ - struct clk s3c24xx_dclk0 = { .name = "dclk0", .id = -1, - .ctrlbit = S3C2410_DCLKCON_DCLK0EN, - .enable = s3c24xx_dclk_enable, - .set_parent = s3c24xx_dclk_setparent, }; struct clk s3c24xx_dclk1 = { .name = "dclk1", .id = -1, - .ctrlbit = S3C2410_DCLKCON_DCLK0EN, - .enable = s3c24xx_dclk_enable, - .set_parent = s3c24xx_dclk_setparent, }; struct clk s3c24xx_clkout0 = { .name = "clkout0", .id = -1, - .set_parent = s3c24xx_clkout_setparent, }; struct clk s3c24xx_clkout1 = { .name = "clkout1", .id = -1, - .set_parent = s3c24xx_clkout_setparent, }; struct clk s3c24xx_uclk = { @@ -427,7 +262,7 @@ struct clk s3c24xx_uclk = { }; -/* standard clock definitions */ +/* clock definitions */ static struct clk init_clocks[] = { { @@ -539,7 +374,7 @@ int s3c24xx_register_clock(struct clk *clk) /* if this is a standard clock, set the usage state */ - if (clk->ctrlbit && clk->enable == s3c24xx_clkcon_enable) { + if (clk->ctrlbit) { unsigned long clkcon = __raw_readl(S3C2410_CLKCON); clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0; @@ -561,7 +396,6 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, unsigned long hclk, unsigned long pclk) { - unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW); struct clk *clkp = init_clocks; int ptr; @@ -572,7 +406,6 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, /* initialise the main system clocks */ clk_xtal.rate = xtal; - clk_upll.rate = s3c2410_get_pll(upllcon, xtal); clk_h.rate = hclk; clk_p.rate = pclk; @@ -606,9 +439,6 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, if (s3c24xx_register_clock(&clk_xtal) < 0) printk(KERN_ERR "failed to register master xtal\n"); - if (s3c24xx_register_clock(&clk_upll) < 0) - printk(KERN_ERR "failed to register upll clock\n"); - if (s3c24xx_register_clock(&clk_f) < 0) printk(KERN_ERR "failed to register cpu fclk\n"); @@ -618,10 +448,6 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, if (s3c24xx_register_clock(&clk_p) < 0) printk(KERN_ERR "failed to register cpu pclk\n"); - - if (s3c24xx_register_clock(&clk_usb_bus) < 0) - printk(KERN_ERR "failed to register usb bus clock\n"); - /* register clocks from clock array */ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h index 01bb458bf..eb5c95d1e 100644 --- a/arch/arm/mach-s3c2410/clock.h +++ b/arch/arm/mach-s3c2410/clock.h @@ -19,11 +19,7 @@ struct clk { int usage; unsigned long rate; unsigned long ctrlbit; - int (*enable)(struct clk *, int enable); - int (*set_rate)(struct clk *c, unsigned long rate); - unsigned long (*round_rate)(struct clk *c, unsigned long rate); - int (*set_parent)(struct clk *c, struct clk *parent); }; /* other clocks which may be registered by board support */ @@ -34,15 +30,11 @@ extern struct clk s3c24xx_clkout0; extern struct clk s3c24xx_clkout1; extern struct clk s3c24xx_uclk; -extern struct clk clk_usb_bus; - /* exports for arch/arm/mach-s3c2410 * * Please DO NOT use these outside of arch/arm/mach-s3c2410 */ -extern struct mutex clocks_mutex; - extern int s3c24xx_clkcon_enable(struct clk *clk, int enable); extern int s3c24xx_register_clock(struct clk *clk); diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c deleted file mode 100644 index c940890f6..000000000 --- a/arch/arm/mach-s3c2410/common-smdk.c +++ /dev/null @@ -1,135 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/common-smdk.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * Common code for SMDK2410 and SMDK2440 boards - * - * http://www.fluff.org/ben/smdk2440/ - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include "common-smdk.h" -#include "devs.h" -#include "pm.h" - -/* NAND parititon from 2.4.18-swl5 */ - -static struct mtd_partition smdk_default_nand_part[] = { - [0] = { - .name = "Boot Agent", - .size = SZ_16K, - .offset = 0, - }, - [1] = { - .name = "S3C2410 flash partition 1", - .offset = 0, - .size = SZ_2M, - }, - [2] = { - .name = "S3C2410 flash partition 2", - .offset = SZ_4M, - .size = SZ_4M, - }, - [3] = { - .name = "S3C2410 flash partition 3", - .offset = SZ_8M, - .size = SZ_2M, - }, - [4] = { - .name = "S3C2410 flash partition 4", - .offset = SZ_1M * 10, - .size = SZ_4M, - }, - [5] = { - .name = "S3C2410 flash partition 5", - .offset = SZ_1M * 14, - .size = SZ_1M * 10, - }, - [6] = { - .name = "S3C2410 flash partition 6", - .offset = SZ_1M * 24, - .size = SZ_1M * 24, - }, - [7] = { - .name = "S3C2410 flash partition 7", - .offset = SZ_1M * 48, - .size = SZ_16M, - } -}; - -static struct s3c2410_nand_set smdk_nand_sets[] = { - [0] = { - .name = "NAND", - .nr_chips = 1, - .nr_partitions = ARRAY_SIZE(smdk_default_nand_part), - .partitions = smdk_default_nand_part, - }, -}; - -/* choose a set of timings which should suit most 512Mbit - * chips and beyond. -*/ - -static struct s3c2410_platform_nand smdk_nand_info = { - .tacls = 20, - .twrph0 = 60, - .twrph1 = 20, - .nr_sets = ARRAY_SIZE(smdk_nand_sets), - .sets = smdk_nand_sets, -}; - -/* devices we initialise */ - -static struct platform_device __initdata *smdk_devs[] = { - &s3c_device_nand, -}; - -void __init smdk_machine_init(void) -{ - /* Configure the LEDs (even if we have no LED support)*/ - - s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP); - s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP); - s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP); - s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP); - - s3c2410_gpio_setpin(S3C2410_GPF4, 1); - s3c2410_gpio_setpin(S3C2410_GPF5, 1); - s3c2410_gpio_setpin(S3C2410_GPF6, 1); - s3c2410_gpio_setpin(S3C2410_GPF7, 1); - - s3c_device_nand.dev.platform_data = &smdk_nand_info; - - platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs)); - - s3c2410_pm_init(); -} diff --git a/arch/arm/mach-s3c2410/common-smdk.h b/arch/arm/mach-s3c2410/common-smdk.h deleted file mode 100644 index 0e3a3be33..000000000 --- a/arch/arm/mach-s3c2410/common-smdk.h +++ /dev/null @@ -1,15 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/common-smdk.h - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * Common code for SMDK2410 and SMDK2440 boards - * - * http://www.fluff.org/ben/smdk2440/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -extern void smdk_machine_init(void); diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c index 70c34fcf7..00a379334 100644 --- a/arch/arm/mach-s3c2410/cpu.c +++ b/arch/arm/mach-s3c2410/cpu.c @@ -146,7 +146,7 @@ void s3c24xx_set_board(struct s3c24xx_board *b) board = b; if (b->clocks_count != 0) { - struct clk **ptr = b->clocks; + struct clk **ptr = b->clocks;; for (i = b->clocks_count; i > 0; i--, ptr++) s3c24xx_register_clock(*ptr); diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c index cc97fbf66..3e327b8e4 100644 --- a/arch/arm/mach-s3c2410/mach-anubis.c +++ b/arch/arm/mach-s3c2410/mach-anubis.c @@ -232,8 +232,8 @@ static void anubis_nand_select(struct s3c2410_nand_set *set, int slot) static struct s3c2410_platform_nand anubis_nand_info = { .tacls = 25, - .twrph0 = 55, - .twrph1 = 40, + .twrph0 = 80, + .twrph1 = 80, .nr_sets = ARRAY_SIZE(anubis_nand_sets), .sets = anubis_nand_sets, .select_chip = anubis_nand_select, diff --git a/arch/arm/mach-s3c2410/mach-osiris.c b/arch/arm/mach-s3c2410/mach-osiris.c deleted file mode 100644 index ae0787557..000000000 --- a/arch/arm/mach-s3c2410/mach-osiris.c +++ /dev/null @@ -1,294 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/mach-osiris.c - * - * Copyright (c) 2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "clock.h" -#include "devs.h" -#include "cpu.h" - -/* onboard perihpheral map */ - -static struct map_desc osiris_iodesc[] __initdata = { - /* ISA IO areas (may be over-written later) */ - - { - .virtual = (u32)S3C24XX_VA_ISA_BYTE, - .pfn = __phys_to_pfn(S3C2410_CS5), - .length = SZ_16M, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_WORD, - .pfn = __phys_to_pfn(S3C2410_CS5), - .length = SZ_16M, - .type = MT_DEVICE, - }, - - /* CPLD control registers */ - - { - .virtual = (u32)OSIRIS_VA_CTRL1, - .pfn = __phys_to_pfn(OSIRIS_PA_CTRL1), - .length = SZ_16K, - .type = MT_DEVICE - }, { - .virtual = (u32)OSIRIS_VA_CTRL2, - .pfn = __phys_to_pfn(OSIRIS_PA_CTRL2), - .length = SZ_16K, - .type = MT_DEVICE - }, -}; - -#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK -#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB -#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE - -static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = { - [0] = { - .name = "uclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "pclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0. - } -}; - - -static struct s3c2410_uartcfg osiris_uartcfgs[] = { - [0] = { - .hwport = 0, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, - .clocks = osiris_serial_clocks, - .clocks_size = ARRAY_SIZE(osiris_serial_clocks) - }, - [1] = { - .hwport = 2, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, - .clocks = osiris_serial_clocks, - .clocks_size = ARRAY_SIZE(osiris_serial_clocks) - }, -}; - -/* NAND Flash on Osiris board */ - -static int external_map[] = { 2 }; -static int chip0_map[] = { 0 }; -static int chip1_map[] = { 1 }; - -static struct mtd_partition osiris_default_nand_part[] = { - [0] = { - .name = "Boot Agent", - .size = SZ_16K, - .offset = 0 - }, - [1] = { - .name = "/boot", - .size = SZ_4M - SZ_16K, - .offset = SZ_16K, - }, - [2] = { - .name = "user1", - .offset = SZ_4M, - .size = SZ_32M - SZ_4M, - }, - [3] = { - .name = "user2", - .offset = SZ_32M, - .size = MTDPART_SIZ_FULL, - } -}; - -/* the Osiris has 3 selectable slots for nand-flash, the two - * on-board chip areas, as well as the external slot. - * - * Note, there is no current hot-plug support for the External - * socket. -*/ - -static struct s3c2410_nand_set osiris_nand_sets[] = { - [1] = { - .name = "External", - .nr_chips = 1, - .nr_map = external_map, - .nr_partitions = ARRAY_SIZE(osiris_default_nand_part), - .partitions = osiris_default_nand_part - }, - [0] = { - .name = "chip0", - .nr_chips = 1, - .nr_map = chip0_map, - .nr_partitions = ARRAY_SIZE(osiris_default_nand_part), - .partitions = osiris_default_nand_part - }, - [2] = { - .name = "chip1", - .nr_chips = 1, - .nr_map = chip1_map, - .nr_partitions = ARRAY_SIZE(osiris_default_nand_part), - .partitions = osiris_default_nand_part - }, -}; - -static void osiris_nand_select(struct s3c2410_nand_set *set, int slot) -{ - unsigned int tmp; - - slot = set->nr_map[slot] & 3; - - pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n", - slot, set, set->nr_map); - - tmp = __raw_readb(OSIRIS_VA_CTRL1); - tmp &= ~OSIRIS_CTRL1_NANDSEL; - tmp |= slot; - - pr_debug("osiris_nand: ctrl1 now %02x\n", tmp); - - __raw_writeb(tmp, OSIRIS_VA_CTRL1); -} - -static struct s3c2410_platform_nand osiris_nand_info = { - .tacls = 25, - .twrph0 = 60, - .twrph1 = 60, - .nr_sets = ARRAY_SIZE(osiris_nand_sets), - .sets = osiris_nand_sets, - .select_chip = osiris_nand_select, -}; - -/* PCMCIA control and configuration */ - -static struct resource osiris_pcmcia_resource[] = { - [0] = { - .start = 0x0f000000, - .end = 0x0f100000, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 0x0c000000, - .end = 0x0c100000, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device osiris_pcmcia = { - .name = "osiris-pcmcia", - .id = -1, - .num_resources = ARRAY_SIZE(osiris_pcmcia_resource), - .resource = osiris_pcmcia_resource, -}; - -/* Standard Osiris devices */ - -static struct platform_device *osiris_devices[] __initdata = { - &s3c_device_i2c, - &s3c_device_nand, - &osiris_pcmcia, -}; - -static struct clk *osiris_clocks[] = { - &s3c24xx_dclk0, - &s3c24xx_dclk1, - &s3c24xx_clkout0, - &s3c24xx_clkout1, - &s3c24xx_uclk, -}; - -static struct s3c24xx_board osiris_board __initdata = { - .devices = osiris_devices, - .devices_count = ARRAY_SIZE(osiris_devices), - .clocks = osiris_clocks, - .clocks_count = ARRAY_SIZE(osiris_clocks) -}; - -static void __init osiris_map_io(void) -{ - unsigned long flags; - - /* initialise the clocks */ - - s3c24xx_dclk0.parent = NULL; - s3c24xx_dclk0.rate = 12*1000*1000; - - s3c24xx_dclk1.parent = NULL; - s3c24xx_dclk1.rate = 24*1000*1000; - - s3c24xx_clkout0.parent = &s3c24xx_dclk0; - s3c24xx_clkout1.parent = &s3c24xx_dclk1; - - s3c24xx_uclk.parent = &s3c24xx_clkout1; - - s3c_device_nand.dev.platform_data = &osiris_nand_info; - - s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc)); - s3c24xx_init_clocks(0); - s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs)); - s3c24xx_set_board(&osiris_board); - - /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */ - - local_irq_save(flags); - __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON); - local_irq_restore(flags); - - /* write-protect line to the NAND */ - s3c2410_gpio_setpin(S3C2410_GPA0, 1); -} - -MACHINE_START(OSIRIS, "Simtec-OSIRIS") - /* Maintainer: Ben Dooks */ - .phys_io = S3C2410_PA_UART, - .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, - .boot_params = S3C2410_SDRAM_PA + 0x100, - .map_io = osiris_map_io, - .init_irq = s3c24xx_init_irq, - .timer = &s3c24xx_timer, -MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index 306afc1d7..0260ed5ab 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c @@ -32,11 +32,6 @@ #include #include -#include -#include -#include -#include - #include #include #include @@ -51,7 +46,6 @@ #include #include -#include #include #include "clock.h" @@ -176,39 +170,12 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { }, }; -static struct mtd_partition rx3715_nand_part[] = { - [0] = { - .name = "Whole Flash", - .offset = 0, - .size = MTDPART_SIZ_FULL, - .mask_flags = MTD_WRITEABLE, - } -}; - -static struct s3c2410_nand_set rx3715_nand_sets[] = { - [0] = { - .name = "Internal", - .nr_chips = 1, - .nr_partitions = ARRAY_SIZE(rx3715_nand_part), - .partitions = rx3715_nand_part, - }, -}; - -static struct s3c2410_platform_nand rx3715_nand_info = { - .tacls = 25, - .twrph0 = 50, - .twrph1 = 15, - .nr_sets = ARRAY_SIZE(rx3715_nand_sets), - .sets = rx3715_nand_sets, -}; - static struct platform_device *rx3715_devices[] __initdata = { &s3c_device_usb, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c, &s3c_device_iis, - &s3c_device_nand, }; static struct s3c24xx_board rx3715_board __initdata = { @@ -218,8 +185,6 @@ static struct s3c24xx_board rx3715_board __initdata = { static void __init rx3715_map_io(void) { - s3c_device_nand.dev.platform_data = &rx3715_nand_info; - s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); s3c24xx_init_clocks(16934000); s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index 2db932d72..1e76e1fdf 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -28,8 +28,7 @@ * Ben Dooks * * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA - * 20-Sep-2005 BJD Added static to non-exported items - * 01-Apr-2006 BJD Moved init code to common smdk + * 20-Sep-2005 BJD Added static to non-exported items * ***********************************************************************/ @@ -55,8 +54,6 @@ #include "devs.h" #include "cpu.h" -#include "common-smdk.h" - static struct map_desc smdk2410_iodesc[] __initdata = { /* nothing here yet */ }; @@ -110,6 +107,11 @@ static void __init smdk2410_map_io(void) s3c24xx_set_board(&smdk2410_board); } +static void __init smdk2410_init_irq(void) +{ + s3c24xx_init_irq(); +} + MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch * to SMDK2410 */ /* Maintainer: Jonas Dietsche */ @@ -117,8 +119,7 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = smdk2410_map_io, - .init_irq = s3c24xx_init_irq, - .init_machine = smdk_machine_init, + .init_irq = smdk2410_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index 5fffd1d51..f4315721c 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -53,8 +53,7 @@ #include "clock.h" #include "devs.h" #include "cpu.h" - -#include "common-smdk.h" +#include "pm.h" static struct map_desc smdk2440_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ @@ -198,9 +197,21 @@ static void __init smdk2440_map_io(void) static void __init smdk2440_machine_init(void) { + /* Configure the LEDs (even if we have no LED support)*/ + + s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP); + s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP); + s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP); + s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP); + + s3c2410_gpio_setpin(S3C2410_GPF4, 0); + s3c2410_gpio_setpin(S3C2410_GPF5, 0); + s3c2410_gpio_setpin(S3C2410_GPF6, 0); + s3c2410_gpio_setpin(S3C2410_GPF7, 0); + s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); - smdk_machine_init(); + s3c2410_pm_init(); } MACHINE_START(S3C2440, "SMDK2440") diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c index d7a30ed6c..b557a2be8 100644 --- a/arch/arm/mach-s3c2410/s3c2440-clock.c +++ b/arch/arm/mach-s3c2410/s3c2440-clock.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -46,47 +45,10 @@ /* S3C2440 extended clock support */ -static unsigned long s3c2440_camif_upll_round(struct clk *clk, - unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - int div; - - if (rate > parent_rate) - return parent_rate; - - /* note, we remove the +/- 1 calculations for the divisor */ - - div = (parent_rate / rate) / 2; - - if (div < 1) - div = 1; - else if (div > 16) - div = 16; - - return parent_rate / (div * 2); -} - -static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); - - rate = s3c2440_camif_upll_round(clk, rate); - - camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK); - - if (rate != parent_rate) { - camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL; - camdivn |= (((parent_rate / rate) / 2) - 1); - } - - __raw_writel(camdivn, S3C2440_CAMDIVN); - - return 0; -} - -/* Extra S3C2440 clocks */ +static struct clk s3c2440_clk_upll = { + .name = "upll", + .id = -1, +}; static struct clk s3c2440_clk_cam = { .name = "camif", @@ -95,13 +57,6 @@ static struct clk s3c2440_clk_cam = { .ctrlbit = S3C2440_CLKCON_CAMERA, }; -static struct clk s3c2440_clk_cam_upll = { - .name = "camif-upll", - .id = -1, - .set_rate = s3c2440_camif_upll_setrate, - .round_rate = s3c2440_camif_upll_round, -}; - static struct clk s3c2440_clk_ac97 = { .name = "ac97", .id = -1, @@ -111,46 +66,38 @@ static struct clk s3c2440_clk_ac97 = { static int s3c2440_clk_add(struct sys_device *sysdev) { + unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); - unsigned long clkdivn; struct clk *clk_h; struct clk *clk_p; - struct clk *clk_upll; + struct clk *clk_xtal; + + clk_xtal = clk_get(NULL, "xtal"); + if (IS_ERR(clk_xtal)) { + printk(KERN_ERR "S3C2440: Failed to get clk_xtal\n"); + return -EINVAL; + } + + s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal->rate); - printk("S3C2440: Clock Support, DVS %s\n", + printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz, DVS %s\n", + print_mhz(s3c2440_clk_upll.rate), (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off"); clk_p = clk_get(NULL, "pclk"); clk_h = clk_get(NULL, "hclk"); - clk_upll = clk_get(NULL, "upll"); - if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) { + if (IS_ERR(clk_p) || IS_ERR(clk_h)) { printk(KERN_ERR "S3C2440: Failed to get parent clocks\n"); return -EINVAL; } - /* check rate of UPLL, and if it is near 96MHz, then change - * to using half the UPLL rate for the system */ - - if (clk_get_rate(clk_upll) > (94 * MHZ)) { - clk_usb_bus.rate = clk_get_rate(clk_upll) / 2; - - mutex_lock(&clocks_mutex); - - clkdivn = __raw_readl(S3C2410_CLKDIVN); - clkdivn |= S3C2440_CLKDIVN_UCLK; - __raw_writel(clkdivn, S3C2410_CLKDIVN); - - mutex_unlock(&clocks_mutex); - } - s3c2440_clk_cam.parent = clk_h; s3c2440_clk_ac97.parent = clk_p; - s3c2440_clk_cam_upll.parent = clk_upll; s3c24xx_register_clock(&s3c2440_clk_ac97); s3c24xx_register_clock(&s3c2440_clk_cam); - s3c24xx_register_clock(&s3c2440_clk_cam_upll); + s3c24xx_register_clock(&s3c2440_clk_upll); clk_disable(&s3c2440_clk_ac97); clk_disable(&s3c2440_clk_cam); diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S index 73de2eaca..832fb86a0 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c2410/sleep.S @@ -59,7 +59,8 @@ ENTRY(s3c2410_cpu_suspend) mrc p15, 0, r5, c13, c0, 0 @ PID mrc p15, 0, r6, c3, c0, 0 @ Domain ID mrc p15, 0, r7, c2, c0, 0 @ translation table base address - mrc p15, 0, r8, c1, c0, 0 @ control register + mrc p15, 0, r8, c2, c0, 0 @ auxiliary control register + mrc p15, 0, r9, c1, c0, 0 @ control register stmia r0, { r4 - r13 } @@ -164,6 +165,7 @@ ENTRY(s3c2410_cpu_resume) mcr p15, 0, r5, c13, c0, 0 @ PID mcr p15, 0, r6, c3, c0, 0 @ Domain ID mcr p15, 0, r7, c2, c0, 0 @ translation table base + mcr p15, 0, r8, c1, c1, 0 @ auxilliary control #ifdef CONFIG_DEBUG_RESUME mov r3, #'R' @@ -171,7 +173,7 @@ ENTRY(s3c2410_cpu_resume) #endif ldr r2, =resume_with_mmu - mcr p15, 0, r8, c1, c0, 0 @ turn on MMU, etc + mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc nop @ second-to-last before mmu mov pc, r2 @ go back to virtual address diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c index 9d7b799ea..10a2976ae 100644 --- a/arch/arm/mach-s3c2410/time.c +++ b/arch/arm/mach-s3c2410/time.c @@ -142,12 +142,6 @@ static struct irqaction s3c2410_timer_irq = { .handler = s3c2410_timer_interrupt, }; -#define use_tclk1_12() ( \ - machine_is_bast() || \ - machine_is_vr1000() || \ - machine_is_anubis() || \ - machine_is_osiris() ) - /* * Set up timer interrupt, and return the current time in seconds. * @@ -171,7 +165,7 @@ static void s3c2410_timer_setup (void) /* configure the system for whichever machine is in use */ - if (use_tclk1_12()) { + if (machine_is_bast() || machine_is_vr1000() || machine_is_anubis()) { /* timer is at 12MHz, scaler is 1 */ timer_usec_ticks = timer_mask_usec_ticks(1, 12000000); tcnt = 12000000 / HZ; diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index cd67ab1b2..6923316b3 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig @@ -111,7 +111,7 @@ config SA1100_LART bool "LART" help Say Y here if you are using the Linux Advanced Radio Terminal - (also known as the LART). See for + (also known as the LART). See for information on the LART. config SA1100_PLEB diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index e27f15042..e4a4a3e8a 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o +obj-y := generic.o irq.o dma.o time.o obj-m := obj-n := obj- := diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index c58f12ba7..a599bb0d4 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c deleted file mode 100644 index b1e8fd766..000000000 --- a/arch/arm/mach-sa1100/clock.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * linux/arch/arm/mach-sa1100/clock.c - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -struct clk { - struct list_head node; - unsigned long rate; - struct module *owner; - const char *name; - unsigned int enabled; - void (*enable)(void); - void (*disable)(void); -}; - -static LIST_HEAD(clocks); -static DECLARE_MUTEX(clocks_sem); -static DEFINE_SPINLOCK(clocks_lock); - -struct clk *clk_get(struct device *dev, const char *id) -{ - struct clk *p, *clk = ERR_PTR(-ENOENT); - - down(&clocks_sem); - list_for_each_entry(p, &clocks, node) { - if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { - clk = p; - break; - } - } - up(&clocks_sem); - - return clk; -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ - module_put(clk->owner); -} -EXPORT_SYMBOL(clk_put); - -int clk_enable(struct clk *clk) -{ - unsigned long flags; - - spin_lock_irqsave(&clocks_lock, flags); - if (clk->enabled++ == 0) - clk->enable(); - spin_unlock_irqrestore(&clocks_lock, flags); - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ - unsigned long flags; - - WARN_ON(clk->enabled == 0); - - spin_lock_irqsave(&clocks_lock, flags); - if (--clk->enabled == 0) - clk->disable(); - spin_unlock_irqrestore(&clocks_lock, flags); -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - - -static void clk_gpio27_enable(void) -{ - /* - * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: - * (SA-1110 Developer's Manual, section 9.1.2.1) - */ - GAFR |= GPIO_32_768kHz; - GPDR |= GPIO_32_768kHz; - TUCR = TUCR_3_6864MHz; -} - -static void clk_gpio27_disable(void) -{ - TUCR = 0; - GPDR &= ~GPIO_32_768kHz; - GAFR &= ~GPIO_32_768kHz; -} - -static struct clk clk_gpio27 = { - .name = "GPIO27_CLK", - .rate = 3686400, - .enable = clk_gpio27_enable, - .disable = clk_gpio27_disable, -}; - -int clk_register(struct clk *clk) -{ - down(&clocks_sem); - list_add(&clk->node, &clocks); - up(&clocks_sem); - return 0; -} -EXPORT_SYMBOL(clk_register); - -void clk_unregister(struct clk *clk) -{ - down(&clocks_sem); - list_del(&clk->node); - up(&clocks_sem); -} -EXPORT_SYMBOL(clk_unregister); - -static int __init clk_init(void) -{ - clk_register(&clk_gpio27); - return 0; -} -arch_initcall(clk_init); diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 676b5c5b7..6888816a1 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -11,8 +11,7 @@ * published by the Free Software Foundation. * * ChangeLog: - * 2006 Pavel Machek - * 03-06-2004 John Lenz + * 03-06-2004 John Lenz * 06-04-2002 Chris Larson * 04-16-2001 Lineo Japan,Inc. ... */ @@ -41,7 +40,6 @@ #include #include #include -#include #include "generic.h" @@ -68,95 +66,6 @@ struct platform_device colliescoop_device = { .resource = collie_scoop_resources, }; -static struct scoop_pcmcia_dev collie_pcmcia_scoop[] = { -{ - .dev = &colliescoop_device.dev, - .irq = COLLIE_IRQ_GPIO_CF_IRQ, - .cd_irq = COLLIE_IRQ_GPIO_CF_CD, - .cd_irq_str = "PCMCIA0 CD", -}, -}; - -static struct scoop_pcmcia_config collie_pcmcia_config = { - .devs = &collie_pcmcia_scoop[0], - .num_devs = 1, -}; - - -static struct mcp_plat_data collie_mcp_data = { - .mccr0 = MCCR0_ADM, - .sclk_rate = 11981000, -}; - -#ifdef CONFIG_SHARP_LOCOMO -/* - * low-level UART features. - */ -static struct locomo_dev *uart_dev = NULL; - -static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) -{ - if (!uart_dev) return; - - if (mctrl & TIOCM_RTS) - locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0); - else - locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1); - - if (mctrl & TIOCM_DTR) - locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0); - else - locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1); -} - -static u_int collie_uart_get_mctrl(struct uart_port *port) -{ - int ret = TIOCM_CD; - unsigned int r; - if (!uart_dev) return ret; - - r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); - if (r & LOCOMO_GPIO_CTS) - ret |= TIOCM_CTS; - if (r & LOCOMO_GPIO_DSR) - ret |= TIOCM_DSR; - - return ret; -} - -static struct sa1100_port_fns collie_port_fns __initdata = { - .set_mctrl = collie_uart_set_mctrl, - .get_mctrl = collie_uart_get_mctrl, -}; - -static int collie_uart_probe(struct locomo_dev *dev) -{ - uart_dev = dev; - return 0; -} - -static int collie_uart_remove(struct locomo_dev *dev) -{ - uart_dev = NULL; - return 0; -} - -static struct locomo_driver collie_uart_driver = { - .drv = { - .name = "collie_uart", - }, - .devid = LOCOMO_DEVID_UART, - .probe = collie_uart_probe, - .remove = collie_uart_remove, -}; - -static int __init collie_uart_init(void) { - return locomo_driver_register(&collie_uart_driver); -} -device_initcall(collie_uart_init); - -#endif - static struct resource locomo_resources[] = { [0] = { @@ -250,8 +159,6 @@ static void __init collie_init(void) GPDR |= GPIO_32_768kHz; TUCR = TUCR_32_768kHz; - platform_scoop_config = &collie_pcmcia_config; - ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) { printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); @@ -259,7 +166,6 @@ static void __init collie_init(void) sa11x0_set_flash_data(&collie_flash_data, collie_flash_resources, ARRAY_SIZE(collie_flash_resources)); - sa11x0_set_mcp_data(&collie_mcp_data); sharpsl_save_param(); } @@ -282,12 +188,6 @@ static void __init collie_map_io(void) { sa1100_map_io(); iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc)); - -#ifdef CONFIG_SHARP_LOCOMO - sa1100_register_uart_fns(&collie_port_fns); -#endif - sa1100_register_uart(0, 3); - sa1100_register_uart(1, 1); } MACHINE_START(COLLIE, "Sharp-Collie") diff --git a/arch/arm/mach-sa1100/collie_pm.c b/arch/arm/mach-sa1100/collie_pm.c deleted file mode 100644 index 696d7d29c..000000000 --- a/arch/arm/mach-sa1100/collie_pm.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Based on spitz_pm.c and sharp code. - * - * Copyright (C) 2001 SHARP - * Copyright 2005 Pavel Machek - * - * Distribute under GPLv2. - * - * Li-ion batteries are angry beasts, and they like to explode. This driver is not finished, - * and sometimes charges them when it should not. If it makes angry lithium to come your way... - * ...well, you have been warned. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../drivers/mfd/ucb1x00.h" - -static struct ucb1x00 *ucb; -static int ad_revise; - -#define ADCtoPower(x) ((330 * x * 2) / 1024) - -static void collie_charger_init(void) -{ - int err; - - if (sharpsl_param.adadj != -1) { - ad_revise = sharpsl_param.adadj; - } - - /* Register interrupt handler. */ - if ((err = request_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr, SA_INTERRUPT, - "ACIN", sharpsl_ac_isr))) { - printk("Could not get irq %d.\n", COLLIE_IRQ_GPIO_AC_IN); - return; - } - if ((err = request_irq(COLLIE_IRQ_GPIO_CO, sharpsl_chrg_full_isr, SA_INTERRUPT, - "CO", sharpsl_chrg_full_isr))) { - free_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr); - printk("Could not get irq %d.\n", COLLIE_IRQ_GPIO_CO); - return; - } - - ucb1x00_io_set_dir(ucb, 0, COLLIE_TC35143_GPIO_MBAT_ON | COLLIE_TC35143_GPIO_TMP_ON | - COLLIE_TC35143_GPIO_BBAT_ON); - return; -} - -static void collie_measure_temp(int on) -{ - if (on) - ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_TMP_ON, 0); - else - ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_TMP_ON); -} - -static void collie_charge(int on) -{ - if (on) { - printk("Should start charger\n"); - } else { - printk("Should stop charger\n"); - } -#ifdef I_AM_SURE - - /* Zaurus seems to contain LTC1731 ; it should know when to - * stop charging itself, so setting charge on should be - * relatively harmless (as long as it is not done too often). - */ -#define CF_BUF_CTRL_BASE 0xF0800000 -#define SCOOP_REG(adr) (*(volatile unsigned short*)(CF_BUF_CTRL_BASE+(adr))) -#define SCOOP_REG_GPWR SCOOP_REG(SCOOP_GPWR) - - if (on) { - set_scoop_gpio(&colliescoop_device.dev, COLLIE_SCP_CHARGE_ON); - } else { - reset_scoop_gpio(&colliescoop_device.dev, COLLIE_SCP_CHARGE_ON); - } -#endif -} - -static void collie_discharge(int on) -{ -} - -static void collie_discharge1(int on) -{ -} - -static void collie_presuspend(void) -{ -} - -static void collie_postsuspend(void) -{ -} - -static int collie_should_wakeup(unsigned int resume_on_alarm) -{ - return 0; -} - -static unsigned long collie_charger_wakeup(void) -{ - return 0; -} - -int collie_read_backup_battery(void) -{ - int voltage; - - ucb1x00_adc_enable(ucb); - - /* Gives 75..130 */ - ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_BBAT_ON, 0); - voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_SYNC); - - ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_BBAT_ON); - ucb1x00_adc_disable(ucb); - - printk("Backup battery = %d(%d)\n", ADCtoPower(voltage), voltage); - - return ADCtoPower(voltage); -} - -int collie_read_main_battery(void) -{ - int voltage, voltage_rev, voltage_volts; - - ucb1x00_adc_enable(ucb); - ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_BBAT_ON); - ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_MBAT_ON, 0); - /* gives values 160..255 with battery removed... and - 145..255 with battery inserted. (on AC), goes as low as - 80 on DC. */ - voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_SYNC); - - ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_MBAT_ON); - ucb1x00_adc_disable(ucb); - - voltage_rev = voltage + ((ad_revise * voltage) / 652); - voltage_volts = ADCtoPower(voltage_rev); - - printk("Main battery = %d(%d)\n", voltage_volts, voltage); - - if (voltage != -1) - return voltage_volts; - else - return voltage; -} - -int collie_read_temp(void) -{ - int voltage; - - /* According to Sharp, temp must be > 973, main battery must be < 465, - FIXME: sharpsl_pm.c has both conditions negated? FIXME: values - are way out of range? */ - - ucb1x00_adc_enable(ucb); - ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_TMP_ON, 0); - /* >1010 = battery removed, 460 = 22C ?, higer = lower temp ? */ - voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD0, UCB_SYNC); - ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_TMP_ON); - ucb1x00_adc_disable(ucb); - - printk("Battery temp = %d\n", voltage); - return voltage; -} - -static unsigned long read_devdata(int which) -{ - switch (which) { - case SHARPSL_BATT_VOLT: - return collie_read_main_battery(); - case SHARPSL_BATT_TEMP: - return collie_read_temp(); - case SHARPSL_ACIN_VOLT: - return 0x1; - case SHARPSL_STATUS_ACIN: { - int ret = GPLR & COLLIE_GPIO_AC_IN; - printk("AC status = %d\n", ret); - return ret; - } - case SHARPSL_STATUS_FATAL: { - int ret = GPLR & COLLIE_GPIO_MAIN_BAT_LOW; - printk("Fatal bat = %d\n", ret); - return ret; - } - default: - return ~0; - } -} - -struct battery_thresh collie_battery_levels[] = { - { 368, 100}, - { 358, 25}, - { 356, 5}, - { 0, 0}, -}; - -struct sharpsl_charger_machinfo collie_pm_machinfo = { - .init = collie_charger_init, - .read_devdata = read_devdata, - .discharge = collie_discharge, - .discharge1 = collie_discharge1, - .charge = collie_charge, - .measure_temp = collie_measure_temp, - .presuspend = collie_presuspend, - .postsuspend = collie_postsuspend, - .charger_wakeup = collie_charger_wakeup, - .should_wakeup = collie_should_wakeup, - .bat_levels = 3, - .bat_levels_noac = collie_battery_levels, - .bat_levels_acin = collie_battery_levels, - .status_high_acin = 368, - .status_low_acin = 358, - .status_high_noac = 368, - .status_low_noac = 358, -}; - -static int __init collie_pm_ucb_add(struct ucb1x00_dev *pdev) -{ - sharpsl_pm.machinfo = &collie_pm_machinfo; - ucb = pdev->ucb; - return 0; -} - -static struct ucb1x00_driver collie_pm_ucb_driver = { - .add = collie_pm_ucb_add, -}; - -static struct platform_device *collie_pm_device; - -static int __init collie_pm_init(void) -{ - int ret; - - collie_pm_device = platform_device_alloc("sharpsl-pm", -1); - if (!collie_pm_device) - return -ENOMEM; - - collie_pm_device->dev.platform_data = &collie_pm_machinfo; - ret = platform_device_add(collie_pm_device); - - if (ret) - platform_device_put(collie_pm_device); - - if (!ret) - ret = ucb1x00_register_driver(&collie_pm_ucb_driver); - - return ret; -} - -static void __exit collie_pm_exit(void) -{ - ucb1x00_unregister_driver(&collie_pm_ucb_driver); - platform_device_unregister(collie_pm_device); -} - -module_init(collie_pm_init); -module_exit(collie_pm_exit); diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c index d68630b74..6435b2e48 100644 --- a/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/arch/arm/mach-sa1100/cpu-sa1100.c @@ -11,7 +11,7 @@ * linux-2.4.5-rmk1 * * This software has been developed while working on the LART - * computing board (http://www.lartmaker.nl/), which is + * computing board (http://www.lart.tudelft.nl/), which is * sponsored by the Mobile Multi-media Communications * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications * (http://www.ubicom.tudelft.nl/) projects. diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 9ea71551f..2abdc419e 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -324,11 +324,6 @@ void sa11x0_set_irda_data(struct irda_platform_data *irda) sa11x0ir_device.dev.platform_data = irda; } -static struct platform_device sa11x0rtc_device = { - .name = "sa1100-rtc", - .id = -1, -}; - static struct platform_device *sa11x0_devices[] __initdata = { &sa11x0udc_device, &sa11x0uart1_device, @@ -338,7 +333,6 @@ static struct platform_device *sa11x0_devices[] __initdata = { &sa11x0pcmcia_device, &sa11x0fb_device, &sa11x0mtd_device, - &sa11x0rtc_device, }; static int __init sa1100_init(void) diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index b3a560241..c131a5201 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c @@ -199,26 +199,10 @@ static void sa1100_unmask_irq(unsigned int irq) ICMR |= (1 << irq); } -/* - * Apart form GPIOs, only the RTC alarm can be a wakeup event. - */ -static int sa1100_set_wake(unsigned int irq, unsigned int on) -{ - if (irq == IRQ_RTCAlrm) { - if (on) - PWER |= PWER_RTC; - else - PWER &= ~PWER_RTC; - return 0; - } - return -EINVAL; -} - static struct irqchip sa1100_normal_chip = { .ack = sa1100_mask_irq, .mask = sa1100_mask_irq, .unmask = sa1100_unmask_irq, - .set_wake = sa1100_set_wake, }; static struct resource irq_resource = { diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index af6d2775c..9e02bc371 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -59,14 +59,6 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg if (irr & (IRR_ETHERNET | IRR_USAR)) { desc->chip->mask(irq); - /* - * Ack the interrupt now to prevent re-entering - * this neponset handler. Again, this is safe - * since we'll check the IRR register prior to - * leaving. - */ - desc->chip->ack(irq); - if (irr & IRR_ETHERNET) { d = irq_desc + IRQ_NEPONSET_SMC9196; desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs); diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index cebd48a3d..9ebbe808b 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -112,9 +112,10 @@ void __init versatile_init_irq(void) { unsigned int i; - vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0); + vic_init(VA_VIC_BASE, ~(1 << 31)); - set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq); + set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq); + enable_irq(IRQ_VICSOURCE31); /* Do second interrupt controller */ writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c55b739e1..3b79d0e23 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -62,7 +62,7 @@ config CPU_ARM720T # ARM920T config CPU_ARM920T bool "Support ARM920T processor" if !ARCH_S3C2410 - depends on ARCH_EP93XX || ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 + depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 default y if ARCH_S3C2410 || ARCH_AT91RM9200 select CPU_32v4 select CPU_ABRT_EV4T @@ -239,17 +239,6 @@ config CPU_XSCALE select CPU_CACHE_VIVT select CPU_TLB_V4WBI -# XScale Core Version 3 -config CPU_XSC3 - bool - depends on ARCH_IXP23XX - default y - select CPU_32v5 - select CPU_ABRT_EV5T - select CPU_CACHE_VIVT - select CPU_TLB_V4WBI - select IO_36 - # ARMv6 config CPU_V6 bool "Support ARM V6 processor" @@ -277,18 +266,12 @@ config CPU_32v6K # This defines the compiler instruction set which depends on the machine type. config CPU_32v3 bool - select TLS_REG_EMUL if SMP - select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v4 bool - select TLS_REG_EMUL if SMP - select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v5 bool - select TLS_REG_EMUL if SMP - select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v6 bool @@ -372,17 +355,11 @@ config CPU_TLB_V4WBI config CPU_TLB_V6 bool -# -# CPU supports 36-bit I/O -# -config IO_36 - bool - comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 + depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_V6 default y help Say Y if you want to include kernel support for running user space @@ -440,6 +417,7 @@ config CPU_BPREDICT_DISABLE config TLS_REG_EMUL bool + default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3) help An SMP system using a pre-ARMv6 processor (there are apparently a few prototypes like that in existence) and therefore access to @@ -458,6 +436,7 @@ config HAS_TLS_REG config NEEDS_SYSCALL_FOR_CMPXCHG bool + default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3) help SMP on a pre-ARMv6 processor? Well OK then. Forget about fast user space cmpxchg support. diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 07a538505..ffe73ba2b 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o -obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o @@ -52,5 +51,4 @@ obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o obj-$(CONFIG_CPU_SA110) += proc-sa110.o obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o -obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o obj-$(CONFIG_CPU_V6) += proc-v6.o diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index 54e3c5bb5..5c4055b62 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include "proc-macros.S" @@ -46,11 +46,6 @@ */ #define CACHE_DLIMIT (CACHE_DSIZE * 4) - .data -flush_base: - .long FLUSH_BASE - .text - /* * flush_user_cache_all() * @@ -68,21 +63,11 @@ ENTRY(v4wb_flush_kern_cache_all) mov ip, #0 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache __flush_whole_cache: - ldr r3, =flush_base - ldr r1, [r3, #0] - eor r1, r1, #CACHE_DSIZE - str r1, [r3, #0] - add r2, r1, #CACHE_DSIZE -1: ldr r3, [r1], #32 - cmp r1, r2 - blo 1b -#ifdef FLUSH_BASE_MINICACHE - add r2, r2, #FLUSH_BASE_MINICACHE - FLUSH_BASE - sub r1, r2, #512 @ only 512 bytes -1: ldr r3, [r1], #32 - cmp r1, r2 + mov r0, #FLUSH_BASE + add r1, r0, #CACHE_DSIZE +1: ldr r2, [r0], #32 + cmp r0, r1 blo 1b -#endif mcr p15, 0, ip, c7, c10, 4 @ drain write buffer mov pc, lr @@ -97,7 +82,6 @@ __flush_whole_cache: * - flags - vma_area_struct flags describing address space */ ENTRY(v4wb_flush_user_cache_range) - mov ip, #0 sub r3, r1, r0 @ calculate total size tst r2, #VM_EXEC @ executable region? mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 50e6b6bfb..c2ee18d20 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -224,8 +223,6 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, pte = consistent_pte[idx] + off; c->vm_pages = page; - split_page(page, order); - /* * Set the "dma handle" */ @@ -234,6 +231,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, do { BUG_ON(!pte_none(*pte)); + set_page_count(page, 1); /* * x86 does not mark the pages reserved... */ @@ -252,6 +250,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, * Free the otherwise unused pages. */ while (page < end) { + set_page_count(page, 1); __free_page(page); page++; } @@ -273,17 +272,6 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) { - if (arch_is_coherent()) { - void *virt; - - virt = kmalloc(size, gfp); - if (!virt) - return NULL; - *handle = virt_to_dma(dev, virt); - - return virt; - } - return __dma_alloc(dev, size, handle, gfp, pgprot_noncached(pgprot_kernel)); } @@ -362,11 +350,6 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr WARN_ON(irqs_disabled()); - if (arch_is_coherent()) { - kfree(cpu_addr); - return; - } - size = PAGE_ALIGN(size); spin_lock_irqsave(&consistent_lock, flags); diff --git a/arch/arm/mm/copypage-xsc3.S b/arch/arm/mm/copypage-xsc3.S deleted file mode 100644 index 9a2cb4332..000000000 --- a/arch/arm/mm/copypage-xsc3.S +++ /dev/null @@ -1,97 +0,0 @@ -/* - * linux/arch/arm/lib/copypage-xsc3.S - * - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Adapted for 3rd gen XScale core, no more mini-dcache - * Author: Matt Gilbert (matthew.m.gilbert@intel.com) - */ - -#include -#include -#include - -/* - * General note: - * We don't really want write-allocate cache behaviour for these functions - * since that will just eat through 8K of the cache. - */ - - .text - .align 5 -/* - * XSC3 optimised copy_user_page - * r0 = destination - * r1 = source - * r2 = virtual user address of ultimate destination page - * - * The source page may have some clean entries in the cache already, but we - * can safely ignore them - break_cow() will flush them out of the cache - * if we eventually end up using our copied page. - * - */ -ENTRY(xsc3_mc_copy_user_page) - stmfd sp!, {r4, r5, lr} - mov lr, #PAGE_SZ/64-1 - - pld [r1, #0] - pld [r1, #32] -1: pld [r1, #64] - pld [r1, #96] - -2: ldrd r2, [r1], #8 - mov ip, r0 - ldrd r4, [r1], #8 - mcr p15, 0, ip, c7, c6, 1 @ invalidate - strd r2, [r0], #8 - ldrd r2, [r1], #8 - strd r4, [r0], #8 - ldrd r4, [r1], #8 - strd r2, [r0], #8 - strd r4, [r0], #8 - ldrd r2, [r1], #8 - mov ip, r0 - ldrd r4, [r1], #8 - mcr p15, 0, ip, c7, c6, 1 @ invalidate - strd r2, [r0], #8 - ldrd r2, [r1], #8 - subs lr, lr, #1 - strd r4, [r0], #8 - ldrd r4, [r1], #8 - strd r2, [r0], #8 - strd r4, [r0], #8 - bgt 1b - beq 2b - - ldmfd sp!, {r4, r5, pc} - - .align 5 -/* - * XScale optimised clear_user_page - * r0 = destination - * r1 = virtual user address of ultimate destination page - */ -ENTRY(xsc3_mc_clear_user_page) - mov r1, #PAGE_SZ/32 - mov r2, #0 - mov r3, #0 -1: mcr p15, 0, r0, c7, c6, 1 @ invalidate line - strd r2, [r0], #8 - strd r2, [r0], #8 - strd r2, [r0], #8 - strd r2, [r0], #8 - subs r1, r1, #1 - bne 1b - mov pc, lr - - __INITDATA - - .type xsc3_mc_user_fns, #object -ENTRY(xsc3_mc_user_fns) - .long xsc3_mc_clear_user_page - .long xsc3_mc_copy_user_page - .size xsc3_mc_user_fns, . - xsc3_mc_user_fns diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 9ea1f87a7..8b276ee38 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -19,8 +19,8 @@ #include #include +#include #include -#include #include #include @@ -456,14 +456,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc) #ifdef FLUSH_BASE map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); map.virtual = FLUSH_BASE; - map.length = SZ_1M; + map.length = PGDIR_SIZE; map.type = MT_CACHECLEAN; create_mapping(&map); #endif #ifdef FLUSH_BASE_MINICACHE - map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + PGDIR_SIZE); map.virtual = FLUSH_BASE_MINICACHE; - map.length = SZ_1M; + map.length = PGDIR_SIZE; map.type = MT_MINICLEAN; create_mapping(&map); #endif @@ -531,7 +531,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s) for (; addr < end; addr += PAGE_SIZE) { struct page *page = virt_to_page(addr); ClearPageReserved(page); - init_page_count(page); + set_page_count(page, 1); free_page(addr); totalram_pages++; } diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index c1f7180c7..da9b35974 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -141,7 +142,7 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, return NULL; addr = (unsigned long)area->addr; if (remap_area_pages(addr, pfn, size, flags)) { - vunmap((void *)addr); + vfree((void *)addr); return NULL; } return (void __iomem *) (offset + (char *)addr); @@ -173,7 +174,7 @@ EXPORT_SYMBOL(__ioremap); void __iounmap(void __iomem *addr) { - vunmap((void *)(PAGE_MASK & (unsigned long)addr)); + vfree((void *) (PAGE_MASK & (unsigned long) addr)); } EXPORT_SYMBOL(__iounmap); diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 95273de4f..ef8d30a18 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -376,7 +376,7 @@ void __init build_mem_type_table(void) ecc_mask = 0; } - if (cpu_arch <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) { + if (cpu_arch <= CPU_ARCH_ARMv5TEJ) { for (i = 0; i < ARRAY_SIZE(mem_types); i++) { if (mem_types[i].prot_l1) mem_types[i].prot_l1 |= PMD_BIT4; @@ -388,17 +388,6 @@ void __init build_mem_type_table(void) cp = &cache_policies[cachepolicy]; kern_pgprot = user_pgprot = cp->pte; - /* - * Enable CPU-specific coherency if supported. - * (Only available on XSC3 at the moment.) - */ - if (arch_is_coherent()) { - if (cpu_is_xsc3()) { - mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; - } - } - /* * ARMv6 and above have extended page tables. */ @@ -568,8 +557,7 @@ void __init create_mapping(struct map_desc *md) * supersections are only allocated for domain 0 regardless * of the actual domain assignments in use. */ - if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) - && domain == 0) { + if (cpu_architecture() >= CPU_ARCH_ARMv6 && domain == 0) { /* * Align to supersection boundary if !high pages. * High pages have already been checked for proper @@ -631,7 +619,7 @@ void setup_mm_for_reboot(char mode) pgd = init_mm.pgd; base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; - if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) + if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ) base_pmdval |= PMD_BIT4; for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) { diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 959588884..82ec954e4 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -29,10 +29,10 @@ #include #include #include -#include #include #include #include +#include /* * This is the maximum size of an area which will be invalidated diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index be6d081ff..7375fe930 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -29,10 +29,10 @@ #include #include #include -#include #include #include #include +#include /* * This is the maximum size of an area which will be invalidated diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S index f778545d5..6ca639094 100644 --- a/arch/arm/mm/proc-arm1022.S +++ b/arch/arm/mm/proc-arm1022.S @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S index 148c111fd..10317e4f5 100644 --- a/arch/arm/mm/proc-arm1026.S +++ b/arch/arm/mm/proc-arm1026.S @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S index 540359b47..8e7e1e70a 100644 --- a/arch/arm/mm/proc-arm6_7.S +++ b/arch/arm/mm/proc-arm6_7.S @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index 26f00ee2a..a13e0184d 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -34,10 +34,10 @@ #include #include #include -#include #include #include #include +#include /* * Function: arm720_proc_init (void) diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index a17f79e01..d16513899 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -28,9 +28,9 @@ #include #include #include -#include #include #include +#include #include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S index bbde4a024..23b8ed97f 100644 --- a/arch/arm/mm/proc-arm922.S +++ b/arch/arm/mm/proc-arm922.S @@ -29,9 +29,9 @@ #include #include #include -#include #include #include +#include #include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index 224ce226a..ee95c52db 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -51,9 +51,9 @@ #include #include #include -#include #include #include +#include #include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 4e2a087cf..7d042dc20 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -28,9 +28,9 @@ #include #include #include -#include #include #include +#include #include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index a2dd5ae10..bd330c407 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -26,7 +25,22 @@ * the cache line size of the I and D cache */ #define DCACHELINESIZE 32 +#define FLUSH_OFFSET 32768 + .macro flush_110_dcache rd, ra, re + ldr \rd, =flush_base + ldr \ra, [\rd] + eor \ra, \ra, #FLUSH_OFFSET + str \ra, [\rd] + add \re, \ra, #16384 @ only necessary for 16k +1001: ldr \rd, [\ra], #DCACHELINESIZE + teq \re, \ra + bne 1001b + .endm + + .data +flush_base: + .long FLUSH_BASE .text /* @@ -130,11 +144,13 @@ ENTRY(cpu_sa110_dcache_clean_area) */ .align 5 ENTRY(cpu_sa110_switch_mm) - str lr, [sp, #-4]! - bl v4wb_flush_kern_cache_all @ clears IP + flush_110_dcache r3, ip, r1 + mov r1, #0 + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer - mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs - ldr pc, [sp], #4 + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr /* * cpu_sa110_set_pte(ptep, pte) diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 777ad99c1..91b89124c 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S @@ -23,13 +23,36 @@ #include #include #include -#include #include /* * the cache line size of the I and D cache */ #define DCACHELINESIZE 32 +#define FLUSH_OFFSET 32768 + + .macro flush_1100_dcache rd, ra, re + ldr \rd, =flush_base + ldr \ra, [\rd] + eor \ra, \ra, #FLUSH_OFFSET + str \ra, [\rd] + add \re, \ra, #8192 @ only necessary for 8k +1001: ldr \rd, [\ra], #DCACHELINESIZE + teq \re, \ra + bne 1001b +#ifdef FLUSH_BASE_MINICACHE + add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE + add \re, \ra, #512 @ only 512 bytes +1002: ldr \rd, [\ra], #DCACHELINESIZE + teq \re, \ra + bne 1002b +#endif + .endm + + .data +flush_base: + .long FLUSH_BASE + .text __INIT @@ -55,8 +78,9 @@ ENTRY(cpu_sa1100_proc_fin) stmfd sp!, {lr} mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE msr cpsr_c, ip - bl v4wb_flush_kern_cache_all - mcr p15, 0, ip, c15, c2, 2 @ Disable clock switching + flush_1100_dcache r0, r1, r2 @ clean caches + mov r0, #0 + mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching mrc p15, 0, r0, c1, c0, 0 @ ctrl register bic r0, r0, #0x1000 @ ...i............ bic r0, r0, #0x000e @ ............wca. @@ -142,12 +166,14 @@ ENTRY(cpu_sa1100_dcache_clean_area) */ .align 5 ENTRY(cpu_sa1100_switch_mm) - str lr, [sp, #-4]! - bl v4wb_flush_kern_cache_all @ clears IP + flush_1100_dcache r3, ip, r1 + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache mcr p15, 0, ip, c9, c0, 0 @ invalidate RB + mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs - ldr pc, [sp], #4 + mov pc, lr /* * cpu_sa1100_set_pte(ptep, pte) diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index ee6f15298..92f3ca31b 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -14,21 +14,12 @@ #include #include #include -#include #include #include "proc-macros.S" #define D_CACHE_LINE_SIZE 32 -#define TTB_C (1 << 0) -#define TTB_S (1 << 1) -#define TTB_IMP (1 << 2) -#define TTB_RGN_NC (0 << 3) -#define TTB_RGN_WBWA (1 << 3) -#define TTB_RGN_WT (2 << 3) -#define TTB_RGN_WB (3 << 3) - .macro cpsie, flags .ifc \flags, f .long 0xf1080040 @@ -123,7 +114,7 @@ ENTRY(cpu_v6_switch_mm) mov r2, #0 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id #ifdef CONFIG_SMP - orr r0, r0, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable + orr r0, r0, #2 @ set shared pgtable #endif mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB mcr p15, 0, r2, c7, c10, 4 @ drain write buffer @@ -169,8 +160,8 @@ ENTRY(cpu_v6_set_pte) tst r1, #L_PTE_YOUNG biceq r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK - tst r1, #L_PTE_EXEC - orreq r2, r2, #PTE_EXT_XN +@ tst r1, #L_PTE_EXEC +@ orreq r2, r2, #PTE_EXT_XN tst r1, #L_PTE_PRESENT moveq r2, #0 @@ -229,7 +220,7 @@ __v6_setup: mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs mcr p15, 0, r0, c2, c0, 2 @ TTB control register #ifdef CONFIG_SMP - orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable + orr r4, r4, #2 @ set shared pgtable #endif mcr p15, 0, r4, c2, c0, 1 @ load TTB1 #ifdef CONFIG_VFP diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S deleted file mode 100644 index 8d32e21fe..000000000 --- a/arch/arm/mm/proc-xsc3.S +++ /dev/null @@ -1,500 +0,0 @@ -/* - * linux/arch/arm/mm/proc-xsc3.S - * - * Original Author: Matthew Gilbert - * Current Maintainer: Deepak Saxena - * - * Copyright 2004 (C) Intel Corp. - * Copyright 2005 (c) MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * MMU functions for the Intel XScale3 Core (XSC3). The XSC3 core is an - * extension to Intel's original XScale core that adds the following - * features: - * - * - ARMv6 Supersections - * - Low Locality Reference pages (replaces mini-cache) - * - 36-bit addressing - * - L2 cache - * - Cache-coherency if chipset supports it - * - * Based on orignal XScale code by Nicolas Pitre - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "proc-macros.S" - -/* - * This is the maximum size of an area which will be flushed. If the - * area is larger than this, then we flush the whole cache. - */ -#define MAX_AREA_SIZE 32768 - -/* - * The cache line size of the I and D cache. - */ -#define CACHELINESIZE 32 - -/* - * The size of the data cache. - */ -#define CACHESIZE 32768 - -/* - * Run with L2 enabled. - */ -#define L2_CACHE_ENABLE 1 - -/* - * Enable the Branch Target Buffer (can cause crashes, see erratum #42.) - */ -#define BTB_ENABLE 0 - -/* - * This macro is used to wait for a CP15 write and is needed - * when we have to ensure that the last operation to the co-pro - * was completed before continuing with operation. - */ - .macro cpwait_ret, lr, rd - mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 - sub pc, \lr, \rd, LSR #32 @ wait for completion and - @ flush instruction pipeline - .endm - -/* - * This macro cleans & invalidates the entire xsc3 dcache by set & way. - */ - - .macro clean_d_cache rd, rs - mov \rd, #0x1f00 - orr \rd, \rd, #0x00e0 -1: mcr p15, 0, \rd, c7, c14, 2 @ clean/inv set/way - adds \rd, \rd, #0x40000000 - bcc 1b - subs \rd, \rd, #0x20 - bpl 1b - .endm - - .text - -/* - * cpu_xsc3_proc_init() - * - * Nothing too exciting at the moment - */ -ENTRY(cpu_xsc3_proc_init) - mov pc, lr - -/* - * cpu_xsc3_proc_fin() - */ -ENTRY(cpu_xsc3_proc_fin) - str lr, [sp, #-4]! - mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE - msr cpsr_c, r0 - bl xsc3_flush_kern_cache_all @ clean caches - mrc p15, 0, r0, c1, c0, 0 @ ctrl register - bic r0, r0, #0x1800 @ ...IZ........... - bic r0, r0, #0x0006 @ .............CA. - mcr p15, 0, r0, c1, c0, 0 @ disable caches - ldr pc, [sp], #4 - -/* - * cpu_xsc3_reset(loc) - * - * Perform a soft reset of the system. Put the CPU into the - * same state as it would be if it had been reset, and branch - * to what would be the reset vector. - * - * loc: location to jump to for soft reset - */ - .align 5 -ENTRY(cpu_xsc3_reset) - mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE - msr cpsr_c, r1 @ reset CPSR - mrc p15, 0, r1, c1, c0, 0 @ ctrl register - bic r1, r1, #0x0086 @ ........B....CA. - bic r1, r1, #0x3900 @ ..VIZ..S........ - mcr p15, 0, r1, c1, c0, 0 @ ctrl register - mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB - bic r1, r1, #0x0001 @ ...............M - mcr p15, 0, r1, c1, c0, 0 @ ctrl register - @ CAUTION: MMU turned off from this point. We count on the pipeline - @ already containing those two last instructions to survive. - mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs - mov pc, r0 - -/* - * cpu_xsc3_do_idle() - * - * Cause the processor to idle - * - * For now we do nothing but go to idle mode for every case - * - * XScale supports clock switching, but using idle mode support - * allows external hardware to react to system state changes. - - MMG: Come back to this one. - */ - .align 5 - -ENTRY(cpu_xsc3_do_idle) - mov r0, #1 - mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE - mov pc, lr - -/* ================================= CACHE ================================ */ - -/* - * flush_user_cache_all() - * - * Invalidate all cache entries in a particular address - * space. - */ -ENTRY(xsc3_flush_user_cache_all) - /* FALLTHROUGH */ - -/* - * flush_kern_cache_all() - * - * Clean and invalidate the entire cache. - */ -ENTRY(xsc3_flush_kern_cache_all) - mov r2, #VM_EXEC - mov ip, #0 -__flush_whole_cache: - clean_d_cache r0, r1 - tst r2, #VM_EXEC - mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB - mcrne p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mcrne p15, 0, ip, c7, c5, 4 @ Prefetch Flush - mov pc, lr - -/* - * flush_user_cache_range(start, end, vm_flags) - * - * Invalidate a range of cache entries in the specified - * address space. - * - * - start - start address (may not be aligned) - * - end - end address (exclusive, may not be aligned) - * - vma - vma_area_struct describing address space - */ - .align 5 -ENTRY(xsc3_flush_user_cache_range) - mov ip, #0 - sub r3, r1, r0 @ calculate total size - cmp r3, #MAX_AREA_SIZE - bhs __flush_whole_cache - -1: tst r2, #VM_EXEC - mcrne p15, 0, r0, c7, c5, 1 @ Invalidate I cache line - mcr p15, 0, r0, c7, c14, 1 @ Clean/invalidate D cache line - add r0, r0, #CACHELINESIZE - cmp r0, r1 - blo 1b - tst r2, #VM_EXEC - mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB - mcrne p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mcrne p15, 0, ip, c7, c5, 4 @ Prefetch Flush - mov pc, lr - -/* - * coherent_kern_range(start, end) - * - * Ensure coherency between the Icache and the Dcache in the - * region described by start. If you have non-snooping - * Harvard caches, you need to implement this function. - * - * - start - virtual start address - * - end - virtual end address - * - * Note: single I-cache line invalidation isn't used here since - * it also trashes the mini I-cache used by JTAG debuggers. - */ -ENTRY(xsc3_coherent_kern_range) -/* FALLTHROUGH */ -ENTRY(xsc3_coherent_user_range) - bic r0, r0, #CACHELINESIZE - 1 -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #CACHELINESIZE - cmp r0, r1 - blo 1b - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer - mcr p15, 0, r0, c7, c5, 4 @ Prefetch Flush - mov pc, lr - -/* - * flush_kern_dcache_page(void *page) - * - * Ensure no D cache aliasing occurs, either with itself or - * the I cache - * - * - addr - page aligned address - */ -ENTRY(xsc3_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ -1: mcr p15, 0, r0, c7, c14, 1 @ Clean/Invalidate D Cache line - add r0, r0, #CACHELINESIZE - cmp r0, r1 - blo 1b - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer - mcr p15, 0, r0, c7, c5, 4 @ Prefetch Flush - mov pc, lr - -/* - * dma_inv_range(start, end) - * - * Invalidate (discard) the specified virtual address range. - * May not write back any entries. If 'start' or 'end' - * are not cache line aligned, those lines must be written - * back. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(xsc3_dma_inv_range) - tst r0, #CACHELINESIZE - 1 - bic r0, r0, #CACHELINESIZE - 1 - mcrne p15, 0, r0, c7, c10, 1 @ clean L1 D entry - mcrne p15, 1, r0, c7, c11, 1 @ clean L2 D entry - tst r1, #CACHELINESIZE - 1 - mcrne p15, 0, r1, c7, c10, 1 @ clean L1 D entry - mcrne p15, 1, r1, c7, c11, 1 @ clean L2 D entry -1: mcr p15, 0, r0, c7, c6, 1 @ invalidate L1 D entry - mcr p15, 1, r0, c7, c7, 1 @ Invalidate L2 D cache line - add r0, r0, #CACHELINESIZE - cmp r0, r1 - blo 1b - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer - mov pc, lr - -/* - * dma_clean_range(start, end) - * - * Clean the specified virtual address range. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(xsc3_dma_clean_range) - bic r0, r0, #CACHELINESIZE - 1 -1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D entry - mcr p15, 1, r0, c7, c11, 1 @ clean L2 D entry - add r0, r0, #CACHELINESIZE - cmp r0, r1 - blo 1b - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer - mov pc, lr - -/* - * dma_flush_range(start, end) - * - * Clean and invalidate the specified virtual address range. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(xsc3_dma_flush_range) - bic r0, r0, #CACHELINESIZE - 1 -1: mcr p15, 0, r0, c7, c14, 1 @ Clean/invalidate L1 D cache line - mcr p15, 1, r0, c7, c11, 1 @ Clean L2 D cache line - mcr p15, 1, r0, c7, c7, 1 @ Invalidate L2 D cache line - add r0, r0, #CACHELINESIZE - cmp r0, r1 - blo 1b - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer - mov pc, lr - -ENTRY(xsc3_cache_fns) - .long xsc3_flush_kern_cache_all - .long xsc3_flush_user_cache_all - .long xsc3_flush_user_cache_range - .long xsc3_coherent_kern_range - .long xsc3_coherent_user_range - .long xsc3_flush_kern_dcache_page - .long xsc3_dma_inv_range - .long xsc3_dma_clean_range - .long xsc3_dma_flush_range - -ENTRY(cpu_xsc3_dcache_clean_area) -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #CACHELINESIZE - subs r1, r1, #CACHELINESIZE - bhi 1b - mov pc, lr - -/* =============================== PageTable ============================== */ - -/* - * cpu_xsc3_switch_mm(pgd) - * - * Set the translation base pointer to be as described by pgd. - * - * pgd: new page tables - */ - .align 5 -ENTRY(cpu_xsc3_switch_mm) - clean_d_cache r1, r2 - mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB - mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mcr p15, 0, ip, c7, c5, 4 @ Prefetch Flush -#ifdef L2_CACHE_ENABLE - orr r0, r0, #0x18 @ cache the page table in L2 -#endif - mcr p15, 0, r0, c2, c0, 0 @ load page table pointer - mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs - cpwait_ret lr, ip - -/* - * cpu_xsc3_set_pte(ptep, pte) - * - * Set a PTE and flush it out - * - */ - .align 5 -ENTRY(cpu_xsc3_set_pte) - str r1, [r0], #-2048 @ linux version - - bic r2, r1, #0xdf0 @ Keep C, B, coherency bits - orr r2, r2, #PTE_TYPE_EXT @ extended page - - eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY - - tst r3, #L_PTE_USER @ User? - orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w - - tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? - orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w - @ combined with user -> user r/w - -#if L2_CACHE_ENABLE - @ If its cacheable it needs to be in L2 also. - eor ip, r1, #L_PTE_CACHEABLE - tst ip, #L_PTE_CACHEABLE - orreq r2, r2, #PTE_EXT_TEX(0x5) -#endif - - tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? - movne r2, #0 @ no -> fault - - str r2, [r0] @ hardware version - mov ip, #0 - mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line mcr - mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mov pc, lr - - .ltorg - - .align - - __INIT - - .type __xsc3_setup, #function -__xsc3_setup: - mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE - msr cpsr_c, r0 - mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB - mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mcr p15, 0, ip, c7, c5, 4 @ Prefetch Flush - mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs -#if L2_CACHE_ENABLE - orr r4, r4, #0x18 @ cache the page table in L2 -#endif - mcr p15, 0, r4, c2, c0, 0 @ load page table pointer - mov r0, #1 @ Allow access to CP0 and CP13 - orr r0, r0, #1 << 13 @ Its undefined whether this - mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes - mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg - and r0, r0, #2 @ preserve bit P bit setting -#if L2_CACHE_ENABLE - orr r0, r0, #(1 << 10) @ enable L2 for LLR cache -#endif - mcr p15, 0, r0, c1, c0, 1 @ set auxiliary control reg - mrc p15, 0, r0, c1, c0, 0 @ get control register - bic r0, r0, #0x0002 @ .... .... .... ..A. - orr r0, r0, #0x0005 @ .... .... .... .C.M -#if BTB_ENABLE - bic r0, r0, #0x0200 @ .... ..R. .... .... - orr r0, r0, #0x3900 @ ..VI Z..S .... .... -#else - bic r0, r0, #0x0a00 @ .... Z.R. .... .... - orr r0, r0, #0x3100 @ ..VI ...S .... .... -#endif -#if L2_CACHE_ENABLE - orr r0, r0, #0x4000000 @ L2 enable -#endif - mov pc, lr - - .size __xsc3_setup, . - __xsc3_setup - - __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - - .type xsc3_processor_functions, #object -ENTRY(xsc3_processor_functions) - .word v5t_early_abort - .word cpu_xsc3_proc_init - .word cpu_xsc3_proc_fin - .word cpu_xsc3_reset - .word cpu_xsc3_do_idle - .word cpu_xsc3_dcache_clean_area - .word cpu_xsc3_switch_mm - .word cpu_xsc3_set_pte - .size xsc3_processor_functions, . - xsc3_processor_functions - - .section ".rodata" - - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_xsc3_name, #object -cpu_xsc3_name: - .asciz "XScale-Core3" - .size cpu_xsc3_name, . - cpu_xsc3_name - - .align - - .section ".proc.info.init", #alloc, #execinstr - - .type __xsc3_proc_info,#object -__xsc3_proc_info: - .long 0x69056000 - .long 0xffffe000 - .long 0x00000c0e - b __xsc3_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_xsc3_name - .long xsc3_processor_functions - .long v4wbi_tlb_fns - .long xsc3_mc_user_fns - .long xsc3_cache_fns - .size __xsc3_proc_info, . - __xsc3_proc_info diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 29bcc4dd6..2d3823ec3 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include #include #include #include "proc-macros.S" diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 6f833358c..6f8bc1f0e 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -10,18 +10,17 @@ #include #include #include -#include #include -#include +#include #include "op_counter.h" #include "op_arm_model.h" static struct op_arm_model_spec *op_arm_model; static int op_arm_enabled; -static DEFINE_MUTEX(op_arm_mutex); +static struct semaphore op_arm_sem; -struct op_counter_config *counter_config; +struct op_counter_config counter_config[OP_MAX_COUNTER]; static int op_arm_create_files(struct super_block *sb, struct dentry *root) { @@ -29,7 +28,7 @@ static int op_arm_create_files(struct super_block *sb, struct dentry *root) for (i = 0; i < op_arm_model->num_counters; i++) { struct dentry *dir; - char buf[4]; + char buf[2]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); @@ -58,40 +57,40 @@ static int op_arm_start(void) { int ret = -EBUSY; - mutex_lock(&op_arm_mutex); + down(&op_arm_sem); if (!op_arm_enabled) { ret = op_arm_model->start(); op_arm_enabled = !ret; } - mutex_unlock(&op_arm_mutex); + up(&op_arm_sem); return ret; } static void op_arm_stop(void) { - mutex_lock(&op_arm_mutex); + down(&op_arm_sem); if (op_arm_enabled) op_arm_model->stop(); op_arm_enabled = 0; - mutex_unlock(&op_arm_mutex); + up(&op_arm_sem); } #ifdef CONFIG_PM static int op_arm_suspend(struct sys_device *dev, pm_message_t state) { - mutex_lock(&op_arm_mutex); + down(&op_arm_sem); if (op_arm_enabled) op_arm_model->stop(); - mutex_unlock(&op_arm_mutex); + up(&op_arm_sem); return 0; } static int op_arm_resume(struct sys_device *dev) { - mutex_lock(&op_arm_mutex); + down(&op_arm_sem); if (op_arm_enabled && op_arm_model->start()) op_arm_enabled = 0; - mutex_unlock(&op_arm_mutex); + up(&op_arm_sem); return 0; } @@ -136,15 +135,12 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) #endif if (spec) { + init_MUTEX(&op_arm_sem); + ret = spec->init(); if (ret < 0) return ret; - counter_config = kcalloc(spec->num_counters, sizeof(struct op_counter_config), - GFP_KERNEL); - if (!counter_config) - return -ENOMEM; - op_arm_model = spec; init_driverfs(); ops->create_files = op_arm_create_files; @@ -166,5 +162,5 @@ void oprofile_arch_exit(void) exit_driverfs(); op_arm_model = NULL; } - kfree(counter_config); } + diff --git a/arch/arm/oprofile/op_counter.h b/arch/arm/oprofile/op_counter.h index 8c5351d75..153c1d467 100644 --- a/arch/arm/oprofile/op_counter.h +++ b/arch/arm/oprofile/op_counter.h @@ -24,6 +24,6 @@ struct op_counter_config { unsigned long user; }; -extern struct op_counter_config *counter_config; +extern struct op_counter_config counter_config[]; #endif /* OP_COUNTER_H */ diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index ec49495e6..0887bb2a2 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -70,13 +70,13 @@ config OMAP_MPU_TIMER config OMAP_32K_TIMER bool "Use 32KHz timer" - depends on ARCH_OMAP16XX || ARCH_OMAP24XX + depends on ARCH_OMAP16XX help Select this option if you want to enable the OMAP 32KHz timer. This timer saves power compared to the OMAP_MPU_TIMER, and has support for no tick during idle. The 32KHz timer provides less intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is - currently only available for OMAP16XX and 24XX. + currently only available for OMAP-16xx. endchoice diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 2896b4546..9ccf1943f 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -3,16 +3,16 @@ # # Common support -obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o fb.o +obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o obj-m := obj-n := obj- := -obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o - # OCPI interconnect support for 1710, 1610 and 5912 obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o +# Power Management +obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_CPU_FREQ) += cpu-omap.o obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 32ec04c58..3c2bfc0ef 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -38,38 +37,17 @@ static struct clk_functions *arch_clock; * Standard clock functions defined in include/linux/clk.h *-------------------------------------------------------------------------*/ -/* - * Returns a clock. Note that we first try to use device id on the bus - * and clock name. If this fails, we try to use clock name only. - */ struct clk * clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); - int idno; - - if (dev == NULL || dev->bus != &platform_bus_type) - idno = -1; - else - idno = to_platform_device(dev)->id; mutex_lock(&clocks_mutex); - - list_for_each_entry(p, &clocks, node) { - if (p->id == idno && - strcmp(id, p->name) == 0 && try_module_get(p->owner)) { - clk = p; - goto found; - } - } - list_for_each_entry(p, &clocks, node) { if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; break; } } - -found: mutex_unlock(&clocks_mutex); return clk; @@ -81,9 +59,6 @@ int clk_enable(struct clk *clk) unsigned long flags; int ret = 0; - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_enable) ret = arch_clock->clk_enable(clk); @@ -97,9 +72,6 @@ void clk_disable(struct clk *clk) { unsigned long flags; - if (clk == NULL || IS_ERR(clk)) - return; - spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_disable) arch_clock->clk_disable(clk); @@ -112,9 +84,6 @@ int clk_get_usecount(struct clk *clk) unsigned long flags; int ret = 0; - if (clk == NULL || IS_ERR(clk)) - return 0; - spin_lock_irqsave(&clockfw_lock, flags); ret = clk->usecount; spin_unlock_irqrestore(&clockfw_lock, flags); @@ -128,9 +97,6 @@ unsigned long clk_get_rate(struct clk *clk) unsigned long flags; unsigned long ret = 0; - if (clk == NULL || IS_ERR(clk)) - return 0; - spin_lock_irqsave(&clockfw_lock, flags); ret = clk->rate; spin_unlock_irqrestore(&clockfw_lock, flags); @@ -155,9 +121,6 @@ long clk_round_rate(struct clk *clk, unsigned long rate) unsigned long flags; long ret = 0; - if (clk == NULL || IS_ERR(clk)) - return ret; - spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_round_rate) ret = arch_clock->clk_round_rate(clk, rate); @@ -170,10 +133,7 @@ EXPORT_SYMBOL(clk_round_rate); int clk_set_rate(struct clk *clk, unsigned long rate) { unsigned long flags; - int ret = -EINVAL; - - if (clk == NULL || IS_ERR(clk)) - return ret; + int ret = 0; spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_set_rate) @@ -187,10 +147,7 @@ EXPORT_SYMBOL(clk_set_rate); int clk_set_parent(struct clk *clk, struct clk *parent) { unsigned long flags; - int ret = -EINVAL; - - if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent)) - return ret; + int ret = 0; spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_set_parent) @@ -206,9 +163,6 @@ struct clk *clk_get_parent(struct clk *clk) unsigned long flags; struct clk * ret = NULL; - if (clk == NULL || IS_ERR(clk)) - return ret; - spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_get_parent) ret = arch_clock->clk_get_parent(clk); @@ -245,9 +199,6 @@ __setup("mpurate=", omap_clk_setup); /* Used for clocks that always have same value as the parent clock */ void followparent_recalc(struct clk *clk) { - if (clk == NULL || IS_ERR(clk)) - return; - clk->rate = clk->parent->rate; } @@ -256,9 +207,6 @@ void propagate_rate(struct clk * tclk) { struct clk *clkp; - if (tclk == NULL || IS_ERR(tclk)) - return; - list_for_each_entry(clkp, &clocks, node) { if (likely(clkp->parent != tclk)) continue; @@ -269,9 +217,6 @@ void propagate_rate(struct clk * tclk) int clk_register(struct clk *clk) { - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - mutex_lock(&clocks_mutex); list_add(&clk->node, &clocks); if (clk->init) @@ -284,9 +229,6 @@ EXPORT_SYMBOL(clk_register); void clk_unregister(struct clk *clk) { - if (clk == NULL || IS_ERR(clk)) - return; - mutex_lock(&clocks_mutex); list_del(&clk->node); mutex_unlock(&clocks_mutex); @@ -297,9 +239,6 @@ void clk_deny_idle(struct clk *clk) { unsigned long flags; - if (clk == NULL || IS_ERR(clk)) - return; - spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_deny_idle) arch_clock->clk_deny_idle(clk); @@ -311,9 +250,6 @@ void clk_allow_idle(struct clk *clk) { unsigned long flags; - if (clk == NULL || IS_ERR(clk)) - return; - spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_allow_idle) arch_clock->clk_allow_idle(clk); diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 5d5d6eb22..9dcce904b 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -24,7 +24,14 @@ #include #include #include -#include + + +void omap_nop_release(struct device *dev) +{ + /* Nothing */ +} + +/*-------------------------------------------------------------------------*/ #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) @@ -51,6 +58,9 @@ static struct resource i2c_resources1[] = { static struct platform_device omap_i2c_device1 = { .name = "i2c_omap", .id = 1, + .dev = { + .release = omap_nop_release, + }, .num_resources = ARRAY_SIZE(i2c_resources1), .resource = i2c_resources1, }; @@ -87,62 +97,6 @@ static void omap_init_i2c(void) static inline void omap_init_i2c(void) {} #endif -/*-------------------------------------------------------------------------*/ -#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) - -static void omap_init_kp(void) -{ - if (machine_is_omap_h2() || machine_is_omap_h3()) { - omap_cfg_reg(F18_1610_KBC0); - omap_cfg_reg(D20_1610_KBC1); - omap_cfg_reg(D19_1610_KBC2); - omap_cfg_reg(E18_1610_KBC3); - omap_cfg_reg(C21_1610_KBC4); - - omap_cfg_reg(G18_1610_KBR0); - omap_cfg_reg(F19_1610_KBR1); - omap_cfg_reg(H14_1610_KBR2); - omap_cfg_reg(E20_1610_KBR3); - omap_cfg_reg(E19_1610_KBR4); - omap_cfg_reg(N19_1610_KBR5); - } else if (machine_is_omap_perseus2()) { - omap_cfg_reg(E2_730_KBR0); - omap_cfg_reg(J7_730_KBR1); - omap_cfg_reg(E1_730_KBR2); - omap_cfg_reg(F3_730_KBR3); - omap_cfg_reg(D2_730_KBR4); - - omap_cfg_reg(C2_730_KBC0); - omap_cfg_reg(D3_730_KBC1); - omap_cfg_reg(E4_730_KBC2); - omap_cfg_reg(F4_730_KBC3); - omap_cfg_reg(E3_730_KBC4); - } else if (machine_is_omap_h4()) { - omap_cfg_reg(T19_24XX_KBR0); - omap_cfg_reg(R19_24XX_KBR1); - omap_cfg_reg(V18_24XX_KBR2); - omap_cfg_reg(M21_24XX_KBR3); - omap_cfg_reg(E5__24XX_KBR4); - if (omap_has_menelaus()) { - omap_cfg_reg(B3__24XX_KBR5); - omap_cfg_reg(AA4_24XX_KBC2); - omap_cfg_reg(B13_24XX_KBC6); - } else { - omap_cfg_reg(M18_24XX_KBR5); - omap_cfg_reg(H19_24XX_KBC2); - omap_cfg_reg(N19_24XX_KBC6); - } - omap_cfg_reg(R20_24XX_KBC0); - omap_cfg_reg(M14_24XX_KBC1); - omap_cfg_reg(V17_24XX_KBC3); - omap_cfg_reg(P21_24XX_KBC4); - omap_cfg_reg(L14_24XX_KBC5); - } -} -#else -static inline void omap_init_kp(void) {} -#endif - /*-------------------------------------------------------------------------*/ #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) @@ -176,6 +130,7 @@ static struct platform_device mmc_omap_device1 = { .name = "mmci-omap", .id = 1, .dev = { + .release = omap_nop_release, .dma_mask = &mmc1_dmamask, .platform_data = &mmc1_conf, }, @@ -205,6 +160,7 @@ static struct platform_device mmc_omap_device2 = { .name = "mmci-omap", .id = 2, .dev = { + .release = omap_nop_release, .dma_mask = &mmc2_dmamask, .platform_data = &mmc2_conf, }, @@ -284,52 +240,6 @@ static void __init omap_init_mmc(void) static inline void omap_init_mmc(void) {} #endif -/*-------------------------------------------------------------------------*/ - -/* Numbering for the SPI-capable controllers when used for SPI: - * spi = 1 - * uwire = 2 - * mmc1..2 = 3..4 - * mcbsp1..3 = 5..7 - */ - -#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE) - -#define OMAP_UWIRE_BASE 0xfffb3000 - -static struct resource uwire_resources[] = { - { - .start = OMAP_UWIRE_BASE, - .end = OMAP_UWIRE_BASE + 0x20, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device omap_uwire_device = { - .name = "omap_uwire", - .id = -1, - .num_resources = ARRAY_SIZE(uwire_resources), - .resource = uwire_resources, -}; - -static void omap_init_uwire(void) -{ - /* FIXME define and use a boot tag; not all boards will be hooking - * up devices to the microwire controller, and multi-board configs - * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway... - */ - - /* board-specific code must configure chipselects (only a few - * are normally used) and SCLK/SDI/SDO (each has two choices). - */ - (void) platform_device_register(&omap_uwire_device); -} -#else -static inline void omap_init_uwire(void) {} -#endif - -/*-------------------------------------------------------------------------*/ - #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) #ifdef CONFIG_ARCH_OMAP24XX @@ -349,6 +259,9 @@ static struct resource wdt_resources[] = { static struct platform_device omap_wdt_device = { .name = "omap_wdt", .id = -1, + .dev = { + .release = omap_nop_release, + }, .num_resources = ARRAY_SIZE(wdt_resources), .resource = wdt_resources, }; @@ -382,6 +295,9 @@ static struct resource rng_resources[] = { static struct platform_device omap_rng_device = { .name = "omap_rng", .id = -1, + .dev = { + .release = omap_nop_release, + }, .num_resources = ARRAY_SIZE(rng_resources), .resource = rng_resources, }; @@ -394,6 +310,40 @@ static void omap_init_rng(void) static inline void omap_init_rng(void) {} #endif +#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) + +static struct omap_lcd_config omap_fb_conf; + +static u64 omap_fb_dma_mask = ~(u32)0; + +static struct platform_device omap_fb_device = { + .name = "omapfb", + .id = -1, + .dev = { + .release = omap_nop_release, + .dma_mask = &omap_fb_dma_mask, + .coherent_dma_mask = ~(u32)0, + .platform_data = &omap_fb_conf, + }, + .num_resources = 0, +}; + +static inline void omap_init_fb(void) +{ + const struct omap_lcd_config *conf; + + conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); + if (conf != NULL) + omap_fb_conf = *conf; + platform_device_register(&omap_fb_device); +} + +#else + +static inline void omap_init_fb(void) {} + +#endif + /* * This gets called after board-specific INIT_MACHINE, and initializes most * on-chip peripherals accessible on this board (except for few like USB): @@ -419,10 +369,9 @@ static int __init omap_init_devices(void) /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ + omap_init_fb(); omap_init_i2c(); - omap_init_kp(); omap_init_mmc(); - omap_init_uwire(); omap_init_wdt(); omap_init_rng(); diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 5dac42303..a4e5ac77f 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1258,11 +1258,6 @@ void omap_stop_lcd_dma(void) omap_writew(w, OMAP1610_DMA_LCD_CTRL); } -int omap_lcd_dma_ext_running(void) -{ - return lcd_dma.ext_ctrl && lcd_dma.active; -} - /*----------------------------------------------------------------------------*/ static int __init omap_init_dma(void) @@ -1394,7 +1389,6 @@ EXPORT_SYMBOL(omap_free_lcd_dma); EXPORT_SYMBOL(omap_enable_lcd_dma); EXPORT_SYMBOL(omap_setup_lcd_dma); EXPORT_SYMBOL(omap_stop_lcd_dma); -EXPORT_SYMBOL(omap_lcd_dma_ext_running); EXPORT_SYMBOL(omap_set_lcd_dma_b1); EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index eba3cb52a..38d7ebf87 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -97,32 +97,6 @@ int omap_dm_timers_active(void) } -/** - * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR - * @inputmask: current value of idlect mask - */ -__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) -{ - int n; - - /* If ARMXOR cannot be idled this function call is unnecessary */ - if (!(inputmask & (1 << 1))) - return inputmask; - - /* If any active timer is using ARMXOR return modified mask */ - for (n = 0; dm_timers[n].base; ++n) - if (omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG)& - OMAP_TIMER_CTRL_ST) { - if (((omap_readl(MOD_CONF_CTRL_1)>>(n*2)) & 0x03) == 0) - inputmask &= ~(1 << 1); - else - inputmask &= ~(1 << 2); - } - - return inputmask; -} - - void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) { int n = (timer - dm_timers) << 1; diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c deleted file mode 100644 index 305e9b990..000000000 --- a/arch/arm/plat-omap/fb.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) - -static struct omapfb_platform_data omapfb_config; - -static u64 omap_fb_dma_mask = ~(u32)0; - -static struct platform_device omap_fb_device = { - .name = "omapfb", - .id = -1, - .dev = { - .dma_mask = &omap_fb_dma_mask, - .coherent_dma_mask = ~(u32)0, - .platform_data = &omapfb_config, - }, - .num_resources = 0, -}; - -/* called from map_io */ -void omapfb_reserve_mem(void) -{ - const struct omap_fbmem_config *fbmem_conf; - - omapfb_config.fbmem.fb_sram_start = omap_fb_sram_start; - omapfb_config.fbmem.fb_sram_size = omap_fb_sram_size; - - fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config); - - if (fbmem_conf != NULL) { - /* indicate that the bootloader already initialized the - * fb device, so we'll skip that part in the fb driver - */ - omapfb_config.fbmem.fb_sdram_start = fbmem_conf->fb_sdram_start; - omapfb_config.fbmem.fb_sdram_size = fbmem_conf->fb_sdram_size; - if (fbmem_conf->fb_sdram_size) { - pr_info("Reserving %u bytes SDRAM for frame buffer\n", - fbmem_conf->fb_sdram_size); - reserve_bootmem(fbmem_conf->fb_sdram_start, - fbmem_conf->fb_sdram_size); - } - } -} - -static inline int omap_init_fb(void) -{ - const struct omap_lcd_config *conf; - - conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); - if (conf == NULL) - return 0; - - omapfb_config.lcd = *conf; - - return platform_device_register(&omap_fb_device); -} - -arch_initcall(omap_init_fb); - -#else - -void omapfb_reserve_mem(void) {} - -#endif - - diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index d3c8ea7ee..b4d5b9e4b 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -174,7 +174,7 @@ static int gpio_bank_count; static inline struct gpio_bank *get_gpio_bank(int gpio) { #ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap15xx()) { + if (cpu_is_omap1510()) { if (OMAP_GPIO_IS_MPUIO(gpio)) return &gpio_bank[0]; return &gpio_bank[1]; @@ -223,7 +223,7 @@ static inline int gpio_valid(int gpio) return 0; } #ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap15xx() && gpio < 16) + if (cpu_is_omap1510() && gpio < 16) return 0; #endif #if defined(CONFIG_ARCH_OMAP16XX) @@ -402,13 +402,13 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr u32 gpio_bit = 1 << gpio; MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, - trigger & __IRQT_LOWLVL); + trigger & IRQT_LOW); MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, - trigger & __IRQT_HIGHLVL); + trigger & IRQT_HIGH); MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, - trigger & __IRQT_RISEDGE); + trigger & IRQT_RISING); MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, - trigger & __IRQT_FALEDGE); + trigger & IRQT_FALLING); /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level * triggering requested. */ } @@ -422,9 +422,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_INT_EDGE; l = __raw_readl(reg); - if (trigger & __IRQT_RISEDGE) + if (trigger == IRQT_RISING) l |= 1 << gpio; - else if (trigger & __IRQT_FALEDGE) + else if (trigger == IRQT_FALLING) l &= ~(1 << gpio); else goto bad; @@ -432,9 +432,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_CONTROL; l = __raw_readl(reg); - if (trigger & __IRQT_RISEDGE) + if (trigger == IRQT_RISING) l |= 1 << gpio; - else if (trigger & __IRQT_FALEDGE) + else if (trigger == IRQT_FALLING) l &= ~(1 << gpio); else goto bad; @@ -446,21 +446,20 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) reg += OMAP1610_GPIO_EDGE_CTRL1; gpio &= 0x07; /* We allow only edge triggering, i.e. two lowest bits */ - if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL)) + if (trigger & ~IRQT_BOTHEDGE) BUG(); + /* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */ + trigger &= 0x03; l = __raw_readl(reg); l &= ~(3 << (gpio << 1)); - if (trigger & __IRQT_RISEDGE) - l |= 2 << (gpio << 1); - if (trigger & __IRQT_FALEDGE) - l |= 1 << (gpio << 1); + l |= trigger << (gpio << 1); break; case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_CONTROL; l = __raw_readl(reg); - if (trigger & __IRQT_RISEDGE) + if (trigger == IRQT_RISING) l |= 1 << gpio; - else if (trigger & __IRQT_FALEDGE) + else if (trigger == IRQT_FALLING) l &= ~(1 << gpio); else goto bad; @@ -492,9 +491,7 @@ static int gpio_irq_type(unsigned irq, unsigned type) if (check_gpio(gpio) < 0) return -EINVAL; - if (type & IRQT_PROBE) - return -EINVAL; - if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL))) + if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE)) return -EINVAL; bank = get_gpio_bank(gpio); @@ -758,32 +755,13 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, if (bank->method == METHOD_GPIO_24XX) isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; #endif - while(1) { - u32 isr_saved, level_mask = 0; - - isr_saved = isr = __raw_readl(isr_reg); - - if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) - isr &= 0x0000ffff; - - if (cpu_is_omap24xx()) - level_mask = - __raw_readl(bank->base + - OMAP24XX_GPIO_LEVELDETECT0) | - __raw_readl(bank->base + - OMAP24XX_GPIO_LEVELDETECT1); - /* clear edge sensitive interrupts before handler(s) are - called so that we don't miss any interrupt occurred while - executing them */ - _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0); - _clear_gpio_irqbank(bank, isr_saved & ~level_mask); - _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1); - - /* if there is only edge sensitive GPIO pin interrupts - configured, we could unmask GPIO bank interrupt immediately */ - if (!level_mask) - desc->chip->unmask(irq); + while(1) { + isr = __raw_readl(isr_reg); + _enable_gpio_irqbank(bank, isr, 0); + _clear_gpio_irqbank(bank, isr); + _enable_gpio_irqbank(bank, isr, 1); + desc->chip->unmask(irq); if (!isr) break; @@ -796,20 +774,6 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, d = irq_desc + gpio_irq; desc_handle_irq(gpio_irq, d, regs); } - - if (cpu_is_omap24xx()) { - /* clear level sensitive interrupts after handler(s) */ - _enable_gpio_irqbank(bank, isr_saved & level_mask, 0); - _clear_gpio_irqbank(bank, isr_saved & level_mask); - _enable_gpio_irqbank(bank, isr_saved & level_mask, 1); - } - - /* if bank has any level sensitive GPIO pin interrupt - configured, we must unmask the bank interrupt only after - handler(s) are executed in order to avoid spurious bank - interrupt */ - if (level_mask) - desc->chip->unmask(irq); } } @@ -884,7 +848,7 @@ static int __init _omap_gpio_init(void) initialized = 1; - if (cpu_is_omap15xx()) { + if (cpu_is_omap1510()) { gpio_ick = clk_get(NULL, "arm_gpio_ck"); if (IS_ERR(gpio_ick)) printk("Could not get arm_gpio_ck\n"); @@ -905,7 +869,7 @@ static int __init _omap_gpio_init(void) } #ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap15xx()) { + if (cpu_is_omap1510()) { printk(KERN_INFO "OMAP1510 GPIO hardware\n"); gpio_bank_count = 2; gpio_bank = gpio_bank_1510; diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 196aac3ac..1cd2cace7 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -34,7 +34,7 @@ #ifdef CONFIG_MCBSP_DEBUG #define DBG(x...) printk(x) #else -#define DBG(x...) do { } while (0) +#define DBG(x...) do { } while (0) #endif struct omap_mcbsp { @@ -44,7 +44,6 @@ struct omap_mcbsp { omap_mcbsp_word_length rx_word_length; omap_mcbsp_word_length tx_word_length; - omap_mcbsp_io_type_t io_type; /* IRQ or poll */ /* IRQ based TX/RX */ int rx_irq; int tx_irq; @@ -65,19 +64,10 @@ struct omap_mcbsp { }; static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; -#ifdef CONFIG_ARCH_OMAP1 static struct clk *mcbsp_dsp_ck = 0; static struct clk *mcbsp_api_ck = 0; static struct clk *mcbsp_dspxor_ck = 0; -#endif -#ifdef CONFIG_ARCH_OMAP2 -static struct clk *mcbsp1_ick = 0; -static struct clk *mcbsp1_fck = 0; -static struct clk *mcbsp2_ick = 0; -static struct clk *mcbsp2_fck = 0; -static struct clk *sys_ck = 0; -static struct clk *sys_clkout = 0; -#endif + static void omap_mcbsp_dump_reg(u8 id) { @@ -98,6 +88,7 @@ static void omap_mcbsp_dump_reg(u8 id) DBG("***********************\n"); } + static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); @@ -118,6 +109,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_re return IRQ_HANDLED; } + static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) { struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); @@ -184,7 +176,7 @@ static int omap_mcbsp_check(unsigned int id) return 0; } - if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { + if (cpu_is_omap1510() || cpu_is_omap16xx()) { if (id > OMAP_MAX_MCBSP_COUNT) { printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); return -1; @@ -195,10 +187,9 @@ static int omap_mcbsp_check(unsigned int id) return -1; } -#ifdef CONFIG_ARCH_OMAP1 static void omap_mcbsp_dsp_request(void) { - if (cpu_is_omap15xx() || cpu_is_omap16xx()) { + if (cpu_is_omap1510() || cpu_is_omap16xx()) { clk_enable(mcbsp_dsp_ck); clk_enable(mcbsp_api_ck); @@ -216,49 +207,12 @@ static void omap_mcbsp_dsp_request(void) static void omap_mcbsp_dsp_free(void) { - if (cpu_is_omap15xx() || cpu_is_omap16xx()) { + if (cpu_is_omap1510() || cpu_is_omap16xx()) { clk_disable(mcbsp_dspxor_ck); clk_disable(mcbsp_dsp_ck); clk_disable(mcbsp_api_ck); } } -#endif - -#ifdef CONFIG_ARCH_OMAP2 -static void omap2_mcbsp2_mux_setup(void) -{ - omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); - omap_cfg_reg(R14_24XX_MCBSP2_FSX); - omap_cfg_reg(W15_24XX_MCBSP2_DR); - omap_cfg_reg(V15_24XX_MCBSP2_DX); - omap_cfg_reg(V14_24XX_GPIO117); - omap_cfg_reg(W14_24XX_SYS_CLKOUT); -} -#endif - -/* - * We can choose between IRQ based or polled IO. - * This needs to be called before omap_mcbsp_request(). - */ -int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) -{ - if (omap_mcbsp_check(id) < 0) - return -EINVAL; - - spin_lock(&mcbsp[id].lock); - - if (!mcbsp[id].free) { - printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); - spin_unlock(&mcbsp[id].lock); - return -EINVAL; - } - - mcbsp[id].io_type = io_type; - - spin_unlock(&mcbsp[id].lock); - - return 0; -} int omap_mcbsp_request(unsigned int id) { @@ -267,26 +221,12 @@ int omap_mcbsp_request(unsigned int id) if (omap_mcbsp_check(id) < 0) return -EINVAL; -#ifdef CONFIG_ARCH_OMAP1 /* * On 1510, 1610 and 1710, McBSP1 and McBSP3 * are DSP public peripherals. */ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) omap_mcbsp_dsp_request(); -#endif - -#ifdef CONFIG_ARCH_OMAP2 - if (cpu_is_omap24xx()) { - if (id == OMAP_MCBSP1) { - clk_enable(mcbsp1_ick); - clk_enable(mcbsp1_fck); - } else { - clk_enable(mcbsp2_ick); - clk_enable(mcbsp2_fck); - } - } -#endif spin_lock(&mcbsp[id].lock); if (!mcbsp[id].free) { @@ -298,33 +238,30 @@ int omap_mcbsp_request(unsigned int id) mcbsp[id].free = 0; spin_unlock(&mcbsp[id].lock); - if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { - /* We need to get IRQs here */ - err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, - "McBSP", - (void *) (&mcbsp[id])); - if (err != 0) { - printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", - mcbsp[id].tx_irq, mcbsp[id].id); - return err; - } - - init_completion(&(mcbsp[id].tx_irq_completion)); + /* We need to get IRQs here */ + err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, + "McBSP", + (void *) (&mcbsp[id])); + if (err != 0) { + printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", + mcbsp[id].tx_irq, mcbsp[id].id); + return err; + } + init_completion(&(mcbsp[id].tx_irq_completion)); - err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, - "McBSP", - (void *) (&mcbsp[id])); - if (err != 0) { - printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", - mcbsp[id].rx_irq, mcbsp[id].id); - free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); - return err; - } - init_completion(&(mcbsp[id].rx_irq_completion)); + err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, + "McBSP", + (void *) (&mcbsp[id])); + if (err != 0) { + printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", + mcbsp[id].rx_irq, mcbsp[id].id); + free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); + return err; } + init_completion(&(mcbsp[id].rx_irq_completion)); return 0; } @@ -334,24 +271,8 @@ void omap_mcbsp_free(unsigned int id) if (omap_mcbsp_check(id) < 0) return; -#ifdef CONFIG_ARCH_OMAP1 - if (cpu_class_is_omap1()) { - if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) - omap_mcbsp_dsp_free(); - } -#endif - -#ifdef CONFIG_ARCH_OMAP2 - if (cpu_is_omap24xx()) { - if (id == OMAP_MCBSP1) { - clk_disable(mcbsp1_ick); - clk_disable(mcbsp1_fck); - } else { - clk_disable(mcbsp2_ick); - clk_disable(mcbsp2_fck); - } - } -#endif + if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) + omap_mcbsp_dsp_free(); spin_lock(&mcbsp[id].lock); if (mcbsp[id].free) { @@ -363,11 +284,9 @@ void omap_mcbsp_free(unsigned int id) mcbsp[id].free = 1; spin_unlock(&mcbsp[id].lock); - if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { - /* Free IRQs */ - free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); - free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); - } + /* Free IRQs */ + free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); + free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); } /* @@ -542,115 +461,6 @@ u32 omap_mcbsp_recv_word(unsigned int id) } -int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) -{ - u32 io_base = mcbsp[id].io_base; - omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; - omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; - u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; - - if (tx_word_length != rx_word_length) - return -EINVAL; - - /* First we wait for the transmitter to be ready */ - spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); - while (!(spcr2 & XRDY)) { - spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); - if (attempts++ > 1000) { - /* We must reset the transmitter */ - OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); - udelay(10); - OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); - udelay(10); - printk("McBSP transmitter not ready\n"); - return -EAGAIN; - } - } - - /* Now we can push the data */ - if (tx_word_length > OMAP_MCBSP_WORD_16) - OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); - OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); - - /* We wait for the receiver to be ready */ - spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); - while (!(spcr1 & RRDY)) { - spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); - if (attempts++ > 1000) { - /* We must reset the receiver */ - OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); - udelay(10); - OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); - udelay(10); - printk("McBSP receiver not ready\n"); - return -EAGAIN; - } - } - - /* Receiver is ready, let's read the dummy data */ - if (rx_word_length > OMAP_MCBSP_WORD_16) - word_msb = OMAP_MCBSP_READ(io_base, DRR2); - word_lsb = OMAP_MCBSP_READ(io_base, DRR1); - - return 0; -} - -int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) -{ - u32 io_base = mcbsp[id].io_base, clock_word = 0; - omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; - omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; - u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; - - if (tx_word_length != rx_word_length) - return -EINVAL; - - /* First we wait for the transmitter to be ready */ - spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); - while (!(spcr2 & XRDY)) { - spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); - if (attempts++ > 1000) { - /* We must reset the transmitter */ - OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); - udelay(10); - OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); - udelay(10); - printk("McBSP transmitter not ready\n"); - return -EAGAIN; - } - } - - /* We first need to enable the bus clock */ - if (tx_word_length > OMAP_MCBSP_WORD_16) - OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16); - OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff); - - /* We wait for the receiver to be ready */ - spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); - while (!(spcr1 & RRDY)) { - spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); - if (attempts++ > 1000) { - /* We must reset the receiver */ - OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); - udelay(10); - OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); - udelay(10); - printk("McBSP receiver not ready\n"); - return -EAGAIN; - } - } - - /* Receiver is ready, there is something for us */ - if (rx_word_length > OMAP_MCBSP_WORD_16) - word_msb = OMAP_MCBSP_READ(io_base, DRR2); - word_lsb = OMAP_MCBSP_READ(io_base, DRR1); - - word[0] = (word_lsb | (word_msb << 16)); - - return 0; -} - - /* * Simple DMA based buffer rx/tx routines. * Nothing fancy, just a single buffer tx/rx through DMA. @@ -661,9 +471,6 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) { int dma_tx_ch; - int src_port = 0; - int dest_port = 0; - int sync_dev = 0; if (omap_mcbsp_check(id) < 0) return -EINVAL; @@ -680,27 +487,20 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng init_completion(&(mcbsp[id].tx_dma_completion)); - if (cpu_class_is_omap1()) { - src_port = OMAP_DMA_PORT_TIPB; - dest_port = OMAP_DMA_PORT_EMIFF; - } - if (cpu_is_omap24xx()) - sync_dev = mcbsp[id].dma_tx_sync; - omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, OMAP_DMA_DATA_TYPE_S16, length >> 1, 1, OMAP_DMA_SYNC_ELEMENT, - sync_dev, 0); + 0, 0); omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, - src_port, + OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1, 0, 0); omap_set_dma_src_params(mcbsp[id].dma_tx_lch, - dest_port, + OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, buffer, 0, 0); @@ -714,9 +514,6 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) { int dma_rx_ch; - int src_port = 0; - int dest_port = 0; - int sync_dev = 0; if (omap_mcbsp_check(id) < 0) return -EINVAL; @@ -733,27 +530,20 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng init_completion(&(mcbsp[id].rx_dma_completion)); - if (cpu_class_is_omap1()) { - src_port = OMAP_DMA_PORT_TIPB; - dest_port = OMAP_DMA_PORT_EMIFF; - } - if (cpu_is_omap24xx()) - sync_dev = mcbsp[id].dma_rx_sync; - omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, OMAP_DMA_DATA_TYPE_S16, length >> 1, 1, OMAP_DMA_SYNC_ELEMENT, - sync_dev, 0); + 0, 0); omap_set_dma_src_params(mcbsp[id].dma_rx_lch, - src_port, + OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1, 0, 0); omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, - dest_port, + OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, buffer, 0, 0); @@ -898,23 +688,6 @@ static const struct omap_mcbsp_info mcbsp_1610[] = { }; #endif -#if defined(CONFIG_ARCH_OMAP24XX) -static const struct omap_mcbsp_info mcbsp_24xx[] = { - [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), - .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, - }, - [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), - .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, - }, -}; -#endif - static int __init omap_mcbsp_init(void) { int mcbsp_count = 0, i; @@ -922,7 +695,6 @@ static int __init omap_mcbsp_init(void) printk("Initializing OMAP McBSP system\n"); -#ifdef CONFIG_ARCH_OMAP1 mcbsp_dsp_ck = clk_get(0, "dsp_ck"); if (IS_ERR(mcbsp_dsp_ck)) { printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); @@ -938,29 +710,6 @@ static int __init omap_mcbsp_init(void) printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); return PTR_ERR(mcbsp_dspxor_ck); } -#endif -#ifdef CONFIG_ARCH_OMAP2 - mcbsp1_ick = clk_get(0, "mcbsp1_ick"); - if (IS_ERR(mcbsp1_ick)) { - printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n"); - return PTR_ERR(mcbsp1_ick); - } - mcbsp1_fck = clk_get(0, "mcbsp1_fck"); - if (IS_ERR(mcbsp1_fck)) { - printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n"); - return PTR_ERR(mcbsp1_fck); - } - mcbsp2_ick = clk_get(0, "mcbsp2_ick"); - if (IS_ERR(mcbsp2_ick)) { - printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n"); - return PTR_ERR(mcbsp2_ick); - } - mcbsp2_fck = clk_get(0, "mcbsp2_fck"); - if (IS_ERR(mcbsp2_fck)) { - printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n"); - return PTR_ERR(mcbsp2_fck); - } -#endif #ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730()) { @@ -969,7 +718,7 @@ static int __init omap_mcbsp_init(void) } #endif #ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap15xx()) { + if (cpu_is_omap1510()) { mcbsp_info = mcbsp_1510; mcbsp_count = ARRAY_SIZE(mcbsp_1510); } @@ -979,19 +728,6 @@ static int __init omap_mcbsp_init(void) mcbsp_info = mcbsp_1610; mcbsp_count = ARRAY_SIZE(mcbsp_1610); } -#endif -#if defined(CONFIG_ARCH_OMAP24XX) - if (cpu_is_omap24xx()) { - mcbsp_info = mcbsp_24xx; - mcbsp_count = ARRAY_SIZE(mcbsp_24xx); - - /* REVISIT: where's the right place? */ - omap2_mcbsp2_mux_setup(); - sys_ck = clk_get(0, "sys_ck"); - sys_clkout = clk_get(0, "sys_clkout"); - clk_set_parent(sys_clkout, sys_ck); - clk_enable(sys_clkout); - } #endif for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { if (i >= mcbsp_count) { @@ -1005,7 +741,6 @@ static int __init omap_mcbsp_init(void) mcbsp[i].dma_rx_lch = -1; mcbsp[i].io_base = mcbsp_info[i].virt_base; - mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */ mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; @@ -1016,11 +751,11 @@ static int __init omap_mcbsp_init(void) return 0; } + arch_initcall(omap_mcbsp_init); EXPORT_SYMBOL(omap_mcbsp_config); EXPORT_SYMBOL(omap_mcbsp_request); -EXPORT_SYMBOL(omap_mcbsp_set_io_type); EXPORT_SYMBOL(omap_mcbsp_free); EXPORT_SYMBOL(omap_mcbsp_start); EXPORT_SYMBOL(omap_mcbsp_stop); @@ -1028,6 +763,4 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word); EXPORT_SYMBOL(omap_mcbsp_recv_word); EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); EXPORT_SYMBOL(omap_mcbsp_recv_buffer); -EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); -EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c index 37792d437..5cc6775c7 100644 --- a/arch/arm/plat-omap/ocpi.c +++ b/arch/arm/plat-omap/ocpi.c @@ -62,6 +62,9 @@ int ocpi_enable(void) if (!cpu_is_omap16xx()) return -ENODEV; + /* Make sure there's clock for OCPI */ + clk_enable(ocpi_ck); + /* Enable access for OHCI in OCPI */ val = omap_readl(OCPI_PROT); val &= ~0xff; diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c index 1a24e2c10..093efd786 100644 --- a/arch/arm/plat-omap/pm.c +++ b/arch/arm/plat-omap/pm.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index b7bf09b1b..ee82763b0 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -16,94 +16,24 @@ #include #include +#include #include #include #include -#include - #include -#include #define OMAP1_SRAM_PA 0x20000000 #define OMAP1_SRAM_VA 0xd0000000 #define OMAP2_SRAM_PA 0x40200000 -#define OMAP2_SRAM_PUB_PA 0x4020f800 #define OMAP2_SRAM_VA 0xd0000000 -#define OMAP2_SRAM_PUB_VA 0xd0000800 -#if defined(CONFIG_ARCH_OMAP24XX) -#define SRAM_BOOTLOADER_SZ 0x00 -#else #define SRAM_BOOTLOADER_SZ 0x80 -#endif - -#define VA_REQINFOPERM0 IO_ADDRESS(0x68005048) -#define VA_READPERM0 IO_ADDRESS(0x68005050) -#define VA_WRITEPERM0 IO_ADDRESS(0x68005058) -#define VA_CONTROL_STAT IO_ADDRESS(0x480002F8) -#define GP_DEVICE 0x300 -#define TYPE_MASK 0x700 - -#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) static unsigned long omap_sram_base; static unsigned long omap_sram_size; static unsigned long omap_sram_ceil; -unsigned long omap_fb_sram_start; -unsigned long omap_fb_sram_size; - -/* Depending on the target RAMFS firewall setup, the public usable amount of - * SRAM varies. The default accessable size for all device types is 2k. A GP - * device allows ARM11 but not other initators for full size. This - * functionality seems ok until some nice security API happens. - */ -static int is_sram_locked(void) -{ - int type = 0; - - if (cpu_is_omap242x()) - type = __raw_readl(VA_CONTROL_STAT) & TYPE_MASK; - - if (type == GP_DEVICE) { - /* RAMFW: R/W access to all initators for all qualifier sets */ - if (cpu_is_omap242x()) { - __raw_writel(0xFF, VA_REQINFOPERM0); /* all q-vects */ - __raw_writel(0xCFDE, VA_READPERM0); /* all i-read */ - __raw_writel(0xCFDE, VA_WRITEPERM0); /* all i-write */ - } - return 0; - } else - return 1; /* assume locked with no PPA or security driver */ -} - -void get_fb_sram_conf(unsigned long start_avail, unsigned size_avail, - unsigned long *start, unsigned long *size) -{ - const struct omap_fbmem_config *fbmem_conf; - - fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config); - if (fbmem_conf != NULL) { - *start = fbmem_conf->fb_sram_start; - *size = fbmem_conf->fb_sram_size; - } else { - *size = 0; - *start = 0; - } - - if (*size && ( - *start < start_avail || - *start + *size > start_avail + size_avail)) { - printk(KERN_ERR "invalid FB SRAM configuration\n"); - *start = start_avail; - *size = size_avail; - } - - if (*size) - pr_info("Reserving %lu bytes SRAM for frame buffer\n", *size); -} - /* * The amount of SRAM depends on the core type. * Note that we cannot try to test for SRAM here because writes @@ -112,45 +42,26 @@ void get_fb_sram_conf(unsigned long start_avail, unsigned size_avail, */ void __init omap_detect_sram(void) { - unsigned long sram_start; - - if (cpu_is_omap24xx()) { - if (is_sram_locked()) { - omap_sram_base = OMAP2_SRAM_PUB_VA; - sram_start = OMAP2_SRAM_PUB_PA; - omap_sram_size = 0x800; /* 2K */ - } else { - omap_sram_base = OMAP2_SRAM_VA; - sram_start = OMAP2_SRAM_PA; - if (cpu_is_omap242x()) - omap_sram_size = 0xa0000; /* 640K */ - else if (cpu_is_omap243x()) - omap_sram_size = 0x10000; /* 64K */ - } - } else { + if (!cpu_is_omap24xx()) omap_sram_base = OMAP1_SRAM_VA; - sram_start = OMAP1_SRAM_PA; - - if (cpu_is_omap730()) - omap_sram_size = 0x32000; /* 200K */ - else if (cpu_is_omap15xx()) - omap_sram_size = 0x30000; /* 192K */ - else if (cpu_is_omap1610() || cpu_is_omap1621() || - cpu_is_omap1710()) - omap_sram_size = 0x4000; /* 16K */ - else if (cpu_is_omap1611()) - omap_sram_size = 0x3e800; /* 250K */ - else { - printk(KERN_ERR "Could not detect SRAM size\n"); - omap_sram_size = 0x4000; - } + else + omap_sram_base = OMAP2_SRAM_VA; + + if (cpu_is_omap730()) + omap_sram_size = 0x32000; /* 200K */ + else if (cpu_is_omap15xx()) + omap_sram_size = 0x30000; /* 192K */ + else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710()) + omap_sram_size = 0x4000; /* 16K */ + else if (cpu_is_omap1611()) + omap_sram_size = 0x3e800; /* 250K */ + else if (cpu_is_omap2420()) + omap_sram_size = 0xa0014; /* 640K */ + else { + printk(KERN_ERR "Could not detect SRAM size\n"); + omap_sram_size = 0x4000; } - get_fb_sram_conf(sram_start + SRAM_BOOTLOADER_SZ, - omap_sram_size - SRAM_BOOTLOADER_SZ, - &omap_fb_sram_start, &omap_fb_sram_size); - if (omap_fb_sram_size) - omap_sram_size -= sram_start + omap_sram_size - - omap_fb_sram_start; + omap_sram_ceil = omap_sram_base + omap_sram_size; } @@ -169,20 +80,12 @@ static struct map_desc omap_sram_io_desc[] __initdata = { */ void __init omap_map_sram(void) { - unsigned long base; - if (omap_sram_size == 0) return; if (cpu_is_omap24xx()) { omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; - - if (is_sram_locked()) - base = OMAP2_SRAM_PUB_PA; - else - base = OMAP2_SRAM_PA; - base = ROUND_DOWN(base, PAGE_SIZE); - omap_sram_io_desc[0].pfn = __phys_to_pfn(base); + omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA); } omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; @@ -190,8 +93,7 @@ void __init omap_map_sram(void) iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", - __pfn_to_phys(omap_sram_io_desc[0].pfn), - omap_sram_io_desc[0].virtual, + omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual, omap_sram_io_desc[0].length); /* @@ -216,9 +118,8 @@ void * omap_sram_push(void * start, unsigned long size) printk(KERN_ERR "Not enough space in SRAM\n"); return NULL; } - omap_sram_ceil -= size; - omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *)); + omap_sram_ceil &= ~0x3; memcpy((void *)omap_sram_ceil, start, size); return (void *)omap_sram_ceil; diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c deleted file mode 100644 index b2a943bf1..000000000 --- a/arch/arm/plat-omap/timer32k.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * linux/arch/arm/plat-omap/timer32k.c - * - * OMAP 32K Timer - * - * Copyright (C) 2004 - 2005 Nokia Corporation - * Partial timer rewrite and additional dynamic tick timer support by - * Tony Lindgen and - * Tuukka Tikkanen - * - * MPU timer code based on the older MPU timer code for OMAP - * Copyright (C) 2000 RidgeRun, Inc. - * Author: Greg Lonnon - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -struct sys_timer omap_timer; - -/* - * --------------------------------------------------------------------------- - * 32KHz OS timer - * - * This currently works only on 16xx, as 1510 does not have the continuous - * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track - * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer - * on 1510 would be possible, but the timer would not be as accurate as - * with the 32KHz synchronized timer. - * --------------------------------------------------------------------------- - */ - -#if defined(CONFIG_ARCH_OMAP16XX) -#define TIMER_32K_SYNCHRONIZED 0xfffbc410 -#elif defined(CONFIG_ARCH_OMAP24XX) -#define TIMER_32K_SYNCHRONIZED 0x48004010 -#else -#error OMAP 32KHz timer does not currently work on 15XX! -#endif - -/* 16xx specific defines */ -#define OMAP1_32K_TIMER_BASE 0xfffb9000 -#define OMAP1_32K_TIMER_CR 0x08 -#define OMAP1_32K_TIMER_TVR 0x00 -#define OMAP1_32K_TIMER_TCR 0x04 - -/* 24xx specific defines */ -#define OMAP2_GP_TIMER_BASE 0x48028000 -#define CM_CLKSEL_WKUP 0x48008440 -#define GP_TIMER_TIDR 0x00 -#define GP_TIMER_TISR 0x18 -#define GP_TIMER_TIER 0x1c -#define GP_TIMER_TCLR 0x24 -#define GP_TIMER_TCRR 0x28 -#define GP_TIMER_TLDR 0x2c -#define GP_TIMER_TTGR 0x30 -#define GP_TIMER_TSICR 0x40 - -#define OMAP_32K_TICKS_PER_HZ (32768 / HZ) - -/* - * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 - * so with HZ = 128, TVR = 255. - */ -#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) - -#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ - (((nr_jiffies) * (clock_rate)) / HZ) - -static inline void omap_32k_timer_write(int val, int reg) -{ - if (cpu_class_is_omap1()) - omap_writew(val, OMAP1_32K_TIMER_BASE + reg); - - if (cpu_is_omap24xx()) - omap_writel(val, OMAP2_GP_TIMER_BASE + reg); -} - -static inline unsigned long omap_32k_timer_read(int reg) -{ - if (cpu_class_is_omap1()) - return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff; - - if (cpu_is_omap24xx()) - return omap_readl(OMAP2_GP_TIMER_BASE + reg); -} - -/* - * The 32KHz synchronized timer is an additional timer on 16xx. - * It is always running. - */ -static inline unsigned long omap_32k_sync_timer_read(void) -{ - return omap_readl(TIMER_32K_SYNCHRONIZED); -} - -static inline void omap_32k_timer_start(unsigned long load_val) -{ - if (cpu_class_is_omap1()) { - omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); - omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); - } - - if (cpu_is_omap24xx()) { - omap_32k_timer_write(0xffffffff - load_val, GP_TIMER_TCRR); - omap_32k_timer_write((1 << 1), GP_TIMER_TIER); - omap_32k_timer_write((1 << 1) | 1, GP_TIMER_TCLR); - } -} - -static inline void omap_32k_timer_stop(void) -{ - if (cpu_class_is_omap1()) - omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR); - - if (cpu_is_omap24xx()) - omap_32k_timer_write(0x0, GP_TIMER_TCLR); -} - -/* - * Rounds down to nearest usec. Note that this will overflow for larger values. - */ -static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) -{ - return (ticks_32k * 5*5*5*5*5*5) >> 9; -} - -/* - * Rounds down to nearest nsec. - */ -static inline unsigned long long -omap_32k_ticks_to_nsecs(unsigned long ticks_32k) -{ - return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9; -} - -static unsigned long omap_32k_last_tick = 0; - -/* - * Returns elapsed usecs since last 32k timer interrupt - */ -static unsigned long omap_32k_timer_gettimeoffset(void) -{ - unsigned long now = omap_32k_sync_timer_read(); - return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); -} - -/* - * Returns current time from boot in nsecs. It's OK for this to wrap - * around for now, as it's just a relative time stamp. - */ -unsigned long long sched_clock(void) -{ - return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); -} - -/* - * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this - * function is also called from other interrupts to remove latency - * issues with dynamic tick. In the dynamic tick case, we need to lock - * with irqsave. - */ -static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - unsigned long flags; - unsigned long now; - - write_seqlock_irqsave(&xtime_lock, flags); - - if (cpu_is_omap24xx()) { - u32 status = omap_32k_timer_read(GP_TIMER_TISR); - omap_32k_timer_write(status, GP_TIMER_TISR); - } - - now = omap_32k_sync_timer_read(); - - while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { - omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; - timer_tick(regs); - } - - /* Restart timer so we don't drift off due to modulo or dynamic tick. - * By default we program the next timer to be continuous to avoid - * latencies during high system load. During dynamic tick operation the - * continuous timer can be overridden from pm_idle to be longer. - */ - omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); - write_sequnlock_irqrestore(&xtime_lock, flags); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_NO_IDLE_HZ -/* - * Programs the next timer interrupt needed. Called when dynamic tick is - * enabled, and to reprogram the ticks to skip from pm_idle. Note that - * we can keep the timer continuous, and don't need to set it to run in - * one-shot mode. This is because the timer will get reprogrammed again - * after next interrupt. - */ -void omap_32k_timer_reprogram(unsigned long next_tick) -{ - omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); -} - -static struct irqaction omap_32k_timer_irq; -extern struct timer_update_handler timer_update; - -static int omap_32k_timer_enable_dyn_tick(void) -{ - /* No need to reprogram timer, just use the next interrupt */ - return 0; -} - -static int omap_32k_timer_disable_dyn_tick(void) -{ - omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); - return 0; -} - -static struct dyn_tick_timer omap_dyn_tick_timer = { - .enable = omap_32k_timer_enable_dyn_tick, - .disable = omap_32k_timer_disable_dyn_tick, - .reprogram = omap_32k_timer_reprogram, - .handler = omap_32k_timer_interrupt, -}; -#endif /* CONFIG_NO_IDLE_HZ */ - -static struct irqaction omap_32k_timer_irq = { - .name = "32KHz timer", - .flags = SA_INTERRUPT | SA_TIMER, - .handler = omap_32k_timer_interrupt, -}; - -static struct clk * gpt1_ick; -static struct clk * gpt1_fck; - -static __init void omap_init_32k_timer(void) -{ -#ifdef CONFIG_NO_IDLE_HZ - omap_timer.dyn_tick = &omap_dyn_tick_timer; -#endif - - if (cpu_class_is_omap1()) - setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); - if (cpu_is_omap24xx()) - setup_irq(37, &omap_32k_timer_irq); - omap_timer.offset = omap_32k_timer_gettimeoffset; - omap_32k_last_tick = omap_32k_sync_timer_read(); - - /* REVISIT: Check 24xx TIOCP_CFG settings after idle works */ - if (cpu_is_omap24xx()) { - omap_32k_timer_write(0, GP_TIMER_TCLR); - omap_writel(0, CM_CLKSEL_WKUP); /* 32KHz clock source */ - - gpt1_ick = clk_get(NULL, "gpt1_ick"); - if (IS_ERR(gpt1_ick)) - printk(KERN_ERR "Could not get gpt1_ick\n"); - else - clk_enable(gpt1_ick); - - gpt1_fck = clk_get(NULL, "gpt1_fck"); - if (IS_ERR(gpt1_fck)) - printk(KERN_ERR "Could not get gpt1_fck\n"); - else - clk_enable(gpt1_fck); - - mdelay(100); /* Wait for clocks to stabilize */ - - omap_32k_timer_write(0x7, GP_TIMER_TISR); - } - - omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); -} - -/* - * --------------------------------------------------------------------------- - * Timer initialization - * --------------------------------------------------------------------------- - */ -static void __init omap_timer_init(void) -{ - omap_init_32k_timer(); -} - -struct sys_timer omap_timer = { - .init = omap_timer_init, - .offset = NULL, /* Initialized later */ -}; diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 6d7de9c04..8ab5300dc 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon May 8 20:11:05 2006 +# Last update: Mon Feb 20 10:18:02 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -566,8 +566,8 @@ switchgrass MACH_SWITCHGRASS SWITCHGRASS 549 ens_cmu MACH_ENS_CMU ENS_CMU 550 mm6_sdb MACH_MM6_SDB MM6_SDB 551 saturn MACH_SATURN SATURN 552 -i30030evb MACH_ARGONPLUSEVB ARGONPLUSEVB 553 -mxc27530evb MACH_SCMA11EVB SCMA11EVB 554 +argonplusevb MACH_ARGONPLUSEVB ARGONPLUSEVB 553 +scma11evb MACH_SCMA11EVB SCMA11EVB 554 smdk2800 MACH_SMDK2800 SMDK2800 555 mtwilson MACH_MTWILSON MTWILSON 556 ziti MACH_ZITI ZITI 557 @@ -647,7 +647,7 @@ sendt MACH_SENDT SENDT 630 mx2jazz MACH_MX2JAZZ MX2JAZZ 631 multiio MACH_MULTIIO MULTIIO 632 hrdisplay MACH_HRDISPLAY HRDISPLAY 633 -mxc27530ads MACH_SCMA11BB SCMA11BB 634 +scma11bb MACH_SCMA11BB SCMA11BB 634 trizeps3 MACH_TRIZEPS3 TRIZEPS3 635 zefeerdza MACH_ZEFEERDZA ZEFEERDZA 636 zefeerdzb MACH_ZEFEERDZB ZEFEERDZB 637 @@ -721,7 +721,7 @@ gp32 MACH_GP32 GP32 706 gem MACH_GEM GEM 707 i858 MACH_I858 I858 708 hx2750 MACH_HX2750 HX2750 709 -mxc91131evb MACH_ZEUSEVB ZEUSEVB 710 +zeusevb MACH_ZEUSEVB ZEUSEVB 710 p700 MACH_P700 P700 711 cpe MACH_CPE CPE 712 spitz MACH_SPITZ SPITZ 713 @@ -802,7 +802,7 @@ cpuat91 MACH_CPUAT91 CPUAT91 787 rea9200 MACH_REA9200 REA9200 788 acts_pune_sa1110 MACH_ACTS_PUNE_SA1110 ACTS_PUNE_SA1110 789 ixp425 MACH_IXP425 IXP425 790 -i30030ads MACH_ARGONPLUSODYSSEY ARGONPLUSODYSSEY 791 +argonplusodyssey MACH_ARGONPLUSODYSSEY ARGONPLUSODYSSEY 791 perch MACH_PERCH PERCH 792 eis05r1 MACH_EIS05R1 EIS05R1 793 pepperpad MACH_PEPPERPAD PEPPERPAD 794 @@ -827,7 +827,7 @@ micro9l MACH_MICRO9L MICRO9L 812 uc5471dsp MACH_UC5471DSP UC5471DSP 813 sj5471eng MACH_SJ5471ENG SJ5471ENG 814 none MACH_CMPXA26X CMPXA26X 815 -nc1 MACH_NC NC 816 +nc MACH_NC NC 816 omap_palmte MACH_OMAP_PALMTE OMAP_PALMTE 817 ajax52x MACH_AJAX52X AJAX52X 818 siriustar MACH_SIRIUSTAR SIRIUSTAR 819 @@ -930,7 +930,7 @@ netclient MACH_NETCLIENT NETCLIENT 916 xscale_palmtt5 MACH_XSCALE_PALMTT5 XSCALE_PALMTT5 917 xscale_palmtc MACH_OMAP_PALMTC OMAP_PALMTC 918 omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 -mxc30030evb MACH_ARGONLVEVB ARGONLVEVB 920 +argonlvevb MACH_ARGONLVEVB ARGONLVEVB 920 rea_2d MACH_REA_2D REA_2D 921 eti3e524 MACH_TI3E524 TI3E524 922 ateb9200 MACH_ATEB9200 ATEB9200 923 @@ -965,78 +965,7 @@ sisteron MACH_SISTERON SISTERON 951 rx1950 MACH_RX1950 RX1950 952 tsc_venus MACH_TSC_VENUS TSC_VENUS 953 ds101j MACH_DS101J DS101J 954 -mxc30030ads MACH_MXC30030ADS MXC30030ADS 955 +mxc300_30ads MACH_MXC30030ADS MXC30030ADS 955 fujitsu_wimaxsoc MACH_FUJITSU_WIMAXSOC FUJITSU_WIMAXSOC 956 dualpcmodem MACH_DUALPCMODEM DUALPCMODEM 957 gesbc9312 MACH_GESBC9312 GESBC9312 958 -htcapache MACH_HTCAPACHE HTCAPACHE 959 -ixdp435 MACH_IXDP435 IXDP435 960 -catprovt100 MACH_CATPROVT100 CATPROVT100 961 -picotux1xx MACH_PICOTUX1XX PICOTUX1XX 962 -picotux2xx MACH_PICOTUX2XX PICOTUX2XX 963 -dsmg600 MACH_DSMG600 DSMG600 964 -empc2 MACH_EMPC2 EMPC2 965 -ventura MACH_VENTURA VENTURA 966 -phidget_sbc MACH_PHIDGET_SBC PHIDGET_SBC 967 -ij3k MACH_IJ3K IJ3K 968 -pisgah MACH_PISGAH PISGAH 969 -omap_fsample MACH_OMAP_FSAMPLE OMAP_FSAMPLE 970 -sg720 MACH_SG720 SG720 971 -redfox MACH_REDFOX REDFOX 972 -mysh_ep9315_1 MACH_MYSH_EP9315_1 MYSH_EP9315_1 973 -tpf106 MACH_TPF106 TPF106 974 -at91rm9200kg MACH_AT91RM9200KG AT91RM9200KG 975 -racemt2 MACH_SLEDB SLEDB 976 -ontrack MACH_ONTRACK ONTRACK 977 -pm1200 MACH_PM1200 PM1200 978 -ess24562 MACH_ESS24XXX ESS24XXX 979 -coremp7 MACH_COREMP7 COREMP7 980 -nexcoder_6446 MACH_NEXCODER_6446 NEXCODER_6446 981 -stvc8380 MACH_STVC8380 STVC8380 982 -teklynx MACH_TEKLYNX TEKLYNX 983 -carbonado MACH_CARBONADO CARBONADO 984 -sysmos_mp730 MACH_SYSMOS_MP730 SYSMOS_MP730 985 -snapper_cl15 MACH_SNAPPER_CL15 SNAPPER_CL15 986 -pgigim MACH_PGIGIM PGIGIM 987 -ptx9160p2 MACH_PTX9160P2 PTX9160P2 988 -dcore1 MACH_DCORE1 DCORE1 989 -victorpxa MACH_VICTORPXA VICTORPXA 990 -mx2dtb MACH_MX2DTB MX2DTB 991 -pxa_irex_er0100 MACH_PXA_IREX_ER0100 PXA_IREX_ER0100 992 -omap_palmz71 MACH_OMAP_PALMZ71 OMAP_PALMZ71 993 -bartec_deg MACH_BARTEC_DEG BARTEC_DEG 994 -hw50251 MACH_HW50251 HW50251 995 -ibox MACH_IBOX IBOX 996 -atlaslh7a404 MACH_ATLASLH7A404 ATLASLH7A404 997 -pt2026 MACH_PT2026 PT2026 998 -htcalpine MACH_HTCALPINE HTCALPINE 999 -bartec_vtu MACH_BARTEC_VTU BARTEC_VTU 1000 -vcoreii MACH_VCOREII VCOREII 1001 -pdnb3 MACH_PDNB3 PDNB3 1002 -htcbeetles MACH_HTCBEETLES HTCBEETLES 1003 -s3c6400 MACH_S3C6400 S3C6400 1004 -s3c2443 MACH_S3C2443 S3C2443 1005 -omap_ldk MACH_OMAP_LDK OMAP_LDK 1006 -smdk2460 MACH_SMDK2460 SMDK2460 1007 -smdk2440 MACH_SMDK2440 SMDK2440 1008 -smdk2412 MACH_SMDK2412 SMDK2412 1009 -webbox MACH_WEBBOX WEBBOX 1010 -cwwndp MACH_CWWNDP CWWNDP 1011 -dragon MACH_DRAGON DRAGON 1012 -opendo_cpu_board MACH_OPENDO_CPU_BOARD OPENDO_CPU_BOARD 1013 -ccm2200 MACH_CCM2200 CCM2200 1014 -etwarm MACH_ETWARM ETWARM 1015 -m93030 MACH_M93030 M93030 1016 -cc7u MACH_CC7U CC7U 1017 -mtt_ranger MACH_MTT_RANGER MTT_RANGER 1018 -nexus MACH_NEXUS NEXUS 1019 -desman MACH_DESMAN DESMAN 1020 -bkde303 MACH_BKDE303 BKDE303 1021 -smdk2413 MACH_SMDK2413 SMDK2413 1022 -aml_m7200 MACH_AML_M7200 AML_M7200 1023 -aml_m5900 MACH_AML_M5900 AML_M5900 1024 -sg640 MACH_SG640 SG640 1025 -edg79524 MACH_EDG79524 EDG79524 1026 -ai2410 MACH_AI2410 AI2410 1027 -ixp465 MACH_IXP465 IXP465 1028 -balloon3 MACH_BALLOON3 BALLOON3 1029 diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index e73c8deca..6f17187ab 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -17,7 +17,7 @@ */ #include #include -#include +#include #include .globl do_vfp diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 009038c81..9b367a65c 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -197,7 +197,7 @@ u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exce dd, d, exceptions); vfp_put_double(dd, d); } - return exceptions; + return exceptions & ~VFP_NAN_FLAG; } /* @@ -588,7 +588,6 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) struct vfp_double vdm; u32 d, exceptions = 0; int rmode = fpscr & FPSCR_RMODE_MASK; - int tm; vfp_double_unpack(&vdm, vfp_get_double(dm)); vfp_double_dump("VDM", &vdm); @@ -596,14 +595,10 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) /* * Do we have denormalised number? */ - tm = vfp_double_type(&vdm); - if (tm & VFP_DENORMAL) + if (vfp_double_type(&vdm) & VFP_DENORMAL) exceptions |= FPSCR_IDC; - if (tm & VFP_NAN) { - d = 0; - exceptions |= FPSCR_IOC; - } else if (vdm.exponent >= 1023 + 32) { + if (vdm.exponent >= 1023 + 32) { d = 0x7fffffff; if (vdm.sign) d = ~d; @@ -1127,9 +1122,9 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) { u32 op = inst & FOP_MASK; u32 exceptions = 0; - unsigned int dd = vfp_get_dd(inst); - unsigned int dn = vfp_get_dn(inst); - unsigned int dm = vfp_get_dm(inst); + unsigned int dd = vfp_get_sd(inst); + unsigned int dn = vfp_get_sn(inst); + unsigned int dm = vfp_get_sm(inst); unsigned int vecitr, veclen, vecstride; u32 (*fop)(int, int, s32, u32); @@ -1146,7 +1141,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, (veclen >> FPSCR_LENGTH_BIT) + 1); - fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; + fop = (op == FOP_EXT) ? fop_extfns[dn] : fop_fns[FOP_TO_IDX(op)]; if (!fop) goto invalid; @@ -1154,13 +1149,17 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) u32 except; if (op == FOP_EXT) - pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n", + pr_debug("VFP: itr%d (d%u.%u) = op[%u] (d%u.%u)\n", vecitr >> FPSCR_LENGTH_BIT, - dd, dn, dm); + dd >> 1, dd & 1, dn, + dm >> 1, dm & 1); else - pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n", + pr_debug("VFP: itr%d (d%u.%u) = (d%u.%u) op[%u] (d%u.%u)\n", vecitr >> FPSCR_LENGTH_BIT, - dd, dn, FOP_TO_IDX(op), dm); + dd >> 1, dd & 1, + dn >> 1, dn & 1, + FOP_TO_IDX(op), + dm >> 1, dm & 1); except = fop(dd, dn, dm, fpscr); pr_debug("VFP: itr%d: exceptions=%08x\n", diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index a3f65b47a..de4ca1223 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -102,6 +102,7 @@ vfp_support_entry: VFPFMRX r8, FPINST2, NE @ FPINST2 if needed - avoids reading @ nonexistant reg on rev0 VFPFSTMIA r4 @ save the working registers + add r4, r4, #8*16+4 stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2 @ and point r4 at the word at the @ start of the register dump @@ -110,9 +111,10 @@ no_old_VFP_process: DBGSTR1 "load state %p", r10 str r10, [r3] @ update the last_VFP_context pointer @ Load the saved state back into the VFP + add r4, r10, #8*16+4 + ldmia r4, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2 VFPFLDMIA r10 @ reload the working registers while @ FPEXC is in a safe state - ldmia r10, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2 tst r1, #FPEXC_FPV2 @ is there an FPINST2 to write? VFPFMXR FPINST2, r8, NE @ FPINST2 if needed - avoids writing @ nonexistant reg on rev0 @@ -189,10 +191,11 @@ vfp_put_float: .globl vfp_get_double vfp_get_double: + mov r0, r0, lsr #1 add pc, pc, r0, lsl #3 mov r0, r0 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 - mrrc p11, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr + mrrc p10, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr mov pc, lr .endr @@ -203,9 +206,10 @@ vfp_get_double: .globl vfp_put_double vfp_put_double: + mov r0, r0, lsr #1 add pc, pc, r0, lsl #3 mov r0, r0 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 - mcrr p11, 1, r1, r2, c\dr @ fmdrr r1, r2, d\dr + mcrr p10, 1, r1, r2, c\dr @ fmrrd r1, r2, d\dr mov pc, lr .endr diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 03486be04..22f3da4e0 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -180,7 +180,7 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) * emulate it. */ } - return exceptions & ~VFP_NAN_FLAG; + return exceptions; } /* @@ -245,7 +245,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) */ barrier(); trigger = fmrx(FPINST2); - orig_fpscr = fpscr = fmrx(FPSCR); + fpscr = fmrx(FPSCR); emulate: exceptions = vfp_emulate_instruction(trigger, fpscr, regs); diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index dae2c2f46..14dd696dd 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -203,7 +203,7 @@ u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exce vfp_put_float(sd, d); } - return exceptions; + return exceptions & ~VFP_NAN_FLAG; } /* @@ -632,7 +632,6 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) struct vfp_single vsm; u32 d, exceptions = 0; int rmode = fpscr & FPSCR_RMODE_MASK; - int tm; vfp_single_unpack(&vsm, m); vfp_single_dump("VSM", &vsm); @@ -640,14 +639,10 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) /* * Do we have a denormalised number? */ - tm = vfp_single_type(&vsm); if (vfp_single_type(&vsm) & VFP_DENORMAL) exceptions |= FPSCR_IDC; - if (tm & VFP_NAN) { - d = 0; - exceptions |= FPSCR_IOC; - } else if (vsm.exponent >= 127 + 32) { + if (vsm.exponent >= 127 + 32) { /* * m >= 2^31-2^7: invalid */ @@ -1193,7 +1188,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, (veclen >> FPSCR_LENGTH_BIT) + 1); - fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; + fop = (op == FOP_EXT) ? fop_extfns[sn] : fop_fns[FOP_TO_IDX(op)]; if (!fop) goto invalid; diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig index 14523899a..76d40545a 100644 --- a/arch/arm26/Kconfig +++ b/arch/arm26/Kconfig @@ -41,10 +41,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config GENERIC_HWEIGHT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y diff --git a/arch/arm26/Makefile b/arch/arm26/Makefile index fe91eda98..844a9e468 100644 --- a/arch/arm26/Makefile +++ b/arch/arm26/Makefile @@ -1,9 +1,6 @@ # # arch/arm26/Makefile # -# This file is included by the global makefile so that you can add your own -# architecture-specific flags and dependencies. -# # 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. @@ -52,9 +49,9 @@ all: zImage boot := arch/arm26/boot -PHONY += maketools FORCE +.PHONY: maketools FORCE maketools: FORCE - + # Convert bzImage to zImage bzImage: vmlinux diff --git a/arch/arm26/boot/Makefile b/arch/arm26/boot/Makefile index 68acb7b0d..b5c227765 100644 --- a/arch/arm26/boot/Makefile +++ b/arch/arm26/boot/Makefile @@ -1,9 +1,6 @@ # # arch/arm26/boot/Makefile # -# This file is included by the global makefile so that you can add your own -# architecture-specific flags and dependencies. -# # 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. @@ -63,7 +60,7 @@ $(obj)/xipImage: vmlinux FORCE @echo ' Kernel: $@ is ready' endif -PHONY += initrd +.PHONY: initrd initrd: @test "$(INITRD_PHYS)" != "" || \ (echo This machine does not support INITRD; exit -1) diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c index 9d66c27f2..811a6376c 100644 --- a/arch/arm26/kernel/armksyms.c +++ b/arch/arm26/kernel/armksyms.c @@ -152,6 +152,7 @@ EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strchr); EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(memset); @@ -211,6 +212,8 @@ EXPORT_SYMBOL(sys_open); EXPORT_SYMBOL(sys_exit); EXPORT_SYMBOL(sys_wait4); +EXPORT_SYMBOL(get_wchan); + #ifdef CONFIG_PREEMPT EXPORT_SYMBOL(kernel_flag); #endif diff --git a/arch/arm26/kernel/traps.c b/arch/arm26/kernel/traps.c index 4eea07403..4110862f1 100644 --- a/arch/arm26/kernel/traps.c +++ b/arch/arm26/kernel/traps.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include "ptrace.h" @@ -208,19 +208,19 @@ void die_if_kernel(const char *str, struct pt_regs *regs, int err) die(str, regs, err); } -static DEFINE_MUTEX(undef_mutex); +static DECLARE_MUTEX(undef_sem); static int (*undef_hook)(struct pt_regs *); int request_undef_hook(int (*fn)(struct pt_regs *)) { int ret = -EBUSY; - mutex_lock(&undef_mutex); + down(&undef_sem); if (undef_hook == NULL) { undef_hook = fn; ret = 0; } - mutex_unlock(&undef_mutex); + up(&undef_sem); return ret; } @@ -229,12 +229,12 @@ int release_undef_hook(int (*fn)(struct pt_regs *)) { int ret = -EINVAL; - mutex_lock(&undef_mutex); + down(&undef_sem); if (undef_hook == fn) { undef_hook = NULL; ret = 0; } - mutex_unlock(&undef_mutex); + up(&undef_sem); return ret; } diff --git a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c index 7da8a5205..1f09a9d0f 100644 --- a/arch/arm26/mm/init.c +++ b/arch/arm26/mm/init.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -102,6 +101,12 @@ struct node_info { int bootmap_pages; }; +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT) +#define PFN_SIZE(x) ((x) >> PAGE_SHIFT) +#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \ + (((unsigned long)(s)) & PAGE_MASK)) + /* * FIXME: We really want to avoid allocating the bootmap bitmap * over the top of the initrd. Hopefully, this is located towards @@ -319,7 +324,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s) for (; addr < end; addr += PAGE_SIZE) { struct page *page = virt_to_page(addr); ClearPageReserved(page); - init_page_count(page); + set_page_count(page, 1); free_page(addr); totalram_pages++; } diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 147014630..4afa4318a 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -16,14 +16,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_HWEIGHT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index c59ee28a3..501fa52d8 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -2944,7 +2944,7 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig int spdl_err; /* Mark output pages dirty. */ spdl_err = set_page_dirty_lock(outpages[i]); - DEBUG(if (spdl_err < 0)printk("cryptocop_ioctl_process: set_page_dirty_lock returned %d\n", spdl_err)); + DEBUG(if (spdl_err)printk("cryptocop_ioctl_process: set_page_dirty_lock returned %d\n", spdl_err)); } for (i = 0; i < nooutpages; i++){ put_page(outpages[i]); diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c index d57859053..de39725da 100644 --- a/arch/cris/kernel/crisksyms.c +++ b/arch/cris/kernel/crisksyms.c @@ -39,6 +39,7 @@ EXPORT_SYMBOL(loops_per_usec); /* String functions */ EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strchr); diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index b504def3e..30deaf1b7 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c @@ -52,8 +52,9 @@ int show_interrupts(struct seq_file *p, void *v) if (i == 0) { seq_printf(p, " "); - for_each_online_cpu(j) - seq_printf(p, "CPU%d ",j); + for (j=0; jtypename); seq_printf(p, " %s", action->name); diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index 123451c44..4ab3e8711 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c @@ -116,7 +116,6 @@ #include #include #include -#include #include #include #include @@ -195,6 +194,8 @@ EXPORT_SYMBOL(enable_hlt); */ void (*pm_idle)(void); +extern void default_idle(void); + /* * The idle thread. There's no useful work to be * done, so just try to conserve power and have a diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index 619a6eefd..1ba57efff 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -18,7 +18,6 @@ #include #include #include -#include #include @@ -89,6 +88,10 @@ setup_arch(char **cmdline_p) init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) + /* min_low_pfn points to the start of DRAM, start_pfn points * to the first DRAM pages after the kernel, and max_low_pfn * to the end of DRAM. diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index b7842ff21..31a0018b5 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c @@ -216,7 +216,7 @@ free_initmem(void) addr = (unsigned long)(&__init_begin); for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); + set_page_count(virt_to_page(addr), 1); free_page(addr); totalram_pages++; } diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 95a3892b8..e08383712 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -17,10 +17,6 @@ config GENERIC_FIND_NEXT_BIT bool default y -config GENERIC_HWEIGHT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default n diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index a9b59527a..1d21c8d34 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1170,6 +1170,12 @@ __syscall_badsys: # syscall vector table # ############################################################################### +#ifdef CONFIG_MMU +#define __MMU(X) X +#else +#define __MMU(X) sys_ni_syscall +#endif + .section .rodata ALIGN .globl sys_call_table @@ -1299,7 +1305,7 @@ sys_call_table: .long sys_newuname .long sys_ni_syscall /* old "cacheflush" */ .long sys_adjtimex - .long sys_mprotect /* 125 */ + .long __MMU(sys_mprotect) /* 125 */ .long sys_sigprocmask .long sys_ni_syscall /* old "create_module" */ .long sys_init_module @@ -1318,16 +1324,16 @@ sys_call_table: .long sys_getdents .long sys_select .long sys_flock - .long sys_msync + .long __MMU(sys_msync) .long sys_readv /* 145 */ .long sys_writev .long sys_getsid .long sys_fdatasync .long sys_sysctl - .long sys_mlock /* 150 */ - .long sys_munlock - .long sys_mlockall - .long sys_munlockall + .long __MMU(sys_mlock) /* 150 */ + .long __MMU(sys_munlock) + .long __MMU(sys_mlockall) + .long __MMU(sys_munlockall) .long sys_sched_setparam .long sys_sched_getparam /* 155 */ .long sys_sched_setscheduler @@ -1337,7 +1343,7 @@ sys_call_table: .long sys_sched_get_priority_min /* 160 */ .long sys_sched_rr_get_interval .long sys_nanosleep - .long sys_mremap + .long __MMU(sys_mremap) .long sys_setresuid16 .long sys_getresuid16 /* 165 */ .long sys_ni_syscall /* for vm86 */ @@ -1392,8 +1398,8 @@ sys_call_table: .long sys_setfsuid /* 215 */ .long sys_setfsgid .long sys_pivot_root - .long sys_mincore - .long sys_madvise + .long __MMU(sys_mincore) + .long __MMU(sys_madvise) .long sys_getdents64 /* 220 */ .long sys_fcntl64 .long sys_ni_syscall /* reserved for TUX */ @@ -1431,7 +1437,7 @@ sys_call_table: .long sys_epoll_create .long sys_epoll_ctl /* 255 */ .long sys_epoll_wait - .long sys_remap_file_pages + .long __MMU(sys_remap_file_pages) .long sys_set_tid_address .long sys_timer_create .long sys_timer_settime /* 260 */ diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index 0f273a7ac..0f1c6cbc4 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c @@ -78,6 +78,8 @@ EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__outsl_ns); EXPORT_SYMBOL(__insl_ns); +EXPORT_SYMBOL(get_wchan); + #ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS EXPORT_SYMBOL(atomic_test_and_ANDNOT_mask); EXPORT_SYMBOL(atomic_test_and_OR_mask); diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c index 508601fad..8f860d9c4 100644 --- a/arch/frv/kernel/gdb-stub.c +++ b/arch/frv/kernel/gdb-stub.c @@ -1406,7 +1406,7 @@ void gdbstub(int sigval) __debug_frame->psr |= PSR_S; __debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12; __debug_regs->brr |= BRR_EB; - sigval = SIGXCPU; + sigval = SIGXCPU;; } LEDS(0x5002); diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c index 11fa326a8..27ab4c30a 100644 --- a/arch/frv/kernel/irq.c +++ b/arch/frv/kernel/irq.c @@ -75,8 +75,9 @@ int show_interrupts(struct seq_file *p, void *v) switch (i) { case 0: seq_printf(p, " "); - for_each_online_cpu(j) - seq_printf(p, "CPU%d ",j); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "CPU%d ",j); seq_putc(p, '\n'); break; @@ -99,8 +100,9 @@ int show_interrupts(struct seq_file *p, void *v) #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 - 1]); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i - 1]); #endif level = group->sources[ix]->level - frv_irq_levels; diff --git a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c index 636b2f8b5..342823aad 100644 --- a/arch/frv/mm/dma-alloc.c +++ b/arch/frv/mm/dma-alloc.c @@ -115,7 +115,9 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle) */ if (order > 0) { struct page *rpage = virt_to_page(page); - split_page(rpage, order); + + for (i = 1; i < (1 << order); i++) + set_page_count(rpage + i, 1); } err = 0; diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c index 8899aa1a4..765088ea8 100644 --- a/arch/frv/mm/init.c +++ b/arch/frv/mm/init.c @@ -169,7 +169,7 @@ void __init mem_init(void) struct page *page = &mem_map[pfn]; ClearPageReserved(page); - init_page_count(page); + set_page_count(page, 1); __free_page(page); totalram_pages++; } @@ -210,7 +210,7 @@ void __init free_initmem(void) /* next to check that the page we free is not a partial page */ for (addr = start; addr < end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); + set_page_count(virt_to_page(addr), 1); free_page(addr); totalram_pages++; } @@ -230,7 +230,7 @@ void __init 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)); + set_page_count(virt_to_page(start), 1); free_page(start); totalram_pages++; pages++; diff --git a/arch/frv/mm/mmu-context.c b/arch/frv/mm/mmu-context.c index 27c54a1e0..6983198ca 100644 --- a/arch/frv/mm/mmu-context.c +++ b/arch/frv/mm/mmu-context.c @@ -55,9 +55,9 @@ static unsigned get_cxn(mm_context_t *ctx) /* find the first unallocated context number * - 0 is reserved for the kernel */ - cxn = find_next_zero_bit(cxn_bitmap, NR_CXN, 1); + cxn = find_next_zero_bit(&cxn_bitmap, NR_CXN, 1); if (cxn < NR_CXN) { - set_bit(cxn, cxn_bitmap); + set_bit(cxn, &cxn_bitmap); } else { /* none remaining - need to steal someone else's cxn */ @@ -139,7 +139,7 @@ void destroy_context(struct mm_struct *mm) cxn_pinned = -1; list_del_init(&ctx->id_link); - clear_bit(ctx->id, cxn_bitmap); + clear_bit(ctx->id, &cxn_bitmap); __flush_tlb_mm(ctx->id); ctx->id = 0; } diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 3f2426d37..a6038b070 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -29,14 +29,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default n -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_HWEIGHT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c index f8d6dee84..5cc76efaf 100644 --- a/arch/h8300/kernel/h8300_ksyms.c +++ b/arch/h8300/kernel/h8300_ksyms.c @@ -54,6 +54,8 @@ EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(get_wchan); + /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index 16ccddc69..dd344f112 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -54,7 +54,7 @@ asmlinkage void ret_from_fork(void); * The idle loop on an H8/300.. */ #if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM) -static void default_idle(void) +void default_idle(void) { local_irq_disable(); if (!need_resched()) { @@ -65,7 +65,7 @@ static void default_idle(void) local_irq_enable(); } #else -static void default_idle(void) +void default_idle(void) { cpu_relax(); } diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c index 09efc4b1f..1e0929ddc 100644 --- a/arch/h8300/mm/init.c +++ b/arch/h8300/mm/init.c @@ -196,7 +196,7 @@ 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)); + set_page_count(virt_to_page(start), 1); free_page(start); totalram_pages++; pages++; @@ -219,7 +219,7 @@ free_initmem() /* next to check that the page we free is not a partial page */ for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); + set_page_count(virt_to_page(addr), 1); free_page(addr); totalram_pages++; } diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index d75fa4047..20d835e0d 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -37,10 +37,6 @@ config GENERIC_IOMAP bool default y -config GENERIC_HWEIGHT - bool - default y - config ARCH_MAY_HAVE_PC_FDC bool default y @@ -53,35 +49,6 @@ source "init/Kconfig" menu "Processor type and features" -config SMP - bool "Symmetric multi-processing support" - ---help--- - This enables support for systems with more than one CPU. If you have - a system with only one CPU, like most personal computers, say N. If - you have a system with more than one CPU, say Y. - - If you say N here, the kernel will run on single and multiprocessor - machines, but will use only one CPU of a multiprocessor machine. If - you say Y here, the kernel will run on many, but not all, - singleprocessor machines. On a singleprocessor machine, the kernel - will run faster if you say N here. - - Note that if you say Y here and choose architecture "586" or - "Pentium" under "Processor family", the kernel will not work on 486 - architectures. Similarly, multiprocessor kernels for the "PPro" - architecture may not work on all Pentium based boards. - - People using multiprocessor machines who say Y here should also say - Y to "Enhanced Real Time Clock Support", below. The "Advanced Power - Management" code will be disabled if you say Y here. - - See also the , - , - and the SMP-HOWTO available at - . - - If you don't know what to do here, say N. - choice prompt "Subarchitecture Type" default X86_PC @@ -91,15 +58,6 @@ config X86_PC help Choose this option if your computer is a standard PC or compatible. -config X86_XEN - bool "Xen-compatible" - select X86_UP_APIC if !SMP && XEN_PRIVILEGED_GUEST - select X86_UP_IOAPIC if !SMP && XEN_PRIVILEGED_GUEST - select SWIOTLB - help - Choose this option if you plan to run this kernel on top of the - Xen Hypervisor. - config X86_ELAN bool "AMD Elan" help @@ -122,7 +80,6 @@ config X86_VOYAGER config X86_NUMAQ bool "NUMAQ (IBM/Sequent)" - select SMP select NUMA help This option is used for getting Linux to run on a (IBM/Sequent) NUMA @@ -202,7 +159,6 @@ source "arch/i386/Kconfig.cpu" config HPET_TIMER bool "HPET Timer Support" - depends on !X86_XEN help This enables the use of the HPET for the kernel's internal timer. HPET is the next generation timer replacing legacy 8254s. @@ -217,6 +173,35 @@ config HPET_EMULATE_RTC depends on HPET_TIMER && RTC=y default y +config SMP + bool "Symmetric multi-processing support" + ---help--- + This enables support for systems with more than one CPU. If you have + a system with only one CPU, like most personal computers, say N. If + you have a system with more than one CPU, say Y. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on many, but not all, + singleprocessor machines. On a singleprocessor machine, the kernel + will run faster if you say N here. + + Note that if you say Y here and choose architecture "586" or + "Pentium" under "Processor family", the kernel will not work on 486 + architectures. Similarly, multiprocessor kernels for the "PPro" + architecture may not work on all Pentium based boards. + + People using multiprocessor machines who say Y here should also say + Y to "Enhanced Real Time Clock Support", below. The "Advanced Power + Management" code will be disabled if you say Y here. + + See also the , + , + and the SMP-HOWTO available at + . + + If you don't know what to do here, say N. + config NR_CPUS int "Maximum number of CPUs (2-255)" range 2 255 @@ -233,7 +218,7 @@ config NR_CPUS config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" - depends on SMP && !X86_XEN + depends on SMP default off help SMT scheduler support improves the CPU scheduler's decision making @@ -241,20 +226,11 @@ config SCHED_SMT cost of slightly increased overhead in some places. If unsure say N here. -config SCHED_MC - bool "Multi-core scheduler support" - depends on SMP && !X86_XEN - default y - help - Multi-core scheduler support improves the CPU scheduler's decision - making when dealing with multi-core CPU chips at a cost of slightly - increased overhead in some places. If unsure say N here. - source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on !SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST) + depends on !SMP && !(X86_VISWS || X86_VOYAGER) help A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU @@ -279,12 +255,12 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC bool - depends on X86_UP_APIC || ((X86_VISWS || SMP) && !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)) + depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) default y config X86_IO_APIC bool - depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)) + depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) default y config X86_VISWS_APIC @@ -292,14 +268,9 @@ config X86_VISWS_APIC depends on X86_VISWS default y -config X86_TSC - bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ && !X86_XEN - default y - config X86_MCE bool "Machine Check Exception" - depends on !(X86_VOYAGER || X86_XEN) + depends on !X86_VOYAGER ---help--- Machine Check Exception support allows the processor to notify the kernel if it detects a problem (e.g. overheating, component failure). @@ -389,7 +360,6 @@ config X86_REBOOTFIXUPS config MICROCODE tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" - depends on !XEN_UNPRIVILEGED_GUEST ---help--- If you say Y here and also to "/dev file system support" in the 'File systems' section, you will be able to update the microcode on @@ -407,7 +377,6 @@ config MICROCODE config X86_MSR tristate "/dev/cpu/*/msr - Model-specific register support" - depends on !X86_XEN help This device gives privileged processes access to the x86 Model-Specific Registers (MSRs). It is a character device with @@ -423,10 +392,6 @@ config X86_CPUID with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to /dev/cpu/31/cpuid. -config SWIOTLB - bool - default n - source "drivers/firmware/Kconfig" choice @@ -435,7 +400,6 @@ choice config NOHIGHMEM bool "off" - depends on !X86_NUMAQ ---help--- Linux can use up to 64 Gigabytes of physical memory on x86 systems. However, the address space of 32-bit x86 processors is only 4 @@ -472,7 +436,6 @@ config NOHIGHMEM config HIGHMEM4G bool "4GB" - depends on !X86_NUMAQ help Select this if you have a 32-bit processor and between 1 and 4 gigabytes of physical RAM. @@ -488,7 +451,7 @@ endchoice choice depends on EXPERIMENTAL && !X86_PAE - prompt "Memory split" if EMBEDDED + prompt "Memory split" default VMSPLIT_3G help Select the desired split between kernel and user memory. @@ -503,23 +466,43 @@ choice will also likely make your kernel incompatible with binary-only kernel modules. - If you are not absolutely sure what you are doing, leave this - option alone! - config VMSPLIT_3G - bool "3G/1G user/kernel split" - config VMSPLIT_3G_OPT - bool "3G/1G user/kernel split (for full 1G low memory)" + bool "3G/1G user/kernel split (Default)" + help + This is the default split of 3GB userspace to 1GB kernel + space, which will result in about 860MB of lowmem. + + config VMSPLIT_25G + bool "2.5G/1.5G user/kernel split" + help + This split provides 2.5GB userspace and 1.5GB kernel + space, which will result in about 1370MB of lowmem. + config VMSPLIT_2G bool "2G/2G user/kernel split" + help + This split provides 2GB userspace and 2GB kernel + space, which will result in about 1880MB of lowmem. + + config VMSPLIT_15G + bool "1.5G/2.5G user/kernel split" + help + This split provides 1.5GB userspace and 2.5GB kernel + space, which will result in about 2390MB of lowmem. + config VMSPLIT_1G bool "1G/3G user/kernel split" + help + This split provides 1GB userspace and 3GB kernel + space, which will result in about 2900MB of lowmem. + endchoice config PAGE_OFFSET hex - default 0xB0000000 if VMSPLIT_3G_OPT - default 0x78000000 if VMSPLIT_2G + default 0xA0000000 if VMSPLIT_25G + default 0x80000000 if VMSPLIT_2G + default 0x60000000 if VMSPLIT_15G default 0x40000000 if VMSPLIT_1G default 0xC0000000 @@ -540,15 +523,13 @@ config NUMA default n if X86_PC default y if (X86_NUMAQ || X86_SUMMIT) +# Need comments to help the hapless user trying to turn on NUMA support +comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" + depends on X86_NUMAQ && (!HIGHMEM64G || !SMP) + comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) -config NODES_SHIFT - int - default "4" if X86_NUMAQ - default "3" - depends on NEED_MULTIPLE_NODES - config HAVE_ARCH_BOOTMEM_NODE bool depends on NUMA @@ -599,7 +580,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" - depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN + depends on HIGHMEM4G || HIGHMEM64G help The VM uses one page table entry for each page of physical memory. For systems with a lot of RAM, this can be wasteful of precious @@ -608,7 +589,6 @@ config HIGHPTE config MATH_EMULATION bool "Math emulation" - depends on !X86_XEN ---help--- Linux can emulate a math coprocessor (used for floating point operations) if you don't have one. 486DX and Pentium processors have @@ -634,8 +614,6 @@ config MATH_EMULATION config MTRR bool "MTRR (Memory Type Range Register) support" - depends on !XEN_UNPRIVILEGED_GUEST - default y if X86_XEN ---help--- On Intel P6 family processors (Pentium Pro, Pentium II and later) the Memory Type Range Registers (MTRRs) may be used to control @@ -670,7 +648,7 @@ config MTRR config EFI bool "Boot from EFI support (EXPERIMENTAL)" - depends on ACPI && !X86_XEN + depends on ACPI default n ---help--- This enables the the kernel to boot on EFI platforms using @@ -688,7 +666,7 @@ config EFI config IRQBALANCE bool "Enable kernel irq balancing" - depends on SMP && X86_IO_APIC && !X86_XEN + depends on SMP && X86_IO_APIC default y help The default yes will allow the kernel to do irq load balancing. @@ -702,18 +680,13 @@ config BOOT_IOREMAP default y config REGPARM - bool "Use register arguments" - default y + bool "Use register arguments (EXPERIMENTAL)" + depends on EXPERIMENTAL + default n help - Compile the kernel with -mregparm=3. This instructs gcc to use - a more efficient function call ABI which passes the first three - arguments of a function call via registers, which results in denser - and faster code. - - If this option is disabled, then the default ABI of passing - arguments via the stack is used. - - If unsure, say Y. + Compile the kernel with -mregparm=3. This uses a different ABI + and passes the first three arguments of a function call in registers. + This will probably break binary only modules. config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" @@ -736,7 +709,7 @@ source kernel/Kconfig.hz config KEXEC bool "kexec system call (EXPERIMENTAL)" - depends on EXPERIMENTAL && !X86_XEN + depends on 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 @@ -759,7 +732,7 @@ config CRASH_DUMP Generate crash dump after being started by kexec. config PHYSICAL_START - hex "Physical address where the kernel is loaded" + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) default "0x1000000" if CRASH_DUMP default "0x100000" @@ -782,10 +755,19 @@ config HOTPLUG_CPU bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER ---help--- - Say Y here to experiment with turning CPUs off and on, and to - enable suspend on SMP systems. CPUs can be controlled through - /sys/devices/system/cpu. + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu. + Say N. + +config DOUBLEFAULT + default y + bool "Enable doublefault exception handler" if EMBEDDED + help + This option allows trapping of rare doublefault exceptions that + would otherwise cause a system to silently reboot. Disabling this + option saves about 4k and might cause you much additional grey + hair. endmenu @@ -794,20 +776,18 @@ config ARCH_ENABLE_MEMORY_HOTPLUG depends on HIGHMEM menu "Power management options (ACPI, APM)" - depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST) + depends on !X86_VOYAGER -if !X86_XEN source kernel/power/Kconfig -endif source "drivers/acpi/Kconfig" menu "APM (Advanced Power Management) BIOS Support" -depends on PM && !(X86_VISWS || X86_XEN) +depends on PM && !X86_VISWS config APM tristate "APM (Advanced Power Management) BIOS support" - depends on PM && PM_LEGACY + depends on PM ---help--- APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with @@ -992,7 +972,6 @@ choice config PCI_GOBIOS bool "BIOS" - depends on !X86_XEN config PCI_GOMMCONFIG bool "MMConfig" @@ -1000,13 +979,6 @@ config PCI_GOMMCONFIG config PCI_GODIRECT bool "Direct" -config PCI_GOXEN_FE - bool "Xen PCI Frontend" - depends on X86_XEN - help - The PCI device frontend driver allows the kernel to import arbitrary - PCI devices from a PCI backend to support PCI driver domains. - config PCI_GOANY bool "Any" @@ -1014,7 +986,7 @@ endchoice config PCI_BIOS bool - depends on !(X86_VISWS || X86_XEN) && PCI && (PCI_GOBIOS || PCI_GOANY) + depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) default y config PCI_DIRECT @@ -1027,18 +999,6 @@ config PCI_MMCONFIG depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) default y -config XEN_PCIDEV_FRONTEND - bool - depends on PCI && X86_XEN && (PCI_GOXEN_FE || PCI_GOANY) - default y - -config XEN_PCIDEV_FE_DEBUG - bool "Xen PCI Frontend Debugging" - depends on XEN_PCIDEV_FRONTEND - default n - help - Enables some debug statements within the PCI Frontend. - source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" @@ -1049,7 +1009,7 @@ config ISA_DMA_API config ISA bool "ISA support" - depends on !(X86_VOYAGER || X86_VISWS || X86_XEN) + depends on !(X86_VOYAGER || X86_VISWS) help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff @@ -1076,7 +1036,7 @@ config EISA source "drivers/eisa/Kconfig" config MCA - bool "MCA support" if !(X86_VISWS || X86_VOYAGER || X86_XEN) + bool "MCA support" if !(X86_VISWS || X86_VOYAGER) default y if X86_VOYAGER help MicroChannel Architecture is found in some IBM PS/2 machines and @@ -1140,8 +1100,6 @@ source "security/Kconfig" source "crypto/Kconfig" -source "drivers/xen/Kconfig" - source "lib/Kconfig" # @@ -1167,7 +1125,7 @@ config X86_SMP config X86_HT bool - depends on SMP && !(X86_VISWS || X86_VOYAGER || X86_XEN) + depends on SMP && !(X86_VISWS || X86_VOYAGER) default y config X86_BIOS_REBOOT @@ -1180,16 +1138,6 @@ config X86_TRAMPOLINE depends on X86_SMP || (X86_VOYAGER && SMP) default y -config X86_NO_TSS - bool - depends on X86_XEN - default y - -config X86_NO_IDT - bool - depends on X86_XEN - default y - config KTIME_SCALAR bool default y diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index f90d8d0df..e99d58e5e 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu @@ -7,6 +7,7 @@ choice config M386 bool "386" + depends on !UML ---help--- This is the processor type of your CPU. This information is used for optimizing purposes. In order to compile a kernel that can run on @@ -251,7 +252,7 @@ config X86_PPRO_FENCE config X86_F00F_BUG bool - depends on (M586MMX || M586TSC || M586 || M486 || M386) && !X86_NO_IDT + depends on M586MMX || M586TSC || M586 || M486 || M386 default y config X86_WP_WORKS_OK @@ -301,7 +302,7 @@ config X86_USE_PPRO_CHECKSUM config X86_USE_3DNOW bool - depends on MCYRIXIII || MK7 || MGEODE_LX + depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML default y config X86_OOSTORE @@ -311,5 +312,5 @@ config X86_OOSTORE config X86_TSC bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ default y diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug index fb28fe741..bf32ecc9a 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/i386/Kconfig.debug @@ -31,21 +31,12 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. -config STACK_BACKTRACE_COLS - int "Stack backtraces per line" if DEBUG_KERNEL - range 1 3 - default 2 - help - Selects how many stack backtrace entries per line to display. - - This can save screen space when displaying traces. - comment "Page alloc debug is incompatible with Software Suspend on i386" depends on DEBUG_KERNEL && SOFTWARE_SUSPEND config DEBUG_PAGEALLOC - bool "Debug page memory allocations" - depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND && !HUGETLBFS + bool "Page alloc debugging" + depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND help Unmap pages from the kernel linear mapping after free_pages(). This results in a large slowdown, but helps to find certain types @@ -81,14 +72,4 @@ config X86_MPPARSE depends on X86_LOCAL_APIC && !X86_VISWS default y -config DOUBLEFAULT - default y - bool "Enable doublefault exception handler" if EMBEDDED - depends on !X86_NO_TSS - help - This option allows trapping of rare doublefault exceptions that - would otherwise cause a system to silently reboot. Disabling this - option saves about 4k and might cause you much additional grey - hair. - endmenu diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 53b7343aa..36bef6543 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -29,7 +29,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S LDFLAGS_vmlinux := CHECKFLAGS += -D__i386__ -CFLAGS += -pipe -msoft-float -fno-builtin-sprintf -fno-builtin-log2 -fno-builtin-puts +CFLAGS += -pipe -msoft-float # prevent gcc from keeping the stack 16 byte aligned CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) @@ -39,20 +39,12 @@ include $(srctree)/arch/i386/Makefile.cpu cflags-$(CONFIG_REGPARM) += -mregparm=3 -# temporary until string.h is fixed -cflags-y += -ffreestanding - # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use # a lot more stack due to the lack of sharing of stacklots: CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) CFLAGS += $(cflags-y) -cppflags-$(CONFIG_XEN) += \ - -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION) - -CPPFLAGS += $(cppflags-y) - # Default subarch .c files mcore-y := mach-default @@ -76,10 +68,6 @@ mcore-$(CONFIG_X86_BIGSMP) := mach-default mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit mcore-$(CONFIG_X86_SUMMIT) := mach-default -# Xen subarch support -mflags-$(CONFIG_X86_XEN) := -Iinclude/asm-i386/mach-xen -mcore-$(CONFIG_X86_XEN) := mach-xen - # generic subarchitecture mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-i386/mach-generic mcore-$(CONFIG_X86_GENERICARCH) := mach-default @@ -111,22 +99,9 @@ AFLAGS += $(mflags-y) boot := arch/i386/boot -PHONY += zImage bzImage compressed zlilo bzlilo \ - zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install +.PHONY: zImage bzImage compressed zlilo bzlilo \ + zdisk bzdisk fdimage fdimage144 fdimage288 install -ifdef CONFIG_XEN -CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS) -head-y := arch/i386/kernel/head-xen.o arch/i386/kernel/init_task-xen.o -boot := arch/i386/boot-xen -.PHONY: vmlinuz -all: vmlinuz - -vmlinuz: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $@ - -install: - $(Q)$(MAKE) $(build)=$(boot) XENGUEST=$(XENGUEST) $@ -else all: bzImage # KBUILD_IMAGE specify target image being built @@ -144,12 +119,11 @@ zlilo bzlilo: vmlinux zdisk bzdisk: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk -fdimage fdimage144 fdimage288 isoimage: vmlinux +fdimage fdimage144 fdimage288: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ install: $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install -endif archclean: $(Q)$(MAKE) $(clean)=arch/i386/boot @@ -162,10 +136,6 @@ define archhelp echo ' install to $$(INSTALL_PATH) and run lilo' echo ' bzdisk - Create a boot floppy in /dev/fd0' echo ' fdimage - Create a boot floppy image' - echo ' isoimage - Create a boot CD-ROM image' endef -CLEAN_FILES += arch/$(ARCH)/boot/fdimage \ - arch/$(ARCH)/boot/image.iso \ - arch/$(ARCH)/boot/mtools.conf -CLEAN_FILES += vmlinuz vmlinux-stripped +CLEAN_FILES += arch/$(ARCH)/boot/fdimage arch/$(ARCH)/boot/mtools.conf diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu index 7a06a2869..dcd936ef4 100644 --- a/arch/i386/Makefile.cpu +++ b/arch/i386/Makefile.cpu @@ -15,7 +15,7 @@ cflags-$(CONFIG_M486) += -march=i486 cflags-$(CONFIG_M586) += -march=i586 cflags-$(CONFIG_M586TSC) += -march=i586 cflags-$(CONFIG_M586MMX) += -march=pentium-mmx -cflags-$(CONFIG_M686) += -march=i686 $(call tune,generic) +cflags-$(CONFIG_M686) += -march=i686 cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call tune,pentium2) cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call tune,pentium3) cflags-$(CONFIG_MPENTIUMM) += -march=i686 $(call tune,pentium3) @@ -39,7 +39,3 @@ cflags-$(CONFIG_X86_ELAN) += -march=i486 # Geode GX1 support cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx -# add at the end to overwrite eventual tuning options from earlier -# cpu entries -cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic) - diff --git a/arch/i386/boot-xen/Makefile b/arch/i386/boot-xen/Makefile deleted file mode 100644 index bf15a7709..000000000 --- a/arch/i386/boot-xen/Makefile +++ /dev/null @@ -1,21 +0,0 @@ - -OBJCOPYFLAGS := -g --strip-unneeded - -vmlinuz: vmlinux-stripped FORCE - $(call if_changed,gzip) - -vmlinux-stripped: vmlinux FORCE - $(call if_changed,objcopy) - -INSTALL_ROOT := $(patsubst %/boot,%,$(INSTALL_PATH)) - -XINSTALL_NAME ?= $(KERNELRELEASE) -install: - mkdir -p $(INSTALL_ROOT)/boot - ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_ROOT)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(XENGUEST)$(INSTALL_SUFFIX) - rm -f $(INSTALL_ROOT)/boot/vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) - install -m0644 vmlinuz $(INSTALL_ROOT)/boot/vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) - install -m0644 vmlinux $(INSTALL_ROOT)/boot/vmlinux-syms-$(XINSTALL_NAME)$(INSTALL_SUFFIX) - install -m0664 .config $(INSTALL_ROOT)/boot/config-$(XINSTALL_NAME)$(INSTALL_SUFFIX) - install -m0664 System.map $(INSTALL_ROOT)/boot/System.map-$(XINSTALL_NAME)$(INSTALL_SUFFIX) - ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_ROOT)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX) diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index 33e554763..f13675256 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile @@ -62,12 +62,8 @@ $(obj)/setup $(obj)/bootsect: %: %.o FORCE $(obj)/compressed/vmlinux: FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@ -# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel +# Set this if you want to pass append arguments to the zdisk/fdimage kernel FDARGS = -# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel -FDINITRD = - -image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,) $(obj)/mtools.conf: $(src)/mtools.conf.in sed -e 's|@OBJ@|$(obj)|g' < $< > $@ @@ -76,11 +72,8 @@ $(obj)/mtools.conf: $(src)/mtools.conf.in zdisk: $(BOOTIMAGE) $(obj)/mtools.conf MTOOLSRC=$(obj)/mtools.conf mformat a: ; sync syslinux /dev/fd0 ; sync - echo '$(image_cmdline)' | \ + echo 'default linux $(FDARGS)' | \ MTOOLSRC=$(src)/mtools.conf mcopy - a:syslinux.cfg - if [ -f '$(FDINITRD)' ] ; then \ - MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \ - fi MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync # These require being root or having syslinux 2.02 or higher installed @@ -88,39 +81,18 @@ fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440 MTOOLSRC=$(obj)/mtools.conf mformat v: ; sync syslinux $(obj)/fdimage ; sync - echo '$(image_cmdline)' | \ + echo 'default linux $(FDARGS)' | \ MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg - if [ -f '$(FDINITRD)' ] ; then \ - MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \ - fi MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880 MTOOLSRC=$(obj)/mtools.conf mformat w: ; sync syslinux $(obj)/fdimage ; sync - echo '$(image_cmdline)' | \ + echo 'default linux $(FDARGS)' | \ MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg - if [ -f '$(FDINITRD)' ] ; then \ - MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \ - fi MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync -isoimage: $(BOOTIMAGE) - -rm -rf $(obj)/isoimage - mkdir $(obj)/isoimage - cp `echo /usr/lib*/syslinux/isolinux.bin | awk '{ print $1; }'` \ - $(obj)/isoimage - cp $(BOOTIMAGE) $(obj)/isoimage/linux - echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg - if [ -f '$(FDINITRD)' ] ; then \ - cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \ - fi - mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \ - -no-emul-boot -boot-load-size 4 -boot-info-table \ - $(obj)/isoimage - rm -rf $(obj)/isoimage - zlilo: $(BOOTIMAGE) if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index f19f3a749..6f962291a 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -309,7 +309,7 @@ static void setup_normal_output_buffer(void) #else if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif - output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */ + output_data = (char *)PHYSICAL_START; /* Normally Points to 1M */ free_mem_end_ptr = (long)real_mode; } @@ -334,8 +334,8 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) low_buffer_size = low_buffer_end - LOW_BUFFER_START; high_loaded = 1; free_mem_end_ptr = (long)high_buffer_start; - if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { - high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); + if ((PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { + high_buffer_start = (uch *)(PHYSICAL_START + low_buffer_size); mv->hcount = 0; /* say: we need not to move high_buffer */ } else mv->hcount = -1; diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S index 4b84ea216..d8d69f2b9 100644 --- a/arch/i386/boot/edd.S +++ b/arch/i386/boot/edd.S @@ -76,8 +76,6 @@ edd_mbr_sig_read: popw %es popw %bx jc edd_mbr_sig_done # on failure, we're done. - cmpb $0, %ah # some BIOSes do not set CF - jne edd_mbr_sig_done # on failure, we're done. movl (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR movl %eax, (%bx) # store success incb (EDD_MBR_SIG_NR_BUF) # note that we stored something diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index 668b99600..2ac40c824 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S @@ -97,7 +97,6 @@ #define PARAM_VESAPM_OFF 0x30 #define PARAM_LFB_PAGES 0x32 #define PARAM_VESA_ATTRIB 0x34 -#define PARAM_CAPABILITIES 0x36 /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ #ifdef CONFIG_VIDEO_RETAIN @@ -127,12 +126,8 @@ video: pushw %ds # We use different segments call mode_set # Set the mode jc vid1 -#if 0 leaw badmdt, %si # Invalid mode ID call prtstr -#else - jmp vid1 -#endif /* CONFIG_VIDEO_IGNORE_BAD_MODE */ vid2: call mode_menu vid1: #ifdef CONFIG_VIDEO_RETAIN @@ -238,10 +233,6 @@ mopar_gr: movw 18(%di), %ax movl %eax, %fs:(PARAM_LFB_SIZE) -# store mode capabilities - movl 10(%di), %eax - movl %eax, %fs:(PARAM_CAPABILITIES) - # switching the DAC to 8-bit is for <= 8 bpp only movw %fs:(PARAM_LFB_DEPTH), %ax cmpw $8, %ax @@ -1933,7 +1924,6 @@ skip10: movb %ah, %al ret store_edid: -#ifdef CONFIG_FB_FIRMWARE_EDID pushw %es # just save all registers pushw %ax pushw %bx @@ -1952,29 +1942,18 @@ store_edid: stosl movw $0x4f15, %ax # do VBE/DDC - movw $0x00, %bx # INSTALLATION CHECK / CAPABILITIES + movw $0x01, %bx movw $0x00, %cx - movw $0x00, %dx - movw $0x140, %di - int $0x10 - cmpb $0x01, %ah - je no_edid - - movw $0x4f15, %ax # do VBE/DDC - movw $0x01, %bx # READ_EDID - movw $0x00, %cx - movw $0x00, %dx + movw $0x00, %dx movw $0x140, %di int $0x10 -no_edid: popw %di # restore all registers popw %dx popw %cx popw %bx popw %ax popw %es -#endif ret # VIDEO_SELECT-only variables diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 1629c3ac9..23cc26d1b 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -197,7 +197,7 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set CONFIG_SOFTWARE_SUSPEND=y -CONFIG_PM_STD_PARTITION="/dev/hda2" +CONFIG_PM_STD_PARTITION="" # # ACPI (Advanced Configuration and Power Interface) Support @@ -219,7 +219,7 @@ CONFIG_ACPI_BLACKLIST_YEAR=0 CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y -# CONFIG_X86_PM_TIMER is not set +CONFIG_X86_PM_TIMER=y # CONFIG_ACPI_CONTAINER is not set # @@ -416,7 +416,7 @@ CONFIG_IP_NF_TARGET_LOG=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set +CONFIG_FW_LOADER=y # # Connector - unified userspace <-> kernelspace linker @@ -447,7 +447,7 @@ CONFIG_PARPORT_1284=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_FD=y # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set @@ -575,7 +575,22 @@ CONFIG_BLK_DEV_SD=y # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_SATA is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_ATA_PIIX is not set +# CONFIG_SCSI_SATA_MV is not set +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_PDC_ADMA is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIL24 is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +CONFIG_SCSI_SATA_VIA=y +# CONFIG_SCSI_SATA_VITESSE is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set @@ -1011,6 +1026,11 @@ CONFIG_VIDEO_DEV=y # CONFIG_VIDEO_ZORAN is not set CONFIG_VIDEO_SAA7134=y # CONFIG_VIDEO_SAA7134_ALSA is not set +CONFIG_VIDEO_SAA7134_DVB=y +# CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS is not set +# CONFIG_VIDEO_SAA7134_DVB_MT352 is not set +CONFIG_VIDEO_SAA7134_DVB_TDA1004X=y +# CONFIG_VIDEO_SAA7134_DVB_NXT200X is not set # CONFIG_VIDEO_MXB is not set # CONFIG_VIDEO_DPC is not set # CONFIG_VIDEO_HEXIUM_ORION is not set @@ -1031,9 +1051,90 @@ CONFIG_VIDEO_SAA7134=y # # Digital Video Broadcasting Devices # -# CONFIG_DVB is not set +CONFIG_DVB=y +CONFIG_DVB_CORE=y + +# +# Supported SAA7146 based PCI Adapters +# +# CONFIG_DVB_AV7110 is not set +# CONFIG_DVB_BUDGET is not set +# CONFIG_DVB_BUDGET_CI is not set +# CONFIG_DVB_BUDGET_AV is not set + +# +# Supported USB Adapters +# +# CONFIG_DVB_USB is not set +# CONFIG_DVB_TTUSB_BUDGET is not set +# CONFIG_DVB_TTUSB_DEC is not set +# CONFIG_DVB_CINERGYT2 is not set + +# +# Supported FlexCopII (B2C2) Adapters +# +# CONFIG_DVB_B2C2_FLEXCOP is not set + +# +# Supported BT878 Adapters +# + +# +# Supported Pluto2 Adapters +# +# CONFIG_DVB_PLUTO2 is not set + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# + +# +# DVB-S (satellite) frontends +# +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_S5H1420 is not set + +# +# 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_L64781 is not set +CONFIG_DVB_TDA1004X=y +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set + +# +# DVB-C (cable) frontends +# +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_STV0297 is not set + +# +# ATSC (North American/Korean Terresterial 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_VIDEO_TUNER=y CONFIG_VIDEO_BUF=y +CONFIG_VIDEO_BUF_DVB=y CONFIG_VIDEO_IR=y # @@ -1349,11 +1450,7 @@ CONFIG_USB_STORAGE=y # CONFIG_INFINIBAND is not set # -# SN Devices -# - -# -# EDAC - error detection and reporting (RAS) +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # # CONFIG_EDAC is not set diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index ddaa19d89..65656c033 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -6,8 +6,8 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ - pci-dma.o i386_ksyms.o i387.o bootflag.o \ - quirks.o i8237.o topology.o alternative.o + pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ + quirks.o i8237.o topology.o obj-y += cpu/ obj-y += timers/ @@ -42,12 +42,6 @@ EXTRA_AFLAGS := -traditional obj-$(CONFIG_SCx200) += scx200.o -ifdef CONFIG_XEN -vsyscall_note := vsyscall-note-xen.o -else -vsyscall_note := vsyscall-note.o -endif - # vsyscall.o contains the vsyscall DSO images as __initdata. # We must build both images before we can assemble it. # Note: kbuild does not track this dependency due to usage of .incbin @@ -68,7 +62,7 @@ SYSCFLAGS_vsyscall-int80.so = $(vsyscall-flags) $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \ $(obj)/vsyscall-%.so: $(src)/vsyscall.lds \ - $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE + $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE $(call if_changed,syscall) # We also create a special relocatable object that should mirror the symbol @@ -80,17 +74,5 @@ $(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o SYSCFLAGS_vsyscall-syms.o = -r $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \ - $(obj)/vsyscall-sysenter.o $(obj)/$(vsyscall_note) FORCE + $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE $(call if_changed,syscall) - -ifdef CONFIG_XEN -include $(srctree)/scripts/Makefile.xen - -obj-y += fixup.o -microcode-$(subst m,y,$(CONFIG_MICROCODE)) := microcode-xen.o -n-obj-xen := i8259.o timers/ reboot.o smpboot.o trampoline.o - -obj-y := $(call filterxen, $(obj-y), $(n-obj-xen)) -obj-y := $(call cherrypickxen, $(obj-y)) -extra-y := $(call cherrypickxen, $(extra-y)) -endif diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index fa783e6f9..7e9ac9935 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile @@ -6,7 +6,3 @@ ifneq ($(CONFIG_ACPI_PROCESSOR),) obj-y += cstate.o processor.o endif -ifdef CONFIG_XEN -include $(srctree)/scripts/Makefile.xen -obj-y := $(call cherrypickxen, $(obj-y), $(src)) -endif diff --git a/arch/i386/kernel/acpi/boot-xen.c b/arch/i386/kernel/acpi/boot-xen.c deleted file mode 100644 index 6bd4b798f..000000000 --- a/arch/i386/kernel/acpi/boot-xen.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * boot.c - Architecture-Specific Low-Level ACPI Boot Support - * - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * Copyright (C) 2001 Jun Nakajima - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef CONFIG_X86_64 - -extern void __init clustered_apic_check(void); - -extern int gsi_irq_sharing(int gsi); -#include - -static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } - - -#else /* X86 */ - -#ifdef CONFIG_X86_LOCAL_APIC -#include -#include -#endif /* CONFIG_X86_LOCAL_APIC */ - -static inline int gsi_irq_sharing(int gsi) { return gsi; } - -#endif /* X86 */ - -#define BAD_MADT_ENTRY(entry, end) ( \ - (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((acpi_table_entry_header *)entry)->length != sizeof(*entry)) - -#define PREFIX "ACPI: " - -int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ -int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ -int acpi_ht __initdata = 1; /* enable HT */ - -int acpi_lapic; -int acpi_ioapic; -int acpi_strict; -EXPORT_SYMBOL(acpi_strict); - -acpi_interrupt_flags acpi_sci_flags __initdata; -int acpi_sci_override_gsi __initdata; -int acpi_skip_timer_override __initdata; - -#ifdef CONFIG_X86_LOCAL_APIC -static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; -#endif - -#ifndef __HAVE_ARCH_CMPXCHG -#warning ACPI uses CMPXCHG, i486 and later hardware -#endif - -#define MAX_MADT_ENTRIES 256 -u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = - {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; -EXPORT_SYMBOL(x86_acpiid_to_apicid); - -/* -------------------------------------------------------------------------- - Boot-time Configuration - -------------------------------------------------------------------------- */ - -/* - * The default interrupt routing model is PIC (8259). This gets - * overriden if IOAPICs are enumerated (below). - */ -enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; - -#if defined(CONFIG_X86_64) && !defined(CONFIG_XEN) - -/* rely on all ACPI tables being in the direct mapping */ -char *__acpi_map_table(unsigned long phys_addr, unsigned long size) -{ - if (!phys_addr || !size) - return NULL; - - if (phys_addr+size <= (end_pfn_map << PAGE_SHIFT) + PAGE_SIZE) - return __va(phys_addr); - - return NULL; -} - -#else - -/* - * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, - * to map the target physical address. The problem is that set_fixmap() - * provides a single page, and it is possible that the page is not - * sufficient. - * By using this area, we can map up to MAX_IO_APICS pages temporarily, - * i.e. until the next __va_range() call. - * - * Important Safety Note: The fixed I/O APIC page numbers are *subtracted* - * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and - * count idx down while incrementing the phys address. - */ -char *__acpi_map_table(unsigned long phys, unsigned long size) -{ - unsigned long base, offset, mapped_size; - int idx; - -#ifndef CONFIG_XEN - if (phys + size < 8 * 1024 * 1024) - return __va(phys); -#endif - - offset = phys & (PAGE_SIZE - 1); - mapped_size = PAGE_SIZE - offset; - set_fixmap(FIX_ACPI_END, phys); - base = fix_to_virt(FIX_ACPI_END); - - /* - * Most cases can be covered by the below. - */ - idx = FIX_ACPI_END; - while (mapped_size < size) { - if (--idx < FIX_ACPI_BEGIN) - return NULL; /* cannot handle this */ - phys += PAGE_SIZE; - set_fixmap(idx, phys); - mapped_size += PAGE_SIZE; - } - - return ((unsigned char *)base + offset); -} -#endif - -#ifdef CONFIG_PCI_MMCONFIG -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -struct acpi_table_mcfg_config *pci_mmcfg_config; -int pci_mmcfg_config_num; - -int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) -{ - struct acpi_table_mcfg *mcfg; - unsigned long i; - int config_size; - - if (!phys_addr || !size) - return -EINVAL; - - mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); - if (!mcfg) { - printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); - return -ENODEV; - } - - /* how many config structures do we have */ - pci_mmcfg_config_num = 0; - i = size - sizeof(struct acpi_table_mcfg); - while (i >= sizeof(struct acpi_table_mcfg_config)) { - ++pci_mmcfg_config_num; - i -= sizeof(struct acpi_table_mcfg_config); - }; - if (pci_mmcfg_config_num == 0) { - printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); - return -ENODEV; - } - - config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); - pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); - if (!pci_mmcfg_config) { - printk(KERN_WARNING PREFIX - "No memory for MCFG config tables\n"); - return -ENOMEM; - } - - memcpy(pci_mmcfg_config, &mcfg->config, config_size); - for (i = 0; i < pci_mmcfg_config_num; ++i) { - if (mcfg->config[i].base_reserved) { - printk(KERN_ERR PREFIX - "MMCONFIG not in low 4GB of memory\n"); - return -ENODEV; - } - } - - return 0; -} -#endif /* CONFIG_PCI_MMCONFIG */ - -#ifdef CONFIG_X86_LOCAL_APIC -static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) -{ - struct acpi_table_madt *madt = NULL; - - if (!phys_addr || !size) - return -EINVAL; - - madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); - if (!madt) { - printk(KERN_WARNING PREFIX "Unable to map MADT\n"); - return -ENODEV; - } - - if (madt->lapic_address) { - acpi_lapic_addr = (u64) madt->lapic_address; - - printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", - madt->lapic_address); - } - -#ifndef CONFIG_X86_64 - acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); -#endif - return 0; -} - -static int __init -acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) -{ - struct acpi_table_lapic *processor = NULL; - - processor = (struct acpi_table_lapic *)header; - - if (BAD_MADT_ENTRY(processor, end)) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - /* Record local apic id only when enabled */ - if (processor->flags.enabled) - x86_acpiid_to_apicid[processor->acpi_id] = processor->id; - - /* - * 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. - */ - mp_register_lapic(processor->id, /* APIC ID */ - processor->flags.enabled); /* Enabled? */ - - return 0; -} - -static int __init -acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, - const unsigned long end) -{ - struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; - - lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header; - - if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) - return -EINVAL; - - acpi_lapic_addr = lapic_addr_ovr->address; - - return 0; -} - -static int __init -acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) -{ - struct acpi_table_lapic_nmi *lapic_nmi = NULL; - - lapic_nmi = (struct acpi_table_lapic_nmi *)header; - - if (BAD_MADT_ENTRY(lapic_nmi, end)) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - if (lapic_nmi->lint != 1) - printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); - - return 0; -} - -#endif /*CONFIG_X86_LOCAL_APIC */ - -#ifdef CONFIG_X86_IO_APIC - -static int __init -acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) -{ - struct acpi_table_ioapic *ioapic = NULL; - - ioapic = (struct acpi_table_ioapic *)header; - - if (BAD_MADT_ENTRY(ioapic, end)) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - mp_register_ioapic(ioapic->id, - ioapic->address, ioapic->global_irq_base); - - return 0; -} - -/* - * Parse Interrupt Source Override for the ACPI SCI - */ -static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) -{ - if (trigger == 0) /* compatible SCI trigger is level */ - trigger = 3; - - if (polarity == 0) /* compatible SCI polarity is low */ - polarity = 3; - - /* Command-line over-ride via acpi_sci= */ - if (acpi_sci_flags.trigger) - trigger = acpi_sci_flags.trigger; - - if (acpi_sci_flags.polarity) - polarity = acpi_sci_flags.polarity; - - /* - * mp_config_acpi_legacy_irqs() already setup IRQs < 16 - * If GSI is < 16, this will update its flags, - * else it will create a new mp_irqs[] entry. - */ - mp_override_legacy_irq(gsi, polarity, trigger, gsi); - - /* - * stash over-ride to indicate we've been here - * and for later update of acpi_fadt - */ - acpi_sci_override_gsi = gsi; - return; -} - -static int __init -acpi_parse_int_src_ovr(acpi_table_entry_header * header, - const unsigned long end) -{ - struct acpi_table_int_src_ovr *intsrc = NULL; - - intsrc = (struct acpi_table_int_src_ovr *)header; - - if (BAD_MADT_ENTRY(intsrc, end)) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - if (intsrc->bus_irq == acpi_fadt.sci_int) { - acpi_sci_ioapic_setup(intsrc->global_irq, - intsrc->flags.polarity, - intsrc->flags.trigger); - return 0; - } - - if (acpi_skip_timer_override && - intsrc->bus_irq == 0 && intsrc->global_irq == 2) { - printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); - return 0; - } - - mp_override_legacy_irq(intsrc->bus_irq, - intsrc->flags.polarity, - intsrc->flags.trigger, intsrc->global_irq); - - return 0; -} - -static int __init -acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) -{ - struct acpi_table_nmi_src *nmi_src = NULL; - - nmi_src = (struct acpi_table_nmi_src *)header; - - if (BAD_MADT_ENTRY(nmi_src, end)) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - /* TBD: Support nimsrc entries? */ - - return 0; -} - -#endif /* CONFIG_X86_IO_APIC */ - -/* - * acpi_pic_sci_set_trigger() - * - * use ELCR to set PIC-mode trigger type for SCI - * - * If a PIC-mode SCI is not recognized or gives spurious IRQ7's - * it may require Edge Trigger -- use "acpi_sci=edge" - * - * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers - * for the 8259 PIC. bit[n] = 1 means irq[n] is Level, otherwise Edge. - * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0) - * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0) - */ - -void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) -{ - unsigned int mask = 1 << irq; - unsigned int old, new; - - /* Real old ELCR mask */ - old = inb(0x4d0) | (inb(0x4d1) << 8); - - /* - * If we use ACPI to set PCI irq's, then we should clear ELCR - * since we will set it correctly as we enable the PCI irq - * routing. - */ - new = acpi_noirq ? old : 0; - - /* - * Update SCI information in the ELCR, it isn't in the PCI - * routing tables.. - */ - switch (trigger) { - case 1: /* Edge - clear */ - new &= ~mask; - break; - case 3: /* Level - set */ - new |= mask; - break; - } - - if (old == new) - return; - - printk(PREFIX "setting ELCR to %04x (from %04x)\n", new, old); - outb(new, 0x4d0); - outb(new >> 8, 0x4d1); -} - -int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) -{ -#ifdef CONFIG_X86_IO_APIC - if (use_pci_vector() && !platform_legacy_irq(gsi)) - *irq = IO_APIC_VECTOR(gsi); - else -#endif - *irq = gsi_irq_sharing(gsi); - return 0; -} - -/* - * success: return IRQ number (>=0) - * failure: return < 0 - */ -int acpi_register_gsi(u32 gsi, int triggering, int polarity) -{ - unsigned int irq; - unsigned int plat_gsi = gsi; - -#ifdef CONFIG_PCI - /* - * Make sure all (legacy) PCI IRQs are set as level-triggered. - */ - if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { - extern void eisa_set_level_irq(unsigned int irq); - - if (triggering == ACPI_LEVEL_SENSITIVE) - eisa_set_level_irq(gsi); - } -#endif - -#ifdef CONFIG_X86_IO_APIC - if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { - plat_gsi = mp_register_gsi(gsi, triggering, polarity); - } -#endif - acpi_gsi_to_irq(plat_gsi, &irq); - return irq; -} - -EXPORT_SYMBOL(acpi_register_gsi); - -/* - * ACPI based hotplug support for CPU - */ -#ifdef CONFIG_ACPI_HOTPLUG_CPU -int acpi_map_lsapic(acpi_handle handle, int *pcpu) -{ - /* TBD */ - return -EINVAL; -} - -EXPORT_SYMBOL(acpi_map_lsapic); - -int acpi_unmap_lsapic(int cpu) -{ - /* TBD */ - return -EINVAL; -} - -EXPORT_SYMBOL(acpi_unmap_lsapic); -#endif /* CONFIG_ACPI_HOTPLUG_CPU */ - -int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) -{ - /* TBD */ - return -EINVAL; -} - -EXPORT_SYMBOL(acpi_register_ioapic); - -int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) -{ - /* TBD */ - return -EINVAL; -} - -EXPORT_SYMBOL(acpi_unregister_ioapic); - -static unsigned long __init -acpi_scan_rsdp(unsigned long start, unsigned long length) -{ - unsigned long offset = 0; - unsigned long sig_len = sizeof("RSD PTR ") - 1; - unsigned long vstart = (unsigned long)isa_bus_to_virt(start); - - /* - * Scan all 16-byte boundaries of the physical memory region for the - * RSDP signature. - */ - for (offset = 0; offset < length; offset += 16) { - if (strncmp((char *)(vstart + offset), "RSD PTR ", sig_len)) - continue; - return (start + offset); - } - - return 0; -} - -static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) -{ - struct acpi_table_sbf *sb; - - if (!phys_addr || !size) - return -EINVAL; - - sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); - if (!sb) { - printk(KERN_WARNING PREFIX "Unable to map SBF\n"); - return -ENODEV; - } - - sbf_port = sb->sbf_cmos; /* Save CMOS port */ - - return 0; -} - -#ifdef CONFIG_HPET_TIMER - -static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) -{ - struct acpi_table_hpet *hpet_tbl; - - if (!phys || !size) - return -EINVAL; - - hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size); - if (!hpet_tbl) { - printk(KERN_WARNING PREFIX "Unable to map HPET\n"); - return -ENODEV; - } - - if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { - printk(KERN_WARNING PREFIX "HPET timers must be located in " - "memory.\n"); - return -1; - } -#ifdef CONFIG_X86_64 - vxtime.hpet_address = hpet_tbl->addr.addrl | - ((long)hpet_tbl->addr.addrh << 32); - - printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", - hpet_tbl->id, vxtime.hpet_address); -#else /* X86 */ - { - extern unsigned long hpet_address; - - hpet_address = hpet_tbl->addr.addrl; - printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", - hpet_tbl->id, hpet_address); - } -#endif /* X86 */ - - return 0; -} -#else -#define acpi_parse_hpet NULL -#endif - -#ifdef CONFIG_X86_PM_TIMER -extern u32 pmtmr_ioport; -#endif - -static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) -{ - struct fadt_descriptor_rev2 *fadt = NULL; - - fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size); - if (!fadt) { - printk(KERN_WARNING PREFIX "Unable to map FADT\n"); - return 0; - } - /* initialize sci_int early for INT_SRC_OVR MADT parsing */ - acpi_fadt.sci_int = fadt->sci_int; - - /* initialize rev and apic_phys_dest_mode for x86_64 genapic */ - acpi_fadt.revision = fadt->revision; - acpi_fadt.force_apic_physical_destination_mode = - fadt->force_apic_physical_destination_mode; - -#if defined(CONFIG_X86_PM_TIMER) && !defined(CONFIG_XEN) - /* detect the location of the ACPI PM Timer */ - if (fadt->revision >= FADT2_REVISION_ID) { - /* FADT rev. 2 */ - if (fadt->xpm_tmr_blk.address_space_id != - ACPI_ADR_SPACE_SYSTEM_IO) - return 0; - - pmtmr_ioport = fadt->xpm_tmr_blk.address; - /* - * "X" fields are optional extensions to the original V1.0 - * fields, so we must selectively expand V1.0 fields if the - * corresponding X field is zero. - */ - if (!pmtmr_ioport) - pmtmr_ioport = fadt->V1_pm_tmr_blk; - } else { - /* FADT rev. 1 */ - pmtmr_ioport = fadt->V1_pm_tmr_blk; - } - if (pmtmr_ioport) - printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", - pmtmr_ioport); -#endif - return 0; -} - -unsigned long __init acpi_find_rsdp(void) -{ - unsigned long rsdp_phys = 0; - - if (efi_enabled) { - if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) - return efi.acpi20; - else if (efi.acpi != EFI_INVALID_TABLE_ADDR) - return efi.acpi; - } - /* - * Scan memory looking for the RSDP signature. First search EBDA (low - * memory) paragraphs and then search upper memory (E0000-FFFFF). - */ - rsdp_phys = acpi_scan_rsdp(0, 0x400); - if (!rsdp_phys) - rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000); - - return rsdp_phys; -} - -#ifdef CONFIG_X86_LOCAL_APIC -/* - * Parse LAPIC entries in MADT - * returns 0 on success, < 0 on error - */ -static int __init acpi_parse_madt_lapic_entries(void) -{ - int count; - - if (!cpu_has_apic) - return -ENODEV; - - /* - * Note that the LAPIC address is obtained from the MADT (32-bit value) - * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). - */ - - count = - acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, - acpi_parse_lapic_addr_ovr, 0); - if (count < 0) { - printk(KERN_ERR PREFIX - "Error parsing LAPIC address override entry\n"); - return count; - } - - mp_register_lapic_address(acpi_lapic_addr); - - count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, - MAX_APICS); - if (!count) { - printk(KERN_ERR PREFIX "No LAPIC entries present\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return -ENODEV; - } else if (count < 0) { - printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return count; - } - - count = - acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); - if (count < 0) { - printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return count; - } - return 0; -} -#endif /* CONFIG_X86_LOCAL_APIC */ - -#ifdef CONFIG_X86_IO_APIC -/* - * Parse IOAPIC related entries in MADT - * returns 0 on success, < 0 on error - */ -static int __init acpi_parse_madt_ioapic_entries(void) -{ - int count; - - /* - * ACPI interpreter is required to complete interrupt setup, - * so if it is off, don't enumerate the io-apics with ACPI. - * If MPS is present, it will handle them, - * otherwise the system will stay in PIC mode - */ - if (acpi_disabled || acpi_noirq) { - return -ENODEV; - } - - if (!cpu_has_apic) - return -ENODEV; - - /* - * if "noapic" boot option, don't look for IO-APICs - */ - if (skip_ioapic_setup) { - printk(KERN_INFO PREFIX "Skipping IOAPIC probe " - "due to 'noapic' option.\n"); - return -ENODEV; - } - - count = - acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, - MAX_IO_APICS); - if (!count) { - printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); - return -ENODEV; - } else if (count < 0) { - printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); - return count; - } - - count = - acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, - NR_IRQ_VECTORS); - if (count < 0) { - printk(KERN_ERR PREFIX - "Error parsing interrupt source overrides entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return count; - } - - /* - * If BIOS did not supply an INT_SRC_OVR for the SCI - * pretend we got one so we can set the SCI flags. - */ - if (!acpi_sci_override_gsi) - acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); - - /* Fill in identity legacy mapings where no override */ - mp_config_acpi_legacy_irqs(); - - count = - acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, - NR_IRQ_VECTORS); - if (count < 0) { - printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return count; - } - - return 0; -} -#else -static inline int acpi_parse_madt_ioapic_entries(void) -{ - return -1; -} -#endif /* !CONFIG_X86_IO_APIC */ - -static void __init acpi_process_madt(void) -{ -#ifdef CONFIG_X86_LOCAL_APIC - int count, error; - - count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); - if (count >= 1) { - - /* - * Parse MADT LAPIC entries - */ - error = acpi_parse_madt_lapic_entries(); - if (!error) { - acpi_lapic = 1; - -#ifdef CONFIG_X86_GENERICARCH - generic_bigsmp_probe(); -#endif - /* - * Parse MADT IO-APIC entries - */ - error = acpi_parse_madt_ioapic_entries(); - if (!error) { - acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; - acpi_irq_balance_set(NULL); - acpi_ioapic = 1; - - smp_found_config = 1; - clustered_apic_check(); - } - } - if (error == -EINVAL) { - /* - * Dell Precision Workstation 410, 610 come here. - */ - printk(KERN_ERR PREFIX - "Invalid BIOS MADT, disabling ACPI\n"); - disable_acpi(); - } - } -#endif - return; -} - -extern int acpi_force; - -#ifdef __i386__ - -static int __init disable_acpi_irq(struct dmi_system_id *d) -{ - if (!acpi_force) { - printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", - d->ident); - acpi_noirq_set(); - } - return 0; -} - -static int __init disable_acpi_pci(struct dmi_system_id *d) -{ - if (!acpi_force) { - printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", - d->ident); - acpi_disable_pci(); - } - return 0; -} - -static int __init dmi_disable_acpi(struct dmi_system_id *d) -{ - if (!acpi_force) { - printk(KERN_NOTICE "%s detected: acpi off\n", d->ident); - disable_acpi(); - } else { - printk(KERN_NOTICE - "Warning: DMI blacklist says broken, but acpi forced\n"); - } - return 0; -} - -/* - * Limit ACPI to CPU enumeration for HT - */ -static int __init force_acpi_ht(struct dmi_system_id *d) -{ - if (!acpi_force) { - printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", - d->ident); - disable_acpi(); - acpi_ht = 1; - } else { - printk(KERN_NOTICE - "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); - } - return 0; -} - -/* - * If your system is blacklisted here, but you find that acpi=force - * works for you, please contact acpi-devel@sourceforge.net - */ -static struct dmi_system_id __initdata acpi_dmi_table[] = { - /* - * Boxes that need ACPI disabled - */ - { - .callback = dmi_disable_acpi, - .ident = "IBM Thinkpad", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "2629H1G"), - }, - }, - - /* - * Boxes that need acpi=ht - */ - { - .callback = force_acpi_ht, - .ident = "FSC Primergy T850", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "DELL GX240", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "HP VISUALIZE NT Workstation", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "Compaq Workstation W8000", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), - DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "ASUS P4B266", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "P4B266"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "ASUS P2B-DS", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "ASUS CUR-DLS", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "ABIT i440BX-W83977", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ABIT "), - DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "IBM Bladecenter", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "IBM eServer xSeries 360", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "IBM eserver xSeries 330", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "IBM eserver xSeries 440", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), - }, - }, - - /* - * Boxes that need ACPI PCI IRQ routing disabled - */ - { - .callback = disable_acpi_irq, - .ident = "ASUS A7V", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), - DMI_MATCH(DMI_BOARD_NAME, ""), - /* newer BIOS, Revision 1011, does work */ - DMI_MATCH(DMI_BIOS_VERSION, - "ASUS A7V ACPI BIOS Revision 1007"), - }, - }, - - /* - * Boxes that need ACPI PCI IRQ routing and PCI scan disabled - */ - { /* _BBN 0 bug */ - .callback = disable_acpi_pci, - .ident = "ASUS PR-DLS", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"), - DMI_MATCH(DMI_BIOS_VERSION, - "ASUS PR-DLS ACPI BIOS Revision 1010"), - DMI_MATCH(DMI_BIOS_DATE, "03/21/2003") - }, - }, - { - .callback = disable_acpi_pci, - .ident = "Acer TravelMate 36x Laptop", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), - }, - }, - {} -}; - -#endif /* __i386__ */ - -/* - * acpi_boot_table_init() and acpi_boot_init() - * called from setup_arch(), always. - * 1. checksums all tables - * 2. enumerates lapics - * 3. enumerates io-apics - * - * acpi_table_init() is separate to allow reading SRAT without - * other side effects. - * - * side effects of acpi_boot_init: - * acpi_lapic = 1 if LAPIC found - * acpi_ioapic = 1 if IOAPIC found - * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; - * if acpi_blacklisted() acpi_disabled = 1; - * acpi_irq_model=... - * ... - * - * return value: (currently ignored) - * 0: success - * !0: failure - */ - -int __init acpi_boot_table_init(void) -{ - int error; - -#ifdef __i386__ - dmi_check_system(acpi_dmi_table); -#endif - - /* - * If acpi_disabled, bail out - * One exception: acpi=ht continues far enough to enumerate LAPICs - */ - if (acpi_disabled && !acpi_ht) - return 1; - - /* - * Initialize the ACPI boot-time table parser. - */ - error = acpi_table_init(); - if (error) { - disable_acpi(); - return error; - } - - acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); - - /* - * blacklist may disable ACPI entirely - */ - error = acpi_blacklisted(); - if (error) { - if (acpi_force) { - printk(KERN_WARNING PREFIX "acpi=force override\n"); - } else { - printk(KERN_WARNING PREFIX "Disabling ACPI support\n"); - disable_acpi(); - return error; - } - } - - return 0; -} - -int __init acpi_boot_init(void) -{ - /* - * If acpi_disabled, bail out - * One exception: acpi=ht continues far enough to enumerate LAPICs - */ - if (acpi_disabled && !acpi_ht) - return 1; - - acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); - - /* - * set sci_int and PM timer address - */ - acpi_table_parse(ACPI_FADT, acpi_parse_fadt); - - /* - * Process the Multiple APIC Description Table (MADT), if present - */ - acpi_process_madt(); - - acpi_table_parse(ACPI_HPET, acpi_parse_hpet); - - return 0; -} diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 40e5aba3a..f1a219459 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -668,10 +668,10 @@ unsigned long __init acpi_find_rsdp(void) unsigned long rsdp_phys = 0; if (efi_enabled) { - if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) - return efi.acpi20; - else if (efi.acpi != EFI_INVALID_TABLE_ADDR) - return efi.acpi; + if (efi.acpi20) + return __pa(efi.acpi20); + else if (efi.acpi) + return __pa(efi.acpi); } /* * Scan memory looking for the RSDP signature. First search EBDA (low @@ -693,9 +693,6 @@ static int __init acpi_parse_madt_lapic_entries(void) { int count; - if (!cpu_has_apic) - return -ENODEV; - /* * Note that the LAPIC address is obtained from the MADT (32-bit value) * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). @@ -754,9 +751,6 @@ static int __init acpi_parse_madt_ioapic_entries(void) return -ENODEV; } - if (!cpu_has_apic) - return -ENODEV; - /* * if "noapic" boot option, don't look for IO-APICs */ diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 1649a175a..2e3b643a4 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -5,34 +5,17 @@ #include #include #include -#include - #include #include #include -#ifdef CONFIG_ACPI - -static int nvidia_hpet_detected __initdata; - -static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) -{ - nvidia_hpet_detected = 1; - return 0; -} -#endif - static int __init check_bridge(int vendor, int device) { #ifdef CONFIG_ACPI - /* According to Nvidia all timer overrides are bogus unless HPET - is enabled. */ + /* According to Nvidia all timer overrides are bogus. Just ignore + them all. */ if (vendor == PCI_VENDOR_ID_NVIDIA) { - nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_HPET, nvidia_hpet_check); - if (nvidia_hpet_detected == 0) { - acpi_skip_timer_override = 1; - } + acpi_skip_timer_override = 1; } #endif if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) { diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c deleted file mode 100644 index f36e6ecc7..000000000 --- a/arch/i386/kernel/alternative.c +++ /dev/null @@ -1,327 +0,0 @@ -#include -#include -#include -#include -#include - -#define DEBUG 0 -#if DEBUG -# define DPRINTK(fmt, args...) printk(fmt, args) -#else -# define DPRINTK(fmt, args...) -#endif - -/* Use inline assembly to define this because the nops are defined - as inline assembly strings in the include files and we cannot - get them easily into strings. */ -asm("\t.data\nintelnops: " - GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 - GENERIC_NOP7 GENERIC_NOP8); -asm("\t.data\nk8nops: " - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 - K8_NOP7 K8_NOP8); -asm("\t.data\nk7nops: " - K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 - K7_NOP7 K7_NOP8); - -extern unsigned char intelnops[], k8nops[], k7nops[]; -static unsigned char *intel_nops[ASM_NOP_MAX+1] = { - NULL, - intelnops, - intelnops + 1, - intelnops + 1 + 2, - intelnops + 1 + 2 + 3, - intelnops + 1 + 2 + 3 + 4, - intelnops + 1 + 2 + 3 + 4 + 5, - intelnops + 1 + 2 + 3 + 4 + 5 + 6, - intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -static unsigned char *k8_nops[ASM_NOP_MAX+1] = { - NULL, - k8nops, - k8nops + 1, - k8nops + 1 + 2, - k8nops + 1 + 2 + 3, - k8nops + 1 + 2 + 3 + 4, - k8nops + 1 + 2 + 3 + 4 + 5, - k8nops + 1 + 2 + 3 + 4 + 5 + 6, - k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -static unsigned char *k7_nops[ASM_NOP_MAX+1] = { - NULL, - k7nops, - k7nops + 1, - k7nops + 1 + 2, - k7nops + 1 + 2 + 3, - k7nops + 1 + 2 + 3 + 4, - k7nops + 1 + 2 + 3 + 4 + 5, - k7nops + 1 + 2 + 3 + 4 + 5 + 6, - k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -static struct nop { - int cpuid; - unsigned char **noptable; -} noptypes[] = { - { X86_FEATURE_K8, k8_nops }, - { X86_FEATURE_K7, k7_nops }, - { -1, NULL } -}; - - -extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; -extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; -extern u8 *__smp_locks[], *__smp_locks_end[]; - -extern u8 __smp_alt_begin[], __smp_alt_end[]; - - -static unsigned char** find_nop_table(void) -{ - unsigned char **noptable = intel_nops; - int i; - - for (i = 0; noptypes[i].cpuid >= 0; i++) { - if (boot_cpu_has(noptypes[i].cpuid)) { - noptable = noptypes[i].noptable; - break; - } - } - return noptable; -} - -/* Replace instructions with better alternatives for this CPU type. - This runs before SMP is initialized to avoid SMP problems with - self modifying code. This implies that assymetric systems where - APs have less capabilities than the boot processor are not handled. - Tough. Make sure you disable such features by hand. */ - -void apply_alternatives(struct alt_instr *start, struct alt_instr *end) -{ - unsigned char **noptable = find_nop_table(); - struct alt_instr *a; - int diff, i, k; - - DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); - for (a = start; a < end; a++) { - BUG_ON(a->replacementlen > a->instrlen); - if (!boot_cpu_has(a->cpuid)) - continue; - memcpy(a->instr, a->replacement, a->replacementlen); - diff = a->instrlen - a->replacementlen; - /* Pad the rest with nops */ - for (i = a->replacementlen; diff > 0; diff -= k, i += k) { - k = diff; - if (k > ASM_NOP_MAX) - k = ASM_NOP_MAX; - memcpy(a->instr + i, noptable[k], k); - } - } -} - -#ifdef CONFIG_SMP -static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end) -{ - struct alt_instr *a; - - DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end); - for (a = start; a < end; a++) { - memcpy(a->replacement + a->replacementlen, - a->instr, - a->instrlen); - } -} - -static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end) -{ - struct alt_instr *a; - - for (a = start; a < end; a++) { - memcpy(a->instr, - a->replacement + a->replacementlen, - a->instrlen); - } -} - -static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) -{ - u8 **ptr; - - for (ptr = start; ptr < end; ptr++) { - if (*ptr < text) - continue; - if (*ptr > text_end) - continue; - **ptr = 0xf0; /* lock prefix */ - }; -} - -static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) -{ - unsigned char **noptable = find_nop_table(); - u8 **ptr; - - for (ptr = start; ptr < end; ptr++) { - if (*ptr < text) - continue; - if (*ptr > text_end) - continue; - **ptr = noptable[1][0]; - }; -} - -struct smp_alt_module { - /* what is this ??? */ - struct module *mod; - char *name; - - /* ptrs to lock prefixes */ - u8 **locks; - u8 **locks_end; - - /* .text segment, needed to avoid patching init code ;) */ - u8 *text; - u8 *text_end; - - struct list_head next; -}; -static LIST_HEAD(smp_alt_modules); -static DEFINE_SPINLOCK(smp_alt); - -static int smp_alt_once = 0; -static int __init bootonly(char *str) -{ - smp_alt_once = 1; - return 1; -} -__setup("smp-alt-boot", bootonly); - -void alternatives_smp_module_add(struct module *mod, char *name, - void *locks, void *locks_end, - void *text, void *text_end) -{ - struct smp_alt_module *smp; - unsigned long flags; - - if (smp_alt_once) { - if (boot_cpu_has(X86_FEATURE_UP)) - alternatives_smp_unlock(locks, locks_end, - text, text_end); - return; - } - - smp = kzalloc(sizeof(*smp), GFP_KERNEL); - if (NULL == smp) - return; /* we'll run the (safe but slow) SMP code then ... */ - - smp->mod = mod; - smp->name = name; - smp->locks = locks; - smp->locks_end = locks_end; - smp->text = text; - smp->text_end = text_end; - DPRINTK("%s: locks %p -> %p, text %p -> %p, name %s\n", - __FUNCTION__, smp->locks, smp->locks_end, - smp->text, smp->text_end, smp->name); - - spin_lock_irqsave(&smp_alt, flags); - list_add_tail(&smp->next, &smp_alt_modules); - if (boot_cpu_has(X86_FEATURE_UP)) - alternatives_smp_unlock(smp->locks, smp->locks_end, - smp->text, smp->text_end); - spin_unlock_irqrestore(&smp_alt, flags); -} - -void alternatives_smp_module_del(struct module *mod) -{ - struct smp_alt_module *item; - unsigned long flags; - - if (smp_alt_once) - return; - - spin_lock_irqsave(&smp_alt, flags); - list_for_each_entry(item, &smp_alt_modules, next) { - if (mod != item->mod) - continue; - list_del(&item->next); - spin_unlock_irqrestore(&smp_alt, flags); - DPRINTK("%s: %s\n", __FUNCTION__, item->name); - kfree(item); - return; - } - spin_unlock_irqrestore(&smp_alt, flags); -} - -void alternatives_smp_switch(int smp) -{ - struct smp_alt_module *mod; - unsigned long flags; - - if (smp_alt_once) - return; - BUG_ON(!smp && (num_online_cpus() > 1)); - - spin_lock_irqsave(&smp_alt, flags); - if (smp) { - printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); - clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); - clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - alternatives_smp_apply(__smp_alt_instructions, - __smp_alt_instructions_end); - list_for_each_entry(mod, &smp_alt_modules, next) - alternatives_smp_lock(mod->locks, mod->locks_end, - mod->text, mod->text_end); - } else { - printk(KERN_INFO "SMP alternatives: switching to UP code\n"); - set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); - set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - apply_alternatives(__smp_alt_instructions, - __smp_alt_instructions_end); - list_for_each_entry(mod, &smp_alt_modules, next) - alternatives_smp_unlock(mod->locks, mod->locks_end, - mod->text, mod->text_end); - } - spin_unlock_irqrestore(&smp_alt, flags); -} -#endif - - -void __init alternative_instructions(void) -{ - apply_alternatives(__alt_instructions, __alt_instructions_end); - -#ifdef CONFIG_SMP - - /* switch to patch-once-at-boottime-only mode and free the - * tables in case we know the number of CPUs will never ever - * change */ -#ifdef CONFIG_HOTPLUG_CPU - if (num_possible_cpus() < 2) - smp_alt_once = 1; -#else - smp_alt_once = 1; -#endif - - if (smp_alt_once) { - if (1 == num_possible_cpus()) { - printk(KERN_INFO "SMP alternatives: switching to UP code\n"); - set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); - set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - apply_alternatives(__smp_alt_instructions, - __smp_alt_instructions_end); - alternatives_smp_unlock(__smp_locks, __smp_locks_end, - _text, _etext); - } - free_init_pages("SMP alternatives", - (unsigned long)__smp_alt_begin, - (unsigned long)__smp_alt_end); - } else { - alternatives_smp_save(__smp_alt_instructions, - __smp_alt_instructions_end); - alternatives_smp_module_add(NULL, "core kernel", - __smp_locks, __smp_locks_end, - _text, _etext); - alternatives_smp_switch(0); - } -#endif -} diff --git a/arch/i386/kernel/apic-xen.c b/arch/i386/kernel/apic-xen.c deleted file mode 100644 index ecd4b69f0..000000000 --- a/arch/i386/kernel/apic-xen.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Local APIC handling, local APIC timers - * - * (c) 1999, 2000 Ingo Molnar - * - * Fixes - * Maciej W. Rozycki : Bits for genuine 82489DX APICs; - * thanks to Eric Gilmore - * and Rolf G. Tews - * for testing these extensively. - * Maciej W. Rozycki : Various updates and fixes. - * Mikael Pettersson : Power Management for UP-APIC. - * Pavel Machek and - * Mikael Pettersson : PM converted to driver model. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "io_ports.h" - -#ifndef CONFIG_XEN -/* - * cpu_mask that denotes the CPUs that needs timer interrupt coming in as - * IPIs in place of local APIC timers - */ -static cpumask_t timer_bcast_ipi; -#endif - -/* - * Knob to control our willingness to enable the local APIC. - */ -int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ - -/* - * Debug level - */ -int apic_verbosity; - -int modern_apic(void) -{ -#ifndef CONFIG_XEN - unsigned int lvr, version; - /* AMD systems use old APIC versions, so check the CPU */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && - boot_cpu_data.x86 >= 0xf) - return 1; - lvr = apic_read(APIC_LVR); - version = GET_APIC_VERSION(lvr); - return version >= 0x14; -#else - return 1; -#endif -} - -/* - * '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("unexpected IRQ trap at vector %02x\n", irq); - /* - * Currently unexpected vectors happen only on SMP and APIC. - * We _must_ ack these because every local APIC has only N - * irq slots per priority level, and a 'hanging, unacked' IRQ - * holds up an irq slot - in excessive cases (when multiple - * unexpected vectors occur) that might lock up the APIC - * completely. - * But only ack when the APIC is enabled -AK - */ - if (cpu_has_apic) - ack_APIC_irq(); -} - -int get_physical_broadcast(void) -{ - if (modern_apic()) - return 0xff; - else - return 0xf; -} - -#ifndef CONFIG_XEN -#ifndef CONFIG_SMP -static void up_apic_timer_interrupt_call(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - - /* - * the NMI deadlock-detector uses this. - */ - per_cpu(irq_stat, cpu).apic_timer_irqs++; - - smp_local_timer_interrupt(regs); -} -#endif - -void smp_send_timer_broadcast_ipi(struct pt_regs *regs) -{ - cpumask_t mask; - - cpus_and(mask, cpu_online_map, timer_bcast_ipi); - if (!cpus_empty(mask)) { -#ifdef CONFIG_SMP - send_IPI_mask(mask, LOCAL_TIMER_VECTOR); -#else - /* - * We can directly call the apic timer interrupt handler - * in UP case. Minus all irq related functions - */ - up_apic_timer_interrupt_call(regs); -#endif - } -} -#endif - -int setup_profiling_timer(unsigned int multiplier) -{ - return -EINVAL; -} - -/* - * This initializes the IO-APIC and APIC hardware if this is - * a UP kernel. - */ -int __init APIC_init_uniprocessor (void) -{ -#ifdef CONFIG_X86_IO_APIC - if (smp_found_config) - if (!skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); -#endif - - return 0; -} diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 3d4b2f3d1..776c90989 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -38,7 +38,6 @@ #include #include -#include #include #include "io_ports.h" @@ -62,18 +61,6 @@ int apic_verbosity; static void apic_pm_activate(void); -int modern_apic(void) -{ - unsigned int lvr, version; - /* AMD systems use old APIC versions, so check the CPU */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && - boot_cpu_data.x86 >= 0xf) - return 1; - lvr = apic_read(APIC_LVR); - version = GET_APIC_VERSION(lvr); - return version >= 0x14; -} - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -131,7 +118,10 @@ void enable_NMI_through_LVT0 (void * dummy) int get_physical_broadcast(void) { - if (modern_apic()) + unsigned int lvr, version; + lvr = apic_read(APIC_LVR); + version = GET_APIC_VERSION(lvr); + if (!APIC_INTEGRATED(version) || version >= 0x14) return 0xff; else return 0xf; @@ -358,9 +348,9 @@ int __init verify_local_APIC(void) void __init sync_Arb_IDs(void) { - /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 - And not needed on AMD */ - if (modern_apic()) + /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ + unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); + if (ver >= 0x14) /* P4 or higher */ return; /* * Wait for idle. @@ -424,7 +414,6 @@ void __init init_bsp_APIC(void) void __devinit setup_local_APIC(void) { unsigned long oldvalue, value, ver, maxlvt; - int i, j; /* Pound the ESR really hard over the head with a big hammer - mbligh */ if (esr_disable) { @@ -461,25 +450,6 @@ void __devinit setup_local_APIC(void) value &= ~APIC_TPRI_MASK; apic_write_around(APIC_TASKPRI, value); - /* - * After a crash, we no longer service the interrupts and a pending - * interrupt from previous kernel might still have ISR bit set. - * - * Most probably by now CPU has serviced that pending interrupt and - * it might not have done the ack_APIC_irq() because it thought, - * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it - * does not clear the ISR bit and cpu thinks it has already serivced - * the interrupt. Hence a vector might get locked. It was noticed - * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. - */ - for (i = APIC_ISR_NR - 1; i >= 0; i--) { - value = apic_read(APIC_ISR + i*0x10); - for (j = 31; j >= 0; j--) { - if (value & (1<" #sym " %0 " #val : : "i" (val)) @@ -54,7 +53,6 @@ void foo(void) OFFSET(TI_preempt_count, thread_info, preempt_count); OFFSET(TI_addr_limit, thread_info, addr_limit); OFFSET(TI_restart_block, thread_info, restart_block); - OFFSET(TI_sysenter_return, thread_info, sysenter_return); BLANK(); OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); @@ -65,14 +63,10 @@ void foo(void) OFFSET(pbe_orig_address, pbe, orig_address); OFFSET(pbe_next, pbe, next); -#ifndef CONFIG_X86_NO_TSS /* Offset from the sysenter stack to tss.esp0 */ - DEFINE(SYSENTER_stack_esp0, offsetof(struct tss_struct, esp0) - + DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) - sizeof(struct tss_struct)); -#else - /* sysenter stack points directly to esp0 */ - DEFINE(SYSENTER_stack_esp0, 0); -#endif DEFINE(PAGE_SIZE_asm, PAGE_SIZE); + DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL)); } diff --git a/arch/i386/kernel/cpu/Makefile b/arch/i386/kernel/cpu/Makefile index 753f1d770..010aecfff 100644 --- a/arch/i386/kernel/cpu/Makefile +++ b/arch/i386/kernel/cpu/Makefile @@ -17,8 +17,3 @@ obj-$(CONFIG_X86_MCE) += mcheck/ obj-$(CONFIG_MTRR) += mtrr/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ - -ifdef CONFIG_XEN -include $(srctree)/scripts/Makefile.xen -obj-y := $(call cherrypickxen, $(obj-y), $(src)) -endif diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 786d1a570..d2d50cbdc 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -214,6 +214,8 @@ static void __init init_amd(struct cpuinfo_x86 *c) if (cpuid_eax(0x80000000) >= 0x80000008) { c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; + if (c->x86_max_cores & (c->x86_max_cores - 1)) + c->x86_max_cores = 1; } if (cpuid_eax(0x80000000) >= 0x80000007) { diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c index bd75629dd..f52669ecb 100644 --- a/arch/i386/kernel/cpu/centaur.c +++ b/arch/i386/kernel/cpu/centaur.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "cpu.h" #ifdef CONFIG_X86_OOSTORE diff --git a/arch/i386/kernel/cpu/common-xen.c b/arch/i386/kernel/cpu/common-xen.c deleted file mode 100644 index 50a235acf..000000000 --- a/arch/i386/kernel/cpu/common-xen.c +++ /dev/null @@ -1,732 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_X86_LOCAL_APIC -#include -#include -#include -#endif -#include - -#include "cpu.h" - -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); - -#ifndef CONFIG_XEN -DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); -EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); -#endif - -static int cachesize_override __cpuinitdata = -1; -static int disable_x86_fxsr __cpuinitdata; -static int disable_x86_serial_nr __cpuinitdata = 1; -static int disable_x86_sep __cpuinitdata; - -struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; - -extern int disable_pse; - -static void default_init(struct cpuinfo_x86 * c) -{ - /* Not much we can do here... */ - /* Check if at least it has cpuid */ - if (c->cpuid_level == -1) { - /* No cpuid. It must be an ancient CPU */ - if (c->x86 == 4) - strcpy(c->x86_model_id, "486"); - else if (c->x86 == 3) - strcpy(c->x86_model_id, "386"); - } -} - -static struct cpu_dev default_cpu = { - .c_init = default_init, - .c_vendor = "Unknown", -}; -static struct cpu_dev * this_cpu = &default_cpu; - -static int __init cachesize_setup(char *str) -{ - get_option (&str, &cachesize_override); - return 1; -} -__setup("cachesize=", cachesize_setup); - -int __cpuinit get_model_name(struct cpuinfo_x86 *c) -{ - unsigned int *v; - char *p, *q; - - if (cpuid_eax(0x80000000) < 0x80000004) - return 0; - - v = (unsigned int *) c->x86_model_id; - cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); - cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); - cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); - c->x86_model_id[48] = 0; - - /* Intel chips right-justify this string for some dumb reason; - undo that brain damage */ - p = q = &c->x86_model_id[0]; - while ( *p == ' ' ) - p++; - if ( p != q ) { - while ( *p ) - *q++ = *p++; - while ( q <= &c->x86_model_id[48] ) - *q++ = '\0'; /* Zero-pad the rest */ - } - - return 1; -} - - -void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) -{ - unsigned int n, dummy, ecx, edx, l2size; - - n = cpuid_eax(0x80000000); - - if (n >= 0x80000005) { - cpuid(0x80000005, &dummy, &dummy, &ecx, &edx); - printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n", - edx>>24, edx&0xFF, ecx>>24, ecx&0xFF); - c->x86_cache_size=(ecx>>24)+(edx>>24); - } - - if (n < 0x80000006) /* Some chips just has a large L1. */ - return; - - ecx = cpuid_ecx(0x80000006); - l2size = ecx >> 16; - - /* do processor-specific cache resizing */ - if (this_cpu->c_size_cache) - l2size = this_cpu->c_size_cache(c,l2size); - - /* Allow user to override all this if necessary. */ - if (cachesize_override != -1) - l2size = cachesize_override; - - if ( l2size == 0 ) - return; /* Again, no L2 cache is possible */ - - c->x86_cache_size = l2size; - - printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n", - l2size, ecx & 0xFF); -} - -/* Naming convention should be: [()] */ -/* This table only is used unless init_() below doesn't set it; */ -/* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ - -/* Look up CPU names by table lookup. */ -static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) -{ - struct cpu_model_info *info; - - if ( c->x86_model >= 16 ) - return NULL; /* Range check */ - - if (!this_cpu) - return NULL; - - info = this_cpu->c_models; - - while (info && info->family) { - if (info->family == c->x86) - return info->model_names[c->x86_model]; - info++; - } - return NULL; /* Not found */ -} - - -static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) -{ - char *v = c->x86_vendor_id; - int i; - static int printed; - - for (i = 0; i < X86_VENDOR_NUM; i++) { - if (cpu_devs[i]) { - if (!strcmp(v,cpu_devs[i]->c_ident[0]) || - (cpu_devs[i]->c_ident[1] && - !strcmp(v,cpu_devs[i]->c_ident[1]))) { - c->x86_vendor = i; - if (!early) - this_cpu = cpu_devs[i]; - return; - } - } - } - if (!printed) { - printed++; - printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n"); - printk(KERN_ERR "CPU: Your system may be unstable.\n"); - } - c->x86_vendor = X86_VENDOR_UNKNOWN; - this_cpu = &default_cpu; -} - - -static int __init x86_fxsr_setup(char * s) -{ - disable_x86_fxsr = 1; - return 1; -} -__setup("nofxsr", x86_fxsr_setup); - - -static int __init x86_sep_setup(char * s) -{ - disable_x86_sep = 1; - return 1; -} -__setup("nosep", x86_sep_setup); - - -/* Standard macro to see if a specific flag is changeable */ -static inline int flag_is_changeable_p(u32 flag) -{ - u32 f1, f2; - - asm("pushfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "movl %0,%1\n\t" - "xorl %2,%0\n\t" - "pushl %0\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "popfl\n\t" - : "=&r" (f1), "=&r" (f2) - : "ir" (flag)); - - return ((f1^f2) & flag) != 0; -} - - -/* Probe for the CPUID instruction */ -static int __cpuinit have_cpuid_p(void) -{ - return flag_is_changeable_p(X86_EFLAGS_ID); -} - -/* Do minimum CPU detection early. - Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. - The others are not touched to avoid unwanted side effects. - - WARNING: this function is only called on the BP. Don't add code here - that is supposed to run on all CPUs. */ -static void __init early_cpu_detect(void) -{ - struct cpuinfo_x86 *c = &boot_cpu_data; - - c->x86_cache_alignment = 32; - - if (!have_cpuid_p()) - return; - - /* Get vendor name */ - cpuid(0x00000000, &c->cpuid_level, - (int *)&c->x86_vendor_id[0], - (int *)&c->x86_vendor_id[8], - (int *)&c->x86_vendor_id[4]); - - get_cpu_vendor(c, 1); - - c->x86 = 4; - if (c->cpuid_level >= 0x00000001) { - u32 junk, tfms, cap0, misc; - cpuid(0x00000001, &tfms, &misc, &junk, &cap0); - c->x86 = (tfms >> 8) & 15; - c->x86_model = (tfms >> 4) & 15; - if (c->x86 == 0xf) - c->x86 += (tfms >> 20) & 0xff; - if (c->x86 >= 0x6) - c->x86_model += ((tfms >> 16) & 0xF) << 4; - c->x86_mask = tfms & 15; - if (cap0 & (1<<19)) - c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8; - } -} - -void __cpuinit generic_identify(struct cpuinfo_x86 * c) -{ - u32 tfms, xlvl; - int ebx; - - if (have_cpuid_p()) { - /* Get vendor name */ - cpuid(0x00000000, &c->cpuid_level, - (int *)&c->x86_vendor_id[0], - (int *)&c->x86_vendor_id[8], - (int *)&c->x86_vendor_id[4]); - - get_cpu_vendor(c, 0); - /* Initialize the standard set of capabilities */ - /* Note that the vendor-specific code below might override */ - - /* Intel-defined flags: level 0x00000001 */ - if ( c->cpuid_level >= 0x00000001 ) { - u32 capability, excap; - cpuid(0x00000001, &tfms, &ebx, &excap, &capability); - c->x86_capability[0] = capability; - c->x86_capability[4] = excap; - c->x86 = (tfms >> 8) & 15; - c->x86_model = (tfms >> 4) & 15; - if (c->x86 == 0xf) - c->x86 += (tfms >> 20) & 0xff; - if (c->x86 >= 0x6) - c->x86_model += ((tfms >> 16) & 0xF) << 4; - c->x86_mask = tfms & 15; -#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) - c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); -#else - c->apicid = (ebx >> 24) & 0xFF; -#endif - } else { - /* Have CPUID level 0 only - unheard of */ - c->x86 = 4; - } - - /* AMD-defined flags: level 0x80000001 */ - xlvl = cpuid_eax(0x80000000); - if ( (xlvl & 0xffff0000) == 0x80000000 ) { - if ( xlvl >= 0x80000001 ) { - c->x86_capability[1] = cpuid_edx(0x80000001); - c->x86_capability[6] = cpuid_ecx(0x80000001); - } - if ( xlvl >= 0x80000004 ) - get_model_name(c); /* Default name */ - } - } - - early_intel_workaround(c); - -#ifdef CONFIG_X86_HT - phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; -#endif -} - -static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) -{ - if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { - /* Disable processor serial number */ - unsigned long lo,hi; - rdmsr(MSR_IA32_BBL_CR_CTL,lo,hi); - lo |= 0x200000; - wrmsr(MSR_IA32_BBL_CR_CTL,lo,hi); - printk(KERN_NOTICE "CPU serial number disabled.\n"); - clear_bit(X86_FEATURE_PN, c->x86_capability); - - /* Disabling the serial number may affect the cpuid level */ - c->cpuid_level = cpuid_eax(0); - } -} - -static int __init x86_serial_nr_setup(char *s) -{ - disable_x86_serial_nr = 0; - return 1; -} -__setup("serialnumber", x86_serial_nr_setup); - - - -/* - * This does the hard work of actually picking apart the CPU stuff... - */ -void __cpuinit identify_cpu(struct cpuinfo_x86 *c) -{ - int i; - - c->loops_per_jiffy = loops_per_jiffy; - c->x86_cache_size = -1; - c->x86_vendor = X86_VENDOR_UNKNOWN; - c->cpuid_level = -1; /* CPUID not detected */ - c->x86_model = c->x86_mask = 0; /* So far unknown... */ - c->x86_vendor_id[0] = '\0'; /* Unset */ - c->x86_model_id[0] = '\0'; /* Unset */ - c->x86_max_cores = 1; - memset(&c->x86_capability, 0, sizeof c->x86_capability); - - if (!have_cpuid_p()) { - /* First of all, decide if this is a 486 or higher */ - /* It's a 486 if we can modify the AC flag */ - if ( flag_is_changeable_p(X86_EFLAGS_AC) ) - c->x86 = 4; - else - c->x86 = 3; - } - - generic_identify(c); - - printk(KERN_DEBUG "CPU: After generic identify, caps:"); - for (i = 0; i < NCAPINTS; i++) - printk(" %08lx", c->x86_capability[i]); - printk("\n"); - - if (this_cpu->c_identify) { - this_cpu->c_identify(c); - - printk(KERN_DEBUG "CPU: After vendor identify, caps:"); - for (i = 0; i < NCAPINTS; i++) - printk(" %08lx", c->x86_capability[i]); - printk("\n"); - } - - /* - * Vendor-specific initialization. In this section we - * canonicalize the feature flags, meaning if there are - * features a certain CPU supports which CPUID doesn't - * tell us, CPUID claiming incorrect flags, or other bugs, - * we handle them here. - * - * At the end of this section, c->x86_capability better - * indicate the features this CPU genuinely supports! - */ - if (this_cpu->c_init) - this_cpu->c_init(c); - - /* Disable the PN if appropriate */ - squash_the_stupid_serial_number(c); - - /* - * The vendor-specific functions might have changed features. Now - * we do "generic changes." - */ - - /* TSC disabled? */ - if ( tsc_disable ) - clear_bit(X86_FEATURE_TSC, c->x86_capability); - - /* FXSR disabled? */ - if (disable_x86_fxsr) { - clear_bit(X86_FEATURE_FXSR, c->x86_capability); - clear_bit(X86_FEATURE_XMM, c->x86_capability); - } - - /* SEP disabled? */ - if (disable_x86_sep) - clear_bit(X86_FEATURE_SEP, c->x86_capability); - - if (disable_pse) - clear_bit(X86_FEATURE_PSE, c->x86_capability); - - /* If the model name is still unset, do table lookup. */ - if ( !c->x86_model_id[0] ) { - char *p; - p = table_lookup_model(c); - if ( p ) - strcpy(c->x86_model_id, p); - else - /* Last resort... */ - sprintf(c->x86_model_id, "%02x/%02x", - c->x86, c->x86_model); - } - - /* Now the feature flags better reflect actual CPU features! */ - - printk(KERN_DEBUG "CPU: After all inits, caps:"); - for (i = 0; i < NCAPINTS; i++) - printk(" %08lx", c->x86_capability[i]); - printk("\n"); - - /* - * On SMP, boot_cpu_data holds the common feature set between - * all CPUs; so make sure that we indicate which features are - * common between the CPUs. The first time this routine gets - * executed, c == &boot_cpu_data. - */ - if ( c != &boot_cpu_data ) { - /* AND the already accumulated flags with these */ - for ( i = 0 ; i < NCAPINTS ; i++ ) - boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; - } - - /* Init Machine Check Exception if available. */ - mcheck_init(c); - - if (c == &boot_cpu_data) - sysenter_setup(); - enable_sep_cpu(); - - if (c == &boot_cpu_data) - mtrr_bp_init(); - else - mtrr_ap_init(); -} - -#ifdef CONFIG_X86_HT -void __cpuinit detect_ht(struct cpuinfo_x86 *c) -{ - u32 eax, ebx, ecx, edx; - int index_msb, core_bits; - int cpu = smp_processor_id(); - - cpuid(1, &eax, &ebx, &ecx, &edx); - - - if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) - return; - - smp_num_siblings = (ebx & 0xff0000) >> 16; - - if (smp_num_siblings == 1) { - printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); - } else if (smp_num_siblings > 1 ) { - - if (smp_num_siblings > NR_CPUS) { - printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); - smp_num_siblings = 1; - return; - } - - index_msb = get_count_order(smp_num_siblings); - phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); - - printk(KERN_INFO "CPU: Physical Processor ID: %d\n", - phys_proc_id[cpu]); - - smp_num_siblings = smp_num_siblings / c->x86_max_cores; - - index_msb = get_count_order(smp_num_siblings) ; - - core_bits = get_count_order(c->x86_max_cores); - - cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) & - ((1 << core_bits) - 1); - - if (c->x86_max_cores > 1) - printk(KERN_INFO "CPU: Processor Core ID: %d\n", - cpu_core_id[cpu]); - } -} -#endif - -void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) -{ - char *vendor = NULL; - - if (c->x86_vendor < X86_VENDOR_NUM) - vendor = this_cpu->c_vendor; - else if (c->cpuid_level >= 0) - vendor = c->x86_vendor_id; - - if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor))) - printk("%s ", vendor); - - if (!c->x86_model_id[0]) - printk("%d86", c->x86); - else - printk("%s", c->x86_model_id); - - if (c->x86_mask || c->cpuid_level >= 0) - printk(" stepping %02x\n", c->x86_mask); - else - printk("\n"); -} - -cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; - -/* This is hacky. :) - * We're emulating future behavior. - * In the future, the cpu-specific init functions will be called implicitly - * via the magic of initcalls. - * They will insert themselves into the cpu_devs structure. - * Then, when cpu_init() is called, we can just iterate over that array. - */ - -extern int intel_cpu_init(void); -extern int cyrix_init_cpu(void); -extern int nsc_init_cpu(void); -extern int amd_init_cpu(void); -extern int centaur_init_cpu(void); -extern int transmeta_init_cpu(void); -extern int rise_init_cpu(void); -extern int nexgen_init_cpu(void); -extern int umc_init_cpu(void); - -void __init early_cpu_init(void) -{ - intel_cpu_init(); - cyrix_init_cpu(); - nsc_init_cpu(); - amd_init_cpu(); - centaur_init_cpu(); - transmeta_init_cpu(); - rise_init_cpu(); - nexgen_init_cpu(); - umc_init_cpu(); - early_cpu_detect(); - -#ifdef CONFIG_DEBUG_PAGEALLOC - /* pse is not compatible with on-the-fly unmapping, - * disable it even if the cpus claim to support it. - */ - clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); - disable_pse = 1; -#endif -} - -void __cpuinit cpu_gdt_init(struct Xgt_desc_struct *gdt_descr) -{ - unsigned long frames[16]; - unsigned long va; - int f; - - for (va = gdt_descr->address, f = 0; - va < gdt_descr->address + gdt_descr->size; - va += PAGE_SIZE, f++) { - frames[f] = virt_to_mfn(va); - make_lowmem_page_readonly( - (void *)va, XENFEAT_writable_descriptor_tables); - } - if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8)) - BUG(); -} - -/* - * cpu_init() initializes state that is per-CPU. Some data is already - * initialized (naturally) in the bootstrap process, such as the GDT - * and IDT. We reload them nevertheless, this function acts as a - * 'CPU state barrier', nothing should get across. - */ -void __cpuinit cpu_init(void) -{ - int cpu = smp_processor_id(); -#ifndef CONFIG_X86_NO_TSS - struct tss_struct * t = &per_cpu(init_tss, cpu); -#endif - struct thread_struct *thread = ¤t->thread; - struct desc_struct *gdt; - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - - if (cpu_test_and_set(cpu, cpu_initialized)) { - printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); - for (;;) local_irq_enable(); - } - printk(KERN_INFO "Initializing CPU#%d\n", cpu); - - if (cpu_has_vme || cpu_has_de) - clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); - if (tsc_disable && cpu_has_tsc) { - printk(KERN_NOTICE "Disabling TSC...\n"); - /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ - clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); - set_in_cr4(X86_CR4_TSD); - } - -#ifndef CONFIG_XEN - /* - * This is a horrible hack to allocate the GDT. The problem - * is that cpu_init() is called really early for the boot CPU - * (and hence needs bootmem) but much later for the secondary - * CPUs, when bootmem will have gone away - */ - if (NODE_DATA(0)->bdata->node_bootmem_map) { - gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); - /* alloc_bootmem_pages panics on failure, so no check */ - memset(gdt, 0, PAGE_SIZE); - } else { - gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); - if (unlikely(!gdt)) { - printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); - for (;;) - local_irq_enable(); - } - } - - /* - * Initialize the per-CPU GDT with the boot GDT, - * and set up the GDT descriptor: - */ - memcpy(gdt, cpu_gdt_table, GDT_SIZE); - - /* Set up GDT entry for 16bit stack */ - *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |= - ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) | - ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) | - (CPU_16BIT_STACK_SIZE - 1); - - cpu_gdt_descr->size = GDT_SIZE - 1; - cpu_gdt_descr->address = (unsigned long)gdt; -#else - if (cpu == 0 && cpu_gdt_descr->address == 0) { - gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); - /* alloc_bootmem_pages panics on failure, so no check */ - memset(gdt, 0, PAGE_SIZE); - - memcpy(gdt, cpu_gdt_table, GDT_SIZE); - - cpu_gdt_descr->size = GDT_SIZE; - cpu_gdt_descr->address = (unsigned long)gdt; - } -#endif - - cpu_gdt_init(cpu_gdt_descr); - - /* - * Set up and load the per-CPU TSS and LDT - */ - atomic_inc(&init_mm.mm_count); - current->active_mm = &init_mm; - if (current->mm) - BUG(); - enter_lazy_tlb(&init_mm, current); - - load_esp0(t, thread); - - load_LDT(&init_mm.context); - -#ifdef CONFIG_DOUBLEFAULT - /* Set up doublefault TSS pointer in the GDT */ - __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); -#endif - - /* Clear %fs and %gs. */ - asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); - - /* Clear all 6 debug registers: */ - set_debugreg(0, 0); - set_debugreg(0, 1); - set_debugreg(0, 2); - set_debugreg(0, 3); - set_debugreg(0, 6); - set_debugreg(0, 7); - - /* - * Force FPU initialization: - */ - current_thread_info()->status = 0; - clear_used_math(); - mxcsr_feature_mask_init(); -} - -#ifdef CONFIG_HOTPLUG_CPU -void __cpuinit cpu_uninit(void) -{ - int cpu = raw_smp_processor_id(); - cpu_clear(cpu, cpu_initialized); - - /* lazy TLB state */ - per_cpu(cpu_tlbstate, cpu).state = 0; - per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm; -} -#endif diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index ad8cc4bd2..e6bd095ae 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -25,10 +25,9 @@ EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); -static int cachesize_override __cpuinitdata = -1; -static int disable_x86_fxsr __cpuinitdata; -static int disable_x86_serial_nr __cpuinitdata = 1; -static int disable_x86_sep __cpuinitdata; +static int cachesize_override __devinitdata = -1; +static int disable_x86_fxsr __devinitdata = 0; +static int disable_x86_serial_nr __devinitdata = 1; struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; @@ -60,7 +59,7 @@ static int __init cachesize_setup(char *str) } __setup("cachesize=", cachesize_setup); -int __cpuinit get_model_name(struct cpuinfo_x86 *c) +int __devinit get_model_name(struct cpuinfo_x86 *c) { unsigned int *v; char *p, *q; @@ -90,7 +89,7 @@ int __cpuinit get_model_name(struct cpuinfo_x86 *c) } -void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) +void __devinit display_cacheinfo(struct cpuinfo_x86 *c) { unsigned int n, dummy, ecx, edx, l2size; @@ -131,7 +130,7 @@ void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ /* Look up CPU names by table lookup. */ -static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) +static char __devinit *table_lookup_model(struct cpuinfo_x86 *c) { struct cpu_model_info *info; @@ -152,7 +151,7 @@ static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) } -static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) +static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) { char *v = c->x86_vendor_id; int i; @@ -188,14 +187,6 @@ static int __init x86_fxsr_setup(char * s) __setup("nofxsr", x86_fxsr_setup); -static int __init x86_sep_setup(char * s) -{ - disable_x86_sep = 1; - return 1; -} -__setup("nosep", x86_sep_setup); - - /* Standard macro to see if a specific flag is changeable */ static inline int flag_is_changeable_p(u32 flag) { @@ -219,7 +210,7 @@ static inline int flag_is_changeable_p(u32 flag) /* Probe for the CPUID instruction */ -static int __cpuinit have_cpuid_p(void) +static int __devinit have_cpuid_p(void) { return flag_is_changeable_p(X86_EFLAGS_ID); } @@ -263,10 +254,10 @@ static void __init early_cpu_detect(void) } } -void __cpuinit generic_identify(struct cpuinfo_x86 * c) +void __devinit generic_identify(struct cpuinfo_x86 * c) { u32 tfms, xlvl; - int ebx; + int junk; if (have_cpuid_p()) { /* Get vendor name */ @@ -282,7 +273,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) /* Intel-defined flags: level 0x00000001 */ if ( c->cpuid_level >= 0x00000001 ) { u32 capability, excap; - cpuid(0x00000001, &tfms, &ebx, &excap, &capability); + cpuid(0x00000001, &tfms, &junk, &excap, &capability); c->x86_capability[0] = capability; c->x86_capability[4] = excap; c->x86 = (tfms >> 8) & 15; @@ -292,11 +283,6 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xF) << 4; c->x86_mask = tfms & 15; -#ifdef CONFIG_SMP - c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); -#else - c->apicid = (ebx >> 24) & 0xFF; -#endif } else { /* Have CPUID level 0 only - unheard of */ c->x86 = 4; @@ -321,7 +307,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) #endif } -static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) +static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { /* Disable processor serial number */ @@ -349,7 +335,7 @@ __setup("serialnumber", x86_serial_nr_setup); /* * This does the hard work of actually picking apart the CPU stuff... */ -void __cpuinit identify_cpu(struct cpuinfo_x86 *c) +void __devinit identify_cpu(struct cpuinfo_x86 *c) { int i; @@ -419,20 +405,9 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) clear_bit(X86_FEATURE_XMM, c->x86_capability); } - /* SEP disabled? */ - if (disable_x86_sep) - clear_bit(X86_FEATURE_SEP, c->x86_capability); - if (disable_pse) clear_bit(X86_FEATURE_PSE, c->x86_capability); - if (exec_shield != 0) { -#ifdef CONFIG_HIGHMEM64G /* NX implies PAE */ - if (!test_bit(X86_FEATURE_NX, c->x86_capability)) -#endif - clear_bit(X86_FEATURE_SEP, c->x86_capability); - } - /* If the model name is still unset, do table lookup. */ if ( !c->x86_model_id[0] ) { char *p; @@ -442,7 +417,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) else /* Last resort... */ sprintf(c->x86_model_id, "%02x/%02x", - c->x86, c->x86_model); + c->x86_vendor, c->x86_model); } /* Now the feature flags better reflect actual CPU features! */ @@ -478,7 +453,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) } #ifdef CONFIG_X86_HT -void __cpuinit detect_ht(struct cpuinfo_x86 *c) +void __devinit detect_ht(struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx; int index_msb, core_bits; @@ -486,6 +461,7 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) cpuid(1, &eax, &ebx, &ecx, &edx); + c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) return; @@ -524,7 +500,7 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) } #endif -void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) +void __devinit print_cpu_info(struct cpuinfo_x86 *c) { char *vendor = NULL; @@ -547,7 +523,7 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) printk("\n"); } -cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; +cpumask_t cpu_initialized __devinitdata = CPU_MASK_NONE; /* This is hacky. :) * We're emulating future behavior. @@ -594,7 +570,7 @@ void __init early_cpu_init(void) * and IDT. We reload them nevertheless, this function acts as a * 'CPU state barrier', nothing should get across. */ -void __cpuinit cpu_init(void) +void __devinit cpu_init(void) { int cpu = smp_processor_id(); struct tss_struct * t = &per_cpu(init_tss, cpu); @@ -694,7 +670,7 @@ void __cpuinit cpu_init(void) } #ifdef CONFIG_HOTPLUG_CPU -void __cpuinit cpu_uninit(void) +void __devinit cpu_uninit(void) { int cpu = raw_smp_processor_id(); cpu_clear(cpu, cpu_initialized); diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig index e44a4c6a4..16f2e356c 100644 --- a/arch/i386/kernel/cpu/cpufreq/Kconfig +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig @@ -96,6 +96,7 @@ config X86_POWERNOW_K8_ACPI config X86_GX_SUSPMOD tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" + depends on PCI help This add the CPUFreq driver for NatSemi Geode processors which support suspend modulation. @@ -114,9 +115,9 @@ config X86_SPEEDSTEP_CENTRINO you also need to say Y to "Use ACPI tables to decode..." below [which might imply enabling ACPI] if you want to use this driver on non-Banias CPUs. - + For details, take a look at . - + If in doubt, say N. config X86_SPEEDSTEP_CENTRINO_ACPI @@ -147,7 +148,7 @@ config X86_SPEEDSTEP_ICH help This adds the CPUFreq driver for certain mobile Intel Pentium III (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all - mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2, + mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2, ICH3 or ICH4 southbridge. For details, take a look at . @@ -160,7 +161,7 @@ config X86_SPEEDSTEP_SMI depends on EXPERIMENTAL help This adds the CPUFreq driver for certain mobile Intel Pentium III - (Coppermine), all mobile Intel Pentium III-M (Tualatin) + (Coppermine), all mobile Intel Pentium III-M (Tualatin) on systems which have an Intel 440BX/ZX/MX southbridge. For details, take a look at . @@ -204,8 +205,8 @@ config X86_LONGHAUL select CPU_FREQ_TABLE depends on BROKEN help - This adds the CPUFreq driver for VIA Samuel/CyrixIII, - VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T + This adds the CPUFreq driver for VIA Samuel/CyrixIII, + VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T processors. For details, take a look at . @@ -215,11 +216,11 @@ config X86_LONGHAUL comment "shared options" config X86_ACPI_CPUFREQ_PROC_INTF - bool "/proc/acpi/processor/../performance interface (deprecated)" + bool "/proc/acpi/processor/../performance interface (deprecated)" depends on PROC_FS depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI help - This enables the deprecated /proc/acpi/processor/../performance + This enables the deprecated /proc/acpi/processor/../performance interface. While it is helpful for debugging, the generic, cross-architecture cpufreq interfaces should be used. @@ -233,9 +234,9 @@ config X86_SPEEDSTEP_RELAXED_CAP_CHECK bool "Relaxed speedstep capability checks" depends on (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH) help - Don't perform all checks for a speedstep capable system which would - normally be done. Some ancient or strange systems, though speedstep - capable, don't always indicate that they are speedstep capable. This + Don't perform all checks for a speedstep capable system which would + normally be done. Some ancient or strange systems, though speedstep + capable, don't always indicate that they are speedstep capable. This option lets the probing code bypass some of those checks if the parameter "relaxed_check=1" is passed to the module. diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 97ddb54fe..3852d0a4c 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -452,7 +452,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = { .name = "acpi-cpufreq", .owner = THIS_MODULE, .attr = acpi_cpufreq_attr, - .flags = CPUFREQ_STICKY, }; diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c index f275e0d4a..2b62dee35 100644 --- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c @@ -39,7 +39,7 @@ static struct pci_dev *nforce2_chipset_dev; static int fid = 0; /* min_fsb, max_fsb: - * minimum and maximum FSB (= FSB at boot time) + * minimum and maximum FSB (= FSB at boot time) */ static int min_fsb = 0; static int max_fsb = 0; @@ -57,10 +57,10 @@ MODULE_PARM_DESC(min_fsb, #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg) -/** +/* * nforce2_calc_fsb - calculate FSB * @pll: PLL value - * + * * Calculates FSB from PLL value */ static int nforce2_calc_fsb(int pll) @@ -76,10 +76,10 @@ static int nforce2_calc_fsb(int pll) return 0; } -/** +/* * nforce2_calc_pll - calculate PLL value * @fsb: FSB - * + * * Calculate PLL value for given FSB */ static int nforce2_calc_pll(unsigned int fsb) @@ -106,10 +106,10 @@ static int nforce2_calc_pll(unsigned int fsb) return NFORCE2_PLL(mul, div); } -/** +/* * nforce2_write_pll - write PLL value to chipset * @pll: PLL value - * + * * Writes new FSB PLL value to chipset */ static void nforce2_write_pll(int pll) @@ -121,13 +121,15 @@ static void nforce2_write_pll(int pll) pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, temp); /* Now write the value in all 64 registers */ - for (temp = 0; temp <= 0x3f; temp++) - pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, pll); + for (temp = 0; temp <= 0x3f; temp++) { + pci_write_config_dword(nforce2_chipset_dev, + NFORCE2_PLLREG, pll); + } return; } -/** +/* * nforce2_fsb_read - Read FSB * * Read FSB from chipset @@ -138,32 +140,39 @@ static unsigned int nforce2_fsb_read(int bootfsb) struct pci_dev *nforce2_sub5; u32 fsb, temp = 0; + /* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */ nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, - 0x01EF,PCI_ANY_ID,PCI_ANY_ID,NULL); + 0x01EF, + PCI_ANY_ID, + PCI_ANY_ID, + NULL); + if (!nforce2_sub5) return 0; pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb); fsb /= 1000000; - + /* Check if PLL register is already set */ - pci_read_config_byte(nforce2_chipset_dev,NFORCE2_PLLENABLE, (u8 *)&temp); - + pci_read_config_byte(nforce2_chipset_dev, + NFORCE2_PLLENABLE, (u8 *)&temp); + if(bootfsb || !temp) return fsb; /* Use PLL register FSB value */ - pci_read_config_dword(nforce2_chipset_dev,NFORCE2_PLLREG, &temp); + pci_read_config_dword(nforce2_chipset_dev, + NFORCE2_PLLREG, &temp); fsb = nforce2_calc_fsb(temp); return fsb; } -/** +/* * nforce2_set_fsb - set new FSB * @fsb: New FSB - * + * * Sets new FSB */ static int nforce2_set_fsb(unsigned int fsb) @@ -177,7 +186,7 @@ static int nforce2_set_fsb(unsigned int fsb) printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb); return -EINVAL; } - + tfsb = nforce2_fsb_read(0); if (!tfsb) { printk(KERN_ERR "cpufreq: Error while reading the FSB\n"); @@ -185,7 +194,8 @@ static int nforce2_set_fsb(unsigned int fsb) } /* First write? Then set actual value */ - pci_read_config_byte(nforce2_chipset_dev,NFORCE2_PLLENABLE, (u8 *)&temp); + pci_read_config_byte(nforce2_chipset_dev, + NFORCE2_PLLENABLE, (u8 *)&temp); if (!temp) { pll = nforce2_calc_pll(tfsb); @@ -213,7 +223,7 @@ static int nforce2_set_fsb(unsigned int fsb) /* Calculate the PLL reg. value */ if ((pll = nforce2_calc_pll(tfsb)) == -1) return -EINVAL; - + nforce2_write_pll(pll); #ifdef NFORCE2_DELAY mdelay(NFORCE2_DELAY); @@ -229,7 +239,7 @@ static int nforce2_set_fsb(unsigned int fsb) /** * nforce2_get - get the CPU frequency * @cpu: CPU number - * + * * Returns the CPU frequency */ static unsigned int nforce2_get(unsigned int cpu) @@ -344,10 +354,10 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy) printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb, fid / 10, fid % 10); - + /* Set maximum FSB to FSB at boot time */ max_fsb = nforce2_fsb_read(1); - + if(!max_fsb) return -EIO; @@ -388,15 +398,17 @@ static struct cpufreq_driver nforce2_driver = { * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic * * Detects nForce2 A2 and C1 stepping - * + * */ static unsigned int nforce2_detect_chipset(void) { u8 revision; nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, - PCI_DEVICE_ID_NVIDIA_NFORCE2, - PCI_ANY_ID, PCI_ANY_ID, NULL); + PCI_DEVICE_ID_NVIDIA_NFORCE2, + PCI_ANY_ID, + PCI_ANY_ID, + NULL); if (nforce2_chipset_dev == NULL) return -ENODEV; diff --git a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c index f317276af..3f7caa4ae 100644 --- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c @@ -1,16 +1,16 @@ /* - * elanfreq: cpufreq driver for the AMD ELAN family + * elanfreq: cpufreq driver for the AMD ELAN family * * (c) Copyright 2002 Robert Schwebel * - * Parts of this code are (c) Sven Geggus + * Parts of this code are (c) Sven Geggus * - * All Rights Reserved. + * 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. + * 2 of the License, or (at your option) any later version. * * 2002-02-13: - initial revision for 2.4.18-pre9 by Robert Schwebel * @@ -28,7 +28,7 @@ #include #include -#define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */ +#define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */ #define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */ /* Module parameter */ @@ -41,7 +41,7 @@ struct s_elan_multiplier { }; /* - * It is important that the frequencies + * It is important that the frequencies * are listed in ascending order here! */ struct s_elan_multiplier elan_multiplier[] = { @@ -72,79 +72,78 @@ static struct cpufreq_frequency_table elanfreq_table[] = { * elanfreq_get_cpu_frequency: determine current cpu speed * * Finds out at which frequency the CPU of the Elan SOC runs - * at the moment. Frequencies from 1 to 33 MHz are generated + * at the moment. Frequencies from 1 to 33 MHz are generated * the normal way, 66 and 99 MHz are called "Hyperspeed Mode" - * and have the rest of the chip running with 33 MHz. + * and have the rest of the chip running with 33 MHz. */ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) { - u8 clockspeed_reg; /* Clock Speed Register */ - + u8 clockspeed_reg; /* Clock Speed Register */ + local_irq_disable(); - outb_p(0x80,REG_CSCIR); - clockspeed_reg = inb_p(REG_CSCDR); + outb_p(0x80,REG_CSCIR); + clockspeed_reg = inb_p(REG_CSCDR); local_irq_enable(); - if ((clockspeed_reg & 0xE0) == 0xE0) - return 0; + if ((clockspeed_reg & 0xE0) == 0xE0) { return 0; } - /* Are we in CPU clock multiplied mode (66/99 MHz)? */ - if ((clockspeed_reg & 0xE0) == 0xC0) { - if ((clockspeed_reg & 0x01) == 0) + /* Are we in CPU clock multiplied mode (66/99 MHz)? */ + if ((clockspeed_reg & 0xE0) == 0xC0) { + if ((clockspeed_reg & 0x01) == 0) { return 66000; - else - return 99000; - } + } else { + return 99000; + } + } /* 33 MHz is not 32 MHz... */ if ((clockspeed_reg & 0xE0)==0xA0) return 33000; - return ((1<<((clockspeed_reg & 0xE0) >> 5)) * 1000); + return ((1<<((clockspeed_reg & 0xE0) >> 5)) * 1000); } /** - * elanfreq_set_cpu_frequency: Change the CPU core frequency - * @cpu: cpu number + * elanfreq_set_cpu_frequency: Change the CPU core frequency + * @cpu: cpu number * @freq: frequency in kHz * - * This function takes a frequency value and changes the CPU frequency + * This function takes a frequency value and changes the CPU frequency * according to this. Note that the frequency has to be checked by * elanfreq_validatespeed() for correctness! - * - * There is no return value. + * + * There is no return value. */ -static void elanfreq_set_cpu_state (unsigned int state) -{ +static void elanfreq_set_cpu_state (unsigned int state) { + struct cpufreq_freqs freqs; freqs.old = elanfreq_get_cpu_frequency(0); freqs.new = elan_multiplier[state].clock; freqs.cpu = 0; /* elanfreq.c is UP only driver */ - + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n", - elan_multiplier[state].clock); + printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n",elan_multiplier[state].clock); - /* - * Access to the Elan's internal registers is indexed via - * 0x22: Chip Setup & Control Register Index Register (CSCI) - * 0x23: Chip Setup & Control Register Data Register (CSCD) + /* + * Access to the Elan's internal registers is indexed via + * 0x22: Chip Setup & Control Register Index Register (CSCI) + * 0x23: Chip Setup & Control Register Data Register (CSCD) * */ - /* - * 0x40 is the Power Management Unit's Force Mode Register. + /* + * 0x40 is the Power Management Unit's Force Mode Register. * Bit 6 enables Hyperspeed Mode (66/100 MHz core frequency) */ local_irq_disable(); - outb_p(0x40,REG_CSCIR); /* Disable hyperspeed mode */ + outb_p(0x40,REG_CSCIR); /* Disable hyperspeed mode */ outb_p(0x00,REG_CSCDR); local_irq_enable(); /* wait till internal pipelines and */ udelay(1000); /* buffers have cleaned up */ @@ -167,10 +166,10 @@ static void elanfreq_set_cpu_state (unsigned int state) /** * elanfreq_validatespeed: test if frequency range is valid - * @policy: the policy to validate + * @policy: the policy to validate * - * This function checks if a given frequency range in kHz is valid - * for the hardware supported by the driver. + * This function checks if a given frequency range in kHz is valid + * for the hardware supported by the driver. */ static int elanfreq_verify (struct cpufreq_policy *policy) @@ -178,11 +177,11 @@ static int elanfreq_verify (struct cpufreq_policy *policy) return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]); } -static int elanfreq_target (struct cpufreq_policy *policy, - unsigned int target_freq, +static int elanfreq_target (struct cpufreq_policy *policy, + unsigned int target_freq, unsigned int relation) { - unsigned int newstate = 0; + unsigned int newstate = 0; if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate)) return -EINVAL; @@ -213,7 +212,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) max_freq = elanfreq_get_cpu_frequency(0); /* table init */ - for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { + for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { if (elanfreq_table[i].frequency > max_freq) elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; } @@ -227,7 +226,8 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) if (result) return (result); - cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu); + cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu); + return 0; } @@ -268,9 +268,9 @@ static struct freq_attr* elanfreq_attr[] = { static struct cpufreq_driver elanfreq_driver = { - .get = elanfreq_get_cpu_frequency, - .verify = elanfreq_verify, - .target = elanfreq_target, + .get = elanfreq_get_cpu_frequency, + .verify = elanfreq_verify, + .target = elanfreq_target, .init = elanfreq_cpu_init, .exit = elanfreq_cpu_exit, .name = "elanfreq", @@ -279,21 +279,23 @@ static struct cpufreq_driver elanfreq_driver = { }; -static int __init elanfreq_init(void) -{ +static int __init elanfreq_init(void) +{ struct cpuinfo_x86 *c = cpu_data; /* Test if we have the right hardware */ if ((c->x86_vendor != X86_VENDOR_AMD) || - (c->x86 != 4) || (c->x86_model!=10)) { + (c->x86 != 4) || (c->x86_model!=10)) + { printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); return -ENODEV; } + return cpufreq_register_driver(&elanfreq_driver); } -static void __exit elanfreq_exit(void) +static void __exit elanfreq_exit(void) { cpufreq_unregister_driver(&elanfreq_driver); } @@ -307,3 +309,4 @@ MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs"); module_init(elanfreq_init); module_exit(elanfreq_exit); + diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index 92afa3bc8..e86ea486c 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c @@ -6,12 +6,12 @@ * * 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 + * version 2 as published by the Free Software Foundation * * The author(s) of this software shall not be held liable for damages * of any nature resulting due to the use of this software. This * software is provided AS-IS with no warranties. - * + * * Theoritical note: * * (see Geode(tm) CS5530 manual (rev.4.1) page.56) @@ -21,18 +21,18 @@ * * Suspend Modulation works by asserting and de-asserting the SUSP# pin * to CPU(GX1/GXLV) for configurable durations. When asserting SUSP# - * the CPU enters an idle state. GX1 stops its core clock when SUSP# is + * the CPU enters an idle state. GX1 stops its core clock when SUSP# is * asserted then power consumption is reduced. * - * Suspend Modulation's OFF/ON duration are configurable + * Suspend Modulation's OFF/ON duration are configurable * with 'Suspend Modulation OFF Count Register' * and 'Suspend Modulation ON Count Register'. - * These registers are 8bit counters that represent the number of + * These registers are 8bit counters that represent the number of * 32us intervals which the SUSP# pin is asserted(ON)/de-asserted(OFF) * to the processor. * - * These counters define a ratio which is the effective frequency - * of operation of the system. + * These counters define a ratio which is the effective frequency + * of operation of the system. * * OFF Count * F_eff = Fgx * ---------------------- @@ -40,24 +40,24 @@ * * 0 <= On Count, Off Count <= 255 * - * From these limits, we can get register values + * From these limits, we can get register values * * off_duration + on_duration <= MAX_DURATION * on_duration = off_duration * (stock_freq - freq) / freq * - * off_duration = (freq * DURATION) / stock_freq - * on_duration = DURATION - off_duration + * off_duration = (freq * DURATION) / stock_freq + * on_duration = DURATION - off_duration * * *--------------------------------------------------------------------------- * * ChangeLog: - * Dec. 12, 2003 Hiroshi Miura - * - fix on/off register mistake - * - fix cpu_khz calc when it stops cpu modulation. + * Dec. 12, 2003 Hiroshi Miura + * - fix on/off register mistake + * - fix cpu_khz calc when it stops cpu modulation. * - * Dec. 11, 2002 Hiroshi Miura - * - rewrite for Cyrix MediaGX Cx5510/5520 and + * Dec. 11, 2002 Hiroshi Miura + * - rewrite for Cyrix MediaGX Cx5510/5520 and * NatSemi Geode Cs5530(A). * * Jul. ??, 2002 Zwane Mwaikambo @@ -74,40 +74,40 @@ ************************************************************************/ #include -#include +#include #include #include #include #include -#include +#include #include /* PCI config registers, all at F0 */ -#define PCI_PMER1 0x80 /* power management enable register 1 */ -#define PCI_PMER2 0x81 /* power management enable register 2 */ -#define PCI_PMER3 0x82 /* power management enable register 3 */ -#define PCI_IRQTC 0x8c /* irq speedup timer counter register:typical 2 to 4ms */ -#define PCI_VIDTC 0x8d /* video speedup timer counter register: typical 50 to 100ms */ -#define PCI_MODOFF 0x94 /* suspend modulation OFF counter register, 1 = 32us */ -#define PCI_MODON 0x95 /* suspend modulation ON counter register */ -#define PCI_SUSCFG 0x96 /* suspend configuration register */ +#define PCI_PMER1 0x80 /* power management enable register 1 */ +#define PCI_PMER2 0x81 /* power management enable register 2 */ +#define PCI_PMER3 0x82 /* power management enable register 3 */ +#define PCI_IRQTC 0x8c /* irq speedup timer counter register:typical 2 to 4ms */ +#define PCI_VIDTC 0x8d /* video speedup timer counter register: typical 50 to 100ms */ +#define PCI_MODOFF 0x94 /* suspend modulation OFF counter register, 1 = 32us */ +#define PCI_MODON 0x95 /* suspend modulation ON counter register */ +#define PCI_SUSCFG 0x96 /* suspend configuration register */ /* PMER1 bits */ -#define GPM (1<<0) /* global power management */ -#define GIT (1<<1) /* globally enable PM device idle timers */ -#define GTR (1<<2) /* globally enable IO traps */ -#define IRQ_SPDUP (1<<3) /* disable clock throttle during interrupt handling */ -#define VID_SPDUP (1<<4) /* disable clock throttle during vga video handling */ +#define GPM (1<<0) /* global power management */ +#define GIT (1<<1) /* globally enable PM device idle timers */ +#define GTR (1<<2) /* globally enable IO traps */ +#define IRQ_SPDUP (1<<3) /* disable clock throttle during interrupt handling */ +#define VID_SPDUP (1<<4) /* disable clock throttle during vga video handling */ /* SUSCFG bits */ -#define SUSMOD (1<<0) /* enable/disable suspend modulation */ -/* the belows support only with cs5530 (after rev.1.2)/cs5530A */ -#define SMISPDUP (1<<1) /* select how SMI re-enable suspend modulation: */ - /* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */ -#define SUSCFG (1<<2) /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */ -/* the belows support only with cs5530A */ -#define PWRSVE_ISA (1<<3) /* stop ISA clock */ -#define PWRSVE (1<<4) /* active idle */ +#define SUSMOD (1<<0) /* enable/disable suspend modulation */ +/* the belows support only with cs5530 (after rev.1.2)/cs5530A */ +#define SMISPDUP (1<<1) /* select how SMI re-enable suspend modulation: */ + /* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */ +#define SUSCFG (1<<2) /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */ +/* the belows support only with cs5530A */ +#define PWRSVE_ISA (1<<3) /* stop ISA clock */ +#define PWRSVE (1<<4) /* active idle */ struct gxfreq_params { u8 on_duration; @@ -128,7 +128,7 @@ module_param (pci_busclk, int, 0444); /* maximum duration for which the cpu may be suspended * (32us * MAX_DURATION). If no parameter is given, this defaults - * to 255. + * to 255. * Note that this leads to a maximum of 8 ms(!) where the CPU clock * is suspended -- processing power is just 0.39% of what it used to be, * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */ @@ -144,17 +144,17 @@ module_param (max_duration, int, 0444); #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg) /** - * we can detect a core multipiler from dir0_lsb - * from GX1 datasheet p.56, - * MULT[3:0]: - * 0000 = SYSCLK multiplied by 4 (test only) - * 0001 = SYSCLK multiplied by 10 - * 0010 = SYSCLK multiplied by 4 - * 0011 = SYSCLK multiplied by 6 - * 0100 = SYSCLK multiplied by 9 - * 0101 = SYSCLK multiplied by 5 - * 0110 = SYSCLK multiplied by 7 - * 0111 = SYSCLK multiplied by 8 + * we can detect a core multipiler from dir0_lsb + * from GX1 datasheet p.56, + * MULT[3:0]: + * 0000 = SYSCLK multiplied by 4 (test only) + * 0001 = SYSCLK multiplied by 10 + * 0010 = SYSCLK multiplied by 4 + * 0011 = SYSCLK multiplied by 6 + * 0100 = SYSCLK multiplied by 9 + * 0101 = SYSCLK multiplied by 5 + * 0110 = SYSCLK multiplied by 7 + * 0111 = SYSCLK multiplied by 8 * of 33.3MHz **/ static int gx_freq_mult[16] = { @@ -164,17 +164,17 @@ static int gx_freq_mult[16] = { /**************************************************************** - * Low Level chipset interface * + * Low Level chipset interface * ****************************************************************/ static struct pci_device_id gx_chipset_tbl[] __initdata = { - { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, - { 0, }, + { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID }, + { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, + { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, + { 0, }, }; /** - * gx_detect_chipset: + * gx_detect_chipset: * **/ static __init struct pci_dev *gx_detect_chipset(void) @@ -182,16 +182,17 @@ static __init struct pci_dev *gx_detect_chipset(void) struct pci_dev *gx_pci = NULL; /* check if CPU is a MediaGX or a Geode. */ - if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && + if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && (current_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { dprintk("error: no MediaGX/Geode processor found!\n"); - return NULL; + return NULL; } /* detect which companion chip is used */ while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { - if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) + if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) { return gx_pci; + } } dprintk("error: no supported chipset found!\n"); @@ -199,24 +200,24 @@ static __init struct pci_dev *gx_detect_chipset(void) } /** - * gx_get_cpuspeed: + * gx_get_cpuspeed: * * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs. */ static unsigned int gx_get_cpuspeed(unsigned int cpu) { - if ((gx_params->pci_suscfg & SUSMOD) == 0) + if ((gx_params->pci_suscfg & SUSMOD) == 0) return stock_freq; - return (stock_freq * gx_params->off_duration) + return (stock_freq * gx_params->off_duration) / (gx_params->on_duration + gx_params->off_duration); } /** * gx_validate_speed: * determine current cpu speed - * - **/ + * +**/ static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) { @@ -229,7 +230,7 @@ static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off *on_duration=0; for (i=max_duration; i>0; i--) { - tmp_off = ((khz * i) / stock_freq) & 0xff; + tmp_off = ((khz * i) / stock_freq) & 0xff; tmp_on = i - tmp_off; tmp_freq = (stock_freq * tmp_off) / i; /* if this relation is closer to khz, use this. If it's equal, @@ -246,17 +247,18 @@ static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off /** - * gx_set_cpuspeed: - * set cpu speed in khz. + * gx_set_cpuspeed: + * set cpu speed in khz. **/ static void gx_set_cpuspeed(unsigned int khz) { - u8 suscfg, pmer1; + u8 suscfg, pmer1; unsigned int new_khz; unsigned long flags; struct cpufreq_freqs freqs; + freqs.cpu = 0; freqs.old = gx_get_cpuspeed(0); @@ -301,18 +303,18 @@ static void gx_set_cpuspeed(unsigned int khz) pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration); pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration); - pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg); - pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); + pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg); + pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); - local_irq_restore(flags); + local_irq_restore(flags); gx_params->pci_suscfg = suscfg; cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - dprintk("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", - gx_params->on_duration * 32, gx_params->off_duration * 32); - dprintk("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); + dprintk("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", + gx_params->on_duration * 32, gx_params->off_duration * 32); + dprintk("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); } /**************************************************************** @@ -320,10 +322,10 @@ static void gx_set_cpuspeed(unsigned int khz) ****************************************************************/ /* - * cpufreq_gx_verify: test if frequency range is valid + * cpufreq_gx_verify: test if frequency range is valid * - * This function checks if a given frequency range in kHz is valid - * for the hardware supported by the driver. + * This function checks if a given frequency range in kHz is valid + * for the hardware supported by the driver. */ static int cpufreq_gx_verify(struct cpufreq_policy *policy) @@ -331,8 +333,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) unsigned int tmp_freq = 0; u8 tmp1, tmp2; - if (!stock_freq || !policy) - return -EINVAL; + if (!stock_freq || !policy) + return -EINVAL; policy->cpu = 0; cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); @@ -340,14 +342,14 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) /* it needs to be assured that at least one supported frequency is * within policy->min and policy->max. If it is not, policy->max * needs to be increased until one freuqency is supported. - * policy->min may not be decreased, though. This way we guarantee a + * policy->min may not be decreased, though. This way we guarantee a * specific processing capacity. */ tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2); - if (tmp_freq < policy->min) + if (tmp_freq < policy->min) tmp_freq += stock_freq / max_duration; policy->min = tmp_freq; - if (policy->min > policy->max) + if (policy->min > policy->max) policy->max = tmp_freq; tmp_freq = gx_validate_speed(policy->max, &tmp1, &tmp2); if (tmp_freq > policy->max) @@ -356,12 +358,12 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) if (policy->max < policy->min) policy->max = policy->min; cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); - + return 0; } /* - * cpufreq_gx_target: + * cpufreq_gx_target: * */ static int cpufreq_gx_target(struct cpufreq_policy *policy, @@ -371,8 +373,8 @@ static int cpufreq_gx_target(struct cpufreq_policy *policy, u8 tmp1, tmp2; unsigned int tmp_freq; - if (!stock_freq || !policy) - return -EINVAL; + if (!stock_freq || !policy) + return -EINVAL; policy->cpu = 0; @@ -429,7 +431,7 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) return 0; } -/* +/* * cpufreq_gx_init: * MediaGX/Geode GX initialize cpufreq driver */ @@ -450,7 +452,7 @@ static int __init cpufreq_gx_init(void) u32 class_rev; /* Test if we have the right hardware */ - if ((gx_pci = gx_detect_chipset()) == NULL) + if ((gx_pci = gx_detect_chipset()) == NULL) return -ENODEV; /* check whether module parameters are sane */ @@ -459,9 +461,10 @@ static int __init cpufreq_gx_init(void) dprintk("geode suspend modulation available.\n"); - params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL); + params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL); if (params == NULL) return -ENOMEM; + memset(params, 0, sizeof(struct gxfreq_params)); params->cs55x0 = gx_pci; gx_params = params; @@ -475,7 +478,7 @@ static int __init cpufreq_gx_init(void) pci_read_config_dword(params->cs55x0, PCI_CLASS_REVISION, &class_rev); params->pci_rev = class_rev && 0xff; - if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { + if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { kfree(params); return ret; /* register error! */ } diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.h b/arch/i386/kernel/cpu/cpufreq/longhaul.h index d3a95d77e..2a495c162 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.h +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.h @@ -234,7 +234,7 @@ static int __initdata ezrat_eblcr[32] = { /* * VIA C3 Nehemiah */ - + static int __initdata nehemiah_a_clock_ratio[32] = { 100, /* 0000 -> 10.0x */ 160, /* 0001 -> 16.0x */ @@ -446,7 +446,7 @@ static int __initdata nehemiah_c_eblcr[32] = { /* end of table */ }; -/* +/* * Voltage scales. Div/Mod by 1000 to get actual voltage. * Which scale to use depends on the VRM type in use. */ diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index ab6504efd..ebe184816 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -14,7 +14,7 @@ * The author(s) of this software shall not be held liable for damages * of any nature resulting due to the use of this software. This * software is provided AS-IS with no warranties. - * + * * Date Errata Description * 20020525 N44, O17 12.5% or 25% DC causes lockup * @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include @@ -30,7 +30,7 @@ #include #include /* current / set_cpus_allowed() */ -#include +#include #include #include @@ -79,7 +79,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) } else { dprintk("CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10)); - /* bits 63 - 5 : reserved + /* bits 63 - 5 : reserved * bit 4 : enable/disable * bits 3-1 : duty cycle * bit 0 : reserved @@ -132,7 +132,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, } /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software - * Developer's Manual, Volume 3 + * Developer's Manual, Volume 3 */ cpus_allowed = current->cpus_allowed; @@ -206,7 +206,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4D); } - + static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) { @@ -234,7 +234,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) dprintk("has errata -- disabling frequencies lower than 2ghz\n"); break; } - + /* get max frequency */ stock_freq = cpufreq_p4_get_frequency(c); if (!stock_freq) @@ -250,7 +250,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) p4clockmod_table[i].frequency = (stock_freq * i)/8; } cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); - + /* cpuinfo and default policy values */ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 1000000; /* assumed */ @@ -262,7 +262,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy) { - cpufreq_frequency_table_put_attr(policy->cpu); + cpufreq_frequency_table_put_attr(policy->cpu); return 0; } @@ -298,7 +298,7 @@ static struct freq_attr* p4clockmod_attr[] = { }; static struct cpufreq_driver p4clockmod_driver = { - .verify = cpufreq_p4_verify, + .verify = cpufreq_p4_verify, .target = cpufreq_p4_target, .init = cpufreq_p4_cpu_init, .exit = cpufreq_p4_cpu_exit, @@ -310,12 +310,12 @@ static struct cpufreq_driver p4clockmod_driver = { static int __init cpufreq_p4_init(void) -{ +{ struct cpuinfo_x86 *c = cpu_data; int ret; /* - * THERM_CONTROL is architectural for IA32 now, so + * THERM_CONTROL is architectural for IA32 now, so * we can rely on the capability checks */ if (c->x86_vendor != X86_VENDOR_INTEL) diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c index f89524051..222f8cfe3 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c @@ -8,7 +8,7 @@ */ #include -#include +#include #include #include #include @@ -50,7 +50,7 @@ static int powernow_k6_get_cpu_multiplier(void) { u64 invalue = 0; u32 msrval; - + msrval = POWERNOW_IOPORT + 0x1; wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ invalue=inl(POWERNOW_IOPORT + 0x8); @@ -81,7 +81,7 @@ static void powernow_k6_set_state (unsigned int best_i) freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); freqs.new = busfreq * clock_ratio[best_i].index; freqs.cpu = 0; /* powernow-k6.c is UP only driver */ - + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); /* we now need to transform best_i to the BVC format, see AMD#23446 */ @@ -152,7 +152,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) busfreq = cpu_khz / max_multiplier; /* table init */ - for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { + for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { if (clock_ratio[i].index > max_multiplier) clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; else @@ -182,7 +182,7 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) powernow_k6_set_state(i); } cpufreq_frequency_table_put_attr(policy->cpu); - return 0; + return 0; } static unsigned int powernow_k6_get(unsigned int cpu) @@ -196,8 +196,8 @@ static struct freq_attr* powernow_k6_attr[] = { }; static struct cpufreq_driver powernow_k6_driver = { - .verify = powernow_k6_verify, - .target = powernow_k6_target, + .verify = powernow_k6_verify, + .target = powernow_k6_target, .init = powernow_k6_cpu_init, .exit = powernow_k6_cpu_exit, .get = powernow_k6_get, @@ -215,7 +215,7 @@ static struct cpufreq_driver powernow_k6_driver = { * on success. */ static int __init powernow_k6_init(void) -{ +{ struct cpuinfo_x86 *c = cpu_data; if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) || diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index a748409b7..8439f90eb 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c @@ -199,8 +199,8 @@ static int get_ranges (unsigned char *pst) powernow_table[j].index |= (vid << 8); /* upper 8 bits */ dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " - "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, - fid_codes[fid] % 10, speed/1000, vid, + "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, + fid_codes[fid] % 10, speed/1000, vid, mobile_vid_table[vid]/1000, mobile_vid_table[vid]%1000); } @@ -368,8 +368,8 @@ static int powernow_acpi_init(void) } dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " - "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, - fid_codes[fid] % 10, speed/1000, vid, + "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, + fid_codes[fid] % 10, speed/1000, vid, mobile_vid_table[vid]/1000, mobile_vid_table[vid]%1000); @@ -460,7 +460,7 @@ static int powernow_decode_bios (int maxfid, int startvid) (maxfid==pst->maxfid) && (startvid==pst->startvid)) { dprintk ("PST:%d (@%p)\n", i, pst); - dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", + dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); ret = get_ranges ((char *) pst + sizeof (struct pst_s)); diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 2ea3c6cac..c2719ab69 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -40,17 +40,16 @@ #ifdef CONFIG_X86_POWERNOW_K8_ACPI #include -#include #include #endif #define PFX "powernow-k8: " #define BFX PFX "BIOS error: " -#define VERSION "version 1.60.2" +#define VERSION "version 1.60.0" #include "powernow-k8.h" /* serialize freq changes */ -static DEFINE_MUTEX(fidvid_mutex); +static DECLARE_MUTEX(fidvid_sem); static struct powernow_k8_data *powernow_data[NR_CPUS]; @@ -84,10 +83,11 @@ static u32 find_millivolts_from_vid(struct powernow_k8_data *data, u32 vid) */ static u32 convert_fid_to_vco_fid(u32 fid) { - if (fid < HI_FID_TABLE_BOTTOM) + if (fid < HI_FID_TABLE_BOTTOM) { return 8 + (2 * fid); - else + } else { return fid; + } } /* @@ -177,7 +177,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) if (i++ > 100) { printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); return 1; - } + } } while (query_current_values_with_pending_wait(data)); count_off_irt(data); @@ -474,10 +474,8 @@ static int check_supported_cpu(unsigned int cpu) goto out; eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); - if ((eax & CPUID_XFAM) != CPUID_XFAM_K8) - goto out; - if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || + ((eax & CPUID_XFAM) != CPUID_XFAM_K8) || ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); goto out; @@ -782,7 +780,9 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) /* verify only 1 entry from the lo frequency table */ if (fid < HI_FID_TABLE_BOTTOM) { if (cntlofreq) { - /* if both entries are the same, ignore this one ... */ + /* if both entries are the same, ignore this + * one... + */ if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || (powernow_table[i].index != powernow_table[cntlofreq].index)) { printk(KERN_ERR PFX "Too many lo freq table entries\n"); @@ -854,7 +854,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); /* fid are the lower 8 bits of the index we stored into - * the cpufreq frequency table in find_psb_table, vid are + * the cpufreq frequency table in find_psb_table, vid are * the upper 8 bits. */ @@ -905,16 +905,11 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi { cpumask_t oldmask = CPU_MASK_ALL; struct powernow_k8_data *data = powernow_data[pol->cpu]; - u32 checkfid; - u32 checkvid; + u32 checkfid = data->currfid; + u32 checkvid = data->currvid; unsigned int newstate; int ret = -EIO; - - if (!data) - return -EINVAL; - - checkfid = data->currfid; - checkvid = data->currvid; + int i; /* only run on specific CPU from here on */ oldmask = current->cpus_allowed; @@ -950,17 +945,23 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) goto err_out; - mutex_lock(&fidvid_mutex); + down(&fidvid_sem); powernow_k8_acpi_pst_values(data, newstate); if (transition_frequency(data, newstate)) { printk(KERN_ERR PFX "transition frequency failed\n"); ret = 1; - mutex_unlock(&fidvid_mutex); + up(&fidvid_sem); goto err_out; } - mutex_unlock(&fidvid_mutex); + + /* Update all the fid/vids of our siblings */ + for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { + powernow_data[i]->currvid = data->currvid; + powernow_data[i]->currfid = data->currfid; + } + up(&fidvid_sem); pol->cur = find_khz_freq_from_fid(data->currfid); ret = 0; @@ -975,9 +976,6 @@ static int powernowk8_verify(struct cpufreq_policy *pol) { struct powernow_k8_data *data = powernow_data[pol->cpu]; - if (!data) - return -EINVAL; - return cpufreq_frequency_table_verify(pol, data->powernow_table); } @@ -986,7 +984,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) { struct powernow_k8_data *data; cpumask_t oldmask = CPU_MASK_ALL; - int rc; + int rc, i; if (!cpu_online(pol->cpu)) return -ENODEV; @@ -1050,7 +1048,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) pol->governor = CPUFREQ_DEFAULT_GOVERNOR; pol->cpus = cpu_core_map[pol->cpu]; - /* Take a crude guess here. + /* Take a crude guess here. * That guess was in microseconds, so multiply with 1000 */ pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) + (3 * (1 << data->irt) * 10)) * 1000; @@ -1072,7 +1070,9 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) printk("cpu_init done, current fid 0x%x, vid 0x%x\n", data->currfid, data->currvid); - powernow_data[pol->cpu] = data; + for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { + powernow_data[i] = data; + } return 0; @@ -1103,15 +1103,10 @@ static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol) static unsigned int powernowk8_get (unsigned int cpu) { - struct powernow_k8_data *data; + struct powernow_k8_data *data = powernow_data[cpu]; cpumask_t oldmask = current->cpus_allowed; unsigned int khz = 0; - data = powernow_data[first_cpu(cpu_core_map[cpu])]; - - if (!data) - return -EINVAL; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); if (smp_processor_id() != cpu) { printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu); @@ -1150,14 +1145,16 @@ static int __cpuinit powernowk8_init(void) { unsigned int i, supported_cpus = 0; - for_each_online_cpu(i) { + for (i=0; icpu]; /* Only Intel makes Enhanced Speedstep-capable CPUs */ if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST)) return -ENODEV; - if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC)) + if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { centrino_driver.flags |= CPUFREQ_CONST_LOOPS; + } if (centrino_cpu_init_acpi(policy)) { if (policy->cpu != 0) diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index 4f46cac15..7c47005a1 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include #include @@ -36,8 +36,8 @@ static unsigned int pentium3_get_frequency (unsigned int processor) /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ struct { unsigned int ratio; /* Frequency Multiplier (x10) */ - u8 bitmap; /* power on configuration bits - [27, 25:22] (in MSR 0x2a) */ + u8 bitmap; /* power on configuration bits + [27, 25:22] (in MSR 0x2a) */ } msr_decode_mult [] = { { 30, 0x01 }, { 35, 0x05 }, @@ -58,9 +58,9 @@ static unsigned int pentium3_get_frequency (unsigned int processor) /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ struct { - unsigned int value; /* Front Side Bus speed in MHz */ - u8 bitmap; /* power on configuration bits [18: 19] - (in MSR 0x2a) */ + unsigned int value; /* Front Side Bus speed in MHz */ + u8 bitmap; /* power on configuration bits [18: 19] + (in MSR 0x2a) */ } msr_decode_fsb [] = { { 66, 0x0 }, { 100, 0x2 }, @@ -68,8 +68,8 @@ static unsigned int pentium3_get_frequency (unsigned int processor) { 0, 0xff} }; - u32 msr_lo, msr_tmp; - int i = 0, j = 0; + u32 msr_lo, msr_tmp; + int i = 0, j = 0; /* read MSR 0x2a - we only need the low 32 bits */ rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); @@ -106,7 +106,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor) static unsigned int pentiumM_get_frequency(void) { - u32 msr_lo, msr_tmp; + u32 msr_lo, msr_tmp; rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); dprintk("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); @@ -134,7 +134,7 @@ static unsigned int pentium4_get_frequency(void) dprintk("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); - /* decode the FSB: see IA-32 Intel (C) Architecture Software + /* decode the FSB: see IA-32 Intel (C) Architecture Software * Developer's Manual, Volume 3: System Prgramming Guide, * revision #12 in Table B-1: MSRs in the Pentium 4 and * Intel Xeon Processors, on page B-4 and B-5. @@ -170,7 +170,7 @@ static unsigned int pentium4_get_frequency(void) return (fsb * mult); } - + unsigned int speedstep_get_processor_frequency(unsigned int processor) { switch (processor) { @@ -198,11 +198,11 @@ EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency); unsigned int speedstep_detect_processor (void) { struct cpuinfo_x86 *c = cpu_data; - u32 ebx, msr_lo, msr_hi; + u32 ebx, msr_lo, msr_hi; dprintk("x86: %x, model: %x\n", c->x86, c->x86_model); - if ((c->x86_vendor != X86_VENDOR_INTEL) || + if ((c->x86_vendor != X86_VENDOR_INTEL) || ((c->x86 != 6) && (c->x86 != 0xF))) return 0; @@ -218,15 +218,15 @@ unsigned int speedstep_detect_processor (void) dprintk("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask); switch (c->x86_mask) { - case 4: + case 4: /* - * B-stepping [M-P4-M] + * B-stepping [M-P4-M] * sample has ebx = 0x0f, production has 0x0e. */ if ((ebx == 0x0e) || (ebx == 0x0f)) return SPEEDSTEP_PROCESSOR_P4M; break; - case 7: + case 7: /* * C-stepping [M-P4-M] * needs to have ebx=0x0e, else it's a celeron: @@ -253,7 +253,7 @@ unsigned int speedstep_detect_processor (void) * also, M-P4M HTs have ebx=0x8, too * For now, they are distinguished by the model_id string */ - if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL)) + if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL)) return SPEEDSTEP_PROCESSOR_P4M; break; default: @@ -264,7 +264,8 @@ unsigned int speedstep_detect_processor (void) switch (c->x86_model) { case 0x0B: /* Intel PIII [Tualatin] */ - /* cpuid_ebx(1) is 0x04 for desktop PIII, 0x06 for mobile PIII-M */ + /* cpuid_ebx(1) is 0x04 for desktop PIII, + 0x06 for mobile PIII-M */ ebx = cpuid_ebx(0x00000001); dprintk("ebx is %x\n", ebx); @@ -274,8 +275,9 @@ unsigned int speedstep_detect_processor (void) return 0; /* So far all PIII-M processors support SpeedStep. See - * Intel's 24540640.pdf of June 2003 + * Intel's 24540640.pdf of June 2003 */ + return SPEEDSTEP_PROCESSOR_PIII_T; case 0x08: /* Intel PIII [Coppermine] */ @@ -397,7 +399,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, } } -out: + out: local_irq_restore(flags); return (ret); } diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h index b735429c5..6a727fd3a 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h @@ -14,7 +14,7 @@ #define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001 /* Coppermine core */ #define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002 /* Coppermine core */ -#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */ +#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */ #define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M */ /* the following processors are not speedstep-capable and are not auto-detected @@ -25,8 +25,8 @@ /* speedstep states -- only two of them */ -#define SPEEDSTEP_HIGH 0x00000000 -#define SPEEDSTEP_LOW 0x00000001 +#define SPEEDSTEP_HIGH 0x00000000 +#define SPEEDSTEP_LOW 0x00000001 /* detect a speedstep-capable processor */ @@ -36,13 +36,13 @@ extern unsigned int speedstep_detect_processor (void); extern unsigned int speedstep_get_processor_frequency(unsigned int processor); -/* detect the low and high speeds of the processor. The callback - * set_state"'s first argument is either SPEEDSTEP_HIGH or - * SPEEDSTEP_LOW; the second argument is zero so that no +/* detect the low and high speeds of the processor. The callback + * set_state"'s first argument is either SPEEDSTEP_HIGH or + * SPEEDSTEP_LOW; the second argument is zero so that no * cpufreq_notify_transition calls are initiated. */ extern unsigned int speedstep_get_freqs(unsigned int processor, - unsigned int *low_speed, - unsigned int *high_speed, - unsigned int *transition_latency, - void (*set_state) (unsigned int state)); + unsigned int *low_speed, + unsigned int *high_speed, + unsigned int *transition_latency, + void (*set_state) (unsigned int state)); diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index c28333d53..cfc4276e6 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c @@ -13,8 +13,8 @@ *********************************************************************/ #include -#include -#include +#include +#include #include #include #include @@ -28,21 +28,21 @@ * * These parameters are got from IST-SMI BIOS call. * If user gives it, these are used. - * + * */ -static int smi_port = 0; -static int smi_cmd = 0; -static unsigned int smi_sig = 0; +static int smi_port = 0; +static int smi_cmd = 0; +static unsigned int smi_sig = 0; /* info about the processor */ -static unsigned int speedstep_processor = 0; +static unsigned int speedstep_processor = 0; -/* - * There are only two frequency states for each processor. Values +/* + * There are only two frequency states for each processor. Values * are in kHz for the time being. */ static struct cpufreq_frequency_table speedstep_freqs[] = { - {SPEEDSTEP_HIGH, 0}, + {SPEEDSTEP_HIGH, 0}, {SPEEDSTEP_LOW, 0}, {0, CPUFREQ_TABLE_END}, }; @@ -125,7 +125,7 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high) *low = low_mhz * 1000; return result; -} +} /** * speedstep_get_state - set the SpeedStep state @@ -206,7 +206,7 @@ static void speedstep_set_state (unsigned int state) * speedstep_target - set a new CPUFreq policy * @policy: new policy * @target_freq: new freq - * @relation: + * @relation: * * Sets a new CPUFreq policy/freq. */ @@ -285,7 +285,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) state = speedstep_get_state(); speed = speedstep_freqs[state].frequency; - dprintk("currently at %s speed setting - %i MHz\n", + dprintk("currently at %s speed setting - %i MHz\n", (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high", (speed / 1000)); @@ -298,7 +298,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) if (result) return (result); - cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); + cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); return 0; } @@ -334,8 +334,8 @@ static struct freq_attr* speedstep_attr[] = { static struct cpufreq_driver speedstep_driver = { .name = "speedstep-smi", - .verify = speedstep_verify, - .target = speedstep_target, + .verify = speedstep_verify, + .target = speedstep_target, .init = speedstep_cpu_init, .exit = speedstep_cpu_exit, .get = speedstep_get, @@ -372,12 +372,13 @@ static int __init speedstep_init(void) return -ENODEV; } - dprintk("signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n", + dprintk("signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n", ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level); - /* Error if no IST-SMI BIOS or no PARM + + /* Error if no IST-SMI BIOS or no PARM sig= 'ISGE' aka 'Intel Speedstep Gate E' */ - if ((ist_info.signature != 0x47534943) && ( + if ((ist_info.signature != 0x47534943) && ( (smi_port == 0) || (smi_cmd == 0))) return -ENODEV; @@ -387,15 +388,17 @@ static int __init speedstep_init(void) smi_sig = ist_info.signature; /* setup smi_port from MODLULE_PARM or BIOS */ - if ((smi_port > 0xff) || (smi_port < 0)) + if ((smi_port > 0xff) || (smi_port < 0)) { return -EINVAL; - else if (smi_port == 0) + } else if (smi_port == 0) { smi_port = ist_info.command & 0xff; + } - if ((smi_cmd > 0xff) || (smi_cmd < 0)) + if ((smi_cmd > 0xff) || (smi_cmd < 0)) { return -EINVAL; - else if (smi_cmd == 0) + } else if (smi_cmd == 0) { smi_cmd = (ist_info.command >> 16) & 0xff; + } return cpufreq_register_driver(&speedstep_driver); } diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 5386b29bb..8c0120186 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -29,7 +29,7 @@ extern int trap_init_f00f_bug(void); struct movsl_mask movsl_mask __read_mostly; #endif -void __cpuinit early_intel_workaround(struct cpuinfo_x86 *c) +void __devinit early_intel_workaround(struct cpuinfo_x86 *c) { if (c->x86_vendor != X86_VENDOR_INTEL) return; @@ -44,7 +44,7 @@ void __cpuinit early_intel_workaround(struct cpuinfo_x86 *c) * This is called before we do cpu ident work */ -int __cpuinit ppro_with_ram_bug(void) +int __devinit ppro_with_ram_bug(void) { /* Uses data from early_cpu_detect now */ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && @@ -62,7 +62,7 @@ int __cpuinit ppro_with_ram_bug(void) * P4 Xeon errata 037 workaround. * Hardware prefetcher may cause stale data to be loaded into the cache. */ -static void __cpuinit Intel_errata_workarounds(struct cpuinfo_x86 *c) +static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c) { unsigned long lo, hi; @@ -81,7 +81,7 @@ static void __cpuinit Intel_errata_workarounds(struct cpuinfo_x86 *c) /* * find out the number of processor cores on the die */ -static int __cpuinit num_cpu_cores(struct cpuinfo_x86 *c) +static int __devinit num_cpu_cores(struct cpuinfo_x86 *c) { unsigned int eax, ebx, ecx, edx; @@ -96,7 +96,7 @@ static int __cpuinit num_cpu_cores(struct cpuinfo_x86 *c) return 1; } -static void __cpuinit init_intel(struct cpuinfo_x86 *c) +static void __devinit init_intel(struct cpuinfo_x86 *c) { unsigned int l2 = 0; char *p = NULL; @@ -205,7 +205,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) return size; } -static struct cpu_dev intel_cpu_dev __cpuinitdata = { +static struct cpu_dev intel_cpu_dev __devinitdata = { .c_vendor = "Intel", .c_ident = { "GenuineIntel" }, .c_models = { diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index f3f2bc883..ffe58cee0 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -173,12 +173,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ - unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; -#ifdef CONFIG_SMP - unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data); -#endif - if (c->cpuid_level > 3) { + if (c->cpuid_level > 4) { static int is_initialized; if (is_initialized == 0) { @@ -209,15 +205,9 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) break; case 2: new_l2 = this_leaf.size/1024; - num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; - index_msb = get_count_order(num_threads_sharing); - l2_id = c->apicid >> index_msb; break; case 3: new_l3 = this_leaf.size/1024; - num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; - index_msb = get_count_order(num_threads_sharing); - l3_id = c->apicid >> index_msb; break; default: break; @@ -225,19 +215,11 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) } } } - /* - * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for - * trace cache - */ - if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { + if (c->cpuid_level > 1) { /* supports eax=2 call */ int i, j, n; int regs[4]; unsigned char *dp = (unsigned char *)regs; - int only_trace = 0; - - if (num_cache_leaves != 0 && c->x86 == 15) - only_trace = 1; /* Number of times to iterate */ n = cpuid_eax(2) & 0xFF; @@ -259,8 +241,6 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) while (cache_table[k].descriptor != 0) { if (cache_table[k].descriptor == des) { - if (only_trace && cache_table[k].cache_type != LVL_TRACE) - break; switch (cache_table[k].cache_type) { case LVL_1_INST: l1i += cache_table[k].size; @@ -286,45 +266,34 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) } } } - } - if (new_l1d) - l1d = new_l1d; + if (new_l1d) + l1d = new_l1d; - if (new_l1i) - l1i = new_l1i; + if (new_l1i) + l1i = new_l1i; - if (new_l2) { - l2 = new_l2; -#ifdef CONFIG_SMP - cpu_llc_id[cpu] = l2_id; -#endif - } + if (new_l2) + l2 = new_l2; - if (new_l3) { - l3 = new_l3; -#ifdef CONFIG_SMP - cpu_llc_id[cpu] = l3_id; -#endif - } - - if (trace) - printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); - else if ( l1i ) - printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); + if (new_l3) + l3 = new_l3; - if (l1d) - printk(", L1 D cache: %dK\n", l1d); - else - printk("\n"); + if ( trace ) + printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); + else if ( l1i ) + printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); + if ( l1d ) + printk(", L1 D cache: %dK\n", l1d); + else + printk("\n"); + if ( l2 ) + printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); + if ( l3 ) + printk(KERN_INFO "CPU: L3 cache: %dK\n", l3); - if (l2) - printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); - - if (l3) - printk(KERN_INFO "CPU: L3 cache: %dK\n", l3); - - c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); + c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); + } return l2; } @@ -361,7 +330,7 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) } } } -static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) +static void __devinit cache_remove_shared_cpu_map(unsigned int cpu, int index) { struct _cpuid4_info *this_leaf, *sibling_leaf; int sibling; @@ -628,7 +597,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) return retval; } -static void cache_remove_dev(struct sys_device * sys_dev) +static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) { unsigned int cpu = sys_dev->id; unsigned long i; @@ -642,7 +611,7 @@ static void cache_remove_dev(struct sys_device * sys_dev) return; } -static int cacheinfo_cpu_callback(struct notifier_block *nfb, +static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c index afa0888f9..6170af3c2 100644 --- a/arch/i386/kernel/cpu/mcheck/mce.c +++ b/arch/i386/kernel/cpu/mcheck/mce.c @@ -64,13 +64,13 @@ void mcheck_init(struct cpuinfo_x86 *c) static int __init mcheck_disable(char *str) { mce_disabled = 1; - return 1; + return 0; } static int __init mcheck_enable(char *str) { mce_disabled = -1; - return 1; + return 0; } __setup("nomce", mcheck_disable); diff --git a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/i386/kernel/cpu/mtrr/Makefile index 06df4feee..a25b701ab 100644 --- a/arch/i386/kernel/cpu/mtrr/Makefile +++ b/arch/i386/kernel/cpu/mtrr/Makefile @@ -3,10 +3,3 @@ obj-y += amd.o obj-y += cyrix.o obj-y += centaur.o -ifdef CONFIG_XEN -include $(srctree)/scripts/Makefile.xen -n-obj-xen := generic.o state.o amd.o cyrix.o centaur.o - -obj-y := $(call filterxen, $(obj-y), $(n-obj-xen)) -obj-y := $(call cherrypickxen, $(obj-y)) -endif diff --git a/arch/i386/kernel/cpu/mtrr/main-xen.c b/arch/i386/kernel/cpu/mtrr/main-xen.c deleted file mode 100644 index 9d68dac22..000000000 --- a/arch/i386/kernel/cpu/mtrr/main-xen.c +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include "mtrr.h" - -static DEFINE_MUTEX(mtrr_mutex); - -void generic_get_mtrr(unsigned int reg, unsigned long *base, - unsigned int *size, mtrr_type * type) -{ - dom0_op_t op; - - op.cmd = DOM0_READ_MEMTYPE; - op.u.read_memtype.reg = reg; - (void)HYPERVISOR_dom0_op(&op); - - *size = op.u.read_memtype.nr_mfns; - *base = op.u.read_memtype.mfn; - *type = op.u.read_memtype.type; -} - -struct mtrr_ops generic_mtrr_ops = { - .use_intel_if = 1, - .get = generic_get_mtrr, -}; - -struct mtrr_ops *mtrr_if = &generic_mtrr_ops; -unsigned int num_var_ranges; -unsigned int *usage_table; - -static void __init set_num_var_ranges(void) -{ - dom0_op_t op; - - for (num_var_ranges = 0; ; num_var_ranges++) { - op.cmd = DOM0_READ_MEMTYPE; - op.u.read_memtype.reg = num_var_ranges; - if (HYPERVISOR_dom0_op(&op) != 0) - break; - } -} - -static void __init init_table(void) -{ - int i, max; - - max = num_var_ranges; - if ((usage_table = kmalloc(max * sizeof *usage_table, GFP_KERNEL)) - == NULL) { - printk(KERN_ERR "mtrr: could not allocate\n"); - return; - } - for (i = 0; i < max; i++) - usage_table[i] = 0; -} - -int mtrr_add_page(unsigned long base, unsigned long size, - unsigned int type, char increment) -{ - int error; - dom0_op_t op; - - mutex_lock(&mtrr_mutex); - - op.cmd = DOM0_ADD_MEMTYPE; - op.u.add_memtype.mfn = base; - op.u.add_memtype.nr_mfns = size; - op.u.add_memtype.type = type; - error = HYPERVISOR_dom0_op(&op); - if (error) { - mutex_unlock(&mtrr_mutex); - BUG_ON(error > 0); - return error; - } - - if (increment) - ++usage_table[op.u.add_memtype.reg]; - - mutex_unlock(&mtrr_mutex); - - return op.u.add_memtype.reg; -} - -static int mtrr_check(unsigned long base, unsigned long size) -{ - if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { - printk(KERN_WARNING - "mtrr: size and base must be multiples of 4 kiB\n"); - printk(KERN_DEBUG - "mtrr: size: 0x%lx base: 0x%lx\n", size, base); - dump_stack(); - return -1; - } - return 0; -} - -int -mtrr_add(unsigned long base, unsigned long size, unsigned int type, - char increment) -{ - if (mtrr_check(base, size)) - return -EINVAL; - return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, - increment); -} - -int mtrr_del_page(int reg, unsigned long base, unsigned long size) -{ - unsigned i; - mtrr_type ltype; - unsigned long lbase; - unsigned int lsize; - int error = -EINVAL; - dom0_op_t op; - - mutex_lock(&mtrr_mutex); - - if (reg < 0) { - /* Search for existing MTRR */ - for (i = 0; i < num_var_ranges; ++i) { - mtrr_if->get(i, &lbase, &lsize, <ype); - if (lbase == base && lsize == size) { - reg = i; - break; - } - } - if (reg < 0) { - printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base, - size); - goto out; - } - } - if (usage_table[reg] < 1) { - printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg); - goto out; - } - if (--usage_table[reg] < 1) { - op.cmd = DOM0_DEL_MEMTYPE; - op.u.del_memtype.handle = 0; - op.u.del_memtype.reg = reg; - error = HYPERVISOR_dom0_op(&op); - if (error) { - BUG_ON(error > 0); - goto out; - } - } - error = reg; - out: - mutex_unlock(&mtrr_mutex); - return error; -} - -int -mtrr_del(int reg, unsigned long base, unsigned long size) -{ - if (mtrr_check(base, size)) - return -EINVAL; - return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); -} - -EXPORT_SYMBOL(mtrr_add); -EXPORT_SYMBOL(mtrr_del); - -void __init mtrr_bp_init(void) -{ -} - -void mtrr_ap_init(void) -{ -} - -static int __init mtrr_init(void) -{ - struct cpuinfo_x86 *c = &boot_cpu_data; - - if (!(xen_start_info->flags & SIF_PRIVILEGED)) - return -ENODEV; - - if ((!cpu_has(c, X86_FEATURE_MTRR)) && - (!cpu_has(c, X86_FEATURE_K6_MTRR)) && - (!cpu_has(c, X86_FEATURE_CYRIX_ARR)) && - (!cpu_has(c, X86_FEATURE_CENTAUR_MCR))) - return -ENODEV; - - set_num_var_ranges(); - init_table(); - - return 0; -} - -subsys_initcall(mtrr_init); diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index fff90bda4..3b4618bed 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -36,7 +36,6 @@ #include #include #include -#include #include @@ -48,7 +47,7 @@ u32 num_var_ranges = 0; unsigned int *usage_table; -static DEFINE_MUTEX(mtrr_mutex); +static DECLARE_MUTEX(mtrr_sem); u32 size_or_mask, size_and_mask; @@ -334,7 +333,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, /* No CPU hotplug when we change MTRR entries */ lock_cpu_hotplug(); /* Search for existing MTRR */ - mutex_lock(&mtrr_mutex); + down(&mtrr_sem); for (i = 0; i < num_var_ranges; ++i) { mtrr_if->get(i, &lbase, &lsize, <ype); if (base >= lbase + lsize) @@ -372,7 +371,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, printk(KERN_INFO "mtrr: no more MTRRs available\n"); error = i; out: - mutex_unlock(&mtrr_mutex); + up(&mtrr_sem); unlock_cpu_hotplug(); return error; } @@ -465,7 +464,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) max = num_var_ranges; /* No CPU hotplug when we change MTRR entries */ lock_cpu_hotplug(); - mutex_lock(&mtrr_mutex); + down(&mtrr_sem); if (reg < 0) { /* Search for existing MTRR */ for (i = 0; i < max; ++i) { @@ -504,7 +503,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) set_mtrr(reg, 0, 0, 0); error = reg; out: - mutex_unlock(&mtrr_mutex); + up(&mtrr_sem); unlock_cpu_hotplug(); return error; } @@ -686,7 +685,7 @@ void mtrr_ap_init(void) if (!mtrr_if || !use_intel()) return; /* - * Ideally we should hold mtrr_mutex here to avoid mtrr entries changed, + * Ideally we should hold mtrr_sem here to avoid mtrr entries changed, * but this routine will be called in cpu boot time, holding the lock * breaks it. This routine is called in two cases: 1.very earily time * of software resume, when there absolutely isn't mtrr entry changes; diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index f94cdb7ac..89a85af33 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c @@ -40,12 +40,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Other (Linux-defined) */ "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", NULL, NULL, NULL, NULL, - "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL, + "constant_tsc", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* Intel-defined (#2) */ - "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", + "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est", "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 1d9a4abcd..006141d1c 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -168,7 +168,7 @@ static int cpuid_class_device_create(int i) return err; } -static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) +static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c index 2b0cfce24..d49dbe8dc 100644 --- a/arch/i386/kernel/crash.c +++ b/arch/i386/kernel/crash.c @@ -69,7 +69,7 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) * for the data I pass, and I need tags * on the data to indicate what information I have * squirrelled away. ELF notes happen to provide - * all of that, so there is no need to invent something new. + * all of that that no need to invent something new. */ buf = (u32*)per_cpu_ptr(crash_notes, cpu); if (!buf) @@ -105,7 +105,7 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu) return 1; local_irq_disable(); - if (!user_mode_vm(regs)) { + if (!user_mode(regs)) { crash_fixup_ss_esp(&fixed_regs, regs); regs = &fixed_regs; } diff --git a/drivers/firmware/dmi_scan.c b/arch/i386/kernel/dmi_scan.c similarity index 73% rename from drivers/firmware/dmi_scan.c rename to arch/i386/kernel/dmi_scan.c index 948bd7e14..ca2a0cbca 100644 --- a/drivers/firmware/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c @@ -3,10 +3,8 @@ #include #include #include -#include #include #include -#include static char * __init dmi_string(struct dmi_header *dm, u8 s) { @@ -27,7 +25,7 @@ static char * __init dmi_string(struct dmi_header *dm, u8 s) else printk(KERN_ERR "dmi_string: out of memory.\n"); } - } + } return str; } @@ -41,7 +39,7 @@ static int __init dmi_table(u32 base, int len, int num, { u8 *buf, *data; int i = 0; - + buf = dmi_ioremap(base, len); if (buf == NULL) return -1; @@ -49,9 +47,9 @@ static int __init dmi_table(u32 base, int len, int num, data = buf; /* - * Stop when we see all the items the table claimed to have - * OR we run off the end of the table (also happens) - */ + * Stop when we see all the items the table claimed to have + * OR we run off the end of the table (also happens) + */ while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { struct dmi_header *dm = (struct dmi_header *)data; /* @@ -75,7 +73,7 @@ static int __init dmi_checksum(u8 *buf) { u8 sum = 0; int a; - + for (a = 0; a < 15; a++) sum += buf[a]; @@ -186,72 +184,47 @@ static void __init dmi_decode(struct dmi_header *dm) } } -static int __init dmi_present(char __iomem *p) -{ - u8 buf[15]; - memcpy_fromio(buf, p, 15); - if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { - u16 num = (buf[13] << 8) | buf[12]; - u16 len = (buf[7] << 8) | buf[6]; - u32 base = (buf[11] << 24) | (buf[10] << 16) | - (buf[9] << 8) | buf[8]; - - /* - * DMI version 0.0 means that the real version is taken from - * the SMBIOS version, which we don't know at this point. - */ - if (buf[14] != 0) - printk(KERN_INFO "DMI %d.%d present.\n", - buf[14] >> 4, buf[14] & 0xF); - else - printk(KERN_INFO "DMI present.\n"); - if (dmi_table(base,len, num, dmi_decode) == 0) - return 0; - } - return 1; -} - void __init dmi_scan_machine(void) { + u8 buf[15]; char __iomem *p, *q; - int rc; - - if (efi_enabled) { - if (efi.smbios == EFI_INVALID_TABLE_ADDR) - goto out; - - /* This is called as a core_initcall() because it isn't - * needed during early boot. This also means we can - * iounmap the space when we're done with it. - */ - p = dmi_ioremap(efi.smbios, 32); - if (p == NULL) - goto out; - - rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ - dmi_iounmap(p, 32); - if (!rc) - return; - } - else { - /* - * no iounmap() for that ioremap(); it would be a no-op, but - * it's so early in setup that sucker gets confused into doing - * what it shouldn't if we actually call it. - */ - p = dmi_ioremap(0xF0000, 0x10000); - if (p == NULL) - goto out; - for (q = p; q < p + 0x10000; q += 16) { - rc = dmi_present(q); - if (!rc) + /* + * no iounmap() for that ioremap(); it would be a no-op, but it's + * so early in setup that sucker gets confused into doing what + * it shouldn't if we actually call it. + */ + p = ioremap(0xF0000, 0x10000); + if (p == NULL) + goto out; + + for (q = p; q < p + 0x10000; q += 16) { + memcpy_fromio(buf, q, 15); + if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { + u16 num = (buf[13] << 8) | buf[12]; + u16 len = (buf[7] << 8) | buf[6]; + u32 base = (buf[11] << 24) | (buf[10] << 16) | + (buf[9] << 8) | buf[8]; + + /* + * DMI version 0.0 means that the real version is taken from + * the SMBIOS version, which we don't know at this point. + */ + if (buf[14] != 0) + printk(KERN_INFO "DMI %d.%d present.\n", + buf[14] >> 4, buf[14] & 0xF); + else + printk(KERN_INFO "DMI present.\n"); + + if (dmi_table(base,len, num, dmi_decode) == 0) return; } } - out: printk(KERN_INFO "DMI not present or invalid.\n"); + +out: printk(KERN_INFO "DMI not present or invalid.\n"); } + /** * dmi_check_system - check system DMI data * @list: array of dmi_system_id structures to match against @@ -326,33 +299,3 @@ struct dmi_device * dmi_find_device(int type, const char *name, return NULL; } EXPORT_SYMBOL(dmi_find_device); - -/** - * dmi_get_year - Return year of a DMI date - * @field: data index (like dmi_get_system_info) - * - * Returns -1 when the field doesn't exist. 0 when it is broken. - */ -int dmi_get_year(int field) -{ - int year; - char *s = dmi_get_system_info(field); - - if (!s) - return -1; - if (*s == '\0') - return 0; - s = strrchr(s, '/'); - if (!s) - return 0; - - s += 1; - year = simple_strtoul(s, NULL, 0); - if (year && year < 100) { /* 2-digit year */ - year += 1900; - if (year < 1996) /* no dates < spec 1.0 */ - year += 100; - } - - return year; -} diff --git a/arch/i386/kernel/early_printk-xen.c b/arch/i386/kernel/early_printk-xen.c deleted file mode 100644 index 7a5d2064e..000000000 --- a/arch/i386/kernel/early_printk-xen.c +++ /dev/null @@ -1,2 +0,0 @@ - -#include "../../x86_64/kernel/early_printk-xen.c" diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index 9202b67c4..c9cad7ba0 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c @@ -115,7 +115,7 @@ static void efi_call_phys_epilog(void) unsigned long cr4; struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); - cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address); + cpu_gdt_descr->address = __va(cpu_gdt_descr->address); load_gdt(cpu_gdt_descr); cr4 = read_cr4(); @@ -361,7 +361,7 @@ void __init efi_init(void) */ c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2); if (c16) { - for (i = 0; i < (sizeof(vendor) - 1) && *c16; ++i) + for (i = 0; i < sizeof(vendor) && *c16; ++i) vendor[i] = *c16++; vendor[i] = '\0'; } else @@ -381,38 +381,29 @@ void __init efi_init(void) if (config_tables == NULL) printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n"); - efi.mps = EFI_INVALID_TABLE_ADDR; - efi.acpi = EFI_INVALID_TABLE_ADDR; - efi.acpi20 = EFI_INVALID_TABLE_ADDR; - efi.smbios = EFI_INVALID_TABLE_ADDR; - efi.sal_systab = EFI_INVALID_TABLE_ADDR; - efi.boot_info = EFI_INVALID_TABLE_ADDR; - efi.hcdp = EFI_INVALID_TABLE_ADDR; - efi.uga = EFI_INVALID_TABLE_ADDR; - for (i = 0; i < num_config_tables; i++) { if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { - efi.mps = config_tables[i].table; + efi.mps = (void *)config_tables[i].table; printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { - efi.acpi20 = config_tables[i].table; + efi.acpi20 = __va(config_tables[i].table); printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { - efi.acpi = config_tables[i].table; + efi.acpi = __va(config_tables[i].table); printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { - efi.smbios = config_tables[i].table; + efi.smbios = (void *) config_tables[i].table; printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { - efi.hcdp = config_tables[i].table; + efi.hcdp = (void *)config_tables[i].table; printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) { - efi.uga = config_tables[i].table; + efi.uga = (void *)config_tables[i].table; printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table); } } @@ -552,7 +543,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > 0x100000000ULL) continue; - res = kzalloc(sizeof(struct resource), GFP_ATOMIC); + res = alloc_bootmem_low(sizeof(struct resource)); switch (md->type) { case EFI_RESERVED_TYPE: res->name = "Reserved Memory"; diff --git a/arch/i386/kernel/entry-xen.S b/arch/i386/kernel/entry-xen.S deleted file mode 100644 index 1f3c30ae1..000000000 --- a/arch/i386/kernel/entry-xen.S +++ /dev/null @@ -1,907 +0,0 @@ -/* - * linux/arch/i386/entry.S - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -/* - * entry.S contains the system-call and fault low-level handling routines. - * This also contains the timer-interrupt handler, as well as all interrupts - * and faults that can result in a task-switch. - * - * NOTE: This code handles signal-recognition, which happens every time - * after a timer-interrupt and after each system call. - * - * I changed all the .align's to 4 (16 byte alignment), as that's faster - * on a 486. - * - * Stack layout in 'ret_from_system_call': - * ptrace needs to have all regs on the stack. - * if the order here is changed, it needs to be - * updated in fork.c:copy_process, signal.c:do_signal, - * ptrace.c and ptrace.h - * - * 0(%esp) - %ebx - * 4(%esp) - %ecx - * 8(%esp) - %edx - * C(%esp) - %esi - * 10(%esp) - %edi - * 14(%esp) - %ebp - * 18(%esp) - %eax - * 1C(%esp) - %ds - * 20(%esp) - %es - * 24(%esp) - orig_eax - * 28(%esp) - %eip - * 2C(%esp) - %cs - * 30(%esp) - %eflags - * 34(%esp) - %oldesp - * 38(%esp) - %oldss - * - * "current" is in register %ebx during any slow entries. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "irq_vectors.h" -#include - -#define nr_syscalls ((syscall_table_size)/4) - -EBX = 0x00 -ECX = 0x04 -EDX = 0x08 -ESI = 0x0C -EDI = 0x10 -EBP = 0x14 -EAX = 0x18 -DS = 0x1C -ES = 0x20 -ORIG_EAX = 0x24 -EIP = 0x28 -CS = 0x2C -EFLAGS = 0x30 -OLDESP = 0x34 -OLDSS = 0x38 - -CF_MASK = 0x00000001 -TF_MASK = 0x00000100 -IF_MASK = 0x00000200 -DF_MASK = 0x00000400 -NT_MASK = 0x00004000 -VM_MASK = 0x00020000 -/* Pseudo-eflags. */ -NMI_MASK = 0x80000000 - -#ifndef CONFIG_XEN -#define DISABLE_INTERRUPTS cli -#define ENABLE_INTERRUPTS sti -#else -/* Offsets into shared_info_t. */ -#define evtchn_upcall_pending /* 0 */ -#define evtchn_upcall_mask 1 - -#define sizeof_vcpu_shift 6 - -#ifdef CONFIG_SMP -#define GET_VCPU_INFO movl TI_cpu(%ebp),%esi ; \ - shl $sizeof_vcpu_shift,%esi ; \ - addl HYPERVISOR_shared_info,%esi -#else -#define GET_VCPU_INFO movl HYPERVISOR_shared_info,%esi -#endif - -#define __DISABLE_INTERRUPTS movb $1,evtchn_upcall_mask(%esi) -#define __ENABLE_INTERRUPTS movb $0,evtchn_upcall_mask(%esi) -#define DISABLE_INTERRUPTS GET_VCPU_INFO ; \ - __DISABLE_INTERRUPTS -#define ENABLE_INTERRUPTS GET_VCPU_INFO ; \ - __ENABLE_INTERRUPTS -#define __TEST_PENDING testb $0xFF,evtchn_upcall_pending(%esi) -#endif - -#ifdef CONFIG_PREEMPT -#define preempt_stop cli -#else -#define preempt_stop -#define resume_kernel restore_nocheck -#endif - -#define SAVE_ALL \ - cld; \ - pushl %es; \ - pushl %ds; \ - pushl %eax; \ - pushl %ebp; \ - pushl %edi; \ - pushl %esi; \ - pushl %edx; \ - pushl %ecx; \ - pushl %ebx; \ - movl $(__USER_DS), %edx; \ - movl %edx, %ds; \ - movl %edx, %es; - -#define RESTORE_INT_REGS \ - popl %ebx; \ - popl %ecx; \ - popl %edx; \ - popl %esi; \ - popl %edi; \ - popl %ebp; \ - popl %eax - -#define RESTORE_REGS \ - RESTORE_INT_REGS; \ -1: popl %ds; \ -2: popl %es; \ -.section .fixup,"ax"; \ -3: movl $0,(%esp); \ - jmp 1b; \ -4: movl $0,(%esp); \ - jmp 2b; \ -.previous; \ -.section __ex_table,"a";\ - .align 4; \ - .long 1b,3b; \ - .long 2b,4b; \ -.previous - - -ENTRY(ret_from_fork) - pushl %eax - call schedule_tail - GET_THREAD_INFO(%ebp) - popl %eax - jmp syscall_exit - -/* - * Return to user mode is not as complex as all this looks, - * but we want the default path for a system call return to - * go as quickly as possible which is why some of this is - * less clear than it otherwise should be. - */ - - # userspace resumption stub bypassing syscall exit tracing - ALIGN -ret_from_exception: - preempt_stop -ret_from_intr: - GET_THREAD_INFO(%ebp) - movl EFLAGS(%esp), %eax # mix EFLAGS and CS - movb CS(%esp), %al - testl $(VM_MASK | 2), %eax - jz resume_kernel -ENTRY(resume_userspace) - DISABLE_INTERRUPTS # make sure we don't miss an interrupt - # setting need_resched or sigpending - # between sampling and the iret - movl TI_flags(%ebp), %ecx - andl $_TIF_WORK_MASK, %ecx # is there any work to be done on - # int/exception return? - jne work_pending - jmp restore_all - -#ifdef CONFIG_PREEMPT -ENTRY(resume_kernel) - cli - cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? - jnz restore_nocheck -need_resched: - movl TI_flags(%ebp), %ecx # need_resched set ? - testb $_TIF_NEED_RESCHED, %cl - jz restore_all - testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ? - jz restore_all - call preempt_schedule_irq - jmp need_resched -#endif - -/* SYSENTER_RETURN points to after the "sysenter" instruction in - the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ - - # sysenter call handler stub -ENTRY(sysenter_entry) - movl SYSENTER_stack_esp0(%esp),%esp -sysenter_past_esp: - sti - pushl $(__USER_DS) - pushl %ebp - pushfl - pushl $(__USER_CS) - /* - * Push current_thread_info()->sysenter_return to the stack. - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words - * pushed above; +8 corresponds to copy_thread's esp0 setting. - */ - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) -/* - * Load the potential sixth argument from user stack. - * Careful about security. - */ - cmpl $__PAGE_OFFSET-3,%ebp - jae syscall_fault -1: movl (%ebp),%ebp -.section __ex_table,"a" - .align 4 - .long 1b,syscall_fault -.previous - - pushl %eax - SAVE_ALL - GET_THREAD_INFO(%ebp) - - /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ - testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) - jnz syscall_trace_entry - cmpl $(nr_syscalls), %eax - jae syscall_badsys - call *sys_call_table(,%eax,4) - movl %eax,EAX(%esp) - DISABLE_INTERRUPTS - movl TI_flags(%ebp), %ecx - testw $_TIF_ALLWORK_MASK, %cx - jne syscall_exit_work -/* if something modifies registers it must also disable sysexit */ - movl EIP(%esp), %edx - movl OLDESP(%esp), %ecx - xorl %ebp,%ebp -#ifdef CONFIG_XEN - __ENABLE_INTERRUPTS -sysexit_scrit: /**** START OF SYSEXIT CRITICAL REGION ****/ - __TEST_PENDING - jnz 14f # process more events if necessary... - movl ESI(%esp), %esi - sysexit -14: __DISABLE_INTERRUPTS -sysexit_ecrit: /**** END OF SYSEXIT CRITICAL REGION ****/ - push %esp - call evtchn_do_upcall - add $4,%esp - jmp ret_from_intr -#else - sti - sysexit -#endif /* !CONFIG_XEN */ - - - # system call handler stub -ENTRY(system_call) - pushl %eax # save orig_eax - SAVE_ALL - GET_THREAD_INFO(%ebp) - testl $TF_MASK,EFLAGS(%esp) - jz no_singlestep - orl $_TIF_SINGLESTEP,TI_flags(%ebp) -no_singlestep: - # system call tracing in operation / emulation - /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ - testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) - jnz syscall_trace_entry - cmpl $(nr_syscalls), %eax - jae syscall_badsys -syscall_call: - call *sys_call_table(,%eax,4) - movl %eax,EAX(%esp) # store the return value -syscall_exit: - DISABLE_INTERRUPTS # make sure we don't miss an interrupt - # setting need_resched or sigpending - # between sampling and the iret - movl TI_flags(%ebp), %ecx - testw $_TIF_ALLWORK_MASK, %cx # current->work - jne syscall_exit_work - -restore_all: -#ifndef CONFIG_XEN - movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS - # Warning: OLDSS(%esp) contains the wrong/random values if we - # are returning to the kernel. - # See comments in process.c:copy_thread() for details. - movb OLDSS(%esp), %ah - movb CS(%esp), %al - andl $(VM_MASK | (4 << 8) | 3), %eax - cmpl $((4 << 8) | 3), %eax - je ldt_ss # returning to user-space with LDT SS -restore_nocheck: -#else -restore_nocheck: - movl EFLAGS(%esp), %eax - testl $(VM_MASK|NMI_MASK), %eax - jnz hypervisor_iret - shr $9, %eax # EAX[0] == IRET_EFLAGS.IF - GET_VCPU_INFO - andb evtchn_upcall_mask(%esi),%al - andb $1,%al # EAX[0] == IRET_EFLAGS.IF & event_mask - jnz restore_all_enable_events # != 0 => enable event delivery -#endif - RESTORE_REGS - addl $4, %esp -1: iret -.section .fixup,"ax" -iret_exc: -#ifndef CONFIG_XEN - sti -#endif - pushl $0 # no error code - pushl $do_iret_error - jmp error_code -.previous -.section __ex_table,"a" - .align 4 - .long 1b,iret_exc -.previous - -#ifndef CONFIG_XEN -ldt_ss: - larl OLDSS(%esp), %eax - jnz restore_nocheck - testl $0x00400000, %eax # returning to 32bit stack? - jnz restore_nocheck # allright, normal return - /* If returning to userspace with 16bit stack, - * try to fix the higher word of ESP, as the CPU - * won't restore it. - * This is an "official" bug of all the x86-compatible - * CPUs, which we can try to work around to make - * dosemu and wine happy. */ - subl $8, %esp # reserve space for switch16 pointer - cli - movl %esp, %eax - /* Set up the 16bit stack frame with switch32 pointer on top, - * and a switch16 pointer on top of the current frame. */ - call setup_x86_bogus_stack - RESTORE_REGS - lss 20+4(%esp), %esp # switch to 16bit stack -1: iret -.section __ex_table,"a" - .align 4 - .long 1b,iret_exc -.previous -#else -hypervisor_iret: - andl $~NMI_MASK, EFLAGS(%esp) - RESTORE_REGS - addl $4, %esp - jmp hypercall_page + (__HYPERVISOR_iret * 32) -#endif - - # perform work that needs to be done immediately before resumption - ALIGN -work_pending: - testb $_TIF_NEED_RESCHED, %cl - jz work_notifysig -work_resched: - call schedule - DISABLE_INTERRUPTS # make sure we don't miss an interrupt - # setting need_resched or sigpending - # between sampling and the iret - movl TI_flags(%ebp), %ecx - andl $_TIF_WORK_MASK, %ecx # is there any work to be done other - # than syscall tracing? - jz restore_all - testb $_TIF_NEED_RESCHED, %cl - jnz work_resched - -work_notifysig: # deal with pending signals and - # notify-resume requests - testl $VM_MASK, EFLAGS(%esp) - movl %esp, %eax - jne work_notifysig_v86 # returning to kernel-space or - # vm86-space - xorl %edx, %edx - call do_notify_resume - jmp resume_userspace - - ALIGN -work_notifysig_v86: -#ifdef CONFIG_VM86 - pushl %ecx # save ti_flags for do_notify_resume - call save_v86_state # %eax contains pt_regs pointer - popl %ecx - movl %eax, %esp - xorl %edx, %edx - call do_notify_resume - jmp resume_userspace -#endif - - # perform syscall exit tracing - ALIGN -syscall_trace_entry: - movl $-ENOSYS,EAX(%esp) - movl %esp, %eax - xorl %edx,%edx - call do_syscall_trace - cmpl $0, %eax - jne resume_userspace # ret != 0 -> running under PTRACE_SYSEMU, - # so must skip actual syscall - movl ORIG_EAX(%esp), %eax - cmpl $(nr_syscalls), %eax - jnae syscall_call - jmp syscall_exit - - # perform syscall exit tracing - ALIGN -syscall_exit_work: - testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl - jz work_pending - ENABLE_INTERRUPTS # could let do_syscall_trace() call - # schedule() instead - movl %esp, %eax - movl $1, %edx - call do_syscall_trace - jmp resume_userspace - - ALIGN -syscall_fault: - pushl %eax # save orig_eax - SAVE_ALL - GET_THREAD_INFO(%ebp) - movl $-EFAULT,EAX(%esp) - jmp resume_userspace - - ALIGN -syscall_badsys: - movl $-ENOSYS,EAX(%esp) - jmp resume_userspace - -#ifndef CONFIG_XEN -#define FIXUP_ESPFIX_STACK \ - movl %esp, %eax; \ - /* switch to 32bit stack using the pointer on top of 16bit stack */ \ - lss %ss:CPU_16BIT_STACK_SIZE-8, %esp; \ - /* copy data from 16bit stack to 32bit stack */ \ - call fixup_x86_bogus_stack; \ - /* put ESP to the proper location */ \ - movl %eax, %esp; -#define UNWIND_ESPFIX_STACK \ - pushl %eax; \ - movl %ss, %eax; \ - /* see if on 16bit stack */ \ - cmpw $__ESPFIX_SS, %ax; \ - jne 28f; \ - movl $__KERNEL_DS, %edx; \ - movl %edx, %ds; \ - movl %edx, %es; \ - /* switch to 32bit stack */ \ - FIXUP_ESPFIX_STACK \ -28: popl %eax; - -/* - * Build the entry stubs and pointer table with - * some assembler magic. - */ -.data -ENTRY(interrupt) -.text - -vector=0 -ENTRY(irq_entries_start) -.rept NR_IRQS - ALIGN -1: pushl $~(vector) - jmp common_interrupt -.data - .long 1b -.text -vector=vector+1 -.endr - - ALIGN -common_interrupt: - SAVE_ALL - movl %esp,%eax - call do_IRQ - jmp ret_from_intr - -#define BUILD_INTERRUPT(name, nr) \ -ENTRY(name) \ - pushl $~(nr); \ - SAVE_ALL \ - movl %esp,%eax; \ - call smp_/**/name; \ - jmp ret_from_intr; - -/* The include is where all of the SMP etc. interrupts come from */ -#include "entry_arch.h" -#else -#define UNWIND_ESPFIX_STACK -#endif - -ENTRY(divide_error) - pushl $0 # no error code - pushl $do_divide_error - ALIGN -error_code: - pushl %ds - pushl %eax - xorl %eax, %eax - pushl %ebp - pushl %edi - pushl %esi - pushl %edx - decl %eax # eax = -1 - pushl %ecx - pushl %ebx - cld - pushl %es - UNWIND_ESPFIX_STACK - popl %ecx - movl ES(%esp), %edi # get the function address - movl ORIG_EAX(%esp), %edx # get the error code - movl %eax, ORIG_EAX(%esp) - movl %ecx, ES(%esp) - movl $(__USER_DS), %ecx - movl %ecx, %ds - movl %ecx, %es - movl %esp,%eax # pt_regs pointer - call *%edi - jmp ret_from_exception - -#ifdef CONFIG_XEN -# A note on the "critical region" in our callback handler. -# We want to avoid stacking callback handlers due to events occurring -# during handling of the last event. To do this, we keep events disabled -# until we've done all processing. HOWEVER, we must enable events before -# popping the stack frame (can't be done atomically) and so it would still -# be possible to get enough handler activations to overflow the stack. -# Although unlikely, bugs of that kind are hard to track down, so we'd -# like to avoid the possibility. -# So, on entry to the handler we detect whether we interrupted an -# existing activation in its critical region -- if so, we pop the current -# activation and restart the handler using the previous one. -# -# The sysexit critical region is slightly different. sysexit -# atomically removes the entire stack frame. If we interrupt in the -# critical region we know that the entire frame is present and correct -# so we can simply throw away the new one. -ENTRY(hypervisor_callback) - pushl %eax - SAVE_ALL - movl EIP(%esp),%eax - cmpl $scrit,%eax - jb 11f - cmpl $ecrit,%eax - jb critical_region_fixup - cmpl $sysexit_scrit,%eax - jb 11f - cmpl $sysexit_ecrit,%eax - ja 11f - addl $0x34,%esp # Remove cs...ebx from stack frame. -11: push %esp - call evtchn_do_upcall - add $4,%esp - jmp ret_from_intr - - ALIGN -restore_all_enable_events: - __ENABLE_INTERRUPTS -scrit: /**** START OF CRITICAL REGION ****/ - __TEST_PENDING - jnz 14f # process more events if necessary... - RESTORE_REGS - addl $4, %esp -1: iret -.section __ex_table,"a" - .align 4 - .long 1b,iret_exc -.previous -14: __DISABLE_INTERRUPTS - jmp 11b -ecrit: /**** END OF CRITICAL REGION ****/ -# [How we do the fixup]. We want to merge the current stack frame with the -# just-interrupted frame. How we do this depends on where in the critical -# region the interrupted handler was executing, and so how many saved -# registers are in each frame. We do this quickly using the lookup table -# 'critical_fixup_table'. For each byte offset in the critical region, it -# provides the number of bytes which have already been popped from the -# interrupted stack frame. -critical_region_fixup: - addl $critical_fixup_table-scrit,%eax - movzbl (%eax),%eax # %eax contains num bytes popped - cmpb $0xff,%al # 0xff => vcpu_info critical region - jne 15f - GET_THREAD_INFO(%ebp) - xorl %eax,%eax -15: mov %esp,%esi - add %eax,%esi # %esi points at end of src region - mov %esp,%edi - add $0x34,%edi # %edi points at end of dst region - mov %eax,%ecx - shr $2,%ecx # convert words to bytes - je 17f # skip loop if nothing to copy -16: subl $4,%esi # pre-decrementing copy loop - subl $4,%edi - movl (%esi),%eax - movl %eax,(%edi) - loop 16b -17: movl %edi,%esp # final %edi is top of merged stack - jmp 11b - -critical_fixup_table: - .byte 0xff,0xff,0xff # testb $0xff,(%esi) = __TEST_PENDING - .byte 0xff,0xff # jnz 14f - .byte 0x00 # pop %ebx - .byte 0x04 # pop %ecx - .byte 0x08 # pop %edx - .byte 0x0c # pop %esi - .byte 0x10 # pop %edi - .byte 0x14 # pop %ebp - .byte 0x18 # pop %eax - .byte 0x1c # pop %ds - .byte 0x20 # pop %es - .byte 0x24,0x24,0x24 # add $4,%esp - .byte 0x28 # iret - .byte 0xff,0xff,0xff,0xff # movb $1,1(%esi) - .byte 0x00,0x00 # jmp 11b - -# Hypervisor uses this for application faults while it executes. -# We get here for two reasons: -# 1. Fault while reloading DS, ES, FS or GS -# 2. Fault while executing IRET -# Category 1 we fix up by reattempting the load, and zeroing the segment -# register if the load fails. -# Category 2 we fix up by jumping to do_iret_error. We cannot use the -# normal Linux return path in this case because if we use the IRET hypercall -# to pop the stack frame we end up in an infinite loop of failsafe callbacks. -# We distinguish between categories by maintaining a status value in EAX. -ENTRY(failsafe_callback) - pushl %eax - movl $1,%eax -1: mov 4(%esp),%ds -2: mov 8(%esp),%es -3: mov 12(%esp),%fs -4: mov 16(%esp),%gs - testl %eax,%eax - popl %eax - jz 5f - addl $16,%esp # EAX != 0 => Category 2 (Bad IRET) - jmp iret_exc -5: addl $16,%esp # EAX == 0 => Category 1 (Bad segment) - pushl $0 - SAVE_ALL - jmp ret_from_exception -.section .fixup,"ax"; \ -6: xorl %eax,%eax; \ - movl %eax,4(%esp); \ - jmp 1b; \ -7: xorl %eax,%eax; \ - movl %eax,8(%esp); \ - jmp 2b; \ -8: xorl %eax,%eax; \ - movl %eax,12(%esp); \ - jmp 3b; \ -9: xorl %eax,%eax; \ - movl %eax,16(%esp); \ - jmp 4b; \ -.previous; \ -.section __ex_table,"a"; \ - .align 4; \ - .long 1b,6b; \ - .long 2b,7b; \ - .long 3b,8b; \ - .long 4b,9b; \ -.previous -#endif - -ENTRY(coprocessor_error) - pushl $0 - pushl $do_coprocessor_error - jmp error_code - -ENTRY(simd_coprocessor_error) - pushl $0 - pushl $do_simd_coprocessor_error - jmp error_code - -ENTRY(device_not_available) - pushl $-1 # mark this as an int - SAVE_ALL -#ifndef CONFIG_XEN - movl %cr0, %eax - testl $0x4, %eax # EM (math emulation bit) - je device_available_emulate - pushl $0 # temporary storage for ORIG_EIP - call math_emulate - addl $4, %esp - jmp ret_from_exception -device_available_emulate: -#endif - preempt_stop - call math_state_restore - jmp ret_from_exception - -#ifndef CONFIG_XEN -/* - * Debug traps and NMI can happen at the one SYSENTER instruction - * that sets up the real kernel stack. Check here, since we can't - * allow the wrong stack to be used. - * - * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have - * already pushed 3 words if it hits on the sysenter instruction: - * eflags, cs and eip. - * - * We just load the right stack, and push the three (known) values - * by hand onto the new stack - while updating the return eip past - * the instruction that would have done it for sysenter. - */ -#define FIX_STACK(offset, ok, label) \ - cmpw $__KERNEL_CS,4(%esp); \ - jne ok; \ -label: \ - movl SYSENTER_stack_esp0+offset(%esp),%esp; \ - pushfl; \ - pushl $__KERNEL_CS; \ - pushl $sysenter_past_esp -#endif /* CONFIG_XEN */ - -KPROBE_ENTRY(debug) -#ifndef CONFIG_XEN - cmpl $sysenter_entry,(%esp) - jne debug_stack_correct - FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) -debug_stack_correct: -#endif /* !CONFIG_XEN */ - pushl $-1 # mark this as an int - SAVE_ALL - xorl %edx,%edx # error code 0 - movl %esp,%eax # pt_regs pointer - call do_debug - jmp ret_from_exception - .previous .text - -#ifndef CONFIG_XEN -/* - * NMI is doubly nasty. It can happen _while_ we're handling - * a debug fault, and the debug fault hasn't yet been able to - * clear up the stack. So we first check whether we got an - * NMI on the sysenter entry path, but after that we need to - * check whether we got an NMI on the debug path where the debug - * fault happened on the sysenter path. - */ -ENTRY(nmi) - pushl %eax - movl %ss, %eax - cmpw $__ESPFIX_SS, %ax - popl %eax - je nmi_16bit_stack - cmpl $sysenter_entry,(%esp) - je nmi_stack_fixup - pushl %eax - movl %esp,%eax - /* Do not access memory above the end of our stack page, - * it might not exist. - */ - andl $(THREAD_SIZE-1),%eax - cmpl $(THREAD_SIZE-20),%eax - popl %eax - jae nmi_stack_correct - cmpl $sysenter_entry,12(%esp) - je nmi_debug_stack_check -nmi_stack_correct: - pushl %eax - SAVE_ALL - xorl %edx,%edx # zero error code - movl %esp,%eax # pt_regs pointer - call do_nmi - jmp restore_all - -nmi_stack_fixup: - FIX_STACK(12,nmi_stack_correct, 1) - jmp nmi_stack_correct -nmi_debug_stack_check: - cmpw $__KERNEL_CS,16(%esp) - jne nmi_stack_correct - cmpl $debug,(%esp) - jb nmi_stack_correct - cmpl $debug_esp_fix_insn,(%esp) - ja nmi_stack_correct - FIX_STACK(24,nmi_stack_correct, 1) - jmp nmi_stack_correct - -nmi_16bit_stack: - /* create the pointer to lss back */ - pushl %ss - pushl %esp - movzwl %sp, %esp - addw $4, (%esp) - /* copy the iret frame of 12 bytes */ - .rept 3 - pushl 16(%esp) - .endr - pushl %eax - SAVE_ALL - FIXUP_ESPFIX_STACK # %eax == %esp - xorl %edx,%edx # zero error code - call do_nmi - RESTORE_REGS - lss 12+4(%esp), %esp # back to 16bit stack -1: iret -.section __ex_table,"a" - .align 4 - .long 1b,iret_exc -.previous -#else -ENTRY(nmi) - pushl %eax - SAVE_ALL - xorl %edx,%edx # zero error code - movl %esp,%eax # pt_regs pointer - call do_nmi - orl $NMI_MASK, EFLAGS(%esp) - jmp restore_all -#endif - -KPROBE_ENTRY(int3) - pushl $-1 # mark this as an int - SAVE_ALL - xorl %edx,%edx # zero error code - movl %esp,%eax # pt_regs pointer - call do_int3 - jmp ret_from_exception - .previous .text - -ENTRY(overflow) - pushl $0 - pushl $do_overflow - jmp error_code - -ENTRY(bounds) - pushl $0 - pushl $do_bounds - jmp error_code - -ENTRY(invalid_op) - pushl $0 - pushl $do_invalid_op - jmp error_code - -ENTRY(coprocessor_segment_overrun) - pushl $0 - pushl $do_coprocessor_segment_overrun - jmp error_code - -ENTRY(invalid_TSS) - pushl $do_invalid_TSS - jmp error_code - -ENTRY(segment_not_present) - pushl $do_segment_not_present - jmp error_code - -ENTRY(stack_segment) - pushl $do_stack_segment - jmp error_code - -KPROBE_ENTRY(general_protection) - pushl $do_general_protection - jmp error_code - .previous .text - -ENTRY(alignment_check) - pushl $do_alignment_check - jmp error_code - -KPROBE_ENTRY(page_fault) - pushl $do_page_fault - jmp error_code - .previous .text - -#ifdef CONFIG_X86_MCE -ENTRY(machine_check) - pushl $0 - pushl machine_check_vector - jmp error_code -#endif - -ENTRY(fixup_4gb_segment) - pushl $do_fixup_4gb_segment - jmp error_code - -.section .rodata,"a" -#include "syscall_table.S" - -syscall_table_size=(.-sys_call_table) diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index eed41e6dd..a14218c9e 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -128,6 +128,8 @@ ENTRY(ret_from_fork) call schedule_tail GET_THREAD_INFO(%ebp) popl %eax + pushl $0x0202 # Reset kernel eflags + popfl jmp syscall_exit /* @@ -177,19 +179,15 @@ need_resched: # sysenter call handler stub ENTRY(sysenter_entry) - movl SYSENTER_stack_esp0(%esp),%esp + movl TSS_sysenter_esp0(%esp),%esp sysenter_past_esp: sti pushl $(__USER_DS) pushl %ebp pushfl pushl $(__USER_CS) - /* - * Push current_thread_info()->sysenter_return to the stack. - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words - * pushed above; +8 corresponds to copy_thread's esp0 setting. - */ - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) + pushl $SYSENTER_RETURN + /* * Load the potential sixth argument from user stack. * Careful about security. @@ -230,10 +228,6 @@ ENTRY(system_call) pushl %eax # save orig_eax SAVE_ALL GET_THREAD_INFO(%ebp) - testl $TF_MASK,EFLAGS(%esp) - jz no_singlestep - orl $_TIF_SINGLESTEP,TI_flags(%ebp) -no_singlestep: # system call tracing in operation / emulation /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) @@ -414,7 +408,7 @@ vector=0 ENTRY(irq_entries_start) .rept NR_IRQS ALIGN -1: pushl $~(vector) +1: pushl $vector-256 jmp common_interrupt .data .long 1b @@ -431,7 +425,7 @@ common_interrupt: #define BUILD_INTERRUPT(name, nr) \ ENTRY(name) \ - pushl $~(nr); \ + pushl $nr-256; \ SAVE_ALL \ movl %esp,%eax; \ call smp_/**/name; \ @@ -500,7 +494,7 @@ device_not_available_emulate: * that sets up the real kernel stack. Check here, since we can't * allow the wrong stack to be used. * - * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have + * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have * already pushed 3 words if it hits on the sysenter instruction: * eflags, cs and eip. * @@ -512,7 +506,7 @@ device_not_available_emulate: cmpw $__KERNEL_CS,4(%esp); \ jne ok; \ label: \ - movl SYSENTER_stack_esp0+offset(%esp),%esp; \ + movl TSS_sysenter_esp0+offset(%esp),%esp; \ pushfl; \ pushl $__KERNEL_CS; \ pushl $sysenter_past_esp diff --git a/arch/i386/kernel/fixup.c b/arch/i386/kernel/fixup.c deleted file mode 100644 index 15a8f2078..000000000 --- a/arch/i386/kernel/fixup.c +++ /dev/null @@ -1,86 +0,0 @@ -/****************************************************************************** - * fixup.c - * - * Binary-rewriting of certain IA32 instructions, on notification by Xen. - * Used to avoid repeated slow emulation of common instructions used by the - * user-space TLS (Thread-Local Storage) libraries. - * - * **** NOTE **** - * Issues with the binary rewriting have caused it to be removed. Instead - * we rely on Xen's emulator to boot the kernel, and then print a banner - * message recommending that the user disables /lib/tls. - * - * Copyright (c) 2004, K A Fraser - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#define DP(_f, _args...) printk(KERN_ALERT " " _f "\n" , ## _args ) - -fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code) -{ - static unsigned long printed = 1; - char info[100]; - int i; - - if (test_and_set_bit(0, &printed)) - return; - - HYPERVISOR_vm_assist( - VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify); - - sprintf(info, "%s (pid=%d)", current->comm, current->tgid); - - - DP(""); - DP("***************************************************************"); - DP("***************************************************************"); - DP("** WARNING: Currently emulating unsupported memory accesses **"); - DP("** in /lib/tls glibc libraries. The emulation is **"); - DP("** slow. To ensure full performance you should **"); - DP("** install a 'xen-friendly' (nosegneg) version of **"); - DP("** the library, or disable tls support by executing **"); - DP("** the following as root: **"); - DP("** mv /lib/tls /lib/tls.disabled **"); - DP("** Offending process: %-38.38s **", info); - DP("***************************************************************"); - DP("***************************************************************"); - DP(""); - - for (i = 5; i > 0; i--) { - touch_softlockup_watchdog(); - printk("Pausing... %d", i); - mdelay(1000); - printk("\b\b\b\b\b\b\b\b\b\b\b\b"); - } - - printk("Continuing...\n\n"); -} - -static int __init fixup_init(void) -{ - HYPERVISOR_vm_assist( - VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify); - return 0; -} -__initcall(fixup_init); diff --git a/arch/i386/kernel/head-xen.S b/arch/i386/kernel/head-xen.S deleted file mode 100644 index 25ce03247..000000000 --- a/arch/i386/kernel/head-xen.S +++ /dev/null @@ -1,181 +0,0 @@ - - -.text -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * References to members of the new_cpu_data structure. - */ - -#define X86 new_cpu_data+CPUINFO_x86 -#define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor -#define X86_MODEL new_cpu_data+CPUINFO_x86_model -#define X86_MASK new_cpu_data+CPUINFO_x86_mask -#define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math -#define X86_CPUID new_cpu_data+CPUINFO_cpuid_level -#define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability -#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id - -#define VIRT_ENTRY_OFFSET 0x0 -.org VIRT_ENTRY_OFFSET -ENTRY(startup_32) - movl %esi,xen_start_info - cld - - /* Set up the stack pointer */ - movl $(init_thread_union+THREAD_SIZE),%esp - - /* get vendor info */ - xorl %eax,%eax # call CPUID with 0 -> return vendor ID - XEN_CPUID - movl %eax,X86_CPUID # save CPUID level - movl %ebx,X86_VENDOR_ID # lo 4 chars - movl %edx,X86_VENDOR_ID+4 # next 4 chars - movl %ecx,X86_VENDOR_ID+8 # last 4 chars - - movl $1,%eax # Use the CPUID instruction to get CPU type - XEN_CPUID - movb %al,%cl # save reg for future use - andb $0x0f,%ah # mask processor family - movb %ah,X86 - andb $0xf0,%al # mask model - shrb $4,%al - movb %al,X86_MODEL - andb $0x0f,%cl # mask mask revision - movb %cl,X86_MASK - movl %edx,X86_CAPABILITY - - movb $1,X86_HARD_MATH - - xorl %eax,%eax # Clear FS/GS and LDT - movl %eax,%fs - movl %eax,%gs - cld # gcc2 wants the direction flag cleared at all times - - call start_kernel -L6: - jmp L6 # main should never return here, but - # just in case, we know what happens. - -#define HYPERCALL_PAGE_OFFSET 0x1000 -.org HYPERCALL_PAGE_OFFSET -ENTRY(hypercall_page) -.skip 0x1000 - -/* - * Real beginning of normal "text" segment - */ -ENTRY(stext) -ENTRY(_stext) - -/* - * BSS section - */ -.section ".bss.page_aligned","w" -ENTRY(empty_zero_page) - .fill 4096,1,0 - -/* - * This starts the data section. - */ -.data - -/* - * The Global Descriptor Table contains 28 quadwords, per-CPU. - */ -ENTRY(cpu_gdt_table) - .quad 0x0000000000000000 /* NULL descriptor */ - .quad 0x0000000000000000 /* 0x0b reserved */ - .quad 0x0000000000000000 /* 0x13 reserved */ - .quad 0x0000000000000000 /* 0x1b reserved */ - .quad 0x0000000000000000 /* 0x20 unused */ - .quad 0x0000000000000000 /* 0x28 unused */ - .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ - .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ - .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ - .quad 0x0000000000000000 /* 0x4b reserved */ - .quad 0x0000000000000000 /* 0x53 reserved */ - .quad 0x0000000000000000 /* 0x5b reserved */ - - .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ - .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ - .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */ - .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */ - - .quad 0x0000000000000000 /* 0x80 TSS descriptor */ - .quad 0x0000000000000000 /* 0x88 LDT descriptor */ - - /* - * Segments used for calling PnP BIOS have byte granularity. - * They code segments and data segments have fixed 64k limits, - * the transfer segment sizes are set at run time. - */ - .quad 0x0000000000000000 /* 0x90 32-bit code */ - .quad 0x0000000000000000 /* 0x98 16-bit code */ - .quad 0x0000000000000000 /* 0xa0 16-bit data */ - .quad 0x0000000000000000 /* 0xa8 16-bit data */ - .quad 0x0000000000000000 /* 0xb0 16-bit data */ - - /* - * The APM segments have byte granularity and their bases - * are set at run time. All have 64k limits. - */ - .quad 0x0000000000000000 /* 0xb8 APM CS code */ - .quad 0x0000000000000000 /* 0xc0 APM CS 16 code (16 bit) */ - .quad 0x0000000000000000 /* 0xc8 APM DS data */ - - .quad 0x0000000000000000 /* 0xd0 - ESPFIX 16-bit SS */ - .quad 0x0000000000000000 /* 0xd8 - unused */ - .quad 0x0000000000000000 /* 0xe0 - unused */ - .quad 0x0000000000000000 /* 0xe8 - unused */ - .quad 0x0000000000000000 /* 0xf0 - unused */ - .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ - -/* - * __xen_guest information - */ -.macro utoa value - .if (\value) < 0 || (\value) >= 0x10 - utoa (((\value)>>4)&0x0fffffff) - .endif - .if ((\value) & 0xf) < 10 - .byte '0' + ((\value) & 0xf) - .else - .byte 'A' + ((\value) & 0xf) - 10 - .endif -.endm - -.section __xen_guest - .ascii "GUEST_OS=linux,GUEST_VER=2.6" - .ascii ",XEN_VER=xen-3.0" - .ascii ",VIRT_BASE=0x" - utoa __PAGE_OFFSET -#ifdef CONFIG_XEN_COMPAT_030002 - .ascii ",ELF_PADDR_OFFSET=0x" - utoa __PAGE_OFFSET -#else - .ascii ",ELF_PADDR_OFFSET=0x0" -#endif /* !CONFIG_XEN_COMPAT_030002 */ - .ascii ",VIRT_ENTRY=0x" - utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET) - .ascii ",HYPERCALL_PAGE=0x" - utoa ((__PHYSICAL_START+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT) - .ascii ",FEATURES=writable_page_tables" - .ascii "|writable_descriptor_tables" - .ascii "|auto_translated_physmap" - .ascii "|pae_pgdir_above_4gb" - .ascii "|supervisor_mode_kernel" -#ifdef CONFIG_X86_PAE - .ascii ",PAE=yes[extended-cr3]" -#else - .ascii ",PAE=no" -#endif - .ascii ",LOADER=generic" - .byte 0 diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 3debc2e26..e0b7c632e 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -450,6 +450,7 @@ int_msg: .globl boot_gdt_descr .globl idt_descr +.globl cpu_gdt_descr ALIGN # early boot GDT descriptor (must use 1:1 address mapping) @@ -469,6 +470,8 @@ cpu_gdt_descr: .word GDT_ENTRIES*8-1 .long cpu_gdt_table + .fill NR_CPUS-1,8,0 # space for the other GDT descriptors + /* * The boot_gdt_table must mirror the equivalent in setup.S and is * used only for booting. @@ -482,7 +485,7 @@ ENTRY(boot_gdt_table) /* * The Global Descriptor Table contains 28 quadwords, per-CPU. */ - .align L1_CACHE_BYTES + .align PAGE_SIZE_asm ENTRY(cpu_gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* 0x0b reserved */ diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 036a98579..055325056 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -19,6 +19,7 @@ EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); +EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strstr); #ifdef CONFIG_SMP diff --git a/arch/i386/kernel/init_task-xen.c b/arch/i386/kernel/init_task-xen.c deleted file mode 100644 index c4da1cce8..000000000 --- a/arch/i386/kernel/init_task-xen.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); - -#define swapper_pg_dir ((pgd_t *)NULL) -struct mm_struct init_mm = INIT_MM(init_mm); -#undef swapper_pg_dir - -EXPORT_SYMBOL(init_mm); - -/* - * Initial thread structure. - * - * We need to make sure that this is THREAD_SIZE aligned due to the - * way process stacks are handled. This is done by having a special - * "init_task" linker map entry.. - */ -union thread_union init_thread_union - __attribute__((__section__(".data.init_task"))) = - { INIT_THREAD_INFO(init_task) }; - -/* - * Initial task structure. - * - * All other task structs will be allocated on slabs in fork.c - */ -struct task_struct init_task = INIT_TASK(init_task); - -EXPORT_SYMBOL(init_task); - -#ifndef CONFIG_X86_NO_TSS -/* - * per-CPU TSS segments. Threads are completely 'soft' on Linux, - * no more per-task TSS's. - */ -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; -#endif - diff --git a/arch/i386/kernel/io_apic-xen.c b/arch/i386/kernel/io_apic-xen.c deleted file mode 100644 index 49e3ff89b..000000000 --- a/arch/i386/kernel/io_apic-xen.c +++ /dev/null @@ -1,2751 +0,0 @@ -/* - * Intel IO-APIC support for multi-Pentium hosts. - * - * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo - * - * Many thanks to Stig Venaas for trying out countless experimental - * patches and reporting/debugging problems patiently! - * - * (c) 1999, Multiple IO-APIC support, developed by - * Ken-ichi Yaku and - * Hidemi Kishimoto , - * further tested and cleaned up by Zach Brown - * and Ingo Molnar - * - * Fixes - * Maciej W. Rozycki : Bits for genuine 82489DX APICs; - * thanks to Eric Gilmore - * and Rolf G. Tews - * for testing these extensively - * Paul Diefenbaugh : Added full ACPI support - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "io_ports.h" - -#ifdef CONFIG_XEN - -#include -#include - -/* Fake i8259 */ -#define make_8259A_irq(_irq) (io_apic_irqs &= ~(1UL<<(_irq))) -#define disable_8259A_irq(_irq) ((void)0) -#define i8259A_irq_pending(_irq) (0) - -unsigned long io_apic_irqs; - -static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg) -{ - struct physdev_apic apic_op; - int ret; - - apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr; - apic_op.reg = reg; - ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op); - if (ret) - return ret; - return apic_op.value; -} - -static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) -{ - struct physdev_apic apic_op; - - apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr; - apic_op.reg = reg; - apic_op.value = value; - HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op); -} - -#define io_apic_read(a,r) xen_io_apic_read(a,r) -#define io_apic_write(a,r,v) xen_io_apic_write(a,r,v) - -#endif /* CONFIG_XEN */ - -int (*ioapic_renumber_irq)(int ioapic, int irq); -atomic_t irq_mis_count; - -/* Where if anywhere is the i8259 connect in external int mode */ -static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; - -static DEFINE_SPINLOCK(ioapic_lock); - -int timer_over_8254 __initdata = 1; - -/* - * Is the SiS APIC rmw bug present ? - * -1 = don't know, 0 = no, 1 = yes - */ -int sis_apic_bug = -1; - -/* - * # of IRQ routing registers - */ -int nr_ioapic_registers[MAX_IO_APICS]; - -int disable_timer_pin_1 __initdata; - -/* - * Rough estimation of how many shared IRQs there are, can - * be changed anytime. - */ -#define MAX_PLUS_SHARED_IRQS NR_IRQS -#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS) - -/* - * This is performance-critical, we want to do it O(1) - * - * the indexing order of this array favors 1:1 mappings - * between pins and IRQs. - */ - -static struct irq_pin_list { - int apic, pin, next; -} irq_2_pin[PIN_MAP_SIZE]; - -int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; -#ifdef CONFIG_PCI_MSI -#define vector_to_irq(vector) \ - (platform_legacy_irq(vector) ? vector : vector_irq[vector]) -#else -#define vector_to_irq(vector) (vector) -#endif - -/* - * The common case is 1:1 IRQ<->pin mappings. Sometimes there are - * shared ISA-space IRQs, so we have to support them. We are super - * fast in the common case, and fast for shared ISA-space IRQs. - */ -static void add_pin_to_irq(unsigned int irq, int apic, int pin) -{ - static int first_free_entry = NR_IRQS; - struct irq_pin_list *entry = irq_2_pin + irq; - - while (entry->next) - entry = irq_2_pin + entry->next; - - if (entry->pin != -1) { - entry->next = first_free_entry; - entry = irq_2_pin + entry->next; - if (++first_free_entry >= PIN_MAP_SIZE) - panic("io_apic.c: whoops"); - } - entry->apic = apic; - entry->pin = pin; -} - -#ifdef CONFIG_XEN -#define clear_IO_APIC() ((void)0) -#else -/* - * Reroute an IRQ to a different pin. - */ -static void __init replace_pin_at_irq(unsigned int irq, - int oldapic, int oldpin, - int newapic, int newpin) -{ - struct irq_pin_list *entry = irq_2_pin + irq; - - while (1) { - if (entry->apic == oldapic && entry->pin == oldpin) { - entry->apic = newapic; - entry->pin = newpin; - } - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } -} - -static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable) -{ - struct irq_pin_list *entry = irq_2_pin + irq; - unsigned int pin, reg; - - for (;;) { - pin = entry->pin; - if (pin == -1) - break; - reg = io_apic_read(entry->apic, 0x10 + pin*2); - reg &= ~disable; - reg |= enable; - io_apic_modify(entry->apic, 0x10 + pin*2, reg); - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } -} - -/* mask = 1 */ -static void __mask_IO_APIC_irq (unsigned int irq) -{ - __modify_IO_APIC_irq(irq, 0x00010000, 0); -} - -/* mask = 0 */ -static void __unmask_IO_APIC_irq (unsigned int irq) -{ - __modify_IO_APIC_irq(irq, 0, 0x00010000); -} - -/* mask = 1, trigger = 0 */ -static void __mask_and_edge_IO_APIC_irq (unsigned int irq) -{ - __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); -} - -/* mask = 0, trigger = 1 */ -static void __unmask_and_level_IO_APIC_irq (unsigned int irq) -{ - __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); -} - -static void mask_IO_APIC_irq (unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - __mask_IO_APIC_irq(irq); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -static void unmask_IO_APIC_irq (unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - __unmask_IO_APIC_irq(irq); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) -{ - struct IO_APIC_route_entry entry; - unsigned long flags; - - /* Check delivery_mode to be sure we're not clearing an SMI pin */ - spin_lock_irqsave(&ioapic_lock, flags); - *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); - *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); - spin_unlock_irqrestore(&ioapic_lock, flags); - if (entry.delivery_mode == dest_SMI) - return; - - /* - * Disable it in the IO-APIC irq-routing table: - */ - memset(&entry, 0, sizeof(entry)); - entry.mask = 1; - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0)); - io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1)); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -static void clear_IO_APIC (void) -{ - int apic, pin; - - for (apic = 0; apic < nr_ioapics; apic++) - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) - clear_IO_APIC_pin(apic, pin); -} - -#ifdef CONFIG_SMP -static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) -{ - unsigned long flags; - int pin; - struct irq_pin_list *entry = irq_2_pin + irq; - unsigned int apicid_value; - cpumask_t tmp; - - cpus_and(tmp, cpumask, cpu_online_map); - if (cpus_empty(tmp)) - tmp = TARGET_CPUS; - - cpus_and(cpumask, tmp, CPU_MASK_ALL); - - apicid_value = cpu_mask_to_apicid(cpumask); - /* Prepare to do the io_apic_write */ - apicid_value = apicid_value << 24; - spin_lock_irqsave(&ioapic_lock, flags); - for (;;) { - pin = entry->pin; - if (pin == -1) - break; - io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value); - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } - set_irq_info(irq, cpumask); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -#if defined(CONFIG_IRQBALANCE) -# include /* kernel_thread() */ -# include /* kstat */ -# include /* kmalloc() */ -# include /* time_after() */ - -# ifdef CONFIG_BALANCED_IRQ_DEBUG -# define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) -# define Dprintk(x...) do { TDprintk(x); } while (0) -# else -# define TDprintk(x...) -# define Dprintk(x...) -# endif - - -#define IRQBALANCE_CHECK_ARCH -999 -static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; -static int physical_balance = 0; - -static struct irq_cpu_info { - unsigned long * last_irq; - unsigned long * irq_delta; - unsigned long irq; -} irq_cpu_data[NR_CPUS]; - -#define CPU_IRQ(cpu) (irq_cpu_data[cpu].irq) -#define LAST_CPU_IRQ(cpu,irq) (irq_cpu_data[cpu].last_irq[irq]) -#define IRQ_DELTA(cpu,irq) (irq_cpu_data[cpu].irq_delta[irq]) - -#define IDLE_ENOUGH(cpu,now) \ - (idle_cpu(cpu) && ((now) - per_cpu(irq_stat, (cpu)).idle_timestamp > 1)) - -#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask) - -#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) - -#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) -#define MIN_BALANCED_IRQ_INTERVAL (HZ/2) -#define BALANCED_IRQ_MORE_DELTA (HZ/10) -#define BALANCED_IRQ_LESS_DELTA (HZ) - -static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; - -static unsigned long move(int curr_cpu, cpumask_t allowed_mask, - unsigned long now, int direction) -{ - int search_idle = 1; - int cpu = curr_cpu; - - goto inside; - - do { - if (unlikely(cpu == curr_cpu)) - search_idle = 0; -inside: - if (direction == 1) { - cpu++; - if (cpu >= NR_CPUS) - cpu = 0; - } else { - cpu--; - if (cpu == -1) - cpu = NR_CPUS-1; - } - } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu,allowed_mask) || - (search_idle && !IDLE_ENOUGH(cpu,now))); - - return cpu; -} - -static inline void balance_irq(int cpu, int irq) -{ - unsigned long now = jiffies; - cpumask_t allowed_mask; - unsigned int new_cpu; - - if (irqbalance_disabled) - return; - - cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); - new_cpu = move(cpu, allowed_mask, now, 1); - if (cpu != new_cpu) { - set_pending_irq(irq, cpumask_of_cpu(new_cpu)); - } -} - -static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) -{ - int i, j; - Dprintk("Rotating IRQs among CPUs.\n"); - for_each_online_cpu(i) { - for (j = 0; j < NR_IRQS; j++) { - if (!irq_desc[j].action) - continue; - /* Is it a significant load ? */ - if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i),j) < - useful_load_threshold) - continue; - balance_irq(i, j); - } - } - balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, - balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); - return; -} - -static void do_irq_balance(void) -{ - int i, j; - unsigned long max_cpu_irq = 0, min_cpu_irq = (~0); - unsigned long move_this_load = 0; - int max_loaded = 0, min_loaded = 0; - int load; - unsigned long useful_load_threshold = balanced_irq_interval + 10; - int selected_irq; - int tmp_loaded, first_attempt = 1; - unsigned long tmp_cpu_irq; - unsigned long imbalance = 0; - cpumask_t allowed_mask, target_cpu_mask, tmp; - - for_each_possible_cpu(i) { - int package_index; - CPU_IRQ(i) = 0; - if (!cpu_online(i)) - continue; - package_index = CPU_TO_PACKAGEINDEX(i); - for (j = 0; j < NR_IRQS; j++) { - unsigned long value_now, delta; - /* Is this an active IRQ? */ - if (!irq_desc[j].action) - continue; - if ( package_index == i ) - IRQ_DELTA(package_index,j) = 0; - /* Determine the total count per processor per IRQ */ - value_now = (unsigned long) kstat_cpu(i).irqs[j]; - - /* Determine the activity per processor per IRQ */ - delta = value_now - LAST_CPU_IRQ(i,j); - - /* Update last_cpu_irq[][] for the next time */ - LAST_CPU_IRQ(i,j) = value_now; - - /* Ignore IRQs whose rate is less than the clock */ - if (delta < useful_load_threshold) - continue; - /* update the load for the processor or package total */ - IRQ_DELTA(package_index,j) += delta; - - /* Keep track of the higher numbered sibling as well */ - if (i != package_index) - CPU_IRQ(i) += delta; - /* - * We have sibling A and sibling B in the package - * - * cpu_irq[A] = load for cpu A + load for cpu B - * cpu_irq[B] = load for cpu B - */ - CPU_IRQ(package_index) += delta; - } - } - /* Find the least loaded processor package */ - for_each_online_cpu(i) { - if (i != CPU_TO_PACKAGEINDEX(i)) - continue; - if (min_cpu_irq > CPU_IRQ(i)) { - min_cpu_irq = CPU_IRQ(i); - min_loaded = i; - } - } - max_cpu_irq = ULONG_MAX; - -tryanothercpu: - /* Look for heaviest loaded processor. - * We may come back to get the next heaviest loaded processor. - * Skip processors with trivial loads. - */ - tmp_cpu_irq = 0; - tmp_loaded = -1; - for_each_online_cpu(i) { - if (i != CPU_TO_PACKAGEINDEX(i)) - continue; - if (max_cpu_irq <= CPU_IRQ(i)) - continue; - if (tmp_cpu_irq < CPU_IRQ(i)) { - tmp_cpu_irq = CPU_IRQ(i); - tmp_loaded = i; - } - } - - if (tmp_loaded == -1) { - /* In the case of small number of heavy interrupt sources, - * loading some of the cpus too much. We use Ingo's original - * approach to rotate them around. - */ - if (!first_attempt && imbalance >= useful_load_threshold) { - rotate_irqs_among_cpus(useful_load_threshold); - return; - } - goto not_worth_the_effort; - } - - first_attempt = 0; /* heaviest search */ - max_cpu_irq = tmp_cpu_irq; /* load */ - max_loaded = tmp_loaded; /* processor */ - imbalance = (max_cpu_irq - min_cpu_irq) / 2; - - Dprintk("max_loaded cpu = %d\n", max_loaded); - Dprintk("min_loaded cpu = %d\n", min_loaded); - Dprintk("max_cpu_irq load = %ld\n", max_cpu_irq); - Dprintk("min_cpu_irq load = %ld\n", min_cpu_irq); - Dprintk("load imbalance = %lu\n", imbalance); - - /* if imbalance is less than approx 10% of max load, then - * observe diminishing returns action. - quit - */ - if (imbalance < (max_cpu_irq >> 3)) { - Dprintk("Imbalance too trivial\n"); - goto not_worth_the_effort; - } - -tryanotherirq: - /* if we select an IRQ to move that can't go where we want, then - * see if there is another one to try. - */ - move_this_load = 0; - selected_irq = -1; - for (j = 0; j < NR_IRQS; j++) { - /* Is this an active IRQ? */ - if (!irq_desc[j].action) - continue; - if (imbalance <= IRQ_DELTA(max_loaded,j)) - continue; - /* Try to find the IRQ that is closest to the imbalance - * without going over. - */ - if (move_this_load < IRQ_DELTA(max_loaded,j)) { - move_this_load = IRQ_DELTA(max_loaded,j); - selected_irq = j; - } - } - if (selected_irq == -1) { - goto tryanothercpu; - } - - imbalance = move_this_load; - - /* For physical_balance case, we accumlated both load - * values in the one of the siblings cpu_irq[], - * to use the same code for physical and logical processors - * as much as possible. - * - * NOTE: the cpu_irq[] array holds the sum of the load for - * sibling A and sibling B in the slot for the lowest numbered - * sibling (A), _AND_ the load for sibling B in the slot for - * the higher numbered sibling. - * - * We seek the least loaded sibling by making the comparison - * (A+B)/2 vs B - */ - load = CPU_IRQ(min_loaded) >> 1; - for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) { - if (load > CPU_IRQ(j)) { - /* This won't change cpu_sibling_map[min_loaded] */ - load = CPU_IRQ(j); - min_loaded = j; - } - } - - cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]); - target_cpu_mask = cpumask_of_cpu(min_loaded); - cpus_and(tmp, target_cpu_mask, allowed_mask); - - if (!cpus_empty(tmp)) { - - Dprintk("irq = %d moved to cpu = %d\n", - selected_irq, min_loaded); - /* mark for change destination */ - set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded)); - - /* Since we made a change, come back sooner to - * check for more variation. - */ - balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, - balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); - return; - } - goto tryanotherirq; - -not_worth_the_effort: - /* - * if we did not find an IRQ to move, then adjust the time interval - * upward - */ - balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL, - balanced_irq_interval + BALANCED_IRQ_MORE_DELTA); - Dprintk("IRQ worth rotating not found\n"); - return; -} - -static int balanced_irq(void *unused) -{ - int i; - unsigned long prev_balance_time = jiffies; - long time_remaining = balanced_irq_interval; - - daemonize("kirqd"); - - /* push everything to CPU 0 to give us a starting point. */ - for (i = 0 ; i < NR_IRQS ; i++) { - pending_irq_cpumask[i] = cpumask_of_cpu(0); - set_pending_irq(i, cpumask_of_cpu(0)); - } - - for ( ; ; ) { - time_remaining = schedule_timeout_interruptible(time_remaining); - try_to_freeze(); - if (time_after(jiffies, - prev_balance_time+balanced_irq_interval)) { - preempt_disable(); - do_irq_balance(); - prev_balance_time = jiffies; - time_remaining = balanced_irq_interval; - preempt_enable(); - } - } - return 0; -} - -static int __init balanced_irq_init(void) -{ - int i; - struct cpuinfo_x86 *c; - cpumask_t tmp; - - cpus_shift_right(tmp, cpu_online_map, 2); - c = &boot_cpu_data; - /* When not overwritten by the command line ask subarchitecture. */ - if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH) - irqbalance_disabled = NO_BALANCE_IRQ; - if (irqbalance_disabled) - return 0; - - /* disable irqbalance completely if there is only one processor online */ - if (num_online_cpus() < 2) { - irqbalance_disabled = 1; - return 0; - } - /* - * Enable physical balance only if more than 1 physical processor - * is present - */ - if (smp_num_siblings > 1 && !cpus_empty(tmp)) - physical_balance = 1; - - for_each_online_cpu(i) { - irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); - irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); - if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { - printk(KERN_ERR "balanced_irq_init: out of memory"); - goto failed; - } - memset(irq_cpu_data[i].irq_delta,0,sizeof(unsigned long) * NR_IRQS); - memset(irq_cpu_data[i].last_irq,0,sizeof(unsigned long) * NR_IRQS); - } - - printk(KERN_INFO "Starting balanced_irq\n"); - if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) - return 0; - else - printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); -failed: - for_each_possible_cpu(i) { - kfree(irq_cpu_data[i].irq_delta); - irq_cpu_data[i].irq_delta = NULL; - kfree(irq_cpu_data[i].last_irq); - irq_cpu_data[i].last_irq = NULL; - } - return 0; -} - -int __init irqbalance_disable(char *str) -{ - irqbalance_disabled = 1; - return 1; -} - -__setup("noirqbalance", irqbalance_disable); - -late_initcall(balanced_irq_init); -#endif /* CONFIG_IRQBALANCE */ -#endif /* CONFIG_SMP */ -#endif - -#ifndef CONFIG_SMP -void fastcall send_IPI_self(int vector) -{ -#ifndef CONFIG_XEN - unsigned int cfg; - - /* - * Wait for idle. - */ - apic_wait_icr_idle(); - cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL; - /* - * Send the IPI. The write to APIC_ICR fires this off. - */ - apic_write_around(APIC_ICR, cfg); -#endif -} -#endif /* !CONFIG_SMP */ - - -/* - * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to - * specific CPU-side IRQs. - */ - -#define MAX_PIRQS 8 -static int pirq_entries [MAX_PIRQS]; -static int pirqs_enabled; -int skip_ioapic_setup; - -static int __init ioapic_setup(char *str) -{ - skip_ioapic_setup = 1; - return 1; -} - -__setup("noapic", ioapic_setup); - -static int __init ioapic_pirq_setup(char *str) -{ - int i, max; - int ints[MAX_PIRQS+1]; - - get_options(str, ARRAY_SIZE(ints), ints); - - for (i = 0; i < MAX_PIRQS; i++) - pirq_entries[i] = -1; - - pirqs_enabled = 1; - apic_printk(APIC_VERBOSE, KERN_INFO - "PIRQ redirection, working around broken MP-BIOS.\n"); - max = MAX_PIRQS; - if (ints[0] < MAX_PIRQS) - max = ints[0]; - - for (i = 0; i < max; i++) { - apic_printk(APIC_VERBOSE, KERN_DEBUG - "... PIRQ%d -> IRQ %d\n", i, ints[i+1]); - /* - * PIRQs are mapped upside down, usually. - */ - pirq_entries[MAX_PIRQS-i-1] = ints[i+1]; - } - return 1; -} - -__setup("pirq=", ioapic_pirq_setup); - -/* - * Find the IRQ entry number of a certain pin. - */ -static int find_irq_entry(int apic, int pin, int type) -{ - int i; - - for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].mpc_irqtype == type && - (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid || - mp_irqs[i].mpc_dstapic == MP_APIC_ALL) && - mp_irqs[i].mpc_dstirq == pin) - return i; - - return -1; -} - -/* - * Find the pin to which IRQ[irq] (ISA) is connected - */ -static int __init find_isa_irq_pin(int irq, int type) -{ - int i; - - for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].mpc_srcbus; - - if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || - mp_bus_id_to_type[lbus] == MP_BUS_EISA || - mp_bus_id_to_type[lbus] == MP_BUS_MCA || - mp_bus_id_to_type[lbus] == MP_BUS_NEC98 - ) && - (mp_irqs[i].mpc_irqtype == type) && - (mp_irqs[i].mpc_srcbusirq == irq)) - - return mp_irqs[i].mpc_dstirq; - } - return -1; -} - -static int __init find_isa_irq_apic(int irq, int type) -{ - int i; - - for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].mpc_srcbus; - - if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || - mp_bus_id_to_type[lbus] == MP_BUS_EISA || - mp_bus_id_to_type[lbus] == MP_BUS_MCA || - mp_bus_id_to_type[lbus] == MP_BUS_NEC98 - ) && - (mp_irqs[i].mpc_irqtype == type) && - (mp_irqs[i].mpc_srcbusirq == irq)) - break; - } - if (i < mp_irq_entries) { - int apic; - for(apic = 0; apic < nr_ioapics; apic++) { - if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic) - return apic; - } - } - - return -1; -} - -/* - * Find a specific PCI IRQ entry. - * Not an __init, possibly needed by modules - */ -static int pin_2_irq(int idx, int apic, int pin); - -int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) -{ - int apic, i, best_guess = -1; - - apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, " - "slot:%d, pin:%d.\n", bus, slot, pin); - if (mp_bus_id_to_pci_bus[bus] == -1) { - printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus); - return -1; - } - for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].mpc_srcbus; - - for (apic = 0; apic < nr_ioapics; apic++) - if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic || - mp_irqs[i].mpc_dstapic == MP_APIC_ALL) - break; - - if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) && - !mp_irqs[i].mpc_irqtype && - (bus == lbus) && - (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) { - int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq); - - if (!(apic || IO_APIC_IRQ(irq))) - continue; - - if (pin == (mp_irqs[i].mpc_srcbusirq & 3)) - return irq; - /* - * Use the first all-but-pin matching entry as a - * best-guess fuzzy result for broken mptables. - */ - if (best_guess < 0) - best_guess = irq; - } - } - return best_guess; -} -EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); - -/* - * This function currently is only a helper for the i386 smp boot process where - * we need to reprogram the ioredtbls to cater for the cpus which have come online - * so mask in all cases should simply be TARGET_CPUS - */ -#ifdef CONFIG_SMP -#ifndef CONFIG_XEN -void __init setup_ioapic_dest(void) -{ - int pin, ioapic, irq, irq_entry; - - if (skip_ioapic_setup == 1) - return; - - for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { - for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { - irq_entry = find_irq_entry(ioapic, pin, mp_INT); - if (irq_entry == -1) - continue; - irq = pin_2_irq(irq_entry, ioapic, pin); - set_ioapic_affinity_irq(irq, TARGET_CPUS); - } - - } -} -#endif /* !CONFIG_XEN */ -#endif - -/* - * EISA Edge/Level control register, ELCR - */ -static int EISA_ELCR(unsigned int irq) -{ - if (irq < 16) { - unsigned int port = 0x4d0 + (irq >> 3); - return (inb(port) >> (irq & 7)) & 1; - } - apic_printk(APIC_VERBOSE, KERN_INFO - "Broken MPtable reports ISA irq %d\n", irq); - return 0; -} - -/* EISA interrupts are always polarity zero and can be edge or level - * trigger depending on the ELCR value. If an interrupt is listed as - * EISA conforming in the MP table, that means its trigger type must - * be read in from the ELCR */ - -#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq)) -#define default_EISA_polarity(idx) (0) - -/* ISA interrupts are always polarity zero edge triggered, - * when listed as conforming in the MP table. */ - -#define default_ISA_trigger(idx) (0) -#define default_ISA_polarity(idx) (0) - -/* PCI interrupts are always polarity one level triggered, - * when listed as conforming in the MP table. */ - -#define default_PCI_trigger(idx) (1) -#define default_PCI_polarity(idx) (1) - -/* MCA interrupts are always polarity zero level triggered, - * when listed as conforming in the MP table. */ - -#define default_MCA_trigger(idx) (1) -#define default_MCA_polarity(idx) (0) - -/* NEC98 interrupts are always polarity zero edge triggered, - * when listed as conforming in the MP table. */ - -#define default_NEC98_trigger(idx) (0) -#define default_NEC98_polarity(idx) (0) - -static int __init MPBIOS_polarity(int idx) -{ - int bus = mp_irqs[idx].mpc_srcbus; - int polarity; - - /* - * Determine IRQ line polarity (high active or low active): - */ - switch (mp_irqs[idx].mpc_irqflag & 3) - { - case 0: /* conforms, ie. bus-type dependent polarity */ - { - switch (mp_bus_id_to_type[bus]) - { - case MP_BUS_ISA: /* ISA pin */ - { - polarity = default_ISA_polarity(idx); - break; - } - case MP_BUS_EISA: /* EISA pin */ - { - polarity = default_EISA_polarity(idx); - break; - } - case MP_BUS_PCI: /* PCI pin */ - { - polarity = default_PCI_polarity(idx); - break; - } - case MP_BUS_MCA: /* MCA pin */ - { - polarity = default_MCA_polarity(idx); - break; - } - case MP_BUS_NEC98: /* NEC 98 pin */ - { - polarity = default_NEC98_polarity(idx); - break; - } - default: - { - printk(KERN_WARNING "broken BIOS!!\n"); - polarity = 1; - break; - } - } - break; - } - case 1: /* high active */ - { - polarity = 0; - break; - } - case 2: /* reserved */ - { - printk(KERN_WARNING "broken BIOS!!\n"); - polarity = 1; - break; - } - case 3: /* low active */ - { - polarity = 1; - break; - } - default: /* invalid */ - { - printk(KERN_WARNING "broken BIOS!!\n"); - polarity = 1; - break; - } - } - return polarity; -} - -static int MPBIOS_trigger(int idx) -{ - int bus = mp_irqs[idx].mpc_srcbus; - int trigger; - - /* - * Determine IRQ trigger mode (edge or level sensitive): - */ - switch ((mp_irqs[idx].mpc_irqflag>>2) & 3) - { - case 0: /* conforms, ie. bus-type dependent */ - { - switch (mp_bus_id_to_type[bus]) - { - case MP_BUS_ISA: /* ISA pin */ - { - trigger = default_ISA_trigger(idx); - break; - } - case MP_BUS_EISA: /* EISA pin */ - { - trigger = default_EISA_trigger(idx); - break; - } - case MP_BUS_PCI: /* PCI pin */ - { - trigger = default_PCI_trigger(idx); - break; - } - case MP_BUS_MCA: /* MCA pin */ - { - trigger = default_MCA_trigger(idx); - break; - } - case MP_BUS_NEC98: /* NEC 98 pin */ - { - trigger = default_NEC98_trigger(idx); - break; - } - default: - { - printk(KERN_WARNING "broken BIOS!!\n"); - trigger = 1; - break; - } - } - break; - } - case 1: /* edge */ - { - trigger = 0; - break; - } - case 2: /* reserved */ - { - printk(KERN_WARNING "broken BIOS!!\n"); - trigger = 1; - break; - } - case 3: /* level */ - { - trigger = 1; - break; - } - default: /* invalid */ - { - printk(KERN_WARNING "broken BIOS!!\n"); - trigger = 0; - break; - } - } - return trigger; -} - -static inline int irq_polarity(int idx) -{ - return MPBIOS_polarity(idx); -} - -static inline int irq_trigger(int idx) -{ - return MPBIOS_trigger(idx); -} - -static int pin_2_irq(int idx, int apic, int pin) -{ - int irq, i; - int bus = mp_irqs[idx].mpc_srcbus; - - /* - * Debugging check, we are in big trouble if this message pops up! - */ - if (mp_irqs[idx].mpc_dstirq != pin) - printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); - - switch (mp_bus_id_to_type[bus]) - { - case MP_BUS_ISA: /* ISA pin */ - case MP_BUS_EISA: - case MP_BUS_MCA: - case MP_BUS_NEC98: - { - irq = mp_irqs[idx].mpc_srcbusirq; - break; - } - case MP_BUS_PCI: /* PCI pin */ - { - /* - * PCI IRQs are mapped in order - */ - i = irq = 0; - while (i < apic) - irq += nr_ioapic_registers[i++]; - irq += pin; - - /* - * For MPS mode, so far only needed by ES7000 platform - */ - if (ioapic_renumber_irq) - irq = ioapic_renumber_irq(apic, irq); - - break; - } - default: - { - printk(KERN_ERR "unknown bus type %d.\n",bus); - irq = 0; - break; - } - } - - /* - * PCI IRQ command line redirection. Yes, limits are hardcoded. - */ - if ((pin >= 16) && (pin <= 23)) { - if (pirq_entries[pin-16] != -1) { - if (!pirq_entries[pin-16]) { - apic_printk(APIC_VERBOSE, KERN_DEBUG - "disabling PIRQ%d\n", pin-16); - } else { - irq = pirq_entries[pin-16]; - apic_printk(APIC_VERBOSE, KERN_DEBUG - "using PIRQ%d -> IRQ %d\n", - pin-16, irq); - } - } - } - return irq; -} - -static inline int IO_APIC_irq_trigger(int irq) -{ - int apic, idx, pin; - - for (apic = 0; apic < nr_ioapics; apic++) { - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { - idx = find_irq_entry(apic,pin,mp_INT); - if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin))) - return irq_trigger(idx); - } - } - /* - * nonexistent IRQs are edge default - */ - return 0; -} - -/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ -u8 irq_vector[NR_IRQ_VECTORS] __read_mostly; /* = { FIRST_DEVICE_VECTOR , 0 }; */ - -int assign_irq_vector(int irq) -{ - struct physdev_irq irq_op; - - BUG_ON(irq >= NR_IRQ_VECTORS); - if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) - return IO_APIC_VECTOR(irq); - - irq_op.irq = irq; - if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) - return -ENOSPC; - - vector_irq[irq_op.vector] = irq; - if (irq != AUTO_ASSIGN) - IO_APIC_VECTOR(irq) = irq_op.vector; - - return irq_op.vector; -} - -#ifndef CONFIG_XEN -static struct hw_interrupt_type ioapic_level_type; -static struct hw_interrupt_type ioapic_edge_type; - -#define IOAPIC_AUTO -1 -#define IOAPIC_EDGE 0 -#define IOAPIC_LEVEL 1 - -static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) -{ - if (use_pci_vector() && !platform_legacy_irq(irq)) { - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[vector].handler = &ioapic_level_type; - else - irq_desc[vector].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[vector]); - } else { - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[irq].handler = &ioapic_level_type; - else - irq_desc[irq].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[irq]); - } -} -#else -#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0) -#endif - -static void __init setup_IO_APIC_irqs(void) -{ - struct IO_APIC_route_entry entry; - int apic, pin, idx, irq, first_notcon = 1, vector; - unsigned long flags; - - apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); - - for (apic = 0; apic < nr_ioapics; apic++) { - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { - - /* - * add it to the IO-APIC irq-routing table: - */ - memset(&entry,0,sizeof(entry)); - - entry.delivery_mode = INT_DELIVERY_MODE; - entry.dest_mode = INT_DEST_MODE; - entry.mask = 0; /* enable IRQ */ - entry.dest.logical.logical_dest = - cpu_mask_to_apicid(TARGET_CPUS); - - idx = find_irq_entry(apic,pin,mp_INT); - if (idx == -1) { - if (first_notcon) { - apic_printk(APIC_VERBOSE, KERN_DEBUG - " IO-APIC (apicid-pin) %d-%d", - mp_ioapics[apic].mpc_apicid, - pin); - first_notcon = 0; - } else - apic_printk(APIC_VERBOSE, ", %d-%d", - mp_ioapics[apic].mpc_apicid, pin); - continue; - } - - entry.trigger = irq_trigger(idx); - entry.polarity = irq_polarity(idx); - - if (irq_trigger(idx)) { - entry.trigger = 1; - entry.mask = 1; - } - - irq = pin_2_irq(idx, apic, pin); - /* - * skip adding the timer int on secondary nodes, which causes - * a small but painful rift in the time-space continuum - */ - if (multi_timer_check(apic, irq)) - continue; - else - add_pin_to_irq(irq, apic, pin); - - if (/*!apic &&*/ !IO_APIC_IRQ(irq)) - continue; - - if (IO_APIC_IRQ(irq)) { - vector = assign_irq_vector(irq); - entry.vector = vector; - ioapic_register_intr(irq, vector, IOAPIC_AUTO); - - if (!apic && (irq < 16)) - disable_8259A_irq(irq); - } - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); - io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); - set_native_irq_info(irq, TARGET_CPUS); - spin_unlock_irqrestore(&ioapic_lock, flags); - } - } - - if (!first_notcon) - apic_printk(APIC_VERBOSE, " not connected.\n"); -} - -/* - * Set up the 8259A-master output pin: - */ -#ifndef CONFIG_XEN -static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector) -{ - struct IO_APIC_route_entry entry; - unsigned long flags; - - memset(&entry,0,sizeof(entry)); - - disable_8259A_irq(0); - - /* mask LVT0 */ - apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); - - /* - * We use logical delivery to get the timer IRQ - * to the first CPU. - */ - entry.dest_mode = INT_DEST_MODE; - entry.mask = 0; /* unmask IRQ now */ - entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); - entry.delivery_mode = INT_DELIVERY_MODE; - entry.polarity = 0; - entry.trigger = 0; - entry.vector = vector; - - /* - * The timer IRQ doesn't have to know that behind the - * scene we have a 8259A-master in AEOI mode ... - */ - irq_desc[0].handler = &ioapic_edge_type; - - /* - * Add it to the IO-APIC irq-routing table: - */ - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); - io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); - spin_unlock_irqrestore(&ioapic_lock, flags); - - enable_8259A_irq(0); -} - -static inline void UNEXPECTED_IO_APIC(void) -{ -} - -void __init print_IO_APIC(void) -{ - int apic, i; - union IO_APIC_reg_00 reg_00; - union IO_APIC_reg_01 reg_01; - union IO_APIC_reg_02 reg_02; - union IO_APIC_reg_03 reg_03; - unsigned long flags; - - if (apic_verbosity == APIC_QUIET) - return; - - printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); - for (i = 0; i < nr_ioapics; i++) - printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", - mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]); - - /* - * We are a bit conservative about what we expect. We have to - * know about every hardware change ASAP. - */ - printk(KERN_INFO "testing the IO APIC.......................\n"); - - for (apic = 0; apic < nr_ioapics; apic++) { - - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(apic, 0); - reg_01.raw = io_apic_read(apic, 1); - if (reg_01.bits.version >= 0x10) - reg_02.raw = io_apic_read(apic, 2); - if (reg_01.bits.version >= 0x20) - reg_03.raw = io_apic_read(apic, 3); - spin_unlock_irqrestore(&ioapic_lock, flags); - - printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid); - printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); - printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); - printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); - printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); - if (reg_00.bits.ID >= get_physical_broadcast()) - UNEXPECTED_IO_APIC(); - if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) - UNEXPECTED_IO_APIC(); - - printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw); - printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); - if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */ - (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */ - (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */ - (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */ - (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */ - (reg_01.bits.entries != 0x2E) && - (reg_01.bits.entries != 0x3F) - ) - UNEXPECTED_IO_APIC(); - - printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); - printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); - if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */ - (reg_01.bits.version != 0x10) && /* oldest IO-APICs */ - (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */ - (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */ - (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */ - ) - UNEXPECTED_IO_APIC(); - if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2) - UNEXPECTED_IO_APIC(); - - /* - * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, - * but the value of reg_02 is read as the previous read register - * value, so ignore it if reg_02 == reg_01. - */ - if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { - printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); - printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); - if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2) - UNEXPECTED_IO_APIC(); - } - - /* - * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02 - * or reg_03, but the value of reg_0[23] is read as the previous read - * register value, so ignore it if reg_03 == reg_0[12]. - */ - if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw && - reg_03.raw != reg_01.raw) { - printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); - printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); - if (reg_03.bits.__reserved_1) - UNEXPECTED_IO_APIC(); - } - - printk(KERN_DEBUG ".... IRQ redirection table:\n"); - - printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol" - " Stat Dest Deli Vect: \n"); - - for (i = 0; i <= reg_01.bits.entries; i++) { - struct IO_APIC_route_entry entry; - - spin_lock_irqsave(&ioapic_lock, flags); - *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); - *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); - spin_unlock_irqrestore(&ioapic_lock, flags); - - printk(KERN_DEBUG " %02x %03X %02X ", - i, - entry.dest.logical.logical_dest, - entry.dest.physical.physical_dest - ); - - printk("%1d %1d %1d %1d %1d %1d %1d %02X\n", - entry.mask, - entry.trigger, - entry.irr, - entry.polarity, - entry.delivery_status, - entry.dest_mode, - entry.delivery_mode, - entry.vector - ); - } - } - if (use_pci_vector()) - printk(KERN_INFO "Using vector-based indexing\n"); - printk(KERN_DEBUG "IRQ to pin mappings:\n"); - for (i = 0; i < NR_IRQS; i++) { - struct irq_pin_list *entry = irq_2_pin + i; - if (entry->pin < 0) - continue; - if (use_pci_vector() && !platform_legacy_irq(i)) - printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); - else - printk(KERN_DEBUG "IRQ%d ", i); - for (;;) { - printk("-> %d:%d", entry->apic, entry->pin); - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } - printk("\n"); - } - - printk(KERN_INFO ".................................... done.\n"); - - return; -} - -#if 0 - -static void print_APIC_bitfield (int base) -{ - unsigned int v; - int i, j; - - if (apic_verbosity == APIC_QUIET) - return; - - printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG); - for (i = 0; i < 8; i++) { - v = apic_read(base + i*0x10); - for (j = 0; j < 32; j++) { - if (v & (1< 3) /* Due to the Pentium erratum 3AP. */ - apic_write(APIC_ESR, 0); - v = apic_read(APIC_ESR); - printk(KERN_DEBUG "... APIC ESR: %08x\n", v); - } - - v = apic_read(APIC_ICR); - printk(KERN_DEBUG "... APIC ICR: %08x\n", v); - v = apic_read(APIC_ICR2); - printk(KERN_DEBUG "... APIC ICR2: %08x\n", v); - - v = apic_read(APIC_LVTT); - printk(KERN_DEBUG "... APIC LVTT: %08x\n", v); - - if (maxlvt > 3) { /* PC is LVT#4. */ - v = apic_read(APIC_LVTPC); - printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v); - } - v = apic_read(APIC_LVT0); - printk(KERN_DEBUG "... APIC LVT0: %08x\n", v); - v = apic_read(APIC_LVT1); - printk(KERN_DEBUG "... APIC LVT1: %08x\n", v); - - if (maxlvt > 2) { /* ERR is LVT#3. */ - v = apic_read(APIC_LVTERR); - printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v); - } - - v = apic_read(APIC_TMICT); - printk(KERN_DEBUG "... APIC TMICT: %08x\n", v); - v = apic_read(APIC_TMCCT); - printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v); - v = apic_read(APIC_TDCR); - printk(KERN_DEBUG "... APIC TDCR: %08x\n", v); - printk("\n"); -} - -void print_all_local_APICs (void) -{ - on_each_cpu(print_local_APIC, NULL, 1, 1); -} - -void /*__init*/ print_PIC(void) -{ - unsigned int v; - unsigned long flags; - - if (apic_verbosity == APIC_QUIET) - return; - - printk(KERN_DEBUG "\nprinting PIC contents\n"); - - spin_lock_irqsave(&i8259A_lock, flags); - - v = inb(0xa1) << 8 | inb(0x21); - printk(KERN_DEBUG "... PIC IMR: %04x\n", v); - - v = inb(0xa0) << 8 | inb(0x20); - printk(KERN_DEBUG "... PIC IRR: %04x\n", v); - - outb(0x0b,0xa0); - outb(0x0b,0x20); - v = inb(0xa0) << 8 | inb(0x20); - outb(0x0a,0xa0); - outb(0x0a,0x20); - - spin_unlock_irqrestore(&i8259A_lock, flags); - - printk(KERN_DEBUG "... PIC ISR: %04x\n", v); - - v = inb(0x4d1) << 8 | inb(0x4d0); - printk(KERN_DEBUG "... PIC ELCR: %04x\n", v); -} - -#endif /* 0 */ - -#else -void __init print_IO_APIC(void) { } -#endif /* !CONFIG_XEN */ - -static void __init enable_IO_APIC(void) -{ - union IO_APIC_reg_01 reg_01; - int i8259_apic, i8259_pin; - int i, apic; - unsigned long flags; - - for (i = 0; i < PIN_MAP_SIZE; i++) { - irq_2_pin[i].pin = -1; - irq_2_pin[i].next = 0; - } - if (!pirqs_enabled) - for (i = 0; i < MAX_PIRQS; i++) - pirq_entries[i] = -1; - - /* - * The number of IO-APIC IRQ registers (== #pins): - */ - for (apic = 0; apic < nr_ioapics; apic++) { - spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(apic, 1); - spin_unlock_irqrestore(&ioapic_lock, flags); - nr_ioapic_registers[apic] = reg_01.bits.entries+1; - } - for(apic = 0; apic < nr_ioapics; apic++) { - int pin; - /* See if any of the pins is in ExtINT mode */ - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { - struct IO_APIC_route_entry entry; - spin_lock_irqsave(&ioapic_lock, flags); - *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); - *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); - spin_unlock_irqrestore(&ioapic_lock, flags); - - - /* If the interrupt line is enabled and in ExtInt mode - * I have found the pin where the i8259 is connected. - */ - if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) { - ioapic_i8259.apic = apic; - ioapic_i8259.pin = pin; - goto found_i8259; - } - } - } - found_i8259: - /* Look to see what if the MP table has reported the ExtINT */ - /* If we could not find the appropriate pin by looking at the ioapic - * the i8259 probably is not connected the ioapic but give the - * mptable a chance anyway. - */ - i8259_pin = find_isa_irq_pin(0, mp_ExtINT); - i8259_apic = find_isa_irq_apic(0, mp_ExtINT); - /* Trust the MP table if nothing is setup in the hardware */ - if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) { - printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n"); - ioapic_i8259.pin = i8259_pin; - ioapic_i8259.apic = i8259_apic; - } - /* Complain if the MP table and the hardware disagree */ - if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) && - (i8259_pin >= 0) && (ioapic_i8259.pin >= 0)) - { - printk(KERN_WARNING "ExtINT in hardware and MP table differ\n"); - } - - /* - * Do not trust the IO-APIC being empty at bootup - */ - clear_IO_APIC(); -} - -/* - * Not an __init, needed by the reboot code - */ -void disable_IO_APIC(void) -{ - /* - * Clear the IO-APIC before rebooting: - */ - clear_IO_APIC(); - -#ifndef CONFIG_XEN - /* - * If the i8259 is routed through an IOAPIC - * Put that IOAPIC in virtual wire mode - * so legacy interrupts can be delivered. - */ - if (ioapic_i8259.pin != -1) { - struct IO_APIC_route_entry entry; - unsigned long flags; - - memset(&entry, 0, sizeof(entry)); - entry.mask = 0; /* Enabled */ - entry.trigger = 0; /* Edge */ - entry.irr = 0; - entry.polarity = 0; /* High */ - entry.delivery_status = 0; - entry.dest_mode = 0; /* Physical */ - entry.delivery_mode = dest_ExtINT; /* ExtInt */ - entry.vector = 0; - entry.dest.physical.physical_dest = - GET_APIC_ID(apic_read(APIC_ID)); - - /* - * Add it to the IO-APIC irq-routing table: - */ - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin, - *(((int *)&entry)+1)); - io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin, - *(((int *)&entry)+0)); - spin_unlock_irqrestore(&ioapic_lock, flags); - } - disconnect_bsp_APIC(ioapic_i8259.pin != -1); -#endif -} - -/* - * function to set the IO-APIC physical IDs based on the - * values stored in the MPC table. - * - * by Matt Domsch Tue Dec 21 12:25:05 CST 1999 - */ - -#if !defined(CONFIG_XEN) && !defined(CONFIG_X86_NUMAQ) -static void __init setup_ioapic_ids_from_mpc(void) -{ - union IO_APIC_reg_00 reg_00; - physid_mask_t phys_id_present_map; - int apic; - int i; - unsigned char old_id; - unsigned long flags; - - /* - * Don't check I/O APIC IDs for xAPIC systems. They have - * no meaning without the serial APIC bus. - */ - if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) - return; - /* - * This is broken; anything with a real cpu count has to - * circumvent this idiocy regardless. - */ - phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map); - - /* - * Set the IOAPIC ID to the value stored in the MPC table. - */ - for (apic = 0; apic < nr_ioapics; apic++) { - - /* Read the register 0 value */ - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(apic, 0); - spin_unlock_irqrestore(&ioapic_lock, flags); - - old_id = mp_ioapics[apic].mpc_apicid; - - if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) { - printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", - apic, mp_ioapics[apic].mpc_apicid); - printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", - reg_00.bits.ID); - mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; - } - - /* - * Sanity check, is the ID really free? Every APIC in a - * system must have a unique ID or we get lots of nice - * 'stuck on smp_invalidate_needed IPI wait' messages. - */ - if (check_apicid_used(phys_id_present_map, - mp_ioapics[apic].mpc_apicid)) { - printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", - apic, mp_ioapics[apic].mpc_apicid); - for (i = 0; i < get_physical_broadcast(); i++) - if (!physid_isset(i, phys_id_present_map)) - break; - if (i >= get_physical_broadcast()) - panic("Max APIC ID exceeded!\n"); - printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", - i); - physid_set(i, phys_id_present_map); - mp_ioapics[apic].mpc_apicid = i; - } else { - physid_mask_t tmp; - tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid); - apic_printk(APIC_VERBOSE, "Setting %d in the " - "phys_id_present_map\n", - mp_ioapics[apic].mpc_apicid); - physids_or(phys_id_present_map, phys_id_present_map, tmp); - } - - - /* - * We need to adjust the IRQ routing table - * if the ID changed. - */ - if (old_id != mp_ioapics[apic].mpc_apicid) - for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].mpc_dstapic == old_id) - mp_irqs[i].mpc_dstapic - = mp_ioapics[apic].mpc_apicid; - - /* - * Read the right value from the MPC table and - * write it into the ID register. - */ - apic_printk(APIC_VERBOSE, KERN_INFO - "...changing IO-APIC physical APIC ID to %d ...", - mp_ioapics[apic].mpc_apicid); - - reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0, reg_00.raw); - spin_unlock_irqrestore(&ioapic_lock, flags); - - /* - * Sanity check - */ - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(apic, 0); - spin_unlock_irqrestore(&ioapic_lock, flags); - if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) - printk("could not set ID!\n"); - else - apic_printk(APIC_VERBOSE, " ok.\n"); - } -} -#else -static void __init setup_ioapic_ids_from_mpc(void) { } -#endif - -#ifndef CONFIG_XEN -/* - * There is a nasty bug in some older SMP boards, their mptable lies - * about the timer IRQ. We do the following to work around the situation: - * - * - timer IRQ defaults to IO-APIC IRQ - * - if this function detects that timer IRQs are defunct, then we fall - * back to ISA timer IRQs - */ -static int __init timer_irq_works(void) -{ - unsigned long t1 = jiffies; - - local_irq_enable(); - /* Let ten ticks pass... */ - mdelay((10 * 1000) / HZ); - - /* - * Expect a few ticks at least, to be sure some possible - * glue logic does not lock up after one or two first - * ticks in a non-ExtINT mode. Also the local APIC - * might have cached one ExtINT interrupt. Finally, at - * least one tick may be lost due to delays. - */ - if (jiffies - t1 > 4) - return 1; - - return 0; -} - -/* - * In the SMP+IOAPIC case it might happen that there are an unspecified - * number of pending IRQ events unhandled. These cases are very rare, - * so we 'resend' these IRQs via IPIs, to the same CPU. It's much - * better to do it this way as thus we do not have to be aware of - * 'pending' interrupts in the IRQ path, except at this point. - */ -/* - * Edge triggered needs to resend any interrupt - * that was delayed but this is now handled in the device - * independent code. - */ - -/* - * Starting up a edge-triggered IO-APIC interrupt is - * nasty - we need to make sure that we get the edge. - * If it is already asserted for some reason, we need - * return 1 to indicate that is was pending. - * - * This is not complete - we should be able to fake - * an edge even if it isn't on the 8259A... - */ -static unsigned int startup_edge_ioapic_irq(unsigned int irq) -{ - int was_pending = 0; - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - if (irq < 16) { - disable_8259A_irq(irq); - if (i8259A_irq_pending(irq)) - was_pending = 1; - } - __unmask_IO_APIC_irq(irq); - spin_unlock_irqrestore(&ioapic_lock, flags); - - return was_pending; -} - -/* - * Once we have recorded IRQ_PENDING already, we can mask the - * interrupt for real. This prevents IRQ storms from unhandled - * devices. - */ -static void ack_edge_ioapic_irq(unsigned int irq) -{ - move_irq(irq); - if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) - == (IRQ_PENDING | IRQ_DISABLED)) - mask_IO_APIC_irq(irq); - ack_APIC_irq(); -} - -/* - * Level triggered interrupts can just be masked, - * and shutting down and starting up the interrupt - * is the same as enabling and disabling them -- except - * with a startup need to return a "was pending" value. - * - * Level triggered interrupts are special because we - * do not touch any IO-APIC register while handling - * them. We ack the APIC in the end-IRQ handler, not - * in the start-IRQ-handler. Protection against reentrance - * from the same interrupt is still provided, both by the - * generic IRQ layer and by the fact that an unacked local - * APIC does not accept IRQs. - */ -static unsigned int startup_level_ioapic_irq (unsigned int irq) -{ - unmask_IO_APIC_irq(irq); - - return 0; /* don't check for pending */ -} - -static void end_level_ioapic_irq (unsigned int irq) -{ - unsigned long v; - int i; - - move_irq(irq); -/* - * It appears there is an erratum which affects at least version 0x11 - * of I/O APIC (that's the 82093AA and cores integrated into various - * chipsets). Under certain conditions a level-triggered interrupt is - * erroneously delivered as edge-triggered one but the respective IRR - * bit gets set nevertheless. As a result the I/O unit expects an EOI - * message but it will never arrive and further interrupts are blocked - * from the source. The exact reason is so far unknown, but the - * phenomenon was observed when two consecutive interrupt requests - * from a given source get delivered to the same CPU and the source is - * temporarily disabled in between. - * - * A workaround is to simulate an EOI message manually. We achieve it - * by setting the trigger mode to edge and then to level when the edge - * trigger mode gets detected in the TMR of a local APIC for a - * level-triggered interrupt. We mask the source for the time of the - * operation to prevent an edge-triggered interrupt escaping meanwhile. - * The idea is from Manfred Spraul. --macro - */ - i = IO_APIC_VECTOR(irq); - - v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); - - ack_APIC_irq(); - - if (!(v & (1 << (i & 0x1f)))) { - atomic_inc(&irq_mis_count); - spin_lock(&ioapic_lock); - __mask_and_edge_IO_APIC_irq(irq); - __unmask_and_level_IO_APIC_irq(irq); - spin_unlock(&ioapic_lock); - } -} - -#ifdef CONFIG_PCI_MSI -static unsigned int startup_edge_ioapic_vector(unsigned int vector) -{ - int irq = vector_to_irq(vector); - - return startup_edge_ioapic_irq(irq); -} - -static void ack_edge_ioapic_vector(unsigned int vector) -{ - int irq = vector_to_irq(vector); - - move_native_irq(vector); - ack_edge_ioapic_irq(irq); -} - -static unsigned int startup_level_ioapic_vector (unsigned int vector) -{ - int irq = vector_to_irq(vector); - - return startup_level_ioapic_irq (irq); -} - -static void end_level_ioapic_vector (unsigned int vector) -{ - int irq = vector_to_irq(vector); - - move_native_irq(vector); - end_level_ioapic_irq(irq); -} - -static void mask_IO_APIC_vector (unsigned int vector) -{ - int irq = vector_to_irq(vector); - - mask_IO_APIC_irq(irq); -} - -static void unmask_IO_APIC_vector (unsigned int vector) -{ - int irq = vector_to_irq(vector); - - unmask_IO_APIC_irq(irq); -} - -#ifdef CONFIG_SMP -static void set_ioapic_affinity_vector (unsigned int vector, - cpumask_t cpu_mask) -{ - int irq = vector_to_irq(vector); - - set_native_irq_info(vector, cpu_mask); - set_ioapic_affinity_irq(irq, cpu_mask); -} -#endif -#endif - -/* - * Level and edge triggered IO-APIC interrupts need different handling, - * so we use two separate IRQ descriptors. Edge triggered IRQs can be - * handled with the level-triggered descriptor, but that one has slightly - * more overhead. Level-triggered interrupts cannot be handled with the - * edge-triggered handler, without risking IRQ storms and other ugly - * races. - */ -static struct hw_interrupt_type ioapic_edge_type __read_mostly = { - .typename = "IO-APIC-edge", - .startup = startup_edge_ioapic, - .shutdown = shutdown_edge_ioapic, - .enable = enable_edge_ioapic, - .disable = disable_edge_ioapic, - .ack = ack_edge_ioapic, - .end = end_edge_ioapic, -#ifdef CONFIG_SMP - .set_affinity = set_ioapic_affinity, -#endif -}; - -static struct hw_interrupt_type ioapic_level_type __read_mostly = { - .typename = "IO-APIC-level", - .startup = startup_level_ioapic, - .shutdown = shutdown_level_ioapic, - .enable = enable_level_ioapic, - .disable = disable_level_ioapic, - .ack = mask_and_ack_level_ioapic, - .end = end_level_ioapic, -#ifdef CONFIG_SMP - .set_affinity = set_ioapic_affinity, -#endif -}; -#endif /* !CONFIG_XEN */ - -static inline void init_IO_APIC_traps(void) -{ - int irq; - - /* - * NOTE! The local APIC isn't very good at handling - * multiple interrupts at the same interrupt level. - * As the interrupt level is determined by taking the - * vector number and shifting that right by 4, we - * want to spread these out a bit so that they don't - * all fall in the same interrupt level. - * - * Also, we've got to be careful not to trash gate - * 0x80, because int 0x80 is hm, kind of importantish. ;) - */ - for (irq = 0; irq < NR_IRQS ; irq++) { - int tmp = irq; - if (use_pci_vector()) { - if (!platform_legacy_irq(tmp)) - if ((tmp = vector_to_irq(tmp)) == -1) - continue; - } - if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { - /* - * Hmm.. We don't have an entry for this, - * so default to an old-fashioned 8259 - * interrupt if we can.. - */ - if (irq < 16) - make_8259A_irq(irq); -#ifndef CONFIG_XEN - else - /* Strange. Oh, well.. */ - irq_desc[irq].handler = &no_irq_type; -#endif - } - } -} - -#ifndef CONFIG_XEN -static void enable_lapic_irq (unsigned int irq) -{ - unsigned long v; - - v = apic_read(APIC_LVT0); - apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); -} - -static void disable_lapic_irq (unsigned int irq) -{ - unsigned long v; - - v = apic_read(APIC_LVT0); - apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); -} - -static void ack_lapic_irq (unsigned int irq) -{ - ack_APIC_irq(); -} - -static void end_lapic_irq (unsigned int i) { /* nothing */ } - -static struct hw_interrupt_type lapic_irq_type __read_mostly = { - .typename = "local-APIC-edge", - .startup = NULL, /* startup_irq() not used for IRQ0 */ - .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */ - .enable = enable_lapic_irq, - .disable = disable_lapic_irq, - .ack = ack_lapic_irq, - .end = end_lapic_irq -}; - -static void setup_nmi (void) -{ - /* - * Dirty trick to enable the NMI watchdog ... - * We put the 8259A master into AEOI mode and - * unmask on all local APICs LVT0 as NMI. - * - * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') - * is from Maciej W. Rozycki - so we do not have to EOI from - * the NMI handler or the timer interrupt. - */ - apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); - - on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1); - - apic_printk(APIC_VERBOSE, " done.\n"); -} - -/* - * This looks a bit hackish but it's about the only one way of sending - * a few INTA cycles to 8259As and any associated glue logic. ICR does - * not support the ExtINT mode, unfortunately. We need to send these - * cycles as some i82489DX-based boards have glue logic that keeps the - * 8259A interrupt line asserted until INTA. --macro - */ -static inline void unlock_ExtINT_logic(void) -{ - int apic, pin, i; - struct IO_APIC_route_entry entry0, entry1; - unsigned char save_control, save_freq_select; - unsigned long flags; - - pin = find_isa_irq_pin(8, mp_INT); - apic = find_isa_irq_apic(8, mp_INT); - if (pin == -1) - return; - - spin_lock_irqsave(&ioapic_lock, flags); - *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin); - *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin); - spin_unlock_irqrestore(&ioapic_lock, flags); - clear_IO_APIC_pin(apic, pin); - - memset(&entry1, 0, sizeof(entry1)); - - entry1.dest_mode = 0; /* physical delivery */ - entry1.mask = 0; /* unmask IRQ now */ - entry1.dest.physical.physical_dest = hard_smp_processor_id(); - entry1.delivery_mode = dest_ExtINT; - entry1.polarity = entry0.polarity; - entry1.trigger = 0; - entry1.vector = 0; - - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1)); - io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0)); - spin_unlock_irqrestore(&ioapic_lock, flags); - - save_control = CMOS_READ(RTC_CONTROL); - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); - CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6, - RTC_FREQ_SELECT); - CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL); - - i = 100; - while (i-- > 0) { - mdelay(10); - if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF) - i -= 10; - } - - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - clear_IO_APIC_pin(apic, pin); - - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1)); - io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0)); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -int timer_uses_ioapic_pin_0; - -/* - * This code may look a bit paranoid, but it's supposed to cooperate with - * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ - * is so screwy. Thanks to Brian Perkins for testing/hacking this beast - * fanatically on his truly buggy board. - */ -static inline void check_timer(void) -{ - int apic1, pin1, apic2, pin2; - int vector; - - /* - * get/set the timer IRQ vector: - */ - disable_8259A_irq(0); - vector = assign_irq_vector(0); - set_intr_gate(vector, interrupt[0]); - - /* - * Subtle, code in do_timer_interrupt() expects an AEOI - * mode for the 8259A whenever interrupts are routed - * through I/O APICs. Also IRQ0 has to be enabled in - * the 8259A which implies the virtual wire has to be - * disabled in the local APIC. - */ - apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); - init_8259A(1); - timer_ack = 1; - if (timer_over_8254 > 0) - enable_8259A_irq(0); - - pin1 = find_isa_irq_pin(0, mp_INT); - apic1 = find_isa_irq_apic(0, mp_INT); - pin2 = ioapic_i8259.pin; - apic2 = ioapic_i8259.apic; - - if (pin1 == 0) - timer_uses_ioapic_pin_0 = 1; - - printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", - vector, apic1, pin1, apic2, pin2); - - if (pin1 != -1) { - /* - * Ok, does IRQ0 through the IOAPIC work? - */ - unmask_IO_APIC_irq(0); - if (timer_irq_works()) { - if (nmi_watchdog == NMI_IO_APIC) { - disable_8259A_irq(0); - setup_nmi(); - enable_8259A_irq(0); - } - if (disable_timer_pin_1 > 0) - clear_IO_APIC_pin(0, pin1); - return; - } - clear_IO_APIC_pin(apic1, pin1); - printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to " - "IO-APIC\n"); - } - - printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... "); - if (pin2 != -1) { - printk("\n..... (found pin %d) ...", pin2); - /* - * legacy devices should be connected to IO APIC #0 - */ - setup_ExtINT_IRQ0_pin(apic2, pin2, vector); - if (timer_irq_works()) { - printk("works.\n"); - if (pin1 != -1) - replace_pin_at_irq(0, apic1, pin1, apic2, pin2); - else - add_pin_to_irq(0, apic2, pin2); - if (nmi_watchdog == NMI_IO_APIC) { - setup_nmi(); - } - return; - } - /* - * Cleanup, just in case ... - */ - clear_IO_APIC_pin(apic2, pin2); - } - printk(" failed.\n"); - - if (nmi_watchdog == NMI_IO_APIC) { - printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); - nmi_watchdog = 0; - } - - printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); - - disable_8259A_irq(0); - irq_desc[0].handler = &lapic_irq_type; - apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ - enable_8259A_irq(0); - - if (timer_irq_works()) { - printk(" works.\n"); - return; - } - apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); - printk(" failed.\n"); - - printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); - - timer_ack = 0; - init_8259A(0); - make_8259A_irq(0); - apic_write_around(APIC_LVT0, APIC_DM_EXTINT); - - unlock_ExtINT_logic(); - - if (timer_irq_works()) { - printk(" works.\n"); - return; - } - printk(" failed :(.\n"); - panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " - "report. Then try booting with the 'noapic' option"); -} -#else -int timer_uses_ioapic_pin_0; -#define check_timer() ((void)0) -#endif - -/* - * - * IRQ's that are handled by the PIC in the MPS IOAPIC case. - * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ. - * Linux doesn't really care, as it's not actually used - * for any interrupt handling anyway. - */ -#define PIC_IRQS (1 << PIC_CASCADE_IR) - -void __init setup_IO_APIC(void) -{ - enable_IO_APIC(); - - if (acpi_ioapic) - io_apic_irqs = ~0; /* all IRQs go through IOAPIC */ - else - io_apic_irqs = ~PIC_IRQS; - - printk("ENABLING IO-APIC IRQs\n"); - - /* - * Set up IO-APIC IRQ routing. - */ - if (!acpi_ioapic) - setup_ioapic_ids_from_mpc(); -#ifndef CONFIG_XEN - sync_Arb_IDs(); -#endif - setup_IO_APIC_irqs(); - init_IO_APIC_traps(); - check_timer(); - if (!acpi_ioapic) - print_IO_APIC(); -} - -static int __init setup_disable_8254_timer(char *s) -{ - timer_over_8254 = -1; - return 1; -} -static int __init setup_enable_8254_timer(char *s) -{ - timer_over_8254 = 2; - return 1; -} - -__setup("disable_8254_timer", setup_disable_8254_timer); -__setup("enable_8254_timer", setup_enable_8254_timer); - -/* - * Called after all the initialization is done. If we didnt find any - * APIC bugs then we can allow the modify fast path - */ - -static int __init io_apic_bug_finalize(void) -{ - if(sis_apic_bug == -1) - sis_apic_bug = 0; - if (xen_start_info->flags & SIF_INITDOMAIN) { - dom0_op_t op = { .cmd = DOM0_PLATFORM_QUIRK }; - op.u.platform_quirk.quirk_id = sis_apic_bug ? - QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL; - HYPERVISOR_dom0_op(&op); - } - return 0; -} - -late_initcall(io_apic_bug_finalize); - -struct sysfs_ioapic_data { - struct sys_device dev; - struct IO_APIC_route_entry entry[0]; -}; -static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; - -static int ioapic_suspend(struct sys_device *dev, pm_message_t state) -{ - struct IO_APIC_route_entry *entry; - struct sysfs_ioapic_data *data; - unsigned long flags; - int i; - - data = container_of(dev, struct sysfs_ioapic_data, dev); - entry = data->entry; - spin_lock_irqsave(&ioapic_lock, flags); - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { - *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); - *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); - } - spin_unlock_irqrestore(&ioapic_lock, flags); - - return 0; -} - -static int ioapic_resume(struct sys_device *dev) -{ - struct IO_APIC_route_entry *entry; - struct sysfs_ioapic_data *data; - unsigned long flags; - union IO_APIC_reg_00 reg_00; - int i; - - data = container_of(dev, struct sysfs_ioapic_data, dev); - entry = data->entry; - - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(dev->id, 0); - if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) { - reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; - io_apic_write(dev->id, 0, reg_00.raw); - } - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { - io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); - io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); - } - spin_unlock_irqrestore(&ioapic_lock, flags); - - return 0; -} - -static struct sysdev_class ioapic_sysdev_class = { - set_kset_name("ioapic"), - .suspend = ioapic_suspend, - .resume = ioapic_resume, -}; - -static int __init ioapic_init_sysfs(void) -{ - struct sys_device * dev; - int i, size, error = 0; - - error = sysdev_class_register(&ioapic_sysdev_class); - if (error) - return error; - - for (i = 0; i < nr_ioapics; i++ ) { - size = sizeof(struct sys_device) + nr_ioapic_registers[i] - * sizeof(struct IO_APIC_route_entry); - mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL); - if (!mp_ioapic_data[i]) { - printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); - continue; - } - memset(mp_ioapic_data[i], 0, size); - dev = &mp_ioapic_data[i]->dev; - dev->id = i; - dev->cls = &ioapic_sysdev_class; - error = sysdev_register(dev); - if (error) { - kfree(mp_ioapic_data[i]); - mp_ioapic_data[i] = NULL; - printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); - continue; - } - } - - return 0; -} - -device_initcall(ioapic_init_sysfs); - -/* -------------------------------------------------------------------------- - ACPI-based IOAPIC Configuration - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI - -int __init io_apic_get_unique_id (int ioapic, int apic_id) -{ -#ifndef CONFIG_XEN - union IO_APIC_reg_00 reg_00; - static physid_mask_t apic_id_map = PHYSID_MASK_NONE; - physid_mask_t tmp; - unsigned long flags; - int i = 0; - - /* - * The P4 platform supports up to 256 APIC IDs on two separate APIC - * buses (one for LAPICs, one for IOAPICs), where predecessors only - * supports up to 16 on one shared APIC bus. - * - * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full - * advantage of new APIC bus architecture. - */ - - if (physids_empty(apic_id_map)) - apic_id_map = ioapic_phys_id_map(phys_cpu_present_map); - - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(ioapic, 0); - spin_unlock_irqrestore(&ioapic_lock, flags); - - if (apic_id >= get_physical_broadcast()) { - printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " - "%d\n", ioapic, apic_id, reg_00.bits.ID); - apic_id = reg_00.bits.ID; - } - - /* - * Every APIC in a system must have a unique ID or we get lots of nice - * 'stuck on smp_invalidate_needed IPI wait' messages. - */ - if (check_apicid_used(apic_id_map, apic_id)) { - - for (i = 0; i < get_physical_broadcast(); i++) { - if (!check_apicid_used(apic_id_map, i)) - break; - } - - if (i == get_physical_broadcast()) - panic("Max apic_id exceeded!\n"); - - printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " - "trying %d\n", ioapic, apic_id, i); - - apic_id = i; - } - - tmp = apicid_to_cpu_present(apic_id); - physids_or(apic_id_map, apic_id_map, tmp); - - if (reg_00.bits.ID != apic_id) { - reg_00.bits.ID = apic_id; - - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(ioapic, 0, reg_00.raw); - reg_00.raw = io_apic_read(ioapic, 0); - spin_unlock_irqrestore(&ioapic_lock, flags); - - /* Sanity check */ - if (reg_00.bits.ID != apic_id) { - printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); - return -1; - } - } - - apic_printk(APIC_VERBOSE, KERN_INFO - "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); -#endif /* !CONFIG_XEN */ - - return apic_id; -} - - -int __init io_apic_get_version (int ioapic) -{ - union IO_APIC_reg_01 reg_01; - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(ioapic, 1); - spin_unlock_irqrestore(&ioapic_lock, flags); - - return reg_01.bits.version; -} - - -int __init io_apic_get_redir_entries (int ioapic) -{ - union IO_APIC_reg_01 reg_01; - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(ioapic, 1); - spin_unlock_irqrestore(&ioapic_lock, flags); - - return reg_01.bits.entries; -} - - -int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low) -{ - struct IO_APIC_route_entry entry; - unsigned long flags; - - if (!IO_APIC_IRQ(irq)) { - printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", - ioapic); - return -EINVAL; - } - - /* - * Generate a PCI IRQ routing entry and program the IOAPIC accordingly. - * Note that we mask (disable) IRQs now -- these get enabled when the - * corresponding device driver registers for this IRQ. - */ - - memset(&entry,0,sizeof(entry)); - - entry.delivery_mode = INT_DELIVERY_MODE; - entry.dest_mode = INT_DEST_MODE; - entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); - entry.trigger = edge_level; - entry.polarity = active_high_low; - entry.mask = 1; - - /* - * IRQs < 16 are already in the irq_2_pin[] map - */ - if (irq >= 16) - add_pin_to_irq(irq, ioapic, pin); - - entry.vector = assign_irq_vector(irq); - - apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry " - "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic, - mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, - edge_level, active_high_low); - - ioapic_register_intr(irq, entry.vector, edge_level); - - if (!ioapic && (irq < 16)) - disable_8259A_irq(irq); - - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); - io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); - set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); - spin_unlock_irqrestore(&ioapic_lock, flags); - - return 0; -} - -#endif /* CONFIG_ACPI */ diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index d70f2ade5..39d9a5fa9 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -351,8 +351,8 @@ static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) { int i, j; Dprintk("Rotating IRQs among CPUs.\n"); - for_each_online_cpu(i) { - for (j = 0; j < NR_IRQS; j++) { + for (i = 0; i < NR_CPUS; i++) { + for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) { if (!irq_desc[j].action) continue; /* Is it a significant load ? */ @@ -381,7 +381,7 @@ static void do_irq_balance(void) unsigned long imbalance = 0; cpumask_t allowed_mask, target_cpu_mask, tmp; - for_each_possible_cpu(i) { + for (i = 0; i < NR_CPUS; i++) { int package_index; CPU_IRQ(i) = 0; if (!cpu_online(i)) @@ -422,7 +422,9 @@ static void do_irq_balance(void) } } /* Find the least loaded processor package */ - for_each_online_cpu(i) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; if (i != CPU_TO_PACKAGEINDEX(i)) continue; if (min_cpu_irq > CPU_IRQ(i)) { @@ -439,7 +441,9 @@ tryanothercpu: */ tmp_cpu_irq = 0; tmp_loaded = -1; - for_each_online_cpu(i) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; if (i != CPU_TO_PACKAGEINDEX(i)) continue; if (max_cpu_irq <= CPU_IRQ(i)) @@ -615,7 +619,9 @@ static int __init balanced_irq_init(void) if (smp_num_siblings > 1 && !cpus_empty(tmp)) physical_balance = 1; - for_each_online_cpu(i) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { @@ -632,11 +638,9 @@ static int __init balanced_irq_init(void) else printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); failed: - for_each_possible_cpu(i) { + for (i = 0; i < NR_CPUS; i++) { kfree(irq_cpu_data[i].irq_delta); - irq_cpu_data[i].irq_delta = NULL; kfree(irq_cpu_data[i].last_irq); - irq_cpu_data[i].last_irq = NULL; } return 0; } @@ -644,7 +648,7 @@ failed: int __init irqbalance_disable(char *str) { irqbalance_disabled = 1; - return 1; + return 0; } __setup("noirqbalance", irqbalance_disable); @@ -1757,8 +1761,7 @@ static void __init setup_ioapic_ids_from_mpc(void) * Don't check I/O APIC IDs for xAPIC systems. They have * no meaning without the serial APIC bus. */ - if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) + if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15)) return; /* * This is broken; anything with a real cpu count has to @@ -2238,8 +2241,6 @@ static inline void unlock_ExtINT_logic(void) spin_unlock_irqrestore(&ioapic_lock, flags); } -int timer_uses_ioapic_pin_0; - /* * This code may look a bit paranoid, but it's supposed to cooperate with * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ @@ -2276,9 +2277,6 @@ static inline void check_timer(void) pin2 = ioapic_i8259.pin; apic2 = ioapic_i8259.apic; - if (pin1 == 0) - timer_uses_ioapic_pin_0 = 1; - printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", vector, apic1, pin1, apic2, pin2); diff --git a/arch/i386/kernel/ioport-xen.c b/arch/i386/kernel/ioport-xen.c deleted file mode 100644 index ee66fc288..000000000 --- a/arch/i386/kernel/ioport-xen.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * linux/arch/i386/kernel/ioport.c - * - * This contains the io-permission bitmap code - written by obz, with changes - * by Linus. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ -static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) -{ - unsigned long mask; - unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG); - unsigned int low_index = base & (BITS_PER_LONG-1); - int length = low_index + extent; - - if (low_index != 0) { - mask = (~0UL << low_index); - if (length < BITS_PER_LONG) - mask &= ~(~0UL << length); - if (new_value) - *bitmap_base++ |= mask; - else - *bitmap_base++ &= ~mask; - length -= BITS_PER_LONG; - } - - mask = (new_value ? ~0UL : 0UL); - while (length >= BITS_PER_LONG) { - *bitmap_base++ = mask; - length -= BITS_PER_LONG; - } - - if (length > 0) { - mask = ~(~0UL << length); - if (new_value) - *bitmap_base++ |= mask; - else - *bitmap_base++ &= ~mask; - } -} - - -/* - * this changes the io permissions bitmap in the current task. - */ -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) -{ - struct thread_struct * t = ¤t->thread; - unsigned long *bitmap; - struct physdev_set_iobitmap set_iobitmap; - - if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) - return -EINVAL; - if (turn_on && !capable(CAP_SYS_RAWIO)) - return -EPERM; - - /* - * If it's the first ioperm() call in this thread's lifetime, set the - * IO bitmap up. ioperm() is much less timing critical than clone(), - * this is why we delay this operation until now: - */ - if (!t->io_bitmap_ptr) { - bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); - if (!bitmap) - return -ENOMEM; - - memset(bitmap, 0xff, IO_BITMAP_BYTES); - t->io_bitmap_ptr = bitmap; - - set_iobitmap.bitmap = (char *)bitmap; - set_iobitmap.nr_ports = IO_BITMAP_BITS; - HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap); - } - - set_bitmap(t->io_bitmap_ptr, from, num, !turn_on); - - return 0; -} - -/* - * sys_iopl has to be used when you want to access the IO ports - * beyond the 0x3ff range: to get the full 65536 ports bitmapped - * you'd need 8kB of bitmaps/process, which is a bit excessive. - * - * Here we just change the eflags value on the stack: we allow - * only the super-user to do it. This depends on the stack-layout - * on system-call entry - see also fork() and the signal handling - * code. - */ - -asmlinkage long sys_iopl(unsigned long unused) -{ - volatile struct pt_regs * regs = (struct pt_regs *) &unused; - unsigned int level = regs->ebx; - struct thread_struct *t = ¤t->thread; - unsigned int old = (t->iopl >> 12) & 3; - - if (level > 3) - return -EINVAL; - /* Trying to gain more privileges? */ - if (level > old) { - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - } - t->iopl = level << 12; - set_iopl_mask(t->iopl); - return 0; -} diff --git a/arch/i386/kernel/irq-xen.c b/arch/i386/kernel/irq-xen.c deleted file mode 100644 index b4a38e4d9..000000000 --- a/arch/i386/kernel/irq-xen.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * linux/arch/i386/kernel/irq.c - * - * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar - * - * This file contains the lowest level x86-specific interrupt - * entry, irq-stacks and irq statistics code. All the remaining - * irq logic is done by the generic kernel/irq/ code and - * by the x86-specific irq controller code. (e.g. i8259.c and - * io_apic.c.) - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp; -EXPORT_PER_CPU_SYMBOL(irq_stat); - -#ifndef CONFIG_X86_LOCAL_APIC -/* - * '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("unexpected IRQ trap at vector %02x\n", irq); -} -#endif - -#ifdef CONFIG_4KSTACKS -/* - * per-CPU IRQ handling contexts (thread information and stack) - */ -union irq_ctx { - struct thread_info tinfo; - u32 stack[THREAD_SIZE/sizeof(u32)]; -}; - -static union irq_ctx *hardirq_ctx[NR_CPUS]; -static union irq_ctx *softirq_ctx[NR_CPUS]; -#endif - -/* - * do_IRQ handles all normal device IRQ's (the special - * SMP cross-CPU interrupts have their own specific - * handlers). - */ -fastcall unsigned int do_IRQ(struct pt_regs *regs) -{ - /* high bit used in ret_from_ code */ - int irq = ~regs->orig_eax; -#ifdef CONFIG_4KSTACKS - union irq_ctx *curctx, *irqctx; - u32 *isp; -#endif - - irq_enter(); -#ifdef CONFIG_DEBUG_STACKOVERFLOW - /* Debugging check for stack overflow: is there less than 1KB free? */ - { - long esp; - - __asm__ __volatile__("andl %%esp,%0" : - "=r" (esp) : "0" (THREAD_SIZE - 1)); - if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) { - printk("do_IRQ: stack overflow: %ld\n", - esp - sizeof(struct thread_info)); - dump_stack(); - } - } -#endif - -#ifdef CONFIG_4KSTACKS - - curctx = (union irq_ctx *) current_thread_info(); - irqctx = hardirq_ctx[smp_processor_id()]; - - /* - * this is where we switch to the IRQ stack. However, if we are - * already using the IRQ stack (because we interrupted a hardirq - * handler) we can't do that and just have to keep using the - * current stack (which is the irq stack already after all) - */ - if (curctx != irqctx) { - int arg1, arg2, ebx; - - /* build the stack frame on the IRQ stack */ - isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); - irqctx->tinfo.task = curctx->tinfo.task; - irqctx->tinfo.previous_esp = current_stack_pointer; - - asm volatile( - " xchgl %%ebx,%%esp \n" - " call __do_IRQ \n" - " movl %%ebx,%%esp \n" - : "=a" (arg1), "=d" (arg2), "=b" (ebx) - : "0" (irq), "1" (regs), "2" (isp) - : "memory", "cc", "ecx" - ); - } else -#endif - __do_IRQ(irq, regs); - - irq_exit(); - - return 1; -} - -#ifdef CONFIG_4KSTACKS - -/* - * These should really be __section__(".bss.page_aligned") as well, but - * gcc's 3.0 and earlier don't handle that correctly. - */ -static char softirq_stack[NR_CPUS * THREAD_SIZE] - __attribute__((__aligned__(THREAD_SIZE))); - -static char hardirq_stack[NR_CPUS * THREAD_SIZE] - __attribute__((__aligned__(THREAD_SIZE))); - -/* - * allocate per-cpu stacks for hardirq and for softirq processing - */ -void irq_ctx_init(int cpu) -{ - union irq_ctx *irqctx; - - if (hardirq_ctx[cpu]) - return; - - irqctx = (union irq_ctx*) &hardirq_stack[cpu*THREAD_SIZE]; - irqctx->tinfo.task = NULL; - irqctx->tinfo.exec_domain = NULL; - irqctx->tinfo.cpu = cpu; - irqctx->tinfo.preempt_count = HARDIRQ_OFFSET; - irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); - - hardirq_ctx[cpu] = irqctx; - - irqctx = (union irq_ctx*) &softirq_stack[cpu*THREAD_SIZE]; - irqctx->tinfo.task = NULL; - irqctx->tinfo.exec_domain = NULL; - irqctx->tinfo.cpu = cpu; - irqctx->tinfo.preempt_count = SOFTIRQ_OFFSET; - irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); - - softirq_ctx[cpu] = irqctx; - - printk("CPU %u irqstacks, hard=%p soft=%p\n", - cpu,hardirq_ctx[cpu],softirq_ctx[cpu]); -} - -void irq_ctx_exit(int cpu) -{ - hardirq_ctx[cpu] = NULL; -} - -extern asmlinkage void __do_softirq(void); - -asmlinkage void do_softirq(void) -{ - unsigned long flags; - struct thread_info *curctx; - union irq_ctx *irqctx; - u32 *isp; - - if (in_interrupt()) - return; - - local_irq_save(flags); - - if (local_softirq_pending()) { - curctx = current_thread_info(); - irqctx = softirq_ctx[smp_processor_id()]; - irqctx->tinfo.task = curctx->task; - irqctx->tinfo.previous_esp = current_stack_pointer; - - /* build the stack frame on the softirq stack */ - isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); - - asm volatile( - " xchgl %%ebx,%%esp \n" - " call __do_softirq \n" - " movl %%ebx,%%esp \n" - : "=b"(isp) - : "0"(isp) - : "memory", "cc", "edx", "ecx", "eax" - ); - } - - local_irq_restore(flags); -} - -EXPORT_SYMBOL(do_softirq); -#endif - -/* - * Interrupt statistics: - */ - -atomic_t irq_err_count; - -/* - * /proc/interrupts printing: - */ - -int show_interrupts(struct seq_file *p, void *v) -{ - int i = *(loff_t *) v, j; - struct irqaction * action; - unsigned long flags; - - if (i == 0) { - seq_printf(p, " "); - for_each_online_cpu(j) - seq_printf(p, "CPU%d ",j); - seq_putc(p, '\n'); - } - - if (i < NR_IRQS) { - 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, " %14s", irq_desc[i].handler->typename); - 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); - } else if (i == NR_IRQS) { - seq_printf(p, "NMI: "); - for_each_online_cpu(j) - seq_printf(p, "%10u ", nmi_count(j)); - seq_putc(p, '\n'); -#ifdef CONFIG_X86_LOCAL_APIC - seq_printf(p, "LOC: "); - for_each_online_cpu(j) - seq_printf(p, "%10u ", - per_cpu(irq_stat,j).apic_timer_irqs); - seq_putc(p, '\n'); -#endif - seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); -#if defined(CONFIG_X86_IO_APIC) - seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); -#endif - } - return 0; -} - -#ifdef CONFIG_HOTPLUG_CPU - -void fixup_irqs(cpumask_t map) -{ - unsigned int irq; - static int warned; - - for (irq = 0; irq < NR_IRQS; irq++) { - cpumask_t mask; - if (irq == 2) - continue; - - cpus_and(mask, irq_affinity[irq], map); - if (any_online_cpu(mask) == NR_CPUS) { - /*printk("Breaking affinity for irq %i\n", irq);*/ - mask = map; - } - if (irq_desc[irq].handler->set_affinity) - irq_desc[irq].handler->set_affinity(irq, mask); - else if (irq_desc[irq].action && !(warned++)) - printk("Cannot set affinity for irq %i\n", irq); - } - -#if 0 - barrier(); - /* Ingo Molnar says: "after the IO-APIC masks have been redirected - [note the nop - the interrupt-enable boundary on x86 is two - instructions from sti] - to flush out pending hardirqs and - IPIs. After this point nothing is supposed to reach this CPU." */ - __asm__ __volatile__("sti; nop; cli"); - barrier(); -#else - /* That doesn't seem sufficient. Give it 1ms. */ - local_irq_enable(); - mdelay(1); - local_irq_disable(); -#endif -} -#endif - diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 2904a6686..f3a9c78c4 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPUS]; */ fastcall unsigned int do_IRQ(struct pt_regs *regs) { - /* high bit used in ret_from_ code */ - int irq = ~regs->orig_eax; + /* high bits used in ret_from_ code */ + int irq = regs->orig_eax & 0xff; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; u32 *isp; diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 38806f427..694a13997 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -35,60 +35,16 @@ #include #include #include -#include void jprobe_return_end(void); DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); -/* insert a jmp code */ -static __always_inline void set_jmp_op(void *from, void *to) -{ - struct __arch_jmp_op { - char op; - long raddr; - } __attribute__((packed)) *jop; - jop = (struct __arch_jmp_op *)from; - jop->raddr = (long)(to) - ((long)(from) + 5); - jop->op = RELATIVEJUMP_INSTRUCTION; -} - -/* - * returns non-zero if opcodes can be boosted. - */ -static __always_inline int can_boost(kprobe_opcode_t opcode) -{ - switch (opcode & 0xf0 ) { - case 0x70: - return 0; /* can't boost conditional jump */ - case 0x90: - /* can't boost call and pushf */ - return opcode != 0x9a && opcode != 0x9c; - case 0xc0: - /* can't boost undefined opcodes and soft-interruptions */ - return (0xc1 < opcode && opcode < 0xc6) || - (0xc7 < opcode && opcode < 0xcc) || opcode == 0xcf; - case 0xd0: - /* can boost AA* and XLAT */ - return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7); - case 0xe0: - /* can boost in/out and (may be) jmps */ - return (0xe3 < opcode && opcode != 0xe8); - case 0xf0: - /* clear and set flags can be boost */ - return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); - default: - /* currently, can't boost 2 bytes opcodes */ - return opcode != 0x0f; - } -} - - /* * returns non-zero if opcode modifies the interrupt flag. */ -static int __kprobes is_IF_modifier(kprobe_opcode_t opcode) +static inline int is_IF_modifier(kprobe_opcode_t opcode) { switch (opcode) { case 0xfa: /* cli */ @@ -109,11 +65,6 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); p->opcode = *p->addr; - if (can_boost(p->opcode)) { - p->ainsn.boostable = 0; - } else { - p->ainsn.boostable = -1; - } return 0; } @@ -133,12 +84,12 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { - mutex_lock(&kprobe_mutex); + down(&kprobe_mutex); free_insn_slot(p->ainsn.insn); - mutex_unlock(&kprobe_mutex); + up(&kprobe_mutex); } -static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) +static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) { kcb->prev_kprobe.kp = kprobe_running(); kcb->prev_kprobe.status = kcb->kprobe_status; @@ -146,7 +97,7 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags; } -static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) +static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) { __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; kcb->kprobe_status = kcb->prev_kprobe.status; @@ -154,7 +105,7 @@ static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags; } -static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, +static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { __get_cpu_var(current_kprobe) = p; @@ -164,7 +115,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, kcb->kprobe_saved_eflags &= ~IF_MASK; } -static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) +static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) { regs->eflags |= TF_MASK; regs->eflags &= ~IF_MASK; @@ -204,13 +155,9 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) { struct kprobe *p; int ret = 0; - kprobe_opcode_t *addr; + kprobe_opcode_t *addr = NULL; + unsigned long *lp; struct kprobe_ctlblk *kcb; -#ifdef CONFIG_PREEMPT - unsigned pre_preempt_count = preempt_count(); -#endif /* CONFIG_PREEMPT */ - - addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t)); /* * We don't want to be preempted for the entire @@ -219,6 +166,17 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) preempt_disable(); kcb = get_kprobe_ctlblk(); + /* Check if the application is using LDT entry for its code segment and + * calculate the address by reading the base address from the LDT entry. + */ + if ((regs->xcs & 4) && (current->mm)) { + lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8) + + (char *) current->mm->context.ldt); + addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip - + sizeof(kprobe_opcode_t)); + } else { + addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t)); + } /* Check we're not actually recursing */ if (kprobe_running()) { p = get_kprobe(addr); @@ -242,6 +200,10 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) kcb->kprobe_status = KPROBE_REENTER; return 1; } else { + if (regs->eflags & VM_MASK) { + /* We are in virtual-8086 mode. Return 0 */ + goto no_kprobe; + } if (*addr != BREAKPOINT_INSTRUCTION) { /* The breakpoint instruction was removed by * another cpu right after we hit, no further @@ -261,6 +223,11 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) p = get_kprobe(addr); if (!p) { + if (regs->eflags & VM_MASK) { + /* We are in virtual-8086 mode. Return 0 */ + goto no_kprobe; + } + if (*addr != BREAKPOINT_INSTRUCTION) { /* * The breakpoint instruction was removed right @@ -285,21 +252,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) /* handler has already set things up, so skip ss setup */ return 1; - if (p->ainsn.boostable == 1 && -#ifdef CONFIG_PREEMPT - !(pre_preempt_count) && /* - * This enables booster when the direct - * execution path aren't preempted. - */ -#endif /* CONFIG_PREEMPT */ - !p->post_handler && !p->break_handler ) { - /* Boost up -- we can execute copied instructions directly */ - reset_current_kprobe(); - regs->eip = (unsigned long)p->ainsn.insn; - preempt_enable_no_resched(); - return 1; - } - ss_probe: prepare_singlestep(p, regs); kcb->kprobe_status = KPROBE_HIT_SS; @@ -315,44 +267,17 @@ no_kprobe: * here. When a retprobed function returns, this probe is hit and * trampoline_probe_handler() runs, calling the kretprobe's handler. */ - void __kprobes kretprobe_trampoline_holder(void) + void kretprobe_trampoline_holder(void) { - asm volatile ( ".global kretprobe_trampoline\n" + asm volatile ( ".global kretprobe_trampoline\n" "kretprobe_trampoline: \n" - " pushf\n" - /* skip cs, eip, orig_eax, es, ds */ - " subl $20, %esp\n" - " pushl %eax\n" - " pushl %ebp\n" - " pushl %edi\n" - " pushl %esi\n" - " pushl %edx\n" - " pushl %ecx\n" - " pushl %ebx\n" - " movl %esp, %eax\n" - " call trampoline_handler\n" - /* move eflags to cs */ - " movl 48(%esp), %edx\n" - " movl %edx, 44(%esp)\n" - /* save true return address on eflags */ - " movl %eax, 48(%esp)\n" - " popl %ebx\n" - " popl %ecx\n" - " popl %edx\n" - " popl %esi\n" - " popl %edi\n" - " popl %ebp\n" - " popl %eax\n" - /* skip eip, orig_eax, es, ds */ - " addl $16, %esp\n" - " popf\n" - " ret\n"); -} + "nop\n"); + } /* - * Called from kretprobe_trampoline + * Called when we hit the probe point at kretprobe_trampoline */ -fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) +int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; struct hlist_head *head; @@ -381,11 +306,8 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) /* another task is sharing our hash bucket */ continue; - if (ri->rp && ri->rp->handler){ - __get_cpu_var(current_kprobe) = &ri->rp->kp; + if (ri->rp && ri->rp->handler) ri->rp->handler(ri, regs); - __get_cpu_var(current_kprobe) = NULL; - } orig_ret_address = (unsigned long)ri->ret_addr; recycle_rp_inst(ri); @@ -400,10 +322,18 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) } BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->eip = orig_ret_address; + reset_current_kprobe(); spin_unlock_irqrestore(&kretprobe_lock, flags); + preempt_enable_no_resched(); - return (void*)orig_ret_address; + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we don't want the post_handler + * to run (and have re-enabled preemption) + */ + return 1; } /* @@ -427,82 +357,62 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) * 2) If the single-stepped instruction was a call, the return address * that is atop the stack is the address following the copied instruction. * We need to make it the address following the original instruction. - * - * This function also checks instruction size for preparing direct execution. */ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { unsigned long *tos = (unsigned long *)®s->esp; + unsigned long next_eip = 0; unsigned long copy_eip = (unsigned long)p->ainsn.insn; unsigned long orig_eip = (unsigned long)p->addr; - regs->eflags &= ~TF_MASK; switch (p->ainsn.insn[0]) { case 0x9c: /* pushfl */ *tos &= ~(TF_MASK | IF_MASK); *tos |= kcb->kprobe_old_eflags; break; - case 0xc2: /* iret/ret/lret */ - case 0xc3: - case 0xca: + case 0xc3: /* ret/lret */ case 0xcb: - case 0xcf: - case 0xea: /* jmp absolute -- eip is correct */ - /* eip is already adjusted, no more changes required */ - p->ainsn.boostable = 1; - goto no_change; + case 0xc2: + case 0xca: + regs->eflags &= ~TF_MASK; + /* eip is already adjusted, no more changes required*/ + return; case 0xe8: /* call relative - Fix return addr */ *tos = orig_eip + (*tos - copy_eip); break; - case 0x9a: /* call absolute -- same as call absolute, indirect */ - *tos = orig_eip + (*tos - copy_eip); - goto no_change; case 0xff: if ((p->ainsn.insn[1] & 0x30) == 0x10) { - /* - * call absolute, indirect - * Fix return addr; eip is correct. - * But this is not boostable - */ + /* call absolute, indirect */ + /* Fix return addr; eip is correct. */ + next_eip = regs->eip; *tos = orig_eip + (*tos - copy_eip); - goto no_change; } else if (((p->ainsn.insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ ((p->ainsn.insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */ - /* eip is correct. And this is boostable */ - p->ainsn.boostable = 1; - goto no_change; + /* eip is correct. */ + next_eip = regs->eip; } + break; + case 0xea: /* jmp absolute -- eip is correct */ + next_eip = regs->eip; + break; default: break; } - if (p->ainsn.boostable == 0) { - if ((regs->eip > copy_eip) && - (regs->eip - copy_eip) + 5 < MAX_INSN_SIZE) { - /* - * These instructions can be executed directly if it - * jumps back to correct address. - */ - set_jmp_op((void *)regs->eip, - (void *)orig_eip + (regs->eip - copy_eip)); - p->ainsn.boostable = 1; - } else { - p->ainsn.boostable = -1; - } + regs->eflags &= ~TF_MASK; + if (next_eip) { + regs->eip = next_eip; + } else { + regs->eip = orig_eip + (regs->eip - copy_eip); } - - regs->eip = orig_eip + (regs->eip - copy_eip); - -no_change: - return; } /* * Interrupts are disabled on entry as trap1 is an interrupt gate and they * remain disabled thoroughout this function. */ -static int __kprobes post_kprobe_handler(struct pt_regs *regs) +static inline int post_kprobe_handler(struct pt_regs *regs) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -538,62 +448,20 @@ out: return 1; } -static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) +static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); - switch(kcb->kprobe_status) { - case KPROBE_HIT_SS: - case KPROBE_REENTER: - /* - * We are here because the instruction being single - * stepped caused a page fault. We reset the current - * kprobe and the eip points back to the probe address - * and allow the page fault handler to continue as a - * normal page fault. - */ - regs->eip = (unsigned long)cur->addr; - regs->eflags |= kcb->kprobe_old_eflags; - if (kcb->kprobe_status == KPROBE_REENTER) - restore_previous_kprobe(kcb); - else - reset_current_kprobe(); - preempt_enable_no_resched(); - break; - case KPROBE_HIT_ACTIVE: - case KPROBE_HIT_SSDONE: - /* - * We increment the nmissed count for accounting, - * we can also use npre/npostfault count for accouting - * these specific fault cases. - */ - kprobes_inc_nmissed_count(cur); - - /* - * We come here because instructions in the pre/post - * handler caused the page_fault, this could happen - * if handler tries to access user space by - * copy_from_user(), get_user() etc. Let the - * user-specified handler try to fix it first. - */ - if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) - return 1; + if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) + return 1; - /* - * In case the user-specified fault handler returned - * zero, try to fix up. - */ - if (fixup_exception(regs)) - return 1; + if (kcb->kprobe_status & KPROBE_HIT_SS) { + resume_execution(cur, regs, kcb); + regs->eflags |= kcb->kprobe_old_eflags; - /* - * fixup_exception() could not handle it, - * Let do_page_fault() fix it. - */ - break; - default: - break; + reset_current_kprobe(); + preempt_enable_no_resched(); } return 0; } @@ -607,9 +475,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, struct die_args *args = (struct die_args *)data; int ret = NOTIFY_DONE; - if (args->regs && user_mode(args->regs)) - return ret; - switch (val) { case DIE_INT3: if (kprobe_handler(args->regs)) @@ -699,7 +564,12 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) return 0; } +static struct kprobe trampoline_p = { + .addr = (kprobe_opcode_t *) &kretprobe_trampoline, + .pre_handler = trampoline_probe_handler +}; + int __init arch_init_kprobes(void) { - return 0; + return register_kprobe(&trampoline_p); } diff --git a/arch/i386/kernel/ldt-xen.c b/arch/i386/kernel/ldt-xen.c deleted file mode 100644 index d2cceffbb..000000000 --- a/arch/i386/kernel/ldt-xen.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * linux/kernel/ldt.c - * - * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds - * Copyright (C) 1999 Ingo Molnar - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */ -static void flush_ldt(void *null) -{ - if (current->active_mm) - load_LDT(¤t->active_mm->context); -} -#endif - -static int alloc_ldt(mm_context_t *pc, int mincount, int reload) -{ - void *oldldt; - void *newldt; - int oldsize; - - if (mincount <= pc->size) - return 0; - oldsize = pc->size; - mincount = (mincount+511)&(~511); - if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE) - newldt = vmalloc(mincount*LDT_ENTRY_SIZE); - else - newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL); - - if (!newldt) - return -ENOMEM; - - if (oldsize) - memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE); - oldldt = pc->ldt; - memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE); - pc->ldt = newldt; - wmb(); - pc->size = mincount; - wmb(); - - if (reload) { -#ifdef CONFIG_SMP - cpumask_t mask; - preempt_disable(); -#endif - make_pages_readonly( - pc->ldt, - (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE, - XENFEAT_writable_descriptor_tables); - load_LDT(pc); -#ifdef CONFIG_SMP - mask = cpumask_of_cpu(smp_processor_id()); - if (!cpus_equal(current->mm->cpu_vm_mask, mask)) - smp_call_function(flush_ldt, NULL, 1, 1); - preempt_enable(); -#endif - } - if (oldsize) { - make_pages_writable( - oldldt, - (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE, - XENFEAT_writable_descriptor_tables); - if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE) - vfree(oldldt); - else - kfree(oldldt); - } - return 0; -} - -static inline int copy_ldt(mm_context_t *new, mm_context_t *old) -{ - int err = alloc_ldt(new, old->size, 0); - if (err < 0) - return err; - memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE); - make_pages_readonly( - new->ldt, - (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE, - XENFEAT_writable_descriptor_tables); - return 0; -} - -/* - * we do not have to muck with descriptors here, that is - * done in switch_mm() as needed. - */ -int init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - struct mm_struct * old_mm; - int retval = 0; - - init_MUTEX(&mm->context.sem); - mm->context.size = 0; - mm->context.has_foreign_mappings = 0; - old_mm = current->mm; - if (old_mm && old_mm->context.size > 0) { - down(&old_mm->context.sem); - retval = copy_ldt(&mm->context, &old_mm->context); - up(&old_mm->context.sem); - } - return retval; -} - -/* - * No need to lock the MM as we are the last user - */ -void destroy_context(struct mm_struct *mm) -{ - if (mm->context.size) { - if (mm == current->active_mm) - clear_LDT(); - make_pages_writable( - mm->context.ldt, - (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE, - XENFEAT_writable_descriptor_tables); - if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE) - vfree(mm->context.ldt); - else - kfree(mm->context.ldt); - mm->context.size = 0; - } -} - -static int read_ldt(void __user * ptr, unsigned long bytecount) -{ - int err; - unsigned long size; - struct mm_struct * mm = current->mm; - - if (!mm->context.size) - return 0; - if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) - bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; - - down(&mm->context.sem); - size = mm->context.size*LDT_ENTRY_SIZE; - if (size > bytecount) - size = bytecount; - - err = 0; - if (copy_to_user(ptr, mm->context.ldt, size)) - err = -EFAULT; - up(&mm->context.sem); - if (err < 0) - goto error_return; - if (size != bytecount) { - /* zero-fill the rest */ - if (clear_user(ptr+size, bytecount-size) != 0) { - err = -EFAULT; - goto error_return; - } - } - return bytecount; -error_return: - return err; -} - -static int read_default_ldt(void __user * ptr, unsigned long bytecount) -{ - int err; - unsigned long size; - void *address; - - err = 0; - address = &default_ldt[0]; - size = 5*sizeof(struct desc_struct); - if (size > bytecount) - size = bytecount; - - err = size; - if (copy_to_user(ptr, address, size)) - err = -EFAULT; - - return err; -} - -static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode) -{ - struct mm_struct * mm = current->mm; - __u32 entry_1, entry_2; - int error; - struct user_desc ldt_info; - - error = -EINVAL; - if (bytecount != sizeof(ldt_info)) - goto out; - error = -EFAULT; - if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) - goto out; - - error = -EINVAL; - if (ldt_info.entry_number >= LDT_ENTRIES) - goto out; - if (ldt_info.contents == 3) { - if (oldmode) - goto out; - if (ldt_info.seg_not_present == 0) - goto out; - } - - down(&mm->context.sem); - if (ldt_info.entry_number >= mm->context.size) { - error = alloc_ldt(¤t->mm->context, ldt_info.entry_number+1, 1); - if (error < 0) - goto out_unlock; - } - - /* Allow LDTs to be cleared by the user. */ - if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { - if (oldmode || LDT_empty(&ldt_info)) { - entry_1 = 0; - entry_2 = 0; - goto install; - } - } - - entry_1 = LDT_entry_a(&ldt_info); - entry_2 = LDT_entry_b(&ldt_info); - if (oldmode) - entry_2 &= ~(1 << 20); - - /* Install the new entry ... */ -install: - error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number, - entry_1, entry_2); - -out_unlock: - up(&mm->context.sem); -out: - return error; -} - -asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) -{ - int ret = -ENOSYS; - - switch (func) { - case 0: - ret = read_ldt(ptr, bytecount); - break; - case 1: - ret = write_ldt(ptr, bytecount, 1); - break; - case 2: - ret = read_default_ldt(ptr, bytecount); - break; - case 0x11: - ret = write_ldt(ptr, bytecount, 0); - break; - } - return ret; -} diff --git a/arch/i386/kernel/microcode-xen.c b/arch/i386/kernel/microcode-xen.c deleted file mode 100644 index 082324fd1..000000000 --- a/arch/i386/kernel/microcode-xen.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Intel CPU Microcode Update Driver for Linux - * - * Copyright (C) 2000-2004 Tigran Aivazian - * - * This driver allows to upgrade microcode on Intel processors - * belonging to IA-32 family - PentiumPro, Pentium II, - * Pentium III, Xeon, Pentium 4, etc. - * - * Reference: Section 8.10 of Volume III, Intel Pentium 4 Manual, - * Order Number 245472 or free download from: - * - * http://developer.intel.com/design/pentium4/manuals/245472.htm - * - * For more information, go to http://www.urbanmyth.org/microcode - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 DEBUG /* pr_debug */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver"); -MODULE_AUTHOR("Tigran Aivazian "); -MODULE_LICENSE("GPL"); - -#define MICROCODE_VERSION "1.14-xen" - -#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ -#define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */ -#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */ - -/* no concurrent ->write()s are allowed on /dev/cpu/microcode */ -static DEFINE_MUTEX(microcode_mutex); - -static void __user *user_buffer; /* user area microcode data buffer */ -static unsigned int user_buffer_size; /* it's size */ - -static int microcode_open (struct inode *unused1, struct file *unused2) -{ - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; -} - - -static int do_microcode_update (void) -{ - int err; - dom0_op_t op; - - err = sys_mlock((unsigned long)user_buffer, user_buffer_size); - if (err != 0) - return err; - - op.cmd = DOM0_MICROCODE; - set_xen_guest_handle(op.u.microcode.data, user_buffer); - op.u.microcode.length = user_buffer_size; - err = HYPERVISOR_dom0_op(&op); - - (void)sys_munlock((unsigned long)user_buffer, user_buffer_size); - - return err; -} - -static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos) -{ - ssize_t ret; - - if (len < DEFAULT_UCODE_TOTALSIZE) { - printk(KERN_ERR "microcode: not enough data\n"); - return -EINVAL; - } - - if ((len >> PAGE_SHIFT) > num_physpages) { - printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages); - return -EINVAL; - } - - mutex_lock(µcode_mutex); - - user_buffer = (void __user *) buf; - user_buffer_size = (int) len; - - ret = do_microcode_update(); - if (!ret) - ret = (ssize_t)len; - - mutex_unlock(µcode_mutex); - - return ret; -} - -static struct file_operations microcode_fops = { - .owner = THIS_MODULE, - .write = microcode_write, - .open = microcode_open, -}; - -static struct miscdevice microcode_dev = { - .minor = MICROCODE_MINOR, - .name = "microcode", - .devfs_name = "cpu/microcode", - .fops = µcode_fops, -}; - -static int __init microcode_init (void) -{ - int error; - - error = misc_register(µcode_dev); - if (error) { - printk(KERN_ERR - "microcode: can't misc_register on minor=%d\n", - MICROCODE_MINOR); - return error; - } - - printk(KERN_INFO - "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " \n"); - return 0; -} - -static void __exit microcode_exit (void) -{ - misc_deregister(µcode_dev); -} - -module_init(microcode_init) -module_exit(microcode_exit) -MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index e7c138f66..5390b521a 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -81,7 +81,6 @@ #include #include #include -#include #include #include @@ -115,7 +114,7 @@ MODULE_LICENSE("GPL"); static DEFINE_SPINLOCK(microcode_update_lock); /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ -static DEFINE_MUTEX(microcode_mutex); +static DECLARE_MUTEX(microcode_sem); static void __user *user_buffer; /* user area microcode data buffer */ static unsigned int user_buffer_size; /* it's size */ @@ -203,6 +202,8 @@ static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_he } else if (mc_header->rev == uci->rev) { /* notify the caller of success on this cpu */ uci->err = MC_SUCCESS; + printk(KERN_ERR "microcode: CPU%d already at revision" + " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); goto out; } @@ -368,6 +369,7 @@ static void do_update_one (void * unused) struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; if (uci->mc == NULL) { + printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num); return; } @@ -445,7 +447,7 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_ return -EINVAL; } - mutex_lock(µcode_mutex); + down(µcode_sem); user_buffer = (void __user *) buf; user_buffer_size = (int) len; @@ -454,14 +456,31 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_ if (!ret) ret = (ssize_t)len; - mutex_unlock(µcode_mutex); + up(µcode_sem); return ret; } +static int microcode_ioctl (struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + /* + * XXX: will be removed after microcode_ctl + * is updated to ignore failure of this ioctl() + */ + case MICROCODE_IOCFREE: + return 0; + default: + return -EINVAL; + } + return -EINVAL; +} + static struct file_operations microcode_fops = { .owner = THIS_MODULE, .write = microcode_write, + .ioctl = microcode_ioctl, .open = microcode_open, }; @@ -492,6 +511,7 @@ static int __init microcode_init (void) static void __exit microcode_exit (void) { misc_deregister(µcode_dev); + printk(KERN_INFO "IA-32 Microcode Update Driver v" MICROCODE_VERSION " unregistered\n"); } module_init(microcode_init) diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c index 2c6e3bed5..5149c8a62 100644 --- a/arch/i386/kernel/module.c +++ b/arch/i386/kernel/module.c @@ -104,42 +104,26 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, return -ENOEXEC; } +extern void apply_alternatives(void *start, void *end); + int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL; + const Elf_Shdr *s; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + /* look for .altinstructions to patch */ for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { - if (!strcmp(".text", secstrings + s->sh_name)) - text = s; - if (!strcmp(".altinstructions", secstrings + s->sh_name)) - alt = s; - if (!strcmp(".smp_locks", secstrings + s->sh_name)) - locks= s; - } - - if (alt) { - /* patch .altinstructions */ - void *aseg = (void *)alt->sh_addr; - apply_alternatives(aseg, aseg + alt->sh_size); - } -#ifdef CONFIG_SMP - if (locks && text) { - void *lseg = (void *)locks->sh_addr; - void *tseg = (void *)text->sh_addr; - alternatives_smp_module_add(me, me->name, - lseg, lseg + locks->sh_size, - tseg, tseg + text->sh_size); - } -#endif + void *seg; + if (strcmp(".altinstructions", secstrings + s->sh_name)) + continue; + seg = (void *)s->sh_addr; + apply_alternatives(seg, seg + s->sh_size); + } return 0; } void module_arch_cleanup(struct module *mod) { -#ifdef CONFIG_SMP - alternatives_smp_module_del(mod); -#endif } diff --git a/arch/i386/kernel/mpparse-xen.c b/arch/i386/kernel/mpparse-xen.c deleted file mode 100644 index 48e0bc0f8..000000000 --- a/arch/i386/kernel/mpparse-xen.c +++ /dev/null @@ -1,1186 +0,0 @@ -/* - * Intel Multiprocessor Specification 1.1 and 1.4 - * compliant MP-table parsing routines. - * - * (c) 1995 Alan Cox, Building #3 - * (c) 1998, 1999, 2000 Ingo Molnar - * - * Fixes - * Erich Boleyn : MP v1.4 and additional changes. - * Alan Cox : Added EBDA scanning - * Ingo Molnar : various cleanups and rewrites - * Maciej W. Rozycki: Bits for default MP configurations - * Paul Diefenbaugh: Added full ACPI support - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Have we found an MP table */ -int smp_found_config; -unsigned int __initdata maxcpus = NR_CPUS; - -/* - * Various Linux-internal data structures created from the - * MP-table. - */ -int apic_version [MAX_APICS]; -int mp_bus_id_to_type [MAX_MP_BUSSES]; -int mp_bus_id_to_node [MAX_MP_BUSSES]; -int mp_bus_id_to_local [MAX_MP_BUSSES]; -int quad_local_to_mp_bus_id [NR_CPUS/4][4]; -int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; -static int mp_current_pci_id; - -/* I/O APIC entries */ -struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; - -/* # of MP IRQ source entries */ -struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; - -/* MP IRQ source entries */ -int mp_irq_entries; - -int nr_ioapics; - -int pic_mode; -unsigned long mp_lapic_addr; - -unsigned int def_to_bigsmp = 0; - -/* Processor that is doing the boot up */ -unsigned int boot_cpu_physical_apicid = -1U; -/* Internal processor count */ -static unsigned int __devinitdata num_processors; - -/* Bitmask of physically existing CPUs */ -physid_mask_t phys_cpu_present_map; - -u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; - -/* - * Intel MP BIOS table parsing routines: - */ - - -/* - * Checksum an MP configuration block. - */ - -static int __init mpf_checksum(unsigned char *mp, int len) -{ - int sum = 0; - - while (len--) - sum += *mp++; - - return sum & 0xFF; -} - -/* - * Have to match translation table entries to main table entries by counter - * hence the mpc_record variable .... can't see a less disgusting way of - * doing this .... - */ - -static int mpc_record; -static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; - -#ifndef CONFIG_XEN -static void __devinit MP_processor_info (struct mpc_config_processor *m) -{ - int ver, apicid; - physid_mask_t phys_cpu; - - if (!(m->mpc_cpuflag & CPU_ENABLED)) - return; - - apicid = mpc_apic_id(m, translation_table[mpc_record]); - - if (m->mpc_featureflag&(1<<0)) - Dprintk(" Floating point unit present.\n"); - if (m->mpc_featureflag&(1<<7)) - Dprintk(" Machine Exception supported.\n"); - if (m->mpc_featureflag&(1<<8)) - Dprintk(" 64 bit compare & exchange supported.\n"); - if (m->mpc_featureflag&(1<<9)) - Dprintk(" Internal APIC present.\n"); - if (m->mpc_featureflag&(1<<11)) - Dprintk(" SEP present.\n"); - if (m->mpc_featureflag&(1<<12)) - Dprintk(" MTRR present.\n"); - if (m->mpc_featureflag&(1<<13)) - Dprintk(" PGE present.\n"); - if (m->mpc_featureflag&(1<<14)) - Dprintk(" MCA present.\n"); - if (m->mpc_featureflag&(1<<15)) - Dprintk(" CMOV present.\n"); - if (m->mpc_featureflag&(1<<16)) - Dprintk(" PAT present.\n"); - if (m->mpc_featureflag&(1<<17)) - Dprintk(" PSE present.\n"); - if (m->mpc_featureflag&(1<<18)) - Dprintk(" PSN present.\n"); - if (m->mpc_featureflag&(1<<19)) - Dprintk(" Cache Line Flush Instruction present.\n"); - /* 20 Reserved */ - if (m->mpc_featureflag&(1<<21)) - Dprintk(" Debug Trace and EMON Store present.\n"); - if (m->mpc_featureflag&(1<<22)) - Dprintk(" ACPI Thermal Throttle Registers present.\n"); - if (m->mpc_featureflag&(1<<23)) - Dprintk(" MMX present.\n"); - if (m->mpc_featureflag&(1<<24)) - Dprintk(" FXSR present.\n"); - if (m->mpc_featureflag&(1<<25)) - Dprintk(" XMM present.\n"); - if (m->mpc_featureflag&(1<<26)) - Dprintk(" Willamette New Instructions present.\n"); - if (m->mpc_featureflag&(1<<27)) - Dprintk(" Self Snoop present.\n"); - if (m->mpc_featureflag&(1<<28)) - Dprintk(" HT present.\n"); - if (m->mpc_featureflag&(1<<29)) - Dprintk(" Thermal Monitor present.\n"); - /* 30, 31 Reserved */ - - - if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { - Dprintk(" Bootup CPU\n"); - boot_cpu_physical_apicid = m->mpc_apicid; - } - - ver = m->mpc_apicver; - - /* - * Validate version - */ - if (ver == 0x0) { - printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! " - "fixing up to 0x10. (tell your hw vendor)\n", - m->mpc_apicid); - ver = 0x10; - } - apic_version[m->mpc_apicid] = ver; - - phys_cpu = apicid_to_cpu_present(apicid); - physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu); - - if (num_processors >= NR_CPUS) { - printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." - " Processor ignored.\n", NR_CPUS); - return; - } - - if (num_processors >= maxcpus) { - printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." - " Processor ignored.\n", maxcpus); - return; - } - - cpu_set(num_processors, cpu_possible_map); - num_processors++; - - /* - * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y - * but we need to work other dependencies like SMP_SUSPEND etc - * before this can be done without some confusion. - * if (CPU_HOTPLUG_ENABLED || num_processors > 8) - * - Ashok Raj - */ - if (num_processors > 8) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_INTEL: - if (!APIC_XAPIC(ver)) { - def_to_bigsmp = 0; - break; - } - /* If P4 and above fall through */ - case X86_VENDOR_AMD: - def_to_bigsmp = 1; - } - } - bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; -} -#else -void __init MP_processor_info (struct mpc_config_processor *m) -{ - num_processors++; -} -#endif /* CONFIG_XEN */ - -static void __init MP_bus_info (struct mpc_config_bus *m) -{ - char str[7]; - - memcpy(str, m->mpc_bustype, 6); - str[6] = 0; - - mpc_oem_bus_info(m, str, translation_table[mpc_record]); - - if (m->mpc_busid >= MAX_MP_BUSSES) { - printk(KERN_WARNING "MP table busid value (%d) for bustype %s " - " is too large, max. supported is %d\n", - m->mpc_busid, str, MAX_MP_BUSSES - 1); - return; - } - - if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { - mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; - } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { - mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; - } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) { - mpc_oem_pci_bus(m, translation_table[mpc_record]); - mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; - mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; - mp_current_pci_id++; - } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) { - mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; - } else if (strncmp(str, BUSTYPE_NEC98, sizeof(BUSTYPE_NEC98)-1) == 0) { - mp_bus_id_to_type[m->mpc_busid] = MP_BUS_NEC98; - } else { - printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); - } -} - -static void __init MP_ioapic_info (struct mpc_config_ioapic *m) -{ - if (!(m->mpc_flags & MPC_APIC_USABLE)) - return; - - printk(KERN_INFO "I/O APIC #%d Version %d at 0x%lX.\n", - m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n", - MAX_IO_APICS, nr_ioapics); - panic("Recompile kernel with bigger MAX_IO_APICS!.\n"); - } - if (!m->mpc_apicaddr) { - printk(KERN_ERR "WARNING: bogus zero I/O APIC address" - " found in MP table, skipping!\n"); - return; - } - mp_ioapics[nr_ioapics] = *m; - nr_ioapics++; -} - -static void __init MP_intsrc_info (struct mpc_config_intsrc *m) -{ - mp_irqs [mp_irq_entries] = *m; - Dprintk("Int: type %d, pol %d, trig %d, bus %d," - " IRQ %02x, APIC ID %x, APIC INT %02x\n", - m->mpc_irqtype, m->mpc_irqflag & 3, - (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus, - m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq); - if (++mp_irq_entries == MAX_IRQ_SOURCES) - panic("Max # of irq sources exceeded!!\n"); -} - -static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) -{ - Dprintk("Lint: type %d, pol %d, trig %d, bus %d," - " IRQ %02x, APIC ID %x, APIC LINT %02x\n", - m->mpc_irqtype, m->mpc_irqflag & 3, - (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, - m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); - /* - * Well it seems all SMP boards in existence - * use ExtINT/LVT1 == LINT0 and - * NMI/LVT2 == LINT1 - the following check - * will show us if this assumptions is false. - * Until then we do not have to add baggage. - */ - if ((m->mpc_irqtype == mp_ExtINT) && - (m->mpc_destapiclint != 0)) - BUG(); - if ((m->mpc_irqtype == mp_NMI) && - (m->mpc_destapiclint != 1)) - BUG(); -} - -#ifdef CONFIG_X86_NUMAQ -static void __init MP_translation_info (struct mpc_config_translation *m) -{ - printk(KERN_INFO "Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local); - - if (mpc_record >= MAX_MPC_ENTRY) - printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n"); - else - translation_table[mpc_record] = m; /* stash this for later */ - if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad)) - node_set_online(m->trans_quad); -} - -/* - * Read/parse the MPC oem tables - */ - -static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \ - unsigned short oemsize) -{ - int count = sizeof (*oemtable); /* the header size */ - unsigned char *oemptr = ((unsigned char *)oemtable)+count; - - mpc_record = 0; - printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n", oemtable); - if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4)) - { - printk(KERN_WARNING "SMP mpc oemtable: bad signature [%c%c%c%c]!\n", - oemtable->oem_signature[0], - oemtable->oem_signature[1], - oemtable->oem_signature[2], - oemtable->oem_signature[3]); - return; - } - if (mpf_checksum((unsigned char *)oemtable,oemtable->oem_length)) - { - printk(KERN_WARNING "SMP oem mptable: checksum error!\n"); - return; - } - while (count < oemtable->oem_length) { - switch (*oemptr) { - case MP_TRANSLATION: - { - struct mpc_config_translation *m= - (struct mpc_config_translation *)oemptr; - MP_translation_info(m); - oemptr += sizeof(*m); - count += sizeof(*m); - ++mpc_record; - break; - } - default: - { - printk(KERN_WARNING "Unrecognised OEM table entry type! - %d\n", (int) *oemptr); - return; - } - } - } -} - -static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, - char *productid) -{ - if (strncmp(oem, "IBM NUMA", 8)) - printk("Warning! May not be a NUMA-Q system!\n"); - if (mpc->mpc_oemptr) - smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, - mpc->mpc_oemsize); -} -#endif /* CONFIG_X86_NUMAQ */ - -/* - * Read/parse the MPC - */ - -static int __init smp_read_mpc(struct mp_config_table *mpc) -{ - char str[16]; - char oem[10]; - int count=sizeof(*mpc); - unsigned char *mpt=((unsigned char *)mpc)+count; - - if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { - printk(KERN_ERR "SMP mptable: bad signature [0x%x]!\n", - *(u32 *)mpc->mpc_signature); - return 0; - } - if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { - printk(KERN_ERR "SMP mptable: checksum error!\n"); - return 0; - } - if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { - printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n", - mpc->mpc_spec); - return 0; - } - if (!mpc->mpc_lapic) { - printk(KERN_ERR "SMP mptable: null local APIC address!\n"); - return 0; - } - memcpy(oem,mpc->mpc_oem,8); - oem[8]=0; - printk(KERN_INFO "OEM ID: %s ",oem); - - memcpy(str,mpc->mpc_productid,12); - str[12]=0; - printk("Product ID: %s ",str); - - mps_oem_check(mpc, oem, str); - - printk("APIC at: 0x%lX\n",mpc->mpc_lapic); - - /* - * Save the local APIC address (it might be non-default) -- but only - * if we're not using ACPI. - */ - if (!acpi_lapic) - mp_lapic_addr = mpc->mpc_lapic; - - /* - * Now process the configuration blocks. - */ - mpc_record = 0; - while (count < mpc->mpc_length) { - switch(*mpt) { - case MP_PROCESSOR: - { - struct mpc_config_processor *m= - (struct mpc_config_processor *)mpt; - /* ACPI may have already provided this data */ - if (!acpi_lapic) - MP_processor_info(m); - mpt += sizeof(*m); - count += sizeof(*m); - break; - } - case MP_BUS: - { - struct mpc_config_bus *m= - (struct mpc_config_bus *)mpt; - MP_bus_info(m); - mpt += sizeof(*m); - count += sizeof(*m); - break; - } - case MP_IOAPIC: - { - struct mpc_config_ioapic *m= - (struct mpc_config_ioapic *)mpt; - MP_ioapic_info(m); - mpt+=sizeof(*m); - count+=sizeof(*m); - break; - } - case MP_INTSRC: - { - struct mpc_config_intsrc *m= - (struct mpc_config_intsrc *)mpt; - - MP_intsrc_info(m); - mpt+=sizeof(*m); - count+=sizeof(*m); - break; - } - case MP_LINTSRC: - { - struct mpc_config_lintsrc *m= - (struct mpc_config_lintsrc *)mpt; - MP_lintsrc_info(m); - mpt+=sizeof(*m); - count+=sizeof(*m); - break; - } - default: - { - count = mpc->mpc_length; - break; - } - } - ++mpc_record; - } - clustered_apic_check(); - if (!num_processors) - printk(KERN_ERR "SMP mptable: no processors registered!\n"); - return num_processors; -} - -static int __init ELCR_trigger(unsigned int irq) -{ - unsigned int port; - - port = 0x4d0 + (irq >> 3); - return (inb(port) >> (irq & 7)) & 1; -} - -static void __init construct_default_ioirq_mptable(int mpc_default_type) -{ - struct mpc_config_intsrc intsrc; - int i; - int ELCR_fallback = 0; - - intsrc.mpc_type = MP_INTSRC; - intsrc.mpc_irqflag = 0; /* conforming */ - intsrc.mpc_srcbus = 0; - intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid; - - intsrc.mpc_irqtype = mp_INT; - - /* - * If true, we have an ISA/PCI system with no IRQ entries - * in the MP table. To prevent the PCI interrupts from being set up - * incorrectly, we try to use the ELCR. The sanity check to see if - * there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can - * never be level sensitive, so we simply see if the ELCR agrees. - * If it does, we assume it's valid. - */ - if (mpc_default_type == 5) { - printk(KERN_INFO "ISA/PCI bus type with no IRQ information... falling back to ELCR\n"); - - if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13)) - printk(KERN_WARNING "ELCR contains invalid data... not using ELCR\n"); - else { - printk(KERN_INFO "Using ELCR to identify PCI interrupts\n"); - ELCR_fallback = 1; - } - } - - for (i = 0; i < 16; i++) { - switch (mpc_default_type) { - case 2: - if (i == 0 || i == 13) - continue; /* IRQ0 & IRQ13 not connected */ - /* fall through */ - default: - if (i == 2) - continue; /* IRQ2 is never connected */ - } - - if (ELCR_fallback) { - /* - * If the ELCR indicates a level-sensitive interrupt, we - * copy that information over to the MP table in the - * irqflag field (level sensitive, active high polarity). - */ - if (ELCR_trigger(i)) - intsrc.mpc_irqflag = 13; - else - intsrc.mpc_irqflag = 0; - } - - intsrc.mpc_srcbusirq = i; - intsrc.mpc_dstirq = i ? i : 2; /* IRQ0 to INTIN2 */ - MP_intsrc_info(&intsrc); - } - - intsrc.mpc_irqtype = mp_ExtINT; - intsrc.mpc_srcbusirq = 0; - intsrc.mpc_dstirq = 0; /* 8259A to INTIN0 */ - MP_intsrc_info(&intsrc); -} - -static inline void __init construct_default_ISA_mptable(int mpc_default_type) -{ - struct mpc_config_processor processor; - struct mpc_config_bus bus; - struct mpc_config_ioapic ioapic; - struct mpc_config_lintsrc lintsrc; - int linttypes[2] = { mp_ExtINT, mp_NMI }; - int i; - - /* - * local APIC has default address - */ - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; - - /* - * 2 CPUs, numbered 0 & 1. - */ - processor.mpc_type = MP_PROCESSOR; - /* Either an integrated APIC or a discrete 82489DX. */ - processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; - processor.mpc_cpuflag = CPU_ENABLED; - processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | - (boot_cpu_data.x86_model << 4) | - boot_cpu_data.x86_mask; - processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; - processor.mpc_reserved[0] = 0; - processor.mpc_reserved[1] = 0; - for (i = 0; i < 2; i++) { - processor.mpc_apicid = i; - MP_processor_info(&processor); - } - - bus.mpc_type = MP_BUS; - bus.mpc_busid = 0; - switch (mpc_default_type) { - default: - printk("???\n"); - printk(KERN_ERR "Unknown standard configuration %d\n", - mpc_default_type); - /* fall through */ - case 1: - case 5: - memcpy(bus.mpc_bustype, "ISA ", 6); - break; - case 2: - case 6: - case 3: - memcpy(bus.mpc_bustype, "EISA ", 6); - break; - case 4: - case 7: - memcpy(bus.mpc_bustype, "MCA ", 6); - } - MP_bus_info(&bus); - if (mpc_default_type > 4) { - bus.mpc_busid = 1; - memcpy(bus.mpc_bustype, "PCI ", 6); - MP_bus_info(&bus); - } - - ioapic.mpc_type = MP_IOAPIC; - ioapic.mpc_apicid = 2; - ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; - ioapic.mpc_flags = MPC_APIC_USABLE; - ioapic.mpc_apicaddr = 0xFEC00000; - MP_ioapic_info(&ioapic); - - /* - * We set up most of the low 16 IO-APIC pins according to MPS rules. - */ - construct_default_ioirq_mptable(mpc_default_type); - - lintsrc.mpc_type = MP_LINTSRC; - lintsrc.mpc_irqflag = 0; /* conforming */ - lintsrc.mpc_srcbusid = 0; - lintsrc.mpc_srcbusirq = 0; - lintsrc.mpc_destapic = MP_APIC_ALL; - for (i = 0; i < 2; i++) { - lintsrc.mpc_irqtype = linttypes[i]; - lintsrc.mpc_destapiclint = i; - MP_lintsrc_info(&lintsrc); - } -} - -static struct intel_mp_floating *mpf_found; - -/* - * Scan the memory blocks for an SMP configuration block. - */ -void __init get_smp_config (void) -{ - struct intel_mp_floating *mpf = mpf_found; - - /* - * ACPI supports both logical (e.g. Hyper-Threading) and physical - * processors, where MPS only supports physical. - */ - if (acpi_lapic && acpi_ioapic) { - printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n"); - return; - } - else if (acpi_lapic) - printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); - - printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); - if (mpf->mpf_feature2 & (1<<7)) { - printk(KERN_INFO " IMCR and PIC compatibility mode.\n"); - pic_mode = 1; - } else { - printk(KERN_INFO " Virtual Wire compatibility mode.\n"); - pic_mode = 0; - } - - /* - * Now see if we need to read further. - */ - if (mpf->mpf_feature1 != 0) { - - printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1); - construct_default_ISA_mptable(mpf->mpf_feature1); - - } else if (mpf->mpf_physptr) { - - /* - * Read the physical hardware table. Anything here will - * override the defaults. - */ - if (!smp_read_mpc(isa_bus_to_virt(mpf->mpf_physptr))) { - smp_found_config = 0; - printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"); - printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n"); - return; - } - /* - * If there are no explicit MP IRQ entries, then we are - * broken. We set up most of the low 16 IO-APIC pins to - * ISA defaults and hope it will work. - */ - if (!mp_irq_entries) { - struct mpc_config_bus bus; - - printk(KERN_ERR "BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n"); - - bus.mpc_type = MP_BUS; - bus.mpc_busid = 0; - memcpy(bus.mpc_bustype, "ISA ", 6); - MP_bus_info(&bus); - - construct_default_ioirq_mptable(0); - } - - } else - BUG(); - - printk(KERN_INFO "Processors: %d\n", num_processors); - /* - * Only use the first configuration found. - */ -} - -static int __init smp_scan_config (unsigned long base, unsigned long length) -{ - unsigned long *bp = isa_bus_to_virt(base); - struct intel_mp_floating *mpf; - - Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length); - if (sizeof(*mpf) != 16) - printk("Error: MPF size\n"); - - while (length > 0) { - mpf = (struct intel_mp_floating *)bp; - if ((*bp == SMP_MAGIC_IDENT) && - (mpf->mpf_length == 1) && - !mpf_checksum((unsigned char *)bp, 16) && - ((mpf->mpf_specification == 1) - || (mpf->mpf_specification == 4)) ) { - - smp_found_config = 1; -#ifndef CONFIG_XEN - printk(KERN_INFO "found SMP MP-table at %08lx\n", - virt_to_phys(mpf)); - reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE); - if (mpf->mpf_physptr) { - /* - * We cannot access to MPC table to compute - * table size yet, as only few megabytes from - * the bottom is mapped now. - * PC-9800's MPC table places on the very last - * of physical memory; so that simply reserving - * PAGE_SIZE from mpg->mpf_physptr yields BUG() - * in reserve_bootmem. - */ - unsigned long size = PAGE_SIZE; - unsigned long end = max_low_pfn * PAGE_SIZE; - if (mpf->mpf_physptr + size > end) - size = end - mpf->mpf_physptr; - reserve_bootmem(mpf->mpf_physptr, size); - } -#else - printk(KERN_INFO "found SMP MP-table at %08lx\n", - ((unsigned long)bp - (unsigned long)isa_bus_to_virt(base)) + base); -#endif - - mpf_found = mpf; - return 1; - } - bp += 4; - length -= 16; - } - return 0; -} - -void __init find_smp_config (void) -{ -#ifndef CONFIG_XEN - unsigned int address; -#endif - - /* - * FIXME: Linux assumes you have 640K of base ram.. - * this continues the error... - * - * 1) Scan the bottom 1K for a signature - * 2) Scan the top 1K of base RAM - * 3) Scan the 64K of bios - */ - if (smp_scan_config(0x0,0x400) || - smp_scan_config(639*0x400,0x400) || - smp_scan_config(0xF0000,0x10000)) - return; - /* - * If it is an SMP machine we should know now, unless the - * configuration is in an EISA/MCA bus machine with an - * extended bios data area. - * - * there is a real-mode segmented pointer pointing to the - * 4K EBDA area at 0x40E, calculate and scan it here. - * - * NOTE! There are Linux loaders that will corrupt the EBDA - * area, and as such this kind of SMP config may be less - * trustworthy, simply because the SMP table may have been - * stomped on during early boot. These loaders are buggy and - * should be fixed. - * - * MP1.4 SPEC states to only scan first 1K of 4K EBDA. - */ - -#ifndef CONFIG_XEN - address = get_bios_ebda(); - if (address) - smp_scan_config(address, 0x400); -#endif -} - -int es7000_plat; - -/* -------------------------------------------------------------------------- - ACPI-based MP Configuration - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI - -void __init mp_register_lapic_address ( - u64 address) -{ -#ifndef CONFIG_XEN - mp_lapic_addr = (unsigned long) address; - - set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); - - if (boot_cpu_physical_apicid == -1U) - boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); - - Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); -#endif -} - - -void __devinit mp_register_lapic ( - u8 id, - u8 enabled) -{ - struct mpc_config_processor processor; - int boot_cpu = 0; - - if (MAX_APICS - id <= 0) { - printk(KERN_WARNING "Processor #%d invalid (max %d)\n", - id, MAX_APICS); - return; - } - - if (id == boot_cpu_physical_apicid) - boot_cpu = 1; - -#ifndef CONFIG_XEN - processor.mpc_type = MP_PROCESSOR; - processor.mpc_apicid = id; - processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR)); - processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0); - processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0); - processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | - (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; - processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; - processor.mpc_reserved[0] = 0; - processor.mpc_reserved[1] = 0; -#endif - - MP_processor_info(&processor); -} - -#ifdef CONFIG_X86_IO_APIC - -#define MP_ISA_BUS 0 -#define MP_MAX_IOAPIC_PIN 127 - -static struct mp_ioapic_routing { - int apic_id; - int gsi_base; - int gsi_end; - u32 pin_programmed[4]; -} mp_ioapic_routing[MAX_IO_APICS]; - - -static int mp_find_ioapic ( - int gsi) -{ - int i = 0; - - /* Find the IOAPIC that manages this GSI. */ - for (i = 0; i < nr_ioapics; i++) { - if ((gsi >= mp_ioapic_routing[i].gsi_base) - && (gsi <= mp_ioapic_routing[i].gsi_end)) - return i; - } - - printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); - - return -1; -} - - -void __init mp_register_ioapic ( - u8 id, - u32 address, - u32 gsi_base) -{ - int idx = 0; - int tmpid; - - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " - "(found %d)\n", MAX_IO_APICS, nr_ioapics); - panic("Recompile kernel with bigger MAX_IO_APICS!\n"); - } - if (!address) { - printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" - " found in MADT table, skipping!\n"); - return; - } - - idx = nr_ioapics++; - - mp_ioapics[idx].mpc_type = MP_IOAPIC; - mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE; - mp_ioapics[idx].mpc_apicaddr = address; - -#ifndef CONFIG_XEN - set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); -#endif - if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) - tmpid = io_apic_get_unique_id(idx, id); - else - tmpid = id; - if (tmpid == -1) { - nr_ioapics--; - return; - } - mp_ioapics[idx].mpc_apicid = tmpid; - mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); - - /* - * Build basic GSI lookup table to facilitate gsi->io_apic lookups - * and to prevent reprogramming of IOAPIC pins (PCI GSIs). - */ - mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid; - mp_ioapic_routing[idx].gsi_base = gsi_base; - mp_ioapic_routing[idx].gsi_end = gsi_base + - io_apic_get_redir_entries(idx); - - printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " - "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, - mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, - mp_ioapic_routing[idx].gsi_base, - mp_ioapic_routing[idx].gsi_end); - - return; -} - - -void __init mp_override_legacy_irq ( - u8 bus_irq, - u8 polarity, - u8 trigger, - u32 gsi) -{ - struct mpc_config_intsrc intsrc; - int ioapic = -1; - int pin = -1; - - /* - * Convert 'gsi' to 'ioapic.pin'. - */ - ioapic = mp_find_ioapic(gsi); - if (ioapic < 0) - return; - pin = gsi - mp_ioapic_routing[ioapic].gsi_base; - - /* - * TBD: This check is for faulty timer entries, where the override - * erroneously sets the trigger to level, resulting in a HUGE - * increase of timer interrupts! - */ - if ((bus_irq == 0) && (trigger == 3)) - trigger = 1; - - intsrc.mpc_type = MP_INTSRC; - intsrc.mpc_irqtype = mp_INT; - intsrc.mpc_irqflag = (trigger << 2) | polarity; - intsrc.mpc_srcbus = MP_ISA_BUS; - intsrc.mpc_srcbusirq = bus_irq; /* IRQ */ - intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; /* APIC ID */ - intsrc.mpc_dstirq = pin; /* INTIN# */ - - Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", - intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, - (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, - intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq); - - mp_irqs[mp_irq_entries] = intsrc; - if (++mp_irq_entries == MAX_IRQ_SOURCES) - panic("Max # of irq sources exceeded!\n"); - - return; -} - -void __init mp_config_acpi_legacy_irqs (void) -{ - struct mpc_config_intsrc intsrc; - int i = 0; - int ioapic = -1; - - /* - * Fabricate the legacy ISA bus (bus #31). - */ - mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; - Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); - - /* - * Older generations of ES7000 have no legacy identity mappings - */ - if (es7000_plat == 1) - return; - - /* - * Locate the IOAPIC that manages the ISA IRQs (0-15). - */ - ioapic = mp_find_ioapic(0); - if (ioapic < 0) - return; - - intsrc.mpc_type = MP_INTSRC; - intsrc.mpc_irqflag = 0; /* Conforming */ - intsrc.mpc_srcbus = MP_ISA_BUS; - intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; - - /* - * Use the default configuration for the IRQs 0-15. Unless - * overriden by (MADT) interrupt source override entries. - */ - for (i = 0; i < 16; i++) { - int idx; - - for (idx = 0; idx < mp_irq_entries; idx++) { - struct mpc_config_intsrc *irq = mp_irqs + idx; - - /* Do we already have a mapping for this ISA IRQ? */ - if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i) - break; - - /* Do we already have a mapping for this IOAPIC pin */ - if ((irq->mpc_dstapic == intsrc.mpc_dstapic) && - (irq->mpc_dstirq == i)) - break; - } - - if (idx != mp_irq_entries) { - printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i); - continue; /* IRQ already used */ - } - - intsrc.mpc_irqtype = mp_INT; - intsrc.mpc_srcbusirq = i; /* Identity mapped */ - intsrc.mpc_dstirq = i; - - Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, " - "%d-%d\n", intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, - (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, - intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, - intsrc.mpc_dstirq); - - mp_irqs[mp_irq_entries] = intsrc; - if (++mp_irq_entries == MAX_IRQ_SOURCES) - panic("Max # of irq sources exceeded!\n"); - } -} - -#define MAX_GSI_NUM 4096 - -int mp_register_gsi (u32 gsi, int triggering, int polarity) -{ - int ioapic = -1; - int ioapic_pin = 0; - int idx, bit = 0; - static int pci_irq = 16; - /* - * Mapping between Global System Interrups, which - * represent all possible interrupts, and IRQs - * assigned to actual devices. - */ - static int gsi_to_irq[MAX_GSI_NUM]; - - /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_fadt.sci_int == gsi) - return gsi; - - ioapic = mp_find_ioapic(gsi); - if (ioapic < 0) { - printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); - return gsi; - } - - ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; - - if (ioapic_renumber_irq) - gsi = ioapic_renumber_irq(ioapic, gsi); - - /* - * Avoid pin reprogramming. PRTs typically include entries - * with redundant pin->gsi mappings (but unique PCI devices); - * we only program the IOAPIC on the first. - */ - bit = ioapic_pin % 32; - idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); - if (idx > 3) { - printk(KERN_ERR "Invalid reference to IOAPIC pin " - "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, - ioapic_pin); - return gsi; - } - if ((1< 15), but - * avoid a problem where the 8254 timer (IRQ0) is setup - * via an override (so it's not on pin 0 of the ioapic), - * and at the same time, the pin 0 interrupt is a PCI - * type. The gsi > 15 test could cause these two pins - * to be shared as IRQ0, and they are not shareable. - * So test for this condition, and if necessary, avoid - * the pin collision. - */ - if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0)) - gsi = pci_irq++; - /* - * Don't assign IRQ used by ACPI SCI - */ - if (gsi == acpi_fadt.sci_int) - gsi = pci_irq++; - gsi_to_irq[irq] = gsi; - } else { - printk(KERN_ERR "GSI %u is too high\n", gsi); - return gsi; - } - } - - io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, - triggering == ACPI_EDGE_SENSITIVE ? 0 : 1, - polarity == ACPI_ACTIVE_HIGH ? 0 : 1); - return gsi; -} - -#endif /* CONFIG_X86_IO_APIC */ -#endif /* CONFIG_ACPI */ diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 6b1392d33..e6e2f43db 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -38,6 +38,12 @@ int smp_found_config; unsigned int __initdata maxcpus = NR_CPUS; +#ifdef CONFIG_HOTPLUG_CPU +#define CPU_HOTPLUG_ENABLED (1) +#else +#define CPU_HOTPLUG_ENABLED (0) +#endif + /* * Various Linux-internal data structures created from the * MP-table. @@ -104,6 +110,21 @@ static int __init mpf_checksum(unsigned char *mp, int len) static int mpc_record; static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; +#ifdef CONFIG_X86_NUMAQ +static int MP_valid_apicid(int apicid, int version) +{ + return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf; +} +#else +static int MP_valid_apicid(int apicid, int version) +{ + if (version >= 0x14) + return apicid < 0xff; + else + return apicid < 0xf; +} +#endif + static void __devinit MP_processor_info (struct mpc_config_processor *m) { int ver, apicid; @@ -169,6 +190,12 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m) ver = m->mpc_apicver; + if (!MP_valid_apicid(apicid, ver)) { + printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", + m->mpc_apicid, MAX_APICS); + return; + } + /* * Validate version */ @@ -198,14 +225,7 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m) cpu_set(num_processors, cpu_possible_map); num_processors++; - /* - * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y - * but we need to work other dependencies like SMP_SUSPEND etc - * before this can be done without some confusion. - * if (CPU_HOTPLUG_ENABLED || num_processors > 8) - * - Ashok Raj - */ - if (num_processors > 8) { + if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) { switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_INTEL: if (!APIC_XAPIC(ver)) { @@ -229,13 +249,6 @@ static void __init MP_bus_info (struct mpc_config_bus *m) mpc_oem_bus_info(m, str, translation_table[mpc_record]); - if (m->mpc_busid >= MAX_MP_BUSSES) { - printk(KERN_WARNING "MP table busid value (%d) for bustype %s " - " is too large, max. supported is %d\n", - m->mpc_busid, str, MAX_MP_BUSSES - 1); - return; - } - if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { @@ -815,8 +828,6 @@ void __init find_smp_config (void) smp_scan_config(address, 0x400); } -int es7000_plat; - /* -------------------------------------------------------------------------- ACPI-based MP Configuration -------------------------------------------------------------------------- */ @@ -924,8 +935,7 @@ void __init mp_register_ioapic ( mp_ioapics[idx].mpc_apicaddr = address; set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); - if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) + if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15)) tmpid = io_apic_get_unique_id(idx, id); else tmpid = id; @@ -1001,6 +1011,8 @@ void __init mp_override_legacy_irq ( return; } +int es7000_plat; + void __init mp_config_acpi_legacy_irqs (void) { struct mpc_config_intsrc intsrc; @@ -1130,17 +1142,7 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity) */ int irq = gsi; if (gsi < MAX_GSI_NUM) { - /* - * Retain the VIA chipset work-around (gsi > 15), but - * avoid a problem where the 8254 timer (IRQ0) is setup - * via an override (so it's not on pin 0 of the ioapic), - * and at the same time, the pin 0 interrupt is a PCI - * type. The gsi > 15 test could cause these two pins - * to be shared as IRQ0, and they are not shareable. - * So test for this condition, and if necessary, avoid - * the pin collision. - */ - if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0)) + if (gsi > 15) gsi = pci_irq++; /* * Don't assign IRQ used by ACPI SCI diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 7a328230e..1d0a55e68 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -251,7 +251,7 @@ static int msr_class_device_create(int i) return err; } -static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) +static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index d43b498ec..be87c5e2e 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -138,12 +138,12 @@ static int __init check_nmi_watchdog(void) if (nmi_watchdog == NMI_LOCAL_APIC) smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); - for_each_possible_cpu(cpu) + for_each_cpu(cpu) prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; local_irq_enable(); mdelay((10*1000)/nmi_hz); // wait 10 ticks - for_each_possible_cpu(cpu) { + for (cpu = 0; cpu < NR_CPUS; cpu++) { #ifdef CONFIG_SMP /* Check cpu_callin_map here because that is set after the timer is started. */ @@ -510,7 +510,7 @@ void touch_nmi_watchdog (void) * Just reset the alert counters, (other CPUs might be * spinning on locks we hold): */ - for_each_possible_cpu(i) + for (i = 0; i < NR_CPUS; i++) alert_counter[i] = 0; /* @@ -529,8 +529,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) * always switch the stack NMI-atomically, it's safe to use * smp_processor_id(). */ - unsigned int sum; - int cpu = smp_processor_id(); + int sum, cpu = smp_processor_id(); sum = per_cpu(irq_stat, cpu).apic_timer_irqs; @@ -544,7 +543,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) /* * die_nmi will return ONLY if NOTIFY_STOP happens.. */ - die_nmi(regs, "BUG: NMI Watchdog detected LOCKUP"); + die_nmi(regs, "NMI Watchdog detected LOCKUP"); } else { last_irq_sums[cpu] = sum; alert_counter[cpu] = 0; diff --git a/arch/i386/kernel/pci-dma-xen.c b/arch/i386/kernel/pci-dma-xen.c deleted file mode 100644 index 5c32dd0c3..000000000 --- a/arch/i386/kernel/pci-dma-xen.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Dynamic DMA mapping support. - * - * On i386 there is no hardware dynamic DMA address translation, - * so consistent alloc/free are merely page allocation/freeing. - * The rest of the dynamic DMA mapping interface is implemented - * in asm/pci.h. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __x86_64__ -int iommu_merge __read_mostly = 0; -EXPORT_SYMBOL(iommu_merge); - -dma_addr_t bad_dma_address __read_mostly; -EXPORT_SYMBOL(bad_dma_address); - -/* This tells the BIO block layer to assume merging. Default to off - because we cannot guarantee merging later. */ -int iommu_bio_merge __read_mostly = 0; -EXPORT_SYMBOL(iommu_bio_merge); - -__init int iommu_setup(char *p) -{ - return 1; -} -#endif - -struct dma_coherent_mem { - void *virt_base; - u32 device_base; - int size; - int flags; - unsigned long *bitmap; -}; - -#define IOMMU_BUG_ON(test) \ -do { \ - if (unlikely(test)) { \ - printk(KERN_ALERT "Fatal DMA error! " \ - "Please use 'swiotlb=force'\n"); \ - BUG(); \ - } \ -} while (0) - -int -dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) -{ - int i, rc; - - if (direction == DMA_NONE) - BUG(); - WARN_ON(nents == 0 || sg[0].length == 0); - - if (swiotlb) { - rc = swiotlb_map_sg(hwdev, sg, nents, direction); - } else { - for (i = 0; i < nents; i++ ) { - sg[i].dma_address = - page_to_bus(sg[i].page) + sg[i].offset; - sg[i].dma_length = sg[i].length; - BUG_ON(!sg[i].page); - IOMMU_BUG_ON(address_needs_mapping( - hwdev, sg[i].dma_address)); - } - rc = nents; - } - - flush_write_buffers(); - return rc; -} -EXPORT_SYMBOL(dma_map_sg); - -void -dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) -{ - BUG_ON(direction == DMA_NONE); - if (swiotlb) - swiotlb_unmap_sg(hwdev, sg, nents, direction); -} -EXPORT_SYMBOL(dma_unmap_sg); - -/* - * XXX This file is also used by xenLinux/ia64. - * "defined(__i386__) || defined (__x86_64__)" means "!defined(__ia64__)". - * This #if work around should be removed once this file is merbed back into - * i386' pci-dma or is moved to drivers/xen/core. - */ -#if defined(__i386__) || defined(__x86_64__) -dma_addr_t -dma_map_page(struct device *dev, struct page *page, unsigned long offset, - size_t size, enum dma_data_direction direction) -{ - dma_addr_t dma_addr; - - BUG_ON(direction == DMA_NONE); - - if (swiotlb) { - dma_addr = swiotlb_map_page( - dev, page, offset, size, direction); - } else { - dma_addr = page_to_bus(page) + offset; - IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr)); - } - - return dma_addr; -} -EXPORT_SYMBOL(dma_map_page); - -void -dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(direction == DMA_NONE); - if (swiotlb) - swiotlb_unmap_page(dev, dma_address, size, direction); -} -EXPORT_SYMBOL(dma_unmap_page); -#endif /* defined(__i386__) || defined(__x86_64__) */ - -int -dma_mapping_error(dma_addr_t dma_addr) -{ - if (swiotlb) - return swiotlb_dma_mapping_error(dma_addr); - return 0; -} -EXPORT_SYMBOL(dma_mapping_error); - -int -dma_supported(struct device *dev, u64 mask) -{ - if (swiotlb) - return swiotlb_dma_supported(dev, mask); - /* - * By default we'll BUG when an infeasible DMA is requested, and - * request swiotlb=force (see IOMMU_BUG_ON). - */ - return 1; -} -EXPORT_SYMBOL(dma_supported); - -void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) -{ - void *ret; - struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; - unsigned int order = get_order(size); - unsigned long vstart; - /* ignore region specifiers */ - gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); - - if (mem) { - int page = bitmap_find_free_region(mem->bitmap, mem->size, - order); - if (page >= 0) { - *dma_handle = mem->device_base + (page << PAGE_SHIFT); - ret = mem->virt_base + (page << PAGE_SHIFT); - memset(ret, 0, size); - return ret; - } - if (mem->flags & DMA_MEMORY_EXCLUSIVE) - return NULL; - } - - if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) - gfp |= GFP_DMA; - - vstart = __get_free_pages(gfp, order); - ret = (void *)vstart; - - if (ret != NULL) { - /* NB. Hardcode 31 address bits for now: aacraid limitation. */ - if (xen_create_contiguous_region(vstart, order, 31) != 0) { - free_pages(vstart, order); - return NULL; - } - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - } - return ret; -} -EXPORT_SYMBOL(dma_alloc_coherent); - -void dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; - int order = get_order(size); - - if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { - int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; - - bitmap_release_region(mem->bitmap, page, order); - } else { - xen_destroy_contiguous_region((unsigned long)vaddr, order); - free_pages((unsigned long)vaddr, order); - } -} -EXPORT_SYMBOL(dma_free_coherent); - -#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY -int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, - dma_addr_t device_addr, size_t size, int flags) -{ - void __iomem *mem_base; - int pages = size >> PAGE_SHIFT; - int bitmap_size = (pages + 31)/32; - - if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) - goto out; - if (!size) - goto out; - if (dev->dma_mem) - goto out; - - /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ - - mem_base = ioremap(bus_addr, size); - if (!mem_base) - goto out; - - dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); - if (!dev->dma_mem) - goto out; - memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem)); - dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL); - if (!dev->dma_mem->bitmap) - goto free1_out; - memset(dev->dma_mem->bitmap, 0, bitmap_size); - - dev->dma_mem->virt_base = mem_base; - dev->dma_mem->device_base = device_addr; - dev->dma_mem->size = pages; - dev->dma_mem->flags = flags; - - if (flags & DMA_MEMORY_MAP) - return DMA_MEMORY_MAP; - - return DMA_MEMORY_IO; - - free1_out: - kfree(dev->dma_mem->bitmap); - out: - return 0; -} -EXPORT_SYMBOL(dma_declare_coherent_memory); - -void dma_release_declared_memory(struct device *dev) -{ - struct dma_coherent_mem *mem = dev->dma_mem; - - if(!mem) - return; - dev->dma_mem = NULL; - iounmap(mem->virt_base); - kfree(mem->bitmap); - kfree(mem); -} -EXPORT_SYMBOL(dma_release_declared_memory); - -void *dma_mark_declared_memory_occupied(struct device *dev, - dma_addr_t device_addr, size_t size) -{ - struct dma_coherent_mem *mem = dev->dma_mem; - int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT; - int pos, err; - - if (!mem) - return ERR_PTR(-EINVAL); - - pos = (device_addr - mem->device_base) >> PAGE_SHIFT; - err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); - if (err != 0) - return ERR_PTR(err); - return mem->virt_base + (pos << PAGE_SHIFT); -} -EXPORT_SYMBOL(dma_mark_declared_memory_occupied); -#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */ - -dma_addr_t -dma_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction) -{ - dma_addr_t dma; - - if (direction == DMA_NONE) - BUG(); - WARN_ON(size == 0); - - if (swiotlb) { - dma = swiotlb_map_single(dev, ptr, size, direction); - } else { - dma = virt_to_bus(ptr); - IOMMU_BUG_ON(range_straddles_page_boundary(ptr, size)); - IOMMU_BUG_ON(address_needs_mapping(dev, dma)); - } - - flush_write_buffers(); - return dma; -} -EXPORT_SYMBOL(dma_map_single); - -void -dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) -{ - if (direction == DMA_NONE) - BUG(); - if (swiotlb) - swiotlb_unmap_single(dev, dma_addr, size, direction); -} -EXPORT_SYMBOL(dma_unmap_single); - -void -dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) -{ - if (swiotlb) - swiotlb_sync_single_for_cpu(dev, dma_handle, size, direction); -} -EXPORT_SYMBOL(dma_sync_single_for_cpu); - -void -dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) -{ - if (swiotlb) - swiotlb_sync_single_for_device(dev, dma_handle, size, direction); -} -EXPORT_SYMBOL(dma_sync_single_for_device); diff --git a/arch/i386/kernel/process-xen.c b/arch/i386/kernel/process-xen.c deleted file mode 100644 index 0c2fdcc19..000000000 --- a/arch/i386/kernel/process-xen.c +++ /dev/null @@ -1,870 +0,0 @@ -/* - * linux/arch/i386/kernel/process.c - * - * Copyright (C) 1995 Linus Torvalds - * - * Pentium III FXSR, SSE support - * Gareth Hughes , May 2000 - */ - -/* - * This file handles the architecture-dependent parts of process handling.. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_MATH_EMULATION -#include -#endif - -#include -#include -#include - -#include - -#include -#include - -#include -#include - -asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); - -static int hlt_counter; - -unsigned long boot_option_idle_override = 0; -EXPORT_SYMBOL(boot_option_idle_override); - -/* - * Return saved PC of a blocked thread. - */ -unsigned long thread_saved_pc(struct task_struct *tsk) -{ - return ((unsigned long *)tsk->thread.esp)[3]; -} - -/* - * Powermanagement idle function, if any.. - */ -void (*pm_idle)(void); -EXPORT_SYMBOL(pm_idle); -static DEFINE_PER_CPU(unsigned int, cpu_idle_state); - -void disable_hlt(void) -{ - hlt_counter++; -} - -EXPORT_SYMBOL(disable_hlt); - -void enable_hlt(void) -{ - hlt_counter--; -} - -EXPORT_SYMBOL(enable_hlt); - -/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */ -void xen_idle(void) -{ - local_irq_disable(); - - if (need_resched()) - local_irq_enable(); - else { - clear_thread_flag(TIF_POLLING_NRFLAG); - smp_mb__after_clear_bit(); - safe_halt(); - set_thread_flag(TIF_POLLING_NRFLAG); - } -} -#ifdef CONFIG_APM_MODULE -EXPORT_SYMBOL(default_idle); -#endif - -#ifdef CONFIG_HOTPLUG_CPU -extern cpumask_t cpu_initialized; -static inline void play_dead(void) -{ - idle_task_exit(); - local_irq_disable(); - cpu_clear(smp_processor_id(), cpu_initialized); - preempt_enable_no_resched(); - HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL); - cpu_bringup(); -} -#else -static inline void play_dead(void) -{ - BUG(); -} -#endif /* CONFIG_HOTPLUG_CPU */ - -/* - * The idle thread. There's no useful work to be - * done, so just try to conserve power and have a - * low exit latency (ie sit in a loop waiting for - * somebody to say that they'd like to reschedule) - */ -void cpu_idle(void) -{ - int cpu = smp_processor_id(); - - set_thread_flag(TIF_POLLING_NRFLAG); - - /* endless idle loop with no priority at all */ - while (1) { - while (!need_resched()) { - - if (__get_cpu_var(cpu_idle_state)) - __get_cpu_var(cpu_idle_state) = 0; - - rmb(); - - if (cpu_is_offline(cpu)) - play_dead(); - - __get_cpu_var(irq_stat).idle_timestamp = jiffies; - xen_idle(); - } - preempt_enable_no_resched(); - schedule(); - preempt_disable(); - } -} - -void cpu_idle_wait(void) -{ - unsigned int cpu, this_cpu = get_cpu(); - cpumask_t map; - - set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); - put_cpu(); - - cpus_clear(map); - for_each_online_cpu(cpu) { - per_cpu(cpu_idle_state, cpu) = 1; - cpu_set(cpu, map); - } - - __get_cpu_var(cpu_idle_state) = 0; - - wmb(); - do { - ssleep(1); - for_each_online_cpu(cpu) { - if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) - cpu_clear(cpu, map); - } - cpus_and(map, map, cpu_online_map); - } while (!cpus_empty(map)); -} -EXPORT_SYMBOL_GPL(cpu_idle_wait); - -/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */ -/* Always use xen_idle() instead. */ -void __devinit select_idle_routine(const struct cpuinfo_x86 *c) {} - -void show_regs(struct pt_regs * regs) -{ - unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; - - printk("\n"); - printk("Pid: %d, comm: %20s\n", current->pid, current->comm); - printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); - print_symbol("EIP is at %s\n", regs->eip); - - if (user_mode_vm(regs)) - printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); - printk(" EFLAGS: %08lx %s (%s %.*s)\n", - regs->eflags, print_tainted(), system_utsname.release, - (int)strcspn(system_utsname.version, " "), - system_utsname.version); - printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", - regs->eax,regs->ebx,regs->ecx,regs->edx); - printk("ESI: %08lx EDI: %08lx EBP: %08lx", - regs->esi, regs->edi, regs->ebp); - printk(" DS: %04x ES: %04x\n", - 0xffff & regs->xds,0xffff & regs->xes); - - cr0 = read_cr0(); - cr2 = read_cr2(); - cr3 = read_cr3(); - cr4 = read_cr4_safe(); - printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); - show_trace(NULL, ®s->esp); -} - -/* - * This gets run with %ebx containing the - * function to call, and %edx containing - * the "args". - */ -extern void kernel_thread_helper(void); -__asm__(".section .text\n" - ".align 4\n" - "kernel_thread_helper:\n\t" - "movl %edx,%eax\n\t" - "pushl %edx\n\t" - "call *%ebx\n\t" - "pushl %eax\n\t" - "call do_exit\n" - ".previous"); - -/* - * Create a kernel thread - */ -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.ebx = (unsigned long) fn; - regs.edx = (unsigned long) arg; - - regs.xds = __USER_DS; - regs.xes = __USER_DS; - regs.orig_eax = -1; - regs.eip = (unsigned long) kernel_thread_helper; - regs.xcs = GET_KERNEL_CS(); - regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; - - /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} -EXPORT_SYMBOL(kernel_thread); - -/* - * Free current thread data structures etc.. - */ -void exit_thread(void) -{ - struct task_struct *tsk = current; - struct thread_struct *t = &tsk->thread; - - /* The process may have allocated an io port bitmap... nuke it. */ - if (unlikely(NULL != t->io_bitmap_ptr)) { - struct physdev_set_iobitmap set_iobitmap = { 0 }; - HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap); - kfree(t->io_bitmap_ptr); - t->io_bitmap_ptr = NULL; - } -} - -void flush_thread(void) -{ - struct task_struct *tsk = current; - - memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); - memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); - /* - * Forget coprocessor state.. - */ - clear_fpu(tsk); - clear_used_math(); -} - -void release_thread(struct task_struct *dead_task) -{ - BUG_ON(dead_task->mm); - release_vm86_irqs(dead_task); -} - -/* - * This gets called before we allocate a new thread and copy - * the current task into it. - */ -void prepare_to_copy(struct task_struct *tsk) -{ - unlazy_fpu(tsk); -} - -int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, - unsigned long unused, - struct task_struct * p, struct pt_regs * regs) -{ - struct pt_regs * childregs; - struct task_struct *tsk; - int err; - - childregs = task_pt_regs(p); - *childregs = *regs; - childregs->eax = 0; - childregs->esp = esp; - - p->thread.esp = (unsigned long) childregs; - p->thread.esp0 = (unsigned long) (childregs+1); - - p->thread.eip = (unsigned long) ret_from_fork; - - savesegment(fs,p->thread.fs); - savesegment(gs,p->thread.gs); - - tsk = current; - if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) { - p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); - if (!p->thread.io_bitmap_ptr) { - p->thread.io_bitmap_max = 0; - return -ENOMEM; - } - memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr, - IO_BITMAP_BYTES); - } - - /* - * Set a new TLS for the child thread? - */ - if (clone_flags & CLONE_SETTLS) { - struct desc_struct *desc; - struct user_desc info; - int idx; - - err = -EFAULT; - if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info))) - goto out; - err = -EINVAL; - if (LDT_empty(&info)) - goto out; - - idx = info.entry_number; - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - goto out; - - desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; - desc->a = LDT_entry_a(&info); - desc->b = LDT_entry_b(&info); - } - - p->thread.iopl = current->thread.iopl; - - err = 0; - out: - if (err && p->thread.io_bitmap_ptr) { - kfree(p->thread.io_bitmap_ptr); - p->thread.io_bitmap_max = 0; - } - return err; -} - -/* - * fill in the user structure for a core dump.. - */ -void dump_thread(struct pt_regs * regs, struct user * dump) -{ - int i; - -/* changed the size calculations - should hopefully work better. lbt */ - dump->magic = CMAGIC; - dump->start_code = 0; - dump->start_stack = regs->esp & ~(PAGE_SIZE - 1); - dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; - dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; - dump->u_dsize -= dump->u_tsize; - dump->u_ssize = 0; - for (i = 0; i < 8; i++) - dump->u_debugreg[i] = current->thread.debugreg[i]; - - if (dump->start_stack < TASK_SIZE) - dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; - - dump->regs.ebx = regs->ebx; - dump->regs.ecx = regs->ecx; - dump->regs.edx = regs->edx; - dump->regs.esi = regs->esi; - dump->regs.edi = regs->edi; - dump->regs.ebp = regs->ebp; - dump->regs.eax = regs->eax; - dump->regs.ds = regs->xds; - dump->regs.es = regs->xes; - savesegment(fs,dump->regs.fs); - savesegment(gs,dump->regs.gs); - dump->regs.orig_eax = regs->orig_eax; - dump->regs.eip = regs->eip; - dump->regs.cs = regs->xcs; - dump->regs.eflags = regs->eflags; - dump->regs.esp = regs->esp; - dump->regs.ss = regs->xss; - - dump->u_fpvalid = dump_fpu (regs, &dump->i387); -} -EXPORT_SYMBOL(dump_thread); - -/* - * Capture the user space registers if the task is not running (in user space) - */ -int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) -{ - struct pt_regs ptregs = *task_pt_regs(tsk); - ptregs.xcs &= 0xffff; - ptregs.xds &= 0xffff; - ptregs.xes &= 0xffff; - ptregs.xss &= 0xffff; - - elf_core_copy_regs(regs, &ptregs); - - return 1; -} - -/* - * This function selects if the context switch from prev to next - * has to tweak the TSC disable bit in the cr4. - */ -static inline void disable_tsc(struct task_struct *prev_p, - struct task_struct *next_p) -{ - struct thread_info *prev, *next; - - /* - * gcc should eliminate the ->thread_info dereference if - * has_secure_computing returns 0 at compile time (SECCOMP=n). - */ - prev = task_thread_info(prev_p); - next = task_thread_info(next_p); - - if (has_secure_computing(prev) || has_secure_computing(next)) { - /* slow path here */ - if (has_secure_computing(prev) && - !has_secure_computing(next)) { - write_cr4(read_cr4() & ~X86_CR4_TSD); - } else if (!has_secure_computing(prev) && - has_secure_computing(next)) - write_cr4(read_cr4() | X86_CR4_TSD); - } -} - -/* - * switch_to(x,yn) should switch tasks from x to y. - * - * We fsave/fwait so that an exception goes off at the right time - * (as a call from the fsave or fwait in effect) rather than to - * the wrong process. Lazy FP saving no longer makes any sense - * with modern CPU's, and this simplifies a lot of things (SMP - * and UP become the same). - * - * NOTE! We used to use the x86 hardware context switching. The - * reason for not using it any more becomes apparent when you - * try to recover gracefully from saved state that is no longer - * valid (stale segment register values in particular). With the - * hardware task-switch, there is no way to fix up bad state in - * a reasonable manner. - * - * The fact that Intel documents the hardware task-switching to - * be slow is a fairly red herring - this code is not noticeably - * faster. However, there _is_ some room for improvement here, - * so the performance issues may eventually be a valid point. - * More important, however, is the fact that this allows us much - * more flexibility. - * - * The return value (in %eax) will be the "prev" task after - * the task-switch, and shows up in ret_from_fork in entry.S, - * for example. - */ -struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) -{ - struct thread_struct *prev = &prev_p->thread, - *next = &next_p->thread; - int cpu = smp_processor_id(); -#ifndef CONFIG_X86_NO_TSS - struct tss_struct *tss = &per_cpu(init_tss, cpu); -#endif - struct physdev_set_iopl iopl_op; - struct physdev_set_iobitmap iobmp_op; - multicall_entry_t _mcl[8], *mcl = _mcl; - - /* XEN NOTE: FS/GS saved in switch_mm(), not here. */ - - /* - * This is basically '__unlazy_fpu', except that we queue a - * multicall to indicate FPU task switch, rather than - * synchronously trapping to Xen. - */ - if (prev_p->thread_info->status & TS_USEDFPU) { - __save_init_fpu(prev_p); /* _not_ save_init_fpu() */ - mcl->op = __HYPERVISOR_fpu_taskswitch; - mcl->args[0] = 1; - mcl++; - } -#if 0 /* lazy fpu sanity check */ - else BUG_ON(!(read_cr0() & 8)); -#endif - if (next_p->mm) - load_user_cs_desc(cpu, next_p->mm); - - /* - * Reload esp0. - * This is load_esp0(tss, next) with a multicall. - */ - mcl->op = __HYPERVISOR_stack_switch; - mcl->args[0] = __KERNEL_DS; - mcl->args[1] = next->esp0; - mcl++; - - /* - * Load the per-thread Thread-Local Storage descriptor. - * This is load_TLS(next, cpu) with multicalls. - */ -#define C(i) do { \ - if (unlikely(next->tls_array[i].a != prev->tls_array[i].a || \ - next->tls_array[i].b != prev->tls_array[i].b)) { \ - mcl->op = __HYPERVISOR_update_descriptor; \ - *(u64 *)&mcl->args[0] = virt_to_machine( \ - &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]);\ - *(u64 *)&mcl->args[2] = *(u64 *)&next->tls_array[i]; \ - mcl++; \ - } \ -} while (0) - C(0); C(1); C(2); -#undef C - - if (unlikely(prev->iopl != next->iopl)) { - iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3; - mcl->op = __HYPERVISOR_physdev_op; - mcl->args[0] = PHYSDEVOP_set_iopl; - mcl->args[1] = (unsigned long)&iopl_op; - mcl++; - } - - if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { - iobmp_op.bitmap = (char *)next->io_bitmap_ptr; - iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0; - mcl->op = __HYPERVISOR_physdev_op; - mcl->args[0] = PHYSDEVOP_set_iobitmap; - mcl->args[1] = (unsigned long)&iobmp_op; - mcl++; - } - - (void)HYPERVISOR_multicall(_mcl, mcl - _mcl); - - /* - * Restore %fs and %gs if needed. - * - * Glibc normally makes %fs be zero, and %gs is one of - * the TLS segments. - */ - if (unlikely(next->fs)) - loadsegment(fs, next->fs); - - if (next->gs) - loadsegment(gs, next->gs); - - /* - * Now maybe reload the debug registers - */ - if (unlikely(next->debugreg[7])) { - set_debugreg(next->debugreg[0], 0); - set_debugreg(next->debugreg[1], 1); - set_debugreg(next->debugreg[2], 2); - set_debugreg(next->debugreg[3], 3); - /* no 4 and 5 */ - set_debugreg(next->debugreg[6], 6); - set_debugreg(next->debugreg[7], 7); - } - - disable_tsc(prev_p, next_p); - - return prev_p; -} - -asmlinkage int sys_fork(struct pt_regs regs) -{ - return do_fork(SIGCHLD, regs.esp, ®s, 0, NULL, NULL); -} - -asmlinkage int sys_clone(struct pt_regs regs) -{ - unsigned long clone_flags; - unsigned long newsp; - int __user *parent_tidptr, *child_tidptr; - - clone_flags = regs.ebx; - newsp = regs.ecx; - parent_tidptr = (int __user *)regs.edx; - child_tidptr = (int __user *)regs.edi; - if (!newsp) - newsp = regs.esp; - return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); -} - -/* - * This is trivial, and on the face of it looks like it - * could equally well be done in user mode. - * - * Not so, for quite unobvious reasons - register pressure. - * In user mode vfork() cannot have a stack frame, and if - * done by calling the "clone()" system call directly, you - * do not have enough call-clobbered registers to hold all - * the information you need. - */ -asmlinkage int sys_vfork(struct pt_regs regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL, NULL); -} - -/* - * sys_execve() executes a new program. - */ -asmlinkage int sys_execve(struct pt_regs regs) -{ - int error; - char * filename; - - filename = getname((char __user *) regs.ebx); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, - (char __user * __user *) regs.ecx, - (char __user * __user *) regs.edx, - ®s); - if (error == 0) { - task_lock(current); - current->ptrace &= ~PT_DTRACE; - task_unlock(current); - /* Make sure we don't return using sysenter.. */ - set_thread_flag(TIF_IRET); - } - putname(filename); -out: - return error; -} - -#define top_esp (THREAD_SIZE - sizeof(unsigned long)) -#define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) - -unsigned long get_wchan(struct task_struct *p) -{ - unsigned long ebp, esp, eip; - unsigned long stack_page; - int count = 0; - if (!p || p == current || p->state == TASK_RUNNING) - return 0; - stack_page = (unsigned long)task_stack_page(p); - esp = p->thread.esp; - if (!stack_page || esp < stack_page || esp > top_esp+stack_page) - return 0; - /* include/asm-i386/system.h:switch_to() pushes ebp last. */ - ebp = *(unsigned long *) esp; - do { - if (ebp < stack_page || ebp > top_ebp+stack_page) - return 0; - eip = *(unsigned long *) (ebp+4); - if (!in_sched_functions(eip)) - return eip; - ebp = *(unsigned long *) ebp; - } while (count++ < 16); - return 0; -} - -/* - * sys_alloc_thread_area: get a yet unused TLS descriptor index. - */ -static int get_free_idx(void) -{ - struct thread_struct *t = ¤t->thread; - int idx; - - for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) - if (desc_empty(t->tls_array + idx)) - return idx + GDT_ENTRY_TLS_MIN; - return -ESRCH; -} - -/* - * Set a given TLS descriptor: - */ -asmlinkage int sys_set_thread_area(struct user_desc __user *u_info) -{ - struct thread_struct *t = ¤t->thread; - struct user_desc info; - struct desc_struct *desc; - int cpu, idx; - - if (copy_from_user(&info, u_info, sizeof(info))) - return -EFAULT; - idx = info.entry_number; - - /* - * index -1 means the kernel should try to find and - * allocate an empty descriptor: - */ - if (idx == -1) { - idx = get_free_idx(); - if (idx < 0) - return idx; - if (put_user(idx, &u_info->entry_number)) - return -EFAULT; - } - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN; - - /* - * We must not get preempted while modifying the TLS. - */ - cpu = get_cpu(); - - if (LDT_empty(&info)) { - desc->a = 0; - desc->b = 0; - } else { - desc->a = LDT_entry_a(&info); - desc->b = LDT_entry_b(&info); - } - load_TLS(t, cpu); - - put_cpu(); - - return 0; -} - -/* - * Get the current Thread-Local Storage area: - */ - -#define GET_BASE(desc) ( \ - (((desc)->a >> 16) & 0x0000ffff) | \ - (((desc)->b << 16) & 0x00ff0000) | \ - ( (desc)->b & 0xff000000) ) - -#define GET_LIMIT(desc) ( \ - ((desc)->a & 0x0ffff) | \ - ((desc)->b & 0xf0000) ) - -#define GET_32BIT(desc) (((desc)->b >> 22) & 1) -#define GET_CONTENTS(desc) (((desc)->b >> 10) & 3) -#define GET_WRITABLE(desc) (((desc)->b >> 9) & 1) -#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1) -#define GET_PRESENT(desc) (((desc)->b >> 15) & 1) -#define GET_USEABLE(desc) (((desc)->b >> 20) & 1) - -asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) -{ - struct user_desc info; - struct desc_struct *desc; - int idx; - - if (get_user(idx, &u_info->entry_number)) - return -EFAULT; - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - memset(&info, 0, sizeof(info)); - - desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; - - info.entry_number = idx; - info.base_addr = GET_BASE(desc); - info.limit = GET_LIMIT(desc); - info.seg_32bit = GET_32BIT(desc); - info.contents = GET_CONTENTS(desc); - info.read_exec_only = !GET_WRITABLE(desc); - info.limit_in_pages = GET_LIMIT_PAGES(desc); - info.seg_not_present = !GET_PRESENT(desc); - info.useable = GET_USEABLE(desc); - - if (copy_to_user(u_info, &info, sizeof(info))) - return -EFAULT; - return 0; -} - -unsigned long arch_align_stack(unsigned long sp) -{ - if (randomize_va_space) - sp -= get_random_int() % 8192; - return sp & ~0xf; -} - -void arch_add_exec_range(struct mm_struct *mm, unsigned long limit) -{ - if (limit > mm->context.exec_limit) { - mm->context.exec_limit = limit; - set_user_cs(&mm->context.user_cs, limit); - if (mm == current->mm) { - preempt_disable(); - load_user_cs_desc(smp_processor_id(), mm); - preempt_enable(); - } - } -} -void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end) -{ - struct vm_area_struct *vma; - unsigned long limit = PAGE_SIZE; - - if (old_end == mm->context.exec_limit) { - for (vma = mm->mmap; vma; vma = vma->vm_next) - if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit)) - limit = vma->vm_end; - - mm->context.exec_limit = limit; - set_user_cs(&mm->context.user_cs, limit); - if (mm == current->mm) { - preempt_disable(); - load_user_cs_desc(smp_processor_id(), mm); - preempt_enable(); - } - } -} - -void arch_flush_exec_range(struct mm_struct *mm) -{ - mm->context.exec_limit = 0; - set_user_cs(&mm->context.user_cs, 0); -} - -/* - * Generate random brk address between 128MB and 196MB. (if the layout - * allows it.) - */ -void randomize_brk(unsigned long old_brk) -{ - unsigned long new_brk, range_start, range_end; - - range_start = 0x08000000; - if (current->mm->brk >= range_start) - range_start = current->mm->brk; - range_end = range_start + 0x02000000; - new_brk = randomize_range(range_start, range_end, 0); - if (new_brk) - current->mm->brk = new_brk; -} - diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index a995ce854..0480454eb 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -294,7 +295,7 @@ void show_regs(struct pt_regs * regs) printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); print_symbol("EIP is at %s\n", regs->eip); - if (user_mode_vm(regs)) + if (user_mode(regs)) printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); printk(" EFLAGS: %08lx %s (%s %.*s)\n", regs->eflags, print_tainted(), system_utsname.release, @@ -363,6 +364,13 @@ void exit_thread(void) struct task_struct *tsk = current; struct thread_struct *t = &tsk->thread; + /* + * Remove function-return probe instances associated with this task + * and put them back on the free list. Do not insert an exit probe for + * this function, it will be disabled by kprobe_flush_task if you do. + */ + kprobe_flush_task(tsk); + /* The process may have allocated an io port bitmap... nuke it. */ if (unlikely(NULL != t->io_bitmap_ptr)) { int cpu = get_cpu(); @@ -630,8 +638,6 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ __unlazy_fpu(prev_p); - if (next_p->mm) - load_user_cs_desc(cpu, next_p->mm); /* * Reload esp0. @@ -783,6 +789,7 @@ unsigned long get_wchan(struct task_struct *p) } while (count++ < 16); return 0; } +EXPORT_SYMBOL(get_wchan); /* * sys_alloc_thread_area: get a yet unused TLS descriptor index. @@ -904,60 +911,3 @@ unsigned long arch_align_stack(unsigned long sp) sp -= get_random_int() % 8192; return sp & ~0xf; } - -void arch_add_exec_range(struct mm_struct *mm, unsigned long limit) -{ - if (limit > mm->context.exec_limit) { - mm->context.exec_limit = limit; - set_user_cs(&mm->context.user_cs, limit); - if (mm == current->mm) { - preempt_disable(); - load_user_cs_desc(smp_processor_id(), mm); - preempt_enable(); - } - } -} - -void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end) -{ - struct vm_area_struct *vma; - unsigned long limit = PAGE_SIZE; - - if (old_end == mm->context.exec_limit) { - for (vma = mm->mmap; vma; vma = vma->vm_next) - if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit)) - limit = vma->vm_end; - - mm->context.exec_limit = limit; - set_user_cs(&mm->context.user_cs, limit); - if (mm == current->mm) { - preempt_disable(); - load_user_cs_desc(smp_processor_id(), mm); - preempt_enable(); - } - } -} - -void arch_flush_exec_range(struct mm_struct *mm) -{ - mm->context.exec_limit = 0; - set_user_cs(&mm->context.user_cs, 0); -} - -/* - * Generate random brk address between 128MB and 196MB. (if the layout - * allows it.) - */ -void randomize_brk(unsigned long old_brk) -{ - unsigned long new_brk, range_start, range_end; - - range_start = 0x08000000; - if (current->mm->brk >= range_start) - range_start = current->mm->brk; - range_end = range_start + 0x02000000; - new_brk = randomize_range(range_start, range_end, 0); - if (new_brk) - current->mm->brk = new_brk; -} - diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index fd7eaf786..5c1fb6aad 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -34,10 +34,10 @@ /* * Determines which flags the user has access to [1 = access, 0 = no access]. - * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), NT(14), IOPL(12-13), IF(9). + * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9). * Also masks reserved bits (31-22, 15, 5, 3, 1). */ -#define FLAG_MASK 0x00050dd5 +#define FLAG_MASK 0x00054dd5 /* set's the trap flag. */ #define TRAP_FLAG 0x100 @@ -671,7 +671,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit) if (unlikely(current->audit_context)) { if (entryexit) - audit_syscall_exit(AUDITSC_RESULT(regs->eax), + audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is @@ -720,13 +720,14 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit) ret = is_sysemu; out: if (unlikely(current->audit_context) && !entryexit) - audit_syscall_entry(AUDIT_ARCH_I386, regs->orig_eax, + audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax, regs->ebx, regs->ecx, regs->edx, regs->esi); if (ret == 0) return 0; regs->orig_eax = -1; /* force skip of syscall restarting */ if (unlikely(current->audit_context)) - audit_syscall_exit(AUDITSC_RESULT(regs->eax), regs->eax); + audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), + regs->eax); return 1; } diff --git a/arch/i386/kernel/quirks-xen.c b/arch/i386/kernel/quirks-xen.c deleted file mode 100644 index 7e44d81bd..000000000 --- a/arch/i386/kernel/quirks-xen.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file contains work-arounds for x86 and x86_64 platform bugs. - */ -#include -#include -#include - -#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_SMP) || defined(CONFIG_XEN)) && defined(CONFIG_PCI) - -static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) -{ - u8 config, rev; - u32 word; - - /* BIOS may enable hardware IRQ balancing for - * E7520/E7320/E7525(revision ID 0x9 and below) - * based platforms. - * Disable SW irqbalance/affinity on those platforms. - */ - pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); - if (rev > 0x9) - return; - - printk(KERN_INFO "Intel E7520/7320/7525 detected."); - - /* enable access to config space*/ - pci_read_config_byte(dev, 0xf4, &config); - pci_write_config_byte(dev, 0xf4, config|0x2); - - /* read xTPR register */ - raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); - - if (!(word & (1 << 13))) { - dom0_op_t op; - printk(KERN_INFO "Disabling irq balancing and affinity\n"); - op.cmd = DOM0_PLATFORM_QUIRK; - op.u.platform_quirk.quirk_id = QUIRK_NOIRQBALANCING; - (void)HYPERVISOR_dom0_op(&op); - } - - /* put back the original value for config space*/ - if (!(config & 0x2)) - pci_write_config_byte(dev, 0xf4, config); -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); -#endif diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c index 1b183b378..10e21a477 100644 --- a/arch/i386/kernel/reboot_fixups.c +++ b/arch/i386/kernel/reboot_fixups.c @@ -10,6 +10,7 @@ #include #include +#include static void cs5530a_warm_reset(struct pci_dev *dev) { @@ -42,9 +43,9 @@ void mach_reboot_fixups(void) struct pci_dev *dev; int i; - for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) { + for (i=0; i < ARRAY_SIZE(fixups_table); i++) { cur = &(fixups_table[i]); - dev = pci_get_device(cur->vendor, cur->device, 0); + dev = pci_get_device(cur->vendor, cur->device, NULL); if (!dev) continue; diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c index 967dc74df..7455ab643 100644 --- a/arch/i386/kernel/semaphore.c +++ b/arch/i386/kernel/semaphore.c @@ -110,11 +110,11 @@ asm( ".align 4\n" ".globl __write_lock_failed\n" "__write_lock_failed:\n\t" - LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" + LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" "1: rep; nop\n\t" "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" "jne 1b\n\t" - LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" "jnz __write_lock_failed\n\t" "ret" ); @@ -124,11 +124,11 @@ asm( ".align 4\n" ".globl __read_lock_failed\n" "__read_lock_failed:\n\t" - LOCK_PREFIX "incl (%eax)\n" + LOCK "incl (%eax)\n" "1: rep; nop\n\t" "cmpl $1,(%eax)\n\t" "js 1b\n\t" - LOCK_PREFIX "decl (%eax)\n\t" + LOCK "decl (%eax)\n\t" "js __read_lock_failed\n\t" "ret" ); diff --git a/arch/i386/kernel/setup-xen.c b/arch/i386/kernel/setup-xen.c deleted file mode 100644 index 3508a883f..000000000 --- a/arch/i386/kernel/setup-xen.c +++ /dev/null @@ -1,1827 +0,0 @@ -/* - * linux/arch/i386/kernel/setup.c - * - * Copyright (C) 1995 Linus Torvalds - * - * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 - * - * Memory region support - * David Parsons , July-August 1999 - * - * Added E820 sanitization routine (removes overlapping memory regions); - * Brian Moyle , February 2001 - * - * Moved CPU detection code to cpu/${cpu}.c - * Patrick Mochel , March 2002 - * - * Provisions for empty E820 memory regions (reported by certain BIOSes). - * Alex Achenbach , December 2002. - * - */ - -/* - * This file handles the architecture-dependent parts of initialization - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include , (default is __obsolete_setup("amijoy="); static int amijoy_used; -static DEFINE_MUTEX(amijoy_mutex); +static DECLARE_MUTEX(amijoy_sem); static struct input_dev *amijoy_dev[2]; static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" }; @@ -86,7 +85,7 @@ static int amijoy_open(struct input_dev *dev) { int err; - err = mutex_lock_interruptible(&amijoy_mutex); + err = down_interruptible(&amijoy_sem); if (err) return err; @@ -98,16 +97,16 @@ static int amijoy_open(struct input_dev *dev) amijoy_used++; out: - mutex_unlock(&amijoy_mutex); + up(&amijoy_sem); return err; } static void amijoy_close(struct input_dev *dev) { - mutex_lock(&amijoy_mutex); + down(&amijoy_sem); if (!--amijoy_used) free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt); - mutex_unlock(&amijoy_mutex); + up(&amijoy_sem); } static int __init amijoy_init(void) diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index e61894685..dcffc34f3 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -38,7 +38,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver"); @@ -112,7 +111,7 @@ struct db9 { struct pardevice *pd; int mode; int used; - struct mutex mutex; + struct semaphore sem; char phys[DB9_MAX_DEVICES][32]; }; @@ -526,7 +525,7 @@ static int db9_open(struct input_dev *dev) struct parport *port = db9->pd->port; int err; - err = mutex_lock_interruptible(&db9->mutex); + err = down_interruptible(&db9->sem); if (err) return err; @@ -540,7 +539,7 @@ static int db9_open(struct input_dev *dev) mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME); } - mutex_unlock(&db9->mutex); + up(&db9->sem); return 0; } @@ -549,14 +548,14 @@ static void db9_close(struct input_dev *dev) struct db9 *db9 = dev->private; struct parport *port = db9->pd->port; - mutex_lock(&db9->mutex); + down(&db9->sem); if (!--db9->used) { del_timer_sync(&db9->timer); parport_write_control(port, 0x00); parport_data_forward(port); parport_release(db9->pd); } - mutex_unlock(&db9->mutex); + up(&db9->sem); } static struct db9 __init *db9_probe(int parport, int mode) @@ -604,7 +603,7 @@ static struct db9 __init *db9_probe(int parport, int mode) goto err_unreg_pardev; } - mutex_init(&db9->mutex); + init_MUTEX(&db9->sem); db9->pd = pd; db9->mode = mode; init_timer(&db9->timer); diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index ecbdb6b9b..900587acd 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -7,7 +7,6 @@ * Based on the work of: * Andree Borrmann John Dahlstrom * David Kuder Nathan Hand - * Raphael Assenat */ /* @@ -37,7 +36,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); @@ -74,9 +72,8 @@ __obsolete_setup("gc_3="); #define GC_N64 6 #define GC_PSX 7 #define GC_DDR 8 -#define GC_SNESMOUSE 9 -#define GC_MAX 9 +#define GC_MAX 8 #define GC_REFRESH_TIME HZ/100 @@ -86,7 +83,7 @@ struct gc { struct timer_list timer; unsigned char pads[GC_MAX + 1]; int used; - struct mutex mutex; + struct semaphore sem; char phys[GC_MAX_DEVICES][32]; }; @@ -96,7 +93,7 @@ static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", "Multisystem 2-button joystick", "N64 controller", "PSX controller", - "PSX DDR controller", "SNES mouse" }; + "PSX DDR controller" }; /* * N64 support. */ @@ -208,12 +205,9 @@ static void gc_n64_process_packet(struct gc *gc) * NES/SNES support. */ -#define GC_NES_DELAY 6 /* Delay between bits - 6us */ -#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */ -#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the - last 4 bits are unused */ -#define GC_SNESMOUSE_LENGTH 32 /* The SNES mouse uses 32 bits, the first - 16 bits are equivalent to a gamepad */ +#define GC_NES_DELAY 6 /* Delay between bits - 6us */ +#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */ +#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the last 4 bits are unused */ #define GC_NES_POWER 0xfc #define GC_NES_CLOCK 0x01 @@ -248,15 +242,11 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data) static void gc_nes_process_packet(struct gc *gc) { - unsigned char data[GC_SNESMOUSE_LENGTH]; + unsigned char data[GC_SNES_LENGTH]; struct input_dev *dev; - int i, j, s, len; - char x_rel, y_rel; - - len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH : - (gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH); + int i, j, s; - gc_nes_read_packet(gc, len, data); + gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data); for (i = 0; i < GC_MAX_DEVICES; i++) { @@ -279,44 +269,6 @@ static void gc_nes_process_packet(struct gc *gc) for (j = 0; j < 8; j++) input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); - if (s & gc->pads[GC_SNESMOUSE]) { - /* - * The 4 unused bits from SNES controllers appear to be ID bits - * so use them to make sure iwe are dealing with a mouse. - * gamepad is connected. This is important since - * my SNES gamepad sends 1's for bits 16-31, which - * cause the mouse pointer to quickly move to the - * upper left corner of the screen. - */ - if (!(s & data[12]) && !(s & data[13]) && - !(s & data[14]) && (s & data[15])) { - input_report_key(dev, BTN_LEFT, s & data[9]); - input_report_key(dev, BTN_RIGHT, s & data[8]); - - x_rel = y_rel = 0; - for (j = 0; j < 7; j++) { - x_rel <<= 1; - if (data[25 + j] & s) - x_rel |= 1; - - y_rel <<= 1; - if (data[17 + j] & s) - y_rel |= 1; - } - - if (x_rel) { - if (data[24] & s) - x_rel = -x_rel; - input_report_rel(dev, REL_X, x_rel); - } - - if (y_rel) { - if (data[16] & s) - y_rel = -y_rel; - input_report_rel(dev, REL_Y, y_rel); - } - } - } input_sync(dev); } } @@ -572,10 +524,10 @@ static void gc_timer(unsigned long private) gc_n64_process_packet(gc); /* - * NES and SNES pads or mouse + * NES and SNES pads */ - if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE]) + if (gc->pads[GC_NES] || gc->pads[GC_SNES]) gc_nes_process_packet(gc); /* @@ -600,7 +552,7 @@ static int gc_open(struct input_dev *dev) struct gc *gc = dev->private; int err; - err = mutex_lock_interruptible(&gc->mutex); + err = down_interruptible(&gc->sem); if (err) return err; @@ -610,7 +562,7 @@ static int gc_open(struct input_dev *dev) mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); } - mutex_unlock(&gc->mutex); + up(&gc->sem); return 0; } @@ -618,13 +570,13 @@ static void gc_close(struct input_dev *dev) { struct gc *gc = dev->private; - mutex_lock(&gc->mutex); + down(&gc->sem); if (!--gc->used) { del_timer_sync(&gc->timer); parport_write_control(gc->pd->port, 0x00); parport_release(gc->pd); } - mutex_unlock(&gc->mutex); + up(&gc->sem); } static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) @@ -657,13 +609,10 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) input_dev->open = gc_open; input_dev->close = gc_close; - if (pad_type != GC_SNESMOUSE) { - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - for (i = 0; i < 2; i++) - input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0); - } else - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + for (i = 0; i < 2; i++) + input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0); gc->pads[0] |= gc_status_bit[idx]; gc->pads[pad_type] |= gc_status_bit[idx]; @@ -681,13 +630,6 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) break; - case GC_SNESMOUSE: - set_bit(BTN_LEFT, input_dev->keybit); - set_bit(BTN_RIGHT, input_dev->keybit); - set_bit(REL_X, input_dev->relbit); - set_bit(REL_Y, input_dev->relbit); - break; - case GC_SNES: for (i = 4; i < 8; i++) set_bit(gc_snes_btn[i], input_dev->keybit); @@ -751,7 +693,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) goto err_unreg_pardev; } - mutex_init(&gc->mutex); + init_MUTEX(&gc->sem); gc->pd = pd; init_timer(&gc->timer); gc->timer.data = (long) gc; diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index 2b8e8456c..4678b6dab 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c @@ -42,14 +42,14 @@ static int make_magnitude_modifier(struct iforce* iforce, unsigned char data[3]; if (!no_alloc) { - mutex_lock(&iforce->mem_mutex); + down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 2, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { - mutex_unlock(&iforce->mem_mutex); + up(&iforce->mem_mutex); return -ENOMEM; } - mutex_unlock(&iforce->mem_mutex); + up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); @@ -75,14 +75,14 @@ static int make_period_modifier(struct iforce* iforce, period = TIME_SCALE(period); if (!no_alloc) { - mutex_lock(&iforce->mem_mutex); + down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { - mutex_unlock(&iforce->mem_mutex); + up(&iforce->mem_mutex); return -ENOMEM; } - mutex_unlock(&iforce->mem_mutex); + up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); @@ -115,14 +115,14 @@ static int make_envelope_modifier(struct iforce* iforce, fade_duration = TIME_SCALE(fade_duration); if (!no_alloc) { - mutex_lock(&iforce->mem_mutex); + down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { - mutex_unlock(&iforce->mem_mutex); + up(&iforce->mem_mutex); return -ENOMEM; } - mutex_unlock(&iforce->mem_mutex); + up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); @@ -152,14 +152,14 @@ static int make_condition_modifier(struct iforce* iforce, unsigned char data[10]; if (!no_alloc) { - mutex_lock(&iforce->mem_mutex); + down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 8, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { - mutex_unlock(&iforce->mem_mutex); + up(&iforce->mem_mutex); return -ENOMEM; } - mutex_unlock(&iforce->mem_mutex); + up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index ab0a26b92..b6bc04998 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -350,7 +350,7 @@ int iforce_init_device(struct iforce *iforce) init_waitqueue_head(&iforce->wait); spin_lock_init(&iforce->xmit_lock); - mutex_init(&iforce->mem_mutex); + init_MUTEX(&iforce->mem_mutex); iforce->xmit.buf = iforce->xmit_data; iforce->dev = input_dev; diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index 668f24535..146f406b8 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h @@ -37,7 +37,7 @@ #include #include #include -#include +#include /* This module provides arbitrary resource management routines. * I use it to manage the device's memory. @@ -45,7 +45,6 @@ */ #include - #define IFORCE_MAX_LENGTH 16 /* iforce::bus */ @@ -147,7 +146,7 @@ struct iforce { wait_queue_head_t wait; struct resource device_memory; struct iforce_core_effect core_effects[FF_EFFECTS_MAX]; - struct mutex mem_mutex; + struct semaphore mem_mutex; }; /* Get hi and low bytes of a 16-bits int */ diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 95c0de796..2b2ec1057 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -589,7 +589,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) struct sw *sw; struct input_dev *input_dev; int i, j, k, l; - int err = 0; + int err; unsigned char *buf = NULL; /* [SW_LENGTH] */ unsigned char *idbuf = NULL; /* [SW_LENGTH] */ unsigned char m = 1; @@ -776,10 +776,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) goto fail4; } - out: kfree(buf); - kfree(idbuf); - - return err; + return 0; fail4: input_free_device(sw->dev[i]); fail3: while (--i >= 0) @@ -787,7 +784,9 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) fail2: gameport_close(gameport); fail1: gameport_set_drvdata(gameport, NULL); kfree(sw); - goto out; + kfree(buf); + kfree(idbuf); + return err; } static void sw_disconnect(struct gameport *gameport) diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index 5570fd548..b154938e8 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -37,7 +37,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("TurboGraFX parallel port interface driver"); @@ -87,7 +86,7 @@ static struct tgfx { char phys[TGFX_MAX_DEVICES][32]; int sticks; int used; - struct mutex sem; + struct semaphore sem; } *tgfx_base[TGFX_MAX_PORTS]; /* @@ -129,7 +128,7 @@ static int tgfx_open(struct input_dev *dev) struct tgfx *tgfx = dev->private; int err; - err = mutex_lock_interruptible(&tgfx->sem); + err = down_interruptible(&tgfx->sem); if (err) return err; @@ -139,7 +138,7 @@ static int tgfx_open(struct input_dev *dev) mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME); } - mutex_unlock(&tgfx->sem); + up(&tgfx->sem); return 0; } @@ -147,13 +146,13 @@ static void tgfx_close(struct input_dev *dev) { struct tgfx *tgfx = dev->private; - mutex_lock(&tgfx->sem); + down(&tgfx->sem); if (!--tgfx->used) { del_timer_sync(&tgfx->timer); parport_write_control(tgfx->pd->port, 0x00); parport_release(tgfx->pd); } - mutex_unlock(&tgfx->sem); + up(&tgfx->sem); } @@ -192,7 +191,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) goto err_unreg_pardev; } - mutex_init(&tgfx->sem); + init_MUTEX(&tgfx->sem); tgfx->pd = pd; init_timer(&tgfx->timer); tgfx->timer.data = (long) tgfx; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a9dda56f6..3b0ac3b43 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -13,7 +13,7 @@ menuconfig INPUT_KEYBOARD if INPUT_KEYBOARD config KEYBOARD_ATKBD - tristate "AT keyboard" if EMBEDDED || !X86_PC + tristate "AT keyboard" if !X86_PC default y select SERIO select SERIO_LIBPS2 diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 5550b6d01..ffacf6eca 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -27,7 +27,6 @@ #include #include #include -#include #define DRIVER_DESC "AT and PS/2 keyboard driver" @@ -217,7 +216,7 @@ struct atkbd { unsigned long time; struct work_struct event_work; - struct mutex event_mutex; + struct semaphore event_sem; unsigned long event_mask; }; @@ -303,19 +302,19 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, if (atkbd->translated) { if (atkbd->emul || - (code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 && - code != ATKBD_RET_HANGUEL && code != ATKBD_RET_HANJA && - (code != ATKBD_RET_ERR || atkbd->err_xl) && - (code != ATKBD_RET_BAT || atkbd->bat_xl))) { + !(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 || + code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA || + (code == ATKBD_RET_ERR && !atkbd->err_xl) || + (code == ATKBD_RET_BAT && !atkbd->bat_xl))) { atkbd->release = code >> 7; code &= 0x7f; } if (!atkbd->emul) { if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f)) - atkbd->bat_xl = !(data >> 7); + atkbd->bat_xl = !atkbd->release; if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f)) - atkbd->err_xl = !(data >> 7); + atkbd->err_xl = !atkbd->release; } } @@ -340,7 +339,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3); goto out; case ATKBD_RET_ERR: -// printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); + printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); goto out; } @@ -360,13 +359,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, break; case ATKBD_KEY_UNKNOWN: if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) { -#if 0 -/* Quite a few key switchers and other tools trigger this and it confuses - people who can do nothing about it */ printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, " "like XFree86, might be trying access hardware directly.\n", data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); -#endif } else { printk(KERN_WARNING "atkbd.c: Unknown key %s " "(%s set %d, code %#x on %s).\n", @@ -454,7 +449,7 @@ static void atkbd_event_work(void *data) unsigned char param[2]; int i, j; - mutex_lock(&atkbd->event_mutex); + down(&atkbd->event_sem); if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) { param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) @@ -485,7 +480,7 @@ static void atkbd_event_work(void *data) ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); } - mutex_unlock(&atkbd->event_mutex); + up(&atkbd->event_sem); } /* @@ -851,7 +846,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->dev = dev; ps2_init(&atkbd->ps2dev, serio); INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd); - mutex_init(&atkbd->event_mutex); + init_MUTEX(&atkbd->event_sem); switch (serio->id.type) { @@ -867,6 +862,9 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->softrepeat = atkbd_softrepeat; atkbd->scroll = atkbd_scroll; + if (!atkbd->write) + atkbd->softrepeat = 1; + if (atkbd->softrepeat) atkbd->softraw = 1; diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 1f0e72026..e301ee4ca 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -29,11 +29,11 @@ #define KB_COLS 12 #define KB_ROWMASK(r) (1 << (r)) #define SCANCODE(r,c) ( ((r)<<4) + (c) + 1 ) -/* zero code, 124 scancodes */ -#define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 ) +/* zero code, 124 scancodes + 3 hinge combinations */ +#define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 +3 ) +#define SCAN_INTERVAL (HZ/10) -#define SCAN_INTERVAL (50) /* ms */ -#define HINGE_SCAN_INTERVAL (250) /* ms */ +#define HINGE_SCAN_INTERVAL (HZ/4) #define CORGI_KEY_CALENDER KEY_F1 #define CORGI_KEY_ADDRESS KEY_F2 @@ -49,6 +49,9 @@ #define CORGI_KEY_MAIL KEY_F10 #define CORGI_KEY_OK KEY_F11 #define CORGI_KEY_MENU KEY_F12 +#define CORGI_HINGE_0 KEY_KP0 +#define CORGI_HINGE_1 KEY_KP1 +#define CORGI_HINGE_2 KEY_KP2 static unsigned char corgikbd_keycode[NR_SCANCODES] = { 0, /* 0 */ @@ -60,6 +63,7 @@ static unsigned char corgikbd_keycode[NR_SCANCODES] = { CORGI_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0, /* 81-96 */ KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, CORGI_KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0, /* 97-112 */ CORGI_KEY_OFF, CORGI_KEY_EXOK, CORGI_KEY_EXCANCEL, CORGI_KEY_EXJOGDOWN, CORGI_KEY_EXJOGUP, 0, 0, 0, 0, 0, 0, 0, /* 113-124 */ + CORGI_HINGE_0, CORGI_HINGE_1, CORGI_HINGE_2 /* 125-127 */ }; @@ -183,7 +187,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs /* if any keys are pressed, enable the timer */ if (num_pressed) - mod_timer(&corgikbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL)); + mod_timer(&corgikbd_data->timer, jiffies + SCAN_INTERVAL); spin_unlock_irqrestore(&corgikbd_data->lock, flags); } @@ -224,7 +228,6 @@ static void corgikbd_timer_callback(unsigned long data) * 0x0c - Keyboard and Screen Closed */ -#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) #define HINGE_STABLE_COUNT 2 static int sharpsl_hinge_state; static int hinge_count; @@ -236,7 +239,6 @@ static void corgikbd_hinge_timer(unsigned long data) unsigned long flags; gprr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPRR) & (CORGI_SCP_SWA | CORGI_SCP_SWB); - gprr |= (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0); if (gprr != sharpsl_hinge_state) { hinge_count = 0; sharpsl_hinge_state = gprr; @@ -245,40 +247,29 @@ static void corgikbd_hinge_timer(unsigned long data) if (hinge_count >= HINGE_STABLE_COUNT) { spin_lock_irqsave(&corgikbd_data->lock, flags); - input_report_switch(corgikbd_data->input, SW_LID, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0)); - input_report_switch(corgikbd_data->input, SW_TABLET_MODE, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0)); - input_report_switch(corgikbd_data->input, SW_HEADPHONE_INSERT, (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0)); + input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0)); + input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0)); input_sync(corgikbd_data->input); spin_unlock_irqrestore(&corgikbd_data->lock, flags); } } - mod_timer(&corgikbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); + mod_timer(&corgikbd_data->htimer, jiffies + HINGE_SCAN_INTERVAL); } #ifdef CONFIG_PM static int corgikbd_suspend(struct platform_device *dev, pm_message_t state) { - int i; struct corgikbd *corgikbd = platform_get_drvdata(dev); - corgikbd->suspended = 1; - /* strobe 0 is the power key so this can't be made an input for - powersaving therefore i = 1 */ - for (i = 1; i < CORGI_KEY_STROBE_NUM; i++) - pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_IN); return 0; } static int corgikbd_resume(struct platform_device *dev) { - int i; struct corgikbd *corgikbd = platform_get_drvdata(dev); - for (i = 1; i < CORGI_KEY_STROBE_NUM; i++) - pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH); - /* Upon resume, ignore the suspend key for a short while */ corgikbd->suspend_jiffies=jiffies; corgikbd->suspended = 0; @@ -340,13 +331,12 @@ static int __init corgikbd_probe(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++) set_bit(corgikbd->keycode[i], input_dev->keybit); clear_bit(0, input_dev->keybit); - set_bit(SW_LID, input_dev->swbit); - set_bit(SW_TABLET_MODE, input_dev->swbit); - set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); + set_bit(SW_0, input_dev->swbit); + set_bit(SW_1, input_dev->swbit); input_register_device(corgikbd->input); - mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); + mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL); /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) { @@ -361,9 +351,6 @@ static int __init corgikbd_probe(struct platform_device *pdev) for (i = 0; i < CORGI_KEY_STROBE_NUM; i++) pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH); - /* Setup the headphone jack as an input */ - pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN); - return 0; } diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index ef78bffed..0a90962c3 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -204,7 +204,7 @@ static irqreturn_t hil_kbd_interrupt(struct serio *serio, hil_packet packet; int idx; - kbd = (struct hil_kbd *)serio->private; + kbd = serio_get_drvdata(serio); if (kbd == NULL) { BUG(); return IRQ_HANDLED; @@ -234,7 +234,7 @@ static void hil_kbd_disconnect(struct serio *serio) { struct hil_kbd *kbd; - kbd = (struct hil_kbd *)serio->private; + kbd = serio_get_drvdata(serio); if (kbd == NULL) { BUG(); return; @@ -245,20 +245,20 @@ static void hil_kbd_disconnect(struct serio *serio) kfree(kbd); } -static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv) +static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) { struct hil_kbd *kbd; uint8_t did, *idd; int i; - if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return; - - if (!(kbd = kmalloc(sizeof(struct hil_kbd), GFP_KERNEL))) return; + kbd = kmalloc(sizeof(*kbd), GFP_KERNEL); + if (!kbd) + return -ENOMEM; memset(kbd, 0, sizeof(struct hil_kbd)); if (serio_open(serio, drv)) goto bail0; - serio->private = kbd; + serio_set_drvdata(serio, kbd); kbd->serio = serio; kbd->dev.private = kbd; @@ -342,19 +342,31 @@ static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv) down(&(kbd->sem)); up(&(kbd->sem)); - return; + return 0; bail1: serio_close(serio); bail0: kfree(kbd); + serio_set_drvdata(serio, NULL); + return -EIO; } +static struct serio_device_id hil_kbd_ids[] = { + { + .type = SERIO_HIL_MLC, + .proto = SERIO_HIL, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; struct serio_driver hil_kbd_serio_drv = { .driver = { .name = "hil_kbd", }, .description = "HP HIL keyboard driver", + .id_table = hil_kbd_ids, .connect = hil_kbd_connect, .disconnect = hil_kbd_disconnect, .interrupt = hil_kbd_interrupt diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 33edd030a..e95bc052e 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -3,7 +3,7 @@ * * Copyright (C) 1998 Philip Blundell * Copyright (C) 1999 Matthew Wilcox - * Copyright (C) 1999-2006 Helge Deller + * Copyright (C) 1999-2003 Helge Deller * * Very basic HP Human Interface Loop (HIL) driver. * This driver handles the keyboard on HP300 (m68k) and on some @@ -90,7 +90,7 @@ static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = /* HIL structure */ static struct { - struct input_dev *dev; + struct input_dev dev; unsigned int curdev; @@ -117,7 +117,7 @@ static void poll_finished(void) down = (hil_dev.data[1] & 1) == 0; scode = hil_dev.data[1] >> 1; key = hphilkeyb_keycode[scode]; - input_report_key(hil_dev.dev, key, down); + input_report_key(&hil_dev.dev, key, down); break; } hil_dev.curdev = 0; @@ -207,14 +207,9 @@ hil_keyb_init(void) unsigned int i, kbid; wait_queue_head_t hil_wait; - if (hil_dev.dev) { + if (hil_dev.dev.id.bustype) { return -ENODEV; /* already initialized */ } - - hil_dev.dev = input_allocate_device(); - if (!hil_dev.dev) - return -ENOMEM; - hil_dev.dev->private = &hil_dev; #if defined(CONFIG_HP300) if (!hwreg_present((void *)(HILBASE + HIL_DATA))) @@ -252,26 +247,28 @@ hil_keyb_init(void) c = 0; hil_do(HIL_WRITEKBDSADR, &c, 1); + init_input_dev(&hil_dev.dev); + for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) if (hphilkeyb_keycode[i] != KEY_RESERVED) - set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); - - hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); - hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; - hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]); - hil_dev.dev->keycode = hphilkeyb_keycode; - hil_dev.dev->name = "HIL keyboard"; - hil_dev.dev->phys = "hpkbd/input0"; - - hil_dev.dev->id.bustype = BUS_HIL; - hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP; - hil_dev.dev->id.product = 0x0001; - hil_dev.dev->id.version = 0x0010; - - input_register_device(hil_dev.dev); + set_bit(hphilkeyb_keycode[i], hil_dev.dev.keybit); + + hil_dev.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + hil_dev.dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); + hil_dev.dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE; + hil_dev.dev.keycodesize = sizeof(hphilkeyb_keycode[0]); + hil_dev.dev.keycode = hphilkeyb_keycode; + hil_dev.dev.name = "HIL keyboard"; + hil_dev.dev.phys = "hpkbd/input0"; + + hil_dev.dev.id.bustype = BUS_HIL; + hil_dev.dev.id.vendor = PCI_VENDOR_ID_HP; + hil_dev.dev.id.product = 0x0001; + hil_dev.dev.id.version = 0x0010; + + input_register_device(&hil_dev.dev); printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", - hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); + hil_dev.dev.name, kbid, HILBASE, HIL_IRQ); return 0; } @@ -332,9 +329,7 @@ static void __exit hil_exit(void) /* Turn off interrupts */ hil_do(HIL_INTOFF, NULL, 0); - input_unregister_device(hil_dev.dev); - - hil_dev.dev = NULL; + input_unregister_device(&hil_dev.dev); #if defined(CONFIG_PARISC) unregister_parisc_driver(&hil_driver); diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index c5d03fb77..83999d583 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -30,7 +30,6 @@ #define SCANCODE(r,c) (((r)<<4) + (c) + 1) #define NR_SCANCODES ((KB_ROWS<<4) + 1) -#define SCAN_INTERVAL (50) /* ms */ #define HINGE_SCAN_INTERVAL (150) /* ms */ #define SPITZ_KEY_CALENDER KEY_F1 @@ -53,8 +52,8 @@ static unsigned char spitzkbd_keycode[NR_SCANCODES] = { KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0, /* 1-16 */ 0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */ KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */ - SPITZ_KEY_ADDRESS, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */ - SPITZ_KEY_CALENDER, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */ + SPITZ_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */ + SPITZ_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */ SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0, /* 81-96 */ KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0 /* 97-112 */ }; @@ -231,7 +230,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs /* if any keys are pressed, enable the timer */ if (num_pressed) - mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL)); + mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(100)); spin_unlock_irqrestore(&spitzkbd_data->lock, flags); } @@ -288,7 +287,6 @@ static void spitzkbd_hinge_timer(unsigned long data) unsigned long flags; state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB)); - state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)); if (state != sharpsl_hinge_state) { hinge_count = 0; sharpsl_hinge_state = state; @@ -299,9 +297,8 @@ static void spitzkbd_hinge_timer(unsigned long data) if (hinge_count >= HINGE_STABLE_COUNT) { spin_lock_irqsave(&spitzkbd_data->lock, flags); - input_report_switch(spitzkbd_data->input, SW_LID, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0)); - input_report_switch(spitzkbd_data->input, SW_TABLET_MODE, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0)); - input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0)); + input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0)); + input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0)); input_sync(spitzkbd_data->input); spin_unlock_irqrestore(&spitzkbd_data->lock, flags); @@ -398,9 +395,8 @@ static int __init spitzkbd_probe(struct platform_device *dev) for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++) set_bit(spitzkbd->keycode[i], input_dev->keybit); clear_bit(0, input_dev->keybit); - set_bit(SW_LID, input_dev->swbit); - set_bit(SW_TABLET_MODE, input_dev->swbit); - set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); + set_bit(SW_0, input_dev->swbit); + set_bit(SW_1, input_dev->swbit); input_register_device(input_dev); @@ -436,9 +432,6 @@ static int __init spitzkbd_probe(struct platform_device *dev) request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, "Spitzkbd SWB", spitzkbd); - request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, - SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, - "Spitzkbd HP", spitzkbd); printk(KERN_INFO "input: Spitz Keyboard Registered\n"); @@ -457,7 +450,6 @@ static int spitzkbd_remove(struct platform_device *dev) free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd); free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd); free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd); - free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd); del_timer_sync(&spitzkbd->htimer); del_timer_sync(&spitzkbd->timer); diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index b15b6d8d4..84c00a53f 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -226,7 +226,7 @@ static void sunkbd_reinit(void *data) static void sunkbd_enable(struct sunkbd *sunkbd, int enable) { serio_pause_rx(sunkbd->serio); - sunkbd->enabled = 1; + sunkbd->enabled = enable; serio_continue_rx(sunkbd->serio); } diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index afd322185..1ef477f44 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -24,6 +24,7 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("PC Speaker beeper driver"); MODULE_LICENSE("GPL"); +static struct platform_device *pcspkr_platform_device; static DEFINE_SPINLOCK(i8253_beep_lock); static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) @@ -134,11 +135,35 @@ static struct platform_driver pcspkr_platform_driver = { static int __init pcspkr_init(void) { - return platform_driver_register(&pcspkr_platform_driver); + int err; + + err = platform_driver_register(&pcspkr_platform_driver); + if (err) + return err; + + pcspkr_platform_device = platform_device_alloc("pcspkr", -1); + if (!pcspkr_platform_device) { + err = -ENOMEM; + goto err_unregister_driver; + } + + err = platform_device_add(pcspkr_platform_device); + if (err) + goto err_free_device; + + return 0; + + err_free_device: + platform_device_put(pcspkr_platform_device); + err_unregister_driver: + platform_driver_unregister(&pcspkr_platform_driver); + + return err; } static void __exit pcspkr_exit(void) { + platform_device_unregister(pcspkr_platform_device); platform_driver_unregister(&pcspkr_platform_driver); } diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index d723e9ad7..546ed9b49 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -194,7 +194,7 @@ static int uinput_open(struct inode *inode, struct file *file) if (!newdev) return -ENOMEM; - mutex_init(&newdev->mutex); + init_MUTEX(&newdev->sem); spin_lock_init(&newdev->requests_lock); init_waitqueue_head(&newdev->requests_waitq); init_waitqueue_head(&newdev->waitq); @@ -340,7 +340,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t struct uinput_device *udev = file->private_data; int retval; - retval = mutex_lock_interruptible(&udev->mutex); + retval = down_interruptible(&udev->sem); if (retval) return retval; @@ -348,7 +348,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t uinput_inject_event(udev, buffer, count) : uinput_setup_device(udev, buffer, count); - mutex_unlock(&udev->mutex); + up(&udev->sem); return retval; } @@ -369,7 +369,7 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, if (retval) return retval; - retval = mutex_lock_interruptible(&udev->mutex); + retval = down_interruptible(&udev->sem); if (retval) return retval; @@ -388,7 +388,7 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, } out: - mutex_unlock(&udev->mutex); + up(&udev->sem); return retval; } @@ -439,7 +439,7 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg) udev = file->private_data; - retval = mutex_lock_interruptible(&udev->mutex); + retval = down_interruptible(&udev->sem); if (retval) return retval; @@ -589,7 +589,7 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } out: - mutex_unlock(&udev->mutex); + up(&udev->sem); return retval; } diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index e4e5be111..4b415d9b0 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -273,18 +273,6 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] = { { KE_END, 0 } }; -static struct key_entry keymap_fujitsu_n3510[] = { - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_KEY, 0x36, KEY_WWW }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x71, KEY_STOPCD }, - { KE_KEY, 0x72, KEY_PLAYPAUSE }, - { KE_KEY, 0x74, KEY_REWIND }, - { KE_KEY, 0x78, KEY_FORWARD }, - { KE_END, 0 } -}; - static struct key_entry keymap_wistron_ms2141[] = { { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, @@ -318,16 +306,6 @@ static struct key_entry keymap_acer_travelmate_240[] = { { KE_END, 0 } }; -static struct key_entry keymap_aopen_1559as[] = { - { KE_KEY, 0x01, KEY_HELP }, - { KE_KEY, 0x06, KEY_PROG3 }, - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_WIFI, 0x30, 0 }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, -}; - /* * If your machine is not here (which is currently rather likely), please send * a list of buttons and their key codes (reported when loading this module @@ -343,24 +321,6 @@ static struct dmi_system_id dmi_ids[] = { }, .driver_data = keymap_fs_amilo_pro_v2000 }, - { - .callback = dmi_matched, - .ident = "Fujitsu-Siemens Amilo M7400", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), - }, - .driver_data = keymap_fs_amilo_pro_v2000 - }, - { - .callback = dmi_matched, - .ident = "Fujitsu N3510", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), - DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), - }, - .driver_data = keymap_fujitsu_n3510 - }, { .callback = dmi_matched, .ident = "Acer Aspire 1500", @@ -379,15 +339,6 @@ static struct dmi_system_id dmi_ids[] = { }, .driver_data = keymap_acer_travelmate_240 }, - { - .callback = dmi_matched, - .ident = "AOpen 1559AS", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), - DMI_MATCH(DMI_BOARD_NAME, "E2U"), - }, - .driver_data = keymap_aopen_1559as - }, { NULL, } }; diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a0e2e797c..2141501e9 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -100,8 +100,8 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs) } if (priv->i->flags & ALPS_OLDPROTO) { - left = packet[2] & 0x10; - right = packet[2] & 0x08; + left = packet[2] & 0x08; + right = packet[2] & 0x10; middle = 0; x = packet[1] | ((packet[0] & 0x07) << 7); y = packet[4] | ((packet[3] & 0x07) << 7); diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index bc22849c6..c2bf2ed07 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c @@ -196,7 +196,7 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio, hil_packet packet; int idx; - ptr = (struct hil_ptr *)serio->private; + ptr = serio_get_drvdata(serio); if (ptr == NULL) { BUG(); return IRQ_HANDLED; @@ -227,7 +227,7 @@ static void hil_ptr_disconnect(struct serio *serio) { struct hil_ptr *ptr; - ptr = (struct hil_ptr *)serio->private; + ptr = serio_get_drvdata(serio); if (ptr == NULL) { BUG(); return; @@ -238,21 +238,19 @@ static void hil_ptr_disconnect(struct serio *serio) kfree(ptr); } -static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver) +static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) { struct hil_ptr *ptr; char *txt; unsigned int i, naxsets, btntype; uint8_t did, *idd; - if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return; - - if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return; + if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM; memset(ptr, 0, sizeof(struct hil_ptr)); if (serio_open(serio, driver)) goto bail0; - serio->private = ptr; + serio_set_drvdata(serio, ptr); ptr->serio = serio; ptr->dev.private = ptr; @@ -380,23 +378,34 @@ static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver) (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", did); - return; + return 0; bail1: serio_close(serio); bail0: kfree(ptr); - return; + serio_set_drvdata(serio, NULL); + return -ENODEV; } +static struct serio_device_id hil_ptr_ids[] = { + { + .type = SERIO_HIL_MLC, + .proto = SERIO_HIL, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; static struct serio_driver hil_ptr_serio_driver = { .driver = { .name = "hil_ptr", }, .description = "HP HIL mouse/tablet driver", - .connect = hil_ptr_connect, - .disconnect = hil_ptr_disconnect, - .interrupt = hil_ptr_interrupt + .id_table = hil_ptr_ids, + .connect = hil_ptr_connect, + .disconnect = hil_ptr_disconnect, + .interrupt = hil_ptr_interrupt }; static int __init hil_ptr_init(void) diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index c14395ba7..5ccc3ef3b 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -21,36 +21,12 @@ #include "lifebook.h" static struct dmi_system_id lifebook_dmi_table[] = { - { - .ident = "LifeBook B", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), - }, - }, { .ident = "Lifebook B", .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), }, }, - { - .ident = "Lifebook B213x/B2150", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), - }, - }, - { - .ident = "Zephyr", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), - }, - }, - { - .ident = "CF-18", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), - }, - }, { .ident = "Lifebook B142", .matches = { diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 2f0d28840..54b696cfe 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -238,8 +238,7 @@ static struct ps2pp_info *get_model_info(unsigned char model) { 100, PS2PP_KIND_MX, /* MX510 */ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, - { 111, PS2PP_KIND_MX, /* MX300 */ - PS2PP_WHEEL | PS2PP_EXTRA_BTN | PS2PP_TASK_BTN }, + { 111, PS2PP_KIND_MX, PS2PP_WHEEL | PS2PP_SIDE_BTN }, /* MX300 reports task button as side */ { 112, PS2PP_KIND_MX, /* MX500 */ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 136321a2c..b2bed1acf 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -20,8 +20,6 @@ #include #include #include -#include - #include "psmouse.h" #include "synaptics.h" #include "logips2pp.h" @@ -100,13 +98,13 @@ __obsolete_setup("psmouse_resetafter="); __obsolete_setup("psmouse_rate="); /* - * psmouse_mutex protects all operations changing state of mouse + * psmouse_sem protects all operations changing state of mouse * (connecting, disconnecting, changing rate or resolution via * sysfs). We could use a per-device semaphore but since there * rarely more than one PS/2 mouse connected and since semaphore * is taken in "slow" paths it is not worth it. */ -static DEFINE_MUTEX(psmouse_mutex); +static DECLARE_MUTEX(psmouse_sem); static struct workqueue_struct *kpsmoused_wq; @@ -872,7 +870,7 @@ static void psmouse_resync(void *p) int failed = 0, enabled = 0; int i; - mutex_lock(&psmouse_mutex); + down(&psmouse_sem); if (psmouse->state != PSMOUSE_RESYNCING) goto out; @@ -952,7 +950,7 @@ static void psmouse_resync(void *p) if (parent) psmouse_activate(parent); out: - mutex_unlock(&psmouse_mutex); + up(&psmouse_sem); } /* @@ -978,14 +976,14 @@ static void psmouse_disconnect(struct serio *serio) sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group); - mutex_lock(&psmouse_mutex); + down(&psmouse_sem); psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); /* make sure we don't have a resync in progress */ - mutex_unlock(&psmouse_mutex); + up(&psmouse_sem); flush_workqueue(kpsmoused_wq); - mutex_lock(&psmouse_mutex); + down(&psmouse_sem); if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { parent = serio_get_drvdata(serio->parent); @@ -1008,7 +1006,7 @@ static void psmouse_disconnect(struct serio *serio) if (parent) psmouse_activate(parent); - mutex_unlock(&psmouse_mutex); + up(&psmouse_sem); } static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) @@ -1080,7 +1078,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int retval = -ENOMEM; - mutex_lock(&psmouse_mutex); + down(&psmouse_sem); /* * If this is a pass-through port deactivate parent so the device @@ -1148,7 +1146,7 @@ out: if (parent) psmouse_activate(parent); - mutex_unlock(&psmouse_mutex); + up(&psmouse_sem); return retval; } @@ -1165,7 +1163,7 @@ static int psmouse_reconnect(struct serio *serio) return -1; } - mutex_lock(&psmouse_mutex); + down(&psmouse_sem); if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { parent = serio_get_drvdata(serio->parent); @@ -1199,7 +1197,7 @@ out: if (parent) psmouse_activate(parent); - mutex_unlock(&psmouse_mutex); + up(&psmouse_sem); return rc; } @@ -1277,7 +1275,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev goto out_unpin; } - retval = mutex_lock_interruptible(&psmouse_mutex); + retval = down_interruptible(&psmouse_sem); if (retval) goto out_unpin; @@ -1285,7 +1283,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev if (psmouse->state == PSMOUSE_IGNORE) { retval = -ENODEV; - goto out_unlock; + goto out_up; } if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { @@ -1303,8 +1301,8 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev if (parent) psmouse_activate(parent); - out_unlock: - mutex_unlock(&psmouse_mutex); + out_up: + up(&psmouse_sem); out_unpin: serio_unpin_driver(serio); return retval; @@ -1361,11 +1359,11 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co return -EIO; } - mutex_unlock(&psmouse_mutex); + up(&psmouse_sem); serio_unpin_driver(serio); serio_unregister_child_port(serio); serio_pin_driver_uninterruptible(serio); - mutex_lock(&psmouse_mutex); + down(&psmouse_sem); if (serio->drv != &psmouse_drv) { input_free_device(new_dev); diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ad5d0a85e..2051bec2c 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -247,12 +247,14 @@ static void synaptics_pt_create(struct psmouse *psmouse) { struct serio *serio; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (!serio) { printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n"); return; } + memset(serio, 0, sizeof(struct serio)); + serio->id.type = SERIO_PS_PSTHRU; strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); @@ -603,21 +605,14 @@ static struct dmi_system_id toshiba_dmi_table[] = { .ident = "Toshiba Satellite", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), + DMI_MATCH(DMI_PRODUCT_NAME , "Satellite"), }, }, { .ident = "Toshiba Dynabook", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"), - }, - }, - { - .ident = "Toshiba Portege M300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), + DMI_MATCH(DMI_PRODUCT_NAME , "dynabook"), }, }, { } @@ -628,9 +623,10 @@ int synaptics_init(struct psmouse *psmouse) { struct synaptics_data *priv; - psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); + psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL); if (!priv) return -1; + memset(priv, 0, sizeof(struct synaptics_data)); if (synaptics_query_hardware(psmouse)) { printk(KERN_ERR "Unable to query Synaptics hardware.\n"); diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index b685a5079..9abed18d2 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -412,8 +412,9 @@ static int mousedev_open(struct inode * inode, struct file * file) if (i >= MOUSEDEV_MINORS || !mousedev_table[i]) return -ENODEV; - if (!(list = kzalloc(sizeof(struct mousedev_list), GFP_KERNEL))) + if (!(list = kmalloc(sizeof(struct mousedev_list), GFP_KERNEL))) return -ENOMEM; + memset(list, 0, sizeof(struct mousedev_list)); spin_lock_init(&list->packet_lock); list->pos_x = xres / 2; @@ -625,8 +626,9 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru return NULL; } - if (!(mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL))) + if (!(mousedev = kmalloc(sizeof(struct mousedev), GFP_KERNEL))) return NULL; + memset(mousedev, 0, sizeof(struct mousedev)); INIT_LIST_HEAD(&mousedev->list); init_waitqueue_head(&mousedev->wait); diff --git a/drivers/input/power.c b/drivers/input/power.c index 526e60706..bfc5c63eb 100644 --- a/drivers/input/power.c +++ b/drivers/input/power.c @@ -103,8 +103,9 @@ static struct input_handle *power_connect(struct input_handler *handler, { struct input_handle *handle; - if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) + if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) return NULL; + memset(handle, 0, sizeof(struct input_handle)); handle->dev = dev; handle->handler = handler; diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index c0b1e4bec..a7b0de0f9 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -1,7 +1,7 @@ /* * drivers/input/serio/gscps2.c * - * Copyright (c) 2004-2006 Helge Deller + * Copyright (c) 2004 Helge Deller * Copyright (c) 2002 Laurent Canet * Copyright (c) 2002 Thibaut Varene * @@ -354,7 +354,7 @@ static int __init gscps2_probe(struct parisc_device *dev) memset(serio, 0, sizeof(struct serio)); ps2port->port = serio; ps2port->padev = dev; - ps2port->addr = ioremap_nocache(hpa, GSC_STATUS + 4); + ps2port->addr = ioremap(hpa, GSC_STATUS + 4); spin_lock_init(&ps2port->lock); gscps2_reset(ps2port); diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index c243cb6fd..570420496 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -801,7 +801,8 @@ static int hil_mlc_serio_open(struct serio *serio) { struct hil_mlc_serio_map *map; struct hil_mlc *mlc; - if (serio->private != NULL) return -EBUSY; + if (serio_get_drvdata(serio) != NULL) + return -EBUSY; map = serio->port_data; if (map == NULL) { @@ -832,11 +833,18 @@ static void hil_mlc_serio_close(struct serio *serio) { return; } - serio->private = NULL; + serio_set_drvdata(serio, NULL); serio->drv = NULL; /* TODO wake up interruptable */ } +static struct serio_device_id hil_mlc_serio_id = { + .type = SERIO_HIL_MLC, + .proto = SERIO_HIL, + .extra = SERIO_ANY, + .id = SERIO_ANY, +}; + int hil_mlc_register(hil_mlc *mlc) { int i; unsigned long flags; @@ -867,7 +875,7 @@ int hil_mlc_register(hil_mlc *mlc) { mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL); mlc->serio[i] = mlc_serio; memset(mlc_serio, 0, sizeof(*mlc_serio)); - mlc_serio->type = SERIO_HIL | SERIO_HIL_MLC; + mlc_serio->id = hil_mlc_serio_id; mlc_serio->write = hil_mlc_serio_write; mlc_serio->open = hil_mlc_serio_open; mlc_serio->close = hil_mlc_serio_close; diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index e3c44ffae..1c9426fd5 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c @@ -40,6 +40,7 @@ #include #include #include +#include #define PREFIX "HP SDC MLC: " diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h index cc21914fb..9a9221644 100644 --- a/drivers/input/serio/i8042-io.h +++ b/drivers/input/serio/i8042-io.h @@ -67,14 +67,14 @@ static inline int i8042_platform_init(void) * On some platforms touching the i8042 data register region can do really * bad things. Because of this the region is always reserved on such boxes. */ -#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC_MERGE) +#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC64) if (!request_region(I8042_DATA_REG, 16, "i8042")) return -EBUSY; #endif i8042_reset = 1; -#if defined(CONFIG_PPC_MERGE) +#if defined(CONFIG_PPC64) if (check_legacy_ioport(I8042_DATA_REG)) return -EBUSY; if (!request_region(I8042_DATA_REG, 16, "i8042")) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 0487ecbb8..a4c6f3522 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -84,6 +84,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), }, }, + { + .ident = "OQO Model 01", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "OQO"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "00"), + }, + }, { } }; @@ -130,6 +138,20 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), }, }, + { + .ident = "Fujitsu-Siemens Lifebook T3010", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), + }, + }, + { + .ident = "Fujitsu-Siemens Lifebook E4010", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), + }, + }, { .ident = "Toshiba P10", .matches = { @@ -137,6 +159,27 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), }, }, + { + .ident = "Alienware Sentia", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), + }, + }, + { + .ident = "Sharp Actius MM20", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), + DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), + }, + }, + { + .ident = "Sony Vaio FS-115b", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), + }, + }, { } }; @@ -242,9 +285,10 @@ static void i8042_pnp_exit(void) } } -static int i8042_pnp_init(void) +static int __init i8042_pnp_init(void) { - int result_kbd, result_aux; + int result_kbd = 0, result_aux = 0; + char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; if (i8042_nopnp) { printk(KERN_INFO "i8042: PNP detection disabled\n"); @@ -253,6 +297,7 @@ static int i8042_pnp_init(void) if ((result_kbd = pnp_register_driver(&i8042_pnp_kbd_driver)) >= 0) i8042_pnp_kbd_registered = 1; + if ((result_aux = pnp_register_driver(&i8042_pnp_aux_driver)) >= 0) i8042_pnp_aux_registered = 1; @@ -266,6 +311,27 @@ static int i8042_pnp_init(void) #endif } + if (result_kbd > 0) + snprintf(kbd_irq_str, sizeof(kbd_irq_str), + "%d", i8042_pnp_kbd_irq); + if (result_aux > 0) + snprintf(aux_irq_str, sizeof(aux_irq_str), + "%d", i8042_pnp_aux_irq); + + printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", + i8042_pnp_kbd_name, (result_kbd > 0 && result_aux > 0) ? "," : "", + i8042_pnp_aux_name, + i8042_pnp_data_reg, i8042_pnp_command_reg, + kbd_irq_str, (result_kbd > 0 && result_aux > 0) ? "," : "", + aux_irq_str); + +#if defined(__ia64__) + if (result_kbd <= 0) + i8042_nokbd = 1; + if (result_aux <= 0) + i8042_noaux = 1; +#endif + if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && i8042_pnp_data_reg != i8042_data_reg) || !i8042_pnp_data_reg) { printk(KERN_WARNING "PNP: PS/2 controller has invalid data port %#x; using default %#x\n", @@ -280,53 +346,47 @@ static int i8042_pnp_init(void) i8042_pnp_command_reg = i8042_command_reg; } - if (!i8042_pnp_kbd_irq) { - printk(KERN_WARNING "PNP: PS/2 controller doesn't have KBD irq; using default %#x\n", i8042_kbd_irq); + if (!i8042_nokbd && !i8042_pnp_kbd_irq) { + printk(KERN_WARNING "PNP: PS/2 controller doesn't have KBD irq; using default %d\n", i8042_kbd_irq); i8042_pnp_kbd_irq = i8042_kbd_irq; } - if (!i8042_pnp_aux_irq) { - printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq); + if (!i8042_noaux && !i8042_pnp_aux_irq) { + printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %d\n", i8042_aux_irq); i8042_pnp_aux_irq = i8042_aux_irq; } -#if defined(__ia64__) - if (result_aux <= 0) - i8042_noaux = 1; -#endif - i8042_data_reg = i8042_pnp_data_reg; i8042_command_reg = i8042_pnp_command_reg; i8042_kbd_irq = i8042_pnp_kbd_irq; i8042_aux_irq = i8042_pnp_aux_irq; - printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %d%s%d\n", - i8042_pnp_kbd_name, (result_kbd > 0 && result_aux > 0) ? "," : "", i8042_pnp_aux_name, - i8042_data_reg, i8042_command_reg, i8042_kbd_irq, - (result_aux > 0) ? "," : "", i8042_aux_irq); - return 0; } +#else +static inline int i8042_pnp_init(void) { return 0; } +static inline void i8042_pnp_exit(void) { } #endif -static inline int i8042_platform_init(void) +static int __init i8042_platform_init(void) { + int retval; + /* * On ix86 platforms touching the i8042 data register region can do really * bad things. Because of this the region is always reserved on ix86 boxes. * * if (!request_region(I8042_DATA_REG, 16, "i8042")) - * return -1; + * return -EBUSY; */ i8042_kbd_irq = I8042_MAP_IRQ(1); i8042_aux_irq = I8042_MAP_IRQ(12); -#ifdef CONFIG_PNP - if (i8042_pnp_init()) - return -1; -#endif + retval = i8042_pnp_init(); + if (retval) + return retval; #if defined(__ia64__) i8042_reset = 1; @@ -340,14 +400,12 @@ static inline int i8042_platform_init(void) i8042_nomux = 1; #endif - return 0; + return retval; } static inline void i8042_platform_exit(void) { -#ifdef CONFIG_PNP i8042_pnp_exit(); -#endif } #endif /* _I8042_X86IA64IO_H */ diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 79c97f94b..d4c990f7c 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -84,7 +84,7 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) maxbytes = sizeof(ps2dev->cmdbuf); } - mutex_lock(&ps2dev->cmd_mutex); + down(&ps2dev->cmd_sem); serio_pause_rx(ps2dev->serio); ps2dev->flags = PS2_FLAG_CMD; @@ -94,7 +94,7 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) wait_event_timeout(ps2dev->wait, !(ps2dev->flags & PS2_FLAG_CMD), msecs_to_jiffies(timeout)); - mutex_unlock(&ps2dev->cmd_mutex); + up(&ps2dev->cmd_sem); } /* @@ -177,7 +177,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) return -1; } - mutex_lock(&ps2dev->cmd_mutex); + down(&ps2dev->cmd_sem); serio_pause_rx(ps2dev->serio); ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; @@ -229,7 +229,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) ps2dev->flags = 0; serio_continue_rx(ps2dev->serio); - mutex_unlock(&ps2dev->cmd_mutex); + up(&ps2dev->cmd_sem); return rc; } @@ -281,7 +281,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman void ps2_init(struct ps2dev *ps2dev, struct serio *serio) { - mutex_init(&ps2dev->cmd_mutex); + init_MUTEX(&ps2dev->cmd_sem); init_waitqueue_head(&ps2dev->wait); ps2dev->serio = serio; } diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index a5c1fb3a4..1d15c2819 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c @@ -171,8 +171,9 @@ static struct serio * __init parkbd_allocate_serio(void) { struct serio *serio; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { + memset(serio, 0, sizeof(struct serio)); serio->id.type = parkbd_mode; serio->write = parkbd_write, strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name)); diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 513d37fc1..a3bd11589 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -111,10 +111,11 @@ static int __devinit rpckbd_probe(struct platform_device *dev) { struct serio *serio; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (!serio) return -ENOMEM; + memset(serio, 0, sizeof(struct serio)); serio->id.type = SERIO_8042; serio->write = rpckbd_write; serio->open = rpckbd_open; diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 6521034bc..2f76813c3 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -34,7 +34,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Serio abstraction core"); @@ -53,10 +52,10 @@ EXPORT_SYMBOL(serio_rescan); EXPORT_SYMBOL(serio_reconnect); /* - * serio_mutex protects entire serio subsystem and is taken every time + * serio_sem protects entire serio subsystem and is taken every time * serio port or driver registrered or unregistered. */ -static DEFINE_MUTEX(serio_mutex); +static DECLARE_MUTEX(serio_sem); static LIST_HEAD(serio_list); @@ -71,9 +70,9 @@ static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) { int retval; - mutex_lock(&serio->drv_mutex); + down(&serio->drv_sem); retval = drv->connect(serio, drv); - mutex_unlock(&serio->drv_mutex); + up(&serio->drv_sem); return retval; } @@ -82,20 +81,20 @@ static int serio_reconnect_driver(struct serio *serio) { int retval = -1; - mutex_lock(&serio->drv_mutex); + down(&serio->drv_sem); if (serio->drv && serio->drv->reconnect) retval = serio->drv->reconnect(serio); - mutex_unlock(&serio->drv_mutex); + up(&serio->drv_sem); return retval; } static void serio_disconnect_driver(struct serio *serio) { - mutex_lock(&serio->drv_mutex); + down(&serio->drv_sem); if (serio->drv) serio->drv->disconnect(serio); - mutex_unlock(&serio->drv_mutex); + up(&serio->drv_sem); } static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) @@ -196,7 +195,6 @@ static void serio_queue_event(void *object, struct module *owner, if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { if (!try_module_get(owner)) { printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type); - kfree(event); goto out; } @@ -274,7 +272,7 @@ static void serio_handle_event(void) struct serio_event *event; struct serio_driver *serio_drv; - mutex_lock(&serio_mutex); + down(&serio_sem); /* * Note that we handle only one event here to give swsusp @@ -316,7 +314,7 @@ static void serio_handle_event(void) serio_free_event(event); } - mutex_unlock(&serio_mutex); + up(&serio_sem); } /* @@ -451,7 +449,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * struct device_driver *drv; int retval; - retval = mutex_lock_interruptible(&serio_mutex); + retval = down_interruptible(&serio_sem); if (retval) return retval; @@ -471,7 +469,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * retval = -EINVAL; } - mutex_unlock(&serio_mutex); + up(&serio_sem); return retval; } @@ -526,7 +524,7 @@ static void serio_init_port(struct serio *serio) __module_get(THIS_MODULE); spin_lock_init(&serio->lock); - mutex_init(&serio->drv_mutex); + init_MUTEX(&serio->drv_sem); device_initialize(&serio->dev); snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), "serio%ld", (long)atomic_inc_return(&serio_no) - 1); @@ -663,10 +661,10 @@ void __serio_register_port(struct serio *serio, struct module *owner) */ void serio_unregister_port(struct serio *serio) { - mutex_lock(&serio_mutex); + down(&serio_sem); serio_disconnect_port(serio); serio_destroy_port(serio); - mutex_unlock(&serio_mutex); + up(&serio_sem); } /* @@ -674,17 +672,17 @@ void serio_unregister_port(struct serio *serio) */ void serio_unregister_child_port(struct serio *serio) { - mutex_lock(&serio_mutex); + down(&serio_sem); if (serio->child) { serio_disconnect_port(serio->child); serio_destroy_port(serio->child); } - mutex_unlock(&serio_mutex); + up(&serio_sem); } /* * Submits register request to kseriod for subsequent execution. - * Can be used when it is not obvious whether the serio_mutex is + * Can be used when it is not obvious whether the serio_sem is * taken or not and when delayed execution is feasible. */ void __serio_unregister_port_delayed(struct serio *serio, struct module *owner) @@ -767,7 +765,7 @@ void serio_unregister_driver(struct serio_driver *drv) { struct serio *serio; - mutex_lock(&serio_mutex); + down(&serio_sem); drv->manual_bind = 1; /* so serio_find_driver ignores it */ start_over: @@ -781,7 +779,7 @@ start_over: } driver_unregister(&drv->driver); - mutex_unlock(&serio_mutex); + up(&serio_sem); } static void serio_set_drv(struct serio *serio, struct serio_driver *drv) @@ -860,7 +858,7 @@ static int serio_resume(struct device *dev) return 0; } -/* called from serio_driver->connect/disconnect methods under serio_mutex */ +/* called from serio_driver->connect/disconnect methods under serio_sem */ int serio_open(struct serio *serio, struct serio_driver *drv) { serio_set_drv(serio, drv); @@ -872,7 +870,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv) return 0; } -/* called from serio_driver->connect/disconnect methods under serio_mutex */ +/* called from serio_driver->connect/disconnect methods under serio_sem */ void serio_close(struct serio *serio) { if (serio->close) @@ -925,5 +923,5 @@ static void __exit serio_exit(void) kthread_stop(serio_task); } -subsys_initcall(serio_init); +module_init(serio_init); module_exit(serio_exit); diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 5a2703b53..47e08de18 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -19,7 +19,6 @@ #include #include #include -#include #define DRIVER_DESC "Raw serio driver" @@ -47,7 +46,7 @@ struct serio_raw_list { struct list_head node; }; -static DEFINE_MUTEX(serio_raw_mutex); +static DECLARE_MUTEX(serio_raw_sem); static LIST_HEAD(serio_raw_list); static unsigned int serio_raw_no; @@ -82,7 +81,7 @@ static int serio_raw_open(struct inode *inode, struct file *file) struct serio_raw_list *list; int retval = 0; - retval = mutex_lock_interruptible(&serio_raw_mutex); + retval = down_interruptible(&serio_raw_sem); if (retval) return retval; @@ -96,11 +95,12 @@ static int serio_raw_open(struct inode *inode, struct file *file) goto out; } - if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { + if (!(list = kmalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { retval = -ENOMEM; goto out; } + memset(list, 0, sizeof(struct serio_raw_list)); list->serio_raw = serio_raw; file->private_data = list; @@ -108,7 +108,7 @@ static int serio_raw_open(struct inode *inode, struct file *file) list_add_tail(&list->node, &serio_raw->list); out: - mutex_unlock(&serio_raw_mutex); + up(&serio_raw_sem); return retval; } @@ -130,12 +130,12 @@ static int serio_raw_release(struct inode *inode, struct file *file) struct serio_raw_list *list = file->private_data; struct serio_raw *serio_raw = list->serio_raw; - mutex_lock(&serio_raw_mutex); + down(&serio_raw_sem); serio_raw_fasync(-1, file, 0); serio_raw_cleanup(serio_raw); - mutex_unlock(&serio_raw_mutex); + up(&serio_raw_sem); return 0; } @@ -194,7 +194,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, siz int retval; unsigned char c; - retval = mutex_lock_interruptible(&serio_raw_mutex); + retval = down_interruptible(&serio_raw_sem); if (retval) return retval; @@ -219,7 +219,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, siz }; out: - mutex_unlock(&serio_raw_mutex); + up(&serio_raw_sem); return written; } @@ -275,13 +275,14 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) struct serio_raw *serio_raw; int err; - if (!(serio_raw = kzalloc(sizeof(struct serio_raw), GFP_KERNEL))) { + if (!(serio_raw = kmalloc(sizeof(struct serio_raw), GFP_KERNEL))) { printk(KERN_ERR "serio_raw.c: can't allocate memory for a device\n"); return -ENOMEM; } - mutex_lock(&serio_raw_mutex); + down(&serio_raw_sem); + memset(serio_raw, 0, sizeof(struct serio_raw)); snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++); serio_raw->refcnt = 1; serio_raw->serio = serio; @@ -324,7 +325,7 @@ out_free: serio_set_drvdata(serio, NULL); kfree(serio_raw); out: - mutex_unlock(&serio_raw_mutex); + up(&serio_raw_sem); return err; } @@ -349,7 +350,7 @@ static void serio_raw_disconnect(struct serio *serio) { struct serio_raw *serio_raw; - mutex_lock(&serio_raw_mutex); + down(&serio_raw_sem); serio_raw = serio_get_drvdata(serio); @@ -360,7 +361,7 @@ static void serio_raw_disconnect(struct serio *serio) if (!serio_raw_cleanup(serio_raw)) wake_up_interruptible(&serio_raw->wait); - mutex_unlock(&serio_raw_mutex); + up(&serio_raw_sem); } static struct serio_device_id serio_raw_serio_ids[] = { diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 161afddd0..8c12a974b 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -2,8 +2,6 @@ * ADS7846 based touchscreen and sensor driver * * Copyright (c) 2005 David Brownell - * Copyright (c) 2006 Nokia Corporation - * Various changes: Imre Deak * * Using code from: * - corgi_ts.c @@ -25,7 +23,6 @@ #include #include #include -#include #ifdef CONFIG_ARM #include @@ -36,22 +33,17 @@ /* - * This code has been heavily tested on a Nokia 770, and lightly - * tested on other ads7846 devices (OSK/Mistral, Lubbock). + * This code has been lightly tested on an ads7846. * Support for ads7843 and ads7845 has only been stubbed in. * - * IRQ handling needs a workaround because of a shortcoming in handling - * edge triggered IRQs on some platforms like the OMAP1/2. These - * platforms don't handle the ARM lazy IRQ disabling properly, thus we - * have to maintain our own SW IRQ disabled status. This should be - * removed as soon as the affected platform's IRQ handling is fixed. + * Not yet done: investigate the values reported. Are x/y/pressure + * event values sane enough for X11? How accurate are the temperature + * and voltage readings? (System-specific calibration should support + * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.) * * app note sbaa036 talks in more detail about accurate sampling... * that ought to help in situations like LCDs inducing noise (which * can also be helped by using synch signals) and more generally. - * This driver tries to utilize the measures described in the app - * note. The strength of filtering can be set in the board-* specific - * files. */ #define TS_POLL_PERIOD msecs_to_jiffies(10) @@ -68,7 +60,6 @@ struct ts_event { __be16 x; __be16 y; __be16 z1, z2; - int ignore; }; struct ads7846 { @@ -79,23 +70,12 @@ struct ads7846 { u16 model; u16 vref_delay_usecs; u16 x_plate_ohms; - u16 pressure_max; - u8 read_x, read_y, read_z1, read_z2, pwrdown; - u16 dummy; /* for the pwrdown read */ + u8 read_x, read_y, read_z1, read_z2; struct ts_event tc; - struct spi_transfer xfer[10]; - struct spi_message msg[5]; - struct spi_message *last_msg; - int msg_idx; - int read_cnt; - int read_rep; - int last_read; - - u16 debounce_max; - u16 debounce_tol; - u16 debounce_rep; + struct spi_transfer xfer[8]; + struct spi_message msg; spinlock_t lock; struct timer_list timer; /* P: lock */ @@ -103,9 +83,6 @@ struct ads7846 { unsigned pending:1; /* P: lock */ // FIXME remove "irq_disabled" unsigned irq_disabled:1; /* P: lock */ - unsigned disabled:1; - - int (*get_pendown_state)(void); }; /* leave chip selected when we're done, for quicker re-select? */ @@ -147,9 +124,7 @@ struct ads7846 { #define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON) #define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON) #define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON) - -#define READ_X (READ_12BIT_DFR(x) | ADS_PD10_ADC_ON) -#define PWRDOWN (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /* LAST */ +#define READ_X (READ_12BIT_DFR(x) | ADS_PD10_PDOWN) /* LAST */ /* single-ended samples need to first power up reference voltage; * we leave both ADC and VREF powered @@ -176,15 +151,6 @@ struct ser_req { struct spi_transfer xfer[6]; }; -static void ads7846_enable(struct ads7846 *ts); -static void ads7846_disable(struct ads7846 *ts); - -static int device_suspended(struct device *dev) -{ - struct ads7846 *ts = dev_get_drvdata(dev); - return dev->power.power_state.event != PM_EVENT_ON || ts->disabled; -} - static int ads7846_read12_ser(struct device *dev, unsigned command) { struct spi_device *spi = to_spi_device(dev); @@ -197,7 +163,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) if (!req) return -ENOMEM; - spi_message_init(&req->msg); + INIT_LIST_HEAD(&req->msg.transfers); /* activate reference, so it has time to settle; */ req->ref_on = REF_ON; @@ -237,21 +203,16 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) for (i = 0; i < 6; i++) spi_message_add_tail(&req->xfer[i], &req->msg); - ts->irq_disabled = 1; disable_irq(spi->irq); status = spi_sync(spi, &req->msg); - ts->irq_disabled = 0; enable_irq(spi->irq); if (req->msg.status) status = req->msg.status; - - /* on-wire is a must-ignore bit, a BE12 value, then padding */ sample = be16_to_cpu(req->sample); - sample = sample >> 3; - sample &= 0x0fff; - + sample = sample >> 4; kfree(req); + return status ? status : sample; } @@ -271,52 +232,6 @@ SHOW(temp1) SHOW(vaux) SHOW(vbatt) -static int is_pen_down(struct device *dev) -{ - struct ads7846 *ts = dev_get_drvdata(dev); - - return ts->pendown; -} - -static ssize_t ads7846_pen_down_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", is_pen_down(dev)); -} - -static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); - -static ssize_t ads7846_disable_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ads7846 *ts = dev_get_drvdata(dev); - - return sprintf(buf, "%u\n", ts->disabled); -} - -static ssize_t ads7846_disable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct ads7846 *ts = dev_get_drvdata(dev); - char *endp; - int i; - - i = simple_strtoul(buf, &endp, 10); - spin_lock_irq(&ts->lock); - - if (i) - ads7846_disable(ts); - else - ads7846_enable(ts); - - spin_unlock_irq(&ts->lock); - - return count; -} - -static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); - /*--------------------------------------------------------------------------*/ /* @@ -336,19 +251,19 @@ static void ads7846_rx(void *ads) u16 x, y, z1, z2; unsigned long flags; - /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; - * built from two 8 bit values written msb-first. + /* adjust: 12 bit samples (left aligned), built from + * two 8 bit values writen msb-first. */ - x = (be16_to_cpu(ts->tc.x) >> 3) & 0x0fff; - y = (be16_to_cpu(ts->tc.y) >> 3) & 0x0fff; - z1 = (be16_to_cpu(ts->tc.z1) >> 3) & 0x0fff; - z2 = (be16_to_cpu(ts->tc.z2) >> 3) & 0x0fff; + x = be16_to_cpu(ts->tc.x) >> 4; + y = be16_to_cpu(ts->tc.y) >> 4; + z1 = be16_to_cpu(ts->tc.z1) >> 4; + z2 = be16_to_cpu(ts->tc.z2) >> 4; /* range filtering */ if (x == MAX_12BIT) x = 0; - if (likely(x && z1 && !device_suspended(&ts->spi->dev))) { + if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) { /* compute touch pressure resistance using equation #2 */ Rt = z2; Rt -= z1; @@ -359,14 +274,6 @@ static void ads7846_rx(void *ads) } else Rt = 0; - /* Sample found inconsistent by debouncing or pressure is beyond - * the maximum. Don't report it to user space, repeat at least - * once more the measurement */ - if (ts->tc.ignore || Rt > ts->pressure_max) { - mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); - return; - } - /* NOTE: "pendown" is inferred from pressure; we don't rely on * being able to check nPENIRQ status, or "friendly" trigger modes * (both-edges is much better than just-falling or low-level). @@ -388,13 +295,11 @@ static void ads7846_rx(void *ads) if (Rt) { input_report_abs(input_dev, ABS_X, x); input_report_abs(input_dev, ABS_Y, y); + input_report_abs(input_dev, ABS_PRESSURE, Rt); sync = 1; } - - if (sync) { - input_report_abs(input_dev, ABS_PRESSURE, Rt); + if (sync) input_sync(input_dev); - } #ifdef VERBOSE if (Rt || ts->pendown) @@ -402,137 +307,80 @@ static void ads7846_rx(void *ads) x, y, Rt, Rt ? "" : " UP"); #endif + /* don't retrigger while we're suspended */ spin_lock_irqsave(&ts->lock, flags); ts->pendown = (Rt != 0); - mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); - - spin_unlock_irqrestore(&ts->lock, flags); -} - -static void ads7846_debounce(void *ads) -{ - struct ads7846 *ts = ads; - struct spi_message *m; - struct spi_transfer *t; - int val; - int status; - - m = &ts->msg[ts->msg_idx]; - t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); - val = (be16_to_cpu(*(__be16 *)t->rx_buf) >> 3) & 0x0fff; - if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) { - /* Repeat it, if this was the first read or the read - * wasn't consistent enough. */ - if (ts->read_cnt < ts->debounce_max) { - ts->last_read = val; - ts->read_cnt++; - } else { - /* Maximum number of debouncing reached and still - * not enough number of consistent readings. Abort - * the whole sample, repeat it in the next sampling - * period. - */ - ts->tc.ignore = 1; - ts->read_cnt = 0; - /* Last message will contain ads7846_rx() as the - * completion function. - */ - m = ts->last_msg; - } - /* Start over collecting consistent readings. */ - ts->read_rep = 0; - } else { - if (++ts->read_rep > ts->debounce_rep) { - /* Got a good reading for this coordinate, - * go for the next one. */ - ts->tc.ignore = 0; - ts->msg_idx++; - ts->read_cnt = 0; - ts->read_rep = 0; - m++; - } else - /* Read more values that are consistent. */ - ts->read_cnt++; - } - status = spi_async(ts->spi, m); - if (status) - dev_err(&ts->spi->dev, "spi_async --> %d\n", - status); -} - -static void ads7846_timer(unsigned long handle) -{ - struct ads7846 *ts = (void *)handle; - int status = 0; - - spin_lock_irq(&ts->lock); + ts->pending = 0; - if (unlikely(ts->msg_idx && !ts->pendown)) { - /* measurement cycle ended */ - if (!device_suspended(&ts->spi->dev)) { + if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) { + if (ts->pendown) + mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); + else if (ts->irq_disabled) { ts->irq_disabled = 0; enable_irq(ts->spi->irq); } - ts->pending = 0; - ts->msg_idx = 0; - } else { - /* pen is still down, continue with the measurement */ - ts->msg_idx = 0; - status = spi_async(ts->spi, &ts->msg[0]); - if (status) - dev_err(&ts->spi->dev, "spi_async --> %d\n", status); } - spin_unlock_irq(&ts->lock); + spin_unlock_irqrestore(&ts->lock, flags); } -static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs) +static void ads7846_timer(unsigned long handle) { - struct ads7846 *ts = handle; - unsigned long flags; + struct ads7846 *ts = (void *)handle; + int status = 0; + unsigned long flags; spin_lock_irqsave(&ts->lock, flags); - if (likely(ts->get_pendown_state())) { + if (!ts->pending) { + ts->pending = 1; if (!ts->irq_disabled) { - /* The ARM do_simple_IRQ() dispatcher doesn't act - * like the other dispatchers: it will report IRQs - * even after they've been disabled. We work around - * that here. (The "generic irq" framework may help...) - */ ts->irq_disabled = 1; disable_irq(ts->spi->irq); - ts->pending = 1; - mod_timer(&ts->timer, jiffies); } + status = spi_async(ts->spi, &ts->msg); + if (status) + dev_err(&ts->spi->dev, "spi_async --> %d\n", + status); } spin_unlock_irqrestore(&ts->lock, flags); +} +static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs) +{ + ads7846_timer((unsigned long) handle); return IRQ_HANDLED; } /*--------------------------------------------------------------------------*/ -/* Must be called with ts->lock held */ -static void ads7846_disable(struct ads7846 *ts) +static int +ads7846_suspend(struct spi_device *spi, pm_message_t message) { - if (ts->disabled) - return; + struct ads7846 *ts = dev_get_drvdata(&spi->dev); + unsigned long flags; - ts->disabled = 1; + spin_lock_irqsave(&ts->lock, flags); + + spi->dev.power.power_state = message; /* are we waiting for IRQ, or polling? */ - if (!ts->pending) { - ts->irq_disabled = 1; - disable_irq(ts->spi->irq); + if (!ts->pendown) { + if (!ts->irq_disabled) { + ts->irq_disabled = 1; + disable_irq(ts->spi->irq); + } } else { - /* the timer will run at least once more, and - * leave everything in a clean state, IRQ disabled + /* polling; force a final SPI completion; + * that will clean things up neatly */ - while (ts->pending) { - spin_unlock_irq(&ts->lock); - msleep(1); - spin_lock_irq(&ts->lock); + if (!ts->pending) + mod_timer(&ts->timer, jiffies); + + while (ts->pendown || ts->pending) { + spin_unlock_irqrestore(&ts->lock, flags); + udelay(10); + spin_lock_irqsave(&ts->lock, flags); } } @@ -540,45 +388,17 @@ static void ads7846_disable(struct ads7846 *ts) * leave it that way after every request */ -} - -/* Must be called with ts->lock held */ -static void ads7846_enable(struct ads7846 *ts) -{ - if (!ts->disabled) - return; - - ts->disabled = 0; - ts->irq_disabled = 0; - enable_irq(ts->spi->irq); -} - -static int ads7846_suspend(struct spi_device *spi, pm_message_t message) -{ - struct ads7846 *ts = dev_get_drvdata(&spi->dev); - - spin_lock_irq(&ts->lock); - - spi->dev.power.power_state = message; - ads7846_disable(ts); - - spin_unlock_irq(&ts->lock); - + spin_unlock_irqrestore(&ts->lock, flags); return 0; - } static int ads7846_resume(struct spi_device *spi) { struct ads7846 *ts = dev_get_drvdata(&spi->dev); - spin_lock_irq(&ts->lock); - + ts->irq_disabled = 0; + enable_irq(ts->spi->irq); spi->dev.power.power_state = PMSG_ON; - ads7846_enable(ts); - - spin_unlock_irq(&ts->lock); - return 0; } @@ -587,7 +407,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) struct ads7846 *ts; struct input_dev *input_dev; struct ads7846_platform_data *pdata = spi->dev.platform_data; - struct spi_message *m; struct spi_transfer *x; int err; @@ -608,20 +427,11 @@ static int __devinit ads7846_probe(struct spi_device *spi) return -EINVAL; } - /* REVISIT when the irq can be triggered active-low, or if for some - * reason the touchscreen isn't hooked up, we don't need to access - * the pendown state. + /* We'd set the wordsize to 12 bits ... except that some controllers + * will then treat the 8 bit command words as 12 bits (and drop the + * four MSBs of the 12 bit result). Result: inputs must be shifted + * to discard the four garbage LSBs. */ - if (pdata->get_pendown_state == NULL) { - dev_dbg(&spi->dev, "no get_pendown_state function?\n"); - return -EINVAL; - } - - /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except - * that even if the hardware can do that, the SPI controller driver - * may not. So we stick to very-portable 8 bit words, both RX and TX. - */ - spi->bits_per_word = 8; ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); input_dev = input_allocate_device(); @@ -640,21 +450,9 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->timer.data = (unsigned long) ts; ts->timer.function = ads7846_timer; - spin_lock_init(&ts->lock); - ts->model = pdata->model ? : 7846; 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; - if (pdata->debounce_max) { - ts->debounce_max = pdata->debounce_max; - ts->debounce_tol = pdata->debounce_tol; - ts->debounce_rep = pdata->debounce_rep; - if (ts->debounce_rep > ts->debounce_max + 1) - ts->debounce_rep = ts->debounce_max - 1; - } else - ts->debounce_tol = ~0; - ts->get_pendown_state = pdata->get_pendown_state; snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); @@ -678,104 +476,64 @@ static int __devinit ads7846_probe(struct spi_device *spi) /* set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3. */ - m = &ts->msg[0]; + INIT_LIST_HEAD(&ts->msg.transfers); x = ts->xfer; - spi_message_init(m); - /* y- still on; turn on only y+ (and ADC) */ ts->read_y = READ_Y; x->tx_buf = &ts->read_y; x->len = 1; - spi_message_add_tail(x, m); + spi_message_add_tail(x, &ts->msg); x++; x->rx_buf = &ts->tc.y; x->len = 2; - spi_message_add_tail(x, m); - - m->complete = ads7846_debounce; - m->context = ts; - - m++; - spi_message_init(m); - - /* turn y- off, x+ on, then leave in lowpower */ - x++; - ts->read_x = READ_X; - x->tx_buf = &ts->read_x; - x->len = 1; - spi_message_add_tail(x, m); - - x++; - x->rx_buf = &ts->tc.x; - x->len = 2; - spi_message_add_tail(x, m); - - m->complete = ads7846_debounce; - m->context = ts; + spi_message_add_tail(x, &ts->msg); /* turn y+ off, x- on; we'll use formula #2 */ if (ts->model == 7846) { - m++; - spi_message_init(m); - x++; ts->read_z1 = READ_Z1; x->tx_buf = &ts->read_z1; x->len = 1; - spi_message_add_tail(x, m); + spi_message_add_tail(x, &ts->msg); x++; x->rx_buf = &ts->tc.z1; x->len = 2; - spi_message_add_tail(x, m); - - m->complete = ads7846_debounce; - m->context = ts; - - m++; - spi_message_init(m); + spi_message_add_tail(x, &ts->msg); x++; ts->read_z2 = READ_Z2; x->tx_buf = &ts->read_z2; x->len = 1; - spi_message_add_tail(x, m); + spi_message_add_tail(x, &ts->msg); x++; x->rx_buf = &ts->tc.z2; x->len = 2; - spi_message_add_tail(x, m); - - m->complete = ads7846_debounce; - m->context = ts; + spi_message_add_tail(x, &ts->msg); } - /* power down */ - m++; - spi_message_init(m); - + /* turn y- off, x+ on, then leave in lowpower */ x++; - ts->pwrdown = PWRDOWN; - x->tx_buf = &ts->pwrdown; + ts->read_x = READ_X; + x->tx_buf = &ts->read_x; x->len = 1; - spi_message_add_tail(x, m); + spi_message_add_tail(x, &ts->msg); x++; - x->rx_buf = &ts->dummy; + x->rx_buf = &ts->tc.x; x->len = 2; CS_CHANGE(*x); - spi_message_add_tail(x, m); - - m->complete = ads7846_rx; - m->context = ts; + spi_message_add_tail(x, &ts->msg); - ts->last_msg = m; + ts->msg.complete = ads7846_rx; + ts->msg.context = ts; if (request_irq(spi->irq, ads7846_irq, SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, - spi->dev.driver->name, ts)) { + spi->dev.bus_id, ts)) { dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); err = -EBUSY; goto err_free_mem; @@ -800,27 +558,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) device_create_file(&spi->dev, &dev_attr_vbatt); device_create_file(&spi->dev, &dev_attr_vaux); - device_create_file(&spi->dev, &dev_attr_pen_down); - - device_create_file(&spi->dev, &dev_attr_disable); - err = input_register_device(input_dev); if (err) - goto err_remove_attr; + goto err_free_irq; return 0; - err_remove_attr: - device_remove_file(&spi->dev, &dev_attr_disable); - device_remove_file(&spi->dev, &dev_attr_pen_down); - if (ts->model == 7846) { - device_remove_file(&spi->dev, &dev_attr_temp1); - device_remove_file(&spi->dev, &dev_attr_temp0); - } - if (ts->model != 7845) - device_remove_file(&spi->dev, &dev_attr_vbatt); - device_remove_file(&spi->dev, &dev_attr_vaux); - + err_free_irq: free_irq(spi->irq, ts); err_free_mem: input_free_device(input_dev); @@ -832,24 +576,20 @@ static int __devexit ads7846_remove(struct spi_device *spi) { struct ads7846 *ts = dev_get_drvdata(&spi->dev); - input_unregister_device(ts->input); - ads7846_suspend(spi, PMSG_SUSPEND); + free_irq(ts->spi->irq, ts); + if (ts->irq_disabled) + enable_irq(ts->spi->irq); - device_remove_file(&spi->dev, &dev_attr_disable); - device_remove_file(&spi->dev, &dev_attr_pen_down); if (ts->model == 7846) { - device_remove_file(&spi->dev, &dev_attr_temp1); device_remove_file(&spi->dev, &dev_attr_temp0); + device_remove_file(&spi->dev, &dev_attr_temp1); } if (ts->model != 7845) device_remove_file(&spi->dev, &dev_attr_vbatt); device_remove_file(&spi->dev, &dev_attr_vaux); - free_irq(ts->spi->irq, ts); - /* suspend left the IRQ disabled */ - enable_irq(ts->spi->irq); - + input_unregister_device(ts->input); kfree(ts); dev_dbg(&spi->dev, "unregistered touchscreen\n"); diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 5013703db..104298785 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -17,7 +17,7 @@ #include #include #include -//#include +#include #include #include diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index d678d144b..ca1547929 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -157,8 +157,9 @@ static int tsdev_open(struct inode *inode, struct file *file) if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) return -ENODEV; - if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL))) + if (!(list = kmalloc(sizeof(struct tsdev_list), GFP_KERNEL))) return -ENOMEM; + memset(list, 0, sizeof(struct tsdev_list)); list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0; @@ -378,8 +379,9 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, return NULL; } - if (!(tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL))) + if (!(tsdev = kmalloc(sizeof(struct tsdev), GFP_KERNEL))) return NULL; + memset(tsdev, 0, sizeof(struct tsdev)); INIT_LIST_HEAD(&tsdev->list); init_waitqueue_head(&tsdev->wait); diff --git a/drivers/isdn/Makefile b/drivers/isdn/Makefile index 988142c30..03d8ccd51 100644 --- a/drivers/isdn/Makefile +++ b/drivers/isdn/Makefile @@ -13,4 +13,3 @@ obj-$(CONFIG_ISDN_DRV_SC) += sc/ obj-$(CONFIG_ISDN_DRV_LOOP) += isdnloop/ obj-$(CONFIG_ISDN_DRV_ACT2000) += act2000/ obj-$(CONFIG_HYSDN) += hysdn/ -obj-$(CONFIG_ISDN_DRV_GIGASET) += gigaset/ diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 173c899a1..623adbb0d 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1485,7 +1485,6 @@ static int __init capi_init(void) { char *p; char *compileinfo; - int major_ret; if ((p = strchr(revision, ':')) != 0 && p[1]) { strlcpy(rev, p + 2, sizeof(rev)); @@ -1494,11 +1493,11 @@ static int __init capi_init(void) } else strcpy(rev, "1.0"); - major_ret = register_chrdev(capi_major, "capi20", &capi_fops); - if (major_ret < 0) { + if (register_chrdev(capi_major, "capi20", &capi_fops)) { printk(KERN_ERR "capi20: unable to get major %d\n", capi_major); - return major_ret; + return -EIO; } + capi_class = class_create(THIS_MODULE, "capi"); if (IS_ERR(capi_class)) { unregister_chrdev(capi_major, "capi20"); diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 8c4fcb902..feec40cf5 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -32,7 +32,6 @@ #ifdef CONFIG_AVMB1_COMPAT #include #endif -#include static char *revision = "$Revision: 1.1.2.8 $"; @@ -67,7 +66,7 @@ LIST_HEAD(capi_drivers); DEFINE_RWLOCK(capi_drivers_list_lock); static DEFINE_RWLOCK(application_lock); -static DEFINE_MUTEX(controller_mutex); +static DECLARE_MUTEX(controller_sem); struct capi20_appl *capi_applications[CAPI_MAXAPPL]; struct capi_ctr *capi_cards[CAPI_MAXCONTR]; @@ -396,20 +395,20 @@ attach_capi_ctr(struct capi_ctr *card) { int i; - mutex_lock(&controller_mutex); + down(&controller_sem); for (i = 0; i < CAPI_MAXCONTR; i++) { if (capi_cards[i] == NULL) break; } if (i == CAPI_MAXCONTR) { - mutex_unlock(&controller_mutex); + up(&controller_sem); printk(KERN_ERR "kcapi: out of controller slots\n"); return -EBUSY; } capi_cards[i] = card; - mutex_unlock(&controller_mutex); + up(&controller_sem); card->nrecvctlpkt = 0; card->nrecvdatapkt = 0; @@ -532,13 +531,13 @@ u16 capi20_register(struct capi20_appl *ap) write_unlock_irqrestore(&application_lock, flags); - mutex_lock(&controller_mutex); + down(&controller_sem); for (i = 0; i < CAPI_MAXCONTR; i++) { if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) continue; register_appl(capi_cards[i], applid, &ap->rparam); } - mutex_unlock(&controller_mutex); + up(&controller_sem); if (showcapimsgs & 1) { printk(KERN_DEBUG "kcapi: appl %d up\n", applid); @@ -561,13 +560,13 @@ u16 capi20_release(struct capi20_appl *ap) capi_applications[ap->applid - 1] = NULL; write_unlock_irqrestore(&application_lock, flags); - mutex_lock(&controller_mutex); + down(&controller_sem); for (i = 0; i < CAPI_MAXCONTR; i++) { if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) continue; release_appl(capi_cards[i], ap->applid); } - mutex_unlock(&controller_mutex); + up(&controller_sem); flush_scheduled_work(); skb_queue_purge(&ap->recv_queue); diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c index ca9dc00a4..2cc8b27e4 100644 --- a/drivers/isdn/capi/kcapi_proc.c +++ b/drivers/isdn/capi/kcapi_proc.c @@ -233,7 +233,7 @@ static struct file_operations proc_applstats_ops = { }; static void -create_seq_entry(char *name, mode_t mode, const struct file_operations *f) +create_seq_entry(char *name, mode_t mode, struct file_operations *f) { struct proc_dir_entry *entry; entry = create_proc_entry(name, mode, NULL); diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig deleted file mode 100644 index 5b203fe21..000000000 --- a/drivers/isdn/gigaset/Kconfig +++ /dev/null @@ -1,42 +0,0 @@ -menu "Siemens Gigaset" - depends on ISDN_I4L - -config ISDN_DRV_GIGASET - tristate "Siemens Gigaset support (isdn)" - depends on ISDN_I4L - select CRC_CCITT - help - Say m here if you have a Gigaset or Sinus isdn device. - -if ISDN_DRV_GIGASET!=n - -config GIGASET_BASE - tristate "Gigaset base station support" - depends on ISDN_DRV_GIGASET && USB - help - Say m here if you need to communicate with the base - directly via USB. - -config GIGASET_M105 - tristate "Gigaset M105 support" - depends on ISDN_DRV_GIGASET && USB - help - Say m here if you need the driver for the Gigaset M105 device. - -config GIGASET_DEBUG - bool "Gigaset debugging" - help - This enables debugging code in the Gigaset drivers. - If in doubt, say yes. - -config GIGASET_UNDOCREQ - bool "Support for undocumented USB requests" - help - This enables support for USB requests we only know from - reverse engineering (currently M105 only). If you need - features like configuration mode of M105, say yes. If you - care about your device, say no. - -endif - -endmenu diff --git a/drivers/isdn/gigaset/Makefile b/drivers/isdn/gigaset/Makefile deleted file mode 100644 index 9b9acf1a2..000000000 --- a/drivers/isdn/gigaset/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -gigaset-y := common.o interface.o proc.o ev-layer.o i4l.o -usb_gigaset-y := usb-gigaset.o asyncdata.o -bas_gigaset-y := bas-gigaset.o isocdata.o - -obj-$(CONFIG_GIGASET_M105) += usb_gigaset.o gigaset.o -obj-$(CONFIG_GIGASET_BASE) += bas_gigaset.o gigaset.o diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c deleted file mode 100644 index ce3cd7709..000000000 --- a/drivers/isdn/gigaset/asyncdata.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Common data handling layer for ser_gigaset and usb_gigaset - * - * Copyright (c) 2005 by Tilman Schmidt , - * Hansjoerg Lipp , - * Stefan Eilers. - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" -#include - -//#define GIG_M10x_STUFF_VOICE_DATA - -/* check if byte must be stuffed/escaped - * I'm not sure which data should be encoded. - * Therefore I will go the hard way and decode every value - * less than 0x20, the flag sequence and the control escape char. - */ -static inline int muststuff(unsigned char c) -{ - if (c < PPP_TRANS) return 1; - if (c == PPP_FLAG) return 1; - if (c == PPP_ESCAPE) return 1; - /* other possible candidates: */ - /* 0x91: XON with parity set */ - /* 0x93: XOFF with parity set */ - return 0; -} - -/* == data input =========================================================== */ - -/* process a block of received bytes in command mode (modem response) - * Return value: - * number of processed bytes - */ -static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, - struct inbuf_t *inbuf) -{ - struct cardstate *cs = inbuf->cs; - unsigned cbytes = cs->cbytes; - int inputstate = inbuf->inputstate; - int startbytes = numbytes; - - for (;;) { - cs->respdata[cbytes] = c; - if (c == 10 || c == 13) { - gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", - __func__, cbytes); - cs->cbytes = cbytes; - gigaset_handle_modem_response(cs); /* can change - cs->dle */ - cbytes = 0; - - if (cs->dle && - !(inputstate & INS_DLE_command)) { - inputstate &= ~INS_command; - break; - } - } else { - /* advance in line buffer, checking for overflow */ - if (cbytes < MAX_RESP_SIZE - 1) - cbytes++; - else - dev_warn(cs->dev, "response too large\n"); - } - - if (!numbytes) - break; - c = *src++; - --numbytes; - if (c == DLE_FLAG && - (cs->dle || inputstate & INS_DLE_command)) { - inputstate |= INS_DLE_char; - break; - } - } - - cs->cbytes = cbytes; - inbuf->inputstate = inputstate; - - return startbytes - numbytes; -} - -/* process a block of received bytes in lock mode (tty i/f) - * Return value: - * number of processed bytes - */ -static inline int lock_loop(unsigned char *src, int numbytes, - struct inbuf_t *inbuf) -{ - struct cardstate *cs = inbuf->cs; - - gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", - numbytes, src); - gigaset_if_receive(cs, src, numbytes); - - return numbytes; -} - -/* process a block of received bytes in HDLC data mode - * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes. - * When a frame is complete, check the FCS and pass valid frames to the LL. - * If DLE is encountered, return immediately to let the caller handle it. - * Return value: - * number of processed bytes - * numbytes (all bytes processed) on error --FIXME - */ -static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes, - struct inbuf_t *inbuf) -{ - struct cardstate *cs = inbuf->cs; - struct bc_state *bcs = inbuf->bcs; - int inputstate = bcs->inputstate; - __u16 fcs = bcs->fcs; - struct sk_buff *skb = bcs->skb; - unsigned char error; - struct sk_buff *compskb; - int startbytes = numbytes; - int l; - - if (unlikely(inputstate & INS_byte_stuff)) { - inputstate &= ~INS_byte_stuff; - goto byte_stuff; - } - for (;;) { - if (unlikely(c == PPP_ESCAPE)) { - if (unlikely(!numbytes)) { - inputstate |= INS_byte_stuff; - break; - } - c = *src++; - --numbytes; - if (unlikely(c == DLE_FLAG && - (cs->dle || - inbuf->inputstate & INS_DLE_command))) { - inbuf->inputstate |= INS_DLE_char; - inputstate |= INS_byte_stuff; - break; - } -byte_stuff: - c ^= PPP_TRANS; -#ifdef CONFIG_GIGASET_DEBUG - if (unlikely(!muststuff(c))) - gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c); -#endif - } else if (unlikely(c == PPP_FLAG)) { - if (unlikely(inputstate & INS_skip_frame)) { - if (!(inputstate & INS_have_data)) { /* 7E 7E */ -#ifdef CONFIG_GIGASET_DEBUG - ++bcs->emptycount; -#endif - } else - gig_dbg(DEBUG_HDLC, - "7e----------------------------"); - - /* end of frame */ - error = 1; - gigaset_rcv_error(NULL, cs, bcs); - } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ -#ifdef CONFIG_GIGASET_DEBUG - ++bcs->emptycount; -#endif - break; - } else { - gig_dbg(DEBUG_HDLC, - "7e----------------------------"); - - /* end of frame */ - error = 0; - - if (unlikely(fcs != PPP_GOODFCS)) { - dev_err(cs->dev, - "Packet checksum at %lu failed, " - "packet is corrupted (%u bytes)!\n", - bcs->rcvbytes, skb->len); - compskb = NULL; - gigaset_rcv_error(compskb, cs, bcs); - error = 1; - } else { - if (likely((l = skb->len) > 2)) { - skb->tail -= 2; - skb->len -= 2; - } else { - dev_kfree_skb(skb); - skb = NULL; - inputstate |= INS_skip_frame; - if (l == 1) { - dev_err(cs->dev, - "invalid packet size (1)!\n"); - error = 1; - gigaset_rcv_error(NULL, - cs, bcs); - } - } - if (likely(!(error || - (inputstate & - INS_skip_frame)))) { - gigaset_rcv_skb(skb, cs, bcs); - } - } - } - - if (unlikely(error)) - if (skb) - dev_kfree_skb(skb); - - fcs = PPP_INITFCS; - inputstate &= ~(INS_have_data | INS_skip_frame); - if (unlikely(bcs->ignore)) { - inputstate |= INS_skip_frame; - skb = NULL; - } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) { - skb_reserve(skb, HW_HDR_LEN); - } else { - dev_warn(cs->dev, - "could not allocate new skb\n"); - inputstate |= INS_skip_frame; - } - - break; -#ifdef CONFIG_GIGASET_DEBUG - } else if (unlikely(muststuff(c))) { - /* Should not happen. Possible after ZDLE=1. */ - gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c); -#endif - } - - /* add character */ - -#ifdef CONFIG_GIGASET_DEBUG - if (unlikely(!(inputstate & INS_have_data))) { - gig_dbg(DEBUG_HDLC, "7e (%d x) ================", - bcs->emptycount); - bcs->emptycount = 0; - } -#endif - - inputstate |= INS_have_data; - - if (likely(!(inputstate & INS_skip_frame))) { - if (unlikely(skb->len == SBUFSIZE)) { - dev_warn(cs->dev, "received packet too long\n"); - dev_kfree_skb_any(skb); - skb = NULL; - inputstate |= INS_skip_frame; - break; - } - *__skb_put(skb, 1) = c; - fcs = crc_ccitt_byte(fcs, c); - } - - if (unlikely(!numbytes)) - break; - c = *src++; - --numbytes; - if (unlikely(c == DLE_FLAG && - (cs->dle || - inbuf->inputstate & INS_DLE_command))) { - inbuf->inputstate |= INS_DLE_char; - break; - } - } - bcs->inputstate = inputstate; - bcs->fcs = fcs; - bcs->skb = skb; - return startbytes - numbytes; -} - -/* process a block of received bytes in transparent data mode - * Invert bytes, undoing byte stuffing and watching for DLE escapes. - * If DLE is encountered, return immediately to let the caller handle it. - * Return value: - * number of processed bytes - * numbytes (all bytes processed) on error --FIXME - */ -static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, - struct inbuf_t *inbuf) -{ - struct cardstate *cs = inbuf->cs; - struct bc_state *bcs = inbuf->bcs; - int inputstate = bcs->inputstate; - struct sk_buff *skb = bcs->skb; - int startbytes = numbytes; - - for (;;) { - /* add character */ - inputstate |= INS_have_data; - - if (likely(!(inputstate & INS_skip_frame))) { - if (unlikely(skb->len == SBUFSIZE)) { - //FIXME just pass skb up and allocate a new one - dev_warn(cs->dev, "received packet too long\n"); - dev_kfree_skb_any(skb); - skb = NULL; - inputstate |= INS_skip_frame; - break; - } - *__skb_put(skb, 1) = gigaset_invtab[c]; - } - - if (unlikely(!numbytes)) - break; - c = *src++; - --numbytes; - if (unlikely(c == DLE_FLAG && - (cs->dle || - inbuf->inputstate & INS_DLE_command))) { - inbuf->inputstate |= INS_DLE_char; - break; - } - } - - /* pass data up */ - if (likely(inputstate & INS_have_data)) { - if (likely(!(inputstate & INS_skip_frame))) { - gigaset_rcv_skb(skb, cs, bcs); - } - inputstate &= ~(INS_have_data | INS_skip_frame); - if (unlikely(bcs->ignore)) { - inputstate |= INS_skip_frame; - skb = NULL; - } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) - != NULL)) { - skb_reserve(skb, HW_HDR_LEN); - } else { - dev_warn(cs->dev, "could not allocate new skb\n"); - inputstate |= INS_skip_frame; - } - } - - bcs->inputstate = inputstate; - bcs->skb = skb; - return startbytes - numbytes; -} - -/* process a block of data received from the device - */ -void gigaset_m10x_input(struct inbuf_t *inbuf) -{ - struct cardstate *cs; - unsigned tail, head, numbytes; - unsigned char *src, c; - int procbytes; - - head = atomic_read(&inbuf->head); - tail = atomic_read(&inbuf->tail); - gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); - - if (head != tail) { - cs = inbuf->cs; - src = inbuf->data + head; - numbytes = (head > tail ? RBUFSIZE : tail) - head; - gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); - - while (numbytes) { - if (atomic_read(&cs->mstate) == MS_LOCKED) { - procbytes = lock_loop(src, numbytes, inbuf); - src += procbytes; - numbytes -= procbytes; - } else { - c = *src++; - --numbytes; - if (c == DLE_FLAG && (cs->dle || - inbuf->inputstate & INS_DLE_command)) { - if (!(inbuf->inputstate & INS_DLE_char)) { - inbuf->inputstate |= INS_DLE_char; - goto nextbyte; - } - /* => in data stream */ - inbuf->inputstate &= ~INS_DLE_char; - } - - if (!(inbuf->inputstate & INS_DLE_char)) { - - /* FIXME use function pointers? */ - if (inbuf->inputstate & INS_command) - procbytes = cmd_loop(c, src, numbytes, inbuf); - else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC) - procbytes = hdlc_loop(c, src, numbytes, inbuf); - else - procbytes = iraw_loop(c, src, numbytes, inbuf); - - src += procbytes; - numbytes -= procbytes; - } else { /* DLE char */ - inbuf->inputstate &= ~INS_DLE_char; - switch (c) { - case 'X': /*begin of command*/ -#ifdef CONFIG_GIGASET_DEBUG - if (inbuf->inputstate & INS_command) - dev_err(cs->dev, - "received 'X' in command mode\n"); -#endif - inbuf->inputstate |= - INS_command | INS_DLE_command; - break; - case '.': /*end of command*/ -#ifdef CONFIG_GIGASET_DEBUG - if (!(inbuf->inputstate & INS_command)) - dev_err(cs->dev, - "received '.' in hdlc mode\n"); -#endif - inbuf->inputstate &= cs->dle ? - ~(INS_DLE_command|INS_command) - : ~INS_DLE_command; - break; - //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */ - default: - dev_err(cs->dev, - "received 0x10 0x%02x!\n", - (int) c); - /* FIXME: reset driver?? */ - } - } - } -nextbyte: - if (!numbytes) { - /* end of buffer, check for wrap */ - if (head > tail) { - head = 0; - src = inbuf->data; - numbytes = tail; - } else { - head = tail; - break; - } - } - } - - gig_dbg(DEBUG_INTR, "setting head to %u", head); - atomic_set(&inbuf->head, head); - } -} - - -/* == data output ========================================================== */ - -/* Encoding of a PPP packet into an octet stuffed HDLC frame - * with FCS, opening and closing flags. - * parameters: - * skb skb containing original packet (freed upon return) - * head number of headroom bytes to allocate in result skb - * tail number of tailroom bytes to allocate in result skb - * Return value: - * pointer to newly allocated skb containing the result frame - */ -static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) -{ - struct sk_buff *hdlc_skb; - __u16 fcs; - unsigned char c; - unsigned char *cp; - int len; - unsigned int stuf_cnt; - - stuf_cnt = 0; - fcs = PPP_INITFCS; - cp = skb->data; - len = skb->len; - while (len--) { - if (muststuff(*cp)) - stuf_cnt++; - fcs = crc_ccitt_byte(fcs, *cp++); - } - fcs ^= 0xffff; /* complement */ - - /* size of new buffer: original size + number of stuffing bytes - * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes - */ - hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); - if (!hdlc_skb) { - dev_kfree_skb(skb); - return NULL; - } - skb_reserve(hdlc_skb, head); - - /* Copy acknowledge request into new skb */ - memcpy(hdlc_skb->head, skb->head, 2); - - /* Add flag sequence in front of everything.. */ - *(skb_put(hdlc_skb, 1)) = PPP_FLAG; - - /* Perform byte stuffing while copying data. */ - while (skb->len--) { - if (muststuff(*skb->data)) { - *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; - *(skb_put(hdlc_skb, 1)) = (*skb->data++) ^ PPP_TRANS; - } else - *(skb_put(hdlc_skb, 1)) = *skb->data++; - } - - /* Finally add FCS (byte stuffed) and flag sequence */ - c = (fcs & 0x00ff); /* least significant byte first */ - if (muststuff(c)) { - *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; - c ^= PPP_TRANS; - } - *(skb_put(hdlc_skb, 1)) = c; - - c = ((fcs >> 8) & 0x00ff); - if (muststuff(c)) { - *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; - c ^= PPP_TRANS; - } - *(skb_put(hdlc_skb, 1)) = c; - - *(skb_put(hdlc_skb, 1)) = PPP_FLAG; - - dev_kfree_skb(skb); - return hdlc_skb; -} - -/* Encoding of a raw packet into an octet stuffed bit inverted frame - * parameters: - * skb skb containing original packet (freed upon return) - * head number of headroom bytes to allocate in result skb - * tail number of tailroom bytes to allocate in result skb - * Return value: - * pointer to newly allocated skb containing the result frame - */ -static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) -{ - struct sk_buff *iraw_skb; - unsigned char c; - unsigned char *cp; - int len; - - /* worst case: every byte must be stuffed */ - iraw_skb = dev_alloc_skb(2*skb->len + tail + head); - if (!iraw_skb) { - dev_kfree_skb(skb); - return NULL; - } - skb_reserve(iraw_skb, head); - - cp = skb->data; - len = skb->len; - while (len--) { - c = gigaset_invtab[*cp++]; - if (c == DLE_FLAG) - *(skb_put(iraw_skb, 1)) = c; - *(skb_put(iraw_skb, 1)) = c; - } - dev_kfree_skb(skb); - return iraw_skb; -} - -/* gigaset_send_skb - * called by common.c to queue an skb for sending - * and start transmission if necessary - * parameters: - * B Channel control structure - * skb - * Return value: - * number of bytes accepted for sending - * (skb->len if ok, 0 if out of buffer space) - * or error code (< 0, eg. -EINVAL) - */ -int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) -{ - unsigned len = skb->len; - unsigned long flags; - - if (bcs->proto2 == ISDN_PROTO_L2_HDLC) - skb = HDLC_Encode(skb, HW_HDR_LEN, 0); - else - skb = iraw_encode(skb, HW_HDR_LEN, 0); - if (!skb) { - err("unable to allocate memory for encoding!\n"); - return -ENOMEM; - } - - skb_queue_tail(&bcs->squeue, skb); - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->cs->connected) - tasklet_schedule(&bcs->cs->write_tasklet); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - - return len; /* ok so far */ -} diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c deleted file mode 100644 index eb41aba3d..000000000 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ /dev/null @@ -1,2370 +0,0 @@ -/* - * USB driver for Gigaset 307x base via direct USB connection. - * - * Copyright (c) 2001 by Hansjoerg Lipp , - * Tilman Schmidt , - * Stefan Eilers. - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" - -#include -#include -#include -#include -#include -#include -#include - -/* Version Information */ -#define DRIVER_AUTHOR "Tilman Schmidt , Hansjoerg Lipp , Stefan Eilers" -#define DRIVER_DESC "USB Driver for Gigaset 307x" - - -/* Module parameters */ - -static int startmode = SM_ISDN; -static int cidmode = 1; - -module_param(startmode, int, S_IRUGO); -module_param(cidmode, int, S_IRUGO); -MODULE_PARM_DESC(startmode, "start in isdn4linux mode"); -MODULE_PARM_DESC(cidmode, "Call-ID mode"); - -#define GIGASET_MINORS 1 -#define GIGASET_MINOR 16 -#define GIGASET_MODULENAME "bas_gigaset" -#define GIGASET_DEVFSNAME "gig/bas/" -#define GIGASET_DEVNAME "ttyGB" - -/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ -#define IF_WRITEBUF 264 - -/* Values for the Gigaset 307x */ -#define USB_GIGA_VENDOR_ID 0x0681 -#define USB_3070_PRODUCT_ID 0x0001 -#define USB_3075_PRODUCT_ID 0x0002 -#define USB_SX303_PRODUCT_ID 0x0021 -#define USB_SX353_PRODUCT_ID 0x0022 - -/* table of devices that work with this driver */ -static struct usb_device_id gigaset_table [] = { - { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) }, - { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) }, - { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) }, - { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX353_PRODUCT_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, gigaset_table); - -/*======================= local function prototypes =============================*/ - -/* This function is called if a new device is connected to the USB port. It - * checks whether this new device belongs to this driver. - */ -static int gigaset_probe(struct usb_interface *interface, - const struct usb_device_id *id); - -/* Function will be called if the device is unplugged */ -static void gigaset_disconnect(struct usb_interface *interface); - -static void read_ctrl_callback(struct urb *, struct pt_regs *); -static void stopurbs(struct bas_bc_state *); -static int atwrite_submit(struct cardstate *, unsigned char *, int); -static int start_cbsend(struct cardstate *); - -/*==============================================================================*/ - -struct bas_cardstate { - struct usb_device *udev; /* USB device pointer */ - struct usb_interface *interface; /* interface for this device */ - unsigned char minor; /* starting minor number */ - - struct urb *urb_ctrl; /* control pipe default URB */ - struct usb_ctrlrequest dr_ctrl; - struct timer_list timer_ctrl; /* control request timeout */ - - struct timer_list timer_atrdy; /* AT command ready timeout */ - struct urb *urb_cmd_out; /* for sending AT commands */ - struct usb_ctrlrequest dr_cmd_out; - int retry_cmd_out; - - struct urb *urb_cmd_in; /* for receiving AT replies */ - struct usb_ctrlrequest dr_cmd_in; - struct timer_list timer_cmd_in; /* receive request timeout */ - unsigned char *rcvbuf; /* AT reply receive buffer */ - - struct urb *urb_int_in; /* URB for interrupt pipe */ - unsigned char int_in_buf[3]; - - spinlock_t lock; /* locks all following */ - atomic_t basstate; /* bitmap (BS_*) */ - int pending; /* uncompleted base request */ - int rcvbuf_size; /* size of AT receive buffer */ - /* 0: no receive in progress */ - int retry_cmd_in; /* receive req retry count */ -}; - -/* status of direct USB connection to 307x base (bits in basstate) */ -#define BS_ATOPEN 0x001 /* AT channel open */ -#define BS_B1OPEN 0x002 /* B channel 1 open */ -#define BS_B2OPEN 0x004 /* B channel 2 open */ -#define BS_ATREADY 0x008 /* base ready for AT command */ -#define BS_INIT 0x010 /* base has signalled INIT_OK */ -#define BS_ATTIMER 0x020 /* waiting for HD_READY_SEND_ATDATA */ -#define BS_ATRDPEND 0x040 /* urb_cmd_in in use */ -#define BS_ATWRPEND 0x080 /* urb_cmd_out in use */ - - -static struct gigaset_driver *driver = NULL; -static struct cardstate *cardstate = NULL; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver gigaset_usb_driver = { - .name = GIGASET_MODULENAME, - .probe = gigaset_probe, - .disconnect = gigaset_disconnect, - .id_table = gigaset_table, -}; - -/* get message text for usb_submit_urb return code - */ -static char *get_usb_rcmsg(int rc) -{ - static char unkmsg[28]; - - switch (rc) { - case 0: - return "success"; - case -ENOMEM: - return "out of memory"; - case -ENODEV: - return "device not present"; - case -ENOENT: - return "endpoint not present"; - case -ENXIO: - return "URB type not supported"; - case -EINVAL: - return "invalid argument"; - case -EAGAIN: - return "start frame too early or too much scheduled"; - case -EFBIG: - return "too many isochronous frames requested"; - case -EPIPE: - return "endpoint stalled"; - case -EMSGSIZE: - return "invalid packet size"; - case -ENOSPC: - return "would overcommit USB bandwidth"; - case -ESHUTDOWN: - return "device shut down"; - case -EPERM: - return "reject flag set"; - case -EHOSTUNREACH: - return "device suspended"; - default: - snprintf(unkmsg, sizeof(unkmsg), "unknown error %d", rc); - return unkmsg; - } -} - -/* get message text for USB status code - */ -static char *get_usb_statmsg(int status) -{ - static char unkmsg[28]; - - switch (status) { - case 0: - return "success"; - case -ENOENT: - return "unlinked (sync)"; - case -EINPROGRESS: - return "pending"; - case -EPROTO: - return "bit stuffing error, timeout, or unknown USB error"; - case -EILSEQ: - return "CRC mismatch, timeout, or unknown USB error"; - case -ETIMEDOUT: - return "timed out"; - case -EPIPE: - return "endpoint stalled"; - case -ECOMM: - return "IN buffer overrun"; - case -ENOSR: - return "OUT buffer underrun"; - case -EOVERFLOW: - return "too much data"; - case -EREMOTEIO: - return "short packet detected"; - case -ENODEV: - return "device removed"; - case -EXDEV: - return "partial isochronous transfer"; - case -EINVAL: - return "invalid argument"; - case -ECONNRESET: - return "unlinked (async)"; - case -ESHUTDOWN: - return "device shut down"; - default: - snprintf(unkmsg, sizeof(unkmsg), "unknown status %d", status); - return unkmsg; - } -} - -/* usb_pipetype_str - * retrieve string representation of USB pipe type - */ -static inline char *usb_pipetype_str(int pipe) -{ - if (usb_pipeisoc(pipe)) - return "Isoc"; - if (usb_pipeint(pipe)) - return "Int"; - if (usb_pipecontrol(pipe)) - return "Ctrl"; - if (usb_pipebulk(pipe)) - return "Bulk"; - return "?"; -} - -/* dump_urb - * write content of URB to syslog for debugging - */ -static inline void dump_urb(enum debuglevel level, const char *tag, - struct urb *urb) -{ -#ifdef CONFIG_GIGASET_DEBUG - int i; - gig_dbg(level, "%s urb(0x%08lx)->{", tag, (unsigned long) urb); - if (urb) { - gig_dbg(level, - " dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, " - "status=%d, hcpriv=0x%08lx, transfer_flags=0x%x,", - (unsigned long) urb->dev, - usb_pipetype_str(urb->pipe), - usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe), - usb_pipein(urb->pipe) ? "in" : "out", - urb->status, (unsigned long) urb->hcpriv, - urb->transfer_flags); - gig_dbg(level, - " transfer_buffer=0x%08lx[%d], actual_length=%d, " - "bandwidth=%d, setup_packet=0x%08lx,", - (unsigned long) urb->transfer_buffer, - urb->transfer_buffer_length, urb->actual_length, - urb->bandwidth, (unsigned long) urb->setup_packet); - gig_dbg(level, - " start_frame=%d, number_of_packets=%d, interval=%d, " - "error_count=%d,", - urb->start_frame, urb->number_of_packets, urb->interval, - urb->error_count); - gig_dbg(level, - " context=0x%08lx, complete=0x%08lx, " - "iso_frame_desc[]={", - (unsigned long) urb->context, - (unsigned long) urb->complete); - for (i = 0; i < urb->number_of_packets; i++) { - struct usb_iso_packet_descriptor *pifd - = &urb->iso_frame_desc[i]; - gig_dbg(level, - " {offset=%u, length=%u, actual_length=%u, " - "status=%u}", - pifd->offset, pifd->length, pifd->actual_length, - pifd->status); - } - } - gig_dbg(level, "}}"); -#endif -} - -/* read/set modem control bits etc. (m10x only) */ -static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, - unsigned new_state) -{ - return -EINVAL; -} - -static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) -{ - return -EINVAL; -} - -static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) -{ - return -EINVAL; -} - -/* error_hangup - * hang up any existing connection because of an unrecoverable error - * This function may be called from any context and takes care of scheduling - * the necessary actions for execution outside of interrupt context. - * argument: - * B channel control structure - */ -static inline void error_hangup(struct bc_state *bcs) -{ - struct cardstate *cs = bcs->cs; - - gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d", - __func__, bcs->channel); - - if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) - dev_err(cs->dev, "event queue full\n"); - - gigaset_schedule_event(cs); -} - -/* error_reset - * reset Gigaset device because of an unrecoverable error - * This function may be called from any context, and should take care of - * scheduling the necessary actions for execution outside of interrupt context. - * Right now, it just generates a kernel message calling for help. - * argument: - * controller state structure - */ -static inline void error_reset(struct cardstate *cs) -{ - //FIXME try to recover without bothering the user - dev_err(cs->dev, - "unrecoverable error - please disconnect Gigaset base to reset\n"); -} - -/* check_pending - * check for completion of pending control request - * parameter: - * ucs hardware specific controller state structure - */ -static void check_pending(struct bas_cardstate *ucs) -{ - unsigned long flags; - - spin_lock_irqsave(&ucs->lock, flags); - switch (ucs->pending) { - case 0: - break; - case HD_OPEN_ATCHANNEL: - if (atomic_read(&ucs->basstate) & BS_ATOPEN) - ucs->pending = 0; - break; - case HD_OPEN_B1CHANNEL: - if (atomic_read(&ucs->basstate) & BS_B1OPEN) - ucs->pending = 0; - break; - case HD_OPEN_B2CHANNEL: - if (atomic_read(&ucs->basstate) & BS_B2OPEN) - ucs->pending = 0; - break; - case HD_CLOSE_ATCHANNEL: - if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) - ucs->pending = 0; - break; - case HD_CLOSE_B1CHANNEL: - if (!(atomic_read(&ucs->basstate) & BS_B1OPEN)) - ucs->pending = 0; - break; - case HD_CLOSE_B2CHANNEL: - if (!(atomic_read(&ucs->basstate) & BS_B2OPEN)) - ucs->pending = 0; - break; - case HD_DEVICE_INIT_ACK: /* no reply expected */ - ucs->pending = 0; - break; - /* HD_READ_ATMESSAGE, HD_WRITE_ATMESSAGE, HD_RESET_INTERRUPTPIPE - * are handled separately and should never end up here - */ - default: - dev_warn(&ucs->interface->dev, - "unknown pending request 0x%02x cleared\n", - ucs->pending); - ucs->pending = 0; - } - - if (!ucs->pending) - del_timer(&ucs->timer_ctrl); - - spin_unlock_irqrestore(&ucs->lock, flags); -} - -/* cmd_in_timeout - * timeout routine for command input request - * argument: - * controller state structure - */ -static void cmd_in_timeout(unsigned long data) -{ - struct cardstate *cs = (struct cardstate *) data; - struct bas_cardstate *ucs = cs->hw.bas; - - if (!ucs->rcvbuf_size) { - gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); - return; - } - - dev_err(cs->dev, "timeout reading AT response\n"); - error_reset(cs); //FIXME retry? -} - -/* set/clear bits in base connection state, return previous state - */ -inline static int update_basstate(struct bas_cardstate *ucs, - int set, int clear) -{ - unsigned long flags; - int state; - - spin_lock_irqsave(&ucs->lock, flags); - state = atomic_read(&ucs->basstate); - atomic_set(&ucs->basstate, (state & ~clear) | set); - spin_unlock_irqrestore(&ucs->lock, flags); - return state; -} - -/* atread_submit - * submit an HD_READ_ATMESSAGE command URB and optionally start a timeout - * parameters: - * cs controller state structure - * timeout timeout in 1/10 sec., 0: none - * return value: - * 0 on success - * -EBUSY if another request is pending - * any URB submission error code - */ -static int atread_submit(struct cardstate *cs, int timeout) -{ - struct bas_cardstate *ucs = cs->hw.bas; - int ret; - - gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", - ucs->rcvbuf_size); - - if (update_basstate(ucs, BS_ATRDPEND, 0) & BS_ATRDPEND) { - dev_err(cs->dev, - "could not submit HD_READ_ATMESSAGE: URB busy\n"); - return -EBUSY; - } - - ucs->dr_cmd_in.bRequestType = IN_VENDOR_REQ; - ucs->dr_cmd_in.bRequest = HD_READ_ATMESSAGE; - ucs->dr_cmd_in.wValue = 0; - ucs->dr_cmd_in.wIndex = 0; - ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size); - usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev, - usb_rcvctrlpipe(ucs->udev, 0), - (unsigned char*) & ucs->dr_cmd_in, - ucs->rcvbuf, ucs->rcvbuf_size, - read_ctrl_callback, cs->inbuf); - - if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { - update_basstate(ucs, 0, BS_ATRDPEND); - dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", - get_usb_statmsg(ret)); - return ret; - } - - if (timeout > 0) { - gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); - ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; - ucs->timer_cmd_in.data = (unsigned long) cs; - ucs->timer_cmd_in.function = cmd_in_timeout; - add_timer(&ucs->timer_cmd_in); - } - return 0; -} - -/* read_int_callback - * USB completion handler for interrupt pipe input - * called by the USB subsystem in interrupt context - * parameter: - * urb USB request block - * urb->context = controller state structure - */ -static void read_int_callback(struct urb *urb, struct pt_regs *regs) -{ - struct cardstate *cs = urb->context; - struct bas_cardstate *ucs = cs->hw.bas; - struct bc_state *bcs; - unsigned long flags; - int rc; - unsigned l; - int channel; - - switch (urb->status) { - case 0: /* success */ - break; - case -ENOENT: /* cancelled */ - case -ECONNRESET: /* cancelled (async) */ - case -EINPROGRESS: /* pending */ - /* ignore silently */ - gig_dbg(DEBUG_USBREQ, "%s: %s", - __func__, get_usb_statmsg(urb->status)); - return; - case -ENODEV: /* device removed */ - case -ESHUTDOWN: /* device shut down */ - //FIXME use this as disconnect indicator? - gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__); - return; - default: /* severe trouble */ - dev_warn(cs->dev, "interrupt read: %s\n", - get_usb_statmsg(urb->status)); - //FIXME corrective action? resubmission always ok? - goto resubmit; - } - - /* drop incomplete packets even if the missing bytes wouldn't matter */ - if (unlikely(urb->actual_length < 3)) { - dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n", - urb->actual_length); - goto resubmit; - } - - l = (unsigned) ucs->int_in_buf[1] + - (((unsigned) ucs->int_in_buf[2]) << 8); - - gig_dbg(DEBUG_USBREQ, "<-------%d: 0x%02x (%u [0x%02x 0x%02x])", - urb->actual_length, (int)ucs->int_in_buf[0], l, - (int)ucs->int_in_buf[1], (int)ucs->int_in_buf[2]); - - channel = 0; - - switch (ucs->int_in_buf[0]) { - case HD_DEVICE_INIT_OK: - update_basstate(ucs, BS_INIT, 0); - break; - - case HD_READY_SEND_ATDATA: - del_timer(&ucs->timer_atrdy); - update_basstate(ucs, BS_ATREADY, BS_ATTIMER); - start_cbsend(cs); - break; - - case HD_OPEN_B2CHANNEL_ACK: - ++channel; - case HD_OPEN_B1CHANNEL_ACK: - bcs = cs->bcs + channel; - update_basstate(ucs, BS_B1OPEN << channel, 0); - gigaset_bchannel_up(bcs); - break; - - case HD_OPEN_ATCHANNEL_ACK: - update_basstate(ucs, BS_ATOPEN, 0); - start_cbsend(cs); - break; - - case HD_CLOSE_B2CHANNEL_ACK: - ++channel; - case HD_CLOSE_B1CHANNEL_ACK: - bcs = cs->bcs + channel; - update_basstate(ucs, 0, BS_B1OPEN << channel); - stopurbs(bcs->hw.bas); - gigaset_bchannel_down(bcs); - break; - - case HD_CLOSE_ATCHANNEL_ACK: - update_basstate(ucs, 0, BS_ATOPEN); - break; - - case HD_B2_FLOW_CONTROL: - ++channel; - case HD_B1_FLOW_CONTROL: - bcs = cs->bcs + channel; - atomic_add((l - BAS_NORMFRAME) * BAS_CORRFRAMES, - &bcs->hw.bas->corrbytes); - gig_dbg(DEBUG_ISO, - "Flow control (channel %d, sub %d): 0x%02x => %d", - channel, bcs->hw.bas->numsub, l, - atomic_read(&bcs->hw.bas->corrbytes)); - break; - - case HD_RECEIVEATDATA_ACK: /* AT response ready to be received */ - if (!l) { - dev_warn(cs->dev, - "HD_RECEIVEATDATA_ACK with length 0 ignored\n"); - break; - } - spin_lock_irqsave(&cs->lock, flags); - if (ucs->rcvbuf_size) { - /* throw away previous buffer - we have no queue */ - dev_err(cs->dev, - "receive AT data overrun, %d bytes lost\n", - ucs->rcvbuf_size); - kfree(ucs->rcvbuf); - ucs->rcvbuf_size = 0; - } - if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { - spin_unlock_irqrestore(&cs->lock, flags); - dev_err(cs->dev, "out of memory receiving AT data\n"); - error_reset(cs); - break; - } - ucs->rcvbuf_size = l; - ucs->retry_cmd_in = 0; - if ((rc = atread_submit(cs, BAS_TIMEOUT)) < 0) { - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - if (rc != -ENODEV) - //FIXME corrective action? - error_reset(cs); - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - - case HD_RESET_INTERRUPT_PIPE_ACK: - gig_dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK"); - break; - - case HD_SUSPEND_END: - gig_dbg(DEBUG_USBREQ, "HD_SUSPEND_END"); - break; - - default: - dev_warn(cs->dev, - "unknown Gigaset signal 0x%02x (%u) ignored\n", - (int) ucs->int_in_buf[0], l); - } - - check_pending(ucs); - -resubmit: - rc = usb_submit_urb(urb, SLAB_ATOMIC); - if (unlikely(rc != 0 && rc != -ENODEV)) { - dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", - get_usb_rcmsg(rc)); - error_reset(cs); - } -} - -/* read_ctrl_callback - * USB completion handler for control pipe input - * called by the USB subsystem in interrupt context - * parameter: - * urb USB request block - * urb->context = inbuf structure for controller state - */ -static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) -{ - struct inbuf_t *inbuf = urb->context; - struct cardstate *cs = inbuf->cs; - struct bas_cardstate *ucs = cs->hw.bas; - int have_data = 0; - unsigned numbytes; - int rc; - - update_basstate(ucs, 0, BS_ATRDPEND); - - if (!ucs->rcvbuf_size) { - dev_warn(cs->dev, "%s: no receive in progress\n", __func__); - return; - } - - del_timer(&ucs->timer_cmd_in); - - switch (urb->status) { - case 0: /* normal completion */ - numbytes = urb->actual_length; - if (unlikely(numbytes == 0)) { - dev_warn(cs->dev, - "control read: empty block received\n"); - goto retry; - } - if (unlikely(numbytes != ucs->rcvbuf_size)) { - dev_warn(cs->dev, - "control read: received %d chars, expected %d\n", - numbytes, ucs->rcvbuf_size); - if (numbytes > ucs->rcvbuf_size) - numbytes = ucs->rcvbuf_size; - } - - /* copy received bytes to inbuf */ - have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); - - if (unlikely(numbytes < ucs->rcvbuf_size)) { - /* incomplete - resubmit for remaining bytes */ - ucs->rcvbuf_size -= numbytes; - ucs->retry_cmd_in = 0; - goto retry; - } - break; - - case -ENOENT: /* cancelled */ - case -ECONNRESET: /* cancelled (async) */ - case -EINPROGRESS: /* pending */ - case -ENODEV: /* device removed */ - case -ESHUTDOWN: /* device shut down */ - /* no action necessary */ - gig_dbg(DEBUG_USBREQ, "%s: %s", - __func__, get_usb_statmsg(urb->status)); - break; - - default: /* severe trouble */ - dev_warn(cs->dev, "control read: %s\n", - get_usb_statmsg(urb->status)); - retry: - if (ucs->retry_cmd_in++ < BAS_RETRY) { - dev_notice(cs->dev, "control read: retry %d\n", - ucs->retry_cmd_in); - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ - return; - } else { - dev_err(cs->dev, - "control read: giving up after %d tries\n", - ucs->retry_cmd_in); - } - error_reset(cs); - } - - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - if (have_data) { - gig_dbg(DEBUG_INTR, "%s-->BH", __func__); - gigaset_schedule_event(cs); - } -} - -/* read_iso_callback - * USB completion handler for B channel isochronous input - * called by the USB subsystem in interrupt context - * parameter: - * urb USB request block of completed request - * urb->context = bc_state structure - */ -static void read_iso_callback(struct urb *urb, struct pt_regs *regs) -{ - struct bc_state *bcs; - struct bas_bc_state *ubc; - unsigned long flags; - int i, rc; - - /* status codes not worth bothering the tasklet with */ - if (unlikely(urb->status == -ENOENT || - urb->status == -ECONNRESET || - urb->status == -EINPROGRESS || - urb->status == -ENODEV || - urb->status == -ESHUTDOWN)) { - gig_dbg(DEBUG_ISO, "%s: %s", - __func__, get_usb_statmsg(urb->status)); - return; - } - - bcs = urb->context; - ubc = bcs->hw.bas; - - spin_lock_irqsave(&ubc->isoinlock, flags); - if (likely(ubc->isoindone == NULL)) { - /* pass URB to tasklet */ - ubc->isoindone = urb; - tasklet_schedule(&ubc->rcvd_tasklet); - } else { - /* tasklet still busy, drop data and resubmit URB */ - ubc->loststatus = urb->status; - for (i = 0; i < BAS_NUMFRAMES; i++) { - ubc->isoinlost += urb->iso_frame_desc[i].actual_length; - if (unlikely(urb->iso_frame_desc[i].status != 0 && - urb->iso_frame_desc[i].status != - -EINPROGRESS)) - ubc->loststatus = urb->iso_frame_desc[i].status; - urb->iso_frame_desc[i].status = 0; - urb->iso_frame_desc[i].actual_length = 0; - } - if (likely(atomic_read(&ubc->running))) { - /* urb->dev is clobbered by USB subsystem */ - urb->dev = bcs->cs->hw.bas->udev; - urb->transfer_flags = URB_ISO_ASAP; - urb->number_of_packets = BAS_NUMFRAMES; - gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", - __func__); - rc = usb_submit_urb(urb, SLAB_ATOMIC); - if (unlikely(rc != 0 && rc != -ENODEV)) { - dev_err(bcs->cs->dev, - "could not resubmit isochronous read " - "URB: %s\n", get_usb_rcmsg(rc)); - dump_urb(DEBUG_ISO, "isoc read", urb); - error_hangup(bcs); - } - } - } - spin_unlock_irqrestore(&ubc->isoinlock, flags); -} - -/* write_iso_callback - * USB completion handler for B channel isochronous output - * called by the USB subsystem in interrupt context - * parameter: - * urb USB request block of completed request - * urb->context = isow_urbctx_t structure - */ -static void write_iso_callback(struct urb *urb, struct pt_regs *regs) -{ - struct isow_urbctx_t *ucx; - struct bas_bc_state *ubc; - unsigned long flags; - - /* status codes not worth bothering the tasklet with */ - if (unlikely(urb->status == -ENOENT || - urb->status == -ECONNRESET || - urb->status == -EINPROGRESS || - urb->status == -ENODEV || - urb->status == -ESHUTDOWN)) { - gig_dbg(DEBUG_ISO, "%s: %s", - __func__, get_usb_statmsg(urb->status)); - return; - } - - /* pass URB context to tasklet */ - ucx = urb->context; - ubc = ucx->bcs->hw.bas; - - spin_lock_irqsave(&ubc->isooutlock, flags); - ubc->isooutovfl = ubc->isooutdone; - ubc->isooutdone = ucx; - spin_unlock_irqrestore(&ubc->isooutlock, flags); - tasklet_schedule(&ubc->sent_tasklet); -} - -/* starturbs - * prepare and submit USB request blocks for isochronous input and output - * argument: - * B channel control structure - * return value: - * 0 on success - * < 0 on error (no URBs submitted) - */ -static int starturbs(struct bc_state *bcs) -{ - struct bas_bc_state *ubc = bcs->hw.bas; - struct urb *urb; - int j, k; - int rc; - - /* initialize L2 reception */ - if (bcs->proto2 == ISDN_PROTO_L2_HDLC) - bcs->inputstate |= INS_flag_hunt; - - /* submit all isochronous input URBs */ - atomic_set(&ubc->running, 1); - for (k = 0; k < BAS_INURBS; k++) { - urb = ubc->isoinurbs[k]; - if (!urb) { - rc = -EFAULT; - goto error; - } - - urb->dev = bcs->cs->hw.bas->udev; - urb->pipe = usb_rcvisocpipe(urb->dev, 3 + 2 * bcs->channel); - urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = ubc->isoinbuf + k * BAS_INBUFSIZE; - urb->transfer_buffer_length = BAS_INBUFSIZE; - urb->number_of_packets = BAS_NUMFRAMES; - urb->interval = BAS_FRAMETIME; - urb->complete = read_iso_callback; - urb->context = bcs; - for (j = 0; j < BAS_NUMFRAMES; j++) { - urb->iso_frame_desc[j].offset = j * BAS_MAXFRAME; - urb->iso_frame_desc[j].length = BAS_MAXFRAME; - urb->iso_frame_desc[j].status = 0; - urb->iso_frame_desc[j].actual_length = 0; - } - - dump_urb(DEBUG_ISO, "Initial isoc read", urb); - if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) - goto error; - } - - /* initialize L2 transmission */ - gigaset_isowbuf_init(ubc->isooutbuf, PPP_FLAG); - - /* set up isochronous output URBs for flag idling */ - for (k = 0; k < BAS_OUTURBS; ++k) { - urb = ubc->isoouturbs[k].urb; - if (!urb) { - rc = -EFAULT; - goto error; - } - urb->dev = bcs->cs->hw.bas->udev; - urb->pipe = usb_sndisocpipe(urb->dev, 4 + 2 * bcs->channel); - urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = ubc->isooutbuf->data; - urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data); - urb->number_of_packets = BAS_NUMFRAMES; - urb->interval = BAS_FRAMETIME; - urb->complete = write_iso_callback; - urb->context = &ubc->isoouturbs[k]; - for (j = 0; j < BAS_NUMFRAMES; ++j) { - urb->iso_frame_desc[j].offset = BAS_OUTBUFSIZE; - urb->iso_frame_desc[j].length = BAS_NORMFRAME; - urb->iso_frame_desc[j].status = 0; - urb->iso_frame_desc[j].actual_length = 0; - } - ubc->isoouturbs[k].limit = -1; - } - - /* submit two URBs, keep third one */ - for (k = 0; k < 2; ++k) { - dump_urb(DEBUG_ISO, "Initial isoc write", urb); - rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); - if (rc != 0) - goto error; - } - dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb); - ubc->isooutfree = &ubc->isoouturbs[2]; - ubc->isooutdone = ubc->isooutovfl = NULL; - return 0; - error: - stopurbs(ubc); - return rc; -} - -/* stopurbs - * cancel the USB request blocks for isochronous input and output - * errors are silently ignored - * argument: - * B channel control structure - */ -static void stopurbs(struct bas_bc_state *ubc) -{ - int k, rc; - - atomic_set(&ubc->running, 0); - - for (k = 0; k < BAS_INURBS; ++k) { - rc = usb_unlink_urb(ubc->isoinurbs[k]); - gig_dbg(DEBUG_ISO, - "%s: isoc input URB %d unlinked, result = %s", - __func__, k, get_usb_rcmsg(rc)); - } - - for (k = 0; k < BAS_OUTURBS; ++k) { - rc = usb_unlink_urb(ubc->isoouturbs[k].urb); - gig_dbg(DEBUG_ISO, - "%s: isoc output URB %d unlinked, result = %s", - __func__, k, get_usb_rcmsg(rc)); - } -} - -/* Isochronous Write - Bottom Half */ -/* =============================== */ - -/* submit_iso_write_urb - * fill and submit the next isochronous write URB - * parameters: - * ucx context structure containing URB - * return value: - * number of frames submitted in URB - * 0 if URB not submitted because no data available (isooutbuf busy) - * error code < 0 on error - */ -static int submit_iso_write_urb(struct isow_urbctx_t *ucx) -{ - struct urb *urb = ucx->urb; - struct bas_bc_state *ubc = ucx->bcs->hw.bas; - struct usb_iso_packet_descriptor *ifd; - int corrbytes, nframe, rc; - - /* urb->dev is clobbered by USB subsystem */ - urb->dev = ucx->bcs->cs->hw.bas->udev; - urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = ubc->isooutbuf->data; - urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data); - - for (nframe = 0; nframe < BAS_NUMFRAMES; nframe++) { - ifd = &urb->iso_frame_desc[nframe]; - - /* compute frame length according to flow control */ - ifd->length = BAS_NORMFRAME; - if ((corrbytes = atomic_read(&ubc->corrbytes)) != 0) { - gig_dbg(DEBUG_ISO, "%s: corrbytes=%d", - __func__, corrbytes); - if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME) - corrbytes = BAS_HIGHFRAME - BAS_NORMFRAME; - else if (corrbytes < BAS_LOWFRAME - BAS_NORMFRAME) - corrbytes = BAS_LOWFRAME - BAS_NORMFRAME; - ifd->length += corrbytes; - atomic_add(-corrbytes, &ubc->corrbytes); - } - - /* retrieve block of data to send */ - ifd->offset = gigaset_isowbuf_getbytes(ubc->isooutbuf, - ifd->length); - if (ifd->offset < 0) { - if (ifd->offset == -EBUSY) { - gig_dbg(DEBUG_ISO, - "%s: buffer busy at frame %d", - __func__, nframe); - /* tasklet will be restarted from - gigaset_send_skb() */ - } else { - dev_err(ucx->bcs->cs->dev, - "%s: buffer error %d at frame %d\n", - __func__, ifd->offset, nframe); - return ifd->offset; - } - break; - } - ucx->limit = atomic_read(&ubc->isooutbuf->nextread); - ifd->status = 0; - ifd->actual_length = 0; - } - if (unlikely(nframe == 0)) - return 0; /* no data to send */ - urb->number_of_packets = nframe; - - rc = usb_submit_urb(urb, SLAB_ATOMIC); - if (unlikely(rc)) { - if (rc == -ENODEV) - /* device removed - give up silently */ - gig_dbg(DEBUG_ISO, "%s: disconnected", __func__); - else - dev_err(ucx->bcs->cs->dev, - "could not submit isochronous write URB: %s\n", - get_usb_rcmsg(rc)); - return rc; - } - ++ubc->numsub; - return nframe; -} - -/* write_iso_tasklet - * tasklet scheduled when an isochronous output URB from the Gigaset device - * has completed - * parameter: - * data B channel state structure - */ -static void write_iso_tasklet(unsigned long data) -{ - struct bc_state *bcs = (struct bc_state *) data; - struct bas_bc_state *ubc = bcs->hw.bas; - struct cardstate *cs = bcs->cs; - struct isow_urbctx_t *done, *next, *ovfl; - struct urb *urb; - struct usb_iso_packet_descriptor *ifd; - int offset; - unsigned long flags; - int i; - struct sk_buff *skb; - int len; - int rc; - - /* loop while completed URBs arrive in time */ - for (;;) { - if (unlikely(!(atomic_read(&ubc->running)))) { - gig_dbg(DEBUG_ISO, "%s: not running", __func__); - return; - } - - /* retrieve completed URBs */ - spin_lock_irqsave(&ubc->isooutlock, flags); - done = ubc->isooutdone; - ubc->isooutdone = NULL; - ovfl = ubc->isooutovfl; - ubc->isooutovfl = NULL; - spin_unlock_irqrestore(&ubc->isooutlock, flags); - if (ovfl) { - dev_err(cs->dev, "isochronous write buffer underrun\n"); - error_hangup(bcs); - break; - } - if (!done) - break; - - /* submit free URB if available */ - spin_lock_irqsave(&ubc->isooutlock, flags); - next = ubc->isooutfree; - ubc->isooutfree = NULL; - spin_unlock_irqrestore(&ubc->isooutlock, flags); - if (next) { - rc = submit_iso_write_urb(next); - if (unlikely(rc <= 0 && rc != -ENODEV)) { - /* could not submit URB, put it back */ - spin_lock_irqsave(&ubc->isooutlock, flags); - if (ubc->isooutfree == NULL) { - ubc->isooutfree = next; - next = NULL; - } - spin_unlock_irqrestore(&ubc->isooutlock, flags); - if (next) { - /* couldn't put it back */ - dev_err(cs->dev, - "losing isochronous write URB\n"); - error_hangup(bcs); - } - } - } - - /* process completed URB */ - urb = done->urb; - switch (urb->status) { - case -EXDEV: /* partial completion */ - gig_dbg(DEBUG_ISO, "%s: URB partially completed", - __func__); - /* fall through - what's the difference anyway? */ - case 0: /* normal completion */ - /* inspect individual frames - * assumptions (for lack of documentation): - * - actual_length bytes of first frame in error are - * successfully sent - * - all following frames are not sent at all - */ - offset = done->limit; /* default (no error) */ - for (i = 0; i < BAS_NUMFRAMES; i++) { - ifd = &urb->iso_frame_desc[i]; - if (ifd->status || - ifd->actual_length != ifd->length) { - dev_warn(cs->dev, - "isochronous write: frame %d: %s, " - "only %d of %d bytes sent\n", - i, get_usb_statmsg(ifd->status), - ifd->actual_length, ifd->length); - offset = (ifd->offset + - ifd->actual_length) - % BAS_OUTBUFSIZE; - break; - } - } -#ifdef CONFIG_GIGASET_DEBUG - /* check assumption on remaining frames */ - for (; i < BAS_NUMFRAMES; i++) { - ifd = &urb->iso_frame_desc[i]; - if (ifd->status != -EINPROGRESS - || ifd->actual_length != 0) { - dev_warn(cs->dev, - "isochronous write: frame %d: %s, " - "%d of %d bytes sent\n", - i, get_usb_statmsg(ifd->status), - ifd->actual_length, ifd->length); - offset = (ifd->offset + - ifd->actual_length) - % BAS_OUTBUFSIZE; - break; - } - } -#endif - break; - case -EPIPE: /* stall - probably underrun */ - dev_err(cs->dev, "isochronous write stalled\n"); - error_hangup(bcs); - break; - default: /* severe trouble */ - dev_warn(cs->dev, "isochronous write: %s\n", - get_usb_statmsg(urb->status)); - } - - /* mark the write buffer area covered by this URB as free */ - if (done->limit >= 0) - atomic_set(&ubc->isooutbuf->read, done->limit); - - /* mark URB as free */ - spin_lock_irqsave(&ubc->isooutlock, flags); - next = ubc->isooutfree; - ubc->isooutfree = done; - spin_unlock_irqrestore(&ubc->isooutlock, flags); - if (next) { - /* only one URB still active - resubmit one */ - rc = submit_iso_write_urb(next); - if (unlikely(rc <= 0 && rc != -ENODEV)) { - /* couldn't submit */ - error_hangup(bcs); - } - } - } - - /* process queued SKBs */ - while ((skb = skb_dequeue(&bcs->squeue))) { - /* copy to output buffer, doing L2 encapsulation */ - len = skb->len; - if (gigaset_isoc_buildframe(bcs, skb->data, len) == -EAGAIN) { - /* insufficient buffer space, push back onto queue */ - skb_queue_head(&bcs->squeue, skb); - gig_dbg(DEBUG_ISO, "%s: skb requeued, qlen=%d", - __func__, skb_queue_len(&bcs->squeue)); - break; - } - skb_pull(skb, len); - gigaset_skb_sent(bcs, skb); - dev_kfree_skb_any(skb); - } -} - -/* Isochronous Read - Bottom Half */ -/* ============================== */ - -/* read_iso_tasklet - * tasklet scheduled when an isochronous input URB from the Gigaset device - * has completed - * parameter: - * data B channel state structure - */ -static void read_iso_tasklet(unsigned long data) -{ - struct bc_state *bcs = (struct bc_state *) data; - struct bas_bc_state *ubc = bcs->hw.bas; - struct cardstate *cs = bcs->cs; - struct urb *urb; - char *rcvbuf; - unsigned long flags; - int totleft, numbytes, offset, frame, rc; - - /* loop while more completed URBs arrive in the meantime */ - for (;;) { - /* retrieve URB */ - spin_lock_irqsave(&ubc->isoinlock, flags); - if (!(urb = ubc->isoindone)) { - spin_unlock_irqrestore(&ubc->isoinlock, flags); - return; - } - ubc->isoindone = NULL; - if (unlikely(ubc->loststatus != -EINPROGRESS)) { - dev_warn(cs->dev, - "isochronous read overrun, " - "dropped URB with status: %s, %d bytes lost\n", - get_usb_statmsg(ubc->loststatus), - ubc->isoinlost); - ubc->loststatus = -EINPROGRESS; - } - spin_unlock_irqrestore(&ubc->isoinlock, flags); - - if (unlikely(!(atomic_read(&ubc->running)))) { - gig_dbg(DEBUG_ISO, - "%s: channel not running, " - "dropped URB with status: %s", - __func__, get_usb_statmsg(urb->status)); - return; - } - - switch (urb->status) { - case 0: /* normal completion */ - break; - case -EXDEV: /* inspect individual frames - (we do that anyway) */ - gig_dbg(DEBUG_ISO, "%s: URB partially completed", - __func__); - break; - case -ENOENT: - case -ECONNRESET: - case -EINPROGRESS: - gig_dbg(DEBUG_ISO, "%s: %s", - __func__, get_usb_statmsg(urb->status)); - continue; /* -> skip */ - case -EPIPE: - dev_err(cs->dev, "isochronous read stalled\n"); - error_hangup(bcs); - continue; /* -> skip */ - default: /* severe trouble */ - dev_warn(cs->dev, "isochronous read: %s\n", - get_usb_statmsg(urb->status)); - goto error; - } - - rcvbuf = urb->transfer_buffer; - totleft = urb->actual_length; - for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { - if (unlikely(urb->iso_frame_desc[frame].status)) { - dev_warn(cs->dev, - "isochronous read: frame %d: %s\n", - frame, - get_usb_statmsg( - urb->iso_frame_desc[frame].status)); - break; - } - numbytes = urb->iso_frame_desc[frame].actual_length; - if (unlikely(numbytes > BAS_MAXFRAME)) { - dev_warn(cs->dev, - "isochronous read: frame %d: " - "numbytes (%d) > BAS_MAXFRAME\n", - frame, numbytes); - break; - } - if (unlikely(numbytes > totleft)) { - dev_warn(cs->dev, - "isochronous read: frame %d: " - "numbytes (%d) > totleft (%d)\n", - frame, numbytes, totleft); - break; - } - offset = urb->iso_frame_desc[frame].offset; - if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { - dev_warn(cs->dev, - "isochronous read: frame %d: " - "offset (%d) + numbytes (%d) " - "> BAS_INBUFSIZE\n", - frame, offset, numbytes); - break; - } - gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); - totleft -= numbytes; - } - if (unlikely(totleft > 0)) - dev_warn(cs->dev, - "isochronous read: %d data bytes missing\n", - totleft); - - error: - /* URB processed, resubmit */ - for (frame = 0; frame < BAS_NUMFRAMES; frame++) { - urb->iso_frame_desc[frame].status = 0; - urb->iso_frame_desc[frame].actual_length = 0; - } - /* urb->dev is clobbered by USB subsystem */ - urb->dev = bcs->cs->hw.bas->udev; - urb->transfer_flags = URB_ISO_ASAP; - urb->number_of_packets = BAS_NUMFRAMES; - rc = usb_submit_urb(urb, SLAB_ATOMIC); - if (unlikely(rc != 0 && rc != -ENODEV)) { - dev_err(cs->dev, - "could not resubmit isochronous read URB: %s\n", - get_usb_rcmsg(rc)); - dump_urb(DEBUG_ISO, "resubmit iso read", urb); - error_hangup(bcs); - } - } -} - -/* Channel Operations */ -/* ================== */ - -/* req_timeout - * timeout routine for control output request - * argument: - * B channel control structure - */ -static void req_timeout(unsigned long data) -{ - struct bc_state *bcs = (struct bc_state *) data; - struct bas_cardstate *ucs = bcs->cs->hw.bas; - int pending; - unsigned long flags; - - check_pending(ucs); - - spin_lock_irqsave(&ucs->lock, flags); - pending = ucs->pending; - ucs->pending = 0; - spin_unlock_irqrestore(&ucs->lock, flags); - - switch (pending) { - case 0: /* no pending request */ - gig_dbg(DEBUG_USBREQ, "%s: no request pending", __func__); - break; - - case HD_OPEN_ATCHANNEL: - dev_err(bcs->cs->dev, "timeout opening AT channel\n"); - error_reset(bcs->cs); - break; - - case HD_OPEN_B2CHANNEL: - case HD_OPEN_B1CHANNEL: - dev_err(bcs->cs->dev, "timeout opening channel %d\n", - bcs->channel + 1); - error_hangup(bcs); - break; - - case HD_CLOSE_ATCHANNEL: - dev_err(bcs->cs->dev, "timeout closing AT channel\n"); - break; - - case HD_CLOSE_B2CHANNEL: - case HD_CLOSE_B1CHANNEL: - dev_err(bcs->cs->dev, "timeout closing channel %d\n", - bcs->channel + 1); - break; - - default: - dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", - pending); - } -} - -/* write_ctrl_callback - * USB completion handler for control pipe output - * called by the USB subsystem in interrupt context - * parameter: - * urb USB request block of completed request - * urb->context = hardware specific controller state structure - */ -static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) -{ - struct bas_cardstate *ucs = urb->context; - unsigned long flags; - - spin_lock_irqsave(&ucs->lock, flags); - if (urb->status && ucs->pending) { - dev_err(&ucs->interface->dev, - "control request 0x%02x failed: %s\n", - ucs->pending, get_usb_statmsg(urb->status)); - del_timer(&ucs->timer_ctrl); - ucs->pending = 0; - } - /* individual handling of specific request types */ - switch (ucs->pending) { - case HD_DEVICE_INIT_ACK: /* no reply expected */ - ucs->pending = 0; - break; - } - spin_unlock_irqrestore(&ucs->lock, flags); -} - -/* req_submit - * submit a control output request without message buffer to the Gigaset base - * and optionally start a timeout - * parameters: - * bcs B channel control structure - * req control request code (HD_*) - * val control request parameter value (set to 0 if unused) - * timeout timeout in seconds (0: no timeout) - * return value: - * 0 on success - * -EBUSY if another request is pending - * any URB submission error code - */ -static int req_submit(struct bc_state *bcs, int req, int val, int timeout) -{ - struct bas_cardstate *ucs = bcs->cs->hw.bas; - int ret; - unsigned long flags; - - gig_dbg(DEBUG_USBREQ, "-------> 0x%02x (%d)", req, val); - - spin_lock_irqsave(&ucs->lock, flags); - if (ucs->pending) { - spin_unlock_irqrestore(&ucs->lock, flags); - dev_err(bcs->cs->dev, - "submission of request 0x%02x failed: " - "request 0x%02x still pending\n", - req, ucs->pending); - return -EBUSY; - } - - ucs->dr_ctrl.bRequestType = OUT_VENDOR_REQ; - ucs->dr_ctrl.bRequest = req; - ucs->dr_ctrl.wValue = cpu_to_le16(val); - ucs->dr_ctrl.wIndex = 0; - ucs->dr_ctrl.wLength = 0; - usb_fill_control_urb(ucs->urb_ctrl, ucs->udev, - usb_sndctrlpipe(ucs->udev, 0), - (unsigned char*) &ucs->dr_ctrl, NULL, 0, - write_ctrl_callback, ucs); - if ((ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC)) != 0) { - dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n", - req, get_usb_statmsg(ret)); - spin_unlock_irqrestore(&ucs->lock, flags); - return ret; - } - ucs->pending = req; - - if (timeout > 0) { - gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); - ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; - ucs->timer_ctrl.data = (unsigned long) bcs; - ucs->timer_ctrl.function = req_timeout; - add_timer(&ucs->timer_ctrl); - } - - spin_unlock_irqrestore(&ucs->lock, flags); - return 0; -} - -/* gigaset_init_bchannel - * called by common.c to connect a B channel - * initialize isochronous I/O and tell the Gigaset base to open the channel - * argument: - * B channel control structure - * return value: - * 0 on success, error code < 0 on error - */ -static int gigaset_init_bchannel(struct bc_state *bcs) -{ - int req, ret; - unsigned long flags; - - spin_lock_irqsave(&bcs->cs->lock, flags); - if (unlikely(!bcs->cs->connected)) { - gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - return -ENODEV; - } - - if ((ret = starturbs(bcs)) < 0) { - dev_err(bcs->cs->dev, - "could not start isochronous I/O for channel B%d: %s\n", - bcs->channel + 1, - ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); - if (ret != -ENODEV) - error_hangup(bcs); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - return ret; - } - - req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; - if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { - dev_err(bcs->cs->dev, "could not open channel B%d\n", - bcs->channel + 1); - stopurbs(bcs->hw.bas); - if (ret != -ENODEV) - error_hangup(bcs); - } - - spin_unlock_irqrestore(&bcs->cs->lock, flags); - return ret; -} - -/* gigaset_close_bchannel - * called by common.c to disconnect a B channel - * tell the Gigaset base to close the channel - * stopping isochronous I/O and LL notification will be done when the - * acknowledgement for the close arrives - * argument: - * B channel control structure - * return value: - * 0 on success, error code < 0 on error - */ -static int gigaset_close_bchannel(struct bc_state *bcs) -{ - int req, ret; - unsigned long flags; - - spin_lock_irqsave(&bcs->cs->lock, flags); - if (unlikely(!bcs->cs->connected)) { - spin_unlock_irqrestore(&bcs->cs->lock, flags); - gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); - return -ENODEV; - } - - if (!(atomic_read(&bcs->cs->hw.bas->basstate) & - (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { - /* channel not running: just signal common.c */ - spin_unlock_irqrestore(&bcs->cs->lock, flags); - gigaset_bchannel_down(bcs); - return 0; - } - - /* channel running: tell device to close it */ - req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; - if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) - dev_err(bcs->cs->dev, "closing channel B%d failed\n", - bcs->channel + 1); - - spin_unlock_irqrestore(&bcs->cs->lock, flags); - return ret; -} - -/* Device Operations */ -/* ================= */ - -/* complete_cb - * unqueue first command buffer from queue, waking any sleepers - * must be called with cs->cmdlock held - * parameter: - * cs controller state structure - */ -static void complete_cb(struct cardstate *cs) -{ - struct cmdbuf_t *cb = cs->cmdbuf; - - /* unqueue completed buffer */ - cs->cmdbytes -= cs->curlen; - gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, - "write_command: sent %u bytes, %u left", - cs->curlen, cs->cmdbytes); - if ((cs->cmdbuf = cb->next) != NULL) { - cs->cmdbuf->prev = NULL; - cs->curlen = cs->cmdbuf->len; - } else { - cs->lastcmdbuf = NULL; - cs->curlen = 0; - } - - if (cb->wake_tasklet) - tasklet_schedule(cb->wake_tasklet); - - kfree(cb); -} - -/* write_command_callback - * USB completion handler for AT command transmission - * called by the USB subsystem in interrupt context - * parameter: - * urb USB request block of completed request - * urb->context = controller state structure - */ -static void write_command_callback(struct urb *urb, struct pt_regs *regs) -{ - struct cardstate *cs = urb->context; - struct bas_cardstate *ucs = cs->hw.bas; - unsigned long flags; - - update_basstate(ucs, 0, BS_ATWRPEND); - - /* check status */ - switch (urb->status) { - case 0: /* normal completion */ - break; - case -ENOENT: /* cancelled */ - case -ECONNRESET: /* cancelled (async) */ - case -EINPROGRESS: /* pending */ - case -ENODEV: /* device removed */ - case -ESHUTDOWN: /* device shut down */ - /* ignore silently */ - gig_dbg(DEBUG_USBREQ, "%s: %s", - __func__, get_usb_statmsg(urb->status)); - return; - default: /* any failure */ - if (++ucs->retry_cmd_out > BAS_RETRY) { - dev_warn(cs->dev, - "command write: %s, " - "giving up after %d retries\n", - get_usb_statmsg(urb->status), - ucs->retry_cmd_out); - break; - } - if (cs->cmdbuf == NULL) { - dev_warn(cs->dev, - "command write: %s, " - "cannot retry - cmdbuf gone\n", - get_usb_statmsg(urb->status)); - break; - } - dev_notice(cs->dev, "command write: %s, retry %d\n", - get_usb_statmsg(urb->status), ucs->retry_cmd_out); - if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0) - /* resubmitted - bypass regular exit block */ - return; - /* command send failed, assume base still waiting */ - update_basstate(ucs, BS_ATREADY, 0); - } - - spin_lock_irqsave(&cs->cmdlock, flags); - if (cs->cmdbuf != NULL) - complete_cb(cs); - spin_unlock_irqrestore(&cs->cmdlock, flags); -} - -/* atrdy_timeout - * timeout routine for AT command transmission - * argument: - * controller state structure - */ -static void atrdy_timeout(unsigned long data) -{ - struct cardstate *cs = (struct cardstate *) data; - struct bas_cardstate *ucs = cs->hw.bas; - - dev_warn(cs->dev, "timeout waiting for HD_READY_SEND_ATDATA\n"); - - /* fake the missing signal - what else can I do? */ - update_basstate(ucs, BS_ATREADY, BS_ATTIMER); - start_cbsend(cs); -} - -/* atwrite_submit - * submit an HD_WRITE_ATMESSAGE command URB - * parameters: - * cs controller state structure - * buf buffer containing command to send - * len length of command to send - * return value: - * 0 on success - * -EBUSY if another request is pending - * any URB submission error code - */ -static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) -{ - struct bas_cardstate *ucs = cs->hw.bas; - int rc; - - gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); - - if (update_basstate(ucs, BS_ATWRPEND, 0) & BS_ATWRPEND) { - dev_err(cs->dev, - "could not submit HD_WRITE_ATMESSAGE: URB busy\n"); - return -EBUSY; - } - - ucs->dr_cmd_out.bRequestType = OUT_VENDOR_REQ; - ucs->dr_cmd_out.bRequest = HD_WRITE_ATMESSAGE; - ucs->dr_cmd_out.wValue = 0; - ucs->dr_cmd_out.wIndex = 0; - ucs->dr_cmd_out.wLength = cpu_to_le16(len); - usb_fill_control_urb(ucs->urb_cmd_out, ucs->udev, - usb_sndctrlpipe(ucs->udev, 0), - (unsigned char*) &ucs->dr_cmd_out, buf, len, - write_command_callback, cs); - rc = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC); - if (unlikely(rc)) { - update_basstate(ucs, 0, BS_ATWRPEND); - dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", - get_usb_rcmsg(rc)); - return rc; - } - - /* submitted successfully, start timeout if necessary */ - if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) { - gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", - ATRDY_TIMEOUT); - ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; - ucs->timer_atrdy.data = (unsigned long) cs; - ucs->timer_atrdy.function = atrdy_timeout; - add_timer(&ucs->timer_atrdy); - } - return 0; -} - -/* start_cbsend - * start transmission of AT command queue if necessary - * parameter: - * cs controller state structure - * return value: - * 0 on success - * error code < 0 on error - */ -static int start_cbsend(struct cardstate *cs) -{ - struct cmdbuf_t *cb; - struct bas_cardstate *ucs = cs->hw.bas; - unsigned long flags; - int rc; - int retval = 0; - - /* check if AT channel is open */ - if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) { - gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); - rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); - if (rc < 0) { - /* flush command queue */ - spin_lock_irqsave(&cs->cmdlock, flags); - while (cs->cmdbuf != NULL) - complete_cb(cs); - spin_unlock_irqrestore(&cs->cmdlock, flags); - } - return rc; - } - - /* try to send first command in queue */ - spin_lock_irqsave(&cs->cmdlock, flags); - - while ((cb = cs->cmdbuf) != NULL && - atomic_read(&ucs->basstate) & BS_ATREADY) { - ucs->retry_cmd_out = 0; - rc = atwrite_submit(cs, cb->buf, cb->len); - if (unlikely(rc)) { - retval = rc; - complete_cb(cs); - } - } - - spin_unlock_irqrestore(&cs->cmdlock, flags); - return retval; -} - -/* gigaset_write_cmd - * This function is called by the device independent part of the driver - * to transmit an AT command string to the Gigaset device. - * It encapsulates the device specific method for transmission over the - * direct USB connection to the base. - * The command string is added to the queue of commands to send, and - * USB transmission is started if necessary. - * parameters: - * cs controller state structure - * buf command string to send - * len number of bytes to send (max. IF_WRITEBUF) - * wake_tasklet tasklet to run when transmission is completed - * (NULL if none) - * return value: - * number of bytes queued on success - * error code < 0 on error - */ -static int gigaset_write_cmd(struct cardstate *cs, - const unsigned char *buf, int len, - struct tasklet_struct *wake_tasklet) -{ - struct cmdbuf_t *cb; - unsigned long flags; - int status; - - gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? - DEBUG_TRANSCMD : DEBUG_LOCKCMD, - "CMD Transmit", len, buf); - - if (len <= 0) - return 0; /* nothing to do */ - - if (len > IF_WRITEBUF) - len = IF_WRITEBUF; - if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { - dev_err(cs->dev, "%s: out of memory\n", __func__); - return -ENOMEM; - } - - memcpy(cb->buf, buf, len); - cb->len = len; - cb->offset = 0; - cb->next = NULL; - cb->wake_tasklet = wake_tasklet; - - spin_lock_irqsave(&cs->cmdlock, flags); - cb->prev = cs->lastcmdbuf; - if (cs->lastcmdbuf) - cs->lastcmdbuf->next = cb; - else { - cs->cmdbuf = cb; - cs->curlen = len; - } - cs->cmdbytes += len; - cs->lastcmdbuf = cb; - spin_unlock_irqrestore(&cs->cmdlock, flags); - - spin_lock_irqsave(&cs->lock, flags); - if (unlikely(!cs->connected)) { - spin_unlock_irqrestore(&cs->lock, flags); - gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); - return -ENODEV; - } - status = start_cbsend(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return status < 0 ? status : len; -} - -/* gigaset_write_room - * tty_driver.write_room interface routine - * return number of characters the driver will accept to be written via - * gigaset_write_cmd - * parameter: - * controller state structure - * return value: - * number of characters - */ -static int gigaset_write_room(struct cardstate *cs) -{ - return IF_WRITEBUF; -} - -/* gigaset_chars_in_buffer - * tty_driver.chars_in_buffer interface routine - * return number of characters waiting to be sent - * parameter: - * controller state structure - * return value: - * number of characters - */ -static int gigaset_chars_in_buffer(struct cardstate *cs) -{ - unsigned long flags; - unsigned bytes; - - spin_lock_irqsave(&cs->cmdlock, flags); - bytes = cs->cmdbytes; - spin_unlock_irqrestore(&cs->cmdlock, flags); - - return bytes; -} - -/* gigaset_brkchars - * implementation of ioctl(GIGASET_BRKCHARS) - * parameter: - * controller state structure - * return value: - * -EINVAL (unimplemented function) - */ -static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) -{ - return -EINVAL; -} - - -/* Device Initialization/Shutdown */ -/* ============================== */ - -/* Free hardware dependent part of the B channel structure - * parameter: - * bcs B channel structure - * return value: - * !=0 on success - */ -static int gigaset_freebcshw(struct bc_state *bcs) -{ - struct bas_bc_state *ubc = bcs->hw.bas; - int i; - - if (!ubc) - return 0; - - /* kill URBs and tasklets before freeing - better safe than sorry */ - atomic_set(&ubc->running, 0); - for (i = 0; i < BAS_OUTURBS; ++i) - if (ubc->isoouturbs[i].urb) { - gig_dbg(DEBUG_INIT, "%s: killing iso out URB %d", - __func__, i); - usb_kill_urb(ubc->isoouturbs[i].urb); - usb_free_urb(ubc->isoouturbs[i].urb); - } - for (i = 0; i < BAS_INURBS; ++i) - if (ubc->isoinurbs[i]) { - gig_dbg(DEBUG_INIT, "%s: killing iso in URB %d", - __func__, i); - usb_kill_urb(ubc->isoinurbs[i]); - usb_free_urb(ubc->isoinurbs[i]); - } - tasklet_kill(&ubc->sent_tasklet); - tasklet_kill(&ubc->rcvd_tasklet); - kfree(ubc->isooutbuf); - kfree(ubc); - bcs->hw.bas = NULL; - return 1; -} - -/* Initialize hardware dependent part of the B channel structure - * parameter: - * bcs B channel structure - * return value: - * !=0 on success - */ -static int gigaset_initbcshw(struct bc_state *bcs) -{ - int i; - struct bas_bc_state *ubc; - - bcs->hw.bas = ubc = kmalloc(sizeof(struct bas_bc_state), GFP_KERNEL); - if (!ubc) { - err("could not allocate bas_bc_state"); - return 0; - } - - atomic_set(&ubc->running, 0); - atomic_set(&ubc->corrbytes, 0); - spin_lock_init(&ubc->isooutlock); - for (i = 0; i < BAS_OUTURBS; ++i) { - ubc->isoouturbs[i].urb = NULL; - ubc->isoouturbs[i].bcs = bcs; - } - ubc->isooutdone = ubc->isooutfree = ubc->isooutovfl = NULL; - ubc->numsub = 0; - if (!(ubc->isooutbuf = kmalloc(sizeof(struct isowbuf_t), GFP_KERNEL))) { - err("could not allocate isochronous output buffer"); - kfree(ubc); - bcs->hw.bas = NULL; - return 0; - } - tasklet_init(&ubc->sent_tasklet, - &write_iso_tasklet, (unsigned long) bcs); - - spin_lock_init(&ubc->isoinlock); - for (i = 0; i < BAS_INURBS; ++i) - ubc->isoinurbs[i] = NULL; - ubc->isoindone = NULL; - ubc->loststatus = -EINPROGRESS; - ubc->isoinlost = 0; - ubc->seqlen = 0; - ubc->inbyte = 0; - ubc->inbits = 0; - ubc->goodbytes = 0; - ubc->alignerrs = 0; - ubc->fcserrs = 0; - ubc->frameerrs = 0; - ubc->giants = 0; - ubc->runts = 0; - ubc->aborts = 0; - ubc->shared0s = 0; - ubc->stolen0s = 0; - tasklet_init(&ubc->rcvd_tasklet, - &read_iso_tasklet, (unsigned long) bcs); - return 1; -} - -static void gigaset_reinitbcshw(struct bc_state *bcs) -{ - struct bas_bc_state *ubc = bcs->hw.bas; - - atomic_set(&bcs->hw.bas->running, 0); - atomic_set(&bcs->hw.bas->corrbytes, 0); - bcs->hw.bas->numsub = 0; - spin_lock_init(&ubc->isooutlock); - spin_lock_init(&ubc->isoinlock); - ubc->loststatus = -EINPROGRESS; -} - -static void gigaset_freecshw(struct cardstate *cs) -{ - /* timers, URBs and rcvbuf are disposed of in disconnect */ - kfree(cs->hw.bas); - cs->hw.bas = NULL; -} - -static int gigaset_initcshw(struct cardstate *cs) -{ - struct bas_cardstate *ucs; - - cs->hw.bas = ucs = kmalloc(sizeof *ucs, GFP_KERNEL); - if (!ucs) - return 0; - - ucs->urb_cmd_in = NULL; - ucs->urb_cmd_out = NULL; - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - - spin_lock_init(&ucs->lock); - ucs->pending = 0; - - atomic_set(&ucs->basstate, 0); - init_timer(&ucs->timer_ctrl); - init_timer(&ucs->timer_atrdy); - init_timer(&ucs->timer_cmd_in); - - return 1; -} - -/* freeurbs - * unlink and deallocate all URBs unconditionally - * caller must make sure that no commands are still in progress - * parameter: - * cs controller state structure - */ -static void freeurbs(struct cardstate *cs) -{ - struct bas_cardstate *ucs = cs->hw.bas; - struct bas_bc_state *ubc; - int i, j; - - for (j = 0; j < 2; ++j) { - ubc = cs->bcs[j].hw.bas; - for (i = 0; i < BAS_OUTURBS; ++i) - if (ubc->isoouturbs[i].urb) { - usb_kill_urb(ubc->isoouturbs[i].urb); - gig_dbg(DEBUG_INIT, - "%s: isoc output URB %d/%d unlinked", - __func__, j, i); - usb_free_urb(ubc->isoouturbs[i].urb); - ubc->isoouturbs[i].urb = NULL; - } - for (i = 0; i < BAS_INURBS; ++i) - if (ubc->isoinurbs[i]) { - usb_kill_urb(ubc->isoinurbs[i]); - gig_dbg(DEBUG_INIT, - "%s: isoc input URB %d/%d unlinked", - __func__, j, i); - usb_free_urb(ubc->isoinurbs[i]); - ubc->isoinurbs[i] = NULL; - } - } - if (ucs->urb_int_in) { - usb_kill_urb(ucs->urb_int_in); - gig_dbg(DEBUG_INIT, "%s: interrupt input URB unlinked", - __func__); - usb_free_urb(ucs->urb_int_in); - ucs->urb_int_in = NULL; - } - if (ucs->urb_cmd_out) { - usb_kill_urb(ucs->urb_cmd_out); - gig_dbg(DEBUG_INIT, "%s: command output URB unlinked", - __func__); - usb_free_urb(ucs->urb_cmd_out); - ucs->urb_cmd_out = NULL; - } - if (ucs->urb_cmd_in) { - usb_kill_urb(ucs->urb_cmd_in); - gig_dbg(DEBUG_INIT, "%s: command input URB unlinked", - __func__); - usb_free_urb(ucs->urb_cmd_in); - ucs->urb_cmd_in = NULL; - } - if (ucs->urb_ctrl) { - usb_kill_urb(ucs->urb_ctrl); - gig_dbg(DEBUG_INIT, "%s: control output URB unlinked", - __func__); - usb_free_urb(ucs->urb_ctrl); - ucs->urb_ctrl = NULL; - } -} - -/* gigaset_probe - * This function is called when a new USB device is connected. - * It checks whether the new device is handled by this driver. - */ -static int gigaset_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct usb_host_interface *hostif; - struct usb_device *udev = interface_to_usbdev(interface); - struct cardstate *cs = NULL; - struct bas_cardstate *ucs = NULL; - struct bas_bc_state *ubc; - struct usb_endpoint_descriptor *endpoint; - int i, j; - int rc; - - gig_dbg(DEBUG_ANY, - "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", - __func__, le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - /* set required alternate setting */ - hostif = interface->cur_altsetting; - if (hostif->desc.bAlternateSetting != 3) { - gig_dbg(DEBUG_ANY, - "%s: wrong alternate setting %d - trying to switch", - __func__, hostif->desc.bAlternateSetting); - if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3) < 0) { - dev_warn(&udev->dev, "usb_set_interface failed, " - "device %d interface %d altsetting %d\n", - udev->devnum, hostif->desc.bInterfaceNumber, - hostif->desc.bAlternateSetting); - return -ENODEV; - } - hostif = interface->cur_altsetting; - } - - /* Reject application specific interfaces - */ - if (hostif->desc.bInterfaceClass != 255) { - dev_warn(&udev->dev, "%s: bInterfaceClass == %d\n", - __func__, hostif->desc.bInterfaceClass); - return -ENODEV; - } - - dev_info(&udev->dev, - "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n", - __func__, le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - cs = gigaset_getunassignedcs(driver); - if (!cs) { - dev_err(&udev->dev, "no free cardstate\n"); - return -ENODEV; - } - ucs = cs->hw.bas; - - /* save off device structure ptrs for later use */ - usb_get_dev(udev); - ucs->udev = udev; - ucs->interface = interface; - cs->dev = &interface->dev; - - /* allocate URBs: - * - one for the interrupt pipe - * - three for the different uses of the default control pipe - * - three for each isochronous pipe - */ - if (!(ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL)) || - !(ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL)) || - !(ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL)) || - !(ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL))) - goto allocerr; - - for (j = 0; j < 2; ++j) { - ubc = cs->bcs[j].hw.bas; - for (i = 0; i < BAS_OUTURBS; ++i) - if (!(ubc->isoouturbs[i].urb = - usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL))) - goto allocerr; - for (i = 0; i < BAS_INURBS; ++i) - if (!(ubc->isoinurbs[i] = - usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL))) - goto allocerr; - } - - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - - /* Fill the interrupt urb and send it to the core */ - endpoint = &hostif->endpoint[0].desc; - usb_fill_int_urb(ucs->urb_int_in, udev, - usb_rcvintpipe(udev, - (endpoint->bEndpointAddress) & 0x0f), - ucs->int_in_buf, 3, read_int_callback, cs, - endpoint->bInterval); - if ((rc = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL)) != 0) { - dev_err(cs->dev, "could not submit interrupt URB: %s\n", - get_usb_rcmsg(rc)); - goto error; - } - - /* tell the device that the driver is ready */ - if ((rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0) - goto error; - - /* tell common part that the device is ready */ - if (startmode == SM_LOCKED) - atomic_set(&cs->mstate, MS_LOCKED); - - /* save address of controller structure */ - usb_set_intfdata(interface, cs); - - if (!gigaset_start(cs)) - goto error; - - return 0; - -allocerr: - dev_err(cs->dev, "could not allocate URBs\n"); -error: - freeurbs(cs); - usb_set_intfdata(interface, NULL); - gigaset_unassign(cs); - return -ENODEV; -} - -/* gigaset_disconnect - * This function is called when the Gigaset base is unplugged. - */ -static void gigaset_disconnect(struct usb_interface *interface) -{ - struct cardstate *cs; - struct bas_cardstate *ucs; - int j; - - cs = usb_get_intfdata(interface); - - ucs = cs->hw.bas; - - dev_info(cs->dev, "disconnecting Gigaset base\n"); - - /* mark base as not ready, all channels disconnected */ - atomic_set(&ucs->basstate, 0); - - /* tell LL all channels are down */ - //FIXME shouldn't gigaset_stop() do this? - for (j = 0; j < 2; ++j) - gigaset_bchannel_down(cs->bcs + j); - - /* stop driver (common part) */ - gigaset_stop(cs); - - /* stop timers and URBs, free ressources */ - del_timer_sync(&ucs->timer_ctrl); - del_timer_sync(&ucs->timer_atrdy); - del_timer_sync(&ucs->timer_cmd_in); - freeurbs(cs); - usb_set_intfdata(interface, NULL); - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - usb_put_dev(ucs->udev); - ucs->interface = NULL; - ucs->udev = NULL; - cs->dev = NULL; - gigaset_unassign(cs); -} - -static struct gigaset_ops gigops = { - gigaset_write_cmd, - gigaset_write_room, - gigaset_chars_in_buffer, - gigaset_brkchars, - gigaset_init_bchannel, - gigaset_close_bchannel, - gigaset_initbcshw, - gigaset_freebcshw, - gigaset_reinitbcshw, - gigaset_initcshw, - gigaset_freecshw, - gigaset_set_modem_ctrl, - gigaset_baud_rate, - gigaset_set_line_ctrl, - gigaset_isoc_send_skb, - gigaset_isoc_input, -}; - -/* bas_gigaset_init - * This function is called after the kernel module is loaded. - */ -static int __init bas_gigaset_init(void) -{ - int result; - - /* allocate memory for our driver state and intialize it */ - if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, - GIGASET_MODULENAME, GIGASET_DEVNAME, - GIGASET_DEVFSNAME, &gigops, - THIS_MODULE)) == NULL) - goto error; - - /* allocate memory for our device state and intialize it */ - cardstate = gigaset_initcs(driver, 2, 0, 0, cidmode, - GIGASET_MODULENAME); - if (!cardstate) - goto error; - - /* register this driver with the USB subsystem */ - result = usb_register(&gigaset_usb_driver); - if (result < 0) { - err("usb_register failed (error %d)", -result); - goto error; - } - - info(DRIVER_AUTHOR); - info(DRIVER_DESC); - return 0; - -error: if (cardstate) - gigaset_freecs(cardstate); - cardstate = NULL; - if (driver) - gigaset_freedriver(driver); - driver = NULL; - return -1; -} - -/* bas_gigaset_exit - * This function is called before the kernel module is unloaded. - */ -static void __exit bas_gigaset_exit(void) -{ - struct bas_cardstate *ucs = cardstate->hw.bas; - - gigaset_blockdriver(driver); /* => probe will fail - * => no gigaset_start any more - */ - - gigaset_shutdown(cardstate); - /* from now on, no isdn callback should be possible */ - - /* close all still open channels */ - if (atomic_read(&ucs->basstate) & BS_B1OPEN) { - gig_dbg(DEBUG_INIT, "closing B1 channel"); - usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), - HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ, 0, 0, - NULL, 0, BAS_TIMEOUT); - } - if (atomic_read(&ucs->basstate) & BS_B2OPEN) { - gig_dbg(DEBUG_INIT, "closing B2 channel"); - usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), - HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ, 0, 0, - NULL, 0, BAS_TIMEOUT); - } - if (atomic_read(&ucs->basstate) & BS_ATOPEN) { - gig_dbg(DEBUG_INIT, "closing AT channel"); - usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), - HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ, 0, 0, - NULL, 0, BAS_TIMEOUT); - } - atomic_set(&ucs->basstate, 0); - - /* deregister this driver with the USB subsystem */ - usb_deregister(&gigaset_usb_driver); - /* this will call the disconnect-callback */ - /* from now on, no disconnect/probe callback should be running */ - - gigaset_freecs(cardstate); - cardstate = NULL; - gigaset_freedriver(driver); - driver = NULL; -} - - -module_init(bas_gigaset_init); -module_exit(bas_gigaset_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c deleted file mode 100644 index e55767b2c..000000000 --- a/drivers/isdn/gigaset/common.c +++ /dev/null @@ -1,1233 +0,0 @@ -/* - * Stuff used by all variants of the driver - * - * Copyright (c) 2001 by Stefan Eilers, - * Hansjoerg Lipp , - * Tilman Schmidt . - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" -#include -#include -#include - -/* Version Information */ -#define DRIVER_AUTHOR "Hansjoerg Lipp , Tilman Schmidt , Stefan Eilers" -#define DRIVER_DESC "Driver for Gigaset 307x" - -/* Module parameters */ -int gigaset_debuglevel = DEBUG_DEFAULT; -EXPORT_SYMBOL_GPL(gigaset_debuglevel); -module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(debug, "debug level"); - -/* driver state flags */ -#define VALID_MINOR 0x01 -#define VALID_ID 0x02 -#define ASSIGNED 0x04 - -/* bitwise byte inversion table */ -__u8 gigaset_invtab[256] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; -EXPORT_SYMBOL_GPL(gigaset_invtab); - -void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, - size_t len, const unsigned char *buf) -{ - unsigned char outbuf[80]; - unsigned char c; - size_t space = sizeof outbuf - 1; - unsigned char *out = outbuf; - size_t numin = len; - - while (numin--) { - c = *buf++; - if (c == '~' || c == '^' || c == '\\') { - if (!space--) - break; - *out++ = '\\'; - } - if (c & 0x80) { - if (!space--) - break; - *out++ = '~'; - c ^= 0x80; - } - if (c < 0x20 || c == 0x7f) { - if (!space--) - break; - *out++ = '^'; - c ^= 0x40; - } - if (!space--) - break; - *out++ = c; - } - *out = 0; - - gig_dbg(level, "%s (%u bytes): %s", msg, (unsigned) len, outbuf); -} -EXPORT_SYMBOL_GPL(gigaset_dbg_buffer); - -static int setflags(struct cardstate *cs, unsigned flags, unsigned delay) -{ - int r; - - r = cs->ops->set_modem_ctrl(cs, cs->control_state, flags); - cs->control_state = flags; - if (r < 0) - return r; - - if (delay) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(delay * HZ / 1000); - } - - return 0; -} - -int gigaset_enterconfigmode(struct cardstate *cs) -{ - int i, r; - - cs->control_state = TIOCM_RTS; //FIXME - - r = setflags(cs, TIOCM_DTR, 200); - if (r < 0) - goto error; - r = setflags(cs, 0, 200); - if (r < 0) - goto error; - for (i = 0; i < 5; ++i) { - r = setflags(cs, TIOCM_RTS, 100); - if (r < 0) - goto error; - r = setflags(cs, 0, 100); - if (r < 0) - goto error; - } - r = setflags(cs, TIOCM_RTS|TIOCM_DTR, 800); - if (r < 0) - goto error; - - return 0; - -error: - dev_err(cs->dev, "error %d on setuartbits\n", -r); - cs->control_state = TIOCM_RTS|TIOCM_DTR; // FIXME is this a good value? - cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR); - - return -1; //r -} - -static int test_timeout(struct at_state_t *at_state) -{ - if (!at_state->timer_expires) - return 0; - - if (--at_state->timer_expires) { - gig_dbg(DEBUG_MCMD, "decreased timer of %p to %lu", - at_state, at_state->timer_expires); - return 0; - } - - if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL, - at_state->timer_index, NULL)) { - //FIXME what should we do? - } - - return 1; -} - -static void timer_tick(unsigned long data) -{ - struct cardstate *cs = (struct cardstate *) data; - unsigned long flags; - unsigned channel; - struct at_state_t *at_state; - int timeout = 0; - - spin_lock_irqsave(&cs->lock, flags); - - for (channel = 0; channel < cs->channels; ++channel) - if (test_timeout(&cs->bcs[channel].at_state)) - timeout = 1; - - if (test_timeout(&cs->at_state)) - timeout = 1; - - list_for_each_entry(at_state, &cs->temp_at_states, list) - if (test_timeout(at_state)) - timeout = 1; - - if (cs->running) { - mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK)); - if (timeout) { - gig_dbg(DEBUG_CMD, "scheduling timeout"); - tasklet_schedule(&cs->event_tasklet); - } - } - - spin_unlock_irqrestore(&cs->lock, flags); -} - -int gigaset_get_channel(struct bc_state *bcs) -{ - unsigned long flags; - - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->use_count) { - gig_dbg(DEBUG_ANY, "could not allocate channel %d", - bcs->channel); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - return 0; - } - ++bcs->use_count; - bcs->busy = 1; - gig_dbg(DEBUG_ANY, "allocated channel %d", bcs->channel); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - return 1; -} - -void gigaset_free_channel(struct bc_state *bcs) -{ - unsigned long flags; - - spin_lock_irqsave(&bcs->cs->lock, flags); - if (!bcs->busy) { - gig_dbg(DEBUG_ANY, "could not free channel %d", bcs->channel); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - return; - } - --bcs->use_count; - bcs->busy = 0; - gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel); - spin_unlock_irqrestore(&bcs->cs->lock, flags); -} - -int gigaset_get_channels(struct cardstate *cs) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&cs->lock, flags); - for (i = 0; i < cs->channels; ++i) - if (cs->bcs[i].use_count) { - spin_unlock_irqrestore(&cs->lock, flags); - gig_dbg(DEBUG_ANY, "could not allocate all channels"); - return 0; - } - for (i = 0; i < cs->channels; ++i) - ++cs->bcs[i].use_count; - spin_unlock_irqrestore(&cs->lock, flags); - - gig_dbg(DEBUG_ANY, "allocated all channels"); - - return 1; -} - -void gigaset_free_channels(struct cardstate *cs) -{ - unsigned long flags; - int i; - - gig_dbg(DEBUG_ANY, "unblocking all channels"); - spin_lock_irqsave(&cs->lock, flags); - for (i = 0; i < cs->channels; ++i) - --cs->bcs[i].use_count; - spin_unlock_irqrestore(&cs->lock, flags); -} - -void gigaset_block_channels(struct cardstate *cs) -{ - unsigned long flags; - int i; - - gig_dbg(DEBUG_ANY, "blocking all channels"); - spin_lock_irqsave(&cs->lock, flags); - for (i = 0; i < cs->channels; ++i) - ++cs->bcs[i].use_count; - spin_unlock_irqrestore(&cs->lock, flags); -} - -static void clear_events(struct cardstate *cs) -{ - struct event_t *ev; - unsigned head, tail; - unsigned long flags; - - spin_lock_irqsave(&cs->ev_lock, flags); - - head = cs->ev_head; - tail = cs->ev_tail; - - while (tail != head) { - ev = cs->events + head; - kfree(ev->ptr); - head = (head + 1) % MAX_EVENTS; - } - - cs->ev_head = tail; - - spin_unlock_irqrestore(&cs->ev_lock, flags); -} - -struct event_t *gigaset_add_event(struct cardstate *cs, - struct at_state_t *at_state, int type, - void *ptr, int parameter, void *arg) -{ - unsigned long flags; - unsigned next, tail; - struct event_t *event = NULL; - - spin_lock_irqsave(&cs->ev_lock, flags); - - tail = cs->ev_tail; - next = (tail + 1) % MAX_EVENTS; - if (unlikely(next == cs->ev_head)) - err("event queue full"); - else { - event = cs->events + tail; - event->type = type; - event->at_state = at_state; - event->cid = -1; - event->ptr = ptr; - event->arg = arg; - event->parameter = parameter; - cs->ev_tail = next; - } - - spin_unlock_irqrestore(&cs->ev_lock, flags); - - return event; -} -EXPORT_SYMBOL_GPL(gigaset_add_event); - -static void free_strings(struct at_state_t *at_state) -{ - int i; - - for (i = 0; i < STR_NUM; ++i) { - kfree(at_state->str_var[i]); - at_state->str_var[i] = NULL; - } -} - -static void clear_at_state(struct at_state_t *at_state) -{ - free_strings(at_state); -} - -static void dealloc_at_states(struct cardstate *cs) -{ - struct at_state_t *cur, *next; - - list_for_each_entry_safe(cur, next, &cs->temp_at_states, list) { - list_del(&cur->list); - free_strings(cur); - kfree(cur); - } -} - -static void gigaset_freebcs(struct bc_state *bcs) -{ - int i; - - gig_dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel); - if (!bcs->cs->ops->freebcshw(bcs)) { - gig_dbg(DEBUG_INIT, "failed"); - } - - gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel); - clear_at_state(&bcs->at_state); - gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel); - - if (bcs->skb) - dev_kfree_skb(bcs->skb); - for (i = 0; i < AT_NUM; ++i) { - kfree(bcs->commands[i]); - bcs->commands[i] = NULL; - } -} - -static struct cardstate *alloc_cs(struct gigaset_driver *drv) -{ - unsigned long flags; - unsigned i; - static struct cardstate *ret = NULL; - - spin_lock_irqsave(&drv->lock, flags); - for (i = 0; i < drv->minors; ++i) { - if (!(drv->flags[i] & VALID_MINOR)) { - drv->flags[i] = VALID_MINOR; - ret = drv->cs + i; - } - if (ret) - break; - } - spin_unlock_irqrestore(&drv->lock, flags); - return ret; -} - -static void free_cs(struct cardstate *cs) -{ - unsigned long flags; - struct gigaset_driver *drv = cs->driver; - spin_lock_irqsave(&drv->lock, flags); - drv->flags[cs->minor_index] = 0; - spin_unlock_irqrestore(&drv->lock, flags); -} - -static void make_valid(struct cardstate *cs, unsigned mask) -{ - unsigned long flags; - struct gigaset_driver *drv = cs->driver; - spin_lock_irqsave(&drv->lock, flags); - drv->flags[cs->minor_index] |= mask; - spin_unlock_irqrestore(&drv->lock, flags); -} - -static void make_invalid(struct cardstate *cs, unsigned mask) -{ - unsigned long flags; - struct gigaset_driver *drv = cs->driver; - spin_lock_irqsave(&drv->lock, flags); - drv->flags[cs->minor_index] &= ~mask; - spin_unlock_irqrestore(&drv->lock, flags); -} - -void gigaset_freecs(struct cardstate *cs) -{ - int i; - unsigned long flags; - - if (!cs) - return; - - mutex_lock(&cs->mutex); - - if (!cs->bcs) - goto f_cs; - if (!cs->inbuf) - goto f_bcs; - - spin_lock_irqsave(&cs->lock, flags); - cs->running = 0; - spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are - not rescheduled below */ - - tasklet_kill(&cs->event_tasklet); - del_timer_sync(&cs->timer); - - switch (cs->cs_init) { - default: - gigaset_if_free(cs); - - gig_dbg(DEBUG_INIT, "clearing hw"); - cs->ops->freecshw(cs); - - //FIXME cmdbuf - - /* fall through */ - case 2: /* error in initcshw */ - /* Deregister from LL */ - make_invalid(cs, VALID_ID); - gig_dbg(DEBUG_INIT, "clearing iif"); - gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); - - /* fall through */ - case 1: /* error when regestering to LL */ - gig_dbg(DEBUG_INIT, "clearing at_state"); - clear_at_state(&cs->at_state); - dealloc_at_states(cs); - - /* fall through */ - case 0: /* error in one call to initbcs */ - for (i = 0; i < cs->channels; ++i) { - gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i); - gigaset_freebcs(cs->bcs + i); - } - - clear_events(cs); - gig_dbg(DEBUG_INIT, "freeing inbuf"); - kfree(cs->inbuf); - } -f_bcs: gig_dbg(DEBUG_INIT, "freeing bcs[]"); - kfree(cs->bcs); -f_cs: gig_dbg(DEBUG_INIT, "freeing cs"); - mutex_unlock(&cs->mutex); - free_cs(cs); -} -EXPORT_SYMBOL_GPL(gigaset_freecs); - -void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, - struct cardstate *cs, int cid) -{ - int i; - - INIT_LIST_HEAD(&at_state->list); - at_state->waiting = 0; - at_state->getstring = 0; - at_state->pending_commands = 0; - at_state->timer_expires = 0; - at_state->timer_active = 0; - at_state->timer_index = 0; - at_state->seq_index = 0; - at_state->ConState = 0; - for (i = 0; i < STR_NUM; ++i) - at_state->str_var[i] = NULL; - at_state->int_var[VAR_ZDLE] = 0; - at_state->int_var[VAR_ZCTP] = -1; - at_state->int_var[VAR_ZSAU] = ZSAU_NULL; - at_state->cs = cs; - at_state->bcs = bcs; - at_state->cid = cid; - if (!cid) - at_state->replystruct = cs->tabnocid; - else - at_state->replystruct = cs->tabcid; -} - - -static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, - struct cardstate *cs, int inputstate) -/* inbuf->read must be allocated before! */ -{ - atomic_set(&inbuf->head, 0); - atomic_set(&inbuf->tail, 0); - inbuf->cs = cs; - inbuf->bcs = bcs; /*base driver: NULL*/ - inbuf->rcvbuf = NULL; //FIXME - inbuf->inputstate = inputstate; -} - -/* append received bytes to inbuf */ -int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, - unsigned numbytes) -{ - unsigned n, head, tail, bytesleft; - - gig_dbg(DEBUG_INTR, "received %u bytes", numbytes); - - if (!numbytes) - return 0; - - bytesleft = numbytes; - tail = atomic_read(&inbuf->tail); - head = atomic_read(&inbuf->head); - gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); - - while (bytesleft) { - if (head > tail) - n = head - 1 - tail; - else if (head == 0) - n = (RBUFSIZE-1) - tail; - else - n = RBUFSIZE - tail; - if (!n) { - dev_err(inbuf->cs->dev, - "buffer overflow (%u bytes lost)", bytesleft); - break; - } - if (n > bytesleft) - n = bytesleft; - memcpy(inbuf->data + tail, src, n); - bytesleft -= n; - tail = (tail + n) % RBUFSIZE; - src += n; - } - gig_dbg(DEBUG_INTR, "setting tail to %u", tail); - atomic_set(&inbuf->tail, tail); - return numbytes != bytesleft; -} -EXPORT_SYMBOL_GPL(gigaset_fill_inbuf); - -/* Initialize the b-channel structure */ -static struct bc_state *gigaset_initbcs(struct bc_state *bcs, - struct cardstate *cs, int channel) -{ - int i; - - bcs->tx_skb = NULL; //FIXME -> hw part - - skb_queue_head_init(&bcs->squeue); - - bcs->corrupted = 0; - bcs->trans_down = 0; - bcs->trans_up = 0; - - gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel); - gigaset_at_init(&bcs->at_state, bcs, cs, -1); - - bcs->rcvbytes = 0; - -#ifdef CONFIG_GIGASET_DEBUG - bcs->emptycount = 0; -#endif - - gig_dbg(DEBUG_INIT, "allocating bcs[%d]->skb", channel); - bcs->fcs = PPP_INITFCS; - bcs->inputstate = 0; - if (cs->ignoreframes) { - bcs->inputstate |= INS_skip_frame; - bcs->skb = NULL; - } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) - skb_reserve(bcs->skb, HW_HDR_LEN); - else { - dev_warn(cs->dev, "could not allocate skb\n"); - bcs->inputstate |= INS_skip_frame; - } - - bcs->channel = channel; - bcs->cs = cs; - - bcs->chstate = 0; - bcs->use_count = 1; - bcs->busy = 0; - bcs->ignore = cs->ignoreframes; - - for (i = 0; i < AT_NUM; ++i) - bcs->commands[i] = NULL; - - gig_dbg(DEBUG_INIT, " setting up bcs[%d]->hw", channel); - if (cs->ops->initbcshw(bcs)) - return bcs; - - gig_dbg(DEBUG_INIT, " failed"); - - gig_dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel); - if (bcs->skb) - dev_kfree_skb(bcs->skb); - - return NULL; -} - -/* gigaset_initcs - * Allocate and initialize cardstate structure for Gigaset driver - * Calls hardware dependent gigaset_initcshw() function - * Calls B channel initialization function gigaset_initbcs() for each B channel - * parameters: - * drv hardware driver the device belongs to - * channels number of B channels supported by device - * onechannel !=0: B channel data and AT commands share one - * communication channel - * ==0: B channels have separate communication channels - * ignoreframes number of frames to ignore after setting up B channel - * cidmode !=0: start in CallID mode - * modulename name of driver module (used for I4L registration) - * return value: - * pointer to cardstate structure - */ -struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, - int onechannel, int ignoreframes, - int cidmode, const char *modulename) -{ - struct cardstate *cs = NULL; - unsigned long flags; - int i; - - gig_dbg(DEBUG_INIT, "allocating cs"); - cs = alloc_cs(drv); - if (!cs) - goto error; - gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); - cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); - if (!cs->bcs) - goto error; - gig_dbg(DEBUG_INIT, "allocating inbuf"); - cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); - if (!cs->inbuf) - goto error; - - cs->cs_init = 0; - cs->channels = channels; - cs->onechannel = onechannel; - cs->ignoreframes = ignoreframes; - INIT_LIST_HEAD(&cs->temp_at_states); - cs->running = 0; - init_timer(&cs->timer); /* clear next & prev */ - spin_lock_init(&cs->ev_lock); - cs->ev_tail = 0; - cs->ev_head = 0; - mutex_init(&cs->mutex); - mutex_lock(&cs->mutex); - - tasklet_init(&cs->event_tasklet, &gigaset_handle_event, - (unsigned long) cs); - atomic_set(&cs->commands_pending, 0); - cs->cur_at_seq = 0; - cs->gotfwver = -1; - cs->open_count = 0; - cs->dev = NULL; - cs->tty = NULL; - cs->cidmode = cidmode != 0; - - //if(onechannel) { //FIXME - cs->tabnocid = gigaset_tab_nocid_m10x; - cs->tabcid = gigaset_tab_cid_m10x; - //} else { - // cs->tabnocid = gigaset_tab_nocid; - // cs->tabcid = gigaset_tab_cid; - //} - - init_waitqueue_head(&cs->waitqueue); - cs->waiting = 0; - - atomic_set(&cs->mode, M_UNKNOWN); - atomic_set(&cs->mstate, MS_UNINITIALIZED); - - for (i = 0; i < channels; ++i) { - gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); - if (!gigaset_initbcs(cs->bcs + i, cs, i)) - goto error; - } - - ++cs->cs_init; - - gig_dbg(DEBUG_INIT, "setting up at_state"); - spin_lock_init(&cs->lock); - gigaset_at_init(&cs->at_state, NULL, cs, 0); - cs->dle = 0; - cs->cbytes = 0; - - gig_dbg(DEBUG_INIT, "setting up inbuf"); - if (onechannel) { //FIXME distinction necessary? - gigaset_inbuf_init(cs->inbuf, cs->bcs, cs, INS_command); - } else - gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command); - - cs->connected = 0; - cs->isdn_up = 0; - - gig_dbg(DEBUG_INIT, "setting up cmdbuf"); - cs->cmdbuf = cs->lastcmdbuf = NULL; - spin_lock_init(&cs->cmdlock); - cs->curlen = 0; - cs->cmdbytes = 0; - - gig_dbg(DEBUG_INIT, "setting up iif"); - if (!gigaset_register_to_LL(cs, modulename)) { - err("register_isdn failed"); - goto error; - } - - make_valid(cs, VALID_ID); - ++cs->cs_init; - gig_dbg(DEBUG_INIT, "setting up hw"); - if (!cs->ops->initcshw(cs)) - goto error; - - ++cs->cs_init; - - gigaset_if_init(cs); - - spin_lock_irqsave(&cs->lock, flags); - cs->running = 1; - spin_unlock_irqrestore(&cs->lock, flags); - setup_timer(&cs->timer, timer_tick, (unsigned long) cs); - cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK); - /* FIXME: can jiffies increase too much until the timer is added? - * Same problem(?) with mod_timer() in timer_tick(). */ - add_timer(&cs->timer); - - gig_dbg(DEBUG_INIT, "cs initialized"); - mutex_unlock(&cs->mutex); - return cs; - -error: if (cs) - mutex_unlock(&cs->mutex); - gig_dbg(DEBUG_INIT, "failed"); - gigaset_freecs(cs); - return NULL; -} -EXPORT_SYMBOL_GPL(gigaset_initcs); - -/* ReInitialize the b-channel structure on hangup */ -void gigaset_bcs_reinit(struct bc_state *bcs) -{ - struct sk_buff *skb; - struct cardstate *cs = bcs->cs; - unsigned long flags; - - while ((skb = skb_dequeue(&bcs->squeue)) != NULL) - dev_kfree_skb(skb); - - spin_lock_irqsave(&cs->lock, flags); - clear_at_state(&bcs->at_state); - bcs->at_state.ConState = 0; - bcs->at_state.timer_active = 0; - bcs->at_state.timer_expires = 0; - bcs->at_state.cid = -1; /* No CID defined */ - spin_unlock_irqrestore(&cs->lock, flags); - - bcs->inputstate = 0; - -#ifdef CONFIG_GIGASET_DEBUG - bcs->emptycount = 0; -#endif - - bcs->fcs = PPP_INITFCS; - bcs->chstate = 0; - - bcs->ignore = cs->ignoreframes; - if (bcs->ignore) - bcs->inputstate |= INS_skip_frame; - - - cs->ops->reinitbcshw(bcs); -} - -static void cleanup_cs(struct cardstate *cs) -{ - struct cmdbuf_t *cb, *tcb; - int i; - unsigned long flags; - - spin_lock_irqsave(&cs->lock, flags); - - atomic_set(&cs->mode, M_UNKNOWN); - atomic_set(&cs->mstate, MS_UNINITIALIZED); - - clear_at_state(&cs->at_state); - dealloc_at_states(cs); - free_strings(&cs->at_state); - gigaset_at_init(&cs->at_state, NULL, cs, 0); - - kfree(cs->inbuf->rcvbuf); - cs->inbuf->rcvbuf = NULL; - cs->inbuf->inputstate = INS_command; - atomic_set(&cs->inbuf->head, 0); - atomic_set(&cs->inbuf->tail, 0); - - cb = cs->cmdbuf; - while (cb) { - tcb = cb; - cb = cb->next; - kfree(tcb); - } - cs->cmdbuf = cs->lastcmdbuf = NULL; - cs->curlen = 0; - cs->cmdbytes = 0; - cs->gotfwver = -1; - cs->dle = 0; - cs->cur_at_seq = 0; - atomic_set(&cs->commands_pending, 0); - cs->cbytes = 0; - - spin_unlock_irqrestore(&cs->lock, flags); - - for (i = 0; i < cs->channels; ++i) { - gigaset_freebcs(cs->bcs + i); - if (!gigaset_initbcs(cs->bcs + i, cs, i)) - break; //FIXME error handling - } - - if (cs->waiting) { - cs->cmd_result = -ENODEV; - cs->waiting = 0; - wake_up_interruptible(&cs->waitqueue); - } -} - - -int gigaset_start(struct cardstate *cs) -{ - unsigned long flags; - - if (mutex_lock_interruptible(&cs->mutex)) - return 0; - - spin_lock_irqsave(&cs->lock, flags); - cs->connected = 1; - spin_unlock_irqrestore(&cs->lock, flags); - - if (atomic_read(&cs->mstate) != MS_LOCKED) { - cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); - cs->ops->baud_rate(cs, B115200); - cs->ops->set_line_ctrl(cs, CS8); - cs->control_state = TIOCM_DTR|TIOCM_RTS; - } else { - //FIXME use some saved values? - } - - cs->waiting = 1; - - if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) { - cs->waiting = 0; - //FIXME what should we do? - goto error; - } - - gig_dbg(DEBUG_CMD, "scheduling START"); - gigaset_schedule_event(cs); - - wait_event(cs->waitqueue, !cs->waiting); - - /* set up device sysfs */ - gigaset_init_dev_sysfs(cs); - - mutex_unlock(&cs->mutex); - return 1; - -error: - mutex_unlock(&cs->mutex); - return 0; -} -EXPORT_SYMBOL_GPL(gigaset_start); - -void gigaset_shutdown(struct cardstate *cs) -{ - mutex_lock(&cs->mutex); - - cs->waiting = 1; - - if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) { - //FIXME what should we do? - goto exit; - } - - gig_dbg(DEBUG_CMD, "scheduling SHUTDOWN"); - gigaset_schedule_event(cs); - - if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { - warn("%s: aborted", __func__); - //FIXME - } - - if (atomic_read(&cs->mstate) != MS_LOCKED) { - //FIXME? - //gigaset_baud_rate(cs, B115200); - //gigaset_set_line_ctrl(cs, CS8); - //gigaset_set_modem_ctrl(cs, TIOCM_DTR|TIOCM_RTS, 0); - //cs->control_state = 0; - } else { - //FIXME use some saved values? - } - - cleanup_cs(cs); - -exit: - mutex_unlock(&cs->mutex); -} -EXPORT_SYMBOL_GPL(gigaset_shutdown); - -void gigaset_stop(struct cardstate *cs) -{ - mutex_lock(&cs->mutex); - - cs->waiting = 1; - - if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL)) { - //FIXME what should we do? - goto exit; - } - - gig_dbg(DEBUG_CMD, "scheduling STOP"); - gigaset_schedule_event(cs); - - if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { - warn("%s: aborted", __func__); - //FIXME - } - - /* clear device sysfs */ - gigaset_free_dev_sysfs(cs); - - cleanup_cs(cs); - -exit: - mutex_unlock(&cs->mutex); -} -EXPORT_SYMBOL_GPL(gigaset_stop); - -static LIST_HEAD(drivers); -static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; - -struct cardstate *gigaset_get_cs_by_id(int id) -{ - unsigned long flags; - static struct cardstate *ret = NULL; - static struct cardstate *cs; - struct gigaset_driver *drv; - unsigned i; - - spin_lock_irqsave(&driver_lock, flags); - list_for_each_entry(drv, &drivers, list) { - spin_lock(&drv->lock); - for (i = 0; i < drv->minors; ++i) { - if (drv->flags[i] & VALID_ID) { - cs = drv->cs + i; - if (cs->myid == id) - ret = cs; - } - if (ret) - break; - } - spin_unlock(&drv->lock); - if (ret) - break; - } - spin_unlock_irqrestore(&driver_lock, flags); - return ret; -} - -void gigaset_debugdrivers(void) -{ - unsigned long flags; - static struct cardstate *cs; - struct gigaset_driver *drv; - unsigned i; - - spin_lock_irqsave(&driver_lock, flags); - list_for_each_entry(drv, &drivers, list) { - gig_dbg(DEBUG_DRIVER, "driver %p", drv); - spin_lock(&drv->lock); - for (i = 0; i < drv->minors; ++i) { - gig_dbg(DEBUG_DRIVER, " index %u", i); - gig_dbg(DEBUG_DRIVER, " flags 0x%02x", - drv->flags[i]); - cs = drv->cs + i; - gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); - gig_dbg(DEBUG_DRIVER, " minor_index %u", - cs->minor_index); - gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); - gig_dbg(DEBUG_DRIVER, " i4l id %d", cs->myid); - } - spin_unlock(&drv->lock); - } - spin_unlock_irqrestore(&driver_lock, flags); -} - -static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) -{ - unsigned long flags; - static struct cardstate *ret = NULL; - struct gigaset_driver *drv; - unsigned index; - - spin_lock_irqsave(&driver_lock, flags); - list_for_each_entry(drv, &drivers, list) { - if (minor < drv->minor || minor >= drv->minor + drv->minors) - continue; - index = minor - drv->minor; - spin_lock(&drv->lock); - if (drv->flags[index] & VALID_MINOR) - ret = drv->cs + index; - spin_unlock(&drv->lock); - if (ret) - break; - } - spin_unlock_irqrestore(&driver_lock, flags); - return ret; -} - -struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty) -{ - if (tty->index < 0 || tty->index >= tty->driver->num) - return NULL; - return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); -} - -void gigaset_freedriver(struct gigaset_driver *drv) -{ - unsigned long flags; - - spin_lock_irqsave(&driver_lock, flags); - list_del(&drv->list); - spin_unlock_irqrestore(&driver_lock, flags); - - gigaset_if_freedriver(drv); - module_put(drv->owner); - - kfree(drv->cs); - kfree(drv->flags); - kfree(drv); -} -EXPORT_SYMBOL_GPL(gigaset_freedriver); - -/* gigaset_initdriver - * Allocate and initialize gigaset_driver structure. Initialize interface. - * parameters: - * minor First minor number - * minors Number of minors this driver can handle - * procname Name of the driver - * devname Name of the device files (prefix without minor number) - * devfsname Devfs name of the device files without %d - * return value: - * Pointer to the gigaset_driver structure on success, NULL on failure. - */ -struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, - const char *procname, - const char *devname, - const char *devfsname, - const struct gigaset_ops *ops, - struct module *owner) -{ - struct gigaset_driver *drv; - unsigned long flags; - unsigned i; - - drv = kmalloc(sizeof *drv, GFP_KERNEL); - if (!drv) - return NULL; - - if (!try_module_get(owner)) - goto out1; - - drv->cs = NULL; - drv->have_tty = 0; - drv->minor = minor; - drv->minors = minors; - spin_lock_init(&drv->lock); - drv->blocked = 0; - drv->ops = ops; - drv->owner = owner; - INIT_LIST_HEAD(&drv->list); - - drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); - if (!drv->cs) - goto out2; - - drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); - if (!drv->flags) - goto out3; - - for (i = 0; i < minors; ++i) { - drv->flags[i] = 0; - drv->cs[i].driver = drv; - drv->cs[i].ops = drv->ops; - drv->cs[i].minor_index = i; - } - - gigaset_if_initdriver(drv, procname, devname, devfsname); - - spin_lock_irqsave(&driver_lock, flags); - list_add(&drv->list, &drivers); - spin_unlock_irqrestore(&driver_lock, flags); - - return drv; - -out3: - kfree(drv->cs); -out2: - module_put(owner); -out1: - kfree(drv); - return NULL; -} -EXPORT_SYMBOL_GPL(gigaset_initdriver); - -/* For drivers without fixed assignment device<->cardstate (usb) */ -struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv) -{ - unsigned long flags; - struct cardstate *cs = NULL; - unsigned i; - - spin_lock_irqsave(&drv->lock, flags); - if (drv->blocked) - goto exit; - for (i = 0; i < drv->minors; ++i) { - if ((drv->flags[i] & VALID_MINOR) && - !(drv->flags[i] & ASSIGNED)) { - drv->flags[i] |= ASSIGNED; - cs = drv->cs + i; - break; - } - } -exit: - spin_unlock_irqrestore(&drv->lock, flags); - return cs; -} -EXPORT_SYMBOL_GPL(gigaset_getunassignedcs); - -void gigaset_unassign(struct cardstate *cs) -{ - unsigned long flags; - unsigned *minor_flags; - struct gigaset_driver *drv; - - if (!cs) - return; - drv = cs->driver; - spin_lock_irqsave(&drv->lock, flags); - minor_flags = drv->flags + cs->minor_index; - if (*minor_flags & VALID_MINOR) - *minor_flags &= ~ASSIGNED; - spin_unlock_irqrestore(&drv->lock, flags); -} -EXPORT_SYMBOL_GPL(gigaset_unassign); - -void gigaset_blockdriver(struct gigaset_driver *drv) -{ - unsigned long flags; - spin_lock_irqsave(&drv->lock, flags); - drv->blocked = 1; - spin_unlock_irqrestore(&drv->lock, flags); -} -EXPORT_SYMBOL_GPL(gigaset_blockdriver); - -static int __init gigaset_init_module(void) -{ - /* in accordance with the principle of least astonishment, - * setting the 'debug' parameter to 1 activates a sensible - * set of default debug levels - */ - if (gigaset_debuglevel == 1) - gigaset_debuglevel = DEBUG_DEFAULT; - - info(DRIVER_AUTHOR); - info(DRIVER_DESC); - return 0; -} - -static void __exit gigaset_exit_module(void) -{ -} - -module_init(gigaset_init_module); -module_exit(gigaset_exit_module); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); - -MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c deleted file mode 100644 index 18e05c09b..000000000 --- a/drivers/isdn/gigaset/ev-layer.c +++ /dev/null @@ -1,1985 +0,0 @@ -/* - * Stuff used by all variants of the driver - * - * Copyright (c) 2001 by Stefan Eilers, - * Hansjoerg Lipp , - * Tilman Schmidt . - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" - -/* ========================================================== */ -/* bit masks for pending commands */ -#define PC_DIAL 0x001 -#define PC_HUP 0x002 -#define PC_INIT 0x004 -#define PC_DLE0 0x008 -#define PC_DLE1 0x010 -#define PC_SHUTDOWN 0x020 -#define PC_ACCEPT 0x040 -#define PC_CID 0x080 -#define PC_NOCID 0x100 -#define PC_CIDMODE 0x200 -#define PC_UMMODE 0x400 - -/* types of modem responses */ -#define RT_NOTHING 0 -#define RT_ZSAU 1 -#define RT_RING 2 -#define RT_NUMBER 3 -#define RT_STRING 4 -#define RT_HEX 5 -#define RT_ZCAU 6 - -/* Possible ASCII responses */ -#define RSP_OK 0 -//#define RSP_BUSY 1 -//#define RSP_CONNECT 2 -#define RSP_ZGCI 3 -#define RSP_RING 4 -#define RSP_ZAOC 5 -#define RSP_ZCSTR 6 -#define RSP_ZCFGT 7 -#define RSP_ZCFG 8 -#define RSP_ZCCR 9 -#define RSP_EMPTY 10 -#define RSP_ZLOG 11 -#define RSP_ZCAU 12 -#define RSP_ZMWI 13 -#define RSP_ZABINFO 14 -#define RSP_ZSMLSTCHG 15 -#define RSP_VAR 100 -#define RSP_ZSAU (RSP_VAR + VAR_ZSAU) -#define RSP_ZDLE (RSP_VAR + VAR_ZDLE) -#define RSP_ZVLS (RSP_VAR + VAR_ZVLS) -#define RSP_ZCTP (RSP_VAR + VAR_ZCTP) -#define RSP_STR (RSP_VAR + VAR_NUM) -#define RSP_NMBR (RSP_STR + STR_NMBR) -#define RSP_ZCPN (RSP_STR + STR_ZCPN) -#define RSP_ZCON (RSP_STR + STR_ZCON) -#define RSP_ZBC (RSP_STR + STR_ZBC) -#define RSP_ZHLC (RSP_STR + STR_ZHLC) -#define RSP_ERROR -1 /* ERROR */ -#define RSP_WRONG_CID -2 /* unknown cid in cmd */ -//#define RSP_EMPTY -3 -#define RSP_UNKNOWN -4 /* unknown response */ -#define RSP_FAIL -5 /* internal error */ -#define RSP_INVAL -6 /* invalid response */ - -#define RSP_NONE -19 -#define RSP_STRING -20 -#define RSP_NULL -21 -//#define RSP_RETRYFAIL -22 -//#define RSP_RETRY -23 -//#define RSP_SKIP -24 -#define RSP_INIT -27 -#define RSP_ANY -26 -#define RSP_LAST -28 -#define RSP_NODEV -9 - -/* actions for process_response */ -#define ACT_NOTHING 0 -#define ACT_SETDLE1 1 -#define ACT_SETDLE0 2 -#define ACT_FAILINIT 3 -#define ACT_HUPMODEM 4 -#define ACT_CONFIGMODE 5 -#define ACT_INIT 6 -#define ACT_DLE0 7 -#define ACT_DLE1 8 -#define ACT_FAILDLE0 9 -#define ACT_FAILDLE1 10 -#define ACT_RING 11 -#define ACT_CID 12 -#define ACT_FAILCID 13 -#define ACT_SDOWN 14 -#define ACT_FAILSDOWN 15 -#define ACT_DEBUG 16 -#define ACT_WARN 17 -#define ACT_DIALING 18 -#define ACT_ABORTDIAL 19 -#define ACT_DISCONNECT 20 -#define ACT_CONNECT 21 -#define ACT_REMOTEREJECT 22 -#define ACT_CONNTIMEOUT 23 -#define ACT_REMOTEHUP 24 -#define ACT_ABORTHUP 25 -#define ACT_ICALL 26 -#define ACT_ACCEPTED 27 -#define ACT_ABORTACCEPT 28 -#define ACT_TIMEOUT 29 -#define ACT_GETSTRING 30 -#define ACT_SETVER 31 -#define ACT_FAILVER 32 -#define ACT_GOTVER 33 -#define ACT_TEST 34 -#define ACT_ERROR 35 -#define ACT_ABORTCID 36 -#define ACT_ZCAU 37 -#define ACT_NOTIFY_BC_DOWN 38 -#define ACT_NOTIFY_BC_UP 39 -#define ACT_DIAL 40 -#define ACT_ACCEPT 41 -#define ACT_PROTO_L2 42 -#define ACT_HUP 43 -#define ACT_IF_LOCK 44 -#define ACT_START 45 -#define ACT_STOP 46 -#define ACT_FAKEDLE0 47 -#define ACT_FAKEHUP 48 -#define ACT_FAKESDOWN 49 -#define ACT_SHUTDOWN 50 -#define ACT_PROC_CIDMODE 51 -#define ACT_UMODESET 52 -#define ACT_FAILUMODE 53 -#define ACT_CMODESET 54 -#define ACT_FAILCMODE 55 -#define ACT_IF_VER 56 -#define ACT_CMD 100 - -/* at command sequences */ -#define SEQ_NONE 0 -#define SEQ_INIT 100 -#define SEQ_DLE0 200 -#define SEQ_DLE1 250 -#define SEQ_CID 300 -#define SEQ_NOCID 350 -#define SEQ_HUP 400 -#define SEQ_DIAL 600 -#define SEQ_ACCEPT 720 -#define SEQ_SHUTDOWN 500 -#define SEQ_CIDMODE 10 -#define SEQ_UMMODE 11 - - -// 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring -struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ -{ - /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ - - /* initialize device, set cid mode if possible */ - //{RSP_INIT, -1, -1,100, 900, 0, {ACT_TEST}}, - //{RSP_ERROR, 900,900, -1, 0, 0, {ACT_FAILINIT}}, - //{RSP_OK, 900,900, -1, 100, INIT_TIMEOUT, - // {ACT_TIMEOUT}}, - - {RSP_INIT, -1, -1,SEQ_INIT, 100, INIT_TIMEOUT, - {ACT_TIMEOUT}}, /* wait until device is ready */ - - {EV_TIMEOUT, 100,100, -1, 101, 3, {0}, "Z\r"}, /* device in transparent mode? try to initialize it. */ - {RSP_OK, 101,103, -1, 120, 5, {ACT_GETSTRING}, "+GMR\r"}, /* get version */ - - {EV_TIMEOUT, 101,101, -1, 102, 5, {0}, "Z\r"}, /* timeout => try once again. */ - {RSP_ERROR, 101,101, -1, 102, 5, {0}, "Z\r"}, /* error => try once again. */ - - {EV_TIMEOUT, 102,102, -1, 108, 5, {ACT_SETDLE1}, "^SDLE=0\r"}, /* timeout => try again in DLE mode. */ - {RSP_OK, 108,108, -1, 104,-1}, - {RSP_ZDLE, 104,104, 0, 103, 5, {0}, "Z\r"}, - {EV_TIMEOUT, 104,104, -1, 0, 0, {ACT_FAILINIT}}, - {RSP_ERROR, 108,108, -1, 0, 0, {ACT_FAILINIT}}, - - {EV_TIMEOUT, 108,108, -1, 105, 2, {ACT_SETDLE0, - ACT_HUPMODEM, - ACT_TIMEOUT}}, /* still timeout => connection in unimodem mode? */ - {EV_TIMEOUT, 105,105, -1, 103, 5, {0}, "Z\r"}, - - {RSP_ERROR, 102,102, -1, 107, 5, {0}, "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */ - {RSP_OK, 107,107, -1, 0, 0, {ACT_CONFIGMODE}}, - {RSP_ERROR, 107,107, -1, 0, 0, {ACT_FAILINIT}}, - {EV_TIMEOUT, 107,107, -1, 0, 0, {ACT_FAILINIT}}, - - {RSP_ERROR, 103,103, -1, 0, 0, {ACT_FAILINIT}}, - {EV_TIMEOUT, 103,103, -1, 0, 0, {ACT_FAILINIT}}, - - {RSP_STRING, 120,120, -1, 121,-1, {ACT_SETVER}}, - - {EV_TIMEOUT, 120,121, -1, 0, 0, {ACT_FAILVER, ACT_INIT}}, - {RSP_ERROR, 120,121, -1, 0, 0, {ACT_FAILVER, ACT_INIT}}, - {RSP_OK, 121,121, -1, 0, 0, {ACT_GOTVER, ACT_INIT}}, -#if 0 - {EV_TIMEOUT, 120,121, -1, 130, 5, {ACT_FAILVER}, "^SGCI=1\r"}, - {RSP_ERROR, 120,121, -1, 130, 5, {ACT_FAILVER}, "^SGCI=1\r"}, - {RSP_OK, 121,121, -1, 130, 5, {ACT_GOTVER}, "^SGCI=1\r"}, - - {RSP_OK, 130,130, -1, 0, 0, {ACT_INIT}}, - {RSP_ERROR, 130,130, -1, 0, 0, {ACT_FAILINIT}}, - {EV_TIMEOUT, 130,130, -1, 0, 0, {ACT_FAILINIT}}, -#endif - - /* leave dle mode */ - {RSP_INIT, 0, 0,SEQ_DLE0, 201, 5, {0}, "^SDLE=0\r"}, - {RSP_OK, 201,201, -1, 202,-1}, - //{RSP_ZDLE, 202,202, 0, 202, 0, {ACT_ERROR}},//DELETE - {RSP_ZDLE, 202,202, 0, 0, 0, {ACT_DLE0}}, - {RSP_NODEV, 200,249, -1, 0, 0, {ACT_FAKEDLE0}}, - {RSP_ERROR, 200,249, -1, 0, 0, {ACT_FAILDLE0}}, - {EV_TIMEOUT, 200,249, -1, 0, 0, {ACT_FAILDLE0}}, - - /* enter dle mode */ - {RSP_INIT, 0, 0,SEQ_DLE1, 251, 5, {0}, "^SDLE=1\r"}, - {RSP_OK, 251,251, -1, 252,-1}, - {RSP_ZDLE, 252,252, 1, 0, 0, {ACT_DLE1}}, - {RSP_ERROR, 250,299, -1, 0, 0, {ACT_FAILDLE1}}, - {EV_TIMEOUT, 250,299, -1, 0, 0, {ACT_FAILDLE1}}, - - /* incoming call */ - {RSP_RING, -1, -1, -1, -1,-1, {ACT_RING}}, - - /* get cid */ - //{RSP_INIT, 0, 0,300, 901, 0, {ACT_TEST}}, - //{RSP_ERROR, 901,901, -1, 0, 0, {ACT_FAILCID}}, - //{RSP_OK, 901,901, -1, 301, 5, {0}, "^SGCI?\r"}, - - {RSP_INIT, 0, 0,SEQ_CID, 301, 5, {0}, "^SGCI?\r"}, - {RSP_OK, 301,301, -1, 302,-1}, - {RSP_ZGCI, 302,302, -1, 0, 0, {ACT_CID}}, - {RSP_ERROR, 301,349, -1, 0, 0, {ACT_FAILCID}}, - {EV_TIMEOUT, 301,349, -1, 0, 0, {ACT_FAILCID}}, - - /* enter cid mode */ - {RSP_INIT, 0, 0,SEQ_CIDMODE, 150, 5, {0}, "^SGCI=1\r"}, - {RSP_OK, 150,150, -1, 0, 0, {ACT_CMODESET}}, - {RSP_ERROR, 150,150, -1, 0, 0, {ACT_FAILCMODE}}, - {EV_TIMEOUT, 150,150, -1, 0, 0, {ACT_FAILCMODE}}, - - /* leave cid mode */ - //{RSP_INIT, 0, 0,SEQ_UMMODE, 160, 5, {0}, "^SGCI=0\r"}, - {RSP_INIT, 0, 0,SEQ_UMMODE, 160, 5, {0}, "Z\r"}, - {RSP_OK, 160,160, -1, 0, 0, {ACT_UMODESET}}, - {RSP_ERROR, 160,160, -1, 0, 0, {ACT_FAILUMODE}}, - {EV_TIMEOUT, 160,160, -1, 0, 0, {ACT_FAILUMODE}}, - - /* abort getting cid */ - {RSP_INIT, 0, 0,SEQ_NOCID, 0, 0, {ACT_ABORTCID}}, - - /* reset */ -#if 0 - {RSP_INIT, 0, 0,SEQ_SHUTDOWN, 503, 5, {0}, "^SGCI=0\r"}, - {RSP_OK, 503,503, -1, 504, 5, {0}, "Z\r"}, -#endif - {RSP_INIT, 0, 0,SEQ_SHUTDOWN, 504, 5, {0}, "Z\r"}, - {RSP_OK, 504,504, -1, 0, 0, {ACT_SDOWN}}, - {RSP_ERROR, 501,599, -1, 0, 0, {ACT_FAILSDOWN}}, - {EV_TIMEOUT, 501,599, -1, 0, 0, {ACT_FAILSDOWN}}, - {RSP_NODEV, 501,599, -1, 0, 0, {ACT_FAKESDOWN}}, - - {EV_PROC_CIDMODE,-1, -1, -1, -1,-1, {ACT_PROC_CIDMODE}}, //FIXME - {EV_IF_LOCK, -1, -1, -1, -1,-1, {ACT_IF_LOCK}}, //FIXME - {EV_IF_VER, -1, -1, -1, -1,-1, {ACT_IF_VER}}, //FIXME - {EV_START, -1, -1, -1, -1,-1, {ACT_START}}, //FIXME - {EV_STOP, -1, -1, -1, -1,-1, {ACT_STOP}}, //FIXME - {EV_SHUTDOWN, -1, -1, -1, -1,-1, {ACT_SHUTDOWN}}, //FIXME - - /* misc. */ - {RSP_EMPTY, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZCFGT, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZCFG, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZLOG, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZMWI, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZABINFO, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZSMLSTCHG,-1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - - {RSP_ZCAU, -1, -1, -1, -1,-1, {ACT_ZCAU}}, - {RSP_NONE, -1, -1, -1, -1,-1, {ACT_DEBUG}}, - {RSP_ANY, -1, -1, -1, -1,-1, {ACT_WARN}}, - {RSP_LAST} -}; - -// 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall -struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */ -{ - /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ - - /* dial */ - {EV_DIAL, -1, -1, -1, -1,-1, {ACT_DIAL}}, //FIXME - {RSP_INIT, 0, 0,SEQ_DIAL, 601, 5, {ACT_CMD+AT_BC}}, - {RSP_OK, 601,601, -1, 602, 5, {ACT_CMD+AT_HLC}}, - {RSP_NULL, 602,602, -1, 603, 5, {ACT_CMD+AT_PROTO}}, - {RSP_OK, 602,602, -1, 603, 5, {ACT_CMD+AT_PROTO}}, - {RSP_OK, 603,603, -1, 604, 5, {ACT_CMD+AT_TYPE}}, - {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}}, - {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, - {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, - {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, /* set "Endgeraetemodus" */ - {RSP_OK, 607,607, -1, 608,-1}, - //{RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 608, 0, {ACT_ERROR}},//DELETE - {RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}}, - {RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}}, - - {RSP_ZVLS, 608,608, 17, -1,-1, {ACT_DEBUG}}, - {RSP_ZCTP, 609,609, -1, -1,-1, {ACT_DEBUG}}, - {RSP_ZCPN, 609,609, -1, -1,-1, {ACT_DEBUG}}, - {RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, - {EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, - - /* dialing */ - {RSP_ZCTP, 650,650, -1, -1,-1, {ACT_DEBUG}}, - {RSP_ZCPN, 650,650, -1, -1,-1, {ACT_DEBUG}}, - {RSP_ZSAU, 650,650,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, /* some devices don't send this */ - - /* connection established */ - {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1 - {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1 - - {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}}, //FIXME new constate + timeout - - /* remote hangup */ - {RSP_ZSAU, 650,650,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}}, - {RSP_ZSAU, 750,750,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, - {RSP_ZSAU, 800,800,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, - - /* hangup */ - {EV_HUP, -1, -1, -1, -1,-1, {ACT_HUP}}, //FIXME - {RSP_INIT, -1, -1,SEQ_HUP, 401, 5, {0}, "+VLS=0\r"}, /* hang up */ //-1,-1? - {RSP_OK, 401,401, -1, 402, 5}, - {RSP_ZVLS, 402,402, 0, 403, 5}, - {RSP_ZSAU, 403,403,ZSAU_DISCONNECT_REQ, -1,-1, {ACT_DEBUG}}, /* if not remote hup */ - //{RSP_ZSAU, 403,403,ZSAU_NULL, 401, 0, {ACT_ERROR}}, //DELETE//FIXME -> DLE0 // should we do this _before_ hanging up for base driver? - {RSP_ZSAU, 403,403,ZSAU_NULL, 0, 0, {ACT_DISCONNECT}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver? - {RSP_NODEV, 401,403, -1, 0, 0, {ACT_FAKEHUP}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver? - {RSP_ERROR, 401,401, -1, 0, 0, {ACT_ABORTHUP}}, - {EV_TIMEOUT, 401,403, -1, 0, 0, {ACT_ABORTHUP}}, - - {EV_BC_CLOSED, 0, 0, -1, 0,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME new constate + timeout - - /* ring */ - {RSP_ZBC, 700,700, -1, -1,-1, {0}}, - {RSP_ZHLC, 700,700, -1, -1,-1, {0}}, - {RSP_NMBR, 700,700, -1, -1,-1, {0}}, - {RSP_ZCPN, 700,700, -1, -1,-1, {0}}, - {RSP_ZCTP, 700,700, -1, -1,-1, {0}}, - {EV_TIMEOUT, 700,700, -1, 720,720, {ACT_ICALL}}, - {EV_BC_CLOSED,720,720, -1, 0,-1, {ACT_NOTIFY_BC_DOWN}}, - - /*accept icall*/ - {EV_ACCEPT, -1, -1, -1, -1,-1, {ACT_ACCEPT}}, //FIXME - {RSP_INIT, 720,720,SEQ_ACCEPT, 721, 5, {ACT_CMD+AT_PROTO}}, - {RSP_OK, 721,721, -1, 722, 5, {ACT_CMD+AT_ISO}}, - {RSP_OK, 722,722, -1, 723, 5, {0}, "+VLS=17\r"}, /* set "Endgeraetemodus" */ - {RSP_OK, 723,723, -1, 724, 5, {0}}, - {RSP_ZVLS, 724,724, 17, 750,50, {ACT_ACCEPTED}}, - {RSP_ERROR, 721,729, -1, 0, 0, {ACT_ABORTACCEPT}}, - {EV_TIMEOUT, 721,729, -1, 0, 0, {ACT_ABORTACCEPT}}, - {RSP_ZSAU, 700,729,ZSAU_NULL, 0, 0, {ACT_ABORTACCEPT}}, - {RSP_ZSAU, 700,729,ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT}}, - {RSP_ZSAU, 700,729,ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT}}, - - {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}}, - - /* B channel closed (general case) */ - {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME - - /* misc. */ - {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME - - {RSP_ZCON, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZCCR, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZAOC, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - {RSP_ZCSTR, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME - - {RSP_ZCAU, -1, -1, -1, -1,-1, {ACT_ZCAU}}, - {RSP_NONE, -1, -1, -1, -1,-1, {ACT_DEBUG}}, - {RSP_ANY, -1, -1, -1, -1,-1, {ACT_WARN}}, - {RSP_LAST} -}; - - -#if 0 -static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME -{ - /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ - - {RSP_ANY, -1, -1, -1, -1,-1, ACT_WARN, NULL}, - {RSP_LAST,0,0,0,0,0,0} -}; - -static struct reply_t tab_cid[] = /* no dle mode */ //FIXME -{ - /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ - - {RSP_ANY, -1, -1, -1, -1,-1, ACT_WARN, NULL}, - {RSP_LAST,0,0,0,0,0,0} -}; -#endif - -static struct resp_type_t resp_type[]= -{ - /*{"", RSP_EMPTY, RT_NOTHING},*/ - {"OK", RSP_OK, RT_NOTHING}, - {"ERROR", RSP_ERROR, RT_NOTHING}, - {"ZSAU", RSP_ZSAU, RT_ZSAU}, - {"ZCAU", RSP_ZCAU, RT_ZCAU}, - {"RING", RSP_RING, RT_RING}, - {"ZGCI", RSP_ZGCI, RT_NUMBER}, - {"ZVLS", RSP_ZVLS, RT_NUMBER}, - {"ZCTP", RSP_ZCTP, RT_NUMBER}, - {"ZDLE", RSP_ZDLE, RT_NUMBER}, - {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, - {"ZCCR", RSP_ZCCR, RT_NUMBER}, - {"ZMWI", RSP_ZMWI, RT_NUMBER}, - {"ZHLC", RSP_ZHLC, RT_STRING}, - {"ZBC", RSP_ZBC, RT_STRING}, - {"NMBR", RSP_NMBR, RT_STRING}, - {"ZCPN", RSP_ZCPN, RT_STRING}, - {"ZCON", RSP_ZCON, RT_STRING}, - {"ZAOC", RSP_ZAOC, RT_STRING}, - {"ZCSTR", RSP_ZCSTR, RT_STRING}, - {"ZCFG", RSP_ZCFG, RT_HEX}, - {"ZLOG", RSP_ZLOG, RT_NOTHING}, - {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, - {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, - {NULL,0,0} -}; - -/* - * Get integer from char-pointer - */ -static int isdn_getnum(char *p) -{ - int v = -1; - - gig_dbg(DEBUG_TRANSCMD, "string: %s", p); - - while (*p >= '0' && *p <= '9') - v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); - if (*p) - v = -1; /* invalid Character */ - return v; -} - -/* - * Get integer from char-pointer - */ -static int isdn_gethex(char *p) -{ - int v = 0; - int c; - - gig_dbg(DEBUG_TRANSCMD, "string: %s", p); - - if (!*p) - return -1; - - do { - if (v > (INT_MAX - 15) / 16) - return -1; - c = *p; - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'a' && c <= 'f') - c -= 'a' - 10; - else if (c >= 'A' && c <= 'F') - c -= 'A' - 10; - else - return -1; - v = v * 16 + c; - } while (*++p); - - return v; -} - -/* retrieve CID from parsed response - * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 - */ -static int cid_of_response(char *s) -{ - int cid; - - if (s[-1] != ';') - return 0; /* no CID separator */ - cid = isdn_getnum(s); - if (cid < 0) - return 0; /* CID not numeric */ - if (cid < 1 || cid > 65535) - return -1; /* CID out of range */ - return cid; - //FIXME is ;+ at end of non-CID response really impossible? -} - -/* This function will be called via task queue from the callback handler. - * We received a modem response and have to handle it.. - */ -void gigaset_handle_modem_response(struct cardstate *cs) -{ - unsigned char *argv[MAX_REC_PARAMS + 1]; - int params; - int i, j; - struct resp_type_t *rt; - int curarg; - unsigned long flags; - unsigned next, tail, head; - struct event_t *event; - int resp_code; - int param_type; - int abort; - size_t len; - int cid; - int rawstring; - - len = cs->cbytes; - if (!len) { - /* ignore additional LFs/CRs (M10x config mode or cx100) */ - gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); - return; - } - cs->respdata[len] = 0; - gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); - argv[0] = cs->respdata; - params = 1; - if (cs->at_state.getstring) { - /* getstring only allowed without cid at the moment */ - cs->at_state.getstring = 0; - rawstring = 1; - cid = 0; - } else { - /* parse line */ - for (i = 0; i < len; i++) - switch (cs->respdata[i]) { - case ';': - case ',': - case '=': - if (params > MAX_REC_PARAMS) { - dev_warn(cs->dev, - "too many parameters in response\n"); - /* need last parameter (might be CID) */ - params--; - } - argv[params++] = cs->respdata + i + 1; - } - - rawstring = 0; - cid = params > 1 ? cid_of_response(argv[params-1]) : 0; - if (cid < 0) { - gigaset_add_event(cs, &cs->at_state, RSP_INVAL, - NULL, 0, NULL); - return; - } - - for (j = 1; j < params; ++j) - argv[j][-1] = 0; - - gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); - if (cid) { - --params; - gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); - } - gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); - for (j = 1; j < params; j++) - gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); - } - - spin_lock_irqsave(&cs->ev_lock, flags); - head = cs->ev_head; - tail = cs->ev_tail; - - abort = 1; - curarg = 0; - while (curarg < params) { - next = (tail + 1) % MAX_EVENTS; - if (unlikely(next == head)) { - dev_err(cs->dev, "event queue full\n"); - break; - } - - event = cs->events + tail; - event->at_state = NULL; - event->cid = cid; - event->ptr = NULL; - event->arg = NULL; - tail = next; - - if (rawstring) { - resp_code = RSP_STRING; - param_type = RT_STRING; - } else { - for (rt = resp_type; rt->response; ++rt) - if (!strcmp(argv[curarg], rt->response)) - break; - - if (!rt->response) { - event->type = RSP_UNKNOWN; - dev_warn(cs->dev, - "unknown modem response: %s\n", - argv[curarg]); - break; - } - - resp_code = rt->resp_code; - param_type = rt->type; - ++curarg; - } - - event->type = resp_code; - - switch (param_type) { - case RT_NOTHING: - break; - case RT_RING: - if (!cid) { - dev_err(cs->dev, - "received RING without CID!\n"); - event->type = RSP_INVAL; - abort = 1; - } else { - event->cid = 0; - event->parameter = cid; - abort = 0; - } - break; - case RT_ZSAU: - if (curarg >= params) { - event->parameter = ZSAU_NONE; - break; - } - if (!strcmp(argv[curarg], "OUTGOING_CALL_PROCEEDING")) - event->parameter = ZSAU_OUTGOING_CALL_PROCEEDING; - else if (!strcmp(argv[curarg], "CALL_DELIVERED")) - event->parameter = ZSAU_CALL_DELIVERED; - else if (!strcmp(argv[curarg], "ACTIVE")) - event->parameter = ZSAU_ACTIVE; - else if (!strcmp(argv[curarg], "DISCONNECT_IND")) - event->parameter = ZSAU_DISCONNECT_IND; - else if (!strcmp(argv[curarg], "NULL")) - event->parameter = ZSAU_NULL; - else if (!strcmp(argv[curarg], "DISCONNECT_REQ")) - event->parameter = ZSAU_DISCONNECT_REQ; - else { - event->parameter = ZSAU_UNKNOWN; - dev_warn(cs->dev, - "%s: unknown parameter %s after ZSAU\n", - __func__, argv[curarg]); - } - ++curarg; - break; - case RT_STRING: - if (curarg < params) { - event->ptr = kstrdup(argv[curarg], GFP_ATOMIC); - if (!event->ptr) - dev_err(cs->dev, "out of memory\n"); - ++curarg; - } -#ifdef CONFIG_GIGASET_DEBUG - if (!event->ptr) - gig_dbg(DEBUG_CMD, "string==NULL"); - else - gig_dbg(DEBUG_CMD, "string==%s", - (char *) event->ptr); -#endif - break; - case RT_ZCAU: - event->parameter = -1; - if (curarg + 1 < params) { - i = isdn_gethex(argv[curarg]); - j = isdn_gethex(argv[curarg + 1]); - if (i >= 0 && i < 256 && j >= 0 && j < 256) - event->parameter = (unsigned) i << 8 - | j; - curarg += 2; - } else - curarg = params - 1; - break; - case RT_NUMBER: - case RT_HEX: - if (curarg < params) { - if (param_type == RT_HEX) - event->parameter = - isdn_gethex(argv[curarg]); - else - event->parameter = - isdn_getnum(argv[curarg]); - ++curarg; - } else - event->parameter = -1; -#ifdef CONFIG_GIGASET_DEBUG - gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter); -#endif - break; - } - - if (resp_code == RSP_ZDLE) - cs->dle = event->parameter; - - if (abort) - break; - } - - cs->ev_tail = tail; - spin_unlock_irqrestore(&cs->ev_lock, flags); - - if (curarg != params) - gig_dbg(DEBUG_ANY, - "invalid number of processed parameters: %d/%d", - curarg, params); -} -EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); - -/* disconnect - * process closing of connection associated with given AT state structure - */ -static void disconnect(struct at_state_t **at_state_p) -{ - unsigned long flags; - struct bc_state *bcs = (*at_state_p)->bcs; - struct cardstate *cs = (*at_state_p)->cs; - - spin_lock_irqsave(&cs->lock, flags); - ++(*at_state_p)->seq_index; - - /* revert to selected idle mode */ - if (!cs->cidmode) { - cs->at_state.pending_commands |= PC_UMMODE; - atomic_set(&cs->commands_pending, 1); //FIXME - gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); - } - spin_unlock_irqrestore(&cs->lock, flags); - - if (bcs) { - /* B channel assigned: invoke hardware specific handler */ - cs->ops->close_bchannel(bcs); - } else { - /* no B channel assigned: just deallocate */ - spin_lock_irqsave(&cs->lock, flags); - list_del(&(*at_state_p)->list); - kfree(*at_state_p); - *at_state_p = NULL; - spin_unlock_irqrestore(&cs->lock, flags); - } -} - -/* get_free_channel - * get a free AT state structure: either one of those associated with the - * B channels of the Gigaset device, or if none of those is available, - * a newly allocated one with bcs=NULL - * The structure should be freed by calling disconnect() after use. - */ -static inline struct at_state_t *get_free_channel(struct cardstate *cs, - int cid) -/* cids: >0: siemens-cid - 0: without cid - -1: no cid assigned yet -*/ -{ - unsigned long flags; - int i; - struct at_state_t *ret; - - for (i = 0; i < cs->channels; ++i) - if (gigaset_get_channel(cs->bcs + i)) { - ret = &cs->bcs[i].at_state; - ret->cid = cid; - return ret; - } - - spin_lock_irqsave(&cs->lock, flags); - ret = kmalloc(sizeof(struct at_state_t), GFP_ATOMIC); - if (ret) { - gigaset_at_init(ret, NULL, cs, cid); - list_add(&ret->list, &cs->temp_at_states); - } - spin_unlock_irqrestore(&cs->lock, flags); - return ret; -} - -static void init_failed(struct cardstate *cs, int mode) -{ - int i; - struct at_state_t *at_state; - - cs->at_state.pending_commands &= ~PC_INIT; - atomic_set(&cs->mode, mode); - atomic_set(&cs->mstate, MS_UNINITIALIZED); - gigaset_free_channels(cs); - for (i = 0; i < cs->channels; ++i) { - at_state = &cs->bcs[i].at_state; - if (at_state->pending_commands & PC_CID) { - at_state->pending_commands &= ~PC_CID; - at_state->pending_commands |= PC_NOCID; - atomic_set(&cs->commands_pending, 1); - } - } -} - -static void schedule_init(struct cardstate *cs, int state) -{ - if (cs->at_state.pending_commands & PC_INIT) { - gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); - return; - } - atomic_set(&cs->mstate, state); - atomic_set(&cs->mode, M_UNKNOWN); - gigaset_block_channels(cs); - cs->at_state.pending_commands |= PC_INIT; - atomic_set(&cs->commands_pending, 1); - gig_dbg(DEBUG_CMD, "Scheduling PC_INIT"); -} - -/* Add "AT" to a command, add the cid, dle encode it, send the result to the - hardware. */ -static void send_command(struct cardstate *cs, const char *cmd, int cid, - int dle, gfp_t kmallocflags) -{ - size_t cmdlen, buflen; - char *cmdpos, *cmdbuf, *cmdtail; - - cmdlen = strlen(cmd); - buflen = 11 + cmdlen; - if (unlikely(buflen <= cmdlen)) { - dev_err(cs->dev, "integer overflow in buflen\n"); - return; - } - - cmdbuf = kmalloc(buflen, kmallocflags); - if (unlikely(!cmdbuf)) { - dev_err(cs->dev, "out of memory\n"); - return; - } - - cmdpos = cmdbuf + 9; - cmdtail = cmdpos + cmdlen; - memcpy(cmdpos, cmd, cmdlen); - - if (cid > 0 && cid <= 65535) { - do { - *--cmdpos = '0' + cid % 10; - cid /= 10; - ++cmdlen; - } while (cid); - } - - cmdlen += 2; - *--cmdpos = 'T'; - *--cmdpos = 'A'; - - if (dle) { - cmdlen += 4; - *--cmdpos = '('; - *--cmdpos = 0x10; - *cmdtail++ = 0x10; - *cmdtail++ = ')'; - } - - cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); - kfree(cmdbuf); -} - -static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) -{ - struct at_state_t *at_state; - int i; - unsigned long flags; - - if (cid == 0) - return &cs->at_state; - - for (i = 0; i < cs->channels; ++i) - if (cid == cs->bcs[i].at_state.cid) - return &cs->bcs[i].at_state; - - spin_lock_irqsave(&cs->lock, flags); - - list_for_each_entry(at_state, &cs->temp_at_states, list) - if (cid == at_state->cid) { - spin_unlock_irqrestore(&cs->lock, flags); - return at_state; - } - - spin_unlock_irqrestore(&cs->lock, flags); - - return NULL; -} - -static void bchannel_down(struct bc_state *bcs) -{ - if (bcs->chstate & CHS_B_UP) { - bcs->chstate &= ~CHS_B_UP; - gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); - } - - if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { - bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); - gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP); - } - - gigaset_free_channel(bcs); - - gigaset_bcs_reinit(bcs); -} - -static void bchannel_up(struct bc_state *bcs) -{ - if (!(bcs->chstate & CHS_D_UP)) { - dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__); - bcs->chstate |= CHS_D_UP; - gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); - } - - if (bcs->chstate & CHS_B_UP) { - dev_notice(bcs->cs->dev, "%s: B channel already up\n", - __func__); - return; - } - - bcs->chstate |= CHS_B_UP; - gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); -} - -static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index) -{ - struct bc_state *bcs = at_state->bcs; - struct cardstate *cs = at_state->cs; - int retval; - unsigned long flags; - - bcs->chstate |= CHS_NOTIFY_LL; - - spin_lock_irqsave(&cs->lock, flags); - if (at_state->seq_index != seq_index) { - spin_unlock_irqrestore(&cs->lock, flags); - goto error; - } - spin_unlock_irqrestore(&cs->lock, flags); - - retval = gigaset_isdn_setup_dial(at_state, data); - if (retval != 0) - goto error; - - - at_state->pending_commands |= PC_CID; - gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); - atomic_set(&cs->commands_pending, 1); - return; - -error: - at_state->pending_commands |= PC_NOCID; - gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); - atomic_set(&cs->commands_pending, 1); - return; -} - -static void start_accept(struct at_state_t *at_state) -{ - struct cardstate *cs = at_state->cs; - int retval; - - retval = gigaset_isdn_setup_accept(at_state); - - if (retval == 0) { - at_state->pending_commands |= PC_ACCEPT; - gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); - atomic_set(&cs->commands_pending, 1); - } else { - //FIXME - at_state->pending_commands |= PC_HUP; - gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); - atomic_set(&cs->commands_pending, 1); - } -} - -static void do_start(struct cardstate *cs) -{ - gigaset_free_channels(cs); - - if (atomic_read(&cs->mstate) != MS_LOCKED) - schedule_init(cs, MS_INIT); - - cs->isdn_up = 1; - gigaset_i4l_cmd(cs, ISDN_STAT_RUN); - // FIXME: not in locked mode - // FIXME 2: only after init sequence - - cs->waiting = 0; - wake_up(&cs->waitqueue); -} - -static void finish_shutdown(struct cardstate *cs) -{ - if (atomic_read(&cs->mstate) != MS_LOCKED) { - atomic_set(&cs->mstate, MS_UNINITIALIZED); - atomic_set(&cs->mode, M_UNKNOWN); - } - - /* Tell the LL that the device is not available .. */ - if (cs->isdn_up) { - cs->isdn_up = 0; - gigaset_i4l_cmd(cs, ISDN_STAT_STOP); - } - - /* The rest is done by cleanup_cs () in user mode. */ - - cs->cmd_result = -ENODEV; - cs->waiting = 0; - wake_up_interruptible(&cs->waitqueue); -} - -static void do_shutdown(struct cardstate *cs) -{ - gigaset_block_channels(cs); - - if (atomic_read(&cs->mstate) == MS_READY) { - atomic_set(&cs->mstate, MS_SHUTDOWN); - cs->at_state.pending_commands |= PC_SHUTDOWN; - atomic_set(&cs->commands_pending, 1); - gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); - } else - finish_shutdown(cs); -} - -static void do_stop(struct cardstate *cs) -{ - unsigned long flags; - - spin_lock_irqsave(&cs->lock, flags); - cs->connected = 0; - spin_unlock_irqrestore(&cs->lock, flags); - - do_shutdown(cs); -} - -/* Entering cid mode or getting a cid failed: - * try to initialize the device and try again. - * - * channel >= 0: getting cid for the channel failed - * channel < 0: entering cid mode failed - * - * returns 0 on failure - */ -static int reinit_and_retry(struct cardstate *cs, int channel) -{ - int i; - - if (--cs->retry_count <= 0) - return 0; - - for (i = 0; i < cs->channels; ++i) - if (cs->bcs[i].at_state.cid > 0) - return 0; - - if (channel < 0) - dev_warn(cs->dev, - "Could not enter cid mode. Reinit device and try again.\n"); - else { - dev_warn(cs->dev, - "Could not get a call id. Reinit device and try again.\n"); - cs->bcs[channel].at_state.pending_commands |= PC_CID; - } - schedule_init(cs, MS_INIT); - return 1; -} - -static int at_state_invalid(struct cardstate *cs, - struct at_state_t *test_ptr) -{ - unsigned long flags; - unsigned channel; - struct at_state_t *at_state; - int retval = 0; - - spin_lock_irqsave(&cs->lock, flags); - - if (test_ptr == &cs->at_state) - goto exit; - - list_for_each_entry(at_state, &cs->temp_at_states, list) - if (at_state == test_ptr) - goto exit; - - for (channel = 0; channel < cs->channels; ++channel) - if (&cs->bcs[channel].at_state == test_ptr) - goto exit; - - retval = 1; -exit: - spin_unlock_irqrestore(&cs->lock, flags); - return retval; -} - -static void handle_icall(struct cardstate *cs, struct bc_state *bcs, - struct at_state_t **p_at_state) -{ - int retval; - struct at_state_t *at_state = *p_at_state; - - retval = gigaset_isdn_icall(at_state); - switch (retval) { - case ICALL_ACCEPT: - break; - default: - dev_err(cs->dev, "internal error: disposition=%d\n", retval); - /* --v-- fall through --v-- */ - case ICALL_IGNORE: - case ICALL_REJECT: - /* hang up actively - * Device doc says that would reject the call. - * In fact it doesn't. - */ - at_state->pending_commands |= PC_HUP; - atomic_set(&cs->commands_pending, 1); - break; - } -} - -static int do_lock(struct cardstate *cs) -{ - int mode; - int i; - - switch (atomic_read(&cs->mstate)) { - case MS_UNINITIALIZED: - case MS_READY: - if (cs->cur_at_seq || !list_empty(&cs->temp_at_states) || - cs->at_state.pending_commands) - return -EBUSY; - - for (i = 0; i < cs->channels; ++i) - if (cs->bcs[i].at_state.pending_commands) - return -EBUSY; - - if (!gigaset_get_channels(cs)) - return -EBUSY; - - break; - case MS_LOCKED: - //retval = -EACCES; - break; - default: - return -EBUSY; - } - - mode = atomic_read(&cs->mode); - atomic_set(&cs->mstate, MS_LOCKED); - atomic_set(&cs->mode, M_UNKNOWN); - - return mode; -} - -static int do_unlock(struct cardstate *cs) -{ - if (atomic_read(&cs->mstate) != MS_LOCKED) - return -EINVAL; - - atomic_set(&cs->mstate, MS_UNINITIALIZED); - atomic_set(&cs->mode, M_UNKNOWN); - gigaset_free_channels(cs); - if (cs->connected) - schedule_init(cs, MS_INIT); - - return 0; -} - -static void do_action(int action, struct cardstate *cs, - struct bc_state *bcs, - struct at_state_t **p_at_state, char **pp_command, - int *p_genresp, int *p_resp_code, - struct event_t *ev) -{ - struct at_state_t *at_state = *p_at_state; - struct at_state_t *at_state2; - unsigned long flags; - - int channel; - - unsigned char *s, *e; - int i; - unsigned long val; - - switch (action) { - case ACT_NOTHING: - break; - case ACT_TIMEOUT: - at_state->waiting = 1; - break; - case ACT_INIT: - cs->at_state.pending_commands &= ~PC_INIT; - cs->cur_at_seq = SEQ_NONE; - atomic_set(&cs->mode, M_UNIMODEM); - spin_lock_irqsave(&cs->lock, flags); - if (!cs->cidmode) { - spin_unlock_irqrestore(&cs->lock, flags); - gigaset_free_channels(cs); - atomic_set(&cs->mstate, MS_READY); - break; - } - spin_unlock_irqrestore(&cs->lock, flags); - cs->at_state.pending_commands |= PC_CIDMODE; - atomic_set(&cs->commands_pending, 1); - gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); - break; - case ACT_FAILINIT: - dev_warn(cs->dev, "Could not initialize the device.\n"); - cs->dle = 0; - init_failed(cs, M_UNKNOWN); - cs->cur_at_seq = SEQ_NONE; - break; - case ACT_CONFIGMODE: - init_failed(cs, M_CONFIG); - cs->cur_at_seq = SEQ_NONE; - break; - case ACT_SETDLE1: - cs->dle = 1; - /* cs->inbuf[0].inputstate |= INS_command | INS_DLE_command; */ - cs->inbuf[0].inputstate &= - ~(INS_command | INS_DLE_command); - break; - case ACT_SETDLE0: - cs->dle = 0; - cs->inbuf[0].inputstate = - (cs->inbuf[0].inputstate & ~INS_DLE_command) - | INS_command; - break; - case ACT_CMODESET: - if (atomic_read(&cs->mstate) == MS_INIT || - atomic_read(&cs->mstate) == MS_RECOVER) { - gigaset_free_channels(cs); - atomic_set(&cs->mstate, MS_READY); - } - atomic_set(&cs->mode, M_CID); - cs->cur_at_seq = SEQ_NONE; - break; - case ACT_UMODESET: - atomic_set(&cs->mode, M_UNIMODEM); - cs->cur_at_seq = SEQ_NONE; - break; - case ACT_FAILCMODE: - cs->cur_at_seq = SEQ_NONE; - if (atomic_read(&cs->mstate) == MS_INIT || - atomic_read(&cs->mstate) == MS_RECOVER) { - init_failed(cs, M_UNKNOWN); - break; - } - if (!reinit_and_retry(cs, -1)) - schedule_init(cs, MS_RECOVER); - break; - case ACT_FAILUMODE: - cs->cur_at_seq = SEQ_NONE; - schedule_init(cs, MS_RECOVER); - break; - case ACT_HUPMODEM: - /* send "+++" (hangup in unimodem mode) */ - cs->ops->write_cmd(cs, "+++", 3, NULL); - break; - case ACT_RING: - /* get fresh AT state structure for new CID */ - at_state2 = get_free_channel(cs, ev->parameter); - if (!at_state2) { - dev_warn(cs->dev, - "RING ignored: could not allocate channel structure\n"); - break; - } - - /* initialize AT state structure - * note that bcs may be NULL if no B channel is free - */ - at_state2->ConState = 700; - kfree(at_state2->str_var[STR_NMBR]); - at_state2->str_var[STR_NMBR] = NULL; - kfree(at_state2->str_var[STR_ZCPN]); - at_state2->str_var[STR_ZCPN] = NULL; - kfree(at_state2->str_var[STR_ZBC]); - at_state2->str_var[STR_ZBC] = NULL; - kfree(at_state2->str_var[STR_ZHLC]); - at_state2->str_var[STR_ZHLC] = NULL; - at_state2->int_var[VAR_ZCTP] = -1; - - spin_lock_irqsave(&cs->lock, flags); - at_state2->timer_expires = RING_TIMEOUT; - at_state2->timer_active = 1; - spin_unlock_irqrestore(&cs->lock, flags); - break; - case ACT_ICALL: - handle_icall(cs, bcs, p_at_state); - at_state = *p_at_state; - break; - case ACT_FAILSDOWN: - dev_warn(cs->dev, "Could not shut down the device.\n"); - /* fall through */ - case ACT_FAKESDOWN: - case ACT_SDOWN: - cs->cur_at_seq = SEQ_NONE; - finish_shutdown(cs); - break; - case ACT_CONNECT: - if (cs->onechannel) { - at_state->pending_commands |= PC_DLE1; - atomic_set(&cs->commands_pending, 1); - break; - } - bcs->chstate |= CHS_D_UP; - gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); - cs->ops->init_bchannel(bcs); - break; - case ACT_DLE1: - cs->cur_at_seq = SEQ_NONE; - bcs = cs->bcs + cs->curchannel; - - bcs->chstate |= CHS_D_UP; - gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); - cs->ops->init_bchannel(bcs); - break; - case ACT_FAKEHUP: - at_state->int_var[VAR_ZSAU] = ZSAU_NULL; - /* fall through */ - case ACT_DISCONNECT: - cs->cur_at_seq = SEQ_NONE; - at_state->cid = -1; - if (bcs && cs->onechannel && cs->dle) { - /* Check for other open channels not needed: - * DLE only used for M10x with one B channel. - */ - at_state->pending_commands |= PC_DLE0; - atomic_set(&cs->commands_pending, 1); - } else { - disconnect(p_at_state); - at_state = *p_at_state; - } - break; - case ACT_FAKEDLE0: - at_state->int_var[VAR_ZDLE] = 0; - cs->dle = 0; - /* fall through */ - case ACT_DLE0: - cs->cur_at_seq = SEQ_NONE; - at_state2 = &cs->bcs[cs->curchannel].at_state; - disconnect(&at_state2); - break; - case ACT_ABORTHUP: - cs->cur_at_seq = SEQ_NONE; - dev_warn(cs->dev, "Could not hang up.\n"); - at_state->cid = -1; - if (bcs && cs->onechannel) - at_state->pending_commands |= PC_DLE0; - else { - disconnect(p_at_state); - at_state = *p_at_state; - } - schedule_init(cs, MS_RECOVER); - break; - case ACT_FAILDLE0: - cs->cur_at_seq = SEQ_NONE; - dev_warn(cs->dev, "Could not leave DLE mode.\n"); - at_state2 = &cs->bcs[cs->curchannel].at_state; - disconnect(&at_state2); - schedule_init(cs, MS_RECOVER); - break; - case ACT_FAILDLE1: - cs->cur_at_seq = SEQ_NONE; - dev_warn(cs->dev, - "Could not enter DLE mode. Trying to hang up.\n"); - channel = cs->curchannel; - cs->bcs[channel].at_state.pending_commands |= PC_HUP; - atomic_set(&cs->commands_pending, 1); - break; - - case ACT_CID: /* got cid; start dialing */ - cs->cur_at_seq = SEQ_NONE; - channel = cs->curchannel; - if (ev->parameter > 0 && ev->parameter <= 65535) { - cs->bcs[channel].at_state.cid = ev->parameter; - cs->bcs[channel].at_state.pending_commands |= - PC_DIAL; - atomic_set(&cs->commands_pending, 1); - break; - } - /* fall through */ - case ACT_FAILCID: - cs->cur_at_seq = SEQ_NONE; - channel = cs->curchannel; - if (!reinit_and_retry(cs, channel)) { - dev_warn(cs->dev, - "Could not get a call ID. Cannot dial.\n"); - at_state2 = &cs->bcs[channel].at_state; - disconnect(&at_state2); - } - break; - case ACT_ABORTCID: - cs->cur_at_seq = SEQ_NONE; - at_state2 = &cs->bcs[cs->curchannel].at_state; - disconnect(&at_state2); - break; - - case ACT_DIALING: - case ACT_ACCEPTED: - cs->cur_at_seq = SEQ_NONE; - break; - - case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL processing */ - disconnect(p_at_state); - at_state = *p_at_state; - break; - - case ACT_ABORTDIAL: /* error/timeout during dial preparation */ - cs->cur_at_seq = SEQ_NONE; - at_state->pending_commands |= PC_HUP; - atomic_set(&cs->commands_pending, 1); - break; - - case ACT_REMOTEREJECT: /* DISCONNECT_IND after dialling */ - case ACT_CONNTIMEOUT: /* timeout waiting for ZSAU=ACTIVE */ - case ACT_REMOTEHUP: /* DISCONNECT_IND with established connection */ - at_state->pending_commands |= PC_HUP; - atomic_set(&cs->commands_pending, 1); - break; - case ACT_GETSTRING: /* warning: RING, ZDLE, ... - are not handled properly anymore */ - at_state->getstring = 1; - break; - case ACT_SETVER: - if (!ev->ptr) { - *p_genresp = 1; - *p_resp_code = RSP_ERROR; - break; - } - s = ev->ptr; - - if (!strcmp(s, "OK")) { - *p_genresp = 1; - *p_resp_code = RSP_ERROR; - break; - } - - for (i = 0; i < 4; ++i) { - val = simple_strtoul(s, (char **) &e, 10); - if (val > INT_MAX || e == s) - break; - if (i == 3) { - if (*e) - break; - } else if (*e != '.') - break; - else - s = e + 1; - cs->fwver[i] = val; - } - if (i != 4) { - *p_genresp = 1; - *p_resp_code = RSP_ERROR; - break; - } - /*at_state->getstring = 1;*/ - cs->gotfwver = 0; - break; - case ACT_GOTVER: - if (cs->gotfwver == 0) { - cs->gotfwver = 1; - gig_dbg(DEBUG_ANY, - "firmware version %02d.%03d.%02d.%02d", - cs->fwver[0], cs->fwver[1], - cs->fwver[2], cs->fwver[3]); - break; - } - /* fall through */ - case ACT_FAILVER: - cs->gotfwver = -1; - dev_err(cs->dev, "could not read firmware version.\n"); - break; -#ifdef CONFIG_GIGASET_DEBUG - case ACT_ERROR: - *p_genresp = 1; - *p_resp_code = RSP_ERROR; - break; - case ACT_TEST: - { - static int count = 3; //2; //1; - *p_genresp = 1; - *p_resp_code = count ? RSP_ERROR : RSP_OK; - if (count > 0) - --count; - } - break; -#endif - case ACT_DEBUG: - gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", - __func__, ev->type, at_state->ConState); - break; - case ACT_WARN: - dev_warn(cs->dev, "%s: resp_code %d in ConState %d!\n", - __func__, ev->type, at_state->ConState); - break; - case ACT_ZCAU: - dev_warn(cs->dev, "cause code %04x in connection state %d.\n", - ev->parameter, at_state->ConState); - break; - - /* events from the LL */ - case ACT_DIAL: - start_dial(at_state, ev->ptr, ev->parameter); - break; - case ACT_ACCEPT: - start_accept(at_state); - break; - case ACT_PROTO_L2: - gig_dbg(DEBUG_CMD, "set protocol to %u", - (unsigned) ev->parameter); - at_state->bcs->proto2 = ev->parameter; - break; - case ACT_HUP: - at_state->pending_commands |= PC_HUP; - atomic_set(&cs->commands_pending, 1); - gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); - break; - - /* hotplug events */ - case ACT_STOP: - do_stop(cs); - break; - case ACT_START: - do_start(cs); - break; - - /* events from the interface */ // FIXME without ACT_xxxx? - case ACT_IF_LOCK: - cs->cmd_result = ev->parameter ? do_lock(cs) : do_unlock(cs); - cs->waiting = 0; - wake_up(&cs->waitqueue); - break; - case ACT_IF_VER: - if (ev->parameter != 0) - cs->cmd_result = -EINVAL; - else if (cs->gotfwver != 1) { - cs->cmd_result = -ENOENT; - } else { - memcpy(ev->arg, cs->fwver, sizeof cs->fwver); - cs->cmd_result = 0; - } - cs->waiting = 0; - wake_up(&cs->waitqueue); - break; - - /* events from the proc file system */ // FIXME without ACT_xxxx? - case ACT_PROC_CIDMODE: - spin_lock_irqsave(&cs->lock, flags); - if (ev->parameter != cs->cidmode) { - cs->cidmode = ev->parameter; - if (ev->parameter) { - cs->at_state.pending_commands |= PC_CIDMODE; - gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); - } else { - cs->at_state.pending_commands |= PC_UMMODE; - gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); - } - atomic_set(&cs->commands_pending, 1); - } - spin_unlock_irqrestore(&cs->lock, flags); - cs->waiting = 0; - wake_up(&cs->waitqueue); - break; - - /* events from the hardware drivers */ - case ACT_NOTIFY_BC_DOWN: - bchannel_down(bcs); - break; - case ACT_NOTIFY_BC_UP: - bchannel_up(bcs); - break; - case ACT_SHUTDOWN: - do_shutdown(cs); - break; - - - default: - if (action >= ACT_CMD && action < ACT_CMD + AT_NUM) { - *pp_command = at_state->bcs->commands[action - ACT_CMD]; - if (!*pp_command) { - *p_genresp = 1; - *p_resp_code = RSP_NULL; - } - } else - dev_err(cs->dev, "%s: action==%d!\n", __func__, action); - } -} - -/* State machine to do the calling and hangup procedure */ -static void process_event(struct cardstate *cs, struct event_t *ev) -{ - struct bc_state *bcs; - char *p_command = NULL; - struct reply_t *rep; - int rcode; - int genresp = 0; - int resp_code = RSP_ERROR; - int sendcid; - struct at_state_t *at_state; - int index; - int curact; - unsigned long flags; - - if (ev->cid >= 0) { - at_state = at_state_from_cid(cs, ev->cid); - if (!at_state) { - gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, - NULL, 0, NULL); - return; - } - } else { - at_state = ev->at_state; - if (at_state_invalid(cs, at_state)) { - gig_dbg(DEBUG_ANY, "event for invalid at_state %p", - at_state); - return; - } - } - - gig_dbg(DEBUG_CMD, "connection state %d, event %d", - at_state->ConState, ev->type); - - bcs = at_state->bcs; - sendcid = at_state->cid; - - /* Setting the pointer to the dial array */ - rep = at_state->replystruct; - - spin_lock_irqsave(&cs->lock, flags); - if (ev->type == EV_TIMEOUT) { - if (ev->parameter != at_state->timer_index - || !at_state->timer_active) { - ev->type = RSP_NONE; /* old timeout */ - gig_dbg(DEBUG_ANY, "old timeout"); - } else if (!at_state->waiting) - gig_dbg(DEBUG_ANY, "timeout occurred"); - else - gig_dbg(DEBUG_ANY, "stopped waiting"); - } - spin_unlock_irqrestore(&cs->lock, flags); - - /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] - or at_state->str_var[STR_XXXX], set it */ - if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { - index = ev->type - RSP_VAR; - at_state->int_var[index] = ev->parameter; - } else if (ev->type >= RSP_STR && ev->type < RSP_STR + STR_NUM) { - index = ev->type - RSP_STR; - kfree(at_state->str_var[index]); - at_state->str_var[index] = ev->ptr; - ev->ptr = NULL; /* prevent process_events() from - deallocating ptr */ - } - - if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) - at_state->getstring = 0; - - /* Search row in dial array which matches modem response and current - constate */ - for (;; rep++) { - rcode = rep->resp_code; - if (rcode == RSP_LAST) { - /* found nothing...*/ - dev_warn(cs->dev, "%s: rcode=RSP_LAST: " - "resp_code %d in ConState %d!\n", - __func__, ev->type, at_state->ConState); - return; - } - if ((rcode == RSP_ANY || rcode == ev->type) - && ((int) at_state->ConState >= rep->min_ConState) - && (rep->max_ConState < 0 - || (int) at_state->ConState <= rep->max_ConState) - && (rep->parameter < 0 || rep->parameter == ev->parameter)) - break; - } - - p_command = rep->command; - - at_state->waiting = 0; - for (curact = 0; curact < MAXACT; ++curact) { - /* The row tells us what we should do .. - */ - do_action(rep->action[curact], cs, bcs, &at_state, &p_command, &genresp, &resp_code, ev); - if (!at_state) - break; /* may be freed after disconnect */ - } - - if (at_state) { - /* Jump to the next con-state regarding the array */ - if (rep->new_ConState >= 0) - at_state->ConState = rep->new_ConState; - - if (genresp) { - spin_lock_irqsave(&cs->lock, flags); - at_state->timer_expires = 0; //FIXME - at_state->timer_active = 0; //FIXME - spin_unlock_irqrestore(&cs->lock, flags); - gigaset_add_event(cs, at_state, resp_code, NULL, 0, NULL); - } else { - /* Send command to modem if not NULL... */ - if (p_command/*rep->command*/) { - if (cs->connected) - send_command(cs, p_command, - sendcid, cs->dle, - GFP_ATOMIC); - else - gigaset_add_event(cs, at_state, - RSP_NODEV, - NULL, 0, NULL); - } - - spin_lock_irqsave(&cs->lock, flags); - if (!rep->timeout) { - at_state->timer_expires = 0; - at_state->timer_active = 0; - } else if (rep->timeout > 0) { /* new timeout */ - at_state->timer_expires = rep->timeout * 10; - at_state->timer_active = 1; - ++at_state->timer_index; - } - spin_unlock_irqrestore(&cs->lock, flags); - } - } -} - -static void schedule_sequence(struct cardstate *cs, - struct at_state_t *at_state, int sequence) -{ - cs->cur_at_seq = sequence; - gigaset_add_event(cs, at_state, RSP_INIT, NULL, sequence, NULL); -} - -static void process_command_flags(struct cardstate *cs) -{ - struct at_state_t *at_state = NULL; - struct bc_state *bcs; - int i; - int sequence; - unsigned long flags; - - atomic_set(&cs->commands_pending, 0); - - if (cs->cur_at_seq) { - gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); - return; - } - - gig_dbg(DEBUG_CMD, "searching scheduled commands"); - - sequence = SEQ_NONE; - - /* clear pending_commands and hangup channels on shutdown */ - if (cs->at_state.pending_commands & PC_SHUTDOWN) { - cs->at_state.pending_commands &= ~PC_CIDMODE; - for (i = 0; i < cs->channels; ++i) { - bcs = cs->bcs + i; - at_state = &bcs->at_state; - at_state->pending_commands &= - ~(PC_DLE1 | PC_ACCEPT | PC_DIAL); - if (at_state->cid > 0) - at_state->pending_commands |= PC_HUP; - if (at_state->pending_commands & PC_CID) { - at_state->pending_commands |= PC_NOCID; - at_state->pending_commands &= ~PC_CID; - } - } - } - - /* clear pending_commands and hangup channels on reset */ - if (cs->at_state.pending_commands & PC_INIT) { - cs->at_state.pending_commands &= ~PC_CIDMODE; - for (i = 0; i < cs->channels; ++i) { - bcs = cs->bcs + i; - at_state = &bcs->at_state; - at_state->pending_commands &= - ~(PC_DLE1 | PC_ACCEPT | PC_DIAL); - if (at_state->cid > 0) - at_state->pending_commands |= PC_HUP; - if (atomic_read(&cs->mstate) == MS_RECOVER) { - if (at_state->pending_commands & PC_CID) { - at_state->pending_commands |= PC_NOCID; - at_state->pending_commands &= ~PC_CID; - } - } - } - } - - /* only switch back to unimodem mode, if no commands are pending and no channels are up */ - spin_lock_irqsave(&cs->lock, flags); - if (cs->at_state.pending_commands == PC_UMMODE - && !cs->cidmode - && list_empty(&cs->temp_at_states) - && atomic_read(&cs->mode) == M_CID) { - sequence = SEQ_UMMODE; - at_state = &cs->at_state; - for (i = 0; i < cs->channels; ++i) { - bcs = cs->bcs + i; - if (bcs->at_state.pending_commands || - bcs->at_state.cid > 0) { - sequence = SEQ_NONE; - break; - } - } - } - spin_unlock_irqrestore(&cs->lock, flags); - cs->at_state.pending_commands &= ~PC_UMMODE; - if (sequence != SEQ_NONE) { - schedule_sequence(cs, at_state, sequence); - return; - } - - for (i = 0; i < cs->channels; ++i) { - bcs = cs->bcs + i; - if (bcs->at_state.pending_commands & PC_HUP) { - bcs->at_state.pending_commands &= ~PC_HUP; - if (bcs->at_state.pending_commands & PC_CID) { - /* not yet dialing: PC_NOCID is sufficient */ - bcs->at_state.pending_commands |= PC_NOCID; - bcs->at_state.pending_commands &= ~PC_CID; - } else { - schedule_sequence(cs, &bcs->at_state, SEQ_HUP); - return; - } - } - if (bcs->at_state.pending_commands & PC_NOCID) { - bcs->at_state.pending_commands &= ~PC_NOCID; - cs->curchannel = bcs->channel; - schedule_sequence(cs, &cs->at_state, SEQ_NOCID); - return; - } else if (bcs->at_state.pending_commands & PC_DLE0) { - bcs->at_state.pending_commands &= ~PC_DLE0; - cs->curchannel = bcs->channel; - schedule_sequence(cs, &cs->at_state, SEQ_DLE0); - return; - } - } - - list_for_each_entry(at_state, &cs->temp_at_states, list) - if (at_state->pending_commands & PC_HUP) { - at_state->pending_commands &= ~PC_HUP; - schedule_sequence(cs, at_state, SEQ_HUP); - return; - } - - if (cs->at_state.pending_commands & PC_INIT) { - cs->at_state.pending_commands &= ~PC_INIT; - cs->dle = 0; //FIXME - cs->inbuf->inputstate = INS_command; - //FIXME reset card state (or -> LOCK0)? - schedule_sequence(cs, &cs->at_state, SEQ_INIT); - return; - } - if (cs->at_state.pending_commands & PC_SHUTDOWN) { - cs->at_state.pending_commands &= ~PC_SHUTDOWN; - schedule_sequence(cs, &cs->at_state, SEQ_SHUTDOWN); - return; - } - if (cs->at_state.pending_commands & PC_CIDMODE) { - cs->at_state.pending_commands &= ~PC_CIDMODE; - if (atomic_read(&cs->mode) == M_UNIMODEM) { - cs->retry_count = 1; - schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); - return; - } - } - - for (i = 0; i < cs->channels; ++i) { - bcs = cs->bcs + i; - if (bcs->at_state.pending_commands & PC_DLE1) { - bcs->at_state.pending_commands &= ~PC_DLE1; - cs->curchannel = bcs->channel; - schedule_sequence(cs, &cs->at_state, SEQ_DLE1); - return; - } - if (bcs->at_state.pending_commands & PC_ACCEPT) { - bcs->at_state.pending_commands &= ~PC_ACCEPT; - schedule_sequence(cs, &bcs->at_state, SEQ_ACCEPT); - return; - } - if (bcs->at_state.pending_commands & PC_DIAL) { - bcs->at_state.pending_commands &= ~PC_DIAL; - schedule_sequence(cs, &bcs->at_state, SEQ_DIAL); - return; - } - if (bcs->at_state.pending_commands & PC_CID) { - switch (atomic_read(&cs->mode)) { - case M_UNIMODEM: - cs->at_state.pending_commands |= PC_CIDMODE; - gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); - atomic_set(&cs->commands_pending, 1); - return; -#ifdef GIG_MAYINITONDIAL - case M_UNKNOWN: - schedule_init(cs, MS_INIT); - return; -#endif - } - bcs->at_state.pending_commands &= ~PC_CID; - cs->curchannel = bcs->channel; -#ifdef GIG_RETRYCID - cs->retry_count = 2; -#else - cs->retry_count = 1; -#endif - schedule_sequence(cs, &cs->at_state, SEQ_CID); - return; - } - } -} - -static void process_events(struct cardstate *cs) -{ - struct event_t *ev; - unsigned head, tail; - int i; - int check_flags = 0; - int was_busy; - unsigned long flags; - - spin_lock_irqsave(&cs->ev_lock, flags); - head = cs->ev_head; - - for (i = 0; i < 2 * MAX_EVENTS; ++i) { - tail = cs->ev_tail; - if (tail == head) { - if (!check_flags && !atomic_read(&cs->commands_pending)) - break; - check_flags = 0; - spin_unlock_irqrestore(&cs->ev_lock, flags); - process_command_flags(cs); - spin_lock_irqsave(&cs->ev_lock, flags); - tail = cs->ev_tail; - if (tail == head) { - if (!atomic_read(&cs->commands_pending)) - break; - continue; - } - } - - ev = cs->events + head; - was_busy = cs->cur_at_seq != SEQ_NONE; - spin_unlock_irqrestore(&cs->ev_lock, flags); - process_event(cs, ev); - spin_lock_irqsave(&cs->ev_lock, flags); - kfree(ev->ptr); - ev->ptr = NULL; - if (was_busy && cs->cur_at_seq == SEQ_NONE) - check_flags = 1; - - head = (head + 1) % MAX_EVENTS; - cs->ev_head = head; - } - - spin_unlock_irqrestore(&cs->ev_lock, flags); - - if (i == 2 * MAX_EVENTS) { - dev_err(cs->dev, - "infinite loop in process_events; aborting.\n"); - } -} - -/* tasklet scheduled on any event received from the Gigaset device - * parameter: - * data ISDN controller state structure - */ -void gigaset_handle_event(unsigned long data) -{ - struct cardstate *cs = (struct cardstate *) data; - - /* handle incoming data on control/common channel */ - if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { - gig_dbg(DEBUG_INTR, "processing new data"); - cs->ops->handle_input(cs->inbuf); - } - - process_events(cs); -} diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h deleted file mode 100644 index 22b9693f7..000000000 --- a/drivers/isdn/gigaset/gigaset.h +++ /dev/null @@ -1,905 +0,0 @@ -/* - * Siemens Gigaset 307x driver - * Common header file for all connection variants - * - * Written by Stefan Eilers - * and Hansjoerg Lipp - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 GIGASET_H -#define GIGASET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GIG_VERSION {0,5,0,0} -#define GIG_COMPAT {0,4,0,0} - -#define MAX_REC_PARAMS 10 /* Max. number of params in response string */ -#define MAX_RESP_SIZE 512 /* Max. size of a response string */ -#define HW_HDR_LEN 2 /* Header size used to store ack info */ - -#define MAX_EVENTS 64 /* size of event queue */ - -#define RBUFSIZE 8192 -#define SBUFSIZE 4096 /* sk_buff payload size */ - -#define TRANSBUFSIZE 768 /* bytes per skb for transparent receive */ -#define MAX_BUF_SIZE (SBUFSIZE - 2) /* Max. size of a data packet from LL */ - -/* compile time options */ -#define GIG_MAJOR 0 - -#define GIG_MAYINITONDIAL -#define GIG_RETRYCID -#define GIG_X75 - -#define GIG_TICK 100 /* in milliseconds */ - -/* timeout values (unit: 1 sec) */ -#define INIT_TIMEOUT 1 - -/* timeout values (unit: 0.1 sec) */ -#define RING_TIMEOUT 3 /* for additional parameters to RING */ -#define BAS_TIMEOUT 20 /* for response to Base USB ops */ -#define ATRDY_TIMEOUT 3 /* for HD_READY_SEND_ATDATA */ - -#define BAS_RETRY 3 /* max. retries for base USB ops */ - -#define MAXACT 3 - -extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */ - -/* any combination of these can be given with the 'debug=' parameter to insmod, - * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and - * DEBUG_INTR. - */ -enum debuglevel { - DEBUG_REG = 0x0002, /* serial port I/O register operations */ - DEBUG_OPEN = 0x0004, /* open/close serial port */ - DEBUG_INTR = 0x0008, /* interrupt processing */ - DEBUG_INTR_DUMP = 0x0010, /* Activating hexdump debug output on - interrupt requests, not available as - run-time option */ - DEBUG_CMD = 0x00020, /* sent/received LL commands */ - DEBUG_STREAM = 0x00040, /* application data stream I/O events */ - DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ - DEBUG_LLDATA = 0x00100, /* sent/received LL data */ - DEBUG_INTR_0 = 0x00200, /* serial port interrupt processing */ - DEBUG_DRIVER = 0x00400, /* driver structure */ - DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ - DEBUG_WRITE = 0x01000, /* M105 data write */ - DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ - DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */ - DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data - structures */ - DEBUG_LOCK = 0x10000, /* semaphore operations */ - DEBUG_OUTPUT = 0x20000, /* output to device */ - DEBUG_ISO = 0x40000, /* isochronous transfers */ - DEBUG_IF = 0x80000, /* character device operations */ - DEBUG_USBREQ = 0x100000, /* USB communication (except payload - data) */ - DEBUG_LOCKCMD = 0x200000, /* AT commands and responses when - MS_LOCKED */ - - DEBUG_ANY = 0x3fffff, /* print message if any of the others is - activated */ -}; - -/* missing from linux/device.h ... */ -#ifndef dev_notice -#define dev_notice(dev, format, arg...) \ - dev_printk(KERN_NOTICE , dev , format , ## arg) -#endif - -/* Kernel message macros for situations where dev_printk and friends cannot be - * used for lack of reliable access to a device structure. - * linux/usb.h already contains these but in an obsolete form which clutters - * the log needlessly, and according to the USB maintainer those should be - * removed rather than fixed anyway. - */ -#undef err -#undef info -#undef warn -#undef notice - -#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ - format "\n" , ## arg) -#define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \ - format "\n" , ## arg) -#define warn(format, arg...) printk(KERN_WARNING KBUILD_MODNAME ": " \ - format "\n" , ## arg) -#define notice(format, arg...) printk(KERN_NOTICE KBUILD_MODNAME ": " \ - format "\n" , ## arg) - -#ifdef CONFIG_GIGASET_DEBUG - -#define gig_dbg(level, format, arg...) \ - do { \ - if (unlikely(((enum debuglevel)gigaset_debuglevel) & (level))) \ - printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \ - ## arg); \ - } while (0) -#define DEBUG_DEFAULT (DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) - -#else - -#define gig_dbg(level, format, arg...) do {} while (0) -#define DEBUG_DEFAULT 0 - -#endif - -void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, - size_t len, const unsigned char *buf); - -/* connection state */ -#define ZSAU_NONE 0 -#define ZSAU_DISCONNECT_IND 4 -#define ZSAU_OUTGOING_CALL_PROCEEDING 1 -#define ZSAU_PROCEEDING 1 -#define ZSAU_CALL_DELIVERED 2 -#define ZSAU_ACTIVE 3 -#define ZSAU_NULL 5 -#define ZSAU_DISCONNECT_REQ 6 -#define ZSAU_UNKNOWN -1 - -/* USB control transfer requests */ -#define OUT_VENDOR_REQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) -#define IN_VENDOR_REQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) - -/* int-in-events 3070 */ -#define HD_B1_FLOW_CONTROL 0x80 -#define HD_B2_FLOW_CONTROL 0x81 -#define HD_RECEIVEATDATA_ACK (0x35) // 3070 - // att: HD_RECEIVE>>AT< ignore */ - int max_ConState; /* <0 => ignore */ - int parameter; /* e.g. ZSAU_XXXX <0: ignore*/ - int new_ConState; /* <0 => ignore */ - int timeout; /* >0 => *HZ; <=0 => TOUT_XXXX*/ - int action[MAXACT]; /* ACT_XXXX */ - char *command; /* NULL==none */ -}; - -extern struct reply_t gigaset_tab_cid_m10x[]; -extern struct reply_t gigaset_tab_nocid_m10x[]; - -struct inbuf_t { - unsigned char *rcvbuf; /* usb-gigaset receive buffer */ - struct bc_state *bcs; - struct cardstate *cs; - int inputstate; - atomic_t head, tail; - unsigned char data[RBUFSIZE]; -}; - -/* isochronous write buffer structure - * circular buffer with pad area for extraction of complete USB frames - * - data[read..nextread-1] is valid data already submitted to the USB subsystem - * - data[nextread..write-1] is valid data yet to be sent - * - data[write] is the next byte to write to - * - in byte-oriented L2 procotols, it is completely free - * - in bit-oriented L2 procotols, it may contain a partial byte of valid data - * - data[write+1..read-1] is free - * - wbits is the number of valid data bits in data[write], starting at the LSB - * - writesem is the semaphore for writing to the buffer: - * if writesem <= 0, data[write..read-1] is currently being written to - * - idle contains the byte value to repeat when the end of valid data is - * reached; if nextread==write (buffer contains no data to send), either the - * BAS_OUTBUFPAD bytes immediately before data[write] (if - * write>=BAS_OUTBUFPAD) or those of the pad area (if write for modem reponses (and - * incoming data for M10x) - * -> on timeout - * -> after setting bits in - * xxx.at_state.pending_command - * (e.g. command from LL) */ - struct tasklet_struct write_tasklet; - /* tasklet for serial output - * (not used in base driver) */ - - /* event queue */ - struct event_t events[MAX_EVENTS]; - unsigned ev_tail, ev_head; - spinlock_t ev_lock; - - /* current modem response */ - unsigned char respdata[MAX_RESP_SIZE]; - unsigned cbytes; - - /* private data of hardware drivers */ - union { - struct usb_cardstate *usb; /* USB hardware driver (m105) */ - struct ser_cardstate *ser; /* serial hardware driver */ - struct bas_cardstate *bas; /* USB hardware driver (base) */ - } hw; -}; - -struct gigaset_driver { - struct list_head list; - spinlock_t lock; /* locks minor tables and blocked */ - struct tty_driver *tty; - unsigned have_tty; - unsigned minor; - unsigned minors; - struct cardstate *cs; - unsigned *flags; - int blocked; - - const struct gigaset_ops *ops; - struct module *owner; -}; - -struct cmdbuf_t { - struct cmdbuf_t *next, *prev; - int len, offset; - struct tasklet_struct *wake_tasklet; - unsigned char buf[0]; -}; - -struct bas_bc_state { - /* isochronous output state */ - atomic_t running; - atomic_t corrbytes; - spinlock_t isooutlock; - struct isow_urbctx_t isoouturbs[BAS_OUTURBS]; - struct isow_urbctx_t *isooutdone, *isooutfree, *isooutovfl; - struct isowbuf_t *isooutbuf; - unsigned numsub; /* submitted URB counter - (for diagnostic messages only) */ - struct tasklet_struct sent_tasklet; - - /* isochronous input state */ - spinlock_t isoinlock; - struct urb *isoinurbs[BAS_INURBS]; - unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS]; - struct urb *isoindone; /* completed isoc read URB */ - int loststatus; /* status of dropped URB */ - unsigned isoinlost; /* number of bytes lost */ - /* state of bit unstuffing algorithm - (in addition to BC_state.inputstate) */ - unsigned seqlen; /* number of '1' bits not yet - unstuffed */ - unsigned inbyte, inbits; /* collected bits for next byte */ - /* statistics */ - unsigned goodbytes; /* bytes correctly received */ - unsigned alignerrs; /* frames with incomplete byte at end */ - unsigned fcserrs; /* FCS errors */ - unsigned frameerrs; /* framing errors */ - unsigned giants; /* long frames */ - unsigned runts; /* short frames */ - unsigned aborts; /* HDLC aborts */ - unsigned shared0s; /* '0' bits shared between flags */ - unsigned stolen0s; /* '0' stuff bits also serving as - leading flag bits */ - struct tasklet_struct rcvd_tasklet; -}; - -struct gigaset_ops { - /* Called from ev-layer.c/interface.c for sending AT commands to the - device */ - int (*write_cmd)(struct cardstate *cs, - const unsigned char *buf, int len, - struct tasklet_struct *wake_tasklet); - - /* Called from interface.c for additional device control */ - int (*write_room)(struct cardstate *cs); - int (*chars_in_buffer)(struct cardstate *cs); - int (*brkchars)(struct cardstate *cs, const unsigned char buf[6]); - - /* Called from ev-layer.c after setting up connection - * Should call gigaset_bchannel_up(), when finished. */ - int (*init_bchannel)(struct bc_state *bcs); - - /* Called from ev-layer.c after hanging up - * Should call gigaset_bchannel_down(), when finished. */ - int (*close_bchannel)(struct bc_state *bcs); - - /* Called by gigaset_initcs() for setting up bcs->hw.xxx */ - int (*initbcshw)(struct bc_state *bcs); - - /* Called by gigaset_freecs() for freeing bcs->hw.xxx */ - int (*freebcshw)(struct bc_state *bcs); - - /* Called by gigaset_bchannel_down() for resetting bcs->hw.xxx */ - void (*reinitbcshw)(struct bc_state *bcs); - - /* Called by gigaset_initcs() for setting up cs->hw.xxx */ - int (*initcshw)(struct cardstate *cs); - - /* Called by gigaset_freecs() for freeing cs->hw.xxx */ - void (*freecshw)(struct cardstate *cs); - - /* Called from common.c/interface.c for additional serial port - control */ - int (*set_modem_ctrl)(struct cardstate *cs, unsigned old_state, - unsigned new_state); - int (*baud_rate)(struct cardstate *cs, unsigned cflag); - int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); - - /* Called from i4l.c to put an skb into the send-queue. */ - int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb); - - /* Called from ev-layer.c to process a block of data - * received through the common/control channel. */ - void (*handle_input)(struct inbuf_t *inbuf); - -}; - -/* = Common structures and definitions ======================================= */ - -/* Parser states for DLE-Event: - * : "X" "." - * : 0x10 - * : ((a-z)* | (A-Z)* | (0-10)*)+ - */ -#define DLE_FLAG 0x10 - -/* =========================================================================== - * Functions implemented in asyncdata.c - */ - -/* Called from i4l.c to put an skb into the send-queue. - * After sending gigaset_skb_sent() should be called. */ -int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb); - -/* Called from ev-layer.c to process a block of data - * received through the common/control channel. */ -void gigaset_m10x_input(struct inbuf_t *inbuf); - -/* =========================================================================== - * Functions implemented in isocdata.c - */ - -/* Called from i4l.c to put an skb into the send-queue. - * After sending gigaset_skb_sent() should be called. */ -int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb); - -/* Called from ev-layer.c to process a block of data - * received through the common/control channel. */ -void gigaset_isoc_input(struct inbuf_t *inbuf); - -/* Called from bas-gigaset.c to process a block of data - * received through the isochronous channel */ -void gigaset_isoc_receive(unsigned char *src, unsigned count, - struct bc_state *bcs); - -/* Called from bas-gigaset.c to put a block of data - * into the isochronous output buffer */ -int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len); - -/* Called from bas-gigaset.c to initialize the isochronous output buffer */ -void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle); - -/* Called from bas-gigaset.c to retrieve a block of bytes for sending */ -int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size); - -/* =========================================================================== - * Functions implemented in i4l.c/gigaset.h - */ - -/* Called by gigaset_initcs() for setting up with the isdn4linux subsystem */ -int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid); - -/* Called from xxx-gigaset.c to indicate completion of sending an skb */ -void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); - -/* Called from common.c/ev-layer.c to indicate events relevant to the LL */ -int gigaset_isdn_icall(struct at_state_t *at_state); -int gigaset_isdn_setup_accept(struct at_state_t *at_state); -int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data); - -void gigaset_i4l_cmd(struct cardstate *cs, int cmd); -void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd); - - -static inline void gigaset_isdn_rcv_err(struct bc_state *bcs) -{ - isdn_ctrl response; - - /* error -> LL */ - gig_dbg(DEBUG_CMD, "sending L1ERR"); - response.driver = bcs->cs->myid; - response.command = ISDN_STAT_L1ERR; - response.arg = bcs->channel; - response.parm.errcode = ISDN_STAT_L1ERR_RECV; - bcs->cs->iif.statcallb(&response); -} - -/* =========================================================================== - * Functions implemented in ev-layer.c - */ - -/* tasklet called from common.c to process queued events */ -void gigaset_handle_event(unsigned long data); - -/* called from isocdata.c / asyncdata.c - * when a complete modem response line has been received */ -void gigaset_handle_modem_response(struct cardstate *cs); - -/* =========================================================================== - * Functions implemented in proc.c - */ - -/* initialize sysfs for device */ -void gigaset_init_dev_sysfs(struct cardstate *cs); -void gigaset_free_dev_sysfs(struct cardstate *cs); - -/* =========================================================================== - * Functions implemented in common.c/gigaset.h - */ - -void gigaset_bcs_reinit(struct bc_state *bcs); -void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, - struct cardstate *cs, int cid); -int gigaset_get_channel(struct bc_state *bcs); -void gigaset_free_channel(struct bc_state *bcs); -int gigaset_get_channels(struct cardstate *cs); -void gigaset_free_channels(struct cardstate *cs); -void gigaset_block_channels(struct cardstate *cs); - -/* Allocate and initialize driver structure. */ -struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, - const char *procname, - const char *devname, - const char *devfsname, - const struct gigaset_ops *ops, - struct module *owner); - -/* Deallocate driver structure. */ -void gigaset_freedriver(struct gigaset_driver *drv); -void gigaset_debugdrivers(void); -struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); -struct cardstate *gigaset_get_cs_by_id(int id); - -/* For drivers without fixed assignment device<->cardstate (usb) */ -struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv); -void gigaset_unassign(struct cardstate *cs); -void gigaset_blockdriver(struct gigaset_driver *drv); - -/* Allocate and initialize card state. Calls hardware dependent - gigaset_init[b]cs(). */ -struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, - int onechannel, int ignoreframes, - int cidmode, const char *modulename); - -/* Free card state. Calls hardware dependent gigaset_free[b]cs(). */ -void gigaset_freecs(struct cardstate *cs); - -/* Tell common.c that hardware and driver are ready. */ -int gigaset_start(struct cardstate *cs); - -/* Tell common.c that the device is not present any more. */ -void gigaset_stop(struct cardstate *cs); - -/* Tell common.c that the driver is being unloaded. */ -void gigaset_shutdown(struct cardstate *cs); - -/* Tell common.c that an skb has been sent. */ -void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); - -/* Append event to the queue. - * Returns NULL on failure or a pointer to the event on success. - * ptr must be kmalloc()ed (and not be freed by the caller). - */ -struct event_t *gigaset_add_event(struct cardstate *cs, - struct at_state_t *at_state, int type, - void *ptr, int parameter, void *arg); - -/* Called on CONFIG1 command from frontend. */ -int gigaset_enterconfigmode(struct cardstate *cs); //0: success <0: errorcode - -/* cs->lock must not be locked */ -static inline void gigaset_schedule_event(struct cardstate *cs) -{ - unsigned long flags; - spin_lock_irqsave(&cs->lock, flags); - if (cs->running) - tasklet_schedule(&cs->event_tasklet); - spin_unlock_irqrestore(&cs->lock, flags); -} - -/* Tell common.c that B channel has been closed. */ -/* cs->lock must not be locked */ -static inline void gigaset_bchannel_down(struct bc_state *bcs) -{ - gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL); - - gig_dbg(DEBUG_CMD, "scheduling BC_CLOSED"); - gigaset_schedule_event(bcs->cs); -} - -/* Tell common.c that B channel has been opened. */ -/* cs->lock must not be locked */ -static inline void gigaset_bchannel_up(struct bc_state *bcs) -{ - gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL); - - gig_dbg(DEBUG_CMD, "scheduling BC_OPEN"); - gigaset_schedule_event(bcs->cs); -} - -/* handling routines for sk_buff */ -/* ============================= */ - -/* pass received skb to LL - * Warning: skb must not be accessed anymore! - */ -static inline void gigaset_rcv_skb(struct sk_buff *skb, - struct cardstate *cs, - struct bc_state *bcs) -{ - cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb); - bcs->trans_down++; -} - -/* handle reception of corrupted skb - * Warning: skb must not be accessed anymore! - */ -static inline void gigaset_rcv_error(struct sk_buff *procskb, - struct cardstate *cs, - struct bc_state *bcs) -{ - if (procskb) - dev_kfree_skb(procskb); - - if (bcs->ignore) - --bcs->ignore; - else { - ++bcs->corrupted; - gigaset_isdn_rcv_err(bcs); - } -} - - -/* bitwise byte inversion table */ -extern __u8 gigaset_invtab[]; /* in common.c */ - -/* append received bytes to inbuf */ -int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, - unsigned numbytes); - -/* =========================================================================== - * Functions implemented in interface.c - */ - -/* initialize interface */ -void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, - const char *devname, const char *devfsname); -/* release interface */ -void gigaset_if_freedriver(struct gigaset_driver *drv); -/* add minor */ -void gigaset_if_init(struct cardstate *cs); -/* remove minor */ -void gigaset_if_free(struct cardstate *cs); -/* device received data */ -void gigaset_if_receive(struct cardstate *cs, - unsigned char *buffer, size_t len); - -#endif diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c deleted file mode 100644 index 1654fa413..000000000 --- a/drivers/isdn/gigaset/i4l.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Stuff used by all variants of the driver - * - * Copyright (c) 2001 by Stefan Eilers, - * Hansjoerg Lipp , - * Tilman Schmidt . - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" - -/* == Handling of I4L IO =====================================================*/ - -/* writebuf_from_LL - * called by LL to transmit data on an open channel - * inserts the buffer data into the send queue and starts the transmission - * Note that this operation must not sleep! - * When the buffer is processed completely, gigaset_skb_sent() should be called. - * parameters: - * driverID driver ID as assigned by LL - * channel channel number - * ack if != 0 LL wants to be notified on completion via - * statcallb(ISDN_STAT_BSENT) - * skb skb containing data to send - * return value: - * number of accepted bytes - * 0 if temporarily unable to accept data (out of buffer space) - * <0 on error (eg. -EINVAL) - */ -static int writebuf_from_LL(int driverID, int channel, int ack, - struct sk_buff *skb) -{ - struct cardstate *cs; - struct bc_state *bcs; - unsigned len; - unsigned skblen; - - if (!(cs = gigaset_get_cs_by_id(driverID))) { - err("%s: invalid driver ID (%d)", __func__, driverID); - return -ENODEV; - } - if (channel < 0 || channel >= cs->channels) { - err("%s: invalid channel ID (%d)", __func__, channel); - return -ENODEV; - } - bcs = &cs->bcs[channel]; - len = skb->len; - - gig_dbg(DEBUG_LLDATA, - "Receiving data from LL (id: %d, ch: %d, ack: %d, sz: %d)", - driverID, channel, ack, len); - - if (!len) { - if (ack) - notice("%s: not ACKing empty packet", __func__); - return 0; - } - if (len > MAX_BUF_SIZE) { - err("%s: packet too large (%d bytes)", __func__, len); - return -EINVAL; - } - - skblen = ack ? len : 0; - skb->head[0] = skblen & 0xff; - skb->head[1] = skblen >> 8; - gig_dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x", - len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]); - - /* pass to device-specific module */ - return cs->ops->send_skb(bcs, skb); -} - -void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) -{ - unsigned len; - isdn_ctrl response; - - ++bcs->trans_up; - - if (skb->len) - dev_warn(bcs->cs->dev, "%s: skb->len==%d\n", - __func__, skb->len); - - len = (unsigned char) skb->head[0] | - (unsigned) (unsigned char) skb->head[1] << 8; - if (len) { - gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)", - bcs->cs->myid, bcs->channel, len); - - response.driver = bcs->cs->myid; - response.command = ISDN_STAT_BSENT; - response.arg = bcs->channel; - response.parm.length = len; - bcs->cs->iif.statcallb(&response); - } -} -EXPORT_SYMBOL_GPL(gigaset_skb_sent); - -/* This function will be called by LL to send commands - * NOTE: LL ignores the returned value, for commands other than ISDN_CMD_IOCTL, - * so don't put too much effort into it. - */ -static int command_from_LL(isdn_ctrl *cntrl) -{ - struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver); - //isdn_ctrl response; - //unsigned long flags; - struct bc_state *bcs; - int retval = 0; - struct setup_parm *sp; - unsigned param; - unsigned long flags; - - gigaset_debugdrivers(); - - if (!cs) { - warn("LL tried to access unknown device with nr. %d", - cntrl->driver); - return -ENODEV; - } - - switch (cntrl->command) { - case ISDN_CMD_IOCTL: - gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)", - cntrl->driver, cntrl->arg); - - warn("ISDN_CMD_IOCTL is not supported."); - return -EINVAL; - - case ISDN_CMD_DIAL: - gig_dbg(DEBUG_ANY, - "ISDN_CMD_DIAL (driver: %d, ch: %ld, " - "phone: %s, ownmsn: %s, si1: %d, si2: %d)", - cntrl->driver, cntrl->arg, - cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, - cntrl->parm.setup.si1, cntrl->parm.setup.si2); - - if (cntrl->arg >= cs->channels) { - err("ISDN_CMD_DIAL: invalid channel (%d)", - (int) cntrl->arg); - return -EINVAL; - } - - bcs = cs->bcs + cntrl->arg; - - if (!gigaset_get_channel(bcs)) { - err("ISDN_CMD_DIAL: channel not free"); - return -EBUSY; - } - - sp = kmalloc(sizeof *sp, GFP_ATOMIC); - if (!sp) { - gigaset_free_channel(bcs); - err("ISDN_CMD_DIAL: out of memory"); - return -ENOMEM; - } - *sp = cntrl->parm.setup; - - spin_lock_irqsave(&cs->lock, flags); - param = bcs->at_state.seq_index; - spin_unlock_irqrestore(&cs->lock, flags); - - if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, param, - NULL)) { - //FIXME what should we do? - kfree(sp); - gigaset_free_channel(bcs); - return -ENOMEM; - } - - gig_dbg(DEBUG_CMD, "scheduling DIAL"); - gigaset_schedule_event(cs); - break; - case ISDN_CMD_ACCEPTD: //FIXME - gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD"); - - if (cntrl->arg >= cs->channels) { - err("ISDN_CMD_ACCEPTD: invalid channel (%d)", - (int) cntrl->arg); - return -EINVAL; - } - - if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, - EV_ACCEPT, NULL, 0, NULL)) { - //FIXME what should we do? - return -ENOMEM; - } - - gig_dbg(DEBUG_CMD, "scheduling ACCEPT"); - gigaset_schedule_event(cs); - - break; - case ISDN_CMD_ACCEPTB: - gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB"); - break; - case ISDN_CMD_HANGUP: - gig_dbg(DEBUG_ANY, "ISDN_CMD_HANGUP (ch: %d)", - (int) cntrl->arg); - - if (cntrl->arg >= cs->channels) { - err("ISDN_CMD_HANGUP: invalid channel (%u)", - (unsigned) cntrl->arg); - return -EINVAL; - } - - if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, - EV_HUP, NULL, 0, NULL)) { - //FIXME what should we do? - return -ENOMEM; - } - - gig_dbg(DEBUG_CMD, "scheduling HUP"); - gigaset_schedule_event(cs); - - break; - case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME - gig_dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ"); - break; - case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME - gig_dbg(DEBUG_ANY, - "ISDN_CMD_SETEAZ (id: %d, ch: %ld, number: %s)", - cntrl->driver, cntrl->arg, cntrl->parm.num); - break; - case ISDN_CMD_SETL2: /* Set L2 to given protocol */ - gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (ch: %ld, proto: %lx)", - cntrl->arg & 0xff, (cntrl->arg >> 8)); - - if ((cntrl->arg & 0xff) >= cs->channels) { - err("ISDN_CMD_SETL2: invalid channel (%u)", - (unsigned) cntrl->arg & 0xff); - return -EINVAL; - } - - if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state, - EV_PROTO_L2, NULL, cntrl->arg >> 8, - NULL)) { - //FIXME what should we do? - return -ENOMEM; - } - - gig_dbg(DEBUG_CMD, "scheduling PROTO_L2"); - gigaset_schedule_event(cs); - break; - case ISDN_CMD_SETL3: /* Set L3 to given protocol */ - gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (ch: %ld, proto: %lx)", - cntrl->arg & 0xff, (cntrl->arg >> 8)); - - if ((cntrl->arg & 0xff) >= cs->channels) { - err("ISDN_CMD_SETL3: invalid channel (%u)", - (unsigned) cntrl->arg & 0xff); - return -EINVAL; - } - - if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { - err("ISDN_CMD_SETL3: invalid protocol %lu", - cntrl->arg >> 8); - return -EINVAL; - } - - break; - case ISDN_CMD_PROCEED: - gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME - break; - case ISDN_CMD_ALERT: - gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME - if (cntrl->arg >= cs->channels) { - err("ISDN_CMD_ALERT: invalid channel (%d)", - (int) cntrl->arg); - return -EINVAL; - } - //bcs = cs->bcs + cntrl->arg; - //bcs->proto2 = -1; - // FIXME - break; - case ISDN_CMD_REDIR: - gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME - break; - case ISDN_CMD_PROT_IO: - gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO"); - break; - case ISDN_CMD_FAXCMD: - gig_dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD"); - break; - case ISDN_CMD_GETL2: - gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL2"); - break; - case ISDN_CMD_GETL3: - gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL3"); - break; - case ISDN_CMD_GETEAZ: - gig_dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ"); - break; - case ISDN_CMD_SETSIL: - gig_dbg(DEBUG_ANY, "ISDN_CMD_SETSIL"); - break; - case ISDN_CMD_GETSIL: - gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL"); - break; - default: - err("unknown command %d from LL", cntrl->command); - return -EINVAL; - } - - return retval; -} - -void gigaset_i4l_cmd(struct cardstate *cs, int cmd) -{ - isdn_ctrl command; - - command.driver = cs->myid; - command.command = cmd; - command.arg = 0; - cs->iif.statcallb(&command); -} - -void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd) -{ - isdn_ctrl command; - - command.driver = bcs->cs->myid; - command.command = cmd; - command.arg = bcs->channel; - bcs->cs->iif.statcallb(&command); -} - -int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data) -{ - struct bc_state *bcs = at_state->bcs; - unsigned proto; - const char *bc; - size_t length[AT_NUM]; - size_t l; - int i; - struct setup_parm *sp = data; - - switch (bcs->proto2) { - case ISDN_PROTO_L2_HDLC: - proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */ - break; - case ISDN_PROTO_L2_TRANS: - proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ - break; - default: - dev_err(bcs->cs->dev, "%s: invalid L2 protocol: %u\n", - __func__, bcs->proto2); - return -EINVAL; - } - - switch (sp->si1) { - case 1: /* audio */ - bc = "9090A3"; /* 3.1 kHz audio, A-law */ - break; - case 7: /* data */ - default: /* hope the app knows what it is doing */ - bc = "8890"; /* unrestricted digital information */ - } - //FIXME add missing si1 values from 1TR6, inspect si2, set HLC/LLC - - length[AT_DIAL ] = 1 + strlen(sp->phone) + 1 + 1; - l = strlen(sp->eazmsn); - length[AT_MSN ] = l ? 6 + l + 1 + 1 : 0; - length[AT_BC ] = 5 + strlen(bc) + 1 + 1; - length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */ - length[AT_ISO ] = 6 + 1 + 1 + 1; /* channel: 1 character */ - length[AT_TYPE ] = 6 + 1 + 1 + 1; /* call type: 1 character */ - length[AT_HLC ] = 0; - - for (i = 0; i < AT_NUM; ++i) { - kfree(bcs->commands[i]); - bcs->commands[i] = NULL; - if (length[i] && - !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { - dev_err(bcs->cs->dev, "out of memory\n"); - return -ENOMEM; - } - } - - /* type = 1: extern, 0: intern, 2: recall, 3: door, 4: centrex */ - if (sp->phone[0] == '*' && sp->phone[1] == '*') { - /* internal call: translate ** prefix to CTP value */ - snprintf(bcs->commands[AT_DIAL], length[AT_DIAL], - "D%s\r", sp->phone+2); - strncpy(bcs->commands[AT_TYPE], "^SCTP=0\r", length[AT_TYPE]); - } else { - snprintf(bcs->commands[AT_DIAL], length[AT_DIAL], - "D%s\r", sp->phone); - strncpy(bcs->commands[AT_TYPE], "^SCTP=1\r", length[AT_TYPE]); - } - - if (bcs->commands[AT_MSN]) - snprintf(bcs->commands[AT_MSN], length[AT_MSN], - "^SMSN=%s\r", sp->eazmsn); - snprintf(bcs->commands[AT_BC ], length[AT_BC ], - "^SBC=%s\r", bc); - snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], - "^SBPR=%u\r", proto); - snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], - "^SISO=%u\r", (unsigned)bcs->channel + 1); - - return 0; -} - -int gigaset_isdn_setup_accept(struct at_state_t *at_state) -{ - unsigned proto; - size_t length[AT_NUM]; - int i; - struct bc_state *bcs = at_state->bcs; - - switch (bcs->proto2) { - case ISDN_PROTO_L2_HDLC: - proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */ - break; - case ISDN_PROTO_L2_TRANS: - proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ - break; - default: - dev_err(at_state->cs->dev, "%s: invalid protocol: %u\n", - __func__, bcs->proto2); - return -EINVAL; - } - - length[AT_DIAL ] = 0; - length[AT_MSN ] = 0; - length[AT_BC ] = 0; - length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */ - length[AT_ISO ] = 6 + 1 + 1 + 1; /* channel: 1 character */ - length[AT_TYPE ] = 0; - length[AT_HLC ] = 0; - - for (i = 0; i < AT_NUM; ++i) { - kfree(bcs->commands[i]); - bcs->commands[i] = NULL; - if (length[i] && - !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { - dev_err(at_state->cs->dev, "out of memory\n"); - return -ENOMEM; - } - } - - snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], - "^SBPR=%u\r", proto); - snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], - "^SISO=%u\r", (unsigned) bcs->channel + 1); - - return 0; -} - -int gigaset_isdn_icall(struct at_state_t *at_state) -{ - struct cardstate *cs = at_state->cs; - struct bc_state *bcs = at_state->bcs; - isdn_ctrl response; - int retval; - - /* fill ICALL structure */ - response.parm.setup.si1 = 0; /* default: unknown */ - response.parm.setup.si2 = 0; - response.parm.setup.screen = 0; //FIXME how to set these? - response.parm.setup.plan = 0; - if (!at_state->str_var[STR_ZBC]) { - /* no BC (internal call): assume speech, A-law */ - response.parm.setup.si1 = 1; - } else if (!strcmp(at_state->str_var[STR_ZBC], "8890")) { - /* unrestricted digital information */ - response.parm.setup.si1 = 7; - } else if (!strcmp(at_state->str_var[STR_ZBC], "8090A3")) { - /* speech, A-law */ - response.parm.setup.si1 = 1; - } else if (!strcmp(at_state->str_var[STR_ZBC], "9090A3")) { - /* 3,1 kHz audio, A-law */ - response.parm.setup.si1 = 1; - response.parm.setup.si2 = 2; - } else { - dev_warn(cs->dev, "RING ignored - unsupported BC %s\n", - at_state->str_var[STR_ZBC]); - return ICALL_IGNORE; - } - if (at_state->str_var[STR_NMBR]) { - strncpy(response.parm.setup.phone, at_state->str_var[STR_NMBR], - sizeof response.parm.setup.phone - 1); - response.parm.setup.phone[sizeof response.parm.setup.phone - 1] = 0; - } else - response.parm.setup.phone[0] = 0; - if (at_state->str_var[STR_ZCPN]) { - strncpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN], - sizeof response.parm.setup.eazmsn - 1); - response.parm.setup.eazmsn[sizeof response.parm.setup.eazmsn - 1] = 0; - } else - response.parm.setup.eazmsn[0] = 0; - - if (!bcs) { - dev_notice(cs->dev, "no channel for incoming call\n"); - response.command = ISDN_STAT_ICALLW; - response.arg = 0; //FIXME - } else { - gig_dbg(DEBUG_CMD, "Sending ICALL"); - response.command = ISDN_STAT_ICALL; - response.arg = bcs->channel; //FIXME - } - response.driver = cs->myid; - retval = cs->iif.statcallb(&response); - gig_dbg(DEBUG_CMD, "Response: %d", retval); - switch (retval) { - case 0: /* no takers */ - return ICALL_IGNORE; - case 1: /* alerting */ - bcs->chstate |= CHS_NOTIFY_LL; - return ICALL_ACCEPT; - case 2: /* reject */ - return ICALL_REJECT; - case 3: /* incomplete */ - dev_warn(cs->dev, - "LL requested unsupported feature: Incomplete Number\n"); - return ICALL_IGNORE; - case 4: /* proceeding */ - /* Gigaset will send ALERTING anyway. - * There doesn't seem to be a way to avoid this. - */ - return ICALL_ACCEPT; - case 5: /* deflect */ - dev_warn(cs->dev, - "LL requested unsupported feature: Call Deflection\n"); - return ICALL_IGNORE; - default: - dev_err(cs->dev, "LL error %d on ICALL\n", retval); - return ICALL_IGNORE; - } -} - -/* Set Callback function pointer */ -int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) -{ - isdn_if *iif = &cs->iif; - - gig_dbg(DEBUG_ANY, "Register driver capabilities to LL"); - - //iif->id[sizeof(iif->id) - 1]=0; - //strncpy(iif->id, isdnid, sizeof(iif->id) - 1); - if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index) - >= sizeof iif->id) - return -ENOMEM; //FIXME EINVAL/...?? - - iif->owner = THIS_MODULE; - iif->channels = cs->channels; - iif->maxbufsize = MAX_BUF_SIZE; - iif->features = ISDN_FEATURE_L2_TRANS | - ISDN_FEATURE_L2_HDLC | -#ifdef GIG_X75 - ISDN_FEATURE_L2_X75I | -#endif - ISDN_FEATURE_L3_TRANS | - ISDN_FEATURE_P_EURO; - iif->hl_hdrlen = HW_HDR_LEN; /* Area for storing ack */ - iif->command = command_from_LL; - iif->writebuf_skb = writebuf_from_LL; - iif->writecmd = NULL; /* Don't support isdnctrl */ - iif->readstat = NULL; /* Don't support isdnctrl */ - iif->rcvcallb_skb = NULL; /* Will be set by LL */ - iif->statcallb = NULL; /* Will be set by LL */ - - if (!register_isdn(iif)) - return 0; - - cs->myid = iif->channels; /* Set my device id */ - return 1; -} diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c deleted file mode 100644 index 08e4c4eea..000000000 --- a/drivers/isdn/gigaset/interface.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * interface to user space for the gigaset driver - * - * Copyright (c) 2004 by Hansjoerg Lipp - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" -#include -#include -#include - -/*** our ioctls ***/ - -static int if_lock(struct cardstate *cs, int *arg) -{ - int cmd = *arg; - - gig_dbg(DEBUG_IF, "%u: if_lock (%d)", cs->minor_index, cmd); - - if (cmd > 1) - return -EINVAL; - - if (cmd < 0) { - *arg = atomic_read(&cs->mstate) == MS_LOCKED; //FIXME remove? - return 0; - } - - if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED - && cs->connected) { - cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); - cs->ops->baud_rate(cs, B115200); - cs->ops->set_line_ctrl(cs, CS8); - cs->control_state = TIOCM_DTR|TIOCM_RTS; - } - - cs->waiting = 1; - if (!gigaset_add_event(cs, &cs->at_state, EV_IF_LOCK, - NULL, cmd, NULL)) { - cs->waiting = 0; - return -ENOMEM; - } - - gig_dbg(DEBUG_CMD, "scheduling IF_LOCK"); - gigaset_schedule_event(cs); - - wait_event(cs->waitqueue, !cs->waiting); - - if (cs->cmd_result >= 0) { - *arg = cs->cmd_result; - return 0; - } - - return cs->cmd_result; -} - -static int if_version(struct cardstate *cs, unsigned arg[4]) -{ - static const unsigned version[4] = GIG_VERSION; - static const unsigned compat[4] = GIG_COMPAT; - unsigned cmd = arg[0]; - - gig_dbg(DEBUG_IF, "%u: if_version (%d)", cs->minor_index, cmd); - - switch (cmd) { - case GIGVER_DRIVER: - memcpy(arg, version, sizeof version); - return 0; - case GIGVER_COMPAT: - memcpy(arg, compat, sizeof compat); - return 0; - case GIGVER_FWBASE: - cs->waiting = 1; - if (!gigaset_add_event(cs, &cs->at_state, EV_IF_VER, - NULL, 0, arg)) { - cs->waiting = 0; - return -ENOMEM; - } - - gig_dbg(DEBUG_CMD, "scheduling IF_VER"); - gigaset_schedule_event(cs); - - wait_event(cs->waitqueue, !cs->waiting); - - if (cs->cmd_result >= 0) - return 0; - - return cs->cmd_result; - default: - return -EINVAL; - } -} - -static int if_config(struct cardstate *cs, int *arg) -{ - gig_dbg(DEBUG_IF, "%u: if_config (%d)", cs->minor_index, *arg); - - if (*arg != 1) - return -EINVAL; - - if (atomic_read(&cs->mstate) != MS_LOCKED) - return -EBUSY; - - if (!cs->connected) { - err("not connected!"); - return -ENODEV; - } - - *arg = 0; - return gigaset_enterconfigmode(cs); -} - -/*** the terminal driver ***/ -/* stolen from usbserial and some other tty drivers */ - -static int if_open(struct tty_struct *tty, struct file *filp); -static void if_close(struct tty_struct *tty, struct file *filp); -static int if_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); -static int if_write_room(struct tty_struct *tty); -static int if_chars_in_buffer(struct tty_struct *tty); -static void if_throttle(struct tty_struct *tty); -static void if_unthrottle(struct tty_struct *tty); -static void if_set_termios(struct tty_struct *tty, struct termios *old); -static int if_tiocmget(struct tty_struct *tty, struct file *file); -static int if_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear); -static int if_write(struct tty_struct *tty, - const unsigned char *buf, int count); - -static struct tty_operations if_ops = { - .open = if_open, - .close = if_close, - .ioctl = if_ioctl, - .write = if_write, - .write_room = if_write_room, - .chars_in_buffer = if_chars_in_buffer, - .set_termios = if_set_termios, - .throttle = if_throttle, - .unthrottle = if_unthrottle, -#if 0 - .break_ctl = serial_break, -#endif - .tiocmget = if_tiocmget, - .tiocmset = if_tiocmset, -}; - -static int if_open(struct tty_struct *tty, struct file *filp) -{ - struct cardstate *cs; - unsigned long flags; - - gig_dbg(DEBUG_IF, "%d+%d: %s()", - tty->driver->minor_start, tty->index, __func__); - - tty->driver_data = NULL; - - cs = gigaset_get_cs_by_tty(tty); - if (!cs) - return -ENODEV; - - if (mutex_lock_interruptible(&cs->mutex)) - return -ERESTARTSYS; // FIXME -EINTR? - tty->driver_data = cs; - - ++cs->open_count; - - if (cs->open_count == 1) { - spin_lock_irqsave(&cs->lock, flags); - cs->tty = tty; - spin_unlock_irqrestore(&cs->lock, flags); - tty->low_latency = 1; //FIXME test - } - - mutex_unlock(&cs->mutex); - return 0; -} - -static void if_close(struct tty_struct *tty, struct file *filp) -{ - struct cardstate *cs; - unsigned long flags; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return; - } - - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); - - mutex_lock(&cs->mutex); - - if (!cs->open_count) - warn("%s: device not opened", __func__); - else { - if (!--cs->open_count) { - spin_lock_irqsave(&cs->lock, flags); - cs->tty = NULL; - spin_unlock_irqrestore(&cs->lock, flags); - } - } - - mutex_unlock(&cs->mutex); -} - -static int if_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct cardstate *cs; - int retval = -ENODEV; - int int_arg; - unsigned char buf[6]; - unsigned version[4]; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return -ENODEV; - } - - gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd); - - if (mutex_lock_interruptible(&cs->mutex)) - return -ERESTARTSYS; // FIXME -EINTR? - - if (!cs->open_count) - warn("%s: device not opened", __func__); - else { - retval = 0; - switch (cmd) { - case GIGASET_REDIR: - retval = get_user(int_arg, (int __user *) arg); - if (retval >= 0) - retval = if_lock(cs, &int_arg); - if (retval >= 0) - retval = put_user(int_arg, (int __user *) arg); - break; - case GIGASET_CONFIG: - retval = get_user(int_arg, (int __user *) arg); - if (retval >= 0) - retval = if_config(cs, &int_arg); - if (retval >= 0) - 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; - if (retval >= 0) { - gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS", - 6, (const unsigned char *) arg); - retval = cs->ops->brkchars(cs, buf); - } - break; - case GIGASET_VERSION: - retval = copy_from_user(version, - (unsigned __user *) arg, sizeof version) - ? -EFAULT : 0; - if (retval >= 0) - retval = if_version(cs, version); - if (retval >= 0) - retval = copy_to_user((unsigned __user *) arg, - version, sizeof version) - ? -EFAULT : 0; - break; - default: - gig_dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x", - __func__, cmd); - retval = -ENOIOCTLCMD; - } - } - - mutex_unlock(&cs->mutex); - - return retval; -} - -static int if_tiocmget(struct tty_struct *tty, struct file *file) -{ - struct cardstate *cs; - int retval; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return -ENODEV; - } - - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); - - if (mutex_lock_interruptible(&cs->mutex)) - return -ERESTARTSYS; // FIXME -EINTR? - - // FIXME read from device? - retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR); - - mutex_unlock(&cs->mutex); - - return retval; -} - -static int if_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) -{ - struct cardstate *cs; - int retval; - unsigned mc; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return -ENODEV; - } - - gig_dbg(DEBUG_IF, "%u: %s(0x%x, 0x%x)", - cs->minor_index, __func__, set, clear); - - if (mutex_lock_interruptible(&cs->mutex)) - return -ERESTARTSYS; // FIXME -EINTR? - - if (!cs->connected) { - gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); - retval = -ENODEV; - } else { - mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR); - retval = cs->ops->set_modem_ctrl(cs, cs->control_state, mc); - cs->control_state = mc; - } - - mutex_unlock(&cs->mutex); - - return retval; -} - -static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - struct cardstate *cs; - int retval = -ENODEV; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return -ENODEV; - } - - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); - - if (mutex_lock_interruptible(&cs->mutex)) - return -ERESTARTSYS; // FIXME -EINTR? - - if (!cs->open_count) - warn("%s: device not opened", __func__); - else if (atomic_read(&cs->mstate) != MS_LOCKED) { - warn("can't write to unlocked device"); - 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); - } - - mutex_unlock(&cs->mutex); - - return retval; -} - -static int if_write_room(struct tty_struct *tty) -{ - struct cardstate *cs; - int retval = -ENODEV; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return -ENODEV; - } - - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); - - if (mutex_lock_interruptible(&cs->mutex)) - return -ERESTARTSYS; // FIXME -EINTR? - - if (!cs->open_count) - warn("%s: device not opened", __func__); - else if (atomic_read(&cs->mstate) != MS_LOCKED) { - warn("can't write to unlocked device"); - retval = -EBUSY; //FIXME - } else if (!cs->connected) { - gig_dbg(DEBUG_ANY, "can't write to unplugged device"); - retval = -EBUSY; //FIXME - } else - retval = cs->ops->write_room(cs); - - mutex_unlock(&cs->mutex); - - return retval; -} - -static int if_chars_in_buffer(struct tty_struct *tty) -{ - struct cardstate *cs; - int retval = -ENODEV; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return -ENODEV; - } - - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); - - if (mutex_lock_interruptible(&cs->mutex)) - return -ERESTARTSYS; // FIXME -EINTR? - - if (!cs->open_count) - warn("%s: device not opened", __func__); - else if (atomic_read(&cs->mstate) != MS_LOCKED) { - warn("can't write to unlocked device"); - 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); - - mutex_unlock(&cs->mutex); - - return retval; -} - -static void if_throttle(struct tty_struct *tty) -{ - struct cardstate *cs; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return; - } - - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); - - mutex_lock(&cs->mutex); - - if (!cs->open_count) - warn("%s: device not opened", __func__); - else { - //FIXME - } - - mutex_unlock(&cs->mutex); -} - -static void if_unthrottle(struct tty_struct *tty) -{ - struct cardstate *cs; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return; - } - - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); - - mutex_lock(&cs->mutex); - - if (!cs->open_count) - warn("%s: device not opened", __func__); - else { - //FIXME - } - - mutex_unlock(&cs->mutex); -} - -static void if_set_termios(struct tty_struct *tty, struct termios *old) -{ - struct cardstate *cs; - unsigned int iflag; - unsigned int cflag; - unsigned int old_cflag; - unsigned int control_state, new_state; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - err("cs==NULL in %s", __func__); - return; - } - - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); - - mutex_lock(&cs->mutex); - - if (!cs->open_count) { - warn("%s: device not opened", __func__); - goto out; - } - - if (!cs->connected) { - gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); - goto out; - } - - // stolen from mct_u232.c - iflag = tty->termios->c_iflag; - cflag = tty->termios->c_cflag; - old_cflag = old ? old->c_cflag : cflag; //FIXME? - gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", - cs->minor_index, iflag, cflag, old_cflag); - - /* get a local copy of the current port settings */ - control_state = cs->control_state; - - /* - * Update baud rate. - * Do not attempt to cache old rates and skip settings, - * disconnects screw such tricks up completely. - * Premature optimization is the root of all evil. - */ - - /* reassert DTR and (maybe) RTS on transition from B0 */ - if ((old_cflag & CBAUD) == B0) { - new_state = control_state | TIOCM_DTR; - /* don't set RTS if using hardware flow control */ - if (!(old_cflag & CRTSCTS)) - new_state |= TIOCM_RTS; - gig_dbg(DEBUG_IF, "%u: from B0 - set DTR%s", - cs->minor_index, - (new_state & TIOCM_RTS) ? " only" : "/RTS"); - cs->ops->set_modem_ctrl(cs, control_state, new_state); - control_state = new_state; - } - - cs->ops->baud_rate(cs, cflag & CBAUD); - - if ((cflag & CBAUD) == B0) { - /* Drop RTS and DTR */ - gig_dbg(DEBUG_IF, "%u: to B0 - drop DTR/RTS", cs->minor_index); - new_state = control_state & ~(TIOCM_DTR | TIOCM_RTS); - cs->ops->set_modem_ctrl(cs, control_state, new_state); - control_state = new_state; - } - - /* - * Update line control register (LCR) - */ - - cs->ops->set_line_ctrl(cs, cflag); - -#if 0 - //FIXME this hangs M101 [ts 2005-03-09] - //FIXME do we need this? - /* - * Set flow control: well, I do not really now how to handle DTR/RTS. - * Just do what we have seen with SniffUSB on Win98. - */ - /* Drop DTR/RTS if no flow control otherwise assert */ - gig_dbg(DEBUG_IF, "%u: control_state %x", - cs->minor_index, control_state); - new_state = control_state; - if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) - new_state |= TIOCM_DTR | TIOCM_RTS; - else - new_state &= ~(TIOCM_DTR | TIOCM_RTS); - if (new_state != control_state) { - gig_dbg(DEBUG_IF, "%u: new_state %x", - cs->minor_index, new_state); - gigaset_set_modem_ctrl(cs, control_state, new_state); - control_state = new_state; - } -#endif - - /* save off the modified port settings */ - cs->control_state = control_state; - -out: - mutex_unlock(&cs->mutex); -} - - -/* wakeup tasklet for the write operation */ -static void if_wake(unsigned long data) -{ - struct cardstate *cs = (struct cardstate *) data; - struct tty_struct *tty; - - tty = cs->tty; - if (!tty) - return; - - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) { - gig_dbg(DEBUG_IF, "write wakeup call"); - tty->ldisc.write_wakeup(tty); - } - - wake_up_interruptible(&tty->write_wait); -} - -/*** interface to common ***/ - -void gigaset_if_init(struct cardstate *cs) -{ - struct gigaset_driver *drv; - - drv = cs->driver; - if (!drv->have_tty) - return; - - tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); - tty_register_device(drv->tty, cs->minor_index, NULL); -} - -void gigaset_if_free(struct cardstate *cs) -{ - struct gigaset_driver *drv; - - drv = cs->driver; - if (!drv->have_tty) - return; - - tasklet_disable(&cs->if_wake_tasklet); - tasklet_kill(&cs->if_wake_tasklet); - tty_unregister_device(drv->tty, cs->minor_index); -} - -void gigaset_if_receive(struct cardstate *cs, - unsigned char *buffer, size_t len) -{ - unsigned long flags; - struct tty_struct *tty; - - spin_lock_irqsave(&cs->lock, flags); - if ((tty = cs->tty) == NULL) - gig_dbg(DEBUG_ANY, "receive on closed device"); - else { - tty_buffer_request_room(tty, len); - tty_insert_flip_string(tty, buffer, len); - tty_flip_buffer_push(tty); - } - spin_unlock_irqrestore(&cs->lock, flags); -} -EXPORT_SYMBOL_GPL(gigaset_if_receive); - -/* gigaset_if_initdriver - * Initialize tty interface. - * parameters: - * drv Driver - * procname Name of the driver (e.g. for /proc/tty/drivers) - * devname Name of the device files (prefix without minor number) - * devfsname Devfs name of the device files without %d - */ -void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, - const char *devname, const char *devfsname) -{ - unsigned minors = drv->minors; - int ret; - struct tty_driver *tty; - - drv->have_tty = 0; - - if ((drv->tty = alloc_tty_driver(minors)) == NULL) - goto enomem; - tty = drv->tty; - - tty->magic = TTY_DRIVER_MAGIC, - tty->major = GIG_MAJOR, - tty->type = TTY_DRIVER_TYPE_SERIAL, - tty->subtype = SERIAL_TYPE_NORMAL, - tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, - - tty->driver_name = procname; - tty->name = devname; - tty->minor_start = drv->minor; - tty->num = drv->minors; - - tty->owner = THIS_MODULE; - tty->devfs_name = devfsname; - - tty->init_termios = tty_std_termios; //FIXME - tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; //FIXME - tty_set_operations(tty, &if_ops); - - ret = tty_register_driver(tty); - if (ret < 0) { - warn("failed to register tty driver (error %d)", ret); - goto error; - } - gig_dbg(DEBUG_IF, "tty driver initialized"); - drv->have_tty = 1; - return; - -enomem: - warn("could not allocate tty structures"); -error: - if (drv->tty) - put_tty_driver(drv->tty); -} - -void gigaset_if_freedriver(struct gigaset_driver *drv) -{ - if (!drv->have_tty) - return; - - drv->have_tty = 0; - tty_unregister_driver(drv->tty); - put_tty_driver(drv->tty); -} diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c deleted file mode 100644 index 8667daaa1..000000000 --- a/drivers/isdn/gigaset/isocdata.c +++ /dev/null @@ -1,1010 +0,0 @@ -/* - * Common data handling layer for bas_gigaset - * - * Copyright (c) 2005 by Tilman Schmidt , - * Hansjoerg Lipp . - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" -#include - -/* access methods for isowbuf_t */ -/* ============================ */ - -/* initialize buffer structure - */ -void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle) -{ - atomic_set(&iwb->read, 0); - atomic_set(&iwb->nextread, 0); - atomic_set(&iwb->write, 0); - atomic_set(&iwb->writesem, 1); - iwb->wbits = 0; - iwb->idle = idle; - memset(iwb->data + BAS_OUTBUFSIZE, idle, BAS_OUTBUFPAD); -} - -/* compute number of bytes which can be appended to buffer - * so that there is still room to append a maximum frame of flags - */ -static inline int isowbuf_freebytes(struct isowbuf_t *iwb) -{ - int read, write, freebytes; - - read = atomic_read(&iwb->read); - write = atomic_read(&iwb->write); - if ((freebytes = read - write) > 0) { - /* no wraparound: need padding space within regular area */ - return freebytes - BAS_OUTBUFPAD; - } else if (read < BAS_OUTBUFPAD) { - /* wraparound: can use space up to end of regular area */ - return BAS_OUTBUFSIZE - write; - } else { - /* following the wraparound yields more space */ - return freebytes + BAS_OUTBUFSIZE - BAS_OUTBUFPAD; - } -} - -/* compare two offsets within the buffer - * The buffer is seen as circular, with the read position as start - * returns -1/0/1 if position a position b without crossing 'read' - */ -static inline int isowbuf_poscmp(struct isowbuf_t *iwb, int a, int b) -{ - int read; - if (a == b) - return 0; - read = atomic_read(&iwb->read); - if (a < b) { - if (a < read && read <= b) - return +1; - else - return -1; - } else { - if (b < read && read <= a) - return -1; - else - return +1; - } -} - -/* start writing - * acquire the write semaphore - * return true if acquired, false if busy - */ -static inline int isowbuf_startwrite(struct isowbuf_t *iwb) -{ - if (!atomic_dec_and_test(&iwb->writesem)) { - atomic_inc(&iwb->writesem); - gig_dbg(DEBUG_ISO, "%s: couldn't acquire iso write semaphore", - __func__); - return 0; - } -#ifdef CONFIG_GIGASET_DEBUG - gig_dbg(DEBUG_ISO, - "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d", - __func__, iwb->data[atomic_read(&iwb->write)], iwb->wbits); -#endif - return 1; -} - -/* finish writing - * release the write semaphore and update the maximum buffer fill level - * returns the current write position - */ -static inline int isowbuf_donewrite(struct isowbuf_t *iwb) -{ - int write = atomic_read(&iwb->write); - atomic_inc(&iwb->writesem); - return write; -} - -/* append bits to buffer without any checks - * - data contains bits to append, starting at LSB - * - nbits is number of bits to append (0..24) - * must be called with the write semaphore held - * If more than nbits bits are set in data, the extraneous bits are set in the - * buffer too, but the write position is only advanced by nbits. - */ -static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits) -{ - int write = atomic_read(&iwb->write); - data <<= iwb->wbits; - data |= iwb->data[write]; - nbits += iwb->wbits; - while (nbits >= 8) { - iwb->data[write++] = data & 0xff; - write %= BAS_OUTBUFSIZE; - data >>= 8; - nbits -= 8; - } - iwb->wbits = nbits; - iwb->data[write] = data & 0xff; - atomic_set(&iwb->write, write); -} - -/* put final flag on HDLC bitstream - * also sets the idle fill byte to the correspondingly shifted flag pattern - * must be called with the write semaphore held - */ -static inline void isowbuf_putflag(struct isowbuf_t *iwb) -{ - int write; - - /* add two flags, thus reliably covering one byte */ - isowbuf_putbits(iwb, 0x7e7e, 8); - /* recover the idle flag byte */ - write = atomic_read(&iwb->write); - iwb->idle = iwb->data[write]; - gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle); - /* mask extraneous bits in buffer */ - iwb->data[write] &= (1 << iwb->wbits) - 1; -} - -/* retrieve a block of bytes for sending - * The requested number of bytes is provided as a contiguous block. - * If necessary, the frame is filled to the requested number of bytes - * with the idle value. - * returns offset to frame, < 0 on busy or error - */ -int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) -{ - int read, write, limit, src, dst; - unsigned char pbyte; - - read = atomic_read(&iwb->nextread); - write = atomic_read(&iwb->write); - if (likely(read == write)) { - /* return idle frame */ - return read < BAS_OUTBUFPAD ? - BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD; - } - - limit = read + size; - gig_dbg(DEBUG_STREAM, "%s: read=%d write=%d limit=%d", - __func__, read, write, limit); -#ifdef CONFIG_GIGASET_DEBUG - if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) { - err("invalid size %d", size); - return -EINVAL; - } - src = atomic_read(&iwb->read); - if (unlikely(limit > BAS_OUTBUFSIZE + BAS_OUTBUFPAD || - (read < src && limit >= src))) { - err("isoc write buffer frame reservation violated"); - return -EFAULT; - } -#endif - - if (read < write) { - /* no wraparound in valid data */ - if (limit >= write) { - /* append idle frame */ - if (!isowbuf_startwrite(iwb)) - return -EBUSY; - /* write position could have changed */ - if (limit >= (write = atomic_read(&iwb->write))) { - pbyte = iwb->data[write]; /* save - partial byte */ - limit = write + BAS_OUTBUFPAD; - gig_dbg(DEBUG_STREAM, - "%s: filling %d->%d with %02x", - __func__, write, limit, iwb->idle); - if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE) - memset(iwb->data + write, iwb->idle, - BAS_OUTBUFPAD); - else { - /* wraparound, fill entire pad area */ - memset(iwb->data + write, iwb->idle, - BAS_OUTBUFSIZE + BAS_OUTBUFPAD - - write); - limit = 0; - } - gig_dbg(DEBUG_STREAM, - "%s: restoring %02x at %d", - __func__, pbyte, limit); - iwb->data[limit] = pbyte; /* restore - partial byte */ - atomic_set(&iwb->write, limit); - } - isowbuf_donewrite(iwb); - } - } else { - /* valid data wraparound */ - if (limit >= BAS_OUTBUFSIZE) { - /* copy wrapped part into pad area */ - src = 0; - dst = BAS_OUTBUFSIZE; - while (dst < limit && src < write) - iwb->data[dst++] = iwb->data[src++]; - if (dst <= limit) { - /* fill pad area with idle byte */ - memset(iwb->data + dst, iwb->idle, - BAS_OUTBUFSIZE + BAS_OUTBUFPAD - dst); - } - limit = src; - } - } - atomic_set(&iwb->nextread, limit); - return read; -} - -/* dump_bytes - * write hex bytes to syslog for debugging - */ -static inline void dump_bytes(enum debuglevel level, const char *tag, - unsigned char *bytes, int count) -{ -#ifdef CONFIG_GIGASET_DEBUG - unsigned char c; - static char dbgline[3 * 32 + 1]; - static const char hexdigit[] = "0123456789abcdef"; - int i = 0; - while (count-- > 0) { - if (i > sizeof(dbgline) - 4) { - dbgline[i] = '\0'; - gig_dbg(level, "%s:%s", tag, dbgline); - i = 0; - } - c = *bytes++; - dbgline[i] = (i && !(i % 12)) ? '-' : ' '; - i++; - dbgline[i++] = hexdigit[(c >> 4) & 0x0f]; - dbgline[i++] = hexdigit[c & 0x0f]; - } - dbgline[i] = '\0'; - gig_dbg(level, "%s:%s", tag, dbgline); -#endif -} - -/*============================================================================*/ - -/* bytewise HDLC bitstuffing via table lookup - * lookup table: 5 subtables for 0..4 preceding consecutive '1' bits - * index: 256*(number of preceding '1' bits) + (next byte to stuff) - * value: bit 9.. 0 = result bits - * bit 12..10 = number of trailing '1' bits in result - * bit 14..13 = number of bits added by stuffing - */ -static u16 stufftab[5 * 256] = { -// previous 1s = 0: - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x205f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x209f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20df, - 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f, - 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x251f, - 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af, - 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x255f, - 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf, - 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x299f, - 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef, - 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf, - -// previous 1s = 1: - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x206f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x208f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20af, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20cf, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20ef, - 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x250f, - 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x252f, - 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x254f, - 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x256f, - 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x298f, - 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29af, - 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf, - 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef, - -// previous 1s = 2: - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x2067, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x2077, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x2087, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x2097, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x20a7, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20b7, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x20c7, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20d7, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x20e7, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20f7, - 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x2507, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x2517, - 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x2527, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x2537, - 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x2547, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x2557, - 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x2567, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x2577, - 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x2987, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x2997, - 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x29a7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29b7, - 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7, - 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7, - -// previous 1s = 3: - 0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b, - 0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b, - 0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b, - 0x0030, 0x0031, 0x0032, 0x2063, 0x0034, 0x0035, 0x0036, 0x206b, 0x0038, 0x0039, 0x003a, 0x2073, 0x003c, 0x003d, 0x203e, 0x207b, - 0x0040, 0x0041, 0x0042, 0x2083, 0x0044, 0x0045, 0x0046, 0x208b, 0x0048, 0x0049, 0x004a, 0x2093, 0x004c, 0x004d, 0x004e, 0x209b, - 0x0050, 0x0051, 0x0052, 0x20a3, 0x0054, 0x0055, 0x0056, 0x20ab, 0x0058, 0x0059, 0x005a, 0x20b3, 0x005c, 0x005d, 0x005e, 0x20bb, - 0x0060, 0x0061, 0x0062, 0x20c3, 0x0064, 0x0065, 0x0066, 0x20cb, 0x0068, 0x0069, 0x006a, 0x20d3, 0x006c, 0x006d, 0x006e, 0x20db, - 0x0070, 0x0071, 0x0072, 0x20e3, 0x0074, 0x0075, 0x0076, 0x20eb, 0x0078, 0x0079, 0x007a, 0x20f3, 0x207c, 0x207d, 0x20be, 0x40fb, - 0x0480, 0x0481, 0x0482, 0x2503, 0x0484, 0x0485, 0x0486, 0x250b, 0x0488, 0x0489, 0x048a, 0x2513, 0x048c, 0x048d, 0x048e, 0x251b, - 0x0490, 0x0491, 0x0492, 0x2523, 0x0494, 0x0495, 0x0496, 0x252b, 0x0498, 0x0499, 0x049a, 0x2533, 0x049c, 0x049d, 0x049e, 0x253b, - 0x04a0, 0x04a1, 0x04a2, 0x2543, 0x04a4, 0x04a5, 0x04a6, 0x254b, 0x04a8, 0x04a9, 0x04aa, 0x2553, 0x04ac, 0x04ad, 0x04ae, 0x255b, - 0x04b0, 0x04b1, 0x04b2, 0x2563, 0x04b4, 0x04b5, 0x04b6, 0x256b, 0x04b8, 0x04b9, 0x04ba, 0x2573, 0x04bc, 0x04bd, 0x253e, 0x257b, - 0x08c0, 0x08c1, 0x08c2, 0x2983, 0x08c4, 0x08c5, 0x08c6, 0x298b, 0x08c8, 0x08c9, 0x08ca, 0x2993, 0x08cc, 0x08cd, 0x08ce, 0x299b, - 0x08d0, 0x08d1, 0x08d2, 0x29a3, 0x08d4, 0x08d5, 0x08d6, 0x29ab, 0x08d8, 0x08d9, 0x08da, 0x29b3, 0x08dc, 0x08dd, 0x08de, 0x29bb, - 0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb, - 0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb, - -// previous 1s = 4: - 0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d, - 0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d, - 0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d, - 0x0030, 0x2061, 0x0032, 0x2065, 0x0034, 0x2069, 0x0036, 0x206d, 0x0038, 0x2071, 0x003a, 0x2075, 0x003c, 0x2079, 0x203e, 0x407d, - 0x0040, 0x2081, 0x0042, 0x2085, 0x0044, 0x2089, 0x0046, 0x208d, 0x0048, 0x2091, 0x004a, 0x2095, 0x004c, 0x2099, 0x004e, 0x209d, - 0x0050, 0x20a1, 0x0052, 0x20a5, 0x0054, 0x20a9, 0x0056, 0x20ad, 0x0058, 0x20b1, 0x005a, 0x20b5, 0x005c, 0x20b9, 0x005e, 0x20bd, - 0x0060, 0x20c1, 0x0062, 0x20c5, 0x0064, 0x20c9, 0x0066, 0x20cd, 0x0068, 0x20d1, 0x006a, 0x20d5, 0x006c, 0x20d9, 0x006e, 0x20dd, - 0x0070, 0x20e1, 0x0072, 0x20e5, 0x0074, 0x20e9, 0x0076, 0x20ed, 0x0078, 0x20f1, 0x007a, 0x20f5, 0x207c, 0x40f9, 0x20be, 0x417d, - 0x0480, 0x2501, 0x0482, 0x2505, 0x0484, 0x2509, 0x0486, 0x250d, 0x0488, 0x2511, 0x048a, 0x2515, 0x048c, 0x2519, 0x048e, 0x251d, - 0x0490, 0x2521, 0x0492, 0x2525, 0x0494, 0x2529, 0x0496, 0x252d, 0x0498, 0x2531, 0x049a, 0x2535, 0x049c, 0x2539, 0x049e, 0x253d, - 0x04a0, 0x2541, 0x04a2, 0x2545, 0x04a4, 0x2549, 0x04a6, 0x254d, 0x04a8, 0x2551, 0x04aa, 0x2555, 0x04ac, 0x2559, 0x04ae, 0x255d, - 0x04b0, 0x2561, 0x04b2, 0x2565, 0x04b4, 0x2569, 0x04b6, 0x256d, 0x04b8, 0x2571, 0x04ba, 0x2575, 0x04bc, 0x2579, 0x253e, 0x467d, - 0x08c0, 0x2981, 0x08c2, 0x2985, 0x08c4, 0x2989, 0x08c6, 0x298d, 0x08c8, 0x2991, 0x08ca, 0x2995, 0x08cc, 0x2999, 0x08ce, 0x299d, - 0x08d0, 0x29a1, 0x08d2, 0x29a5, 0x08d4, 0x29a9, 0x08d6, 0x29ad, 0x08d8, 0x29b1, 0x08da, 0x29b5, 0x08dc, 0x29b9, 0x08de, 0x29bd, - 0x0ce0, 0x2dc1, 0x0ce2, 0x2dc5, 0x0ce4, 0x2dc9, 0x0ce6, 0x2dcd, 0x0ce8, 0x2dd1, 0x0cea, 0x2dd5, 0x0cec, 0x2dd9, 0x0cee, 0x2ddd, - 0x10f0, 0x31e1, 0x10f2, 0x31e5, 0x10f4, 0x31e9, 0x10f6, 0x31ed, 0x20f8, 0x41f1, 0x20fa, 0x41f5, 0x257c, 0x46f9, 0x29be, 0x4b7d -}; - -/* hdlc_bitstuff_byte - * perform HDLC bitstuffing for one input byte (8 bits, LSB first) - * parameters: - * cin input byte - * ones number of trailing '1' bits in result before this step - * iwb pointer to output buffer structure (write semaphore must be held) - * return value: - * number of trailing '1' bits in result after this step - */ - -static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin, - int ones) -{ - u16 stuff; - int shiftinc, newones; - - /* get stuffing information for input byte - * value: bit 9.. 0 = result bits - * bit 12..10 = number of trailing '1' bits in result - * bit 14..13 = number of bits added by stuffing - */ - stuff = stufftab[256 * ones + cin]; - shiftinc = (stuff >> 13) & 3; - newones = (stuff >> 10) & 7; - stuff &= 0x3ff; - - /* append stuffed byte to output stream */ - isowbuf_putbits(iwb, stuff, 8 + shiftinc); - return newones; -} - -/* hdlc_buildframe - * Perform HDLC framing with bitstuffing on a byte buffer - * The input buffer is regarded as a sequence of bits, starting with the least - * significant bit of the first byte and ending with the most significant bit - * of the last byte. A 16 bit FCS is appended as defined by RFC 1662. - * Whenever five consecutive '1' bits appear in the resulting bit sequence, a - * '0' bit is inserted after them. - * The resulting bit string and a closing flag pattern (PPP_FLAG, '01111110') - * are appended to the output buffer starting at the given bit position, which - * is assumed to already contain a leading flag. - * The output buffer must have sufficient length; count + count/5 + 6 bytes - * starting at *out are safe and are verified to be present. - * parameters: - * in input buffer - * count number of bytes in input buffer - * iwb pointer to output buffer structure (write semaphore must be held) - * return value: - * position of end of packet in output buffer on success, - * -EAGAIN if write semaphore busy or buffer full - */ - -static inline int hdlc_buildframe(struct isowbuf_t *iwb, - unsigned char *in, int count) -{ - int ones; - u16 fcs; - int end; - unsigned char c; - - if (isowbuf_freebytes(iwb) < count + count / 5 + 6 || - !isowbuf_startwrite(iwb)) { - gig_dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN", - __func__, isowbuf_freebytes(iwb)); - return -EAGAIN; - } - - dump_bytes(DEBUG_STREAM, "snd data", in, count); - - /* bitstuff and checksum input data */ - fcs = PPP_INITFCS; - ones = 0; - while (count-- > 0) { - c = *in++; - ones = hdlc_bitstuff_byte(iwb, c, ones); - fcs = crc_ccitt_byte(fcs, c); - } - - /* bitstuff and append FCS (complemented, least significant byte first) */ - fcs ^= 0xffff; - ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones); - ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones); - - /* put closing flag and repeat byte for flag idle */ - isowbuf_putflag(iwb); - end = isowbuf_donewrite(iwb); - dump_bytes(DEBUG_STREAM_DUMP, "isowbuf", iwb->data, end + 1); - return end; -} - -/* trans_buildframe - * Append a block of 'transparent' data to the output buffer, - * inverting the bytes. - * The output buffer must have sufficient length; count bytes - * starting at *out are safe and are verified to be present. - * parameters: - * in input buffer - * count number of bytes in input buffer - * iwb pointer to output buffer structure (write semaphore must be held) - * return value: - * position of end of packet in output buffer on success, - * -EAGAIN if write semaphore busy or buffer full - */ - -static inline int trans_buildframe(struct isowbuf_t *iwb, - unsigned char *in, int count) -{ - int write; - unsigned char c; - - if (unlikely(count <= 0)) - return atomic_read(&iwb->write); /* better ideas? */ - - if (isowbuf_freebytes(iwb) < count || - !isowbuf_startwrite(iwb)) { - gig_dbg(DEBUG_ISO, "can't put %d bytes", count); - return -EAGAIN; - } - - gig_dbg(DEBUG_STREAM, "put %d bytes", count); - write = atomic_read(&iwb->write); - do { - c = gigaset_invtab[*in++]; - iwb->data[write++] = c; - write %= BAS_OUTBUFSIZE; - } while (--count > 0); - atomic_set(&iwb->write, write); - iwb->idle = c; - - return isowbuf_donewrite(iwb); -} - -int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len) -{ - int result; - - switch (bcs->proto2) { - case ISDN_PROTO_L2_HDLC: - result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len); - gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d", - __func__, len, result); - break; - default: /* assume transparent */ - result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len); - gig_dbg(DEBUG_ISO, "%s: %d bytes trans -> %d", - __func__, len, result); - } - return result; -} - -/* hdlc_putbyte - * append byte c to current skb of B channel structure *bcs, updating fcs - */ -static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs) -{ - bcs->fcs = crc_ccitt_byte(bcs->fcs, c); - if (unlikely(bcs->skb == NULL)) { - /* skipping */ - return; - } - if (unlikely(bcs->skb->len == SBUFSIZE)) { - dev_warn(bcs->cs->dev, "received oversized packet discarded\n"); - bcs->hw.bas->giants++; - dev_kfree_skb_any(bcs->skb); - bcs->skb = NULL; - return; - } - *__skb_put(bcs->skb, 1) = c; -} - -/* hdlc_flush - * drop partial HDLC data packet - */ -static inline void hdlc_flush(struct bc_state *bcs) -{ - /* clear skb or allocate new if not skipping */ - if (likely(bcs->skb != NULL)) - skb_trim(bcs->skb, 0); - else if (!bcs->ignore) { - if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) - skb_reserve(bcs->skb, HW_HDR_LEN); - else - dev_err(bcs->cs->dev, "could not allocate skb\n"); - } - - /* reset packet state */ - bcs->fcs = PPP_INITFCS; -} - -/* hdlc_done - * process completed HDLC data packet - */ -static inline void hdlc_done(struct bc_state *bcs) -{ - struct sk_buff *procskb; - - if (unlikely(bcs->ignore)) { - bcs->ignore--; - hdlc_flush(bcs); - return; - } - - if ((procskb = bcs->skb) == NULL) { - /* previous error */ - gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__); - gigaset_rcv_error(NULL, bcs->cs, bcs); - } else if (procskb->len < 2) { - dev_notice(bcs->cs->dev, "received short frame (%d octets)\n", - procskb->len); - bcs->hw.bas->runts++; - gigaset_rcv_error(procskb, bcs->cs, bcs); - } else if (bcs->fcs != PPP_GOODFCS) { - dev_notice(bcs->cs->dev, "frame check error (0x%04x)\n", - bcs->fcs); - bcs->hw.bas->fcserrs++; - gigaset_rcv_error(procskb, bcs->cs, bcs); - } else { - procskb->len -= 2; /* subtract FCS */ - procskb->tail -= 2; - gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", - __func__, procskb->len); - dump_bytes(DEBUG_STREAM, - "rcv data", procskb->data, procskb->len); - bcs->hw.bas->goodbytes += procskb->len; - gigaset_rcv_skb(procskb, bcs->cs, bcs); - } - - if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) - skb_reserve(bcs->skb, HW_HDR_LEN); - else - dev_err(bcs->cs->dev, "could not allocate skb\n"); - bcs->fcs = PPP_INITFCS; -} - -/* hdlc_frag - * drop HDLC data packet with non-integral last byte - */ -static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits) -{ - if (unlikely(bcs->ignore)) { - bcs->ignore--; - hdlc_flush(bcs); - return; - } - - dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits); - bcs->hw.bas->alignerrs++; - gigaset_rcv_error(bcs->skb, bcs->cs, bcs); - - if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) - skb_reserve(bcs->skb, HW_HDR_LEN); - else - dev_err(bcs->cs->dev, "could not allocate skb\n"); - bcs->fcs = PPP_INITFCS; -} - -/* bit counts lookup table for HDLC bit unstuffing - * index: input byte - * value: bit 0..3 = number of consecutive '1' bits starting from LSB - * bit 4..6 = number of consecutive '1' bits starting from MSB - * (replacing 8 by 7 to make it fit; the algorithm won't care) - * bit 7 set if there are 5 or more "interior" consecutive '1' bits - */ -static unsigned char bitcounts[256] = { - 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x80, 0x06, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x81, 0x80, 0x07, - 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14, - 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x15, - 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14, - 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x90, 0x16, - 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x24, - 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x25, - 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x34, - 0x40, 0x41, 0x40, 0x42, 0x40, 0x41, 0x40, 0x43, 0x50, 0x51, 0x50, 0x52, 0x60, 0x61, 0x70, 0x78 -}; - -/* hdlc_unpack - * perform HDLC frame processing (bit unstuffing, flag detection, FCS calculation) - * on a sequence of received data bytes (8 bits each, LSB first) - * pass on successfully received, complete frames as SKBs via gigaset_rcv_skb - * notify of errors via gigaset_rcv_error - * tally frames, errors etc. in BC structure counters - * parameters: - * src received data - * count number of received bytes - * bcs receiving B channel structure - */ -static inline void hdlc_unpack(unsigned char *src, unsigned count, - struct bc_state *bcs) -{ - struct bas_bc_state *ubc = bcs->hw.bas; - int inputstate; - unsigned seqlen, inbyte, inbits; - - /* load previous state: - * inputstate = set of flag bits: - * - INS_flag_hunt: no complete opening flag received since connection setup or last abort - * - INS_have_data: at least one complete data byte received since last flag - * seqlen = number of consecutive '1' bits in last 7 input stream bits (0..7) - * inbyte = accumulated partial data byte (if !INS_flag_hunt) - * inbits = number of valid bits in inbyte, starting at LSB (0..6) - */ - inputstate = bcs->inputstate; - seqlen = ubc->seqlen; - inbyte = ubc->inbyte; - inbits = ubc->inbits; - - /* bit unstuffing a byte a time - * Take your time to understand this; it's straightforward but tedious. - * The "bitcounts" lookup table is used to speed up the counting of - * leading and trailing '1' bits. - */ - while (count--) { - unsigned char c = *src++; - unsigned char tabentry = bitcounts[c]; - unsigned lead1 = tabentry & 0x0f; - unsigned trail1 = (tabentry >> 4) & 0x0f; - - seqlen += lead1; - - if (unlikely(inputstate & INS_flag_hunt)) { - if (c == PPP_FLAG) { - /* flag-in-one */ - inputstate &= ~(INS_flag_hunt | INS_have_data); - inbyte = 0; - inbits = 0; - } else if (seqlen == 6 && trail1 != 7) { - /* flag completed & not followed by abort */ - inputstate &= ~(INS_flag_hunt | INS_have_data); - inbyte = c >> (lead1 + 1); - inbits = 7 - lead1; - if (trail1 >= 8) { - /* interior stuffing: omitting the MSB handles most cases */ - inbits--; - /* correct the incorrectly handled cases individually */ - switch (c) { - case 0xbe: - inbyte = 0x3f; - break; - } - } - } - /* else: continue flag-hunting */ - } else if (likely(seqlen < 5 && trail1 < 7)) { - /* streamlined case: 8 data bits, no stuffing */ - inbyte |= c << inbits; - hdlc_putbyte(inbyte & 0xff, bcs); - inputstate |= INS_have_data; - inbyte >>= 8; - /* inbits unchanged */ - } else if (likely(seqlen == 6 && inbits == 7 - lead1 && - trail1 + 1 == inbits && - !(inputstate & INS_have_data))) { - /* streamlined case: flag idle - state unchanged */ - } else if (unlikely(seqlen > 6)) { - /* abort sequence */ - ubc->aborts++; - hdlc_flush(bcs); - inputstate |= INS_flag_hunt; - } else if (seqlen == 6) { - /* closing flag, including (6 - lead1) '1's and one '0' from inbits */ - if (inbits > 7 - lead1) { - hdlc_frag(bcs, inbits + lead1 - 7); - inputstate &= ~INS_have_data; - } else { - if (inbits < 7 - lead1) - ubc->stolen0s ++; - if (inputstate & INS_have_data) { - hdlc_done(bcs); - inputstate &= ~INS_have_data; - } - } - - if (c == PPP_FLAG) { - /* complete flag, LSB overlaps preceding flag */ - ubc->shared0s ++; - inbits = 0; - inbyte = 0; - } else if (trail1 != 7) { - /* remaining bits */ - inbyte = c >> (lead1 + 1); - inbits = 7 - lead1; - if (trail1 >= 8) { - /* interior stuffing: omitting the MSB handles most cases */ - inbits--; - /* correct the incorrectly handled cases individually */ - switch (c) { - case 0xbe: - inbyte = 0x3f; - break; - } - } - } else { - /* abort sequence follows, skb already empty anyway */ - ubc->aborts++; - inputstate |= INS_flag_hunt; - } - } else { /* (seqlen < 6) && (seqlen == 5 || trail1 >= 7) */ - - if (c == PPP_FLAG) { - /* complete flag */ - if (seqlen == 5) - ubc->stolen0s++; - if (inbits) { - hdlc_frag(bcs, inbits); - inbits = 0; - inbyte = 0; - } else if (inputstate & INS_have_data) - hdlc_done(bcs); - inputstate &= ~INS_have_data; - } else if (trail1 == 7) { - /* abort sequence */ - ubc->aborts++; - hdlc_flush(bcs); - inputstate |= INS_flag_hunt; - } else { - /* stuffed data */ - if (trail1 < 7) { /* => seqlen == 5 */ - /* stuff bit at position lead1, no interior stuffing */ - unsigned char mask = (1 << lead1) - 1; - c = (c & mask) | ((c & ~mask) >> 1); - inbyte |= c << inbits; - inbits += 7; - } else if (seqlen < 5) { /* trail1 >= 8 */ - /* interior stuffing: omitting the MSB handles most cases */ - /* correct the incorrectly handled cases individually */ - switch (c) { - case 0xbe: - c = 0x7e; - break; - } - inbyte |= c << inbits; - inbits += 7; - } else { /* seqlen == 5 && trail1 >= 8 */ - - /* stuff bit at lead1 *and* interior stuffing */ - switch (c) { /* unstuff individually */ - case 0x7d: - c = 0x3f; - break; - case 0xbe: - c = 0x3f; - break; - case 0x3e: - c = 0x1f; - break; - case 0x7c: - c = 0x3e; - break; - } - inbyte |= c << inbits; - inbits += 6; - } - if (inbits >= 8) { - inbits -= 8; - hdlc_putbyte(inbyte & 0xff, bcs); - inputstate |= INS_have_data; - inbyte >>= 8; - } - } - } - seqlen = trail1 & 7; - } - - /* save new state */ - bcs->inputstate = inputstate; - ubc->seqlen = seqlen; - ubc->inbyte = inbyte; - ubc->inbits = inbits; -} - -/* trans_receive - * pass on received USB frame transparently as SKB via gigaset_rcv_skb - * invert bytes - * tally frames, errors etc. in BC structure counters - * parameters: - * src received data - * count number of received bytes - * bcs receiving B channel structure - */ -static inline void trans_receive(unsigned char *src, unsigned count, - struct bc_state *bcs) -{ - struct sk_buff *skb; - int dobytes; - unsigned char *dst; - - if (unlikely(bcs->ignore)) { - bcs->ignore--; - hdlc_flush(bcs); - return; - } - if (unlikely((skb = bcs->skb) == NULL)) { - bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); - if (!skb) { - dev_err(bcs->cs->dev, "could not allocate skb\n"); - return; - } - skb_reserve(skb, HW_HDR_LEN); - } - bcs->hw.bas->goodbytes += skb->len; - dobytes = TRANSBUFSIZE - skb->len; - while (count > 0) { - dst = skb_put(skb, count < dobytes ? count : dobytes); - while (count > 0 && dobytes > 0) { - *dst++ = gigaset_invtab[*src++]; - count--; - dobytes--; - } - if (dobytes == 0) { - gigaset_rcv_skb(skb, bcs->cs, bcs); - bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); - if (!skb) { - dev_err(bcs->cs->dev, - "could not allocate skb\n"); - return; - } - skb_reserve(bcs->skb, HW_HDR_LEN); - dobytes = TRANSBUFSIZE; - } - } -} - -void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *bcs) -{ - switch (bcs->proto2) { - case ISDN_PROTO_L2_HDLC: - hdlc_unpack(src, count, bcs); - break; - default: /* assume transparent */ - trans_receive(src, count, bcs); - } -} - -/* == data input =========================================================== */ - -static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf) -{ - struct cardstate *cs = inbuf->cs; - unsigned cbytes = cs->cbytes; - - while (numbytes--) { - /* copy next character, check for end of line */ - switch (cs->respdata[cbytes] = *src++) { - case '\r': - case '\n': - /* end of line */ - gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", - __func__, cbytes); - cs->cbytes = cbytes; - gigaset_handle_modem_response(cs); - cbytes = 0; - break; - default: - /* advance in line buffer, checking for overflow */ - if (cbytes < MAX_RESP_SIZE - 1) - cbytes++; - else - dev_warn(cs->dev, "response too large\n"); - } - } - - /* save state */ - cs->cbytes = cbytes; -} - - -/* process a block of data received through the control channel - */ -void gigaset_isoc_input(struct inbuf_t *inbuf) -{ - struct cardstate *cs = inbuf->cs; - unsigned tail, head, numbytes; - unsigned char *src; - - head = atomic_read(&inbuf->head); - while (head != (tail = atomic_read(&inbuf->tail))) { - gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); - if (head > tail) - tail = RBUFSIZE; - src = inbuf->data + head; - numbytes = tail - head; - gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); - - if (atomic_read(&cs->mstate) == MS_LOCKED) { - gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", - numbytes, src); - gigaset_if_receive(inbuf->cs, src, numbytes); - } else { - gigaset_dbg_buffer(DEBUG_CMD, "received response", - numbytes, src); - cmd_loop(src, numbytes, inbuf); - } - - head += numbytes; - if (head == RBUFSIZE) - head = 0; - gig_dbg(DEBUG_INTR, "setting head to %u", head); - atomic_set(&inbuf->head, head); - } -} - - -/* == data output ========================================================== */ - -/* gigaset_send_skb - * called by common.c to queue an skb for sending - * and start transmission if necessary - * parameters: - * B Channel control structure - * skb - * return value: - * number of bytes accepted for sending - * (skb->len if ok, 0 if out of buffer space) - * or error code (< 0, eg. -EINVAL) - */ -int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb) -{ - int len = skb->len; - unsigned long flags; - - spin_lock_irqsave(&bcs->cs->lock, flags); - if (!bcs->cs->connected) { - spin_unlock_irqrestore(&bcs->cs->lock, flags); - return -ENODEV; - } - - skb_queue_tail(&bcs->squeue, skb); - gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d", - __func__, skb_queue_len(&bcs->squeue)); - - /* tasklet submits URB if necessary */ - tasklet_schedule(&bcs->hw.bas->sent_tasklet); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - - return len; /* ok so far */ -} diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c deleted file mode 100644 index d267a636b..000000000 --- a/drivers/isdn/gigaset/proc.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Stuff used by all variants of the driver - * - * Copyright (c) 2001 by Stefan Eilers, - * Hansjoerg Lipp , - * Tilman Schmidt . - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" -#include - -static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, - char *buf) -{ - int ret; - unsigned long flags; - struct cardstate *cs = dev_get_drvdata(dev); - - spin_lock_irqsave(&cs->lock, flags); - ret = sprintf(buf, "%u\n", cs->cidmode); - spin_unlock_irqrestore(&cs->lock, flags); - - return ret; -} - -static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cardstate *cs = dev_get_drvdata(dev); - long int value; - char *end; - - value = simple_strtol(buf, &end, 0); - while (*end) - if (!isspace(*end++)) - return -EINVAL; - if (value < 0 || value > 1) - return -EINVAL; - - if (mutex_lock_interruptible(&cs->mutex)) - return -ERESTARTSYS; // FIXME -EINTR? - - cs->waiting = 1; - if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE, - NULL, value, NULL)) { - cs->waiting = 0; - mutex_unlock(&cs->mutex); - return -ENOMEM; - } - - gig_dbg(DEBUG_CMD, "scheduling PROC_CIDMODE"); - gigaset_schedule_event(cs); - - wait_event(cs->waitqueue, !cs->waiting); - - mutex_unlock(&cs->mutex); - - return count; -} - -static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); - -/* free sysfs for device */ -void gigaset_free_dev_sysfs(struct cardstate *cs) -{ - gig_dbg(DEBUG_INIT, "removing sysfs entries"); - device_remove_file(cs->dev, &dev_attr_cidmode); -} - -/* initialize sysfs for device */ -void gigaset_init_dev_sysfs(struct cardstate *cs) -{ - gig_dbg(DEBUG_INIT, "setting up sysfs"); - device_create_file(cs->dev, &dev_attr_cidmode); -} diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c deleted file mode 100644 index d86ab6811..000000000 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ /dev/null @@ -1,961 +0,0 @@ -/* - * USB driver for Gigaset 307x directly or using M105 Data. - * - * Copyright (c) 2001 by Stefan Eilers - * and Hansjoerg Lipp . - * - * This driver was derived from the USB skeleton driver by - * Greg Kroah-Hartman - * - * ===================================================================== - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 "gigaset.h" - -#include -#include -#include -#include -#include -#include - -/* Version Information */ -#define DRIVER_AUTHOR "Hansjoerg Lipp , Stefan Eilers" -#define DRIVER_DESC "USB Driver for Gigaset 307x using M105" - -/* Module parameters */ - -static int startmode = SM_ISDN; -static int cidmode = 1; - -module_param(startmode, int, S_IRUGO); -module_param(cidmode, int, S_IRUGO); -MODULE_PARM_DESC(startmode, "start in isdn4linux mode"); -MODULE_PARM_DESC(cidmode, "Call-ID mode"); - -#define GIGASET_MINORS 1 -#define GIGASET_MINOR 8 -#define GIGASET_MODULENAME "usb_gigaset" -#define GIGASET_DEVFSNAME "gig/usb/" -#define GIGASET_DEVNAME "ttyGU" - -#define IF_WRITEBUF 2000 //FIXME // WAKEUP_CHARS: 256 - -/* Values for the Gigaset M105 Data */ -#define USB_M105_VENDOR_ID 0x0681 -#define USB_M105_PRODUCT_ID 0x0009 - -/* table of devices that work with this driver */ -static struct usb_device_id gigaset_table [] = { - { USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, gigaset_table); - -/* - * Control requests (empty fields: 00) - * - * RT|RQ|VALUE|INDEX|LEN |DATA - * In: - * C1 08 01 - * Get flags (1 byte). Bits: 0=dtr,1=rts,3-7:? - * C1 0F ll ll - * Get device information/status (llll: 0x200 and 0x40 seen). - * Real size: I only saw MIN(llll,0x64). - * Contents: seems to be always the same... - * offset 0x00: Length of this structure (0x64) (len: 1,2,3 bytes) - * offset 0x3c: String (16 bit chars): "MCCI USB Serial V2.0" - * rest: ? - * Out: - * 41 11 - * Initialize/reset device ? - * 41 00 xx 00 - * ? (xx=00 or 01; 01 on start, 00 on close) - * 41 07 vv mm - * Set/clear flags vv=value, mm=mask (see RQ 08) - * 41 12 xx - * Used before the following configuration requests are issued - * (with xx=0x0f). I've seen other values<0xf, though. - * 41 01 xx xx - * Set baud rate. xxxx=ceil(0x384000/rate)=trunc(0x383fff/rate)+1. - * 41 03 ps bb - * Set byte size and parity. p: 0x20=even,0x10=odd,0x00=no parity - * [ 0x30: m, 0x40: s ] - * [s: 0: 1 stop bit; 1: 1.5; 2: 2] - * bb: bits/byte (seen 7 and 8) - * 41 13 -- -- -- -- 10 00 ww 00 00 00 xx 00 00 00 yy 00 00 00 zz 00 00 00 - * ?? - * Initialization: 01, 40, 00, 00 - * Open device: 00 40, 00, 00 - * yy and zz seem to be equal, either 0x00 or 0x0a - * (ww,xx) pairs seen: (00,00), (00,40), (01,40), (09,80), (19,80) - * 41 19 -- -- -- -- 06 00 00 00 00 xx 11 13 - * Used after every "configuration sequence" (RQ 12, RQs 01/03/13). - * xx is usually 0x00 but was 0x7e before starting data transfer - * in unimodem mode. So, this might be an array of characters that need - * special treatment ("commit all bufferd data"?), 11=^Q, 13=^S. - * - * Unimodem mode: use "modprobe ppp_async flag_time=0" as the device _needs_ two - * flags per packet. - */ - -static int gigaset_probe(struct usb_interface *interface, - const struct usb_device_id *id); -static void gigaset_disconnect(struct usb_interface *interface); - -static struct gigaset_driver *driver = NULL; -static struct cardstate *cardstate = NULL; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver gigaset_usb_driver = { - .name = GIGASET_MODULENAME, - .probe = gigaset_probe, - .disconnect = gigaset_disconnect, - .id_table = gigaset_table, -}; - -struct usb_cardstate { - struct usb_device *udev; /* usb device pointer */ - struct usb_interface *interface; /* interface for this device */ - atomic_t busy; /* bulk output in progress */ - - /* Output buffer */ - unsigned char *bulk_out_buffer; - int bulk_out_size; - __u8 bulk_out_endpointAddr; - struct urb *bulk_out_urb; - - /* Input buffer */ - int rcvbuf_size; - struct urb *read_urb; - __u8 int_in_endpointAddr; - - char bchars[6]; /* for request 0x19 */ -}; - -struct usb_bc_state {}; - -static inline unsigned tiocm_to_gigaset(unsigned state) -{ - return ((state & TIOCM_DTR) ? 1 : 0) | ((state & TIOCM_RTS) ? 2 : 0); -} - -#ifdef CONFIG_GIGASET_UNDOCREQ -/* WARNING: EXPERIMENTAL! */ -static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, - unsigned new_state) -{ - struct usb_device *udev = cs->hw.usb->udev; - unsigned mask, val; - int r; - - mask = tiocm_to_gigaset(old_state ^ new_state); - val = tiocm_to_gigaset(new_state); - - gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask); - // don't use this in an interrupt/BH - r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41, - (val & 0xff) | ((mask & 0xff) << 8), 0, - NULL, 0, 2000 /* timeout? */); - if (r < 0) - return r; - //.. - return 0; -} - -static int set_value(struct cardstate *cs, u8 req, u16 val) -{ - struct usb_device *udev = cs->hw.usb->udev; - int r, r2; - - gig_dbg(DEBUG_USBREQ, "request %02x (%04x)", - (unsigned)req, (unsigned)val); - r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x12, 0x41, - 0xf /*?*/, 0, NULL, 0, 2000 /*?*/); - /* no idea what this does */ - if (r < 0) { - dev_err(&udev->dev, "error %d on request 0x12\n", -r); - return r; - } - - r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), req, 0x41, - val, 0, NULL, 0, 2000 /*?*/); - if (r < 0) - dev_err(&udev->dev, "error %d on request 0x%02x\n", - -r, (unsigned)req); - - r2 = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, - 0, 0, cs->hw.usb->bchars, 6, 2000 /*?*/); - if (r2 < 0) - dev_err(&udev->dev, "error %d on request 0x19\n", -r2); - - return r < 0 ? r : (r2 < 0 ? r2 : 0); -} - -/* WARNING: HIGHLY EXPERIMENTAL! */ -// don't use this in an interrupt/BH -static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) -{ - u16 val; - u32 rate; - - cflag &= CBAUD; - - switch (cflag) { - //FIXME more values? - case B300: rate = 300; break; - case B600: rate = 600; break; - case B1200: rate = 1200; break; - case B2400: rate = 2400; break; - case B4800: rate = 4800; break; - case B9600: rate = 9600; break; - case B19200: rate = 19200; break; - case B38400: rate = 38400; break; - case B57600: rate = 57600; break; - case B115200: rate = 115200; break; - default: - rate = 9600; - dev_err(cs->dev, "unsupported baudrate request 0x%x," - " using default of B9600\n", cflag); - } - - val = 0x383fff / rate + 1; - - return set_value(cs, 1, val); -} - -/* WARNING: HIGHLY EXPERIMENTAL! */ -// don't use this in an interrupt/BH -static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) -{ - u16 val = 0; - - /* set the parity */ - if (cflag & PARENB) - val |= (cflag & PARODD) ? 0x10 : 0x20; - - /* set the number of data bits */ - switch (cflag & CSIZE) { - case CS5: - val |= 5 << 8; break; - case CS6: - val |= 6 << 8; break; - case CS7: - val |= 7 << 8; break; - case CS8: - val |= 8 << 8; break; - default: - dev_err(cs->dev, "CSIZE was not CS5-CS8, using default of 8\n"); - val |= 8 << 8; - break; - } - - /* set the number of stop bits */ - if (cflag & CSTOPB) { - if ((cflag & CSIZE) == CS5) - val |= 1; /* 1.5 stop bits */ //FIXME is this okay? - else - val |= 2; /* 2 stop bits */ - } - - return set_value(cs, 3, val); -} - -#else -static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, - unsigned new_state) -{ - return -EINVAL; -} - -static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) -{ - return -EINVAL; -} - -static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) -{ - return -EINVAL; -} -#endif - - - /*================================================================================================================*/ -static int gigaset_init_bchannel(struct bc_state *bcs) -{ - /* nothing to do for M10x */ - gigaset_bchannel_up(bcs); - return 0; -} - -static int gigaset_close_bchannel(struct bc_state *bcs) -{ - /* nothing to do for M10x */ - gigaset_bchannel_down(bcs); - return 0; -} - -static int write_modem(struct cardstate *cs); -static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb); - - -/* Write tasklet handler: Continue sending current skb, or send command, or - * start sending an skb from the send queue. - */ -static void gigaset_modem_fill(unsigned long data) -{ - struct cardstate *cs = (struct cardstate *) data; - struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ - struct cmdbuf_t *cb; - unsigned long flags; - int again; - - gig_dbg(DEBUG_OUTPUT, "modem_fill"); - - if (atomic_read(&cs->hw.usb->busy)) { - gig_dbg(DEBUG_OUTPUT, "modem_fill: busy"); - return; - } - - do { - again = 0; - if (!bcs->tx_skb) { /* no skb is being sent */ - spin_lock_irqsave(&cs->cmdlock, flags); - cb = cs->cmdbuf; - spin_unlock_irqrestore(&cs->cmdlock, flags); - if (cb) { /* commands to send? */ - gig_dbg(DEBUG_OUTPUT, "modem_fill: cb"); - if (send_cb(cs, cb) < 0) { - gig_dbg(DEBUG_OUTPUT, - "modem_fill: send_cb failed"); - again = 1; /* no callback will be - called! */ - } - } else { /* skbs to send? */ - bcs->tx_skb = skb_dequeue(&bcs->squeue); - if (bcs->tx_skb) - gig_dbg(DEBUG_INTR, - "Dequeued skb (Adr: %lx)!", - (unsigned long) bcs->tx_skb); - } - } - - if (bcs->tx_skb) { - gig_dbg(DEBUG_OUTPUT, "modem_fill: tx_skb"); - if (write_modem(cs) < 0) { - gig_dbg(DEBUG_OUTPUT, - "modem_fill: write_modem failed"); - // FIXME should we tell the LL? - again = 1; /* no callback will be called! */ - } - } - } while (again); -} - -/** - * gigaset_read_int_callback - * - * It is called if the data was received from the device. - */ -static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs) -{ - struct inbuf_t *inbuf = urb->context; - struct cardstate *cs = inbuf->cs; - int resubmit = 0; - int r; - unsigned numbytes; - unsigned char *src; - unsigned long flags; - - if (!urb->status) { - if (!cs->connected) { - err("%s: disconnected", __func__); /* should never happen */ - return; - } - - numbytes = urb->actual_length; - - if (numbytes) { - src = inbuf->rcvbuf; - if (unlikely(*src)) - dev_warn(cs->dev, - "%s: There was no leading 0, but 0x%02x!\n", - __func__, (unsigned) *src); - ++src; /* skip leading 0x00 */ - --numbytes; - if (gigaset_fill_inbuf(inbuf, src, numbytes)) { - gig_dbg(DEBUG_INTR, "%s-->BH", __func__); - gigaset_schedule_event(inbuf->cs); - } - } else - gig_dbg(DEBUG_INTR, "Received zero block length"); - resubmit = 1; - } else { - /* The urb might have been killed. */ - gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", - __func__, urb->status); - if (urb->status != -ENOENT) { /* not killed */ - if (!cs->connected) { - err("%s: disconnected", __func__); /* should never happen */ - return; - } - resubmit = 1; - } - } - - if (resubmit) { - spin_lock_irqsave(&cs->lock, flags); - r = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; - spin_unlock_irqrestore(&cs->lock, flags); - if (r) - dev_err(cs->dev, "error %d when resubmitting urb.\n", - -r); - } -} - - -/* This callback routine is called when data was transmitted to the device. */ -static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) -{ - struct cardstate *cs = urb->context; - unsigned long flags; - - if (urb->status) - dev_err(cs->dev, "bulk transfer failed (status %d)\n", - -urb->status); - /* That's all we can do. Communication problems - are handled by timeouts or network protocols. */ - - spin_lock_irqsave(&cs->lock, flags); - if (!cs->connected) { - err("%s: not connected", __func__); - } else { - atomic_set(&cs->hw.usb->busy, 0); - tasklet_schedule(&cs->write_tasklet); - } - spin_unlock_irqrestore(&cs->lock, flags); -} - -static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) -{ - struct cmdbuf_t *tcb; - unsigned long flags; - int count; - int status = -ENOENT; // FIXME - struct usb_cardstate *ucs = cs->hw.usb; - - do { - if (!cb->len) { - tcb = cb; - - spin_lock_irqsave(&cs->cmdlock, flags); - cs->cmdbytes -= cs->curlen; - gig_dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left", - cs->curlen, cs->cmdbytes); - cs->cmdbuf = cb = cb->next; - if (cb) { - cb->prev = NULL; - cs->curlen = cb->len; - } else { - cs->lastcmdbuf = NULL; - cs->curlen = 0; - } - spin_unlock_irqrestore(&cs->cmdlock, flags); - - if (tcb->wake_tasklet) - tasklet_schedule(tcb->wake_tasklet); - kfree(tcb); - } - if (cb) { - count = min(cb->len, ucs->bulk_out_size); - gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count); - - usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, - usb_sndbulkpipe(ucs->udev, - ucs->bulk_out_endpointAddr & 0x0f), - cb->buf + cb->offset, count, - gigaset_write_bulk_callback, cs); - - cb->offset += count; - cb->len -= count; - atomic_set(&ucs->busy, 1); - - spin_lock_irqsave(&cs->lock, flags); - status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC) : -ENODEV; - spin_unlock_irqrestore(&cs->lock, flags); - - if (status) { - atomic_set(&ucs->busy, 0); - err("could not submit urb (error %d)\n", - -status); - cb->len = 0; /* skip urb => remove cb+wakeup - in next loop cycle */ - } - } - } while (cb && status); /* next command on error */ - - return status; -} - -/* Send command to device. */ -static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, - int len, struct tasklet_struct *wake_tasklet) -{ - struct cmdbuf_t *cb; - unsigned long flags; - - gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? - DEBUG_TRANSCMD : DEBUG_LOCKCMD, - "CMD Transmit", len, buf); - - if (len <= 0) - return 0; - - if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { - dev_err(cs->dev, "%s: out of memory\n", __func__); - return -ENOMEM; - } - - memcpy(cb->buf, buf, len); - cb->len = len; - cb->offset = 0; - cb->next = NULL; - cb->wake_tasklet = wake_tasklet; - - spin_lock_irqsave(&cs->cmdlock, flags); - cb->prev = cs->lastcmdbuf; - if (cs->lastcmdbuf) - cs->lastcmdbuf->next = cb; - else { - cs->cmdbuf = cb; - cs->curlen = len; - } - cs->cmdbytes += len; - cs->lastcmdbuf = cb; - spin_unlock_irqrestore(&cs->cmdlock, flags); - - spin_lock_irqsave(&cs->lock, flags); - if (cs->connected) - tasklet_schedule(&cs->write_tasklet); - spin_unlock_irqrestore(&cs->lock, flags); - return len; -} - -static int gigaset_write_room(struct cardstate *cs) -{ - unsigned long flags; - unsigned bytes; - - spin_lock_irqsave(&cs->cmdlock, flags); - bytes = cs->cmdbytes; - spin_unlock_irqrestore(&cs->cmdlock, flags); - - return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0; -} - -static int gigaset_chars_in_buffer(struct cardstate *cs) -{ - return cs->cmdbytes; -} - -static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) -{ -#ifdef CONFIG_GIGASET_UNDOCREQ - struct usb_device *udev = cs->hw.usb->udev; - - gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf); - memcpy(cs->hw.usb->bchars, buf, 6); - return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, - 0, 0, &buf, 6, 2000); -#else - return -EINVAL; -#endif -} - -static int gigaset_freebcshw(struct bc_state *bcs) -{ - if (!bcs->hw.usb) - return 0; - //FIXME - kfree(bcs->hw.usb); - return 1; -} - -/* Initialize the b-channel structure */ -static int gigaset_initbcshw(struct bc_state *bcs) -{ - bcs->hw.usb = kmalloc(sizeof(struct usb_bc_state), GFP_KERNEL); - if (!bcs->hw.usb) - return 0; - - return 1; -} - -static void gigaset_reinitbcshw(struct bc_state *bcs) -{ -} - -static void gigaset_freecshw(struct cardstate *cs) -{ - tasklet_kill(&cs->write_tasklet); - kfree(cs->hw.usb); -} - -static int gigaset_initcshw(struct cardstate *cs) -{ - struct usb_cardstate *ucs; - - cs->hw.usb = ucs = - kmalloc(sizeof(struct usb_cardstate), GFP_KERNEL); - if (!ucs) - return 0; - - ucs->bchars[0] = 0; - ucs->bchars[1] = 0; - ucs->bchars[2] = 0; - ucs->bchars[3] = 0; - ucs->bchars[4] = 0x11; - ucs->bchars[5] = 0x13; - ucs->bulk_out_buffer = NULL; - ucs->bulk_out_urb = NULL; - //ucs->urb_cmd_out = NULL; - ucs->read_urb = NULL; - tasklet_init(&cs->write_tasklet, - &gigaset_modem_fill, (unsigned long) cs); - - return 1; -} - -/* Send data from current skb to the device. */ -static int write_modem(struct cardstate *cs) -{ - int ret = 0; - int count; - struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ - struct usb_cardstate *ucs = cs->hw.usb; - unsigned long flags; - - gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); - - if (!bcs->tx_skb->len) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - return -EINVAL; - } - - /* Copy data to bulk out buffer and // FIXME copying not necessary - * transmit data - */ - count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); - memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count); - skb_pull(bcs->tx_skb, count); - atomic_set(&ucs->busy, 1); - gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); - - spin_lock_irqsave(&cs->lock, flags); - if (cs->connected) { - usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, - usb_sndbulkpipe(ucs->udev, - ucs->bulk_out_endpointAddr & 0x0f), - ucs->bulk_out_buffer, count, - gigaset_write_bulk_callback, cs); - ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); - } else { - ret = -ENODEV; - } - spin_unlock_irqrestore(&cs->lock, flags); - - if (ret) { - err("could not submit urb (error %d)\n", -ret); - atomic_set(&ucs->busy, 0); - } - - if (!bcs->tx_skb->len) { - /* skb sent completely */ - gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? - - gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!", - (unsigned long) bcs->tx_skb); - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - } - - return ret; -} - -static int gigaset_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - int retval; - struct usb_device *udev = interface_to_usbdev(interface); - unsigned int ifnum; - struct usb_host_interface *hostif; - struct cardstate *cs = NULL; - struct usb_cardstate *ucs = NULL; - struct usb_endpoint_descriptor *endpoint; - int buffer_size; - int alt; - - gig_dbg(DEBUG_ANY, - "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", - __func__, le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - retval = -ENODEV; //FIXME - - /* See if the device offered us matches what we can accept */ - if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) || - (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) - return -ENODEV; - - /* this starts to become ascii art... */ - hostif = interface->cur_altsetting; - alt = hostif->desc.bAlternateSetting; - ifnum = hostif->desc.bInterfaceNumber; // FIXME ? - - if (alt != 0 || ifnum != 0) { - dev_warn(&udev->dev, "ifnum %d, alt %d\n", ifnum, alt); - return -ENODEV; - } - - /* Reject application specific intefaces - * - */ - if (hostif->desc.bInterfaceClass != 255) { - dev_info(&udev->dev, - "%s: Device matched but iface_desc[%d]->bInterfaceClass==%d!\n", - __func__, ifnum, hostif->desc.bInterfaceClass); - return -ENODEV; - } - - dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); - - cs = gigaset_getunassignedcs(driver); - if (!cs) { - dev_warn(&udev->dev, "no free cardstate\n"); - return -ENODEV; - } - ucs = cs->hw.usb; - - /* save off device structure ptrs for later use */ - usb_get_dev(udev); - ucs->udev = udev; - ucs->interface = interface; - cs->dev = &interface->dev; - - /* save address of controller structure */ - usb_set_intfdata(interface, cs); // dev_set_drvdata(&interface->dev, cs); - - endpoint = &hostif->endpoint[0].desc; - - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - ucs->bulk_out_size = buffer_size; - ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress; - ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!ucs->bulk_out_buffer) { - dev_err(cs->dev, "Couldn't allocate bulk_out_buffer\n"); - retval = -ENOMEM; - goto error; - } - - ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL); - if (!ucs->bulk_out_urb) { - dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n"); - retval = -ENOMEM; - goto error; - } - - endpoint = &hostif->endpoint[1].desc; - - atomic_set(&ucs->busy, 0); - - ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL); - if (!ucs->read_urb) { - dev_err(cs->dev, "No free urbs available\n"); - retval = -ENOMEM; - goto error; - } - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - ucs->rcvbuf_size = buffer_size; - ucs->int_in_endpointAddr = endpoint->bEndpointAddress; - cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL); - if (!cs->inbuf[0].rcvbuf) { - dev_err(cs->dev, "Couldn't allocate rcvbuf\n"); - retval = -ENOMEM; - goto error; - } - /* Fill the interrupt urb and send it to the core */ - usb_fill_int_urb(ucs->read_urb, udev, - usb_rcvintpipe(udev, - endpoint->bEndpointAddress & 0x0f), - cs->inbuf[0].rcvbuf, buffer_size, - gigaset_read_int_callback, - cs->inbuf + 0, endpoint->bInterval); - - retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL); - if (retval) { - dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval); - goto error; - } - - /* tell common part that the device is ready */ - if (startmode == SM_LOCKED) - atomic_set(&cs->mstate, MS_LOCKED); - - if (!gigaset_start(cs)) { - tasklet_kill(&cs->write_tasklet); - retval = -ENODEV; //FIXME - goto error; - } - return 0; - -error: - if (ucs->read_urb) - usb_kill_urb(ucs->read_urb); - kfree(ucs->bulk_out_buffer); - if (ucs->bulk_out_urb != NULL) - usb_free_urb(ucs->bulk_out_urb); - kfree(cs->inbuf[0].rcvbuf); - if (ucs->read_urb != NULL) - usb_free_urb(ucs->read_urb); - usb_set_intfdata(interface, NULL); - ucs->read_urb = ucs->bulk_out_urb = NULL; - cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; - usb_put_dev(ucs->udev); - ucs->udev = NULL; - ucs->interface = NULL; - gigaset_unassign(cs); - return retval; -} - -static void gigaset_disconnect(struct usb_interface *interface) -{ - struct cardstate *cs; - struct usb_cardstate *ucs; - - cs = usb_get_intfdata(interface); - ucs = cs->hw.usb; - usb_kill_urb(ucs->read_urb); - - gigaset_stop(cs); - - usb_set_intfdata(interface, NULL); - tasklet_kill(&cs->write_tasklet); - - usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */ - - kfree(ucs->bulk_out_buffer); - if (ucs->bulk_out_urb != NULL) - usb_free_urb(ucs->bulk_out_urb); - kfree(cs->inbuf[0].rcvbuf); - if (ucs->read_urb != NULL) - usb_free_urb(ucs->read_urb); - ucs->read_urb = ucs->bulk_out_urb = NULL; - cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; - - usb_put_dev(ucs->udev); - ucs->interface = NULL; - ucs->udev = NULL; - cs->dev = NULL; - gigaset_unassign(cs); -} - -static struct gigaset_ops ops = { - gigaset_write_cmd, - gigaset_write_room, - gigaset_chars_in_buffer, - gigaset_brkchars, - gigaset_init_bchannel, - gigaset_close_bchannel, - gigaset_initbcshw, - gigaset_freebcshw, - gigaset_reinitbcshw, - gigaset_initcshw, - gigaset_freecshw, - gigaset_set_modem_ctrl, - gigaset_baud_rate, - gigaset_set_line_ctrl, - gigaset_m10x_send_skb, - gigaset_m10x_input, -}; - -/** - * usb_gigaset_init - * This function is called while kernel-module is loaded - */ -static int __init usb_gigaset_init(void) -{ - int result; - - /* allocate memory for our driver state and intialize it */ - if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, - GIGASET_MODULENAME, GIGASET_DEVNAME, - GIGASET_DEVFSNAME, &ops, - THIS_MODULE)) == NULL) - goto error; - - /* allocate memory for our device state and intialize it */ - cardstate = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); - if (!cardstate) - goto error; - - /* register this driver with the USB subsystem */ - result = usb_register(&gigaset_usb_driver); - if (result < 0) { - err("usb_gigaset: usb_register failed (error %d)", - -result); - goto error; - } - - info(DRIVER_AUTHOR); - info(DRIVER_DESC); - return 0; - -error: if (cardstate) - gigaset_freecs(cardstate); - cardstate = NULL; - if (driver) - gigaset_freedriver(driver); - driver = NULL; - return -1; -} - - -/** - * usb_gigaset_exit - * This function is called while unloading the kernel-module - */ -static void __exit usb_gigaset_exit(void) -{ - gigaset_blockdriver(driver); /* => probe will fail - * => no gigaset_start any more - */ - - gigaset_shutdown(cardstate); - /* from now on, no isdn callback should be possible */ - - /* deregister this driver with the USB subsystem */ - usb_deregister(&gigaset_usb_driver); - /* this will call the disconnect-callback */ - /* from now on, no disconnect/probe callback should be running */ - - gigaset_freecs(cardstate); - cardstate = NULL; - gigaset_freedriver(driver); - driver = NULL; -} - - -module_init(usb_gigaset_init); -module_exit(usb_gigaset_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); - -MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 7bbfd85ab..2a2b03ff0 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -51,8 +51,8 @@ MODULE_LICENSE("GPL"); handler. */ -static int avmcs_config(struct pcmcia_device *link); -static void avmcs_release(struct pcmcia_device *link); +static void avmcs_config(dev_link_t *link); +static void avmcs_release(dev_link_t *link); /* The attach() and detach() entry points are used to create and destroy @@ -65,10 +65,10 @@ static void avmcs_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the skeleton device. Each actual PCMCIA card corresponds to one device instance, and is described - by one struct pcmcia_device structure (defined in ds.h). + by one dev_link_t structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of struct pcmcia_device pointers, where minor + memory card driver uses an array of dev_link_t pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -78,7 +78,7 @@ static void avmcs_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device + in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally can't be allocated dynamically. */ @@ -99,38 +99,54 @@ typedef struct local_info_t { ======================================================================*/ -static int avmcs_probe(struct pcmcia_device *p_dev) +static int avmcs_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; local_info_t *local; + /* Initialize the dev_link_t structure */ + link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); + if (!link) + goto err; + memset(link, 0, sizeof(struct dev_link_t)); + /* The io structure describes IO port mapping */ - p_dev->io.NumPorts1 = 16; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.NumPorts2 = 0; + link->io.NumPorts1 = 16; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.NumPorts2 = 0; /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; - - p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + /* General socket configuration */ - p_dev->conf.Attributes = CONF_ENABLE_IRQ; - p_dev->conf.IntType = INT_MEMORY_AND_IO; - p_dev->conf.ConfigIndex = 1; - p_dev->conf.Present = PRESENT_OPTION; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) - goto err; + goto err_kfree; memset(local, 0, sizeof(local_info_t)); - p_dev->priv = local; + link->priv = local; - return avmcs_config(p_dev); + link->handle = p_dev; + p_dev->instance = link; + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + avmcs_config(link); + + return 0; + + err_kfree: + kfree(link); err: - return -ENOMEM; + return -EINVAL; } /* avmcs_attach */ /*====================================================================== @@ -142,10 +158,15 @@ static int avmcs_probe(struct pcmcia_device *p_dev) ======================================================================*/ -static void avmcs_detach(struct pcmcia_device *link) +static void avmcs_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + + if (link->state & DEV_CONFIG) avmcs_release(link); - kfree(link->priv); + + kfree(link->priv); + kfree(link); } /* avmcs_detach */ /*====================================================================== @@ -156,7 +177,7 @@ static void avmcs_detach(struct pcmcia_device *link) ======================================================================*/ -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_tuple_data(handle, tuple); @@ -164,7 +185,7 @@ static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_first_tuple(handle, tuple); @@ -172,7 +193,7 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_next_tuple(handle, tuple); @@ -180,8 +201,9 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int avmcs_config(struct pcmcia_device *link) +static void avmcs_config(dev_link_t *link) { + client_handle_t handle; tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; @@ -191,7 +213,8 @@ static int avmcs_config(struct pcmcia_device *link) char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); - + + handle = link->handle; dev = link->priv; /* @@ -200,21 +223,25 @@ static int avmcs_config(struct pcmcia_device *link) */ do { tuple.DesiredTuple = CISTPL_CONFIG; - i = pcmcia_get_first_tuple(link, &tuple); + i = pcmcia_get_first_tuple(handle, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - i = pcmcia_get_tuple_data(link, &tuple); + i = pcmcia_get_tuple_data(handle, &tuple); if (i != CS_SUCCESS) break; - i = pcmcia_parse_tuple(link, &tuple, &parse); + i = pcmcia_parse_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { - cs_error(link, ParseTuple, i); - return -ENODEV; + cs_error(link->handle, ParseTuple, i); + link->state &= ~DEV_CONFIG_PENDING; + return; } + + /* Configure card */ + link->state |= DEV_CONFIG; do { @@ -225,7 +252,7 @@ static int avmcs_config(struct pcmcia_device *link) tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; - if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { + if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } @@ -236,7 +263,7 @@ static int avmcs_config(struct pcmcia_device *link) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link, &tuple, &parse); + i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; @@ -246,36 +273,36 @@ static int avmcs_config(struct pcmcia_device *link) printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } - i = next_tuple(link, &tuple, &parse); + i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); break; } - + /* * allocate an interrupt line */ - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { - cs_error(link, RequestIRQ, i); - /* undo */ - pcmcia_disable_device(link); + cs_error(link->handle, RequestIRQ, i); + pcmcia_release_io(link->handle, &link->io); break; } - + /* * configure the PCMCIA socket */ - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { - cs_error(link, RequestConfiguration, i); - pcmcia_disable_device(link); + cs_error(link->handle, RequestConfiguration, i); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); break; } @@ -304,12 +331,13 @@ found_port: dev->node.major = 64; dev->node.minor = 0; - link->dev_node = &dev->node; - + link->dev = &dev->node; + + link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if (i != 0) { avmcs_release(link); - return -ENODEV; + return; } @@ -323,10 +351,9 @@ found_port: printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); avmcs_release(link); - return -ENODEV; + return; } dev->node.minor = i; - return 0; } /* avmcs_config */ @@ -338,12 +365,56 @@ found_port: ======================================================================*/ -static void avmcs_release(struct pcmcia_device *link) +static void avmcs_release(dev_link_t *link) { - b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); - pcmcia_disable_device(link); + b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); + + /* Unlink the device chain */ + link->dev = NULL; + + /* Don't bother checking to see if these succeed or not */ + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } /* avmcs_release */ +static int avmcs_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int avmcs_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + + return 0; +} + +/*====================================================================== + + The card status event handler. Mostly, this schedules other + stuff to run after an event is received. A CARD_REMOVAL event + also sets some flags to discourage the net drivers from trying + to talk to the card any more. + + When a CARD_REMOVAL event is received, we immediately set a 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 struct pcmcia_device_id avmcs_ids[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), @@ -358,9 +429,11 @@ static struct pcmcia_driver avmcs_driver = { .drv = { .name = "avm_cs", }, - .probe = avmcs_probe, + .probe = avmcs_attach, .remove = avmcs_detach, .id_table = avmcs_ids, + .suspend= avmcs_suspend, + .resume = avmcs_resume, }; static int __init avmcs_init(void) diff --git a/drivers/isdn/hardware/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h index 3b431723c..296d6a6f7 100644 --- a/drivers/isdn/hardware/avm/avmcard.h +++ b/drivers/isdn/hardware/avm/avmcard.h @@ -437,7 +437,9 @@ static inline unsigned int t1_get_slice(unsigned int base, #endif dp += i; i = 0; - break; + if (i == 0) + break; + /* fall through */ default: *dp++ = b1_get_byte(base); i--; diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c index 4d64e5cbc..91dd0551f 100644 --- a/drivers/isdn/hardware/avm/b1dma.c +++ b/drivers/isdn/hardware/avm/b1dma.c @@ -39,7 +39,7 @@ MODULE_AUTHOR("Carsten Paeth"); MODULE_LICENSE("GPL"); static int suppress_pollack = 0; -module_param(suppress_pollack, bool, 0); +MODULE_PARM(suppress_pollack, "0-1i"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/hardware/avm/b1isa.c b/drivers/isdn/hardware/avm/b1isa.c index 80fb48884..38bd4dfec 100644 --- a/drivers/isdn/hardware/avm/b1isa.c +++ b/drivers/isdn/hardware/avm/b1isa.c @@ -169,8 +169,8 @@ static struct pci_dev isa_dev[MAX_CARDS]; static int io[MAX_CARDS]; static int irq[MAX_CARDS]; -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); +MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i"); MODULE_PARM_DESC(io, "I/O base address(es)"); MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index f7253b213..724aac2c1 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c @@ -50,7 +50,7 @@ MODULE_DEVICE_TABLE(pci, c4_pci_tbl); MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM C2/C4 cards"); MODULE_AUTHOR("Carsten Paeth"); MODULE_LICENSE("GPL"); -module_param(suppress_pollack, bool, 0); +MODULE_PARM(suppress_pollack, "0-1i"); /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c index 5a2f854d5..3b701d97b 100644 --- a/drivers/isdn/hardware/avm/t1isa.c +++ b/drivers/isdn/hardware/avm/t1isa.c @@ -519,9 +519,9 @@ static int io[MAX_CARDS]; static int irq[MAX_CARDS]; static int cardnr[MAX_CARDS]; -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param_array(cardnr, int, NULL, 0); +MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i"); +MODULE_PARM(cardnr, "1-" __MODULE_STRING(MAX_CARDS) "i"); MODULE_PARM_DESC(io, "I/O base address(es)"); MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); MODULE_PARM_DESC(cardnr, "Card number(s) (as jumpered)"); diff --git a/drivers/isdn/hardware/eicon/divasync.h b/drivers/isdn/hardware/eicon/divasync.h index 0a5be7f96..af3eb9e79 100644 --- a/drivers/isdn/hardware/eicon/divasync.h +++ b/drivers/isdn/hardware/eicon/divasync.h @@ -256,7 +256,6 @@ typedef struct #define NO_ORDER_CHECK_MASK 0x00000010 #define LOW_CHANNEL_MASK 0x00000020 #define NO_HSCX30_MASK 0x00000040 -#define MODE_MASK 0x00000080 #define SET_BOARD 0x00001000 #define SET_CRC4 0x00030000 #define SET_L1_TRISTATE 0x00040000 diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index ac28e3278..969da40c4 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -67,8 +67,8 @@ module_param(isdnprot, int, 0); handler. */ -static int avma1cs_config(struct pcmcia_device *link); -static void avma1cs_release(struct pcmcia_device *link); +static void avma1cs_config(dev_link_t *link); +static void avma1cs_release(dev_link_t *link); /* The attach() and detach() entry points are used to create and destroy @@ -82,10 +82,10 @@ static void avma1cs_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the skeleton device. Each actual PCMCIA card corresponds to one device instance, and is described - by one struct pcmcia_device structure (defined in ds.h). + by one dev_link_t structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of struct pcmcia_device pointers, where minor + memory card driver uses an array of dev_link_t pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -95,7 +95,7 @@ static void avma1cs_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device + in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally can't be allocated dynamically. */ @@ -116,40 +116,55 @@ typedef struct local_info_t { ======================================================================*/ -static int avma1cs_probe(struct pcmcia_device *p_dev) +static int avma1cs_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; local_info_t *local; DEBUG(0, "avma1cs_attach()\n"); + /* Initialize the dev_link_t structure */ + link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); + if (!link) + return -ENOMEM; + memset(link, 0, sizeof(struct dev_link_t)); + /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) + if (!local) { + kfree(link); return -ENOMEM; - + } memset(local, 0, sizeof(local_info_t)); - p_dev->priv = local; + link->priv = local; /* The io structure describes IO port mapping */ - p_dev->io.NumPorts1 = 16; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.NumPorts2 = 16; - p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16; - p_dev->io.IOAddrLines = 5; + link->io.NumPorts1 = 16; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.NumPorts2 = 16; + link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; + link->io.IOAddrLines = 5; /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; - p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; /* General socket configuration */ - p_dev->conf.Attributes = CONF_ENABLE_IRQ; - p_dev->conf.IntType = INT_MEMORY_AND_IO; - p_dev->conf.ConfigIndex = 1; - p_dev->conf.Present = PRESENT_OPTION; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; - return avma1cs_config(p_dev); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + avma1cs_config(link); + + return 0; } /* avma1cs_attach */ /*====================================================================== @@ -161,11 +176,17 @@ static int avma1cs_probe(struct pcmcia_device *p_dev) ======================================================================*/ -static void avma1cs_detach(struct pcmcia_device *link) +static void avma1cs_detach(struct pcmcia_device *p_dev) { - DEBUG(0, "avma1cs_detach(0x%p)\n", link); - avma1cs_release(link); - kfree(link->priv); + dev_link_t *link = dev_to_instance(p_dev); + + DEBUG(0, "avma1cs_detach(0x%p)\n", link); + + if (link->state & DEV_CONFIG) + avma1cs_release(link); + + kfree(link->priv); + kfree(link); } /* avma1cs_detach */ /*====================================================================== @@ -176,7 +197,7 @@ static void avma1cs_detach(struct pcmcia_device *link) ======================================================================*/ -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_tuple_data(handle, tuple); @@ -184,7 +205,7 @@ static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_first_tuple(handle, tuple); @@ -192,7 +213,7 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_next_tuple(handle, tuple); @@ -200,8 +221,9 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int avma1cs_config(struct pcmcia_device *link) +static void avma1cs_config(dev_link_t *link) { + client_handle_t handle; tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; @@ -211,7 +233,8 @@ static int avma1cs_config(struct pcmcia_device *link) char devname[128]; IsdnCard_t icard; int busy = 0; - + + handle = link->handle; dev = link->priv; DEBUG(0, "avma1cs_config(0x%p)\n", link); @@ -222,21 +245,25 @@ static int avma1cs_config(struct pcmcia_device *link) */ do { tuple.DesiredTuple = CISTPL_CONFIG; - i = pcmcia_get_first_tuple(link, &tuple); + i = pcmcia_get_first_tuple(handle, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - i = pcmcia_get_tuple_data(link, &tuple); + i = pcmcia_get_tuple_data(handle, &tuple); if (i != CS_SUCCESS) break; - i = pcmcia_parse_tuple(link, &tuple, &parse); + i = pcmcia_parse_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { - cs_error(link, ParseTuple, i); - return -ENODEV; + cs_error(link->handle, ParseTuple, i); + link->state &= ~DEV_CONFIG_PENDING; + return; } + + /* Configure card */ + link->state |= DEV_CONFIG; do { @@ -247,7 +274,7 @@ static int avma1cs_config(struct pcmcia_device *link) tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; - if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { + if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } @@ -258,7 +285,7 @@ static int avma1cs_config(struct pcmcia_device *link) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link, &tuple, &parse); + i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; @@ -268,36 +295,36 @@ static int avma1cs_config(struct pcmcia_device *link) printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1 - 1); - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } - i = next_tuple(link, &tuple, &parse); + i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); break; } /* * allocate an interrupt line */ - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { - cs_error(link, RequestIRQ, i); - /* undo */ - pcmcia_disable_device(link); + cs_error(link->handle, RequestIRQ, i); + pcmcia_release_io(link->handle, &link->io); break; } - + /* * configure the PCMCIA socket */ - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { - cs_error(link, RequestConfiguration, i); - pcmcia_disable_device(link); + cs_error(link->handle, RequestConfiguration, i); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); break; } @@ -309,12 +336,13 @@ found_port: strcpy(dev->node.dev_name, "A1"); dev->node.major = 45; dev->node.minor = 0; - link->dev_node = &dev->node; - + link->dev = &dev->node; + + link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if (i != 0) { avma1cs_release(link); - return -ENODEV; + return; } printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", @@ -329,11 +357,10 @@ found_port: if (i < 0) { printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); avma1cs_release(link); - return -ENODEV; + return; } dev->node.minor = i; - return 0; } /* avma1cs_config */ /*====================================================================== @@ -344,18 +371,47 @@ found_port: ======================================================================*/ -static void avma1cs_release(struct pcmcia_device *link) +static void avma1cs_release(dev_link_t *link) { - local_info_t *local = link->priv; + local_info_t *local = link->priv; - DEBUG(0, "avma1cs_release(0x%p)\n", link); + DEBUG(0, "avma1cs_release(0x%p)\n", link); - /* now unregister function with hisax */ - HiSax_closecard(local->node.minor); + /* no unregister function with hisax */ + HiSax_closecard(local->node.minor); - pcmcia_disable_device(link); + /* Unlink the device chain */ + link->dev = NULL; + + /* Don't bother checking to see if these succeed or not */ + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } /* avma1cs_release */ +static int avma1cs_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int avma1cs_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + + return 0; +} + static struct pcmcia_device_id avma1cs_ids[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), @@ -369,11 +425,13 @@ static struct pcmcia_driver avma1cs_driver = { .drv = { .name = "avma1_cs", }, - .probe = avma1cs_probe, + .probe = avma1cs_attach, .remove = avma1cs_detach, .id_table = avma1cs_ids, + .suspend = avma1cs_suspend, + .resume = avma1cs_resume, }; - + /*====================================================================*/ static int __init init_avma1_cs(void) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 27332506f..df9d65201 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -25,6 +25,7 @@ #include #include #define HISAX_STATUS_BUFSIZE 4096 +#define INCLUDE_INLINE_FUNCS /* * This structure array contains one entry per card. An entry looks diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index f8ca4b323..110e9fd66 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -108,6 +108,7 @@ static const char *ITACVer[] = #define ELSA_ASSIGN 4 #define RS_ISR_PASS_LIMIT 256 +#define _INLINE_ inline #define FLG_MODEM_ACTIVE 1 /* IPAC AUX */ #define ELSA_IPAC_LINE_LED 0x40 /* Bit 6 Gelbe LED */ diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index e18e75be8..062fb8f07 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -94,8 +94,8 @@ module_param(protocol, int, 0); handler. */ -static int elsa_cs_config(struct pcmcia_device *link); -static void elsa_cs_release(struct pcmcia_device *link); +static void elsa_cs_config(dev_link_t *link); +static void elsa_cs_release(dev_link_t *link); /* The attach() and detach() entry points are used to create and destroy @@ -111,7 +111,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device + in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. In this case, we also provide a flag to indicate if a device is @@ -121,7 +121,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev); */ typedef struct local_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; int busy; int cardnr; @@ -139,8 +139,9 @@ typedef struct local_info_t { ======================================================================*/ -static int elsa_cs_probe(struct pcmcia_device *link) +static int elsa_cs_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; local_info_t *local; DEBUG(0, "elsa_cs_attach()\n"); @@ -149,11 +150,8 @@ static int elsa_cs_probe(struct pcmcia_device *link) local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); - - local->p_dev = link; - link->priv = local; - local->cardnr = -1; + link = &local->link; link->priv = local; /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; @@ -172,9 +170,16 @@ static int elsa_cs_probe(struct pcmcia_device *link) link->io.IOAddrLines = 3; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - return elsa_cs_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + elsa_cs_config(link); + + return 0; } /* elsa_cs_attach */ /*====================================================================== @@ -186,16 +191,20 @@ static int elsa_cs_probe(struct pcmcia_device *link) ======================================================================*/ -static void elsa_cs_detach(struct pcmcia_device *link) +static void elsa_cs_detach(struct pcmcia_device *p_dev) { - local_info_t *info = link->priv; + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *info = link->priv; - DEBUG(0, "elsa_cs_detach(0x%p)\n", link); + DEBUG(0, "elsa_cs_detach(0x%p)\n", link); - info->busy = 1; - elsa_cs_release(link); + if (link->state & DEV_CONFIG) { + info->busy = 1; + elsa_cs_release(link); + } + + kfree(info); - kfree(info); } /* elsa_cs_detach */ /*====================================================================== @@ -205,7 +214,7 @@ static void elsa_cs_detach(struct pcmcia_device *link) device available to the system. ======================================================================*/ -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_tuple_data(handle, tuple); @@ -213,7 +222,7 @@ static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_first_tuple(handle, tuple); @@ -221,7 +230,7 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_next_tuple(handle, tuple); @@ -229,8 +238,9 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int elsa_cs_config(struct pcmcia_device *link) +static void elsa_cs_config(dev_link_t *link) { + client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; @@ -240,6 +250,7 @@ static int elsa_cs_config(struct pcmcia_device *link) IsdnCard_t icard; DEBUG(0, "elsa_config(0x%p)\n", link); + handle = link->handle; dev = link->priv; /* @@ -251,7 +262,7 @@ static int elsa_cs_config(struct pcmcia_device *link) tuple.TupleDataMax = 255; tuple.TupleOffset = 0; tuple.Attributes = 0; - i = first_tuple(link, &tuple, &parse); + i = first_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -259,29 +270,32 @@ static int elsa_cs_config(struct pcmcia_device *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link, &tuple, &parse); + i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } break; } - i = next_tuple(link, &tuple, &parse); + i = next_tuple(handle, &tuple, &parse); } if (i != CS_SUCCESS) { @@ -289,14 +303,14 @@ static int elsa_cs_config(struct pcmcia_device *link) goto cs_failed; } - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; @@ -307,11 +321,14 @@ static int elsa_cs_config(struct pcmcia_device *link) sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; - link->dev_node = &dev->node; + link->dev = &dev->node; /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x: ", - dev->node.dev_name, link->conf.ConfigIndex); + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", + dev->node.dev_name, link->conf.ConfigIndex, + link->conf.Vcc/10, link->conf.Vcc%10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -322,6 +339,8 @@ static int elsa_cs_config(struct pcmcia_device *link) link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); + link->state &= ~DEV_CONFIG_PENDING; + icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; @@ -335,11 +354,10 @@ static int elsa_cs_config(struct pcmcia_device *link) } else ((local_info_t*)link->priv)->cardnr = i; - return 0; + return; cs_failed: - cs_error(link, last_fn, i); + cs_error(link->handle, last_fn, i); elsa_cs_release(link); - return -ENODEV; } /* elsa_cs_config */ /*====================================================================== @@ -350,7 +368,7 @@ cs_failed: ======================================================================*/ -static void elsa_cs_release(struct pcmcia_device *link) +static void elsa_cs_release(dev_link_t *link) { local_info_t *local = link->priv; @@ -362,23 +380,39 @@ static void elsa_cs_release(struct pcmcia_device *link) HiSax_closecard(local->cardnr); } } - - pcmcia_disable_device(link); + /* Unlink the device chain */ + link->dev = NULL; + + /* Don't bother checking to see if these succeed or not */ + if (link->win) + pcmcia_release_window(link->win); + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } /* elsa_cs_release */ -static int elsa_suspend(struct pcmcia_device *link) +static int elsa_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; + link->state |= DEV_SUSPEND; dev->busy = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); return 0; } -static int elsa_resume(struct pcmcia_device *link) +static int elsa_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); dev->busy = 0; return 0; @@ -396,7 +430,7 @@ static struct pcmcia_driver elsa_cs_driver = { .drv = { .name = "elsa_cs", }, - .probe = elsa_cs_probe, + .probe = elsa_cs_attach, .remove = elsa_cs_detach, .id_table = elsa_ids, .suspend = elsa_suspend, diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index dbcca287e..dc7ef957e 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -387,7 +387,8 @@ static void hdlc_fill_fifo(struct fritz_bcs *bcs) DBG(0x40, "hdlc_fill_fifo"); - BUG_ON(skb->len == 0); + if (skb->len == 0) + BUG(); bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME; if (bcs->tx_skb->len > bcs->fifo_size) { @@ -629,7 +630,9 @@ static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg) switch (pr) { case PH_DATA | REQUEST: - BUG_ON(bcs->tx_skb); + if (bcs->tx_skb) + BUG(); + bcs->tx_skb = skb; DBG_SKB(1, skb); hdlc_fill_fifo(bcs); diff --git a/drivers/isdn/hisax/hisax_isac.c b/drivers/isdn/hisax/hisax_isac.c index 81eac344b..f4972f6c1 100644 --- a/drivers/isdn/hisax/hisax_isac.c +++ b/drivers/isdn/hisax/hisax_isac.c @@ -476,10 +476,12 @@ static void isac_fill_fifo(struct isac *isac) unsigned char cmd; u_char *ptr; - BUG_ON(!isac->tx_skb); + if (!isac->tx_skb) + BUG(); count = isac->tx_skb->len; - BUG_ON(count <= 0); + if (count <= 0) + BUG(); DBG(DBG_IRQ, "count %d", count); @@ -857,7 +859,8 @@ void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) dev_kfree_skb(skb); break; } - BUG_ON(isac->tx_skb); + if (isac->tx_skb) + BUG(); isac->tx_skb = skb; isac_fill_fifo(isac); diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 9bb18f3f7..6f5213a18 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -95,8 +95,8 @@ module_param(protocol, int, 0); event handler. */ -static int sedlbauer_config(struct pcmcia_device *link); -static void sedlbauer_release(struct pcmcia_device *link); +static void sedlbauer_config(dev_link_t *link); +static void sedlbauer_release(dev_link_t *link); /* The attach() and detach() entry points are used to create and destroy @@ -119,7 +119,7 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device + in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. @@ -130,7 +130,7 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev); */ typedef struct local_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; int stop; int cardnr; @@ -148,10 +148,11 @@ typedef struct local_info_t { ======================================================================*/ -static int sedlbauer_probe(struct pcmcia_device *link) +static int sedlbauer_attach(struct pcmcia_device *p_dev) { local_info_t *local; - + dev_link_t *link; + DEBUG(0, "sedlbauer_attach()\n"); /* Allocate space for private device-specific data */ @@ -159,10 +160,8 @@ static int sedlbauer_probe(struct pcmcia_device *link) if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; - - local->p_dev = link; - link->priv = local; - + link = &local->link; link->priv = local; + /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; @@ -183,10 +182,18 @@ static int sedlbauer_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = 3; + link->conf.Attributes = 0; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - return sedlbauer_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + sedlbauer_config(link); + + return 0; } /* sedlbauer_attach */ /*====================================================================== @@ -198,15 +205,19 @@ static int sedlbauer_probe(struct pcmcia_device *link) ======================================================================*/ -static void sedlbauer_detach(struct pcmcia_device *link) +static void sedlbauer_detach(struct pcmcia_device *p_dev) { - DEBUG(0, "sedlbauer_detach(0x%p)\n", link); + dev_link_t *link = dev_to_instance(p_dev); + + DEBUG(0, "sedlbauer_detach(0x%p)\n", link); - ((local_info_t *)link->priv)->stop = 1; - sedlbauer_release(link); + if (link->state & DEV_CONFIG) { + ((local_info_t *)link->priv)->stop = 1; + sedlbauer_release(link); + } - /* This points to the parent local_info_t struct */ - kfree(link->priv); + /* This points to the parent local_info_t struct */ + kfree(link->priv); } /* sedlbauer_detach */ /*====================================================================== @@ -219,8 +230,9 @@ static void sedlbauer_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int sedlbauer_config(struct pcmcia_device *link) +static void sedlbauer_config(dev_link_t *link) { + client_handle_t handle = link->handle; local_info_t *dev = link->priv; tuple_t tuple; cisparse_t parse; @@ -242,13 +254,18 @@ static int sedlbauer_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; /* In this loop, we scan the CIS for configuration table entries, @@ -263,12 +280,12 @@ static int sedlbauer_config(struct pcmcia_device *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; @@ -292,10 +309,10 @@ static int sedlbauer_config(struct pcmcia_device *link) } if (cfg->vpp1.present & (1<conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* Do we need to allocate an interrupt? */ @@ -322,13 +339,13 @@ static int sedlbauer_config(struct pcmcia_device *link) 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) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; } /* Now set up a common memory window, if needed. There is room - in the struct pcmcia_device structure for one memory window handle, + in the dev_link_t structure for one memory window handle, but if the base addresses need to be saved, or if multiple windows are needed, the info should go in the private data structure for this device. @@ -349,7 +366,7 @@ static int sedlbauer_config(struct pcmcia_device *link) req.Size = 0x1000; */ req.AccessSpeed = 0; - if (pcmcia_request_window(&link, &req, &link->win) != 0) + if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(link->win, &map) != 0) @@ -357,25 +374,29 @@ static int sedlbauer_config(struct pcmcia_device *link) } /* If we got this far, we're cool! */ break; - + next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); +/* new in dummy.cs 2001/01/28 MN + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); +*/ + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } - + /* Allocate an interrupt line. Note that this does not assign a handler to the interrupt, unless the 'Handler' member of the irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); /* At this point, the dev_node_t structure(s) need to be @@ -383,13 +404,14 @@ static int sedlbauer_config(struct pcmcia_device *link) */ sprintf(dev->node.dev_name, "sedlbauer"); dev->node.major = dev->node.minor = 0; - link->dev_node = &dev->node; + link->dev = &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.Vpp) - printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", + dev->node.dev_name, link->conf.ConfigIndex, + link->conf.Vcc/10, link->conf.Vcc%10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -402,6 +424,8 @@ static int sedlbauer_config(struct pcmcia_device *link) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base+req.Size-1); printk("\n"); + + link->state &= ~DEV_CONFIG_PENDING; icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; @@ -413,16 +437,14 @@ static int sedlbauer_config(struct pcmcia_device *link) printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n", last_ret, link->io.BasePort1); sedlbauer_release(link); - return -ENODEV; } else ((local_info_t*)link->priv)->cardnr = last_ret; - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); sedlbauer_release(link); - return -ENODEV; } /* sedlbauer_config */ @@ -434,7 +456,7 @@ cs_failed: ======================================================================*/ -static void sedlbauer_release(struct pcmcia_device *link) +static void sedlbauer_release(dev_link_t *link) { local_info_t *local = link->priv; DEBUG(0, "sedlbauer_release(0x%p)\n", link); @@ -445,23 +467,46 @@ static void sedlbauer_release(struct pcmcia_device *link) HiSax_closecard(local->cardnr); } } + /* Unlink the device chain */ + link->dev = NULL; - pcmcia_disable_device(link); + /* + In a normal driver, additional code may be needed to release + other kernel data structures associated with this device. + */ + + /* Don't bother checking to see if these succeed or not */ + if (link->win) + pcmcia_release_window(link->win); + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } /* sedlbauer_release */ -static int sedlbauer_suspend(struct pcmcia_device *link) +static int sedlbauer_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; + link->state |= DEV_SUSPEND; dev->stop = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); return 0; } -static int sedlbauer_resume(struct pcmcia_device *link) +static int sedlbauer_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); dev->stop = 0; return 0; @@ -485,7 +530,7 @@ static struct pcmcia_driver sedlbauer_driver = { .drv = { .name = "sedlbauer_cs", }, - .probe = sedlbauer_probe, + .probe = sedlbauer_attach, .remove = sedlbauer_detach, .id_table = sedlbauer_ids, .suspend = sedlbauer_suspend, diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c index 22fd5db18..657817a59 100644 --- a/drivers/isdn/hisax/st5481_b.c +++ b/drivers/isdn/hisax/st5481_b.c @@ -356,7 +356,9 @@ void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg) switch (pr) { case PH_DATA | REQUEST: - BUG_ON(bcs->b_out.tx_skb); + if (bcs->b_out.tx_skb) + BUG(); + bcs->b_out.tx_skb = skb; break; case PH_ACTIVATE | REQUEST: diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index 493dc9499..941f7022a 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c @@ -596,7 +596,9 @@ void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) break; case PH_DATA | REQUEST: DBG(2, "PH_DATA REQUEST len %d", skb->len); - BUG_ON(adapter->d_out.tx_skb); + if (adapter->d_out.tx_skb) + BUG(); + adapter->d_out.tx_skb = skb; FsmEvent(&adapter->d_out.fsm, EV_DOUT_START_XMIT, NULL); break; diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index afcc2aead..4e5c14c72 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -75,8 +75,8 @@ module_param(protocol, int, 0); handler. */ -static int teles_cs_config(struct pcmcia_device *link); -static void teles_cs_release(struct pcmcia_device *link); +static void teles_cs_config(dev_link_t *link); +static void teles_cs_release(dev_link_t *link); /* The attach() and detach() entry points are used to create and destroy @@ -89,10 +89,10 @@ static void teles_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the teles_cs device. Each actual PCMCIA card corresponds to one device instance, and is described - by one struct pcmcia_device structure (defined in ds.h). + by one dev_link_t structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of struct pcmcia_device pointers, where minor + memory card driver uses an array of dev_link_t pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -102,7 +102,7 @@ static void teles_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device + in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. In this case, we also provide a flag to indicate if a device is @@ -112,7 +112,7 @@ static void teles_detach(struct pcmcia_device *p_dev); */ typedef struct local_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; int busy; int cardnr; @@ -130,8 +130,9 @@ typedef struct local_info_t { ======================================================================*/ -static int teles_probe(struct pcmcia_device *link) +static int teles_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; local_info_t *local; DEBUG(0, "teles_attach()\n"); @@ -141,9 +142,7 @@ static int teles_probe(struct pcmcia_device *link) if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; - - local->p_dev = link; - link->priv = local; + link = &local->link; link->priv = local; /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; @@ -162,9 +161,16 @@ static int teles_probe(struct pcmcia_device *link) link->io.IOAddrLines = 5; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - return teles_cs_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + teles_cs_config(link); + + return 0; } /* teles_attach */ /*====================================================================== @@ -176,16 +182,20 @@ static int teles_probe(struct pcmcia_device *link) ======================================================================*/ -static void teles_detach(struct pcmcia_device *link) +static void teles_detach(struct pcmcia_device *p_dev) { - local_info_t *info = link->priv; + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *info = link->priv; + + DEBUG(0, "teles_detach(0x%p)\n", link); - DEBUG(0, "teles_detach(0x%p)\n", link); + if (link->state & DEV_CONFIG) { + info->busy = 1; + teles_cs_release(link); + } - info->busy = 1; - teles_cs_release(link); + kfree(info); - kfree(info); } /* teles_detach */ /*====================================================================== @@ -195,7 +205,7 @@ static void teles_detach(struct pcmcia_device *link) device available to the system. ======================================================================*/ -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_tuple_data(handle, tuple); @@ -203,7 +213,7 @@ static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_first_tuple(handle, tuple); @@ -211,7 +221,7 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i = pcmcia_get_next_tuple(handle, tuple); @@ -219,8 +229,9 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, return get_tuple(handle, tuple, parse); } -static int teles_cs_config(struct pcmcia_device *link) +static void teles_cs_config(dev_link_t *link) { + client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; @@ -230,6 +241,7 @@ static int teles_cs_config(struct pcmcia_device *link) IsdnCard_t icard; DEBUG(0, "teles_config(0x%p)\n", link); + handle = link->handle; dev = link->priv; /* @@ -241,7 +253,7 @@ static int teles_cs_config(struct pcmcia_device *link) tuple.TupleDataMax = 255; tuple.TupleOffset = 0; tuple.Attributes = 0; - i = first_tuple(link, &tuple, &parse); + i = first_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -249,29 +261,32 @@ static int teles_cs_config(struct pcmcia_device *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link, &tuple, &parse); + i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } break; } - i = next_tuple(link, &tuple, &parse); + i = next_tuple(handle, &tuple, &parse); } if (i != CS_SUCCESS) { @@ -279,14 +294,14 @@ static int teles_cs_config(struct pcmcia_device *link) goto cs_failed; } - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; @@ -297,11 +312,14 @@ static int teles_cs_config(struct pcmcia_device *link) sprintf(dev->node.dev_name, "teles"); dev->node.major = dev->node.minor = 0x0; - link->dev_node = &dev->node; + link->dev = &dev->node; /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x:", - dev->node.dev_name, link->conf.ConfigIndex); + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", + dev->node.dev_name, link->conf.ConfigIndex, + link->conf.Vcc/10, link->conf.Vcc%10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -312,6 +330,8 @@ static int teles_cs_config(struct pcmcia_device *link) link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); + link->state &= ~DEV_CONFIG_PENDING; + icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; @@ -322,16 +342,13 @@ static int teles_cs_config(struct pcmcia_device *link) printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); teles_cs_release(link); - return -ENODEV; - } - - ((local_info_t*)link->priv)->cardnr = i; - return 0; + } else + ((local_info_t*)link->priv)->cardnr = i; + return; cs_failed: - cs_error(link, last_fn, i); + cs_error(link->handle, last_fn, i); teles_cs_release(link); - return -ENODEV; } /* teles_cs_config */ /*====================================================================== @@ -342,7 +359,7 @@ cs_failed: ======================================================================*/ -static void teles_cs_release(struct pcmcia_device *link) +static void teles_cs_release(dev_link_t *link) { local_info_t *local = link->priv; @@ -354,23 +371,39 @@ static void teles_cs_release(struct pcmcia_device *link) HiSax_closecard(local->cardnr); } } - - pcmcia_disable_device(link); + /* Unlink the device chain */ + link->dev = NULL; + + /* Don't bother checking to see if these succeed or not */ + if (link->win) + pcmcia_release_window(link->win); + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } /* teles_cs_release */ -static int teles_suspend(struct pcmcia_device *link) +static int teles_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; + link->state |= DEV_SUSPEND; dev->busy = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); return 0; } -static int teles_resume(struct pcmcia_device *link) +static int teles_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); local_info_t *dev = link->priv; + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); dev->busy = 0; return 0; @@ -388,7 +421,7 @@ static struct pcmcia_driver teles_cs_driver = { .drv = { .name = "teles_cs", }, - .probe = teles_probe, + .probe = teles_attach, .remove = teles_detach, .id_table = teles_ids, .suspend = teles_suspend, diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c index 48d134be9..e19a01a30 100644 --- a/drivers/isdn/hysdn/boardergo.c +++ b/drivers/isdn/hysdn/boardergo.c @@ -38,8 +38,8 @@ ergo_interrupt(int intno, void *dev_id, struct pt_regs *regs) { hysdn_card *card = dev_id; /* parameter from irq */ tErgDpram *dpr; - unsigned long flags; - unsigned char volatile b; + ulong flags; + uchar volatile b; if (!card) return IRQ_NONE; /* error -> spurious interrupt */ @@ -77,7 +77,7 @@ ergo_irq_bh(hysdn_card * card) { tErgDpram *dpr; int again; - unsigned long flags; + ulong flags; if (card->state != CARD_STATE_RUN) return; /* invalid call */ @@ -131,8 +131,8 @@ ergo_irq_bh(hysdn_card * card) static void ergo_stopcard(hysdn_card * card) { - unsigned long flags; - unsigned char val; + ulong flags; + uchar val; hysdn_net_release(card); /* first release the net device if existing */ #ifdef CONFIG_HYSDN_CAPI @@ -157,7 +157,7 @@ ergo_stopcard(hysdn_card * card) static void ergo_set_errlog_state(hysdn_card * card, int on) { - unsigned long flags; + ulong flags; if (card->state != CARD_STATE_RUN) { card->err_log_state = ERRLOG_STATE_OFF; /* must be off */ @@ -217,10 +217,9 @@ ergo_testram(hysdn_card * card) /* Negative return values are interpreted as errors. */ /*****************************************************************************/ static int -ergo_writebootimg(struct HYSDN_CARD *card, unsigned char *buf, - unsigned long offs) +ergo_writebootimg(struct HYSDN_CARD *card, uchar * buf, ulong offs) { - unsigned char *dst; + uchar *dst; tErgDpram *dpram; int cnt = (BOOT_IMG_SIZE >> 2); /* number of words to move and swap (byte order!) */ @@ -265,14 +264,14 @@ ergo_writebootimg(struct HYSDN_CARD *card, unsigned char *buf, /* case of errors a negative error value is returned. */ /********************************************************************************/ static int -ergo_writebootseq(struct HYSDN_CARD *card, unsigned char *buf, int len) +ergo_writebootseq(struct HYSDN_CARD *card, uchar * buf, int len) { tDpramBootSpooler *sp = (tDpramBootSpooler *) card->dpram; - unsigned char *dst; - unsigned char buflen; + uchar *dst; + uchar buflen; int nr_write; - unsigned char tmp_rdptr; - unsigned char wr_mirror; + uchar tmp_rdptr; + uchar wr_mirror; int i; if (card->debug_flags & LOG_POF_CARD) @@ -331,7 +330,7 @@ ergo_waitpofready(struct HYSDN_CARD *card) { tErgDpram *dpr = card->dpram; /* pointer to DPRAM structure */ int timecnt = 10000 / 50; /* timeout is 10 secs max. */ - unsigned long flags; + ulong flags; int msg_size; int i; @@ -346,7 +345,7 @@ ergo_waitpofready(struct HYSDN_CARD *card) if ((dpr->ToPcChannel != CHAN_SYSTEM) || (dpr->ToPcSize < MIN_RDY_MSG_SIZE) || (dpr->ToPcSize > MAX_RDY_MSG_SIZE) || - ((*(unsigned long *) dpr->ToPcBuf) != RDY_MAGIC)) + ((*(ulong *) dpr->ToPcBuf) != RDY_MAGIC)) break; /* an error occurred */ /* Check for additional data delivered during SysReady */ diff --git a/drivers/isdn/hysdn/boardergo.h b/drivers/isdn/hysdn/boardergo.h index c59422aa8..b56ff0889 100644 --- a/drivers/isdn/hysdn/boardergo.h +++ b/drivers/isdn/hysdn/boardergo.h @@ -23,36 +23,36 @@ /* following DPRAM layout copied from OS2-driver boarderg.h */ typedef struct ErgDpram_tag { -/*0000 */ unsigned char ToHyBuf[ERG_TO_HY_BUF_SIZE]; -/*0E00 */ unsigned char ToPcBuf[ERG_TO_PC_BUF_SIZE]; +/*0000 */ uchar ToHyBuf[ERG_TO_HY_BUF_SIZE]; +/*0E00 */ uchar ToPcBuf[ERG_TO_PC_BUF_SIZE]; - /*1C00 */ unsigned char bSoftUart[SIZE_RSV_SOFT_UART]; + /*1C00 */ uchar bSoftUart[SIZE_RSV_SOFT_UART]; /* size 0x1B0 */ - /*1DB0 *//* tErrLogEntry */ unsigned char volatile ErrLogMsg[64]; + /*1DB0 *//* tErrLogEntry */ uchar volatile ErrLogMsg[64]; /* size 64 bytes */ - /*1DB0 unsigned long ulErrType; */ - /*1DB4 unsigned long ulErrSubtype; */ - /*1DB8 unsigned long ucTextSize; */ - /*1DB9 unsigned long ucText[ERRLOG_TEXT_SIZE]; *//* ASCIIZ of len ucTextSize-1 */ + /*1DB0 ulong ulErrType; */ + /*1DB4 ulong ulErrSubtype; */ + /*1DB8 ulong ucTextSize; */ + /*1DB9 ulong ucText[ERRLOG_TEXT_SIZE]; *//* ASCIIZ of len ucTextSize-1 */ /*1DF0 */ -/*1DF0 */ unsigned short volatile ToHyChannel; -/*1DF2 */ unsigned short volatile ToHySize; - /*1DF4 */ unsigned char volatile ToHyFlag; +/*1DF0 */ word volatile ToHyChannel; +/*1DF2 */ word volatile ToHySize; + /*1DF4 */ uchar volatile ToHyFlag; /* !=0: msg for Hy waiting */ - /*1DF5 */ unsigned char volatile ToPcFlag; + /*1DF5 */ uchar volatile ToPcFlag; /* !=0: msg for PC waiting */ -/*1DF6 */ unsigned short volatile ToPcChannel; -/*1DF8 */ unsigned short volatile ToPcSize; - /*1DFA */ unsigned char bRes1DBA[0x1E00 - 0x1DFA]; +/*1DF6 */ word volatile ToPcChannel; +/*1DF8 */ word volatile ToPcSize; + /*1DFA */ uchar bRes1DBA[0x1E00 - 0x1DFA]; /* 6 bytes */ -/*1E00 */ unsigned char bRestOfEntryTbl[0x1F00 - 0x1E00]; -/*1F00 */ unsigned long TrapTable[62]; - /*1FF8 */ unsigned char bRes1FF8[0x1FFB - 0x1FF8]; +/*1E00 */ uchar bRestOfEntryTbl[0x1F00 - 0x1E00]; +/*1F00 */ ulong TrapTable[62]; + /*1FF8 */ uchar bRes1FF8[0x1FFB - 0x1FF8]; /* low part of reset vetor */ -/*1FFB */ unsigned char ToPcIntMetro; +/*1FFB */ uchar ToPcIntMetro; /* notes: * - metro has 32-bit boot ram - accessing * ToPcInt and ToHyInt would be the same; @@ -65,16 +65,16 @@ typedef struct ErgDpram_tag { * so E1 side should NOT change this byte * when writing! */ -/*1FFC */ unsigned char volatile ToHyNoDpramErrLog; +/*1FFC */ uchar volatile ToHyNoDpramErrLog; /* note: ToHyNoDpramErrLog is used to inform * boot loader, not to use DPRAM based * ErrLog; when DOS driver is rewritten * this becomes obsolete */ -/*1FFD */ unsigned char bRes1FFD; - /*1FFE */ unsigned char ToPcInt; +/*1FFD */ uchar bRes1FFD; + /*1FFE */ uchar ToPcInt; /* E1_intclear; on CHAMP2: E1_intset */ - /*1FFF */ unsigned char ToHyInt; + /*1FFF */ uchar ToHyInt; /* E1_intset; on CHAMP2: E1_intclear */ } tErgDpram; diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index 6bac43cc9..acc1d3cce 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c @@ -31,7 +31,7 @@ static char hycapi_revision[]="$Revision: 1.8.6.4 $"; unsigned int hycapi_enable = 0xffffffff; -module_param(hycapi_enable, uint, 0); +MODULE_PARM(hycapi_enable, "i"); typedef struct _hycapi_appl { unsigned int ctrl_mask; @@ -523,7 +523,7 @@ New nccis are created if necessary. *******************************************************************/ void -hycapi_rx_capipkt(hysdn_card * card, unsigned char *buf, unsigned short len) +hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len) { struct sk_buff *skb; hycapictrl_info *cinfo = card->hyctrlinfo; diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c index 6d0eb0f42..7bfba196f 100644 --- a/drivers/isdn/hysdn/hysdn_boot.c +++ b/drivers/isdn/hysdn/hysdn_boot.c @@ -30,17 +30,17 @@ /* needed during boot and so allocated dynamically. */ /************************************************************/ struct boot_data { - unsigned short Cryptor; /* for use with Decrypt function */ - unsigned short Nrecs; /* records remaining in file */ - unsigned char pof_state;/* actual state of read handler */ - unsigned char is_crypted;/* card data is crypted */ + word Cryptor; /* for use with Decrypt function */ + word Nrecs; /* records remaining in file */ + uchar pof_state; /* actual state of read handler */ + uchar is_crypted; /* card data is crypted */ int BufSize; /* actual number of bytes bufferd */ int last_error; /* last occurred error */ - unsigned short pof_recid;/* actual pof recid */ - unsigned long pof_reclen;/* total length of pof record data */ - unsigned long pof_recoffset;/* actual offset inside pof record */ + word pof_recid; /* actual pof recid */ + ulong pof_reclen; /* total length of pof record data */ + ulong pof_recoffset; /* actual offset inside pof record */ union { - unsigned char BootBuf[BOOT_BUF_SIZE];/* buffer as byte count */ + uchar BootBuf[BOOT_BUF_SIZE]; /* buffer as byte count */ tPofRecHdr PofRecHdr; /* header for actual record/chunk */ tPofFileHdr PofFileHdr; /* header from POF file */ tPofTimeStamp PofTime; /* time information */ @@ -69,11 +69,11 @@ StartDecryption(struct boot_data *boot) static void DecryptBuf(struct boot_data *boot, int cnt) { - unsigned char *bufp = boot->buf.BootBuf; + uchar *bufp = boot->buf.BootBuf; while (cnt--) { boot->Cryptor = (boot->Cryptor >> 1) ^ ((boot->Cryptor & 1U) ? CRYPT_FEEDTERM : 0); - *bufp++ ^= (unsigned char)boot->Cryptor; + *bufp++ ^= (uchar) boot->Cryptor; } } /* DecryptBuf */ @@ -86,7 +86,7 @@ pof_handle_data(hysdn_card * card, int datlen) { struct boot_data *boot = card->boot; /* pointer to boot specific data */ long l; - unsigned char *imgp; + uchar *imgp; int img_len; /* handle the different record types */ @@ -197,7 +197,7 @@ pof_write_buffer(hysdn_card * card, int datlen) break; } /* Setup the new state and vars */ - boot->Nrecs = (unsigned short)(boot->buf.PofFileHdr.N_PofRecs); /* limited to 65535 */ + boot->Nrecs = (word) (boot->buf.PofFileHdr.N_PofRecs); /* limited to 65535 */ boot->pof_state = POF_READ_TAG_HEAD; /* now start with single tags */ boot->last_error = sizeof(tPofRecHdr); /* new length */ break; @@ -268,7 +268,7 @@ pof_write_buffer(hysdn_card * card, int datlen) /* occurred. Additionally the pointer to the buffer data area is set on success */ /*******************************************************************************/ int -pof_write_open(hysdn_card * card, unsigned char **bufp) +pof_write_open(hysdn_card * card, uchar ** bufp) { struct boot_data *boot; /* pointer to boot specific data */ @@ -335,7 +335,7 @@ pof_write_close(hysdn_card * card) /* when POF has been booted. A return value of 0 is used if no error occurred. */ /*********************************************************************************/ int -EvalSysrTokData(hysdn_card *card, unsigned char *cp, int len) +EvalSysrTokData(hysdn_card * card, uchar * cp, int len) { u_char *p; u_char crc; diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h index 3a9b29b38..432f6f990 100644 --- a/drivers/isdn/hysdn/hysdn_defs.h +++ b/drivers/isdn/hysdn/hysdn_defs.h @@ -20,6 +20,14 @@ #include #include +/****************************/ +/* storage type definitions */ +/****************************/ +#define uchar unsigned char +#define uint unsigned int +#define ulong unsigned long +#define word unsigned short + #include "ince1pc.h" #ifdef CONFIG_HYSDN_CAPI @@ -139,18 +147,18 @@ typedef struct HYSDN_CARD { /* general variables for the cards */ int myid; /* own driver card id */ - unsigned char bus; /* pci bus the card is connected to */ - unsigned char devfn; /* slot+function bit encoded */ - unsigned short subsysid;/* PCI subsystem id */ - unsigned char brdtype; /* type of card */ - unsigned int bchans; /* number of available B-channels */ - unsigned int faxchans; /* number of available fax-channels */ - unsigned char mac_addr[6];/* MAC Address read from card */ - unsigned int irq; /* interrupt number */ - unsigned int iobase; /* IO-port base address */ - unsigned long plxbase; /* PLX memory base */ - unsigned long membase; /* DPRAM memory base */ - unsigned long memend; /* DPRAM memory end */ + uchar bus; /* pci bus the card is connected to */ + uchar devfn; /* slot+function bit encoded */ + word subsysid; /* PCI subsystem id */ + uchar brdtype; /* type of card */ + uint bchans; /* number of available B-channels */ + uint faxchans; /* number of available fax-channels */ + uchar mac_addr[6]; /* MAC Address read from card */ + uint irq; /* interrupt number */ + uint iobase; /* IO-port base address */ + ulong plxbase; /* PLX memory base */ + ulong membase; /* DPRAM memory base */ + ulong memend; /* DPRAM memory end */ void *dpram; /* mapped dpram */ int state; /* actual state of card -> CARD_STATE_** */ struct HYSDN_CARD *next; /* pointer to next card */ @@ -160,26 +168,26 @@ typedef struct HYSDN_CARD { void *procconf; /* pointer to procconf filesystem specific data */ /* debugging and logging */ - unsigned char err_log_state;/* actual error log state of the card */ - unsigned long debug_flags;/* tells what should be debugged and where */ + uchar err_log_state; /* actual error log state of the card */ + ulong debug_flags; /* tells what should be debugged and where */ void (*set_errlog_state) (struct HYSDN_CARD *, int); /* interrupt handler + interrupt synchronisation */ struct work_struct irq_queue; /* interrupt task queue */ - unsigned char volatile irq_enabled;/* interrupt enabled if != 0 */ - unsigned char volatile hw_lock;/* hardware is currently locked -> no access */ + uchar volatile irq_enabled; /* interrupt enabled if != 0 */ + uchar volatile hw_lock; /* hardware is currently locked -> no access */ /* boot process */ void *boot; /* pointer to boot private data */ - int (*writebootimg) (struct HYSDN_CARD *, unsigned char *, unsigned long); - int (*writebootseq) (struct HYSDN_CARD *, unsigned char *, int); + int (*writebootimg) (struct HYSDN_CARD *, uchar *, ulong); + int (*writebootseq) (struct HYSDN_CARD *, uchar *, int); int (*waitpofready) (struct HYSDN_CARD *); int (*testram) (struct HYSDN_CARD *); /* scheduler for data transfer (only async parts) */ - unsigned char async_data[256];/* async data to be sent (normally for config) */ - unsigned short volatile async_len;/* length of data to sent */ - unsigned short volatile async_channel;/* channel number for async transfer */ + uchar async_data[256]; /* async data to be sent (normally for config) */ + word volatile async_len; /* length of data to sent */ + word volatile async_channel; /* channel number for async transfer */ int volatile async_busy; /* flag != 0 sending in progress */ int volatile net_tx_busy; /* a network packet tx is in progress */ @@ -243,18 +251,15 @@ extern int ergo_inithardware(hysdn_card * card); /* get hardware -> module init /* hysdn_boot.c */ extern int pof_write_close(hysdn_card *); /* close proc file after writing pof */ -extern int pof_write_open(hysdn_card *, unsigned char **); /* open proc file for writing pof */ +extern int pof_write_open(hysdn_card *, uchar **); /* open proc file for writing pof */ extern int pof_write_buffer(hysdn_card *, int); /* write boot data to card */ -extern int EvalSysrTokData(hysdn_card *, unsigned char *, int); /* Check Sysready Token Data */ +extern int EvalSysrTokData(hysdn_card *, uchar *, int); /* Check Sysready Token Data */ /* hysdn_sched.c */ -extern int hysdn_sched_tx(hysdn_card *, unsigned char *, - unsigned short volatile *, unsigned short volatile *, - unsigned short); -extern int hysdn_sched_rx(hysdn_card *, unsigned char *, unsigned short, - unsigned short); -extern int hysdn_tx_cfgline(hysdn_card *, unsigned char *, - unsigned short); /* send one cfg line */ +extern int hysdn_sched_tx(hysdn_card *, uchar *, word volatile *, word volatile *, + word); +extern int hysdn_sched_rx(hysdn_card *, uchar *, word, word); +extern int hysdn_tx_cfgline(hysdn_card *, uchar *, word); /* send one cfg line */ /* hysdn_net.c */ extern unsigned int hynet_enable; @@ -264,16 +269,14 @@ extern int hysdn_net_release(hysdn_card *); /* delete the device */ extern char *hysdn_net_getname(hysdn_card *); /* get name of net interface */ extern void hysdn_tx_netack(hysdn_card *); /* acknowledge a packet tx */ extern struct sk_buff *hysdn_tx_netget(hysdn_card *); /* get next network packet */ -extern void hysdn_rx_netpkt(hysdn_card *, unsigned char *, - unsigned short); /* rxed packet from network */ +extern void hysdn_rx_netpkt(hysdn_card *, uchar *, word); /* rxed packet from network */ #ifdef CONFIG_HYSDN_CAPI extern unsigned int hycapi_enable; extern int hycapi_capi_create(hysdn_card *); /* create a new capi device */ extern int hycapi_capi_release(hysdn_card *); /* delete the device */ extern int hycapi_capi_stop(hysdn_card *card); /* suspend */ -extern void hycapi_rx_capipkt(hysdn_card * card, unsigned char * buf, - unsigned short len); +extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len); extern void hycapi_tx_capiack(hysdn_card * card); extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card); extern int hycapi_init(void); diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c index b75ac5af2..cb791f8e7 100644 --- a/drivers/isdn/hysdn/hysdn_init.c +++ b/drivers/isdn/hysdn/hysdn_init.c @@ -41,8 +41,8 @@ hysdn_card *card_root = NULL; /* pointer to first card */ /* the last entry contains all 0 */ /**********************************************/ static struct { - unsigned short subid; /* PCI sub id */ - unsigned char cardtyp; /* card type assigned */ + word subid; /* PCI sub id */ + uchar cardtyp; /* card type assigned */ } pci_subid_map[] = { { diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c index d205249a1..aa01628d7 100644 --- a/drivers/isdn/hysdn/hysdn_net.c +++ b/drivers/isdn/hysdn/hysdn_net.c @@ -24,7 +24,7 @@ #include "hysdn_defs.h" unsigned int hynet_enable = 0xffffffff; -module_param(hynet_enable, uint, 0); +MODULE_PARM(hynet_enable, "i"); /* store the actual version for log reporting */ char *hysdn_net_revision = "$Revision: 1.8.6.4 $"; @@ -83,12 +83,12 @@ net_open(struct net_device *dev) /* Fill in the MAC-level header (if not already set) */ if (!card->mac_addr[0]) { - for (i = 0; i < ETH_ALEN - sizeof(unsigned long); i++) + for (i = 0; i < ETH_ALEN - sizeof(ulong); i++) dev->dev_addr[i] = 0xfc; if ((in_dev = dev->ip_ptr) != NULL) { struct in_ifaddr *ifa = in_dev->ifa_list; if (ifa != NULL) - memcpy(dev->dev_addr + (ETH_ALEN - sizeof(unsigned long)), &ifa->ifa_local, sizeof(unsigned long)); + memcpy(dev->dev_addr + (ETH_ALEN - sizeof(ulong)), &ifa->ifa_local, sizeof(ulong)); } } else memcpy(dev->dev_addr, card->mac_addr, ETH_ALEN); @@ -197,7 +197,7 @@ hysdn_tx_netack(hysdn_card * card) /* we got a packet from the network, go and queue it */ /*****************************************************/ void -hysdn_rx_netpkt(hysdn_card * card, unsigned char *buf, unsigned short len) +hysdn_rx_netpkt(hysdn_card * card, uchar * buf, word len) { struct net_local *lp = card->netif; struct sk_buff *skb; diff --git a/drivers/isdn/hysdn/hysdn_pof.h b/drivers/isdn/hysdn/hysdn_pof.h index a368d6cac..6cd81b9b0 100644 --- a/drivers/isdn/hysdn/hysdn_pof.h +++ b/drivers/isdn/hysdn/hysdn_pof.h @@ -47,20 +47,20 @@ /*--------------------------------------POF file record structs------------*/ typedef struct PofFileHdr_tag { /* Pof file header */ -/*00 */ unsigned long Magic __attribute__((packed)); -/*04 */ unsigned long N_PofRecs __attribute__((packed)); +/*00 */ ulong Magic __attribute__((packed)); +/*04 */ ulong N_PofRecs __attribute__((packed)); /*08 */ } tPofFileHdr; typedef struct PofRecHdr_tag { /* Pof record header */ -/*00 */ unsigned short PofRecId __attribute__((packed)); -/*02 */ unsigned long PofRecDataLen __attribute__((packed)); +/*00 */ word PofRecId __attribute__((packed)); +/*02 */ ulong PofRecDataLen __attribute__((packed)); /*06 */ } tPofRecHdr; typedef struct PofTimeStamp_tag { -/*00 */ unsigned long UnixTime __attribute__((packed)); - /*04 */ unsigned char DateTimeText[0x28] __attribute__((packed)); +/*00 */ ulong UnixTime __attribute__((packed)); + /*04 */ uchar DateTimeText[0x28] __attribute__((packed)); /* =40 */ /*2C */ } tPofTimeStamp; diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index 8e2b03889..40e56143c 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c @@ -36,9 +36,9 @@ struct conf_writedata { int buf_size; /* actual number of bytes in the buffer */ int needed_size; /* needed size when reading pof */ int state; /* actual interface states from above constants */ - unsigned char conf_line[CONF_LINE_LEN]; /* buffered conf line */ - unsigned short channel; /* active channel number */ - unsigned char *pof_buffer; /* buffer when writing pof */ + uchar conf_line[CONF_LINE_LEN]; /* buffered conf line */ + word channel; /* active channel number */ + uchar *pof_buffer; /* buffer when writing pof */ }; /***********************************************************************/ @@ -49,7 +49,7 @@ struct conf_writedata { static int process_line(struct conf_writedata *cnf) { - unsigned char *cp = cnf->conf_line; + uchar *cp = cnf->conf_line; int i; if (cnf->card->debug_flags & LOG_CNF_LINE) @@ -92,7 +92,7 @@ hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t { struct conf_writedata *cnf; int i; - unsigned char ch, *cp; + uchar ch, *cp; if (!count) return (0); /* nothing to handle */ @@ -390,7 +390,7 @@ int hysdn_procconf_init(void) { hysdn_card *card; - unsigned char conf_name[20]; + uchar conf_name[20]; hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, proc_net); if (!hysdn_proc_entry) { @@ -423,7 +423,7 @@ void hysdn_procconf_release(void) { hysdn_card *card; - unsigned char conf_name[20]; + uchar conf_name[20]; card = card_root; /* start with first card */ while (card) { diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index c4301e833..6c26f1efa 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -28,7 +28,7 @@ static void put_log_buffer(hysdn_card * card, char *cp); /*************************************************/ struct log_data { struct log_data *next; - unsigned long usage_cnt;/* number of files still to work */ + ulong usage_cnt; /* number of files still to work */ void *proc_ctrl; /* pointer to own control procdata structure */ char log_start[2]; /* log string start (final len aligned by size) */ }; @@ -42,7 +42,7 @@ struct procdata { struct log_data *log_head, *log_tail; /* head and tail for queue */ int if_used; /* open count for interface */ int volatile del_lock; /* lock for delete operations */ - unsigned char logtmp[LOG_MAX_LINELEN]; + uchar logtmp[LOG_MAX_LINELEN]; wait_queue_head_t rd_queue; }; @@ -153,9 +153,9 @@ put_log_buffer(hysdn_card * card, char *cp) static ssize_t hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t * off) { - unsigned long u = 0; + ulong u = 0; int found = 0; - unsigned char *cp, valbuf[128]; + uchar *cp, valbuf[128]; long base = 10; hysdn_card *card = (hysdn_card *) file->private_data; @@ -249,7 +249,7 @@ hysdn_log_open(struct inode *ino, struct file *filep) { hysdn_card *card; struct procdata *pd = NULL; - unsigned long flags; + ulong flags; lock_kernel(); card = card_root; diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c index 133032920..4fa3b0170 100644 --- a/drivers/isdn/hysdn/hysdn_sched.c +++ b/drivers/isdn/hysdn/hysdn_sched.c @@ -30,8 +30,7 @@ /* to keep the data until later. */ /*****************************************************************************/ int -hysdn_sched_rx(hysdn_card *card, unsigned char *buf, unsigned short len, - unsigned short chan) +hysdn_sched_rx(hysdn_card * card, uchar * buf, word len, word chan) { switch (chan) { @@ -73,9 +72,7 @@ hysdn_sched_rx(hysdn_card *card, unsigned char *buf, unsigned short len, /* sending. */ /*****************************************************************************/ int -hysdn_sched_tx(hysdn_card *card, unsigned char *buf, - unsigned short volatile *len, unsigned short volatile *chan, - unsigned short maxlen) +hysdn_sched_tx(hysdn_card * card, uchar * buf, word volatile *len, word volatile *chan, word maxlen) { struct sk_buff *skb; @@ -148,10 +145,10 @@ hysdn_sched_tx(hysdn_card *card, unsigned char *buf, /* are to be sent and this happens very seldom. */ /*****************************************************************************/ int -hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) +hysdn_tx_cfgline(hysdn_card * card, uchar * line, word chan) { int cnt = 50; /* timeout intervalls */ - unsigned long flags; + ulong flags; if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); diff --git a/drivers/isdn/hysdn/ince1pc.h b/drivers/isdn/hysdn/ince1pc.h index 7a36694df..4a115a87c 100644 --- a/drivers/isdn/hysdn/ince1pc.h +++ b/drivers/isdn/hysdn/ince1pc.h @@ -62,7 +62,7 @@ * s. RotlCRC algorithm * * RotlCRC algorithm: - * ucSum= 0 1 unsigned char + * ucSum= 0 1 uchar * for all NonEndTokenChunk bytes: * ROTL(ucSum,1) rotate left by 1 * ucSum += Char; add current byte with swap around @@ -85,13 +85,13 @@ typedef struct ErrLogEntry_tag { -/*00 */ unsigned long ulErrType; +/*00 */ ulong ulErrType; -/*04 */ unsigned long ulErrSubtype; +/*04 */ ulong ulErrSubtype; -/*08 */ unsigned char ucTextSize; +/*08 */ uchar ucTextSize; - /*09 */ unsigned char ucText[ERRLOG_TEXT_SIZE]; + /*09 */ uchar ucText[ERRLOG_TEXT_SIZE]; /* ASCIIZ of len ucTextSize-1 */ /*40 */ @@ -111,13 +111,13 @@ typedef struct ErrLogEntry_tag { #define DPRAM_SPOOLER_DATA_SIZE 0x20 typedef struct DpramBootSpooler_tag { -/*00 */ unsigned char Len; +/*00 */ uchar Len; -/*01 */ volatile unsigned char RdPtr; +/*01 */ volatile uchar RdPtr; -/*02 */ unsigned char WrPtr; +/*02 */ uchar WrPtr; -/*03 */ unsigned char Data[DPRAM_SPOOLER_DATA_SIZE]; +/*03 */ uchar Data[DPRAM_SPOOLER_DATA_SIZE]; /*23 */ } tDpramBootSpooler; diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index a4f7288a1..1789b607f 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig @@ -139,4 +139,3 @@ source "drivers/isdn/hysdn/Kconfig" endmenu -source "drivers/isdn/gigaset/Kconfig" diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 22759c017..4cd1a5a0b 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -1125,9 +1125,12 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off) if (dev->drv[drvidx]->interface->readstat) { if (count > dev->drv[drvidx]->stavail) count = dev->drv[drvidx]->stavail; - len = dev->drv[drvidx]->interface-> - readstat(buf, count, drvidx, - isdn_minor2chan(minor)); + len = dev->drv[drvidx]->interface->readstat(buf, count, + drvidx, isdn_minor2chan(minor)); + if (len < 0) { + retval = len; + goto out; + } } else { len = 0; } diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 918742271..b3f0e01f7 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -109,7 +109,7 @@ isdn_ppp_free(isdn_net_local * lp) { struct ippp_struct *is; - if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { + if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: ppp_slot(%d) out of range\n", __FUNCTION__, lp->ppp_slot); return 0; @@ -126,7 +126,7 @@ isdn_ppp_free(isdn_net_local * lp) lp->netdev->pb->ref_ct--; spin_unlock(&lp->netdev->pb->lock); #endif /* CONFIG_ISDN_MPP */ - if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { + if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: ppp_slot(%d) now invalid\n", __FUNCTION__, lp->ppp_slot); return 0; @@ -279,7 +279,7 @@ isdn_ppp_open(int min, struct file *file) int slot; struct ippp_struct *is; - if (min < 0 || min >= ISDN_MAX_CHANNELS) + if (min < 0 || min > ISDN_MAX_CHANNELS) return -ENODEV; slot = isdn_ppp_get_slot(); @@ -782,8 +782,7 @@ isdn_ppp_read(int min, struct file *file, char __user *buf, int count) is->first = b; spin_unlock_irqrestore(&is->buflock, flags); - if (copy_to_user(buf, save_buf, count)) - count = -EFAULT; + copy_to_user(buf, save_buf, count); kfree(save_buf); return count; @@ -974,7 +973,8 @@ void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buf int slot; int proto; - BUG_ON(net_dev->local->master); // we're called with the master device always + if (net_dev->local->master) + BUG(); // we're called with the master device always slot = lp->ppp_slot; if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { @@ -1042,7 +1042,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff if (lp->master) { // FIXME? mlp = (isdn_net_local *) lp->master->priv; slot = mlp->ppp_slot; - if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { + if (slot < 0 || slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n", lp->ppp_slot); goto drop_packet; @@ -1264,7 +1264,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) /* we have our lp locked from now on */ slot = lp->ppp_slot; - if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { + if (slot < 0 || slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n", lp->ppp_slot); kfree_skb(skb); @@ -1603,7 +1603,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, mp = net_dev->pb; stats = &mp->stats; slot = lp->ppp_slot; - if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { + if (slot < 0 || slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: lp->ppp_slot(%d)\n", __FUNCTION__, lp->ppp_slot); stats->frame_drops++; @@ -1640,7 +1640,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, is->last_link_seqno = minseq = newseq; for (lpq = net_dev->queue;;) { slot = lpq->ppp_slot; - if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { + if (slot < 0 || slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n", __FUNCTION__, lpq->ppp_slot); } else { @@ -2346,6 +2346,7 @@ static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_s rs->state = CCPResetIdle; rs->is = is; rs->id = id; + init_timer(&rs->timer); rs->timer.data = (unsigned long)rs; rs->timer.function = isdn_ppp_ccp_timer_callback; is->reset->rs[id] = rs; @@ -2526,7 +2527,8 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc printk(KERN_DEBUG "ippp: no decompressor defined!\n"); return skb; } - BUG_ON(!stat); // if we have a compressor, stat has been set as well + if (!stat) // if we have a compressor, stat has been set as well + BUG(); if((master && *proto == PPP_COMP) || (!master && *proto == PPP_COMPFRAG) ) { // compressed packets are compressed by their protocol type @@ -2648,7 +2650,7 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, printk(KERN_DEBUG "Received CCP frame from peer slot(%d)\n", lp->ppp_slot); - if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { + if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", __FUNCTION__, lp->ppp_slot); return; @@ -2658,7 +2660,7 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, if(lp->master) { int slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot; - if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { + if (slot < 0 || slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: slot(%d) out of range\n", __FUNCTION__, slot); return; @@ -2845,7 +2847,7 @@ static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct if (lp->master) { slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot; - if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { + if (slot < 0 || slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: slot(%d) out of range\n", __FUNCTION__, slot); return; diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 2ac90242d..aeaa1db74 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -2345,15 +2345,12 @@ isdn_tty_at_cout(char *msg, modem_info * info) u_long flags; struct sk_buff *skb = NULL; char *sp = NULL; - int l; + int l = strlen(msg); if (!msg) { printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); return; } - - l = strlen(msg); - spin_lock_irqsave(&info->readlock, flags); tty = info->tty; if ((info->flags & ISDN_ASYNC_CLOSING) || (!tty)) { @@ -2880,7 +2877,7 @@ isdn_tty_cmd_ATand(char **p, modem_info * info) p[0]++; i = 0; while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) && - (i < ISDN_LMSNLEN - 1)) + (i < ISDN_LMSNLEN)) m->lmsn[i++] = *p[0]++; m->lmsn[i] = '\0'; break; diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c index 743ac4077..edf14a2aa 100644 --- a/drivers/isdn/i4l/isdn_x25iface.c +++ b/drivers/isdn/i4l/isdn_x25iface.c @@ -7,7 +7,7 @@ * * stuff needed to support the Linux X.25 PLP code on top of devices that * can provide a lab_b service using the concap_proto mechanism. - * This module supports a network interface which provides lapb_sematics + * This module supports a network interface wich provides lapb_sematics * -- as defined in Documentation/networking/x25-iface.txt -- to * the upper layer and assumes that the lower layer provides a reliable * data link service by means of the concap_device_ops callbacks. diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index a67d31af7..33d339700 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c @@ -22,7 +22,7 @@ static char *isdnloop_id = "loop0"; MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); MODULE_AUTHOR("Fritz Elfert"); MODULE_LICENSE("GPL"); -module_param(isdnloop_id, charp, 0); +MODULE_PARM(isdnloop_id, "s"); MODULE_PARM_DESC(isdnloop_id, "ID-String of first card"); static int isdnloop_addcard(char *); diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index f4f71226a..94c9afb70 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c @@ -46,8 +46,7 @@ int sc_ioctl(int card, scs_ioctl *data) pr_debug("%s: SCIOCRESET: ioctl received\n", sc_adapter[card]->devicename); sc_adapter[card]->StartOnReset = 0; - kfree(rcvmsg); - return reset(card); + return (reset(card)); } case SCIOCLOAD: @@ -184,7 +183,7 @@ int sc_ioctl(int card, scs_ioctl *data) sc_adapter[card]->devicename); spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); - if (!spid) { + if(!spid) { kfree(rcvmsg); return -ENOMEM; } @@ -196,10 +195,10 @@ int sc_ioctl(int card, scs_ioctl *data) if (!status) { pr_debug("%s: SCIOCGETSPID: command successful\n", sc_adapter[card]->devicename); - } else { + } + else { pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n", sc_adapter[card]->devicename, status); - kfree(spid); kfree(rcvmsg); return status; } diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig deleted file mode 100644 index 626506234..000000000 --- a/drivers/leds/Kconfig +++ /dev/null @@ -1,91 +0,0 @@ - -menu "LED devices" - -config NEW_LEDS - bool "LED Support" - help - Say Y to enable Linux LED support. This allows control of supported - LEDs from both userspace and optionally, by kernel events (triggers). - - This is not related to standard keyboard LEDs which are controlled - via the input system. - -config LEDS_CLASS - tristate "LED Class Support" - depends NEW_LEDS - help - This option enables the led sysfs class in /sys/class/leds. You'll - need this to do anything useful with LEDs. If unsure, say N. - -comment "LED drivers" - -config LEDS_CORGI - tristate "LED Support for the Sharp SL-C7x0 series" - depends LEDS_CLASS && PXA_SHARP_C7xx - help - This option enables support for the LEDs on Sharp Zaurus - SL-C7x0 series (C700, C750, C760, C860). - -config LEDS_LOCOMO - tristate "LED Support for Locomo device" - depends LEDS_CLASS && SHARP_LOCOMO - help - This option enables support for the LEDs on Sharp Locomo. - Zaurus models SL-5500 and SL-5600. - -config LEDS_SPITZ - tristate "LED Support for the Sharp SL-Cxx00 series" - depends LEDS_CLASS && PXA_SHARP_Cxx00 - help - This option enables support for the LEDs on Sharp Zaurus - SL-Cxx00 series (C1000, C3000, C3100). - -config LEDS_IXP4XX - tristate "LED Support for GPIO connected LEDs on IXP4XX processors" - depends LEDS_CLASS && ARCH_IXP4XX - help - This option enables support for the LEDs connected to GPIO - outputs of the Intel IXP4XX processors. To be useful the - particular board must have LEDs and they must be connected - to the GPIO lines. If unsure, say Y. - -config LEDS_TOSA - tristate "LED Support for the Sharp SL-6000 series" - depends LEDS_CLASS && PXA_SHARPSL - help - This option enables support for the LEDs on Sharp Zaurus - SL-6000 series. - -config LEDS_S3C24XX - tristate "LED Support for Samsung S3C24XX GPIO LEDs" - depends on LEDS_CLASS && ARCH_S3C2410 - help - This option enables support for LEDs connected to GPIO lines - on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. - -comment "LED Triggers" - -config LEDS_TRIGGERS - bool "LED Trigger support" - depends NEW_LEDS - help - This option enables trigger support for the leds class. - These triggers allow kernel events to drive the LEDs and can - be configured via sysfs. If unsure, say Y. - -config LEDS_TRIGGER_TIMER - tristate "LED Timer Trigger" - depends LEDS_TRIGGERS - help - This allows LEDs to be controlled by a programmable timer - via sysfs. If unsure, say Y. - -config LEDS_TRIGGER_IDE_DISK - bool "LED IDE Disk Trigger" - depends LEDS_TRIGGERS && BLK_DEV_IDEDISK - help - This allows LEDs to be controlled by IDE disk activity. - If unsure, say Y. - -endmenu - diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile deleted file mode 100644 index 40f042633..000000000 --- a/drivers/leds/Makefile +++ /dev/null @@ -1,17 +0,0 @@ - -# LED Core -obj-$(CONFIG_NEW_LEDS) += led-core.o -obj-$(CONFIG_LEDS_CLASS) += led-class.o -obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o - -# LED Platform Drivers -obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o -obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o -obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o -obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o -obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o -obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o - -# LED Triggers -obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o -obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c deleted file mode 100644 index c75d0ef16..000000000 --- a/drivers/leds/led-class.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * LED Class Core - * - * Copyright (C) 2005 John Lenz - * Copyright (C) 2005-2006 Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "leds.h" - -static struct class *leds_class; - -static ssize_t led_brightness_show(struct class_device *dev, char *buf) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - ssize_t ret = 0; - - /* no lock needed for this */ - sprintf(buf, "%u\n", led_cdev->brightness); - ret = strlen(buf) + 1; - - return ret; -} - -static ssize_t led_brightness_store(struct class_device *dev, - const char *buf, size_t size) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - ssize_t ret = -EINVAL; - char *after; - unsigned long state = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - - if (*after && isspace(*after)) - count++; - - if (count == size) { - ret = count; - led_set_brightness(led_cdev, state); - } - - return ret; -} - -static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show, - led_brightness_store); -#ifdef CONFIG_LEDS_TRIGGERS -static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); -#endif - -/** - * led_classdev_suspend - suspend an led_classdev. - * @led_cdev: the led_classdev to suspend. - */ -void led_classdev_suspend(struct led_classdev *led_cdev) -{ - led_cdev->flags |= LED_SUSPENDED; - led_cdev->brightness_set(led_cdev, 0); -} -EXPORT_SYMBOL_GPL(led_classdev_suspend); - -/** - * led_classdev_resume - resume an led_classdev. - * @led_cdev: the led_classdev to resume. - */ -void led_classdev_resume(struct led_classdev *led_cdev) -{ - led_cdev->brightness_set(led_cdev, led_cdev->brightness); - led_cdev->flags &= ~LED_SUSPENDED; -} -EXPORT_SYMBOL_GPL(led_classdev_resume); - -/** - * led_classdev_register - register a new object of led_classdev class. - * @dev: The device to register. - * @led_cdev: the led_classdev structure for this device. - */ -int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) -{ - led_cdev->class_dev = class_device_create(leds_class, NULL, 0, - parent, "%s", led_cdev->name); - if (unlikely(IS_ERR(led_cdev->class_dev))) - return PTR_ERR(led_cdev->class_dev); - - class_set_devdata(led_cdev->class_dev, led_cdev); - - /* register the attributes */ - class_device_create_file(led_cdev->class_dev, - &class_device_attr_brightness); - - /* add to the list of leds */ - write_lock(&leds_list_lock); - list_add_tail(&led_cdev->node, &leds_list); - write_unlock(&leds_list_lock); - -#ifdef CONFIG_LEDS_TRIGGERS - rwlock_init(&led_cdev->trigger_lock); - - led_trigger_set_default(led_cdev); - - class_device_create_file(led_cdev->class_dev, - &class_device_attr_trigger); -#endif - - printk(KERN_INFO "Registered led device: %s\n", - led_cdev->class_dev->class_id); - - return 0; -} -EXPORT_SYMBOL_GPL(led_classdev_register); - -/** - * led_classdev_unregister - unregisters a object of led_properties class. - * @led_cdev: the led device to unreigister - * - * Unregisters a previously registered via led_classdev_register object. - */ -void led_classdev_unregister(struct led_classdev *led_cdev) -{ - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_brightness); -#ifdef CONFIG_LEDS_TRIGGERS - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_trigger); - write_lock(&led_cdev->trigger_lock); - if (led_cdev->trigger) - led_trigger_set(led_cdev, NULL); - write_unlock(&led_cdev->trigger_lock); -#endif - - class_device_unregister(led_cdev->class_dev); - - write_lock(&leds_list_lock); - list_del(&led_cdev->node); - write_unlock(&leds_list_lock); -} -EXPORT_SYMBOL_GPL(led_classdev_unregister); - -static int __init leds_init(void) -{ - leds_class = class_create(THIS_MODULE, "leds"); - if (IS_ERR(leds_class)) - return PTR_ERR(leds_class); - return 0; -} - -static void __exit leds_exit(void) -{ - class_destroy(leds_class); -} - -subsys_initcall(leds_init); -module_exit(leds_exit); - -MODULE_AUTHOR("John Lenz, Richard Purdie"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("LED Class Interface"); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c deleted file mode 100644 index fe6541326..000000000 --- a/drivers/leds/led-core.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * LED Class Core - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include "leds.h" - -rwlock_t leds_list_lock = RW_LOCK_UNLOCKED; -LIST_HEAD(leds_list); - -EXPORT_SYMBOL_GPL(leds_list); -EXPORT_SYMBOL_GPL(leds_list_lock); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c deleted file mode 100644 index 5e2cd8be1..000000000 --- a/drivers/leds/led-triggers.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * LED Triggers Core - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "leds.h" - -/* - * Nests outside led_cdev->trigger_lock - */ -static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED; -static LIST_HEAD(trigger_list); - -ssize_t led_trigger_store(struct class_device *dev, const char *buf, - size_t count) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - char trigger_name[TRIG_NAME_MAX]; - struct led_trigger *trig; - size_t len; - - trigger_name[sizeof(trigger_name) - 1] = '\0'; - strncpy(trigger_name, buf, sizeof(trigger_name) - 1); - len = strlen(trigger_name); - - if (len && trigger_name[len - 1] == '\n') - trigger_name[len - 1] = '\0'; - - if (!strcmp(trigger_name, "none")) { - write_lock(&led_cdev->trigger_lock); - led_trigger_set(led_cdev, NULL); - write_unlock(&led_cdev->trigger_lock); - return count; - } - - read_lock(&triggers_list_lock); - list_for_each_entry(trig, &trigger_list, next_trig) { - if (!strcmp(trigger_name, trig->name)) { - write_lock(&led_cdev->trigger_lock); - led_trigger_set(led_cdev, trig); - write_unlock(&led_cdev->trigger_lock); - - read_unlock(&triggers_list_lock); - return count; - } - } - read_unlock(&triggers_list_lock); - - return -EINVAL; -} - - -ssize_t led_trigger_show(struct class_device *dev, char *buf) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct led_trigger *trig; - int len = 0; - - read_lock(&triggers_list_lock); - read_lock(&led_cdev->trigger_lock); - - if (!led_cdev->trigger) - len += sprintf(buf+len, "[none] "); - else - len += sprintf(buf+len, "none "); - - list_for_each_entry(trig, &trigger_list, next_trig) { - if (led_cdev->trigger && !strcmp(led_cdev->trigger->name, - trig->name)) - len += sprintf(buf+len, "[%s] ", trig->name); - else - len += sprintf(buf+len, "%s ", trig->name); - } - read_unlock(&led_cdev->trigger_lock); - read_unlock(&triggers_list_lock); - - len += sprintf(len+buf, "\n"); - return len; -} - -void led_trigger_event(struct led_trigger *trigger, - enum led_brightness brightness) -{ - struct list_head *entry; - - if (!trigger) - return; - - read_lock(&trigger->leddev_list_lock); - list_for_each(entry, &trigger->led_cdevs) { - struct led_classdev *led_cdev; - - led_cdev = list_entry(entry, struct led_classdev, trig_list); - led_set_brightness(led_cdev, brightness); - } - read_unlock(&trigger->leddev_list_lock); -} - -/* Caller must ensure led_cdev->trigger_lock held */ -void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) -{ - unsigned long flags; - - /* Remove any existing trigger */ - if (led_cdev->trigger) { - write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); - list_del(&led_cdev->trig_list); - write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); - if (led_cdev->trigger->deactivate) - led_cdev->trigger->deactivate(led_cdev); - } - if (trigger) { - write_lock_irqsave(&trigger->leddev_list_lock, flags); - list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); - write_unlock_irqrestore(&trigger->leddev_list_lock, flags); - if (trigger->activate) - trigger->activate(led_cdev); - } - led_cdev->trigger = trigger; -} - -void led_trigger_set_default(struct led_classdev *led_cdev) -{ - struct led_trigger *trig; - - if (!led_cdev->default_trigger) - return; - - read_lock(&triggers_list_lock); - write_lock(&led_cdev->trigger_lock); - list_for_each_entry(trig, &trigger_list, next_trig) { - if (!strcmp(led_cdev->default_trigger, trig->name)) - led_trigger_set(led_cdev, trig); - } - write_unlock(&led_cdev->trigger_lock); - read_unlock(&triggers_list_lock); -} - -int led_trigger_register(struct led_trigger *trigger) -{ - struct led_classdev *led_cdev; - - rwlock_init(&trigger->leddev_list_lock); - INIT_LIST_HEAD(&trigger->led_cdevs); - - /* Add to the list of led triggers */ - write_lock(&triggers_list_lock); - list_add_tail(&trigger->next_trig, &trigger_list); - write_unlock(&triggers_list_lock); - - /* Register with any LEDs that have this as a default trigger */ - read_lock(&leds_list_lock); - list_for_each_entry(led_cdev, &leds_list, node) { - write_lock(&led_cdev->trigger_lock); - if (!led_cdev->trigger && led_cdev->default_trigger && - !strcmp(led_cdev->default_trigger, trigger->name)) - led_trigger_set(led_cdev, trigger); - write_unlock(&led_cdev->trigger_lock); - } - read_unlock(&leds_list_lock); - - return 0; -} - -void led_trigger_register_simple(const char *name, struct led_trigger **tp) -{ - struct led_trigger *trigger; - - trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); - - if (trigger) { - trigger->name = name; - led_trigger_register(trigger); - } - *tp = trigger; -} - -void led_trigger_unregister(struct led_trigger *trigger) -{ - struct led_classdev *led_cdev; - - /* Remove from the list of led triggers */ - write_lock(&triggers_list_lock); - list_del(&trigger->next_trig); - write_unlock(&triggers_list_lock); - - /* Remove anyone actively using this trigger */ - read_lock(&leds_list_lock); - list_for_each_entry(led_cdev, &leds_list, node) { - write_lock(&led_cdev->trigger_lock); - if (led_cdev->trigger == trigger) - led_trigger_set(led_cdev, NULL); - write_unlock(&led_cdev->trigger_lock); - } - read_unlock(&leds_list_lock); -} - -void led_trigger_unregister_simple(struct led_trigger *trigger) -{ - led_trigger_unregister(trigger); - kfree(trigger); -} - -/* Used by LED Class */ -EXPORT_SYMBOL_GPL(led_trigger_set); -EXPORT_SYMBOL_GPL(led_trigger_set_default); -EXPORT_SYMBOL_GPL(led_trigger_show); -EXPORT_SYMBOL_GPL(led_trigger_store); - -/* LED Trigger Interface */ -EXPORT_SYMBOL_GPL(led_trigger_register); -EXPORT_SYMBOL_GPL(led_trigger_unregister); - -/* Simple LED Tigger Interface */ -EXPORT_SYMBOL_GPL(led_trigger_register_simple); -EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); -EXPORT_SYMBOL_GPL(led_trigger_event); - -MODULE_AUTHOR("Richard Purdie"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("LED Triggers Core"); diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c deleted file mode 100644 index bb7d84df0..000000000 --- a/drivers/leds/leds-corgi.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * LED Triggers Core - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) -{ - if (value) - GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); - else - GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); -} - -static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightness value) -{ - if (value) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); -} - -static struct led_classdev corgi_amber_led = { - .name = "corgi:amber", - .default_trigger = "sharpsl-charge", - .brightness_set = corgiled_amber_set, -}; - -static struct led_classdev corgi_green_led = { - .name = "corgi:green", - .default_trigger = "nand-disk", - .brightness_set = corgiled_green_set, -}; - -#ifdef CONFIG_PM -static int corgiled_suspend(struct platform_device *dev, pm_message_t state) -{ -#ifdef CONFIG_LEDS_TRIGGERS - if (corgi_amber_led.trigger && strcmp(corgi_amber_led.trigger->name, "sharpsl-charge")) -#endif - led_classdev_suspend(&corgi_amber_led); - led_classdev_suspend(&corgi_green_led); - return 0; -} - -static int corgiled_resume(struct platform_device *dev) -{ - led_classdev_resume(&corgi_amber_led); - led_classdev_resume(&corgi_green_led); - return 0; -} -#endif - -static int corgiled_probe(struct platform_device *pdev) -{ - int ret; - - ret = led_classdev_register(&pdev->dev, &corgi_amber_led); - if (ret < 0) - return ret; - - ret = led_classdev_register(&pdev->dev, &corgi_green_led); - if (ret < 0) - led_classdev_unregister(&corgi_amber_led); - - return ret; -} - -static int corgiled_remove(struct platform_device *pdev) -{ - led_classdev_unregister(&corgi_amber_led); - led_classdev_unregister(&corgi_green_led); - return 0; -} - -static struct platform_driver corgiled_driver = { - .probe = corgiled_probe, - .remove = corgiled_remove, -#ifdef CONFIG_PM - .suspend = corgiled_suspend, - .resume = corgiled_resume, -#endif - .driver = { - .name = "corgi-led", - }, -}; - -static int __init corgiled_init(void) -{ - return platform_driver_register(&corgiled_driver); -} - -static void __exit corgiled_exit(void) -{ - platform_driver_unregister(&corgiled_driver); -} - -module_init(corgiled_init); -module_exit(corgiled_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("Corgi LED driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-ixp4xx-gpio.c b/drivers/leds/leds-ixp4xx-gpio.c deleted file mode 100644 index 30ced150e..000000000 --- a/drivers/leds/leds-ixp4xx-gpio.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * IXP4XX GPIO driver LED driver - * - * Author: John Bowler - * - * Copyright (c) 2006 John Bowler - * - * Permission is hereby granted, free of charge, to any - * person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the - * Software without restriction, including without - * limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice - * shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -extern spinlock_t gpio_lock; - -/* Up to 16 gpio lines are possible. */ -#define GPIO_MAX 16 -static struct ixp4xxgpioled_device { - struct led_classdev ancestor; - int flags; -} ixp4xxgpioled_devices[GPIO_MAX]; - -void ixp4xxgpioled_brightness_set(struct led_classdev *pled, - enum led_brightness value) -{ - const struct ixp4xxgpioled_device *const ixp4xx_dev = - container_of(pled, struct ixp4xxgpioled_device, ancestor); - const u32 gpio_pin = ixp4xx_dev - ixp4xxgpioled_devices; - - if (gpio_pin < GPIO_MAX && ixp4xx_dev->ancestor.name != 0) { - /* Set or clear the 'gpio_pin' bit according to the style - * and the required setting (value > 0 == on) - */ - const int gpio_value = - (value > 0) == (ixp4xx_dev->flags != IXP4XX_GPIO_LOW) ? - IXP4XX_GPIO_HIGH : IXP4XX_GPIO_LOW; - - { - unsigned long flags; - spin_lock_irqsave(&gpio_lock, flags); - gpio_line_set(gpio_pin, gpio_value); - spin_unlock_irqrestore(&gpio_lock, flags); - } - } -} - -/* LEDs are described in resources, the following iterates over the valid - * LED resources. - */ -#define for_all_leds(i, pdev) \ - for (i=0; inum_resources; ++i) \ - if (pdev->resource[i].start < GPIO_MAX && \ - pdev->resource[i].name != 0) - -/* The following applies 'operation' to each LED from the given platform, - * the function always returns 0 to allow tail call elimination. - */ -static int apply_to_all_leds(struct platform_device *pdev, - void (*operation)(struct led_classdev *pled)) -{ - int i; - - for_all_leds(i, pdev) - operation(&ixp4xxgpioled_devices[pdev->resource[i].start].ancestor); - return 0; -} - -#ifdef CONFIG_PM -static int ixp4xxgpioled_suspend(struct platform_device *pdev, - pm_message_t state) -{ - return apply_to_all_leds(pdev, led_classdev_suspend); -} - -static int ixp4xxgpioled_resume(struct platform_device *pdev) -{ - return apply_to_all_leds(pdev, led_classdev_resume); -} -#endif - -static void ixp4xxgpioled_remove_one_led(struct led_classdev *pled) -{ - led_classdev_unregister(pled); - pled->name = 0; -} - -static int ixp4xxgpioled_remove(struct platform_device *pdev) -{ - return apply_to_all_leds(pdev, ixp4xxgpioled_remove_one_led); -} - -static int ixp4xxgpioled_probe(struct platform_device *pdev) -{ - /* The board level has to tell the driver where the - * LEDs are connected - there is no way to find out - * electrically. It must also say whether the GPIO - * lines are active high or active low. - * - * To do this read the num_resources (the number of - * LEDs) and the struct resource (the data for each - * LED). The name comes from the resource, and it - * isn't copied. - */ - int i; - - for_all_leds(i, pdev) { - const u8 gpio_pin = pdev->resource[i].start; - int rc; - - if (ixp4xxgpioled_devices[gpio_pin].ancestor.name == 0) { - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - gpio_line_config(gpio_pin, IXP4XX_GPIO_OUT); - /* The config can, apparently, reset the state, - * I suspect the gpio line may be an input and - * the config may cause the line to be latched, - * so the setting depends on how the LED is - * connected to the line (which affects how it - * floats if not driven). - */ - gpio_line_set(gpio_pin, IXP4XX_GPIO_HIGH); - spin_unlock_irqrestore(&gpio_lock, flags); - - ixp4xxgpioled_devices[gpio_pin].flags = - pdev->resource[i].flags & IORESOURCE_BITS; - - ixp4xxgpioled_devices[gpio_pin].ancestor.name = - pdev->resource[i].name; - - /* This is how a board manufacturer makes the LED - * come on on reset - the GPIO line will be high, so - * make the LED light when the line is low... - */ - if (ixp4xxgpioled_devices[gpio_pin].flags != IXP4XX_GPIO_LOW) - ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 100; - else - ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 0; - - ixp4xxgpioled_devices[gpio_pin].ancestor.flags = 0; - - ixp4xxgpioled_devices[gpio_pin].ancestor.brightness_set = - ixp4xxgpioled_brightness_set; - - ixp4xxgpioled_devices[gpio_pin].ancestor.default_trigger = 0; - } - - rc = led_classdev_register(&pdev->dev, - &ixp4xxgpioled_devices[gpio_pin].ancestor); - if (rc < 0) { - ixp4xxgpioled_devices[gpio_pin].ancestor.name = 0; - ixp4xxgpioled_remove(pdev); - return rc; - } - } - - return 0; -} - -static struct platform_driver ixp4xxgpioled_driver = { - .probe = ixp4xxgpioled_probe, - .remove = ixp4xxgpioled_remove, -#ifdef CONFIG_PM - .suspend = ixp4xxgpioled_suspend, - .resume = ixp4xxgpioled_resume, -#endif - .driver = { - .name = "IXP4XX-GPIO-LED", - }, -}; - -static int __init ixp4xxgpioled_init(void) -{ - return platform_driver_register(&ixp4xxgpioled_driver); -} - -static void __exit ixp4xxgpioled_exit(void) -{ - platform_driver_unregister(&ixp4xxgpioled_driver); -} - -module_init(ixp4xxgpioled_init); -module_exit(ixp4xxgpioled_exit); - -MODULE_AUTHOR("John Bowler "); -MODULE_DESCRIPTION("IXP4XX GPIO LED driver"); -MODULE_LICENSE("Dual MIT/GPL"); diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c deleted file mode 100644 index 749a86c2a..000000000 --- a/drivers/leds/leds-locomo.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * linux/drivers/leds/locomo.c - * - * Copyright (C) 2005 John Lenz - * - * 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 -#include -#include -#include -#include - -#include -#include - -static void locomoled_brightness_set(struct led_classdev *led_cdev, - enum led_brightness value, int offset) -{ - struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->class_dev->dev); - unsigned long flags; - - local_irq_save(flags); - if (value) - locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset); - else - locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset); - local_irq_restore(flags); -} - -static void locomoled_brightness_set0(struct led_classdev *led_cdev, - enum led_brightness value) -{ - locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0); -} - -static void locomoled_brightness_set1(struct led_classdev *led_cdev, - enum led_brightness value) -{ - locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1); -} - -static struct led_classdev locomo_led0 = { - .name = "locomo:amber", - .brightness_set = locomoled_brightness_set0, -}; - -static struct led_classdev locomo_led1 = { - .name = "locomo:green", - .brightness_set = locomoled_brightness_set1, -}; - -static int locomoled_probe(struct locomo_dev *ldev) -{ - int ret; - - ret = led_classdev_register(&ldev->dev, &locomo_led0); - if (ret < 0) - return ret; - - ret = led_classdev_register(&ldev->dev, &locomo_led1); - if (ret < 0) - led_classdev_unregister(&locomo_led0); - - return ret; -} - -static int locomoled_remove(struct locomo_dev *dev) -{ - led_classdev_unregister(&locomo_led0); - led_classdev_unregister(&locomo_led1); - return 0; -} - -static struct locomo_driver locomoled_driver = { - .drv = { - .name = "locomoled" - }, - .devid = LOCOMO_DEVID_LED, - .probe = locomoled_probe, - .remove = locomoled_remove, -}; - -static int __init locomoled_init(void) -{ - return locomo_driver_register(&locomoled_driver); -} -module_init(locomoled_init); - -MODULE_AUTHOR("John Lenz "); -MODULE_DESCRIPTION("Locomo LED driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c deleted file mode 100644 index 650cf72dc..000000000 --- a/drivers/leds/leds-s3c24xx.c +++ /dev/null @@ -1,163 +0,0 @@ -/* drivers/leds/leds-s3c24xx.c - * - * (c) 2006 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * S3C24XX - LEDs GPIO driver - * - * 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 -#include -#include -#include -#include - -#include -#include -#include - -/* our context */ - -struct s3c24xx_gpio_led { - struct led_classdev cdev; - struct s3c24xx_led_platdata *pdata; -}; - -static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev) -{ - return platform_get_drvdata(dev); -} - -static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev) -{ - return container_of(led_cdev, struct s3c24xx_gpio_led, cdev); -} - -static void s3c24xx_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct s3c24xx_gpio_led *led = to_gpio(led_cdev); - struct s3c24xx_led_platdata *pd = led->pdata; - - /* there will be a sort delay between setting the output and - * going from output to input when using tristate. */ - - s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^ - (pd->flags & S3C24XX_LEDF_ACTLOW)); - - if (pd->flags & S3C24XX_LEDF_TRISTATE) - s3c2410_gpio_cfgpin(pd->gpio, - value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT); - -} - -static int s3c24xx_led_remove(struct platform_device *dev) -{ - struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); - - led_classdev_unregister(&led->cdev); - kfree(led); - - return 0; -} - -static int s3c24xx_led_probe(struct platform_device *dev) -{ - struct s3c24xx_led_platdata *pdata = dev->dev.platform_data; - struct s3c24xx_gpio_led *led; - int ret; - - led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL); - if (led == NULL) { - dev_err(&dev->dev, "No memory for device\n"); - return -ENOMEM; - } - - platform_set_drvdata(dev, led); - - led->cdev.brightness_set = s3c24xx_led_set; - led->cdev.default_trigger = pdata->def_trigger; - led->cdev.name = pdata->name; - - led->pdata = pdata; - - /* no point in having a pull-up if we are always driving */ - - if (pdata->flags & S3C24XX_LEDF_TRISTATE) { - s3c2410_gpio_setpin(pdata->gpio, 0); - s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT); - } else { - s3c2410_gpio_pullup(pdata->gpio, 0); - s3c2410_gpio_setpin(pdata->gpio, 0); - s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT); - } - - /* register our new led device */ - - ret = led_classdev_register(&dev->dev, &led->cdev); - if (ret < 0) { - dev_err(&dev->dev, "led_classdev_register failed\n"); - goto exit_err1; - } - - return 0; - - exit_err1: - kfree(led); - return ret; -} - - -#ifdef CONFIG_PM -static int s3c24xx_led_suspend(struct platform_device *dev, pm_message_t state) -{ - struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); - - led_classdev_suspend(&led->cdev); - return 0; -} - -static int s3c24xx_led_resume(struct platform_device *dev) -{ - struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); - - led_classdev_resume(&led->cdev); - return 0; -} -#else -#define s3c24xx_led_suspend NULL -#define s3c24xx_led_resume NULL -#endif - -static struct platform_driver s3c24xx_led_driver = { - .probe = s3c24xx_led_probe, - .remove = s3c24xx_led_remove, - .suspend = s3c24xx_led_suspend, - .resume = s3c24xx_led_resume, - .driver = { - .name = "s3c24xx_led", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c24xx_led_init(void) -{ - return platform_driver_register(&s3c24xx_led_driver); -} - -static void __exit s3c24xx_led_exit(void) -{ - platform_driver_unregister(&s3c24xx_led_driver); -} - -module_init(s3c24xx_led_init); -module_exit(s3c24xx_led_exit); - -MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("S3C24XX LED driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c deleted file mode 100644 index 65bbef4a5..000000000 --- a/drivers/leds/leds-spitz.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * LED Triggers Core - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) -{ - if (value) - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); - else - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); -} - -static void spitzled_green_set(struct led_classdev *led_cdev, enum led_brightness value) -{ - if (value) - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); - else - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); -} - -static struct led_classdev spitz_amber_led = { - .name = "spitz:amber", - .default_trigger = "sharpsl-charge", - .brightness_set = spitzled_amber_set, -}; - -static struct led_classdev spitz_green_led = { - .name = "spitz:green", - .default_trigger = "ide-disk", - .brightness_set = spitzled_green_set, -}; - -#ifdef CONFIG_PM -static int spitzled_suspend(struct platform_device *dev, pm_message_t state) -{ -#ifdef CONFIG_LEDS_TRIGGERS - if (spitz_amber_led.trigger && strcmp(spitz_amber_led.trigger->name, "sharpsl-charge")) -#endif - led_classdev_suspend(&spitz_amber_led); - led_classdev_suspend(&spitz_green_led); - return 0; -} - -static int spitzled_resume(struct platform_device *dev) -{ - led_classdev_resume(&spitz_amber_led); - led_classdev_resume(&spitz_green_led); - return 0; -} -#endif - -static int spitzled_probe(struct platform_device *pdev) -{ - int ret; - - if (machine_is_akita()) - spitz_green_led.default_trigger = "nand-disk"; - - ret = led_classdev_register(&pdev->dev, &spitz_amber_led); - if (ret < 0) - return ret; - - ret = led_classdev_register(&pdev->dev, &spitz_green_led); - if (ret < 0) - led_classdev_unregister(&spitz_amber_led); - - return ret; -} - -static int spitzled_remove(struct platform_device *pdev) -{ - led_classdev_unregister(&spitz_amber_led); - led_classdev_unregister(&spitz_green_led); - - return 0; -} - -static struct platform_driver spitzled_driver = { - .probe = spitzled_probe, - .remove = spitzled_remove, -#ifdef CONFIG_PM - .suspend = spitzled_suspend, - .resume = spitzled_resume, -#endif - .driver = { - .name = "spitz-led", - }, -}; - -static int __init spitzled_init(void) -{ - return platform_driver_register(&spitzled_driver); -} - -static void __exit spitzled_exit(void) -{ - platform_driver_unregister(&spitzled_driver); -} - -module_init(spitzled_init); -module_exit(spitzled_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("Spitz LED driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-tosa.c b/drivers/leds/leds-tosa.c deleted file mode 100644 index c9e8cc1ec..000000000 --- a/drivers/leds/leds-tosa.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * LED Triggers Core - * - * Copyright 2005 Dirk Opfer - * - * Author: Dirk Opfer - * based on spitz.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void tosaled_amber_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value) - set_scoop_gpio(&tosascoop_jc_device.dev, - TOSA_SCOOP_JC_CHRG_ERR_LED); - else - reset_scoop_gpio(&tosascoop_jc_device.dev, - TOSA_SCOOP_JC_CHRG_ERR_LED); -} - -static void tosaled_green_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value) - set_scoop_gpio(&tosascoop_jc_device.dev, - TOSA_SCOOP_JC_NOTE_LED); - else - reset_scoop_gpio(&tosascoop_jc_device.dev, - TOSA_SCOOP_JC_NOTE_LED); -} - -static struct led_classdev tosa_amber_led = { - .name = "tosa:amber", - .default_trigger = "sharpsl-charge", - .brightness_set = tosaled_amber_set, -}; - -static struct led_classdev tosa_green_led = { - .name = "tosa:green", - .default_trigger = "nand-disk", - .brightness_set = tosaled_green_set, -}; - -#ifdef CONFIG_PM -static int tosaled_suspend(struct platform_device *dev, pm_message_t state) -{ -#ifdef CONFIG_LEDS_TRIGGERS - if (tosa_amber_led.trigger && strcmp(tosa_amber_led.trigger->name, - "sharpsl-charge")) -#endif - led_classdev_suspend(&tosa_amber_led); - led_classdev_suspend(&tosa_green_led); - return 0; -} - -static int tosaled_resume(struct platform_device *dev) -{ - led_classdev_resume(&tosa_amber_led); - led_classdev_resume(&tosa_green_led); - return 0; -} -#else -#define tosaled_suspend NULL -#define tosaled_resume NULL -#endif - -static int tosaled_probe(struct platform_device *pdev) -{ - int ret; - - ret = led_classdev_register(&pdev->dev, &tosa_amber_led); - if (ret < 0) - return ret; - - ret = led_classdev_register(&pdev->dev, &tosa_green_led); - if (ret < 0) - led_classdev_unregister(&tosa_amber_led); - - return ret; -} - -static int tosaled_remove(struct platform_device *pdev) -{ - led_classdev_unregister(&tosa_amber_led); - led_classdev_unregister(&tosa_green_led); - - return 0; -} - -static struct platform_driver tosaled_driver = { - .probe = tosaled_probe, - .remove = tosaled_remove, - .suspend = tosaled_suspend, - .resume = tosaled_resume, - .driver = { - .name = "tosa-led", - }, -}; - -static int __init tosaled_init(void) -{ - return platform_driver_register(&tosaled_driver); -} - -static void __exit tosaled_exit(void) -{ - platform_driver_unregister(&tosaled_driver); -} - -module_init(tosaled_init); -module_exit(tosaled_exit); - -MODULE_AUTHOR("Dirk Opfer "); -MODULE_DESCRIPTION("Tosa LED driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h deleted file mode 100644 index a715c4ed9..000000000 --- a/drivers/leds/leds.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * LED Core - * - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#ifndef __LEDS_H_INCLUDED -#define __LEDS_H_INCLUDED - -#include - -static inline void led_set_brightness(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value > LED_FULL) - value = LED_FULL; - led_cdev->brightness = value; - if (!(led_cdev->flags & LED_SUSPENDED)) - led_cdev->brightness_set(led_cdev, value); -} - -extern rwlock_t leds_list_lock; -extern struct list_head leds_list; - -#ifdef CONFIG_LEDS_TRIGGERS -void led_trigger_set_default(struct led_classdev *led_cdev); -void led_trigger_set(struct led_classdev *led_cdev, - struct led_trigger *trigger); -#else -#define led_trigger_set_default(x) do {} while(0) -#define led_trigger_set(x, y) do {} while(0) -#endif - -ssize_t led_trigger_store(struct class_device *dev, const char *buf, - size_t count); -ssize_t led_trigger_show(struct class_device *dev, char *buf); - -#endif /* __LEDS_H_INCLUDED */ diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c deleted file mode 100644 index fa651886a..000000000 --- a/drivers/leds/ledtrig-ide-disk.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * LED IDE-Disk Activity Trigger - * - * Copyright 2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include - -static void ledtrig_ide_timerfunc(unsigned long data); - -DEFINE_LED_TRIGGER(ledtrig_ide); -static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0); -static int ide_activity; -static int ide_lastactivity; - -void ledtrig_ide_activity(void) -{ - ide_activity++; - if (!timer_pending(&ledtrig_ide_timer)) - mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10)); -} -EXPORT_SYMBOL(ledtrig_ide_activity); - -static void ledtrig_ide_timerfunc(unsigned long data) -{ - if (ide_lastactivity != ide_activity) { - ide_lastactivity = ide_activity; - led_trigger_event(ledtrig_ide, LED_FULL); - mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10)); - } else { - led_trigger_event(ledtrig_ide, LED_OFF); - } -} - -static int __init ledtrig_ide_init(void) -{ - led_trigger_register_simple("ide-disk", &ledtrig_ide); - return 0; -} - -static void __exit ledtrig_ide_exit(void) -{ - led_trigger_unregister_simple(ledtrig_ide); -} - -module_init(ledtrig_ide_init); -module_exit(ledtrig_ide_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("LED IDE Disk Activity Trigger"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c deleted file mode 100644 index fbf141ef4..000000000 --- a/drivers/leds/ledtrig-timer.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * LED Kernel Timer Trigger - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "leds.h" - -struct timer_trig_data { - unsigned long delay_on; /* milliseconds on */ - unsigned long delay_off; /* milliseconds off */ - struct timer_list timer; -}; - -static void led_timer_function(unsigned long data) -{ - struct led_classdev *led_cdev = (struct led_classdev *) data; - struct timer_trig_data *timer_data = led_cdev->trigger_data; - unsigned long brightness = LED_OFF; - unsigned long delay = timer_data->delay_off; - - if (!timer_data->delay_on || !timer_data->delay_off) { - led_set_brightness(led_cdev, LED_OFF); - return; - } - - if (!led_cdev->brightness) { - brightness = LED_FULL; - delay = timer_data->delay_on; - } - - led_set_brightness(led_cdev, brightness); - - mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); -} - -static ssize_t led_delay_on_show(struct class_device *dev, char *buf) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct timer_trig_data *timer_data = led_cdev->trigger_data; - - sprintf(buf, "%lu\n", timer_data->delay_on); - - return strlen(buf) + 1; -} - -static ssize_t led_delay_on_store(struct class_device *dev, const char *buf, - size_t size) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct timer_trig_data *timer_data = led_cdev->trigger_data; - int ret = -EINVAL; - char *after; - unsigned long state = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - - if (*after && isspace(*after)) - count++; - - if (count == size) { - timer_data->delay_on = state; - mod_timer(&timer_data->timer, jiffies + 1); - ret = count; - } - - return ret; -} - -static ssize_t led_delay_off_show(struct class_device *dev, char *buf) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct timer_trig_data *timer_data = led_cdev->trigger_data; - - sprintf(buf, "%lu\n", timer_data->delay_off); - - return strlen(buf) + 1; -} - -static ssize_t led_delay_off_store(struct class_device *dev, const char *buf, - size_t size) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct timer_trig_data *timer_data = led_cdev->trigger_data; - int ret = -EINVAL; - char *after; - unsigned long state = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - - if (*after && isspace(*after)) - count++; - - if (count == size) { - timer_data->delay_off = state; - mod_timer(&timer_data->timer, jiffies + 1); - ret = count; - } - - return ret; -} - -static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show, - led_delay_on_store); -static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show, - led_delay_off_store); - -static void timer_trig_activate(struct led_classdev *led_cdev) -{ - struct timer_trig_data *timer_data; - - timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); - if (!timer_data) - return; - - led_cdev->trigger_data = timer_data; - - init_timer(&timer_data->timer); - timer_data->timer.function = led_timer_function; - timer_data->timer.data = (unsigned long) led_cdev; - - class_device_create_file(led_cdev->class_dev, - &class_device_attr_delay_on); - class_device_create_file(led_cdev->class_dev, - &class_device_attr_delay_off); -} - -static void timer_trig_deactivate(struct led_classdev *led_cdev) -{ - struct timer_trig_data *timer_data = led_cdev->trigger_data; - - if (timer_data) { - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_delay_on); - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_delay_off); - del_timer_sync(&timer_data->timer); - kfree(timer_data); - } -} - -static struct led_trigger timer_led_trigger = { - .name = "timer", - .activate = timer_trig_activate, - .deactivate = timer_trig_deactivate, -}; - -static int __init timer_trig_init(void) -{ - return led_trigger_register(&timer_led_trigger); -} - -static void __exit timer_trig_exit(void) -{ - led_trigger_unregister(&timer_led_trigger); -} - -module_init(timer_trig_init); -module_exit(timer_trig_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("Timer LED trigger"); -MODULE_LICENSE("GPL"); diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 259fd8973..d2ead1776 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -42,7 +42,6 @@ #include #ifdef CONFIG_PPC #include -#include #endif @@ -81,7 +80,7 @@ static struct adb_driver *adb_driver_list[] = { static struct class *adb_dev_class; struct adb_driver *adb_controller; -BLOCKING_NOTIFIER_HEAD(adb_client_list); +struct notifier_block *adb_client_list = NULL; static int adb_got_sleep; static int adb_inited; static pid_t adb_probe_task_pid; @@ -295,7 +294,7 @@ int __init adb_init(void) int i; #ifdef CONFIG_PPC32 - if (!machine_is(chrp) && !machine_is(powermac)) + if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) return 0; #endif #ifdef CONFIG_MAC @@ -355,8 +354,7 @@ adb_notify_sleep(struct pmu_sleep_notifier *self, int when) /* Stop autopoll */ if (adb_controller->autopoll) adb_controller->autopoll(0); - ret = blocking_notifier_call_chain(&adb_client_list, - ADB_MSG_POWERDOWN, NULL); + ret = notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL); if (ret & NOTIFY_STOP_MASK) { up(&adb_probe_mutex); return PBOOK_SLEEP_REFUSE; @@ -393,8 +391,7 @@ do_adb_reset_bus(void) if (adb_controller->autopoll) adb_controller->autopoll(0); - nret = blocking_notifier_call_chain(&adb_client_list, - ADB_MSG_PRE_RESET, NULL); + nret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL); if (nret & NOTIFY_STOP_MASK) { if (adb_controller->autopoll) adb_controller->autopoll(autopoll_devs); @@ -429,8 +426,7 @@ do_adb_reset_bus(void) } up(&adb_handler_sem); - nret = blocking_notifier_call_chain(&adb_client_list, - ADB_MSG_POST_RESET, NULL); + nret = notifier_call_chain(&adb_client_list, ADB_MSG_POST_RESET, NULL); if (nret & NOTIFY_STOP_MASK) return -EBUSY; diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 394334ec5..c0b46bceb 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -1206,16 +1206,15 @@ init_ms_a3(int id) static int __init adbhid_init(void) { #ifndef CONFIG_MAC - if (!machine_is(chrp) && !machine_is(powermac)) - return 0; + if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) + return 0; #endif led_request.complete = 1; adbhid_probe(); - blocking_notifier_chain_register(&adb_client_list, - &adbhid_adb_notifier); + notifier_chain_register(&adb_client_list, &adbhid_adb_notifier); return 0; } diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 431bd3722..69596f643 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -550,12 +550,15 @@ static void macio_pci_add_devices(struct macio_chip *chip) */ int macio_register_driver(struct macio_driver *drv) { + int count = 0; + /* initialize common driver fields */ drv->driver.name = drv->name; drv->driver.bus = &macio_bus_type; /* register with core */ - return driver_register(&drv->driver); + count = driver_register(&drv->driver); + return count ? count : 1; } /** diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 53c1c7909..8dbf2852b 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -839,8 +839,8 @@ static int __init media_bay_init(void) media_bays[i].cd_index = -1; #endif } - if (!machine_is(powermac)) - return 0; + if (_machine != _MACH_Pmac) + return -ENODEV; macio_register_driver(&media_bay_driver); diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index f4516ca7a..db2ae71d0 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -93,7 +92,7 @@ struct smu_device { * for now, just hard code that */ static struct smu_device *smu; -static DEFINE_MUTEX(smu_part_access); +static DECLARE_MUTEX(smu_part_access); static void smu_i2c_retry(unsigned long data); @@ -630,6 +629,8 @@ static struct of_platform_driver smu_of_platform_driver = static int __init smu_init_sysfs(void) { + int rc; + /* * Due to sysfs bogosity, a sysdev is not a real device, so * we should in fact create both if we want sysdev semantics @@ -638,7 +639,7 @@ static int __init smu_init_sysfs(void) * I'm a bit too far from figuring out how that works with those * new chipsets, but that will come back and bite us */ - of_register_driver(&smu_of_platform_driver); + rc = of_register_driver(&smu_of_platform_driver); return 0; } @@ -977,11 +978,11 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, if (interruptible) { int rc; - rc = mutex_lock_interruptible(&smu_part_access); + rc = down_interruptible(&smu_part_access); if (rc) return ERR_PTR(rc); } else - mutex_lock(&smu_part_access); + down(&smu_part_access); part = (struct smu_sdbp_header *)get_property(smu->of_node, pname, size); @@ -991,7 +992,7 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, if (part != NULL && size) *size = part->len << 2; } - mutex_unlock(&smu_part_access); + up(&smu_part_access); return part; } diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 231146f43..4f50ee576 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -104,6 +104,7 @@ #include #include #include +#include #include #include #include @@ -112,6 +113,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 0b5ff553e..4a478eb0e 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -161,9 +161,7 @@ static int drop_interrupts; #if defined(CONFIG_PM) && defined(CONFIG_PPC32) static int option_lid_wakeup = 1; #endif /* CONFIG_PM && CONFIG_PPC32 */ -#if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT) static int sleep_in_progress; -#endif static unsigned long async_req_locks; static unsigned int pmu_irq_stats[11]; @@ -187,7 +185,7 @@ extern int disable_kernel_backlight; int __fake_sleep; int asleep; -BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); +struct notifier_block *sleep_notifier_list; #ifdef CONFIG_ADB static int adb_dev_map = 0; @@ -2203,7 +2201,8 @@ pmac_wakeup_devices(void) #define GRACKLE_NAP (1<<4) #define GRACKLE_SLEEP (1<<3) -static int powerbook_sleep_grackle(void) +int +powerbook_sleep_grackle(void) { unsigned long save_l2cr; unsigned short pmcr1; diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index 35b70323e..f08e52f21 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -102,7 +102,7 @@ static int pmu_kind = PMU_UNKNOWN; static int pmu_fully_inited = 0; int asleep; -BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); +struct notifier_block *sleep_notifier_list; static int pmu_probe(void); static int pmu_init(void); @@ -913,8 +913,7 @@ int powerbook_sleep(void) struct adb_request sleep_req; /* Notify device drivers */ - ret = blocking_notifier_call_chain(&sleep_notifier_list, - PBOOK_SLEEP, NULL); + ret = notifier_call_chain(&sleep_notifier_list, PBOOK_SLEEP, NULL); if (ret & NOTIFY_STOP_MASK) return -EBUSY; @@ -985,7 +984,7 @@ int powerbook_sleep(void) enable_irq(i); /* Notify drivers */ - blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); + notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); /* reenable ADB autopoll */ pmu_adb_autopoll(adb_dev_map); diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index ab3faa702..6c0ba04bc 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -52,7 +52,7 @@ static LIST_HEAD(wf_controls); static LIST_HEAD(wf_sensors); static DEFINE_MUTEX(wf_lock); -static BLOCKING_NOTIFIER_HEAD(wf_client_list); +static struct notifier_block *wf_client_list; static int wf_client_count; static unsigned int wf_overtemp; static unsigned int wf_overtemp_counter; @@ -68,7 +68,7 @@ static struct platform_device wf_platform_device = { static inline void wf_notify(int event, void *param) { - blocking_notifier_call_chain(&wf_client_list, event, param); + notifier_call_chain(&wf_client_list, event, param); } int wf_critical_overtemp(void) @@ -398,7 +398,7 @@ int wf_register_client(struct notifier_block *nb) struct wf_sensor *sr; mutex_lock(&wf_lock); - rc = blocking_notifier_chain_register(&wf_client_list, nb); + rc = notifier_chain_register(&wf_client_list, nb); if (rc != 0) goto bail; wf_client_count++; @@ -417,7 +417,7 @@ EXPORT_SYMBOL_GPL(wf_register_client); int wf_unregister_client(struct notifier_block *nb) { mutex_lock(&wf_lock); - blocking_notifier_chain_unregister(&wf_client_list, nb); + notifier_chain_unregister(&wf_client_list, nb); wf_client_count++; if (wf_client_count == 0) wf_stop_thread(); diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 3f7967fea..423bfa243 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index eae1189d6..8e99d408f 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index e295a07a1..24e51d5e9 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index ac25a4836..ac43f9806 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -127,33 +127,6 @@ config MD_RAID5 If unsure, say Y. -config MD_RAID5_RESHAPE - bool "Support adding drives to a raid-5 array (experimental)" - depends on MD_RAID5 && EXPERIMENTAL - ---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. However it is still EXPERIMENTAL code. It should - work, but please be sure that you have backups. - - You will need mdadm verion 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. - config MD_RAID6 tristate "RAID-6 mode" depends on BLK_DEV_MD diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index f8ffaee20..eae4473ea 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -89,6 +89,16 @@ int bitmap_active(struct bitmap *bitmap) } #define WRITE_POOL_SIZE 256 +/* mempool for queueing pending writes on the bitmap file */ +static void *write_pool_alloc(gfp_t gfp_flags, void *data) +{ + return kmalloc(sizeof(struct page_list), gfp_flags); +} + +static void write_pool_free(void *ptr, void *data) +{ + kfree(ptr); +} /* * just a placeholder - calls kmalloc for bitmap pages @@ -546,7 +556,7 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, unsigned long flags; spin_lock_irqsave(&bitmap->lock, flags); - if (!bitmap->sb_page) { /* can't set the state */ + if (!bitmap || !bitmap->sb_page) { /* can't set the state */ spin_unlock_irqrestore(&bitmap->lock, flags); return; } @@ -1299,7 +1309,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect case 1: *bmc = 2; } - BUG_ON((*bmc & COUNTER_MAX) == COUNTER_MAX); + if ((*bmc & COUNTER_MAX) == COUNTER_MAX) BUG(); (*bmc)++; spin_unlock_irq(&bitmap->lock); @@ -1554,8 +1564,8 @@ int bitmap_create(mddev_t *mddev) spin_lock_init(&bitmap->write_lock); INIT_LIST_HEAD(&bitmap->complete_pages); init_waitqueue_head(&bitmap->write_wait); - bitmap->write_pool = mempool_create_kmalloc_pool(WRITE_POOL_SIZE, - sizeof(struct page_list)); + bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc, + write_pool_free, NULL); err = -ENOMEM; if (!bitmap->write_pool) goto error; diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 61a590bb6..aa9b7728d 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -93,6 +93,20 @@ struct crypt_config { static kmem_cache_t *_crypt_io_pool; +/* + * Mempool alloc and free functions for the page + */ +static void *mempool_alloc_page(gfp_t gfp_mask, void *data) +{ + return alloc_page(gfp_mask); +} + +static void mempool_free_page(void *page, void *data) +{ + __free_page(page); +} + + /* * Different IV generation algorithms: * @@ -518,7 +532,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) char *ivopts; unsigned int crypto_flags; unsigned int key_size; - unsigned long long tmpll; if (argc != 5) { ti->error = PFX "Not enough arguments"; @@ -617,13 +630,15 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) } } - cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool); + cc->io_pool = mempool_create(MIN_IOS, mempool_alloc_slab, + mempool_free_slab, _crypt_io_pool); if (!cc->io_pool) { ti->error = PFX "Cannot allocate crypt io mempool"; goto bad3; } - cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0); + cc->page_pool = mempool_create(MIN_POOL_PAGES, mempool_alloc_page, + mempool_free_page, NULL); if (!cc->page_pool) { ti->error = PFX "Cannot allocate page mempool"; goto bad4; @@ -634,17 +649,15 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad5; } - if (sscanf(argv[2], "%llu", &tmpll) != 1) { + if (sscanf(argv[2], SECTOR_FORMAT, &cc->iv_offset) != 1) { ti->error = PFX "Invalid iv_offset sector"; goto bad5; } - cc->iv_offset = tmpll; - if (sscanf(argv[4], "%llu", &tmpll) != 1) { + if (sscanf(argv[4], SECTOR_FORMAT, &cc->start) != 1) { ti->error = PFX "Invalid device sector"; goto bad5; } - cc->start = tmpll; if (dm_get_device(ti, argv[3], cc->start, ti->len, dm_table_get_mode(ti->table), &cc->dev)) { @@ -717,13 +730,15 @@ static int crypt_endio(struct bio *bio, unsigned int done, int error) if (bio->bi_size) return 1; + if (!bio_flagged(bio, BIO_UPTODATE) && !error) + error = -EIO; + bio_put(bio); /* * successful reads are decrypted by the worker thread */ - if ((bio_data_dir(bio) == READ) - && bio_flagged(bio, BIO_UPTODATE)) { + if (bio_data_dir(io->bio) == READ && !error) { kcryptd_queue_io(io); return 0; } @@ -888,8 +903,8 @@ static int crypt_status(struct dm_target *ti, status_type_t type, result[sz++] = '-'; } - DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset, - cc->dev->name, (unsigned long long)cc->start); + DMEMIT(" " SECTOR_FORMAT " %s " SECTOR_FORMAT, + cc->iv_offset, cc->dev->name, cc->start); break; } return 0; diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 34a75939a..ab8756a40 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -517,6 +517,16 @@ static void persistent_commit(struct exception_store *store, if (r) ps->valid = 0; + /* + * Have we completely filled the current area ? + */ + if (ps->current_committed == ps->exceptions_per_area) { + ps->current_committed = 0; + r = zero_area(ps, ps->current_area + 1); + if (r) + ps->valid = 0; + } + for (i = 0; i < ps->callback_count; i++) { cb = ps->callbacks + i; cb->callback(cb->context, r == 0 ? 1 : 0); @@ -524,16 +534,6 @@ static void persistent_commit(struct exception_store *store, ps->callback_count = 0; } - - /* - * Have we completely filled the current area ? - */ - if (ps->current_committed == ps->exceptions_per_area) { - ps->current_committed = 0; - r = zero_area(ps, ps->current_area + 1); - if (r) - ps->valid = 0; - } } static void persistent_drop(struct exception_store *store) diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 45754bb6a..4809b209f 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -32,7 +32,7 @@ struct io { static unsigned _num_ios; static mempool_t *_io_pool; -static void *alloc_io(unsigned int __nocast gfp_mask, void *pool_data) +static void *alloc_io(gfp_t gfp_mask, void *pool_data) { return kmalloc(sizeof(struct io), gfp_mask); } @@ -239,6 +239,11 @@ static void vm_dp_init(struct dpages *dp, void *data) dp->context_ptr = data; } +static void dm_bio_destructor(struct bio *bio) +{ + bio_free(bio, _bios); +} + /*----------------------------------------------------------------- * IO routines that accept a list of pages. *---------------------------------------------------------------*/ @@ -263,6 +268,7 @@ static void do_region(int rw, unsigned int region, struct io_region *where, bio->bi_bdev = where->bdev; bio->bi_end_io = endio; bio->bi_private = io; + bio->bi_destructor = dm_bio_destructor; bio_set_region(bio, region); /* diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index f7e743691..442e2be60 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -15,7 +15,6 @@ #include #include #include -#include #include @@ -102,10 +101,8 @@ static struct hash_cell *__get_name_cell(const char *str) unsigned int h = hash_str(str); list_for_each_entry (hc, _name_buckets + h, name_list) - if (!strcmp(hc->name, str)) { - dm_get(hc->md); + if (!strcmp(hc->name, str)) return hc; - } return NULL; } @@ -116,10 +113,8 @@ static struct hash_cell *__get_uuid_cell(const char *str) unsigned int h = hash_str(str); list_for_each_entry (hc, _uuid_buckets + h, uuid_list) - if (!strcmp(hc->uuid, str)) { - dm_get(hc->md); + if (!strcmp(hc->uuid, str)) return hc; - } return NULL; } @@ -195,7 +190,7 @@ static int unregister_with_devfs(struct hash_cell *hc) */ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md) { - struct hash_cell *cell, *hc; + struct hash_cell *cell; /* * Allocate the new cells. @@ -208,19 +203,14 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi * Insert the cell into both hash tables. */ down_write(&_hash_lock); - hc = __get_name_cell(name); - if (hc) { - dm_put(hc->md); + if (__get_name_cell(name)) goto bad; - } list_add(&cell->name_list, _name_buckets + hash_str(name)); if (uuid) { - hc = __get_uuid_cell(uuid); - if (hc) { + if (__get_uuid_cell(uuid)) { list_del(&cell->name_list); - dm_put(hc->md); goto bad; } list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); @@ -254,9 +244,9 @@ static void __hash_remove(struct hash_cell *hc) dm_table_put(table); } + dm_put(hc->md); if (hc->new_map) dm_table_put(hc->new_map); - dm_put(hc->md); free_cell(hc); } @@ -298,7 +288,6 @@ static int dm_hash_rename(const char *old, const char *new) if (hc) { DMWARN("asked to rename to an already existing name %s -> %s", old, new); - dm_put(hc->md); up_write(&_hash_lock); kfree(new_name); return -EBUSY; @@ -338,7 +327,6 @@ static int dm_hash_rename(const char *old, const char *new) dm_table_put(table); } - dm_put(hc->md); up_write(&_hash_lock); kfree(old_name); return 0; @@ -612,20 +600,12 @@ static int dev_create(struct dm_ioctl *param, size_t param_size) */ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) { - struct mapped_device *md; - void *mdptr = NULL; - if (*param->uuid) return __get_uuid_cell(param->uuid); - - if (*param->name) + else if (*param->name) return __get_name_cell(param->name); - - md = dm_get_md(huge_decode_dev(param->dev)); - if (md) - mdptr = dm_get_mdptr(md); - - return mdptr; + else + return dm_get_mdptr(huge_decode_dev(param->dev)); } static struct mapped_device *find_device(struct dm_ioctl *param) @@ -637,6 +617,7 @@ static struct mapped_device *find_device(struct dm_ioctl *param) hc = __find_device_hash_cell(param); if (hc) { md = hc->md; + dm_get(md); /* * Sneakily write in both the name and the uuid @@ -661,7 +642,6 @@ static struct mapped_device *find_device(struct dm_ioctl *param) static int dev_remove(struct dm_ioctl *param, size_t param_size) { struct hash_cell *hc; - struct mapped_device *md; down_write(&_hash_lock); hc = __find_device_hash_cell(param); @@ -672,11 +652,8 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size) return -ENXIO; } - md = hc->md; - __hash_remove(hc); up_write(&_hash_lock); - dm_put(md); param->data_size = 0; return 0; } @@ -713,54 +690,6 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size) return dm_hash_rename(param->name, new_name); } -static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) -{ - int r = -EINVAL, x; - struct mapped_device *md; - struct hd_geometry geometry; - unsigned long indata[4]; - char *geostr = (char *) param + param->data_start; - - md = find_device(param); - if (!md) - return -ENXIO; - - if (geostr < (char *) (param + 1) || - invalid_str(geostr, (void *) param + param_size)) { - DMWARN("Invalid geometry supplied."); - goto out; - } - - x = sscanf(geostr, "%lu %lu %lu %lu", indata, - indata + 1, indata + 2, indata + 3); - - if (x != 4) { - DMWARN("Unable to interpret geometry settings."); - goto out; - } - - if (indata[0] > 65535 || indata[1] > 255 || - indata[2] > 255 || indata[3] > ULONG_MAX) { - DMWARN("Geometry exceeds range limits."); - goto out; - } - - geometry.cylinders = indata[0]; - geometry.heads = indata[1]; - geometry.sectors = indata[2]; - geometry.start = indata[3]; - - r = dm_set_geometry(md, &geometry); - if (!r) - r = __dev_status(md, param); - - param->data_size = 0; - -out: - dm_put(md); - return r; -} - static int do_suspend(struct dm_ioctl *param) { int r = 0; @@ -802,6 +731,7 @@ static int do_resume(struct dm_ioctl *param) } md = hc->md; + dm_get(md); new_map = hc->new_map; hc->new_map = NULL; @@ -1045,43 +975,33 @@ static int table_load(struct dm_ioctl *param, size_t param_size) int r; struct hash_cell *hc; struct dm_table *t; - struct mapped_device *md; - - md = find_device(param); - if (!md) - return -ENXIO; - r = dm_table_create(&t, get_mode(param), param->target_count, md); + r = dm_table_create(&t, get_mode(param), param->target_count); if (r) - goto out; + return r; r = populate_table(t, param, param_size); if (r) { dm_table_put(t); - goto out; + return r; } down_write(&_hash_lock); - hc = dm_get_mdptr(md); - if (!hc || hc->md != md) { - DMWARN("device has been removed from the dev hash table."); - dm_table_put(t); + hc = __find_device_hash_cell(param); + if (!hc) { + DMWARN("device doesn't appear to be in the dev hash table."); up_write(&_hash_lock); - r = -ENXIO; - goto out; + dm_table_put(t); + return -ENXIO; } if (hc->new_map) dm_table_put(hc->new_map); hc->new_map = t; - up_write(&_hash_lock); - param->flags |= DM_INACTIVE_PRESENT_FLAG; - r = __dev_status(md, param); - -out: - dm_put(md); + r = __dev_status(hc->md, param); + up_write(&_hash_lock); return r; } @@ -1089,7 +1009,6 @@ static int table_clear(struct dm_ioctl *param, size_t param_size) { int r; struct hash_cell *hc; - struct mapped_device *md; down_write(&_hash_lock); @@ -1108,9 +1027,7 @@ static int table_clear(struct dm_ioctl *param, size_t param_size) param->flags &= ~DM_INACTIVE_PRESENT_FLAG; r = __dev_status(hc->md, param); - md = hc->md; up_write(&_hash_lock); - dm_put(md); return r; } @@ -1297,8 +1214,7 @@ static ioctl_fn lookup_ioctl(unsigned int cmd) {DM_LIST_VERSIONS_CMD, list_versions}, - {DM_TARGET_MSG_CMD, target_message}, - {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry} + {DM_TARGET_MSG_CMD, target_message} }; return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index daf586c08..6a2cd5dc8 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -26,7 +26,6 @@ struct linear_c { static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) { struct linear_c *lc; - unsigned long long tmp; if (argc != 2) { ti->error = "dm-linear: Invalid argument count"; @@ -39,11 +38,10 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -ENOMEM; } - if (sscanf(argv[1], "%llu", &tmp) != 1) { + if (sscanf(argv[1], SECTOR_FORMAT, &lc->start) != 1) { ti->error = "dm-linear: Invalid device sector"; goto bad; } - lc->start = tmp; if (dm_get_device(ti, argv[0], lc->start, ti->len, dm_table_get_mode(ti->table), &lc->dev)) { @@ -89,8 +87,8 @@ static int linear_status(struct dm_target *ti, status_type_t type, break; case STATUSTYPE_TABLE: - snprintf(result, maxlen, "%s %llu", lc->dev->name, - (unsigned long long)lc->start); + snprintf(result, maxlen, "%s " SECTOR_FORMAT, lc->dev->name, + lc->start); break; } return 0; diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 5af5265cf..cf70a0dc8 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -179,7 +179,8 @@ static struct multipath *alloc_multipath(void) m->queue_io = 1; INIT_WORK(&m->process_queued_ios, process_queued_ios, m); INIT_WORK(&m->trigger_event, trigger_event, m); - m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); + m->mpio_pool = mempool_create(MIN_IOS, mempool_alloc_slab, + mempool_free_slab, _mpio_cache); if (!m->mpio_pool) { kfree(m); return NULL; diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 2cab46ed1..0242cc399 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -152,6 +152,16 @@ static inline sector_t region_to_sector(struct region_hash *rh, region_t region) /* FIXME move this */ static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw); +static void *region_alloc(gfp_t gfp_mask, void *pool_data) +{ + return kmalloc(sizeof(struct region), gfp_mask); +} + +static void region_free(void *element, void *pool_data) +{ + kfree(element); +} + #define MIN_REGIONS 64 #define MAX_RECOVERY 1 static int rh_init(struct region_hash *rh, struct mirror_set *ms, @@ -193,8 +203,8 @@ static int rh_init(struct region_hash *rh, struct mirror_set *ms, INIT_LIST_HEAD(&rh->quiesced_regions); INIT_LIST_HEAD(&rh->recovered_regions); - rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS, - sizeof(struct region)); + rh->region_pool = mempool_create(MIN_REGIONS, region_alloc, + region_free, NULL); if (!rh->region_pool) { vfree(rh->buckets); rh->buckets = NULL; @@ -434,21 +444,9 @@ static void rh_dec(struct region_hash *rh, region_t region) spin_lock_irqsave(&rh->region_lock, flags); if (atomic_dec_and_test(®->pending)) { - /* - * There is no pending I/O for this region. - * We can move the region to corresponding list for next action. - * At this point, the region is not yet connected to any list. - * - * If the state is RH_NOSYNC, the region should be kept off - * from clean list. - * The hash entry for RH_NOSYNC will remain in memory - * until the region is recovered or the map is reloaded. - */ - - /* do nothing for RH_NOSYNC */ if (reg->state == RH_RECOVERING) { list_add_tail(®->list, &rh->quiesced_regions); - } else if (reg->state == RH_DIRTY) { + } else { reg->state = RH_CLEAN; list_add(®->list, &rh->clean_regions); } @@ -937,9 +935,9 @@ static inline int _check_region_size(struct dm_target *ti, uint32_t size) static int get_mirror(struct mirror_set *ms, struct dm_target *ti, unsigned int mirror, char **argv) { - unsigned long long offset; + sector_t offset; - if (sscanf(argv[1], "%llu", &offset) != 1) { + if (sscanf(argv[1], SECTOR_FORMAT, &offset) != 1) { ti->error = "dm-mirror: Invalid offset"; return -EINVAL; } @@ -1206,17 +1204,16 @@ static int mirror_status(struct dm_target *ti, status_type_t type, for (m = 0; m < ms->nr_mirrors; m++) DMEMIT("%s ", ms->mirror[m].dev->name); - DMEMIT("%llu/%llu", - (unsigned long long)ms->rh.log->type-> - get_sync_count(ms->rh.log), - (unsigned long long)ms->nr_regions); + DMEMIT(SECTOR_FORMAT "/" SECTOR_FORMAT, + ms->rh.log->type->get_sync_count(ms->rh.log), + ms->nr_regions); break; case STATUSTYPE_TABLE: DMEMIT("%d ", ms->nr_mirrors); for (m = 0; m < ms->nr_mirrors; m++) - DMEMIT("%s %llu ", ms->mirror[m].dev->name, - (unsigned long long)ms->mirror[m].offset); + DMEMIT("%s " SECTOR_FORMAT " ", + ms->mirror[m].dev->name, ms->mirror[m].offset); } return 0; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index b84bc1aae..5487b7cca 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -49,26 +49,11 @@ struct pending_exception { struct bio_list snapshot_bios; /* - * Short-term queue of pending exceptions prior to submission. + * Other pending_exceptions that are processing this + * chunk. When this list is empty, we know we can + * complete the origins. */ - struct list_head list; - - /* - * The primary pending_exception is the one that holds - * the sibling_count and the list of origin_bios for a - * group of pending_exceptions. It is always last to get freed. - * These fields get set up when writing to the origin. - */ - struct pending_exception *primary_pe; - - /* - * Number of pending_exceptions processing this chunk. - * When this drops to zero we must complete the origin bios. - * If incrementing or decrementing this, hold pe->snap->lock for - * the sibling concerned and not pe->primary_pe->snap->lock unless - * they are the same. - */ - atomic_t sibling_count; + struct list_head siblings; /* Pointer back to snapshot context */ struct dm_snapshot *snap; @@ -392,8 +377,6 @@ static void read_snapshot_metadata(struct dm_snapshot *s) down_write(&s->lock); s->valid = 0; up_write(&s->lock); - - dm_table_event(s->table); } } @@ -607,117 +590,78 @@ static void error_bios(struct bio *bio) } } -static inline void error_snapshot_bios(struct pending_exception *pe) -{ - error_bios(bio_list_get(&pe->snapshot_bios)); -} - static struct bio *__flush_bios(struct pending_exception *pe) { - /* - * If this pe is involved in a write to the origin and - * it is the last sibling to complete then release - * the bios for the original write to the origin. - */ + struct pending_exception *sibling; - if (pe->primary_pe && - atomic_dec_and_test(&pe->primary_pe->sibling_count)) - return bio_list_get(&pe->primary_pe->origin_bios); + if (list_empty(&pe->siblings)) + return bio_list_get(&pe->origin_bios); - return NULL; -} + sibling = list_entry(pe->siblings.next, + struct pending_exception, siblings); -static void __invalidate_snapshot(struct dm_snapshot *s, - struct pending_exception *pe, int err) -{ - if (!s->valid) - return; - - if (err == -EIO) - DMERR("Invalidating snapshot: Error reading/writing."); - else if (err == -ENOMEM) - DMERR("Invalidating snapshot: Unable to allocate exception."); - - if (pe) - remove_exception(&pe->e); + list_del(&pe->siblings); - if (s->store.drop_snapshot) - s->store.drop_snapshot(&s->store); - - s->valid = 0; + /* This is fine as long as kcopyd is single-threaded. If kcopyd + * becomes multi-threaded, we'll need some locking here. + */ + bio_list_merge(&sibling->origin_bios, &pe->origin_bios); - dm_table_event(s->table); + return NULL; } static void pending_complete(struct pending_exception *pe, int success) { struct exception *e; - struct pending_exception *primary_pe; struct dm_snapshot *s = pe->snap; struct bio *flush = NULL; - if (!success) { - /* Read/write error - snapshot is unusable */ - down_write(&s->lock); - __invalidate_snapshot(s, pe, -EIO); - flush = __flush_bios(pe); - up_write(&s->lock); - - error_snapshot_bios(pe); - goto out; - } + if (success) { + e = alloc_exception(); + if (!e) { + DMWARN("Unable to allocate exception."); + down_write(&s->lock); + s->store.drop_snapshot(&s->store); + s->valid = 0; + flush = __flush_bios(pe); + up_write(&s->lock); + + error_bios(bio_list_get(&pe->snapshot_bios)); + goto out; + } + *e = pe->e; - e = alloc_exception(); - if (!e) { + /* + * Add a proper exception, and remove the + * in-flight exception from the list. + */ down_write(&s->lock); - __invalidate_snapshot(s, pe, -ENOMEM); + insert_exception(&s->complete, e); + remove_exception(&pe->e); flush = __flush_bios(pe); - up_write(&s->lock); - error_snapshot_bios(pe); - goto out; - } - *e = pe->e; + /* Submit any pending write bios */ + up_write(&s->lock); - /* - * Add a proper exception, and remove the - * in-flight exception from the list. - */ - down_write(&s->lock); - if (!s->valid) { + flush_bios(bio_list_get(&pe->snapshot_bios)); + } else { + /* Read/write error - snapshot is unusable */ + down_write(&s->lock); + if (s->valid) + DMERR("Error reading/writing snapshot"); + s->store.drop_snapshot(&s->store); + s->valid = 0; + remove_exception(&pe->e); flush = __flush_bios(pe); up_write(&s->lock); - free_exception(e); + error_bios(bio_list_get(&pe->snapshot_bios)); - error_snapshot_bios(pe); - goto out; + dm_table_event(s->table); } - insert_exception(&s->complete, e); - remove_exception(&pe->e); - flush = __flush_bios(pe); - - up_write(&s->lock); - - /* Submit any pending write bios */ - flush_bios(bio_list_get(&pe->snapshot_bios)); - out: - primary_pe = pe->primary_pe; - - /* - * Free the pe if it's not linked to an origin write or if - * it's not itself a primary pe. - */ - if (!primary_pe || primary_pe != pe) - free_pending_exception(pe); - - /* - * Free the primary pe if nothing references it. - */ - if (primary_pe && !atomic_read(&primary_pe->sibling_count)) - free_pending_exception(primary_pe); + free_pending_exception(pe); if (flush) flush_bios(flush); @@ -794,45 +738,38 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio) if (e) { /* cast the exception to a pending exception */ pe = container_of(e, struct 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(); - down_write(&s->lock); - if (!s->valid) { - free_pending_exception(pe); - return NULL; - } + } else { + /* + * 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(); + down_write(&s->lock); - e = lookup_exception(&s->pending, chunk); - if (e) { - free_pending_exception(pe); - pe = container_of(e, struct pending_exception, e); - goto out; - } + e = lookup_exception(&s->pending, chunk); + if (e) { + free_pending_exception(pe); + pe = container_of(e, struct pending_exception, e); + } else { + pe->e.old_chunk = chunk; + bio_list_init(&pe->origin_bios); + bio_list_init(&pe->snapshot_bios); + INIT_LIST_HEAD(&pe->siblings); + pe->snap = s; + pe->started = 0; + + if (s->store.prepare_exception(&s->store, &pe->e)) { + free_pending_exception(pe); + s->valid = 0; + return NULL; + } - pe->e.old_chunk = chunk; - bio_list_init(&pe->origin_bios); - bio_list_init(&pe->snapshot_bios); - pe->primary_pe = NULL; - atomic_set(&pe->sibling_count, 1); - pe->snap = s; - pe->started = 0; - - if (s->store.prepare_exception(&s->store, &pe->e)) { - free_pending_exception(pe); - return NULL; + insert_exception(&s->pending, &pe->e); + } } - insert_exception(&s->pending, &pe->e); - - out: return pe; } @@ -849,15 +786,13 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, { struct exception *e; struct dm_snapshot *s = (struct dm_snapshot *) ti->private; - int copy_needed = 0; int r = 1; chunk_t chunk; - struct pending_exception *pe = NULL; + struct pending_exception *pe; chunk = sector_to_chunk(s, bio->bi_sector); /* Full snapshots are not usable */ - /* To get here the table must be live so s->active is always set. */ if (!s->valid) return -EIO; @@ -875,41 +810,36 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, * to copy an exception */ down_write(&s->lock); - if (!s->valid) { - r = -EIO; - goto out_unlock; - } - /* If the block is already remapped - use that, else remap it */ e = lookup_exception(&s->complete, chunk); if (e) { remap_exception(s, e, bio); - goto out_unlock; - } - - pe = __find_pending_exception(s, bio); - if (!pe) { - __invalidate_snapshot(s, pe, -ENOMEM); - r = -EIO; - goto out_unlock; - } - - remap_exception(s, &pe->e, bio); - bio_list_add(&pe->snapshot_bios, bio); - - if (!pe->started) { - /* this is protected by snap->lock */ - pe->started = 1; - copy_needed = 1; + up_write(&s->lock); + + } else { + pe = __find_pending_exception(s, bio); + + if (!pe) { + if (s->store.drop_snapshot) + s->store.drop_snapshot(&s->store); + s->valid = 0; + r = -EIO; + up_write(&s->lock); + } else { + remap_exception(s, &pe->e, bio); + bio_list_add(&pe->snapshot_bios, bio); + + if (!pe->started) { + /* this is protected by snap->lock */ + pe->started = 1; + up_write(&s->lock); + start_copy(pe); + } else + up_write(&s->lock); + r = 0; + } } - r = 0; - - out_unlock: - up_write(&s->lock); - - if (copy_needed) - start_copy(pe); } else { /* * FIXME: this read path scares me because we @@ -921,11 +851,6 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, /* Do reads */ down_read(&s->lock); - if (!s->valid) { - up_read(&s->lock); - return -EIO; - } - /* See if it it has been remapped */ e = lookup_exception(&s->complete, chunk); if (e) @@ -963,9 +888,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, snap->store.fraction_full(&snap->store, &numerator, &denominator); - snprintf(result, maxlen, "%llu/%llu", - (unsigned long long)numerator, - (unsigned long long)denominator); + snprintf(result, maxlen, + SECTOR_FORMAT "/" SECTOR_FORMAT, + numerator, denominator); } else snprintf(result, maxlen, "Unknown"); @@ -978,10 +903,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", + snprintf(result, maxlen, "%s %s %c " SECTOR_FORMAT, snap->origin->name, snap->cow->name, - snap->type, - (unsigned long long)snap->chunk_size); + snap->type, snap->chunk_size); break; } @@ -991,27 +915,40 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, /*----------------------------------------------------------------- * Origin methods *---------------------------------------------------------------*/ +static void list_merge(struct list_head *l1, struct list_head *l2) +{ + struct list_head *l1_n, *l2_p; + + l1_n = l1->next; + l2_p = l2->prev; + + l1->next = l2; + l2->prev = l1; + + l2_p->next = l1_n; + l1_n->prev = l2_p; +} + static int __origin_write(struct list_head *snapshots, struct bio *bio) { - int r = 1, first = 0; + int r = 1, first = 1; struct dm_snapshot *snap; struct exception *e; - struct pending_exception *pe, *next_pe, *primary_pe = NULL; + struct pending_exception *pe, *last = NULL; chunk_t chunk; - LIST_HEAD(pe_queue); /* Do all the snapshots on this origin */ list_for_each_entry (snap, snapshots, list) { - down_write(&snap->lock); - /* Only deal with valid and active snapshots */ if (!snap->valid || !snap->active) - goto next_snapshot; + continue; /* Nothing to do if writing beyond end of snapshot */ if (bio->bi_sector >= dm_table_get_size(snap->table)) - goto next_snapshot; + continue; + + down_write(&snap->lock); /* * Remember, different snapshots can have @@ -1023,75 +960,49 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) * Check exception table to see if block * is already remapped in this snapshot * and trigger an exception if not. - * - * sibling_count is initialised to 1 so pending_complete() - * won't destroy the primary_pe while we're inside this loop. */ e = lookup_exception(&snap->complete, chunk); - if (e) - goto next_snapshot; - - pe = __find_pending_exception(snap, bio); - if (!pe) { - __invalidate_snapshot(snap, pe, ENOMEM); - goto next_snapshot; - } - - if (!primary_pe) { - /* - * Either every pe here has same - * primary_pe or none has one yet. - */ - if (pe->primary_pe) - primary_pe = pe->primary_pe; - else { - primary_pe = pe; - first = 1; + if (!e) { + pe = __find_pending_exception(snap, bio); + if (!pe) { + snap->store.drop_snapshot(&snap->store); + snap->valid = 0; + + } else { + if (last) + list_merge(&pe->siblings, + &last->siblings); + + last = pe; + r = 0; } - - bio_list_add(&primary_pe->origin_bios, bio); - - r = 0; - } - - if (!pe->primary_pe) { - atomic_inc(&primary_pe->sibling_count); - pe->primary_pe = primary_pe; - } - - if (!pe->started) { - pe->started = 1; - list_add_tail(&pe->list, &pe_queue); } - next_snapshot: up_write(&snap->lock); } - if (!primary_pe) - goto out; - - /* - * If this is the first time we're processing this chunk and - * sibling_count is now 1 it means all the pending exceptions - * got completed while we were in the loop above, so it falls to - * us here to remove the primary_pe and submit any origin_bios. - */ - - if (first && atomic_dec_and_test(&primary_pe->sibling_count)) { - flush_bios(bio_list_get(&primary_pe->origin_bios)); - free_pending_exception(primary_pe); - /* If we got here, pe_queue is necessarily empty. */ - goto out; - } - /* * Now that we have a complete pe list we can start the copying. */ - list_for_each_entry_safe(pe, next_pe, &pe_queue, list) - start_copy(pe); + if (last) { + pe = last; + do { + down_write(&pe->snap->lock); + if (first) + bio_list_add(&pe->origin_bios, bio); + if (!pe->started) { + pe->started = 1; + up_write(&pe->snap->lock); + start_copy(pe); + } else + up_write(&pe->snap->lock); + first = 0; + pe = list_entry(pe->siblings.next, + struct pending_exception, siblings); + + } while (pe != last); + } - out: return r; } @@ -1267,7 +1178,8 @@ static int __init dm_snapshot_init(void) goto bad4; } - pending_pool = mempool_create_slab_pool(128, pending_cache); + pending_pool = mempool_create(128, mempool_alloc_slab, + mempool_free_slab, pending_cache); if (!pending_pool) { DMERR("Couldn't create pending pool."); r = -ENOMEM; diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index 08328a8f5..697aacafb 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -49,9 +49,9 @@ static inline struct stripe_c *alloc_context(unsigned int stripes) static int get_stripe(struct dm_target *ti, struct stripe_c *sc, unsigned int stripe, char **argv) { - unsigned long long start; + sector_t start; - if (sscanf(argv[1], "%llu", &start) != 1) + if (sscanf(argv[1], SECTOR_FORMAT, &start) != 1) return -EINVAL; if (dm_get_device(ti, argv[0], start, sc->stripe_width, @@ -103,7 +103,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - if (ti->len & (chunk_size - 1)) { + if (((uint32_t)ti->len) & (chunk_size - 1)) { ti->error = "dm-stripe: Target length not divisible by " "chunk size"; return -EINVAL; @@ -201,11 +201,10 @@ static int stripe_status(struct dm_target *ti, break; case STATUSTYPE_TABLE: - DMEMIT("%d %llu", sc->stripes, - (unsigned long long)sc->chunk_mask + 1); + DMEMIT("%d " SECTOR_FORMAT, sc->stripes, sc->chunk_mask + 1); for (i = 0; i < sc->stripes; i++) - DMEMIT(" %s %llu", sc->stripe[i].dev->name, - (unsigned long long)sc->stripe[i].physical_start); + DMEMIT(" %s " SECTOR_FORMAT, sc->stripe[i].dev->name, + sc->stripe[i].physical_start); break; } return 0; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 8f56a54cf..9b1e2f5ca 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #define MAX_DEPTH 16 @@ -23,7 +22,6 @@ #define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) struct dm_table { - struct mapped_device *md; atomic_t holders; /* btree table */ @@ -99,8 +97,6 @@ static void combine_restrictions_low(struct io_restrictions *lhs, lhs->seg_boundary_mask = min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask); - - lhs->no_cluster |= rhs->no_cluster; } /* @@ -208,8 +204,7 @@ static int alloc_targets(struct dm_table *t, unsigned int num) return 0; } -int dm_table_create(struct dm_table **result, int mode, - unsigned num_targets, struct mapped_device *md) +int dm_table_create(struct dm_table **result, int mode, unsigned num_targets) { struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL); @@ -232,7 +227,6 @@ int dm_table_create(struct dm_table **result, int mode, } t->mode = mode; - t->md = md; *result = t; return 0; } @@ -351,19 +345,20 @@ static struct dm_dev *find_device(struct list_head *l, dev_t dev) /* * Open a device so we can use it as a map destination. */ -static int open_dev(struct dm_dev *d, dev_t dev, struct mapped_device *md) +static int open_dev(struct dm_dev *d, dev_t dev) { static char *_claim_ptr = "I belong to device-mapper"; struct block_device *bdev; int r; - BUG_ON(d->bdev); + if (d->bdev) + BUG(); bdev = open_by_devnum(dev, d->mode); if (IS_ERR(bdev)) return PTR_ERR(bdev); - r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md)); + r = bd_claim(bdev, _claim_ptr); if (r) blkdev_put(bdev); else @@ -374,12 +369,12 @@ static int open_dev(struct dm_dev *d, dev_t dev, struct mapped_device *md) /* * Close a device that we've been using. */ -static void close_dev(struct dm_dev *d, struct mapped_device *md) +static void close_dev(struct dm_dev *d) { if (!d->bdev) return; - bd_release_from_disk(d->bdev, dm_disk(md)); + bd_release(d->bdev); blkdev_put(d->bdev); d->bdev = NULL; } @@ -400,7 +395,7 @@ static int check_device_area(struct dm_dev *dd, sector_t start, sector_t len) * careful to leave things as they were if we fail to reopen the * device. */ -static int upgrade_mode(struct dm_dev *dd, int new_mode, struct mapped_device *md) +static int upgrade_mode(struct dm_dev *dd, int new_mode) { int r; struct dm_dev dd_copy; @@ -410,9 +405,9 @@ static int upgrade_mode(struct dm_dev *dd, int new_mode, struct mapped_device *m dd->mode |= new_mode; dd->bdev = NULL; - r = open_dev(dd, dev, md); + r = open_dev(dd, dev); if (!r) - close_dev(&dd_copy, md); + close_dev(&dd_copy); else *dd = dd_copy; @@ -432,7 +427,8 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti, struct dm_dev *dd; unsigned int major, minor; - BUG_ON(!t); + if (!t) + BUG(); if (sscanf(path, "%u:%u", &major, &minor) == 2) { /* Extract the major/minor numbers */ @@ -454,7 +450,7 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti, dd->mode = mode; dd->bdev = NULL; - if ((r = open_dev(dd, dev, t->md))) { + if ((r = open_dev(dd, dev))) { kfree(dd); return r; } @@ -465,7 +461,7 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti, list_add(&dd->list, &t->devices); } else if (dd->mode != (mode | dd->mode)) { - r = upgrade_mode(dd, mode, t->md); + r = upgrade_mode(dd, mode); if (r) return r; } @@ -529,8 +525,6 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start, rs->seg_boundary_mask = min_not_zero(rs->seg_boundary_mask, q->seg_boundary_mask); - - rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); } return r; @@ -542,7 +536,7 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start, void dm_put_device(struct dm_target *ti, struct dm_dev *dd) { if (atomic_dec_and_test(&dd->count)) { - close_dev(dd, ti->table->md); + close_dev(dd); list_del(&dd->list); kfree(dd); } @@ -771,14 +765,14 @@ int dm_table_complete(struct dm_table *t) return r; } -static DEFINE_MUTEX(_event_lock); +static DECLARE_MUTEX(_event_lock); void dm_table_event_callback(struct dm_table *t, void (*fn)(void *), void *context) { - mutex_lock(&_event_lock); + down(&_event_lock); t->event_fn = fn; t->event_context = context; - mutex_unlock(&_event_lock); + up(&_event_lock); } void dm_table_event(struct dm_table *t) @@ -789,10 +783,10 @@ void dm_table_event(struct dm_table *t) */ BUG_ON(in_interrupt()); - mutex_lock(&_event_lock); + down(&_event_lock); if (t->event_fn) t->event_fn(t->event_context); - mutex_unlock(&_event_lock); + up(&_event_lock); } sector_t dm_table_get_size(struct dm_table *t) @@ -840,11 +834,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q) q->hardsect_size = t->limits.hardsect_size; q->max_segment_size = t->limits.max_segment_size; q->seg_boundary_mask = t->limits.seg_boundary_mask; - if (t->limits.no_cluster) - q->queue_flags &= ~(1 << QUEUE_FLAG_CLUSTER); - else - q->queue_flags |= (1 << QUEUE_FLAG_CLUSTER); - } unsigned int dm_table_get_num_targets(struct dm_table *t) @@ -956,20 +945,12 @@ int dm_table_flush_all(struct dm_table *t) return ret; } -struct mapped_device *dm_table_get_md(struct dm_table *t) -{ - dm_get(t->md); - - return t->md; -} - EXPORT_SYMBOL(dm_vcalloc); EXPORT_SYMBOL(dm_get_device); EXPORT_SYMBOL(dm_put_device); EXPORT_SYMBOL(dm_table_event); EXPORT_SYMBOL(dm_table_get_size); EXPORT_SYMBOL(dm_table_get_mode); -EXPORT_SYMBOL(dm_table_get_md); EXPORT_SYMBOL(dm_table_put); EXPORT_SYMBOL(dm_table_get); EXPORT_SYMBOL(dm_table_unplug_all); diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c index 64fd8e79e..aecd9e0c2 100644 --- a/drivers/md/dm-target.c +++ b/drivers/md/dm-target.c @@ -78,7 +78,8 @@ void dm_put_target_type(struct target_type *t) if (--ti->use == 0) module_put(ti->tt.module); - BUG_ON(ti->use < 0); + if (ti->use < 0) + BUG(); up_read(&_lock); return; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index dfd037858..973b6f6ff 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -18,15 +17,12 @@ #include #include #include -#include -#include static const char *_name = DM_NAME; static unsigned int major = 0; static unsigned int _major = 0; -static DEFINE_SPINLOCK(_minor_lock); /* * One of these is allocated per bio. */ @@ -55,15 +51,12 @@ union map_info *dm_get_mapinfo(struct bio *bio) return NULL; } -#define MINOR_ALLOCED ((void *)-1) - /* * Bits for the md->flags field. */ #define DMF_BLOCK_IO 0 #define DMF_SUSPENDED 1 #define DMF_FROZEN 2 -#define DMF_FREEING 3 struct mapped_device { struct rw_semaphore io_lock; @@ -75,7 +68,6 @@ struct mapped_device { request_queue_t *queue; struct gendisk *disk; - char name[16]; void *interface_ptr; @@ -108,9 +100,6 @@ struct mapped_device { */ struct super_block *frozen_sb; struct block_device *suspended_bdev; - - /* forced geometry settings */ - struct hd_geometry geometry; }; #define MIN_IOS 256 @@ -222,23 +211,9 @@ static int dm_blk_open(struct inode *inode, struct file *file) { struct mapped_device *md; - spin_lock(&_minor_lock); - md = inode->i_bdev->bd_disk->private_data; - if (!md) - goto out; - - if (test_bit(DMF_FREEING, &md->flags)) { - md = NULL; - goto out; - } - dm_get(md); - -out: - spin_unlock(&_minor_lock); - - return md ? 0 : -ENXIO; + return 0; } static int dm_blk_close(struct inode *inode, struct file *file) @@ -250,13 +225,6 @@ static int dm_blk_close(struct inode *inode, struct file *file) return 0; } -static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct mapped_device *md = bdev->bd_disk->private_data; - - return dm_get_geometry(md, geo); -} - static inline struct dm_io *alloc_io(struct mapped_device *md) { return mempool_alloc(md->io_pool, GFP_NOIO); @@ -343,33 +311,6 @@ struct dm_table *dm_get_table(struct mapped_device *md) return t; } -/* - * Get the geometry associated with a dm device - */ -int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo) -{ - *geo = md->geometry; - - return 0; -} - -/* - * Set the geometry of a device. - */ -int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo) -{ - sector_t sz = (sector_t)geo->cylinders * geo->heads * geo->sectors; - - if (geo->start > sz) { - DMWARN("Start sector is beyond the geometry limits."); - return -EINVAL; - } - - md->geometry = *geo; - - return 0; -} - /*----------------------------------------------------------------- * CRUD START: * A more elegant soln is in the works that uses the queue @@ -393,8 +334,6 @@ static void dec_pending(struct dm_io *io, int error) /* nudge anyone waiting on suspend queue */ wake_up(&io->md->wait); - blk_add_trace_bio(io->md->queue, io->bio, BLK_TA_COMPLETE); - bio_endio(io->bio, io->bio->bi_size, io->error); free_io(io->md, io); } @@ -453,7 +392,6 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, struct target_io *tio) { int r; - sector_t sector; /* * Sanity checks. @@ -469,17 +407,10 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, * this io. */ atomic_inc(&tio->io->io_count); - sector = clone->bi_sector; r = ti->type->map(ti, clone, &tio->info); - if (r > 0) { + if (r > 0) /* the bio has been remapped so dispatch it */ - - blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone, - tio->io->bio->bi_bdev->bd_dev, sector, - clone->bi_sector); - generic_make_request(clone); - } else if (r < 0) { /* error the io and bail out */ @@ -762,13 +693,14 @@ static int dm_any_congested(void *congested_data, int bdi_bits) /*----------------------------------------------------------------- * An IDR is used to keep track of allocated minor numbers. *---------------------------------------------------------------*/ +static DECLARE_MUTEX(_minor_lock); static DEFINE_IDR(_minor_idr); static void free_minor(unsigned int minor) { - spin_lock(&_minor_lock); + down(&_minor_lock); idr_remove(&_minor_idr, minor); - spin_unlock(&_minor_lock); + up(&_minor_lock); } /* @@ -781,20 +713,23 @@ static int specific_minor(struct mapped_device *md, unsigned int minor) if (minor >= (1 << MINORBITS)) return -EINVAL; - r = idr_pre_get(&_minor_idr, GFP_KERNEL); - if (!r) - return -ENOMEM; - - spin_lock(&_minor_lock); + down(&_minor_lock); if (idr_find(&_minor_idr, minor)) { r = -EBUSY; goto out; } - r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m); - if (r) + r = idr_pre_get(&_minor_idr, GFP_KERNEL); + if (!r) { + r = -ENOMEM; goto out; + } + + r = idr_get_new_above(&_minor_idr, md, minor, &m); + if (r) { + goto out; + } if (m != minor) { idr_remove(&_minor_idr, m); @@ -803,7 +738,7 @@ static int specific_minor(struct mapped_device *md, unsigned int minor) } out: - spin_unlock(&_minor_lock); + up(&_minor_lock); return r; } @@ -812,13 +747,15 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor) int r; unsigned int m; - r = idr_pre_get(&_minor_idr, GFP_KERNEL); - if (!r) - return -ENOMEM; + down(&_minor_lock); - spin_lock(&_minor_lock); + r = idr_pre_get(&_minor_idr, GFP_KERNEL); + if (!r) { + r = -ENOMEM; + goto out; + } - r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m); + r = idr_get_new(&_minor_idr, md, &m); if (r) { goto out; } @@ -832,7 +769,7 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor) *minor = m; out: - spin_unlock(&_minor_lock); + up(&_minor_lock); return r; } @@ -845,7 +782,6 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) { int r; struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL); - void *old_md; if (!md) { DMWARN("unable to allocate device, out of memory."); @@ -879,11 +815,13 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) md->queue->unplug_fn = dm_unplug_all; md->queue->issue_flush_fn = dm_flush_all; - md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache); + md->io_pool = mempool_create(MIN_IOS, mempool_alloc_slab, + mempool_free_slab, _io_cache); if (!md->io_pool) goto bad2; - md->tio_pool = mempool_create_slab_pool(MIN_IOS, _tio_cache); + md->tio_pool = mempool_create(MIN_IOS, mempool_alloc_slab, + mempool_free_slab, _tio_cache); if (!md->tio_pool) goto bad3; @@ -891,10 +829,6 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) if (!md->disk) goto bad4; - atomic_set(&md->pending, 0); - init_waitqueue_head(&md->wait); - init_waitqueue_head(&md->eventq); - md->disk->major = _major; md->disk->first_minor = minor; md->disk->fops = &dm_blk_dops; @@ -902,14 +836,10 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) md->disk->private_data = md; sprintf(md->disk->disk_name, "dm-%d", minor); add_disk(md->disk); - format_dev_t(md->name, MKDEV(_major, minor)); - /* Populate the mapping, nobody knows we exist yet */ - spin_lock(&_minor_lock); - old_md = idr_replace(&_minor_idr, md, minor); - spin_unlock(&_minor_lock); - - BUG_ON(old_md != MINOR_ALLOCED); + atomic_set(&md->pending, 0); + init_waitqueue_head(&md->wait); + init_waitqueue_head(&md->eventq); return md; @@ -918,7 +848,7 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) bad3: mempool_destroy(md->io_pool); bad2: - blk_cleanup_queue(md->queue); + blk_put_queue(md->queue); free_minor(minor); bad1: module_put(THIS_MODULE); @@ -939,13 +869,8 @@ static void free_dev(struct mapped_device *md) mempool_destroy(md->io_pool); del_gendisk(md->disk); free_minor(minor); - - spin_lock(&_minor_lock); - md->disk->private_data = NULL; - spin_unlock(&_minor_lock); - put_disk(md->disk); - blk_cleanup_queue(md->queue); + blk_put_queue(md->queue); module_put(THIS_MODULE); kfree(md); } @@ -976,13 +901,6 @@ static int __bind(struct mapped_device *md, struct dm_table *t) sector_t size; size = dm_table_get_size(t); - - /* - * Wipe any geometry if the size of the table changed. - */ - if (size != get_capacity(md->disk)) - memset(&md->geometry, 0, sizeof(md->geometry)); - __set_size(md, size); if (size == 0) return 0; @@ -1046,18 +964,13 @@ static struct mapped_device *dm_find_md(dev_t dev) if (MAJOR(dev) != _major || minor >= (1 << MINORBITS)) return NULL; - spin_lock(&_minor_lock); + down(&_minor_lock); md = idr_find(&_minor_idr, minor); - if (md && (md == MINOR_ALLOCED || - (dm_disk(md)->first_minor != minor) || - test_bit(DMF_FREEING, &md->flags))) { + if (!md || (dm_disk(md)->first_minor != minor)) md = NULL; - goto out; - } -out: - spin_unlock(&_minor_lock); + up(&_minor_lock); return md; } @@ -1072,9 +985,15 @@ struct mapped_device *dm_get_md(dev_t dev) return md; } -void *dm_get_mdptr(struct mapped_device *md) +void *dm_get_mdptr(dev_t dev) { - return md->interface_ptr; + struct mapped_device *md; + void *mdptr = NULL; + + md = dm_find_md(dev); + if (md) + mdptr = md->interface_ptr; + return mdptr; } void dm_set_mdptr(struct mapped_device *md, void *ptr) @@ -1089,23 +1008,18 @@ void dm_get(struct mapped_device *md) void dm_put(struct mapped_device *md) { - struct dm_table *map; - - BUG_ON(test_bit(DMF_FREEING, &md->flags)); + struct dm_table *map = dm_get_table(md); - if (atomic_dec_and_lock(&md->holders, &_minor_lock)) { - map = dm_get_table(md); - idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor); - set_bit(DMF_FREEING, &md->flags); - spin_unlock(&_minor_lock); + if (atomic_dec_and_test(&md->holders)) { if (!dm_suspended(md)) { dm_table_presuspend_targets(map); dm_table_postsuspend_targets(map); } __unbind(md); - dm_table_put(map); free_dev(md); } + + dm_table_put(map); } /* @@ -1348,7 +1262,6 @@ int dm_suspended(struct mapped_device *md) static struct block_device_operations dm_blk_dops = { .open = dm_blk_open, .release = dm_blk_close, - .getgeo = dm_blk_getgeo, .owner = THIS_MODULE }; diff --git a/drivers/md/dm.h b/drivers/md/dm.h index fd90bc8f9..4eaf075da 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -14,7 +14,6 @@ #include #include #include -#include #define DM_NAME "device-mapper" #define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x) @@ -24,6 +23,16 @@ #define DMEMIT(x...) sz += ((sz >= maxlen) ? \ 0 : scnprintf(result + sz, maxlen - sz, x)) +/* + * FIXME: I think this should be with the definition of sector_t + * in types.h. + */ +#ifdef CONFIG_LBD +#define SECTOR_FORMAT "%llu" +#else +#define SECTOR_FORMAT "%lu" +#endif + #define SECTOR_SHIFT 9 /* @@ -48,7 +57,7 @@ struct mapped_device; int dm_create(struct mapped_device **md); int dm_create_with_minor(unsigned int minor, struct mapped_device **md); void dm_set_mdptr(struct mapped_device *md, void *ptr); -void *dm_get_mdptr(struct mapped_device *md); +void *dm_get_mdptr(dev_t dev); struct mapped_device *dm_get_md(dev_t dev); /* @@ -86,18 +95,11 @@ int dm_wait_event(struct mapped_device *md, int event_nr); struct gendisk *dm_disk(struct mapped_device *md); int dm_suspended(struct mapped_device *md); -/* - * Geometry functions. - */ -int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo); -int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); - /*----------------------------------------------------------------- * Functions for manipulating a table. Tables are also reference * counted. *---------------------------------------------------------------*/ -int dm_table_create(struct dm_table **result, int mode, - unsigned num_targets, struct mapped_device *md); +int dm_table_create(struct dm_table **result, int mode, unsigned num_targets); void dm_table_get(struct dm_table *t); void dm_table_put(struct dm_table *t); @@ -115,7 +117,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q); unsigned int dm_table_get_num_targets(struct dm_table *t); struct list_head *dm_table_get_devices(struct dm_table *t); int dm_table_get_mode(struct dm_table *t); -struct mapped_device *dm_table_get_md(struct dm_table *t); void dm_table_presuspend_targets(struct dm_table *t); void dm_table_postsuspend_targets(struct dm_table *t); void dm_table_resume_targets(struct dm_table *t); diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c index 72480a48d..fc009cb39 100644 --- a/drivers/md/kcopyd.c +++ b/drivers/md/kcopyd.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "kcopyd.h" @@ -231,7 +230,8 @@ static int jobs_init(void) if (!_job_cache) return -ENOMEM; - _job_pool = mempool_create_slab_pool(MIN_JOBS, _job_cache); + _job_pool = mempool_create(MIN_JOBS, mempool_alloc_slab, + mempool_free_slab, _job_cache); if (!_job_pool) { kmem_cache_destroy(_job_cache); return -ENOMEM; @@ -582,68 +582,68 @@ int kcopyd_cancel(struct kcopyd_job *job, int block) /*----------------------------------------------------------------- * Unit setup *---------------------------------------------------------------*/ -static DEFINE_MUTEX(_client_lock); +static DECLARE_MUTEX(_client_lock); static LIST_HEAD(_clients); static void client_add(struct kcopyd_client *kc) { - mutex_lock(&_client_lock); + down(&_client_lock); list_add(&kc->list, &_clients); - mutex_unlock(&_client_lock); + up(&_client_lock); } static void client_del(struct kcopyd_client *kc) { - mutex_lock(&_client_lock); + down(&_client_lock); list_del(&kc->list); - mutex_unlock(&_client_lock); + up(&_client_lock); } -static DEFINE_MUTEX(kcopyd_init_lock); +static DECLARE_MUTEX(kcopyd_init_lock); static int kcopyd_clients = 0; static int kcopyd_init(void) { int r; - mutex_lock(&kcopyd_init_lock); + down(&kcopyd_init_lock); if (kcopyd_clients) { /* Already initialized. */ kcopyd_clients++; - mutex_unlock(&kcopyd_init_lock); + up(&kcopyd_init_lock); return 0; } r = jobs_init(); if (r) { - mutex_unlock(&kcopyd_init_lock); + up(&kcopyd_init_lock); return r; } _kcopyd_wq = create_singlethread_workqueue("kcopyd"); if (!_kcopyd_wq) { jobs_exit(); - mutex_unlock(&kcopyd_init_lock); + up(&kcopyd_init_lock); return -ENOMEM; } kcopyd_clients++; INIT_WORK(&_kcopyd_work, do_work, NULL); - mutex_unlock(&kcopyd_init_lock); + up(&kcopyd_init_lock); return 0; } static void kcopyd_exit(void) { - mutex_lock(&kcopyd_init_lock); + down(&kcopyd_init_lock); kcopyd_clients--; if (!kcopyd_clients) { jobs_exit(); destroy_workqueue(_kcopyd_wq); _kcopyd_wq = NULL; } - mutex_unlock(&kcopyd_init_lock); + up(&kcopyd_init_lock); } int kcopyd_client_create(unsigned int nr_pages, struct kcopyd_client **result) diff --git a/drivers/md/md.c b/drivers/md/md.c index f19b87475..2fd2cd447 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -43,7 +43,6 @@ #include /* for invalidate_bdev */ #include #include -#include #include @@ -159,18 +158,7 @@ static int start_readonly; */ static DECLARE_WAIT_QUEUE_HEAD(md_event_waiters); static atomic_t md_event_count; -void md_new_event(mddev_t *mddev) -{ - atomic_inc(&md_event_count); - wake_up(&md_event_waiters); - sysfs_notify(&mddev->kobj, NULL, "sync_action"); -} -EXPORT_SYMBOL_GPL(md_new_event); - -/* Alternate version that can be called from interrupts - * when calling sysfs_notify isn't needed. - */ -void md_new_event_inintr(mddev_t *mddev) +static void md_new_event(mddev_t *mddev) { atomic_inc(&md_event_count); wake_up(&md_event_waiters); @@ -225,11 +213,10 @@ static void mddev_put(mddev_t *mddev) return; if (!mddev->raid_disks && list_empty(&mddev->disks)) { list_del(&mddev->all_mddevs); - spin_unlock(&all_mddevs_lock); - blk_cleanup_queue(mddev->queue); + blk_put_queue(mddev->queue); kobject_unregister(&mddev->kobj); - } else - spin_unlock(&all_mddevs_lock); + } + spin_unlock(&all_mddevs_lock); } static mddev_t * mddev_find(dev_t unit) @@ -263,7 +250,7 @@ static mddev_t * mddev_find(dev_t unit) else new->md_minor = MINOR(unit) >> MdpMinorShift; - mutex_init(&new->reconfig_mutex); + init_MUTEX(&new->reconfig_sem); INIT_LIST_HEAD(&new->disks); INIT_LIST_HEAD(&new->all_mddevs); init_timer(&new->safemode_timer); @@ -276,7 +263,6 @@ static mddev_t * mddev_find(dev_t unit) kfree(new); return NULL; } - set_bit(QUEUE_FLAG_CLUSTER, &new->queue->queue_flags); blk_queue_make_request(new->queue, md_fail_request); @@ -285,17 +271,22 @@ static mddev_t * mddev_find(dev_t unit) static inline int mddev_lock(mddev_t * mddev) { - return mutex_lock_interruptible(&mddev->reconfig_mutex); + return down_interruptible(&mddev->reconfig_sem); +} + +static inline void mddev_lock_uninterruptible(mddev_t * mddev) +{ + down(&mddev->reconfig_sem); } static inline int mddev_trylock(mddev_t * mddev) { - return mutex_trylock(&mddev->reconfig_mutex); + return down_trylock(&mddev->reconfig_sem); } static inline void mddev_unlock(mddev_t * mddev) { - mutex_unlock(&mddev->reconfig_mutex); + up(&mddev->reconfig_sem); md_wakeup_thread(mddev->thread); } @@ -666,8 +657,7 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version } if (sb->major_version != 0 || - sb->minor_version < 90 || - sb->minor_version > 91) { + sb->minor_version != 90) { printk(KERN_WARNING "Bad version number %d.%d on %s\n", sb->major_version, sb->minor_version, b); @@ -752,20 +742,6 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) mddev->bitmap_offset = 0; mddev->default_bitmap_offset = MD_SB_BYTES >> 9; - if (mddev->minor_version >= 91) { - mddev->reshape_position = sb->reshape_position; - mddev->delta_disks = sb->delta_disks; - mddev->new_level = sb->new_level; - mddev->new_layout = sb->new_layout; - mddev->new_chunk = sb->new_chunk; - } else { - mddev->reshape_position = MaxSector; - mddev->delta_disks = 0; - mddev->new_level = mddev->level; - mddev->new_layout = mddev->layout; - mddev->new_chunk = mddev->chunk_size; - } - if (sb->state & (1<recovery_cp = MaxSector; else { @@ -785,8 +761,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) if (sb->state & (1<bitmap_file == NULL) { - if (mddev->level != 1 && mddev->level != 4 - && mddev->level != 5 && mddev->level != 6 + if (mddev->level != 1 && mddev->level != 5 && mddev->level != 6 && mddev->level != 10) { /* FIXME use a better test */ printk(KERN_WARNING "md: bitmaps not supported for this level.\n"); @@ -860,6 +835,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->md_magic = MD_SB_MAGIC; sb->major_version = mddev->major_version; + sb->minor_version = mddev->minor_version; sb->patch_version = mddev->patch_version; sb->gvalid_words = 0; /* ignored */ memcpy(&sb->set_uuid0, mddev->uuid+0, 4); @@ -878,17 +854,6 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->events_hi = (mddev->events>>32); sb->events_lo = (u32)mddev->events; - if (mddev->reshape_position == MaxSector) - sb->minor_version = 90; - else { - sb->minor_version = 91; - sb->reshape_position = mddev->reshape_position; - sb->new_level = mddev->new_level; - sb->delta_disks = mddev->delta_disks; - sb->new_layout = mddev->new_layout; - sb->new_chunk = mddev->new_chunk; - } - mddev->minor_version = sb->minor_version; if (mddev->in_sync) { sb->recovery_cp = mddev->recovery_cp; @@ -925,9 +890,10 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) d->raid_disk = rdev2->raid_disk; else d->raid_disk = rdev2->desc_nr; /* compatibility */ - if (test_bit(Faulty, &rdev2->flags)) + if (test_bit(Faulty, &rdev2->flags)) { d->state = (1<flags)) { + failed++; + } else if (test_bit(In_sync, &rdev2->flags)) { d->state = (1<state |= (1<bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset); } - if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) { - mddev->reshape_position = le64_to_cpu(sb->reshape_position); - mddev->delta_disks = le32_to_cpu(sb->delta_disks); - mddev->new_level = le32_to_cpu(sb->new_level); - mddev->new_layout = le32_to_cpu(sb->new_layout); - mddev->new_chunk = le32_to_cpu(sb->new_chunk)<<9; - } else { - mddev->reshape_position = MaxSector; - mddev->delta_disks = 0; - mddev->new_level = mddev->level; - mddev->new_layout = mddev->layout; - mddev->new_chunk = mddev->chunk_size; - } - } else if (mddev->pers == NULL) { /* Insist of good event counter while assembling */ __u64 ev1 = le64_to_cpu(sb->events); @@ -1218,14 +1170,6 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); } - if (mddev->reshape_position != MaxSector) { - sb->feature_map |= cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE); - sb->reshape_position = cpu_to_le64(mddev->reshape_position); - sb->new_layout = cpu_to_le32(mddev->new_layout); - sb->delta_disks = cpu_to_le32(mddev->delta_disks); - sb->new_level = cpu_to_le32(mddev->new_level); - sb->new_chunk = cpu_to_le32(mddev->new_chunk>>9); - } max_dev = 0; ITERATE_RDEV(mddev,rdev2,tmp) @@ -1354,7 +1298,6 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) else ko = &rdev->bdev->bd_disk->kobj; sysfs_create_link(&rdev->kobj, ko, "block"); - bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk); return 0; } @@ -1365,7 +1308,6 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) MD_BUG(); return; } - bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk); list_del_init(&rdev->same_set); printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); rdev->mddev = NULL; @@ -1548,7 +1490,7 @@ static void sync_sbs(mddev_t * mddev) } } -void md_update_sb(mddev_t * mddev) +static void md_update_sb(mddev_t * mddev) { int err; struct list_head *tmp; @@ -1625,7 +1567,6 @@ repeat: wake_up(&mddev->sb_wait); } -EXPORT_SYMBOL_GPL(md_update_sb); /* words written to sysfs files may, or my not, be \n terminated. * We want to accept with case. For this we use cmd_match. @@ -2218,9 +2159,7 @@ action_show(mddev_t *mddev, char *page) char *type = "idle"; if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) { - if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) - type = "reshape"; - else if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { + if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) type = "resync"; else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) @@ -2251,17 +2190,10 @@ action_store(mddev_t *mddev, const char *page, size_t len) return -EBUSY; else if (cmd_match(page, "resync") || cmd_match(page, "recover")) set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); - else if (cmd_match(page, "reshape")) { - int err; - if (mddev->pers->start_reshape == NULL) - return -EINVAL; - err = mddev->pers->start_reshape(mddev); - if (err) - return err; - } else { + else { if (cmd_match(page, "check")) set_bit(MD_RECOVERY_CHECK, &mddev->recovery); - else if (!cmd_match(page, "repair")) + else if (cmd_match(page, "repair")) return -EINVAL; set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); set_bit(MD_RECOVERY_SYNC, &mddev->recovery); @@ -2369,63 +2301,6 @@ sync_completed_show(mddev_t *mddev, char *page) static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); -static ssize_t -suspend_lo_show(mddev_t *mddev, char *page) -{ - return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_lo); -} - -static ssize_t -suspend_lo_store(mddev_t *mddev, const char *buf, size_t len) -{ - char *e; - unsigned long long new = simple_strtoull(buf, &e, 10); - - if (mddev->pers->quiesce == NULL) - return -EINVAL; - if (buf == e || (*e && *e != '\n')) - return -EINVAL; - if (new >= mddev->suspend_hi || - (new > mddev->suspend_lo && new < mddev->suspend_hi)) { - mddev->suspend_lo = new; - mddev->pers->quiesce(mddev, 2); - return len; - } else - return -EINVAL; -} -static struct md_sysfs_entry md_suspend_lo = -__ATTR(suspend_lo, S_IRUGO|S_IWUSR, suspend_lo_show, suspend_lo_store); - - -static ssize_t -suspend_hi_show(mddev_t *mddev, char *page) -{ - return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_hi); -} - -static ssize_t -suspend_hi_store(mddev_t *mddev, const char *buf, size_t len) -{ - char *e; - unsigned long long new = simple_strtoull(buf, &e, 10); - - if (mddev->pers->quiesce == NULL) - return -EINVAL; - if (buf == e || (*e && *e != '\n')) - return -EINVAL; - if ((new <= mddev->suspend_lo && mddev->suspend_lo >= mddev->suspend_hi) || - (new > mddev->suspend_lo && new > mddev->suspend_hi)) { - mddev->suspend_hi = new; - mddev->pers->quiesce(mddev, 1); - mddev->pers->quiesce(mddev, 0); - return len; - } else - return -EINVAL; -} -static struct md_sysfs_entry md_suspend_hi = -__ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store); - - static struct attribute *md_default_attrs[] = { &md_level.attr, &md_raid_disks.attr, @@ -2443,8 +2318,6 @@ static struct attribute *md_redundancy_attrs[] = { &md_sync_max.attr, &md_sync_speed.attr, &md_sync_completed.attr, - &md_suspend_lo.attr, - &md_suspend_hi.attr, NULL, }; static struct attribute_group md_redundancy_group = { @@ -2462,11 +2335,9 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) if (!entry->show) return -EIO; - rv = mddev_lock(mddev); - if (!rv) { - rv = entry->show(mddev, page); - mddev_unlock(mddev); - } + mddev_lock(mddev); + rv = entry->show(mddev, page); + mddev_unlock(mddev); return rv; } @@ -2480,11 +2351,9 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, if (!entry->store) return -EIO; - rv = mddev_lock(mddev); - if (!rv) { - rv = entry->store(mddev, page, length); - mddev_unlock(mddev); - } + mddev_lock(mddev); + rv = entry->store(mddev, page, length); + mddev_unlock(mddev); return rv; } @@ -2508,7 +2377,7 @@ int mdp_major = 0; static struct kobject *md_probe(dev_t dev, int *part, void *data) { - static DEFINE_MUTEX(disks_mutex); + static DECLARE_MUTEX(disks_sem); mddev_t *mddev = mddev_find(dev); struct gendisk *disk; int partitioned = (MAJOR(dev) != MD_MAJOR); @@ -2518,15 +2387,15 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) if (!mddev) return NULL; - mutex_lock(&disks_mutex); + down(&disks_sem); if (mddev->gendisk) { - mutex_unlock(&disks_mutex); + up(&disks_sem); mddev_put(mddev); return NULL; } disk = alloc_disk(1 << shift); if (!disk) { - mutex_unlock(&disks_mutex); + up(&disks_sem); mddev_put(mddev); return NULL; } @@ -2544,7 +2413,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) disk->queue = mddev->queue; add_disk(disk); mddev->gendisk = disk; - mutex_unlock(&disks_mutex); + up(&disks_sem); mddev->kobj.parent = &disk->kobj; mddev->kobj.k_name = NULL; snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md"); @@ -2667,14 +2536,6 @@ static int do_md_run(mddev_t * mddev) mddev->level = pers->level; strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); - if (mddev->reshape_position != MaxSector && - pers->start_reshape == NULL) { - /* This personality cannot handle reshaping... */ - mddev->pers = NULL; - module_put(pers->owner); - return -EINVAL; - } - mddev->recovery = 0; mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ mddev->barriers_work = 1; @@ -2908,6 +2769,7 @@ static void autorun_array(mddev_t *mddev) */ static void autorun_devices(int part) { + struct list_head candidates; struct list_head *tmp; mdk_rdev_t *rdev0, *rdev; mddev_t *mddev; @@ -2916,7 +2778,6 @@ static void autorun_devices(int part) printk(KERN_INFO "md: autorun ...\n"); while (!list_empty(&pending_raid_disks)) { dev_t dev; - LIST_HEAD(candidates); rdev0 = list_entry(pending_raid_disks.next, mdk_rdev_t, same_set); @@ -3563,18 +3424,11 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) mddev->default_bitmap_offset = MD_SB_BYTES >> 9; mddev->bitmap_offset = 0; - mddev->reshape_position = MaxSector; - /* * Generate a 128 bit UUID */ get_random_bytes(mddev->uuid, 16); - mddev->new_level = mddev->level; - mddev->new_chunk = mddev->chunk_size; - mddev->new_layout = mddev->layout; - mddev->delta_disks = 0; - return 0; } @@ -3630,16 +3484,14 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) { int rv; /* change the number of raid disks */ - if (mddev->pers->check_reshape == NULL) + if (mddev->pers->reshape == NULL) return -EINVAL; if (raid_disks <= 0 || raid_disks >= mddev->max_disks) return -EINVAL; - if (mddev->sync_thread || mddev->reshape_position != MaxSector) + if (mddev->sync_thread) return -EBUSY; - mddev->delta_disks = raid_disks - mddev->raid_disks; - - rv = mddev->pers->check_reshape(mddev); + rv = mddev->pers->reshape(mddev, raid_disks); return rv; } @@ -3810,7 +3662,7 @@ static int md_ioctl(struct inode *inode, struct file *file, if (cnt > 0 ) { printk(KERN_WARNING "md: %s(pid %d) used deprecated START_ARRAY ioctl. " - "This will not be supported beyond July 2006\n", + "START_ARRAY is removed in kernel 2.6.19 and above.\n", current->comm, current->pid); cnt--; } @@ -4158,7 +4010,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) set_bit(MD_RECOVERY_INTR, &mddev->recovery); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); - md_new_event_inintr(mddev); + md_new_event(mddev); } /* seq_file implementation /proc/mdstat */ @@ -4186,10 +4038,7 @@ static void status_unused(struct seq_file *seq) static void status_resync(struct seq_file *seq, mddev_t * mddev) { - sector_t max_blocks, resync, res; - unsigned long dt, db, rt; - int scale; - unsigned int per_milli; + unsigned long max_blocks, resync, res, dt, db, rt; resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active))/2; @@ -4205,22 +4054,9 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev) MD_BUG(); return; } - /* Pick 'scale' such that (resync>>scale)*1000 will fit - * in a sector_t, and (max_blocks>>scale) will fit in a - * u32, as those are the requirements for sector_div. - * Thus 'scale' must be at least 10 - */ - scale = 10; - if (sizeof(sector_t) > sizeof(unsigned long)) { - while ( max_blocks/2 > (1ULL<<(scale+32))) - scale++; - } - res = (resync>>scale)*1000; - sector_div(res, (u32)((max_blocks>>scale)+1)); - - per_milli = res; + res = (resync/1024)*1000/(max_blocks/1024 + 1); { - int i, x = per_milli/50, y = 20-x; + int i, x = res/50, y = 20-x; seq_printf(seq, "["); for (i = 0; i < x; i++) seq_printf(seq, "="); @@ -4229,14 +4065,10 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev) seq_printf(seq, "."); seq_printf(seq, "] "); } - seq_printf(seq, " %s =%3u.%u%% (%llu/%llu)", - (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)? - "reshape" : + seq_printf(seq, " %s =%3lu.%lu%% (%lu/%lu)", (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ? - "resync" : "recovery")), - per_milli/10, per_milli % 10, - (unsigned long long) resync, - (unsigned long long) max_blocks); + "resync" : "recovery"), + res/10, res % 10, resync, max_blocks); /* * We do not want to overflow, so the order of operands and @@ -4250,7 +4082,7 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev) dt = ((jiffies - mddev->resync_mark) / HZ); if (!dt) dt++; db = resync - (mddev->resync_mark_cnt/2); - rt = (dt * ((unsigned long)(max_blocks-resync) / (db/100+1)))/100; + rt = (dt * ((max_blocks-resync) / (db/100+1)))/100; seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6); @@ -4349,9 +4181,8 @@ static int md_seq_show(struct seq_file *seq, void *v) return 0; } - if (mddev_lock(mddev) < 0) + if (mddev_lock(mddev)!=0) return -EINTR; - if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) { seq_printf(seq, "%s : %sactive", mdname(mddev), mddev->pers ? "" : "in"); @@ -4608,7 +4439,7 @@ static DECLARE_WAIT_QUEUE_HEAD(resync_wait); #define SYNC_MARKS 10 #define SYNC_MARK_STEP (3*HZ) -void md_do_sync(mddev_t *mddev) +static void md_do_sync(mddev_t *mddev) { mddev_t *mddev2; unsigned int currspeed = 0, @@ -4688,9 +4519,7 @@ void md_do_sync(mddev_t *mddev) */ max_sectors = mddev->resync_max_sectors; mddev->resync_mismatches = 0; - } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) - max_sectors = mddev->size << 1; - else + } else /* recovery follows the physical size of devices */ max_sectors = mddev->size << 1; @@ -4826,8 +4655,6 @@ void md_do_sync(mddev_t *mddev) mddev->pers->sync_request(mddev, max_sectors, &skipped, 1); if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && - test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && - !test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && mddev->curr_resync > 2 && mddev->curr_resync >= mddev->recovery_cp) { if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { @@ -4845,7 +4672,6 @@ void md_do_sync(mddev_t *mddev) set_bit(MD_RECOVERY_DONE, &mddev->recovery); md_wakeup_thread(mddev->thread); } -EXPORT_SYMBOL_GPL(md_do_sync); /* @@ -4901,7 +4727,7 @@ void md_check_recovery(mddev_t *mddev) )) return; - if (mddev_trylock(mddev)) { + if (mddev_trylock(mddev)==0) { int spares =0; spin_lock_irq(&mddev->write_lock); @@ -5037,10 +4863,8 @@ static int md_notify_reboot(struct notifier_block *this, printk(KERN_INFO "md: stopping all md devices.\n"); ITERATE_MDDEV(mddev,tmp) - if (mddev_trylock(mddev)) { + if (mddev_trylock(mddev)==0) do_md_stop (mddev, 1); - mddev_unlock(mddev); - } /* * certain more exotic SCSI devices are known to be * volatile wrt too early system reboots. While the diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 1cc9de44c..96f7af4ae 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -35,6 +35,18 @@ #define NR_RESERVED_BUFS 32 +static void *mp_pool_alloc(gfp_t gfp_flags, void *data) +{ + struct multipath_bh *mpb; + mpb = kzalloc(sizeof(*mpb), gfp_flags); + return mpb; +} + +static void mp_pool_free(void *mpb, void *data) +{ + kfree(mpb); +} + static int multipath_map (multipath_conf_t *conf) { int i, disks = conf->raid_disks; @@ -482,8 +494,9 @@ static int multipath_run (mddev_t *mddev) } mddev->degraded = conf->raid_disks = conf->working_disks; - conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS, - sizeof(struct multipath_bh)); + conf->pool = mempool_create(NR_RESERVED_BUFS, + mp_pool_alloc, mp_pool_free, + NULL); if (conf->pool == NULL) { printk(KERN_ERR "multipath: couldn't allocate memory for %s\n", diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index cb8c6317e..678f4dbbe 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -331,14 +331,13 @@ static int raid0_run (mddev_t *mddev) goto out_free_conf; size = conf->strip_zone[cur].size; - conf->hash_table[0] = conf->strip_zone + cur; - for (i=1; i< nb_zone; i++) { + for (i=0; i< nb_zone; i++) { + conf->hash_table[i] = conf->strip_zone + cur; while (size <= conf->hash_spacing) { cur++; size += conf->strip_zone[cur].size; } size -= conf->hash_spacing; - conf->hash_table[i] = conf->strip_zone + cur; } if (conf->preshift) { conf->hash_spacing >>= conf->preshift; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5a5449400..f0b7caa4a 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -315,11 +315,10 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int if (r1_bio->bios[mirror] == bio) break; - if (error == -EOPNOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) { + if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) { set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags); set_bit(R1BIO_BarrierRetry, &r1_bio->state); r1_bio->mddev->barriers_work = 0; - /* Don't rdev_dec_pending in this branch - keep it for the retry */ } else { /* * this branch is our 'one mirror IO has finished' event handler: @@ -366,7 +365,6 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int } } } - rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); } /* * @@ -376,9 +374,11 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int if (atomic_dec_and_test(&r1_bio->remaining)) { if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { reschedule_retry(r1_bio); + /* Don't dec_pending yet, we want to hold + * the reference over the retry + */ goto out; } - /* it really is the end of this request */ if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { /* free extra copy of the data pages */ int i = bio->bi_vcnt; @@ -393,6 +393,8 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int md_write_end(r1_bio->mddev); raid_end_bio_io(r1_bio); } + + rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); out: if (to_put) bio_put(to_put); @@ -751,24 +753,18 @@ static int make_request(request_queue_t *q, struct bio * bio) const int rw = bio_data_dir(bio); int do_barriers; + if (unlikely(!mddev->barriers_work && bio_barrier(bio))) { + bio_endio(bio, bio->bi_size, -EOPNOTSUPP); + return 0; + } + /* * Register the new request and wait if the reconstruction * thread has put up a bar for new requests. * Continue immediately if no resync is active currently. - * We test barriers_work *after* md_write_start as md_write_start - * may cause the first superblock write, and that will check out - * if barriers work. */ - md_write_start(mddev, bio); /* wait on superblock update early */ - if (unlikely(!mddev->barriers_work && bio_barrier(bio))) { - if (rw == WRITE) - md_write_end(mddev); - bio_endio(bio, bio->bi_size, -EOPNOTSUPP); - return 0; - } - wait_barrier(conf); disk_stat_inc(mddev->gendisk, ios[rw]); @@ -1139,19 +1135,8 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error) mirror = i; break; } - if (!uptodate) { - int sync_blocks = 0; - sector_t s = r1_bio->sector; - long sectors_to_go = r1_bio->sectors; - /* make sure these bits doesn't get cleared. */ - do { - bitmap_end_sync(mddev->bitmap, r1_bio->sector, - &sync_blocks, 1); - s += sync_blocks; - sectors_to_go -= sync_blocks; - } while (sectors_to_go > 0); + if (!uptodate) md_error(mddev, conf->mirrors[mirror].rdev); - } update_head_pos(mirror, r1_bio); @@ -1408,18 +1393,14 @@ static void raid1d(mddev_t *mddev) unplug = 1; } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { /* some requests in the r1bio were BIO_RW_BARRIER - * requests which failed with -EOPNOTSUPP. Hohumm.. + * requests which failed with -ENOTSUPP. Hohumm.. * Better resubmit without the barrier. * We know which devices to resubmit for, because * all others have had their bios[] entry cleared. - * We already have a nr_pending reference on these rdevs. */ int i; clear_bit(R1BIO_BarrierRetry, &r1_bio->state); clear_bit(R1BIO_Barrier, &r1_bio->state); - for (i=0; i < conf->raid_disks; i++) - if (r1_bio->bios[i]) - atomic_inc(&r1_bio->remaining); for (i=0; i < conf->raid_disks; i++) if (r1_bio->bios[i]) { struct bio_vec *bvec; @@ -1565,7 +1546,8 @@ static int init_resync(conf_t *conf) int buffs; buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE; - BUG_ON(conf->r1buf_pool); + if (conf->r1buf_pool) + BUG(); conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free, conf->poolinfo); if (!conf->r1buf_pool) @@ -1738,7 +1720,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) break; - BUG_ON(sync_blocks < (PAGE_SIZE>>9)); + if (sync_blocks < (PAGE_SIZE>>9)) + BUG(); if (len > (sync_blocks<<9)) len = sync_blocks<<9; } @@ -1808,11 +1791,6 @@ static int run(mddev_t *mddev) mdname(mddev), mddev->level); goto out; } - if (mddev->reshape_position != MaxSector) { - printk("raid1: %s: reshape_position set but not supported\n", - mdname(mddev)); - goto out; - } /* * copy the already verified devices into our private RAID1 * bookkeeping area. [whatever we allocate in run(), @@ -1995,7 +1973,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors) return 0; } -static int raid1_reshape(mddev_t *mddev) +static int raid1_reshape(mddev_t *mddev, int raid_disks) { /* We need to: * 1/ resize the r1bio_pool @@ -2012,22 +1990,10 @@ static int raid1_reshape(mddev_t *mddev) struct pool_info *newpoolinfo; mirror_info_t *newmirrors; conf_t *conf = mddev_to_conf(mddev); - int cnt, raid_disks; + int cnt; int d, d2; - /* Cannot change chunk_size, layout, or level */ - if (mddev->chunk_size != mddev->new_chunk || - mddev->layout != mddev->new_layout || - mddev->level != mddev->new_level) { - mddev->new_chunk = mddev->chunk_size; - mddev->new_layout = mddev->layout; - mddev->new_level = mddev->level; - return -EINVAL; - } - - raid_disks = mddev->raid_disks + mddev->delta_disks; - if (raid_disks < conf->raid_disks) { cnt=0; for (d= 0; d < conf->raid_disks; d++) @@ -2074,7 +2040,6 @@ static int raid1_reshape(mddev_t *mddev) mddev->degraded += (raid_disks - conf->raid_disks); conf->raid_disks = mddev->raid_disks = raid_disks; - mddev->delta_disks = 0; conf->last_used = 0; /* just make sure it is in-range */ lower_barrier(conf); @@ -2116,7 +2081,7 @@ static struct mdk_personality raid1_personality = .spare_active = raid1_spare_active, .sync_request = sync_request, .resize = raid1_resize, - .check_reshape = raid1_reshape, + .reshape = raid1_reshape, .quiesce = raid1_quiesce, }; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 144093541..039ed49b3 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1117,7 +1117,8 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error) for (i=0; icopies; i++) if (r10_bio->devs[i].bio == bio) break; - BUG_ON(i == conf->copies); + if (i == conf->copies) + BUG(); update_head_pos(i, r10_bio); d = r10_bio->devs[i].devnum; @@ -1407,45 +1408,36 @@ static void raid10d(mddev_t *mddev) if (s > (PAGE_SIZE>>9)) s = PAGE_SIZE >> 9; - rcu_read_lock(); do { int d = r10_bio->devs[sl].devnum; - rdev = rcu_dereference(conf->mirrors[d].rdev); + rdev = conf->mirrors[d].rdev; if (rdev && - test_bit(In_sync, &rdev->flags)) { - atomic_inc(&rdev->nr_pending); - rcu_read_unlock(); - success = sync_page_io(rdev->bdev, - r10_bio->devs[sl].addr + - sect + rdev->data_offset, - s<<9, - conf->tmppage, READ); - rdev_dec_pending(rdev, mddev); - rcu_read_lock(); - if (success) - break; + test_bit(In_sync, &rdev->flags) && + sync_page_io(rdev->bdev, + r10_bio->devs[sl].addr + + sect + rdev->data_offset, + s<<9, + conf->tmppage, READ)) + success = 1; + else { + sl++; + if (sl == conf->copies) + sl = 0; } - sl++; - if (sl == conf->copies) - sl = 0; } while (!success && sl != r10_bio->read_slot); - rcu_read_unlock(); if (success) { int start = sl; /* write it back and re-read */ - rcu_read_lock(); while (sl != r10_bio->read_slot) { int d; if (sl==0) sl = conf->copies; sl--; d = r10_bio->devs[sl].devnum; - rdev = rcu_dereference(conf->mirrors[d].rdev); + rdev = conf->mirrors[d].rdev; if (rdev && test_bit(In_sync, &rdev->flags)) { - atomic_inc(&rdev->nr_pending); - rcu_read_unlock(); atomic_add(s, &rdev->corrected_errors); if (sync_page_io(rdev->bdev, r10_bio->devs[sl].addr + @@ -1453,8 +1445,6 @@ static void raid10d(mddev_t *mddev) s<<9, conf->tmppage, WRITE) == 0) /* Well, this device is dead */ md_error(mddev, rdev); - rdev_dec_pending(rdev, mddev); - rcu_read_lock(); } } sl = start; @@ -1464,22 +1454,17 @@ static void raid10d(mddev_t *mddev) sl = conf->copies; sl--; d = r10_bio->devs[sl].devnum; - rdev = rcu_dereference(conf->mirrors[d].rdev); + rdev = conf->mirrors[d].rdev; if (rdev && test_bit(In_sync, &rdev->flags)) { - atomic_inc(&rdev->nr_pending); - rcu_read_unlock(); if (sync_page_io(rdev->bdev, r10_bio->devs[sl].addr + sect + rdev->data_offset, s<<9, conf->tmppage, READ) == 0) /* Well, this device is dead */ md_error(mddev, rdev); - rdev_dec_pending(rdev, mddev); - rcu_read_lock(); } } - rcu_read_unlock(); } else { /* Cannot read from anywhere -- bye bye array */ md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev); @@ -1533,7 +1518,8 @@ static int init_resync(conf_t *conf) int buffs; buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE; - BUG_ON(conf->r10buf_pool); + if (conf->r10buf_pool) + BUG(); conf->r10buf_pool = mempool_create(buffs, r10buf_pool_alloc, r10buf_pool_free, conf); if (!conf->r10buf_pool) return -ENOMEM; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 318436040..2dba305da 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -73,8 +72,10 @@ static void print_raid5_conf (raid5_conf_t *conf); static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) { if (atomic_dec_and_test(&sh->count)) { - BUG_ON(!list_empty(&sh->lru)); - BUG_ON(atomic_read(&conf->active_stripes)==0); + if (!list_empty(&sh->lru)) + BUG(); + if (atomic_read(&conf->active_stripes)==0) + BUG(); if (test_bit(STRIPE_HANDLE, &sh->state)) { if (test_bit(STRIPE_DELAYED, &sh->state)) list_add_tail(&sh->lru, &conf->delayed_list); @@ -92,11 +93,11 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) md_wakeup_thread(conf->mddev->thread); } + list_add_tail(&sh->lru, &conf->inactive_list); atomic_dec(&conf->active_stripes); - if (!test_bit(STRIPE_EXPANDING, &sh->state)) { - list_add_tail(&sh->lru, &conf->inactive_list); + if (!conf->inactive_blocked || + atomic_read(&conf->active_stripes) < (conf->max_nr_stripes*3/4)) wake_up(&conf->wait_for_stripe); - } } } } @@ -177,13 +178,15 @@ static int grow_buffers(struct stripe_head *sh, int num) static void raid5_build_block (struct stripe_head *sh, int i); -static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks) +static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx) { raid5_conf_t *conf = sh->raid_conf; - int i; + int disks = conf->raid_disks, i; - BUG_ON(atomic_read(&sh->count) != 0); - BUG_ON(test_bit(STRIPE_HANDLE, &sh->state)); + if (atomic_read(&sh->count) != 0) + BUG(); + if (test_bit(STRIPE_HANDLE, &sh->state)) + BUG(); CHECK_DEVLOCK(); PRINTK("init_stripe called, stripe %llu\n", @@ -195,9 +198,7 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int sh->pd_idx = pd_idx; sh->state = 0; - sh->disks = disks; - - for (i = sh->disks; i--; ) { + for (i=disks; i--; ) { struct r5dev *dev = &sh->dev[i]; if (dev->toread || dev->towrite || dev->written || @@ -214,7 +215,7 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int 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) { struct stripe_head *sh; struct hlist_node *hn; @@ -222,7 +223,7 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in CHECK_DEVLOCK(); PRINTK("__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) return sh; PRINTK("__stripe %llu not in cache\n", (unsigned long long)sector); return NULL; @@ -231,8 +232,8 @@ 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(request_queue_t *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 pd_idx, int noblock) { struct stripe_head *sh; @@ -244,7 +245,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); if (!sh) { if (!conf->inactive_blocked) sh = get_free_stripe(conf); @@ -258,19 +259,21 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector < (conf->max_nr_stripes *3/4) || !conf->inactive_blocked), conf->device_lock, - unplug_slaves(conf->mddev) + unplug_slaves(conf->mddev); ); conf->inactive_blocked = 0; } else - init_stripe(sh, sector, pd_idx, disks); + init_stripe(sh, sector, pd_idx); } else { if (atomic_read(&sh->count)) { - BUG_ON(!list_empty(&sh->lru)); + if (!list_empty(&sh->lru)) + BUG(); } else { if (!test_bit(STRIPE_HANDLE, &sh->state)) atomic_inc(&conf->active_stripes); - if (!list_empty(&sh->lru)) - list_del_init(&sh->lru); + if (list_empty(&sh->lru)) + BUG(); + list_del_init(&sh->lru); } } } while (sh == NULL); @@ -297,7 +300,6 @@ static int grow_one_stripe(raid5_conf_t *conf) kmem_cache_free(conf->slab_cache, sh); return 0; } - sh->disks = conf->raid_disks; /* we just created an active stripe so... */ atomic_set(&sh->count, 1); atomic_inc(&conf->active_stripes); @@ -311,16 +313,14 @@ static int grow_stripes(raid5_conf_t *conf, int num) kmem_cache_t *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)); - conf->active_name = 0; - sc = kmem_cache_create(conf->cache_name[conf->active_name], + sprintf(conf->cache_name, "raid5/%s", mdname(conf->mddev)); + + sc = kmem_cache_create(conf->cache_name, sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev), 0, 0, NULL, NULL); if (!sc) return 1; conf->slab_cache = sc; - conf->pool_size = devs; while (num--) { if (!grow_one_stripe(conf)) return 1; @@ -328,129 +328,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. - * New slots in each stripe get 'page' set to a new page. - * - * This happens in stages: - * 1/ create a new kmem_cache and allocate the required number of - * stripe_heads. - * 2/ gather all the old stripe_heads and tranfer the pages across - * to the new stripe_heads. This will have the side effect of - * freezing the array as once all stripe_heads have been collected, - * no IO will be possible. Old stripe heads are freed once their - * pages have been transferred over, and the old kmem_cache is - * freed when all stripes are done. - * 3/ reallocate conf->disks to be suitable bigger. If this fails, - * we simple return a failre status - no need to clean anything up. - * 4/ allocate new pages for the new slots in the new stripe_heads. - * If this fails, we don't bother trying the shrink the - * stripe_heads down again, we just leave them as they are. - * As each stripe_head is processed the new one is released into - * active service. - * - * Once step2 is started, we cannot afford to wait for a write, - * so we use GFP_NOIO allocations. - */ - struct stripe_head *osh, *nsh; - LIST_HEAD(newstripes); - struct disk_info *ndisks; - int err = 0; - kmem_cache_t *sc; - int i; - - if (newsize <= conf->pool_size) - return 0; /* never bother to shrink */ - - /* Step 1 */ - sc = kmem_cache_create(conf->cache_name[1-conf->active_name], - sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev), - 0, 0, NULL, NULL); - if (!sc) - return -ENOMEM; - - for (i = conf->max_nr_stripes; i; i--) { - nsh = kmem_cache_alloc(sc, GFP_KERNEL); - if (!nsh) - break; - - memset(nsh, 0, sizeof(*nsh) + (newsize-1)*sizeof(struct r5dev)); - - nsh->raid_conf = conf; - spin_lock_init(&nsh->lock); - - list_add(&nsh->lru, &newstripes); - } - if (i) { - /* didn't get enough, give up */ - while (!list_empty(&newstripes)) { - nsh = list_entry(newstripes.next, struct stripe_head, lru); - list_del(&nsh->lru); - kmem_cache_free(sc, nsh); - } - kmem_cache_destroy(sc); - return -ENOMEM; - } - /* Step 2 - Must use GFP_NOIO now. - * OK, we have enough stripes, start collecting inactive - * stripes and copying them over - */ - list_for_each_entry(nsh, &newstripes, lru) { - spin_lock_irq(&conf->device_lock); - wait_event_lock_irq(conf->wait_for_stripe, - !list_empty(&conf->inactive_list), - conf->device_lock, - unplug_slaves(conf->mddev) - ); - osh = get_free_stripe(conf); - spin_unlock_irq(&conf->device_lock); - atomic_set(&nsh->count, 1); - for(i=0; ipool_size; i++) - nsh->dev[i].page = osh->dev[i].page; - for( ; idev[i].page = NULL; - kmem_cache_free(conf->slab_cache, osh); - } - kmem_cache_destroy(conf->slab_cache); - - /* Step 3. - * At this point, we are holding all the stripes so the array - * is completely stalled, so now is a good time to resize - * conf->disks. - */ - ndisks = kzalloc(newsize * sizeof(struct disk_info), GFP_NOIO); - if (ndisks) { - for (i=0; iraid_disks; i++) - ndisks[i] = conf->disks[i]; - kfree(conf->disks); - conf->disks = ndisks; - } else - err = -ENOMEM; - - /* Step 4, return new stripes to service */ - while(!list_empty(&newstripes)) { - nsh = list_entry(newstripes.next, struct stripe_head, lru); - list_del_init(&nsh->lru); - for (i=conf->raid_disks; i < newsize; i++) - if (nsh->dev[i].page == NULL) { - struct page *p = alloc_page(GFP_NOIO); - nsh->dev[i].page = p; - if (!p) - err = -ENOMEM; - } - release_stripe(nsh); - } - /* critical section pass, GFP_NOIO no longer needed */ - - conf->slab_cache = sc; - conf->active_name = 1-conf->active_name; - conf->pool_size = newsize; - return err; -} -#endif - static int drop_one_stripe(raid5_conf_t *conf) { struct stripe_head *sh; @@ -460,8 +337,9 @@ static int drop_one_stripe(raid5_conf_t *conf) spin_unlock_irq(&conf->device_lock); if (!sh) return 0; - BUG_ON(atomic_read(&sh->count)); - shrink_buffers(sh, conf->pool_size); + if (atomic_read(&sh->count)) + BUG(); + shrink_buffers(sh, conf->raid_disks); kmem_cache_free(conf->slab_cache, sh); atomic_dec(&conf->active_stripes); return 1; @@ -482,7 +360,7 @@ static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done, { struct stripe_head *sh = bi->bi_private; raid5_conf_t *conf = sh->raid_conf; - int disks = sh->disks, i; + int disks = conf->raid_disks, i; int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); if (bi->bi_size) @@ -580,7 +458,7 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done, { struct stripe_head *sh = bi->bi_private; raid5_conf_t *conf = sh->raid_conf; - int disks = sh->disks, i; + int disks = conf->raid_disks, i; unsigned long flags; int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); @@ -734,7 +612,7 @@ 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) { raid5_conf_t *conf = sh->raid_conf; - int raid_disks = sh->disks, data_disks = raid_disks - 1; + int raid_disks = conf->raid_disks, data_disks = raid_disks - 1; sector_t new_sector = sh->sector, check; int sectors_per_chunk = conf->chunk_size >> 9; sector_t stripe; @@ -835,7 +713,8 @@ static void copy_data(int frombio, struct bio *bio, static void compute_block(struct stripe_head *sh, int dd_idx) { - int i, count, disks = sh->disks; + raid5_conf_t *conf = sh->raid_conf; + int i, count, disks = conf->raid_disks; void *ptr[MAX_XOR_BLOCKS], *p; PRINTK("compute_block, stripe %llu, idx %d\n", @@ -865,7 +744,7 @@ static void compute_block(struct stripe_head *sh, int dd_idx) static void compute_parity(struct stripe_head *sh, int method) { raid5_conf_t *conf = sh->raid_conf; - int i, pd_idx = sh->pd_idx, disks = sh->disks, count; + int i, pd_idx = sh->pd_idx, disks = conf->raid_disks, count; void *ptr[MAX_XOR_BLOCKS]; struct bio *chosen; @@ -876,7 +755,8 @@ static void compute_parity(struct stripe_head *sh, int method) ptr[0] = page_address(sh->dev[pd_idx].page); switch(method) { case READ_MODIFY_WRITE: - BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags)); + if (!test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags)) + BUG(); for (i=disks ; i-- ;) { if (i==pd_idx) continue; @@ -889,7 +769,7 @@ static void compute_parity(struct stripe_head *sh, int method) if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) wake_up(&conf->wait_for_overlap); - BUG_ON(sh->dev[i].written); + if (sh->dev[i].written) BUG(); sh->dev[i].written = chosen; check_xor(); } @@ -905,7 +785,7 @@ static void compute_parity(struct stripe_head *sh, int method) if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) wake_up(&conf->wait_for_overlap); - BUG_ON(sh->dev[i].written); + if (sh->dev[i].written) BUG(); sh->dev[i].written = chosen; } break; @@ -988,7 +868,8 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9)) goto overlap; - BUG_ON(*bip && bi->bi_next && (*bip) != bi->bi_next); + if (*bip && bi->bi_next && (*bip) != bi->bi_next) + BUG(); if (*bip) bi->bi_next = *bip; *bip = bi; @@ -1029,20 +910,6 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in return 0; } -static void end_reshape(raid5_conf_t *conf); - -static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) -{ - int sectors_per_chunk = conf->chunk_size >> 9; - sector_t x = stripe; - int pd_idx, dd_idx; - int chunk_offset = sector_div(x, sectors_per_chunk); - stripe = x; - raid5_compute_sector(stripe*(disks-1)*sectors_per_chunk - + chunk_offset, disks, disks-1, &dd_idx, &pd_idx, conf); - return pd_idx; -} - /* * handle_stripe - do things to a stripe. @@ -1065,11 +932,11 @@ static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) static void handle_stripe(struct stripe_head *sh) { raid5_conf_t *conf = sh->raid_conf; - int disks = sh->disks; + int disks = conf->raid_disks; struct bio *return_bi= NULL; struct bio *bi; int i; - int syncing, expanding, expanded; + int syncing; int locked=0, uptodate=0, to_read=0, to_write=0, failed=0, written=0; int non_overwrite = 0; int failed_num=0; @@ -1084,8 +951,6 @@ static void handle_stripe(struct stripe_head *sh) clear_bit(STRIPE_DELAYED, &sh->state); syncing = test_bit(STRIPE_SYNCING, &sh->state); - expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state); - expanded = test_bit(STRIPE_EXPAND_READY, &sh->state); /* Now to look around and see what can be done */ rcu_read_lock(); @@ -1278,14 +1143,13 @@ static void handle_stripe(struct stripe_head *sh) * parity, or to satisfy requests * or to load a block that is being partially written. */ - if (to_read || non_overwrite || (syncing && (uptodate < disks)) || expanding) { + if (to_read || non_overwrite || (syncing && (uptodate < disks))) { for (i=disks; i--;) { dev = &sh->dev[i]; if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) && (dev->toread || (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) || syncing || - expanding || (failed && (sh->dev[failed_num].toread || (sh->dev[failed_num].towrite && !test_bit(R5_OVERWRITE, &sh->dev[failed_num].flags)))) ) @@ -1422,7 +1286,8 @@ static void handle_stripe(struct stripe_head *sh) set_bit(STRIPE_HANDLE, &sh->state); if (failed == 0) { char *pagea; - BUG_ON(uptodate != disks); + if (uptodate != disks) + BUG(); compute_parity(sh, CHECK_PARITY); uptodate--; pagea = page_address(sh->dev[sh->pd_idx].page); @@ -1474,77 +1339,13 @@ static void handle_stripe(struct stripe_head *sh) set_bit(R5_Wantwrite, &dev->flags); set_bit(R5_ReWrite, &dev->flags); set_bit(R5_LOCKED, &dev->flags); - locked++; } else { /* let's read it back */ set_bit(R5_Wantread, &dev->flags); set_bit(R5_LOCKED, &dev->flags); - locked++; } } - if (expanded && test_bit(STRIPE_EXPANDING, &sh->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); - compute_parity(sh, RECONSTRUCT_WRITE); - for (i= conf->raid_disks; i--;) { - set_bit(R5_LOCKED, &sh->dev[i].flags); - locked++; - set_bit(R5_Wantwrite, &sh->dev[i].flags); - } - clear_bit(STRIPE_EXPANDING, &sh->state); - } else if (expanded) { - clear_bit(STRIPE_EXPAND_READY, &sh->state); - atomic_dec(&conf->reshape_stripes); - wake_up(&conf->wait_for_overlap); - md_done_sync(conf->mddev, STRIPE_SECTORS, 1); - } - - if (expanding && locked == 0) { - /* We have read all the blocks in this stripe and now we need to - * copy some of them into a target stripe for expand. - */ - clear_bit(STRIPE_EXPAND_SOURCE, &sh->state); - for (i=0; i< sh->disks; i++) - if (i != sh->pd_idx) { - int dd_idx, pd_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-1, - &dd_idx, &pd_idx, conf); - sh2 = get_active_stripe(conf, s, conf->raid_disks, pd_idx, 1); - if (sh2 == NULL) - /* so far only the early blocks of this stripe - * have been requested. When later blocks - * get requested, we will try again - */ - continue; - if(!test_bit(STRIPE_EXPANDING, &sh2->state) || - test_bit(R5_Expanded, &sh2->dev[dd_idx].flags)) { - /* must have already done this block */ - release_stripe(sh2); - continue; - } - memcpy(page_address(sh2->dev[dd_idx].page), - page_address(sh->dev[i].page), - STRIPE_SIZE); - set_bit(R5_Expanded, &sh2->dev[dd_idx].flags); - set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags); - for (j=0; jraid_disks; j++) - if (j != sh2->pd_idx && - !test_bit(R5_Expanded, &sh2->dev[j].flags)) - break; - if (j == conf->raid_disks) { - set_bit(STRIPE_EXPAND_READY, &sh2->state); - set_bit(STRIPE_HANDLE, &sh2->state); - } - release_stripe(sh2); - } - } - spin_unlock(&sh->lock); while ((bi=return_bi)) { @@ -1583,7 +1384,7 @@ static void handle_stripe(struct stripe_head *sh) rcu_read_unlock(); if (rdev) { - if (syncing || expanding || expanded) + if (syncing) md_sync_acct(rdev->bdev, STRIPE_SECTORS); bi->bi_bdev = rdev->bdev; @@ -1725,16 +1526,17 @@ static inline void raid5_plug_device(raid5_conf_t *conf) spin_unlock_irq(&conf->device_lock); } -static int make_request(request_queue_t *q, struct bio * bi) +static int make_request (request_queue_t *q, struct bio * bi) { 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 - 1; unsigned int dd_idx, pd_idx; sector_t new_sector; sector_t logical_sector, last_sector; struct stripe_head *sh; const int rw = bio_data_dir(bi); - int remaining; if (unlikely(bio_barrier(bi))) { bio_endio(bi, bi->bi_size, -EOPNOTSUPP); @@ -1753,77 +1555,20 @@ static int make_request(request_queue_t *q, struct bio * bi) for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { DEFINE_WAIT(w); - int disks; + + new_sector = raid5_compute_sector(logical_sector, + raid_disks, data_disks, &dd_idx, &pd_idx, conf); - retry: - 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 - * 64bit on a 32bit platform, and so it might be - * possible to see a half-updated value - * Ofcourse expand_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) - disks = conf->previous_raid_disks; - else { - if (logical_sector >= conf->expand_lo) { - spin_unlock_irq(&conf->device_lock); - schedule(); - goto retry; - } - } - spin_unlock_irq(&conf->device_lock); - } - new_sector = raid5_compute_sector(logical_sector, disks, disks - 1, - &dd_idx, &pd_idx, conf); PRINTK("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)); + retry: + prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); + sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK)); if (sh) { - if (unlikely(conf->expand_progress != MaxSector)) { - /* 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 - * test, but as we are holding a reference to - * 'sh', we know that if that happens, - * STRIPE_EXPANDING will get set and the expansion - * won't proceed until we finish with the stripe. - */ - int must_retry = 0; - spin_lock_irq(&conf->device_lock); - if (logical_sector < conf->expand_progress && - disks == conf->previous_raid_disks) - /* mismatch, need to try again */ - must_retry = 1; - spin_unlock_irq(&conf->device_lock); - if (must_retry) { - release_stripe(sh); - goto retry; - } - } - /* FIXME what if we get a false positive because these - * are being updated. - */ - if (logical_sector >= mddev->suspend_lo && - logical_sector < mddev->suspend_hi) { - release_stripe(sh); - schedule(); - goto retry; - } - - if (test_bit(STRIPE_EXPANDING, &sh->state) || - !add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) { - /* Stripe is busy expanding or - * add failed due to overlap. Flush everything + if (!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) { + /* Add failed due to overlap. Flush everything * and wait a while */ raid5_unplug_device(mddev->queue); @@ -1835,6 +1580,7 @@ static int make_request(request_queue_t *q, struct bio * bi) raid5_plug_device(conf); handle_stripe(sh); release_stripe(sh); + } else { /* cannot get stripe for read-ahead, just give-up */ clear_bit(BIO_UPTODATE, &bi->bi_flags); @@ -1844,9 +1590,7 @@ static int make_request(request_queue_t *q, struct bio * bi) } spin_lock_irq(&conf->device_lock); - remaining = --bi->bi_phys_segments; - spin_unlock_irq(&conf->device_lock); - if (remaining == 0) { + if (--bi->bi_phys_segments == 0) { int bytes = bi->bi_size; if ( bio_data_dir(bi) == WRITE ) @@ -1854,6 +1598,7 @@ static int make_request(request_queue_t *q, struct bio * bi) bi->bi_size = 0; bi->bi_end_io(bi, bytes, 0); } + spin_unlock_irq(&conf->device_lock); return 0; } @@ -1862,8 +1607,12 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i { raid5_conf_t *conf = (raid5_conf_t *) mddev->private; struct stripe_head *sh; - int pd_idx; - sector_t first_sector, last_sector; + int sectors_per_chunk = conf->chunk_size >> 9; + sector_t x; + unsigned long stripe; + int chunk_offset; + int dd_idx, pd_idx; + sector_t first_sector; int raid_disks = conf->raid_disks; int data_disks = raid_disks-1; sector_t max_sector = mddev->size << 1; @@ -1872,10 +1621,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i 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; - } if (mddev->curr_resync < max_sector) /* aborted */ bitmap_end_sync(mddev->bitmap, mddev->curr_resync, @@ -1886,123 +1631,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i return 0; } - - if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { - /* reshaping is quite different to recovery/resync so it is - * handled quite separately ... here. - * - * On each call to sync_request, we gather one chunk worth of - * destination stripes and flag them as expanding. - * Then we find all the source stripes and request reads. - * As the reads complete, handle_stripe will copy the data - * into the destination stripe and release that stripe. - */ - 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_div(sector_nr, conf->raid_disks-1); - *skipped = 1; - return sector_nr; - } - - /* 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 - */ - writepos = conf->expand_progress + - conf->chunk_size/512*(conf->raid_disks-1); - sector_div(writepos, conf->raid_disks-1); - safepos = conf->expand_lo; - sector_div(safepos, conf->previous_raid_disks-1); - gap = conf->expand_progress - conf->expand_lo; - - if (writepos >= safepos || - gap > (conf->raid_disks-1)*3000*2 /*3Meg*/) { - /* 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->sb_dirty = 1; - md_wakeup_thread(mddev->thread); - wait_event(mddev->sb_wait, mddev->sb_dirty == 0 || - kthread_should_stop()); - spin_lock_irq(&conf->device_lock); - conf->expand_lo = 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) { - 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); - set_bit(STRIPE_EXPANDING, &sh->state); - atomic_inc(&conf->reshape_stripes); - /* If any of this stripe is beyond the end of the old - * array, then we need to zero those blocks - */ - for (j=sh->disks; j--;) { - sector_t s; - if (j == sh->pd_idx) - continue; - s = compute_blocknr(sh, j); - if (s < (mddev->array_size<<1)) { - skipped = 1; - continue; - } - memset(page_address(sh->dev[j].page), 0, STRIPE_SIZE); - set_bit(R5_Expanded, &sh->dev[j].flags); - set_bit(R5_UPTODATE, &sh->dev[j].flags); - } - if (!skipped) { - set_bit(STRIPE_EXPAND_READY, &sh->state); - set_bit(STRIPE_HANDLE, &sh->state); - } - release_stripe(sh); - } - spin_lock_irq(&conf->device_lock); - conf->expand_progress = (sector_nr + i)*(conf->raid_disks-1); - spin_unlock_irq(&conf->device_lock); - /* Ok, those stripe are ready. We can start scheduling - * reads on the source stripes. - * The source stripes are determined by mapping the first and last - * block on the destination stripes. - */ - raid_disks = conf->previous_raid_disks; - data_disks = raid_disks - 1; - first_sector = - raid5_compute_sector(sector_nr*(conf->raid_disks-1), - raid_disks, data_disks, - &dd_idx, &pd_idx, conf); - last_sector = - raid5_compute_sector((sector_nr+conf->chunk_size/512) - *(conf->raid_disks-1) -1, - raid_disks, data_disks, - &dd_idx, &pd_idx, conf); - if (last_sector >= (mddev->size<<1)) - last_sector = (mddev->size<<1)-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); - set_bit(STRIPE_EXPAND_SOURCE, &sh->state); - set_bit(STRIPE_HANDLE, &sh->state); - release_stripe(sh); - first_sector += STRIPE_SECTORS; - } - return conf->chunk_size>>9; - } /* if there is 1 or more failed drives and we are trying * to resync, then assert that we are finished, because there is * nothing we can do. @@ -2021,10 +1649,16 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */ } - pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks); - sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1); + x = sector_nr; + chunk_offset = sector_div(x, sectors_per_chunk); + stripe = x; + BUG_ON(x != stripe); + + first_sector = raid5_compute_sector((sector_t)stripe*data_disks*sectors_per_chunk + + chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf); + sh = get_active_stripe(conf, sector_nr, pd_idx, 1); if (sh == NULL) { - sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0); + sh = get_active_stripe(conf, sector_nr, pd_idx, 0); /* make sure we don't swamp the stripe cache if someone else * is trying to get access */ @@ -2087,7 +1721,8 @@ static void raid5d (mddev_t *mddev) list_del_init(first); atomic_inc(&sh->count); - BUG_ON(atomic_read(&sh->count)!= 1); + if (atomic_read(&sh->count)!= 1) + BUG(); spin_unlock_irq(&conf->device_lock); handled++; @@ -2187,64 +1822,11 @@ static int run(mddev_t *mddev) return -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; - - 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-1))) { - 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-1)); - /* 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; */ - } - - - mddev->private = kzalloc(sizeof (raid5_conf_t), GFP_KERNEL); + mddev->private = kzalloc(sizeof (raid5_conf_t) + + mddev->raid_disks * sizeof(struct disk_info), + GFP_KERNEL); if ((conf = mddev->private) == 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->previous_raid_disks = mddev->raid_disks - mddev->delta_disks; - } - - conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info), - GFP_KERNEL); - if (!conf->disks) - goto abort; conf->mddev = mddev; @@ -2265,7 +1847,7 @@ static int run(mddev_t *mddev) ITERATE_RDEV(mddev,rdev,tmp) { raid_disk = rdev->raid_disk; - if (raid_disk >= conf->raid_disks + if (raid_disk >= mddev->raid_disks || raid_disk < 0) continue; disk = conf->disks + raid_disk; @@ -2281,6 +1863,7 @@ static int run(mddev_t *mddev) } } + conf->raid_disks = mddev->raid_disks; /* * 0 for a fully functional array, 1 for a degraded array. */ @@ -2290,7 +1873,6 @@ static int run(mddev_t *mddev) conf->level = mddev->level; conf->algorithm = mddev->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); @@ -2363,21 +1945,6 @@ static int run(mddev_t *mddev) print_raid5_conf(conf); - if (conf->expand_progress != MaxSector) { - printk("...ok start reshape thread\n"); - conf->expand_lo = conf->expand_progress; - atomic_set(&conf->reshape_stripes, 0); - clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); - clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); - set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); - set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); - mddev->sync_thread = md_register_thread(md_do_sync, mddev, - "%s_reshape"); - /* FIXME if md_register_thread fails?? */ - md_wakeup_thread(mddev->sync_thread); - - } - /* read-ahead size must cover two whole stripes, which is * 2 * (n-1) * chunksize where 'n' is the number of raid devices */ @@ -2393,13 +1960,12 @@ static int run(mddev_t *mddev) mddev->queue->unplug_fn = raid5_unplug_device; mddev->queue->issue_flush_fn = raid5_issue_flush; - mddev->array_size = mddev->size * (conf->previous_raid_disks - 1); + mddev->array_size = mddev->size * (mddev->raid_disks - 1); return 0; abort: if (conf) { print_raid5_conf(conf); - kfree(conf->disks); kfree(conf->stripe_hashtbl); kfree(conf); } @@ -2420,7 +1986,6 @@ static int stop(mddev_t *mddev) kfree(conf->stripe_hashtbl); blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); - kfree(conf->disks); kfree(conf); mddev->private = NULL; return 0; @@ -2436,7 +2001,7 @@ static void print_sh (struct stripe_head *sh) printk("sh %llu, count %d.\n", (unsigned long long)sh->sector, atomic_read(&sh->count)); printk("sh %llu, ", (unsigned long long)sh->sector); - for (i = 0; i < sh->disks; i++) { + for (i = 0; i < sh->raid_conf->raid_disks; i++) { printk("(cache%d: %p %ld) ", i, sh->dev[i].page, sh->dev[i].flags); } @@ -2567,7 +2132,7 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) /* * find the disk ... */ - for (disk=0; disk < conf->raid_disks; disk++) + for (disk=0; disk < mddev->raid_disks; disk++) if ((p=conf->disks + disk)->rdev == NULL) { clear_bit(In_sync, &rdev->flags); rdev->raid_disk = disk; @@ -2603,146 +2168,11 @@ static int raid5_resize(mddev_t *mddev, sector_t 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 */ - - /* Can only proceed if there are plenty of stripe_heads. - * We need a minimum of one full stripe,, and for sensible progress - * it is best to have about 4 times that. - * If we require 4 times, then the default 256 4K stripe_heads will - * allow for chunk sizes up to 256K, which is probably OK. - * If the chunk size is greater, user-space should request more - * stripe_heads first. - */ - 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); - return -ENOSPC; - } - - err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks); - if (err) - return err; - - /* looks like we might be able to manage this */ - return 0; -} - -static int raid5_start_reshape(mddev_t *mddev) -{ - raid5_conf_t *conf = mddev_to_conf(mddev); - mdk_rdev_t *rdev; - struct list_head *rtmp; - int spares = 0; - int added_devices = 0; - - if (mddev->degraded || - test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) - return -EBUSY; - - ITERATE_RDEV(mddev, rdev, rtmp) - if (rdev->raid_disk < 0 && - !test_bit(Faulty, &rdev->flags)) - spares++; - - if (spares < mddev->delta_disks-1) - /* Not enough devices even to make a degraded array - * of that size - */ - 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; - spin_unlock_irq(&conf->device_lock); - - /* Add some new drives, as many as will fit. - * We know there are enough to make the newly sized array work. - */ - ITERATE_RDEV(mddev, rdev, rtmp) - if (rdev->raid_disk < 0 && - !test_bit(Faulty, &rdev->flags)) { - if (raid5_add_disk(mddev, rdev)) { - char nm[20]; - set_bit(In_sync, &rdev->flags); - conf->working_disks++; - added_devices++; - sprintf(nm, "rd%d", rdev->raid_disk); - sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); - } else - break; - } - - mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices; - mddev->raid_disks = conf->raid_disks; - mddev->reshape_position = 0; - mddev->sb_dirty = 1; - - clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); - clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); - set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); - set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); - mddev->sync_thread = md_register_thread(md_do_sync, mddev, - "%s_reshape"); - if (!mddev->sync_thread) { - mddev->recovery = 0; - spin_lock_irq(&conf->device_lock); - mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks; - conf->expand_progress = MaxSector; - spin_unlock_irq(&conf->device_lock); - return -EAGAIN; - } - md_wakeup_thread(mddev->sync_thread); - md_new_event(mddev); - return 0; -} -#endif - -static void end_reshape(raid5_conf_t *conf) -{ - struct block_device *bdev; - - if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { - conf->mddev->array_size = conf->mddev->size * (conf->raid_disks-1); - set_capacity(conf->mddev->gendisk, conf->mddev->array_size << 1); - 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, conf->mddev->array_size << 10); - mutex_unlock(&bdev->bd_inode->i_mutex); - bdput(bdev); - } - spin_lock_irq(&conf->device_lock); - conf->expand_progress = MaxSector; - spin_unlock_irq(&conf->device_lock); - conf->mddev->reshape_position = MaxSector; - } -} - static void raid5_quiesce(mddev_t *mddev, int state) { raid5_conf_t *conf = mddev_to_conf(mddev); switch(state) { - case 2: /* resume for a suspend */ - wake_up(&conf->wait_for_overlap); - break; - case 1: /* stop all writes */ spin_lock_irq(&conf->device_lock); conf->quiesce = 1; @@ -2756,7 +2186,6 @@ static void raid5_quiesce(mddev_t *mddev, int state) spin_lock_irq(&conf->device_lock); conf->quiesce = 0; wake_up(&conf->wait_for_stripe); - wake_up(&conf->wait_for_overlap); spin_unlock_irq(&conf->device_lock); break; } @@ -2777,10 +2206,6 @@ static struct mdk_personality raid5_personality = .spare_active = raid5_spare_active, .sync_request = sync_request, .resize = raid5_resize, -#ifdef CONFIG_MD_RAID5_RESHAPE - .check_reshape = raid5_check_reshape, - .start_reshape = raid5_start_reshape, -#endif .quiesce = raid5_quiesce, }; diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index bc69355e0..cd477ebf2 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -91,8 +91,10 @@ static void print_raid6_conf (raid6_conf_t *conf); static void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh) { if (atomic_dec_and_test(&sh->count)) { - BUG_ON(!list_empty(&sh->lru)); - BUG_ON(atomic_read(&conf->active_stripes)==0); + if (!list_empty(&sh->lru)) + BUG(); + if (atomic_read(&conf->active_stripes)==0) + BUG(); if (test_bit(STRIPE_HANDLE, &sh->state)) { if (test_bit(STRIPE_DELAYED, &sh->state)) list_add_tail(&sh->lru, &conf->delayed_list); @@ -200,8 +202,10 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx) raid6_conf_t *conf = sh->raid_conf; int disks = conf->raid_disks, i; - BUG_ON(atomic_read(&sh->count) != 0); - BUG_ON(test_bit(STRIPE_HANDLE, &sh->state)); + if (atomic_read(&sh->count) != 0) + BUG(); + if (test_bit(STRIPE_HANDLE, &sh->state)) + BUG(); CHECK_DEVLOCK(); PRINTK("init_stripe called, stripe %llu\n", @@ -280,11 +284,13 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector init_stripe(sh, sector, pd_idx); } else { if (atomic_read(&sh->count)) { - BUG_ON(!list_empty(&sh->lru)); + if (!list_empty(&sh->lru)) + BUG(); } else { if (!test_bit(STRIPE_HANDLE, &sh->state)) atomic_inc(&conf->active_stripes); - BUG_ON(list_empty(&sh->lru)); + if (list_empty(&sh->lru)) + BUG(); list_del_init(&sh->lru); } } @@ -325,9 +331,9 @@ static int grow_stripes(raid6_conf_t *conf, int num) kmem_cache_t *sc; int devs = conf->raid_disks; - sprintf(conf->cache_name[0], "raid6/%s", mdname(conf->mddev)); + sprintf(conf->cache_name, "raid6/%s", mdname(conf->mddev)); - sc = kmem_cache_create(conf->cache_name[0], + sc = kmem_cache_create(conf->cache_name, sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev), 0, 0, NULL, NULL); if (!sc) @@ -347,7 +353,8 @@ static int drop_one_stripe(raid6_conf_t *conf) spin_unlock_irq(&conf->device_lock); if (!sh) return 0; - BUG_ON(atomic_read(&sh->count)); + if (atomic_read(&sh->count)) + BUG(); shrink_buffers(sh, conf->raid_disks); kmem_cache_free(conf->slab_cache, sh); atomic_dec(&conf->active_stripes); @@ -773,7 +780,7 @@ static void compute_parity(struct stripe_head *sh, int method) if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) wake_up(&conf->wait_for_overlap); - BUG_ON(sh->dev[i].written); + if (sh->dev[i].written) BUG(); sh->dev[i].written = chosen; } break; @@ -963,7 +970,8 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9)) goto overlap; - BUG_ON(*bip && bi->bi_next && (*bip) != bi->bi_next); + if (*bip && bi->bi_next && (*bip) != bi->bi_next) + BUG(); if (*bip) bi->bi_next = *bip; *bip = bi; @@ -1898,7 +1906,8 @@ static void raid6d (mddev_t *mddev) list_del_init(first); atomic_inc(&sh->count); - BUG_ON(atomic_read(&sh->count)!= 1); + if (atomic_read(&sh->count)!= 1) + BUG(); spin_unlock_irq(&conf->device_lock); handled++; @@ -1997,14 +2006,11 @@ static int run(mddev_t *mddev) return -EIO; } - mddev->private = kzalloc(sizeof (raid6_conf_t), GFP_KERNEL); - if ((conf = mddev->private) == NULL) - goto abort; - conf->disks = kzalloc(mddev->raid_disks * sizeof(struct disk_info), + mddev->private = kzalloc(sizeof (raid6_conf_t) + + mddev->raid_disks * sizeof(struct disk_info), GFP_KERNEL); - if (!conf->disks) + if ((conf = mddev->private) == NULL) goto abort; - conf->mddev = mddev; if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) @@ -2142,8 +2148,6 @@ static int run(mddev_t *mddev) } /* Ok, everything is just fine now */ - sysfs_create_group(&mddev->kobj, &raid6_attrs_group); - mddev->array_size = mddev->size * (mddev->raid_disks - 2); mddev->queue->unplug_fn = raid6_unplug_device; @@ -2154,7 +2158,6 @@ abort: print_raid6_conf(conf); safe_put_page(conf->spare_page); kfree(conf->stripe_hashtbl); - kfree(conf->disks); kfree(conf); } mddev->private = NULL; diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 344d83aae..c2602b340 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -8,54 +8,22 @@ config VIDEO_DEV tristate "Video For Linux" ---help--- Support for audio/video capture and overlay devices and FM radio - cards. The exact capabilities of each device vary. + cards. The exact capabilities of each device vary. User tools for + this are available from + . This kernel includes support for the new Video for Linux Two API, (V4L2) as well as the original system. Drivers and applications need to be rewritten to use V4L2, but drivers for popular cards and applications for most video capture functions already exist. - Additional info and docs are available on the web at - - - Documentation for V4L2 is also available on the web at - . + Documentation for the original API is included in the file + . Documentation for V4L2 is + available on the web at . To compile this driver as a module, choose M here: the module will be called videodev. -config VIDEO_V4L1 - boolean "Enable Video For Linux API 1 (DEPRECATED)" - depends on VIDEO_DEV - select VIDEO_V4L1_COMPAT - default y - ---help--- - Enables a compatibility API used by most V4L2 devices to allow - its usage with legacy applications that supports only V4L1 api. - - If you are unsure as to whether this is required, answer Y. - -config VIDEO_V4L1_COMPAT - boolean "Enable Video For Linux API 1 compatible Layer" - depends on VIDEO_DEV - default y - ---help--- - This api were developed to be used at Kernel 2.2 and 2.4, but - lacks support for several video standards. There are several - drivers at kernel that still depends on it. - - Documentation for the original API is included in the file - . - - User tools for this are available from - . - - If you are unsure as to whether this is required, answer Y. - -config VIDEO_V4L2 - tristate - default y - source "drivers/media/video/Kconfig" source "drivers/media/radio/Kconfig" @@ -82,18 +50,5 @@ config VIDEO_IR config VIDEO_TVEEPROM tristate -config USB_DABUSB - tristate "DABUSB driver" - depends on USB - ---help--- - A Digital Audio Broadcasting (DAB) Receiver for USB and Linux - brought to you by the DAB-Team - . This driver can be taken - as an example for URB-based bulk, control, and isochronous - transactions. URB's are explained in - . - - To compile this driver as a module, choose M here: the - module will be called dabusb. - endmenu + diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig index 1a04db455..6a901a026 100644 --- a/drivers/media/common/Kconfig +++ b/drivers/media/common/Kconfig @@ -1,10 +1,9 @@ config VIDEO_SAA7146 tristate - depends on I2C + select I2C config VIDEO_SAA7146_VV tristate - select VIDEO_V4L2 select VIDEO_BUF select VIDEO_VIDEOBUF select VIDEO_SAA7146 diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile index 61b89617a..bd458cb9b 100644 --- a/drivers/media/common/Makefile +++ b/drivers/media/common/Makefile @@ -1,6 +1,5 @@ saa7146-objs := saa7146_i2c.o saa7146_core.o saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o -ir-common-objs := ir-functions.o ir-keymaps.o obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c new file mode 100644 index 000000000..97fa3fc57 --- /dev/null +++ b/drivers/media/common/ir-common.c @@ -0,0 +1,519 @@ +/* + * + * some common structs and functions to handle infrared remotes via + * input layer ... + * + * (c) 2003 Gerd Knorr [SuSE Labs] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 +#include +#include +#include + +/* -------------------------------------------------------------------------- */ + +MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); +MODULE_LICENSE("GPL"); + +static int repeat = 1; +module_param(repeat, int, 0444); +MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); + +static int debug = 0; /* debug level (0,1,2) */ +module_param(debug, int, 0644); + +#define dprintk(level, fmt, arg...) if (debug >= level) \ + printk(KERN_DEBUG fmt , ## arg) + +/* -------------------------------------------------------------------------- */ + +/* generic RC5 keytable */ +/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ +/* used by old (black) Hauppauge remotes */ +IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = { + /* Keys 0 to 9 */ + [ 0x00 ] = KEY_KP0, + [ 0x01 ] = KEY_KP1, + [ 0x02 ] = KEY_KP2, + [ 0x03 ] = KEY_KP3, + [ 0x04 ] = KEY_KP4, + [ 0x05 ] = KEY_KP5, + [ 0x06 ] = KEY_KP6, + [ 0x07 ] = KEY_KP7, + [ 0x08 ] = KEY_KP8, + [ 0x09 ] = KEY_KP9, + + [ 0x0b ] = KEY_CHANNEL, /* channel / program (japan: 11) */ + [ 0x0c ] = KEY_POWER, /* standby */ + [ 0x0d ] = KEY_MUTE, /* mute / demute */ + [ 0x0f ] = KEY_TV, /* display */ + [ 0x10 ] = KEY_VOLUMEUP, + [ 0x11 ] = KEY_VOLUMEDOWN, + [ 0x12 ] = KEY_BRIGHTNESSUP, + [ 0x13 ] = KEY_BRIGHTNESSDOWN, + [ 0x1e ] = KEY_SEARCH, /* search + */ + [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ + [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ + [ 0x22 ] = KEY_CHANNEL, /* alt / channel */ + [ 0x23 ] = KEY_LANGUAGE, /* 1st / 2nd language */ + [ 0x26 ] = KEY_SLEEP, /* sleeptimer */ + [ 0x2e ] = KEY_MENU, /* 2nd controls (USA: menu) */ + [ 0x30 ] = KEY_PAUSE, + [ 0x32 ] = KEY_REWIND, + [ 0x33 ] = KEY_GOTO, + [ 0x35 ] = KEY_PLAY, + [ 0x36 ] = KEY_STOP, + [ 0x37 ] = KEY_RECORD, /* recording */ + [ 0x3c ] = KEY_TEXT, /* teletext submode (Japan: 12) */ + [ 0x3d ] = KEY_SUSPEND, /* system standby */ + +}; +EXPORT_SYMBOL_GPL(ir_codes_rc5_tv); + +/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ +IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { + /* Keys 0 to 9 */ + [ 18 ] = KEY_KP0, + [ 5 ] = KEY_KP1, + [ 6 ] = KEY_KP2, + [ 7 ] = KEY_KP3, + [ 9 ] = KEY_KP4, + [ 10 ] = KEY_KP5, + [ 11 ] = KEY_KP6, + [ 13 ] = KEY_KP7, + [ 14 ] = KEY_KP8, + [ 15 ] = KEY_KP9, + + [ 0 ] = KEY_POWER, + [ 2 ] = KEY_TUNER, /* TV/FM */ + [ 30 ] = KEY_VIDEO, + [ 4 ] = KEY_VOLUMEUP, + [ 8 ] = KEY_VOLUMEDOWN, + [ 12 ] = KEY_CHANNELUP, + [ 16 ] = KEY_CHANNELDOWN, + [ 3 ] = KEY_ZOOM, /* fullscreen */ + [ 31 ] = KEY_SUBTITLE, /* closed caption/teletext */ + [ 32 ] = KEY_SLEEP, + [ 20 ] = KEY_MUTE, + [ 43 ] = KEY_RED, + [ 44 ] = KEY_GREEN, + [ 45 ] = KEY_YELLOW, + [ 46 ] = KEY_BLUE, + [ 24 ] = KEY_KPPLUS, /* fine tune + */ + [ 25 ] = KEY_KPMINUS, /* fine tune - */ + [ 33 ] = KEY_KPDOT, + [ 19 ] = KEY_KPENTER, + [ 34 ] = KEY_BACK, + [ 35 ] = KEY_PLAYPAUSE, + [ 36 ] = KEY_NEXT, + [ 38 ] = KEY_STOP, + [ 39 ] = KEY_RECORD +}; +EXPORT_SYMBOL_GPL(ir_codes_winfast); + +IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { + [ 0x59 ] = KEY_MUTE, + [ 0x4a ] = KEY_POWER, + + [ 0x18 ] = KEY_TEXT, + [ 0x26 ] = KEY_TV, + [ 0x3d ] = KEY_PRINT, + + [ 0x48 ] = KEY_RED, + [ 0x04 ] = KEY_GREEN, + [ 0x11 ] = KEY_YELLOW, + [ 0x00 ] = KEY_BLUE, + + [ 0x2d ] = KEY_VOLUMEUP, + [ 0x1e ] = KEY_VOLUMEDOWN, + + [ 0x49 ] = KEY_MENU, + + [ 0x16 ] = KEY_CHANNELUP, + [ 0x17 ] = KEY_CHANNELDOWN, + + [ 0x20 ] = KEY_UP, + [ 0x21 ] = KEY_DOWN, + [ 0x22 ] = KEY_LEFT, + [ 0x23 ] = KEY_RIGHT, + [ 0x0d ] = KEY_SELECT, + + + + [ 0x08 ] = KEY_BACK, + [ 0x07 ] = KEY_REFRESH, + + [ 0x2f ] = KEY_ZOOM, + [ 0x29 ] = KEY_RECORD, + + [ 0x4b ] = KEY_PAUSE, + [ 0x4d ] = KEY_REWIND, + [ 0x2e ] = KEY_PLAY, + [ 0x4e ] = KEY_FORWARD, + [ 0x53 ] = KEY_PREVIOUS, + [ 0x4c ] = KEY_STOP, + [ 0x54 ] = KEY_NEXT, + + [ 0x69 ] = KEY_KP0, + [ 0x6a ] = KEY_KP1, + [ 0x6b ] = KEY_KP2, + [ 0x6c ] = KEY_KP3, + [ 0x6d ] = KEY_KP4, + [ 0x6e ] = KEY_KP5, + [ 0x6f ] = KEY_KP6, + [ 0x70 ] = KEY_KP7, + [ 0x71 ] = KEY_KP8, + [ 0x72 ] = KEY_KP9, + + [ 0x74 ] = KEY_CHANNEL, + [ 0x0a ] = KEY_BACKSPACE, +}; + +EXPORT_SYMBOL_GPL(ir_codes_pinnacle); + +/* empty keytable, can be used as placeholder for not-yet created keytables */ +IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { + [ 42 ] = KEY_COFFEE, +}; +EXPORT_SYMBOL_GPL(ir_codes_empty); + +/* Hauppauge: the newer, gray remotes (seems there are multiple + * slightly different versions), shipped with cx88+ivtv cards. + * almost rc5 coding, but some non-standard keys */ +IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { + /* Keys 0 to 9 */ + [ 0x00 ] = KEY_KP0, + [ 0x01 ] = KEY_KP1, + [ 0x02 ] = KEY_KP2, + [ 0x03 ] = KEY_KP3, + [ 0x04 ] = KEY_KP4, + [ 0x05 ] = KEY_KP5, + [ 0x06 ] = KEY_KP6, + [ 0x07 ] = KEY_KP7, + [ 0x08 ] = KEY_KP8, + [ 0x09 ] = KEY_KP9, + + [ 0x0a ] = KEY_TEXT, /* keypad asterisk as well */ + [ 0x0b ] = KEY_RED, /* red button */ + [ 0x0c ] = KEY_RADIO, + [ 0x0d ] = KEY_MENU, + [ 0x0e ] = KEY_SUBTITLE, /* also the # key */ + [ 0x0f ] = KEY_MUTE, + [ 0x10 ] = KEY_VOLUMEUP, + [ 0x11 ] = KEY_VOLUMEDOWN, + [ 0x12 ] = KEY_PREVIOUS, /* previous channel */ + [ 0x14 ] = KEY_UP, + [ 0x15 ] = KEY_DOWN, + [ 0x16 ] = KEY_LEFT, + [ 0x17 ] = KEY_RIGHT, + [ 0x18 ] = KEY_VIDEO, /* Videos */ + [ 0x19 ] = KEY_AUDIO, /* Music */ + /* 0x1a: Pictures - presume this means + "Multimedia Home Platform" - + no "PICTURES" key in input.h + */ + [ 0x1a ] = KEY_MHP, + + [ 0x1b ] = KEY_EPG, /* Guide */ + [ 0x1c ] = KEY_TV, + [ 0x1e ] = KEY_NEXTSONG, /* skip >| */ + [ 0x1f ] = KEY_EXIT, /* back/exit */ + [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ + [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ + [ 0x22 ] = KEY_CHANNEL, /* source (old black remote) */ + [ 0x24 ] = KEY_PREVIOUSSONG, /* replay |< */ + [ 0x25 ] = KEY_ENTER, /* OK */ + [ 0x26 ] = KEY_SLEEP, /* minimize (old black remote) */ + [ 0x29 ] = KEY_BLUE, /* blue key */ + [ 0x2e ] = KEY_GREEN, /* green button */ + [ 0x30 ] = KEY_PAUSE, /* pause */ + [ 0x32 ] = KEY_REWIND, /* backward << */ + [ 0x34 ] = KEY_FASTFORWARD, /* forward >> */ + [ 0x35 ] = KEY_PLAY, + [ 0x36 ] = KEY_STOP, + [ 0x37 ] = KEY_RECORD, /* recording */ + [ 0x38 ] = KEY_YELLOW, /* yellow key */ + [ 0x3b ] = KEY_SELECT, /* top right button */ + [ 0x3c ] = KEY_ZOOM, /* full */ + [ 0x3d ] = KEY_POWER, /* system power (green button) */ +}; +EXPORT_SYMBOL(ir_codes_hauppauge_new); + +IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { + [ 2 ] = KEY_KP0, + [ 1 ] = KEY_KP1, + [ 11 ] = KEY_KP2, + [ 27 ] = KEY_KP3, + [ 5 ] = KEY_KP4, + [ 9 ] = KEY_KP5, + [ 21 ] = KEY_KP6, + [ 6 ] = KEY_KP7, + [ 10 ] = KEY_KP8, + [ 18 ] = KEY_KP9, + + [ 3 ] = KEY_TUNER, /* TV/FM */ + [ 7 ] = KEY_SEARCH, /* scan */ + [ 28 ] = KEY_ZOOM, /* full screen */ + [ 30 ] = KEY_POWER, + [ 23 ] = KEY_VOLUMEDOWN, + [ 31 ] = KEY_VOLUMEUP, + [ 20 ] = KEY_CHANNELDOWN, + [ 22 ] = KEY_CHANNELUP, + [ 24 ] = KEY_MUTE, + + [ 0 ] = KEY_LIST, /* source */ + [ 19 ] = KEY_INFO, /* loop */ + [ 16 ] = KEY_LAST, /* +100 */ + [ 13 ] = KEY_CLEAR, /* reset */ + [ 12 ] = BTN_RIGHT, /* fun++ */ + [ 4 ] = BTN_LEFT, /* fun-- */ + [ 14 ] = KEY_GOTO, /* function */ + [ 15 ] = KEY_STOP, /* freeze */ +}; +EXPORT_SYMBOL(ir_codes_pixelview); + +/* -------------------------------------------------------------------------- */ + +static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) +{ + if (KEY_RESERVED == ir->keycode) { + printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", + dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); + return; + } + dprintk(1,"%s: key event code=%d down=%d\n", + dev->name,ir->keycode,ir->keypressed); + input_report_key(dev,ir->keycode,ir->keypressed); + input_sync(dev); +} + +/* -------------------------------------------------------------------------- */ + +void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, + int ir_type, IR_KEYTAB_TYPE *ir_codes) +{ + int i; + + ir->ir_type = ir_type; + if (ir_codes) + memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); + + + dev->keycode = ir->ir_codes; + dev->keycodesize = sizeof(IR_KEYTAB_TYPE); + dev->keycodemax = IR_KEYTAB_SIZE; + for (i = 0; i < IR_KEYTAB_SIZE; i++) + set_bit(ir->ir_codes[i], dev->keybit); + clear_bit(0, dev->keybit); + + set_bit(EV_KEY, dev->evbit); + if (repeat) + set_bit(EV_REP, dev->evbit); +} + +void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) +{ + if (ir->keypressed) { + ir->keypressed = 0; + ir_input_key_event(dev,ir); + } +} + +void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, + u32 ir_key, u32 ir_raw) +{ + u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); + + if (ir->keypressed && ir->keycode != keycode) { + ir->keypressed = 0; + ir_input_key_event(dev,ir); + } + if (!ir->keypressed) { + ir->ir_key = ir_key; + ir->ir_raw = ir_raw; + ir->keycode = keycode; + ir->keypressed = 1; + ir_input_key_event(dev,ir); + } +} + +/* -------------------------------------------------------------------------- */ + +u32 ir_extract_bits(u32 data, u32 mask) +{ + int mbit, vbit; + u32 value; + + value = 0; + vbit = 0; + for (mbit = 0; mbit < 32; mbit++) { + if (!(mask & ((u32)1 << mbit))) + continue; + if (data & ((u32)1 << mbit)) + value |= (1 << vbit); + vbit++; + } + return value; +} + +static int inline getbit(u32 *samples, int bit) +{ + return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; +} + +/* sump raw samples for visual debugging ;) */ +int ir_dump_samples(u32 *samples, int count) +{ + int i, bit, start; + + printk(KERN_DEBUG "ir samples: "); + start = 0; + for (i = 0; i < count * 32; i++) { + bit = getbit(samples,i); + if (bit) + start = 1; + if (0 == start) + continue; + printk("%s", bit ? "#" : "_"); + } + printk("\n"); + return 0; +} + +/* decode raw samples, pulse distance coding used by NEC remotes */ +int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) +{ + int i,last,bit,len; + u32 curBit; + u32 value; + + /* find start burst */ + for (i = len = 0; i < count * 32; i++) { + bit = getbit(samples,i); + if (bit) { + len++; + } else { + if (len >= 29) + break; + len = 0; + } + } + + /* start burst to short */ + if (len < 29) + return 0xffffffff; + + /* find start silence */ + for (len = 0; i < count * 32; i++) { + bit = getbit(samples,i); + if (bit) { + break; + } else { + len++; + } + } + + /* silence to short */ + if (len < 7) + return 0xffffffff; + + /* go decoding */ + len = 0; + last = 1; + value = 0; curBit = 1; + for (; i < count * 32; i++) { + bit = getbit(samples,i); + if (last) { + if(bit) { + continue; + } else { + len = 1; + } + } else { + if (bit) { + if (len > (low + high) /2) + value |= curBit; + curBit <<= 1; + if (curBit == 1) + break; + } else { + len++; + } + } + last = bit; + } + + return value; +} + +/* decode raw samples, biphase coding, used by rc5 for example */ +int ir_decode_biphase(u32 *samples, int count, int low, int high) +{ + int i,last,bit,len,flips; + u32 value; + + /* find start bit (1) */ + for (i = 0; i < 32; i++) { + bit = getbit(samples,i); + if (bit) + break; + } + + /* go decoding */ + len = 0; + flips = 0; + value = 1; + for (; i < count * 32; i++) { + if (len > high) + break; + if (flips > 1) + break; + last = bit; + bit = getbit(samples,i); + if (last == bit) { + len++; + continue; + } + if (len < low) { + len++; + flips++; + continue; + } + value <<= 1; + value |= bit; + flips = 0; + len = 1; + } + return value; +} + +EXPORT_SYMBOL_GPL(ir_input_init); +EXPORT_SYMBOL_GPL(ir_input_nokey); +EXPORT_SYMBOL_GPL(ir_input_keydown); + +EXPORT_SYMBOL_GPL(ir_extract_bits); +EXPORT_SYMBOL_GPL(ir_dump_samples); +EXPORT_SYMBOL_GPL(ir_decode_biphase); +EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ + diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c deleted file mode 100644 index 397cff8b3..000000000 --- a/drivers/media/common/ir-functions.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * - * some common structs and functions to handle infrared remotes via - * input layer ... - * - * (c) 2003 Gerd Knorr [SuSE Labs] - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include - -/* -------------------------------------------------------------------------- */ - -MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); -MODULE_LICENSE("GPL"); - -static int repeat = 1; -module_param(repeat, int, 0444); -MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); - -static int debug = 0; /* debug level (0,1,2) */ -module_param(debug, int, 0644); - -#define dprintk(level, fmt, arg...) if (debug >= level) \ - printk(KERN_DEBUG fmt , ## arg) - -/* -------------------------------------------------------------------------- */ - -static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) -{ - if (KEY_RESERVED == ir->keycode) { - printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", - dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); - return; - } - dprintk(1,"%s: key event code=%d down=%d\n", - dev->name,ir->keycode,ir->keypressed); - input_report_key(dev,ir->keycode,ir->keypressed); - input_sync(dev); -} - -/* -------------------------------------------------------------------------- */ - -void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, - int ir_type, IR_KEYTAB_TYPE *ir_codes) -{ - int i; - - ir->ir_type = ir_type; - if (ir_codes) - memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); - - - dev->keycode = ir->ir_codes; - dev->keycodesize = sizeof(IR_KEYTAB_TYPE); - dev->keycodemax = IR_KEYTAB_SIZE; - for (i = 0; i < IR_KEYTAB_SIZE; i++) - set_bit(ir->ir_codes[i], dev->keybit); - clear_bit(0, dev->keybit); - - set_bit(EV_KEY, dev->evbit); - if (repeat) - set_bit(EV_REP, dev->evbit); -} - -void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) -{ - if (ir->keypressed) { - ir->keypressed = 0; - ir_input_key_event(dev,ir); - } -} - -void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, - u32 ir_key, u32 ir_raw) -{ - u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); - - if (ir->keypressed && ir->keycode != keycode) { - ir->keypressed = 0; - ir_input_key_event(dev,ir); - } - if (!ir->keypressed) { - ir->ir_key = ir_key; - ir->ir_raw = ir_raw; - ir->keycode = keycode; - ir->keypressed = 1; - ir_input_key_event(dev,ir); - } -} - -/* -------------------------------------------------------------------------- */ - -u32 ir_extract_bits(u32 data, u32 mask) -{ - int mbit, vbit; - u32 value; - - value = 0; - vbit = 0; - for (mbit = 0; mbit < 32; mbit++) { - if (!(mask & ((u32)1 << mbit))) - continue; - if (data & ((u32)1 << mbit)) - value |= (1 << vbit); - vbit++; - } - return value; -} - -static int inline getbit(u32 *samples, int bit) -{ - return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; -} - -/* sump raw samples for visual debugging ;) */ -int ir_dump_samples(u32 *samples, int count) -{ - int i, bit, start; - - printk(KERN_DEBUG "ir samples: "); - start = 0; - for (i = 0; i < count * 32; i++) { - bit = getbit(samples,i); - if (bit) - start = 1; - if (0 == start) - continue; - printk("%s", bit ? "#" : "_"); - } - printk("\n"); - return 0; -} - -/* decode raw samples, pulse distance coding used by NEC remotes */ -int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) -{ - int i,last,bit,len; - u32 curBit; - u32 value; - - /* find start burst */ - for (i = len = 0; i < count * 32; i++) { - bit = getbit(samples,i); - if (bit) { - len++; - } else { - if (len >= 29) - break; - len = 0; - } - } - - /* start burst to short */ - if (len < 29) - return 0xffffffff; - - /* find start silence */ - for (len = 0; i < count * 32; i++) { - bit = getbit(samples,i); - if (bit) { - break; - } else { - len++; - } - } - - /* silence to short */ - if (len < 7) - return 0xffffffff; - - /* go decoding */ - len = 0; - last = 1; - value = 0; curBit = 1; - for (; i < count * 32; i++) { - bit = getbit(samples,i); - if (last) { - if(bit) { - continue; - } else { - len = 1; - } - } else { - if (bit) { - if (len > (low + high) /2) - value |= curBit; - curBit <<= 1; - if (curBit == 1) - break; - } else { - len++; - } - } - last = bit; - } - - return value; -} - -/* decode raw samples, biphase coding, used by rc5 for example */ -int ir_decode_biphase(u32 *samples, int count, int low, int high) -{ - int i,last,bit,len,flips; - u32 value; - - /* find start bit (1) */ - for (i = 0; i < 32; i++) { - bit = getbit(samples,i); - if (bit) - break; - } - - /* go decoding */ - len = 0; - flips = 0; - value = 1; - for (; i < count * 32; i++) { - if (len > high) - break; - if (flips > 1) - break; - last = bit; - bit = getbit(samples,i); - if (last == bit) { - len++; - continue; - } - if (len < low) { - len++; - flips++; - continue; - } - value <<= 1; - value |= bit; - flips = 0; - len = 1; - } - return value; -} - -EXPORT_SYMBOL_GPL(ir_input_init); -EXPORT_SYMBOL_GPL(ir_input_nokey); -EXPORT_SYMBOL_GPL(ir_input_keydown); - -EXPORT_SYMBOL_GPL(ir_extract_bits); -EXPORT_SYMBOL_GPL(ir_dump_samples); -EXPORT_SYMBOL_GPL(ir_decode_biphase); -EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ - diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c deleted file mode 100644 index a294d5c2c..000000000 --- a/drivers/media/common/ir-keymaps.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* - - - Keytables for supported remote controls. This file is part of - video4linux. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You 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 -#include - -#include -#include - -/* empty keytable, can be used as placeholder for not-yet created keytables */ -IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { - [ 0x2a ] = KEY_COFFEE, -}; - -EXPORT_SYMBOL_GPL(ir_codes_empty); - -/* Matt Jesson >' - [ 0x3a ] = KEY_RECORD, // 'capture' - [ 0x0a ] = KEY_MUTE, // 'mute' - [ 0x2c ] = KEY_RECORD, // 'record' - [ 0x1c ] = KEY_PAUSE, // 'pause' - [ 0x3c ] = KEY_STOP, // 'stop' - [ 0x0c ] = KEY_PLAY, // 'play' - [ 0x2e ] = KEY_RED, // 'red' - [ 0x01 ] = KEY_BLUE, // 'blue' / 'cancel' - [ 0x0e ] = KEY_YELLOW, // 'yellow' / 'ok' - [ 0x21 ] = KEY_GREEN, // 'green' - [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -' - [ 0x31 ] = KEY_CHANNELUP, // 'channel +' - [ 0x1e ] = KEY_VOLUMEDOWN, // 'volume -' - [ 0x3e ] = KEY_VOLUMEUP, // 'volume +' -}; - -EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt); - -/* Attila Kondoros */ -IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { - - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - [ 0x00 ] = KEY_0, - [ 0x17 ] = KEY_LAST, // +100 - [ 0x0a ] = KEY_LIST, // recall - - - [ 0x1c ] = KEY_TUNER, // TV/FM - [ 0x15 ] = KEY_SEARCH, // scan - [ 0x12 ] = KEY_POWER, // power - [ 0x1f ] = KEY_VOLUMEDOWN, // vol up - [ 0x1b ] = KEY_VOLUMEUP, // vol down - [ 0x1e ] = KEY_CHANNELDOWN, // chn up - [ 0x1a ] = KEY_CHANNELUP, // chn down - - [ 0x11 ] = KEY_VIDEO, // video - [ 0x0f ] = KEY_ZOOM, // full screen - [ 0x13 ] = KEY_MUTE, // mute/unmute - [ 0x10 ] = KEY_TEXT, // min - - [ 0x0d ] = KEY_STOP, // freeze - [ 0x0e ] = KEY_RECORD, // record - [ 0x1d ] = KEY_PLAYPAUSE, // stop - [ 0x19 ] = KEY_PLAY, // play - - [ 0x16 ] = KEY_GOTO, // osd - [ 0x14 ] = KEY_REFRESH, // default - [ 0x0c ] = KEY_KPPLUS, // fine tune >>>> - [ 0x18 ] = KEY_KPMINUS // fine tune <<<< -}; - -EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp); - -/* ---------------------------------------------------------------------- */ - -IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { - - [ 0x1e ] = KEY_POWER, // power - [ 0x07 ] = KEY_MEDIA, // source - [ 0x1c ] = KEY_SEARCH, // scan - -/* FIXME: duplicate keycodes? - * - * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>> - * The GPIO values are - * 6397fb for both "Scan <" and "CH -", - * 639ffb for "Scan >" and "CH+", - * 6384fb for "Tune <" and "<<<", - * 638cfb for "Tune >" and ">>>", regardless of the mask. - * - * [ 0x17 ] = KEY_BACK, // fm scan << - * [ 0x1f ] = KEY_FORWARD, // fm scan >> - * - * [ 0x04 ] = KEY_LEFT, // fm tuning < - * [ 0x0c ] = KEY_RIGHT, // fm tuning > - * - * For now, these four keys are disabled. Pressing them will generate - * the CH+/CH-/<<>> events - */ - - [ 0x03 ] = KEY_TUNER, // TV/FM - - [ 0x00 ] = KEY_RECORD, - [ 0x08 ] = KEY_STOP, - [ 0x11 ] = KEY_PLAY, - - [ 0x1a ] = KEY_PLAYPAUSE, // freeze - [ 0x19 ] = KEY_ZOOM, // zoom - [ 0x0f ] = KEY_TEXT, // min - - [ 0x01 ] = KEY_1, - [ 0x0b ] = KEY_2, - [ 0x1b ] = KEY_3, - [ 0x05 ] = KEY_4, - [ 0x09 ] = KEY_5, - [ 0x15 ] = KEY_6, - [ 0x06 ] = KEY_7, - [ 0x0a ] = KEY_8, - [ 0x12 ] = KEY_9, - [ 0x02 ] = KEY_0, - [ 0x10 ] = KEY_LAST, // +100 - [ 0x13 ] = KEY_LIST, // recall - - [ 0x1f ] = KEY_CHANNELUP, // chn down - [ 0x17 ] = KEY_CHANNELDOWN, // chn up - [ 0x16 ] = KEY_VOLUMEUP, // vol down - [ 0x14 ] = KEY_VOLUMEDOWN, // vol up - - [ 0x04 ] = KEY_KPMINUS, // <<< - [ 0x0e ] = KEY_SETUP, // function - [ 0x0c ] = KEY_KPPLUS, // >>> - - [ 0x0d ] = KEY_GOTO, // mts - [ 0x1d ] = KEY_REFRESH, // reset - [ 0x18 ] = KEY_MUTE // mute/unmute -}; - -EXPORT_SYMBOL_GPL(ir_codes_pixelview); - -IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = { - [ 0x00 ] = KEY_0, - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - [ 0x0a ] = KEY_TV, - [ 0x0b ] = KEY_AUX, - [ 0x0c ] = KEY_DVD, - [ 0x0d ] = KEY_POWER, - [ 0x0e ] = KEY_MHP, /* labelled 'Picture' */ - [ 0x0f ] = KEY_AUDIO, - [ 0x10 ] = KEY_INFO, - [ 0x11 ] = KEY_F13, /* 16:9 */ - [ 0x12 ] = KEY_F14, /* 14:9 */ - [ 0x13 ] = KEY_EPG, - [ 0x14 ] = KEY_EXIT, - [ 0x15 ] = KEY_MENU, - [ 0x16 ] = KEY_UP, - [ 0x17 ] = KEY_DOWN, - [ 0x18 ] = KEY_LEFT, - [ 0x19 ] = KEY_RIGHT, - [ 0x1a ] = KEY_ENTER, - [ 0x1b ] = KEY_CHANNELUP, - [ 0x1c ] = KEY_CHANNELDOWN, - [ 0x1d ] = KEY_VOLUMEUP, - [ 0x1e ] = KEY_VOLUMEDOWN, - [ 0x1f ] = KEY_RED, - [ 0x20 ] = KEY_GREEN, - [ 0x21 ] = KEY_YELLOW, - [ 0x22 ] = KEY_BLUE, - [ 0x23 ] = KEY_SUBTITLE, - [ 0x24 ] = KEY_F15, /* AD */ - [ 0x25 ] = KEY_TEXT, - [ 0x26 ] = KEY_MUTE, - [ 0x27 ] = KEY_REWIND, - [ 0x28 ] = KEY_STOP, - [ 0x29 ] = KEY_PLAY, - [ 0x2a ] = KEY_FASTFORWARD, - [ 0x2b ] = KEY_F16, /* chapter */ - [ 0x2c ] = KEY_PAUSE, - [ 0x2d ] = KEY_PLAY, - [ 0x2e ] = KEY_RECORD, - [ 0x2f ] = KEY_F17, /* picture in picture */ - [ 0x30 ] = KEY_KPPLUS, /* zoom in */ - [ 0x31 ] = KEY_KPMINUS, /* zoom out */ - [ 0x32 ] = KEY_F18, /* capture */ - [ 0x33 ] = KEY_F19, /* web */ - [ 0x34 ] = KEY_EMAIL, - [ 0x35 ] = KEY_PHONE, - [ 0x36 ] = KEY_PC -}; - -EXPORT_SYMBOL_GPL(ir_codes_nebula); - -/* DigitalNow DNTV Live DVB-T Remote */ -IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = { - [ 0x00 ] = KEY_ESC, /* 'go up a level?' */ - /* Keys 0 to 9 */ - [ 0x0a ] = KEY_0, - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - - [ 0x0b ] = KEY_TUNER, /* tv/fm */ - [ 0x0c ] = KEY_SEARCH, /* scan */ - [ 0x0d ] = KEY_STOP, - [ 0x0e ] = KEY_PAUSE, - [ 0x0f ] = KEY_LIST, /* source */ - - [ 0x10 ] = KEY_MUTE, - [ 0x11 ] = KEY_REWIND, /* backward << */ - [ 0x12 ] = KEY_POWER, - [ 0x13 ] = KEY_S, /* snap */ - [ 0x14 ] = KEY_AUDIO, /* stereo */ - [ 0x15 ] = KEY_CLEAR, /* reset */ - [ 0x16 ] = KEY_PLAY, - [ 0x17 ] = KEY_ENTER, - [ 0x18 ] = KEY_ZOOM, /* full screen */ - [ 0x19 ] = KEY_FASTFORWARD, /* forward >> */ - [ 0x1a ] = KEY_CHANNELUP, - [ 0x1b ] = KEY_VOLUMEUP, - [ 0x1c ] = KEY_INFO, /* preview */ - [ 0x1d ] = KEY_RECORD, /* record */ - [ 0x1e ] = KEY_CHANNELDOWN, - [ 0x1f ] = KEY_VOLUMEDOWN, -}; - -EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t); - -/* ---------------------------------------------------------------------- */ - -/* IO-DATA BCTV7E Remote */ -IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = { - [ 0x40 ] = KEY_TV, - [ 0x20 ] = KEY_RADIO, /* FM */ - [ 0x60 ] = KEY_EPG, - [ 0x00 ] = KEY_POWER, - - /* Keys 0 to 9 */ - [ 0x44 ] = KEY_0, /* 10 */ - [ 0x50 ] = KEY_1, - [ 0x30 ] = KEY_2, - [ 0x70 ] = KEY_3, - [ 0x48 ] = KEY_4, - [ 0x28 ] = KEY_5, - [ 0x68 ] = KEY_6, - [ 0x58 ] = KEY_7, - [ 0x38 ] = KEY_8, - [ 0x78 ] = KEY_9, - - [ 0x10 ] = KEY_L, /* Live */ - [ 0x08 ] = KEY_T, /* Time Shift */ - - [ 0x18 ] = KEY_PLAYPAUSE, /* Play */ - - [ 0x24 ] = KEY_ENTER, /* 11 */ - [ 0x64 ] = KEY_ESC, /* 12 */ - [ 0x04 ] = KEY_M, /* Multi */ - - [ 0x54 ] = KEY_VIDEO, - [ 0x34 ] = KEY_CHANNELUP, - [ 0x74 ] = KEY_VOLUMEUP, - [ 0x14 ] = KEY_MUTE, - - [ 0x4c ] = KEY_S, /* SVIDEO */ - [ 0x2c ] = KEY_CHANNELDOWN, - [ 0x6c ] = KEY_VOLUMEDOWN, - [ 0x0c ] = KEY_ZOOM, - - [ 0x5c ] = KEY_PAUSE, - [ 0x3c ] = KEY_C, /* || (red) */ - [ 0x7c ] = KEY_RECORD, /* recording */ - [ 0x1c ] = KEY_STOP, - - [ 0x41 ] = KEY_REWIND, /* backward << */ - [ 0x21 ] = KEY_PLAY, - [ 0x61 ] = KEY_FASTFORWARD, /* forward >> */ - [ 0x01 ] = KEY_NEXT, /* skip >| */ -}; - -EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e); - -/* ---------------------------------------------------------------------- */ - -/* ADS Tech Instant TV DVB-T PCI Remote */ -IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = { - /* Keys 0 to 9 */ - [ 0x4d ] = KEY_0, - [ 0x57 ] = KEY_1, - [ 0x4f ] = KEY_2, - [ 0x53 ] = KEY_3, - [ 0x56 ] = KEY_4, - [ 0x4e ] = KEY_5, - [ 0x5e ] = KEY_6, - [ 0x54 ] = KEY_7, - [ 0x4c ] = KEY_8, - [ 0x5c ] = KEY_9, - - [ 0x5b ] = KEY_POWER, - [ 0x5f ] = KEY_MUTE, - [ 0x55 ] = KEY_GOTO, - [ 0x5d ] = KEY_SEARCH, - [ 0x17 ] = KEY_EPG, /* Guide */ - [ 0x1f ] = KEY_MENU, - [ 0x0f ] = KEY_UP, - [ 0x46 ] = KEY_DOWN, - [ 0x16 ] = KEY_LEFT, - [ 0x1e ] = KEY_RIGHT, - [ 0x0e ] = KEY_SELECT, /* Enter */ - [ 0x5a ] = KEY_INFO, - [ 0x52 ] = KEY_EXIT, - [ 0x59 ] = KEY_PREVIOUS, - [ 0x51 ] = KEY_NEXT, - [ 0x58 ] = KEY_REWIND, - [ 0x50 ] = KEY_FORWARD, - [ 0x44 ] = KEY_PLAYPAUSE, - [ 0x07 ] = KEY_STOP, - [ 0x1b ] = KEY_RECORD, - [ 0x13 ] = KEY_TUNER, /* Live */ - [ 0x0a ] = KEY_A, - [ 0x12 ] = KEY_B, - [ 0x03 ] = KEY_PROG1, /* 1 */ - [ 0x01 ] = KEY_PROG2, /* 2 */ - [ 0x00 ] = KEY_PROG3, /* 3 */ - [ 0x06 ] = KEY_DVD, - [ 0x48 ] = KEY_AUX, /* Photo */ - [ 0x40 ] = KEY_VIDEO, - [ 0x19 ] = KEY_AUDIO, /* Music */ - [ 0x0b ] = KEY_CHANNELUP, - [ 0x08 ] = KEY_CHANNELDOWN, - [ 0x15 ] = KEY_VOLUMEUP, - [ 0x1c ] = KEY_VOLUMEDOWN, -}; - -EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci); - -/* ---------------------------------------------------------------------- */ - -/* MSI TV@nywhere remote */ -IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = { - /* Keys 0 to 9 */ - [ 0x00 ] = KEY_0, - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - - [ 0x0c ] = KEY_MUTE, - [ 0x0f ] = KEY_SCREEN, /* Full Screen */ - [ 0x10 ] = KEY_F, /* Funtion */ - [ 0x11 ] = KEY_T, /* Time shift */ - [ 0x12 ] = KEY_POWER, - [ 0x13 ] = KEY_MEDIA, /* MTS */ - [ 0x14 ] = KEY_SLOW, - [ 0x16 ] = KEY_REWIND, /* backward << */ - [ 0x17 ] = KEY_ENTER, /* Return */ - [ 0x18 ] = KEY_FASTFORWARD, /* forward >> */ - [ 0x1a ] = KEY_CHANNELUP, - [ 0x1b ] = KEY_VOLUMEUP, - [ 0x1e ] = KEY_CHANNELDOWN, - [ 0x1f ] = KEY_VOLUMEDOWN, -}; - -EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere); - -/* ---------------------------------------------------------------------- */ - -/* Cinergy 1400 DVB-T */ -IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { - [ 0x01 ] = KEY_POWER, - [ 0x02 ] = KEY_1, - [ 0x03 ] = KEY_2, - [ 0x04 ] = KEY_3, - [ 0x05 ] = KEY_4, - [ 0x06 ] = KEY_5, - [ 0x07 ] = KEY_6, - [ 0x08 ] = KEY_7, - [ 0x09 ] = KEY_8, - [ 0x0a ] = KEY_9, - [ 0x0c ] = KEY_0, - - [ 0x0b ] = KEY_VIDEO, - [ 0x0d ] = KEY_REFRESH, - [ 0x0e ] = KEY_SELECT, - [ 0x0f ] = KEY_EPG, - [ 0x10 ] = KEY_UP, - [ 0x11 ] = KEY_LEFT, - [ 0x12 ] = KEY_OK, - [ 0x13 ] = KEY_RIGHT, - [ 0x14 ] = KEY_DOWN, - [ 0x15 ] = KEY_TEXT, - [ 0x16 ] = KEY_INFO, - - [ 0x17 ] = KEY_RED, - [ 0x18 ] = KEY_GREEN, - [ 0x19 ] = KEY_YELLOW, - [ 0x1a ] = KEY_BLUE, - - [ 0x1b ] = KEY_CHANNELUP, - [ 0x1c ] = KEY_VOLUMEUP, - [ 0x1d ] = KEY_MUTE, - [ 0x1e ] = KEY_VOLUMEDOWN, - [ 0x1f ] = KEY_CHANNELDOWN, - - [ 0x40 ] = KEY_PAUSE, - [ 0x4c ] = KEY_PLAY, - [ 0x58 ] = KEY_RECORD, - [ 0x54 ] = KEY_PREVIOUS, - [ 0x48 ] = KEY_STOP, - [ 0x5c ] = KEY_NEXT, -}; - -EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400); - -/* ---------------------------------------------------------------------- */ - -/* AVERTV STUDIO 303 Remote */ -IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = { - [ 0x2a ] = KEY_1, - [ 0x32 ] = KEY_2, - [ 0x3a ] = KEY_3, - [ 0x4a ] = KEY_4, - [ 0x52 ] = KEY_5, - [ 0x5a ] = KEY_6, - [ 0x6a ] = KEY_7, - [ 0x72 ] = KEY_8, - [ 0x7a ] = KEY_9, - [ 0x0e ] = KEY_0, - - [ 0x02 ] = KEY_POWER, - [ 0x22 ] = KEY_VIDEO, - [ 0x42 ] = KEY_AUDIO, - [ 0x62 ] = KEY_ZOOM, - [ 0x0a ] = KEY_TV, - [ 0x12 ] = KEY_CD, - [ 0x1a ] = KEY_TEXT, - - [ 0x16 ] = KEY_SUBTITLE, - [ 0x1e ] = KEY_REWIND, - [ 0x06 ] = KEY_PRINT, - - [ 0x2e ] = KEY_SEARCH, - [ 0x36 ] = KEY_SLEEP, - [ 0x3e ] = KEY_SHUFFLE, - [ 0x26 ] = KEY_MUTE, - - [ 0x4e ] = KEY_RECORD, - [ 0x56 ] = KEY_PAUSE, - [ 0x5e ] = KEY_STOP, - [ 0x46 ] = KEY_PLAY, - - [ 0x6e ] = KEY_RED, - [ 0x0b ] = KEY_GREEN, - [ 0x66 ] = KEY_YELLOW, - [ 0x03 ] = KEY_BLUE, - - [ 0x76 ] = KEY_LEFT, - [ 0x7e ] = KEY_RIGHT, - [ 0x13 ] = KEY_DOWN, - [ 0x1b ] = KEY_UP, -}; - -EXPORT_SYMBOL_GPL(ir_codes_avertv_303); - -/* ---------------------------------------------------------------------- */ - -/* DigitalNow DNTV Live! DVB-T Pro Remote */ -IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = { - [ 0x16 ] = KEY_POWER, - [ 0x5b ] = KEY_HOME, - - [ 0x55 ] = KEY_TV, /* live tv */ - [ 0x58 ] = KEY_TUNER, /* digital Radio */ - [ 0x5a ] = KEY_RADIO, /* FM radio */ - [ 0x59 ] = KEY_DVD, /* dvd menu */ - [ 0x03 ] = KEY_1, - [ 0x01 ] = KEY_2, - [ 0x06 ] = KEY_3, - [ 0x09 ] = KEY_4, - [ 0x1d ] = KEY_5, - [ 0x1f ] = KEY_6, - [ 0x0d ] = KEY_7, - [ 0x19 ] = KEY_8, - [ 0x1b ] = KEY_9, - [ 0x0c ] = KEY_CANCEL, - [ 0x15 ] = KEY_0, - [ 0x4a ] = KEY_CLEAR, - [ 0x13 ] = KEY_BACK, - [ 0x00 ] = KEY_TAB, - [ 0x4b ] = KEY_UP, - [ 0x4e ] = KEY_LEFT, - [ 0x4f ] = KEY_OK, - [ 0x52 ] = KEY_RIGHT, - [ 0x51 ] = KEY_DOWN, - [ 0x1e ] = KEY_VOLUMEUP, - [ 0x0a ] = KEY_VOLUMEDOWN, - [ 0x02 ] = KEY_CHANNELDOWN, - [ 0x05 ] = KEY_CHANNELUP, - [ 0x11 ] = KEY_RECORD, - [ 0x14 ] = KEY_PLAY, - [ 0x4c ] = KEY_PAUSE, - [ 0x1a ] = KEY_STOP, - [ 0x40 ] = KEY_REWIND, - [ 0x12 ] = KEY_FASTFORWARD, - [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */ - [ 0x42 ] = KEY_NEXTSONG, /* skip >| */ - [ 0x54 ] = KEY_CAMERA, /* capture */ - [ 0x50 ] = KEY_LANGUAGE, /* sap */ - [ 0x47 ] = KEY_TV2, /* pip */ - [ 0x4d ] = KEY_SCREEN, - [ 0x43 ] = KEY_SUBTITLE, - [ 0x10 ] = KEY_MUTE, - [ 0x49 ] = KEY_AUDIO, /* l/r */ - [ 0x07 ] = KEY_SLEEP, - [ 0x08 ] = KEY_VIDEO, /* a/v */ - [ 0x0e ] = KEY_PREVIOUS, /* recall */ - [ 0x45 ] = KEY_ZOOM, /* zoom + */ - [ 0x46 ] = KEY_ANGLE, /* zoom - */ - [ 0x56 ] = KEY_RED, - [ 0x57 ] = KEY_GREEN, - [ 0x5c ] = KEY_YELLOW, - [ 0x5d ] = KEY_BLUE, -}; - -EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro); - -IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { - [ 0x01 ] = KEY_CHANNEL, - [ 0x02 ] = KEY_SELECT, - [ 0x03 ] = KEY_MUTE, - [ 0x04 ] = KEY_POWER, - [ 0x05 ] = KEY_1, - [ 0x06 ] = KEY_2, - [ 0x07 ] = KEY_3, - [ 0x08 ] = KEY_CHANNELUP, - [ 0x09 ] = KEY_4, - [ 0x0a ] = KEY_5, - [ 0x0b ] = KEY_6, - [ 0x0c ] = KEY_CHANNELDOWN, - [ 0x0d ] = KEY_7, - [ 0x0e ] = KEY_8, - [ 0x0f ] = KEY_9, - [ 0x10 ] = KEY_VOLUMEUP, - [ 0x11 ] = KEY_0, - [ 0x12 ] = KEY_MENU, - [ 0x13 ] = KEY_PRINT, - [ 0x14 ] = KEY_VOLUMEDOWN, - [ 0x16 ] = KEY_PAUSE, - [ 0x18 ] = KEY_RECORD, - [ 0x19 ] = KEY_REWIND, - [ 0x1a ] = KEY_PLAY, - [ 0x1b ] = KEY_FORWARD, - [ 0x1c ] = KEY_BACKSPACE, - [ 0x1e ] = KEY_STOP, - [ 0x40 ] = KEY_ZOOM, -}; - -EXPORT_SYMBOL_GPL(ir_codes_em_terratec); - -IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { - [ 0x3a ] = KEY_0, - [ 0x31 ] = KEY_1, - [ 0x32 ] = KEY_2, - [ 0x33 ] = KEY_3, - [ 0x34 ] = KEY_4, - [ 0x35 ] = KEY_5, - [ 0x36 ] = KEY_6, - [ 0x37 ] = KEY_7, - [ 0x38 ] = KEY_8, - [ 0x39 ] = KEY_9, - - [ 0x2f ] = KEY_POWER, - - [ 0x2e ] = KEY_P, - [ 0x1f ] = KEY_L, - [ 0x2b ] = KEY_I, - - [ 0x2d ] = KEY_ZOOM, - [ 0x1e ] = KEY_ZOOM, - [ 0x1b ] = KEY_VOLUMEUP, - [ 0x0f ] = KEY_VOLUMEDOWN, - [ 0x17 ] = KEY_CHANNELUP, - [ 0x1c ] = KEY_CHANNELDOWN, - [ 0x25 ] = KEY_INFO, - - [ 0x3c ] = KEY_MUTE, - - [ 0x3d ] = KEY_LEFT, - [ 0x3b ] = KEY_RIGHT, - - [ 0x3f ] = KEY_UP, - [ 0x3e ] = KEY_DOWN, - [ 0x1a ] = KEY_PAUSE, - - [ 0x1d ] = KEY_MENU, - [ 0x19 ] = KEY_PLAY, - [ 0x16 ] = KEY_REWIND, - [ 0x13 ] = KEY_FORWARD, - [ 0x15 ] = KEY_PAUSE, - [ 0x0e ] = KEY_REWIND, - [ 0x0d ] = KEY_PLAY, - [ 0x0b ] = KEY_STOP, - [ 0x07 ] = KEY_FORWARD, - [ 0x27 ] = KEY_RECORD, - [ 0x26 ] = KEY_TUNER, - [ 0x29 ] = KEY_TEXT, - [ 0x2a ] = KEY_MEDIA, - [ 0x18 ] = KEY_EPG, - [ 0x27 ] = KEY_RECORD, -}; - -EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb); - -IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { - [ 0x0f ] = KEY_0, - [ 0x03 ] = KEY_1, - [ 0x04 ] = KEY_2, - [ 0x05 ] = KEY_3, - [ 0x07 ] = KEY_4, - [ 0x08 ] = KEY_5, - [ 0x09 ] = KEY_6, - [ 0x0b ] = KEY_7, - [ 0x0c ] = KEY_8, - [ 0x0d ] = KEY_9, - - [ 0x0e ] = KEY_MODE, // Air/Cable - [ 0x11 ] = KEY_VIDEO, // Video - [ 0x15 ] = KEY_AUDIO, // Audio - [ 0x00 ] = KEY_POWER, // Power - [ 0x18 ] = KEY_TUNER, // AV Source - [ 0x02 ] = KEY_ZOOM, // Fullscreen - [ 0x1a ] = KEY_LANGUAGE, // Stereo - [ 0x1b ] = KEY_MUTE, // Mute - [ 0x14 ] = KEY_VOLUMEUP, // Volume + - [ 0x17 ] = KEY_VOLUMEDOWN, // Volume - - [ 0x12 ] = KEY_CHANNELUP, // Channel + - [ 0x13 ] = KEY_CHANNELDOWN, // Channel - - [ 0x06 ] = KEY_AGAIN, // Recall - [ 0x10 ] = KEY_ENTER, // Enter -}; - -EXPORT_SYMBOL_GPL(ir_codes_flyvideo); - -IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE] = { - [ 0x01 ] = KEY_ZOOM, // Full Screen - [ 0x00 ] = KEY_POWER, // Power - - [ 0x03 ] = KEY_1, - [ 0x04 ] = KEY_2, - [ 0x05 ] = KEY_3, - [ 0x07 ] = KEY_4, - [ 0x08 ] = KEY_5, - [ 0x09 ] = KEY_6, - [ 0x0b ] = KEY_7, - [ 0x0c ] = KEY_8, - [ 0x0d ] = KEY_9, - [ 0x06 ] = KEY_AGAIN, // Recall - [ 0x0f ] = KEY_0, - [ 0x10 ] = KEY_MUTE, // Mute - [ 0x02 ] = KEY_RADIO, // TV/Radio - [ 0x1b ] = KEY_LANGUAGE, // SAP (Second Audio Program) - - [ 0x14 ] = KEY_VOLUMEUP, // VOL+ - [ 0x17 ] = KEY_VOLUMEDOWN, // VOL- - [ 0x12 ] = KEY_CHANNELUP, // CH+ - [ 0x13 ] = KEY_CHANNELDOWN, // CH- - [ 0x1d ] = KEY_ENTER, // Enter - - [ 0x1a ] = KEY_MODE, // PIP - [ 0x18 ] = KEY_TUNER, // Source - - [ 0x1e ] = KEY_RECORD, // Record/Pause - [ 0x15 ] = KEY_ANGLE, // Swap (no label on key) - [ 0x1c ] = KEY_PAUSE, // Timeshift/Pause - [ 0x19 ] = KEY_BACK, // Rewind << - [ 0x0a ] = KEY_PLAYPAUSE, // Play/Pause - [ 0x1f ] = KEY_FORWARD, // Forward >> - [ 0x16 ] = KEY_PREVIOUS, // Back |<< - [ 0x11 ] = KEY_STOP, // Stop - [ 0x0e ] = KEY_NEXT, // End >>| -}; - -EXPORT_SYMBOL_GPL(ir_codes_flydvb); - -IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE] = { - [ 0x00 ] = KEY_0, - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - - [ 0x0a ] = KEY_POWER, - [ 0x0b ] = KEY_PROG1, // app - [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen - [ 0x0d ] = KEY_CHANNELUP, // channel - [ 0x0e ] = KEY_CHANNELDOWN, // channel- - [ 0x0f ] = KEY_VOLUMEUP, - [ 0x10 ] = KEY_VOLUMEDOWN, - [ 0x11 ] = KEY_TUNER, // AV - [ 0x12 ] = KEY_NUMLOCK, // -/-- - [ 0x13 ] = KEY_AUDIO, // audio - [ 0x14 ] = KEY_MUTE, - [ 0x15 ] = KEY_UP, - [ 0x16 ] = KEY_DOWN, - [ 0x17 ] = KEY_LEFT, - [ 0x18 ] = KEY_RIGHT, - [ 0x19 ] = BTN_LEFT, - [ 0x1a ] = BTN_RIGHT, - [ 0x1b ] = KEY_WWW, // text - [ 0x1c ] = KEY_REWIND, - [ 0x1d ] = KEY_FORWARD, - [ 0x1e ] = KEY_RECORD, - [ 0x1f ] = KEY_PLAY, - [ 0x20 ] = KEY_PREVIOUSSONG, - [ 0x21 ] = KEY_NEXTSONG, - [ 0x22 ] = KEY_PAUSE, - [ 0x23 ] = KEY_STOP, -}; - -EXPORT_SYMBOL_GPL(ir_codes_cinergy); - -/* Alfons Geser - * updates from Job D. R. Borges */ -IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE] = { - [ 0x12 ] = KEY_POWER, - [ 0x01 ] = KEY_TV, // DVR - [ 0x15 ] = KEY_DVD, // DVD - [ 0x17 ] = KEY_AUDIO, // music - // DVR mode / DVD mode / music mode - - [ 0x1b ] = KEY_MUTE, // mute - [ 0x02 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek - [ 0x1e ] = KEY_SUBTITLE, // closed captioning / subtitle / seek - [ 0x16 ] = KEY_ZOOM, // full screen - [ 0x1c ] = KEY_VIDEO, // video source / eject / delall - [ 0x1d ] = KEY_RESTART, // playback / angle / del - [ 0x2f ] = KEY_SEARCH, // scan / menu / playlist - [ 0x30 ] = KEY_CHANNEL, // CH surfing / bookmark / memo - - [ 0x31 ] = KEY_HELP, // help - [ 0x32 ] = KEY_MODE, // num/memo - [ 0x33 ] = KEY_ESC, // cancel - - [ 0x0c ] = KEY_UP, // up - [ 0x10 ] = KEY_DOWN, // down - [ 0x08 ] = KEY_LEFT, // left - [ 0x04 ] = KEY_RIGHT, // right - [ 0x03 ] = KEY_SELECT, // select - - [ 0x1f ] = KEY_REWIND, // rewind - [ 0x20 ] = KEY_PLAYPAUSE, // play/pause - [ 0x29 ] = KEY_FORWARD, // forward - [ 0x14 ] = KEY_AGAIN, // repeat - [ 0x2b ] = KEY_RECORD, // recording - [ 0x2c ] = KEY_STOP, // stop - [ 0x2d ] = KEY_PLAY, // play - [ 0x2e ] = KEY_SHUFFLE, // snapshot / shuffle - - [ 0x00 ] = KEY_0, - [ 0x05 ] = KEY_1, - [ 0x06 ] = KEY_2, - [ 0x07 ] = KEY_3, - [ 0x09 ] = KEY_4, - [ 0x0a ] = KEY_5, - [ 0x0b ] = KEY_6, - [ 0x0d ] = KEY_7, - [ 0x0e ] = KEY_8, - [ 0x0f ] = KEY_9, - - [ 0x2a ] = KEY_VOLUMEUP, - [ 0x11 ] = KEY_VOLUMEDOWN, - [ 0x18 ] = KEY_CHANNELUP, // CH.tracking up - [ 0x19 ] = KEY_CHANNELDOWN, // CH.tracking down - - [ 0x13 ] = KEY_ENTER, // enter - [ 0x21 ] = KEY_DOT, // . (decimal dot) -}; - -EXPORT_SYMBOL_GPL(ir_codes_eztv); - -/* Alex Hermann */ -IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = { - [ 0x28 ] = KEY_1, - [ 0x18 ] = KEY_2, - [ 0x38 ] = KEY_3, - [ 0x24 ] = KEY_4, - [ 0x14 ] = KEY_5, - [ 0x34 ] = KEY_6, - [ 0x2c ] = KEY_7, - [ 0x1c ] = KEY_8, - [ 0x3c ] = KEY_9, - [ 0x22 ] = KEY_0, - - [ 0x20 ] = KEY_TV, /* TV/FM */ - [ 0x10 ] = KEY_CD, /* CD */ - [ 0x30 ] = KEY_TEXT, /* TELETEXT */ - [ 0x00 ] = KEY_POWER, /* POWER */ - - [ 0x08 ] = KEY_VIDEO, /* VIDEO */ - [ 0x04 ] = KEY_AUDIO, /* AUDIO */ - [ 0x0c ] = KEY_ZOOM, /* FULL SCREEN */ - - [ 0x12 ] = KEY_SUBTITLE, /* DISPLAY */ - [ 0x32 ] = KEY_REWIND, /* LOOP */ - [ 0x02 ] = KEY_PRINT, /* PREVIEW */ - - [ 0x2a ] = KEY_SEARCH, /* AUTOSCAN */ - [ 0x1a ] = KEY_SLEEP, /* FREEZE */ - [ 0x3a ] = KEY_SHUFFLE, /* SNAPSHOT */ - [ 0x0a ] = KEY_MUTE, /* MUTE */ - - [ 0x26 ] = KEY_RECORD, /* RECORD */ - [ 0x16 ] = KEY_PAUSE, /* PAUSE */ - [ 0x36 ] = KEY_STOP, /* STOP */ - [ 0x06 ] = KEY_PLAY, /* PLAY */ - - [ 0x2e ] = KEY_RED, /* RED */ - [ 0x21 ] = KEY_GREEN, /* GREEN */ - [ 0x0e ] = KEY_YELLOW, /* YELLOW */ - [ 0x01 ] = KEY_BLUE, /* BLUE */ - - [ 0x1e ] = KEY_VOLUMEDOWN, /* VOLUME- */ - [ 0x3e ] = KEY_VOLUMEUP, /* VOLUME+ */ - [ 0x11 ] = KEY_CHANNELDOWN, /* CHANNEL/PAGE- */ - [ 0x31 ] = KEY_CHANNELUP /* CHANNEL/PAGE+ */ -}; - -EXPORT_SYMBOL_GPL(ir_codes_avermedia); - -IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE] = { - [ 0x14 ] = KEY_MUTE, - [ 0x24 ] = KEY_ZOOM, - - [ 0x01 ] = KEY_DVD, - [ 0x23 ] = KEY_RADIO, - [ 0x00 ] = KEY_TV, - - [ 0x0a ] = KEY_REWIND, - [ 0x08 ] = KEY_PLAYPAUSE, - [ 0x0f ] = KEY_FORWARD, - - [ 0x02 ] = KEY_PREVIOUS, - [ 0x07 ] = KEY_STOP, - [ 0x06 ] = KEY_NEXT, - - [ 0x0c ] = KEY_UP, - [ 0x0e ] = KEY_DOWN, - [ 0x0b ] = KEY_LEFT, - [ 0x0d ] = KEY_RIGHT, - [ 0x11 ] = KEY_OK, - - [ 0x03 ] = KEY_MENU, - [ 0x09 ] = KEY_SETUP, - [ 0x05 ] = KEY_VIDEO, - [ 0x22 ] = KEY_CHANNEL, - - [ 0x12 ] = KEY_VOLUMEUP, - [ 0x15 ] = KEY_VOLUMEDOWN, - [ 0x10 ] = KEY_CHANNELUP, - [ 0x13 ] = KEY_CHANNELDOWN, - - [ 0x04 ] = KEY_RECORD, - - [ 0x16 ] = KEY_1, - [ 0x17 ] = KEY_2, - [ 0x18 ] = KEY_3, - [ 0x19 ] = KEY_4, - [ 0x1a ] = KEY_5, - [ 0x1b ] = KEY_6, - [ 0x1c ] = KEY_7, - [ 0x1d ] = KEY_8, - [ 0x1e ] = KEY_9, - [ 0x1f ] = KEY_0, - - [ 0x20 ] = KEY_LANGUAGE, - [ 0x21 ] = KEY_SLEEP, -}; - -EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr); - -/* Michael Tokarev - http://www.corpit.ru/mjt/beholdTV/remote_control.jpg - keytable is used by MANLI MTV00[ 0x0c ] and BeholdTV 40[13] at - least, and probably other cards too. - The "ascii-art picture" below (in comments, first row - is the keycode in hex, and subsequent row(s) shows - the button labels (several variants when appropriate) - helps to descide which keycodes to assign to the buttons. - */ -IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = { - - /* 0x1c 0x12 * - * FUNCTION POWER * - * FM (|) * - * */ - [ 0x1c ] = KEY_RADIO, /*XXX*/ - [ 0x12 ] = KEY_POWER, - - /* 0x01 0x02 0x03 * - * 1 2 3 * - * * - * 0x04 0x05 0x06 * - * 4 5 6 * - * * - * 0x07 0x08 0x09 * - * 7 8 9 * - * */ - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - - /* 0x0a 0x00 0x17 * - * RECALL 0 +100 * - * PLUS * - * */ - [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */ - [ 0x00 ] = KEY_0, - [ 0x17 ] = KEY_DIGITS, /*XXX*/ - - /* 0x14 0x10 * - * MENU INFO * - * OSD */ - [ 0x14 ] = KEY_MENU, - [ 0x10 ] = KEY_INFO, - - /* 0x0b * - * Up * - * * - * 0x18 0x16 0x0c * - * Left Ok Right * - * * - * 0x015 * - * Down * - * */ - [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */ - [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */ - [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */ - [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */ - [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */ - - /* 0x11 0x0d * - * TV/AV MODE * - * SOURCE STEREO * - * */ - [ 0x11 ] = KEY_TV, /*XXX*/ - [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */ - - /* 0x0f 0x1b 0x1a * - * AUDIO Vol+ Chan+ * - * TIMESHIFT??? * - * * - * 0x0e 0x1f 0x1e * - * SLEEP Vol- Chan- * - * */ - [ 0x0f ] = KEY_AUDIO, - [ 0x1b ] = KEY_VOLUMEUP, - [ 0x1a ] = KEY_CHANNELUP, - [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */ - [ 0x1f ] = KEY_VOLUMEDOWN, - [ 0x1e ] = KEY_CHANNELDOWN, - - /* 0x13 0x19 * - * MUTE SNAPSHOT* - * */ - [ 0x13 ] = KEY_MUTE, - [ 0x19 ] = KEY_RECORD, /*XXX*/ - - // 0x1d unused ? -}; - -EXPORT_SYMBOL_GPL(ir_codes_manli); - -/* Mike Baikov */ -IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = { - - [ 0x21 ] = KEY_POWER, - [ 0x69 ] = KEY_TV, - [ 0x33 ] = KEY_0, - [ 0x51 ] = KEY_1, - [ 0x31 ] = KEY_2, - [ 0x71 ] = KEY_3, - [ 0x3b ] = KEY_4, - [ 0x58 ] = KEY_5, - [ 0x41 ] = KEY_6, - [ 0x48 ] = KEY_7, - [ 0x30 ] = KEY_8, - [ 0x53 ] = KEY_9, - [ 0x73 ] = KEY_AGAIN, /* LOOP */ - [ 0x0a ] = KEY_AUDIO, - [ 0x61 ] = KEY_PRINT, /* PREVIEW */ - [ 0x7a ] = KEY_VIDEO, - [ 0x20 ] = KEY_CHANNELUP, - [ 0x40 ] = KEY_CHANNELDOWN, - [ 0x18 ] = KEY_VOLUMEDOWN, - [ 0x50 ] = KEY_VOLUMEUP, - [ 0x10 ] = KEY_MUTE, - [ 0x4a ] = KEY_SEARCH, - [ 0x7b ] = KEY_SHUFFLE, /* SNAPSHOT */ - [ 0x22 ] = KEY_RECORD, - [ 0x62 ] = KEY_STOP, - [ 0x78 ] = KEY_PLAY, - [ 0x39 ] = KEY_REWIND, - [ 0x59 ] = KEY_PAUSE, - [ 0x19 ] = KEY_FORWARD, - [ 0x09 ] = KEY_ZOOM, - - [ 0x52 ] = KEY_F21, /* LIVE TIMESHIFT */ - [ 0x1a ] = KEY_F22, /* MIN TIMESHIFT */ - [ 0x3a ] = KEY_F23, /* TIMESHIFT */ - [ 0x70 ] = KEY_F24, /* NORMAL TIMESHIFT */ -}; - -EXPORT_SYMBOL_GPL(ir_codes_gotview7135); - -IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { - [ 0x03 ] = KEY_POWER, - [ 0x6f ] = KEY_MUTE, - [ 0x10 ] = KEY_BACKSPACE, /* Recall */ - - [ 0x11 ] = KEY_0, - [ 0x04 ] = KEY_1, - [ 0x05 ] = KEY_2, - [ 0x06 ] = KEY_3, - [ 0x08 ] = KEY_4, - [ 0x09 ] = KEY_5, - [ 0x0a ] = KEY_6, - [ 0x0c ] = KEY_7, - [ 0x0d ] = KEY_8, - [ 0x0e ] = KEY_9, - [ 0x12 ] = KEY_DOT, /* 100+ */ - - [ 0x07 ] = KEY_VOLUMEUP, - [ 0x0b ] = KEY_VOLUMEDOWN, - [ 0x1a ] = KEY_KPPLUS, - [ 0x18 ] = KEY_KPMINUS, - [ 0x15 ] = KEY_UP, - [ 0x1d ] = KEY_DOWN, - [ 0x0f ] = KEY_CHANNELUP, - [ 0x13 ] = KEY_CHANNELDOWN, - [ 0x48 ] = KEY_ZOOM, - - [ 0x1b ] = KEY_VIDEO, /* Video source */ - [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ - [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ - - [ 0x4b ] = KEY_RECORD, - [ 0x46 ] = KEY_PLAY, - [ 0x45 ] = KEY_PAUSE, /* Pause */ - [ 0x44 ] = KEY_STOP, - [ 0x40 ] = KEY_FORWARD, /* Forward ? */ - [ 0x42 ] = KEY_REWIND, /* Backward ? */ - -}; - -EXPORT_SYMBOL_GPL(ir_codes_purpletv); - -/* Mapping for the 28 key remote control as seen at - http://www.sednacomputer.com/photo/cardbus-tv.jpg - Pavel Mihaylov */ -IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = { - [ 0x00 ] = KEY_0, - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - - [ 0x0a ] = KEY_AGAIN, /* Recall */ - [ 0x0b ] = KEY_CHANNELUP, - [ 0x0c ] = KEY_VOLUMEUP, - [ 0x0d ] = KEY_MODE, /* Stereo */ - [ 0x0e ] = KEY_STOP, - [ 0x0f ] = KEY_PREVIOUSSONG, - [ 0x10 ] = KEY_ZOOM, - [ 0x11 ] = KEY_TUNER, /* Source */ - [ 0x12 ] = KEY_POWER, - [ 0x13 ] = KEY_MUTE, - [ 0x15 ] = KEY_CHANNELDOWN, - [ 0x18 ] = KEY_VOLUMEDOWN, - [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */ - [ 0x1a ] = KEY_NEXTSONG, - [ 0x1b ] = KEY_TEXT, /* Time Shift */ - [ 0x1c ] = KEY_RADIO, /* FM Radio */ - [ 0x1d ] = KEY_RECORD, - [ 0x1e ] = KEY_PAUSE, -}; - -EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna); - -/* Mark Phalan */ -IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { - [ 0x00 ] = KEY_0, - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - - [ 0x12 ] = KEY_POWER, - [ 0x10 ] = KEY_MUTE, - [ 0x1f ] = KEY_VOLUMEDOWN, - [ 0x1b ] = KEY_VOLUMEUP, - [ 0x1a ] = KEY_CHANNELUP, - [ 0x1e ] = KEY_CHANNELDOWN, - [ 0x0e ] = KEY_PAGEUP, - [ 0x1d ] = KEY_PAGEDOWN, - [ 0x13 ] = KEY_SOUND, - - [ 0x18 ] = KEY_KPPLUSMINUS, /* CH +/- */ - [ 0x16 ] = KEY_SUBTITLE, /* CC */ - [ 0x0d ] = KEY_TEXT, /* TTX */ - [ 0x0b ] = KEY_TV, /* AIR/CBL */ - [ 0x11 ] = KEY_PC, /* PC/TV */ - [ 0x17 ] = KEY_OK, /* CH RTN */ - [ 0x19 ] = KEY_MODE, /* FUNC */ - [ 0x0c ] = KEY_SEARCH, /* AUTOSCAN */ - - /* Not sure what to do with these ones! */ - [ 0x0f ] = KEY_SELECT, /* SOURCE */ - [ 0x0a ] = KEY_KPPLUS, /* +100 */ - [ 0x14 ] = KEY_EQUAL, /* SYNC */ - [ 0x1c ] = KEY_MEDIA, /* PC/TV */ -}; - -EXPORT_SYMBOL_GPL(ir_codes_pv951); - -/* generic RC5 keytable */ -/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ -/* used by old (black) Hauppauge remotes */ -IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = { - /* Keys 0 to 9 */ - [ 0x00 ] = KEY_0, - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - - [ 0x0b ] = KEY_CHANNEL, /* channel / program (japan: 11) */ - [ 0x0c ] = KEY_POWER, /* standby */ - [ 0x0d ] = KEY_MUTE, /* mute / demute */ - [ 0x0f ] = KEY_TV, /* display */ - [ 0x10 ] = KEY_VOLUMEUP, - [ 0x11 ] = KEY_VOLUMEDOWN, - [ 0x12 ] = KEY_BRIGHTNESSUP, - [ 0x13 ] = KEY_BRIGHTNESSDOWN, - [ 0x1e ] = KEY_SEARCH, /* search + */ - [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ - [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ - [ 0x22 ] = KEY_CHANNEL, /* alt / channel */ - [ 0x23 ] = KEY_LANGUAGE, /* 1st / 2nd language */ - [ 0x26 ] = KEY_SLEEP, /* sleeptimer */ - [ 0x2e ] = KEY_MENU, /* 2nd controls (USA: menu) */ - [ 0x30 ] = KEY_PAUSE, - [ 0x32 ] = KEY_REWIND, - [ 0x33 ] = KEY_GOTO, - [ 0x35 ] = KEY_PLAY, - [ 0x36 ] = KEY_STOP, - [ 0x37 ] = KEY_RECORD, /* recording */ - [ 0x3c ] = KEY_TEXT, /* teletext submode (Japan: 12) */ - [ 0x3d ] = KEY_SUSPEND, /* system standby */ - -}; - -EXPORT_SYMBOL_GPL(ir_codes_rc5_tv); - -/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ -IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { - /* Keys 0 to 9 */ - [ 0x12 ] = KEY_0, - [ 0x05 ] = KEY_1, - [ 0x06 ] = KEY_2, - [ 0x07 ] = KEY_3, - [ 0x09 ] = KEY_4, - [ 0x0a ] = KEY_5, - [ 0x0b ] = KEY_6, - [ 0x0d ] = KEY_7, - [ 0x0e ] = KEY_8, - [ 0x0f ] = KEY_9, - - [ 0x00 ] = KEY_POWER, - [ 0x02 ] = KEY_TUNER, /* TV/FM */ - [ 0x1e ] = KEY_VIDEO, - [ 0x04 ] = KEY_VOLUMEUP, - [ 0x08 ] = KEY_VOLUMEDOWN, - [ 0x0c ] = KEY_CHANNELUP, - [ 0x10 ] = KEY_CHANNELDOWN, - [ 0x03 ] = KEY_ZOOM, /* fullscreen */ - [ 0x1f ] = KEY_SUBTITLE, /* closed caption/teletext */ - [ 0x20 ] = KEY_SLEEP, - [ 0x14 ] = KEY_MUTE, - [ 0x2b ] = KEY_RED, - [ 0x2c ] = KEY_GREEN, - [ 0x2d ] = KEY_YELLOW, - [ 0x2e ] = KEY_BLUE, - [ 0x18 ] = KEY_KPPLUS, /* fine tune + */ - [ 0x19 ] = KEY_KPMINUS, /* fine tune - */ - [ 0x21 ] = KEY_DOT, - [ 0x13 ] = KEY_ENTER, - [ 0x22 ] = KEY_BACK, - [ 0x23 ] = KEY_PLAYPAUSE, - [ 0x24 ] = KEY_NEXT, - [ 0x26 ] = KEY_STOP, - [ 0x27 ] = KEY_RECORD -}; - -EXPORT_SYMBOL_GPL(ir_codes_winfast); - -IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { - [ 0x59 ] = KEY_MUTE, - [ 0x4a ] = KEY_POWER, - - [ 0x18 ] = KEY_TEXT, - [ 0x26 ] = KEY_TV, - [ 0x3d ] = KEY_PRINT, - - [ 0x48 ] = KEY_RED, - [ 0x04 ] = KEY_GREEN, - [ 0x11 ] = KEY_YELLOW, - [ 0x00 ] = KEY_BLUE, - - [ 0x2d ] = KEY_VOLUMEUP, - [ 0x1e ] = KEY_VOLUMEDOWN, - - [ 0x49 ] = KEY_MENU, - - [ 0x16 ] = KEY_CHANNELUP, - [ 0x17 ] = KEY_CHANNELDOWN, - - [ 0x20 ] = KEY_UP, - [ 0x21 ] = KEY_DOWN, - [ 0x22 ] = KEY_LEFT, - [ 0x23 ] = KEY_RIGHT, - [ 0x0d ] = KEY_SELECT, - - - - [ 0x08 ] = KEY_BACK, - [ 0x07 ] = KEY_REFRESH, - - [ 0x2f ] = KEY_ZOOM, - [ 0x29 ] = KEY_RECORD, - - [ 0x4b ] = KEY_PAUSE, - [ 0x4d ] = KEY_REWIND, - [ 0x2e ] = KEY_PLAY, - [ 0x4e ] = KEY_FORWARD, - [ 0x53 ] = KEY_PREVIOUS, - [ 0x4c ] = KEY_STOP, - [ 0x54 ] = KEY_NEXT, - - [ 0x69 ] = KEY_0, - [ 0x6a ] = KEY_1, - [ 0x6b ] = KEY_2, - [ 0x6c ] = KEY_3, - [ 0x6d ] = KEY_4, - [ 0x6e ] = KEY_5, - [ 0x6f ] = KEY_6, - [ 0x70 ] = KEY_7, - [ 0x71 ] = KEY_8, - [ 0x72 ] = KEY_9, - - [ 0x74 ] = KEY_CHANNEL, - [ 0x0a ] = KEY_BACKSPACE, -}; - -EXPORT_SYMBOL_GPL(ir_codes_pinnacle); - -/* Hauppauge: the newer, gray remotes (seems there are multiple - * slightly different versions), shipped with cx88+ivtv cards. - * almost rc5 coding, but some non-standard keys */ -IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { - /* Keys 0 to 9 */ - [ 0x00 ] = KEY_0, - [ 0x01 ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x03 ] = KEY_3, - [ 0x04 ] = KEY_4, - [ 0x05 ] = KEY_5, - [ 0x06 ] = KEY_6, - [ 0x07 ] = KEY_7, - [ 0x08 ] = KEY_8, - [ 0x09 ] = KEY_9, - - [ 0x0a ] = KEY_TEXT, /* keypad asterisk as well */ - [ 0x0b ] = KEY_RED, /* red button */ - [ 0x0c ] = KEY_RADIO, - [ 0x0d ] = KEY_MENU, - [ 0x0e ] = KEY_SUBTITLE, /* also the # key */ - [ 0x0f ] = KEY_MUTE, - [ 0x10 ] = KEY_VOLUMEUP, - [ 0x11 ] = KEY_VOLUMEDOWN, - [ 0x12 ] = KEY_PREVIOUS, /* previous channel */ - [ 0x14 ] = KEY_UP, - [ 0x15 ] = KEY_DOWN, - [ 0x16 ] = KEY_LEFT, - [ 0x17 ] = KEY_RIGHT, - [ 0x18 ] = KEY_VIDEO, /* Videos */ - [ 0x19 ] = KEY_AUDIO, /* Music */ - /* 0x1a: Pictures - presume this means - "Multimedia Home Platform" - - no "PICTURES" key in input.h - */ - [ 0x1a ] = KEY_MHP, - - [ 0x1b ] = KEY_EPG, /* Guide */ - [ 0x1c ] = KEY_TV, - [ 0x1e ] = KEY_NEXTSONG, /* skip >| */ - [ 0x1f ] = KEY_EXIT, /* back/exit */ - [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ - [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ - [ 0x22 ] = KEY_CHANNEL, /* source (old black remote) */ - [ 0x24 ] = KEY_PREVIOUSSONG, /* replay |< */ - [ 0x25 ] = KEY_ENTER, /* OK */ - [ 0x26 ] = KEY_SLEEP, /* minimize (old black remote) */ - [ 0x29 ] = KEY_BLUE, /* blue key */ - [ 0x2e ] = KEY_GREEN, /* green button */ - [ 0x30 ] = KEY_PAUSE, /* pause */ - [ 0x32 ] = KEY_REWIND, /* backward << */ - [ 0x34 ] = KEY_FASTFORWARD, /* forward >> */ - [ 0x35 ] = KEY_PLAY, - [ 0x36 ] = KEY_STOP, - [ 0x37 ] = KEY_RECORD, /* recording */ - [ 0x38 ] = KEY_YELLOW, /* yellow key */ - [ 0x3b ] = KEY_SELECT, /* top right button */ - [ 0x3c ] = KEY_ZOOM, /* full */ - [ 0x3d ] = KEY_POWER, /* system power (green button) */ -}; - -EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); - diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c index 8cdd4d265..04c1938b9 100644 --- a/drivers/media/common/saa7146_core.c +++ b/drivers/media/common/saa7146_core.c @@ -21,7 +21,7 @@ #include LIST_HEAD(saa7146_devices); -DEFINE_MUTEX(saa7146_devices_lock); +DECLARE_MUTEX(saa7146_devices_lock); static int saa7146_num; @@ -116,7 +116,8 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) pg = vmalloc_to_page(virt); if (NULL == pg) goto err; - BUG_ON(PageHighMem(pg)); + if (PageHighMem(pg)) + BUG(); sglist[i].page = pg; sglist[i].length = PAGE_SIZE; } @@ -401,11 +402,11 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent pci_set_drvdata(pci, dev); - mutex_init(&dev->lock); + init_MUTEX(&dev->lock); spin_lock_init(&dev->int_slock); spin_lock_init(&dev->slock); - mutex_init(&dev->i2c_lock); + init_MUTEX(&dev->i2c_lock); dev->module = THIS_MODULE; init_waitqueue_head(&dev->i2c_wq); diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 523ab3851..f8cf73ed4 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -17,18 +17,18 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit) } /* is it free? */ - mutex_lock(&dev->lock); + down(&dev->lock); if (vv->resources & bit) { DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit)); /* no, someone else uses it */ - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } /* it's free, grab it */ fh->resources |= bit; vv->resources |= bit; DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources)); - mutex_unlock(&dev->lock); + up(&dev->lock); return 1; } @@ -37,28 +37,29 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits) struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; - BUG_ON((fh->resources & bits) != bits); + if ((fh->resources & bits) != bits) + BUG(); - mutex_lock(&dev->lock); + down(&dev->lock); fh->resources &= ~bits; vv->resources &= ~bits; DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources)); - mutex_unlock(&dev->lock); + up(&dev->lock); } /********************************************************************************/ /* common dma functions */ -void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q, - struct saa7146_buf *buf) +void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf) { DEB_EE(("dev:%p, buf:%p\n",dev,buf)); - BUG_ON(in_interrupt()); + if (in_interrupt()) + BUG(); videobuf_waiton(&buf->vb,0,0); - videobuf_dma_unmap(q, &buf->vb.dma); + videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma); videobuf_dma_free(&buf->vb.dma); buf->vb.state = STATE_NEEDS_INIT; } @@ -203,7 +204,7 @@ static int fops_open(struct inode *inode, struct file *file) DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor)); - if (mutex_lock_interruptible(&saa7146_devices_lock)) + if (down_interruptible(&saa7146_devices_lock)) return -ERESTARTSYS; list_for_each(list,&saa7146_devices) { @@ -275,7 +276,7 @@ out: kfree(fh); file->private_data = NULL; } - mutex_unlock(&saa7146_devices_lock); + up(&saa7146_devices_lock); return result; } @@ -286,7 +287,7 @@ static int fops_release(struct inode *inode, struct file *file) DEB_EE(("inode:%p, file:%p\n",inode,file)); - if (mutex_lock_interruptible(&saa7146_devices_lock)) + if (down_interruptible(&saa7146_devices_lock)) return -ERESTARTSYS; if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { @@ -302,7 +303,7 @@ static int fops_release(struct inode *inode, struct file *file) file->private_data = NULL; kfree(fh); - mutex_unlock(&saa7146_devices_lock); + up(&saa7146_devices_lock); return 0; } diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index d9953f7a8..8aabdd8fb 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -279,7 +279,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, in int address_err = 0; int short_delay = 0; - if (mutex_lock_interruptible(&dev->i2c_lock)) + if (down_interruptible (&dev->i2c_lock)) return -ERESTARTSYS; for(i=0;ii2c_lock); + up(&dev->i2c_lock); return err; } diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c index 063608462..468d3c959 100644 --- a/drivers/media/common/saa7146_vbi.c +++ b/drivers/media/common/saa7146_vbi.c @@ -236,7 +236,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e } if (buf->vb.size != size) - saa7146_dma_free(dev,q,buf); + saa7146_dma_free(dev,buf); if (STATE_NEEDS_INIT == buf->vb.state) { buf->vb.width = llength; @@ -247,7 +247,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e saa7146_pgtable_free(dev->pci, &buf->pt[2]); saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); - err = videobuf_iolock(q,&buf->vb, NULL); + err = videobuf_iolock(dev->pci,&buf->vb, NULL); if (err) goto oops; err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen); @@ -261,7 +261,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e oops: DEB_VBI(("error out.\n")); - saa7146_dma_free(dev,q,buf); + saa7146_dma_free(dev,buf); return err; } @@ -301,7 +301,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) struct saa7146_buf *buf = (struct saa7146_buf *)vb; DEB_VBI(("vb:%p\n",vb)); - saa7146_dma_free(dev,q,buf); + saa7146_dma_free(dev,buf); } static struct videobuf_queue_ops vbi_qops = { @@ -410,7 +410,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file) V4L2_FIELD_SEQ_TB, // FIXME: does this really work? sizeof(struct saa7146_buf), file); - mutex_init(&fh->vbi_q.lock); + init_MUTEX(&fh->vbi_q.lock); init_timer(&fh->vbi_read_timeout); fh->vbi_read_timeout.function = vbi_read_timeout; diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index e7079d1bd..7ebac7949 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -378,20 +378,20 @@ static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) err = try_win(dev,&f->fmt.win); if (0 != err) return err; - mutex_lock(&dev->lock); + down(&dev->lock); fh->ov.win = f->fmt.win; fh->ov.nclips = f->fmt.win.clipcount; if (fh->ov.nclips > 16) fh->ov.nclips = 16; if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) { - mutex_unlock(&dev->lock); + up(&dev->lock); return -EFAULT; } /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ fh->ov.fh = fh; - mutex_unlock(&dev->lock); + up(&dev->lock); /* check if our current overlay is active */ if (IS_OVERLAY_ACTIVE(fh) != 0) { @@ -516,7 +516,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) return -EINVAL; } - mutex_lock(&dev->lock); + down(&dev->lock); switch (ctrl->type) { case V4L2_CTRL_TYPE_BOOLEAN: @@ -560,7 +560,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) /* fixme: we can support changing VFLIP and HFLIP here... */ if (IS_CAPTURE_ACTIVE(fh) != 0) { DEB_D(("V4L2_CID_HFLIP while active capture.\n")); - mutex_unlock(&dev->lock); + up(&dev->lock); return -EINVAL; } vv->hflip = c->value; @@ -568,7 +568,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) case V4L2_CID_VFLIP: if (IS_CAPTURE_ACTIVE(fh) != 0) { DEB_D(("V4L2_CID_VFLIP while active capture.\n")); - mutex_unlock(&dev->lock); + up(&dev->lock); return -EINVAL; } vv->vflip = c->value; @@ -577,7 +577,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) return -EINVAL; } } - mutex_unlock(&dev->lock); + up(&dev->lock); if (IS_OVERLAY_ACTIVE(fh) != 0) { saa7146_stop_preview(fh); @@ -939,7 +939,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int } } - mutex_lock(&dev->lock); + down(&dev->lock); /* ok, accept it */ vv->ov_fb = *fb; @@ -948,7 +948,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width*fmt->depth/8; - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } @@ -1086,7 +1086,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int } } - mutex_lock(&dev->lock); + down(&dev->lock); for(i = 0; i < dev->ext_vv_data->num_stds; i++) if (*id & dev->ext_vv_data->stds[i].id) @@ -1098,7 +1098,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int found = 1; } - mutex_unlock(&dev->lock); + up(&dev->lock); if (vv->ov_suspend != NULL) { saa7146_start_preview(vv->ov_suspend); @@ -1201,11 +1201,11 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int DEB_D(("VIDIOCGMBUF \n")); q = &fh->video_q; - mutex_lock(&q->lock); + down(&q->lock); err = videobuf_mmap_setup(q,gbuffers,gbufsize, V4L2_MEMORY_MMAP); if (err < 0) { - mutex_unlock(&q->lock); + up(&q->lock); return err; } memset(mbuf,0,sizeof(*mbuf)); @@ -1213,7 +1213,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int mbuf->size = gbuffers * gbufsize; for (i = 0; i < gbuffers; i++) mbuf->offsets[i] = i * gbufsize; - mutex_unlock(&q->lock); + up(&q->lock); return 0; } default: @@ -1275,7 +1275,7 @@ static int buffer_prepare(struct videobuf_queue *q, buf->vb.field != field || buf->vb.field != fh->video_fmt.field || buf->fmt != &fh->video_fmt) { - saa7146_dma_free(dev,q,buf); + saa7146_dma_free(dev,buf); } if (STATE_NEEDS_INIT == buf->vb.state) { @@ -1304,7 +1304,7 @@ static int buffer_prepare(struct videobuf_queue *q, saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); } - err = videobuf_iolock(q,&buf->vb, &vv->ov_fb); + err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb); if (err) goto oops; err = saa7146_pgtable_build(dev,buf); @@ -1318,7 +1318,7 @@ static int buffer_prepare(struct videobuf_queue *q, oops: DEB_D(("error out.\n")); - saa7146_dma_free(dev,q,buf); + saa7146_dma_free(dev,buf); return err; } @@ -1363,7 +1363,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) struct saa7146_buf *buf = (struct saa7146_buf *)vb; DEB_CAP(("vbuf:%p\n",vb)); - saa7146_dma_free(dev,q,buf); + saa7146_dma_free(dev,buf); } static struct videobuf_queue_ops video_qops = { @@ -1414,7 +1414,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file) sizeof(struct saa7146_buf), file); - mutex_init(&fh->video_q.lock); + init_MUTEX(&fh->video_q.lock); return 0; } diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index a97c8f5e9..3f0ec6be0 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -22,26 +22,26 @@ config DVB source "drivers/media/dvb/dvb-core/Kconfig" comment "Supported SAA7146 based PCI Adapters" - depends on DVB_CORE && PCI && I2C + depends on DVB_CORE && PCI source "drivers/media/dvb/ttpci/Kconfig" comment "Supported USB Adapters" - depends on DVB_CORE && USB && I2C + depends on DVB_CORE && USB source "drivers/media/dvb/dvb-usb/Kconfig" source "drivers/media/dvb/ttusb-budget/Kconfig" source "drivers/media/dvb/ttusb-dec/Kconfig" source "drivers/media/dvb/cinergyT2/Kconfig" comment "Supported FlexCopII (B2C2) Adapters" - depends on DVB_CORE && (PCI || USB) && I2C + depends on DVB_CORE && (PCI || USB) source "drivers/media/dvb/b2c2/Kconfig" comment "Supported BT878 Adapters" - depends on DVB_CORE && PCI && I2C + depends on DVB_CORE && PCI source "drivers/media/dvb/bt8xx/Kconfig" comment "Supported Pluto2 Adapters" - depends on DVB_CORE && PCI && I2C + depends on DVB_CORE && PCI source "drivers/media/dvb/pluto2/Kconfig" comment "Supported DVB Frontends" diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig index d7f1fd5b7..2963605c0 100644 --- a/drivers/media/dvb/b2c2/Kconfig +++ b/drivers/media/dvb/b2c2/Kconfig @@ -1,6 +1,6 @@ config DVB_B2C2_FLEXCOP tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters" - depends on DVB_CORE && I2C + depends on DVB_CORE select DVB_STV0299 select DVB_MT352 select DVB_MT312 @@ -16,7 +16,7 @@ config DVB_B2C2_FLEXCOP config DVB_B2C2_FLEXCOP_PCI tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI" - depends on DVB_B2C2_FLEXCOP && PCI && I2C + depends on DVB_B2C2_FLEXCOP && PCI help Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2. @@ -24,7 +24,7 @@ config DVB_B2C2_FLEXCOP_PCI config DVB_B2C2_FLEXCOP_USB tristate "Technisat/B2C2 Air/Sky/Cable2PC USB" - depends on DVB_B2C2_FLEXCOP && USB && I2C + depends on DVB_B2C2_FLEXCOP && USB help Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2, diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index b3dd0603c..7d7e1613c 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h @@ -10,7 +10,6 @@ #include #include -#include #include "flexcop-reg.h" @@ -74,7 +73,8 @@ struct flexcop_device { int (*fe_sleep) (struct dvb_frontend *); struct i2c_adapter i2c_adap; - struct mutex i2c_mutex; + struct semaphore i2c_sem; + struct module *owner; /* options and status */ diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index be4266d4a..56495cb6c 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -172,8 +172,6 @@ static u32 flexcop_i2c_func(struct i2c_adapter *adapter) } static struct i2c_algorithm flexcop_algo = { - .name = "FlexCop I2C algorithm", - .id = I2C_ALGO_BIT, .master_xfer = flexcop_master_xfer, .functionality = flexcop_i2c_func, }; @@ -192,7 +190,6 @@ int flexcop_i2c_init(struct flexcop_device *fc) fc->i2c_adap.class = I2C_CLASS_TV_DIGITAL; fc->i2c_adap.algo = &flexcop_algo; fc->i2c_adap.algo_data = NULL; - fc->i2c_adap.id = I2C_ALGO_BIT; if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0) return ret; diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 06ec9fff0..a6c91db40 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c @@ -541,7 +541,6 @@ static struct usb_device_id flexcop_usb_table [] = { { USB_DEVICE(0x0af7, 0x0101) }, { } }; -MODULE_DEVICE_TABLE (usb, flexcop_usb_table); /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver flexcop_usb_driver = { diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig index f39400211..2337b4171 100644 --- a/drivers/media/dvb/bt8xx/Kconfig +++ b/drivers/media/dvb/bt8xx/Kconfig @@ -1,14 +1,12 @@ config DVB_BT8XX tristate "BT8xx based PCI cards" - depends on DVB_CORE && PCI && I2C && VIDEO_BT848 + depends on DVB_CORE && PCI && VIDEO_BT848 select DVB_MT352 select DVB_SP887X select DVB_NXT6000 select DVB_CX24110 select DVB_OR51211 select DVB_LGDT330X - select DVB_ZL10353 - select FW_LOADER help Support for PCI cards based on the Bt8xx PCI bridge. Examples are the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile index 9d197efb4..d188e4c67 100644 --- a/drivers/media/dvb/bt8xx/Makefile +++ b/drivers/media/dvb/bt8xx/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o -EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video/bt8xx -Idrivers/media/dvb/frontends +EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 5500f8a0f..356f447ee 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c @@ -344,7 +344,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet * int retval; retval = 0; - if (mutex_lock_interruptible(&bt->gpio_lock)) + if (down_interruptible (&bt->gpio_lock)) return -ERESTARTSYS; /* special gpio signal */ switch (cmd) { @@ -375,7 +375,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet * retval = -EINVAL; break; } - mutex_unlock(&bt->gpio_lock); + up(&bt->gpio_lock); return retval; } diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h index f685bc129..9faf93770 100644 --- a/drivers/media/dvb/bt8xx/bt878.h +++ b/drivers/media/dvb/bt8xx/bt878.h @@ -25,8 +25,6 @@ #include #include #include -#include - #include "bt848.h" #include "bttv.h" @@ -110,7 +108,7 @@ struct cards { extern int bt878_num; struct bt878 { - struct mutex gpio_lock; + struct semaphore gpio_lock; unsigned int nr; unsigned int bttv_nr; struct i2c_adapter *adapter; diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 1cfa5e503..0310e3dd0 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -910,7 +910,7 @@ static int dst_get_device_id(struct dst_state *state) static int dst_probe(struct dst_state *state) { - mutex_init(&state->dst_mutex); + sema_init(&state->dst_mutex, 1); if ((rdc_8820_reset(state)) < 0) { dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); return -1; @@ -962,7 +962,7 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) { u8 reply; - mutex_lock(&state->dst_mutex); + down(&state->dst_mutex); if ((dst_comm_init(state)) < 0) { dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); goto error; @@ -1013,11 +1013,11 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) dprintk(verbose, DST_INFO, 1, "checksum failure"); goto error; } - mutex_unlock(&state->dst_mutex); + up(&state->dst_mutex); return 0; error: - mutex_unlock(&state->dst_mutex); + up(&state->dst_mutex); return -EIO; } @@ -1128,7 +1128,7 @@ static int dst_write_tuna(struct dvb_frontend *fe) dst_set_voltage(fe, SEC_VOLTAGE_13); } state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); - mutex_lock(&state->dst_mutex); + down(&state->dst_mutex); if ((dst_comm_init(state)) < 0) { dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); goto error; @@ -1160,11 +1160,11 @@ static int dst_write_tuna(struct dvb_frontend *fe) state->diseq_flags |= ATTEMPT_TUNE; retval = dst_get_tuna(state); werr: - mutex_unlock(&state->dst_mutex); + up(&state->dst_mutex); return retval; error: - mutex_unlock(&state->dst_mutex); + up(&state->dst_mutex); return -EIO; } diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index f6b49a801..c650b4bf7 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c @@ -81,7 +81,7 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 { u8 reply; - mutex_lock(&state->dst_mutex); + down(&state->dst_mutex); dst_comm_init(state); msleep(65); @@ -110,11 +110,11 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 goto error; } } - mutex_unlock(&state->dst_mutex); + up(&state->dst_mutex); return 0; error: - mutex_unlock(&state->dst_mutex); + up(&state->dst_mutex); return -EIO; } diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index 51d4e0437..81557f38f 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h @@ -25,7 +25,6 @@ #include #include #include -#include #include "bt878.h" #include "dst_ca.h" @@ -122,7 +121,7 @@ struct dst_state { u8 vendor[8]; u8 board_info[8]; - struct mutex dst_mutex; + struct semaphore dst_mutex; }; struct dst_types { diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 0bcaa358c..ea27b1500 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -76,13 +76,13 @@ static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed) if (!dvbdmx->dmx.frontend) return -EINVAL; - mutex_lock(&card->lock); + down(&card->lock); card->nfeeds++; rc = card->nfeeds; if (card->nfeeds == 1) bt878_start(card->bt, card->gpio_mode, card->op_sync_orin, card->irq_err_ignore); - mutex_unlock(&card->lock); + up(&card->lock); return rc; } @@ -96,11 +96,11 @@ static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) if (!dvbdmx->dmx.frontend) return -EINVAL; - mutex_lock(&card->lock); + down(&card->lock); card->nfeeds--; if (card->nfeeds == 0) bt878_stop(card->bt); - mutex_unlock(&card->lock); + up(&card->lock); return 0; } @@ -115,7 +115,7 @@ static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev) return 0; } -static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev) +static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev) { unsigned int card_nr; @@ -184,11 +184,6 @@ static struct mt352_config thomson_dtt7579_config = { .pll_set = thomson_dtt7579_pll_set, }; -static struct zl10353_config thomson_dtt7579_zl10353_config = { - .demod_address = 0x0f, - .pll_set = thomson_dtt7579_pll_set, -}; - static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { u32 freq = params->frequency; @@ -244,20 +239,6 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete static int pinnsat_pll_init(struct dvb_frontend* fe) { - struct dvb_bt8xx_card *card = fe->dvb->priv; - - bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */ - bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */ - - return 0; -} - -static int pinnsat_pll_sleep(struct dvb_frontend* fe) -{ - struct dvb_bt8xx_card *card = fe->dvb->priv; - - bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */ - return 0; } @@ -265,7 +246,6 @@ static struct cx24110_config pctvsat_config = { .demod_address = 0x55, .pll_init = pinnsat_pll_init, .pll_set = cx24108_pll_set, - .pll_sleep = pinnsat_pll_sleep, }; static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) @@ -622,11 +602,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) switch(type) { case BTTV_BOARD_DVICO_DVBT_LITE: card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); - - if (card->fe == NULL) - card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config, - card->i2c_adapter); - if (card->fe != NULL) { card->fe->ops->info.frequency_min = 174000000; card->fe->ops->info.frequency_max = 862000000; @@ -719,7 +694,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) } } -static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) +static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) { int result; @@ -804,7 +779,7 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) return 0; } -static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) +static int dvb_bt8xx_probe(struct bttv_sub_device *sub) { struct dvb_bt8xx_card *card; struct pci_dev* bttv_pci_dev; @@ -813,7 +788,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL))) return -ENOMEM; - mutex_init(&card->lock); + init_MUTEX(&card->lock); card->bttv_nr = sub->core->nr; strncpy(card->card_name, sub->core->name, sizeof(sub->core->name)); card->i2c_adapter = &sub->core->i2c_adap; @@ -823,14 +798,14 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) card->gpio_mode = 0x0400c060; /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; + card->op_sync_orin = 0; + card->irq_err_ignore = 0; break; case BTTV_BOARD_DVICO_DVBT_LITE: card->gpio_mode = 0x0400C060; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; + card->op_sync_orin = 0; + card->irq_err_ignore = 0; /* 26, 15, 14, 6, 5 * A_PWRDN DA_DPM DA_SBR DA_IOM_DA * DA_APP(parallel) */ @@ -845,15 +820,15 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) case BTTV_BOARD_NEBULA_DIGITV: case BTTV_BOARD_AVDVBT_761: card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; + card->op_sync_orin = 0; + card->irq_err_ignore = 0; /* A_PWRDN DA_SBR DA_APP (high speed serial) */ break; case BTTV_BOARD_AVDVBT_771: //case 0x07711461: card->gpio_mode = 0x0400402B; card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; + card->irq_err_ignore = 0; /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ break; @@ -877,8 +852,8 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) case BTTV_BOARD_PC_HDTV: card->gpio_mode = 0x0100EC7B; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; + card->op_sync_orin = 0; + card->irq_err_ignore = 0; break; default: @@ -906,7 +881,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) return -EFAULT; } - mutex_init(&card->bt->gpio_lock); + init_MUTEX(&card->bt->gpio_lock); card->bt->bttv_nr = sub->core->nr; if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) { diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index e41066ae7..cf035a803 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h @@ -26,7 +26,6 @@ #define DVB_BT8XX_H #include -#include #include "dvbdev.h" #include "dvb_net.h" #include "bttv.h" @@ -37,10 +36,9 @@ #include "cx24110.h" #include "or51211.h" #include "lgdt330x.h" -#include "zl10353.h" struct dvb_bt8xx_card { - struct mutex lock; + struct semaphore lock; int nfeeds; char card_name[32]; struct dvb_adapter dvb_adapter; diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 9325d039e..c4b4c5b6b 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -30,7 +30,6 @@ #include #include #include -#include #include "dmxdev.h" #include "dvb_demux.h" @@ -117,7 +116,7 @@ static struct dvb_frontend_info cinergyt2_fe_info = { struct cinergyt2 { struct dvb_demux demux; struct usb_device *udev; - struct mutex sem; + struct semaphore sem; struct dvb_adapter adapter; struct dvb_device *fedev; struct dmxdev dmxdev; @@ -346,14 +345,14 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed) struct dvb_demux *demux = dvbdmxfeed->demux; struct cinergyt2 *cinergyt2 = demux->priv; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (cinergyt2->streaming == 0) cinergyt2_start_stream_xfer(cinergyt2); cinergyt2->streaming++; - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); return 0; } @@ -362,13 +361,13 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed) struct dvb_demux *demux = dvbdmxfeed->demux; struct cinergyt2 *cinergyt2 = demux->priv; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (--cinergyt2->streaming == 0) cinergyt2_stop_stream_xfer(cinergyt2); - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); return 0; } @@ -484,11 +483,11 @@ static int cinergyt2_open (struct inode *inode, struct file *file) struct cinergyt2 *cinergyt2 = dvbdev->priv; int err = -ERESTARTSYS; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if ((err = dvb_generic_open(inode, file))) { - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); return err; } @@ -500,15 +499,12 @@ static int cinergyt2_open (struct inode *inode, struct file *file) atomic_inc(&cinergyt2->inuse); - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); return 0; } static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) { - dvb_net_release(&cinergyt2->dvbnet); - dvb_dmxdev_release(&cinergyt2->dmxdev); - dvb_dmx_release(&cinergyt2->demux); dvb_unregister_device(cinergyt2->fedev); dvb_unregister_adapter(&cinergyt2->adapter); @@ -521,7 +517,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; - if (mutex_lock_interruptible(&cinergyt2->sem)) + if (down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { @@ -530,7 +526,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file) cinergyt2_sleep(cinergyt2, 1); } - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { warn("delayed unregister in release"); @@ -545,12 +541,12 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; poll_wait(file, &cinergyt2->poll_wq, wait); - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); return (POLLIN | POLLRDNORM | POLLPRI); } @@ -617,7 +613,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, if (copy_from_user(&p, (void __user*) arg, sizeof(p))) return -EFAULT; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; @@ -633,7 +629,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, (char *) param, sizeof(*param), NULL, 0); - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); return (err < 0) ? err : 0; } @@ -728,7 +724,7 @@ static void cinergyt2_query_rc (void *data) struct cinergyt2_rc_event rc_events[12]; int n, len, i; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return; len = cinergyt2_command(cinergyt2, buf, sizeof(buf), @@ -788,7 +784,7 @@ out: schedule_delayed_work(&cinergyt2->rc_query_work, msecs_to_jiffies(RC_QUERY_INTERVAL)); - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); } static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) @@ -853,7 +849,7 @@ static void cinergyt2_query (void *data) uint8_t lock_bits; uint32_t unc; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return; unc = s->uncorrected_block_count; @@ -872,7 +868,7 @@ static void cinergyt2_query (void *data) schedule_delayed_work(&cinergyt2->query_work, msecs_to_jiffies(QUERY_INTERVAL)); - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); } static int cinergyt2_probe (struct usb_interface *intf, @@ -889,7 +885,7 @@ static int cinergyt2_probe (struct usb_interface *intf, memset (cinergyt2, 0, sizeof (struct cinergyt2)); usb_set_intfdata (intf, (void *) cinergyt2); - mutex_init(&cinergyt2->sem); + init_MUTEX(&cinergyt2->sem); init_waitqueue_head (&cinergyt2->poll_wq); INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2); @@ -902,10 +898,7 @@ static int cinergyt2_probe (struct usb_interface *intf, return -ENOMEM; } - if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE)) < 0) { - kfree(cinergyt2); - return err; - } + dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE); cinergyt2->demux.priv = cinergyt2; cinergyt2->demux.filternum = 256; @@ -944,7 +937,6 @@ static int cinergyt2_probe (struct usb_interface *intf, return 0; bailout: - dvb_net_release(&cinergyt2->dvbnet); dvb_dmxdev_release(&cinergyt2->dmxdev); dvb_dmx_release(&cinergyt2->demux); dvb_unregister_adapter(&cinergyt2->adapter); @@ -975,7 +967,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (state.event > PM_EVENT_ON) { @@ -989,7 +981,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) cinergyt2_sleep(cinergyt2, 1); } - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); return 0; } @@ -998,7 +990,7 @@ static int cinergyt2_resume (struct usb_interface *intf) struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); struct dvbt_set_parameters_msg *param = &cinergyt2->param; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (!cinergyt2->sleeping) { @@ -1011,7 +1003,7 @@ static int cinergyt2_resume (struct usb_interface *intf) cinergyt2_resume_rc(cinergyt2); - mutex_unlock(&cinergyt2->sem); + up(&cinergyt2->sem); return 0; } diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 04578df3f..7b8373ad1 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -1,8 +1,9 @@ /* * dmxdev.c - DVB demultiplexer device * - * Copyright (C) 2000 Ralph Metzler & Marcus Metzler - * for convergence integrated media GmbH + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -31,6 +32,7 @@ #include #include #include + #include "dmxdev.h" static int debug; @@ -40,139 +42,177 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); #define dprintk if (debug) printk -static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf, - const u8 *src, size_t len) +static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer) { - ssize_t free; + buffer->data=NULL; + buffer->size=8192; + buffer->pread=0; + buffer->pwrite=0; + buffer->error=0; + init_waitqueue_head(&buffer->queue); +} + +static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, const u8 *src, int len) +{ + int split; + int free; + int todo; if (!len) return 0; if (!buf->data) return 0; - free = dvb_ringbuffer_free(buf); - if (len > free) { + free=buf->pread-buf->pwrite; + split=0; + if (free<=0) { + free+=buf->size; + split=buf->size-buf->pwrite; + } + if (len>=free) { dprintk("dmxdev: buffer overflow\n"); - return -EOVERFLOW; + return -1; } - - return dvb_ringbuffer_write(buf, src, len); + if (split>=len) + split=0; + todo=len; + if (split) { + memcpy(buf->data + buf->pwrite, src, split); + todo-=split; + buf->pwrite=0; + } + memcpy(buf->data + buf->pwrite, src+split, todo); + buf->pwrite=(buf->pwrite+todo)%buf->size; + return len; } -static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src, - int non_blocking, char __user *buf, - size_t count, loff_t *ppos) +static ssize_t dvb_dmxdev_buffer_read(struct dmxdev_buffer *src, + int non_blocking, char __user *buf, size_t count, loff_t *ppos) { - size_t todo; - ssize_t avail; - ssize_t ret = 0; + unsigned long todo=count; + int split, avail, error; if (!src->data) return 0; - if (src->error) { - ret = src->error; - dvb_ringbuffer_flush(src); - return ret; + if ((error=src->error)) { + src->pwrite=src->pread; + src->error=0; + return error; } - for (todo = count; todo > 0; todo -= ret) { - if (non_blocking && dvb_ringbuffer_empty(src)) { - ret = -EWOULDBLOCK; - break; - } + if (non_blocking && (src->pwrite==src->pread)) + return -EWOULDBLOCK; - ret = wait_event_interruptible(src->queue, - !dvb_ringbuffer_empty(src) || - (src->error != 0)); - if (ret < 0) - break; + while (todo>0) { + if (non_blocking && (src->pwrite==src->pread)) + return (count-todo) ? (count-todo) : -EWOULDBLOCK; - if (src->error) { - ret = src->error; - dvb_ringbuffer_flush(src); - break; - } + if (wait_event_interruptible(src->queue, + (src->pread!=src->pwrite) || + (src->error))<0) + return count-todo; - avail = dvb_ringbuffer_avail(src); - if (avail > todo) - avail = todo; - - ret = dvb_ringbuffer_read(src, buf, avail, 1); - if (ret < 0) - break; + if ((error=src->error)) { + src->pwrite=src->pread; + src->error=0; + return error; + } - buf += ret; + split=src->size; + avail=src->pwrite - src->pread; + if (avail<0) { + avail+=src->size; + split=src->size - src->pread; + } + if (avail>todo) + avail=todo; + if (splitdata+src->pread, split)) + return -EFAULT; + buf+=split; + src->pread=0; + todo-=split; + avail-=split; + } + if (avail) { + if (copy_to_user(buf, src->data+src->pread, avail)) + return -EFAULT; + src->pread = (src->pread + avail) % src->size; + todo-=avail; + buf+=avail; + } } - - return (count - todo) ? (count - todo) : ret; + return count; } -static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type) +static struct dmx_frontend * get_fe(struct dmx_demux *demux, int type) { struct list_head *head, *pos; - head = demux->get_frontends(demux); + head=demux->get_frontends(demux); if (!head) return NULL; list_for_each(pos, head) - if (DMX_FE_ENTRY(pos)->source == type) + if (DMX_FE_ENTRY(pos)->source==type) return DMX_FE_ENTRY(pos); return NULL; } +static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int state) +{ + spin_lock_irq(&dmxdevdvr->dev->lock); + dmxdevdvr->state=state; + spin_unlock_irq(&dmxdevdvr->dev->lock); +} + static int dvb_dvr_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; struct dmx_frontend *front; - dprintk("function : %s\n", __FUNCTION__); + dprintk ("function : %s\n", __FUNCTION__); - if (mutex_lock_interruptible(&dmxdev->mutex)) + if (down_interruptible (&dmxdev->mutex)) return -ERESTARTSYS; - if ((file->f_flags & O_ACCMODE) == O_RDWR) { - if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { - mutex_unlock(&dmxdev->mutex); + if ((file->f_flags&O_ACCMODE)==O_RDWR) { + if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) { + up(&dmxdev->mutex); return -EOPNOTSUPP; } } - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - void *mem; - if (!dvbdev->readers) { - mutex_unlock(&dmxdev->mutex); - return -EBUSY; - } - mem = vmalloc(DVR_BUFFER_SIZE); - if (!mem) { - mutex_unlock(&dmxdev->mutex); - return -ENOMEM; - } - dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE); - dvbdev->readers--; + if ((file->f_flags&O_ACCMODE)==O_RDONLY) { + dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); + dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE; + dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE); + if (!dmxdev->dvr_buffer.data) { + up(&dmxdev->mutex); + return -ENOMEM; + } } - if ((file->f_flags & O_ACCMODE) == O_WRONLY) { - dmxdev->dvr_orig_fe = dmxdev->demux->frontend; + if ((file->f_flags&O_ACCMODE)==O_WRONLY) { + dmxdev->dvr_orig_fe=dmxdev->demux->frontend; if (!dmxdev->demux->write) { - mutex_unlock(&dmxdev->mutex); + up(&dmxdev->mutex); return -EOPNOTSUPP; } - front = get_fe(dmxdev->demux, DMX_MEMORY_FE); + front=get_fe(dmxdev->demux, DMX_MEMORY_FE); if (!front) { - mutex_unlock(&dmxdev->mutex); + up(&dmxdev->mutex); return -EINVAL; } dmxdev->demux->disconnect_frontend(dmxdev->demux); dmxdev->demux->connect_frontend(dmxdev->demux, front); } - mutex_unlock(&dmxdev->mutex); + up(&dmxdev->mutex); return 0; } @@ -181,31 +221,30 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; - if (mutex_lock_interruptible(&dmxdev->mutex)) + if (down_interruptible (&dmxdev->mutex)) return -ERESTARTSYS; - if ((file->f_flags & O_ACCMODE) == O_WRONLY) { + if ((file->f_flags&O_ACCMODE)==O_WRONLY) { dmxdev->demux->disconnect_frontend(dmxdev->demux); dmxdev->demux->connect_frontend(dmxdev->demux, dmxdev->dvr_orig_fe); } - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - dvbdev->readers++; + if ((file->f_flags&O_ACCMODE)==O_RDONLY) { if (dmxdev->dvr_buffer.data) { - void *mem = dmxdev->dvr_buffer.data; + void *mem=dmxdev->dvr_buffer.data; mb(); spin_lock_irq(&dmxdev->lock); - dmxdev->dvr_buffer.data = NULL; + dmxdev->dvr_buffer.data=NULL; spin_unlock_irq(&dmxdev->lock); vfree(mem); } } - mutex_unlock(&dmxdev->mutex); + up(&dmxdev->mutex); return 0; } static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; @@ -213,62 +252,60 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, if (!dmxdev->demux->write) return -EOPNOTSUPP; - if ((file->f_flags & O_ACCMODE) != O_WRONLY) + if ((file->f_flags&O_ACCMODE)!=O_WRONLY) return -EINVAL; - if (mutex_lock_interruptible(&dmxdev->mutex)) + if (down_interruptible (&dmxdev->mutex)) return -ERESTARTSYS; - ret = dmxdev->demux->write(dmxdev->demux, buf, count); - mutex_unlock(&dmxdev->mutex); + ret=dmxdev->demux->write(dmxdev->demux, buf, count); + up(&dmxdev->mutex); return ret; } static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) + loff_t *ppos) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; int ret; - //mutex_lock(&dmxdev->mutex); - ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, - file->f_flags & O_NONBLOCK, - buf, count, ppos); - //mutex_unlock(&dmxdev->mutex); + //down(&dmxdev->mutex); + ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, + file->f_flags&O_NONBLOCK, + buf, count, ppos); + //up(&dmxdev->mutex); return ret; } -static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter - *dmxdevfilter, int state) +static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter *dmxdevfilter, int state) { spin_lock_irq(&dmxdevfilter->dev->lock); - dmxdevfilter->state = state; + dmxdevfilter->state=state; spin_unlock_irq(&dmxdevfilter->dev->lock); } -static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, - unsigned long size) +static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsigned long size) { - struct dvb_ringbuffer *buf = &dmxdevfilter->buffer; + struct dmxdev_buffer *buf=&dmxdevfilter->buffer; void *mem; - if (buf->size == size) + if (buf->size==size) return 0; - if (dmxdevfilter->state >= DMXDEV_STATE_GO) + if (dmxdevfilter->state>=DMXDEV_STATE_GO) return -EBUSY; spin_lock_irq(&dmxdevfilter->dev->lock); - mem = buf->data; - buf->data = NULL; - buf->size = size; - dvb_ringbuffer_flush(buf); + mem=buf->data; + buf->data=NULL; + buf->size=size; + buf->pwrite=buf->pread=0; spin_unlock_irq(&dmxdevfilter->dev->lock); vfree(mem); if (buf->size) { - mem = vmalloc(dmxdevfilter->buffer.size); + mem=vmalloc(dmxdevfilter->buffer.size); if (!mem) return -ENOMEM; spin_lock_irq(&dmxdevfilter->dev->lock); - buf->data = mem; + buf->data=mem; spin_unlock_irq(&dmxdevfilter->dev->lock); } return 0; @@ -276,33 +313,31 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, static void dvb_dmxdev_filter_timeout(unsigned long data) { - struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data; + struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *)data; - dmxdevfilter->buffer.error = -ETIMEDOUT; + dmxdevfilter->buffer.error=-ETIMEDOUT; spin_lock_irq(&dmxdevfilter->dev->lock); - dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT; + dmxdevfilter->state=DMXDEV_STATE_TIMEDOUT; spin_unlock_irq(&dmxdevfilter->dev->lock); wake_up(&dmxdevfilter->buffer.queue); } static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter) { - struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec; + struct dmx_sct_filter_params *para=&dmxdevfilter->params.sec; del_timer(&dmxdevfilter->timer); if (para->timeout) { - dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout; - dmxdevfilter->timer.data = (unsigned long)dmxdevfilter; - dmxdevfilter->timer.expires = - jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000; + dmxdevfilter->timer.function=dvb_dmxdev_filter_timeout; + dmxdevfilter->timer.data=(unsigned long) dmxdevfilter; + dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000; add_timer(&dmxdevfilter->timer); } } static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, - struct dmx_section_filter *filter, - enum dmx_success success) + const u8 *buffer2, size_t buffer2_len, + struct dmx_section_filter *filter, enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = filter->priv; int ret; @@ -312,68 +347,68 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, return 0; } spin_lock(&dmxdevfilter->dev->lock); - if (dmxdevfilter->state != DMXDEV_STATE_GO) { + if (dmxdevfilter->state!=DMXDEV_STATE_GO) { spin_unlock(&dmxdevfilter->dev->lock); return 0; } del_timer(&dmxdevfilter->timer); dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n", buffer1[0], buffer1[1], - buffer1[2], buffer1[3], buffer1[4], buffer1[5]); - ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, - buffer1_len); - if (ret == buffer1_len) { - ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, - buffer2_len); + buffer1[2], buffer1[3], + buffer1[4], buffer1[5]); + ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len); + if (ret==buffer1_len) { + ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, buffer2_len); } - if (ret < 0) { - dvb_ringbuffer_flush(&dmxdevfilter->buffer); - dmxdevfilter->buffer.error = ret; + if (ret<0) { + dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread; + dmxdevfilter->buffer.error=-EOVERFLOW; } - if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) - dmxdevfilter->state = DMXDEV_STATE_DONE; + if (dmxdevfilter->params.sec.flags&DMX_ONESHOT) + dmxdevfilter->state=DMXDEV_STATE_DONE; spin_unlock(&dmxdevfilter->dev->lock); wake_up(&dmxdevfilter->buffer.queue); return 0; } static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, - struct dmx_ts_feed *feed, - enum dmx_success success) + const u8 *buffer2, size_t buffer2_len, + struct dmx_ts_feed *feed, enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = feed->priv; - struct dvb_ringbuffer *buffer; + struct dmxdev_buffer *buffer; int ret; spin_lock(&dmxdevfilter->dev->lock); - if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { + if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER) { spin_unlock(&dmxdevfilter->dev->lock); return 0; } - if (dmxdevfilter->params.pes.output == DMX_OUT_TAP) - buffer = &dmxdevfilter->buffer; + if (dmxdevfilter->params.pes.output==DMX_OUT_TAP) + buffer=&dmxdevfilter->buffer; else - buffer = &dmxdevfilter->dev->dvr_buffer; + buffer=&dmxdevfilter->dev->dvr_buffer; if (buffer->error) { spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } - ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); - if (ret == buffer1_len) - ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); - if (ret < 0) { - dvb_ringbuffer_flush(buffer); - buffer->error = ret; + ret=dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); + if (ret==buffer1_len) + ret=dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); + if (ret<0) { + buffer->pwrite=buffer->pread; + buffer->error=-EOVERFLOW; } spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } + /* stop feed but only mark the specified filter as stopped (state set) */ + static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) { dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); @@ -392,16 +427,20 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) return 0; } + /* start feed associated with the specified filter */ + static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) { - dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO); + dvb_dmxdev_filter_state_set (filter, DMXDEV_STATE_GO); switch (filter->type) { case DMXDEV_TYPE_SEC: return filter->feed.sec->start_filtering(filter->feed.sec); + break; case DMXDEV_TYPE_PES: return filter->feed.ts->start_filtering(filter->feed.ts); + break; default: return -EINVAL; } @@ -409,31 +448,32 @@ static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) return 0; } + /* restart section feed if it has filters left associated with it, otherwise release the feed */ + static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter) { int i; struct dmxdev *dmxdev = filter->dev; u16 pid = filter->params.sec.pid; - for (i = 0; i < dmxdev->filternum; i++) - if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && - dmxdev->filter[i].type == DMXDEV_TYPE_SEC && - dmxdev->filter[i].params.sec.pid == pid) { + for (i=0; ifilternum; i++) + if (dmxdev->filter[i].state>=DMXDEV_STATE_GO && + dmxdev->filter[i].type==DMXDEV_TYPE_SEC && + dmxdev->filter[i].pid==pid) { dvb_dmxdev_feed_start(&dmxdev->filter[i]); return 0; } - filter->dev->demux->release_section_feed(dmxdev->demux, - filter->feed.sec); + filter->dev->demux->release_section_feed(dmxdev->demux, filter->feed.sec); return 0; } static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) { - if (dmxdevfilter->state < DMXDEV_STATE_GO) + if (dmxdevfilter->statetype) { @@ -443,36 +483,36 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) dvb_dmxdev_feed_stop(dmxdevfilter); if (dmxdevfilter->filter.sec) dmxdevfilter->feed.sec-> - release_filter(dmxdevfilter->feed.sec, - dmxdevfilter->filter.sec); + release_filter(dmxdevfilter->feed.sec, + dmxdevfilter->filter.sec); dvb_dmxdev_feed_restart(dmxdevfilter); - dmxdevfilter->feed.sec = NULL; + dmxdevfilter->feed.sec=NULL; break; case DMXDEV_TYPE_PES: if (!dmxdevfilter->feed.ts) break; dvb_dmxdev_feed_stop(dmxdevfilter); dmxdevfilter->dev->demux-> - release_ts_feed(dmxdevfilter->dev->demux, - dmxdevfilter->feed.ts); - dmxdevfilter->feed.ts = NULL; + release_ts_feed(dmxdevfilter->dev->demux, + dmxdevfilter->feed.ts); + dmxdevfilter->feed.ts=NULL; break; default: - if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED) + if (dmxdevfilter->state==DMXDEV_STATE_ALLOCATED) return 0; return -EINVAL; } - - dvb_ringbuffer_flush(&dmxdevfilter->buffer); + dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0; return 0; } static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter) { - if (dmxdevfilter->state < DMXDEV_STATE_SET) + if (dmxdevfilter->statetype = DMXDEV_TYPE_NONE; + dmxdevfilter->type=DMXDEV_TYPE_NONE; + dmxdevfilter->pid=0xffff; dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); return 0; } @@ -489,33 +529,32 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) if (filter->state >= DMXDEV_STATE_GO) dvb_dmxdev_filter_stop(filter); - if (!filter->buffer.data) { + if (!(mem = filter->buffer.data)) { mem = vmalloc(filter->buffer.size); - if (!mem) - return -ENOMEM; spin_lock_irq(&filter->dev->lock); - filter->buffer.data = mem; + filter->buffer.data=mem; spin_unlock_irq(&filter->dev->lock); + if (!filter->buffer.data) + return -ENOMEM; } - dvb_ringbuffer_flush(&filter->buffer); + filter->buffer.pwrite = filter->buffer.pread = 0; switch (filter->type) { case DMXDEV_TYPE_SEC: { - struct dmx_sct_filter_params *para = &filter->params.sec; - struct dmx_section_filter **secfilter = &filter->filter.sec; - struct dmx_section_feed **secfeed = &filter->feed.sec; - - *secfilter = NULL; - *secfeed = NULL; + struct dmx_sct_filter_params *para=&filter->params.sec; + struct dmx_section_filter **secfilter=&filter->filter.sec; + struct dmx_section_feed **secfeed=&filter->feed.sec; + *secfilter=NULL; + *secfeed=NULL; /* find active filter/feed with same PID */ - for (i = 0; i < dmxdev->filternum; i++) { + for (i=0; ifilternum; i++) { if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && - dmxdev->filter[i].type == DMXDEV_TYPE_SEC && - dmxdev->filter[i].params.sec.pid == para->pid) { + dmxdev->filter[i].pid == para->pid && + dmxdev->filter[i].type == DMXDEV_TYPE_SEC) { *secfeed = dmxdev->filter[i].feed.sec; break; } @@ -523,20 +562,21 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) /* if no feed found, try to allocate new one */ if (!*secfeed) { - ret = dmxdev->demux->allocate_section_feed(dmxdev->demux, - secfeed, - dvb_dmxdev_section_callback); - if (ret < 0) { - printk("DVB (%s): could not alloc feed\n", - __FUNCTION__); + ret=dmxdev->demux->allocate_section_feed(dmxdev->demux, + secfeed, + dvb_dmxdev_section_callback); + if (ret<0) { + printk ("DVB (%s): could not alloc feed\n", + __FUNCTION__); return ret; } - ret = (*secfeed)->set(*secfeed, para->pid, 32768, - (para->flags & DMX_CHECK_CRC) ? 1 : 0); - if (ret < 0) { - printk("DVB (%s): could not set feed\n", - __FUNCTION__); + ret=(*secfeed)->set(*secfeed, para->pid, 32768, + (para->flags & DMX_CHECK_CRC) ? 1 : 0); + + if (ret<0) { + printk ("DVB (%s): could not set feed\n", + __FUNCTION__); dvb_dmxdev_feed_restart(filter); return ret; } @@ -544,38 +584,41 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) dvb_dmxdev_feed_stop(filter); } - ret = (*secfeed)->allocate_filter(*secfeed, secfilter); + ret=(*secfeed)->allocate_filter(*secfeed, secfilter); + if (ret < 0) { dvb_dmxdev_feed_restart(filter); filter->feed.sec->start_filtering(*secfeed); - dprintk("could not get filter\n"); + dprintk ("could not get filter\n"); return ret; } (*secfilter)->priv = filter; memcpy(&((*secfilter)->filter_value[3]), - &(para->filter.filter[1]), DMX_FILTER_SIZE - 1); + &(para->filter.filter[1]), DMX_FILTER_SIZE-1); memcpy(&(*secfilter)->filter_mask[3], - ¶->filter.mask[1], DMX_FILTER_SIZE - 1); + ¶->filter.mask[1], DMX_FILTER_SIZE-1); memcpy(&(*secfilter)->filter_mode[3], - ¶->filter.mode[1], DMX_FILTER_SIZE - 1); + ¶->filter.mode[1], DMX_FILTER_SIZE-1); - (*secfilter)->filter_value[0] = para->filter.filter[0]; - (*secfilter)->filter_mask[0] = para->filter.mask[0]; - (*secfilter)->filter_mode[0] = para->filter.mode[0]; - (*secfilter)->filter_mask[1] = 0; - (*secfilter)->filter_mask[2] = 0; + (*secfilter)->filter_value[0]=para->filter.filter[0]; + (*secfilter)->filter_mask[0]=para->filter.mask[0]; + (*secfilter)->filter_mode[0]=para->filter.mode[0]; + (*secfilter)->filter_mask[1]=0; + (*secfilter)->filter_mask[2]=0; filter->todo = 0; - ret = filter->feed.sec->start_filtering(filter->feed.sec); + ret = filter->feed.sec->start_filtering (filter->feed.sec); + if (ret < 0) return ret; dvb_dmxdev_filter_timer(filter); break; } + case DMXDEV_TYPE_PES: { struct timespec timeout = { 0 }; @@ -587,41 +630,41 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) struct dmx_ts_feed **tsfeed = &filter->feed.ts; filter->feed.ts = NULL; - otype = para->output; + otype=para->output; - ts_pes = (enum dmx_ts_pes)para->pes_type; + ts_pes=(enum dmx_ts_pes) para->pes_type; - if (ts_pes < DMX_PES_OTHER) - ts_type = TS_DECODER; + if (ts_pesdemux->allocate_ts_feed(dmxdev->demux, - tsfeed, - dvb_dmxdev_ts_callback); - if (ret < 0) + ret=dmxdev->demux->allocate_ts_feed(dmxdev->demux, + tsfeed, + dvb_dmxdev_ts_callback); + if (ret<0) return ret; - (*tsfeed)->priv = filter; + (*tsfeed)->priv = (void *) filter; ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes, 32768, timeout); + if (ret < 0) { - dmxdev->demux->release_ts_feed(dmxdev->demux, - *tsfeed); + dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed); return ret; } ret = filter->feed.ts->start_filtering(filter->feed.ts); + if (ret < 0) { - dmxdev->demux->release_ts_feed(dmxdev->demux, - *tsfeed); + dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed); return ret; } @@ -645,40 +688,41 @@ static int dvb_demux_open(struct inode *inode, struct file *file) if (!dmxdev->filter) return -EINVAL; - if (mutex_lock_interruptible(&dmxdev->mutex)) + if (down_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; - for (i = 0; i < dmxdev->filternum; i++) - if (dmxdev->filter[i].state == DMXDEV_STATE_FREE) + for (i=0; ifilternum; i++) + if (dmxdev->filter[i].state==DMXDEV_STATE_FREE) break; - if (i == dmxdev->filternum) { - mutex_unlock(&dmxdev->mutex); + if (i==dmxdev->filternum) { + up(&dmxdev->mutex); return -EMFILE; } - dmxdevfilter = &dmxdev->filter[i]; - mutex_init(&dmxdevfilter->mutex); - file->private_data = dmxdevfilter; + dmxdevfilter=&dmxdev->filter[i]; + sema_init(&dmxdevfilter->mutex, 1); + dmxdevfilter->dvbdev=dmxdev->dvbdev; + file->private_data=dmxdevfilter; - dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); - dmxdevfilter->type = DMXDEV_TYPE_NONE; + dvb_dmxdev_buffer_init(&dmxdevfilter->buffer); + dmxdevfilter->type=DMXDEV_TYPE_NONE; dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); - dmxdevfilter->feed.ts = NULL; + dmxdevfilter->feed.ts=NULL; init_timer(&dmxdevfilter->timer); - mutex_unlock(&dmxdev->mutex); + up(&dmxdev->mutex); return 0; } -static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, - struct dmxdev_filter *dmxdevfilter) + +static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter) { - if (mutex_lock_interruptible(&dmxdev->mutex)) + if (down_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); + if (down_interruptible(&dmxdevfilter->mutex)) { + up(&dmxdev->mutex); return -ERESTARTSYS; } @@ -686,18 +730,18 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, dvb_dmxdev_filter_reset(dmxdevfilter); if (dmxdevfilter->buffer.data) { - void *mem = dmxdevfilter->buffer.data; + void *mem=dmxdevfilter->buffer.data; spin_lock_irq(&dmxdev->lock); - dmxdevfilter->buffer.data = NULL; + dmxdevfilter->buffer.data=NULL; spin_unlock_irq(&dmxdev->lock); vfree(mem); } dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE); wake_up(&dmxdevfilter->buffer.queue); - mutex_unlock(&dmxdevfilter->mutex); - mutex_unlock(&dmxdev->mutex); + up(&dmxdevfilter->mutex); + up(&dmxdev->mutex); return 0; } @@ -705,171 +749,173 @@ static inline void invert_mode(dmx_filter_t *filter) { int i; - for (i = 0; i < DMX_FILTER_SIZE; i++) - filter->mode[i] ^= 0xff; + for (i=0; imode[i]^=0xff; } + static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, - struct dmxdev_filter *dmxdevfilter, - struct dmx_sct_filter_params *params) + struct dmxdev_filter *dmxdevfilter, + struct dmx_sct_filter_params *params) { - dprintk("function : %s\n", __FUNCTION__); + dprintk ("function : %s\n", __FUNCTION__); dvb_dmxdev_filter_stop(dmxdevfilter); - dmxdevfilter->type = DMXDEV_TYPE_SEC; + dmxdevfilter->type=DMXDEV_TYPE_SEC; + dmxdevfilter->pid=params->pid; memcpy(&dmxdevfilter->params.sec, params, sizeof(struct dmx_sct_filter_params)); invert_mode(&dmxdevfilter->params.sec.filter); dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); - if (params->flags & DMX_IMMEDIATE_START) + if (params->flags&DMX_IMMEDIATE_START) return dvb_dmxdev_filter_start(dmxdevfilter); return 0; } static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev, - struct dmxdev_filter *dmxdevfilter, - struct dmx_pes_filter_params *params) + struct dmxdev_filter *dmxdevfilter, + struct dmx_pes_filter_params *params) { dvb_dmxdev_filter_stop(dmxdevfilter); - if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0) + if (params->pes_type>DMX_PES_OTHER || params->pes_type<0) return -EINVAL; - dmxdevfilter->type = DMXDEV_TYPE_PES; - memcpy(&dmxdevfilter->params, params, - sizeof(struct dmx_pes_filter_params)); + dmxdevfilter->type=DMXDEV_TYPE_PES; + dmxdevfilter->pid=params->pid; + memcpy(&dmxdevfilter->params, params, sizeof(struct dmx_pes_filter_params)); dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); - if (params->flags & DMX_IMMEDIATE_START) + if (params->flags&DMX_IMMEDIATE_START) return dvb_dmxdev_filter_start(dmxdevfilter); return 0; } static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil, - struct file *file, char __user *buf, - size_t count, loff_t *ppos) + struct file *file, char __user *buf, size_t count, loff_t *ppos) { int result, hcount; - int done = 0; - - if (dfil->todo <= 0) { - hcount = 3 + dfil->todo; - if (hcount > count) - hcount = count; - result = dvb_dmxdev_buffer_read(&dfil->buffer, - file->f_flags & O_NONBLOCK, - buf, hcount, ppos); - if (result < 0) { - dfil->todo = 0; + int done=0; + + if (dfil->todo<=0) { + hcount=3+dfil->todo; + if (hcount>count) + hcount=count; + result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK, + buf, hcount, ppos); + if (result<0) { + dfil->todo=0; return result; } - if (copy_from_user(dfil->secheader - dfil->todo, buf, result)) + if (copy_from_user(dfil->secheader-dfil->todo, buf, result)) return -EFAULT; - buf += result; - done = result; - count -= result; - dfil->todo -= result; - if (dfil->todo > -3) + buf+=result; + done=result; + count-=result; + dfil->todo-=result; + if (dfil->todo>-3) return done; - dfil->todo = ((dfil->secheader[1] << 8) | dfil->secheader[2]) & 0xfff; + dfil->todo=((dfil->secheader[1]<<8)|dfil->secheader[2])&0xfff; if (!count) return done; } - if (count > dfil->todo) - count = dfil->todo; - result = dvb_dmxdev_buffer_read(&dfil->buffer, - file->f_flags & O_NONBLOCK, - buf, count, ppos); - if (result < 0) + if (count>dfil->todo) + count=dfil->todo; + result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK, + buf, count, ppos); + if (result<0) return result; - dfil->todo -= result; - return (result + done); + dfil->todo-=result; + return (result+done); } + static ssize_t -dvb_demux_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) +dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct dmxdev_filter *dmxdevfilter = file->private_data; - int ret; + struct dmxdev_filter *dmxdevfilter= file->private_data; + int ret=0; - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) + if (down_interruptible(&dmxdevfilter->mutex)) return -ERESTARTSYS; - if (dmxdevfilter->type == DMXDEV_TYPE_SEC) - ret = dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos); + if (dmxdevfilter->type==DMXDEV_TYPE_SEC) + ret=dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos); else - ret = dvb_dmxdev_buffer_read(&dmxdevfilter->buffer, - file->f_flags & O_NONBLOCK, - buf, count, ppos); + ret=dvb_dmxdev_buffer_read(&dmxdevfilter->buffer, + file->f_flags&O_NONBLOCK, + buf, count, ppos); - mutex_unlock(&dmxdevfilter->mutex); + up(&dmxdevfilter->mutex); return ret; } + static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { struct dmxdev_filter *dmxdevfilter = file->private_data; - struct dmxdev *dmxdev = dmxdevfilter->dev; - unsigned long arg = (unsigned long)parg; - int ret = 0; + struct dmxdev *dmxdev=dmxdevfilter->dev; + unsigned long arg=(unsigned long) parg; + int ret=0; - if (mutex_lock_interruptible(&dmxdev->mutex)) + if (down_interruptible (&dmxdev->mutex)) return -ERESTARTSYS; switch (cmd) { case DMX_START: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); + if (down_interruptible(&dmxdevfilter->mutex)) { + up(&dmxdev->mutex); return -ERESTARTSYS; } - if (dmxdevfilter->state < DMXDEV_STATE_SET) + if (dmxdevfilter->statemutex); + up(&dmxdevfilter->mutex); break; case DMX_STOP: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); + if (down_interruptible(&dmxdevfilter->mutex)) { + up(&dmxdev->mutex); return -ERESTARTSYS; } - ret = dvb_dmxdev_filter_stop(dmxdevfilter); - mutex_unlock(&dmxdevfilter->mutex); + ret=dvb_dmxdev_filter_stop(dmxdevfilter); + up(&dmxdevfilter->mutex); break; case DMX_SET_FILTER: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); + if (down_interruptible(&dmxdevfilter->mutex)) { + up(&dmxdev->mutex); return -ERESTARTSYS; } - ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg); - mutex_unlock(&dmxdevfilter->mutex); + ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, + (struct dmx_sct_filter_params *)parg); + up(&dmxdevfilter->mutex); break; case DMX_SET_PES_FILTER: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); + if (down_interruptible(&dmxdevfilter->mutex)) { + up(&dmxdev->mutex); return -ERESTARTSYS; } - ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg); - mutex_unlock(&dmxdevfilter->mutex); + ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, + (struct dmx_pes_filter_params *)parg); + up(&dmxdevfilter->mutex); break; case DMX_SET_BUFFER_SIZE: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); + if (down_interruptible(&dmxdevfilter->mutex)) { + up(&dmxdev->mutex); return -ERESTARTSYS; } - ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg); - mutex_unlock(&dmxdevfilter->mutex); + ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg); + up(&dmxdevfilter->mutex); break; case DMX_GET_EVENT: @@ -877,10 +923,10 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, case DMX_GET_PES_PIDS: if (!dmxdev->demux->get_pes_pids) { - ret = -EINVAL; + ret=-EINVAL; break; } - dmxdev->demux->get_pes_pids(dmxdev->demux, parg); + dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg); break; case DMX_GET_CAPS: @@ -901,20 +947,19 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, case DMX_GET_STC: if (!dmxdev->demux->get_stc) { - ret = -EINVAL; + ret=-EINVAL; break; } ret = dmxdev->demux->get_stc(dmxdev->demux, - ((struct dmx_stc *)parg)->num, - &((struct dmx_stc *)parg)->stc, - &((struct dmx_stc *)parg)->base); + ((struct dmx_stc *)parg)->num, + &((struct dmx_stc *)parg)->stc, + &((struct dmx_stc *)parg)->base); break; default: - ret = -EINVAL; - break; + ret=-EINVAL; } - mutex_unlock(&dmxdev->mutex); + up(&dmxdev->mutex); return ret; } @@ -924,7 +969,8 @@ static int dvb_demux_ioctl(struct inode *inode, struct file *file, return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl); } -static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) + +static unsigned int dvb_demux_poll (struct file *file, poll_table *wait) { struct dmxdev_filter *dmxdevfilter = file->private_data; unsigned int mask = 0; @@ -942,12 +988,13 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) if (dmxdevfilter->buffer.error) mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); - if (!dvb_ringbuffer_empty(&dmxdevfilter->buffer)) + if (dmxdevfilter->buffer.pread != dmxdevfilter->buffer.pwrite) mask |= (POLLIN | POLLRDNORM | POLLPRI); return mask; } + static int dvb_demux_release(struct inode *inode, struct file *file) { struct dmxdev_filter *dmxdevfilter = file->private_data; @@ -956,67 +1003,72 @@ static int dvb_demux_release(struct inode *inode, struct file *file) return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); } + static struct file_operations dvb_demux_fops = { - .owner = THIS_MODULE, - .read = dvb_demux_read, - .ioctl = dvb_demux_ioctl, - .open = dvb_demux_open, - .release = dvb_demux_release, - .poll = dvb_demux_poll, + .owner = THIS_MODULE, + .read = dvb_demux_read, + .ioctl = dvb_demux_ioctl, + .open = dvb_demux_open, + .release = dvb_demux_release, + .poll = dvb_demux_poll, }; + static struct dvb_device dvbdev_demux = { - .priv = NULL, - .users = 1, - .writers = 1, - .fops = &dvb_demux_fops + .priv = NULL, + .users = 1, + .writers = 1, + .fops = &dvb_demux_fops }; + static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) + unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; - int ret; - if (mutex_lock_interruptible(&dmxdev->mutex)) + int ret=0; + + if (down_interruptible (&dmxdev->mutex)) return -ERESTARTSYS; switch (cmd) { case DMX_SET_BUFFER_SIZE: // FIXME: implement - ret = 0; + ret=0; break; default: - ret = -EINVAL; - break; + ret=-EINVAL; } - mutex_unlock(&dmxdev->mutex); + up(&dmxdev->mutex); return ret; } + static int dvb_dvr_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl); } -static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) + +static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; unsigned int mask = 0; - dprintk("function : %s\n", __FUNCTION__); + dprintk ("function : %s\n", __FUNCTION__); poll_wait(file, &dmxdev->dvr_buffer.queue, wait); - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if ((file->f_flags&O_ACCMODE) == O_RDONLY) { if (dmxdev->dvr_buffer.error) mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); - if (!dvb_ringbuffer_empty(&dmxdev->dvr_buffer)) + if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite) mask |= (POLLIN | POLLRDNORM | POLLPRI); } else mask |= (POLLOUT | POLLWRNORM | POLLPRI); @@ -1024,62 +1076,73 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) return mask; } + static struct file_operations dvb_dvr_fops = { - .owner = THIS_MODULE, - .read = dvb_dvr_read, - .write = dvb_dvr_write, - .ioctl = dvb_dvr_ioctl, - .open = dvb_dvr_open, - .release = dvb_dvr_release, - .poll = dvb_dvr_poll, + .owner = THIS_MODULE, + .read = dvb_dvr_read, + .write = dvb_dvr_write, + .ioctl = dvb_dvr_ioctl, + .open = dvb_dvr_open, + .release = dvb_dvr_release, + .poll = dvb_dvr_poll, }; static struct dvb_device dvbdev_dvr = { - .priv = NULL, - .readers = 1, - .fops = &dvb_dvr_fops + .priv = NULL, + .users = 1, + .writers = 1, + .fops = &dvb_dvr_fops }; -int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) +int +dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) { int i; if (dmxdev->demux->open(dmxdev->demux) < 0) return -EUSERS; - dmxdev->filter = vmalloc(dmxdev->filternum * sizeof(struct dmxdev_filter)); + dmxdev->filter = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_filter)); if (!dmxdev->filter) return -ENOMEM; - mutex_init(&dmxdev->mutex); + dmxdev->dvr = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_dvr)); + if (!dmxdev->dvr) { + vfree(dmxdev->filter); + dmxdev->filter = NULL; + return -ENOMEM; + } + + sema_init(&dmxdev->mutex, 1); spin_lock_init(&dmxdev->lock); - for (i = 0; i < dmxdev->filternum; i++) { - dmxdev->filter[i].dev = dmxdev; - dmxdev->filter[i].buffer.data = NULL; - dvb_dmxdev_filter_state_set(&dmxdev->filter[i], - DMXDEV_STATE_FREE); + for (i=0; ifilternum; i++) { + dmxdev->filter[i].dev=dmxdev; + dmxdev->filter[i].buffer.data=NULL; + dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE); + dmxdev->dvr[i].dev=dmxdev; + dmxdev->dvr[i].buffer.data=NULL; + dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE); } - dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, - DVB_DEVICE_DEMUX); - dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, - dmxdev, DVB_DEVICE_DVR); + dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX); + dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR); - dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); + dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); return 0; } - EXPORT_SYMBOL(dvb_dmxdev_init); -void dvb_dmxdev_release(struct dmxdev *dmxdev) +void +dvb_dmxdev_release(struct dmxdev *dmxdev) { dvb_unregister_device(dmxdev->dvbdev); dvb_unregister_device(dmxdev->dvr_dvbdev); vfree(dmxdev->filter); - dmxdev->filter = NULL; + dmxdev->filter=NULL; + vfree(dmxdev->dvr); + dmxdev->dvr=NULL; dmxdev->demux->close(dmxdev->demux); } - EXPORT_SYMBOL(dvb_dmxdev_release); diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h index d2bee9ffe..fd72920c2 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.h +++ b/drivers/media/dvb/dvb-core/dmxdev.h @@ -30,15 +30,14 @@ #include #include #include -#include +#include #include #include "dvbdev.h" #include "demux.h" -#include "dvb_ringbuffer.h" -enum dmxdev_type { +enum dmxdevype { DMXDEV_TYPE_NONE, DMXDEV_TYPE_SEC, DMXDEV_TYPE_PES, @@ -53,7 +52,18 @@ enum dmxdev_state { DMXDEV_STATE_TIMEDOUT }; +struct dmxdev_buffer { + u8 *data; + int size; + int pread; + int pwrite; + wait_queue_head_t queue; + int error; +}; + struct dmxdev_filter { + struct dvb_device *dvbdev; + union { struct dmx_section_filter *sec; } filter; @@ -68,17 +78,26 @@ struct dmxdev_filter { struct dmx_pes_filter_params pes; } params; - enum dmxdev_type type; + int type; enum dmxdev_state state; struct dmxdev *dev; - struct dvb_ringbuffer buffer; + struct dmxdev_buffer buffer; - struct mutex mutex; + struct semaphore mutex; /* only for sections */ struct timer_list timer; int todo; u8 secheader[3]; + + u16 pid; +}; + + +struct dmxdev_dvr { + int state; + struct dmxdev *dev; + struct dmxdev_buffer buffer; }; @@ -87,6 +106,7 @@ struct dmxdev { struct dvb_device *dvr_dvbdev; struct dmxdev_filter *filter; + struct dmxdev_dvr *dvr; struct dmx_demux *demux; int filternum; @@ -94,10 +114,10 @@ struct dmxdev { #define DMXDEV_CAP_DUPLEX 1 struct dmx_frontend *dvr_orig_fe; - struct dvb_ringbuffer dvr_buffer; + struct dmxdev_buffer dvr_buffer; #define DVR_BUFFER_SIZE (10*188*1024) - struct mutex mutex; + struct semaphore mutex; spinlock_t lock; }; diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index 83ec5e06c..b4c899b15 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -589,18 +589,18 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, if (pid > DMX_MAX_PID) return -EINVAL; - if (mutex_lock_interruptible(&demux->mutex)) + if (down_interruptible(&demux->mutex)) return -ERESTARTSYS; if (ts_type & TS_DECODER) { if (pes_type >= DMX_TS_PES_OTHER) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -EINVAL; } if (demux->pesfilter[pes_type] && demux->pesfilter[pes_type] != feed) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -EINVAL; } @@ -622,14 +622,14 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, #else feed->buffer = vmalloc(feed->buffer_size); if (!feed->buffer) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -ENOMEM; } #endif } feed->state = DMX_STATE_READY; - mutex_unlock(&demux->mutex); + up(&demux->mutex); return 0; } @@ -640,21 +640,21 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed) struct dvb_demux *demux = feed->demux; int ret; - if (mutex_lock_interruptible(&demux->mutex)) + if (down_interruptible(&demux->mutex)) return -ERESTARTSYS; if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -EINVAL; } if (!demux->start_feed) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -ENODEV; } if ((ret = demux->start_feed(feed)) < 0) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return ret; } @@ -662,7 +662,7 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed) ts_feed->is_filtering = 1; feed->state = DMX_STATE_GO; spin_unlock_irq(&demux->lock); - mutex_unlock(&demux->mutex); + up(&demux->mutex); return 0; } @@ -673,16 +673,16 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) struct dvb_demux *demux = feed->demux; int ret; - if (mutex_lock_interruptible(&demux->mutex)) + if (down_interruptible(&demux->mutex)) return -ERESTARTSYS; if (feed->state < DMX_STATE_GO) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -EINVAL; } if (!demux->stop_feed) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -ENODEV; } @@ -692,7 +692,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) ts_feed->is_filtering = 0; feed->state = DMX_STATE_ALLOCATED; spin_unlock_irq(&demux->lock); - mutex_unlock(&demux->mutex); + up(&demux->mutex); return ret; } @@ -704,11 +704,11 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, struct dvb_demux *demux = (struct dvb_demux *)dmx; struct dvb_demux_feed *feed; - if (mutex_lock_interruptible(&demux->mutex)) + if (down_interruptible(&demux->mutex)) return -ERESTARTSYS; if (!(feed = dvb_dmx_feed_alloc(demux))) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -EBUSY; } @@ -729,7 +729,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, if (!(feed->filter = dvb_dmx_filter_alloc(demux))) { feed->state = DMX_STATE_FREE; - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -EBUSY; } @@ -737,7 +737,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, feed->filter->feed = feed; feed->filter->state = DMX_STATE_READY; - mutex_unlock(&demux->mutex); + up(&demux->mutex); return 0; } @@ -748,11 +748,11 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dvb_demux *demux = (struct dvb_demux *)dmx; struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; - if (mutex_lock_interruptible(&demux->mutex)) + if (down_interruptible(&demux->mutex)) return -ERESTARTSYS; if (feed->state == DMX_STATE_FREE) { - mutex_unlock(&demux->mutex); + up(&demux->mutex); return -EINVAL; } #ifndef NOBUFS @@ -770,7 +770,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER) demux->pesfilter[feed->pes_type] = NULL; - mutex_unlock(&demux->mutex); + up(&demux->mutex); return 0; } @@ -785,12 +785,12 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed, struct dvb_demux *dvbdemux = dvbdmxfeed->demux; struct dvb_demux_filter *dvbdmxfilter; - if (mutex_lock_interruptible(&dvbdemux->mutex)) + if (down_interruptible(&dvbdemux->mutex)) return -ERESTARTSYS; dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux); if (!dvbdmxfilter) { - mutex_unlock(&dvbdemux->mutex); + up(&dvbdemux->mutex); return -EBUSY; } @@ -805,7 +805,7 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed, dvbdmxfeed->filter = dvbdmxfilter; spin_unlock_irq(&dvbdemux->lock); - mutex_unlock(&dvbdemux->mutex); + up(&dvbdemux->mutex); return 0; } @@ -819,7 +819,7 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed, if (pid > 0x1fff) return -EINVAL; - if (mutex_lock_interruptible(&dvbdmx->mutex)) + if (down_interruptible(&dvbdmx->mutex)) return -ERESTARTSYS; dvb_demux_feed_add(dvbdmxfeed); @@ -833,13 +833,13 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed, #else dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size); if (!dvbdmxfeed->buffer) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return -ENOMEM; } #endif dvbdmxfeed->state = DMX_STATE_READY; - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return 0; } @@ -871,16 +871,16 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) struct dvb_demux *dvbdmx = dvbdmxfeed->demux; int ret; - if (mutex_lock_interruptible(&dvbdmx->mutex)) + if (down_interruptible(&dvbdmx->mutex)) return -ERESTARTSYS; if (feed->is_filtering) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return -EBUSY; } if (!dvbdmxfeed->filter) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return -EINVAL; } @@ -890,14 +890,14 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) dvbdmxfeed->feed.sec.seclen = 0; if (!dvbdmx->start_feed) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return -ENODEV; } prepare_secfilters(dvbdmxfeed); if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return ret; } @@ -906,7 +906,7 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) dvbdmxfeed->state = DMX_STATE_GO; spin_unlock_irq(&dvbdmx->lock); - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return 0; } @@ -916,11 +916,11 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) struct dvb_demux *dvbdmx = dvbdmxfeed->demux; int ret; - if (mutex_lock_interruptible(&dvbdmx->mutex)) + if (down_interruptible(&dvbdmx->mutex)) return -ERESTARTSYS; if (!dvbdmx->stop_feed) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return -ENODEV; } @@ -931,7 +931,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) feed->is_filtering = 0; spin_unlock_irq(&dvbdmx->lock); - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return ret; } @@ -942,11 +942,11 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - if (mutex_lock_interruptible(&dvbdmx->mutex)) + if (down_interruptible(&dvbdmx->mutex)) return -ERESTARTSYS; if (dvbdmxfilter->feed != dvbdmxfeed) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return -EINVAL; } @@ -966,7 +966,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, dvbdmxfilter->state = DMX_STATE_FREE; spin_unlock_irq(&dvbdmx->lock); - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return 0; } @@ -977,11 +977,11 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; struct dvb_demux_feed *dvbdmxfeed; - if (mutex_lock_interruptible(&dvbdmx->mutex)) + if (down_interruptible(&dvbdmx->mutex)) return -ERESTARTSYS; if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return -EBUSY; } @@ -1006,7 +1006,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, (*feed)->stop_filtering = dmx_section_feed_stop_filtering; (*feed)->release_filter = dmx_section_feed_release_filter; - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return 0; } @@ -1016,11 +1016,11 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; - if (mutex_lock_interruptible(&dvbdmx->mutex)) + if (down_interruptible(&dvbdmx->mutex)) return -ERESTARTSYS; if (dvbdmxfeed->state == DMX_STATE_FREE) { - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return -EINVAL; } #ifndef NOBUFS @@ -1033,7 +1033,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, dvbdmxfeed->pid = 0xffff; - mutex_unlock(&dvbdmx->mutex); + up(&dvbdmx->mutex); return 0; } @@ -1071,10 +1071,10 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) return -EINVAL; - if (mutex_lock_interruptible(&dvbdemux->mutex)) + if (down_interruptible(&dvbdemux->mutex)) return -ERESTARTSYS; dvb_dmx_swfilter(dvbdemux, buf, count); - mutex_unlock(&dvbdemux->mutex); + up(&dvbdemux->mutex); if (signal_pending(current)) return -EINTR; @@ -1126,11 +1126,11 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, if (demux->frontend) return -EINVAL; - if (mutex_lock_interruptible(&dvbdemux->mutex)) + if (down_interruptible(&dvbdemux->mutex)) return -ERESTARTSYS; demux->frontend = frontend; - mutex_unlock(&dvbdemux->mutex); + up(&dvbdemux->mutex); return 0; } @@ -1138,11 +1138,11 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) { struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - if (mutex_lock_interruptible(&dvbdemux->mutex)) + if (down_interruptible(&dvbdemux->mutex)) return -ERESTARTSYS; demux->frontend = NULL; - mutex_unlock(&dvbdemux->mutex); + up(&dvbdemux->mutex); return 0; } @@ -1215,7 +1215,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) dmx->disconnect_frontend = dvbdmx_disconnect_frontend; dmx->get_pes_pids = dvbdmx_get_pes_pids; - mutex_init(&dvbdemux->mutex); + sema_init(&dvbdemux->mutex, 1); spin_lock_init(&dvbdemux->lock); return 0; diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h index 2c5f91532..0cc888339 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/drivers/media/dvb/dvb-core/dvb_demux.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "demux.h" @@ -125,7 +125,7 @@ struct dvb_demux { u8 tsbuf[204]; int tsbufp; - struct mutex mutex; + struct semaphore mutex; spinlock_t lock; }; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index cb69372fe..771f32d88 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "dvbdev.h" @@ -49,13 +50,13 @@ static int dvb_powerdown_on_sleep = 1; module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); -module_param(dvb_shutdown_timeout, int, 0644); +module_param(dvb_shutdown_timeout, int, 0444); MODULE_PARM_DESC(dvb_shutdown_timeout, "wait seconds after close() before suspending hardware"); -module_param(dvb_force_auto_inversion, int, 0644); +module_param(dvb_force_auto_inversion, int, 0444); MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always"); -module_param(dvb_override_tune_delay, int, 0644); +module_param(dvb_override_tune_delay, int, 0444); MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); -module_param(dvb_powerdown_on_sleep, int, 0644); +module_param(dvb_powerdown_on_sleep, int, 0444); MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); #define dprintk if (dvb_frontend_debug) printk @@ -87,7 +88,7 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB vola * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again. */ -static DEFINE_MUTEX(frontend_mutex); +static DECLARE_MUTEX(frontend_mutex); struct dvb_frontend_private { @@ -105,9 +106,6 @@ struct dvb_frontend_private { fe_status_t status; unsigned long tune_mode_flags; unsigned int delay; - unsigned int reinitialise; - int tone; - int voltage; /* swzigzag values */ unsigned int state; @@ -124,7 +122,6 @@ struct dvb_frontend_private { unsigned int check_wrapped; }; -static void dvb_frontend_wakeup(struct dvb_frontend *fe); static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) { @@ -217,15 +214,6 @@ static void dvb_frontend_init(struct dvb_frontend *fe) fe->ops->init(fe); } -void dvb_frontend_reinitialise(struct dvb_frontend *fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - fepriv->reinitialise = 1; - dvb_frontend_wakeup(fe); -} -EXPORT_SYMBOL(dvb_frontend_reinitialise); - static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) { int q2; @@ -518,10 +506,8 @@ static int dvb_frontend_thread(void *data) fepriv->quality = 0; fepriv->delay = 3*HZ; fepriv->status = 0; - fepriv->wakeup = 0; - fepriv->reinitialise = 0; - dvb_frontend_init(fe); + fepriv->wakeup = 0; while (1) { up(&fepriv->sem); /* is locked when we enter the thread... */ @@ -539,17 +525,6 @@ static int dvb_frontend_thread(void *data) if (down_interruptible(&fepriv->sem)) break; - if (fepriv->reinitialise) { - dvb_frontend_init(fe); - if (fepriv->tone != -1) { - fe->ops->set_tone(fe, fepriv->tone); - } - if (fepriv->voltage != -1) { - fe->ops->set_voltage(fe, fepriv->voltage); - } - fepriv->reinitialise = 0; - } - /* do an iteration of the tuning loop */ if (fe->ops->tune) { /* have we been asked to retune? */ @@ -798,7 +773,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_SET_TONE: if (fe->ops->set_tone) { err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); - fepriv->tone = (fe_sec_tone_mode_t) parg; fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } @@ -807,7 +781,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_SET_VOLTAGE: if (fe->ops->set_voltage) { err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg); - fepriv->voltage = (fe_sec_voltage_t) parg; fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } @@ -998,17 +971,15 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) return ret; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - /* normal tune mode when opened R/W */ - fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; - fepriv->tone = -1; - fepriv->voltage = -1; - ret = dvb_frontend_start (fe); if (ret) dvb_generic_release (inode, file); /* empty event queue */ fepriv->events.eventr = fepriv->events.eventw = 0; + + /* normal tune mode when opened R/W */ + fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; } return ret; @@ -1050,12 +1021,12 @@ int dvb_register_frontend(struct dvb_adapter* dvb, dprintk ("%s\n", __FUNCTION__); - if (mutex_lock_interruptible(&frontend_mutex)) + if (down_interruptible (&frontend_mutex)) return -ERESTARTSYS; fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL); if (fe->frontend_priv == NULL) { - mutex_unlock(&frontend_mutex); + up(&frontend_mutex); return -ENOMEM; } fepriv = fe->frontend_priv; @@ -1074,7 +1045,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, fe, DVB_DEVICE_FRONTEND); - mutex_unlock(&frontend_mutex); + up (&frontend_mutex); return 0; } EXPORT_SYMBOL(dvb_register_frontend); @@ -1084,7 +1055,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) struct dvb_frontend_private *fepriv = fe->frontend_priv; dprintk ("%s\n", __FUNCTION__); - mutex_lock(&frontend_mutex); + down (&frontend_mutex); dvb_unregister_device (fepriv->dvbdev); dvb_frontend_stop (fe); if (fe->ops->release) @@ -1093,7 +1064,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name); /* fe is invalid now */ kfree(fepriv); - mutex_unlock(&frontend_mutex); + up (&frontend_mutex); return 0; } EXPORT_SYMBOL(dvb_unregister_frontend); diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 5926a3b74..70a6d14ef 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -104,7 +104,6 @@ struct dvb_frontend { struct dvb_adapter *dvb; void* demodulator_priv; void* frontend_priv; - void* misc_priv; }; extern int dvb_register_frontend(struct dvb_adapter* dvb, @@ -112,8 +111,6 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb, extern int dvb_unregister_frontend(struct dvb_frontend* fe); -extern void dvb_frontend_reinitialise(struct dvb_frontend *fe); - extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 9fd87521a..bdc491452 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -62,7 +62,6 @@ #include #include #include -#include #include "dvb_demux.h" #include "dvb_net.h" @@ -152,7 +151,8 @@ struct dvb_net_priv { unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */ int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */ unsigned long ts_count; /* Current ts cell counter. */ - struct mutex mutex; + + struct semaphore mutex; }; @@ -492,7 +492,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) } else priv->ule_dbit = 0; - if (priv->ule_sndu_len > 32763) { + if (priv->ule_sndu_len > 32763 || + priv->ule_sndu_len < ((priv->ule_dbit) ? 4 : 4 + ETH_ALEN)) { printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); priv->ule_sndu_len = 0; @@ -889,7 +890,7 @@ static int dvb_net_feed_start(struct net_device *dev) unsigned char *mac = (unsigned char *) dev->dev_addr; dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode); - mutex_lock(&priv->mutex); + down(&priv->mutex); if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0]) printk("%s: BUG %d\n", __FUNCTION__, __LINE__); @@ -974,7 +975,7 @@ static int dvb_net_feed_start(struct net_device *dev) ret = -EINVAL; error: - mutex_unlock(&priv->mutex); + up(&priv->mutex); return ret; } @@ -984,7 +985,7 @@ static int dvb_net_feed_stop(struct net_device *dev) int i, ret = 0; dprintk("%s\n", __FUNCTION__); - mutex_lock(&priv->mutex); + down(&priv->mutex); if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) { if (priv->secfeed) { if (priv->secfeed->is_filtering) { @@ -1026,7 +1027,7 @@ static int dvb_net_feed_stop(struct net_device *dev) printk("%s: no ts feed to stop\n", dev->name); } else ret = -EINVAL; - mutex_unlock(&priv->mutex); + up(&priv->mutex); return ret; } @@ -1052,7 +1053,7 @@ static void wq_set_multicast_list (void *data) dvb_net_feed_stop(dev); priv->rx_mode = RX_MODE_UNI; - netif_tx_lock_bh(dev); + spin_lock_bh(&dev->xmit_lock); if (dev->flags & IFF_PROMISC) { dprintk("%s: promiscuous mode\n", dev->name); @@ -1077,7 +1078,7 @@ static void wq_set_multicast_list (void *data) } } - netif_tx_unlock_bh(dev); + spin_unlock_bh(&dev->xmit_lock); dvb_net_feed_start(dev); } @@ -1208,7 +1209,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net); INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net); - mutex_init(&priv->mutex); + init_MUTEX(&priv->mutex); net->base_addr = pid; diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index c972fe014..77ad2410f 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c @@ -45,7 +45,6 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len) rbuf->pread=rbuf->pwrite=0; rbuf->data=data; rbuf->size=len; - rbuf->error=0; init_waitqueue_head(&rbuf->queue); @@ -88,7 +87,6 @@ ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf) void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) { rbuf->pread = rbuf->pwrite; - rbuf->error = 0; } diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index d97714e75..6d2560972 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h @@ -35,7 +35,6 @@ struct dvb_ringbuffer { ssize_t size; ssize_t pread; ssize_t pwrite; - int error; wait_queue_head_t queue; spinlock_t lock; diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 3852430d0..54f8b9571 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -86,7 +86,7 @@ static int dvb_device_open(struct inode *inode, struct file *file) if (dvbdev && dvbdev->fops) { int err = 0; - const struct file_operations *old_fops; + struct file_operations *old_fops; file->private_data = dvbdev; old_fops = file->f_op; @@ -219,6 +219,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENOMEM; } + mutex_unlock(&dvbdev_register_lock); + memcpy(dvbdev, template, sizeof(struct dvb_device)); dvbdev->type = type; dvbdev->id = id; @@ -229,8 +231,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, list_add_tail (&dvbdev->list_head, &adap->device_list); - mutex_unlock(&dvbdev_register_lock); - devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), S_IFCHR | S_IRUSR | S_IWUSR, "dvb/adapter%d/%s%d", adap->num, dnames[type], id); diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index e388fb156..d3df12039 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -1,6 +1,6 @@ config DVB_USB tristate "Support for various USB DVB devices" - depends on DVB_CORE && USB && I2C + depends on DVB_CORE && USB select FW_LOADER help By enabling this you will be able to choose the various supported diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 1f0d3e995..356a09a69 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -77,23 +77,22 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) struct dvb_usb_device *d = i2c_get_adapdata(adap); int i; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + if (down_interruptible(&d->i2c_sem) < 0) return -EAGAIN; if (num > 2) - warn("more than two i2c messages at a time is not handled yet. TODO."); + warn("more than 2 i2c messages at a time is not handled yet. TODO."); for (i = 0; i < num; i++) { - if (d->udev->descriptor.idVendor == USB_VID_MEDION) - switch (msg[i].addr) { - case 0x63: - cxusb_gpio_tuner(d,0); - break; - default: - cxusb_gpio_tuner(d,1); - break; - } + switch (msg[i].addr) { + case 0x63: + cxusb_gpio_tuner(d,0); + break; + default: + cxusb_gpio_tuner(d,1); + break; + } /* read request */ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { @@ -109,7 +108,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) break; if (ibuf[0] != 0x08) - deb_i2c("i2c read may have failed\n"); + deb_info("i2c read could have been failed\n"); memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len); @@ -123,11 +122,11 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0) break; if (ibuf != 0x08) - deb_i2c("i2c write may have failed\n"); + deb_info("i2c write could have been failed\n"); } } - mutex_unlock(&d->i2c_mutex); + up(&d->i2c_sem); return i; } @@ -242,45 +241,6 @@ static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { { 0xfe, 0x4e, KEY_POWER }, }; -static struct dvb_usb_rc_key dvico_portable_rc_keys[] = { - { 0xfc, 0x02, KEY_SETUP }, /* Profile */ - { 0xfc, 0x43, KEY_POWER2 }, - { 0xfc, 0x06, KEY_EPG }, - { 0xfc, 0x5a, KEY_BACK }, - { 0xfc, 0x05, KEY_MENU }, - { 0xfc, 0x47, KEY_INFO }, - { 0xfc, 0x01, KEY_TAB }, - { 0xfc, 0x42, KEY_PREVIOUSSONG },/* Replay */ - { 0xfc, 0x49, KEY_VOLUMEUP }, - { 0xfc, 0x09, KEY_VOLUMEDOWN }, - { 0xfc, 0x54, KEY_CHANNELUP }, - { 0xfc, 0x0b, KEY_CHANNELDOWN }, - { 0xfc, 0x16, KEY_CAMERA }, - { 0xfc, 0x40, KEY_TUNER }, /* ATV/DTV */ - { 0xfc, 0x45, KEY_OPEN }, - { 0xfc, 0x19, KEY_1 }, - { 0xfc, 0x18, KEY_2 }, - { 0xfc, 0x1b, KEY_3 }, - { 0xfc, 0x1a, KEY_4 }, - { 0xfc, 0x58, KEY_5 }, - { 0xfc, 0x59, KEY_6 }, - { 0xfc, 0x15, KEY_7 }, - { 0xfc, 0x14, KEY_8 }, - { 0xfc, 0x17, KEY_9 }, - { 0xfc, 0x44, KEY_ANGLE }, /* Aspect */ - { 0xfc, 0x55, KEY_0 }, - { 0xfc, 0x07, KEY_ZOOM }, - { 0xfc, 0x0a, KEY_REWIND }, - { 0xfc, 0x08, KEY_PLAYPAUSE }, - { 0xfc, 0x4b, KEY_FASTFORWARD }, - { 0xfc, 0x5b, KEY_MUTE }, - { 0xfc, 0x04, KEY_STOP }, - { 0xfc, 0x56, KEY_RECORD }, - { 0xfc, 0x57, KEY_POWER }, - { 0xfc, 0x41, KEY_UNKNOWN }, /* INPUT */ - { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */ -}; - static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) { static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; @@ -459,6 +419,7 @@ static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) && fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) { + /* FIXME: are we allowed to change the fw-data ? */ fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1; fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8; @@ -559,11 +520,6 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { .i2c_algo = &cxusb_i2c_algo, - .rc_interval = 100, - .rc_key_map = dvico_portable_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), - .rc_query = cxusb_rc_query, - .generic_bulk_ctrl_endpoint = 0x01, /* parameter for the MPEG2-data transfer */ .urb = { @@ -653,11 +609,6 @@ static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = { .i2c_algo = &cxusb_i2c_algo, - .rc_interval = 100, - .rc_key_map = dvico_portable_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), - .rc_query = cxusb_rc_query, - .generic_bulk_ctrl_endpoint = 0x01, /* parameter for the MPEG2-data transfer */ .urb = { @@ -698,11 +649,6 @@ static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties = { .i2c_algo = &cxusb_i2c_algo, - .rc_interval = 100, - .rc_key_map = dvico_portable_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), - .rc_query = cxusb_rc_query, - .generic_bulk_ctrl_endpoint = 0x01, /* parameter for the MPEG2-data transfer */ .urb = { diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h index c8ef77554..087c99427 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.h +++ b/drivers/media/dvb/dvb-usb/cxusb.h @@ -6,8 +6,6 @@ extern int dvb_usb_cxusb_debug; #define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) -#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \ - dprintk(dvb_usb_cxusb_debug,0x01,args) /* usb commands - some of it are guesses, don't have a reference yet */ #define CMD_I2C_WRITE 0x08 diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 2d52b7667..269d899da 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -128,7 +128,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num struct dvb_usb_device *d = i2c_get_adapdata(adap); int i; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + if (down_interruptible(&d->i2c_sem) < 0) return -EAGAIN; if (num > 2) @@ -146,7 +146,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num break; } - mutex_unlock(&d->i2c_mutex); + up(&d->i2c_sem); return i; } diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 91136c00c..caa1346e3 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -48,7 +48,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num struct dvb_usb_device *d = i2c_get_adapdata(adap); int i; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + if (down_interruptible(&d->i2c_sem) < 0) return -EAGAIN; if (num > 2) @@ -67,7 +67,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num break; } - mutex_unlock(&d->i2c_mutex); + up(&d->i2c_sem); return i; } diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 70afcfd14..12ebaf8bd 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -94,14 +94,12 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d) static struct dvb_usb_properties dtt200u_properties; static struct dvb_usb_properties wt220u_properties; -static struct dvb_usb_properties wt220u_zl0353_properties; static int dtt200u_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0) + dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0) return 0; return -ENODEV; @@ -112,8 +110,6 @@ static struct usb_device_id dtt200u_usb_table [] = { { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) }, { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) }, { 0 }, }; MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); @@ -200,47 +196,6 @@ static struct dvb_usb_properties wt220u_properties = { } }; -static struct dvb_usb_properties wt220u_zl0353_properties = { - .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, - .pid_filter_count = 15, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-wt220u-zl0353-01.fw", - - .power_ctrl = dtt200u_power_ctrl, - .streaming_ctrl = dtt200u_streaming_ctrl, - .pid_filter = dtt200u_pid_filter, - .frontend_attach = dtt200u_frontend_attach, - - .rc_interval = 300, - .rc_key_map = dtt200u_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), - .rc_query = dtt200u_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - - /* parameter for the MPEG2-data transfer */ - .urb = { - .type = DVB_USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - - .num_device_descs = 1, - .devices = { - { .name = "WideView WT-220U PenType Receiver (based on ZL353)", - .cold_ids = { &dtt200u_usb_table[4], NULL }, - .warm_ids = { &dtt200u_usb_table[5], NULL }, - }, - { NULL }, - } -}; - /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver dtt200u_usb_driver = { .name = "dvb_usb_dtt200u", diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index cb239049b..4a1b9e77e 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -83,8 +83,6 @@ #define USB_PID_DTT200U_WARM 0x0301 #define USB_PID_WT220U_COLD 0x0222 #define USB_PID_WT220U_WARM 0x0221 -#define USB_PID_WT220U_ZL0353_COLD 0x022a -#define USB_PID_WT220U_ZL0353_WARM 0x022b #define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 #define USB_PID_NEBULA_DIGITV 0x0201 diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index a1705ecb9..ce34a55e5 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -42,8 +42,8 @@ static int dvb_usb_init(struct dvb_usb_device *d) { int ret = 0; - mutex_init(&d->usb_mutex); - mutex_init(&d->i2c_mutex); + sema_init(&d->usb_sem, 1); + sema_init(&d->i2c_sem, 1); d->state = DVB_USB_STATE_INIT; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index 9002f35aa..ee821974d 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c @@ -21,7 +21,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, if (wbuf == NULL || wlen == 0) return -EINVAL; - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) + if ((ret = down_interruptible(&d->usb_sem))) return ret; deb_xfer(">>> "); @@ -53,7 +53,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, } } - mutex_unlock(&d->usb_mutex); + up(&d->usb_sem); return ret; } EXPORT_SYMBOL(dvb_usb_generic_rw); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index fead958a5..d4909e5c6 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -12,7 +12,6 @@ #include #include #include -#include #include "dvb_frontend.h" #include "dvb_demux.h" @@ -228,8 +227,8 @@ struct dvb_usb_properties { * @feedcount: number of reqested feeds (used for streaming-activation) * @pid_filtering: is hardware pid_filtering used or not. * - * @usb_mutex: semaphore of USB control messages (reading needs two messages) - * @i2c_mutex: semaphore for i2c-transfers + * @usb_sem: semaphore of USB control messages (reading needs two messages) + * @i2c_sem: semaphore for i2c-transfers * * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB * @pll_addr: I2C address of the tuner for programming @@ -284,10 +283,10 @@ struct dvb_usb_device { int pid_filtering; /* locking */ - struct mutex usb_mutex; + struct semaphore usb_sem; /* i2c */ - struct mutex i2c_mutex; + struct semaphore i2c_sem; struct i2c_adapter i2c_adap; /* tuner programming information */ diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c index 2a89f8c5d..b6d95e1c9 100644 --- a/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c @@ -147,9 +147,8 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe, cmd[4] = (sr >> 4) & 0xff; cmd[5] = (sr << 4) & 0xf0; - deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %lu (%lx)\n", - fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, - (unsigned long) sr, (unsigned long) sr); + deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %Lu (%Lx)\n", + fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, sr, sr); /* if (fep->inversion == INVERSION_ON) cmd[6] |= 0x80; */ diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c index b2f098a2d..4a95eca81 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ b/drivers/media/dvb/dvb-usb/vp702x.c @@ -75,7 +75,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il { int ret; - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) + if ((ret = down_interruptible(&d->usb_sem))) return ret; if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0) @@ -84,7 +84,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen); unlock: - mutex_unlock(&d->usb_mutex); + up(&d->usb_sem); return ret; } diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 8ea3834a6..3835235b6 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -38,7 +38,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, deb_xfer("out buffer: "); debug_dump(outbuf,outlen+1,deb_xfer); - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) + if ((ret = down_interruptible(&d->usb_sem))) return ret; if (usb_control_msg(d->udev, @@ -68,7 +68,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, memcpy(in,&inbuf[1],inlen); unlock: - mutex_unlock(&d->usb_mutex); + up(&d->usb_sem); return ret; } diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 37d5e0af1..c676b1e23 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -116,12 +116,6 @@ config DVB_MT352 help A DVB-T tuner module. Say Y when you want to support this frontend. -config DVB_ZL10353 - tristate "Zarlink ZL10353 based" - depends on DVB_CORE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - config DVB_DIB3000MB tristate "DiBcom 3000M-B" depends on DVB_CORE @@ -161,7 +155,7 @@ comment "ATSC (North American/Korean Terresterial DTV) frontends" depends on DVB_CORE config DVB_NXT200X - tristate "NxtWave Communications NXT2002/NXT2004 based" + tristate "Nextwave NXT2002/NXT2004 based" depends on DVB_CORE select FW_LOADER help @@ -175,32 +169,20 @@ config DVB_NXT200X or /lib/firmware (depending on configuration of firmware hotplug). config DVB_OR51211 - tristate "Oren OR51211 based" + tristate "or51211 based (pcHDTV HD2000 card)" depends on DVB_CORE select FW_LOADER help An ATSC 8VSB tuner module. Say Y when you want to support this frontend. - This driver needs external firmware. Please use the command - "/Documentation/dvb/get_dvb_firmware or51211" to - download it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - config DVB_OR51132 - tristate "Oren OR51132 based" + tristate "OR51132 based (pcHDTV HD3000 card)" depends on DVB_CORE select FW_LOADER help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. - This driver needs external firmware. Please use the commands - "/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or - "/Documentation/dvb/get_dvb_firmware or51132_qam" to - download firmwares for 8VSB and QAM64/256, respectively. Copy them to - /usr/lib/hotplug/firmware or /lib/firmware (depending on - configuration of firmware hotplug). - config DVB_BCM3510 tristate "Broadcom BCM3510" depends on DVB_CORE diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index d09b6071f..1af769cd9 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o obj-$(CONFIG_DVB_SP887X) += sp887x.o obj-$(CONFIG_DVB_NXT6000) += nxt6000.o obj-$(CONFIG_DVB_MT352) += mt352.o -obj-$(CONFIG_DVB_ZL10353) += zl10353.o obj-$(CONFIG_DVB_CX22702) += cx22702.o obj-$(CONFIG_DVB_TDA10021) += tda10021.o obj-$(CONFIG_DVB_STV0297) += stv0297.o diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index 1708a1d48..caaee893c 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c @@ -39,7 +39,6 @@ #include #include #include -#include #include "dvb_frontend.h" #include "bcm3510.h" @@ -53,7 +52,7 @@ struct bcm3510_state { struct dvb_frontend frontend; /* demodulator private data */ - struct mutex hab_mutex; + struct semaphore hab_sem; u8 firmware_loaded:1; unsigned long next_status_check; @@ -214,7 +213,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob dbufout(ob,olen+2,deb_hab); deb_hab("\n"); - if (mutex_lock_interruptible(&st->hab_mutex) < 0) + if (down_interruptible(&st->hab_sem) < 0) return -EAGAIN; if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 || @@ -227,7 +226,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob memcpy(ibuf,&ib[2],ilen); error: - mutex_unlock(&st->hab_mutex); + up(&st->hab_sem); return ret; } @@ -797,7 +796,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; - mutex_init(&state->hab_mutex); + sema_init(&state->hab_sem, 1); if ((ret = bcm3510_readB(state,0xe0,&v)) < 0) goto error; diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h deleted file mode 100644 index 78573b22a..000000000 --- a/drivers/media/dvb/frontends/bsbe1.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.c) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You 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. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef BSBE1_H -#define BSBE1_H - -static u8 alps_bsbe1_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x92, - 0xff, 0xff -}; - - -static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } - else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } - else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } - else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } - else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } - else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio ) & 0xf0); - - return 0; -} - -static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) -{ - int ret; - u8 data[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = (params->frequency + (125 - 1)) / 125; // round correctly - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; - - ret = i2c_transfer(i2c, &msg, 1); - return (ret != 1) ? -EIO : 0; -} - -static struct stv0299_config alps_bsbe1_config = { - .demod_address = 0x68, - .inittab = alps_bsbe1_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsbe1_set_symbol_rate, - .pll_set = alps_bsbe1_pll_set, -}; - -#endif diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h deleted file mode 100644 index 2a5366ce7..000000000 --- a/drivers/media/dvb/frontends/bsru6.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You 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. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef BSRU6_H -#define BSRU6_H - -static u8 alps_bsru6_inittab[] = { - 0x01, 0x15, - 0x02, 0x00, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x52, - 0xff, 0xff -}; - -static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { - aclk = 0xb7; - bclk = 0x47; - } else if (srate < 3000000) { - aclk = 0xb7; - bclk = 0x4b; - } else if (srate < 7000000) { - aclk = 0xb7; - bclk = 0x4f; - } else if (srate < 14000000) { - aclk = 0xb7; - bclk = 0x53; - } else if (srate < 30000000) { - aclk = 0xb6; - bclk = 0x53; - } else if (srate < 45000000) { - aclk = 0xb4; - bclk = 0x51; - } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, ratio & 0xf0); - - return 0; -} - -static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) -{ - u8 buf[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = (params->frequency + (125 - 1)) / 125; // round correctly - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - buf[3] = 0xC4; - - if (params->frequency > 1530000) - buf[3] = 0xc0; - - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct stv0299_config alps_bsru6_config = { - .demod_address = 0x68, - .inittab = alps_bsru6_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsru6_set_symbol_rate, - .pll_set = alps_bsru6_pll_set, -}; - -#endif diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index f3edf8b51..d15d32c51 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -371,15 +371,6 @@ static int cx24110_initfe(struct dvb_frontend* fe) return 0; } -static int cx24110_sleep(struct dvb_frontend *fe) -{ - struct cx24110_state *state = fe->demodulator_priv; - - if (state->config->pll_sleep) - return state->config->pll_sleep(fe); - return 0; -} - static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) { struct cx24110_state *state = fe->demodulator_priv; @@ -427,9 +418,6 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe, struct cx24110_state *state = fe->demodulator_priv; unsigned long timeout; - if (cmd->msg_len < 3 || cmd->msg_len > 6) - return -EINVAL; /* not implemented */ - for (i = 0; i < cmd->msg_len; i++) cx24110_writereg(state, 0x79 + i, cmd->msg[i]); @@ -651,7 +639,6 @@ static struct dvb_frontend_ops cx24110_ops = { .release = cx24110_release, .init = cx24110_initfe, - .sleep = cx24110_sleep, .set_frontend = cx24110_set_frontend, .get_frontend = cx24110_get_frontend, .read_status = cx24110_read_status, diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h index 609ac642b..b63ecf264 100644 --- a/drivers/media/dvb/frontends/cx24110.h +++ b/drivers/media/dvb/frontends/cx24110.h @@ -35,7 +35,6 @@ struct cx24110_config /* PLL maintenance */ int (*pll_init)(struct dvb_frontend* fe); int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); - int (*pll_sleep)(struct dvb_frontend* fe); }; extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index 691dc840d..d661c6f9c 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c @@ -29,9 +29,6 @@ #include "dvb_frontend.h" #include "cx24123.h" -#define XTAL 10111000 - -static int force_band; static int debug; #define dprintk(args...) \ do { \ @@ -55,7 +52,6 @@ struct cx24123_state u32 VGAarg; u32 bandselectarg; u32 pllarg; - u32 FILTune; /* The Demod/Tuner can't easily provide these, we cache them */ u32 currentfreq; @@ -67,33 +63,43 @@ static struct { u32 symbolrate_low; u32 symbolrate_high; + u32 VCAslope; + u32 VCAoffset; + u32 VGA1offset; + u32 VGA2offset; u32 VCAprogdata; u32 VGAprogdata; - u32 FILTune; } cx24123_AGC_vals[] = { { .symbolrate_low = 1000000, .symbolrate_high = 4999999, - /* the specs recommend other values for VGA offsets, - but tests show they are wrong */ - .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x07, - .FILTune = 0x27f /* 0.41 V */ + .VCAslope = 0x07, + .VCAoffset = 0x0f, + .VGA1offset = 0x1f8, + .VGA2offset = 0x1f8, + .VGAprogdata = (2 << 18) | (0x1f8 << 9) | 0x1f8, + .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x07, }, { .symbolrate_low = 5000000, .symbolrate_high = 14999999, - .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x1f, - .FILTune = 0x317 /* 0.90 V */ + .VCAslope = 0x1f, + .VCAoffset = 0x1f, + .VGA1offset = 0x1e0, + .VGA2offset = 0x180, + .VGAprogdata = (2 << 18) | (0x180 << 9) | 0x1e0, + .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x1f, }, { .symbolrate_low = 15000000, .symbolrate_high = 45000000, - .VGAprogdata = (1 << 19) | (0x100 << 9) | 0x180, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x3f, - .FILTune = 0x145 /* 2.70 V */ + .VCAslope = 0x3f, + .VCAoffset = 0x3f, + .VGA1offset = 0x180, + .VGA2offset = 0x100, + .VGAprogdata = (2 << 18) | (0x100 << 9) | 0x180, + .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x3f, }, }; @@ -106,80 +112,91 @@ static struct { u32 freq_low; u32 freq_high; + u32 bandselect; u32 VCOdivider; + u32 VCOnumber; u32 progdata; } cx24123_bandselect_vals[] = { - /* band 1 */ { .freq_low = 950000, + .freq_high = 1018999, + .bandselect = 0x40, + .VCOdivider = 4, + .VCOnumber = 7, + .progdata = (0 << 18) | (0 << 9) | 0x40, + }, + { + .freq_low = 1019000, .freq_high = 1074999, + .bandselect = 0x80, .VCOdivider = 4, - .progdata = (0 << 19) | (0 << 9) | 0x40, + .VCOnumber = 8, + .progdata = (0 << 18) | (0 << 9) | 0x80, }, - - /* band 2 */ { .freq_low = 1075000, - .freq_high = 1177999, - .VCOdivider = 4, - .progdata = (0 << 19) | (0 << 9) | 0x80, + .freq_high = 1227999, + .bandselect = 0x01, + .VCOdivider = 2, + .VCOnumber = 1, + .progdata = (0 << 18) | (1 << 9) | 0x01, }, - - /* band 3 */ { - .freq_low = 1178000, - .freq_high = 1295999, + .freq_low = 1228000, + .freq_high = 1349999, + .bandselect = 0x02, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x01, + .VCOnumber = 2, + .progdata = (0 << 18) | (1 << 9) | 0x02, }, - - /* band 4 */ { - .freq_low = 1296000, - .freq_high = 1431999, + .freq_low = 1350000, + .freq_high = 1481999, + .bandselect = 0x04, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x02, + .VCOnumber = 3, + .progdata = (0 << 18) | (1 << 9) | 0x04, }, - - /* band 5 */ { - .freq_low = 1432000, - .freq_high = 1575999, + .freq_low = 1482000, + .freq_high = 1595999, + .bandselect = 0x08, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x04, + .VCOnumber = 4, + .progdata = (0 << 18) | (1 << 9) | 0x08, }, - - /* band 6 */ { - .freq_low = 1576000, + .freq_low = 1596000, .freq_high = 1717999, + .bandselect = 0x10, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x08, + .VCOnumber = 5, + .progdata = (0 << 18) | (1 << 9) | 0x10, }, - - /* band 7 */ { .freq_low = 1718000, .freq_high = 1855999, + .bandselect = 0x20, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x10, + .VCOnumber = 6, + .progdata = (0 << 18) | (1 << 9) | 0x20, }, - - /* band 8 */ { .freq_low = 1856000, .freq_high = 2035999, + .bandselect = 0x40, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x20, + .VCOnumber = 7, + .progdata = (0 << 18) | (1 << 9) | 0x40, }, - - /* band 9 */ { .freq_low = 2036000, - .freq_high = 2150000, + .freq_high = 2149999, + .bandselect = 0x80, .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x40, + .VCOnumber = 8, + .progdata = (0 << 18) | (1 << 9) | 0x80, }, }; @@ -190,44 +207,49 @@ static struct { { {0x00, 0x03}, /* Reset system */ {0x00, 0x00}, /* Clear reset */ - {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */ - {0x04, 0x10}, /* MPEG */ - {0x05, 0x04}, /* MPEG */ - {0x06, 0x31}, /* MPEG (default) */ - {0x0b, 0x00}, /* Freq search start point (default) */ - {0x0c, 0x00}, /* Demodulator sample gain (default) */ - {0x0d, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */ - {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */ - {0x0f, 0xfe}, /* FEC search mask (all supported codes) */ - {0x10, 0x01}, /* Default search inversion, no repeat (default) */ - {0x16, 0x00}, /* Enable reading of frequency */ - {0x17, 0x01}, /* Enable EsNO Ready Counter */ - {0x1c, 0x80}, /* Enable error counter */ - {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */ - {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */ - {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */ - {0x29, 0x00}, /* DiSEqC LNB_DC off */ - {0x2a, 0xb0}, /* DiSEqC Parameters (default) */ - {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */ - {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */ + {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */ + {0x03, 0x07}, + {0x04, 0x10}, + {0x05, 0x04}, + {0x06, 0x31}, + {0x0d, 0x02}, + {0x0e, 0x03}, + {0x0f, 0xfe}, + {0x10, 0x01}, + {0x14, 0x01}, + {0x15, 0x98}, + {0x16, 0x00}, + {0x17, 0x01}, + {0x1b, 0x05}, + {0x1c, 0x80}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x20, 0x41}, + {0x21, 0x15}, + {0x27, 0x14}, + {0x28, 0x46}, + {0x29, 0x00}, + {0x2a, 0xb0}, + {0x2b, 0x73}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, {0x30, 0x00}, {0x31, 0x00}, - {0x32, 0x8c}, /* DiSEqC Parameters (default) */ - {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */ + {0x32, 0x8c}, + {0x33, 0x00}, {0x34, 0x00}, - {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */ - {0x36, 0x02}, /* DiSEqC Parameters (default) */ - {0x37, 0x3a}, /* DiSEqC Parameters (default) */ - {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */ - {0x44, 0x00}, /* Constellation (default) */ - {0x45, 0x00}, /* Symbol count (default) */ - {0x46, 0x0d}, /* Symbol rate estimator on (default) */ - {0x56, 0x41}, /* Various (default) */ - {0x57, 0xff}, /* Error Counter Window (default) */ - {0x67, 0x83}, /* Non-DCII symbol clock */ + {0x35, 0x03}, + {0x36, 0x02}, + {0x37, 0x3a}, + {0x3a, 0x00}, /* Enable AGC accumulator */ + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x05}, + {0x56, 0x41}, + {0x57, 0xff}, + {0x67, 0x83}, }; static int cx24123_writereg(struct cx24123_state* state, int reg, int data) @@ -236,10 +258,6 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data) struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; int err; - if (debug>1) - printk("cx24123: %s: write reg 0x%02x, value 0x%02x\n", - __FUNCTION__,reg, data); - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { printk("%s: writereg error(err == %i, reg == 0x%02x," " data == 0x%02x)\n", __FUNCTION__, err, reg, data); @@ -256,10 +274,6 @@ static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; int err; - if (debug>1) - printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n", - __FUNCTION__,reg, data); - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { printk("%s: writelnbreg error (err == %i, reg == 0x%02x," " data == 0x%02x)\n", __FUNCTION__, err, reg, data); @@ -289,9 +303,6 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg) return ret; } - if (debug>1) - printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret); - return b1[0]; } @@ -302,23 +313,17 @@ static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) { - u8 nom_reg = cx24123_readreg(state, 0x0e); - u8 auto_reg = cx24123_readreg(state, 0x10); - switch (inversion) { case INVERSION_OFF: - dprintk("%s: inversion off\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg & ~0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); + cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f); + cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); break; case INVERSION_ON: - dprintk("%s: inversion on\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); + cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80); + cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); break; case INVERSION_AUTO: - dprintk("%s: inversion auto\n",__FUNCTION__); - cx24123_writereg(state, 0x10, auto_reg & ~0x80); + cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f); break; default: return -EINVAL; @@ -333,191 +338,92 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers val = cx24123_readreg(state, 0x1b) >> 7; - if (val == 0) { - dprintk("%s: read inversion off\n",__FUNCTION__); + if (val == 0) *inversion = INVERSION_OFF; - } else { - dprintk("%s: read inversion on\n",__FUNCTION__); + else *inversion = INVERSION_ON; - } return 0; } static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) { - u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07; - if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) fec = FEC_AUTO; + /* Hardware has 5/11 and 3/5 but are never unused */ switch (fec) { + case FEC_NONE: + return cx24123_writereg(state, 0x0f, 0x01); case FEC_1_2: - dprintk("%s: set FEC to 1/2\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x01); - cx24123_writereg(state, 0x0f, 0x02); - break; + return cx24123_writereg(state, 0x0f, 0x02); case FEC_2_3: - dprintk("%s: set FEC to 2/3\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x02); - cx24123_writereg(state, 0x0f, 0x04); - break; + return cx24123_writereg(state, 0x0f, 0x04); case FEC_3_4: - dprintk("%s: set FEC to 3/4\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x03); - cx24123_writereg(state, 0x0f, 0x08); - break; - case FEC_4_5: - dprintk("%s: set FEC to 4/5\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x04); - cx24123_writereg(state, 0x0f, 0x10); - break; + return cx24123_writereg(state, 0x0f, 0x08); case FEC_5_6: - dprintk("%s: set FEC to 5/6\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x05); - cx24123_writereg(state, 0x0f, 0x20); - break; - case FEC_6_7: - dprintk("%s: set FEC to 6/7\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x06); - cx24123_writereg(state, 0x0f, 0x40); - break; + return cx24123_writereg(state, 0x0f, 0x20); case FEC_7_8: - dprintk("%s: set FEC to 7/8\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x07); - cx24123_writereg(state, 0x0f, 0x80); - break; + return cx24123_writereg(state, 0x0f, 0x80); case FEC_AUTO: - dprintk("%s: set FEC to auto\n",__FUNCTION__); - cx24123_writereg(state, 0x0f, 0xfe); - break; + return cx24123_writereg(state, 0x0f, 0xae); default: return -EOPNOTSUPP; } - - return 0; } static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec) { int ret; + u8 val; ret = cx24123_readreg (state, 0x1b); if (ret < 0) return ret; - ret = ret & 0x07; - - switch (ret) { + val = ret & 0x07; + switch (val) { case 1: *fec = FEC_1_2; break; - case 2: - *fec = FEC_2_3; - break; case 3: - *fec = FEC_3_4; + *fec = FEC_2_3; break; case 4: - *fec = FEC_4_5; + *fec = FEC_3_4; break; case 5: - *fec = FEC_5_6; + *fec = FEC_4_5; break; case 6: - *fec = FEC_6_7; + *fec = FEC_5_6; break; case 7: *fec = FEC_7_8; break; + case 2: /* *fec = FEC_3_5; break; */ + case 0: /* *fec = FEC_5_11; break; */ + *fec = FEC_AUTO; + break; default: - /* this can happen when there's no lock */ - *fec = FEC_NONE; + *fec = FEC_NONE; // can't happen } return 0; } -/* Approximation of closest integer of log2(a/b). It actually gives the - lowest integer i such that 2^i >= round(a/b) */ -static u32 cx24123_int_log2(u32 a, u32 b) -{ - u32 exp, nearest = 0; - u32 div = a / b; - if(a % b >= b / 2) ++div; - if(div < (1 << 31)) - { - for(exp = 1; div > exp; nearest++) - exp += exp; - } - return nearest; -} - +/* fixme: Symbol rates < 3MSps may not work because of precision loss */ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) { - u32 tmp, sample_rate, ratio, sample_gain; - u8 pll_mult; - - /* check if symbol rate is within limits */ - if ((srate > state->ops.info.symbol_rate_max) || - (srate < state->ops.info.symbol_rate_min)) - return -EOPNOTSUPP;; - - /* choose the sampling rate high enough for the required operation, - while optimizing the power consumed by the demodulator */ - if (srate < (XTAL*2)/2) - pll_mult = 2; - else if (srate < (XTAL*3)/2) - pll_mult = 3; - else if (srate < (XTAL*4)/2) - pll_mult = 4; - else if (srate < (XTAL*5)/2) - pll_mult = 5; - else if (srate < (XTAL*6)/2) - pll_mult = 6; - else if (srate < (XTAL*7)/2) - pll_mult = 7; - else if (srate < (XTAL*8)/2) - pll_mult = 8; - else - pll_mult = 9; - - - sample_rate = pll_mult * XTAL; - - /* - SYSSymbolRate[21:0] = (srate << 23) / sample_rate - - We have to use 32 bit unsigned arithmetic without precision loss. - The maximum srate is 45000000 or 0x02AEA540. This number has - only 6 clear bits on top, hence we can shift it left only 6 bits - at a time. Borrowed from cx24110.c - */ - - tmp = srate << 6; - ratio = tmp / sample_rate; - - tmp = (tmp % sample_rate) << 6; - ratio = (ratio << 6) + (tmp / sample_rate); - - tmp = (tmp % sample_rate) << 6; - ratio = (ratio << 6) + (tmp / sample_rate); - - tmp = (tmp % sample_rate) << 5; - ratio = (ratio << 5) + (tmp / sample_rate); - - - cx24123_writereg(state, 0x01, pll_mult * 6); + u32 val; - cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f ); - cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff ); - cx24123_writereg(state, 0x0a, (ratio ) & 0xff ); + val = (srate / 1185) * 100; - /* also set the demodulator sample gain */ - sample_gain = cx24123_int_log2(sample_rate, srate); - tmp = cx24123_readreg(state, 0x0c) & ~0xe0; - cx24123_writereg(state, 0x0c, tmp | sample_gain << 5); + /* Compensate for scaling up, by removing 17 symbols per 1Msps */ + val = val - (17 * (srate / 1000000)); - dprintk("%s: srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", __FUNCTION__, srate, ratio, sample_rate, sample_gain); + cx24123_writereg(state, 0x08, (val >> 16) & 0xff ); + cx24123_writereg(state, 0x09, (val >> 8) & 0xff ); + cx24123_writereg(state, 0x0a, (val ) & 0xff ); return 0; } @@ -531,9 +437,6 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa struct cx24123_state *state = fe->demodulator_priv; u32 ndiv = 0, adiv = 0, vco_div = 0; int i = 0; - int pump = 2; - int band = 0; - int num_bands = sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); /* Defaults for low freq, low rate */ state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; @@ -541,49 +444,38 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa state->bandselectarg = cx24123_bandselect_vals[0].progdata; vco_div = cx24123_bandselect_vals[0].VCOdivider; - /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */ + /* For the given symbolerate, determine the VCA and VGA programming bits */ for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) { if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && - (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { + (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; - state->FILTune = cx24123_AGC_vals[i].FILTune; } } - /* determine the band to use */ - if(force_band < 1 || force_band > num_bands) + /* For the given frequency, determine the bandselect programming bits */ + for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++) { - for (i = 0; i < num_bands; i++) - { - if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && - (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) - band = i; + if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && + (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) { + state->bandselectarg = cx24123_bandselect_vals[i].progdata; + vco_div = cx24123_bandselect_vals[i].VCOdivider; } } - else - band = force_band - 1; - - state->bandselectarg = cx24123_bandselect_vals[band].progdata; - vco_div = cx24123_bandselect_vals[band].VCOdivider; - - /* determine the charge pump current */ - if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 ) - pump = 0x01; - else - pump = 0x02; /* Determine the N/A dividers for the requested lband freq (in kHz). */ - /* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */ - ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff; - adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f; + /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */ + ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff; + adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f; if (adiv == 0) - ndiv++; + adiv++; - /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */ - state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv; + /* determine the correct pll frequency values. */ + /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */ + state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14); + state->pllarg |= (ndiv << 5) | adiv; return 0; } @@ -597,8 +489,6 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par struct cx24123_state *state = fe->demodulator_priv; unsigned long timeout; - dprintk("%s: pll writereg called, data=0x%08x\n",__FUNCTION__,data); - /* align the 21 bytes into to bit23 boundary */ data = data << 3; @@ -648,9 +538,6 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - dprintk("frequency=%i\n", p->frequency); if (cx24123_pll_calculate(fe, p) != 0) { printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__); @@ -665,14 +552,6 @@ static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_paramet cx24123_pll_writereg(fe, p, state->bandselectarg); cx24123_pll_writereg(fe, p, state->pllarg); - /* set the FILTUNE voltage */ - val = cx24123_readreg(state, 0x28) & ~0x3; - cx24123_writereg(state, 0x27, state->FILTune >> 2); - cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3)); - - dprintk("%s: pll tune VCA=%d, band=%d, pll=%d\n",__FUNCTION__,state->VCAarg, - state->bandselectarg,state->pllarg); - return 0; } @@ -681,8 +560,6 @@ static int cx24123_initfe(struct dvb_frontend* fe) struct cx24123_state *state = fe->demodulator_priv; int i; - dprintk("%s: init frontend\n",__FUNCTION__); - /* Configure the demod to a good set of defaults */ for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); @@ -710,13 +587,10 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage switch (voltage) { case SEC_VOLTAGE_13: - dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ case SEC_VOLTAGE_18: - dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ case SEC_VOLTAGE_OFF: - dprintk("%s: isl5421 voltage off\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val & 0x30); default: return -EINVAL; @@ -750,93 +624,13 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage return 0; } -/* wait for diseqc queue to become ready (or timeout) */ -static void cx24123_wait_for_diseqc(struct cx24123_state *state) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(200); - while (!(cx24123_readreg(state, 0x29) & 0x40)) { - if(time_after(jiffies, timeout)) { - printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__); - break; - } - msleep(10); - } -} - -static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) +static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, + struct dvb_diseqc_master_cmd *cmd) { - struct cx24123_state *state = fe->demodulator_priv; - int i, val; - - dprintk("%s:\n",__FUNCTION__); - - /* check if continuous tone has been stopped */ - if (state->config->use_isl6421) - val = cx24123_readlnbreg(state, 0x00) & 0x10; - else - val = cx24123_readreg(state, 0x29) & 0x10; + /* fixme: Implement diseqc */ + printk("%s: No support yet\n",__FUNCTION__); - - if (val) { - printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); - return -ENOTSUPP; - } - - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); - - /* select tone mode */ - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8); - - for (i = 0; i < cmd->msg_len; i++) - cx24123_writereg(state, 0x2C + i, cmd->msg[i]); - - val = cx24123_readreg(state, 0x29); - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3)); - - /* wait for diseqc message to finish sending */ - cx24123_wait_for_diseqc(state); - - return 0; -} - -static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - struct cx24123_state *state = fe->demodulator_priv; - int val; - - dprintk("%s:\n", __FUNCTION__); - - /* check if continuous tone has been stoped */ - if (state->config->use_isl6421) - val = cx24123_readlnbreg(state, 0x00) & 0x10; - else - val = cx24123_readreg(state, 0x29) & 0x10; - - - if (val) { - printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); - return -ENOTSUPP; - } - - cx24123_wait_for_diseqc(state); - - /* select tone mode */ - val = cx24123_readreg(state, 0x2a) & 0xf8; - cx24123_writereg(state, 0x2a, val | 0x04); - - val = cx24123_readreg(state, 0x29); - - if (burst == SEC_MINI_A) - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); - else if (burst == SEC_MINI_B) - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08)); - else - return -EINVAL; - - cx24123_wait_for_diseqc(state); - - return 0; + return -ENOTSUPP; } static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) @@ -848,15 +642,13 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) *status = 0; if (lock & 0x01) - *status |= FE_HAS_SIGNAL; - if (sync & 0x02) - *status |= FE_HAS_CARRIER; + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; if (sync & 0x04) *status |= FE_HAS_VITERBI; if (sync & 0x08) - *status |= FE_HAS_SYNC; + *status |= FE_HAS_CARRIER; if (sync & 0x80) - *status |= FE_HAS_LOCK; + *status |= FE_HAS_SYNC | FE_HAS_LOCK; return 0; } @@ -889,8 +681,6 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) else state->snr = 0; - dprintk("%s: BER = %d, S/N index = %d\n",__FUNCTION__,state->lastber, state->snr); - *ber = state->lastber; return 0; @@ -901,8 +691,6 @@ static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_str struct cx24123_state *state = fe->demodulator_priv; *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ - dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength); - return 0; } @@ -911,8 +699,6 @@ static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) struct cx24123_state *state = fe->demodulator_priv; *snr = state->snr; - dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr); - return 0; } @@ -921,8 +707,6 @@ static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) struct cx24123_state *state = fe->demodulator_priv; *ucblocks = state->lastber; - dprintk("%s: ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks); - return 0; } @@ -930,8 +714,6 @@ static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par { struct cx24123_state *state = fe->demodulator_priv; - dprintk("%s: set_frontend\n",__FUNCTION__); - if (state->config->set_ts_params) state->config->set_ts_params(fe, 0); @@ -955,8 +737,6 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par { struct cx24123_state *state = fe->demodulator_priv; - dprintk("%s: get_frontend\n",__FUNCTION__); - if (cx24123_get_inversion(state, &p->inversion) != 0) { printk("%s: Failed to get inversion status\n",__FUNCTION__); return -EREMOTEIO; @@ -983,10 +763,8 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) switch (tone) { case SEC_TONE_ON: - dprintk("%s: isl6421 sec tone on\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val | 0x10); case SEC_TONE_OFF: - dprintk("%s: isl6421 sec tone off\n",__FUNCTION__); return cx24123_writelnbreg(state, 0x0, val & 0x2f); default: printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); @@ -1077,13 +855,12 @@ static struct dvb_frontend_ops cx24123_ops = { .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 5000, + .frequency_tolerance = 29500, .symbol_rate_min = 1000000, .symbol_rate_max = 45000000, .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_RECOVER }, @@ -1098,16 +875,12 @@ static struct dvb_frontend_ops cx24123_ops = { .read_snr = cx24123_read_snr, .read_ucblocks = cx24123_read_ucblocks, .diseqc_send_master_cmd = cx24123_send_diseqc_msg, - .diseqc_send_burst = cx24123_diseqc_send_burst, .set_tone = cx24123_set_tone, .set_voltage = cx24123_set_voltage, }; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -module_param(force_band, int, 0644); -MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off)."); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware"); MODULE_AUTHOR("Steven Toth"); diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 40930a358..e7937c63b 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -235,8 +235,8 @@ struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { .max = 863000000, .count = 3, .entries = { - { 165000000, 44000000, 62500, 0xce, 0x01 }, - { 450000000, 44000000, 62500, 0xce, 0x02 }, + { 160000000, 44000000, 62500, 0xce, 0x01 }, + { 455000000, 44000000, 62500, 0xce, 0x02 }, { 999999999, 44000000, 62500, 0xce, 0x04 }, }, }; @@ -404,21 +404,6 @@ struct dvb_pll_desc dvb_pll_philips_td1316 = { }; EXPORT_SYMBOL(dvb_pll_philips_td1316); -/* FE6600 used on DViCO Hybrid */ -struct dvb_pll_desc dvb_pll_thomson_fe6600 = { - .name = "Thomson FE6600", - .min = 44250000, - .max = 858000000, - .count = 4, - .entries = { - { 250000000, 36213333, 166667, 0xb4, 0x12 }, - { 455000000, 36213333, 166667, 0xfe, 0x11 }, - { 775500000, 36213333, 166667, 0xbc, 0x18 }, - { 999999999, 36213333, 166667, 0xf4, 0x18 }, - } -}; -EXPORT_SYMBOL(dvb_pll_thomson_fe6600); - /* ----------------------------------------------------------- */ /* code */ @@ -448,8 +433,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; buf[0] = div >> 8; buf[1] = div & 0xff; - buf[2] = desc->entries[i].config; - buf[3] = desc->entries[i].cb; + buf[2] = desc->entries[i].cb1; + buf[3] = desc->entries[i].cb2; if (desc->setbw) desc->setbw(buf, freq, bandwidth); diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 2b8461784..b22966e5f 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h @@ -15,8 +15,8 @@ struct dvb_pll_desc { u32 limit; u32 offset; u32 stepsize; - u8 config; - u8 cb; + u8 cb1; + u8 cb2; } entries[12]; }; @@ -42,8 +42,6 @@ extern struct dvb_pll_desc dvb_pll_samsung_tbmv; extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; extern struct dvb_pll_desc dvb_pll_philips_td1316; -extern struct dvb_pll_desc dvb_pll_thomson_fe6600; - int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, u32 freq, int bandwidth); diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 4691ac54b..8de081bf6 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c @@ -433,9 +433,6 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) /* Test signal does not exist flag */ /* as well as the AGC lock flag. */ *status |= FE_HAS_SIGNAL; - } else { - /* Without a signal all other status bits are meaningless */ - return 0; } /* @@ -498,9 +495,6 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) /* Test input signal does not exist flag */ /* as well as the AGC lock flag. */ *status |= FE_HAS_SIGNAL; - } else { - /* Without a signal all other status bits are meaningless */ - return 0; } /* Carrier Recovery Lock Status Register */ diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h deleted file mode 100644 index 0dcbe61b6..000000000 --- a/drivers/media/dvb/frontends/lnbp21.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * lnbp21.h - driver for lnb supply and control ic lnbp21 - * - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You 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. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef _LNBP21_H -#define _LNBP21_H - -/* system register */ -#define LNBP21_OLF 0x01 -#define LNBP21_OTF 0x02 -#define LNBP21_EN 0x04 -#define LNBP21_VSEL 0x08 -#define LNBP21_LLC 0x10 -#define LNBP21_TEN 0x20 -#define LNBP21_ISEL 0x40 -#define LNBP21_PCL 0x80 - -struct lnbp21 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; - void (*release_chain)(struct dvb_frontend* fe); -}; - -static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, - .buf = &lnbp21->config, - .len = sizeof(lnbp21->config) }; - - lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); - - switch(voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - lnbp21->config |= LNBP21_EN; - break; - case SEC_VOLTAGE_18: - lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); - break; - default: - return -EINVAL; - }; - - lnbp21->config |= lnbp21->override_or; - lnbp21->config &= lnbp21->override_and; - - return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, - .buf = &lnbp21->config, - .len = sizeof(lnbp21->config) }; - - if (arg) - lnbp21->config |= LNBP21_LLC; - else - lnbp21->config &= ~LNBP21_LLC; - - lnbp21->config |= lnbp21->override_or; - lnbp21->config &= lnbp21->override_and; - - return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void lnbp21_exit(struct dvb_frontend *fe) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; - - /* LNBP power off */ - lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free data & call next release routine */ - fe->ops->release = lnbp21->release_chain; - kfree(fe->misc_priv); - fe->misc_priv = NULL; - if (fe->ops->release) - fe->ops->release(fe); -} - -static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) -{ - struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); - - if (!lnbp21) - return -ENOMEM; - - /* default configuration */ - lnbp21->config = LNBP21_ISEL; - - /* bits which should be forced to '1' */ - lnbp21->override_or = override_set; - - /* bits which should be forced to '0' */ - lnbp21->override_and = ~override_clear; - - /* install release callback */ - lnbp21->release_chain = fe->ops->release; - fe->ops->release = lnbp21_exit; - - /* override frontend ops */ - fe->ops->set_voltage = lnbp21_set_voltage; - fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; - - lnbp21->i2c = i2c; - fe->misc_priv = lnbp21; - - return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); -} - -#endif diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index b83dafa4e..8e8df7b4c 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -52,6 +52,7 @@ struct tda1004x_state { struct dvb_frontend frontend; /* private demod data */ + u8 initialised; enum tda1004x_demod demod_type; }; @@ -593,6 +594,9 @@ static int tda10045_init(struct dvb_frontend* fe) dprintk("%s\n", __FUNCTION__); + if (state->initialised) + return 0; + if (tda10045_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); return -EIO; @@ -622,6 +626,7 @@ static int tda10045_init(struct dvb_frontend* fe) tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk); + state->initialised = 1; return 0; } @@ -630,6 +635,9 @@ static int tda10046_init(struct dvb_frontend* fe) struct tda1004x_state* state = fe->demodulator_priv; dprintk("%s\n", __FUNCTION__); + if (state->initialised) + return 0; + if (tda10046_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); return -EIO; @@ -689,6 +697,7 @@ static int tda10046_init(struct dvb_frontend* fe) // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); + state->initialised = 1; return 0; } @@ -1198,6 +1207,7 @@ static int tda1004x_sleep(struct dvb_frontend* fe) tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); break; } + state->initialised = 0; return 0; } @@ -1261,6 +1271,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); + state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ @@ -1319,6 +1330,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); + state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c deleted file mode 100644 index d7d9f59d7..000000000 --- a/drivers/media/dvb/frontends/zl10353.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006 Christopher Pascoe - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" -#include "zl10353_priv.h" -#include "zl10353.h" - -struct zl10353_state { - struct i2c_adapter *i2c; - struct dvb_frontend frontend; - struct dvb_frontend_ops ops; - - struct zl10353_config config; -}; - -static int debug_regs = 0; - -static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 buf[2] = { reg, val }; - struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0, - .buf = buf, .len = 2 }; - int err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err); - return err; - } - return 0; -} - -int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) -{ - int err, i; - for (i = 0; i < ilen - 1; i++) - if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1]))) - return err; - - return 0; -} - -static int zl10353_read_register(struct zl10353_state *state, u8 reg) -{ - int ret; - u8 b0[1] = { reg }; - u8 b1[1] = { 0 }; - struct i2c_msg msg[2] = { { .addr = state->config.demod_address, - .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config.demod_address, - .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk("%s: readreg error (reg=%d, ret==%i)\n", - __FUNCTION__, reg, ret); - return ret; - } - - return b1[0]; -} - -static void zl10353_dump_regs(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - char buf[52], buf2[4]; - int ret; - u8 reg; - - /* Dump all registers. */ - for (reg = 0; ; reg++) { - if (reg % 16 == 0) { - if (reg) - printk(KERN_DEBUG "%s\n", buf); - sprintf(buf, "%02x: ", reg); - } - ret = zl10353_read_register(state, reg); - if (ret >= 0) - sprintf(buf2, "%02x ", (u8)ret); - else - strcpy(buf2, "-- "); - strcat(buf, buf2); - if (reg == 0xff) - break; - } - printk(KERN_DEBUG "%s\n", buf); -} - -static int zl10353_sleep(struct dvb_frontend *fe) -{ - static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 }; - - zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown)); - return 0; -} - -static int zl10353_set_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 pllbuf[6] = { 0x67 }; - - /* These settings set "auto-everything" and start the FSM. */ - zl10353_single_write(fe, 0x55, 0x80); - udelay(200); - zl10353_single_write(fe, 0xEA, 0x01); - udelay(200); - zl10353_single_write(fe, 0xEA, 0x00); - - zl10353_single_write(fe, 0x56, 0x28); - zl10353_single_write(fe, 0x89, 0x20); - zl10353_single_write(fe, 0x5E, 0x00); - zl10353_single_write(fe, 0x65, 0x5A); - zl10353_single_write(fe, 0x66, 0xE9); - zl10353_single_write(fe, 0x62, 0x0A); - - state->config.pll_set(fe, param, pllbuf + 1); - zl10353_write(fe, pllbuf, sizeof(pllbuf)); - - zl10353_single_write(fe, 0x70, 0x01); - udelay(250); - zl10353_single_write(fe, 0xE4, 0x00); - zl10353_single_write(fe, 0xE5, 0x2A); - zl10353_single_write(fe, 0xE9, 0x02); - zl10353_single_write(fe, 0xE7, 0x40); - zl10353_single_write(fe, 0xE8, 0x10); - - return 0; -} - -static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct zl10353_state *state = fe->demodulator_priv; - int s6, s7, s8; - - if ((s6 = zl10353_read_register(state, STATUS_6)) < 0) - return -EREMOTEIO; - if ((s7 = zl10353_read_register(state, STATUS_7)) < 0) - return -EREMOTEIO; - if ((s8 = zl10353_read_register(state, STATUS_8)) < 0) - return -EREMOTEIO; - - *status = 0; - if (s6 & (1 << 2)) - *status |= FE_HAS_CARRIER; - if (s6 & (1 << 1)) - *status |= FE_HAS_VITERBI; - if (s6 & (1 << 5)) - *status |= FE_HAS_LOCK; - if (s7 & (1 << 4)) - *status |= FE_HAS_SYNC; - if (s8 & (1 << 6)) - *status |= FE_HAS_SIGNAL; - - if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != - (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) - *status &= ~FE_HAS_LOCK; - - return 0; -} - -static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 _snr; - - if (debug_regs) - zl10353_dump_regs(fe); - - _snr = zl10353_read_register(state, SNR); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int zl10353_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings - *fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 1000; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static int zl10353_init(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F }; - int rc = 0; - - if (debug_regs) - zl10353_dump_regs(fe); - - /* Do a "hard" reset if not already done */ - if (zl10353_read_register(state, 0x50) != 0x03) { - rc = zl10353_write(fe, zl10353_reset_attach, - sizeof(zl10353_reset_attach)); - if (debug_regs) - zl10353_dump_regs(fe); - } - - return 0; -} - -static void zl10353_release(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - - kfree(state); -} - -static struct dvb_frontend_ops zl10353_ops; - -struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, - struct i2c_adapter *i2c) -{ - struct zl10353_state *state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct zl10353_config)); - memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); - - /* check if the demod is there */ - if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) - goto error; - - /* create dvb_frontend */ - state->frontend.ops = &state->ops; - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops zl10353_ops = { - - .info = { - .name = "Zarlink ZL10353 DVB-T", - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 166667, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = zl10353_release, - - .init = zl10353_init, - .sleep = zl10353_sleep, - - .set_frontend = zl10353_set_parameters, - .get_tune_settings = zl10353_get_tune_settings, - - .read_status = zl10353_read_status, - .read_snr = zl10353_read_snr, -}; - -module_param(debug_regs, int, 0644); -MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off)."); - -MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver"); -MODULE_AUTHOR("Chris Pascoe"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(zl10353_attach); -EXPORT_SYMBOL(zl10353_write); diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h deleted file mode 100644 index 5cc4ae718..000000000 --- a/drivers/media/dvb/frontends/zl10353.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006 Christopher Pascoe - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You 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 ZL10353_H -#define ZL10353_H - -#include - -struct zl10353_config -{ - /* demodulator's I2C address */ - u8 demod_address; - - /* function which configures the PLL buffer (for secondary I2C - * connected tuner) or tunes the PLL (for direct connected tuner) */ - int (*pll_set)(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, u8 *pllbuf); -}; - -extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, - struct i2c_adapter *i2c); - -extern int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen); - -#endif /* ZL10353_H */ diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h deleted file mode 100644 index b72224bd7..000000000 --- a/drivers/media/dvb/frontends/zl10353_priv.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006 Christopher Pascoe - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You 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 _ZL10353_PRIV_ -#define _ZL10353_PRIV_ - -#define ID_ZL10353 0x14 - -enum zl10353_reg_addr { - INTERRUPT_0 = 0x00, - INTERRUPT_1 = 0x01, - INTERRUPT_2 = 0x02, - INTERRUPT_3 = 0x03, - INTERRUPT_4 = 0x04, - INTERRUPT_5 = 0x05, - STATUS_6 = 0x06, - STATUS_7 = 0x07, - STATUS_8 = 0x08, - STATUS_9 = 0x09, - SNR = 0x10, - CHIP_ID = 0x7F, -}; - -#endif /* _ZL10353_PRIV_ */ diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig index 7d8e6e87b..84f8f9f52 100644 --- a/drivers/media/dvb/pluto2/Kconfig +++ b/drivers/media/dvb/pluto2/Kconfig @@ -1,6 +1,7 @@ config DVB_PLUTO2 tristate "Pluto2 cards" - depends on DVB_CORE && PCI && I2C + depends on DVB_CORE && PCI + select I2C select I2C_ALGOBIT select DVB_TDA1004X help diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile index ce6a9aaf9..86ca84b2b 100644 --- a/drivers/media/dvb/pluto2/Makefile +++ b/drivers/media/dvb/pluto2/Makefile @@ -1,3 +1,3 @@ -obj-$(CONFIG_DVB_PLUTO2) += pluto2.o +obj-$(CONFIG_DVB_PLUTO2) = pluto2.o EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index b5ac7dfde..5b2aadb83 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig @@ -1,7 +1,8 @@ config DVB_AV7110 tristate "AV7110 cards" - depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 + depends on DVB_CORE && PCI select FW_LOADER + select VIDEO_DEV select VIDEO_SAA7146_VV select DVB_VES1820 select DVB_VES1X93 @@ -58,7 +59,7 @@ config DVB_AV7110_OSD config DVB_BUDGET tristate "Budget cards" - depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 + depends on DVB_CORE && PCI select VIDEO_SAA7146 select DVB_STV0299 select DVB_VES1X93 @@ -79,7 +80,7 @@ config DVB_BUDGET config DVB_BUDGET_CI tristate "Budget cards with onboard CI connector" - depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 + depends on DVB_CORE && PCI select VIDEO_SAA7146 select DVB_STV0297 select DVB_STV0299 @@ -99,7 +100,8 @@ config DVB_BUDGET_CI config DVB_BUDGET_AV tristate "Budget cards with analog video inputs" - depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 + depends on DVB_CORE && PCI + select VIDEO_DEV select VIDEO_SAA7146_VV select DVB_STV0299 select DVB_TDA1004X @@ -117,7 +119,7 @@ config DVB_BUDGET_AV config DVB_BUDGET_PATCH tristate "AV7110 cards with Budget Patch" - depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1 + depends on DVB_CORE && DVB_BUDGET select DVB_AV7110 select DVB_STV0299 select DVB_VES1X93 diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 6c8f02de2..7c6ccb96b 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -54,6 +54,7 @@ #include #include +#include #include @@ -66,10 +67,6 @@ #include "av7110_ca.h" #include "av7110_ipack.h" -#include "bsbe1.h" -#include "lnbp21.h" -#include "bsru6.h" - #define TS_WIDTH 376 #define TS_HEIGHT 512 #define TS_BUFLEN (TS_WIDTH*TS_HEIGHT) @@ -85,9 +82,6 @@ static int hw_sections; static int rgb_on; static int volume = 255; static int budgetpatch; -static int wss_cfg_4_3 = 0x4008; -static int wss_cfg_16_9 = 0x0007; -static int tv_standard; module_param_named(debug, av7110_debug, int, 0644); MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); @@ -106,12 +100,6 @@ module_param(volume, int, 0444); MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); module_param(budgetpatch, int, 0444); MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)"); -module_param(wss_cfg_4_3, int, 0444); -MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data"); -module_param(wss_cfg_16_9, int, 0444); -MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data"); -module_param(tv_standard, int, 0444); -MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC"); static void restart_feeds(struct av7110 *av7110); @@ -137,13 +125,6 @@ static void init_av7110_av(struct av7110 *av7110) if (ret < 0) printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret); - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3); - if (ret < 0) - printk("dvb-ttpci: unable to configure 4:3 wss\n"); - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9); - if (ret < 0) - printk("dvb-ttpci: unable to configure 16:9 wss\n"); - ret = av7710_set_video_mode(av7110, vidmode); if (ret < 0) printk("dvb-ttpci:cannot set video mode:%d\n",ret); @@ -261,10 +242,10 @@ static int arm_thread(void *data) if (!av7110->arm_ready) continue; - if (mutex_lock_interruptible(&av7110->dcomlock)) + if (down_interruptible(&av7110->dcomlock)) break; newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); if (newloops == av7110->arm_loops || av7110->arm_errors > 3) { printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", @@ -272,10 +253,10 @@ static int arm_thread(void *data) recover_arm(av7110); - if (mutex_lock_interruptible(&av7110->dcomlock)) + if (down_interruptible(&av7110->dcomlock)) break; newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); } av7110->arm_loops = newloops; av7110->arm_errors = 0; @@ -760,7 +741,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, int ret = 0; dprintk(4, "%p\n", av7110); - if (mutex_lock_interruptible(&av7110->pid_mutex)) + if (down_interruptible(&av7110->pid_mutex)) return -ERESTARTSYS; if (!(vpid & 0x8000)) @@ -779,7 +760,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); } - mutex_unlock(&av7110->pid_mutex); + up(&av7110->pid_mutex); return ret; } @@ -1107,9 +1088,11 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, struct av7110 *av7110; /* pointer casting paranoia... */ - BUG_ON(!demux); + if (!demux) + BUG(); dvbdemux = (struct dvb_demux *) demux->priv; - BUG_ON(!dvbdemux); + if (!dvbdemux) + BUG(); av7110 = (struct av7110 *) dvbdemux->priv; dprintk(4, "%p\n", av7110); @@ -1587,6 +1570,208 @@ static struct ves1x93_config alps_bsrv2_config = { .pll_set = alps_bsrv2_pll_set, }; + +static u8 alps_bsru6_inittab[] = { + 0x01, 0x15, + 0x02, 0x30, + 0x03, 0x00, + 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ + 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x40, /* DAC not used, set to high impendance mode */ + 0x07, 0x00, /* DAC LSB */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ + 0x09, 0x00, /* FIFO */ + 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ + 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ + 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ + 0x10, 0x3f, // AGC2 0x3d + 0x11, 0x84, + 0x12, 0xb9, + 0x15, 0xc9, // lock detector threshold + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, + 0x1f, 0x50, + 0x20, 0x00, + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 + 0x29, 0x1e, // 1/2 threshold + 0x2a, 0x14, // 2/3 threshold + 0x2b, 0x0f, // 3/4 threshold + 0x2c, 0x09, // 5/6 threshold + 0x2d, 0x05, // 7/8 threshold + 0x2e, 0x01, + 0x31, 0x1f, // test all FECs + 0x32, 0x19, // viterbi and synchro search + 0x33, 0xfc, // rs control + 0x34, 0x93, // error control + 0x0f, 0x52, + 0xff, 0xff +}; + +static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) +{ + u8 aclk = 0; + u8 bclk = 0; + + if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } + else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } + else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } + else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } + else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } + else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } + + stv0299_writereg(fe, 0x13, aclk); + stv0299_writereg(fe, 0x14, bclk); + stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); + stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); + stv0299_writereg(fe, 0x21, (ratio ) & 0xf0); + + return 0; +} + +static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) +{ + int ret; + u8 data[4]; + u32 div; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; + + if ((params->frequency < 950000) || (params->frequency > 2150000)) + return -EINVAL; + + div = (params->frequency + (125 - 1)) / 125; // round correctly + data[0] = (div >> 8) & 0x7f; + data[1] = div & 0xff; + data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; + data[3] = 0xC4; + + if (params->frequency > 1530000) data[3] = 0xc0; + + ret = i2c_transfer(i2c, &msg, 1); + if (ret != 1) + return -EIO; + return 0; +} + +static struct stv0299_config alps_bsru6_config = { + + .demod_address = 0x68, + .inittab = alps_bsru6_inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .lock_output = STV0229_LOCKOUTPUT_1, + .volt13_op0_op1 = STV0299_VOLT13_OP1, + .min_delay_ms = 100, + .set_symbol_rate = alps_bsru6_set_symbol_rate, + .pll_set = alps_bsru6_pll_set, +}; + + +static u8 alps_bsbe1_inittab[] = { + 0x01, 0x15, + 0x02, 0x30, + 0x03, 0x00, + 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ + 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x40, /* DAC not used, set to high impendance mode */ + 0x07, 0x00, /* DAC LSB */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ + 0x09, 0x00, /* FIFO */ + 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ + 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ + 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ + 0x10, 0x3f, // AGC2 0x3d + 0x11, 0x84, + 0x12, 0xb9, + 0x15, 0xc9, // lock detector threshold + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, + 0x1f, 0x50, + 0x20, 0x00, + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 + 0x29, 0x1e, // 1/2 threshold + 0x2a, 0x14, // 2/3 threshold + 0x2b, 0x0f, // 3/4 threshold + 0x2c, 0x09, // 5/6 threshold + 0x2d, 0x05, // 7/8 threshold + 0x2e, 0x01, + 0x31, 0x1f, // test all FECs + 0x32, 0x19, // viterbi and synchro search + 0x33, 0xfc, // rs control + 0x34, 0x93, // error control + 0x0f, 0x92, + 0xff, 0xff +}; + +static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) +{ + int ret; + u8 data[4]; + u32 div; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; + + if ((params->frequency < 950000) || (params->frequency > 2150000)) + return -EINVAL; + + div = (params->frequency + (125 - 1)) / 125; // round correctly + data[0] = (div >> 8) & 0x7f; + data[1] = div & 0xff; + data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; + data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; + + ret = i2c_transfer(i2c, &msg, 1); + return (ret != 1) ? -EIO : 0; +} + +static struct stv0299_config alps_bsbe1_config = { + .demod_address = 0x68, + .inittab = alps_bsbe1_inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .min_delay_ms = 100, + .set_symbol_rate = alps_bsru6_set_symbol_rate, + .pll_set = alps_bsbe1_pll_set, +}; + +static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +{ + struct av7110* av7110 = (struct av7110*) fe->dvb->priv; + int ret; + u8 data[1]; + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) }; + + switch(voltage) { + case SEC_VOLTAGE_OFF: + data[0] = 0x00; + break; + case SEC_VOLTAGE_13: + data[0] = 0x44; + break; + case SEC_VOLTAGE_18: + data[0] = 0x4c; + break; + default: + return -EINVAL; + }; + + ret = i2c_transfer(&av7110->i2c_adap, &msg, 1); + return (ret != 1) ? -EIO : 0; +} + + static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct av7110* av7110 = fe->dvb->priv; @@ -1911,7 +2096,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) if (av7110->playing) return 0; - if (mutex_lock_interruptible(&av7110->pid_mutex)) + if (down_interruptible(&av7110->pid_mutex)) return -ERESTARTSYS; if (synced) { @@ -1933,7 +2118,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) if (!ret) av7110->fe_synced = synced; - mutex_unlock(&av7110->pid_mutex); + up(&av7110->pid_mutex); return ret; } @@ -2126,7 +2311,7 @@ static int frontend_init(struct av7110 *av7110) read_pwm(av7110)); break; case 0x0003: - /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ + /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */ av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); break; @@ -2189,15 +2374,9 @@ static int frontend_init(struct av7110 *av7110) /* ALPS BSBE1 */ av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); if (av7110->fe) { - if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) { - printk("dvb-ttpci: LNBP21 not found!\n"); - if (av7110->fe->ops->release) - av7110->fe->ops->release(av7110->fe); - av7110->fe = NULL; - } else { - av7110->fe->ops->dishnetwork_send_legacy_command = NULL; - av7110->recover = dvb_s_recover; - } + av7110->fe->ops->set_voltage = lnbp21_set_voltage; + av7110->fe->ops->dishnetwork_send_legacy_command = NULL; + av7110->recover = dvb_s_recover; } break; } @@ -2535,19 +2714,16 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); - mutex_init(&av7110->pid_mutex); + sema_init(&av7110->pid_mutex, 1); /* locks for data transfers from/to AV7110 */ spin_lock_init(&av7110->debilock); - mutex_init(&av7110->dcomlock); + sema_init(&av7110->dcomlock, 1); av7110->debitype = -1; /* default OSD window */ av7110->osdwin = 1; - mutex_init(&av7110->osd_mutex); - - /* TV standard */ - av7110->vidmode = tv_standard == 1 ? VIDEO_MODE_NTSC : VIDEO_MODE_PAL; + sema_init(&av7110->osd_sema, 1); /* ARM "watchdog" */ init_waitqueue_head(&av7110->arm_wait); @@ -2793,7 +2969,7 @@ MODULE_DEVICE_TABLE(pci, pci_tbl); static struct saa7146_extension av7110_extension = { - .name = "dvb", + .name = "dvb\0", .flags = SAA7146_I2C_SHORT_DELAY, .module = THIS_MODULE, diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index 3e2e12124..fafd25fab 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h @@ -16,7 +16,6 @@ #include #include #include -#include #include "dvbdev.h" #include "demux.h" @@ -128,7 +127,7 @@ struct av7110 { /* DEBI and polled command interface */ spinlock_t debilock; - struct mutex dcomlock; + struct semaphore dcomlock; volatile int debitype; volatile int debilen; @@ -147,7 +146,7 @@ struct av7110 { int osdwin; /* currently active window */ u16 osdbpp[8]; - struct mutex osd_mutex; + struct semaphore osd_sema; /* CA */ @@ -173,7 +172,7 @@ struct av7110 { struct tasklet_struct vpe_tasklet; int fe_synced; - struct mutex pid_mutex; + struct semaphore pid_mutex; int video_blank; struct video_status videostate; diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 2eff09f63..400facec7 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -1479,6 +1479,8 @@ int av7110_av_init(struct av7110 *av7110) void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb }; int i, ret; + av7110->vidmode = VIDEO_MODE_PAL; + for (i = 0; i < 2; i++) { struct ipack *ipack = av7110->ipack + i; diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 75736f2fe..0bb6e74ae 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c @@ -327,10 +327,10 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags) start = jiffies; for (;;) { err = time_after(jiffies, start + ARM_WAIT_FREE); - if (mutex_lock_interruptible(&av7110->dcomlock)) + if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); if ((stat & flags) == 0) break; if (err) { @@ -487,11 +487,11 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) dprintk(1, "arm not ready.\n"); return -1; } - if (mutex_lock_interruptible(&av7110->dcomlock)) + if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; ret = __av7110_send_fw_cmd(av7110, buf, length); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); if (ret && ret!=-ERESTARTSYS) printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n", __FUNCTION__, ret); @@ -563,11 +563,11 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, return -1; } - if (mutex_lock_interruptible(&av7110->dcomlock)) + if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) { - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err); return err; } @@ -579,7 +579,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, break; if (err) { printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return -ETIMEDOUT; } #ifdef _NOHANDSHAKE @@ -595,7 +595,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, break; if (err) { printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return -ETIMEDOUT; } msleep(1); @@ -606,12 +606,12 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); if (stat & GPMQOver) { printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return -1; } else if (stat & OSDQOver) { printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return -1; } #endif @@ -619,7 +619,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, for (i = 0; i < reply_buf_len; i++) reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return 0; } @@ -735,7 +735,7 @@ static int FlushText(struct av7110 *av7110) unsigned long start; int err; - if (mutex_lock_interruptible(&av7110->dcomlock)) + if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; start = jiffies; while (1) { @@ -745,12 +745,12 @@ static int FlushText(struct av7110 *av7110) if (err) { printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return -ETIMEDOUT; } msleep(1); } - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return 0; } @@ -761,7 +761,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) int length = strlen(buf) + 1; u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y }; - if (mutex_lock_interruptible(&av7110->dcomlock)) + if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; start = jiffies; @@ -772,7 +772,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) if (ret) { printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return -ETIMEDOUT; } msleep(1); @@ -786,7 +786,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) if (ret) { printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); return -ETIMEDOUT; } msleep(1); @@ -798,7 +798,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) if (length & 1) wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2); ret = __av7110_send_fw_cmd(av7110, cbuf, 5); - mutex_unlock(&av7110->dcomlock); + up(&av7110->dcomlock); if (ret && ret!=-ERESTARTSYS) printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret); return ret; @@ -1062,7 +1062,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) { int ret; - if (mutex_lock_interruptible(&av7110->osd_mutex)) + if (down_interruptible(&av7110->osd_sema)) return -ERESTARTSYS; switch (dc->cmd) { @@ -1198,7 +1198,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) break; } - mutex_unlock(&av7110->osd_mutex); + up(&av7110->osd_sema); if (ret==-ERESTARTSYS) dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd); else if (ret) diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index 603a22e4b..94cf38c7e 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c @@ -369,11 +369,6 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) fm_matrix = 0x3001; // stereo src = 0x0020; break; - case V4L2_TUNER_MODE_LANG1_LANG2: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"); - fm_matrix = 0x3000; // bilingual - src = 0x0020; - break; case V4L2_TUNER_MODE_LANG1: dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"); fm_matrix = 0x3000; // mono @@ -584,11 +579,14 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size return -EFAULT; if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23) return -EINVAL; - if (d.id) + if (d.id) { av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0]; - else - av7110->wssData = 0x8000; - rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 1, av7110->wssData); + rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, + 2, 1, av7110->wssData); + } else { + av7110->wssData = 0; + rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); + } return (rc < 0) ? rc : count; } diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 3f4aa083f..adba47ce8 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -58,14 +58,13 @@ struct budget_av { struct tasklet_struct ciintf_irq_tasklet; int slot_status; struct dvb_ca_en50221 ca; - u8 reinitialise_demod:1; }; -/* GPIO Connections: - * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! - * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory - * 2 - CI Card Enable (Active Low) - * 3 - CI Card Detect +/* GPIO CI Connections: + * 0 - Vcc/Reset (Reset is controlled by capacitor) + * 1 - Attribute Memory + * 2 - Card Enable (Active Low) + * 3 - Card Detect */ /**************************************************************************** @@ -215,10 +214,6 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) msleep(100); - /* reinitialise the frontend if necessary */ - if (budget_av->reinitialise_demod) - dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); - if (timeout <= 0) { printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); @@ -1005,7 +1000,6 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBS_TV_STAR 0x0014 #define SUBID_DVBS_TV_STAR_CI 0x0016 -#define SUBID_DVBS_EASYWATCH 0x001e #define SUBID_DVBC_KNC1 0x0020 #define SUBID_DVBC_KNC1_PLUS 0x0021 #define SUBID_DVBC_CINERGY1200 0x1156 @@ -1045,7 +1039,6 @@ static void frontend_init(struct budget_av *budget_av) case SUBID_DVBS_TV_STAR: case SUBID_DVBS_TV_STAR_CI: case SUBID_DVBS_CYNERGY1200N: - case SUBID_DVBS_EASYWATCH: fe = stv0299_attach(&philips_sd1878_config, &budget_av->budget.i2c_adap); break; @@ -1062,14 +1055,7 @@ static void frontend_init(struct budget_av *budget_av) break; case SUBID_DVBC_KNC1: - budget_av->reinitialise_demod = 1; - fe = tda10021_attach(&philips_cu1216_config, - &budget_av->budget.i2c_adap, - read_pwm(budget_av)); - break; - case SUBID_DVBC_KNC1_PLUS: - budget_av->reinitialise_demod = 1; fe = tda10021_attach(&philips_cu1216_config, &budget_av->budget.i2c_adap, read_pwm(budget_av)); @@ -1200,6 +1186,8 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio SAA7146_HPS_SYNC_PORT_A); saa7113_setinput(budget_av, 0); + } else { + ciintf_init(budget_av); } /* fixme: find some sane values here... */ @@ -1218,7 +1206,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio budget_av->budget.dvb_adapter.priv = budget_av; frontend_init(budget_av); - ciintf_init(budget_av); + return 0; } @@ -1298,7 +1286,6 @@ MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); -MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); @@ -1314,7 +1301,6 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), - MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 36e4a8056..b9b3cd9c0 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -42,9 +42,6 @@ #include "stv0299.h" #include "stv0297.h" #include "tda1004x.h" -#include "lnbp21.h" -#include "bsbe1.h" -#include "bsru6.h" #define DEBIADDR_IR 0x1234 #define DEBIADDR_CICONTROL 0x0000 @@ -71,7 +68,6 @@ struct budget_ci { struct tasklet_struct msp430_irq_tasklet; struct tasklet_struct ciintf_irq_tasklet; int slot_status; - int ci_irq; struct dvb_ca_en50221 ca; char ir_dev_name[50]; u8 tuner_pll_address; /* used for philips_tdm1316l configs */ @@ -277,10 +273,8 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) if (slot != 0) return -EINVAL; - if (budget_ci->ci_irq) { - // trigger on RISING edge during reset so we know when READY is re-asserted - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } + // trigger on RISING edge during reset so we know when READY is re-asserted + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); budget_ci->slot_status = SLOTSTATUS_RESET; ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); msleep(1); @@ -373,50 +367,11 @@ static void ciintf_interrupt(unsigned long data) } } -static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - unsigned int flags; - - // ensure we don't get spurious IRQs during initialisation - if (!budget_ci->budget.ci_present) - return -EINVAL; - - // read the CAM status - flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - if (flags & CICONTROL_CAMDETECT) { - // mark it as present if it wasn't before - if (budget_ci->slot_status & SLOTSTATUS_NONE) { - budget_ci->slot_status = SLOTSTATUS_PRESENT; - } - - // during a RESET, we check if we can read from IO memory to see when CAM is ready - if (budget_ci->slot_status & SLOTSTATUS_RESET) { - if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) { - budget_ci->slot_status = SLOTSTATUS_READY; - } - } - } else { - budget_ci->slot_status = SLOTSTATUS_NONE; - } - - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - if (budget_ci->slot_status & SLOTSTATUS_READY) { - return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; - } - return DVB_CA_EN50221_POLL_CAM_PRESENT; - } - - return 0; -} - static int ciintf_init(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; int flags; int result; - int ci_version; - int ca_flags; memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221)); @@ -424,29 +379,16 @@ static int ciintf_init(struct budget_ci *budget_ci) saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800); // test if it is there - ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0); - if ((ci_version & 0xa0) != 0xa0) { + if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) { result = -ENODEV; goto error; } - // determine whether a CAM is present or not flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); budget_ci->slot_status = SLOTSTATUS_NONE; if (flags & CICONTROL_CAMDETECT) budget_ci->slot_status = SLOTSTATUS_PRESENT; - // version 0xa2 of the CI firmware doesn't generate interrupts - if (ci_version == 0xa2) { - ca_flags = 0; - budget_ci->ci_irq = 0; - } else { - ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | - DVB_CA_EN50221_FLAG_IRQ_FR | - DVB_CA_EN50221_FLAG_IRQ_DA; - budget_ci->ci_irq = 1; - } - // register CI interface budget_ci->ca.owner = THIS_MODULE; budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem; @@ -456,27 +398,23 @@ static int ciintf_init(struct budget_ci *budget_ci) budget_ci->ca.slot_reset = ciintf_slot_reset; budget_ci->ca.slot_shutdown = ciintf_slot_shutdown; budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; - budget_ci->ca.poll_slot_status = ciintf_poll_slot_status; budget_ci->ca.data = budget_ci; if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, &budget_ci->ca, - ca_flags, 1)) != 0) { + DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | + DVB_CA_EN50221_FLAG_IRQ_FR | + DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) { printk("budget_ci: CI interface detected, but initialisation failed.\n"); goto error; } - // Setup CI slot IRQ - if (budget_ci->ci_irq) { - tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - } else { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } - saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); + tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); + if (budget_ci->slot_status != SLOTSTATUS_NONE) { + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); + } else { + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); } - - // enable interface + saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET, 1, 0); @@ -485,12 +423,10 @@ static int ciintf_init(struct budget_ci *budget_ci) budget_ci->budget.ci_present = 1; // forge a fake CI IRQ so the CAM state is setup correctly - if (budget_ci->ci_irq) { - flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; - if (budget_ci->slot_status != SLOTSTATUS_NONE) - flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); - } + flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; + if (budget_ci->slot_status != SLOTSTATUS_NONE) + flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; + dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); return 0; @@ -504,13 +440,9 @@ static void ciintf_deinit(struct budget_ci *budget_ci) struct saa7146_dev *saa = budget_ci->budget.dev; // disable CI interrupts - if (budget_ci->ci_irq) { - saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03); - saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ciintf_irq_tasklet); - } - - // reset interface + saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03); + saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); + tasklet_kill(&budget_ci->ciintf_irq_tasklet); ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); msleep(1); ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, @@ -538,10 +470,127 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr) if (*isr & MASK_10) ttpci_budget_irq10_handler(dev, isr); - if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq)) + if ((*isr & MASK_03) && (budget_ci->budget.ci_present)) tasklet_schedule(&budget_ci->ciintf_irq_tasklet); } + +static u8 alps_bsru6_inittab[] = { + 0x01, 0x15, + 0x02, 0x00, + 0x03, 0x00, + 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ + 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x40, /* DAC not used, set to high impendance mode */ + 0x07, 0x00, /* DAC LSB */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ + 0x09, 0x00, /* FIFO */ + 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ + 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ + 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ + 0x10, 0x3f, // AGC2 0x3d + 0x11, 0x84, + 0x12, 0xb9, + 0x15, 0xc9, // lock detector threshold + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, + 0x1f, 0x50, + 0x20, 0x00, + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 + 0x29, 0x1e, // 1/2 threshold + 0x2a, 0x14, // 2/3 threshold + 0x2b, 0x0f, // 3/4 threshold + 0x2c, 0x09, // 5/6 threshold + 0x2d, 0x05, // 7/8 threshold + 0x2e, 0x01, + 0x31, 0x1f, // test all FECs + 0x32, 0x19, // viterbi and synchro search + 0x33, 0xfc, // rs control + 0x34, 0x93, // error control + 0x0f, 0x52, + 0xff, 0xff +}; + +static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) +{ + u8 aclk = 0; + u8 bclk = 0; + + if (srate < 1500000) { + aclk = 0xb7; + bclk = 0x47; + } else if (srate < 3000000) { + aclk = 0xb7; + bclk = 0x4b; + } else if (srate < 7000000) { + aclk = 0xb7; + bclk = 0x4f; + } else if (srate < 14000000) { + aclk = 0xb7; + bclk = 0x53; + } else if (srate < 30000000) { + aclk = 0xb6; + bclk = 0x53; + } else if (srate < 45000000) { + aclk = 0xb4; + bclk = 0x51; + } + + stv0299_writereg(fe, 0x13, aclk); + stv0299_writereg(fe, 0x14, bclk); + stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); + stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); + stv0299_writereg(fe, 0x21, (ratio) & 0xf0); + + return 0; +} + +static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) +{ + u8 buf[4]; + u32 div; + struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; + + if ((params->frequency < 950000) || (params->frequency > 2150000)) + return -EINVAL; + + div = (params->frequency + (125 - 1)) / 125; // round correctly + buf[0] = (div >> 8) & 0x7f; + buf[1] = div & 0xff; + buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; + buf[3] = 0xC4; + + if (params->frequency > 1530000) + buf[3] = 0xc0; + + if (i2c_transfer(i2c, &msg, 1) != 1) + return -EIO; + return 0; +} + +static struct stv0299_config alps_bsru6_config = { + + .demod_address = 0x68, + .inittab = alps_bsru6_inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .lock_output = STV0229_LOCKOUTPUT_1, + .volt13_op0_op1 = STV0299_VOLT13_OP1, + .min_delay_ms = 100, + .set_symbol_rate = alps_bsru6_set_symbol_rate, + .pll_set = alps_bsru6_pll_set, +}; + + + + static u8 philips_su1278_tt_inittab[] = { 0x01, 0x0f, 0x02, 0x30, @@ -1020,20 +1069,6 @@ static void frontend_init(struct budget_ci *budget_ci) break; } break; - - case 0x1017: // TT S-1500 PCI - budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; - if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { - printk("%s: No LNBP21 found!\n", __FUNCTION__); - if (budget_ci->budget.dvb_frontend->ops->release) - budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - - break; } if (budget_ci->budget.dvb_frontend == NULL) { @@ -1111,7 +1146,6 @@ static int budget_ci_detach(struct saa7146_dev *dev) static struct saa7146_extension budget_extension; -MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); @@ -1123,7 +1157,6 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010), MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), - MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), { .vendor = 0, } @@ -1132,7 +1165,7 @@ static struct pci_device_id pci_tbl[] = { MODULE_DEVICE_TABLE(pci, pci_tbl); static struct saa7146_extension budget_extension = { - .name = "budget_ci dvb", + .name = "budget_ci dvb\0", .flags = SAA7146_I2C_SHORT_DELAY, .module = THIS_MODULE, diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index ea2066d46..633e68c34 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c @@ -39,21 +39,9 @@ #include "budget.h" #include "ttpci-eeprom.h" -#define TS_WIDTH (2 * TS_SIZE) -#define TS_WIDTH_ACTIVY TS_SIZE -#define TS_HEIGHT_MASK 0xf00 -#define TS_HEIGHT_MASK_ACTIVY 0xc00 -#define TS_MIN_BUFSIZE_K 188 -#define TS_MAX_BUFSIZE_K 1410 -#define TS_MAX_BUFSIZE_K_ACTIVY 564 -#define BUFFER_WARNING_WAIT (30*HZ) - int budget_debug; -static int dma_buffer_size = TS_MIN_BUFSIZE_K; module_param_named(debug, budget_debug, int, 0644); -module_param_named(bufsize, dma_buffer_size, int, 0444); MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off)."); -MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)"); /**************************************************************************** * TT budget / WinTV Nova @@ -82,10 +70,11 @@ static int start_ts_capture(struct budget *budget) saa7146_write(dev, MC1, MASK_20); // DMA3 off - memset(budget->grabbing, 0x00, budget->buffer_size); + memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH); saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000)); + budget->tsf = 0xff; budget->ttbp = 0; /* @@ -126,12 +115,16 @@ static int start_ts_capture(struct budget *budget) saa7146_write(dev, BASE_ODD3, 0); saa7146_write(dev, BASE_EVEN3, 0); - saa7146_write(dev, PROT_ADDR3, budget->buffer_size); + saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT); saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); - saa7146_write(dev, PITCH3, budget->buffer_width); - saa7146_write(dev, NUM_LINE_BYTE3, - (budget->buffer_height << 16) | budget->buffer_width); + if (budget->card->type == BUDGET_FS_ACTIVY) { + saa7146_write(dev, PITCH3, TS_WIDTH / 2); + saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT * 2) << 16) | (TS_WIDTH / 2)); + } else { + saa7146_write(dev, PITCH3, TS_WIDTH); + saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH); + } saa7146_write(dev, MC2, (MASK_04 | MASK_20)); @@ -148,12 +141,11 @@ static void vpeirq(unsigned long data) u8 *mem = (u8 *) (budget->grabbing); u32 olddma = budget->ttbp; u32 newdma = saa7146_read(budget->dev, PCI_VDP3); - u32 count; /* nearest lower position divisible by 188 */ newdma -= newdma % 188; - if (newdma >= budget->buffer_size) + if (newdma >= TS_BUFLEN) return; budget->ttbp = newdma; @@ -162,24 +154,11 @@ static void vpeirq(unsigned long data) return; if (newdma > olddma) { /* no wraparound, dump olddma..newdma */ - count = newdma - olddma; - dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188); + dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, (newdma - olddma) / 188); } else { /* wraparound, dump olddma..buflen and 0..newdma */ - count = budget->buffer_size - olddma; - dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188); - count += newdma; + dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, (TS_BUFLEN - olddma) / 188); dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188); } - - if (count > budget->buffer_warning_threshold) - budget->buffer_warnings++; - - if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) { - printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n", - budget->dev->name, __FUNCTION__, budget->buffer_warnings, count); - budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT; - budget->buffer_warnings = 0; - } } @@ -362,10 +341,9 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, struct saa7146_pci_extension_data *info, struct module *owner) { + int length = TS_WIDTH * TS_HEIGHT; int ret = 0; struct budget_info *bi = info->ext_priv; - int max_bufsize; - int height_mask; memset(budget, 0, sizeof(struct budget)); @@ -374,32 +352,6 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, budget->card = bi; budget->dev = (struct saa7146_dev *) dev; - if (budget->card->type == BUDGET_FS_ACTIVY) { - budget->buffer_width = TS_WIDTH_ACTIVY; - max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; - height_mask = TS_HEIGHT_MASK_ACTIVY; - } else { - budget->buffer_width = TS_WIDTH; - max_bufsize = TS_MAX_BUFSIZE_K; - height_mask = TS_HEIGHT_MASK; - } - - if (dma_buffer_size < TS_MIN_BUFSIZE_K) - dma_buffer_size = TS_MIN_BUFSIZE_K; - else if (dma_buffer_size > max_bufsize) - dma_buffer_size = max_bufsize; - - budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width; - budget->buffer_height &= height_mask; - budget->buffer_size = budget->buffer_height * budget->buffer_width; - budget->buffer_warning_threshold = budget->buffer_size * 80/100; - budget->buffer_warnings = 0; - budget->buffer_warning_time = jiffies; - - dprintk(2, "%s: width = %d, height = %d\n", - budget->dev->name, budget->buffer_width, budget->buffer_height); - printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); - dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner); /* set dd1 stream a & b */ @@ -440,7 +392,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac); if (NULL == - (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt))) { + (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, length, &budget->pt))) { ret = -ENOMEM; goto err; } diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index 05d63b6bd..fc416cf52 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c @@ -37,8 +37,6 @@ #include "ves1x93.h" #include "tda8083.h" -#include "bsru6.h" - #define budget_patch budget static struct saa7146_extension budget_extension; @@ -292,6 +290,103 @@ static struct ves1x93_config alps_bsrv2_config = { .pll_set = alps_bsrv2_pll_set, }; +static u8 alps_bsru6_inittab[] = { + 0x01, 0x15, + 0x02, 0x00, + 0x03, 0x00, + 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ + 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x40, /* DAC not used, set to high impendance mode */ + 0x07, 0x00, /* DAC LSB */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ + 0x09, 0x00, /* FIFO */ + 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ + 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ + 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ + 0x10, 0x3f, // AGC2 0x3d + 0x11, 0x84, + 0x12, 0xb9, + 0x15, 0xc9, // lock detector threshold + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, + 0x1f, 0x50, + 0x20, 0x00, + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 + 0x29, 0x1e, // 1/2 threshold + 0x2a, 0x14, // 2/3 threshold + 0x2b, 0x0f, // 3/4 threshold + 0x2c, 0x09, // 5/6 threshold + 0x2d, 0x05, // 7/8 threshold + 0x2e, 0x01, + 0x31, 0x1f, // test all FECs + 0x32, 0x19, // viterbi and synchro search + 0x33, 0xfc, // rs control + 0x34, 0x93, // error control + 0x0f, 0x52, + 0xff, 0xff +}; + +static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) +{ + u8 aclk = 0; + u8 bclk = 0; + + if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } + else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } + else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } + else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } + else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } + else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } + + stv0299_writereg (fe, 0x13, aclk); + stv0299_writereg (fe, 0x14, bclk); + stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); + stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); + stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); + + return 0; +} + +static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) +{ + u8 data[4]; + u32 div; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; + + if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL; + + div = (params->frequency + (125 - 1)) / 125; // round correctly + data[0] = (div >> 8) & 0x7f; + data[1] = div & 0xff; + data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; + data[3] = 0xC4; + + if (params->frequency > 1530000) data[3] = 0xc0; + + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; + return 0; +} + +static struct stv0299_config alps_bsru6_config = { + + .demod_address = 0x68, + .inittab = alps_bsru6_inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .lock_output = STV0229_LOCKOUTPUT_1, + .volt13_op0_op1 = STV0299_VOLT13_OP1, + .min_delay_ms = 100, + .set_symbol_rate = alps_bsru6_set_symbol_rate, + .pll_set = alps_bsru6_pll_set, +}; + static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; @@ -577,17 +672,6 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // Set RPS1 Address register to point to RPS code (r108 p42) saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); - - if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL))) - return -ENOMEM; - - dprintk(2, "budget: %p\n", budget); - - if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) { - kfree (budget); - return err; - } - // Set Source Line Counter Threshold, using BRS (rCC p43) // It generates HS event every TS_HEIGHT lines // this is related to TS_WIDTH set in register @@ -596,13 +680,24 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte //,then RPS_THRESH1 // should be set to trigger every TS_HEIGHT (512) lines. // - saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 ); + saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 ); // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 ); // Enable RPS1 (rFC p33) saa7146_write(dev, MC1, (MASK_13 | MASK_29)); + if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL))) + return -ENOMEM; + + dprintk(2, "budget: %p\n", budget); + + if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) { + kfree (budget); + return err; + } + + dev->ext_priv = budget; budget->dvb_adapter.priv = budget; @@ -636,7 +731,7 @@ static void __exit budget_patch_exit(void) } static struct saa7146_extension budget_extension = { - .name = "budget_patch dvb", + .name = "budget_patch dvb\0", .flags = 0, .module = THIS_MODULE, diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index d6d37cf02..fab7d8d69 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -41,8 +41,6 @@ #include "l64781.h" #include "tda8083.h" #include "s5h1420.h" -#include "lnbp21.h" -#include "bsru6.h" static void Set22K (struct budget *budget, int state) { @@ -186,6 +184,64 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m return 0; } +static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +{ + struct budget* budget = (struct budget*) fe->dvb->priv; + u8 buf; + struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) }; + + if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + + switch(voltage) { + case SEC_VOLTAGE_13: + buf = (buf & 0xf7) | 0x04; + break; + + case SEC_VOLTAGE_18: + buf = (buf & 0xf7) | 0x0c; + break; + + case SEC_VOLTAGE_OFF: + buf = buf & 0xf0; + break; + } + + msg.flags = 0; + if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + + return 0; +} + +static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg) +{ + struct budget* budget = (struct budget*) fe->dvb->priv; + u8 buf; + struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) }; + + if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + + if (arg) { + buf = buf | 0x10; + } else { + buf = buf & 0xef; + } + + msg.flags = 0; + if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + + return 0; +} + +static int lnbp21_init(struct budget* budget) +{ + u8 buf = 0x00; + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) }; + + if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) + return -EIO; + return 0; +} + static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget* budget = (struct budget*) fe->dvb->priv; @@ -221,6 +277,176 @@ static struct ves1x93_config alps_bsrv2_config = .pll_set = alps_bsrv2_pll_set, }; +static u8 alps_bsru6_inittab[] = { + 0x01, 0x15, + 0x02, 0x00, + 0x03, 0x00, + 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ + 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x40, /* DAC not used, set to high impendance mode */ + 0x07, 0x00, /* DAC LSB */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ + 0x09, 0x00, /* FIFO */ + 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ + 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ + 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ + 0x10, 0x3f, // AGC2 0x3d + 0x11, 0x84, + 0x12, 0xb9, + 0x15, 0xc9, // lock detector threshold + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, + 0x1f, 0x50, + 0x20, 0x00, + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 + 0x29, 0x1e, // 1/2 threshold + 0x2a, 0x14, // 2/3 threshold + 0x2b, 0x0f, // 3/4 threshold + 0x2c, 0x09, // 5/6 threshold + 0x2d, 0x05, // 7/8 threshold + 0x2e, 0x01, + 0x31, 0x1f, // test all FECs + 0x32, 0x19, // viterbi and synchro search + 0x33, 0xfc, // rs control + 0x34, 0x93, // error control + 0x0f, 0x52, + 0xff, 0xff +}; + +static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) +{ + u8 aclk = 0; + u8 bclk = 0; + + if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } + else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } + else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } + else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } + else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } + else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } + + stv0299_writereg (fe, 0x13, aclk); + stv0299_writereg (fe, 0x14, bclk); + stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); + stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); + stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); + + return 0; +} + +static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) +{ + u8 data[4]; + u32 div; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; + + if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL; + + div = (params->frequency + (125 - 1)) / 125; // round correctly + data[0] = (div >> 8) & 0x7f; + data[1] = div & 0xff; + data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; + data[3] = 0xC4; + + if (params->frequency > 1530000) data[3] = 0xc0; + + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; + return 0; +} + +static struct stv0299_config alps_bsru6_config = { + + .demod_address = 0x68, + .inittab = alps_bsru6_inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .lock_output = STV0229_LOCKOUTPUT_1, + .volt13_op0_op1 = STV0299_VOLT13_OP1, + .min_delay_ms = 100, + .set_symbol_rate = alps_bsru6_set_symbol_rate, + .pll_set = alps_bsru6_pll_set, +}; + +static u8 alps_bsbe1_inittab[] = { + 0x01, 0x15, + 0x02, 0x30, + 0x03, 0x00, + 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ + 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x40, /* DAC not used, set to high impendance mode */ + 0x07, 0x00, /* DAC LSB */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ + 0x09, 0x00, /* FIFO */ + 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ + 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ + 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ + 0x10, 0x3f, // AGC2 0x3d + 0x11, 0x84, + 0x12, 0xb9, + 0x15, 0xc9, // lock detector threshold + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, + 0x1f, 0x50, + 0x20, 0x00, + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 + 0x29, 0x1e, // 1/2 threshold + 0x2a, 0x14, // 2/3 threshold + 0x2b, 0x0f, // 3/4 threshold + 0x2c, 0x09, // 5/6 threshold + 0x2d, 0x05, // 7/8 threshold + 0x2e, 0x01, + 0x31, 0x1f, // test all FECs + 0x32, 0x19, // viterbi and synchro search + 0x33, 0xfc, // rs control + 0x34, 0x93, // error control + 0x0f, 0x92, // 0x80 = inverse AGC + 0xff, 0xff +}; + +static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) +{ + int ret; + u8 data[4]; + u32 div; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; + + if ((params->frequency < 950000) || (params->frequency > 2150000)) + return -EINVAL; + + div = (params->frequency + (125 - 1)) / 125; // round correctly + data[0] = (div >> 8) & 0x7f; + data[1] = div & 0xff; + data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; + data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; + + ret = i2c_transfer(i2c, &msg, 1); + return (ret != 1) ? -EIO : 0; +} + +static struct stv0299_config alps_bsbe1_config = { + .demod_address = 0x68, + .inittab = alps_bsbe1_inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .min_delay_ms = 100, + .set_symbol_rate = alps_bsru6_set_symbol_rate, + .pll_set = alps_bsbe1_pll_set, +}; + static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget* budget = (struct budget*) fe->dvb->priv; @@ -354,6 +580,20 @@ static u8 read_pwm(struct budget* budget) static void frontend_init(struct budget *budget) { switch(budget->dev->pci->subsystem_device) { + case 0x1017: + // try the ALPS BSBE1 now + budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap); + if (budget->dvb_frontend) { + budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; + budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; + budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; + if (lnbp21_init(budget)) { + printk("%s: No LNBP21 found!\n", __FUNCTION__); + goto error_out; + } + } + + break; case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) case 0x1013: // try the ALPS BSRV2 first of all @@ -400,7 +640,9 @@ static void frontend_init(struct budget *budget) case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); if (budget->dvb_frontend) { - if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { + budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; + budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; + if (lnbp21_init(budget)) { printk("%s: No LNBP21 found!\n", __FUNCTION__); goto error_out; } @@ -471,6 +713,7 @@ static int budget_detach (struct saa7146_dev* dev) static struct saa7146_extension budget_extension; +MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT); MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); @@ -483,6 +726,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), + MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), @@ -494,7 +738,7 @@ static struct pci_device_id pci_tbl[] = { MODULE_DEVICE_TABLE(pci, pci_tbl); static struct saa7146_extension budget_extension = { - .name = "budget dvb", + .name = "budget dvb\0", .flags = SAA7146_I2C_SHORT_DELAY, .module = THIS_MODULE, diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h index ecea3a130..c7bb63c4d 100644 --- a/drivers/media/dvb/ttpci/budget.h +++ b/drivers/media/dvb/ttpci/budget.h @@ -10,8 +10,6 @@ #include "dvb_net.h" #include -#include - #include extern int budget_debug; @@ -53,18 +51,12 @@ struct budget { struct dmx_frontend mem_frontend; int fe_synced; - struct mutex pid_mutex; + struct semaphore pid_mutex; int ci_present; int video_port; - u32 buffer_width; - u32 buffer_height; - u32 buffer_size; - u32 buffer_warning_threshold; - u32 buffer_warnings; - unsigned long buffer_warning_time; - + u8 tsf; u32 ttbp; int feeding; @@ -85,6 +77,11 @@ static struct saa7146_pci_extension_data x_var = { \ .ext_priv = &x_var ## _info, \ .ext = &budget_extension }; +#define TS_WIDTH (376) +#define TS_HEIGHT (512) +#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT) +#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE) + #define BUDGET_TT 0 #define BUDGET_TT_HW_DISEQC 1 #define BUDGET_PATCH 3 diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 6ceae3812..5a13c4744 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "dvb_frontend.h" #include "dmxdev.h" @@ -35,6 +35,7 @@ #include #include + /* TTUSB_HWSECTIONS: the DSP supports filtering in hardware, however, since the "muxstream" @@ -82,8 +83,8 @@ struct ttusb { struct dvb_net dvbnet; /* and one for USB access. */ - struct mutex semi2c; - struct mutex semusb; + struct semaphore semi2c; + struct semaphore semusb; struct dvb_adapter adapter; struct usb_device *dev; @@ -149,7 +150,7 @@ static int ttusb_cmd(struct ttusb *ttusb, printk("\n"); #endif - if (mutex_lock_interruptible(&ttusb->semusb) < 0) + if (down_interruptible(&ttusb->semusb) < 0) return -EAGAIN; err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe, @@ -157,13 +158,13 @@ static int ttusb_cmd(struct ttusb *ttusb, if (err != 0) { dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n", __FUNCTION__, err); - mutex_unlock(&ttusb->semusb); + up(&ttusb->semusb); return err; } if (actual_len != len) { dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__, actual_len, len); - mutex_unlock(&ttusb->semusb); + up(&ttusb->semusb); return -1; } @@ -173,7 +174,7 @@ static int ttusb_cmd(struct ttusb *ttusb, if (err != 0) { printk("%s: failed, receive error %d\n", __FUNCTION__, err); - mutex_unlock(&ttusb->semusb); + up(&ttusb->semusb); return err; } #if DEBUG >= 3 @@ -184,14 +185,14 @@ static int ttusb_cmd(struct ttusb *ttusb, printk("\n"); #endif if (!needresult) - mutex_unlock(&ttusb->semusb); + up(&ttusb->semusb); return 0; } static int ttusb_result(struct ttusb *ttusb, u8 * data, int len) { memcpy(data, ttusb->last_result, len); - mutex_unlock(&ttusb->semusb); + up(&ttusb->semusb); return 0; } @@ -249,7 +250,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num int i = 0; int inc; - if (mutex_lock_interruptible(&ttusb->semi2c) < 0) + if (down_interruptible(&ttusb->semi2c) < 0) return -EAGAIN; while (i < num) { @@ -283,7 +284,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num i += inc; } - mutex_unlock(&ttusb->semi2c); + up(&ttusb->semi2c); return i; } @@ -688,7 +689,8 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) memcpy(ttusb->muxpack + ttusb->muxpack_ptr, data, avail); ttusb->muxpack_ptr += avail; - BUG_ON(ttusb->muxpack_ptr > 264); + if (ttusb->muxpack_ptr > 264) + BUG(); data += avail; len -= avail; /* determine length */ @@ -1493,11 +1495,8 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ttusb->dev = udev; ttusb->c = 0; ttusb->mux_state = 0; - mutex_init(&ttusb->semi2c); - - mutex_lock(&ttusb->semi2c); - - mutex_init(&ttusb->semusb); + sema_init(&ttusb->semi2c, 0); + sema_init(&ttusb->semusb, 1); ttusb_setup_interfaces(ttusb); @@ -1505,13 +1504,9 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i if (ttusb_init_controller(ttusb)) printk("ttusb_init_controller: error\n"); - mutex_unlock(&ttusb->semi2c); + up(&ttusb->semi2c); - if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE)) < 0) { - ttusb_free_iso_urbs(ttusb); - kfree(ttusb); - return result; - } + dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE); ttusb->adapter.priv = ttusb; /* i2c */ diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 44dea3211..df831171e 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -20,8 +20,7 @@ * */ -#include - +#include #include #include #include @@ -116,7 +115,7 @@ struct ttusb_dec { unsigned int out_pipe; unsigned int irq_pipe; enum ttusb_dec_interface interface; - struct mutex usb_mutex; + struct semaphore usb_sem; void *irq_buffer; struct urb *irq_urb; @@ -125,7 +124,7 @@ struct ttusb_dec { dma_addr_t iso_dma_handle; struct urb *iso_urb[ISO_BUF_COUNT]; int iso_stream_count; - struct mutex iso_mutex; + struct semaphore iso_sem; u8 packet[MAX_PVA_LENGTH + 4]; enum ttusb_dec_packet_type packet_type; @@ -274,9 +273,9 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (!b) return -ENOMEM; - if ((result = mutex_lock_interruptible(&dec->usb_mutex))) { + if ((result = down_interruptible(&dec->usb_sem))) { kfree(b); - printk("%s: Failed to lock usb mutex.\n", __FUNCTION__); + printk("%s: Failed to down usb semaphore.\n", __FUNCTION__); return result; } @@ -301,7 +300,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: command bulk message failed: error %d\n", __FUNCTION__, result); - mutex_unlock(&dec->usb_mutex); + up(&dec->usb_sem); kfree(b); return result; } @@ -312,7 +311,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: result bulk message failed: error %d\n", __FUNCTION__, result); - mutex_unlock(&dec->usb_mutex); + up(&dec->usb_sem); kfree(b); return result; } else { @@ -328,7 +327,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (cmd_result && b[3] > 0) memcpy(cmd_result, &b[4], b[3]); - mutex_unlock(&dec->usb_mutex); + up(&dec->usb_sem); kfree(b); return 0; @@ -836,7 +835,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) dprintk("%s\n", __FUNCTION__); - if (mutex_lock_interruptible(&dec->iso_mutex)) + if (down_interruptible(&dec->iso_sem)) return; dec->iso_stream_count--; @@ -846,7 +845,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) usb_kill_urb(dec->iso_urb[i]); } - mutex_unlock(&dec->iso_mutex); + up(&dec->iso_sem); } /* Setting the interface of the DEC tends to take down the USB communications @@ -891,7 +890,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) dprintk("%s\n", __FUNCTION__); - if (mutex_lock_interruptible(&dec->iso_mutex)) + if (down_interruptible(&dec->iso_sem)) return -EAGAIN; if (!dec->iso_stream_count) { @@ -912,7 +911,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) i--; } - mutex_unlock(&dec->iso_mutex); + up(&dec->iso_sem); return result; } } @@ -920,7 +919,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) dec->iso_stream_count++; - mutex_unlock(&dec->iso_mutex); + up(&dec->iso_sem); return 0; } @@ -1230,8 +1229,8 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) { dprintk("%s\n", __FUNCTION__); - mutex_init(&dec->usb_mutex); - mutex_init(&dec->iso_mutex); + sema_init(&dec->usb_sem, 1); + sema_init(&dec->iso_sem, 1); dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE); dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE); diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 3fff75763..d318be383 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -7,7 +7,7 @@ menu "Radio Adapters" config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these AM/FM radio cards, and then fill in the port address below. @@ -25,7 +25,7 @@ config RADIO_CADET config RADIO_RTRACK tristate "AIMSlab RadioTrack (aka RadioReveal) support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. @@ -59,7 +59,7 @@ config RADIO_RTRACK_PORT config RADIO_RTRACK2 tristate "AIMSlab RadioTrack II support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. @@ -82,7 +82,7 @@ config RADIO_RTRACK2_PORT config RADIO_AZTECH tristate "Aztech/Packard Bell Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. @@ -106,7 +106,7 @@ config RADIO_AZTECH_PORT config RADIO_GEMTEK tristate "GemTek Radio Card support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. @@ -131,7 +131,7 @@ config RADIO_GEMTEK_PORT config RADIO_GEMTEK_PCI tristate "GemTek PCI Radio Card support" - depends on VIDEO_V4L1 && PCI + depends on VIDEO_DEV && PCI ---help--- Choose Y here if you have this PCI FM radio card. @@ -145,7 +145,7 @@ config RADIO_GEMTEK_PCI config RADIO_MAXIRADIO tristate "Guillemot MAXI Radio FM 2000 radio" - depends on VIDEO_V4L1 && PCI + depends on VIDEO_DEV && PCI ---help--- Choose Y here if you have this radio card. This card may also be found as Gemtek PCI FM. @@ -160,7 +160,7 @@ config RADIO_MAXIRADIO config RADIO_MAESTRO tristate "Maestro on board radio" - depends on VIDEO_V4L1 + depends on VIDEO_DEV ---help--- Say Y here to directly support the on-board radio tuner on the Maestro 2 or 2E sound card. @@ -175,7 +175,7 @@ config RADIO_MAESTRO config RADIO_MIROPCM20 tristate "miroSOUND PCM20 radio" - depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER + depends on ISA && VIDEO_DEV && SOUND_ACI_MIXER ---help--- Choose Y here if you have this FM radio card. You also need to say Y to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound") @@ -208,7 +208,7 @@ config RADIO_MIROPCM20_RDS config RADIO_SF16FMI tristate "SF16FMI Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards. If you compile the driver into the kernel and your card is not PnP one, you @@ -225,7 +225,7 @@ config RADIO_SF16FMI config RADIO_SF16FMR2 tristate "SF16FMR2 Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards. @@ -239,7 +239,7 @@ config RADIO_SF16FMR2 config RADIO_TERRATEC tristate "TerraTec ActiveRadio ISA Standalone" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. (TODO) @@ -268,7 +268,7 @@ config RADIO_TERRATEC_PORT config RADIO_TRUST tristate "Trust FM radio card" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV help This is a driver for the Trust FM radio cards. Say Y if you have such a card and want to use it under Linux. @@ -286,7 +286,7 @@ config RADIO_TRUST_PORT config RADIO_TYPHOON tristate "Typhoon Radio (a.k.a. EcoRadio)" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address and the frequency used for muting below. @@ -330,7 +330,7 @@ config RADIO_TYPHOON_MUTEFREQ config RADIO_ZOLTRIX tristate "Zoltrix Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_DEV ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. diff --git a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c index b602c73e2..a917a90cb 100644 --- a/drivers/media/radio/miropcm20-rds-core.c +++ b/drivers/media/radio/miropcm20-rds-core.c @@ -18,15 +18,14 @@ #include #include #include -#include - +#include #include #include "../../../sound/oss/aci.h" #include "miropcm20-rds-core.h" #define DEBUG 0 -static struct mutex aci_rds_mutex; +static struct semaphore aci_rds_sem; #define RDS_DATASHIFT 2 /* Bit 2 */ #define RDS_DATAMASK (1 << RDS_DATASHIFT) @@ -182,7 +181,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize) { int ret; - if (mutex_lock_interruptible(&aci_rds_mutex)) + if (down_interruptible(&aci_rds_sem)) return -EINTR; rds_write(cmd); @@ -193,7 +192,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize) else ret = 0; - mutex_unlock(&aci_rds_mutex); + up(&aci_rds_sem); return ret; } @@ -201,7 +200,7 @@ EXPORT_SYMBOL(aci_rds_cmd); int __init attach_aci_rds(void) { - mutex_init(&aci_rds_mutex); + init_MUTEX(&aci_rds_sem); return 0; } diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 557fb5c4a..914deab4e 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -43,7 +43,7 @@ static int io = CONFIG_RADIO_RTRACK_PORT; static int radio_nr = -1; -static struct mutex lock; +static struct semaphore lock; struct rt_device { @@ -83,23 +83,23 @@ static void rt_incvol(void) static void rt_mute(struct rt_device *dev) { dev->muted = 1; - mutex_lock(&lock); + down(&lock); outb(0xd0, io); /* volume steady, off */ - mutex_unlock(&lock); + up(&lock); } static int rt_setvol(struct rt_device *dev, int vol) { int i; - mutex_lock(&lock); + down(&lock); if(vol == dev->curvol) { /* requested volume = current */ if (dev->muted) { /* user is unmuting the card */ dev->muted = 0; outb (0xd8, io); /* enable card */ } - mutex_unlock(&lock); + up(&lock); return 0; } @@ -108,7 +108,7 @@ static int rt_setvol(struct rt_device *dev, int vol) sleep_delay(2000000); /* make sure it's totally down */ outb(0xd0, io); /* volume steady, off */ dev->curvol = 0; /* track the volume state! */ - mutex_unlock(&lock); + up(&lock); return 0; } @@ -121,7 +121,7 @@ static int rt_setvol(struct rt_device *dev, int vol) rt_decvol(); dev->curvol = vol; - mutex_unlock(&lock); + up(&lock); return 0; } @@ -168,7 +168,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) freq += 171200; /* Add 10.7 MHz IF */ freq /= 800; /* Convert to 50 kHz units */ - mutex_lock(&lock); /* Stop other ops interfering */ + down(&lock); /* Stop other ops interfering */ send_0_byte (io, dev); /* 0: LSB of frequency */ @@ -196,7 +196,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) else outb (0xd8, io); /* volume steady + sigstr + on */ - mutex_unlock(&lock); + up(&lock); return 0; } @@ -337,7 +337,7 @@ static int __init rtrack_init(void) /* Set up the I/O locking */ - mutex_init(&lock); + init_MUTEX(&lock); /* mute card - prevents noisy bootups */ diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 83bdae234..523be820f 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -42,7 +42,7 @@ static int io = CONFIG_RADIO_AZTECH_PORT; static int radio_nr = -1; static int radio_wait_time = 1000; -static struct mutex lock; +static struct semaphore lock; struct az_device { @@ -87,9 +87,9 @@ static void send_1_byte (struct az_device *dev) static int az_setvol(struct az_device *dev, int vol) { - mutex_lock(&lock); + down(&lock); outb (volconvert(vol), io); - mutex_unlock(&lock); + up(&lock); return 0; } @@ -122,7 +122,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) frequency += 171200; /* Add 10.7 MHz IF */ frequency /= 800; /* Convert to 50 kHz units */ - mutex_lock(&lock); + down(&lock); send_0_byte (dev); /* 0: LSB of frequency */ @@ -152,7 +152,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) udelay (radio_wait_time); outb_p(128+64+volconvert(dev->curvol), io); - mutex_unlock(&lock); + up(&lock); return 0; } @@ -283,7 +283,7 @@ static int __init aztech_init(void) return -EBUSY; } - mutex_init(&lock); + init_MUTEX(&lock); aztech_radio.priv=&aztech_unit; if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 39c1d9118..36c9f5bf8 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -23,11 +23,10 @@ #include #include #include -#include +#include #include #include - #define DRIVER_VERSION "0.05" #define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ @@ -105,7 +104,7 @@ struct radio_device { muted, /* VIDEO_AUDIO_MUTE */ stereo, /* VIDEO_TUNER_STEREO_ON */ tuned; /* signal strength (0 or 0xffff) */ - struct mutex lock; + struct semaphore lock; }; static u32 radio_bits_get(struct radio_device *dev) @@ -259,9 +258,9 @@ static int radio_ioctl(struct inode *inode, struct file *file, struct radio_device *card = video_get_drvdata(dev); int ret; - mutex_lock(&card->lock); + down(&card->lock); ret = video_usercopy(inode, file, cmd, arg, radio_function); - mutex_unlock(&card->lock); + up(&card->lock); return ret; } @@ -312,7 +311,7 @@ static int __devinit maestro_probe(struct pci_dev *pdev, } radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA; - mutex_init(&radio_unit->lock); + init_MUTEX(&radio_unit->lock); maestro_radio_inst = video_device_alloc(); if (maestro_radio_inst == NULL) { diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index f0bf47bcb..c975ddd86 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -37,8 +37,7 @@ #include #include #include -#include - +#include #include #include @@ -102,7 +101,7 @@ static struct radio_device unsigned long freq; - struct mutex lock; + struct semaphore lock; } radio_unit = {0, 0, 0, 0, }; @@ -268,9 +267,9 @@ static int radio_ioctl(struct inode *inode, struct file *file, struct radio_device *card=dev->priv; int ret; - mutex_lock(&card->lock); + down(&card->lock); ret = video_usercopy(inode, file, cmd, arg, radio_function); - mutex_unlock(&card->lock); + up(&card->lock); return ret; } @@ -291,7 +290,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d goto err_out_free_region; radio_unit.io = pci_resource_start(pdev, 0); - mutex_init(&radio_unit.lock); + init_MUTEX(&radio_unit.lock); maxiradio_radio.priv = &radio_unit; if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 53073b424..0229f792a 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -24,7 +24,7 @@ #include #include /* outb, outb_p */ #include /* copy to/from user */ -#include +#include struct fmi_device { @@ -37,7 +37,7 @@ struct fmi_device static int io = -1; static int radio_nr = -1; static struct pnp_dev *dev = NULL; -static struct mutex lock; +static struct semaphore lock; /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ /* It is only useful to give freq in intervall of 800 (=0.05Mhz), @@ -68,16 +68,16 @@ static void outbits(int bits, unsigned int data, int port) static inline void fmi_mute(int port) { - mutex_lock(&lock); + down(&lock); outb(0x00, port); - mutex_unlock(&lock); + up(&lock); } static inline void fmi_unmute(int port) { - mutex_lock(&lock); + down(&lock); outb(0x08, port); - mutex_unlock(&lock); + up(&lock); } static inline int fmi_setfreq(struct fmi_device *dev) @@ -85,12 +85,12 @@ static inline int fmi_setfreq(struct fmi_device *dev) int myport = dev->port; unsigned long freq = dev->curfreq; - mutex_lock(&lock); + down(&lock); outbits(16, RSF16_ENCODE(freq), myport); outbits(8, 0xC0, myport); msleep(143); /* was schedule_timeout(HZ/7) */ - mutex_unlock(&lock); + up(&lock); if (dev->curvol) fmi_unmute(myport); return 0; } @@ -102,7 +102,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) int myport = dev->port; - mutex_lock(&lock); + down(&lock); val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ outb(val, myport); outb(val | 0x10, myport); @@ -110,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) res = (int)inb(myport+1); outb(val, myport); - mutex_unlock(&lock); + up(&lock); return (res & 2) ? 0 : 0xFFFF; } @@ -296,7 +296,7 @@ static int __init fmi_init(void) fmi_unit.flags = VIDEO_TUNER_LOW; fmi_radio.priv = &fmi_unit; - mutex_init(&lock); + init_MUTEX(&lock); if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { release_region(io, 2); diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index bcebd8cb1..099ffb3b9 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -19,9 +19,9 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include +#include -static struct mutex lock; +static struct semaphore lock; #undef DEBUG //#define DEBUG 1 @@ -238,9 +238,9 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, if (fmr2->mute) v->flags |= VIDEO_AUDIO_MUTE; v->mode=VIDEO_MODE_AUTO; - mutex_lock(&lock); + down(&lock); v->signal = fmr2_getsigstr(fmr2); - mutex_unlock(&lock); + up(&lock); return 0; } case VIDIOCSTUNER: @@ -274,9 +274,9 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, /* set card freq (if not muted) */ if (fmr2->curvol && !fmr2->mute) { - mutex_lock(&lock); + down(&lock); fmr2_setfreq(fmr2); - mutex_unlock(&lock); + up(&lock); } return 0; } @@ -318,14 +318,14 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, else printk(KERN_DEBUG "mute\n"); #endif - mutex_lock(&lock); + down(&lock); if (fmr2->curvol && !fmr2->mute) { fmr2_setvolume(fmr2); fmr2_setfreq(fmr2); } else fmr2_mute(fmr2->port); - mutex_unlock(&lock); + up(&lock); return 0; } case VIDIOCGUNIT: @@ -380,7 +380,7 @@ static int __init fmr2_init(void) fmr2_unit.card_type = 0; fmr2_radio.priv = &fmr2_unit; - mutex_init(&lock); + init_MUTEX(&lock); if (request_region(io, 2, "sf16fmr2")) { @@ -397,10 +397,10 @@ static int __init fmr2_init(void) printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io); debug_print((KERN_DEBUG "Mute %d Low %d\n",VIDEO_AUDIO_MUTE,VIDEO_TUNER_LOW)); /* mute card - prevents noisy bootups */ - mutex_lock(&lock); + down(&lock); fmr2_mute(io); fmr2_product_info(&fmr2_unit); - mutex_unlock(&lock); + up(&lock); debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type)); return 0; } diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index e50955836..8ac9a8ef9 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -59,7 +59,7 @@ struct typhoon_device { int muted; unsigned long curfreq; unsigned long mutefreq; - struct mutex lock; + struct semaphore lock; }; static void typhoon_setvol_generic(struct typhoon_device *dev, int vol); @@ -77,12 +77,12 @@ static int typhoon_get_info(char *buf, char **start, off_t offset, int len); static void typhoon_setvol_generic(struct typhoon_device *dev, int vol) { - mutex_lock(&dev->lock); + down(&dev->lock); vol >>= 14; /* Map 16 bit to 2 bit */ vol &= 3; outb_p(vol / 2, dev->iobase); /* Set the volume, high bit. */ outb_p(vol % 2, dev->iobase + 2); /* Set the volume, low bit. */ - mutex_unlock(&dev->lock); + up(&dev->lock); } static int typhoon_setfreq_generic(struct typhoon_device *dev, @@ -102,7 +102,7 @@ static int typhoon_setfreq_generic(struct typhoon_device *dev, * */ - mutex_lock(&dev->lock); + down(&dev->lock); x = frequency / 160; outval = (x * x + 2500) / 5000; outval = (outval * x + 5000) / 10000; @@ -112,7 +112,7 @@ static int typhoon_setfreq_generic(struct typhoon_device *dev, outb_p((outval >> 8) & 0x01, dev->iobase + 4); outb_p(outval >> 9, dev->iobase + 6); outb_p(outval & 0xff, dev->iobase + 8); - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } @@ -337,7 +337,7 @@ static int __init typhoon_init(void) #endif /* MODULE */ printk(KERN_INFO BANNER); - mutex_init(&typhoon_unit.lock); + init_MUTEX(&typhoon_unit.lock); io = typhoon_unit.iobase; if (!request_region(io, 8, "typhoon")) { printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n", diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 7bf1a4264..d590e80c9 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -48,7 +48,7 @@ struct zol_device { unsigned long curfreq; int muted; unsigned int stereo; - struct mutex lock; + struct semaphore lock; }; static int zol_setvol(struct zol_device *dev, int vol) @@ -57,30 +57,30 @@ static int zol_setvol(struct zol_device *dev, int vol) if (dev->muted) return 0; - mutex_lock(&dev->lock); + down(&dev->lock); if (vol == 0) { outb(0, io); outb(0, io); inb(io + 3); /* Zoltrix needs to be read to confirm */ - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } outb(dev->curvol-1, io); msleep(10); inb(io + 2); - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } static void zol_mute(struct zol_device *dev) { dev->muted = 1; - mutex_lock(&dev->lock); + down(&dev->lock); outb(0, io); outb(0, io); inb(io + 3); /* Zoltrix needs to be read to confirm */ - mutex_unlock(&dev->lock); + up(&dev->lock); } static void zol_unmute(struct zol_device *dev) @@ -104,7 +104,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) bitmask = 0xc480402c10080000ull; i = 45; - mutex_lock(&dev->lock); + down(&dev->lock); outb(0, io); outb(0, io); @@ -149,7 +149,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) udelay(1000); } - mutex_unlock(&dev->lock); + up(&dev->lock); if(!dev->muted) { @@ -164,7 +164,7 @@ static int zol_getsigstr(struct zol_device *dev) { int a, b; - mutex_lock(&dev->lock); + down(&dev->lock); outb(0x00, io); /* This stuff I found to do nothing */ outb(dev->curvol, io); msleep(20); @@ -173,7 +173,7 @@ static int zol_getsigstr(struct zol_device *dev) msleep(10); b = inb(io); - mutex_unlock(&dev->lock); + up(&dev->lock); if (a != b) return (0); @@ -188,7 +188,7 @@ static int zol_is_stereo (struct zol_device *dev) { int x1, x2; - mutex_lock(&dev->lock); + down(&dev->lock); outb(0x00, io); outb(dev->curvol, io); @@ -198,7 +198,7 @@ static int zol_is_stereo (struct zol_device *dev) msleep(10); x2 = inb(io); - mutex_unlock(&dev->lock); + up(&dev->lock); if ((x1 == x2) && (x1 == 0xcf)) return 1; @@ -350,7 +350,7 @@ static int __init zoltrix_init(void) } printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); - mutex_init(&zoltrix_unit.lock); + init_MUTEX(&zoltrix_unit.lock); /* mute card - prevents noisy bootups */ diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 67d729a84..ef42a260e 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -2,10 +2,10 @@ # Multimedia Video device configuration # -menu "Video Capture Adapters" +menu "Video For Linux" depends on VIDEO_DEV -comment "Video Capture Adapters" +comment "Video Adapters" config VIDEO_ADV_DEBUG bool "Enable advanced debug functionality" @@ -16,23 +16,34 @@ config VIDEO_ADV_DEBUG V4L devices. In doubt, say N. -config VIDEO_VIVI - tristate "Virtual Video Driver" - depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 +config VIDEO_BT848 + tristate "BT848 Video For Linux" + depends on VIDEO_DEV && PCI && I2C + select I2C_ALGOBIT + select FW_LOADER + select VIDEO_BTCX select VIDEO_BUF - default n + select VIDEO_IR + select VIDEO_TUNER + select VIDEO_TVEEPROM ---help--- - Enables a virtual video driver. This device shows a color bar - and a timestamp, as a real device would generate by using V4L2 - api. - Say Y here if you want to test video apps or debug V4L devices. - In doubt, say N. + Support for BT848 based frame grabber/overlay boards. This includes + the Miro, Hauppauge and STB boards. Please read the material in + for more information. -source "drivers/media/video/bt8xx/Kconfig" + To compile this driver as a module, choose M here: the + module will be called bttv. + +config VIDEO_BT848_DVB + bool "DVB/ATSC Support for bt878 based TV cards" + depends on VIDEO_BT848 && DVB_CORE + select DVB_BT8XX + ---help--- + This adds support for DVB/ATSC cards based on the BT878 chip. config VIDEO_SAA6588 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" - depends on I2C && VIDEO_BT848 + depends on VIDEO_DEV && I2C && VIDEO_BT848 help Support for Radio Data System (RDS) decoder. This allows seeing @@ -44,7 +55,7 @@ config VIDEO_SAA6588 config VIDEO_PMS tristate "Mediavision Pro Movie Studio Video For Linux" - depends on ISA && VIDEO_V4L1 + depends on VIDEO_DEV && ISA help Say Y if you have such a thing. @@ -53,7 +64,7 @@ config VIDEO_PMS config VIDEO_PLANB tristate "PlanB Video-In on PowerMac" - depends on PPC_PMAC && VIDEO_V4L1 && BROKEN + depends on PPC_PMAC && VIDEO_DEV && BROKEN help PlanB is the V4L driver for the PowerMac 7x00/8x00 series video input hardware. If you want to experiment with this, say Y. @@ -64,7 +75,7 @@ config VIDEO_PLANB config VIDEO_BWQCAM tristate "Quickcam BW Video For Linux" - depends on PARPORT && VIDEO_V4L1 + depends on VIDEO_DEV && PARPORT help Say Y have if you the black and white version of the QuickCam camera. See the next option for the color version. @@ -74,7 +85,7 @@ config VIDEO_BWQCAM config VIDEO_CQCAM tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" - depends on EXPERIMENTAL && PARPORT && VIDEO_V4L1 + depends on EXPERIMENTAL && VIDEO_DEV && PARPORT help This is the video4linux driver for the colour version of the Connectix QuickCam. If you have one of these cameras, say Y here, @@ -85,7 +96,7 @@ config VIDEO_CQCAM config VIDEO_W9966 tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux" - depends on PARPORT_1284 && PARPORT && VIDEO_V4L1 + depends on PARPORT_1284 && VIDEO_DEV && PARPORT help Video4linux driver for Winbond's w9966 based Webcams. Currently tested with the LifeView FlyCam Supra. @@ -98,7 +109,7 @@ config VIDEO_W9966 config VIDEO_CPIA tristate "CPiA Video For Linux" - depends on VIDEO_V4L1 + depends on VIDEO_DEV ---help--- This is the video4linux driver for cameras based on Vision's CPiA (Colour Processor Interface ASIC), such as the Creative Labs Video @@ -131,11 +142,9 @@ config VIDEO_CPIA_USB otherwise say N. This will not work with the Creative Webcam III. It is also available as a module (cpia_usb). -source "drivers/media/video/cpia2/Kconfig" - config VIDEO_SAA5246A tristate "SAA5246A, SAA5281 Teletext processor" - depends on I2C && VIDEO_V4L1 + depends on VIDEO_DEV && I2C help Support for I2C bus based teletext using the SAA5246A or SAA5281 chip. Useful only if you live in Europe. @@ -162,7 +171,7 @@ config TUNER_3036 config VIDEO_VINO tristate "SGI Vino Video For Linux (EXPERIMENTAL)" - depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L1 + depends on VIDEO_DEV && I2C && SGI_IP22 && EXPERIMENTAL select I2C_ALGO_SGI help Say Y here to build in support for the Vino video input system found @@ -170,7 +179,7 @@ config VIDEO_VINO config VIDEO_STRADIS tristate "Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)" - depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && !PPC64 + depends on EXPERIMENTAL && VIDEO_DEV && PCI help Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video driver for PCI. There is a product page at @@ -178,7 +187,7 @@ config VIDEO_STRADIS config VIDEO_ZORAN tristate "Zoran ZR36057/36067 Video For Linux" - depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && !PPC64 + depends on VIDEO_DEV && PCI && I2C_ALGOBIT help Say Y for support for MJPEG capture cards based on the Zoran 36057/36067 PCI controller chipset. This includes the Iomega @@ -226,7 +235,7 @@ config VIDEO_ZORAN_LML33R10 config VIDEO_ZR36120 tristate "Zoran ZR36120/36125 Video For Linux" - depends on PCI && I2C && VIDEO_V4L1 && BROKEN + depends on VIDEO_DEV && PCI && I2C && BROKEN help Support for ZR36120/ZR36125 based frame grabber/overlay boards. This includes the Victor II, WaveWatcher, Video Wonder, Maxi-TV, @@ -238,7 +247,7 @@ config VIDEO_ZR36120 config VIDEO_MEYE tristate "Sony Vaio Picturebook Motion Eye Video For Linux" - depends on PCI && SONYPI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI && SONYPI ---help--- This is the video4linux driver for the Motion Eye camera found in the Vaio Picturebook laptops. Please read the material in @@ -254,7 +263,7 @@ source "drivers/media/video/saa7134/Kconfig" config VIDEO_MXB tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" - depends on PCI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI select VIDEO_SAA7146_VV select VIDEO_TUNER ---help--- @@ -266,9 +275,8 @@ config VIDEO_MXB config VIDEO_DPC tristate "Philips-Semiconductors 'dpc7146 demonstration board'" - depends on PCI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI select VIDEO_SAA7146_VV - select VIDEO_V4L2 ---help--- This is a video4linux driver for the 'dpc7146 demonstration board' by Philips-Semiconductors. It's the reference design @@ -281,9 +289,8 @@ config VIDEO_DPC config VIDEO_HEXIUM_ORION tristate "Hexium HV-PCI6 and Orion frame grabber" - depends on PCI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI select VIDEO_SAA7146_VV - select VIDEO_V4L2 ---help--- This is a video4linux driver for the Hexium HV-PCI6 and Orion frame grabber cards by Hexium. @@ -293,9 +300,8 @@ config VIDEO_HEXIUM_ORION config VIDEO_HEXIUM_GEMINI tristate "Hexium Gemini frame grabber" - depends on PCI && VIDEO_V4L1 + depends on VIDEO_DEV && PCI select VIDEO_SAA7146_VV - select VIDEO_V4L2 ---help--- This is a video4linux driver for the Hexium Gemini frame grabber card by Hexium. Please note that the Gemini Dual @@ -306,20 +312,22 @@ config VIDEO_HEXIUM_GEMINI source "drivers/media/video/cx88/Kconfig" +source "drivers/media/video/em28xx/Kconfig" + config VIDEO_OVCAMCHIP tristate "OmniVision Camera Chip support" - depends on I2C && VIDEO_V4L1 + depends on VIDEO_DEV && I2C ---help--- Support for the OmniVision OV6xxx and OV7xxx series of camera chips. This driver is intended to be used with the ov511 and w9968cf USB camera drivers. To compile this driver as a module, choose M here: the - module will be called ovcamchip. + module will be called ovcamchip config VIDEO_M32R_AR tristate "AR devices" - depends on M32R && VIDEO_V4L1 + depends on M32R ---help--- This is a video4linux driver for the Renesas AR (Artificial Retina) camera module. @@ -331,180 +339,19 @@ config VIDEO_M32R_AR_M64278 Say Y here to use the Renesas M64278E-800 camera module, which supports VGA(640x480 pixcels) size of images. -# -# Encoder / Decoder module configuration -# - -menu "Encoders and Decoders" - depends on VIDEO_DEV - -config VIDEO_MSP3400 - tristate "Micronas MSP34xx audio decoders" - depends on VIDEO_DEV && I2C - ---help--- - Support for the Micronas MSP34xx series of audio decoders. - - To compile this driver as a module, choose M here: the - module will be called msp3400. - -config VIDEO_CS53L32A - tristate "Cirrus Logic CS53L32A audio ADC" +config VIDEO_AUDIO_DECODER + tristate "Add support for additional audio chipsets" depends on VIDEO_DEV && I2C && EXPERIMENTAL ---help--- - Support for the Cirrus Logic CS53L32A low voltage - stereo A/D converter. - - To compile this driver as a module, choose M here: the - module will be called cs53l32a. + Say Y here to compile drivers for WM8775 and CS53L32A audio + decoders. -config VIDEO_WM8775 - tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer" +config VIDEO_DECODER + tristate "Add support for additional video chipsets" depends on VIDEO_DEV && I2C && EXPERIMENTAL + select FW_LOADER ---help--- - Support for the Wolfson Microelectronics WM8775 high - performance stereo A/D Converter with a 4 channel input mixer. - - To compile this driver as a module, choose M here: the - module will be called wm8775. - -config VIDEO_WM8739 - tristate "Wolfson Microelectronics WM8739 stereo audio ADC" - depends on VIDEO_DEV && I2C && EXPERIMENTAL - ---help--- - Support for the Wolfson Microelectronics WM8739 - stereo A/D Converter. - - To compile this driver as a module, choose M here: the - module will be called wm8739. - -source "drivers/media/video/cx25840/Kconfig" - -config VIDEO_SAA711X - tristate "Philips SAA7113/4/5 video decoders" - depends on VIDEO_DEV && I2C && EXPERIMENTAL - ---help--- - Support for the Philips SAA7113/4/5 video decoders. - - To compile this driver as a module, choose M here: the - module will be called saa7115. - -config VIDEO_SAA7127 - tristate "Philips SAA7127/9 digital video encoders" - depends on VIDEO_V4L2 && I2C && EXPERIMENTAL - ---help--- - Support for the Philips SAA7127/9 digital video encoders. - - To compile this driver as a module, choose M here: the - module will be called saa7127. - -config VIDEO_UPD64031A - tristate "NEC Electronics uPD64031A Ghost Reduction" - depends on VIDEO_V4L2 && I2C && EXPERIMENTAL - ---help--- - Support for the NEC Electronics uPD64031A Ghost Reduction - video chip. It is most often found in NTSC TV cards made for - Japan and is used to reduce the 'ghosting' effect that can - be present in analog TV broadcasts. - - To compile this driver as a module, choose M here: the - module will be called upd64031a. - -config VIDEO_UPD64083 - tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation" - depends on VIDEO_V4L2 && I2C && EXPERIMENTAL - ---help--- - Support for the NEC Electronics uPD64083 3-Dimensional Y/C - separation video chip. It is used to improve the quality of - the colors of a composite signal. - - To compile this driver as a module, choose M here: the - module will be called upd64083. - -endmenu # encoder / decoder chips - -# -# USB Multimedia device configuration -# - -menu "V4L USB devices" - depends on USB && VIDEO_DEV - -source "drivers/media/video/em28xx/Kconfig" - -config USB_DSBR - tristate "D-Link USB FM radio support (EXPERIMENTAL)" - depends on USB && VIDEO_V4L1 && EXPERIMENTAL - ---help--- - Say Y here if you want to connect this type of radio to your - computer's USB port. Note that the audio is not digital, and - you must connect the line out connector to a sound card or a - set of speakers. - - To compile this driver as a module, choose M here: the - module will be called dsbr100. - -source "drivers/media/video/usbvideo/Kconfig" - -source "drivers/media/video/et61x251/Kconfig" - -config USB_OV511 - tristate "USB OV511 Camera support" - depends on USB && VIDEO_V4L1 - ---help--- - Say Y here if you want to connect this type of camera to your - computer's USB port. See - for more information and for a list of supported cameras. - - To compile this driver as a module, choose M here: the - module will be called ov511. - -config USB_SE401 - tristate "USB SE401 Camera support" - depends on USB && VIDEO_V4L1 - ---help--- - Say Y here if you want to connect this type of camera to your - computer's USB port. See - for more information and for a list of supported cameras. - - To compile this driver as a module, choose M here: the - module will be called se401. - -source "drivers/media/video/sn9c102/Kconfig" - -config USB_STV680 - tristate "USB STV680 (Pencam) Camera support" - depends on USB && VIDEO_V4L1 - ---help--- - Say Y here if you want to connect this type of camera to your - computer's USB port. This includes the Pencam line of cameras. - See for more information - and for a list of supported cameras. - - To compile this driver as a module, choose M here: the - module will be called stv680. - -config USB_W9968CF - tristate "USB W996[87]CF JPEG Dual Mode Camera support" - depends on USB && VIDEO_V4L1 && I2C - select VIDEO_OVCAMCHIP - ---help--- - Say Y here if you want support for cameras based on OV681 or - Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. - - This driver has an optional plugin, which is distributed as a - separate module only (released under GPL). It allows to use higher - resolutions and framerates, but cannot be included in the official - Linux kernel for performance purposes. - - See for more info. - - To compile this driver as a module, choose M here: the - module will be called w9968cf. - -source "drivers/media/video/zc0301/Kconfig" - -source "drivers/media/video/pwc/Kconfig" - -endmenu # V4L USB devices + Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 + video decoders. endmenu diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index e5bf2687b..faf728366 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -2,6 +2,9 @@ # Makefile for the video capture/playback device drivers. # +bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ + bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \ + bttv-input.o zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o @@ -10,14 +13,10 @@ tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ msp3400-objs := msp3400-driver.o msp3400-kthreads.o -obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o +obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o -ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) - obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o -endif - -obj-$(CONFIG_VIDEO_BT848) += bt8xx/ -obj-$(CONFIG_VIDEO_BT848) += tvaudio.o tda7432.o tda9875.o ir-kbd-i2c.o +obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ + tda7432.o tda9875.o ir-kbd-i2c.o obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o obj-$(CONFIG_VIDEO_ZR36120) += zoran.o @@ -45,14 +44,10 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ obj-$(CONFIG_VIDEO_CX88) += cx88/ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ -obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o -obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o -obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o -obj-$(CONFIG_VIDEO_WM8775) += wm8775.o -obj-$(CONFIG_VIDEO_WM8739) += wm8739.o +obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o +obj-$(CONFIG_VIDEO_AUDIO_DECODER) += wm8775.o cs53l32a.o obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ -obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ -obj-$(CONFIG_VIDEO_MXB) += saa7111.o tda9840.o tea6415c.o tea6420.o mxb.o +obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o @@ -66,30 +61,6 @@ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o -obj-$(CONFIG_VIDEO_CX25840) += cx25840/ -obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o -obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o -obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o -obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o - -obj-$(CONFIG_USB_DABUSB) += dabusb.o -obj-$(CONFIG_USB_DSBR) += dsbr100.o -obj-$(CONFIG_USB_OV511) += ov511.o -obj-$(CONFIG_USB_SE401) += se401.o -obj-$(CONFIG_USB_STV680) += stv680.o -obj-$(CONFIG_USB_W9968CF) += w9968cf.o - -obj-$(CONFIG_USB_SN9C102) += sn9c102/ -obj-$(CONFIG_USB_ET61X251) += et61x251/ -obj-$(CONFIG_USB_PWC) += pwc/ -obj-$(CONFIG_USB_ZC0301) += zc0301/ - -obj-$(CONFIG_USB_IBMCAM) += usbvideo/ -obj-$(CONFIG_USB_KONICAWC) += usbvideo/ -obj-$(CONFIG_USB_VICAM) += usbvideo/ - -obj-$(CONFIG_VIDEO_VIVI) += vivi.o - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT +obj-$(CONFIG_VIDEO_DECODER) += saa7115.o cx25840/ saa7127.o +EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 48709582a..4ce07ae62 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -1,9 +1,9 @@ -/* +/* * adv7170 - adv7170, adv7171 video encoder driver version 0.0.1 * * Copyright (C) 2002 Maxim Yevtyushkin * - * Based on adv7176 driver by: + * Based on adv7176 driver by: * * Copyright (C) 1998 Dave Perks * Copyright (C) 1999 Wolfgang Scherr @@ -53,6 +53,7 @@ MODULE_AUTHOR("Maxim Yevtyushkin"); MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(x) (x)->name @@ -124,21 +125,24 @@ adv7170_write_block (struct i2c_client *client, if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ struct adv7170 *encoder = i2c_get_clientdata(client); + struct i2c_msg msg; u8 block_data[32]; - int block_len; + msg.addr = client->addr; + msg.flags = 0; while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; + msg.buf = (char *) block_data; + msg.len = 0; + block_data[msg.len++] = reg = data[0]; do { - block_data[block_len++] = + block_data[msg.len++] = encoder->reg[reg++] = data[1]; len -= 2; data += 2; } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + msg.len < 32); + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { @@ -173,7 +177,7 @@ adv7170_write_block (struct i2c_client *client, static const unsigned char init_NTSC[] = { 0x00, 0x10, // MR0 0x01, 0x20, // MR1 - 0x02, 0x0e, // MR2 RTC control: bits 2 and 1 + 0x02, 0x0e, // MR2 RTC control: bits 2 and 1 0x03, 0x80, // MR3 0x04, 0x30, // MR4 0x05, 0x00, // Reserved @@ -196,7 +200,7 @@ static const unsigned char init_NTSC[] = { 0x16, 0x00, // CGMS_WSS_0 0x17, 0x00, // CGMS_WSS_1 0x18, 0x00, // CGMS_WSS_2 - 0x19, 0x00, // Teletext Ctl + 0x19, 0x00, // Teletext Ctl }; static const unsigned char init_PAL[] = { @@ -381,7 +385,7 @@ static unsigned short normal_i2c[] = }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 68e7d7aff..4e218f22b 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -1,4 +1,4 @@ -/* +/* * adv7175 - adv7175a video encoder driver version 0.0.3 * * Copyright (C) 1998 Dave Perks @@ -49,6 +49,7 @@ MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(s) (s)->name @@ -67,6 +68,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ struct adv7175 { + unsigned char reg[128]; + int norm; int input; int enable; @@ -92,6 +95,9 @@ adv7175_write (struct i2c_client *client, u8 reg, u8 value) { + struct adv7175 *encoder = i2c_get_clientdata(client); + + encoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -114,21 +120,25 @@ adv7175_write_block (struct i2c_client *client, * the adapter understands raw I2C */ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ + struct adv7175 *encoder = i2c_get_clientdata(client); + struct i2c_msg msg; u8 block_data[32]; - int block_len; + msg.addr = client->addr; + msg.flags = 0; while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; + msg.buf = (char *) block_data; + msg.len = 0; + block_data[msg.len++] = reg = data[0]; do { - block_data[block_len++] = data[1]; - reg++; + block_data[msg.len++] = + encoder->reg[reg++] = data[1]; len -= 2; data += 2; } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + msg.len < 32); + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { @@ -161,6 +171,24 @@ set_subcarrier_freq (struct i2c_client *client, adv7175_write(client, 0x05, 0x25); } +#ifdef ENCODER_DUMP +static void +dump (struct i2c_client *client) +{ + struct adv7175 *encoder = i2c_get_clientdata(client); + int i, j; + + printk(KERN_INFO "%s: registry dump\n", I2C_NAME(client)); + for (i = 0; i < 182 / 8; i++) { + printk("%s: 0x%02x -", I2C_NAME(client), i * 8); + for (j = 0; j < 8; j++) { + printk(" 0x%02x", encoder->reg[i * 8 + j]); + } + printk("\n"); + } +} +#endif + /* ----------------------------------------------------------------------- */ // Output filter: S-Video Composite @@ -233,7 +261,7 @@ adv7175_command (struct i2c_client *client, sizeof(init_common)); adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - break; + break; case ENCODER_GET_CAPABILITIES: { @@ -379,6 +407,14 @@ adv7175_command (struct i2c_client *client, } break; +#ifdef ENCODER_DUMP + case ENCODER_DUMP: + { + dump(client); + } + break; +#endif + default: return -EINVAL; } @@ -399,7 +435,7 @@ static unsigned short normal_i2c[] = }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index dbe025170..994b75fe1 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c @@ -31,8 +31,8 @@ #include #include #include -#include +#include #include #include #include @@ -117,7 +117,7 @@ struct ar_device { int width, height; int frame_bytes, line_bytes; wait_queue_head_t wait; - struct mutex lock; + struct semaphore lock; }; static int video_nr = -1; /* video device number (first free) */ @@ -161,39 +161,39 @@ void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2, { int i; - /* Slave Address */ - ar_outl(addr, PLDI2CDATA); + /* Slave Address */ + ar_outl(addr, PLDI2CDATA); wait_for_vsync(); - /* Start */ - ar_outl(1, PLDI2CCND); + /* Start */ + ar_outl(1, PLDI2CCND); wait_acknowledge(); /* Transfer data 1 */ - ar_outl(data1, PLDI2CDATA); + ar_outl(data1, PLDI2CDATA); wait_for_vsync(); - ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); + ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); wait_acknowledge(); /* Transfer data 2 */ - ar_outl(data2, PLDI2CDATA); + ar_outl(data2, PLDI2CDATA); wait_for_vsync(); - ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); + ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); wait_acknowledge(); if (n == 3) { /* Transfer data 3 */ - ar_outl(data3, PLDI2CDATA); + ar_outl(data3, PLDI2CDATA); wait_for_vsync(); - ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); + ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); wait_acknowledge(); - } + } - /* Stop */ + /* Stop */ for (i = 0; i < 100; i++) cpu_relax(); - ar_outl(2, PLDI2CCND); - ar_outl(2, PLDI2CCND); + ar_outl(2, PLDI2CCND); + ar_outl(2, PLDI2CCND); while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB) cpu_relax(); @@ -204,24 +204,24 @@ void init_iic(void) { DEBUG(1, "init_iic:\n"); - /* + /* * ICU Setting (iic) */ - /* I2C Setting */ - ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */ - ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ - ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ + /* I2C Setting */ + ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */ + ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ + ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ /* I2C CLK */ - /* 50MH-100k */ + /* 50MH-100k */ if (freq == 75) { - ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ + ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ } else if (freq == 50) { ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */ } else { ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */ } - ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */ + ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */ } /************************************************************************** @@ -253,7 +253,7 @@ static inline void wait_for_vertical_sync(int exp_line) /* * check HCOUNT because we cannot check vertical sync. - */ + */ for (; tmout >= 0; tmout--) { l = ar_inl(ARVHCOUNT); if (l == exp_line) @@ -288,7 +288,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) if (ar->mode == AR_MODE_NORMAL) arvcr1 |= ARVCR1_NORMAL; - mutex_lock(&ar->lock); + down(&ar->lock); #if USE_INT local_irq_save(flags); @@ -392,7 +392,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) } DEBUG(1, "ret = %d\n", ret); out_up: - mutex_unlock(&ar->lock); + up(&ar->lock); return ret; } @@ -456,7 +456,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file, (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA)) return -EINVAL; - mutex_lock(&ar->lock); + down(&ar->lock); ar->width = w->width; ar->height = w->height; if (ar->width == AR_WIDTH_VGA) { @@ -473,7 +473,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file, ar->line_bytes = AR_LINE_BYTES_QVGA; ar->mode = AR_MODE_INTERLACE; } - mutex_unlock(&ar->lock); + up(&ar->lock); return 0; } case VIDIOCGFBUF: @@ -562,8 +562,8 @@ static void ar_interrupt(int irq, void *dev, struct pt_regs *regs) /* operations for interlace mode */ if ( line_count < (AR_HEIGHT_VGA/2) ) /* even line */ line_number = (line_count << 1); - else /* odd line */ - line_number = + else /* odd line */ + line_number = (((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1); } else { line_number = line_count; @@ -651,7 +651,7 @@ static int ar_initialize(struct video_device *dev) cr |= ARVCR1_NORMAL; ar_outl(cr, ARVCR1); - /* + /* * Initialize IIC so that CPU can communicate with AR LSI, * and send boot commands to AR LSI. */ @@ -734,7 +734,7 @@ static int ar_initialize(struct video_device *dev) void ar_release(struct video_device *vfd) { struct ar_device *ar = vfd->priv; - mutex_lock(&ar->lock); + down(&ar->lock); video_device_release(vfd); } @@ -824,7 +824,7 @@ static int __init ar_init(void) ar->line_bytes = AR_LINE_BYTES_QVGA; ar->mode = AR_MODE_INTERLACE; } - mutex_init(&ar->lock); + init_MUTEX(&ar->lock); init_waitqueue_head(&ar->wait); #if USE_INT @@ -846,7 +846,7 @@ static int __init ar_init(void) * so register video device as a frame grabber type. * device is named "video[0-64]". * video_register_device() initializes h/w using ar_initialize(). - */ + */ if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) { /* return -1, -ENFILE(full) or others */ printk("arv: register video (Colour AR) failed.\n"); diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index e7b38fdd5..d6447791d 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -1,4 +1,4 @@ -/* +/* * bt819 - BT819A VideoStream Decoder (Rockwell Part) * * Copyright (C) 1999 Mike Bernson @@ -6,7 +6,7 @@ * * Modifications for LML33/DC10plus unified driver * Copyright (C) 2000 Serguei Miridonov - * + * * Changes by Ronald Bultje * - moved over to linux>=2.4.x i2c protocol (9/9/2002) * @@ -53,6 +53,7 @@ MODULE_AUTHOR("Mike Bernson & Dave Perks"); MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(s) (s)->name @@ -140,21 +141,24 @@ bt819_write_block (struct i2c_client *client, if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ struct bt819 *decoder = i2c_get_clientdata(client); + struct i2c_msg msg; u8 block_data[32]; - int block_len; + msg.addr = client->addr; + msg.flags = 0; while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; + msg.buf = (char *) block_data; + msg.len = 0; + block_data[msg.len++] = reg = data[0]; do { - block_data[block_len++] = + block_data[msg.len++] = decoder->reg[reg++] = data[1]; len -= 2; data += 2; } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + msg.len < 32); + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { @@ -206,9 +210,9 @@ bt819_init (struct i2c_client *client) Bug in the bt819 stepping on my board? */ 0x14, 0x00, /* 0x14 Vertial Scaling lsb */ - 0x16, 0x07, /* 0x16 Video Timing Polarity + 0x16, 0x07, /* 0x16 Video Timing Polarity ACTIVE=active low - FIELD: high=odd, + FIELD: high=odd, vreset=active high, hreset=active high */ 0x18, 0x68, /* 0x18 AGC Delay */ @@ -497,7 +501,7 @@ static unsigned short normal_i2c[] = { }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, diff --git a/drivers/media/video/bt8xx/bt832.c b/drivers/media/video/bt832.c similarity index 98% rename from drivers/media/video/bt8xx/bt832.c rename to drivers/media/video/bt832.c index a51876137..cc54b62f4 100644 --- a/drivers/media/video/bt8xx/bt832.c +++ b/drivers/media/video/bt832.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "bttv.h" @@ -38,7 +39,7 @@ MODULE_LICENSE("GPL"); /* Addresses to scan */ -static unsigned short normal_i2c[] = { I2C_ADDR_BT832_ALT1>>1, I2C_ADDR_BT832_ALT2>>1, +static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; diff --git a/drivers/media/video/bt8xx/bt832.h b/drivers/media/video/bt832.h similarity index 100% rename from drivers/media/video/bt8xx/bt832.h rename to drivers/media/video/bt832.h diff --git a/drivers/media/video/bt8xx/bt848.h b/drivers/media/video/bt848.h similarity index 100% rename from drivers/media/video/bt8xx/bt848.h rename to drivers/media/video/bt848.h diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index af3b61d4f..909b59353 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -1,4 +1,4 @@ -/* +/* * bt856 - BT856A Digital Video Encoder (Rockwell Part) * * Copyright (C) 1999 Mike Bernson @@ -53,6 +53,7 @@ MODULE_AUTHOR("Mike Bernson & Dave Perks"); MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(s) (s)->name @@ -70,14 +71,17 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ -#define REG_OFFSET 0xDA -#define BT856_NR_REG 6 +#define REG_OFFSET 0xCE struct bt856 { - unsigned char reg[BT856_NR_REG]; + unsigned char reg[32]; int norm; int enable; + int bright; + int contrast; + int hue; + int sat; }; #define I2C_BT856 0x88 @@ -116,8 +120,8 @@ bt856_dump (struct i2c_client *client) struct bt856 *encoder = i2c_get_clientdata(client); printk(KERN_INFO "%s: register dump:", I2C_NAME(client)); - for (i = 0; i < BT856_NR_REG; i += 2) - printk(" %02x", encoder->reg[i]); + for (i = 0xd6; i <= 0xde; i += 2) + printk(" %02x", encoder->reg[i - REG_OFFSET]); printk("\n"); } @@ -285,7 +289,7 @@ bt856_command (struct i2c_client *client, static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig deleted file mode 100644 index 153f6a4a9..000000000 --- a/drivers/media/video/bt8xx/Kconfig +++ /dev/null @@ -1,25 +0,0 @@ -config VIDEO_BT848 - tristate "BT848 Video For Linux" - depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 - select I2C_ALGOBIT - select FW_LOADER - select VIDEO_BTCX - select VIDEO_BUF - select VIDEO_IR - select VIDEO_TUNER - select VIDEO_TVEEPROM - select VIDEO_MSP3400 - ---help--- - Support for BT848 based frame grabber/overlay boards. This includes - the Miro, Hauppauge and STB boards. Please read the material in - for more information. - - To compile this driver as a module, choose M here: the - module will be called bttv. - -config VIDEO_BT848_DVB - bool "DVB/ATSC Support for bt878 based TV cards" - depends on VIDEO_BT848 && DVB_CORE - select DVB_BT8XX - ---help--- - This adds support for DVB/ATSC cards based on the BT878 chip. diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile deleted file mode 100644 index a096a0341..000000000 --- a/drivers/media/video/bt8xx/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the video capture/playback device drivers. -# - -bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ - bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \ - bttv-input.o - -obj-$(CONFIG_VIDEO_BT848) += bttv.o - -EXTRA_CFLAGS += -Idrivers/media/video -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c deleted file mode 100644 index 69efa0e51..000000000 --- a/drivers/media/video/bt8xx/bttv-input.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * - * Copyright (c) 2003 Gerd Knorr - * Copyright (c) 2003 Pavel Machek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include - -#include "bttv.h" -#include "bttvp.h" - - -static int debug; -module_param(debug, int, 0644); /* debug level (0,1,2) */ -static int repeat_delay = 500; -module_param(repeat_delay, int, 0644); -static int repeat_period = 33; -module_param(repeat_period, int, 0644); - -#define DEVNAME "bttv-input" - -/* ---------------------------------------------------------------------- */ - -static void ir_handle_key(struct bttv *btv) -{ - struct bttv_ir *ir = btv->remote; - u32 gpio,data; - - /* read gpio value */ - gpio = bttv_gpio_read(&btv->c); - if (ir->polling) { - if (ir->last_gpio == gpio) - return; - ir->last_gpio = gpio; - } - - /* extract data */ - data = ir_extract_bits(gpio, ir->mask_keycode); - dprintk(KERN_INFO DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n", - gpio, data, - ir->polling ? "poll" : "irq", - (gpio & ir->mask_keydown) ? " down" : "", - (gpio & ir->mask_keyup) ? " up" : ""); - - if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || - (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - ir_input_keydown(ir->dev,&ir->ir,data,data); - } else { - ir_input_nokey(ir->dev,&ir->ir); - } - -} - -void bttv_input_irq(struct bttv *btv) -{ - struct bttv_ir *ir = btv->remote; - - if (!ir->polling) - ir_handle_key(btv); -} - -static void bttv_input_timer(unsigned long data) -{ - struct bttv *btv = (struct bttv*)data; - struct bttv_ir *ir = btv->remote; - unsigned long timeout; - - ir_handle_key(btv); - timeout = jiffies + (ir->polling * HZ / 1000); - mod_timer(&ir->timer, timeout); -} - -/* ---------------------------------------------------------------*/ - -static int rc5_remote_gap = 885; -module_param(rc5_remote_gap, int, 0644); -static int rc5_key_timeout = 200; -module_param(rc5_key_timeout, int, 0644); - -#define RC5_START(x) (((x)>>12)&3) -#define RC5_TOGGLE(x) (((x)>>11)&1) -#define RC5_ADDR(x) (((x)>>6)&31) -#define RC5_INSTR(x) ((x)&63) - -/* decode raw bit pattern to RC5 code */ -static u32 rc5_decode(unsigned int code) -{ - unsigned int org_code = code; - unsigned int pair; - unsigned int rc5 = 0; - int i; - - code = (code << 1) | 1; - for (i = 0; i < 14; ++i) { - pair = code & 0x3; - code >>= 2; - - rc5 <<= 1; - switch (pair) { - case 0: - case 2: - break; - case 1: - rc5 |= 1; - break; - case 3: - dprintk(KERN_WARNING "bad code: %x\n", org_code); - return 0; - } - } - dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " - "instr=%x\n", rc5, org_code, RC5_START(rc5), - RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); - return rc5; -} - -static int bttv_rc5_irq(struct bttv *btv) -{ - struct bttv_ir *ir = btv->remote; - struct timeval tv; - u32 gpio; - u32 gap; - unsigned long current_jiffies, timeout; - - /* read gpio port */ - gpio = bttv_gpio_read(&btv->c); - - /* remote IRQ? */ - if (!(gpio & 0x20)) - return 0; - - /* get time of bit */ - current_jiffies = jiffies; - do_gettimeofday(&tv); - - /* avoid overflow with gap >1s */ - if (tv.tv_sec - ir->base_time.tv_sec > 1) { - gap = 200000; - } else { - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; - } - - /* active code => add bit */ - if (ir->active) { - /* only if in the code (otherwise spurious IRQ or timer - late) */ - if (ir->last_bit < 28) { - ir->last_bit = (gap - rc5_remote_gap / 2) / - rc5_remote_gap; - ir->code |= 1 << ir->last_bit; - } - /* starting new code */ - } else { - ir->active = 1; - ir->code = 0; - ir->base_time = tv; - ir->last_bit = 0; - - timeout = current_jiffies + (500 + 30 * HZ) / 1000; - mod_timer(&ir->timer_end, timeout); - } - - /* toggle GPIO pin 4 to reset the irq */ - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); - bttv_gpio_write(&btv->c, gpio | (1 << 4)); - return 1; -} - - -static void bttv_rc5_timer_end(unsigned long data) -{ - struct bttv_ir *ir = (struct bttv_ir *)data; - struct timeval tv; - unsigned long current_jiffies, timeout; - u32 gap; - - /* get time */ - current_jiffies = jiffies; - do_gettimeofday(&tv); - - /* avoid overflow with gap >1s */ - if (tv.tv_sec - ir->base_time.tv_sec > 1) { - gap = 200000; - } else { - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; - } - - /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ - if (gap < 28000) { - dprintk(KERN_WARNING "spurious timer_end\n"); - return; - } - - ir->active = 0; - if (ir->last_bit < 20) { - /* ignore spurious codes (caused by light/other remotes) */ - dprintk(KERN_WARNING "short code: %x\n", ir->code); - } else { - u32 rc5 = rc5_decode(ir->code); - - /* two start bits? */ - if (RC5_START(rc5) != 3) { - dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5)); - - /* right address? */ - } else if (RC5_ADDR(rc5) == 0x0) { - u32 toggle = RC5_TOGGLE(rc5); - u32 instr = RC5_INSTR(rc5); - - /* Good code, decide if repeat/repress */ - if (toggle != RC5_TOGGLE(ir->last_rc5) || - instr != RC5_INSTR(ir->last_rc5)) { - dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr, - toggle); - ir_input_nokey(ir->dev, &ir->ir); - ir_input_keydown(ir->dev, &ir->ir, instr, - instr); - } - - /* Set/reset key-up timer */ - timeout = current_jiffies + (500 + rc5_key_timeout - * HZ) / 1000; - mod_timer(&ir->timer_keyup, timeout); - - /* Save code for repeat test */ - ir->last_rc5 = rc5; - } - } -} - -static void bttv_rc5_timer_keyup(unsigned long data) -{ - struct bttv_ir *ir = (struct bttv_ir *)data; - - dprintk(KERN_DEBUG "key released\n"); - ir_input_nokey(ir->dev, &ir->ir); -} - -/* ---------------------------------------------------------------------- */ - -int bttv_input_init(struct bttv *btv) -{ - struct bttv_ir *ir; - IR_KEYTAB_TYPE *ir_codes = NULL; - struct input_dev *input_dev; - int ir_type = IR_TYPE_OTHER; - - if (!btv->has_remote) - return -ENODEV; - - ir = kzalloc(sizeof(*ir),GFP_KERNEL); - input_dev = input_allocate_device(); - if (!ir || !input_dev) { - kfree(ir); - input_free_device(input_dev); - return -ENOMEM; - } - memset(ir,0,sizeof(*ir)); - - /* detect & configure */ - switch (btv->c.type) { - case BTTV_BOARD_AVERMEDIA: - case BTTV_BOARD_AVPHONE98: - case BTTV_BOARD_AVERMEDIA98: - ir_codes = ir_codes_avermedia; - ir->mask_keycode = 0xf88000; - ir->mask_keydown = 0x010000; - ir->polling = 50; // ms - break; - - case BTTV_BOARD_AVDVBT_761: - case BTTV_BOARD_AVDVBT_771: - ir_codes = ir_codes_avermedia_dvbt; - ir->mask_keycode = 0x0f00c0; - ir->mask_keydown = 0x000020; - ir->polling = 50; // ms - break; - - case BTTV_BOARD_PXELVWPLTVPAK: - ir_codes = ir_codes_pixelview; - ir->mask_keycode = 0x003e00; - ir->mask_keyup = 0x010000; - ir->polling = 50; // ms - break; - case BTTV_BOARD_PV_BT878P_9B: - case BTTV_BOARD_PV_BT878P_PLUS: - ir_codes = ir_codes_pixelview; - ir->mask_keycode = 0x001f00; - ir->mask_keyup = 0x008000; - ir->polling = 50; // ms - break; - - case BTTV_BOARD_WINFAST2000: - ir_codes = ir_codes_winfast; - ir->mask_keycode = 0x1f8; - break; - case BTTV_BOARD_MAGICTVIEW061: - case BTTV_BOARD_MAGICTVIEW063: - ir_codes = ir_codes_winfast; - ir->mask_keycode = 0x0008e000; - ir->mask_keydown = 0x00200000; - break; - case BTTV_BOARD_APAC_VIEWCOMP: - ir_codes = ir_codes_apac_viewcomp; - ir->mask_keycode = 0x001f00; - ir->mask_keyup = 0x008000; - ir->polling = 50; // ms - break; - case BTTV_BOARD_CONCEPTRONIC_CTVFMI2: - case BTTV_BOARD_CONTVFMI: - ir_codes = ir_codes_pixelview; - ir->mask_keycode = 0x001F00; - ir->mask_keyup = 0x006000; - ir->polling = 50; // ms - break; - case BTTV_BOARD_NEBULA_DIGITV: - ir_codes = ir_codes_nebula; - btv->custom_irq = bttv_rc5_irq; - ir->rc5_gpio = 1; - break; - case BTTV_BOARD_MACHTV_MAGICTV: - ir_codes = ir_codes_apac_viewcomp; - ir->mask_keycode = 0x001F00; - ir->mask_keyup = 0x004000; - ir->polling = 50; /* ms */ - break; - } - if (NULL == ir_codes) { - dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type); - kfree(ir); - input_free_device(input_dev); - return -ENODEV; - } - - if (ir->rc5_gpio) { - u32 gpio; - /* enable remote irq */ - bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); - gpio = bttv_gpio_read(&btv->c); - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); - bttv_gpio_write(&btv->c, gpio | (1 << 4)); - } else { - /* init hardware-specific stuff */ - bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0); - } - - /* init input device */ - ir->dev = input_dev; - - snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", - btv->c.type); - snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", - pci_name(btv->c.pci)); - - ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); - input_dev->name = ir->name; - input_dev->phys = ir->phys; - input_dev->id.bustype = BUS_PCI; - input_dev->id.version = 1; - if (btv->c.pci->subsystem_vendor) { - input_dev->id.vendor = btv->c.pci->subsystem_vendor; - input_dev->id.product = btv->c.pci->subsystem_device; - } else { - input_dev->id.vendor = btv->c.pci->vendor; - input_dev->id.product = btv->c.pci->device; - } - input_dev->cdev.dev = &btv->c.pci->dev; - - btv->remote = ir; - if (ir->polling) { - init_timer(&ir->timer); - ir->timer.function = bttv_input_timer; - ir->timer.data = (unsigned long)btv; - ir->timer.expires = jiffies + HZ; - add_timer(&ir->timer); - } else if (ir->rc5_gpio) { - /* set timer_end for code completion */ - init_timer(&ir->timer_end); - ir->timer_end.function = bttv_rc5_timer_end; - ir->timer_end.data = (unsigned long)ir; - - init_timer(&ir->timer_keyup); - ir->timer_keyup.function = bttv_rc5_timer_keyup; - ir->timer_keyup.data = (unsigned long)ir; - } - - /* all done */ - input_register_device(btv->remote->dev); - printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys); - - /* the remote isn't as bouncy as a keyboard */ - ir->dev->rep[REP_DELAY] = repeat_delay; - ir->dev->rep[REP_PERIOD] = repeat_period; - - return 0; -} - -void bttv_input_fini(struct bttv *btv) -{ - if (btv->remote == NULL) - return; - - if (btv->remote->polling) { - del_timer_sync(&btv->remote->timer); - flush_scheduled_work(); - } - - - if (btv->remote->rc5_gpio) { - u32 gpio; - - del_timer_sync(&btv->remote->timer_end); - flush_scheduled_work(); - - gpio = bttv_gpio_read(&btv->c); - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); - } - - input_unregister_device(btv->remote->dev); - kfree(btv->remote); - btv->remote = NULL; -} - - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bttv-cards.c similarity index 95% rename from drivers/media/video/bt8xx/bttv-cards.c rename to drivers/media/video/bttv-cards.c index 2b64aa835..9749d6ed6 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c @@ -39,7 +39,6 @@ #include "bttvp.h" #include -#include /* fwd decl */ static void boot_msp34xx(struct bttv *btv, int pin); @@ -138,8 +137,6 @@ MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a li MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)"); MODULE_PARM_DESC(tuner,"specify installed tuner type"); MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)"); -MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" - " [some VIA/SIS chipsets are known to have problem with overlay]"); /* ----------------------------------------------------------------------- */ /* list of card IDs for bt878+ cards */ @@ -278,6 +275,7 @@ static struct CARD { { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" }, { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" }, { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" }, + { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" }, { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" }, { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" }, @@ -299,14 +297,13 @@ static struct CARD { * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */ /* DVB cards (using pci function .1 for mpeg data xfer) */ - { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, - { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, + { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, + { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" }, { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, - { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, @@ -337,8 +334,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, + .audiomux = { 2, 0, 0, 0, 10 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -352,8 +348,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .audiomux = { 0, 1, 2, 3, 4 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -367,8 +362,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 4, 0, 2, 3 }, - .gpiomute = 1, + .audiomux = { 4, 0, 2, 3, 1 }, .no_msp34xx = 1, .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, @@ -387,7 +381,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 0, .tuner_type = 4, .tuner_addr = ADDR_UNSET, @@ -401,8 +395,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 0, 1, 0, 1 }, - .gpiomute = 3, + .audiomux = { 0, 1, 0, 1, 3 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -416,7 +409,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .muxsel = { 2, 3, 1, 1 }, .gpiomask = 0x0f, - .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, + .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0 }, /* 0x04 for some cards ?? */ .needs_tvaudio = 1, .tuner_type = -1, @@ -433,7 +426,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -449,8 +442,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xc00, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0xc00, 0x800, 0x400 }, - .gpiomute = 0xc00, + .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -465,7 +457,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 1, 1, 2, 3 }, + .audiomux = { 1, 1, 2, 3, 0 }, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, @@ -480,8 +472,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x0f, /* old: 7 */ .muxsel = { 2, 0, 1, 1 }, - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .audiomux = { 0, 1, 2, 3, 4 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -496,8 +487,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x3014f, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x20001,0x10001, 0, 0 }, - .gpiomute = 10, + .audiomux = { 0x20001,0x10001, 0, 0,10 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -513,7 +503,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 13, 14, 11, 7 }, + .audiomux = { 13, 14, 11, 7, 0, 0 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -527,7 +517,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 13, 14, 11, 7 }, + .audiomux = { 13, 14, 11, 7, 0, 0 }, .needs_tvaudio = 1, .msp34xx_alt = 1, .pll = PLL_28, @@ -545,8 +535,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ - .gpiomute = 4, + .audiomux = { 0, 2, 1, 3, 4 }, /* old: {0, 1, 2, 3, 4} */ .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -561,8 +550,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0, 1, 0 }, - .gpiomute = 10, + .audiomux = { 0 , 0, 1 , 0, 10 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -580,11 +568,10 @@ struct tvcard bttv_tvcards[] = { .muxsel = { 2, 3, 1, 1 }, #if 0 /* old */ - .gpiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000 }, + .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }, #else /* 2003-10-20 by "Anton A. Arapov" */ - .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, - .gpiomute = 0x002000, + .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, #endif .needs_tvaudio = 1, .pll = PLL_28, @@ -598,8 +585,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x8300f8, .muxsel = { 2, 3, 1, 1,0 }, - .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, - .gpiomute = 0xcfa007, + .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -615,7 +601,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 1, 0, 0, 0 }, + .audiomux = { 1, 0, 0, 0, 0 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -629,7 +615,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 0x8dff00, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .no_msp34xx = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -656,8 +642,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800 }, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -671,8 +656,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xc00, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 1, 0x800, 0x400 }, - .gpiomute = 0xc00, + .audiomux = { 0, 1, 0x800, 0x400, 0xc00, 0 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -688,7 +672,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 7, .muxsel = { 2, 3, -1 }, .digital_mode = DIGITAL_MODE_CAMERA, - .gpiomux = { 0, 0, 0, 0 }, + .audiomux = { 0, 0, 0, 0, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ALPS_TSBB5_PAL_I, @@ -705,8 +689,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xe00, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = {0x400, 0x400, 0x400, 0x400 }, - .gpiomute = 0xc00, + .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -722,8 +705,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1f0fff, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, - .gpiomute = 0x40000, + .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000 }, .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -738,8 +720,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 7, .muxsel = { 2, 0, 1, 1 }, - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .audiomux = { 0, 1, 2, 3, 4 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -753,8 +734,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800 }, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_SECAM, .tuner_addr = ADDR_UNSET, @@ -770,8 +750,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1f0fff, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, - .gpiomute = 0x40000, + .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000 }, .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -818,7 +797,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 1, /* was: 4 */ .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0}, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -834,8 +813,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, /* 0x8dfe00 */ .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0x0800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, .pll = PLL_28, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -849,7 +827,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 1, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 1, 0, 0, 0 }, + .audiomux = { 1, 0, 0, 0, 0 }, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -865,7 +843,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 0, .tuner_type = 4, .tuner_addr = ADDR_UNSET, @@ -879,8 +857,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xffff00, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x500, 0, 0x300, 0x900 }, - .gpiomute = 0x900, + .audiomux = { 0x500, 0, 0x300, 0x900, 0x900 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -896,12 +873,11 @@ struct tvcard bttv_tvcards[] = { .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */ #if 0 .gpiomask = 0xc33000, - .gpiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 }, + .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 }, #else /* Alexander Varakin [stereo version] */ .gpiomask = 0xb33000, - .gpiomux = { 0x122000,0x1000,0x0000,0x620000 }, - .gpiomute = 0x800000, + .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 }, #endif /* Audio Routing for "WinFast 2000 XP" (no tv stereo !) gpio23 -- hef4052:nEnable (0x800000) @@ -931,8 +907,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800 }, .pll = PLL_28, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -948,8 +923,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, .pll = PLL_28, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -964,8 +938,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xff, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, - .gpiomute = 0x29, + .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = -1, @@ -980,8 +953,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x551e00, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 0x551400, 0x551200, 0, 0 }, - .gpiomute = 0x551c00, + .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = 1, @@ -997,8 +969,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 2, 0xd0001, 0, 0 }, - .gpiomute = 1, + .audiomux = { 2, 0xd0001, 0, 0, 1 }, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = -1, @@ -1015,8 +986,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 4, 0, 2, 3 }, - .gpiomute = 1, + .audiomux = { 4, 0, 2, 3, 1 }, .no_msp34xx = 1, .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, @@ -1033,7 +1003,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 13, 4, 11, 7 }, + .audiomux = { 13, 4, 11, 7, 0, 0 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -1050,7 +1020,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1}, - .gpiomux = { 0, 0, 0, 0}, + .audiomux = { 0, 0, 0, 0, 0}, .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, @@ -1066,8 +1036,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xe00b, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 }, - .gpiomute = 0xff3ffc, + .audiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc }, .no_msp34xx = 1, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -1083,8 +1052,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 1, 1, 0, 2 }, - .gpiomute = 3, + .audiomux = { 1, 1, 0, 2, 3 }, .no_msp34xx = 1, .pll = PLL_NONE, .tuner_type = -1, @@ -1099,7 +1067,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = -1, @@ -1114,8 +1082,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xbcf03f, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 }, - .gpiomute = 0xbcb03f, + .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = 21, @@ -1130,8 +1097,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x70000, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, - .gpiomute = 0x40000, + .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 }, .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_35, @@ -1150,8 +1116,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = {2,0,0,0 }, - .gpiomute = 1, + .audiomux = {2,0,0,0,1 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -1166,7 +1131,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x010f00, .muxsel = {2, 3, 0, 0 }, - .gpiomux = {0x10000, 0, 0x10000, 0 }, + .audiomux = {0x10000, 0, 0x10000, 0, 0, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ALPS_TSHC6_NTSC, @@ -1183,8 +1148,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0xAA0000, .muxsel = { 2,3,1,1,-1 }, .digital_mode = DIGITAL_MODE_CAMERA, - .gpiomux = { 0x20000, 0, 0x80000, 0x80000 }, - .gpiomute = 0xa8000, + .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1209,8 +1173,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = { 2, 0, 1, 1 }, - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .audiomux = { 0, 1, 2, 3, 4 }, .pll = PLL_28, .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */, .tuner_addr = ADDR_UNSET, @@ -1227,8 +1190,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 1, 0xd0001, 0, 0 }, - .gpiomute = 10, + .audiomux = { 1, 0xd0001, 0, 0, 10 }, /* sound path (5 sources): MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable) 0= ext. Audio IN @@ -1254,8 +1216,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1c, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0, 0x10, 8 }, - .gpiomute = 4, + .audiomux = { 0, 0, 0x10, 8, 4 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1267,7 +1228,7 @@ struct tvcard bttv_tvcards[] = { /* Tim Röstermundt in de.comp.os.unix.linux.hardware: options bttv card=0 pll=1 radio=1 gpiomask=0x18e0 - gpiomux =0x44c71f,0x44d71f,0,0x44d71f,0x44dfff + audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff options tuner type=5 */ .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", .video_inputs = 4, @@ -1276,8 +1237,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x18e0, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, - .gpiomute = 0x18e0, + .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 }, /* For cards with tda9820/tda9821: 0x0000: Tuner normal stereo 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) @@ -1297,8 +1257,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xF, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, + .audiomux = { 2, 0, 0, 0, 10 }, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, @@ -1316,8 +1275,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, .pll = PLL_28, .tuner_type = 5, .tuner_addr = ADDR_UNSET, @@ -1334,7 +1292,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 1, .gpiomask = 0, .muxsel = { 3, 1 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_35, @@ -1351,8 +1309,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xe00, .muxsel = { 2, 3, 1, 1}, - .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, - .gpiomute = 0x800, + .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4036FY5_NTSC, @@ -1368,8 +1325,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 1, + .audiomux = { 2, 0, 0, 0, 1 }, .pll = PLL_28, .tuner_type = 0, .tuner_addr = ADDR_UNSET, @@ -1386,8 +1342,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 11, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 2, 0, 0, 1 }, - .gpiomute = 8, + .audiomux = { 2, 0, 0, 1, 8 }, .pll = PLL_35, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -1402,7 +1357,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 1, .gpiomask = 0xF, .muxsel = { 2, 2 }, - .gpiomux = { }, + .audiomux = { }, .no_msp34xx = 1, .needs_tvaudio = 0, .pll = PLL_28, @@ -1421,8 +1376,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xFF, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 1, 0, 4, 4 }, - .gpiomute = 9, + .audiomux = { 1, 0, 4, 4, 9 }, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1438,8 +1392,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xf03f, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 0xbffe, 0, 0xbfff, 0 }, - .gpiomute = 0xbffe, + .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe }, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, .tuner_addr = ADDR_UNSET, @@ -1456,7 +1409,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 1, .muxsel = { 2, 3, 0, 1 }, - .gpiomux = { 0, 0, 1, 0 }, + .audiomux = { 0, 0, 1, 0, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, @@ -1475,8 +1428,7 @@ struct tvcard bttv_tvcards[] = { /* Radio changed from 1e80 to 0x800 to make FlyVideo2000S in .hu happy (gm)*/ /* -dk-???: set mute=0x1800 for tda9874h daughterboard */ - .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, - .gpiomute = 0x1800, + .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 }, .audio_hook = fv2000s_audio, .no_msp34xx = 1, .no_tda9875 = 1, @@ -1494,8 +1446,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xffff00, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, - .gpiomute = 0x900, + .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1512,7 +1463,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x010f00, .muxsel = {2, 3, 0, 0 }, - .gpiomux = {0x10000, 0, 0x10000, 0 }, + .audiomux = {0x10000, 0, 0x10000, 0, 0, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_SHARP_2U5JF5540_NTSC, @@ -1533,8 +1484,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x4f8a00, /* 0x100000: 1=MSP enabled (0=disable again) * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ - .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff }, - .gpiomute = 0x947fff, + .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff}, /* tvtuner, radio, external,internal, mute, stereo * tuner, Composit, SVid, Composit-on-Svid-adapter */ .muxsel = { 2, 3 ,0 ,1 }, @@ -1566,8 +1516,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ - .gpiomute = 13, + .audiomux = { 0, 0, 11, 7, 13, 0 }, /* TV and Radio with same GPIO ! */ .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = 25, @@ -1606,8 +1555,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x3f, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, - .gpiomute = 0x09, + .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, .needs_tvaudio = 1, .no_msp34xx = 1, .no_tda9875 = 1, @@ -1636,7 +1584,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 4, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 0, .tuner_type = -1, .tuner_addr = ADDR_UNSET, @@ -1668,8 +1616,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ .muxsel = { 2, 1, 1, }, - .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 4, + .audiomux = { 0, 1, 2, 2, 4 }, .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1688,8 +1635,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x140007, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .audiomux = { 0, 1, 2, 3, 4, 0 }, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1703,7 +1649,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 0, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, @@ -1719,14 +1665,13 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ - .gpiomux = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio! + .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio! * This card lacks external Audio In, so we mute it on Ext. & Int. * The PCB can take a sbx1637/sbx1673, wiring unknown. * This card lacks PCI subsystem ID, sigh. - * gpiomux =1: lower volume, 2+3: mute + * audiomux=1: lower volume, 2+3: mute * btwincap uses 0x80000/0x80003 */ - .gpiomute = 4, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, @@ -1773,7 +1718,7 @@ struct tvcard bttv_tvcards[] = { .radio_addr = ADDR_UNSET, .gpiomask = 7, - .gpiomux = {7}, + .audiomux = {7}, }, [BTTV_BOARD_GVBCTV5PCI] = { .name = "IODATA GV-BCTV5/PCI", @@ -1783,8 +1728,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x0f0f80, .muxsel = {2, 3, 1, 0 }, - .gpiomux = {0x030000, 0x010000, 0, 0 }, - .gpiomute = 0x020000, + .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0}, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, @@ -2014,7 +1958,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 2, /* TV, Comp1, Composite over SVID con, SVID */ .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 2, 2, 0, 0 }, + .audiomux = { 2, 2, 0, 0, 0 }, .pll = PLL_28, .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, @@ -2038,8 +1982,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 7, .muxsel = { 2, 3, 1, 1}, - .gpiomux = { 0, 1, 2, 3}, - .gpiomute = 4, + .audiomux = { 0, 1, 2, 3, 4}, .needs_tvaudio = 1, .tuner_type = 5, .tuner_addr = ADDR_UNSET, @@ -2071,7 +2014,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 0, .muxsel = { 2, 3 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, @@ -2090,8 +2033,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x001e8007, .muxsel = { 2, 3, 1, 0 }, /* Tuner, Radio, external, internal, off, on */ - .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, - .gpiomute = 0x0f, + .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, @@ -2208,7 +2150,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 0, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 0 }, + .audiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, @@ -2225,7 +2167,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 0x00, .muxsel = { 2, 3, 1, 0 }, - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -2240,7 +2182,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 0x00, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -2260,7 +2202,7 @@ struct tvcard bttv_tvcards[] = { via the upper nibble of muxsel. here: used for xternal video-mux */ .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -2278,7 +2220,7 @@ struct tvcard bttv_tvcards[] = { via the upper nibble of muxsel. here: used for xternal video-mux */ .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -2366,7 +2308,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 1, 1, 1, 1 }, + .audiomux = { 1, 1, 1, 1, 0 }, .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2397,8 +2339,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x008007, .muxsel = { 2, 3, 0, 0 }, - .gpiomux = { 0, 0, 0, 0 }, - .gpiomute = 0x000003, + .audiomux = { 0, 0, 0, 0, 0x000003, 0 }, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2434,7 +2375,7 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .gpiomask = 0x68, .muxsel = { 2, 3, 1 }, - .gpiomux = { 0x68, 0x68, 0x61, 0x61 }, + .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 }, .pll = PLL_28, }, @@ -2449,8 +2390,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x008007, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 3, + .audiomux = { 0, 1, 2, 2, 3 }, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -2475,7 +2415,7 @@ struct tvcard bttv_tvcards[] = { .no_tda9875 = 1, .no_tda7432 = 1, .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ - .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ .pll = PLL_28, .needs_tvaudio = 0, .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ @@ -2493,7 +2433,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x0000000f, .muxsel = { 2, 1, 1 }, - .gpiomux = { 0x02, 0x00, 0x00, 0x00 }, + .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00 }, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2549,7 +2489,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 }, .muxsel_hook = sigmaSQ_muxsel, - .gpiomux = { 0 }, + .audiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = -1, @@ -2566,7 +2506,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x0, .muxsel = { 2, 2, 2, 2 }, .muxsel_hook = sigmaSLC_muxsel, - .gpiomux = { 0 }, + .audiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = -1, @@ -2584,8 +2524,7 @@ struct tvcard bttv_tvcards[] = { .svhs = -1, .gpiomask = 0xFF, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, + .audiomux = { 2, 0, 0, 0, 10 }, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -2619,8 +2558,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x3f, .muxsel = {2, 3, 1, 0 }, - .gpiomux = {0x31, 0x31, 0x31, 0x31 }, - .gpiomute = 0x31, + .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, @@ -2643,7 +2581,7 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .gpiomask = 0x008007, - .gpiomux = { 0, 0x000001,0,0 }, + .audiomux = { 0, 0x000001,0,0, 0 }, .needs_tvaudio = 1, .has_radio = 1, }, @@ -2753,8 +2691,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .muxsel = { 2, 3, 1 }, .gpiomask = 0x00e00007, - .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, - .gpiomute = 0x00c00007, + .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2770,8 +2707,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x01fe00, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, - .gpiomute = 0x002000, + .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, @@ -2788,8 +2724,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x001c0007, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 3, + .audiomux = { 0, 1, 2, 2, 3 }, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TENA_9533_DI, @@ -2808,8 +2743,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x01fe00, .muxsel = { 2,3,1,1,-1 }, .digital_mode = DIGITAL_MODE_CAMERA, - .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 }, - .gpiomute = 0x12400, + .audiomux = { 0x00400, 0x10400, 0x04400, 0x80000, 0x12400, 0x46000 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_LG_PAL_FM, @@ -2827,8 +2761,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x3f, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, - .gpiomute = 0x29, + .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF_5533MF, @@ -2862,8 +2795,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 1, + .audiomux = { 2, 0, 0, 0, 1 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = 2, @@ -2879,7 +2811,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x108007, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 100000, 100002, 100002, 100000 }, + .audiomux = { 100000, 100002, 100002, 100000 }, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2919,8 +2851,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .audiomux = { 0, 1, 2, 3, 4 }, .tuner_type = TUNER_TEMIC_4009FR5_PAL, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2991,21 +2922,21 @@ void __devinit bttv_idcard(struct bttv *btv) if (UNSET != audiomux[0]) { gpiobits = 0; - for (i = 0; i < 4; i++) { - bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i]; + for (i = 0; i < 5; i++) { + bttv_tvcards[btv->c.type].audiomux[i] = audiomux[i]; gpiobits |= audiomux[i]; } } else { gpiobits = audioall; - for (i = 0; i < 4; i++) { - bttv_tvcards[btv->c.type].gpiomux[i] = audioall; + for (i = 0; i < 5; i++) { + bttv_tvcards[btv->c.type].audiomux[i] = audioall; } } bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits; printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=", btv->c.nr,bttv_tvcards[btv->c.type].gpiomask); for (i = 0; i < 5; i++) { - printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]); + printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].audiomux[i]); } printk("\n"); } @@ -3113,7 +3044,7 @@ static void miro_pinnacle_gpio(struct bttv *btv) gpio_inout(0xffffff, 0); gpio = gpio_read(); id = ((gpio>>10) & 63) -1; - msp = bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx"); + msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); if (id < 32) { btv->tuner_type = miro_tunermap[id]; if (0 == (gpio & 0x20)) { @@ -3509,8 +3440,8 @@ void __devinit bttv_init_card2(struct bttv *btv) if (bttv_tvcards[btv->c.type].digital_mode == DIGITAL_MODE_CAMERA) { /* detect Bt832 chip for quartzsight digital camera */ - if ((bttv_I2CRead(btv, I2C_ADDR_BT832_ALT1, "Bt832") >=0) || - (bttv_I2CRead(btv, I2C_ADDR_BT832_ALT2, "Bt832") >=0)) + if ((bttv_I2CRead(btv, I2C_BT832_ALT1, "Bt832") >=0) || + (bttv_I2CRead(btv, I2C_BT832_ALT2, "Bt832") >=0)) boot_bt832(btv); } @@ -3519,19 +3450,19 @@ void __devinit bttv_init_card2(struct bttv *btv) /* try to detect audio/fader chips */ if (!bttv_tvcards[btv->c.type].no_msp34xx && - bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0) + bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) request_module("msp3400"); if (bttv_tvcards[btv->c.type].msp34xx_alt && - bttv_I2CRead(btv, I2C_ADDR_MSP3400_ALT, "MSP34xx (alternate address)") >=0) + bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0) request_module("msp3400"); if (!bttv_tvcards[btv->c.type].no_tda9875 && - bttv_I2CRead(btv, I2C_ADDR_TDA9875, "TDA9875") >=0) + bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) request_module("tda9875"); if (!bttv_tvcards[btv->c.type].no_tda7432 && - bttv_I2CRead(btv, I2C_ADDR_TDA7432, "TDA7432") >=0) + bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) request_module("tda7432"); if (bttv_tvcards[btv->c.type].needs_tvaudio) @@ -3542,7 +3473,7 @@ void __devinit bttv_init_card2(struct bttv *btv) if (btv->tda9887_conf) tda9887 = 1; if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && - bttv_I2CRead(btv, I2C_ADDR_TDA9887, "TDA9887") >=0) + bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) tda9887 = 1; /* Hybrid DVB card, DOES have a tda9887 */ if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE) @@ -3863,18 +3794,18 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm) { /* fix up our card entry */ if(norm==VIDEO_MODE_NTSC) { - bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff; - bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x957fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x957fff; dprintk("bttv_tda9880_setnorm to NTSC\n"); } else { - bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff; - bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x947fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x947fff; dprintk("bttv_tda9880_setnorm to PAL\n"); } /* set GPIO according */ gpio_bits(bttv_tvcards[btv->c.type].gpiomask, - bttv_tvcards[btv->c.type].gpiomux[btv->audio]); + bttv_tvcards[btv->c.type].audiomux[btv->audio]); } @@ -5013,14 +4944,12 @@ void __devinit bttv_check_chipset(void) if (vsfx) printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n"); if (pcipci_fail) { - printk(KERN_INFO "bttv: bttv and your chipset may not work " - "together.\n"); + printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n"); if (!no_overlay) { - printk(KERN_INFO "bttv: overlay will be disabled.\n"); + printk(KERN_WARNING "bttv: overlay will be disabled.\n"); no_overlay = 1; } else { - printk(KERN_INFO "bttv: overlay forced. Use this " - "option at your own risk.\n"); + printk(KERN_WARNING "bttv: overlay forced. Use this option at your own risk.\n"); } } if (UNSET != latency) diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bttv-driver.c similarity index 94% rename from drivers/media/video/bt8xx/bttv-driver.c rename to drivers/media/video/bttv-driver.c index 423e95494..578b20085 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -36,15 +36,13 @@ #include #include "bttvp.h" #include -#include -#include #include #include #include -#include +#include "rds.h" unsigned int bttv_num; /* number of Bt848s in use */ @@ -928,106 +926,56 @@ video_mux(struct bttv *btv, unsigned int input) static char *audio_modes[] = { "audio: tuner", "audio: radio", "audio: extern", - "audio: intern", "audio: mute" + "audio: intern", "audio: off" }; static int -audio_mux(struct bttv *btv, int input, int mute) +audio_mux(struct bttv *btv, int mode) { - int gpio_val, signal; - struct v4l2_control ctrl; - struct i2c_client *c; + int val,mux,i2c_mux,signal; gpio_inout(bttv_tvcards[btv->c.type].gpiomask, bttv_tvcards[btv->c.type].gpiomask); signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; - btv->mute = mute; - btv->audio = input; - - /* automute */ - mute = mute || (btv->opt_automute && !signal && !btv->radio_user); - - if (mute) - gpio_val = bttv_tvcards[btv->c.type].gpiomute; - else - gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; - - gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); + switch (mode) { + case AUDIO_MUTE: + btv->audio |= AUDIO_MUTE; + break; + case AUDIO_UNMUTE: + btv->audio &= ~AUDIO_MUTE; + break; + case AUDIO_TUNER: + case AUDIO_RADIO: + case AUDIO_EXTERN: + case AUDIO_INTERN: + btv->audio &= AUDIO_MUTE; + btv->audio |= mode; + } + i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio; + if (btv->opt_automute && !signal && !btv->radio_user) + mux = AUDIO_OFF; + + val = bttv_tvcards[btv->c.type].audiomux[mux]; + gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val); if (bttv_gpio) - bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]); - if (in_interrupt()) - return 0; - - ctrl.id = V4L2_CID_AUDIO_MUTE; - ctrl.value = btv->mute; - bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl); - c = btv->i2c_msp34xx_client; - if (c) { - struct v4l2_routing route; - - /* Note: the inputs tuner/radio/extern/intern are translated - to msp routings. This assumes common behavior for all msp3400 - based TV cards. When this assumption fails, then the - specific MSP routing must be added to the card table. - For now this is sufficient. */ - switch (input) { - case TVAUDIO_INPUT_RADIO: - route.input = 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, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - case TVAUDIO_INPUT_INTERN: - /* Yes, this is the same input as for RADIO. I doubt - if this is ever used. The only board with an INTERN - 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, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - case TVAUDIO_INPUT_TUNER: - default: - route.input = MSP_INPUT_DEFAULT; - break; - } - route.output = MSP_OUTPUT_DEFAULT; - c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route); - } - c = btv->i2c_tvaudio_client; - if (c) { - struct v4l2_routing route; - - route.input = input; - route.output = 0; - c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route); - } + bttv_gpio_tracking(btv,audio_modes[mux]); + if (!in_interrupt()) + bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux)); return 0; } -static inline int -audio_mute(struct bttv *btv, int mute) -{ - return audio_mux(btv, btv->audio, mute); -} - -static inline int -audio_input(struct bttv *btv, int input) -{ - return audio_mux(btv, input, btv->mute); -} - static void i2c_vidiocschan(struct bttv *btv) { - v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id; + struct video_channel c; - bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); + memset(&c,0,sizeof(c)); + c.norm = btv->tvnorm; + c.channel = btv->input; + bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) - bttv_tda9880_setnorm(btv,btv->tvnorm); + bttv_tda9880_setnorm(btv,c.norm); } static int @@ -1075,8 +1023,8 @@ set_input(struct bttv *btv, unsigned int input) } else { video_mux(btv,input); } - audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ? - TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN)); + audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ? + AUDIO_TUNER : AUDIO_EXTERN)); set_tvnorm(btv,btv->tvnorm); i2c_vidiocschan(btv); } @@ -1181,27 +1129,11 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) break; if (i == BTTV_CTLS) return -EINVAL; - if (btv->audio_hook && i >= 4 && i <= 8) { + if (i >= 4 && i <= 8) { memset(&va,0,sizeof(va)); - btv->audio_hook(btv,&va,0); - switch (c->id) { - case V4L2_CID_AUDIO_MUTE: - c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0; - break; - case V4L2_CID_AUDIO_VOLUME: - c->value = va.volume; - break; - case V4L2_CID_AUDIO_BALANCE: - c->value = va.balance; - break; - case V4L2_CID_AUDIO_BASS: - c->value = va.bass; - break; - case V4L2_CID_AUDIO_TREBLE: - c->value = va.treble; - break; - } - return 0; + bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); + if (btv->audio_hook) + btv->audio_hook(btv,&va,0); } switch (c->id) { case V4L2_CID_BRIGHTNESS: @@ -1218,11 +1150,19 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) break; case V4L2_CID_AUDIO_MUTE: + c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0; + break; case V4L2_CID_AUDIO_VOLUME: + c->value = va.volume; + break; case V4L2_CID_AUDIO_BALANCE: + c->value = va.balance; + break; case V4L2_CID_AUDIO_BASS: + c->value = va.bass; + break; case V4L2_CID_AUDIO_TREBLE: - bttv_call_i2c_clients(btv,VIDIOC_G_CTRL,c); + c->value = va.treble; break; case V4L2_CID_PRIVATE_CHROMA_AGC: @@ -1274,35 +1214,11 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) break; if (i == BTTV_CTLS) return -EINVAL; - if (btv->audio_hook && i >= 4 && i <= 8) { + if (i >= 4 && i <= 8) { memset(&va,0,sizeof(va)); - btv->audio_hook(btv,&va,0); - switch (c->id) { - case V4L2_CID_AUDIO_MUTE: - if (c->value) { - va.flags |= VIDEO_AUDIO_MUTE; - audio_mute(btv, 1); - } else { - va.flags &= ~VIDEO_AUDIO_MUTE; - audio_mute(btv, 0); - } - break; - - case V4L2_CID_AUDIO_VOLUME: - va.volume = c->value; - break; - case V4L2_CID_AUDIO_BALANCE: - va.balance = c->value; - break; - case V4L2_CID_AUDIO_BASS: - va.bass = c->value; - break; - case V4L2_CID_AUDIO_TREBLE: - va.treble = c->value; - break; - } - btv->audio_hook(btv,&va,1); - return 0; + bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); + if (btv->audio_hook) + btv->audio_hook(btv,&va,0); } switch (c->id) { case V4L2_CID_BRIGHTNESS: @@ -1318,13 +1234,26 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) bt848_sat(btv,c->value); break; case V4L2_CID_AUDIO_MUTE: - audio_mute(btv, c->value); - /* fall through */ + if (c->value) { + va.flags |= VIDEO_AUDIO_MUTE; + audio_mux(btv, AUDIO_MUTE); + } else { + va.flags &= ~VIDEO_AUDIO_MUTE; + audio_mux(btv, AUDIO_UNMUTE); + } + break; + case V4L2_CID_AUDIO_VOLUME: + va.volume = c->value; + break; case V4L2_CID_AUDIO_BALANCE: + va.balance = c->value; + break; case V4L2_CID_AUDIO_BASS: + va.bass = c->value; + break; case V4L2_CID_AUDIO_TREBLE: - bttv_call_i2c_clients(btv,VIDIOC_S_CTRL,c); + va.treble = c->value; break; case V4L2_CID_PRIVATE_CHROMA_AGC: @@ -1380,6 +1309,11 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) default: return -EINVAL; } + if (i >= 4 && i <= 8) { + bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va); + if (btv->audio_hook) + btv->audio_hook(btv,&va,1); + } return 0; } @@ -1463,7 +1397,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, free_btres(btv,fh,RESOURCE_OVERLAY); if (NULL != old) { dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state); - bttv_dma_free(&fh->cap,btv, old); + bttv_dma_free(btv, old); kfree(old); } dprintk("switch_overlay: done\n"); @@ -1473,8 +1407,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, /* ----------------------------------------------------------------------- */ /* video4linux (1) interface */ -static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, - struct bttv_buffer *buf, +static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, const struct bttv_format *fmt, unsigned int width, unsigned int height, enum v4l2_field field) @@ -1517,7 +1450,7 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, /* alloc risc memory */ if (STATE_NEEDS_INIT == buf->vb.state) { redo_dma_risc = 1; - if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf))) + if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf))) goto fail; } @@ -1529,7 +1462,7 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, return 0; fail: - bttv_dma_free(q,btv,buf); + bttv_dma_free(btv,buf); return rc; } @@ -1553,7 +1486,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); struct bttv_fh *fh = q->priv_data; - return bttv_prepare_buffer(q,fh->btv, buf, fh->fmt, + return bttv_prepare_buffer(fh->btv, buf, fh->fmt, fh->width, fh->height, field); } @@ -1577,7 +1510,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); struct bttv_fh *fh = q->priv_data; - bttv_dma_free(&fh->cap,fh->btv,buf); + bttv_dma_free(fh->btv,buf); } static struct videobuf_queue_ops bttv_video_qops = { @@ -1602,16 +1535,12 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) } case VIDIOCSFREQ: { - struct v4l2_frequency freq; - - memset(&freq, 0, sizeof(freq)); - freq.frequency = *(unsigned long *)arg; + unsigned long *freq = arg; mutex_lock(&btv->lock); - freq.type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - btv->freq = *(unsigned long *)arg; - bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,&freq); + btv->freq=*freq; + bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq); if (btv->has_matchbox && btv->radio_user) - tea5757_set_freq(btv,*(unsigned long *)arg); + tea5757_set_freq(btv,*freq); mutex_unlock(&btv->lock); return 0; } @@ -1724,7 +1653,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&btv->lock); - audio_mute(btv, (v->flags&VIDEO_AUDIO_MUTE) ? 1 : 0); + audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE); bttv_call_i2c_clients(btv,cmd,v); /* card specific hooks */ @@ -1842,26 +1771,33 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&btv->lock); memset(t,0,sizeof(*t)); - t->rxsubchans = V4L2_TUNER_SUB_MONO; - bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); strcpy(t->name, "Television"); - t->capability = V4L2_TUNER_CAP_NORM; t->type = V4L2_TUNER_ANALOG_TV; + t->capability = V4L2_TUNER_CAP_NORM; + t->rxsubchans = V4L2_TUNER_SUB_MONO; if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) t->signal = 0xffff; - - if (btv->audio_hook) { + { + struct video_tuner tuner; + + memset(&tuner, 0, sizeof (tuner)); + tuner.rangehigh = 0xffffffffUL; + bttv_call_i2c_clients(btv, VIDIOCGTUNER, &tuner); + t->rangelow = tuner.rangelow; + t->rangehigh = tuner.rangehigh; + } + { /* Hmmm ... */ struct video_audio va; memset(&va, 0, sizeof(struct video_audio)); - btv->audio_hook(btv,&va,0); - t->audmode = V4L2_TUNER_MODE_MONO; - t->rxsubchans = V4L2_TUNER_SUB_MONO; + bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); + if (btv->audio_hook) + btv->audio_hook(btv,&va,0); if(va.mode & VIDEO_SOUND_STEREO) { - t->audmode = V4L2_TUNER_MODE_STEREO; - t->rxsubchans = V4L2_TUNER_SUB_STEREO; + t->audmode = V4L2_TUNER_MODE_STEREO; + t->rxsubchans |= V4L2_TUNER_SUB_STEREO; } - if(va.mode & VIDEO_SOUND_LANG2) { + if(va.mode & VIDEO_SOUND_LANG1) { t->audmode = V4L2_TUNER_MODE_LANG1; t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; @@ -1880,20 +1816,21 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) if (0 != t->index) return -EINVAL; mutex_lock(&btv->lock); - bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t); - if (btv->audio_hook) { + { struct video_audio va; memset(&va, 0, sizeof(struct video_audio)); + bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); if (t->audmode == V4L2_TUNER_MODE_MONO) va.mode = VIDEO_SOUND_MONO; - else if (t->audmode == V4L2_TUNER_MODE_STEREO || - t->audmode == V4L2_TUNER_MODE_LANG1_LANG2) + else if (t->audmode == V4L2_TUNER_MODE_STEREO) va.mode = VIDEO_SOUND_STEREO; else if (t->audmode == V4L2_TUNER_MODE_LANG1) va.mode = VIDEO_SOUND_LANG1; else if (t->audmode == V4L2_TUNER_MODE_LANG2) va.mode = VIDEO_SOUND_LANG2; - btv->audio_hook(btv,&va,1); + bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va); + if (btv->audio_hook) + btv->audio_hook(btv,&va,1); } mutex_unlock(&btv->lock); return 0; @@ -1918,7 +1855,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&btv->lock); btv->freq = f->frequency; - bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,f); + bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq); if (btv->has_matchbox && btv->radio_user) tea5757_set_freq(btv,btv->freq); mutex_unlock(&btv->lock); @@ -1926,9 +1863,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) } case VIDIOC_LOG_STATUS: { - printk(KERN_INFO "bttv%d: ================= START STATUS CARD #%d =================\n", btv->c.nr, btv->c.nr); bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL); - printk(KERN_INFO "bttv%d: ================== END STATUS CARD #%d ==================\n", btv->c.nr, btv->c.nr); return 0; } @@ -2030,7 +1965,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, BUG(); } - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); kfree(fh->ov.clips); fh->ov.clips = clips; fh->ov.nclips = n; @@ -2051,7 +1986,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); retval = bttv_switch_overlay(btv,fh,new); } - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return retval; } @@ -2231,7 +2166,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, fmt = format_by_fourcc(f->fmt.pix.pixelformat); /* update our state informations */ - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); fh->fmt = fmt; fh->cap.field = f->fmt.pix.field; fh->cap.last = V4L2_FIELD_NONE; @@ -2240,7 +2175,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, btv->init.fmt = fmt; btv->init.width = f->fmt.pix.width; btv->init.height = f->fmt.pix.height; - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return 0; } @@ -2347,7 +2282,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, fmt = format_by_palette(pic->palette); if (NULL == fmt) return -EINVAL; - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); if (fmt->depth != pic->depth) { retval = -EINVAL; goto fh_unlock_and_return; @@ -2378,7 +2313,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, bt848_contrast(btv,pic->contrast); bt848_hue(btv,pic->hue); bt848_sat(btv,pic->colour); - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return 0; } @@ -2444,7 +2379,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, return -EPERM; end = (unsigned long)fbuf->base + fbuf->height * fbuf->bytesperline; - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); retval = -EINVAL; switch (fbuf->depth) { @@ -2482,7 +2417,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, btv->fbuf.fmt.bytesperline = fbuf->bytesperline; else btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8; - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return 0; } @@ -2505,7 +2440,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY)) return -EBUSY; - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); if (*on) { fh->ov.tvnorm = btv->tvnorm; new = videobuf_alloc(sizeof(*new)); @@ -2516,7 +2451,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, /* switch over */ retval = bttv_switch_overlay(btv,fh,new); - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return retval; } @@ -2525,7 +2460,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, struct video_mbuf *mbuf = arg; unsigned int i; - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize, V4L2_MEMORY_MMAP); if (retval < 0) @@ -2535,7 +2470,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, mbuf->size = gbuffers * gbufsize; for (i = 0; i < gbuffers; i++) mbuf->offsets[i] = i * gbufsize; - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return 0; } case VIDIOCMCAPTURE: @@ -2547,7 +2482,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, if (vm->frame >= VIDEO_MAX_FRAME) return -EINVAL; - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); retval = -EINVAL; buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame]; if (NULL == buf) @@ -2561,7 +2496,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2) ? V4L2_FIELD_INTERLACED : V4L2_FIELD_BOTTOM; - retval = bttv_prepare_buffer(&fh->cap,btv,buf, + retval = bttv_prepare_buffer(btv,buf, format_by_palette(vm->format), vm->width,vm->height,field); if (0 != retval) @@ -2569,7 +2504,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, spin_lock_irqsave(&btv->s_lock,flags); buffer_queue(&fh->cap,&buf->vb); spin_unlock_irqrestore(&btv->s_lock,flags); - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return 0; } case VIDIOCSYNC: @@ -2580,7 +2515,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, if (*frame >= VIDEO_MAX_FRAME) return -EINVAL; - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); retval = -EINVAL; buf = (struct bttv_buffer *)fh->cap.bufs[*frame]; if (NULL == buf) @@ -2593,14 +2528,14 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, retval = -EIO; /* fall through */ case STATE_DONE: - videobuf_dma_sync(&fh->cap,&buf->vb.dma); - bttv_dma_free(&fh->cap,btv,buf); + videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma); + bttv_dma_free(btv,buf); break; default: retval = -EINVAL; break; } - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return retval; } @@ -2784,7 +2719,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) return -EINVAL; - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); retval = -EINVAL; if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth) @@ -2824,7 +2759,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, retval = bttv_switch_overlay(btv,fh,new); } } - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return retval; } @@ -2878,10 +2813,12 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, return 0; } *c = bttv_ctls[i]; - if (btv->audio_hook && i >= 4 && i <= 8) { + if (i >= 4 && i <= 8) { struct video_audio va; memset(&va,0,sizeof(va)); - btv->audio_hook(btv,&va,0); + bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va); + if (btv->audio_hook) + btv->audio_hook(btv,&va,0); switch (bttv_ctls[i].id) { case V4L2_CID_AUDIO_VOLUME: if (!(va.flags & VIDEO_AUDIO_VOLUME)) @@ -2953,7 +2890,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, return 0; fh_unlock_and_return: - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return retval; } @@ -3020,16 +2957,16 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); } else { /* read() capture */ - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); if (NULL == fh->cap.read_buf) { /* need to capture a new frame */ if (locked_btres(fh->btv,RESOURCE_VIDEO)) { - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return POLLERR; } fh->cap.read_buf = videobuf_alloc(fh->cap.msize); if (NULL == fh->cap.read_buf) { - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return POLLERR; } fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; @@ -3037,13 +2974,13 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) { kfree (fh->cap.read_buf); fh->cap.read_buf = NULL; - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return POLLERR; } fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); fh->cap.read_off = 0; } - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); buf = (struct bttv_buffer*)fh->cap.read_buf; } @@ -3225,8 +3162,8 @@ static int radio_open(struct inode *inode, struct file *file) file->private_data = btv; - bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL); - audio_input(btv,TVAUDIO_INPUT_RADIO); + bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type); + audio_mux(btv,AUDIO_RADIO); mutex_unlock(&btv->lock); return 0; @@ -3812,7 +3749,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) bttv_irq_switch_video(btv); if ((astat & BT848_INT_HLOCK) && btv->opt_automute) - audio_mute(btv, btv->mute); /* trigger automute */ + audio_mux(btv, -1); if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) { printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr, @@ -4113,7 +4050,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, bt848_contrast(btv,32768); bt848_hue(btv,32768); bt848_sat(btv,32768); - audio_mute(btv, 1); + audio_mux(btv,AUDIO_MUTE); set_input(btv,0); } diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bttv-gpio.c similarity index 100% rename from drivers/media/video/bt8xx/bttv-gpio.c rename to drivers/media/video/bttv-gpio.c diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bttv-i2c.c similarity index 98% rename from drivers/media/video/bt8xx/bttv-i2c.c rename to drivers/media/video/bttv-i2c.c index 4b562b386..614c12018 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -302,10 +302,6 @@ static int attach_inform(struct i2c_client *client) if (!client->driver->command) return 0; - if (client->driver->id == I2C_DRIVERID_MSP3400) - btv->i2c_msp34xx_client = client; - if (client->driver->id == I2C_DRIVERID_TVAUDIO) - btv->i2c_tvaudio_client = client; if (btv->tuner_type != UNSET) { struct tuner_setup tun_setup; diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/video/bttv-if.c similarity index 100% rename from drivers/media/video/bt8xx/bttv-if.c rename to drivers/media/video/bttv-if.c diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bttv-risc.c similarity index 96% rename from drivers/media/video/bt8xx/bttv-risc.c rename to drivers/media/video/bttv-risc.c index afcfe71e3..b40e9734b 100644 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ b/drivers/media/video/bttv-risc.c @@ -51,10 +51,8 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, int rc; /* estimate risc mem: worst case is one write per page border + - one write per scan line + sync + jump (all 2 dwords). padding - can cause next bpl to start close to a page border. First DMA - region may be smaller than PAGE_SIZE */ - instructions = 1 + ((bpl + padding) * lines) / PAGE_SIZE + lines; + one write per scan line + sync + jump (all 2 dwords) */ + instructions = (bpl * lines) / PAGE_SIZE + lines; instructions += 2; if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) return rc; @@ -106,7 +104,7 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); + BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); return 0; } @@ -224,7 +222,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); + BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); return 0; } @@ -233,7 +231,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, const struct bttv_format *fmt, struct bttv_overlay *ov, int skip_even, int skip_odd) { - int dwords,rc,line,maxy,start,end,skip,nskips; + int instructions,rc,line,maxy,start,end,skip,nskips; struct btcx_skiplist *skips; u32 *rp,ri,ra; u32 addr; @@ -242,12 +240,12 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL))) return -ENOMEM; - /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions + /* estimate risc mem: worst case is (clip+1) * lines instructions + sync + jump (all 2 dwords) */ - dwords = (3 * ov->nclips + 2) * - ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height); - dwords += 4; - if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) { + instructions = (ov->nclips + 1) * + ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height); + instructions += 2; + if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) { kfree(skips); return rc; } @@ -309,7 +307,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); + BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); kfree(skips); return 0; } @@ -507,11 +505,12 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, } void -bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf) +bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf) { - BUG_ON(in_interrupt()); + if (in_interrupt()) + BUG(); videobuf_waiton(&buf->vb,0,0); - videobuf_dma_unmap(q, &buf->vb.dma); + videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma); videobuf_dma_free(&buf->vb.dma); btcx_riscmem_free(btv->c.pci,&buf->bottom); btcx_riscmem_free(btv->c.pci,&buf->top); diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bttv-vbi.c similarity index 97% rename from drivers/media/video/bt8xx/bttv-vbi.c rename to drivers/media/video/bttv-vbi.c index 8c9f0f7cf..72afdd64b 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bttv-vbi.c @@ -96,7 +96,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q, return -EINVAL; if (STATE_NEEDS_INIT == buf->vb.state) { - if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) + if (0 != (rc = videobuf_iolock(btv->c.pci, &buf->vb, NULL))) goto fail; if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines))) goto fail; @@ -109,7 +109,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q, return 0; fail: - bttv_dma_free(q,btv,buf); + bttv_dma_free(btv,buf); return rc; } @@ -136,7 +136,7 @@ static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); dprintk("free %p\n",vb); - bttv_dma_free(&fh->cap,fh->btv,buf); + bttv_dma_free(fh->btv,buf); } struct videobuf_queue_ops bttv_vbi_qops = { @@ -184,7 +184,7 @@ void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) - tvnorm->vbistart[0]; count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1] - tvnorm->vbistart[1]; - count = clamp (max (count0, count1), (s64) 1, (s64) VBI_MAXLINES); + count = clamp (max (count0, count1), 1LL, (s64) VBI_MAXLINES); f->fmt.vbi.start[0] = tvnorm->vbistart[0]; f->fmt.vbi.start[1] = tvnorm->vbistart[1]; diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bttv.h similarity index 95% rename from drivers/media/video/bt8xx/bttv.h rename to drivers/media/video/bttv.h index 3a23265c1..9908c8e0c 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bttv.h @@ -18,7 +18,6 @@ #include #include #include -#include /* ---------------------------------------------------------- */ /* exported by bttv-cards.c */ @@ -169,6 +168,25 @@ #define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f #define BTTV_BOARD_MACHTV_MAGICTV 0x90 +/* i2c address list */ +#define I2C_TSA5522 0xc2 +#define I2C_TDA7432 0x8a +#define I2C_BT832_ALT1 0x88 +#define I2C_BT832_ALT2 0x8a // alternate setting +#define I2C_TDA8425 0x82 +#define I2C_TDA9840 0x84 +#define I2C_TDA9850 0xb6 /* also used by 9855,9873 */ +#define I2C_TDA9874 0xb0 /* also used by 9875 */ +#define I2C_TDA9875 0xb0 +#define I2C_HAUPEE 0xa0 +#define I2C_STBEE 0xae +#define I2C_VHX 0xc0 +#define I2C_MSP3400 0x80 +#define I2C_MSP3400_ALT 0x88 +#define I2C_TEA6300 0x80 /* also used by 6320 */ +#define I2C_DPL3518 0x84 +#define I2C_TDA9887 0x86 + /* more card-specific defines */ #define PT2254_L_CHANNEL 0x10 #define PT2254_R_CHANNEL 0x08 @@ -234,8 +252,7 @@ struct tvcard unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO u32 gpiomask; u32 muxsel[16]; - u32 gpiomux[4]; /* Tuner, Radio, external, internal */ - u32 gpiomute; /* GPIO mute setting */ + u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ u32 gpiomask2; /* GPIO MUX mask */ /* i2c audio flags */ diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bttvp.h similarity index 98% rename from drivers/media/video/bt8xx/bttvp.h rename to drivers/media/video/bttvp.h index ee989d2e1..9cb72f176 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bttvp.h @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -189,8 +190,7 @@ int bttv_buffer_activate_video(struct bttv *btv, struct bttv_buffer_set *set); int bttv_buffer_activate_vbi(struct bttv *btv, struct bttv_buffer *vbi); -void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv, - struct bttv_buffer *buf); +void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf); /* overlay handling */ int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, @@ -298,8 +298,6 @@ struct bttv { int i2c_state, i2c_rc; int i2c_done; wait_queue_head_t i2c_queue; - struct i2c_client *i2c_msp34xx_client; - struct i2c_client *i2c_tvaudio_client; /* video4linux (1) */ struct video_device *video_dev; @@ -322,7 +320,6 @@ struct bttv { /* video state */ unsigned int input; unsigned int audio; - unsigned int mute; unsigned long freq; int tvnorm,hue,contrast,bright,saturation; struct v4l2_framebuffer fbuf; diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index cf61c590f..6bad93ef9 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -73,7 +73,7 @@ OTHER DEALINGS IN THE SOFTWARE. #include #include #include -#include +#include #include #include "bw-qcam.h" @@ -150,7 +150,7 @@ static int qc_calibrate(struct qcam_device *q) static struct qcam_device *qcam_init(struct parport *port) { struct qcam_device *q; - + q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); if(q==NULL) return NULL; @@ -158,17 +158,17 @@ static struct qcam_device *qcam_init(struct parport *port) q->pport = port; q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, NULL, 0, NULL); - if (q->pdev == NULL) + if (q->pdev == NULL) { printk(KERN_ERR "bw-qcam: couldn't register for %s.\n", port->name); kfree(q); return NULL; } - + memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); - - mutex_init(&q->lock); + + init_MUTEX(&q->lock); q->port_mode = (QC_ANY | QC_NOTSET); q->width = 320; @@ -236,12 +236,12 @@ static int qc_waithand(struct qcam_device *q, int val) while (!((status = read_lpstatus(q)) & 8)) { /* 1000 is enough spins on the I/O for all normal - cases, at that point we start to poll slowly + cases, at that point we start to poll slowly until the camera wakes up. However, we are busy blocked until the camera responds, so setting it lower is much better for interactive response. */ - + if(runs++>maxpoll) { msleep_interruptible(5); @@ -255,12 +255,12 @@ static int qc_waithand(struct qcam_device *q, int val) while (((status = read_lpstatus(q)) & 8)) { /* 1000 is enough spins on the I/O for all normal - cases, at that point we start to poll slowly + cases, at that point we start to poll slowly until the camera wakes up. However, we are busy blocked until the camera responds, so setting it lower is much better for interactive response. */ - + if(runs++>maxpoll) { msleep_interruptible(5); @@ -282,17 +282,17 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val) { unsigned int status; int runs=0; - - do + + do { status = read_lpdata(q); /* 1000 is enough spins on the I/O for all normal - cases, at that point we start to poll slowly + cases, at that point we start to poll slowly until the camera wakes up. However, we are busy blocked until the camera responds, so setting it lower is much better for interactive response. */ - + if(runs++>maxpoll) { msleep_interruptible(5); @@ -321,7 +321,7 @@ static int qc_detect(struct qcam_device *q) lastreg = reg = read_lpstatus(q) & 0xf0; - for (i = 0; i < 500; i++) + for (i = 0; i < 500; i++) { reg = read_lpstatus(q) & 0xf0; if (reg != lastreg) @@ -357,7 +357,7 @@ static int qc_detect(struct qcam_device *q) static void qc_reset(struct qcam_device *q) { - switch (q->port_mode & QC_FORCE_MASK) + switch (q->port_mode & QC_FORCE_MASK) { case QC_FORCE_UNIDIR: q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; @@ -370,7 +370,7 @@ static void qc_reset(struct qcam_device *q) case QC_ANY: write_lpcontrol(q, 0x20); write_lpdata(q, 0x75); - + if (read_lpdata(q) != 0x75) { q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; } else { @@ -398,8 +398,8 @@ static void qc_reset(struct qcam_device *q) static int qc_setscanmode(struct qcam_device *q) { int old_mode = q->mode; - - switch (q->transfer_scale) + + switch (q->transfer_scale) { case 1: q->mode = 0; @@ -412,7 +412,7 @@ static int qc_setscanmode(struct qcam_device *q) break; } - switch (q->bpp) + switch (q->bpp) { case 4: break; @@ -421,7 +421,7 @@ static int qc_setscanmode(struct qcam_device *q) break; } - switch (q->port_mode & QC_MODE_MASK) + switch (q->port_mode & QC_MODE_MASK) { case QC_BIDIR: q->mode += 1; @@ -430,10 +430,10 @@ static int qc_setscanmode(struct qcam_device *q) case QC_UNIDIR: break; } - + if (q->mode != old_mode) q->status |= QC_PARAM_CHANGE; - + return 0; } @@ -451,7 +451,7 @@ static void qc_set(struct qcam_device *q) /* Set the brightness. Yes, this is repetitive, but it works. * Shorter versions seem to fail subtly. Feel free to try :-). */ /* I think the problem was in qc_command, not here -- bls */ - + qc_command(q, 0xb); qc_command(q, q->brightness); @@ -502,13 +502,13 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) unsigned int hi2, lo2; static int state = 0; - if (buffer == NULL) + if (buffer == NULL) { state = 0; return 0; } - - switch (q->port_mode & QC_MODE_MASK) + + switch (q->port_mode & QC_MODE_MASK) { case QC_BIDIR: /* Bi-directional Port */ write_lpcontrol(q, 0x26); @@ -517,7 +517,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) write_lpcontrol(q, 0x2e); lo2 = (qc_waithand2(q, 0) >> 1); hi2 = (read_lpstatus(q) >> 3) & 0x1f; - switch (q->bpp) + switch (q->bpp) { case 4: buffer[0] = lo & 0xf; @@ -544,7 +544,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) write_lpcontrol(q, 0xe); hi = (qc_waithand(q, 0) & 0xf0) >> 4; - switch (q->bpp) + switch (q->bpp) { case 4: buffer[0] = lo; @@ -552,7 +552,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) ret = 2; break; case 6: - switch (state) + switch (state) { case 0: buffer[0] = (lo << 2) | ((hi & 0xc) >> 2); @@ -604,13 +604,13 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l int shift=8-q->bpp; char invert; - if (q->mode == -1) + if (q->mode == -1) return -ENXIO; qc_command(q, 0x7); qc_command(q, q->mode); - if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) + if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) { write_lpcontrol(q, 0x2e); /* turn port around */ write_lpcontrol(q, 0x26); @@ -618,7 +618,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l write_lpcontrol(q, 0x2e); (void) qc_waithand(q, 0); } - + /* strange -- should be 15:63 below, but 4bpp is odd */ invert = (q->bpp == 4) ? 16 : 63; @@ -629,15 +629,15 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l q->transfer_scale; transperline = (transperline + divisor - 1) / divisor; - for (i = 0, yield = yieldlines; i < linestotrans; i++) + for (i = 0, yield = yieldlines; i < linestotrans; i++) { - for (pixels_read = j = 0; j < transperline; j++) + for (pixels_read = j = 0; j < transperline; j++) { bytes = qc_readbytes(q, buffer); - for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) + for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) { int o; - if (buffer[k] == 0 && invert == 16) + if (buffer[k] == 0 && invert == 16) { /* 4bpp is odd (again) -- inverter is 16, not 15, but output must be 0-15 -- bls */ @@ -653,7 +653,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l pixels_read += bytes; } (void) qc_readbytes(q, NULL); /* reset state machine */ - + /* Grabbing an entire frame from the quickcam is a lengthy process. We don't (usually) want to busy-block the processor for the entire frame. yieldlines is a module @@ -666,7 +666,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l } } - if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) + if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) { write_lpcontrol(q, 2); write_lpcontrol(q, 6); @@ -687,7 +687,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, { struct video_device *dev = video_devdata(file); struct qcam_device *qcam=(struct qcam_device *)dev; - + switch(cmd) { case VIDIOCGCAP: @@ -762,7 +762,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if(p->depth!=4 && p->depth!=6) return -EINVAL; - + /* * Now load the camera. */ @@ -772,9 +772,9 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, qcam->whitebal = p->whiteness>>8; qcam->bpp = p->depth; - mutex_lock(&qcam->lock); + down(&qcam->lock); qc_setscanmode(qcam); - mutex_unlock(&qcam->lock); + up(&qcam->lock); qcam->status |= QC_PARAM_CHANGE; return 0; @@ -790,11 +790,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if(vw->width<80||vw->width>320) return -EINVAL; - + qcam->width = 320; qcam->height = 240; qcam->transfer_scale = 4; - + if(vw->width>=160 && vw->height>=120) { qcam->transfer_scale = 2; @@ -805,14 +805,14 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, qcam->height = 240; qcam->transfer_scale = 1; } - mutex_lock(&qcam->lock); + down(&qcam->lock); qc_setscanmode(qcam); - mutex_unlock(&qcam->lock); - + up(&qcam->lock); + /* We must update the camera before we grab. We could just have changed the grab size */ qcam->status |= QC_PARAM_CHANGE; - + /* Ok we figured out what to use from our wide choice */ return 0; } @@ -853,9 +853,9 @@ static ssize_t qcam_read(struct file *file, char __user *buf, struct qcam_device *qcam=(struct qcam_device *)v; int len; parport_claim_or_block(qcam->pdev); - - mutex_lock(&qcam->lock); - + + down(&qcam->lock); + qc_reset(qcam); /* Update the camera parameters if we need to */ @@ -863,13 +863,13 @@ static ssize_t qcam_read(struct file *file, char __user *buf, qc_set(qcam); len=qc_capture(qcam, buf,count); - - mutex_unlock(&qcam->lock); - + + up(&qcam->lock); + parport_release(qcam->pdev); return len; } - + static struct file_operations qcam_fops = { .owner = THIS_MODULE, .open = video_exclusive_open, @@ -905,11 +905,11 @@ static int init_bwqcam(struct parport *port) qcam=qcam_init(port); if(qcam==NULL) return -ENODEV; - + parport_claim_or_block(qcam->pdev); qc_reset(qcam); - + if(qc_detect(qcam)==0) { parport_release(qcam->pdev); @@ -920,9 +920,9 @@ static int init_bwqcam(struct parport *port) qc_calibrate(qcam); parport_release(qcam->pdev); - + printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name); - + if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1) { parport_unregister_device(qcam->pdev); @@ -1013,7 +1013,7 @@ static int __init init_bw_qcams(void) printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n"); maxpoll = 5000; } - + if (yieldlines < 1) { printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n"); yieldlines = 1; diff --git a/drivers/media/video/bw-qcam.h b/drivers/media/video/bw-qcam.h index 6701dafbc..723e8ad9e 100644 --- a/drivers/media/video/bw-qcam.h +++ b/drivers/media/video/bw-qcam.h @@ -55,7 +55,7 @@ struct qcam_device { struct video_device vdev; struct pardevice *pdev; struct parport *pport; - struct mutex lock; + struct semaphore lock; int width, height; int bpp; int mode; diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 22a7386bb..9976db4f6 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -16,7 +16,7 @@ * * The parport parameter controls which parports will be scanned. * Scanning all parports causes some printers to print a garbage page. - * -- March 14, 1999 Billy Donahue + * -- March 14, 1999 Billy Donahue * * Fixed data format to BGR, added force_rgb parameter. Added missing * parport_unregister_driver() on module removal. @@ -34,8 +34,7 @@ #include #include #include -#include - +#include #include struct qcam_device { @@ -48,7 +47,7 @@ struct qcam_device { int contrast, brightness, whitebal; int top, left; unsigned int bidirectional; - struct mutex lock; + struct semaphore lock; }; /* cameras maximum */ @@ -88,7 +87,7 @@ static inline unsigned int qcam_ready2(struct qcam_device *qcam) return (parport_read_data(qcam->pport) & 0x1)?1:0; } -static unsigned int qcam_await_ready1(struct qcam_device *qcam, +static unsigned int qcam_await_ready1(struct qcam_device *qcam, int value) { unsigned long oldjiffies = jiffies; @@ -98,7 +97,7 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam, if (qcam_ready1(qcam) == value) return 0; - /* If the camera didn't respond within 1/25 second, poll slowly + /* If the camera didn't respond within 1/25 second, poll slowly for a while. */ for (i = 0; i < 50; i++) { @@ -123,7 +122,7 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) if (qcam_ready2(qcam) == value) return 0; - /* If the camera didn't respond within 1/25 second, poll slowly + /* If the camera didn't respond within 1/25 second, poll slowly for a while. */ for (i = 0; i < 50; i++) { @@ -157,12 +156,12 @@ static int qcam_write_data(struct qcam_device *qcam, unsigned int data) unsigned int idata; parport_write_data(qcam->pport, data); idata = qcam_read_data(qcam); - if (data != idata) + if (data != idata) { - printk(KERN_WARNING "cqcam: sent %x but received %x\n", data, + printk(KERN_WARNING "cqcam: sent %x but received %x\n", data, idata); return 1; - } + } return 0; } @@ -193,12 +192,12 @@ static int qc_detect(struct qcam_device *qcam) no device was found". Fix this one day. */ if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA && qcam->pport->probe_info[0].model - && !strcmp(qcam->pdev->port->probe_info[0].model, + && !strcmp(qcam->pdev->port->probe_info[0].model, "Color QuickCam 2.0")) { printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n"); return 1; } - + if (probe < 2) return 0; @@ -206,11 +205,11 @@ static int qc_detect(struct qcam_device *qcam) /* look for a heartbeat */ ostat = stat = parport_read_status(qcam->pport); - for (i=0; i<250; i++) + for (i=0; i<250; i++) { mdelay(1); stat = parport_read_status(qcam->pport); - if (ostat != stat) + if (ostat != stat) { if (++count >= 3) return 1; ostat = stat; @@ -226,11 +225,11 @@ static int qc_detect(struct qcam_device *qcam) count = 0; ostat = stat = parport_read_status(qcam->pport); - for (i=0; i<250; i++) + for (i=0; i<250; i++) { mdelay(1); stat = parport_read_status(qcam->pport); - if (ostat != stat) + if (ostat != stat) { if (++count >= 3) return 1; ostat = stat; @@ -247,7 +246,7 @@ static void qc_reset(struct qcam_device *qcam) parport_write_control(qcam->pport, 0x8); mdelay(1); parport_write_control(qcam->pport, 0xc); - mdelay(1); + mdelay(1); } /* Reset the QuickCam and program for brightness, contrast, @@ -258,7 +257,7 @@ static void qc_setup(struct qcam_device *q) qc_reset(q); /* Set the brightness. */ - qcam_set(q, 11, q->brightness); + qcam_set(q, 11, q->brightness); /* Set the height and width. These refer to the actual CCD area *before* applying the selected decimation. */ @@ -272,12 +271,12 @@ static void qc_setup(struct qcam_device *q) /* Set contrast and white balance. */ qcam_set(q, 0x19, q->contrast); qcam_set(q, 0x1f, q->whitebal); - + /* Set the speed. */ qcam_set(q, 45, 2); } -/* Read some bytes from the camera and put them in the buffer. +/* Read some bytes from the camera and put them in the buffer. nbytes should be a multiple of 3, because bidirectional mode gives us three bytes at a time. */ @@ -383,7 +382,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1)) return -EIO; - + lines = q->height; pixelsperline = q->width; bitsperxfer = (is_bi_dir) ? 24 : 8; @@ -499,7 +498,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, { struct video_device *dev = video_devdata(file); struct qcam_device *qcam=(struct qcam_device *)dev; - + switch(cmd) { case VIDIOCGCAP: @@ -574,7 +573,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, */ if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24) return -EINVAL; - + /* * Now load the camera. */ @@ -582,11 +581,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, qcam->contrast = p->contrast>>8; qcam->whitebal = p->whiteness>>8; - mutex_lock(&qcam->lock); + down(&qcam->lock); parport_claim_or_block(qcam->pdev); - qc_setup(qcam); + qc_setup(qcam); parport_release(qcam->pdev); - mutex_unlock(&qcam->lock); + up(&qcam->lock); return 0; } case VIDIOCSWIN: @@ -601,11 +600,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if(vw->width<80||vw->width>320) return -EINVAL; - + qcam->width = 80; qcam->height = 60; qcam->mode = QC_DECIMATION_4; - + if(vw->width>=160 && vw->height>=120) { qcam->width = 160; @@ -627,13 +626,13 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, qcam->mode = QC_BILLIONS | QC_DECIMATION_1; } #endif - /* Ok we figured out what to use from our + /* Ok we figured out what to use from our wide choice */ - mutex_lock(&qcam->lock); + down(&qcam->lock); parport_claim_or_block(qcam->pdev); qc_setup(qcam); parport_release(qcam->pdev); - mutex_unlock(&qcam->lock); + up(&qcam->lock); return 0; } case VIDIOCGWIN: @@ -673,12 +672,12 @@ static ssize_t qcam_read(struct file *file, char __user *buf, struct qcam_device *qcam=(struct qcam_device *)v; int len; - mutex_lock(&qcam->lock); + down(&qcam->lock); parport_claim_or_block(qcam->pdev); /* Probably should have a semaphore against multiple users */ - len = qc_capture(qcam, buf,count); + len = qc_capture(qcam, buf,count); parport_release(qcam->pdev); - mutex_unlock(&qcam->lock); + up(&qcam->lock); return len; } @@ -707,7 +706,7 @@ static struct video_device qcam_template= static struct qcam_device *qcam_init(struct parport *port) { struct qcam_device *q; - + q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); if(q==NULL) return NULL; @@ -718,17 +717,17 @@ static struct qcam_device *qcam_init(struct parport *port) q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0; - if (q->pdev == NULL) + if (q->pdev == NULL) { printk(KERN_ERR "c-qcam: couldn't register for %s.\n", port->name); kfree(q); return NULL; } - + memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); - mutex_init(&q->lock); + init_MUTEX(&q->lock); q->width = q->ccd_width = 320; q->height = q->ccd_height = 240; q->mode = QC_MILLIONS | QC_DECIMATION_1; @@ -766,11 +765,11 @@ static int init_cqcam(struct parport *port) qcam = qcam_init(port); if (qcam==NULL) return -ENODEV; - + parport_claim_or_block(qcam->pdev); qc_reset(qcam); - + if (probe && qc_detect(qcam)==0) { parport_release(qcam->pdev); @@ -782,7 +781,7 @@ static int init_cqcam(struct parport *port) qc_setup(qcam); parport_release(qcam->pdev); - + if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1) { printk(KERN_ERR "Unable to register Colour QuickCam on %s\n", @@ -792,9 +791,9 @@ static int init_cqcam(struct parport *port) return -ENODEV; } - printk(KERN_INFO "video%d: Colour QuickCam found on %s\n", + printk(KERN_INFO "video%d: Colour QuickCam found on %s\n", qcam->vdev.minor, qcam->pport->name); - + qcams[num_cams++] = qcam; return 0; diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 85d84e89d..85d964b5b 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -24,7 +24,7 @@ */ /* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */ -/* #define _CPIA_DEBUG_ 1 */ +/* #define _CPIA_DEBUG_ 1 */ #include @@ -39,7 +39,7 @@ #include #include #include -#include +#include #ifdef CONFIG_KMOD #include @@ -58,19 +58,20 @@ static int video_nr = -1; #ifdef MODULE module_param(video_nr, int, 0); -MODULE_AUTHOR("Scott J. Bertin & Peter Pregler & Johannes Erdfelt "); +MODULE_AUTHOR("Scott J. Bertin & Peter Pregler & Johannes Erdfelt "); MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("video"); #endif -static unsigned short colorspace_conv; +static unsigned short colorspace_conv = 0; module_param(colorspace_conv, ushort, 0444); MODULE_PARM_DESC(colorspace_conv, - " Colorspace conversion:" - "\n 0 = disable, 1 = enable" - "\n Default value is 0" - ); + "\n Colorspace conversion:" + "\n0 = disable" + "\n1 = enable" + "\nDefault value is 0" + "\n"); #define ABOUT "V4L-Driver for Vision CPiA based cameras" @@ -188,8 +189,8 @@ enum { #define TC 94 #define EXP_ACC_DARK 50 #define EXP_ACC_LIGHT 90 -#define HIGH_COMP_102 160 -#define MAX_COMP 239 +#define HIGH_COMP_102 160 +#define MAX_COMP 239 #define DARK_TIME 3 #define LIGHT_TIME 3 @@ -207,7 +208,7 @@ static u8 flicker_jumps[2][2][4] = static void reset_camera_struct(struct cam_data *cam); static int find_over_exposure(int brightness); static void set_flicker(struct cam_params *params, volatile u32 *command_flags, - int on); + int on); /********************************************************************** @@ -261,7 +262,7 @@ static void rvfree(void *mem, unsigned long size) static struct proc_dir_entry *cpia_proc_root=NULL; static int cpia_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) + int count, int *eof, void *data) { char *out = page; int len, tmp; @@ -275,58 +276,58 @@ static int cpia_read_proc(char *page, char **start, off_t off, out += sprintf(out, "V4L Driver version: %d.%d.%d\n", CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER); out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n", - cam->params.version.firmwareVersion, - cam->params.version.firmwareRevision, - cam->params.version.vcVersion, - cam->params.version.vcRevision); + cam->params.version.firmwareVersion, + cam->params.version.firmwareRevision, + cam->params.version.vcVersion, + cam->params.version.vcRevision); out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n", - cam->params.pnpID.vendor, cam->params.pnpID.product, - cam->params.pnpID.deviceRevision); + cam->params.pnpID.vendor, cam->params.pnpID.product, + cam->params.pnpID.deviceRevision); out += sprintf(out, "VP-Version: %d.%d %04x\n", - cam->params.vpVersion.vpVersion, - cam->params.vpVersion.vpRevision, - cam->params.vpVersion.cameraHeadID); - + cam->params.vpVersion.vpVersion, + cam->params.vpVersion.vpRevision, + cam->params.vpVersion.cameraHeadID); + out += sprintf(out, "system_state: %#04x\n", - cam->params.status.systemState); + cam->params.status.systemState); out += sprintf(out, "grab_state: %#04x\n", - cam->params.status.grabState); + cam->params.status.grabState); out += sprintf(out, "stream_state: %#04x\n", - cam->params.status.streamState); + cam->params.status.streamState); out += sprintf(out, "fatal_error: %#04x\n", - cam->params.status.fatalError); + cam->params.status.fatalError); out += sprintf(out, "cmd_error: %#04x\n", - cam->params.status.cmdError); + cam->params.status.cmdError); out += sprintf(out, "debug_flags: %#04x\n", - cam->params.status.debugFlags); + cam->params.status.debugFlags); out += sprintf(out, "vp_status: %#04x\n", - cam->params.status.vpStatus); + cam->params.status.vpStatus); out += sprintf(out, "error_code: %#04x\n", - cam->params.status.errorCode); + cam->params.status.errorCode); /* QX3 specific entries */ if (cam->params.qx3.qx3_detected) { out += sprintf(out, "button: %4d\n", - cam->params.qx3.button); + cam->params.qx3.button); out += sprintf(out, "cradled: %4d\n", - cam->params.qx3.cradled); + cam->params.qx3.cradled); } out += sprintf(out, "video_size: %s\n", - cam->params.format.videoSize == VIDEOSIZE_CIF ? + cam->params.format.videoSize == VIDEOSIZE_CIF ? "CIF " : "QCIF"); out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n", - cam->params.roi.colStart*8, - cam->params.roi.rowStart*4, - cam->params.roi.colEnd*8, - cam->params.roi.rowEnd*4); + cam->params.roi.colStart*8, + cam->params.roi.rowStart*4, + cam->params.roi.colEnd*8, + cam->params.roi.rowEnd*4); out += sprintf(out, "actual_fps: %3d\n", cam->fps); out += sprintf(out, "transfer_rate: %4dkB/s\n", - cam->transfer_rate); - + cam->transfer_rate); + out += sprintf(out, "\nread-write\n"); out += sprintf(out, "----------------------- current min" - " max default comment\n"); + " max default comment\n"); out += sprintf(out, "brightness: %8d %8d %8d %8d\n", - cam->params.colourParams.brightness, 0, 100, 50); + cam->params.colourParams.brightness, 0, 100, 50); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) /* 1-02 firmware limits contrast to 80 */ @@ -335,26 +336,26 @@ static int cpia_read_proc(char *page, char **start, off_t off, tmp = 96; out += sprintf(out, "contrast: %8d %8d %8d %8d" - " steps of 8\n", - cam->params.colourParams.contrast, 0, tmp, 48); + " steps of 8\n", + cam->params.colourParams.contrast, 0, tmp, 48); out += sprintf(out, "saturation: %8d %8d %8d %8d\n", - cam->params.colourParams.saturation, 0, 100, 50); + cam->params.colourParams.saturation, 0, 100, 50); tmp = (25000+5000*cam->params.sensorFps.baserate)/ (1<params.sensorFps.divisor); out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n", - tmp/1000, tmp%1000, 3, 30, 15); + tmp/1000, tmp%1000, 3, 30, 15); out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n", - 2*cam->params.streamStartLine, 0, + 2*cam->params.streamStartLine, 0, cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144, cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120); out += sprintf(out, "sub_sample: %8s %8s %8s %8s\n", - cam->params.format.subSample == SUBSAMPLE_420 ? + cam->params.format.subSample == SUBSAMPLE_420 ? "420" : "422", "420", "422", "422"); out += sprintf(out, "yuv_order: %8s %8s %8s %8s\n", - cam->params.format.yuvOrder == YUVORDER_YUYV ? + cam->params.format.yuvOrder == YUVORDER_YUYV ? "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV"); out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n", - cam->params.ecpTiming ? "slow" : "normal", "slow", + cam->params.ecpTiming ? "slow" : "normal", "slow", "normal", "normal"); if (cam->params.colourBalance.balanceMode == 2) { @@ -365,11 +366,11 @@ static int cpia_read_proc(char *page, char **start, off_t off, out += sprintf(out, "color_balance_mode: %8s %8s %8s" " %8s\n", tmpstr, "manual", "auto", "auto"); out += sprintf(out, "red_gain: %8d %8d %8d %8d\n", - cam->params.colourBalance.redGain, 0, 212, 32); + cam->params.colourBalance.redGain, 0, 212, 32); out += sprintf(out, "green_gain: %8d %8d %8d %8d\n", - cam->params.colourBalance.greenGain, 0, 212, 6); + cam->params.colourBalance.greenGain, 0, 212, 6); out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n", - cam->params.colourBalance.blueGain, 0, 212, 92); + cam->params.colourBalance.blueGain, 0, 212, 92); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) @@ -380,11 +381,11 @@ static int cpia_read_proc(char *page, char **start, off_t off, if (cam->params.exposure.gainMode == 0) out += sprintf(out, "max_gain: unknown %28s" - " powers of 2\n", tmpstr); + " powers of 2\n", tmpstr); else out += sprintf(out, "max_gain: %8d %28s" " 1,2,4 or 8 \n", - 1<<(cam->params.exposure.gainMode-1), tmpstr); + 1<<(cam->params.exposure.gainMode-1), tmpstr); switch(cam->params.exposure.expMode) { case 1: @@ -401,10 +402,10 @@ static int cpia_read_proc(char *page, char **start, off_t off, out += sprintf(out, "exposure_mode: %8s %8s %8s" " %8s\n", tmpstr, "manual", "auto", "auto"); out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n", - (2-cam->params.exposure.centreWeight) ? "on" : "off", - "off", "on", "on"); + (2-cam->params.exposure.centreWeight) ? "on" : "off", + "off", "on", "on"); out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n", - 1<params.exposure.gain, 1, 1); + 1<params.exposure.gain, 1, 1); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) /* 1-02 firmware limits fineExp/2 to 127 */ @@ -413,7 +414,7 @@ static int cpia_read_proc(char *page, char **start, off_t off, tmp = 510; out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n", - cam->params.exposure.fineExp*2, 0, tmp, 0); + cam->params.exposure.fineExp*2, 0, tmp, 0); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) /* 1-02 firmware limits coarseExpHi to 0 */ @@ -425,46 +426,46 @@ static int cpia_read_proc(char *page, char **start, off_t off, " %8d\n", cam->params.exposure.coarseExpLo+ 256*cam->params.exposure.coarseExpHi, 0, tmp, 185); out += sprintf(out, "red_comp: %8d %8d %8d %8d\n", - cam->params.exposure.redComp, COMP_RED, 255, COMP_RED); + cam->params.exposure.redComp, COMP_RED, 255, COMP_RED); out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n", - cam->params.exposure.green1Comp, COMP_GREEN1, 255, + cam->params.exposure.green1Comp, COMP_GREEN1, 255, COMP_GREEN1); out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n", - cam->params.exposure.green2Comp, COMP_GREEN2, 255, + cam->params.exposure.green2Comp, COMP_GREEN2, 255, COMP_GREEN2); out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n", - cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE); - + cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE); + out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n", - cam->params.apcor.gain1, 0, 0xff, 0x1c); + cam->params.apcor.gain1, 0, 0xff, 0x1c); out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n", - cam->params.apcor.gain2, 0, 0xff, 0x1a); + cam->params.apcor.gain2, 0, 0xff, 0x1a); out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n", - cam->params.apcor.gain4, 0, 0xff, 0x2d); + cam->params.apcor.gain4, 0, 0xff, 0x2d); out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n", - cam->params.apcor.gain8, 0, 0xff, 0x2a); + cam->params.apcor.gain8, 0, 0xff, 0x2a); out += sprintf(out, "vl_offset_gain1: %8d %8d %8d %8d\n", - cam->params.vlOffset.gain1, 0, 255, 24); + cam->params.vlOffset.gain1, 0, 255, 24); out += sprintf(out, "vl_offset_gain2: %8d %8d %8d %8d\n", - cam->params.vlOffset.gain2, 0, 255, 28); + cam->params.vlOffset.gain2, 0, 255, 28); out += sprintf(out, "vl_offset_gain4: %8d %8d %8d %8d\n", - cam->params.vlOffset.gain4, 0, 255, 30); + cam->params.vlOffset.gain4, 0, 255, 30); out += sprintf(out, "vl_offset_gain8: %8d %8d %8d %8d\n", - cam->params.vlOffset.gain8, 0, 255, 30); + cam->params.vlOffset.gain8, 0, 255, 30); out += sprintf(out, "flicker_control: %8s %8s %8s %8s\n", - cam->params.flickerControl.flickerMode ? "on" : "off", + cam->params.flickerControl.flickerMode ? "on" : "off", "off", "on", "off"); out += sprintf(out, "mains_frequency: %8d %8d %8d %8d" - " only 50/60\n", - cam->mainsFreq ? 60 : 50, 50, 60, 50); + " only 50/60\n", + cam->mainsFreq ? 60 : 50, 50, 60, 50); if(cam->params.flickerControl.allowableOverExposure < 0) out += sprintf(out, "allowable_overexposure: %4dauto auto %8d auto\n", - -cam->params.flickerControl.allowableOverExposure, - 255); + -cam->params.flickerControl.allowableOverExposure, + 255); else out += sprintf(out, "allowable_overexposure: %8d auto %8d auto\n", - cam->params.flickerControl.allowableOverExposure, - 255); + cam->params.flickerControl.allowableOverExposure, + 255); out += sprintf(out, "compression_mode: "); switch(cam->params.compression.mode) { case CPIA_COMPRESSION_NONE: @@ -482,52 +483,52 @@ static int cpia_read_proc(char *page, char **start, off_t off, } out += sprintf(out, " none,auto,manual auto\n"); out += sprintf(out, "decimation_enable: %8s %8s %8s %8s\n", - cam->params.compression.decimation == - DECIMATION_ENAB ? "on":"off", "off", "on", + cam->params.compression.decimation == + DECIMATION_ENAB ? "on":"off", "off", "on", "off"); out += sprintf(out, "compression_target: %9s %9s %9s %9s\n", - cam->params.compressionTarget.frTargeting == + cam->params.compressionTarget.frTargeting == CPIA_COMPRESSION_TARGET_FRAMERATE ? "framerate":"quality", "framerate", "quality", "quality"); out += sprintf(out, "target_framerate: %8d %8d %8d %8d\n", - cam->params.compressionTarget.targetFR, 1, 30, 15); + cam->params.compressionTarget.targetFR, 1, 30, 15); out += sprintf(out, "target_quality: %8d %8d %8d %8d\n", - cam->params.compressionTarget.targetQ, 1, 64, 5); + cam->params.compressionTarget.targetQ, 1, 64, 5); out += sprintf(out, "y_threshold: %8d %8d %8d %8d\n", - cam->params.yuvThreshold.yThreshold, 0, 31, 6); + cam->params.yuvThreshold.yThreshold, 0, 31, 6); out += sprintf(out, "uv_threshold: %8d %8d %8d %8d\n", - cam->params.yuvThreshold.uvThreshold, 0, 31, 6); + cam->params.yuvThreshold.uvThreshold, 0, 31, 6); out += sprintf(out, "hysteresis: %8d %8d %8d %8d\n", - cam->params.compressionParams.hysteresis, 0, 255, 3); + cam->params.compressionParams.hysteresis, 0, 255, 3); out += sprintf(out, "threshold_max: %8d %8d %8d %8d\n", - cam->params.compressionParams.threshMax, 0, 255, 11); + cam->params.compressionParams.threshMax, 0, 255, 11); out += sprintf(out, "small_step: %8d %8d %8d %8d\n", - cam->params.compressionParams.smallStep, 0, 255, 1); + cam->params.compressionParams.smallStep, 0, 255, 1); out += sprintf(out, "large_step: %8d %8d %8d %8d\n", - cam->params.compressionParams.largeStep, 0, 255, 3); + cam->params.compressionParams.largeStep, 0, 255, 3); out += sprintf(out, "decimation_hysteresis: %8d %8d %8d %8d\n", - cam->params.compressionParams.decimationHysteresis, + cam->params.compressionParams.decimationHysteresis, 0, 255, 2); out += sprintf(out, "fr_diff_step_thresh: %8d %8d %8d %8d\n", - cam->params.compressionParams.frDiffStepThresh, + cam->params.compressionParams.frDiffStepThresh, 0, 255, 5); out += sprintf(out, "q_diff_step_thresh: %8d %8d %8d %8d\n", - cam->params.compressionParams.qDiffStepThresh, + cam->params.compressionParams.qDiffStepThresh, 0, 255, 3); out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n", - cam->params.compressionParams.decimationThreshMod, + cam->params.compressionParams.decimationThreshMod, 0, 255, 2); /* QX3 specific entries */ if (cam->params.qx3.qx3_detected) { - out += sprintf(out, "toplight: %8s %8s %8s %8s\n", - cam->params.qx3.toplight ? "on" : "off", + out += sprintf(out, "toplight: %8s %8s %8s %8s\n", + cam->params.qx3.toplight ? "on" : "off", "off", "on", "off"); - out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n", - cam->params.qx3.bottomlight ? "on" : "off", + out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n", + cam->params.qx3.bottomlight ? "on" : "off", "off", "on", "off"); } - + len = out - page; len -= off; if (len < count) { @@ -542,7 +543,7 @@ static int cpia_read_proc(char *page, char **start, off_t off, static int match(char *checkstr, char **buffer, unsigned long *count, - int *find_colon, int *err) + int *find_colon, int *err) { int ret, colon_found = 1; int len = strlen(checkstr); @@ -582,7 +583,7 @@ static unsigned long int value(char **buffer, unsigned long *count, int *err) } static int cpia_write_proc(struct file *file, const char __user *buf, - unsigned long count, void *data) + unsigned long count, void *data) { struct cam_data *cam = data; struct cam_params new_params; @@ -618,12 +619,12 @@ static int cpia_write_proc(struct file *file, const char __user *buf, retval = -EINVAL; goto out; } - + buffer = page; - - if (mutex_lock_interruptible(&cam->param_lock)) + + if (down_interruptible(&cam->param_lock)) return -ERESTARTSYS; - + /* * Skip over leading whitespace */ @@ -631,15 +632,15 @@ static int cpia_write_proc(struct file *file, const char __user *buf, --count; ++buffer; } - + memcpy(&new_params, &cam->params, sizeof(struct cam_params)); new_mains = cam->mainsFreq; - + #define MATCH(x) (match(x, &buffer, &count, &find_colon, &retval)) #define VALUE (value(&buffer,&count, &retval)) #define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \ - new_params.version.firmwareRevision == (y)) - + new_params.version.firmwareRevision == (y)) + retval = 0; while (count && !retval) { find_colon = 1; @@ -655,7 +656,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, } command_flags |= COMMAND_SETCOLOURPARAMS; if(new_params.flickerControl.allowableOverExposure < 0) - new_params.flickerControl.allowableOverExposure = + new_params.flickerControl.allowableOverExposure = -find_over_exposure(new_params.colourParams.brightness); if(new_params.flickerControl.flickerMode != 0) command_flags |= COMMAND_SETFLICKERCTRL; @@ -720,7 +721,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, /* Either base rate would work here */ new_params.sensorFps.baserate = 1; } - new_params.flickerControl.coarseJump = + new_params.flickerControl.coarseJump = flicker_jumps[new_mains] [new_params.sensorFps.baserate] [new_params.sensorFps.divisor]; @@ -1084,7 +1085,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, } else if (MATCH("mains_frequency")) { if (!retval && MATCH("50")) { new_mains = 0; - new_params.flickerControl.coarseJump = + new_params.flickerControl.coarseJump = flicker_jumps[new_mains] [new_params.sensorFps.baserate] [new_params.sensorFps.divisor]; @@ -1092,7 +1093,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, command_flags |= COMMAND_SETFLICKERCTRL; } else if (!retval && MATCH("60")) { new_mains = 1; - new_params.flickerControl.coarseJump = + new_params.flickerControl.coarseJump = flicker_jumps[new_mains] [new_params.sensorFps.baserate] [new_params.sensorFps.divisor]; @@ -1102,7 +1103,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, retval = -EINVAL; } else if (MATCH("allowable_overexposure")) { if (!retval && MATCH("auto")) { - new_params.flickerControl.allowableOverExposure = + new_params.flickerControl.allowableOverExposure = -find_over_exposure(new_params.colourParams.brightness); if(new_params.flickerControl.flickerMode != 0) command_flags |= COMMAND_SETFLICKERCTRL; @@ -1145,10 +1146,10 @@ static int cpia_write_proc(struct file *file, const char __user *buf, command_flags |= COMMAND_SETCOMPRESSION; } else if (MATCH("compression_target")) { if (!retval && MATCH("quality")) - new_params.compressionTarget.frTargeting = + new_params.compressionTarget.frTargeting = CPIA_COMPRESSION_TARGET_QUALITY; else if (!retval && MATCH("framerate")) - new_params.compressionTarget.frTargeting = + new_params.compressionTarget.frTargeting = CPIA_COMPRESSION_TARGET_FRAMERATE; else retval = -EINVAL; @@ -1172,7 +1173,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, if (!retval) { if(val > 0 && val <= 64) new_params.compressionTarget.targetQ = val; - else + else retval = -EINVAL; } command_flags |= COMMAND_SETCOMPRESSIONTARGET; @@ -1287,19 +1288,19 @@ static int cpia_write_proc(struct file *file, const char __user *buf, } command_flags |= COMMAND_SETCOMPRESSIONPARAMS; } else if (MATCH("toplight")) { - if (!retval && MATCH("on")) + if (!retval && MATCH("on")) new_params.qx3.toplight = 1; else if (!retval && MATCH("off")) new_params.qx3.toplight = 0; - else + else retval = -EINVAL; command_flags |= COMMAND_SETLIGHTS; } else if (MATCH("bottomlight")) { - if (!retval && MATCH("on")) + if (!retval && MATCH("on")) new_params.qx3.bottomlight = 1; - else if (!retval && MATCH("off")) + else if (!retval && MATCH("off")) new_params.qx3.bottomlight = 0; - else + else retval = -EINVAL; command_flags |= COMMAND_SETLIGHTS; } else { @@ -1325,7 +1326,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, } } } -#undef MATCH +#undef MATCH #undef VALUE #undef FIRMWARE_VERSION if (!retval) { @@ -1348,24 +1349,24 @@ static int cpia_write_proc(struct file *file, const char __user *buf, retval = size; } else DBG("error: %d\n", retval); - - mutex_unlock(&cam->param_lock); - + + up(&cam->param_lock); + out: free_page((unsigned long)page); - return retval; + return retval; } static void create_proc_cpia_cam(struct cam_data *cam) { char name[7]; struct proc_dir_entry *ent; - + if (!cpia_proc_root || !cam) return; sprintf(name, "video%d", cam->vdev.minor); - + ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root); if (!ent) return; @@ -1373,9 +1374,9 @@ static void create_proc_cpia_cam(struct cam_data *cam) ent->data = cam; ent->read_proc = cpia_read_proc; ent->write_proc = cpia_write_proc; - /* + /* size of the proc entry is 3736 bytes for the standard webcam; - the extra features of the QX3 microscope add 189 bytes. + the extra features of the QX3 microscope add 189 bytes. (we have not yet probed the camera to see which type it is). */ ent->size = 3736 + 189; @@ -1385,10 +1386,10 @@ static void create_proc_cpia_cam(struct cam_data *cam) static void destroy_proc_cpia_cam(struct cam_data *cam) { char name[7]; - + if (!cam || !cam->proc_entry) return; - + sprintf(name, "video%d", cam->vdev.minor); remove_proc_entry(name, cpia_proc_root); cam->proc_entry = NULL; @@ -1595,13 +1596,13 @@ static void set_vw_size(struct cam_data *cam) cam->vc.width = cam->vw.width; if(cam->vc.height == 0) cam->vc.height = cam->vw.height; - + cam->params.roi.colStart += cam->vc.x >> 3; cam->params.roi.colEnd = cam->params.roi.colStart + - (cam->vc.width >> 3); + (cam->vc.width >> 3); cam->params.roi.rowStart += cam->vc.y >> 2; cam->params.roi.rowEnd = cam->params.roi.rowStart + - (cam->vc.height >> 2); + (cam->vc.height >> 2); return; } @@ -1623,7 +1624,7 @@ static int allocate_frame_buf(struct cam_data *cam) static int free_frame_buf(struct cam_data *cam) { int i; - + rvfree(cam->frame_buf, FRAME_NUM*CPIA_MAX_FRAME_SIZE); cam->frame_buf = NULL; for (i=0; i < FRAME_NUM; i++) @@ -1663,10 +1664,10 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) case CPIA_COMMAND_GetColourParams: case CPIA_COMMAND_GetColourBalance: case CPIA_COMMAND_GetExposure: - mutex_lock(&cam->param_lock); + down(&cam->param_lock); datasize=8; break; - case CPIA_COMMAND_ReadMCPorts: + case CPIA_COMMAND_ReadMCPorts: case CPIA_COMMAND_ReadVCRegs: datasize = 4; break; @@ -1690,7 +1691,7 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) if (command == CPIA_COMMAND_GetColourParams || command == CPIA_COMMAND_GetColourBalance || command == CPIA_COMMAND_GetExposure) - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); } else { switch(command) { case CPIA_COMMAND_GetCPIAVersion: @@ -1725,13 +1726,13 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) cam->params.colourParams.brightness = data[0]; cam->params.colourParams.contrast = data[1]; cam->params.colourParams.saturation = data[2]; - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); break; case CPIA_COMMAND_GetColourBalance: cam->params.colourBalance.redGain = data[0]; cam->params.colourBalance.greenGain = data[1]; cam->params.colourBalance.blueGain = data[2]; - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); break; case CPIA_COMMAND_GetExposure: cam->params.exposure.gain = data[0]; @@ -1742,13 +1743,13 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) cam->params.exposure.green1Comp = data[5]; cam->params.exposure.green2Comp = data[6]; cam->params.exposure.blueComp = data[7]; - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); break; - case CPIA_COMMAND_ReadMCPorts: - if (!cam->params.qx3.qx3_detected) + case CPIA_COMMAND_ReadMCPorts: + if (!cam->params.qx3.qx3_detected) break; - /* test button press */ + /* test button press */ cam->params.qx3.button = ((data[1] & 0x02) == 0); if (cam->params.qx3.button) { /* button pressed - unlock the latch */ @@ -1769,9 +1770,9 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d) /* send a command to the camera with an additional data transaction */ static int do_command_extended(struct cam_data *cam, u16 command, - u8 a, u8 b, u8 c, u8 d, - u8 e, u8 f, u8 g, u8 h, - u8 i, u8 j, u8 k, u8 l) + u8 a, u8 b, u8 c, u8 d, + u8 e, u8 f, u8 g, u8 h, + u8 i, u8 j, u8 k, u8 l) { int retval; u8 cmd[8], data[8]; @@ -1808,10 +1809,10 @@ static int do_command_extended(struct cam_data *cam, u16 command, #define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16) static int convert420(unsigned char *yuv, unsigned char *rgb, int out_fmt, - int linesize, int mmap_kludge) + int linesize, int mmap_kludge) { int y, u, v, r, g, b, y1; - + /* Odd lines use the same u and v as the previous line. * Because of compression, it is necessary to get this * information from the decoded image. */ @@ -1924,7 +1925,7 @@ static int convert420(unsigned char *yuv, unsigned char *rgb, int out_fmt, static int yuvconvert(unsigned char *yuv, unsigned char *rgb, int out_fmt, - int in_uyvy, int mmap_kludge) + int in_uyvy, int mmap_kludge) { int y, u, v, r, g, b, y1; @@ -2058,7 +2059,7 @@ static int parse_picture(struct cam_data *cam, int size) int rows, cols, linesize, subsample_422; /* make sure params don't change while we are decoding */ - mutex_lock(&cam->param_lock); + down(&cam->param_lock); obuf = cam->decompressed_frame.data; end_obuf = obuf+CPIA_MAX_FRAME_SIZE; @@ -2068,55 +2069,55 @@ static int parse_picture(struct cam_data *cam, int size) if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) { LOG("header not found\n"); - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return -1; } if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) { LOG("wrong video size\n"); - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return -1; } - + if (ibuf[17] != SUBSAMPLE_420 && ibuf[17] != SUBSAMPLE_422) { LOG("illegal subtype %d\n",ibuf[17]); - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return -1; } subsample_422 = ibuf[17] == SUBSAMPLE_422; - + if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) { LOG("illegal yuvorder %d\n",ibuf[18]); - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return -1; } in_uyvy = ibuf[18] == YUVORDER_UYVY; - + if ((ibuf[24] != cam->params.roi.colStart) || (ibuf[25] != cam->params.roi.colEnd) || (ibuf[26] != cam->params.roi.rowStart) || (ibuf[27] != cam->params.roi.rowEnd)) { LOG("ROI mismatch\n"); - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return -1; } cols = 8*(ibuf[25] - ibuf[24]); rows = 4*(ibuf[27] - ibuf[26]); - + if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) { LOG("illegal compression %d\n",ibuf[28]); - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return -1; } compressed = (ibuf[28] == COMPRESSED); - + if (ibuf[29] != NO_DECIMATION && ibuf[29] != DECIMATION_ENAB) { LOG("illegal decimation %d\n",ibuf[29]); - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return -1; } - decimation = (ibuf[29] == DECIMATION_ENAB); + decimation = (ibuf[29] == DECIMATION_ENAB); cam->params.yuvThreshold.yThreshold = ibuf[30]; cam->params.yuvThreshold.uvThreshold = ibuf[31]; @@ -2129,8 +2130,8 @@ static int parse_picture(struct cam_data *cam, int size) cam->params.status.vpStatus = ibuf[38]; cam->params.status.errorCode = ibuf[39]; cam->fps = ibuf[41]; - mutex_unlock(&cam->param_lock); - + up(&cam->param_lock); + linesize = skipcount(cols, out_fmt); ibuf += FRAME_HEADER_SIZE; size -= FRAME_HEADER_SIZE; @@ -2149,14 +2150,14 @@ static int parse_picture(struct cam_data *cam, int size) if (!compressed || (compressed && !(*ibuf & 1))) { if(subsample_422 || even_line) { obuf += yuvconvert(ibuf, obuf, out_fmt, - in_uyvy, cam->mmap_kludge); + in_uyvy, cam->mmap_kludge); ibuf += 4; ll -= 4; } else { /* SUBSAMPLE_420 on an odd line */ obuf += convert420(ibuf, obuf, - out_fmt, linesize, - cam->mmap_kludge); + out_fmt, linesize, + cam->mmap_kludge); ibuf += 2; ll -= 2; } @@ -2182,7 +2183,7 @@ static int parse_picture(struct cam_data *cam, int size) if ((size > 3) && (ibuf[0] == EOI) && (ibuf[1] == EOI) && (ibuf[2] == EOI) && (ibuf[3] == EOI)) { - size -= 4; + size -= 4; break; } @@ -2203,7 +2204,7 @@ static int parse_picture(struct cam_data *cam, int size) return -1; } } - + if(decimation) { /* interpolate odd rows */ int i, j; @@ -2232,7 +2233,7 @@ static int parse_picture(struct cam_data *cam, int size) static inline int init_stream_cap(struct cam_data *cam) { return do_command(cam, CPIA_COMMAND_InitStreamCap, - 0, cam->params.streamStartLine, 0, 0); + 0, cam->params.streamStartLine, 0, 0); } @@ -2253,7 +2254,7 @@ static int find_over_exposure(int brightness) int MaxAllowableOverExposure, OverExposure; MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness - - FLICKER_BRIGHTNESS_CONSTANT; + FLICKER_BRIGHTNESS_CONSTANT; if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE) { OverExposure = MaxAllowableOverExposure; @@ -2270,71 +2271,71 @@ static int find_over_exposure(int brightness) /* update various camera modes and settings */ static void dispatch_commands(struct cam_data *cam) { - mutex_lock(&cam->param_lock); + down(&cam->param_lock); if (cam->cmd_queue==COMMAND_NONE) { - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return; } DEB_BYTE(cam->cmd_queue); DEB_BYTE(cam->cmd_queue>>8); if (cam->cmd_queue & COMMAND_SETFORMAT) { do_command(cam, CPIA_COMMAND_SetFormat, - cam->params.format.videoSize, - cam->params.format.subSample, - cam->params.format.yuvOrder, 0); + cam->params.format.videoSize, + cam->params.format.subSample, + cam->params.format.yuvOrder, 0); do_command(cam, CPIA_COMMAND_SetROI, - cam->params.roi.colStart, cam->params.roi.colEnd, - cam->params.roi.rowStart, cam->params.roi.rowEnd); + cam->params.roi.colStart, cam->params.roi.colEnd, + cam->params.roi.rowStart, cam->params.roi.rowEnd); cam->first_frame = 1; } if (cam->cmd_queue & COMMAND_SETCOLOURPARAMS) do_command(cam, CPIA_COMMAND_SetColourParams, - cam->params.colourParams.brightness, - cam->params.colourParams.contrast, - cam->params.colourParams.saturation, 0); + cam->params.colourParams.brightness, + cam->params.colourParams.contrast, + cam->params.colourParams.saturation, 0); if (cam->cmd_queue & COMMAND_SETAPCOR) do_command(cam, CPIA_COMMAND_SetApcor, - cam->params.apcor.gain1, - cam->params.apcor.gain2, - cam->params.apcor.gain4, - cam->params.apcor.gain8); + cam->params.apcor.gain1, + cam->params.apcor.gain2, + cam->params.apcor.gain4, + cam->params.apcor.gain8); if (cam->cmd_queue & COMMAND_SETVLOFFSET) do_command(cam, CPIA_COMMAND_SetVLOffset, - cam->params.vlOffset.gain1, - cam->params.vlOffset.gain2, - cam->params.vlOffset.gain4, - cam->params.vlOffset.gain8); + cam->params.vlOffset.gain1, + cam->params.vlOffset.gain2, + cam->params.vlOffset.gain4, + cam->params.vlOffset.gain8); if (cam->cmd_queue & COMMAND_SETEXPOSURE) { do_command_extended(cam, CPIA_COMMAND_SetExposure, - cam->params.exposure.gainMode, - 1, - cam->params.exposure.compMode, - cam->params.exposure.centreWeight, - cam->params.exposure.gain, - cam->params.exposure.fineExp, - cam->params.exposure.coarseExpLo, - cam->params.exposure.coarseExpHi, - cam->params.exposure.redComp, - cam->params.exposure.green1Comp, - cam->params.exposure.green2Comp, - cam->params.exposure.blueComp); + cam->params.exposure.gainMode, + 1, + cam->params.exposure.compMode, + cam->params.exposure.centreWeight, + cam->params.exposure.gain, + cam->params.exposure.fineExp, + cam->params.exposure.coarseExpLo, + cam->params.exposure.coarseExpHi, + cam->params.exposure.redComp, + cam->params.exposure.green1Comp, + cam->params.exposure.green2Comp, + cam->params.exposure.blueComp); if(cam->params.exposure.expMode != 1) { do_command_extended(cam, CPIA_COMMAND_SetExposure, - 0, - cam->params.exposure.expMode, - 0, 0, - cam->params.exposure.gain, - cam->params.exposure.fineExp, - cam->params.exposure.coarseExpLo, - cam->params.exposure.coarseExpHi, - 0, 0, 0, 0); + 0, + cam->params.exposure.expMode, + 0, 0, + cam->params.exposure.gain, + cam->params.exposure.fineExp, + cam->params.exposure.coarseExpLo, + cam->params.exposure.coarseExpHi, + 0, 0, 0, 0); } } - + if (cam->cmd_queue & COMMAND_SETCOLOURBALANCE) { if (cam->params.colourBalance.balanceMode == 1) { do_command(cam, CPIA_COMMAND_SetColourBalance, @@ -2357,47 +2358,47 @@ static void dispatch_commands(struct cam_data *cam) if (cam->cmd_queue & COMMAND_SETCOMPRESSIONTARGET) do_command(cam, CPIA_COMMAND_SetCompressionTarget, - cam->params.compressionTarget.frTargeting, - cam->params.compressionTarget.targetFR, - cam->params.compressionTarget.targetQ, 0); + cam->params.compressionTarget.frTargeting, + cam->params.compressionTarget.targetFR, + cam->params.compressionTarget.targetQ, 0); if (cam->cmd_queue & COMMAND_SETYUVTHRESH) do_command(cam, CPIA_COMMAND_SetYUVThresh, - cam->params.yuvThreshold.yThreshold, - cam->params.yuvThreshold.uvThreshold, 0, 0); + cam->params.yuvThreshold.yThreshold, + cam->params.yuvThreshold.uvThreshold, 0, 0); if (cam->cmd_queue & COMMAND_SETCOMPRESSIONPARAMS) do_command_extended(cam, CPIA_COMMAND_SetCompressionParams, - 0, 0, 0, 0, - cam->params.compressionParams.hysteresis, - cam->params.compressionParams.threshMax, - cam->params.compressionParams.smallStep, - cam->params.compressionParams.largeStep, - cam->params.compressionParams.decimationHysteresis, - cam->params.compressionParams.frDiffStepThresh, - cam->params.compressionParams.qDiffStepThresh, - cam->params.compressionParams.decimationThreshMod); + 0, 0, 0, 0, + cam->params.compressionParams.hysteresis, + cam->params.compressionParams.threshMax, + cam->params.compressionParams.smallStep, + cam->params.compressionParams.largeStep, + cam->params.compressionParams.decimationHysteresis, + cam->params.compressionParams.frDiffStepThresh, + cam->params.compressionParams.qDiffStepThresh, + cam->params.compressionParams.decimationThreshMod); if (cam->cmd_queue & COMMAND_SETCOMPRESSION) do_command(cam, CPIA_COMMAND_SetCompression, - cam->params.compression.mode, + cam->params.compression.mode, cam->params.compression.decimation, 0, 0); if (cam->cmd_queue & COMMAND_SETSENSORFPS) do_command(cam, CPIA_COMMAND_SetSensorFPS, - cam->params.sensorFps.divisor, - cam->params.sensorFps.baserate, 0, 0); + cam->params.sensorFps.divisor, + cam->params.sensorFps.baserate, 0, 0); if (cam->cmd_queue & COMMAND_SETFLICKERCTRL) do_command(cam, CPIA_COMMAND_SetFlickerCtrl, - cam->params.flickerControl.flickerMode, - cam->params.flickerControl.coarseJump, - abs(cam->params.flickerControl.allowableOverExposure), - 0); + cam->params.flickerControl.flickerMode, + cam->params.flickerControl.coarseJump, + abs(cam->params.flickerControl.allowableOverExposure), + 0); if (cam->cmd_queue & COMMAND_SETECPTIMING) do_command(cam, CPIA_COMMAND_SetECPTiming, - cam->params.ecpTiming, 0, 0, 0); + cam->params.ecpTiming, 0, 0, 0); if (cam->cmd_queue & COMMAND_PAUSE) do_command(cam, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0); @@ -2408,24 +2409,24 @@ static void dispatch_commands(struct cam_data *cam) if (cam->cmd_queue & COMMAND_SETLIGHTS && cam->params.qx3.qx3_detected) { int p1 = (cam->params.qx3.bottomlight == 0) << 1; - int p2 = (cam->params.qx3.toplight == 0) << 3; - do_command(cam, CPIA_COMMAND_WriteVCReg, 0x90, 0x8F, 0x50, 0); - do_command(cam, CPIA_COMMAND_WriteMCPort, 2, 0, (p1|p2|0xE0), 0); + int p2 = (cam->params.qx3.toplight == 0) << 3; + do_command(cam, CPIA_COMMAND_WriteVCReg, 0x90, 0x8F, 0x50, 0); + do_command(cam, CPIA_COMMAND_WriteMCPort, 2, 0, (p1|p2|0xE0), 0); } cam->cmd_queue = COMMAND_NONE; - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return; } static void set_flicker(struct cam_params *params, volatile u32 *command_flags, - int on) + int on) { /* Everything in here is from the Windows driver */ #define FIRMWARE_VERSION(x,y) (params->version.firmwareVersion == (x) && \ - params->version.firmwareRevision == (y)) + params->version.firmwareRevision == (y)) /* define for compgain calculation */ #if 0 #define COMPGAIN(base, curexp, newexp) \ @@ -2440,7 +2441,7 @@ static void set_flicker(struct cam_params *params, volatile u32 *command_flags, (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128))) #endif - + int currentexp = params->exposure.coarseExpLo + params->exposure.coarseExpHi*256; int startexp; @@ -2481,7 +2482,7 @@ static void set_flicker(struct cam_params *params, volatile u32 *command_flags, } if(FIRMWARE_VERSION(1,2)) params->exposure.compMode = 0; - else + else params->exposure.compMode = 1; params->apcor.gain1 = 0x18; @@ -2532,14 +2533,14 @@ static void set_flicker(struct cam_params *params, volatile u32 *command_flags, } #define FIRMWARE_VERSION(x,y) (cam->params.version.firmwareVersion == (x) && \ - cam->params.version.firmwareRevision == (y)) + cam->params.version.firmwareRevision == (y)) /* monitor the exposure and adjust the sensor frame rate if needed */ static void monitor_exposure(struct cam_data *cam) { u8 exp_acc, bcomp, gain, coarseL, cmd[8], data[8]; int retval, light_exp, dark_exp, very_dark_exp; int old_exposure, new_exposure, framerate; - + /* get necessary stats and register settings from camera */ /* do_command can't handle this, so do it ourselves */ cmd[0] = CPIA_COMMAND_ReadVPRegs>>8; @@ -2561,19 +2562,19 @@ static void monitor_exposure(struct cam_data *cam) gain = data[2]; coarseL = data[3]; - mutex_lock(&cam->param_lock); + down(&cam->param_lock); light_exp = cam->params.colourParams.brightness + - TC - 50 + EXP_ACC_LIGHT; + TC - 50 + EXP_ACC_LIGHT; if(light_exp > 255) light_exp = 255; dark_exp = cam->params.colourParams.brightness + - TC - 50 - EXP_ACC_DARK; + TC - 50 - EXP_ACC_DARK; if(dark_exp < 0) dark_exp = 0; very_dark_exp = dark_exp/2; - + old_exposure = cam->params.exposure.coarseExpHi * 256 + - cam->params.exposure.coarseExpLo; + cam->params.exposure.coarseExpLo; if(!cam->params.flickerControl.disabled) { /* Flicker control on */ @@ -2666,11 +2667,11 @@ static void monitor_exposure(struct cam_data *cam) cam->exposure_status = EXPOSURE_NORMAL; } } - + framerate = cam->fps; if(framerate > 30 || framerate < 1) framerate = 1; - + if(!cam->params.flickerControl.disabled) { /* Flicker control on */ if((cam->exposure_status == EXPOSURE_VERY_DARK || @@ -2682,10 +2683,10 @@ static void monitor_exposure(struct cam_data *cam) ++cam->params.sensorFps.divisor; cam->cmd_queue |= COMMAND_SETSENSORFPS; - cam->params.flickerControl.coarseJump = + cam->params.flickerControl.coarseJump = flicker_jumps[cam->mainsFreq] - [cam->params.sensorFps.baserate] - [cam->params.sensorFps.divisor]; + [cam->params.sensorFps.baserate] + [cam->params.sensorFps.divisor]; cam->cmd_queue |= COMMAND_SETFLICKERCTRL; new_exposure = cam->params.flickerControl.coarseJump-1; @@ -2703,15 +2704,15 @@ static void monitor_exposure(struct cam_data *cam) cam->params.sensorFps.divisor > 0) { /* light for too long */ - int max_exp = FIRMWARE_VERSION(1,2) ? MAX_EXP_102 : MAX_EXP ; + int max_exp = FIRMWARE_VERSION(1,2) ? MAX_EXP_102 : MAX_EXP ; --cam->params.sensorFps.divisor; cam->cmd_queue |= COMMAND_SETSENSORFPS; - cam->params.flickerControl.coarseJump = + cam->params.flickerControl.coarseJump = flicker_jumps[cam->mainsFreq] - [cam->params.sensorFps.baserate] - [cam->params.sensorFps.divisor]; + [cam->params.sensorFps.baserate] + [cam->params.sensorFps.divisor]; cam->cmd_queue |= COMMAND_SETFLICKERCTRL; new_exposure = cam->params.flickerControl.coarseJump-1; @@ -2761,7 +2762,7 @@ static void monitor_exposure(struct cam_data *cam) LOG("Automatically increasing sensor_fps\n"); } } - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); } /*-----------------------------------------------------------------*/ @@ -2771,36 +2772,36 @@ static void monitor_exposure(struct cam_data *cam) It also adjust the colour balance when an exposure step is detected - as long as flicker is running -*/ +*/ static void restart_flicker(struct cam_data *cam) { int cam_exposure, old_exp; if(!FIRMWARE_VERSION(1,2)) return; - mutex_lock(&cam->param_lock); + down(&cam->param_lock); if(cam->params.flickerControl.flickerMode == 0 || cam->raw_image[39] == 0) { - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); return; } cam_exposure = cam->raw_image[39]*2; old_exp = cam->params.exposure.coarseExpLo + - cam->params.exposure.coarseExpHi*256; - /* - see how far away camera exposure is from a valid - flicker exposure value - */ - cam_exposure %= cam->params.flickerControl.coarseJump; + cam->params.exposure.coarseExpHi*256; + /* + see how far away camera exposure is from a valid + flicker exposure value + */ + cam_exposure %= cam->params.flickerControl.coarseJump; if(!cam->params.flickerControl.disabled && - cam_exposure <= cam->params.flickerControl.coarseJump - 3) { + cam_exposure <= cam->params.flickerControl.coarseJump - 3) { /* Flicker control auto-disabled */ cam->params.flickerControl.disabled = 1; } - + if(cam->params.flickerControl.disabled && cam->params.flickerControl.flickerMode && old_exp > cam->params.flickerControl.coarseJump + - ROUND_UP_EXP_FOR_FLICKER) { + ROUND_UP_EXP_FOR_FLICKER) { /* exposure is now high enough to switch flicker control back on */ set_flicker(&cam->params, &cam->cmd_queue, 1); @@ -2809,7 +2810,7 @@ static void restart_flicker(struct cam_data *cam) cam->exposure_status = EXPOSURE_NORMAL; } - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); } #undef FIRMWARE_VERSION @@ -2817,7 +2818,7 @@ static int clear_stall(struct cam_data *cam) { /* FIXME: Does this actually work? */ LOG("Clearing stall\n"); - + cam->ops->streamRead(cam->lowlevel_data, cam->raw_image, 0); do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0); return cam->params.status.streamState != STREAM_PAUSED; @@ -2877,7 +2878,7 @@ static int fetch_frame(void *data) return -EINTR; do_command(cam, CPIA_COMMAND_GetCameraStatus, - 0, 0, 0, 0); + 0, 0, 0, 0); } if(cam->params.status.streamState != STREAM_READY) { continue; @@ -2902,18 +2903,18 @@ static int fetch_frame(void *data) /* Switch flicker control back on if it got turned off */ restart_flicker(cam); - + /* If AEC is enabled, monitor the exposure and adjust the sensor frame rate if needed */ if(cam->params.exposure.expMode == 2) monitor_exposure(cam); - + /* camera idle now so dispatch queued commands */ dispatch_commands(cam); /* Update our knowledge of the camera state */ - do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0); - do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0); + do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0); + do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0); do_command(cam, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0); /* decompress and convert image to by copying it from @@ -2932,7 +2933,7 @@ static int fetch_frame(void *data) uncompressed. */ cam->first_frame = 1; do_command(cam, CPIA_COMMAND_SetGrabMode, - CPIA_GRAB_SINGLE, 0, 0, 0); + CPIA_GRAB_SINGLE, 0, 0, 0); /* FIXME: Trial & error - need up to 70ms for the grab mode change to complete ? */ msleep_interruptible(70); @@ -2956,12 +2957,12 @@ static int fetch_frame(void *data) if (cam->first_frame) { cam->first_frame = 0; do_command(cam, CPIA_COMMAND_SetCompression, - cam->params.compression.mode, + cam->params.compression.mode, cam->params.compression.decimation, 0, 0); /* Switch from single-grab to continuous grab */ do_command(cam, CPIA_COMMAND_SetGrabMode, - CPIA_GRAB_CONTINUOUS, 0, 0, 0); + CPIA_GRAB_CONTINUOUS, 0, 0, 0); } return 0; } @@ -2976,12 +2977,12 @@ static int capture_frame(struct cam_data *cam, struct video_mmap *vm) if ((err = allocate_frame_buf(cam))) return err; } - + cam->curframe = vm->frame; cam->frame[cam->curframe].state = FRAME_READY; return fetch_frame(cam); } - + static int goto_high_power(struct cam_data *cam) { if (do_command(cam, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0)) @@ -3038,22 +3039,22 @@ static void save_camera_state(struct cam_data *cam) static int set_camera_state(struct cam_data *cam) { cam->cmd_queue = COMMAND_SETCOMPRESSION | - COMMAND_SETCOMPRESSIONTARGET | - COMMAND_SETCOLOURPARAMS | - COMMAND_SETFORMAT | - COMMAND_SETYUVTHRESH | - COMMAND_SETECPTIMING | - COMMAND_SETCOMPRESSIONPARAMS | - COMMAND_SETEXPOSURE | - COMMAND_SETCOLOURBALANCE | - COMMAND_SETSENSORFPS | - COMMAND_SETAPCOR | - COMMAND_SETFLICKERCTRL | - COMMAND_SETVLOFFSET; + COMMAND_SETCOMPRESSIONTARGET | + COMMAND_SETCOLOURPARAMS | + COMMAND_SETFORMAT | + COMMAND_SETYUVTHRESH | + COMMAND_SETECPTIMING | + COMMAND_SETCOMPRESSIONPARAMS | + COMMAND_SETEXPOSURE | + COMMAND_SETCOLOURBALANCE | + COMMAND_SETSENSORFPS | + COMMAND_SETAPCOR | + COMMAND_SETFLICKERCTRL | + COMMAND_SETVLOFFSET; do_command(cam, CPIA_COMMAND_SetGrabMode, CPIA_GRAB_SINGLE,0,0,0); dispatch_commands(cam); - + /* Wait 6 frames for the sensor to get all settings and AEC/ACB to settle */ msleep_interruptible(6*(cam->params.sensorFps.baserate ? 33 : 40) * @@ -3061,7 +3062,7 @@ static int set_camera_state(struct cam_data *cam) if(signal_pending(current)) return -EINTR; - + save_camera_state(cam); return 0; @@ -3093,9 +3094,9 @@ static int reset_camera(struct cam_data *cam) if (goto_low_power(cam)) return -ENODEV; } - + /* procedure described in developer's guide p3-28 */ - + /* Check the firmware version. */ cam->params.version.firmwareVersion = 0; get_version_information(cam); @@ -3112,14 +3113,14 @@ static int reset_camera(struct cam_data *cam) cam->params.qx3.qx3_detected = (cam->params.pnpID.vendor == 0x0813 && cam->params.pnpID.product == 0x0001); - /* The fatal error checking should be done after + /* The fatal error checking should be done after * the camera powers up (developer's guide p 3-38) */ /* Set streamState before transition to high power to avoid bug * in firmware 1-02 */ do_command(cam, CPIA_COMMAND_ModifyCameraStatus, STREAMSTATE, 0, - STREAM_NOT_READY, 0); - + STREAM_NOT_READY, 0); + /* GotoHiPower */ err = goto_high_power(cam); if (err) @@ -3141,16 +3142,16 @@ static int reset_camera(struct cam_data *cam) /* Firmware 1-02 may do this for parallel port cameras, * just clear the flags (developer's guide p 3-38) */ do_command(cam, CPIA_COMMAND_ModifyCameraStatus, - FATALERROR, ~(COM_FLAG|CPIA_FLAG), 0, 0); + FATALERROR, ~(COM_FLAG|CPIA_FLAG), 0, 0); } } - + /* Check the camera status again */ if (cam->params.status.fatalError) { if (cam->params.status.fatalError) return -EIO; } - + /* VPVersion can't be retrieved before the camera is in HiPower, * so get it here instead of in get_version_information. */ do_command(cam, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0); @@ -3185,31 +3186,31 @@ static int cpia_open(struct inode *inode, struct file *file) if (!try_module_get(cam->ops->owner)) return -ENODEV; - mutex_lock(&cam->busy_lock); + down(&cam->busy_lock); err = -ENOMEM; if (!cam->raw_image) { cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE); if (!cam->raw_image) goto oops; } - + if (!cam->decompressed_frame.data) { cam->decompressed_frame.data = rvmalloc(CPIA_MAX_FRAME_SIZE); if (!cam->decompressed_frame.data) goto oops; } - + /* open cpia */ err = -ENODEV; if (cam->ops->open(cam->lowlevel_data)) goto oops; - + /* reset the camera */ if ((err = reset_camera(cam)) != 0) { cam->ops->close(cam->lowlevel_data); goto oops; } - + err = -EINTR; if(signal_pending(current)) goto oops; @@ -3223,10 +3224,10 @@ static int cpia_open(struct inode *inode, struct file *file) /* init it to something */ cam->mmap_kludge = 0; - + ++cam->open_count; file->private_data = dev; - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return 0; oops: @@ -3238,7 +3239,7 @@ static int cpia_open(struct inode *inode, struct file *file) rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE); cam->raw_image = NULL; } - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); put_cam(cam->ops); return err; } @@ -3249,10 +3250,10 @@ static int cpia_close(struct inode *inode, struct file *file) struct cam_data *cam = dev->priv; if (cam->ops) { - /* Return ownership of /proc/cpia/videoX to root */ + /* Return ownership of /proc/cpia/videoX to root */ if(cam->proc_entry) cam->proc_entry->uid = 0; - + /* save camera state for later open (developers guide ch 3.5.3) */ save_camera_state(cam); @@ -3302,24 +3303,24 @@ static ssize_t cpia_read(struct file *file, char __user *buf, int err; /* make this _really_ smp and multithread-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) + if (down_interruptible(&cam->busy_lock)) return -EINTR; if (!buf) { DBG("buf NULL\n"); - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return -EINVAL; } if (!count) { DBG("count 0\n"); - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return 0; } if (!cam->ops) { DBG("ops NULL\n"); - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return -ENODEV; } @@ -3328,7 +3329,7 @@ static ssize_t cpia_read(struct file *file, char __user *buf, cam->mmap_kludge=0; if((err = fetch_frame(cam)) != 0) { DBG("ERROR from fetch_frame: %d\n", err); - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return err; } cam->decompressed_frame.state = FRAME_UNUSED; @@ -3337,17 +3338,17 @@ static ssize_t cpia_read(struct file *file, char __user *buf, if (cam->decompressed_frame.count > count) { DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count, (unsigned long) count); - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return -EFAULT; } if (copy_to_user(buf, cam->decompressed_frame.data, - cam->decompressed_frame.count)) { + cam->decompressed_frame.count)) { DBG("copy_to_user failed\n"); - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return -EFAULT; } - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return cam->decompressed_frame.count; } @@ -3360,9 +3361,9 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, if (!cam || !cam->ops) return -ENODEV; - + /* make this _really_ smp-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) + if (down_interruptible(&cam->busy_lock)) return -EINTR; //DBG("cpia_ioctl: %u\n", ioctlnr); @@ -3404,7 +3405,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, v->norm = 0; break; } - + case VIDIOCSCHAN: { struct video_channel *v = arg; @@ -3423,7 +3424,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, *pic = cam->vp; break; } - + case VIDIOCSPICT: { struct video_picture *vp = arg; @@ -3438,7 +3439,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, break; } - mutex_lock(&cam->param_lock); + down(&cam->param_lock); /* brightness, colour, contrast need no check 0-65535 */ cam->vp = *vp; /* update cam->params.colourParams */ @@ -3457,15 +3458,15 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, /* Adjust flicker control if necessary */ if(cam->params.flickerControl.allowableOverExposure < 0) - cam->params.flickerControl.allowableOverExposure = + cam->params.flickerControl.allowableOverExposure = -find_over_exposure(cam->params.colourParams.brightness); if(cam->params.flickerControl.flickerMode != 0) cam->cmd_queue |= COMMAND_SETFLICKERCTRL; - + /* queue command to update camera */ cam->cmd_queue |= COMMAND_SETCOLOURPARAMS; - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n", vp->depth, vp->palette, vp->brightness, vp->hue, vp->colour, vp->contrast); @@ -3481,7 +3482,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, *vw = cam->vw; break; } - + case VIDIOCSWIN: { /* copy_from_user, check validity, copy to internal structure */ @@ -3500,26 +3501,26 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, /* we set the video window to something smaller or equal to what * is requested by the user??? */ - mutex_lock(&cam->param_lock); + down(&cam->param_lock); if (vw->width != cam->vw.width || vw->height != cam->vw.height) { int video_size = match_videosize(vw->width, vw->height); if (video_size < 0) { retval = -EINVAL; - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); break; } cam->video_size = video_size; /* video size is changing, reset the subcapture area */ memset(&cam->vc, 0, sizeof(cam->vc)); - + set_vw_size(cam); DBG("%d / %d\n", cam->vw.width, cam->vw.height); cam->cmd_queue |= COMMAND_SETFORMAT; } - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); /* setformat ignored by camera during streaming, * so stop/dispatch/start */ @@ -3546,7 +3547,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, vm->offsets[i] = CPIA_MAX_FRAME_SIZE * i; break; } - + case VIDIOCMCAPTURE: { struct video_mmap *vm = arg; @@ -3596,7 +3597,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, /* video size is changing, reset the subcapture area */ memset(&cam->vc, 0, sizeof(cam->vc)); - + set_vw_size(cam); cam->cmd_queue |= COMMAND_SETFORMAT; dispatch_commands(cam); @@ -3607,7 +3608,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, break; } - + case VIDIOCSYNC: { int *frame = arg; @@ -3648,7 +3649,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, *vc = cam->vc; break; - } + } case VIDIOCSCAPTURE: { @@ -3664,7 +3665,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, retval = -EINVAL; break; } - + /* Clip to the resolution we can set for the ROI (every 8 columns and 4 rows) */ vc->x = vc->x & ~(__u32)7; @@ -3680,25 +3681,25 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, } DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height); - - mutex_lock(&cam->param_lock); - + + down(&cam->param_lock); + cam->vc.x = vc->x; cam->vc.y = vc->y; cam->vc.width = vc->width; cam->vc.height = vc->height; - + set_vw_size(cam); cam->cmd_queue |= COMMAND_SETFORMAT; - mutex_unlock(&cam->param_lock); + up(&cam->param_lock); /* setformat ignored by camera during streaming, * so stop/dispatch/start */ dispatch_commands(cam); break; } - + case VIDIOCGUNIT: { struct video_unit *vu = arg; @@ -3714,7 +3715,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, break; } - + /* pointless to implement overlay with this camera */ case VIDIOCCAPTURE: case VIDIOCGFBUF: @@ -3735,9 +3736,9 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, break; } - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return retval; -} +} static int cpia_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -3758,7 +3759,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) if (!cam || !cam->ops) return -ENODEV; - + DBG("cpia_mmap: %ld\n", size); if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE) @@ -3766,14 +3767,14 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) if (!cam || !cam->ops) return -ENODEV; - + /* make this _really_ smp-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) + if (down_interruptible(&cam->busy_lock)) return -EINTR; if (!cam->frame_buf) { /* we do lazy allocation */ if ((retval = allocate_frame_buf(cam))) { - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return retval; } } @@ -3782,7 +3783,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) while (size > 0) { page = vmalloc_to_pfn((void *)pos); if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return -EAGAIN; } start += PAGE_SIZE; @@ -3794,7 +3795,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) } DBG("cpia_mmap: %ld\n", size); - mutex_unlock(&cam->busy_lock); + up(&cam->busy_lock); return 0; } @@ -3850,11 +3851,11 @@ static void reset_camera_struct(struct cam_data *cam) cam->params.flickerControl.flickerMode = 0; cam->params.flickerControl.disabled = 1; - cam->params.flickerControl.coarseJump = + cam->params.flickerControl.coarseJump = flicker_jumps[cam->mainsFreq] - [cam->params.sensorFps.baserate] - [cam->params.sensorFps.divisor]; - cam->params.flickerControl.allowableOverExposure = + [cam->params.sensorFps.baserate] + [cam->params.sensorFps.divisor]; + cam->params.flickerControl.allowableOverExposure = -find_over_exposure(cam->params.colourParams.brightness); cam->params.vlOffset.gain1 = 20; cam->params.vlOffset.gain2 = 24; @@ -3869,21 +3870,21 @@ static void reset_camera_struct(struct cam_data *cam) cam->params.compressionParams.qDiffStepThresh = 3; cam->params.compressionParams.decimationThreshMod = 2; /* End of default values from Software Developer's Guide */ - + cam->transfer_rate = 0; cam->exposure_status = EXPOSURE_NORMAL; - + /* Set Sensor FPS to 15fps. This seems better than 30fps * for indoor lighting. */ cam->params.sensorFps.divisor = 1; cam->params.sensorFps.baserate = 1; - + cam->params.yuvThreshold.yThreshold = 6; /* From windows driver */ cam->params.yuvThreshold.uvThreshold = 6; /* From windows driver */ - + cam->params.format.subSample = SUBSAMPLE_422; cam->params.format.yuvOrder = YUVORDER_YUYV; - + cam->params.compression.mode = CPIA_COMPRESSION_AUTO; cam->params.compressionTarget.frTargeting = CPIA_COMPRESSION_TARGET_QUALITY; @@ -3897,7 +3898,7 @@ static void reset_camera_struct(struct cam_data *cam) cam->params.qx3.cradled = 0; cam->video_size = VIDEOSIZE_CIF; - + cam->vp.colour = 32768; /* 50% */ cam->vp.hue = 32768; /* 50% */ cam->vp.brightness = 32768; /* 50% */ @@ -3910,7 +3911,7 @@ static void reset_camera_struct(struct cam_data *cam) cam->vc.y = 0; cam->vc.width = 0; cam->vc.height = 0; - + cam->vw.x = 0; cam->vw.y = 0; set_vw_size(cam); @@ -3927,7 +3928,7 @@ static void reset_camera_struct(struct cam_data *cam) /* initialize cam_data structure */ static void init_camera_struct(struct cam_data *cam, - struct cpia_camera_ops *ops ) + struct cpia_camera_ops *ops ) { int i; @@ -3935,8 +3936,8 @@ static void init_camera_struct(struct cam_data *cam, memset(cam, 0, sizeof(struct cam_data)); cam->ops = ops; - mutex_init(&cam->param_lock); - mutex_init(&cam->busy_lock); + init_MUTEX(&cam->param_lock); + init_MUTEX(&cam->busy_lock); reset_camera_struct(cam); @@ -3944,7 +3945,7 @@ static void init_camera_struct(struct cam_data *cam, memcpy(&cam->vdev, &cpia_template, sizeof(cpia_template)); cam->vdev.priv = cam; - + cam->curframe = 0; for (i = 0; i < FRAME_NUM; i++) { cam->frame[i].width = 0; @@ -3960,15 +3961,15 @@ static void init_camera_struct(struct cam_data *cam, struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel) { - struct cam_data *camera; - + struct cam_data *camera; + if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL) return NULL; - + init_camera_struct( camera, ops ); camera->lowlevel_data = lowlevel; - + /* register v4l device */ if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { kfree(camera); @@ -3981,7 +3982,7 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve /* open cpia */ if (camera->ops->open(camera->lowlevel_data)) return camera; - + /* reset the camera */ if (reset_camera(camera) != 0) { camera->ops->close(camera->lowlevel_data); @@ -4021,11 +4022,11 @@ void cpia_unregister_camera(struct cam_data *cam) DBG("camera open -- setting ops to NULL\n"); cam->ops = NULL; } - + #ifdef CONFIG_PROC_FS DBG("destroying /proc/cpia/video%d\n", cam->vdev.minor); destroy_proc_cpia_cam(cam); -#endif +#endif if (!cam->open_count) { DBG("freeing camera\n"); kfree(cam); @@ -4041,7 +4042,7 @@ static int __init cpia_init(void) "allowed, it is disabled by default now. Users should fix the " "applications in case they don't work without conversion " "reenabled by setting the 'colorspace_conv' module " - "parameter to 1\n"); + "parameter to 1"); #ifdef CONFIG_PROC_FS proc_cpia_create(); diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h index dde27a6a4..f629b693e 100644 --- a/drivers/media/video/cpia.h +++ b/drivers/media/video/cpia.h @@ -47,15 +47,14 @@ #include #include #include -#include struct cpia_camera_ops { /* open sets privdata to point to structure for this camera. - * Returns negative value on error, otherwise 0. + * Returns negative value on error, otherwise 0. */ int (*open)(void *privdata); - + /* Registers callback function cb to be called with cbdata * when an image is ready. If cb is NULL, only single image grabs * should be used. cb should immediately call streamRead to read @@ -63,8 +62,8 @@ struct cpia_camera_ops * otherwise 0. */ int (*registerCallback)(void *privdata, void (*cb)(void *cbdata), - void *cbdata); - + void *cbdata); + /* transferCmd sends commands to the camera. command MUST point to * an 8 byte buffer in kernel space. data can be NULL if no extra * data is needed. The size of the data is given by the last 2 @@ -77,30 +76,30 @@ struct cpia_camera_ops * Returns negative value on error, otherwise 0. */ int (*streamStart)(void *privdata); - + /* streamStop terminates stream capture mode. * Returns negative value on error, otherwise 0. */ int (*streamStop)(void *privdata); - + /* streamRead reads a frame from the camera. buffer points to a - * buffer large enough to hold a complete frame in kernel space. - * noblock indicates if this should be a non blocking read. + * buffer large enough to hold a complete frame in kernel space. + * noblock indicates if this should be a non blocking read. * Returns the number of bytes read, or negative value on error. - */ + */ int (*streamRead)(void *privdata, u8 *buffer, int noblock); - + /* close disables the device until open() is called again. * Returns negative value on error, otherwise 0. */ int (*close)(void *privdata); - + /* If wait_for_stream_ready is non-zero, wait until the streamState * is STREAM_READY before calling streamRead. */ int wait_for_stream_ready; - /* + /* * Used to maintain lowlevel module usage counts */ struct module *owner; @@ -215,14 +214,14 @@ struct cam_params { u8 videoSize; /* CIF/QCIF */ u8 subSample; u8 yuvOrder; - } format; - struct { /* Intel QX3 specific data */ - u8 qx3_detected; /* a QX3 is present */ - u8 toplight; /* top light lit , R/W */ - u8 bottomlight; /* bottom light lit, R/W */ - u8 button; /* snapshot button pressed (R/O) */ - u8 cradled; /* microscope is in cradle (R/O) */ - } qx3; + } format; + struct { /* Intel QX3 specific data */ + u8 qx3_detected; /* a QX3 is present */ + u8 toplight; /* top light lit , R/W */ + u8 bottomlight; /* bottom light lit, R/W */ + u8 button; /* snapshot button pressed (R/O) */ + u8 cradled; /* microscope is in cradle (R/O) */ + } qx3; struct { u8 colStart; /* skip first 8*colStart pixels */ u8 colEnd; /* finish at 8*colEnd pixels */ @@ -247,13 +246,13 @@ enum v4l_camstates { struct cam_data { struct list_head cam_data_list; - struct mutex busy_lock; /* guard against SMP multithreading */ + struct semaphore busy_lock; /* guard against SMP multithreading */ struct cpia_camera_ops *ops; /* lowlevel driver operations */ void *lowlevel_data; /* private data for lowlevel driver */ u8 *raw_image; /* buffer for raw image data */ struct cpia_frame decompressed_frame; - /* buffer to hold decompressed frame */ - int image_size; /* sizeof last decompressed image */ + /* buffer to hold decompressed frame */ + int image_size; /* sizeof last decompressed image */ int open_count; /* # of process that have camera open */ /* camera status */ @@ -262,10 +261,10 @@ struct cam_data { u8 mainsFreq; /* for flicker control */ /* proc interface */ - struct mutex param_lock; /* params lock for this camera */ + struct semaphore param_lock; /* params lock for this camera */ struct cam_params params; /* camera settings */ struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */ - + /* v4l */ int video_size; /* VIDEO_SIZE_ */ volatile enum v4l_camstates camstate; /* v4l layer status */ @@ -277,7 +276,7 @@ struct cam_data { /* mmap interface */ int curframe; /* the current frame to grab into */ u8 *frame_buf; /* frame buffer data */ - struct cpia_frame frame[FRAME_NUM]; + struct cpia_frame frame[FRAME_NUM]; /* FRAME_NUM-buffering, so we need a array */ int first_frame; @@ -424,7 +423,7 @@ void cpia_unregister_camera(struct cam_data *cam); #define DEB_BYTE(p)\ DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\ (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\ - (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0); + (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0); #endif /* __KERNEL__ */ diff --git a/drivers/media/video/cpia2/Kconfig b/drivers/media/video/cpia2/Kconfig deleted file mode 100644 index 513cc0927..000000000 --- a/drivers/media/video/cpia2/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config VIDEO_CPIA2 - tristate "CPiA2 Video For Linux" - depends on VIDEO_DEV && USB - ---help--- - This is the video4linux driver for cameras based on Vision's CPiA2 - (Colour Processor Interface ASIC), such as the Digital Blue QX5 - Microscope. If you have one of these cameras, say Y here - - This driver is also available as a module (cpia2). diff --git a/drivers/media/video/cpia2/Makefile b/drivers/media/video/cpia2/Makefile deleted file mode 100644 index 828cf1b1d..000000000 --- a/drivers/media/video/cpia2/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -cpia2-objs := cpia2_v4l.o cpia2_usb.o cpia2_core.o - -obj-$(CONFIG_VIDEO_CPIA2) += cpia2.o diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h deleted file mode 100644 index 1764991b0..000000000 --- a/drivers/media/video/cpia2/cpia2.h +++ /dev/null @@ -1,497 +0,0 @@ -/**************************************************************************** - * - * Filename: cpia2.h - * - * Copyright 2001, STMicrolectronics, Inc. - * - * Contact: steve.miller@st.com - * - * Description: - * This is a USB driver for CPiA2 based video cameras. - * - * This driver is modelled on the cpia usb driver by - * Jochen Scharrlach and Johannes Erdfeldt. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 __CPIA2_H__ -#define __CPIA2_H__ - -#include -#include -#include -#include - -#include "cpia2dev.h" -#include "cpia2_registers.h" - -/* define for verbose debug output */ -//#define _CPIA2_DEBUG_ - -#define CPIA2_MAJ_VER 2 -#define CPIA2_MIN_VER 0 -#define CPIA2_PATCH_VER 0 - -/*** - * Image defines - ***/ -#ifndef true -#define true 1 -#define false 0 -#endif - -/* Misc constants */ -#define ALLOW_CORRUPT 0 /* Causes collater to discard checksum */ - -/* USB Transfer mode */ -#define XFER_ISOC 0 -#define XFER_BULK 1 - -/* USB Alternates */ -#define USBIF_CMDONLY 0 -#define USBIF_BULK 1 -#define USBIF_ISO_1 2 /* 128 bytes/ms */ -#define USBIF_ISO_2 3 /* 384 bytes/ms */ -#define USBIF_ISO_3 4 /* 640 bytes/ms */ -#define USBIF_ISO_4 5 /* 768 bytes/ms */ -#define USBIF_ISO_5 6 /* 896 bytes/ms */ -#define USBIF_ISO_6 7 /* 1023 bytes/ms */ - -/* Flicker Modes */ -#define NEVER_FLICKER 0 -#define ANTI_FLICKER_ON 1 -#define FLICKER_60 60 -#define FLICKER_50 50 - -/* Debug flags */ -#define DEBUG_NONE 0 -#define DEBUG_REG 0x00000001 -#define DEBUG_DUMP_PATCH 0x00000002 -#define DEBUG_DUMP_REGS 0x00000004 - -/*** - * Video frame sizes - ***/ -enum { - VIDEOSIZE_VGA = 0, /* 640x480 */ - VIDEOSIZE_CIF, /* 352x288 */ - VIDEOSIZE_QVGA, /* 320x240 */ - VIDEOSIZE_QCIF, /* 176x144 */ - VIDEOSIZE_288_216, - VIDEOSIZE_256_192, - VIDEOSIZE_224_168, - VIDEOSIZE_192_144, -}; - -#define STV_IMAGE_CIF_ROWS 288 -#define STV_IMAGE_CIF_COLS 352 - -#define STV_IMAGE_QCIF_ROWS 144 -#define STV_IMAGE_QCIF_COLS 176 - -#define STV_IMAGE_VGA_ROWS 480 -#define STV_IMAGE_VGA_COLS 640 - -#define STV_IMAGE_QVGA_ROWS 240 -#define STV_IMAGE_QVGA_COLS 320 - -#define JPEG_MARKER_COM (1<<6) /* Comment segment */ - -/*** - * Enums - ***/ -/* Sensor types available with cpia2 asics */ -enum sensors { - CPIA2_SENSOR_410, - CPIA2_SENSOR_500 -}; - -/* Asic types available in the CPiA2 architecture */ -#define CPIA2_ASIC_672 0x67 - -/* Device types (stv672, stv676, etc) */ -#define DEVICE_STV_672 0x0001 -#define DEVICE_STV_676 0x0002 - -enum frame_status { - FRAME_EMPTY, - FRAME_READING, /* In the process of being grabbed into */ - FRAME_READY, /* Ready to be read */ - FRAME_ERROR, -}; - -/*** - * Register access (for USB request byte) - ***/ -enum { - CAMERAACCESS_SYSTEM = 0, - CAMERAACCESS_VC, - CAMERAACCESS_VP, - CAMERAACCESS_IDATA -}; - -#define CAMERAACCESS_TYPE_BLOCK 0x00 -#define CAMERAACCESS_TYPE_RANDOM 0x04 -#define CAMERAACCESS_TYPE_MASK 0x08 -#define CAMERAACCESS_TYPE_REPEAT 0x0C - -#define TRANSFER_READ 0 -#define TRANSFER_WRITE 1 - -#define DEFAULT_ALT USBIF_ISO_6 -#define DEFAULT_BRIGHTNESS 0x46 -#define DEFAULT_CONTRAST 0x93 -#define DEFAULT_SATURATION 0x7f -#define DEFAULT_TARGET_KB 0x30 - -/* Power state */ -#define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER -#define LO_POWER_MODE CPIA2_SYSTEM_CONTROL_LOW_POWER - - -/******** - * Commands - *******/ -enum { - CPIA2_CMD_NONE = 0, - CPIA2_CMD_GET_VERSION, - CPIA2_CMD_GET_PNP_ID, - CPIA2_CMD_GET_ASIC_TYPE, - CPIA2_CMD_GET_SENSOR, - CPIA2_CMD_GET_VP_DEVICE, - CPIA2_CMD_GET_VP_BRIGHTNESS, - CPIA2_CMD_SET_VP_BRIGHTNESS, - CPIA2_CMD_GET_CONTRAST, - CPIA2_CMD_SET_CONTRAST, - CPIA2_CMD_GET_VP_SATURATION, - CPIA2_CMD_SET_VP_SATURATION, - CPIA2_CMD_GET_VP_GPIO_DIRECTION, - CPIA2_CMD_SET_VP_GPIO_DIRECTION, - CPIA2_CMD_GET_VP_GPIO_DATA, - CPIA2_CMD_SET_VP_GPIO_DATA, - CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, - CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, - CPIA2_CMD_GET_VC_MP_GPIO_DATA, - CPIA2_CMD_SET_VC_MP_GPIO_DATA, - CPIA2_CMD_ENABLE_PACKET_CTRL, - CPIA2_CMD_GET_FLICKER_MODES, - CPIA2_CMD_SET_FLICKER_MODES, - CPIA2_CMD_RESET_FIFO, /* clear fifo and enable stream block */ - CPIA2_CMD_SET_HI_POWER, - CPIA2_CMD_SET_LOW_POWER, - CPIA2_CMD_CLEAR_V2W_ERR, - CPIA2_CMD_SET_USER_MODE, - CPIA2_CMD_GET_USER_MODE, - CPIA2_CMD_FRAMERATE_REQ, - CPIA2_CMD_SET_COMPRESSION_STATE, - CPIA2_CMD_GET_WAKEUP, - CPIA2_CMD_SET_WAKEUP, - CPIA2_CMD_GET_PW_CONTROL, - CPIA2_CMD_SET_PW_CONTROL, - CPIA2_CMD_GET_SYSTEM_CTRL, - CPIA2_CMD_SET_SYSTEM_CTRL, - CPIA2_CMD_GET_VP_SYSTEM_STATE, - CPIA2_CMD_GET_VP_SYSTEM_CTRL, - CPIA2_CMD_SET_VP_SYSTEM_CTRL, - CPIA2_CMD_GET_VP_EXP_MODES, - CPIA2_CMD_SET_VP_EXP_MODES, - CPIA2_CMD_GET_DEVICE_CONFIG, - CPIA2_CMD_SET_DEVICE_CONFIG, - CPIA2_CMD_SET_SERIAL_ADDR, - CPIA2_CMD_SET_SENSOR_CR1, - CPIA2_CMD_GET_VC_CONTROL, - CPIA2_CMD_SET_VC_CONTROL, - CPIA2_CMD_SET_TARGET_KB, - CPIA2_CMD_SET_DEF_JPEG_OPT, - CPIA2_CMD_REHASH_VP4, - CPIA2_CMD_GET_USER_EFFECTS, - CPIA2_CMD_SET_USER_EFFECTS -}; - -enum user_cmd { - COMMAND_NONE = 0x00000001, - COMMAND_SET_FPS = 0x00000002, - COMMAND_SET_COLOR_PARAMS = 0x00000004, - COMMAND_GET_COLOR_PARAMS = 0x00000008, - COMMAND_SET_FORMAT = 0x00000010, /* size, etc */ - COMMAND_SET_FLICKER = 0x00000020 -}; - -/*** - * Some defines specific to the 676 chip - ***/ -#define CAMACC_CIF 0x01 -#define CAMACC_VGA 0x02 -#define CAMACC_QCIF 0x04 -#define CAMACC_QVGA 0x08 - - -struct cpia2_register { - u8 index; - u8 value; -}; - -struct cpia2_reg_mask { - u8 index; - u8 and_mask; - u8 or_mask; - u8 fill; -}; - -struct cpia2_command { - u32 command; - u8 req_mode; /* (Block or random) | registerBank */ - u8 reg_count; - u8 direction; - u8 start; - union reg_types { - struct cpia2_register registers[32]; - struct cpia2_reg_mask masks[16]; - u8 block_data[64]; - u8 *patch_data; /* points to function defined block */ - } buffer; -}; - -struct camera_params { - struct { - u8 firmware_revision_hi; /* For system register set (bank 0) */ - u8 firmware_revision_lo; - u8 asic_id; /* Video Compressor set (bank 1) */ - u8 asic_rev; - u8 vp_device_hi; /* Video Processor set (bank 2) */ - u8 vp_device_lo; - u8 sensor_flags; - u8 sensor_rev; - } version; - - struct { - u32 device_type; /* enumerated from vendor/product ids. - * Currently, either STV_672 or STV_676 */ - u16 vendor; - u16 product; - u16 device_revision; - } pnp_id; - - struct { - u8 brightness; /* CPIA2_VP_EXPOSURE_TARGET */ - u8 contrast; /* Note: this is CPIA2_VP_YRANGE */ - u8 saturation; /* CPIA2_VP_SATURATION */ - } color_params; - - struct { - u8 cam_register; - u8 flicker_mode_req; /* 1 if flicker on, else never flicker */ - int mains_frequency; - } flicker_control; - - struct { - u8 jpeg_options; - u8 creep_period; - u8 user_squeeze; - u8 inhibit_htables; - } compression; - - struct { - u8 ohsize; /* output image size */ - u8 ovsize; - u8 hcrop; /* cropping start_pos/4 */ - u8 vcrop; - u8 hphase; /* scaling registers */ - u8 vphase; - u8 hispan; - u8 vispan; - u8 hicrop; - u8 vicrop; - u8 hifraction; - u8 vifraction; - } image_size; - - struct { - int width; /* actual window width */ - int height; /* actual window height */ - } roi; - - struct { - u8 video_mode; - u8 frame_rate; - u8 video_size; /* Not a register, just a convenience for cropped sizes */ - u8 gpio_direction; - u8 gpio_data; - u8 system_ctrl; - u8 system_state; - u8 lowlight_boost; /* Bool: 0 = off, 1 = on */ - u8 device_config; - u8 exposure_modes; - u8 user_effects; - } vp_params; - - struct { - u8 pw_control; - u8 wakeup; - u8 vc_control; - u8 vc_mp_direction; - u8 vc_mp_data; - u8 target_kb; - } vc_params; - - struct { - u8 power_mode; - u8 system_ctrl; - u8 stream_mode; /* This is the current alternate for usb drivers */ - u8 allow_corrupt; - } camera_state; -}; - -#define NUM_SBUF 2 - -struct cpia2_sbuf { - char *data; - struct urb *urb; -}; - -struct framebuf { - struct timeval timestamp; - unsigned long seq; - int num; - int length; - int max_length; - volatile enum frame_status status; - u8 *data; - struct framebuf *next; -}; - -struct cpia2_fh { - enum v4l2_priority prio; - u8 mmapped; -}; - -struct camera_data { - /* locks */ - struct mutex busy_lock; /* guard against SMP multithreading */ - struct v4l2_prio_state prio; - - /* camera status */ - volatile int present; /* Is the camera still present? */ - int open_count; /* # of process that have camera open */ - int first_image_seen; - u8 mains_freq; /* for flicker control */ - enum sensors sensor_type; - u8 flush; - u8 mmapped; - int streaming; /* 0 = no, 1 = yes */ - int xfer_mode; /* XFER_BULK or XFER_ISOC */ - struct camera_params params; /* camera settings */ - - /* v4l */ - int video_size; /* VIDEO_SIZE_ */ - struct video_device *vdev; /* v4l videodev */ - struct video_picture vp; /* v4l camera settings */ - struct video_window vw; /* v4l capture area */ - __u32 pixelformat; /* Format fourcc */ - - /* USB */ - struct usb_device *dev; - unsigned char iface; - unsigned int cur_alt; - unsigned int old_alt; - struct cpia2_sbuf sbuf[NUM_SBUF]; /* Double buffering */ - - wait_queue_head_t wq_stream; - - /* Buffering */ - u32 frame_size; - int num_frames; - unsigned long frame_count; - u8 *frame_buffer; /* frame buffer data */ - struct framebuf *buffers; - struct framebuf * volatile curbuff; - struct framebuf *workbuff; - - /* MJPEG Extension */ - int APPn; /* Number of APP segment to be written, must be 0..15 */ - int APP_len; /* Length of data in JPEG APPn segment */ - char APP_data[60]; /* Data in the JPEG APPn segment. */ - - int COM_len; /* Length of data in JPEG COM segment */ - char COM_data[60]; /* Data in JPEG COM segment */ -}; - -/* v4l */ -int cpia2_register_camera(struct camera_data *cam); -void cpia2_unregister_camera(struct camera_data *cam); - -/* core */ -int cpia2_reset_camera(struct camera_data *cam); -int cpia2_set_low_power(struct camera_data *cam); -void cpia2_dbg_dump_registers(struct camera_data *cam); -int cpia2_match_video_size(int width, int height); -void cpia2_set_camera_state(struct camera_data *cam); -void cpia2_save_camera_state(struct camera_data *cam); -void cpia2_set_color_params(struct camera_data *cam); -void cpia2_set_brightness(struct camera_data *cam, unsigned char value); -void cpia2_set_contrast(struct camera_data *cam, unsigned char value); -void cpia2_set_saturation(struct camera_data *cam, unsigned char value); -int cpia2_set_flicker_mode(struct camera_data *cam, int mode); -void cpia2_set_format(struct camera_data *cam); -int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd); -int cpia2_do_command(struct camera_data *cam, - unsigned int command, - unsigned char direction, unsigned char param); -struct camera_data *cpia2_init_camera_struct(void); -int cpia2_init_camera(struct camera_data *cam); -int cpia2_allocate_buffers(struct camera_data *cam); -void cpia2_free_buffers(struct camera_data *cam); -long cpia2_read(struct camera_data *cam, - char __user *buf, unsigned long count, int noblock); -unsigned int cpia2_poll(struct camera_data *cam, - struct file *filp, poll_table *wait); -int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma); -void cpia2_set_property_flip(struct camera_data *cam, int prop_val); -void cpia2_set_property_mirror(struct camera_data *cam, int prop_val); -int cpia2_set_target_kb(struct camera_data *cam, unsigned char value); -int cpia2_set_gpio(struct camera_data *cam, unsigned char setting); -int cpia2_set_fps(struct camera_data *cam, int framerate); - -/* usb */ -int cpia2_usb_init(void); -void cpia2_usb_cleanup(void); -int cpia2_usb_transfer_cmd(struct camera_data *cam, void *registers, - u8 request, u8 start, u8 count, u8 direction); -int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate); -int cpia2_usb_stream_stop(struct camera_data *cam); -int cpia2_usb_stream_pause(struct camera_data *cam); -int cpia2_usb_stream_resume(struct camera_data *cam); -int cpia2_usb_change_streaming_alternate(struct camera_data *cam, - unsigned int alt); - - -/* ----------------------- debug functions ---------------------- */ -#ifdef _CPIA2_DEBUG_ -#define ALOG(lev, fmt, args...) printk(lev "%s:%d %s(): " fmt, __FILE__, __LINE__, __func__, ## args) -#define LOG(fmt, args...) ALOG(KERN_INFO, fmt, ## args) -#define ERR(fmt, args...) ALOG(KERN_ERR, fmt, ## args) -#define DBG(fmt, args...) ALOG(KERN_DEBUG, fmt, ## args) -#else -#define ALOG(fmt,args...) printk(fmt,##args) -#define LOG(fmt,args...) ALOG(KERN_INFO "cpia2: "fmt,##args) -#define ERR(fmt,args...) ALOG(KERN_ERR "cpia2: "fmt,##args) -#define DBG(fmn,args...) do {} while(0) -#endif -/* No function or lineno, for shorter lines */ -#define KINFO(fmt, args...) printk(KERN_INFO fmt,##args) - -#endif diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c deleted file mode 100644 index fd771c7a2..000000000 --- a/drivers/media/video/cpia2/cpia2_core.c +++ /dev/null @@ -1,2525 +0,0 @@ -/**************************************************************************** - * - * Filename: cpia2_core.c - * - * Copyright 2001, STMicrolectronics, Inc. - * Contact: steve.miller@st.com - * - * Description: - * This is a USB driver for CPia2 based video cameras. - * The infrastructure of this driver is based on the cpia usb driver by - * Jochen Scharrlach and Johannes Erdfeldt. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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. - * - * Stripped of 2.4 stuff ready for main kernel submit by - * Alan Cox - * - ****************************************************************************/ - -#include "cpia2.h" - -#include -#include - -//#define _CPIA2_DEBUG_ - -#include "cpia2patch.h" - -#ifdef _CPIA2_DEBUG_ - -static const char *block_name[] = { - "System", - "VC", - "VP", - "IDATA" -}; -#endif - -static unsigned int debugs_on = 0;//DEBUG_REG; - - -/****************************************************************************** - * - * Forward Declarations - * - *****************************************************************************/ -static int apply_vp_patch(struct camera_data *cam); -static int set_default_user_mode(struct camera_data *cam); -static int set_vw_size(struct camera_data *cam, int size); -static int configure_sensor(struct camera_data *cam, - int reqwidth, int reqheight); -static int config_sensor_410(struct camera_data *cam, - int reqwidth, int reqheight); -static int config_sensor_500(struct camera_data *cam, - int reqwidth, int reqheight); -static int set_all_properties(struct camera_data *cam); -static void get_color_params(struct camera_data *cam); -static void wake_system(struct camera_data *cam); -static void set_lowlight_boost(struct camera_data *cam); -static void reset_camera_struct(struct camera_data *cam); -static int cpia2_set_high_power(struct camera_data *cam); - -/* Here we want the physical address of the memory. - * This is used when initializing the contents of the - * area and marking the pages as reserved. - */ -static inline unsigned long kvirt_to_pa(unsigned long adr) -{ - unsigned long kva, ret; - - kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); - kva |= adr & (PAGE_SIZE-1); /* restore the offset */ - ret = __pa(kva); - return ret; -} - -static void *rvmalloc(unsigned long size) -{ - void *mem; - unsigned long adr; - - /* Round it off to PAGE_SIZE */ - size = PAGE_ALIGN(size); - - mem = vmalloc_32(size); - if (!mem) - return NULL; - - memset(mem, 0, size); /* Clear the ram out, no junk to the user */ - adr = (unsigned long) mem; - - while ((long)size > 0) { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - return mem; -} - -static void rvfree(void *mem, unsigned long size) -{ - unsigned long adr; - - if (!mem) - return; - - size = PAGE_ALIGN(size); - - adr = (unsigned long) mem; - while ((long)size > 0) { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - vfree(mem); -} - -/****************************************************************************** - * - * cpia2_do_command - * - * Send an arbitrary command to the camera. For commands that read from - * the camera, copy the buffers into the proper param structures. - *****************************************************************************/ -int cpia2_do_command(struct camera_data *cam, - u32 command, u8 direction, u8 param) -{ - int retval = 0; - struct cpia2_command cmd; - unsigned int device = cam->params.pnp_id.device_type; - - cmd.command = command; - cmd.reg_count = 2; /* default */ - cmd.direction = direction; - - /*** - * Set up the command. - ***/ - switch (command) { - case CPIA2_CMD_GET_VERSION: - cmd.req_mode = - CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; - cmd.start = CPIA2_SYSTEM_DEVICE_HI; - break; - case CPIA2_CMD_GET_PNP_ID: - cmd.req_mode = - CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; - cmd.reg_count = 8; - cmd.start = CPIA2_SYSTEM_DESCRIP_VID_HI; - break; - case CPIA2_CMD_GET_ASIC_TYPE: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.start = CPIA2_VC_ASIC_ID; - break; - case CPIA2_CMD_GET_SENSOR: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.start = CPIA2_VP_SENSOR_FLAGS; - break; - case CPIA2_CMD_GET_VP_DEVICE: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.start = CPIA2_VP_DEVICEH; - break; - case CPIA2_CMD_SET_VP_BRIGHTNESS: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VP_BRIGHTNESS: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - if (device == DEVICE_STV_672) - cmd.start = CPIA2_VP4_EXPOSURE_TARGET; - else - cmd.start = CPIA2_VP5_EXPOSURE_TARGET; - break; - case CPIA2_CMD_SET_CONTRAST: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_CONTRAST: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_YRANGE; - break; - case CPIA2_CMD_SET_VP_SATURATION: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VP_SATURATION: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - if (device == DEVICE_STV_672) - cmd.start = CPIA2_VP_SATURATION; - else - cmd.start = CPIA2_VP5_MCUVSATURATION; - break; - case CPIA2_CMD_SET_VP_GPIO_DATA: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VP_GPIO_DATA: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_GPIO_DATA; - break; - case CPIA2_CMD_SET_VP_GPIO_DIRECTION: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VP_GPIO_DIRECTION: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_GPIO_DIRECTION; - break; - case CPIA2_CMD_SET_VC_MP_GPIO_DATA: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VC_MP_GPIO_DATA: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.reg_count = 1; - cmd.start = CPIA2_VC_MP_DATA; - break; - case CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.reg_count = 1; - cmd.start = CPIA2_VC_MP_DIR; - break; - case CPIA2_CMD_ENABLE_PACKET_CTRL: - cmd.req_mode = - CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; - cmd.start = CPIA2_SYSTEM_INT_PACKET_CTRL; - cmd.reg_count = 1; - cmd.buffer.block_data[0] = param; - break; - case CPIA2_CMD_SET_FLICKER_MODES: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_FLICKER_MODES: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_FLICKER_MODES; - break; - case CPIA2_CMD_RESET_FIFO: /* clear fifo and enable stream block */ - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; - cmd.reg_count = 2; - cmd.start = 0; - cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL; - cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC | - CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT; - cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL; - cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC | - CPIA2_VC_ST_CTRL_DST_USB | - CPIA2_VC_ST_CTRL_EOF_DETECT | - CPIA2_VC_ST_CTRL_FIFO_ENABLE; - break; - case CPIA2_CMD_SET_HI_POWER: - cmd.req_mode = - CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM; - cmd.reg_count = 2; - cmd.buffer.registers[0].index = - CPIA2_SYSTEM_SYSTEM_CONTROL; - cmd.buffer.registers[1].index = - CPIA2_SYSTEM_SYSTEM_CONTROL; - cmd.buffer.registers[0].value = CPIA2_SYSTEM_CONTROL_CLEAR_ERR; - cmd.buffer.registers[1].value = - CPIA2_SYSTEM_CONTROL_HIGH_POWER; - break; - case CPIA2_CMD_SET_LOW_POWER: - cmd.req_mode = - CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; - cmd.reg_count = 1; - cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; - cmd.buffer.block_data[0] = 0; - break; - case CPIA2_CMD_CLEAR_V2W_ERR: - cmd.req_mode = - CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; - cmd.reg_count = 1; - cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; - cmd.buffer.block_data[0] = CPIA2_SYSTEM_CONTROL_CLEAR_ERR; - break; - case CPIA2_CMD_SET_USER_MODE: /* Then fall through */ - cmd.buffer.block_data[0] = param; - case CPIA2_CMD_GET_USER_MODE: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - if (device == DEVICE_STV_672) - cmd.start = CPIA2_VP4_USER_MODE; - else - cmd.start = CPIA2_VP5_USER_MODE; - break; - case CPIA2_CMD_FRAMERATE_REQ: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - if (device == DEVICE_STV_672) - cmd.start = CPIA2_VP4_FRAMERATE_REQUEST; - else - cmd.start = CPIA2_VP5_FRAMERATE_REQUEST; - cmd.buffer.block_data[0] = param; - break; - case CPIA2_CMD_SET_WAKEUP: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_WAKEUP: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.reg_count = 1; - cmd.start = CPIA2_VC_WAKEUP; - break; - case CPIA2_CMD_SET_PW_CONTROL: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_PW_CONTROL: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.reg_count = 1; - cmd.start = CPIA2_VC_PW_CTRL; - break; - case CPIA2_CMD_GET_VP_SYSTEM_STATE: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_SYSTEMSTATE; - break; - case CPIA2_CMD_SET_SYSTEM_CTRL: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_SYSTEM_CTRL: - cmd.req_mode = - CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; - cmd.reg_count = 1; - cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL; - break; - case CPIA2_CMD_SET_VP_SYSTEM_CTRL: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VP_SYSTEM_CTRL: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_SYSTEMCTRL; - break; - case CPIA2_CMD_SET_VP_EXP_MODES: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VP_EXP_MODES: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_EXPOSURE_MODES; - break; - case CPIA2_CMD_SET_DEVICE_CONFIG: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_DEVICE_CONFIG: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_DEVICE_CONFIG; - break; - case CPIA2_CMD_SET_SERIAL_ADDR: - cmd.buffer.block_data[0] = param; - cmd.req_mode = - CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; - cmd.reg_count = 1; - cmd.start = CPIA2_SYSTEM_VP_SERIAL_ADDR; - break; - case CPIA2_CMD_SET_SENSOR_CR1: - cmd.buffer.block_data[0] = param; - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_SENSOR_CR1; - break; - case CPIA2_CMD_SET_VC_CONTROL: - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_VC_CONTROL: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.reg_count = 1; - cmd.start = CPIA2_VC_VC_CTRL; - break; - case CPIA2_CMD_SET_TARGET_KB: - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; - cmd.reg_count = 1; - cmd.buffer.registers[0].index = CPIA2_VC_VC_TARGET_KB; - cmd.buffer.registers[0].value = param; - break; - case CPIA2_CMD_SET_DEF_JPEG_OPT: - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; - cmd.reg_count = 4; - cmd.buffer.registers[0].index = CPIA2_VC_VC_JPEG_OPT; - cmd.buffer.registers[0].value = - CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE; - cmd.buffer.registers[1].index = CPIA2_VC_VC_USER_SQUEEZE; - cmd.buffer.registers[1].value = 20; - cmd.buffer.registers[2].index = CPIA2_VC_VC_CREEP_PERIOD; - cmd.buffer.registers[2].value = 2; - cmd.buffer.registers[3].index = CPIA2_VC_VC_JPEG_OPT; - cmd.buffer.registers[3].value = CPIA2_VC_VC_JPEG_OPT_DEFAULT; - break; - case CPIA2_CMD_REHASH_VP4: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - cmd.start = CPIA2_VP_REHASH_VALUES; - cmd.buffer.block_data[0] = param; - break; - case CPIA2_CMD_SET_USER_EFFECTS: /* Note: Be careful with this as - this register can also affect - flicker modes */ - cmd.buffer.block_data[0] = param; /* Then fall through */ - case CPIA2_CMD_GET_USER_EFFECTS: - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 1; - if (device == DEVICE_STV_672) - cmd.start = CPIA2_VP4_USER_EFFECTS; - else - cmd.start = CPIA2_VP5_USER_EFFECTS; - break; - default: - LOG("DoCommand received invalid command\n"); - return -EINVAL; - } - - retval = cpia2_send_command(cam, &cmd); - if (retval) { - return retval; - } - - /*** - * Now copy any results from a read into the appropriate param struct. - ***/ - switch (command) { - case CPIA2_CMD_GET_VERSION: - cam->params.version.firmware_revision_hi = - cmd.buffer.block_data[0]; - cam->params.version.firmware_revision_lo = - cmd.buffer.block_data[1]; - break; - case CPIA2_CMD_GET_PNP_ID: - cam->params.pnp_id.vendor = (cmd.buffer.block_data[0] << 8) | - cmd.buffer.block_data[1]; - cam->params.pnp_id.product = (cmd.buffer.block_data[2] << 8) | - cmd.buffer.block_data[3]; - cam->params.pnp_id.device_revision = - (cmd.buffer.block_data[4] << 8) | - cmd.buffer.block_data[5]; - if (cam->params.pnp_id.vendor == 0x553) { - if (cam->params.pnp_id.product == 0x100) { - cam->params.pnp_id.device_type = DEVICE_STV_672; - } else if (cam->params.pnp_id.product == 0x140 || - cam->params.pnp_id.product == 0x151) { - cam->params.pnp_id.device_type = DEVICE_STV_676; - } - } - break; - case CPIA2_CMD_GET_ASIC_TYPE: - cam->params.version.asic_id = cmd.buffer.block_data[0]; - cam->params.version.asic_rev = cmd.buffer.block_data[1]; - break; - case CPIA2_CMD_GET_SENSOR: - cam->params.version.sensor_flags = cmd.buffer.block_data[0]; - cam->params.version.sensor_rev = cmd.buffer.block_data[1]; - break; - case CPIA2_CMD_GET_VP_DEVICE: - cam->params.version.vp_device_hi = cmd.buffer.block_data[0]; - cam->params.version.vp_device_lo = cmd.buffer.block_data[1]; - break; - case CPIA2_CMD_GET_VP_BRIGHTNESS: - cam->params.color_params.brightness = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_CONTRAST: - cam->params.color_params.contrast = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VP_SATURATION: - cam->params.color_params.saturation = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VP_GPIO_DATA: - cam->params.vp_params.gpio_data = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VP_GPIO_DIRECTION: - cam->params.vp_params.gpio_direction = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION: - cam->params.vc_params.vc_mp_direction =cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VC_MP_GPIO_DATA: - cam->params.vc_params.vc_mp_data = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_FLICKER_MODES: - cam->params.flicker_control.cam_register = - cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_WAKEUP: - cam->params.vc_params.wakeup = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_PW_CONTROL: - cam->params.vc_params.pw_control = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_SYSTEM_CTRL: - cam->params.camera_state.system_ctrl = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VP_SYSTEM_STATE: - cam->params.vp_params.system_state = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VP_SYSTEM_CTRL: - cam->params.vp_params.system_ctrl = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VP_EXP_MODES: - cam->params.vp_params.exposure_modes = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_DEVICE_CONFIG: - cam->params.vp_params.device_config = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_VC_CONTROL: - cam->params.vc_params.vc_control = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_USER_MODE: - cam->params.vp_params.video_mode = cmd.buffer.block_data[0]; - break; - case CPIA2_CMD_GET_USER_EFFECTS: - cam->params.vp_params.user_effects = cmd.buffer.block_data[0]; - break; - default: - break; - } - return retval; -} - -/****************************************************************************** - * - * cpia2_send_command - * - *****************************************************************************/ -int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd) -{ - u8 count; - u8 start; - u8 block_index; - u8 *buffer; - int retval; - const char* dir; - - if (cmd->direction == TRANSFER_WRITE) { - dir = "Write"; - } else { - dir = "Read"; - } - - block_index = cmd->req_mode & 0x03; - - switch (cmd->req_mode & 0x0c) { - case CAMERAACCESS_TYPE_RANDOM: - count = cmd->reg_count * sizeof(struct cpia2_register); - start = 0; - buffer = (u8 *) & cmd->buffer; - if (debugs_on & DEBUG_REG) - DBG("%s Random: Register block %s\n", dir, - block_name[block_index]); - break; - case CAMERAACCESS_TYPE_BLOCK: - count = cmd->reg_count; - start = cmd->start; - buffer = cmd->buffer.block_data; - if (debugs_on & DEBUG_REG) - DBG("%s Block: Register block %s\n", dir, - block_name[block_index]); - break; - case CAMERAACCESS_TYPE_MASK: - count = cmd->reg_count * sizeof(struct cpia2_reg_mask); - start = 0; - buffer = (u8 *) & cmd->buffer; - if (debugs_on & DEBUG_REG) - DBG("%s Mask: Register block %s\n", dir, - block_name[block_index]); - break; - case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */ - count = cmd->reg_count; - start = cmd->start; - buffer = cmd->buffer.block_data; - if (debugs_on & DEBUG_REG) - DBG("%s Repeat: Register block %s\n", dir, - block_name[block_index]); - break; - default: - LOG("%s: invalid request mode\n",__FUNCTION__); - return -EINVAL; - } - - retval = cpia2_usb_transfer_cmd(cam, - buffer, - cmd->req_mode, - start, count, cmd->direction); -#ifdef _CPIA2_DEBUG_ - if (debugs_on & DEBUG_REG) { - int i; - for (i = 0; i < cmd->reg_count; i++) { - if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK) - KINFO("%s Block: [0x%02X] = 0x%02X\n", - dir, start + i, buffer[i]); - if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM) - KINFO("%s Random: [0x%02X] = 0x%02X\n", - dir, cmd->buffer.registers[i].index, - cmd->buffer.registers[i].value); - } - } -#endif - - return retval; -}; - -/************* - * Functions to implement camera functionality - *************/ -/****************************************************************************** - * - * cpia2_get_version_info - * - *****************************************************************************/ -static void cpia2_get_version_info(struct camera_data *cam) -{ - cpia2_do_command(cam, CPIA2_CMD_GET_VERSION, TRANSFER_READ, 0); - cpia2_do_command(cam, CPIA2_CMD_GET_PNP_ID, TRANSFER_READ, 0); - cpia2_do_command(cam, CPIA2_CMD_GET_ASIC_TYPE, TRANSFER_READ, 0); - cpia2_do_command(cam, CPIA2_CMD_GET_SENSOR, TRANSFER_READ, 0); - cpia2_do_command(cam, CPIA2_CMD_GET_VP_DEVICE, TRANSFER_READ, 0); -} - -/****************************************************************************** - * - * cpia2_reset_camera - * - * Called at least during the open process, sets up initial params. - *****************************************************************************/ -int cpia2_reset_camera(struct camera_data *cam) -{ - u8 tmp_reg; - int retval = 0; - int i; - struct cpia2_command cmd; - - /*** - * VC setup - ***/ - retval = configure_sensor(cam, - cam->params.roi.width, - cam->params.roi.height); - if (retval < 0) { - ERR("Couldn't configure sensor, error=%d\n", retval); - return retval; - } - - /* Clear FIFO and route/enable stream block */ - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; - cmd.direction = TRANSFER_WRITE; - cmd.reg_count = 2; - cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL; - cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC | - CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT; - cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL; - cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC | - CPIA2_VC_ST_CTRL_DST_USB | - CPIA2_VC_ST_CTRL_EOF_DETECT | CPIA2_VC_ST_CTRL_FIFO_ENABLE; - - cpia2_send_command(cam, &cmd); - - cpia2_set_high_power(cam); - - if (cam->params.pnp_id.device_type == DEVICE_STV_672) { - /* Enable button notification */ - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM; - cmd.buffer.registers[0].index = CPIA2_SYSTEM_INT_PACKET_CTRL; - cmd.buffer.registers[0].value = - CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX; - cmd.reg_count = 1; - cpia2_send_command(cam, &cmd); - } - - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ - - if (cam->params.pnp_id.device_type == DEVICE_STV_672) - retval = apply_vp_patch(cam); - - /* wait for vp to go to sleep */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ - - /*** - * If this is a 676, apply VP5 fixes before we start streaming - ***/ - if (cam->params.pnp_id.device_type == DEVICE_STV_676) { - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; - - /* The following writes improve the picture */ - cmd.buffer.registers[0].index = CPIA2_VP5_MYBLACK_LEVEL; - cmd.buffer.registers[0].value = 0; /* reduce from the default - * rec 601 pedestal of 16 */ - cmd.buffer.registers[1].index = CPIA2_VP5_MCYRANGE; - cmd.buffer.registers[1].value = 0x92; /* increase from 100% to - * (256/256 - 31) to fill - * available range */ - cmd.buffer.registers[2].index = CPIA2_VP5_MYCEILING; - cmd.buffer.registers[2].value = 0xFF; /* Increase from the - * default rec 601 ceiling - * of 240 */ - cmd.buffer.registers[3].index = CPIA2_VP5_MCUVSATURATION; - cmd.buffer.registers[3].value = 0xFF; /* Increase from the rec - * 601 100% level (128) - * to 145-192 */ - cmd.buffer.registers[4].index = CPIA2_VP5_ANTIFLKRSETUP; - cmd.buffer.registers[4].value = 0x80; /* Inhibit the - * anti-flicker */ - - /* The following 4 writes are a fix to allow QVGA to work at 30 fps */ - cmd.buffer.registers[5].index = CPIA2_VP_RAM_ADDR_H; - cmd.buffer.registers[5].value = 0x01; - cmd.buffer.registers[6].index = CPIA2_VP_RAM_ADDR_L; - cmd.buffer.registers[6].value = 0xE3; - cmd.buffer.registers[7].index = CPIA2_VP_RAM_DATA; - cmd.buffer.registers[7].value = 0x02; - cmd.buffer.registers[8].index = CPIA2_VP_RAM_DATA; - cmd.buffer.registers[8].value = 0xFC; - - cmd.direction = TRANSFER_WRITE; - cmd.reg_count = 9; - - cpia2_send_command(cam, &cmd); - } - - /* Activate all settings and start the data stream */ - /* Set user mode */ - set_default_user_mode(cam); - - /* Give VP time to wake up */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ - - set_all_properties(cam); - - cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0); - DBG("After SetAllProperties(cam), user mode is 0x%0X\n", - cam->params.vp_params.video_mode); - - /*** - * Set audio regulator off. This and the code to set the compresison - * state are too complex to form a CPIA2_CMD_, and seem to be somewhat - * intertwined. This stuff came straight from the windows driver. - ***/ - /* Turn AutoExposure off in VP and enable the serial bridge to the sensor */ - cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0); - tmp_reg = cam->params.vp_params.system_ctrl; - cmd.buffer.registers[0].value = tmp_reg & - (tmp_reg & (CPIA2_VP_SYSTEMCTRL_HK_CONTROL ^ 0xFF)); - - cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0); - cmd.buffer.registers[1].value = cam->params.vp_params.device_config | - CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE; - cmd.buffer.registers[0].index = CPIA2_VP_SYSTEMCTRL; - cmd.buffer.registers[1].index = CPIA2_VP_DEVICE_CONFIG; - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; - cmd.reg_count = 2; - cmd.direction = TRANSFER_WRITE; - cmd.start = 0; - cpia2_send_command(cam, &cmd); - - /* Set the correct I2C address in the CPiA-2 system register */ - cpia2_do_command(cam, - CPIA2_CMD_SET_SERIAL_ADDR, - TRANSFER_WRITE, - CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR); - - /* Now have sensor access - set bit to turn the audio regulator off */ - cpia2_do_command(cam, - CPIA2_CMD_SET_SENSOR_CR1, - TRANSFER_WRITE, CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR); - - /* Set the correct I2C address in the CPiA-2 system register */ - if (cam->params.pnp_id.device_type == DEVICE_STV_672) - cpia2_do_command(cam, - CPIA2_CMD_SET_SERIAL_ADDR, - TRANSFER_WRITE, - CPIA2_SYSTEM_VP_SERIAL_ADDR_VP); // 0x88 - else - cpia2_do_command(cam, - CPIA2_CMD_SET_SERIAL_ADDR, - TRANSFER_WRITE, - CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP); // 0x8a - - /* increase signal drive strength */ - if (cam->params.pnp_id.device_type == DEVICE_STV_676) - cpia2_do_command(cam, - CPIA2_CMD_SET_VP_EXP_MODES, - TRANSFER_WRITE, - CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP); - - /* Start autoexposure */ - cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0); - cmd.buffer.registers[0].value = cam->params.vp_params.device_config & - (CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE ^ 0xFF); - - cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0); - cmd.buffer.registers[1].value = - cam->params.vp_params.system_ctrl | CPIA2_VP_SYSTEMCTRL_HK_CONTROL; - - cmd.buffer.registers[0].index = CPIA2_VP_DEVICE_CONFIG; - cmd.buffer.registers[1].index = CPIA2_VP_SYSTEMCTRL; - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP; - cmd.reg_count = 2; - cmd.direction = TRANSFER_WRITE; - - cpia2_send_command(cam, &cmd); - - /* Set compression state */ - cpia2_do_command(cam, CPIA2_CMD_GET_VC_CONTROL, TRANSFER_READ, 0); - if (cam->params.compression.inhibit_htables) { - tmp_reg = cam->params.vc_params.vc_control | - CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES; - } else { - tmp_reg = cam->params.vc_params.vc_control & - ~CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES; - } - cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg); - - /* Set target size (kb) on vc */ - cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB, - TRANSFER_WRITE, cam->params.vc_params.target_kb); - - /* Wiggle VC Reset */ - /*** - * First read and wait a bit. - ***/ - for (i = 0; i < 50; i++) { - cpia2_do_command(cam, CPIA2_CMD_GET_PW_CONTROL, - TRANSFER_READ, 0); - } - - tmp_reg = cam->params.vc_params.pw_control; - tmp_reg &= ~CPIA2_VC_PW_CTRL_VC_RESET_N; - - cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg); - - tmp_reg |= CPIA2_VC_PW_CTRL_VC_RESET_N; - cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg); - - cpia2_do_command(cam, CPIA2_CMD_SET_DEF_JPEG_OPT, TRANSFER_WRITE, 0); - - cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0); - DBG("After VC RESET, user mode is 0x%0X\n", - cam->params.vp_params.video_mode); - - return retval; -} - -/****************************************************************************** - * - * cpia2_set_high_power - * - *****************************************************************************/ -static int cpia2_set_high_power(struct camera_data *cam) -{ - int i; - for (i = 0; i <= 50; i++) { - /* Read system status */ - cpia2_do_command(cam,CPIA2_CMD_GET_SYSTEM_CTRL,TRANSFER_READ,0); - - /* If there is an error, clear it */ - if(cam->params.camera_state.system_ctrl & - CPIA2_SYSTEM_CONTROL_V2W_ERR) - cpia2_do_command(cam, CPIA2_CMD_CLEAR_V2W_ERR, - TRANSFER_WRITE, 0); - - /* Try to set high power mode */ - cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL, - TRANSFER_WRITE, 1); - - /* Try to read something in VP to check if everything is awake */ - cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_STATE, - TRANSFER_READ, 0); - if (cam->params.vp_params.system_state & - CPIA2_VP_SYSTEMSTATE_HK_ALIVE) { - break; - } else if (i == 50) { - cam->params.camera_state.power_mode = LO_POWER_MODE; - ERR("Camera did not wake up\n"); - return -EIO; - } - } - - DBG("System now in high power state\n"); - cam->params.camera_state.power_mode = HI_POWER_MODE; - return 0; -} - -/****************************************************************************** - * - * cpia2_set_low_power - * - *****************************************************************************/ -int cpia2_set_low_power(struct camera_data *cam) -{ - cam->params.camera_state.power_mode = LO_POWER_MODE; - cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL, TRANSFER_WRITE, 0); - return 0; -} - -/****************************************************************************** - * - * apply_vp_patch - * - *****************************************************************************/ -static int apply_vp_patch(struct camera_data *cam) -{ - int i, j; - struct cpia2_command cmd; - - cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP; - cmd.direction = TRANSFER_WRITE; - - for (i = 0; i < PATCH_DATA_SIZE; i++) { - for (j = 0; j < patch_data[i].count; j++) { - cmd.buffer.block_data[j] = patch_data[i].data[j]; - } - - cmd.start = patch_data[i].reg; - cmd.reg_count = patch_data[i].count; - cpia2_send_command(cam, &cmd); - } - - return 0; -} - -/****************************************************************************** - * - * set_default_user_mode - * - *****************************************************************************/ -static int set_default_user_mode(struct camera_data *cam) -{ - unsigned char user_mode; - unsigned char frame_rate; - int width = cam->params.roi.width; - int height = cam->params.roi.height; - - switch (cam->params.version.sensor_flags) { - case CPIA2_VP_SENSOR_FLAGS_404: - case CPIA2_VP_SENSOR_FLAGS_407: - case CPIA2_VP_SENSOR_FLAGS_409: - case CPIA2_VP_SENSOR_FLAGS_410: - if ((width > STV_IMAGE_QCIF_COLS) - || (height > STV_IMAGE_QCIF_ROWS)) { - user_mode = CPIA2_VP_USER_MODE_CIF; - } else { - user_mode = CPIA2_VP_USER_MODE_QCIFDS; - } - frame_rate = CPIA2_VP_FRAMERATE_30; - break; - case CPIA2_VP_SENSOR_FLAGS_500: - if ((width > STV_IMAGE_CIF_COLS) - || (height > STV_IMAGE_CIF_ROWS)) { - user_mode = CPIA2_VP_USER_MODE_VGA; - } else { - user_mode = CPIA2_VP_USER_MODE_QVGADS; - } - if (cam->params.pnp_id.device_type == DEVICE_STV_672) - frame_rate = CPIA2_VP_FRAMERATE_15; - else - frame_rate = CPIA2_VP_FRAMERATE_30; - break; - default: - LOG("%s: Invalid sensor flag value 0x%0X\n",__FUNCTION__, - cam->params.version.sensor_flags); - return -EINVAL; - } - - DBG("Sensor flag = 0x%0x, user mode = 0x%0x, frame rate = 0x%X\n", - cam->params.version.sensor_flags, user_mode, frame_rate); - cpia2_do_command(cam, CPIA2_CMD_SET_USER_MODE, TRANSFER_WRITE, - user_mode); - if(cam->params.vp_params.frame_rate > 0 && - frame_rate > cam->params.vp_params.frame_rate) - frame_rate = cam->params.vp_params.frame_rate; - - cpia2_set_fps(cam, frame_rate); - -// if (cam->params.pnp_id.device_type == DEVICE_STV_676) -// cpia2_do_command(cam, -// CPIA2_CMD_SET_VP_SYSTEM_CTRL, -// TRANSFER_WRITE, -// CPIA2_VP_SYSTEMCTRL_HK_CONTROL | -// CPIA2_VP_SYSTEMCTRL_POWER_CONTROL); - - return 0; -} - -/****************************************************************************** - * - * cpia2_match_video_size - * - * return the best match, where 'best' is as always - * the largest that is not bigger than what is requested. - *****************************************************************************/ -int cpia2_match_video_size(int width, int height) -{ - if (width >= STV_IMAGE_VGA_COLS && height >= STV_IMAGE_VGA_ROWS) - return VIDEOSIZE_VGA; - - if (width >= STV_IMAGE_CIF_COLS && height >= STV_IMAGE_CIF_ROWS) - return VIDEOSIZE_CIF; - - if (width >= STV_IMAGE_QVGA_COLS && height >= STV_IMAGE_QVGA_ROWS) - return VIDEOSIZE_QVGA; - - if (width >= 288 && height >= 216) - return VIDEOSIZE_288_216; - - if (width >= 256 && height >= 192) - return VIDEOSIZE_256_192; - - if (width >= 224 && height >= 168) - return VIDEOSIZE_224_168; - - if (width >= 192 && height >= 144) - return VIDEOSIZE_192_144; - - if (width >= STV_IMAGE_QCIF_COLS && height >= STV_IMAGE_QCIF_ROWS) - return VIDEOSIZE_QCIF; - - return -1; -} - -/****************************************************************************** - * - * SetVideoSize - * - *****************************************************************************/ -static int set_vw_size(struct camera_data *cam, int size) -{ - int retval = 0; - - cam->params.vp_params.video_size = size; - - switch (size) { - case VIDEOSIZE_VGA: - DBG("Setting size to VGA\n"); - cam->params.roi.width = STV_IMAGE_VGA_COLS; - cam->params.roi.height = STV_IMAGE_VGA_ROWS; - cam->vw.width = STV_IMAGE_VGA_COLS; - cam->vw.height = STV_IMAGE_VGA_ROWS; - break; - case VIDEOSIZE_CIF: - DBG("Setting size to CIF\n"); - cam->params.roi.width = STV_IMAGE_CIF_COLS; - cam->params.roi.height = STV_IMAGE_CIF_ROWS; - cam->vw.width = STV_IMAGE_CIF_COLS; - cam->vw.height = STV_IMAGE_CIF_ROWS; - break; - case VIDEOSIZE_QVGA: - DBG("Setting size to QVGA\n"); - cam->params.roi.width = STV_IMAGE_QVGA_COLS; - cam->params.roi.height = STV_IMAGE_QVGA_ROWS; - cam->vw.width = STV_IMAGE_QVGA_COLS; - cam->vw.height = STV_IMAGE_QVGA_ROWS; - break; - case VIDEOSIZE_288_216: - cam->params.roi.width = 288; - cam->params.roi.height = 216; - cam->vw.width = 288; - cam->vw.height = 216; - break; - case VIDEOSIZE_256_192: - cam->vw.width = 256; - cam->vw.height = 192; - cam->params.roi.width = 256; - cam->params.roi.height = 192; - break; - case VIDEOSIZE_224_168: - cam->vw.width = 224; - cam->vw.height = 168; - cam->params.roi.width = 224; - cam->params.roi.height = 168; - break; - case VIDEOSIZE_192_144: - cam->vw.width = 192; - cam->vw.height = 144; - cam->params.roi.width = 192; - cam->params.roi.height = 144; - break; - case VIDEOSIZE_QCIF: - DBG("Setting size to QCIF\n"); - cam->params.roi.width = STV_IMAGE_QCIF_COLS; - cam->params.roi.height = STV_IMAGE_QCIF_ROWS; - cam->vw.width = STV_IMAGE_QCIF_COLS; - cam->vw.height = STV_IMAGE_QCIF_ROWS; - break; - default: - retval = -EINVAL; - } - return retval; -} - -/****************************************************************************** - * - * configure_sensor - * - *****************************************************************************/ -static int configure_sensor(struct camera_data *cam, - int req_width, int req_height) -{ - int retval; - - switch (cam->params.version.sensor_flags) { - case CPIA2_VP_SENSOR_FLAGS_404: - case CPIA2_VP_SENSOR_FLAGS_407: - case CPIA2_VP_SENSOR_FLAGS_409: - case CPIA2_VP_SENSOR_FLAGS_410: - retval = config_sensor_410(cam, req_width, req_height); - break; - case CPIA2_VP_SENSOR_FLAGS_500: - retval = config_sensor_500(cam, req_width, req_height); - break; - default: - return -EINVAL; - } - - return retval; -} - -/****************************************************************************** - * - * config_sensor_410 - * - *****************************************************************************/ -static int config_sensor_410(struct camera_data *cam, - int req_width, int req_height) -{ - struct cpia2_command cmd; - int i = 0; - int image_size; - int image_type; - int width = req_width; - int height = req_height; - - /*** - * Make sure size doesn't exceed CIF. - ***/ - if (width > STV_IMAGE_CIF_COLS) - width = STV_IMAGE_CIF_COLS; - if (height > STV_IMAGE_CIF_ROWS) - height = STV_IMAGE_CIF_ROWS; - - image_size = cpia2_match_video_size(width, height); - - DBG("Config 410: width = %d, height = %d\n", width, height); - DBG("Image size returned is %d\n", image_size); - if (image_size >= 0) { - set_vw_size(cam, image_size); - width = cam->params.roi.width; - height = cam->params.roi.height; - - DBG("After set_vw_size(), width = %d, height = %d\n", - width, height); - if (width <= 176 && height <= 144) { - DBG("image type = VIDEOSIZE_QCIF\n"); - image_type = VIDEOSIZE_QCIF; - } - else if (width <= 320 && height <= 240) { - DBG("image type = VIDEOSIZE_QVGA\n"); - image_type = VIDEOSIZE_QVGA; - } - else { - DBG("image type = VIDEOSIZE_CIF\n"); - image_type = VIDEOSIZE_CIF; - } - } else { - ERR("ConfigSensor410 failed\n"); - return -EINVAL; - } - - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; - cmd.direction = TRANSFER_WRITE; - - /* VC Format */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT; - if (image_type == VIDEOSIZE_CIF) { - cmd.buffer.registers[i++].value = - (u8) (CPIA2_VC_VC_FORMAT_UFIRST | - CPIA2_VC_VC_FORMAT_SHORTLINE); - } else { - cmd.buffer.registers[i++].value = - (u8) CPIA2_VC_VC_FORMAT_UFIRST; - } - - /* VC Clocks */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS; - if (image_type == VIDEOSIZE_QCIF) { - if (cam->params.pnp_id.device_type == DEVICE_STV_672) { - cmd.buffer.registers[i++].value= - (u8)(CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 | - CPIA2_VC_VC_672_CLOCKS_SCALING | - CPIA2_VC_VC_CLOCKS_LOGDIV2); - DBG("VC_Clocks (0xc4) should be B\n"); - } - else { - cmd.buffer.registers[i++].value= - (u8)(CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 | - CPIA2_VC_VC_CLOCKS_LOGDIV2); - } - } else { - if (cam->params.pnp_id.device_type == DEVICE_STV_672) { - cmd.buffer.registers[i++].value = - (u8) (CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 | - CPIA2_VC_VC_CLOCKS_LOGDIV0); - } - else { - cmd.buffer.registers[i++].value = - (u8) (CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 | - CPIA2_VC_VC_676_CLOCKS_SCALING | - CPIA2_VC_VC_CLOCKS_LOGDIV0); - } - } - DBG("VC_Clocks (0xc4) = 0x%0X\n", cmd.buffer.registers[i-1].value); - - /* Input reqWidth from VC */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = - (u8) (STV_IMAGE_QCIF_COLS / 4); - else - cmd.buffer.registers[i++].value = - (u8) (STV_IMAGE_CIF_COLS / 4); - - /* Timings */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 0; - else - cmd.buffer.registers[i++].value = (u8) 1; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 208; - else - cmd.buffer.registers[i++].value = (u8) 160; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 0; - else - cmd.buffer.registers[i++].value = (u8) 1; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 160; - else - cmd.buffer.registers[i++].value = (u8) 64; - - /* Output Image Size */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE; - cmd.buffer.registers[i++].value = cam->params.roi.width / 4; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE; - cmd.buffer.registers[i++].value = cam->params.roi.height / 4; - - /* Cropping */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2); - else - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2); - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2); - else - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2); - - /* Scaling registers (defaults) */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE; - cmd.buffer.registers[i++].value = (u8) 0; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE; - cmd.buffer.registers[i++].value = (u8) 0; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN; - cmd.buffer.registers[i++].value = (u8) 31; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN; - cmd.buffer.registers[i++].value = (u8) 31; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP; - cmd.buffer.registers[i++].value = (u8) 0; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP; - cmd.buffer.registers[i++].value = (u8) 0; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT; - cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */ - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT; - cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */ - - cmd.reg_count = i; - - cpia2_send_command(cam, &cmd); - - return i; -} - - -/****************************************************************************** - * - * config_sensor_500(cam) - * - *****************************************************************************/ -static int config_sensor_500(struct camera_data *cam, - int req_width, int req_height) -{ - struct cpia2_command cmd; - int i = 0; - int image_size = VIDEOSIZE_CIF; - int image_type = VIDEOSIZE_VGA; - int width = req_width; - int height = req_height; - unsigned int device = cam->params.pnp_id.device_type; - - image_size = cpia2_match_video_size(width, height); - - if (width > STV_IMAGE_CIF_COLS || height > STV_IMAGE_CIF_ROWS) - image_type = VIDEOSIZE_VGA; - else if (width > STV_IMAGE_QVGA_COLS || height > STV_IMAGE_QVGA_ROWS) - image_type = VIDEOSIZE_CIF; - else if (width > STV_IMAGE_QCIF_COLS || height > STV_IMAGE_QCIF_ROWS) - image_type = VIDEOSIZE_QVGA; - else - image_type = VIDEOSIZE_QCIF; - - if (image_size >= 0) { - set_vw_size(cam, image_size); - width = cam->params.roi.width; - height = cam->params.roi.height; - } else { - ERR("ConfigSensor500 failed\n"); - return -EINVAL; - } - - DBG("image_size = %d, width = %d, height = %d, type = %d\n", - image_size, width, height, image_type); - - cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC; - cmd.direction = TRANSFER_WRITE; - i = 0; - - /* VC Format */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT; - cmd.buffer.registers[i].value = (u8) CPIA2_VC_VC_FORMAT_UFIRST; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i].value |= (u8) CPIA2_VC_VC_FORMAT_DECIMATING; - i++; - - /* VC Clocks */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS; - if (device == DEVICE_STV_672) { - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i].value = - (u8)CPIA2_VC_VC_CLOCKS_LOGDIV1; - else - cmd.buffer.registers[i].value = - (u8)(CPIA2_VC_VC_672_CLOCKS_SCALING | - CPIA2_VC_VC_CLOCKS_LOGDIV3); - } else { - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i].value = - (u8)CPIA2_VC_VC_CLOCKS_LOGDIV0; - else - cmd.buffer.registers[i].value = - (u8)(CPIA2_VC_VC_676_CLOCKS_SCALING | - CPIA2_VC_VC_CLOCKS_LOGDIV2); - } - i++; - - DBG("VC_CLOCKS = 0x%X\n", cmd.buffer.registers[i-1].value); - - /* Input width from VP */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO; - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i].value = - (u8) (STV_IMAGE_VGA_COLS / 4); - else - cmd.buffer.registers[i].value = - (u8) (STV_IMAGE_QVGA_COLS / 4); - i++; - DBG("Input width = %d\n", cmd.buffer.registers[i-1].value); - - /* Timings */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI; - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i++].value = (u8) 2; - else - cmd.buffer.registers[i++].value = (u8) 1; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO; - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i++].value = (u8) 250; - else if (image_type == VIDEOSIZE_QVGA) - cmd.buffer.registers[i++].value = (u8) 125; - else - cmd.buffer.registers[i++].value = (u8) 160; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI; - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i++].value = (u8) 2; - else - cmd.buffer.registers[i++].value = (u8) 1; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO; - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i++].value = (u8) 12; - else if (image_type == VIDEOSIZE_QVGA) - cmd.buffer.registers[i++].value = (u8) 64; - else - cmd.buffer.registers[i++].value = (u8) 6; - - /* Output Image Size */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = STV_IMAGE_CIF_COLS / 4; - else - cmd.buffer.registers[i++].value = width / 4; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE; - if (image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = STV_IMAGE_CIF_ROWS / 4; - else - cmd.buffer.registers[i++].value = height / 4; - - /* Cropping */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP; - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_VGA_COLS / 4) - (width / 4)) / 2); - else if (image_type == VIDEOSIZE_QVGA) - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_QVGA_COLS / 4) - (width / 4)) / 2); - else if (image_type == VIDEOSIZE_CIF) - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2); - else /*if (image_type == VIDEOSIZE_QCIF)*/ - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2); - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP; - if (image_type == VIDEOSIZE_VGA) - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_VGA_ROWS / 4) - (height / 4)) / 2); - else if (image_type == VIDEOSIZE_QVGA) - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_QVGA_ROWS / 4) - (height / 4)) / 2); - else if (image_type == VIDEOSIZE_CIF) - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2); - else /*if (image_type == VIDEOSIZE_QCIF)*/ - cmd.buffer.registers[i++].value = - (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2); - - /* Scaling registers (defaults) */ - cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE; - if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 36; - else - cmd.buffer.registers[i++].value = (u8) 0; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE; - if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 32; - else - cmd.buffer.registers[i++].value = (u8) 0; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN; - if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 26; - else - cmd.buffer.registers[i++].value = (u8) 31; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN; - if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 21; - else - cmd.buffer.registers[i++].value = (u8) 31; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP; - cmd.buffer.registers[i++].value = (u8) 0; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP; - cmd.buffer.registers[i++].value = (u8) 0; - - cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT; - if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 0x2B; /* 2/11 */ - else - cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */ - - cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT; - if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF) - cmd.buffer.registers[i++].value = (u8) 0x13; /* 1/3 */ - else - cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */ - - cmd.reg_count = i; - - cpia2_send_command(cam, &cmd); - - return i; -} - - -/****************************************************************************** - * - * setallproperties - * - * This sets all user changeable properties to the values in cam->params. - *****************************************************************************/ -int set_all_properties(struct camera_data *cam) -{ - /** - * Don't set target_kb here, it will be set later. - * framerate and user_mode were already set (set_default_user_mode). - **/ - - cpia2_set_color_params(cam); - - cpia2_usb_change_streaming_alternate(cam, - cam->params.camera_state.stream_mode); - - cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, - cam->params.vp_params.user_effects); - - cpia2_set_flicker_mode(cam, - cam->params.flicker_control.flicker_mode_req); - - cpia2_do_command(cam, - CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, - TRANSFER_WRITE, cam->params.vp_params.gpio_direction); - cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE, - cam->params.vp_params.gpio_data); - - wake_system(cam); - - set_lowlight_boost(cam); - - return 0; -} - -/****************************************************************************** - * - * cpia2_save_camera_state - * - *****************************************************************************/ -void cpia2_save_camera_state(struct camera_data *cam) -{ - get_color_params(cam); - cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); - cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ, - 0); - cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DATA, TRANSFER_READ, 0); - /* Don't get framerate or target_kb. Trust the values we already have */ -} - -/****************************************************************************** - * - * get_color_params - * - *****************************************************************************/ -void get_color_params(struct camera_data *cam) -{ - cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0); - cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0); - cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, TRANSFER_READ, 0); -} - -/****************************************************************************** - * - * cpia2_set_color_params - * - *****************************************************************************/ -void cpia2_set_color_params(struct camera_data *cam) -{ - DBG("Setting color params\n"); - cpia2_set_brightness(cam, cam->params.color_params.brightness); - cpia2_set_contrast(cam, cam->params.color_params.contrast); - cpia2_set_saturation(cam, cam->params.color_params.saturation); -} - -/****************************************************************************** - * - * cpia2_set_flicker_mode - * - *****************************************************************************/ -int cpia2_set_flicker_mode(struct camera_data *cam, int mode) -{ - unsigned char cam_reg; - int err = 0; - - if(cam->params.pnp_id.device_type != DEVICE_STV_672) - return -EINVAL; - - /* Set the appropriate bits in FLICKER_MODES, preserving the rest */ - if((err = cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES, - TRANSFER_READ, 0))) - return err; - cam_reg = cam->params.flicker_control.cam_register; - - switch(mode) { - case NEVER_FLICKER: - cam_reg |= CPIA2_VP_FLICKER_MODES_NEVER_FLICKER; - cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ; - break; - case FLICKER_60: - cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER; - cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ; - break; - case FLICKER_50: - cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER; - cam_reg |= CPIA2_VP_FLICKER_MODES_50HZ; - break; - default: - return -EINVAL; - } - - if((err = cpia2_do_command(cam, CPIA2_CMD_SET_FLICKER_MODES, - TRANSFER_WRITE, cam_reg))) - return err; - - /* Set the appropriate bits in EXP_MODES, preserving the rest */ - if((err = cpia2_do_command(cam, CPIA2_CMD_GET_VP_EXP_MODES, - TRANSFER_READ, 0))) - return err; - cam_reg = cam->params.vp_params.exposure_modes; - - if (mode == NEVER_FLICKER) { - cam_reg |= CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER; - } else { - cam_reg &= ~CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER; - } - - if((err = cpia2_do_command(cam, CPIA2_CMD_SET_VP_EXP_MODES, - TRANSFER_WRITE, cam_reg))) - return err; - - if((err = cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4, - TRANSFER_WRITE, 1))) - return err; - - switch(mode) { - case NEVER_FLICKER: - cam->params.flicker_control.flicker_mode_req = mode; - break; - case FLICKER_60: - cam->params.flicker_control.flicker_mode_req = mode; - cam->params.flicker_control.mains_frequency = 60; - break; - case FLICKER_50: - cam->params.flicker_control.flicker_mode_req = mode; - cam->params.flicker_control.mains_frequency = 50; - break; - default: - err = -EINVAL; - } - - return err; -} - -/****************************************************************************** - * - * cpia2_set_property_flip - * - *****************************************************************************/ -void cpia2_set_property_flip(struct camera_data *cam, int prop_val) -{ - unsigned char cam_reg; - - cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); - cam_reg = cam->params.vp_params.user_effects; - - if (prop_val) - { - cam_reg |= CPIA2_VP_USER_EFFECTS_FLIP; - } - else - { - cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP; - } - cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, - cam_reg); -} - -/****************************************************************************** - * - * cpia2_set_property_mirror - * - *****************************************************************************/ -void cpia2_set_property_mirror(struct camera_data *cam, int prop_val) -{ - unsigned char cam_reg; - - cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); - cam_reg = cam->params.vp_params.user_effects; - - if (prop_val) - { - cam_reg |= CPIA2_VP_USER_EFFECTS_MIRROR; - } - else - { - cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR; - } - cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, - cam_reg); -} - -/****************************************************************************** - * - * set_target_kb - * - * The new Target KB is set in cam->params.vc_params.target_kb and - * activates on reset. - *****************************************************************************/ - -int cpia2_set_target_kb(struct camera_data *cam, unsigned char value) -{ - DBG("Requested target_kb = %d\n", value); - if (value != cam->params.vc_params.target_kb) { - - cpia2_usb_stream_pause(cam); - - /* reset camera for new target_kb */ - cam->params.vc_params.target_kb = value; - cpia2_reset_camera(cam); - - cpia2_usb_stream_resume(cam); - } - - return 0; -} - -/****************************************************************************** - * - * cpia2_set_gpio - * - *****************************************************************************/ -int cpia2_set_gpio(struct camera_data *cam, unsigned char setting) -{ - int ret; - - /* Set the microport direction (register 0x90, should be defined - * already) to 1 (user output), and set the microport data (0x91) to - * the value in the ioctl argument. - */ - - ret = cpia2_do_command(cam, - CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, - CPIA2_VC_MP_DIR_OUTPUT, - 255); - if (ret < 0) - return ret; - cam->params.vp_params.gpio_direction = 255; - - ret = cpia2_do_command(cam, - CPIA2_CMD_SET_VC_MP_GPIO_DATA, - CPIA2_VC_MP_DIR_OUTPUT, - setting); - if (ret < 0) - return ret; - cam->params.vp_params.gpio_data = setting; - - return 0; -} - -/****************************************************************************** - * - * cpia2_set_fps - * - *****************************************************************************/ -int cpia2_set_fps(struct camera_data *cam, int framerate) -{ - int retval; - - switch(framerate) { - case CPIA2_VP_FRAMERATE_30: - case CPIA2_VP_FRAMERATE_25: - if(cam->params.pnp_id.device_type == DEVICE_STV_672 && - cam->params.version.sensor_flags == - CPIA2_VP_SENSOR_FLAGS_500) { - return -EINVAL; - } - /* Fall through */ - case CPIA2_VP_FRAMERATE_15: - case CPIA2_VP_FRAMERATE_12_5: - case CPIA2_VP_FRAMERATE_7_5: - case CPIA2_VP_FRAMERATE_6_25: - break; - default: - return -EINVAL; - } - - if (cam->params.pnp_id.device_type == DEVICE_STV_672 && - framerate == CPIA2_VP_FRAMERATE_15) - framerate = 0; /* Work around bug in VP4 */ - - retval = cpia2_do_command(cam, - CPIA2_CMD_FRAMERATE_REQ, - TRANSFER_WRITE, - framerate); - - if(retval == 0) - cam->params.vp_params.frame_rate = framerate; - - return retval; -} - -/****************************************************************************** - * - * cpia2_set_brightness - * - *****************************************************************************/ -void cpia2_set_brightness(struct camera_data *cam, unsigned char value) -{ - /*** - * Don't let the register be set to zero - bug in VP4 - flash of full - * brightness - ***/ - if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0) - value++; - DBG("Setting brightness to %d (0x%0x)\n", value, value); - cpia2_do_command(cam,CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE,value); -} - -/****************************************************************************** - * - * cpia2_set_contrast - * - *****************************************************************************/ -void cpia2_set_contrast(struct camera_data *cam, unsigned char value) -{ - DBG("Setting contrast to %d (0x%0x)\n", value, value); - cam->params.color_params.contrast = value; - cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value); -} - -/****************************************************************************** - * - * cpia2_set_saturation - * - *****************************************************************************/ -void cpia2_set_saturation(struct camera_data *cam, unsigned char value) -{ - DBG("Setting saturation to %d (0x%0x)\n", value, value); - cam->params.color_params.saturation = value; - cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value); -} - -/****************************************************************************** - * - * wake_system - * - *****************************************************************************/ -void wake_system(struct camera_data *cam) -{ - cpia2_do_command(cam, CPIA2_CMD_SET_WAKEUP, TRANSFER_WRITE, 0); -} - -/****************************************************************************** - * - * set_lowlight_boost - * - * Valid for STV500 sensor only - *****************************************************************************/ -void set_lowlight_boost(struct camera_data *cam) -{ - struct cpia2_command cmd; - - if (cam->params.pnp_id.device_type != DEVICE_STV_672 || - cam->params.version.sensor_flags != CPIA2_VP_SENSOR_FLAGS_500) - return; - - cmd.direction = TRANSFER_WRITE; - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 3; - cmd.start = CPIA2_VP_RAM_ADDR_H; - - cmd.buffer.block_data[0] = 0; /* High byte of address to write to */ - cmd.buffer.block_data[1] = 0x59; /* Low byte of address to write to */ - cmd.buffer.block_data[2] = 0; /* High byte of data to write */ - - cpia2_send_command(cam, &cmd); - - if (cam->params.vp_params.lowlight_boost) { - cmd.buffer.block_data[0] = 0x02; /* Low byte data to write */ - } else { - cmd.buffer.block_data[0] = 0x06; - } - cmd.start = CPIA2_VP_RAM_DATA; - cmd.reg_count = 1; - cpia2_send_command(cam, &cmd); - - /* Rehash the VP4 values */ - cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4, TRANSFER_WRITE, 1); -} - -/****************************************************************************** - * - * cpia2_set_format - * - * Assumes that new size is already set in param struct. - *****************************************************************************/ -void cpia2_set_format(struct camera_data *cam) -{ - cam->flush = true; - - cpia2_usb_stream_pause(cam); - - /* reset camera to new size */ - cpia2_set_low_power(cam); - cpia2_reset_camera(cam); - cam->flush = false; - - cpia2_dbg_dump_registers(cam); - - cpia2_usb_stream_resume(cam); -} - -/****************************************************************************** - * - * cpia2_dbg_dump_registers - * - *****************************************************************************/ -void cpia2_dbg_dump_registers(struct camera_data *cam) -{ -#ifdef _CPIA2_DEBUG_ - struct cpia2_command cmd; - - if (!(debugs_on & DEBUG_DUMP_REGS)) - return; - - cmd.direction = TRANSFER_READ; - - /* Start with bank 0 (SYSTEM) */ - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM; - cmd.reg_count = 3; - cmd.start = 0; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "System Device Hi = 0x%X\n", - cmd.buffer.block_data[0]); - printk(KERN_DEBUG "System Device Lo = 0x%X\n", - cmd.buffer.block_data[1]); - printk(KERN_DEBUG "System_system control = 0x%X\n", - cmd.buffer.block_data[2]); - - /* Bank 1 (VC) */ - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.reg_count = 4; - cmd.start = 0x80; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "ASIC_ID = 0x%X\n", - cmd.buffer.block_data[0]); - printk(KERN_DEBUG "ASIC_REV = 0x%X\n", - cmd.buffer.block_data[1]); - printk(KERN_DEBUG "PW_CONTRL = 0x%X\n", - cmd.buffer.block_data[2]); - printk(KERN_DEBUG "WAKEUP = 0x%X\n", - cmd.buffer.block_data[3]); - - cmd.start = 0xA0; /* ST_CTRL */ - cmd.reg_count = 1; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "Stream ctrl = 0x%X\n", - cmd.buffer.block_data[0]); - - cmd.start = 0xA4; /* Stream status */ - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "Stream status = 0x%X\n", - cmd.buffer.block_data[0]); - - cmd.start = 0xA8; /* USB status */ - cmd.reg_count = 3; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "USB_CTRL = 0x%X\n", - cmd.buffer.block_data[0]); - printk(KERN_DEBUG "USB_STRM = 0x%X\n", - cmd.buffer.block_data[1]); - printk(KERN_DEBUG "USB_STATUS = 0x%X\n", - cmd.buffer.block_data[2]); - - cmd.start = 0xAF; /* USB settings */ - cmd.reg_count = 1; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "USB settings = 0x%X\n", - cmd.buffer.block_data[0]); - - cmd.start = 0xC0; /* VC stuff */ - cmd.reg_count = 26; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "VC Control = 0x%0X\n", - cmd.buffer.block_data[0]); - printk(KERN_DEBUG "VC Format = 0x%0X\n", - cmd.buffer.block_data[3]); - printk(KERN_DEBUG "VC Clocks = 0x%0X\n", - cmd.buffer.block_data[4]); - printk(KERN_DEBUG "VC IHSize = 0x%0X\n", - cmd.buffer.block_data[5]); - printk(KERN_DEBUG "VC Xlim Hi = 0x%0X\n", - cmd.buffer.block_data[6]); - printk(KERN_DEBUG "VC XLim Lo = 0x%0X\n", - cmd.buffer.block_data[7]); - printk(KERN_DEBUG "VC YLim Hi = 0x%0X\n", - cmd.buffer.block_data[8]); - printk(KERN_DEBUG "VC YLim Lo = 0x%0X\n", - cmd.buffer.block_data[9]); - printk(KERN_DEBUG "VC OHSize = 0x%0X\n", - cmd.buffer.block_data[10]); - printk(KERN_DEBUG "VC OVSize = 0x%0X\n", - cmd.buffer.block_data[11]); - printk(KERN_DEBUG "VC HCrop = 0x%0X\n", - cmd.buffer.block_data[12]); - printk(KERN_DEBUG "VC VCrop = 0x%0X\n", - cmd.buffer.block_data[13]); - printk(KERN_DEBUG "VC HPhase = 0x%0X\n", - cmd.buffer.block_data[14]); - printk(KERN_DEBUG "VC VPhase = 0x%0X\n", - cmd.buffer.block_data[15]); - printk(KERN_DEBUG "VC HIspan = 0x%0X\n", - cmd.buffer.block_data[16]); - printk(KERN_DEBUG "VC VIspan = 0x%0X\n", - cmd.buffer.block_data[17]); - printk(KERN_DEBUG "VC HiCrop = 0x%0X\n", - cmd.buffer.block_data[18]); - printk(KERN_DEBUG "VC ViCrop = 0x%0X\n", - cmd.buffer.block_data[19]); - printk(KERN_DEBUG "VC HiFract = 0x%0X\n", - cmd.buffer.block_data[20]); - printk(KERN_DEBUG "VC ViFract = 0x%0X\n", - cmd.buffer.block_data[21]); - printk(KERN_DEBUG "VC JPeg Opt = 0x%0X\n", - cmd.buffer.block_data[22]); - printk(KERN_DEBUG "VC Creep Per = 0x%0X\n", - cmd.buffer.block_data[23]); - printk(KERN_DEBUG "VC User Sq. = 0x%0X\n", - cmd.buffer.block_data[24]); - printk(KERN_DEBUG "VC Target KB = 0x%0X\n", - cmd.buffer.block_data[25]); - - /*** VP ***/ - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP; - cmd.reg_count = 14; - cmd.start = 0; - cpia2_send_command(cam, &cmd); - - printk(KERN_DEBUG "VP Dev Hi = 0x%0X\n", - cmd.buffer.block_data[0]); - printk(KERN_DEBUG "VP Dev Lo = 0x%0X\n", - cmd.buffer.block_data[1]); - printk(KERN_DEBUG "VP Sys State = 0x%0X\n", - cmd.buffer.block_data[2]); - printk(KERN_DEBUG "VP Sys Ctrl = 0x%0X\n", - cmd.buffer.block_data[3]); - printk(KERN_DEBUG "VP Sensor flg = 0x%0X\n", - cmd.buffer.block_data[5]); - printk(KERN_DEBUG "VP Sensor Rev = 0x%0X\n", - cmd.buffer.block_data[6]); - printk(KERN_DEBUG "VP Dev Config = 0x%0X\n", - cmd.buffer.block_data[7]); - printk(KERN_DEBUG "VP GPIO_DIR = 0x%0X\n", - cmd.buffer.block_data[8]); - printk(KERN_DEBUG "VP GPIO_DATA = 0x%0X\n", - cmd.buffer.block_data[9]); - printk(KERN_DEBUG "VP Ram ADDR H = 0x%0X\n", - cmd.buffer.block_data[10]); - printk(KERN_DEBUG "VP Ram ADDR L = 0x%0X\n", - cmd.buffer.block_data[11]); - printk(KERN_DEBUG "VP RAM Data = 0x%0X\n", - cmd.buffer.block_data[12]); - printk(KERN_DEBUG "Do Call = 0x%0X\n", - cmd.buffer.block_data[13]); - - if (cam->params.pnp_id.device_type == DEVICE_STV_672) { - cmd.reg_count = 9; - cmd.start = 0x0E; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n", - cmd.buffer.block_data[0]); - printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n", - cmd.buffer.block_data[1]); - printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n", - cmd.buffer.block_data[2]); - printk(KERN_DEBUG "VP Framerate = 0x%0X\n", - cmd.buffer.block_data[3]); - printk(KERN_DEBUG "VP UserEffect = 0x%0X\n", - cmd.buffer.block_data[4]); - printk(KERN_DEBUG "VP White Bal = 0x%0X\n", - cmd.buffer.block_data[5]); - printk(KERN_DEBUG "VP WB thresh = 0x%0X\n", - cmd.buffer.block_data[6]); - printk(KERN_DEBUG "VP Exp Modes = 0x%0X\n", - cmd.buffer.block_data[7]); - printk(KERN_DEBUG "VP Exp Target = 0x%0X\n", - cmd.buffer.block_data[8]); - - cmd.reg_count = 1; - cmd.start = 0x1B; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "VP FlickerMds = 0x%0X\n", - cmd.buffer.block_data[0]); - } else { - cmd.reg_count = 8 ; - cmd.start = 0x0E; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n", - cmd.buffer.block_data[0]); - printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n", - cmd.buffer.block_data[1]); - printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n", - cmd.buffer.block_data[5]); - printk(KERN_DEBUG "VP Framerate = 0x%0X\n", - cmd.buffer.block_data[6]); - printk(KERN_DEBUG "VP UserEffect = 0x%0X\n", - cmd.buffer.block_data[7]); - - cmd.reg_count = 1; - cmd.start = CPIA2_VP5_EXPOSURE_TARGET; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "VP5 Exp Target= 0x%0X\n", - cmd.buffer.block_data[0]); - - cmd.reg_count = 4; - cmd.start = 0x3A; - cpia2_send_command(cam, &cmd); - printk(KERN_DEBUG "VP5 MY Black = 0x%0X\n", - cmd.buffer.block_data[0]); - printk(KERN_DEBUG "VP5 MCY Range = 0x%0X\n", - cmd.buffer.block_data[1]); - printk(KERN_DEBUG "VP5 MYCEILING = 0x%0X\n", - cmd.buffer.block_data[2]); - printk(KERN_DEBUG "VP5 MCUV Sat = 0x%0X\n", - cmd.buffer.block_data[3]); - } -#endif -} - -/****************************************************************************** - * - * reset_camera_struct - * - * Sets all values to the defaults - *****************************************************************************/ -void reset_camera_struct(struct camera_data *cam) -{ - /*** - * The following parameter values are the defaults from the register map. - ***/ - cam->params.color_params.brightness = DEFAULT_BRIGHTNESS; - cam->params.color_params.contrast = DEFAULT_CONTRAST; - cam->params.color_params.saturation = DEFAULT_SATURATION; - cam->params.vp_params.lowlight_boost = 0; - - /* FlickerModes */ - cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER; - cam->params.flicker_control.mains_frequency = 60; - - /* jpeg params */ - cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT; - cam->params.compression.creep_period = 2; - cam->params.compression.user_squeeze = 20; - cam->params.compression.inhibit_htables = false; - - /* gpio params */ - cam->params.vp_params.gpio_direction = 0; /* write, the default safe mode */ - cam->params.vp_params.gpio_data = 0; - - /* Target kb params */ - cam->params.vc_params.target_kb = DEFAULT_TARGET_KB; - - /*** - * Set Sensor FPS as fast as possible. - ***/ - if(cam->params.pnp_id.device_type == DEVICE_STV_672) { - if(cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) - cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_15; - else - cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30; - } else { - cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30; - } - - /*** - * Set default video mode as large as possible : - * for vga sensor set to vga, for cif sensor set to CIF. - ***/ - if (cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) { - cam->sensor_type = CPIA2_SENSOR_500; - cam->video_size = VIDEOSIZE_VGA; - cam->params.roi.width = STV_IMAGE_VGA_COLS; - cam->params.roi.height = STV_IMAGE_VGA_ROWS; - } else { - cam->sensor_type = CPIA2_SENSOR_410; - cam->video_size = VIDEOSIZE_CIF; - cam->params.roi.width = STV_IMAGE_CIF_COLS; - cam->params.roi.height = STV_IMAGE_CIF_ROWS; - } - - /*** - * Fill in the v4l structures. video_cap is filled in inside the VIDIOCCAP - * Ioctl. Here, just do the window and picture stucts. - ***/ - cam->vp.palette = (u16) VIDEO_PALETTE_RGB24; /* Is this right? */ - cam->vp.brightness = (u16) cam->params.color_params.brightness * 256; - cam->vp.colour = (u16) cam->params.color_params.saturation * 256; - cam->vp.contrast = (u16) cam->params.color_params.contrast * 256; - - cam->vw.x = 0; - cam->vw.y = 0; - cam->vw.width = cam->params.roi.width; - cam->vw.height = cam->params.roi.height; - cam->vw.flags = 0; - cam->vw.clipcount = 0; - - return; -} - -/****************************************************************************** - * - * cpia2_init_camera_struct - * - * Initializes camera struct, does not call reset to fill in defaults. - *****************************************************************************/ -struct camera_data *cpia2_init_camera_struct(void) -{ - struct camera_data *cam; - - cam = kmalloc(sizeof(*cam), GFP_KERNEL); - - if (!cam) { - ERR("couldn't kmalloc cpia2 struct\n"); - return NULL; - } - - /* Default everything to 0 */ - memset(cam, 0, sizeof(struct camera_data)); - - cam->present = 1; - mutex_init(&cam->busy_lock); - init_waitqueue_head(&cam->wq_stream); - - return cam; -} - -/****************************************************************************** - * - * cpia2_init_camera - * - * Initializes camera. - *****************************************************************************/ -int cpia2_init_camera(struct camera_data *cam) -{ - DBG("Start\n"); - - cam->mmapped = false; - - /* Get sensor and asic types before reset. */ - cpia2_set_high_power(cam); - cpia2_get_version_info(cam); - if (cam->params.version.asic_id != CPIA2_ASIC_672) { - ERR("Device IO error (asicID has incorrect value of 0x%X\n", - cam->params.version.asic_id); - return -ENODEV; - } - - /* Set GPIO direction and data to a safe state. */ - cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, - TRANSFER_WRITE, 0); - cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, - TRANSFER_WRITE, 0); - - /* resetting struct requires version info for sensor and asic types */ - reset_camera_struct(cam); - - cpia2_set_low_power(cam); - - DBG("End\n"); - - return 0; -} - -/****************************************************************************** - * - * cpia2_allocate_buffers - * - *****************************************************************************/ -int cpia2_allocate_buffers(struct camera_data *cam) -{ - int i; - - if(!cam->buffers) { - u32 size = cam->num_frames*sizeof(struct framebuf); - cam->buffers = kmalloc(size, GFP_KERNEL); - if(!cam->buffers) { - ERR("couldn't kmalloc frame buffer structures\n"); - return -ENOMEM; - } - } - - if(!cam->frame_buffer) { - cam->frame_buffer = rvmalloc(cam->frame_size*cam->num_frames); - if (!cam->frame_buffer) { - ERR("couldn't vmalloc frame buffer data area\n"); - kfree(cam->buffers); - cam->buffers = NULL; - return -ENOMEM; - } - } - - for(i=0; inum_frames-1; ++i) { - cam->buffers[i].next = &cam->buffers[i+1]; - cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size; - cam->buffers[i].status = FRAME_EMPTY; - cam->buffers[i].length = 0; - cam->buffers[i].max_length = 0; - cam->buffers[i].num = i; - } - cam->buffers[i].next = cam->buffers; - cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size; - cam->buffers[i].status = FRAME_EMPTY; - cam->buffers[i].length = 0; - cam->buffers[i].max_length = 0; - cam->buffers[i].num = i; - cam->curbuff = cam->buffers; - cam->workbuff = cam->curbuff->next; - DBG("buffers=%p, curbuff=%p, workbuff=%p\n", cam->buffers, cam->curbuff, - cam->workbuff); - return 0; -} - -/****************************************************************************** - * - * cpia2_free_buffers - * - *****************************************************************************/ -void cpia2_free_buffers(struct camera_data *cam) -{ - if(cam->buffers) { - kfree(cam->buffers); - cam->buffers = NULL; - } - if(cam->frame_buffer) { - rvfree(cam->frame_buffer, cam->frame_size*cam->num_frames); - cam->frame_buffer = NULL; - } -} - -/****************************************************************************** - * - * cpia2_read - * - *****************************************************************************/ -long cpia2_read(struct camera_data *cam, - char __user *buf, unsigned long count, int noblock) -{ - struct framebuf *frame; - if (!count) { - return 0; - } - - if (!buf) { - ERR("%s: buffer NULL\n",__FUNCTION__); - return -EINVAL; - } - - if (!cam) { - ERR("%s: Internal error, camera_data NULL!\n",__FUNCTION__); - return -EINVAL; - } - - /* make this _really_ smp and multithread-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) - return -ERESTARTSYS; - - if (!cam->present) { - LOG("%s: camera removed\n",__FUNCTION__); - mutex_unlock(&cam->busy_lock); - return 0; /* EOF */ - } - - if(!cam->streaming) { - /* Start streaming */ - cpia2_usb_stream_start(cam, - cam->params.camera_state.stream_mode); - } - - /* Copy cam->curbuff in case it changes while we're processing */ - frame = cam->curbuff; - if (noblock && frame->status != FRAME_READY) { - mutex_unlock(&cam->busy_lock); - return -EAGAIN; - } - - if(frame->status != FRAME_READY) { - mutex_unlock(&cam->busy_lock); - wait_event_interruptible(cam->wq_stream, - !cam->present || - (frame = cam->curbuff)->status == FRAME_READY); - if (signal_pending(current)) - return -ERESTARTSYS; - /* make this _really_ smp and multithread-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) { - return -ERESTARTSYS; - } - if(!cam->present) { - mutex_unlock(&cam->busy_lock); - return 0; - } - } - - /* copy data to user space */ - if (frame->length > count) { - mutex_unlock(&cam->busy_lock); - return -EFAULT; - } - if (copy_to_user(buf, frame->data, frame->length)) { - mutex_unlock(&cam->busy_lock); - return -EFAULT; - } - - count = frame->length; - - frame->status = FRAME_EMPTY; - - mutex_unlock(&cam->busy_lock); - return count; -} - -/****************************************************************************** - * - * cpia2_poll - * - *****************************************************************************/ -unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, - poll_table *wait) -{ - unsigned int status=0; - - if(!cam) { - ERR("%s: Internal error, camera_data not found!\n",__FUNCTION__); - return POLLERR; - } - - mutex_lock(&cam->busy_lock); - - if(!cam->present) { - mutex_unlock(&cam->busy_lock); - return POLLHUP; - } - - if(!cam->streaming) { - /* Start streaming */ - cpia2_usb_stream_start(cam, - cam->params.camera_state.stream_mode); - } - - mutex_unlock(&cam->busy_lock); - poll_wait(filp, &cam->wq_stream, wait); - mutex_lock(&cam->busy_lock); - - if(!cam->present) - status = POLLHUP; - else if(cam->curbuff->status == FRAME_READY) - status = POLLIN | POLLRDNORM; - - mutex_unlock(&cam->busy_lock); - return status; -} - -/****************************************************************************** - * - * cpia2_remap_buffer - * - *****************************************************************************/ -int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma) -{ - const char *adr = (const char *)vma->vm_start; - unsigned long size = vma->vm_end-vma->vm_start; - unsigned long start_offset = vma->vm_pgoff << PAGE_SHIFT; - unsigned long start = (unsigned long) adr; - unsigned long page, pos; - - if (!cam) - return -ENODEV; - - DBG("mmap offset:%ld size:%ld\n", start_offset, size); - - /* make this _really_ smp-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) - return -ERESTARTSYS; - - if (!cam->present) { - mutex_unlock(&cam->busy_lock); - return -ENODEV; - } - - if (size > cam->frame_size*cam->num_frames || - (start_offset % cam->frame_size) != 0 || - (start_offset+size > cam->frame_size*cam->num_frames)) { - mutex_unlock(&cam->busy_lock); - return -EINVAL; - } - - pos = ((unsigned long) (cam->frame_buffer)) + start_offset; - while (size > 0) { - page = kvirt_to_pa(pos); - if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) { - mutex_unlock(&cam->busy_lock); - return -EAGAIN; - } - start += PAGE_SIZE; - pos += PAGE_SIZE; - if (size > PAGE_SIZE) - size -= PAGE_SIZE; - else - size = 0; - } - - cam->mmapped = true; - mutex_unlock(&cam->busy_lock); - return 0; -} - diff --git a/drivers/media/video/cpia2/cpia2_registers.h b/drivers/media/video/cpia2/cpia2_registers.h deleted file mode 100644 index 3bbec514a..000000000 --- a/drivers/media/video/cpia2/cpia2_registers.h +++ /dev/null @@ -1,476 +0,0 @@ -/**************************************************************************** - * - * Filename: cpia2registers.h - * - * Copyright 2001, STMicrolectronics, Inc. - * - * Description: - * Definitions for the CPia2 register set - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 CPIA2_REGISTER_HEADER -#define CPIA2_REGISTER_HEADER - -/*** - * System register set (Bank 0) - ***/ -#define CPIA2_SYSTEM_DEVICE_HI 0x00 -#define CPIA2_SYSTEM_DEVICE_LO 0x01 - -#define CPIA2_SYSTEM_SYSTEM_CONTROL 0x02 -#define CPIA2_SYSTEM_CONTROL_LOW_POWER 0x00 -#define CPIA2_SYSTEM_CONTROL_HIGH_POWER 0x01 -#define CPIA2_SYSTEM_CONTROL_SUSPEND 0x02 -#define CPIA2_SYSTEM_CONTROL_V2W_ERR 0x10 -#define CPIA2_SYSTEM_CONTROL_RB_ERR 0x10 -#define CPIA2_SYSTEM_CONTROL_CLEAR_ERR 0x80 - -#define CPIA2_SYSTEM_INT_PACKET_CTRL 0x04 -#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX 0x01 -#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_EOF 0x02 -#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_INT1 0x04 - -#define CPIA2_SYSTEM_CACHE_CTRL 0x05 -#define CPIA2_SYSTEM_CACHE_CTRL_CACHE_RESET 0x01 -#define CPIA2_SYSTEM_CACHE_CTRL_CACHE_FLUSH 0x02 - -#define CPIA2_SYSTEM_SERIAL_CTRL 0x06 -#define CPIA2_SYSTEM_SERIAL_CTRL_NULL_CMD 0x00 -#define CPIA2_SYSTEM_SERIAL_CTRL_START_CMD 0x01 -#define CPIA2_SYSTEM_SERIAL_CTRL_STOP_CMD 0x02 -#define CPIA2_SYSTEM_SERIAL_CTRL_WRITE_CMD 0x03 -#define CPIA2_SYSTEM_SERIAL_CTRL_READ_ACK_CMD 0x04 -#define CPIA2_SYSTEM_SERIAL_CTRL_READ_NACK_CMD 0x05 - -#define CPIA2_SYSTEM_SERIAL_DATA 0x07 - -#define CPIA2_SYSTEM_VP_SERIAL_ADDR 0x08 - -/*** - * I2C addresses for various devices in CPiA2 - ***/ -#define CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR 0x20 -#define CPIA2_SYSTEM_VP_SERIAL_ADDR_VP 0x88 -#define CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP 0x8A - -#define CPIA2_SYSTEM_SPARE_REG1 0x09 -#define CPIA2_SYSTEM_SPARE_REG2 0x0A -#define CPIA2_SYSTEM_SPARE_REG3 0x0B - -#define CPIA2_SYSTEM_MC_PORT_0 0x0C -#define CPIA2_SYSTEM_MC_PORT_1 0x0D -#define CPIA2_SYSTEM_MC_PORT_2 0x0E -#define CPIA2_SYSTEM_MC_PORT_3 0x0F - -#define CPIA2_SYSTEM_STATUS_PKT 0x20 -#define CPIA2_SYSTEM_STATUS_PKT_END 0x27 - -#define CPIA2_SYSTEM_DESCRIP_VID_HI 0x30 -#define CPIA2_SYSTEM_DESCRIP_VID_LO 0x31 -#define CPIA2_SYSTEM_DESCRIP_PID_HI 0x32 -#define CPIA2_SYSTEM_DESCRIP_PID_LO 0x33 - -#define CPIA2_SYSTEM_FW_VERSION_HI 0x34 -#define CPIA2_SYSTEM_FW_VERSION_LO 0x35 - -#define CPIA2_SYSTEM_CACHE_START_INDEX 0x80 -#define CPIA2_SYSTEM_CACHE_MAX_WRITES 0x10 - -/*** - * VC register set (Bank 1) - ***/ -#define CPIA2_VC_ASIC_ID 0x80 - -#define CPIA2_VC_ASIC_REV 0x81 - -#define CPIA2_VC_PW_CTRL 0x82 -#define CPIA2_VC_PW_CTRL_COLDSTART 0x01 -#define CPIA2_VC_PW_CTRL_CP_CLK_EN 0x02 -#define CPIA2_VC_PW_CTRL_VP_RESET_N 0x04 -#define CPIA2_VC_PW_CTRL_VC_CLK_EN 0x08 -#define CPIA2_VC_PW_CTRL_VC_RESET_N 0x10 -#define CPIA2_VC_PW_CTRL_GOTO_SUSPEND 0x20 -#define CPIA2_VC_PW_CTRL_UDC_SUSPEND 0x40 -#define CPIA2_VC_PW_CTRL_PWR_DOWN 0x80 - -#define CPIA2_VC_WAKEUP 0x83 -#define CPIA2_VC_WAKEUP_SW_ENABLE 0x01 -#define CPIA2_VC_WAKEUP_XX_ENABLE 0x02 -#define CPIA2_VC_WAKEUP_SW_ATWAKEUP 0x04 -#define CPIA2_VC_WAKEUP_XX_ATWAKEUP 0x08 - -#define CPIA2_VC_CLOCK_CTRL 0x84 -#define CPIA2_VC_CLOCK_CTRL_TESTUP72 0x01 - -#define CPIA2_VC_INT_ENABLE 0x88 -#define CPIA2_VC_INT_ENABLE_XX_IE 0x01 -#define CPIA2_VC_INT_ENABLE_SW_IE 0x02 -#define CPIA2_VC_INT_ENABLE_VC_IE 0x04 -#define CPIA2_VC_INT_ENABLE_USBDATA_IE 0x08 -#define CPIA2_VC_INT_ENABLE_USBSETUP_IE 0x10 -#define CPIA2_VC_INT_ENABLE_USBCFG_IE 0x20 - -#define CPIA2_VC_INT_FLAG 0x89 -#define CPIA2_VC_INT_ENABLE_XX_FLAG 0x01 -#define CPIA2_VC_INT_ENABLE_SW_FLAG 0x02 -#define CPIA2_VC_INT_ENABLE_VC_FLAG 0x04 -#define CPIA2_VC_INT_ENABLE_USBDATA_FLAG 0x08 -#define CPIA2_VC_INT_ENABLE_USBSETUP_FLAG 0x10 -#define CPIA2_VC_INT_ENABLE_USBCFG_FLAG 0x20 -#define CPIA2_VC_INT_ENABLE_SET_RESET_BIT 0x80 - -#define CPIA2_VC_INT_STATE 0x8A -#define CPIA2_VC_INT_STATE_XX_STATE 0x01 -#define CPIA2_VC_INT_STATE_SW_STATE 0x02 - -#define CPIA2_VC_MP_DIR 0x90 -#define CPIA2_VC_MP_DIR_INPUT 0x00 -#define CPIA2_VC_MP_DIR_OUTPUT 0x01 - -#define CPIA2_VC_MP_DATA 0x91 - -#define CPIA2_VC_DP_CTRL 0x98 -#define CPIA2_VC_DP_CTRL_MODE_0 0x00 -#define CPIA2_VC_DP_CTRL_MODE_A 0x01 -#define CPIA2_VC_DP_CTRL_MODE_B 0x02 -#define CPIA2_VC_DP_CTRL_MODE_C 0x03 -#define CPIA2_VC_DP_CTRL_FAKE_FST 0x04 - -#define CPIA2_VC_AD_CTRL 0x99 -#define CPIA2_VC_AD_CTRL_SRC_0 0x00 -#define CPIA2_VC_AD_CTRL_SRC_DIGI_A 0x01 -#define CPIA2_VC_AD_CTRL_SRC_REG 0x02 -#define CPIA2_VC_AD_CTRL_DST_USB 0x00 -#define CPIA2_VC_AD_CTRL_DST_REG 0x04 - -#define CPIA2_VC_AD_TEST_IN 0x9B - -#define CPIA2_VC_AD_TEST_OUT 0x9C - -#define CPIA2_VC_AD_STATUS 0x9D -#define CPIA2_VC_AD_STATUS_EMPTY 0x01 -#define CPIA2_VC_AD_STATUS_FULL 0x02 - -#define CPIA2_VC_DP_DATA 0x9E - -#define CPIA2_VC_ST_CTRL 0xA0 -#define CPIA2_VC_ST_CTRL_SRC_VC 0x00 -#define CPIA2_VC_ST_CTRL_SRC_DP 0x01 -#define CPIA2_VC_ST_CTRL_SRC_REG 0x02 - -#define CPIA2_VC_ST_CTRL_RAW_SELECT 0x04 - -#define CPIA2_VC_ST_CTRL_DST_USB 0x00 -#define CPIA2_VC_ST_CTRL_DST_DP 0x08 -#define CPIA2_VC_ST_CTRL_DST_REG 0x10 - -#define CPIA2_VC_ST_CTRL_FIFO_ENABLE 0x20 -#define CPIA2_VC_ST_CTRL_EOF_DETECT 0x40 - -#define CPIA2_VC_ST_TEST 0xA1 -#define CPIA2_VC_ST_TEST_MODE_MANUAL 0x00 -#define CPIA2_VC_ST_TEST_MODE_INCREMENT 0x02 - -#define CPIA2_VC_ST_TEST_AUTO_FILL 0x08 - -#define CPIA2_VC_ST_TEST_REPEAT_FIFO 0x10 - -#define CPIA2_VC_ST_TEST_IN 0xA2 - -#define CPIA2_VC_ST_TEST_OUT 0xA3 - -#define CPIA2_VC_ST_STATUS 0xA4 -#define CPIA2_VC_ST_STATUS_EMPTY 0x01 -#define CPIA2_VC_ST_STATUS_FULL 0x02 - -#define CPIA2_VC_ST_FRAME_DETECT_1 0xA5 - -#define CPIA2_VC_ST_FRAME_DETECT_2 0xA6 - -#define CPIA2_VC_USB_CTRL 0xA8 -#define CPIA2_VC_USB_CTRL_CMD_STALLED 0x01 -#define CPIA2_VC_USB_CTRL_CMD_READY 0x02 -#define CPIA2_VC_USB_CTRL_CMD_STATUS 0x04 -#define CPIA2_VC_USB_CTRL_CMD_STATUS_DIR 0x08 -#define CPIA2_VC_USB_CTRL_CMD_NO_CLASH 0x10 -#define CPIA2_VC_USB_CTRL_CMD_MICRO_ACCESS 0x80 - -#define CPIA2_VC_USB_STRM 0xA9 -#define CPIA2_VC_USB_STRM_ISO_ENABLE 0x01 -#define CPIA2_VC_USB_STRM_BLK_ENABLE 0x02 -#define CPIA2_VC_USB_STRM_INT_ENABLE 0x04 -#define CPIA2_VC_USB_STRM_AUD_ENABLE 0x08 - -#define CPIA2_VC_USB_STATUS 0xAA -#define CPIA2_VC_USB_STATUS_CMD_IN_PROGRESS 0x01 -#define CPIA2_VC_USB_STATUS_CMD_STATUS_STALL 0x02 -#define CPIA2_VC_USB_STATUS_CMD_HANDSHAKE 0x04 -#define CPIA2_VC_USB_STATUS_CMD_OVERRIDE 0x08 -#define CPIA2_VC_USB_STATUS_CMD_FIFO_BUSY 0x10 -#define CPIA2_VC_USB_STATUS_BULK_REPEAT_TXN 0x20 -#define CPIA2_VC_USB_STATUS_CONFIG_DONE 0x40 -#define CPIA2_VC_USB_STATUS_USB_SUSPEND 0x80 - -#define CPIA2_VC_USB_CMDW 0xAB - -#define CPIA2_VC_USB_DATARW 0xAC - -#define CPIA2_VC_USB_INFO 0xAD - -#define CPIA2_VC_USB_CONFIG 0xAE - -#define CPIA2_VC_USB_SETTINGS 0xAF -#define CPIA2_VC_USB_SETTINGS_CONFIG_MASK 0x03 -#define CPIA2_VC_USB_SETTINGS_INTERFACE_MASK 0x0C -#define CPIA2_VC_USB_SETTINGS_ALTERNATE_MASK 0x70 - -#define CPIA2_VC_USB_ISOLIM 0xB0 - -#define CPIA2_VC_USB_ISOFAILS 0xB1 - -#define CPIA2_VC_USB_ISOMAXPKTHI 0xB2 - -#define CPIA2_VC_USB_ISOMAXPKTLO 0xB3 - -#define CPIA2_VC_V2W_CTRL 0xB8 -#define CPIA2_VC_V2W_SELECT 0x01 - -#define CPIA2_VC_V2W_SCL 0xB9 - -#define CPIA2_VC_V2W_SDA 0xBA - -#define CPIA2_VC_VC_CTRL 0xC0 -#define CPIA2_VC_VC_CTRL_RUN 0x01 -#define CPIA2_VC_VC_CTRL_SINGLESHOT 0x02 -#define CPIA2_VC_VC_CTRL_IDLING 0x04 -#define CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES 0x10 -#define CPIA2_VC_VC_CTRL_INHIBIT_Q_TABLES 0x20 -#define CPIA2_VC_VC_CTRL_INHIBIT_PRIVATE 0x40 - -#define CPIA2_VC_VC_RESTART_IVAL_HI 0xC1 - -#define CPIA2_VC_VC_RESTART_IVAL_LO 0xC2 - -#define CPIA2_VC_VC_FORMAT 0xC3 -#define CPIA2_VC_VC_FORMAT_UFIRST 0x01 -#define CPIA2_VC_VC_FORMAT_MONO 0x02 -#define CPIA2_VC_VC_FORMAT_DECIMATING 0x04 -#define CPIA2_VC_VC_FORMAT_SHORTLINE 0x08 -#define CPIA2_VC_VC_FORMAT_SELFTEST 0x10 - -#define CPIA2_VC_VC_CLOCKS 0xC4 -#define CPIA2_VC_VC_CLOCKS_CLKDIV_MASK 0x03 -#define CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 0x04 -#define CPIA2_VC_VC_672_CLOCKS_SCALING 0x08 -#define CPIA2_VC_VC_CLOCKS_LOGDIV0 0x00 -#define CPIA2_VC_VC_CLOCKS_LOGDIV1 0x01 -#define CPIA2_VC_VC_CLOCKS_LOGDIV2 0x02 -#define CPIA2_VC_VC_CLOCKS_LOGDIV3 0x03 -#define CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 0x08 -#define CPIA2_VC_VC_676_CLOCKS_SCALING 0x10 - -#define CPIA2_VC_VC_IHSIZE_LO 0xC5 - -#define CPIA2_VC_VC_XLIM_HI 0xC6 - -#define CPIA2_VC_VC_XLIM_LO 0xC7 - -#define CPIA2_VC_VC_YLIM_HI 0xC8 - -#define CPIA2_VC_VC_YLIM_LO 0xC9 - -#define CPIA2_VC_VC_OHSIZE 0xCA - -#define CPIA2_VC_VC_OVSIZE 0xCB - -#define CPIA2_VC_VC_HCROP 0xCC - -#define CPIA2_VC_VC_VCROP 0xCD - -#define CPIA2_VC_VC_HPHASE 0xCE - -#define CPIA2_VC_VC_VPHASE 0xCF - -#define CPIA2_VC_VC_HISPAN 0xD0 - -#define CPIA2_VC_VC_VISPAN 0xD1 - -#define CPIA2_VC_VC_HICROP 0xD2 - -#define CPIA2_VC_VC_VICROP 0xD3 - -#define CPIA2_VC_VC_HFRACT 0xD4 -#define CPIA2_VC_VC_HFRACT_DEN_MASK 0x0F -#define CPIA2_VC_VC_HFRACT_NUM_MASK 0xF0 - -#define CPIA2_VC_VC_VFRACT 0xD5 -#define CPIA2_VC_VC_VFRACT_DEN_MASK 0x0F -#define CPIA2_VC_VC_VFRACT_NUM_MASK 0xF0 - -#define CPIA2_VC_VC_JPEG_OPT 0xD6 -#define CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE 0x01 -#define CPIA2_VC_VC_JPEG_OPT_NO_DC_AUTO_SQUEEZE 0x02 -#define CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE 0x04 -#define CPIA2_VC_VC_JPEG_OPT_DEFAULT (CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE|\ - CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE) - - -#define CPIA2_VC_VC_CREEP_PERIOD 0xD7 -#define CPIA2_VC_VC_USER_SQUEEZE 0xD8 -#define CPIA2_VC_VC_TARGET_KB 0xD9 - -#define CPIA2_VC_VC_AUTO_SQUEEZE 0xE6 - - -/*** - * VP register set (Bank 2) - ***/ -#define CPIA2_VP_DEVICEH 0 -#define CPIA2_VP_DEVICEL 1 - -#define CPIA2_VP_SYSTEMSTATE 0x02 -#define CPIA2_VP_SYSTEMSTATE_HK_ALIVE 0x01 - -#define CPIA2_VP_SYSTEMCTRL 0x03 -#define CPIA2_VP_SYSTEMCTRL_REQ_CLEAR_ERROR 0x80 -#define CPIA2_VP_SYSTEMCTRL_POWER_DOWN_PLL 0x20 -#define CPIA2_VP_SYSTEMCTRL_REQ_SUSPEND_STATE 0x10 -#define CPIA2_VP_SYSTEMCTRL_REQ_SERIAL_WAKEUP 0x08 -#define CPIA2_VP_SYSTEMCTRL_REQ_AUTOLOAD 0x04 -#define CPIA2_VP_SYSTEMCTRL_HK_CONTROL 0x02 -#define CPIA2_VP_SYSTEMCTRL_POWER_CONTROL 0x01 - -#define CPIA2_VP_SENSOR_FLAGS 0x05 -#define CPIA2_VP_SENSOR_FLAGS_404 0x01 -#define CPIA2_VP_SENSOR_FLAGS_407 0x02 -#define CPIA2_VP_SENSOR_FLAGS_409 0x04 -#define CPIA2_VP_SENSOR_FLAGS_410 0x08 -#define CPIA2_VP_SENSOR_FLAGS_500 0x10 - -#define CPIA2_VP_SENSOR_REV 0x06 - -#define CPIA2_VP_DEVICE_CONFIG 0x07 -#define CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE 0x01 - -#define CPIA2_VP_GPIO_DIRECTION 0x08 -#define CPIA2_VP_GPIO_READ 0xFF -#define CPIA2_VP_GPIO_WRITE 0x00 - -#define CPIA2_VP_GPIO_DATA 0x09 - -#define CPIA2_VP_RAM_ADDR_H 0x0A -#define CPIA2_VP_RAM_ADDR_L 0x0B -#define CPIA2_VP_RAM_DATA 0x0C - -#define CPIA2_VP_PATCH_REV 0x0F - -#define CPIA2_VP4_USER_MODE 0x10 -#define CPIA2_VP5_USER_MODE 0x13 -#define CPIA2_VP_USER_MODE_CIF 0x01 -#define CPIA2_VP_USER_MODE_QCIFDS 0x02 -#define CPIA2_VP_USER_MODE_QCIFPTC 0x04 -#define CPIA2_VP_USER_MODE_QVGADS 0x08 -#define CPIA2_VP_USER_MODE_QVGAPTC 0x10 -#define CPIA2_VP_USER_MODE_VGA 0x20 - -#define CPIA2_VP4_FRAMERATE_REQUEST 0x11 -#define CPIA2_VP5_FRAMERATE_REQUEST 0x14 -#define CPIA2_VP_FRAMERATE_60 0x80 -#define CPIA2_VP_FRAMERATE_50 0x40 -#define CPIA2_VP_FRAMERATE_30 0x20 -#define CPIA2_VP_FRAMERATE_25 0x10 -#define CPIA2_VP_FRAMERATE_15 0x08 -#define CPIA2_VP_FRAMERATE_12_5 0x04 -#define CPIA2_VP_FRAMERATE_7_5 0x02 -#define CPIA2_VP_FRAMERATE_6_25 0x01 - -#define CPIA2_VP4_USER_EFFECTS 0x12 -#define CPIA2_VP5_USER_EFFECTS 0x15 -#define CPIA2_VP_USER_EFFECTS_COLBARS 0x01 -#define CPIA2_VP_USER_EFFECTS_COLBARS_GRAD 0x02 -#define CPIA2_VP_USER_EFFECTS_MIRROR 0x04 -#define CPIA2_VP_USER_EFFECTS_FLIP 0x40 // VP5 only - -/* NOTE: CPIA2_VP_EXPOSURE_MODES shares the same register as VP5 User - * Effects */ -#define CPIA2_VP_EXPOSURE_MODES 0x15 -#define CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER 0x20 -#define CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP 0x10 - -#define CPIA2_VP4_EXPOSURE_TARGET 0x16 // VP4 -#define CPIA2_VP5_EXPOSURE_TARGET 0x20 // VP5 - -#define CPIA2_VP_FLICKER_MODES 0x1B -#define CPIA2_VP_FLICKER_MODES_50HZ 0x80 -#define CPIA2_VP_FLICKER_MODES_CUSTOM_FLT_FFREQ 0x40 -#define CPIA2_VP_FLICKER_MODES_NEVER_FLICKER 0x20 -#define CPIA2_VP_FLICKER_MODES_INHIBIT_RUB 0x10 -#define CPIA2_VP_FLICKER_MODES_ADJUST_LINE_FREQ 0x08 -#define CPIA2_VP_FLICKER_MODES_CUSTOM_INT_FFREQ 0x04 - -#define CPIA2_VP_UMISC 0x1D -#define CPIA2_VP_UMISC_FORCE_MONO 0x80 -#define CPIA2_VP_UMISC_FORCE_ID_MASK 0x40 -#define CPIA2_VP_UMISC_INHIBIT_AUTO_FGS 0x20 -#define CPIA2_VP_UMISC_INHIBIT_AUTO_DIMS 0x08 -#define CPIA2_VP_UMISC_OPT_FOR_SENSOR_DS 0x04 -#define CPIA2_VP_UMISC_INHIBIT_AUTO_MODE_INT 0x02 - -#define CPIA2_VP5_ANTIFLKRSETUP 0x22 //34 - -#define CPIA2_VP_INTERPOLATION 0x24 -#define CPIA2_VP_INTERPOLATION_EVEN_FIRST 0x40 -#define CPIA2_VP_INTERPOLATION_HJOG 0x20 -#define CPIA2_VP_INTERPOLATION_VJOG 0x10 - -#define CPIA2_VP_GAMMA 0x25 -#define CPIA2_VP_DEFAULT_GAMMA 0x10 - -#define CPIA2_VP_YRANGE 0x26 - -#define CPIA2_VP_SATURATION 0x27 - -#define CPIA2_VP5_MYBLACK_LEVEL 0x3A //58 -#define CPIA2_VP5_MCYRANGE 0x3B //59 -#define CPIA2_VP5_MYCEILING 0x3C //60 -#define CPIA2_VP5_MCUVSATURATION 0x3D //61 - - -#define CPIA2_VP_REHASH_VALUES 0x60 - - -/*** - * Common sensor registers - ***/ -#define CPIA2_SENSOR_DEVICE_H 0x00 -#define CPIA2_SENSOR_DEVICE_L 0x01 - -#define CPIA2_SENSOR_DATA_FORMAT 0x16 -#define CPIA2_SENSOR_DATA_FORMAT_HMIRROR 0x08 -#define CPIA2_SENSOR_DATA_FORMAT_VMIRROR 0x10 - -#define CPIA2_SENSOR_CR1 0x76 -#define CPIA2_SENSOR_CR1_STAND_BY 0x01 -#define CPIA2_SENSOR_CR1_DOWN_RAMP_GEN 0x02 -#define CPIA2_SENSOR_CR1_DOWN_COLUMN_ADC 0x04 -#define CPIA2_SENSOR_CR1_DOWN_CAB_REGULATOR 0x08 -#define CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR 0x10 -#define CPIA2_SENSOR_CR1_DOWN_VRT_AMP 0x20 -#define CPIA2_SENSOR_CR1_DOWN_BAND_GAP 0x40 - -#endif diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c deleted file mode 100644 index f4da02941..000000000 --- a/drivers/media/video/cpia2/cpia2_usb.c +++ /dev/null @@ -1,907 +0,0 @@ -/**************************************************************************** - * - * Filename: cpia2_usb.c - * - * Copyright 2001, STMicrolectronics, Inc. - * Contact: steve.miller@st.com - * - * Description: - * This is a USB driver for CPia2 based video cameras. - * The infrastructure of this driver is based on the cpia usb driver by - * Jochen Scharrlach and Johannes Erdfeldt. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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. - * - * Stripped of 2.4 stuff ready for main kernel submit by - * Alan Cox - ****************************************************************************/ - -#include -#include -#include - -#include "cpia2.h" - -static int frame_sizes[] = { - 0, // USBIF_CMDONLY - 0, // USBIF_BULK - 128, // USBIF_ISO_1 - 384, // USBIF_ISO_2 - 640, // USBIF_ISO_3 - 768, // USBIF_ISO_4 - 896, // USBIF_ISO_5 - 1023, // USBIF_ISO_6 -}; - -#define FRAMES_PER_DESC 10 -#define FRAME_SIZE_PER_DESC frame_sizes[cam->cur_alt] - -static void process_frame(struct camera_data *cam); -static void cpia2_usb_complete(struct urb *urb, struct pt_regs *); -static int cpia2_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id); -static void cpia2_usb_disconnect(struct usb_interface *intf); - -static void free_sbufs(struct camera_data *cam); -static void add_APPn(struct camera_data *cam); -static void add_COM(struct camera_data *cam); -static int submit_urbs(struct camera_data *cam); -static int set_alternate(struct camera_data *cam, unsigned int alt); -static int configure_transfer_mode(struct camera_data *cam, unsigned int alt); - -static struct usb_device_id cpia2_id_table[] = { - {USB_DEVICE(0x0553, 0x0100)}, - {USB_DEVICE(0x0553, 0x0140)}, - {USB_DEVICE(0x0553, 0x0151)}, /* STV0676 */ - {} /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, cpia2_id_table); - -static struct usb_driver cpia2_driver = { - .name = "cpia2", - .probe = cpia2_usb_probe, - .disconnect = cpia2_usb_disconnect, - .id_table = cpia2_id_table -}; - - -/****************************************************************************** - * - * process_frame - * - *****************************************************************************/ -static void process_frame(struct camera_data *cam) -{ - static int frame_count = 0; - - unsigned char *inbuff = cam->workbuff->data; - - DBG("Processing frame #%d, current:%d\n", - cam->workbuff->num, cam->curbuff->num); - - if(cam->workbuff->length > cam->workbuff->max_length) - cam->workbuff->max_length = cam->workbuff->length; - - if ((inbuff[0] == 0xFF) && (inbuff[1] == 0xD8)) { - frame_count++; - } else { - cam->workbuff->status = FRAME_ERROR; - DBG("Start of frame not found\n"); - return; - } - - /*** - * Now the output buffer should have a JPEG image in it. - ***/ - if(!cam->first_image_seen) { - /* Always skip the first image after streaming - * starts. It is almost certainly corrupt. */ - cam->first_image_seen = 1; - cam->workbuff->status = FRAME_EMPTY; - return; - } - if (cam->workbuff->length > 3) { - if(cam->mmapped && - cam->workbuff->length < cam->workbuff->max_length) { - /* No junk in the buffers */ - memset(cam->workbuff->data+cam->workbuff->length, - 0, cam->workbuff->max_length- - cam->workbuff->length); - } - cam->workbuff->max_length = cam->workbuff->length; - cam->workbuff->status = FRAME_READY; - - if(!cam->mmapped && cam->num_frames > 2) { - /* During normal reading, the most recent - * frame will be read. If the current frame - * hasn't started reading yet, it will never - * be read, so mark it empty. If the buffer is - * mmapped, or we have few buffers, we need to - * wait for the user to free the buffer. - * - * NOTE: This is not entirely foolproof with 3 - * buffers, but it would take an EXTREMELY - * overloaded system to cause problems (possible - * image data corruption). Basically, it would - * need to take more time to execute cpia2_read - * than it would for the camera to send - * cam->num_frames-2 frames before problems - * could occur. - */ - cam->curbuff->status = FRAME_EMPTY; - } - cam->curbuff = cam->workbuff; - cam->workbuff = cam->workbuff->next; - DBG("Changed buffers, work:%d, current:%d\n", - cam->workbuff->num, cam->curbuff->num); - return; - } else { - DBG("Not enough data for an image.\n"); - } - - cam->workbuff->status = FRAME_ERROR; - return; -} - -/****************************************************************************** - * - * add_APPn - * - * Adds a user specified APPn record - *****************************************************************************/ -static void add_APPn(struct camera_data *cam) -{ - if(cam->APP_len > 0) { - cam->workbuff->data[cam->workbuff->length++] = 0xFF; - cam->workbuff->data[cam->workbuff->length++] = 0xE0+cam->APPn; - cam->workbuff->data[cam->workbuff->length++] = 0; - cam->workbuff->data[cam->workbuff->length++] = cam->APP_len+2; - memcpy(cam->workbuff->data+cam->workbuff->length, - cam->APP_data, cam->APP_len); - cam->workbuff->length += cam->APP_len; - } -} - -/****************************************************************************** - * - * add_COM - * - * Adds a user specified COM record - *****************************************************************************/ -static void add_COM(struct camera_data *cam) -{ - if(cam->COM_len > 0) { - cam->workbuff->data[cam->workbuff->length++] = 0xFF; - cam->workbuff->data[cam->workbuff->length++] = 0xFE; - cam->workbuff->data[cam->workbuff->length++] = 0; - cam->workbuff->data[cam->workbuff->length++] = cam->COM_len+2; - memcpy(cam->workbuff->data+cam->workbuff->length, - cam->COM_data, cam->COM_len); - cam->workbuff->length += cam->COM_len; - } -} - -/****************************************************************************** - * - * cpia2_usb_complete - * - * callback when incoming packet is received - *****************************************************************************/ -static void cpia2_usb_complete(struct urb *urb, struct pt_regs *regs) -{ - int i; - unsigned char *cdata; - static int frame_ready = false; - struct camera_data *cam = (struct camera_data *) urb->context; - - if (urb->status!=0) { - if (!(urb->status == -ENOENT || - urb->status == -ECONNRESET || - urb->status == -ESHUTDOWN)) - { - DBG("urb->status = %d!\n", urb->status); - } - DBG("Stopping streaming\n"); - return; - } - - if (!cam->streaming || !cam->present || cam->open_count == 0) { - LOG("Will now stop the streaming: streaming = %d, " - "present=%d, open_count=%d\n", - cam->streaming, cam->present, cam->open_count); - return; - } - - /*** - * Packet collater - ***/ - //DBG("Collating %d packets\n", urb->number_of_packets); - for (i = 0; i < urb->number_of_packets; i++) { - u16 checksum, iso_checksum; - int j; - int n = urb->iso_frame_desc[i].actual_length; - int st = urb->iso_frame_desc[i].status; - - if(cam->workbuff->status == FRAME_READY) { - struct framebuf *ptr; - /* Try to find an available buffer */ - DBG("workbuff full, searching\n"); - for (ptr = cam->workbuff->next; - ptr != cam->workbuff; - ptr = ptr->next) - { - if (ptr->status == FRAME_EMPTY) { - ptr->status = FRAME_READING; - ptr->length = 0; - break; - } - } - if (ptr == cam->workbuff) - break; /* No READING or EMPTY buffers left */ - - cam->workbuff = ptr; - } - - if (cam->workbuff->status == FRAME_EMPTY || - cam->workbuff->status == FRAME_ERROR) { - cam->workbuff->status = FRAME_READING; - cam->workbuff->length = 0; - } - - //DBG(" Packet %d length = %d, status = %d\n", i, n, st); - cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset; - - if (st) { - LOG("cpia2 data error: [%d] len=%d, status = %d\n", - i, n, st); - if(!ALLOW_CORRUPT) - cam->workbuff->status = FRAME_ERROR; - continue; - } - - if(n<=2) - continue; - - checksum = 0; - for(j=0; jworkbuff->status = FRAME_ERROR; - continue; - } - } - n -= 2; - - if(cam->workbuff->status != FRAME_READING) { - if((0xFF == cdata[0] && 0xD8 == cdata[1]) || - (0xD8 == cdata[0] && 0xFF == cdata[1] && - 0 != cdata[2])) { - /* frame is skipped, but increment total - * frame count anyway */ - cam->frame_count++; - } - DBG("workbuff not reading, status=%d\n", - cam->workbuff->status); - continue; - } - - if (cam->frame_size < cam->workbuff->length + n) { - ERR("buffer overflow! length: %d, n: %d\n", - cam->workbuff->length, n); - cam->workbuff->status = FRAME_ERROR; - if(cam->workbuff->length > cam->workbuff->max_length) - cam->workbuff->max_length = - cam->workbuff->length; - continue; - } - - if (cam->workbuff->length == 0) { - int data_offset; - if ((0xD8 == cdata[0]) && (0xFF == cdata[1])) { - data_offset = 1; - } else if((0xFF == cdata[0]) && (0xD8 == cdata[1]) - && (0xFF == cdata[2])) { - data_offset = 2; - } else { - DBG("Ignoring packet, not beginning!\n"); - continue; - } - DBG("Start of frame pattern found\n"); - do_gettimeofday(&cam->workbuff->timestamp); - cam->workbuff->seq = cam->frame_count++; - cam->workbuff->data[0] = 0xFF; - cam->workbuff->data[1] = 0xD8; - cam->workbuff->length = 2; - add_APPn(cam); - add_COM(cam); - memcpy(cam->workbuff->data+cam->workbuff->length, - cdata+data_offset, n-data_offset); - cam->workbuff->length += n-data_offset; - } else if (cam->workbuff->length > 0) { - memcpy(cam->workbuff->data + cam->workbuff->length, - cdata, n); - cam->workbuff->length += n; - } - - if ((cam->workbuff->length >= 3) && - (cam->workbuff->data[cam->workbuff->length - 3] == 0xFF) && - (cam->workbuff->data[cam->workbuff->length - 2] == 0xD9) && - (cam->workbuff->data[cam->workbuff->length - 1] == 0xFF)) { - frame_ready = true; - cam->workbuff->data[cam->workbuff->length - 1] = 0; - cam->workbuff->length -= 1; - } else if ((cam->workbuff->length >= 2) && - (cam->workbuff->data[cam->workbuff->length - 2] == 0xFF) && - (cam->workbuff->data[cam->workbuff->length - 1] == 0xD9)) { - frame_ready = true; - } - - if (frame_ready) { - DBG("Workbuff image size = %d\n",cam->workbuff->length); - process_frame(cam); - - frame_ready = false; - - if (waitqueue_active(&cam->wq_stream)) - wake_up_interruptible(&cam->wq_stream); - } - } - - if(cam->streaming) { - /* resubmit */ - urb->dev = cam->dev; - if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0) - ERR("%s: usb_submit_urb ret %d!\n", __func__, i); - } -} - -/****************************************************************************** - * - * configure_transfer_mode - * - *****************************************************************************/ -static int configure_transfer_mode(struct camera_data *cam, unsigned int alt) -{ - static unsigned char iso_regs[8][4] = { - {0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00}, - {0xB9, 0x00, 0x00, 0x7E}, - {0xB9, 0x00, 0x01, 0x7E}, - {0xB9, 0x00, 0x02, 0x7E}, - {0xB9, 0x00, 0x02, 0xFE}, - {0xB9, 0x00, 0x03, 0x7E}, - {0xB9, 0x00, 0x03, 0xFD} - }; - struct cpia2_command cmd; - unsigned char reg; - - if(!cam->present) - return -ENODEV; - - /*** - * Write the isoc registers according to the alternate selected - ***/ - cmd.direction = TRANSFER_WRITE; - cmd.buffer.block_data[0] = iso_regs[alt][0]; - cmd.buffer.block_data[1] = iso_regs[alt][1]; - cmd.buffer.block_data[2] = iso_regs[alt][2]; - cmd.buffer.block_data[3] = iso_regs[alt][3]; - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.start = CPIA2_VC_USB_ISOLIM; - cmd.reg_count = 4; - cpia2_send_command(cam, &cmd); - - /*** - * Enable relevant streams before starting polling. - * First read USB Stream Config Register. - ***/ - cmd.direction = TRANSFER_READ; - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cmd.start = CPIA2_VC_USB_STRM; - cmd.reg_count = 1; - cpia2_send_command(cam, &cmd); - reg = cmd.buffer.block_data[0]; - - /* Clear iso, bulk, and int */ - reg &= ~(CPIA2_VC_USB_STRM_BLK_ENABLE | - CPIA2_VC_USB_STRM_ISO_ENABLE | - CPIA2_VC_USB_STRM_INT_ENABLE); - - if (alt == USBIF_BULK) { - DBG("Enabling bulk xfer\n"); - reg |= CPIA2_VC_USB_STRM_BLK_ENABLE; /* Enable Bulk */ - cam->xfer_mode = XFER_BULK; - } else if (alt >= USBIF_ISO_1) { - DBG("Enabling ISOC xfer\n"); - reg |= CPIA2_VC_USB_STRM_ISO_ENABLE; - cam->xfer_mode = XFER_ISOC; - } - - cmd.buffer.block_data[0] = reg; - cmd.direction = TRANSFER_WRITE; - cmd.start = CPIA2_VC_USB_STRM; - cmd.reg_count = 1; - cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC; - cpia2_send_command(cam, &cmd); - - return 0; -} - -/****************************************************************************** - * - * cpia2_usb_change_streaming_alternate - * - *****************************************************************************/ -int cpia2_usb_change_streaming_alternate(struct camera_data *cam, - unsigned int alt) -{ - int ret = 0; - - if(alt < USBIF_ISO_1 || alt > USBIF_ISO_6) - return -EINVAL; - - if(alt == cam->params.camera_state.stream_mode) - return 0; - - cpia2_usb_stream_pause(cam); - - configure_transfer_mode(cam, alt); - - cam->params.camera_state.stream_mode = alt; - - /* Reset the camera to prevent image quality degradation */ - cpia2_reset_camera(cam); - - cpia2_usb_stream_resume(cam); - - return ret; -} - -/****************************************************************************** - * - * set_alternate - * - *****************************************************************************/ -int set_alternate(struct camera_data *cam, unsigned int alt) -{ - int ret = 0; - - if(alt == cam->cur_alt) - return 0; - - if (cam->cur_alt != USBIF_CMDONLY) { - DBG("Changing from alt %d to %d\n", cam->cur_alt, USBIF_CMDONLY); - ret = usb_set_interface(cam->dev, cam->iface, USBIF_CMDONLY); - if (ret != 0) - return ret; - } - if (alt != USBIF_CMDONLY) { - DBG("Changing from alt %d to %d\n", USBIF_CMDONLY, alt); - ret = usb_set_interface(cam->dev, cam->iface, alt); - if (ret != 0) - return ret; - } - - cam->old_alt = cam->cur_alt; - cam->cur_alt = alt; - - return ret; -} - -/****************************************************************************** - * - * free_sbufs - * - * Free all cam->sbuf[]. All non-NULL .data and .urb members that are non-NULL - * are assumed to be allocated. Non-NULL .urb members are also assumed to be - * submitted (and must therefore be killed before they are freed). - *****************************************************************************/ -static void free_sbufs(struct camera_data *cam) -{ - int i; - - for (i = 0; i < NUM_SBUF; i++) { - if(cam->sbuf[i].urb) { - usb_kill_urb(cam->sbuf[i].urb); - usb_free_urb(cam->sbuf[i].urb); - cam->sbuf[i].urb = NULL; - } - if(cam->sbuf[i].data) { - kfree(cam->sbuf[i].data); - cam->sbuf[i].data = NULL; - } - } -} - -/******* -* Convenience functions -*******/ -/**************************************************************************** - * - * write_packet - * - ***************************************************************************/ -static int write_packet(struct usb_device *udev, - u8 request, u8 * registers, u16 start, size_t size) -{ - if (!registers || size <= 0) - return -EINVAL; - - return usb_control_msg(udev, - usb_sndctrlpipe(udev, 0), - request, - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - start, /* value */ - 0, /* index */ - registers, /* buffer */ - size, - HZ); -} - -/**************************************************************************** - * - * read_packet - * - ***************************************************************************/ -static int read_packet(struct usb_device *udev, - u8 request, u8 * registers, u16 start, size_t size) -{ - if (!registers || size <= 0) - return -EINVAL; - - return usb_control_msg(udev, - usb_rcvctrlpipe(udev, 0), - request, - USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE, - start, /* value */ - 0, /* index */ - registers, /* buffer */ - size, - HZ); -} - -/****************************************************************************** - * - * cpia2_usb_transfer_cmd - * - *****************************************************************************/ -int cpia2_usb_transfer_cmd(struct camera_data *cam, - void *registers, - u8 request, u8 start, u8 count, u8 direction) -{ - int err = 0; - struct usb_device *udev = cam->dev; - - if (!udev) { - ERR("%s: Internal driver error: udev is NULL\n", __func__); - return -EINVAL; - } - - if (!registers) { - ERR("%s: Internal driver error: register array is NULL\n", __func__); - return -EINVAL; - } - - if (direction == TRANSFER_READ) { - err = read_packet(udev, request, (u8 *)registers, start, count); - if (err > 0) - err = 0; - } else if (direction == TRANSFER_WRITE) { - err =write_packet(udev, request, (u8 *)registers, start, count); - if (err < 0) { - LOG("Control message failed, err val = %d\n", err); - LOG("Message: request = 0x%0X, start = 0x%0X\n", - request, start); - LOG("Message: count = %d, register[0] = 0x%0X\n", - count, ((unsigned char *) registers)[0]); - } else - err=0; - } else { - LOG("Unexpected first byte of direction: %d\n", - direction); - return -EINVAL; - } - - if(err != 0) - LOG("Unexpected error: %d\n", err); - return err; -} - - -/****************************************************************************** - * - * submit_urbs - * - *****************************************************************************/ -static int submit_urbs(struct camera_data *cam) -{ - struct urb *urb; - int fx, err, i; - - for(i=0; isbuf[i].data) - continue; - cam->sbuf[i].data = - kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL); - if (!cam->sbuf[i].data) { - return -ENOMEM; - } - } - - /* We double buffer the Isoc lists, and also know the polling - * interval is every frame (1 == (1 << (bInterval -1))). - */ - for(i=0; isbuf[i].urb) { - continue; - } - urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); - if (!urb) { - return -ENOMEM; - } - - cam->sbuf[i].urb = urb; - urb->dev = cam->dev; - urb->context = cam; - urb->pipe = usb_rcvisocpipe(cam->dev, 1 /*ISOC endpoint*/); - urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = cam->sbuf[i].data; - urb->complete = cpia2_usb_complete; - urb->number_of_packets = FRAMES_PER_DESC; - urb->interval = 1; - urb->transfer_buffer_length = - FRAME_SIZE_PER_DESC * FRAMES_PER_DESC; - - for (fx = 0; fx < FRAMES_PER_DESC; fx++) { - urb->iso_frame_desc[fx].offset = - FRAME_SIZE_PER_DESC * fx; - urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC; - } - } - - - /* Queue the ISO urbs, and resubmit in the completion handler */ - for(i=0; isbuf[i].urb, GFP_KERNEL); - if (err) { - ERR("usb_submit_urb[%d]() = %d\n", i, err); - return err; - } - } - - return 0; -} - -/****************************************************************************** - * - * cpia2_usb_stream_start - * - *****************************************************************************/ -int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate) -{ - int ret; - int old_alt; - - if(cam->streaming) - return 0; - - if (cam->flush) { - int i; - DBG("Flushing buffers\n"); - for(i=0; inum_frames; ++i) { - cam->buffers[i].status = FRAME_EMPTY; - cam->buffers[i].length = 0; - } - cam->curbuff = &cam->buffers[0]; - cam->workbuff = cam->curbuff->next; - cam->flush = false; - } - - old_alt = cam->params.camera_state.stream_mode; - cam->params.camera_state.stream_mode = 0; - ret = cpia2_usb_change_streaming_alternate(cam, alternate); - if (ret < 0) { - int ret2; - ERR("cpia2_usb_change_streaming_alternate() = %d!\n", ret); - cam->params.camera_state.stream_mode = old_alt; - ret2 = set_alternate(cam, USBIF_CMDONLY); - if (ret2 < 0) { - ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already " - "failed. Then tried to call " - "set_alternate(USBIF_CMDONLY) = %d.\n", - alternate, ret, ret2); - } - } else { - cam->frame_count = 0; - cam->streaming = 1; - ret = cpia2_usb_stream_resume(cam); - } - return ret; -} - -/****************************************************************************** - * - * cpia2_usb_stream_pause - * - *****************************************************************************/ -int cpia2_usb_stream_pause(struct camera_data *cam) -{ - int ret = 0; - if(cam->streaming) { - ret = set_alternate(cam, USBIF_CMDONLY); - free_sbufs(cam); - } - return ret; -} - -/****************************************************************************** - * - * cpia2_usb_stream_resume - * - *****************************************************************************/ -int cpia2_usb_stream_resume(struct camera_data *cam) -{ - int ret = 0; - if(cam->streaming) { - cam->first_image_seen = 0; - ret = set_alternate(cam, cam->params.camera_state.stream_mode); - if(ret == 0) { - ret = submit_urbs(cam); - } - } - return ret; -} - -/****************************************************************************** - * - * cpia2_usb_stream_stop - * - *****************************************************************************/ -int cpia2_usb_stream_stop(struct camera_data *cam) -{ - int ret; - ret = cpia2_usb_stream_pause(cam); - cam->streaming = 0; - configure_transfer_mode(cam, 0); - return ret; -} - -/****************************************************************************** - * - * cpia2_usb_probe - * - * Probe and initialize. - *****************************************************************************/ -static int cpia2_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_interface_descriptor *interface; - struct camera_data *cam; - int ret; - - /* A multi-config CPiA2 camera? */ - if (udev->descriptor.bNumConfigurations != 1) - return -ENODEV; - interface = &intf->cur_altsetting->desc; - - /* If we get to this point, we found a CPiA2 camera */ - LOG("CPiA2 USB camera found\n"); - - if((cam = cpia2_init_camera_struct()) == NULL) - return -ENOMEM; - - cam->dev = udev; - cam->iface = interface->bInterfaceNumber; - - ret = set_alternate(cam, USBIF_CMDONLY); - if (ret < 0) { - ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; - } - - if ((ret = cpia2_register_camera(cam)) < 0) { - ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; - } - - - if((ret = cpia2_init_camera(cam)) < 0) { - ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); - cpia2_unregister_camera(cam); - kfree(cam); - return ret; - } - LOG(" CPiA Version: %d.%02d (%d.%d)\n", - cam->params.version.firmware_revision_hi, - cam->params.version.firmware_revision_lo, - cam->params.version.asic_id, - cam->params.version.asic_rev); - LOG(" CPiA PnP-ID: %04x:%04x:%04x\n", - cam->params.pnp_id.vendor, - cam->params.pnp_id.product, - cam->params.pnp_id.device_revision); - LOG(" SensorID: %d.(version %d)\n", - cam->params.version.sensor_flags, - cam->params.version.sensor_rev); - - usb_set_intfdata(intf, cam); - - return 0; -} - -/****************************************************************************** - * - * cpia2_disconnect - * - *****************************************************************************/ -static void cpia2_usb_disconnect(struct usb_interface *intf) -{ - struct camera_data *cam = usb_get_intfdata(intf); - usb_set_intfdata(intf, NULL); - cam->present = 0; - - DBG("Stopping stream\n"); - cpia2_usb_stream_stop(cam); - - DBG("Unregistering camera\n"); - cpia2_unregister_camera(cam); - - if(cam->buffers) { - DBG("Wakeup waiting processes\n"); - cam->curbuff->status = FRAME_READY; - cam->curbuff->length = 0; - if (waitqueue_active(&cam->wq_stream)) - wake_up_interruptible(&cam->wq_stream); - } - - DBG("Releasing interface\n"); - usb_driver_release_interface(&cpia2_driver, intf); - - if (cam->open_count == 0) { - DBG("Freeing camera structure\n"); - kfree(cam); - } - - LOG("CPiA2 camera disconnected.\n"); -} - - -/****************************************************************************** - * - * usb_cpia2_init - * - *****************************************************************************/ -int cpia2_usb_init(void) -{ - return usb_register(&cpia2_driver); -} - -/****************************************************************************** - * - * usb_cpia_cleanup - * - *****************************************************************************/ -void cpia2_usb_cleanup(void) -{ - schedule_timeout(2 * HZ); - usb_deregister(&cpia2_driver); -} diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c deleted file mode 100644 index 481e178ef..000000000 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ /dev/null @@ -1,2080 +0,0 @@ -/**************************************************************************** - * - * Filename: cpia2_v4l.c - * - * Copyright 2001, STMicrolectronics, Inc. - * Contact: steve.miller@st.com - * Copyright 2001,2005, Scott J. Bertin - * - * Description: - * This is a USB driver for CPia2 based video cameras. - * The infrastructure of this driver is based on the cpia usb driver by - * Jochen Scharrlach and Johannes Erdfeldt. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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. - * - * Stripped of 2.4 stuff ready for main kernel submit by - * Alan Cox - ****************************************************************************/ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include "cpia2.h" -#include "cpia2dev.h" - - -//#define _CPIA2_DEBUG_ - -#define MAKE_STRING_1(x) #x -#define MAKE_STRING(x) MAKE_STRING_1(x) - -static int video_nr = -1; -module_param(video_nr, int, 0); -MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)"); - -static int buffer_size = 68*1024; -module_param(buffer_size, int, 0); -MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)"); - -static int num_buffers = 3; -module_param(num_buffers, int, 0); -MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-" - MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)"); - -static int alternate = DEFAULT_ALT; -module_param(alternate, int, 0); -MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-" - MAKE_STRING(USBIF_ISO_6) ", default " - MAKE_STRING(DEFAULT_ALT) ")"); - -static int flicker_freq = 60; -module_param(flicker_freq, int, 0); -MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or" - MAKE_STRING(60) ", default " - MAKE_STRING(60) ")"); - -static int flicker_mode = NEVER_FLICKER; -module_param(flicker_mode, int, 0); -MODULE_PARM_DESC(flicker_mode, - "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or" - MAKE_STRING(ANTI_FLICKER_ON) ", default " - MAKE_STRING(NEVER_FLICKER) ")"); - -MODULE_AUTHOR("Steve Miller (STMicroelectronics) "); -MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); -MODULE_SUPPORTED_DEVICE("video"); -MODULE_LICENSE("GPL"); - -#define ABOUT "V4L-Driver for Vision CPiA2 based cameras" - -#ifndef VID_HARDWARE_CPIA2 -#error "VID_HARDWARE_CPIA2 should have been defined in linux/videodev.h" -#endif - -struct control_menu_info { - int value; - char name[32]; -}; - -static struct control_menu_info framerate_controls[] = -{ - { CPIA2_VP_FRAMERATE_6_25, "6.25 fps" }, - { CPIA2_VP_FRAMERATE_7_5, "7.5 fps" }, - { CPIA2_VP_FRAMERATE_12_5, "12.5 fps" }, - { CPIA2_VP_FRAMERATE_15, "15 fps" }, - { CPIA2_VP_FRAMERATE_25, "25 fps" }, - { CPIA2_VP_FRAMERATE_30, "30 fps" }, -}; -#define NUM_FRAMERATE_CONTROLS (sizeof(framerate_controls)/sizeof(framerate_controls[0])) - -static struct control_menu_info flicker_controls[] = -{ - { NEVER_FLICKER, "Off" }, - { FLICKER_50, "50 Hz" }, - { FLICKER_60, "60 Hz" }, -}; -#define NUM_FLICKER_CONTROLS (sizeof(flicker_controls)/sizeof(flicker_controls[0])) - -static struct control_menu_info lights_controls[] = -{ - { 0, "Off" }, - { 64, "Top" }, - { 128, "Bottom" }, - { 192, "Both" }, -}; -#define NUM_LIGHTS_CONTROLS (sizeof(lights_controls)/sizeof(lights_controls[0])) -#define GPIO_LIGHTS_MASK 192 - -static struct v4l2_queryctrl controls[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = DEFAULT_BRIGHTNESS, - }, - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = DEFAULT_CONTRAST, - }, - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = DEFAULT_SATURATION, - }, - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Horizontally", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Vertically", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = CPIA2_CID_TARGET_KB, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Target KB", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = DEFAULT_TARGET_KB, - }, - { - .id = CPIA2_CID_GPIO, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "GPIO", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 0, - }, - { - .id = CPIA2_CID_FLICKER_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flicker Reduction", - .minimum = 0, - .maximum = NUM_FLICKER_CONTROLS-1, - .step = 1, - .default_value = 0, - }, - { - .id = CPIA2_CID_FRAMERATE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Framerate", - .minimum = 0, - .maximum = NUM_FRAMERATE_CONTROLS-1, - .step = 1, - .default_value = NUM_FRAMERATE_CONTROLS-1, - }, - { - .id = CPIA2_CID_USB_ALT, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "USB Alternate", - .minimum = USBIF_ISO_1, - .maximum = USBIF_ISO_6, - .step = 1, - .default_value = DEFAULT_ALT, - }, - { - .id = CPIA2_CID_LIGHTS, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Lights", - .minimum = 0, - .maximum = NUM_LIGHTS_CONTROLS-1, - .step = 1, - .default_value = 0, - }, - { - .id = CPIA2_CID_RESET_CAMERA, - .type = V4L2_CTRL_TYPE_BUTTON, - .name = "Reset Camera", - .minimum = 0, - .maximum = 0, - .step = 0, - .default_value = 0, - }, -}; -#define NUM_CONTROLS (sizeof(controls)/sizeof(controls[0])) - - -/****************************************************************************** - * - * cpia2_open - * - *****************************************************************************/ -static int cpia2_open(struct inode *inode, struct file *file) -{ - struct video_device *dev = video_devdata(file); - struct camera_data *cam = video_get_drvdata(dev); - int retval = 0; - - if (!cam) { - ERR("Internal error, camera_data not found!\n"); - return -ENODEV; - } - - if(mutex_lock_interruptible(&cam->busy_lock)) - return -ERESTARTSYS; - - if(!cam->present) { - retval = -ENODEV; - goto err_return; - } - - if (cam->open_count > 0) { - goto skip_init; - } - - if (cpia2_allocate_buffers(cam)) { - retval = -ENOMEM; - goto err_return; - } - - /* reset the camera */ - if (cpia2_reset_camera(cam) < 0) { - retval = -EIO; - goto err_return; - } - - cam->APP_len = 0; - cam->COM_len = 0; - -skip_init: - { - struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL); - if(!fh) { - retval = -ENOMEM; - goto err_return; - } - file->private_data = fh; - fh->prio = V4L2_PRIORITY_UNSET; - v4l2_prio_open(&cam->prio, &fh->prio); - fh->mmapped = 0; - } - - ++cam->open_count; - - cpia2_dbg_dump_registers(cam); - -err_return: - mutex_unlock(&cam->busy_lock); - return retval; -} - -/****************************************************************************** - * - * cpia2_close - * - *****************************************************************************/ -static int cpia2_close(struct inode *inode, struct file *file) -{ - struct video_device *dev = video_devdata(file); - struct camera_data *cam = video_get_drvdata(dev); - struct cpia2_fh *fh = file->private_data; - - mutex_lock(&cam->busy_lock); - - if (cam->present && - (cam->open_count == 1 - || fh->prio == V4L2_PRIORITY_RECORD - )) { - cpia2_usb_stream_stop(cam); - - if(cam->open_count == 1) { - /* save camera state for later open */ - cpia2_save_camera_state(cam); - - cpia2_set_low_power(cam); - cpia2_free_buffers(cam); - } - } - - { - if(fh->mmapped) - cam->mmapped = 0; - v4l2_prio_close(&cam->prio,&fh->prio); - file->private_data = NULL; - kfree(fh); - } - - if (--cam->open_count == 0) { - cpia2_free_buffers(cam); - if (!cam->present) { - video_unregister_device(dev); - kfree(cam); - } - } - - mutex_unlock(&cam->busy_lock); - - return 0; -} - -/****************************************************************************** - * - * cpia2_v4l_read - * - *****************************************************************************/ -static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count, - loff_t *off) -{ - struct video_device *dev = video_devdata(file); - struct camera_data *cam = video_get_drvdata(dev); - int noblock = file->f_flags&O_NONBLOCK; - - struct cpia2_fh *fh = file->private_data; - - if(!cam) - return -EINVAL; - - /* Priority check */ - if(fh->prio != V4L2_PRIORITY_RECORD) { - return -EBUSY; - } - - return cpia2_read(cam, buf, count, noblock); -} - - -/****************************************************************************** - * - * cpia2_v4l_poll - * - *****************************************************************************/ -static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait) -{ - struct video_device *dev = video_devdata(filp); - struct camera_data *cam = video_get_drvdata(dev); - - struct cpia2_fh *fh = filp->private_data; - - if(!cam) - return POLLERR; - - /* Priority check */ - if(fh->prio != V4L2_PRIORITY_RECORD) { - return POLLERR; - } - - return cpia2_poll(cam, filp, wait); -} - - -/****************************************************************************** - * - * ioctl_cap_query - * - *****************************************************************************/ -static int ioctl_cap_query(void *arg, struct camera_data *cam) -{ - struct video_capability *vc; - int retval = 0; - vc = arg; - - if (cam->params.pnp_id.product == 0x151) - strcpy(vc->name, "QX5 Microscope"); - else - strcpy(vc->name, "CPiA2 Camera"); - - vc->type = VID_TYPE_CAPTURE | VID_TYPE_MJPEG_ENCODER; - vc->channels = 1; - vc->audios = 0; - vc->minwidth = 176; /* VIDEOSIZE_QCIF */ - vc->minheight = 144; - switch (cam->params.version.sensor_flags) { - case CPIA2_VP_SENSOR_FLAGS_500: - vc->maxwidth = STV_IMAGE_VGA_COLS; - vc->maxheight = STV_IMAGE_VGA_ROWS; - break; - case CPIA2_VP_SENSOR_FLAGS_410: - vc->maxwidth = STV_IMAGE_CIF_COLS; - vc->maxheight = STV_IMAGE_CIF_ROWS; - break; - default: - return -EINVAL; - } - - return retval; -} - -/****************************************************************************** - * - * ioctl_get_channel - * - *****************************************************************************/ -static int ioctl_get_channel(void *arg) -{ - int retval = 0; - struct video_channel *v; - v = arg; - - if (v->channel != 0) - return -EINVAL; - - v->channel = 0; - strcpy(v->name, "Camera"); - v->tuners = 0; - v->flags = 0; - v->type = VIDEO_TYPE_CAMERA; - v->norm = 0; - - return retval; -} - -/****************************************************************************** - * - * ioctl_set_channel - * - *****************************************************************************/ -static int ioctl_set_channel(void *arg) -{ - struct video_channel *v; - int retval = 0; - v = arg; - - if (retval == 0 && v->channel != 0) - retval = -EINVAL; - - return retval; -} - -/****************************************************************************** - * - * ioctl_set_image_prop - * - *****************************************************************************/ -static int ioctl_set_image_prop(void *arg, struct camera_data *cam) -{ - struct video_picture *vp; - int retval = 0; - vp = arg; - - /* brightness, color, contrast need no check 0-65535 */ - memcpy(&cam->vp, vp, sizeof(*vp)); - - /* update cam->params.colorParams */ - cam->params.color_params.brightness = vp->brightness / 256; - cam->params.color_params.saturation = vp->colour / 256; - cam->params.color_params.contrast = vp->contrast / 256; - - DBG("Requested params: bright 0x%X, sat 0x%X, contrast 0x%X\n", - cam->params.color_params.brightness, - cam->params.color_params.saturation, - cam->params.color_params.contrast); - - cpia2_set_color_params(cam); - - return retval; -} - -static int sync(struct camera_data *cam, int frame_nr) -{ - struct framebuf *frame = &cam->buffers[frame_nr]; - - while (1) { - if (frame->status == FRAME_READY) - return 0; - - if (!cam->streaming) { - frame->status = FRAME_READY; - frame->length = 0; - return 0; - } - - mutex_unlock(&cam->busy_lock); - wait_event_interruptible(cam->wq_stream, - !cam->streaming || - frame->status == FRAME_READY); - mutex_lock(&cam->busy_lock); - if (signal_pending(current)) - return -ERESTARTSYS; - if(!cam->present) - return -ENOTTY; - } -} - -/****************************************************************************** - * - * ioctl_set_window_size - * - *****************************************************************************/ -static int ioctl_set_window_size(void *arg, struct camera_data *cam, - struct cpia2_fh *fh) -{ - /* copy_from_user, check validity, copy to internal structure */ - struct video_window *vw; - int frame, err; - vw = arg; - - if (vw->clipcount != 0) /* clipping not supported */ - return -EINVAL; - - if (vw->clips != NULL) /* clipping not supported */ - return -EINVAL; - - /* Ensure that only this process can change the format. */ - err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); - if(err != 0) - return err; - - cam->pixelformat = V4L2_PIX_FMT_JPEG; - - /* Be sure to supply the Huffman tables, this isn't MJPEG */ - cam->params.compression.inhibit_htables = 0; - - /* we set the video window to something smaller or equal to what - * is requested by the user??? - */ - DBG("Requested width = %d, height = %d\n", vw->width, vw->height); - if (vw->width != cam->vw.width || vw->height != cam->vw.height) { - cam->vw.width = vw->width; - cam->vw.height = vw->height; - cam->params.roi.width = vw->width; - cam->params.roi.height = vw->height; - cpia2_set_format(cam); - } - - for (frame = 0; frame < cam->num_frames; ++frame) { - if (cam->buffers[frame].status == FRAME_READING) - if ((err = sync(cam, frame)) < 0) - return err; - - cam->buffers[frame].status = FRAME_EMPTY; - } - - return 0; -} - -/****************************************************************************** - * - * ioctl_get_mbuf - * - *****************************************************************************/ -static int ioctl_get_mbuf(void *arg, struct camera_data *cam) -{ - struct video_mbuf *vm; - int i; - vm = arg; - - memset(vm, 0, sizeof(*vm)); - vm->size = cam->frame_size*cam->num_frames; - vm->frames = cam->num_frames; - for (i = 0; i < cam->num_frames; i++) - vm->offsets[i] = cam->frame_size * i; - - return 0; -} - -/****************************************************************************** - * - * ioctl_mcapture - * - *****************************************************************************/ -static int ioctl_mcapture(void *arg, struct camera_data *cam, - struct cpia2_fh *fh) -{ - struct video_mmap *vm; - int video_size, err; - vm = arg; - - if (vm->frame < 0 || vm->frame >= cam->num_frames) - return -EINVAL; - - /* set video size */ - video_size = cpia2_match_video_size(vm->width, vm->height); - if (cam->video_size < 0) { - return -EINVAL; - } - - /* Ensure that only this process can change the format. */ - err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); - if(err != 0) - return err; - - if (video_size != cam->video_size) { - cam->video_size = video_size; - cam->params.roi.width = vm->width; - cam->params.roi.height = vm->height; - cpia2_set_format(cam); - } - - if (cam->buffers[vm->frame].status == FRAME_READING) - if ((err=sync(cam, vm->frame)) < 0) - return err; - - cam->buffers[vm->frame].status = FRAME_EMPTY; - - return cpia2_usb_stream_start(cam,cam->params.camera_state.stream_mode); -} - -/****************************************************************************** - * - * ioctl_sync - * - *****************************************************************************/ -static int ioctl_sync(void *arg, struct camera_data *cam) -{ - int frame; - - frame = *(int*)arg; - - if (frame < 0 || frame >= cam->num_frames) - return -EINVAL; - - return sync(cam, frame); -} - - -/****************************************************************************** - * - * ioctl_set_gpio - * - *****************************************************************************/ - -static int ioctl_set_gpio(void *arg, struct camera_data *cam) -{ - __u32 gpio_val; - - gpio_val = *(__u32*) arg; - - if (gpio_val &~ 0xFFU) - return -EINVAL; - - return cpia2_set_gpio(cam, (unsigned char)gpio_val); -} - -/****************************************************************************** - * - * ioctl_querycap - * - * V4L2 device capabilities - * - *****************************************************************************/ - -static int ioctl_querycap(void *arg, struct camera_data *cam) -{ - struct v4l2_capability *vc = arg; - - memset(vc, 0, sizeof(*vc)); - strcpy(vc->driver, "cpia2"); - - if (cam->params.pnp_id.product == 0x151) - strcpy(vc->card, "QX5 Microscope"); - else - strcpy(vc->card, "CPiA2 Camera"); - switch (cam->params.pnp_id.device_type) { - case DEVICE_STV_672: - strcat(vc->card, " (672/"); - break; - case DEVICE_STV_676: - strcat(vc->card, " (676/"); - break; - default: - strcat(vc->card, " (???/"); - break; - } - switch (cam->params.version.sensor_flags) { - case CPIA2_VP_SENSOR_FLAGS_404: - strcat(vc->card, "404)"); - break; - case CPIA2_VP_SENSOR_FLAGS_407: - strcat(vc->card, "407)"); - break; - case CPIA2_VP_SENSOR_FLAGS_409: - strcat(vc->card, "409)"); - break; - case CPIA2_VP_SENSOR_FLAGS_410: - strcat(vc->card, "410)"); - break; - case CPIA2_VP_SENSOR_FLAGS_500: - strcat(vc->card, "500)"); - break; - default: - strcat(vc->card, "???)"); - break; - } - - if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0) - memset(vc->bus_info,0, sizeof(vc->bus_info)); - - vc->version = KERNEL_VERSION(CPIA2_MAJ_VER, CPIA2_MIN_VER, - CPIA2_PATCH_VER); - - vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - - return 0; -} - -/****************************************************************************** - * - * ioctl_input - * - * V4L2 input get/set/enumerate - * - *****************************************************************************/ - -static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam) -{ - struct v4l2_input *i = arg; - - if(ioclt_nr != VIDIOC_G_INPUT) { - if (i->index != 0) - return -EINVAL; - } - - memset(i, 0, sizeof(*i)); - strcpy(i->name, "Camera"); - i->type = V4L2_INPUT_TYPE_CAMERA; - - return 0; -} - -/****************************************************************************** - * - * ioctl_enum_fmt - * - * V4L2 format enumerate - * - *****************************************************************************/ - -static int ioctl_enum_fmt(void *arg,struct camera_data *cam) -{ - struct v4l2_fmtdesc *f = arg; - int index = f->index; - - if (index < 0 || index > 1) - return -EINVAL; - - memset(f, 0, sizeof(*f)); - f->index = index; - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->flags = V4L2_FMT_FLAG_COMPRESSED; - switch(index) { - case 0: - strcpy(f->description, "MJPEG"); - f->pixelformat = V4L2_PIX_FMT_MJPEG; - break; - case 1: - strcpy(f->description, "JPEG"); - f->pixelformat = V4L2_PIX_FMT_JPEG; - break; - default: - return -EINVAL; - } - - return 0; -} - -/****************************************************************************** - * - * ioctl_try_fmt - * - * V4L2 format try - * - *****************************************************************************/ - -static int ioctl_try_fmt(void *arg,struct camera_data *cam) -{ - struct v4l2_format *f = arg; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG && - f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) - return -EINVAL; - - f->fmt.pix.field = V4L2_FIELD_NONE; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = cam->frame_size; - f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; - f->fmt.pix.priv = 0; - - switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) { - case VIDEOSIZE_VGA: - f->fmt.pix.width = 640; - f->fmt.pix.height = 480; - break; - case VIDEOSIZE_CIF: - f->fmt.pix.width = 352; - f->fmt.pix.height = 288; - break; - case VIDEOSIZE_QVGA: - f->fmt.pix.width = 320; - f->fmt.pix.height = 240; - break; - case VIDEOSIZE_288_216: - f->fmt.pix.width = 288; - f->fmt.pix.height = 216; - break; - case VIDEOSIZE_256_192: - f->fmt.pix.width = 256; - f->fmt.pix.height = 192; - break; - case VIDEOSIZE_224_168: - f->fmt.pix.width = 224; - f->fmt.pix.height = 168; - break; - case VIDEOSIZE_192_144: - f->fmt.pix.width = 192; - f->fmt.pix.height = 144; - break; - case VIDEOSIZE_QCIF: - default: - f->fmt.pix.width = 176; - f->fmt.pix.height = 144; - break; - } - - return 0; -} - -/****************************************************************************** - * - * ioctl_set_fmt - * - * V4L2 format set - * - *****************************************************************************/ - -static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) -{ - struct v4l2_format *f = arg; - int err, frame; - - err = ioctl_try_fmt(arg, cam); - if(err != 0) - return err; - - /* Ensure that only this process can change the format. */ - err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); - if(err != 0) { - return err; - } - - cam->pixelformat = f->fmt.pix.pixelformat; - - /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle - * the missing Huffman table properly. */ - cam->params.compression.inhibit_htables = 0; - /*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/ - - /* we set the video window to something smaller or equal to what - * is requested by the user??? - */ - DBG("Requested width = %d, height = %d\n", - f->fmt.pix.width, f->fmt.pix.height); - if (f->fmt.pix.width != cam->vw.width || - f->fmt.pix.height != cam->vw.height) { - cam->vw.width = f->fmt.pix.width; - cam->vw.height = f->fmt.pix.height; - cam->params.roi.width = f->fmt.pix.width; - cam->params.roi.height = f->fmt.pix.height; - cpia2_set_format(cam); - } - - for (frame = 0; frame < cam->num_frames; ++frame) { - if (cam->buffers[frame].status == FRAME_READING) - if ((err = sync(cam, frame)) < 0) - return err; - - cam->buffers[frame].status = FRAME_EMPTY; - } - - return 0; -} - -/****************************************************************************** - * - * ioctl_get_fmt - * - * V4L2 format get - * - *****************************************************************************/ - -static int ioctl_get_fmt(void *arg,struct camera_data *cam) -{ - struct v4l2_format *f = arg; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - f->fmt.pix.width = cam->vw.width; - f->fmt.pix.height = cam->vw.height; - f->fmt.pix.pixelformat = cam->pixelformat; - f->fmt.pix.field = V4L2_FIELD_NONE; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = cam->frame_size; - f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; - f->fmt.pix.priv = 0; - - return 0; -} - -/****************************************************************************** - * - * ioctl_cropcap - * - * V4L2 query cropping capabilities - * NOTE: cropping is currently disabled - * - *****************************************************************************/ - -static int ioctl_cropcap(void *arg,struct camera_data *cam) -{ - struct v4l2_cropcap *c = arg; - - if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - c->bounds.left = 0; - c->bounds.top = 0; - c->bounds.width = cam->vw.width; - c->bounds.height = cam->vw.height; - c->defrect.left = 0; - c->defrect.top = 0; - c->defrect.width = cam->vw.width; - c->defrect.height = cam->vw.height; - c->pixelaspect.numerator = 1; - c->pixelaspect.denominator = 1; - - return 0; -} - -/****************************************************************************** - * - * ioctl_queryctrl - * - * V4L2 query possible control variables - * - *****************************************************************************/ - -static int ioctl_queryctrl(void *arg,struct camera_data *cam) -{ - struct v4l2_queryctrl *c = arg; - int i; - - for(i=0; iid == controls[i].id) { - memcpy(c, controls+i, sizeof(*c)); - break; - } - } - - if(i == NUM_CONTROLS) - return -EINVAL; - - /* Some devices have additional limitations */ - switch(c->id) { - case V4L2_CID_BRIGHTNESS: - /*** - * Don't let the register be set to zero - bug in VP4 - * flash of full brightness - ***/ - if (cam->params.pnp_id.device_type == DEVICE_STV_672) - c->minimum = 1; - break; - case V4L2_CID_VFLIP: - // VP5 Only - if(cam->params.pnp_id.device_type == DEVICE_STV_672) - c->flags |= V4L2_CTRL_FLAG_DISABLED; - break; - case CPIA2_CID_FRAMERATE: - if(cam->params.pnp_id.device_type == DEVICE_STV_672 && - cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ - // Maximum 15fps - int i; - for(i=0; imaximum; ++i) { - if(framerate_controls[i].value == - CPIA2_VP_FRAMERATE_15) { - c->maximum = i; - c->default_value = i; - } - } - } - break; - case CPIA2_CID_FLICKER_MODE: - // Flicker control only valid for 672. - if(cam->params.pnp_id.device_type != DEVICE_STV_672) - c->flags |= V4L2_CTRL_FLAG_DISABLED; - break; - case CPIA2_CID_LIGHTS: - // Light control only valid for the QX5 Microscope. - if(cam->params.pnp_id.product != 0x151) - c->flags |= V4L2_CTRL_FLAG_DISABLED; - break; - default: - break; - } - - return 0; -} - -/****************************************************************************** - * - * ioctl_querymenu - * - * V4L2 query possible control variables - * - *****************************************************************************/ - -static int ioctl_querymenu(void *arg,struct camera_data *cam) -{ - struct v4l2_querymenu *m = arg; - - memset(m->name, 0, sizeof(m->name)); - m->reserved = 0; - - switch(m->id) { - case CPIA2_CID_FLICKER_MODE: - if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS) - return -EINVAL; - - strcpy(m->name, flicker_controls[m->index].name); - break; - case CPIA2_CID_FRAMERATE: - { - int maximum = NUM_FRAMERATE_CONTROLS - 1; - if(cam->params.pnp_id.device_type == DEVICE_STV_672 && - cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ - // Maximum 15fps - int i; - for(i=0; iindex < 0 || m->index > maximum) - return -EINVAL; - - strcpy(m->name, framerate_controls[m->index].name); - break; - } - case CPIA2_CID_LIGHTS: - if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS) - return -EINVAL; - - strcpy(m->name, lights_controls[m->index].name); - break; - default: - return -EINVAL; - } - - return 0; -} - -/****************************************************************************** - * - * ioctl_g_ctrl - * - * V4L2 get the value of a control variable - * - *****************************************************************************/ - -static int ioctl_g_ctrl(void *arg,struct camera_data *cam) -{ - struct v4l2_control *c = arg; - - switch(c->id) { - case V4L2_CID_BRIGHTNESS: - cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, - TRANSFER_READ, 0); - c->value = cam->params.color_params.brightness; - break; - case V4L2_CID_CONTRAST: - cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, - TRANSFER_READ, 0); - c->value = cam->params.color_params.contrast; - break; - case V4L2_CID_SATURATION: - cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, - TRANSFER_READ, 0); - c->value = cam->params.color_params.saturation; - break; - case V4L2_CID_HFLIP: - cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, - TRANSFER_READ, 0); - c->value = (cam->params.vp_params.user_effects & - CPIA2_VP_USER_EFFECTS_MIRROR) != 0; - break; - case V4L2_CID_VFLIP: - cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, - TRANSFER_READ, 0); - c->value = (cam->params.vp_params.user_effects & - CPIA2_VP_USER_EFFECTS_FLIP) != 0; - break; - case CPIA2_CID_TARGET_KB: - c->value = cam->params.vc_params.target_kb; - break; - case CPIA2_CID_GPIO: - cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA, - TRANSFER_READ, 0); - c->value = cam->params.vp_params.gpio_data; - break; - case CPIA2_CID_FLICKER_MODE: - { - int i, mode; - cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES, - TRANSFER_READ, 0); - if(cam->params.flicker_control.cam_register & - CPIA2_VP_FLICKER_MODES_NEVER_FLICKER) { - mode = NEVER_FLICKER; - } else { - if(cam->params.flicker_control.cam_register & - CPIA2_VP_FLICKER_MODES_50HZ) { - mode = FLICKER_50; - } else { - mode = FLICKER_60; - } - } - for(i=0; ivalue = i; - break; - } - } - if(i == NUM_FLICKER_CONTROLS) - return -EINVAL; - break; - } - case CPIA2_CID_FRAMERATE: - { - int maximum = NUM_FRAMERATE_CONTROLS - 1; - int i; - for(i=0; i<= maximum; i++) { - if(cam->params.vp_params.frame_rate == - framerate_controls[i].value) - break; - } - if(i > maximum) - return -EINVAL; - c->value = i; - break; - } - case CPIA2_CID_USB_ALT: - c->value = cam->params.camera_state.stream_mode; - break; - case CPIA2_CID_LIGHTS: - { - int i; - cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA, - TRANSFER_READ, 0); - for(i=0; iparams.vp_params.gpio_data&GPIO_LIGHTS_MASK) == - lights_controls[i].value) { - break; - } - } - if(i == NUM_LIGHTS_CONTROLS) - return -EINVAL; - c->value = i; - break; - } - case CPIA2_CID_RESET_CAMERA: - return -EINVAL; - default: - return -EINVAL; - } - - DBG("Get control id:%d, value:%d\n", c->id, c->value); - - return 0; -} - -/****************************************************************************** - * - * ioctl_s_ctrl - * - * V4L2 set the value of a control variable - * - *****************************************************************************/ - -static int ioctl_s_ctrl(void *arg,struct camera_data *cam) -{ - struct v4l2_control *c = arg; - int i; - int retval = 0; - - DBG("Set control id:%d, value:%d\n", c->id, c->value); - - /* Check that the value is in range */ - for(i=0; iid == controls[i].id) { - if(c->value < controls[i].minimum || - c->value > controls[i].maximum) { - return -EINVAL; - } - break; - } - } - if(i == NUM_CONTROLS) - return -EINVAL; - - switch(c->id) { - case V4L2_CID_BRIGHTNESS: - cpia2_set_brightness(cam, c->value); - break; - case V4L2_CID_CONTRAST: - cpia2_set_contrast(cam, c->value); - break; - case V4L2_CID_SATURATION: - cpia2_set_saturation(cam, c->value); - break; - case V4L2_CID_HFLIP: - cpia2_set_property_mirror(cam, c->value); - break; - case V4L2_CID_VFLIP: - cpia2_set_property_flip(cam, c->value); - break; - case CPIA2_CID_TARGET_KB: - retval = cpia2_set_target_kb(cam, c->value); - break; - case CPIA2_CID_GPIO: - retval = cpia2_set_gpio(cam, c->value); - break; - case CPIA2_CID_FLICKER_MODE: - retval = cpia2_set_flicker_mode(cam, - flicker_controls[c->value].value); - break; - case CPIA2_CID_FRAMERATE: - retval = cpia2_set_fps(cam, framerate_controls[c->value].value); - break; - case CPIA2_CID_USB_ALT: - retval = cpia2_usb_change_streaming_alternate(cam, c->value); - break; - case CPIA2_CID_LIGHTS: - retval = cpia2_set_gpio(cam, lights_controls[c->value].value); - break; - case CPIA2_CID_RESET_CAMERA: - cpia2_usb_stream_pause(cam); - cpia2_reset_camera(cam); - cpia2_usb_stream_resume(cam); - break; - default: - retval = -EINVAL; - } - - return retval; -} - -/****************************************************************************** - * - * ioctl_g_jpegcomp - * - * V4L2 get the JPEG compression parameters - * - *****************************************************************************/ - -static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam) -{ - struct v4l2_jpegcompression *parms = arg; - - memset(parms, 0, sizeof(*parms)); - - parms->quality = 80; // TODO: Can this be made meaningful? - - parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI; - if(!cam->params.compression.inhibit_htables) { - parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT; - } - - parms->APPn = cam->APPn; - parms->APP_len = cam->APP_len; - if(cam->APP_len > 0) { - memcpy(parms->APP_data, cam->APP_data, cam->APP_len); - parms->jpeg_markers |= V4L2_JPEG_MARKER_APP; - } - - parms->COM_len = cam->COM_len; - if(cam->COM_len > 0) { - memcpy(parms->COM_data, cam->COM_data, cam->COM_len); - parms->jpeg_markers |= JPEG_MARKER_COM; - } - - DBG("G_JPEGCOMP APP_len:%d COM_len:%d\n", - parms->APP_len, parms->COM_len); - - return 0; -} - -/****************************************************************************** - * - * ioctl_s_jpegcomp - * - * V4L2 set the JPEG compression parameters - * NOTE: quality and some jpeg_markers are ignored. - * - *****************************************************************************/ - -static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam) -{ - struct v4l2_jpegcompression *parms = arg; - - DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n", - parms->APP_len, parms->COM_len); - - cam->params.compression.inhibit_htables = - !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT); - - if(parms->APP_len != 0) { - if(parms->APP_len > 0 && - parms->APP_len <= sizeof(cam->APP_data) && - parms->APPn >= 0 && parms->APPn <= 15) { - cam->APPn = parms->APPn; - cam->APP_len = parms->APP_len; - memcpy(cam->APP_data, parms->APP_data, parms->APP_len); - } else { - LOG("Bad APPn Params n=%d len=%d\n", - parms->APPn, parms->APP_len); - return -EINVAL; - } - } else { - cam->APP_len = 0; - } - - if(parms->COM_len != 0) { - if(parms->COM_len > 0 && - parms->COM_len <= sizeof(cam->COM_data)) { - cam->COM_len = parms->COM_len; - memcpy(cam->COM_data, parms->COM_data, parms->COM_len); - } else { - LOG("Bad COM_len=%d\n", parms->COM_len); - return -EINVAL; - } - } - - return 0; -} - -/****************************************************************************** - * - * ioctl_reqbufs - * - * V4L2 Initiate memory mapping. - * NOTE: The user's request is ignored. For now the buffers are fixed. - * - *****************************************************************************/ - -static int ioctl_reqbufs(void *arg,struct camera_data *cam) -{ - struct v4l2_requestbuffers *req = arg; - - if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - req->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames); - req->count = cam->num_frames; - memset(&req->reserved, 0, sizeof(req->reserved)); - - return 0; -} - -/****************************************************************************** - * - * ioctl_querybuf - * - * V4L2 Query memory buffer status. - * - *****************************************************************************/ - -static int ioctl_querybuf(void *arg,struct camera_data *cam) -{ - struct v4l2_buffer *buf = arg; - - if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf->index > cam->num_frames) - return -EINVAL; - - buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; - buf->length = cam->frame_size; - - buf->memory = V4L2_MEMORY_MMAP; - - if(cam->mmapped) - buf->flags = V4L2_BUF_FLAG_MAPPED; - else - buf->flags = 0; - - switch (cam->buffers[buf->index].status) { - case FRAME_EMPTY: - case FRAME_ERROR: - case FRAME_READING: - buf->bytesused = 0; - buf->flags = V4L2_BUF_FLAG_QUEUED; - break; - case FRAME_READY: - buf->bytesused = cam->buffers[buf->index].length; - buf->timestamp = cam->buffers[buf->index].timestamp; - buf->sequence = cam->buffers[buf->index].seq; - buf->flags = V4L2_BUF_FLAG_DONE; - break; - } - - DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n", - buf->index, buf->m.offset, buf->flags, buf->sequence, - buf->bytesused); - - return 0; -} - -/****************************************************************************** - * - * ioctl_qbuf - * - * V4L2 User is freeing buffer - * - *****************************************************************************/ - -static int ioctl_qbuf(void *arg,struct camera_data *cam) -{ - struct v4l2_buffer *buf = arg; - - if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf->memory != V4L2_MEMORY_MMAP || - buf->index > cam->num_frames) - return -EINVAL; - - DBG("QBUF #%d\n", buf->index); - - if(cam->buffers[buf->index].status == FRAME_READY) - cam->buffers[buf->index].status = FRAME_EMPTY; - - return 0; -} - -/****************************************************************************** - * - * find_earliest_filled_buffer - * - * Helper for ioctl_dqbuf. Find the next ready buffer. - * - *****************************************************************************/ - -static int find_earliest_filled_buffer(struct camera_data *cam) -{ - int i; - int found = -1; - for (i=0; inum_frames; i++) { - if(cam->buffers[i].status == FRAME_READY) { - if(found < 0) { - found = i; - } else { - /* find which buffer is earlier */ - struct timeval *tv1, *tv2; - tv1 = &cam->buffers[i].timestamp; - tv2 = &cam->buffers[found].timestamp; - if(tv1->tv_sec < tv2->tv_sec || - (tv1->tv_sec == tv2->tv_sec && - tv1->tv_usec < tv2->tv_usec)) - found = i; - } - } - } - return found; -} - -/****************************************************************************** - * - * ioctl_dqbuf - * - * V4L2 User is asking for a filled buffer. - * - *****************************************************************************/ - -static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) -{ - struct v4l2_buffer *buf = arg; - int frame; - - if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - frame = find_earliest_filled_buffer(cam); - - if(frame < 0 && file->f_flags&O_NONBLOCK) - return -EAGAIN; - - if(frame < 0) { - /* Wait for a frame to become available */ - struct framebuf *cb=cam->curbuff; - mutex_unlock(&cam->busy_lock); - wait_event_interruptible(cam->wq_stream, - !cam->present || - (cb=cam->curbuff)->status == FRAME_READY); - mutex_lock(&cam->busy_lock); - if (signal_pending(current)) - return -ERESTARTSYS; - if(!cam->present) - return -ENOTTY; - frame = cb->num; - } - - - buf->index = frame; - buf->bytesused = cam->buffers[buf->index].length; - buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; - buf->field = V4L2_FIELD_NONE; - buf->timestamp = cam->buffers[buf->index].timestamp; - buf->sequence = cam->buffers[buf->index].seq; - buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; - buf->length = cam->frame_size; - buf->input = 0; - buf->reserved = 0; - memset(&buf->timecode, 0, sizeof(buf->timecode)); - - DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index, - cam->buffers[buf->index].status, buf->sequence, buf->bytesused); - - return 0; -} - -/****************************************************************************** - * - * cpia2_ioctl - * - *****************************************************************************/ -static int cpia2_do_ioctl(struct inode *inode, struct file *file, - unsigned int ioctl_nr, void *arg) -{ - struct video_device *dev = video_devdata(file); - struct camera_data *cam = video_get_drvdata(dev); - int retval = 0; - - if (!cam) - return -ENOTTY; - - /* make this _really_ smp-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) - return -ERESTARTSYS; - - if (!cam->present) { - mutex_unlock(&cam->busy_lock); - return -ENODEV; - } - - /* Priority check */ - switch (ioctl_nr) { - case VIDIOCSWIN: - case VIDIOCMCAPTURE: - case VIDIOC_S_FMT: - { - struct cpia2_fh *fh = file->private_data; - retval = v4l2_prio_check(&cam->prio, &fh->prio); - if(retval) { - mutex_unlock(&cam->busy_lock); - return retval; - } - break; - } - case VIDIOCGMBUF: - case VIDIOCSYNC: - { - struct cpia2_fh *fh = file->private_data; - if(fh->prio != V4L2_PRIORITY_RECORD) { - mutex_unlock(&cam->busy_lock); - return -EBUSY; - } - break; - } - default: - break; - } - - switch (ioctl_nr) { - case VIDIOCGCAP: /* query capabilities */ - retval = ioctl_cap_query(arg, cam); - break; - - case VIDIOCGCHAN: /* get video source - we are a camera, nothing else */ - retval = ioctl_get_channel(arg); - break; - case VIDIOCSCHAN: /* set video source - we are a camera, nothing else */ - retval = ioctl_set_channel(arg); - break; - case VIDIOCGPICT: /* image properties */ - memcpy(arg, &cam->vp, sizeof(struct video_picture)); - break; - case VIDIOCSPICT: - retval = ioctl_set_image_prop(arg, cam); - break; - case VIDIOCGWIN: /* get/set capture window */ - memcpy(arg, &cam->vw, sizeof(struct video_window)); - break; - case VIDIOCSWIN: - retval = ioctl_set_window_size(arg, cam, file->private_data); - break; - case VIDIOCGMBUF: /* mmap interface */ - retval = ioctl_get_mbuf(arg, cam); - break; - case VIDIOCMCAPTURE: - retval = ioctl_mcapture(arg, cam, file->private_data); - break; - case VIDIOCSYNC: - retval = ioctl_sync(arg, cam); - break; - /* pointless to implement overlay with this camera */ - case VIDIOCCAPTURE: - case VIDIOCGFBUF: - case VIDIOCSFBUF: - case VIDIOCKEY: - retval = -EINVAL; - break; - - /* tuner interface - we have none */ - case VIDIOCGTUNER: - case VIDIOCSTUNER: - case VIDIOCGFREQ: - case VIDIOCSFREQ: - retval = -EINVAL; - break; - - /* audio interface - we have none */ - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - retval = -EINVAL; - break; - - /* CPIA2 extension to Video4Linux API */ - case CPIA2_IOC_SET_GPIO: - retval = ioctl_set_gpio(arg, cam); - break; - case VIDIOC_QUERYCAP: - retval = ioctl_querycap(arg,cam); - break; - - case VIDIOC_ENUMINPUT: - case VIDIOC_G_INPUT: - case VIDIOC_S_INPUT: - retval = ioctl_input(ioctl_nr, arg,cam); - break; - - case VIDIOC_ENUM_FMT: - retval = ioctl_enum_fmt(arg,cam); - break; - case VIDIOC_TRY_FMT: - retval = ioctl_try_fmt(arg,cam); - break; - case VIDIOC_G_FMT: - retval = ioctl_get_fmt(arg,cam); - break; - case VIDIOC_S_FMT: - retval = ioctl_set_fmt(arg,cam,file->private_data); - break; - - case VIDIOC_CROPCAP: - retval = ioctl_cropcap(arg,cam); - break; - case VIDIOC_G_CROP: - case VIDIOC_S_CROP: - // TODO: I think cropping can be implemented - SJB - retval = -EINVAL; - break; - - case VIDIOC_QUERYCTRL: - retval = ioctl_queryctrl(arg,cam); - break; - case VIDIOC_QUERYMENU: - retval = ioctl_querymenu(arg,cam); - break; - case VIDIOC_G_CTRL: - retval = ioctl_g_ctrl(arg,cam); - break; - case VIDIOC_S_CTRL: - retval = ioctl_s_ctrl(arg,cam); - break; - - case VIDIOC_G_JPEGCOMP: - retval = ioctl_g_jpegcomp(arg,cam); - break; - case VIDIOC_S_JPEGCOMP: - retval = ioctl_s_jpegcomp(arg,cam); - break; - - case VIDIOC_G_PRIORITY: - { - struct cpia2_fh *fh = file->private_data; - *(enum v4l2_priority*)arg = fh->prio; - break; - } - case VIDIOC_S_PRIORITY: - { - struct cpia2_fh *fh = file->private_data; - enum v4l2_priority prio; - prio = *(enum v4l2_priority*)arg; - if(cam->streaming && - prio != fh->prio && - fh->prio == V4L2_PRIORITY_RECORD) { - /* Can't drop record priority while streaming */ - retval = -EBUSY; - } else if(prio == V4L2_PRIORITY_RECORD && - prio != fh->prio && - v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) { - /* Only one program can record at a time */ - retval = -EBUSY; - } else { - retval = v4l2_prio_change(&cam->prio, &fh->prio, prio); - } - break; - } - - case VIDIOC_REQBUFS: - retval = ioctl_reqbufs(arg,cam); - break; - case VIDIOC_QUERYBUF: - retval = ioctl_querybuf(arg,cam); - break; - case VIDIOC_QBUF: - retval = ioctl_qbuf(arg,cam); - break; - case VIDIOC_DQBUF: - retval = ioctl_dqbuf(arg,cam,file); - break; - case VIDIOC_STREAMON: - { - int type; - DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming); - type = *(int*)arg; - if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - retval = -EINVAL; - - if(!cam->streaming) { - retval = cpia2_usb_stream_start(cam, - cam->params.camera_state.stream_mode); - } else { - retval = -EINVAL; - } - - break; - } - case VIDIOC_STREAMOFF: - { - int type; - DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming); - type = *(int*)arg; - if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - retval = -EINVAL; - - if(cam->streaming) { - retval = cpia2_usb_stream_stop(cam); - } else { - retval = -EINVAL; - } - - break; - } - - case VIDIOC_ENUMOUTPUT: - case VIDIOC_G_OUTPUT: - case VIDIOC_S_OUTPUT: - case VIDIOC_G_MODULATOR: - case VIDIOC_S_MODULATOR: - - case VIDIOC_ENUMAUDIO: - case VIDIOC_G_AUDIO: - case VIDIOC_S_AUDIO: - - case VIDIOC_ENUMAUDOUT: - case VIDIOC_G_AUDOUT: - case VIDIOC_S_AUDOUT: - - case VIDIOC_ENUMSTD: - case VIDIOC_QUERYSTD: - case VIDIOC_G_STD: - case VIDIOC_S_STD: - - case VIDIOC_G_TUNER: - case VIDIOC_S_TUNER: - case VIDIOC_G_FREQUENCY: - case VIDIOC_S_FREQUENCY: - - case VIDIOC_OVERLAY: - case VIDIOC_G_FBUF: - case VIDIOC_S_FBUF: - - case VIDIOC_G_PARM: - case VIDIOC_S_PARM: - retval = -EINVAL; - break; - default: - retval = -ENOIOCTLCMD; - break; - } - - mutex_unlock(&cam->busy_lock); - return retval; -} - -static int cpia2_ioctl(struct inode *inode, struct file *file, - unsigned int ioctl_nr, unsigned long iarg) -{ - return video_usercopy(inode, file, ioctl_nr, iarg, cpia2_do_ioctl); -} - -/****************************************************************************** - * - * cpia2_mmap - * - *****************************************************************************/ -static int cpia2_mmap(struct file *file, struct vm_area_struct *area) -{ - int retval; - struct video_device *dev = video_devdata(file); - struct camera_data *cam = video_get_drvdata(dev); - - /* Priority check */ - struct cpia2_fh *fh = file->private_data; - if(fh->prio != V4L2_PRIORITY_RECORD) { - return -EBUSY; - } - - retval = cpia2_remap_buffer(cam, area); - - if(!retval) - fh->mmapped = 1; - return retval; -} - -/****************************************************************************** - * - * reset_camera_struct_v4l - * - * Sets all values to the defaults - *****************************************************************************/ -static void reset_camera_struct_v4l(struct camera_data *cam) -{ - /*** - * Fill in the v4l structures. video_cap is filled in inside the VIDIOCCAP - * Ioctl. Here, just do the window and picture stucts. - ***/ - cam->vp.palette = (u16) VIDEO_PALETTE_RGB24; /* Is this right? */ - cam->vp.brightness = (u16) cam->params.color_params.brightness * 256; - cam->vp.colour = (u16) cam->params.color_params.saturation * 256; - cam->vp.contrast = (u16) cam->params.color_params.contrast * 256; - - cam->vw.x = 0; - cam->vw.y = 0; - cam->vw.width = cam->params.roi.width; - cam->vw.height = cam->params.roi.height; - cam->vw.flags = 0; - cam->vw.clipcount = 0; - - cam->frame_size = buffer_size; - cam->num_frames = num_buffers; - - /* FlickerModes */ - cam->params.flicker_control.flicker_mode_req = flicker_mode; - cam->params.flicker_control.mains_frequency = flicker_freq; - - /* streamMode */ - cam->params.camera_state.stream_mode = alternate; - - cam->pixelformat = V4L2_PIX_FMT_JPEG; - v4l2_prio_init(&cam->prio); - return; -} - -/*** - * The v4l video device structure initialized for this device - ***/ -static struct file_operations fops_template = { - .owner = THIS_MODULE, - .open = cpia2_open, - .release = cpia2_close, - .read = cpia2_v4l_read, - .poll = cpia2_v4l_poll, - .ioctl = cpia2_ioctl, - .llseek = no_llseek, - .compat_ioctl = v4l_compat_ioctl32, - .mmap = cpia2_mmap, -}; - -static struct video_device cpia2_template = { - /* I could not find any place for the old .initialize initializer?? */ - .owner= THIS_MODULE, - .name= "CPiA2 Camera", - .type= VID_TYPE_CAPTURE, - .type2 = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING, - .hardware= VID_HARDWARE_CPIA2, - .minor= -1, - .fops= &fops_template, - .release= video_device_release, -}; - -/****************************************************************************** - * - * cpia2_register_camera - * - *****************************************************************************/ -int cpia2_register_camera(struct camera_data *cam) -{ - cam->vdev = video_device_alloc(); - if(!cam->vdev) - return -ENOMEM; - - memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template)); - video_set_drvdata(cam->vdev, cam); - - reset_camera_struct_v4l(cam); - - /* register v4l device */ - if (video_register_device - (cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { - ERR("video_register_device failed\n"); - video_device_release(cam->vdev); - return -ENODEV; - } - - return 0; -} - -/****************************************************************************** - * - * cpia2_unregister_camera - * - *****************************************************************************/ -void cpia2_unregister_camera(struct camera_data *cam) -{ - if (!cam->open_count) { - video_unregister_device(cam->vdev); - } else { - LOG("/dev/video%d removed while open, " - "deferring video_unregister_device\n", - cam->vdev->minor); - } -} - -/****************************************************************************** - * - * check_parameters - * - * Make sure that all user-supplied parameters are sensible - *****************************************************************************/ -static void __init check_parameters(void) -{ - if(buffer_size < PAGE_SIZE) { - buffer_size = PAGE_SIZE; - LOG("buffer_size too small, setting to %d\n", buffer_size); - } else if(buffer_size > 1024*1024) { - /* arbitrary upper limiit */ - buffer_size = 1024*1024; - LOG("buffer_size ridiculously large, setting to %d\n", - buffer_size); - } else { - buffer_size += PAGE_SIZE-1; - buffer_size &= ~(PAGE_SIZE-1); - } - - if(num_buffers < 1) { - num_buffers = 1; - LOG("num_buffers too small, setting to %d\n", num_buffers); - } else if(num_buffers > VIDEO_MAX_FRAME) { - num_buffers = VIDEO_MAX_FRAME; - LOG("num_buffers too large, setting to %d\n", num_buffers); - } - - if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) { - alternate = DEFAULT_ALT; - LOG("alternate specified is invalid, using %d\n", alternate); - } - - if (flicker_mode != NEVER_FLICKER && flicker_mode != ANTI_FLICKER_ON) { - flicker_mode = NEVER_FLICKER; - LOG("Flicker mode specified is invalid, using %d\n", - flicker_mode); - } - - if (flicker_freq != FLICKER_50 && flicker_freq != FLICKER_60) { - flicker_freq = FLICKER_60; - LOG("Flicker mode specified is invalid, using %d\n", - flicker_freq); - } - - if(video_nr < -1 || video_nr > 64) { - video_nr = -1; - LOG("invalid video_nr specified, must be -1 to 64\n"); - } - - DBG("Using %d buffers, each %d bytes, alternate=%d\n", - num_buffers, buffer_size, alternate); -} - -/************ Module Stuff ***************/ - - -/****************************************************************************** - * - * cpia2_init/module_init - * - *****************************************************************************/ -static int __init cpia2_init(void) -{ - LOG("%s v%d.%d.%d\n", - ABOUT, CPIA2_MAJ_VER, CPIA2_MIN_VER, CPIA2_PATCH_VER); - check_parameters(); - cpia2_usb_init(); - return 0; -} - - -/****************************************************************************** - * - * cpia2_exit/module_exit - * - *****************************************************************************/ -static void __exit cpia2_exit(void) -{ - cpia2_usb_cleanup(); - schedule_timeout(2 * HZ); -} - -module_init(cpia2_init); -module_exit(cpia2_exit); - diff --git a/drivers/media/video/cpia2/cpia2dev.h b/drivers/media/video/cpia2/cpia2dev.h deleted file mode 100644 index d58097ce0..000000000 --- a/drivers/media/video/cpia2/cpia2dev.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** - * - * Filename: cpia2dev.h - * - * Copyright 2001, STMicrolectronics, Inc. - * - * Contact: steve.miller@st.com - * - * Description: - * This file provides definitions for applications wanting to use the - * cpia2 driver beyond the generic v4l capabilities. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 CPIA2_DEV_HEADER -#define CPIA2_DEV_HEADER - -#include - -/*** - * The following defines are ioctl numbers based on video4linux private ioctls, - * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int - * args - */ -#define CPIA2_IOC_SET_GPIO _IOW('v', BASE_VIDIOCPRIVATE + 17, __u32) - -/* V4L2 driver specific controls */ -#define CPIA2_CID_TARGET_KB (V4L2_CID_PRIVATE_BASE+0) -#define CPIA2_CID_GPIO (V4L2_CID_PRIVATE_BASE+1) -#define CPIA2_CID_FLICKER_MODE (V4L2_CID_PRIVATE_BASE+2) -#define CPIA2_CID_FRAMERATE (V4L2_CID_PRIVATE_BASE+3) -#define CPIA2_CID_USB_ALT (V4L2_CID_PRIVATE_BASE+4) -#define CPIA2_CID_LIGHTS (V4L2_CID_PRIVATE_BASE+5) -#define CPIA2_CID_RESET_CAMERA (V4L2_CID_PRIVATE_BASE+6) - -#endif diff --git a/drivers/media/video/cpia2/cpia2patch.h b/drivers/media/video/cpia2/cpia2patch.h deleted file mode 100644 index 7f085fbe7..000000000 --- a/drivers/media/video/cpia2/cpia2patch.h +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** - * - * Filename: cpia2patch.h - * - * Copyright 2001, STMicrolectronics, Inc. - * - * Contact: steve.miller@st.com - * - * Description: - * This file contains patch data for the CPiA2 (stv0672) VP4. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 CPIA2_PATCH_HEADER -#define CPIA2_PATCH_HEADER - -typedef struct { - unsigned char reg; - unsigned char count; - const unsigned char *data; -} cpia2_patch; - -static const unsigned char start_address_hi[1] = { - 0x01 -}; - -static const unsigned char start_address_lo[1] = { - 0xBC -}; - -static const unsigned char patch_block0[64] = { - 0xE3, 0x02, 0xE3, 0x03, 0xE3, 0x04, 0xE3, 0x05, - 0xE3, 0x06, 0xE3, 0x07, 0x93, 0x44, 0x56, 0xD4, - 0x93, 0x4E, 0x56, 0x51, 0x93, 0x4E, 0x51, 0xD6, - 0x93, 0x4E, 0x4F, 0x54, 0x93, 0x4E, 0x92, 0x4F, - 0x92, 0xA4, 0x93, 0x05, 0x92, 0xF4, 0x93, 0x1B, - 0x92, 0x92, 0x91, 0xE6, 0x92, 0x36, 0x92, 0x74, - 0x92, 0x4A, 0x92, 0x8C, 0x92, 0x8E, 0xC8, 0xD0, - 0x0B, 0x42, 0x02, 0xA0, 0xCA, 0x92, 0x09, 0x02 -}; - -static const unsigned char patch_block1[64] = { - 0xC9, 0x10, 0x0A, 0x0A, 0x0A, 0x81, 0xE3, 0xB8, - 0xE3, 0xB0, 0xE3, 0xA8, 0xE3, 0xA0, 0xE3, 0x98, - 0xE3, 0x90, 0xE1, 0x00, 0xCF, 0xD7, 0x0A, 0x12, - 0xCC, 0x95, 0x08, 0xB2, 0x0A, 0x18, 0xE1, 0x00, - 0x01, 0xEE, 0x0C, 0x08, 0x4A, 0x12, 0xC8, 0x18, - 0xF0, 0x9A, 0xC0, 0x22, 0xF3, 0x1C, 0x4A, 0x13, - 0xF3, 0x14, 0xC8, 0xA0, 0xF2, 0x14, 0xF2, 0x1C, - 0xEB, 0x13, 0xD3, 0xA2, 0x63, 0x16, 0x48, 0x9E -}; - -static const unsigned char patch_block2[64] = { - 0xF0, 0x18, 0xA4, 0x03, 0xF3, 0x93, 0xC0, 0x58, - 0xF7, 0x13, 0x51, 0x9C, 0xE9, 0x20, 0xCF, 0xEF, - 0x63, 0xF9, 0x92, 0x2E, 0xD3, 0x5F, 0x63, 0xFA, - 0x92, 0x2E, 0xD3, 0x67, 0x63, 0xFB, 0x92, 0x2E, - 0xD3, 0x6F, 0xE9, 0x1A, 0x63, 0x16, 0x48, 0xA7, - 0xF0, 0x20, 0xA4, 0x06, 0xF3, 0x94, 0xC0, 0x27, - 0xF7, 0x14, 0xF5, 0x13, 0x51, 0x9D, 0xF6, 0x13, - 0x63, 0x18, 0xC4, 0x20, 0xCB, 0xEF, 0x63, 0xFC -}; - -static const unsigned char patch_block3[64] = { - 0x92, 0x2E, 0xD3, 0x77, 0x63, 0xFD, 0x92, 0x2E, - 0xD3, 0x7F, 0x63, 0xFE, 0x92, 0x2E, 0xD3, 0x87, - 0x63, 0xFF, 0x92, 0x2E, 0xD3, 0x8F, 0x64, 0x38, - 0x92, 0x2E, 0xD3, 0x97, 0x64, 0x39, 0x92, 0x2E, - 0xD3, 0x9F, 0xE1, 0x00, 0xF5, 0x3A, 0xF4, 0x3B, - 0xF7, 0xBF, 0xF2, 0xBC, 0xF2, 0x3D, 0xE1, 0x00, - 0x80, 0x87, 0x90, 0x80, 0x51, 0xD5, 0x02, 0x22, - 0x02, 0x32, 0x4B, 0xD3, 0xF7, 0x11, 0x0B, 0xDA -}; - -static const unsigned char patch_block4[64] = { - 0xE1, 0x00, 0x0E, 0x02, 0x02, 0x40, 0x0D, 0xB5, - 0xE3, 0x02, 0x48, 0x55, 0xE5, 0x12, 0xA4, 0x01, - 0xE8, 0x1B, 0xE3, 0x90, 0xF0, 0x18, 0xA4, 0x01, - 0xE8, 0xBF, 0x8D, 0xB8, 0x4B, 0xD1, 0x4B, 0xD8, - 0x0B, 0xCB, 0x0B, 0xC2, 0xE1, 0x00, 0xE3, 0x02, - 0xE3, 0x03, 0x52, 0xD3, 0x60, 0x59, 0xE6, 0x93, - 0x0D, 0x22, 0x52, 0xD4, 0xE6, 0x93, 0x0D, 0x2A, - 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x5D -}; - -static const unsigned char patch_block5[64] = { - 0x02, 0x63, 0xE3, 0x02, 0xC8, 0x12, 0x02, 0xCA, - 0xC8, 0x52, 0x02, 0xC2, 0x82, 0x68, 0xE3, 0x02, - 0xC8, 0x14, 0x02, 0xCA, 0xC8, 0x90, 0x02, 0xC2, - 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA, 0xCC, 0xD2, - 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA, 0x0A, 0x98, - 0x0A, 0xA0, 0x0A, 0xA8, 0xE3, 0x90, 0xE1, 0x00, - 0xE3, 0x02, 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA, - 0xCC, 0xD2, 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA -}; - -static const unsigned char patch_block6[64] = { - 0x0A, 0x98, 0x0A, 0xA0, 0x0A, 0xA8, 0x49, 0x91, - 0xE5, 0x6A, 0xA4, 0x04, 0xC8, 0x12, 0x02, 0xCA, - 0xC8, 0x52, 0x82, 0x89, 0xC8, 0x14, 0x02, 0xCA, - 0xC8, 0x90, 0x02, 0xC2, 0xE3, 0x90, 0xE1, 0x00, - 0x08, 0x60, 0xE1, 0x00, 0x48, 0x53, 0xE8, 0x97, - 0x08, 0x5A, 0xE1, 0x00, 0xE3, 0x02, 0xE3, 0x03, - 0x54, 0xD3, 0x60, 0x59, 0xE6, 0x93, 0x0D, 0x52, - 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x9C -}; - -static const unsigned char patch_block7[64] = { - 0xE3, 0x02, 0x55, 0x13, 0x93, 0x17, 0x55, 0x13, - 0x93, 0x17, 0xE3, 0x90, 0xE1, 0x00, 0x75, 0x30, - 0xE3, 0x02, 0xE3, 0x03, 0x55, 0x55, 0x60, 0x59, - 0xE6, 0x93, 0x0D, 0xB2, 0xE3, 0x98, 0xE3, 0x90, - 0xE1, 0x00, 0x02, 0xAE, 0xE7, 0x92, 0xE9, 0x18, - 0xEA, 0x9A, 0xE8, 0x98, 0xE8, 0x10, 0xE8, 0x11, - 0xE8, 0x51, 0xD2, 0xDA, 0xD2, 0xF3, 0xE8, 0x13, - 0xD2, 0xFA, 0xE8, 0x50, 0xD2, 0xEA, 0xE8, 0xD0 -}; - -static const unsigned char patch_block8[64] = { - 0xE8, 0xD1, 0xD3, 0x0A, 0x03, 0x09, 0x48, 0x23, - 0xE5, 0x2C, 0xA0, 0x03, 0x48, 0x24, 0xEA, 0x1C, - 0x03, 0x08, 0xD2, 0xE3, 0xD3, 0x03, 0xD3, 0x13, - 0xE1, 0x00, 0x02, 0xCB, 0x05, 0x93, 0x57, 0x93, - 0xF0, 0x9A, 0xAC, 0x0B, 0xE3, 0x07, 0x92, 0xEA, - 0xE2, 0x9F, 0xE5, 0x06, 0xE3, 0xB0, 0xA0, 0x02, - 0xEB, 0x1E, 0x82, 0xD7, 0xEA, 0x1E, 0xE2, 0x3B, - 0x85, 0x9B, 0xE9, 0x1E, 0xC8, 0x90, 0x85, 0x94 -}; - -static const unsigned char patch_block9[64] = { - 0x02, 0xDE, 0x05, 0x80, 0x57, 0x93, 0xF0, 0xBA, - 0xAC, 0x06, 0x92, 0xEA, 0xE2, 0xBF, 0xE5, 0x06, - 0xA0, 0x01, 0xEB, 0xBF, 0x85, 0x88, 0xE9, 0x3E, - 0xC8, 0x90, 0x85, 0x81, 0xE9, 0x3E, 0xF0, 0xBA, - 0xF3, 0x39, 0xF0, 0x3A, 0x60, 0x17, 0xF0, 0x3A, - 0xC0, 0x90, 0xF0, 0xBA, 0xE1, 0x00, 0x00, 0x3F, - 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x10, 0x60, 0x59, - 0xE6, 0x93, 0x0D, 0xA2, 0x58, 0x12, 0xE6, 0x93 -}; - -static const unsigned char patch_block10[64] = { - 0x0D, 0xAA, 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, - 0x03, 0x01, 0xE1, 0x00, 0x03, 0x03, 0x9B, 0x7D, - 0x8B, 0x8B, 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x56, - 0x60, 0x59, 0xE6, 0x93, 0x0D, 0xBA, 0xE3, 0x98, - 0xE3, 0x90, 0xE1, 0x00, 0x03, 0x0F, 0x93, 0x11, - 0xE1, 0x00, 0xE3, 0x02, 0x4A, 0x11, 0x0B, 0x42, - 0x91, 0xAF, 0xE3, 0x90, 0xE1, 0x00, 0xF2, 0x91, - 0xF0, 0x91, 0xA3, 0xFE, 0xE1, 0x00, 0x60, 0x92 -}; - -static const unsigned char patch_block11[64] = { - 0xC0, 0x5F, 0xF0, 0x13, 0xF0, 0x13, 0x59, 0x5B, - 0xE2, 0x13, 0xF0, 0x11, 0x5A, 0x19, 0xE2, 0x13, - 0xE1, 0x00, 0x00, 0x00, 0x03, 0x27, 0x68, 0x61, - 0x76, 0x61, 0x6E, 0x61, 0x00, 0x06, 0x03, 0x2C, - 0xE3, 0x02, 0xE3, 0x03, 0xE9, 0x38, 0x59, 0x15, - 0x59, 0x5A, 0xF2, 0x9A, 0xBC, 0x0B, 0xA4, 0x0A, - 0x59, 0x1E, 0xF3, 0x11, 0xF0, 0x1A, 0xE2, 0xBB, - 0x59, 0x15, 0xF0, 0x11, 0x19, 0x2A, 0xE5, 0x02 -}; - -static const unsigned char patch_block12[54] = { - 0xA4, 0x01, 0xEB, 0xBF, 0xE3, 0x98, 0xE3, 0x90, - 0xE1, 0x00, 0x03, 0x42, 0x19, 0x28, 0xE1, 0x00, - 0xE9, 0x30, 0x60, 0x79, 0xE1, 0x00, 0xE3, 0x03, - 0xE3, 0x07, 0x60, 0x79, 0x93, 0x4E, 0xE3, 0xB8, - 0xE3, 0x98, 0xE1, 0x00, 0xE9, 0x1A, 0xF0, 0x1F, - 0xE2, 0x33, 0xF0, 0x91, 0xE2, 0x92, 0xE0, 0x32, - 0xF0, 0x31, 0xE1, 0x00, 0x00, 0x00 -}; - -static const unsigned char do_call[1] = { - 0x01 -}; - - -#define PATCH_DATA_SIZE 18 - -static const cpia2_patch patch_data[PATCH_DATA_SIZE] = { - {0x0A, sizeof(start_address_hi), start_address_hi} - , // 0 - {0x0B, sizeof(start_address_lo), start_address_lo} - , // 1 - {0x0C, sizeof(patch_block0), patch_block0} - , // 2 - {0x0C, sizeof(patch_block1), patch_block1} - , // 3 - {0x0C, sizeof(patch_block2), patch_block2} - , // 4 - {0x0C, sizeof(patch_block3), patch_block3} - , // 5 - {0x0C, sizeof(patch_block4), patch_block4} - , // 6 - {0x0C, sizeof(patch_block5), patch_block5} - , // 7 - {0x0C, sizeof(patch_block6), patch_block6} - , // 8 - {0x0C, sizeof(patch_block7), patch_block7} - , // 9 - {0x0C, sizeof(patch_block8), patch_block8} - , // 10 - {0x0C, sizeof(patch_block9), patch_block9} - , //11 - {0x0C, sizeof(patch_block10), patch_block10} - , // 12 - {0x0C, sizeof(patch_block11), patch_block11} - , // 13 - {0x0C, sizeof(patch_block12), patch_block12} - , // 14 - {0x0A, sizeof(start_address_hi), start_address_hi} - , // 15 - {0x0B, sizeof(start_address_lo), start_address_lo} - , // 16 - {0x0D, sizeof(do_call), do_call} //17 -}; - - -#endif diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c index 0b00e6027..74cff626e 100644 --- a/drivers/media/video/cpia_pp.c +++ b/drivers/media/video/cpia_pp.c @@ -23,7 +23,7 @@ */ /* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */ -/* #define _CPIA_DEBUG_ 1 */ +/* #define _CPIA_DEBUG_ 1 */ #include @@ -45,7 +45,7 @@ static int cpia_pp_open(void *privdata); static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata), - void *cbdata); + void *cbdata); static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data); static int cpia_pp_streamStart(void *privdata); static int cpia_pp_streamStop(void *privdata); @@ -93,7 +93,7 @@ struct pp_cam_entry { int stream_irq; }; -static struct cpia_camera_ops cpia_pp_ops = +static struct cpia_camera_ops cpia_pp_ops = { cpia_pp_open, cpia_pp_registerCallback, @@ -123,7 +123,7 @@ static void cpia_parport_disable_irq( struct parport *port ) { } /* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility - * Link Flag during negotiation */ + * Link Flag during negotiation */ #define UPLOAD_FLAG 0x08 #define NIBBLE_TRANSFER 0x01 #define ECP_TRANSFER 0x03 @@ -139,17 +139,17 @@ static void cpia_parport_disable_irq( struct parport *port ) { /* CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */ /* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */ -static size_t cpia_read_nibble (struct parport *port, - void *buffer, size_t len, +static size_t cpia_read_nibble (struct parport *port, + void *buffer, size_t len, int flags) { - /* adapted verbatim, with one change, from + /* adapted verbatim, with one change, from parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */ unsigned char *buf = buffer; int i; unsigned char byte = 0; - + len *= 2; /* in nibbles */ for (i=0; i < len; i++) { unsigned char nibble; @@ -158,12 +158,12 @@ static size_t cpia_read_nibble (struct parport *port, * after every second nibble to signal that more * data is available. (the total number of Bytes that * should be sent is known; if too few are received, an error - * will be recorded after a timeout). + * will be recorded after a timeout). * This is incompatible with parport_ieee1284_read_nibble(), * which expects to find nFault LO after every second nibble. */ - /* Solution: modify cpia_read_nibble to only check for + /* Solution: modify cpia_read_nibble to only check for * nDataAvail before the first nibble is sent. */ @@ -216,7 +216,7 @@ static size_t cpia_read_nibble (struct parport *port, /* Second nibble */ byte |= nibble << 4; *buf++ = byte; - } else + } else byte = nibble; } @@ -238,18 +238,18 @@ static size_t cpia_read_nibble (struct parport *port, } /* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1) - * (See CPiA Data sheet p. 31) - * - * "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a - * nonstandard variant of nibble mode which allows the same (mediocre) - * data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable + * (See CPiA Data sheet p. 31) + * + * "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a + * nonstandard variant of nibble mode which allows the same (mediocre) + * data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable * parallel ports, but works also for non-TRISTATE-capable ports. * (Standard nibble mode only send 4 bits per cycle) * */ -static size_t cpia_read_nibble_stream(struct parport *port, - void *buffer, size_t len, +static size_t cpia_read_nibble_stream(struct parport *port, + void *buffer, size_t len, int flags) { int i; @@ -260,7 +260,7 @@ static size_t cpia_read_nibble_stream(struct parport *port, unsigned char nibble[2], byte = 0; int j; - /* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */ + /* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */ if (endseen > 3 ) break; @@ -268,7 +268,7 @@ static size_t cpia_read_nibble_stream(struct parport *port, parport_frob_control (port, PARPORT_CONTROL_AUTOFD, PARPORT_CONTROL_AUTOFD); - + /* Event 9: nAck goes low. */ port->ieee1284.phase = IEEE1284_PH_REV_DATA; if (parport_wait_peripheral (port, @@ -282,7 +282,7 @@ static size_t cpia_read_nibble_stream(struct parport *port, /* Read lower nibble */ nibble[0] = parport_read_status (port) >>3; - + /* Event 10: Set nAutoFd high. */ parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0); @@ -295,10 +295,10 @@ static size_t cpia_read_nibble_stream(struct parport *port, port->name); break; } - + /* Read upper nibble */ nibble[1] = parport_read_status (port) >>3; - + /* reassemble the byte */ for (j = 0; j < 2 ; j++ ) { nibble[j] &= ~8; @@ -335,8 +335,8 @@ static void EndTransferMode(struct pp_cam_entry *cam) static int ForwardSetup(struct pp_cam_entry *cam) { int retry; - - /* The CPiA uses ECP protocol for Downloads from the Host to the camera. + + /* The CPiA uses ECP protocol for Downloads from the Host to the camera. * This will be software-emulated if ECP hardware is not present */ @@ -375,9 +375,9 @@ static int ReverseSetup(struct pp_cam_entry *cam, int extensibility) upload_mode = mode; if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK; - /* the usual camera maximum response time is 10ms, but after + /* the usual camera maximum response time is 10ms, but after * receiving some commands, it needs up to 40ms. */ - + for(retry = 0; retry < 4; ++retry) { if(!parport_negotiate(cam->port, mode)) { break; @@ -439,10 +439,10 @@ static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size) /* support for CPiA variant nibble reads */ if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) { - if(cpia_read_nibble(cam->port, packet, size, 0) != size) - retval = -EIO; + if(cpia_read_nibble(cam->port, packet, size, 0) != size) + retval = -EIO; } else { - if(parport_read(cam->port, packet, size) != size) + if(parport_read(cam->port, packet, size) != size) retval = -EIO; } EndTransferMode(cam); @@ -542,18 +542,18 @@ static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock) block_size = PARPORT_CHUNK_SIZE; while( !cam->image_complete ) { cond_resched(); - + new_bytes = cpia_pp_read(cam->port, buffer, block_size ); if( new_bytes <= 0 ) { break; } i=-1; while(++iopen_count == 0) { if (parport_claim(cam->pdev)) { DBG("failed to claim the port\n"); @@ -645,12 +645,12 @@ static int cpia_pp_open(void *privdata) parport_write_control(cam->port, PARPORT_CONTROL_SELECT); udelay(50); parport_write_control(cam->port, - PARPORT_CONTROL_SELECT - | PARPORT_CONTROL_INIT); + PARPORT_CONTROL_SELECT + | PARPORT_CONTROL_INIT); } - + ++cam->open_count; - + return 0; } @@ -663,7 +663,7 @@ static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), vo { struct pp_cam_entry *cam = privdata; int retval = 0; - + if(cam->port->irq != PARPORT_IRQ_NONE) { INIT_WORK(&cam->cb_task, cb, cbdata); } else { @@ -707,9 +707,9 @@ static int cpia_pp_register(struct parport *port) LOG("failed to allocate camera structure\n"); return -ENOMEM; } - + pdev = parport_register_device(port, "cpia_pp", NULL, NULL, - NULL, 0, cam); + NULL, 0, cam); if (!pdev) { LOG("failed to parport_register_device\n"); @@ -753,19 +753,19 @@ static void cpia_pp_detach (struct parport *port) } cpia = NULL; } - spin_unlock( &cam_list_lock_pp ); + spin_unlock( &cam_list_lock_pp ); if (!cpia) { DBG("cpia_pp_detach failed to find cam_data in cam_list\n"); return; } - - cam = (struct pp_cam_entry *) cpia->lowlevel_data; + + cam = (struct pp_cam_entry *) cpia->lowlevel_data; cpia_unregister_camera(cpia); - if(cam->open_count > 0) + if(cam->open_count > 0) cpia_pp_close(cam); parport_unregister_device(cam->pdev); - cpia->lowlevel_data = NULL; + cpia->lowlevel_data = NULL; kfree(cam); } @@ -805,14 +805,14 @@ static struct parport_driver cpia_pp_driver = { int cpia_pp_init(void) { - printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, + printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER); if(parport_nr[0] == PPCPIA_PARPORT_OFF) { printk(" disabled\n"); return 0; } - + spin_lock_init( &cam_list_lock_pp ); if (parport_register_driver (&cpia_pp_driver)) { @@ -873,7 +873,7 @@ static int __init cpia_pp_setup(char *str) parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE; } - return 1; + return 0; } __setup("cpia_pp=", cpia_pp_setup); diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 9c49a4b00..03275c37c 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c @@ -22,7 +22,7 @@ */ /* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */ -/* #define _CPIA_DEBUG_ 1 */ +/* #define _CPIA_DEBUG_ 1 */ #include #include @@ -85,7 +85,7 @@ struct usb_cpia { static int cpia_usb_open(void *privdata); static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata), - void *cbdata); + void *cbdata); static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data); static int cpia_usb_streamStart(void *privdata); static int cpia_usb_streamStop(void *privdata); @@ -127,7 +127,7 @@ static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs) ucpia->workbuff->status = FRAME_READING; ucpia->workbuff->length = 0; } - + for (i = 0; i < urb->number_of_packets; i++) { int n = urb->iso_frame_desc[i].actual_length; int st = urb->iso_frame_desc[i].status; @@ -141,9 +141,9 @@ static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs) printk(KERN_DEBUG "cpia: scratch buf overflow!scr_len: %d, n: %d\n", ucpia->workbuff->length, n); return; } - + if (n) { - if ((ucpia->workbuff->length > 0) || + if ((ucpia->workbuff->length > 0) || (0x19 == cdata[0] && 0x68 == cdata[1])) { memcpy(ucpia->workbuff->data + ucpia->workbuff->length, cdata, n); ucpia->workbuff->length += n; @@ -160,7 +160,7 @@ static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs) ucpia->workbuff = ucpia->workbuff->next; ucpia->workbuff->status = FRAME_EMPTY; ucpia->workbuff->length = 0; - + if (waitqueue_active(&ucpia->wq_stream)) wake_up_interruptible(&ucpia->wq_stream); } @@ -178,7 +178,7 @@ static int cpia_usb_open(void *privdata) struct usb_cpia *ucpia = (struct usb_cpia *) privdata; struct urb *urb; int ret, retval = 0, fx, err; - + if (!ucpia) return -EINVAL; @@ -191,7 +191,7 @@ static int cpia_usb_open(void *privdata) retval = -EINVAL; goto error_0; } - + ret = usb_set_interface(ucpia->dev, ucpia->iface, 3); if (ret < 0) { printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret); @@ -286,7 +286,7 @@ error_1: error_0: kfree (ucpia->sbuf[0].data); ucpia->sbuf[0].data = NULL; - + return retval; } @@ -307,7 +307,7 @@ static int WritePacket(struct usb_device *udev, const u8 *packet, u8 *buf, size_ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), packet[1] + (packet[0] << 8), USB_TYPE_VENDOR | USB_RECIP_DEVICE, - packet[2] + (packet[3] << 8), + packet[2] + (packet[3] << 8), packet[4] + (packet[5] << 8), buf, size, 1000); } @@ -324,7 +324,7 @@ static int ReadPacket(struct usb_device *udev, u8 *packet, u8 *buf, size_t size) return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), packet[1] + (packet[0] << 8), USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - packet[2] + (packet[3] << 8), + packet[2] + (packet[3] << 8), packet[4] + (packet[5] << 8), buf, size, 1000); } @@ -393,7 +393,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock) if (!ucpia || !ucpia->present) return -1; - + if (ucpia->curbuff->status != FRAME_READY) interruptible_sleep_on(&ucpia->wq_stream); else @@ -403,7 +403,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock) if (!mybuff) return -1; - + if (mybuff->status != FRAME_READY || mybuff->length < 4) { DBG("Something went wrong!\n"); return -1; @@ -411,7 +411,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock) memcpy(frame, mybuff->data, mybuff->length); mybuff->status = FRAME_EMPTY; - + /* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", */ /* mybuff->length, frame[0], frame[1], */ /* frame[mybuff->length-4], frame[mybuff->length-3], */ @@ -447,7 +447,7 @@ static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try) kfree(ucpia->sbuf[1].data); ucpia->sbuf[1].data = NULL; - + if (ucpia->sbuf[0].urb) { usb_kill_urb(ucpia->sbuf[0].urb); usb_free_urb(ucpia->sbuf[0].urb); @@ -490,7 +490,7 @@ static int cpia_probe(struct usb_interface *intf, struct usb_cpia *ucpia; struct cam_data *cam; int ret; - + /* A multi-config CPiA camera? */ if (udev->descriptor.bNumConfigurations != 1) return -ENODEV; @@ -539,7 +539,7 @@ static int cpia_probe(struct usb_interface *intf, /* Before register_camera, important */ ucpia->present = 1; - + cam = cpia_register_camera(&cpia_usb_ops, ucpia); if (!cam) { LOG("failed to cpia_register_camera\n"); @@ -591,7 +591,7 @@ static void cpia_disconnect(struct usb_interface *intf) struct cam_data *cam = usb_get_intfdata(intf); struct usb_cpia *ucpia; struct usb_device *udev; - + usb_set_intfdata(intf, NULL); if (!cam) return; @@ -600,7 +600,7 @@ static void cpia_disconnect(struct usb_interface *intf) spin_lock( &cam_list_lock_usb ); list_del(&cam->cam_data_list); spin_unlock( &cam_list_lock_usb ); - + ucpia->present = 0; cpia_unregister_camera(cam); @@ -631,7 +631,7 @@ static void cpia_disconnect(struct usb_interface *intf) static int __init usb_cpia_init(void) { - printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, + printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER); spin_lock_init(&cam_list_lock_usb); diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index de87247c7..8739c6478 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c @@ -59,25 +59,25 @@ static int cs53l32a_read(struct i2c_client *client, u8 reg) static int cs53l32a_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct v4l2_routing *route = arg; + struct v4l2_audio *input = arg; struct v4l2_control *ctrl = arg; switch (cmd) { - case VIDIOC_INT_G_AUDIO_ROUTING: - route->input = (cs53l32a_read(client, 0x01) >> 4) & 3; - route->output = 0; - break; - - case VIDIOC_INT_S_AUDIO_ROUTING: + case VIDIOC_S_AUDIO: /* 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) { - v4l_err(client, "Invalid input %d.\n", route->input); + if (input->index > 2) { + v4l_err(client, "Invalid input %d.\n", input->index); return -EINVAL; } - cs53l32a_write(client, 0x01, 0x01 + (route->input << 4)); + cs53l32a_write(client, 0x01, 0x01 + (input->index << 4)); + break; + + case VIDIOC_G_AUDIO: + memset(input, 0, sizeof(*input)); + input->index = (cs53l32a_read(client, 0x01) >> 4) & 3; break; case VIDIOC_G_CTRL: diff --git a/drivers/media/video/cs8420.h b/drivers/media/video/cs8420.h index 621c0c667..2b22f3a38 100644 --- a/drivers/media/video/cs8420.h +++ b/drivers/media/video/cs8420.h @@ -20,7 +20,7 @@ #define __CS8420_H__ /* Initialization Sequence */ - + static __u8 init8420[] = { 1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46, 5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13, diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig deleted file mode 100644 index 854264e42..000000000 --- a/drivers/media/video/cx25840/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config VIDEO_CX25840 - tristate "Conexant CX2584x audio/video decoders" - depends on VIDEO_DEV && I2C && EXPERIMENTAL - select FW_LOADER - ---help--- - Support for the Conexant CX2584x audio/video decoders. - - To compile this driver as a module, choose M here: the - module will be called cx25840 diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/video/cx25840/Makefile index 6e8665be8..543ebacdc 100644 --- a/drivers/media/video/cx25840/Makefile +++ b/drivers/media/video/cx25840/Makefile @@ -1,6 +1,6 @@ cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \ cx25840-vbi.o -obj-$(CONFIG_VIDEO_CX25840) += cx25840.o +obj-$(CONFIG_VIDEO_DECODER) += cx25840.o -EXTRA_CFLAGS += -Idrivers/media/video +EXTRA_CFLAGS += -I$(src)/.. diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 9a4b81315..cb9a7981e 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c @@ -18,10 +18,10 @@ #include #include +#include #include -#include -#include "cx25840-core.h" +#include "cx25840.h" static int set_audclk_freq(struct i2c_client *client, u32 freq) { diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index a961bb2ab..5588b9a5c 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -31,10 +31,10 @@ #include #include #include +#include #include -#include -#include "cx25840-core.h" +#include "cx25840.h" MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver"); MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford"); @@ -176,9 +176,9 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) cx25840_write(client, 0x4a5, 0x00); cx25840_write(client, 0x402, 0x00); /* 8. */ - cx25840_and_or(client, 0x401, ~0x18, 0); - cx25840_and_or(client, 0x4a2, ~0x10, 0x10); - /* steps 8c and 8d are done in change_input() */ + cx25840_write(client, 0x401, 0x18); + cx25840_write(client, 0x4a2, 0x10); + cx25840_write(client, 0x402, 0x04); /* 10. */ cx25840_write(client, 0x8d3, 0x1f); cx25840_write(client, 0x8e3, 0x03); @@ -209,17 +209,6 @@ static void input_change(struct i2c_client *client) struct cx25840_state *state = i2c_get_clientdata(client); v4l2_std_id std = cx25840_get_v4lstd(client); - /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ - if (std & V4L2_STD_SECAM) { - cx25840_write(client, 0x402, 0); - } - else { - cx25840_write(client, 0x402, 0x04); - cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); - } - cx25840_and_or(client, 0x401, ~0x60, 0); - cx25840_and_or(client, 0x401, ~0x60, 0x60); - /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC instead of V4L2_STD_PAL. Someone needs to test this. */ if (std & V4L2_STD_PAL) { @@ -354,15 +343,6 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) } } - /* Follow step 9 of section 3.16 in the cx25840 datasheet. - Without this PAL may display a vertical ghosting effect. - This happens for example with the Yuan MPC622. */ - if (fmt >= 4 && fmt < 8) { - /* Set format to NTSC-M */ - cx25840_and_or(client, 0x400, ~0xf, 1); - /* Turn off LCOMB */ - cx25840_and_or(client, 0x47b, ~6, 0); - } cx25840_and_or(client, 0x400, ~0xf, fmt); cx25840_vbi_setup(client); return 0; @@ -379,14 +359,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) } switch (fmt) { - case 0x1: - { - /* if the audio std is A2-M, then this is the South Korean - NTSC standard */ - if (cx25840_read(client, 0x805) == 2) - return V4L2_STD_NTSC_M_KR; - return V4L2_STD_NTSC_M; - } + case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR; case 0x2: return V4L2_STD_NTSC_M_JP; case 0x3: return V4L2_STD_NTSC_443; case 0x4: return V4L2_STD_PAL; @@ -669,7 +642,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, { struct cx25840_state *state = i2c_get_clientdata(client); struct v4l2_tuner *vt = arg; - struct v4l2_routing *route = arg; switch (cmd) { #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -751,21 +723,28 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, state->radio = 1; break; - case VIDIOC_INT_G_VIDEO_ROUTING: - route->input = state->vid_input; - route->output = 0; + case VIDIOC_G_INPUT: + *(int *)arg = state->vid_input; break; - case VIDIOC_INT_S_VIDEO_ROUTING: - return set_input(client, route->input, state->aud_input); + case VIDIOC_S_INPUT: + return set_input(client, *(enum cx25840_video_input *)arg, state->aud_input); - case VIDIOC_INT_G_AUDIO_ROUTING: - route->input = state->aud_input; - route->output = 0; - break; + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *input = arg; + + return set_input(client, state->vid_input, input->index); + } - case VIDIOC_INT_S_AUDIO_ROUTING: - return set_input(client, state->vid_input, route->input); + case VIDIOC_G_AUDIO: + { + struct v4l2_audio *input = arg; + + memset(input, 0, sizeof(*input)); + input->index = state->aud_input; + break; + } case VIDIOC_S_FREQUENCY: input_change(client); @@ -774,6 +753,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, case VIDIOC_G_TUNER: { u8 mode = cx25840_read(client, 0x804); + u8 pref = cx25840_read(client, 0x809) & 0xf; u8 vpres = cx25840_read(client, 0x80a) & 0x10; int val = 0; @@ -793,50 +773,44 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, val |= V4L2_TUNER_SUB_MONO; if (mode == 2 || mode == 4) - val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; if (mode & 0x10) val |= V4L2_TUNER_SUB_SAP; vt->rxsubchans = val; - vt->audmode = state->audmode; + + switch (pref) { + case 0: + vt->audmode = V4L2_TUNER_MODE_MONO; + break; + case 1: + case 2: + vt->audmode = V4L2_TUNER_MODE_LANG2; + break; + case 4: + default: + vt->audmode = V4L2_TUNER_MODE_STEREO; + } break; } case VIDIOC_S_TUNER: - if (state->radio) - break; - switch (vt->audmode) { case V4L2_TUNER_MODE_MONO: - /* mono -> mono - stereo -> mono - bilingual -> lang1 */ + case V4L2_TUNER_MODE_LANG1: + /* Force PREF_MODE to MONO */ cx25840_and_or(client, 0x809, ~0xf, 0x00); break; case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1: - /* mono -> mono - stereo -> stereo - bilingual -> lang1 */ + /* Force PREF_MODE to STEREO */ cx25840_and_or(client, 0x809, ~0xf, 0x04); break; - case V4L2_TUNER_MODE_LANG1_LANG2: - /* mono -> mono - stereo -> stereo - bilingual -> lang1/lang2 */ - cx25840_and_or(client, 0x809, ~0xf, 0x07); - break; case V4L2_TUNER_MODE_LANG2: - /* mono -> mono - stereo -> stereo - bilingual -> lang2 */ + /* Force PREF_MODE to LANG2 */ cx25840_and_or(client, 0x809, ~0xf, 0x01); break; - default: - return -EINVAL; } - state->audmode = vt->audmode; break; case VIDIOC_G_FMT: @@ -917,7 +891,6 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, state->aud_input = CX25840_AUDIO8; state->audclk_freq = 48000; state->pvr150_workaround = 0; - state->audmode = V4L2_TUNER_MODE_LANG1; cx25840_initialize(client, 1); diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h deleted file mode 100644 index 1736929fc..000000000 --- a/drivers/media/video/cx25840/cx25840-core.h +++ /dev/null @@ -1,67 +0,0 @@ -/* cx25840 internal API header - * - * Copyright (C) 2003-2004 Chris Kennedy - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _CX25840_CORE_H_ -#define _CX25840_CORE_H_ - - -#include -#include - -/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is - present in Hauppauge PVR-150 (and possibly PVR-500) cards that have - certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The - audio autodetect fails on some channels for these models and the workaround - is to select the audio standard explicitly. Many thanks to Hauppauge for - providing this information. */ -#define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0) - -struct cx25840_state { - int pvr150_workaround; - int radio; - enum cx25840_video_input vid_input; - enum cx25840_audio_input aud_input; - u32 audclk_freq; - int audmode; -}; - -/* ----------------------------------------------------------------------- */ -/* cx25850-core.c */ -int cx25840_write(struct i2c_client *client, u16 addr, u8 value); -int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); -u8 cx25840_read(struct i2c_client *client, u16 addr); -u32 cx25840_read4(struct i2c_client *client, u16 addr); -int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value); -v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client); - -/* ----------------------------------------------------------------------- */ -/* cx25850-firmware.c */ -int cx25840_loadfw(struct i2c_client *client); - -/* ----------------------------------------------------------------------- */ -/* cx25850-audio.c */ -int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); -void cx25840_audio_set_path(struct i2c_client *client); - -/* ----------------------------------------------------------------------- */ -/* cx25850-vbi.c */ -void cx25840_vbi_setup(struct i2c_client *client); -int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg); - -#endif diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index 1958d4016..e1a7823d8 100644 --- a/drivers/media/video/cx25840/cx25840-firmware.c +++ b/drivers/media/video/cx25840/cx25840-firmware.c @@ -20,31 +20,37 @@ #include #include #include -#include -#include "cx25840-core.h" +#include "cx25840.h" #define FWFILE "v4l-cx25840.fw" - -/* - * Mike Isely - The FWSEND parameter controls the - * size of the firmware chunks sent down the I2C bus to the chip. - * Previously this had been set to 1024 but unfortunately some I2C - * implementations can't transfer data in such big gulps. - * Specifically, the pvrusb2 driver has a hard limit of around 60 - * bytes, due to the encapsulation there of I2C traffic into USB - * messages. So we have to significantly reduce this parameter. - */ -#define FWSEND 48 +#define FWSEND 1024 #define FWDEV(x) &((x)->adapter->dev) +static int fastfw = 1; static char *firmware = FWFILE; +module_param(fastfw, bool, 0444); module_param(firmware, charp, 0444); +MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); +static void set_i2c_delay(struct i2c_client *client, int delay) +{ + struct i2c_algo_bit_data *algod = client->adapter->algo_data; + + /* We aren't guaranteed to be using algo_bit, + * so avoid the null pointer dereference + * and disable the 'fast firmware load' */ + if (algod) { + algod->udelay = delay; + } else { + fastfw = 0; + } +} + static void start_fw_load(struct i2c_client *client) { /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ @@ -54,10 +60,16 @@ static void start_fw_load(struct i2c_client *client) cx25840_write(client, 0x803, 0x0b); /* AUTO_INC_DIS=1 */ cx25840_write(client, 0x000, 0x20); + + if (fastfw) + set_i2c_delay(client, 3); } static void end_fw_load(struct i2c_client *client) { + if (fastfw) + set_i2c_delay(client, 10); + /* AUTO_INC_DIS=0 */ cx25840_write(client, 0x000, 0x00); /* DL_ENABLE=0 */ @@ -84,8 +96,30 @@ static int fw_write(struct i2c_client *client, u8 * data, int size) int sent; if ((sent = i2c_master_send(client, data, size)) < size) { - v4l_err(client, "firmware load i2c failure\n"); - return -ENOSYS; + + if (fastfw) { + v4l_err(client, "333MHz i2c firmware load failed\n"); + fastfw = 0; + set_i2c_delay(client, 10); + + if (sent > 2) { + u16 dl_addr = cx25840_read(client, 0x801) << 8; + dl_addr |= cx25840_read(client, 0x800); + dl_addr -= sent - 2; + cx25840_write(client, 0x801, dl_addr >> 8); + cx25840_write(client, 0x800, dl_addr & 0xff); + } + + if (i2c_master_send(client, data, size) < size) { + v4l_err(client, "100MHz i2c firmware load failed\n"); + return -ENOSYS; + } + + } else { + v4l_err(client, "firmware load i2c failure\n"); + return -ENOSYS; + } + } return 0; diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 57feca288..04d879da7 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c @@ -19,9 +19,8 @@ #include #include #include -#include -#include "cx25840-core.h" +#include "cx25840.h" static int odd_parity(u8 c) { diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 630273992..87d79df05 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -1,7 +1,3 @@ -config VIDEO_CX88_VP3054 - tristate - depends on VIDEO_CX88_DVB && DVB_MT352 - config VIDEO_CX88 tristate "Conexant 2388x (bt878 successor) support" depends on VIDEO_DEV && PCI && I2C @@ -20,16 +16,15 @@ config VIDEO_CX88 module will be called cx8800 config VIDEO_CX88_ALSA - tristate "Conexant 2388x DMA audio support" + tristate "ALSA DMA audio support" depends on VIDEO_CX88 && SND && EXPERIMENTAL select SND_PCM ---help--- This is a video4linux driver for direct (DMA) audio on - Conexant 2388x based TV cards using ALSA. - + Conexant 2388x based TV cards. It only works with boards with function 01 enabled. To check if your board supports, use lspci -n. - If supported, you should see 14f1:8801 or 14f1:8811 + If supported, you should see 1471:8801 or 1471:8811 PCI device. To compile this driver as a module, choose M here: the @@ -55,7 +50,6 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS depends on VIDEO_CX88_DVB select DVB_MT352 select VIDEO_CX88_VP3054 - select DVB_ZL10353 select DVB_OR51132 select DVB_CX22702 select DVB_LGDT330X @@ -77,27 +71,16 @@ config VIDEO_CX88_DVB_MT352 This adds DVB-T support for cards based on the Connexant 2388x chip and the MT352 demodulator. -config VIDEO_CX88_DVB_VP3054 - bool "VP-3054 Secondary I2C Bus Support" - default y - depends on VIDEO_CX88_DVB_MT352 - select VIDEO_CX88_VP3054 +config VIDEO_CX88_VP3054 + tristate "VP-3054 Secondary I2C Bus Support" + default m + depends on DVB_MT352 ---help--- This adds DVB-T support for cards based on the Connexant 2388x chip and the MT352 demodulator, which also require support for the VP-3054 Secondary I2C bus, such at DNTV Live! DVB-T Pro. -config VIDEO_CX88_DVB_ZL10353 - bool "Zarlink ZL10353 DVB-T Support" - default y - depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS - select DVB_ZL10353 - ---help--- - This adds DVB-T support for cards based on the - Connexant 2388x chip and the ZL10353 demodulator, - successor to the Zarlink MT352. - config VIDEO_CX88_DVB_OR51132 bool "OR51132 ATSC Support" default y diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 0dcd09b9b..2b902784f 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile @@ -8,16 +8,15 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o -EXTRA_CFLAGS += -Idrivers/media/video -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends +EXTRA_CFLAGS += -I$(src)/.. +EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core +EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1 extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1 extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 -extra-cflags-$(CONFIG_DVB_ZL10353) += -DHAVE_ZL10353=1 extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1 diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 320b3d938..2acccd6d4 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c @@ -63,7 +63,7 @@ struct cx88_audio_dev { /* audio controls */ int irq; - struct snd_card *card; + snd_card_t *card; spinlock_t reg_lock; @@ -82,7 +82,7 @@ struct cx88_audio_dev { struct cx88_buffer *buf; long opened; - struct snd_pcm_substream *substream; + snd_pcm_substream_t *substream; }; typedef struct cx88_audio_dev snd_cx88_card_t; @@ -96,7 +96,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t; static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; -static struct snd_card *snd_cx88_cards[SNDRV_CARDS]; +static snd_card_t *snd_cx88_cards[SNDRV_CARDS]; module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled."); @@ -303,7 +303,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip) BUG_ON(!chip->dma_size); dprintk(2,"Freeing buffer\n"); - videobuf_pci_dma_unmap(chip->pci, &chip->dma_risc); + videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc); videobuf_dma_free(&chip->dma_risc); btcx_riscmem_free(chip->pci,&chip->buf->risc); kfree(chip->buf); @@ -320,7 +320,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip) /* * Digital hardware definition */ -static struct snd_pcm_hardware snd_cx88_digital_hw = { +static snd_pcm_hardware_t snd_cx88_digital_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -342,16 +342,16 @@ static struct snd_pcm_hardware snd_cx88_digital_hw = { /* * audio pcm capture runtime free */ -static void snd_card_cx88_runtime_free(struct snd_pcm_runtime *runtime) +static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime) { } /* * audio pcm capture open callback */ -static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) +static int snd_cx88_pcm_open(snd_pcm_substream_t *substream) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_runtime_t *runtime = substream->runtime; int err; if (test_and_set_bit(0, &chip->opened)) @@ -380,7 +380,7 @@ _error: /* * audio close callback */ -static int snd_cx88_close(struct snd_pcm_substream *substream) +static int snd_cx88_close(snd_pcm_substream_t *substream) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); @@ -393,8 +393,8 @@ static int snd_cx88_close(struct snd_pcm_substream *substream) /* * hw_params callback */ -static int snd_cx88_hw_params(struct snd_pcm_substream * substream, - struct snd_pcm_hw_params * hw_params) +static int snd_cx88_hw_params(snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); struct cx88_buffer *buf; @@ -429,7 +429,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE, (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT)); - videobuf_pci_dma_map(chip->pci,&buf->vb.dma); + videobuf_dma_pci_map(chip->pci,&buf->vb.dma); cx88_risc_databuffer(chip->pci, &buf->risc, @@ -453,7 +453,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, /* * hw free callback */ -static int snd_cx88_hw_free(struct snd_pcm_substream * substream) +static int snd_cx88_hw_free(snd_pcm_substream_t * substream) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); @@ -469,7 +469,7 @@ static int snd_cx88_hw_free(struct snd_pcm_substream * substream) /* * prepare callback */ -static int snd_cx88_prepare(struct snd_pcm_substream *substream) +static int snd_cx88_prepare(snd_pcm_substream_t *substream) { return 0; } @@ -478,7 +478,7 @@ static int snd_cx88_prepare(struct snd_pcm_substream *substream) /* * trigger callback */ -static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd) +static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); int err; @@ -505,10 +505,10 @@ static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd) /* * pointer callback */ -static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream) +static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_runtime_t *runtime = substream->runtime; if (chip->read_count) { chip->read_count -= snd_pcm_lib_period_bytes(substream); @@ -525,7 +525,7 @@ static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream) /* * operators */ -static struct snd_pcm_ops snd_cx88_pcm_ops = { +static snd_pcm_ops_t snd_cx88_pcm_ops = { .open = snd_cx88_pcm_open, .close = snd_cx88_close, .ioctl = snd_pcm_lib_ioctl, @@ -542,7 +542,7 @@ static struct snd_pcm_ops snd_cx88_pcm_ops = { static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) { int err; - struct snd_pcm *pcm; + snd_pcm_t *pcm; err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); if (err < 0) @@ -557,8 +557,7 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) /**************************************************************************** CONTROL INTERFACE ****************************************************************************/ -static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) +static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info) { info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; info->count = 1; @@ -569,8 +568,7 @@ static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol, } /* OK - TODO: test it */ -static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) +static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value) { snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core=chip->core; @@ -581,8 +579,7 @@ static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol, } /* OK - TODO: test it */ -static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) +static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value) { snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core=chip->core; @@ -598,7 +595,7 @@ static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol, return v != old_control; } -static struct snd_kcontrol_new snd_cx88_capture_volume = { +static snd_kcontrol_new_t snd_cx88_capture_volume = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Volume", .info = snd_cx88_capture_volume_info, @@ -616,7 +613,7 @@ static struct snd_kcontrol_new snd_cx88_capture_volume = { * Only boards with eeprom and byte 1 at eeprom=1 have it */ -static struct pci_device_id cx88_audio_pci_tbl[] __devinitdata = { +static struct pci_device_id cx88_audio_pci_tbl[] = { {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, {0, } @@ -644,7 +641,7 @@ static int snd_cx88_free(snd_cx88_card_t *chip) /* * Component Destructor */ -static void snd_cx88_dev_free(struct snd_card * card) +static void snd_cx88_dev_free(snd_card_t * card) { snd_cx88_card_t *chip = card->private_data; @@ -657,9 +654,8 @@ static void snd_cx88_dev_free(struct snd_card * card) */ static int devno; -static int __devinit snd_cx88_create(struct snd_card *card, - struct pci_dev *pci, - snd_cx88_card_t **rchip) +static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, + snd_cx88_card_t **rchip) { snd_cx88_card_t *chip; struct cx88_core *core; @@ -676,11 +672,6 @@ static int __devinit snd_cx88_create(struct snd_card *card, chip = (snd_cx88_card_t *) card->private_data; core = cx88_core_get(pci); - if (NULL == core) { - err = -EINVAL; - kfree (chip); - return err; - } if (!pci_dma_supported(pci,0xffffffff)) { dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); @@ -697,6 +688,11 @@ static int __devinit snd_cx88_create(struct snd_card *card, spin_lock_init(&chip->reg_lock); cx88_reset(core); + if (NULL == core) { + err = -EINVAL; + kfree (chip); + return err; + } chip->core = core; /* get irq */ @@ -730,7 +726,7 @@ static int __devinit snd_cx88_create(struct snd_card *card, static int __devinit cx88_audio_initdev(struct pci_dev *pci, const struct pci_device_id *pci_id) { - struct snd_card *card; + snd_card_t *card; snd_cx88_card_t *chip; int err; diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index e100d8ef3..a502a4d6e 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1341,7 +1341,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct cx8802_fh *fh = q->priv_data; - return cx8802_buf_prepare(q, fh->dev, (struct cx88_buffer*)vb, field); + return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field); } static void @@ -1354,7 +1354,8 @@ bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) static void bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { - cx88_free_buffer(q, (struct cx88_buffer*)vb); + struct cx8802_fh *fh = q->priv_data; + cx88_free_buffer(fh->dev->pci, (struct cx88_buffer*)vb); } static struct videobuf_queue_ops blackbird_qops = { diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index f80154b87..a24af92c7 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -184,18 +184,17 @@ struct cx88_board cx88_boards[] = { .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio1 = 0xe09f, + .gpio1 = 0x309f, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio1 = 0xe05f, + .gpio1 = 0x305f, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio1 = 0xe05f, + .gpio1 = 0x305f, }}, .radio = { - .gpio1 = 0xe0df, .type = CX88_RADIO, }, }, @@ -323,19 +322,19 @@ struct cx88_board cx88_boards[] = { .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio0 = 0xbff0, + .gpio0 = 0xff00, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio0 = 0xbff3, + .gpio0 = 0xff03, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio0 = 0xbff3, + .gpio0 = 0xff03, }}, .radio = { .type = CX88_RADIO, - .gpio0 = 0xbff0, + .gpio0 = 0xff00, }, }, [CX88_BOARD_ASUS_PVR_416] = { @@ -564,7 +563,7 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_PCHDTV_HD3000] = { .name = "pcHDTV HD3000 HDTV", - .tuner_type = TUNER_THOMSON_DTT761X, + .tuner_type = TUNER_THOMSON_DTT7610, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1049,50 +1048,6 @@ struct cx88_board cx88_boards[] = { }}, .dvb = 1, }, - [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = { - /* FIXME: Standard video using the cx88 broadcast decoder is - * working, but blackbird isn't working yet, audio is only - * working correctly for television mode. S-Video and Composite - * are working for video-only, so I have them disabled for now. - */ - .name = "KWorld HardwareMpegTV XPert", - .tuner_type = TUNER_PHILIPS_TDA8290, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x3de2, - .gpio2 = 0x00ff, - }}, - .radio = { - .type = CX88_RADIO, - .gpio0 = 0x3de6, - .gpio2 = 0x00ff, - }, - }, - [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = { - .name = "DViCO FusionHDTV DVB-T Hybrid", - .tuner_type = TUNER_THOMSON_FE6600, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x0000a75f, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x0000a75b, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x0000a75b, - }}, - .dvb = 1, - }, }; const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); @@ -1299,18 +1254,6 @@ struct cx88_subid cx88_subids[] = { .subdevice = 0xdb11, .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, /* Re-branded DViCO: UltraView DVB-T Plus */ - },{ - .subvendor = 0x17de, - .subdevice = 0x0840, - .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, - },{ - .subvendor = 0x18ac, - .subdevice = 0xdb40, - .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID, - },{ - .subvendor = 0x18ac, - .subdevice = 0xdb44, - .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID, }, }; const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); @@ -1318,7 +1261,7 @@ const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); /* ----------------------------------------------------------------------- */ /* some leadtek specific stuff */ -static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) +static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) { /* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on * any others. @@ -1429,40 +1372,6 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) core->has_radio = gdi_tuner[eeprom_data[0x0d]].fm; } -/* ----------------------------------------------------------------------- */ -/* some DViCO specific stuff */ - -static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core) -{ - struct i2c_msg msg = { .addr = 0x45, .flags = 0 }; - int i, err; - static u8 init_bufs[13][5] = { - { 0x10, 0x00, 0x20, 0x01, 0x03 }, - { 0x10, 0x10, 0x01, 0x00, 0x21 }, - { 0x10, 0x10, 0x10, 0x00, 0xCA }, - { 0x10, 0x10, 0x12, 0x00, 0x08 }, - { 0x10, 0x10, 0x13, 0x00, 0x0A }, - { 0x10, 0x10, 0x16, 0x01, 0xC0 }, - { 0x10, 0x10, 0x22, 0x01, 0x3D }, - { 0x10, 0x10, 0x73, 0x01, 0x2E }, - { 0x10, 0x10, 0x72, 0x00, 0xC5 }, - { 0x10, 0x10, 0x71, 0x01, 0x97 }, - { 0x10, 0x10, 0x70, 0x00, 0x0F }, - { 0x10, 0x10, 0xB0, 0x00, 0x01 }, - { 0x03, 0x0C }, - }; - - for (i = 0; i < 13; i++) { - msg.buf = init_bufs[i]; - msg.len = (i != 12 ? 5 : 2); - err = i2c_transfer(&core->i2c_adap, &msg, 1); - if (err != 1) { - printk("dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", i, err); - return; - } - } -} - /* ----------------------------------------------------------------------- */ void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) @@ -1529,15 +1438,11 @@ void cx88_card_setup(struct cx88_core *core) case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: - case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: /* GPIO0:0 is hooked to mt352 reset pin */ cx_set(MO_GP0_IO, 0x00000101); cx_clear(MO_GP0_IO, 0x00000001); msleep(1); cx_set(MO_GP0_IO, 0x00000101); - if (0 == core->i2c_rc && - core->board == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID) - dvico_fusionhdtv_hybrid_init(core); break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: @@ -1555,7 +1460,7 @@ void cx88_card_setup(struct cx88_core *core) if (0 == core->i2c_rc) { /* enable tuner */ int i; - static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; + u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; core->i2c_client.addr = 0x0a; for (i = 0; i < 5; i++) diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index e1092d5d4..3720f24a2 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -146,11 +146,9 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, fields++; /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Padding - can cause next bpl to start close to a page border. First DMA - region may be smaller than PAGE_SIZE */ - instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); - instructions += 2; + one write per scan line + syncs + jump (all 2 dwords) */ + instructions = (bpl * lines * fields) / PAGE_SIZE + lines * fields; + instructions += 3 + 4; if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) return rc; @@ -165,7 +163,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); + BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); return 0; } @@ -178,11 +176,9 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, int rc; /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Here - there is no padding and no sync. First DMA region may be smaller - than PAGE_SIZE */ - instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; - instructions += 1; + one write per scan line + syncs + jump (all 2 dwords) */ + instructions = (bpl * lines) / PAGE_SIZE + lines; + instructions += 3 + 4; if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) return rc; @@ -192,7 +188,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); + BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); return 0; } @@ -217,13 +213,14 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, } void -cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) +cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf) { - BUG_ON(in_interrupt()); + if (in_interrupt()) + BUG(); videobuf_waiton(&buf->vb,0,0); - videobuf_dma_unmap(q, &buf->vb.dma); + videobuf_dma_pci_unmap(pci, &buf->vb.dma); videobuf_dma_free(&buf->vb.dma); - btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc); + btcx_riscmem_free(pci, &buf->risc); buf->vb.state = STATE_NEEDS_INIT; } @@ -1064,7 +1061,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) core->pci_bus = pci->bus->number; core->pci_slot = PCI_SLOT(pci->devfn); core->pci_irqmask = 0x00fc00; - mutex_init(&core->lock); + init_MUTEX(&core->lock); core->nr = cx88_devcount++; sprintf(core->name,"cx88[%d]",core->nr); diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 3619a449a..e48aa3f6e 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -40,9 +40,6 @@ # include "cx88-vp3054-i2c.h" # endif #endif -#ifdef HAVE_ZL10353 -# include "zl10353.h" -#endif #ifdef HAVE_CX22702 # include "cx22702.h" #endif @@ -90,7 +87,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct cx8802_dev *dev = q->priv_data; - return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field); + return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field); } static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) @@ -101,7 +98,8 @@ static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { - cx88_free_buffer(q, (struct cx88_buffer*)vb); + struct cx8802_dev *dev = q->priv_data; + cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb); } static struct videobuf_queue_ops dvb_qops = { @@ -113,21 +111,6 @@ static struct videobuf_queue_ops dvb_qops = { /* ------------------------------------------------------------------ */ -#if defined(HAVE_MT352) || defined(HAVE_ZL10353) -static int zarlink_pll_set(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, - u8 *pllbuf) -{ - struct cx8802_dev *dev = fe->dvb->priv; - - pllbuf[0] = dev->core->pll_addr << 1; - dvb_pll_configure(dev->core->pll_desc, pllbuf + 1, - params->frequency, - params->u.ofdm.bandwidth); - return 0; -} -#endif - #ifdef HAVE_MT352 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) { @@ -193,22 +176,35 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) return 0; } +static int mt352_pll_set(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params, + u8* pllbuf) +{ + struct cx8802_dev *dev= fe->dvb->priv; + + pllbuf[0] = dev->core->pll_addr << 1; + dvb_pll_configure(dev->core->pll_desc, pllbuf+1, + params->frequency, + params->u.ofdm.bandwidth); + return 0; +} + static struct mt352_config dvico_fusionhdtv = { .demod_address = 0x0F, .demod_init = dvico_fusionhdtv_demod_init, - .pll_set = zarlink_pll_set, + .pll_set = mt352_pll_set, }; static struct mt352_config dntv_live_dvbt_config = { .demod_address = 0x0f, .demod_init = dntv_live_dvbt_demod_init, - .pll_set = zarlink_pll_set, + .pll_set = mt352_pll_set, }; static struct mt352_config dvico_fusionhdtv_dual = { .demod_address = 0x0F, .demod_init = dvico_dual_demod_init, - .pll_set = zarlink_pll_set, + .pll_set = mt352_pll_set, }; #ifdef HAVE_VP3054_I2C @@ -298,46 +294,6 @@ static struct mt352_config dntv_live_dvbt_pro_config = { #endif #endif -#ifdef HAVE_ZL10353 -static int dvico_hybrid_tune_pll(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, - u8 *pllbuf) -{ - struct cx8802_dev *dev= fe->dvb->priv; - struct i2c_msg msg = - { .addr = dev->core->pll_addr, .flags = 0, - .buf = pllbuf + 1, .len = 4 }; - int err; - - pllbuf[0] = dev->core->pll_addr << 1; - dvb_pll_configure(dev->core->pll_desc, pllbuf + 1, - params->frequency, - params->u.ofdm.bandwidth); - - if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { - printk(KERN_WARNING "cx88-dvb: %s error " - "(addr %02x <- %02x, err = %i)\n", - __FUNCTION__, pllbuf[0], pllbuf[1], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} - -static struct zl10353_config dvico_fusionhdtv_hybrid = { - .demod_address = 0x0F, - .pll_set = dvico_hybrid_tune_pll, -}; - -static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { - .demod_address = 0x0F, - .pll_set = zarlink_pll_set, -}; -#endif - #ifdef HAVE_CX22702 static struct cx22702_config connexant_refboard_config = { .demod_address = 0x43, @@ -372,7 +328,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe, static struct or51132_config pchdtv_hd3000 = { .demod_address = 0x15, .pll_address = 0x61, - .pll_desc = &dvb_pll_thomson_dtt761x, + .pll_desc = &dvb_pll_thomson_dtt7610, .set_ts_params = or51132_set_ts_param, }; #endif @@ -544,23 +500,6 @@ static int dvb_register(struct cx8802_dev *dev) &dev->core->i2c_adap); break; #endif -#if defined(HAVE_MT352) || defined(HAVE_ZL10353) - case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: - dev->core->pll_addr = 0x60; - dev->core->pll_desc = &dvb_pll_thomson_dtt7579; -#ifdef HAVE_MT352 - dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, - &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) - break; -#endif -#ifdef HAVE_ZL10353 - /* ZL10353 replaces MT352 on later cards */ - dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1, - &dev->core->i2c_adap); -#endif - break; -#endif /* HAVE_MT352 || HAVE_ZL10353 */ #ifdef HAVE_MT352 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: dev->core->pll_addr = 0x61; @@ -568,6 +507,12 @@ static int dvb_register(struct cx8802_dev *dev) dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, &dev->core->i2c_adap); break; + case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: + dev->core->pll_addr = 0x60; + dev->core->pll_desc = &dvb_pll_thomson_dtt7579; + dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, + &dev->core->i2c_adap); + break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: @@ -595,14 +540,6 @@ static int dvb_register(struct cx8802_dev *dev) &dev->core->i2c_adap); break; #endif -#ifdef HAVE_ZL10353 - case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: - dev->core->pll_addr = 0x61; - dev->core->pll_desc = &dvb_pll_thomson_fe6600; - dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid, - &dev->core->i2c_adap); - break; -#endif #ifdef HAVE_OR51132 case CX88_BOARD_PCHDTV_HD3000: dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 78a63b7dd..165d94862 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -34,6 +34,337 @@ /* ---------------------------------------------------------------------- */ +/* DigitalNow DNTV Live DVB-T Remote */ +static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = { + [0x00] = KEY_ESC, /* 'go up a level?' */ + /* Keys 0 to 9 */ + [0x0a] = KEY_KP0, + [0x01] = KEY_KP1, + [0x02] = KEY_KP2, + [0x03] = KEY_KP3, + [0x04] = KEY_KP4, + [0x05] = KEY_KP5, + [0x06] = KEY_KP6, + [0x07] = KEY_KP7, + [0x08] = KEY_KP8, + [0x09] = KEY_KP9, + + [0x0b] = KEY_TUNER, /* tv/fm */ + [0x0c] = KEY_SEARCH, /* scan */ + [0x0d] = KEY_STOP, + [0x0e] = KEY_PAUSE, + [0x0f] = KEY_LIST, /* source */ + + [0x10] = KEY_MUTE, + [0x11] = KEY_REWIND, /* backward << */ + [0x12] = KEY_POWER, + [0x13] = KEY_S, /* snap */ + [0x14] = KEY_AUDIO, /* stereo */ + [0x15] = KEY_CLEAR, /* reset */ + [0x16] = KEY_PLAY, + [0x17] = KEY_ENTER, + [0x18] = KEY_ZOOM, /* full screen */ + [0x19] = KEY_FASTFORWARD, /* forward >> */ + [0x1a] = KEY_CHANNELUP, + [0x1b] = KEY_VOLUMEUP, + [0x1c] = KEY_INFO, /* preview */ + [0x1d] = KEY_RECORD, /* record */ + [0x1e] = KEY_CHANNELDOWN, + [0x1f] = KEY_VOLUMEDOWN, +}; + +/* ---------------------------------------------------------------------- */ + +/* IO-DATA BCTV7E Remote */ +static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = { + [0x40] = KEY_TV, + [0x20] = KEY_RADIO, /* FM */ + [0x60] = KEY_EPG, + [0x00] = KEY_POWER, + + /* Keys 0 to 9 */ + [0x44] = KEY_KP0, /* 10 */ + [0x50] = KEY_KP1, + [0x30] = KEY_KP2, + [0x70] = KEY_KP3, + [0x48] = KEY_KP4, + [0x28] = KEY_KP5, + [0x68] = KEY_KP6, + [0x58] = KEY_KP7, + [0x38] = KEY_KP8, + [0x78] = KEY_KP9, + + [0x10] = KEY_L, /* Live */ + [0x08] = KEY_T, /* Time Shift */ + + [0x18] = KEY_PLAYPAUSE, /* Play */ + + [0x24] = KEY_ENTER, /* 11 */ + [0x64] = KEY_ESC, /* 12 */ + [0x04] = KEY_M, /* Multi */ + + [0x54] = KEY_VIDEO, + [0x34] = KEY_CHANNELUP, + [0x74] = KEY_VOLUMEUP, + [0x14] = KEY_MUTE, + + [0x4c] = KEY_S, /* SVIDEO */ + [0x2c] = KEY_CHANNELDOWN, + [0x6c] = KEY_VOLUMEDOWN, + [0x0c] = KEY_ZOOM, + + [0x5c] = KEY_PAUSE, + [0x3c] = KEY_C, /* || (red) */ + [0x7c] = KEY_RECORD, /* recording */ + [0x1c] = KEY_STOP, + + [0x41] = KEY_REWIND, /* backward << */ + [0x21] = KEY_PLAY, + [0x61] = KEY_FASTFORWARD, /* forward >> */ + [0x01] = KEY_NEXT, /* skip >| */ +}; + +/* ---------------------------------------------------------------------- */ + +/* ADS Tech Instant TV DVB-T PCI Remote */ +static IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = { + /* Keys 0 to 9 */ + [0x4d] = KEY_0, + [0x57] = KEY_1, + [0x4f] = KEY_2, + [0x53] = KEY_3, + [0x56] = KEY_4, + [0x4e] = KEY_5, + [0x5e] = KEY_6, + [0x54] = KEY_7, + [0x4c] = KEY_8, + [0x5c] = KEY_9, + + [0x5b] = KEY_POWER, + [0x5f] = KEY_MUTE, + [0x55] = KEY_GOTO, + [0x5d] = KEY_SEARCH, + [0x17] = KEY_EPG, /* Guide */ + [0x1f] = KEY_MENU, + [0x0f] = KEY_UP, + [0x46] = KEY_DOWN, + [0x16] = KEY_LEFT, + [0x1e] = KEY_RIGHT, + [0x0e] = KEY_SELECT, /* Enter */ + [0x5a] = KEY_INFO, + [0x52] = KEY_EXIT, + [0x59] = KEY_PREVIOUS, + [0x51] = KEY_NEXT, + [0x58] = KEY_REWIND, + [0x50] = KEY_FORWARD, + [0x44] = KEY_PLAYPAUSE, + [0x07] = KEY_STOP, + [0x1b] = KEY_RECORD, + [0x13] = KEY_TUNER, /* Live */ + [0x0a] = KEY_A, + [0x12] = KEY_B, + [0x03] = KEY_PROG1, /* 1 */ + [0x01] = KEY_PROG2, /* 2 */ + [0x00] = KEY_PROG3, /* 3 */ + [0x06] = KEY_DVD, + [0x48] = KEY_AUX, /* Photo */ + [0x40] = KEY_VIDEO, + [0x19] = KEY_AUDIO, /* Music */ + [0x0b] = KEY_CHANNELUP, + [0x08] = KEY_CHANNELDOWN, + [0x15] = KEY_VOLUMEUP, + [0x1c] = KEY_VOLUMEDOWN, +}; + +/* ---------------------------------------------------------------------- */ + +/* MSI TV@nywhere remote */ +static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = { + /* Keys 0 to 9 */ + [0x00] = KEY_0, + [0x01] = KEY_1, + [0x02] = KEY_2, + [0x03] = KEY_3, + [0x04] = KEY_4, + [0x05] = KEY_5, + [0x06] = KEY_6, + [0x07] = KEY_7, + [0x08] = KEY_8, + [0x09] = KEY_9, + + [0x0c] = KEY_MUTE, + [0x0f] = KEY_SCREEN, /* Full Screen */ + [0x10] = KEY_F, /* Funtion */ + [0x11] = KEY_T, /* Time shift */ + [0x12] = KEY_POWER, + [0x13] = KEY_MEDIA, /* MTS */ + [0x14] = KEY_SLOW, + [0x16] = KEY_REWIND, /* backward << */ + [0x17] = KEY_ENTER, /* Return */ + [0x18] = KEY_FASTFORWARD, /* forward >> */ + [0x1a] = KEY_CHANNELUP, + [0x1b] = KEY_VOLUMEUP, + [0x1e] = KEY_CHANNELDOWN, + [0x1f] = KEY_VOLUMEDOWN, +}; + +/* ---------------------------------------------------------------------- */ + +/* Cinergy 1400 DVB-T */ +static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { + [0x01] = KEY_POWER, + [0x02] = KEY_1, + [0x03] = KEY_2, + [0x04] = KEY_3, + [0x05] = KEY_4, + [0x06] = KEY_5, + [0x07] = KEY_6, + [0x08] = KEY_7, + [0x09] = KEY_8, + [0x0a] = KEY_9, + [0x0c] = KEY_0, + + [0x0b] = KEY_VIDEO, + [0x0d] = KEY_REFRESH, + [0x0e] = KEY_SELECT, + [0x0f] = KEY_EPG, + [0x10] = KEY_UP, + [0x11] = KEY_LEFT, + [0x12] = KEY_OK, + [0x13] = KEY_RIGHT, + [0x14] = KEY_DOWN, + [0x15] = KEY_TEXT, + [0x16] = KEY_INFO, + + [0x17] = KEY_RED, + [0x18] = KEY_GREEN, + [0x19] = KEY_YELLOW, + [0x1a] = KEY_BLUE, + + [0x1b] = KEY_CHANNELUP, + [0x1c] = KEY_VOLUMEUP, + [0x1d] = KEY_MUTE, + [0x1e] = KEY_VOLUMEDOWN, + [0x1f] = KEY_CHANNELDOWN, + + [0x40] = KEY_PAUSE, + [0x4c] = KEY_PLAY, + [0x58] = KEY_RECORD, + [0x54] = KEY_PREVIOUS, + [0x48] = KEY_STOP, + [0x5c] = KEY_NEXT, +}; + +/* ---------------------------------------------------------------------- */ + +/* AVERTV STUDIO 303 Remote */ +static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = { + [ 0x2a ] = KEY_KP1, + [ 0x32 ] = KEY_KP2, + [ 0x3a ] = KEY_KP3, + [ 0x4a ] = KEY_KP4, + [ 0x52 ] = KEY_KP5, + [ 0x5a ] = KEY_KP6, + [ 0x6a ] = KEY_KP7, + [ 0x72 ] = KEY_KP8, + [ 0x7a ] = KEY_KP9, + [ 0x0e ] = KEY_KP0, + + [ 0x02 ] = KEY_POWER, + [ 0x22 ] = KEY_VIDEO, + [ 0x42 ] = KEY_AUDIO, + [ 0x62 ] = KEY_ZOOM, + [ 0x0a ] = KEY_TV, + [ 0x12 ] = KEY_CD, + [ 0x1a ] = KEY_TEXT, + + [ 0x16 ] = KEY_SUBTITLE, + [ 0x1e ] = KEY_REWIND, + [ 0x06 ] = KEY_PRINT, + + [ 0x2e ] = KEY_SEARCH, + [ 0x36 ] = KEY_SLEEP, + [ 0x3e ] = KEY_SHUFFLE, + [ 0x26 ] = KEY_MUTE, + + [ 0x4e ] = KEY_RECORD, + [ 0x56 ] = KEY_PAUSE, + [ 0x5e ] = KEY_STOP, + [ 0x46 ] = KEY_PLAY, + + [ 0x6e ] = KEY_RED, + [ 0x0b ] = KEY_GREEN, + [ 0x66 ] = KEY_YELLOW, + [ 0x03 ] = KEY_BLUE, + + [ 0x76 ] = KEY_LEFT, + [ 0x7e ] = KEY_RIGHT, + [ 0x13 ] = KEY_DOWN, + [ 0x1b ] = KEY_UP, +}; + +/* ---------------------------------------------------------------------- */ + +/* DigitalNow DNTV Live! DVB-T Pro Remote */ +static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = { + [ 0x16 ] = KEY_POWER, + [ 0x5b ] = KEY_HOME, + + [ 0x55 ] = KEY_TV, /* live tv */ + [ 0x58 ] = KEY_TUNER, /* digital Radio */ + [ 0x5a ] = KEY_RADIO, /* FM radio */ + [ 0x59 ] = KEY_DVD, /* dvd menu */ + [ 0x03 ] = KEY_1, + [ 0x01 ] = KEY_2, + [ 0x06 ] = KEY_3, + [ 0x09 ] = KEY_4, + [ 0x1d ] = KEY_5, + [ 0x1f ] = KEY_6, + [ 0x0d ] = KEY_7, + [ 0x19 ] = KEY_8, + [ 0x1b ] = KEY_9, + [ 0x0c ] = KEY_CANCEL, + [ 0x15 ] = KEY_0, + [ 0x4a ] = KEY_CLEAR, + [ 0x13 ] = KEY_BACK, + [ 0x00 ] = KEY_TAB, + [ 0x4b ] = KEY_UP, + [ 0x4e ] = KEY_LEFT, + [ 0x4f ] = KEY_OK, + [ 0x52 ] = KEY_RIGHT, + [ 0x51 ] = KEY_DOWN, + [ 0x1e ] = KEY_VOLUMEUP, + [ 0x0a ] = KEY_VOLUMEDOWN, + [ 0x02 ] = KEY_CHANNELDOWN, + [ 0x05 ] = KEY_CHANNELUP, + [ 0x11 ] = KEY_RECORD, + [ 0x14 ] = KEY_PLAY, + [ 0x4c ] = KEY_PAUSE, + [ 0x1a ] = KEY_STOP, + [ 0x40 ] = KEY_REWIND, + [ 0x12 ] = KEY_FASTFORWARD, + [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */ + [ 0x42 ] = KEY_NEXTSONG, /* skip >| */ + [ 0x54 ] = KEY_CAMERA, /* capture */ + [ 0x50 ] = KEY_LANGUAGE, /* sap */ + [ 0x47 ] = KEY_TV2, /* pip */ + [ 0x4d ] = KEY_SCREEN, + [ 0x43 ] = KEY_SUBTITLE, + [ 0x10 ] = KEY_MUTE, + [ 0x49 ] = KEY_AUDIO, /* l/r */ + [ 0x07 ] = KEY_SLEEP, + [ 0x08 ] = KEY_VIDEO, /* a/v */ + [ 0x0e ] = KEY_PREVIOUS, /* recall */ + [ 0x45 ] = KEY_ZOOM, /* zoom + */ + [ 0x46 ] = KEY_ANGLE, /* zoom - */ + [ 0x56 ] = KEY_RED, + [ 0x57 ] = KEY_GREEN, + [ 0x5c ] = KEY_YELLOW, + [ 0x5d ] = KEY_BLUE, +}; + +/* ---------------------------------------------------------------------- */ + struct cx88_IR { struct cx88_core *core; struct input_dev *input; @@ -186,7 +517,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keydown = 0x02; ir->polling = 5; /* ms */ break; - case CX88_BOARD_PROLINK_PLAYTVPVR: case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: ir_codes = ir_codes_pixelview; ir->gpio_addr = MO_GP1_IO; @@ -194,13 +524,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keyup = 0x80; ir->polling = 1; /* ms */ break; - case CX88_BOARD_KWORLD_LTV883: - ir_codes = ir_codes_pixelview; - ir->gpio_addr = MO_GP1_IO; - ir->mask_keycode = 0x1f; - ir->mask_keyup = 0x60; - ir->polling = 1; /* ms */ - break; case CX88_BOARD_ADSTECH_DVB_T_PCI: ir_codes = ir_codes_adstech_dvb_t_pci; ir->gpio_addr = MO_GP1_IO; diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 7d16888b4..c79cc1d2b 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -163,8 +163,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, /* ------------------------------------------------------------------ */ -int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, - struct cx88_buffer *buf, enum v4l2_field field) +int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf, + enum v4l2_field field) { int size = dev->ts_packet_size * dev->ts_packet_count; int rc; @@ -179,7 +179,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, buf->vb.size = size; buf->vb.field = field /*V4L2_FIELD_TOP*/; - if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) + if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) goto fail; cx88_risc_databuffer(dev->pci, &buf->risc, buf->vb.dma.sglist, @@ -189,36 +189,36 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, return 0; fail: - cx88_free_buffer(q,buf); + cx88_free_buffer(dev->pci,buf); return rc; } void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) { struct cx88_buffer *prev; - struct cx88_dmaqueue *cx88q = &dev->mpegq; + struct cx88_dmaqueue *q = &dev->mpegq; dprintk( 1, "cx8802_buf_queue\n" ); /* add jump to stopper */ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); + buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); - if (list_empty(&cx88q->active)) { + if (list_empty(&q->active)) { dprintk( 0, "queue is empty - first active\n" ); - list_add_tail(&buf->vb.queue,&cx88q->active); - cx8802_start_dma(dev, cx88q, buf); + list_add_tail(&buf->vb.queue,&q->active); + cx8802_start_dma(dev, q, buf); buf->vb.state = STATE_ACTIVE; - buf->count = cx88q->count++; - mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); + buf->count = q->count++; + mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(0,"[%p/%d] %s - first active\n", buf, buf->vb.i, __FUNCTION__); } else { dprintk( 1, "queue is not empty - append to active\n" ); - prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue); - list_add_tail(&buf->vb.queue,&cx88q->active); + prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); + list_add_tail(&buf->vb.queue,&q->active); buf->vb.state = STATE_ACTIVE; - buf->count = cx88q->count++; + buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk( 1, "[%p/%d] %s - append to active\n", buf, buf->vb.i, __FUNCTION__); diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 641a0c5a6..da8d97ce0 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -885,7 +885,6 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP); break; case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1_LANG2: set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO); break; } @@ -906,7 +905,6 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) EN_NICAM_FORCE_MONO2); break; case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1_LANG2: set_audio_standard_NICAM(core, EN_NICAM_FORCE_STEREO); break; @@ -928,7 +926,6 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) EN_A2_FORCE_MONO2); break; case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1_LANG2: set_audio_standard_A2(core, EN_A2_FORCE_STEREO); break; diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index 846faadc9..9bc6c8995 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c @@ -175,7 +175,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, buf->vb.size = size; buf->vb.field = V4L2_FIELD_SEQ_TB; - if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) + if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) goto fail; cx88_risc_buffer(dev->pci, &buf->risc, buf->vb.dma.sglist, @@ -187,7 +187,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, return 0; fail: - cx88_free_buffer(q,buf); + cx88_free_buffer(dev->pci,buf); return rc; } @@ -227,8 +227,9 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); + struct cx8800_fh *fh = q->priv_data; - cx88_free_buffer(q,buf); + cx88_free_buffer(fh->dev->pci,buf); } struct videobuf_queue_ops cx8800_vbi_qops = { diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 694d1d80f..073494cea 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -35,10 +35,8 @@ #include "cx88.h" #include -#ifdef CONFIG_VIDEO_V4L1_COMPAT /* Include V4L1 specific functions. Should be removed soon */ #include -#endif MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); @@ -229,7 +227,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0x00, .maximum = 0xff, .step = 1, - .default_value = 0x7f, + .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, .off = 128, @@ -257,7 +255,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0, .maximum = 0xff, .step = 1, - .default_value = 0x7f, + .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, .off = 128, @@ -302,7 +300,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0, .maximum = 0x3f, .step = 1, - .default_value = 0x3f, + .default_value = 0x1f, .type = V4L2_CTRL_TYPE_INTEGER, }, .reg = AUD_VOL_CTL, @@ -338,17 +336,17 @@ static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bi return 1; /* is it free? */ - mutex_lock(&core->lock); + down(&core->lock); if (dev->resources & bit) { /* no, someone else uses it */ - mutex_unlock(&core->lock); + up(&core->lock); return 0; } /* it's free, grab it */ fh->resources |= bit; dev->resources |= bit; dprintk(1,"res: get %d\n",bit); - mutex_unlock(&core->lock); + up(&core->lock); return 1; } @@ -368,13 +366,14 @@ static void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) { struct cx88_core *core = dev->core; - BUG_ON((fh->resources & bits) != bits); + if ((fh->resources & bits) != bits) + BUG(); - mutex_lock(&core->lock); + down(&core->lock); fh->resources &= ~bits; dev->resources &= ~bits; dprintk(1,"res: put %d\n",bits); - mutex_unlock(&core->lock); + up(&core->lock); } /* ------------------------------------------------------------------ */ @@ -566,7 +565,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, if (STATE_NEEDS_INIT == buf->vb.state) { init_buffer = 1; - if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) + if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) goto fail; } @@ -616,7 +615,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, return 0; fail: - cx88_free_buffer(q,buf); + cx88_free_buffer(dev->pci,buf); return rc; } @@ -673,8 +672,9 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); + struct cx8800_fh *fh = q->priv_data; - cx88_free_buffer(q,buf); + cx88_free_buffer(fh->dev->pci,buf); } static struct videobuf_queue_ops cx8800_video_qops = { @@ -909,8 +909,7 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl) value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg); switch (ctl->id) { case V4L2_CID_AUDIO_BALANCE: - ctl->value = ((value & 0x7f) < 0x40) ? ((value & 0x7f) + 0x40) - : (0x7f - (value & 0x7f)); + ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f)); break; case V4L2_CID_AUDIO_VOLUME: ctl->value = 0x3f - (value & 0x3f); @@ -919,9 +918,9 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl) ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; break; } - dprintk(1,"get_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", - ctl->id, c->v.name, ctl->value, c->reg, - value,c->mask, c->sreg ? " [shadowed]" : ""); + printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", + ctl->id, c->reg, ctl->value, + c->mask, c->sreg ? " [shadowed]" : ""); return 0; } @@ -947,7 +946,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) mask=c->mask; switch (ctl->id) { case V4L2_CID_AUDIO_BALANCE: - value = (ctl->value < 0x40) ? (0x7f - ctl->value) : (ctl->value - 0x40); + value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; break; case V4L2_CID_AUDIO_VOLUME: value = 0x3f - (ctl->value & 0x3f); @@ -970,9 +969,9 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) value = ((ctl->value - c->off) << c->shift) & c->mask; break; } - dprintk(1,"set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", - ctl->id, c->v.name, ctl->value, c->reg, value, - mask, c->sreg ? " [shadowed]" : ""); + printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", + ctl->id, c->reg, value, + mask, c->sreg ? " [shadowed]" : ""); if (c->sreg) { cx_sandor(c->sreg, c->reg, mask, value); } else { @@ -988,7 +987,8 @@ static void init_controls(struct cx88_core *core) for (i = 0; i < CX8800_CTLS; i++) { ctrl.id=cx8800_ctls[i].v.id; - ctrl.value=cx8800_ctls[i].v.default_value; + ctrl.value=cx8800_ctls[i].v.default_value + +cx8800_ctls[i].off; set_control(core, &ctrl); } } @@ -1252,17 +1252,9 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, { int err; - if (video_debug) { - if (video_debug > 1) { - if (_IOC_DIR(cmd) & _IOC_WRITE) - v4l_printk_ioctl_arg("cx88(w)",cmd, arg); - else if (!_IOC_DIR(cmd) & _IOC_READ) { - v4l_print_ioctl("cx88", cmd); - } - } else - v4l_print_ioctl(core->name,cmd); - - } + dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); + if (video_debug > 1) + v4l_print_ioctl(core->name,cmd); switch (cmd) { /* ---------- tv norms ---------- */ @@ -1299,9 +1291,9 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, if (i == ARRAY_SIZE(tvnorms)) return -EINVAL; - mutex_lock(&core->lock); + down(&core->lock); cx88_set_tvnorm(core,&tvnorms[i]); - mutex_unlock(&core->lock); + up(&core->lock); return 0; } @@ -1351,10 +1343,10 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, if (*i >= 4) return -EINVAL; - mutex_lock(&core->lock); + down(&core->lock); cx88_newstation(core); video_mux(core,*i); - mutex_unlock(&core->lock); + up(&core->lock); return 0; } @@ -1446,7 +1438,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, return -EINVAL; if (1 == radio && f->type != V4L2_TUNER_RADIO) return -EINVAL; - mutex_lock(&core->lock); + down(&core->lock); core->freq = f->frequency; cx88_newstation(core); cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); @@ -1455,7 +1447,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, msleep (10); cx88_set_tvaudio(core); - mutex_unlock(&core->lock); + up(&core->lock); return 0; } @@ -1469,19 +1461,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, static int video_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int retval; - - retval=video_usercopy(inode, file, cmd, arg, video_do_ioctl); - - if (video_debug > 1) { - if (retval < 0) { - v4l_print_ioctl("cx88(err)", cmd); - printk(KERN_DEBUG "cx88(err): errcode=%d\n",retval); - } else if (_IOC_DIR(cmd) & _IOC_READ) - v4l_printk_ioctl_arg("cx88(r)",cmd, (void *)arg); - } - - return retval; + return video_usercopy(inode, file, cmd, arg, video_do_ioctl); } /* ----------------------------------------------------------- */ @@ -1941,11 +1921,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, pci_set_drvdata(pci_dev,dev); /* initial device configuration */ - mutex_lock(&core->lock); + down(&core->lock); cx88_set_tvnorm(core,tvnorms); init_controls(core); video_mux(core,0); - mutex_unlock(&core->lock); + up(&core->lock); /* start tvaudio thread */ if (core->tuner_type != TUNER_ABSENT) diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 326a25f14..e9fd55b57 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -34,7 +35,6 @@ #include "cx88-reg.h" #include -#include #define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) #ifndef TRUE @@ -62,7 +62,7 @@ /* need "shadow" registers for some write-only ones ... */ #define SHADOW_AUD_VOL_CTL 1 #define SHADOW_AUD_BAL_CTL 2 -#define SHADOW_MAX 3 +#define SHADOW_MAX 2 /* FM Radio deemphasis type */ enum cx88_deemph_type { @@ -187,8 +187,6 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42 #define CX88_BOARD_KWORLD_DVB_T_CX22702 43 #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 -#define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45 -#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, @@ -310,7 +308,8 @@ struct cx88_core { /* IR remote control state */ struct cx88_IR *ir; - struct mutex lock; + struct semaphore lock; + /* various v4l controls */ u32 freq; @@ -484,7 +483,7 @@ extern int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, u32 reg, u32 mask, u32 value); extern void -cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf); +cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf); extern void cx88_risc_disasm(struct cx88_core *core, struct btcx_riscmem *risc); @@ -576,8 +575,8 @@ void cx88_ir_irq(struct cx88_core *core); /* ----------------------------------------------------------- */ /* cx88-mpeg.c */ -int cx8802_buf_prepare(struct videobuf_queue *q,struct cx8802_dev *dev, - struct cx88_buffer *buf, enum v4l2_field field); +int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf, + enum v4l2_field field); void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); void cx8802_cancel_buffers(struct cx8802_dev *dev); diff --git a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c index 0fcc93582..2831bdd12 100644 --- a/drivers/media/video/dpc7146.c +++ b/drivers/media/video/dpc7146.c @@ -1,6 +1,6 @@ /* dpc7146.c - v4l2 driver for the dpc7146 demonstration board - + Copyright (C) 2000-2003 Michael Hunold This program is free software; you can redistribute it and/or modify @@ -52,7 +52,7 @@ #define SAA711X_DECODED_BYTES_OF_TS_2 0x1C #define SAA711X_STATUS_BYTE 0x1F -#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) +#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) static int debug = 0; module_param(debug, int, 0); @@ -81,16 +81,16 @@ struct dpc struct video_device *video_dev; struct video_device *vbi_dev; - struct i2c_adapter i2c_adapter; + struct i2c_adapter i2c_adapter; struct i2c_client *saa7111a; - + int cur_input; /* current input */ }; /* fixme: add vbi stuff here */ static int dpc_probe(struct saa7146_dev* dev) { - struct dpc* dpc = NULL; + struct dpc* dpc = NULL; struct i2c_client *client; struct list_head *item; @@ -118,20 +118,20 @@ static int dpc_probe(struct saa7146_dev* dev) /* loop through all i2c-devices on the bus and look who is there */ list_for_each(item,&dpc->i2c_adapter.clients) { client = list_entry(item, struct i2c_client, list); - if( I2C_SAA7111A == client->addr ) + if( I2C_SAA7111A == client->addr ) dpc->saa7111a = client; } /* check if all devices are present */ if( 0 == dpc->saa7111a ) { - DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); + DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); i2c_del_adapter(&dpc->i2c_adapter); kfree(dpc); return -ENODEV; } - - /* all devices are present, probe was successful */ - DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); + + /* all devices are present, probe was successful */ + DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); /* we store the pointer in our private data field */ dev->ext_priv = dpc; @@ -182,7 +182,7 @@ static struct saa7146_ext_vv vv_data; static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) { struct dpc* dpc = (struct dpc*)dev->ext_priv; - + DEB_D(("dpc_v4l2.o: dpc_attach called.\n")); /* checking for i2c-devices can be omitted here, because we @@ -193,7 +193,7 @@ static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data ERR(("cannot register capture v4l2 device. skipping.\n")); return -1; } - + /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) { @@ -205,18 +205,18 @@ static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num); dpc_num++; - + /* the rest */ dpc->cur_input = 0; dpc_init_done(dev); - + return 0; } static int dpc_detach(struct saa7146_dev* dev) { struct dpc* dpc = (struct dpc*)dev->ext_priv; - + DEB_EE(("dev:%p\n",dev)); i2c_release_client(dpc->saa7111a); @@ -238,25 +238,25 @@ static int dpc_detach(struct saa7146_dev* dev) int dpc_vbi_bypass(struct saa7146_dev* dev) { struct dpc* dpc = (struct dpc*)dev->ext_priv; - + int i = 1; /* switch bypass in saa7111a */ if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) { printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n"); return -1; - } + } return 0; } #endif -static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct saa7146_dev *dev = fh->dev; struct dpc* dpc = (struct dpc*)dev->ext_priv; /* - struct saa7146_vv *vv = dev->vv_data; + struct saa7146_vv *vv = dev->vv_data; */ switch(cmd) { @@ -264,11 +264,11 @@ static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct v4l2_input *i = arg; DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); - + if( i->index < 0 || i->index >= DPC_INPUTS) { return -EINVAL; } - + memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input)); DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index)); @@ -289,13 +289,13 @@ static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) if (input < 0 || input >= DPC_INPUTS) { return -EINVAL; } - + dpc->cur_input = input; /* fixme: switch input here, switch audio, too! */ // saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n"); - + return 0; } default: @@ -334,8 +334,8 @@ static struct saa7146_standard standard[] = { static struct saa7146_extension extension; static struct saa7146_pci_extension_data dpc = { - .ext_priv = "Multimedia eXtension Board", - .ext = &extension, + .ext_priv = "Multimedia eXtension Board", + .ext = &extension, }; static struct pci_device_id pci_tbl[] = { @@ -357,7 +357,7 @@ static struct saa7146_ext_vv vv_data = { .capabilities = V4L2_CAP_VBI_CAPTURE, .stds = &standard[0], .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), - .std_callback = &std_callback, + .std_callback = &std_callback, .ioctls = &ioctls[0], .ioctl = dpc_ioctl, }; @@ -365,7 +365,7 @@ static struct saa7146_ext_vv vv_data = { static struct saa7146_extension extension = { .name = "dpc7146 demonstration board", .flags = SAA7146_USE_I2C_IRQ, - + .pci_tbl = &pci_tbl[0], .module = THIS_MODULE, @@ -375,7 +375,7 @@ static struct saa7146_extension extension = { .irq_mask = 0, .irq_func = NULL, -}; +}; static int __init dpc_init_module(void) { @@ -383,7 +383,7 @@ static int __init dpc_init_module(void) DEB_S(("failed to register extension.\n")); return -ENODEV; } - + return 0; } diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index dfb15bfb8..885fd0170 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig @@ -1,11 +1,10 @@ config VIDEO_EM28XX tristate "Empia EM2800/2820/2840 USB video capture support" - depends on VIDEO_V4L1 && USB && I2C + depends on VIDEO_DEV && USB && I2C select VIDEO_BUF select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_IR - select VIDEO_SAA711X ---help--- This is a video4linux driver for Empia 28xx based TV cards. diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile index 826d0e340..da457a05b 100644 --- a/drivers/media/video/em28xx/Makefile +++ b/drivers/media/video/em28xx/Makefile @@ -3,4 +3,4 @@ em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \ obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o -EXTRA_CFLAGS += -Idrivers/media/video +EXTRA_CFLAGS += -I$(src)/.. diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 3ba3439db..58f7b4194 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -28,10 +28,10 @@ #include #include #include -#include -#include #include +#include #include +#include "msp3400.h" #include "em28xx.h" @@ -72,24 +72,6 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, }}, }, - [EM2820_BOARD_KWORLD_PVRTV2800RF] = { - .name = "Kworld PVR TV 2800 RF", - .is_em2800 = 0, - .vchannels = 2, - .norm = VIDEO_MODE_PAL, - .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, - .decoder = EM28XX_SAA7113, - .input = {{ - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM28XX_VMUX_SVIDEO, - .vmux = 9, - .amux = 1, - }}, - }, [EM2820_BOARD_TERRATEC_CINERGY_250] = { .name = "Terratec Cinergy 250 USB", .vchannels = 3, @@ -101,7 +83,7 @@ struct em28xx_board em28xx_boards[] = { .input = {{ .type = EM28XX_VMUX_TELEVISION, .vmux = 2, - .amux = 1, + .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, .vmux = 0, @@ -147,12 +129,11 @@ struct em28xx_board em28xx_boards[] = { .input = {{ .type = EM28XX_VMUX_TELEVISION, .vmux = 0, - .amux = MSP_INPUT_DEFAULT, + .amux = 6, },{ .type = EM28XX_VMUX_SVIDEO, .vmux = 2, - .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), + .amux = 1, }}, }, [EM2820_BOARD_MSI_VOX_USB_2] = { @@ -276,51 +257,27 @@ struct usb_device_id em28xx_id_table [] = { { }, }; -void em28xx_pre_card_setup(struct em28xx *dev) -{ - /* request some modules */ - switch(dev->model){ - case EM2880_BOARD_TERRATEC_PRODIGY_XS: - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: - case EM2880_BOARD_TERRATEC_HYBRID_XS: - { - em28xx_write_regs_req(dev, 0x00, 0x08, "\x7d", 1); // reset through GPIO? - break; - } - } -} - void em28xx_card_setup(struct em28xx *dev) { /* request some modules */ - switch(dev->model){ - case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: - { - struct tveeprom tv; + if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { + struct tveeprom tv; #ifdef CONFIG_MODULES - request_module("tveeprom"); - request_module("ir-kbd-i2c"); - request_module("msp3400"); + request_module("tveeprom"); + request_module("ir-kbd-i2c"); + request_module("msp3400"); #endif - /* Call first TVeeprom */ - - dev->i2c_client.addr = 0xa0 >> 1; - tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); + /* Call first TVeeprom */ - dev->tuner_type= tv.tuner_type; - if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { - dev->i2s_speed=2048000; - dev->has_msp34xx=1; - } else - dev->has_msp34xx=0; - break; - } - case EM2820_BOARD_KWORLD_PVRTV2800RF: - { - em28xx_write_regs_req(dev,0x00,0x08, "\xf9", 1); // GPIO enables sound on KWORLD PVR TV 2800RF - break; - } + dev->i2c_client.addr = 0xa0 >> 1; + tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); + dev->tuner_type= tv.tuner_type; + if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { + dev->i2s_speed=2048000; + dev->has_msp34xx=1; + } else + dev->has_msp34xx=0; } } diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 5b6cece37..6ca8631bc 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c @@ -420,6 +420,7 @@ static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client) tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; tun_setup.type = dev->tuner_type; tun_setup.addr = dev->tuner_addr; + em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); } diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 31e89e4f1..30dfa5370 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -43,6 +43,91 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); #define dprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) +/* ---------------------------------------------------------------------- */ + +static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { + [ 0x01 ] = KEY_CHANNEL, + [ 0x02 ] = KEY_SELECT, + [ 0x03 ] = KEY_MUTE, + [ 0x04 ] = KEY_POWER, + [ 0x05 ] = KEY_KP1, + [ 0x06 ] = KEY_KP2, + [ 0x07 ] = KEY_KP3, + [ 0x08 ] = KEY_CHANNELUP, + [ 0x09 ] = KEY_KP4, + [ 0x0a ] = KEY_KP5, + [ 0x0b ] = KEY_KP6, + [ 0x0c ] = KEY_CHANNELDOWN, + [ 0x0d ] = KEY_KP7, + [ 0x0e ] = KEY_KP8, + [ 0x0f ] = KEY_KP9, + [ 0x10 ] = KEY_VOLUMEUP, + [ 0x11 ] = KEY_KP0, + [ 0x12 ] = KEY_MENU, + [ 0x13 ] = KEY_PRINT, + [ 0x14 ] = KEY_VOLUMEDOWN, + [ 0x16 ] = KEY_PAUSE, + [ 0x18 ] = KEY_RECORD, + [ 0x19 ] = KEY_REWIND, + [ 0x1a ] = KEY_PLAY, + [ 0x1b ] = KEY_FORWARD, + [ 0x1c ] = KEY_BACKSPACE, + [ 0x1e ] = KEY_STOP, + [ 0x40 ] = KEY_ZOOM, +}; + +static IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { + [ 0x3a ] = KEY_KP0, + [ 0x31 ] = KEY_KP1, + [ 0x32 ] = KEY_KP2, + [ 0x33 ] = KEY_KP3, + [ 0x34 ] = KEY_KP4, + [ 0x35 ] = KEY_KP5, + [ 0x36 ] = KEY_KP6, + [ 0x37 ] = KEY_KP7, + [ 0x38 ] = KEY_KP8, + [ 0x39 ] = KEY_KP9, + + [ 0x2f ] = KEY_POWER, + + [ 0x2e ] = KEY_P, + [ 0x1f ] = KEY_L, + [ 0x2b ] = KEY_I, + + [ 0x2d ] = KEY_ZOOM, + [ 0x1e ] = KEY_ZOOM, + [ 0x1b ] = KEY_VOLUMEUP, + [ 0x0f ] = KEY_VOLUMEDOWN, + [ 0x17 ] = KEY_CHANNELUP, + [ 0x1c ] = KEY_CHANNELDOWN, + [ 0x25 ] = KEY_INFO, + + [ 0x3c ] = KEY_MUTE, + + [ 0x3d ] = KEY_LEFT, + [ 0x3b ] = KEY_RIGHT, + + [ 0x3f ] = KEY_UP, + [ 0x3e ] = KEY_DOWN, + [ 0x1a ] = KEY_PAUSE, + + [ 0x1d ] = KEY_MENU, + [ 0x19 ] = KEY_PLAY, + [ 0x16 ] = KEY_REWIND, + [ 0x13 ] = KEY_FORWARD, + [ 0x15 ] = KEY_PAUSE, + [ 0x0e ] = KEY_REWIND, + [ 0x0d ] = KEY_PLAY, + [ 0x0b ] = KEY_STOP, + [ 0x07 ] = KEY_FORWARD, + [ 0x27 ] = KEY_RECORD, + [ 0x26 ] = KEY_TUNER, + [ 0x29 ] = KEY_TEXT, + [ 0x2a ] = KEY_MEDIA, + [ 0x18 ] = KEY_EPG, + [ 0x27 ] = KEY_RECORD, +}; + /* ----------------------------------------------------------------------- */ static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index cf7cdf9ef..5b267808a 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +37,6 @@ #include "em28xx.h" #include #include -#include #define DRIVER_AUTHOR "Ludovico Cavedon , " \ "Markus Rechberger , " \ @@ -61,14 +59,8 @@ MODULE_LICENSE("GPL"); static LIST_HEAD(em28xx_devlist); static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; -static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; -static unsigned int vbi_nr[] = {[0 ... (EM28XX_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_PARM_DESC(card,"card type"); -MODULE_PARM_DESC(video_nr,"video device numbers"); -MODULE_PARM_DESC(vbi_nr,"vbi device numbers"); static int tuner = -1; module_param(tuner, int, 0444); @@ -78,9 +70,6 @@ static unsigned int video_debug = 0; module_param(video_debug,int,0644); MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); -/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ -static unsigned long em28xx_devused; - /* supported tv norms */ static struct em28xx_tvnorm tvnorms[] = { { @@ -102,6 +91,23 @@ static struct em28xx_tvnorm tvnorms[] = { } }; +static const unsigned char saa7114_i2c_init[] = { + 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0, + 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a, + 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42, + 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff, + 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff, + 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff, + 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00, + 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00, + 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0, + 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06, + 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67, + 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd, + 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00, + 0xbe,0x00,0xbf,0x00 +}; + #define TVNORMS ARRAY_SIZE(tvnorms) /* supported controls */ @@ -128,6 +134,65 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { } }; +/* FIXME: These are specific to saa711x - should be moved to its code */ +static struct v4l2_queryctrl saa711x_qctrl[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = -128, + .maximum = 127, + .step = 1, + .default_value = 0, + .flags = 0, + },{ + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0x0, + .maximum = 0x1f, + .step = 0x1, + .default_value = 0x10, + .flags = 0, + },{ + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0x0, + .maximum = 0x1f, + .step = 0x1, + .default_value = 0x10, + .flags = 0, + },{ + .id = V4L2_CID_RED_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Red chroma balance", + .minimum = -128, + .maximum = 127, + .step = 1, + .default_value = 0, + .flags = 0, + },{ + .id = V4L2_CID_BLUE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Blue chroma balance", + .minimum = -128, + .maximum = 127, + .step = 1, + .default_value = 0, + .flags = 0, + },{ + .id = V4L2_CID_GAMMA, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gamma", + .minimum = 0x0, + .maximum = 0x3f, + .step = 0x1, + .default_value = 0x20, + .flags = 0, + } +}; + static struct usb_driver em28xx_usb_driver; static DEFINE_MUTEX(em28xx_sysfs_lock); @@ -146,11 +211,6 @@ static int em28xx_config(struct em28xx *dev) em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1); /* enable vbi capturing */ - -/* em28xx_write_regs_req(dev,0x00,0x0e,"\xC0",1); audio register */ -/* em28xx_write_regs_req(dev,0x00,0x0f,"\x80",1); clk register */ - em28xx_write_regs_req(dev,0x00,0x11,"\x51",1); - em28xx_audio_usb_mute(dev, 1); dev->mute = 1; /* maybe not the right place... */ dev->volume = 0x1f; @@ -170,9 +230,22 @@ static int em28xx_config(struct em28xx *dev) static void em28xx_config_i2c(struct em28xx *dev) { struct v4l2_frequency f; - em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); - em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &dev->ctl_input); - em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); + struct video_decoder_init em28xx_vdi = {.data = NULL }; + + + /* configure decoder */ + if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){ + em28xx_vdi.data=saa7114_i2c_init; + em28xx_vdi.len=sizeof(saa7114_i2c_init); + } + + + em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi); + em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input); +/* em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */ +/* em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */ +/* em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */ +/* em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */ /* configure tuner */ f.tuner = 0; @@ -212,28 +285,24 @@ static void video_mux(struct em28xx *dev, int index) dev->ctl_input = index; dev->ctl_ainput = INPUT(index)->amux; - em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &input); + em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input); + em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); if (dev->has_msp34xx) { - struct v4l2_routing route; - if (dev->i2s_speed) em28xx_i2c_call_clients(dev, VIDIOC_INT_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); + em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput); ainput = EM28XX_AUDIO_SRC_TUNER; em28xx_audio_source(dev, ainput); } else { switch (dev->ctl_ainput) { - case 0: - ainput = EM28XX_AUDIO_SRC_TUNER; - break; - default: - ainput = EM28XX_AUDIO_SRC_LINE; + case 0: + ainput = EM28XX_AUDIO_SRC_TUNER; + break; + default: + ainput = EM28XX_AUDIO_SRC_LINE; } em28xx_audio_source(dev, ainput); } @@ -254,20 +323,13 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) h = list_entry(list, struct em28xx, devlist); if (h->vdev->minor == minor) { dev = h; - dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - if (h->vbi_dev->minor == minor) { - dev = h; - dev->type = V4L2_BUF_TYPE_VBI_CAPTURE; } } - if (NULL == dev) - return -ENODEV; filp->private_data=dev; - em28xx_videodbg("open minor=%d type=%s users=%d\n", - minor,v4l2_type_names[dev->type],dev->users); + + em28xx_videodbg("users=%d\n", dev->users); if (!down_read_trylock(&em28xx_disconnect)) return -ERESTARTSYS; @@ -278,36 +340,40 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) return -EBUSY; } - mutex_init(&dev->fileop_lock); /* to 1 == available */ +/* if(dev->vbi_dev->minor == minor){ + dev->type=V4L2_BUF_TYPE_VBI_CAPTURE; + }*/ + if (dev->vdev->minor == minor) { + dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + } + + init_MUTEX(&dev->fileop_lock); /* to 1 == available */ spin_lock_init(&dev->queue_lock); init_waitqueue_head(&dev->wait_frame); init_waitqueue_head(&dev->wait_stream); - mutex_lock(&dev->lock); + down(&dev->lock); - if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - em28xx_set_alternate(dev); - - dev->width = norm_maxw(dev); - dev->height = norm_maxh(dev); - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ - dev->bytesperline = dev->width * 2; - dev->hscale = 0; - dev->vscale = 0; + em28xx_set_alternate(dev); - em28xx_capture_start(dev, 1); - em28xx_resolution_set(dev); + dev->width = norm_maxw(dev); + dev->height = norm_maxh(dev); + dev->frame_size = dev->width * dev->height * 2; + dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ + dev->bytesperline = dev->width * 2; + dev->hscale = 0; + dev->vscale = 0; - /* device needs to be initialized before isoc transfer */ - video_mux(dev, 0); + em28xx_capture_start(dev, 1); + em28xx_resolution_set(dev); - /* start the transfer */ - errCode = em28xx_init_isoc(dev); - if (errCode) - goto err; + /* device needs to be initialized before isoc transfer */ + video_mux(dev, 0); - } + /* start the transfer */ + errCode = em28xx_init_isoc(dev); + if (errCode) + goto err; dev->users++; filp->private_data = dev; @@ -320,8 +386,10 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) dev->state |= DEV_INITIALIZED; -err: - mutex_unlock(&dev->lock); + video_mux(dev, 0); + + err: + up(&dev->lock); up_read(&em28xx_disconnect); return errCode; } @@ -335,21 +403,14 @@ static void em28xx_release_resources(struct em28xx *dev) { mutex_lock(&em28xx_sysfs_lock); - /*FIXME: I2C IR should be disconnected */ - - em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", - dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, - dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); + em28xx_info("V4L2 device /dev/video%d deregistered\n", + dev->vdev->minor); list_del(&dev->devlist); video_unregister_device(dev->vdev); - video_unregister_device(dev->vbi_dev); +/* video_unregister_device(dev->vbi_dev); */ em28xx_i2c_unregister(dev); usb_put_dev(dev->udev); mutex_unlock(&em28xx_sysfs_lock); - - - /* Mark device as unused */ - em28xx_devused&=~(1<devno); } /* @@ -363,7 +424,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) em28xx_videodbg("users=%d\n", dev->users); - mutex_lock(&dev->lock); + down(&dev->lock); em28xx_uninit_isoc(dev); @@ -372,7 +433,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) /* the device is already disconnect, free the remaining resources */ if (dev->state & DEV_DISCONNECTED) { em28xx_release_resources(dev); - mutex_unlock(&dev->lock); + up(&dev->lock); kfree(dev); return 0; } @@ -388,7 +449,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) dev->users--; wake_up_interruptible_nr(&dev->open, 1); - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } @@ -405,54 +466,32 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, int ret = 0; struct em28xx *dev = filp->private_data; - if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - em28xx_videodbg("V4l2_Buf_type_videocapture is set\n"); - } - if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n"); - em28xx_videodbg("not supported yet! ...\n"); - if (copy_to_user(buf, "", 1)) { - mutex_unlock(&dev->fileop_lock); - return -EFAULT; - } - return (1); - } - if (dev->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { - em28xx_videodbg("V4L2_BUF_TYPE_SLICED_VBI_CAPTURE is set\n"); - em28xx_videodbg("not supported yet! ...\n"); - if (copy_to_user(buf, "", 1)) { - mutex_unlock(&dev->fileop_lock); - return -EFAULT; - } - return (1); - } - - if (mutex_lock_interruptible(&dev->fileop_lock)) + if (down_interruptible(&dev->fileop_lock)) return -ERESTARTSYS; if (dev->state & DEV_DISCONNECTED) { em28xx_videodbg("device not present\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -ENODEV; } if (dev->state & DEV_MISCONFIGURED) { em28xx_videodbg("device misconfigured; close and open it again\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EIO; } if (dev->io == IO_MMAP) { em28xx_videodbg ("IO method is set to mmap; close and open" " the device again to choose the read method\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EINVAL; } if (dev->io == IO_NONE) { if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) { em28xx_errdev("read failed, not enough memory\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -ENOMEM; } dev->io = IO_READ; @@ -461,13 +500,13 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, } if (!count) { - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return 0; } if (list_empty(&dev->outqueue)) { if (filp->f_flags & O_NONBLOCK) { - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EAGAIN; } ret = wait_event_interruptible @@ -475,11 +514,11 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, (!list_empty(&dev->outqueue)) || (dev->state & DEV_DISCONNECTED)); if (ret) { - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return ret; } if (dev->state & DEV_DISCONNECTED) { - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -ENODEV; } } @@ -498,12 +537,12 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, count = f->buf.length; if (copy_to_user(buf, f->bufmem, count)) { - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EFAULT; } *f_pos += count; - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return count; } @@ -517,7 +556,7 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) unsigned int mask = 0; struct em28xx *dev = filp->private_data; - if (mutex_lock_interruptible(&dev->fileop_lock)) + if (down_interruptible(&dev->fileop_lock)) return POLLERR; if (dev->state & DEV_DISCONNECTED) { @@ -543,13 +582,13 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) if (!list_empty(&dev->outqueue)) mask |= POLLIN | POLLRDNORM; - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return mask; } } - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return POLLERR; } @@ -589,25 +628,25 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) struct em28xx *dev = filp->private_data; - if (mutex_lock_interruptible(&dev->fileop_lock)) + if (down_interruptible(&dev->fileop_lock)) return -ERESTARTSYS; if (dev->state & DEV_DISCONNECTED) { em28xx_videodbg("mmap: device not present\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -ENODEV; } if (dev->state & DEV_MISCONFIGURED) { em28xx_videodbg ("mmap: Device is misconfigured; close and " "open it again\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EIO; } if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || size != PAGE_ALIGN(dev->frame[0].buf.length)) { - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EINVAL; } @@ -617,7 +656,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) } if (i == dev->num_frames) { em28xx_videodbg("mmap: user supplied mapping address is out of range\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EINVAL; } @@ -629,7 +668,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) while (size > 0) { /* size is page-aligned */ if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { em28xx_videodbg("mmap: vm_insert_page failed\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EAGAIN; } start += PAGE_SIZE; @@ -641,7 +680,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_private_data = &dev->frame[i]; em28xx_vm_open(vma); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return 0; } @@ -663,6 +702,43 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) } } +/*FIXME: should be moved to saa711x */ +static int saa711x_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) +{ + s32 tmp; + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + if ((tmp = em28xx_brightness_get(dev)) < 0) + return -EIO; + ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ + return 0; + case V4L2_CID_CONTRAST: + if ((ctrl->value = em28xx_contrast_get(dev)) < 0) + return -EIO; + return 0; + case V4L2_CID_SATURATION: + if ((ctrl->value = em28xx_saturation_get(dev)) < 0) + return -EIO; + return 0; + case V4L2_CID_RED_BALANCE: + if ((tmp = em28xx_v_balance_get(dev)) < 0) + return -EIO; + ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ + return 0; + case V4L2_CID_BLUE_BALANCE: + if ((tmp = em28xx_u_balance_get(dev)) < 0) + return -EIO; + ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ + return 0; + case V4L2_CID_GAMMA: + if ((ctrl->value = em28xx_gamma_get(dev)) < 0) + return -EIO; + return 0; + default: + return -EINVAL; + } +} + /* * em28xx_set_ctrl() * mute or set new saturation, brightness or contrast @@ -685,6 +761,27 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) } } +/*FIXME: should be moved to saa711x */ +static int saa711x_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + return em28xx_brightness_set(dev, ctrl->value); + case V4L2_CID_CONTRAST: + return em28xx_contrast_set(dev, ctrl->value); + case V4L2_CID_SATURATION: + return em28xx_saturation_set(dev, ctrl->value); + case V4L2_CID_RED_BALANCE: + return em28xx_v_balance_set(dev, ctrl->value); + case V4L2_CID_BLUE_BALANCE: + return em28xx_u_balance_set(dev, ctrl->value); + case V4L2_CID_GAMMA: + return em28xx_gamma_set(dev, ctrl->value); + default: + return -EINVAL; + } +} + /* * em28xx_stream_interrupt() * stops streaming @@ -705,8 +802,7 @@ static int em28xx_stream_interrupt(struct em28xx *dev) else if (ret) { dev->state |= DEV_MISCONFIGURED; em28xx_videodbg("device is misconfigured; close and " - "open /dev/video%d again\n", - dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); + "open /dev/video%d again\n", dev->vdev->minor); return ret; } @@ -757,181 +853,6 @@ static int em28xx_set_norm(struct em28xx *dev, int width, int height) return 0; } -static int em28xx_get_fmt(struct em28xx *dev, struct v4l2_format *format) -{ - em28xx_videodbg("VIDIOC_G_FMT: type=%s\n", - (format->type ==V4L2_BUF_TYPE_VIDEO_CAPTURE) ? - "V4L2_BUF_TYPE_VIDEO_CAPTURE" : - (format->type ==V4L2_BUF_TYPE_VBI_CAPTURE) ? - "V4L2_BUF_TYPE_VBI_CAPTURE" : - (format->type ==V4L2_CAP_SLICED_VBI_CAPTURE) ? - "V4L2_BUF_TYPE_SLICED_VBI_CAPTURE " : - "not supported"); - - switch (format->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - { - format->fmt.pix.width = dev->width; - format->fmt.pix.height = dev->height; - format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; - format->fmt.pix.bytesperline = dev->bytesperline; - format->fmt.pix.sizeimage = dev->frame_size; - format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ - - em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width, - dev->height); - break; - } - - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - { - format->fmt.sliced.service_set=0; - - em28xx_i2c_call_clients(dev,VIDIOC_G_FMT,format); - - if (format->fmt.sliced.service_set==0) - return -EINVAL; - - break; - } - - default: - return -EINVAL; - } - return (0); -} - -static int em28xx_set_fmt(struct em28xx *dev, unsigned int cmd, struct v4l2_format *format) -{ - u32 i; - int ret = 0; - int width = format->fmt.pix.width; - int height = format->fmt.pix.height; - unsigned int hscale, vscale; - unsigned int maxh, maxw; - - maxw = norm_maxw(dev); - maxh = norm_maxh(dev); - - em28xx_videodbg("%s: type=%s\n", - cmd == VIDIOC_TRY_FMT ? - "VIDIOC_TRY_FMT" : "VIDIOC_S_FMT", - format->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? - "V4L2_BUF_TYPE_VIDEO_CAPTURE" : - format->type == V4L2_BUF_TYPE_VBI_CAPTURE ? - "V4L2_BUF_TYPE_VBI_CAPTURE " : - "not supported"); - - if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { - em28xx_i2c_call_clients(dev,VIDIOC_G_FMT,format); - - if (format->fmt.sliced.service_set==0) - return -EINVAL; - - return 0; - } - - - if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - em28xx_videodbg("%s: requested %dx%d\n", - cmd == VIDIOC_TRY_FMT ? - "VIDIOC_TRY_FMT" : "VIDIOC_S_FMT", - format->fmt.pix.width, format->fmt.pix.height); - - /* FIXME: Move some code away from here */ - /* width must even because of the YUYV format */ - /* height must be even because of interlacing */ - height &= 0xfffe; - width &= 0xfffe; - - if (height < 32) - height = 32; - if (height > maxh) - height = maxh; - if (width < 48) - width = 48; - if (width > maxw) - width = maxw; - - if(dev->is_em2800){ - /* the em2800 can only scale down to 50% */ - if(height % (maxh / 2)) - height=maxh; - if(width % (maxw / 2)) - width=maxw; - /* according to empiatech support */ - /* the MaxPacketSize is to small to support */ - /* framesizes larger than 640x480 @ 30 fps */ - /* or 640x576 @ 25 fps. As this would cut */ - /* of a part of the image we prefer */ - /* 360x576 or 360x480 for now */ - if(width == maxw && height == maxh) - width /= 2; - } - - if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000) - hscale = 0x3fff; - - width = (((unsigned long)maxw) << 12) / (hscale + 4096L); - - if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000) - vscale = 0x3fff; - - height = (((unsigned long)maxh) << 12) / (vscale + 4096L); - - format->fmt.pix.width = width; - format->fmt.pix.height = height; - format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; - format->fmt.pix.bytesperline = width * 2; - format->fmt.pix.sizeimage = width * 2 * height; - format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - format->fmt.pix.field = V4L2_FIELD_INTERLACED; - - em28xx_videodbg("%s: returned %dx%d (%d, %d)\n", - cmd == VIDIOC_TRY_FMT ? - "VIDIOC_TRY_FMT" :"VIDIOC_S_FMT", - format->fmt.pix.width, format->fmt.pix.height, hscale, vscale); - - if (cmd == VIDIOC_TRY_FMT) - return 0; - - for (i = 0; i < dev->num_frames; i++) - if (dev->frame[i].vma_use_count) { - em28xx_videodbg("VIDIOC_S_FMT failed. " - "Unmap the buffers first.\n"); - return -EINVAL; - } - - /* stop io in case it is already in progress */ - if (dev->stream == STREAM_ON) { - em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n"); - if ((ret = em28xx_stream_interrupt(dev))) - return ret; - } - - em28xx_release_buffers(dev); - dev->io = IO_NONE; - - /* set new image size */ - dev->width = width; - dev->height = height; - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->frame_size >> 1; - dev->bytesperline = dev->width * 2; - dev->hscale = hscale; - dev->vscale = vscale; - em28xx_uninit_isoc(dev); - em28xx_set_alternate(dev); - em28xx_capture_start(dev, 1); - em28xx_resolution_set(dev); - em28xx_init_isoc(dev); - - return 0; -} - /* * em28xx_v4l2_do_ioctl() * This function is _not_ called directly, but from @@ -947,302 +868,392 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, switch (cmd) { /* ---------- tv norms ---------- */ case VIDIOC_ENUMSTD: - { - struct v4l2_standard *e = arg; - unsigned int i; + { + struct v4l2_standard *e = arg; + unsigned int i; - i = e->index; - if (i >= TVNORMS) - return -EINVAL; - ret = v4l2_video_std_construct(e, tvnorms[e->index].id, - tvnorms[e->index].name); - e->index = i; - if (ret < 0) - return ret; - return 0; - } + i = e->index; + if (i >= TVNORMS) + return -EINVAL; + ret = v4l2_video_std_construct(e, tvnorms[e->index].id, + tvnorms[e->index].name); + e->index = i; + if (ret < 0) + return ret; + return 0; + } case VIDIOC_G_STD: - { - v4l2_std_id *id = arg; + { + v4l2_std_id *id = arg; - *id = dev->tvnorm->id; - return 0; - } + *id = dev->tvnorm->id; + return 0; + } case VIDIOC_S_STD: - { - v4l2_std_id *id = arg; - unsigned int i; + { + v4l2_std_id *id = arg; + unsigned int i; - for (i = 0; i < TVNORMS; i++) - if (*id == tvnorms[i].id) - break; - if (i == TVNORMS) for (i = 0; i < TVNORMS; i++) - if (*id & tvnorms[i].id) + if (*id == tvnorms[i].id) break; - if (i == TVNORMS) - return -EINVAL; + if (i == TVNORMS) + for (i = 0; i < TVNORMS; i++) + if (*id & tvnorms[i].id) + break; + if (i == TVNORMS) + return -EINVAL; - mutex_lock(&dev->lock); - dev->tvnorm = &tvnorms[i]; + down(&dev->lock); + dev->tvnorm = &tvnorms[i]; - em28xx_set_norm(dev, dev->width, dev->height); + em28xx_set_norm(dev, dev->width, dev->height); - em28xx_i2c_call_clients(dev, VIDIOC_S_STD, - &dev->tvnorm->id); +/* + dev->width=norm_maxw(dev); + dev->height=norm_maxh(dev); + dev->frame_size=dev->width*dev->height*2; + dev->field_size=dev->frame_size>>1; + dev->bytesperline=dev->width*2; + dev->hscale=0; + dev->vscale=0; - mutex_unlock(&dev->lock); + em28xx_resolution_set(dev); +*/ +/* + em28xx_uninit_isoc(dev); + em28xx_set_alternate(dev); + em28xx_capture_start(dev, 1); + em28xx_resolution_set(dev); + em28xx_init_isoc(dev); +*/ + em28xx_i2c_call_clients(dev, DECODER_SET_NORM, + &tvnorms[i].mode); + em28xx_i2c_call_clients(dev, VIDIOC_S_STD, + &dev->tvnorm->id); - return 0; - } + up(&dev->lock); - /* ------ input switching ---------- */ + return 0; + } + + /* ------ input switching ---------- */ case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - unsigned int n; - static const char *iname[] = { - [EM28XX_VMUX_COMPOSITE1] = "Composite1", - [EM28XX_VMUX_COMPOSITE2] = "Composite2", - [EM28XX_VMUX_COMPOSITE3] = "Composite3", - [EM28XX_VMUX_COMPOSITE4] = "Composite4", - [EM28XX_VMUX_SVIDEO] = "S-Video", - [EM28XX_VMUX_TELEVISION] = "Television", - [EM28XX_VMUX_CABLE] = "Cable TV", - [EM28XX_VMUX_DVB] = "DVB", - [EM28XX_VMUX_DEBUG] = "for debug only", - }; - - n = i->index; - if (n >= MAX_EM28XX_INPUT) - return -EINVAL; - if (0 == INPUT(n)->type) - return -EINVAL; - memset(i, 0, sizeof(*i)); - i->index = n; - i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name, iname[INPUT(n)->type]); - if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) || - (EM28XX_VMUX_CABLE == INPUT(n)->type)) - i->type = V4L2_INPUT_TYPE_TUNER; - for (n = 0; n < ARRAY_SIZE(tvnorms); n++) - i->std |= tvnorms[n].id; - return 0; - } + { + struct v4l2_input *i = arg; + unsigned int n; + static const char *iname[] = { + [EM28XX_VMUX_COMPOSITE1] = "Composite1", + [EM28XX_VMUX_COMPOSITE2] = "Composite2", + [EM28XX_VMUX_COMPOSITE3] = "Composite3", + [EM28XX_VMUX_COMPOSITE4] = "Composite4", + [EM28XX_VMUX_SVIDEO] = "S-Video", + [EM28XX_VMUX_TELEVISION] = "Television", + [EM28XX_VMUX_CABLE] = "Cable TV", + [EM28XX_VMUX_DVB] = "DVB", + [EM28XX_VMUX_DEBUG] = "for debug only", + }; + + n = i->index; + if (n >= MAX_EM28XX_INPUT) + return -EINVAL; + if (0 == INPUT(n)->type) + return -EINVAL; + memset(i, 0, sizeof(*i)); + i->index = n; + i->type = V4L2_INPUT_TYPE_CAMERA; + strcpy(i->name, iname[INPUT(n)->type]); + if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) || + (EM28XX_VMUX_CABLE == INPUT(n)->type)) + i->type = V4L2_INPUT_TYPE_TUNER; + for (n = 0; n < ARRAY_SIZE(tvnorms); n++) + i->std |= tvnorms[n].id; + return 0; + } + case VIDIOC_G_INPUT: - { - int *i = arg; - *i = dev->ctl_input; + { + int *i = arg; + *i = dev->ctl_input; + + return 0; + } - return 0; - } case VIDIOC_S_INPUT: - { - int *index = arg; + { + int *index = arg; - if (*index >= MAX_EM28XX_INPUT) - return -EINVAL; - if (0 == INPUT(*index)->type) - return -EINVAL; + if (*index >= MAX_EM28XX_INPUT) + return -EINVAL; + if (0 == INPUT(*index)->type) + return -EINVAL; - mutex_lock(&dev->lock); - video_mux(dev, *index); - mutex_unlock(&dev->lock); + down(&dev->lock); + video_mux(dev, *index); + up(&dev->lock); + + return 0; + } - return 0; - } case VIDIOC_G_AUDIO: - { - struct v4l2_audio *a = arg; - unsigned int index = a->index; + { + struct v4l2_audio *a = arg; + unsigned int index = a->index; - if (a->index > 1) - return -EINVAL; - memset(a, 0, sizeof(*a)); - index = dev->ctl_ainput; + if (a->index > 1) + return -EINVAL; + memset(a, 0, sizeof(*a)); + index = dev->ctl_ainput; - if (index == 0) { - strcpy(a->name, "Television"); - } else { - strcpy(a->name, "Line In"); + if (index == 0) { + strcpy(a->name, "Television"); + } else { + strcpy(a->name, "Line In"); + } + a->capability = V4L2_AUDCAP_STEREO; + a->index = index; + return 0; } - a->capability = V4L2_AUDCAP_STEREO; - a->index = index; - return 0; - } - case VIDIOC_S_AUDIO: - { - struct v4l2_audio *a = arg; - if (a->index != dev->ctl_ainput) - return -EINVAL; + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *a = arg; + if (a->index != dev->ctl_ainput) + return -EINVAL; - return 0; - } + return 0; + } - /* --- controls ---------------------------------------------- */ + /* --- controls ---------------------------------------------- */ case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i, id=qc->id; - - memset(qc,0,sizeof(*qc)); - qc->id=id; - - if (!dev->has_msp34xx) { - for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { - if (qc->id && qc->id == em28xx_qctrl[i].id) { - memcpy(qc, &(em28xx_qctrl[i]), - sizeof(*qc)); + { + struct v4l2_queryctrl *qc = arg; + int i, id=qc->id; + + memset(qc,0,sizeof(*qc)); + qc->id=id; + + if (!dev->has_msp34xx) { + for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { + if (qc->id && qc->id == em28xx_qctrl[i].id) { + memcpy(qc, &(em28xx_qctrl[i]), + sizeof(*qc)); + return 0; + } + } + } + if (dev->decoder == EM28XX_TVP5150) { + em28xx_i2c_call_clients(dev,cmd,qc); + if (qc->type) + return 0; + else + return -EINVAL; + } + for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { + if (qc->id && qc->id == saa711x_qctrl[i].id) { + memcpy(qc, &(saa711x_qctrl[i]), + sizeof(*qc)); return 0; } } - } - em28xx_i2c_call_clients(dev,cmd,qc); - if (qc->type) - return 0; - else + return -EINVAL; - } + } + case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - int retval=-EINVAL; + { + struct v4l2_control *ctrl = arg; + int retval=-EINVAL; + + if (!dev->has_msp34xx) + retval=em28xx_get_ctrl(dev, ctrl); + if (retval==-EINVAL) { + if (dev->decoder == EM28XX_TVP5150) { + em28xx_i2c_call_clients(dev,cmd,arg); + return 0; + } + + return saa711x_get_ctrl(dev, ctrl); + } else return retval; + } - if (!dev->has_msp34xx) - retval=em28xx_get_ctrl(dev, ctrl); - if (retval==-EINVAL) { - em28xx_i2c_call_clients(dev,cmd,arg); - return 0; - } else return retval; - } case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - u8 i; - - if (!dev->has_msp34xx){ - for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { - if (ctrl->id == em28xx_qctrl[i].id) { - if (ctrl->value < - em28xx_qctrl[i].minimum - || ctrl->value > - em28xx_qctrl[i].maximum) - return -ERANGE; - return em28xx_set_ctrl(dev, ctrl); + { + struct v4l2_control *ctrl = arg; + u8 i; + + if (!dev->has_msp34xx){ + for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { + if (ctrl->id == em28xx_qctrl[i].id) { + if (ctrl->value < + em28xx_qctrl[i].minimum + || ctrl->value > + em28xx_qctrl[i].maximum) + return -ERANGE; + return em28xx_set_ctrl(dev, ctrl); + } + } + } + + if (dev->decoder == EM28XX_TVP5150) { + em28xx_i2c_call_clients(dev,cmd,arg); + return 0; + } else if (!dev->has_msp34xx) { + for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { + if (ctrl->id == em28xx_qctrl[i].id) { + if (ctrl->value < + em28xx_qctrl[i].minimum + || ctrl->value > + em28xx_qctrl[i].maximum) + return -ERANGE; + return em28xx_set_ctrl(dev, ctrl); + } + } + for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { + if (ctrl->id == saa711x_qctrl[i].id) { + if (ctrl->value < + saa711x_qctrl[i].minimum + || ctrl->value > + saa711x_qctrl[i].maximum) + return -ERANGE; + return saa711x_set_ctrl(dev, ctrl); + } } } + + return -EINVAL; } - em28xx_i2c_call_clients(dev,cmd,arg); - return 0; - } - /* --- tuner ioctls ------------------------------------------ */ + /* --- tuner ioctls ------------------------------------------ */ case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; + { + struct v4l2_tuner *t = arg; + int status = 0; - if (0 != t->index) - return -EINVAL; + if (0 != t->index) + return -EINVAL; - memset(t, 0, sizeof(*t)); - strcpy(t->name, "Tuner"); - mutex_lock(&dev->lock); - /* let clients fill in the remainder of this struct */ - em28xx_i2c_call_clients(dev, cmd, t); - mutex_unlock(&dev->lock); - em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal, - t->afc); - return 0; - } + memset(t, 0, sizeof(*t)); + strcpy(t->name, "Tuner"); + t->type = V4L2_TUNER_ANALOG_TV; + t->capability = V4L2_TUNER_CAP_NORM; + t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ +/* t->signal = 0xffff;*/ +/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/ + /* No way to get signal strength? */ + down(&dev->lock); + em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, + &status); + up(&dev->lock); + t->signal = + (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; + + em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal, + t->afc); + return 0; + } case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; + { + struct v4l2_tuner *t = arg; + int status = 0; - if (0 != t->index) - return -EINVAL; - mutex_lock(&dev->lock); - /* let clients handle this */ - em28xx_i2c_call_clients(dev, cmd, t); - mutex_unlock(&dev->lock); - return 0; - } + if (0 != t->index) + return -EINVAL; + memset(t, 0, sizeof(*t)); + strcpy(t->name, "Tuner"); + t->type = V4L2_TUNER_ANALOG_TV; + t->capability = V4L2_TUNER_CAP_NORM; + t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ +/* t->signal = 0xffff; */ + /* No way to get signal strength? */ + down(&dev->lock); + em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, + &status); + up(&dev->lock); + t->signal = + (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; + + em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n", + t->signal, t->afc); + return 0; + } case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; + { + struct v4l2_frequency *f = arg; - memset(f, 0, sizeof(*f)); - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = dev->ctl_freq; + memset(f, 0, sizeof(*f)); + f->type = V4L2_TUNER_ANALOG_TV; + f->frequency = dev->ctl_freq; - return 0; - } + return 0; + } case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; + { + struct v4l2_frequency *f = arg; - if (0 != f->tuner) - return -EINVAL; + if (0 != f->tuner) + return -EINVAL; - if (V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; + if (V4L2_TUNER_ANALOG_TV != f->type) + return -EINVAL; + + down(&dev->lock); + dev->ctl_freq = f->frequency; + em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); + up(&dev->lock); + return 0; + } - mutex_lock(&dev->lock); - dev->ctl_freq = f->frequency; - em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); - mutex_unlock(&dev->lock); - return 0; - } case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *cc = arg; + { + struct v4l2_cropcap *cc = arg; - 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; - } + 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; + } case VIDIOC_STREAMON: - { - int *type = arg; + { + int *type = arg; - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE - || dev->io != IO_MMAP) - return -EINVAL; + if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE + || dev->io != IO_MMAP) + return -EINVAL; - if (list_empty(&dev->inqueue)) - return -EINVAL; + if (list_empty(&dev->inqueue)) + return -EINVAL; - dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ + dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ - em28xx_videodbg("VIDIOC_STREAMON: starting stream\n"); + em28xx_videodbg("VIDIOC_STREAMON: starting stream\n"); - return 0; - } + return 0; + } case VIDIOC_STREAMOFF: - { - int *type = arg; - int ret; + { + int *type = arg; + int ret; - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE - || dev->io != IO_MMAP) - return -EINVAL; + if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE + || dev->io != IO_MMAP) + return -EINVAL; - if (dev->stream == STREAM_ON) { - em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n"); - if ((ret = em28xx_stream_interrupt(dev))) - return ret; - } - em28xx_empty_framequeues(dev); + if (dev->stream == STREAM_ON) { + em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n"); + if ((ret = em28xx_stream_interrupt(dev))) + return ret; + } + em28xx_empty_framequeues(dev); - return 0; - } + return 0; + } default: return v4l_compat_translate_ioctl(inode, filp, cmd, arg, driver_ioctl); @@ -1272,170 +1283,327 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp, /* --- capabilities ------------------------------------------ */ case VIDIOC_QUERYCAP: { - struct v4l2_capability *cap = arg; - - memset(cap, 0, sizeof(*cap)); - strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); - strlcpy(cap->card, em28xx_boards[dev->model].name, - sizeof(cap->card)); - strlcpy(cap->bus_info, dev->udev->dev.bus_id, - sizeof(cap->bus_info)); - cap->version = EM28XX_VERSION_CODE; - cap->capabilities = - V4L2_CAP_SLICED_VBI_CAPTURE | - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - if (dev->has_tuner) - cap->capabilities |= V4L2_CAP_TUNER; - return 0; - } - /* --- capture ioctls ---------------------------------------- */ + struct v4l2_capability *cap = arg; + + memset(cap, 0, sizeof(*cap)); + strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); + strlcpy(cap->card, em28xx_boards[dev->model].name, + sizeof(cap->card)); + strlcpy(cap->bus_info, dev->udev->dev.bus_id, + sizeof(cap->bus_info)); + cap->version = EM28XX_VERSION_CODE; + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_AUDIO | + V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; + if (dev->has_tuner) + cap->capabilities |= V4L2_CAP_TUNER; + return 0; + } + + /* --- capture ioctls ---------------------------------------- */ case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmtd = arg; + { + struct v4l2_fmtdesc *fmtd = arg; + + if (fmtd->index != 0) + return -EINVAL; + memset(fmtd, 0, sizeof(*fmtd)); + fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + strcpy(fmtd->description, "Packed YUY2"); + fmtd->pixelformat = V4L2_PIX_FMT_YUYV; + memset(fmtd->reserved, 0, sizeof(fmtd->reserved)); + return 0; + } - if (fmtd->index != 0) - return -EINVAL; - memset(fmtd, 0, sizeof(*fmtd)); - fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - strcpy(fmtd->description, "Packed YUY2"); - fmtd->pixelformat = V4L2_PIX_FMT_YUYV; - memset(fmtd->reserved, 0, sizeof(fmtd->reserved)); - return 0; - } case VIDIOC_G_FMT: - return em28xx_get_fmt(dev, (struct v4l2_format *) arg); + { + struct v4l2_format *format = arg; + + em28xx_videodbg("VIDIOC_G_FMT: type=%s\n", + format->type == + V4L2_BUF_TYPE_VIDEO_CAPTURE ? + "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == + V4L2_BUF_TYPE_VBI_CAPTURE ? + "V4L2_BUF_TYPE_VBI_CAPTURE " : + "not supported"); + + if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + format->fmt.pix.width = dev->width; + format->fmt.pix.height = dev->height; + format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + format->fmt.pix.bytesperline = dev->bytesperline; + format->fmt.pix.sizeimage = dev->frame_size; + format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ + + em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width, + dev->height); + return 0; + } case VIDIOC_TRY_FMT: case VIDIOC_S_FMT: - return em28xx_set_fmt(dev, cmd, (struct v4l2_format *)arg); + { + struct v4l2_format *format = arg; + u32 i; + int ret = 0; + int width = format->fmt.pix.width; + int height = format->fmt.pix.height; + unsigned int hscale, vscale; + unsigned int maxh, maxw; + + maxw = norm_maxw(dev); + maxh = norm_maxh(dev); + +/* int both_fields; */ + + em28xx_videodbg("%s: type=%s\n", + cmd == + VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : + "VIDIOC_S_FMT", + format->type == + V4L2_BUF_TYPE_VIDEO_CAPTURE ? + "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == + V4L2_BUF_TYPE_VBI_CAPTURE ? + "V4L2_BUF_TYPE_VBI_CAPTURE " : + "not supported"); + + if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *rb = arg; - u32 i; - int ret; + em28xx_videodbg("%s: requested %dx%d\n", + cmd == + VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : + "VIDIOC_S_FMT", format->fmt.pix.width, + format->fmt.pix.height); + + /* FIXME: Move some code away from here */ + /* width must even because of the YUYV format */ + /* height must be even because of interlacing */ + height &= 0xfffe; + width &= 0xfffe; + + if (height < 32) + height = 32; + if (height > maxh) + height = maxh; + if (width < 48) + width = 48; + if (width > maxw) + width = maxw; + + if(dev->is_em2800){ + /* the em2800 can only scale down to 50% */ + if(height % (maxh / 2)) + height=maxh; + if(width % (maxw / 2)) + width=maxw; + /* according to empiatech support */ + /* the MaxPacketSize is to small to support */ + /* framesizes larger than 640x480 @ 30 fps */ + /* or 640x576 @ 25 fps. As this would cut */ + /* of a part of the image we prefer */ + /* 360x576 or 360x480 for now */ + if(width == maxw && height == maxh) + width /= 2; + } - if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - rb->memory != V4L2_MEMORY_MMAP) - return -EINVAL; + if ((hscale = + (((unsigned long)maxw) << 12) / width - 4096L) >= + 0x4000) + hscale = 0x3fff; + width = + (((unsigned long)maxw) << 12) / (hscale + 4096L); + + if ((vscale = + (((unsigned long)maxh) << 12) / height - 4096L) >= + 0x4000) + vscale = 0x3fff; + height = + (((unsigned long)maxh) << 12) / (vscale + 4096L); + + format->fmt.pix.width = width; + format->fmt.pix.height = height; + format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + format->fmt.pix.bytesperline = width * 2; + format->fmt.pix.sizeimage = width * 2 * height; + format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + format->fmt.pix.field = V4L2_FIELD_INTERLACED; + + em28xx_videodbg("%s: returned %dx%d (%d, %d)\n", + cmd == + VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : + "VIDIOC_S_FMT", format->fmt.pix.width, + format->fmt.pix.height, hscale, vscale); + + if (cmd == VIDIOC_TRY_FMT) + return 0; + + for (i = 0; i < dev->num_frames; i++) + if (dev->frame[i].vma_use_count) { + em28xx_videodbg("VIDIOC_S_FMT failed. " + "Unmap the buffers first.\n"); + return -EINVAL; + } - if (dev->io == IO_READ) { - em28xx_videodbg ("method is set to read;" - " close and open the device again to" - " choose the mmap I/O method\n"); - return -EINVAL; + /* stop io in case it is already in progress */ + if (dev->stream == STREAM_ON) { + em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n"); + if ((ret = em28xx_stream_interrupt(dev))) + return ret; + } + + em28xx_release_buffers(dev); + dev->io = IO_NONE; + + /* set new image size */ + dev->width = width; + dev->height = height; + dev->frame_size = dev->width * dev->height * 2; + dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ + dev->bytesperline = dev->width * 2; + dev->hscale = hscale; + dev->vscale = vscale; +/* dev->both_fileds = both_fileds; */ + em28xx_uninit_isoc(dev); + em28xx_set_alternate(dev); + em28xx_capture_start(dev, 1); + em28xx_resolution_set(dev); + em28xx_init_isoc(dev); + + return 0; } - for (i = 0; i < dev->num_frames; i++) - if (dev->frame[i].vma_use_count) { - em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n"); + /* --- streaming capture ------------------------------------- */ + case VIDIOC_REQBUFS: + { + struct v4l2_requestbuffers *rb = arg; + u32 i; + int ret; + + if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + rb->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + + if (dev->io == IO_READ) { + em28xx_videodbg ("method is set to read;" + " close and open the device again to" + " choose the mmap I/O method\n"); return -EINVAL; } - if (dev->stream == STREAM_ON) { - em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n"); - if ((ret = em28xx_stream_interrupt(dev))) - return ret; - } + for (i = 0; i < dev->num_frames; i++) + if (dev->frame[i].vma_use_count) { + em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n"); + return -EINVAL; + } - em28xx_empty_framequeues(dev); + if (dev->stream == STREAM_ON) { + em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n"); + if ((ret = em28xx_stream_interrupt(dev))) + return ret; + } - em28xx_release_buffers(dev); - if (rb->count) - rb->count = - em28xx_request_buffers(dev, rb->count); + em28xx_empty_framequeues(dev); - dev->frame_current = NULL; + em28xx_release_buffers(dev); + if (rb->count) + rb->count = + em28xx_request_buffers(dev, rb->count); + + dev->frame_current = NULL; + + em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n", + rb->count); + dev->io = rb->count ? IO_MMAP : IO_NONE; + return 0; + } - em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n", - rb->count); - dev->io = rb->count ? IO_MMAP : IO_NONE; - return 0; - } case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *b = arg; + { + struct v4l2_buffer *b = arg; - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b->index >= dev->num_frames || dev->io != IO_MMAP) - return -EINVAL; + if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + b->index >= dev->num_frames || dev->io != IO_MMAP) + return -EINVAL; - memcpy(b, &dev->frame[b->index].buf, sizeof(*b)); + memcpy(b, &dev->frame[b->index].buf, sizeof(*b)); - if (dev->frame[b->index].vma_use_count) { - b->flags |= V4L2_BUF_FLAG_MAPPED; + if (dev->frame[b->index].vma_use_count) { + b->flags |= V4L2_BUF_FLAG_MAPPED; + } + if (dev->frame[b->index].state == F_DONE) + b->flags |= V4L2_BUF_FLAG_DONE; + else if (dev->frame[b->index].state != F_UNUSED) + b->flags |= V4L2_BUF_FLAG_QUEUED; + return 0; } - if (dev->frame[b->index].state == F_DONE) - b->flags |= V4L2_BUF_FLAG_DONE; - else if (dev->frame[b->index].state != F_UNUSED) - b->flags |= V4L2_BUF_FLAG_QUEUED; - return 0; - } case VIDIOC_QBUF: - { - struct v4l2_buffer *b = arg; - unsigned long lock_flags; + { + struct v4l2_buffer *b = arg; + unsigned long lock_flags; - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b->index >= dev->num_frames || dev->io != IO_MMAP) { - return -EINVAL; - } + if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + b->index >= dev->num_frames || dev->io != IO_MMAP) { + return -EINVAL; + } - if (dev->frame[b->index].state != F_UNUSED) { - return -EAGAIN; - } - dev->frame[b->index].state = F_QUEUED; + if (dev->frame[b->index].state != F_UNUSED) { + return -EAGAIN; + } + dev->frame[b->index].state = F_QUEUED; - /* add frame to fifo */ - spin_lock_irqsave(&dev->queue_lock, lock_flags); - list_add_tail(&dev->frame[b->index].frame, - &dev->inqueue); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); + /* add frame to fifo */ + spin_lock_irqsave(&dev->queue_lock, lock_flags); + list_add_tail(&dev->frame[b->index].frame, + &dev->inqueue); + spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - return 0; - } + return 0; + } case VIDIOC_DQBUF: - { - struct v4l2_buffer *b = arg; - struct em28xx_frame_t *f; - unsigned long lock_flags; - int ret = 0; - - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE - || dev->io != IO_MMAP) - return -EINVAL; + { + struct v4l2_buffer *b = arg; + struct em28xx_frame_t *f; + unsigned long lock_flags; + int ret = 0; - if (list_empty(&dev->outqueue)) { - if (dev->stream == STREAM_OFF) + if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE + || dev->io != IO_MMAP) return -EINVAL; - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - ret = wait_event_interruptible - (dev->wait_frame, - (!list_empty(&dev->outqueue)) || - (dev->state & DEV_DISCONNECTED)); - if (ret) - return ret; - if (dev->state & DEV_DISCONNECTED) - return -ENODEV; - } - spin_lock_irqsave(&dev->queue_lock, lock_flags); - f = list_entry(dev->outqueue.next, - struct em28xx_frame_t, frame); - list_del(dev->outqueue.next); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); + if (list_empty(&dev->outqueue)) { + if (dev->stream == STREAM_OFF) + return -EINVAL; + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + ret = wait_event_interruptible + (dev->wait_frame, + (!list_empty(&dev->outqueue)) || + (dev->state & DEV_DISCONNECTED)); + if (ret) + return ret; + if (dev->state & DEV_DISCONNECTED) + return -ENODEV; + } - f->state = F_UNUSED; - memcpy(b, &f->buf, sizeof(*b)); + spin_lock_irqsave(&dev->queue_lock, lock_flags); + f = list_entry(dev->outqueue.next, + struct em28xx_frame_t, frame); + list_del(dev->outqueue.next); + spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - if (f->vma_use_count) - b->flags |= V4L2_BUF_FLAG_MAPPED; + f->state = F_UNUSED; + memcpy(b, &f->buf, sizeof(*b)); - return 0; - } + if (f->vma_use_count) + b->flags |= V4L2_BUF_FLAG_MAPPED; + + return 0; + } default: return em28xx_do_ioctl(inode, filp, dev, cmd, arg, em28xx_video_do_ioctl); @@ -1453,25 +1621,25 @@ static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp, int ret = 0; struct em28xx *dev = filp->private_data; - if (mutex_lock_interruptible(&dev->fileop_lock)) + if (down_interruptible(&dev->fileop_lock)) return -ERESTARTSYS; if (dev->state & DEV_DISCONNECTED) { em28xx_errdev("v4l2 ioctl: device not present\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -ENODEV; } if (dev->state & DEV_MISCONFIGURED) { em28xx_errdev ("v4l2 ioctl: device is misconfigured; close and open it again\n"); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return -EIO; } ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl); - mutex_unlock(&dev->fileop_lock); + up(&dev->fileop_lock); return ret; } @@ -1505,7 +1673,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->udev = udev; dev->model = model; - mutex_init(&dev->lock); + init_MUTEX(&dev->lock); init_waitqueue_head(&dev->open); dev->em28xx_write_regs = em28xx_write_regs; @@ -1561,11 +1729,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->vpic.depth = 16; dev->vpic.palette = VIDEO_PALETTE_YUV422; - em28xx_pre_card_setup(dev); #ifdef CONFIG_MODULES /* request some modules */ if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114) - request_module("saa7115"); + request_module("saa711x"); if (dev->decoder == EM28XX_TVP5150) request_module("tvp5150"); if (dev->has_tuner) @@ -1576,12 +1743,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, errCode = em28xx_config(dev); if (errCode) { em28xx_errdev("error configuring device\n"); - em28xx_devused&=~(1<devno); kfree(dev); return -ENOMEM; } - mutex_lock(&dev->lock); + down(&dev->lock); /* register i2c bus */ em28xx_i2c_register(dev); @@ -1591,7 +1757,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, /* configure the device */ em28xx_config_i2c(dev); - mutex_unlock(&dev->lock); + up(&dev->lock); errCode = em28xx_config(dev); @@ -1603,31 +1769,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->vdev = video_device_alloc(); if (NULL == dev->vdev) { em28xx_errdev("cannot allocate video_device.\n"); - em28xx_devused&=~(1<devno); kfree(dev); return -ENOMEM; } - dev->vbi_dev = video_device_alloc(); - if (NULL == dev->vbi_dev) { - em28xx_errdev("cannot allocate video_device.\n"); - kfree(dev->vdev); - em28xx_devused&=~(1<devno); - kfree(dev); - return -ENOMEM; - } - - /* Fills VBI device info */ - dev->vbi_dev->type = VFL_TYPE_VBI; - dev->vbi_dev->hardware = 0; - dev->vbi_dev->fops = &em28xx_v4l_fops; - dev->vbi_dev->minor = -1; - dev->vbi_dev->dev = &dev->udev->dev; - dev->vbi_dev->release = video_device_release; - snprintf(dev->vbi_dev->name, sizeof(dev->vbi_dev->name), "%s#%d %s", - "em28xx",dev->devno,"vbi"); - - /* Fills CAPTURE device info */ dev->vdev->type = VID_TYPE_CAPTURE; if (dev->has_tuner) dev->vdev->type |= VID_TYPE_TUNER; @@ -1636,39 +1781,21 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->vdev->minor = -1; dev->vdev->dev = &dev->udev->dev; dev->vdev->release = video_device_release; - snprintf(dev->vdev->name, sizeof(dev->vbi_dev->name), "%s#%d %s", - "em28xx",dev->devno,"video"); - + snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s", + "em28xx video"); list_add_tail(&dev->devlist,&em28xx_devlist); /* register v4l2 device */ - mutex_lock(&dev->lock); - if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, - video_nr[dev->devno]))) { + down(&dev->lock); + if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) { em28xx_errdev("unable to register video device (error=%i).\n", retval); - mutex_unlock(&dev->lock); + up(&dev->lock); list_del(&dev->devlist); video_device_release(dev->vdev); - em28xx_devused&=~(1<devno); kfree(dev); return -ENODEV; } - - if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI, - vbi_nr[dev->devno]) < 0) { - printk("unable to register vbi device\n"); - mutex_unlock(&dev->lock); - list_del(&dev->devlist); - video_device_release(dev->vbi_dev); - video_device_release(dev->vdev); - em28xx_devused&=~(1<devno); - kfree(dev); - return -ENODEV; - } else { - printk("registered VBI\n"); - } - if (dev->has_msp34xx) { /* Send a reset to other chips via gpio */ em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); @@ -1679,11 +1806,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, } video_mux(dev, 0); - mutex_unlock(&dev->lock); + up(&dev->lock); - em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", - dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, - dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); + em28xx_info("V4L2 device registered as /dev/video%d\n", + dev->vdev->minor); return 0; } @@ -1705,9 +1831,6 @@ static int em28xx_usb_probe(struct usb_interface *interface, udev = usb_get_dev(interface_to_usbdev(interface)); ifnum = interface->altsetting[0].desc.bInterfaceNumber; - /* Check to see next free device and mark as used */ - nr=find_first_zero_bit(&em28xx_devused,EM28XX_MAXBOARDS); - em28xx_devused|=1<altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { @@ -1715,8 +1838,6 @@ static int em28xx_usb_probe(struct usb_interface *interface, udev->descriptor.idVendor,udev->descriptor.idProduct, ifnum, interface->altsetting[0].desc.bInterfaceClass); - - em28xx_devused&=~(1<bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); - em28xx_devused&=~(1<bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); - em28xx_devused&=~(1<driver_info; + nr=interface->minor; - if (nr >= EM28XX_MAXBOARDS) { + if (nr>EM28XX_MAXBOARDS) { printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS); - em28xx_devused&=~(1<name, 29, "em28xx #%d", nr); - dev->devno=nr; - /* compute alternate max packet sizes */ uif = udev->actconfig->interface[0]; dev->num_alt=uif->num_altsetting; - em28xx_info("Alternate settings: %i\n",dev->num_alt); + printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt); // dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* dev->alt_max_pkt_size = kmalloc(32* dev->num_alt,GFP_KERNEL); if (dev->alt_max_pkt_size == NULL) { - em28xx_errdev("out of memory!\n"); - em28xx_devused&=~(1<alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - em28xx_info("Alternate setting %i, max size= %i\n",i, + printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i, dev->alt_max_pkt_size[i]); } + snprintf(dev->name, 29, "em28xx #%d", nr); + if ((card[nr]>=0)&&(card[nr] insmod option to\n" "%s: workaround that. Redirect complaints to the vendor of\n" - "%s: the TV card. Generic type will be used." - "%s: Best regards,\n" + "%s: the TV card. Best regards,\n" "%s: -- tux\n", dev->name,dev->name,dev->name,dev->name,dev->name); - em28xx_errdev("%s: Here is a list of valid choices for the card= insmod option:\n", + printk("%s: Here is a list of valid choices for the card= insmod option:\n", dev->name); for (i = 0; i < em28xx_bcount; i++) { - em28xx_errdev(" card=%d -> %s\n", i, - em28xx_boards[i].name); + printk("%s: card=%d -> %s\n", + dev->name, i, em28xx_boards[i].name); } } @@ -1823,12 +1938,15 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) struct em28xx *dev = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); +/*FIXME: IR should be disconnected */ + if (!dev) return; + down_write(&em28xx_disconnect); - mutex_lock(&dev->lock); + down(&dev->lock); em28xx_info("disconnecting %s\n", dev->vdev->name); @@ -1837,9 +1955,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) if (dev->users) { em28xx_warn ("device /dev/video%d is open! Deregistration and memory " - "deallocation are deferred on close.\n", - dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); - + "deallocation are deferred on close.\n", dev->vdev->minor); dev->state |= DEV_MISCONFIGURED; em28xx_uninit_isoc(dev); dev->state |= DEV_DISCONNECTED; @@ -1850,7 +1966,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) em28xx_release_resources(dev); } - mutex_unlock(&dev->lock); + up(&dev->lock); if (!dev->users) { kfree(dev->alt_max_pkt_size); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index e1ddc2f27..33de9d846 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -27,7 +27,6 @@ #include #include -#include #include /* Boards supported by driver */ @@ -42,10 +41,6 @@ #define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 #define EM2800_BOARD_KWORLD_USB2800 8 #define EM2820_BOARD_PINNACLE_DVC_90 9 -#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 -#define EM2880_BOARD_TERRATEC_HYBRID_XS 11 -#define EM2820_BOARD_KWORLD_PVRTV2800RF 12 -#define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 #define UNSET -1 @@ -214,7 +209,6 @@ struct em28xx { /* 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 */ unsigned int is_em2800; int video_inputs; /* number of video inputs */ struct list_head devlist; @@ -262,7 +256,7 @@ struct em28xx { enum em28xx_stream_state stream; enum em28xx_io_method io; /* locks */ - struct mutex lock, fileop_lock; + struct semaphore lock, fileop_lock; spinlock_t queue_lock; struct list_head inqueue, outqueue; wait_queue_head_t open, wait_frame, wait_stream; @@ -332,7 +326,6 @@ int em28xx_set_alternate(struct em28xx *dev); /* Provided by em28xx-cards.c */ extern int em2800_variant_detect(struct usb_device* udev,int model); -extern void em28xx_pre_card_setup(struct em28xx *dev); extern void em28xx_card_setup(struct em28xx *dev); extern struct em28xx_board em28xx_boards[]; extern struct usb_device_id em28xx_id_table[]; diff --git a/drivers/media/video/et61x251/Kconfig b/drivers/media/video/et61x251/Kconfig deleted file mode 100644 index c6bff7056..000000000 --- a/drivers/media/video/et61x251/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -config USB_ET61X251 - tristate "USB ET61X[12]51 PC Camera Controller support" - depends on USB && VIDEO_V4L1 - ---help--- - Say Y here if you want support for cameras based on Etoms ET61X151 - or ET61X251 PC Camera Controllers. - - See for more info. - - This driver uses the Video For Linux API. You must say Y or M to - "Video For Linux" to use this driver. - - To compile this driver as a module, choose M here: the - module will be called et61x251. diff --git a/drivers/media/video/et61x251/Makefile b/drivers/media/video/et61x251/Makefile deleted file mode 100644 index 2ff4db9ec..000000000 --- a/drivers/media/video/et61x251/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o - -obj-$(CONFIG_USB_ET61X251) += et61x251.o - diff --git a/drivers/media/video/et61x251/et61x251.h b/drivers/media/video/et61x251/et61x251.h deleted file mode 100644 index 2e5ca4032..000000000 --- a/drivers/media/video/et61x251/et61x251.h +++ /dev/null @@ -1,234 +0,0 @@ -/*************************************************************************** - * V4L2 driver for ET61X[12]51 PC Camera Controllers * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 _ET61X251_H_ -#define _ET61X251_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "et61x251_sensor.h" - -/*****************************************************************************/ - -#define ET61X251_DEBUG -#define ET61X251_DEBUG_LEVEL 2 -#define ET61X251_MAX_DEVICES 64 -#define ET61X251_PRESERVE_IMGSCALE 0 -#define ET61X251_FORCE_MUNMAP 0 -#define ET61X251_MAX_FRAMES 32 -#define ET61X251_COMPRESSION_QUALITY 0 -#define ET61X251_URBS 2 -#define ET61X251_ISO_PACKETS 7 -#define ET61X251_ALTERNATE_SETTING 13 -#define ET61X251_URB_TIMEOUT msecs_to_jiffies(2 * ET61X251_ISO_PACKETS) -#define ET61X251_CTRL_TIMEOUT 100 -#define ET61X251_FRAME_TIMEOUT 2 - -/*****************************************************************************/ - -static const struct usb_device_id et61x251_id_table[] = { - { USB_DEVICE(0x102c, 0x6151), }, - { USB_DEVICE(0x102c, 0x6251), }, - { USB_DEVICE(0x102c, 0x6253), }, - { USB_DEVICE(0x102c, 0x6254), }, - { USB_DEVICE(0x102c, 0x6255), }, - { USB_DEVICE(0x102c, 0x6256), }, - { USB_DEVICE(0x102c, 0x6257), }, - { USB_DEVICE(0x102c, 0x6258), }, - { USB_DEVICE(0x102c, 0x6259), }, - { USB_DEVICE(0x102c, 0x625a), }, - { USB_DEVICE(0x102c, 0x625b), }, - { USB_DEVICE(0x102c, 0x625c), }, - { USB_DEVICE(0x102c, 0x625d), }, - { USB_DEVICE(0x102c, 0x625e), }, - { USB_DEVICE(0x102c, 0x625f), }, - { USB_DEVICE(0x102c, 0x6260), }, - { USB_DEVICE(0x102c, 0x6261), }, - { USB_DEVICE(0x102c, 0x6262), }, - { USB_DEVICE(0x102c, 0x6263), }, - { USB_DEVICE(0x102c, 0x6264), }, - { USB_DEVICE(0x102c, 0x6265), }, - { USB_DEVICE(0x102c, 0x6266), }, - { USB_DEVICE(0x102c, 0x6267), }, - { USB_DEVICE(0x102c, 0x6268), }, - { USB_DEVICE(0x102c, 0x6269), }, - { } -}; - -ET61X251_SENSOR_TABLE - -/*****************************************************************************/ - -enum et61x251_frame_state { - F_UNUSED, - F_QUEUED, - F_GRABBING, - F_DONE, - F_ERROR, -}; - -struct et61x251_frame_t { - void* bufmem; - struct v4l2_buffer buf; - enum et61x251_frame_state state; - struct list_head frame; - unsigned long vma_use_count; -}; - -enum et61x251_dev_state { - DEV_INITIALIZED = 0x01, - DEV_DISCONNECTED = 0x02, - DEV_MISCONFIGURED = 0x04, -}; - -enum et61x251_io_method { - IO_NONE, - IO_READ, - IO_MMAP, -}; - -enum et61x251_stream_state { - STREAM_OFF, - STREAM_INTERRUPT, - STREAM_ON, -}; - -struct et61x251_sysfs_attr { - u8 reg, i2c_reg; -}; - -struct et61x251_module_param { - u8 force_munmap; - u16 frame_timeout; -}; - -static DEFINE_MUTEX(et61x251_sysfs_lock); -static DECLARE_RWSEM(et61x251_disconnect); - -struct et61x251_device { - struct video_device* v4ldev; - - struct et61x251_sensor sensor; - - struct usb_device* usbdev; - struct urb* urb[ET61X251_URBS]; - void* transfer_buffer[ET61X251_URBS]; - u8* control_buffer; - - struct et61x251_frame_t *frame_current, frame[ET61X251_MAX_FRAMES]; - struct list_head inqueue, outqueue; - u32 frame_count, nbuffers, nreadbuffers; - - enum et61x251_io_method io; - enum et61x251_stream_state stream; - - struct v4l2_jpegcompression compression; - - struct et61x251_sysfs_attr sysfs; - struct et61x251_module_param module_param; - - enum et61x251_dev_state state; - u8 users; - - struct mutex dev_mutex, fileop_mutex; - spinlock_t queue_lock; - wait_queue_head_t open, wait_frame, wait_stream; -}; - -/*****************************************************************************/ - -struct et61x251_device* -et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id) -{ - if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id)) - return cam; - - return NULL; -} - - -void -et61x251_attach_sensor(struct et61x251_device* cam, - struct et61x251_sensor* sensor) -{ - memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor)); -} - -/*****************************************************************************/ - -#undef DBG -#undef KDBG -#ifdef ET61X251_DEBUG -# define DBG(level, fmt, args...) \ -do { \ - if (debug >= (level)) { \ - if ((level) == 1) \ - dev_err(&cam->usbdev->dev, fmt "\n", ## args); \ - else if ((level) == 2) \ - dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ - else if ((level) >= 3) \ - dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args); \ - } \ -} while (0) -# define KDBG(level, fmt, args...) \ -do { \ - if (debug >= (level)) { \ - if ((level) == 1 || (level) == 2) \ - pr_info("et61x251: " fmt "\n", ## args); \ - else if ((level) == 3) \ - pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \ - __LINE__ , ## args); \ - } \ -} while (0) -# define V4LDBG(level, name, cmd) \ -do { \ - if (debug >= (level)) \ - v4l_print_ioctl(name, cmd); \ -} while (0) -#else -# define DBG(level, fmt, args...) do {;} while(0) -# define KDBG(level, fmt, args...) do {;} while(0) -# define V4LDBG(level, name, cmd) do {;} while(0) -#endif - -#undef PDBG -#define PDBG(fmt, args...) \ -dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args) - -#undef PDBGG -#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ - -#endif /* _ET61X251_H_ */ diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c deleted file mode 100644 index dfc9dd732..000000000 --- a/drivers/media/video/et61x251/et61x251_core.c +++ /dev/null @@ -1,2630 +0,0 @@ -/*************************************************************************** - * V4L2 driver for ET61X[12]51 PC Camera Controllers * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "et61x251.h" - -/*****************************************************************************/ - -#define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \ - "PC Camera Controllers" -#define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia" -#define ET61X251_AUTHOR_EMAIL "" -#define ET61X251_MODULE_LICENSE "GPL" -#define ET61X251_MODULE_VERSION "1:1.02" -#define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 2) - -/*****************************************************************************/ - -MODULE_DEVICE_TABLE(usb, et61x251_id_table); - -MODULE_AUTHOR(ET61X251_MODULE_AUTHOR " " ET61X251_AUTHOR_EMAIL); -MODULE_DESCRIPTION(ET61X251_MODULE_NAME); -MODULE_VERSION(ET61X251_MODULE_VERSION); -MODULE_LICENSE(ET61X251_MODULE_LICENSE); - -static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1}; -module_param_array(video_nr, short, NULL, 0444); -MODULE_PARM_DESC(video_nr, - "\n<-1|n[,...]> Specify V4L2 minor mode number." - "\n -1 = use next available (default)" - "\n n = use minor number n (integer >= 0)" - "\nYou can specify up to " - __MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way." - "\nFor example:" - "\nvideo_nr=-1,2,-1 would assign minor number 2 to" - "\nthe second registered camera and use auto for the first" - "\none and for every other camera." - "\n"); - -static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] = - ET61X251_FORCE_MUNMAP}; -module_param_array(force_munmap, bool, NULL, 0444); -MODULE_PARM_DESC(force_munmap, - "\n<0|1[,...]> Force the application to unmap previously" - "\nmapped buffer memory before calling any VIDIOC_S_CROP or" - "\nVIDIOC_S_FMT ioctl's. Not all the applications support" - "\nthis feature. This parameter is specific for each" - "\ndetected camera." - "\n 0 = do not force memory unmapping" - "\n 1 = force memory unmapping (save memory)" - "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." - "\n"); - -static unsigned int frame_timeout[] = {[0 ... ET61X251_MAX_DEVICES-1] = - ET61X251_FRAME_TIMEOUT}; -module_param_array(frame_timeout, uint, NULL, 0644); -MODULE_PARM_DESC(frame_timeout, - "\n Timeout for a video frame in seconds." - "\nThis parameter is specific for each detected camera." - "\nDefault value is " - __MODULE_STRING(ET61X251_FRAME_TIMEOUT)"." - "\n"); - -#ifdef ET61X251_DEBUG -static unsigned short debug = ET61X251_DEBUG_LEVEL; -module_param(debug, ushort, 0644); -MODULE_PARM_DESC(debug, - "\n Debugging information level, from 0 to 3:" - "\n0 = none (use carefully)" - "\n1 = critical errors" - "\n2 = significant informations" - "\n3 = more verbose messages" - "\nLevel 3 is useful for testing only, when only " - "one device is used." - "\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"." - "\n"); -#endif - -/*****************************************************************************/ - -static u32 -et61x251_request_buffers(struct et61x251_device* cam, u32 count, - enum et61x251_io_method io) -{ - struct v4l2_pix_format* p = &(cam->sensor.pix_format); - struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); - const size_t imagesize = cam->module_param.force_munmap || - io == IO_READ ? - (p->width * p->height * p->priv) / 8 : - (r->width * r->height * p->priv) / 8; - void* buff = NULL; - u32 i; - - if (count > ET61X251_MAX_FRAMES) - count = ET61X251_MAX_FRAMES; - - cam->nbuffers = count; - while (cam->nbuffers > 0) { - if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize)))) - break; - cam->nbuffers--; - } - - for (i = 0; i < cam->nbuffers; i++) { - cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize); - cam->frame[i].buf.index = i; - cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize); - cam->frame[i].buf.length = imagesize; - cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cam->frame[i].buf.sequence = 0; - cam->frame[i].buf.field = V4L2_FIELD_NONE; - cam->frame[i].buf.memory = V4L2_MEMORY_MMAP; - cam->frame[i].buf.flags = 0; - } - - return cam->nbuffers; -} - - -static void et61x251_release_buffers(struct et61x251_device* cam) -{ - if (cam->nbuffers) { - vfree(cam->frame[0].bufmem); - cam->nbuffers = 0; - } - cam->frame_current = NULL; -} - - -static void et61x251_empty_framequeues(struct et61x251_device* cam) -{ - u32 i; - - INIT_LIST_HEAD(&cam->inqueue); - INIT_LIST_HEAD(&cam->outqueue); - - for (i = 0; i < ET61X251_MAX_FRAMES; i++) { - cam->frame[i].state = F_UNUSED; - cam->frame[i].buf.bytesused = 0; - } -} - - -static void et61x251_requeue_outqueue(struct et61x251_device* cam) -{ - struct et61x251_frame_t *i; - - list_for_each_entry(i, &cam->outqueue, frame) { - i->state = F_QUEUED; - list_add(&i->frame, &cam->inqueue); - } - - INIT_LIST_HEAD(&cam->outqueue); -} - - -static void et61x251_queue_unusedframes(struct et61x251_device* cam) -{ - unsigned long lock_flags; - u32 i; - - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].state == F_UNUSED) { - cam->frame[i].state = F_QUEUED; - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_add_tail(&cam->frame[i].frame, &cam->inqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - } -} - -/*****************************************************************************/ - -int et61x251_write_reg(struct et61x251_device* cam, u8 value, u16 index) -{ - struct usb_device* udev = cam->usbdev; - u8* buff = cam->control_buffer; - int res; - - *buff = value; - - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, - 0, index, buff, 1, ET61X251_CTRL_TIMEOUT); - if (res < 0) { - DBG(3, "Failed to write a register (value 0x%02X, index " - "0x%02X, error %d)", value, index, res); - return -1; - } - - return 0; -} - - -int et61x251_read_reg(struct et61x251_device* cam, u16 index) -{ - struct usb_device* udev = cam->usbdev; - u8* buff = cam->control_buffer; - int res; - - res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1, - 0, index, buff, 1, ET61X251_CTRL_TIMEOUT); - if (res < 0) - DBG(3, "Failed to read a register (index 0x%02X, error %d)", - index, res); - - return (res >= 0) ? (int)(*buff) : -1; -} - - -static int -et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor) -{ - int i, r; - - for (i = 1; i <= 8; i++) { - if (sensor->interface == ET61X251_I2C_3WIRES) { - r = et61x251_read_reg(cam, 0x8e); - if (!(r & 0x02) && (r >= 0)) - return 0; - } else { - r = et61x251_read_reg(cam, 0x8b); - if (!(r & 0x01) && (r >= 0)) - return 0; - } - if (r < 0) - return -EIO; - udelay(8*8); /* minimum for sensors at 400kHz */ - } - - return -EBUSY; -} - - -int -et61x251_i2c_try_read(struct et61x251_device* cam, - struct et61x251_sensor* sensor, u8 address) -{ - struct usb_device* udev = cam->usbdev; - u8* data = cam->control_buffer; - int err = 0, res; - - data[0] = address; - data[1] = cam->sensor.i2c_slave_id; - data[2] = cam->sensor.rsta | 0x10; - data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02); - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, - 0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT); - if (res < 0) - err += res; - - err += et61x251_i2c_wait(cam, sensor); - - res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1, - 0, 0x80, data, 8, ET61X251_CTRL_TIMEOUT); - if (res < 0) - err += res; - - if (err) - DBG(3, "I2C read failed for %s image sensor", sensor->name); - - PDBGG("I2C read: address 0x%02X, value: 0x%02X", address, data[0]); - - return err ? -1 : (int)data[0]; -} - - -int -et61x251_i2c_try_write(struct et61x251_device* cam, - struct et61x251_sensor* sensor, u8 address, u8 value) -{ - struct usb_device* udev = cam->usbdev; - u8* data = cam->control_buffer; - int err = 0, res; - - data[0] = address; - data[1] = cam->sensor.i2c_slave_id; - data[2] = cam->sensor.rsta | 0x12; - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, - 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); - if (res < 0) - err += res; - - data[0] = value; - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, - 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT); - if (res < 0) - err += res; - - err += et61x251_i2c_wait(cam, sensor); - - if (err) - DBG(3, "I2C write failed for %s image sensor", sensor->name); - - PDBGG("I2C write: address 0x%02X, value: 0x%02X", address, value); - - return err ? -1 : 0; -} - - -int -et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2, - u8 data3, u8 data4, u8 data5, u8 data6, u8 data7, - u8 data8, u8 address) -{ - struct usb_device* udev = cam->usbdev; - u8* data = cam->control_buffer; - int err = 0, res; - - data[0] = data2; - data[1] = data3; - data[2] = data4; - data[3] = data5; - data[4] = data6; - data[5] = data7; - data[6] = data8; - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, - 0, 0x81, data, n-1, ET61X251_CTRL_TIMEOUT); - if (res < 0) - err += res; - - data[0] = address; - data[1] = cam->sensor.i2c_slave_id; - data[2] = cam->sensor.rsta | 0x02 | (n << 4); - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, - 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); - if (res < 0) - err += res; - - /* Start writing through the serial interface */ - data[0] = data1; - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, - 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT); - if (res < 0) - err += res; - - err += et61x251_i2c_wait(cam, &cam->sensor); - - if (err) - DBG(3, "I2C raw write failed for %s image sensor", - cam->sensor.name); - - PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, " - "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X," - " data6 = 0x%02X, data7 = 0x%02X, data8 = 0x%02X", n, address, - data1, data2, data3, data4, data5, data6, data7, data8); - - return err ? -1 : 0; - -} - - -int et61x251_i2c_read(struct et61x251_device* cam, u8 address) -{ - return et61x251_i2c_try_read(cam, &cam->sensor, address); -} - - -int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value) -{ - return et61x251_i2c_try_write(cam, &cam->sensor, address, value); -} - -/*****************************************************************************/ - -static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs) -{ - struct et61x251_device* cam = urb->context; - struct et61x251_frame_t** f; - size_t imagesize; - u8 i; - int err = 0; - - if (urb->status == -ENOENT) - return; - - f = &cam->frame_current; - - if (cam->stream == STREAM_INTERRUPT) { - cam->stream = STREAM_OFF; - if ((*f)) - (*f)->state = F_QUEUED; - DBG(3, "Stream interrupted"); - wake_up(&cam->wait_stream); - } - - if (cam->state & DEV_DISCONNECTED) - return; - - if (cam->state & DEV_MISCONFIGURED) { - wake_up_interruptible(&cam->wait_frame); - return; - } - - if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue)) - goto resubmit_urb; - - if (!(*f)) - (*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t, - frame); - - imagesize = (cam->sensor.pix_format.width * - cam->sensor.pix_format.height * - cam->sensor.pix_format.priv) / 8; - - for (i = 0; i < urb->number_of_packets; i++) { - unsigned int len, status; - void *pos; - u8* b1, * b2, sof; - const u8 VOID_BYTES = 6; - size_t imglen; - - len = urb->iso_frame_desc[i].actual_length; - status = urb->iso_frame_desc[i].status; - pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer; - - if (status) { - DBG(3, "Error in isochronous frame"); - (*f)->state = F_ERROR; - continue; - } - - b1 = pos++; - b2 = pos++; - sof = ((*b1 & 0x3f) == 63); - imglen = ((*b1 & 0xc0) << 2) | *b2; - - PDBGG("Isochrnous frame: length %u, #%u i, image length %zu", - len, i, imglen); - - if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) -start_of_frame: - if (sof) { - (*f)->state = F_GRABBING; - (*f)->buf.bytesused = 0; - do_gettimeofday(&(*f)->buf.timestamp); - pos += 22; - DBG(3, "SOF detected: new video frame"); - } - - if ((*f)->state == F_GRABBING) { - if (sof && (*f)->buf.bytesused) { - if (cam->sensor.pix_format.pixelformat == - V4L2_PIX_FMT_ET61X251) - goto end_of_frame; - else { - DBG(3, "Not expected SOF detected " - "after %lu bytes", - (unsigned long)(*f)->buf.bytesused); - (*f)->state = F_ERROR; - continue; - } - } - - if ((*f)->buf.bytesused + imglen > imagesize) { - DBG(3, "Video frame size exceeded"); - (*f)->state = F_ERROR; - continue; - } - - pos += VOID_BYTES; - - memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, imglen); - (*f)->buf.bytesused += imglen; - - if ((*f)->buf.bytesused == imagesize) { - u32 b; -end_of_frame: - b = (*f)->buf.bytesused; - (*f)->state = F_DONE; - (*f)->buf.sequence= ++cam->frame_count; - spin_lock(&cam->queue_lock); - list_move_tail(&(*f)->frame, &cam->outqueue); - if (!list_empty(&cam->inqueue)) - (*f) = list_entry(cam->inqueue.next, - struct et61x251_frame_t, - frame); - else - (*f) = NULL; - spin_unlock(&cam->queue_lock); - DBG(3, "Video frame captured: : %lu bytes", - (unsigned long)(b)); - - if (!(*f)) - goto resubmit_urb; - - if (sof && - cam->sensor.pix_format.pixelformat == - V4L2_PIX_FMT_ET61X251) - goto start_of_frame; - } - } - } - -resubmit_urb: - urb->dev = cam->usbdev; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0 && err != -EPERM) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "usb_submit_urb() failed"); - } - - wake_up_interruptible(&cam->wait_frame); -} - - -static int et61x251_start_transfer(struct et61x251_device* cam) -{ - struct usb_device *udev = cam->usbdev; - struct urb* urb; - const unsigned int wMaxPacketSize[] = {0, 256, 384, 512, 640, 768, 832, - 864, 896, 920, 956, 980, 1000, - 1022}; - const unsigned int psz = wMaxPacketSize[ET61X251_ALTERNATE_SETTING]; - s8 i, j; - int err = 0; - - for (i = 0; i < ET61X251_URBS; i++) { - cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz, - GFP_KERNEL); - if (!cam->transfer_buffer[i]) { - err = -ENOMEM; - DBG(1, "Not enough memory"); - goto free_buffers; - } - } - - for (i = 0; i < ET61X251_URBS; i++) { - urb = usb_alloc_urb(ET61X251_ISO_PACKETS, GFP_KERNEL); - cam->urb[i] = urb; - if (!urb) { - err = -ENOMEM; - DBG(1, "usb_alloc_urb() failed"); - goto free_urbs; - } - urb->dev = udev; - urb->context = cam; - urb->pipe = usb_rcvisocpipe(udev, 1); - urb->transfer_flags = URB_ISO_ASAP; - urb->number_of_packets = ET61X251_ISO_PACKETS; - urb->complete = et61x251_urb_complete; - urb->transfer_buffer = cam->transfer_buffer[i]; - urb->transfer_buffer_length = psz * ET61X251_ISO_PACKETS; - urb->interval = 1; - for (j = 0; j < ET61X251_ISO_PACKETS; j++) { - urb->iso_frame_desc[j].offset = psz * j; - urb->iso_frame_desc[j].length = psz; - } - } - - err = et61x251_write_reg(cam, 0x01, 0x03); - err = et61x251_write_reg(cam, 0x00, 0x03); - err = et61x251_write_reg(cam, 0x08, 0x03); - if (err) { - err = -EIO; - DBG(1, "I/O hardware error"); - goto free_urbs; - } - - err = usb_set_interface(udev, 0, ET61X251_ALTERNATE_SETTING); - if (err) { - DBG(1, "usb_set_interface() failed"); - goto free_urbs; - } - - cam->frame_current = NULL; - - for (i = 0; i < ET61X251_URBS; i++) { - err = usb_submit_urb(cam->urb[i], GFP_KERNEL); - if (err) { - for (j = i-1; j >= 0; j--) - usb_kill_urb(cam->urb[j]); - DBG(1, "usb_submit_urb() failed, error %d", err); - goto free_urbs; - } - } - - return 0; - -free_urbs: - for (i = 0; (i < ET61X251_URBS) && cam->urb[i]; i++) - usb_free_urb(cam->urb[i]); - -free_buffers: - for (i = 0; (i < ET61X251_URBS) && cam->transfer_buffer[i]; i++) - kfree(cam->transfer_buffer[i]); - - return err; -} - - -static int et61x251_stop_transfer(struct et61x251_device* cam) -{ - struct usb_device *udev = cam->usbdev; - s8 i; - int err = 0; - - if (cam->state & DEV_DISCONNECTED) - return 0; - - for (i = ET61X251_URBS-1; i >= 0; i--) { - usb_kill_urb(cam->urb[i]); - usb_free_urb(cam->urb[i]); - kfree(cam->transfer_buffer[i]); - } - - err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */ - if (err) - DBG(3, "usb_set_interface() failed"); - - return err; -} - - -static int et61x251_stream_interrupt(struct et61x251_device* cam) -{ - long timeout; - - cam->stream = STREAM_INTERRUPT; - timeout = wait_event_timeout(cam->wait_stream, - (cam->stream == STREAM_OFF) || - (cam->state & DEV_DISCONNECTED), - ET61X251_URB_TIMEOUT); - if (cam->state & DEV_DISCONNECTED) - return -ENODEV; - else if (cam->stream != STREAM_OFF) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "URB timeout reached. The camera is misconfigured. To " - "use it, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -EIO; - } - - return 0; -} - -/*****************************************************************************/ - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count) -{ - char str[5]; - char* endp; - unsigned long val; - - if (len < 4) { - strncpy(str, buff, len); - str[len+1] = '\0'; - } else { - strncpy(str, buff, 4); - str[4] = '\0'; - } - - val = simple_strtoul(str, &endp, 0); - - *count = 0; - if (val <= 0xff) - *count = (ssize_t)(endp - str); - if ((*count) && (len == *count+1) && (buff[*count] == '\n')) - *count += 1; - - return (u8)val; -} - -/* - NOTE 1: being inside one of the following methods implies that the v4l - device exists for sure (see kobjects and reference counters) - NOTE 2: buffers are PAGE_SIZE long -*/ - -static ssize_t et61x251_show_reg(struct class_device* cd, char* buf) -{ - struct et61x251_device* cam; - ssize_t count; - - if (mutex_lock_interruptible(&et61x251_sysfs_lock)) - return -ERESTARTSYS; - - cam = video_get_drvdata(to_video_device(cd)); - if (!cam) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENODEV; - } - - count = sprintf(buf, "%u\n", cam->sysfs.reg); - - mutex_unlock(&et61x251_sysfs_lock); - - return count; -} - - -static ssize_t -et61x251_store_reg(struct class_device* cd, const char* buf, size_t len) -{ - struct et61x251_device* cam; - u8 index; - ssize_t count; - - if (mutex_lock_interruptible(&et61x251_sysfs_lock)) - return -ERESTARTSYS; - - cam = video_get_drvdata(to_video_device(cd)); - if (!cam) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENODEV; - } - - index = et61x251_strtou8(buf, len, &count); - if (index > 0x8e || !count) { - mutex_unlock(&et61x251_sysfs_lock); - return -EINVAL; - } - - cam->sysfs.reg = index; - - DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg); - DBG(3, "Written bytes: %zd", count); - - mutex_unlock(&et61x251_sysfs_lock); - - return count; -} - - -static ssize_t et61x251_show_val(struct class_device* cd, char* buf) -{ - struct et61x251_device* cam; - ssize_t count; - int val; - - if (mutex_lock_interruptible(&et61x251_sysfs_lock)) - return -ERESTARTSYS; - - cam = video_get_drvdata(to_video_device(cd)); - if (!cam) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENODEV; - } - - if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) { - mutex_unlock(&et61x251_sysfs_lock); - return -EIO; - } - - count = sprintf(buf, "%d\n", val); - - DBG(3, "Read bytes: %zd", count); - - mutex_unlock(&et61x251_sysfs_lock); - - return count; -} - - -static ssize_t -et61x251_store_val(struct class_device* cd, const char* buf, size_t len) -{ - struct et61x251_device* cam; - u8 value; - ssize_t count; - int err; - - if (mutex_lock_interruptible(&et61x251_sysfs_lock)) - return -ERESTARTSYS; - - cam = video_get_drvdata(to_video_device(cd)); - if (!cam) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENODEV; - } - - value = et61x251_strtou8(buf, len, &count); - if (!count) { - mutex_unlock(&et61x251_sysfs_lock); - return -EINVAL; - } - - err = et61x251_write_reg(cam, value, cam->sysfs.reg); - if (err) { - mutex_unlock(&et61x251_sysfs_lock); - return -EIO; - } - - DBG(2, "Written ET61X[12]51 reg. 0x%02X, val. 0x%02X", - cam->sysfs.reg, value); - DBG(3, "Written bytes: %zd", count); - - mutex_unlock(&et61x251_sysfs_lock); - - return count; -} - - -static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf) -{ - struct et61x251_device* cam; - ssize_t count; - - if (mutex_lock_interruptible(&et61x251_sysfs_lock)) - return -ERESTARTSYS; - - cam = video_get_drvdata(to_video_device(cd)); - if (!cam) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENODEV; - } - - count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg); - - DBG(3, "Read bytes: %zd", count); - - mutex_unlock(&et61x251_sysfs_lock); - - return count; -} - - -static ssize_t -et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len) -{ - struct et61x251_device* cam; - u8 index; - ssize_t count; - - if (mutex_lock_interruptible(&et61x251_sysfs_lock)) - return -ERESTARTSYS; - - cam = video_get_drvdata(to_video_device(cd)); - if (!cam) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENODEV; - } - - index = et61x251_strtou8(buf, len, &count); - if (!count) { - mutex_unlock(&et61x251_sysfs_lock); - return -EINVAL; - } - - cam->sysfs.i2c_reg = index; - - DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg); - DBG(3, "Written bytes: %zd", count); - - mutex_unlock(&et61x251_sysfs_lock); - - return count; -} - - -static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf) -{ - struct et61x251_device* cam; - ssize_t count; - int val; - - if (mutex_lock_interruptible(&et61x251_sysfs_lock)) - return -ERESTARTSYS; - - cam = video_get_drvdata(to_video_device(cd)); - if (!cam) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENODEV; - } - - if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENOSYS; - } - - if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) { - mutex_unlock(&et61x251_sysfs_lock); - return -EIO; - } - - count = sprintf(buf, "%d\n", val); - - DBG(3, "Read bytes: %zd", count); - - mutex_unlock(&et61x251_sysfs_lock); - - return count; -} - - -static ssize_t -et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len) -{ - struct et61x251_device* cam; - u8 value; - ssize_t count; - int err; - - if (mutex_lock_interruptible(&et61x251_sysfs_lock)) - return -ERESTARTSYS; - - cam = video_get_drvdata(to_video_device(cd)); - if (!cam) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENODEV; - } - - if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) { - mutex_unlock(&et61x251_sysfs_lock); - return -ENOSYS; - } - - value = et61x251_strtou8(buf, len, &count); - if (!count) { - mutex_unlock(&et61x251_sysfs_lock); - return -EINVAL; - } - - err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value); - if (err) { - mutex_unlock(&et61x251_sysfs_lock); - return -EIO; - } - - DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X", - cam->sysfs.i2c_reg, value); - DBG(3, "Written bytes: %zd", count); - - mutex_unlock(&et61x251_sysfs_lock); - - return count; -} - - -static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, - et61x251_show_reg, et61x251_store_reg); -static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR, - et61x251_show_val, et61x251_store_val); -static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR, - et61x251_show_i2c_reg, et61x251_store_i2c_reg); -static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, - et61x251_show_i2c_val, et61x251_store_i2c_val); - - -static void et61x251_create_sysfs(struct et61x251_device* cam) -{ - struct video_device *v4ldev = cam->v4ldev; - - video_device_create_file(v4ldev, &class_device_attr_reg); - video_device_create_file(v4ldev, &class_device_attr_val); - if (cam->sensor.sysfs_ops) { - video_device_create_file(v4ldev, &class_device_attr_i2c_reg); - video_device_create_file(v4ldev, &class_device_attr_i2c_val); - } -} -#endif /* CONFIG_VIDEO_ADV_DEBUG */ - -/*****************************************************************************/ - -static int -et61x251_set_pix_format(struct et61x251_device* cam, - struct v4l2_pix_format* pix) -{ - int r, err = 0; - - if ((r = et61x251_read_reg(cam, 0x12)) < 0) - err += r; - if (pix->pixelformat == V4L2_PIX_FMT_ET61X251) - err += et61x251_write_reg(cam, r & 0xfd, 0x12); - else - err += et61x251_write_reg(cam, r | 0x02, 0x12); - - return err ? -EIO : 0; -} - - -static int -et61x251_set_compression(struct et61x251_device* cam, - struct v4l2_jpegcompression* compression) -{ - int r, err = 0; - - if ((r = et61x251_read_reg(cam, 0x12)) < 0) - err += r; - if (compression->quality == 0) - err += et61x251_write_reg(cam, r & 0xfb, 0x12); - else - err += et61x251_write_reg(cam, r | 0x04, 0x12); - - return err ? -EIO : 0; -} - - -static int et61x251_set_scale(struct et61x251_device* cam, u8 scale) -{ - int r = 0, err = 0; - - r = et61x251_read_reg(cam, 0x12); - if (r < 0) - err += r; - - if (scale == 1) - err += et61x251_write_reg(cam, r & ~0x01, 0x12); - else if (scale == 2) - err += et61x251_write_reg(cam, r | 0x01, 0x12); - - if (err) - return -EIO; - - PDBGG("Scaling factor: %u", scale); - - return 0; -} - - -static int -et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect) -{ - struct et61x251_sensor* s = &cam->sensor; - u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left + - s->active_pixel.left), - fmw_sy = (u16)(rect->top - s->cropcap.bounds.top + - s->active_pixel.top), - fmw_length = (u16)(rect->width), - fmw_height = (u16)(rect->height); - int err = 0; - - err += et61x251_write_reg(cam, fmw_sx & 0xff, 0x69); - err += et61x251_write_reg(cam, fmw_sy & 0xff, 0x6a); - err += et61x251_write_reg(cam, fmw_length & 0xff, 0x6b); - err += et61x251_write_reg(cam, fmw_height & 0xff, 0x6c); - err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6) - | ((fmw_length & 0x300) >> 4) - | ((fmw_height & 0x300) >> 2), 0x6d); - if (err) - return -EIO; - - PDBGG("fmw_sx, fmw_sy, fmw_length, fmw_height: %u %u %u %u", - fmw_sx, fmw_sy, fmw_length, fmw_height); - - return 0; -} - - -static int et61x251_init(struct et61x251_device* cam) -{ - struct et61x251_sensor* s = &cam->sensor; - struct v4l2_control ctrl; - struct v4l2_queryctrl *qctrl; - struct v4l2_rect* rect; - u8 i = 0; - int err = 0; - - if (!(cam->state & DEV_INITIALIZED)) { - init_waitqueue_head(&cam->open); - qctrl = s->qctrl; - rect = &(s->cropcap.defrect); - cam->compression.quality = ET61X251_COMPRESSION_QUALITY; - } else { /* use current values */ - qctrl = s->_qctrl; - rect = &(s->_rect); - } - - err += et61x251_set_scale(cam, rect->width / s->pix_format.width); - err += et61x251_set_crop(cam, rect); - if (err) - return err; - - if (s->init) { - err = s->init(cam); - if (err) { - DBG(3, "Sensor initialization failed"); - return err; - } - } - - err += et61x251_set_compression(cam, &cam->compression); - err += et61x251_set_pix_format(cam, &s->pix_format); - if (s->set_pix_format) - err += s->set_pix_format(cam, &s->pix_format); - if (err) - return err; - - if (s->pix_format.pixelformat == V4L2_PIX_FMT_ET61X251) - DBG(3, "Compressed video format is active, quality %d", - cam->compression.quality); - else - DBG(3, "Uncompressed video format is active"); - - if (s->set_crop) - if ((err = s->set_crop(cam, rect))) { - DBG(3, "set_crop() failed"); - return err; - } - - if (s->set_ctrl) { - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (s->qctrl[i].id != 0 && - !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { - ctrl.id = s->qctrl[i].id; - ctrl.value = qctrl[i].default_value; - err = s->set_ctrl(cam, &ctrl); - if (err) { - DBG(3, "Set %s control failed", - s->qctrl[i].name); - return err; - } - DBG(3, "Image sensor supports '%s' control", - s->qctrl[i].name); - } - } - - if (!(cam->state & DEV_INITIALIZED)) { - mutex_init(&cam->fileop_mutex); - spin_lock_init(&cam->queue_lock); - init_waitqueue_head(&cam->wait_frame); - init_waitqueue_head(&cam->wait_stream); - cam->nreadbuffers = 2; - memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); - memcpy(&(s->_rect), &(s->cropcap.defrect), - sizeof(struct v4l2_rect)); - cam->state |= DEV_INITIALIZED; - } - - DBG(2, "Initialization succeeded"); - return 0; -} - - -static void et61x251_release_resources(struct et61x251_device* cam) -{ - mutex_lock(&et61x251_sysfs_lock); - - DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); - video_set_drvdata(cam->v4ldev, NULL); - video_unregister_device(cam->v4ldev); - - usb_put_dev(cam->usbdev); - - mutex_unlock(&et61x251_sysfs_lock); - - kfree(cam->control_buffer); -} - -/*****************************************************************************/ - -static int et61x251_open(struct inode* inode, struct file* filp) -{ - struct et61x251_device* cam; - int err = 0; - - /* - This is the only safe way to prevent race conditions with - disconnect - */ - if (!down_read_trylock(&et61x251_disconnect)) - return -ERESTARTSYS; - - cam = video_get_drvdata(video_devdata(filp)); - - if (mutex_lock_interruptible(&cam->dev_mutex)) { - up_read(&et61x251_disconnect); - return -ERESTARTSYS; - } - - if (cam->users) { - DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); - if ((filp->f_flags & O_NONBLOCK) || - (filp->f_flags & O_NDELAY)) { - err = -EWOULDBLOCK; - goto out; - } - mutex_unlock(&cam->dev_mutex); - err = wait_event_interruptible_exclusive(cam->open, - cam->state & DEV_DISCONNECTED - || !cam->users); - if (err) { - up_read(&et61x251_disconnect); - return err; - } - if (cam->state & DEV_DISCONNECTED) { - up_read(&et61x251_disconnect); - return -ENODEV; - } - mutex_lock(&cam->dev_mutex); - } - - - if (cam->state & DEV_MISCONFIGURED) { - err = et61x251_init(cam); - if (err) { - DBG(1, "Initialization failed again. " - "I will retry on next open()."); - goto out; - } - cam->state &= ~DEV_MISCONFIGURED; - } - - if ((err = et61x251_start_transfer(cam))) - goto out; - - filp->private_data = cam; - cam->users++; - cam->io = IO_NONE; - cam->stream = STREAM_OFF; - cam->nbuffers = 0; - cam->frame_count = 0; - et61x251_empty_framequeues(cam); - - DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); - -out: - mutex_unlock(&cam->dev_mutex); - up_read(&et61x251_disconnect); - return err; -} - - -static int et61x251_release(struct inode* inode, struct file* filp) -{ - struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); - - mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ - - et61x251_stop_transfer(cam); - - et61x251_release_buffers(cam); - - if (cam->state & DEV_DISCONNECTED) { - et61x251_release_resources(cam); - mutex_unlock(&cam->dev_mutex); - kfree(cam); - return 0; - } - - cam->users--; - wake_up_interruptible_nr(&cam->open, 1); - - DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); - - mutex_unlock(&cam->dev_mutex); - - return 0; -} - - -static ssize_t -et61x251_read(struct file* filp, char __user * buf, - size_t count, loff_t* f_pos) -{ - struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); - struct et61x251_frame_t* f, * i; - unsigned long lock_flags; - long timeout; - int err = 0; - - if (mutex_lock_interruptible(&cam->fileop_mutex)) - return -ERESTARTSYS; - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); - return -ENODEV; - } - - if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it " - "again."); - mutex_unlock(&cam->fileop_mutex); - return -EIO; - } - - if (cam->io == IO_MMAP) { - DBG(3, "Close and open the device again to choose the read " - "method"); - mutex_unlock(&cam->fileop_mutex); - return -EINVAL; - } - - if (cam->io == IO_NONE) { - if (!et61x251_request_buffers(cam, cam->nreadbuffers, - IO_READ)) { - DBG(1, "read() failed, not enough memory"); - mutex_unlock(&cam->fileop_mutex); - return -ENOMEM; - } - cam->io = IO_READ; - cam->stream = STREAM_ON; - } - - if (list_empty(&cam->inqueue)) { - if (!list_empty(&cam->outqueue)) - et61x251_empty_framequeues(cam); - et61x251_queue_unusedframes(cam); - } - - if (!count) { - mutex_unlock(&cam->fileop_mutex); - return 0; - } - - if (list_empty(&cam->outqueue)) { - if (filp->f_flags & O_NONBLOCK) { - mutex_unlock(&cam->fileop_mutex); - return -EAGAIN; - } - timeout = wait_event_interruptible_timeout - ( cam->wait_frame, - (!list_empty(&cam->outqueue)) || - (cam->state & DEV_DISCONNECTED) || - (cam->state & DEV_MISCONFIGURED), - cam->module_param.frame_timeout * - 1000 * msecs_to_jiffies(1) ); - if (timeout < 0) { - mutex_unlock(&cam->fileop_mutex); - return timeout; - } - if (cam->state & DEV_DISCONNECTED) { - mutex_unlock(&cam->fileop_mutex); - return -ENODEV; - } - if (!timeout || (cam->state & DEV_MISCONFIGURED)) { - mutex_unlock(&cam->fileop_mutex); - return -EIO; - } - } - - f = list_entry(cam->outqueue.prev, struct et61x251_frame_t, frame); - - if (count > f->buf.bytesused) - count = f->buf.bytesused; - - if (copy_to_user(buf, f->bufmem, count)) { - err = -EFAULT; - goto exit; - } - *f_pos += count; - -exit: - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_for_each_entry(i, &cam->outqueue, frame) - i->state = F_UNUSED; - INIT_LIST_HEAD(&cam->outqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - - et61x251_queue_unusedframes(cam); - - PDBGG("Frame #%lu, bytes read: %zu", - (unsigned long)f->buf.index, count); - - mutex_unlock(&cam->fileop_mutex); - - return err ? err : count; -} - - -static unsigned int et61x251_poll(struct file *filp, poll_table *wait) -{ - struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); - struct et61x251_frame_t* f; - unsigned long lock_flags; - unsigned int mask = 0; - - if (mutex_lock_interruptible(&cam->fileop_mutex)) - return POLLERR; - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - goto error; - } - - if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it " - "again."); - goto error; - } - - if (cam->io == IO_NONE) { - if (!et61x251_request_buffers(cam, cam->nreadbuffers, - IO_READ)) { - DBG(1, "poll() failed, not enough memory"); - goto error; - } - cam->io = IO_READ; - cam->stream = STREAM_ON; - } - - if (cam->io == IO_READ) { - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_for_each_entry(f, &cam->outqueue, frame) - f->state = F_UNUSED; - INIT_LIST_HEAD(&cam->outqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - et61x251_queue_unusedframes(cam); - } - - poll_wait(filp, &cam->wait_frame, wait); - - if (!list_empty(&cam->outqueue)) - mask |= POLLIN | POLLRDNORM; - - mutex_unlock(&cam->fileop_mutex); - - return mask; - -error: - mutex_unlock(&cam->fileop_mutex); - return POLLERR; -} - - -static void et61x251_vm_open(struct vm_area_struct* vma) -{ - struct et61x251_frame_t* f = vma->vm_private_data; - f->vma_use_count++; -} - - -static void et61x251_vm_close(struct vm_area_struct* vma) -{ - /* NOTE: buffers are not freed here */ - struct et61x251_frame_t* f = vma->vm_private_data; - f->vma_use_count--; -} - - -static struct vm_operations_struct et61x251_vm_ops = { - .open = et61x251_vm_open, - .close = et61x251_vm_close, -}; - - -static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) -{ - struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); - unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start; - void *pos; - u32 i; - - if (mutex_lock_interruptible(&cam->fileop_mutex)) - return -ERESTARTSYS; - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); - return -ENODEV; - } - - if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it " - "again."); - mutex_unlock(&cam->fileop_mutex); - return -EIO; - } - - if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || - size != PAGE_ALIGN(cam->frame[0].buf.length)) { - mutex_unlock(&cam->fileop_mutex); - return -EINVAL; - } - - for (i = 0; i < cam->nbuffers; i++) { - if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff) - break; - } - if (i == cam->nbuffers) { - mutex_unlock(&cam->fileop_mutex); - return -EINVAL; - } - - vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; - - pos = cam->frame[i].bufmem; - while (size > 0) { /* size is page-aligned */ - if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { - mutex_unlock(&cam->fileop_mutex); - return -EAGAIN; - } - start += PAGE_SIZE; - pos += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vma->vm_ops = &et61x251_vm_ops; - vma->vm_private_data = &cam->frame[i]; - - et61x251_vm_open(vma); - - mutex_unlock(&cam->fileop_mutex); - - return 0; -} - -/*****************************************************************************/ - -static int -et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_capability cap = { - .driver = "et61x251", - .version = ET61X251_MODULE_VERSION_CODE, - .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING, - }; - - strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); - if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) - strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, - sizeof(cap.bus_info)); - - if (copy_to_user(arg, &cap, sizeof(cap))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_input i; - - if (copy_from_user(&i, arg, sizeof(i))) - return -EFAULT; - - if (i.index) - return -EINVAL; - - memset(&i, 0, sizeof(i)); - strcpy(i.name, "Camera"); - i.type = V4L2_INPUT_TYPE_CAMERA; - - if (copy_to_user(arg, &i, sizeof(i))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_g_input(struct et61x251_device* cam, void __user * arg) -{ - int index = 0; - - if (copy_to_user(arg, &index, sizeof(index))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_s_input(struct et61x251_device* cam, void __user * arg) -{ - int index; - - if (copy_from_user(&index, arg, sizeof(index))) - return -EFAULT; - - if (index != 0) - return -EINVAL; - - return 0; -} - - -static int -et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg) -{ - struct et61x251_sensor* s = &cam->sensor; - struct v4l2_queryctrl qc; - u8 i; - - if (copy_from_user(&qc, arg, sizeof(qc))) - return -EFAULT; - - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (qc.id && qc.id == s->qctrl[i].id) { - memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); - if (copy_to_user(arg, &qc, sizeof(qc))) - return -EFAULT; - return 0; - } - - return -EINVAL; -} - - -static int -et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg) -{ - struct et61x251_sensor* s = &cam->sensor; - struct v4l2_control ctrl; - int err = 0; - u8 i; - - if (!s->get_ctrl && !s->set_ctrl) - return -EINVAL; - - if (copy_from_user(&ctrl, arg, sizeof(ctrl))) - return -EFAULT; - - if (!s->get_ctrl) { - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (ctrl.id == s->qctrl[i].id) { - ctrl.value = s->_qctrl[i].default_value; - goto exit; - } - return -EINVAL; - } else - err = s->get_ctrl(cam, &ctrl); - -exit: - if (copy_to_user(arg, &ctrl, sizeof(ctrl))) - return -EFAULT; - - return err; -} - - -static int -et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg) -{ - struct et61x251_sensor* s = &cam->sensor; - struct v4l2_control ctrl; - u8 i; - int err = 0; - - if (!s->set_ctrl) - return -EINVAL; - - if (copy_from_user(&ctrl, arg, sizeof(ctrl))) - return -EFAULT; - - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (ctrl.id == s->qctrl[i].id) { - if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) - return -EINVAL; - if (ctrl.value < s->qctrl[i].minimum || - ctrl.value > s->qctrl[i].maximum) - return -ERANGE; - ctrl.value -= ctrl.value % s->qctrl[i].step; - break; - } - - if ((err = s->set_ctrl(cam, &ctrl))) - return err; - - s->_qctrl[i].default_value = ctrl.value; - - return 0; -} - - -static int -et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_cropcap* cc = &(cam->sensor.cropcap); - - cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cc->pixelaspect.numerator = 1; - cc->pixelaspect.denominator = 1; - - if (copy_to_user(arg, cc, sizeof(*cc))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg) -{ - struct et61x251_sensor* s = &cam->sensor; - struct v4l2_crop crop = { - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - }; - - memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect)); - - if (copy_to_user(arg, &crop, sizeof(crop))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) -{ - struct et61x251_sensor* s = &cam->sensor; - struct v4l2_crop crop; - struct v4l2_rect* rect; - struct v4l2_rect* bounds = &(s->cropcap.bounds); - struct v4l2_pix_format* pix_format = &(s->pix_format); - u8 scale; - const enum et61x251_stream_state stream = cam->stream; - const u32 nbuffers = cam->nbuffers; - u32 i; - int err = 0; - - if (copy_from_user(&crop, arg, sizeof(crop))) - return -EFAULT; - - rect = &(crop.c); - - if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (cam->module_param.force_munmap) - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_S_CROP failed. " - "Unmap the buffers first."); - return -EINVAL; - } - - /* Preserve R,G or B origin */ - rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L; - rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L; - - if (rect->width < 4) - rect->width = 4; - if (rect->height < 4) - rect->height = 4; - if (rect->width > bounds->width) - rect->width = bounds->width; - if (rect->height > bounds->height) - rect->height = bounds->height; - if (rect->left < bounds->left) - rect->left = bounds->left; - if (rect->top < bounds->top) - rect->top = bounds->top; - if (rect->left + rect->width > bounds->left + bounds->width) - rect->left = bounds->left+bounds->width - rect->width; - if (rect->top + rect->height > bounds->top + bounds->height) - rect->top = bounds->top+bounds->height - rect->height; - - rect->width &= ~3L; - rect->height &= ~3L; - - if (ET61X251_PRESERVE_IMGSCALE) { - /* Calculate the actual scaling factor */ - u32 a, b; - a = rect->width * rect->height; - b = pix_format->width * pix_format->height; - scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1; - } else - scale = 1; - - if (cam->stream == STREAM_ON) - if ((err = et61x251_stream_interrupt(cam))) - return err; - - if (copy_to_user(arg, &crop, sizeof(crop))) { - cam->stream = stream; - return -EFAULT; - } - - if (cam->module_param.force_munmap || cam->io == IO_READ) - et61x251_release_buffers(cam); - - err = et61x251_set_crop(cam, rect); - if (s->set_crop) - err += s->set_crop(cam, rect); - err += et61x251_set_scale(cam, scale); - - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -EIO; - } - - s->pix_format.width = rect->width/scale; - s->pix_format.height = rect->height/scale; - memcpy(&(s->_rect), rect, sizeof(*rect)); - - if ((cam->module_param.force_munmap || cam->io == IO_READ) && - nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -ENOMEM; - } - - if (cam->io == IO_READ) - et61x251_empty_framequeues(cam); - else if (cam->module_param.force_munmap) - et61x251_requeue_outqueue(cam); - - cam->stream = stream; - - return 0; -} - - -static int -et61x251_vidioc_enum_fmt(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_fmtdesc fmtd; - - if (copy_from_user(&fmtd, arg, sizeof(fmtd))) - return -EFAULT; - - if (fmtd.index == 0) { - strcpy(fmtd.description, "bayer rgb"); - fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8; - } else if (fmtd.index == 1) { - strcpy(fmtd.description, "compressed"); - fmtd.pixelformat = V4L2_PIX_FMT_ET61X251; - fmtd.flags = V4L2_FMT_FLAG_COMPRESSED; - } else - return -EINVAL; - - fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memset(&fmtd.reserved, 0, sizeof(fmtd.reserved)); - - if (copy_to_user(arg, &fmtd, sizeof(fmtd))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_format format; - struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); - - if (copy_from_user(&format, arg, sizeof(format))) - return -EFAULT; - - if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251) - ? 0 : (pfmt->width * pfmt->priv) / 8; - pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); - pfmt->field = V4L2_FIELD_NONE; - memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt)); - - if (copy_to_user(arg, &format, sizeof(format))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, - void __user * arg) -{ - struct et61x251_sensor* s = &cam->sensor; - struct v4l2_format format; - struct v4l2_pix_format* pix; - struct v4l2_pix_format* pfmt = &(s->pix_format); - struct v4l2_rect* bounds = &(s->cropcap.bounds); - struct v4l2_rect rect; - u8 scale; - const enum et61x251_stream_state stream = cam->stream; - const u32 nbuffers = cam->nbuffers; - u32 i; - int err = 0; - - if (copy_from_user(&format, arg, sizeof(format))) - return -EFAULT; - - pix = &(format.fmt.pix); - - if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - memcpy(&rect, &(s->_rect), sizeof(rect)); - - { /* calculate the actual scaling factor */ - u32 a, b; - a = rect.width * rect.height; - b = pix->width * pix->height; - scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1; - } - - rect.width = scale * pix->width; - rect.height = scale * pix->height; - - if (rect.width < 4) - rect.width = 4; - if (rect.height < 4) - rect.height = 4; - if (rect.width > bounds->left + bounds->width - rect.left) - rect.width = bounds->left + bounds->width - rect.left; - if (rect.height > bounds->top + bounds->height - rect.top) - rect.height = bounds->top + bounds->height - rect.top; - - rect.width &= ~3L; - rect.height &= ~3L; - - { /* adjust the scaling factor */ - u32 a, b; - a = rect.width * rect.height; - b = pix->width * pix->height; - scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1; - } - - pix->width = rect.width / scale; - pix->height = rect.height / scale; - - if (pix->pixelformat != V4L2_PIX_FMT_ET61X251 && - pix->pixelformat != V4L2_PIX_FMT_SBGGR8) - pix->pixelformat = pfmt->pixelformat; - pix->priv = pfmt->priv; /* bpp */ - pix->colorspace = pfmt->colorspace; - pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251) - ? 0 : (pix->width * pix->priv) / 8; - pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8); - pix->field = V4L2_FIELD_NONE; - - if (cmd == VIDIOC_TRY_FMT) { - if (copy_to_user(arg, &format, sizeof(format))) - return -EFAULT; - return 0; - } - - if (cam->module_param.force_munmap) - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_S_FMT failed. " - "Unmap the buffers first."); - return -EINVAL; - } - - if (cam->stream == STREAM_ON) - if ((err = et61x251_stream_interrupt(cam))) - return err; - - if (copy_to_user(arg, &format, sizeof(format))) { - cam->stream = stream; - return -EFAULT; - } - - if (cam->module_param.force_munmap || cam->io == IO_READ) - et61x251_release_buffers(cam); - - err += et61x251_set_pix_format(cam, pix); - err += et61x251_set_crop(cam, &rect); - if (s->set_pix_format) - err += s->set_pix_format(cam, pix); - if (s->set_crop) - err += s->set_crop(cam, &rect); - err += et61x251_set_scale(cam, scale); - - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -EIO; - } - - memcpy(pfmt, pix, sizeof(*pix)); - memcpy(&(s->_rect), &rect, sizeof(rect)); - - if ((cam->module_param.force_munmap || cam->io == IO_READ) && - nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -ENOMEM; - } - - if (cam->io == IO_READ) - et61x251_empty_framequeues(cam); - else if (cam->module_param.force_munmap) - et61x251_requeue_outqueue(cam); - - cam->stream = stream; - - return 0; -} - - -static int -et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg) -{ - if (copy_to_user(arg, &cam->compression, - sizeof(cam->compression))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_jpegcompression jc; - const enum et61x251_stream_state stream = cam->stream; - int err = 0; - - if (copy_from_user(&jc, arg, sizeof(jc))) - return -EFAULT; - - if (jc.quality != 0 && jc.quality != 1) - return -EINVAL; - - if (cam->stream == STREAM_ON) - if ((err = et61x251_stream_interrupt(cam))) - return err; - - err += et61x251_set_compression(cam, &jc); - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " - "problems. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->minor); - return -EIO; - } - - cam->compression.quality = jc.quality; - - cam->stream = stream; - - return 0; -} - - -static int -et61x251_vidioc_reqbufs(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_requestbuffers rb; - u32 i; - int err; - - if (copy_from_user(&rb, arg, sizeof(rb))) - return -EFAULT; - - if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - rb.memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - if (cam->io == IO_READ) { - DBG(3, "Close and open the device again to choose the mmap " - "I/O method"); - return -EINVAL; - } - - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_REQBUFS failed. " - "Previous buffers are still mapped."); - return -EINVAL; - } - - if (cam->stream == STREAM_ON) - if ((err = et61x251_stream_interrupt(cam))) - return err; - - et61x251_empty_framequeues(cam); - - et61x251_release_buffers(cam); - if (rb.count) - rb.count = et61x251_request_buffers(cam, rb.count, IO_MMAP); - - if (copy_to_user(arg, &rb, sizeof(rb))) { - et61x251_release_buffers(cam); - cam->io = IO_NONE; - return -EFAULT; - } - - cam->io = rb.count ? IO_MMAP : IO_NONE; - - return 0; -} - - -static int -et61x251_vidioc_querybuf(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_buffer b; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b.index >= cam->nbuffers || cam->io != IO_MMAP) - return -EINVAL; - - memcpy(&b, &cam->frame[b.index].buf, sizeof(b)); - - if (cam->frame[b.index].vma_use_count) - b.flags |= V4L2_BUF_FLAG_MAPPED; - - if (cam->frame[b.index].state == F_DONE) - b.flags |= V4L2_BUF_FLAG_DONE; - else if (cam->frame[b.index].state != F_UNUSED) - b.flags |= V4L2_BUF_FLAG_QUEUED; - - if (copy_to_user(arg, &b, sizeof(b))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_qbuf(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_buffer b; - unsigned long lock_flags; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b.index >= cam->nbuffers || cam->io != IO_MMAP) - return -EINVAL; - - if (cam->frame[b.index].state != F_UNUSED) - return -EINVAL; - - cam->frame[b.index].state = F_QUEUED; - - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_add_tail(&cam->frame[b.index].frame, &cam->inqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - - PDBGG("Frame #%lu queued", (unsigned long)b.index); - - return 0; -} - - -static int -et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp, - void __user * arg) -{ - struct v4l2_buffer b; - struct et61x251_frame_t *f; - unsigned long lock_flags; - long timeout; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP) - return -EINVAL; - - if (list_empty(&cam->outqueue)) { - if (cam->stream == STREAM_OFF) - return -EINVAL; - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - timeout = wait_event_interruptible_timeout - ( cam->wait_frame, - (!list_empty(&cam->outqueue)) || - (cam->state & DEV_DISCONNECTED) || - (cam->state & DEV_MISCONFIGURED), - cam->module_param.frame_timeout * - 1000 * msecs_to_jiffies(1) ); - if (timeout < 0) - return timeout; - if (cam->state & DEV_DISCONNECTED) - return -ENODEV; - if (!timeout || (cam->state & DEV_MISCONFIGURED)) - return -EIO; - } - - spin_lock_irqsave(&cam->queue_lock, lock_flags); - f = list_entry(cam->outqueue.next, struct et61x251_frame_t, frame); - list_del(cam->outqueue.next); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - - f->state = F_UNUSED; - - memcpy(&b, &f->buf, sizeof(b)); - if (f->vma_use_count) - b.flags |= V4L2_BUF_FLAG_MAPPED; - - if (copy_to_user(arg, &b, sizeof(b))) - return -EFAULT; - - PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index); - - return 0; -} - - -static int -et61x251_vidioc_streamon(struct et61x251_device* cam, void __user * arg) -{ - int type; - - if (copy_from_user(&type, arg, sizeof(type))) - return -EFAULT; - - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) - return -EINVAL; - - if (list_empty(&cam->inqueue)) - return -EINVAL; - - cam->stream = STREAM_ON; - - DBG(3, "Stream on"); - - return 0; -} - - -static int -et61x251_vidioc_streamoff(struct et61x251_device* cam, void __user * arg) -{ - int type, err; - - if (copy_from_user(&type, arg, sizeof(type))) - return -EFAULT; - - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) - return -EINVAL; - - if (cam->stream == STREAM_ON) - if ((err = et61x251_stream_interrupt(cam))) - return err; - - et61x251_empty_framequeues(cam); - - DBG(3, "Stream off"); - - return 0; -} - - -static int -et61x251_vidioc_g_parm(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_streamparm sp; - - if (copy_from_user(&sp, arg, sizeof(sp))) - return -EFAULT; - - if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - sp.parm.capture.extendedmode = 0; - sp.parm.capture.readbuffers = cam->nreadbuffers; - - if (copy_to_user(arg, &sp, sizeof(sp))) - return -EFAULT; - - return 0; -} - - -static int -et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg) -{ - struct v4l2_streamparm sp; - - if (copy_from_user(&sp, arg, sizeof(sp))) - return -EFAULT; - - if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - sp.parm.capture.extendedmode = 0; - - if (sp.parm.capture.readbuffers == 0) - sp.parm.capture.readbuffers = cam->nreadbuffers; - - if (sp.parm.capture.readbuffers > ET61X251_MAX_FRAMES) - sp.parm.capture.readbuffers = ET61X251_MAX_FRAMES; - - if (copy_to_user(arg, &sp, sizeof(sp))) - return -EFAULT; - - cam->nreadbuffers = sp.parm.capture.readbuffers; - - return 0; -} - - -static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, - unsigned int cmd, void __user * arg) -{ - struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); - - switch (cmd) { - - case VIDIOC_QUERYCAP: - return et61x251_vidioc_querycap(cam, arg); - - case VIDIOC_ENUMINPUT: - return et61x251_vidioc_enuminput(cam, arg); - - case VIDIOC_G_INPUT: - return et61x251_vidioc_g_input(cam, arg); - - case VIDIOC_S_INPUT: - return et61x251_vidioc_s_input(cam, arg); - - case VIDIOC_QUERYCTRL: - return et61x251_vidioc_query_ctrl(cam, arg); - - case VIDIOC_G_CTRL: - return et61x251_vidioc_g_ctrl(cam, arg); - - case VIDIOC_S_CTRL_OLD: - case VIDIOC_S_CTRL: - return et61x251_vidioc_s_ctrl(cam, arg); - - case VIDIOC_CROPCAP_OLD: - case VIDIOC_CROPCAP: - return et61x251_vidioc_cropcap(cam, arg); - - case VIDIOC_G_CROP: - return et61x251_vidioc_g_crop(cam, arg); - - case VIDIOC_S_CROP: - return et61x251_vidioc_s_crop(cam, arg); - - case VIDIOC_ENUM_FMT: - return et61x251_vidioc_enum_fmt(cam, arg); - - case VIDIOC_G_FMT: - return et61x251_vidioc_g_fmt(cam, arg); - - case VIDIOC_TRY_FMT: - case VIDIOC_S_FMT: - return et61x251_vidioc_try_s_fmt(cam, cmd, arg); - - case VIDIOC_G_JPEGCOMP: - return et61x251_vidioc_g_jpegcomp(cam, arg); - - case VIDIOC_S_JPEGCOMP: - return et61x251_vidioc_s_jpegcomp(cam, arg); - - case VIDIOC_REQBUFS: - return et61x251_vidioc_reqbufs(cam, arg); - - case VIDIOC_QUERYBUF: - return et61x251_vidioc_querybuf(cam, arg); - - case VIDIOC_QBUF: - return et61x251_vidioc_qbuf(cam, arg); - - case VIDIOC_DQBUF: - return et61x251_vidioc_dqbuf(cam, filp, arg); - - case VIDIOC_STREAMON: - return et61x251_vidioc_streamon(cam, arg); - - case VIDIOC_STREAMOFF: - return et61x251_vidioc_streamoff(cam, arg); - - case VIDIOC_G_PARM: - return et61x251_vidioc_g_parm(cam, arg); - - case VIDIOC_S_PARM_OLD: - case VIDIOC_S_PARM: - return et61x251_vidioc_s_parm(cam, arg); - - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case VIDIOC_QUERYSTD: - case VIDIOC_ENUMSTD: - case VIDIOC_QUERYMENU: - return -EINVAL; - - default: - return -EINVAL; - - } -} - - -static int et61x251_ioctl(struct inode* inode, struct file* filp, - unsigned int cmd, unsigned long arg) -{ - struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); - int err = 0; - - if (mutex_lock_interruptible(&cam->fileop_mutex)) - return -ERESTARTSYS; - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); - return -ENODEV; - } - - if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it " - "again."); - mutex_unlock(&cam->fileop_mutex); - return -EIO; - } - - V4LDBG(3, "et61x251", cmd); - - err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); - - mutex_unlock(&cam->fileop_mutex); - - return err; -} - - -static struct file_operations et61x251_fops = { - .owner = THIS_MODULE, - .open = et61x251_open, - .release = et61x251_release, - .ioctl = et61x251_ioctl, - .read = et61x251_read, - .poll = et61x251_poll, - .mmap = et61x251_mmap, - .llseek = no_llseek, -}; - -/*****************************************************************************/ - -/* It exists a single interface only. We do not need to validate anything. */ -static int -et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct et61x251_device* cam; - static unsigned int dev_nr = 0; - unsigned int i; - int err = 0; - - if (!(cam = kzalloc(sizeof(struct et61x251_device), GFP_KERNEL))) - return -ENOMEM; - - cam->usbdev = udev; - - if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) { - DBG(1, "kmalloc() failed"); - err = -ENOMEM; - goto fail; - } - - if (!(cam->v4ldev = video_device_alloc())) { - DBG(1, "video_device_alloc() failed"); - err = -ENOMEM; - goto fail; - } - - mutex_init(&cam->dev_mutex); - - DBG(2, "ET61X[12]51 PC Camera Controller detected " - "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); - - for (i = 0; et61x251_sensor_table[i]; i++) { - err = et61x251_sensor_table[i](cam); - if (!err) - break; - } - - if (!err) - DBG(2, "%s image sensor detected", cam->sensor.name); - else { - DBG(1, "No supported image sensor detected"); - err = -ENODEV; - goto fail; - } - - if (et61x251_init(cam)) { - DBG(1, "Initialization failed. I will retry on open()."); - cam->state |= DEV_MISCONFIGURED; - } - - strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); - cam->v4ldev->owner = THIS_MODULE; - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; - cam->v4ldev->hardware = 0; - cam->v4ldev->fops = &et61x251_fops; - cam->v4ldev->minor = video_nr[dev_nr]; - cam->v4ldev->release = video_device_release; - video_set_drvdata(cam->v4ldev, cam); - - mutex_lock(&cam->dev_mutex); - - err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, - video_nr[dev_nr]); - if (err) { - DBG(1, "V4L2 device registration failed"); - if (err == -ENFILE && video_nr[dev_nr] == -1) - DBG(1, "Free /dev/videoX node not found"); - video_nr[dev_nr] = -1; - dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; - mutex_unlock(&cam->dev_mutex); - goto fail; - } - - DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); - - cam->module_param.force_munmap = force_munmap[dev_nr]; - cam->module_param.frame_timeout = frame_timeout[dev_nr]; - - dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; - -#ifdef CONFIG_VIDEO_ADV_DEBUG - et61x251_create_sysfs(cam); - DBG(2, "Optional device control through 'sysfs' interface ready"); -#endif - - usb_set_intfdata(intf, cam); - - mutex_unlock(&cam->dev_mutex); - - return 0; - -fail: - if (cam) { - kfree(cam->control_buffer); - if (cam->v4ldev) - video_device_release(cam->v4ldev); - kfree(cam); - } - return err; -} - - -static void et61x251_usb_disconnect(struct usb_interface* intf) -{ - struct et61x251_device* cam = usb_get_intfdata(intf); - - if (!cam) - return; - - down_write(&et61x251_disconnect); - - mutex_lock(&cam->dev_mutex); - - DBG(2, "Disconnecting %s...", cam->v4ldev->name); - - wake_up_interruptible_all(&cam->open); - - if (cam->users) { - DBG(2, "Device /dev/video%d is open! Deregistration and " - "memory deallocation are deferred on close.", - cam->v4ldev->minor); - cam->state |= DEV_MISCONFIGURED; - et61x251_stop_transfer(cam); - cam->state |= DEV_DISCONNECTED; - wake_up_interruptible(&cam->wait_frame); - wake_up(&cam->wait_stream); - usb_get_dev(cam->usbdev); - } else { - cam->state |= DEV_DISCONNECTED; - et61x251_release_resources(cam); - } - - mutex_unlock(&cam->dev_mutex); - - if (!cam->users) - kfree(cam); - - up_write(&et61x251_disconnect); -} - - -static struct usb_driver et61x251_usb_driver = { - .name = "et61x251", - .id_table = et61x251_id_table, - .probe = et61x251_usb_probe, - .disconnect = et61x251_usb_disconnect, -}; - -/*****************************************************************************/ - -static int __init et61x251_module_init(void) -{ - int err = 0; - - KDBG(2, ET61X251_MODULE_NAME " v" ET61X251_MODULE_VERSION); - KDBG(3, ET61X251_MODULE_AUTHOR); - - if ((err = usb_register(&et61x251_usb_driver))) - KDBG(1, "usb_register() failed"); - - return err; -} - - -static void __exit et61x251_module_exit(void) -{ - usb_deregister(&et61x251_usb_driver); -} - - -module_init(et61x251_module_init); -module_exit(et61x251_module_exit); diff --git a/drivers/media/video/et61x251/et61x251_sensor.h b/drivers/media/video/et61x251/et61x251_sensor.h deleted file mode 100644 index 65edd08dc..000000000 --- a/drivers/media/video/et61x251/et61x251_sensor.h +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** - * API for image sensors connected to ET61X[12]51 PC Camera Controllers * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 _ET61X251_SENSOR_H_ -#define _ET61X251_SENSOR_H_ - -#include -#include -#include -#include -#include -#include - -struct et61x251_device; -struct et61x251_sensor; - -/*****************************************************************************/ - -extern int et61x251_probe_tas5130d1b(struct et61x251_device* cam); - -#define ET61X251_SENSOR_TABLE \ -/* Weak detections must go at the end of the list */ \ -static int (*et61x251_sensor_table[])(struct et61x251_device*) = { \ - &et61x251_probe_tas5130d1b, \ - NULL, \ -}; - -extern struct et61x251_device* -et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id); - -extern void -et61x251_attach_sensor(struct et61x251_device* cam, - struct et61x251_sensor* sensor); - -/*****************************************************************************/ - -extern int et61x251_write_reg(struct et61x251_device*, u8 value, u16 index); -extern int et61x251_read_reg(struct et61x251_device*, u16 index); -extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value); -extern int et61x251_i2c_read(struct et61x251_device*, u8 address); -extern int et61x251_i2c_try_write(struct et61x251_device*, - struct et61x251_sensor*, u8 address, - u8 value); -extern int et61x251_i2c_try_read(struct et61x251_device*, - struct et61x251_sensor*, u8 address); -extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1, - u8 data2, u8 data3, u8 data4, u8 data5, - u8 data6, u8 data7, u8 data8, u8 address); - -/*****************************************************************************/ - -enum et61x251_i2c_sysfs_ops { - ET61X251_I2C_READ = 0x01, - ET61X251_I2C_WRITE = 0x02, -}; - -enum et61x251_i2c_interface { - ET61X251_I2C_2WIRES, - ET61X251_I2C_3WIRES, -}; - -/* Repeat start condition when RSTA is high */ -enum et61x251_i2c_rsta { - ET61X251_I2C_RSTA_STOP = 0x00, /* stop then start */ - ET61X251_I2C_RSTA_REPEAT = 0x01, /* repeat start */ -}; - -#define ET61X251_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10 - -struct et61x251_sensor { - char name[32]; - - enum et61x251_i2c_sysfs_ops sysfs_ops; - - enum et61x251_i2c_interface interface; - u8 i2c_slave_id; - enum et61x251_i2c_rsta rsta; - struct v4l2_rect active_pixel; /* left and top define FVSX and FVSY */ - - struct v4l2_queryctrl qctrl[ET61X251_MAX_CTRLS]; - struct v4l2_cropcap cropcap; - struct v4l2_pix_format pix_format; - - int (*init)(struct et61x251_device* cam); - int (*get_ctrl)(struct et61x251_device* cam, - struct v4l2_control* ctrl); - int (*set_ctrl)(struct et61x251_device* cam, - const struct v4l2_control* ctrl); - int (*set_crop)(struct et61x251_device* cam, - const struct v4l2_rect* rect); - int (*set_pix_format)(struct et61x251_device* cam, - const struct v4l2_pix_format* pix); - - /* Private */ - struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS]; - struct v4l2_rect _rect; -}; - -#endif /* _ET61X251_SENSOR_H_ */ diff --git a/drivers/media/video/et61x251/et61x251_tas5130d1b.c b/drivers/media/video/et61x251/et61x251_tas5130d1b.c deleted file mode 100644 index a7d65b82b..000000000 --- a/drivers/media/video/et61x251/et61x251_tas5130d1b.c +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************** - * Plug-in for TAS5130D1B image sensor connected to the ET61X[12]51 * - * PC Camera Controllers * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 "et61x251_sensor.h" - - -static int tas5130d1b_init(struct et61x251_device* cam) -{ - int err = 0; - - err += et61x251_write_reg(cam, 0x14, 0x01); - err += et61x251_write_reg(cam, 0x1b, 0x02); - err += et61x251_write_reg(cam, 0x02, 0x12); - err += et61x251_write_reg(cam, 0x0e, 0x60); - err += et61x251_write_reg(cam, 0x80, 0x61); - err += et61x251_write_reg(cam, 0xf0, 0x62); - err += et61x251_write_reg(cam, 0x03, 0x63); - err += et61x251_write_reg(cam, 0x14, 0x64); - err += et61x251_write_reg(cam, 0xf4, 0x65); - err += et61x251_write_reg(cam, 0x01, 0x66); - err += et61x251_write_reg(cam, 0x05, 0x67); - err += et61x251_write_reg(cam, 0x8f, 0x68); - err += et61x251_write_reg(cam, 0x0f, 0x8d); - err += et61x251_write_reg(cam, 0x08, 0x8e); - - return err; -} - - -static int tas5130d1b_set_ctrl(struct et61x251_device* cam, - const struct v4l2_control* ctrl) -{ - int err = 0; - - switch (ctrl->id) { - case V4L2_CID_GAIN: - err += et61x251_i2c_raw_write(cam, 2, 0x20, - 0xf6-ctrl->value, 0, 0, 0, - 0, 0, 0, 0); - break; - case V4L2_CID_EXPOSURE: - err += et61x251_i2c_raw_write(cam, 2, 0x40, - 0x47-ctrl->value, 0, 0, 0, - 0, 0, 0, 0); - break; - default: - return -EINVAL; - } - - return err ? -EIO : 0; -} - - -static struct et61x251_sensor tas5130d1b = { - .name = "TAS5130D1B", - .interface = ET61X251_I2C_3WIRES, - .rsta = ET61X251_I2C_RSTA_STOP, - .active_pixel = { - .left = 106, - .top = 13, - }, - .init = &tas5130d1b_init, - .qctrl = { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "global gain", - .minimum = 0x00, - .maximum = 0xf6, - .step = 0x02, - .default_value = 0x0d, - .flags = 0, - }, - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0x47, - .step = 0x01, - .default_value = 0x23, - .flags = 0, - }, - }, - .set_ctrl = &tas5130d1b_set_ctrl, - .cropcap = { - .bounds = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - .defrect = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - }, - .pix_format = { - .width = 640, - .height = 480, - .pixelformat = V4L2_PIX_FMT_SBGGR8, - .priv = 8, - }, -}; - - -int et61x251_probe_tas5130d1b(struct et61x251_device* cam) -{ - const struct usb_device_id tas5130d1b_id_table[] = { - { USB_DEVICE(0x102c, 0x6251), }, - { } - }; - - /* Sensor detection is based on USB pid/vid */ - if (!et61x251_match_id(cam, tas5130d1b_id_table)) - return -ENODEV; - - et61x251_attach_sensor(cam, &tas5130d1b); - - return 0; -} diff --git a/drivers/media/video/font.h b/drivers/media/video/font.h deleted file mode 100644 index 8b1fecc37..000000000 --- a/drivers/media/video/font.h +++ /dev/null @@ -1,407 +0,0 @@ -static unsigned char rom8x16_bits[] = { -/* Character 0 (0x30): - ht=16, width=8 - +--------+ - | | - | | - | ***** | - |** ** | - |** ** | - |** *** | - |** **** | - |**** ** | - |*** ** | - |** ** | - |** ** | - | ***** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x7c, -0xc6, -0xc6, -0xce, -0xde, -0xf6, -0xe6, -0xc6, -0xc6, -0x7c, -0x00, -0x00, -0x00, -0x00, - -/* Character 1 (0x31): - ht=16, width=8 - +--------+ - | | - | | - | ** | - | **** | - | ** | - | ** | - | ** | - | ** | - | ** | - | ** | - | ** | - | ****** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x18, -0x78, -0x18, -0x18, -0x18, -0x18, -0x18, -0x18, -0x18, -0x7e, -0x00, -0x00, -0x00, -0x00, - -/* Character 2 (0x32): - ht=16, width=8 - +--------+ - | | - | | - | ***** | - |** ** | - |** ** | - | ** | - | ** | - | ** | - | ** | - | ** | - |** ** | - |******* | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x7c, -0xc6, -0xc6, -0x06, -0x0c, -0x18, -0x30, -0x60, -0xc6, -0xfe, -0x00, -0x00, -0x00, -0x00, - -/* Character 3 (0x33): - ht=16, width=8 - +--------+ - | | - | | - | ***** | - |** ** | - | ** | - | ** | - | **** | - | ** | - | ** | - | ** | - |** ** | - | ***** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x7c, -0xc6, -0x06, -0x06, -0x3c, -0x06, -0x06, -0x06, -0xc6, -0x7c, -0x00, -0x00, -0x00, -0x00, - -/* Character 4 (0x34): - ht=16, width=8 - +--------+ - | | - | | - | ** | - | *** | - | **** | - | ** ** | - |** ** | - |** ** | - |******* | - | ** | - | ** | - | **** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x0c, -0x1c, -0x3c, -0x6c, -0xcc, -0xcc, -0xfe, -0x0c, -0x0c, -0x1e, -0x00, -0x00, -0x00, -0x00, - -/* Character 5 (0x35): - ht=16, width=8 - +--------+ - | | - | | - |******* | - |** | - |** | - |** | - |****** | - | ** | - | ** | - | ** | - |** ** | - | ***** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0xfe, -0xc0, -0xc0, -0xc0, -0xfc, -0x06, -0x06, -0x06, -0xc6, -0x7c, -0x00, -0x00, -0x00, -0x00, - -/* Character 6 (0x36): - ht=16, width=8 - +--------+ - | | - | | - | ***** | - |** ** | - |** | - |** | - |****** | - |** ** | - |** ** | - |** ** | - |** ** | - | ***** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x7c, -0xc6, -0xc0, -0xc0, -0xfc, -0xc6, -0xc6, -0xc6, -0xc6, -0x7c, -0x00, -0x00, -0x00, -0x00, - -/* Character 7 (0x37): - ht=16, width=8 - +--------+ - | | - | | - |******* | - |** ** | - | ** | - | ** | - | ** | - | ** | - | ** | - | ** | - | ** | - | ** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0xfe, -0xc6, -0x06, -0x0c, -0x18, -0x30, -0x30, -0x30, -0x30, -0x30, -0x00, -0x00, -0x00, -0x00, - -/* Character 8 (0x38): - ht=16, width=8 - +--------+ - | | - | | - | ***** | - |** ** | - |** ** | - |** ** | - | ***** | - |** ** | - |** ** | - |** ** | - |** ** | - | ***** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x7c, -0xc6, -0xc6, -0xc6, -0x7c, -0xc6, -0xc6, -0xc6, -0xc6, -0x7c, -0x00, -0x00, -0x00, -0x00, - -/* Character 9 (0x39): - ht=16, width=8 - +--------+ - | | - | | - | ***** | - |** ** | - |** ** | - |** ** | - |** ** | - | ****** | - | ** | - | ** | - |** ** | - | ***** | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x7c, -0xc6, -0xc6, -0xc6, -0xc6, -0x7e, -0x06, -0x06, -0xc6, -0x7c, -0x00, -0x00, -0x00, -0x00, -/* Character : (0x3a): - ht=16, width=8 - +--------+ - | | - | | - | | - | | - | | - | ** | - | ** | - | | - | | - | ** | - | ** | - | | - | | - | | - | | - | | - +--------+ */ -0x00, -0x00, -0x00, -0x00, -0x00, -0x0c, -0x0c, -0x00, -0x00, -0x0c, -0x0c, -0x00, -0x00, -0x00, -0x00, -0x00, -}; diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index c7fed3405..e7bbeb115 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c @@ -1,9 +1,9 @@ /* hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards - + Visit http://www.mihu.de/linux/saa7146/ and follow the link to "hexium" for further details about this card. - + Copyright (C) 2003 Michael Hunold This program is free software; you can redistribute it and/or modify @@ -81,7 +81,7 @@ struct hexium struct video_device *video_dev; struct i2c_adapter i2c_adapter; - + int cur_input; /* current input */ v4l2_std_id cur_std; /* current standard */ int cur_bw; /* current black/white status */ @@ -174,7 +174,7 @@ static struct saa7146_standard hexium_standards[] = { .h_offset = 1, .h_pixels = 720, .v_max_out = 576, .h_max_out = 768, } -}; +}; /* bring hardware to a sane state. this has to be done, just in case someone wants to capture from this device before it has been properly initialized. @@ -311,7 +311,7 @@ static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) struct saa7146_dev *dev = fh->dev; struct hexium *hexium = (struct hexium *) dev->ext_priv; /* - struct saa7146_vv *vv = dev->vv_data; + struct saa7146_vv *vv = dev->vv_data; */ switch (cmd) { case VIDIOC_ENUMINPUT: diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 137c4736d..aad4a18aa 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c @@ -3,7 +3,7 @@ Visit http://www.mihu.de/linux/saa7146/ and follow the link to "hexium" for further details about this card. - + Copyright (C) 2003 Michael Hunold This program is free software; you can redistribute it and/or modify @@ -69,7 +69,7 @@ struct hexium { int type; struct video_device *video_dev; - struct i2c_adapter i2c_adapter; + struct i2c_adapter i2c_adapter; int cur_input; /* current input */ }; @@ -86,7 +86,7 @@ static u8 hexium_saa7110[53]={ }; static struct { - struct hexium_data data[8]; + struct hexium_data data[8]; } hexium_input_select[] = { { { /* cvbs 1 */ @@ -153,7 +153,7 @@ static struct { { 0x30, 0x60 }, { 0x31, 0xB5 }, // ?? { 0x21, 0x03 }, - } + } }, { { /* y/c 1 */ { 0x06, 0x80 }, @@ -187,7 +187,7 @@ static struct { { 0x31, 0x75 }, { 0x21, 0x21 }, } -} +} }; static struct saa7146_standard hexium_standards[] = { @@ -207,7 +207,7 @@ static struct saa7146_standard hexium_standards[] = { .h_offset = 1, .h_pixels = 720, .v_max_out = 576, .h_max_out = 768, } -}; +}; /* this is only called for old HV-PCI6/Orion cards without eeprom */ @@ -272,7 +272,7 @@ static int hexium_probe(struct saa7146_dev *dev) return 0; } - /* check if this is an old hexium Orion card by looking at + /* check if this is an old hexium Orion card by looking at a saa7110 at address 0x4e */ if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) { printk("hexium_orion: device is a Hexium HV-PCI6/Orion (old).\n"); @@ -314,7 +314,7 @@ static int hexium_set_input(struct hexium *hexium, int input) { union i2c_smbus_data data; int i = 0; - + DEB_D((".\n")); for (i = 0; i < 8; i++) { @@ -375,7 +375,7 @@ static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) struct saa7146_dev *dev = fh->dev; struct hexium *hexium = (struct hexium *) dev->ext_priv; /* - struct saa7146_vv *vv = dev->vv_data; + struct saa7146_vv *vv = dev->vv_data; */ switch (cmd) { case VIDIOC_ENUMINPUT: diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 7e66d83fe..58b0e6982 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -44,17 +44,51 @@ #include #include +/* Mark Phalan */ +static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { + [ 0 ] = KEY_KP0, + [ 1 ] = KEY_KP1, + [ 2 ] = KEY_KP2, + [ 3 ] = KEY_KP3, + [ 4 ] = KEY_KP4, + [ 5 ] = KEY_KP5, + [ 6 ] = KEY_KP6, + [ 7 ] = KEY_KP7, + [ 8 ] = KEY_KP8, + [ 9 ] = KEY_KP9, + + [ 18 ] = KEY_POWER, + [ 16 ] = KEY_MUTE, + [ 31 ] = KEY_VOLUMEDOWN, + [ 27 ] = KEY_VOLUMEUP, + [ 26 ] = KEY_CHANNELUP, + [ 30 ] = KEY_CHANNELDOWN, + [ 14 ] = KEY_PAGEUP, + [ 29 ] = KEY_PAGEDOWN, + [ 19 ] = KEY_SOUND, + + [ 24 ] = KEY_KPPLUSMINUS, /* CH +/- */ + [ 22 ] = KEY_SUBTITLE, /* CC */ + [ 13 ] = KEY_TEXT, /* TTX */ + [ 11 ] = KEY_TV, /* AIR/CBL */ + [ 17 ] = KEY_PC, /* PC/TV */ + [ 23 ] = KEY_OK, /* CH RTN */ + [ 25 ] = KEY_MODE, /* FUNC */ + [ 12 ] = KEY_SEARCH, /* AUTOSCAN */ + + /* Not sure what to do with these ones! */ + [ 15 ] = KEY_SELECT, /* SOURCE */ + [ 10 ] = KEY_KPPLUS, /* +100 */ + [ 20 ] = KEY_KPEQUAL, /* SYNC */ + [ 28 ] = KEY_MEDIA, /* PC/TV */ +}; + /* ----------------------------------------------------------------------- */ /* insmod parameters */ static int debug; module_param(debug, int, 0644); /* debug level (0,1,2) */ -static int hauppauge = 0; -module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */ -MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)"); - - #define DEVNAME "ir-kbd-i2c" #define dprintk(level, fmt, arg...) if (debug >= level) \ printk(KERN_DEBUG DEVNAME ": " fmt , ## arg) @@ -302,11 +336,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, name = "Hauppauge"; ir->get_key = get_key_haup; ir_type = IR_TYPE_RC5; - if (hauppauge == 1) { - ir_codes = ir_codes_hauppauge_new; - } else { - ir_codes = ir_codes_rc5_tv; - } + ir_codes = ir_codes_rc5_tv; break; case 0x30: name = "KNC One"; @@ -411,9 +441,6 @@ static int ir_probe(struct i2c_adapter *adap) case I2C_HW_B_BT848: probe = probe_bttv; break; - case I2C_HW_B_CX2341X: - probe = probe_bttv; - break; case I2C_HW_SAA7134: probe = probe_saa7134; break; diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 850bee970..2869464ae 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -925,7 +925,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (p->palette != VIDEO_PALETTE_YUV422) return -EINVAL; - mutex_lock(&meye.lock); + down(&meye.lock); sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, p->brightness >> 10); sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, @@ -935,7 +935,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, p->contrast >> 10); meye.picture = *p; - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -946,21 +946,21 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, if (*i < 0 || *i >= gbuffers) return -EINVAL; - mutex_lock(&meye.lock); + down(&meye.lock); switch (meye.grab_buffer[*i].state) { case MEYE_BUF_UNUSED: - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; case MEYE_BUF_USING: if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EAGAIN; } if (wait_event_interruptible(meye.proc_list, (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINTR; } /* fall through */ @@ -968,7 +968,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); } - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -987,7 +987,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED) return -EBUSY; - mutex_lock(&meye.lock); + down(&meye.lock); if (vm->width == 640 && vm->height == 480) { if (meye.params.subsample) { meye.params.subsample = 0; @@ -999,7 +999,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, restart = 1; } } else { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; } @@ -1007,7 +1007,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, mchip_continuous_start(); meye.grab_buffer[vm->frame].state = MEYE_BUF_USING; kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int)); - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1039,7 +1039,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (jp->framerate > 31) return -EINVAL; - mutex_lock(&meye.lock); + down(&meye.lock); if (meye.params.subsample != jp->subsample || meye.params.quality != jp->quality) mchip_hic_stop(); /* need restart */ @@ -1050,7 +1050,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, meye.params.agc); sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, meye.params.picture); - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1068,12 +1068,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, } if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED) return -EBUSY; - mutex_lock(&meye.lock); + down(&meye.lock); if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) mchip_cont_compression_start(); meye.grab_buffer[*nb].state = MEYE_BUF_USING; kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1084,20 +1084,20 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, if (*i < 0 || *i >= gbuffers) return -EINVAL; - mutex_lock(&meye.lock); + down(&meye.lock); switch (meye.grab_buffer[*i].state) { case MEYE_BUF_UNUSED: - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; case MEYE_BUF_USING: if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EAGAIN; } if (wait_event_interruptible(meye.proc_list, (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINTR; } /* fall through */ @@ -1106,7 +1106,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); } *i = meye.grab_buffer[*i].size; - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1116,14 +1116,14 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) return -EBUSY; - mutex_lock(&meye.lock); + down(&meye.lock); meye.grab_buffer[0].state = MEYE_BUF_USING; mchip_take_picture(); mchip_get_picture( meye.grab_fbuffer, mchip_hsize() * mchip_vsize() * 2); meye.grab_buffer[0].state = MEYE_BUF_DONE; - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1134,7 +1134,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) return -EBUSY; - mutex_lock(&meye.lock); + down(&meye.lock); meye.grab_buffer[0].state = MEYE_BUF_USING; *len = -1; while (*len == -1) { @@ -1142,7 +1142,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize); } meye.grab_buffer[0].state = MEYE_BUF_DONE; - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1285,7 +1285,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_S_CTRL: { struct v4l2_control *c = arg; - mutex_lock(&meye.lock); + down(&meye.lock); switch (c->id) { case V4L2_CID_BRIGHTNESS: sonypi_camera_command( @@ -1329,17 +1329,17 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, meye.params.framerate = c->value; break; default: - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; } - mutex_unlock(&meye.lock); + up(&meye.lock); break; } case VIDIOC_G_CTRL: { struct v4l2_control *c = arg; - mutex_lock(&meye.lock); + down(&meye.lock); switch (c->id) { case V4L2_CID_BRIGHTNESS: c->value = meye.picture.brightness >> 10; @@ -1369,10 +1369,10 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, c->value = meye.params.framerate; break; default: - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; } - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1469,7 +1469,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, f->fmt.pix.field != V4L2_FIELD_NONE) return -EINVAL; f->fmt.pix.field = V4L2_FIELD_NONE; - mutex_lock(&meye.lock); + down(&meye.lock); if (f->fmt.pix.width <= 320) { f->fmt.pix.width = 320; f->fmt.pix.height = 240; @@ -1487,7 +1487,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; break; } - mutex_unlock(&meye.lock); + up(&meye.lock); f->fmt.pix.bytesperline = f->fmt.pix.width * 2; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; @@ -1509,11 +1509,11 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, /* already allocated, no modifications */ break; } - mutex_lock(&meye.lock); + down(&meye.lock); if (meye.grab_fbuffer) { for (i = 0; i < gbuffers; i++) if (meye.vma_use_count[i]) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; } rvfree(meye.grab_fbuffer, gbuffers * gbufsize); @@ -1525,12 +1525,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, if (!meye.grab_fbuffer) { printk(KERN_ERR "meye: v4l framebuffer allocation" " failed\n"); - mutex_unlock(&meye.lock); + up(&meye.lock); return -ENOMEM; } for (i = 0; i < gbuffers; i++) meye.vma_use_count[i] = 0; - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1569,12 +1569,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED) return -EINVAL; - mutex_lock(&meye.lock); + down(&meye.lock); buf->flags |= V4L2_BUF_FLAG_QUEUED; buf->flags &= ~V4L2_BUF_FLAG_DONE; meye.grab_buffer[buf->index].state = MEYE_BUF_USING; kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1587,23 +1587,23 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, if (buf->memory != V4L2_MEMORY_MMAP) return -EINVAL; - mutex_lock(&meye.lock); + down(&meye.lock); if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EAGAIN; } if (wait_event_interruptible(meye.proc_list, kfifo_len(meye.doneq) != 0) < 0) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINTR; } if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, sizeof(int))) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EBUSY; } if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; } buf->index = reqnr; @@ -1616,12 +1616,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, buf->m.offset = reqnr * gbufsize; buf->length = gbufsize; meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED; - mutex_unlock(&meye.lock); + up(&meye.lock); break; } case VIDIOC_STREAMON: { - mutex_lock(&meye.lock); + down(&meye.lock); switch (meye.mchip_mode) { case MCHIP_HIC_MODE_CONT_OUT: mchip_continuous_start(); @@ -1630,23 +1630,23 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, mchip_cont_compression_start(); break; default: - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; } - mutex_unlock(&meye.lock); + up(&meye.lock); break; } case VIDIOC_STREAMOFF: { int i; - mutex_lock(&meye.lock); + down(&meye.lock); mchip_hic_stop(); kfifo_reset(meye.grabq); kfifo_reset(meye.doneq); for (i = 0; i < MEYE_MAX_BUFNBRS; i++) meye.grab_buffer[i].state = MEYE_BUF_UNUSED; - mutex_unlock(&meye.lock); + up(&meye.lock); break; } @@ -1672,11 +1672,11 @@ static unsigned int meye_poll(struct file *file, poll_table *wait) { unsigned int res = 0; - mutex_lock(&meye.lock); + down(&meye.lock); poll_wait(file, &meye.proc_list, wait); if (kfifo_len(meye.doneq)) res = POLLIN | POLLRDNORM; - mutex_unlock(&meye.lock); + up(&meye.lock); return res; } @@ -1704,9 +1704,9 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; unsigned long page, pos; - mutex_lock(&meye.lock); + down(&meye.lock); if (size > gbuffers * gbufsize) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EINVAL; } if (!meye.grab_fbuffer) { @@ -1716,7 +1716,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize); if (!meye.grab_fbuffer) { printk(KERN_ERR "meye: v4l framebuffer allocation failed\n"); - mutex_unlock(&meye.lock); + up(&meye.lock); return -ENOMEM; } for (i = 0; i < gbuffers; i++) @@ -1727,7 +1727,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) while (size > 0) { page = vmalloc_to_pfn((void *)pos); if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { - mutex_unlock(&meye.lock); + up(&meye.lock); return -EAGAIN; } start += PAGE_SIZE; @@ -1744,7 +1744,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_private_data = (void *) (offset / gbufsize); meye_vm_open(vma); - mutex_unlock(&meye.lock); + up(&meye.lock); return 0; } @@ -1913,7 +1913,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev, goto outvideoreg; } - mutex_init(&meye.lock); + init_MUTEX(&meye.lock); init_waitqueue_head(&meye.proc_list); meye.picture.depth = 16; meye.picture.palette = VIDEO_PALETTE_YUV422; diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h index 0d09a0e38..e8cd897b0 100644 --- a/drivers/media/video/meye.h +++ b/drivers/media/video/meye.h @@ -260,8 +260,6 @@ /* private API definitions */ #include -#include - /* Enable jpg software correction */ #define MEYE_JPEG_CORRECTION 1 @@ -303,7 +301,7 @@ struct meye { /* list of buffers */ struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ - struct mutex lock; /* mutex for open/mmap... */ + struct semaphore lock; /* semaphore for open/mmap... */ struct kfifo *grabq; /* queue for buffers to be grabbed */ spinlock_t grabq_lock; /* lock protecting the queue */ struct kfifo *doneq; /* queue for grabbed buffers */ diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index b806999d6..69ed369c2 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -53,11 +53,10 @@ #include #include #include -#include -#include +#include #include #include -#include "msp3400-driver.h" +#include "msp3400.h" /* ---------------------------------------------------------------------- */ @@ -246,31 +245,31 @@ int msp_write_dsp(struct i2c_client *client, int addr, int val) * ----------------------------------------------------------------------- */ static int scarts[3][9] = { - /* MASK IN1 IN2 IN3 IN4 IN1_DA IN2_DA MONO MUTE */ + /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ /* SCART DSP Input select */ - { 0x0320, 0x0000, 0x0200, 0x0300, 0x0020, -1, -1, 0x0100, 0x0320 }, + { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, /* SCART1 Output select */ - { 0x0c40, 0x0440, 0x0400, 0x0000, 0x0840, 0x0c00, 0x0040, 0x0800, 0x0c40 }, + { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, /* SCART2 Output select */ - { 0x3080, 0x1000, 0x1080, 0x2080, 0x3080, 0x0000, 0x0080, 0x2000, 0x3000 }, + { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, }; static char *scart_names[] = { - "in1", "in2", "in3", "in4", "in1 da", "in2 da", "mono", "mute" + "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" }; void msp_set_scart(struct i2c_client *client, int in, int out) { struct msp_state *state = i2c_get_clientdata(client); - state->in_scart = in; + state->in_scart=in; - if (in >= 0 && in <= 7 && out >= 0 && out <= 2) { - if (-1 == scarts[out][in + 1]) + if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { + if (-1 == scarts[out][in]) return; - state->acb &= ~scarts[out][0]; - state->acb |= scarts[out][in + 1]; + state->acb &= ~scarts[out][SCART_MASK]; + state->acb |= scarts[out][in]; } else state->acb = 0xf60; /* Mute Input and SCART 1 Output */ @@ -279,8 +278,20 @@ void msp_set_scart(struct i2c_client *client, int in, int out) msp_write_dsp(client, 0x13, state->acb); /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ - if (state->has_i2s_conf) - msp_write_dem(client, 0x40, state->i2s_mode); + msp_write_dem(client, 0x40, state->i2s_mode); +} + +void msp_set_mute(struct i2c_client *client) +{ + struct msp_state *state = i2c_get_clientdata(client); + + v4l_dbg(1, msp_debug, client, "mute audio\n"); + msp_write_dsp(client, 0x0000, 0); + msp_write_dsp(client, 0x0007, 1); + if (state->has_scart2_out_volume) + msp_write_dsp(client, 0x0040, 1); + if (state->has_headphones) + msp_write_dsp(client, 0x0006, 0); } void msp_set_audio(struct i2c_client *client) @@ -288,19 +299,17 @@ void msp_set_audio(struct i2c_client *client) struct msp_state *state = i2c_get_clientdata(client); int bal = 0, bass, treble, loudness; int val = 0; - int reallymuted = state->muted | state->scan_in_progress; - if (!reallymuted) + if (!state->muted) val = (state->volume * 0x7f / 65535) << 8; - v4l_dbg(1, msp_debug, client, "mute=%s scanning=%s volume=%d\n", - state->muted ? "on" : "off", state->scan_in_progress ? "yes" : "no", - state->volume); + v4l_dbg(1, msp_debug, client, "mute=%s volume=%d\n", + state->muted ? "on" : "off", state->volume); msp_write_dsp(client, 0x0000, val); - msp_write_dsp(client, 0x0007, reallymuted ? 0x1 : (val | 0x1)); + msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1)); if (state->has_scart2_out_volume) - msp_write_dsp(client, 0x0040, reallymuted ? 0x1 : (val | 0x1)); + msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1)); if (state->has_headphones) msp_write_dsp(client, 0x0006, val); if (!state->has_sound_processing) @@ -327,6 +336,37 @@ void msp_set_audio(struct i2c_client *client) msp_write_dsp(client, 0x0033, loudness); } +int msp_modus(struct i2c_client *client) +{ + struct msp_state *state = i2c_get_clientdata(client); + + if (state->radio) { + v4l_dbg(1, msp_debug, client, "video mode selected to Radio\n"); + return 0x0003; + } + + if (state->v4l2_std & V4L2_STD_PAL) { + v4l_dbg(1, msp_debug, client, "video mode selected to PAL\n"); + +#if 1 + /* experimental: not sure this works with all chip versions */ + return 0x7003; +#else + /* previous value, try this if it breaks ... */ + return 0x1003; +#endif + } + if (state->v4l2_std & V4L2_STD_NTSC) { + v4l_dbg(1, msp_debug, client, "video mode selected to NTSC\n"); + return 0x2003; + } + if (state->v4l2_std & V4L2_STD_SECAM) { + v4l_dbg(1, msp_debug, client, "video mode selected to SECAM\n"); + return 0x0003; + } + return 0x0003; +} + /* ------------------------------------------------------------------------ */ @@ -336,6 +376,7 @@ static void msp_wake_thread(struct i2c_client *client) if (NULL == state->kthread) return; + msp_set_mute(client); state->watch_stereo = 0; state->restart = 1; wake_up_interruptible(&state->wq); @@ -363,15 +404,19 @@ int msp_sleep(struct msp_state *state, int timeout) /* ------------------------------------------------------------------------ */ -static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) +static int msp_mode_v4l2_to_v4l1(int rxsubchans) { - if (rxsubchans == V4L2_TUNER_SUB_MONO) - return VIDEO_SOUND_MONO; - if (rxsubchans == V4L2_TUNER_SUB_STEREO) - return VIDEO_SOUND_STEREO; - if (audmode == V4L2_TUNER_MODE_LANG2) - return VIDEO_SOUND_LANG2; - return VIDEO_SOUND_LANG1; + int mode = 0; + + if (rxsubchans & V4L2_TUNER_SUB_STEREO) + mode |= VIDEO_SOUND_STEREO; + if (rxsubchans & V4L2_TUNER_SUB_LANG2) + mode |= VIDEO_SOUND_LANG2; + if (rxsubchans & V4L2_TUNER_SUB_LANG1) + mode |= VIDEO_SOUND_LANG1; + if (mode == 0) + mode |= VIDEO_SOUND_MONO; + return mode; } static int msp_mode_v4l1_to_v4l2(int mode) @@ -385,6 +430,21 @@ static int msp_mode_v4l1_to_v4l2(int mode) return V4L2_TUNER_MODE_MONO; } +static void msp_any_detect_stereo(struct i2c_client *client) +{ + struct msp_state *state = i2c_get_clientdata(client); + + switch (state->opmode) { + case OPMODE_MANUAL: + case OPMODE_AUTODETECT: + autodetect_stereo(client); + break; + case OPMODE_AUTOSELECT: + msp34xxg_detect_stereo(client); + break; + } +} + static struct v4l2_queryctrl msp_qctrl_std[] = { { .id = V4L2_CID_AUDIO_VOLUME, @@ -446,6 +506,22 @@ static struct v4l2_queryctrl msp_qctrl_sound_processing[] = { }; +static void msp_any_set_audmode(struct i2c_client *client, int audmode) +{ + struct msp_state *state = i2c_get_clientdata(client); + + switch (state->opmode) { + case OPMODE_MANUAL: + case OPMODE_AUTODETECT: + state->watch_stereo = 0; + msp3400c_setstereo(client, audmode); + break; + case OPMODE_AUTOSELECT: + msp34xxg_set_audmode(client, audmode); + break; + } +} + static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) { struct msp_state *state = i2c_get_clientdata(client); @@ -540,11 +616,52 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct msp_state *state = i2c_get_clientdata(client); + u16 *sarg = arg; + int scart = 0; if (msp_debug >= 2) v4l_i2c_print_ioctl(client, cmd); switch (cmd) { + case AUDC_SET_INPUT: + if (*sarg == state->input) + break; + state->input = *sarg; + switch (*sarg) { + case AUDIO_RADIO: + /* Hauppauge uses IN2 for the radio */ + state->mode = MSP_MODE_FM_RADIO; + scart = SCART_IN2; + break; + case AUDIO_EXTERN_1: + /* IN1 is often used for external input ... */ + state->mode = MSP_MODE_EXTERN; + scart = SCART_IN1; + break; + case AUDIO_EXTERN_2: + /* ... sometimes it is IN2 through ;) */ + state->mode = MSP_MODE_EXTERN; + scart = SCART_IN2; + break; + case AUDIO_TUNER: + state->mode = -1; + break; + default: + if (*sarg & AUDIO_MUTE) + msp_set_scart(client, SCART_MUTE, 0); + break; + } + if (scart) { + state->rxsubchans = V4L2_TUNER_SUB_STEREO; + state->audmode = V4L2_TUNER_MODE_STEREO; + msp_set_scart(client, scart, 0); + msp_write_dsp(client, 0x000d, 0x1900); + if (state->opmode != OPMODE_AUTOSELECT) + msp3400c_setstereo(client, state->audmode); + } + msp_wake_thread(client); + break; + case AUDC_SET_RADIO: if (state->radio) return 0; @@ -554,8 +671,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) switch (state->opmode) { case OPMODE_MANUAL: /* set msp3400 to FM radio mode */ - msp3400c_set_mode(client, MSP_MODE_FM_RADIO); - msp3400c_set_carrier(client, MSP_CARRIER(10.7), + msp3400c_setmode(client, MSP_MODE_FM_RADIO); + msp3400c_setcarrier(client, MSP_CARRIER(10.7), MSP_CARRIER(10.7)); msp_set_audio(client); break; @@ -589,8 +706,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) if (state->radio) break; if (state->opmode == OPMODE_AUTOSELECT) - msp_detect_stereo(client); - va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode); + msp_any_detect_stereo(client); + va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); break; } @@ -605,11 +722,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) state->treble = va->treble; msp_set_audio(client); - if (va->mode != 0 && state->radio == 0 && - state->audmode != msp_mode_v4l1_to_v4l2(va->mode)) { - state->audmode = msp_mode_v4l1_to_v4l2(va->mode); - msp_set_audmode(client); - } + if (va->mode != 0 && state->radio == 0) + msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode)); break; } @@ -645,6 +759,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) break; } + /* msp34xx specific */ + case MSP_SET_MATRIX: + { + struct msp_matrix *mspm = arg; + + msp_set_scart(client, mspm->input, mspm->output); + break; + } + /* --- v4l2 ioctls --- */ case VIDIOC_S_STD: { @@ -658,38 +781,101 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } - case VIDIOC_INT_G_AUDIO_ROUTING: + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; + + if (i->index != 0) + return -EINVAL; + + i->type = V4L2_INPUT_TYPE_TUNER; + switch (i->index) { + case AUDIO_RADIO: + strcpy(i->name, "Radio"); + break; + case AUDIO_EXTERN_1: + strcpy(i->name, "Extern 1"); + break; + case AUDIO_EXTERN_2: + strcpy(i->name, "Extern 2"); + break; + case AUDIO_TUNER: + strcpy(i->name, "Television"); + break; + default: + return -EINVAL; + } + return 0; + } + + case VIDIOC_G_AUDIO: { - struct v4l2_routing *rt = arg; + struct v4l2_audio *a = arg; + + memset(a, 0, sizeof(*a)); + + switch (a->index) { + case AUDIO_RADIO: + strcpy(a->name, "Radio"); + break; + case AUDIO_EXTERN_1: + strcpy(a->name, "Extern 1"); + break; + case AUDIO_EXTERN_2: + strcpy(a->name, "Extern 2"); + break; + case AUDIO_TUNER: + strcpy(a->name, "Television"); + break; + default: + return -EINVAL; + } + + msp_any_detect_stereo(client); + if (state->audmode == V4L2_TUNER_MODE_STEREO) { + a->capability = V4L2_AUDCAP_STEREO; + } - *rt = state->routing; break; } - case VIDIOC_INT_S_AUDIO_ROUTING: + case VIDIOC_S_AUDIO: { - struct v4l2_routing *rt = arg; - 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; - u16 val, reg; - - if (state->routing.input == rt->input && - state->routing.output == rt->output) + struct v4l2_audio *sarg = arg; + + switch (sarg->index) { + case AUDIO_RADIO: + /* Hauppauge uses IN2 for the radio */ + state->mode = MSP_MODE_FM_RADIO; + scart = SCART_IN2; + break; + case AUDIO_EXTERN_1: + /* IN1 is often used for external input ... */ + state->mode = MSP_MODE_EXTERN; + scart = SCART_IN1; + break; + case AUDIO_EXTERN_2: + /* ... sometimes it is IN2 through ;) */ + state->mode = MSP_MODE_EXTERN; + scart = SCART_IN2; + break; + case AUDIO_TUNER: + state->mode = -1; break; - state->routing = *rt; - msp_set_scart(client, sc_in, 0); - msp_set_scart(client, sc1_out, 1); - msp_set_scart(client, sc2_out, 2); - msp_set_audmode(client); - reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb; - val = msp_read_dem(client, reg); - if (tuner != ((val >> 8) & 1)) { - msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); - /* wake thread when a new tuner input is chosen */ - msp_wake_thread(client); } + if (scart) { + state->rxsubchans = V4L2_TUNER_SUB_STEREO; + state->audmode = V4L2_TUNER_MODE_STEREO; + msp_set_scart(client, scart, 0); + msp_write_dsp(client, 0x000d, 0x1900); + } + if (sarg->capability == V4L2_AUDCAP_STEREO) { + state->audmode = V4L2_TUNER_MODE_STEREO; + } else { + state->audmode &= ~V4L2_TUNER_MODE_STEREO; + } + msp_any_set_audmode(client, state->audmode); + msp_wake_thread(client); break; } @@ -700,10 +886,10 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) if (state->radio) break; if (state->opmode == OPMODE_AUTOSELECT) - msp_detect_stereo(client); + msp_any_detect_stereo(client); vt->audmode = state->audmode; vt->rxsubchans = state->rxsubchans; - vt->capability |= V4L2_TUNER_CAP_STEREO | + vt->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; break; } @@ -712,13 +898,48 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; - if (state->radio) /* TODO: add mono/stereo support for radio */ - break; - if (state->audmode == vt->audmode) + if (state->radio) break; - state->audmode = vt->audmode; /* only set audmode */ - msp_set_audmode(client); + if (vt->audmode != -1 && vt->audmode != 0) + msp_any_set_audmode(client, vt->audmode); + break; + } + + case VIDIOC_G_AUDOUT: + { + struct v4l2_audioout *a = (struct v4l2_audioout *)arg; + int idx = a->index; + + memset(a, 0, sizeof(*a)); + + switch (idx) { + case 0: + strcpy(a->name, "Scart1 Out"); + break; + case 1: + strcpy(a->name, "Scart2 Out"); + break; + case 2: + strcpy(a->name, "I2S Out"); + break; + default: + return -EINVAL; + } + break; + + } + + case VIDIOC_S_AUDOUT: + { + struct v4l2_audioout *a = (struct v4l2_audioout *)arg; + + if (a->index < 0 || a->index > 2) + return -EINVAL; + + v4l_dbg(1, msp_debug, client, "Setting audio out on msp34xx to input %i\n", a->index); + msp_set_scart(client, state->in_scart, a->index + 1); + break; } @@ -772,7 +993,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) const char *p; if (state->opmode == OPMODE_AUTOSELECT) - msp_detect_stereo(client); + msp_any_detect_stereo(client); v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", client->name, state->rev1, state->rev2); v4l_info(client, "Audio: volume %d%s\n", @@ -799,16 +1020,12 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); } else { - if (state->opmode == OPMODE_AUTODETECT) - v4l_info(client, "Mode: %s\n", p); + v4l_info(client, "Mode: %s\n", p); v4l_info(client, "Standard: %s (%s%s)\n", msp_standard_std_name(state->std), (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); } - 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); v4l_info(client, "ACB: 0x%04x\n", state->acb); break; } @@ -877,7 +1094,6 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) memset(state, 0, sizeof(*state)); state->v4l2_std = V4L2_STD_NTSC; - state->audmode = V4L2_TUNER_MODE_STEREO; state->volume = 58880; /* 0db gain */ state->balance = 32768; /* 0db gain */ state->bass = 32768; @@ -887,9 +1103,6 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) state->muted = 0; 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->rev1 = msp_read_dsp(client, 0x1e); if (state->rev1 != -1) @@ -921,16 +1134,13 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) state->has_radio = msp_revision >= 'G'; /* Has headphones output: not for stripped down products */ state->has_headphones = msp_prod_lo < 5; - /* Has scart2 input: not in stripped down products of the '3' family */ - state->has_scart2 = msp_family >= 4 || msp_prod_lo < 7; - /* Has scart3 input: not in stripped down products of the '3' family */ - state->has_scart3 = msp_family >= 4 || msp_prod_lo < 5; /* Has scart4 input: not in pre D revisions, not in stripped D revs */ state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5); - /* Has scart2 output: not in stripped down products of the '3' family */ - state->has_scart2_out = msp_family >= 4 || msp_prod_lo < 5; + /* Has scart2 and scart3 inputs and scart2 output: not in stripped + down products of the '3' family */ + state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5; /* Has scart2 a volume control? Not in pre-D revisions. */ - state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart2_out; + state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out; /* Has a configurable i2s out? */ state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7; /* Has subwoofer output: not in pre-D revs and not in stripped down products */ diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 633a10213..2072c3efe 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c @@ -26,10 +26,10 @@ #include #include #include -#include +#include #include #include -#include "msp3400-driver.h" +#include "msp3400.h" /* this one uses the automatic sound standard detection of newer msp34xx chip versions */ @@ -45,13 +45,11 @@ static struct { { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" }, { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" }, { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" }, - { 0x0007, MSP_CARRIER(6.5), MSP_CARRIER(5.7421875), "6.5/5.74 D/K3 Dual FM-Stereo" }, { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" }, { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" }, { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" }, { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" }, { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" }, - { 0x000d, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV3)" }, { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" }, { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" }, { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" }, @@ -111,7 +109,7 @@ static struct msp3400c_init_data_dem { {-2, -8, -10, 10, 50, 86}, {-4, -12, -9, 23, 79, 126}, MSP_CARRIER(6.5), MSP_CARRIER(6.5), - 0x00c6, 0x0140, 0x0120, 0x7c00 + 0x00c6, 0x0140, 0x0120, 0x7c03 }, }; @@ -156,170 +154,139 @@ const char *msp_standard_std_name(int std) return "unknown"; } -static void msp_set_source(struct i2c_client *client, u16 src) -{ - struct msp_state *state = i2c_get_clientdata(client); - - if (msp_dolby) { - msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ - msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */ - } else { - msp_write_dsp(client, 0x0008, src); - msp_write_dsp(client, 0x0009, src); - } - msp_write_dsp(client, 0x000a, src); - msp_write_dsp(client, 0x000b, src); - msp_write_dsp(client, 0x000c, src); - if (state->has_scart2_out) - msp_write_dsp(client, 0x0041, src); -} - -void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2) +void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) { msp_write_dem(client, 0x0093, cdo1 & 0xfff); msp_write_dem(client, 0x009b, cdo1 >> 12); msp_write_dem(client, 0x00a3, cdo2 & 0xfff); msp_write_dem(client, 0x00ab, cdo2 >> 12); - msp_write_dem(client, 0x0056, 0); /* LOAD_REG_1/2 */ + msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ } -void msp3400c_set_mode(struct i2c_client *client, int mode) +void msp3400c_setmode(struct i2c_client *client, int type) { struct msp_state *state = i2c_get_clientdata(client); - struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode]; - int tuner = (state->routing.input >> 3) & 1; int i; - v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode); - state->mode = mode; + v4l_dbg(1, msp_debug, client, "setmode: %d\n", type); + state->mode = type; + state->audmode = V4L2_TUNER_MODE_MONO; state->rxsubchans = V4L2_TUNER_SUB_MONO; - msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0)); + msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv); for (i = 5; i >= 0; i--) /* fir 1 */ - msp_write_dem(client, 0x0001, data->fir1[i]); + msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]); msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ msp_write_dem(client, 0x0005, 0x0040); msp_write_dem(client, 0x0005, 0x0000); for (i = 5; i >= 0; i--) - msp_write_dem(client, 0x0005, data->fir2[i]); + msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]); - msp_write_dem(client, 0x0083, data->mode_reg); + msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg); - msp3400c_set_carrier(client, data->cdo1, data->cdo2); + msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1, + msp3400c_init_data[type].cdo2); - msp_set_source(client, data->dsp_src); - /* set prescales */ + msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ - /* volume prescale for SCART (AM mono input) */ - msp_write_dsp(client, 0x000d, 0x1900); - msp_write_dsp(client, 0x000e, data->dsp_matrix); - if (state->has_nicam) /* nicam prescale */ - msp_write_dsp(client, 0x0010, 0x5a00); + if (msp_dolby) { + msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ + msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */ + msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); + } else { + msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src); + msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src); + msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); + } + msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src); + msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix); + + if (state->has_nicam) { + /* nicam prescale */ + msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */ + } } -/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP, - nor do they support stereo BTSC. */ -static void msp3400c_set_audmode(struct i2c_client *client) +/* turn on/off nicam + stereo */ +void msp3400c_setstereo(struct i2c_client *client, int mode) { - static char *strmode[] = { "mono", "stereo", "lang2", "lang1", "lang1+lang2" }; + static char *strmode[] = { "mono", "stereo", "lang2", "lang1" }; struct msp_state *state = i2c_get_clientdata(client); - char *modestr = (state->audmode >= 0 && state->audmode < 5) ? - strmode[state->audmode] : "unknown"; - int src = 0; /* channel source: FM/AM, nicam or SCART */ - int audmode = state->audmode; + int nicam = 0; /* channel source: FM/AM or nicam */ + int src = 0; if (state->opmode == OPMODE_AUTOSELECT) { /* this method would break everything, let's make sure * it's never called */ - v4l_dbg(1, msp_debug, client, - "set_audmode called with mode=%d instead of set_source (ignored)\n", - state->audmode); + v4l_dbg(1, msp_debug, client, "setstereo called with mode=%d instead of set_source (ignored)\n", + mode); return; } - /* Note: for the C and D revs no NTSC stereo + SAP is possible as - the hardware does not support SAP. So the rxsubchans combination - of STEREO | LANG2 does not occur. */ - - /* switch to mono if only mono is available */ - if (state->rxsubchans == V4L2_TUNER_SUB_MONO) - audmode = V4L2_TUNER_MODE_MONO; - /* if bilingual */ - else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { - /* and mono or stereo, then fallback to lang1 */ - if (audmode == V4L2_TUNER_MODE_MONO || - audmode == V4L2_TUNER_MODE_STEREO) - audmode = V4L2_TUNER_MODE_LANG1; - } - /* if stereo, and audmode is not mono, then switch to stereo */ - else if (audmode != V4L2_TUNER_MODE_MONO) - audmode = V4L2_TUNER_MODE_STEREO; - /* switch demodulator */ switch (state->mode) { case MSP_MODE_FM_TERRA: - v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr); - switch (audmode) { + v4l_dbg(1, msp_debug, client, "FM setstereo: %s\n", strmode[mode]); + msp3400c_setcarrier(client, state->second, state->main); + switch (mode) { case V4L2_TUNER_MODE_STEREO: msp_write_dsp(client, 0x000e, 0x3001); break; case V4L2_TUNER_MODE_MONO: case V4L2_TUNER_MODE_LANG1: case V4L2_TUNER_MODE_LANG2: - case V4L2_TUNER_MODE_LANG1_LANG2: msp_write_dsp(client, 0x000e, 0x3000); break; } break; case MSP_MODE_FM_SAT: - v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr); - switch (audmode) { + v4l_dbg(1, msp_debug, client, "SAT setstereo: %s\n", strmode[mode]); + switch (mode) { case V4L2_TUNER_MODE_MONO: - msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); + msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); break; case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1_LANG2: - msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); + msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); break; case V4L2_TUNER_MODE_LANG1: - msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); break; case V4L2_TUNER_MODE_LANG2: - msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); break; } break; case MSP_MODE_FM_NICAM1: case MSP_MODE_FM_NICAM2: case MSP_MODE_AM_NICAM: - v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr); + v4l_dbg(1, msp_debug, client, "NICAM setstereo: %s\n",strmode[mode]); + msp3400c_setcarrier(client,state->second,state->main); if (state->nicam_on) - src = 0x0100; /* NICAM */ + nicam=0x0100; break; case MSP_MODE_BTSC: - v4l_dbg(1, msp_debug, client, "BTSC set_audmode: %s\n",modestr); + v4l_dbg(1, msp_debug, client, "BTSC setstereo: %s\n",strmode[mode]); + nicam=0x0300; break; case MSP_MODE_EXTERN: - v4l_dbg(1, msp_debug, client, "extern set_audmode: %s\n",modestr); - src = 0x0200; /* SCART */ + v4l_dbg(1, msp_debug, client, "extern setstereo: %s\n",strmode[mode]); + nicam = 0x0200; break; case MSP_MODE_FM_RADIO: - v4l_dbg(1, msp_debug, client, "FM-Radio set_audmode: %s\n",modestr); + v4l_dbg(1, msp_debug, client, "FM-Radio setstereo: %s\n",strmode[mode]); break; default: - v4l_dbg(1, msp_debug, client, "mono set_audmode\n"); + v4l_dbg(1, msp_debug, client, "mono setstereo\n"); return; } /* switch audio */ - v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode); - switch (audmode) { + switch (mode) { case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1_LANG2: - src |= 0x0020; + src = 0x0020 | nicam; break; case V4L2_TUNER_MODE_MONO: if (state->mode == MSP_MODE_AM_NICAM) { @@ -330,18 +297,29 @@ static void msp3400c_set_audmode(struct i2c_client *client) src = 0x0200; break; } - if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) - src = 0x0030; - break; case V4L2_TUNER_MODE_LANG1: + src = 0x0000 | nicam; break; case V4L2_TUNER_MODE_LANG2: - src |= 0x0010; + src = 0x0010 | nicam; break; } - v4l_dbg(1, msp_debug, client, "set_audmode final source/matrix = 0x%x\n", src); + v4l_dbg(1, msp_debug, client, "setstereo final source/matrix = 0x%x\n", src); - msp_set_source(client, src); + if (msp_dolby) { + msp_write_dsp(client, 0x0008, 0x0520); + msp_write_dsp(client, 0x0009, 0x0620); + msp_write_dsp(client, 0x000a, src); + msp_write_dsp(client, 0x000b, src); + } else { + msp_write_dsp(client, 0x0008, src); + msp_write_dsp(client, 0x0009, src); + msp_write_dsp(client, 0x000a, src); + msp_write_dsp(client, 0x000b, src); + msp_write_dsp(client, 0x000c, src); + if (state->has_scart23_in_scart2_out) + msp_write_dsp(client, 0x0041, src); + } } static void msp3400c_print_mode(struct i2c_client *client) @@ -369,12 +347,12 @@ static void msp3400c_print_mode(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -static int msp3400c_detect_stereo(struct i2c_client *client) +int autodetect_stereo(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); int val; int rxsubchans = state->rxsubchans; - int newnicam = state->nicam_on; + int newnicam = state->nicam_on; int update = 0; switch (state->mode) { @@ -383,8 +361,8 @@ static int msp3400c_detect_stereo(struct i2c_client *client) if (val > 32767) val -= 65536; v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val); - if (val > 8192) { - rxsubchans = V4L2_TUNER_SUB_STEREO; + if (val > 4096) { + rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; } else if (val < -4096) { rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; } else { @@ -408,11 +386,14 @@ static int msp3400c_detect_stereo(struct i2c_client *client) break; case 1: case 9: - rxsubchans = V4L2_TUNER_SUB_MONO; + rxsubchans = V4L2_TUNER_SUB_MONO + | V4L2_TUNER_SUB_LANG1; break; case 2: case 10: - rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + rxsubchans = V4L2_TUNER_SUB_MONO + | V4L2_TUNER_SUB_LANG1 + | V4L2_TUNER_SUB_LANG2; break; default: rxsubchans = V4L2_TUNER_SUB_MONO; @@ -424,17 +405,30 @@ static int msp3400c_detect_stereo(struct i2c_client *client) rxsubchans = V4L2_TUNER_SUB_MONO; } break; + case MSP_MODE_BTSC: + val = msp_read_dem(client, 0x200); + v4l_dbg(2, msp_debug, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n", + val, + (val & 0x0002) ? "no" : "yes", + (val & 0x0004) ? "no" : "yes", + (val & 0x0040) ? "stereo" : "mono", + (val & 0x0080) ? ", nicam 2nd mono" : "", + (val & 0x0100) ? ", bilingual/SAP" : ""); + rxsubchans = V4L2_TUNER_SUB_MONO; + if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO; + if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1; + break; } if (rxsubchans != state->rxsubchans) { update = 1; - v4l_dbg(1, msp_debug, client, "watch: rxsubchans %02x => %02x\n", - state->rxsubchans, rxsubchans); + v4l_dbg(1, msp_debug, client, "watch: rxsubchans %d => %d\n", + state->rxsubchans,rxsubchans); state->rxsubchans = rxsubchans; } if (newnicam != state->nicam_on) { update = 1; v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n", - state->nicam_on, newnicam); + state->nicam_on,newnicam); state->nicam_on = newnicam; } return update; @@ -449,8 +443,13 @@ static void watch_stereo(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); - if (msp_detect_stereo(client)) { - msp_set_audmode(client); + if (autodetect_stereo(client)) { + if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) + msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); + else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1) + msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); + else + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); } if (msp_once) @@ -462,7 +461,7 @@ int msp3400c_thread(void *data) struct i2c_client *client = data; struct msp_state *state = i2c_get_clientdata(client); struct msp3400c_carrier_detect *cd; - int count, max1, max2, val1, val2, val, this; + int count, max1,max2,val1,val2, val,this; v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n"); @@ -472,7 +471,7 @@ int msp3400c_thread(void *data) v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n"); restart: - v4l_dbg(2, msp_debug, client, "thread: restart scan\n"); + v4l_dbg(1, msp_debug, client, "thread: restart scan\n"); state->restart = 0; if (kthread_should_stop()) break; @@ -480,23 +479,19 @@ int msp3400c_thread(void *data) if (state->radio || MSP_MODE_EXTERN == state->mode) { /* no carrier scan, just unmute */ v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); - state->scan_in_progress = 0; msp_set_audio(client); continue; } - /* mute audio */ - state->scan_in_progress = 1; - msp_set_audio(client); - - msp3400c_set_mode(client, MSP_MODE_AM_DETECT); + /* mute */ + msp_set_mute(client); + msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); val1 = val2 = 0; max1 = max2 = -1; state->watch_stereo = 0; - state->nicam_on = 0; - /* wait for tuner to settle down after a channel change */ - if (msp_sleep(state, 200)) + /* some time for the tuner to sync */ + if (msp_sleep(state,200)) goto restart; /* carrier detect pass #1 -- main carrier */ @@ -511,7 +506,7 @@ int msp3400c_thread(void *data) } for (this = 0; this < count; this++) { - msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo); + msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); if (msp_sleep(state,100)) goto restart; val = msp_read_dsp(client, 0x1b); @@ -547,7 +542,7 @@ int msp3400c_thread(void *data) max2 = 0; } for (this = 0; this < count; this++) { - msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo); + msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); if (msp_sleep(state,100)) goto restart; val = msp_read_dsp(client, 0x1b); @@ -559,19 +554,22 @@ int msp3400c_thread(void *data) } /* program the msp3400 according to the results */ - state->main = msp3400c_carrier_detect_main[max1].cdo; + state->main = msp3400c_carrier_detect_main[max1].cdo; switch (max1) { case 1: /* 5.5 */ if (max2 == 0) { /* B/G FM-stereo */ state->second = msp3400c_carrier_detect_55[max2].cdo; - msp3400c_set_mode(client, MSP_MODE_FM_TERRA); + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + state->nicam_on = 0; + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); state->watch_stereo = 1; } else if (max2 == 1 && state->has_nicam) { /* B/G NICAM */ state->second = msp3400c_carrier_detect_55[max2].cdo; - msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); + msp3400c_setmode(client, MSP_MODE_FM_NICAM1); state->nicam_on = 1; + msp3400c_setcarrier(client, state->second, state->main); state->watch_stereo = 1; } else { goto no_second; @@ -580,26 +578,35 @@ int msp3400c_thread(void *data) case 2: /* 6.0 */ /* PAL I NICAM */ state->second = MSP_CARRIER(6.552); - msp3400c_set_mode(client, MSP_MODE_FM_NICAM2); + msp3400c_setmode(client, MSP_MODE_FM_NICAM2); state->nicam_on = 1; + msp3400c_setcarrier(client, state->second, state->main); state->watch_stereo = 1; break; case 3: /* 6.5 */ if (max2 == 1 || max2 == 2) { /* D/K FM-stereo */ state->second = msp3400c_carrier_detect_65[max2].cdo; - msp3400c_set_mode(client, MSP_MODE_FM_TERRA); + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + state->nicam_on = 0; + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); state->watch_stereo = 1; } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) { /* L NICAM or AM-mono */ state->second = msp3400c_carrier_detect_65[max2].cdo; - msp3400c_set_mode(client, MSP_MODE_AM_NICAM); + msp3400c_setmode(client, MSP_MODE_AM_NICAM); + state->nicam_on = 0; + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); + msp3400c_setcarrier(client, state->second, state->main); + /* volume prescale for SCART (AM mono input) */ + msp_write_dsp(client, 0x000d, 0x1900); state->watch_stereo = 1; } else if (max2 == 0 && state->has_nicam) { /* D/K NICAM */ state->second = msp3400c_carrier_detect_65[max2].cdo; - msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); + msp3400c_setmode(client, MSP_MODE_FM_NICAM1); state->nicam_on = 1; + msp3400c_setcarrier(client, state->second, state->main); state->watch_stereo = 1; } else { goto no_second; @@ -609,26 +616,24 @@ int msp3400c_thread(void *data) default: no_second: state->second = msp3400c_carrier_detect_main[max1].cdo; - msp3400c_set_mode(client, MSP_MODE_FM_TERRA); + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + state->nicam_on = 0; + msp3400c_setcarrier(client, state->second, state->main); + state->rxsubchans = V4L2_TUNER_SUB_MONO; + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); break; } - msp3400c_set_carrier(client, state->second, state->main); /* unmute */ - state->scan_in_progress = 0; - msp3400c_set_audmode(client); msp_set_audio(client); if (msp_debug) msp3400c_print_mode(client); - /* monitor tv audio mode, the first time don't wait - so long to get a quick stereo/bilingual result */ - count = 3; + /* monitor tv audio mode */ while (state->watch_stereo) { - if (msp_sleep(state, count ? 1000 : 5000)) + if (msp_sleep(state,5000)) goto restart; - if (count) count--; watch_stereo(client); } } @@ -641,7 +646,7 @@ int msp3410d_thread(void *data) { struct i2c_client *client = data; struct msp_state *state = i2c_get_clientdata(client); - int val, i, std, count; + int val, i, std; v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); @@ -651,7 +656,7 @@ int msp3410d_thread(void *data) v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n"); restart: - v4l_dbg(2, msp_debug, client, "thread: restart scan\n"); + v4l_dbg(1, msp_debug, client, "thread: restart scan\n"); state->restart = 0; if (kthread_should_stop()) break; @@ -659,30 +664,26 @@ int msp3410d_thread(void *data) if (state->mode == MSP_MODE_EXTERN) { /* no carrier scan needed, just unmute */ v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); - state->scan_in_progress = 0; msp_set_audio(client); continue; } - /* mute audio */ - state->scan_in_progress = 1; - msp_set_audio(client); + /* put into sane state (and mute) */ + msp_reset(client); + + /* some time for the tuner to sync */ + if (msp_sleep(state,200)) + goto restart; - /* start autodetect. Note: autodetect is not supported for - NTSC-M and radio, hence we force the standard in those cases. */ + /* start autodetect */ if (state->radio) std = 0x40; else std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1; state->watch_stereo = 0; - state->nicam_on = 0; - - /* wait for tuner to settle down after a channel change */ - if (msp_sleep(state, 200)) - goto restart; if (msp_debug) - v4l_dbg(2, msp_debug, client, "setting standard: %s (0x%04x)\n", + v4l_dbg(1, msp_debug, client, "setting standard: %s (0x%04x)\n", msp_standard_std_name(std), std); if (std != 1) { @@ -699,7 +700,7 @@ int msp3410d_thread(void *data) val = msp_read_dem(client, 0x7e); if (val < 0x07ff) break; - v4l_dbg(2, msp_debug, client, "detection still in progress\n"); + v4l_dbg(1, msp_debug, client, "detection still in progress\n"); } } for (i = 0; msp_stdlist[i].name != NULL; i++) @@ -710,7 +711,6 @@ int msp3410d_thread(void *data) state->main = msp_stdlist[i].main; state->second = msp_stdlist[i].second; state->std = val; - state->rxsubchans = V4L2_TUNER_SUB_MONO; if (msp_amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) && (val != 0x0009)) { @@ -718,71 +718,83 @@ int msp3410d_thread(void *data) v4l_dbg(1, msp_debug, client, "autodetection failed," " switching to backup standard: %s (0x%04x)\n", msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val); - state->std = val = 0x0009; + val = 0x0009; msp_write_dem(client, 0x20, val); } + /* set various prescales */ + msp_write_dsp(client, 0x0d, 0x1900); /* scart */ + msp_write_dsp(client, 0x0e, 0x2403); /* FM */ + msp_write_dsp(client, 0x10, 0x5a00); /* nicam */ + /* set stereo */ switch (val) { case 0x0008: /* B/G NICAM */ case 0x000a: /* I NICAM */ - case 0x000b: /* D/K NICAM */ - if (val == 0x000a) - state->mode = MSP_MODE_FM_NICAM2; - else + if (val == 0x0008) state->mode = MSP_MODE_FM_NICAM1; + else + state->mode = MSP_MODE_FM_NICAM2; /* just turn on stereo */ + state->rxsubchans = V4L2_TUNER_SUB_STEREO; state->nicam_on = 1; state->watch_stereo = 1; + msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); break; case 0x0009: state->mode = MSP_MODE_AM_NICAM; + state->rxsubchans = V4L2_TUNER_SUB_MONO; state->nicam_on = 1; + msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO); state->watch_stereo = 1; break; case 0x0020: /* BTSC */ - /* The pre-'G' models only have BTSC-mono */ + /* just turn on stereo */ state->mode = MSP_MODE_BTSC; + state->rxsubchans = V4L2_TUNER_SUB_STEREO; + state->nicam_on = 0; + state->watch_stereo = 1; + msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); break; case 0x0040: /* FM radio */ state->mode = MSP_MODE_FM_RADIO; state->rxsubchans = V4L2_TUNER_SUB_STEREO; + state->audmode = V4L2_TUNER_MODE_STEREO; + state->nicam_on = 0; + state->watch_stereo = 0; /* not needed in theory if we have radio, but short programming enables carrier mute */ - msp3400c_set_mode(client, MSP_MODE_FM_RADIO); - msp3400c_set_carrier(client, MSP_CARRIER(10.7), + msp3400c_setmode(client, MSP_MODE_FM_RADIO); + msp3400c_setcarrier(client, MSP_CARRIER(10.7), MSP_CARRIER(10.7)); + /* scart routing */ + msp_set_scart(client,SCART_IN2,0); + /* msp34xx does radio decoding */ + msp_write_dsp(client, 0x08, 0x0020); + msp_write_dsp(client, 0x09, 0x0020); + msp_write_dsp(client, 0x0b, 0x0020); break; - case 0x0002: case 0x0003: case 0x0004: case 0x0005: state->mode = MSP_MODE_FM_TERRA; + state->rxsubchans = V4L2_TUNER_SUB_MONO; + state->audmode = V4L2_TUNER_MODE_MONO; + state->nicam_on = 0; state->watch_stereo = 1; break; } - /* set various prescales */ - msp_write_dsp(client, 0x0d, 0x1900); /* scart */ - msp_write_dsp(client, 0x0e, 0x3000); /* FM */ - if (state->has_nicam) - msp_write_dsp(client, 0x10, 0x5a00); /* nicam */ - + /* unmute, restore misc registers */ + msp_set_audio(client); + msp_write_dsp(client, 0x13, state->acb); if (state->has_i2s_conf) msp_write_dem(client, 0x40, state->i2s_mode); - /* unmute */ - msp3400c_set_audmode(client); - state->scan_in_progress = 0; - msp_set_audio(client); - - /* monitor tv audio mode, the first time don't wait - so long to get a quick stereo/bilingual result */ - count = 3; + /* monitor tv audio mode */ while (state->watch_stereo) { - if (msp_sleep(state, count ? 1000 : 5000)) + if (msp_sleep(state,5000)) goto restart; - if (count) count--; watch_stereo(client); } } @@ -792,150 +804,102 @@ int msp3410d_thread(void *data) /* ----------------------------------------------------------------------- */ -/* msp34xxG + (autoselect no-thread) - * this one uses both automatic standard detection and automatic sound - * select which are available in the newer G versions - * struct msp: only norm, acb and source are really used in this mode - */ +/* msp34xxG + (autoselect no-thread) */ +/* this one uses both automatic standard detection and automatic sound */ +/* select which are available in the newer G versions */ +/* struct msp: only norm, acb and source are really used in this mode */ -static int msp34xxg_modus(struct i2c_client *client) +/* set the same 'source' for the loudspeaker, scart and quasi-peak detector + * the value for source is the same as bit 15:8 of DSP registers 0x08, + * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B + * + * this function replaces msp3400c_setstereo + */ +static void msp34xxg_set_source(struct i2c_client *client, int source) { struct msp_state *state = i2c_get_clientdata(client); - if (state->radio) { - v4l_dbg(1, msp_debug, client, "selected radio modus\n"); - return 0x0001; - } - - if (state->v4l2_std & V4L2_STD_PAL) { - v4l_dbg(1, msp_debug, client, "selected PAL modus\n"); - return 0x7001; - } - if (state->v4l2_std == V4L2_STD_NTSC_M_JP) { - v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n"); - return 0x4001; - } - if (state->v4l2_std == V4L2_STD_NTSC_M_KR) { - v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n"); - return 0x0001; - } - if (state->v4l2_std & V4L2_STD_MN) { - v4l_dbg(1, msp_debug, client, "selected M (BTSC) modus\n"); - return 0x2001; - } - if (state->v4l2_std & V4L2_STD_SECAM) { - v4l_dbg(1, msp_debug, client, "selected SECAM modus\n"); - return 0x6001; - } - return 0x0001; -} - -static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) - { - struct msp_state *state = i2c_get_clientdata(client); - int source, matrix; - - switch (state->audmode) { - case V4L2_TUNER_MODE_MONO: - source = 0; /* mono only */ - matrix = 0x30; - break; - case V4L2_TUNER_MODE_LANG2: - source = 4; /* stereo or B */ - matrix = 0x10; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - source = 1; /* stereo or A|B */ - matrix = 0x20; - break; - case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1: - default: - source = 3; /* stereo or A */ - matrix = 0x00; - break; - } - - if (in == MSP_DSP_IN_TUNER) - source = (source << 8) | 0x20; - /* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14 - instead of 11, 12, 13. So we add one for that msp version. */ - else if (in >= MSP_DSP_IN_MAIN_AVC && state->has_dolby_pro_logic) - source = ((in + 1) << 8) | matrix; - else - source = (in << 8) | matrix; - - v4l_dbg(1, msp_debug, client, "set source to %d (0x%x) for output %02x\n", - in, source, reg); - msp_write_dsp(client, reg, source); -} - -static void msp34xxg_set_sources(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - u32 in = state->routing.input; - - msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf); - /* quasi-peak detector is set to same input as the loudspeaker (MAIN) */ - msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf); - msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf); - msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf); - if (state->has_scart2_out) - msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf); - msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf); + /* fix matrix mode to stereo and let the msp choose what + * to output according to 'source', as recommended + * for MONO (source==0) downmixing set bit[7:0] to 0x30 + */ + int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20); + + v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value); + /* Loudspeaker Output */ + msp_write_dsp(client, 0x08, value); + /* SCART1 DA Output */ + msp_write_dsp(client, 0x0a, value); + /* Quasi-peak detector */ + msp_write_dsp(client, 0x0c, value); + /* + * set identification threshold. Personally, I + * I set it to a higher value that the default + * of 0x190 to ignore noisy stereo signals. + * this needs tuning. (recommended range 0x00a0-0x03c0) + * 0x7f0 = forced mono mode + */ + /* a2 threshold for stereo/bilingual */ + msp_write_dem(client, 0x22, msp_stereo_thresh); + state->source = source; } -/* (re-)initialize the msp34xxg */ -static void msp34xxg_reset(struct i2c_client *client) +/* (re-)initialize the msp34xxg, according to the current norm in state->norm + * return 0 if it worked, -1 if it failed + */ +static int msp34xxg_reset(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); - int tuner = (state->routing.input >> 3) & 1; - int modus; + int modus, std; - /* initialize std to 1 (autodetect) to signal that no standard is - selected yet. */ - state->std = 1; + if (msp_reset(client)) + return -1; - msp_reset(client); + /* make sure that input/output is muted (paranoid mode) */ + /* ACB, mute DSP input, mute SCART 1 */ + if (msp_write_dsp(client, 0x13, 0x0f20)) + return -1; if (state->has_i2s_conf) msp_write_dem(client, 0x40, state->i2s_mode); /* step-by-step initialisation, as described in the manual */ - modus = msp34xxg_modus(client); - modus |= tuner ? 0x100 : 0; - msp_write_dem(client, 0x30, modus); + modus = msp_modus(client); + if (state->radio) + std = 0x40; + else + std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1; + modus &= ~0x03; /* STATUS_CHANGE = 0 */ + modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION = 1 */ + if (msp_write_dem(client, 0x30, modus)) + return -1; + if (msp_write_dem(client, 0x20, std)) + return -1; /* write the dsps that may have an influence on standard/audio autodetection right now */ - msp34xxg_set_sources(client); + msp34xxg_set_source(client, state->source); - msp_write_dsp(client, 0x0d, 0x1900); /* scart */ - msp_write_dsp(client, 0x0e, 0x3000); /* FM */ - if (state->has_nicam) - msp_write_dsp(client, 0x10, 0x5a00); /* nicam */ + /* AM/FM Prescale [15:8] 75khz deviation */ + if (msp_write_dsp(client, 0x0e, 0x3000)) + return -1; - /* set identification threshold. Personally, I - * I set it to a higher value than the default - * of 0x190 to ignore noisy stereo signals. - * this needs tuning. (recommended range 0x00a0-0x03c0) - * 0x7f0 = forced mono mode - * - * a2 threshold for stereo/bilingual. - * Note: this register is part of the Manual/Compatibility mode. - * It is supported by all 'G'-family chips. - */ - msp_write_dem(client, 0x22, msp_stereo_thresh); + /* NICAM Prescale 9db gain (as recommended) */ + if (msp_write_dsp(client, 0x10, 0x5a00)) + return -1; + + return 0; } int msp34xxg_thread(void *data) { struct i2c_client *client = data; struct msp_state *state = i2c_get_clientdata(client); - int val, i; + int val, std, i; v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n"); + state->source = 1; /* default */ for (;;) { v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n"); msp_sleep(state, -1); @@ -949,14 +913,12 @@ int msp34xxg_thread(void *data) /* setup the chip*/ msp34xxg_reset(client); - state->std = state->radio ? 0x40 : msp_standard; - if (state->std != 1) + std = msp_standard; + if (std != 0x01) goto unmute; - /* start autodetect */ - msp_write_dem(client, 0x20, state->std); /* watch autodetect */ - v4l_dbg(1, msp_debug, client, "started autodetect, waiting for result\n"); + v4l_dbg(1, msp_debug, client, "triggered autodetect, waiting for result\n"); for (i = 0; i < 10; i++) { if (msp_sleep(state, 100)) goto restart; @@ -964,19 +926,20 @@ int msp34xxg_thread(void *data) /* check results */ val = msp_read_dem(client, 0x7e); if (val < 0x07ff) { - state->std = val; + std = val; break; } v4l_dbg(2, msp_debug, client, "detection still in progress\n"); } - if (state->std == 1) { + if (std == 1) { v4l_dbg(1, msp_debug, client, "detection still in progress after 10 tries. giving up.\n"); continue; } unmute: - v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n", - msp_standard_std_name(state->std), state->std); + state->std = std; + v4l_dbg(1, msp_debug, client, "current standard: %s (0x%04x)\n", + msp_standard_std_name(std), std); /* unmute: dispatch sound to scart output, set scart volume */ msp_set_audio(client); @@ -985,93 +948,63 @@ int msp34xxg_thread(void *data) if (msp_write_dsp(client, 0x13, state->acb)) return -1; - /* the periodic stereo/SAP check is only relevant for - the 0x20 standard (BTSC) */ - if (state->std != 0x20) - continue; - - state->watch_stereo = 1; - - /* monitor tv audio mode, the first time don't wait - in order to get a quick stereo/SAP update */ - watch_stereo(client); - while (state->watch_stereo) { - watch_stereo(client); - if (msp_sleep(state, 5000)) - goto restart; - } + msp_write_dem(client, 0x40, state->i2s_mode); } v4l_dbg(1, msp_debug, client, "thread: exit\n"); return 0; } -static int msp34xxg_detect_stereo(struct i2c_client *client) +void msp34xxg_detect_stereo(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); + int status = msp_read_dem(client, 0x0200); int is_bilingual = status & 0x100; int is_stereo = status & 0x40; - int oldrx = state->rxsubchans; state->rxsubchans = 0; if (is_stereo) - state->rxsubchans = V4L2_TUNER_SUB_STEREO; + state->rxsubchans |= V4L2_TUNER_SUB_STEREO; else - state->rxsubchans = V4L2_TUNER_SUB_MONO; + state->rxsubchans |= V4L2_TUNER_SUB_MONO; if (is_bilingual) { - if (state->std == 0x20) - state->rxsubchans |= V4L2_TUNER_SUB_SAP; - else - state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + /* I'm supposed to check whether it's SAP or not + * and set only LANG2/SAP in this case. Yet, the MSP + * does a lot of work to hide this and handle everything + * the same way. I don't want to work around it so unless + * this is a problem, I'll handle SAP just like lang1/lang2. + */ } v4l_dbg(1, msp_debug, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", status, is_stereo, is_bilingual, state->rxsubchans); - return (oldrx != state->rxsubchans); } -static void msp34xxg_set_audmode(struct i2c_client *client) +void msp34xxg_set_audmode(struct i2c_client *client, int audmode) { struct msp_state *state = i2c_get_clientdata(client); + int source; - if (state->std == 0x20) { - if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) && - (state->audmode == V4L2_TUNER_MODE_LANG1_LANG2 || - state->audmode == V4L2_TUNER_MODE_LANG2)) { - msp_write_dem(client, 0x20, 0x21); - } else { - msp_write_dem(client, 0x20, 0x20); - } - } - - msp34xxg_set_sources(client); -} - -void msp_set_audmode(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - switch (state->opmode) { - case OPMODE_MANUAL: - case OPMODE_AUTODETECT: - msp3400c_set_audmode(client); + switch (audmode) { + case V4L2_TUNER_MODE_MONO: + source = 0; /* mono only */ break; - case OPMODE_AUTOSELECT: - msp34xxg_set_audmode(client); + case V4L2_TUNER_MODE_STEREO: + source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */ + /* problem: that could also mean 2 (scart input) */ + break; + case V4L2_TUNER_MODE_LANG1: + source = 3; /* stereo or A */ + break; + case V4L2_TUNER_MODE_LANG2: + source = 4; /* stereo or B */ + break; + default: + audmode = 0; + source = 1; break; } -} - -int msp_detect_stereo(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - switch (state->opmode) { - case OPMODE_MANUAL: - case OPMODE_AUTODETECT: - return msp3400c_detect_stereo(client); - case OPMODE_AUTOSELECT: - return msp34xxg_detect_stereo(client); - } - return 0; + state->audmode = audmode; + msp34xxg_set_source(client, source); } diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400.h similarity index 74% rename from drivers/media/video/msp3400-driver.h rename to drivers/media/video/msp3400.h index 4e4510490..a9ac57d07 100644 --- a/drivers/media/video/msp3400-driver.h +++ b/drivers/media/video/msp3400.h @@ -1,10 +1,8 @@ /* */ -#ifndef MSP3400_DRIVER_H -#define MSP3400_DRIVER_H - -#include +#ifndef MSP3400_H +#define MSP3400_H /* ---------------------------------------------------------------------- */ @@ -22,14 +20,15 @@ #define MSP_MODE_BTSC 8 #define MSP_MODE_EXTERN 9 -#define SCART_IN1 0 -#define SCART_IN2 1 -#define SCART_IN3 2 -#define SCART_IN4 3 -#define SCART_IN1_DA 4 -#define SCART_IN2_DA 5 -#define SCART_MONO 6 -#define SCART_MUTE 7 +#define SCART_MASK 0 +#define SCART_IN1 1 +#define SCART_IN2 2 +#define SCART_IN1_DA 3 +#define SCART_IN2_DA 4 +#define SCART_IN3 5 +#define SCART_IN4 6 +#define SCART_MONO 7 +#define SCART_MUTE 8 #define SCART_DSP_IN 0 #define SCART1_OUT 1 @@ -54,10 +53,8 @@ struct msp_state { u8 has_radio; u8 has_headphones; u8 has_ntsc_jp_d_k3; - u8 has_scart2; - u8 has_scart3; u8 has_scart4; - u8 has_scart2_out; + u8 has_scart23_in_scart2_out; u8 has_scart2_out_volume; u8 has_i2s_conf; u8 has_subwoofer; @@ -76,7 +73,7 @@ struct msp_state { int i2s_mode; int main, second; /* sound carrier */ int input; - struct v4l2_routing routing; + int source; /* see msp34xxg_set_source */ /* v4l2 */ int audmode; @@ -85,7 +82,6 @@ struct msp_state { int volume, muted; int balance, loudness; int bass, treble; - int scan_in_progress; /* thread */ struct task_struct *kthread; @@ -101,17 +97,21 @@ int msp_read_dem(struct i2c_client *client, int addr); int msp_read_dsp(struct i2c_client *client, int addr); int msp_reset(struct i2c_client *client); void msp_set_scart(struct i2c_client *client, int in, int out); +void msp_set_mute(struct i2c_client *client); void msp_set_audio(struct i2c_client *client); +int msp_modus(struct i2c_client *client); int msp_sleep(struct msp_state *state, int timeout); /* msp3400-kthreads.c */ const char *msp_standard_std_name(int std); -void msp_set_audmode(struct i2c_client *client); -int msp_detect_stereo(struct i2c_client *client); +void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2); +void msp3400c_setmode(struct i2c_client *client, int type); +void msp3400c_setstereo(struct i2c_client *client, int mode); +int autodetect_stereo(struct i2c_client *client); int msp3400c_thread(void *data); int msp3410d_thread(void *data); int msp34xxg_thread(void *data); -void msp3400c_set_mode(struct i2c_client *client, int mode); -void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2); +void msp34xxg_detect_stereo(struct i2c_client *client); +void msp34xxg_set_audmode(struct i2c_client *client, int audmode); -#endif /* MSP3400_DRIVER_H */ +#endif /* MSP3400_H */ diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index b0aea4002..41715cacf 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c @@ -1,11 +1,11 @@ /* mxb - v4l2 driver for the Multimedia eXtension Board - + Copyright (C) 1998-2006 Michael Hunold Visit http://www.mihu.de/linux/saa7146/mxb/ for further details about this card. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -35,12 +35,12 @@ #define I2C_SAA7111 0x24 -#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) +#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) /* global variable */ static int mxb_num = 0; -/* initial frequence the tuner will be tuned to. +/* initial frequence the tuner will be tuned to. in verden (lower saxony, germany) 4148 is a channel called "phoenix" */ static int freq = 4148; @@ -55,7 +55,7 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); enum { TUNER, AUX1, AUX3, AUX3_YC }; static struct v4l2_input mxb_inputs[MXB_INPUTS] = { - { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, + { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, @@ -66,7 +66,7 @@ static struct v4l2_input mxb_inputs[MXB_INPUTS] = { static struct { int hps_source; int hps_sync; -} input_port_selection[MXB_INPUTS] = { +} input_port_selection[MXB_INPUTS] = { { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, @@ -81,7 +81,7 @@ static int video_audio_connect[MXB_INPUTS] = /* these are the necessary input-output-pins for bringing one audio source (see above) to the CD-output */ static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] = - { + { {{1,1,0},{1,1,0}}, /* Tuner */ {{5,1,0},{6,1,0}}, /* AUX 1 */ {{4,1,0},{6,1,0}}, /* AUX 2 */ @@ -122,8 +122,8 @@ static struct saa7146_extension_ioctls ioctls[] = { { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE }, { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, - { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */ - { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */ + { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */ + { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */ { 0, 0 } }; @@ -132,7 +132,7 @@ struct mxb struct video_device *video_dev; struct video_device *vbi_dev; - struct i2c_adapter i2c_adapter; + struct i2c_adapter i2c_adapter; struct i2c_client* saa7111a; struct i2c_client* tda9840; @@ -198,17 +198,17 @@ static int mxb_probe(struct saa7146_dev* dev) /* loop through all i2c-devices on the bus and look who is there */ list_for_each(item,&mxb->i2c_adapter.clients) { client = list_entry(item, struct i2c_client, list); - if( I2C_ADDR_TEA6420_1 == client->addr ) + if( I2C_TEA6420_1 == client->addr ) mxb->tea6420_1 = client; - if( I2C_ADDR_TEA6420_2 == client->addr ) + if( I2C_TEA6420_2 == client->addr ) mxb->tea6420_2 = client; - if( I2C_TEA6415C_2 == client->addr ) + if( I2C_TEA6415C_2 == client->addr ) mxb->tea6415c = client; - if( I2C_ADDR_TDA9840 == client->addr ) + if( I2C_TDA9840 == client->addr ) mxb->tda9840 = client; if( I2C_SAA7111 == client->addr ) mxb->saa7111a = client; - if( 0x60 == client->addr ) + if( 0x60 == client->addr ) mxb->tuner = client; } @@ -222,7 +222,7 @@ static int mxb_probe(struct saa7146_dev* dev) return -ENODEV; } - /* all devices are present, probe was successful */ + /* all devices are present, probe was successful */ /* we store the pointer in our private data field */ dev->ext_priv = mxb; @@ -230,7 +230,7 @@ static int mxb_probe(struct saa7146_dev* dev) return 0; } -/* some init data for the saa7740, the so-called 'sound arena module'. +/* some init data for the saa7740, the so-called 'sound arena module'. there are no specs available, so we simply use some init values */ static struct { int length; @@ -330,7 +330,7 @@ static int mxb_init_done(struct saa7146_dev* dev) v4l2_std_id std = V4L2_STD_PAL_BG; int i = 0, err = 0; - struct tea6415c_multiplex vm; + struct tea6415c_multiplex vm; /* select video mode in saa7111a */ i = VIDEO_MODE_PAL; @@ -380,16 +380,16 @@ static int mxb_init_done(struct saa7146_dev* dev) vm.in = 3; vm.out = 13; mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm); - + /* the rest for mxb */ mxb->cur_input = 0; mxb->cur_mute = 1; mxb->cur_mode = V4L2_TUNER_MODE_STEREO; mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode); - + /* check if the saa7740 (aka 'sound arena module') is present - on the mxb. if so, we must initialize it. due to lack of + on the mxb. if so, we must initialize it. due to lack of informations about the saa7740, the values were reverse engineered. */ msg.addr = 0x1b; @@ -409,7 +409,7 @@ static int mxb_init_done(struct saa7146_dev* dev) break; } - msg.len = mxb_saa7740_init[i].length; + msg.len = mxb_saa7740_init[i].length; msg.buf = &mxb_saa7740_init[i].data[0]; if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) { DEB_D(("failed to initialize 'sound arena module'.\n")); @@ -418,12 +418,12 @@ static int mxb_init_done(struct saa7146_dev* dev) } INFO(("'sound arena module' detected.\n")); } -err: +err: /* the rest for saa7146: you should definitely set some basic values for the input-port handling of the saa7146. */ /* ext->saa has been filled by the core driver */ - + /* some stuff is done via variables */ saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync); @@ -431,7 +431,7 @@ err: /* this is ugly, but because of the fact that this is completely hardware dependend, it should be done directly... */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); + saa7146_write(dev, DD1_STREAM_B, 0x00000000); saa7146_write(dev, DD1_INIT, 0x02000200); saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); @@ -453,7 +453,7 @@ static struct saa7146_ext_vv vv_data; static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) { struct mxb* mxb = (struct mxb*)dev->ext_priv; - + DEB_EE(("dev:%p\n",dev)); /* checking for i2c-devices can be omitted here, because we @@ -464,7 +464,7 @@ static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data ERR(("cannot register capture v4l2 device. skipping.\n")); return -1; } - + /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) { if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { @@ -513,17 +513,17 @@ static int mxb_detach(struct saa7146_dev* dev) return 0; } -static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct saa7146_dev *dev = fh->dev; struct mxb* mxb = (struct mxb*)dev->ext_priv; - struct saa7146_vv *vv = dev->vv_data; - + struct saa7146_vv *vv = dev->vv_data; + switch(cmd) { case VIDIOC_ENUMINPUT: { struct v4l2_input *i = arg; - + DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); if( i->index < 0 || i->index >= MXB_INPUTS) { return -EINVAL; @@ -559,11 +559,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) break; } } - + if( i < 0 ) { return -EAGAIN; } - + switch (vc->id ) { case V4L2_CID_AUDIO_MUTE: { vc->value = mxb->cur_mute; @@ -571,7 +571,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) return 0; } } - + DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value)); return 0; } @@ -580,17 +580,17 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct v4l2_control *vc = arg; int i = 0; - + for (i = MAXCONTROLS - 1; i >= 0; i--) { if (mxb_controls[i].id == vc->id) { break; } } - + if( i < 0 ) { return -EAGAIN; } - + switch (vc->id ) { case V4L2_CID_AUDIO_MUTE: { mxb->cur_mute = vc->value; @@ -614,12 +614,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) *input = mxb->cur_input; DEB_EE(("VIDIOC_G_INPUT %d.\n",*input)); - return 0; - } + return 0; + } case VIDIOC_S_INPUT: { int input = *(int *)arg; - struct tea6415c_multiplex vm; + struct tea6415c_multiplex vm; int i = 0; DEB_EE(("VIDIOC_S_INPUT %d.\n",input)); @@ -627,34 +627,34 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) if (input < 0 || input >= MXB_INPUTS) { return -EINVAL; } - + /* fixme: locke das setzen des inputs mit hilfe des mutexes - mutex_lock(&dev->lock); + down(&dev->lock); video_mux(dev,*i); - mutex_unlock(&dev->lock); + up(&dev->lock); */ - + /* fixme: check if streaming capture if ( 0 != dev->streaming ) { DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n")); return -EPERM; } */ - + mxb->cur_input = input; - + saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); - + /* prepare switching of tea6415c and saa7111a; have a look at the 'background'-file for further informations */ switch( input ) { - + case TUNER: { i = 0; vm.in = 3; vm.out = 17; - + if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) { printk("VIDIOC_S_INPUT: could not address tea6415c #1\n"); return -EFAULT; @@ -662,7 +662,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) /* connect tuner-output always to multicable */ vm.in = 3; vm.out = 13; - break; + break; } case AUX3_YC: { @@ -703,11 +703,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) break; } } - + /* switch video in saa7111a */ if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) { printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n"); - } + } /* switch the audio-source only if necessary */ if( 0 == mxb->cur_mute ) { @@ -738,11 +738,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ /* FIXME: add the real signal strength here */ t->signal = 0xffff; - t->afc = 0; + t->afc = 0; mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte); t->audmode = mxb->cur_mode; - + if( byte < 0 ) { t->rxsubchans = V4L2_TUNER_SUB_MONO; } else { @@ -777,12 +777,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) struct v4l2_tuner *t = arg; int result = 0; int byte = 0; - + if( 0 != t->index ) { DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index)); return -EINVAL; } - + switch(t->audmode) { case V4L2_TUNER_MODE_STEREO: { mxb->cur_mode = V4L2_TUNER_MODE_STEREO; @@ -790,12 +790,6 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n")); break; } - case V4L2_TUNER_MODE_LANG1_LANG2: { - mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2; - byte = TDA9840_SET_BOTH; - DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n")); - break; - } case V4L2_TUNER_MODE_LANG1: { mxb->cur_mode = V4L2_TUNER_MODE_LANG1; byte = TDA9840_SET_LANG1; @@ -819,7 +813,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) { printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte); } - + return 0; } case VIDIOC_G_FREQUENCY: @@ -845,7 +839,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) if (V4L2_TUNER_ANALOG_TV != f->type) return -EINVAL; - + if(0 != mxb->cur_input) { DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input)); return -EINVAL; @@ -854,7 +848,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) mxb->cur_freq = *f; DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency)); - /* tune in desired frequency */ + /* tune in desired frequency */ mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq); /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ @@ -867,12 +861,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) case MXB_S_AUDIO_CD: { int i = *(int*)arg; - + if( i < 0 || i >= MXB_AUDIOS ) { DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i)); return -EINVAL; } - + DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i)); mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]); @@ -883,12 +877,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) case MXB_S_AUDIO_LINE: { int i = *(int*)arg; - + if( i < 0 || i >= MXB_AUDIOS ) { DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i)); return -EINVAL; } - + DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i)); mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]); mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]); @@ -900,13 +894,13 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) struct v4l2_audio *a = arg; if( a->index < 0 || a->index > MXB_INPUTS ) { - DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index)); + DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index)); return -EINVAL; } - - DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index)); + + DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index)); memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio)); - + return 0; } case VIDIOC_S_AUDIO: @@ -914,7 +908,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) struct v4l2_audio *a = arg; DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index)); return 0; - } + } default: /* DEB2(printk("does not handle this ioctl.\n")); @@ -934,7 +928,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) v4l2_std_id std = V4L2_STD_PAL_I; DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n")); /* set the 7146 gpio register -- I don't know what this does exactly */ - saa7146_write(dev, GPIO_CTRL, 0x00404050); + saa7146_write(dev, GPIO_CTRL, 0x00404050); /* unset the 7111 gpio register -- I don't know what this does exactly */ mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero); mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); @@ -942,7 +936,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) v4l2_std_id std = V4L2_STD_PAL_BG; DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n")); /* set the 7146 gpio register -- I don't know what this does exactly */ - saa7146_write(dev, GPIO_CTRL, 0x00404050); + saa7146_write(dev, GPIO_CTRL, 0x00404050); /* set the 7111 gpio register -- I don't know what this does exactly */ mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one); mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); @@ -975,8 +969,8 @@ static struct saa7146_standard standard[] = { }; static struct saa7146_pci_extension_data mxb = { - .ext_priv = "Multimedia eXtension Board", - .ext = &extension, + .ext_priv = "Multimedia eXtension Board", + .ext = &extension, }; static struct pci_device_id pci_tbl[] = { @@ -998,7 +992,7 @@ static struct saa7146_ext_vv vv_data = { .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, .stds = &standard[0], .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), - .std_callback = &std_callback, + .std_callback = &std_callback, .ioctls = &ioctls[0], .ioctl = mxb_ioctl, }; @@ -1006,7 +1000,7 @@ static struct saa7146_ext_vv vv_data = { static struct saa7146_extension extension = { .name = MXB_IDENTIFIER, .flags = SAA7146_USE_I2C_IRQ, - + .pci_tbl = &pci_tbl[0], .module = THIS_MODULE, @@ -1016,7 +1010,7 @@ static struct saa7146_extension extension = { .irq_mask = 0, .irq_func = NULL, -}; +}; static int __init mxb_init_module(void) { @@ -1024,7 +1018,7 @@ static int __init mxb_init_module(void) DEB_S(("failed to register extension.\n")); return -ENODEV; } - + return 0; } diff --git a/drivers/media/video/mxb.h b/drivers/media/video/mxb.h index 400a57ba6..2332ed5f7 100644 --- a/drivers/media/video/mxb.h +++ b/drivers/media/video/mxb.h @@ -38,5 +38,5 @@ static struct v4l2_audio mxb_audios[MXB_AUDIOS] = { .name = "CD-ROM (X10)", .capability = V4L2_AUDCAP_STEREO, } -}; +}; #endif diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c index 54dd5612d..e76b53d59 100644 --- a/drivers/media/video/ovcamchip/ovcamchip_core.c +++ b/drivers/media/video/ovcamchip/ovcamchip_core.c @@ -296,10 +296,10 @@ static int ovcamchip_attach(struct i2c_adapter *adap) * attach to adapters that are known to contain OV camera chips. */ switch (adap->id) { - case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511): - case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518): - case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OVFX2): - case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF): + case I2C_HW_SMBUS_OV511: + case I2C_HW_SMBUS_OV518: + case I2C_HW_SMBUS_OVFX2: + case I2C_HW_SMBUS_W9968CF: PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id); break; default: @@ -314,21 +314,20 @@ static int ovcamchip_attach(struct i2c_adapter *adap) } memcpy(c, &client_template, sizeof *c); c->adapter = adap; - strcpy(i2c_clientname(c), "OV????"); + strcpy(c->name, "OV????"); - ov = kmalloc(sizeof *ov, GFP_KERNEL); + ov = kzalloc(sizeof *ov, GFP_KERNEL); if (!ov) { rc = -ENOMEM; goto no_ov; } - memset(ov, 0, sizeof *ov); i2c_set_clientdata(c, ov); rc = ovcamchip_detect(c); if (rc < 0) goto error; - strcpy(i2c_clientname(c), chip_names[ov->subtype]); + strcpy(c->name, chip_names[ov->subtype]); PDEBUG(1, "Camera chip detection complete"); @@ -410,18 +409,18 @@ static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg) /* ----------------------------------------------------------------------- */ static struct i2c_driver driver = { - .owner = THIS_MODULE, - .name = "ovcamchip", + .driver = { + .name = "ovcamchip", + }, .id = I2C_DRIVERID_OVCAMCHIP, .class = I2C_CLASS_CAM_DIGITAL, - .flags = I2C_DF_NOTIFY, .attach_adapter = ovcamchip_attach, .detach_client = ovcamchip_detach, .command = ovcamchip_command, }; static struct i2c_client client_template = { - I2C_DEVNAME("(unset)"), + .name = "(unset)", .driver = &driver, }; diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c index d9e3cada5..f3fc361be 100644 --- a/drivers/media/video/planb.c +++ b/drivers/media/video/planb.c @@ -1,4 +1,4 @@ -/* +/* planb - PlanB frame grabber driver PlanB is used in the 7x00/8x00 series of PowerMacintosh @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include "planb.h" #include "saa7196.h" @@ -329,12 +329,12 @@ static volatile struct dbdma_cmd *cmd_geo_setup( static inline void planb_lock(struct planb *pb) { - mutex_lock(&pb->lock); + down(&pb->lock); } static inline void planb_unlock(struct planb *pb) { - mutex_unlock(&pb->lock); + up(&pb->lock); } /***************/ @@ -584,7 +584,7 @@ finish: wake_up_interruptible(&pb->suspendq); } -static void add_clip(struct planb *pb, struct video_clip *clip) +static void add_clip(struct planb *pb, struct video_clip *clip) { volatile unsigned char *base; int xc = clip->x, yc = clip->y; @@ -758,7 +758,7 @@ static void cmd_buff(struct planb *pb) PLANB_SET(CH_SYNC)); tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), PLANB_SET(DMA_ABORT)); - + /* odd field data: */ jump = virt_to_bus(c1 + nlines / 2); for (i=1; i < nlines; i += stepsize, c1++) @@ -1247,7 +1247,7 @@ static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb) tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++; tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), PLANB_SET(DMA_ABORT)); - + /* odd field data: */ jump_addr = c1 + TAB_FACTOR * nlines / 2; jump = virt_to_bus(jump_addr); @@ -1383,7 +1383,7 @@ static int planb_open(struct video_device *dev, int mode) pb->user++; DEBUG("PlanB: device opened\n"); - return 0; + return 0; } static void planb_close(struct video_device *dev) @@ -1424,9 +1424,9 @@ static long planb_write(struct video_device *v, const char *buf, static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { struct planb *pb=(struct planb *)dev; - + switch (cmd) - { + { case VIDIOCGCAP: { struct video_capability b; @@ -1440,26 +1440,26 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) b.channels = 2; /* composite & svhs */ b.audios = 0; b.maxwidth = PLANB_MAXPIXELS; - b.maxheight = PLANB_MAXLINES; - b.minwidth = 32; /* wild guess */ - b.minheight = 32; - if (copy_to_user(arg,&b,sizeof(b))) - return -EFAULT; + b.maxheight = PLANB_MAXLINES; + b.minwidth = 32; /* wild guess */ + b.minheight = 32; + if (copy_to_user(arg,&b,sizeof(b))) + return -EFAULT; return 0; } case VIDIOCSFBUF: { - struct video_buffer v; + struct video_buffer v; unsigned short bpp; unsigned int fmt; DEBUG("PlanB: IOCTL VIDIOCSFBUF\n"); - if (!capable(CAP_SYS_ADMIN) + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) - return -EPERM; - if (copy_from_user(&v, arg,sizeof(v))) - return -EFAULT; + return -EPERM; + if (copy_from_user(&v, arg,sizeof(v))) + return -EFAULT; planb_lock(pb); switch(v.depth) { case 8: @@ -1478,7 +1478,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) break; default: planb_unlock(pb); - return -EINVAL; + return -EINVAL; } if (bpp * v.width > v.bytesperline) { planb_unlock(pb); @@ -1493,7 +1493,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) pb->win.bpl = pb->win.bpp * pb->win.swidth; pb->win.pad = v.bytesperline - pb->win.bpl; - DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d," + DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d," " bpl %d (+ %d)\n", v.base, v.width,v.height, pb->win.bpp, pb->win.bpl, pb->win.pad); @@ -1504,11 +1504,11 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) resume_overlay(pb); } planb_unlock(pb); - return 0; + return 0; } case VIDIOCGFBUF: { - struct video_buffer v; + struct video_buffer v; DEBUG("PlanB: IOCTL VIDIOCGFBUF\n"); @@ -1518,15 +1518,15 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) v.depth = pb->win.depth; v.bytesperline = pb->win.bpl + pb->win.pad; if (copy_to_user(arg, &v, sizeof(v))) - return -EFAULT; + return -EFAULT; return 0; } case VIDIOCCAPTURE: { int i; - if(copy_from_user(&i, arg, sizeof(i))) - return -EFAULT; + if(copy_from_user(&i, arg, sizeof(i))) + return -EFAULT; if(i==0) { DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n"); @@ -1695,7 +1695,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) struct video_window vw; struct video_clip clip; int i; - + DEBUG("PlanB: IOCTL VIDIOCSWIN\n"); if(copy_from_user(&vw,arg,sizeof(vw))) @@ -1749,7 +1749,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) return -EFAULT; return 0; } - case VIDIOCSYNC: { + case VIDIOCSYNC: { int i; IDEBUG("PlanB: IOCTL VIDIOCSYNC\n"); @@ -1759,42 +1759,42 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) IDEBUG("PlanB: sync to frame %d\n", i); - if(i > (MAX_GBUFFERS - 1) || i < 0) - return -EINVAL; + if(i > (MAX_GBUFFERS - 1) || i < 0) + return -EINVAL; chk_grab: - switch (pb->frame_stat[i]) { - case GBUFFER_UNUSED: - return -EINVAL; + switch (pb->frame_stat[i]) { + case GBUFFER_UNUSED: + return -EINVAL; case GBUFFER_GRABBING: IDEBUG("PlanB: waiting for grab" " done (%d)\n", i); - interruptible_sleep_on(&pb->capq); + interruptible_sleep_on(&pb->capq); if(signal_pending(current)) return -EINTR; goto chk_grab; - case GBUFFER_DONE: - pb->frame_stat[i] = GBUFFER_UNUSED; - break; - } - return 0; + case GBUFFER_DONE: + pb->frame_stat[i] = GBUFFER_UNUSED; + break; + } + return 0; } - case VIDIOCMCAPTURE: + case VIDIOCMCAPTURE: { - struct video_mmap vm; + struct video_mmap vm; volatile unsigned int status; IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n"); if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm))) return -EFAULT; - status = pb->frame_stat[vm.frame]; - if (status != GBUFFER_UNUSED) - return -EBUSY; + status = pb->frame_stat[vm.frame]; + if (status != GBUFFER_UNUSED) + return -EBUSY; - return vgrab(pb, &vm); + return vgrab(pb, &vm); } - + case VIDIOCGMBUF: { int i; @@ -1811,7 +1811,7 @@ chk_grab: return -EFAULT; return 0; } - + case PLANBIOCGSAAREGS: { struct planb_saa_regs preg; @@ -1828,7 +1828,7 @@ chk_grab: return -EFAULT; return 0; } - + case PLANBIOCSSAAREGS: { struct planb_saa_regs preg; @@ -1842,7 +1842,7 @@ chk_grab: saa_set (preg.addr, preg.val, pb); return 0; } - + case PLANBIOCGSTAT: { struct planb_stat_regs pstat; @@ -1859,7 +1859,7 @@ chk_grab: return -EFAULT; return 0; } - + case PLANBIOCSMODE: { int v; @@ -1985,10 +1985,10 @@ static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, cons { int i; struct planb *pb = (struct planb *)dev; - unsigned long start = (unsigned long)adr; + unsigned long start = (unsigned long)adr; if (size > MAX_GBUFFERS * PLANB_MAX_FBUF) - return -EINVAL; + return -EINVAL; if (!pb->rawbuf) { int err; if((err=grabbuf_alloc(pb))) @@ -2067,7 +2067,7 @@ static int init_planb(struct planb *pb) #endif pb->tab_size = PLANB_MAXLINES + 40; pb->suspend = 0; - mutex_init(&pb->lock); + init_MUTEX(&pb->lock); pb->ch1_cmd = 0; pb->ch2_cmd = 0; pb->mask = 0; @@ -2091,10 +2091,10 @@ static int init_planb(struct planb *pb) /* clear interrupt mask */ pb->intr_mask = PLANB_CLR_IRQ; - result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb); - if (result < 0) { - if (result==-EINVAL) - printk(KERN_ERR "PlanB: Bad irq number (%d) " + result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb); + if (result < 0) { + if (result==-EINVAL) + printk(KERN_ERR "PlanB: Bad irq number (%d) " "or handler\n", (int)pb->irq); else if (result==-EBUSY) printk(KERN_ERR "PlanB: I don't know why, " @@ -2102,7 +2102,7 @@ static int init_planb(struct planb *pb) return result; } disable_irq(pb->irq); - + /* Now add the template and register the device unit. */ memcpy(&pb->video_dev,&planb_template,sizeof(planb_template)); @@ -2143,7 +2143,7 @@ static int init_planb(struct planb *pb) } /* - * Scan for a PlanB controller, request the irq and map the io memory + * Scan for a PlanB controller, request the irq and map the io memory */ static int find_planb(void) @@ -2156,7 +2156,7 @@ static int find_planb(void) struct pci_dev *pdev; int rc; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return 0; planb_devices = find_devices("planb"); @@ -2171,9 +2171,9 @@ static int find_planb(void) pb = &planbs[0]; planb_num = 1; - if (planb_devices->n_addrs != 1) { - printk (KERN_WARNING "PlanB: expecting 1 address for planb " - "(got %d)", planb_devices->n_addrs); + if (planb_devices->n_addrs != 1) { + printk (KERN_WARNING "PlanB: expecting 1 address for planb " + "(got %d)", planb_devices->n_addrs); return 0; } @@ -2236,7 +2236,7 @@ static int find_planb(void) pb->planb_base = planb_regs; pb->planb_base_phys = (struct planb_registers *)new_base; pb->irq = irq; - + return planb_num; err_out_disable: @@ -2251,7 +2251,7 @@ static void release_planb(void) int i; struct planb *pb; - for (i=0;i - * - pms_capture: report back -EFAULT + * - pms_capture: report back -EFAULT */ #include @@ -30,8 +30,6 @@ #include #include #include -#include - #include @@ -46,7 +44,7 @@ struct pms_device struct video_picture picture; int height; int width; - struct mutex lock; + struct semaphore lock; }; struct i2c_info @@ -66,14 +64,14 @@ static int standard = 0; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ /* * I/O ports and Shared Memory */ - + static int io_port = 0x250; static int data_port = 0x251; static int mem_base = 0xC8000; static void __iomem *mem; static int video_nr = -1; - + static inline void mvv_write(u8 index, u8 value) { @@ -90,9 +88,9 @@ static int pms_i2c_stat(u8 slave) { int counter; int i; - + outb(0x28, io_port); - + counter=0; while((inb(data_port)&0x01)==0) if(counter++==256) @@ -101,9 +99,9 @@ static int pms_i2c_stat(u8 slave) while((inb(data_port)&0x01)!=0) if(counter++==256) break; - + outb(slave, io_port); - + counter=0; while((inb(data_port)&0x01)==0) if(counter++==256) @@ -112,7 +110,7 @@ static int pms_i2c_stat(u8 slave) while((inb(data_port)&0x01)!=0) if(counter++==256) break; - + for(i=0;i<12;i++) { char st=inb(data_port); @@ -122,7 +120,7 @@ static int pms_i2c_stat(u8 slave) break; } outb(0x29, io_port); - return inb(data_port); + return inb(data_port); } static int pms_i2c_write(u16 slave, u16 sub, u16 data) @@ -130,19 +128,19 @@ static int pms_i2c_write(u16 slave, u16 sub, u16 data) int skip=0; int count; int i; - + for(i=0;i255) @@ -167,9 +165,9 @@ static int pms_i2c_write(u16 slave, u16 sub, u16 data) while((inb(data_port)&1)!=0) if(count>255) break; - + count=inb(data_port); - + if(count&2) return -1; return count; @@ -189,8 +187,8 @@ static int pms_i2c_read(int slave, int sub) static void pms_i2c_andor(int slave, int sub, int and, int or) { - u8 tmp; - + u8 tmp; + tmp=pms_i2c_read(slave, sub); tmp = (tmp&and)|or; pms_i2c_write(slave, sub, tmp); @@ -199,7 +197,7 @@ static void pms_i2c_andor(int slave, int sub, int and, int or) /* * Control functions */ - + static void pms_videosource(short source) { @@ -234,8 +232,8 @@ static void pms_colour(short colour) break; } } - - + + static void pms_contrast(short contrast) { switch(decoder) @@ -269,14 +267,14 @@ static void pms_format(short format) { int target; standard = format; - + if(decoder==PHILIPS1) target=0x42; else if(decoder==PHILIPS2) target=0x8A; else return; - + switch(format) { case 0: /* Auto */ @@ -302,7 +300,7 @@ static void pms_format(short format) /* * These features of the PMS card are not currently exposes. They - * could become a private v4l ioctl for PMSCONFIG or somesuch if + * could become a private v4l ioctl for PMSCONFIG or somesuch if * people need it. We also don't yet use the PMS interrupt. */ @@ -324,7 +322,7 @@ static void pms_hstart(short start) /* * Bandpass filters */ - + static void pms_bandpass(short pass) { if(decoder==PHILIPS2) @@ -493,7 +491,7 @@ static void pms_vert(u8 deciden, u8 decinum) /* * Turn 16bit ratios into best small ratio the chipset can grok */ - + static void pms_vertdeci(unsigned short decinum, unsigned short deciden) { /* Knock it down by /5 once */ @@ -546,7 +544,7 @@ static void pms_horzdeci(short decinum, short deciden) decinum=512; deciden=640; /* 768 would be ideal */ } - + while(((decinum|deciden)&1)==0) { decinum>>=1; @@ -559,7 +557,7 @@ static void pms_horzdeci(short decinum, short deciden) } if(deciden==32) deciden--; - + mvv_write(0x24, 0x80|deciden); mvv_write(0x25, decinum); } @@ -567,14 +565,14 @@ static void pms_horzdeci(short decinum, short deciden) static void pms_resolution(short width, short height) { int fg_height; - + fg_height=height; if(fg_height>280) fg_height=280; - + mvv_write(0x18, fg_height); mvv_write(0x19, fg_height>>8); - + if(standard==1) { mvv_write(0x1A, 0xFC); @@ -598,7 +596,7 @@ static void pms_resolution(short width, short height) mvv_write(0x42, 0x00); mvv_write(0x43, 0x00); mvv_write(0x44, MVVMEMORYWIDTH); - + mvv_write(0x22, width+8); mvv_write(0x23, (width+8)>> 8); @@ -618,7 +616,7 @@ static void pms_resolution(short width, short height) /* * Set Input */ - + static void pms_vcrinput(short input) { if(decoder==PHILIPS2) @@ -643,20 +641,20 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */ /* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */ - - for (y = 0; y < dev->height; y++ ) + + for (y = 0; y < dev->height; y++ ) { writeb(0, mem); /* synchronisiert neue Zeile */ - + /* * This is in truth a fifo, be very careful as if you * forgot this odd things will occur 8) */ - + memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */ cnt -= dev->height; - while (cnt <= 0) - { + while (cnt <= 0) + { /* * Don't copy too far */ @@ -666,7 +664,7 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int cnt += dev->height; if (copy_to_user(buf, tmp+32, dt)) return len ? len : -EFAULT; - buf += dt; + buf += dt; len += dt; } } @@ -683,7 +681,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, { struct video_device *dev = video_devdata(file); struct pms_device *pd=(struct pms_device *)dev; - + switch(cmd) { case VIDIOCGCAP: @@ -726,10 +724,10 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, struct video_channel *v = arg; if(v->channel<0 || v->channel>3) return -EINVAL; - mutex_lock(&pd->lock); + down(&pd->lock); pms_videosource(v->channel&1); pms_vcrinput(v->channel>>1); - mutex_unlock(&pd->lock); + up(&pd->lock); return 0; } case VIDIOCGTUNER: @@ -763,7 +761,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, struct video_tuner *v = arg; if(v->tuner) return -EINVAL; - mutex_lock(&pd->lock); + down(&pd->lock); switch(v->mode) { case VIDEO_MODE_AUTO: @@ -787,10 +785,10 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, pms_format(2); break; default: - mutex_unlock(&pd->lock); + up(&pd->lock); return -EINVAL; } - mutex_unlock(&pd->lock); + up(&pd->lock); return 0; } case VIDIOCGPICT: @@ -806,17 +804,17 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15))) return -EINVAL; pd->picture= *p; - + /* * Now load the card. */ - mutex_lock(&pd->lock); + down(&pd->lock); pms_brightness(p->brightness>>8); pms_hue(p->hue>>8); pms_colour(p->colour>>8); - pms_contrast(p->contrast>>8); - mutex_unlock(&pd->lock); + pms_contrast(p->contrast>>8); + up(&pd->lock); return 0; } case VIDIOCSWIN: @@ -832,9 +830,9 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; pd->width=vw->width; pd->height=vw->height; - mutex_lock(&pd->lock); + down(&pd->lock); pms_resolution(pd->width, pd->height); - mutex_unlock(&pd->lock); /* Ok we figured out what to use from our wide choice */ + up(&pd->lock); /* Ok we figured out what to use from our wide choice */ return 0; } case VIDIOCGWIN: @@ -873,10 +871,10 @@ static ssize_t pms_read(struct file *file, char __user *buf, struct video_device *v = video_devdata(file); struct pms_device *pd=(struct pms_device *)v; int len; - - mutex_lock(&pd->lock); + + down(&pd->lock); len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count); - mutex_unlock(&pd->lock); + up(&pd->lock); return len; } @@ -905,13 +903,13 @@ static struct pms_device pms_device; /* * Probe for and initialise the Mediavision PMS */ - + static int init_mediavision(void) { int id; int idec, decst; int i; - + unsigned char i2c_defs[]={ 0x4C,0x30,0x00,0xE8, 0xB6,0xE2,0x00,0x00, @@ -925,7 +923,7 @@ static int init_mediavision(void) mem = ioremap(mem_base, 0x800); if (!mem) return -ENOMEM; - + if (!request_region(0x9A01, 1, "Mediavision PMS config")) { printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n"); @@ -941,18 +939,18 @@ static int init_mediavision(void) } outb(0xB8, 0x9A01); /* Unlock */ outb(io_port>>4, 0x9A01); /* Set IO port */ - - + + id=mvv_read(3); decst=pms_i2c_stat(0x43); - + if(decst!=-1) idec=2; else if(pms_i2c_stat(0xb9)!=-1) idec=3; else if(pms_i2c_stat(0x8b)!=-1) idec=1; - else + else idec=0; printk(KERN_INFO "PMS type is %d\n", idec); @@ -966,11 +964,11 @@ static int init_mediavision(void) /* * Ok we have a PMS of some sort */ - + mvv_write(0x04, mem_base>>12); /* Set the memory area */ - + /* Ok now load the defaults */ - + for(i=0;i<0x19;i++) { if(i2c_defs[i]==0xFF) @@ -978,7 +976,7 @@ static int init_mediavision(void) else pms_i2c_write(0x8A, i, i2c_defs[i]); } - + pms_i2c_write(0xB8,0x00,0x12); pms_i2c_write(0xB8,0x04,0x00); pms_i2c_write(0xB8,0x07,0x00); @@ -987,18 +985,18 @@ static int init_mediavision(void) pms_i2c_write(0xB8,0x0A,0x00); pms_i2c_write(0xB8,0x0B,0x10); pms_i2c_write(0xB8,0x10,0x03); - + mvv_write(0x01, 0x00); mvv_write(0x05, 0xA0); mvv_write(0x08, 0x25); mvv_write(0x09, 0x00); - mvv_write(0x0A, 0x20|MVVMEMORYWIDTH); - + mvv_write(0x0A, 0x20|MVVMEMORYWIDTH); + mvv_write(0x10, 0x02); mvv_write(0x1E, 0x0C); mvv_write(0x1F, 0x03); mvv_write(0x26, 0x06); - + mvv_write(0x2B, 0x00); mvv_write(0x2C, 0x20); mvv_write(0x2D, 0x00); @@ -1018,20 +1016,20 @@ static int init_mediavision(void) /* * Initialization and module stuff */ - + static int __init init_pms_cards(void) { printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n"); - + data_port = io_port +1; - + if(init_mediavision()) { printk(KERN_INFO "Board not found.\n"); return -ENODEV; } memcpy(&pms_device, &pms_template, sizeof(pms_template)); - mutex_init(&pms_device.lock); + init_MUTEX(&pms_device.lock); pms_device.height=240; pms_device.width=320; pms_swsense(75); diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig deleted file mode 100644 index 53cbc950f..000000000 --- a/drivers/media/video/pwc/Kconfig +++ /dev/null @@ -1,28 +0,0 @@ -config USB_PWC - tristate "USB Philips Cameras" - depends on USB && VIDEO_V4L1 - ---help--- - Say Y or M here if you want to use one of these Philips & OEM - webcams: - * Philips PCA645, PCA646 - * Philips PCVC675, PCVC680, PCVC690 - * Philips PCVC720/40, PCVC730, PCVC740, PCVC750 - * Askey VC010 - * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro' - and 'Orbit'/'Sphere' - * Samsung MPC-C10, MPC-C30 - * Creative Webcam 5, Pro Ex - * SOTEC Afina Eye - * Visionite VCS-UC300, VCS-UM100 - - The PCA635, PCVC665 and PCVC720/20 are not supported by this driver - and never will be, but the 665 and 720/20 are supported by other - drivers. - - See for more information and - installation instructions. - - The built-in microphone is enabled by selecting USB Audio support. - - To compile this driver as a module, choose M here: the - module will be called pwc. diff --git a/drivers/media/video/pwc/Makefile b/drivers/media/video/pwc/Makefile deleted file mode 100644 index 33d60126c..000000000 --- a/drivers/media/video/pwc/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o - -obj-$(CONFIG_USB_PWC) += pwc.o diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/video/pwc/pwc-kiara.c deleted file mode 100644 index 4c96037f7..000000000 --- a/drivers/media/video/pwc/pwc-kiara.c +++ /dev/null @@ -1,318 +0,0 @@ -/* Linux driver for Philips webcam - (C) 2004 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - -/* This tables contains entries for the 730/740/750 (Kiara) camera, with - 4 different qualities (no compression, low, medium, high). - It lists the bandwidth requirements for said mode by its alternate interface - number. An alternate of 0 means that the mode is unavailable. - - There are 6 * 4 * 4 entries: - 6 different resolutions subqcif, qsif, qcif, sif, cif, vga - 6 framerates: 5, 10, 15, 20, 25, 30 - 4 compression modi: none, low, medium, high - - When an uncompressed mode is not available, the next available compressed mode - will be chosen (unless the decompressor is absent). Sometimes there are only - 1 or 2 compressed modes available; in that case entries are duplicated. -*/ - - -#include "pwc-kiara.h" -#include "pwc-uncompress.h" - -const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] = -{ - /* SQCIF */ - { - /* 5 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 10 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 15 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, - /* QSIF */ - { - /* 5 fps */ - { - {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, - {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, - {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, - {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, - }, - /* 10 fps */ - { - {2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}}, - {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, - {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, - {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, - }, - /* 15 fps */ - { - {3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}}, - {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}}, - {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}}, - {1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}}, - }, - /* 20 fps */ - { - {4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}}, - {3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}}, - {2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}}, - {1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}}, - }, - /* 25 fps */ - { - {5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}}, - {3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}}, - {2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}}, - {1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}}, - }, - /* 30 fps */ - { - {8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}}, - {5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}}, - {3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}}, - {2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}}, - }, - }, - /* QCIF */ - { - /* 5 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 10 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 15 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, - /* SIF */ - { - /* 5 fps */ - { - {4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}}, - {3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}}, - {2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}}, - {1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}}, - }, - /* 10 fps */ - { - {0, }, - {6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}}, - {3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}}, - {2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}}, - }, - /* 15 fps */ - { - {0, }, - {9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}}, - {4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}}, - {3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}}, - }, - /* 20 fps */ - { - {0, }, - {9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}}, - {5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}}, - {3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}}, - }, - /* 25 fps */ - { - {0, }, - {9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}}, - {6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}}, - {4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}}, - }, - /* 30 fps */ - { - {0, }, - {9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}}, - {6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}}, - {4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}}, - }, - }, - /* CIF */ - { - /* 5 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 10 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 15 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, - /* VGA */ - { - /* 5 fps */ - { - {0, }, - {6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}}, - {4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}}, - {3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}}, - }, - /* 10 fps */ - { - {0, }, - {9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}}, - {6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}}, - {4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}}, - }, - /* 15 fps */ - { - {0, }, - {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}}, - {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}}, - {8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}}, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, -}; - diff --git a/drivers/media/video/pwc/pwc-timon.c b/drivers/media/video/pwc/pwc-timon.c deleted file mode 100644 index 175250d08..000000000 --- a/drivers/media/video/pwc/pwc-timon.c +++ /dev/null @@ -1,316 +0,0 @@ -/* Linux driver for Philips webcam - (C) 2004 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - -/* This tables contains entries for the 675/680/690 (Timon) camera, with - 4 different qualities (no compression, low, medium, high). - It lists the bandwidth requirements for said mode by its alternate interface - number. An alternate of 0 means that the mode is unavailable. - - There are 6 * 4 * 4 entries: - 6 different resolutions subqcif, qsif, qcif, sif, cif, vga - 6 framerates: 5, 10, 15, 20, 25, 30 - 4 compression modi: none, low, medium, high - - When an uncompressed mode is not available, the next available compressed mode - will be chosen (unless the decompressor is absent). Sometimes there are only - 1 or 2 compressed modes available; in that case entries are duplicated. -*/ - -#include "pwc-timon.h" - -const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = -{ - /* SQCIF */ - { - /* 5 fps */ - { - {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, - {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, - {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, - {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, - }, - /* 10 fps */ - { - {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, - {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, - {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, - {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, - }, - /* 15 fps */ - { - {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, - {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, - {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, - {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, - }, - /* 20 fps */ - { - {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, - {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, - {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, - {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, - }, - /* 25 fps */ - { - {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, - {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, - {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, - {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, - }, - /* 30 fps */ - { - {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, - {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, - {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, - {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, - }, - }, - /* QSIF */ - { - /* 5 fps */ - { - {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, - {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, - {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, - {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, - }, - /* 10 fps */ - { - {2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}}, - {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, - {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, - {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, - }, - /* 15 fps */ - { - {3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}}, - {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, - {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, - {1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, - }, - /* 20 fps */ - { - {4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}}, - {3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, - {1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}}, - }, - /* 25 fps */ - { - {5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}}, - {3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, - {1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}}, - }, - /* 30 fps */ - { - {8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}}, - {5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}}, - {3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}}, - {2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}}, - }, - }, - /* QCIF */ - { - /* 5 fps */ - { - {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, - {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, - {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, - {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, - }, - /* 10 fps */ - { - {3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}}, - {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, - {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, - {1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}}, - }, - /* 15 fps */ - { - {4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}}, - {3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}}, - {1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}}, - }, - /* 20 fps */ - { - {6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}}, - {4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}}, - {3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}}, - }, - /* 25 fps */ - { - {9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}}, - {5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}}, - {3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, - }, - /* 30 fps */ - { - {0, }, - {9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}}, - {4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}}, - {2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}}, - }, - }, - /* SIF */ - { - /* 5 fps */ - { - {4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}}, - {3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}}, - {2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}}, - {1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}}, - }, - /* 10 fps */ - { - {0, }, - {6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}}, - {3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}}, - {2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}}, - }, - /* 15 fps */ - { - {0, }, - {9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}}, - {4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}}, - {3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}}, - }, - /* 20 fps */ - { - {0, }, - {9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}}, - {5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}}, - {3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}}, - }, - /* 25 fps */ - { - {0, }, - {9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}}, - {6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}}, - {4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}}, - }, - /* 30 fps */ - { - {0, }, - {9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}}, - {6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}}, - {4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}}, - }, - }, - /* CIF */ - { - /* 5 fps */ - { - {6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}}, - {4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}}, - {2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}}, - {1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}}, - }, - /* 10 fps */ - { - {0, }, - {9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}}, - {4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}}, - {2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}}, - }, - /* 15 fps */ - { - {0, }, - {9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}}, - {5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}}, - {3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}}, - }, - /* 20 fps */ - { - {0, }, - {9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}}, - {6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}}, - {4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}}, - }, - /* 25 fps */ - { - {0, }, - {9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}}, - {7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}}, - {5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}}, - }, - /* 30 fps */ - { - {0, }, - {9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}}, - {7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}}, - {6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}}, - }, - }, - /* VGA */ - { - /* 5 fps */ - { - {0, }, - {6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}}, - {4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}}, - {3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}}, - }, - /* 10 fps */ - { - {0, }, - {9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}}, - {6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}}, - {4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}}, - }, - /* 15 fps */ - { - {0, }, - {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}}, - {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}}, - {8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}}, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, -}; - diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index dd830e0e5..2ce010201 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -46,8 +46,6 @@ #include #include #include -#include - #include "saa5246a.h" MODULE_AUTHOR("Michael Geng "); @@ -59,7 +57,7 @@ struct saa5246a_device u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; int is_searching[NUM_DAUS]; struct i2c_client *client; - struct mutex lock; + struct semaphore lock; }; static struct video_device saa_template; /* Declared near bottom */ @@ -92,7 +90,7 @@ static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind) return -ENOMEM; } strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); - mutex_init(&t->lock); + init_MUTEX(&t->lock); /* * Now create a video4linux device @@ -721,9 +719,9 @@ static int saa5246a_ioctl(struct inode *inode, struct file *file, int err; cmd = vtx_fix_command(cmd); - mutex_lock(&t->lock); + down(&t->lock); err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl); - mutex_unlock(&t->lock); + up(&t->lock); return err; } diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 531e9461c..5694eb58c 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -56,8 +56,6 @@ #include #include #include -#include - #include #include @@ -71,7 +69,7 @@ #define NUM_BUFS 8 #define IF_NAME "SAA5249" -static const int disp_modes[8][3] = +static const int disp_modes[8][3] = { { 0x46, 0x03, 0x03 }, /* DISPOFF */ { 0x46, 0xcc, 0xcc }, /* DISPNORM */ @@ -107,7 +105,7 @@ struct saa5249_device int disp_mode; int virtual_mode; struct i2c_client *client; - struct mutex lock; + struct semaphore lock; }; @@ -150,8 +148,8 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) client=kmalloc(sizeof(*client), GFP_KERNEL); if(client==NULL) return -ENOMEM; - client_template.adapter = adap; - client_template.addr = addr; + client_template.adapter = adap; + client_template.addr = addr; memcpy(client, &client_template, sizeof(*client)); t = kzalloc(sizeof(*t), GFP_KERNEL); if(t==NULL) @@ -160,12 +158,12 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) return -ENOMEM; } strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); - mutex_init(&t->lock); - + init_MUTEX(&t->lock); + /* * Now create a video4linux device */ - + vd = kmalloc(sizeof(struct video_device), GFP_KERNEL); if(vd==NULL) { @@ -175,8 +173,8 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) } i2c_set_clientdata(client, vd); memcpy(vd, &saa_template, sizeof(*vd)); - - for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) + + for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); @@ -186,9 +184,9 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) t->vdau[pgbuf].stopped = TRUE; t->is_searching[pgbuf] = FALSE; } - vd->priv=t; - - + vd->priv=t; + + /* * Register it */ @@ -208,7 +206,7 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) /* * We do most of the hard work when we become a device on the i2c. */ - + static int saa5249_probe(struct i2c_adapter *adap) { if (adap->class & I2C_CLASS_TV_ANALOG) @@ -229,7 +227,7 @@ static int saa5249_detach(struct i2c_client *client) /* new I2C driver support */ -static struct i2c_driver i2c_driver_videotext = +static struct i2c_driver i2c_driver_videotext = { .driver = { .name = IF_NAME, /* name */ @@ -249,7 +247,7 @@ static struct i2c_client client_template = { * delay may be longer. */ -static void jdelay(unsigned long delay) +static void jdelay(unsigned long delay) { sigset_t oldblocked = current->blocked; @@ -269,14 +267,14 @@ static void jdelay(unsigned long delay) /* * I2C interfaces */ - -static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data) + +static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data) { char buf[64]; - + buf[0] = reg; memcpy(buf+1, data, count); - + if(i2c_master_send(t->client, buf, count+1)==count+1) return 0; return -1; @@ -289,7 +287,7 @@ static int i2c_senddata(struct saa5249_device *t, ...) int ct=0; va_list argp; va_start(argp,t); - + while((v=va_arg(argp,int))!=-1) buf[ct++]=v; return i2c_sendbuf(t, buf[0], ct-1, buf+1); @@ -301,7 +299,7 @@ static int i2c_senddata(struct saa5249_device *t, ...) * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise */ -static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) +static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) { if(i2c_master_recv(t->client, buf, count)!=count) return -1; @@ -320,9 +318,9 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, struct video_device *vd = video_devdata(file); struct saa5249_device *t=vd->priv; - switch(cmd) + switch(cmd) { - case VTXIOCGETINFO: + case VTXIOCGETINFO: { vtx_info_t *info = arg; info->version_major = VTX_VER_MAJ; @@ -332,10 +330,10 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return 0; } - case VTXIOCCLRPAGE: + case VTXIOCCLRPAGE: { vtx_pagereq_t *req = arg; - + if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) return -EINVAL; memset(t->vdau[req->pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); @@ -343,17 +341,17 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return 0; } - case VTXIOCCLRFOUND: + case VTXIOCCLRFOUND: { vtx_pagereq_t *req = arg; - + if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) return -EINVAL; t->vdau[req->pgbuf].clrfound = TRUE; return 0; } - case VTXIOCPAGEREQ: + case VTXIOCPAGEREQ: { vtx_pagereq_t *req = arg; if (!(req->pagemask & PGMASK_PAGE)) @@ -381,7 +379,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return 0; } - case VTXIOCGETSTAT: + case VTXIOCGETSTAT: { vtx_pagereq_t *req = arg; u8 infobits[10]; @@ -390,7 +388,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) return -EINVAL; - if (!t->vdau[req->pgbuf].stopped) + if (!t->vdau[req->pgbuf].stopped) { if (i2c_senddata(t, 2, 0, -1) || i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req->pgbuf].sregs) || @@ -403,7 +401,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return -EIO; if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */ - (memcmp(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)) || + (memcmp(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)) || time_after_eq(jiffies, t->vdau[req->pgbuf].expire))) { /* check if new page arrived */ if (i2c_senddata(t, 8, 0, 0, 0, -1) || @@ -411,7 +409,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return -EIO; t->vdau[req->pgbuf].expire = jiffies + PGBUF_EXPIRE; memset(t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE); - if (t->virtual_mode) + if (t->virtual_mode) { /* Packet X/24 */ if (i2c_senddata(t, 8, 0, 0x20, 0, -1) || @@ -459,9 +457,9 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, info.notfound = !!(infobits[8] & 0x10); info.pblf = !!(infobits[9] & 0x20); info.hamming = 0; - for (a = 0; a <= 7; a++) + for (a = 0; a <= 7; a++) { - if (infobits[a] & 0xf0) + if (infobits[a] & 0xf0) { info.hamming = 1; break; @@ -471,14 +469,14 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, info.notfound = 1; if(copy_to_user(req->buffer, &info, sizeof(vtx_pageinfo_t))) return -EFAULT; - if (!info.hamming && !info.notfound) + if (!info.hamming && !info.notfound) { t->is_searching[req->pgbuf] = FALSE; } return 0; } - case VTXIOCGETPAGE: + case VTXIOCGETPAGE: { vtx_pagereq_t *req = arg; int start, end; @@ -488,15 +486,15 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return -EINVAL; if(copy_to_user(req->buffer, &t->vdau[req->pgbuf].pgbuf[req->start], req->end - req->start + 1)) return -EFAULT; - - /* + + /* * Always read the time directly from SAA5249 */ - - if (req->start <= 39 && req->end >= 32) + + if (req->start <= 39 && req->end >= 32) { int len; - char buf[16]; + char buf[16]; start = max(req->start, 32); end = min(req->end, 39); len=end-start+1; @@ -507,7 +505,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return -EFAULT; } /* Insert the current header if DAU is still searching for a page */ - if (req->start <= 31 && req->end >= 7 && t->is_searching[req->pgbuf]) + if (req->start <= 31 && req->end >= 7 && t->is_searching[req->pgbuf]) { char buf[32]; int len; @@ -523,7 +521,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return 0; } - case VTXIOCSTOPDAU: + case VTXIOCSTOPDAU: { vtx_pagereq_t *req = arg; @@ -534,12 +532,12 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return 0; } - case VTXIOCPUTPAGE: - case VTXIOCSETDISP: - case VTXIOCPUTSTAT: + case VTXIOCPUTPAGE: + case VTXIOCSETDISP: + case VTXIOCPUTSTAT: return 0; - - case VTXIOCCLRCACHE: + + case VTXIOCCLRCACHE: { if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11, ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', @@ -551,7 +549,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return 0; } - case VTXIOCSETVIRT: + case VTXIOCSETVIRT: { /* The SAA5249 has virtual-row reception turned on always */ t->virtual_mode = (int)(long)arg; @@ -612,22 +610,22 @@ static inline unsigned int vtx_fix_command(unsigned int cmd) /* * Handle the locking */ - + static int saa5249_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { struct video_device *vd = video_devdata(file); struct saa5249_device *t=vd->priv; int err; - + cmd = vtx_fix_command(cmd); - mutex_lock(&t->lock); + down(&t->lock); err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl); - mutex_unlock(&t->lock); + up(&t->lock); return err; } -static int saa5249_open(struct inode *inode, struct file *file) +static int saa5249_open(struct inode *inode, struct file *file) { struct video_device *vd = video_devdata(file); struct saa5249_device *t=vd->priv; @@ -636,7 +634,7 @@ static int saa5249_open(struct inode *inode, struct file *file) err = video_exclusive_open(inode,file); if (err < 0) return err; - + if (t->client==NULL) { err = -ENODEV; goto fail; @@ -647,13 +645,13 @@ static int saa5249_open(struct inode *inode, struct file *file) i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) || /* Display TV-picture, no virtual rows */ i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */ - + { err = -EIO; goto fail; } - for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) + for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); @@ -673,7 +671,7 @@ static int saa5249_open(struct inode *inode, struct file *file) -static int saa5249_release(struct inode *inode, struct file *file) +static int saa5249_release(struct inode *inode, struct file *file) { struct video_device *vd = video_devdata(file); struct saa5249_device *t=vd->priv; @@ -690,7 +688,7 @@ static int __init init_saa_5249 (void) return i2c_add_driver(&i2c_driver_videotext); } -static void __exit cleanup_saa_5249 (void) +static void __exit cleanup_saa_5249 (void) { i2c_del_driver(&i2c_driver_videotext); } diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index a81285ca7..d17395c4f 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c @@ -32,7 +32,7 @@ #include -#include +#include "rds.h" /* Addresses to scan */ static unsigned short normal_i2c[] = { diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 41d951db6..7bb85a7b3 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c @@ -39,6 +39,7 @@ MODULE_AUTHOR("Pauline Middelink"); MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(s) (s)->name @@ -107,8 +108,13 @@ saa7110_write_block (struct i2c_client *client, * the adapter understands raw I2C */ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { struct saa7110 *decoder = i2c_get_clientdata(client); + struct i2c_msg msg; - ret = i2c_master_send(client, data, len); + msg.len = len; + msg.buf = (char *) data; + msg.addr = client->addr; + msg.flags = 0; + ret = i2c_transfer(client->adapter, &msg, 1); /* Cache the written data */ memcpy(decoder->reg + reg, data + 1, len - 1); @@ -139,7 +145,7 @@ saa7110_read (struct i2c_client *client) static int saa7110_selmux (struct i2c_client *client, - int chan) + int chan) { static const unsigned char modes[9][8] = { /* mode 0 */ @@ -426,13 +432,15 @@ saa7110_command (struct i2c_client *client, break; case DECODER_DUMP: - for (v = 0; v < SAA7110_NR_REG; v += 16) { + for (v = 0; v < 0x34; v += 16) { int j; - dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client), + dprintk(1, KERN_INFO "%s: %03x\n", I2C_NAME(client), v); - for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) - dprintk(1, " %02x", decoder->reg[v + j]); - dprintk(1, "\n"); + for (j = 0; j < 16; j++) { + dprintk(1, KERN_INFO " %02x", + decoder->reg[v + j]); + } + dprintk(1, KERN_INFO "\n"); } break; @@ -457,7 +465,7 @@ static unsigned short normal_i2c[] = { }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 686fd4746..8c06592b3 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -1,4 +1,4 @@ -/* +/* * saa7111 - Philips SAA7111A video decoder driver version 0.0.3 * * Copyright (C) 1998 Dave Perks @@ -52,6 +52,7 @@ MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(s) (s)->name @@ -69,10 +70,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ -#define SAA7111_NR_REG 0x18 - struct saa7111 { - unsigned char reg[SAA7111_NR_REG]; + unsigned char reg[32]; int norm; int input; @@ -111,21 +110,24 @@ saa7111_write_block (struct i2c_client *client, if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ struct saa7111 *decoder = i2c_get_clientdata(client); + struct i2c_msg msg; u8 block_data[32]; - int block_len; + msg.addr = client->addr; + msg.flags = 0; while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; + msg.buf = (char *) block_data; + msg.len = 0; + block_data[msg.len++] = reg = data[0]; do { - block_data[block_len++] = + block_data[msg.len++] = decoder->reg[reg++] = data[1]; len -= 2; data += 2; } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + msg.len < 32); + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { @@ -208,7 +210,6 @@ saa7111_command (struct i2c_client *client, switch (cmd) { case 0: - break; case DECODER_INIT: { struct video_decoder_init *init = arg; @@ -226,11 +227,11 @@ saa7111_command (struct i2c_client *client, { int i; - for (i = 0; i < SAA7111_NR_REG; i += 16) { + for (i = 0; i < 32; i += 16) { int j; printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); - for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { + for (j = 0; j < 16; ++j) { printk(" %02x", saa7111_read(client, i + j)); } @@ -482,7 +483,7 @@ saa7111_command (struct i2c_client *client, static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index 90398ab82..fd0a4b4ef 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c @@ -1,4 +1,4 @@ -/* +/* * saa7114 - Philips SAA7114H video decoder driver version 0.0.1 * * Copyright (C) 2002 Maxim Yevtyushkin @@ -55,6 +55,7 @@ MODULE_AUTHOR("Maxim Yevtyushkin"); MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(x) (x)->name @@ -138,6 +139,9 @@ saa7114_write (struct i2c_client *client, u8 reg, u8 value) { + /*struct saa7114 *decoder = i2c_get_clientdata(client);*/ + + /*decoder->reg[reg] = value;*/ return i2c_smbus_write_byte_data(client, reg, value); } @@ -153,21 +157,25 @@ saa7114_write_block (struct i2c_client *client, * the adapter understands raw I2C */ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ + /*struct saa7114 *decoder = i2c_get_clientdata(client);*/ + struct i2c_msg msg; u8 block_data[32]; - int block_len; + msg.addr = client->addr; + msg.flags = 0; while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; + msg.buf = (char *) block_data; + msg.len = 0; + block_data[msg.len++] = reg = data[0]; do { - block_data[block_len++] = data[1]; - reg++; + block_data[msg.len++] = + /*decoder->reg[reg++] =*/ data[1]; len -= 2; data += 2; } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + msg.len < 32); + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { @@ -300,7 +308,7 @@ static const unsigned char init[] = { 0x55, 0xff, 0x56, 0xff, 0x57, 0xff, - 0x58, 0x40, // framing code + 0x58, 0x40, // framing code 0x59, 0x47, // horizontal offset 0x5a, 0x06, // vertical offset 0x5b, 0x83, // field offset @@ -345,7 +353,7 @@ static const unsigned char init[] = { 0x82, 0x00, 0x83, 0x00, 0x84, 0xc5, - 0x85, 0x0d, // hsync and vsync ? + 0x85, 0x0d, // hsync and vsync ? 0x86, 0x40, 0x87, 0x01, 0x88, 0x00, @@ -434,7 +442,7 @@ static const unsigned char init[] = { 0xd9, 0x04, 0xda, 0x00, // horizontal luminance phase offset 0xdb, 0x00, - 0xdc, 0x00, // horizontal chrominance scaling increment + 0xdc, 0x00, // horizontal chrominance scaling increment 0xdd, 0x02, 0xde, 0x00, // horizontal chrominance phase offset 0xdf, 0x00, @@ -754,7 +762,7 @@ saa7114_command (struct i2c_client *client, saa7114_write(client, 0x87, decoder->reg[REG_ADDR(0x87)]); saa7114_write(client, 0x88, 0xd8); // sw reset scaler - saa7114_write(client, 0x88, 0xf8); // sw reset scaler release + saa7114_write(client, 0x88, 0xf8); // sw reset scaler release saa7114_write(client, 0x80, 0x36); } @@ -813,7 +821,7 @@ static unsigned short normal_i2c[] = { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index dceebc0b1..ffd87ce55 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1,4 +1,4 @@ -/* saa7115 - Philips SAA7113/SAA7114/SAA7115 video decoder driver +/* saa7115 - Philips SAA7114/SAA7115 video decoder driver * * Based on saa7114 driver by Maxim Yevtyushkin, which is based on * the saa7111 driver by Dave Perks. @@ -16,7 +16,6 @@ * (2/17/2003) * * VBI support (2004) and cleanups (2005) by Hans Verkuil - * SAA7113 support by Mauro Carvalho Chehab * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -40,12 +39,11 @@ #include #include #include -#include +#include #include -MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver"); -MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, " - "Hans Verkuil, Mauro Carvalho Chehab"); +MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver"); +MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil"); MODULE_LICENSE("GPL"); static int debug = 0; @@ -53,10 +51,7 @@ module_param(debug, bool, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -static unsigned short normal_i2c[] = { - 0x4a >> 1, 0x48 >> 1, /* SAA7113 */ - 0x42 >> 1, 0x40 >> 1, /* SAA7114 and SAA7115 */ - I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; @@ -106,12 +101,10 @@ static inline int saa7115_read(struct i2c_client *client, u8 reg) Hauppauge driver sets. */ static const unsigned char saa7115_init_auto_input[] = { - /* Front-End Part */ 0x01, 0x48, /* white peak control disabled */ 0x03, 0x20, /* was 0x30. 0x20: long vertical blanking */ 0x04, 0x90, /* analog gain set to 0 */ 0x05, 0x90, /* analog gain set to 0 */ - /* Decoder Part */ 0x06, 0xeb, /* horiz sync begin = -21 */ 0x07, 0xe0, /* horiz sync stop = -17 */ 0x0a, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */ @@ -130,8 +123,6 @@ static const unsigned char saa7115_init_auto_input[] = { 0x1b, 0x42, /* misc chroma control 0x42 = recommended */ 0x1c, 0xa9, /* combfilter control 0xA9 = recommended */ 0x1d, 0x01, /* combfilter control 0x01 = recommended */ - - /* Power Device Control */ 0x88, 0xd0, /* reset device */ 0x88, 0xf0, /* set device programmed, all in operational mode */ 0x00, 0x00 @@ -347,33 +338,6 @@ static const unsigned char saa7115_cfg_vbi_off[] = { 0x00, 0x00 }; -static const unsigned char saa7113_init_auto_input[] = { - 0x01, 0x08, /* PH7113_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */ - 0x02, 0xc2, /* PH7113_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */ - 0x03, 0x30, /* PH7113_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */ - 0x04, 0x00, /* PH7113_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */ - 0x05, 0x00, /* PH7113_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */ - 0x06, 0x89, /* PH7113_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */ - 0x07, 0x0d, /* PH7113_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */ - 0x08, 0x88, /* PH7113_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */ - 0x09, 0x01, /* PH7113_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */ - 0x0a, 0x80, /* PH7113_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */ - 0x0b, 0x47, /* PH7113_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */ - 0x0c, 0x40, /* PH7113_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */ - 0x0d, 0x00, /* PH7113_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */ - 0x0e, 0x01, /* PH7113_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */ - 0x0f, 0x2a, /* PH7113_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */ - 0x10, 0x08, /* PH7113_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */ - 0x11, 0x0c, /* PH7113_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */ - 0x12, 0x07, /* PH7113_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */ - 0x13, 0x00, /* PH7113_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */ - 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */ - 0x15, 0x00, /* PH7113_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */ - 0x16, 0x00, /* PH7113_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */ - 0x17, 0x00, /* PH7113_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */ - 0x00, 0x00 -}; - static const unsigned char saa7115_init_misc[] = { 0x38, 0x03, /* audio stuff */ 0x39, 0x10, @@ -713,35 +677,10 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std) saa7115_writeregs(client, saa7115_cfg_50hz_video); } - /* Register 0E - Bits D6-D4 on NO-AUTO mode - (SAA7113 doesn't have auto mode) - 50 Hz / 625 lines 60 Hz / 525 lines - 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz) - 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz) - 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz) - 011 NTSC N (3.58MHz) PAL M (3.58MHz) - 100 reserved NTSC-Japan (3.58MHz) - */ - if (state->ident == V4L2_IDENT_SAA7113) { - u8 reg = saa7115_read(client, 0x0e) & 0x8f; - - if (std == V4L2_STD_PAL_M) { - reg |= 0x30; - } else if (std == V4L2_STD_PAL_N) { - reg |= 0x20; - } else if (std == V4L2_STD_PAL_60) { - reg |= 0x10; - } else if (std == V4L2_STD_NTSC_M_JP) { - reg |= 0x40; - } - saa7115_write(client, 0x0e, reg); - } - - state->std = std; /* restart task B if needed */ - if (taskb && state->ident != V4L2_IDENT_SAA7115) { + if (taskb && state->ident == V4L2_IDENT_SAA7114) { saa7115_writeregs(client, saa7115_cfg_vbi_on); } @@ -764,7 +703,7 @@ static void saa7115_log_status(struct i2c_client *client) int vcr; v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq); - if (state->ident != V4L2_IDENT_SAA7115) { + if (client->name[6] == '4') { /* status for the saa7114 */ reg1f = saa7115_read(client, 0x1f); signalOk = (reg1f & 0xc1) == 0x81; @@ -812,8 +751,8 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo u8 lcr[24]; int i, x; - /* saa7113/7114 doesn't yet support VBI */ - if (state->ident != V4L2_IDENT_SAA7115) + /* saa7114 doesn't yet support VBI */ + if (state->ident == V4L2_IDENT_SAA7114) return; for (i = 0; i <= 23; i++) @@ -1181,46 +1120,6 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar state->radio = 1; break; - case VIDIOC_INT_G_VIDEO_ROUTING: - { - struct v4l2_routing *route = arg; - - route->input = state->input; - route->output = 0; - break; - } - - case VIDIOC_INT_S_VIDEO_ROUTING: - { - struct v4l2_routing *route = arg; - - v4l_dbg(1, debug, client, "decoder set input %d\n", route->input); - /* saa7113 does not have these inputs */ - if (state->ident == V4L2_IDENT_SAA7113 && - (route->input == SAA7115_COMPOSITE4 || - route->input == SAA7115_COMPOSITE5)) { - return -EINVAL; - } - if (route->input > SAA7115_SVIDEO3) - return -EINVAL; - if (state->input == route->input) - break; - v4l_dbg(1, debug, client, "now setting %s input\n", - (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite"); - state->input = route->input; - - /* select mode */ - saa7115_write(client, 0x02, - (saa7115_read(client, 0x02) & 0xf0) | - state->input); - - /* bypass chrominance trap for S-Video modes */ - saa7115_write(client, 0x09, - (saa7115_read(client, 0x09) & 0x7f) | - (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0)); - break; - } - case VIDIOC_G_INPUT: *(int *)arg = state->input; break; @@ -1362,12 +1261,14 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) saa7115_write(client, 0, 5); chip_id = saa7115_read(client, 0) & 0x0f; - if (chip_id < 3 && chip_id > 5) { + if (chip_id != 4 && chip_id != 5) { v4l_dbg(1, debug, client, "saa7115 not found\n"); kfree(client); return 0; } - snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id); + if (chip_id == 4) { + snprintf(client->name, sizeof(client->name) - 1, "saa7114"); + } v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL); @@ -1384,27 +1285,13 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) state->contrast = 64; state->hue = 0; state->sat = 64; - switch (chip_id) { - case 3: - state->ident = V4L2_IDENT_SAA7113; - break; - case 4: - state->ident = V4L2_IDENT_SAA7114; - break; - default: - state->ident = V4L2_IDENT_SAA7115; - break; - } - + state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115; state->audclk_freq = 48000; v4l_dbg(1, debug, client, "writing init values\n"); /* init to 60hz/48khz */ - if (state->ident == V4L2_IDENT_SAA7113) - saa7115_writeregs(client, saa7113_init_auto_input); - else - saa7115_writeregs(client, saa7115_init_auto_input); + saa7115_writeregs(client, saa7115_init_auto_input); saa7115_writeregs(client, saa7115_init_misc); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c index 708fae51e..6c161f2f5 100644 --- a/drivers/media/video/saa711x.c +++ b/drivers/media/video/saa711x.c @@ -45,6 +45,7 @@ MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(s) (s)->name diff --git a/drivers/media/video/saa7121.h b/drivers/media/video/saa7121.h index 66967ae37..74e37d405 100644 --- a/drivers/media/video/saa7121.h +++ b/drivers/media/video/saa7121.h @@ -64,7 +64,7 @@ #define PAL_MSB_VERTICAL 0x40 /* 7c */ /* Initialization Sequence */ - + static __u8 init7121ntsc[] = { 0x26, 0x0, 0x27, 0x0, 0x28, NTSC_BURST_START, 0x29, NTSC_BURST_END, @@ -95,7 +95,7 @@ static __u8 init7121ntsc[] = { 0x78, 0x0, 0x79, 0x0, 0x7a, NTSC_FIRST_ACTIVE, 0x7b, NTSC_LAST_ACTIVE, 0x7c, NTSC_MSB_VERTICAL, 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0 -}; +}; #define INIT7121LEN (sizeof(init7121ntsc)/2) static __u8 init7121pal[] = { @@ -128,5 +128,5 @@ static __u8 init7121pal[] = { 0x78, 0x0, 0x79, 0x0, 0x7a, PAL_FIRST_ACTIVE, 0x7b, PAL_LAST_ACTIVE, 0x7c, PAL_MSB_VERTICAL, 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0 -}; +}; #endif diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index c271e2e14..9e4c178bd 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -54,7 +54,6 @@ #include #include #include -#include static int debug = 0; static int test_image = 0; @@ -224,6 +223,22 @@ static struct i2c_reg_value saa7127_init_config_50hz[] = { { 0, 0 } }; +/* Enumeration for the Supported input types */ +enum saa7127_input_type { + SAA7127_INPUT_TYPE_NORMAL, + SAA7127_INPUT_TYPE_TEST_IMAGE +}; + +/* Enumeration for the Supported Output signal types */ +enum saa7127_output_type { + SAA7127_OUTPUT_TYPE_BOTH, + SAA7127_OUTPUT_TYPE_COMPOSITE, + SAA7127_OUTPUT_TYPE_SVIDEO, + SAA7127_OUTPUT_TYPE_RGB, + SAA7127_OUTPUT_TYPE_YUV_C, + SAA7127_OUTPUT_TYPE_YUV_V +}; + /* ********************************************************************** * @@ -547,7 +562,7 @@ static int saa7127_command(struct i2c_client *client, { struct saa7127_state *state = i2c_get_clientdata(client); struct v4l2_format *fmt = arg; - struct v4l2_routing *route = arg; + int *iarg = arg; switch (cmd) { case VIDIOC_S_STD: @@ -559,23 +574,15 @@ static int saa7127_command(struct i2c_client *client, *(v4l2_std_id *)arg = state->std; break; - case VIDIOC_INT_G_VIDEO_ROUTING: - route->input = state->input_type; - route->output = state->output_type; - break; - - case VIDIOC_INT_S_VIDEO_ROUTING: - { - int rc = 0; + case VIDIOC_S_INPUT: + if (state->input_type == *iarg) + break; + return saa7127_set_input_type(client, *iarg); - if (state->input_type != route->input) { - rc = saa7127_set_input_type(client, route->input); - } - if (rc == 0 && state->output_type != route->output) { - rc = saa7127_set_output_type(client, route->output); - } - return rc; - } + case VIDIOC_S_OUTPUT: + if (state->output_type == *iarg) + break; + return saa7127_set_output_type(client, *iarg); case VIDIOC_STREAMON: case VIDIOC_STREAMOFF: diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index be7b9ee69..1ba998424 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile @@ -11,9 +11,9 @@ obj-$(CONFIG_VIDEO_SAA7134_OSS) += saa7134-oss.o obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o -EXTRA_CFLAGS += -Idrivers/media/video -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends +EXTRA_CFLAGS += -I$(src)/.. +EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core +EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index bb3e0ba94..5f21416f2 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c @@ -71,7 +71,7 @@ MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s)."); */ typedef struct snd_card_saa7134 { - struct snd_card *card; + snd_card_t *card; spinlock_t mixer_lock; int mixer_volume[MIXER_ADDR_LAST+1][2]; int capture_source[MIXER_ADDR_LAST+1][2]; @@ -95,10 +95,10 @@ typedef struct snd_card_saa7134_pcm { spinlock_t lock; - struct snd_pcm_substream *substream; + snd_pcm_substream_t *substream; } snd_card_saa7134_pcm_t; -static struct snd_card *snd_saa7134_cards[SNDRV_CARDS]; +static snd_card_t *snd_saa7134_cards[SNDRV_CARDS]; /* @@ -251,10 +251,10 @@ out: * */ -static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream, +static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream, int cmd) { - struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_runtime_t *runtime = substream->runtime; snd_card_saa7134_pcm_t *pcm = runtime->private_data; struct saa7134_dev *dev=pcm->dev; int err = 0; @@ -308,7 +308,8 @@ static int dsp_buffer_init(struct saa7134_dev *dev) static int dsp_buffer_free(struct saa7134_dev *dev) { - BUG_ON(!dev->dmasound.blksize); + if (!dev->dmasound.blksize) + BUG(); videobuf_dma_free(&dev->dmasound.dma); @@ -332,9 +333,9 @@ static int dsp_buffer_free(struct saa7134_dev *dev) * */ -static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream) +static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) { - struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_runtime_t *runtime = substream->runtime; int bswap, sign; u32 fmt, control; snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); @@ -421,10 +422,9 @@ static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream * */ -static snd_pcm_uframes_t -snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream) +static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream) { - struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_runtime_t *runtime = substream->runtime; snd_card_saa7134_pcm_t *pcm = runtime->private_data; struct saa7134_dev *dev=pcm->dev; @@ -442,7 +442,7 @@ snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream) * ALSA hardware capabilities definition */ -static struct snd_pcm_hardware snd_card_saa7134_capture = +static snd_pcm_hardware_t snd_card_saa7134_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -465,7 +465,7 @@ static struct snd_pcm_hardware snd_card_saa7134_capture = .periods_max = 1024, }; -static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime) +static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) { snd_card_saa7134_pcm_t *pcm = runtime->private_data; @@ -482,8 +482,8 @@ static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime) * */ -static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, - struct snd_pcm_hw_params * hw_params) +static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params) { snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); struct saa7134_dev *dev; @@ -507,7 +507,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, /* release the old buffer */ if (substream->runtime->dma_area) { saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); - videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma); + videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); dsp_buffer_free(dev); substream->runtime->dma_area = NULL; } @@ -523,12 +523,12 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, return err; } - if (0 != (err = videobuf_pci_dma_map(dev->pci, &dev->dmasound.dma))) { + if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) { dsp_buffer_free(dev); return err; } if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) { - videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma); + videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); dsp_buffer_free(dev); return err; } @@ -537,7 +537,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, dev->dmasound.dma.sglen, 0))) { saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); - videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma); + videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); dsp_buffer_free(dev); return err; } @@ -562,7 +562,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, * */ -static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream) +static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) { snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); struct saa7134_dev *dev; @@ -571,7 +571,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream) if (substream->runtime->dma_area) { saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); - videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma); + videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); dsp_buffer_free(dev); substream->runtime->dma_area = NULL; } @@ -588,7 +588,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream) * */ -static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream) +static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) { return 0; } @@ -603,20 +603,20 @@ static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream) * */ -static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) +static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) { - struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_runtime_t *runtime = substream->runtime; snd_card_saa7134_pcm_t *pcm; snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); struct saa7134_dev *dev = saa7134->dev; int err; - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); dev->dmasound.read_count = 0; dev->dmasound.read_offset = 0; - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); if (pcm == NULL) @@ -641,7 +641,7 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) * ALSA capture callbacks definition */ -static struct snd_pcm_ops snd_card_saa7134_capture_ops = { +static snd_pcm_ops_t snd_card_saa7134_capture_ops = { .open = snd_card_saa7134_capture_open, .close = snd_card_saa7134_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -662,7 +662,7 @@ static struct snd_pcm_ops snd_card_saa7134_capture_ops = { static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device) { - struct snd_pcm *pcm; + snd_pcm_t *pcm; int err; if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0) @@ -680,8 +680,7 @@ static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device) .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \ .private_value = addr } -static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol, - struct snd_ctl_elem_info * uinfo) +static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; @@ -690,8 +689,7 @@ static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol, return 0; } -static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol, - struct snd_ctl_elem_value * ucontrol) +static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); int addr = kcontrol->private_value; @@ -701,8 +699,7 @@ static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol, return 0; } -static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol, - struct snd_ctl_elem_value * ucontrol) +static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); int change, addr = kcontrol->private_value; @@ -733,8 +730,7 @@ static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol, .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \ .private_value = addr } -static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol, - struct snd_ctl_elem_info * uinfo) +static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 2; @@ -743,8 +739,7 @@ static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol, return 0; } -static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol, - struct snd_ctl_elem_value * ucontrol) +static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); int addr = kcontrol->private_value; @@ -757,8 +752,7 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol, return 0; } -static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol, - struct snd_ctl_elem_value * ucontrol) +static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); int change, addr = kcontrol->private_value; @@ -835,7 +829,7 @@ static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol, return change; } -static struct snd_kcontrol_new snd_saa7134_controls[] = { +static snd_kcontrol_new_t snd_saa7134_controls[] = { SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER), SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1), @@ -854,7 +848,7 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2), static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) { - struct snd_card *card = chip->card; + snd_card_t *card = chip->card; unsigned int idx; int err; @@ -868,7 +862,7 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) return 0; } -static void snd_saa7134_free(struct snd_card * card) +static void snd_saa7134_free(snd_card_t * card) { snd_card_saa7134_t *chip = card->private_data; @@ -895,7 +889,7 @@ static void snd_saa7134_free(struct snd_card * card) static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) { - struct snd_card *card; + snd_card_t *card; snd_card_saa7134_t *chip; int err; @@ -940,7 +934,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) chip->irq = dev->pci->irq; - mutex_init(&dev->dmasound.lock); + init_MUTEX(&dev->dmasound.lock); if ((err = snd_card_saa7134_new_mixer(chip)) < 0) goto __nodev; @@ -997,9 +991,9 @@ static int saa7134_alsa_init(void) struct saa7134_dev *dev = NULL; struct list_head *list; - if (!dmasound_init && !dmasound_exit) { - dmasound_init = alsa_device_init; - dmasound_exit = alsa_device_exit; + if (!saa7134_dmasound_init && !saa7134_dmasound_exit) { + saa7134_dmasound_init = alsa_device_init; + saa7134_dmasound_exit = alsa_device_exit; } else { printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n"); return -EBUSY; @@ -1036,8 +1030,8 @@ static void saa7134_alsa_exit(void) snd_card_free(snd_saa7134_cards[idx]); } - dmasound_init = NULL; - dmasound_exit = NULL; + saa7134_dmasound_init = NULL; + saa7134_dmasound_exit = NULL; printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); return; diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 86eae3528..c328dc666 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -536,7 +536,7 @@ struct saa7134_board saa7134_boards[] = { .radio = { .name = name_radio, .amux = LINE2, - }, + }, }, [SAA7134_BOARD_MD7134] = { .name = "Medion 7134", @@ -2028,7 +2028,7 @@ struct saa7134_board saa7134_boards[] = { [SAA7134_BOARD_FLYTV_DIGIMATRIX] = { .name = "FlyTV mini Asus Digimatrix", .audio_clock = 0x00200000, - .tuner_type = TUNER_LG_TALN, + .tuner_type = TUNER_LG_NTSC_TALN_MINI, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2624,7 +2624,6 @@ struct saa7134_board saa7134_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .gpiomask = 0x00200000, - .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, /* Analog broadcast/cable TV */ .vmux = 1, @@ -2763,7 +2762,7 @@ struct saa7134_board saa7134_boards[] = { but only one of them is currently working. */ .name = "AVerMedia A169 B", .audio_clock = 0x02187de7, - .tuner_type = TUNER_LG_TALN, + .tuner_type = TUNER_LG_NTSC_TALN_MINI, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2775,7 +2774,7 @@ struct saa7134_board saa7134_boards[] = { /* Rickard Osser */ .name = "AVerMedia A169 B1", .audio_clock = 0x02187de7, - .tuner_type = TUNER_LG_TALN, + .tuner_type = TUNER_LG_NTSC_TALN_MINI, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -3491,20 +3490,18 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_KWORLD_TERMINATOR: case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: case SAA7134_BOARD_FLYDVBT_LR301: - case SAA7134_BOARD_FLYDVBTDUO: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_MD5044: printk("%s: seems there are two different versions of the MD5044\n" - "%s: (with the same ID) out there. If sound doesn't work for\n" - "%s: you try the audio_clock_override=0x200000 insmod option.\n", - dev->name,dev->name,dev->name); + "%s: (with the same ID) out there. If sound doesn't work for\n" + "%s: you try the audio_clock_override=0x200000 insmod option.\n", + dev->name,dev->name,dev->name); break; case SAA7134_BOARD_CINERGY400_CARDBUS: /* power-up tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); - break; case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: /* this turns the remote control chip off to work around a bug in it */ saa_writeb(SAA7134_GPIO_GPMODE1, 0x80); @@ -3685,13 +3682,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); } break; - case SAA7134_BOARD_FLYDVB_TRIO: - { - u8 data[] = { 0x3c, 0x33, 0x62}; - struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)}; - i2c_transfer(&dev->i2c_adap, &msg, 1); - } - break; case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: /* make the tda10046 find its eeprom */ @@ -3705,7 +3695,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) { /* enable tuner */ int i; - static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; + u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; dev->i2c_client.addr = 0x0a; for (i = 0; i < 5; i++) if (2 != i2c_master_send(&dev->i2c_client,&buffer[i*2],2)) diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index f0c2111f1..2e0c9b1b6 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "saa7134-reg.h" #include "saa7134.h" @@ -67,11 +66,6 @@ static unsigned int latency = UNSET; module_param(latency, int, 0444); MODULE_PARM_DESC(latency,"pci latency timer"); -int saa7134_no_overlay=-1; -module_param_named(no_overlay, saa7134_no_overlay, int, 0444); -MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" - " [some VIA/SIS chipsets are known to have problem with overlay]"); - static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; @@ -96,8 +90,8 @@ LIST_HEAD(saa7134_devlist); static LIST_HEAD(mops_list); static unsigned int saa7134_devcount; -int (*dmasound_init)(struct saa7134_dev *dev); -int (*dmasound_exit)(struct saa7134_dev *dev); +int (*saa7134_dmasound_init)(struct saa7134_dev *dev); +int (*saa7134_dmasound_exit)(struct saa7134_dev *dev); #define dprintk(fmt, arg...) if (core_debug) \ printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) @@ -255,12 +249,13 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt) /* ------------------------------------------------------------------ */ -void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf) +void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf) { - BUG_ON(in_interrupt()); + if (in_interrupt()) + BUG(); videobuf_waiton(&buf->vb,0,0); - videobuf_dma_unmap(q, &buf->vb.dma); + videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma); videobuf_dma_free(&buf->vb.dma); buf->vb.state = STATE_NEEDS_INIT; } @@ -548,8 +543,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) if (report & SAA7134_IRQ_REPORT_GPIO16) { switch (dev->has_remote) { case SAA7134_REMOTE_GPIO: - if (!dev->remote) - break; if (dev->remote->mask_keydown & 0x10000) { saa7134_input_irq(dev); } @@ -566,8 +559,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) if (report & SAA7134_IRQ_REPORT_GPIO18) { switch (dev->has_remote) { case SAA7134_REMOTE_GPIO: - if (!dev->remote) - break; if ((dev->remote->mask_keydown & 0x40000) || (dev->remote->mask_keyup & 0x40000)) { saa7134_input_irq(dev); @@ -622,7 +613,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev) saa_writel(SAA7134_IRQ1, 0); saa_writel(SAA7134_IRQ2, 0); - mutex_init(&dev->lock); + init_MUTEX(&dev->lock); spin_lock_init(&dev->slock); saa7134_track_gpio(dev,"pre-init"); @@ -680,7 +671,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) SAA7134_IRQ2_INTE_PE | SAA7134_IRQ2_INTE_AR; - if (dev->has_remote == SAA7134_REMOTE_GPIO && dev->remote) { + if (dev->has_remote == SAA7134_REMOTE_GPIO) { if (dev->remote->mask_keydown & 0x10000) irq2_mask |= SAA7134_IRQ2_INTE_GPIO16; else if (dev->remote->mask_keydown & 0x40000) @@ -844,22 +835,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, latency = 0x0A; } #endif - if (pci_pci_problems & PCIPCI_FAIL) { - printk(KERN_INFO "%s: quirk: this driver and your " - "chipset may not work together" - " in overlay mode.\n",dev->name); - if (!saa7134_no_overlay) { - printk(KERN_INFO "%s: quirk: overlay " - "mode will be disabled.\n", - dev->name); - saa7134_no_overlay = 1; - } else { - printk(KERN_INFO "%s: quirk: overlay " - "mode will be forced. Use this" - " option at your own risk.\n", - dev->name); - } - } } if (UNSET != latency) { printk(KERN_INFO "%s: setting pci latency timer to %d\n", @@ -875,7 +850,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat,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,0xffffffff)) { printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); err = -EIO; goto fail1; @@ -962,11 +937,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, v4l2_prio_init(&dev->prio); /* register v4l devices */ - if (saa7134_no_overlay <= 0) { - saa7134_video_template.type |= VID_TYPE_OVERLAY; - } else { - printk("%s: Overlay support disabled.\n",dev->name); - } dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, video_nr[dev->nr]); @@ -1011,8 +981,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, /* check for signal */ saa7134_irq_video_intl(dev); - if (dmasound_init && !dev->dmasound.priv_data) { - dmasound_init(dev); + if (saa7134_dmasound_init && !dev->dmasound.priv_data) { + saa7134_dmasound_init(dev); } return 0; @@ -1039,8 +1009,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) struct saa7134_mpeg_ops *mops; /* Release DMA sound modules if present */ - if (dmasound_exit && dev->dmasound.priv_data) { - dmasound_exit(dev); + if (saa7134_dmasound_exit && dev->dmasound.priv_data) { + saa7134_dmasound_exit(dev); } /* debugging ... */ @@ -1172,8 +1142,8 @@ EXPORT_SYMBOL(saa7134_boards); /* ----------------- for the DMA sound modules --------------- */ -EXPORT_SYMBOL(dmasound_init); -EXPORT_SYMBOL(dmasound_exit); +EXPORT_SYMBOL(saa7134_dmasound_init); +EXPORT_SYMBOL(saa7134_dmasound_exit); EXPORT_SYMBOL(saa7134_pgtable_free); EXPORT_SYMBOL(saa7134_pgtable_build); EXPORT_SYMBOL(saa7134_pgtable_alloc); diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 222a36c38..746ec3156 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -814,7 +814,7 @@ static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_pa tda8290_msg.buf = tda8290_open; i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); return ret; -} +}; static int philips_tiger_dvb_mode(struct dvb_frontend *fe) { @@ -852,46 +852,13 @@ static struct tda1004x_config philips_tiger_config = { /* ------------------------------------------------------------------ */ -static int lifeview_trio_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - int ret; - - ret = philips_tda827xa_pll_set(0x60, fe, params); - return ret; -} - -static int lifeview_trio_dvb_mode(struct dvb_frontend *fe) -{ - return 0; -} - -static void lifeview_trio_analog_mode(struct dvb_frontend *fe) -{ - philips_tda827xa_pll_sleep(0x60, fe); -} - -static struct tda1004x_config lifeview_trio_config = { - .demod_address = 0x09, - .invert = 1, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_TDA827X_GPL, - .if_freq = TDA10046_FREQ_045, - .pll_init = lifeview_trio_dvb_mode, - .pll_set = lifeview_trio_pll_set, - .pll_sleep = lifeview_trio_analog_mode, - .request_firmware = NULL, -}; - -/* ------------------------------------------------------------------ */ - static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { int ret; ret = philips_tda827xa_pll_set(0x61, fe, params); return ret; -} +}; static int ads_duo_dvb_mode(struct dvb_frontend *fe) { @@ -1052,10 +1019,6 @@ static int dvb_init(struct saa7134_dev *dev) dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, &dev->i2c_adap); break; - case SAA7134_BOARD_FLYDVB_TRIO: - dev->dvb.frontend = tda10046_attach(&lifeview_trio_config, - &dev->i2c_adap); - break; case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, &dev->i2c_adap); diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 1d972edb3..bd4c389d4 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -89,7 +89,7 @@ static int ts_open(struct inode *inode, struct file *file) dprintk("open minor=%d\n",minor); err = -EBUSY; - if (!mutex_trylock(&dev->empress_tsq.lock)) + if (down_trylock(&dev->empress_tsq.lock)) goto done; if (dev->empress_users) goto done_up; @@ -99,7 +99,7 @@ static int ts_open(struct inode *inode, struct file *file) err = 0; done_up: - mutex_unlock(&dev->empress_tsq.lock); + up(&dev->empress_tsq.lock); done: return err; } @@ -110,7 +110,7 @@ static int ts_release(struct inode *inode, struct file *file) if (dev->empress_tsq.streaming) videobuf_streamoff(&dev->empress_tsq); - mutex_lock(&dev->empress_tsq.lock); + down(&dev->empress_tsq.lock); if (dev->empress_tsq.reading) videobuf_read_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); @@ -119,7 +119,7 @@ static int ts_release(struct inode *inode, struct file *file) /* stop the encoder */ ts_reset_encoder(dev); - mutex_unlock(&dev->empress_tsq.lock); + up(&dev->empress_tsq.lock); return 0; } diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 1426e4c86..d0acb56a8 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -42,6 +42,523 @@ 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) +/* ---------------------------------------------------------------------- */ + +static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = { + [ 15 ] = KEY_KP0, + [ 3 ] = KEY_KP1, + [ 4 ] = KEY_KP2, + [ 5 ] = KEY_KP3, + [ 7 ] = KEY_KP4, + [ 8 ] = KEY_KP5, + [ 9 ] = KEY_KP6, + [ 11 ] = KEY_KP7, + [ 12 ] = KEY_KP8, + [ 13 ] = KEY_KP9, + + [ 14 ] = KEY_MODE, // Air/Cable + [ 17 ] = KEY_VIDEO, // Video + [ 21 ] = KEY_AUDIO, // Audio + [ 0 ] = KEY_POWER, // Power + [ 24 ] = KEY_TUNER, // AV Source + [ 2 ] = KEY_ZOOM, // Fullscreen + [ 26 ] = KEY_LANGUAGE, // Stereo + [ 27 ] = KEY_MUTE, // Mute + [ 20 ] = KEY_VOLUMEUP, // Volume + + [ 23 ] = KEY_VOLUMEDOWN, // Volume - + [ 18 ] = KEY_CHANNELUP, // Channel + + [ 19 ] = KEY_CHANNELDOWN, // Channel - + [ 6 ] = KEY_AGAIN, // Recall + [ 16 ] = KEY_ENTER, // Enter +}; + +static IR_KEYTAB_TYPE flydvb_codes[IR_KEYTAB_SIZE] = { + [ 0x01 ] = KEY_ZOOM, // Full Screen + [ 0x00 ] = KEY_POWER, // Power + + [ 0x03 ] = KEY_1, + [ 0x04 ] = KEY_2, + [ 0x05 ] = KEY_3, + [ 0x07 ] = KEY_4, + [ 0x08 ] = KEY_5, + [ 0x09 ] = KEY_6, + [ 0x0b ] = KEY_7, + [ 0x0c ] = KEY_8, + [ 0x0d ] = KEY_9, + [ 0x06 ] = KEY_AGAIN, // Recall + [ 0x0f ] = KEY_0, + [ 0x10 ] = KEY_MUTE, // Mute + [ 0x02 ] = KEY_RADIO, // TV/Radio + [ 0x1b ] = KEY_LANGUAGE, // SAP (Second Audio Program) + + [ 0x14 ] = KEY_VOLUMEUP, // VOL+ + [ 0x17 ] = KEY_VOLUMEDOWN, // VOL- + [ 0x12 ] = KEY_CHANNELUP, // CH+ + [ 0x13 ] = KEY_CHANNELDOWN, // CH- + [ 0x1d ] = KEY_ENTER, // Enter + + [ 0x1a ] = KEY_MODE, // PIP + [ 0x18 ] = KEY_TUNER, // Source + + [ 0x1e ] = KEY_RECORD, // Record/Pause + [ 0x15 ] = KEY_ANGLE, // Swap (no label on key) + [ 0x1c ] = KEY_PAUSE, // Timeshift/Pause + [ 0x19 ] = KEY_BACK, // Rewind << + [ 0x0a ] = KEY_PLAYPAUSE, // Play/Pause + [ 0x1f ] = KEY_FORWARD, // Forward >> + [ 0x16 ] = KEY_PREVIOUS, // Back |<< + [ 0x11 ] = KEY_STOP, // Stop + [ 0x0e ] = KEY_NEXT, // End >>| +}; + +static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { + [ 0 ] = KEY_KP0, + [ 1 ] = KEY_KP1, + [ 2 ] = KEY_KP2, + [ 3 ] = KEY_KP3, + [ 4 ] = KEY_KP4, + [ 5 ] = KEY_KP5, + [ 6 ] = KEY_KP6, + [ 7 ] = KEY_KP7, + [ 8 ] = KEY_KP8, + [ 9 ] = KEY_KP9, + + [ 0x0a ] = KEY_POWER, + [ 0x0b ] = KEY_PROG1, // app + [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen + [ 0x0d ] = KEY_CHANNELUP, // channel + [ 0x0e ] = KEY_CHANNELDOWN, // channel- + [ 0x0f ] = KEY_VOLUMEUP, + [ 0x10 ] = KEY_VOLUMEDOWN, + [ 0x11 ] = KEY_TUNER, // AV + [ 0x12 ] = KEY_NUMLOCK, // -/-- + [ 0x13 ] = KEY_AUDIO, // audio + [ 0x14 ] = KEY_MUTE, + [ 0x15 ] = KEY_UP, + [ 0x16 ] = KEY_DOWN, + [ 0x17 ] = KEY_LEFT, + [ 0x18 ] = KEY_RIGHT, + [ 0x19 ] = BTN_LEFT, + [ 0x1a ] = BTN_RIGHT, + [ 0x1b ] = KEY_WWW, // text + [ 0x1c ] = KEY_REWIND, + [ 0x1d ] = KEY_FORWARD, + [ 0x1e ] = KEY_RECORD, + [ 0x1f ] = KEY_PLAY, + [ 0x20 ] = KEY_PREVIOUSSONG, + [ 0x21 ] = KEY_NEXTSONG, + [ 0x22 ] = KEY_PAUSE, + [ 0x23 ] = KEY_STOP, +}; + +/* Alfons Geser + * updates from Job D. R. Borges */ +static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { + [ 18 ] = KEY_POWER, + [ 1 ] = KEY_TV, // DVR + [ 21 ] = KEY_DVD, // DVD + [ 23 ] = KEY_AUDIO, // music + // DVR mode / DVD mode / music mode + + [ 27 ] = KEY_MUTE, // mute + [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek + [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek + [ 22 ] = KEY_ZOOM, // full screen + [ 28 ] = KEY_VIDEO, // video source / eject / delall + [ 29 ] = KEY_RESTART, // playback / angle / del + [ 47 ] = KEY_SEARCH, // scan / menu / playlist + [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo + + [ 49 ] = KEY_HELP, // help + [ 50 ] = KEY_MODE, // num/memo + [ 51 ] = KEY_ESC, // cancel + + [ 12 ] = KEY_UP, // up + [ 16 ] = KEY_DOWN, // down + [ 8 ] = KEY_LEFT, // left + [ 4 ] = KEY_RIGHT, // right + [ 3 ] = KEY_SELECT, // select + + [ 31 ] = KEY_REWIND, // rewind + [ 32 ] = KEY_PLAYPAUSE, // play/pause + [ 41 ] = KEY_FORWARD, // forward + [ 20 ] = KEY_AGAIN, // repeat + [ 43 ] = KEY_RECORD, // recording + [ 44 ] = KEY_STOP, // stop + [ 45 ] = KEY_PLAY, // play + [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle + + [ 0 ] = KEY_KP0, + [ 5 ] = KEY_KP1, + [ 6 ] = KEY_KP2, + [ 7 ] = KEY_KP3, + [ 9 ] = KEY_KP4, + [ 10 ] = KEY_KP5, + [ 11 ] = KEY_KP6, + [ 13 ] = KEY_KP7, + [ 14 ] = KEY_KP8, + [ 15 ] = KEY_KP9, + + [ 42 ] = KEY_VOLUMEUP, + [ 17 ] = KEY_VOLUMEDOWN, + [ 24 ] = KEY_CHANNELUP, // CH.tracking up + [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down + + [ 19 ] = KEY_KPENTER, // enter + [ 33 ] = KEY_KPDOT, // . (decimal dot) +}; + +static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { + [ 30 ] = KEY_POWER, // power + [ 28 ] = KEY_SEARCH, // scan + [ 7 ] = KEY_SELECT, // source + + [ 22 ] = KEY_VOLUMEUP, + [ 20 ] = KEY_VOLUMEDOWN, + [ 31 ] = KEY_CHANNELUP, + [ 23 ] = KEY_CHANNELDOWN, + [ 24 ] = KEY_MUTE, + + [ 2 ] = KEY_KP0, + [ 1 ] = KEY_KP1, + [ 11 ] = KEY_KP2, + [ 27 ] = KEY_KP3, + [ 5 ] = KEY_KP4, + [ 9 ] = KEY_KP5, + [ 21 ] = KEY_KP6, + [ 6 ] = KEY_KP7, + [ 10 ] = KEY_KP8, + [ 18 ] = KEY_KP9, + [ 16 ] = KEY_KPDOT, + + [ 3 ] = KEY_TUNER, // tv/fm + [ 4 ] = KEY_REWIND, // fm tuning left or function left + [ 12 ] = KEY_FORWARD, // fm tuning right or function right + + [ 0 ] = KEY_RECORD, + [ 8 ] = KEY_STOP, + [ 17 ] = KEY_PLAY, + + [ 25 ] = KEY_ZOOM, + [ 14 ] = KEY_MENU, // function + [ 19 ] = KEY_AGAIN, // recall + [ 29 ] = KEY_RESTART, // reset + [ 26 ] = KEY_SHUFFLE, // snapshot/shuffle + +// FIXME + [ 13 ] = KEY_F21, // mts + [ 15 ] = KEY_F22, // min +}; + +/* Alex Hermann */ +static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = { + [ 40 ] = KEY_KP1, + [ 24 ] = KEY_KP2, + [ 56 ] = KEY_KP3, + [ 36 ] = KEY_KP4, + [ 20 ] = KEY_KP5, + [ 52 ] = KEY_KP6, + [ 44 ] = KEY_KP7, + [ 28 ] = KEY_KP8, + [ 60 ] = KEY_KP9, + [ 34 ] = KEY_KP0, + + [ 32 ] = KEY_TV, // TV/FM + [ 16 ] = KEY_CD, // CD + [ 48 ] = KEY_TEXT, // TELETEXT + [ 0 ] = KEY_POWER, // POWER + + [ 8 ] = KEY_VIDEO, // VIDEO + [ 4 ] = KEY_AUDIO, // AUDIO + [ 12 ] = KEY_ZOOM, // FULL SCREEN + + [ 18 ] = KEY_SUBTITLE, // DISPLAY - ??? + [ 50 ] = KEY_REWIND, // LOOP - ??? + [ 2 ] = KEY_PRINT, // PREVIEW - ??? + + [ 42 ] = KEY_SEARCH, // AUTOSCAN + [ 26 ] = KEY_SLEEP, // FREEZE - ??? + [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ??? + [ 10 ] = KEY_MUTE, // MUTE + + [ 38 ] = KEY_RECORD, // RECORD + [ 22 ] = KEY_PAUSE, // PAUSE + [ 54 ] = KEY_STOP, // STOP + [ 6 ] = KEY_PLAY, // PLAY + + [ 46 ] = KEY_RED, // + [ 33 ] = KEY_GREEN, // + [ 14 ] = KEY_YELLOW, // + [ 1 ] = KEY_BLUE, // + + [ 30 ] = KEY_VOLUMEDOWN, // VOLUME- + [ 62 ] = KEY_VOLUMEUP, // VOLUME+ + [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE- + [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+ +}; + +static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = { + [ 20 ] = KEY_MUTE, + [ 36 ] = KEY_ZOOM, + + [ 1 ] = KEY_DVD, + [ 35 ] = KEY_RADIO, + [ 0 ] = KEY_TV, + + [ 10 ] = KEY_REWIND, + [ 8 ] = KEY_PLAYPAUSE, + [ 15 ] = KEY_FORWARD, + + [ 2 ] = KEY_PREVIOUS, + [ 7 ] = KEY_STOP, + [ 6 ] = KEY_NEXT, + + [ 12 ] = KEY_UP, + [ 14 ] = KEY_DOWN, + [ 11 ] = KEY_LEFT, + [ 13 ] = KEY_RIGHT, + [ 17 ] = KEY_OK, + + [ 3 ] = KEY_MENU, + [ 9 ] = KEY_SETUP, + [ 5 ] = KEY_VIDEO, + [ 34 ] = KEY_CHANNEL, + + [ 18 ] = KEY_VOLUMEUP, + [ 21 ] = KEY_VOLUMEDOWN, + [ 16 ] = KEY_CHANNELUP, + [ 19 ] = KEY_CHANNELDOWN, + + [ 4 ] = KEY_RECORD, + + [ 22 ] = KEY_KP1, + [ 23 ] = KEY_KP2, + [ 24 ] = KEY_KP3, + [ 25 ] = KEY_KP4, + [ 26 ] = KEY_KP5, + [ 27 ] = KEY_KP6, + [ 28 ] = KEY_KP7, + [ 29 ] = KEY_KP8, + [ 30 ] = KEY_KP9, + [ 31 ] = KEY_KP0, + + [ 32 ] = KEY_LANGUAGE, + [ 33 ] = KEY_SLEEP, +}; + +/* Michael Tokarev + http://www.corpit.ru/mjt/beholdTV/remote_control.jpg + keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at + least, and probably other cards too. + The "ascii-art picture" below (in comments, first row + is the keycode in hex, and subsequent row(s) shows + the button labels (several variants when appropriate) + helps to descide which keycodes to assign to the buttons. + */ +static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = { + + /* 0x1c 0x12 * + * FUNCTION POWER * + * FM (|) * + * */ + [ 0x1c ] = KEY_RADIO, /*XXX*/ + [ 0x12 ] = KEY_POWER, + + /* 0x01 0x02 0x03 * + * 1 2 3 * + * * + * 0x04 0x05 0x06 * + * 4 5 6 * + * * + * 0x07 0x08 0x09 * + * 7 8 9 * + * */ + [ 0x01 ] = KEY_KP1, + [ 0x02 ] = KEY_KP2, + [ 0x03 ] = KEY_KP3, + [ 0x04 ] = KEY_KP4, + [ 0x05 ] = KEY_KP5, + [ 0x06 ] = KEY_KP6, + [ 0x07 ] = KEY_KP7, + [ 0x08 ] = KEY_KP8, + [ 0x09 ] = KEY_KP9, + + /* 0x0a 0x00 0x17 * + * RECALL 0 +100 * + * PLUS * + * */ + [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */ + [ 0x00 ] = KEY_KP0, + [ 0x17 ] = KEY_DIGITS, /*XXX*/ + + /* 0x14 0x10 * + * MENU INFO * + * OSD */ + [ 0x14 ] = KEY_MENU, + [ 0x10 ] = KEY_INFO, + + /* 0x0b * + * Up * + * * + * 0x18 0x16 0x0c * + * Left Ok Right * + * * + * 0x015 * + * Down * + * */ + [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */ + [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */ + [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */ + [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */ + [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */ + + /* 0x11 0x0d * + * TV/AV MODE * + * SOURCE STEREO * + * */ + [ 0x11 ] = KEY_TV, /*XXX*/ + [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */ + + /* 0x0f 0x1b 0x1a * + * AUDIO Vol+ Chan+ * + * TIMESHIFT??? * + * * + * 0x0e 0x1f 0x1e * + * SLEEP Vol- Chan- * + * */ + [ 0x0f ] = KEY_AUDIO, + [ 0x1b ] = KEY_VOLUMEUP, + [ 0x1a ] = KEY_CHANNELUP, + [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */ + [ 0x1f ] = KEY_VOLUMEDOWN, + [ 0x1e ] = KEY_CHANNELDOWN, + + /* 0x13 0x19 * + * MUTE SNAPSHOT* + * */ + [ 0x13 ] = KEY_MUTE, + [ 0x19 ] = KEY_RECORD, /*XXX*/ + + // 0x1d unused ? +}; + + +/* Mike Baikov */ +static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = { + + [ 33 ] = KEY_POWER, + [ 105] = KEY_TV, + [ 51 ] = KEY_KP0, + [ 81 ] = KEY_KP1, + [ 49 ] = KEY_KP2, + [ 113] = KEY_KP3, + [ 59 ] = KEY_KP4, + [ 88 ] = KEY_KP5, + [ 65 ] = KEY_KP6, + [ 72 ] = KEY_KP7, + [ 48 ] = KEY_KP8, + [ 83 ] = KEY_KP9, + [ 115] = KEY_AGAIN, /* LOOP */ + [ 10 ] = KEY_AUDIO, + [ 97 ] = KEY_PRINT, /* PREVIEW */ + [ 122] = KEY_VIDEO, + [ 32 ] = KEY_CHANNELUP, + [ 64 ] = KEY_CHANNELDOWN, + [ 24 ] = KEY_VOLUMEDOWN, + [ 80 ] = KEY_VOLUMEUP, + [ 16 ] = KEY_MUTE, + [ 74 ] = KEY_SEARCH, + [ 123] = KEY_SHUFFLE, /* SNAPSHOT */ + [ 34 ] = KEY_RECORD, + [ 98 ] = KEY_STOP, + [ 120] = KEY_PLAY, + [ 57 ] = KEY_REWIND, + [ 89 ] = KEY_PAUSE, + [ 25 ] = KEY_FORWARD, + [ 9 ] = KEY_ZOOM, + + [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */ + [ 26 ] = KEY_F22, /* MIN TIMESHIFT */ + [ 58 ] = KEY_F23, /* TIMESHIFT */ + [ 112] = KEY_F24, /* NORMAL TIMESHIFT */ +}; + +static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { + [ 0x3 ] = KEY_POWER, + [ 0x6f ] = KEY_MUTE, + [ 0x10 ] = KEY_BACKSPACE, /* Recall */ + + [ 0x11 ] = KEY_KP0, + [ 0x4 ] = KEY_KP1, + [ 0x5 ] = KEY_KP2, + [ 0x6 ] = KEY_KP3, + [ 0x8 ] = KEY_KP4, + [ 0x9 ] = KEY_KP5, + [ 0xa ] = KEY_KP6, + [ 0xc ] = KEY_KP7, + [ 0xd ] = KEY_KP8, + [ 0xe ] = KEY_KP9, + [ 0x12 ] = KEY_KPDOT, /* 100+ */ + + [ 0x7 ] = KEY_VOLUMEUP, + [ 0xb ] = KEY_VOLUMEDOWN, + [ 0x1a ] = KEY_KPPLUS, + [ 0x18 ] = KEY_KPMINUS, + [ 0x15 ] = KEY_UP, + [ 0x1d ] = KEY_DOWN, + [ 0xf ] = KEY_CHANNELUP, + [ 0x13 ] = KEY_CHANNELDOWN, + [ 0x48 ] = KEY_ZOOM, + + [ 0x1b ] = KEY_VIDEO, /* Video source */ + [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ + [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ + + [ 0x4b ] = KEY_RECORD, + [ 0x46 ] = KEY_PLAY, + [ 0x45 ] = KEY_PAUSE, /* Pause */ + [ 0x44 ] = KEY_STOP, + [ 0x40 ] = KEY_FORWARD, /* Forward ? */ + [ 0x42 ] = KEY_REWIND, /* Backward ? */ + +}; + +/* Mapping for the 28 key remote control as seen at + http://www.sednacomputer.com/photo/cardbus-tv.jpg + Pavel Mihaylov */ +static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = { + [ 0 ] = KEY_KP0, + [ 1 ] = KEY_KP1, + [ 2 ] = KEY_KP2, + [ 3 ] = KEY_KP3, + [ 4 ] = KEY_KP4, + [ 5 ] = KEY_KP5, + [ 6 ] = KEY_KP6, + [ 7 ] = KEY_KP7, + [ 8 ] = KEY_KP8, + [ 9 ] = KEY_KP9, + + [ 0x0a ] = KEY_AGAIN, /* Recall */ + [ 0x0b ] = KEY_CHANNELUP, + [ 0x0c ] = KEY_VOLUMEUP, + [ 0x0d ] = KEY_MODE, /* Stereo */ + [ 0x0e ] = KEY_STOP, + [ 0x0f ] = KEY_PREVIOUSSONG, + [ 0x10 ] = KEY_ZOOM, + [ 0x11 ] = KEY_TUNER, /* Source */ + [ 0x12 ] = KEY_POWER, + [ 0x13 ] = KEY_MUTE, + [ 0x15 ] = KEY_CHANNELDOWN, + [ 0x18 ] = KEY_VOLUMEDOWN, + [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */ + [ 0x1a ] = KEY_NEXTSONG, + [ 0x1b ] = KEY_TEXT, /* Time Shift */ + [ 0x1c ] = KEY_RADIO, /* FM Radio */ + [ 0x1d ] = KEY_RECORD, + [ 0x1e ] = KEY_PAUSE, +}; + + /* -------------------- GPIO generic keycode builder -------------------- */ static int build_key(struct saa7134_dev *dev) @@ -149,27 +666,27 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_FLYVIDEO3000: case SAA7134_BOARD_FLYTVPLATINUM_FM: case SAA7134_BOARD_FLYTVPLATINUM_MINI2: - ir_codes = ir_codes_flyvideo; + ir_codes = flyvideo_codes; mask_keycode = 0xEC00000; mask_keydown = 0x0040000; break; case SAA7134_BOARD_CINERGY400: case SAA7134_BOARD_CINERGY600: case SAA7134_BOARD_CINERGY600_MK3: - ir_codes = ir_codes_cinergy; + ir_codes = cinergy_codes; mask_keycode = 0x00003f; mask_keyup = 0x040000; break; case SAA7134_BOARD_ECS_TVP3XP: case SAA7134_BOARD_ECS_TVP3XP_4CB5: - ir_codes = ir_codes_eztv; + ir_codes = eztv_codes; mask_keycode = 0x00017c; mask_keyup = 0x000002; polling = 50; // ms break; case SAA7134_BOARD_KWORLD_XPERT: case SAA7134_BOARD_AVACSSMARTTV: - ir_codes = ir_codes_pixelview; + ir_codes = avacssmart_codes; mask_keycode = 0x00001F; mask_keyup = 0x000020; polling = 50; // ms @@ -181,7 +698,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_STUDIO_305: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: - ir_codes = ir_codes_avermedia; + ir_codes = md2819_codes; mask_keycode = 0x0007C8; mask_keydown = 0x000010; polling = 50; // ms @@ -190,7 +707,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); break; case SAA7134_BOARD_KWORLD_TERMINATOR: - ir_codes = ir_codes_pixelview; + ir_codes = avacssmart_codes; mask_keycode = 0x00001f; mask_keyup = 0x000060; polling = 50; // ms @@ -198,19 +715,19 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_MANLI_MTV001: case SAA7134_BOARD_MANLI_MTV002: case SAA7134_BOARD_BEHOLD_409FM: - ir_codes = ir_codes_manli; + ir_codes = manli_codes; mask_keycode = 0x001f00; mask_keyup = 0x004000; polling = 50; // ms break; case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: - ir_codes = ir_codes_pctv_sedna; + ir_codes = pctv_sedna_codes; mask_keycode = 0x001f00; mask_keyup = 0x004000; polling = 50; // ms break; case SAA7134_BOARD_GOTVIEW_7135: - ir_codes = ir_codes_gotview7135; + ir_codes = gotview7135_codes; mask_keycode = 0x0003EC; mask_keyup = 0x008000; mask_keydown = 0x000010; @@ -219,20 +736,19 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_VIDEOMATE_TV_PVR: case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: - ir_codes = ir_codes_videomate_tv_pvr; + ir_codes = videomate_tv_pvr_codes; mask_keycode = 0x00003F; mask_keyup = 0x400000; polling = 50; // ms break; case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_VIDEOMATE_DVBT_200: - ir_codes = ir_codes_videomate_tv_pvr; + ir_codes = videomate_tv_pvr_codes; mask_keycode = 0x003F00; mask_keyup = 0x040000; break; case SAA7134_BOARD_FLYDVBT_LR301: - case SAA7134_BOARD_FLYDVBTDUO: - ir_codes = ir_codes_flydvb; + ir_codes = flydvb_codes; mask_keycode = 0x0001F00; mask_keydown = 0x0040000; break; diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c index 7aa02b34e..9a1529817 100644 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ b/drivers/media/video/saa7134/saa7134-oss.c @@ -84,7 +84,8 @@ static int dsp_buffer_init(struct saa7134_dev *dev) { int err; - BUG_ON(!dev->dmasound.bufsize); + if (!dev->dmasound.bufsize) + BUG(); videobuf_dma_init(&dev->dmasound.dma); err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); @@ -95,7 +96,8 @@ static int dsp_buffer_init(struct saa7134_dev *dev) static int dsp_buffer_free(struct saa7134_dev *dev) { - BUG_ON(!dev->dmasound.blksize); + if (!dev->dmasound.blksize) + BUG(); videobuf_dma_free(&dev->dmasound.dma); dev->dmasound.blocks = 0; dev->dmasound.blksize = 0; @@ -124,7 +126,7 @@ static int dsp_rec_start(struct saa7134_dev *dev) unsigned long flags; /* prepare buffer */ - if (0 != (err = videobuf_pci_dma_map(dev->pci,&dev->dmasound.dma))) + if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma))) return err; if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) goto fail1; @@ -213,7 +215,7 @@ static int dsp_rec_start(struct saa7134_dev *dev) fail2: saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); fail1: - videobuf_pci_dma_unmap(dev->pci,&dev->dmasound.dma); + videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); return err; } @@ -231,7 +233,7 @@ static int dsp_rec_stop(struct saa7134_dev *dev) /* unlock buffer */ saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); - videobuf_pci_dma_unmap(dev->pci,&dev->dmasound.dma); + videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); return 0; } @@ -252,7 +254,7 @@ static int dsp_open(struct inode *inode, struct file *file) if (NULL == dev) return -ENODEV; - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); err = -EBUSY; if (dev->dmasound.users_dsp) goto fail1; @@ -268,13 +270,13 @@ static int dsp_open(struct inode *inode, struct file *file) if (0 != err) goto fail2; - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); return 0; fail2: dev->dmasound.users_dsp--; fail1: - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); return err; } @@ -282,13 +284,13 @@ static int dsp_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); if (dev->dmasound.recording_on) dsp_rec_stop(dev); dsp_buffer_free(dev); dev->dmasound.users_dsp--; file->private_data = NULL; - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); return 0; } @@ -302,7 +304,7 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, int err,ret = 0; add_wait_queue(&dev->dmasound.wq, &wait); - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); while (count > 0) { /* wait for data if needed */ if (0 == dev->dmasound.read_count) { @@ -326,12 +328,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, ret = -EAGAIN; break; } - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); set_current_state(TASK_INTERRUPTIBLE); if (0 == dev->dmasound.read_count) schedule(); set_current_state(TASK_RUNNING); - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); if (signal_pending(current)) { if (0 == ret) ret = -EINTR; @@ -360,7 +362,7 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, if (dev->dmasound.read_offset == dev->dmasound.bufsize) dev->dmasound.read_offset = 0; } - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); remove_wait_queue(&dev->dmasound.wq, &wait); return ret; } @@ -433,13 +435,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file, case SNDCTL_DSP_STEREO: if (get_user(val, p)) return -EFAULT; - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); dev->dmasound.channels = val ? 2 : 1; if (dev->dmasound.recording_on) { dsp_rec_stop(dev); dsp_rec_start(dev); } - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); return put_user(dev->dmasound.channels-1, p); case SNDCTL_DSP_CHANNELS: @@ -447,13 +449,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file, return -EFAULT; if (val != 1 && val != 2) return -EINVAL; - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); dev->dmasound.channels = val; if (dev->dmasound.recording_on) { dsp_rec_stop(dev); dsp_rec_start(dev); } - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); /* fall through */ case SOUND_PCM_READ_CHANNELS: return put_user(dev->dmasound.channels, p); @@ -476,13 +478,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file, case AFMT_U16_BE: case AFMT_S16_LE: case AFMT_S16_BE: - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); dev->dmasound.afmt = val; if (dev->dmasound.recording_on) { dsp_rec_stop(dev); dsp_rec_start(dev); } - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); return put_user(dev->dmasound.afmt, p); default: return -EINVAL; @@ -507,10 +509,10 @@ static int dsp_ioctl(struct inode *inode, struct file *file, return 0; case SNDCTL_DSP_RESET: - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); if (dev->dmasound.recording_on) dsp_rec_stop(dev); - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); return 0; case SNDCTL_DSP_GETBLKSIZE: return put_user(dev->dmasound.blksize, p); @@ -554,10 +556,10 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait) poll_wait(file, &dev->dmasound.wq, wait); if (0 == dev->dmasound.read_count) { - mutex_lock(&dev->dmasound.lock); + down(&dev->dmasound.lock); if (!dev->dmasound.recording_on) dsp_rec_start(dev); - mutex_unlock(&dev->dmasound.lock); + up(&dev->dmasound.lock); } else mask |= (POLLIN | POLLRDNORM); return mask; @@ -850,7 +852,7 @@ int saa7134_oss_init1(struct saa7134_dev *dev) return -1; /* general */ - mutex_init(&dev->dmasound.lock); + init_MUTEX(&dev->dmasound.lock); init_waitqueue_head(&dev->dmasound.wq); switch (dev->pci->device) { @@ -993,9 +995,9 @@ static int saa7134_oss_init(void) struct saa7134_dev *dev = NULL; struct list_head *list; - if (!dmasound_init && !dmasound_exit) { - dmasound_init = oss_device_init; - dmasound_exit = oss_device_exit; + if (!saa7134_dmasound_init && !saa7134_dmasound_exit) { + saa7134_dmasound_init = oss_device_init; + saa7134_dmasound_exit = oss_device_exit; } else { printk(KERN_WARNING "saa7134 OSS: can't load, DMA sound handler already assigned (probably to ALSA)\n"); return -EBUSY; @@ -1037,8 +1039,8 @@ static void saa7134_oss_exit(void) } - dmasound_init = NULL; - dmasound_exit = NULL; + saa7134_dmasound_init = NULL; + saa7134_dmasound_exit = NULL; printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n"); diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index 60a90a261..470903e2f 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c @@ -89,7 +89,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, return -EINVAL; if (buf->vb.size != size) { - saa7134_dma_free(q,buf); + saa7134_dma_free(dev,buf); } if (STATE_NEEDS_INIT == buf->vb.state) { @@ -98,7 +98,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, buf->vb.size = size; buf->pt = &dev->ts.pt_ts; - err = videobuf_iolock(q,&buf->vb,NULL); + err = videobuf_iolock(dev->pci,&buf->vb,NULL); if (err) goto oops; err = saa7134_pgtable_build(dev->pci,buf->pt, @@ -126,7 +126,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, return 0; oops: - saa7134_dma_free(q,buf); + saa7134_dma_free(dev,buf); return err; } @@ -152,9 +152,10 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { + struct saa7134_dev *dev = q->priv_data; struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); - saa7134_dma_free(q,buf); + saa7134_dma_free(dev,buf); } struct videobuf_queue_ops saa7134_ts_qops = { diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 0db53d192..afa4dcb3f 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -139,12 +139,6 @@ static struct saa7134_tvaudio tvaudio[] = { .carr1 = 6500, .carr2 = 5850, .mode = TVAUDIO_NICAM_AM, - },{ - .name = "SECAM-L MONO", - .std = V4L2_STD_SECAM, - .carr1 = 6500, - .carr2 = -1, - .mode = TVAUDIO_AM_MONO, },{ .name = "SECAM-D/K", .std = V4L2_STD_SECAM, @@ -340,12 +334,6 @@ static void tvaudio_setmode(struct saa7134_dev *dev, saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1); saa_writeb(SAA7134_NICAM_CONFIG, 0x00); break; - case TVAUDIO_AM_MONO: - saa_writeb(SAA7134_DEMODULATOR, 0x12); - saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00); - saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44); - saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0); - break; case TVAUDIO_FM_SAT_STEREO: /* not implemented (yet) */ break; @@ -426,7 +414,6 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au switch (audio->mode) { case TVAUDIO_FM_MONO: - case TVAUDIO_AM_MONO: return V4L2_TUNER_SUB_MONO; case TVAUDIO_FM_K_STEREO: case TVAUDIO_FM_BG_STEREO: @@ -482,20 +469,17 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au [ V4L2_TUNER_MODE_STEREO ] = "stereo", [ V4L2_TUNER_MODE_LANG1 ] = "lang1", [ V4L2_TUNER_MODE_LANG2 ] = "lang2", - [ V4L2_TUNER_MODE_LANG1_LANG2 ] = "lang1+lang2", }; static u32 fm[] = { [ V4L2_TUNER_MODE_MONO ] = 0x00, /* ch1 */ [ V4L2_TUNER_MODE_STEREO ] = 0x80, /* auto */ [ V4L2_TUNER_MODE_LANG1 ] = 0x00, /* ch1 */ [ V4L2_TUNER_MODE_LANG2 ] = 0x01, /* ch2 */ - [ V4L2_TUNER_MODE_LANG1_LANG2 ] = 0x80, /* auto */ }; u32 reg; switch (audio->mode) { case TVAUDIO_FM_MONO: - case TVAUDIO_AM_MONO: /* nothing to do ... */ break; case TVAUDIO_FM_K_STEREO: diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c index f38366a47..f4aee0af8 100644 --- a/drivers/media/video/saa7134/saa7134-vbi.c +++ b/drivers/media/video/saa7134/saa7134-vbi.c @@ -135,7 +135,7 @@ static int buffer_prepare(struct videobuf_queue *q, return -EINVAL; if (buf->vb.size != size) - saa7134_dma_free(q,buf); + saa7134_dma_free(dev,buf); if (STATE_NEEDS_INIT == buf->vb.state) { buf->vb.width = llength; @@ -143,7 +143,7 @@ static int buffer_prepare(struct videobuf_queue *q, buf->vb.size = size; buf->pt = &fh->pt_vbi; - err = videobuf_iolock(q,&buf->vb,NULL); + err = videobuf_iolock(dev->pci,&buf->vb,NULL); if (err) goto oops; err = saa7134_pgtable_build(dev->pci,buf->pt, @@ -159,7 +159,7 @@ static int buffer_prepare(struct videobuf_queue *q, return 0; oops: - saa7134_dma_free(q,buf); + saa7134_dma_free(dev,buf); return err; } @@ -190,9 +190,11 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { + struct saa7134_fh *fh = q->priv_data; + struct saa7134_dev *dev = fh->dev; struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); - saa7134_dma_free(q,buf); + saa7134_dma_free(dev,buf); } struct videobuf_queue_ops saa7134_vbi_qops = { diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index e4156ec9c..e97426bc8 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -31,10 +31,8 @@ #include "saa7134.h" #include -#ifdef CONFIG_VIDEO_V4L1_COMPAT /* Include V4L1 specific functions. Should be removed soon */ #include -#endif /* ------------------------------------------------------------------ */ @@ -462,17 +460,17 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int return 1; /* is it free? */ - mutex_lock(&dev->lock); + down(&dev->lock); if (dev->resources & bit) { /* no, someone else uses it */ - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } /* it's free, grab it */ fh->resources |= bit; dev->resources |= bit; dprintk("res: get %d\n",bit); - mutex_unlock(&dev->lock); + up(&dev->lock); return 1; } @@ -491,13 +489,14 @@ int res_locked(struct saa7134_dev *dev, unsigned int bit) static void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) { - BUG_ON((fh->resources & bits) != bits); + if ((fh->resources & bits) != bits) + BUG(); - mutex_lock(&dev->lock); + down(&dev->lock); fh->resources &= ~bits; dev->resources &= ~bits; dprintk("res: put %d\n",bits); - mutex_unlock(&dev->lock); + up(&dev->lock); } /* ------------------------------------------------------------------ */ @@ -995,7 +994,7 @@ static int buffer_prepare(struct videobuf_queue *q, buf->vb.size != size || buf->vb.field != field || buf->fmt != fh->fmt) { - saa7134_dma_free(q,buf); + saa7134_dma_free(dev,buf); } if (STATE_NEEDS_INIT == buf->vb.state) { @@ -1006,7 +1005,7 @@ static int buffer_prepare(struct videobuf_queue *q, buf->fmt = fh->fmt; buf->pt = &fh->pt_cap; - err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); + err = videobuf_iolock(dev->pci,&buf->vb,&dev->ovbuf); if (err) goto oops; err = saa7134_pgtable_build(dev->pci,buf->pt, @@ -1021,7 +1020,7 @@ static int buffer_prepare(struct videobuf_queue *q, return 0; oops: - saa7134_dma_free(q,buf); + saa7134_dma_free(dev,buf); return err; } @@ -1047,9 +1046,10 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { + struct saa7134_fh *fh = q->priv_data; struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); - saa7134_dma_free(q,buf); + saa7134_dma_free(fh->dev,buf); } static struct videobuf_queue_ops video_qops = { @@ -1340,21 +1340,21 @@ video_poll(struct file *file, struct poll_table_struct *wait) if (!list_empty(&fh->cap.stream)) buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); } else { - mutex_lock(&fh->cap.lock); + down(&fh->cap.lock); if (UNSET == fh->cap.read_off) { /* need to capture a new frame */ if (res_locked(fh->dev,RESOURCE_VIDEO)) { - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return POLLERR; } if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); return POLLERR; } fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); fh->cap.read_off = 0; } - mutex_unlock(&fh->cap.lock); + up(&fh->cap.lock); buf = fh->cap.read_buf; } @@ -1463,10 +1463,6 @@ static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, f->fmt.pix.height * f->fmt.pix.bytesperline; return 0; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (saa7134_no_overlay > 0) { - printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } f->fmt.win = fh->win; return 0; case V4L2_BUF_TYPE_VBI_CAPTURE: @@ -1531,10 +1527,6 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, return 0; } case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (saa7134_no_overlay > 0) { - printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } err = verify_preview(dev,&f->fmt.win); if (0 != err) return err; @@ -1565,22 +1557,18 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, fh->cap.field = f->fmt.pix.field; return 0; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (saa7134_no_overlay > 0) { - printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } err = verify_preview(dev,&f->fmt.win); if (0 != err) return err; - mutex_lock(&dev->lock); + down(&dev->lock); fh->win = f->fmt.win; fh->nclips = f->fmt.win.clipcount; if (fh->nclips > 8) fh->nclips = 8; if (copy_from_user(fh->clips,f->fmt.win.clips, sizeof(struct v4l2_clip)*fh->nclips)) { - mutex_unlock(&dev->lock); + up(&dev->lock); return -EFAULT; } @@ -1590,7 +1578,7 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, start_preview(dev,fh); spin_unlock_irqrestore(&dev->slock,flags); } - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; case V4L2_BUF_TYPE_VBI_CAPTURE: saa7134_vbi_fmt(dev,f); @@ -1624,9 +1612,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev, return get_control(dev,arg); case VIDIOC_S_CTRL: { - mutex_lock(&dev->lock); + down(&dev->lock); err = set_control(dev,NULL,arg); - mutex_unlock(&dev->lock); + up(&dev->lock); return err; } /* --- input switching --------------------------------------- */ @@ -1676,9 +1664,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev, return -EINVAL; if (NULL == card_in(dev,*i).name) return -EINVAL; - mutex_lock(&dev->lock); + down(&dev->lock); video_mux(dev,*i); - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } @@ -1728,13 +1716,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file, cap->version = SAA7134_VERSION_CODE; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_TUNER; - if (saa7134_no_overlay <= 0) { - cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; - } if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) cap->capabilities &= ~V4L2_CAP_TUNER; @@ -1780,7 +1766,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, if (i == TVNORMS) return -EINVAL; - mutex_lock(&dev->lock); + down(&dev->lock); if (res_check(fh, RESOURCE_OVERLAY)) { spin_lock_irqsave(&dev->slock,flags); stop_preview(dev,fh); @@ -1790,7 +1776,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, } else set_tvnorm(dev,&tvnorms[i]); saa7134_tvaudio_do_scan(dev); - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } @@ -1923,13 +1909,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) return -EINVAL; - mutex_lock(&dev->lock); + down(&dev->lock); dev->ctl_freq = f->frequency; saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); saa7134_tvaudio_do_scan(dev); - mutex_unlock(&dev->lock); + up(&dev->lock); return 0; } @@ -1985,10 +1971,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file, switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (saa7134_no_overlay > 0) { - printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } if (index >= FORMATS) return -EINVAL; if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && @@ -2049,11 +2031,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file, int *on = arg; if (*on) { - if (saa7134_no_overlay > 0) { - printk ("no_overlay\n"); - return -EINVAL; - } - if (!res_get(dev,fh,RESOURCE_OVERLAY)) return -EBUSY; spin_lock_irqsave(&dev->slock,flags); @@ -2305,7 +2282,7 @@ static struct file_operations radio_fops = struct video_device saa7134_video_template = { .name = "saa7134-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| VID_TYPE_CLIPPING|VID_TYPE_SCALES, .hardware = 0, .fops = &video_fops, diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 353af3a8b..2a4de51c8 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -29,11 +29,11 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -60,7 +60,6 @@ enum saa7134_tvaudio_mode { TVAUDIO_FM_K_STEREO = 4, TVAUDIO_NICAM_AM = 5, TVAUDIO_NICAM_FM = 6, - TVAUDIO_AM_MONO = 7 }; enum saa7134_audio_in { @@ -370,7 +369,7 @@ struct saa7134_fh { /* dmasound dsp status */ struct saa7134_dmasound { - struct mutex lock; + struct semaphore lock; int minor_mixer; int minor_dsp; unsigned int users_dsp; @@ -397,7 +396,7 @@ struct saa7134_dmasound { unsigned int read_offset; unsigned int read_count; void * priv_data; - struct snd_pcm_substream *substream; + snd_pcm_substream_t *substream; }; /* IR input */ @@ -434,7 +433,7 @@ struct saa7134_mpeg_ops { /* global device status */ struct saa7134_dev { struct list_head devlist; - struct mutex lock; + struct semaphore lock; spinlock_t slock; #ifdef VIDIOC_G_PRIORITY struct v4l2_prio_state prio; @@ -557,7 +556,6 @@ struct saa7134_dev { /* saa7134-core.c */ extern struct list_head saa7134_devlist; -extern int saa7134_no_overlay; void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); @@ -579,12 +577,12 @@ void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q, unsigned int state); void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q); void saa7134_buffer_timeout(unsigned long data); -void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf); +void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf); int saa7134_set_dmabits(struct saa7134_dev *dev); -extern int (*dmasound_init)(struct saa7134_dev *dev); -extern int (*dmasound_exit)(struct saa7134_dev *dev); +extern int (*saa7134_dmasound_init)(struct saa7134_dev *dev); +extern int (*saa7134_dmasound_exit)(struct saa7134_dev *dev); /* ----------------------------------------------------------- */ diff --git a/drivers/media/video/saa7146.h b/drivers/media/video/saa7146.h index 2830b5e33..756963f01 100644 --- a/drivers/media/video/saa7146.h +++ b/drivers/media/video/saa7146.h @@ -1,7 +1,7 @@ -/* +/* saa7146.h - definitions philips saa7146 based cards Copyright (C) 1999 Nathan Laredo (laredo@gnu.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 @@ -27,7 +27,7 @@ #include -#ifndef O_NONCAP +#ifndef O_NONCAP #define O_NONCAP O_TRUNC #endif @@ -36,7 +36,7 @@ #ifdef __KERNEL__ -struct saa7146_window +struct saa7146_window { int x, y; ushort width, height; @@ -70,7 +70,7 @@ struct saa7146 int irqstate; /* irq routine is state driven */ int writemode; int playmode; - unsigned int nr; + unsigned int nr; unsigned long irq; /* IRQ used by SAA7146 card */ unsigned short id; unsigned char revision; diff --git a/drivers/media/video/saa7146reg.h b/drivers/media/video/saa7146reg.h index 80ec2c146..6cc910f50 100644 --- a/drivers/media/video/saa7146reg.h +++ b/drivers/media/video/saa7146reg.h @@ -1,7 +1,7 @@ -/* +/* saa7146.h - definitions philips saa7146 based cards Copyright (C) 1999 Nathan Laredo (laredo@gnu.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 diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 9c3084108..3ed0edb87 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -1,4 +1,4 @@ -/* +/* * saa7185 - Philips SAA7185B video encoder driver version 0.0.3 * * Copyright (C) 1998 Dave Perks @@ -49,6 +49,7 @@ MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); #include +#include #define I2C_NAME(s) (s)->name @@ -112,21 +113,24 @@ saa7185_write_block (struct i2c_client *client, if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ struct saa7185 *encoder = i2c_get_clientdata(client); + struct i2c_msg msg; u8 block_data[32]; - int block_len; + msg.addr = client->addr; + msg.flags = 0; while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; + msg.buf = (char *) block_data; + msg.len = 0; + block_data[msg.len++] = reg = data[0]; do { - block_data[block_len++] = + block_data[msg.len++] = encoder->reg[reg++] = data[1]; len -= 2; data += 2; } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + msg.len < 32); + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { @@ -377,7 +381,7 @@ saa7185_command (struct i2c_client *client, static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, diff --git a/drivers/media/video/saa7196.h b/drivers/media/video/saa7196.h index cd4b6354a..f92f21cfb 100644 --- a/drivers/media/video/saa7196.h +++ b/drivers/media/video/saa7196.h @@ -2,14 +2,14 @@ Definitions for the Philips SAA7196 digital video decoder, scaler, and clock generator circuit (DESCpro), as used in the PlanB video input of the Powermac 7x00/8x00 series. - + Copyright (C) 1998 Michel Lanners (mlan@cpu.lu) The register defines are shamelessly copied from the meteor driver out of NetBSD (with permission), and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe (Thanks !) - + Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu) The default values used for PlanB are my mistakes. diff --git a/drivers/media/video/sn9c102/Kconfig b/drivers/media/video/sn9c102/Kconfig deleted file mode 100644 index cf552e6b8..000000000 --- a/drivers/media/video/sn9c102/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config USB_SN9C102 - tristate "USB SN9C10x PC Camera Controller support" - depends on USB && VIDEO_V4L1 - ---help--- - Say Y here if you want support for cameras based on SONiX SN9C101, - SN9C102 or SN9C103 PC Camera Controllers. - - See for more info. - - To compile this driver as a module, choose M here: the - module will be called sn9c102. diff --git a/drivers/media/video/sn9c102/Makefile b/drivers/media/video/sn9c102/Makefile deleted file mode 100644 index 536ad3098..000000000 --- a/drivers/media/video/sn9c102/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o \ - sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bca.o \ - sn9c102_pas202bcb.o sn9c102_tas5110c1b.o \ - sn9c102_tas5130d1b.o - -obj-$(CONFIG_USB_SN9C102) += sn9c102.o - diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/video/sn9c102/sn9c102_ov7630.c deleted file mode 100644 index 3da042021..000000000 --- a/drivers/media/video/sn9c102/sn9c102_ov7630.c +++ /dev/null @@ -1,401 +0,0 @@ -/*************************************************************************** - * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera * - * Controllers * - * * - * Copyright (C) 2005-2006 by Luca Risolia * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 "sn9c102_sensor.h" - - -static struct sn9c102_sensor ov7630; - - -static int ov7630_init(struct sn9c102_device* cam) -{ - int err = 0; - - err += sn9c102_write_reg(cam, 0x00, 0x14); - err += sn9c102_write_reg(cam, 0x60, 0x17); - err += sn9c102_write_reg(cam, 0x0f, 0x18); - err += sn9c102_write_reg(cam, 0x50, 0x19); - - err += sn9c102_i2c_write(cam, 0x12, 0x80); - err += sn9c102_i2c_write(cam, 0x11, 0x01); - err += sn9c102_i2c_write(cam, 0x15, 0x34); - err += sn9c102_i2c_write(cam, 0x16, 0x03); - err += sn9c102_i2c_write(cam, 0x17, 0x1c); - err += sn9c102_i2c_write(cam, 0x18, 0xbd); - err += sn9c102_i2c_write(cam, 0x19, 0x06); - err += sn9c102_i2c_write(cam, 0x1a, 0xf6); - err += sn9c102_i2c_write(cam, 0x1b, 0x04); - err += sn9c102_i2c_write(cam, 0x20, 0xf6); - err += sn9c102_i2c_write(cam, 0x23, 0xee); - err += sn9c102_i2c_write(cam, 0x26, 0xa0); - err += sn9c102_i2c_write(cam, 0x27, 0x9a); - err += sn9c102_i2c_write(cam, 0x28, 0xa0); - err += sn9c102_i2c_write(cam, 0x29, 0x30); - err += sn9c102_i2c_write(cam, 0x2a, 0xa0); - err += sn9c102_i2c_write(cam, 0x2b, 0x1f); - err += sn9c102_i2c_write(cam, 0x2f, 0x3d); - err += sn9c102_i2c_write(cam, 0x30, 0x24); - err += sn9c102_i2c_write(cam, 0x32, 0x86); - err += sn9c102_i2c_write(cam, 0x60, 0xa9); - err += sn9c102_i2c_write(cam, 0x61, 0x42); - err += sn9c102_i2c_write(cam, 0x65, 0x00); - err += sn9c102_i2c_write(cam, 0x69, 0x38); - err += sn9c102_i2c_write(cam, 0x6f, 0x88); - err += sn9c102_i2c_write(cam, 0x70, 0x0b); - err += sn9c102_i2c_write(cam, 0x71, 0x00); - err += sn9c102_i2c_write(cam, 0x74, 0x21); - err += sn9c102_i2c_write(cam, 0x7d, 0xf7); - - return err; -} - - -static int ov7630_set_ctrl(struct sn9c102_device* cam, - const struct v4l2_control* ctrl) -{ - int err = 0; - - switch (ctrl->id) { - case V4L2_CID_EXPOSURE: - err += sn9c102_i2c_write(cam, 0x10, ctrl->value >> 2); - err += sn9c102_i2c_write(cam, 0x76, ctrl->value & 0x03); - break; - case V4L2_CID_RED_BALANCE: - err += sn9c102_i2c_write(cam, 0x02, ctrl->value); - break; - case V4L2_CID_BLUE_BALANCE: - err += sn9c102_i2c_write(cam, 0x01, ctrl->value); - break; - case V4L2_CID_GAIN: - err += sn9c102_i2c_write(cam, 0x00, ctrl->value); - break; - case V4L2_CID_CONTRAST: - err += ctrl->value ? sn9c102_i2c_write(cam, 0x05, - (ctrl->value-1) | 0x20) - : sn9c102_i2c_write(cam, 0x05, 0x00); - break; - case V4L2_CID_BRIGHTNESS: - err += sn9c102_i2c_write(cam, 0x06, ctrl->value); - break; - case V4L2_CID_SATURATION: - err += sn9c102_i2c_write(cam, 0x03, ctrl->value << 4); - break; - case V4L2_CID_HUE: - err += ctrl->value ? sn9c102_i2c_write(cam, 0x04, - (ctrl->value-1) | 0x20) - : sn9c102_i2c_write(cam, 0x04, 0x00); - break; - case V4L2_CID_DO_WHITE_BALANCE: - err += sn9c102_i2c_write(cam, 0x0c, ctrl->value); - break; - case V4L2_CID_WHITENESS: - err += sn9c102_i2c_write(cam, 0x0d, ctrl->value); - break; - case V4L2_CID_AUTO_WHITE_BALANCE: - err += sn9c102_i2c_write(cam, 0x12, (ctrl->value << 2) | 0x78); - break; - case V4L2_CID_AUTOGAIN: - err += sn9c102_i2c_write(cam, 0x13, ctrl->value); - break; - case V4L2_CID_VFLIP: - err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7)); - break; - case V4L2_CID_BLACK_LEVEL: - err += sn9c102_i2c_write(cam, 0x25, ctrl->value); - break; - case SN9C102_V4L2_CID_BRIGHT_LEVEL: - err += sn9c102_i2c_write(cam, 0x24, ctrl->value); - break; - case SN9C102_V4L2_CID_GAMMA: - err += sn9c102_i2c_write(cam, 0x14, (ctrl->value << 2) | 0x80); - break; - case SN9C102_V4L2_CID_BAND_FILTER: - err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2); - break; - default: - return -EINVAL; - } - - return err ? -EIO : 0; -} - - -static int ov7630_set_crop(struct sn9c102_device* cam, - const struct v4l2_rect* rect) -{ - struct sn9c102_sensor* s = &ov7630; - int err = 0; - u8 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; - - err += sn9c102_write_reg(cam, v_start, 0x13); - - return err; -} - - -static int ov7630_set_pix_format(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix) -{ - int err = 0; - - if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) - err += sn9c102_write_reg(cam, 0x20, 0x19); - else - err += sn9c102_write_reg(cam, 0x50, 0x19); - - return err; -} - - -static struct sn9c102_sensor ov7630 = { - .name = "OV7630", - .maintainer = "Luca Risolia ", - .sysfs_ops = SN9C102_I2C_WRITE, - .frequency = SN9C102_I2C_100KHZ, - .interface = SN9C102_I2C_2WIRES, - .i2c_slave_id = 0x21, - .init = &ov7630_init, - .qctrl = { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "global gain", - .minimum = 0x00, - .maximum = 0x3f, - .step = 0x01, - .default_value = 0x14, - .flags = 0, - }, - { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "hue", - .minimum = 0x00, - .maximum = 0x1f+1, - .step = 0x01, - .default_value = 0x00, - .flags = 0, - }, - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "saturation", - .minimum = 0x00, - .maximum = 0x0f, - .step = 0x01, - .default_value = 0x08, - .flags = 0, - }, - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "contrast", - .minimum = 0x00, - .maximum = 0x1f+1, - .step = 0x01, - .default_value = 0x00, - .flags = 0, - }, - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x000, - .maximum = 0x3ff, - .step = 0x001, - .default_value = 0x83<<2, - .flags = 0, - }, - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = 0x3a, - .flags = 0, - }, - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = 0x77, - .flags = 0, - }, - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "brightness", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = 0xa0, - .flags = 0, - }, - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "white balance background: blue", - .minimum = 0x00, - .maximum = 0x3f, - .step = 0x01, - .default_value = 0x20, - .flags = 0, - }, - { - .id = V4L2_CID_WHITENESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "white balance background: red", - .minimum = 0x00, - .maximum = 0x3f, - .step = 0x01, - .default_value = 0x20, - .flags = 0, - }, - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0x00, - .maximum = 0x01, - .step = 0x01, - .default_value = 0x01, - .flags = 0, - }, - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain & exposure mode", - .minimum = 0x00, - .maximum = 0x03, - .step = 0x01, - .default_value = 0x00, - .flags = 0, - }, - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0x00, - .maximum = 0x01, - .step = 0x01, - .default_value = 0x01, - .flags = 0, - }, - { - .id = V4L2_CID_BLACK_LEVEL, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "black pixel ratio", - .minimum = 0x01, - .maximum = 0x9a, - .step = 0x01, - .default_value = 0x8a, - .flags = 0, - }, - { - .id = SN9C102_V4L2_CID_BRIGHT_LEVEL, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "bright pixel ratio", - .minimum = 0x01, - .maximum = 0x9a, - .step = 0x01, - .default_value = 0x10, - .flags = 0, - }, - { - .id = SN9C102_V4L2_CID_BAND_FILTER, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "band filter", - .minimum = 0x00, - .maximum = 0x01, - .step = 0x01, - .default_value = 0x00, - .flags = 0, - }, - { - .id = SN9C102_V4L2_CID_GAMMA, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "rgb gamma", - .minimum = 0x00, - .maximum = 0x01, - .step = 0x01, - .default_value = 0x00, - .flags = 0, - }, - }, - .set_ctrl = &ov7630_set_ctrl, - .cropcap = { - .bounds = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - .defrect = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - }, - .set_crop = &ov7630_set_crop, - .pix_format = { - .width = 640, - .height = 480, - .pixelformat = V4L2_PIX_FMT_SBGGR8, - .priv = 8, - }, - .set_pix_format = &ov7630_set_pix_format -}; - - -int sn9c102_probe_ov7630(struct sn9c102_device* cam) -{ - const struct usb_device_id ov7630_id_table[] = { - { USB_DEVICE(0x0c45, 0x602c), }, - { USB_DEVICE(0x0c45, 0x602d), }, - { USB_DEVICE(0x0c45, 0x608f), }, - { USB_DEVICE(0x0c45, 0x60b0), }, - { } - }; - int err = 0; - - if (!sn9c102_match_id(cam, ov7630_id_table)) - return -ENODEV; - - err += sn9c102_write_reg(cam, 0x01, 0x01); - err += sn9c102_write_reg(cam, 0x00, 0x01); - err += sn9c102_write_reg(cam, 0x28, 0x17); - if (err) - return -EIO; - - err += sn9c102_i2c_try_write(cam, &ov7630, 0x0b, 0); - if (err) - return -ENODEV; - - sn9c102_attach_sensor(cam, &ov7630); - - return 0; -} diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bca.c b/drivers/media/video/sn9c102/sn9c102_pas202bca.c deleted file mode 100644 index c8f1ae215..000000000 --- a/drivers/media/video/sn9c102/sn9c102_pas202bca.c +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************** - * Plug-in for PAS202BCA image sensor connected to the SN9C10x PC Camera * - * Controllers * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 -#include "sn9c102_sensor.h" - - -static struct sn9c102_sensor pas202bca; - - -static int pas202bca_init(struct sn9c102_device* cam) -{ - int err = 0; - - err += sn9c102_write_reg(cam, 0x00, 0x10); - err += sn9c102_write_reg(cam, 0x00, 0x11); - err += sn9c102_write_reg(cam, 0x00, 0x14); - err += sn9c102_write_reg(cam, 0x20, 0x17); - err += sn9c102_write_reg(cam, 0x30, 0x19); - err += sn9c102_write_reg(cam, 0x09, 0x18); - - err += sn9c102_i2c_write(cam, 0x02, 0x14); - err += sn9c102_i2c_write(cam, 0x03, 0x40); - err += sn9c102_i2c_write(cam, 0x0d, 0x2c); - err += sn9c102_i2c_write(cam, 0x0e, 0x01); - err += sn9c102_i2c_write(cam, 0x0f, 0xa9); - err += sn9c102_i2c_write(cam, 0x10, 0x08); - err += sn9c102_i2c_write(cam, 0x13, 0x63); - err += sn9c102_i2c_write(cam, 0x15, 0x70); - err += sn9c102_i2c_write(cam, 0x11, 0x01); - - msleep(400); - - return err; -} - - -static int pas202bca_set_pix_format(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix) -{ - int err = 0; - - if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) - err += sn9c102_write_reg(cam, 0x24, 0x17); - else - err += sn9c102_write_reg(cam, 0x20, 0x17); - - return err; -} - - -static int pas202bca_set_ctrl(struct sn9c102_device* cam, - const struct v4l2_control* ctrl) -{ - int err = 0; - - switch (ctrl->id) { - case V4L2_CID_EXPOSURE: - err += sn9c102_i2c_write(cam, 0x04, ctrl->value >> 6); - err += sn9c102_i2c_write(cam, 0x05, ctrl->value & 0x3f); - break; - case V4L2_CID_RED_BALANCE: - err += sn9c102_i2c_write(cam, 0x09, ctrl->value); - break; - case V4L2_CID_BLUE_BALANCE: - err += sn9c102_i2c_write(cam, 0x07, ctrl->value); - break; - case V4L2_CID_GAIN: - err += sn9c102_i2c_write(cam, 0x10, ctrl->value); - break; - case SN9C102_V4L2_CID_GREEN_BALANCE: - err += sn9c102_i2c_write(cam, 0x08, ctrl->value); - break; - case SN9C102_V4L2_CID_DAC_MAGNITUDE: - err += sn9c102_i2c_write(cam, 0x0c, ctrl->value); - break; - default: - return -EINVAL; - } - err += sn9c102_i2c_write(cam, 0x11, 0x01); - - return err ? -EIO : 0; -} - - -static int pas202bca_set_crop(struct sn9c102_device* cam, - const struct v4l2_rect* rect) -{ - struct sn9c102_sensor* s = &pas202bca; - int err = 0; - u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 3, - v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3; - - err += sn9c102_write_reg(cam, h_start, 0x12); - err += sn9c102_write_reg(cam, v_start, 0x13); - - return err; -} - - -static struct sn9c102_sensor pas202bca = { - .name = "PAS202BCA", - .maintainer = "Luca Risolia ", - .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, - .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, - .interface = SN9C102_I2C_2WIRES, - .i2c_slave_id = 0x40, - .init = &pas202bca_init, - .qctrl = { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x01e5, - .maximum = 0x3fff, - .step = 0x0001, - .default_value = 0x01e5, - .flags = 0, - }, - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "global gain", - .minimum = 0x00, - .maximum = 0x1f, - .step = 0x01, - .default_value = 0x0c, - .flags = 0, - }, - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0x0f, - .step = 0x01, - .default_value = 0x01, - .flags = 0, - }, - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0x0f, - .step = 0x01, - .default_value = 0x05, - .flags = 0, - }, - { - .id = SN9C102_V4L2_CID_GREEN_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "green balance", - .minimum = 0x00, - .maximum = 0x0f, - .step = 0x01, - .default_value = 0x00, - .flags = 0, - }, - { - .id = SN9C102_V4L2_CID_DAC_MAGNITUDE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DAC magnitude", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = 0x04, - .flags = 0, - }, - }, - .set_ctrl = &pas202bca_set_ctrl, - .cropcap = { - .bounds = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - .defrect = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - }, - .set_crop = &pas202bca_set_crop, - .pix_format = { - .width = 640, - .height = 480, - .pixelformat = V4L2_PIX_FMT_SBGGR8, - .priv = 8, - }, - .set_pix_format = &pas202bca_set_pix_format -}; - - -int sn9c102_probe_pas202bca(struct sn9c102_device* cam) -{ - const struct usb_device_id pas202bca_id_table[] = { - { USB_DEVICE(0x0c45, 0x60af), }, - { } - }; - int err = 0; - - if (!sn9c102_match_id(cam,pas202bca_id_table)) - return -ENODEV; - - err += sn9c102_write_reg(cam, 0x01, 0x01); - err += sn9c102_write_reg(cam, 0x40, 0x01); - err += sn9c102_write_reg(cam, 0x28, 0x17); - if (err) - return -EIO; - - if (sn9c102_i2c_try_write(cam, &pas202bca, 0x10, 0)) /* try to write */ - return -ENODEV; - - sn9c102_attach_sensor(cam, &pas202bca); - - return 0; -} diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index af372dd25..9d769264a 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -1,4 +1,4 @@ -/* +/* * stradis.c - stradis 4:2:2 mpeg decoder driver * * Stradis 4:2:2 MPEG-2 Decoder Driver @@ -1191,9 +1191,9 @@ static void saa7146_set_winsize(struct saa7146 *saa) } /* clip_draw_rectangle(cm,x,y,w,h) -- handle clipping an area - * bitmap is fixed width, 128 bytes (1024 pixels represented) - * arranged most-sigificant-bit-left in 32-bit words - * based on saa7146 clipping hardware, it swaps bytes if LE + * bitmap is fixed width, 128 bytes (1024 pixels represented) + * arranged most-sigificant-bit-left in 32-bit words + * based on saa7146 clipping hardware, it swaps bytes if LE * much of this makes up for egcs brain damage -- so if you * are wondering "why did he do this?" it is because the C * was adjusted to generate the optimal asm output without @@ -1259,7 +1259,7 @@ static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr) clip_draw_rectangle(clipmap, cr[i].x, cr[i].y, cr[i].width, cr[i].height); } - /* clip against viewing window AND screen + /* clip against viewing window AND screen so we do not have to rely on the user program */ clip_draw_rectangle(clipmap, (saa->win.x + width > saa->win.swidth) ? @@ -2180,6 +2180,7 @@ static struct pci_device_id stradis_pci_tbl[] = { { 0 } }; +MODULE_DEVICE_TABLE(pci, stradis_pci_tbl); static struct pci_driver stradis_driver = { .name = "stradis", diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 78e043ac9..fc3d5824e 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -48,8 +48,9 @@ #include #include +#include "bttv.h" +#include #include -#include #ifndef VIDEO_AUDIO_BALANCE # define VIDEO_AUDIO_BALANCE 32 @@ -70,7 +71,7 @@ module_param(maxvol, int, S_IRUGO | S_IWUSR); /* Address to scan (I2C address of this chip) */ static unsigned short normal_i2c[] = { - I2C_ADDR_TDA7432 >> 1, + I2C_TDA7432 >> 1, I2C_CLIENT_END, }; I2C_CLIENT_INSMOD; diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index b27cc348d..65930a310 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c @@ -1,9 +1,23 @@ /* - * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $ - * - * i2c tv tuner chip device driver - * controls the philips tda8290+75 tuner chip combo. - */ + + i2c tv tuner chip device driver + controls the philips tda8290+75 tuner chip combo. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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 #include #include @@ -11,167 +25,420 @@ /* ---------------------------------------------------------------------- */ -struct freq_entry { - u16 freq; - u8 value; +struct tda827x_data { + u32 lomax; + u8 spd; + u8 bs; + u8 bp; + u8 cp; + u8 gc3; + u8 div1p5; }; -static struct freq_entry band_table[] = { - { 0x2DF4, 0x1C }, - { 0x2574, 0x14 }, - { 0x22B4, 0x0C }, - { 0x20D4, 0x0B }, - { 0x1E74, 0x3B }, - { 0x1C34, 0x33 }, - { 0x16F4, 0x5B }, - { 0x1454, 0x53 }, - { 0x12D4, 0x52 }, - { 0x1034, 0x4A }, - { 0x0EE4, 0x7A }, - { 0x0D34, 0x72 }, - { 0x0B54, 0x9A }, - { 0x0914, 0x91 }, - { 0x07F4, 0x89 }, - { 0x0774, 0xB9 }, - { 0x067B, 0xB1 }, - { 0x0634, 0xD9 }, - { 0x05A4, 0xD8 }, // FM radio - { 0x0494, 0xD0 }, - { 0x03BC, 0xC8 }, - { 0x0394, 0xF8 }, // 57250000 Hz - { 0x0000, 0xF0 }, // 0 -}; + /* Note lomax entry is lo / 62500 */ -static struct freq_entry div_table[] = { - { 0x1C34, 3 }, - { 0x0D34, 2 }, - { 0x067B, 1 }, - { 0x0000, 0 }, +static struct tda827x_data tda827x_analog[] = { + { .lomax = 992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 62 MHz */ + { .lomax = 1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 66 MHz */ + { .lomax = 1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 76 MHz */ + { .lomax = 1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 84 MHz */ + { .lomax = 1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 93 MHz */ + { .lomax = 1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 98 MHz */ + { .lomax = 1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */ + { .lomax = 1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */ + { .lomax = 2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */ + { .lomax = 2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */ + { .lomax = 2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */ + { .lomax = 2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */ + { .lomax = 2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */ + { .lomax = 3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */ + { .lomax = 3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */ + { .lomax = 4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */ + { .lomax = 4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */ + { .lomax = 5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */ + { .lomax = 5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */ + { .lomax = 7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */ + { .lomax = 7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */ + { .lomax = 8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */ + { .lomax = 8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */ + { .lomax = 9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */ + { .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */ + { .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */ + { .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */ + { .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */ + { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */ }; -static struct freq_entry agc_table[] = { - { 0x22B4, 0x8F }, - { 0x0B54, 0x9F }, - { 0x09A4, 0x8F }, - { 0x0554, 0x9F }, - { 0x0000, 0xBF }, -}; +static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq) +{ + unsigned char tuner_reg[8]; + unsigned char reg2[2]; + u32 N; + int i; + struct tuner *t = i2c_get_clientdata(c); + struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0}; + + if (t->mode == V4L2_TUNER_RADIO) + freq = freq / 1000; -static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) + N = freq + ifc; + i = 0; + while (tda827x_analog[i].lomax < N) { + if(tda827x_analog[i + 1].lomax == 0) + break; + i++; + } + + N = N << tda827x_analog[i].spd; + + tuner_reg[0] = 0; + tuner_reg[1] = (unsigned char)(N>>8); + tuner_reg[2] = (unsigned char) N; + tuner_reg[3] = 0x40; + tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5); + tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) + + (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp; + tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4); + tuner_reg[7] = 0x8f; + + msg.buf = tuner_reg; + msg.len = 8; + i2c_transfer(c->adapter, &msg, 1); + + msg.buf= reg2; + msg.len = 2; + reg2[0] = 0x80; + reg2[1] = 0; + i2c_transfer(c->adapter, &msg, 1); + + reg2[0] = 0x60; + reg2[1] = 0xbf; + i2c_transfer(c->adapter, &msg, 1); + + reg2[0] = 0x30; + reg2[1] = tuner_reg[4] + 0x80; + i2c_transfer(c->adapter, &msg, 1); + + msleep(1); + reg2[0] = 0x30; + reg2[1] = tuner_reg[4] + 4; + i2c_transfer(c->adapter, &msg, 1); + + msleep(1); + reg2[0] = 0x30; + reg2[1] = tuner_reg[4]; + i2c_transfer(c->adapter, &msg, 1); + + msleep(550); + reg2[0] = 0x30; + reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ; + i2c_transfer(c->adapter, &msg, 1); + + reg2[0] = 0x60; + reg2[1] = 0x3f; + i2c_transfer(c->adapter, &msg, 1); + + reg2[0] = 0x80; + reg2[1] = 0x08; // Vsync en + i2c_transfer(c->adapter, &msg, 1); +} + +static void tda827x_agcf(struct i2c_client *c) { - while(table->freq && table->freq > freq) - table++; - return table->value; + struct tuner *t = i2c_get_clientdata(c); + unsigned char data[] = {0x80, 0x0c}; + struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data, + .flags = 0, .len = 2}; + i2c_transfer(c->adapter, &msg, 1); } /* ---------------------------------------------------------------------- */ -static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; -static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; -static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x04, 0xA3, 0x3F, - 0x2A, 0x04, 0xFF, 0x00, - 0x00, 0x40 }; -static unsigned char i2c_set_VS[2] = { 0x30, 0x6F }; -static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B }; -static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 }; -static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 }; -static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 }; -static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 }; -static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF }; -static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 }; -static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 }; -static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 }; -static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 }; -static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F }; -static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 }; - -static struct i2c_msg i2c_msg_init[] = { - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 }, - { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, - { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS }, - { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF }, +struct tda827xa_data { + u32 lomax; + u8 svco; + u8 spd; + u8 scr; + u8 sbs; + u8 gc3; }; -static struct i2c_msg i2c_msg_prolog[] = { -// { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode }, - { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off }, - { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset }, - { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge }, +static struct tda827xa_data tda827xa_analog[] = { + { .lomax = 910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, /* 56.875 MHz */ + { .lomax = 1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 67.25 MHz */ + { .lomax = 1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 81.25 MHz */ + { .lomax = 1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 97.5 MHz */ + { .lomax = 1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, /* 113.75 MHz */ + { .lomax = 2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 134.5 MHz */ + { .lomax = 2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 154 MHz */ + { .lomax = 2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 162.5 MHz */ + { .lomax = 2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 183 MHz */ + { .lomax = 3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, /* 195 MHz */ + { .lomax = 3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, /* 227.5 MHz */ + { .lomax = 4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, /* 269 MHz */ + { .lomax = 5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, /* 325 MHz */ + { .lomax = 6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 390 MHz */ + { .lomax = 7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 455 MHz */ + { .lomax = 8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 520 MHz */ + { .lomax = 8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, /* 538 MHz */ + { .lomax = 8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 554 MHz */ + { .lomax = 9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 620 MHz */ + { .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 650 MHz */ + { .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 700 MHz */ + { .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 780 MHz */ + { .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 820 MHz */ + { .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 870 MHz */ + { .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, /* 911 MHz */ + { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */ }; -static struct i2c_msg i2c_msg_config[] = { -// { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq }, - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 }, - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF }, - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 }, - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 }, - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 }, -}; - -static struct i2c_msg i2c_msg_epilog[] = { - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 }, - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F }, - { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 }, - { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, - { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on }, -}; - -static int tda8290_tune(struct i2c_client *c) +static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) { + unsigned char tuner_reg[14]; + unsigned char reg2[2]; + u32 N; + int i; struct tuner *t = i2c_get_clientdata(c); - struct i2c_msg easy_mode = - { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode }; - struct i2c_msg set_freq = - { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq }; + struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0}; + + if (t->mode == V4L2_TUNER_RADIO) + freq = freq / 1000; - i2c_transfer(c->adapter, &easy_mode, 1); - i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog)); + N = freq + ifc; + i = 0; + while (tda827xa_analog[i].lomax < N) { + if(tda827xa_analog[i + 1].lomax == 0) + break; + i++; + } - i2c_transfer(c->adapter, &set_freq, 1); - i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config)); + N = N << tda827xa_analog[i].spd; + + tuner_reg[0] = 0; + tuner_reg[1] = (unsigned char)(N>>8); + tuner_reg[2] = (unsigned char) N; + tuner_reg[3] = 0; + tuner_reg[4] = 0x16; + tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) + + tda827xa_analog[i].sbs; + tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4); + tuner_reg[7] = 0x0c; + tuner_reg[8] = 4; + tuner_reg[9] = 0x20; + tuner_reg[10] = 0xff; + tuner_reg[11] = 0xe0; + tuner_reg[12] = 0; + tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1); + + msg.buf = tuner_reg; + msg.len = 14; + i2c_transfer(c->adapter, &msg, 1); + + msg.buf= reg2; + msg.len = 2; + reg2[0] = 0x60; + reg2[1] = 0x3c; + i2c_transfer(c->adapter, &msg, 1); + + reg2[0] = 0xa0; + reg2[1] = 0xc0; + i2c_transfer(c->adapter, &msg, 1); + + msleep(2); + reg2[0] = 0x30; + reg2[1] = 0x10 + tda827xa_analog[i].scr; + i2c_transfer(c->adapter, &msg, 1); msleep(550); - i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog)); - return 0; + reg2[0] = 0x50; + reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); + i2c_transfer(c->adapter, &msg, 1); + + reg2[0] = 0x80; + reg2[1] = 0x28; + i2c_transfer(c->adapter, &msg, 1); + + reg2[0] = 0xb0; + reg2[1] = 0x01; + i2c_transfer(c->adapter, &msg, 1); + + reg2[0] = 0xc0; + reg2[1] = 0x19 + (t->tda827x_lpsel << 1); + i2c_transfer(c->adapter, &msg, 1); } -static void set_frequency(struct tuner *t, u16 ifc) +static void tda827xa_agcf(struct i2c_client *c) { - u32 N = (((t->freq<<3)+ifc)&0x3fffc); - - N = N >> get_freq_entry(div_table, t->freq); - t->i2c_set_freq[0] = 0; - t->i2c_set_freq[1] = (unsigned char)(N>>8); - t->i2c_set_freq[2] = (unsigned char) N; - t->i2c_set_freq[3] = 0x40; - t->i2c_set_freq[4] = 0x52; - t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq); - t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq); - t->i2c_set_freq[7] = 0x8f; + struct tuner *t = i2c_get_clientdata(c); + unsigned char data[] = {0x80, 0x2c}; + struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data, + .flags = 0, .len = 2}; + i2c_transfer(c->adapter, &msg, 1); } -#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) -#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) -#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) -#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK) +/*---------------------------------------------------------------------*/ + +static void tda8290_i2c_bridge(struct i2c_client *c, int close) +{ + unsigned char enable[2] = { 0x21, 0xC0 }; + unsigned char disable[2] = { 0x21, 0x00 }; + unsigned char *msg; + if(close) { + msg = enable; + i2c_master_send(c, msg, 2); + /* let the bridge stabilize */ + msleep(20); + } else { + msg = disable; + i2c_master_send(c, msg, 2); + } +} + +/*---------------------------------------------------------------------*/ + +static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) +{ + struct tuner *t = i2c_get_clientdata(c); + unsigned char soft_reset[] = { 0x00, 0x00 }; + unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode }; + unsigned char expert_mode[] = { 0x01, 0x80 }; + unsigned char agc_out_on[] = { 0x02, 0x00 }; + unsigned char gainset_off[] = { 0x28, 0x14 }; + unsigned char if_agc_spd[] = { 0x0f, 0x88 }; + unsigned char adc_head_6[] = { 0x05, 0x04 }; + unsigned char adc_head_9[] = { 0x05, 0x02 }; + unsigned char adc_head_12[] = { 0x05, 0x01 }; + unsigned char pll_bw_nom[] = { 0x0d, 0x47 }; + unsigned char pll_bw_low[] = { 0x0d, 0x27 }; + unsigned char gainset_2[] = { 0x28, 0x64 }; + unsigned char agc_rst_on[] = { 0x0e, 0x0b }; + unsigned char agc_rst_off[] = { 0x0e, 0x09 }; + unsigned char if_agc_set[] = { 0x0f, 0x81 }; + unsigned char addr_adc_sat = 0x1a; + unsigned char addr_agc_stat = 0x1d; + unsigned char addr_pll_stat = 0x1b; + unsigned char adc_sat, agc_stat, + pll_stat; + + i2c_master_send(c, easy_mode, 2); + i2c_master_send(c, agc_out_on, 2); + i2c_master_send(c, soft_reset, 2); + msleep(1); + + expert_mode[1] = t->tda8290_easy_mode + 0x80; + i2c_master_send(c, expert_mode, 2); + i2c_master_send(c, gainset_off, 2); + i2c_master_send(c, if_agc_spd, 2); + if (t->tda8290_easy_mode & 0x60) + i2c_master_send(c, adc_head_9, 2); + else + i2c_master_send(c, adc_head_6, 2); + i2c_master_send(c, pll_bw_nom, 2); + + tda8290_i2c_bridge(c, 1); + if (t->tda827x_ver != 0) + tda827xa_tune(c, ifc, freq); + else + tda827x_tune(c, ifc, freq); + /* adjust headroom resp. gain */ + i2c_master_send(c, &addr_adc_sat, 1); + i2c_master_recv(c, &adc_sat, 1); + i2c_master_send(c, &addr_agc_stat, 1); + i2c_master_recv(c, &agc_stat, 1); + i2c_master_send(c, &addr_pll_stat, 1); + i2c_master_recv(c, &pll_stat, 1); + if (pll_stat & 0x80) + tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); + else + tuner_dbg("tda8290 not locked, no signal?\n"); + if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { + tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", + agc_stat, adc_sat, pll_stat & 0x80); + i2c_master_send(c, gainset_2, 2); + msleep(100); + i2c_master_send(c, &addr_agc_stat, 1); + i2c_master_recv(c, &agc_stat, 1); + i2c_master_send(c, &addr_pll_stat, 1); + i2c_master_recv(c, &pll_stat, 1); + if ((agc_stat > 115) || !(pll_stat & 0x80)) { + tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", + agc_stat, pll_stat & 0x80); + if (t->tda827x_ver != 0) + tda827xa_agcf(c); + else + tda827x_agcf(c); + msleep(100); + i2c_master_send(c, &addr_agc_stat, 1); + i2c_master_recv(c, &agc_stat, 1); + i2c_master_send(c, &addr_pll_stat, 1); + i2c_master_recv(c, &pll_stat, 1); + if((agc_stat > 115) || !(pll_stat & 0x80)) { + tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); + i2c_master_send(c, adc_head_12, 2); + i2c_master_send(c, pll_bw_low, 2); + msleep(100); + } + } + } + + /* l/ l' deadlock? */ + if(t->tda8290_easy_mode & 0x60) { + i2c_master_send(c, &addr_adc_sat, 1); + i2c_master_recv(c, &adc_sat, 1); + i2c_master_send(c, &addr_pll_stat, 1); + i2c_master_recv(c, &pll_stat, 1); + if ((adc_sat > 20) || !(pll_stat & 0x80)) { + tuner_dbg("trying to resolve SECAM L deadlock\n"); + i2c_master_send(c, agc_rst_on, 2); + msleep(40); + i2c_master_send(c, agc_rst_off, 2); + } + } + + tda8290_i2c_bridge(c, 0); + i2c_master_send(c, if_agc_set, 2); + return 0; +} + +/*---------------------------------------------------------------------*/ static void set_audio(struct tuner *t) { - t->i2c_easy_mode[0] = 0x01; - - if (t->std & V4L2_STD_MN) - t->i2c_easy_mode[1] = 0x01; - else if (t->std & V4L2_STD_B) - t->i2c_easy_mode[1] = 0x02; - else if (t->std & V4L2_STD_GH) - t->i2c_easy_mode[1] = 0x04; - else if (t->std & V4L2_STD_PAL_I) - t->i2c_easy_mode[1] = 0x08; - else if (t->std & V4L2_STD_DK) - t->i2c_easy_mode[1] = 0x10; - else if (t->std & V4L2_STD_SECAM_L) - t->i2c_easy_mode[1] = 0x20; + char* mode; + + t->tda827x_lpsel = 0; + mode = "xx"; + if (t->std & V4L2_STD_MN) { + t->sgIF = 92; + t->tda8290_easy_mode = 0x01; + t->tda827x_lpsel = 1; + mode = "MN"; + } else if (t->std & V4L2_STD_B) { + t->sgIF = 108; + t->tda8290_easy_mode = 0x02; + mode = "B"; + } else if (t->std & V4L2_STD_GH) { + t->sgIF = 124; + t->tda8290_easy_mode = 0x04; + mode = "GH"; + } else if (t->std & V4L2_STD_PAL_I) { + t->sgIF = 124; + t->tda8290_easy_mode = 0x08; + mode = "I"; + } else if (t->std & V4L2_STD_DK) { + t->sgIF = 124; + t->tda8290_easy_mode = 0x10; + mode = "DK"; + } else if (t->std & V4L2_STD_SECAM_L) { + t->sgIF = 124; + t->tda8290_easy_mode = 0x20; + mode = "L"; + } else if (t->std & V4L2_STD_SECAM_LC) { + t->sgIF = 20; + t->tda8290_easy_mode = 0x40; + mode = "LC"; + } + tuner_dbg("setting tda8290 to system %s\n", mode); } static void set_tv_freq(struct i2c_client *c, unsigned int freq) @@ -179,15 +446,13 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) struct tuner *t = i2c_get_clientdata(c); set_audio(t); - set_frequency(t, 864); - tda8290_tune(c); + tda8290_tune(c, t->sgIF, freq); } static void set_radio_freq(struct i2c_client *c, unsigned int freq) { - struct tuner *t = i2c_get_clientdata(c); - set_frequency(t, 704); - tda8290_tune(c); + /* if frequency is 5.5 MHz */ + tda8290_tune(c, 88, freq); } static int has_signal(struct i2c_client *c) @@ -200,21 +465,149 @@ static int has_signal(struct i2c_client *c) return (afc & 0x80)? 65535:0; } +/*---------------------------------------------------------------------*/ + +static void standby(struct i2c_client *c) +{ + struct tuner *t = i2c_get_clientdata(c); + unsigned char cb1[] = { 0x30, 0xD0 }; + unsigned char tda8290_standby[] = { 0x00, 0x02 }; + unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; + struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; + + tda8290_i2c_bridge(c, 1); + if (t->tda827x_ver != 0) + cb1[1] = 0x90; + i2c_transfer(c->adapter, &msg, 1); + tda8290_i2c_bridge(c, 0); + i2c_master_send(c, tda8290_agc_tri, 2); + i2c_master_send(c, tda8290_standby, 2); +} + + +static void tda8290_init_if(struct i2c_client *c) +{ + unsigned char set_VS[] = { 0x30, 0x6F }; + unsigned char set_GP01_CF[] = { 0x20, 0x0B }; + + i2c_master_send(c, set_VS, 2); + i2c_master_send(c, set_GP01_CF, 2); +} + +static void tda8290_init_tuner(struct i2c_client *c) +{ + struct tuner *t = i2c_get_clientdata(c); + unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, + 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; + unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, + 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; + struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, + .buf=tda8275_init, .len = 14}; + if (t->tda827x_ver != 0) + msg.buf = tda8275a_init; + + tda8290_i2c_bridge(c, 1); + i2c_transfer(c->adapter, &msg, 1); + tda8290_i2c_bridge(c, 0); +} + +/*---------------------------------------------------------------------*/ + int tda8290_init(struct i2c_client *c) { struct tuner *t = i2c_get_clientdata(c); + u8 data; + int i, ret, tuners_found; + u32 tuner_addrs; + struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1}; + + tda8290_i2c_bridge(c, 1); + /* probe for tuner chip */ + tuners_found = 0; + tuner_addrs = 0; + for (i=0x60; i<= 0x63; i++) { + msg.addr = i; + ret = i2c_transfer(c->adapter, &msg, 1); + if (ret == 1) { + tuners_found++; + tuner_addrs = (tuner_addrs << 8) + i; + } + } + /* if there is more than one tuner, we expect the right one is + behind the bridge and we choose the highest address that doesn't + give a response now + */ + tda8290_i2c_bridge(c, 0); + if(tuners_found > 1) + for (i = 0; i < tuners_found; i++) { + msg.addr = tuner_addrs & 0xff; + ret = i2c_transfer(c->adapter, &msg, 1); + if(ret == 1) + tuner_addrs = tuner_addrs >> 8; + else + break; + } + if (tuner_addrs == 0) { + tuner_addrs = 0x61; + tuner_info ("could not clearly identify tuner address, defaulting to %x\n", + tuner_addrs); + } else { + tuner_addrs = tuner_addrs & 0xff; + tuner_info ("setting tuner address to %x\n", tuner_addrs); + } + t->tda827x_addr = tuner_addrs; + msg.addr = tuner_addrs; - strlcpy(c->name, "tda8290+75", sizeof(c->name)); + tda8290_i2c_bridge(c, 1); + ret = i2c_transfer(c->adapter, &msg, 1); + if( ret != 1) + tuner_warn ("TDA827x access failed!\n"); + if ((data & 0x3c) == 0) { + strlcpy(c->name, "tda8290+75", sizeof(c->name)); + t->tda827x_ver = 0; + } else { + strlcpy(c->name, "tda8290+75a", sizeof(c->name)); + t->tda827x_ver = 2; + } tuner_info("tuner: type set to %s\n", c->name); - t->tv_freq = set_tv_freq; - t->radio_freq = set_radio_freq; + + t->set_tv_freq = set_tv_freq; + t->set_radio_freq = set_radio_freq; t->has_signal = has_signal; + t->standby = standby; + t->tda827x_lpsel = 0; - i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge)); - i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init)); + tda8290_init_tuner(c); + tda8290_init_if(c); return 0; } +int tda8290_probe(struct i2c_client *c) +{ + unsigned char soft_reset[] = { 0x00, 0x00 }; + unsigned char easy_mode_b[] = { 0x01, 0x02 }; + unsigned char easy_mode_g[] = { 0x01, 0x04 }; + unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 }; + unsigned char addr_dto_lsb = 0x07; + unsigned char data; + + i2c_master_send(c, easy_mode_b, 2); + i2c_master_send(c, soft_reset, 2); + i2c_master_send(c, &addr_dto_lsb, 1); + i2c_master_recv(c, &data, 1); + if (data == 0) { + i2c_master_send(c, easy_mode_g, 2); + i2c_master_send(c, soft_reset, 2); + i2c_master_send(c, &addr_dto_lsb, 1); + i2c_master_recv(c, &data, 1); + if (data == 0x7b) { + return 0; + } + } + i2c_master_send(c, restore_9886, 3); + return -1; +} + /* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index ef494febb..ed4c04119 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -24,7 +24,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include #include @@ -35,7 +34,7 @@ static int debug = 0; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) #define SWITCH 0x00 #define LEVEL_ADJUST 0x02 @@ -43,7 +42,7 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #define TEST 0x04 /* addresses to scan, found only at 0x42 (7-Bit) */ -static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { I2C_TDA9840, I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; @@ -223,7 +222,7 @@ static int detach(struct i2c_client *client) static struct i2c_driver driver = { .driver = { - .name = "tda9840", + .name = "tda9840", }, .id = I2C_DRIVERID_TDA9840, .attach_adapter = attach, diff --git a/drivers/media/video/tda9840.h b/drivers/media/video/tda9840.h index 7da8432cd..28021053b 100644 --- a/drivers/media/video/tda9840.h +++ b/drivers/media/video/tda9840.h @@ -1,7 +1,7 @@ #ifndef __INCLUDED_TDA9840__ #define __INCLUDED_TDA9840__ -#define I2C_ADDR_TDA9840 0x42 +#define I2C_TDA9840 0x42 #define TDA9840_DETECT _IOR('v',1,int) /* return values for TDA9840_DETCT */ diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 103ccb919..ef98c4982 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -30,22 +30,24 @@ #include #include - -#include +#include "bttv.h" +#include static int debug; /* insmod parameter */ module_param(debug, int, S_IRUGO | S_IWUSR); MODULE_LICENSE("GPL"); + /* Addresses to scan */ static unsigned short normal_i2c[] = { - I2C_ADDR_TDA9875 >> 1, + I2C_TDA9875 >> 1, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; /* This is a superset of the TDA9875 */ struct tda9875 { + int mode; int rvol, lvol; int bass, treble; struct i2c_client c; @@ -195,6 +197,7 @@ static void do_tda9875_init(struct i2c_client *client) tda9875_write(client, TDA9875_MUT, 0xcc ); /* General mute */ + t->mode=AUDIO_UNMUTE; t->lvol=t->rvol =0; /* 0dB */ t->bass=0; /* 0dB */ t->treble=0; /* 0dB */ diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 523df0b8c..bb35844e3 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c @@ -26,7 +26,6 @@ Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA. */ - #include #include #include @@ -37,7 +36,7 @@ static int debug = 0; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) #define TEA6415C_NUM_INPUTS 8 #define TEA6415C_NUM_OUTPUTS 6 @@ -108,7 +107,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o) { u8 byte = 0; int ret; - + dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); /* check if the pins are valid */ @@ -192,7 +191,7 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) static struct i2c_driver driver = { .driver = { - .name = "tea6415c", + .name = "tea6415c", }, .id = I2C_DRIVERID_TEA6415C, .attach_adapter = attach, diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index e0ff811fa..4dcba5a4f 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -26,7 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include #include @@ -37,10 +36,10 @@ static int debug = 0; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ -static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; @@ -84,7 +83,7 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } - + return 0; } @@ -168,7 +167,7 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) static struct i2c_driver driver = { .driver = { - .name = "tea6420", + .name = "tea6420", }, .id = I2C_DRIVERID_TEA6420, .attach_adapter = attach, diff --git a/drivers/media/video/tea6420.h b/drivers/media/video/tea6420.h index 5ef7c18e0..ea664df15 100644 --- a/drivers/media/video/tea6420.h +++ b/drivers/media/video/tea6420.h @@ -2,8 +2,8 @@ #define __INCLUDED_TEA6420__ /* possible addresses */ -#define I2C_ADDR_TEA6420_1 0x4c -#define I2C_ADDR_TEA6420_2 0x4d +#define I2C_TEA6420_1 0x4c +#define I2C_TEA6420_2 0x4d struct tea6420_multiplex { diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c index 74ab48c09..c4a78e7a5 100644 --- a/drivers/media/video/tuner-3036.c +++ b/drivers/media/video/tuner-3036.c @@ -5,7 +5,7 @@ * * The SAB3036 is just about different enough from the chips that * tuner.c copes with to make it not worth the effort to crowbar - * the support into that file. So instead we have a separate driver. + * the support into that file. So instead we have a separate driver. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -56,15 +56,15 @@ tuner_getstatus (struct i2c_client *c) #define TUNER_FL 0x80 -static int +static int tuner_islocked (struct i2c_client *c) { - return (tuner_getstatus(c) & TUNER_FL); + return (tuner_getstatus(c) & TUNER_FL); } /* ---------------------------------------------------------------------- */ -static void +static void set_tv_freq(struct i2c_client *c, int freq) { u16 div = ((freq * 20) / 16); @@ -73,26 +73,26 @@ set_tv_freq(struct i2c_client *c, int freq) if (debug) printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div); - + /* Select high tuning current */ buffer[0] = 0x29; buffer[1] = 0x3e; if (i2c_master_send(c, buffer, 2) != 2) printk("tuner: i2c i/o error 1\n"); - + buffer[0] = 0x80 | ((div>>8) & 0x7f); buffer[1] = div & 0xff; if (i2c_master_send(c, buffer, 2) != 2) printk("tuner: i2c i/o error 2\n"); - + while (!tuner_islocked(c) && time_before(jiffies, give_up)) schedule(); - + if (!tuner_islocked(c)) printk(KERN_WARNING "tuner: failed to achieve PLL lock\n"); - + /* Select low tuning current and engage AFC */ buffer[0] = 0x29; buffer[1] = 0xb2; @@ -106,7 +106,7 @@ set_tv_freq(struct i2c_client *c, int freq) /* ---------------------------------------------------------------------- */ -static int +static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) { static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 }; @@ -116,18 +116,18 @@ tuner_attach(struct i2c_adapter *adap, int addr, int kind) if (this_adap > 0) return -1; this_adap++; - - client_template.adapter = adap; - client_template.addr = addr; + + client_template.adapter = adap; + client_template.addr = addr; client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memcpy(client, &client_template, sizeof(struct i2c_client)); + if (client == NULL) + return -ENOMEM; + memcpy(client, &client_template, sizeof(struct i2c_client)); printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client)); - i2c_attach_client(client); + i2c_attach_client(client); if (i2c_master_send(client, buffer, 2) != 2) printk("tuner: i2c i/o error 1\n"); @@ -138,30 +138,30 @@ tuner_attach(struct i2c_adapter *adap, int addr, int kind) return 0; } -static int +static int tuner_detach(struct i2c_client *c) { return 0; } -static int +static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { int *iarg = (int*)arg; - switch (cmd) + switch (cmd) { case VIDIOCSFREQ: set_tv_freq(client, *iarg); break; - + default: return -EINVAL; } return 0; } -static int +static int tuner_probe(struct i2c_adapter *adap) { this_adap = 0; @@ -172,8 +172,8 @@ tuner_probe(struct i2c_adapter *adap) /* ----------------------------------------------------------------------- */ -static struct i2c_driver -i2c_driver_tuner = +static struct i2c_driver +i2c_driver_tuner = { .driver = { .name = "sab3036", @@ -186,7 +186,7 @@ i2c_driver_tuner = static struct i2c_client client_template = { - .driver = &i2c_driver_tuner, + .driver = &i2c_driver_tuner, .name = "SAB3036", }; diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 1013b4de8..b6101bf44 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -21,6 +21,7 @@ #include #include +#include #define UNSET (-1U) @@ -172,6 +173,7 @@ static void set_type(struct i2c_client *c, unsigned int type, } t->type = type; + switch (t->type) { case TUNER_MT2032: microtune_init(c); @@ -401,17 +403,16 @@ static void tuner_status(struct i2c_client *client) } tuner_info("Tuner mode: %s\n", p); tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); - tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std); - if (t->mode != V4L2_TUNER_RADIO) - return; - if (t->has_signal) { - tuner_info("Signal strength: %d\n", t->has_signal(client)); - } - if (t->is_stereo) { - tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no"); + tuner_info("Standard: 0x%08llx\n", t->std); + if (t->mode == V4L2_TUNER_RADIO) { + if (t->has_signal) { + tuner_info("Signal strength: %d\n", t->has_signal(client)); + } + if (t->is_stereo) { + tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no"); + } } } - /* ---------------------------------------------------------------------- */ /* static var Used only in tuner_attach and tuner_probe */ @@ -558,10 +559,10 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, static inline int check_v4l2(struct tuner *t) { - /* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for - TV, v4l1 for radio), until that is fixed this code is disabled. - Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2) - first. */ + if (t->using_v4l2) { + tuner_dbg ("ignore v4l1 call\n"); + return EINVAL; + } return 0; } @@ -743,31 +744,33 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; switch_v4l2(); - tuner->type = t->mode; - if (t->mode == V4L2_TUNER_ANALOG_TV) - tuner->capability |= V4L2_TUNER_CAP_NORM; - if (t->mode != V4L2_TUNER_RADIO) { - tuner->rangelow = tv_range[0] * 16; - tuner->rangehigh = tv_range[1] * 16; - break; - } + if (V4L2_TUNER_RADIO == t->mode) { - /* radio mode */ - if (t->has_signal) - tuner->signal = t->has_signal(client); + if (t->has_signal) + tuner->signal = t->has_signal(client); - tuner->rxsubchans = - V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - if (t->is_stereo) { - tuner->rxsubchans = t->is_stereo(client) ? - V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; - } + if (t->is_stereo) { + if (t->is_stereo(client)) { + tuner->rxsubchans = + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_MONO; + } else { + tuner->rxsubchans = + V4L2_TUNER_SUB_MONO; + } + } + + tuner->capability |= + V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; + + tuner->audmode = t->audmode; - tuner->capability |= - V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; - tuner->audmode = t->audmode; - tuner->rangelow = radio_range[0] * 16000; - tuner->rangehigh = radio_range[1] * 16000; + tuner->rangelow = radio_range[0] * 16000; + tuner->rangehigh = radio_range[1] * 16000; + } else { + tuner->rangelow = tv_range[0] * 16; + tuner->rangehigh = tv_range[1] * 16; + } break; } case VIDIOC_S_TUNER: @@ -779,11 +782,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) switch_v4l2(); - /* do nothing unless we're a radio tuner */ - if (t->mode != V4L2_TUNER_RADIO) - break; - t->audmode = tuner->audmode; - set_radio_freq(client, t->radio_freq); + if (V4L2_TUNER_RADIO == t->mode) { + t->audmode = tuner->audmode; + set_radio_freq(client, t->radio_freq); + } break; } case VIDIOC_LOG_STATUS: diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 5d7abed71..4f2ff1769 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -79,6 +79,17 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); #define TUNER_PLL_LOCKED 0x40 #define TUNER_STEREO_MK3 0x04 +#define TUNER_PARAM_ANALOG 0 /* to be removed */ +/* FIXME: + * Right now, all tuners are using the first tuner_params[] array element + * for analog mode. In the future, we will be merging similar tuner + * definitions together, such that each tuner definition will have a + * tuner_params struct for each available video standard. At that point, + * TUNER_PARAM_ANALOG will be removed, and the tuner_params[] array + * element will be chosen based on the video standard in use. + * + */ + /* ---------------------------------------------------------------------- */ static int tuner_getstatus(struct i2c_client *c) @@ -107,6 +118,7 @@ static int tuner_stereo(struct i2c_client *c) case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FM1256_IH3: + case TUNER_LG_NTSC_TAPE: stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); break; default: @@ -122,53 +134,14 @@ static int tuner_stereo(struct i2c_client *c) static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) { struct tuner *t = i2c_get_clientdata(c); - u8 config, cb, tuneraddr; + u8 config, tuneraddr; u16 div; struct tunertype *tun; u8 buffer[4]; int rc, IFPCoff, i, j; - enum param_type desired_type; tun = &tuners[t->type]; - - /* IFPCoff = Video Intermediate Frequency - Vif: - 940 =16*58.75 NTSC/J (Japan) - 732 =16*45.75 M/N STD - 704 =16*44 ATSC (at DVB code) - 632 =16*39.50 I U.K. - 622.4=16*38.90 B/G D/K I, L STD - 592 =16*37.00 D China - 590 =16.36.875 B Australia - 543.2=16*33.95 L' STD - 171.2=16*10.70 FM Radio (at set_radio_freq) - */ - - if (t->std == V4L2_STD_NTSC_M_JP) { - IFPCoff = 940; - desired_type = TUNER_PARAM_TYPE_NTSC; - } else if ((t->std & V4L2_STD_MN) && - !(t->std & ~V4L2_STD_MN)) { - IFPCoff = 732; - desired_type = TUNER_PARAM_TYPE_NTSC; - } else if (t->std == V4L2_STD_SECAM_LC) { - IFPCoff = 543; - desired_type = TUNER_PARAM_TYPE_SECAM; - } else { - IFPCoff = 623; - desired_type = TUNER_PARAM_TYPE_PAL; - } - - for (j = 0; j < tun->count-1; j++) { - if (desired_type != tun->params[j].type) - continue; - break; - } - /* use default tuner_params if desired_type not available */ - if (desired_type != tun->params[j].type) { - tuner_dbg("IFPCoff = %d: tuner_params undefined for tuner %d\n", - IFPCoff,t->type); - j = 0; - } + j = TUNER_PARAM_ANALOG; for (i = 0; i < tun->params[j].count; i++) { if (freq > tun->params[j].ranges[i].limit) @@ -180,20 +153,11 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) freq, tun->params[j].ranges[i - 1].limit); freq = tun->params[j].ranges[--i].limit; } - config = tun->params[j].ranges[i].config; - cb = tun->params[j].ranges[i].cb; - /* i == 0 -> VHF_LO - * i == 1 -> VHF_HI - * i == 2 -> UHF */ - tuner_dbg("tv: param %d, range %d\n",j,i); - - div=freq + IFPCoff + offset; - - tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", - freq / 16, freq % 16 * 100 / 16, - IFPCoff / 16, IFPCoff % 16 * 100 / 16, - offset / 16, offset % 16 * 100 / 16, - div); + config = tun->params[j].ranges[i].cb; + /* i == 0 -> VHF_LO */ + /* i == 1 -> VHF_HI */ + /* i == 2 -> UHF */ + tuner_dbg("tv: range %d\n",i); /* tv norm specific stuff for multi-norm tuners */ switch (t->type) { @@ -201,40 +165,40 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) /* 0x01 -> ??? no change ??? */ /* 0x02 -> PAL BDGHI / SECAM L */ /* 0x04 -> ??? PAL others / SECAM others ??? */ - cb &= ~0x02; + config &= ~0x02; if (t->std & V4L2_STD_SECAM) - cb |= 0x02; + config |= 0x02; break; case TUNER_TEMIC_4046FM5: - cb &= ~0x0f; + config &= ~0x0f; if (t->std & V4L2_STD_PAL_BG) { - cb |= TEMIC_SET_PAL_BG; + config |= TEMIC_SET_PAL_BG; } else if (t->std & V4L2_STD_PAL_I) { - cb |= TEMIC_SET_PAL_I; + config |= TEMIC_SET_PAL_I; } else if (t->std & V4L2_STD_PAL_DK) { - cb |= TEMIC_SET_PAL_DK; + config |= TEMIC_SET_PAL_DK; } else if (t->std & V4L2_STD_SECAM_L) { - cb |= TEMIC_SET_PAL_L; + config |= TEMIC_SET_PAL_L; } break; case TUNER_PHILIPS_FQ1216ME: - cb &= ~0x0f; + config &= ~0x0f; if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { - cb |= PHILIPS_SET_PAL_BGDK; + config |= PHILIPS_SET_PAL_BGDK; } else if (t->std & V4L2_STD_PAL_I) { - cb |= PHILIPS_SET_PAL_I; + config |= PHILIPS_SET_PAL_I; } else if (t->std & V4L2_STD_SECAM_L) { - cb |= PHILIPS_SET_PAL_L; + config |= PHILIPS_SET_PAL_L; } break; @@ -244,15 +208,15 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) /* 0x01 -> ATSC antenna input 2 */ /* 0x02 -> NTSC antenna input 1 */ /* 0x03 -> NTSC antenna input 2 */ - cb &= ~0x03; + config &= ~0x03; if (!(t->std & V4L2_STD_ATSC)) - cb |= 2; + config |= 2; /* FIXME: input */ break; case TUNER_MICROTUNE_4042FI5: /* Set the charge pump for fast tuning */ - config |= TUNER_CHARGE_PUMP; + tun->params[j].config |= TUNER_CHARGE_PUMP; break; case TUNER_PHILIPS_TUV1236D: @@ -264,9 +228,9 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) buffer[1] = 0x00; buffer[2] = 0x17; buffer[3] = 0x00; - cb &= ~0x40; + config &= ~0x40; if (t->std & V4L2_STD_ATSC) { - cb |= 0x40; + config |= 0x40; buffer[1] = 0x04; } /* set to the correct mode (analog or digital) */ @@ -281,16 +245,47 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) break; } + /* IFPCoff = Video Intermediate Frequency - Vif: + 940 =16*58.75 NTSC/J (Japan) + 732 =16*45.75 M/N STD + 704 =16*44 ATSC (at DVB code) + 632 =16*39.50 I U.K. + 622.4=16*38.90 B/G D/K I, L STD + 592 =16*37.00 D China + 590 =16.36.875 B Australia + 543.2=16*33.95 L' STD + 171.2=16*10.70 FM Radio (at set_radio_freq) + */ + + if (t->std == V4L2_STD_NTSC_M_JP) { + IFPCoff = 940; + } else if ((t->std & V4L2_STD_MN) && + !(t->std & ~V4L2_STD_MN)) { + IFPCoff = 732; + } else if (t->std == V4L2_STD_SECAM_LC) { + IFPCoff = 543; + } else { + IFPCoff = 623; + } + + div=freq + IFPCoff + offset; + + tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", + freq / 16, freq % 16 * 100 / 16, + IFPCoff / 16, IFPCoff % 16 * 100 / 16, + offset / 16, offset % 16 * 100 / 16, + div); + if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) { - buffer[0] = config; - buffer[1] = cb; + buffer[0] = tun->params[j].config; + buffer[1] = config; buffer[2] = (div>>8) & 0x7f; buffer[3] = div & 0xff; } else { buffer[0] = (div>>8) & 0x7f; buffer[1] = div & 0xff; - buffer[2] = config; - buffer[3] = cb; + buffer[2] = tun->params[j].config; + buffer[3] = config; } t->last_div = div; tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", @@ -318,11 +313,11 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) } /* Set the charge pump for optimized phase noise figure */ - config &= ~TUNER_CHARGE_PUMP; + tun->params[j].config &= ~TUNER_CHARGE_PUMP; buffer[0] = (div>>8) & 0x7f; buffer[1] = div & 0xff; - buffer[2] = config; - buffer[3] = cb; + buffer[2] = tun->params[j].config; + buffer[3] = config; tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", buffer[0],buffer[1],buffer[2],buffer[3]); @@ -338,21 +333,12 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) u8 buffer[4]; u16 div; int rc, j; - enum param_type desired_type = TUNER_PARAM_TYPE_RADIO; tun = &tuners[t->type]; - - for (j = 0; j < tun->count-1; j++) { - if (desired_type != tun->params[j].type) - continue; - break; - } - /* use default tuner_params if desired_type not available */ - if (desired_type != tun->params[j].type) - j = 0; + j = TUNER_PARAM_ANALOG; div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */ - buffer[2] = (tun->params[j].ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */ + buffer[2] = (tun->params[j].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */ switch (t->type) { case TUNER_TENA_9533_DI: @@ -362,11 +348,9 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FMD1216ME_MK3: + case TUNER_LG_NTSC_TAPE: buffer[3] = 0x19; break; - case TUNER_TNF_5335MF: - buffer[3] = 0x11; - break; case TUNER_PHILIPS_FM1256_IH3: div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */ buffer[3] = 0x19; diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index a1ae036b4..1aa0ca691 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c @@ -23,25 +23,22 @@ * Each tuner_params array may contain one or more elements, one * for each video standard. * - * FIXME: tuner_params struct contains an element, tda988x. We must - * set this for all tuners that contain a tda988x chip, and then we - * can remove this setting from the various card structs. + * FIXME: Some tuner_range definitions are duplicated, and + * should be eliminated. * - * FIXME: Right now, all tuners are using the first tuner_params[] - * array element for analog mode. In the future, we will be merging - * similar tuner definitions together, such that each tuner definition - * will have a tuner_params struct for each available video standard. - * At that point, the tuner_params[] array element will be chosen - * based on the video standard in use. + * FIXME: tunertype struct contains an element, has_tda988x. + * We must set this for all tunertypes that contain a tda988x + * chip, and then we can remove this setting from the various + * card structs. */ /* 0-9 */ /* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */ static struct tuner_range tuner_temic_pal_ranges[] = { - { 16 * 140.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 463.25 /*MHz*/, 0x8e, 0x04, }, - { 16 * 999.99 , 0x8e, 0x01, }, + { 16 * 140.25 /*MHz*/, 0x02, }, + { 16 * 463.25 /*MHz*/, 0x04, }, + { 16 * 999.99 , 0x01, }, }; static struct tuner_params tuner_temic_pal_params[] = { @@ -49,15 +46,16 @@ static struct tuner_params tuner_temic_pal_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_pal_ranges, .count = ARRAY_SIZE(tuner_temic_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */ static struct tuner_range tuner_philips_pal_i_ranges[] = { - { 16 * 140.25 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 140.25 /*MHz*/, 0xa0, }, + { 16 * 463.25 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_philips_pal_i_params[] = { @@ -65,15 +63,16 @@ static struct tuner_params tuner_philips_pal_i_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_philips_pal_i_ranges, .count = ARRAY_SIZE(tuner_philips_pal_i_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */ static struct tuner_range tuner_philips_ntsc_ranges[] = { - { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 451.25 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 157.25 /*MHz*/, 0xa0, }, + { 16 * 451.25 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_philips_ntsc_params[] = { @@ -81,6 +80,7 @@ static struct tuner_params tuner_philips_ntsc_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_philips_ntsc_ranges, .count = ARRAY_SIZE(tuner_philips_ntsc_ranges), + .config = 0x8e, .cb_first_if_lower_freq = 1, }, }; @@ -88,9 +88,9 @@ static struct tuner_params tuner_philips_ntsc_params[] = { /* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */ static struct tuner_range tuner_philips_secam_ranges[] = { - { 16 * 168.25 /*MHz*/, 0x8e, 0xa7, }, - { 16 * 447.25 /*MHz*/, 0x8e, 0x97, }, - { 16 * 999.99 , 0x8e, 0x37, }, + { 16 * 168.25 /*MHz*/, 0xa7, }, + { 16 * 447.25 /*MHz*/, 0x97, }, + { 16 * 999.99 , 0x37, }, }; static struct tuner_params tuner_philips_secam_params[] = { @@ -98,6 +98,7 @@ static struct tuner_params tuner_philips_secam_params[] = { .type = TUNER_PARAM_TYPE_SECAM, .ranges = tuner_philips_secam_ranges, .count = ARRAY_SIZE(tuner_philips_secam_ranges), + .config = 0x8e, .cb_first_if_lower_freq = 1, }, }; @@ -105,9 +106,9 @@ static struct tuner_params tuner_philips_secam_params[] = { /* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */ static struct tuner_range tuner_philips_pal_ranges[] = { - { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 447.25 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 168.25 /*MHz*/, 0xa0, }, + { 16 * 447.25 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_philips_pal_params[] = { @@ -115,6 +116,7 @@ static struct tuner_params tuner_philips_pal_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_philips_pal_ranges, .count = ARRAY_SIZE(tuner_philips_pal_ranges), + .config = 0x8e, .cb_first_if_lower_freq = 1, }, }; @@ -122,9 +124,9 @@ static struct tuner_params tuner_philips_pal_params[] = { /* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */ static struct tuner_range tuner_temic_ntsc_ranges[] = { - { 16 * 157.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 463.25 /*MHz*/, 0x8e, 0x04, }, - { 16 * 999.99 , 0x8e, 0x01, }, + { 16 * 157.25 /*MHz*/, 0x02, }, + { 16 * 463.25 /*MHz*/, 0x04, }, + { 16 * 999.99 , 0x01, }, }; static struct tuner_params tuner_temic_ntsc_params[] = { @@ -132,15 +134,16 @@ static struct tuner_params tuner_temic_ntsc_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_temic_ntsc_ranges, .count = ARRAY_SIZE(tuner_temic_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */ static struct tuner_range tuner_temic_pal_i_ranges[] = { - { 16 * 170.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 450.00 /*MHz*/, 0x8e, 0x04, }, - { 16 * 999.99 , 0x8e, 0x01, }, + { 16 * 170.00 /*MHz*/, 0x02, }, + { 16 * 450.00 /*MHz*/, 0x04, }, + { 16 * 999.99 , 0x01, }, }; static struct tuner_params tuner_temic_pal_i_params[] = { @@ -148,15 +151,16 @@ static struct tuner_params tuner_temic_pal_i_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_pal_i_ranges, .count = ARRAY_SIZE(tuner_temic_pal_i_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */ static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = { - { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 157.25 /*MHz*/, 0xa0, }, + { 16 * 463.25 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = { @@ -164,15 +168,16 @@ static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_temic_4036fy5_ntsc_ranges, .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */ static struct tuner_range tuner_alps_tsb_1_ranges[] = { - { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 385.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, + { 16 * 137.25 /*MHz*/, 0x01, }, + { 16 * 385.25 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = { @@ -180,6 +185,7 @@ static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_alps_tsb_1_ranges, .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges), + .config = 0x8e, }, }; @@ -191,15 +197,16 @@ static struct tuner_params tuner_alps_tsb_1_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_alps_tsb_1_ranges, .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */ static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = { - { 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 351.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, + { 16 * 133.25 /*MHz*/, 0x01, }, + { 16 * 351.25 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; static struct tuner_params tuner_alps_tsbb5_params[] = { @@ -207,6 +214,7 @@ static struct tuner_params tuner_alps_tsbb5_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_alps_tsb_5_pal_ranges, .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), + .config = 0x8e, }, }; @@ -217,6 +225,7 @@ static struct tuner_params tuner_alps_tsbe5_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_alps_tsb_5_pal_ranges, .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), + .config = 0x8e, }, }; @@ -227,31 +236,33 @@ static struct tuner_params tuner_alps_tsbc5_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_alps_tsb_5_pal_ranges, .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */ -static struct tuner_range tuner_lg_pal_ranges[] = { - { 16 * 170.00 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 450.00 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, +static struct tuner_range tuner_temic_4006fh5_pal_ranges[] = { + { 16 * 170.00 /*MHz*/, 0xa0, }, + { 16 * 450.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_temic_4006fh5_params[] = { { .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_lg_pal_ranges, - .count = ARRAY_SIZE(tuner_lg_pal_ranges), + .ranges = tuner_temic_4006fh5_pal_ranges, + .count = ARRAY_SIZE(tuner_temic_4006fh5_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */ static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = { - { 16 * 137.25 /*MHz*/, 0x8e, 0x14, }, - { 16 * 385.25 /*MHz*/, 0x8e, 0x12, }, - { 16 * 999.99 , 0x8e, 0x11, }, + { 16 * 137.25 /*MHz*/, 0x14, }, + { 16 * 385.25 /*MHz*/, 0x12, }, + { 16 * 999.99 , 0x11, }, }; static struct tuner_params tuner_alps_tshc6_params[] = { @@ -259,15 +270,16 @@ static struct tuner_params tuner_alps_tshc6_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_alps_tshc6_ntsc_ranges, .count = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */ static struct tuner_range tuner_temic_pal_dk_ranges[] = { - { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 456.25 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 168.25 /*MHz*/, 0xa0, }, + { 16 * 456.25 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_temic_pal_dk_params[] = { @@ -275,15 +287,16 @@ static struct tuner_params tuner_temic_pal_dk_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_pal_dk_ranges, .count = ARRAY_SIZE(tuner_temic_pal_dk_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */ static struct tuner_range tuner_philips_ntsc_m_ranges[] = { - { 16 * 160.00 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 160.00 /*MHz*/, 0xa0, }, + { 16 * 454.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_philips_ntsc_m_params[] = { @@ -291,15 +304,16 @@ static struct tuner_params tuner_philips_ntsc_m_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_philips_ntsc_m_ranges, .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */ static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = { - { 16 * 169.00 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 169.00 /*MHz*/, 0xa0, }, + { 16 * 454.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = { @@ -307,6 +321,7 @@ static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_40x6f_5_pal_ranges, .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), + .config = 0x8e, }, }; @@ -317,6 +332,7 @@ static struct tuner_params tuner_temic_4006fn5_multi_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_40x6f_5_pal_ranges, .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), + .config = 0x8e, }, }; @@ -324,9 +340,9 @@ static struct tuner_params tuner_temic_4006fn5_multi_params[] = { /* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */ static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = { - { 16 * 141.00 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 464.00 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 141.00 /*MHz*/, 0xa0, }, + { 16 * 464.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_temic_4009f_5_params[] = { @@ -334,42 +350,58 @@ static struct tuner_params tuner_temic_4009f_5_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_4009f_5_pal_ranges, .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */ -static struct tuner_range tuner_temic_4x3x_f_5_ntsc_ranges[] = { - { 16 * 158.00 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 453.00 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, +static struct tuner_range tuner_temic_4039fr5_ntsc_ranges[] = { + { 16 * 158.00 /*MHz*/, 0xa0, }, + { 16 * 453.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_temic_4039fr5_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_temic_4x3x_f_5_ntsc_ranges, - .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges), + .ranges = tuner_temic_4039fr5_ntsc_ranges, + .count = ARRAY_SIZE(tuner_temic_4039fr5_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */ +static struct tuner_range tuner_temic_4046fm5_pal_ranges[] = { + { 16 * 169.00 /*MHz*/, 0xa0, }, + { 16 * 454.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, +}; + static struct tuner_params tuner_temic_4046fm5_params[] = { { .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_temic_40x6f_5_pal_ranges, - .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges), + .ranges = tuner_temic_4046fm5_pal_ranges, + .count = ARRAY_SIZE(tuner_temic_4046fm5_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */ +static struct tuner_range tuner_lg_pal_ranges[] = { + { 16 * 170.00 /*MHz*/, 0xa0, }, + { 16 * 450.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, +}; + static struct tuner_params tuner_philips_pal_dk_params[] = { { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_lg_pal_ranges, .count = ARRAY_SIZE(tuner_lg_pal_ranges), + .config = 0x8e, }, }; @@ -380,6 +412,7 @@ static struct tuner_params tuner_philips_fq1216me_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_lg_pal_ranges, .count = ARRAY_SIZE(tuner_lg_pal_ranges), + .config = 0x8e, }, }; @@ -390,6 +423,7 @@ static struct tuner_params tuner_lg_pal_i_fm_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_lg_pal_ranges, .count = ARRAY_SIZE(tuner_lg_pal_ranges), + .config = 0x8e, }, }; @@ -400,15 +434,16 @@ static struct tuner_params tuner_lg_pal_i_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_lg_pal_ranges, .count = ARRAY_SIZE(tuner_lg_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */ static struct tuner_range tuner_lg_ntsc_fm_ranges[] = { - { 16 * 210.00 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 497.00 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 210.00 /*MHz*/, 0xa0, }, + { 16 * 497.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_lg_ntsc_fm_params[] = { @@ -416,6 +451,7 @@ static struct tuner_params tuner_lg_ntsc_fm_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_lg_ntsc_fm_ranges, .count = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges), + .config = 0x8e, }, }; @@ -426,6 +462,7 @@ static struct tuner_params tuner_lg_pal_fm_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_lg_pal_ranges, .count = ARRAY_SIZE(tuner_lg_pal_ranges), + .config = 0x8e, }, }; @@ -436,6 +473,7 @@ static struct tuner_params tuner_lg_pal_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_lg_pal_ranges, .count = ARRAY_SIZE(tuner_lg_pal_ranges), + .config = 0x8e, }, }; @@ -447,15 +485,16 @@ static struct tuner_params tuner_temic_4009_fn5_multi_pal_fm_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_4009f_5_pal_ranges, .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */ static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = { - { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 317.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, + { 16 * 137.25 /*MHz*/, 0x01, }, + { 16 * 317.25 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; static struct tuner_params tuner_sharp_2u5jf5540_params[] = { @@ -463,15 +502,16 @@ static struct tuner_params tuner_sharp_2u5jf5540_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_sharp_2u5jf5540_ntsc_ranges, .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */ static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = { - { 16 * 169 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 464 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 169 /*MHz*/, 0xa0, }, + { 16 * 464 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = { @@ -479,6 +519,7 @@ static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_samsung_pal_tcpm9091pd27_ranges, .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges), + .config = 0x8e, }, }; @@ -489,35 +530,50 @@ static struct tuner_params tuner_temic_4106fh5_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_4009f_5_pal_ranges, .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */ +static struct tuner_range tuner_temic_4012fy5_pal_ranges[] = { + { 16 * 140.25 /*MHz*/, 0x02, }, + { 16 * 463.25 /*MHz*/, 0x04, }, + { 16 * 999.99 , 0x01, }, +}; + static struct tuner_params tuner_temic_4012fy5_params[] = { { .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_temic_pal_ranges, - .count = ARRAY_SIZE(tuner_temic_pal_ranges), + .ranges = tuner_temic_4012fy5_pal_ranges, + .count = ARRAY_SIZE(tuner_temic_4012fy5_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */ +static struct tuner_range tuner_temic_4136_fy5_ntsc_ranges[] = { + { 16 * 158.00 /*MHz*/, 0xa0, }, + { 16 * 453.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, +}; + static struct tuner_params tuner_temic_4136_fy5_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_temic_4x3x_f_5_ntsc_ranges, - .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges), + .ranges = tuner_temic_4136_fy5_ntsc_ranges, + .count = ARRAY_SIZE(tuner_temic_4136_fy5_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */ static struct tuner_range tuner_lg_new_tapc_ranges[] = { - { 16 * 170.00 /*MHz*/, 0x8e, 0x01, }, - { 16 * 450.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, + { 16 * 170.00 /*MHz*/, 0x01, }, + { 16 * 450.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; static struct tuner_params tuner_lg_pal_new_tapc_params[] = { @@ -525,15 +581,16 @@ static struct tuner_params tuner_lg_pal_new_tapc_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_lg_new_tapc_ranges, .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */ static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = { - { 16 * 158.00 /*MHz*/, 0x8e, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x04, }, + { 16 * 158.00 /*MHz*/, 0x01, }, + { 16 * 442.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, }; static struct tuner_params tuner_fm1216me_mk3_params[] = { @@ -541,6 +598,7 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_fm1216me_mk3_pal_ranges, .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), + .config = 0x8e, .cb_first_if_lower_freq = 1, }, }; @@ -552,6 +610,7 @@ static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_lg_new_tapc_ranges, .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), + .config = 0x8e, }, }; @@ -563,15 +622,16 @@ static struct tuner_params tuner_hitachi_ntsc_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_lg_new_tapc_ranges, .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */ static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = { - { 16 * 140.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 463.25 /*MHz*/, 0x8e, 0xc2, }, - { 16 * 999.99 , 0x8e, 0xcf, }, + { 16 * 140.25 /*MHz*/, 0x01, }, + { 16 * 463.25 /*MHz*/, 0xc2, }, + { 16 * 999.99 , 0xcf, }, }; static struct tuner_params tuner_philips_pal_mk_params[] = { @@ -579,15 +639,16 @@ static struct tuner_params tuner_philips_pal_mk_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_philips_pal_mk_pal_ranges, .count = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_ATSC - Philips ATSC ------------ */ static struct tuner_range tuner_philips_atsc_ranges[] = { - { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 157.25 /*MHz*/, 0xa0, }, + { 16 * 454.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_philips_atsc_params[] = { @@ -595,15 +656,16 @@ static struct tuner_params tuner_philips_atsc_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_philips_atsc_ranges, .count = ARRAY_SIZE(tuner_philips_atsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */ static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = { - { 16 * 160.00 /*MHz*/, 0x8e, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x04, }, + { 16 * 160.00 /*MHz*/, 0x01, }, + { 16 * 442.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, }; static struct tuner_params tuner_fm1236_mk3_params[] = { @@ -611,17 +673,25 @@ static struct tuner_params tuner_fm1236_mk3_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_fm1236_mk3_ntsc_ranges, .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), + .config = 0x8e, .cb_first_if_lower_freq = 1, }, }; /* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */ +static struct tuner_range tuner_philips_4in1_ntsc_ranges[] = { + { 16 * 160.00 /*MHz*/, 0x01, }, + { 16 * 442.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, +}; + static struct tuner_params tuner_philips_4in1_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_fm1236_mk3_ntsc_ranges, - .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), + .ranges = tuner_philips_4in1_ntsc_ranges, + .count = ARRAY_SIZE(tuner_philips_4in1_ntsc_ranges), + .config = 0x8e, }, }; @@ -632,15 +702,16 @@ static struct tuner_params tuner_microtune_4049_fm5_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_temic_4009f_5_pal_ranges, .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */ static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = { - { 16 * 160.00 /*MHz*/, 0xce, 0x01, }, - { 16 * 454.00 /*MHz*/, 0xce, 0x02, }, - { 16 * 999.99 , 0xce, 0x08, }, + { 16 * 160.00 /*MHz*/, 0x01, }, + { 16 * 454.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; static struct tuner_params tuner_panasonic_vp27_params[] = { @@ -648,25 +719,16 @@ static struct tuner_params tuner_panasonic_vp27_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_panasonic_vp27_ntsc_ranges, .count = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges), - }, -}; - -/* ------------ TUNER_LG_NTSC_TAPE - LGINNOTEK NTSC ------------ */ - -static struct tuner_params tuner_lg_ntsc_tape_params[] = { - { - .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_fm1236_mk3_ntsc_ranges, - .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), + .config = 0xce, }, }; /* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */ static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = { - { 16 * 161.25 /*MHz*/, 0x8e, 0xa0, }, - { 16 * 463.25 /*MHz*/, 0x8e, 0x90, }, - { 16 * 999.99 , 0x8e, 0x30, }, + { 16 * 161.25 /*MHz*/, 0xa0, }, + { 16 * 463.25 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, }; static struct tuner_params tuner_tnf_8831bgff_params[] = { @@ -674,15 +736,16 @@ static struct tuner_params tuner_tnf_8831bgff_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_tnf_8831bgff_pal_ranges, .count = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */ static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = { - { 16 * 162.00 /*MHz*/, 0x8e, 0xa2, }, - { 16 * 457.00 /*MHz*/, 0x8e, 0x94, }, - { 16 * 999.99 , 0x8e, 0x31, }, + { 16 * 162.00 /*MHz*/, 0xa2, }, + { 16 * 457.00 /*MHz*/, 0x94, }, + { 16 * 999.99 , 0x31, }, }; static struct tuner_params tuner_microtune_4042fi5_params[] = { @@ -690,6 +753,7 @@ static struct tuner_params tuner_microtune_4042fi5_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_microtune_4042fi5_ntsc_ranges, .count = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges), + .config = 0x8e, }, }; @@ -697,9 +761,9 @@ static struct tuner_params tuner_microtune_4042fi5_params[] = { /* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */ static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = { - { 16 * 172.00 /*MHz*/, 0x8e, 0x01, }, - { 16 * 448.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, + { 16 * 172.00 /*MHz*/, 0x01, }, + { 16 * 448.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; static struct tuner_params tuner_tcl_2002n_params[] = { @@ -707,26 +771,34 @@ static struct tuner_params tuner_tcl_2002n_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_tcl_2002n_ntsc_ranges, .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges), + .config = 0x8e, .cb_first_if_lower_freq = 1, }, }; /* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */ +static struct tuner_range tuner_philips_fm1256_ih3_pal_ranges[] = { + { 16 * 160.00 /*MHz*/, 0x01, }, + { 16 * 442.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, +}; + static struct tuner_params tuner_philips_fm1256_ih3_params[] = { { .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_fm1236_mk3_ntsc_ranges, - .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), + .ranges = tuner_philips_fm1256_ih3_pal_ranges, + .count = ARRAY_SIZE(tuner_philips_fm1256_ih3_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */ static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = { - { 16 * 157.25 /*MHz*/, 0x8e, 0x39, }, - { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, }, - { 16 * 999.99 , 0x8e, 0x3c, }, + { 16 * 157.25 /*MHz*/, 0x39, }, + { 16 * 454.00 /*MHz*/, 0x3a, }, + { 16 * 999.99 , 0x3c, }, }; static struct tuner_params tuner_thomson_dtt7610_params[] = { @@ -734,15 +806,16 @@ static struct tuner_params tuner_thomson_dtt7610_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_thomson_dtt7610_ntsc_ranges, .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */ static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = { - { 16 * 160.00 /*MHz*/, 0x8e, 0x41, }, - { 16 * 454.00 /*MHz*/, 0x8e, 0x42, }, - { 16 * 999.99 , 0x8e, 0x04, }, + { 16 * 160.00 /*MHz*/, 0x41, }, + { 16 * 454.00 /*MHz*/, 0x42, }, + { 16 * 999.99 , 0x04, }, }; static struct tuner_params tuner_philips_fq1286_params[] = { @@ -750,15 +823,16 @@ static struct tuner_params tuner_philips_fq1286_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_philips_fq1286_ntsc_ranges, .count = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */ static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = { - { 16 * 170.00 /*MHz*/, 0xce, 0x01, }, - { 16 * 450.00 /*MHz*/, 0xce, 0x02, }, - { 16 * 999.99 , 0xce, 0x08, }, + { 16 * 170.00 /*MHz*/, 0x01, }, + { 16 * 450.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; static struct tuner_params tuner_tcl_2002mb_params[] = { @@ -766,22 +840,24 @@ static struct tuner_params tuner_tcl_2002mb_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_tcl_2002mb_pal_ranges, .count = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges), + .config = 0xce, }, }; /* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */ -static struct tuner_range tuner_philips_fq12_6a___mk4_pal_ranges[] = { - { 16 * 160.00 /*MHz*/, 0xce, 0x01, }, - { 16 * 442.00 /*MHz*/, 0xce, 0x02, }, - { 16 * 999.99 , 0xce, 0x04, }, +static struct tuner_range tuner_philips_fq12_6a___mk4_ranges[] = { + { 16 * 160.00 /*MHz*/, 0x01, }, + { 16 * 442.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, }; static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = { { .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_philips_fq12_6a___mk4_pal_ranges, - .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges), + .ranges = tuner_philips_fq12_6a___mk4_ranges, + .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_ranges), + .config = 0xce, }, }; @@ -790,27 +866,35 @@ static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = { static struct tuner_params tuner_philips_fq1236a_mk4_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_fm1236_mk3_ntsc_ranges, - .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), + .ranges = tuner_philips_fq12_6a___mk4_ranges, + .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */ +static struct tuner_range tuner_ymec_tvf_8531mf_ntsc_ranges[] = { + { 16 * 160.00 /*MHz*/, 0xa0, }, + { 16 * 454.00 /*MHz*/, 0x90, }, + { 16 * 999.99 , 0x30, }, +}; + static struct tuner_params tuner_ymec_tvf_8531mf_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_philips_ntsc_m_ranges, - .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges), + .ranges = tuner_ymec_tvf_8531mf_ntsc_ranges, + .count = ARRAY_SIZE(tuner_ymec_tvf_8531mf_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */ static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = { - { 16 * 160.00 /*MHz*/, 0x8e, 0x01, }, - { 16 * 454.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x04, }, + { 16 * 160.00 /*MHz*/, 0x01, }, + { 16 * 454.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, }; static struct tuner_params tuner_ymec_tvf_5533mf_params[] = { @@ -818,6 +902,7 @@ static struct tuner_params tuner_ymec_tvf_5533mf_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges, .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges), + .config = 0x8e, }, }; @@ -826,9 +911,9 @@ static struct tuner_params tuner_ymec_tvf_5533mf_params[] = { /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = { - { 16 * 145.25 /*MHz*/, 0x8e, 0x39, }, - { 16 * 415.25 /*MHz*/, 0x8e, 0x3a, }, - { 16 * 999.99 , 0x8e, 0x3c, }, + { 16 * 145.25 /*MHz*/, 0x39, }, + { 16 * 415.25 /*MHz*/, 0x3a, }, + { 16 * 999.99 , 0x3c, }, }; @@ -837,39 +922,42 @@ static struct tuner_params tuner_thomson_dtt761x_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_thomson_dtt761x_ntsc_ranges, .count = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */ -static struct tuner_range tuner_tena_9533_di_pal_ranges[] = { - { 16 * 160.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 464.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x04, }, +static struct tuner_range tuner_tuner_tena_9533_di_pal_ranges[] = { + { 16 * 160.25 /*MHz*/, 0x01, }, + { 16 * 464.25 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, }; static struct tuner_params tuner_tena_9533_di_params[] = { { .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_tena_9533_di_pal_ranges, - .count = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges), + .ranges = tuner_tuner_tena_9533_di_pal_ranges, + .count = ARRAY_SIZE(tuner_tuner_tena_9533_di_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */ static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { - { 16 * 160.00 /*MHz*/, 0x86, 0x51, }, - { 16 * 442.00 /*MHz*/, 0x86, 0x52, }, - { 16 * 999.99 , 0x86, 0x54, }, + { 16 * 160.00 /*MHz*/, 0x51, }, + { 16 * 442.00 /*MHz*/, 0x52, }, + { 16 * 999.99 , 0x54, }, }; -static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { +static struct tuner_params tuner_tuner_philips_fmd1216me_mk3_params[] = { { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_philips_fmd1216me_mk3_pal_ranges, .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges), + .config = 0x86, }, }; @@ -877,9 +965,9 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { /* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */ static struct tuner_range tuner_tua6034_ntsc_ranges[] = { - { 16 * 165.00 /*MHz*/, 0x8e, 0x01 }, - { 16 * 450.00 /*MHz*/, 0x8e, 0x02 }, - { 16 * 999.99 , 0x8e, 0x04 }, + { 16 * 160.00 /*MHz*/, 0x01 }, + { 16 * 455.00 /*MHz*/, 0x02 }, + { 16 * 999.99 , 0x04 }, }; @@ -888,51 +976,50 @@ static struct tuner_params tuner_tua6034_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_tua6034_ntsc_ranges, .count = ARRAY_SIZE(tuner_tua6034_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */ +static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = { + { 16 * 160.25 /*MHz*/, 0x01, }, + { 16 * 464.25 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, +}; + static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = { { .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_tena_9533_di_pal_ranges, - .count = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges), + .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges, + .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */ -static struct tuner_range tuner_lg_taln_ntsc_ranges[] = { - { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 373.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, -}; - -static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = { - { 16 * 150.00 /*MHz*/, 0x8e, 0x01, }, - { 16 * 425.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, +static struct tuner_range tuner_lg_taln_mini_ntsc_ranges[] = { + { 16 * 137.25 /*MHz*/, 0x01, }, + { 16 * 373.25 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; -static struct tuner_params tuner_lg_taln_params[] = { +static struct tuner_params tuner_lg_taln_mini_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_lg_taln_ntsc_ranges, - .count = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges), - },{ - .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_lg_taln_pal_secam_ranges, - .count = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges), + .ranges = tuner_lg_taln_mini_ntsc_ranges, + .count = ARRAY_SIZE(tuner_lg_taln_mini_ntsc_ranges), + .config = 0x8e, }, }; /* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */ static struct tuner_range tuner_philips_td1316_pal_ranges[] = { - { 16 * 160.00 /*MHz*/, 0xc8, 0xa1, }, - { 16 * 442.00 /*MHz*/, 0xc8, 0xa2, }, - { 16 * 999.99 , 0xc8, 0xa4, }, + { 16 * 160.00 /*MHz*/, 0xa1, }, + { 16 * 442.00 /*MHz*/, 0xa2, }, + { 16 * 999.99 , 0xa4, }, }; static struct tuner_params tuner_philips_td1316_params[] = { @@ -940,42 +1027,34 @@ static struct tuner_params tuner_philips_td1316_params[] = { .type = TUNER_PARAM_TYPE_PAL, .ranges = tuner_philips_td1316_pal_ranges, .count = ARRAY_SIZE(tuner_philips_td1316_pal_ranges), + .config = 0xc8, }, }; /* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */ static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = { - { 16 * 157.25 /*MHz*/, 0xce, 0x01, }, - { 16 * 454.00 /*MHz*/, 0xce, 0x02, }, - { 16 * 999.99 , 0xce, 0x04, }, + { 16 * 157.25 /*MHz*/, 0x01, }, + { 16 * 454.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, }; -static struct tuner_params tuner_tuv1236d_params[] = { +static struct tuner_params tuner_tuner_tuv1236d_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_tuv1236d_ntsc_ranges, .count = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges), + .config = 0xce, }, }; -/* ------------ TUNER_TNF_xxx5 - Texas Instruments--------- */ -/* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF - * but it is expected to work also with other Tenna/Ymec - * models based on TI SN 761677 chip on both PAL and NTSC - */ - -static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = { - { 16 * 168.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 471.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, -}; +/* ------------ TUNER_TNF_5335MF - Philips NTSC ------------ */ static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = { - { 16 * 169.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 469.25 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x08, }, + { 16 * 157.25 /*MHz*/, 0x01, }, + { 16 * 454.00 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x04, }, }; static struct tuner_params tuner_tnf_5335mf_params[] = { @@ -983,11 +1062,7 @@ static struct tuner_params tuner_tnf_5335mf_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_tnf_5335mf_ntsc_ranges, .count = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges), - }, - { - .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_tnf_5335_d_if_pal_ranges, - .count = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges), + .config = 0x8e, }, }; @@ -995,9 +1070,9 @@ static struct tuner_params tuner_tnf_5335mf_params[] = { /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */ static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = { - { 16 * 130.00 /*MHz*/, 0xce, 0x01, }, - { 16 * 364.50 /*MHz*/, 0xce, 0x02, }, - { 16 * 999.99 , 0xce, 0x08, }, + { 16 * 130.00 /*MHz*/, 0x01, }, + { 16 * 364.50 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, }; static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { @@ -1005,22 +1080,7 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges, .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges), - }, -}; - -/* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */ - -static struct tuner_range tuner_thomson_fe6600_ranges[] = { - { 16 * 160.00 /*MHz*/, 0xfe, 0x11, }, - { 16 * 442.00 /*MHz*/, 0xf6, 0x12, }, - { 16 * 999.99 , 0xf6, 0x18, }, -}; - -static struct tuner_params tuner_thomson_fe6600_params[] = { - { - .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_thomson_fe6600_ranges, - .count = ARRAY_SIZE(tuner_thomson_fe6600_ranges), + .config = 0xce, }, }; @@ -1031,22 +1091,18 @@ struct tunertype tuners[] = { [TUNER_TEMIC_PAL] = { /* TEMIC PAL */ .name = "Temic PAL (4002 FH5)", .params = tuner_temic_pal_params, - .count = ARRAY_SIZE(tuner_temic_pal_params), }, [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */ .name = "Philips PAL_I (FI1246 and compatibles)", .params = tuner_philips_pal_i_params, - .count = ARRAY_SIZE(tuner_philips_pal_i_params), }, [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */ .name = "Philips NTSC (FI1236,FM1236 and compatibles)", .params = tuner_philips_ntsc_params, - .count = ARRAY_SIZE(tuner_philips_ntsc_params), }, [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */ .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", .params = tuner_philips_secam_params, - .count = ARRAY_SIZE(tuner_philips_secam_params), }, [TUNER_ABSENT] = { /* Tuner Absent */ .name = "NoTuner", @@ -1054,148 +1110,120 @@ struct tunertype tuners[] = { [TUNER_PHILIPS_PAL] = { /* Philips PAL */ .name = "Philips PAL_BG (FI1216 and compatibles)", .params = tuner_philips_pal_params, - .count = ARRAY_SIZE(tuner_philips_pal_params), }, [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */ .name = "Temic NTSC (4032 FY5)", .params = tuner_temic_ntsc_params, - .count = ARRAY_SIZE(tuner_temic_ntsc_params), }, [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */ .name = "Temic PAL_I (4062 FY5)", .params = tuner_temic_pal_i_params, - .count = ARRAY_SIZE(tuner_temic_pal_i_params), }, [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */ .name = "Temic NTSC (4036 FY5)", .params = tuner_temic_4036fy5_ntsc_params, - .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_params), }, [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */ .name = "Alps HSBH1", .params = tuner_alps_tsbh1_ntsc_params, - .count = ARRAY_SIZE(tuner_alps_tsbh1_ntsc_params), }, /* 10-19 */ [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */ .name = "Alps TSBE1", .params = tuner_alps_tsb_1_params, - .count = ARRAY_SIZE(tuner_alps_tsb_1_params), }, [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */ .name = "Alps TSBB5", .params = tuner_alps_tsbb5_params, - .count = ARRAY_SIZE(tuner_alps_tsbb5_params), }, [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */ .name = "Alps TSBE5", .params = tuner_alps_tsbe5_params, - .count = ARRAY_SIZE(tuner_alps_tsbe5_params), }, [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */ .name = "Alps TSBC5", .params = tuner_alps_tsbc5_params, - .count = ARRAY_SIZE(tuner_alps_tsbc5_params), }, [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */ .name = "Temic PAL_BG (4006FH5)", .params = tuner_temic_4006fh5_params, - .count = ARRAY_SIZE(tuner_temic_4006fh5_params), }, [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */ .name = "Alps TSCH6", .params = tuner_alps_tshc6_params, - .count = ARRAY_SIZE(tuner_alps_tshc6_params), }, [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */ .name = "Temic PAL_DK (4016 FY5)", .params = tuner_temic_pal_dk_params, - .count = ARRAY_SIZE(tuner_temic_pal_dk_params), }, [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */ .name = "Philips NTSC_M (MK2)", .params = tuner_philips_ntsc_m_params, - .count = ARRAY_SIZE(tuner_philips_ntsc_m_params), }, [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */ .name = "Temic PAL_I (4066 FY5)", .params = tuner_temic_4066fy5_pal_i_params, - .count = ARRAY_SIZE(tuner_temic_4066fy5_pal_i_params), }, [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */ .name = "Temic PAL* auto (4006 FN5)", .params = tuner_temic_4006fn5_multi_params, - .count = ARRAY_SIZE(tuner_temic_4006fn5_multi_params), }, /* 20-29 */ [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */ .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", .params = tuner_temic_4009f_5_params, - .count = ARRAY_SIZE(tuner_temic_4009f_5_params), }, [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */ .name = "Temic NTSC (4039 FR5)", .params = tuner_temic_4039fr5_params, - .count = ARRAY_SIZE(tuner_temic_4039fr5_params), }, [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */ .name = "Temic PAL/SECAM multi (4046 FM5)", .params = tuner_temic_4046fm5_params, - .count = ARRAY_SIZE(tuner_temic_4046fm5_params), }, [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */ .name = "Philips PAL_DK (FI1256 and compatibles)", .params = tuner_philips_pal_dk_params, - .count = ARRAY_SIZE(tuner_philips_pal_dk_params), }, [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */ .name = "Philips PAL/SECAM multi (FQ1216ME)", .params = tuner_philips_fq1216me_params, - .count = ARRAY_SIZE(tuner_philips_fq1216me_params), }, [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */ .name = "LG PAL_I+FM (TAPC-I001D)", .params = tuner_lg_pal_i_fm_params, - .count = ARRAY_SIZE(tuner_lg_pal_i_fm_params), }, [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */ .name = "LG PAL_I (TAPC-I701D)", .params = tuner_lg_pal_i_params, - .count = ARRAY_SIZE(tuner_lg_pal_i_params), }, [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */ .name = "LG NTSC+FM (TPI8NSR01F)", .params = tuner_lg_ntsc_fm_params, - .count = ARRAY_SIZE(tuner_lg_ntsc_fm_params), }, [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */ .name = "LG PAL_BG+FM (TPI8PSB01D)", .params = tuner_lg_pal_fm_params, - .count = ARRAY_SIZE(tuner_lg_pal_fm_params), }, [TUNER_LG_PAL] = { /* LGINNOTEK PAL */ .name = "LG PAL_BG (TPI8PSB11D)", .params = tuner_lg_pal_params, - .count = ARRAY_SIZE(tuner_lg_pal_params), }, /* 30-39 */ [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */ .name = "Temic PAL* auto + FM (4009 FN5)", .params = tuner_temic_4009_fn5_multi_pal_fm_params, - .count = ARRAY_SIZE(tuner_temic_4009_fn5_multi_pal_fm_params), }, [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */ .name = "SHARP NTSC_JP (2U5JF5540)", .params = tuner_sharp_2u5jf5540_params, - .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_params), }, [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */ .name = "Samsung PAL TCPM9091PD27", .params = tuner_samsung_pal_tcpm9091pd27_params, - .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_params), }, [TUNER_MT2032] = { /* Microtune PAL|NTSC */ .name = "MT20xx universal", @@ -1203,106 +1231,86 @@ struct tunertype tuners[] = { [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */ .name = "Temic PAL_BG (4106 FH5)", .params = tuner_temic_4106fh5_params, - .count = ARRAY_SIZE(tuner_temic_4106fh5_params), }, [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */ .name = "Temic PAL_DK/SECAM_L (4012 FY5)", .params = tuner_temic_4012fy5_params, - .count = ARRAY_SIZE(tuner_temic_4012fy5_params), }, [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */ .name = "Temic NTSC (4136 FY5)", .params = tuner_temic_4136_fy5_params, - .count = ARRAY_SIZE(tuner_temic_4136_fy5_params), }, [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */ .name = "LG PAL (newer TAPC series)", .params = tuner_lg_pal_new_tapc_params, - .count = ARRAY_SIZE(tuner_lg_pal_new_tapc_params), }, [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */ .name = "Philips PAL/SECAM multi (FM1216ME MK3)", .params = tuner_fm1216me_mk3_params, - .count = ARRAY_SIZE(tuner_fm1216me_mk3_params), }, [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */ .name = "LG NTSC (newer TAPC series)", .params = tuner_lg_ntsc_new_tapc_params, - .count = ARRAY_SIZE(tuner_lg_ntsc_new_tapc_params), }, /* 40-49 */ [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */ .name = "HITACHI V7-J180AT", .params = tuner_hitachi_ntsc_params, - .count = ARRAY_SIZE(tuner_hitachi_ntsc_params), }, [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */ .name = "Philips PAL_MK (FI1216 MK)", .params = tuner_philips_pal_mk_params, - .count = ARRAY_SIZE(tuner_philips_pal_mk_params), }, [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */ .name = "Philips 1236D ATSC/NTSC dual in", .params = tuner_philips_atsc_params, - .count = ARRAY_SIZE(tuner_philips_atsc_params), }, [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", .params = tuner_fm1236_mk3_params, - .count = ARRAY_SIZE(tuner_fm1236_mk3_params), }, [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */ .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", .params = tuner_philips_4in1_params, - .count = ARRAY_SIZE(tuner_philips_4in1_params), }, [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */ .name = "Microtune 4049 FM5", .params = tuner_microtune_4049_fm5_params, - .count = ARRAY_SIZE(tuner_microtune_4049_fm5_params), }, [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */ .name = "Panasonic VP27s/ENGE4324D", .params = tuner_panasonic_vp27_params, - .count = ARRAY_SIZE(tuner_panasonic_vp27_params), }, [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */ .name = "LG NTSC (TAPE series)", - .params = tuner_lg_ntsc_tape_params, - .count = ARRAY_SIZE(tuner_lg_ntsc_tape_params), + .params = tuner_fm1236_mk3_params, }, [TUNER_TNF_8831BGFF] = { /* Philips PAL */ .name = "Tenna TNF 8831 BGFF)", .params = tuner_tnf_8831bgff_params, - .count = ARRAY_SIZE(tuner_tnf_8831bgff_params), }, [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */ .name = "Microtune 4042 FI5 ATSC/NTSC dual in", .params = tuner_microtune_4042fi5_params, - .count = ARRAY_SIZE(tuner_microtune_4042fi5_params), }, /* 50-59 */ [TUNER_TCL_2002N] = { /* TCL NTSC */ .name = "TCL 2002N", .params = tuner_tcl_2002n_params, - .count = ARRAY_SIZE(tuner_tcl_2002n_params), }, [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */ .name = "Philips PAL/SECAM_D (FM 1256 I-H3)", .params = tuner_philips_fm1256_ih3_params, - .count = ARRAY_SIZE(tuner_philips_fm1256_ih3_params), }, [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */ .name = "Thomson DTT 7610 (ATSC/NTSC)", .params = tuner_thomson_dtt7610_params, - .count = ARRAY_SIZE(tuner_thomson_dtt7610_params), }, [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */ .name = "Philips FQ1286", .params = tuner_philips_fq1286_params, - .count = ARRAY_SIZE(tuner_philips_fq1286_params), }, [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */ .name = "tda8290+75", @@ -1310,27 +1318,22 @@ struct tunertype tuners[] = { [TUNER_TCL_2002MB] = { /* TCL PAL */ .name = "TCL 2002MB", .params = tuner_tcl_2002mb_params, - .count = ARRAY_SIZE(tuner_tcl_2002mb_params), }, [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */ .name = "Philips PAL/SECAM multi (FQ1216AME MK4)", .params = tuner_philips_fq1216ame_mk4_params, - .count = ARRAY_SIZE(tuner_philips_fq1216ame_mk4_params), }, [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */ .name = "Philips FQ1236A MK4", .params = tuner_philips_fq1236a_mk4_params, - .count = ARRAY_SIZE(tuner_philips_fq1236a_mk4_params), }, [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */ .name = "Ymec TVision TVF-8531MF/8831MF/8731MF", .params = tuner_ymec_tvf_8531mf_params, - .count = ARRAY_SIZE(tuner_ymec_tvf_8531mf_params), }, [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */ .name = "Ymec TVision TVF-5533MF", .params = tuner_ymec_tvf_5533mf_params, - .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_params), }, /* 60-69 */ @@ -1338,12 +1341,10 @@ struct tunertype tuners[] = { /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ .name = "Thomson DTT 761X (ATSC/NTSC)", .params = tuner_thomson_dtt761x_params, - .count = ARRAY_SIZE(tuner_thomson_dtt761x_params), }, [TUNER_TENA_9533_DI] = { /* Philips PAL */ .name = "Tena TNF9533-D/IF/TNF9533-B/DF", .params = tuner_tena_9533_di_params, - .count = ARRAY_SIZE(tuner_tena_9533_di_params), }, [TUNER_TEA5767] = { /* Philips RADIO */ .name = "Philips TEA5767HN FM Radio", @@ -1351,54 +1352,37 @@ struct tunertype tuners[] = { }, [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */ .name = "Philips FMD1216ME MK3 Hybrid Tuner", - .params = tuner_philips_fmd1216me_mk3_params, - .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), + .params = tuner_tuner_philips_fmd1216me_mk3_params, }, [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */ .name = "LG TDVS-H062F/TUA6034", .params = tuner_tua6034_params, - .count = ARRAY_SIZE(tuner_tua6034_params), }, [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ .name = "Ymec TVF66T5-B/DFF", .params = tuner_ymec_tvf66t5_b_dff_params, - .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params), }, - [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */ - .name = "LG TALN series", - .params = tuner_lg_taln_params, - .count = ARRAY_SIZE(tuner_lg_taln_params), + [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */ + .name = "LG NTSC (TALN mini series)", + .params = tuner_lg_taln_mini_params, }, [TUNER_PHILIPS_TD1316] = { /* Philips PAL */ .name = "Philips TD1316 Hybrid Tuner", .params = tuner_philips_td1316_params, - .count = ARRAY_SIZE(tuner_philips_td1316_params), }, [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */ .name = "Philips TUV1236D ATSC/NTSC dual in", - .params = tuner_tuv1236d_params, - .count = ARRAY_SIZE(tuner_tuv1236d_params), + .params = tuner_tuner_tuv1236d_params, }, - [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */ - .name = "Tena TNF 5335 and similar models", + [TUNER_TNF_5335MF] = { /* Philips NTSC */ + .name = "Tena TNF 5335 MF", .params = tuner_tnf_5335mf_params, - .count = ARRAY_SIZE(tuner_tnf_5335mf_params), }, /* 70-79 */ [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */ .name = "Samsung TCPN 2121P30A", .params = tuner_samsung_tcpn_2121p30a_params, - .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params), - }, - [TUNER_XCEIVE_XC3028] = { /* Xceive 3028 */ - .name = "Xceive xc3028", - /* see xc3028.c for details */ - }, - [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */ - .name = "Thomson FE6600", - .params = tuner_thomson_fe6600_params, - .count = ARRAY_SIZE(tuner_thomson_fe6600_params), }, }; diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index c2b756107..c8e5ad0e8 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -30,10 +30,10 @@ #include #include -#include +#include #include -#include +#include "tvaudio.h" /* ---------------------------------------------------------------------- */ /* insmod args */ @@ -102,7 +102,7 @@ struct CHIPDESC { /* input switch register + values for v4l inputs */ int inputreg; - int inputmap[4]; + int inputmap[8]; int inputmute; int inputmask; }; @@ -119,10 +119,9 @@ struct CHIPSTATE { audiocmd shadow; /* current settings */ - __u16 left,right,treble,bass,muted,mode; + __u16 left,right,treble,bass,mode; int prevmode; int radio; - int input; /* thread */ pid_t tpid; @@ -131,21 +130,20 @@ struct CHIPSTATE { struct timer_list wt; int done; int watch_stereo; - int audmode; }; /* ---------------------------------------------------------------------- */ /* 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_TDA8425 >> 1, + I2C_TEA6300 >> 1, + I2C_TEA6420 >> 1, + I2C_TDA9840 >> 1, + I2C_TDA985x_L >> 1, + I2C_TDA985x_H >> 1, + I2C_TDA9874 >> 1, + I2C_PIC16C54 >> 1, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; @@ -1102,8 +1100,9 @@ static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; } static int tda8425_initialize(struct CHIPSTATE *chip) { struct CHIPDESC *desc = chiplist + chip->type; - int inputmap[4] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1, - /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF}; + int inputmap[8] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1, + /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF, + /* off */ TDA8425_S1_OFF, /* on */ TDA8425_S1_CH2}; if (chip->c.adapter->id == I2C_HW_B_RIVA) { memcpy (desc->inputmap, inputmap, sizeof (inputmap)); @@ -1269,8 +1268,8 @@ static struct CHIPDESC chiplist[] = { .name = "tda9840", .id = I2C_DRIVERID_TDA9840, .insmodopt = &tda9840, - .addr_lo = I2C_ADDR_TDA9840 >> 1, - .addr_hi = I2C_ADDR_TDA9840 >> 1, + .addr_lo = I2C_TDA9840 >> 1, + .addr_hi = I2C_TDA9840 >> 1, .registers = 5, .checkit = tda9840_checkit, @@ -1286,8 +1285,8 @@ static struct CHIPDESC chiplist[] = { .id = I2C_DRIVERID_TDA9873, .checkit = tda9873_checkit, .insmodopt = &tda9873, - .addr_lo = I2C_ADDR_TDA985x_L >> 1, - .addr_hi = I2C_ADDR_TDA985x_H >> 1, + .addr_lo = I2C_TDA985x_L >> 1, + .addr_hi = I2C_TDA985x_H >> 1, .registers = 3, .flags = CHIP_HAS_INPUTSEL, @@ -1298,7 +1297,7 @@ static struct CHIPDESC chiplist[] = { .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, .inputreg = TDA9873_SW, .inputmute = TDA9873_MUTE | TDA9873_AUTOMUTE, - .inputmap = {0xa0, 0xa2, 0xa0, 0xa0}, + .inputmap = {0xa0, 0xa2, 0xa0, 0xa0, 0xc0}, .inputmask = TDA9873_INP_MASK|TDA9873_MUTE|TDA9873_AUTOMUTE, }, @@ -1308,8 +1307,8 @@ static struct CHIPDESC chiplist[] = { .checkit = tda9874a_checkit, .initialize = tda9874a_initialize, .insmodopt = &tda9874a, - .addr_lo = I2C_ADDR_TDA9874 >> 1, - .addr_hi = I2C_ADDR_TDA9874 >> 1, + .addr_lo = I2C_TDA9874 >> 1, + .addr_hi = I2C_TDA9874 >> 1, .getmode = tda9874a_getmode, .setmode = tda9874a_setmode, @@ -1319,8 +1318,8 @@ static struct CHIPDESC chiplist[] = { .name = "tda9850", .id = I2C_DRIVERID_TDA9850, .insmodopt = &tda9850, - .addr_lo = I2C_ADDR_TDA985x_L >> 1, - .addr_hi = I2C_ADDR_TDA985x_H >> 1, + .addr_lo = I2C_TDA985x_L >> 1, + .addr_hi = I2C_TDA985x_H >> 1, .registers = 11, .getmode = tda985x_getmode, @@ -1332,8 +1331,8 @@ static struct CHIPDESC chiplist[] = { .name = "tda9855", .id = I2C_DRIVERID_TDA9855, .insmodopt = &tda9855, - .addr_lo = I2C_ADDR_TDA985x_L >> 1, - .addr_hi = I2C_ADDR_TDA985x_H >> 1, + .addr_lo = I2C_TDA985x_L >> 1, + .addr_hi = I2C_TDA985x_H >> 1, .registers = 11, .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE, @@ -1357,8 +1356,8 @@ static struct CHIPDESC chiplist[] = { .name = "tea6300", .id = I2C_DRIVERID_TEA6300, .insmodopt = &tea6300, - .addr_lo = I2C_ADDR_TEA6300 >> 1, - .addr_hi = I2C_ADDR_TEA6300 >> 1, + .addr_lo = I2C_TEA6300 >> 1, + .addr_hi = I2C_TEA6300 >> 1, .registers = 6, .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, @@ -1379,8 +1378,8 @@ static struct CHIPDESC chiplist[] = { .id = I2C_DRIVERID_TEA6300, .initialize = tea6320_initialize, .insmodopt = &tea6320, - .addr_lo = I2C_ADDR_TEA6300 >> 1, - .addr_hi = I2C_ADDR_TEA6300 >> 1, + .addr_lo = I2C_TEA6300 >> 1, + .addr_hi = I2C_TEA6300 >> 1, .registers = 8, .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, @@ -1400,8 +1399,8 @@ static struct CHIPDESC chiplist[] = { .name = "tea6420", .id = I2C_DRIVERID_TEA6420, .insmodopt = &tea6420, - .addr_lo = I2C_ADDR_TEA6420 >> 1, - .addr_hi = I2C_ADDR_TEA6420 >> 1, + .addr_lo = I2C_TEA6420 >> 1, + .addr_hi = I2C_TEA6420 >> 1, .registers = 1, .flags = CHIP_HAS_INPUTSEL, @@ -1413,8 +1412,8 @@ static struct CHIPDESC chiplist[] = { .name = "tda8425", .id = I2C_DRIVERID_TDA8425, .insmodopt = &tda8425, - .addr_lo = I2C_ADDR_TDA8425 >> 1, - .addr_hi = I2C_ADDR_TDA8425 >> 1, + .addr_lo = I2C_TDA8425 >> 1, + .addr_hi = I2C_TDA8425 >> 1, .registers = 9, .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, @@ -1437,8 +1436,8 @@ static struct CHIPDESC chiplist[] = { .name = "pic16c54 (PV951)", .id = I2C_DRIVERID_PIC16C54_PV9, .insmodopt = &pic16c54, - .addr_lo = I2C_ADDR_PIC16C54 >> 1, - .addr_hi = I2C_ADDR_PIC16C54>> 1, + .addr_lo = I2C_PIC16C54 >> 1, + .addr_hi = I2C_PIC16C54>> 1, .registers = 2, .flags = CHIP_HAS_INPUTSEL, @@ -1446,7 +1445,8 @@ static struct CHIPDESC chiplist[] = { .inputmap = {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER, PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE, PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE, - PIC16C54_MISC_SND_MUTE}, + PIC16C54_MISC_SND_MUTE,PIC16C54_MISC_SND_MUTE, + PIC16C54_MISC_SND_NOTMUTE}, .inputmute = PIC16C54_MISC_SND_MUTE, }, { @@ -1455,8 +1455,8 @@ static struct CHIPDESC chiplist[] = { /*.id = I2C_DRIVERID_TA8874Z, */ .checkit = ta8874z_checkit, .insmodopt = &ta8874z, - .addr_lo = I2C_ADDR_TDA9840 >> 1, - .addr_hi = I2C_ADDR_TDA9840 >> 1, + .addr_lo = I2C_TDA9840 >> 1, + .addr_hi = I2C_TDA9840 >> 1, .registers = 2, .getmode = ta8874z_getmode, @@ -1514,7 +1514,6 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) chip->type = desc-chiplist; chip->shadow.count = desc->registers+1; chip->prevmode = -1; - chip->audmode = V4L2_TUNER_MODE_LANG1; /* register */ i2c_attach_client(&chip->c); @@ -1582,40 +1581,28 @@ static int chip_detach(struct i2c_client *client) return 0; } -static int tvaudio_set_ctrl(struct CHIPSTATE *chip, struct v4l2_control *ctrl) -{ - struct CHIPDESC *desc = chiplist + chip->type; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value < 0 || ctrl->value >= 2) - return -ERANGE; - chip->muted = ctrl->value; - if (chip->muted) - chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask); - else - chip_write_masked(chip,desc->inputreg, - desc->inputmap[chip->input],desc->inputmask); - break; - default: - return -EINVAL; - } - return 0; -} - - /* ---------------------------------------------------------------------- */ /* video4linux interface */ static int chip_command(struct i2c_client *client, unsigned int cmd, void *arg) { + __u16 *sarg = arg; struct CHIPSTATE *chip = i2c_get_clientdata(client); struct CHIPDESC *desc = chiplist + chip->type; v4l_dbg(1, debug, &chip->c, "%s: chip_command 0x%x\n", chip->c.name, cmd); switch (cmd) { + case AUDC_SET_INPUT: + if (desc->flags & CHIP_HAS_INPUTSEL) { + if (*sarg & 0x80) + chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask); + else + chip_write_masked(chip,desc->inputreg,desc->inputmap[*sarg],desc->inputmask); + } + break; + case AUDC_SET_RADIO: chip->radio = 1; chip->watch_stereo = 0; @@ -1679,46 +1666,16 @@ static int chip_command(struct i2c_client *client, break; } - case VIDIOC_S_CTRL: - return tvaudio_set_ctrl(chip, arg); - - case VIDIOC_INT_G_AUDIO_ROUTING: - { - struct v4l2_routing *rt = arg; - - rt->input = chip->input; - rt->output = 0; - break; - } - - case VIDIOC_INT_S_AUDIO_ROUTING: - { - struct v4l2_routing *rt = arg; - - if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4) - return -EINVAL; - /* There are four inputs: tuner, radio, extern and intern. */ - chip->input = rt->input; - if (chip->muted) - break; - chip_write_masked(chip, desc->inputreg, - desc->inputmap[chip->input], desc->inputmask); - break; - } - case VIDIOC_S_TUNER: { struct v4l2_tuner *vt = arg; int mode = 0; - if (chip->radio) - break; switch (vt->audmode) { case V4L2_TUNER_MODE_MONO: mode = VIDEO_SOUND_MONO; break; case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1_LANG2: mode = VIDEO_SOUND_STEREO; break; case V4L2_TUNER_MODE_LANG1: @@ -1728,9 +1685,8 @@ static int chip_command(struct i2c_client *client, mode = VIDEO_SOUND_LANG2; break; default: - return -EINVAL; + break; } - chip->audmode = vt->audmode; if (desc->setmode && mode) { chip->watch_stereo = 0; @@ -1748,7 +1704,7 @@ static int chip_command(struct i2c_client *client, if (chip->radio) break; - vt->audmode = chip->audmode; + vt->audmode = 0; vt->rxsubchans = 0; vt->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; @@ -1760,12 +1716,19 @@ static int chip_command(struct i2c_client *client, vt->rxsubchans |= V4L2_TUNER_SUB_MONO; if (mode & VIDEO_SOUND_STEREO) vt->rxsubchans |= V4L2_TUNER_SUB_STEREO; - /* Note: for SAP it should be mono/lang2 or stereo/lang2. - When this module is converted fully to v4l2, then this - should change for those chips that can detect SAP. */ if (mode & VIDEO_SOUND_LANG1) - vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | - V4L2_TUNER_SUB_LANG2; + vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + mode = chip->mode; + if (mode & VIDEO_SOUND_MONO) + vt->audmode = V4L2_TUNER_MODE_MONO; + if (mode & VIDEO_SOUND_STEREO) + vt->audmode = V4L2_TUNER_MODE_STEREO; + if (mode & VIDEO_SOUND_LANG1) + vt->audmode = V4L2_TUNER_MODE_LANG1; + if (mode & VIDEO_SOUND_LANG2) + vt->audmode = V4L2_TUNER_MODE_LANG2; break; } diff --git a/drivers/media/video/tvaudio.h b/drivers/media/video/tvaudio.h new file mode 100644 index 000000000..af7e116af --- /dev/null +++ b/drivers/media/video/tvaudio.h @@ -0,0 +1,14 @@ +/* + * i2c bus addresses for the chips supported by tvaudio.c + */ + +#define I2C_TDA8425 0x82 +#define I2C_TDA9840 0x84 /* also used by TA8874Z */ +#define I2C_TDA985x_L 0xb4 /* also used by 9873 */ +#define I2C_TDA985x_H 0xb6 +#define I2C_TDA9874 0xb0 /* also used by 9875 */ + +#define I2C_TEA6300 0x80 /* also used by 6320 */ +#define I2C_TEA6420 0x98 + +#define I2C_PIC16C54 0x96 /* PV951 */ diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index b463e9969..582551b09 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -218,7 +218,7 @@ hauppauge_tuner[] = /* 110-119 */ { TUNER_ABSENT, "Thompson DTT75105"}, { TUNER_ABSENT, "Conexant_CX24109"}, - { TUNER_TCL_2002N, "TCL M2523_5N_E"}, + { TUNER_ABSENT, "TCL M2523_5N_E"}, { TUNER_ABSENT, "TCL M2523_3DB_E"}, { TUNER_ABSENT, "Philips 8275A"}, { TUNER_ABSENT, "Microtune MT2060"}, @@ -248,32 +248,32 @@ audioIC[] = {AUDIO_CHIP_MSP34XX, "MSP3410D"}, {AUDIO_CHIP_MSP34XX, "MSP3415"}, {AUDIO_CHIP_MSP34XX, "MSP3430"}, - {AUDIO_CHIP_MSP34XX, "MSP3438"}, + {AUDIO_CHIP_UNKNOWN, "MSP3438"}, {AUDIO_CHIP_UNKNOWN, "CS5331"}, /* 10-14 */ {AUDIO_CHIP_MSP34XX, "MSP3435"}, {AUDIO_CHIP_MSP34XX, "MSP3440"}, {AUDIO_CHIP_MSP34XX, "MSP3445"}, - {AUDIO_CHIP_MSP34XX, "MSP3411"}, - {AUDIO_CHIP_MSP34XX, "MSP3416"}, + {AUDIO_CHIP_UNKNOWN, "MSP3411"}, + {AUDIO_CHIP_UNKNOWN, "MSP3416"}, /* 15-19 */ {AUDIO_CHIP_MSP34XX, "MSP3425"}, - {AUDIO_CHIP_MSP34XX, "MSP3451"}, - {AUDIO_CHIP_MSP34XX, "MSP3418"}, + {AUDIO_CHIP_UNKNOWN, "MSP3451"}, + {AUDIO_CHIP_UNKNOWN, "MSP3418"}, {AUDIO_CHIP_UNKNOWN, "Type 0x12"}, {AUDIO_CHIP_UNKNOWN, "OKI7716"}, /* 20-24 */ - {AUDIO_CHIP_MSP34XX, "MSP4410"}, - {AUDIO_CHIP_MSP34XX, "MSP4420"}, - {AUDIO_CHIP_MSP34XX, "MSP4440"}, - {AUDIO_CHIP_MSP34XX, "MSP4450"}, - {AUDIO_CHIP_MSP34XX, "MSP4408"}, + {AUDIO_CHIP_UNKNOWN, "MSP4410"}, + {AUDIO_CHIP_UNKNOWN, "MSP4420"}, + {AUDIO_CHIP_UNKNOWN, "MSP4440"}, + {AUDIO_CHIP_UNKNOWN, "MSP4450"}, + {AUDIO_CHIP_UNKNOWN, "MSP4408"}, /* 25-29 */ - {AUDIO_CHIP_MSP34XX, "MSP4418"}, - {AUDIO_CHIP_MSP34XX, "MSP4428"}, - {AUDIO_CHIP_MSP34XX, "MSP4448"}, - {AUDIO_CHIP_MSP34XX, "MSP4458"}, - {AUDIO_CHIP_MSP34XX, "Type 0x1d"}, + {AUDIO_CHIP_UNKNOWN, "MSP4418"}, + {AUDIO_CHIP_UNKNOWN, "MSP4428"}, + {AUDIO_CHIP_UNKNOWN, "MSP4448"}, + {AUDIO_CHIP_UNKNOWN, "MSP4458"}, + {AUDIO_CHIP_UNKNOWN, "Type 0x1d"}, /* 30-34 */ {AUDIO_CHIP_INTERNAL, "CX880"}, {AUDIO_CHIP_INTERNAL, "CX881"}, @@ -757,9 +757,9 @@ tveeprom_detect_client(struct i2c_adapter *adapter, static int tveeprom_attach_adapter (struct i2c_adapter *adapter) { - if (adapter->class & I2C_CLASS_TV_ANALOG) - return i2c_probe(adapter, &addr_data, tveeprom_detect_client); - return 0; + if (adapter->id != I2C_HW_B_BT848) + return 0; + return i2c_probe(adapter, &addr_data, tveeprom_detect_client); } static int diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index dab4973bc..1864423b3 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c @@ -1,8 +1,8 @@ /* - * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder driver + * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver * - * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org) - * This code is placed under the terms of the GNU General Public License v2 + * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) + * This code is placed under the terms of the GNU General Public License */ #include @@ -13,11 +13,10 @@ #include "tvp5150_reg.h" -MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); +MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */ MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_LICENSE("GPL"); -/* standard i2c insmod options */ static unsigned short normal_i2c[] = { 0xb8 >> 1, 0xba >> 1, @@ -30,9 +29,6 @@ static int debug = 0; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define tvp5150_err(fmt, arg...) do { \ - printk(KERN_ERR "%s %d-%04x: " fmt, c->driver->driver.name, \ - i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) #define tvp5150_info(fmt, arg...) do { \ printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \ i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) @@ -53,7 +49,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 128, + .default_value = 0, .flags = 0, }, { .id = V4L2_CID_CONTRAST, @@ -62,7 +58,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { .minimum = 0, .maximum = 255, .step = 0x1, - .default_value = 128, + .default_value = 0x10, .flags = 0, }, { .id = V4L2_CID_SATURATION, @@ -71,7 +67,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { .minimum = 0, .maximum = 255, .step = 0x1, - .default_value = 128, + .default_value = 0x10, .flags = 0, }, { .id = V4L2_CID_HUE, @@ -80,7 +76,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { .minimum = -128, .maximum = 127, .step = 0x1, - .default_value = 0, + .default_value = 0x10, .flags = 0, } }; @@ -88,7 +84,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { struct tvp5150 { struct i2c_client *client; - v4l2_std_id norm; /* Current set standard */ + int norm; int input; int enable; int bright; @@ -129,155 +125,310 @@ static inline void tvp5150_write(struct i2c_client *c, unsigned char addr, tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc); } -static void dump_reg_range(struct i2c_client *c, char *s, u8 init, const u8 end,int max_line) -{ - int i=0; - - while (init!=(u8)(end+1)) { - if ((i%max_line) == 0) { - if (i>0) - printk("\n"); - printk("tvp5150: %s reg 0x%02x = ",s,init); - } - printk("%02x ",tvp5150_read(c, init)); - - init++; - i++; - } - printk("\n"); -} - static void dump_reg(struct i2c_client *c) { printk("tvp5150: Video input source selection #1 = 0x%02x\n", - tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1)); + tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1)); printk("tvp5150: Analog channel controls = 0x%02x\n", - tvp5150_read(c, TVP5150_ANAL_CHL_CTL)); + tvp5150_read(c, TVP5150_ANAL_CHL_CTL)); printk("tvp5150: Operation mode controls = 0x%02x\n", - tvp5150_read(c, TVP5150_OP_MODE_CTL)); + tvp5150_read(c, TVP5150_OP_MODE_CTL)); printk("tvp5150: Miscellaneous controls = 0x%02x\n", - tvp5150_read(c, TVP5150_MISC_CTL)); - printk("tvp5150: Autoswitch mask= 0x%02x\n", - tvp5150_read(c, TVP5150_AUTOSW_MSK)); + tvp5150_read(c, TVP5150_MISC_CTL)); + printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n", + tvp5150_read(c, TVP5150_AUTOSW_MSK)); printk("tvp5150: Color killer threshold control = 0x%02x\n", - tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL)); - printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n", - tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1), - tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2), - tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3)); + tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL)); + printk("tvp5150: Luminance processing control #1 = 0x%02x\n", + tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1)); + printk("tvp5150: Luminance processing control #2 = 0x%02x\n", + tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2)); printk("tvp5150: Brightness control = 0x%02x\n", - tvp5150_read(c, TVP5150_BRIGHT_CTL)); + tvp5150_read(c, TVP5150_BRIGHT_CTL)); printk("tvp5150: Color saturation control = 0x%02x\n", - tvp5150_read(c, TVP5150_SATURATION_CTL)); + tvp5150_read(c, TVP5150_SATURATION_CTL)); printk("tvp5150: Hue control = 0x%02x\n", - tvp5150_read(c, TVP5150_HUE_CTL)); + tvp5150_read(c, TVP5150_HUE_CTL)); printk("tvp5150: Contrast control = 0x%02x\n", - tvp5150_read(c, TVP5150_CONTRAST_CTL)); + tvp5150_read(c, TVP5150_CONTRAST_CTL)); printk("tvp5150: Outputs and data rates select = 0x%02x\n", - tvp5150_read(c, TVP5150_DATA_RATE_SEL)); + tvp5150_read(c, TVP5150_DATA_RATE_SEL)); + printk("tvp5150: Luminance processing control #3 = 0x%02x\n", + tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3)); printk("tvp5150: Configuration shared pins = 0x%02x\n", - tvp5150_read(c, TVP5150_CONF_SHARED_PIN)); - printk("tvp5150: Active video cropping start = 0x%02x%02x\n", - tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB), - tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB)); - printk("tvp5150: Active video cropping stop = 0x%02x%02x\n", - tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB), - tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB)); + tvp5150_read(c, TVP5150_CONF_SHARED_PIN)); + printk("tvp5150: Active video cropping start MSB = 0x%02x\n", + tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB)); + printk("tvp5150: Active video cropping start LSB = 0x%02x\n", + tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB)); + printk("tvp5150: Active video cropping stop MSB = 0x%02x\n", + tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB)); + printk("tvp5150: Active video cropping stop LSB = 0x%02x\n", + tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB)); printk("tvp5150: Genlock/RTC = 0x%02x\n", - tvp5150_read(c, TVP5150_GENLOCK)); + tvp5150_read(c, TVP5150_GENLOCK)); printk("tvp5150: Horizontal sync start = 0x%02x\n", - tvp5150_read(c, TVP5150_HORIZ_SYNC_START)); + tvp5150_read(c, TVP5150_HORIZ_SYNC_START)); printk("tvp5150: Vertical blanking start = 0x%02x\n", - tvp5150_read(c, TVP5150_VERT_BLANKING_START)); + tvp5150_read(c, TVP5150_VERT_BLANKING_START)); printk("tvp5150: Vertical blanking stop = 0x%02x\n", - tvp5150_read(c, TVP5150_VERT_BLANKING_STOP)); - printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n", - tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1), - tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2)); + tvp5150_read(c, TVP5150_VERT_BLANKING_STOP)); + printk("tvp5150: Chrominance processing control #1 = 0x%02x\n", + tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1)); + printk("tvp5150: Chrominance processing control #2 = 0x%02x\n", + tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2)); printk("tvp5150: Interrupt reset register B = 0x%02x\n", - tvp5150_read(c, TVP5150_INT_RESET_REG_B)); + tvp5150_read(c, TVP5150_INT_RESET_REG_B)); printk("tvp5150: Interrupt enable register B = 0x%02x\n", - tvp5150_read(c, TVP5150_INT_ENABLE_REG_B)); + tvp5150_read(c, TVP5150_INT_ENABLE_REG_B)); printk("tvp5150: Interrupt configuration register B = 0x%02x\n", - tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B)); + tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B)); printk("tvp5150: Video standard = 0x%02x\n", - tvp5150_read(c, TVP5150_VIDEO_STD)); - printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n", - tvp5150_read(c, TVP5150_CB_GAIN_FACT), - tvp5150_read(c, TVP5150_CR_GAIN_FACTOR)); + tvp5150_read(c, TVP5150_VIDEO_STD)); + printk("tvp5150: Cb gain factor = 0x%02x\n", + tvp5150_read(c, TVP5150_CB_GAIN_FACT)); + printk("tvp5150: Cr gain factor = 0x%02x\n", + tvp5150_read(c, TVP5150_CR_GAIN_FACTOR)); printk("tvp5150: Macrovision on counter = 0x%02x\n", - tvp5150_read(c, TVP5150_MACROVISION_ON_CTR)); + tvp5150_read(c, TVP5150_MACROVISION_ON_CTR)); printk("tvp5150: Macrovision off counter = 0x%02x\n", - tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR)); - printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n", - (tvp5150_read(c, TVP5150_REV_SELECT)&1)?3:4); - printk("tvp5150: Device ID = %02x%02x\n", - tvp5150_read(c, TVP5150_MSB_DEV_ID), - tvp5150_read(c, TVP5150_LSB_DEV_ID)); - printk("tvp5150: ROM version = (hex) %02x.%02x\n", - tvp5150_read(c, TVP5150_ROM_MAJOR_VER), - tvp5150_read(c, TVP5150_ROM_MINOR_VER)); - printk("tvp5150: Vertical line count = 0x%02x%02x\n", - tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB), - tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB)); + tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR)); + printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n", + tvp5150_read(c, TVP5150_REV_SELECT)); + printk("tvp5150: MSB of device ID = 0x%02x\n", + tvp5150_read(c, TVP5150_MSB_DEV_ID)); + printk("tvp5150: LSB of device ID = 0x%02x\n", + tvp5150_read(c, TVP5150_LSB_DEV_ID)); + printk("tvp5150: ROM major version = 0x%02x\n", + tvp5150_read(c, TVP5150_ROM_MAJOR_VER)); + printk("tvp5150: ROM minor version = 0x%02x\n", + tvp5150_read(c, TVP5150_ROM_MINOR_VER)); + printk("tvp5150: Vertical line count MSB = 0x%02x\n", + tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB)); + printk("tvp5150: Vertical line count LSB = 0x%02x\n", + tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB)); printk("tvp5150: Interrupt status register B = 0x%02x\n", - tvp5150_read(c, TVP5150_INT_STATUS_REG_B)); + tvp5150_read(c, TVP5150_INT_STATUS_REG_B)); printk("tvp5150: Interrupt active register B = 0x%02x\n", - tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B)); - printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n", - tvp5150_read(c, TVP5150_STATUS_REG_1), - tvp5150_read(c, TVP5150_STATUS_REG_2), - tvp5150_read(c, TVP5150_STATUS_REG_3), - tvp5150_read(c, TVP5150_STATUS_REG_4), - tvp5150_read(c, TVP5150_STATUS_REG_5)); - - dump_reg_range(c,"Teletext filter 1", TVP5150_TELETEXT_FIL1_INI, - TVP5150_TELETEXT_FIL1_END,8); - dump_reg_range(c,"Teletext filter 2", TVP5150_TELETEXT_FIL2_INI, - TVP5150_TELETEXT_FIL2_END,8); - + tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B)); + printk("tvp5150: Status register #1 = 0x%02x\n", + tvp5150_read(c, TVP5150_STATUS_REG_1)); + printk("tvp5150: Status register #2 = 0x%02x\n", + tvp5150_read(c, TVP5150_STATUS_REG_2)); + printk("tvp5150: Status register #3 = 0x%02x\n", + tvp5150_read(c, TVP5150_STATUS_REG_3)); + printk("tvp5150: Status register #4 = 0x%02x\n", + tvp5150_read(c, TVP5150_STATUS_REG_4)); + printk("tvp5150: Status register #5 = 0x%02x\n", + tvp5150_read(c, TVP5150_STATUS_REG_5)); + printk("tvp5150: Closed caption data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_CC_DATA_REG1)); + printk("tvp5150: Closed caption data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_CC_DATA_REG2)); + printk("tvp5150: Closed caption data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_CC_DATA_REG3)); + printk("tvp5150: Closed caption data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_CC_DATA_REG4)); + printk("tvp5150: WSS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_WSS_DATA_REG1)); + printk("tvp5150: WSS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_WSS_DATA_REG2)); + printk("tvp5150: WSS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_WSS_DATA_REG3)); + printk("tvp5150: WSS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_WSS_DATA_REG4)); + printk("tvp5150: WSS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_WSS_DATA_REG5)); + printk("tvp5150: WSS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_WSS_DATA_REG6)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG1)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG2)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG3)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG4)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG5)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG6)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG7)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG8)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG9)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG10)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG11)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG12)); + printk("tvp5150: VPS data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VPS_DATA_REG13)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG1)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG2)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG3)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG4)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG5)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG6)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG7)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG8)); + printk("tvp5150: VITC data registers = 0x%02x\n", + tvp5150_read(c, TVP5150_VITC_DATA_REG9)); + printk("tvp5150: VBI FIFO read data = 0x%02x\n", + tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA)); + printk("tvp5150: Teletext filter 1 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1)); + printk("tvp5150: Teletext filter 1 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2)); + printk("tvp5150: Teletext filter 1 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3)); + printk("tvp5150: Teletext filter 1 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4)); + printk("tvp5150: Teletext filter 1 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5)); + printk("tvp5150: Teletext filter 2 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1)); + printk("tvp5150: Teletext filter 2 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2)); + printk("tvp5150: Teletext filter 2 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3)); + printk("tvp5150: Teletext filter 2 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4)); + printk("tvp5150: Teletext filter 2 = 0x%02x\n", + tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5)); printk("tvp5150: Teletext filter enable = 0x%02x\n", - tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA)); + tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA)); printk("tvp5150: Interrupt status register A = 0x%02x\n", - tvp5150_read(c, TVP5150_INT_STATUS_REG_A)); + tvp5150_read(c, TVP5150_INT_STATUS_REG_A)); printk("tvp5150: Interrupt enable register A = 0x%02x\n", - tvp5150_read(c, TVP5150_INT_ENABLE_REG_A)); + tvp5150_read(c, TVP5150_INT_ENABLE_REG_A)); printk("tvp5150: Interrupt configuration = 0x%02x\n", - tvp5150_read(c, TVP5150_INT_CONF)); + tvp5150_read(c, TVP5150_INT_CONF)); + printk("tvp5150: VDP configuration RAM data = 0x%02x\n", + tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA)); + printk("tvp5150: Configuration RAM address low byte = 0x%02x\n", + tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW)); + printk("tvp5150: Configuration RAM address high byte = 0x%02x\n", + tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH)); printk("tvp5150: VDP status register = 0x%02x\n", - tvp5150_read(c, TVP5150_VDP_STATUS_REG)); + tvp5150_read(c, TVP5150_VDP_STATUS_REG)); printk("tvp5150: FIFO word count = 0x%02x\n", - tvp5150_read(c, TVP5150_FIFO_WORD_COUNT)); + tvp5150_read(c, TVP5150_FIFO_WORD_COUNT)); printk("tvp5150: FIFO interrupt threshold = 0x%02x\n", - tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD)); + tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD)); printk("tvp5150: FIFO reset = 0x%02x\n", - tvp5150_read(c, TVP5150_FIFO_RESET)); + tvp5150_read(c, TVP5150_FIFO_RESET)); printk("tvp5150: Line number interrupt = 0x%02x\n", - tvp5150_read(c, TVP5150_LINE_NUMBER_INT)); - printk("tvp5150: Pixel alignment register = 0x%02x%02x\n", - tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH), - tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW)); + tvp5150_read(c, TVP5150_LINE_NUMBER_INT)); + printk("tvp5150: Pixel alignment register low byte = 0x%02x\n", + tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW)); + printk("tvp5150: Pixel alignment register high byte = 0x%02x\n", + tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH)); printk("tvp5150: FIFO output control = 0x%02x\n", - tvp5150_read(c, TVP5150_FIFO_OUT_CTRL)); - printk("tvp5150: Full field enable = 0x%02x\n", - tvp5150_read(c, TVP5150_FULL_FIELD_ENA)); + tvp5150_read(c, TVP5150_FIFO_OUT_CTRL)); + printk("tvp5150: Full field enable 1 = 0x%02x\n", + tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1)); + printk("tvp5150: Full field enable 2 = 0x%02x\n", + tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_1)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_2)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_3)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_4)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_5)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_6)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_7)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_8)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_9)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_10)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_11)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_12)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_13)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_14)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_15)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_16)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_17)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_18)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_19)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_20)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_21)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_22)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_23)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_24)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_25)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_27)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_28)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_29)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_30)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_31)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_32)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_33)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_34)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_35)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_36)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_37)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_38)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_39)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_40)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_41)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_42)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_43)); + printk("tvp5150: Line mode registers = 0x%02x\n", + tvp5150_read(c, TVP5150_LINE_MODE_REG_44)); printk("tvp5150: Full field mode register = 0x%02x\n", - tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG)); - - dump_reg_range(c,"CC data", TVP5150_CC_DATA_INI, - TVP5150_CC_DATA_END,8); - - dump_reg_range(c,"WSS data", TVP5150_WSS_DATA_INI, - TVP5150_WSS_DATA_END,8); - - dump_reg_range(c,"VPS data", TVP5150_VPS_DATA_INI, - TVP5150_VPS_DATA_END,8); - - dump_reg_range(c,"VITC data", TVP5150_VITC_DATA_INI, - TVP5150_VITC_DATA_END,10); - - dump_reg_range(c,"Line mode", TVP5150_LINE_MODE_INI, - TVP5150_LINE_MODE_END,8); + tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG)); } /**************************************************************************** @@ -442,10 +593,10 @@ static const struct i2c_reg_value tvp5150_init_default[] = { TVP5150_FIFO_OUT_CTRL,0x01 }, { /* 0xcf */ - TVP5150_FULL_FIELD_ENA,0x00 + TVP5150_FULL_FIELD_ENA_1,0x00 }, { /* 0xd0 */ - TVP5150_LINE_MODE_INI,0x00 + TVP5150_FULL_FIELD_ENA_2,0x00 }, { /* 0xfc */ TVP5150_FULL_FIELD_MODE_REG,0x7f @@ -478,109 +629,54 @@ static const struct i2c_reg_value tvp5150_init_enable[] = { } }; -struct tvp5150_vbi_type { - unsigned int vbi_type; - unsigned int ini_line; - unsigned int end_line; - unsigned int by_field :1; -}; - struct i2c_vbi_ram_value { u16 reg; - struct tvp5150_vbi_type type; - unsigned char values[16]; + unsigned char values[26]; }; -/* This struct have the values for each supported VBI Standard - * by - tvp5150_vbi_types should follow the same order as vbi_ram_default - * value 0 means rom position 0x10, value 1 means rom position 0x30 - * and so on. There are 16 possible locations from 0 to 15. - */ - static struct i2c_vbi_ram_value vbi_ram_default[] = { - /* FIXME: Current api doesn't handle all VBI types, those not - yet supported are placed under #if 0 */ -#if 0 - {0x010, /* Teletext, SECAM, WST System A */ - {V4L2_SLICED_TELETEXT_SECAM,6,23,1}, - { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26, - 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 } + {0x010, /* WST SECAM 6 */ + { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x0, 0x0, 0x0, 0x10, 0x0 } }, -#endif - {0x030, /* Teletext, PAL, WST System B */ - {V4L2_SLICED_TELETEXT_B,6,22,1}, - { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b, - 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 } + {0x030, /* WST PAL B 6 */ + { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0 } }, -#if 0 - {0x050, /* Teletext, PAL, WST System C */ - {V4L2_SLICED_TELETEXT_PAL_C,6,22,1}, - { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, - 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } + {0x050, /* WST PAL C 6 */ + { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } }, - {0x070, /* Teletext, NTSC, WST System B */ - {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1}, - { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23, - 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } + {0x070, /* WST NTSC 6 */ + { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } }, - {0x090, /* Tetetext, NTSC NABTS System C */ - {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1}, - { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, - 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 } + {0x090, /* NABTS, NTSC 6 */ + { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x15, 0x0 } }, - {0x0b0, /* Teletext, NTSC-J, NABTS System D */ - {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1}, - { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23, - 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } + {0x0b0, /* NABTS, NTSC-J 6 */ + { 0xaa, 0xaa, 0xff, 0xff , 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } }, - {0x0d0, /* Closed Caption, PAL/SECAM */ - {V4L2_SLICED_CAPTION_625,22,22,1}, - { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, - 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } + {0x0d0, /* CC, PAL/SECAM 6 */ + { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 } }, -#endif - {0x0f0, /* Closed Caption, NTSC */ - {V4L2_SLICED_CAPTION_525,21,21,1}, - { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, - 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } + {0x0f0, /* CC, NTSC 6 */ + { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 } }, - {0x110, /* Wide Screen Signal, PAL/SECAM */ - {V4L2_SLICED_WSS_625,23,23,1}, - { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42, - 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 } + {0x110, /* WSS, PAL/SECAM 6 */ + { 0x5b, 0x55, 0xc5, 0xff , 0x0, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x0, 0x0, 0x0, 0x3a, 0x0 } }, -#if 0 - {0x130, /* Wide Screen Signal, NTSC C */ - {V4L2_SLICED_WSS_525,20,20,1}, - { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43, - 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 } + {0x130, /* WSS, NTSC C */ + { 0x38, 0x00, 0x3f, 0x00 , 0x0, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x0, 0x0, 0x0, 0x39, 0x0 } }, - {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ - {V4l2_SLICED_VITC_625,6,22,0}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, - 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } + {0x150, /* VITC, PAL/SECAM 6 */ + { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 } }, - {0x170, /* Vertical Interval Timecode (VITC), NTSC */ - {V4l2_SLICED_VITC_525,10,20,0}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, - 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } + {0x170, /* VITC, NTSC 6 */ + { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 } }, -#endif - {0x190, /* Video Program System (VPS), PAL */ - {V4L2_SLICED_VPS,16,16,0}, - { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d, - 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 } - }, - /* 0x1d0 User programmable */ - - /* End of struct */ { (u16)-1 } }; static int tvp5150_write_inittab(struct i2c_client *c, - const struct i2c_reg_value *regs) + const struct i2c_reg_value *regs) { while (regs->reg != 0xff) { tvp5150_write(c, regs->reg, regs->value); @@ -590,15 +686,15 @@ static int tvp5150_write_inittab(struct i2c_client *c, } static int tvp5150_vdp_init(struct i2c_client *c, - const struct i2c_vbi_ram_value *regs) + const struct i2c_vbi_ram_value *regs) { unsigned int i; /* Disable Full Field */ - tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0); + tvp5150_write(c, TVP5150_FULL_FIELD_ENA_1, 0); /* Before programming, Line mode should be at 0xff */ - for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++) + for (i=TVP5150_FULL_FIELD_ENA_2; i<=TVP5150_LINE_MODE_REG_44; i++) tvp5150_write(c, i, 0xff); /* Load Ram Table */ @@ -614,117 +710,6 @@ static int tvp5150_vdp_init(struct i2c_client *c, return 0; } -/* Fills VBI capabilities based on i2c_vbi_ram_value struct */ -static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs, - struct v4l2_sliced_vbi_cap *cap) -{ - int line; - - memset(cap, 0, sizeof *cap); - - while (regs->reg != (u16)-1 ) { - for (line=regs->type.ini_line;line<=regs->type.end_line;line++) { - cap->service_lines[0][line] |= regs->type.vbi_type; - } - cap->service_set |= regs->type.vbi_type; - - regs++; - } -} - -/* Set vbi processing - * type - one of tvp5150_vbi_types - * line - line to gather data - * fields: bit 0 field1, bit 1, field2 - * flags (default=0xf0) is a bitmask, were set means: - * bit 7: enable filtering null bytes on CC - * bit 6: send data also to FIFO - * bit 5: don't allow data with errors on FIFO - * bit 4: enable ECC when possible - * pix_align = pix alignment: - * LSB = field1 - * MSB = field2 - */ -static int tvp5150_set_vbi(struct i2c_client *c, - const struct i2c_vbi_ram_value *regs, - unsigned int type,u8 flags, int line, - const int fields) -{ - struct tvp5150 *decoder = i2c_get_clientdata(c); - v4l2_std_id std=decoder->norm; - u8 reg; - int pos=0; - - if (std == V4L2_STD_ALL) { - tvp5150_err("VBI can't be configured without knowing number of lines\n"); - return 0; - } else if (std && V4L2_STD_625_50) { - /* Don't follow NTSC Line number convension */ - line += 3; - } - - if (line<6||line>27) - return 0; - - while (regs->reg != (u16)-1 ) { - if ((type & regs->type.vbi_type) && - (line>=regs->type.ini_line) && - (line<=regs->type.end_line)) { - type=regs->type.vbi_type; - break; - } - - regs++; - pos++; - } - if (regs->reg == (u16)-1) - return 0; - - type=pos | (flags & 0xf0); - reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; - - if (fields&1) { - tvp5150_write(c, reg, type); - } - - if (fields&2) { - tvp5150_write(c, reg+1, type); - } - - return type; -} - -static int tvp5150_get_vbi(struct i2c_client *c, - const struct i2c_vbi_ram_value *regs, int line) -{ - struct tvp5150 *decoder = i2c_get_clientdata(c); - v4l2_std_id std=decoder->norm; - u8 reg; - int pos, type=0; - - if (std == V4L2_STD_ALL) { - tvp5150_err("VBI can't be configured without knowing number of lines\n"); - return 0; - } else if (std && V4L2_STD_625_50) { - /* Don't follow NTSC Line number convension */ - line += 3; - } - - if (line<6||line>27) - return 0; - - reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; - - pos=tvp5150_read(c, reg)&0x0f; - if (pos<0x0f) - type=regs[pos].type.vbi_type; - - pos=tvp5150_read(c, reg+1)&0x0f; - if (pos<0x0f) - type|=regs[pos].type.vbi_type; - - return type; -} static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) { struct tvp5150 *decoder = i2c_get_clientdata(c); @@ -858,6 +843,7 @@ static int tvp5150_command(struct i2c_client *c, case 0: case VIDIOC_INT_RESET: + case DECODER_INIT: tvp5150_reset(c); break; case VIDIOC_S_STD: @@ -868,69 +854,6 @@ static int tvp5150_command(struct i2c_client *c, *(v4l2_std_id *)arg = decoder->norm; break; - case VIDIOC_G_SLICED_VBI_CAP: - { - struct v4l2_sliced_vbi_cap *cap = arg; - tvp5150_dbg(1, "VIDIOC_G_SLICED_VBI_CAP\n"); - - tvp5150_vbi_get_cap(vbi_ram_default, cap); - break; - } - case VIDIOC_S_FMT: - { - struct v4l2_format *fmt; - struct v4l2_sliced_vbi_format *svbi; - int i; - - fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - if (svbi->service_set != 0) { - for (i = 0; i <= 23; i++) { - svbi->service_lines[1][i] = 0; - - svbi->service_lines[0][i]=tvp5150_set_vbi(c, - vbi_ram_default, - svbi->service_lines[0][i],0xf0,i,3); - } - /* Enables FIFO */ - tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,1); - } else { - /* Disables FIFO*/ - tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,0); - - /* Disable Full Field */ - tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0); - - /* Disable Line modes */ - for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++) - tvp5150_write(c, i, 0xff); - } - break; - } - case VIDIOC_G_FMT: - { - struct v4l2_format *fmt; - struct v4l2_sliced_vbi_format *svbi; - - int i, mask=0; - - fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - memset(svbi, 0, sizeof(*svbi)); - - for (i = 0; i <= 23; i++) { - svbi->service_lines[0][i]=tvp5150_get_vbi(c, - vbi_ram_default,i); - mask|=svbi->service_lines[0][i]; - } - svbi->service_set=mask; - break; - } - #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_INT_G_REGISTER: { @@ -955,16 +878,99 @@ static int tvp5150_command(struct i2c_client *c, } #endif - case VIDIOC_LOG_STATUS: + case DECODER_DUMP: dump_reg(c); break; - case VIDIOC_G_TUNER: + case DECODER_GET_CAPABILITIES: + { + struct video_decoder_capability *cap = arg; + + cap->flags = VIDEO_DECODER_PAL | + VIDEO_DECODER_NTSC | + VIDEO_DECODER_SECAM | + VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR; + cap->inputs = 3; + cap->outputs = 1; + break; + } + case DECODER_GET_STATUS: + { + int *iarg = arg; + int status; + int res=0; + status = tvp5150_read(c, 0x88); + if(status&0x08){ + res |= DECODER_STATUS_COLOR; + } + if(status&0x04 && status&0x02){ + res |= DECODER_STATUS_GOOD; + } + *iarg=res; + break; + } + + case DECODER_SET_GPIO: + break; + + case DECODER_SET_VBI_BYPASS: + break; + + case DECODER_SET_NORM: + { + int *iarg = arg; + + switch (*iarg) { + + case VIDEO_MODE_NTSC: + break; + + case VIDEO_MODE_PAL: + break; + + case VIDEO_MODE_SECAM: + break; + + case VIDEO_MODE_AUTO: + break; + + default: + return -EINVAL; + + } + decoder->norm = *iarg; + break; + } + case DECODER_SET_INPUT: { - struct v4l2_tuner *vt = arg; - int status = tvp5150_read(c, 0x88); + int *iarg = arg; + if (*iarg < 0 || *iarg > 3) { + return -EINVAL; + } + + decoder->input = *iarg; + tvp5150_selmux(c, decoder->input); + + break; + } + case DECODER_SET_OUTPUT: + { + int *iarg = arg; + + /* not much choice of outputs */ + if (*iarg != 0) { + return -EINVAL; + } + break; + } + case DECODER_ENABLE_OUTPUT: + { + int *iarg = arg; + + decoder->enable = (*iarg != 0); + + tvp5150_selmux(c, decoder->input); - vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0; break; } case VIDIOC_QUERYCTRL: @@ -1010,6 +1016,35 @@ static int tvp5150_command(struct i2c_client *c, return -EINVAL; } + case DECODER_SET_PICTURE: + { + struct video_picture *pic = arg; + if (decoder->bright != pic->brightness) { + /* We want 0 to 255 we get 0-65535 */ + decoder->bright = pic->brightness; + tvp5150_write(c, TVP5150_BRIGHT_CTL, + decoder->bright >> 8); + } + if (decoder->contrast != pic->contrast) { + /* We want 0 to 255 we get 0-65535 */ + decoder->contrast = pic->contrast; + tvp5150_write(c, TVP5150_CONTRAST_CTL, + decoder->contrast >> 8); + } + if (decoder->sat != pic->colour) { + /* We want 0 to 255 we get 0-65535 */ + decoder->sat = pic->colour; + tvp5150_write(c, TVP5150_SATURATION_CTL, + decoder->contrast >> 8); + } + if (decoder->hue != pic->hue) { + /* We want -128 to 127 we get 0-65535 */ + decoder->hue = pic->hue; + tvp5150_write(c, TVP5150_HUE_CTL, + (decoder->hue - 32768) >> 8); + } + break; + } default: return -EINVAL; } @@ -1062,7 +1097,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, rv = i2c_attach_client(c); - core->norm = V4L2_STD_ALL; /* Default is autodetect */ + core->norm = V4L2_STD_ALL; core->input = 2; core->enable = 1; core->bright = 32768; diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h index 4240043c0..cd45c1ded 100644 --- a/drivers/media/video/tvp5150_reg.h +++ b/drivers/media/video/tvp5150_reg.h @@ -1,10 +1,3 @@ -/* - * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers - * - * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org) - * This code is placed under the terms of the GNU General Public License v2 - */ - #define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */ #define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */ #define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */ @@ -71,32 +64,49 @@ #define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */ #define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */ /* Reserved 8Dh-8Fh */ - /* Closed caption data registers */ -#define TVP5150_CC_DATA_INI 0x90 -#define TVP5150_CC_DATA_END 0x93 - - /* WSS data registers */ -#define TVP5150_WSS_DATA_INI 0x94 -#define TVP5150_WSS_DATA_END 0x99 - -/* VPS data registers */ -#define TVP5150_VPS_DATA_INI 0x9a -#define TVP5150_VPS_DATA_END 0xa6 - -/* VITC data registers */ -#define TVP5150_VITC_DATA_INI 0xa7 -#define TVP5150_VITC_DATA_END 0xaf - +#define TVP5150_CC_DATA_REG1 0x90 /* Closed caption data registers */ +#define TVP5150_CC_DATA_REG2 0x91 /* Closed caption data registers */ +#define TVP5150_CC_DATA_REG3 0x92 /* Closed caption data registers */ +#define TVP5150_CC_DATA_REG4 0x93 /* Closed caption data registers */ +#define TVP5150_WSS_DATA_REG1 0X94 /* WSS data registers */ +#define TVP5150_WSS_DATA_REG2 0X95 /* WSS data registers */ +#define TVP5150_WSS_DATA_REG3 0X96 /* WSS data registers */ +#define TVP5150_WSS_DATA_REG4 0X97 /* WSS data registers */ +#define TVP5150_WSS_DATA_REG5 0X98 /* WSS data registers */ +#define TVP5150_WSS_DATA_REG6 0X99 /* WSS data registers */ +#define TVP5150_VPS_DATA_REG1 0x9a /* VPS data registers */ +#define TVP5150_VPS_DATA_REG2 0x9b /* VPS data registers */ +#define TVP5150_VPS_DATA_REG3 0x9c /* VPS data registers */ +#define TVP5150_VPS_DATA_REG4 0x9d /* VPS data registers */ +#define TVP5150_VPS_DATA_REG5 0x9e /* VPS data registers */ +#define TVP5150_VPS_DATA_REG6 0x9f /* VPS data registers */ +#define TVP5150_VPS_DATA_REG7 0xa0 /* VPS data registers */ +#define TVP5150_VPS_DATA_REG8 0xa1 /* VPS data registers */ +#define TVP5150_VPS_DATA_REG9 0xa2 /* VPS data registers */ +#define TVP5150_VPS_DATA_REG10 0xa3 /* VPS data registers */ +#define TVP5150_VPS_DATA_REG11 0xa4 /* VPS data registers */ +#define TVP5150_VPS_DATA_REG12 0xa5 /* VPS data registers */ +#define TVP5150_VPS_DATA_REG13 0xa6 /* VPS data registers */ +#define TVP5150_VITC_DATA_REG1 0xa7 /* VITC data registers */ +#define TVP5150_VITC_DATA_REG2 0xa8 /* VITC data registers */ +#define TVP5150_VITC_DATA_REG3 0xa9 /* VITC data registers */ +#define TVP5150_VITC_DATA_REG4 0xaa /* VITC data registers */ +#define TVP5150_VITC_DATA_REG5 0xab /* VITC data registers */ +#define TVP5150_VITC_DATA_REG6 0xac /* VITC data registers */ +#define TVP5150_VITC_DATA_REG7 0xad /* VITC data registers */ +#define TVP5150_VITC_DATA_REG8 0xae /* VITC data registers */ +#define TVP5150_VITC_DATA_REG9 0xaf /* VITC data registers */ #define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */ - -/* Teletext filter 1 */ -#define TVP5150_TELETEXT_FIL1_INI 0xb1 -#define TVP5150_TELETEXT_FIL1_END 0xb5 - -/* Teletext filter 2 */ -#define TVP5150_TELETEXT_FIL2_INI 0xb6 -#define TVP5150_TELETEXT_FIL2_END 0xba - +#define TVP5150_TELETEXT_FIL_1_1 0xb1 /* Teletext filter 1 */ +#define TVP5150_TELETEXT_FIL_1_2 0xb2 /* Teletext filter 1 */ +#define TVP5150_TELETEXT_FIL_1_3 0xb3 /* Teletext filter 1 */ +#define TVP5150_TELETEXT_FIL_1_4 0xb4 /* Teletext filter 1 */ +#define TVP5150_TELETEXT_FIL_1_5 0xb5 /* Teletext filter 1 */ +#define TVP5150_TELETEXT_FIL_2_1 0xb6 /* Teletext filter 2 */ +#define TVP5150_TELETEXT_FIL_2_2 0xb7 /* Teletext filter 2 */ +#define TVP5150_TELETEXT_FIL_2_3 0xb8 /* Teletext filter 2 */ +#define TVP5150_TELETEXT_FIL_2_4 0xb9 /* Teletext filter 2 */ +#define TVP5150_TELETEXT_FIL_2_5 0xba /* Teletext filter 2 */ #define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */ /* Reserved BCh-BFh */ #define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */ @@ -114,11 +124,50 @@ #define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */ #define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */ /* Reserved CEh */ -#define TVP5150_FULL_FIELD_ENA 0xcf /* Full field enable 1 */ - -/* Line mode registers */ -#define TVP5150_LINE_MODE_INI 0xd0 -#define TVP5150_LINE_MODE_END 0xfb - +#define TVP5150_FULL_FIELD_ENA_1 0xcf /* Full field enable 1 */ +#define TVP5150_FULL_FIELD_ENA_2 0xd0 /* Full field enable 2 */ +#define TVP5150_LINE_MODE_REG_1 0xd1 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_2 0xd2 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_3 0xd3 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_4 0xd4 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_5 0xd5 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_6 0xd6 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_7 0xd7 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_8 0xd8 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_9 0xd9 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_10 0xda /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_11 0xdb /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_12 0xdc /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_13 0xdd /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_14 0xde /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_15 0xdf /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_16 0xe0 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_17 0xe1 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_18 0xe2 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_19 0xe3 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_20 0xe4 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_21 0xe5 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_22 0xe6 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_23 0xe7 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_24 0xe8 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_25 0xe9 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_27 0xea /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_28 0xeb /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_29 0xec /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_30 0xed /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_31 0xee /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_32 0xef /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_33 0xf0 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_34 0xf1 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_35 0xf2 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_36 0xf3 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_37 0xf4 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_38 0xf5 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_39 0xf6 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_40 0xf7 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_41 0xf8 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_42 0xf9 /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_43 0xfa /* Line mode registers */ +#define TVP5150_LINE_MODE_REG_44 0xfb /* Line mode registers */ #define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */ /* Reserved FDh-FFh */ diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c deleted file mode 100644 index fc52201d6..000000000 --- a/drivers/media/video/upd64031a.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * upd64031A - NEC Electronics Ghost Reduction for NTSC in Japan - * - * 2003 by T.Adachi - * 2003 by Takeru KOMORIYA - * 2006 by Hans Verkuil - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -// --------------------- read registers functions define ----------------------- - -/* bit masks */ -#define GR_MODE_MASK 0xc0 -#define DIRECT_3DYCS_CONNECT_MASK 0xc0 -#define SYNC_CIRCUIT_MASK 0xa0 - -// ----------------------------------------------------------------------------- - -MODULE_DESCRIPTION("uPD64031A driver"); -MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil"); -MODULE_LICENSE("GPL"); - -static int debug = 0; -module_param(debug, int, 0644); - -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - -static unsigned short normal_i2c[] = { 0x24 >> 1, 0x26 >> 1, I2C_CLIENT_END }; - - -I2C_CLIENT_INSMOD; - -enum { - R00 = 0, R01, R02, R03, R04, - R05, R06, R07, R08, R09, - R0A, R0B, R0C, R0D, R0E, R0F, - /* unused registers - R10, R11, R12, R13, R14, - R15, R16, R17, - */ - TOT_REGS -}; - -struct upd64031a_state { - u8 regs[TOT_REGS]; - u8 gr_mode; - u8 direct_3dycs_connect; - u8 ext_comp_sync; - u8 ext_vert_sync; -}; - -static u8 upd64031a_init[] = { - 0x00, 0xb8, 0x48, 0xd2, 0xe6, - 0x03, 0x10, 0x0b, 0xaf, 0x7f, - 0x00, 0x00, 0x1d, 0x5e, 0x00, - 0xd0 -}; - -/* ------------------------------------------------------------------------ */ - -static u8 upd64031a_read(struct i2c_client *client, u8 reg) -{ - u8 buf[2]; - - if (reg >= sizeof(buf)) - return 0xff; - i2c_master_recv(client, buf, 2); - return buf[reg]; -} - -/* ------------------------------------------------------------------------ */ - -static void upd64031a_write(struct i2c_client *client, u8 reg, u8 val) -{ - u8 buf[2]; - - buf[0] = reg; - buf[1] = val; - v4l_dbg(1, debug, client, "writing reg addr: %02X val: %02X\n", reg, val); - if (i2c_master_send(client, buf, 2) != 2) - v4l_err(client, "I/O error write 0x%02x/0x%02x\n", reg, val); -} - -/* ------------------------------------------------------------------------ */ - -/* The input changed due to new input or channel changed */ -static void upd64031a_change(struct i2c_client *client) -{ - struct upd64031a_state *state = i2c_get_clientdata(client); - u8 reg = state->regs[R00]; - - v4l_dbg(1, debug, client, "changed input or channel\n"); - upd64031a_write(client, R00, reg | 0x10); - upd64031a_write(client, R00, reg & ~0x10); -} - -/* ------------------------------------------------------------------------ */ - -static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - struct upd64031a_state *state = i2c_get_clientdata(client); - struct v4l2_routing *route = arg; - - switch (cmd) { - case VIDIOC_S_FREQUENCY: - upd64031a_change(client); - break; - - case VIDIOC_INT_G_VIDEO_ROUTING: - route->input = (state->gr_mode >> 6) | - (state->direct_3dycs_connect >> 4) | - (state->ext_comp_sync >> 1) | - (state->ext_vert_sync >> 2); - route->output = 0; - break; - - case VIDIOC_INT_S_VIDEO_ROUTING: - { - u8 r00, r05, r08; - - state->gr_mode = (route->input & 3) << 6; - state->direct_3dycs_connect = (route->input & 0xc) << 4; - state->ext_comp_sync = (route->input & UPD64031A_COMPOSITE_EXTERNAL) << 1; - state->ext_vert_sync = (route->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; - r08 = (state->regs[R08] & ~DIRECT_3DYCS_CONNECT_MASK) | - state->direct_3dycs_connect; - upd64031a_write(client, R00, r00); - upd64031a_write(client, R05, r05); - upd64031a_write(client, R08, r08); - upd64031a_change(client); - break; - } - - case VIDIOC_LOG_STATUS: - v4l_info(client, "Status: SA00=0x%02x SA01=0x%02x\n", - upd64031a_read(client, 0), upd64031a_read(client, 1)); - break; - -#ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_UPD64031A) - return -EINVAL; - reg->val = upd64031a_read(client, reg->reg & 0xff); - break; - } - - case VIDIOC_INT_S_REGISTER: - { - struct v4l2_register *reg = arg; - u8 addr = reg->reg & 0xff; - u8 val = reg->val & 0xff; - - if (reg->i2c_id != I2C_DRIVERID_UPD64031A) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - upd64031a_write(client, addr, val); - break; - } -#endif - - default: - break; - } - return 0; -} - -/* ------------------------------------------------------------------------ */ - -/* i2c implementation */ - -static struct i2c_driver i2c_driver; - -static int upd64031a_attach(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct upd64031a_state *state; - int i; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; - - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) { - return -ENOMEM; - } - - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver; - snprintf(client->name, sizeof(client->name) - 1, "uPD64031A"); - - v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); - - state = kmalloc(sizeof(struct upd64031a_state), GFP_KERNEL); - if (state == NULL) { - kfree(client); - return -ENOMEM; - } - i2c_set_clientdata(client, state); - memcpy(state->regs, upd64031a_init, sizeof(state->regs)); - state->gr_mode = UPD64031A_GR_ON << 6; - state->direct_3dycs_connect = UPD64031A_3DYCS_COMPOSITE << 4; - state->ext_comp_sync = state->ext_vert_sync = 0; - for (i = 0; i < TOT_REGS; i++) { - upd64031a_write(client, i, state->regs[i]); - } - - i2c_attach_client(client); - - return 0; -} - -static int upd64031a_probe(struct i2c_adapter *adapter) -{ - if (adapter->class & I2C_CLASS_TV_ANALOG) - return i2c_probe(adapter, &addr_data, upd64031a_attach); - return 0; -} - -static int upd64031a_detach(struct i2c_client *client) -{ - int err; - - err = i2c_detach_client(client); - if (err) - return err; - - kfree(client); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* i2c implementation */ -static struct i2c_driver i2c_driver = { - .driver = { - .name = "upd64031a", - }, - .id = I2C_DRIVERID_UPD64031A, - .attach_adapter = upd64031a_probe, - .detach_client = upd64031a_detach, - .command = upd64031a_command, -}; - - -static int __init upd64031a_init_module(void) -{ - return i2c_add_driver(&i2c_driver); -} - -static void __exit upd64031a_exit_module(void) -{ - i2c_del_driver(&i2c_driver); -} - -module_init(upd64031a_init_module); -module_exit(upd64031a_exit_module); diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c deleted file mode 100644 index c3a7ffe5c..000000000 --- a/drivers/media/video/upd64083.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * upd6408x - NEC Electronics 3-Dimensional Y/C separation driver - * - * 2003 by T.Adachi (tadachi@tadachi-net.com) - * 2003 by Takeru KOMORIYA - * 2006 by Hans Verkuil - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("uPD64083 driver"); -MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil"); -MODULE_LICENSE("GPL"); - -static int debug = 0; -module_param(debug, bool, 0644); - -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - -static unsigned short normal_i2c[] = { 0xb8 >> 1, 0xba >> 1, I2C_CLIENT_END }; - - -I2C_CLIENT_INSMOD; - -enum { - R00 = 0, R01, R02, R03, R04, - R05, R06, R07, R08, R09, - R0A, R0B, R0C, R0D, R0E, R0F, - R10, R11, R12, R13, R14, - R15, R16, - TOT_REGS -}; - -struct upd64083_state { - u8 mode; - u8 ext_y_adc; - u8 regs[TOT_REGS]; -}; - -/* Initial values when used in combination with the - NEC upd64031a ghost reduction chip. */ -static u8 upd64083_init[] = { - 0x1f, 0x01, 0xa0, 0x2d, 0x29, /* we use EXCSS=0 */ - 0x36, 0xdd, 0x05, 0x56, 0x48, - 0x00, 0x3a, 0xa0, 0x05, 0x08, - 0x44, 0x60, 0x08, 0x52, 0xf8, - 0x53, 0x60, 0x10 -}; - -/* ------------------------------------------------------------------------ */ - -static void upd64083_log_status(struct i2c_client *client) -{ - u8 buf[7]; - - i2c_master_recv(client, buf, 7); - v4l_info(client, "Status: SA00=%02x SA01=%02x SA02=%02x SA03=%02x " - "SA04=%02x SA05=%02x SA06=%02x\n", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); -} - -/* ------------------------------------------------------------------------ */ - -static void upd64083_write(struct i2c_client *client, u8 reg, u8 val) -{ - u8 buf[2]; - - buf[0] = reg; - buf[1] = val; - v4l_dbg(1, debug, client, "writing reg addr: %02x val: %02x\n", reg, val); - if (i2c_master_send(client, buf, 2) != 2) - v4l_err(client, "I/O error write 0x%02x/0x%02x\n", reg, val); -} - -/* ------------------------------------------------------------------------ */ - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static u8 upd64083_read(struct i2c_client *client, u8 reg) -{ - u8 buf[7]; - - if (reg >= sizeof(buf)) - return 0xff; - i2c_master_recv(client, buf, sizeof(buf)); - return buf[reg]; -} -#endif - -/* ------------------------------------------------------------------------ */ - -static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - struct upd64083_state *state = i2c_get_clientdata(client); - struct v4l2_routing *route = arg; - - switch (cmd) { - case VIDIOC_INT_G_VIDEO_ROUTING: - route->input = (state->mode >> 6) | (state->ext_y_adc >> 3); - route->output = 0; - break; - - case VIDIOC_INT_S_VIDEO_ROUTING: - { - u8 r00, r02; - - if (route->input > 7 || (route->input & 6) == 6) - return -EINVAL; - state->mode = (route->input & 3) << 6; - state->ext_y_adc = (route->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(client, R00, r00); - upd64083_write(client, R02, r02); - break; - } - - case VIDIOC_LOG_STATUS: - upd64083_log_status(client); - break; - -#ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_UPD64083) - return -EINVAL; - reg->val = upd64083_read(client, reg->reg & 0xff); - break; - } - - case VIDIOC_INT_S_REGISTER: - { - struct v4l2_register *reg = arg; - u8 addr = reg->reg & 0xff; - u8 val = reg->val & 0xff; - - if (reg->i2c_id != I2C_DRIVERID_UPD64083) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - upd64083_write(client, addr, val); - break; - } -#endif - default: - break; - } - - return 0; -} - -/* ------------------------------------------------------------------------ */ - -/* i2c implementation */ - -static struct i2c_driver i2c_driver; - -static int upd64083_attach(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct upd64083_state *state; - int i; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; - - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) { - return -ENOMEM; - } - - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver; - snprintf(client->name, sizeof(client->name) - 1, "uPD64083"); - - v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); - - state = kmalloc(sizeof(struct upd64083_state), GFP_KERNEL); - if (state == NULL) { - kfree(client); - return -ENOMEM; - } - i2c_set_clientdata(client, state); - /* Initially assume that a ghost reduction chip is present */ - state->mode = 0; /* YCS mode */ - state->ext_y_adc = (1 << 5); - memcpy(state->regs, upd64083_init, TOT_REGS); - for (i = 0; i < TOT_REGS; i++) { - upd64083_write(client, i, state->regs[i]); - } - i2c_attach_client(client); - - return 0; -} - -static int upd64083_probe(struct i2c_adapter *adapter) -{ - if (adapter->class & I2C_CLASS_TV_ANALOG) - return i2c_probe(adapter, &addr_data, upd64083_attach); - return 0; -} - -static int upd64083_detach(struct i2c_client *client) -{ - int err; - - err = i2c_detach_client(client); - if (err) - return err; - - kfree(client); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* i2c implementation */ -static struct i2c_driver i2c_driver = { - .driver = { - .name = "upd64083", - }, - .id = I2C_DRIVERID_UPD64083, - .attach_adapter = upd64083_probe, - .detach_client = upd64083_detach, - .command = upd64083_command, -}; - - -static int __init upd64083_init_module(void) -{ - return i2c_add_driver(&i2c_driver); -} - -static void __exit upd64083_exit_module(void) -{ - i2c_del_driver(&i2c_driver); -} - -module_init(upd64083_init_module); -module_exit(upd64083_exit_module); diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig deleted file mode 100644 index 39269a2c5..000000000 --- a/drivers/media/video/usbvideo/Kconfig +++ /dev/null @@ -1,38 +0,0 @@ -config VIDEO_USBVIDEO - tristate - -config USB_VICAM - tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)" - depends on USB && VIDEO_V4L1 && EXPERIMENTAL - select VIDEO_USBVIDEO - ---help--- - Say Y here if you have 3com homeconnect camera (vicam). - - To compile this driver as a module, choose M here: the - module will be called vicam. - -config USB_IBMCAM - tristate "USB IBM (Xirlink) C-it Camera support" - depends on USB && VIDEO_V4L1 - select VIDEO_USBVIDEO - ---help--- - Say Y here if you want to connect a IBM "C-It" camera, also known as - "Xirlink PC Camera" to your computer's USB port. - - To compile this driver as a module, choose M here: the - module will be called ibmcam. - - This camera has several configuration options which - can be specified when you load the module. Read - to learn more. - -config USB_KONICAWC - tristate "USB Konica Webcam support" - depends on USB && VIDEO_V4L1 - select VIDEO_USBVIDEO - ---help--- - Say Y here if you want support for webcams based on a Konica - chipset. This is known to work with the Intel YC76 webcam. - - To compile this driver as a module, choose M here: the - module will be called konicawc. diff --git a/drivers/media/video/usbvideo/Makefile b/drivers/media/video/usbvideo/Makefile deleted file mode 100644 index bb52eb8dc..000000000 --- a/drivers/media/video/usbvideo/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o -obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o -obj-$(CONFIG_USB_KONICAWC) += konicawc.o -obj-$(CONFIG_USB_VICAM) += vicam.o diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index d330fa985..cd2c44755 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -97,7 +97,7 @@ int v4l2_video_std_construct(struct v4l2_standard *vs, memset(vs, 0, sizeof(struct v4l2_standard)); vs->index = index; vs->id = id; - if (id & V4L2_STD_525_60) { + if (id & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) { vs->frameperiod.numerator = 1001; vs->frameperiod.denominator = 30000; vs->framelines = 525; @@ -110,6 +110,7 @@ int v4l2_video_std_construct(struct v4l2_standard *vs, return 0; } + /* ----------------------------------------------------------------- */ /* priority handling */ @@ -170,7 +171,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local) /* ----------------------------------------------------------------- */ -/* some arrays for pretty-printing debug messages of enum types */ +/* some arrays for pretty-printing debug messages */ char *v4l2_field_names[] = { [V4L2_FIELD_ANY] = "any", @@ -191,14 +192,6 @@ char *v4l2_type_names[] = { [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", }; -static char *v4l2_memory_names[] = { - [V4L2_MEMORY_MMAP] = "mmap", - [V4L2_MEMORY_USERPTR] = "userptr", - [V4L2_MEMORY_OVERLAY] = "overlay", -}; - -#define prt_names(a,arr) (((a)>=0)&&((a)width,fmt->height,fmt->pixelformat, - prt_names(fmt->field,v4l2_field_names), - fmt->bytesperline,fmt->sizeimage,fmt->colorspace); -}; - /* 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) @@ -382,537 +362,6 @@ void v4l_printk_ioctl(unsigned int cmd) } } -/* Common ioctl debug function. This function can be used by - external ioctl messages as well as internal V4L ioctl and its - arguments */ -void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) -{ - printk(s); - printk(": "); - v4l_printk_ioctl(cmd); - switch (cmd) { - case VIDIOC_INT_G_CHIP_IDENT: - { - enum v4l2_chip_ident *p=arg; - printk ("%s: chip ident=%d\n", s, *p); - break; - } - case VIDIOC_G_PRIORITY: - case VIDIOC_S_PRIORITY: - { - enum v4l2_priority *p=arg; - printk ("%s: priority=%d\n", s, *p); - break; - } - case VIDIOC_INT_S_TUNER_MODE: - { - enum v4l2_tuner_type *p=arg; - printk ("%s: tuner type=%d\n", s, *p); - break; - } - case DECODER_SET_VBI_BYPASS: - case DECODER_ENABLE_OUTPUT: - case DECODER_GET_STATUS: - case DECODER_SET_OUTPUT: - case DECODER_SET_INPUT: - case DECODER_SET_GPIO: - case DECODER_SET_NORM: - case VIDIOCCAPTURE: - case VIDIOCSYNC: - case VIDIOCSWRITEMODE: - case TUNER_SET_TYPE_ADDR: - case TUNER_SET_STANDBY: - case TDA9887_SET_CONFIG: - case VIDIOC_OVERLAY_OLD: - case VIDIOC_STREAMOFF: - case VIDIOC_G_OUTPUT: - case VIDIOC_S_OUTPUT: - case VIDIOC_STREAMON: - case VIDIOC_G_INPUT: - case VIDIOC_OVERLAY: - case VIDIOC_S_INPUT: - { - int *p=arg; - printk ("%s: value=%d\n", s, *p); - break; - } - case VIDIOC_G_AUDIO: - case VIDIOC_S_AUDIO: - case VIDIOC_ENUMAUDIO: - case VIDIOC_G_AUDIO_OLD: - { - struct v4l2_audio *p=arg; - - printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", - s,p->index, p->name,p->capability, p->mode); - break; - } - case VIDIOC_G_AUDOUT: - case VIDIOC_S_AUDOUT: - case VIDIOC_ENUMAUDOUT: - case VIDIOC_G_AUDOUT_OLD: - { - struct v4l2_audioout *p=arg; - printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s, - p->index, p->name, p->capability,p->mode); - break; - } - case VIDIOC_QBUF: - case VIDIOC_DQBUF: - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *p=arg; - struct v4l2_timecode *tc=&p->timecode; - printk ("%s: %02ld:%02d:%02d.%08ld index=%d, type=%s, " - "bytesused=%d, flags=0x%08x, " - "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n", - s, - (p->timestamp.tv_sec/3600), - (int)(p->timestamp.tv_sec/60)%60, - (int)(p->timestamp.tv_sec%60), - p->timestamp.tv_usec, - p->index, - prt_names(p->type,v4l2_type_names), - p->bytesused,p->flags, - p->field,p->sequence, - prt_names(p->memory,v4l2_memory_names), - p->m.userptr); - printk ("%s: timecode= %02d:%02d:%02d type=%d, " - "flags=0x%08x, frames=%d, userbits=0x%p\n", - s,tc->hours,tc->minutes,tc->seconds, - tc->type, tc->flags, tc->frames, tc->userbits); - break; - } - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *p=arg; - printk ("%s: driver=%s, card=%s, bus=%s, version=0x%08x, " - "capabilities=0x%08x\n", s, - p->driver,p->card,p->bus_info, - p->version, - p->capabilities); - break; - } - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL: - case VIDIOC_S_CTRL_OLD: - { - struct v4l2_control *p=arg; - printk ("%s: id=%d, value=%d\n", s, p->id, p->value); - break; - } - case VIDIOC_G_CROP: - case VIDIOC_S_CROP: - { - struct v4l2_crop *p=arg; - /*FIXME: Should also show rect structs */ - printk ("%s: type=%d\n", s, p->type); - break; - } - case VIDIOC_CROPCAP: - case VIDIOC_CROPCAP_OLD: - { - struct v4l2_cropcap *p=arg; - /*FIXME: Should also show rect structs */ - printk ("%s: type=%d\n", s, p->type); - break; - } - case VIDIOC_INT_DECODE_VBI_LINE: - { - struct v4l2_decode_vbi_line *p=arg; - printk ("%s: is_second_field=%d, ptr=0x%08lx, line=%d, " - "type=%d\n", s, - p->is_second_field,(unsigned long)p->p,p->line,p->type); - break; - } - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *p=arg; - printk ("%s: index=%d, type=%d, flags=%d, description=%s," - " pixelformat=%d\n", s, - p->index, p->type, p->flags,p->description, - p->pixelformat); - - break; - } - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: - { - struct v4l2_format *p=arg; - printk ("%s: type=%s\n", s, - prt_names(p->type,v4l2_type_names)); - switch (p->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - v4l_print_pix_fmt (s, &p->fmt.pix); - break; - default: - break; - } - } - case VIDIOC_G_FBUF: - case VIDIOC_S_FBUF: - { - struct v4l2_framebuffer *p=arg; - printk ("%s: capability=%d, flags=%d, base=0x%08lx\n", s, - p->capability,p->flags, (unsigned long)p->base); - v4l_print_pix_fmt (s, &p->fmt); - break; - } - case VIDIOC_G_FREQUENCY: - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *p=arg; - printk ("%s: tuner=%d, type=%d, frequency=%d\n", s, - p->tuner,p->type,p->frequency); - break; - } - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *p=arg; - printk ("%s: index=%d, name=%s, type=%d, audioset=%d, " - "tuner=%d, std=%Ld, status=%d\n", s, - p->index,p->name,p->type,p->audioset, - p->tuner, - (unsigned long long)p->std, - p->status); - break; - } - case VIDIOC_G_JPEGCOMP: - case VIDIOC_S_JPEGCOMP: - { - struct v4l2_jpegcompression *p=arg; - printk ("%s: quality=%d, APPn=%d, APP_len=%d, COM_len=%d," - " jpeg_markers=%d\n", s, - p->quality,p->APPn,p->APP_len, - p->COM_len,p->jpeg_markers); - break; - } - case VIDIOC_G_MODULATOR: - case VIDIOC_S_MODULATOR: - { - struct v4l2_modulator *p=arg; - printk ("%s: index=%d, name=%s, capability=%d, rangelow=%d," - " rangehigh=%d, txsubchans=%d\n", s, - p->index, p->name,p->capability,p->rangelow, - p->rangehigh,p->txsubchans); - break; - } - case VIDIOC_G_MPEGCOMP: - case VIDIOC_S_MPEGCOMP: - { - struct v4l2_mpeg_compression *p=arg; - /*FIXME: Several fields not shown */ - printk ("%s: ts_pid_pmt=%d, ts_pid_audio=%d, ts_pid_video=%d, " - "ts_pid_pcr=%d, ps_size=%d, au_sample_rate=%d, " - "au_pesid=%c, vi_frame_rate=%d, vi_frames_per_gop=%d, " - "vi_bframes_count=%d, vi_pesid=%c\n", s, - p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video, - p->ts_pid_pcr, p->ps_size, p->au_sample_rate, - p->au_pesid, p->vi_frame_rate, - p->vi_frames_per_gop, p->vi_bframes_count, - p->vi_pesid); - break; - } - case VIDIOC_ENUMOUTPUT: - { - struct v4l2_output *p=arg; - printk ("%s: index=%d, name=%s,type=%d, audioset=%d, " - "modulator=%d, std=%Ld\n", - s,p->index,p->name,p->type,p->audioset, - p->modulator, - (unsigned long long)p->std); - break; - } - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *p=arg; - printk ("%s: id=%d, type=%d, name=%s, min/max=%d/%d," - " step=%d, default=%d, flags=0x%08x\n", s, - p->id,p->type,p->name,p->minimum,p->maximum, - p->step,p->default_value,p->flags); - break; - } - case VIDIOC_QUERYMENU: - { - struct v4l2_querymenu *p=arg; - printk ("%s: id=%d, index=%d, name=%s\n", s, - p->id,p->index,p->name); - break; - } - case VIDIOC_INT_G_REGISTER: - case VIDIOC_INT_S_REGISTER: - { - struct v4l2_register *p=arg; - printk ("%s: i2c_id=%d, reg=%lu, val=%d\n", s, - p->i2c_id,p->reg,p->val); - - break; - } - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *p=arg; - printk ("%s: count=%d, type=%s, memory=%s\n", s, - p->count, - prt_names(p->type,v4l2_type_names), - prt_names(p->memory,v4l2_memory_names)); - break; - } - case VIDIOC_INT_S_AUDIO_ROUTING: - case VIDIOC_INT_S_VIDEO_ROUTING: - case VIDIOC_INT_G_AUDIO_ROUTING: - case VIDIOC_INT_G_VIDEO_ROUTING: - { - struct v4l2_routing *p=arg; - printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output); - break; - } - case VIDIOC_G_SLICED_VBI_CAP: - { - struct v4l2_sliced_vbi_cap *p=arg; - printk ("%s: service_set=%d\n", s, - p->service_set); - break; - } - case VIDIOC_INT_S_VBI_DATA: - case VIDIOC_INT_G_VBI_DATA: - { - struct v4l2_sliced_vbi_data *p=arg; - printk ("%s: id=%d, field=%d, line=%d\n", s, - p->id, p->field, p->line); - break; - } - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *p=arg; - printk ("%s: index=%d, id=%Ld, name=%s, fps=%d/%d, " - "framelines=%d\n", s, p->index, - (unsigned long long)p->id, p->name, - p->frameperiod.numerator, - p->frameperiod.denominator, - p->framelines); - - break; - } - case VIDIOC_G_PARM: - case VIDIOC_S_PARM: - case VIDIOC_S_PARM_OLD: - { - struct v4l2_streamparm *p=arg; - printk ("%s: type=%d\n", s, p->type); - - break; - } - case VIDIOC_G_TUNER: - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *p=arg; - printk ("%s: index=%d, name=%s, type=%d, capability=%d, " - "rangelow=%d, rangehigh=%d, signal=%d, afc=%d, " - "rxsubchans=%d, audmode=%d\n", s, - p->index, p->name, p->type, - p->capability, p->rangelow,p->rangehigh, - p->rxsubchans, p->audmode, p->signal, - p->afc); - break; - } - case VIDIOCGVBIFMT: - case VIDIOCSVBIFMT: - { - struct vbi_format *p=arg; - printk ("%s: sampling_rate=%d, samples_per_line=%d, " - "sample_format=%d, start=%d/%d, count=%d/%d, flags=%d\n", s, - p->sampling_rate,p->samples_per_line, - p->sample_format,p->start[0],p->start[1], - p->count[0],p->count[1],p->flags); - break; - } - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - { - struct video_audio *p=arg; - printk ("%s: audio=%d, volume=%d, bass=%d, treble=%d, " - "flags=%d, name=%s, mode=%d, balance=%d, step=%d\n", - s,p->audio,p->volume,p->bass, p->treble, - p->flags,p->name,p->mode,p->balance,p->step); - break; - } - case VIDIOCGFBUF: - case VIDIOCSFBUF: - { - struct video_buffer *p=arg; - printk ("%s: base=%08lx, height=%d, width=%d, depth=%d, " - "bytesperline=%d\n", s, - (unsigned long) p->base, p->height, p->width, - p->depth,p->bytesperline); - break; - } - case VIDIOCGCAP: - { - struct video_capability *p=arg; - printk ("%s: name=%s, type=%d, channels=%d, audios=%d, " - "maxwidth=%d, maxheight=%d, minwidth=%d, minheight=%d\n", - s,p->name,p->type,p->channels,p->audios, - p->maxwidth,p->maxheight,p->minwidth, - p->minheight); - - break; - } - case VIDIOCGCAPTURE: - case VIDIOCSCAPTURE: - { - struct video_capture *p=arg; - printk ("%s: x=%d, y=%d, width=%d, height=%d, decimation=%d," - " flags=%d\n", s, - p->x, p->y,p->width, p->height, - p->decimation,p->flags); - break; - } - case VIDIOCGCHAN: - case VIDIOCSCHAN: - { - struct video_channel *p=arg; - printk ("%s: channel=%d, name=%s, tuners=%d, flags=%d, " - "type=%d, norm=%d\n", s, - p->channel,p->name,p->tuners, - p->flags,p->type,p->norm); - - break; - } - case VIDIOCSMICROCODE: - { - struct video_code *p=arg; - printk ("%s: loadwhat=%s, datasize=%d\n", s, - p->loadwhat,p->datasize); - break; - } - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *p=arg; - printk ("%s: flags=%d, inputs=%d, outputs=%d\n", s, - p->flags,p->inputs,p->outputs); - break; - } - case DECODER_INIT: - { - struct video_decoder_init *p=arg; - printk ("%s: len=%c\n", s, p->len); - break; - } - case VIDIOCGPLAYINFO: - { - struct video_info *p=arg; - printk ("%s: frame_count=%d, h_size=%d, v_size=%d, " - "smpte_timecode=%d, picture_type=%d, " - "temporal_reference=%d, user_data=%s\n", s, - p->frame_count, p->h_size, - p->v_size, p->smpte_timecode, - p->picture_type, p->temporal_reference, - p->user_data); - break; - } - case VIDIOCKEY: - { - struct video_key *p=arg; - printk ("%s: key=%s, flags=%d\n", s, - p->key, p->flags); - break; - } - case VIDIOCGMBUF: - { - struct video_mbuf *p=arg; - printk ("%s: size=%d, frames=%d, offsets=0x%08lx\n", s, - p->size, - p->frames, - (unsigned long)p->offsets); - break; - } - case VIDIOCMCAPTURE: - { - struct video_mmap *p=arg; - printk ("%s: frame=%d, height=%d, width=%d, format=%d\n", s, - p->frame, - p->height, p->width, - p->format); - break; - } - case VIDIOCGPICT: - case VIDIOCSPICT: - case DECODER_SET_PICTURE: - { - struct video_picture *p=arg; - - printk ("%s: brightness=%d, hue=%d, colour=%d, contrast=%d," - " whiteness=%d, depth=%d, palette=%d\n", s, - p->brightness, p->hue, p->colour, - p->contrast, p->whiteness, p->depth, - p->palette); - break; - } - case VIDIOCSPLAYMODE: - { - struct video_play_mode *p=arg; - printk ("%s: mode=%d, p1=%d, p2=%d\n", s, - p->mode,p->p1,p->p2); - break; - } - case VIDIOCGTUNER: - case VIDIOCSTUNER: - { - struct video_tuner *p=arg; - printk ("%s: tuner=%d, name=%s, rangelow=%ld, rangehigh=%ld, " - "flags=%d, mode=%d, signal=%d\n", s, - p->tuner, p->name,p->rangelow, p->rangehigh, - p->flags,p->mode, p->signal); - break; - } - case VIDIOCGUNIT: - { - struct video_unit *p=arg; - printk ("%s: video=%d, vbi=%d, radio=%d, audio=%d, " - "teletext=%d\n", s, - p->video,p->vbi,p->radio,p->audio,p->teletext); - break; - } - case VIDIOCGWIN: - case VIDIOCSWIN: - { - struct video_window *p=arg; - printk ("%s: x=%d, y=%d, width=%d, height=%d, chromakey=%d," - " flags=%d, clipcount=%d\n", s, - p->x, p->y,p->width, p->height, - p->chromakey,p->flags, - p->clipcount); - break; - } - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - case VIDIOC_INT_I2S_CLOCK_FREQ: - case VIDIOC_INT_S_STANDBY: - { - u32 *p=arg; - - printk ("%s: value=%d\n", s, *p); - break; - } - case VIDIOCGFREQ: - case VIDIOCSFREQ: - { - unsigned long *p=arg; - printk ("%s: value=%lu\n", s, *p); - break; - } - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case VIDIOC_QUERYSTD: - { - v4l2_std_id *p=arg; - - printk ("%s: value=%Lu\n", s, (unsigned long long)*p); - break; - } - } -} - /* ----------------------------------------------------------------- */ EXPORT_SYMBOL(v4l2_video_std_construct); @@ -927,7 +376,6 @@ EXPORT_SYMBOL(v4l2_prio_check); EXPORT_SYMBOL(v4l2_field_names); EXPORT_SYMBOL(v4l2_type_names); EXPORT_SYMBOL(v4l_printk_ioctl); -EXPORT_SYMBOL(v4l_printk_ioctl_arg); /* * Local variables: diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c index caf3e7e2f..0a4004a43 100644 --- a/drivers/media/video/video-buf-dvb.c +++ b/drivers/media/video/video-buf-dvb.c @@ -96,7 +96,7 @@ static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed) if (!demux->dmx.frontend) return -EINVAL; - mutex_lock(&dvb->lock); + down(&dvb->lock); dvb->nfeeds++; rc = dvb->nfeeds; @@ -110,7 +110,7 @@ static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed) } out: - mutex_unlock(&dvb->lock); + up(&dvb->lock); return rc; } @@ -120,14 +120,14 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) struct videobuf_dvb *dvb = demux->priv; int err = 0; - mutex_lock(&dvb->lock); + down(&dvb->lock); dvb->nfeeds--; if (0 == dvb->nfeeds && NULL != dvb->thread) { // FIXME: cx8802_cancel_buffers(dev); err = kthread_stop(dvb->thread); dvb->thread = NULL; } - mutex_unlock(&dvb->lock); + up(&dvb->lock); return err; } @@ -139,7 +139,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, { int result; - mutex_init(&dvb->lock); + init_MUTEX(&dvb->lock); /* register adapter */ result = dvb_register_adapter(&dvb->adapter, dvb->name, module); diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index acc5ea936..9ef477523 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c @@ -1,20 +1,15 @@ /* * * generic helper functions for video4linux capture buffers, to handle - * memory management and PCI DMA. - * Right now, bttv, saa7134, saa7146 and cx88 use it. + * memory management and PCI DMA. Right now bttv + saa7134 use it. * * The functions expect the hardware being able to scatter gatter * (i.e. the buffers are not linear in physical memory, but fragmented * into PAGE_SIZE chunks). They also assume the driver does not need - * to touch the video data. - * - * device specific map/unmap/sync stuff now are mapped as operations - * to allow its usage by USB and virtual devices. + * to touch the video data (thus it is probably not useful for USB 1.1 + * as data often must be uncompressed by the drivers). * * (c) 2001-2004 Gerd Knorr [SUSE Labs] - * (c) 2006 Mauro Carvalho Chehab - * (c) 2006 Ted Walther and John Sokol * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,7 +59,8 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages) pg = vmalloc_to_page(virt); if (NULL == pg) goto err; - BUG_ON(PageHighMem(pg)); + if (PageHighMem(pg)) + BUG(); sglist[i].page = pg; sglist[i].length = PAGE_SIZE; } @@ -172,9 +168,6 @@ int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, dprintk(1,"vmalloc_32(%d pages) failed\n",nr_pages); return -ENOMEM; } - dprintk(1,"vmalloc is at addr 0x%08lx, size=%d\n", - (unsigned long)dma->vmalloc, - nr_pages << PAGE_SHIFT); memset(dma->vmalloc,0,nr_pages << PAGE_SHIFT); dma->nr_pages = nr_pages; return 0; @@ -194,10 +187,8 @@ int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction, return 0; } -int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma) +int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma) { - void *dev=q->dev; - MAGIC_CHECK(dma->magic,MAGIC_DMABUF); BUG_ON(0 == dma->nr_pages); @@ -207,7 +198,7 @@ int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma) } if (dma->vmalloc) { dma->sglist = videobuf_vmalloc_to_sg - (dma->vmalloc,dma->nr_pages); + (dma->vmalloc,dma->nr_pages); } if (dma->bus_addr) { dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL); @@ -222,14 +213,13 @@ int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma) dprintk(1,"scatterlist is NULL\n"); return -ENOMEM; } + if (!dma->bus_addr) { - if (q->ops->vb_map_sg) { - dma->sglen = q->ops->vb_map_sg(dev,dma->sglist, - dma->nr_pages, dma->direction); - } + dma->sglen = pci_map_sg(dev,dma->sglist,dma->nr_pages, + dma->direction); if (0 == dma->sglen) { printk(KERN_WARNING - "%s: videobuf_map_sg failed\n",__FUNCTION__); + "%s: pci_map_sg failed\n",__FUNCTION__); kfree(dma->sglist); dma->sglist = NULL; dma->sglen = 0; @@ -239,31 +229,24 @@ int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma) return 0; } -int videobuf_dma_sync(struct videobuf_queue* q,struct videobuf_dmabuf *dma) +int videobuf_dma_pci_sync(struct pci_dev *dev, struct videobuf_dmabuf *dma) { - void *dev=q->dev; - MAGIC_CHECK(dma->magic,MAGIC_DMABUF); BUG_ON(!dma->sglen); - if (!dma->bus_addr && q->ops->vb_dma_sync_sg) - q->ops->vb_dma_sync_sg(dev,dma->sglist,dma->nr_pages, - dma->direction); - + if (!dma->bus_addr) + pci_dma_sync_sg_for_cpu(dev,dma->sglist,dma->nr_pages,dma->direction); return 0; } -int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma) +int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma) { - void *dev=q->dev; - MAGIC_CHECK(dma->magic,MAGIC_DMABUF); if (!dma->sglen) return 0; - if (!dma->bus_addr && q->ops->vb_unmap_sg) - q->ops->vb_unmap_sg(dev,dma->sglist,dma->nr_pages, - dma->direction); + if (!dma->bus_addr) + pci_unmap_sg(dev,dma->sglist,dma->nr_pages,dma->direction); kfree(dma->sglist); dma->sglist = NULL; dma->sglen = 0; @@ -336,7 +319,7 @@ int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) } int -videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb, +videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb, struct v4l2_framebuffer *fbuf) { int err,pages; @@ -375,7 +358,7 @@ videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb, default: BUG(); } - err = videobuf_dma_map(q,&vb->dma); + err = videobuf_dma_pci_map(pci,&vb->dma); if (0 != err) return err; @@ -384,47 +367,9 @@ videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb, /* --------------------------------------------------------------------- */ -void videobuf_queue_pci(struct videobuf_queue* q) -{ - /* If not specified, defaults to PCI map sg */ - if (!q->ops->vb_map_sg) - q->ops->vb_map_sg=(vb_map_sg_t *)pci_map_sg; - - if (!q->ops->vb_dma_sync_sg) - q->ops->vb_dma_sync_sg=(vb_map_sg_t *)pci_dma_sync_sg_for_cpu; - if (!q->ops->vb_unmap_sg) - q->ops->vb_unmap_sg=(vb_map_sg_t *)pci_unmap_sg; -} - -int videobuf_pci_dma_map(struct pci_dev *pci,struct videobuf_dmabuf *dma) -{ - struct videobuf_queue q; - struct videobuf_queue_ops qops; - - q.dev=pci; - qops.vb_map_sg=(vb_map_sg_t *)pci_map_sg; - qops.vb_unmap_sg=(vb_map_sg_t *)pci_unmap_sg; - q.ops = &qops; - - return (videobuf_dma_map(&q,dma)); -} - -int videobuf_pci_dma_unmap(struct pci_dev *pci,struct videobuf_dmabuf *dma) -{ - struct videobuf_queue q; - struct videobuf_queue_ops qops; - - q.dev=pci; - qops.vb_map_sg=(vb_map_sg_t *)pci_map_sg; - qops.vb_unmap_sg=(vb_map_sg_t *)pci_unmap_sg; - q.ops = &qops; - - return (videobuf_dma_unmap(&q,dma)); -} - void videobuf_queue_init(struct videobuf_queue* q, struct videobuf_queue_ops *ops, - void *dev, + struct pci_dev *pci, spinlock_t *irqlock, enum v4l2_buf_type type, enum v4l2_field field, @@ -433,16 +378,14 @@ void videobuf_queue_init(struct videobuf_queue* q, { memset(q,0,sizeof(*q)); q->irqlock = irqlock; - q->dev = dev; + q->pci = pci; q->type = type; q->field = field; q->msize = msize; q->ops = ops; q->priv_data = priv; - videobuf_queue_pci(q); - - mutex_init(&q->lock); + init_MUTEX(&q->lock); INIT_LIST_HEAD(&q->stream); } @@ -485,12 +428,11 @@ videobuf_queue_is_busy(struct videobuf_queue *q) void videobuf_queue_cancel(struct videobuf_queue *q) { - unsigned long flags=0; + unsigned long flags; int i; /* remove queued buffers from list */ - if (q->irqlock) - spin_lock_irqsave(q->irqlock,flags); + spin_lock_irqsave(q->irqlock,flags); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -499,8 +441,7 @@ videobuf_queue_cancel(struct videobuf_queue *q) q->bufs[i]->state = STATE_ERROR; } } - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock,flags); + spin_unlock_irqrestore(q->irqlock,flags); /* free all buffers + clear queue */ for (i = 0; i < VIDEO_MAX_FRAME; i++) { @@ -594,31 +535,21 @@ videobuf_reqbufs(struct videobuf_queue *q, unsigned int size,count; int retval; - if (req->type != q->type) { - dprintk(1,"reqbufs: queue type invalid\n"); + if (req->type != q->type) return -EINVAL; - } - if (req->count < 1) { - dprintk(1,"reqbufs: count invalid (%d)\n",req->count); + if (req->count < 1) return -EINVAL; - } if (req->memory != V4L2_MEMORY_MMAP && req->memory != V4L2_MEMORY_USERPTR && - req->memory != V4L2_MEMORY_OVERLAY) { - dprintk(1,"reqbufs: memory type invalid\n"); + req->memory != V4L2_MEMORY_OVERLAY) return -EINVAL; - } - if (q->streaming) { - dprintk(1,"reqbufs: streaming already exists\n"); + if (q->streaming) return -EBUSY; - } - if (!list_empty(&q->stream)) { - dprintk(1,"reqbufs: stream running\n"); + if (!list_empty(&q->stream)) return -EBUSY; - } - mutex_lock(&q->lock); + down(&q->lock); count = req->count; if (count > VIDEO_MAX_FRAME) count = VIDEO_MAX_FRAME; @@ -629,33 +560,25 @@ videobuf_reqbufs(struct videobuf_queue *q, count, size, (count*size)>>PAGE_SHIFT); retval = videobuf_mmap_setup(q,count,size,req->memory); - if (retval < 0) { - dprintk(1,"reqbufs: mmap setup returned %d\n",retval); + if (retval < 0) goto done; - } req->count = count; done: - mutex_unlock(&q->lock); + up(&q->lock); return retval; } int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) { - if (unlikely(b->type != q->type)) { - dprintk(1,"querybuf: Wrong type.\n"); + if (unlikely(b->type != q->type)) return -EINVAL; - } - if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) { - dprintk(1,"querybuf: index out of range.\n"); + if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) return -EINVAL; - } - if (unlikely(NULL == q->bufs[b->index])) { - dprintk(1,"querybuf: buffer is null.\n"); + if (unlikely(NULL == q->bufs[b->index])) return -EINVAL; - } videobuf_status(b,q->bufs[b->index],q->type); return 0; } @@ -666,45 +589,31 @@ videobuf_qbuf(struct videobuf_queue *q, { struct videobuf_buffer *buf; enum v4l2_field field; - unsigned long flags=0; + unsigned long flags; int retval; - mutex_lock(&q->lock); + down(&q->lock); retval = -EBUSY; - if (q->reading) { - dprintk(1,"qbuf: Reading running...\n"); + if (q->reading) goto done; - } retval = -EINVAL; - if (b->type != q->type) { - dprintk(1,"qbuf: Wrong type.\n"); + if (b->type != q->type) goto done; - } - if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) { - dprintk(1,"qbuf: index out of range.\n"); + if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) goto done; - } buf = q->bufs[b->index]; - if (NULL == buf) { - dprintk(1,"qbuf: buffer is null.\n"); + if (NULL == buf) goto done; - } MAGIC_CHECK(buf->magic,MAGIC_BUFFER); - if (buf->memory != b->memory) { - dprintk(1,"qbuf: memory type is wrong.\n"); + if (buf->memory != b->memory) goto done; - } if (buf->state == STATE_QUEUED || - buf->state == STATE_ACTIVE) { - dprintk(1,"qbuf: buffer is already queued or active.\n"); + buf->state == STATE_ACTIVE) goto done; - } if (b->flags & V4L2_BUF_FLAG_INPUT) { - if (b->input >= q->inputs) { - dprintk(1,"qbuf: wrong input.\n"); + if (b->input >= q->inputs) goto done; - } buf->input = b->input; } else { buf->input = UNSET; @@ -712,16 +621,12 @@ videobuf_qbuf(struct videobuf_queue *q, switch (b->memory) { case V4L2_MEMORY_MMAP: - if (0 == buf->baddr) { - dprintk(1,"qbuf: mmap requested but buffer addr is zero!\n"); + if (0 == buf->baddr) goto done; - } break; case V4L2_MEMORY_USERPTR: - if (b->length < buf->bsize) { - dprintk(1,"qbuf: buffer length is not enough\n"); + if (b->length < buf->bsize) goto done; - } if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr) q->ops->buf_release(q,buf); buf->baddr = b->m.userptr; @@ -730,31 +635,24 @@ videobuf_qbuf(struct videobuf_queue *q, buf->boff = b->m.offset; break; default: - dprintk(1,"qbuf: wrong memory type\n"); goto done; } - dprintk(1,"qbuf: requesting next field\n"); field = videobuf_next_field(q); retval = q->ops->buf_prepare(q,buf,field); - if (0 != retval) { - dprintk(1,"qbuf: buffer_prepare returned %d\n",retval); + if (0 != retval) goto done; - } list_add_tail(&buf->stream,&q->stream); if (q->streaming) { - if (q->irqlock) - spin_lock_irqsave(q->irqlock,flags); + spin_lock_irqsave(q->irqlock,flags); q->ops->buf_queue(q,buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock,flags); + spin_unlock_irqrestore(q->irqlock,flags); } - dprintk(1,"qbuf: succeded\n"); retval = 0; done: - mutex_unlock(&q->lock); + up(&q->lock); return retval; } @@ -765,41 +663,28 @@ videobuf_dqbuf(struct videobuf_queue *q, struct videobuf_buffer *buf; int retval; - mutex_lock(&q->lock); + down(&q->lock); retval = -EBUSY; - if (q->reading) { - dprintk(1,"dqbuf: Reading running...\n"); + if (q->reading) goto done; - } retval = -EINVAL; - if (b->type != q->type) { - dprintk(1,"dqbuf: Wrong type.\n"); + if (b->type != q->type) goto done; - } - if (list_empty(&q->stream)) { - dprintk(1,"dqbuf: stream running\n"); + if (list_empty(&q->stream)) goto done; - } buf = list_entry(q->stream.next, struct videobuf_buffer, stream); retval = videobuf_waiton(buf, nonblocking, 1); - if (retval < 0) { - dprintk(1,"dqbuf: waiton returned %d\n",retval); + if (retval < 0) goto done; - } switch (buf->state) { case STATE_ERROR: - dprintk(1,"dqbuf: state is error\n"); retval = -EIO; - videobuf_dma_sync(q,&buf->dma); - buf->state = STATE_IDLE; - break; + /* fall through */ case STATE_DONE: - dprintk(1,"dqbuf: state is done\n"); - videobuf_dma_sync(q,&buf->dma); + videobuf_dma_pci_sync(q->pci,&buf->dma); buf->state = STATE_IDLE; break; default: - dprintk(1,"dqbuf: state invalid\n"); retval = -EINVAL; goto done; } @@ -808,7 +693,7 @@ videobuf_dqbuf(struct videobuf_queue *q, videobuf_status(b,buf,q->type); done: - mutex_unlock(&q->lock); + up(&q->lock); return retval; } @@ -816,10 +701,10 @@ int videobuf_streamon(struct videobuf_queue *q) { struct videobuf_buffer *buf; struct list_head *list; - unsigned long flags=0; + unsigned long flags; int retval; - mutex_lock(&q->lock); + down(&q->lock); retval = -EBUSY; if (q->reading) goto done; @@ -827,18 +712,16 @@ int videobuf_streamon(struct videobuf_queue *q) if (q->streaming) goto done; q->streaming = 1; - if (q->irqlock) - spin_lock_irqsave(q->irqlock,flags); + spin_lock_irqsave(q->irqlock,flags); list_for_each(list,&q->stream) { buf = list_entry(list, struct videobuf_buffer, stream); if (buf->state == STATE_PREPARED) q->ops->buf_queue(q,buf); } - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock,flags); + spin_unlock_irqrestore(q->irqlock,flags); done: - mutex_unlock(&q->lock); + up(&q->lock); return retval; } @@ -846,7 +729,7 @@ int videobuf_streamoff(struct videobuf_queue *q) { int retval = -EINVAL; - mutex_lock(&q->lock); + down(&q->lock); if (!q->streaming) goto done; videobuf_queue_cancel(q); @@ -854,7 +737,7 @@ int videobuf_streamoff(struct videobuf_queue *q) retval = 0; done: - mutex_unlock(&q->lock); + up(&q->lock); return retval; } @@ -863,7 +746,7 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos) { enum v4l2_field field; - unsigned long flags=0; + unsigned long flags; int retval; /* setup stuff */ @@ -880,14 +763,12 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data, goto done; /* start capture & wait */ - if (q->irqlock) - spin_lock_irqsave(q->irqlock,flags); + spin_lock_irqsave(q->irqlock,flags); q->ops->buf_queue(q,q->read_buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock,flags); + spin_unlock_irqrestore(q->irqlock,flags); retval = videobuf_waiton(q->read_buf,0,0); if (0 == retval) { - videobuf_dma_sync(q,&q->read_buf->dma); + videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); if (STATE_ERROR == q->read_buf->state) retval = -EIO; else @@ -907,11 +788,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, int nonblocking) { enum v4l2_field field; - unsigned long flags=0; + unsigned long flags; unsigned size, nbufs, bytes; int retval; - mutex_lock(&q->lock); + down(&q->lock); nbufs = 1; size = 0; q->ops->buf_setup(q,&nbufs,&size); @@ -929,7 +810,6 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, /* need to capture a new frame */ retval = -ENOMEM; q->read_buf = videobuf_alloc(q->msize); - dprintk(1,"video alloc=0x%p\n", q->read_buf); if (NULL == q->read_buf) goto done; q->read_buf->memory = V4L2_MEMORY_USERPTR; @@ -941,11 +821,9 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, q->read_buf = NULL; goto done; } - if (q->irqlock) - spin_lock_irqsave(q->irqlock,flags); + spin_lock_irqsave(q->irqlock,flags); q->ops->buf_queue(q,q->read_buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock,flags); + spin_unlock_irqrestore(q->irqlock,flags); q->read_off = 0; } @@ -953,7 +831,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, retval = videobuf_waiton(q->read_buf, nonblocking, 1); if (0 != retval) goto done; - videobuf_dma_sync(q,&q->read_buf->dma); + videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); if (STATE_ERROR == q->read_buf->state) { /* catch I/O errors */ @@ -982,14 +860,14 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, } done: - mutex_unlock(&q->lock); + up(&q->lock); return retval; } int videobuf_read_start(struct videobuf_queue *q) { enum v4l2_field field; - unsigned long flags=0; + unsigned long flags; int count = 0, size = 0; int err, i; @@ -1010,12 +888,10 @@ int videobuf_read_start(struct videobuf_queue *q) return err; list_add_tail(&q->bufs[i]->stream, &q->stream); } - if (q->irqlock) - spin_lock_irqsave(q->irqlock,flags); + spin_lock_irqsave(q->irqlock,flags); for (i = 0; i < count; i++) q->ops->buf_queue(q,q->bufs[i]); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock,flags); + spin_unlock_irqrestore(q->irqlock,flags); q->reading = 1; return 0; } @@ -1043,10 +919,10 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, { unsigned int *fc, bytes; int err, retval; - unsigned long flags=0; + unsigned long flags; dprintk(2,"%s\n",__FUNCTION__); - mutex_lock(&q->lock); + down(&q->lock); retval = -EBUSY; if (q->streaming) goto done; @@ -1110,11 +986,9 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, if (q->read_off == q->read_buf->size) { list_add_tail(&q->read_buf->stream, &q->stream); - if (q->irqlock) - spin_lock_irqsave(q->irqlock,flags); + spin_lock_irqsave(q->irqlock,flags); q->ops->buf_queue(q,q->read_buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock,flags); + spin_unlock_irqrestore(q->irqlock,flags); q->read_buf = NULL; } if (retval < 0) @@ -1122,7 +996,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, } done: - mutex_unlock(&q->lock); + up(&q->lock); return retval; } @@ -1133,7 +1007,7 @@ unsigned int videobuf_poll_stream(struct file *file, struct videobuf_buffer *buf = NULL; unsigned int rc = 0; - mutex_lock(&q->lock); + down(&q->lock); if (q->streaming) { if (!list_empty(&q->stream)) buf = list_entry(q->stream.next, @@ -1161,7 +1035,7 @@ unsigned int videobuf_poll_stream(struct file *file, buf->state == STATE_ERROR) rc = POLLIN|POLLRDNORM; } - mutex_unlock(&q->lock); + up(&q->lock); return rc; } @@ -1190,7 +1064,7 @@ videobuf_vm_close(struct vm_area_struct *vma) map->count--; if (0 == map->count) { dprintk(1,"munmap %p q=%p\n",map,q); - mutex_lock(&q->lock); + down(&q->lock); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -1202,7 +1076,7 @@ videobuf_vm_close(struct vm_area_struct *vma) q->bufs[i]->baddr = 0; q->ops->buf_release(q,q->bufs[i]); } - mutex_unlock(&q->lock); + up(&q->lock); kfree(map); } return; @@ -1296,7 +1170,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, unsigned int first,last,size,i; int retval; - mutex_lock(&q->lock); + down(&q->lock); retval = -EINVAL; if (!(vma->vm_flags & VM_WRITE)) { dprintk(1,"mmap app bug: PROT_WRITE please\n"); @@ -1364,7 +1238,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, retval = 0; done: - mutex_unlock(&q->lock); + up(&q->lock); return retval; } @@ -1376,14 +1250,11 @@ EXPORT_SYMBOL_GPL(videobuf_dma_init); EXPORT_SYMBOL_GPL(videobuf_dma_init_user); EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel); EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay); -EXPORT_SYMBOL_GPL(videobuf_dma_map); -EXPORT_SYMBOL_GPL(videobuf_dma_sync); -EXPORT_SYMBOL_GPL(videobuf_dma_unmap); +EXPORT_SYMBOL_GPL(videobuf_dma_pci_map); +EXPORT_SYMBOL_GPL(videobuf_dma_pci_sync); +EXPORT_SYMBOL_GPL(videobuf_dma_pci_unmap); EXPORT_SYMBOL_GPL(videobuf_dma_free); -EXPORT_SYMBOL_GPL(videobuf_pci_dma_map); -EXPORT_SYMBOL_GPL(videobuf_pci_dma_unmap); - EXPORT_SYMBOL_GPL(videobuf_alloc); EXPORT_SYMBOL_GPL(videobuf_waiton); EXPORT_SYMBOL_GPL(videobuf_iolock); diff --git a/drivers/media/video/videocodec.h b/drivers/media/video/videocodec.h index 8c233720b..b1239ac7f 100644 --- a/drivers/media/video/videocodec.h +++ b/drivers/media/video/videocodec.h @@ -57,7 +57,7 @@ therfor they may not be initialized. The other fuctions are just for convenience, as they are for sure used by - most/all of the codecs. The last ones may be ommited, too. + most/all of the codecs. The last ones may be ommited, too. See the structure declaration below for more information and which data has to be set up for the master and the slave. @@ -75,52 +75,52 @@ /* ========================================== */ /* - ==== master setup ==== + ==== master setup ==== name -> name of the device structure for reference and debugging master_data -> data ref. for the master (e.g. the zr36055,57,67) readreg -> ref. to read-fn from register (setup by master, used by slave) writereg -> ref. to write-fn to register (setup by master, used by slave) - this two functions do the lowlevel I/O job + this two functions do the lowlevel I/O job - ==== slave functionality setup ==== - slave_data -> data ref. for the slave (e.g. the zr36050,60) + ==== slave functionality setup ==== + slave_data -> data ref. for the slave (e.g. the zr36050,60) check -> fn-ref. checks availability of an device, returns -EIO on failure or - the type on success - this makes espcecially sense if a driver module supports more than - one codec which may be quite similar to access, nevertheless it - is good for a first functionality check + the type on success + this makes espcecially sense if a driver module supports more than + one codec which may be quite similar to access, nevertheless it + is good for a first functionality check - -- main functions you always need for compression/decompression -- + -- main functions you always need for compression/decompression -- set_mode -> this fn-ref. resets the entire codec, and sets up the mode - with the last defined norm/size (or device default if not - available) - it returns 0 if the mode is possible + with the last defined norm/size (or device default if not + available) - it returns 0 if the mode is possible set_size -> this fn-ref. sets the norm and image size for - compression/decompression (returns 0 on success) - the norm param is defined in videodev.h (VIDEO_MODE_*) + compression/decompression (returns 0 on success) + the norm param is defined in videodev.h (VIDEO_MODE_*) additional setup may be available, too - but the codec should work with - some default values even without this + some default values even without this - set_data -> sets device-specific data (tables, quality etc.) - get_data -> query device-specific data (tables, quality etc.) + set_data -> sets device-specific data (tables, quality etc.) + get_data -> query device-specific data (tables, quality etc.) - if the device delivers interrupts, they may be setup/handled here - setup_interrupt -> codec irq setup (not needed for 36050/60) - handle_interrupt -> codec irq handling (not needed for 36050/60) + if the device delivers interrupts, they may be setup/handled here + setup_interrupt -> codec irq setup (not needed for 36050/60) + handle_interrupt -> codec irq handling (not needed for 36050/60) - if the device delivers pictures, they may be handled here - put_image -> puts image data to the codec (not needed for 36050/60) - get_image -> gets image data from the codec (not needed for 36050/60) - the calls include frame numbers and flags (even/odd/...) - if needed and a flag which allows blocking until its ready + if the device delivers pictures, they may be handled here + put_image -> puts image data to the codec (not needed for 36050/60) + get_image -> gets image data from the codec (not needed for 36050/60) + the calls include frame numbers and flags (even/odd/...) + if needed and a flag which allows blocking until its ready */ /* ============== */ /* user interface */ /* ============== */ -/* +/* Currently there is only a information display planned, as the layer is not visible for the user space at all. diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 5f87dd5f1..078880e4c 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -97,7 +97,7 @@ static int video_open(struct inode *inode, struct file *file) unsigned int minor = iminor(inode); int err = 0; struct video_device *vfl; - const struct file_operations *old_fops; + struct file_operations *old_fops; if(minor>=VIDEO_NUM_DEVICES) return -ENODEV; @@ -224,13 +224,13 @@ int video_exclusive_open(struct inode *inode, struct file *file) struct video_device *vfl = video_devdata(file); int retval = 0; - mutex_lock(&vfl->lock); + down(&vfl->lock); if (vfl->users) { retval = -EBUSY; } else { vfl->users++; } - mutex_unlock(&vfl->lock); + up(&vfl->lock); return retval; } @@ -279,23 +279,23 @@ int video_register_device(struct video_device *vfd, int type, int nr) switch(type) { case VFL_TYPE_GRABBER: - base=MINOR_VFL_TYPE_GRABBER_MIN; - end=MINOR_VFL_TYPE_GRABBER_MAX+1; + base=0; + end=64; name_base = "video"; break; case VFL_TYPE_VTX: - base=MINOR_VFL_TYPE_VTX_MIN; - end=MINOR_VFL_TYPE_VTX_MAX+1; + base=192; + end=224; name_base = "vtx"; break; case VFL_TYPE_VBI: - base=MINOR_VFL_TYPE_VBI_MIN; - end=MINOR_VFL_TYPE_VBI_MAX+1; + base=224; + end=256; name_base = "vbi"; break; case VFL_TYPE_RADIO: - base=MINOR_VFL_TYPE_RADIO_MIN; - end=MINOR_VFL_TYPE_RADIO_MAX+1; + base=64; + end=128; name_base = "radio"; break; default: @@ -328,7 +328,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base); devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor), S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name); - mutex_init(&vfd->lock); + init_MUTEX(&vfd->lock); /* sysfs class */ memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index a8c101494..c8fd82389 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -246,7 +245,7 @@ struct vino_framebuffer_queue { struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX]; spinlock_t queue_lock; - struct mutex queue_mutex; + struct semaphore queue_sem; wait_queue_head_t frame_wait_queue; }; @@ -284,7 +283,7 @@ struct vino_channel_settings { /* the driver is currently processing the queue */ int capturing; - struct mutex mutex; + struct semaphore sem; spinlock_t capture_lock; unsigned int users; @@ -1132,11 +1131,11 @@ static void vino_queue_free(struct vino_framebuffer_queue *q) if (q->type != VINO_MEMORY_MMAP) return; - mutex_lock(&q->queue_mutex); + down(&q->queue_sem); vino_queue_free_with_count(q, q->length); - mutex_unlock(&q->queue_mutex); + up(&q->queue_sem); } static int vino_queue_init(struct vino_framebuffer_queue *q, @@ -1160,7 +1159,7 @@ static int vino_queue_init(struct vino_framebuffer_queue *q, if (*length < 1) return -EINVAL; - mutex_lock(&q->queue_mutex); + down(&q->queue_sem); if (*length > VINO_FRAMEBUFFER_COUNT_MAX) *length = VINO_FRAMEBUFFER_COUNT_MAX; @@ -1212,7 +1211,7 @@ static int vino_queue_init(struct vino_framebuffer_queue *q, q->magic = VINO_QUEUE_MAGIC; } - mutex_unlock(&q->queue_mutex); + up(&q->queue_sem); return ret; } @@ -1555,12 +1554,12 @@ static void vino_update_line_size(struct vino_channel_settings *vcs) unsigned int w = vcs->clipping.right - vcs->clipping.left; unsigned int d = vcs->decimation; unsigned int bpp = vino_data_formats[vcs->data_format].bpp; - unsigned int lsize; + unsigned int lsize; dprintk("update_line_size(): before: w = %d, d = %d, " "line_size = %d\n", w, d, vcs->line_size); - /* line size must be multiple of 8 bytes */ + /* line size must be multiple of 8 bytes */ lsize = (bpp * (w / d)) & ~7; w = (lsize / bpp) * d; @@ -4046,7 +4045,7 @@ static int vino_open(struct inode *inode, struct file *file) dprintk("open(): channel = %c\n", (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B'); - mutex_lock(&vcs->mutex); + down(&vcs->sem); if (vcs->users) { dprintk("open(): driver busy\n"); @@ -4063,7 +4062,7 @@ static int vino_open(struct inode *inode, struct file *file) vcs->users++; out: - mutex_unlock(&vcs->mutex); + up(&vcs->sem); dprintk("open(): %s!\n", ret ? "failed" : "complete"); @@ -4076,7 +4075,7 @@ static int vino_close(struct inode *inode, struct file *file) struct vino_channel_settings *vcs = video_get_drvdata(dev); dprintk("close():\n"); - mutex_lock(&vcs->mutex); + down(&vcs->sem); vcs->users--; @@ -4088,7 +4087,7 @@ static int vino_close(struct inode *inode, struct file *file) vino_queue_free(&vcs->fb_queue); } - mutex_unlock(&vcs->mutex); + up(&vcs->sem); return 0; } @@ -4131,7 +4130,7 @@ static int vino_mmap(struct file *file, struct vm_area_struct *vma) // TODO: reject mmap if already mapped - if (mutex_lock_interruptible(&vcs->mutex)) + if (down_interruptible(&vcs->sem)) return -EINTR; if (vcs->reading) { @@ -4215,7 +4214,7 @@ found: vma->vm_ops = &vino_vm_ops; out: - mutex_unlock(&vcs->mutex); + up(&vcs->sem); return ret; } @@ -4375,12 +4374,12 @@ static int vino_ioctl(struct inode *inode, struct file *file, struct vino_channel_settings *vcs = video_get_drvdata(dev); int ret; - if (mutex_lock_interruptible(&vcs->mutex)) + if (down_interruptible(&vcs->sem)) return -EINTR; ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl); - mutex_unlock(&vcs->mutex); + up(&vcs->sem); return ret; } @@ -4565,10 +4564,10 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs, vcs->capturing = 0; - mutex_init(&vcs->mutex); + init_MUTEX(&vcs->sem); spin_lock_init(&vcs->capture_lock); - mutex_init(&vcs->fb_queue.queue_mutex); + init_MUTEX(&vcs->fb_queue.queue_sem); spin_lock_init(&vcs->fb_queue.queue_lock); init_waitqueue_head(&vcs->fb_queue.frame_wait_queue); diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c deleted file mode 100644 index 779db2677..000000000 --- a/drivers/media/video/vivi.c +++ /dev/null @@ -1,1459 +0,0 @@ -/* - * Virtual Video driver - This code emulates a real video device with v4l2 api - * - * Copyright (c) 2006 by: - * Mauro Carvalho Chehab - * Ted Walther - * John Sokol - * http://v4l.videotechnology.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the BSD Licence, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_VIDEO_V4L1_COMPAT -/* Include V4L1 specific functions. Should be removed soon */ -#include -#endif -#include -#include -#include -#include -#include - -/* Wake up at about 30 fps */ -#define WAKE_NUMERATOR 30 -#define WAKE_DENOMINATOR 1001 -#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ - -/* These timers are for 1 fps - used only for testing */ -//#define WAKE_DENOMINATOR 30 /* hack for testing purposes */ -//#define BUFFER_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */ - -#include "font.h" - -#ifndef kzalloc -#define kzalloc(size, flags) \ -({ \ - void *__ret = kmalloc(size, flags); \ - if (__ret) \ - memset(__ret, 0, size); \ - __ret; \ -}) -#endif - -MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); -MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); -MODULE_LICENSE("Dual BSD/GPL"); - -#define VIVI_MAJOR_VERSION 0 -#define VIVI_MINOR_VERSION 4 -#define VIVI_RELEASE 0 -#define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) - -static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ -module_param(video_nr, int, 0); - -static int debug = 0; -module_param(debug, int, 0); - -static unsigned int vid_limit = 16; -module_param(vid_limit,int,0644); -MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); - -/* supported controls */ -static struct v4l2_queryctrl vivi_qctrl[] = { - { - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 65535, - .flags = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 127, - .flags = 0, - }, { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 0x1, - .default_value = 0x10, - .flags = 0, - }, { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 0x1, - .default_value = 127, - .flags = 0, - }, { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = -128, - .maximum = 127, - .step = 0x1, - .default_value = 0, - .flags = 0, - } -}; - -static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; - -#define dprintk(level,fmt, arg...) \ - do { \ - if (debug >= (level)) \ - printk(KERN_DEBUG "vivi: " fmt , ## arg); \ - } while (0) - -/* ------------------------------------------------------------------ - Basic structures - ------------------------------------------------------------------*/ - -struct vivi_fmt { - char *name; - u32 fourcc; /* v4l2 format id */ - int depth; -}; - -static struct vivi_fmt format = { - .name = "4:2:2, packed, YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, -}; - -struct sg_to_addr { - int pos; - struct scatterlist *sg; -}; - -/* buffer for one video frame */ -struct vivi_buffer { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - struct vivi_fmt *fmt; - - struct sg_to_addr *to_addr; -}; - -struct vivi_dmaqueue { - struct list_head active; - struct list_head queued; - struct timer_list timeout; - - /* thread for generating video stream*/ - struct task_struct *kthread; - wait_queue_head_t wq; - /* Counters to control fps rate */ - int frame; - int ini_jiffies; -}; - -static LIST_HEAD(vivi_devlist); - -struct vivi_dev { - struct list_head vivi_devlist; - - struct semaphore lock; - - int users; - - /* various device info */ - unsigned int resources; - struct video_device video_dev; - - struct vivi_dmaqueue vidq; - - /* Several counters */ - int h,m,s,us,jiffies; - char timestr[13]; -}; - -struct vivi_fh { - struct vivi_dev *dev; - - /* video capture */ - struct vivi_fmt *fmt; - unsigned int width,height; - struct videobuf_queue vb_vidq; - - enum v4l2_buf_type type; -}; - -/* ------------------------------------------------------------------ - DMA and thread functions - ------------------------------------------------------------------*/ - -/* Bars and Colors should match positions */ - -enum colors { - WHITE, - AMBAR, - CYAN, - GREEN, - MAGENTA, - RED, - BLUE -}; - -static u8 bars[8][3] = { - /* R G B */ - {204,204,204}, /* white */ - {208,208, 0}, /* ambar */ - { 0,206,206}, /* cyan */ - { 0,239, 0}, /* green */ - {239, 0,239}, /* magenta */ - {205, 0, 0}, /* red */ - { 0, 0,255}, /* blue */ - { 0, 0, 0} -}; - -#define TO_Y(r,g,b) (((16829*r +33039*g +6416*b + 32768)>>16)+16) -/* RGB to V(Cr) Color transform */ -#define TO_V(r,g,b) (((28784*r -24103*g -4681*b + 32768)>>16)+128) -/* RGB to U(Cb) Color transform */ -#define TO_U(r,g,b) (((-9714*r -19070*g +28784*b + 32768)>>16)+128) - -#define TSTAMP_MIN_Y 24 -#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 -#define TSTAMP_MIN_X 64 - -void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb) -{ - int i, pos=0; - - for (i=0;idma.nr_pages;i++) { - to_addr[i].sg=&vb->dma.sglist[i]; - to_addr[i].pos=pos; - pos += vb->dma.sglist[i].length; - } -} - -inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) -{ - int p1=0,p2=pages-1,p3=pages/2; - - /* Sanity test */ - BUG_ON (pos>=to_addr[p2].pos+to_addr[p2].sg->length); - - while (p1+1= to_addr[p2].pos) - p1=p2; - - return (p1); -} - -void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, - int hmax, int line, char *timestr) -{ - int w,i,j,pos=inipos,pgpos,oldpg,y; - char *p,*s,*basep; - struct page *pg; - u8 chr,r,g,b,color; - - /* Get first addr pointed to pixel position */ - oldpg=get_addr_pos(pos,pages,to_addr); - pg=pfn_to_page(to_addr[oldpg].sg->dma_address >> PAGE_SHIFT); - basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset; - - /* We will just duplicate the second pixel at the packet */ - wmax/=2; - - /* Generate a standard color bar pattern */ - for (w=0;wdma_address >> PAGE_SHIFT); - kunmap_atomic(basep, KM_BOUNCE_READ); - basep= kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[pgpos].sg->offset; - oldpg=pgpos; - } - p=basep+pos-to_addr[pgpos].pos; - - switch (color) { - case 0: - case 2: - *p=TO_Y(r,g,b); /* Luminance */ - break; - case 1: - *p=TO_U(r,g,b); /* Cb */ - break; - case 3: - *p=TO_V(r,g,b); /* Cr */ - break; - } - pos++; - } - } - - /* Checks if it is possible to show timestamp */ - if (TSTAMP_MAX_Y>=hmax) - goto end; - if (TSTAMP_MIN_X+strlen(timestr)>=wmax) - goto end; - - /* Print stream time */ - if (line>=TSTAMP_MIN_Y && line<=TSTAMP_MAX_Y) { - j=TSTAMP_MIN_X; - for (s=timestr;*s;s++) { - chr=rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y]; - for (i=0;i<7;i++) { - if (chr&1<<(7-i)) { /* Font color*/ - r=bars[BLUE][0]; - g=bars[BLUE][1]; - b=bars[BLUE][2]; - r=g=b=0; - g=198; - } else { /* Background color */ - r=bars[WHITE][0]; - g=bars[WHITE][1]; - b=bars[WHITE][2]; - r=g=b=0; - } - - pos=inipos+j*2; - for (color=0;color<4;color++) { - pgpos=get_addr_pos(pos,pages,to_addr); - if (pgpos!=oldpg) { - pg=pfn_to_page(to_addr[pgpos]. - sg->dma_address - >> PAGE_SHIFT); - kunmap_atomic(basep, - KM_BOUNCE_READ); - basep= kmap_atomic(pg, - KM_BOUNCE_READ)+ - to_addr[pgpos].sg->offset; - oldpg=pgpos; - } - p=basep+pos-to_addr[pgpos].pos; - - y=TO_Y(r,g,b); - - switch (color) { - case 0: - case 2: - *p=TO_Y(r,g,b); /* Luminance */ - break; - case 1: - *p=TO_U(r,g,b); /* Cb */ - break; - case 3: - *p=TO_V(r,g,b); /* Cr */ - break; - } - pos++; - } - j++; - } - } - } - - -end: - kunmap_atomic(basep, KM_BOUNCE_READ); -} -static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) -{ - int h,pos=0; - int hmax = buf->vb.height; - int wmax = buf->vb.width; - struct videobuf_buffer *vb=&buf->vb; - struct sg_to_addr *to_addr=buf->to_addr; - struct timeval ts; - - /* Test if DMA mapping is ready */ - if (!vb->dma.sglist[0].dma_address) - return; - - prep_to_addr(to_addr,vb); - - /* Check if there is enough memory */ - BUG_ON(buf->vb.dma.nr_pages << PAGE_SHIFT < (buf->vb.width*buf->vb.height)*2); - - for (h=0;hdma.nr_pages,wmax,hmax,h,dev->timestr); - pos += wmax*2; - } - - /* Updates stream time */ - - dev->us+=jiffies_to_usecs(jiffies-dev->jiffies); - dev->jiffies=jiffies; - if (dev->us>=1000000) { - dev->us-=1000000; - dev->s++; - if (dev->s>=60) { - dev->s-=60; - dev->m++; - if (dev->m>60) { - dev->m-=60; - dev->h++; - if (dev->h>24) - dev->h-=24; - } - } - } - sprintf(dev->timestr,"%02d:%02d:%02d:%03d", - dev->h,dev->m,dev->s,(dev->us+500)/1000); - - dprintk(2,"vivifill at %s: Buffer 0x%08lx size= %d\n",dev->timestr, - (unsigned long)buf->vb.dma.vmalloc,pos); - - /* Advice that buffer was filled */ - buf->vb.state = STATE_DONE; - buf->vb.field_count++; - do_gettimeofday(&ts); - buf->vb.ts = ts; - - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); -} - -static int restart_video_queue(struct vivi_dmaqueue *dma_q); - -static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) -{ - struct vivi_buffer *buf; - struct vivi_dev *dev= container_of(dma_q,struct vivi_dev,vidq); - - int bc; - - /* Announces videobuf that all went ok */ - for (bc = 0;; bc++) { - if (list_empty(&dma_q->active)) { - dprintk(1,"No active queue to serve\n"); - break; - } - - buf = list_entry(dma_q->active.next, - struct vivi_buffer, vb.queue); - - /* Nobody is waiting something to be done, just return */ - if (!waitqueue_active(&buf->vb.done)) { - mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); - return; - } - - do_gettimeofday(&buf->vb.ts); - dprintk(2,"[%p/%d] wakeup\n",buf,buf->vb.i); - - /* Fill buffer */ - vivi_fillbuff(dev,buf); - } - if (list_empty(&dma_q->active)) { - del_timer(&dma_q->timeout); - } else { - mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); - } - if (bc != 1) - dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); -} - -void vivi_sleep(struct vivi_dmaqueue *dma_q) -{ - int timeout; - DECLARE_WAITQUEUE(wait, current); - - dprintk(1,"%s dma_q=0x%08lx\n",__FUNCTION__,(unsigned long)dma_q); - - add_wait_queue(&dma_q->wq, &wait); - if (!kthread_should_stop()) { - dma_q->frame++; - - /* Calculate time to wake up */ - timeout=dma_q->ini_jiffies+msecs_to_jiffies((dma_q->frame*WAKE_NUMERATOR*1000)/WAKE_DENOMINATOR)-jiffies; - - if (timeout <= 0) { - int old=dma_q->frame; - dma_q->frame=(jiffies_to_msecs(jiffies-dma_q->ini_jiffies)*WAKE_DENOMINATOR)/(WAKE_NUMERATOR*1000)+1; - - timeout=dma_q->ini_jiffies+msecs_to_jiffies((dma_q->frame*WAKE_NUMERATOR*1000)/WAKE_DENOMINATOR)-jiffies; - - dprintk(1,"underrun, losed %d frames. " - "Now, frame is %d. Waking on %d jiffies\n", - dma_q->frame-old,dma_q->frame,timeout); - } else - dprintk(1,"will sleep for %i jiffies\n",timeout); - - vivi_thread_tick(dma_q); - - schedule_timeout_interruptible (timeout); - } - - remove_wait_queue(&dma_q->wq, &wait); - try_to_freeze(); -} - -int vivi_thread(void *data) -{ - struct vivi_dmaqueue *dma_q=data; - - dprintk(1,"thread started\n"); - - for (;;) { - vivi_sleep(dma_q); - - if (kthread_should_stop()) - break; - } - dprintk(1, "thread: exit\n"); - return 0; -} - -int vivi_start_thread(struct vivi_dmaqueue *dma_q) -{ - dma_q->frame=0; - dma_q->ini_jiffies=jiffies; - - dprintk(1,"%s\n",__FUNCTION__); - init_waitqueue_head(&dma_q->wq); - - dma_q->kthread = kthread_run(vivi_thread, dma_q, "vivi"); - - if (dma_q->kthread == NULL) { - printk(KERN_ERR "vivi: kernel_thread() failed\n"); - return -EINVAL; - } - dprintk(1,"returning from %s\n",__FUNCTION__); - return 0; -} - -void vivi_stop_thread(struct vivi_dmaqueue *dma_q) -{ - dprintk(1,"%s\n",__FUNCTION__); - /* shutdown control thread */ - if (dma_q->kthread) { - kthread_stop(dma_q->kthread); - dma_q->kthread=NULL; - } -} - -static int restart_video_queue(struct vivi_dmaqueue *dma_q) -{ - struct vivi_buffer *buf, *prev; - struct list_head *item; - - dprintk(1,"%s dma_q=0x%08lx\n",__FUNCTION__,(unsigned long)dma_q); - - if (!list_empty(&dma_q->active)) { - buf = list_entry(dma_q->active.next, struct vivi_buffer, vb.queue); - dprintk(2,"restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); - - dprintk(1,"Restarting video dma\n"); - vivi_stop_thread(dma_q); -// vivi_start_thread(dma_q); - - /* cancel all outstanding capture / vbi requests */ - list_for_each(item,&dma_q->active) { - buf = list_entry(item, struct vivi_buffer, vb.queue); - - list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; - wake_up(&buf->vb.done); - } - mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); - - return 0; - } - - prev = NULL; - for (;;) { - if (list_empty(&dma_q->queued)) - return 0; - buf = list_entry(dma_q->queued.next, struct vivi_buffer, vb.queue); - if (NULL == prev) { - list_del(&buf->vb.queue); - list_add_tail(&buf->vb.queue,&dma_q->active); - - dprintk(1,"Restarting video dma\n"); - vivi_stop_thread(dma_q); - vivi_start_thread(dma_q); - - buf->vb.state = STATE_ACTIVE; - mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2,"[%p/%d] restart_queue - first active\n", - buf,buf->vb.i); - - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_del(&buf->vb.queue); - list_add_tail(&buf->vb.queue,&dma_q->active); - buf->vb.state = STATE_ACTIVE; - dprintk(2,"[%p/%d] restart_queue - move to active\n", - buf,buf->vb.i); - } else { - return 0; - } - prev = buf; - } -} - -static void vivi_vid_timeout(unsigned long data) -{ - struct vivi_dev *dev = (struct vivi_dev*)data; - struct vivi_dmaqueue *vidq = &dev->vidq; - struct vivi_buffer *buf; - - while (!list_empty(&vidq->active)) { - buf = list_entry(vidq->active.next, struct vivi_buffer, vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; - wake_up(&buf->vb.done); - printk("vivi/0: [%p/%d] timeout\n", buf, buf->vb.i); - } - - restart_video_queue(vidq); -} - -/* ------------------------------------------------------------------ - Videobuf operations - ------------------------------------------------------------------*/ -static int -buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) -{ - struct vivi_fh *fh = vq->priv_data; - - *size = fh->width*fh->height*2; - - if (0 == *count) - *count = 32; - while (*size * *count > vid_limit * 1024 * 1024) - (*count)--; - return 0; -} - -void -free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) -{ - dprintk(1,"%s\n",__FUNCTION__); - - if (in_interrupt()) - BUG(); - - /*FIXME: Maybe a spinlock is required here */ - kfree(buf->to_addr); - buf->to_addr=NULL; - - videobuf_waiton(&buf->vb,0,0); - videobuf_dma_unmap(vq, &buf->vb.dma); - videobuf_dma_free(&buf->vb.dma); - buf->vb.state = STATE_NEEDS_INIT; -} - -#define norm_maxw() 1024 -#define norm_maxh() 768 -static int -buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct vivi_fh *fh = vq->priv_data; - struct vivi_buffer *buf = container_of(vb,struct vivi_buffer,vb); - int rc, init_buffer = 0; - -// dprintk(1,"%s, field=%d\n",__FUNCTION__,field); - - BUG_ON(NULL == fh->fmt); - if (fh->width < 48 || fh->width > norm_maxw() || - fh->height < 32 || fh->height > norm_maxh()) - return -EINVAL; - buf->vb.size = fh->width*fh->height*2; - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) - return -EINVAL; - - if (buf->fmt != fh->fmt || - buf->vb.width != fh->width || - buf->vb.height != fh->height || - buf->vb.field != field) { - buf->fmt = fh->fmt; - buf->vb.width = fh->width; - buf->vb.height = fh->height; - buf->vb.field = field; - init_buffer = 1; - } - - if (STATE_NEEDS_INIT == buf->vb.state) { - if (0 != (rc = videobuf_iolock(vq,&buf->vb,NULL))) - goto fail; - } - - buf->vb.state = STATE_PREPARED; - - if (NULL == (buf->to_addr = kmalloc(sizeof(*buf->to_addr) * vb->dma.nr_pages,GFP_KERNEL))) { - rc=-ENOMEM; - goto fail; - } - - return 0; - -fail: - free_buffer(vq,buf); - return rc; -} - -static void -buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct vivi_buffer *buf = container_of(vb,struct vivi_buffer,vb); - struct vivi_fh *fh = vq->priv_data; - struct vivi_dev *dev = fh->dev; - struct vivi_dmaqueue *vidq = &dev->vidq; - struct vivi_buffer *prev; - - if (!list_empty(&vidq->queued)) { - dprintk(1,"adding vb queue=0x%08lx\n",(unsigned long)&buf->vb.queue); - list_add_tail(&buf->vb.queue,&vidq->queued); - buf->vb.state = STATE_QUEUED; - dprintk(2,"[%p/%d] buffer_queue - append to queued\n", - buf, buf->vb.i); - } else if (list_empty(&vidq->active)) { - list_add_tail(&buf->vb.queue,&vidq->active); - - buf->vb.state = STATE_ACTIVE; - mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2,"[%p/%d] buffer_queue - first active\n", - buf, buf->vb.i); - - vivi_start_thread(vidq); - } else { - prev = list_entry(vidq->active.prev, struct vivi_buffer, vb.queue); - if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_add_tail(&buf->vb.queue,&vidq->active); - buf->vb.state = STATE_ACTIVE; - dprintk(2,"[%p/%d] buffer_queue - append to active\n", - buf, buf->vb.i); - - } else { - list_add_tail(&buf->vb.queue,&vidq->queued); - buf->vb.state = STATE_QUEUED; - dprintk(2,"[%p/%d] buffer_queue - first queued\n", - buf, buf->vb.i); - } - } -} - -static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct vivi_buffer *buf = container_of(vb,struct vivi_buffer,vb); - struct vivi_fh *fh = vq->priv_data; - struct vivi_dev *dev = (struct vivi_dev*)fh->dev; - struct vivi_dmaqueue *vidq = &dev->vidq; - - dprintk(1,"%s\n",__FUNCTION__); - - vivi_stop_thread(vidq); - - free_buffer(vq,buf); -} - -int vivi_map_sg (void *dev, struct scatterlist *sg, int nents, - int direction) -{ - int i; - - dprintk(1,"%s, number of pages=%d\n",__FUNCTION__,nents); - BUG_ON(direction == DMA_NONE); - - for (i = 0; i < nents; i++ ) { - BUG_ON(!sg[i].page); - - sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; - } - - return nents; -} - -int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages, - int direction) -{ - dprintk(1,"%s\n",__FUNCTION__); - return 0; -} - -int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist,int nr_pages, - int direction) -{ -// dprintk(1,"%s\n",__FUNCTION__); - -// flush_write_buffers(); - return 0; -} - -static struct videobuf_queue_ops vivi_video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, - - /* Non-pci handling routines */ - .vb_map_sg = vivi_map_sg, - .vb_dma_sync_sg = vivi_dma_sync_sg, - .vb_unmap_sg = vivi_unmap_sg, -}; - -/* ------------------------------------------------------------------ - IOCTL handling - ------------------------------------------------------------------*/ - -static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh, - struct v4l2_format *f) -{ - struct vivi_fmt *fmt; - enum v4l2_field field; - unsigned int maxw, maxh; - - if (format.fourcc != f->fmt.pix.pixelformat) { - dprintk(1,"Fourcc format invalid.\n"); - return -EINVAL; - } - fmt=&format; - - field = f->fmt.pix.field; - - if (field == V4L2_FIELD_ANY) { -// field=V4L2_FIELD_INTERLACED; - field=V4L2_FIELD_SEQ_TB; - } else if (V4L2_FIELD_INTERLACED != field) { - dprintk(1,"Field type invalid.\n"); - return -EINVAL; - } - - maxw = norm_maxw(); - maxh = norm_maxh(); - - f->fmt.pix.field = field; - if (f->fmt.pix.height < 32) - f->fmt.pix.height = 32; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - f->fmt.pix.width &= ~0x03; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} - -static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) -{ - /* is it free? */ - down(&dev->lock); - if (dev->resources) { - /* no, someone else uses it */ - up(&dev->lock); - return 0; - } - /* it's free, grab it */ - dev->resources =1; - dprintk(1,"res: get\n"); - up(&dev->lock); - return 1; -} - -static inline int res_locked(struct vivi_dev *dev) -{ - return (dev->resources); -} - -static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) -{ - down(&dev->lock); - dev->resources = 0; - dprintk(1,"res: put\n"); - up(&dev->lock); -} - -static int vivi_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) -{ - struct vivi_fh *fh = file->private_data; - struct vivi_dev *dev = fh->dev; - int ret=0; - - if (debug) { - if (_IOC_DIR(cmd) & _IOC_WRITE) - v4l_printk_ioctl_arg("vivi(w)",cmd, arg); - else if (!_IOC_DIR(cmd) & _IOC_READ) { - v4l_print_ioctl("vivi", cmd); - } - } - - switch(cmd) { - /* --- capabilities ------------------------------------------ */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = (struct v4l2_capability*)arg; - - memset(cap, 0, sizeof(*cap)); - - strcpy(cap->driver, "vivi"); - strcpy(cap->card, "vivi"); - cap->version = VIVI_VERSION; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; - break; - } - /* --- capture ioctls ---------------------------------------- */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - enum v4l2_buf_type type; - unsigned int index; - - index = f->index; - type = f->type; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret=-EINVAL; - break; - } - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (index > 0){ - ret=-EINVAL; - break; - } - memset(f,0,sizeof(*f)); - - f->index = index; - f->type = type; - strlcpy(f->description,format.name,sizeof(f->description)); - f->pixelformat = format.fourcc; - break; - default: - ret=-EINVAL; - } - break; - } - case VIDIOC_G_FMT: - { - struct v4l2_format *f = (struct v4l2_format *)arg; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret=-EINVAL; - break; - } - - memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; - f->fmt.pix.field = fh->vb_vidq.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fh->fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - break; - } - case VIDIOC_S_FMT: - { - struct v4l2_format *f = arg; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1,"Only capture supported.\n"); - ret=-EINVAL; - break; - } - - ret = vivi_try_fmt(dev,fh,f); - if (ret < 0) - break; - - fh->fmt = &format; - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - fh->vb_vidq.field = f->fmt.pix.field; - fh->type = f->type; - - break; - } - case VIDIOC_TRY_FMT: - { - struct v4l2_format *f = arg; - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret=-EINVAL; - break; - } - - ret=vivi_try_fmt(dev,fh,f); - break; - } - case VIDIOC_REQBUFS: - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret=-EINVAL; - break; - } - ret=videobuf_reqbufs(&fh->vb_vidq, arg); - break; - case VIDIOC_QUERYBUF: - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret=-EINVAL; - break; - } - ret=videobuf_querybuf(&fh->vb_vidq, arg); - break; - case VIDIOC_QBUF: - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret=-EINVAL; - break; - } - ret=videobuf_qbuf(&fh->vb_vidq, arg); - break; - case VIDIOC_DQBUF: - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret=-EINVAL; - break; - } - ret=videobuf_dqbuf(&fh->vb_vidq, arg, - file->f_flags & O_NONBLOCK); - break; -#ifdef HAVE_V4L1 - /* --- streaming capture ------------------------------------- */ - case VIDIOCGMBUF: - { - struct video_mbuf *mbuf = arg; - struct videobuf_queue *q=&fh->vb_vidq; - struct v4l2_requestbuffers req; - unsigned int i; - - memset(&req,0,sizeof(req)); - req.type = q->type; - req.count = 8; - req.memory = V4L2_MEMORY_MMAP; - ret = videobuf_reqbufs(q,&req); - if (ret < 0) - break; - memset(mbuf,0,sizeof(*mbuf)); - mbuf->frames = req.count; - mbuf->size = 0; - for (i = 0; i < mbuf->frames; i++) { - mbuf->offsets[i] = q->bufs[i]->boff; - mbuf->size += q->bufs[i]->bsize; - } - break; - } -#endif - case VIDIOC_STREAMON: - { - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (!res_get(dev,fh)) - return -EBUSY; - ret=videobuf_streamon(&fh->vb_vidq); - break; - } - case VIDIOC_STREAMOFF: - { - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret=-EINVAL; - break; - } - ret = videobuf_streamoff(&fh->vb_vidq); - if (ret < 0) - break; - res_free(dev,fh); - break; - } - /* ---------- tv norms ---------- */ - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *e = arg; - - if (e->index>0) { - ret=-EINVAL; - break; - } - ret = v4l2_video_std_construct(e, V4L2_STD_NTSC_M, "NTSC-M"); - - /* Allows vivi to use different fps from video std */ - e->frameperiod.numerator = WAKE_NUMERATOR; - e->frameperiod.denominator = WAKE_DENOMINATOR; - - break; - } - case VIDIOC_G_STD: - { - v4l2_std_id *id = arg; - - *id = V4L2_STD_NTSC_M; - break; - } - case VIDIOC_S_STD: - { - break; - } - /* ------ input switching ---------- */ - case VIDIOC_ENUMINPUT: - { /* only one input in this sample driver */ - struct v4l2_input *inp = arg; - - if (inp->index != 0) { - ret=-EINVAL; - break; - } - memset(inp, 0, sizeof(*inp)); - - inp->index = 0; - inp->type = V4L2_INPUT_TYPE_CAMERA; - inp->std = V4L2_STD_NTSC_M; - strcpy(inp->name,"Camera"); - break; - } - case VIDIOC_G_INPUT: - { - unsigned int *i = arg; - - *i = 0; - break; - } - case VIDIOC_S_INPUT: - { - unsigned int *i = arg; - - if (*i > 0) - ret=-EINVAL; - break; - } - - /* --- controls ---------------------------------------------- */ - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - if (qc->id && qc->id == vivi_qctrl[i].id) { - memcpy(qc, &(vivi_qctrl[i]), - sizeof(*qc)); - break; - } - - ret=-EINVAL; - break; - } - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - if (ctrl->id == vivi_qctrl[i].id) { - ctrl->value=qctl_regs[i]; - break; - } - - ret=-EINVAL; - break; - } - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - int i; - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - if (ctrl->id == vivi_qctrl[i].id) { - if (ctrl->value < - vivi_qctrl[i].minimum - || ctrl->value > - vivi_qctrl[i].maximum) { - ret=-ERANGE; - break; - } - qctl_regs[i]=ctrl->value; - break; - } - ret=-EINVAL; - break; - } - default: - ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,vivi_do_ioctl); - } - - if (debug) { - if (ret<0) { - v4l_print_ioctl("vivi(err)", cmd); - dprintk(1,"errcode=%d\n",ret); - } else if (_IOC_DIR(cmd) & _IOC_READ) - v4l_printk_ioctl_arg("vivi(r)",cmd, arg); - } - - return ret; -} - -static int vivi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - return video_usercopy(inode, file, cmd, arg, vivi_do_ioctl); -} - -/* ------------------------------------------------------------------ - File operations for the device - ------------------------------------------------------------------*/ - -#define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8) - -static int vivi_open(struct inode *inode, struct file *file) -{ - int minor = iminor(inode); - struct vivi_dev *h,*dev = NULL; - struct vivi_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; - int i; - - printk(KERN_DEBUG "vivi: open called (minor=%d)\n",minor); - - list_for_each(list,&vivi_devlist) { - h = list_entry(list, struct vivi_dev, vivi_devlist); - if (h->video_dev.minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - if (NULL == dev) - return -ENODEV; - - - /* If more than one user, mutex should be added */ - dev->users++; - - dprintk(1,"open minor=%d type=%s users=%d\n", - minor,v4l2_type_names[type],dev->users); - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) { - dev->users--; - return -ENOMEM; - } - - file->private_data = fh; - fh->dev = dev; - fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fh->fmt = &format; - fh->width = 640; - fh->height = 480; - - /* Put all controls at a sane state */ - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - qctl_regs[i] =vivi_qctrl[i].default_value; - - dprintk(1,"Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n", - (unsigned long)fh,(unsigned long)dev,(unsigned long)&dev->vidq); - dprintk(1,"Open: list_empty queued=%d\n",list_empty(&dev->vidq.queued)); - dprintk(1,"Open: list_empty active=%d\n",list_empty(&dev->vidq.active)); - - /* Resets frame counters */ - dev->h=0; - dev->m=0; - dev->s=0; - dev->us=0; - dev->jiffies=jiffies; - sprintf(dev->timestr,"%02d:%02d:%02d:%03d", - dev->h,dev->m,dev->s,(dev->us+500)/1000); - - videobuf_queue_init(&fh->vb_vidq, &vivi_video_qops, - NULL, NULL, - fh->type, - V4L2_FIELD_INTERLACED, - sizeof(struct vivi_buffer),fh); - - return 0; -} - -static ssize_t -vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ - struct vivi_fh *fh = file->private_data; - - if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { - if (res_locked(fh->dev)) - return -EBUSY; - return videobuf_read_one(&fh->vb_vidq, data, count, ppos, - file->f_flags & O_NONBLOCK); - } - return 0; -} - -static unsigned int -vivi_poll(struct file *file, struct poll_table_struct *wait) -{ - struct vivi_fh *fh = file->private_data; - struct vivi_buffer *buf; - - dprintk(1,"%s\n",__FUNCTION__); - - if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) - return POLLERR; - - if (res_get(fh->dev,fh)) { - dprintk(1,"poll: mmap interface\n"); - /* streaming capture */ - if (list_empty(&fh->vb_vidq.stream)) - return POLLERR; - buf = list_entry(fh->vb_vidq.stream.next,struct vivi_buffer,vb.stream); - } else { - dprintk(1,"poll: read() interface\n"); - /* read() capture */ - buf = (struct vivi_buffer*)fh->vb_vidq.read_buf; - if (NULL == buf) - return POLLERR; - } - poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == STATE_DONE || - buf->vb.state == STATE_ERROR) - return POLLIN|POLLRDNORM; - return 0; -} - -static int vivi_release(struct inode *inode, struct file *file) -{ - struct vivi_fh *fh = file->private_data; - struct vivi_dev *dev = fh->dev; - struct vivi_dmaqueue *vidq = &dev->vidq; - - int minor = iminor(inode); - - vivi_stop_thread(vidq); - videobuf_mmap_free(&fh->vb_vidq); - - kfree (fh); - - dev->users--; - - printk(KERN_DEBUG "vivi: close called (minor=%d, users=%d)\n",minor,dev->users); - - return 0; -} - -static int -vivi_mmap(struct file *file, struct vm_area_struct * vma) -{ - struct vivi_fh *fh = file->private_data; - int ret; - - dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma); - - ret=videobuf_mmap_mapper(&fh->vb_vidq, vma); - - dprintk (1,"vma start=0x%08lx, size=%ld, ret=%d\n", - (unsigned long)vma->vm_start, - (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, - ret); - - return ret; -} - -static struct file_operations vivi_fops = { - .owner = THIS_MODULE, - .open = vivi_open, - .release = vivi_release, - .read = vivi_read, - .poll = vivi_poll, - .ioctl = vivi_ioctl, - .mmap = vivi_mmap, - .llseek = no_llseek, -}; - -static struct video_device vivi = { - .name = "VTM Virtual Video Capture Board", - .type = VID_TYPE_CAPTURE, - .hardware = 0, - .fops = &vivi_fops, - .minor = -1, -// .release = video_device_release, -}; -/* ------------------------------------------------------------------ - Initialization and module stuff - ------------------------------------------------------------------*/ - -static int __init vivi_init(void) -{ - int ret; - struct vivi_dev *dev; - - dev = kzalloc(sizeof(*dev),GFP_KERNEL); - if (NULL == dev) - return -ENOMEM; - list_add_tail(&dev->vivi_devlist,&vivi_devlist); - - /* init video dma queues */ - INIT_LIST_HEAD(&dev->vidq.active); - INIT_LIST_HEAD(&dev->vidq.queued); - - /* initialize locks */ - init_MUTEX(&dev->lock); - - dev->vidq.timeout.function = vivi_vid_timeout; - dev->vidq.timeout.data = (unsigned long)dev; - init_timer(&dev->vidq.timeout); - - ret = video_register_device(&vivi, VFL_TYPE_GRABBER, video_nr); - printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret); - return ret; -} - -static void __exit vivi_exit(void) -{ - struct vivi_dev *h; - struct list_head *list; - - list_for_each(list,&vivi_devlist) { - h = list_entry(list, struct vivi_dev, vivi_devlist); - kfree (h); - } - video_unregister_device(&vivi); -} - -module_init(vivi_init); -module_exit(vivi_exit); diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 40b205b91..d0a1e72ea 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -1,4 +1,4 @@ -/* +/* * vpx3220a, vpx3216b & vpx3214c video decoder driver version 0.0.1 * * Copyright (C) 2001 Laurent Pinchart @@ -30,6 +30,7 @@ #include #include +#include #define I2C_NAME(x) (x)->name @@ -176,8 +177,8 @@ vpx3220_write_block (struct i2c_client *client, static int vpx3220_write_fp_block (struct i2c_client *client, - const u16 *data, - unsigned int len) + const u16 *data, + unsigned int len) { u8 reg; int ret = 0; @@ -316,7 +317,7 @@ vpx3220_command (struct i2c_client *client, vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); switch (decoder->norm) { - + case VIDEO_MODE_NTSC: vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); @@ -324,7 +325,7 @@ vpx3220_command (struct i2c_client *client, case VIDEO_MODE_PAL: vpx3220_write_fp_block(client, init_pal, - sizeof(init_pal) >> 1); + sizeof(init_pal) >> 1); break; case VIDEO_MODE_SECAM: vpx3220_write_fp_block(client, init_secam, @@ -332,10 +333,10 @@ vpx3220_command (struct i2c_client *client, break; default: vpx3220_write_fp_block(client, init_pal, - sizeof(init_pal) >> 1); + sizeof(init_pal) >> 1); break; } - } + } break; case DECODER_DUMP: @@ -411,7 +412,7 @@ vpx3220_command (struct i2c_client *client, /* Here we back up the input selection because it gets overwritten when we fill the registers with the - choosen video norm */ + choosen video norm */ temp_input = vpx3220_fp_read(client, 0xf2); dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n", @@ -578,7 +579,7 @@ static unsigned short normal_i2c[] = }; static unsigned short ignore = I2C_CLIENT_END; - + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, @@ -661,7 +662,7 @@ vpx3220_detect_client (struct i2c_adapter *adapter, break; default: dprintk(1, - KERN_INFO + KERN_INFO "%s: Wrong part number (0x%04x)\n", __func__, pn); kfree(client); diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 80ef8a1b8..b7b0afffd 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -26,7 +26,7 @@ Does any other model using the w9966 interface chip exist ? Todo: - + *Add a working EPP mode, since DMA ECP read isn't implemented in the parport drivers. (That's why it's so sloow) @@ -47,9 +47,9 @@ *Probably some bugs that I don't know of Please support me by sending feedback! - + Changes: - + Alan Cox: Removed RGB mode for kernel merge, added THIS_MODULE and owner support for newer module locks */ @@ -204,7 +204,7 @@ static struct video_device w9966_template = { */ -// Set camera phase flags, so we know what to uninit when terminating +// Set camera phase flags, so we know what to uninit when terminating static inline void w9966_setState(struct w9966_dev* cam, int mask, int val) { cam->dev_state = (cam->dev_state & ~mask) ^ val; @@ -233,7 +233,7 @@ static inline void w9966_pdev_release(struct w9966_dev* cam) parport_release(cam->pdev); w9966_setState(cam, W9966_STATE_CLAIMED, 0); } - + // Read register from W9966 interface-chip // Expects a claimed pdev // -1 on error, else register data (byte) @@ -242,7 +242,7 @@ static int w9966_rReg(struct w9966_dev* cam, int reg) // ECP, read, regtransfer, REG, REG, REG, REG, REG const unsigned char addr = 0x80 | (reg & 0x1f); unsigned char val; - + if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0) return -1; if (parport_write(cam->pport, &addr, 1) != 1) @@ -263,7 +263,7 @@ static int w9966_wReg(struct w9966_dev* cam, int reg, int data) // ECP, write, regtransfer, REG, REG, REG, REG, REG const unsigned char addr = 0xc0 | (reg & 0x1f); const unsigned char val = data; - + if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0) return -1; if (parport_write(cam->pport, &addr, 1) != 1) @@ -284,7 +284,7 @@ static int w9966_init(struct w9966_dev* cam, struct parport* port) { if (cam->dev_state != 0) return -1; - + cam->pport = port; cam->brightness = 128; cam->contrast = 64; @@ -302,7 +302,7 @@ static int w9966_init(struct w9966_dev* cam, struct parport* port) cam->ppmode = IEEE1284_MODE_EPP; else cam->ppmode = IEEE1284_MODE_ECP; - break; + break; case 1: // hw- or sw-ecp cam->ppmode = IEEE1284_MODE_ECP; break; @@ -310,7 +310,7 @@ static int w9966_init(struct w9966_dev* cam, struct parport* port) cam->ppmode = IEEE1284_MODE_EPP; break; } - + // Tell the parport driver that we exists cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL); if (cam->pdev == NULL) { @@ -320,7 +320,7 @@ static int w9966_init(struct w9966_dev* cam, struct parport* port) w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV); w9966_pdev_claim(cam); - + // Setup a default capture mode if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) { DPRINTF("w9966_setup() failed.\n"); @@ -333,11 +333,11 @@ static int w9966_init(struct w9966_dev* cam, struct parport* port) memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device)); cam->vdev.priv = cam; - if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) + if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) return -1; - + w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV); - + // All ok printk( "w9966cf: Found and initialized a webcam on %s.\n", @@ -391,7 +391,7 @@ static int w9966_findlen(int near, int size, int maxlen) // Only continue as long as we keep getting better values if (err > besterr) break; - + besterr = err; bestlen = len; } @@ -399,7 +399,7 @@ static int w9966_findlen(int near, int size, int maxlen) return bestlen; } -// Modify capture window (if necessary) +// Modify capture window (if necessary) // and calculate downscaling // Return -1 on error static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor) @@ -407,7 +407,7 @@ static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsig int maxlen = max - min; int len = *end - *beg + 1; int newlen = w9966_findlen(len, size, maxlen); - int err = newlen - len; + int err = newlen - len; // Check for bad format if (newlen > maxlen || newlen < size) @@ -452,8 +452,8 @@ static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, in 0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0 }; - - + + if (w*h*2 > W9966_SRAMSIZE) { DPRINTF("capture window exceeds SRAM size!.\n"); @@ -469,9 +469,9 @@ static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, in cam->width = w; cam->height = h; - enh_s = 0; + enh_s = 0; enh_e = w*h*2; - + // Modify capture window if necessary and calculate downscaling if ( w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 || @@ -482,14 +482,14 @@ static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, in "%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n", w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80 ); - + // Setup registers regs[0x00] = 0x00; // Set normal operation regs[0x01] = 0x18; // Capture mode regs[0x02] = scale_y; // V-scaling regs[0x03] = scale_x; // H-scaling - - // Capture window + + // Capture window regs[0x04] = (x1 & 0x0ff); // X-start (8 low bits) regs[0x05] = (x1 & 0x300)>>8; // X-start (2 high bits) regs[0x06] = (y1 & 0x0ff); // Y-start (8 low bits) @@ -499,7 +499,7 @@ static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, in regs[0x0a] = (y2 & 0x0ff); // Y-end (8 low bits) regs[0x0c] = W9966_SRAMID; // SRAM-banks (1x 128kb) - + // Enhancement layer regs[0x0d] = (enh_s& 0x000ff); // Enh. start (0-7) regs[0x0e] = (enh_s& 0x0ff00)>>8; // Enh. start (8-15) @@ -515,7 +515,7 @@ static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, in regs[0x19] = 0xff; // I/O port direction control regs[0x1a] = 0xff; // I/O port data register regs[0x1b] = 0x10; // ??? - + // SAA7111 chip settings saa7111_regs[0x0a] = cam->brightness; saa7111_regs[0x0b] = cam->contrast; @@ -551,7 +551,7 @@ static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state) cam->i2c_state |= W9966_I2C_W_DATA; else cam->i2c_state &= ~W9966_I2C_W_DATA; - + w9966_wReg(cam, 0x18, cam->i2c_state); udelay(5); } @@ -577,7 +577,7 @@ static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state) w9966_wReg(cam, 0x18, cam->i2c_state); udelay(5); - + // we go to high, we also expect the peripheral to ack. if (state) { timeout = jiffies + 100; @@ -607,16 +607,16 @@ static int w9966_i2c_wbyte(struct w9966_dev* cam, int data) w9966_i2c_setsda(cam, (data >> i) & 0x01); if (w9966_i2c_setscl(cam, 1) == -1) - return -1; + return -1; w9966_i2c_setscl(cam, 0); } w9966_i2c_setsda(cam, 1); - + if (w9966_i2c_setscl(cam, 1) == -1) return -1; w9966_i2c_setscl(cam, 0); - + return 0; } @@ -626,8 +626,8 @@ static int w9966_i2c_wbyte(struct w9966_dev* cam, int data) static int w9966_i2c_rbyte(struct w9966_dev* cam) { unsigned char data = 0x00; - int i; - + int i; + w9966_i2c_setsda(cam, 1); for (i = 0; i < 8; i++) @@ -637,7 +637,7 @@ static int w9966_i2c_rbyte(struct w9966_dev* cam) data = data << 1; if (w9966_i2c_getsda(cam)) data |= 0x01; - + w9966_i2c_setscl(cam, 0); } return data; @@ -673,11 +673,11 @@ static int w9966_rReg_i2c(struct w9966_dev* cam, int reg) return -1; w9966_i2c_setsda(cam, 0); - + if (w9966_i2c_setscl(cam, 1) == -1) return -1; w9966_i2c_setsda(cam, 1); - + return data; } #endif @@ -699,7 +699,7 @@ static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data) w9966_i2c_setsda(cam, 0); if (w9966_i2c_setscl(cam, 1) == -1) return -1; - + w9966_i2c_setsda(cam, 1); return 0; @@ -714,7 +714,7 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, { struct video_device *vdev = video_devdata(file); struct w9966_dev *cam = vdev->priv; - + switch(cmd) { case VIDIOCGCAP: @@ -790,14 +790,14 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, struct video_picture *vpic = arg; if (vpic->depth != 16 || vpic->palette != VIDEO_PALETTE_YUV422) return -EINVAL; - + cam->brightness = vpic->brightness >> 8; cam->hue = (vpic->hue >> 8) - 128; cam->color = vpic->colour >> 9; cam->contrast = vpic->contrast >> 9; w9966_pdev_claim(cam); - + if ( w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 || w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 || @@ -807,7 +807,7 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, w9966_pdev_release(cam); return -EIO; } - + w9966_pdev_release(cam); return 0; } @@ -815,13 +815,13 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, { int ret; struct video_window *vwin = arg; - + if (vwin->flags != 0) return -EINVAL; if (vwin->clipcount != 0) return -EINVAL; if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W) - return -EINVAL; + return -EINVAL; if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H) return -EINVAL; @@ -829,12 +829,12 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, w9966_pdev_claim(cam); ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height); w9966_pdev_release(cam); - + if (ret != 0) { DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n"); return -EIO; } - + return 0; } case VIDIOCGWIN: @@ -846,7 +846,7 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, return 0; } // Unimplemented - case VIDIOCCAPTURE: + case VIDIOCCAPTURE: case VIDIOCGFBUF: case VIDIOCSFBUF: case VIDIOCKEY: @@ -877,17 +877,17 @@ static ssize_t w9966_v4l_read(struct file *file, char __user *buf, unsigned char __user *dest = (unsigned char __user *)buf; unsigned long dleft = count; unsigned char *tbuf; - + // Why would anyone want more than this?? if (count > cam->width * cam->height * 2) return -EINVAL; - + w9966_pdev_claim(cam); w9966_wReg(cam, 0x00, 0x02); // Reset ECP-FIFO buffer w9966_wReg(cam, 0x00, 0x00); // Return to normal operation w9966_wReg(cam, 0x01, 0x98); // Enable capture - // write special capture-addr and negotiate into data transfer + // write special capture-addr and negotiate into data transfer if ( (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 )|| (parport_write(cam->pport, &addr, 1) != 1 )|| @@ -906,7 +906,7 @@ static ssize_t w9966_v4l_read(struct file *file, char __user *buf, while(dleft > 0) { unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft; - + if (parport_read(cam->pport, tbuf, tsize) < tsize) { count = -EFAULT; goto out; @@ -933,7 +933,7 @@ out: static void w9966_attach(struct parport *port) { int i; - + for (i = 0; i < W9966_MAXCAMS; i++) { if (w9966_cams[i].dev_state != 0) // Cam is already assigned diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c deleted file mode 100644 index a9b59c35c..000000000 --- a/drivers/media/video/wm8739.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * wm8739 - * - * Copyright (C) 2005 T. Adachi - * - * Copyright (C) 2005 Hans Verkuil - * - Cleanup - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("wm8739 driver"); -MODULE_AUTHOR("T. Adachi, Hans Verkuil"); -MODULE_LICENSE("GPL"); - -static int debug = 0; -static unsigned short normal_i2c[] = { 0x34 >> 1, 0x36 >> 1, I2C_CLIENT_END }; - -module_param(debug, int, 0644); - -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - - -I2C_CLIENT_INSMOD; - -/* ------------------------------------------------------------------------ */ - -enum { - R0 = 0, R1, - R5 = 5, R6, R7, R8, R9, R15 = 15, - TOT_REGS -}; - -struct wm8739_state { - u32 clock_freq; - u8 muted; - u16 volume; - u16 balance; - u8 vol_l; /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */ - u8 vol_r; /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */ -}; - -/* ------------------------------------------------------------------------ */ - -static int wm8739_write(struct i2c_client *client, int reg, u16 val) -{ - int i; - - if (reg < 0 || reg >= TOT_REGS) { - v4l_err(client, "Invalid register R%d\n", reg); - return -1; - } - - v4l_dbg(1, debug, client, "write: %02x %02x\n", reg, val); - - for (i = 0; i < 3; i++) { - if (i2c_smbus_write_byte_data(client, (reg << 1) | - (val >> 8), val & 0xff) == 0) { - return 0; - } - } - v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg); - return -1; -} - -/* write regs to set audio volume etc */ -static void wm8739_set_audio(struct i2c_client *client) -{ - struct wm8739_state *state = i2c_get_clientdata(client); - u16 mute = state->muted ? 0x80 : 0; - - /* Volume setting: bits 0-4, 0x1f = 12 dB, 0x00 = -34.5 dB - * Default setting: 0x17 = 0 dB - */ - wm8739_write(client, R0, (state->vol_l & 0x1f) | mute); - wm8739_write(client, R1, (state->vol_r & 0x1f) | mute); -} - -static int wm8739_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) -{ - struct wm8739_state *state = i2c_get_clientdata(client); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value = state->muted; - break; - - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = state->volume; - break; - - case V4L2_CID_AUDIO_BALANCE: - ctrl->value = state->balance; - break; - - default: - return -EINVAL; - } - return 0; -} - -static int wm8739_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) -{ - struct wm8739_state *state = i2c_get_clientdata(client); - unsigned int work_l, work_r; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - state->muted = ctrl->value; - break; - - case V4L2_CID_AUDIO_VOLUME: - state->volume = ctrl->value; - break; - - case V4L2_CID_AUDIO_BALANCE: - state->balance = ctrl->value; - break; - - default: - return -EINVAL; - } - - /* normalize ( 65535 to 0 -> 31 to 0 (12dB to -34.5dB) ) */ - work_l = (min(65536 - state->balance, 32768) * state->volume) / 32768; - work_r = (min(state->balance, (u16)32768) * state->volume) / 32768; - - state->vol_l = (long)work_l * 31 / 65535; - state->vol_r = (long)work_r * 31 / 65535; - - /* set audio volume etc. */ - wm8739_set_audio(client); - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static struct v4l2_queryctrl wm8739_qctrl[] = { - { - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 58880, - .flags = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - .flags = 0, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_AUDIO_BALANCE, - .name = "Balance", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .flags = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - } -}; - -/* ------------------------------------------------------------------------ */ - -static int wm8739_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - struct wm8739_state *state = i2c_get_clientdata(client); - - switch (cmd) { - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - { - u32 audiofreq = *(u32 *)arg; - - state->clock_freq = audiofreq; - wm8739_write(client, R9, 0x000); /* de-activate */ - switch (audiofreq) { - case 44100: - wm8739_write(client, R8, 0x020); /* 256fps, fs=44.1k */ - break; - case 48000: - wm8739_write(client, R8, 0x000); /* 256fps, fs=48k */ - break; - case 32000: - wm8739_write(client, R8, 0x018); /* 256fps, fs=32k */ - break; - default: - break; - } - wm8739_write(client, R9, 0x001); /* activate */ - break; - } - - case VIDIOC_G_CTRL: - return wm8739_get_ctrl(client, arg); - - case VIDIOC_S_CTRL: - return wm8739_set_ctrl(client, arg); - - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(wm8739_qctrl); i++) - if (qc->id && qc->id == wm8739_qctrl[i].id) { - memcpy(qc, &wm8739_qctrl[i], sizeof(*qc)); - return 0; - } - return -EINVAL; - } - - case VIDIOC_LOG_STATUS: - v4l_info(client, "Frequency: %u Hz\n", state->clock_freq); - v4l_info(client, "Volume L: %02x%s\n", state->vol_l & 0x1f, - state->muted ? " (muted)" : ""); - v4l_info(client, "Volume R: %02x%s\n", state->vol_r & 0x1f, - state->muted ? " (muted)" : ""); - break; - - default: - return -EINVAL; - } - - return 0; -} - -/* ------------------------------------------------------------------------ */ - -/* i2c implementation */ - -static struct i2c_driver i2c_driver; - -static int wm8739_attach(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct wm8739_state *state; - - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; - - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver; - snprintf(client->name, sizeof(client->name) - 1, "wm8739"); - - v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); - - state = kmalloc(sizeof(struct wm8739_state), GFP_KERNEL); - if (state == NULL) { - kfree(client); - return -ENOMEM; - } - state->vol_l = 0x17; /* 0dB */ - state->vol_r = 0x17; /* 0dB */ - state->muted = 0; - state->balance = 32768; - /* normalize (12dB(31) to -34.5dB(0) [0dB(23)] -> 65535 to 0) */ - state->volume = ((long)state->vol_l + 1) * 65535 / 31; - state->clock_freq = 48000; - i2c_set_clientdata(client, state); - - /* initialize wm8739 */ - wm8739_write(client, R15, 0x00); /* reset */ - wm8739_write(client, R5, 0x000); /* filter setting, high path, offet clear */ - wm8739_write(client, R6, 0x000); /* ADC, OSC, Power Off mode Disable */ - wm8739_write(client, R7, 0x049); /* Digital Audio interface format */ - /* Enable Master mode */ - /* 24 bit, MSB first/left justified */ - wm8739_write(client, R8, 0x000); /* sampling control */ - /* normal, 256fs, 48KHz sampling rate */ - wm8739_write(client, R9, 0x001); /* activate */ - wm8739_set_audio(client); /* set volume/mute */ - - i2c_attach_client(client); - - return 0; -} - -static int wm8739_probe(struct i2c_adapter *adapter) -{ - if (adapter->class & I2C_CLASS_TV_ANALOG) - return i2c_probe(adapter, &addr_data, wm8739_attach); - return 0; -} - -static int wm8739_detach(struct i2c_client *client) -{ - int err; - - err = i2c_detach_client(client); - if (err) - return err; - - kfree(client); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* i2c implementation */ -static struct i2c_driver i2c_driver = { - .driver = { - .name = "wm8739", - }, - .id = I2C_DRIVERID_WM8739, - .attach_adapter = wm8739_probe, - .detach_client = wm8739_detach, - .command = wm8739_command, -}; - - -static int __init wm8739_init_module(void) -{ - return i2c_add_driver(&i2c_driver); -} - -static void __exit wm8739_cleanup_module(void) -{ - i2c_del_driver(&i2c_driver); -} - -module_init(wm8739_init_module); -module_exit(wm8739_cleanup_module); diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index d81a88bbe..8cb64f8a8 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c @@ -79,26 +79,21 @@ static int wm8775_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct wm8775_state *state = i2c_get_clientdata(client); - struct v4l2_routing *route = arg; + struct v4l2_audio *input = arg; struct v4l2_control *ctrl = arg; switch (cmd) { - case VIDIOC_INT_G_AUDIO_ROUTING: - route->input = state->input; - route->output = 0; - break; - - case VIDIOC_INT_S_AUDIO_ROUTING: + case VIDIOC_S_AUDIO: /* There are 4 inputs and one output. Zero or more inputs are multiplexed together to the output. Hence there are 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) { - v4l_err(client, "Invalid input %d.\n", route->input); + if (input->index > 15) { + v4l_err(client, "Invalid input %d.\n", input->index); return -EINVAL; } - state->input = route->input; + state->input = input->index; if (state->muted) break; wm8775_write(client, R21, 0x0c0); @@ -107,6 +102,11 @@ static int wm8775_command(struct i2c_client *client, unsigned int cmd, wm8775_write(client, R21, 0x100 + state->input); break; + case VIDIOC_G_AUDIO: + memset(input, 0, sizeof(*input)); + input->index = state->input; + break; + case VIDIOC_G_CTRL: if (ctrl->id != V4L2_CID_AUDIO_MUTE) return -EINVAL; diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig deleted file mode 100644 index 115833e4f..000000000 --- a/drivers/media/video/zc0301/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config USB_ZC0301 - tristate "USB ZC0301 Image Processor and Control Chip support" - depends on USB && VIDEO_V4L1 - ---help--- - Say Y here if you want support for cameras based on the ZC0301 - Image Processor and Control Chip. - - See for more info. - - To compile this driver as a module, choose M here: the - module will be called zc0301. diff --git a/drivers/media/video/zc0301/Makefile b/drivers/media/video/zc0301/Makefile deleted file mode 100644 index d749199d8..000000000 --- a/drivers/media/video/zc0301/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -zc0301-objs := zc0301_core.o zc0301_pas202bcb.o - -obj-$(CONFIG_USB_ZC0301) += zc0301.o diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h deleted file mode 100644 index b9c93b8c1..000000000 --- a/drivers/media/video/zc0301/zc0301.h +++ /dev/null @@ -1,192 +0,0 @@ -/*************************************************************************** - * V4L2 driver for ZC0301 Image Processor and Control Chip * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 _ZC0301_H_ -#define _ZC0301_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "zc0301_sensor.h" - -/*****************************************************************************/ - -#define ZC0301_DEBUG -#define ZC0301_DEBUG_LEVEL 2 -#define ZC0301_MAX_DEVICES 64 -#define ZC0301_FORCE_MUNMAP 0 -#define ZC0301_MAX_FRAMES 32 -#define ZC0301_COMPRESSION_QUALITY 0 -#define ZC0301_URBS 2 -#define ZC0301_ISO_PACKETS 7 -#define ZC0301_ALTERNATE_SETTING 7 -#define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS) -#define ZC0301_CTRL_TIMEOUT 100 -#define ZC0301_FRAME_TIMEOUT 2 - -/*****************************************************************************/ - -ZC0301_ID_TABLE -ZC0301_SENSOR_TABLE - -enum zc0301_frame_state { - F_UNUSED, - F_QUEUED, - F_GRABBING, - F_DONE, - F_ERROR, -}; - -struct zc0301_frame_t { - void* bufmem; - struct v4l2_buffer buf; - enum zc0301_frame_state state; - struct list_head frame; - unsigned long vma_use_count; -}; - -enum zc0301_dev_state { - DEV_INITIALIZED = 0x01, - DEV_DISCONNECTED = 0x02, - DEV_MISCONFIGURED = 0x04, -}; - -enum zc0301_io_method { - IO_NONE, - IO_READ, - IO_MMAP, -}; - -enum zc0301_stream_state { - STREAM_OFF, - STREAM_INTERRUPT, - STREAM_ON, -}; - -struct zc0301_module_param { - u8 force_munmap; - u16 frame_timeout; -}; - -static DECLARE_RWSEM(zc0301_disconnect); - -struct zc0301_device { - struct video_device* v4ldev; - - struct zc0301_sensor sensor; - - struct usb_device* usbdev; - struct urb* urb[ZC0301_URBS]; - void* transfer_buffer[ZC0301_URBS]; - u8* control_buffer; - - struct zc0301_frame_t *frame_current, frame[ZC0301_MAX_FRAMES]; - struct list_head inqueue, outqueue; - u32 frame_count, nbuffers, nreadbuffers; - - enum zc0301_io_method io; - enum zc0301_stream_state stream; - - struct v4l2_jpegcompression compression; - - struct zc0301_module_param module_param; - - enum zc0301_dev_state state; - u8 users; - - struct mutex dev_mutex, fileop_mutex; - spinlock_t queue_lock; - wait_queue_head_t open, wait_frame, wait_stream; -}; - -/*****************************************************************************/ - -struct zc0301_device* -zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id) -{ - return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL; -} - -void -zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor) -{ - memcpy(&cam->sensor, sensor, sizeof(struct zc0301_sensor)); -} - -/*****************************************************************************/ - -#undef DBG -#undef KDBG -#ifdef ZC0301_DEBUG -# define DBG(level, fmt, args...) \ -do { \ - if (debug >= (level)) { \ - if ((level) == 1) \ - dev_err(&cam->usbdev->dev, fmt "\n", ## args); \ - else if ((level) == 2) \ - dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ - else if ((level) >= 3) \ - dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args); \ - } \ -} while (0) -# define KDBG(level, fmt, args...) \ -do { \ - if (debug >= (level)) { \ - if ((level) == 1 || (level) == 2) \ - pr_info("zc0301: " fmt "\n", ## args); \ - else if ((level) == 3) \ - pr_debug("zc0301: [%s:%d] " fmt "\n", __FUNCTION__, \ - __LINE__ , ## args); \ - } \ -} while (0) -# define V4LDBG(level, name, cmd) \ -do { \ - if (debug >= (level)) \ - v4l_print_ioctl(name, cmd); \ -} while (0) -#else -# define DBG(level, fmt, args...) do {;} while(0) -# define KDBG(level, fmt, args...) do {;} while(0) -# define V4LDBG(level, name, cmd) do {;} while(0) -#endif - -#undef PDBG -#define PDBG(fmt, args...) \ -dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args) - -#undef PDBGG -#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ - -#endif /* _ZC0301_H_ */ diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c deleted file mode 100644 index 0fad39754..000000000 --- a/drivers/media/video/zc0301/zc0301_core.c +++ /dev/null @@ -1,2055 +0,0 @@ -/*************************************************************************** - * Video4Linux2 driver for ZC0301 Image Processor and Control Chip * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * Informations about the chip internals needed to enable the I2C protocol * - * have been taken from the documentation of the ZC030x Video4Linux1 * - * driver written by Andrew Birkett * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "zc0301.h" - -/*****************************************************************************/ - -#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301 " \ - "Image Processor and Control Chip" -#define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" -#define ZC0301_AUTHOR_EMAIL "" -#define ZC0301_MODULE_LICENSE "GPL" -#define ZC0301_MODULE_VERSION "1:1.03" -#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 3) - -/*****************************************************************************/ - -MODULE_DEVICE_TABLE(usb, zc0301_id_table); - -MODULE_AUTHOR(ZC0301_MODULE_AUTHOR " " ZC0301_AUTHOR_EMAIL); -MODULE_DESCRIPTION(ZC0301_MODULE_NAME); -MODULE_VERSION(ZC0301_MODULE_VERSION); -MODULE_LICENSE(ZC0301_MODULE_LICENSE); - -static short video_nr[] = {[0 ... ZC0301_MAX_DEVICES-1] = -1}; -module_param_array(video_nr, short, NULL, 0444); -MODULE_PARM_DESC(video_nr, - "\n<-1|n[,...]> Specify V4L2 minor mode number." - "\n -1 = use next available (default)" - "\n n = use minor number n (integer >= 0)" - "\nYou can specify up to " - __MODULE_STRING(ZC0301_MAX_DEVICES) " cameras this way." - "\nFor example:" - "\nvideo_nr=-1,2,-1 would assign minor number 2 to" - "\nthe second registered camera and use auto for the first" - "\none and for every other camera." - "\n"); - -static short force_munmap[] = {[0 ... ZC0301_MAX_DEVICES-1] = - ZC0301_FORCE_MUNMAP}; -module_param_array(force_munmap, bool, NULL, 0444); -MODULE_PARM_DESC(force_munmap, - "\n<0|1[,...]> Force the application to unmap previously" - "\nmapped buffer memory before calling any VIDIOC_S_CROP or" - "\nVIDIOC_S_FMT ioctl's. Not all the applications support" - "\nthis feature. This parameter is specific for each" - "\ndetected camera." - "\n 0 = do not force memory unmapping" - "\n 1 = force memory unmapping (save memory)" - "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." - "\n"); - -static unsigned int frame_timeout[] = {[0 ... ZC0301_MAX_DEVICES-1] = - ZC0301_FRAME_TIMEOUT}; -module_param_array(frame_timeout, uint, NULL, 0644); -MODULE_PARM_DESC(frame_timeout, - "\n Timeout for a video frame in seconds." - "\nThis parameter is specific for each detected camera." - "\nDefault value is "__MODULE_STRING(ZC0301_FRAME_TIMEOUT)"." - "\n"); - -#ifdef ZC0301_DEBUG -static unsigned short debug = ZC0301_DEBUG_LEVEL; -module_param(debug, ushort, 0644); -MODULE_PARM_DESC(debug, - "\n Debugging information level, from 0 to 3:" - "\n0 = none (use carefully)" - "\n1 = critical errors" - "\n2 = significant informations" - "\n3 = more verbose messages" - "\nLevel 3 is useful for testing only, when only " - "one device is used." - "\nDefault value is "__MODULE_STRING(ZC0301_DEBUG_LEVEL)"." - "\n"); -#endif - -/*****************************************************************************/ - -static u32 -zc0301_request_buffers(struct zc0301_device* cam, u32 count, - enum zc0301_io_method io) -{ - struct v4l2_pix_format* p = &(cam->sensor.pix_format); - struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); - const size_t imagesize = cam->module_param.force_munmap || - io == IO_READ ? - (p->width * p->height * p->priv) / 8 : - (r->width * r->height * p->priv) / 8; - void* buff = NULL; - u32 i; - - if (count > ZC0301_MAX_FRAMES) - count = ZC0301_MAX_FRAMES; - - cam->nbuffers = count; - while (cam->nbuffers > 0) { - if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize)))) - break; - cam->nbuffers--; - } - - for (i = 0; i < cam->nbuffers; i++) { - cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize); - cam->frame[i].buf.index = i; - cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize); - cam->frame[i].buf.length = imagesize; - cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cam->frame[i].buf.sequence = 0; - cam->frame[i].buf.field = V4L2_FIELD_NONE; - cam->frame[i].buf.memory = V4L2_MEMORY_MMAP; - cam->frame[i].buf.flags = 0; - } - - return cam->nbuffers; -} - - -static void zc0301_release_buffers(struct zc0301_device* cam) -{ - if (cam->nbuffers) { - vfree(cam->frame[0].bufmem); - cam->nbuffers = 0; - } - cam->frame_current = NULL; -} - - -static void zc0301_empty_framequeues(struct zc0301_device* cam) -{ - u32 i; - - INIT_LIST_HEAD(&cam->inqueue); - INIT_LIST_HEAD(&cam->outqueue); - - for (i = 0; i < ZC0301_MAX_FRAMES; i++) { - cam->frame[i].state = F_UNUSED; - cam->frame[i].buf.bytesused = 0; - } -} - - -static void zc0301_requeue_outqueue(struct zc0301_device* cam) -{ - struct zc0301_frame_t *i; - - list_for_each_entry(i, &cam->outqueue, frame) { - i->state = F_QUEUED; - list_add(&i->frame, &cam->inqueue); - } - - INIT_LIST_HEAD(&cam->outqueue); -} - - -static void zc0301_queue_unusedframes(struct zc0301_device* cam) -{ - unsigned long lock_flags; - u32 i; - - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].state == F_UNUSED) { - cam->frame[i].state = F_QUEUED; - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_add_tail(&cam->frame[i].frame, &cam->inqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - } -} - -/*****************************************************************************/ - -int zc0301_write_reg(struct zc0301_device* cam, u16 index, u16 value) -{ - struct usb_device* udev = cam->usbdev; - int res; - - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0xa0, 0x40, - value, index, NULL, 0, ZC0301_CTRL_TIMEOUT); - if (res < 0) { - DBG(3, "Failed to write a register (index 0x%04X, " - "value 0x%02X, error %d)",index, value, res); - return -1; - } - - return 0; -} - - -int zc0301_read_reg(struct zc0301_device* cam, u16 index) -{ - struct usb_device* udev = cam->usbdev; - u8* buff = cam->control_buffer; - int res; - - res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0xa1, 0xc0, - 0x0001, index, buff, 1, ZC0301_CTRL_TIMEOUT); - if (res < 0) - DBG(3, "Failed to read a register (index 0x%04X, error %d)", - index, res); - - PDBGG("Read: index 0x%04X, value: 0x%04X", index, (int)(*buff)); - - return (res >= 0) ? (int)(*buff) : -1; -} - - -int zc0301_i2c_read(struct zc0301_device* cam, u16 address, u8 length) -{ - int err = 0, res, r0, r1; - - err += zc0301_write_reg(cam, 0x0092, address); - err += zc0301_write_reg(cam, 0x0090, 0x02); - - msleep(1); - - res = zc0301_read_reg(cam, 0x0091); - if (res < 0) - err += res; - r0 = zc0301_read_reg(cam, 0x0095); - if (r0 < 0) - err += r0; - r1 = zc0301_read_reg(cam, 0x0096); - if (r1 < 0) - err += r1; - - res = (length <= 1) ? r0 : r0 | (r1 << 8); - - if (err) - DBG(3, "I2C read failed at address 0x%04X, value: 0x%04X", - address, res); - - - PDBGG("I2C read: address 0x%04X, value: 0x%04X", address, res); - - return err ? -1 : res; -} - - -int zc0301_i2c_write(struct zc0301_device* cam, u16 address, u16 value) -{ - int err = 0, res; - - err += zc0301_write_reg(cam, 0x0092, address); - err += zc0301_write_reg(cam, 0x0093, value & 0xff); - err += zc0301_write_reg(cam, 0x0094, value >> 8); - err += zc0301_write_reg(cam, 0x0090, 0x01); - - msleep(1); - - res = zc0301_read_reg(cam, 0x0091); - if (res < 0) - err += res; - - if (err) - DBG(3, "I2C write failed at address 0x%04X, value: 0x%04X", - address, value); - - PDBGG("I2C write: address 0x%04X, value: 0x%04X", address, value); - - return err ? -1 : 0; -} - -/*****************************************************************************/ - -static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs) -{ - struct zc0301_device* cam = urb->context; - struct zc0301_frame_t** f; - size_t imagesize; - u8 i; - int err = 0; - - if (urb->status == -ENOENT) - return; - - f = &cam->frame_current; - - if (cam->stream == STREAM_INTERRUPT) { - cam->stream = STREAM_OFF; - if ((*f)) - (*f)->state = F_QUEUED; - DBG(3, "Stream interrupted"); - wake_up(&cam->wait_stream); - } - - if (cam->state & DEV_DISCONNECTED) - return; - - if (cam->state & DEV_MISCONFIGURED) { - wake_up_interruptible(&cam->wait_frame); - return; - } - - if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue)) - goto resubmit_urb; - - if (!(*f)) - (*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t, - frame); - - imagesize = (cam->sensor.pix_format.width * - cam->sensor.pix_format.height * - cam->sensor.pix_format.priv) / 8; - - for (i = 0; i < urb->number_of_packets; i++) { - unsigned int len, status; - void *pos; - u16* soi; - u8 sof; - - len = urb->iso_frame_desc[i].actual_length; - status = urb->iso_frame_desc[i].status; - pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer; - - if (status) { - DBG(3, "Error in isochronous frame"); - (*f)->state = F_ERROR; - continue; - } - - sof = (*(soi = pos) == 0xd8ff); - - PDBGG("Isochrnous frame: length %u, #%u i,", len, i); - - if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) -start_of_frame: - if (sof) { - (*f)->state = F_GRABBING; - (*f)->buf.bytesused = 0; - do_gettimeofday(&(*f)->buf.timestamp); - DBG(3, "SOF detected: new video frame"); - } - - if ((*f)->state == F_GRABBING) { - if (sof && (*f)->buf.bytesused) - goto end_of_frame; - - if ((*f)->buf.bytesused + len > imagesize) { - DBG(3, "Video frame size exceeded"); - (*f)->state = F_ERROR; - continue; - } - - memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, len); - (*f)->buf.bytesused += len; - - if ((*f)->buf.bytesused == imagesize) { - u32 b; -end_of_frame: - b = (*f)->buf.bytesused; - (*f)->state = F_DONE; - (*f)->buf.sequence= ++cam->frame_count; - spin_lock(&cam->queue_lock); - list_move_tail(&(*f)->frame, &cam->outqueue); - if (!list_empty(&cam->inqueue)) - (*f) = list_entry(cam->inqueue.next, - struct zc0301_frame_t, - frame); - else - (*f) = NULL; - spin_unlock(&cam->queue_lock); - DBG(3, "Video frame captured: : %lu bytes", - (unsigned long)(b)); - - if (!(*f)) - goto resubmit_urb; - - if (sof) - goto start_of_frame; - } - } - } - -resubmit_urb: - urb->dev = cam->usbdev; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0 && err != -EPERM) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "usb_submit_urb() failed"); - } - - wake_up_interruptible(&cam->wait_frame); -} - - -static int zc0301_start_transfer(struct zc0301_device* cam) -{ - struct usb_device *udev = cam->usbdev; - struct urb* urb; - const unsigned int wMaxPacketSize[] = {0, 128, 192, 256, 384, - 512, 768, 1023}; - const unsigned int psz = wMaxPacketSize[ZC0301_ALTERNATE_SETTING]; - s8 i, j; - int err = 0; - - for (i = 0; i < ZC0301_URBS; i++) { - cam->transfer_buffer[i] = kzalloc(ZC0301_ISO_PACKETS * psz, - GFP_KERNEL); - if (!cam->transfer_buffer[i]) { - err = -ENOMEM; - DBG(1, "Not enough memory"); - goto free_buffers; - } - } - - for (i = 0; i < ZC0301_URBS; i++) { - urb = usb_alloc_urb(ZC0301_ISO_PACKETS, GFP_KERNEL); - cam->urb[i] = urb; - if (!urb) { - err = -ENOMEM; - DBG(1, "usb_alloc_urb() failed"); - goto free_urbs; - } - urb->dev = udev; - urb->context = cam; - urb->pipe = usb_rcvisocpipe(udev, 1); - urb->transfer_flags = URB_ISO_ASAP; - urb->number_of_packets = ZC0301_ISO_PACKETS; - urb->complete = zc0301_urb_complete; - urb->transfer_buffer = cam->transfer_buffer[i]; - urb->transfer_buffer_length = psz * ZC0301_ISO_PACKETS; - urb->interval = 1; - for (j = 0; j < ZC0301_ISO_PACKETS; j++) { - urb->iso_frame_desc[j].offset = psz * j; - urb->iso_frame_desc[j].length = psz; - } - } - - err = usb_set_interface(udev, 0, ZC0301_ALTERNATE_SETTING); - if (err) { - DBG(1, "usb_set_interface() failed"); - goto free_urbs; - } - - cam->frame_current = NULL; - - for (i = 0; i < ZC0301_URBS; i++) { - err = usb_submit_urb(cam->urb[i], GFP_KERNEL); - if (err) { - for (j = i-1; j >= 0; j--) - usb_kill_urb(cam->urb[j]); - DBG(1, "usb_submit_urb() failed, error %d", err); - goto free_urbs; - } - } - - return 0; - -free_urbs: - for (i = 0; (i < ZC0301_URBS) && cam->urb[i]; i++) - usb_free_urb(cam->urb[i]); - -free_buffers: - for (i = 0; (i < ZC0301_URBS) && cam->transfer_buffer[i]; i++) - kfree(cam->transfer_buffer[i]); - - return err; -} - - -static int zc0301_stop_transfer(struct zc0301_device* cam) -{ - struct usb_device *udev = cam->usbdev; - s8 i; - int err = 0; - - if (cam->state & DEV_DISCONNECTED) - return 0; - - for (i = ZC0301_URBS-1; i >= 0; i--) { - usb_kill_urb(cam->urb[i]); - usb_free_urb(cam->urb[i]); - kfree(cam->transfer_buffer[i]); - } - - err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */ - if (err) - DBG(3, "usb_set_interface() failed"); - - return err; -} - - -static int zc0301_stream_interrupt(struct zc0301_device* cam) -{ - long timeout; - - cam->stream = STREAM_INTERRUPT; - timeout = wait_event_timeout(cam->wait_stream, - (cam->stream == STREAM_OFF) || - (cam->state & DEV_DISCONNECTED), - ZC0301_URB_TIMEOUT); - if (cam->state & DEV_DISCONNECTED) - return -ENODEV; - else if (cam->stream != STREAM_OFF) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "URB timeout reached. The camera is misconfigured. To " - "use it, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -EIO; - } - - return 0; -} - -/*****************************************************************************/ - -static int -zc0301_set_compression(struct zc0301_device* cam, - struct v4l2_jpegcompression* compression) -{ - int r, err = 0; - - if ((r = zc0301_read_reg(cam, 0x0008)) < 0) - err += r; - err += zc0301_write_reg(cam, 0x0008, r | 0x11 | compression->quality); - - return err ? -EIO : 0; -} - - -static int zc0301_init(struct zc0301_device* cam) -{ - struct zc0301_sensor* s = &cam->sensor; - struct v4l2_control ctrl; - struct v4l2_queryctrl *qctrl; - struct v4l2_rect* rect; - u8 i = 0; - int err = 0; - - if (!(cam->state & DEV_INITIALIZED)) { - init_waitqueue_head(&cam->open); - qctrl = s->qctrl; - rect = &(s->cropcap.defrect); - cam->compression.quality = ZC0301_COMPRESSION_QUALITY; - } else { /* use current values */ - qctrl = s->_qctrl; - rect = &(s->_rect); - } - - if (s->init) { - err = s->init(cam); - if (err) { - DBG(3, "Sensor initialization failed"); - return err; - } - } - - if ((err = zc0301_set_compression(cam, &cam->compression))) { - DBG(3, "set_compression() failed"); - return err; - } - - if (s->set_crop) - if ((err = s->set_crop(cam, rect))) { - DBG(3, "set_crop() failed"); - return err; - } - - if (s->set_ctrl) { - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (s->qctrl[i].id != 0 && - !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { - ctrl.id = s->qctrl[i].id; - ctrl.value = qctrl[i].default_value; - err = s->set_ctrl(cam, &ctrl); - if (err) { - DBG(3, "Set %s control failed", - s->qctrl[i].name); - return err; - } - DBG(3, "Image sensor supports '%s' control", - s->qctrl[i].name); - } - } - - if (!(cam->state & DEV_INITIALIZED)) { - mutex_init(&cam->fileop_mutex); - spin_lock_init(&cam->queue_lock); - init_waitqueue_head(&cam->wait_frame); - init_waitqueue_head(&cam->wait_stream); - cam->nreadbuffers = 2; - memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); - memcpy(&(s->_rect), &(s->cropcap.defrect), - sizeof(struct v4l2_rect)); - cam->state |= DEV_INITIALIZED; - } - - DBG(2, "Initialization succeeded"); - return 0; -} - - -static void zc0301_release_resources(struct zc0301_device* cam) -{ - DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); - video_set_drvdata(cam->v4ldev, NULL); - video_unregister_device(cam->v4ldev); - kfree(cam->control_buffer); -} - -/*****************************************************************************/ - -static int zc0301_open(struct inode* inode, struct file* filp) -{ - struct zc0301_device* cam; - int err = 0; - - /* - This is the only safe way to prevent race conditions with - disconnect - */ - if (!down_read_trylock(&zc0301_disconnect)) - return -ERESTARTSYS; - - cam = video_get_drvdata(video_devdata(filp)); - - if (mutex_lock_interruptible(&cam->dev_mutex)) { - up_read(&zc0301_disconnect); - return -ERESTARTSYS; - } - - if (cam->users) { - DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); - if ((filp->f_flags & O_NONBLOCK) || - (filp->f_flags & O_NDELAY)) { - err = -EWOULDBLOCK; - goto out; - } - mutex_unlock(&cam->dev_mutex); - err = wait_event_interruptible_exclusive(cam->open, - cam->state & DEV_DISCONNECTED - || !cam->users); - if (err) { - up_read(&zc0301_disconnect); - return err; - } - if (cam->state & DEV_DISCONNECTED) { - up_read(&zc0301_disconnect); - return -ENODEV; - } - mutex_lock(&cam->dev_mutex); - } - - - if (cam->state & DEV_MISCONFIGURED) { - err = zc0301_init(cam); - if (err) { - DBG(1, "Initialization failed again. " - "I will retry on next open()."); - goto out; - } - cam->state &= ~DEV_MISCONFIGURED; - } - - if ((err = zc0301_start_transfer(cam))) - goto out; - - filp->private_data = cam; - cam->users++; - cam->io = IO_NONE; - cam->stream = STREAM_OFF; - cam->nbuffers = 0; - cam->frame_count = 0; - zc0301_empty_framequeues(cam); - - DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); - -out: - mutex_unlock(&cam->dev_mutex); - up_read(&zc0301_disconnect); - return err; -} - - -static int zc0301_release(struct inode* inode, struct file* filp) -{ - struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); - - mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ - - zc0301_stop_transfer(cam); - - zc0301_release_buffers(cam); - - if (cam->state & DEV_DISCONNECTED) { - zc0301_release_resources(cam); - usb_put_dev(cam->usbdev); - mutex_unlock(&cam->dev_mutex); - kfree(cam); - return 0; - } - - cam->users--; - wake_up_interruptible_nr(&cam->open, 1); - - DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); - - mutex_unlock(&cam->dev_mutex); - - return 0; -} - - -static ssize_t -zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) -{ - struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); - struct zc0301_frame_t* f, * i; - unsigned long lock_flags; - long timeout; - int err = 0; - - if (mutex_lock_interruptible(&cam->fileop_mutex)) - return -ERESTARTSYS; - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); - return -ENODEV; - } - - if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it " - "again."); - mutex_unlock(&cam->fileop_mutex); - return -EIO; - } - - if (cam->io == IO_MMAP) { - DBG(3, "Close and open the device again to choose the read " - "method"); - mutex_unlock(&cam->fileop_mutex); - return -EINVAL; - } - - if (cam->io == IO_NONE) { - if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) { - DBG(1, "read() failed, not enough memory"); - mutex_unlock(&cam->fileop_mutex); - return -ENOMEM; - } - cam->io = IO_READ; - cam->stream = STREAM_ON; - } - - if (list_empty(&cam->inqueue)) { - if (!list_empty(&cam->outqueue)) - zc0301_empty_framequeues(cam); - zc0301_queue_unusedframes(cam); - } - - if (!count) { - mutex_unlock(&cam->fileop_mutex); - return 0; - } - - if (list_empty(&cam->outqueue)) { - if (filp->f_flags & O_NONBLOCK) { - mutex_unlock(&cam->fileop_mutex); - return -EAGAIN; - } - timeout = wait_event_interruptible_timeout - ( cam->wait_frame, - (!list_empty(&cam->outqueue)) || - (cam->state & DEV_DISCONNECTED) || - (cam->state & DEV_MISCONFIGURED), - cam->module_param.frame_timeout * - 1000 * msecs_to_jiffies(1) ); - if (timeout < 0) { - mutex_unlock(&cam->fileop_mutex); - return timeout; - } - if (cam->state & DEV_DISCONNECTED) { - mutex_unlock(&cam->fileop_mutex); - return -ENODEV; - } - if (!timeout || (cam->state & DEV_MISCONFIGURED)) { - mutex_unlock(&cam->fileop_mutex); - return -EIO; - } - } - - f = list_entry(cam->outqueue.prev, struct zc0301_frame_t, frame); - - if (count > f->buf.bytesused) - count = f->buf.bytesused; - - if (copy_to_user(buf, f->bufmem, count)) { - err = -EFAULT; - goto exit; - } - *f_pos += count; - -exit: - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_for_each_entry(i, &cam->outqueue, frame) - i->state = F_UNUSED; - INIT_LIST_HEAD(&cam->outqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - - zc0301_queue_unusedframes(cam); - - PDBGG("Frame #%lu, bytes read: %zu", - (unsigned long)f->buf.index, count); - - mutex_unlock(&cam->fileop_mutex); - - return err ? err : count; -} - - -static unsigned int zc0301_poll(struct file *filp, poll_table *wait) -{ - struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); - struct zc0301_frame_t* f; - unsigned long lock_flags; - unsigned int mask = 0; - - if (mutex_lock_interruptible(&cam->fileop_mutex)) - return POLLERR; - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - goto error; - } - - if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it " - "again."); - goto error; - } - - if (cam->io == IO_NONE) { - if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) { - DBG(1, "poll() failed, not enough memory"); - goto error; - } - cam->io = IO_READ; - cam->stream = STREAM_ON; - } - - if (cam->io == IO_READ) { - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_for_each_entry(f, &cam->outqueue, frame) - f->state = F_UNUSED; - INIT_LIST_HEAD(&cam->outqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - zc0301_queue_unusedframes(cam); - } - - poll_wait(filp, &cam->wait_frame, wait); - - if (!list_empty(&cam->outqueue)) - mask |= POLLIN | POLLRDNORM; - - mutex_unlock(&cam->fileop_mutex); - - return mask; - -error: - mutex_unlock(&cam->fileop_mutex); - return POLLERR; -} - - -static void zc0301_vm_open(struct vm_area_struct* vma) -{ - struct zc0301_frame_t* f = vma->vm_private_data; - f->vma_use_count++; -} - - -static void zc0301_vm_close(struct vm_area_struct* vma) -{ - /* NOTE: buffers are not freed here */ - struct zc0301_frame_t* f = vma->vm_private_data; - f->vma_use_count--; -} - - -static struct vm_operations_struct zc0301_vm_ops = { - .open = zc0301_vm_open, - .close = zc0301_vm_close, -}; - - -static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma) -{ - struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); - unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start; - void *pos; - u32 i; - - if (mutex_lock_interruptible(&cam->fileop_mutex)) - return -ERESTARTSYS; - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); - return -ENODEV; - } - - if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it " - "again."); - mutex_unlock(&cam->fileop_mutex); - return -EIO; - } - - if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || - size != PAGE_ALIGN(cam->frame[0].buf.length)) { - mutex_unlock(&cam->fileop_mutex); - return -EINVAL; - } - - for (i = 0; i < cam->nbuffers; i++) { - if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff) - break; - } - if (i == cam->nbuffers) { - mutex_unlock(&cam->fileop_mutex); - return -EINVAL; - } - - vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; - - pos = cam->frame[i].bufmem; - while (size > 0) { /* size is page-aligned */ - if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { - mutex_unlock(&cam->fileop_mutex); - return -EAGAIN; - } - start += PAGE_SIZE; - pos += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vma->vm_ops = &zc0301_vm_ops; - vma->vm_private_data = &cam->frame[i]; - - zc0301_vm_open(vma); - - mutex_unlock(&cam->fileop_mutex); - - return 0; -} - -/*****************************************************************************/ - -static int -zc0301_vidioc_querycap(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_capability cap = { - .driver = "zc0301", - .version = ZC0301_MODULE_VERSION_CODE, - .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING, - }; - - strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); - if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) - strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, - sizeof(cap.bus_info)); - - if (copy_to_user(arg, &cap, sizeof(cap))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_enuminput(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_input i; - - if (copy_from_user(&i, arg, sizeof(i))) - return -EFAULT; - - if (i.index) - return -EINVAL; - - memset(&i, 0, sizeof(i)); - strcpy(i.name, "Camera"); - i.type = V4L2_INPUT_TYPE_CAMERA; - - if (copy_to_user(arg, &i, sizeof(i))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_g_input(struct zc0301_device* cam, void __user * arg) -{ - int index = 0; - - if (copy_to_user(arg, &index, sizeof(index))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_s_input(struct zc0301_device* cam, void __user * arg) -{ - int index; - - if (copy_from_user(&index, arg, sizeof(index))) - return -EFAULT; - - if (index != 0) - return -EINVAL; - - return 0; -} - - -static int -zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg) -{ - struct zc0301_sensor* s = &cam->sensor; - struct v4l2_queryctrl qc; - u8 i; - - if (copy_from_user(&qc, arg, sizeof(qc))) - return -EFAULT; - - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (qc.id && qc.id == s->qctrl[i].id) { - memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); - if (copy_to_user(arg, &qc, sizeof(qc))) - return -EFAULT; - return 0; - } - - return -EINVAL; -} - - -static int -zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg) -{ - struct zc0301_sensor* s = &cam->sensor; - struct v4l2_control ctrl; - int err = 0; - u8 i; - - if (!s->get_ctrl && !s->set_ctrl) - return -EINVAL; - - if (copy_from_user(&ctrl, arg, sizeof(ctrl))) - return -EFAULT; - - if (!s->get_ctrl) { - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (ctrl.id == s->qctrl[i].id) { - ctrl.value = s->_qctrl[i].default_value; - goto exit; - } - return -EINVAL; - } else - err = s->get_ctrl(cam, &ctrl); - -exit: - if (copy_to_user(arg, &ctrl, sizeof(ctrl))) - return -EFAULT; - - return err; -} - - -static int -zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg) -{ - struct zc0301_sensor* s = &cam->sensor; - struct v4l2_control ctrl; - u8 i; - int err = 0; - - if (!s->set_ctrl) - return -EINVAL; - - if (copy_from_user(&ctrl, arg, sizeof(ctrl))) - return -EFAULT; - - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (ctrl.id == s->qctrl[i].id) { - if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) - return -EINVAL; - if (ctrl.value < s->qctrl[i].minimum || - ctrl.value > s->qctrl[i].maximum) - return -ERANGE; - ctrl.value -= ctrl.value % s->qctrl[i].step; - break; - } - - if ((err = s->set_ctrl(cam, &ctrl))) - return err; - - s->_qctrl[i].default_value = ctrl.value; - - return 0; -} - - -static int -zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_cropcap* cc = &(cam->sensor.cropcap); - - cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cc->pixelaspect.numerator = 1; - cc->pixelaspect.denominator = 1; - - if (copy_to_user(arg, cc, sizeof(*cc))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg) -{ - struct zc0301_sensor* s = &cam->sensor; - struct v4l2_crop crop = { - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - }; - - memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect)); - - if (copy_to_user(arg, &crop, sizeof(crop))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) -{ - struct zc0301_sensor* s = &cam->sensor; - struct v4l2_crop crop; - struct v4l2_rect* rect; - struct v4l2_rect* bounds = &(s->cropcap.bounds); - const enum zc0301_stream_state stream = cam->stream; - const u32 nbuffers = cam->nbuffers; - u32 i; - int err = 0; - - if (copy_from_user(&crop, arg, sizeof(crop))) - return -EFAULT; - - rect = &(crop.c); - - if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (cam->module_param.force_munmap) - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_S_CROP failed. " - "Unmap the buffers first."); - return -EINVAL; - } - - if (!s->set_crop) { - memcpy(rect, &(s->_rect), sizeof(*rect)); - if (copy_to_user(arg, &crop, sizeof(crop))) - return -EFAULT; - return 0; - } - - rect->left &= ~7L; - rect->top &= ~7L; - if (rect->width < 8) - rect->width = 8; - if (rect->height < 8) - rect->height = 8; - if (rect->width > bounds->width) - rect->width = bounds->width; - if (rect->height > bounds->height) - rect->height = bounds->height; - if (rect->left < bounds->left) - rect->left = bounds->left; - if (rect->top < bounds->top) - rect->top = bounds->top; - if (rect->left + rect->width > bounds->left + bounds->width) - rect->left = bounds->left+bounds->width - rect->width; - if (rect->top + rect->height > bounds->top + bounds->height) - rect->top = bounds->top+bounds->height - rect->height; - rect->width &= ~7L; - rect->height &= ~7L; - - if (cam->stream == STREAM_ON) - if ((err = zc0301_stream_interrupt(cam))) - return err; - - if (copy_to_user(arg, &crop, sizeof(crop))) { - cam->stream = stream; - return -EFAULT; - } - - if (cam->module_param.force_munmap || cam->io == IO_READ) - zc0301_release_buffers(cam); - - if (s->set_crop) - err += s->set_crop(cam, rect); - - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -EIO; - } - - s->pix_format.width = rect->width; - s->pix_format.height = rect->height; - memcpy(&(s->_rect), rect, sizeof(*rect)); - - if ((cam->module_param.force_munmap || cam->io == IO_READ) && - nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -ENOMEM; - } - - if (cam->io == IO_READ) - zc0301_empty_framequeues(cam); - else if (cam->module_param.force_munmap) - zc0301_requeue_outqueue(cam); - - cam->stream = stream; - - return 0; -} - - -static int -zc0301_vidioc_enum_fmt(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_fmtdesc fmtd; - - if (copy_from_user(&fmtd, arg, sizeof(fmtd))) - return -EFAULT; - - if (fmtd.index == 0) { - strcpy(fmtd.description, "JPEG"); - fmtd.pixelformat = V4L2_PIX_FMT_JPEG; - fmtd.flags = V4L2_FMT_FLAG_COMPRESSED; - } else - return -EINVAL; - - fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memset(&fmtd.reserved, 0, sizeof(fmtd.reserved)); - - if (copy_to_user(arg, &fmtd, sizeof(fmtd))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_format format; - struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); - - if (copy_from_user(&format, arg, sizeof(format))) - return -EFAULT; - - if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - pfmt->bytesperline = 0; - pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); - pfmt->field = V4L2_FIELD_NONE; - memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt)); - - if (copy_to_user(arg, &format, sizeof(format))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, - void __user * arg) -{ - struct zc0301_sensor* s = &cam->sensor; - struct v4l2_format format; - struct v4l2_pix_format* pix; - struct v4l2_pix_format* pfmt = &(s->pix_format); - struct v4l2_rect* bounds = &(s->cropcap.bounds); - struct v4l2_rect rect; - const enum zc0301_stream_state stream = cam->stream; - const u32 nbuffers = cam->nbuffers; - u32 i; - int err = 0; - - if (copy_from_user(&format, arg, sizeof(format))) - return -EFAULT; - - pix = &(format.fmt.pix); - - if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - memcpy(&rect, &(s->_rect), sizeof(rect)); - - if (!s->set_crop) { - pix->width = rect.width; - pix->height = rect.height; - } else { - rect.width = pix->width; - rect.height = pix->height; - } - - if (rect.width < 8) - rect.width = 8; - if (rect.height < 8) - rect.height = 8; - if (rect.width > bounds->left + bounds->width - rect.left) - rect.width = bounds->left + bounds->width - rect.left; - if (rect.height > bounds->top + bounds->height - rect.top) - rect.height = bounds->top + bounds->height - rect.top; - rect.width &= ~7L; - rect.height &= ~7L; - - pix->width = rect.width; - pix->height = rect.height; - pix->pixelformat = pfmt->pixelformat; - pix->priv = pfmt->priv; - pix->colorspace = pfmt->colorspace; - pix->bytesperline = 0; - pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8); - pix->field = V4L2_FIELD_NONE; - - if (cmd == VIDIOC_TRY_FMT) { - if (copy_to_user(arg, &format, sizeof(format))) - return -EFAULT; - return 0; - } - - if (cam->module_param.force_munmap) - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_S_FMT failed. " - "Unmap the buffers first."); - return -EINVAL; - } - - if (cam->stream == STREAM_ON) - if ((err = zc0301_stream_interrupt(cam))) - return err; - - if (copy_to_user(arg, &format, sizeof(format))) { - cam->stream = stream; - return -EFAULT; - } - - if (cam->module_param.force_munmap || cam->io == IO_READ) - zc0301_release_buffers(cam); - - if (s->set_crop) - err += s->set_crop(cam, &rect); - - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -EIO; - } - - memcpy(pfmt, pix, sizeof(*pix)); - memcpy(&(s->_rect), &rect, sizeof(rect)); - - if ((cam->module_param.force_munmap || cam->io == IO_READ) && - nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -ENOMEM; - } - - if (cam->io == IO_READ) - zc0301_empty_framequeues(cam); - else if (cam->module_param.force_munmap) - zc0301_requeue_outqueue(cam); - - cam->stream = stream; - - return 0; -} - - -static int -zc0301_vidioc_g_jpegcomp(struct zc0301_device* cam, void __user * arg) -{ - if (copy_to_user(arg, &cam->compression, sizeof(cam->compression))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_jpegcompression jc; - const enum zc0301_stream_state stream = cam->stream; - int err = 0; - - if (copy_from_user(&jc, arg, sizeof(jc))) - return -EFAULT; - - if (jc.quality != 0) - return -EINVAL; - - if (cam->stream == STREAM_ON) - if ((err = zc0301_stream_interrupt(cam))) - return err; - - err += zc0301_set_compression(cam, &jc); - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " - "problems. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->minor); - return -EIO; - } - - cam->compression.quality = jc.quality; - - cam->stream = stream; - - return 0; -} - - -static int -zc0301_vidioc_reqbufs(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_requestbuffers rb; - u32 i; - int err; - - if (copy_from_user(&rb, arg, sizeof(rb))) - return -EFAULT; - - if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - rb.memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - if (cam->io == IO_READ) { - DBG(3, "Close and open the device again to choose the mmap " - "I/O method"); - return -EINVAL; - } - - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_REQBUFS failed. " - "Previous buffers are still mapped."); - return -EINVAL; - } - - if (cam->stream == STREAM_ON) - if ((err = zc0301_stream_interrupt(cam))) - return err; - - zc0301_empty_framequeues(cam); - - zc0301_release_buffers(cam); - if (rb.count) - rb.count = zc0301_request_buffers(cam, rb.count, IO_MMAP); - - if (copy_to_user(arg, &rb, sizeof(rb))) { - zc0301_release_buffers(cam); - cam->io = IO_NONE; - return -EFAULT; - } - - cam->io = rb.count ? IO_MMAP : IO_NONE; - - return 0; -} - - -static int -zc0301_vidioc_querybuf(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_buffer b; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b.index >= cam->nbuffers || cam->io != IO_MMAP) - return -EINVAL; - - memcpy(&b, &cam->frame[b.index].buf, sizeof(b)); - - if (cam->frame[b.index].vma_use_count) - b.flags |= V4L2_BUF_FLAG_MAPPED; - - if (cam->frame[b.index].state == F_DONE) - b.flags |= V4L2_BUF_FLAG_DONE; - else if (cam->frame[b.index].state != F_UNUSED) - b.flags |= V4L2_BUF_FLAG_QUEUED; - - if (copy_to_user(arg, &b, sizeof(b))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_qbuf(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_buffer b; - unsigned long lock_flags; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b.index >= cam->nbuffers || cam->io != IO_MMAP) - return -EINVAL; - - if (cam->frame[b.index].state != F_UNUSED) - return -EINVAL; - - cam->frame[b.index].state = F_QUEUED; - - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_add_tail(&cam->frame[b.index].frame, &cam->inqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - - PDBGG("Frame #%lu queued", (unsigned long)b.index); - - return 0; -} - - -static int -zc0301_vidioc_dqbuf(struct zc0301_device* cam, struct file* filp, - void __user * arg) -{ - struct v4l2_buffer b; - struct zc0301_frame_t *f; - unsigned long lock_flags; - long timeout; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP) - return -EINVAL; - - if (list_empty(&cam->outqueue)) { - if (cam->stream == STREAM_OFF) - return -EINVAL; - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - timeout = wait_event_interruptible_timeout - ( cam->wait_frame, - (!list_empty(&cam->outqueue)) || - (cam->state & DEV_DISCONNECTED) || - (cam->state & DEV_MISCONFIGURED), - cam->module_param.frame_timeout * - 1000 * msecs_to_jiffies(1) ); - if (timeout < 0) - return timeout; - if (cam->state & DEV_DISCONNECTED) - return -ENODEV; - if (!timeout || (cam->state & DEV_MISCONFIGURED)) - return -EIO; - } - - spin_lock_irqsave(&cam->queue_lock, lock_flags); - f = list_entry(cam->outqueue.next, struct zc0301_frame_t, frame); - list_del(cam->outqueue.next); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - - f->state = F_UNUSED; - - memcpy(&b, &f->buf, sizeof(b)); - if (f->vma_use_count) - b.flags |= V4L2_BUF_FLAG_MAPPED; - - if (copy_to_user(arg, &b, sizeof(b))) - return -EFAULT; - - PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index); - - return 0; -} - - -static int -zc0301_vidioc_streamon(struct zc0301_device* cam, void __user * arg) -{ - int type; - - if (copy_from_user(&type, arg, sizeof(type))) - return -EFAULT; - - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) - return -EINVAL; - - if (list_empty(&cam->inqueue)) - return -EINVAL; - - cam->stream = STREAM_ON; - - DBG(3, "Stream on"); - - return 0; -} - - -static int -zc0301_vidioc_streamoff(struct zc0301_device* cam, void __user * arg) -{ - int type, err; - - if (copy_from_user(&type, arg, sizeof(type))) - return -EFAULT; - - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) - return -EINVAL; - - if (cam->stream == STREAM_ON) - if ((err = zc0301_stream_interrupt(cam))) - return err; - - zc0301_empty_framequeues(cam); - - DBG(3, "Stream off"); - - return 0; -} - - -static int -zc0301_vidioc_g_parm(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_streamparm sp; - - if (copy_from_user(&sp, arg, sizeof(sp))) - return -EFAULT; - - if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - sp.parm.capture.extendedmode = 0; - sp.parm.capture.readbuffers = cam->nreadbuffers; - - if (copy_to_user(arg, &sp, sizeof(sp))) - return -EFAULT; - - return 0; -} - - -static int -zc0301_vidioc_s_parm(struct zc0301_device* cam, void __user * arg) -{ - struct v4l2_streamparm sp; - - if (copy_from_user(&sp, arg, sizeof(sp))) - return -EFAULT; - - if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - sp.parm.capture.extendedmode = 0; - - if (sp.parm.capture.readbuffers == 0) - sp.parm.capture.readbuffers = cam->nreadbuffers; - - if (sp.parm.capture.readbuffers > ZC0301_MAX_FRAMES) - sp.parm.capture.readbuffers = ZC0301_MAX_FRAMES; - - if (copy_to_user(arg, &sp, sizeof(sp))) - return -EFAULT; - - cam->nreadbuffers = sp.parm.capture.readbuffers; - - return 0; -} - - -static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, - unsigned int cmd, void __user * arg) -{ - struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); - - switch (cmd) { - - case VIDIOC_QUERYCAP: - return zc0301_vidioc_querycap(cam, arg); - - case VIDIOC_ENUMINPUT: - return zc0301_vidioc_enuminput(cam, arg); - - case VIDIOC_G_INPUT: - return zc0301_vidioc_g_input(cam, arg); - - case VIDIOC_S_INPUT: - return zc0301_vidioc_s_input(cam, arg); - - case VIDIOC_QUERYCTRL: - return zc0301_vidioc_query_ctrl(cam, arg); - - case VIDIOC_G_CTRL: - return zc0301_vidioc_g_ctrl(cam, arg); - - case VIDIOC_S_CTRL_OLD: - case VIDIOC_S_CTRL: - return zc0301_vidioc_s_ctrl(cam, arg); - - case VIDIOC_CROPCAP_OLD: - case VIDIOC_CROPCAP: - return zc0301_vidioc_cropcap(cam, arg); - - case VIDIOC_G_CROP: - return zc0301_vidioc_g_crop(cam, arg); - - case VIDIOC_S_CROP: - return zc0301_vidioc_s_crop(cam, arg); - - case VIDIOC_ENUM_FMT: - return zc0301_vidioc_enum_fmt(cam, arg); - - case VIDIOC_G_FMT: - return zc0301_vidioc_g_fmt(cam, arg); - - case VIDIOC_TRY_FMT: - case VIDIOC_S_FMT: - return zc0301_vidioc_try_s_fmt(cam, cmd, arg); - - case VIDIOC_G_JPEGCOMP: - return zc0301_vidioc_g_jpegcomp(cam, arg); - - case VIDIOC_S_JPEGCOMP: - return zc0301_vidioc_s_jpegcomp(cam, arg); - - case VIDIOC_REQBUFS: - return zc0301_vidioc_reqbufs(cam, arg); - - case VIDIOC_QUERYBUF: - return zc0301_vidioc_querybuf(cam, arg); - - case VIDIOC_QBUF: - return zc0301_vidioc_qbuf(cam, arg); - - case VIDIOC_DQBUF: - return zc0301_vidioc_dqbuf(cam, filp, arg); - - case VIDIOC_STREAMON: - return zc0301_vidioc_streamon(cam, arg); - - case VIDIOC_STREAMOFF: - return zc0301_vidioc_streamoff(cam, arg); - - case VIDIOC_G_PARM: - return zc0301_vidioc_g_parm(cam, arg); - - case VIDIOC_S_PARM_OLD: - case VIDIOC_S_PARM: - return zc0301_vidioc_s_parm(cam, arg); - - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case VIDIOC_QUERYSTD: - case VIDIOC_ENUMSTD: - case VIDIOC_QUERYMENU: - return -EINVAL; - - default: - return -EINVAL; - - } -} - - -static int zc0301_ioctl(struct inode* inode, struct file* filp, - unsigned int cmd, unsigned long arg) -{ - struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); - int err = 0; - - if (mutex_lock_interruptible(&cam->fileop_mutex)) - return -ERESTARTSYS; - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); - return -ENODEV; - } - - if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it " - "again."); - mutex_unlock(&cam->fileop_mutex); - return -EIO; - } - - V4LDBG(3, "zc0301", cmd); - - err = zc0301_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); - - mutex_unlock(&cam->fileop_mutex); - - return err; -} - - -static struct file_operations zc0301_fops = { - .owner = THIS_MODULE, - .open = zc0301_open, - .release = zc0301_release, - .ioctl = zc0301_ioctl, - .read = zc0301_read, - .poll = zc0301_poll, - .mmap = zc0301_mmap, - .llseek = no_llseek, -}; - -/*****************************************************************************/ - -static int -zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct zc0301_device* cam; - static unsigned int dev_nr = 0; - unsigned int i; - int err = 0; - - if (!(cam = kzalloc(sizeof(struct zc0301_device), GFP_KERNEL))) - return -ENOMEM; - - cam->usbdev = udev; - - if (!(cam->control_buffer = kzalloc(4, GFP_KERNEL))) { - DBG(1, "kmalloc() failed"); - err = -ENOMEM; - goto fail; - } - - if (!(cam->v4ldev = video_device_alloc())) { - DBG(1, "video_device_alloc() failed"); - err = -ENOMEM; - goto fail; - } - - mutex_init(&cam->dev_mutex); - - DBG(2, "ZC0301 Image Processor and Control Chip detected " - "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); - - for (i = 0; zc0301_sensor_table[i]; i++) { - err = zc0301_sensor_table[i](cam); - if (!err) - break; - } - - if (!err) - DBG(2, "%s image sensor detected", cam->sensor.name); - else { - DBG(1, "No supported image sensor detected"); - err = -ENODEV; - goto fail; - } - - if (zc0301_init(cam)) { - DBG(1, "Initialization failed. I will retry on open()."); - cam->state |= DEV_MISCONFIGURED; - } - - strcpy(cam->v4ldev->name, "ZC0301 PC Camera"); - cam->v4ldev->owner = THIS_MODULE; - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; - cam->v4ldev->hardware = 0; - cam->v4ldev->fops = &zc0301_fops; - cam->v4ldev->minor = video_nr[dev_nr]; - cam->v4ldev->release = video_device_release; - video_set_drvdata(cam->v4ldev, cam); - - mutex_lock(&cam->dev_mutex); - - err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, - video_nr[dev_nr]); - if (err) { - DBG(1, "V4L2 device registration failed"); - if (err == -ENFILE && video_nr[dev_nr] == -1) - DBG(1, "Free /dev/videoX node not found"); - video_nr[dev_nr] = -1; - dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; - mutex_unlock(&cam->dev_mutex); - goto fail; - } - - DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); - - cam->module_param.force_munmap = force_munmap[dev_nr]; - cam->module_param.frame_timeout = frame_timeout[dev_nr]; - - dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; - - usb_set_intfdata(intf, cam); - - mutex_unlock(&cam->dev_mutex); - - return 0; - -fail: - if (cam) { - kfree(cam->control_buffer); - if (cam->v4ldev) - video_device_release(cam->v4ldev); - kfree(cam); - } - return err; -} - - -static void zc0301_usb_disconnect(struct usb_interface* intf) -{ - struct zc0301_device* cam = usb_get_intfdata(intf); - - if (!cam) - return; - - down_write(&zc0301_disconnect); - - mutex_lock(&cam->dev_mutex); - - DBG(2, "Disconnecting %s...", cam->v4ldev->name); - - wake_up_interruptible_all(&cam->open); - - if (cam->users) { - DBG(2, "Device /dev/video%d is open! Deregistration and " - "memory deallocation are deferred on close.", - cam->v4ldev->minor); - cam->state |= DEV_MISCONFIGURED; - zc0301_stop_transfer(cam); - cam->state |= DEV_DISCONNECTED; - wake_up_interruptible(&cam->wait_frame); - wake_up(&cam->wait_stream); - usb_get_dev(cam->usbdev); - } else { - cam->state |= DEV_DISCONNECTED; - zc0301_release_resources(cam); - } - - mutex_unlock(&cam->dev_mutex); - - if (!cam->users) - kfree(cam); - - up_write(&zc0301_disconnect); -} - - -static struct usb_driver zc0301_usb_driver = { - .name = "zc0301", - .id_table = zc0301_id_table, - .probe = zc0301_usb_probe, - .disconnect = zc0301_usb_disconnect, -}; - -/*****************************************************************************/ - -static int __init zc0301_module_init(void) -{ - int err = 0; - - KDBG(2, ZC0301_MODULE_NAME " v" ZC0301_MODULE_VERSION); - KDBG(3, ZC0301_MODULE_AUTHOR); - - if ((err = usb_register(&zc0301_usb_driver))) - KDBG(1, "usb_register() failed"); - - return err; -} - - -static void __exit zc0301_module_exit(void) -{ - usb_deregister(&zc0301_usb_driver); -} - - -module_init(zc0301_module_init); -module_exit(zc0301_module_exit); diff --git a/drivers/media/video/zc0301/zc0301_pas202bcb.c b/drivers/media/video/zc0301/zc0301_pas202bcb.c deleted file mode 100644 index eaadf0252..000000000 --- a/drivers/media/video/zc0301/zc0301_pas202bcb.c +++ /dev/null @@ -1,361 +0,0 @@ -/*************************************************************************** - * Plug-in for PAS202BCB image sensor connected to the ZC030! Image * - * Processor and Control Chip * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * Initialization values of the ZC0301 have been taken from the SPCA5XX * - * driver maintained by Michel Xhaard * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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: Sensor controls are disabled for now, becouse changing them while - streaming sometimes results in out-of-sync video frames. We'll use - the default initialization, until we know how to stop and start video - in the chip. However, the image quality still looks good under various - light conditions. -*/ - -#include -#include "zc0301_sensor.h" - - -static struct zc0301_sensor pas202bcb; - - -static int pas202bcb_init(struct zc0301_device* cam) -{ - int err = 0; - - err += zc0301_write_reg(cam, 0x0002, 0x00); - err += zc0301_write_reg(cam, 0x0003, 0x02); - err += zc0301_write_reg(cam, 0x0004, 0x80); - err += zc0301_write_reg(cam, 0x0005, 0x01); - err += zc0301_write_reg(cam, 0x0006, 0xE0); - err += zc0301_write_reg(cam, 0x0098, 0x00); - err += zc0301_write_reg(cam, 0x009A, 0x03); - err += zc0301_write_reg(cam, 0x011A, 0x00); - err += zc0301_write_reg(cam, 0x011C, 0x03); - err += zc0301_write_reg(cam, 0x009B, 0x01); - err += zc0301_write_reg(cam, 0x009C, 0xE6); - err += zc0301_write_reg(cam, 0x009D, 0x02); - err += zc0301_write_reg(cam, 0x009E, 0x86); - - err += zc0301_i2c_write(cam, 0x02, 0x02); - err += zc0301_i2c_write(cam, 0x0A, 0x01); - err += zc0301_i2c_write(cam, 0x0B, 0x01); - err += zc0301_i2c_write(cam, 0x0D, 0x00); - err += zc0301_i2c_write(cam, 0x12, 0x05); - err += zc0301_i2c_write(cam, 0x13, 0x63); - err += zc0301_i2c_write(cam, 0x15, 0x70); - - err += zc0301_write_reg(cam, 0x0101, 0xB7); - err += zc0301_write_reg(cam, 0x0100, 0x0D); - err += zc0301_write_reg(cam, 0x0189, 0x06); - err += zc0301_write_reg(cam, 0x01AD, 0x00); - err += zc0301_write_reg(cam, 0x01C5, 0x03); - err += zc0301_write_reg(cam, 0x01CB, 0x13); - err += zc0301_write_reg(cam, 0x0250, 0x08); - err += zc0301_write_reg(cam, 0x0301, 0x08); - err += zc0301_write_reg(cam, 0x018D, 0x70); - err += zc0301_write_reg(cam, 0x0008, 0x03); - err += zc0301_write_reg(cam, 0x01C6, 0x04); - err += zc0301_write_reg(cam, 0x01CB, 0x07); - err += zc0301_write_reg(cam, 0x0120, 0x11); - err += zc0301_write_reg(cam, 0x0121, 0x37); - err += zc0301_write_reg(cam, 0x0122, 0x58); - err += zc0301_write_reg(cam, 0x0123, 0x79); - err += zc0301_write_reg(cam, 0x0124, 0x91); - err += zc0301_write_reg(cam, 0x0125, 0xA6); - err += zc0301_write_reg(cam, 0x0126, 0xB8); - err += zc0301_write_reg(cam, 0x0127, 0xC7); - err += zc0301_write_reg(cam, 0x0128, 0xD3); - err += zc0301_write_reg(cam, 0x0129, 0xDE); - err += zc0301_write_reg(cam, 0x012A, 0xE6); - err += zc0301_write_reg(cam, 0x012B, 0xED); - err += zc0301_write_reg(cam, 0x012C, 0xF3); - err += zc0301_write_reg(cam, 0x012D, 0xF8); - err += zc0301_write_reg(cam, 0x012E, 0xFB); - err += zc0301_write_reg(cam, 0x012F, 0xFF); - err += zc0301_write_reg(cam, 0x0130, 0x26); - err += zc0301_write_reg(cam, 0x0131, 0x23); - err += zc0301_write_reg(cam, 0x0132, 0x20); - err += zc0301_write_reg(cam, 0x0133, 0x1C); - err += zc0301_write_reg(cam, 0x0134, 0x16); - err += zc0301_write_reg(cam, 0x0135, 0x13); - err += zc0301_write_reg(cam, 0x0136, 0x10); - err += zc0301_write_reg(cam, 0x0137, 0x0D); - err += zc0301_write_reg(cam, 0x0138, 0x0B); - err += zc0301_write_reg(cam, 0x0139, 0x09); - err += zc0301_write_reg(cam, 0x013A, 0x07); - err += zc0301_write_reg(cam, 0x013B, 0x06); - err += zc0301_write_reg(cam, 0x013C, 0x05); - err += zc0301_write_reg(cam, 0x013D, 0x04); - err += zc0301_write_reg(cam, 0x013E, 0x03); - err += zc0301_write_reg(cam, 0x013F, 0x02); - err += zc0301_write_reg(cam, 0x010A, 0x4C); - err += zc0301_write_reg(cam, 0x010B, 0xF5); - err += zc0301_write_reg(cam, 0x010C, 0xFF); - err += zc0301_write_reg(cam, 0x010D, 0xF9); - err += zc0301_write_reg(cam, 0x010E, 0x51); - err += zc0301_write_reg(cam, 0x010F, 0xF5); - err += zc0301_write_reg(cam, 0x0110, 0xFB); - err += zc0301_write_reg(cam, 0x0111, 0xED); - err += zc0301_write_reg(cam, 0x0112, 0x5F); - err += zc0301_write_reg(cam, 0x0180, 0x00); - err += zc0301_write_reg(cam, 0x0019, 0x00); - err += zc0301_write_reg(cam, 0x0087, 0x20); - err += zc0301_write_reg(cam, 0x0088, 0x21); - - err += zc0301_i2c_write(cam, 0x20, 0x02); - err += zc0301_i2c_write(cam, 0x21, 0x1B); - err += zc0301_i2c_write(cam, 0x03, 0x44); - err += zc0301_i2c_write(cam, 0x0E, 0x01); - err += zc0301_i2c_write(cam, 0x0F, 0x00); - - err += zc0301_write_reg(cam, 0x01A9, 0x14); - err += zc0301_write_reg(cam, 0x01AA, 0x24); - err += zc0301_write_reg(cam, 0x0190, 0x00); - err += zc0301_write_reg(cam, 0x0191, 0x02); - err += zc0301_write_reg(cam, 0x0192, 0x1B); - err += zc0301_write_reg(cam, 0x0195, 0x00); - err += zc0301_write_reg(cam, 0x0196, 0x00); - err += zc0301_write_reg(cam, 0x0197, 0x4D); - err += zc0301_write_reg(cam, 0x018C, 0x10); - err += zc0301_write_reg(cam, 0x018F, 0x20); - err += zc0301_write_reg(cam, 0x001D, 0x44); - err += zc0301_write_reg(cam, 0x001E, 0x6F); - err += zc0301_write_reg(cam, 0x001F, 0xAD); - err += zc0301_write_reg(cam, 0x0020, 0xEB); - err += zc0301_write_reg(cam, 0x0087, 0x0F); - err += zc0301_write_reg(cam, 0x0088, 0x0E); - err += zc0301_write_reg(cam, 0x0180, 0x40); - err += zc0301_write_reg(cam, 0x0192, 0x1B); - err += zc0301_write_reg(cam, 0x0191, 0x02); - err += zc0301_write_reg(cam, 0x0190, 0x00); - err += zc0301_write_reg(cam, 0x0116, 0x1D); - err += zc0301_write_reg(cam, 0x0117, 0x40); - err += zc0301_write_reg(cam, 0x0118, 0x99); - err += zc0301_write_reg(cam, 0x0180, 0x42); - err += zc0301_write_reg(cam, 0x0116, 0x1D); - err += zc0301_write_reg(cam, 0x0117, 0x40); - err += zc0301_write_reg(cam, 0x0118, 0x99); - err += zc0301_write_reg(cam, 0x0007, 0x00); - - err += zc0301_i2c_write(cam, 0x11, 0x01); - - msleep(100); - - return err; -} - - -static int pas202bcb_get_ctrl(struct zc0301_device* cam, - struct v4l2_control* ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_EXPOSURE: - { - int r1 = zc0301_i2c_read(cam, 0x04, 1), - r2 = zc0301_i2c_read(cam, 0x05, 1); - if (r1 < 0 || r2 < 0) - return -EIO; - ctrl->value = (r1 << 6) | (r2 & 0x3f); - } - return 0; - case V4L2_CID_RED_BALANCE: - if ((ctrl->value = zc0301_i2c_read(cam, 0x09, 1)) < 0) - return -EIO; - ctrl->value &= 0x0f; - return 0; - case V4L2_CID_BLUE_BALANCE: - if ((ctrl->value = zc0301_i2c_read(cam, 0x07, 1)) < 0) - return -EIO; - ctrl->value &= 0x0f; - return 0; - case V4L2_CID_GAIN: - if ((ctrl->value = zc0301_i2c_read(cam, 0x10, 1)) < 0) - return -EIO; - ctrl->value &= 0x1f; - return 0; - case ZC0301_V4L2_CID_GREEN_BALANCE: - if ((ctrl->value = zc0301_i2c_read(cam, 0x08, 1)) < 0) - return -EIO; - ctrl->value &= 0x0f; - return 0; - case ZC0301_V4L2_CID_DAC_MAGNITUDE: - if ((ctrl->value = zc0301_i2c_read(cam, 0x0c, 1)) < 0) - return -EIO; - return 0; - default: - return -EINVAL; - } -} - - -static int pas202bcb_set_ctrl(struct zc0301_device* cam, - const struct v4l2_control* ctrl) -{ - int err = 0; - - switch (ctrl->id) { - case V4L2_CID_EXPOSURE: - err += zc0301_i2c_write(cam, 0x04, ctrl->value >> 6); - err += zc0301_i2c_write(cam, 0x05, ctrl->value & 0x3f); - break; - case V4L2_CID_RED_BALANCE: - err += zc0301_i2c_write(cam, 0x09, ctrl->value); - break; - case V4L2_CID_BLUE_BALANCE: - err += zc0301_i2c_write(cam, 0x07, ctrl->value); - break; - case V4L2_CID_GAIN: - err += zc0301_i2c_write(cam, 0x10, ctrl->value); - break; - case ZC0301_V4L2_CID_GREEN_BALANCE: - err += zc0301_i2c_write(cam, 0x08, ctrl->value); - break; - case ZC0301_V4L2_CID_DAC_MAGNITUDE: - err += zc0301_i2c_write(cam, 0x0c, ctrl->value); - break; - default: - return -EINVAL; - } - err += zc0301_i2c_write(cam, 0x11, 0x01); - - return err ? -EIO : 0; -} - - -static struct zc0301_sensor pas202bcb = { - .name = "PAS202BCB", - .init = &pas202bcb_init, - .qctrl = { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x01e5, - .maximum = 0x3fff, - .step = 0x0001, - .default_value = 0x01e5, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "global gain", - .minimum = 0x00, - .maximum = 0x1f, - .step = 0x01, - .default_value = 0x0c, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = ZC0301_V4L2_CID_DAC_MAGNITUDE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DAC magnitude", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = 0x00, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0x0f, - .step = 0x01, - .default_value = 0x01, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0x0f, - .step = 0x01, - .default_value = 0x05, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = ZC0301_V4L2_CID_GREEN_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "green balance", - .minimum = 0x00, - .maximum = 0x0f, - .step = 0x01, - .default_value = 0x00, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - }, - .get_ctrl = &pas202bcb_get_ctrl, - .set_ctrl = &pas202bcb_set_ctrl, - .cropcap = { - .bounds = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - .defrect = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - }, - .pix_format = { - .width = 640, - .height = 480, - .pixelformat = V4L2_PIX_FMT_JPEG, - .priv = 8, - }, -}; - - -int zc0301_probe_pas202bcb(struct zc0301_device* cam) -{ - int r0 = 0, r1 = 0, err = 0; - unsigned int pid = 0; - - err += zc0301_write_reg(cam, 0x0000, 0x01); - err += zc0301_write_reg(cam, 0x0010, 0x0e); - err += zc0301_write_reg(cam, 0x0001, 0x01); - err += zc0301_write_reg(cam, 0x0012, 0x03); - err += zc0301_write_reg(cam, 0x0012, 0x01); - err += zc0301_write_reg(cam, 0x008d, 0x08); - - msleep(10); - - r0 = zc0301_i2c_read(cam, 0x00, 1); - r1 = zc0301_i2c_read(cam, 0x01, 1); - - if (r0 < 0 || r1 < 0 || err) - return -EIO; - - pid = (r0 << 4) | ((r1 & 0xf0) >> 4); - if (pid != 0x017) - return -ENODEV; - - zc0301_attach_sensor(cam, &pas202bcb); - - return 0; -} diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h deleted file mode 100644 index 1f95c28b1..000000000 --- a/drivers/media/video/zc0301/zc0301_sensor.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************** - * API for image sensors connected to the ZC030! Image Processor and * - * Control Chip * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You 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 _ZC0301_SENSOR_H_ -#define _ZC0301_SENSOR_H_ - -#include -#include -#include -#include -#include -#include - -struct zc0301_device; -struct zc0301_sensor; - -/*****************************************************************************/ - -extern int zc0301_probe_pas202bcb(struct zc0301_device* cam); - -#define ZC0301_SENSOR_TABLE \ -/* Weak detections must go at the end of the list */ \ -static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \ - &zc0301_probe_pas202bcb, \ - NULL, \ -}; - -extern struct zc0301_device* -zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id); - -extern void -zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor); - -#define ZC0301_USB_DEVICE(vend, prod, intclass) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ - USB_DEVICE_ID_MATCH_INT_CLASS, \ - .idVendor = (vend), \ - .idProduct = (prod), \ - .bInterfaceClass = (intclass) - -#define ZC0301_ID_TABLE \ -static const struct usb_device_id zc0301_id_table[] = { \ - { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, \ - { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \ - { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131B */ \ - { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \ - { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \ - { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \ - { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ - { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \ - { } \ -}; - -/*****************************************************************************/ - -extern int zc0301_write_reg(struct zc0301_device*, u16 index, u16 value); -extern int zc0301_read_reg(struct zc0301_device*, u16 index); -extern int zc0301_i2c_write(struct zc0301_device*, u16 address, u16 value); -extern int zc0301_i2c_read(struct zc0301_device*, u16 address, u8 length); - -/*****************************************************************************/ - -#define ZC0301_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10 -#define ZC0301_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE -#define ZC0301_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1 - -struct zc0301_sensor { - char name[32]; - - struct v4l2_queryctrl qctrl[ZC0301_MAX_CTRLS]; - struct v4l2_cropcap cropcap; - struct v4l2_pix_format pix_format; - - int (*init)(struct zc0301_device*); - int (*get_ctrl)(struct zc0301_device*, struct v4l2_control* ctrl); - int (*set_ctrl)(struct zc0301_device*, - const struct v4l2_control* ctrl); - int (*set_crop)(struct zc0301_device*, const struct v4l2_rect* rect); - - /* Private */ - struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS]; - struct v4l2_rect _rect; -}; - -#endif /* _ZC0301_SENSOR_H_ */ diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h index 0166f555a..9fe6ad3b6 100644 --- a/drivers/media/video/zoran.h +++ b/drivers/media/video/zoran.h @@ -1,4 +1,4 @@ -/* +/* * zoran - Iomega Buz driver * * Copyright (C) 1999 Rainer Johanni @@ -395,7 +395,7 @@ struct zoran { struct videocodec *codec; /* video codec */ struct videocodec *vfe; /* video front end */ - struct mutex resource_lock; /* prevent evil stuff */ + struct semaphore resource_lock; /* prevent evil stuff */ u8 initialized; /* flag if zoran has been correctly initalized */ int user; /* number of current users */ diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 0a85c9e7f..246e67cd8 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c @@ -4,7 +4,7 @@ * Media Labs LML33/LML33R10. * * This part handles card-specific data and detection - * + * * Copyright (C) 2000 Serguei Miridonov * * Currently maintained by: @@ -47,7 +47,6 @@ #include #include #include -#include #include @@ -674,7 +673,7 @@ zoran_i2c_client_register (struct i2c_client *client) KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n", ZR_DEVNAME(zr), client->driver->id); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (zr->user > 0) { /* we're already busy, so we keep a reference to @@ -695,7 +694,7 @@ zoran_i2c_client_register (struct i2c_client *client) } clientreg_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -708,7 +707,7 @@ zoran_i2c_client_unregister (struct i2c_client *client) dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (zr->user > 0) { res = -EBUSY; @@ -723,7 +722,7 @@ zoran_i2c_client_unregister (struct i2c_client *client) snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", zr->id); } clientunreg_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -996,7 +995,10 @@ test_interrupts (struct zoran *zr) static int __devinit zr36057_init (struct zoran *zr) { - int j, err; + u32 *mem; + void *vdev; + unsigned mem_needed; + int j; int two = 2; int zero = 0; @@ -1047,16 +1049,19 @@ zr36057_init (struct zoran *zr) /* allocate memory *before* doing anything to the hardware * in case allocation fails */ - zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL); - zr->video_dev = kmalloc(sizeof(struct video_device), GFP_KERNEL); - if (!zr->stat_com || !zr->video_dev) { + mem_needed = BUZ_NUM_STAT_COM * 4; + mem = kzalloc(mem_needed, GFP_KERNEL); + vdev = (void *) kmalloc(sizeof(struct video_device), GFP_KERNEL); + if (!mem || !vdev) { dprintk(1, KERN_ERR "%s: zr36057_init() - kmalloc (STAT_COM) failed\n", ZR_DEVNAME(zr)); - err = -ENOMEM; - goto exit_free; + kfree(vdev); + kfree(mem); + return -ENOMEM; } + zr->stat_com = mem; for (j = 0; j < BUZ_NUM_STAT_COM; j++) { zr->stat_com[j] = 1; /* mark as unavailable to zr36057 */ } @@ -1064,11 +1069,16 @@ zr36057_init (struct zoran *zr) /* * Now add the template and register the device unit. */ + zr->video_dev = vdev; memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); - err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr); - if (err < 0) - goto exit_unregister; + if (video_register_device(zr->video_dev, VFL_TYPE_GRABBER, + video_nr) < 0) { + zoran_unregister_i2c(zr); + kfree((void *) zr->stat_com); + kfree(vdev); + return -1; + } zoran_init_hardware(zr); if (*zr_debug > 2) @@ -1082,13 +1092,6 @@ zr36057_init (struct zoran *zr) zr->zoran_proc = NULL; zr->initialized = 1; return 0; - -exit_unregister: - zoran_unregister_i2c(zr); -exit_free: - kfree(zr->stat_com); - kfree(zr->video_dev); - return err; } static void @@ -1118,7 +1121,7 @@ zoran_release (struct zoran *zr) btwrite(0, ZR36057_SPGPPCR); free_irq(zr->pci_dev->irq, zr); /* unmap and free memory */ - kfree(zr->stat_com); + kfree((void *) zr->stat_com); zoran_proc_cleanup(zr); iounmap(zr->zr36057_mem); pci_disable_device(zr->pci_dev); @@ -1203,7 +1206,7 @@ find_zr36057 (void) zr->id = zoran_num; snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); spin_lock_init(&zr->spinlock); - mutex_init(&zr->resource_lock); + init_MUTEX(&zr->resource_lock); if (pci_enable_device(dev)) continue; zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); diff --git a/drivers/media/video/zoran_card.h b/drivers/media/video/zoran_card.h index ad997c30b..e5b6acd3e 100644 --- a/drivers/media/video/zoran_card.h +++ b/drivers/media/video/zoran_card.h @@ -4,7 +4,7 @@ * Media Labs LML33/LML33R10. * * This part handles card-specific data and detection - * + * * Copyright (C) 2000 Serguei Miridonov * * Currently maintained by: diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index c690b2ee8..4e15afdec 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c @@ -4,7 +4,7 @@ * Media Labs LML33/LML33R10. * * This part handles device access (PCI/I2C/codec/...) - * + * * Copyright (C) 2000 Serguei Miridonov * * Currently maintained by: @@ -492,7 +492,7 @@ zr36057_set_vfe (struct zoran *zr, /* (Ronald) don't write this if overlay_mask = NULL */ if (zr->overlay_mask) { /* Write overlay clipping mask data, but don't enable overlay clipping */ - /* RJ: since this makes only sense on the screen, we use + /* RJ: since this makes only sense on the screen, we use * zr->overlay_settings.width instead of video_width */ mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; @@ -819,12 +819,12 @@ zr36057_set_jpg (struct zoran *zr, if (zr->card.vfe_pol.hsync_pol) btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); else - btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); + btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) | (tvn->Wt << ZR36057_HSP_LineTot); btwrite(reg, ZR36057_HSP); reg = ((zr->jpg_settings.img_x + - tvn->HStart + 4) << ZR36057_FHAP_NAX) | + tvn->HStart + 4) << ZR36057_FHAP_NAX) | (zr->jpg_settings.img_width << ZR36057_FHAP_PAX); btwrite(reg, ZR36057_FHAP); @@ -1272,15 +1272,15 @@ error_handler (struct zoran *zr, if (zr->JPEG_error != 1) { /* * First entry: error just happened during normal operation - * + * * In BUZ_MODE_MOTION_COMPRESS: - * + * * Possible glitch in TV signal. In this case we should * stop the codec and wait for good quality signal before * restarting it to avoid further problems - * + * * In BUZ_MODE_MOTION_DECOMPRESS: - * + * * Bad JPEG frame: we have to mark it as processed (codec crashed * and was not able to do it itself), and to remove it from queue. */ diff --git a/drivers/media/video/zoran_device.h b/drivers/media/video/zoran_device.h index f19705cbd..f315203d7 100644 --- a/drivers/media/video/zoran_device.h +++ b/drivers/media/video/zoran_device.h @@ -4,7 +4,7 @@ * Media Labs LML33/LML33R10. * * This part handles card-specific data and detection - * + * * Copyright (C) 2000 Serguei Miridonov * * Currently maintained by: diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index b5a576a37..485553be1 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -81,7 +81,6 @@ #include #include -#include #include "zoran.h" #include "zoran_device.h" #include "zoran_card.h" @@ -94,7 +93,7 @@ V4L2_CAP_VIDEO_CAPTURE |\ V4L2_CAP_VIDEO_OUTPUT |\ V4L2_CAP_VIDEO_OVERLAY \ - ) + ) #endif #include @@ -165,7 +164,7 @@ const struct zoran_format zoran_formats[] = { #endif .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | - ZORAN_FORMAT_OVERLAY, + ZORAN_FORMAT_OVERLAY, }, { .name = "Hardware-encoded Motion-JPEG", .palette = -1, @@ -670,7 +669,7 @@ jpg_fbuffer_free (struct file *file) j])))); free_page((unsigned long) bus_to_virt - (le32_to_cpu + (le32_to_cpu (fh->jpg_buffers. buffer[i]. frag_tab[2 * j]))); @@ -1293,7 +1292,7 @@ zoran_open (struct inode *inode, /* see fs/device.c - the kernel already locks during open(), * so locking ourselves only causes deadlocks */ - /*mutex_lock(&zr->resource_lock);*/ + /*down(&zr->resource_lock);*/ if (!zr->decoder) { dprintk(1, @@ -1372,7 +1371,7 @@ zoran_open (struct inode *inode, if (zr->user++ == 0) first_open = 1; - /*mutex_unlock(&zr->resource_lock);*/ + /*up(&zr->resource_lock);*/ /* default setup - TODO: look at flags */ if (first_open) { /* First device open */ @@ -1402,7 +1401,7 @@ open_unlock_and_return: /* if there's no device found, we didn't obtain the lock either */ if (zr) { - /*mutex_unlock(&zr->resource_lock);*/ + /*up(&zr->resource_lock);*/ } return res; @@ -1420,7 +1419,7 @@ zoran_close (struct inode *inode, /* kernel locks (fs/device.c), so don't do that ourselves * (prevents deadlocks) */ - /*mutex_lock(&zr->resource_lock);*/ + /*down(&zr->resource_lock);*/ zoran_close_end_session(file); @@ -1467,7 +1466,7 @@ zoran_close (struct inode *inode, } module_put(THIS_MODULE); - /*mutex_unlock(&zr->resource_lock);*/ + /*up(&zr->resource_lock);*/ dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr)); @@ -1871,7 +1870,7 @@ zoran_v4l2_buffer_status (struct file *file, static int zoran_set_norm (struct zoran *zr, - int norm) /* VIDEO_MODE_* */ + int norm) /* VIDEO_MODE_* */ { int norm_encoder, on; @@ -2006,9 +2005,9 @@ zoran_set_input (struct zoran *zr, static int zoran_do_ioctl (struct inode *inode, - struct file *file, - unsigned int cmd, - void *arg) + struct file *file, + unsigned int cmd, + void *arg) { struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; @@ -2028,14 +2027,14 @@ zoran_do_ioctl (struct inode *inode, * but moving the free code outside the munmap() handler fixes * all this... If someone knows why, please explain me (Ronald) */ - if (!!mutex_trylock(&zr->resource_lock)) { + if (!down_trylock(&zr->resource_lock)) { /* we obtained it! Let's try to free some things */ if (fh->jpg_buffers.ready_to_be_freed) jpg_fbuffer_free(file); if (fh->v4l_buffers.ready_to_be_freed) v4l_fbuffer_free(file); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); } switch (cmd) { @@ -2052,12 +2051,12 @@ zoran_do_ioctl (struct inode *inode, vcap->channels = zr->card.inputs; vcap->audios = 0; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); vcap->maxwidth = BUZ_MAX_WIDTH; vcap->maxheight = BUZ_MAX_HEIGHT; vcap->minwidth = BUZ_MIN_WIDTH; vcap->minheight = BUZ_MIN_HEIGHT; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -2085,9 +2084,9 @@ zoran_do_ioctl (struct inode *inode, vchan->tuners = 0; vchan->flags = 0; vchan->type = VIDEO_TYPE_CAMERA; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); vchan->norm = zr->norm; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); vchan->channel = channel; return 0; @@ -2095,7 +2094,7 @@ zoran_do_ioctl (struct inode *inode, break; /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says: - * + * * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input." * * ^^^^^^^ * * The famos BTTV driver has it implemented with a struct video_channel argument @@ -2114,7 +2113,7 @@ zoran_do_ioctl (struct inode *inode, "%s: VIDIOCSCHAN - channel=%d, norm=%d\n", ZR_DEVNAME(zr), vchan->channel, vchan->norm); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if ((res = zoran_set_input(zr, vchan->channel))) goto schan_unlock_and_return; if ((res = zoran_set_norm(zr, vchan->norm))) @@ -2123,7 +2122,7 @@ zoran_do_ioctl (struct inode *inode, /* Make sure the changes come into effect */ res = wait_grab_pending(zr); schan_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } break; @@ -2135,7 +2134,7 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr)); memset(vpict, 0, sizeof(struct video_picture)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); vpict->hue = zr->hue; vpict->brightness = zr->brightness; vpict->contrast = zr->contrast; @@ -2146,7 +2145,7 @@ zoran_do_ioctl (struct inode *inode, } else { vpict->depth = 0; } - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -2181,7 +2180,7 @@ zoran_do_ioctl (struct inode *inode, return -EINVAL; } - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); decoder_command(zr, DECODER_SET_PICTURE, vpict); @@ -2192,7 +2191,7 @@ zoran_do_ioctl (struct inode *inode, fh->overlay_settings.format = &zoran_formats[i]; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -2205,9 +2204,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n", ZR_DEVNAME(zr), *on); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = setup_overlay(file, *on); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2220,12 +2219,12 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr)); memset(vwin, 0, sizeof(struct video_window)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); vwin->x = fh->overlay_settings.x; vwin->y = fh->overlay_settings.y; vwin->width = fh->overlay_settings.width; vwin->height = fh->overlay_settings.height; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); vwin->clipcount = 0; return 0; } @@ -2242,12 +2241,12 @@ zoran_do_ioctl (struct inode *inode, ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width, vwin->height, vwin->clipcount); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = setup_window(file, vwin->x, vwin->y, vwin->width, vwin->height, vwin->clips, vwin->clipcount, NULL); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2259,9 +2258,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); *vbuf = zr->buffer; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } break; @@ -2288,12 +2287,12 @@ zoran_do_ioctl (struct inode *inode, return -EINVAL; } - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = setup_fbuffer(file, vbuf->base, &zoran_formats[i], vbuf->width, vbuf->height, vbuf->bytesperline); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2306,9 +2305,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n", ZR_DEVNAME(zr), *frame); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = v4l_sync(file, *frame); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); if (!res) zr->v4l_sync_tail++; return res; @@ -2326,9 +2325,9 @@ zoran_do_ioctl (struct inode *inode, ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height, vmap->format); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = v4l_grab(file, vmap); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } break; @@ -2349,7 +2348,7 @@ zoran_do_ioctl (struct inode *inode, i * fh->v4l_buffers.buffer_size; } - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { dprintk(1, @@ -2368,7 +2367,7 @@ zoran_do_ioctl (struct inode *inode, /* The next mmap will map the V4L buffers */ fh->map_mode = ZORAN_MAP_MODE_RAW; v4l1reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2422,7 +2421,7 @@ zoran_do_ioctl (struct inode *inode, bparams->major_version = MAJOR_VERSION; bparams->minor_version = MINOR_VERSION; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); bparams->norm = zr->norm; bparams->input = zr->input; @@ -2451,7 +2450,7 @@ zoran_do_ioctl (struct inode *inode, bparams->jpeg_markers = fh->jpg_settings.jpg_comp.jpeg_markers; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); bparams->VFIFO_FB = 0; @@ -2487,7 +2486,7 @@ zoran_do_ioctl (struct inode *inode, sizeof(bparams->COM_data)); settings.jpg_comp.jpeg_markers = bparams->jpeg_markers; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (zr->codec_mode != BUZ_MODE_IDLE) { dprintk(1, @@ -2507,7 +2506,7 @@ zoran_do_ioctl (struct inode *inode, fh->jpg_settings = settings; sparams_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2539,7 +2538,7 @@ zoran_do_ioctl (struct inode *inode, breq->size > MAX_KMALLOC_MEM) breq->size = MAX_KMALLOC_MEM; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { dprintk(1, @@ -2562,7 +2561,7 @@ zoran_do_ioctl (struct inode *inode, * also be *_PLAY, but it doesn't matter here */ fh->map_mode = ZORAN_MAP_MODE_JPG_REC; jpgreqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2575,9 +2574,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_CAPT - frame=%d\n", ZR_DEVNAME(zr), *frame); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_COMPRESS); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2590,9 +2589,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_PLAY - frame=%d\n", ZR_DEVNAME(zr), *frame); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_DECOMPRESS); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2605,9 +2604,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = jpg_sync(file, bsync); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -2631,7 +2630,7 @@ zoran_do_ioctl (struct inode *inode, input = zr->card.input[bstat->input].muxsel; norm = VIDEO_MODE_AUTO; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (zr->codec_mode != BUZ_MODE_IDLE) { dprintk(1, @@ -2656,7 +2655,7 @@ zoran_do_ioctl (struct inode *inode, decoder_command(zr, DECODER_SET_INPUT, &input); decoder_command(zr, DECODER_SET_NORM, &zr->norm); gstat_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); if (!res) { bstat->signal = @@ -2764,7 +2763,7 @@ zoran_do_ioctl (struct inode *inode, switch (fmt->type) { case V4L2_BUF_TYPE_VIDEO_OVERLAY: - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); fmt->fmt.win.w.left = fh->overlay_settings.x; fmt->fmt.win.w.top = fh->overlay_settings.y; @@ -2777,14 +2776,14 @@ zoran_do_ioctl (struct inode *inode, else fmt->fmt.win.field = V4L2_FIELD_TOP; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && fh->map_mode == ZORAN_MAP_MODE_RAW) { @@ -2838,7 +2837,7 @@ zoran_do_ioctl (struct inode *inode, V4L2_COLORSPACE_SMPTE170M; } - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); break; @@ -2871,7 +2870,7 @@ zoran_do_ioctl (struct inode *inode, fmt->fmt.win.w.height, fmt->fmt.win.clipcount, fmt->fmt.win.bitmap); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = setup_window(file, fmt->fmt.win.w.left, fmt->fmt.win.w.top, @@ -2881,7 +2880,7 @@ zoran_do_ioctl (struct inode *inode, fmt->fmt.win.clips, fmt->fmt.win.clipcount, fmt->fmt.win.bitmap); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; break; @@ -2918,7 +2917,7 @@ zoran_do_ioctl (struct inode *inode, } if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); settings = fh->jpg_settings; @@ -2996,7 +2995,7 @@ zoran_do_ioctl (struct inode *inode, ZORAN_MAP_MODE_JPG_REC : ZORAN_MAP_MODE_JPG_PLAY; sfmtjpg_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); } else { for (i = 0; i < zoran_num_formats; i++) if (fmt->fmt.pix.pixelformat == @@ -3011,7 +3010,7 @@ zoran_do_ioctl (struct inode *inode, (char *) &printformat); return -EINVAL; } - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fh->jpg_buffers.allocated || (fh->v4l_buffers.allocated && fh->v4l_buffers.active != @@ -3053,7 +3052,7 @@ zoran_do_ioctl (struct inode *inode, fh->map_mode = ZORAN_MAP_MODE_RAW; sfmtv4l_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); } break; @@ -3078,7 +3077,7 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr)); memset(fb, 0, sizeof(*fb)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); fb->base = zr->buffer.base; fb->fmt.width = zr->buffer.width; fb->fmt.height = zr->buffer.height; @@ -3087,7 +3086,7 @@ zoran_do_ioctl (struct inode *inode, fh->overlay_settings.format->fourcc; } fb->fmt.bytesperline = zr->buffer.bytesperline; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; fb->fmt.field = V4L2_FIELD_INTERLACED; fb->flags = V4L2_FBUF_FLAG_OVERLAY; @@ -3122,12 +3121,12 @@ zoran_do_ioctl (struct inode *inode, return -EINVAL; } - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = setup_fbuffer(file, fb->base, &zoran_formats[i], fb->fmt.width, fb->fmt.height, fb->fmt.bytesperline); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -3140,9 +3139,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n", ZR_DEVNAME(zr), *on); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = setup_overlay(file, *on); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -3164,7 +3163,7 @@ zoran_do_ioctl (struct inode *inode, return -EINVAL; } - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { dprintk(1, @@ -3225,7 +3224,7 @@ zoran_do_ioctl (struct inode *inode, goto v4l2reqbuf_unlock_and_return; } v4l2reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -3246,9 +3245,9 @@ zoran_do_ioctl (struct inode *inode, buf->type = type; buf->index = index; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); res = zoran_v4l2_buffer_status(file, buf, buf->index); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -3263,7 +3262,7 @@ zoran_do_ioctl (struct inode *inode, KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n", ZR_DEVNAME(zr), buf->type, buf->index); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: @@ -3323,7 +3322,7 @@ zoran_do_ioctl (struct inode *inode, goto qbuf_unlock_and_return; } qbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -3337,7 +3336,7 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n", ZR_DEVNAME(zr), buf->type); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: @@ -3411,7 +3410,7 @@ zoran_do_ioctl (struct inode *inode, goto dqbuf_unlock_and_return; } dqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -3423,7 +3422,7 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: /* raw capture */ @@ -3471,7 +3470,7 @@ zoran_do_ioctl (struct inode *inode, goto strmon_unlock_and_return; } strmon_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -3483,7 +3482,7 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: /* raw capture */ @@ -3541,7 +3540,7 @@ zoran_do_ioctl (struct inode *inode, goto strmoff_unlock_and_return; } strmoff_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -3601,7 +3600,7 @@ zoran_do_ioctl (struct inode *inode, ctrl->id > V4L2_CID_HUE) return -EINVAL; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: ctrl->value = zr->brightness; @@ -3616,7 +3615,7 @@ zoran_do_ioctl (struct inode *inode, ctrl->value = zr->hue; break; } - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -3643,7 +3642,7 @@ zoran_do_ioctl (struct inode *inode, return -EINVAL; } - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: zr->brightness = ctrl->value; @@ -3665,7 +3664,7 @@ zoran_do_ioctl (struct inode *inode, decoder_command(zr, DECODER_SET_PICTURE, &pict); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -3733,9 +3732,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); norm = zr->norm; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); switch (norm) { case VIDEO_MODE_PAL: @@ -3777,13 +3776,13 @@ zoran_do_ioctl (struct inode *inode, return -EINVAL; } - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if ((res = zoran_set_norm(zr, norm))) goto sstd_unlock_and_return; res = wait_grab_pending(zr); sstd_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } break; @@ -3810,9 +3809,9 @@ zoran_do_ioctl (struct inode *inode, inp->std = V4L2_STD_ALL; /* Get status of video decoder */ - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); decoder_command(zr, DECODER_GET_STATUS, &status); - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); if (!(status & DECODER_STATUS_GOOD)) { inp->status |= V4L2_IN_ST_NO_POWER; @@ -3831,9 +3830,9 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); *input = zr->input; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -3846,14 +3845,14 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n", ZR_DEVNAME(zr), *input); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if ((res = zoran_set_input(zr, *input))) goto sinput_unlock_and_return; /* Make sure the changes come into effect */ res = wait_grab_pending(zr); sinput_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } break; @@ -3915,7 +3914,7 @@ zoran_do_ioctl (struct inode *inode, memset(cropcap, 0, sizeof(*cropcap)); cropcap->type = type; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || @@ -3935,7 +3934,7 @@ zoran_do_ioctl (struct inode *inode, cropcap->defrect.width = BUZ_MIN_WIDTH; cropcap->defrect.height = BUZ_MIN_HEIGHT; cropcap_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } break; @@ -3951,7 +3950,7 @@ zoran_do_ioctl (struct inode *inode, memset(crop, 0, sizeof(*crop)); crop->type = type; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || @@ -3970,7 +3969,7 @@ zoran_do_ioctl (struct inode *inode, crop->c.height = fh->jpg_settings.img_height; gcrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -3989,7 +3988,7 @@ zoran_do_ioctl (struct inode *inode, ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top, crop->c.width, crop->c.height); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { dprintk(1, @@ -4025,7 +4024,7 @@ zoran_do_ioctl (struct inode *inode, fh->jpg_settings = settings; scrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } break; @@ -4039,7 +4038,7 @@ zoran_do_ioctl (struct inode *inode, memset(params, 0, sizeof(*params)); - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); params->quality = fh->jpg_settings.jpg_comp.quality; params->APPn = fh->jpg_settings.jpg_comp.APPn; @@ -4054,7 +4053,7 @@ zoran_do_ioctl (struct inode *inode, params->jpeg_markers = fh->jpg_settings.jpg_comp.jpeg_markers; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -4075,7 +4074,7 @@ zoran_do_ioctl (struct inode *inode, settings.jpg_comp = *params; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fh->v4l_buffers.active != ZORAN_FREE || fh->jpg_buffers.active != ZORAN_FREE) { @@ -4094,7 +4093,7 @@ zoran_do_ioctl (struct inode *inode, zoran_v4l2_calc_bufsize(&fh->jpg_settings); fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; sjpegc_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return 0; } @@ -4128,7 +4127,7 @@ zoran_do_ioctl (struct inode *inode, switch (fmt->type) { case V4L2_BUF_TYPE_VIDEO_OVERLAY: - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) fmt->fmt.win.w.width = BUZ_MAX_WIDTH; @@ -4139,7 +4138,7 @@ zoran_do_ioctl (struct inode *inode, if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -4147,7 +4146,7 @@ zoran_do_ioctl (struct inode *inode, if (fmt->fmt.pix.bytesperline > 0) return -EINVAL; - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { settings = fh->jpg_settings; @@ -4230,7 +4229,7 @@ zoran_do_ioctl (struct inode *inode, goto tryfmt_unlock_and_return; } tryfmt_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; break; @@ -4281,7 +4280,7 @@ zoran_poll (struct file *file, * if no buffers queued or so, return POLLNVAL */ - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: @@ -4330,7 +4329,7 @@ zoran_poll (struct file *file, } poll_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); return res; } @@ -4386,7 +4385,7 @@ zoran_vm_close (struct vm_area_struct *vma) if (fh->jpg_buffers.buffer[i].map) break; if (i == fh->jpg_buffers.num_buffers) { - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fh->jpg_buffers.active != ZORAN_FREE) { jpg_qbuf(file, -1, zr->codec_mode); @@ -4399,7 +4398,7 @@ zoran_vm_close (struct vm_area_struct *vma) fh->jpg_buffers.allocated = 0; fh->jpg_buffers.ready_to_be_freed = 1; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); } break; @@ -4422,7 +4421,7 @@ zoran_vm_close (struct vm_area_struct *vma) if (fh->v4l_buffers.buffer[i].map) break; if (i == fh->v4l_buffers.num_buffers) { - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); if (fh->v4l_buffers.active != ZORAN_FREE) { zr36057_set_memgrab(zr, 0); @@ -4435,7 +4434,7 @@ zoran_vm_close (struct vm_area_struct *vma) fh->v4l_buffers.allocated = 0; fh->v4l_buffers.ready_to_be_freed = 1; - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); } break; @@ -4490,7 +4489,7 @@ zoran_mmap (struct file *file, case ZORAN_MAP_MODE_JPG_PLAY: /* lock */ - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); /* Map the MJPEG buffers */ if (!fh->jpg_buffers.allocated) { @@ -4580,13 +4579,13 @@ zoran_mmap (struct file *file, } jpg_mmap_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); break; case ZORAN_MAP_MODE_RAW: - mutex_lock(&zr->resource_lock); + down(&zr->resource_lock); /* Map the V4L buffers */ if (!fh->v4l_buffers.allocated) { @@ -4658,7 +4657,7 @@ zoran_mmap (struct file *file, break; } v4l_mmap_unlock_and_return: - mutex_unlock(&zr->resource_lock); + up(&zr->resource_lock); break; diff --git a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c index a00fae902..f0d9b13c3 100644 --- a/drivers/media/video/zoran_procfs.c +++ b/drivers/media/video/zoran_procfs.c @@ -4,7 +4,7 @@ * Media Labs LML33/LML33R10. * * This part handles the procFS entries (/proc/ZORAN[%d]) - * + * * Copyright (C) 2000 Serguei Miridonov * * Currently maintained by: diff --git a/drivers/media/video/zoran_procfs.h b/drivers/media/video/zoran_procfs.h index f2d5b1ba4..8904fc959 100644 --- a/drivers/media/video/zoran_procfs.h +++ b/drivers/media/video/zoran_procfs.h @@ -4,7 +4,7 @@ * Media Labs LML33/LML33R10. * * This part handles card-specific data and detection - * + * * Copyright (C) 2000 Serguei Miridonov * * Currently maintained by: diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c index 62f77584f..10130ef67 100644 --- a/drivers/media/video/zr36016.c +++ b/drivers/media/video/zr36016.c @@ -34,7 +34,7 @@ #include #include -/* includes for structures and defines regarding video +/* includes for structures and defines regarding video #include */ /* I/O commands, error codes */ @@ -143,8 +143,8 @@ zr36016_readi (struct zr36016 *ptr, static void zr36016_writei (struct zr36016 *ptr, - u16 reg, - u8 value) + u16 reg, + u8 value) { dprintk(4, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name, value, reg); @@ -192,7 +192,7 @@ zr36016_basic_test (struct zr36016 *ptr) dprintk(1, "\n"); } // for testing just write 0, then the default value to a register and read - // it back in both cases + // it back in both cases zr36016_writei(ptr, ZR016I_PAX_LO, 0x00); if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) { dprintk(1, @@ -232,17 +232,17 @@ zr36016_basic_test (struct zr36016 *ptr) static int zr36016_pushit (struct zr36016 *ptr, u16 startreg, u16 len, - const char *data) + const char *data) { - int i=0; + int i=0; - dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", + dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, startreg,len); - while (i #include -/* includes for structures and defines regarding video +/* includes for structures and defines regarding video #include */ /* I/O commands, error codes */ @@ -171,7 +171,7 @@ zr36050_wait_end (struct zr36050 *ptr) /* ========================================================================= Local helper function: - basic test of "connectivity", writes/reads to/from memory the SOF marker + basic test of "connectivity", writes/reads to/from memory the SOF marker ========================================================================= */ static int @@ -218,9 +218,9 @@ zr36050_basic_test (struct zr36050 *ptr) static int zr36050_pushit (struct zr36050 *ptr, - u16 startreg, - u16 len, - const char *data) + u16 startreg, + u16 len, + const char *data) { int i = 0; @@ -345,7 +345,7 @@ static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; /* ------------------------------------------------------------------------- */ /* SOF (start of frame) segment depends on width, height and sampling ratio - of each color component */ + of each color component */ static int zr36050_set_sof (struct zr36050 *ptr) @@ -376,8 +376,8 @@ zr36050_set_sof (struct zr36050 *ptr) /* ------------------------------------------------------------------------- */ -/* SOS (start of scan) segment depends on the used scan components - of each color component */ +/* SOS (start of scan) segment depends on the used scan components + of each color component */ static int zr36050_set_sos (struct zr36050 *ptr) diff --git a/drivers/media/video/zr36057.h b/drivers/media/video/zr36057.h index 54c9362aa..159abfa03 100644 --- a/drivers/media/video/zr36057.h +++ b/drivers/media/video/zr36057.h @@ -1,4 +1,4 @@ -/* +/* * zr36057.h - zr36057 register offsets * * Copyright (C) 1998 Dave Perks @@ -27,14 +27,14 @@ #define ZR36057_VFEHCR 0x000 /* Video Front End, Horizontal Configuration Register */ #define ZR36057_VFEHCR_HSPol (1<<30) #define ZR36057_VFEHCR_HStart 10 -#define ZR36057_VFEHCR_HEnd 0 -#define ZR36057_VFEHCR_Hmask 0x3ff +#define ZR36057_VFEHCR_HEnd 0 +#define ZR36057_VFEHCR_Hmask 0x3ff #define ZR36057_VFEVCR 0x004 /* Video Front End, Vertical Configuration Register */ #define ZR36057_VFEVCR_VSPol (1<<30) #define ZR36057_VFEVCR_VStart 10 -#define ZR36057_VFEVCR_VEnd 0 -#define ZR36057_VFEVCR_Vmask 0x3ff +#define ZR36057_VFEVCR_VEnd 0 +#define ZR36057_VFEVCR_Vmask 0x3ff #define ZR36057_VFESPFR 0x008 /* Video Front End, Scaler and Pixel Format Register */ #define ZR36057_VFESPFR_ExtFl (1<<26) diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c index 97c8f9b9d..d8dd003a7 100644 --- a/drivers/media/video/zr36060.c +++ b/drivers/media/video/zr36060.c @@ -34,7 +34,7 @@ #include #include -/* includes for structures and defines regarding video +/* includes for structures and defines regarding video #include */ /* I/O commands, error codes */ @@ -173,7 +173,7 @@ zr36060_wait_end (struct zr36060 *ptr) /* ========================================================================= Local helper function: - basic test of "connectivity", writes/reads to/from memory the SOF marker + basic test of "connectivity", writes/reads to/from memory the SOF marker ========================================================================= */ static int @@ -208,9 +208,9 @@ zr36060_basic_test (struct zr36060 *ptr) static int zr36060_pushit (struct zr36060 *ptr, - u16 startreg, - u16 len, - const char *data) + u16 startreg, + u16 len, + const char *data) { int i = 0; @@ -335,7 +335,7 @@ static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; /* ------------------------------------------------------------------------- */ /* SOF (start of frame) segment depends on width, height and sampling ratio - of each color component */ + of each color component */ static int zr36060_set_sof (struct zr36060 *ptr) @@ -367,8 +367,8 @@ zr36060_set_sof (struct zr36060 *ptr) /* ------------------------------------------------------------------------- */ -/* SOS (start of scan) segment depends on the used scan components - of each color component */ +/* SOS (start of scan) segment depends on the used scan components + of each color component */ static int zr36060_set_sos (struct zr36060 *ptr) @@ -385,7 +385,7 @@ zr36060_set_sos (struct zr36060 *ptr) for (i = 0; i < NO_OF_COMPONENTS; i++) { sos_data[5 + (i * 2)] = i; // index sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) | - zr36060_ta[i]; // AC/DC tbl.sel. + zr36060_ta[i]; // AC/DC tbl.sel. } sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f; @@ -999,7 +999,7 @@ zr36060_cleanup_module (void) dprintk(1, "zr36060: something's wrong - %d codecs left somehow.\n", zr36060_codecs); - } + } /* however, we can't just stay alive */ videocodec_unregister(&zr36060_codec); diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c index 6ac3b6740..d4c633b8a 100644 --- a/drivers/media/video/zr36120.c +++ b/drivers/media/video/zr36120.c @@ -70,10 +70,10 @@ MODULE_AUTHOR("Pauline Middelink "); MODULE_DESCRIPTION("Zoran ZR36120 based framegrabber"); MODULE_LICENSE("GPL"); -module_param(triton1, uint, 0); -module_param_array(cardtype, uint, NULL, 0); -module_param(video_nr, int, 0); -module_param(vbi_nr, int, 0); +MODULE_PARM(triton1,"i"); +MODULE_PARM(cardtype,"1-" __MODULE_STRING(ZORAN_MAX) "i"); +MODULE_PARM(video_nr,"i"); +MODULE_PARM(vbi_nr,"i"); static int zoran_cards; static struct zoran zorans[ZORAN_MAX]; @@ -316,7 +316,7 @@ DEBUG(printk(CARD_DEBUG "%p added to queue\n",CARD,item)); item->status = FBUFFER_BUSY; if (!lastitem) ztv->workqueue = item; - else + else lastitem->next = item; lastitem = item; } @@ -516,7 +516,7 @@ DEBUG(printk(KERN_DEBUG " %d: clip(%d,%d,%d,%d)\n", i,vp->x,vp->y,vp->widt zraor((ztv->vidInterlace*ystep)<<0,~ZORAN_OCR_MASKSTRIDE,ZORAN_OCR); } -struct tvnorm +struct tvnorm { u16 Wt, Wa, Ht, Ha, HStart, VStart; }; @@ -660,7 +660,7 @@ DEBUG(printk(KERN_DEBUG " Y: scale=0, start=%d, end=%d\n", Hstart, Hend)); int HorDcm = 64-X; int hcrop1 = 2*(Wa-We)/4; /* - * BUGFIX: Juha Nurmela + * BUGFIX: Juha Nurmela * found the solution to the color phase shift. * See ChangeLog for the full explanation) */ @@ -812,12 +812,12 @@ void zoran_close(struct video_device* dev) zoran_common_close(ztv); - /* - * This is sucky but right now I can't find a good way to - * be sure its safe to free the buffer. We wait 5-6 fields - * which is more than sufficient to be sure. - */ - msleep(100); /* Wait 1/10th of a second */ + /* + * This is sucky but right now I can't find a good way to + * be sure its safe to free the buffer. We wait 5-6 fields + * which is more than sufficient to be sure. + */ + msleep(100); /* Wait 1/10th of a second */ /* free the allocated framebuffer */ bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE); @@ -1436,7 +1436,7 @@ int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg) /* Why isn't this in the API? * And why doesn't it take a buffer number? - case BTTV_FIELDNR: + case BTTV_FIELDNR: { unsigned long v = ztv->lastfieldnr; if (copy_to_user(arg,&v,sizeof(v))) @@ -1557,12 +1557,12 @@ void vbi_close(struct video_device *dev) zoran_common_close(ztv); - /* - * This is sucky but right now I can't find a good way to - * be sure its safe to free the buffer. We wait 5-6 fields - * which is more than sufficient to be sure. - */ - msleep(100); /* Wait 1/10th of a second */ + /* + * This is sucky but right now I can't find a good way to + * be sure its safe to free the buffer. We wait 5-6 fields + * which is more than sufficient to be sure. + */ + msleep(100); /* Wait 1/10th of a second */ for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++) { @@ -1620,7 +1620,7 @@ long vbi_read(struct video_device* dev, char* buf, unsigned long count, int nonb write_unlock_irq(&ztv->lock); return -EWOULDBLOCK; } - + /* mark the unused buffer as wanted */ unused->status = FBUFFER_BUSY; unused->next = 0; @@ -1671,7 +1671,7 @@ long vbi_read(struct video_device* dev, char* buf, unsigned long count, int nonb if (count == 2*19*2048) { /* * Extreme HACK, old VBI programs expect 2048 points - * of data, and we only got 864 orso. Double each + * of data, and we only got 864 orso. Double each * datapoint and clear the rest of the line. * This way we have appear to have a * sample_frequency of 29.5 Mc. @@ -1956,7 +1956,7 @@ int __init init_zoran(int card) zrand(~ZORAN_VDC_TRICOM, ZORAN_VDC); /* external FL determines TOP frame */ - zror(ZORAN_VFEC_EXTFL, ZORAN_VFEC); + zror(ZORAN_VFEC_EXTFL, ZORAN_VFEC); /* set HSpol */ if (ztv->card->hsync_pos) @@ -2012,7 +2012,7 @@ void release_zoran(int max) struct zoran *ztv; int i; - for (i=0;idev->irq,ztv); - + /* unregister i2c_bus */ i2c_unregister_bus((&ztv->i2c)); @@ -2050,7 +2050,7 @@ void __exit zr36120_exit(void) int __init zr36120_init(void) { int card; - + handle_chipset(); zoran_cards = find_zoran(); if (zoran_cards<0) @@ -2063,7 +2063,7 @@ int __init zr36120_init(void) /* only release the zorans we have registered */ release_zoran(card); return -EIO; - } + } } return 0; } diff --git a/drivers/media/video/zr36120.h b/drivers/media/video/zr36120.h index a71e485b0..571f8e84b 100644 --- a/drivers/media/video/zr36120.h +++ b/drivers/media/video/zr36120.h @@ -1,4 +1,4 @@ -/* +/* zr36120.h - Zoran 36120/36125 based framegrabbers Copyright (C) 1998-1999 Pauline Middelink (middelin@polyware.nl) @@ -89,7 +89,7 @@ struct vidinfo { ulong* overlay; /* kernel addr of overlay mask */ }; -struct zoran +struct zoran { struct video_device video_dev; #define CARD_DEBUG KERN_DEBUG "%s(%lu): " @@ -106,7 +106,7 @@ struct zoran uint norm; /* 0=PAL, 1=NTSC, 2=SECAM */ uint tuner_freq; /* Current freq in kHz */ struct video_picture picture; /* Current picture params */ - + /* videocard details */ uint swidth; /* screen width */ uint sheight; /* screen height */ diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig index bbc229852..e67cf15e9 100644 --- a/drivers/message/fusion/Kconfig +++ b/drivers/message/fusion/Kconfig @@ -9,7 +9,6 @@ config FUSION_SPI tristate "Fusion MPT ScsiHost drivers for SPI" depends on PCI && SCSI select FUSION - select SCSI_SPI_ATTRS ---help--- SCSI HOST support for a parallel SCSI host adapters. diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 51740b346..33ace3732 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile @@ -4,7 +4,6 @@ #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME #EXTRA_CFLAGS += -DMPT_DEBUG_SG #EXTRA_CFLAGS += -DMPT_DEBUG_EVENTS -#EXTRA_CFLAGS += -DMPT_DEBUG_VERBOSE_EVENTS #EXTRA_CFLAGS += -DMPT_DEBUG_INIT #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index a9c14ad13..9259d1ad6 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h @@ -3,11 +3,38 @@ * * * Copyright 2003 LSI Logic Corporation. All rights reserved. * * * - * Description * - * ------------ * - * This include file contains SAS firmware interface IOC Log Info codes * + * This file is confidential and a trade secret of LSI Logic. The * + * receipt of or possession of this file does not convey any rights to * + * reproduce or disclose its contents or to manufacture, use, or sell * + * anything it may describe, in whole, or in part, without the specific * + * written consent of LSI Logic Corporation. * * * - *-------------------------------------------------------------------------* + *************************************************************************** + * + * Name: iopiIocLogInfo.h + * Title: SAS Firmware IOP Interface IOC Log Info Definitions + * Programmer: Guy Kendall + * Creation Date: September 24, 2003 + * + * Version History + * --------------- + * + * Last Updated + * ------------- + * Version %version: 22 % + * Date Updated %date_modified: % + * Programmer %created_by: nperucca % + * + * Date Who Description + * -------- --- ------------------------------------------------------- + * 09/24/03 GWK Initial version + * + * + * Description + * ------------ + * This include file contains SAS firmware interface IOC Log Info codes + * + *------------------------------------------------------------------------- */ #ifndef IOPI_IOCLOGINFO_H_INCLUDED @@ -30,8 +57,6 @@ #define IOC_LOGINFO_ORIGINATOR_PL (0x01000000) #define IOC_LOGINFO_ORIGINATOR_IR (0x02000000) -#define IOC_LOGINFO_ORIGINATOR_MASK (0x0F000000) - /****************************************************************************/ /* LOGINFO_CODE defines */ /****************************************************************************/ @@ -53,27 +78,11 @@ #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ #define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) -#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */ -#define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */ - -#define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001) -#define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002) -#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003) -#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004) -#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005) /****************************************************************************/ /* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */ /****************************************************************************/ #define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000) -#define PL_LOG_INFO_CODE_OPEN_FAILURE_NO_DEST_TIME_OUT (0x00010001) -#define PL_LOGINFO_CODE_OPEN_FAILURE_BAD_DESTINATION (0x00010011) -#define PL_LOGINFO_CODE_OPEN_FAILURE_PROTOCOL_NOT_SUPPORTED (0x00010013) -#define PL_LOGINFO_CODE_OPEN_FAILURE_STP_RESOURCES_BSY (0x00010018) -#define PL_LOGINFO_CODE_OPEN_FAILURE_WRONG_DESTINATION (0x00010019) -#define PL_LOGINFO_CODE_OPEN_FAILURE_ORR_TIMEOUT (0X0001001A) -#define PL_LOGINFO_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0001001B) -#define PL_LOGINFO_CODE_OPEN_FAILURE_AWT_MAXED (0x0001001C) #define PL_LOGINFO_CODE_INVALID_SGL (0x00020000) #define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000) #define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000) @@ -88,7 +97,6 @@ #define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000) #define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000) #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000) -#define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */ #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */ #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */ #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */ @@ -97,23 +105,11 @@ #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */ #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */ #define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000) -#define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below */ -#define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below */ +#define PL_LOGINFO_CODE_RESET (0x00110000) +#define PL_LOGINFO_CODE_ABORT (0x00120000) #define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000) #define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) -#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000) -#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000) #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) -#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101) -#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */ -#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0000011B) -#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */ - -#define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120) -#define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */ -#define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */ - - #define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200) #define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300) #define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) @@ -127,39 +123,26 @@ #define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00) #define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00) #define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00) -#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01) -#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00) #define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000) #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */ -#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */ -#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */ -#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */ -#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */ -#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */ -#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */ +#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200001) /* Error occured on SMP Read */ +#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200002) /* Error occured on SMP Write */ +#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200004) /* Encl Mgmt services not available for this WWID */ +#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200005) /* Address Mode not suppored */ +#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200006) /* Invalid Slot Number in SEP Msg */ +#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200007) /* SGPIO not present/enabled */ #define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */ #define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */ #define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */ #define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */ -#define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */ -#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */ -#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */ -#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */ -#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */ -#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */ -#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */ -#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/ -#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode */ +#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200104) /* SEP stopped or sent bad chksum in Hdr */ +#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200105) /* SEP returned unknown scsi status */ +#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200106) /* SEP returned unknown scsi status */ +#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x00200107) /* SEP returned bad chksum after STOP */ +#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x00200108) /* SEP returned bad chksum after STOP while gettin data*/ /****************************************************************************/ diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 79718c1cf..642a61b6d 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -77,7 +77,6 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); -MODULE_VERSION(MPT_LINUX_VERSION_COMMON); /* * cmd line parameters @@ -181,7 +180,6 @@ static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); -static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); /* module entry point */ static int __init fusion_init (void); @@ -430,7 +428,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) results = ProcessEventNotification(ioc, pEvReply, &evHandlers); if (results != evHandlers) { /* CHECKME! Any special handling needed here? */ - devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n", + devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n", ioc->name, evHandlers, results)); } @@ -440,10 +438,10 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) */ if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { freereq = 0; - devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n", + devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n", ioc->name, pEvReply)); } else { - devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", + devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", ioc->name, pEvReply)); } @@ -1122,6 +1120,65 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) return -1; } +int +mpt_alt_ioc_wait(MPT_ADAPTER *ioc) +{ + int loop_count = 30 * 4; /* Wait 30 seconds */ + int status = -1; /* -1 means failed to get board READY */ + + do { + spin_lock(&ioc->initializing_hba_lock); + if (ioc->initializing_hba_lock_flag == 0) { + ioc->initializing_hba_lock_flag=1; + spin_unlock(&ioc->initializing_hba_lock); + status = 0; + break; + } + spin_unlock(&ioc->initializing_hba_lock); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/4); + } while (--loop_count); + + return status; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* + * mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery + * @ioc: Pointer to MPT adapter structure + * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. + * + * This routine performs all the steps necessary to bring the IOC + * to a OPERATIONAL state. + * + * Special Note: This function was added with spin lock's so as to allow + * the dv(domain validation) work thread to succeed on the other channel + * that maybe occuring at the same time when this function is called. + * Without this lock, the dv would fail when message frames were + * requested during hba bringup on the alternate ioc. + */ +static int +mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag) +{ + int r; + + if(ioc->alt_ioc) { + if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0)) + return r; + } + + r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, + CAN_SLEEP); + + if(ioc->alt_ioc) { + spin_lock(&ioc->alt_ioc->initializing_hba_lock); + ioc->alt_ioc->initializing_hba_lock_flag=0; + spin_unlock(&ioc->alt_ioc->initializing_hba_lock); + } + +return r; +} + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mpt_attach - Install a PCI intelligent MPT adapter. @@ -1190,6 +1247,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->diagPending = 0; spin_lock_init(&ioc->diagLock); spin_lock_init(&ioc->fc_rescan_work_lock); + spin_lock_init(&ioc->fc_rport_lock); spin_lock_init(&ioc->initializing_hba_lock); /* Initialize the event logging. @@ -1424,8 +1482,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) */ mpt_detect_bound_ports(ioc, pdev); - if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, - CAN_SLEEP)) != 0){ + if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){ printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n", ioc->name, r); @@ -1572,6 +1629,7 @@ mpt_resume(struct pci_dev *pdev) MPT_ADAPTER *ioc = pci_get_drvdata(pdev); u32 device_state = pdev->current_state; int recovery_state; + int ii; printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", @@ -1585,6 +1643,14 @@ mpt_resume(struct pci_dev *pdev) CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); ioc->active = 1; + /* F/W not running */ + if(!CHIPREG_READ32(&ioc->chip->Doorbell)) { + /* enable domain validation flags */ + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { + ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV; + } + } + printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n", ioc->name, @@ -1606,21 +1672,6 @@ mpt_resume(struct pci_dev *pdev) } #endif -static int -mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase) -{ - if ((MptDriverClass[index] == MPTSPI_DRIVER && - ioc->bus_type != SPI) || - (MptDriverClass[index] == MPTFC_DRIVER && - ioc->bus_type != FC) || - (MptDriverClass[index] == MPTSAS_DRIVER && - ioc->bus_type != SAS)) - /* make sure we only call the relevant reset handler - * for the bus */ - return 0; - return (MptResetHandlers[index])(ioc, reset_phase); -} - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mpt_do_ioc_recovery - Initialize or recover MPT adapter. @@ -1901,14 +1952,14 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if ((ret == 0) && MptResetHandlers[ii]) { dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n", ioc->name, ii)); - rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET); + rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET); handlers++; } if (alt_ioc_ready && MptResetHandlers[ii]) { drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", ioc->name, ioc->alt_ioc->name, ii)); - rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET); + rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); handlers++; } } @@ -3283,11 +3334,11 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) if (MptResetHandlers[ii]) { dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n", ioc->name, ii)); - r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET); + r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET); if (ioc->alt_ioc) { dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n", ioc->name, ioc->alt_ioc->name, ii)); - r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET); + r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET); } } } @@ -4887,7 +4938,7 @@ done_and_free: return rc; } -static int +int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) { IOCPage3_t *pIoc3; @@ -5095,13 +5146,13 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch) evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc); if (evnp == NULL) { - devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n", + devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n", ioc->name)); return 0; } memset(evnp, 0, sizeof(*evnp)); - devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp)); + devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp)); evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION; evnp->ChainOffset = 0; @@ -5722,11 +5773,11 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) if (MptResetHandlers[ii]) { dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n", ioc->name, ii)); - r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET); + r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET); if (ioc->alt_ioc) { dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n", ioc->name, ioc->alt_ioc->name, ii)); - r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET); + r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET); } } } @@ -5751,13 +5802,11 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) return rc; } -# define EVENT_DESCR_STR_SZ 100 - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static void EventDescriptionStr(u8 event, u32 evData0, char *evStr) { - char *ds = NULL; + char *ds; switch(event) { case MPI_EVENT_NONE: @@ -5794,9 +5843,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP) ds = "Loop State(LIP) Change"; else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE) - ds = "Loop State(LPE) Change"; /* ??? */ + ds = "Loop State(LPE) Change"; /* ??? */ else - ds = "Loop State(LPB) Change"; /* ??? */ + ds = "Loop State(LPB) Change"; /* ??? */ break; case MPI_EVENT_LOGOUT: ds = "Logout"; @@ -5858,31 +5907,23 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) break; case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: { - u8 id = (u8)(evData0); u8 ReasonCode = (u8)(evData0 >> 16); switch (ReasonCode) { case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: Added: id=%d", id); + ds = "SAS Device Status Change: Added"; break; case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: Deleted: id=%d", id); + ds = "SAS Device Status Change: Deleted"; break; case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: SMART Data: id=%d", - id); + ds = "SAS Device Status Change: SMART Data"; break; case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: No Persistancy " - "Added: id=%d", id); + ds = "SAS Device Status Change: No Persistancy Added"; break; default: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS Device Status Change: Unknown: id=%d", id); - break; + ds = "SAS Device Status Change: Unknown"; + break; } break; } @@ -5899,101 +5940,11 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) ds = "Persistent Table Full"; break; case MPI_EVENT_SAS_PHY_LINK_STATUS: - { - u8 LinkRates = (u8)(evData0 >> 8); - u8 PhyNumber = (u8)(evData0); - LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >> - MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT; - switch (LinkRates) { - case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" - " Rate Unknown",PhyNumber); - break; - case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" - " Phy Disabled",PhyNumber); - break; - case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" - " Failed Speed Nego",PhyNumber); - break; - case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" - " Sata OOB Completed",PhyNumber); - break; - case MPI_EVENT_SAS_PLS_LR_RATE_1_5: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" - " Rate 1.5 Gbps",PhyNumber); - break; - case MPI_EVENT_SAS_PLS_LR_RATE_3_0: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d:" - " Rate 3.0 Gpbs",PhyNumber); - break; - default: - snprintf(evStr, EVENT_DESCR_STR_SZ, - "SAS PHY Link Status: Phy=%d", PhyNumber); - break; - } + ds = "SAS PHY Link Status"; break; - } case MPI_EVENT_SAS_DISCOVERY_ERROR: ds = "SAS Discovery Error"; break; - case MPI_EVENT_IR_RESYNC_UPDATE: - { - u8 resync_complete = (u8)(evData0 >> 16); - snprintf(evStr, EVENT_DESCR_STR_SZ, - "IR Resync Update: Complete = %d:",resync_complete); - break; - } - case MPI_EVENT_IR2: - { - u8 ReasonCode = (u8)(evData0 >> 16); - switch (ReasonCode) { - case MPI_EVENT_IR2_RC_LD_STATE_CHANGED: - ds = "IR2: LD State Changed"; - break; - case MPI_EVENT_IR2_RC_PD_STATE_CHANGED: - ds = "IR2: PD State Changed"; - break; - case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL: - ds = "IR2: Bad Block Table Full"; - break; - case MPI_EVENT_IR2_RC_PD_INSERTED: - ds = "IR2: PD Inserted"; - break; - case MPI_EVENT_IR2_RC_PD_REMOVED: - ds = "IR2: PD Removed"; - break; - case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED: - ds = "IR2: Foreign CFG Detected"; - break; - case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR: - ds = "IR2: Rebuild Medium Error"; - break; - default: - ds = "IR2"; - break; - } - break; - } - case MPI_EVENT_SAS_DISCOVERY: - { - if (evData0) - ds = "SAS Discovery: Start"; - else - ds = "SAS Discovery: Stop"; - break; - } - case MPI_EVENT_LOG_ENTRY_ADDED: - ds = "SAS Log Entry Added"; - break; /* * MPT base "custom" events may be added here... @@ -6002,8 +5953,7 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) ds = "Unknown"; break; } - if (ds) - strncpy(evStr, ds, EVENT_DESCR_STR_SZ); + strcpy(evStr,ds); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -6025,7 +5975,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply int ii; int r = 0; int handlers = 0; - char evStr[EVENT_DESCR_STR_SZ]; + char evStr[100]; u8 event; /* @@ -6039,12 +5989,12 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply } EventDescriptionStr(event, evData0, evStr); - devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n", + devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n", ioc->name, - event, - evStr)); + evStr, + event)); -#if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS) +#if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS) printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO); for (ii = 0; ii < evDataLen; ii++) printk(" %08x", le32_to_cpu(pEventReply->Data[ii])); @@ -6103,7 +6053,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply */ for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { if (MptEvHandlers[ii]) { - devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n", + devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n", ioc->name, ii)); r += (*(MptEvHandlers[ii]))(ioc, pEventReply); handlers++; @@ -6115,10 +6065,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply * If needed, send (a single) EventAck. */ if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) { - devtverboseprintk((MYIOC_s_WARN_FMT + devtprintk((MYIOC_s_WARN_FMT "EventAck required\n",ioc->name)); if ((ii = SendEventAck(ioc, pEventReply)) != 0) { - devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n", + devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n", ioc->name, ii)); } } @@ -6255,8 +6205,8 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) "Abort", /* 12h */ "IO Not Yet Executed", /* 13h */ "IO Executed", /* 14h */ - "Persistant Reservation Out Not Affiliation Owner", /* 15h */ - "Open Transmit DMA Abort", /* 16h */ + NULL, /* 15h */ + NULL, /* 16h */ NULL, /* 17h */ NULL, /* 18h */ NULL, /* 19h */ @@ -6481,9 +6431,11 @@ EXPORT_SYMBOL(mpt_stm_index); EXPORT_SYMBOL(mpt_HardResetHandler); EXPORT_SYMBOL(mpt_config); EXPORT_SYMBOL(mpt_findImVolumes); +EXPORT_SYMBOL(mpt_read_ioc_pg_3); EXPORT_SYMBOL(mpt_alloc_fw_memory); EXPORT_SYMBOL(mpt_free_fw_memory); EXPORT_SYMBOL(mptbase_sas_persist_operation); +EXPORT_SYMBOL(mpt_alt_ioc_wait); EXPORT_SYMBOL(mptbase_GetFcPortPage0); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index f673cca50..723d54300 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -76,8 +76,8 @@ #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.03.09" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.09" +#define MPT_LINUX_VERSION_COMMON "3.03.07" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.07" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -331,7 +331,6 @@ typedef struct _SYSIF_REGS * VirtDevice - FC LUN device or SCSI target device */ typedef struct _VirtTarget { - struct scsi_target *starget; u8 tflags; u8 ioc_id; u8 target_id; @@ -344,10 +343,14 @@ typedef struct _VirtTarget { u8 type; /* byte 0 of Inquiry data */ u32 num_luns; u32 luns[8]; /* Max LUNs is 256 */ + u8 inq_data[8]; } VirtTarget; typedef struct _VirtDevice { - VirtTarget *vtarget; + VirtTarget *vtarget; + u8 ioc_id; + u8 bus_id; + u8 target_id; u8 configured_lun; u32 lun; } VirtDevice; @@ -361,7 +364,6 @@ typedef struct _VirtDevice { #define MPT_TARGET_FLAGS_Q_YES 0x08 #define MPT_TARGET_FLAGS_VALID_56 0x10 #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 -#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40 /* * /proc/mpt interface @@ -445,6 +447,13 @@ typedef struct _mpt_ioctl_events { * Substructure to store SCSI specific configuration page data */ /* dvStatus defines: */ +#define MPT_SCSICFG_NEGOTIATE 0x01 /* Negotiate on next IO */ +#define MPT_SCSICFG_NEED_DV 0x02 /* Schedule DV */ +#define MPT_SCSICFG_DV_PENDING 0x04 /* DV on this physical id pending */ +#define MPT_SCSICFG_DV_NOT_DONE 0x08 /* DV has not been performed */ +#define MPT_SCSICFG_BLK_NEGO 0x10 /* WriteSDP1 with WDTR and SDTR disabled */ +#define MPT_SCSICFG_RELOAD_IOC_PG3 0x20 /* IOC Pg 3 data is obsolete */ + /* Args passed to writeSDP1: */ #define MPT_SCSICFG_USE_NVRAM 0x01 /* WriteSDP1 using NVRAM */ #define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */ /* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */ @@ -455,6 +464,7 @@ typedef struct _SpiCfgData { IOCPage4_t *pIocPg4; /* SEP devices addressing */ dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */ int IocPg4Sz; /* IOCPage4 size */ + u8 dvStatus[MPT_MAX_SCSI_DEVICES]; u8 minSyncFactor; /* 0xFF if async */ u8 maxSyncOffset; /* 0 if async */ u8 maxBusWidth; /* 0 if narrow, 1 if wide */ @@ -464,11 +474,13 @@ typedef struct _SpiCfgData { u8 sdp0version; /* SDP0 version */ u8 sdp0length; /* SDP0 length */ u8 dvScheduled; /* 1 if scheduled */ + u8 forceDv; /* 1 to force DV scheduling */ u8 noQas; /* Disable QAS for this adapter */ u8 Saf_Te; /* 1 to force all Processors as * SAF-TE if Inquiry data length * is too short to check for SAF-TE */ + u8 mpt_dv; /* command line option: enhanced=1, basic=0 */ u8 bus_reset; /* 1 to allow bus reset */ u8 rsvd[1]; }SpiCfgData; @@ -489,6 +501,7 @@ typedef struct _RaidCfgData { #define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */ #define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */ +#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04 /* target mapped in vdev */ /* * data allocated for each fc rport device @@ -500,6 +513,7 @@ struct mptfc_rport_info struct scsi_target *starget; FCDevicePage0_t pg0; u8 flags; + u8 remap_needed; }; /* @@ -617,20 +631,16 @@ typedef struct _MPT_ADAPTER struct net_device *netdev; struct list_head sas_topology; struct mutex sas_topology_mutex; - struct mutex sas_discovery_mutex; - u8 sas_discovery_runtime; - u8 sas_discovery_ignore_events; - int sas_index; /* index refrencing */ MPT_SAS_MGMT sas_mgmt; int num_ports; struct work_struct mptscsih_persistTask; struct list_head fc_rports; + spinlock_t fc_rport_lock; /* list and ri flags */ spinlock_t fc_rescan_work_lock; int fc_rescan_work_count; struct work_struct fc_rescan_work; - char fc_rescan_work_q_name[KOBJ_NAME_LEN]; - struct workqueue_struct *fc_rescan_work_q; + } MPT_ADAPTER; /* @@ -718,18 +728,12 @@ typedef struct _mpt_sge { #define dhsprintk(x) #endif -#if defined(MPT_DEBUG_EVENTS) || defined(MPT_DEBUG_VERBOSE_EVENTS) +#ifdef MPT_DEBUG_EVENTS #define devtprintk(x) printk x #else #define devtprintk(x) #endif -#ifdef MPT_DEBUG_VERBOSE_EVENTS -#define devtverboseprintk(x) printk x -#else -#define devtverboseprintk(x) -#endif - #ifdef MPT_DEBUG_RESET #define drsprintk(x) printk x #else @@ -1026,8 +1030,10 @@ extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); extern int mpt_findImVolumes(MPT_ADAPTER *ioc); +extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum); +extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc); /* * Public data decl's... diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index b4967bb8a..9b64e0740 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -140,7 +140,7 @@ static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); * Event Handler function */ static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); -static struct fasync_struct *async_queue=NULL; +struct fasync_struct *async_queue=NULL; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -497,7 +497,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) if (event == 0x21 ) { ioc->aen_event_read_flag=1; dctlprintk(("Raised SIGIO to application\n")); - devtverboseprintk(("Raised SIGIO to application\n")); + devtprintk(("Raised SIGIO to application\n")); kill_fasync(&async_queue, SIGIO, POLL_IN); return 1; } @@ -515,7 +515,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) if (ioc->events && (ioc->eventTypes & ( 1 << event))) { ioc->aen_event_read_flag=1; dctlprintk(("Raised SIGIO to application\n")); - devtverboseprintk(("Raised SIGIO to application\n")); + devtprintk(("Raised SIGIO to application\n")); kill_fasync(&async_queue, SIGIO, POLL_IN); } return 1; @@ -2968,7 +2968,7 @@ static int __init mptctl_init(void) } if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) { - devtverboseprintk((KERN_INFO MYNAM + devtprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n")); } diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 856487741..c3a3499bc 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -154,7 +154,7 @@ MODULE_DEVICE_TABLE(pci, mptfc_pci_table); static struct scsi_transport_template *mptfc_transport_template = NULL; -static struct fc_function_template mptfc_transport_functions = { +struct fc_function_template mptfc_transport_functions = { .dd_fcrport_size = 8, .show_host_node_name = 1, .show_host_port_name = 1, @@ -341,10 +341,31 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid) rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low; rid->port_id = pg0->PortIdentifier; rid->roles = FC_RPORT_ROLE_UNKNOWN; + rid->roles |= FC_RPORT_ROLE_FCP_TARGET; + if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR) + rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR; return 0; } +static void +mptfc_remap_sdev(struct scsi_device *sdev, void *arg) +{ + VirtDevice *vdev; + VirtTarget *vtarget; + struct scsi_target *starget; + + starget = scsi_target(sdev); + if (starget->hostdata == arg) { + vtarget = arg; + vdev = sdev->hostdata; + if (vdev) { + vdev->bus_id = vtarget->bus_id; + vdev->target_id = vtarget->target_id; + } + } +} + static void mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) { @@ -352,18 +373,15 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) struct fc_rport *rport; struct mptfc_rport_info *ri; int new_ri = 1; - u64 pn, nn; + u64 pn; + unsigned long flags; VirtTarget *vtarget; - u32 roles = FC_RPORT_ROLE_UNKNOWN; if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0) return; - roles |= FC_RPORT_ROLE_FCP_TARGET; - if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR) - roles |= FC_RPORT_ROLE_FCP_INITIATOR; - /* scan list looking for a match */ + spin_lock_irqsave(&ioc->fc_rport_lock, flags); list_for_each_entry(ri, &ioc->fc_rports, list) { pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; if (pn == rport_ids.port_name) { /* match */ @@ -373,9 +391,11 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) } } if (new_ri) { /* allocate one */ + spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); if (!ri) return; + spin_lock_irqsave(&ioc->fc_rport_lock, flags); list_add_tail(&ri->list, &ioc->fc_rports); } @@ -385,11 +405,14 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */ if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) { ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED; + spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); rport = fc_remote_port_add(ioc->sh, channel, &rport_ids); + spin_lock_irqsave(&ioc->fc_rport_lock, flags); if (rport) { ri->rport = rport; if (new_ri) /* may have been reset by user */ rport->dev_loss_tmo = mptfc_dev_loss_tmo; + *((struct mptfc_rport_info **)rport->dd_data) = ri; /* * if already mapped, remap here. If not mapped, * target_alloc will allocate vtarget and map, @@ -400,22 +423,19 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) if (vtarget) { vtarget->target_id = pg0->CurrentTargetID; vtarget->bus_id = pg0->CurrentBus; + starget_for_each_device(ri->starget, + vtarget,mptfc_remap_sdev); } + ri->remap_needed = 0; } - *((struct mptfc_rport_info **)rport->dd_data) = ri; - /* scan will be scheduled once rport becomes a target */ - fc_remote_port_rolechg(rport,roles); - - pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; - nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low; dfcprintk ((MYIOC_s_INFO_FMT "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " "rport tid %d, tmo %d\n", ioc->name, - ioc->sh->host_no, + oc->sh->host_no, pg0->PortIdentifier, - (unsigned long long)nn, - (unsigned long long)pn, + pg0->WWNN, + pg0->WWPN, pg0->CurrentTargetID, ri->rport->scsi_target_id, ri->rport->dev_loss_tmo)); @@ -425,6 +445,8 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) ri = NULL; } } + spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); + } /* @@ -474,6 +496,7 @@ mptfc_target_alloc(struct scsi_target *starget) vtarget->target_id = ri->pg0.CurrentTargetID; vtarget->bus_id = ri->pg0.CurrentBus; ri->starget = starget; + ri->remap_needed = 0; rc = 0; } } @@ -491,7 +514,7 @@ mptfc_target_alloc(struct scsi_target *starget) * Return non-zero if allocation fails. * Init memory once per LUN. */ -static int +int mptfc_slave_alloc(struct scsi_device *sdev) { MPT_SCSI_HOST *hd; @@ -499,10 +522,10 @@ mptfc_slave_alloc(struct scsi_device *sdev) VirtDevice *vdev; struct scsi_target *starget; struct fc_rport *rport; + unsigned long flags; - starget = scsi_target(sdev); - rport = starget_to_rport(starget); + rport = starget_to_rport(scsi_target(sdev)); if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; @@ -516,8 +539,10 @@ mptfc_slave_alloc(struct scsi_device *sdev) return -ENOMEM; } + spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags); sdev->hostdata = vdev; + starget = scsi_target(sdev); vtarget = starget->hostdata; if (vtarget->num_luns == 0) { @@ -528,30 +553,23 @@ mptfc_slave_alloc(struct scsi_device *sdev) } vdev->vtarget = vtarget; + vdev->ioc_id = hd->ioc->id; vdev->lun = sdev->lun; + vdev->target_id = vtarget->target_id; + vdev->bus_id = vtarget->bus_id; - vtarget->num_luns++; + spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); + vtarget->num_luns++; -#ifdef DMPT_DEBUG_FC - { - u64 nn, pn; - struct mptfc_rport_info *ri; - ri = *((struct mptfc_rport_info **)rport->dd_data); - pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; - nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low; dfcprintk ((MYIOC_s_INFO_FMT "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " "CurrentTargetID %d, %x %llx %llx\n", - hd->ioc->name, + ioc->name, sdev->host->host_no, vtarget->num_luns, sdev->id, ri->pg0.CurrentTargetID, - ri->pg0.PortIdentifier, - (unsigned long long)pn, - (unsigned long long)nn)); - } -#endif + ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN)); return 0; } @@ -569,31 +587,11 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) done(SCpnt); return 0; } - - /* dd_data is null until finished adding target */ ri = *((struct mptfc_rport_info **)rport->dd_data); - if (unlikely(!ri)) { - dfcprintk ((MYIOC_s_INFO_FMT - "mptfc_qcmd.%d: %d:%d, dd_data is null.\n", - ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun)); - SCpnt->result = DID_IMM_RETRY << 16; - done(SCpnt); - return 0; - } + if (unlikely(ri->remap_needed)) + return SCSI_MLQUEUE_HOST_BUSY; - err = mptscsih_qcmd(SCpnt,done); -#ifdef DMPT_DEBUG_FC - if (unlikely(err)) { - dfcprintk ((MYIOC_s_INFO_FMT - "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero.\n", - ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun)); - } -#endif - return err; + return mptscsih_qcmd(SCpnt,done); } static void @@ -634,17 +632,18 @@ mptfc_rescan_devices(void *arg) MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; int ii; int work_to_do; - u64 pn; unsigned long flags; struct mptfc_rport_info *ri; do { /* start by tagging all ports as missing */ + spin_lock_irqsave(&ioc->fc_rport_lock,flags); list_for_each_entry(ri, &ioc->fc_rports, list) { if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING; } } + spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); /* * now rescan devices known to adapter, @@ -657,24 +656,33 @@ mptfc_rescan_devices(void *arg) } /* delete devices still missing */ + spin_lock_irqsave(&ioc->fc_rport_lock, flags); list_for_each_entry(ri, &ioc->fc_rports, list) { /* if newly missing, delete it */ - if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { + if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED | + MPT_RPORT_INFO_FLAGS_MISSING)) + == (MPT_RPORT_INFO_FLAGS_REGISTERED | + MPT_RPORT_INFO_FLAGS_MISSING)) { ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| MPT_RPORT_INFO_FLAGS_MISSING); - fc_remote_port_delete(ri->rport); /* won't sleep */ + ri->remap_needed = 1; + fc_remote_port_delete(ri->rport); + /* + * remote port not really deleted 'cause + * binding is by WWPN and driver only + * registers FCP_TARGETs but cannot trust + * data structures. + */ ri->rport = NULL; - - pn = (u64)ri->pg0.WWPN.High << 32 | - (u64)ri->pg0.WWPN.Low; dfcprintk ((MYIOC_s_INFO_FMT "mptfc_rescan.%d: %llx deleted\n", ioc->name, ioc->sh->host_no, - (unsigned long long)pn)); + ri->pg0.WWPN)); } } + spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); /* * allow multiple passes as target state @@ -879,23 +887,10 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_mptfc_probe; } - /* initialize workqueue */ - - snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d", - sh->host_no); - ioc->fc_rescan_work_q = - create_singlethread_workqueue(ioc->fc_rescan_work_q_name); - if (!ioc->fc_rescan_work_q) - goto out_mptfc_probe; - - /* - * scan for rports - - * by doing it via the workqueue, some locking is eliminated - */ - - ioc->fc_rescan_work_count = 1; - queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work); - flush_workqueue(ioc->fc_rescan_work_q); + for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { + mptfc_init_host_attr(ioc,ii); + mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); + } return 0; @@ -946,7 +941,7 @@ mptfc_init(void) mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) { - devtverboseprintk((KERN_INFO MYNAM + devtprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n")); } @@ -971,18 +966,8 @@ mptfc_init(void) static void __devexit mptfc_remove(struct pci_dev *pdev) { - MPT_ADAPTER *ioc = pci_get_drvdata(pdev); - struct mptfc_rport_info *p, *n; - struct workqueue_struct *work_q; - unsigned long flags; - - /* destroy workqueue */ - if ((work_q=ioc->fc_rescan_work_q)) { - spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - ioc->fc_rescan_work_q = NULL; - spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); - destroy_workqueue(work_q); - } + MPT_ADAPTER *ioc = pci_get_drvdata(pdev); + struct mptfc_rport_info *p, *n; fc_remove_host(ioc->sh); diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 314c3a275..73f595282 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -1152,7 +1152,10 @@ mpt_lan_receive_post_reply(struct net_device *dev, priv->mpt_rxfidx_tail, MPT_LAN_MAX_BUCKETS_OUT); - return -1; + panic("Damn it Jim! I'm a doctor, not a programmer! " + "Oh, wait a sec, I am a programmer. " + "And, who's Jim?!?!\n" + "Arrgghh! We've done it again!\n"); } if (remaining == 0) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index af6ec553f..2512d0e61 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -91,7 +91,6 @@ enum mptsas_hotplug_action { MPTSAS_DEL_DEVICE, MPTSAS_ADD_RAID, MPTSAS_DEL_RAID, - MPTSAS_IGNORE_EVENT, }; struct mptsas_hotplug_event { @@ -105,13 +104,6 @@ struct mptsas_hotplug_event { u16 handle; u16 parent_handle; u8 phy_id; - u8 phys_disk_num; - u8 phys_disk_num_valid; -}; - -struct mptsas_discovery_event { - struct work_struct work; - MPT_ADAPTER *ioc; }; /* @@ -125,8 +117,6 @@ struct mptsas_discovery_event { struct mptsas_devinfo { u16 handle; /* unique id to address this device */ u16 handle_parent; /* unique id to address parent device */ - u16 handle_enclosure; /* enclosure identifier of the enclosure */ - u16 slot; /* physical slot in enclosure */ u8 phy_id; /* phy number of parent device */ u8 port_id; /* sas physical port this device is assoc'd with */ @@ -147,7 +137,6 @@ struct mptsas_phyinfo { struct mptsas_devinfo attached; /* point to attached device info */ struct sas_phy *phy; struct sas_rphy *rphy; - struct scsi_target *starget; }; struct mptsas_portinfo { @@ -157,17 +146,6 @@ struct mptsas_portinfo { struct mptsas_phyinfo *phy_info; }; -struct mptsas_enclosure { - u64 enclosure_logical_id; /* The WWN for the enclosure */ - u16 enclosure_handle; /* unique id to address this */ - u16 flags; /* details enclosure management */ - u16 num_slot; /* num slots */ - u16 start_slot; /* first slot */ - u8 start_id; /* starting logical target id */ - u8 start_channel; /* starting logical channel id */ - u8 sep_id; /* SEP device logical target id */ - u8 sep_channel; /* SEP channel logical channel id */ -}; #ifdef SASDEBUG static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) @@ -227,7 +205,6 @@ static void mptsas_print_device_pg0(SasDevicePage0_t *pg0) printk("---- SAS DEVICE PAGE 0 ---------\n"); printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)); - printk("Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle)); printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)); printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot)); printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address)); @@ -266,139 +243,6 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1) #define mptsas_print_expander_pg1(pg1) do { } while (0) #endif -static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy) -{ - struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); - return ((MPT_SCSI_HOST *)shost->hostdata)->ioc; -} - -static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy) -{ - struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); - return ((MPT_SCSI_HOST *)shost->hostdata)->ioc; -} - -/* - * mptsas_find_portinfo_by_handle - * - * This function should be called with the sas_topology_mutex already held - */ -static struct mptsas_portinfo * -mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) -{ - struct mptsas_portinfo *port_info, *rc=NULL; - int i; - - list_for_each_entry(port_info, &ioc->sas_topology, list) - for (i = 0; i < port_info->num_phys; i++) - if (port_info->phy_info[i].identify.handle == handle) { - rc = port_info; - goto out; - } - out: - return rc; -} - -/* - * Returns true if there is a scsi end device - */ -static inline int -mptsas_is_end_device(struct mptsas_devinfo * attached) -{ - if ((attached->handle) && - (attached->device_info & - MPI_SAS_DEVICE_INFO_END_DEVICE) && - ((attached->device_info & - MPI_SAS_DEVICE_INFO_SSP_TARGET) | - (attached->device_info & - MPI_SAS_DEVICE_INFO_STP_TARGET) | - (attached->device_info & - MPI_SAS_DEVICE_INFO_SATA_DEVICE))) - return 1; - else - return 0; -} - -static int -mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, - u32 form, u32 form_specific) -{ - ConfigExtendedPageHeader_t hdr; - CONFIGPARMS cfg; - SasEnclosurePage0_t *buffer; - dma_addr_t dma_handle; - int error; - __le64 le_identifier; - - memset(&hdr, 0, sizeof(hdr)); - hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION; - hdr.PageNumber = 0; - hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; - hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE; - - cfg.cfghdr.ehdr = &hdr; - cfg.physAddr = -1; - cfg.pageAddr = form + form_specific; - cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; - cfg.dir = 0; /* read */ - cfg.timeout = 10; - - error = mpt_config(ioc, &cfg); - if (error) - goto out; - if (!hdr.ExtPageLength) { - error = -ENXIO; - goto out; - } - - buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, - &dma_handle); - if (!buffer) { - error = -ENOMEM; - goto out; - } - - cfg.physAddr = dma_handle; - cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; - - error = mpt_config(ioc, &cfg); - if (error) - goto out_free_consistent; - - /* save config data */ - memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64)); - enclosure->enclosure_logical_id = le64_to_cpu(le_identifier); - enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle); - enclosure->flags = le16_to_cpu(buffer->Flags); - enclosure->num_slot = le16_to_cpu(buffer->NumSlots); - enclosure->start_slot = le16_to_cpu(buffer->StartSlot); - enclosure->start_id = buffer->StartTargetID; - enclosure->start_channel = buffer->StartBus; - enclosure->sep_id = buffer->SEPTargetID; - enclosure->sep_channel = buffer->SEPBus; - - out_free_consistent: - pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, - buffer, dma_handle); - out: - return error; -} - -static int -mptsas_slave_configure(struct scsi_device *sdev) -{ - struct Scsi_Host *host = sdev->host; - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; - - /* - * RAID volumes placed beyond the last expected port. - * Ignore sending sas mode pages in that case.. - */ - if (sdev->channel < hd->ioc->num_ports) - sas_read_port_mode_page(sdev); - - return mptscsih_slave_configure(sdev); -} /* * This is pretty ugly. We will be able to seriously clean it up @@ -415,7 +259,6 @@ mptsas_slave_alloc(struct scsi_device *sdev) VirtTarget *vtarget; VirtDevice *vdev; struct scsi_target *starget; - u32 target_id; int i; vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); @@ -424,10 +267,10 @@ mptsas_slave_alloc(struct scsi_device *sdev) hd->ioc->name, sizeof(VirtDevice)); return -ENOMEM; } + vdev->ioc_id = hd->ioc->id; sdev->hostdata = vdev; starget = scsi_target(sdev); vtarget = starget->hostdata; - vtarget->ioc_id = hd->ioc->id; vdev->vtarget = vtarget; if (vtarget->num_luns == 0) { vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; @@ -438,8 +281,8 @@ mptsas_slave_alloc(struct scsi_device *sdev) RAID volumes placed beyond the last expected port. */ if (sdev->channel == hd->ioc->num_ports) { - target_id = sdev->id; - vtarget->bus_id = 0; + vdev->target_id = sdev->id; + vdev->bus_id = 0; vdev->lun = 0; goto out; } @@ -450,21 +293,11 @@ mptsas_slave_alloc(struct scsi_device *sdev) for (i = 0; i < p->num_phys; i++) { if (p->phy_info[i].attached.sas_address == rphy->identify.sas_address) { - target_id = p->phy_info[i].attached.id; - vtarget->bus_id = p->phy_info[i].attached.channel; + vdev->target_id = + p->phy_info[i].attached.id; + vdev->bus_id = p->phy_info[i].attached.channel; vdev->lun = sdev->lun; - p->phy_info[i].starget = sdev->sdev_target; - /* - * Exposing hidden disk (RAID) - */ - if (mptscsih_is_phys_disk(hd->ioc, target_id)) { - target_id = mptscsih_raid_id_to_num(hd, - target_id); - vdev->vtarget->tflags |= - MPT_TARGET_FLAGS_RAID_COMPONENT; - sdev->no_uld_attach = 1; - } - mutex_unlock(&hd->ioc->sas_topology_mutex); + mutex_unlock(&hd->ioc->sas_topology_mutex); goto out; } } @@ -475,7 +308,9 @@ mptsas_slave_alloc(struct scsi_device *sdev) return -ENXIO; out: - vtarget->target_id = target_id; + vtarget->ioc_id = vdev->ioc_id; + vtarget->target_id = vdev->target_id; + vtarget->bus_id = vdev->bus_id; vtarget->num_luns++; return 0; } @@ -485,8 +320,32 @@ mptsas_slave_destroy(struct scsi_device *sdev) { struct Scsi_Host *host = sdev->host; MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + struct sas_rphy *rphy; + struct mptsas_portinfo *p; + int i; VirtDevice *vdev; + /* + * Handle hotplug removal case. + * We need to clear out attached data structure. + */ + rphy = dev_to_rphy(sdev->sdev_target->dev.parent); + + mutex_lock(&hd->ioc->sas_topology_mutex); + list_for_each_entry(p, &hd->ioc->sas_topology, list) { + for (i = 0; i < p->num_phys; i++) { + if (p->phy_info[i].attached.sas_address == + rphy->identify.sas_address) { + memset(&p->phy_info[i].attached, 0, + sizeof(struct mptsas_devinfo)); + p->phy_info[i].rphy = NULL; + goto out; + } + } + } + + out: + mutex_unlock(&hd->ioc->sas_topology_mutex); /* * Issue target reset to flush firmware outstanding commands. */ @@ -494,8 +353,8 @@ mptsas_slave_destroy(struct scsi_device *sdev) if (vdev->configured_lun){ if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, - vdev->vtarget->bus_id, - vdev->vtarget->target_id, + vdev->bus_id, + vdev->target_id, 0, 0, 5 /* 5 second timeout */) < 0){ @@ -505,7 +364,7 @@ mptsas_slave_destroy(struct scsi_device *sdev) printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt id=%d TARGET_RESET\n", hd->ioc->name, - vdev->vtarget->target_id); + vdev->target_id); hd->tmPending = 0; hd->tmState = TM_STATE_NONE; @@ -523,7 +382,7 @@ static struct scsi_host_template mptsas_driver_template = { .queuecommand = mptscsih_qcmd, .target_alloc = mptscsih_target_alloc, .slave_alloc = mptsas_slave_alloc, - .slave_configure = mptsas_slave_configure, + .slave_configure = mptscsih_slave_configure, .target_destroy = mptscsih_target_destroy, .slave_destroy = mptsas_slave_destroy, .change_queue_depth = mptscsih_change_queue_depth, @@ -540,6 +399,12 @@ static struct scsi_host_template mptsas_driver_template = { .use_clustering = ENABLE_CLUSTERING, }; +static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy) +{ + struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); + return ((MPT_SCSI_HOST *)shost->hostdata)->ioc; +} + static int mptsas_get_linkerrors(struct sas_phy *phy) { MPT_ADAPTER *ioc = phy_to_ioc(phy); @@ -681,67 +546,8 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset) return error; } -static int -mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) -{ - MPT_ADAPTER *ioc = rphy_to_ioc(rphy); - int i, error; - struct mptsas_portinfo *p; - struct mptsas_enclosure enclosure_info; - u64 enclosure_handle; - - mutex_lock(&ioc->sas_topology_mutex); - list_for_each_entry(p, &ioc->sas_topology, list) { - for (i = 0; i < p->num_phys; i++) { - if (p->phy_info[i].attached.sas_address == - rphy->identify.sas_address) { - enclosure_handle = p->phy_info[i]. - attached.handle_enclosure; - goto found_info; - } - } - } - mutex_unlock(&ioc->sas_topology_mutex); - return -ENXIO; - - found_info: - mutex_unlock(&ioc->sas_topology_mutex); - memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure)); - error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info, - (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE << - MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle); - if (!error) - *identifier = enclosure_info.enclosure_logical_id; - return error; -} - -static int -mptsas_get_bay_identifier(struct sas_rphy *rphy) -{ - MPT_ADAPTER *ioc = rphy_to_ioc(rphy); - struct mptsas_portinfo *p; - int i, rc; - - mutex_lock(&ioc->sas_topology_mutex); - list_for_each_entry(p, &ioc->sas_topology, list) { - for (i = 0; i < p->num_phys; i++) { - if (p->phy_info[i].attached.sas_address == - rphy->identify.sas_address) { - rc = p->phy_info[i].attached.slot; - goto out; - } - } - } - rc = -ENXIO; - out: - mutex_unlock(&ioc->sas_topology_mutex); - return rc; -} - static struct sas_function_template mptsas_transport_functions = { .get_linkerrors = mptsas_get_linkerrors, - .get_enclosure_identifier = mptsas_get_enclosure_identifier, - .get_bay_identifier = mptsas_get_bay_identifier, .phy_reset = mptsas_phy_reset, }; @@ -801,9 +607,6 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) goto out_free_consistent; } - if (port_info->num_phys) - port_info->handle = - le16_to_cpu(buffer->PhyData[0].ControllerDevHandle); for (i = 0; i < port_info->num_phys; i++) { mptsas_print_phy_data(&buffer->PhyData[i]); port_info->phy_info[i].phy_id = i; @@ -893,11 +696,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, SasDevicePage0_t *buffer; dma_addr_t dma_handle; __le64 sas_address; - int error=0; - - if (ioc->sas_discovery_runtime && - mptsas_is_end_device(device_info)) - goto out; + int error; hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION; hdr.ExtPageLength = 0; @@ -914,7 +713,6 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, cfg.dir = 0; /* read */ cfg.timeout = 10; - memset(device_info, 0, sizeof(struct mptsas_devinfo)); error = mpt_config(ioc, &cfg); if (error) goto out; @@ -941,9 +739,6 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, device_info->handle = le16_to_cpu(buffer->DevHandle); device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle); - device_info->handle_enclosure = - le16_to_cpu(buffer->EnclosureHandle); - device_info->slot = le16_to_cpu(buffer->Slot); device_info->phy_id = buffer->PhyNum; device_info->port_id = buffer->PhysicalPort; device_info->id = buffer->TargetID; @@ -985,7 +780,6 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, cfg.dir = 0; /* read */ cfg.timeout = 10; - memset(port_info, 0, sizeof(struct mptsas_portinfo)); error = mpt_config(ioc, &cfg); if (error) goto out; @@ -1034,11 +828,7 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, CONFIGPARMS cfg; SasExpanderPage1_t *buffer; dma_addr_t dma_handle; - int error=0; - - if (ioc->sas_discovery_runtime && - mptsas_is_end_device(&phy_info->attached)) - goto out; + int error; hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; hdr.ExtPageLength = 0; @@ -1090,6 +880,7 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle); phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle); + out_free_consistent: pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, buffer, dma_handle); @@ -1097,6 +888,26 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, return error; } +/* + * Returns true if there is a scsi end device + */ +static inline int +mptsas_is_end_device(struct mptsas_devinfo * attached) +{ + if ((attached->handle) && + (attached->device_info & + MPI_SAS_DEVICE_INFO_END_DEVICE) && + ((attached->device_info & + MPI_SAS_DEVICE_INFO_SSP_TARGET) | + (attached->device_info & + MPI_SAS_DEVICE_INFO_STP_TARGET) | + (attached->device_info & + MPI_SAS_DEVICE_INFO_SATA_DEVICE))) + return 1; + else + return 0; +} + static void mptsas_parse_device_info(struct sas_identify *identify, struct mptsas_devinfo *device_info) @@ -1159,19 +970,12 @@ mptsas_parse_device_info(struct sas_identify *identify, static int mptsas_probe_one_phy(struct device *dev, struct mptsas_phyinfo *phy_info, int index, int local) { - MPT_ADAPTER *ioc; struct sas_phy *phy; int error; - if (!dev) - return -ENODEV; - - if (!phy_info->phy) { - phy = sas_phy_alloc(dev, index); - if (!phy) - return -ENOMEM; - } else - phy = phy_info->phy; + phy = sas_phy_alloc(dev, index); + if (!phy) + return -ENOMEM; phy->port_identifier = phy_info->port_id; mptsas_parse_device_info(&phy->identify, &phy_info->identify); @@ -1257,54 +1061,24 @@ static int mptsas_probe_one_phy(struct device *dev, break; } - if (!phy_info->phy) { - - if (local) - phy->local_attached = 1; + if (local) + phy->local_attached = 1; - error = sas_phy_add(phy); - if (error) { - sas_phy_free(phy); - return error; - } - phy_info->phy = phy; + error = sas_phy_add(phy); + if (error) { + sas_phy_free(phy); + return error; } + phy_info->phy = phy; - if ((phy_info->attached.handle) && - (!phy_info->rphy)) { - + if (phy_info->attached.handle) { struct sas_rphy *rphy; - struct sas_identify identify; - - ioc = phy_to_ioc(phy_info->phy); - /* - * Let the hotplug_work thread handle processing - * the adding/removing of devices that occur - * after start of day. - */ - if (ioc->sas_discovery_runtime && - mptsas_is_end_device(&phy_info->attached)) - return 0; - - mptsas_parse_device_info(&identify, &phy_info->attached); - switch (identify.device_type) { - case SAS_END_DEVICE: - rphy = sas_end_device_alloc(phy); - break; - case SAS_EDGE_EXPANDER_DEVICE: - case SAS_FANOUT_EXPANDER_DEVICE: - rphy = sas_expander_alloc(phy, identify.device_type); - break; - default: - rphy = NULL; - break; - } + rphy = sas_rphy_alloc(phy); if (!rphy) return 0; /* non-fatal: an rphy can be added later */ - rphy->identify = identify; - + mptsas_parse_device_info(&rphy->identify, &phy_info->attached); error = sas_rphy_add(rphy); if (error) { sas_rphy_free(rphy); @@ -1318,37 +1092,24 @@ static int mptsas_probe_one_phy(struct device *dev, } static int -mptsas_probe_hba_phys(MPT_ADAPTER *ioc) +mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index) { - struct mptsas_portinfo *port_info, *hba; + struct mptsas_portinfo *port_info; u32 handle = 0xFFFF; int error = -ENOMEM, i; - hba = kzalloc(sizeof(*port_info), GFP_KERNEL); - if (! hba) + port_info = kzalloc(sizeof(*port_info), GFP_KERNEL); + if (!port_info) goto out; - error = mptsas_sas_io_unit_pg0(ioc, hba); + error = mptsas_sas_io_unit_pg0(ioc, port_info); if (error) goto out_free_port_info; + ioc->num_ports = port_info->num_phys; mutex_lock(&ioc->sas_topology_mutex); - port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle); - if (!port_info) { - port_info = hba; - list_add_tail(&port_info->list, &ioc->sas_topology); - } else { - port_info->handle = hba->handle; - for (i = 0; i < hba->num_phys; i++) - port_info->phy_info[i].negotiated_link_rate = - hba->phy_info[i].negotiated_link_rate; - if (hba->phy_info) - kfree(hba->phy_info); - kfree(hba); - hba = NULL; - } + list_add_tail(&port_info->list, &ioc->sas_topology); mutex_unlock(&ioc->sas_topology_mutex); - ioc->num_ports = port_info->num_phys; for (i = 0; i < port_info->num_phys; i++) { mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], @@ -1371,49 +1132,38 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) } mptsas_probe_one_phy(&ioc->sh->shost_gendev, - &port_info->phy_info[i], ioc->sas_index, 1); - ioc->sas_index++; + &port_info->phy_info[i], *index, 1); + (*index)++; } return 0; out_free_port_info: - if (hba) - kfree(hba); + kfree(port_info); out: return error; } static int -mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) +mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index) { - struct mptsas_portinfo *port_info, *p, *ex; + struct mptsas_portinfo *port_info, *p; int error = -ENOMEM, i, j; - ex = kzalloc(sizeof(*port_info), GFP_KERNEL); - if (!ex) + port_info = kzalloc(sizeof(*port_info), GFP_KERNEL); + if (!port_info) goto out; - error = mptsas_sas_expander_pg0(ioc, ex, + error = mptsas_sas_expander_pg0(ioc, port_info, (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle); if (error) goto out_free_port_info; - *handle = ex->handle; + *handle = port_info->handle; mutex_lock(&ioc->sas_topology_mutex); - port_info = mptsas_find_portinfo_by_handle(ioc, *handle); - if (!port_info) { - port_info = ex; - list_add_tail(&port_info->list, &ioc->sas_topology); - } else { - port_info->handle = ex->handle; - if (ex->phy_info) - kfree(ex->phy_info); - kfree(ex); - ex = NULL; - } + list_add_tail(&port_info->list, &ioc->sas_topology); mutex_unlock(&ioc->sas_topology_mutex); for (i = 0; i < port_info->num_phys; i++) { @@ -1439,8 +1189,6 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << MPI_SAS_DEVICE_PGAD_FORM_SHIFT), port_info->phy_info[i].attached.handle); - port_info->phy_info[i].attached.phy_id = - port_info->phy_info[i].phy_id; } /* @@ -1460,137 +1208,27 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) mutex_unlock(&ioc->sas_topology_mutex); mptsas_probe_one_phy(parent, &port_info->phy_info[i], - ioc->sas_index, 0); - ioc->sas_index++; + *index, 0); + (*index)++; } return 0; out_free_port_info: - if (ex) { - if (ex->phy_info) - kfree(ex->phy_info); - kfree(ex); - } + kfree(port_info); out: return error; } -/* - * mptsas_delete_expander_phys - * - * - * This will traverse topology, and remove expanders - * that are no longer present - */ -static void -mptsas_delete_expander_phys(MPT_ADAPTER *ioc) -{ - struct mptsas_portinfo buffer; - struct mptsas_portinfo *port_info, *n, *parent; - int i; - - 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))) - continue; - - if (mptsas_sas_expander_pg0(ioc, &buffer, - (MPI_SAS_EXPAND_PGAD_FORM_HANDLE << - MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) { - - /* - * Obtain the port_info instance to the parent port - */ - parent = mptsas_find_portinfo_by_handle(ioc, - port_info->phy_info[0].identify.handle_parent); - - if (!parent) - goto next_port; - - /* - * Delete rphys in the parent that point - * to this expander. The transport layer will - * cleanup all the children. - */ - for (i = 0; i < parent->num_phys; i++) { - if ((!parent->phy_info[i].rphy) || - (parent->phy_info[i].attached.sas_address != - port_info->phy_info[i].identify.sas_address)) - continue; - sas_rphy_delete(parent->phy_info[i].rphy); - memset(&parent->phy_info[i].attached, 0, - sizeof(struct mptsas_devinfo)); - parent->phy_info[i].rphy = NULL; - parent->phy_info[i].starget = NULL; - } - next_port: - list_del(&port_info->list); - if (port_info->phy_info) - kfree(port_info->phy_info); - kfree(port_info); - } - /* - * Free this memory allocated from inside - * mptsas_sas_expander_pg0 - */ - if (buffer.phy_info) - kfree(buffer.phy_info); - } - mutex_unlock(&ioc->sas_topology_mutex); -} - -/* - * Start of day discovery - */ static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc) { u32 handle = 0xFFFF; - int i; + int index = 0; - mutex_lock(&ioc->sas_discovery_mutex); - mptsas_probe_hba_phys(ioc); - while (!mptsas_probe_expander_phys(ioc, &handle)) + mptsas_probe_hba_phys(ioc, &index); + while (!mptsas_probe_expander_phys(ioc, &handle, &index)) ; - /* - Reporting RAID volumes. - */ - if (!ioc->raid_data.pIocPg2) - goto out; - if (!ioc->raid_data.pIocPg2->NumActiveVolumes) - goto out; - for (i=0; iraid_data.pIocPg2->NumActiveVolumes; i++) { - scsi_add_device(ioc->sh, ioc->num_ports, - ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); - } - out: - mutex_unlock(&ioc->sas_discovery_mutex); -} - -/* - * Work queue thread to handle Runtime discovery - * Mere purpose is the hot add/delete of expanders - */ -static void -mptscsih_discovery_work(void * arg) -{ - struct mptsas_discovery_event *ev = arg; - MPT_ADAPTER *ioc = ev->ioc; - u32 handle = 0xFFFF; - - mutex_lock(&ioc->sas_discovery_mutex); - ioc->sas_discovery_runtime=1; - mptsas_delete_expander_phys(ioc); - mptsas_probe_hba_phys(ioc); - while (!mptsas_probe_expander_phys(ioc, &handle)) - ; - kfree(ev); - ioc->sas_discovery_runtime=0; - mutex_unlock(&ioc->sas_discovery_mutex); } static struct mptsas_phyinfo * @@ -1608,8 +1246,10 @@ mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id) (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << MPI_SAS_DEVICE_PGAD_FORM_SHIFT), parent_handle); - if (error) + if (error) { + printk("mptsas: failed to retrieve device page\n"); return NULL; + } /* * The phy_info structures are never deallocated during lifetime of @@ -1656,35 +1296,6 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) return phy_info; } -/* - * Work queue thread to clear the persitency table - */ -static void -mptscsih_sas_persist_clear_table(void * arg) -{ - MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; - - mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); -} - -static void -mptsas_reprobe_lun(struct scsi_device *sdev, void *data) -{ - sdev->no_uld_attach = data ? 1 : 0; - scsi_device_reprobe(sdev); -} - -static void -mptsas_reprobe_target(struct scsi_target *starget, int uld_attach) -{ - starget_for_each_device(starget, uld_attach ? (void *)1 : NULL, - mptsas_reprobe_lun); -} - - -/* - * Work queue thread to handle SAS hotplug events - */ static void mptsas_hotplug_work(void *arg) { @@ -1693,39 +1304,16 @@ mptsas_hotplug_work(void *arg) struct mptsas_phyinfo *phy_info; struct sas_rphy *rphy; struct scsi_device *sdev; - struct sas_identify identify; char *ds = NULL; struct mptsas_devinfo sas_device; - VirtTarget *vtarget; - - mutex_lock(&ioc->sas_discovery_mutex); switch (ev->event_type) { case MPTSAS_DEL_DEVICE: phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id); - - /* - * Sanity checks, for non-existing phys and remote rphys. - */ - if (!phy_info) - break; - if (!phy_info->rphy) + if (!phy_info) { + printk("mptsas: remove event for non-existant PHY.\n"); break; - if (phy_info->starget) { - vtarget = phy_info->starget->hostdata; - - if (!vtarget) - break; - /* - * Handling RAID components - */ - if (ev->phys_disk_num_valid) { - vtarget->target_id = ev->phys_disk_num; - vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; - mptsas_reprobe_target(vtarget->starget, 1); - break; - } } if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) @@ -1739,77 +1327,55 @@ mptsas_hotplug_work(void *arg) "removing %s device, channel %d, id %d, phy %d\n", ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); - sas_rphy_delete(phy_info->rphy); - memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); - phy_info->rphy = NULL; - phy_info->starget = NULL; + if (phy_info->rphy) { + sas_rphy_delete(phy_info->rphy); + phy_info->rphy = NULL; + } break; case MPTSAS_ADD_DEVICE: - if (ev->phys_disk_num_valid) - mpt_findImVolumes(ioc); - /* - * Refresh sas device pg0 data + * When there is no sas address, + * RAID volumes are being deleted, + * and hidden phy disk are being added. + * We don't know the SAS data yet, + * so lookup sas device page to get + * pertaining info */ - if (mptsas_sas_device_pg0(ioc, &sas_device, - (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << - MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) - break; - - phy_info = mptsas_find_phyinfo_by_parent(ioc, - sas_device.handle_parent, sas_device.phy_id); - - if (!phy_info) { - u32 handle = 0xFFFF; - - /* - * Its possible when an expander has been hot added - * containing attached devices, the sas firmware - * may send a RC_ADDED event prior to the - * DISCOVERY STOP event. If that occurs, our - * view of the topology in the driver in respect to this - * expander might of not been setup, and we hit this - * condition. - * Therefore, this code kicks off discovery to - * refresh the data. - * Then again, we check whether the parent phy has - * been created. - */ - ioc->sas_discovery_runtime=1; - mptsas_delete_expander_phys(ioc); - mptsas_probe_hba_phys(ioc); - while (!mptsas_probe_expander_phys(ioc, &handle)) - ; - ioc->sas_discovery_runtime=0; - - phy_info = mptsas_find_phyinfo_by_parent(ioc, - sas_device.handle_parent, sas_device.phy_id); - if (!phy_info) + if (!ev->sas_address) { + if (mptsas_sas_device_pg0(ioc, + &sas_device, ev->id, + (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << + MPI_SAS_DEVICE_PGAD_FORM_SHIFT))) break; + ev->handle = sas_device.handle; + ev->parent_handle = sas_device.handle_parent; + ev->channel = sas_device.channel; + ev->phy_id = sas_device.phy_id; + ev->sas_address = sas_device.sas_address; + ev->device_info = sas_device.device_info; } - if (phy_info->starget) { - vtarget = phy_info->starget->hostdata; - - if (!vtarget) - break; - /* - * Handling RAID components - */ - if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { - vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; - vtarget->target_id = ev->id; - mptsas_reprobe_target(phy_info->starget, 0); - } + phy_info = mptsas_find_phyinfo_by_parent(ioc, + ev->parent_handle, ev->phy_id); + if (!phy_info) { + printk("mptsas: add event for non-existant PHY.\n"); break; } - if (phy_info->rphy) + if (phy_info->rphy) { + printk("mptsas: trying to add existing device.\n"); break; + } - memcpy(&phy_info->attached, &sas_device, - sizeof(struct mptsas_devinfo)); + /* fill attached info */ + phy_info->attached.handle = ev->handle; + phy_info->attached.phy_id = ev->phy_id; + phy_info->attached.port_id = phy_info->identify.port_id; + phy_info->attached.id = ev->id; + phy_info->attached.channel = ev->channel; + phy_info->attached.sas_address = ev->sas_address; + phy_info->attached.device_info = ev->device_info; if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) ds = "ssp"; @@ -1822,23 +1388,13 @@ mptsas_hotplug_work(void *arg) "attaching %s device, channel %d, id %d, phy %d\n", ioc->name, ds, ev->channel, ev->id, ev->phy_id); - mptsas_parse_device_info(&identify, &phy_info->attached); - switch (identify.device_type) { - case SAS_END_DEVICE: - rphy = sas_end_device_alloc(phy_info->phy); - break; - case SAS_EDGE_EXPANDER_DEVICE: - case SAS_FANOUT_EXPANDER_DEVICE: - rphy = sas_expander_alloc(phy_info->phy, identify.device_type); - break; - default: - rphy = NULL; - break; - } + + rphy = sas_rphy_alloc(phy_info->phy); if (!rphy) break; /* non-fatal: an rphy can be added later */ - rphy->identify = identify; + rphy->scsi_target_id = phy_info->attached.id; + mptsas_parse_device_info(&rphy->identify, &phy_info->attached); if (sas_rphy_add(rphy)) { sas_rphy_free(rphy); break; @@ -1857,7 +1413,7 @@ mptsas_hotplug_work(void *arg) break; } printk(MYIOC_s_INFO_FMT - "attaching raid volume, channel %d, id %d\n", + "attaching device, channel %d, id %d\n", ioc->name, ioc->num_ports, ev->id); scsi_add_device(ioc->sh, ioc->num_ports, @@ -1874,19 +1430,15 @@ mptsas_hotplug_work(void *arg) if (!sdev) break; printk(MYIOC_s_INFO_FMT - "removing raid volume, channel %d, id %d\n", + "removing device, channel %d, id %d\n", ioc->name, ioc->num_ports, ev->id); scsi_remove_device(sdev); scsi_device_put(sdev); mpt_findImVolumes(ioc); break; - case MPTSAS_IGNORE_EVENT: - default: - break; } kfree(ev); - mutex_unlock(&ioc->sas_discovery_mutex); } static void @@ -1903,51 +1455,35 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0) return; - switch (sas_event_data->ReasonCode) { - case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: - case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: - ev = kmalloc(sizeof(*ev), GFP_ATOMIC); - if (!ev) { - printk(KERN_WARNING "mptsas: lost hotplug event\n"); - break; - } + if ((sas_event_data->ReasonCode & + (MPI_EVENT_SAS_DEV_STAT_RC_ADDED | + MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0) + return; - INIT_WORK(&ev->work, mptsas_hotplug_work, ev); - ev->ioc = ioc; - ev->handle = le16_to_cpu(sas_event_data->DevHandle); - ev->parent_handle = - le16_to_cpu(sas_event_data->ParentDevHandle); - ev->channel = sas_event_data->Bus; - ev->id = sas_event_data->TargetID; - ev->phy_id = sas_event_data->PhyNum; - memcpy(&sas_address, &sas_event_data->SASAddress, - sizeof(__le64)); - ev->sas_address = le64_to_cpu(sas_address); - ev->device_info = device_info; - - if (sas_event_data->ReasonCode & - MPI_EVENT_SAS_DEV_STAT_RC_ADDED) - ev->event_type = MPTSAS_ADD_DEVICE; - else - ev->event_type = MPTSAS_DEL_DEVICE; - schedule_work(&ev->work); - break; - case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: - /* - * Persistent table is full. - */ - INIT_WORK(&ioc->mptscsih_persistTask, - mptscsih_sas_persist_clear_table, - (void *)ioc); - schedule_work(&ioc->mptscsih_persistTask); - break; - case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: - /* TODO */ - case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: - /* TODO */ - default: - break; + ev = kmalloc(sizeof(*ev), GFP_ATOMIC); + if (!ev) { + printk(KERN_WARNING "mptsas: lost hotplug event\n"); + return; } + + + INIT_WORK(&ev->work, mptsas_hotplug_work, ev); + ev->ioc = ioc; + ev->handle = le16_to_cpu(sas_event_data->DevHandle); + ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle); + ev->channel = sas_event_data->Bus; + ev->id = sas_event_data->TargetID; + ev->phy_id = sas_event_data->PhyNum; + memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64)); + ev->sas_address = le64_to_cpu(sas_address); + ev->device_info = device_info; + + if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED) + ev->event_type = MPTSAS_ADD_DEVICE; + else + ev->event_type = MPTSAS_DEL_DEVICE; + + schedule_work(&ev->work); } static void @@ -1955,8 +1491,7 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, EVENT_DATA_RAID *raid_event_data) { struct mptsas_hotplug_event *ev; - int status = le32_to_cpu(raid_event_data->SettingsStatus); - int state = (status >> 8) & 0xff; + RAID_VOL0_STATUS * volumeStatus; if (ioc->bus_type != SAS) return; @@ -1971,37 +1506,14 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, INIT_WORK(&ev->work, mptsas_hotplug_work, ev); ev->ioc = ioc; ev->id = raid_event_data->VolumeID; - ev->event_type = MPTSAS_IGNORE_EVENT; switch (raid_event_data->ReasonCode) { case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: ev->event_type = MPTSAS_ADD_DEVICE; break; case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: - ioc->raid_data.isRaid = 1; - ev->phys_disk_num_valid = 1; - ev->phys_disk_num = raid_event_data->PhysDiskNum; ev->event_type = MPTSAS_DEL_DEVICE; break; - case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: - switch (state) { - case MPI_PD_STATE_ONLINE: - ioc->raid_data.isRaid = 1; - ev->phys_disk_num_valid = 1; - ev->phys_disk_num = raid_event_data->PhysDiskNum; - ev->event_type = MPTSAS_ADD_DEVICE; - break; - case MPI_PD_STATE_MISSING: - case MPI_PD_STATE_NOT_COMPATIBLE: - case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST: - case MPI_PD_STATE_FAILED_AT_HOST_REQUEST: - case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON: - ev->event_type = MPTSAS_DEL_DEVICE; - break; - default: - break; - } - break; case MPI_EVENT_RAID_RC_VOLUME_DELETED: ev->event_type = MPTSAS_DEL_RAID; break; @@ -2009,18 +1521,11 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, ev->event_type = MPTSAS_ADD_RAID; break; case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: - switch (state) { - case MPI_RAIDVOL0_STATUS_STATE_FAILED: - case MPI_RAIDVOL0_STATUS_STATE_MISSING: - ev->event_type = MPTSAS_DEL_RAID; - break; - case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL: - case MPI_RAIDVOL0_STATUS_STATE_DEGRADED: - ev->event_type = MPTSAS_ADD_RAID; - break; - default: - break; - } + volumeStatus = (RAID_VOL0_STATUS *) & + raid_event_data->SettingsStatus; + ev->event_type = (volumeStatus->State == + MPI_RAIDVOL0_STATUS_STATE_FAILED) ? + MPTSAS_DEL_RAID : MPTSAS_ADD_RAID; break; default: break; @@ -2028,31 +1533,15 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, schedule_work(&ev->work); } +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* work queue thread to clear the persitency table */ static void -mptscsih_send_discovery(MPT_ADAPTER *ioc, - EVENT_DATA_SAS_DISCOVERY *discovery_data) +mptscsih_sas_persist_clear_table(void * arg) { - struct mptsas_discovery_event *ev; - - /* - * DiscoveryStatus - * - * This flag will be non-zero when firmware - * kicks off discovery, and return to zero - * once its completed. - */ - if (discovery_data->DiscoveryStatus) - return; - - ev = kmalloc(sizeof(*ev), GFP_ATOMIC); - if (!ev) - return; - memset(ev,0,sizeof(struct mptsas_discovery_event)); - INIT_WORK(&ev->work, mptscsih_discovery_work, ev); - ev->ioc = ioc; - schedule_work(&ev->work); -}; + MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; + mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); +} static int mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) @@ -2063,17 +1552,6 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) if (!ioc->sh) goto out; - /* - * sas_discovery_ignore_events - * - * This flag is to prevent anymore processing of - * sas events once mptsas_remove function is called. - */ - if (ioc->sas_discovery_ignore_events) { - rc = mptscsih_event_process(ioc, reply); - goto out; - } - switch (event) { case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: mptscsih_send_sas_event(ioc, @@ -2089,10 +1567,6 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) (void *)ioc); schedule_work(&ioc->mptscsih_persistTask); break; - case MPI_EVENT_SAS_DISCOVERY: - mptscsih_send_discovery(ioc, - (EVENT_DATA_SAS_DISCOVERY *)reply->Data); - break; default: rc = mptscsih_event_process(ioc, reply); break; @@ -2194,7 +1668,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) INIT_LIST_HEAD(&ioc->sas_topology); mutex_init(&ioc->sas_topology_mutex); - mutex_init(&ioc->sas_discovery_mutex); + mutex_init(&ioc->sas_mgmt.mutex); init_completion(&ioc->sas_mgmt.done); @@ -2307,6 +1781,20 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) mptsas_scan_sas_topology(ioc); + /* + Reporting RAID volumes. + */ + if (!ioc->raid_data.pIocPg2) + return 0; + if (!ioc->raid_data.pIocPg2->NumActiveVolumes) + return 0; + for (ii=0;iiraid_data.pIocPg2->NumActiveVolumes;ii++) { + scsi_add_device(sh, + ioc->num_ports, + ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID, + 0); + } + return 0; out_mptsas_probe: @@ -2320,14 +1808,11 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) MPT_ADAPTER *ioc = pci_get_drvdata(pdev); struct mptsas_portinfo *p, *n; - ioc->sas_discovery_ignore_events=1; sas_remove_host(ioc->sh); mutex_lock(&ioc->sas_topology_mutex); list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { list_del(&p->list); - if (p->phy_info) - kfree(p->phy_info); kfree(p); } mutex_unlock(&ioc->sas_topology_mutex); @@ -2382,7 +1867,7 @@ mptsas_init(void) mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) { - devtverboseprintk((KERN_INFO MYNAM + devtprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n")); } diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 84fa271eb..4fee6befc 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -114,6 +114,21 @@ typedef struct _internal_cmd { u8 rsvd; } INTERNAL_CMD; +typedef struct _negoparms { + u8 width; + u8 offset; + u8 factor; + u8 flags; +} NEGOPARMS; + +typedef struct _dv_parameters { + NEGOPARMS max; + NEGOPARMS now; + u8 cmd; + u8 id; + u16 pad1; +} DVPARAMETERS; + /* * Other private/forward protos... */ @@ -134,12 +149,28 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 tar int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); -static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); -static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); +static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen); +static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56); +static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); +static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc); +static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); +static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice); +static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); + +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION +static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); +static void mptscsih_domainValidation(void *hd); +static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id); +static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); +static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); +static void mptscsih_fillbuf(char *buffer, int size, int index, int width); +static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id); +static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc); +#endif void mptscsih_remove(struct pci_dev *); void mptscsih_shutdown(struct pci_dev *); @@ -150,6 +181,16 @@ int mptscsih_resume(struct pci_dev *pdev); #define SNS_LEN(scp) sizeof((scp)->sense_buffer) +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION +/* + * Domain Validation task structure + */ +static DEFINE_SPINLOCK(dvtaskQ_lock); +static int dvtaskQ_active = 0; +static int dvtaskQ_release = 0; +static struct work_struct dvTaskQ_task; +#endif + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptscsih_add_sge - Place a simple SGE at address pAddr. @@ -632,11 +673,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ /* Spoof to SCSI Selection Timeout! */ - if (ioc->bus_type != FC) - sc->result = DID_NO_CONNECT << 16; - /* else fibre, just stall until rescan event */ - else - sc->result = DID_REQUEUE << 16; + sc->result = DID_NO_CONNECT << 16; if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) hd->sel_timeout[pScsiReq->TargetID]++; @@ -650,6 +687,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) */ sc->result = DID_RESET << 16; + /* GEM Workaround. */ + if (ioc->bus_type == SPI) + mptscsih_no_negotiate(hd, sc); break; case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ @@ -881,7 +921,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) struct scsi_cmnd *sc; dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", - vdevice->vtarget->target_id, vdevice->lun, max)); + vdevice->target_id, vdevice->lun, max)); for (ii=0; ii < max; ii++) { if ((sc = hd->ScsiLookup[ii]) != NULL) { @@ -891,7 +931,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); - if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) + if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) continue; /* Cleanup @@ -965,6 +1005,10 @@ mptscsih_remove(struct pci_dev *pdev) MPT_ADAPTER *ioc = pci_get_drvdata(pdev); struct Scsi_Host *host = ioc->sh; MPT_SCSI_HOST *hd; +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION + int count; + unsigned long flags; +#endif int sz1; if(!host) { @@ -977,6 +1021,25 @@ mptscsih_remove(struct pci_dev *pdev) if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL) return; +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION + /* Check DV thread active */ + count = 10 * HZ; + spin_lock_irqsave(&dvtaskQ_lock, flags); + if (dvtaskQ_active) { + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + while(dvtaskQ_active && --count) + schedule_timeout_interruptible(1); + } else { + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + } + if (!count) + printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n"); +#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) + else + printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count); +#endif +#endif + mptscsih_shutdown(pdev); sz1=0; @@ -1064,6 +1127,21 @@ mptscsih_resume(struct pci_dev *pdev) if(!hd) return 0; +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION + { + unsigned long lflags; + spin_lock_irqsave(&dvtaskQ_lock, lflags); + if (!dvtaskQ_active) { + dvtaskQ_active = 1; + spin_unlock_irqrestore(&dvtaskQ_lock, lflags); + INIT_WORK(&dvTaskQ_task, + mptscsih_domainValidation, (void *) hd); + schedule_work(&dvTaskQ_task); + } else { + spin_unlock_irqrestore(&dvtaskQ_lock, lflags); + } + } +#endif return 0; } @@ -1239,14 +1317,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) return SCSI_MLQUEUE_HOST_BUSY; } - if ((hd->ioc->bus_type == SPI) && - vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT && - mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) { - SCpnt->result = DID_NO_CONNECT << 16; - done(SCpnt); - return 0; - } - /* * Put together a MPT SCSI request... */ @@ -1290,13 +1360,10 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) /* Use the above information to set up the message frame */ - pScsiReq->TargetID = (u8) vdev->vtarget->target_id; - pScsiReq->Bus = vdev->vtarget->bus_id; + pScsiReq->TargetID = (u8) vdev->target_id; + pScsiReq->Bus = vdev->bus_id; pScsiReq->ChainOffset = 0; - if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) - pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; - else - pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; + pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; pScsiReq->CDBLength = SCpnt->cmd_len; pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; pScsiReq->Reserved = 0; @@ -1344,6 +1411,49 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) hd->ScsiLookup[my_idx] = SCpnt; SCpnt->host_scribble = NULL; +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION + if (hd->ioc->bus_type == SPI) { + int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id]; + int issueCmd = 1; + + if (dvStatus || hd->ioc->spi_data.forceDv) { + + if ((dvStatus & MPT_SCSICFG_NEED_DV) || + (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) { + unsigned long lflags; + /* Schedule DV if necessary */ + spin_lock_irqsave(&dvtaskQ_lock, lflags); + if (!dvtaskQ_active) { + dvtaskQ_active = 1; + spin_unlock_irqrestore(&dvtaskQ_lock, lflags); + INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd); + + schedule_work(&dvTaskQ_task); + } else { + spin_unlock_irqrestore(&dvtaskQ_lock, lflags); + } + hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV; + } + + /* Trying to do DV to this target, extend timeout. + * Wait to issue until flag is clear + */ + if (dvStatus & MPT_SCSICFG_DV_PENDING) { + mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ); + issueCmd = 0; + } + + /* Set the DV flags. + */ + if (dvStatus & MPT_SCSICFG_DV_NOT_DONE) + mptscsih_set_dvflags(hd, SCpnt); + + if (!issueCmd) + goto fail; + } + } +#endif + mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", hd->ioc->name, SCpnt, mf, my_idx)); @@ -1649,6 +1759,7 @@ int mptscsih_abort(struct scsi_cmnd * SCpnt) { MPT_SCSI_HOST *hd; + MPT_ADAPTER *ioc; MPT_FRAME_HDR *mf; u32 ctx2abort; int scpnt_idx; @@ -1666,6 +1777,14 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) return FAILED; } + ioc = hd->ioc; + if (hd->resetPending) { + return FAILED; + } + + if (hd->timeouts < -1) + hd->timeouts++; + /* Find this command */ if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { @@ -1679,13 +1798,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) return SUCCESS; } - if (hd->resetPending) { - return FAILED; - } - - if (hd->timeouts < -1) - hd->timeouts++; - printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n", hd->ioc->name, SCpnt); scsi_print_command(SCpnt); @@ -1704,8 +1816,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) vdev = SCpnt->device->hostdata; retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, - vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, - ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); + vdev->bus_id, vdev->target_id, vdev->lun, + ctx2abort, mptscsih_get_tm_timeout(ioc)); printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", hd->ioc->name, @@ -1755,7 +1867,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) vdev = SCpnt->device->hostdata; retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, - vdev->vtarget->bus_id, vdev->vtarget->target_id, + vdev->bus_id, vdev->target_id, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", @@ -1806,7 +1918,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) vdev = SCpnt->device->hostdata; retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, - vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); + vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", hd->ioc->name, @@ -2106,42 +2218,6 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, return 0; } -/* Search IOC page 3 to determine if this is hidden physical disk - * - */ -int -mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) -{ - int i; - - if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) - return 0; - for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { - if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) - return 1; - } - return 0; -} -EXPORT_SYMBOL(mptscsih_is_phys_disk); - -int -mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid) -{ - int i; - - if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3) - return -ENXIO; - - for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) { - if (physdiskid == - hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) - return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum; - } - - return -ENXIO; -} -EXPORT_SYMBOL(mptscsih_raid_id_to_num); - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * OS entry point to allow host driver to alloc memory @@ -2157,7 +2233,6 @@ mptscsih_target_alloc(struct scsi_target *starget) if (!vtarget) return -ENOMEM; starget->hostdata = vtarget; - vtarget->starget = starget; return 0; } @@ -2183,12 +2258,14 @@ mptscsih_slave_alloc(struct scsi_device *sdev) return -ENOMEM; } + vdev->ioc_id = hd->ioc->id; + vdev->target_id = sdev->id; + vdev->bus_id = sdev->channel; vdev->lun = sdev->lun; sdev->hostdata = vdev; starget = scsi_target(sdev); vtarget = starget->hostdata; - vdev->vtarget = vtarget; if (vtarget->num_luns == 0) { @@ -2197,11 +2274,14 @@ mptscsih_slave_alloc(struct scsi_device *sdev) vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; vtarget->target_id = sdev->id; vtarget->bus_id = sdev->channel; - if (hd->ioc->bus_type == SPI && sdev->channel == 0 && - hd->ioc->raid_data.isRaid & (1 << sdev->id)) { - vtarget->raidVolume = 1; - ddvtprintk((KERN_INFO + if (hd->ioc->bus_type == SPI) { + if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) { + vtarget->raidVolume = 1; + ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", sdev->id)); + } + } else { + vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; } } vtarget->num_luns++; @@ -2241,6 +2321,19 @@ mptscsih_slave_destroy(struct scsi_device *sdev) vtarget->luns[0] &= ~(1 << vdevice->lun); vtarget->num_luns--; if (vtarget->num_luns == 0) { + mptscsih_negotiate_to_asyn_narrow(hd, vdevice); + if (hd->ioc->bus_type == SPI) { + if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) { + hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; + } else { + hd->ioc->spi_data.dvStatus[vtarget->target_id] = + MPT_SCSICFG_NEGOTIATE; + if (!hd->negoNvram) { + hd->ioc->spi_data.dvStatus[vtarget->target_id] |= + MPT_SCSICFG_DV_NOT_DONE; + } + } + } hd->Targets[sdev->id] = NULL; } mptscsih_synchronize_cache(hd, vdevice); @@ -2269,13 +2362,18 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) vtarget = starget->hostdata; if (hd->ioc->bus_type == SPI) { - if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) + if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { + if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) + max_depth = 1; + else if (((vtarget->inq_data[0] & 0x1f) == 0x00) && + (vtarget->minSyncFactor <= MPT_ULTRA160 )) + max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; + else + max_depth = MPT_SCSI_CMD_PER_DEV_LOW; + } else { + /* error case - No Inq. Data */ max_depth = 1; - else if (sdev->type == TYPE_DISK && - vtarget->minSyncFactor <= MPT_ULTRA160) - max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; - else - max_depth = MPT_SCSI_CMD_PER_DEV_LOW; + } } else max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; @@ -2329,7 +2427,8 @@ mptscsih_slave_configure(struct scsi_device *sdev) lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */ indexed_lun = (vdevice->lun % 32); vtarget->luns[lun_index] |= (1 << indexed_lun); - mptscsih_initTarget(hd, vtarget, sdev); + mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry, + sdev->inquiry_len ); mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); dsprintk((MYIOC_s_INFO_FMT @@ -2498,6 +2597,10 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) /* 4. Renegotiate to all devices, if SPI */ + if (ioc->bus_type == SPI) { + dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n")); + mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM); + } /* 5. Enable new commands to be posted */ @@ -2521,17 +2624,24 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) hd->cmdPtr = NULL; } + /* 7. SPI: Set flag to force DV and re-read IOC Page 3 + */ + if (ioc->bus_type == SPI) { + ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; + ddvtprintk(("Set reload IOC Pg3 Flag\n")); + } + /* 7. FC: Rescan for blocked rports which might have returned. */ - if (ioc->bus_type == FC) { + else if (ioc->bus_type == FC) { + int work_count; + unsigned long flags; + spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - if (ioc->fc_rescan_work_q) { - if (ioc->fc_rescan_work_count++ == 0) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_rescan_work); - } - } + work_count = ++ioc->fc_rescan_work_count; spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); + if (work_count == 1) + schedule_work(&ioc->fc_rescan_work); } dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); @@ -2546,9 +2656,10 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) { MPT_SCSI_HOST *hd; u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; + int work_count; unsigned long flags; - devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", + devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", ioc->name, event)); if (ioc->sh == NULL || @@ -2570,13 +2681,10 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) case MPI_EVENT_RESCAN: /* 06 */ spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - if (ioc->fc_rescan_work_q) { - if (ioc->fc_rescan_work_count++ == 0) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_rescan_work); - } - } + work_count = ++ioc->fc_rescan_work_count; spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); + if (work_count == 1) + schedule_work(&ioc->fc_rescan_work); break; /* @@ -2591,7 +2699,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) break; case MPI_EVENT_INTEGRATED_RAID: /* 0B */ + { +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION + pMpiEventDataRaid_t pRaidEventData = + (pMpiEventDataRaid_t) pEvReply->Data; + /* Domain Validation Needed */ + if (ioc->bus_type == SPI && + pRaidEventData->ReasonCode == + MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) + mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum); +#endif break; + } case MPI_EVENT_NONE: /* 00 */ case MPI_EVENT_LOG_DATA: /* 01 */ @@ -2610,7 +2729,9 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) * mptscsih_initTarget - Target, LUN alloc/free functionality. * @hd: Pointer to MPT_SCSI_HOST structure * @vtarget: per target private data - * @sdev: SCSI device + * @lun: SCSI LUN id + * @data: Pointer to data + * @dlen: Number of INQUIRY bytes * * NOTE: It's only SAFE to call this routine if data points to * sane & valid STANDARD INQUIRY data! @@ -2620,46 +2741,98 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) * */ static void -mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, - struct scsi_device *sdev) +mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen) { + SpiCfgData *pSpi; + char data_56; + int inq_len; + dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd)); + /* + * If the peripheral qualifier filter is enabled then if the target reports a 0x1 + * (i.e. The targer is capable of supporting the specified peripheral device type + * on this logical unit; however, the physical device is not currently connected + * to this logical unit) it will be converted to a 0x3 (i.e. The target is not + * capable of supporting a physical device on this logical unit). This is to work + * around a bug in th emid-layer in some distributions in which the mid-layer will + * continue to try to communicate to the LUN and evntually create a dummy LUN. + */ + if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0)) + data[0] |= 0x40; + /* Is LUN supported? If so, upper 2 bits will be 0 * in first byte of inquiry data. */ - if (sdev->inq_periph_qual != 0) + if (data[0] & 0xe0) return; if (vtarget == NULL) return; - vtarget->type = sdev->type; + if (data) + vtarget->type = data[0]; if (hd->ioc->bus_type != SPI) return; - if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { + if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { /* Treat all Processors as SAF-TE if * command line option is set */ vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); - }else if ((sdev->type == TYPE_PROCESSOR) && + }else if ((data[0] == TYPE_PROCESSOR) && !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { - if (sdev->inquiry_len > 49 ) { - if (sdev->inquiry[44] == 'S' && - sdev->inquiry[45] == 'A' && - sdev->inquiry[46] == 'F' && - sdev->inquiry[47] == '-' && - sdev->inquiry[48] == 'T' && - sdev->inquiry[49] == 'E' ) { + if ( dlen > 49 ) { + vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; + if ( data[44] == 'S' && + data[45] == 'A' && + data[46] == 'F' && + data[47] == '-' && + data[48] == 'T' && + data[49] == 'E' ) { vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); } } } - mptscsih_setTargetNegoParms(hd, vtarget, sdev); + if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { + inq_len = dlen < 8 ? dlen : 8; + memcpy (vtarget->inq_data, data, inq_len); + /* If have not done DV, set the DV flag. + */ + pSpi = &hd->ioc->spi_data; + if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) { + if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE) + pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV; + } + vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; + + data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */ + if (dlen > 56) { + if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) { + /* Update the target capabilities + */ + data_56 = data[56]; + vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56; + } + } + mptscsih_setTargetNegoParms(hd, vtarget, data_56); + } else { + /* Initial Inquiry may not request enough data bytes to + * obtain byte 57. DV will; if target doesn't return + * at least 57 bytes, data[56] will be zero. */ + if (dlen > 56) { + if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) { + /* Update the target capabilities + */ + data_56 = data[56]; + vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56; + mptscsih_setTargetNegoParms(hd, vtarget, data_56); + } + } + } } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -2669,51 +2842,66 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, * */ static void -mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, - struct scsi_device *sdev) +mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56) { SpiCfgData *pspi_data = &hd->ioc->spi_data; int id = (int) target->target_id; int nvram; + VirtTarget *vtarget; + int ii; u8 width = MPT_NARROW; u8 factor = MPT_ASYNC; u8 offset = 0; - u8 nfactor; + u8 version, nfactor; u8 noQas = 1; target->negoFlags = pspi_data->noQas; - /* noQas == 0 => device supports QAS. */ + /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine + * support. If available, default QAS to off and allow enabling. + * If not available, default QAS to on, turn off for non-disks. + */ - if (sdev->scsi_level < SCSI_2) { + /* Set flags based on Inquiry data + */ + version = target->inq_data[2] & 0x07; + if (version < 2) { width = 0; factor = MPT_ULTRA2; offset = pspi_data->maxSyncOffset; target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; } else { - if (scsi_device_wide(sdev)) { + if (target->inq_data[7] & 0x20) { width = 1; } - if (scsi_device_sync(sdev)) { + if (target->inq_data[7] & 0x10) { factor = pspi_data->minSyncFactor; - if (!scsi_device_dt(sdev)) + if (target->tflags & MPT_TARGET_FLAGS_VALID_56) { + /* bits 2 & 3 show Clocking support */ + if ((byte56 & 0x0C) == 0) factor = MPT_ULTRA2; - else { - if (!scsi_device_ius(sdev) && - !scsi_device_qas(sdev)) - factor = MPT_ULTRA160; else { - factor = MPT_ULTRA320; - if (scsi_device_qas(sdev)) { - ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id)); - noQas = 0; + if ((byte56 & 0x03) == 0) + factor = MPT_ULTRA160; + else { + factor = MPT_ULTRA320; + if (byte56 & 0x02) + { + ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id)); + noQas = 0; + } + if (target->inq_data[0] == TYPE_TAPE) { + if (byte56 & 0x01) + target->negoFlags |= MPT_TAPE_NEGO_IDP; + } } - if (sdev->type == TYPE_TAPE && - scsi_device_ius(sdev)) - target->negoFlags |= MPT_TAPE_NEGO_IDP; } + } else { + ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id)); + noQas = 0; } + offset = pspi_data->maxSyncOffset; /* If RAID, never disable QAS @@ -2731,7 +2919,7 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, } } - if (!sdev->tagged_supported) { + if ( (target->inq_data[7] & 0x02) == 0) { target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; } @@ -2789,23 +2977,305 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, if ( factor > MPT_ULTRA320 ) noQas = 0; - if (noQas && (pspi_data->noQas == 0)) { - pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; - target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; - - /* Disable QAS in a mixed configuration case - */ + /* GEM, processor WORKAROUND + */ + if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) { + target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC); + pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO; + } else { + if (noQas && (pspi_data->noQas == 0)) { + pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; + target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + + /* Disable QAS in a mixed configuration case + */ + + ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); + for (ii = 0; ii < id; ii++) { + if ( (vtarget = hd->Targets[ii]) ) { + vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags); + } + } + } + } - ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); + /* Write SDP1 on this I/O to this target */ + if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) { + ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id)); + mptscsih_writeSDP1(hd, 0, id, hd->negoNvram); + pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE; + } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) { + ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id)); + mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO); + pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO; } } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* + * If no Target, bus reset on 1st I/O. Set the flag to + * prevent any future negotiations to this device. + */ +static void +mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc) +{ + VirtDevice *vdev; + + if ((vdev = sc->device->hostdata) != NULL) + hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO; + return; +} /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * SCSI Config Page functionality ... */ +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags + * based on width, factor and offset parameters. + * @width: bus width + * @factor: sync factor + * @offset: sync offset + * @requestedPtr: pointer to requested values (updated) + * @configurationPtr: pointer to configuration values (updated) + * @flags: flags to block WDTR or SDTR negotiation + * + * Return: None. + * + * Remark: Called by writeSDP1 and _dv_params + */ +static void +mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags) +{ + u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE; + u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC; + + *configurationPtr = 0; + *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0; + *requestedPtr |= (offset << 16) | (factor << 8); + + if (width && offset && !nowide && !nosync) { + if (factor < MPT_ULTRA160) { + *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT); + if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0) + *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS; + if (flags & MPT_TAPE_NEGO_IDP) + *requestedPtr |= 0x08000000; + } else if (factor < MPT_ULTRA2) { + *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT; + } + } + + if (nowide) + *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED; + + if (nosync) + *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED; + + return; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* mptscsih_writeSDP1 - write SCSI Device Page 1 + * @hd: Pointer to a SCSI Host Strucutre + * @portnum: IOC port number + * @target_id: writeSDP1 for single ID + * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO + * + * Return: -EFAULT if read of config page header fails + * or 0 if success. + * + * Remark: If a target has been found, the settings from the + * target structure are used, else the device is set + * to async/narrow. + * + * Remark: Called during init and after a FW reload. + * Remark: We do not wait for a return, write pages sequentially. + */ +static int +mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) +{ + MPT_ADAPTER *ioc = hd->ioc; + Config_t *pReq; + SCSIDevicePage1_t *pData; + VirtTarget *vtarget=NULL; + MPT_FRAME_HDR *mf; + dma_addr_t dataDma; + u16 req_idx; + u32 frameOffset; + u32 requested, configuration, flagsLength; + int ii, nvram; + int id = 0, maxid = 0; + u8 width; + u8 factor; + u8 offset; + u8 bus = 0; + u8 negoFlags; + u8 maxwidth, maxoffset, maxfactor; + + if (ioc->spi_data.sdp1length == 0) + return 0; + + if (flags & MPT_SCSICFG_ALL_IDS) { + id = 0; + maxid = ioc->sh->max_id - 1; + } else if (ioc->sh) { + id = target_id; + maxid = min_t(int, id, ioc->sh->max_id - 1); + } + + for (; id <= maxid; id++) { + + if (id == ioc->pfacts[portnum].PortSCSIID) + continue; + + /* Use NVRAM to get adapter and target maximums + * Data over-riden by target structure information, if present + */ + maxwidth = ioc->spi_data.maxBusWidth; + maxoffset = ioc->spi_data.maxSyncOffset; + maxfactor = ioc->spi_data.minSyncFactor; + if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { + nvram = ioc->spi_data.nvram[id]; + + if (maxwidth) + maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; + + if (maxoffset > 0) { + maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; + if (maxfactor == 0) { + /* Key for async */ + maxfactor = MPT_ASYNC; + maxoffset = 0; + } else if (maxfactor < ioc->spi_data.minSyncFactor) { + maxfactor = ioc->spi_data.minSyncFactor; + } + } else + maxfactor = MPT_ASYNC; + } + + /* Set the negotiation flags. + */ + negoFlags = ioc->spi_data.noQas; + if (!maxwidth) + negoFlags |= MPT_TARGET_NO_NEGO_WIDE; + + if (!maxoffset) + negoFlags |= MPT_TARGET_NO_NEGO_SYNC; + + if (flags & MPT_SCSICFG_USE_NVRAM) { + width = maxwidth; + factor = maxfactor; + offset = maxoffset; + } else { + width = 0; + factor = MPT_ASYNC; + offset = 0; + //negoFlags = 0; + //negoFlags = MPT_TARGET_NO_NEGO_SYNC; + } + + /* If id is not a raid volume, get the updated + * transmission settings from the target structure. + */ + if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) { + width = vtarget->maxWidth; + factor = vtarget->minSyncFactor; + offset = vtarget->maxOffset; + negoFlags = vtarget->negoFlags; + } + +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION + /* Force to async and narrow if DV has not been executed + * for this ID + */ + if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) { + width = 0; + factor = MPT_ASYNC; + offset = 0; + } +#endif + + if (flags & MPT_SCSICFG_BLK_NEGO) + negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC; + + mptscsih_setDevicePage1Flags(width, factor, offset, + &requested, &configuration, negoFlags); + dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", + target_id, width, factor, offset, negoFlags, requested, configuration)); + + /* Get a MF for this command. + */ + if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { + dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n", + ioc->name)); + return -EAGAIN; + } + + ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n", + hd->ioc->name, mf, id, requested, configuration)); + + + /* Set the request and the data pointers. + * Request takes: 36 bytes (32 bit SGE) + * SCSI Device Page 1 requires 16 bytes + * 40 + 16 <= size of SCSI IO Request = 56 bytes + * and MF size >= 64 bytes. + * Place data at end of MF. + */ + pReq = (Config_t *)mf; + + req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); + frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t); + + pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset); + dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset; + + /* Complete the request frame (same for all requests). + */ + pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + pReq->Reserved = 0; + pReq->ChainOffset = 0; + pReq->Function = MPI_FUNCTION_CONFIG; + pReq->ExtPageLength = 0; + pReq->ExtPageType = 0; + pReq->MsgFlags = 0; + for (ii=0; ii < 8; ii++) { + pReq->Reserved2[ii] = 0; + } + pReq->Header.PageVersion = ioc->spi_data.sdp1version; + pReq->Header.PageLength = ioc->spi_data.sdp1length; + pReq->Header.PageNumber = 1; + pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; + pReq->PageAddress = cpu_to_le32(id | (bus << 8 )); + + /* Add a SGE to the config request. + */ + flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4; + + mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); + + /* Set up the common data portion + */ + pData->Header.PageVersion = pReq->Header.PageVersion; + pData->Header.PageLength = pReq->Header.PageLength; + pData->Header.PageNumber = pReq->Header.PageNumber; + pData->Header.PageType = pReq->Header.PageType; + pData->RequestedParameters = cpu_to_le32(requested); + pData->Reserved = 0; + pData->Configuration = cpu_to_le32(configuration); + + dprintk((MYIOC_s_INFO_FMT + "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n", + ioc->name, id, (id | (bus<<8)), + requested, configuration)); + + mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); + } + + return 0; +} /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* mptscsih_writeIOCPage4 - write IOC Page 4 @@ -2995,7 +3465,6 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) completionCode = MPT_SCANDV_GOOD; else completionCode = MPT_SCANDV_SOME_ERROR; - memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense)); } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) { u8 *sense_data; @@ -3109,6 +3578,78 @@ mptscsih_timer_expired(unsigned long data) return; } +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* mptscsih_do_raid - Format and Issue a RAID volume request message. + * @hd: Pointer to scsi host structure + * @action: What do be done. + * @id: Logical target id. + * @bus: Target locations bus. + * + * Returns: < 0 on a fatal error + * 0 on success + * + * Remark: Wait to return until reply processed by the ISR. + */ +static int +mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io) +{ + MpiRaidActionRequest_t *pReq; + MPT_FRAME_HDR *mf; + int in_isr; + + in_isr = in_interrupt(); + if (in_isr) { + dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n", + hd->ioc->name)); + return -EPERM; + } + + /* Get and Populate a free Frame + */ + if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) { + ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n", + hd->ioc->name)); + return -EAGAIN; + } + pReq = (MpiRaidActionRequest_t *)mf; + pReq->Action = action; + pReq->Reserved1 = 0; + pReq->ChainOffset = 0; + pReq->Function = MPI_FUNCTION_RAID_ACTION; + pReq->VolumeID = io->id; + pReq->VolumeBus = io->bus; + pReq->PhysDiskNum = io->physDiskNum; + pReq->MsgFlags = 0; + pReq->Reserved2 = 0; + pReq->ActionDataWord = 0; /* Reserved for this action */ + //pReq->ActionDataSGE = 0; + + mpt_add_sge((char *)&pReq->ActionDataSGE, + MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); + + ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n", + hd->ioc->name, action, io->id)); + + hd->pLocal = NULL; + hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ + hd->scandv_wait_done = 0; + + /* Save cmd pointer, for resource free if timeout or + * FW reload occurs + */ + hd->cmdPtr = mf; + + add_timer(&hd->timer); + mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf); + wait_event(hd->scandv_waitq, hd->scandv_wait_done); + + if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD)) + return -1; + + return 0; +} +#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** @@ -3362,17 +3903,104 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. + * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state * @hd: Pointer to a SCSI HOST structure * @vtarget: per device private data - * @lun: lun * * Uses the ISR, but with special processing. * MUST be single-threaded. * */ static void -mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) +mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice) +{ + VirtTarget *vtarget = vdevice->vtarget; + MPT_ADAPTER *ioc= hd->ioc; + SCSIDevicePage1_t *pcfg1Data; + CONFIGPARMS cfg; + dma_addr_t cfg1_dma_addr; + ConfigPageHeader_t header; + int id; + int requested, configuration, data,i; + u8 flags, factor; + + if ((ioc->bus_type != SPI) || + (!vdevice->configured_lun)) + return; + + if (!ioc->spi_data.sdp1length) + return; + + pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev, + ioc->spi_data.sdp1length * 4, &cfg1_dma_addr); + + if (pcfg1Data == NULL) + return; + + header.PageVersion = ioc->spi_data.sdp1version; + header.PageLength = ioc->spi_data.sdp1length; + header.PageNumber = 1; + header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; + cfg.cfghdr.hdr = &header; + cfg.physAddr = cfg1_dma_addr; + cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + cfg.dir = 1; + cfg.timeout = 0; + + if (vtarget->raidVolume && ioc->raid_data.pIocPg3) { + for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { + id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID; + flags = hd->ioc->spi_data.noQas; + if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { + data = hd->ioc->spi_data.nvram[id]; + if (data & MPT_NVRAM_WIDE_DISABLE) + flags |= MPT_TARGET_NO_NEGO_WIDE; + factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; + if ((factor == 0) || (factor == MPT_ASYNC)) + flags |= MPT_TARGET_NO_NEGO_SYNC; + } + mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, + &configuration, flags); + dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC " + "offset=0 negoFlags=%x request=%x config=%x\n", + id, flags, requested, configuration)); + pcfg1Data->RequestedParameters = cpu_to_le32(requested); + pcfg1Data->Reserved = 0; + pcfg1Data->Configuration = cpu_to_le32(configuration); + cfg.pageAddr = (vtarget->bus_id<<8) | id; + mpt_config(hd->ioc, &cfg); + } + } else { + flags = vtarget->negoFlags; + mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, + &configuration, flags); + dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC " + "offset=0 negoFlags=%x request=%x config=%x\n", + vtarget->target_id, flags, requested, configuration)); + pcfg1Data->RequestedParameters = cpu_to_le32(requested); + pcfg1Data->Reserved = 0; + pcfg1Data->Configuration = cpu_to_le32(configuration); + cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id; + mpt_config(hd->ioc, &cfg); + } + + if (pcfg1Data) + pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr); +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** + * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. + * @hd: Pointer to a SCSI HOST structure + * @vtarget: per device private data + * @lun: lun + * + * Uses the ISR, but with special processing. + * MUST be single-threaded. + * + */ +static void +mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) { INTERNAL_CMD iocmd; @@ -3386,15 +4014,1637 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) iocmd.data_dma = -1; iocmd.size = 0; iocmd.rsvd = iocmd.rsvd2 = 0; - iocmd.bus = vdevice->vtarget->bus_id; - iocmd.id = vdevice->vtarget->target_id; + iocmd.bus = vdevice->bus_id; + iocmd.id = vdevice->target_id; iocmd.lun = (u8)vdevice->lun; - if ((vdevice->vtarget->type == TYPE_DISK) && + if ((vdevice->vtarget->type & TYPE_DISK) && (vdevice->configured_lun)) mptscsih_do_cmd(hd, &iocmd); } +/* Search IOC page 3 to determine if this is hidden physical disk + */ +static int +mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) +{ + int i; + + if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) + return 0; + + for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { + if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) + return 1; + } + + return 0; +} + +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** + * mptscsih_domainValidation - Top level handler for domain validation. + * @hd: Pointer to MPT_SCSI_HOST structure. + * + * Uses the ISR, but with special processing. + * Called from schedule, should not be in interrupt mode. + * While thread alive, do dv for all devices needing dv + * + * Return: None. + */ +static void +mptscsih_domainValidation(void *arg) +{ + MPT_SCSI_HOST *hd; + MPT_ADAPTER *ioc; + unsigned long flags; + int id, maxid, dvStatus, did; + int ii, isPhysDisk; + + spin_lock_irqsave(&dvtaskQ_lock, flags); + dvtaskQ_active = 1; + if (dvtaskQ_release) { + dvtaskQ_active = 0; + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + return; + } + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + + /* For this ioc, loop through all devices and do dv to each device. + * When complete with this ioc, search through the ioc list, and + * for each scsi ioc found, do dv for all devices. Exit when no + * device needs dv. + */ + did = 1; + while (did) { + did = 0; + list_for_each_entry(ioc, &ioc_list, list) { + spin_lock_irqsave(&dvtaskQ_lock, flags); + if (dvtaskQ_release) { + dvtaskQ_active = 0; + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + return; + } + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + + msleep(250); + + /* DV only to SPI adapters */ + if (ioc->bus_type != SPI) + continue; + + /* Make sure everything looks ok */ + if (ioc->sh == NULL) + continue; + + hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; + if (hd == NULL) + continue; + + if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) { + mpt_read_ioc_pg_3(ioc); + if (ioc->raid_data.pIocPg3) { + Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; + int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; + + while (numPDisk) { + if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE) + ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; + + pPDisk++; + numPDisk--; + } + } + ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3; + } + + maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES); + + for (id = 0; id < maxid; id++) { + spin_lock_irqsave(&dvtaskQ_lock, flags); + if (dvtaskQ_release) { + dvtaskQ_active = 0; + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + return; + } + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + dvStatus = hd->ioc->spi_data.dvStatus[id]; + + if (dvStatus & MPT_SCSICFG_NEED_DV) { + did++; + hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING; + hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV; + + msleep(250); + + /* If hidden phys disk, block IO's to all + * raid volumes + * else, process normally + */ + isPhysDisk = mptscsih_is_phys_disk(ioc, id); + if (isPhysDisk) { + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { + if (hd->ioc->raid_data.isRaid & (1 << ii)) { + hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING; + } + } + } + + if(mpt_alt_ioc_wait(hd->ioc)!=0) { + ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n", + hd->ioc->name)); + continue; + } + + if (mptscsih_doDv(hd, 0, id) == 1) { + /* Untagged device was busy, try again + */ + hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV; + hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING; + } else { + /* DV is complete. Clear flags. + */ + hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING); + } + + spin_lock(&hd->ioc->initializing_hba_lock); + hd->ioc->initializing_hba_lock_flag=0; + spin_unlock(&hd->ioc->initializing_hba_lock); + + if (isPhysDisk) { + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { + if (hd->ioc->raid_data.isRaid & (1 << ii)) { + hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING; + } + } + } + + if (hd->ioc->spi_data.noQas) + mptscsih_qas_check(hd, id); + } + } + } + } + + spin_lock_irqsave(&dvtaskQ_lock, flags); + dvtaskQ_active = 0; + spin_unlock_irqrestore(&dvtaskQ_lock, flags); + + return; +} + +/* Write SDP1 if no QAS has been enabled + */ +static void +mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) +{ + VirtTarget *vtarget; + int ii; + + if (hd->Targets == NULL) + return; + + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { + if (ii == id) + continue; + + if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0) + continue; + + vtarget = hd->Targets[ii]; + + if ((vtarget != NULL) && (!vtarget->raidVolume)) { + if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) { + vtarget->negoFlags |= hd->ioc->spi_data.noQas; + dnegoprintk(("writeSDP1: id=%d flags=0\n", id)); + mptscsih_writeSDP1(hd, 0, ii, 0); + } + } else { + if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) { + dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id)); + mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM); + } + } + } + return; +} + + + +#define MPT_GET_NVRAM_VALS 0x01 +#define MPT_UPDATE_MAX 0x02 +#define MPT_SET_MAX 0x04 +#define MPT_SET_MIN 0x08 +#define MPT_FALLBACK 0x10 +#define MPT_SAVE 0x20 + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** + * mptscsih_doDv - Perform domain validation to a target. + * @hd: Pointer to MPT_SCSI_HOST structure. + * @portnum: IOC port number. + * @target: Physical ID of this target + * + * Uses the ISR, but with special processing. + * MUST be single-threaded. + * Test will exit if target is at async & narrow. + * + * Return: None. + */ +static int +mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) +{ + MPT_ADAPTER *ioc = hd->ioc; + VirtTarget *vtarget; + SCSIDevicePage1_t *pcfg1Data; + SCSIDevicePage0_t *pcfg0Data; + u8 *pbuf1; + u8 *pbuf2; + u8 *pDvBuf; + dma_addr_t dvbuf_dma = -1; + dma_addr_t buf1_dma = -1; + dma_addr_t buf2_dma = -1; + dma_addr_t cfg1_dma_addr = -1; + dma_addr_t cfg0_dma_addr = -1; + ConfigPageHeader_t header1; + ConfigPageHeader_t header0; + DVPARAMETERS dv; + INTERNAL_CMD iocmd; + CONFIGPARMS cfg; + int dv_alloc = 0; + int rc, sz = 0; + int bufsize = 0; + int dataBufSize = 0; + int echoBufSize = 0; + int notDone; + int patt; + int repeat; + int retcode = 0; + int nfactor = MPT_ULTRA320; + char firstPass = 1; + char doFallback = 0; + char readPage0; + char bus, lun; + char inq0 = 0; + + if (ioc->spi_data.sdp1length == 0) + return 0; + + if (ioc->spi_data.sdp0length == 0) + return 0; + + /* If multiple buses are used, require that the initiator + * id be the same on all buses. + */ + if (id == ioc->pfacts[0].PortSCSIID) + return 0; + + lun = 0; + bus = (u8) bus_number; + ddvtprintk((MYIOC_s_NOTE_FMT + "DV started: bus=%d, id=%d dv @ %p\n", + ioc->name, bus, id, &dv)); + + /* Prep DV structure + */ + memset (&dv, 0, sizeof(DVPARAMETERS)); + dv.id = id; + + /* Populate tmax with the current maximum + * transfer parameters for this target. + * Exit if narrow and async. + */ + dv.cmd = MPT_GET_NVRAM_VALS; + mptscsih_dv_parms(hd, &dv, NULL); + + /* Prep SCSI IO structure + */ + iocmd.id = id; + iocmd.bus = bus; + iocmd.lun = lun; + iocmd.flags = 0; + iocmd.physDiskNum = -1; + iocmd.rsvd = iocmd.rsvd2 = 0; + + vtarget = hd->Targets[id]; + + /* Use tagged commands if possible. + */ + if (vtarget) { + if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) + iocmd.flags |= MPT_ICFLAG_TAGGED_CMD; + else { + if (hd->ioc->facts.FWVersion.Word < 0x01000600) + return 0; + + if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) && + (hd->ioc->facts.FWVersion.Word < 0x01010B00)) + return 0; + } + } + + /* Prep cfg structure + */ + cfg.pageAddr = (bus<<8) | id; + cfg.cfghdr.hdr = NULL; + + /* Prep SDP0 header + */ + header0.PageVersion = ioc->spi_data.sdp0version; + header0.PageLength = ioc->spi_data.sdp0length; + header0.PageNumber = 0; + header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; + + /* Prep SDP1 header + */ + header1.PageVersion = ioc->spi_data.sdp1version; + header1.PageLength = ioc->spi_data.sdp1length; + header1.PageNumber = 1; + header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; + + if (header0.PageLength & 1) + dv_alloc = (header0.PageLength * 4) + 4; + + dv_alloc += (2048 + (header1.PageLength * 4)); + + pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma); + if (pDvBuf == NULL) + return 0; + + sz = 0; + pbuf1 = (u8 *)pDvBuf; + buf1_dma = dvbuf_dma; + sz +=1024; + + pbuf2 = (u8 *) (pDvBuf + sz); + buf2_dma = dvbuf_dma + sz; + sz +=1024; + + pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz); + cfg0_dma_addr = dvbuf_dma + sz; + sz += header0.PageLength * 4; + + /* 8-byte alignment + */ + if (header0.PageLength & 1) + sz += 4; + + pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz); + cfg1_dma_addr = dvbuf_dma + sz; + + /* Skip this ID? Set cfg.cfghdr.hdr to force config page write + */ + { + SpiCfgData *pspi_data = &hd->ioc->spi_data; + if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { + /* Set the factor from nvram */ + nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8; + if (nfactor < pspi_data->minSyncFactor ) + nfactor = pspi_data->minSyncFactor; + + if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) || + (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) { + + ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n", + ioc->name, bus, id, lun)); + + dv.cmd = MPT_SET_MAX; + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + cfg.cfghdr.hdr = &header1; + + /* Save the final negotiated settings to + * SCSI device page 1. + */ + cfg.physAddr = cfg1_dma_addr; + cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + cfg.dir = 1; + mpt_config(hd->ioc, &cfg); + goto target_done; + } + } + } + + /* Finish iocmd inititialization - hidden or visible disk? */ + if (ioc->raid_data.pIocPg3) { + /* Search IOC page 3 for matching id + */ + Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; + int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; + + while (numPDisk) { + if (pPDisk->PhysDiskID == id) { + /* match */ + iocmd.flags |= MPT_ICFLAG_PHYS_DISK; + iocmd.physDiskNum = pPDisk->PhysDiskNum; + + /* Quiesce the IM + */ + if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) { + ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name)); + goto target_done; + } + break; + } + pPDisk++; + numPDisk--; + } + } + + /* RAID Volume ID's may double for a physical device. If RAID but + * not a physical ID as well, skip DV. + */ + if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK)) + goto target_done; + + + /* Basic Test. + * Async & Narrow - Inquiry + * Async & Narrow - Inquiry + * Maximum transfer rate - Inquiry + * Compare buffers: + * If compare, test complete. + * If miscompare and first pass, repeat + * If miscompare and not first pass, fall back and repeat + */ + hd->pLocal = NULL; + readPage0 = 0; + sz = SCSI_MAX_INQUIRY_BYTES; + rc = MPT_SCANDV_GOOD; + while (1) { + ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id)); + retcode = 0; + dv.cmd = MPT_SET_MIN; + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + + cfg.cfghdr.hdr = &header1; + cfg.physAddr = cfg1_dma_addr; + cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + cfg.dir = 1; + if (mpt_config(hd->ioc, &cfg) != 0) + goto target_done; + + /* Wide - narrow - wide workaround case + */ + if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) { + /* Send an untagged command to reset disk Qs corrupted + * when a parity error occurs on a Request Sense. + */ + if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) || + ((hd->ioc->facts.FWVersion.Word >= 0x01010000) && + (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) { + + iocmd.cmd = REQUEST_SENSE; + iocmd.data_dma = buf1_dma; + iocmd.data = pbuf1; + iocmd.size = 0x12; + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + else { + if (hd->pLocal == NULL) + goto target_done; + rc = hd->pLocal->completion; + if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) { + dv.max.width = 0; + doFallback = 0; + } else + goto target_done; + } + } else + goto target_done; + } + + iocmd.cmd = INQUIRY; + iocmd.data_dma = buf1_dma; + iocmd.data = pbuf1; + iocmd.size = sz; + memset(pbuf1, 0x00, sz); + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + else { + if (hd->pLocal == NULL) + goto target_done; + rc = hd->pLocal->completion; + if (rc == MPT_SCANDV_GOOD) { + if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) { + if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0) + retcode = 1; + else + retcode = 0; + + goto target_done; + } + } else if (rc == MPT_SCANDV_SENSE) { + ; + } else { + /* If first command doesn't complete + * with a good status or with a check condition, + * exit. + */ + goto target_done; + } + } + + /* Reset the size for disks + */ + inq0 = (*pbuf1) & 0x1F; + if ((inq0 == 0) && vtarget && !vtarget->raidVolume) { + sz = 0x40; + iocmd.size = sz; + } + + /* Another GEM workaround. Check peripheral device type, + * if PROCESSOR, quit DV. + */ + if (inq0 == TYPE_PROCESSOR) { + mptscsih_initTarget(hd, + vtarget, + lun, + pbuf1, + sz); + goto target_done; + } + + if (inq0 > 0x08) + goto target_done; + + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + + if (sz == 0x40) { + if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A) + && (vtarget->minSyncFactor > 0x09)) { + if ((pbuf1[56] & 0x04) == 0) + ; + else if ((pbuf1[56] & 0x01) == 1) { + vtarget->minSyncFactor = + nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; + } else { + vtarget->minSyncFactor = + nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; + } + + dv.max.factor = vtarget->minSyncFactor; + + if ((pbuf1[56] & 0x02) == 0) { + vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; + ddvprintk((MYIOC_s_NOTE_FMT + "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", + ioc->name, id, pbuf1[56])); + } + } + } + + if (doFallback) + dv.cmd = MPT_FALLBACK; + else + dv.cmd = MPT_SET_MAX; + + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + if (mpt_config(hd->ioc, &cfg) != 0) + goto target_done; + + if ((!dv.now.width) && (!dv.now.offset)) + goto target_done; + + iocmd.cmd = INQUIRY; + iocmd.data_dma = buf2_dma; + iocmd.data = pbuf2; + iocmd.size = sz; + memset(pbuf2, 0x00, sz); + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + else if (hd->pLocal == NULL) + goto target_done; + else { + /* Save the return code. + * If this is the first pass, + * read SCSI Device Page 0 + * and update the target max parameters. + */ + rc = hd->pLocal->completion; + doFallback = 0; + if (rc == MPT_SCANDV_GOOD) { + if (!readPage0) { + u32 sdp0_info; + u32 sdp0_nego; + + cfg.cfghdr.hdr = &header0; + cfg.physAddr = cfg0_dma_addr; + cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + cfg.dir = 0; + + if (mpt_config(hd->ioc, &cfg) != 0) + goto target_done; + + sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E; + sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8; + + /* Quantum and Fujitsu workarounds. + * Quantum: PPR U320 -> PPR reply with Ultra2 and wide + * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide + * Resetart with a request for U160. + */ + if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) { + doFallback = 1; + } else { + dv.cmd = MPT_UPDATE_MAX; + mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data); + /* Update the SCSI device page 1 area + */ + pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters; + readPage0 = 1; + } + } + + /* Quantum workaround. Restart this test will the fallback + * flag set. + */ + if (doFallback == 0) { + if (memcmp(pbuf1, pbuf2, sz) != 0) { + if (!firstPass) + doFallback = 1; + } else { + ddvprintk((MYIOC_s_NOTE_FMT + "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); + hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; + mptscsih_initTarget(hd, + vtarget, + lun, + pbuf1, + sz); + break; /* test complete */ + } + } + + + } else if (rc == MPT_SCANDV_ISSUE_SENSE) + doFallback = 1; /* set fallback flag */ + else if ((rc == MPT_SCANDV_DID_RESET) || + (rc == MPT_SCANDV_SENSE) || + (rc == MPT_SCANDV_FALLBACK)) + doFallback = 1; /* set fallback flag */ + else + goto target_done; + + firstPass = 0; + } + } + ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id)); + + if (ioc->spi_data.mpt_dv == 0) + goto target_done; + + inq0 = (*pbuf1) & 0x1F; + + /* Continue only for disks + */ + if (inq0 != 0) + goto target_done; + + if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY ) + goto target_done; + + /* Start the Enhanced Test. + * 0) issue TUR to clear out check conditions + * 1) read capacity of echo (regular) buffer + * 2) reserve device + * 3) do write-read-compare data pattern test + * 4) release + * 5) update nego parms to target struct + */ + cfg.cfghdr.hdr = &header1; + cfg.physAddr = cfg1_dma_addr; + cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + cfg.dir = 1; + + iocmd.cmd = TEST_UNIT_READY; + iocmd.data_dma = -1; + iocmd.data = NULL; + iocmd.size = 0; + notDone = 1; + while (notDone) { + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + + if (hd->pLocal == NULL) + goto target_done; + + rc = hd->pLocal->completion; + if (rc == MPT_SCANDV_GOOD) + notDone = 0; + else if (rc == MPT_SCANDV_SENSE) { + u8 skey = hd->pLocal->sense[2] & 0x0F; + u8 asc = hd->pLocal->sense[12]; + u8 ascq = hd->pLocal->sense[13]; + ddvprintk((MYIOC_s_INFO_FMT + "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", + ioc->name, skey, asc, ascq)); + + if (skey == UNIT_ATTENTION) + notDone++; /* repeat */ + else if ((skey == NOT_READY) && + (asc == 0x04)&&(ascq == 0x01)) { + /* wait then repeat */ + mdelay (2000); + notDone++; + } else if ((skey == NOT_READY) && (asc == 0x3A)) { + /* no medium, try read test anyway */ + notDone = 0; + } else { + /* All other errors are fatal. + */ + ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.", + ioc->name)); + goto target_done; + } + } else + goto target_done; + } + + iocmd.cmd = READ_BUFFER; + iocmd.data_dma = buf1_dma; + iocmd.data = pbuf1; + iocmd.size = 4; + iocmd.flags |= MPT_ICFLAG_BUF_CAP; + + dataBufSize = 0; + echoBufSize = 0; + for (patt = 0; patt < 2; patt++) { + if (patt == 0) + iocmd.flags |= MPT_ICFLAG_ECHO; + else + iocmd.flags &= ~MPT_ICFLAG_ECHO; + + notDone = 1; + while (notDone) { + bufsize = 0; + + /* If not ready after 8 trials, + * give up on this device. + */ + if (notDone > 8) + goto target_done; + + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + else if (hd->pLocal == NULL) + goto target_done; + else { + rc = hd->pLocal->completion; + ddvprintk(("ReadBuffer Comp Code %d", rc)); + ddvprintk((" buff: %0x %0x %0x %0x\n", + pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3])); + + if (rc == MPT_SCANDV_GOOD) { + notDone = 0; + if (iocmd.flags & MPT_ICFLAG_ECHO) { + bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3]; + if (pbuf1[0] & 0x01) + iocmd.flags |= MPT_ICFLAG_EBOS; + } else { + bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3]; + } + } else if (rc == MPT_SCANDV_SENSE) { + u8 skey = hd->pLocal->sense[2] & 0x0F; + u8 asc = hd->pLocal->sense[12]; + u8 ascq = hd->pLocal->sense[13]; + ddvprintk((MYIOC_s_INFO_FMT + "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", + ioc->name, skey, asc, ascq)); + if (skey == ILLEGAL_REQUEST) { + notDone = 0; + } else if (skey == UNIT_ATTENTION) { + notDone++; /* repeat */ + } else if ((skey == NOT_READY) && + (asc == 0x04)&&(ascq == 0x01)) { + /* wait then repeat */ + mdelay (2000); + notDone++; + } else { + /* All other errors are fatal. + */ + ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.", + ioc->name)); + goto target_done; + } + } else { + /* All other errors are fatal + */ + goto target_done; + } + } + } + + if (iocmd.flags & MPT_ICFLAG_ECHO) + echoBufSize = bufsize; + else + dataBufSize = bufsize; + } + sz = 0; + iocmd.flags &= ~MPT_ICFLAG_BUF_CAP; + + /* Use echo buffers if possible, + * Exit if both buffers are 0. + */ + if (echoBufSize > 0) { + iocmd.flags |= MPT_ICFLAG_ECHO; + if (dataBufSize > 0) + bufsize = min(echoBufSize, dataBufSize); + else + bufsize = echoBufSize; + } else if (dataBufSize == 0) + goto target_done; + + ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name, + (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize)); + + /* Data buffers for write-read-compare test max 1K. + */ + sz = min(bufsize, 1024); + + /* --- loop ---- + * On first pass, always issue a reserve. + * On additional loops, only if a reset has occurred. + * iocmd.flags indicates if echo or regular buffer + */ + for (patt = 0; patt < 4; patt++) { + ddvprintk(("Pattern %d\n", patt)); + if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) { + iocmd.cmd = TEST_UNIT_READY; + iocmd.data_dma = -1; + iocmd.data = NULL; + iocmd.size = 0; + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + + iocmd.cmd = RELEASE; + iocmd.data_dma = -1; + iocmd.data = NULL; + iocmd.size = 0; + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + else if (hd->pLocal == NULL) + goto target_done; + else { + rc = hd->pLocal->completion; + ddvprintk(("Release rc %d\n", rc)); + if (rc == MPT_SCANDV_GOOD) + iocmd.flags &= ~MPT_ICFLAG_RESERVED; + else + goto target_done; + } + iocmd.flags &= ~MPT_ICFLAG_RESERVED; + } + iocmd.flags &= ~MPT_ICFLAG_DID_RESET; + + if (iocmd.flags & MPT_ICFLAG_EBOS) + goto skip_Reserve; + + repeat = 5; + while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) { + iocmd.cmd = RESERVE; + iocmd.data_dma = -1; + iocmd.data = NULL; + iocmd.size = 0; + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + else if (hd->pLocal == NULL) + goto target_done; + else { + rc = hd->pLocal->completion; + if (rc == MPT_SCANDV_GOOD) { + iocmd.flags |= MPT_ICFLAG_RESERVED; + } else if (rc == MPT_SCANDV_SENSE) { + /* Wait if coming ready + */ + u8 skey = hd->pLocal->sense[2] & 0x0F; + u8 asc = hd->pLocal->sense[12]; + u8 ascq = hd->pLocal->sense[13]; + ddvprintk((MYIOC_s_INFO_FMT + "DV: Reserve Failed: ", ioc->name)); + ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", + skey, asc, ascq)); + + if ((skey == NOT_READY) && (asc == 0x04)&& + (ascq == 0x01)) { + /* wait then repeat */ + mdelay (2000); + notDone++; + } else { + ddvprintk((MYIOC_s_INFO_FMT + "DV: Reserved Failed.", ioc->name)); + goto target_done; + } + } else { + ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.", + ioc->name)); + goto target_done; + } + } + } + +skip_Reserve: + mptscsih_fillbuf(pbuf1, sz, patt, 1); + iocmd.cmd = WRITE_BUFFER; + iocmd.data_dma = buf1_dma; + iocmd.data = pbuf1; + iocmd.size = sz; + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + else if (hd->pLocal == NULL) + goto target_done; + else { + rc = hd->pLocal->completion; + if (rc == MPT_SCANDV_GOOD) + ; /* Issue read buffer */ + else if (rc == MPT_SCANDV_DID_RESET) { + /* If using echo buffers, reset to data buffers. + * Else do Fallback and restart + * this test (re-issue reserve + * because of bus reset). + */ + if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) { + iocmd.flags &= ~MPT_ICFLAG_ECHO; + } else { + dv.cmd = MPT_FALLBACK; + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + + if (mpt_config(hd->ioc, &cfg) != 0) + goto target_done; + + if ((!dv.now.width) && (!dv.now.offset)) + goto target_done; + } + + iocmd.flags |= MPT_ICFLAG_DID_RESET; + patt = -1; + continue; + } else if (rc == MPT_SCANDV_SENSE) { + /* Restart data test if UA, else quit. + */ + u8 skey = hd->pLocal->sense[2] & 0x0F; + ddvprintk((MYIOC_s_INFO_FMT + "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey, + hd->pLocal->sense[12], hd->pLocal->sense[13])); + if (skey == UNIT_ATTENTION) { + patt = -1; + continue; + } else if (skey == ILLEGAL_REQUEST) { + if (iocmd.flags & MPT_ICFLAG_ECHO) { + if (dataBufSize >= bufsize) { + iocmd.flags &= ~MPT_ICFLAG_ECHO; + patt = -1; + continue; + } + } + goto target_done; + } + else + goto target_done; + } else { + /* fatal error */ + goto target_done; + } + } + + iocmd.cmd = READ_BUFFER; + iocmd.data_dma = buf2_dma; + iocmd.data = pbuf2; + iocmd.size = sz; + if (mptscsih_do_cmd(hd, &iocmd) < 0) + goto target_done; + else if (hd->pLocal == NULL) + goto target_done; + else { + rc = hd->pLocal->completion; + if (rc == MPT_SCANDV_GOOD) { + /* If buffers compare, + * go to next pattern, + * else, do a fallback and restart + * data transfer test. + */ + if (memcmp (pbuf1, pbuf2, sz) == 0) { + ; /* goto next pattern */ + } else { + /* Miscompare with Echo buffer, go to data buffer, + * if that buffer exists. + * Miscompare with Data buffer, check first 4 bytes, + * some devices return capacity. Exit in this case. + */ + if (iocmd.flags & MPT_ICFLAG_ECHO) { + if (dataBufSize >= bufsize) + iocmd.flags &= ~MPT_ICFLAG_ECHO; + else + goto target_done; + } else { + if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) { + /* Argh. Device returning wrong data. + * Quit DV for this device. + */ + goto target_done; + } + + /* Had an actual miscompare. Slow down.*/ + dv.cmd = MPT_FALLBACK; + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + + if (mpt_config(hd->ioc, &cfg) != 0) + goto target_done; + + if ((!dv.now.width) && (!dv.now.offset)) + goto target_done; + } + + patt = -1; + continue; + } + } else if (rc == MPT_SCANDV_DID_RESET) { + /* Do Fallback and restart + * this test (re-issue reserve + * because of bus reset). + */ + dv.cmd = MPT_FALLBACK; + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + + if (mpt_config(hd->ioc, &cfg) != 0) + goto target_done; + + if ((!dv.now.width) && (!dv.now.offset)) + goto target_done; + + iocmd.flags |= MPT_ICFLAG_DID_RESET; + patt = -1; + continue; + } else if (rc == MPT_SCANDV_SENSE) { + /* Restart data test if UA, else quit. + */ + u8 skey = hd->pLocal->sense[2] & 0x0F; + ddvprintk((MYIOC_s_INFO_FMT + "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey, + hd->pLocal->sense[12], hd->pLocal->sense[13])); + if (skey == UNIT_ATTENTION) { + patt = -1; + continue; + } + else + goto target_done; + } else { + /* fatal error */ + goto target_done; + } + } + + } /* --- end of patt loop ---- */ + +target_done: + if (iocmd.flags & MPT_ICFLAG_RESERVED) { + iocmd.cmd = RELEASE; + iocmd.data_dma = -1; + iocmd.data = NULL; + iocmd.size = 0; + if (mptscsih_do_cmd(hd, &iocmd) < 0) + printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d", + ioc->name, id); + else if (hd->pLocal) { + if (hd->pLocal->completion == MPT_SCANDV_GOOD) + iocmd.flags &= ~MPT_ICFLAG_RESERVED; + } else { + printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d", + ioc->name, id); + } + } + + + /* Set if cfg1_dma_addr contents is valid + */ + if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){ + /* If disk, not U320, disable QAS + */ + if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) { + hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; + ddvprintk((MYIOC_s_NOTE_FMT + "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor)); + } + + dv.cmd = MPT_SAVE; + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + + /* Double writes to SDP1 can cause problems, + * skip save of the final negotiated settings to + * SCSI device page 1. + * + cfg.cfghdr.hdr = &header1; + cfg.physAddr = cfg1_dma_addr; + cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + cfg.dir = 1; + mpt_config(hd->ioc, &cfg); + */ + } + + /* If this is a RAID Passthrough, enable internal IOs + */ + if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) { + if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0) + ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name)); + } + + /* Done with the DV scan of the current target + */ + if (pDvBuf) + pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma); + + ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n", + ioc->name, id)); + + return retcode; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* mptscsih_dv_parms - perform a variety of operations on the + * parameters used for negotiation. + * @hd: Pointer to a SCSI host. + * @dv: Pointer to a structure that contains the maximum and current + * negotiated parameters. + */ +static void +mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) +{ + VirtTarget *vtarget; + SCSIDevicePage0_t *pPage0; + SCSIDevicePage1_t *pPage1; + int val = 0, data, configuration; + u8 width = 0; + u8 offset = 0; + u8 factor = 0; + u8 negoFlags = 0; + u8 cmd = dv->cmd; + u8 id = dv->id; + + switch (cmd) { + case MPT_GET_NVRAM_VALS: + ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ", + hd->ioc->name)); + /* Get the NVRAM values and save in tmax + * If not an LVD bus, the adapter minSyncFactor has been + * already throttled back. + */ + negoFlags = hd->ioc->spi_data.noQas; + if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) { + width = vtarget->maxWidth; + offset = vtarget->maxOffset; + factor = vtarget->minSyncFactor; + negoFlags |= vtarget->negoFlags; + } else { + if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { + data = hd->ioc->spi_data.nvram[id]; + width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; + if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0) + factor = MPT_ASYNC; + else { + factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; + if ((factor == 0) || (factor == MPT_ASYNC)){ + factor = MPT_ASYNC; + offset = 0; + } + } + } else { + width = MPT_NARROW; + offset = 0; + factor = MPT_ASYNC; + } + + /* Set the negotiation flags */ + if (!width) + negoFlags |= MPT_TARGET_NO_NEGO_WIDE; + + if (!offset) + negoFlags |= MPT_TARGET_NO_NEGO_SYNC; + } + + /* limit by adapter capabilities */ + width = min(width, hd->ioc->spi_data.maxBusWidth); + offset = min(offset, hd->ioc->spi_data.maxSyncOffset); + factor = max(factor, hd->ioc->spi_data.minSyncFactor); + + /* Check Consistency */ + if (offset && (factor < MPT_ULTRA2) && !width) + factor = MPT_ULTRA2; + + dv->max.width = width; + dv->max.offset = offset; + dv->max.factor = factor; + dv->max.flags = negoFlags; + ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n", + id, width, factor, offset, negoFlags)); + break; + + case MPT_UPDATE_MAX: + ddvprintk((MYIOC_s_NOTE_FMT + "Updating with SDP0 Data: ", hd->ioc->name)); + /* Update tmax values with those from Device Page 0.*/ + pPage0 = (SCSIDevicePage0_t *) pPage; + if (pPage0) { + val = le32_to_cpu(pPage0->NegotiatedParameters); + dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0; + dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16; + dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8; + } + + dv->now.width = dv->max.width; + dv->now.offset = dv->max.offset; + dv->now.factor = dv->max.factor; + ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n", + id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags)); + break; + + case MPT_SET_MAX: + ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ", + hd->ioc->name)); + /* Set current to the max values. Update the config page.*/ + dv->now.width = dv->max.width; + dv->now.offset = dv->max.offset; + dv->now.factor = dv->max.factor; + dv->now.flags = dv->max.flags; + + pPage1 = (SCSIDevicePage1_t *)pPage; + if (pPage1) { + mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor, + dv->now.offset, &val, &configuration, dv->now.flags); + dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", + id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration)); + pPage1->RequestedParameters = cpu_to_le32(val); + pPage1->Reserved = 0; + pPage1->Configuration = cpu_to_le32(configuration); + } + + ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n", + id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration)); + break; + + case MPT_SET_MIN: + ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ", + hd->ioc->name)); + /* Set page to asynchronous and narrow + * Do not update now, breaks fallback routine. */ + width = MPT_NARROW; + offset = 0; + factor = MPT_ASYNC; + negoFlags = dv->max.flags; + + pPage1 = (SCSIDevicePage1_t *)pPage; + if (pPage1) { + mptscsih_setDevicePage1Flags (width, factor, + offset, &val, &configuration, negoFlags); + dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", + id, width, factor, offset, negoFlags, val, configuration)); + pPage1->RequestedParameters = cpu_to_le32(val); + pPage1->Reserved = 0; + pPage1->Configuration = cpu_to_le32(configuration); + } + ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n", + id, width, factor, offset, val, configuration, negoFlags)); + break; + + case MPT_FALLBACK: + ddvprintk((MYIOC_s_NOTE_FMT + "Fallback: Start: offset %d, factor %x, width %d \n", + hd->ioc->name, dv->now.offset, + dv->now.factor, dv->now.width)); + width = dv->now.width; + offset = dv->now.offset; + factor = dv->now.factor; + if ((offset) && (dv->max.width)) { + if (factor < MPT_ULTRA160) + factor = MPT_ULTRA160; + else if (factor < MPT_ULTRA2) { + factor = MPT_ULTRA2; + width = MPT_WIDE; + } else if ((factor == MPT_ULTRA2) && width) { + factor = MPT_ULTRA2; + width = MPT_NARROW; + } else if (factor < MPT_ULTRA) { + factor = MPT_ULTRA; + width = MPT_WIDE; + } else if ((factor == MPT_ULTRA) && width) { + width = MPT_NARROW; + } else if (factor < MPT_FAST) { + factor = MPT_FAST; + width = MPT_WIDE; + } else if ((factor == MPT_FAST) && width) { + factor = MPT_FAST; + width = MPT_NARROW; + } else if (factor < MPT_SCSI) { + factor = MPT_SCSI; + width = MPT_WIDE; + } else if ((factor == MPT_SCSI) && width) { + factor = MPT_SCSI; + width = MPT_NARROW; + } else { + factor = MPT_ASYNC; + offset = 0; + } + + } else if (offset) { + width = MPT_NARROW; + if (factor < MPT_ULTRA) + factor = MPT_ULTRA; + else if (factor < MPT_FAST) + factor = MPT_FAST; + else if (factor < MPT_SCSI) + factor = MPT_SCSI; + else { + factor = MPT_ASYNC; + offset = 0; + } + + } else { + width = MPT_NARROW; + factor = MPT_ASYNC; + } + dv->max.flags |= MPT_TARGET_NO_NEGO_QAS; + dv->max.flags &= ~MPT_TAPE_NEGO_IDP; + + dv->now.width = width; + dv->now.offset = offset; + dv->now.factor = factor; + dv->now.flags = dv->max.flags; + + pPage1 = (SCSIDevicePage1_t *)pPage; + if (pPage1) { + mptscsih_setDevicePage1Flags (width, factor, offset, &val, + &configuration, dv->now.flags); + dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n", + id, width, offset, factor, dv->now.flags, val, configuration)); + + pPage1->RequestedParameters = cpu_to_le32(val); + pPage1->Reserved = 0; + pPage1->Configuration = cpu_to_le32(configuration); + } + + ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n", + id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration)); + break; + + case MPT_SAVE: + ddvprintk((MYIOC_s_NOTE_FMT + "Saving to Target structure: ", hd->ioc->name)); + ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n", + id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags)); + + /* Save these values to target structures + * or overwrite nvram (phys disks only). + */ + + if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) { + vtarget->maxWidth = dv->now.width; + vtarget->maxOffset = dv->now.offset; + vtarget->minSyncFactor = dv->now.factor; + vtarget->negoFlags = dv->now.flags; + } else { + /* Preserv all flags, use + * read-modify-write algorithm + */ + if (hd->ioc->spi_data.nvram) { + data = hd->ioc->spi_data.nvram[id]; + + if (dv->now.width) + data &= ~MPT_NVRAM_WIDE_DISABLE; + else + data |= MPT_NVRAM_WIDE_DISABLE; + + if (!dv->now.offset) + factor = MPT_ASYNC; + + data &= ~MPT_NVRAM_SYNC_MASK; + data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK; + + hd->ioc->spi_data.nvram[id] = data; + } + } + break; + } +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* mptscsih_fillbuf - fill a buffer with a special data pattern + * cleanup. For bus scan only. + * + * @buffer: Pointer to data buffer to be filled. + * @size: Number of bytes to fill + * @index: Pattern index + * @width: bus width, 0 (8 bits) or 1 (16 bits) + */ +static void +mptscsih_fillbuf(char *buffer, int size, int index, int width) +{ + char *ptr = buffer; + int ii; + char byte; + short val; + + switch (index) { + case 0: + + if (width) { + /* Pattern: 0000 FFFF 0000 FFFF + */ + for (ii=0; ii < size; ii++, ptr++) { + if (ii & 0x02) + *ptr = 0xFF; + else + *ptr = 0x00; + } + } else { + /* Pattern: 00 FF 00 FF + */ + for (ii=0; ii < size; ii++, ptr++) { + if (ii & 0x01) + *ptr = 0xFF; + else + *ptr = 0x00; + } + } + break; + + case 1: + if (width) { + /* Pattern: 5555 AAAA 5555 AAAA 5555 + */ + for (ii=0; ii < size; ii++, ptr++) { + if (ii & 0x02) + *ptr = 0xAA; + else + *ptr = 0x55; + } + } else { + /* Pattern: 55 AA 55 AA 55 + */ + for (ii=0; ii < size; ii++, ptr++) { + if (ii & 0x01) + *ptr = 0xAA; + else + *ptr = 0x55; + } + } + break; + + case 2: + /* Pattern: 00 01 02 03 04 05 + * ... FE FF 00 01.. + */ + for (ii=0; ii < size; ii++, ptr++) + *ptr = (char) ii; + break; + + case 3: + if (width) { + /* Wide Pattern: FFFE 0001 FFFD 0002 + * ... 4000 DFFF 8000 EFFF + */ + byte = 0; + for (ii=0; ii < size/2; ii++) { + /* Create the base pattern + */ + val = (1 << byte); + /* every 64 (0x40) bytes flip the pattern + * since we fill 2 bytes / iteration, + * test for ii = 0x20 + */ + if (ii & 0x20) + val = ~(val); + + if (ii & 0x01) { + *ptr = (char)( (val & 0xFF00) >> 8); + ptr++; + *ptr = (char)(val & 0xFF); + byte++; + byte &= 0x0F; + } else { + val = ~val; + *ptr = (char)( (val & 0xFF00) >> 8); + ptr++; + *ptr = (char)(val & 0xFF); + } + + ptr++; + } + } else { + /* Narrow Pattern: FE 01 FD 02 FB 04 + * .. 7F 80 01 FE 02 FD ... 80 7F + */ + byte = 0; + for (ii=0; ii < size; ii++, ptr++) { + /* Base pattern - first 32 bytes + */ + if (ii & 0x01) { + *ptr = (1 << byte); + byte++; + byte &= 0x07; + } else { + *ptr = (char) (~(1 << byte)); + } + + /* Flip the pattern every 32 bytes + */ + if (ii & 0x20) + *ptr = ~(*ptr); + } + } + break; + } +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return. + * Else set the NEED_DV flag after Read Capacity Issued (disks) + * or Mode Sense (cdroms). + * + * Tapes, initTarget will set this flag on completion of Inquiry command. + * Called only if DV_NOT_DONE flag is set + */ +static void +mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc) +{ + MPT_ADAPTER *ioc = hd->ioc; + u8 cmd; + SpiCfgData *pSpi; + + ddvtprintk((MYIOC_s_NOTE_FMT + " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", + hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0])); + + if ((sc->device->lun != 0) || (hd->negoNvram != 0)) + return; + + cmd = sc->cmnd[0]; + + if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { + pSpi = &ioc->spi_data; + if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) { + /* Set NEED_DV for all hidden disks + */ + Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; + int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; + + while (numPDisk) { + pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; + ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID)); + pPDisk++; + numPDisk--; + } + } + pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV; + ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id)); + } +} + +/* mptscsih_raid_set_dv_flags() + * + * New or replaced disk. Set DV flag and schedule DV. + */ +static void +mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id) +{ + MPT_ADAPTER *ioc = hd->ioc; + SpiCfgData *pSpi = &ioc->spi_data; + Ioc3PhysDisk_t *pPDisk; + int numPDisk; + + if (hd->negoNvram != 0) + return; + + ddvtprintk(("DV requested for phys disk id %d\n", id)); + if (ioc->raid_data.pIocPg3) { + pPDisk = ioc->raid_data.pIocPg3->PhysDisk; + numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; + while (numPDisk) { + if (id == pPDisk->PhysDiskNum) { + pSpi->dvStatus[pPDisk->PhysDiskID] = + (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE); + pSpi->forceDv = MPT_SCSICFG_NEED_DV; + ddvtprintk(("NEED_DV set for phys disk id %d\n", + pPDisk->PhysDiskID)); + break; + } + pPDisk++; + numPDisk--; + } + + if (numPDisk == 0) { + /* The physical disk that needs DV was not found + * in the stored IOC Page 3. The driver must reload + * this page. DV routine will set the NEED_DV flag for + * all phys disks that have DV_NOT_DONE set. + */ + pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; + ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id)); + } + } +} +#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ + EXPORT_SYMBOL(mptscsih_remove); EXPORT_SYMBOL(mptscsih_shutdown); #ifdef CONFIG_PM diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 14a5b6c2e..44b248d51 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -60,6 +60,16 @@ #define MPT_SCSI_MAX_SECTORS 8192 +/* To disable domain validation, uncomment the + * following line. No effect for FC devices. + * For SCSI devices, driver will negotiate to + * NVRAM settings (if available) or to maximum adapter + * capabilities. + */ + +#define MPTSCSIH_ENABLE_DOMAIN_VALIDATION + + /* SCSI driver setup structure. Settings can be overridden * by command line options. */ @@ -99,5 +109,3 @@ extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); extern void mptscsih_timer_expired(unsigned long data); extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); -extern int mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid); -extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 3201de053..f148dfa39 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -56,15 +56,12 @@ #include /* notifier code */ #include #include -#include #include #include #include #include #include -#include -#include #include "mptbase.h" #include "mptscsih.h" @@ -79,6 +76,20 @@ MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); /* Command line args */ +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION +static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION; +module_param(mpt_dv, int, 0); +MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)"); + +static int mpt_width = MPTSCSIH_MAX_WIDTH; +module_param(mpt_width, int, 0); +MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)"); + +static ushort mpt_factor = MPTSCSIH_MIN_SYNC; +module_param(mpt_factor, ushort, 0); +MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)"); +#endif + static int mpt_saf_te = MPTSCSIH_SAF_TE; module_param(mpt_saf_te, int, 0); MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)"); @@ -87,308 +98,10 @@ static int mpt_pq_filter = 0; module_param(mpt_pq_filter, int, 0); MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); -static void mptspi_write_offset(struct scsi_target *, int); -static void mptspi_write_width(struct scsi_target *, int); -static int mptspi_write_spi_device_pg1(struct scsi_target *, - struct _CONFIG_PAGE_SCSI_DEVICE_1 *); - -static struct scsi_transport_template *mptspi_transport_template = NULL; - static int mptspiDoneCtx = -1; static int mptspiTaskCtx = -1; static int mptspiInternalCtx = -1; /* Used only for internal commands */ -static int mptspi_target_alloc(struct scsi_target *starget) -{ - struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; - int ret; - - if (hd == NULL) - return -ENODEV; - - ret = mptscsih_target_alloc(starget); - if (ret) - return ret; - - /* if we're a device on virtual channel 1 and we're not part - * of an array, just return here (otherwise the setup below - * may actually affect a real physical device on channel 0 */ - if (starget->channel == 1 && - mptscsih_raid_id_to_num(hd, starget->id) < 0) - return 0; - - if (hd->ioc->spi_data.nvram && - hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { - u32 nvram = hd->ioc->spi_data.nvram[starget->id]; - spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; - spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; - } else { - spi_min_period(starget) = hd->ioc->spi_data.minSyncFactor; - spi_max_width(starget) = hd->ioc->spi_data.maxBusWidth; - } - spi_max_offset(starget) = hd->ioc->spi_data.maxSyncOffset; - - spi_offset(starget) = 0; - mptspi_write_width(starget, 0); - - return 0; -} - -static int mptspi_read_spi_device_pg0(struct scsi_target *starget, - struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0) -{ - struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; - struct _MPT_ADAPTER *ioc = hd->ioc; - struct _CONFIG_PAGE_SCSI_DEVICE_0 *pg0; - dma_addr_t pg0_dma; - int size; - struct _x_config_parms cfg; - struct _CONFIG_PAGE_HEADER hdr; - int err = -EBUSY; - - /* No SPI parameters for RAID devices */ - if (starget->channel == 0 && - (hd->ioc->raid_data.isRaid & (1 << starget->id))) - return -1; - - size = ioc->spi_data.sdp0length * 4; - /* - if (ioc->spi_data.sdp0length & 1) - size += size + 4; - size += 2048; - */ - - pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg0_dma, GFP_KERNEL); - if (pg0 == NULL) { - starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n"); - return -EINVAL; - } - - memset(&hdr, 0, sizeof(hdr)); - - hdr.PageVersion = ioc->spi_data.sdp0version; - hdr.PageLength = ioc->spi_data.sdp0length; - hdr.PageNumber = 0; - hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; - - memset(&cfg, 0, sizeof(cfg)); - - cfg.cfghdr.hdr = &hdr; - cfg.physAddr = pg0_dma; - cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; - cfg.dir = 0; - cfg.pageAddr = starget->id; - - if (mpt_config(ioc, &cfg)) { - starget_printk(KERN_ERR, starget, "mpt_config failed\n"); - goto out_free; - } - err = 0; - memcpy(pass_pg0, pg0, size); - - out_free: - dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma); - return err; -} - -static u32 mptspi_getRP(struct scsi_target *starget) -{ - u32 nego = 0; - - nego |= spi_iu(starget) ? MPI_SCSIDEVPAGE1_RP_IU : 0; - nego |= spi_dt(starget) ? MPI_SCSIDEVPAGE1_RP_DT : 0; - nego |= spi_qas(starget) ? MPI_SCSIDEVPAGE1_RP_QAS : 0; - nego |= spi_hold_mcs(starget) ? MPI_SCSIDEVPAGE1_RP_HOLD_MCS : 0; - nego |= spi_wr_flow(starget) ? MPI_SCSIDEVPAGE1_RP_WR_FLOW : 0; - nego |= spi_rd_strm(starget) ? MPI_SCSIDEVPAGE1_RP_RD_STRM : 0; - nego |= spi_rti(starget) ? MPI_SCSIDEVPAGE1_RP_RTI : 0; - nego |= spi_pcomp_en(starget) ? MPI_SCSIDEVPAGE1_RP_PCOMP_EN : 0; - - nego |= (spi_period(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD) & MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK; - nego |= (spi_offset(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET) & MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK; - nego |= spi_width(starget) ? MPI_SCSIDEVPAGE1_RP_WIDE : 0; - - return nego; -} - -static void mptspi_read_parameters(struct scsi_target *starget) -{ - int nego; - struct _CONFIG_PAGE_SCSI_DEVICE_0 pg0; - - mptspi_read_spi_device_pg0(starget, &pg0); - - nego = le32_to_cpu(pg0.NegotiatedParameters); - - spi_iu(starget) = (nego & MPI_SCSIDEVPAGE0_NP_IU) ? 1 : 0; - spi_dt(starget) = (nego & MPI_SCSIDEVPAGE0_NP_DT) ? 1 : 0; - spi_qas(starget) = (nego & MPI_SCSIDEVPAGE0_NP_QAS) ? 1 : 0; - spi_wr_flow(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WR_FLOW) ? 1 : 0; - spi_rd_strm(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RD_STRM) ? 1 : 0; - spi_rti(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RTI) ? 1 : 0; - spi_pcomp_en(starget) = (nego & MPI_SCSIDEVPAGE0_NP_PCOMP_EN) ? 1 : 0; - spi_hold_mcs(starget) = (nego & MPI_SCSIDEVPAGE0_NP_HOLD_MCS) ? 1 : 0; - spi_period(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD; - spi_offset(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET; - spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0; -} - -static int -mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk) -{ - MpiRaidActionRequest_t *pReq; - MPT_FRAME_HDR *mf; - - /* Get and Populate a free Frame - */ - if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) { - ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n", - hd->ioc->name)); - return -EAGAIN; - } - pReq = (MpiRaidActionRequest_t *)mf; - if (quiesce) - pReq->Action = MPI_RAID_ACTION_QUIESCE_PHYS_IO; - else - pReq->Action = MPI_RAID_ACTION_ENABLE_PHYS_IO; - pReq->Reserved1 = 0; - pReq->ChainOffset = 0; - pReq->Function = MPI_FUNCTION_RAID_ACTION; - pReq->VolumeID = disk; - pReq->VolumeBus = 0; - pReq->PhysDiskNum = 0; - pReq->MsgFlags = 0; - pReq->Reserved2 = 0; - pReq->ActionDataWord = 0; /* Reserved for this action */ - - mpt_add_sge((char *)&pReq->ActionDataSGE, - MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); - - ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n", - hd->ioc->name, action, io->id)); - - hd->pLocal = NULL; - hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ - hd->scandv_wait_done = 0; - - /* Save cmd pointer, for resource free if timeout or - * FW reload occurs - */ - hd->cmdPtr = mf; - - add_timer(&hd->timer); - mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf); - wait_event(hd->scandv_waitq, hd->scandv_wait_done); - - if ((hd->pLocal == NULL) || (hd->pLocal->completion != 0)) - return -1; - - return 0; -} - -static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, - struct scsi_device *sdev) -{ - VirtTarget *vtarget = scsi_target(sdev)->hostdata; - - /* no DV on RAID devices */ - if (sdev->channel == 0 && - (hd->ioc->raid_data.isRaid & (1 << sdev->id))) - return; - - /* If this is a piece of a RAID, then quiesce first */ - if (sdev->channel == 1 && - mptscsih_quiesce_raid(hd, 1, vtarget->target_id) < 0) { - starget_printk(KERN_ERR, scsi_target(sdev), - "Integrated RAID quiesce failed\n"); - return; - } - - spi_dv_device(sdev); - - if (sdev->channel == 1 && - mptscsih_quiesce_raid(hd, 0, vtarget->target_id) < 0) - starget_printk(KERN_ERR, scsi_target(sdev), - "Integrated RAID resume failed\n"); - - mptspi_read_parameters(sdev->sdev_target); - spi_display_xfer_agreement(sdev->sdev_target); - mptspi_read_parameters(sdev->sdev_target); -} - -static int mptspi_slave_alloc(struct scsi_device *sdev) -{ - int ret; - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; - /* gcc doesn't see that all uses of this variable occur within - * the if() statements, so stop it from whining */ - int physdisknum = 0; - - if (sdev->channel == 1) { - physdisknum = mptscsih_raid_id_to_num(hd, sdev->id); - - if (physdisknum < 0) - return physdisknum; - } - - ret = mptscsih_slave_alloc(sdev); - - if (ret) - return ret; - - if (sdev->channel == 1) { - VirtDevice *vdev = sdev->hostdata; - sdev->no_uld_attach = 1; - vdev->vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; - /* The real channel for this device is zero */ - vdev->vtarget->bus_id = 0; - /* The actual physdisknum (for RAID passthrough) */ - vdev->vtarget->target_id = physdisknum; - } - - return 0; -} - -static int mptspi_slave_configure(struct scsi_device *sdev) -{ - int ret = mptscsih_slave_configure(sdev); - struct _MPT_SCSI_HOST *hd = - (struct _MPT_SCSI_HOST *)sdev->host->hostdata; - - if (ret) - return ret; - - if ((sdev->channel == 1 || - !(hd->ioc->raid_data.isRaid & (1 << sdev->id))) && - !spi_initial_dv(sdev->sdev_target)) - mptspi_dv_device(hd, sdev); - - return 0; -} - -static void mptspi_slave_destroy(struct scsi_device *sdev) -{ - struct scsi_target *starget = scsi_target(sdev); - VirtTarget *vtarget = starget->hostdata; - VirtDevice *vdevice = sdev->hostdata; - - /* Will this be the last lun on a non-raid device? */ - if (vtarget->num_luns == 1 && vdevice->configured_lun) { - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - - /* Async Narrow */ - pg1.RequestedParameters = 0; - pg1.Reserved = 0; - pg1.Configuration = 0; - - mptspi_write_spi_device_pg1(starget, &pg1); - } - - mptscsih_slave_destroy(sdev); -} - static struct scsi_host_template mptspi_driver_template = { .module = THIS_MODULE, .proc_name = "mptspi", @@ -396,11 +109,11 @@ static struct scsi_host_template mptspi_driver_template = { .name = "MPT SPI Host", .info = mptscsih_info, .queuecommand = mptscsih_qcmd, - .target_alloc = mptspi_target_alloc, - .slave_alloc = mptspi_slave_alloc, - .slave_configure = mptspi_slave_configure, + .target_alloc = mptscsih_target_alloc, + .slave_alloc = mptscsih_slave_alloc, + .slave_configure = mptscsih_slave_configure, .target_destroy = mptscsih_target_destroy, - .slave_destroy = mptspi_slave_destroy, + .slave_destroy = mptscsih_slave_destroy, .change_queue_depth = mptscsih_change_queue_depth, .eh_abort_handler = mptscsih_abort, .eh_device_reset_handler = mptscsih_dev_reset, @@ -415,360 +128,6 @@ static struct scsi_host_template mptspi_driver_template = { .use_clustering = ENABLE_CLUSTERING, }; -static int mptspi_write_spi_device_pg1(struct scsi_target *starget, - struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1) -{ - struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; - struct _MPT_ADAPTER *ioc = hd->ioc; - struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1; - dma_addr_t pg1_dma; - int size; - struct _x_config_parms cfg; - struct _CONFIG_PAGE_HEADER hdr; - int err = -EBUSY; - - /* don't allow updating nego parameters on RAID devices */ - if (starget->channel == 0 && - (hd->ioc->raid_data.isRaid & (1 << starget->id))) - return -1; - - size = ioc->spi_data.sdp1length * 4; - - pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL); - if (pg1 == NULL) { - starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n"); - return -EINVAL; - } - - memset(&hdr, 0, sizeof(hdr)); - - hdr.PageVersion = ioc->spi_data.sdp1version; - hdr.PageLength = ioc->spi_data.sdp1length; - hdr.PageNumber = 1; - hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; - - memset(&cfg, 0, sizeof(cfg)); - - cfg.cfghdr.hdr = &hdr; - cfg.physAddr = pg1_dma; - cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; - cfg.dir = 1; - cfg.pageAddr = starget->id; - - memcpy(pg1, pass_pg1, size); - - pg1->Header.PageVersion = hdr.PageVersion; - pg1->Header.PageLength = hdr.PageLength; - pg1->Header.PageNumber = hdr.PageNumber; - pg1->Header.PageType = hdr.PageType; - - if (mpt_config(ioc, &cfg)) { - starget_printk(KERN_ERR, starget, "mpt_config failed\n"); - goto out_free; - } - err = 0; - - out_free: - dma_free_coherent(&ioc->pcidev->dev, size, pg1, pg1_dma); - return err; -} - -static void mptspi_write_offset(struct scsi_target *starget, int offset) -{ - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - u32 nego; - - if (offset < 0) - offset = 0; - - if (offset > 255) - offset = 255; - - if (spi_offset(starget) == -1) - mptspi_read_parameters(starget); - - spi_offset(starget) = offset; - - nego = mptspi_getRP(starget); - - pg1.RequestedParameters = cpu_to_le32(nego); - pg1.Reserved = 0; - pg1.Configuration = 0; - - mptspi_write_spi_device_pg1(starget, &pg1); -} - -static void mptspi_write_period(struct scsi_target *starget, int period) -{ - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - u32 nego; - - if (period < 8) - period = 8; - - if (period > 255) - period = 255; - - if (spi_period(starget) == -1) - mptspi_read_parameters(starget); - - if (period == 8) { - spi_iu(starget) = 1; - spi_dt(starget) = 1; - } else if (period == 9) { - spi_dt(starget) = 1; - } - - spi_period(starget) = period; - - nego = mptspi_getRP(starget); - - pg1.RequestedParameters = cpu_to_le32(nego); - pg1.Reserved = 0; - pg1.Configuration = 0; - - mptspi_write_spi_device_pg1(starget, &pg1); -} - -static void mptspi_write_dt(struct scsi_target *starget, int dt) -{ - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - u32 nego; - - if (spi_period(starget) == -1) - mptspi_read_parameters(starget); - - if (!dt && spi_period(starget) < 10) - spi_period(starget) = 10; - - spi_dt(starget) = dt; - - nego = mptspi_getRP(starget); - - - pg1.RequestedParameters = cpu_to_le32(nego); - pg1.Reserved = 0; - pg1.Configuration = 0; - - mptspi_write_spi_device_pg1(starget, &pg1); -} - -static void mptspi_write_iu(struct scsi_target *starget, int iu) -{ - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - u32 nego; - - if (spi_period(starget) == -1) - mptspi_read_parameters(starget); - - if (!iu && spi_period(starget) < 9) - spi_period(starget) = 9; - - spi_iu(starget) = iu; - - nego = mptspi_getRP(starget); - - pg1.RequestedParameters = cpu_to_le32(nego); - pg1.Reserved = 0; - pg1.Configuration = 0; - - mptspi_write_spi_device_pg1(starget, &pg1); -} - -#define MPTSPI_SIMPLE_TRANSPORT_PARM(parm) \ -static void mptspi_write_##parm(struct scsi_target *starget, int parm)\ -{ \ - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; \ - u32 nego; \ - \ - spi_##parm(starget) = parm; \ - \ - nego = mptspi_getRP(starget); \ - \ - pg1.RequestedParameters = cpu_to_le32(nego); \ - pg1.Reserved = 0; \ - pg1.Configuration = 0; \ - \ - mptspi_write_spi_device_pg1(starget, &pg1); \ -} - -MPTSPI_SIMPLE_TRANSPORT_PARM(rd_strm) -MPTSPI_SIMPLE_TRANSPORT_PARM(wr_flow) -MPTSPI_SIMPLE_TRANSPORT_PARM(rti) -MPTSPI_SIMPLE_TRANSPORT_PARM(hold_mcs) -MPTSPI_SIMPLE_TRANSPORT_PARM(pcomp_en) - -static void mptspi_write_qas(struct scsi_target *starget, int qas) -{ - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; - VirtTarget *vtarget = starget->hostdata; - u32 nego; - - if ((vtarget->negoFlags & MPT_TARGET_NO_NEGO_QAS) || - hd->ioc->spi_data.noQas) - spi_qas(starget) = 0; - else - spi_qas(starget) = qas; - - nego = mptspi_getRP(starget); - - pg1.RequestedParameters = cpu_to_le32(nego); - pg1.Reserved = 0; - pg1.Configuration = 0; - - mptspi_write_spi_device_pg1(starget, &pg1); -} - -static void mptspi_write_width(struct scsi_target *starget, int width) -{ - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - u32 nego; - - if (!width) { - spi_dt(starget) = 0; - if (spi_period(starget) < 10) - spi_period(starget) = 10; - } - - spi_width(starget) = width; - - nego = mptspi_getRP(starget); - - pg1.RequestedParameters = cpu_to_le32(nego); - pg1.Reserved = 0; - pg1.Configuration = 0; - - mptspi_write_spi_device_pg1(starget, &pg1); -} - -struct work_queue_wrapper { - struct work_struct work; - struct _MPT_SCSI_HOST *hd; - int disk; -}; - -static void mpt_work_wrapper(void *data) -{ - struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; - struct _MPT_SCSI_HOST *hd = wqw->hd; - struct Scsi_Host *shost = hd->ioc->sh; - struct scsi_device *sdev; - int disk = wqw->disk; - struct _CONFIG_PAGE_IOC_3 *pg3; - - kfree(wqw); - - mpt_findImVolumes(hd->ioc); - pg3 = hd->ioc->raid_data.pIocPg3; - if (!pg3) - return; - - shost_for_each_device(sdev,shost) { - struct scsi_target *starget = scsi_target(sdev); - VirtTarget *vtarget = starget->hostdata; - - /* only want to search RAID components */ - if (sdev->channel != 1) - continue; - - /* The target_id is the raid PhysDiskNum, even if - * starget->id is the actual target address */ - if(vtarget->target_id != disk) - continue; - - starget_printk(KERN_INFO, vtarget->starget, - "Integrated RAID requests DV of new device\n"); - mptspi_dv_device(hd, sdev); - } - shost_printk(KERN_INFO, shost, - "Integrated RAID detects new device %d\n", disk); - scsi_scan_target(&hd->ioc->sh->shost_gendev, 1, disk, 0, 1); -} - - -static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk) -{ - struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); - - if (!wqw) { - shost_printk(KERN_ERR, hd->ioc->sh, - "Failed to act on RAID event for physical disk %d\n", - disk); - return; - } - INIT_WORK(&wqw->work, mpt_work_wrapper, wqw); - wqw->hd = hd; - wqw->disk = disk; - - schedule_work(&wqw->work); -} - -static int -mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) -{ - u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; - - if (hd && event == MPI_EVENT_INTEGRATED_RAID) { - int reason - = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16; - - if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { - int disk = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24; - mpt_dv_raid(hd, disk); - } - } - return mptscsih_event_process(ioc, pEvReply); -} - -static int -mptspi_deny_binding(struct scsi_target *starget) -{ - struct _MPT_SCSI_HOST *hd = - (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata; - return ((hd->ioc->raid_data.isRaid & (1 << starget->id)) && - starget->channel == 0) ? 1 : 0; -} - -static struct spi_function_template mptspi_transport_functions = { - .get_offset = mptspi_read_parameters, - .set_offset = mptspi_write_offset, - .show_offset = 1, - .get_period = mptspi_read_parameters, - .set_period = mptspi_write_period, - .show_period = 1, - .get_width = mptspi_read_parameters, - .set_width = mptspi_write_width, - .show_width = 1, - .get_iu = mptspi_read_parameters, - .set_iu = mptspi_write_iu, - .show_iu = 1, - .get_dt = mptspi_read_parameters, - .set_dt = mptspi_write_dt, - .show_dt = 1, - .get_qas = mptspi_read_parameters, - .set_qas = mptspi_write_qas, - .show_qas = 1, - .get_wr_flow = mptspi_read_parameters, - .set_wr_flow = mptspi_write_wr_flow, - .show_wr_flow = 1, - .get_rd_strm = mptspi_read_parameters, - .set_rd_strm = mptspi_write_rd_strm, - .show_rd_strm = 1, - .get_rti = mptspi_read_parameters, - .set_rti = mptspi_write_rti, - .show_rti = 1, - .get_pcomp_en = mptspi_read_parameters, - .set_pcomp_en = mptspi_write_pcomp_en, - .show_pcomp_en = 1, - .get_hold_mcs = mptspi_read_parameters, - .set_hold_mcs = mptspi_write_hold_mcs, - .show_hold_mcs = 1, - .deny_binding = mptspi_deny_binding, -}; /**************************************************************************** * Supported hardware @@ -783,72 +142,6 @@ static struct pci_device_id mptspi_pci_table[] = { }; MODULE_DEVICE_TABLE(pci, mptspi_pci_table); - -/* - * renegotiate for a given target - */ -static void -mptspi_dv_renegotiate_work(void *data) -{ - struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; - struct _MPT_SCSI_HOST *hd = wqw->hd; - struct scsi_device *sdev; - - kfree(wqw); - - shost_for_each_device(sdev, hd->ioc->sh) - mptspi_dv_device(hd, sdev); -} - -static void -mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd) -{ - struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); - - if (!wqw) - return; - - INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work, wqw); - wqw->hd = hd; - - schedule_work(&wqw->work); -} - -/* - * spi module reset handler - */ -static int -mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) -{ - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; - int rc; - - rc = mptscsih_ioc_reset(ioc, reset_phase); - - if (reset_phase == MPT_IOC_POST_RESET) - mptspi_dv_renegotiate(hd); - - return rc; -} - -#ifdef CONFIG_PM -/* - * spi module resume handler - */ -static int -mptspi_resume(struct pci_dev *pdev) -{ - MPT_ADAPTER *ioc = pci_get_drvdata(pdev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; - int rc; - - rc = mptscsih_resume(pdev); - mptspi_dv_renegotiate(hd); - - return rc; -} -#endif - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -949,14 +242,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) sh->max_id = MPT_MAX_SCSI_DEVICES; sh->max_lun = MPT_LAST_LUN + 1; - /* - * If RAID Firmware Detected, setup virtual channel - */ - if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) - > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) - sh->max_channel = 1; - else - sh->max_channel = 0; + sh->max_channel = 0; sh->this_id = ioc->pfacts[0].PortSCSIID; /* Required entry. @@ -1015,8 +301,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) * indicates a device exists. * max_id = 1 + maximum id (hosts.h) */ - hd->Targets = kcalloc(sh->max_id * (sh->max_channel + 1), - sizeof(void *), GFP_ATOMIC); + hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); if (!hd->Targets) { error = -ENOMEM; goto out_mptspi_probe; @@ -1049,23 +334,49 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ioc->spi_data.Saf_Te = mpt_saf_te; hd->mpt_pq_filter = mpt_pq_filter; +#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION + if (ioc->spi_data.maxBusWidth > mpt_width) + ioc->spi_data.maxBusWidth = mpt_width; + if (ioc->spi_data.minSyncFactor < mpt_factor) + ioc->spi_data.minSyncFactor = mpt_factor; + if (ioc->spi_data.minSyncFactor == MPT_ASYNC) { + ioc->spi_data.maxSyncOffset = 0; + } + ioc->spi_data.mpt_dv = mpt_dv; + hd->negoNvram = 0; + + ddvprintk((MYIOC_s_INFO_FMT + "dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n", + ioc->name, + mpt_dv, + mpt_width, + mpt_factor, + mpt_saf_te, + mpt_pq_filter)); +#else hd->negoNvram = MPT_SCSICFG_USE_NVRAM; ddvprintk((MYIOC_s_INFO_FMT "saf_te %x mpt_pq_filter %x\n", ioc->name, mpt_saf_te, mpt_pq_filter)); +#endif + + ioc->spi_data.forceDv = 0; ioc->spi_data.noQas = 0; + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) + ioc->spi_data.dvStatus[ii] = + MPT_SCSICFG_NEGOTIATE; + + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) + ioc->spi_data.dvStatus[ii] |= + MPT_SCSICFG_DV_NOT_DONE; + init_waitqueue_head(&hd->scandv_waitq); hd->scandv_wait_done = 0; hd->last_queue_full = 0; - /* Some versions of the firmware don't support page 0; without - * that we can't get the parameters */ - if (hd->ioc->spi_data.sdp0length != 0) - sh->transportt = mptspi_transport_template; - error = scsi_add_host (sh, &ioc->pcidev->dev); if(error) { dprintk((KERN_ERR MYNAM @@ -1098,7 +409,7 @@ static struct pci_driver mptspi_driver = { .shutdown = mptscsih_shutdown, #ifdef CONFIG_PM .suspend = mptscsih_suspend, - .resume = mptspi_resume, + .resume = mptscsih_resume, #endif }; @@ -1112,22 +423,19 @@ static struct pci_driver mptspi_driver = { static int __init mptspi_init(void) { - show_mptmod_ver(my_NAME, my_VERSION); - mptspi_transport_template = spi_attach_transport(&mptspi_transport_functions); - if (!mptspi_transport_template) - return -ENODEV; + show_mptmod_ver(my_NAME, my_VERSION); mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER); mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER); mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER); - if (mpt_event_register(mptspiDoneCtx, mptspi_event_process) == 0) { - devtverboseprintk((KERN_INFO MYNAM + if (mpt_event_register(mptspiDoneCtx, mptscsih_event_process) == 0) { + devtprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n")); } - if (mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset) == 0) { + if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) { dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n")); } @@ -1157,7 +465,6 @@ mptspi_exit(void) mpt_deregister(mptspiInternalCtx); mpt_deregister(mptspiTaskCtx); mpt_deregister(mptspiDoneCtx); - spi_release_transport(mptspi_transport_template); } module_init(mptspi_init); diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c index 5a6cca8e8..40d4ea898 100644 --- a/drivers/message/i2o/debug.c +++ b/drivers/message/i2o/debug.c @@ -419,53 +419,58 @@ void i2o_dump_hrt(struct i2o_controller *c) d = (u8 *) (rows + 2); state = p[1] << 8 | p[0]; - printk("TID %04X:[", state & 0xFFF); + printk(KERN_DEBUG "TID %04X:[", state & 0xFFF); state >>= 12; if (state & (1 << 0)) - printk("H"); /* Hidden */ + printk(KERN_DEBUG "H"); /* Hidden */ if (state & (1 << 2)) { - printk("P"); /* Present */ + printk(KERN_DEBUG "P"); /* Present */ if (state & (1 << 1)) - printk("C"); /* Controlled */ + printk(KERN_DEBUG "C"); /* Controlled */ } if (state > 9) - printk("*"); /* Hard */ + printk(KERN_DEBUG "*"); /* Hard */ - printk("]:"); + printk(KERN_DEBUG "]:"); switch (p[3] & 0xFFFF) { case 0: /* Adapter private bus - easy */ - printk("Local bus %d: I/O at 0x%04X Mem 0x%08X", p[2], + printk(KERN_DEBUG + "Local bus %d: I/O at 0x%04X Mem 0x%08X", p[2], d[1] << 8 | d[0], *(u32 *) (d + 4)); break; case 1: /* ISA bus */ - printk("ISA %d: CSN %d I/O at 0x%04X Mem 0x%08X", p[2], + printk(KERN_DEBUG + "ISA %d: CSN %d I/O at 0x%04X Mem 0x%08X", p[2], d[2], d[1] << 8 | d[0], *(u32 *) (d + 4)); break; case 2: /* EISA bus */ - printk("EISA %d: Slot %d I/O at 0x%04X Mem 0x%08X", + printk(KERN_DEBUG + "EISA %d: Slot %d I/O at 0x%04X Mem 0x%08X", p[2], d[3], d[1] << 8 | d[0], *(u32 *) (d + 4)); break; case 3: /* MCA bus */ - printk("MCA %d: Slot %d I/O at 0x%04X Mem 0x%08X", p[2], + printk(KERN_DEBUG + "MCA %d: Slot %d I/O at 0x%04X Mem 0x%08X", p[2], d[3], d[1] << 8 | d[0], *(u32 *) (d + 4)); break; case 4: /* PCI bus */ - printk("PCI %d: Bus %d Device %d Function %d", p[2], + printk(KERN_DEBUG + "PCI %d: Bus %d Device %d Function %d", p[2], d[2], d[1], d[0]); break; case 0x80: /* Other */ default: - printk("Unsupported bus type."); + printk(KERN_DEBUG "Unsupported bus type."); break; } - printk("\n"); + printk(KERN_DEBUG "\n"); rows += length; } } diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 7bd4d85d0..04e035744 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c @@ -58,13 +58,6 @@ struct i2o_exec_wait { spinlock_t lock; /* lock before modifying */ }; -/* Work struct needed to handle LCT NOTIFY replies */ -struct i2o_exec_lct_notify_work { - struct work_struct work; /* work struct */ - struct i2o_controller *c; /* controller on which the LCT NOTIFY - was received */ -}; - /* Exec OSM class handling definition */ static struct i2o_class_id i2o_exec_class_id[] = { {I2O_CLASS_EXECUTIVE}, @@ -360,12 +353,9 @@ static int i2o_exec_remove(struct device *dev) * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY * again, otherwise send LCT NOTIFY to get informed on next LCT change. */ -static void i2o_exec_lct_modified(struct i2o_exec_lct_notify_work *work) +static void i2o_exec_lct_modified(struct i2o_controller *c) { u32 change_ind = 0; - struct i2o_controller *c = work->c; - - kfree(work); if (i2o_device_parse_lct(c) != -EAGAIN) change_ind = c->lct->change_ind + 1; @@ -418,7 +408,7 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, return i2o_msg_post_wait_complete(c, m, msg, context); if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { - struct i2o_exec_lct_notify_work *work; + struct work_struct *work; pr_debug("%s: LCT notify received\n", c->name); @@ -426,11 +416,8 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, if (!work) return -ENOMEM; - work->c = c; - - INIT_WORK(&work->work, (void (*)(void *))i2o_exec_lct_modified, - work); - queue_work(i2o_exec_driver.event_queue, &work->work); + INIT_WORK(work, (void (*)(void *))i2o_exec_lct_modified, c); + queue_work(i2o_exec_driver.event_queue, work); return 1; } diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 7d4c54977..b09fb6307 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -1179,9 +1179,10 @@ static int __init i2o_block_init(void) goto exit; } - i2o_blk_req_pool.pool = - mempool_create_slab_pool(I2O_BLOCK_REQ_MEMPOOL_SIZE, - i2o_blk_req_pool.slab); + i2o_blk_req_pool.pool = mempool_create(I2O_BLOCK_REQ_MEMPOOL_SIZE, + mempool_alloc_slab, + mempool_free_slab, + i2o_blk_req_pool.slab); if (!i2o_blk_req_pool.pool) { osm_err("can't init request mempool\n"); rc = -ENOMEM; diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c index 3d2e76eea..2a0c42b8c 100644 --- a/drivers/message/i2o/i2o_proc.c +++ b/drivers/message/i2o/i2o_proc.c @@ -56,7 +56,7 @@ typedef struct _i2o_proc_entry_t { char *name; /* entry name */ mode_t mode; /* mode */ - const struct file_operations *fops; /* open function */ + struct file_operations *fops; /* open function */ } i2o_proc_entry; /* global I2O /proc/i2o entry */ diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index fc3c8854f..550f29744 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -3,7 +3,6 @@ # menu "Multimedia Capabilities Port drivers" - depends on ARCH_SA1100 config MCP tristate diff --git a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c index 7fd7a43e3..f295401fa 100644 --- a/drivers/misc/ibmasm/heartbeat.c +++ b/drivers/misc/ibmasm/heartbeat.c @@ -52,13 +52,12 @@ static struct notifier_block panic_notifier = { panic_happened, NULL, 1 }; void ibmasm_register_panic_notifier(void) { - atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier); + notifier_chain_register(&panic_notifier_list, &panic_notifier); } void ibmasm_unregister_panic_notifier(void) { - atomic_notifier_chain_unregister(&panic_notifier_list, - &panic_notifier); + notifier_chain_unregister(&panic_notifier_list, &panic_notifier); } diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index 26a230b6f..5c550fcac 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c @@ -101,7 +101,7 @@ static struct super_operations ibmasmfs_s_ops = { .drop_inode = generic_delete_inode, }; -static const struct file_operations *ibmasmfs_dir_ops = &simple_dir_operations; +static struct file_operations *ibmasmfs_dir_ops = &simple_dir_operations; static struct file_system_type ibmasmfs_type = { .owner = THIS_MODULE, diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 45bcf098e..5d397b7a5 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -49,28 +49,6 @@ config MMC_PXA If unsure, say N. -config MMC_SDHCI - tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" - depends on PCI && MMC && EXPERIMENTAL - help - This select the generic Secure Digital Host Controller Interface. - It is used by manufacturers such as Texas Instruments(R), Ricoh(R) - and Toshiba(R). Most controllers found in laptops are of this type. - If you have a controller with this interface, say Y or M here. - - If unsure, say N. - -config MMC_OMAP - tristate "TI OMAP Multimedia Card Interface support" - depends on ARCH_OMAP && MMC - select TPS65010 if MACH_OMAP_H2 - help - This selects the TI OMAP Multimedia card Interface. - If you have an OMAP board with a Multimedia Card slot, - say Y or M here. - - If unsure, say N. - config MMC_WBSD tristate "Winbond W83L51xD SD/MMC Card Interface support" depends on MMC && ISA_DMA_API @@ -84,29 +62,11 @@ config MMC_WBSD config MMC_AU1X tristate "Alchemy AU1XX0 MMC Card Interface support" - depends on MMC && SOC_AU1200 + depends on SOC_AU1X00 && MMC help This selects the AMD Alchemy(R) Multimedia card interface. If you have a Alchemy platform with a MMC slot, say Y or M here. If unsure, say N. -config MMC_AT91RM9200 - tristate "AT91RM9200 SD/MMC Card Interface support" - depends on ARCH_AT91RM9200 && MMC - help - This selects the AT91RM9200 MCI controller. - - If unsure, say N. - -config MMC_IMX - tristate "Motorola i.MX Multimedia Card Interface support" - depends on ARCH_IMX && MMC - help - This selects the Motorola i.MX Multimedia card Interface. - If you have a i.MX platform with a Multimedia Card slot, - say Y or M here. - - If unsure, say N. - endmenu diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index d2957e35c..e351e7114 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -17,15 +17,7 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o # obj-$(CONFIG_MMC_ARMMMCI) += mmci.o obj-$(CONFIG_MMC_PXA) += pxamci.o -obj-$(CONFIG_MMC_IMX) += imxmmc.o -obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o -obj-$(CONFIG_MMC_OMAP) += omap.o -obj-$(CONFIG_MMC_AT91RM9200) += at91_mci.o mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o - -ifeq ($(CONFIG_MMC_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c deleted file mode 100644 index 88f0eef9c..000000000 --- a/drivers/mmc/at91_mci.c +++ /dev/null @@ -1,985 +0,0 @@ -/* - * linux/drivers/mmc/at91_mci.c - ATMEL AT91RM9200 MCI Driver - * - * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved - * - * Copyright (C) 2006 Malcolm Noyes - * - * 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 is the AT91RM9200 MCI driver that has been tested with both MMC cards - and SD-cards. Boards that support write protect are now supported. - The CCAT91SBC001 board does not support SD cards. - - The three entry points are at91_mci_request, at91_mci_set_ios - and at91_mci_get_ro. - - SET IOS - This configures the device to put it into the correct mode and clock speed - required. - - MCI REQUEST - MCI request processes the commands sent in the mmc_request structure. This - can consist of a processing command and a stop command in the case of - multiple block transfers. - - There are three main types of request, commands, reads and writes. - - Commands are straight forward. The command is submitted to the controller and - the request function returns. When the controller generates an interrupt to indicate - the command is finished, the response to the command are read and the mmc_request_done - function called to end the request. - - Reads and writes work in a similar manner to normal commands but involve the PDC (DMA) - controller to manage the transfers. - - A read is done from the controller directly to the scatterlist passed in from the request. - Due to a bug in the controller, when a read is completed, all the words are byte - swapped in the scatterlist buffers. - - The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY - - A write is slightly different in that the bytes to write are read from the scatterlist - into a dma memory buffer (this is in case the source buffer should be read only). The - entire write buffer is then done from this single dma memory buffer. - - The sequence of write interrupts is: ENDTX, TXBUFE, NOTBUSY, CMDRDY - - GET RO - Gets the status of the write protect pin, if available. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "at91_mci" - -#undef SUPPORT_4WIRE - -#ifdef CONFIG_MMC_DEBUG -#define DBG(fmt...) \ - printk(fmt) -#else -#define DBG(fmt...) do { } while (0) -#endif - -static struct clk *mci_clk; - -#define FL_SENT_COMMAND (1 << 0) -#define FL_SENT_STOP (1 << 1) - - - -/* - * Read from a MCI register. - */ -static inline unsigned long at91_mci_read(unsigned int reg) -{ - void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI; - - return __raw_readl(mci_base + reg); -} - -/* - * Write to a MCI register. - */ -static inline void at91_mci_write(unsigned int reg, unsigned long value) -{ - void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI; - - __raw_writel(value, mci_base + reg); -} - -/* - * Low level type for this driver - */ -struct at91mci_host -{ - struct mmc_host *mmc; - struct mmc_command *cmd; - struct mmc_request *request; - - struct at91_mmc_data *board; - int present; - - /* - * Flag indicating when the command has been sent. This is used to - * work out whether or not to send the stop - */ - unsigned int flags; - /* flag for current bus settings */ - u32 bus_mode; - - /* DMA buffer used for transmitting */ - unsigned int* buffer; - dma_addr_t physical_address; - unsigned int total_length; - - /* Latest in the scatterlist that has been enabled for transfer, but not freed */ - int in_use_index; - - /* Latest in the scatterlist that has been enabled for transfer */ - int transfer_index; -}; - -/* - * Copy from sg to a dma block - used for transfers - */ -static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data) -{ - unsigned int len, i, size; - unsigned *dmabuf = host->buffer; - - size = host->total_length; - len = data->sg_len; - - /* - * Just loop through all entries. Size might not - * be the entire list though so make sure that - * we do not transfer too much. - */ - for (i = 0; i < len; i++) { - struct scatterlist *sg; - int amount; - int index; - unsigned int *sgbuffer; - - sg = &data->sg[i]; - - sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; - amount = min(size, sg->length); - size -= amount; - amount /= 4; - - for (index = 0; index < amount; index++) - *dmabuf++ = swab32(sgbuffer[index]); - - kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); - - if (size == 0) - break; - } - - /* - * Check that we didn't get a request to transfer - * more data than can fit into the SG list. - */ - BUG_ON(size != 0); -} - -/* - * Prepare a dma read - */ -static void at91mci_pre_dma_read(struct at91mci_host *host) -{ - int i; - struct scatterlist *sg; - struct mmc_command *cmd; - struct mmc_data *data; - - DBG("pre dma read\n"); - - cmd = host->cmd; - if (!cmd) { - DBG("no command\n"); - return; - } - - data = cmd->data; - if (!data) { - DBG("no data\n"); - return; - } - - for (i = 0; i < 2; i++) { - /* nothing left to transfer */ - if (host->transfer_index >= data->sg_len) { - DBG("Nothing left to transfer (index = %d)\n", host->transfer_index); - break; - } - - /* Check to see if this needs filling */ - if (i == 0) { - if (at91_mci_read(AT91_PDC_RCR) != 0) { - DBG("Transfer active in current\n"); - continue; - } - } - else { - if (at91_mci_read(AT91_PDC_RNCR) != 0) { - DBG("Transfer active in next\n"); - continue; - } - } - - /* Setup the next transfer */ - DBG("Using transfer index %d\n", host->transfer_index); - - sg = &data->sg[host->transfer_index++]; - DBG("sg = %p\n", sg); - - sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE); - - DBG("dma address = %08X, length = %d\n", sg->dma_address, sg->length); - - if (i == 0) { - at91_mci_write(AT91_PDC_RPR, sg->dma_address); - at91_mci_write(AT91_PDC_RCR, sg->length / 4); - } - else { - at91_mci_write(AT91_PDC_RNPR, sg->dma_address); - at91_mci_write(AT91_PDC_RNCR, sg->length / 4); - } - } - - DBG("pre dma read done\n"); -} - -/* - * Handle after a dma read - */ -static void at91mci_post_dma_read(struct at91mci_host *host) -{ - struct mmc_command *cmd; - struct mmc_data *data; - - DBG("post dma read\n"); - - cmd = host->cmd; - if (!cmd) { - DBG("no command\n"); - return; - } - - data = cmd->data; - if (!data) { - DBG("no data\n"); - return; - } - - while (host->in_use_index < host->transfer_index) { - unsigned int *buffer; - int index; - int len; - - struct scatterlist *sg; - - DBG("finishing index %d\n", host->in_use_index); - - sg = &data->sg[host->in_use_index++]; - - DBG("Unmapping page %08X\n", sg->dma_address); - - dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); - - /* Swap the contents of the buffer */ - buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; - DBG("buffer = %p, length = %d\n", buffer, sg->length); - - data->bytes_xfered += sg->length; - - len = sg->length / 4; - - for (index = 0; index < len; index++) { - buffer[index] = swab32(buffer[index]); - } - kunmap_atomic(buffer, KM_BIO_SRC_IRQ); - flush_dcache_page(sg->page); - } - - /* Is there another transfer to trigger? */ - if (host->transfer_index < data->sg_len) - at91mci_pre_dma_read(host); - else { - at91_mci_write(AT91_MCI_IER, AT91_MCI_RXBUFF); - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); - } - - DBG("post dma read done\n"); -} - -/* - * Handle transmitted data - */ -static void at91_mci_handle_transmitted(struct at91mci_host *host) -{ - struct mmc_command *cmd; - struct mmc_data *data; - - DBG("Handling the transmit\n"); - - /* Disable the transfer */ - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); - - /* Now wait for cmd ready */ - at91_mci_write(AT91_MCI_IDR, AT91_MCI_TXBUFE); - at91_mci_write(AT91_MCI_IER, AT91_MCI_NOTBUSY); - - cmd = host->cmd; - if (!cmd) return; - - data = cmd->data; - if (!data) return; - - data->bytes_xfered = host->total_length; -} - -/* - * Enable the controller - */ -static void at91_mci_enable(void) -{ - at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN); - at91_mci_write(AT91_MCI_IDR, 0xFFFFFFFF); - at91_mci_write(AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); - at91_mci_write(AT91_MCI_MR, 0x834A); - at91_mci_write(AT91_MCI_SDCR, 0x0); -} - -/* - * Disable the controller - */ -static void at91_mci_disable(void) -{ - at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); -} - -/* - * Send a command - * return the interrupts to enable - */ -static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd) -{ - unsigned int cmdr, mr; - unsigned int block_length; - struct mmc_data *data = cmd->data; - - unsigned int blocks; - unsigned int ier = 0; - - host->cmd = cmd; - - /* Not sure if this is needed */ -#if 0 - if ((at91_mci_read(AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) { - DBG("Clearing timeout\n"); - at91_mci_write(AT91_MCI_ARGR, 0); - at91_mci_write(AT91_MCI_CMDR, AT91_MCI_OPDCMD); - while (!(at91_mci_read(AT91_MCI_SR) & AT91_MCI_CMDRDY)) { - /* spin */ - DBG("Clearing: SR = %08X\n", at91_mci_read(AT91_MCI_SR)); - } - } -#endif - cmdr = cmd->opcode; - - if (mmc_resp_type(cmd) == MMC_RSP_NONE) - cmdr |= AT91_MCI_RSPTYP_NONE; - else { - /* if a response is expected then allow maximum response latancy */ - cmdr |= AT91_MCI_MAXLAT; - /* set 136 bit response for R2, 48 bit response otherwise */ - if (mmc_resp_type(cmd) == MMC_RSP_R2) - cmdr |= AT91_MCI_RSPTYP_136; - else - cmdr |= AT91_MCI_RSPTYP_48; - } - - if (data) { - block_length = 1 << data->blksz_bits; - blocks = data->blocks; - - /* always set data start - also set direction flag for read */ - if (data->flags & MMC_DATA_READ) - cmdr |= (AT91_MCI_TRDIR | AT91_MCI_TRCMD_START); - else if (data->flags & MMC_DATA_WRITE) - cmdr |= AT91_MCI_TRCMD_START; - - if (data->flags & MMC_DATA_STREAM) - cmdr |= AT91_MCI_TRTYP_STREAM; - if (data->flags & MMC_DATA_MULTI) - cmdr |= AT91_MCI_TRTYP_MULTIPLE; - } - else { - block_length = 0; - blocks = 0; - } - - if (cmd->opcode == MMC_STOP_TRANSMISSION) - cmdr |= AT91_MCI_TRCMD_STOP; - - if (host->bus_mode == MMC_BUSMODE_OPENDRAIN) - cmdr |= AT91_MCI_OPDCMD; - - /* - * Set the arguments and send the command - */ - DBG("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08lX)\n", - cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(AT91_MCI_MR)); - - if (!data) { - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS); - at91_mci_write(AT91_PDC_RPR, 0); - at91_mci_write(AT91_PDC_RCR, 0); - at91_mci_write(AT91_PDC_RNPR, 0); - at91_mci_write(AT91_PDC_RNCR, 0); - at91_mci_write(AT91_PDC_TPR, 0); - at91_mci_write(AT91_PDC_TCR, 0); - at91_mci_write(AT91_PDC_TNPR, 0); - at91_mci_write(AT91_PDC_TNCR, 0); - - at91_mci_write(AT91_MCI_ARGR, cmd->arg); - at91_mci_write(AT91_MCI_CMDR, cmdr); - return AT91_MCI_CMDRDY; - } - - mr = at91_mci_read(AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */ - at91_mci_write(AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); - - /* - * Disable the PDC controller - */ - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); - - if (cmdr & AT91_MCI_TRCMD_START) { - data->bytes_xfered = 0; - host->transfer_index = 0; - host->in_use_index = 0; - if (cmdr & AT91_MCI_TRDIR) { - /* - * Handle a read - */ - host->buffer = NULL; - host->total_length = 0; - - at91mci_pre_dma_read(host); - ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; - } - else { - /* - * Handle a write - */ - host->total_length = block_length * blocks; - host->buffer = dma_alloc_coherent(NULL, - host->total_length, - &host->physical_address, GFP_KERNEL); - - at91mci_sg_to_dma(host, data); - - DBG("Transmitting %d bytes\n", host->total_length); - - at91_mci_write(AT91_PDC_TPR, host->physical_address); - at91_mci_write(AT91_PDC_TCR, host->total_length / 4); - ier = AT91_MCI_TXBUFE; - } - } - - /* - * Send the command and then enable the PDC - not the other way round as - * the data sheet says - */ - - at91_mci_write(AT91_MCI_ARGR, cmd->arg); - at91_mci_write(AT91_MCI_CMDR, cmdr); - - if (cmdr & AT91_MCI_TRCMD_START) { - if (cmdr & AT91_MCI_TRDIR) - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTEN); - else - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTEN); - } - return ier; -} - -/* - * Wait for a command to complete - */ -static void at91mci_process_command(struct at91mci_host *host, struct mmc_command *cmd) -{ - unsigned int ier; - - ier = at91_mci_send_command(host, cmd); - - DBG("setting ier to %08X\n", ier); - - /* Stop on errors or the required value */ - at91_mci_write(AT91_MCI_IER, 0xffff0000 | ier); -} - -/* - * Process the next step in the request - */ -static void at91mci_process_next(struct at91mci_host *host) -{ - if (!(host->flags & FL_SENT_COMMAND)) { - host->flags |= FL_SENT_COMMAND; - at91mci_process_command(host, host->request->cmd); - } - else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) { - host->flags |= FL_SENT_STOP; - at91mci_process_command(host, host->request->stop); - } - else - mmc_request_done(host->mmc, host->request); -} - -/* - * Handle a command that has been completed - */ -static void at91mci_completed_command(struct at91mci_host *host) -{ - struct mmc_command *cmd = host->cmd; - unsigned int status; - - at91_mci_write(AT91_MCI_IDR, 0xffffffff); - - cmd->resp[0] = at91_mci_read(AT91_MCI_RSPR(0)); - cmd->resp[1] = at91_mci_read(AT91_MCI_RSPR(1)); - cmd->resp[2] = at91_mci_read(AT91_MCI_RSPR(2)); - cmd->resp[3] = at91_mci_read(AT91_MCI_RSPR(3)); - - if (host->buffer) { - dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address); - host->buffer = NULL; - } - - status = at91_mci_read(AT91_MCI_SR); - - DBG("Status = %08X [%08X %08X %08X %08X]\n", - status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); - - if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE | - AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE | - AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) { - if ((status & AT91_MCI_RCRCE) && - ((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) { - cmd->error = MMC_ERR_NONE; - } - else { - if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE)) - cmd->error = MMC_ERR_TIMEOUT; - else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE)) - cmd->error = MMC_ERR_BADCRC; - else if (status & (AT91_MCI_OVRE | AT91_MCI_UNRE)) - cmd->error = MMC_ERR_FIFO; - else - cmd->error = MMC_ERR_FAILED; - - DBG("Error detected and set to %d (cmd = %d, retries = %d)\n", - cmd->error, cmd->opcode, cmd->retries); - } - } - else - cmd->error = MMC_ERR_NONE; - - at91mci_process_next(host); -} - -/* - * Handle an MMC request - */ -static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) -{ - struct at91mci_host *host = mmc_priv(mmc); - host->request = mrq; - host->flags = 0; - - at91mci_process_next(host); -} - -/* - * Set the IOS - */ -static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - int clkdiv; - struct at91mci_host *host = mmc_priv(mmc); - unsigned long at91_master_clock = clk_get_rate(mci_clk); - - if (host) - host->bus_mode = ios->bus_mode; - else - printk("MMC: No host for bus_mode\n"); - - if (ios->clock == 0) { - /* Disable the MCI controller */ - at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS); - clkdiv = 0; - } - else { - /* Enable the MCI controller */ - at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN); - - if ((at91_master_clock % (ios->clock * 2)) == 0) - clkdiv = ((at91_master_clock / ios->clock) / 2) - 1; - else - clkdiv = (at91_master_clock / ios->clock) / 2; - - DBG("clkdiv = %d. mcck = %ld\n", clkdiv, - at91_master_clock / (2 * (clkdiv + 1))); - } - if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) { - DBG("MMC: Setting controller bus width to 4\n"); - at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) | AT91_MCI_SDCBUS); - } - else { - DBG("MMC: Setting controller bus width to 1\n"); - at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); - } - - /* Set the clock divider */ - at91_mci_write(AT91_MCI_MR, (at91_mci_read(AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); - - /* maybe switch power to the card */ - if (host && host->board->vcc_pin) { - switch (ios->power_mode) { - case MMC_POWER_OFF: - at91_set_gpio_output(host->board->vcc_pin, 0); - break; - case MMC_POWER_UP: - case MMC_POWER_ON: - at91_set_gpio_output(host->board->vcc_pin, 1); - break; - } - } -} - -/* - * Handle an interrupt - */ -static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs) -{ - struct at91mci_host *host = devid; - int completed = 0; - - unsigned int int_status; - - if (host == NULL) - return IRQ_HANDLED; - - int_status = at91_mci_read(AT91_MCI_SR); - DBG("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(AT91_MCI_IMR), - int_status & at91_mci_read(AT91_MCI_IMR)); - - if ((int_status & at91_mci_read(AT91_MCI_IMR)) & 0xffff0000) - completed = 1; - - int_status &= at91_mci_read(AT91_MCI_IMR); - - if (int_status & AT91_MCI_UNRE) - DBG("MMC: Underrun error\n"); - if (int_status & AT91_MCI_OVRE) - DBG("MMC: Overrun error\n"); - if (int_status & AT91_MCI_DTOE) - DBG("MMC: Data timeout\n"); - if (int_status & AT91_MCI_DCRCE) - DBG("MMC: CRC error in data\n"); - if (int_status & AT91_MCI_RTOE) - DBG("MMC: Response timeout\n"); - if (int_status & AT91_MCI_RENDE) - DBG("MMC: Response end bit error\n"); - if (int_status & AT91_MCI_RCRCE) - DBG("MMC: Response CRC error\n"); - if (int_status & AT91_MCI_RDIRE) - DBG("MMC: Response direction error\n"); - if (int_status & AT91_MCI_RINDE) - DBG("MMC: Response index error\n"); - - /* Only continue processing if no errors */ - if (!completed) { - if (int_status & AT91_MCI_TXBUFE) { - DBG("TX buffer empty\n"); - at91_mci_handle_transmitted(host); - } - - if (int_status & AT91_MCI_RXBUFF) { - DBG("RX buffer full\n"); - at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY); - } - - if (int_status & AT91_MCI_ENDTX) { - DBG("Transmit has ended\n"); - } - - if (int_status & AT91_MCI_ENDRX) { - DBG("Receive has ended\n"); - at91mci_post_dma_read(host); - } - - if (int_status & AT91_MCI_NOTBUSY) { - DBG("Card is ready\n"); - at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY); - } - - if (int_status & AT91_MCI_DTIP) { - DBG("Data transfer in progress\n"); - } - - if (int_status & AT91_MCI_BLKE) { - DBG("Block transfer has ended\n"); - } - - if (int_status & AT91_MCI_TXRDY) { - DBG("Ready to transmit\n"); - } - - if (int_status & AT91_MCI_RXRDY) { - DBG("Ready to receive\n"); - } - - if (int_status & AT91_MCI_CMDRDY) { - DBG("Command ready\n"); - completed = 1; - } - } - at91_mci_write(AT91_MCI_IDR, int_status); - - if (completed) { - DBG("Completed command\n"); - at91_mci_write(AT91_MCI_IDR, 0xffffffff); - at91mci_completed_command(host); - } - - return IRQ_HANDLED; -} - -static irqreturn_t at91_mmc_det_irq(int irq, void *_host, struct pt_regs *regs) -{ - struct at91mci_host *host = _host; - int present = !at91_get_gpio_value(irq); - - /* - * we expect this irq on both insert and remove, - * and use a short delay to debounce. - */ - if (present != host->present) { - host->present = present; - DBG("%s: card %s\n", mmc_hostname(host->mmc), - present ? "insert" : "remove"); - if (!present) { - DBG("****** Resetting SD-card bus width ******\n"); - at91_mci_write(AT91_MCI_SDCR, 0); - } - mmc_detect_change(host->mmc, msecs_to_jiffies(100)); - } - return IRQ_HANDLED; -} - -int at91_mci_get_ro(struct mmc_host *mmc) -{ - int read_only = 0; - struct at91mci_host *host = mmc_priv(mmc); - - if (host->board->wp_pin) { - read_only = at91_get_gpio_value(host->board->wp_pin); - printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc), - (read_only ? "read-only" : "read-write") ); - } - else { - printk(KERN_WARNING "%s: host does not support reading read-only " - "switch. Assuming write-enable.\n", mmc_hostname(mmc)); - } - return read_only; -} - -static struct mmc_host_ops at91_mci_ops = { - .request = at91_mci_request, - .set_ios = at91_mci_set_ios, - .get_ro = at91_mci_get_ro, -}; - -/* - * Probe for the device - */ -static int at91_mci_probe(struct platform_device *pdev) -{ - struct mmc_host *mmc; - struct at91mci_host *host; - int ret; - - DBG("Probe MCI devices\n"); - at91_mci_disable(); - at91_mci_enable(); - - mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); - if (!mmc) { - DBG("Failed to allocate mmc host\n"); - return -ENOMEM; - } - - mmc->ops = &at91_mci_ops; - mmc->f_min = 375000; - mmc->f_max = 25000000; - mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - - host = mmc_priv(mmc); - host->mmc = mmc; - host->buffer = NULL; - host->bus_mode = 0; - host->board = pdev->dev.platform_data; - if (host->board->wire4) { -#ifdef SUPPORT_4WIRE - mmc->caps |= MMC_CAP_4_BIT_DATA; -#else - printk("MMC: 4 wire bus mode not supported by this driver - using 1 wire\n"); -#endif - } - - /* - * Get Clock - */ - mci_clk = clk_get(&pdev->dev, "mci_clk"); - if (!mci_clk) { - printk(KERN_ERR "AT91 MMC: no clock defined.\n"); - return -ENODEV; - } - clk_enable(mci_clk); /* Enable the peripheral clock */ - - /* - * Allocate the MCI interrupt - */ - ret = request_irq(AT91_ID_MCI, at91_mci_irq, SA_SHIRQ, DRIVER_NAME, host); - if (ret) { - DBG("Failed to request MCI interrupt\n"); - return ret; - } - - platform_set_drvdata(pdev, mmc); - - /* - * Add host to MMC layer - */ - if (host->board->det_pin) - host->present = !at91_get_gpio_value(host->board->det_pin); - else - host->present = -1; - - mmc_add_host(mmc); - - /* - * monitor card insertion/removal if we can - */ - if (host->board->det_pin) { - ret = request_irq(host->board->det_pin, at91_mmc_det_irq, - SA_SAMPLE_RANDOM, DRIVER_NAME, host); - if (ret) - DBG("couldn't allocate MMC detect irq\n"); - } - - DBG(KERN_INFO "Added MCI driver\n"); - - return 0; -} - -/* - * Remove a device - */ -static int at91_mci_remove(struct platform_device *pdev) -{ - struct mmc_host *mmc = platform_get_drvdata(pdev); - struct at91mci_host *host; - - if (!mmc) - return -1; - - host = mmc_priv(mmc); - - if (host->present != -1) { - free_irq(host->board->det_pin, host); - cancel_delayed_work(&host->mmc->detect); - } - - mmc_remove_host(mmc); - at91_mci_disable(); - free_irq(AT91_ID_MCI, host); - mmc_free_host(mmc); - - clk_disable(mci_clk); /* Disable the peripheral clock */ - clk_put(mci_clk); - - platform_set_drvdata(pdev, NULL); - - DBG("Removed\n"); - - return 0; -} - -#ifdef CONFIG_PM -static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct mmc_host *mmc = platform_get_drvdata(pdev); - int ret = 0; - - if (mmc) - ret = mmc_suspend_host(mmc, state); - - return ret; -} - -static int at91_mci_resume(struct platform_device *pdev) -{ - struct mmc_host *mmc = platform_get_drvdata(pdev); - int ret = 0; - - if (mmc) - ret = mmc_resume_host(mmc); - - return ret; -} -#else -#define at91_mci_suspend NULL -#define at91_mci_resume NULL -#endif - -static struct platform_driver at91_mci_driver = { - .probe = at91_mci_probe, - .remove = at91_mci_remove, - .suspend = at91_mci_suspend, - .resume = at91_mci_resume, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init at91_mci_init(void) -{ - return platform_driver_register(&at91_mci_driver); -} - -static void __exit at91_mci_exit(void) -{ - platform_driver_unregister(&at91_mci_driver); -} - -module_init(at91_mci_init); -module_exit(at91_mci_exit); - -MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver"); -MODULE_AUTHOR("Nick Randell"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index 5dc4bee7a..8d84b045b 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c @@ -56,11 +56,12 @@ #define DRIVER_NAME "au1xxx-mmc" /* Set this to enable special debugging macros */ +/* #define MMC_DEBUG */ -#ifdef DEBUG -#define DBG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) +#ifdef MMC_DEBUG +#define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) #else -#define DBG(fmt, idx, args...) +#define DEBUG(fmt, idx, args...) #endif const struct { @@ -86,7 +87,7 @@ struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT]; static int dma = 1; #ifdef MODULE -module_param(dma, bool, 0); +MODULE_PARM(dma, "i"); MODULE_PARM_DESC(dma, "Use DMA engine for data transfers (0 = disabled)"); #endif @@ -310,7 +311,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) } else data->bytes_xfered = - (data->blocks * data->blksz) - + (data->blocks * (1 << data->blksz_bits)) - host->pio.len; } @@ -423,18 +424,18 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) break; if (status & SD_STATUS_RC) { - DBG("RX CRC Error [%d + %d].\n", host->id, + DEBUG("RX CRC Error [%d + %d].\n", host->id, host->pio.len, count); break; } if (status & SD_STATUS_RO) { - DBG("RX Overrun [%d + %d]\n", host->id, + DEBUG("RX Overrun [%d + %d]\n", host->id, host->pio.len, count); break; } else if (status & SD_STATUS_RU) { - DBG("RX Underrun [%d + %d]\n", host->id, + DEBUG("RX Underrun [%d + %d]\n", host->id, host->pio.len, count); break; } @@ -575,7 +576,7 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) { - int datalen = data->blocks * data->blksz; + int datalen = data->blocks * (1 << data->blksz_bits); if (dma != 0) host->flags |= HOST_F_DMA; @@ -596,7 +597,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) if (host->dma.len == 0) return MMC_ERR_TIMEOUT; - au_writel(data->blksz - 1, HOST_BLKSIZE(host)); + au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host)); if (host->flags & HOST_F_DMA) { int i; @@ -720,6 +721,10 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) { struct au1xmmc_host *host = mmc_priv(mmc); + DEBUG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", + host->id, ios->power_mode, ios->clock, ios->vdd, + ios->bus_mode); + if (ios->power_mode == MMC_POWER_OFF) au1xmmc_set_power(host, 0); else if (ios->power_mode == MMC_POWER_ON) { @@ -805,7 +810,7 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs) au1xmmc_receive_pio(host); } else if (status & 0x203FBC70) { - DBG("Unhandled status %8.8x\n", host->id, status); + DEBUG("Unhandled status %8.8x\n", host->id, status); handled = 0; } @@ -834,7 +839,7 @@ static void au1xmmc_poll_event(unsigned long arg) if (host->mrq != NULL) { u32 status = au_readl(HOST_STATUS(host)); - DBG("PENDING - %8.8x\n", host->id, status); + DEBUG("PENDING - %8.8x\n", host->id, status); } mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c deleted file mode 100644 index a4eb1d0e7..000000000 --- a/drivers/mmc/imxmmc.c +++ /dev/null @@ -1,1128 +0,0 @@ -/* - * linux/drivers/mmc/imxmmc.c - Motorola i.MX MMCI driver - * - * Copyright (C) 2004 Sascha Hauer, Pengutronix - * Copyright (C) 2006 Pavel Pisa, PiKRON - * - * derived from pxamci.c by 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. - * - * 2005-04-17 Pavel Pisa - * Changed to conform redesigned i.MX scatter gather DMA interface - * - * 2005-11-04 Pavel Pisa - * Updated for 2.6.14 kernel - * - * 2005-12-13 Jay Monkman - * Found and corrected problems in the write path - * - * 2005-12-30 Pavel Pisa - * The event handling rewritten right way in softirq. - * Added many ugly hacks and delays to overcome SDHC - * deficiencies - * - */ -#include - -#ifdef CONFIG_MMC_DEBUG -#define DEBUG -#else -#undef DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "imxmmc.h" - -#define DRIVER_NAME "imx-mmc" - -#define IMXMCI_INT_MASK_DEFAULT (INT_MASK_BUF_READY | INT_MASK_DATA_TRAN | \ - INT_MASK_WRITE_OP_DONE | INT_MASK_END_CMD_RES | \ - INT_MASK_AUTO_CARD_DETECT | INT_MASK_DAT0_EN | INT_MASK_SDIO) - -struct imxmci_host { - struct mmc_host *mmc; - spinlock_t lock; - struct resource *res; - int irq; - imx_dmach_t dma; - unsigned int clkrt; - unsigned int cmdat; - volatile unsigned int imask; - unsigned int power_mode; - unsigned int present; - struct imxmmc_platform_data *pdata; - - struct mmc_request *req; - struct mmc_command *cmd; - struct mmc_data *data; - - struct timer_list timer; - struct tasklet_struct tasklet; - unsigned int status_reg; - unsigned long pending_events; - /* Next to fields are there for CPU driven transfers to overcome SDHC deficiencies */ - u16 *data_ptr; - unsigned int data_cnt; - atomic_t stuck_timeout; - - unsigned int dma_nents; - unsigned int dma_size; - unsigned int dma_dir; - int dma_allocated; - - unsigned char actual_bus_width; -}; - -#define IMXMCI_PEND_IRQ_b 0 -#define IMXMCI_PEND_DMA_END_b 1 -#define IMXMCI_PEND_DMA_ERR_b 2 -#define IMXMCI_PEND_WAIT_RESP_b 3 -#define IMXMCI_PEND_DMA_DATA_b 4 -#define IMXMCI_PEND_CPU_DATA_b 5 -#define IMXMCI_PEND_CARD_XCHG_b 6 -#define IMXMCI_PEND_SET_INIT_b 7 -#define IMXMCI_PEND_STARTED_b 8 - -#define IMXMCI_PEND_IRQ_m (1 << IMXMCI_PEND_IRQ_b) -#define IMXMCI_PEND_DMA_END_m (1 << IMXMCI_PEND_DMA_END_b) -#define IMXMCI_PEND_DMA_ERR_m (1 << IMXMCI_PEND_DMA_ERR_b) -#define IMXMCI_PEND_WAIT_RESP_m (1 << IMXMCI_PEND_WAIT_RESP_b) -#define IMXMCI_PEND_DMA_DATA_m (1 << IMXMCI_PEND_DMA_DATA_b) -#define IMXMCI_PEND_CPU_DATA_m (1 << IMXMCI_PEND_CPU_DATA_b) -#define IMXMCI_PEND_CARD_XCHG_m (1 << IMXMCI_PEND_CARD_XCHG_b) -#define IMXMCI_PEND_SET_INIT_m (1 << IMXMCI_PEND_SET_INIT_b) -#define IMXMCI_PEND_STARTED_m (1 << IMXMCI_PEND_STARTED_b) - -static void imxmci_stop_clock(struct imxmci_host *host) -{ - int i = 0; - MMC_STR_STP_CLK &= ~STR_STP_CLK_START_CLK; - while(i < 0x1000) { - if(!(i & 0x7f)) - MMC_STR_STP_CLK |= STR_STP_CLK_STOP_CLK; - - if(!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) { - /* Check twice before cut */ - if(!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) - return; - } - - i++; - } - dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n"); -} - -static int imxmci_start_clock(struct imxmci_host *host) -{ - unsigned int trials = 0; - unsigned int delay_limit = 128; - unsigned long flags; - - MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK; - - clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); - - /* - * Command start of the clock, this usually succeeds in less - * then 6 delay loops, but during card detection (low clockrate) - * it takes up to 5000 delay loops and sometimes fails for the first time - */ - MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; - - do { - unsigned int delay = delay_limit; - - while(delay--){ - if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) - /* Check twice before cut */ - if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) - return 0; - - if(test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) - return 0; - } - - local_irq_save(flags); - /* - * Ensure, that request is not doubled under all possible circumstances. - * It is possible, that cock running state is missed, because some other - * IRQ or schedule delays this function execution and the clocks has - * been already stopped by other means (response processing, SDHC HW) - */ - if(!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) - MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; - local_irq_restore(flags); - - } while(++trials<256); - - dev_err(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n"); - - return -1; -} - -static void imxmci_softreset(void) -{ - /* reset sequence */ - MMC_STR_STP_CLK = 0x8; - MMC_STR_STP_CLK = 0xD; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - - MMC_RES_TO = 0xff; - MMC_BLK_LEN = 512; - MMC_NOB = 1; -} - -static int imxmci_busy_wait_for_status(struct imxmci_host *host, - unsigned int *pstat, unsigned int stat_mask, - int timeout, const char *where) -{ - int loops=0; - while(!(*pstat & stat_mask)) { - loops+=2; - if(loops >= timeout) { - dev_dbg(mmc_dev(host->mmc), "busy wait timeout in %s, STATUS = 0x%x (0x%x)\n", - where, *pstat, stat_mask); - return -1; - } - udelay(2); - *pstat |= MMC_STATUS; - } - if(!loops) - return 0; - - /* The busy-wait is expected there for clock <8MHz due to SDHC hardware flaws */ - if(!(stat_mask & STATUS_END_CMD_RESP) || (host->mmc->ios.clock>=8000000)) - dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n", - loops, where, *pstat, stat_mask); - return loops; -} - -static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) -{ - unsigned int nob = data->blocks; - unsigned int blksz = 1 << data->blksz_bits; - unsigned int datasz = nob * blksz; - int i; - - if (data->flags & MMC_DATA_STREAM) - nob = 0xffff; - - host->data = data; - data->bytes_xfered = 0; - - MMC_NOB = nob; - MMC_BLK_LEN = blksz; - - /* - * DMA cannot be used for small block sizes, we have to use CPU driven transfers otherwise. - * We are in big troubles for non-512 byte transfers according to note in the paragraph - * 20.6.7 of User Manual anyway, but we need to be able to transfer SCR at least. - * The situation is even more complex in reality. The SDHC in not able to handle wll - * partial FIFO fills and reads. The length has to be rounded up to burst size multiple. - * This is required for SCR read at least. - */ - if (datasz < 64) { - host->dma_size = datasz; - if (data->flags & MMC_DATA_READ) { - host->dma_dir = DMA_FROM_DEVICE; - - /* Hack to enable read SCR */ - if(datasz < 16) { - MMC_NOB = 1; - MMC_BLK_LEN = 16; - } - } else { - host->dma_dir = DMA_TO_DEVICE; - } - - /* Convert back to virtual address */ - host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset); - host->data_cnt = 0; - - clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events); - set_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events); - - return; - } - - if (data->flags & MMC_DATA_READ) { - host->dma_dir = DMA_FROM_DEVICE; - host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, - data->sg_len, host->dma_dir); - - imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, - host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_READ); - - /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_READ, IMX_DMA_WIDTH_16, CCR_REN);*/ - CCR(host->dma) = CCR_DMOD_LINEAR | CCR_DSIZ_32 | CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_REN; - } else { - host->dma_dir = DMA_TO_DEVICE; - - host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, - data->sg_len, host->dma_dir); - - imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, - host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_WRITE); - - /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_WRITE, IMX_DMA_WIDTH_16, CCR_REN);*/ - CCR(host->dma) = CCR_SMOD_LINEAR | CCR_SSIZ_32 | CCR_DMOD_FIFO | CCR_DSIZ_16 | CCR_REN; - } - -#if 1 /* This code is there only for consistency checking and can be disabled in future */ - host->dma_size = 0; - for(i=0; idma_nents; i++) - host->dma_size+=data->sg[i].length; - - if (datasz > host->dma_size) { - dev_err(mmc_dev(host->mmc), "imxmci_setup_data datasz 0x%x > 0x%x dm_size\n", - datasz, host->dma_size); - } -#endif - - host->dma_size = datasz; - - 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); - - /* start DMA engine for read, write is delayed after initial response */ - if (host->dma_dir == DMA_FROM_DEVICE) { - imx_dma_enable(host->dma); - } -} - -static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, unsigned int cmdat) -{ - unsigned long flags; - u32 imask; - - WARN_ON(host->cmd != NULL); - host->cmd = cmd; - - /* Ensure, that clock are stopped else command programming and start fails */ - imxmci_stop_clock(host); - - if (cmd->flags & MMC_RSP_BUSY) - cmdat |= CMD_DAT_CONT_BUSY; - - switch (mmc_resp_type(cmd)) { - case MMC_RSP_R1: /* short CRC, OPCODE */ - case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */ - cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R1; - break; - case MMC_RSP_R2: /* long 136 bit + CRC */ - cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R2; - break; - case MMC_RSP_R3: /* short */ - cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3; - break; - case MMC_RSP_R6: /* short CRC */ - cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R6; - break; - default: - break; - } - - if ( test_and_clear_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events) ) - cmdat |= CMD_DAT_CONT_INIT; /* This command needs init */ - - if ( host->actual_bus_width == MMC_BUS_WIDTH_4 ) - cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; - - MMC_CMD = cmd->opcode; - MMC_ARGH = cmd->arg >> 16; - MMC_ARGL = cmd->arg & 0xffff; - MMC_CMD_DAT_CONT = cmdat; - - atomic_set(&host->stuck_timeout, 0); - set_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events); - - - imask = IMXMCI_INT_MASK_DEFAULT; - imask &= ~INT_MASK_END_CMD_RES; - if ( cmdat & CMD_DAT_CONT_DATA_ENABLE ) { - /*imask &= ~INT_MASK_BUF_READY;*/ - imask &= ~INT_MASK_DATA_TRAN; - if ( cmdat & CMD_DAT_CONT_WRITE ) - imask &= ~INT_MASK_WRITE_OP_DONE; - if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) - imask &= ~INT_MASK_BUF_READY; - } - - spin_lock_irqsave(&host->lock, flags); - host->imask = imask; - MMC_INT_MASK = host->imask; - spin_unlock_irqrestore(&host->lock, flags); - - dev_dbg(mmc_dev(host->mmc), "CMD%02d (0x%02x) mask set to 0x%04x\n", - cmd->opcode, cmd->opcode, imask); - - imxmci_start_clock(host); -} - -static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - - host->pending_events &= ~(IMXMCI_PEND_WAIT_RESP_m | IMXMCI_PEND_DMA_END_m | - IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m); - - host->imask = IMXMCI_INT_MASK_DEFAULT; - MMC_INT_MASK = host->imask; - - spin_unlock_irqrestore(&host->lock, flags); - - host->req = NULL; - host->cmd = NULL; - host->data = NULL; - mmc_request_done(host->mmc, req); -} - -static int imxmci_finish_data(struct imxmci_host *host, unsigned int stat) -{ - struct mmc_data *data = host->data; - int data_error; - - if(test_and_clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)){ - imx_dma_disable(host->dma); - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents, - host->dma_dir); - } - - if ( stat & STATUS_ERR_MASK ) { - dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",stat); - if(stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR)) - data->error = MMC_ERR_BADCRC; - else if(stat & STATUS_TIME_OUT_READ) - data->error = MMC_ERR_TIMEOUT; - else - data->error = MMC_ERR_FAILED; - } else { - data->bytes_xfered = host->dma_size; - } - - data_error = data->error; - - host->data = NULL; - - return data_error; -} - -static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) -{ - struct mmc_command *cmd = host->cmd; - int i; - u32 a,b,c; - struct mmc_data *data = host->data; - - if (!cmd) - return 0; - - host->cmd = NULL; - - if (stat & STATUS_TIME_OUT_RESP) { - dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n"); - cmd->error = MMC_ERR_TIMEOUT; - } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) { - dev_dbg(mmc_dev(host->mmc), "cmd crc error\n"); - cmd->error = MMC_ERR_BADCRC; - } - - if(cmd->flags & MMC_RSP_PRESENT) { - if(cmd->flags & MMC_RSP_136) { - for (i = 0; i < 4; i++) { - u32 a = MMC_RES_FIFO & 0xffff; - u32 b = MMC_RES_FIFO & 0xffff; - cmd->resp[i] = a<<16 | b; - } - } else { - a = MMC_RES_FIFO & 0xffff; - b = MMC_RES_FIFO & 0xffff; - c = MMC_RES_FIFO & 0xffff; - cmd->resp[0] = a<<24 | b<<8 | c>>8; - } - } - - dev_dbg(mmc_dev(host->mmc), "RESP 0x%08x, 0x%08x, 0x%08x, 0x%08x, error %d\n", - cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], cmd->error); - - if (data && (cmd->error == MMC_ERR_NONE) && !(stat & STATUS_ERR_MASK)) { - if (host->req->data->flags & MMC_DATA_WRITE) { - - /* Wait for FIFO to be empty before starting DMA write */ - - stat = MMC_STATUS; - if(imxmci_busy_wait_for_status(host, &stat, - STATUS_APPL_BUFF_FE, - 40, "imxmci_cmd_done DMA WR") < 0) { - cmd->error = MMC_ERR_FIFO; - imxmci_finish_data(host, stat); - if(host->req) - imxmci_finish_request(host, host->req); - dev_warn(mmc_dev(host->mmc), "STATUS = 0x%04x\n", - stat); - return 0; - } - - if(test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) { - imx_dma_enable(host->dma); - } - } - } else { - struct mmc_request *req; - imxmci_stop_clock(host); - req = host->req; - - if(data) - imxmci_finish_data(host, stat); - - if( req ) { - imxmci_finish_request(host, req); - } else { - dev_warn(mmc_dev(host->mmc), "imxmci_cmd_done: no request to finish\n"); - } - } - - return 1; -} - -static int imxmci_data_done(struct imxmci_host *host, unsigned int stat) -{ - struct mmc_data *data = host->data; - int data_error; - - if (!data) - return 0; - - data_error = imxmci_finish_data(host, stat); - - if (host->req->stop) { - imxmci_stop_clock(host); - imxmci_start_cmd(host, host->req->stop, 0); - } else { - struct mmc_request *req; - req = host->req; - if( req ) { - imxmci_finish_request(host, req); - } else { - dev_warn(mmc_dev(host->mmc), "imxmci_data_done: no request to finish\n"); - } - } - - return 1; -} - -static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) -{ - int i; - int burst_len; - int flush_len; - int trans_done = 0; - unsigned int stat = *pstat; - - if(host->actual_bus_width != MMC_BUS_WIDTH_4) - burst_len = 16; - else - burst_len = 64; - - /* This is unfortunately required */ - dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data running STATUS = 0x%x\n", - stat); - - if(host->dma_dir == DMA_FROM_DEVICE) { - imxmci_busy_wait_for_status(host, &stat, - STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE, - 20, "imxmci_cpu_driven_data read"); - - while((stat & (STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE)) && - (host->data_cnt < host->dma_size)) { - if(burst_len >= host->dma_size - host->data_cnt) { - flush_len = burst_len; - burst_len = host->dma_size - host->data_cnt; - flush_len -= burst_len; - host->data_cnt = host->dma_size; - trans_done = 1; - } else { - flush_len = 0; - host->data_cnt += burst_len; - } - - for(i = burst_len; i>=2 ; i-=2) { - *(host->data_ptr++) = MMC_BUFFER_ACCESS; - udelay(20); /* required for clocks < 8MHz*/ - } - - if(i == 1) - *(u8*)(host->data_ptr) = MMC_BUFFER_ACCESS; - - stat = MMC_STATUS; - - /* Flush extra bytes from FIFO */ - while(flush_len && !(stat & STATUS_DATA_TRANS_DONE)){ - i = MMC_BUFFER_ACCESS; - stat = MMC_STATUS; - stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */ - } - - dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read burst %d STATUS = 0x%x\n", - burst_len, stat); - } - } else { - imxmci_busy_wait_for_status(host, &stat, - STATUS_APPL_BUFF_FE, - 20, "imxmci_cpu_driven_data write"); - - while((stat & STATUS_APPL_BUFF_FE) && - (host->data_cnt < host->dma_size)) { - if(burst_len >= host->dma_size - host->data_cnt) { - burst_len = host->dma_size - host->data_cnt; - host->data_cnt = host->dma_size; - trans_done = 1; - } else { - host->data_cnt += burst_len; - } - - for(i = burst_len; i>0 ; i-=2) - MMC_BUFFER_ACCESS = *(host->data_ptr++); - - stat = MMC_STATUS; - - dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data write burst %d STATUS = 0x%x\n", - burst_len, stat); - } - } - - *pstat = stat; - - return trans_done; -} - -static void imxmci_dma_irq(int dma, void *devid, struct pt_regs *regs) -{ - struct imxmci_host *host = devid; - uint32_t stat = MMC_STATUS; - - atomic_set(&host->stuck_timeout, 0); - host->status_reg = stat; - set_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); - tasklet_schedule(&host->tasklet); -} - -static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs) -{ - struct imxmci_host *host = devid; - uint32_t stat = MMC_STATUS; - int handled = 1; - - MMC_INT_MASK = host->imask | INT_MASK_SDIO | INT_MASK_AUTO_CARD_DETECT; - - atomic_set(&host->stuck_timeout, 0); - host->status_reg = stat; - set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); - set_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); - tasklet_schedule(&host->tasklet); - - return IRQ_RETVAL(handled);; -} - -static void imxmci_tasklet_fnc(unsigned long data) -{ - struct imxmci_host *host = (struct imxmci_host *)data; - u32 stat; - unsigned int data_dir_mask = 0; /* STATUS_WR_CRC_ERROR_CODE_MASK */ - int timeout = 0; - - if(atomic_read(&host->stuck_timeout) > 4) { - char *what; - timeout = 1; - stat = MMC_STATUS; - host->status_reg = stat; - if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) - if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) - what = "RESP+DMA"; - else - what = "RESP"; - else - if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) - if(test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events)) - what = "DATA"; - else - what = "DMA"; - else - what = "???"; - - dev_err(mmc_dev(host->mmc), "%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n", - what, stat, MMC_INT_MASK); - dev_err(mmc_dev(host->mmc), "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n", - MMC_CMD_DAT_CONT, MMC_BLK_LEN, MMC_NOB, CCR(host->dma)); - dev_err(mmc_dev(host->mmc), "CMD%d, bus %d-bit, dma_size = 0x%x\n", - host->cmd?host->cmd->opcode:0, 1<actual_bus_width, host->dma_size); - } - - if(!host->present || timeout) - host->status_reg = STATUS_TIME_OUT_RESP | STATUS_TIME_OUT_READ | - STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR; - - if(test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) { - clear_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); - - stat = MMC_STATUS; - /* - * This is not required in theory, but there is chance to miss some flag - * which clears automatically by mask write, FreeScale original code keeps - * stat from IRQ time so do I - */ - stat |= host->status_reg; - - if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { - imxmci_busy_wait_for_status(host, &stat, - STATUS_END_CMD_RESP | STATUS_ERR_MASK, - 20, "imxmci_tasklet_fnc resp (ERRATUM #4)"); - } - - if(stat & (STATUS_END_CMD_RESP | STATUS_ERR_MASK)) { - if(test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) - imxmci_cmd_done(host, stat); - if(host->data && (stat & STATUS_ERR_MASK)) - imxmci_data_done(host, stat); - } - - if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) { - stat |= MMC_STATUS; - if(imxmci_cpu_driven_data(host, &stat)){ - if(test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) - imxmci_cmd_done(host, stat); - atomic_clear_mask(IMXMCI_PEND_IRQ_m|IMXMCI_PEND_CPU_DATA_m, - &host->pending_events); - imxmci_data_done(host, stat); - } - } - } - - if(test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) && - !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { - - stat = MMC_STATUS; - /* Same as above */ - stat |= host->status_reg; - - if(host->dma_dir == DMA_TO_DEVICE) { - data_dir_mask = STATUS_WRITE_OP_DONE; - } else { - data_dir_mask = STATUS_DATA_TRANS_DONE; - } - - if(stat & data_dir_mask) { - clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); - imxmci_data_done(host, stat); - } - } - - if(test_and_clear_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events)) { - - if(host->cmd) - imxmci_cmd_done(host, STATUS_TIME_OUT_RESP); - - if(host->data) - imxmci_data_done(host, STATUS_TIME_OUT_READ | - STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR); - - if(host->req) - imxmci_finish_request(host, host->req); - - mmc_detect_change(host->mmc, msecs_to_jiffies(100)); - - } -} - -static void imxmci_request(struct mmc_host *mmc, struct mmc_request *req) -{ - struct imxmci_host *host = mmc_priv(mmc); - unsigned int cmdat; - - WARN_ON(host->req != NULL); - - host->req = req; - - cmdat = 0; - - if (req->data) { - imxmci_setup_data(host, req->data); - - cmdat |= CMD_DAT_CONT_DATA_ENABLE; - - if (req->data->flags & MMC_DATA_WRITE) - cmdat |= CMD_DAT_CONT_WRITE; - - if (req->data->flags & MMC_DATA_STREAM) { - cmdat |= CMD_DAT_CONT_STREAM_BLOCK; - } - } - - imxmci_start_cmd(host, req->cmd, cmdat); -} - -#define CLK_RATE 19200000 - -static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct imxmci_host *host = mmc_priv(mmc); - int prescaler; - - if( ios->bus_width==MMC_BUS_WIDTH_4 ) { - host->actual_bus_width = MMC_BUS_WIDTH_4; - imx_gpio_mode(PB11_PF_SD_DAT3); - }else{ - host->actual_bus_width = MMC_BUS_WIDTH_1; - imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11); - } - - if ( host->power_mode != ios->power_mode ) { - switch (ios->power_mode) { - case MMC_POWER_OFF: - break; - case MMC_POWER_UP: - set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events); - break; - case MMC_POWER_ON: - break; - } - host->power_mode = ios->power_mode; - } - - if ( ios->clock ) { - unsigned int clk; - - /* The prescaler is 5 for PERCLK2 equal to 96MHz - * then 96MHz / 5 = 19.2 MHz - */ - clk=imx_get_perclk2(); - prescaler=(clk+(CLK_RATE*7)/8)/CLK_RATE; - switch(prescaler) { - case 0: - case 1: prescaler = 0; - break; - case 2: prescaler = 1; - break; - case 3: prescaler = 2; - break; - case 4: prescaler = 4; - break; - default: - case 5: prescaler = 5; - break; - } - - dev_dbg(mmc_dev(host->mmc), "PERCLK2 %d MHz -> prescaler %d\n", - clk, prescaler); - - for(clk=0; clk<8; clk++) { - int x; - x = CLK_RATE / (1<clock) - break; - } - - MMC_STR_STP_CLK |= STR_STP_CLK_ENABLE; /* enable controller */ - - imxmci_stop_clock(host); - MMC_CLK_RATE = (prescaler<<3) | clk; - /* - * Under my understanding, clock should not be started there, because it would - * initiate SDHC sequencer and send last or random command into card - */ - /*imxmci_start_clock(host);*/ - - dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE); - } else { - imxmci_stop_clock(host); - } -} - -static struct mmc_host_ops imxmci_ops = { - .request = imxmci_request, - .set_ios = imxmci_set_ios, -}; - -static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr) -{ - int i; - - for (i = 0; i < dev->num_resources; i++) - if (dev->resource[i].flags == mask && nr-- == 0) - return &dev->resource[i]; - return NULL; -} - -static int platform_device_irq(struct platform_device *dev, int nr) -{ - int i; - - for (i = 0; i < dev->num_resources; i++) - if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0) - return dev->resource[i].start; - return NO_IRQ; -} - -static void imxmci_check_status(unsigned long data) -{ - struct imxmci_host *host = (struct imxmci_host *)data; - - if( host->pdata->card_present() != host->present ) { - host->present ^= 1; - dev_info(mmc_dev(host->mmc), "card %s\n", - host->present ? "inserted" : "removed"); - - set_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events); - tasklet_schedule(&host->tasklet); - } - - if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events) || - test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) { - atomic_inc(&host->stuck_timeout); - if(atomic_read(&host->stuck_timeout) > 4) - tasklet_schedule(&host->tasklet); - } else { - atomic_set(&host->stuck_timeout, 0); - - } - - mod_timer(&host->timer, jiffies + (HZ>>1)); -} - -static int imxmci_probe(struct platform_device *pdev) -{ - struct mmc_host *mmc; - struct imxmci_host *host = NULL; - struct resource *r; - int ret = 0, irq; - - printk(KERN_INFO "i.MX mmc driver\n"); - - r = platform_device_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_device_irq(pdev, 0); - if (!r || irq == NO_IRQ) - return -ENXIO; - - r = request_mem_region(r->start, 0x100, "IMXMCI"); - if (!r) - return -EBUSY; - - mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev); - if (!mmc) { - ret = -ENOMEM; - goto out; - } - - mmc->ops = &imxmci_ops; - mmc->f_min = 150000; - mmc->f_max = CLK_RATE/2; - mmc->ocr_avail = MMC_VDD_32_33; - mmc->caps |= MMC_CAP_4_BIT_DATA; - - /* MMC core transfer sizes tunable parameters */ - mmc->max_hw_segs = 64; - mmc->max_phys_segs = 64; - mmc->max_sectors = 64; /* default 1 << (PAGE_CACHE_SHIFT - 9) */ - mmc->max_seg_size = 64*512; /* default PAGE_CACHE_SIZE */ - - host = mmc_priv(mmc); - host->mmc = mmc; - host->dma_allocated = 0; - host->pdata = pdev->dev.platform_data; - - spin_lock_init(&host->lock); - host->res = r; - host->irq = irq; - - imx_gpio_mode(PB8_PF_SD_DAT0); - imx_gpio_mode(PB9_PF_SD_DAT1); - imx_gpio_mode(PB10_PF_SD_DAT2); - /* Configured as GPIO with pull-up to ensure right MCC card mode */ - /* Switched to PB11_PF_SD_DAT3 if 4 bit bus is configured */ - imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11); - /* imx_gpio_mode(PB11_PF_SD_DAT3); */ - imx_gpio_mode(PB12_PF_SD_CLK); - imx_gpio_mode(PB13_PF_SD_CMD); - - imxmci_softreset(); - - if ( MMC_REV_NO != 0x390 ) { - dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n", - MMC_REV_NO); - goto out; - } - - MMC_READ_TO = 0x2db4; /* recommended in data sheet */ - - host->imask = IMXMCI_INT_MASK_DEFAULT; - MMC_INT_MASK = host->imask; - - - if(imx_dma_request_by_prio(&host->dma, DRIVER_NAME, DMA_PRIO_LOW)<0){ - dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n"); - ret = -EBUSY; - goto out; - } - host->dma_allocated=1; - imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host); - - tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host); - host->status_reg=0; - host->pending_events=0; - - ret = request_irq(host->irq, imxmci_irq, 0, DRIVER_NAME, host); - if (ret) - goto out; - - host->present = host->pdata->card_present(); - init_timer(&host->timer); - host->timer.data = (unsigned long)host; - host->timer.function = imxmci_check_status; - add_timer(&host->timer); - mod_timer(&host->timer, jiffies + (HZ>>1)); - - platform_set_drvdata(pdev, mmc); - - mmc_add_host(mmc); - - return 0; - -out: - if (host) { - if(host->dma_allocated){ - imx_dma_free(host->dma); - host->dma_allocated=0; - } - } - if (mmc) - mmc_free_host(mmc); - release_resource(r); - return ret; -} - -static int imxmci_remove(struct platform_device *pdev) -{ - struct mmc_host *mmc = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - - if (mmc) { - struct imxmci_host *host = mmc_priv(mmc); - - tasklet_disable(&host->tasklet); - - del_timer_sync(&host->timer); - mmc_remove_host(mmc); - - free_irq(host->irq, host); - if(host->dma_allocated){ - imx_dma_free(host->dma); - host->dma_allocated=0; - } - - tasklet_kill(&host->tasklet); - - release_resource(host->res); - - mmc_free_host(mmc); - } - return 0; -} - -#ifdef CONFIG_PM -static int imxmci_suspend(struct platform_device *dev, pm_message_t state) -{ - struct mmc_host *mmc = platform_get_drvdata(dev); - int ret = 0; - - if (mmc) - ret = mmc_suspend_host(mmc, state); - - return ret; -} - -static int imxmci_resume(struct platform_device *dev) -{ - struct mmc_host *mmc = platform_get_drvdata(dev); - struct imxmci_host *host; - int ret = 0; - - if (mmc) { - host = mmc_priv(mmc); - if(host) - set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events); - ret = mmc_resume_host(mmc); - } - - return ret; -} -#else -#define imxmci_suspend NULL -#define imxmci_resume NULL -#endif /* CONFIG_PM */ - -static struct platform_driver imxmci_driver = { - .probe = imxmci_probe, - .remove = imxmci_remove, - .suspend = imxmci_suspend, - .resume = imxmci_resume, - .driver = { - .name = DRIVER_NAME, - } -}; - -static int __init imxmci_init(void) -{ - return platform_driver_register(&imxmci_driver); -} - -static void __exit imxmci_exit(void) -{ - platform_driver_unregister(&imxmci_driver); -} - -module_init(imxmci_init); -module_exit(imxmci_exit); - -MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); -MODULE_AUTHOR("Sascha Hauer, Pengutronix"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/imxmmc.h b/drivers/mmc/imxmmc.h deleted file mode 100644 index e5339e334..000000000 --- a/drivers/mmc/imxmmc.h +++ /dev/null @@ -1,67 +0,0 @@ - -# define __REG16(x) (*((volatile u16 *)IO_ADDRESS(x))) - -#define MMC_STR_STP_CLK __REG16(IMX_MMC_BASE + 0x00) -#define MMC_STATUS __REG16(IMX_MMC_BASE + 0x04) -#define MMC_CLK_RATE __REG16(IMX_MMC_BASE + 0x08) -#define MMC_CMD_DAT_CONT __REG16(IMX_MMC_BASE + 0x0C) -#define MMC_RES_TO __REG16(IMX_MMC_BASE + 0x10) -#define MMC_READ_TO __REG16(IMX_MMC_BASE + 0x14) -#define MMC_BLK_LEN __REG16(IMX_MMC_BASE + 0x18) -#define MMC_NOB __REG16(IMX_MMC_BASE + 0x1C) -#define MMC_REV_NO __REG16(IMX_MMC_BASE + 0x20) -#define MMC_INT_MASK __REG16(IMX_MMC_BASE + 0x24) -#define MMC_CMD __REG16(IMX_MMC_BASE + 0x28) -#define MMC_ARGH __REG16(IMX_MMC_BASE + 0x2C) -#define MMC_ARGL __REG16(IMX_MMC_BASE + 0x30) -#define MMC_RES_FIFO __REG16(IMX_MMC_BASE + 0x34) -#define MMC_BUFFER_ACCESS __REG16(IMX_MMC_BASE + 0x38) -#define MMC_BUFFER_ACCESS_OFS 0x38 - - -#define STR_STP_CLK_ENDIAN (1<<5) -#define STR_STP_CLK_RESET (1<<3) -#define STR_STP_CLK_ENABLE (1<<2) -#define STR_STP_CLK_START_CLK (1<<1) -#define STR_STP_CLK_STOP_CLK (1<<0) -#define STATUS_CARD_PRESENCE (1<<15) -#define STATUS_SDIO_INT_ACTIVE (1<<14) -#define STATUS_END_CMD_RESP (1<<13) -#define STATUS_WRITE_OP_DONE (1<<12) -#define STATUS_DATA_TRANS_DONE (1<<11) -#define STATUS_WR_CRC_ERROR_CODE_MASK (3<<10) -#define STATUS_CARD_BUS_CLK_RUN (1<<8) -#define STATUS_APPL_BUFF_FF (1<<7) -#define STATUS_APPL_BUFF_FE (1<<6) -#define STATUS_RESP_CRC_ERR (1<<5) -#define STATUS_CRC_READ_ERR (1<<3) -#define STATUS_CRC_WRITE_ERR (1<<2) -#define STATUS_TIME_OUT_RESP (1<<1) -#define STATUS_TIME_OUT_READ (1<<0) -#define STATUS_ERR_MASK 0x2f -#define CLK_RATE_PRESCALER(x) ((x) & 0x7) -#define CLK_RATE_CLK_RATE(x) (((x) & 0x7) << 3) -#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1<<12) -#define CMD_DAT_CONT_STOP_READWAIT (1<<11) -#define CMD_DAT_CONT_START_READWAIT (1<<10) -#define CMD_DAT_CONT_BUS_WIDTH_1 (0<<8) -#define CMD_DAT_CONT_BUS_WIDTH_4 (2<<8) -#define CMD_DAT_CONT_INIT (1<<7) -#define CMD_DAT_CONT_BUSY (1<<6) -#define CMD_DAT_CONT_STREAM_BLOCK (1<<5) -#define CMD_DAT_CONT_WRITE (1<<4) -#define CMD_DAT_CONT_DATA_ENABLE (1<<3) -#define CMD_DAT_CONT_RESPONSE_FORMAT_R1 (1) -#define CMD_DAT_CONT_RESPONSE_FORMAT_R2 (2) -#define CMD_DAT_CONT_RESPONSE_FORMAT_R3 (3) -#define CMD_DAT_CONT_RESPONSE_FORMAT_R4 (4) -#define CMD_DAT_CONT_RESPONSE_FORMAT_R5 (5) -#define CMD_DAT_CONT_RESPONSE_FORMAT_R6 (6) -#define INT_MASK_AUTO_CARD_DETECT (1<<6) -#define INT_MASK_DAT0_EN (1<<5) -#define INT_MASK_SDIO (1<<4) -#define INT_MASK_BUF_READY (1<<3) -#define INT_MASK_END_CMD_RES (1<<2) -#define INT_MASK_WRITE_OP_DONE (1<<1) -#define INT_MASK_DATA_TRAN (1<<0) -#define INT_ALL (0x7f) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6201f3086..1888060c5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -27,6 +27,12 @@ #include "mmc.h" +#ifdef CONFIG_MMC_DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) do { } while (0) +#endif + #define CMD_RETRIES 3 /* @@ -59,23 +65,20 @@ static const unsigned int tacc_mant[] = { /** - * mmc_request_done - finish processing an MMC request - * @host: MMC host which completed request - * @mrq: MMC request which request + * mmc_request_done - finish processing an MMC command + * @host: MMC host which completed command + * @mrq: MMC request which completed * * MMC drivers should call this function when they have completed - * their processing of a request. + * their processing of a command. This should be called before the + * data part of the command has completed. */ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) { struct mmc_command *cmd = mrq->cmd; - int err = cmd->error; - - pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", - mmc_hostname(host), cmd->opcode, err, - mrq->data ? mrq->data->error : 0, - mrq->stop ? mrq->stop->error : 0, - cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); + int err = mrq->cmd->error; + DBG("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", cmd->opcode, + err, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); if (err && cmd->retries) { cmd->retries--; @@ -99,9 +102,8 @@ EXPORT_SYMBOL(mmc_request_done); void mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) { - pr_debug("%s: starting CMD%u arg %08x flags %08x\n", - mmc_hostname(host), mrq->cmd->opcode, - mrq->cmd->arg, mrq->cmd->flags); + DBG("MMC: starting cmd %02x arg %08x flags %08x\n", + mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags); WARN_ON(host->card_busy == NULL); @@ -315,18 +317,6 @@ void mmc_release_host(struct mmc_host *host) EXPORT_SYMBOL(mmc_release_host); -static inline void mmc_set_ios(struct mmc_host *host) -{ - struct mmc_ios *ios = &host->ios; - - pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", - mmc_hostname(host), ios->clock, ios->bus_mode, - ios->power_mode, ios->chip_select, ios->vdd, - ios->bus_width); - - host->ops->set_ios(host, ios); -} - static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) { int err; @@ -379,7 +369,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) } } - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); return MMC_ERR_NONE; } @@ -430,7 +420,7 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) ocr = 3 << bit; host->ios.vdd = bit; - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); } else { ocr = 0; } @@ -564,7 +554,6 @@ static void mmc_decode_csd(struct mmc_card *card) csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); - csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_partial = UNSTUFF_BITS(resp, 21, 1); } else { @@ -599,7 +588,6 @@ static void mmc_decode_csd(struct mmc_card *card) csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); - csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_partial = UNSTUFF_BITS(resp, 21, 1); } @@ -683,7 +671,7 @@ static void mmc_idle_cards(struct mmc_host *host) struct mmc_command cmd; host->ios.chip_select = MMC_CS_HIGH; - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); mmc_delay(1); @@ -696,7 +684,7 @@ static void mmc_idle_cards(struct mmc_host *host) mmc_delay(1); host->ios.chip_select = MMC_CS_DONTCARE; - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); mmc_delay(1); } @@ -721,13 +709,13 @@ static void mmc_power_up(struct mmc_host *host) host->ios.chip_select = MMC_CS_DONTCARE; host->ios.power_mode = MMC_POWER_UP; host->ios.bus_width = MMC_BUS_WIDTH_1; - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); mmc_delay(1); host->ios.clock = host->f_min; host->ios.power_mode = MMC_POWER_ON; - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); mmc_delay(2); } @@ -740,7 +728,7 @@ static void mmc_power_off(struct mmc_host *host) host->ios.chip_select = MMC_CS_DONTCARE; host->ios.power_mode = MMC_POWER_OFF; host->ios.bus_width = MMC_BUS_WIDTH_1; - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); } static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) @@ -951,7 +939,6 @@ static void mmc_read_scrs(struct mmc_host *host) data.timeout_ns = card->csd.tacc_ns * 10; data.timeout_clks = card->csd.tacc_clks * 10; data.blksz_bits = 3; - data.blksz = 1 << 3; data.blocks = 1; data.flags = MMC_DATA_READ; data.sg = &sg; @@ -989,9 +976,8 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host) if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) max_dtr = card->csd.max_dtr; - pr_debug("%s: selected %d.%03dMHz transfer rate\n", - mmc_hostname(host), - max_dtr / 1000000, (max_dtr / 1000) % 1000); + DBG("MMC: selected %d.%03dMHz transfer rate\n", + max_dtr / 1000000, (max_dtr / 1000) % 1000); return max_dtr; } @@ -1065,7 +1051,7 @@ static void mmc_setup(struct mmc_host *host) } else { host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; host->ios.clock = host->f_min; - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); /* * We should remember the OCR mask from the existing @@ -1101,7 +1087,7 @@ static void mmc_setup(struct mmc_host *host) * Ok, now switch to push-pull mode. */ host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); mmc_read_csds(host); @@ -1147,7 +1133,7 @@ static void mmc_rescan(void *data) * attached cards and the host support. */ host->ios.clock = mmc_calculate_clock(host); - mmc_set_ios(host); + host->ops->set_ios(host, &host->ios); } mmc_release_host(host); diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 587458b37..79b2eff2b 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c @@ -175,7 +175,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.data.timeout_ns = card->csd.tacc_ns * 10; brq.data.timeout_clks = card->csd.tacc_clks * 10; brq.data.blksz_bits = md->block_bits; - brq.data.blksz = 1 << md->block_bits; brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); brq.stop.opcode = MMC_STOP_TRANSMISSION; brq.stop.arg = 0; @@ -188,12 +187,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.cmd.opcode = MMC_WRITE_BLOCK; brq.data.flags |= MMC_DATA_WRITE; brq.data.blocks = 1; - - /* - * Scale up the timeout by the r2w factor - */ - brq.data.timeout_ns <<= card->csd.r2w_factor; - brq.data.timeout_clks <<= card->csd.r2w_factor; } if (brq.data.blocks > 1) { @@ -325,52 +318,11 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) md->read_only = mmc_blk_readonly(card); /* - * Figure out a workable block size. MMC cards have: - * - two block sizes, one for read and one for write. - * - may support partial reads and/or writes - * (allows block sizes smaller than specified) + * Both SD and MMC specifications state (although a bit + * unclearly in the MMC case) that a block size of 512 + * bytes must always be supported by the card. */ - md->block_bits = card->csd.read_blkbits; - if (card->csd.write_blkbits != card->csd.read_blkbits) { - if (card->csd.write_blkbits < card->csd.read_blkbits && - card->csd.read_partial) { - /* - * write block size is smaller than read block - * size, but we support partial reads, so choose - * the smaller write block size. - */ - md->block_bits = card->csd.write_blkbits; - } else if (card->csd.write_blkbits > card->csd.read_blkbits && - card->csd.write_partial) { - /* - * read block size is smaller than write block - * size, but we support partial writes. Use read - * block size. - */ - } else { - /* - * We don't support this configuration for writes. - */ - printk(KERN_ERR "%s: unable to select block size for " - "writing (rb%u wb%u rp%u wp%u)\n", - mmc_card_id(card), - 1 << card->csd.read_blkbits, - 1 << card->csd.write_blkbits, - card->csd.read_partial, - card->csd.write_partial); - md->read_only = 1; - } - } - - /* - * Refuse to allow block sizes smaller than 512 bytes. - */ - if (md->block_bits < 9) { - printk(KERN_ERR "%s: unable to support block size %u\n", - mmc_card_id(card), 1 << md->block_bits); - ret = -EINVAL; - goto err_kfree; - } + md->block_bits = 9; md->disk = alloc_disk(1 << MMC_SHIFT); if (md->disk == NULL) { diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index da8e4d733..9fef29d97 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c @@ -33,8 +33,12 @@ #define DRIVER_NAME "mmci-pl18x" +#ifdef CONFIG_MMC_DEBUG #define DBG(host,fmt,args...) \ pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args) +#else +#define DBG(host,fmt,args...) do { } while (0) +#endif static unsigned int fmax = 515633; @@ -402,6 +406,9 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) struct mmci_host *host = mmc_priv(mmc); u32 clk = 0, pwr = 0; + DBG(host, "clock %uHz busmode %u powermode %u Vdd %u\n", + ios->clock, ios->bus_mode, ios->power_mode, ios->vdd); + if (ios->clock) { if (ios->clock >= host->mclk) { clk = MCI_CLK_BYPASS; diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c deleted file mode 100644 index becb3c68c..000000000 --- a/drivers/mmc/omap.c +++ /dev/null @@ -1,1226 +0,0 @@ -/* - * linux/drivers/media/mmc/omap.c - * - * Copyright (C) 2004 Nokia Corporation - * Written by Tuukka Tikkanen and Juha Yrjölä - * Misc hacks here and there by Tony Lindgren - * Other hacks (DMA, SD, etc) by David Brownell - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "omap.h" - -#define DRIVER_NAME "mmci-omap" -#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) - -/* Specifies how often in millisecs to poll for card status changes - * when the cover switch is open */ -#define OMAP_MMC_SWITCH_POLL_DELAY 500 - -static int mmc_omap_enable_poll = 1; - -struct mmc_omap_host { - int initialized; - int suspended; - struct mmc_request * mrq; - struct mmc_command * cmd; - struct mmc_data * data; - struct mmc_host * mmc; - struct device * dev; - unsigned char id; /* 16xx chips have 2 MMC blocks */ - struct clk * iclk; - struct clk * fclk; - void __iomem *base; - int irq; - unsigned char bus_mode; - unsigned char hw_bus_mode; - - unsigned int sg_len; - int sg_idx; - u16 * buffer; - u32 buffer_bytes_left; - u32 total_bytes_left; - - unsigned use_dma:1; - unsigned brs_received:1, dma_done:1; - unsigned dma_is_read:1; - unsigned dma_in_use:1; - int dma_ch; - spinlock_t dma_lock; - struct timer_list dma_timer; - unsigned dma_len; - - short power_pin; - short wp_pin; - - int switch_pin; - struct work_struct switch_work; - struct timer_list switch_timer; - int switch_last_state; -}; - -static inline int -mmc_omap_cover_is_open(struct mmc_omap_host *host) -{ - if (host->switch_pin < 0) - return 0; - return omap_get_gpio_datain(host->switch_pin); -} - -static ssize_t -mmc_omap_show_cover_switch(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mmc_omap_host *host = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", mmc_omap_cover_is_open(host) ? "open" : - "closed"); -} - -static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL); - -static ssize_t -mmc_omap_show_enable_poll(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", mmc_omap_enable_poll); -} - -static ssize_t -mmc_omap_store_enable_poll(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t size) -{ - int enable_poll; - - if (sscanf(buf, "%10d", &enable_poll) != 1) - return -EINVAL; - - if (enable_poll != mmc_omap_enable_poll) { - struct mmc_omap_host *host = dev_get_drvdata(dev); - - mmc_omap_enable_poll = enable_poll; - if (enable_poll && host->switch_pin >= 0) - schedule_work(&host->switch_work); - } - return size; -} - -static DEVICE_ATTR(enable_poll, 0664, - mmc_omap_show_enable_poll, mmc_omap_store_enable_poll); - -static void -mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd) -{ - u32 cmdreg; - u32 resptype; - u32 cmdtype; - - host->cmd = cmd; - - resptype = 0; - cmdtype = 0; - - /* Our hardware needs to know exact type */ - switch (RSP_TYPE(mmc_resp_type(cmd))) { - case RSP_TYPE(MMC_RSP_R1): - /* resp 1, resp 1b */ - resptype = 1; - break; - case RSP_TYPE(MMC_RSP_R2): - resptype = 2; - break; - case RSP_TYPE(MMC_RSP_R3): - resptype = 3; - break; - default: - break; - } - - if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) { - cmdtype = OMAP_MMC_CMDTYPE_ADTC; - } else if (mmc_cmd_type(cmd) == MMC_CMD_BC) { - cmdtype = OMAP_MMC_CMDTYPE_BC; - } else if (mmc_cmd_type(cmd) == MMC_CMD_BCR) { - cmdtype = OMAP_MMC_CMDTYPE_BCR; - } else { - cmdtype = OMAP_MMC_CMDTYPE_AC; - } - - cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12); - - if (host->bus_mode == MMC_BUSMODE_OPENDRAIN) - cmdreg |= 1 << 6; - - if (cmd->flags & MMC_RSP_BUSY) - cmdreg |= 1 << 11; - - if (host->data && !(host->data->flags & MMC_DATA_WRITE)) - cmdreg |= 1 << 15; - - clk_enable(host->fclk); - - OMAP_MMC_WRITE(host->base, CTO, 200); - OMAP_MMC_WRITE(host->base, ARGL, cmd->arg & 0xffff); - OMAP_MMC_WRITE(host->base, ARGH, cmd->arg >> 16); - OMAP_MMC_WRITE(host->base, IE, - OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL | - OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT | - OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT | - OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR | - OMAP_MMC_STAT_END_OF_DATA); - OMAP_MMC_WRITE(host->base, CMD, cmdreg); -} - -static void -mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data) -{ - if (host->dma_in_use) { - enum dma_data_direction dma_data_dir; - - BUG_ON(host->dma_ch < 0); - if (data->error != MMC_ERR_NONE) - omap_stop_dma(host->dma_ch); - /* Release DMA channel lazily */ - mod_timer(&host->dma_timer, jiffies + HZ); - if (data->flags & MMC_DATA_WRITE) - dma_data_dir = DMA_TO_DEVICE; - else - dma_data_dir = DMA_FROM_DEVICE; - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, - dma_data_dir); - } - host->data = NULL; - host->sg_len = 0; - clk_disable(host->fclk); - - /* NOTE: MMC layer will sometimes poll-wait CMD13 next, issuing - * dozens of requests until the card finishes writing data. - * It'd be cheaper to just wait till an EOFB interrupt arrives... - */ - - if (!data->stop) { - host->mrq = NULL; - mmc_request_done(host->mmc, data->mrq); - return; - } - - mmc_omap_start_command(host, data->stop); -} - -static void -mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data) -{ - unsigned long flags; - int done; - - if (!host->dma_in_use) { - mmc_omap_xfer_done(host, data); - return; - } - done = 0; - spin_lock_irqsave(&host->dma_lock, flags); - if (host->dma_done) - done = 1; - else - host->brs_received = 1; - spin_unlock_irqrestore(&host->dma_lock, flags); - if (done) - mmc_omap_xfer_done(host, data); -} - -static void -mmc_omap_dma_timer(unsigned long data) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) data; - - BUG_ON(host->dma_ch < 0); - omap_free_dma(host->dma_ch); - host->dma_ch = -1; -} - -static void -mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data) -{ - unsigned long flags; - int done; - - done = 0; - spin_lock_irqsave(&host->dma_lock, flags); - if (host->brs_received) - done = 1; - else - host->dma_done = 1; - spin_unlock_irqrestore(&host->dma_lock, flags); - if (done) - mmc_omap_xfer_done(host, data); -} - -static void -mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd) -{ - host->cmd = NULL; - - if (cmd->flags & MMC_RSP_PRESENT) { - if (cmd->flags & MMC_RSP_136) { - /* response type 2 */ - cmd->resp[3] = - OMAP_MMC_READ(host->base, RSP0) | - (OMAP_MMC_READ(host->base, RSP1) << 16); - cmd->resp[2] = - OMAP_MMC_READ(host->base, RSP2) | - (OMAP_MMC_READ(host->base, RSP3) << 16); - cmd->resp[1] = - OMAP_MMC_READ(host->base, RSP4) | - (OMAP_MMC_READ(host->base, RSP5) << 16); - cmd->resp[0] = - OMAP_MMC_READ(host->base, RSP6) | - (OMAP_MMC_READ(host->base, RSP7) << 16); - } else { - /* response types 1, 1b, 3, 4, 5, 6 */ - cmd->resp[0] = - OMAP_MMC_READ(host->base, RSP6) | - (OMAP_MMC_READ(host->base, RSP7) << 16); - } - } - - if (host->data == NULL || cmd->error != MMC_ERR_NONE) { - host->mrq = NULL; - clk_disable(host->fclk); - mmc_request_done(host->mmc, cmd->mrq); - } -} - -/* PIO only */ -static void -mmc_omap_sg_to_buf(struct mmc_omap_host *host) -{ - struct scatterlist *sg; - - sg = host->data->sg + host->sg_idx; - host->buffer_bytes_left = sg->length; - host->buffer = page_address(sg->page) + sg->offset; - if (host->buffer_bytes_left > host->total_bytes_left) - host->buffer_bytes_left = host->total_bytes_left; -} - -/* PIO only */ -static void -mmc_omap_xfer_data(struct mmc_omap_host *host, int write) -{ - int n; - void __iomem *reg; - u16 *p; - - if (host->buffer_bytes_left == 0) { - host->sg_idx++; - BUG_ON(host->sg_idx == host->sg_len); - mmc_omap_sg_to_buf(host); - } - n = 64; - if (n > host->buffer_bytes_left) - n = host->buffer_bytes_left; - host->buffer_bytes_left -= n; - host->total_bytes_left -= n; - host->data->bytes_xfered += n; - - if (write) { - __raw_writesw(host->base + OMAP_MMC_REG_DATA, host->buffer, n); - } else { - __raw_readsw(host->base + OMAP_MMC_REG_DATA, host->buffer, n); - } -} - -static inline void mmc_omap_report_irq(u16 status) -{ - static const char *mmc_omap_status_bits[] = { - "EOC", "CD", "CB", "BRS", "EOFB", "DTO", "DCRC", "CTO", - "CCRC", "CRW", "AF", "AE", "OCRB", "CIRQ", "CERR" - }; - int i, c = 0; - - for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++) - if (status & (1 << i)) { - if (c) - printk(" "); - printk("%s", mmc_omap_status_bits[i]); - c++; - } -} - -static irqreturn_t mmc_omap_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - struct mmc_omap_host * host = (struct mmc_omap_host *)dev_id; - u16 status; - int end_command; - int end_transfer; - int transfer_error; - - if (host->cmd == NULL && host->data == NULL) { - status = OMAP_MMC_READ(host->base, STAT); - dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status); - if (status != 0) { - OMAP_MMC_WRITE(host->base, STAT, status); - OMAP_MMC_WRITE(host->base, IE, 0); - } - return IRQ_HANDLED; - } - - end_command = 0; - end_transfer = 0; - transfer_error = 0; - - while ((status = OMAP_MMC_READ(host->base, STAT)) != 0) { - OMAP_MMC_WRITE(host->base, STAT, status); -#ifdef CONFIG_MMC_DEBUG - dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ", - status, host->cmd != NULL ? host->cmd->opcode : -1); - mmc_omap_report_irq(status); - printk("\n"); -#endif - if (host->total_bytes_left) { - if ((status & OMAP_MMC_STAT_A_FULL) || - (status & OMAP_MMC_STAT_END_OF_DATA)) - mmc_omap_xfer_data(host, 0); - if (status & OMAP_MMC_STAT_A_EMPTY) - mmc_omap_xfer_data(host, 1); - } - - if (status & OMAP_MMC_STAT_END_OF_DATA) { - end_transfer = 1; - } - - if (status & OMAP_MMC_STAT_DATA_TOUT) { - dev_dbg(mmc_dev(host->mmc), "data timeout\n"); - if (host->data) { - host->data->error |= MMC_ERR_TIMEOUT; - transfer_error = 1; - } - } - - if (status & OMAP_MMC_STAT_DATA_CRC) { - if (host->data) { - host->data->error |= MMC_ERR_BADCRC; - dev_dbg(mmc_dev(host->mmc), - "data CRC error, bytes left %d\n", - host->total_bytes_left); - transfer_error = 1; - } else { - dev_dbg(mmc_dev(host->mmc), "data CRC error\n"); - } - } - - if (status & OMAP_MMC_STAT_CMD_TOUT) { - /* Timeouts are routine with some commands */ - if (host->cmd) { - if (host->cmd->opcode != MMC_ALL_SEND_CID && - host->cmd->opcode != - MMC_SEND_OP_COND && - host->cmd->opcode != - MMC_APP_CMD && - !mmc_omap_cover_is_open(host)) - dev_err(mmc_dev(host->mmc), - "command timeout, CMD %d\n", - host->cmd->opcode); - host->cmd->error = MMC_ERR_TIMEOUT; - end_command = 1; - } - } - - if (status & OMAP_MMC_STAT_CMD_CRC) { - if (host->cmd) { - dev_err(mmc_dev(host->mmc), - "command CRC error (CMD%d, arg 0x%08x)\n", - host->cmd->opcode, host->cmd->arg); - host->cmd->error = MMC_ERR_BADCRC; - end_command = 1; - } else - dev_err(mmc_dev(host->mmc), - "command CRC error without cmd?\n"); - } - - if (status & OMAP_MMC_STAT_CARD_ERR) { - if (host->cmd && host->cmd->opcode == MMC_STOP_TRANSMISSION) { - u32 response = OMAP_MMC_READ(host->base, RSP6) - | (OMAP_MMC_READ(host->base, RSP7) << 16); - /* STOP sometimes sets must-ignore bits */ - if (!(response & (R1_CC_ERROR - | R1_ILLEGAL_COMMAND - | R1_COM_CRC_ERROR))) { - end_command = 1; - continue; - } - } - - dev_dbg(mmc_dev(host->mmc), "card status error (CMD%d)\n", - host->cmd->opcode); - if (host->cmd) { - host->cmd->error = MMC_ERR_FAILED; - end_command = 1; - } - if (host->data) { - host->data->error = MMC_ERR_FAILED; - transfer_error = 1; - } - } - - /* - * NOTE: On 1610 the END_OF_CMD may come too early when - * starting a write - */ - if ((status & OMAP_MMC_STAT_END_OF_CMD) && - (!(status & OMAP_MMC_STAT_A_EMPTY))) { - end_command = 1; - } - } - - if (end_command) { - mmc_omap_cmd_done(host, host->cmd); - } - if (transfer_error) - mmc_omap_xfer_done(host, host->data); - else if (end_transfer) - mmc_omap_end_of_data(host, host->data); - - return IRQ_HANDLED; -} - -static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) dev_id; - - schedule_work(&host->switch_work); - - return IRQ_HANDLED; -} - -static void mmc_omap_switch_timer(unsigned long arg) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) arg; - - schedule_work(&host->switch_work); -} - -/* FIXME: Handle card insertion and removal properly. Maybe use a mask - * for MMC state? */ -static void mmc_omap_switch_callback(unsigned long data, u8 mmc_mask) -{ -} - -static void mmc_omap_switch_handler(void *data) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) data; - struct mmc_card *card; - static int complained = 0; - int cards = 0, cover_open; - - if (host->switch_pin == -1) - return; - cover_open = mmc_omap_cover_is_open(host); - if (cover_open != host->switch_last_state) { - kobject_uevent(&host->dev->kobj, KOBJ_CHANGE); - host->switch_last_state = cover_open; - } - mmc_detect_change(host->mmc, 0); - list_for_each_entry(card, &host->mmc->cards, node) { - if (mmc_card_present(card)) - cards++; - } - if (mmc_omap_cover_is_open(host)) { - if (!complained) { - dev_info(mmc_dev(host->mmc), "cover is open"); - complained = 1; - } - if (mmc_omap_enable_poll) - mod_timer(&host->switch_timer, jiffies + - msecs_to_jiffies(OMAP_MMC_SWITCH_POLL_DELAY)); - } else { - complained = 0; - } -} - -/* Prepare to transfer the next segment of a scatterlist */ -static void -mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) -{ - int dma_ch = host->dma_ch; - unsigned long data_addr; - u16 buf, frame; - u32 count; - struct scatterlist *sg = &data->sg[host->sg_idx]; - int src_port = 0; - int dst_port = 0; - int sync_dev = 0; - - data_addr = io_v2p((u32) host->base) + OMAP_MMC_REG_DATA; - frame = 1 << data->blksz_bits; - count = sg_dma_len(sg); - - if ((data->blocks == 1) && (count > (1 << data->blksz_bits))) - count = frame; - - host->dma_len = count; - - /* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx. - * Use 16 or 32 word frames when the blocksize is at least that large. - * Blocksize is usually 512 bytes; but not for some SD reads. - */ - if (cpu_is_omap15xx() && frame > 32) - frame = 32; - else if (frame > 64) - frame = 64; - count /= frame; - frame >>= 1; - - if (!(data->flags & MMC_DATA_WRITE)) { - buf = 0x800f | ((frame - 1) << 8); - - if (cpu_class_is_omap1()) { - src_port = OMAP_DMA_PORT_TIPB; - dst_port = OMAP_DMA_PORT_EMIFF; - } - if (cpu_is_omap24xx()) - sync_dev = OMAP24XX_DMA_MMC1_RX; - - omap_set_dma_src_params(dma_ch, src_port, - OMAP_DMA_AMODE_CONSTANT, - data_addr, 0, 0); - omap_set_dma_dest_params(dma_ch, dst_port, - OMAP_DMA_AMODE_POST_INC, - sg_dma_address(sg), 0, 0); - omap_set_dma_dest_data_pack(dma_ch, 1); - omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); - } else { - buf = 0x0f80 | ((frame - 1) << 0); - - if (cpu_class_is_omap1()) { - src_port = OMAP_DMA_PORT_EMIFF; - dst_port = OMAP_DMA_PORT_TIPB; - } - if (cpu_is_omap24xx()) - sync_dev = OMAP24XX_DMA_MMC1_TX; - - omap_set_dma_dest_params(dma_ch, dst_port, - OMAP_DMA_AMODE_CONSTANT, - data_addr, 0, 0); - omap_set_dma_src_params(dma_ch, src_port, - OMAP_DMA_AMODE_POST_INC, - sg_dma_address(sg), 0, 0); - omap_set_dma_src_data_pack(dma_ch, 1); - omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); - } - - /* Max limit for DMA frame count is 0xffff */ - if (unlikely(count > 0xffff)) - BUG(); - - OMAP_MMC_WRITE(host->base, BUF, buf); - omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16, - frame, count, OMAP_DMA_SYNC_FRAME, - sync_dev, 0); -} - -/* A scatterlist segment completed */ -static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) data; - struct mmc_data *mmcdat = host->data; - - if (unlikely(host->dma_ch < 0)) { - dev_err(mmc_dev(host->mmc), "DMA callback while DMA not - enabled\n"); - return; - } - /* FIXME: We really should do something to _handle_ the errors */ - if (ch_status & OMAP_DMA_TOUT_IRQ) { - dev_err(mmc_dev(host->mmc),"DMA timeout\n"); - return; - } - if (ch_status & OMAP_DMA_DROP_IRQ) { - dev_err(mmc_dev(host->mmc), "DMA sync error\n"); - return; - } - if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) { - return; - } - mmcdat->bytes_xfered += host->dma_len; - host->sg_idx++; - if (host->sg_idx < host->sg_len) { - mmc_omap_prepare_dma(host, host->data); - omap_start_dma(host->dma_ch); - } else - mmc_omap_dma_done(host, host->data); -} - -static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data) -{ - const char *dev_name; - int sync_dev, dma_ch, is_read, r; - - is_read = !(data->flags & MMC_DATA_WRITE); - del_timer_sync(&host->dma_timer); - if (host->dma_ch >= 0) { - if (is_read == host->dma_is_read) - return 0; - omap_free_dma(host->dma_ch); - host->dma_ch = -1; - } - - if (is_read) { - if (host->id == 1) { - sync_dev = OMAP_DMA_MMC_RX; - dev_name = "MMC1 read"; - } else { - sync_dev = OMAP_DMA_MMC2_RX; - dev_name = "MMC2 read"; - } - } else { - if (host->id == 1) { - sync_dev = OMAP_DMA_MMC_TX; - dev_name = "MMC1 write"; - } else { - sync_dev = OMAP_DMA_MMC2_TX; - dev_name = "MMC2 write"; - } - } - r = omap_request_dma(sync_dev, dev_name, mmc_omap_dma_cb, - host, &dma_ch); - if (r != 0) { - dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r); - return r; - } - host->dma_ch = dma_ch; - host->dma_is_read = is_read; - - return 0; -} - -static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req) -{ - u16 reg; - - reg = OMAP_MMC_READ(host->base, SDIO); - reg &= ~(1 << 5); - OMAP_MMC_WRITE(host->base, SDIO, reg); - /* Set maximum timeout */ - OMAP_MMC_WRITE(host->base, CTO, 0xff); -} - -static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req) -{ - int timeout; - u16 reg; - - /* Convert ns to clock cycles by assuming 20MHz frequency - * 1 cycle at 20MHz = 500 ns - */ - timeout = req->data->timeout_clks + req->data->timeout_ns / 500; - - /* Check if we need to use timeout multiplier register */ - reg = OMAP_MMC_READ(host->base, SDIO); - if (timeout > 0xffff) { - reg |= (1 << 5); - timeout /= 1024; - } else - reg &= ~(1 << 5); - OMAP_MMC_WRITE(host->base, SDIO, reg); - OMAP_MMC_WRITE(host->base, DTO, timeout); -} - -static void -mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) -{ - struct mmc_data *data = req->data; - int i, use_dma, block_size; - unsigned sg_len; - - host->data = data; - if (data == NULL) { - OMAP_MMC_WRITE(host->base, BLEN, 0); - OMAP_MMC_WRITE(host->base, NBLK, 0); - OMAP_MMC_WRITE(host->base, BUF, 0); - host->dma_in_use = 0; - set_cmd_timeout(host, req); - return; - } - - - block_size = 1 << data->blksz_bits; - - OMAP_MMC_WRITE(host->base, NBLK, data->blocks - 1); - OMAP_MMC_WRITE(host->base, BLEN, block_size - 1); - set_data_timeout(host, req); - - /* cope with calling layer confusion; it issues "single - * block" writes using multi-block scatterlists. - */ - sg_len = (data->blocks == 1) ? 1 : data->sg_len; - - /* Only do DMA for entire blocks */ - use_dma = host->use_dma; - if (use_dma) { - for (i = 0; i < sg_len; i++) { - if ((data->sg[i].length % block_size) != 0) { - use_dma = 0; - break; - } - } - } - - host->sg_idx = 0; - if (use_dma) { - if (mmc_omap_get_dma_channel(host, data) == 0) { - enum dma_data_direction dma_data_dir; - - if (data->flags & MMC_DATA_WRITE) - dma_data_dir = DMA_TO_DEVICE; - else - dma_data_dir = DMA_FROM_DEVICE; - - host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, - sg_len, dma_data_dir); - host->total_bytes_left = 0; - mmc_omap_prepare_dma(host, req->data); - host->brs_received = 0; - host->dma_done = 0; - host->dma_in_use = 1; - } else - use_dma = 0; - } - - /* Revert to PIO? */ - if (!use_dma) { - OMAP_MMC_WRITE(host->base, BUF, 0x1f1f); - host->total_bytes_left = data->blocks * block_size; - host->sg_len = sg_len; - mmc_omap_sg_to_buf(host); - host->dma_in_use = 0; - } -} - -static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req) -{ - struct mmc_omap_host *host = mmc_priv(mmc); - - WARN_ON(host->mrq != NULL); - - host->mrq = req; - - /* only touch fifo AFTER the controller readies it */ - mmc_omap_prepare_data(host, req); - mmc_omap_start_command(host, req->cmd); - if (host->dma_in_use) - omap_start_dma(host->dma_ch); -} - -static void innovator_fpga_socket_power(int on) -{ -#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX) - - if (on) { - fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3), - OMAP1510_FPGA_POWER); - } else { - fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3), - OMAP1510_FPGA_POWER); - } -#endif -} - -/* - * Turn the socket power on/off. Innovator uses FPGA, most boards - * probably use GPIO. - */ -static void mmc_omap_power(struct mmc_omap_host *host, int on) -{ - if (on) { - if (machine_is_omap_innovator()) - innovator_fpga_socket_power(1); - else if (machine_is_omap_h2()) - tps65010_set_gpio_out_value(GPIO3, HIGH); - else if (machine_is_omap_h3()) - /* GPIO 4 of TPS65010 sends SD_EN signal */ - tps65010_set_gpio_out_value(GPIO4, HIGH); - else if (cpu_is_omap24xx()) { - u16 reg = OMAP_MMC_READ(host->base, CON); - OMAP_MMC_WRITE(host->base, CON, reg | (1 << 11)); - } else - if (host->power_pin >= 0) - omap_set_gpio_dataout(host->power_pin, 1); - } else { - if (machine_is_omap_innovator()) - innovator_fpga_socket_power(0); - else if (machine_is_omap_h2()) - tps65010_set_gpio_out_value(GPIO3, LOW); - else if (machine_is_omap_h3()) - tps65010_set_gpio_out_value(GPIO4, LOW); - else if (cpu_is_omap24xx()) { - u16 reg = OMAP_MMC_READ(host->base, CON); - OMAP_MMC_WRITE(host->base, CON, reg & ~(1 << 11)); - } else - if (host->power_pin >= 0) - omap_set_gpio_dataout(host->power_pin, 0); - } -} - -static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct mmc_omap_host *host = mmc_priv(mmc); - int dsor; - int realclock, i; - - realclock = ios->clock; - - if (ios->clock == 0) - dsor = 0; - else { - int func_clk_rate = clk_get_rate(host->fclk); - - dsor = func_clk_rate / realclock; - if (dsor < 1) - dsor = 1; - - if (func_clk_rate / dsor > realclock) - dsor++; - - if (dsor > 250) - dsor = 250; - dsor++; - - if (ios->bus_width == MMC_BUS_WIDTH_4) - dsor |= 1 << 15; - } - - switch (ios->power_mode) { - case MMC_POWER_OFF: - mmc_omap_power(host, 0); - break; - case MMC_POWER_UP: - case MMC_POWER_ON: - mmc_omap_power(host, 1); - dsor |= 1<<11; - break; - } - - host->bus_mode = ios->bus_mode; - host->hw_bus_mode = host->bus_mode; - - clk_enable(host->fclk); - - /* On insanely high arm_per frequencies something sometimes - * goes somehow out of sync, and the POW bit is not being set, - * which results in the while loop below getting stuck. - * Writing to the CON register twice seems to do the trick. */ - for (i = 0; i < 2; i++) - OMAP_MMC_WRITE(host->base, CON, dsor); - if (ios->power_mode == MMC_POWER_UP) { - /* Send clock cycles, poll completion */ - OMAP_MMC_WRITE(host->base, IE, 0); - OMAP_MMC_WRITE(host->base, STAT, 0xffff); - OMAP_MMC_WRITE(host->base, CMD, 1<<7); - while (0 == (OMAP_MMC_READ(host->base, STAT) & 1)); - OMAP_MMC_WRITE(host->base, STAT, 1); - } - clk_disable(host->fclk); -} - -static int mmc_omap_get_ro(struct mmc_host *mmc) -{ - struct mmc_omap_host *host = mmc_priv(mmc); - - return host->wp_pin && omap_get_gpio_datain(host->wp_pin); -} - -static struct mmc_host_ops mmc_omap_ops = { - .request = mmc_omap_request, - .set_ios = mmc_omap_set_ios, - .get_ro = mmc_omap_get_ro, -}; - -static int __init mmc_omap_probe(struct platform_device *pdev) -{ - struct omap_mmc_conf *minfo = pdev->dev.platform_data; - struct mmc_host *mmc; - struct mmc_omap_host *host = NULL; - int ret = 0; - - if (platform_get_resource(pdev, IORESOURCE_MEM, 0) || - platform_get_irq(pdev, IORESOURCE_IRQ, 0)) { - dev_err(&pdev->dev, "mmc_omap_probe: invalid resource type\n"); - return -ENODEV; - } - - if (!request_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1, - pdev->name)) { - dev_dbg(&pdev->dev, "request_mem_region failed\n"); - return -EBUSY; - } - - mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev); - if (!mmc) { - ret = -ENOMEM; - goto out; - } - - host = mmc_priv(mmc); - host->mmc = mmc; - - spin_lock_init(&host->dma_lock); - init_timer(&host->dma_timer); - host->dma_timer.function = mmc_omap_dma_timer; - host->dma_timer.data = (unsigned long) host; - - host->id = pdev->id; - - if (cpu_is_omap24xx()) { - host->iclk = clk_get(&pdev->dev, "mmc_ick"); - if (IS_ERR(host->iclk)) - goto out; - clk_enable(host->iclk); - } - - if (!cpu_is_omap24xx()) - host->fclk = clk_get(&pdev->dev, "mmc_ck"); - else - host->fclk = clk_get(&pdev->dev, "mmc_fck"); - - if (IS_ERR(host->fclk)) { - ret = PTR_ERR(host->fclk); - goto out; - } - - /* REVISIT: - * Also, use minfo->cover to decide how to manage - * the card detect sensing. - */ - host->power_pin = minfo->power_pin; - host->switch_pin = minfo->switch_pin; - host->wp_pin = minfo->wp_pin; - host->use_dma = 1; - host->dma_ch = -1; - - host->irq = pdev->resource[1].start; - host->base = ioremap(pdev->res.start, SZ_4K); - if (!host->base) { - ret = -ENOMEM; - goto out; - } - - if (minfo->wire4) - mmc->caps |= MMC_CAP_4_BIT_DATA; - - mmc->ops = &mmc_omap_ops; - mmc->f_min = 400000; - mmc->f_max = 24000000; - mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; - - /* Use scatterlist DMA to reduce per-transfer costs. - * NOTE max_seg_size assumption that small blocks aren't - * normally used (except e.g. for reading SD registers). - */ - mmc->max_phys_segs = 32; - mmc->max_hw_segs = 32; - mmc->max_sectors = 256; /* NBLK max 11-bits, OMAP also limited by DMA */ - mmc->max_seg_size = mmc->max_sectors * 512; - - if (host->power_pin >= 0) { - if ((ret = omap_request_gpio(host->power_pin)) != 0) { - dev_err(mmc_dev(host->mmc), "Unable to get GPIO - pin for MMC power\n"); - goto out; - } - omap_set_gpio_direction(host->power_pin, 0); - } - - ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); - if (ret) - goto out; - - host->dev = &pdev->dev; - platform_set_drvdata(pdev, host); - - mmc_add_host(mmc); - - if (host->switch_pin >= 0) { - INIT_WORK(&host->switch_work, mmc_omap_switch_handler, host); - init_timer(&host->switch_timer); - host->switch_timer.function = mmc_omap_switch_timer; - host->switch_timer.data = (unsigned long) host; - if (omap_request_gpio(host->switch_pin) != 0) { - dev_warn(mmc_dev(host->mmc), "Unable to get GPIO pin for MMC cover switch\n"); - host->switch_pin = -1; - goto no_switch; - } - - omap_set_gpio_direction(host->switch_pin, 1); - ret = request_irq(OMAP_GPIO_IRQ(host->switch_pin), - mmc_omap_switch_irq, SA_TRIGGER_RISING, DRIVER_NAME, host); - if (ret) { - dev_warn(mmc_dev(host->mmc), "Unable to get IRQ for MMC cover switch\n"); - omap_free_gpio(host->switch_pin); - host->switch_pin = -1; - goto no_switch; - } - ret = device_create_file(&pdev->dev, &dev_attr_cover_switch); - if (ret == 0) { - ret = device_create_file(&pdev->dev, &dev_attr_enable_poll); - if (ret != 0) - device_remove_file(&pdev->dev, &dev_attr_cover_switch); - } - if (ret) { - dev_wan(mmc_dev(host->mmc), "Unable to create sysfs attributes\n"); - free_irq(OMAP_GPIO_IRQ(host->switch_pin), host); - omap_free_gpio(host->switch_pin); - host->switch_pin = -1; - goto no_switch; - } - if (mmc_omap_enable_poll && mmc_omap_cover_is_open(host)) - schedule_work(&host->switch_work); - } - -no_switch: - return 0; - -out: - /* FIXME: Free other resources too. */ - if (host) { - if (host->iclk && !IS_ERR(host->iclk)) - clk_put(host->iclk); - if (host->fclk && !IS_ERR(host->fclk)) - clk_put(host->fclk); - mmc_free_host(host->mmc); - } - return ret; -} - -static int mmc_omap_remove(struct platform_device *pdev) -{ - struct mmc_omap_host *host = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - - if (host) { - mmc_remove_host(host->mmc); - free_irq(host->irq, host); - - if (host->power_pin >= 0) - omap_free_gpio(host->power_pin); - if (host->switch_pin >= 0) { - device_remove_file(&pdev->dev, &dev_attr_enable_poll); - device_remove_file(&pdev->dev, &dev_attr_cover_switch); - free_irq(OMAP_GPIO_IRQ(host->switch_pin), host); - omap_free_gpio(host->switch_pin); - host->switch_pin = -1; - del_timer_sync(&host->switch_timer); - flush_scheduled_work(); - } - if (host->iclk && !IS_ERR(host->iclk)) - clk_put(host->iclk); - if (host->fclk && !IS_ERR(host->fclk)) - clk_put(host->fclk); - mmc_free_host(host->mmc); - } - - release_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1); - - return 0; -} - -#ifdef CONFIG_PM -static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - int ret = 0; - struct mmc_omap_host *host = platform_get_drvdata(pdev); - - if (host && host->suspended) - return 0; - - if (host) { - ret = mmc_suspend_host(host->mmc, mesg); - if (ret == 0) - host->suspended = 1; - } - return ret; -} - -static int mmc_omap_resume(struct platform_device *pdev) -{ - int ret = 0; - struct mmc_omap_host *host = platform_get_drvdata(pdev); - - if (host && !host->suspended) - return 0; - - if (host) { - ret = mmc_resume_host(host->mmc); - if (ret == 0) - host->suspended = 0; - } - - return ret; -} -#else -#define mmc_omap_suspend NULL -#define mmc_omap_resume NULL -#endif - -static struct platform_driver mmc_omap_driver = { - .probe = mmc_omap_probe, - .remove = mmc_omap_remove, - .suspend = mmc_omap_suspend, - .resume = mmc_omap_resume, - .driver = { - .name = DRIVER_NAME, - }, -}; - -static int __init mmc_omap_init(void) -{ - return platform_driver_register(&mmc_omap_driver); -} - -static void __exit mmc_omap_exit(void) -{ - platform_driver_unregister(&mmc_omap_driver); -} - -module_init(mmc_omap_init); -module_exit(mmc_omap_exit); - -MODULE_DESCRIPTION("OMAP Multimedia Card driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS(DRIVER_NAME); -MODULE_AUTHOR("Juha Yrjölä"); diff --git a/drivers/mmc/omap.h b/drivers/mmc/omap.h deleted file mode 100644 index c954d355a..000000000 --- a/drivers/mmc/omap.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef DRIVERS_MEDIA_MMC_OMAP_H -#define DRIVERS_MEDIA_MMC_OMAP_H - -#define OMAP_MMC_REG_CMD 0x00 -#define OMAP_MMC_REG_ARGL 0x04 -#define OMAP_MMC_REG_ARGH 0x08 -#define OMAP_MMC_REG_CON 0x0c -#define OMAP_MMC_REG_STAT 0x10 -#define OMAP_MMC_REG_IE 0x14 -#define OMAP_MMC_REG_CTO 0x18 -#define OMAP_MMC_REG_DTO 0x1c -#define OMAP_MMC_REG_DATA 0x20 -#define OMAP_MMC_REG_BLEN 0x24 -#define OMAP_MMC_REG_NBLK 0x28 -#define OMAP_MMC_REG_BUF 0x2c -#define OMAP_MMC_REG_SDIO 0x34 -#define OMAP_MMC_REG_REV 0x3c -#define OMAP_MMC_REG_RSP0 0x40 -#define OMAP_MMC_REG_RSP1 0x44 -#define OMAP_MMC_REG_RSP2 0x48 -#define OMAP_MMC_REG_RSP3 0x4c -#define OMAP_MMC_REG_RSP4 0x50 -#define OMAP_MMC_REG_RSP5 0x54 -#define OMAP_MMC_REG_RSP6 0x58 -#define OMAP_MMC_REG_RSP7 0x5c -#define OMAP_MMC_REG_IOSR 0x60 -#define OMAP_MMC_REG_SYSC 0x64 -#define OMAP_MMC_REG_SYSS 0x68 - -#define OMAP_MMC_STAT_CARD_ERR (1 << 14) -#define OMAP_MMC_STAT_CARD_IRQ (1 << 13) -#define OMAP_MMC_STAT_OCR_BUSY (1 << 12) -#define OMAP_MMC_STAT_A_EMPTY (1 << 11) -#define OMAP_MMC_STAT_A_FULL (1 << 10) -#define OMAP_MMC_STAT_CMD_CRC (1 << 8) -#define OMAP_MMC_STAT_CMD_TOUT (1 << 7) -#define OMAP_MMC_STAT_DATA_CRC (1 << 6) -#define OMAP_MMC_STAT_DATA_TOUT (1 << 5) -#define OMAP_MMC_STAT_END_BUSY (1 << 4) -#define OMAP_MMC_STAT_END_OF_DATA (1 << 3) -#define OMAP_MMC_STAT_CARD_BUSY (1 << 2) -#define OMAP_MMC_STAT_END_OF_CMD (1 << 0) - -#define OMAP_MMC_READ(base, reg) __raw_readw((base) + OMAP_MMC_REG_##reg) -#define OMAP_MMC_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MMC_REG_##reg) - -/* - * Command types - */ -#define OMAP_MMC_CMDTYPE_BC 0 -#define OMAP_MMC_CMDTYPE_BCR 1 -#define OMAP_MMC_CMDTYPE_AC 2 -#define OMAP_MMC_CMDTYPE_ADTC 3 - -#endif diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index b49368fd9..285d7d068 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -37,6 +37,12 @@ #include "pxamci.h" +#ifdef CONFIG_MMC_DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) do { } while (0) +#endif + #define DRIVER_NAME "pxa2xx-mci" #define NR_SG 1 @@ -65,6 +71,11 @@ struct pxamci_host { unsigned int dma_dir; }; +static inline unsigned int ns_to_clocks(unsigned int ns) +{ + return (ns * (CLOCKRATE / 1000000) + 999) / 1000; +} + static void pxamci_stop_clock(struct pxamci_host *host) { if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { @@ -108,7 +119,6 @@ static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask) static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) { unsigned int nob = data->blocks; - unsigned long long clks; unsigned int timeout; u32 dcmd; int i; @@ -119,11 +129,9 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) nob = 0xffff; writel(nob, host->base + MMC_NOB); - writel(data->blksz, host->base + MMC_BLKLEN); + writel(1 << data->blksz_bits, host->base + MMC_BLKLEN); - clks = (unsigned long long)data->timeout_ns * CLOCKRATE; - do_div(clks, 1000000000UL); - timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt); + timeout = ns_to_clocks(data->timeout_ns) + data->timeout_clks; writel((timeout + 255) / 256, host->base + MMC_RDTO); if (data->flags & MMC_DATA_READ) { @@ -198,6 +206,7 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq) { + DBG("PXAMCI: request done\n"); host->mrq = NULL; host->cmd = NULL; host->data = NULL; @@ -243,7 +252,7 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) if ((cmd->resp[0] & 0x80000000) == 0) cmd->error = MMC_ERR_BADCRC; } else { - pr_debug("ignoring CRC from command %d - *risky*\n",cmd->opcode); + DBG("ignoring CRC from command %d - *risky*\n",cmd->opcode); } #else cmd->error = MMC_ERR_BADCRC; @@ -283,14 +292,14 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) * data blocks as being in error. */ if (data->error == MMC_ERR_NONE) - data->bytes_xfered = data->blocks * data->blksz; + data->bytes_xfered = data->blocks << data->blksz_bits; else data->bytes_xfered = 0; pxamci_disable_irq(host, DATA_TRAN_DONE); host->data = NULL; - if (host->mrq->stop) { + if (host->mrq->stop && data->error == MMC_ERR_NONE) { pxamci_stop_clock(host); pxamci_start_cmd(host, host->mrq->stop, 0); } else { @@ -308,10 +317,12 @@ static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs) ireg = readl(host->base + MMC_I_REG); + DBG("PXAMCI: irq %08x\n", ireg); + if (ireg) { unsigned stat = readl(host->base + MMC_STAT); - pr_debug("PXAMCI: irq %08x stat %08x\n", ireg, stat); + DBG("PXAMCI: stat %08x\n", stat); if (ireg & END_CMD_RES) handled |= pxamci_cmd_done(host, stat); @@ -365,6 +376,10 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct pxamci_host *host = mmc_priv(mmc); + DBG("pxamci_set_ios: clock %u power %u vdd %u.%02u\n", + ios->clock, ios->power_mode, ios->vdd / 100, + ios->vdd % 100); + if (ios->clock) { unsigned int clk = CLOCKRATE / ios->clock; if (CLOCKRATE / clk > ios->clock) @@ -390,8 +405,8 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->cmdat |= CMDAT_INIT; } - pr_debug("PXAMCI: clkrt = %x cmdat = %x\n", - host->clkrt, host->cmdat); + DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n", + host->clkrt, host->cmdat); } static struct mmc_host_ops pxamci_ops = { @@ -423,7 +438,7 @@ static int pxamci_probe(struct platform_device *pdev) r = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!r || irq < 0) + if (!r || irq == NO_IRQ) return -ENXIO; r = request_mem_region(r->start, SZ_4K, DRIVER_NAME); diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c deleted file mode 100644 index b0053280f..000000000 --- a/drivers/mmc/sdhci.c +++ /dev/null @@ -1,1257 +0,0 @@ -/* - * linux/drivers/mmc/sdhci.c - Secure Digital Host Controller Interface driver - * - * Copyright (C) 2005-2006 Pierre Ossman, 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. - */ - - /* - * Note that PIO transfer is rather crappy atm. The buffer full/empty - * interrupts aren't reliable so we currently transfer the entire buffer - * directly. Patches to solve the problem are welcome. - */ - -#include -#include -#include -#include - -#include -#include - -#include - -#include "sdhci.h" - -#define DRIVER_NAME "sdhci" -#define DRIVER_VERSION "0.11" - -#define BUGMAIL "" - -#define DBG(f, x...) \ - pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) - -static const struct pci_device_id pci_ids[] __devinitdata = { - /* handle any SD host controller */ - {PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)}, - { /* end: all zeroes */ }, -}; - -MODULE_DEVICE_TABLE(pci, pci_ids); - -static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *); -static void sdhci_finish_data(struct sdhci_host *); - -static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); -static void sdhci_finish_command(struct sdhci_host *); - -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)); - 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)); - printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", - readl(host->ioaddr + SDHCI_ARGUMENT), - readw(host->ioaddr + 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)); - 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)); - printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", - readb(host->ioaddr + SDHCI_WALK_UP_CONTROL), - readw(host->ioaddr + 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)); - 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)); - 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)); - printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n", - readl(host->ioaddr + SDHCI_CAPABILITIES), - readl(host->ioaddr + SDHCI_MAX_CURRENT)); - - printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); -} - -/*****************************************************************************\ - * * - * Low level functions * - * * -\*****************************************************************************/ - -static void sdhci_reset(struct sdhci_host *host, u8 mask) -{ - writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET); - - if (mask & SDHCI_RESET_ALL) { - host->clock = 0; - - mdelay(50); - } -} - -static void sdhci_init(struct sdhci_host *host) -{ - u32 intmask; - - sdhci_reset(host, SDHCI_RESET_ALL); - - intmask = ~(SDHCI_INT_CARD_INT | SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL); - - writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); - writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); - - /* This is unknown magic. */ - writeb(0xE, host->ioaddr + SDHCI_TIMEOUT_CONTROL); -} - -static void sdhci_activate_led(struct sdhci_host *host) -{ - u8 ctrl; - - ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); - ctrl |= SDHCI_CTRL_LED; - writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); -} - -static void sdhci_deactivate_led(struct sdhci_host *host) -{ - u8 ctrl; - - ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); - ctrl &= ~SDHCI_CTRL_LED; - writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); -} - -/*****************************************************************************\ - * * - * Core functions * - * * -\*****************************************************************************/ - -static inline char* sdhci_kmap_sg(struct sdhci_host* host) -{ - host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ); - return host->mapped_sg + host->cur_sg->offset; -} - -static inline void sdhci_kunmap_sg(struct sdhci_host* host) -{ - kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ); -} - -static inline int sdhci_next_sg(struct sdhci_host* host) -{ - /* - * Skip to next SG entry. - */ - host->cur_sg++; - host->num_sg--; - - /* - * Any entries left? - */ - if (host->num_sg > 0) { - host->offset = 0; - host->remain = host->cur_sg->length; - } - - return host->num_sg; -} - -static void sdhci_transfer_pio(struct sdhci_host *host) -{ - char *buffer; - u32 mask; - int bytes, size; - unsigned long max_jiffies; - - BUG_ON(!host->data); - - if (host->num_sg == 0) - return; - - bytes = 0; - if (host->data->flags & MMC_DATA_READ) - mask = SDHCI_DATA_AVAILABLE; - else - mask = SDHCI_SPACE_AVAILABLE; - - buffer = sdhci_kmap_sg(host) + host->offset; - - /* Transfer shouldn't take more than 5 s */ - max_jiffies = jiffies + HZ * 5; - - while (host->size > 0) { - if (time_after(jiffies, max_jiffies)) { - printk(KERN_ERR "%s: PIO transfer stalled. " - "Please report this to " - BUGMAIL ".\n", mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - - sdhci_kunmap_sg(host); - - host->data->error = MMC_ERR_FAILED; - sdhci_finish_data(host); - return; - } - - if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask)) - continue; - - size = min(host->size, host->remain); - - if (size >= 4) { - if (host->data->flags & MMC_DATA_READ) - *(u32*)buffer = readl(host->ioaddr + SDHCI_BUFFER); - else - writel(*(u32*)buffer, host->ioaddr + SDHCI_BUFFER); - size = 4; - } else if (size >= 2) { - if (host->data->flags & MMC_DATA_READ) - *(u16*)buffer = readw(host->ioaddr + SDHCI_BUFFER); - else - writew(*(u16*)buffer, host->ioaddr + SDHCI_BUFFER); - size = 2; - } else { - if (host->data->flags & MMC_DATA_READ) - *(u8*)buffer = readb(host->ioaddr + SDHCI_BUFFER); - else - writeb(*(u8*)buffer, host->ioaddr + SDHCI_BUFFER); - size = 1; - } - - buffer += size; - host->offset += size; - host->remain -= size; - - bytes += size; - host->size -= size; - - if (host->remain == 0) { - sdhci_kunmap_sg(host); - if (sdhci_next_sg(host) == 0) { - DBG("PIO transfer: %d bytes\n", bytes); - return; - } - buffer = sdhci_kmap_sg(host); - } - } - - sdhci_kunmap_sg(host); - - DBG("PIO transfer: %d bytes\n", bytes); -} - -static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) -{ - u16 mode; - - WARN_ON(host->data); - - if (data == NULL) { - writew(0, host->ioaddr + SDHCI_TRANSFER_MODE); - return; - } - - DBG("blksz %04x blks %04x flags %08x\n", - 1 << data->blksz_bits, data->blocks, data->flags); - DBG("tsac %d ms nsac %d clk\n", - data->timeout_ns / 1000000, data->timeout_clks); - - mode = SDHCI_TRNS_BLK_CNT_EN; - if (data->blocks > 1) - mode |= SDHCI_TRNS_MULTI; - if (data->flags & MMC_DATA_READ) - mode |= SDHCI_TRNS_READ; - if (host->flags & SDHCI_USE_DMA) - mode |= SDHCI_TRNS_DMA; - - writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); - - writew(1 << data->blksz_bits, host->ioaddr + SDHCI_BLOCK_SIZE); - writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT); - - if (host->flags & SDHCI_USE_DMA) { - int count; - - count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len, - (data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); - BUG_ON(count != 1); - - writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); - } else { - host->size = (1 << data->blksz_bits) * data->blocks; - - host->cur_sg = data->sg; - host->num_sg = data->sg_len; - - host->offset = 0; - host->remain = host->cur_sg->length; - } -} - -static void sdhci_finish_data(struct sdhci_host *host) -{ - struct mmc_data *data; - u32 intmask; - u16 blocks; - - BUG_ON(!host->data); - - data = host->data; - host->data = NULL; - - if (host->flags & SDHCI_USE_DMA) { - pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len, - (data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); - } else { - intmask = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); - intmask &= ~(SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL); - writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); - - intmask = readl(host->ioaddr + SDHCI_INT_ENABLE); - intmask &= ~(SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL); - writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); - } - - /* - * Controller doesn't count down when in single block mode. - */ - if ((data->blocks == 1) && (data->error == MMC_ERR_NONE)) - blocks = 0; - else - blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); - data->bytes_xfered = (1 << data->blksz_bits) * (data->blocks - blocks); - - if ((data->error == MMC_ERR_NONE) && blocks) { - printk(KERN_ERR "%s: Controller signalled completion even " - "though there were blocks left. Please report this " - "to " BUGMAIL ".\n", mmc_hostname(host->mmc)); - data->error = MMC_ERR_FAILED; - } - - if (host->size != 0) { - printk(KERN_ERR "%s: %d bytes were left untransferred. " - "Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc), host->size); - data->error = MMC_ERR_FAILED; - } - - DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); - - if (data->stop) { - /* - * The controller needs a reset of internal state machines - * upon error conditions. - */ - if (data->error != MMC_ERR_NONE) { - sdhci_reset(host, SDHCI_RESET_CMD); - sdhci_reset(host, SDHCI_RESET_DATA); - } - - sdhci_send_command(host, data->stop); - } else - tasklet_schedule(&host->finish_tasklet); -} - -static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) -{ - int flags; - u32 present; - unsigned long max_jiffies; - - WARN_ON(host->cmd); - - DBG("Sending cmd (%x)\n", cmd->opcode); - - /* Wait max 10 ms */ - max_jiffies = jiffies + (HZ + 99)/100; - do { - if (time_after(jiffies, max_jiffies)) { - printk(KERN_ERR "%s: Controller never released " - "inhibit bits. Please report this to " - BUGMAIL ".\n", mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - cmd->error = MMC_ERR_FAILED; - tasklet_schedule(&host->finish_tasklet); - return; - } - present = readl(host->ioaddr + SDHCI_PRESENT_STATE); - } while (present & (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)); - - mod_timer(&host->timer, jiffies + 10 * HZ); - - host->cmd = cmd; - - sdhci_prepare_data(host, cmd->data); - - writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT); - - if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { - printk(KERN_ERR "%s: Unsupported response type! " - "Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); - cmd->error = MMC_ERR_INVALID; - tasklet_schedule(&host->finish_tasklet); - return; - } - - if (!(cmd->flags & MMC_RSP_PRESENT)) - flags = SDHCI_CMD_RESP_NONE; - else if (cmd->flags & MMC_RSP_136) - flags = SDHCI_CMD_RESP_LONG; - else if (cmd->flags & MMC_RSP_BUSY) - flags = SDHCI_CMD_RESP_SHORT_BUSY; - else - flags = SDHCI_CMD_RESP_SHORT; - - if (cmd->flags & MMC_RSP_CRC) - flags |= SDHCI_CMD_CRC; - if (cmd->flags & MMC_RSP_OPCODE) - flags |= SDHCI_CMD_INDEX; - if (cmd->data) - flags |= SDHCI_CMD_DATA; - - writel(SDHCI_MAKE_CMD(cmd->opcode, flags), - host->ioaddr + SDHCI_COMMAND); -} - -static void sdhci_finish_command(struct sdhci_host *host) -{ - int i; - - BUG_ON(host->cmd == NULL); - - if (host->cmd->flags & MMC_RSP_PRESENT) { - 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 + - SDHCI_RESPONSE + (3-i)*4) << 8; - if (i != 3) - host->cmd->resp[i] |= - readb(host->ioaddr + - SDHCI_RESPONSE + (3-i)*4-1); - } - } else { - host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE); - } - } - - host->cmd->error = MMC_ERR_NONE; - - DBG("Ending cmd (%x)\n", host->cmd->opcode); - - if (host->cmd->data) { - u32 intmask; - - host->data = host->cmd->data; - - if (!(host->flags & SDHCI_USE_DMA)) { - /* - * Don't enable the interrupts until now to make sure we - * get stable handling of the FIFO. - */ - intmask = readl(host->ioaddr + SDHCI_INT_ENABLE); - intmask |= SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL; - writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); - - intmask = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); - intmask |= SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL; - writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); - - /* - * The buffer interrupts are to unreliable so we - * start the transfer immediatly. - */ - sdhci_transfer_pio(host); - } - } else - tasklet_schedule(&host->finish_tasklet); - - host->cmd = NULL; -} - -static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) -{ - int div; - u16 clk; - unsigned long max_jiffies; - - if (clock == host->clock) - return; - - writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); - - if (clock == 0) - goto out; - - for (div = 1;div < 256;div *= 2) { - if ((host->max_clk / div) <= clock) - break; - } - div >>= 1; - - clk = div << SDHCI_DIVIDER_SHIFT; - clk |= SDHCI_CLOCK_INT_EN; - writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); - - /* Wait max 10 ms */ - max_jiffies = jiffies + (HZ + 99)/100; - do { - if (time_after(jiffies, max_jiffies)) { - printk(KERN_ERR "%s: Internal clock never stabilised. " - "Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - return; - } - clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL); - } while (!(clk & SDHCI_CLOCK_INT_STABLE)); - - clk |= SDHCI_CLOCK_CARD_EN; - writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); - -out: - host->clock = clock; -} - -/*****************************************************************************\ - * * - * MMC callbacks * - * * -\*****************************************************************************/ - -static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) -{ - struct sdhci_host *host; - unsigned long flags; - - host = mmc_priv(mmc); - - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); - - sdhci_activate_led(host); - - host->mrq = mrq; - - if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { - host->mrq->cmd->error = MMC_ERR_TIMEOUT; - tasklet_schedule(&host->finish_tasklet); - } else - sdhci_send_command(host, mrq->cmd); - - spin_unlock_irqrestore(&host->lock, flags); -} - -static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct sdhci_host *host; - unsigned long flags; - u8 ctrl; - - host = mmc_priv(mmc); - - spin_lock_irqsave(&host->lock, flags); - - /* - * Reset the chip on each power off. - * Should clear out any weird states. - */ - if (ios->power_mode == MMC_POWER_OFF) { - writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE); - spin_unlock_irqrestore(&host->lock, flags); - sdhci_init(host); - spin_lock_irqsave(&host->lock, flags); - } - - sdhci_set_clock(host, ios->clock); - - if (ios->power_mode == MMC_POWER_OFF) - writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); - else - writeb(0xFF, host->ioaddr + SDHCI_POWER_CONTROL); - - ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); - if (ios->bus_width == MMC_BUS_WIDTH_4) - ctrl |= SDHCI_CTRL_4BITBUS; - else - ctrl &= ~SDHCI_CTRL_4BITBUS; - writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); - - spin_unlock_irqrestore(&host->lock, flags); -} - -static int sdhci_get_ro(struct mmc_host *mmc) -{ - struct sdhci_host *host; - unsigned long flags; - int present; - - host = mmc_priv(mmc); - - spin_lock_irqsave(&host->lock, flags); - - present = readl(host->ioaddr + SDHCI_PRESENT_STATE); - - spin_unlock_irqrestore(&host->lock, flags); - - return !(present & SDHCI_WRITE_PROTECT); -} - -static struct mmc_host_ops sdhci_ops = { - .request = sdhci_request, - .set_ios = sdhci_set_ios, - .get_ro = sdhci_get_ro, -}; - -/*****************************************************************************\ - * * - * Tasklets * - * * -\*****************************************************************************/ - -static void sdhci_tasklet_card(unsigned long param) -{ - struct sdhci_host *host; - unsigned long flags; - - host = (struct sdhci_host*)param; - - spin_lock_irqsave(&host->lock, flags); - - if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { - if (host->mrq) { - printk(KERN_ERR "%s: Card removed during transfer!\n", - mmc_hostname(host->mmc)); - printk(KERN_ERR "%s: Resetting controller.\n", - mmc_hostname(host->mmc)); - - sdhci_reset(host, SDHCI_RESET_CMD); - sdhci_reset(host, SDHCI_RESET_DATA); - - host->mrq->cmd->error = MMC_ERR_FAILED; - tasklet_schedule(&host->finish_tasklet); - } - } - - spin_unlock_irqrestore(&host->lock, flags); - - mmc_detect_change(host->mmc, msecs_to_jiffies(500)); -} - -static void sdhci_tasklet_finish(unsigned long param) -{ - struct sdhci_host *host; - unsigned long flags; - struct mmc_request *mrq; - - host = (struct sdhci_host*)param; - - spin_lock_irqsave(&host->lock, flags); - - del_timer(&host->timer); - - mrq = host->mrq; - - DBG("Ending request, cmd (%x)\n", mrq->cmd->opcode); - - /* - * The controller needs a reset of internal state machines - * upon error conditions. - */ - if ((mrq->cmd->error != MMC_ERR_NONE) || - (mrq->data && ((mrq->data->error != MMC_ERR_NONE) || - (mrq->data->stop && (mrq->data->stop->error != MMC_ERR_NONE))))) { - sdhci_reset(host, SDHCI_RESET_CMD); - sdhci_reset(host, SDHCI_RESET_DATA); - } - - host->mrq = NULL; - host->cmd = NULL; - host->data = NULL; - - sdhci_deactivate_led(host); - - spin_unlock_irqrestore(&host->lock, flags); - - mmc_request_done(host->mmc, mrq); -} - -static void sdhci_timeout_timer(unsigned long data) -{ - struct sdhci_host *host; - unsigned long flags; - - host = (struct sdhci_host*)data; - - spin_lock_irqsave(&host->lock, flags); - - if (host->mrq) { - printk(KERN_ERR "%s: Timeout waiting for hardware interrupt. " - "Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - - if (host->data) { - host->data->error = MMC_ERR_TIMEOUT; - sdhci_finish_data(host); - } else { - if (host->cmd) - host->cmd->error = MMC_ERR_TIMEOUT; - else - host->mrq->cmd->error = MMC_ERR_TIMEOUT; - - tasklet_schedule(&host->finish_tasklet); - } - } - - spin_unlock_irqrestore(&host->lock, flags); -} - -/*****************************************************************************\ - * * - * Interrupt handling * - * * -\*****************************************************************************/ - -static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) -{ - BUG_ON(intmask == 0); - - if (!host->cmd) { - printk(KERN_ERR "%s: Got command interrupt even though no " - "command operation was in progress.\n", - mmc_hostname(host->mmc)); - printk(KERN_ERR "%s: Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - return; - } - - if (intmask & SDHCI_INT_RESPONSE) - sdhci_finish_command(host); - else { - if (intmask & SDHCI_INT_TIMEOUT) - host->cmd->error = MMC_ERR_TIMEOUT; - else if (intmask & SDHCI_INT_CRC) - host->cmd->error = MMC_ERR_BADCRC; - else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) - host->cmd->error = MMC_ERR_FAILED; - else - host->cmd->error = MMC_ERR_INVALID; - - tasklet_schedule(&host->finish_tasklet); - } -} - -static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) -{ - BUG_ON(intmask == 0); - - if (!host->data) { - /* - * A data end interrupt is sent together with the response - * for the stop command. - */ - if (intmask & SDHCI_INT_DATA_END) - return; - - printk(KERN_ERR "%s: Got data interrupt even though no " - "data operation was in progress.\n", - mmc_hostname(host->mmc)); - printk(KERN_ERR "%s: Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - - return; - } - - if (intmask & SDHCI_INT_DATA_TIMEOUT) - host->data->error = MMC_ERR_TIMEOUT; - else if (intmask & SDHCI_INT_DATA_CRC) - host->data->error = MMC_ERR_BADCRC; - else if (intmask & SDHCI_INT_DATA_END_BIT) - host->data->error = MMC_ERR_FAILED; - - if (host->data->error != MMC_ERR_NONE) - sdhci_finish_data(host); - else { - if (intmask & (SDHCI_INT_BUF_FULL | SDHCI_INT_BUF_EMPTY)) - sdhci_transfer_pio(host); - - if (intmask & SDHCI_INT_DATA_END) - sdhci_finish_data(host); - } -} - -static irqreturn_t sdhci_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - irqreturn_t result; - struct sdhci_host* host = dev_id; - u32 intmask; - - spin_lock(&host->lock); - - intmask = readl(host->ioaddr + SDHCI_INT_STATUS); - - if (!intmask) { - result = IRQ_NONE; - goto out; - } - - DBG("*** %s got interrupt: 0x%08x\n", host->slot_descr, intmask); - - if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) - tasklet_schedule(&host->card_tasklet); - - if (intmask & SDHCI_INT_CMD_MASK) { - sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); - - writel(intmask & SDHCI_INT_CMD_MASK, - host->ioaddr + SDHCI_INT_STATUS); - } - - if (intmask & SDHCI_INT_DATA_MASK) { - sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); - - writel(intmask & SDHCI_INT_DATA_MASK, - host->ioaddr + SDHCI_INT_STATUS); - } - - intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); - - if (intmask & SDHCI_INT_CARD_INT) { - printk(KERN_ERR "%s: Unexpected card interrupt. Please " - "report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - } - - if (intmask & SDHCI_INT_BUS_POWER) { - printk(KERN_ERR "%s: Unexpected bus power interrupt. Please " - "report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - } - - if (intmask & SDHCI_INT_ACMD12ERR) { - printk(KERN_ERR "%s: Unexpected auto CMD12 error. Please " - "report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); - sdhci_dumpregs(host); - - writew(~0, host->ioaddr + SDHCI_ACMD12_ERR); - } - - if (intmask) - writel(intmask, host->ioaddr + SDHCI_INT_STATUS); - - result = IRQ_HANDLED; - -out: - spin_unlock(&host->lock); - - return result; -} - -/*****************************************************************************\ - * * - * Suspend/resume * - * * -\*****************************************************************************/ - -#ifdef CONFIG_PM - -static int sdhci_suspend (struct pci_dev *pdev, pm_message_t state) -{ - struct sdhci_chip *chip; - int i, ret; - - chip = pci_get_drvdata(pdev); - if (!chip) - return 0; - - DBG("Suspending...\n"); - - for (i = 0;i < chip->num_slots;i++) { - if (!chip->hosts[i]) - continue; - ret = mmc_suspend_host(chip->hosts[i]->mmc, state); - if (ret) { - for (i--;i >= 0;i--) - mmc_resume_host(chip->hosts[i]->mmc); - return ret; - } - } - - pci_save_state(pdev); - pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - - return 0; -} - -static int sdhci_resume (struct pci_dev *pdev) -{ - struct sdhci_chip *chip; - int i, ret; - - chip = pci_get_drvdata(pdev); - if (!chip) - return 0; - - DBG("Resuming...\n"); - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - pci_enable_device(pdev); - - for (i = 0;i < chip->num_slots;i++) { - if (!chip->hosts[i]) - continue; - if (chip->hosts[i]->flags & SDHCI_USE_DMA) - pci_set_master(pdev); - sdhci_init(chip->hosts[i]); - ret = mmc_resume_host(chip->hosts[i]->mmc); - if (ret) - return ret; - } - - return 0; -} - -#else /* CONFIG_PM */ - -#define sdhci_suspend NULL -#define sdhci_resume NULL - -#endif /* CONFIG_PM */ - -/*****************************************************************************\ - * * - * Device probing/removal * - * * -\*****************************************************************************/ - -static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) -{ - int ret; - struct sdhci_chip *chip; - struct mmc_host *mmc; - struct sdhci_host *host; - - u8 first_bar; - unsigned int caps; - - chip = pci_get_drvdata(pdev); - BUG_ON(!chip); - - ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); - if (ret) - return ret; - - first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; - - if (first_bar > 5) { - printk(KERN_ERR DRIVER_NAME ": Invalid first BAR. Aborting.\n"); - return -ENODEV; - } - - if (!(pci_resource_flags(pdev, first_bar + slot) & IORESOURCE_MEM)) { - printk(KERN_ERR DRIVER_NAME ": BAR is not iomem. Aborting.\n"); - return -ENODEV; - } - - if (pci_resource_len(pdev, first_bar + slot) != 0x100) { - printk(KERN_ERR DRIVER_NAME ": Invalid iomem size. Aborting.\n"); - return -ENODEV; - } - - mmc = mmc_alloc_host(sizeof(struct sdhci_host), &pdev->dev); - if (!mmc) - return -ENOMEM; - - host = mmc_priv(mmc); - host->mmc = mmc; - - host->bar = first_bar + slot; - - host->addr = pci_resource_start(pdev, host->bar); - host->irq = pdev->irq; - - DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq); - - snprintf(host->slot_descr, 20, "sdhci:slot%d", slot); - - ret = pci_request_region(pdev, host->bar, host->slot_descr); - if (ret) - goto free; - - host->ioaddr = ioremap_nocache(host->addr, - pci_resource_len(pdev, host->bar)); - if (!host->ioaddr) { - ret = -ENOMEM; - goto release; - } - - caps = readl(host->ioaddr + SDHCI_CAPABILITIES); - - if ((caps & SDHCI_CAN_DO_DMA) && ((pdev->class & 0x0000FF) == 0x01)) - host->flags |= SDHCI_USE_DMA; - - if (host->flags & SDHCI_USE_DMA) { - if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { - printk(KERN_WARNING "%s: No suitable DMA available. " - "Falling back to PIO.\n", host->slot_descr); - host->flags &= ~SDHCI_USE_DMA; - } - } - - if (host->flags & SDHCI_USE_DMA) - pci_set_master(pdev); - else /* XXX: Hack to get MMC layer to avoid highmem */ - pdev->dma_mask = 0; - - host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; - host->max_clk *= 1000000; - - /* - * Set host parameters. - */ - mmc->ops = &sdhci_ops; - mmc->f_min = host->max_clk / 256; - mmc->f_max = host->max_clk; - mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; - mmc->caps = MMC_CAP_4_BIT_DATA; - - spin_lock_init(&host->lock); - - /* - * Maximum number of segments. Hardware cannot do scatter lists. - */ - if (host->flags & SDHCI_USE_DMA) - mmc->max_hw_segs = 1; - else - mmc->max_hw_segs = 16; - mmc->max_phys_segs = 16; - - /* - * Maximum number of sectors in one transfer. Limited by sector - * count register. - */ - mmc->max_sectors = 0x3FFF; - - /* - * Maximum segment size. Could be one segment with the maximum number - * of sectors. - */ - mmc->max_seg_size = mmc->max_sectors * 512; - - /* - * Init tasklets. - */ - tasklet_init(&host->card_tasklet, - sdhci_tasklet_card, (unsigned long)host); - tasklet_init(&host->finish_tasklet, - sdhci_tasklet_finish, (unsigned long)host); - - setup_timer(&host->timer, sdhci_timeout_timer, (int)host); - - ret = request_irq(host->irq, sdhci_irq, SA_SHIRQ, - host->slot_descr, host); - if (ret) - goto unmap; - - sdhci_init(host); - -#ifdef CONFIG_MMC_DEBUG - sdhci_dumpregs(host); -#endif - - host->chip = chip; - chip->hosts[slot] = host; - - mmc_add_host(mmc); - - printk(KERN_INFO "%s: SDHCI at 0x%08lx irq %d %s\n", mmc_hostname(mmc), - host->addr, host->irq, - (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); - - return 0; - -unmap: - tasklet_kill(&host->card_tasklet); - tasklet_kill(&host->finish_tasklet); - - iounmap(host->ioaddr); -release: - pci_release_region(pdev, host->bar); -free: - mmc_free_host(mmc); - - return ret; -} - -static void sdhci_remove_slot(struct pci_dev *pdev, int slot) -{ - struct sdhci_chip *chip; - struct mmc_host *mmc; - struct sdhci_host *host; - - chip = pci_get_drvdata(pdev); - host = chip->hosts[slot]; - mmc = host->mmc; - - chip->hosts[slot] = NULL; - - mmc_remove_host(mmc); - - sdhci_reset(host, SDHCI_RESET_ALL); - - free_irq(host->irq, host); - - del_timer_sync(&host->timer); - - tasklet_kill(&host->card_tasklet); - tasklet_kill(&host->finish_tasklet); - - iounmap(host->ioaddr); - - pci_release_region(pdev, host->bar); - - mmc_free_host(mmc); -} - -static int __devinit sdhci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int ret, i; - u8 slots; - struct sdhci_chip *chip; - - BUG_ON(pdev == NULL); - BUG_ON(ent == NULL); - - DBG("found at %s\n", pci_name(pdev)); - - ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); - if (ret) - return ret; - - slots = PCI_SLOT_INFO_SLOTS(slots) + 1; - DBG("found %d slot(s)\n", slots); - if (slots == 0) - return -ENODEV; - - ret = pci_enable_device(pdev); - if (ret) - return ret; - - chip = kzalloc(sizeof(struct sdhci_chip) + - sizeof(struct sdhci_host*) * slots, GFP_KERNEL); - if (!chip) { - ret = -ENOMEM; - goto err; - } - - chip->pdev = pdev; - - chip->num_slots = slots; - pci_set_drvdata(pdev, chip); - - for (i = 0;i < slots;i++) { - ret = sdhci_probe_slot(pdev, i); - if (ret) { - for (i--;i >= 0;i--) - sdhci_remove_slot(pdev, i); - goto free; - } - } - - return 0; - -free: - pci_set_drvdata(pdev, NULL); - kfree(chip); - -err: - pci_disable_device(pdev); - return ret; -} - -static void __devexit sdhci_remove(struct pci_dev *pdev) -{ - int i; - struct sdhci_chip *chip; - - chip = pci_get_drvdata(pdev); - - if (chip) { - for (i = 0;i < chip->num_slots;i++) - sdhci_remove_slot(pdev, i); - - pci_set_drvdata(pdev, NULL); - - kfree(chip); - } - - pci_disable_device(pdev); -} - -static struct pci_driver sdhci_driver = { - .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = sdhci_probe, - .remove = __devexit_p(sdhci_remove), - .suspend = sdhci_suspend, - .resume = sdhci_resume, -}; - -/*****************************************************************************\ - * * - * Driver init/exit * - * * -\*****************************************************************************/ - -static int __init sdhci_drv_init(void) -{ - printk(KERN_INFO DRIVER_NAME - ": Secure Digital Host Controller Interface driver, " - DRIVER_VERSION "\n"); - printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); - - return pci_register_driver(&sdhci_driver); -} - -static void __exit sdhci_drv_exit(void) -{ - DBG("Exiting\n"); - - pci_unregister_driver(&sdhci_driver); -} - -module_init(sdhci_drv_init); -module_exit(sdhci_drv_exit); - -MODULE_AUTHOR("Pierre Ossman "); -MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver"); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/sdhci.h deleted file mode 100644 index 3b270ef48..000000000 --- a/drivers/mmc/sdhci.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * linux/drivers/mmc/sdhci.h - Secure Digital Host Controller Interface driver - * - * Copyright (C) 2005 Pierre Ossman, 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. - */ - -/* - * PCI registers - */ - -#define PCI_SLOT_INFO 0x40 /* 8 bits */ -#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7) -#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07 - -/* - * Controller registers - */ - -#define SDHCI_DMA_ADDRESS 0x00 - -#define SDHCI_BLOCK_SIZE 0x04 - -#define SDHCI_BLOCK_COUNT 0x06 - -#define SDHCI_ARGUMENT 0x08 - -#define SDHCI_TRANSFER_MODE 0x0C -#define SDHCI_TRNS_DMA 0x01 -#define SDHCI_TRNS_BLK_CNT_EN 0x02 -#define SDHCI_TRNS_ACMD12 0x04 -#define SDHCI_TRNS_READ 0x10 -#define SDHCI_TRNS_MULTI 0x20 - -#define SDHCI_COMMAND 0x0E -#define SDHCI_CMD_RESP_MASK 0x03 -#define SDHCI_CMD_CRC 0x08 -#define SDHCI_CMD_INDEX 0x10 -#define SDHCI_CMD_DATA 0x20 - -#define SDHCI_CMD_RESP_NONE 0x00 -#define SDHCI_CMD_RESP_LONG 0x01 -#define SDHCI_CMD_RESP_SHORT 0x02 -#define SDHCI_CMD_RESP_SHORT_BUSY 0x03 - -#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff)) - -#define SDHCI_RESPONSE 0x10 - -#define SDHCI_BUFFER 0x20 - -#define SDHCI_PRESENT_STATE 0x24 -#define SDHCI_CMD_INHIBIT 0x00000001 -#define SDHCI_DATA_INHIBIT 0x00000002 -#define SDHCI_DOING_WRITE 0x00000100 -#define SDHCI_DOING_READ 0x00000200 -#define SDHCI_SPACE_AVAILABLE 0x00000400 -#define SDHCI_DATA_AVAILABLE 0x00000800 -#define SDHCI_CARD_PRESENT 0x00010000 -#define SDHCI_WRITE_PROTECT 0x00080000 - -#define SDHCI_HOST_CONTROL 0x28 -#define SDHCI_CTRL_LED 0x01 -#define SDHCI_CTRL_4BITBUS 0x02 - -#define SDHCI_POWER_CONTROL 0x29 - -#define SDHCI_BLOCK_GAP_CONTROL 0x2A - -#define SDHCI_WALK_UP_CONTROL 0x2B - -#define SDHCI_CLOCK_CONTROL 0x2C -#define SDHCI_DIVIDER_SHIFT 8 -#define SDHCI_CLOCK_CARD_EN 0x0004 -#define SDHCI_CLOCK_INT_STABLE 0x0002 -#define SDHCI_CLOCK_INT_EN 0x0001 - -#define SDHCI_TIMEOUT_CONTROL 0x2E - -#define SDHCI_SOFTWARE_RESET 0x2F -#define SDHCI_RESET_ALL 0x01 -#define SDHCI_RESET_CMD 0x02 -#define SDHCI_RESET_DATA 0x04 - -#define SDHCI_INT_STATUS 0x30 -#define SDHCI_INT_ENABLE 0x34 -#define SDHCI_SIGNAL_ENABLE 0x38 -#define SDHCI_INT_RESPONSE 0x00000001 -#define SDHCI_INT_DATA_END 0x00000002 -#define SDHCI_INT_DMA_END 0x00000008 -#define SDHCI_INT_BUF_EMPTY 0x00000010 -#define SDHCI_INT_BUF_FULL 0x00000020 -#define SDHCI_INT_CARD_INSERT 0x00000040 -#define SDHCI_INT_CARD_REMOVE 0x00000080 -#define SDHCI_INT_CARD_INT 0x00000100 -#define SDHCI_INT_TIMEOUT 0x00010000 -#define SDHCI_INT_CRC 0x00020000 -#define SDHCI_INT_END_BIT 0x00040000 -#define SDHCI_INT_INDEX 0x00080000 -#define SDHCI_INT_DATA_TIMEOUT 0x00100000 -#define SDHCI_INT_DATA_CRC 0x00200000 -#define SDHCI_INT_DATA_END_BIT 0x00400000 -#define SDHCI_INT_BUS_POWER 0x00800000 -#define SDHCI_INT_ACMD12ERR 0x01000000 - -#define SDHCI_INT_NORMAL_MASK 0x00007FFF -#define SDHCI_INT_ERROR_MASK 0xFFFF8000 - -#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ - SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) -#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ - SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL | \ - SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ - SDHCI_INT_DATA_END_BIT) - -#define SDHCI_ACMD12_ERR 0x3C - -/* 3E-3F reserved */ - -#define SDHCI_CAPABILITIES 0x40 -#define SDHCI_CAN_DO_DMA 0x00400000 -#define SDHCI_CLOCK_BASE_MASK 0x00003F00 -#define SDHCI_CLOCK_BASE_SHIFT 8 - -/* 44-47 reserved for more caps */ - -#define SDHCI_MAX_CURRENT 0x48 - -/* 4C-4F reserved for more max current */ - -/* 50-FB reserved */ - -#define SDHCI_SLOT_INT_STATUS 0xFC - -#define SDHCI_HOST_VERSION 0xFE - -struct sdhci_chip; - -struct sdhci_host { - struct sdhci_chip *chip; - struct mmc_host *mmc; /* MMC structure */ - - spinlock_t lock; /* Mutex */ - - int flags; /* Host attributes */ -#define SDHCI_USE_DMA (1<<0) - - unsigned int max_clk; /* Max possible freq (MHz) */ - - unsigned int clock; /* Current clock (MHz) */ - - struct mmc_request *mrq; /* Current request */ - struct mmc_command *cmd; /* Current command */ - struct mmc_data *data; /* Current data request */ - - struct scatterlist *cur_sg; /* We're working on this */ - char *mapped_sg; /* This is where it's mapped */ - int num_sg; /* Entries left */ - int offset; /* Offset into current sg */ - int remain; /* Bytes left in current */ - - int size; /* Remaining bytes in transfer */ - - char slot_descr[20]; /* Name for reservations */ - - int irq; /* Device IRQ */ - int bar; /* PCI BAR index */ - unsigned long addr; /* Bus address */ - void __iomem * ioaddr; /* Mapped address */ - - struct tasklet_struct card_tasklet; /* Tasklet structures */ - struct tasklet_struct finish_tasklet; - - struct timer_list timer; /* Timer for timeouts */ -}; - -struct sdhci_chip { - struct pci_dev *pdev; - - int num_slots; /* Slots on controller */ - struct sdhci_host *hosts[0]; /* Pointers to hosts */ -}; diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 8167332d4..3be397d43 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -44,10 +44,15 @@ #define DRIVER_NAME "wbsd" #define DRIVER_VERSION "1.5" +#ifdef CONFIG_MMC_DEBUG #define DBG(x...) \ - pr_debug(DRIVER_NAME ": " x) + printk(KERN_DEBUG DRIVER_NAME ": " x) #define DBGF(f, x...) \ - pr_debug(DRIVER_NAME " [%s()]: " f, __func__ , ##x) + printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__ , ##x) +#else +#define DBG(x...) do { } while (0) +#define DBGF(x...) do { } while (0) +#endif /* * Device resources @@ -662,14 +667,14 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) unsigned long dmaflags; DBGF("blksz %04x blks %04x flags %08x\n", - data->blksz, data->blocks, data->flags); + 1 << data->blksz_bits, data->blocks, data->flags); DBGF("tsac %d ms nsac %d clk\n", data->timeout_ns / 1000000, data->timeout_clks); /* * Calculate size. */ - host->size = data->blocks * data->blksz; + host->size = data->blocks << data->blksz_bits; /* * Check timeout values for overflow. @@ -696,12 +701,12 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) * Two bytes are needed for each data line. */ if (host->bus_width == MMC_BUS_WIDTH_1) { - blksize = data->blksz + 2; + blksize = (1 << data->blksz_bits) + 2; wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); } else if (host->bus_width == MMC_BUS_WIDTH_4) { - blksize = data->blksz + 2 * 4; + blksize = (1 << data->blksz_bits) + 2 * 4; wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH); @@ -931,6 +936,10 @@ static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) struct wbsd_host *host = mmc_priv(mmc); u8 clk, setup, pwr; + DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", + ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, + ios->vdd, ios->bus_width); + spin_lock_bh(&host->lock); /* diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index a7ec5954c..205bb7083 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -25,8 +25,9 @@ config MTD_JEDECPROBE compatible with the Common Flash Interface, but will use the common CFI-targetted flash drivers for any chips which are identified which are in fact compatible in all but the probe method. This actually - covers most AMD/Fujitsu-compatible chips and also non-CFI - Intel chips. + covers most AMD/Fujitsu-compatible chips, and will shortly cover also + non-CFI Intel chips (that code is in MTD CVS and should shortly be sent + for inclusion in Linus' tree) config MTD_GEN_PROBE tristate @@ -200,6 +201,27 @@ config MTD_CFI_AMDSTD provides support for one of those command sets, used on chips including the AMD Am29LV320. +config MTD_CFI_AMDSTD_RETRY + int "Retry failed commands (erase/program)" + depends on MTD_CFI_AMDSTD + default "0" + help + Some chips, when attached to a shared bus, don't properly filter + bus traffic that is destined to other devices. This broken + behavior causes erase and program sequences to be aborted when + the sequences are mixed with traffic for other devices. + + SST49LF040 (and related) chips are know to be broken. + +config MTD_CFI_AMDSTD_RETRY_MAX + int "Max retries of failed commands (erase/program)" + depends on MTD_CFI_AMDSTD_RETRY + default "0" + help + If you have an SST49LF040 (or related chip) then this value should + be set to at least 1. This can also be adjusted at driver load + time with the retry_cmd_max module parameter. + config MTD_CFI_STAA tristate "Support for ST (Advanced Architecture) flash chips" depends on MTD_GEN_PROBE diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c index 57115618c..fdb91b6f1 100644 --- a/drivers/mtd/chips/amd_flash.c +++ b/drivers/mtd/chips/amd_flash.c @@ -664,7 +664,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) printk("%s: Probing for AMD compatible flash...\n", map->name); if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table, - ARRAY_SIZE(table))) + sizeof(table)/sizeof(table[0]))) == -1) { printk(KERN_WARNING "%s: Found no AMD compatible device at location zero\n", @@ -696,7 +696,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) base += (1 << temp.chipshift)) { int numchips = temp.numchips; table_pos[numchips] = probe_new_chip(mtd, base, chips, - &temp, table, ARRAY_SIZE(table)); + &temp, table, sizeof(table)/sizeof(table[0])); } mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 517ea33e7..edb306c03 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -34,7 +34,6 @@ #define MANUFACTURER_MACRONIX 0x00C2 #define MANUFACTURER_NEC 0x0010 #define MANUFACTURER_PMC 0x009D -#define MANUFACTURER_SHARP 0x00b0 #define MANUFACTURER_SST 0x00BF #define MANUFACTURER_ST 0x0020 #define MANUFACTURER_TOSHIBA 0x0098 @@ -125,9 +124,6 @@ #define PM49FL004 0x006E #define PM49FL008 0x006A -/* Sharp */ -#define LH28F640BF 0x00b0 - /* ST - www.st.com */ #define M29W800DT 0x00D7 #define M29W800DB 0x005B @@ -1271,19 +1267,6 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO( 0x01000, 256 ) } - }, { - .mfr_id = MANUFACTURER_SHARP, - .dev_id = LH28F640BF, - .name = "LH28F640BF", - .uaddr = { - [0] = MTD_UADDR_UNNECESSARY, /* x8 */ - }, - .DevSize = SIZE_4MiB, - .CmdSet = P_ID_INTEL_STD, - .NumEraseRegions= 1, - .regions = { - ERASEINFO(0x40000,16), - } }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39LF512, @@ -2052,7 +2035,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, DEBUG(MTD_DEBUG_LEVEL3, "Search for id:(%02x %02x) interleave(%d) type(%d)\n", cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); - for (i = 0; i < ARRAY_SIZE(jedec_table); i++) { + for (i=0; i\n"); diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index a7a7bfe33..6b8bb2e4d 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -42,8 +42,7 @@ /* special size referring to all the remaining space in a partition */ -#define SIZE_REMAINING UINT_MAX -#define OFFSET_CONTINUOUS UINT_MAX +#define SIZE_REMAINING 0xffffffff struct cmdline_mtd_partition { struct cmdline_mtd_partition *next; @@ -76,7 +75,7 @@ static struct mtd_partition * newpart(char *s, { struct mtd_partition *parts; unsigned long size; - unsigned long offset = OFFSET_CONTINUOUS; + unsigned long offset = 0; char *name; int name_len; unsigned char *extra_mem; @@ -315,7 +314,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, { for(i = 0, offset = 0; i < part->num_parts; i++) { - if (part->parts[i].offset == OFFSET_CONTINUOUS) + if (!part->parts[i].offset) part->parts[i].offset = offset; else offset = part->parts[i].offset; diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 7fac438b5..dd628cb51 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -129,8 +129,8 @@ config MTDRAM_ABS_POS allocating space from Linux's available memory. Otherwise, leave this set to zero. Most people will want to leave this as zero. -config MTD_BLOCK2MTD - tristate "MTD using block device" +config MTD_BLKMTD + tristate "MTD emulation using block device" depends on MTD help This driver allows a block device to appear as an MTD. It would @@ -141,6 +141,15 @@ config MTD_BLOCK2MTD Testing MTD users (eg JFFS2) on large media and media that might be removed during a write (using the floppy drive). +config MTD_BLOCK2MTD + tristate "MTD using block device (rewrite)" + depends on MTD && EXPERIMENTAL + help + This driver is basically the same at MTD_BLKMTD above, but + experienced some interface changes plus serious speedups. In + the long term, it should replace MTD_BLKMTD. Right now, you + shouldn't entrust important data to it yet. + comment "Disk-On-Chip Device Drivers" config MTD_DOC2000 diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index b65736703..7c5ed2178 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_MTD_PMC551) += pmc551.o obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o obj-$(CONFIG_MTD_MTDRAM) += mtdram.o obj-$(CONFIG_MTD_LART) += lart.o +obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c new file mode 100644 index 000000000..04f864d23 --- /dev/null +++ b/drivers/mtd/devices/blkmtd.c @@ -0,0 +1,820 @@ +/* + * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $ + * + * blkmtd.c - use a block device as a fake MTD + * + * Author: Simon Evans + * + * Copyright (C) 2001,2002 Simon Evans + * + * Licence: GPL + * + * How it works: + * The driver uses raw/io to read/write the device and the page + * cache to cache access. Writes update the page cache with the + * new data and mark it dirty and add the page into a BIO which + * is then written out. + * + * It can be loaded Read-Only to prevent erases and writes to the + * medium. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) +#define warn(format, arg...) printk(KERN_WARNING "blkmtd: " format "\n" , ## arg) +#define crit(format, arg...) printk(KERN_CRIT "blkmtd: " format "\n" , ## arg) + + +/* Default erase size in K, always make it a multiple of PAGE_SIZE */ +#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ +#define VERSION "$Revision: 1.27 $" + +/* Info for the block device */ +struct blkmtd_dev { + struct list_head list; + struct block_device *blkdev; + struct mtd_info mtd_info; + struct semaphore wrbuf_mutex; +}; + + +/* Static info about the MTD, used in cleanup_module */ +static LIST_HEAD(blkmtd_device_list); + + +static void blkmtd_sync(struct mtd_info *mtd); + +#define MAX_DEVICES 4 + +/* Module parameters passed by insmod/modprobe */ +static char *device[MAX_DEVICES]; /* the block device to use */ +static int erasesz[MAX_DEVICES]; /* optional default erase size */ +static int ro[MAX_DEVICES]; /* optional read only flag */ +static int sync; + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Simon Evans "); +MODULE_DESCRIPTION("Emulate an MTD using a block device"); +module_param_array(device, charp, NULL, 0); +MODULE_PARM_DESC(device, "block device to use"); +module_param_array(erasesz, int, NULL, 0); +MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB."); +module_param_array(ro, bool, NULL, 0); +MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors"); +module_param(sync, bool, 0); +MODULE_PARM_DESC(sync, "1=Synchronous writes"); + + +/* completion handler for BIO reads */ +static int bi_read_complete(struct bio *bio, unsigned int bytes_done, int error) +{ + if (bio->bi_size) + return 1; + + complete((struct completion*)bio->bi_private); + return 0; +} + + +/* completion handler for BIO writes */ +static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error) +{ + const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); + struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; + + if (bio->bi_size) + return 1; + + if(!uptodate) + err("bi_write_complete: not uptodate\n"); + + do { + struct page *page = bvec->bv_page; + DEBUG(3, "Cleaning up page %ld\n", page->index); + if (--bvec >= bio->bi_io_vec) + prefetchw(&bvec->bv_page->flags); + + if (uptodate) { + SetPageUptodate(page); + } else { + ClearPageUptodate(page); + SetPageError(page); + } + clear_page_dirty(page); + unlock_page(page); + page_cache_release(page); + } while (bvec >= bio->bi_io_vec); + + complete((struct completion*)bio->bi_private); + return 0; +} + + +/* read one page from the block device */ +static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page) +{ + struct bio *bio; + struct completion event; + int err = -ENOMEM; + + if(PageUptodate(page)) { + DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index); + unlock_page(page); + return 0; + } + + ClearPageUptodate(page); + ClearPageError(page); + + bio = bio_alloc(GFP_KERNEL, 1); + if(bio) { + init_completion(&event); + bio->bi_bdev = dev->blkdev; + bio->bi_sector = page->index << (PAGE_SHIFT-9); + bio->bi_private = &event; + bio->bi_end_io = bi_read_complete; + if(bio_add_page(bio, page, PAGE_SIZE, 0) == PAGE_SIZE) { + submit_bio(READ_SYNC, bio); + wait_for_completion(&event); + err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; + bio_put(bio); + } + } + + if(err) + SetPageError(page); + else + SetPageUptodate(page); + flush_dcache_page(page); + unlock_page(page); + return err; +} + + +/* write out the current BIO and wait for it to finish */ +static int blkmtd_write_out(struct bio *bio) +{ + struct completion event; + int err; + + if(!bio->bi_vcnt) { + bio_put(bio); + return 0; + } + + init_completion(&event); + bio->bi_private = &event; + bio->bi_end_io = bi_write_complete; + submit_bio(WRITE_SYNC, bio); + wait_for_completion(&event); + DEBUG(3, "submit_bio completed, bi_vcnt = %d\n", bio->bi_vcnt); + err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; + bio_put(bio); + return err; +} + + +/** + * blkmtd_add_page - add a page to the current BIO + * @bio: bio to add to (NULL to alloc initial bio) + * @blkdev: block device + * @page: page to add + * @pagecnt: pages left to add + * + * Adds a page to the current bio, allocating it if necessary. If it cannot be + * added, the current bio is written out and a new one is allocated. Returns + * the new bio to add or NULL on error + */ +static struct bio *blkmtd_add_page(struct bio *bio, struct block_device *blkdev, + struct page *page, int pagecnt) +{ + + retry: + if(!bio) { + bio = bio_alloc(GFP_KERNEL, pagecnt); + if(!bio) + return NULL; + bio->bi_sector = page->index << (PAGE_SHIFT-9); + bio->bi_bdev = blkdev; + } + + if(bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { + blkmtd_write_out(bio); + bio = NULL; + goto retry; + } + return bio; +} + + +/** + * write_pages - write block of data to device via the page cache + * @dev: device to write to + * @buf: data source or NULL if erase (output is set to 0xff) + * @to: offset into output device + * @len: amount to data to write + * @retlen: amount of data written + * + * Grab pages from the page cache and fill them with the source data. + * Non page aligned start and end result in a readin of the page and + * part of the page being modified. Pages are added to the bio and then written + * out. + */ +static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, + size_t len, size_t *retlen) +{ + int pagenr, offset; + size_t start_len = 0, end_len; + int pagecnt = 0; + int err = 0; + struct bio *bio = NULL; + size_t thislen = 0; + + pagenr = to >> PAGE_SHIFT; + offset = to & ~PAGE_MASK; + + DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %zd pagenr = %d offset = %d\n", + buf, (long)to, len, pagenr, offset); + + /* see if we have to do a partial write at the start */ + if(offset) { + start_len = ((offset + len) > PAGE_SIZE) ? PAGE_SIZE - offset : len; + len -= start_len; + } + + /* calculate the length of the other two regions */ + end_len = len & ~PAGE_MASK; + len -= end_len; + + if(start_len) + pagecnt++; + + if(len) + pagecnt += len >> PAGE_SHIFT; + + if(end_len) + pagecnt++; + + down(&dev->wrbuf_mutex); + + DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", + start_len, len, end_len, pagecnt); + + if(start_len) { + /* do partial start region */ + struct page *page; + + DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %zd offset = %d\n", + pagenr, start_len, offset); + + BUG_ON(!buf); + page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); + lock_page(page); + if(PageDirty(page)) { + err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", + to, start_len, len, end_len, pagenr); + BUG(); + } + memcpy(page_address(page)+offset, buf, start_len); + set_page_dirty(page); + SetPageUptodate(page); + buf += start_len; + thislen = start_len; + bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); + if(!bio) { + err = -ENOMEM; + err("bio_add_page failed\n"); + goto write_err; + } + pagecnt--; + pagenr++; + } + + /* Now do the main loop to a page aligned, n page sized output */ + if(len) { + int pagesc = len >> PAGE_SHIFT; + DEBUG(3, "blkmtd: write: whole pages start = %d, count = %d\n", + pagenr, pagesc); + while(pagesc) { + struct page *page; + + /* see if page is in the page cache */ + DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr); + page = grab_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr); + if(PageDirty(page)) { + BUG(); + } + if(!page) { + warn("write: cannot grab cache page %d", pagenr); + err = -ENOMEM; + goto write_err; + } + if(!buf) { + memset(page_address(page), 0xff, PAGE_SIZE); + } else { + memcpy(page_address(page), buf, PAGE_SIZE); + buf += PAGE_SIZE; + } + bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); + if(!bio) { + err = -ENOMEM; + err("bio_add_page failed\n"); + goto write_err; + } + pagenr++; + pagecnt--; + set_page_dirty(page); + SetPageUptodate(page); + pagesc--; + thislen += PAGE_SIZE; + } + } + + if(end_len) { + /* do the third region */ + struct page *page; + DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %zd\n", + pagenr, end_len); + BUG_ON(!buf); + page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); + lock_page(page); + if(PageDirty(page)) { + err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", + to, start_len, len, end_len, pagenr); + BUG(); + } + memcpy(page_address(page), buf, end_len); + set_page_dirty(page); + SetPageUptodate(page); + DEBUG(3, "blkmtd: write: writing out partial end\n"); + thislen += end_len; + bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); + if(!bio) { + err = -ENOMEM; + err("bio_add_page failed\n"); + goto write_err; + } + pagenr++; + } + + DEBUG(3, "blkmtd: write: got %d vectors to write\n", bio->bi_vcnt); + write_err: + if(bio) + blkmtd_write_out(bio); + + DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); + up(&dev->wrbuf_mutex); + + if(retlen) + *retlen = thislen; + return err; +} + + +/* erase a specified part of the device */ +static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + struct blkmtd_dev *dev = mtd->priv; + struct mtd_erase_region_info *einfo = mtd->eraseregions; + int numregions = mtd->numeraseregions; + size_t from; + u_long len; + int err = -EIO; + size_t retlen; + + instr->state = MTD_ERASING; + from = instr->addr; + len = instr->len; + + /* check erase region has valid start and length */ + DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%zx len = 0x%lx\n", + mtd->name+9, from, len); + while(numregions) { + DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n", + einfo->offset, einfo->erasesize, einfo->numblocks); + if(from >= einfo->offset + && from < einfo->offset + (einfo->erasesize * einfo->numblocks)) { + if(len == einfo->erasesize + && ( (from - einfo->offset) % einfo->erasesize == 0)) + break; + } + numregions--; + einfo++; + } + + if(!numregions) { + /* Not a valid erase block */ + err("erase: invalid erase request 0x%lX @ 0x%08zX", len, from); + instr->state = MTD_ERASE_FAILED; + err = -EIO; + } + + if(instr->state != MTD_ERASE_FAILED) { + /* do the erase */ + DEBUG(3, "Doing erase from = %zd len = %ld\n", from, len); + err = write_pages(dev, NULL, from, len, &retlen); + if(err || retlen != len) { + err("erase failed err = %d", err); + instr->state = MTD_ERASE_FAILED; + } else { + instr->state = MTD_ERASE_DONE; + } + } + + DEBUG(3, "blkmtd: erase: checking callback\n"); + mtd_erase_callback(instr); + DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err); + return err; +} + + +/* read a range of the data via the page cache */ +static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct blkmtd_dev *dev = mtd->priv; + int err = 0; + int offset; + int pagenr, pages; + size_t thislen = 0; + + DEBUG(2, "blkmtd: read: dev = `%s' from = %lld len = %zd buf = %p\n", + mtd->name+9, from, len, buf); + + if(from > mtd->size) + return -EINVAL; + if(from + len > mtd->size) + len = mtd->size - from; + + pagenr = from >> PAGE_SHIFT; + offset = from - (pagenr << PAGE_SHIFT); + + pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT; + DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n", + pagenr, offset, pages); + + while(pages) { + struct page *page; + int cpylen; + + DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr); + page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); + if(IS_ERR(page)) { + err = -EIO; + goto readerr; + } + + cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE; + if(offset+cpylen > PAGE_SIZE) + cpylen = PAGE_SIZE-offset; + + memcpy(buf + thislen, page_address(page) + offset, cpylen); + offset = 0; + len -= cpylen; + thislen += cpylen; + pagenr++; + pages--; + if(!PageDirty(page)) + page_cache_release(page); + } + + readerr: + if(retlen) + *retlen = thislen; + DEBUG(2, "blkmtd: end read: retlen = %zd, err = %d\n", thislen, err); + return err; +} + + +/* write data to the underlying device */ +static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + struct blkmtd_dev *dev = mtd->priv; + int err; + + if(!len) + return 0; + + DEBUG(2, "blkmtd: write: dev = `%s' to = %lld len = %zd buf = %p\n", + mtd->name+9, to, len, buf); + + if(to >= mtd->size) { + return -ENOSPC; + } + + if(to + len > mtd->size) { + len = mtd->size - to; + } + + err = write_pages(dev, buf, to, len, retlen); + if(err > 0) + err = 0; + DEBUG(2, "blkmtd: write: end, err = %d\n", err); + return err; +} + + +/* sync the device - wait until the write queue is empty */ +static void blkmtd_sync(struct mtd_info *mtd) +{ + /* Currently all writes are synchronous */ +} + + +static void free_device(struct blkmtd_dev *dev) +{ + DEBUG(2, "blkmtd: free_device() dev = %p\n", dev); + if(dev) { + kfree(dev->mtd_info.eraseregions); + kfree(dev->mtd_info.name); + if(dev->blkdev) { + invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); + close_bdev_excl(dev->blkdev); + } + kfree(dev); + } +} + + +/* For a given size and initial erase size, calculate the number + * and size of each erase region. Goes round the loop twice, + * once to find out how many regions, then allocates space, + * then round the loop again to fill it in. + */ +static struct mtd_erase_region_info *calc_erase_regions( + size_t erase_size, size_t total_size, int *regions) +{ + struct mtd_erase_region_info *info = NULL; + + DEBUG(2, "calc_erase_regions, es = %zd size = %zd regions = %d\n", + erase_size, total_size, *regions); + /* Make any user specified erasesize be a power of 2 + and at least PAGE_SIZE */ + if(erase_size) { + int es = erase_size; + erase_size = 1; + while(es != 1) { + es >>= 1; + erase_size <<= 1; + } + if(erase_size < PAGE_SIZE) + erase_size = PAGE_SIZE; + } else { + erase_size = CONFIG_MTD_BLKDEV_ERASESIZE; + } + + *regions = 0; + + do { + int tot_size = total_size; + int er_size = erase_size; + int count = 0, offset = 0, regcnt = 0; + + while(tot_size) { + count = tot_size / er_size; + if(count) { + tot_size = tot_size % er_size; + if(info) { + DEBUG(2, "adding to erase info off=%d er=%d cnt=%d\n", + offset, er_size, count); + (info+regcnt)->offset = offset; + (info+regcnt)->erasesize = er_size; + (info+regcnt)->numblocks = count; + (*regions)++; + } + regcnt++; + offset += (count * er_size); + } + while(er_size > tot_size) + er_size >>= 1; + } + if(info == NULL) { + info = kmalloc(regcnt * sizeof(struct mtd_erase_region_info), GFP_KERNEL); + if(!info) + break; + } + } while(!(*regions)); + DEBUG(2, "calc_erase_regions done, es = %zd size = %zd regions = %d\n", + erase_size, total_size, *regions); + return info; +} + + +extern dev_t __init name_to_dev_t(const char *line); + +static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) +{ + struct block_device *bdev; + int mode; + struct blkmtd_dev *dev; + + if(!devname) + return NULL; + + /* Get a handle on the device */ + + +#ifdef MODULE + mode = (readonly) ? O_RDONLY : O_RDWR; + bdev = open_bdev_excl(devname, mode, NULL); +#else + mode = (readonly) ? FMODE_READ : FMODE_WRITE; + bdev = open_by_devnum(name_to_dev_t(devname), mode); +#endif + if(IS_ERR(bdev)) { + err("error: cannot open device %s", devname); + DEBUG(2, "blkmtd: opening bdev returned %ld\n", PTR_ERR(bdev)); + return NULL; + } + + DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n", + MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); + + if(MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { + err("attempting to use an MTD device as a block device"); + blkdev_put(bdev); + return NULL; + } + + dev = kmalloc(sizeof(struct blkmtd_dev), GFP_KERNEL); + if(dev == NULL) { + blkdev_put(bdev); + return NULL; + } + + memset(dev, 0, sizeof(struct blkmtd_dev)); + dev->blkdev = bdev; + if(!readonly) { + init_MUTEX(&dev->wrbuf_mutex); + } + + dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; + + /* Setup the MTD structure */ + /* make the name contain the block device in */ + dev->mtd_info.name = kmalloc(sizeof("blkmtd: ") + strlen(devname), GFP_KERNEL); + if(dev->mtd_info.name == NULL) + goto devinit_err; + + sprintf(dev->mtd_info.name, "blkmtd: %s", devname); + dev->mtd_info.eraseregions = calc_erase_regions(erase_size, dev->mtd_info.size, + &dev->mtd_info.numeraseregions); + if(dev->mtd_info.eraseregions == NULL) + goto devinit_err; + + dev->mtd_info.erasesize = dev->mtd_info.eraseregions->erasesize; + DEBUG(1, "blkmtd: init: found %d erase regions\n", + dev->mtd_info.numeraseregions); + + if(readonly) { + dev->mtd_info.type = MTD_ROM; + dev->mtd_info.flags = MTD_CAP_ROM; + } else { + dev->mtd_info.type = MTD_RAM; + dev->mtd_info.flags = MTD_CAP_RAM; + dev->mtd_info.erase = blkmtd_erase; + dev->mtd_info.write = blkmtd_write; + dev->mtd_info.writev = default_mtd_writev; + dev->mtd_info.sync = blkmtd_sync; + } + dev->mtd_info.read = blkmtd_read; + dev->mtd_info.readv = default_mtd_readv; + dev->mtd_info.priv = dev; + dev->mtd_info.owner = THIS_MODULE; + + list_add(&dev->list, &blkmtd_device_list); + if (add_mtd_device(&dev->mtd_info)) { + /* Device didnt get added, so free the entry */ + list_del(&dev->list); + goto devinit_err; + } else { + info("mtd%d: [%s] erase_size = %dKiB %s", + dev->mtd_info.index, dev->mtd_info.name + strlen("blkmtd: "), + dev->mtd_info.erasesize >> 10, + readonly ? "(read-only)" : ""); + } + + return dev; + + devinit_err: + free_device(dev); + return NULL; +} + + +/* Cleanup and exit - sync the device and kill of the kernel thread */ +static void __devexit cleanup_blkmtd(void) +{ + struct list_head *temp1, *temp2; + + /* Remove the MTD devices */ + list_for_each_safe(temp1, temp2, &blkmtd_device_list) { + struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev, + list); + blkmtd_sync(&dev->mtd_info); + del_mtd_device(&dev->mtd_info); + info("mtd%d: [%s] removed", dev->mtd_info.index, + dev->mtd_info.name + strlen("blkmtd: ")); + list_del(&dev->list); + free_device(dev); + } +} + +#ifndef MODULE + +/* Handle kernel boot params */ + + +static int __init param_blkmtd_device(char *str) +{ + int i; + + for(i = 0; i < MAX_DEVICES; i++) { + device[i] = str; + DEBUG(2, "blkmtd: device setup: %d = %s\n", i, device[i]); + strsep(&str, ","); + } + return 1; +} + + +static int __init param_blkmtd_erasesz(char *str) +{ + int i; + for(i = 0; i < MAX_DEVICES; i++) { + char *val = strsep(&str, ","); + if(val) + erasesz[i] = simple_strtoul(val, NULL, 0); + DEBUG(2, "blkmtd: erasesz setup: %d = %d\n", i, erasesz[i]); + } + + return 1; +} + + +static int __init param_blkmtd_ro(char *str) +{ + int i; + for(i = 0; i < MAX_DEVICES; i++) { + char *val = strsep(&str, ","); + if(val) + ro[i] = simple_strtoul(val, NULL, 0); + DEBUG(2, "blkmtd: ro setup: %d = %d\n", i, ro[i]); + } + + return 1; +} + + +static int __init param_blkmtd_sync(char *str) +{ + if(str[0] == '1') + sync = 1; + return 1; +} + +__setup("blkmtd_device=", param_blkmtd_device); +__setup("blkmtd_erasesz=", param_blkmtd_erasesz); +__setup("blkmtd_ro=", param_blkmtd_ro); +__setup("blkmtd_sync=", param_blkmtd_sync); + +#endif + + +/* Startup */ +static int __init init_blkmtd(void) +{ + int i; + + info("version " VERSION); + /* Check args - device[0] is the bare minimum*/ + if(!device[0]) { + err("error: missing `device' name\n"); + return -EINVAL; + } + + for(i = 0; i < MAX_DEVICES; i++) + add_device(device[i], ro[i], erasesz[i] << 10); + + if(list_empty(&blkmtd_device_list)) + return -EINVAL; + + return 0; +} + +module_init(init_blkmtd); +module_exit(cleanup_blkmtd); diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 4160b8334..7ff403b2a 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -18,7 +18,6 @@ #include #include #include -#include #define VERSION "$Revision: 1.30 $" @@ -32,7 +31,7 @@ struct block2mtd_dev { struct list_head list; struct block_device *blkdev; struct mtd_info mtd; - struct mutex write_mutex; + struct semaphore write_mutex; }; @@ -135,9 +134,9 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr) int err; instr->state = MTD_ERASING; - mutex_lock(&dev->write_mutex); + down(&dev->write_mutex); err = _block2mtd_erase(dev, from, len); - mutex_unlock(&dev->write_mutex); + up(&dev->write_mutex); if (err) { ERROR("erase failed err = %d", err); instr->state = MTD_ERASE_FAILED; @@ -250,9 +249,9 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, if (to + len > mtd->size) len = mtd->size - to; - mutex_lock(&dev->write_mutex); + down(&dev->write_mutex); err = _block2mtd_write(dev, buf, to, len, retlen); - mutex_unlock(&dev->write_mutex); + up(&dev->write_mutex); if (err > 0) err = 0; return err; @@ -311,7 +310,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) goto devinit_err; } - mutex_init(&dev->write_mutex); + init_MUTEX(&dev->write_mutex); /* Setup the MTD structure */ /* make the name contain the block device in */ diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index 23e7a5c7d..e4345cf74 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -606,7 +605,7 @@ static void DoC2k_init(struct mtd_info *mtd) this->curfloor = -1; this->curchip = -1; - mutex_init(&this->lock); + init_MUTEX(&this->lock); /* Ident all the chips present. */ DoC_ScanChips(this, maxchips); @@ -646,7 +645,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, if (from >= this->totlen) return -EINVAL; - mutex_lock(&this->lock); + down(&this->lock); *retlen = 0; while (left) { @@ -775,7 +774,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, buf += len; } - mutex_unlock(&this->lock); + up(&this->lock); return ret; } @@ -804,7 +803,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, if (to >= this->totlen) return -EINVAL; - mutex_lock(&this->lock); + down(&this->lock); *retlen = 0; while (left) { @@ -874,7 +873,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; - mutex_unlock(&this->lock); + up(&this->lock); return -EIO; } @@ -936,7 +935,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; - mutex_unlock(&this->lock); + up(&this->lock); return -EIO; } @@ -957,7 +956,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); if (ret) { - mutex_unlock(&this->lock); + up(&this->lock); return ret; } } @@ -967,7 +966,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, buf += len; } - mutex_unlock(&this->lock); + up(&this->lock); return 0; } @@ -976,13 +975,13 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, u_char *eccbuf, struct nand_oobinfo *oobsel) { static char static_buf[512]; - static DEFINE_MUTEX(writev_buf_mutex); + static DECLARE_MUTEX(writev_buf_sem); size_t totretlen = 0; size_t thisvecofs = 0; int ret= 0; - mutex_lock(&writev_buf_mutex); + down(&writev_buf_sem); while(count) { size_t thislen, thisretlen; @@ -1025,7 +1024,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, to += thislen; } - mutex_unlock(&writev_buf_mutex); + up(&writev_buf_sem); *retlen = totretlen; return ret; } @@ -1038,7 +1037,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, int len256 = 0, ret; struct Nand *mychip; - mutex_lock(&this->lock); + down(&this->lock); mychip = &this->chips[ofs >> this->chipshift]; @@ -1084,7 +1083,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ret = DoC_WaitReady(this); - mutex_unlock(&this->lock); + up(&this->lock); return ret; } @@ -1198,10 +1197,10 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, struct DiskOnChip *this = mtd->priv; int ret; - mutex_lock(&this->lock); + down(&this->lock); ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf); - mutex_unlock(&this->lock); + up(&this->lock); return ret; } @@ -1215,10 +1214,10 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) struct Nand *mychip; int status; - mutex_lock(&this->lock); + down(&this->lock); if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) { - mutex_unlock(&this->lock); + up(&this->lock); return -EINVAL; } @@ -1266,7 +1265,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) callback: mtd_erase_callback(instr); - mutex_unlock(&this->lock); + up(&this->lock); return 0; } diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 29b0ddaa3..1e876fcb0 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -581,6 +581,8 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen /***************************************************************************************************/ +#define NB_OF(x) (sizeof (x) / sizeof (x[0])) + static struct mtd_info mtd; static struct mtd_erase_region_info erase_regions[] = { @@ -638,7 +640,7 @@ int __init lart_flash_init (void) mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; - mtd.numeraseregions = ARRAY_SIZE(erase_regions); + mtd.numeraseregions = NB_OF (erase_regions); mtd.eraseregions = erase_regions; mtd.erase = flash_erase; mtd.read = flash_read; @@ -668,9 +670,9 @@ int __init lart_flash_init (void) result,mtd.eraseregions[result].numblocks); #ifdef HAVE_PARTITIONS - printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions)); + printk ("\npartitions = %d\n",NB_OF (lart_partitions)); - for (result = 0; result < ARRAY_SIZE(lart_partitions); result++) + for (result = 0; result < NB_OF (lart_partitions); result++) printk (KERN_DEBUG "\n\n" "lart_partitions[%d].name = %s\n" @@ -685,7 +687,7 @@ int __init lart_flash_init (void) #ifndef HAVE_PARTITIONS result = add_mtd_device (&mtd); #else - result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions)); + result = add_mtd_partitions (&mtd,lart_partitions,NB_OF (lart_partitions)); #endif return (result); diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 04e65d5da..d5f24089b 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -186,7 +186,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) struct m25p *flash = mtd_to_m25p(mtd); u32 addr,len; - DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n", + DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", flash->spi->dev.bus_id, __FUNCTION__, "at", (u32)instr->addr, instr->len); diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 485f66349..0ff2e4378 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c @@ -308,7 +308,7 @@ static int __init ms02nv_init(void) break; } - for (i = 0; i < ARRAY_SIZE(ms02nv_addrs); i++) + for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++) if (!ms02nv_init_one(ms02nv_addrs[i] << stride)) count++; diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index a19480d07..dabffa280 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -536,7 +536,7 @@ static int __devinit dataflash_probe(struct spi_device *spi) if (status <= 0 || status == 0xff) { DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n", spi->dev.bus_id, status); - if (status == 0xff) + if (status == 0 || status == 0xff) status = -ENODEV; return status; } diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index a3b924797..8a5448901 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c @@ -47,6 +47,9 @@ */ #define MAX_LOOPS 10000 +extern void INFTL_dumptables(struct INFTLrecord *inftl); +extern void INFTL_dumpVUchains(struct INFTLrecord *inftl); + static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { struct INFTLrecord *inftl; @@ -129,7 +132,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) return; } #ifdef PSYCHO_DEBUG - printk(KERN_INFO "INFTL: Found new inftl%c\n", inftl->mbd.devnum + 'a'); + printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); #endif return; } @@ -882,6 +885,8 @@ static struct mtd_blktrans_ops inftl_tr = { .owner = THIS_MODULE, }; +extern char inftlmountrev[]; + static int __init init_inftl(void) { printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, " diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c index b933a2a27..a57791a6c 100644 --- a/drivers/mtd/maps/alchemy-flash.c +++ b/drivers/mtd/maps/alchemy-flash.c @@ -126,6 +126,8 @@ static struct mtd_partition alchemy_partitions[] = { } }; +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + static struct mtd_info *mymtd; int __init alchemy_mtd_init(void) @@ -152,7 +154,7 @@ int __init alchemy_mtd_init(void) * Static partition definition selection */ parts = alchemy_partitions; - nb_parts = ARRAY_SIZE(alchemy_partitions); + nb_parts = NB_OF(alchemy_partitions); alchemy_map.size = window_size; /* diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c index fd0f0d318..6a8c0415b 100644 --- a/drivers/mtd/maps/cfi_flagadm.c +++ b/drivers/mtd/maps/cfi_flagadm.c @@ -86,7 +86,7 @@ struct mtd_partition flagadm_parts[] = { } }; -#define PARTITION_COUNT ARRAY_SIZE(flagadm_parts) +#define PARTITION_COUNT (sizeof(flagadm_parts)/sizeof(struct mtd_partition)) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c index 652813cd6..49d90542f 100644 --- a/drivers/mtd/maps/dbox2-flash.c +++ b/drivers/mtd/maps/dbox2-flash.c @@ -57,7 +57,7 @@ static struct mtd_partition partition_info[]= { } }; -#define NUM_PARTITIONS ARRAY_SIZE(partition_info) +#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0])) #define WINDOW_ADDR 0x10000000 #define WINDOW_SIZE 0x800000 diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c index c299d10b3..b51c75781 100644 --- a/drivers/mtd/maps/dilnetpc.c +++ b/drivers/mtd/maps/dilnetpc.c @@ -218,8 +218,8 @@ static void dnp_set_vpp(struct map_info *not_used, int on) { if(--vpp_counter == 0) setcsc(CSC_RBWR, getcsc(CSC_RBWR) | 0x4); - else - BUG_ON(vpp_counter < 0); + else if(vpp_counter < 0) + BUG(); } spin_unlock_irq(&dnpc_spin); } @@ -240,8 +240,8 @@ static void adnp_set_vpp(struct map_info *not_used, int on) { if(--vpp_counter == 0) setcsc(CSC_RBWR, getcsc(CSC_RBWR) | 0x8); - else - BUG_ON(vpp_counter < 0); + else if(vpp_counter < 0) + BUG(); } spin_unlock_irq(&dnpc_spin); } @@ -300,7 +300,7 @@ static struct mtd_partition partition_info[]= }, }; -#define NUM_PARTITIONS ARRAY_SIZE(partition_info) +#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) static struct mtd_info *mymtd; static struct mtd_info *lowlvl_parts[NUM_PARTITIONS]; @@ -345,7 +345,7 @@ static struct mtd_partition higlvl_partition_info[]= }, }; -#define NUM_HIGHLVL_PARTITIONS ARRAY_SIZE(higlvl_partition_info) +#define NUM_HIGHLVL_PARTITIONS (sizeof(higlvl_partition_info)/sizeof(partition_info[0])) static int dnp_adnp_probe(void) diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c index 2bb3c0f0f..b993ac01a 100644 --- a/drivers/mtd/maps/dmv182.c +++ b/drivers/mtd/maps/dmv182.c @@ -99,7 +99,7 @@ static struct mtd_info *this_mtd; static int __init init_svme182(void) { struct mtd_partition *partitions; - int num_parts = ARRAY_SIZE(svme182_partitions); + int num_parts = sizeof(svme182_partitions) / sizeof(struct mtd_partition); partitions = svme182_partitions; diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c index 0667101cc..319094821 100644 --- a/drivers/mtd/maps/h720x-flash.c +++ b/drivers/mtd/maps/h720x-flash.c @@ -59,7 +59,7 @@ static struct mtd_partition h720x_partitions[] = { } }; -#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions) +#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0])) static int nr_mtd_parts; static struct mtd_partition *mtd_parts; diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c index ed2154701..33060a315 100644 --- a/drivers/mtd/maps/netsc520.c +++ b/drivers/mtd/maps/netsc520.c @@ -76,7 +76,7 @@ static struct mtd_partition partition_info[]={ .size = 0x80000 }, }; -#define NUM_PARTITIONS ARRAY_SIZE(partition_info) +#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) #define WINDOW_SIZE 0x00100000 #define WINDOW_ADDR 0x00200000 @@ -88,7 +88,7 @@ static struct map_info netsc520_map = { .phys = WINDOW_ADDR, }; -#define NUM_FLASH_BANKS ARRAY_SIZE(netsc520_map) +#define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info)) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c index 54a3102ab..632eb2aa9 100644 --- a/drivers/mtd/maps/nettel.c +++ b/drivers/mtd/maps/nettel.c @@ -128,7 +128,8 @@ static struct mtd_partition nettel_amd_partitions[] = { } }; -#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions) +#define NUM_AMD_PARTITIONS \ + (sizeof(nettel_amd_partitions)/sizeof(nettel_amd_partitions[0])) /****************************************************************************/ diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c index a21fcd195..c223514ca 100644 --- a/drivers/mtd/maps/ocotea.c +++ b/drivers/mtd/maps/ocotea.c @@ -58,6 +58,8 @@ static struct mtd_partition ocotea_large_partitions[] = { } }; +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + int __init init_ocotea(void) { u8 fpga0_reg; @@ -95,7 +97,7 @@ int __init init_ocotea(void) if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ocotea_small_partitions, - ARRAY_SIZE(ocotea_small_partitions)); + NB_OF(ocotea_small_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; @@ -116,7 +118,7 @@ int __init init_ocotea(void) if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ocotea_large_partitions, - ARRAY_SIZE(ocotea_large_partitions)); + NB_OF(ocotea_large_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index d2ab1bae9..21822c2ed 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c @@ -334,6 +334,9 @@ mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return 0; release: + if (mtd) + map_destroy(mtd); + if (map) { map->exit(dev, map); kfree(map); diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index d27f4129a..f0f8916da 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -28,7 +28,7 @@ #ifdef CONFIG_MTD_DEBUG static int debug = CONFIG_MTD_DEBUG_VERBOSE; -module_param(debug, int, 0); +MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy"); #undef DEBUG #define DEBUG(n, format, arg...) \ @@ -54,7 +54,7 @@ static const int debug = 0; #define MAX_PCMCIA_ADDR 0x4000000 struct pcmciamtd_dev { - struct pcmcia_device *p_dev; + dev_link_t link; /* PCMCIA link */ dev_node_t node; /* device node */ caddr_t win_base; /* ioremapped address of PCMCIA window */ unsigned int win_size; /* size of window */ @@ -89,17 +89,17 @@ static int mem_type; MODULE_LICENSE("GPL"); MODULE_AUTHOR("Simon Evans "); MODULE_DESCRIPTION(DRIVER_DESC); -module_param(bankwidth, int, 0); +MODULE_PARM(bankwidth, "i"); MODULE_PARM_DESC(bankwidth, "Set bankwidth (1=8 bit, 2=16 bit, default=2)"); -module_param(mem_speed, int, 0); +MODULE_PARM(mem_speed, "i"); MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns"); -module_param(force_size, int, 0); +MODULE_PARM(force_size, "i"); MODULE_PARM_DESC(force_size, "Force size of card in MiB (1-64)"); -module_param(setvpp, int, 0); +MODULE_PARM(setvpp, "i"); MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)"); -module_param(vpp, int, 0); +MODULE_PARM(vpp, "i"); MODULE_PARM_DESC(vpp, "Vpp value in 1/10ths eg 33=3.3V 120=12V (Dangerous)"); -module_param(mem_type, int, 0); +MODULE_PARM(mem_type, "i"); MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)"); @@ -111,8 +111,8 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) memreq_t mrq; int ret; - if (!pcmcia_dev_present(dev->p_dev)) { - DEBUG(1, "device removed"); + if(!(dev->link.state & DEV_PRESENT)) { + DEBUG(1, "device removed state = 0x%4.4X", dev->link.state); return 0; } @@ -122,7 +122,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) dev->offset, mrq.CardOffset); mrq.Page = 0; if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) { - cs_error(dev->p_dev, MapMemPage, ret); + cs_error(dev->link.handle, MapMemPage, ret); return NULL; } dev->offset = mrq.CardOffset; @@ -238,7 +238,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v /* read/write{8,16} copy_{from,to} routines with direct access */ -#define DEV_REMOVED(x) (!(pcmcia_dev_present(((struct pcmciamtd_dev *)map->map_priv_1)->p_dev))) +#define DEV_REMOVED(x) (!(*(u_int *)x->map_priv_1 & DEV_PRESENT)) static map_word pcmcia_read8(struct map_info *map, unsigned long ofs) { @@ -319,7 +319,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f static void pcmciamtd_set_vpp(struct map_info *map, int on) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; - struct pcmcia_device *link = dev->p_dev; + dev_link_t *link = &dev->link; modconf_t mod; int ret; @@ -328,9 +328,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0; DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); - ret = pcmcia_modify_configuration(link, &mod); + ret = pcmcia_modify_configuration(link->handle, &mod); if(ret != CS_SUCCESS) { - cs_error(link, ModifyConfiguration, ret); + cs_error(link->handle, ModifyConfiguration, ret); } } @@ -340,7 +340,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) * still open, this will be postponed until it is closed. */ -static void pcmciamtd_release(struct pcmcia_device *link) +static void pcmciamtd_release(dev_link_t *link) { struct pcmciamtd_dev *dev = link->priv; @@ -353,11 +353,12 @@ static void pcmciamtd_release(struct pcmcia_device *link) } pcmcia_release_window(link->win); } - pcmcia_disable_device(link); + pcmcia_release_configuration(link->handle); + link->state &= ~DEV_CONFIG; } -static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) +static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_name) { int rc; tuple_t tuple; @@ -370,16 +371,16 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, tuple.TupleOffset = 0; tuple.DesiredTuple = RETURN_FIRST_TUPLE; - rc = pcmcia_get_first_tuple(link, &tuple); + rc = pcmcia_get_first_tuple(link->handle, &tuple); while(rc == CS_SUCCESS) { - rc = pcmcia_get_tuple_data(link, &tuple); + rc = pcmcia_get_tuple_data(link->handle, &tuple); if(rc != CS_SUCCESS) { - cs_error(link, GetTupleData, rc); + cs_error(link->handle, GetTupleData, rc); break; } - rc = pcmcia_parse_tuple(link, &tuple, &parse); + rc = pcmcia_parse_tuple(link->handle, &tuple, &parse); if(rc != CS_SUCCESS) { - cs_error(link, ParseTuple, rc); + cs_error(link->handle, ParseTuple, rc); break; } @@ -450,7 +451,7 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); } - rc = pcmcia_get_next_tuple(link, &tuple); + rc = pcmcia_get_next_tuple(link->handle, &tuple); } if(!dev->pcmcia_map.size) dev->pcmcia_map.size = MAX_PCMCIA_ADDR; @@ -487,7 +488,7 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int pcmciamtd_config(struct pcmcia_device *link) +static void pcmciamtd_config(dev_link_t *link) { struct pcmciamtd_dev *dev = link->priv; struct mtd_info *mtd = NULL; @@ -503,10 +504,13 @@ static int pcmciamtd_config(struct pcmcia_device *link) DEBUG(3, "link=0x%p", link); + /* Configure card */ + link->state |= DEV_CONFIG; + DEBUG(2, "Validating CIS"); - ret = pcmcia_validate_cis(link, &cisinfo); + ret = pcmcia_validate_cis(link->handle, &cisinfo); if(ret != CS_SUCCESS) { - cs_error(link, GetTupleData, ret); + cs_error(link->handle, GetTupleData, ret); } else { DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains); } @@ -534,7 +538,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; req.Base = 0; req.AccessSpeed = mem_speed; - link->win = (window_handle_t)link; + link->win = (window_handle_t)link->handle; req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR; dev->win_size = 0; @@ -542,7 +546,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) int ret; DEBUG(2, "requesting window with size = %dKiB memspeed = %d", req.Size >> 10, req.AccessSpeed); - ret = pcmcia_request_window(&link, &req, &link->win); + ret = pcmcia_request_window(&link->handle, &req, &link->win); DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); if(ret) { req.Size >>= 1; @@ -558,19 +562,19 @@ static int pcmciamtd_config(struct pcmcia_device *link) if(!dev->win_size) { err("Cant allocate memory window"); pcmciamtd_release(link); - return -ENODEV; + return; } DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); /* Get write protect status */ - CS_CHECK(GetStatus, pcmcia_get_status(link, &status)); + CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", status.CardState, (unsigned long)link->win); dev->win_base = ioremap(req.Base, req.Size); if(!dev->win_base) { err("ioremap(%lu, %u) failed", req.Base, req.Size); pcmciamtd_release(link); - return -ENODEV; + return; } DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", dev, req.Base, dev->win_base, req.Size); @@ -580,14 +584,17 @@ static int pcmciamtd_config(struct pcmcia_device *link) dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; DEBUG(2, "Getting configuration"); - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t)); + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link->handle, &t)); DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2); dev->vpp = (vpp) ? vpp : t.Vpp1; link->conf.Attributes = 0; + link->conf.Vcc = t.Vcc; if(setvpp == 2) { - link->conf.Vpp = dev->vpp; + link->conf.Vpp1 = dev->vpp; + link->conf.Vpp2 = dev->vpp; } else { - link->conf.Vpp = 0; + link->conf.Vpp1 = 0; + link->conf.Vpp2 = 0; } link->conf.IntType = INT_MEMORY; @@ -599,10 +606,9 @@ static int pcmciamtd_config(struct pcmcia_device *link) link->conf.ConfigIndex = 0; link->conf.Present = t.Present; DEBUG(2, "Setting Configuration"); - ret = pcmcia_request_configuration(link, &link->conf); + ret = pcmcia_request_configuration(link->handle, &link->conf); if(ret != CS_SUCCESS) { - cs_error(link, RequestConfiguration, ret); - return -ENODEV; + cs_error(link->handle, RequestConfiguration, ret); } if(mem_type == 1) { @@ -610,7 +616,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) } else if(mem_type == 2) { mtd = do_map_probe("map_rom", &dev->pcmcia_map); } else { - for(i = 0; i < ARRAY_SIZE(probes); i++) { + for(i = 0; i < sizeof(probes) / sizeof(char *); i++) { DEBUG(1, "Trying %s", probes[i]); mtd = do_map_probe(probes[i], &dev->pcmcia_map); if(mtd) @@ -623,7 +629,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) if(!mtd) { DEBUG(1, "Cant find an MTD"); pcmciamtd_release(link); - return -ENODEV; + return; } dev->mtd_info = mtd; @@ -648,6 +654,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) use the faster non-remapping read/write functions */ if(mtd->size <= dev->win_size) { DEBUG(1, "Using non remapping memory functions"); + dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state); dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base; if (dev->pcmcia_map.bankwidth == 1) { dev->pcmcia_map.read = pcmcia_read8; @@ -665,18 +672,19 @@ static int pcmciamtd_config(struct pcmcia_device *link) dev->mtd_info = NULL; err("Couldnt register MTD device"); pcmciamtd_release(link); - return -ENODEV; + return; } snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index); info("mtd%d: %s", mtd->index, mtd->name); - link->dev_node = &dev->node; - return 0; + link->state &= ~DEV_CONFIG_PENDING; + link->dev = &dev->node; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); err("CS Error, exiting"); pcmciamtd_release(link); - return -ENODEV; + return; } @@ -705,18 +713,21 @@ static int pcmciamtd_resume(struct pcmcia_device *dev) * when the device is released. */ -static void pcmciamtd_detach(struct pcmcia_device *link) +static void pcmciamtd_detach(struct pcmcia_device *p_dev) { - struct pcmciamtd_dev *dev = link->priv; + dev_link_t *link = dev_to_instance(p_dev); DEBUG(3, "link=0x%p", link); - if(dev->mtd_info) { - del_mtd_device(dev->mtd_info); - info("mtd%d: Removed", dev->mtd_info->index); - } + if(link->state & DEV_CONFIG) { + struct pcmciamtd_dev *dev = link->priv; + if(dev->mtd_info) { + del_mtd_device(dev->mtd_info); + info("mtd%d: Removed", dev->mtd_info->index); + } - pcmciamtd_release(link); + pcmciamtd_release(link); + } } @@ -725,9 +736,10 @@ static void pcmciamtd_detach(struct pcmcia_device *link) * with Card Services. */ -static int pcmciamtd_probe(struct pcmcia_device *link) +static int pcmciamtd_attach(struct pcmcia_device *p_dev) { struct pcmciamtd_dev *dev; + dev_link_t *link; /* Create new memory card device */ dev = kmalloc(sizeof(*dev), GFP_KERNEL); @@ -735,13 +747,20 @@ static int pcmciamtd_probe(struct pcmcia_device *link) DEBUG(1, "dev=0x%p", dev); memset(dev, 0, sizeof(*dev)); - dev->p_dev = link; + link = &dev->link; link->priv = dev; link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY; - return pcmciamtd_config(link); + link->next = NULL; + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + pcmciamtd_config(link); + + return 0; } static struct pcmcia_device_id pcmciamtd_ids[] = { @@ -775,7 +794,7 @@ static struct pcmcia_driver pcmciamtd_driver = { .drv = { .name = "pcmciamtd" }, - .probe = pcmciamtd_probe, + .probe = pcmciamtd_attach, .remove = pcmciamtd_detach, .owner = THIS_MODULE, .id_table = pcmciamtd_ids, diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c index 50b140336..5b76ed886 100644 --- a/drivers/mtd/maps/redwood.c +++ b/drivers/mtd/maps/redwood.c @@ -121,7 +121,8 @@ struct map_info redwood_flash_map = { }; -#define NUM_REDWOOD_FLASH_PARTITIONS ARRAY_SIZE(redwood_flash_partitions) +#define NUM_REDWOOD_FLASH_PARTITIONS \ + (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0])) static struct mtd_info *redwood_mtd; diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c index 350286dc1..225cdd9ba 100644 --- a/drivers/mtd/maps/sbc8240.c +++ b/drivers/mtd/maps/sbc8240.c @@ -66,7 +66,7 @@ static struct map_info sbc8240_map[2] = { } }; -#define NUM_FLASH_BANKS ARRAY_SIZE(sbc8240_map) +#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info)) /* * The following defines the partition layout of SBC8240 boards. @@ -125,6 +125,8 @@ static struct mtd_partition sbc8240_fs_partitions [] = { } }; +#define NB_OF(x) (sizeof (x) / sizeof (x[0])) + /* trivial struct to describe partition information */ struct mtd_part_def { @@ -188,10 +190,10 @@ int __init init_sbc8240_mtd (void) #ifdef CONFIG_MTD_PARTITIONS sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions; sbc8240_part_banks[0].type = "static image"; - sbc8240_part_banks[0].nums = ARRAY_SIZE(sbc8240_uboot_partitions); + sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions); sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions; sbc8240_part_banks[1].type = "static file system"; - sbc8240_part_banks[1].nums = ARRAY_SIZE(sbc8240_fs_partitions); + sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions); for (i = 0; i < NUM_FLASH_BANKS; i++) { diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c index e8c130e1e..ed92afadd 100644 --- a/drivers/mtd/maps/sc520cdp.c +++ b/drivers/mtd/maps/sc520cdp.c @@ -107,7 +107,7 @@ static struct map_info sc520cdp_map[] = { }, }; -#define NUM_FLASH_BANKS ARRAY_SIZE(sc520cdp_map) +#define NUM_FLASH_BANKS (sizeof(sc520cdp_map)/sizeof(struct map_info)) static struct mtd_info *mymtd[NUM_FLASH_BANKS]; static struct mtd_info *merged_mtd; diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index 28b8a571a..2c91dff8b 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c @@ -70,7 +70,7 @@ static struct mtd_partition partition_info[] = { .size = 0x80000 }, }; -#define NUM_PARTITIONS ARRAY_SIZE(partition_info) +#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) #endif diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c index b3b39cb7c..999f4bb3d 100644 --- a/drivers/mtd/maps/sharpsl-flash.c +++ b/drivers/mtd/maps/sharpsl-flash.c @@ -1,10 +1,10 @@ /* * sharpsl-flash.c - * + * * Copyright (C) 2001 Lineo Japan, Inc. * Copyright (C) 2002 SHARP * - * $Id: sharpsl-flash.c,v 1.2 2004/11/24 20:38:06 rpurdie Exp $ + * $Id: sharpsl-flash.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $ * * 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 @@ -24,13 +24,14 @@ #include #include #include -#include #include #include #include +#include +#include #define WINDOW_ADDR 0x00000000 -#define WINDOW_SIZE 0x01000000 +#define WINDOW_SIZE 0x00800000 #define BANK_WIDTH 2 static struct mtd_info *mymtd; @@ -44,9 +45,7 @@ struct map_info sharpsl_map = { static struct mtd_partition sharpsl_partitions[1] = { { - name: "Filesystem", - size: 0x006d0000, - offset: 0x00120000 + name: "Boot PROM Filesystem", } }; @@ -58,12 +57,16 @@ int __init init_sharpsl(void) int nb_parts = 0; char *part_type = "static"; - printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); + 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); @@ -72,6 +75,22 @@ int __init init_sharpsl(void) 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 = NB_OF(sharpsl_partitions); diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c index a7422c200..4b372bcb1 100644 --- a/drivers/mtd/maps/ts5500_flash.c +++ b/drivers/mtd/maps/ts5500_flash.c @@ -64,7 +64,7 @@ static struct mtd_partition ts5500_partitions[] = { } }; -#define NUM_PARTITIONS ARRAY_SIZE(ts5500_partitions) +#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index f7264dc2a..79d92808b 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c @@ -37,7 +37,7 @@ struct mtd_partition uclinux_romfs[] = { { .name = "ROMfs" } }; -#define NUM_PARTITIONS ARRAY_SIZE(uclinux_romfs) +#define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0])) /****************************************************************************/ diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c index b3e487395..e0063941c 100644 --- a/drivers/mtd/maps/vmax301.c +++ b/drivers/mtd/maps/vmax301.c @@ -182,7 +182,7 @@ int __init init_vmax301(void) } } - if (!vmax_mtd[0] && !vmax_mtd[1]) { + if (!vmax_mtd[1] && !vmax_mtd[2]) { iounmap((void *)iomapadr); return -ENXIO; } diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 458d3c8ae..7f3ff500b 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -19,12 +19,12 @@ #include #include #include -#include +#include #include static LIST_HEAD(blktrans_majors); -extern struct mutex mtd_table_mutex; +extern struct semaphore mtd_table_mutex; extern struct mtd_info *mtd_table[]; struct mtd_blkcore_priv { @@ -122,9 +122,9 @@ static int mtd_blktrans_thread(void *arg) spin_unlock_irq(rq->queue_lock); - mutex_lock(&dev->lock); + down(&dev->sem); res = do_blktrans_request(tr, dev, req); - mutex_unlock(&dev->lock); + up(&dev->sem); spin_lock_irq(rq->queue_lock); @@ -235,8 +235,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int last_devnum = -1; struct gendisk *gd; - if (!!mutex_trylock(&mtd_table_mutex)) { - mutex_unlock(&mtd_table_mutex); + if (!down_trylock(&mtd_table_mutex)) { + up(&mtd_table_mutex); BUG(); } @@ -267,7 +267,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) return -EBUSY; } - mutex_init(&new->lock); + init_MUTEX(&new->sem); list_add_tail(&new->list, &tr->devs); added: if (!tr->writesect) @@ -313,8 +313,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) { - if (!!mutex_trylock(&mtd_table_mutex)) { - mutex_unlock(&mtd_table_mutex); + if (!down_trylock(&mtd_table_mutex)) { + up(&mtd_table_mutex); BUG(); } @@ -378,14 +378,14 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv)); - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); ret = register_blkdev(tr->major, tr->name); if (ret) { printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n", tr->name, tr->major, ret); kfree(tr->blkcore_priv); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } spin_lock_init(&tr->blkcore_priv->queue_lock); @@ -396,7 +396,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) if (!tr->blkcore_priv->rq) { unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return -ENOMEM; } @@ -407,7 +407,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } @@ -419,7 +419,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) tr->add_mtd(tr, mtd_table[i]); } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return 0; } @@ -428,7 +428,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) { struct list_head *this, *next; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); /* Clean up the kernel thread */ tr->blkcore_priv->exiting = 1; @@ -446,11 +446,12 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); kfree(tr->blkcore_priv); - BUG_ON(!list_empty(&tr->devs)); + if (!list_empty(&tr->devs)) + BUG(); return 0; } diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index 2cef280e3..e84756644 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -19,13 +19,11 @@ #include #include -#include - static struct mtdblk_dev { struct mtd_info *mtd; int count; - struct mutex cache_mutex; + struct semaphore cache_sem; unsigned char *cache_data; unsigned long cache_offset; unsigned int cache_size; @@ -286,7 +284,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd) mtdblk->count = 1; mtdblk->mtd = mtd; - mutex_init(&mtdblk->cache_mutex); + init_MUTEX (&mtdblk->cache_sem); mtdblk->cache_state = STATE_EMPTY; if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && mtdblk->mtd->erasesize) { @@ -308,9 +306,9 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd) DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); - mutex_lock(&mtdblk->cache_mutex); + down(&mtdblk->cache_sem); write_cached_data(mtdblk); - mutex_unlock(&mtdblk->cache_mutex); + up(&mtdblk->cache_sem); if (!--mtdblk->count) { /* It was the last usage. Free the device */ @@ -329,9 +327,9 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev) { struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; - mutex_lock(&mtdblk->cache_mutex); + down(&mtdblk->cache_sem); write_cached_data(mtdblk); - mutex_unlock(&mtdblk->cache_mutex); + up(&mtdblk->cache_sem); if (mtdblk->mtd->sync) mtdblk->mtd->sync(mtdblk->mtd); diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 9af840364..b1bf8c411 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -477,7 +477,8 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) } /* must never happen since size limit has been verified above */ - BUG_ON(i >= concat->num_subdev); + if (i >= concat->num_subdev) + BUG(); /* now do the erase: */ err = 0; @@ -499,7 +500,8 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) if ((err = concat_dev_erase(subdev, erase))) { /* sanity check: should never happen since * block alignment has been checked above */ - BUG_ON(err == -EINVAL); + if (err == -EINVAL) + BUG(); if (erase->fail_addr != 0xffffffff) instr->fail_addr = erase->fail_addr + offset; break; diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 9905870f5..dade02ab0 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -19,13 +19,15 @@ #include #include #include +#ifdef CONFIG_PROC_FS #include +#endif #include /* These are exported solely for the purpose of mtd_blkdevs.c. You should not use them for _anything_ else */ -DEFINE_MUTEX(mtd_table_mutex); +DECLARE_MUTEX(mtd_table_mutex); struct mtd_info *mtd_table[MAX_MTD_DEVICES]; EXPORT_SYMBOL_GPL(mtd_table_mutex); @@ -47,7 +49,7 @@ int add_mtd_device(struct mtd_info *mtd) { int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); for (i=0; i < MAX_MTD_DEVICES; i++) if (!mtd_table[i]) { @@ -65,7 +67,7 @@ int add_mtd_device(struct mtd_info *mtd) not->add(mtd); } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); /* We _know_ we aren't being removed, because our caller is still holding us here. So none of this try_ nonsense, and no bitching about it @@ -74,7 +76,7 @@ int add_mtd_device(struct mtd_info *mtd) return 0; } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return 1; } @@ -92,7 +94,7 @@ int del_mtd_device (struct mtd_info *mtd) { int ret; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); if (mtd_table[mtd->index] != mtd) { ret = -ENODEV; @@ -116,7 +118,7 @@ int del_mtd_device (struct mtd_info *mtd) ret = 0; } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } @@ -133,7 +135,7 @@ void register_mtd_user (struct mtd_notifier *new) { int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); list_add(&new->list, &mtd_notifiers); @@ -143,7 +145,7 @@ void register_mtd_user (struct mtd_notifier *new) if (mtd_table[i]) new->add(mtd_table[i]); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); } /** @@ -160,7 +162,7 @@ int unregister_mtd_user (struct mtd_notifier *old) { int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); module_put(THIS_MODULE); @@ -169,7 +171,7 @@ int unregister_mtd_user (struct mtd_notifier *old) old->remove(mtd_table[i]); list_del(&old->list); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return 0; } @@ -191,7 +193,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) struct mtd_info *ret = NULL; int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); if (num == -1) { for (i=0; i< MAX_MTD_DEVICES; i++) @@ -209,7 +211,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) if (ret) ret->usecount++; - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } @@ -217,9 +219,9 @@ void put_mtd_device(struct mtd_info *mtd) { int c; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); c = --mtd->usecount; - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); BUG_ON(c < 0); module_put(mtd->owner); @@ -294,11 +296,10 @@ EXPORT_SYMBOL(unregister_mtd_user); EXPORT_SYMBOL(default_mtd_writev); EXPORT_SYMBOL(default_mtd_readv); -#ifdef CONFIG_PROC_FS - /*====================================================================*/ /* Support for /proc/mtd */ +#ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_mtd; static inline int mtd_proc_info (char *buf, int i) @@ -318,7 +319,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, int len, l, i; off_t begin = 0; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); len = sprintf(page, "dev: size erasesize name\n"); for (i=0; i< MAX_MTD_DEVICES; i++) { @@ -336,34 +337,38 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, *eof = 1; done: - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); if (off >= len+begin) return 0; *start = page + (off-begin); return ((count < begin+len-off) ? count : begin+len-off); } +#endif /* CONFIG_PROC_FS */ + /*====================================================================*/ /* Init code */ static int __init init_mtd(void) { +#ifdef CONFIG_PROC_FS if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) proc_mtd->read_proc = mtd_read_proc; +#endif return 0; } static void __exit cleanup_mtd(void) { +#ifdef CONFIG_PROC_FS if (proc_mtd) remove_proc_entry( "mtd", NULL); +#endif } module_init(init_mtd); module_exit(cleanup_mtd); -#endif /* CONFIG_PROC_FS */ - MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse "); diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index bde355091..201e1362d 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -55,6 +55,8 @@ static const struct mtd_partition partition_info[] = { .size = MTDPART_SIZ_FULL } }; +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + /** * au_read_byte - read one byte from the chip @@ -460,7 +462,7 @@ int __init au1xxx_nand_init (void) } /* Register the partitions */ - add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info)); + add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info)); return 0; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 95e96fa1f..5d222460b 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -80,7 +80,6 @@ #include #include #include -#include #include #ifdef CONFIG_MTD_PARTITIONS @@ -516,8 +515,6 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i return nand_isbad_bbt (mtd, ofs, allowbbt); } -DEFINE_LED_TRIGGER(nand_led_trigger); - /* * Wait for the ready pin, after a command * The timeout is catched later. @@ -527,14 +524,12 @@ static void nand_wait_ready(struct mtd_info *mtd) struct nand_chip *this = mtd->priv; unsigned long timeo = jiffies + 2; - led_trigger_event(nand_led_trigger, LED_FULL); /* wait until command is processed or timeout occures */ do { if (this->dev_ready(mtd)) - break; + return; touch_softlockup_watchdog(); } while (time_before(jiffies, timeo)); - led_trigger_event(nand_led_trigger, LED_OFF); } /** @@ -822,8 +817,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) else timeo += (HZ * 20) / 1000; - led_trigger_event(nand_led_trigger, LED_FULL); - /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ ndelay (100); @@ -847,8 +840,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) } cond_resched(); } - led_trigger_event(nand_led_trigger, LED_OFF); - status = (int) this->read_byte(mtd); return status; } @@ -2733,21 +2724,6 @@ void nand_release (struct mtd_info *mtd) EXPORT_SYMBOL_GPL (nand_scan); EXPORT_SYMBOL_GPL (nand_release); - -static int __init nand_base_init(void) -{ - led_trigger_register_simple("nand-disk", &nand_led_trigger); - return 0; -} - -static void __exit nand_base_exit(void) -{ - led_trigger_unregister_simple(nand_led_trigger); -} - -module_init(nand_base_init); -module_exit(nand_base_exit); - MODULE_LICENSE ("GPL"); MODULE_AUTHOR ("Steven J. Hill , Thomas Gleixner "); MODULE_DESCRIPTION ("Generic NAND flash driver code"); diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index c077d2ec9..8815c8dbe 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -85,6 +85,10 @@ static int parse_redboot_partitions(struct mtd_info *master, numslots = (master->erasesize / sizeof(struct fis_image_desc)); for (i = 0; i < numslots; i++) { + if (buf[i].name[0] == 0xff) { + i = numslots; + break; + } if (!memcmp(buf[i].name, "FIS directory", 14)) { /* This is apparently the FIS directory entry for the * FIS directory itself. The FIS directory size is @@ -124,7 +128,7 @@ static int parse_redboot_partitions(struct mtd_info *master, struct fis_list *new_fl, **prev; if (buf[i].name[0] == 0xff) - continue; + break; if (!redboot_checksum(&buf[i])) break; diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index dc845f36f..830528dce 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -100,10 +100,6 @@ static int max_interrupt_work = 10; static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n"; static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n"; -#if defined(CONFIG_PM) && (defined(CONFIG_MCA) || defined(CONFIG_EISA)) -#define EL3_SUSPEND -#endif - #ifdef EL3_DEBUG static int el3_debug = EL3_DEBUG; #else @@ -178,6 +174,9 @@ struct el3_private { /* skb send-queue */ int head, size; struct sk_buff *queue[SKB_QUEUE_SIZE]; +#ifdef CONFIG_PM_LEGACY + struct pm_dev *pmdev; +#endif enum { EL3_MCA, EL3_PNP, @@ -202,15 +201,11 @@ static void el3_tx_timeout (struct net_device *dev); static void el3_down(struct net_device *dev); static void el3_up(struct net_device *dev); static struct ethtool_ops ethtool_ops; -#ifdef EL3_SUSPEND -static int el3_suspend(struct device *, pm_message_t); -static int el3_resume(struct device *); -#else -#define el3_suspend NULL -#define el3_resume NULL +#ifdef CONFIG_PM_LEGACY +static int el3_suspend(struct pm_dev *pdev); +static int el3_resume(struct pm_dev *pdev); +static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data); #endif - - /* generic device remove for all device types */ #if defined(CONFIG_EISA) || defined(CONFIG_MCA) static int el3_device_remove (struct device *device); @@ -234,9 +229,7 @@ static struct eisa_driver el3_eisa_driver = { .driver = { .name = "3c509", .probe = el3_eisa_probe, - .remove = __devexit_p (el3_device_remove), - .suspend = el3_suspend, - .resume = el3_resume, + .remove = __devexit_p (el3_device_remove) } }; #endif @@ -269,8 +262,6 @@ static struct mca_driver el3_mca_driver = { .bus = &mca_bus_type, .probe = el3_mca_probe, .remove = __devexit_p(el3_device_remove), - .suspend = el3_suspend, - .resume = el3_resume, }, }; #endif /* CONFIG_MCA */ @@ -371,6 +362,10 @@ static void el3_common_remove (struct net_device *dev) struct el3_private *lp = netdev_priv(dev); (void) lp; /* Keep gcc quiet... */ +#ifdef CONFIG_PM_LEGACY + if (lp->pmdev) + pm_unregister(lp->pmdev); +#endif #if defined(__ISAPNP__) if (lp->type == EL3_PNP) pnp_device_detach(to_pnp_dev(lp->dev)); @@ -577,6 +572,16 @@ no_pnp: if (err) goto out1; +#ifdef CONFIG_PM_LEGACY + /* register power management */ + lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback); + if (lp->pmdev) { + struct pm_dev *p; + p = lp->pmdev; + p->data = (struct net_device *)dev; + } +#endif + el3_cards++; lp->next_dev = el3_root_dev; el3_root_dev = dev; @@ -1475,17 +1480,20 @@ el3_up(struct net_device *dev) } /* Power Management support functions */ -#ifdef EL3_SUSPEND +#ifdef CONFIG_PM_LEGACY static int -el3_suspend(struct device *pdev, pm_message_t state) +el3_suspend(struct pm_dev *pdev) { unsigned long flags; struct net_device *dev; struct el3_private *lp; int ioaddr; - dev = pdev->driver_data; + if (!pdev && !pdev->data) + return -EINVAL; + + dev = (struct net_device *)pdev->data; lp = netdev_priv(dev); ioaddr = dev->base_addr; @@ -1502,14 +1510,17 @@ el3_suspend(struct device *pdev, pm_message_t state) } static int -el3_resume(struct device *pdev) +el3_resume(struct pm_dev *pdev) { unsigned long flags; struct net_device *dev; struct el3_private *lp; int ioaddr; - dev = pdev->driver_data; + if (!pdev && !pdev->data) + return -EINVAL; + + dev = (struct net_device *)pdev->data; lp = netdev_priv(dev); ioaddr = dev->base_addr; @@ -1525,7 +1536,20 @@ el3_resume(struct device *pdev) return 0; } -#endif /* EL3_SUSPEND */ +static int +el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data) +{ + switch (rqst) { + case PM_SUSPEND: + return el3_suspend(pdev); + + case PM_RESUME: + return el3_resume(pdev); + } + return 0; +} + +#endif /* CONFIG_PM_LEGACY */ /* Parameters that may be passed into the module. */ static int debug = -1; diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index b40885d41..9e1fe2e04 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -105,7 +105,6 @@ #include #include #include -#include #include #include @@ -659,7 +658,7 @@ static int init586(struct net_device *dev) s = jiffies; /* warning: only active with interrupts on !! */ while (!(cfg_cmd->cmd_status & STAT_COMPL)) { - if (time_after(jiffies, s + 30*HZ/100)) + if (jiffies - s > 30*HZ/100) break; } @@ -685,7 +684,7 @@ static int init586(struct net_device *dev) s = jiffies; while (!(ias_cmd->cmd_status & STAT_COMPL)) { - if (time_after(jiffies, s + 30*HZ/100)) + if (jiffies - s > 30*HZ/100) break; } @@ -710,7 +709,7 @@ static int init586(struct net_device *dev) s = jiffies; while (!(tdr_cmd->cmd_status & STAT_COMPL)) { - if (time_after(jiffies, s + 30*HZ/100)) { + if (jiffies - s > 30*HZ/100) { printk(KERN_WARNING "%s: %d Problems while running the TDR.\n", dev->name, __LINE__); result = 1; break; @@ -799,7 +798,7 @@ static int init586(struct net_device *dev) elmc_id_attn586(); s = jiffies; while (!(mc_cmd->cmd_status & STAT_COMPL)) { - if (time_after(jiffies, s + 30*HZ/100)) + if (jiffies - s > 30*HZ/100) break; } if (!(mc_cmd->cmd_status & STAT_COMPL)) { diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 274b0138d..7f47124f1 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -196,6 +196,8 @@ #define DRV_NAME "3c59x" +#define DRV_VERSION "LK1.1.19" +#define DRV_RELDATE "10 Nov 2002" @@ -256,7 +258,6 @@ static int vortex_debug = 1; #include #include #include -#include #include /* For NR_IRQS only. */ #include #include @@ -273,8 +274,10 @@ static char version[] __devinitdata = DRV_NAME ": Donald Becker and others. www.scyld.com/network/vortex.html\n"; MODULE_AUTHOR("Donald Becker "); -MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver "); +MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver " + DRV_VERSION " " DRV_RELDATE); MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); /* Operational parameter that usually are not changed. */ @@ -788,7 +791,7 @@ struct vortex_private { int options; /* User-settable misc. driver options. */ unsigned int media_override:4, /* Passed-in media type. */ default_media:4, /* Read from the EEPROM/Wn3_Config. */ - full_duplex:1, autoselect:1, + full_duplex:1, force_fd:1, autoselect:1, bus_master:1, /* Vortex can only do a fragment bus-m. */ full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */ @@ -838,7 +841,7 @@ enum xcvr_types { XCVR_100baseFx, XCVR_MII=6, XCVR_NWAY=8, XCVR_ExtMII=9, XCVR_Default=10, }; -static const struct media_table { +static struct media_table { char *name; unsigned int media_bits:16, /* Bits to set in Wn4_Media register. */ mask:8, /* The transceiver-present bit in Wn3_Config.*/ @@ -900,6 +903,7 @@ static void acpi_set_WOL(struct net_device *dev); static struct ethtool_ops vortex_ethtool_ops; static void set_8021q_mode(struct net_device *dev, int enable); + /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ /* Option count limit only -- unlimited interfaces are supported. */ #define MAX_UNITS 8 @@ -914,6 +918,8 @@ static int global_full_duplex = -1; static int global_enable_wol = -1; static int global_use_mmio = -1; +/* #define dev_alloc_skb dev_alloc_skb_debug */ + /* Variables to work-around the Compaq PCI BIOS32 problem. */ static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900; static struct net_device *compaq_net_device; @@ -969,7 +975,7 @@ static void poll_vortex(struct net_device *dev) #ifdef CONFIG_PM -static int vortex_suspend(struct pci_dev *pdev, pm_message_t state) +static int vortex_suspend (struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); @@ -987,7 +993,7 @@ static int vortex_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } -static int vortex_resume(struct pci_dev *pdev) +static int vortex_resume (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct vortex_private *vp = netdev_priv(dev); @@ -1020,8 +1026,8 @@ static struct eisa_device_id vortex_eisa_ids[] = { { "" } }; -static int vortex_eisa_probe(struct device *device); -static int vortex_eisa_remove(struct device *device); +static int vortex_eisa_probe (struct device *device); +static int vortex_eisa_remove (struct device *device); static struct eisa_driver vortex_eisa_driver = { .id_table = vortex_eisa_ids, @@ -1032,12 +1038,12 @@ static struct eisa_driver vortex_eisa_driver = { } }; -static int vortex_eisa_probe(struct device *device) +static int vortex_eisa_probe (struct device *device) { void __iomem *ioaddr; struct eisa_device *edev; - edev = to_eisa_device(device); + edev = to_eisa_device (device); if (!request_region(edev->base_addr, VORTEX_TOTAL_SIZE, DRV_NAME)) return -EBUSY; @@ -1046,7 +1052,7 @@ static int vortex_eisa_probe(struct device *device) if (vortex_probe1(device, ioaddr, ioread16(ioaddr + 0xC88) >> 12, edev->id.driver_data, vortex_cards_found)) { - release_region(edev->base_addr, VORTEX_TOTAL_SIZE); + release_region (edev->base_addr, VORTEX_TOTAL_SIZE); return -ENODEV; } @@ -1055,15 +1061,15 @@ static int vortex_eisa_probe(struct device *device) return 0; } -static int vortex_eisa_remove(struct device *device) +static int vortex_eisa_remove (struct device *device) { struct eisa_device *edev; struct net_device *dev; struct vortex_private *vp; void __iomem *ioaddr; - edev = to_eisa_device(device); - dev = eisa_get_drvdata(edev); + edev = to_eisa_device (device); + dev = eisa_get_drvdata (edev); if (!dev) { printk("vortex_eisa_remove called for Compaq device!\n"); @@ -1073,34 +1079,30 @@ static int vortex_eisa_remove(struct device *device) vp = netdev_priv(dev); ioaddr = vp->ioaddr; - unregister_netdev(dev); - iowrite16(TotalReset|0x14, ioaddr + EL3_CMD); - release_region(dev->base_addr, VORTEX_TOTAL_SIZE); + unregister_netdev (dev); + iowrite16 (TotalReset|0x14, ioaddr + EL3_CMD); + release_region (dev->base_addr, VORTEX_TOTAL_SIZE); - free_netdev(dev); + free_netdev (dev); return 0; } #endif /* returns count found (>= 0), or negative on error */ -static int __init vortex_eisa_init(void) +static int __init vortex_eisa_init (void) { int eisa_found = 0; int orig_cards_found = vortex_cards_found; #ifdef CONFIG_EISA - int err; - - err = eisa_driver_register (&vortex_eisa_driver); - if (!err) { - /* - * Because of the way EISA bus is probed, we cannot assume - * any device have been found when we exit from - * eisa_driver_register (the bus root driver may not be - * initialized yet). So we blindly assume something was - * found, and let the sysfs magic happend... - */ - eisa_found = 1; + if (eisa_driver_register (&vortex_eisa_driver) >= 0) { + /* Because of the way EISA bus is probed, we cannot assume + * any device have been found when we exit from + * eisa_driver_register (the bus root driver may not be + * initialized yet). So we blindly assume something was + * found, and let the sysfs magic happend... */ + + eisa_found = 1; } #endif @@ -1114,7 +1116,7 @@ static int __init vortex_eisa_init(void) } /* returns count (>= 0), or negative on error */ -static int __devinit vortex_init_one(struct pci_dev *pdev, +static int __devinit vortex_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { int rc, unit, pci_bar; @@ -1122,7 +1124,7 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, void __iomem *ioaddr; /* wake up and enable device */ - rc = pci_enable_device(pdev); + rc = pci_enable_device (pdev); if (rc < 0) goto out; @@ -1144,7 +1146,7 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq, ent->driver_data, unit); if (rc < 0) { - pci_disable_device(pdev); + pci_disable_device (pdev); goto out; } @@ -1229,7 +1231,7 @@ static int __devinit vortex_probe1(struct device *gendev, if (print_info) printk (KERN_INFO "See Documentation/networking/vortex.txt\n"); - printk(KERN_INFO "%s: 3Com %s %s at %p.\n", + printk(KERN_INFO "%s: 3Com %s %s at %p. Vers " DRV_VERSION "\n", print_name, pdev ? "PCI" : "EISA", vci->name, @@ -1259,7 +1261,7 @@ static int __devinit vortex_probe1(struct device *gendev, /* enable bus-mastering if necessary */ if (vci->flags & PCI_USES_MASTER) - pci_set_master(pdev); + pci_set_master (pdev); if (vci->drv_flags & IS_VORTEX) { u8 pci_latency; @@ -1303,7 +1305,7 @@ static int __devinit vortex_probe1(struct device *gendev, if (pdev) pci_set_drvdata(pdev, dev); if (edev) - eisa_set_drvdata(edev, dev); + eisa_set_drvdata (edev, dev); vp->media_override = 7; if (option >= 0) { @@ -1328,7 +1330,7 @@ static int __devinit vortex_probe1(struct device *gendev, vp->enable_wol = 1; } - vp->mii.force_media = vp->full_duplex; + vp->force_fd = vp->full_duplex; vp->options = option; /* Read the station address from the EEPROM. */ EL3WINDOW(0); @@ -1443,7 +1445,7 @@ static int __devinit vortex_probe1(struct device *gendev, } { - static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; + static const char * ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; unsigned int config; EL3WINDOW(3); vp->available_media = ioread16(ioaddr + Wn3_Options); @@ -1617,47 +1619,13 @@ issue_and_wait(struct net_device *dev, int cmd) dev->name, cmd, ioread16(ioaddr + EL3_STATUS)); } -static void -vortex_set_duplex(struct net_device *dev) -{ - struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; - - printk(KERN_INFO "%s: setting %s-duplex.\n", - dev->name, (vp->full_duplex) ? "full" : "half"); - - EL3WINDOW(3); - /* Set the full-duplex bit. */ - iowrite16(((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | - (vp->large_frames ? 0x40 : 0) | - ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? - 0x100 : 0), - ioaddr + Wn3_MAC_Ctrl); -} - -static void vortex_check_media(struct net_device *dev, unsigned int init) -{ - struct vortex_private *vp = netdev_priv(dev); - unsigned int ok_to_print = 0; - - if (vortex_debug > 3) - ok_to_print = 1; - - if (mii_check_media(&vp->mii, ok_to_print, init)) { - vp->full_duplex = vp->mii.full_duplex; - vortex_set_duplex(dev); - } else if (init) { - vortex_set_duplex(dev); - } -} - static void vortex_up(struct net_device *dev) { struct vortex_private *vp = netdev_priv(dev); void __iomem *ioaddr = vp->ioaddr; unsigned int config; - int i, mii_reg1, mii_reg5; + int i; if (VORTEX_PCI(vp)) { pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ @@ -1711,22 +1679,47 @@ vortex_up(struct net_device *dev) printk(KERN_DEBUG "%s: Initial media type %s.\n", dev->name, media_tbl[dev->if_port].name); - vp->full_duplex = vp->mii.force_media; + vp->full_duplex = vp->force_fd; config = BFINS(config, dev->if_port, 20, 4); if (vortex_debug > 6) printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config); iowrite32(config, ioaddr + Wn3_Config); if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { + int mii_reg1, mii_reg5; EL3WINDOW(4); + /* Read BMSR (reg1) only to clear old status. */ mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR); mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); + if (mii_reg5 == 0xffff || mii_reg5 == 0x0000) { + netif_carrier_off(dev); /* No MII device or no link partner report */ + } else { + mii_reg5 &= vp->advertising; + if ((mii_reg5 & 0x0100) != 0 /* 100baseTx-FD */ + || (mii_reg5 & 0x00C0) == 0x0040) /* 10T-FD, but not 100-HD */ + vp->full_duplex = 1; + netif_carrier_on(dev); + } vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0); + if (vortex_debug > 1) + printk(KERN_INFO "%s: MII #%d status %4.4x, link partner capability %4.4x," + " info1 %04x, setting %s-duplex.\n", + dev->name, vp->phys[0], + mii_reg1, mii_reg5, + vp->info1, ((vp->info1 & 0x8000) || vp->full_duplex) ? "full" : "half"); + EL3WINDOW(3); + } + + /* Set the full-duplex bit. */ + iowrite16( ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | + (vp->large_frames ? 0x40 : 0) | + ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), + ioaddr + Wn3_MAC_Ctrl); - vortex_check_media(dev, 1); + if (vortex_debug > 1) { + printk(KERN_DEBUG "%s: vortex_up() InternalConfig %8.8x.\n", + dev->name, config); } - else - vortex_set_duplex(dev); issue_and_wait(dev, TxReset); /* @@ -1734,7 +1727,6 @@ vortex_up(struct net_device *dev) */ issue_and_wait(dev, RxReset|0x04); - iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD); if (vortex_debug > 1) { @@ -1808,6 +1800,7 @@ vortex_up(struct net_device *dev) set_8021q_mode(dev, 1); iowrite16(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ +// issue_and_wait(dev, SetTxStart|0x07ff); iowrite16(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ iowrite16(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ /* Allow status bits to be seen. */ @@ -1894,7 +1887,7 @@ vortex_timer(unsigned long data) void __iomem *ioaddr = vp->ioaddr; int next_tick = 60*HZ; int ok = 0; - int media_status, old_window; + int media_status, mii_status, old_window; if (vortex_debug > 2) { printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n", @@ -1902,6 +1895,8 @@ vortex_timer(unsigned long data) printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo); } + if (vp->medialock) + goto leave_media_alone; disable_irq(dev->irq); old_window = ioread16(ioaddr + EL3_CMD) >> 13; EL3WINDOW(4); @@ -1924,9 +1919,44 @@ vortex_timer(unsigned long data) break; case XCVR_MII: case XCVR_NWAY: { - ok = 1; spin_lock_bh(&vp->lock); - vortex_check_media(dev, 0); + mii_status = mdio_read(dev, vp->phys[0], MII_BMSR); + if (!(mii_status & BMSR_LSTATUS)) { + /* Re-read to get actual link status */ + mii_status = mdio_read(dev, vp->phys[0], MII_BMSR); + } + ok = 1; + if (vortex_debug > 2) + printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n", + dev->name, mii_status); + if (mii_status & BMSR_LSTATUS) { + int mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); + if (! vp->force_fd && mii_reg5 != 0xffff) { + int duplex; + + mii_reg5 &= vp->advertising; + duplex = (mii_reg5&0x0100) || (mii_reg5 & 0x01C0) == 0x0040; + if (vp->full_duplex != duplex) { + vp->full_duplex = duplex; + printk(KERN_INFO "%s: Setting %s-duplex based on MII " + "#%d link partner capability of %4.4x.\n", + dev->name, vp->full_duplex ? "full" : "half", + vp->phys[0], mii_reg5); + /* Set the full-duplex bit. */ + EL3WINDOW(3); + iowrite16( (vp->full_duplex ? 0x20 : 0) | + (vp->large_frames ? 0x40 : 0) | + ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), + ioaddr + Wn3_MAC_Ctrl); + if (vortex_debug > 1) + printk(KERN_DEBUG "Setting duplex in Wn3_MAC_Ctrl\n"); + /* AKPM: bug: should reset Tx and Rx after setting Duplex. Page 180 */ + } + } + netif_carrier_on(dev); + } else { + netif_carrier_off(dev); + } spin_unlock_bh(&vp->lock); } break; @@ -1936,14 +1966,7 @@ vortex_timer(unsigned long data) dev->name, media_tbl[dev->if_port].name, media_status); ok = 1; } - - if (!netif_carrier_ok(dev)) - next_tick = 5*HZ; - - if (vp->medialock) - goto leave_media_alone; - - if (!ok) { + if ( ! ok) { unsigned int config; do { @@ -1976,14 +1999,14 @@ vortex_timer(unsigned long data) printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config); /* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */ } + EL3WINDOW(old_window); + enable_irq(dev->irq); leave_media_alone: if (vortex_debug > 2) printk(KERN_DEBUG "%s: Media selection timer finished, %s.\n", dev->name, media_tbl[dev->if_port].name); - EL3WINDOW(old_window); - enable_irq(dev->irq); mod_timer(&vp->timer, RUN_AT(next_tick)); if (vp->deferred) iowrite16(FakeIntr, ioaddr + EL3_CMD); @@ -2086,14 +2109,16 @@ vortex_error(struct net_device *dev, int status) } if (tx_status & 0x14) vp->stats.tx_fifo_errors++; if (tx_status & 0x38) vp->stats.tx_aborted_errors++; - if (tx_status & 0x08) vp->xstats.tx_max_collisions++; iowrite8(0, ioaddr + TxStatus); if (tx_status & 0x30) { /* txJabber or txUnderrun */ do_tx_reset = 1; - } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */ - do_tx_reset = 1; - reset_mask = 0x0108; /* Reset interface logic, but not download logic */ - } else { /* Merely re-enable the transmitter. */ + } else if (tx_status & 0x08) { /* maxCollisions */ + vp->xstats.tx_max_collisions++; + if (vp->drv_flags & MAX_COLLISION_RESET) { + do_tx_reset = 1; + reset_mask = 0x0108; /* Reset interface logic, but not download logic */ + } + } else { /* Merely re-enable the transmitter. */ iowrite16(TxEnable, ioaddr + EL3_CMD); } } @@ -2176,7 +2201,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) if (vp->bus_master) { /* Set the bus-master controller to transfer the packet. */ int len = (skb->len + 3) & ~3; - iowrite32(vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE), + iowrite32( vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE), ioaddr + Wn7_MasterAddr); iowrite16(len, ioaddr + Wn7_MasterLen); vp->tx_skb = skb; @@ -2699,7 +2724,7 @@ boomerang_rx(struct net_device *dev) skb = dev_alloc_skb(PKT_BUF_SZ); if (skb == NULL) { static unsigned long last_jif; - if (time_after(jiffies, last_jif + 10 * HZ)) { + if ((jiffies - last_jif) > 10 * HZ) { printk(KERN_WARNING "%s: memory shortage\n", dev->name); last_jif = jiffies; } @@ -2953,6 +2978,20 @@ static int vortex_nway_reset(struct net_device *dev) return rc; } +static u32 vortex_get_link(struct net_device *dev) +{ + struct vortex_private *vp = netdev_priv(dev); + void __iomem *ioaddr = vp->ioaddr; + unsigned long flags; + int rc; + + spin_lock_irqsave(&vp->lock, flags); + EL3WINDOW(4); + rc = mii_link_ok(&vp->mii); + spin_unlock_irqrestore(&vp->lock, flags); + return rc; +} + static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct vortex_private *vp = netdev_priv(dev); @@ -3033,6 +3072,7 @@ static void vortex_get_drvinfo(struct net_device *dev, struct vortex_private *vp = netdev_priv(dev); strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); if (VORTEX_PCI(vp)) { strcpy(info->bus_info, pci_name(VORTEX_PCI(vp))); } else { @@ -3053,9 +3093,9 @@ static struct ethtool_ops vortex_ethtool_ops = { .get_stats_count = vortex_get_stats_count, .get_settings = vortex_get_settings, .set_settings = vortex_set_settings, - .get_link = ethtool_op_get_link, + .get_link = vortex_get_link, .nway_reset = vortex_nway_reset, - .get_perm_addr = ethtool_op_get_perm_addr, + .get_perm_addr = ethtool_op_get_perm_addr, }; #ifdef CONFIG_PCI @@ -3256,7 +3296,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val } return; } - + /* ACPI: Advanced Configuration and Power Interface. */ /* Set Wake-On-LAN mode and put the board into D3 (power-down) state. */ static void acpi_set_WOL(struct net_device *dev) @@ -3280,7 +3320,7 @@ static void acpi_set_WOL(struct net_device *dev) } -static void __devexit vortex_remove_one(struct pci_dev *pdev) +static void __devexit vortex_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct vortex_private *vp; @@ -3336,7 +3376,7 @@ static int vortex_have_pci; static int vortex_have_eisa; -static int __init vortex_init(void) +static int __init vortex_init (void) { int pci_rc, eisa_rc; @@ -3352,14 +3392,14 @@ static int __init vortex_init(void) } -static void __exit vortex_eisa_cleanup(void) +static void __exit vortex_eisa_cleanup (void) { struct vortex_private *vp; void __iomem *ioaddr; #ifdef CONFIG_EISA /* Take care of the EISA devices */ - eisa_driver_unregister(&vortex_eisa_driver); + eisa_driver_unregister (&vortex_eisa_driver); #endif if (compaq_net_device) { @@ -3367,24 +3407,33 @@ static void __exit vortex_eisa_cleanup(void) ioaddr = ioport_map(compaq_net_device->base_addr, VORTEX_TOTAL_SIZE); - unregister_netdev(compaq_net_device); - iowrite16(TotalReset, ioaddr + EL3_CMD); + unregister_netdev (compaq_net_device); + iowrite16 (TotalReset, ioaddr + EL3_CMD); release_region(compaq_net_device->base_addr, VORTEX_TOTAL_SIZE); - free_netdev(compaq_net_device); + free_netdev (compaq_net_device); } } -static void __exit vortex_cleanup(void) +static void __exit vortex_cleanup (void) { if (vortex_have_pci) - pci_unregister_driver(&vortex_driver); + pci_unregister_driver (&vortex_driver); if (vortex_have_eisa) - vortex_eisa_cleanup(); + vortex_eisa_cleanup (); } module_init(vortex_init); module_exit(vortex_cleanup); + + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 86633c5f1..18b027e73 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include /* Used for the temporal inet entries and routing */ #include #include diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 365a07494..dd410496a 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -539,7 +539,8 @@ rx_status_loop: unsigned buflen; skb = cp->rx_skb[rx_tail].skb; - BUG_ON(!skb); + if (!skb) + BUG(); desc = &cp->rx_ring[rx_tail]; status = le32_to_cpu(desc->opts1); @@ -722,7 +723,8 @@ static void cp_tx (struct cp_private *cp) break; skb = cp->tx_skb[tx_tail].skb; - BUG_ON(!skb); + if (!skb) + BUG(); pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE); @@ -792,7 +794,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) entry = cp->tx_head; eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; if (dev->features & NETIF_F_TSO) - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; if (skb_shinfo(skb)->nr_frags == 0) { struct cp_desc *txd = &cp->tx_ring[entry]; @@ -1274,7 +1276,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu) } #endif /* BROKEN */ -static const char mii_2_8139_map[8] = { +static char mii_2_8139_map[8] = { BasicModeCtrl, BasicModeStatus, 0, @@ -1548,7 +1550,8 @@ static void cp_get_ethtool_stats (struct net_device *dev, tmp_stats[i++] = le16_to_cpu(nic_stats->tx_abort); tmp_stats[i++] = le16_to_cpu(nic_stats->tx_underrun); tmp_stats[i++] = cp->cp_stats.rx_frags; - BUG_ON(i != CP_NUM_STATS); + if (i != CP_NUM_STATS) + BUG(); pci_free_consistent(cp->pdev, sizeof(*nic_stats), nic_stats, dma); } @@ -1853,7 +1856,8 @@ static void cp_remove_one (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct cp_private *cp = netdev_priv(dev); - BUG_ON(!dev); + if (!dev) + BUG(); unregister_netdev(dev); iounmap(cp->regs); if (cp->wol_enabled) pci_set_power_state (pdev, PCI_D0); diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index feae7832f..2beac55b5 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -229,7 +229,7 @@ typedef enum { /* indexed by board_t, above */ -static const struct { +static struct { const char *name; u32 hw_flags; } board_info[] __devinitdata = { @@ -1131,7 +1131,7 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev) No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. */ -#define eeprom_delay() (void)RTL_R32(Cfg9346) +#define eeprom_delay() RTL_R32(Cfg9346) /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD (5) @@ -1192,7 +1192,7 @@ static int __devinit read_eeprom (void __iomem *ioaddr, int location, int addr_l #define mdio_delay() RTL_R8(Config4) -static const char mii_2_8139_map[8] = { +static char mii_2_8139_map[8] = { BasicModeCtrl, BasicModeStatus, 0, @@ -1605,7 +1605,7 @@ static void rtl8139_thread (void *_data) if (tp->watchdog_fired) { tp->watchdog_fired = 0; rtl8139_tx_timeout_task(_data); - } else if (rtnl_trylock()) { + } else if (rtnl_shlock_nowait() == 0) { rtl8139_thread_iter (dev, tp, tp->mmio_addr); rtnl_unlock (); } else { diff --git a/drivers/net/82596.c b/drivers/net/82596.c index da0c878dc..13b745b39 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -614,7 +614,7 @@ static void rebuild_rx_bufs(struct net_device *dev) static int init_i596_mem(struct net_device *dev) { struct i596_private *lp = dev->priv; -#if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) || defined(ENABLE_APRICOT) +#if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) short ioaddr = dev->base_addr; #endif unsigned long flags; diff --git a/drivers/net/8390.h b/drivers/net/8390.h index 51e39dcd0..599b68d8c 100644 --- a/drivers/net/8390.h +++ b/drivers/net/8390.h @@ -134,7 +134,7 @@ struct ei_device { #define inb_p(_p) inb(_p) #define outb_p(_v,_p) outb(_v,_p) -#elif defined(CONFIG_NE_H8300) || defined(CONFIG_NE_H8300_MODULE) +#elif defined(CONFIG_NET_CBUS) || defined(CONFIG_NE_H8300) || defined(CONFIG_NE_H8300_MODULE) #define EI_SHIFT(x) (ei_local->reg_offset[x]) #else #define EI_SHIFT(x) (x) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b7c3e118e..39f14a48a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -66,7 +66,7 @@ config BONDING 'Trunking' by Sun, 802.3ad by the IEEE, and 'Bonding' in Linux. The driver supports multiple bonding modes to allow for both high - performance and high availability operation. + perfomance and high availability operation. Refer to for more information. @@ -698,8 +698,8 @@ config VORTEX depends on NET_VENDOR_3COM && (PCI || EISA) select MII ---help--- - This option enables driver support for a large number of 10Mbps and - 10/100Mbps EISA, PCI and PCMCIA 3Com network cards: + This option enables driver support for a large number of 10mbps and + 10/100mbps EISA, PCI and PCMCIA 3Com network cards: "Vortex" (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI "Boomerang" (EtherLink XL 3c900 or 3c905) PCI @@ -1021,7 +1021,7 @@ config EEXPRESS_PRO depends on NET_ISA ---help--- If you have a network (Ethernet) card of this type, say Y. This - driver supports Intel i82595{FX,TX} based boards. Note however + driver supports intel i82595{FX,TX} based boards. Note however that the EtherExpress PRO/100 Ethernet card has its own separate driver. Please read the Ethernet-HOWTO, available from . @@ -1208,7 +1208,7 @@ config IBM_EMAC_RX_SKB_HEADROOM help Additional receive skb headroom. Note, that driver will always reserve at least 2 bytes to make IP header - aligned, so usually there is no need to add any additional + aligned, so usualy there is no need to add any additional headroom. If unsure, set to 0. @@ -1372,8 +1372,8 @@ config B44 called b44. config FORCEDETH - tristate "nForce Ethernet support" - depends on NET_PCI && PCI + tristate "Reverse Engineered nForce Ethernet support (EXPERIMENTAL)" + depends on NET_PCI && PCI && EXPERIMENTAL help If you have a network (Ethernet) controller of this type, say Y and read the Ethernet-HOWTO, available from @@ -1614,7 +1614,11 @@ config SIS900 ---help--- This is a driver for the Fast Ethernet PCI network cards based on the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in - SiS 630 and SiS 540 chipsets. + SiS 630 and SiS 540 chipsets. If you have one of those, say Y and + read the Ethernet-HOWTO, available at + . Please read + and comments at the + beginning of for more information. This driver also supports AMD 79C901 HomePNA so that you can use your phone line as a network cable. @@ -1914,7 +1918,7 @@ config E1000_DISABLE_PACKET_SPLIT depends on E1000 help Say Y here if you want to use the legacy receive path for PCI express - hardware. + hadware. If in doubt, say N. @@ -1930,7 +1934,7 @@ config MYRI_SBUS will be called myri_sbus. This is recommended. config NS83820 - tristate "National Semiconductor DP83820 support" + tristate "National Semiconduct DP83820 support" depends on PCI help This is a driver for the National Semiconductor DP83820 series @@ -2201,7 +2205,6 @@ config BCM5700 config SPIDER_NET tristate "Spider Gigabit Ethernet driver" depends on PCI && PPC_CELL - select FW_LOADER help This driver supports the Gigabit Ethernet chips present on the Cell Processor-Based Blades from IBM. @@ -2221,7 +2224,6 @@ config GFAR_NAPI config MV643XX_ETH tristate "MV-643XX Ethernet support" depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MOMENCO_OCELOT_3 || PPC_MULTIPLATFORM - select MII help This driver supports the gigabit Ethernet on the Marvell MV643XX chipset which is used in the Momenco Ocelot C and Jaguar ATX and @@ -2342,11 +2344,13 @@ config S2IO_NAPI endmenu +if !UML source "drivers/net/tokenring/Kconfig" source "drivers/net/wireless/Kconfig" source "drivers/net/pcmcia/Kconfig" +endif source "drivers/net/wan/Kconfig" @@ -2539,7 +2543,7 @@ config PPP_FILTER Say Y here if you want to be able to filter the packets passing over PPP interfaces. This allows you to control which packets count as activity (i.e. which packets will reset the idle timer or bring up - a demand-dialed link) and which packets are to be dropped entirely. + a demand-dialled link) and which packets are to be dropped entirely. You need to say Y here if you wish to use the pass-filter and active-filter options to pppd. @@ -2727,8 +2731,8 @@ config SHAPER for more information. An alternative to this traffic shaper is the experimental - Class-Based Queuing (CBQ) scheduling support which you get if you - say Y to "QoS and/or fair queuing" above. + Class-Based Queueing (CBQ) scheduling support which you get if you + say Y to "QoS and/or fair queueing" above. To compile this driver as a module, choose M here: the module will be called shaper. If unsure, say N. diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 0e455ffeb..6ef9f17cd 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -59,8 +59,8 @@ obj-$(CONFIG_STNIC) += stnic.o 8390.o obj-$(CONFIG_FEALNX) += fealnx.o obj-$(CONFIG_TIGON3) += tg3.o obj-$(CONFIG_BNX2) += bnx2.o -spidernet-y += spider_net.o spider_net_ethtool.o -obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o +spidernet-y += spider_net.o spider_net_ethtool.o sungem_phy.o +obj-$(CONFIG_SPIDER_NET) += spidernet.o obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_SKGE) += skge.o obj-$(CONFIG_SKY2) += sky2.o @@ -146,7 +146,6 @@ obj-$(CONFIG_EL3) += 3c509.o obj-$(CONFIG_3C515) += 3c515.o obj-$(CONFIG_EEXPRESS) += eexpress.o obj-$(CONFIG_EEXPRESS_PRO) += eepro.o -obj-$(CONFIG_MAMBO_NET) += mambonet.o obj-$(CONFIG_8139CP) += 8139cp.o obj-$(CONFIG_8139TOO) += 8139too.o obj-$(CONFIG_ZNET) += znet.o diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 79bb56b8d..8e538a6d7 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -829,7 +829,7 @@ static void __devexit a2065_remove_one(struct zorro_dev *z) static int __init a2065_init_module(void) { - return zorro_register_driver(&a2065_driver); + return zorro_module_init(&a2065_driver); } static void __exit a2065_cleanup_module(void) diff --git a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h index d7882dd78..6d625d595 100644 --- a/drivers/net/acenic_firmware.h +++ b/drivers/net/acenic_firmware.h @@ -4397,7 +4397,7 @@ static u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = { 0x3c010001, 0x220821, 0xac317e30, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0028, 0x0 }; -static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { +static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, @@ -4571,7 +4571,7 @@ static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { 0x0, 0x14c38, 0x14c38, 0x14b80, 0x14bc4, 0x14c38, 0x14c38, 0x0, 0x0, 0x0 }; -static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __devinitdata = { +static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __initdata = { 0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242, @@ -4612,7 +4612,7 @@ static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __devinitdata = { #define tigon2FwSbssLen 0xcc #define tigon2FwBssAddr 0x00016f50 #define tigon2FwBssLen 0x20c0 -static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = { +static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x10000003, 0x0, 0xd, 0xd, 0x3c1d0001, 0x8fbd6d20, 0x3a0f021, 0x3c100000, @@ -9154,7 +9154,7 @@ static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = { 0x24020001, 0x8f430328, 0x1021, 0x24630001, 0x3e00008, 0xaf430328, 0x3e00008, 0x0, 0x0, 0x0, 0x0, 0x0 }; -static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { +static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, @@ -9425,7 +9425,7 @@ static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { 0x14ed8, 0x14b8c, 0x14bd8, 0x14c24, 0x14ed8, 0x7365746d, 0x61636163, 0x74000000, 0x0, 0x0 }; -static u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __devinitdata = { +static u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __initdata = { 0x1, 0x1, 0x1, 0xc001fc, 0x3ffc, 0xc00000, 0x416c7465, 0x6f6e2041, 0x63654e49, diff --git a/drivers/net/apne.c b/drivers/net/apne.c index b9820b86c..a94216b87 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -217,7 +216,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(" not found (no reset ack).\n"); return -ENODEV; } @@ -383,7 +382,7 @@ apne_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk("%s: ne_reset_8390() did not complete.\n", dev->name); break; } @@ -531,7 +530,7 @@ apne_block_output(struct net_device *dev, int count, dma_start = jiffies; while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk("%s: timeout waiting for Tx RDC.\n", dev->name); apne_reset_8390(dev); NS8390_init(dev,1); diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig index 7284ccad0..948de2532 100644 --- a/drivers/net/arcnet/Kconfig +++ b/drivers/net/arcnet/Kconfig @@ -68,10 +68,10 @@ config ARCNET_CAP packet is stuffed with an extra 4 byte "cookie" which doesn't actually appear on the network. After transmit the driver will send back a packet with protocol byte 0 containing the status of the - transmission: + transmition: 0=no hardware acknowledge 1=excessive nak - 2=transmission accepted by the receiver hardware + 2=transmition accepted by the reciever hardware Received packets are also stuffed with the extra 4 bytes but it will be random data. diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c index e7555d4e6..e1ea29b0c 100644 --- a/drivers/net/arcnet/arc-rawmode.c +++ b/drivers/net/arcnet/arc-rawmode.c @@ -42,7 +42,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev, static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); -static struct ArcProto rawmode_proto = +struct ArcProto rawmode_proto = { .suffix = 'r', .mtu = XMTU, diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 8c8d6c453..38c3f033f 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -97,44 +97,25 @@ static int __init arcrimi_probe(struct net_device *dev) "must specify the shmem and irq!\n"); return -ENODEV; } - if (dev->dev_addr[0] == 0) { - BUGMSG(D_NORMAL, "You need to specify your card's station " - "ID!\n"); - return -ENODEV; - } /* - * Grab the memory region at mem_start for MIRROR_SIZE bytes. + * Grab the memory region at mem_start for BUFFER_SIZE bytes. * Later in arcrimi_found() the real size will be determined * and this reserve will be released and the correct size * will be taken. */ - if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { + if (!request_mem_region(dev->mem_start, BUFFER_SIZE, "arcnet (90xx)")) { BUGMSG(D_NORMAL, "Card memory already allocated\n"); return -ENODEV; } + if (dev->dev_addr[0] == 0) { + release_mem_region(dev->mem_start, BUFFER_SIZE); + BUGMSG(D_NORMAL, "You need to specify your card's station " + "ID!\n"); + return -ENODEV; + } return arcrimi_found(dev); } -static int check_mirror(unsigned long addr, size_t size) -{ - void __iomem *p; - int res = -1; - - if (!request_mem_region(addr, size, "arcnet (90xx)")) - return -1; - - p = ioremap(addr, size); - if (p) { - if (readb(p) == TESTvalue) - res = 1; - else - res = 0; - iounmap(p); - } - - release_mem_region(addr, size); - return res; -} /* * Set up the struct net_device associated with this card. Called after @@ -144,28 +125,19 @@ static int __init arcrimi_found(struct net_device *dev) { struct arcnet_local *lp; unsigned long first_mirror, last_mirror, shmem; - void __iomem *p; int mirror_size; int err; - p = ioremap(dev->mem_start, MIRROR_SIZE); - if (!p) { - release_mem_region(dev->mem_start, MIRROR_SIZE); - BUGMSG(D_NORMAL, "Can't ioremap\n"); - return -ENODEV; - } - /* reserve the irq */ if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) { - iounmap(p); - release_mem_region(dev->mem_start, MIRROR_SIZE); + release_mem_region(dev->mem_start, BUFFER_SIZE); BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); return -ENODEV; } shmem = dev->mem_start; - writeb(TESTvalue, p); - writeb(dev->dev_addr[0], p + 1); /* actually the node ID */ + isa_writeb(TESTvalue, shmem); + isa_writeb(dev->dev_addr[0], shmem + 1); /* actually the node ID */ /* find the real shared memory start/end points, including mirrors */ @@ -174,18 +146,17 @@ static int __init arcrimi_found(struct net_device *dev) * 2k (or there are no mirrors at all) but on some, it's 4k. */ mirror_size = MIRROR_SIZE; - if (readb(p) == TESTvalue - && check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 - && check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1) - mirror_size = 2 * MIRROR_SIZE; + if (isa_readb(shmem) == TESTvalue + && isa_readb(shmem - mirror_size) != TESTvalue + && isa_readb(shmem - 2 * mirror_size) == TESTvalue) + mirror_size *= 2; - first_mirror = shmem - mirror_size; - while (check_mirror(first_mirror, mirror_size) == 1) + first_mirror = last_mirror = shmem; + while (isa_readb(first_mirror) == TESTvalue) first_mirror -= mirror_size; first_mirror += mirror_size; - last_mirror = shmem + mirror_size; - while (check_mirror(last_mirror, mirror_size) == 1) + while (isa_readb(last_mirror) == TESTvalue) last_mirror += mirror_size; last_mirror -= mirror_size; @@ -210,8 +181,7 @@ static int __init arcrimi_found(struct net_device *dev) * with the correct size. There is a VERY slim chance this could * fail. */ - iounmap(p); - release_mem_region(shmem, MIRROR_SIZE); + release_mem_region(shmem, BUFFER_SIZE); if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)")) { diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index fabc0607b..12ef52c19 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -52,7 +52,6 @@ #include #include #include -#include /* "do nothing" functions for protocol drivers */ static void null_rx(struct net_device *dev, int bufnum, @@ -62,7 +61,6 @@ static int null_build_header(struct sk_buff *skb, struct net_device *dev, static int null_prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); -static void arcnet_rx(struct net_device *dev, int bufnum); /* * one ArcProto per possible proto ID. None of the elements of @@ -73,7 +71,7 @@ static void arcnet_rx(struct net_device *dev, int bufnum); struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto, *arc_raw_proto; -static struct ArcProto arc_proto_null = +struct ArcProto arc_proto_null = { .suffix = '?', .mtu = XMTU, @@ -92,6 +90,7 @@ EXPORT_SYMBOL(arc_proto_map); EXPORT_SYMBOL(arc_proto_default); EXPORT_SYMBOL(arc_bcast_proto); EXPORT_SYMBOL(arc_raw_proto); +EXPORT_SYMBOL(arc_proto_null); EXPORT_SYMBOL(arcnet_unregister_proto); EXPORT_SYMBOL(arcnet_debug); EXPORT_SYMBOL(alloc_arcdev); @@ -119,7 +118,7 @@ static int __init arcnet_init(void) arcnet_debug = debug; - printk("arcnet loaded.\n"); + printk(VERSION); #ifdef ALPHA_WARNING BUGLVL(D_EXTRA) { @@ -179,8 +178,8 @@ EXPORT_SYMBOL(arcnet_dump_skb); * Dump the contents of an ARCnet buffer */ #if (ARCNET_DEBUG_MAX & (D_RX | D_TX)) -static void arcnet_dump_packet(struct net_device *dev, int bufnum, - char *desc, int take_arcnet_lock) +void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc, + int take_arcnet_lock) { struct arcnet_local *lp = dev->priv; int i, length; @@ -209,10 +208,7 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum, } -#else - -#define arcnet_dump_packet(dev, bufnum, desc,take_arcnet_lock) do { } while (0) - +EXPORT_SYMBOL(arcnet_dump_packet); #endif @@ -737,7 +733,7 @@ static void arcnet_timeout(struct net_device *dev) spin_unlock_irqrestore(&lp->lock, flags); - if (time_after(jiffies, lp->last_timeout + 10*HZ)) { + if (jiffies - lp->last_timeout > 10*HZ) { BUGMSG(D_EXTRA, "tx timed out%s (status=%Xh, intmask=%Xh, dest=%02Xh)\n", msg, status, lp->intmask, lp->lasttrans_dest); lp->last_timeout = jiffies; @@ -765,7 +761,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) BUGMSG(D_DURING, "in arcnet_interrupt\n"); lp = dev->priv; - BUG_ON(!lp); + if (!lp) + BUG(); spin_lock(&lp->lock); @@ -999,7 +996,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) * This is a generic packet receiver that calls arcnet??_rx depending on the * protocol ID found. */ -static void arcnet_rx(struct net_device *dev, int bufnum) +void arcnet_rx(struct net_device *dev, int bufnum) { struct arcnet_local *lp = dev->priv; struct archdr pkt; diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index 0d45553ff..6c2c9b9ac 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c @@ -53,7 +53,7 @@ /* Internal function declarations */ -static int com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *); +static int com90xx_found(int ioaddr, int airq, u_long shmem); static void com90xx_command(struct net_device *dev, int command); static int com90xx_status(struct net_device *dev); static void com90xx_setmask(struct net_device *dev, int mask); @@ -116,26 +116,14 @@ static void __init com90xx_probe(void) unsigned long airqmask; int ports[(0x3f0 - 0x200) / 16 + 1] = {0}; - unsigned long *shmems; - void __iomem **iomem; + u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] = + {0}; int numports, numshmems, *port; u_long *p; - int index; if (!io && !irq && !shmem && !*device && com90xx_skip_probe) return; - shmems = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(unsigned long), - GFP_KERNEL); - if (!shmems) - return; - iomem = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(void __iomem *), - GFP_KERNEL); - if (!iomem) { - kfree(shmems); - return; - } - BUGLVL(D_NORMAL) printk(VERSION); /* set up the arrays where we'll store the possible probe addresses */ @@ -191,8 +179,6 @@ static void __init com90xx_probe(void) if (!numports) { BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n"); - kfree(shmems); - kfree(iomem); return; } /* Stage 2: we have now reset any possible ARCnet cards, so we can't @@ -216,8 +202,8 @@ static void __init com90xx_probe(void) * 0xD1 byte in the right place, or are read-only. */ numprint = -1; - for (index = 0, p = &shmems[0]; index < numshmems; p++, index++) { - void __iomem *base; + for (p = &shmems[0]; p < shmems + numshmems; p++) { + u_long ptr = *p; numprint++; numprint %= 8; @@ -227,49 +213,38 @@ static void __init com90xx_probe(void) } BUGMSG2(D_INIT, "%lXh ", *p); - if (!request_mem_region(*p, MIRROR_SIZE, "arcnet (90xx)")) { + if (!request_mem_region(*p, BUFFER_SIZE, "arcnet (90xx)")) { BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n"); BUGMSG2(D_INIT_REASONS, "Stage 3: "); BUGLVL(D_INIT_REASONS) numprint = 0; - goto out; - } - base = ioremap(*p, MIRROR_SIZE); - if (!base) { - BUGMSG2(D_INIT_REASONS, "(ioremap)\n"); - BUGMSG2(D_INIT_REASONS, "Stage 3: "); - BUGLVL(D_INIT_REASONS) numprint = 0; - goto out1; + *p-- = shmems[--numshmems]; + continue; } - if (readb(base) != TESTvalue) { + if (isa_readb(ptr) != TESTvalue) { BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n", - readb(base), TESTvalue); + isa_readb(ptr), TESTvalue); BUGMSG2(D_INIT_REASONS, "S3: "); BUGLVL(D_INIT_REASONS) numprint = 0; - goto out2; + release_mem_region(*p, BUFFER_SIZE); + *p-- = shmems[--numshmems]; + continue; } /* By writing 0x42 to the TESTvalue location, we also make * sure no "mirror" shmem areas show up - if they occur * in another pass through this loop, they will be discarded * because *cptr != TESTvalue. */ - writeb(0x42, base); - if (readb(base) != 0x42) { + isa_writeb(0x42, ptr); + if (isa_readb(ptr) != 0x42) { BUGMSG2(D_INIT_REASONS, "(read only)\n"); BUGMSG2(D_INIT_REASONS, "S3: "); - goto out2; + release_mem_region(*p, BUFFER_SIZE); + *p-- = shmems[--numshmems]; + continue; } BUGMSG2(D_INIT_REASONS, "\n"); BUGMSG2(D_INIT_REASONS, "S3: "); BUGLVL(D_INIT_REASONS) numprint = 0; - iomem[index] = base; - continue; - out2: - iounmap(base); - out1: - release_mem_region(*p, MIRROR_SIZE); - out: - *p-- = shmems[--numshmems]; - index--; } BUGMSG2(D_INIT, "\n"); @@ -277,8 +252,6 @@ static void __init com90xx_probe(void) BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n"); for (port = &ports[0]; port < ports + numports; port++) release_region(*port, ARCNET_TOTAL_SIZE); - kfree(shmems); - kfree(iomem); return; } /* Stage 4: something of a dummy, to report the shmems that are @@ -378,32 +351,30 @@ static void __init com90xx_probe(void) mdelay(RESETtime); } else { /* just one shmem and port, assume they match */ - writeb(TESTvalue, iomem[0]); + isa_writeb(TESTvalue, shmems[0]); } #else inb(_RESET); mdelay(RESETtime); #endif - for (index = 0; index < numshmems; index++) { - u_long ptr = shmems[index]; - void __iomem *base = iomem[index]; + for (p = &shmems[0]; p < shmems + numshmems; p++) { + u_long ptr = *p; - if (readb(base) == TESTvalue) { /* found one */ + if (isa_readb(ptr) == TESTvalue) { /* found one */ BUGMSG2(D_INIT, "%lXh)\n", *p); openparen = 0; /* register the card */ - if (com90xx_found(*port, airq, ptr, base) == 0) + if (com90xx_found(*port, airq, *p) == 0) found = 1; numprint = -1; /* remove shmem from the list */ - shmems[index] = shmems[--numshmems]; - iomem[index] = iomem[numshmems]; + *p = shmems[--numshmems]; break; /* go to the next I/O port */ } else { - BUGMSG2(D_INIT_REASONS, "%Xh-", readb(base)); + BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr)); } } @@ -420,40 +391,17 @@ static void __init com90xx_probe(void) BUGLVL(D_INIT_REASONS) printk("\n"); /* Now put back TESTvalue on all leftover shmems. */ - for (index = 0; index < numshmems; index++) { - writeb(TESTvalue, iomem[index]); - iounmap(iomem[index]); - release_mem_region(shmems[index], MIRROR_SIZE); + for (p = &shmems[0]; p < shmems + numshmems; p++) { + isa_writeb(TESTvalue, *p); + release_mem_region(*p, BUFFER_SIZE); } - kfree(shmems); - kfree(iomem); } -static int check_mirror(unsigned long addr, size_t size) -{ - void __iomem *p; - int res = -1; - - if (!request_mem_region(addr, size, "arcnet (90xx)")) - return -1; - - p = ioremap(addr, size); - if (p) { - if (readb(p) == TESTvalue) - res = 1; - else - res = 0; - iounmap(p); - } - - release_mem_region(addr, size); - return res; -} /* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *p) +static int __init com90xx_found(int ioaddr, int airq, u_long shmem) { struct net_device *dev = NULL; struct arcnet_local *lp; @@ -464,8 +412,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem dev = alloc_arcdev(device); if (!dev) { BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n"); - iounmap(p); - release_mem_region(shmem, MIRROR_SIZE); + release_mem_region(shmem, BUFFER_SIZE); return -ENOMEM; } lp = dev->priv; @@ -476,27 +423,24 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem * 2k (or there are no mirrors at all) but on some, it's 4k. */ mirror_size = MIRROR_SIZE; - if (readb(p) == TESTvalue && - check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 && - check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1) - mirror_size = 2 * MIRROR_SIZE; + if (isa_readb(shmem) == TESTvalue + && isa_readb(shmem - mirror_size) != TESTvalue + && isa_readb(shmem - 2 * mirror_size) == TESTvalue) + mirror_size *= 2; - first_mirror = shmem - mirror_size; - while (check_mirror(first_mirror, mirror_size) == 1) + first_mirror = last_mirror = shmem; + while (isa_readb(first_mirror) == TESTvalue) first_mirror -= mirror_size; first_mirror += mirror_size; - last_mirror = shmem + mirror_size; - while (check_mirror(last_mirror, mirror_size) == 1) + while (isa_readb(last_mirror) == TESTvalue) last_mirror += mirror_size; last_mirror -= mirror_size; dev->mem_start = first_mirror; dev->mem_end = last_mirror + MIRROR_SIZE - 1; - iounmap(p); - release_mem_region(shmem, MIRROR_SIZE); - + release_mem_region(shmem, BUFFER_SIZE); if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)")) goto err_free_dev; diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c index 6d6c69f03..6d7913704 100644 --- a/drivers/net/arcnet/rfc1051.c +++ b/drivers/net/arcnet/rfc1051.c @@ -43,7 +43,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); -static struct ArcProto rfc1051_proto = +struct ArcProto rfc1051_proto = { .suffix = 's', .mtu = XMTU - RFC1051_HDR_SIZE, diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c index bee34226a..6b6ae4bf3 100644 --- a/drivers/net/arcnet/rfc1201.c +++ b/drivers/net/arcnet/rfc1201.c @@ -43,7 +43,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); static int continue_tx(struct net_device *dev, int bufnum); -static struct ArcProto rfc1201_proto = +struct ArcProto rfc1201_proto = { .suffix = 'a', .mtu = 1500, /* could be more, but some receivers can't handle it... */ diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index d1b6b1f79..9fe93acfc 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -864,7 +864,7 @@ static void __devexit ariadne_remove_one(struct zorro_dev *z) static int __init ariadne_init_module(void) { - return zorro_register_driver(&ariadne_driver); + return zorro_module_init(&ariadne_driver); } static void __exit ariadne_cleanup_module(void) diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index 77fe20dbe..625184b65 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig @@ -31,11 +31,3 @@ config ARM_ETHERH help If you have an Acorn system with one of these network cards, you should say Y to this option if you wish to use it with Linux. - -config ARM_AT91_ETHER - tristate "AT91RM9200 Ethernet support" - depends on NET_ETHERNET && ARM && ARCH_AT91RM9200 - select MII - help - If you wish to compile a kernel for the AT91RM9200 and enable - ethernet support, then you should always answer Y to this. diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index 42c95b79c..bc263edf0 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile @@ -7,4 +7,3 @@ obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o obj-$(CONFIG_ARM_ETHERH) += etherh.o obj-$(CONFIG_ARM_ETHER3) += ether3.o obj-$(CONFIG_ARM_ETHER1) += ether1.o -obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 09d5c3f26..53e3afc1b 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -696,9 +696,7 @@ static int __init am79c961_probe(struct platform_device *pdev) dev->base_addr = res->start; dev->irq = platform_get_irq(pdev, 0); - ret = -ENODEV; - if (dev->irq < 0) - goto nodev; + ret = -ENODEV; if (!request_region(dev->base_addr, 0x18, dev->name)) goto nodev; diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c deleted file mode 100644 index 5503dc8a6..000000000 --- a/drivers/net/arm/at91_ether.c +++ /dev/null @@ -1,1110 +0,0 @@ -/* - * Ethernet driver for the Atmel AT91RM9200 (Thunder) - * - * Copyright (C) 2003 SAN People (Pty) Ltd - * - * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc. - * Initial version by Rick Bronson 01/11/2003 - * - * Intel LXT971A PHY support by Christopher Bahns & David Knickerbocker - * (Polaroid Corporation) - * - * Realtek RTL8201(B)L PHY support by Roman Avramenko - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "at91_ether.h" - -#define DRV_NAME "at91_ether" -#define DRV_VERSION "1.0" - -static struct net_device *at91_dev; -static struct clk *ether_clk; - -/* ..................................................................... */ - -/* - * Read from a EMAC register. - */ -static inline unsigned long at91_emac_read(unsigned int reg) -{ - void __iomem *emac_base = (void __iomem *)AT91_VA_BASE_EMAC; - - return __raw_readl(emac_base + reg); -} - -/* - * Write to a EMAC register. - */ -static inline void at91_emac_write(unsigned int reg, unsigned long value) -{ - void __iomem *emac_base = (void __iomem *)AT91_VA_BASE_EMAC; - - __raw_writel(value, emac_base + reg); -} - -/* ........................... PHY INTERFACE ........................... */ - -/* - * Enable the MDIO bit in MAC control register - * When not called from an interrupt-handler, access to the PHY must be - * protected by a spinlock. - */ -static void enable_mdi(void) -{ - unsigned long ctl; - - ctl = at91_emac_read(AT91_EMAC_CTL); - at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_MPE); /* enable management port */ -} - -/* - * Disable the MDIO bit in the MAC control register - */ -static void disable_mdi(void) -{ - unsigned long ctl; - - ctl = at91_emac_read(AT91_EMAC_CTL); - at91_emac_write(AT91_EMAC_CTL, ctl & ~AT91_EMAC_MPE); /* disable management port */ -} - -/* - * Wait until the PHY operation is complete. - */ -static inline void at91_phy_wait(void) { - unsigned long timeout = jiffies + 2; - - while (!(at91_emac_read(AT91_EMAC_SR) & AT91_EMAC_SR_IDLE)) { - if (time_after(jiffies, timeout)) { - printk("at91_ether: MIO timeout\n"); - break; - } - cpu_relax(); - } -} - -/* - * Write value to the a PHY register - * Note: MDI interface is assumed to already have been enabled. - */ -static void write_phy(unsigned char phy_addr, unsigned char address, unsigned int value) -{ - at91_emac_write(AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_W - | ((phy_addr & 0x1f) << 23) | (address << 18) | (value & AT91_EMAC_DATA)); - - /* Wait until IDLE bit in Network Status register is cleared */ - at91_phy_wait(); -} - -/* - * Read value stored in a PHY register. - * Note: MDI interface is assumed to already have been enabled. - */ -static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int *value) -{ - at91_emac_write(AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_R - | ((phy_addr & 0x1f) << 23) | (address << 18)); - - /* Wait until IDLE bit in Network Status register is cleared */ - at91_phy_wait(); - - *value = at91_emac_read(AT91_EMAC_MAN) & AT91_EMAC_DATA; -} - -/* ........................... PHY MANAGEMENT .......................... */ - -/* - * Access the PHY to determine the current link speed and mode, and update the - * MAC accordingly. - * If no link or auto-negotiation is busy, then no changes are made. - */ -static void update_linkspeed(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - unsigned int bmsr, bmcr, lpa, mac_cfg; - unsigned int speed, duplex; - - if (!mii_link_ok(&lp->mii)) { /* no link */ - netif_carrier_off(dev); - printk(KERN_INFO "%s: Link down.\n", dev->name); - return; - } - - /* Link up, or auto-negotiation still in progress */ - read_phy(lp->phy_address, MII_BMSR, &bmsr); - read_phy(lp->phy_address, MII_BMCR, &bmcr); - if (bmcr & BMCR_ANENABLE) { /* AutoNegotiation is enabled */ - if (!(bmsr & BMSR_ANEGCOMPLETE)) - return; /* Do nothing - another interrupt generated when negotiation complete */ - - read_phy(lp->phy_address, MII_LPA, &lpa); - if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100; - else speed = SPEED_10; - if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL; - else duplex = DUPLEX_HALF; - } else { - speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10; - duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; - } - - /* Update the MAC */ - mac_cfg = at91_emac_read(AT91_EMAC_CFG) & ~(AT91_EMAC_SPD | AT91_EMAC_FD); - if (speed == SPEED_100) { - if (duplex == DUPLEX_FULL) /* 100 Full Duplex */ - mac_cfg |= AT91_EMAC_SPD | AT91_EMAC_FD; - else /* 100 Half Duplex */ - mac_cfg |= AT91_EMAC_SPD; - } else { - if (duplex == DUPLEX_FULL) /* 10 Full Duplex */ - mac_cfg |= AT91_EMAC_FD; - else {} /* 10 Half Duplex */ - } - at91_emac_write(AT91_EMAC_CFG, mac_cfg); - - printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); - netif_carrier_on(dev); -} - -/* - * Handle interrupts from the PHY - */ -static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct at91_private *lp = (struct at91_private *) dev->priv; - unsigned int phy; - - /* - * This hander is triggered on both edges, but the PHY chips expect - * level-triggering. We therefore have to check if the PHY actually has - * an IRQ pending. - */ - enable_mdi(); - if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { - read_phy(lp->phy_address, MII_DSINTR_REG, &phy); /* ack interrupt in Davicom PHY */ - if (!(phy & (1 << 0))) - goto done; - } - else if (lp->phy_type == MII_LXT971A_ID) { - read_phy(lp->phy_address, MII_ISINTS_REG, &phy); /* ack interrupt in Intel PHY */ - if (!(phy & (1 << 2))) - goto done; - } - else if (lp->phy_type == MII_BCM5221_ID) { - read_phy(lp->phy_address, MII_BCMINTR_REG, &phy); /* ack interrupt in Broadcom PHY */ - if (!(phy & (1 << 0))) - goto done; - } - else if (lp->phy_type == MII_KS8721_ID) { - read_phy(lp->phy_address, MII_TPISTATUS, &phy); /* ack interrupt in Micrel PHY */ - if (!(phy & ((1 << 2) | 1))) - goto done; - } - - update_linkspeed(dev); - -done: - disable_mdi(); - - return IRQ_HANDLED; -} - -/* - * Initialize and enable the PHY interrupt for link-state changes - */ -static void enable_phyirq(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - unsigned int dsintr, irq_number; - int status; - - if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ - return; - if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ - return; - if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ - return; - - irq_number = lp->board_data.phy_irq_pin; - status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); - if (status) { - printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); - return; - } - - spin_lock_irq(&lp->lock); - enable_mdi(); - - if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { /* for Davicom PHY */ - read_phy(lp->phy_address, MII_DSINTR_REG, &dsintr); - dsintr = dsintr & ~0xf00; /* clear bits 8..11 */ - write_phy(lp->phy_address, MII_DSINTR_REG, dsintr); - } - else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */ - read_phy(lp->phy_address, MII_ISINTE_REG, &dsintr); - dsintr = dsintr | 0xf2; /* set bits 1, 4..7 */ - write_phy(lp->phy_address, MII_ISINTE_REG, dsintr); - } - else if (lp->phy_type == MII_BCM5221_ID) { /* for Broadcom PHY */ - dsintr = (1 << 15) | ( 1 << 14); - write_phy(lp->phy_address, MII_BCMINTR_REG, dsintr); - } - else if (lp->phy_type == MII_KS8721_ID) { /* for Micrel PHY */ - dsintr = (1 << 10) | ( 1 << 8); - write_phy(lp->phy_address, MII_TPISTATUS, dsintr); - } - - disable_mdi(); - spin_unlock_irq(&lp->lock); -} - -/* - * Disable the PHY interrupt - */ -static void disable_phyirq(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - unsigned int dsintr; - unsigned int irq_number; - - if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ - return; - if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ - return; - if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ - return; - - spin_lock_irq(&lp->lock); - enable_mdi(); - - if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { /* for Davicom PHY */ - read_phy(lp->phy_address, MII_DSINTR_REG, &dsintr); - dsintr = dsintr | 0xf00; /* set bits 8..11 */ - write_phy(lp->phy_address, MII_DSINTR_REG, dsintr); - } - else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */ - read_phy(lp->phy_address, MII_ISINTE_REG, &dsintr); - dsintr = dsintr & ~0xf2; /* clear bits 1, 4..7 */ - write_phy(lp->phy_address, MII_ISINTE_REG, dsintr); - } - else if (lp->phy_type == MII_BCM5221_ID) { /* for Broadcom PHY */ - read_phy(lp->phy_address, MII_BCMINTR_REG, &dsintr); - dsintr = ~(1 << 14); - write_phy(lp->phy_address, MII_BCMINTR_REG, dsintr); - } - else if (lp->phy_type == MII_KS8721_ID) { /* for Micrel PHY */ - read_phy(lp->phy_address, MII_TPISTATUS, &dsintr); - dsintr = ~((1 << 10) | (1 << 8)); - write_phy(lp->phy_address, MII_TPISTATUS, dsintr); - } - - disable_mdi(); - spin_unlock_irq(&lp->lock); - - irq_number = lp->board_data.phy_irq_pin; - free_irq(irq_number, dev); /* Free interrupt handler */ -} - -/* - * Perform a software reset of the PHY. - */ -#if 0 -static void reset_phy(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - unsigned int bmcr; - - spin_lock_irq(&lp->lock); - enable_mdi(); - - /* Perform PHY reset */ - write_phy(lp->phy_address, MII_BMCR, BMCR_RESET); - - /* Wait until PHY reset is complete */ - do { - read_phy(lp->phy_address, MII_BMCR, &bmcr); - } while (!(bmcr && BMCR_RESET)); - - disable_mdi(); - spin_unlock_irq(&lp->lock); -} -#endif - -/* ......................... ADDRESS MANAGEMENT ........................ */ - -/* - * NOTE: Your bootloader must always set the MAC address correctly before - * booting into Linux. - * - * - It must always set the MAC address after reset, even if it doesn't - * happen to access the Ethernet while it's booting. Some versions of - * U-Boot on the AT91RM9200-DK do not do this. - * - * - Likewise it must store the addresses in the correct byte order. - * MicroMonitor (uMon) on the CSB337 does this incorrectly (and - * continues to do so, for bug-compatibility). - */ - -static short __init unpack_mac_address(struct net_device *dev, unsigned int hi, unsigned int lo) -{ - char addr[6]; - - if (machine_is_csb337()) { - addr[5] = (lo & 0xff); /* The CSB337 bootloader stores the MAC the wrong-way around */ - addr[4] = (lo & 0xff00) >> 8; - addr[3] = (lo & 0xff0000) >> 16; - addr[2] = (lo & 0xff000000) >> 24; - addr[1] = (hi & 0xff); - addr[0] = (hi & 0xff00) >> 8; - } - else { - addr[0] = (lo & 0xff); - addr[1] = (lo & 0xff00) >> 8; - addr[2] = (lo & 0xff0000) >> 16; - addr[3] = (lo & 0xff000000) >> 24; - addr[4] = (hi & 0xff); - addr[5] = (hi & 0xff00) >> 8; - } - - if (is_valid_ether_addr(addr)) { - memcpy(dev->dev_addr, &addr, 6); - return 1; - } - return 0; -} - -/* - * Set the ethernet MAC address in dev->dev_addr - */ -static void __init get_mac_address(struct net_device *dev) -{ - /* Check Specific-Address 1 */ - if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA1H), at91_emac_read(AT91_EMAC_SA1L))) - return; - /* Check Specific-Address 2 */ - if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA2H), at91_emac_read(AT91_EMAC_SA2L))) - return; - /* Check Specific-Address 3 */ - if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA3H), at91_emac_read(AT91_EMAC_SA3L))) - return; - /* Check Specific-Address 4 */ - if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA4H), at91_emac_read(AT91_EMAC_SA4L))) - return; - - printk(KERN_ERR "at91_ether: Your bootloader did not configure a MAC address.\n"); -} - -/* - * Program the hardware MAC address from dev->dev_addr. - */ -static void update_mac_address(struct net_device *dev) -{ - at91_emac_write(AT91_EMAC_SA1L, (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) | (dev->dev_addr[1] << 8) | (dev->dev_addr[0])); - at91_emac_write(AT91_EMAC_SA1H, (dev->dev_addr[5] << 8) | (dev->dev_addr[4])); - - at91_emac_write(AT91_EMAC_SA2L, 0); - at91_emac_write(AT91_EMAC_SA2H, 0); -} - -/* - * Store the new hardware address in dev->dev_addr, and update the MAC. - */ -static int set_mac_address(struct net_device *dev, void* addr) -{ - struct sockaddr *address = addr; - - if (!is_valid_ether_addr(address->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(dev->dev_addr, address->sa_data, dev->addr_len); - update_mac_address(dev); - - printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - - return 0; -} - -static int inline hash_bit_value(int bitnr, __u8 *addr) -{ - if (addr[bitnr / 8] & (1 << (bitnr % 8))) - return 1; - return 0; -} - -/* - * The hash address register is 64 bits long and takes up two locations in the memory map. - * The least significant bits are stored in EMAC_HSL and the most significant - * bits in EMAC_HSH. - * - * The unicast hash enable and the multicast hash enable bits in the network configuration - * register enable the reception of hash matched frames. The destination address is - * reduced to a 6 bit index into the 64 bit hash register using the following hash function. - * The hash function is an exclusive or of every sixth bit of the destination address. - * hash_index[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47] - * hash_index[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46] - * hash_index[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45] - * hash_index[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44] - * hash_index[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43] - * hash_index[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42] - * da[0] represents the least significant bit of the first byte received, that is, the multicast/ - * unicast indicator, and da[47] represents the most significant bit of the last byte - * received. - * If the hash index points to a bit that is set in the hash register then the frame will be - * matched according to whether the frame is multicast or unicast. - * A multicast match will be signalled if the multicast hash enable bit is set, da[0] is 1 and - * the hash index points to a bit set in the hash register. - * A unicast match will be signalled if the unicast hash enable bit is set, da[0] is 0 and the - * hash index points to a bit set in the hash register. - * To receive all multicast frames, the hash register should be set with all ones and the - * multicast hash enable bit should be set in the network configuration register. - */ - -/* - * Return the hash index value for the specified address. - */ -static int hash_get_index(__u8 *addr) -{ - int i, j, bitval; - int hash_index = 0; - - for (j = 0; j < 6; j++) { - for (i = 0, bitval = 0; i < 8; i++) - bitval ^= hash_bit_value(i*6 + j, addr); - - hash_index |= (bitval << j); - } - - return hash_index; -} - -/* - * Add multicast addresses to the internal multicast-hash table. - */ -static void at91ether_sethashtable(struct net_device *dev) -{ - struct dev_mc_list *curr; - unsigned long mc_filter[2]; - unsigned int i, bitnr; - - mc_filter[0] = mc_filter[1] = 0; - - curr = dev->mc_list; - for (i = 0; i < dev->mc_count; i++, curr = curr->next) { - if (!curr) break; /* unexpected end of list */ - - bitnr = hash_get_index(curr->dmi_addr); - mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); - } - - at91_emac_write(AT91_EMAC_HSH, mc_filter[0]); - at91_emac_write(AT91_EMAC_HSL, mc_filter[1]); -} - -/* - * Enable/Disable promiscuous and multicast modes. - */ -static void at91ether_set_rx_mode(struct net_device *dev) -{ - unsigned long cfg; - - cfg = at91_emac_read(AT91_EMAC_CFG); - - if (dev->flags & IFF_PROMISC) /* Enable promiscuous mode */ - cfg |= AT91_EMAC_CAF; - else if (dev->flags & (~IFF_PROMISC)) /* Disable promiscuous mode */ - cfg &= ~AT91_EMAC_CAF; - - if (dev->flags & IFF_ALLMULTI) { /* Enable all multicast mode */ - at91_emac_write(AT91_EMAC_HSH, -1); - at91_emac_write(AT91_EMAC_HSL, -1); - cfg |= AT91_EMAC_MTI; - } else if (dev->mc_count > 0) { /* Enable specific multicasts */ - at91ether_sethashtable(dev); - cfg |= AT91_EMAC_MTI; - } else if (dev->flags & (~IFF_ALLMULTI)) { /* Disable all multicast mode */ - at91_emac_write(AT91_EMAC_HSH, 0); - at91_emac_write(AT91_EMAC_HSL, 0); - cfg &= ~AT91_EMAC_MTI; - } - - at91_emac_write(AT91_EMAC_CFG, cfg); -} - - -/* ......................... ETHTOOL SUPPORT ........................... */ - - -static int mdio_read(struct net_device *dev, int phy_id, int location) -{ - unsigned int value; - - read_phy(phy_id, location, &value); - return value; -} - -static void mdio_write(struct net_device *dev, int phy_id, int location, int value) -{ - write_phy(phy_id, location, value); -} - -static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - int ret; - - spin_lock_irq(&lp->lock); - enable_mdi(); - - ret = mii_ethtool_gset(&lp->mii, cmd); - - disable_mdi(); - spin_unlock_irq(&lp->lock); - - if (lp->phy_media == PORT_FIBRE) { /* override media type since mii.c doesn't know */ - cmd->supported = SUPPORTED_FIBRE; - cmd->port = PORT_FIBRE; - } - - return ret; -} - -static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - int ret; - - spin_lock_irq(&lp->lock); - enable_mdi(); - - ret = mii_ethtool_sset(&lp->mii, cmd); - - disable_mdi(); - spin_unlock_irq(&lp->lock); - - return ret; -} - -static int at91ether_nwayreset(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - int ret; - - spin_lock_irq(&lp->lock); - enable_mdi(); - - ret = mii_nway_restart(&lp->mii); - - disable_mdi(); - spin_unlock_irq(&lp->lock); - - return ret; -} - -static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_VERSION, sizeof(info->version)); - strlcpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info)); -} - -static struct ethtool_ops at91ether_ethtool_ops = { - .get_settings = at91ether_get_settings, - .set_settings = at91ether_set_settings, - .get_drvinfo = at91ether_get_drvinfo, - .nway_reset = at91ether_nwayreset, - .get_link = ethtool_op_get_link, -}; - - -/* ................................ MAC ................................ */ - -/* - * Initialize and start the Receiver and Transmit subsystems - */ -static void at91ether_start(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - struct recv_desc_bufs *dlist, *dlist_phys; - int i; - unsigned long ctl; - - dlist = lp->dlist; - dlist_phys = lp->dlist_phys; - - for (i = 0; i < MAX_RX_DESCR; i++) { - dlist->descriptors[i].addr = (unsigned int) &dlist_phys->recv_buf[i][0]; - dlist->descriptors[i].size = 0; - } - - /* Set the Wrap bit on the last descriptor */ - dlist->descriptors[i-1].addr |= EMAC_DESC_WRAP; - - /* Reset buffer index */ - lp->rxBuffIndex = 0; - - /* Program address of descriptor list in Rx Buffer Queue register */ - at91_emac_write(AT91_EMAC_RBQP, (unsigned long) dlist_phys); - - /* Enable Receive and Transmit */ - ctl = at91_emac_read(AT91_EMAC_CTL); - at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_RE | AT91_EMAC_TE); -} - -/* - * Open the ethernet interface - */ -static int at91ether_open(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - unsigned long ctl; - - if (!is_valid_ether_addr(dev->dev_addr)) - return -EADDRNOTAVAIL; - - clk_enable(ether_clk); /* Re-enable Peripheral clock */ - - /* Clear internal statistics */ - ctl = at91_emac_read(AT91_EMAC_CTL); - at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_CSR); - - /* Update the MAC address (incase user has changed it) */ - update_mac_address(dev); - - /* Enable PHY interrupt */ - enable_phyirq(dev); - - /* Enable MAC interrupts */ - at91_emac_write(AT91_EMAC_IER, AT91_EMAC_RCOM | AT91_EMAC_RBNA - | AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM - | AT91_EMAC_ROVR | AT91_EMAC_ABT); - - /* Determine current link speed */ - spin_lock_irq(&lp->lock); - enable_mdi(); - update_linkspeed(dev); - disable_mdi(); - spin_unlock_irq(&lp->lock); - - at91ether_start(dev); - netif_start_queue(dev); - return 0; -} - -/* - * Close the interface - */ -static int at91ether_close(struct net_device *dev) -{ - unsigned long ctl; - - /* Disable Receiver and Transmitter */ - ctl = at91_emac_read(AT91_EMAC_CTL); - at91_emac_write(AT91_EMAC_CTL, ctl & ~(AT91_EMAC_TE | AT91_EMAC_RE)); - - /* Disable PHY interrupt */ - disable_phyirq(dev); - - /* Disable MAC interrupts */ - at91_emac_write(AT91_EMAC_IDR, AT91_EMAC_RCOM | AT91_EMAC_RBNA - | AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM - | AT91_EMAC_ROVR | AT91_EMAC_ABT); - - netif_stop_queue(dev); - - clk_disable(ether_clk); /* Disable Peripheral clock */ - - return 0; -} - -/* - * Transmit packet. - */ -static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - - if (at91_emac_read(AT91_EMAC_TSR) & AT91_EMAC_TSR_BNQ) { - netif_stop_queue(dev); - - /* Store packet information (to free when Tx completed) */ - lp->skb = skb; - lp->skb_length = skb->len; - lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE); - lp->stats.tx_bytes += skb->len; - - /* Set address of the data in the Transmit Address register */ - at91_emac_write(AT91_EMAC_TAR, lp->skb_physaddr); - /* Set length of the packet in the Transmit Control register */ - at91_emac_write(AT91_EMAC_TCR, skb->len); - - dev->trans_start = jiffies; - } else { - printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n"); - return 1; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb) - on this skb, he also reports -ENETDOWN and printk's, so either - we free and return(0) or don't free and return 1 */ - } - - return 0; -} - -/* - * Update the current statistics from the internal statistics registers. - */ -static struct net_device_stats *at91ether_stats(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - int ale, lenerr, seqe, lcol, ecol; - - if (netif_running(dev)) { - lp->stats.rx_packets += at91_emac_read(AT91_EMAC_OK); /* Good frames received */ - ale = at91_emac_read(AT91_EMAC_ALE); - lp->stats.rx_frame_errors += ale; /* Alignment errors */ - lenerr = at91_emac_read(AT91_EMAC_ELR) + at91_emac_read(AT91_EMAC_USF); - lp->stats.rx_length_errors += lenerr; /* Excessive Length or Undersize Frame error */ - seqe = at91_emac_read(AT91_EMAC_SEQE); - lp->stats.rx_crc_errors += seqe; /* CRC error */ - lp->stats.rx_fifo_errors += at91_emac_read(AT91_EMAC_DRFC); /* Receive buffer not available */ - lp->stats.rx_errors += (ale + lenerr + seqe - + at91_emac_read(AT91_EMAC_CDE) + at91_emac_read(AT91_EMAC_RJB)); - - lp->stats.tx_packets += at91_emac_read(AT91_EMAC_FRA); /* Frames successfully transmitted */ - lp->stats.tx_fifo_errors += at91_emac_read(AT91_EMAC_TUE); /* Transmit FIFO underruns */ - lp->stats.tx_carrier_errors += at91_emac_read(AT91_EMAC_CSE); /* Carrier Sense errors */ - lp->stats.tx_heartbeat_errors += at91_emac_read(AT91_EMAC_SQEE);/* Heartbeat error */ - - lcol = at91_emac_read(AT91_EMAC_LCOL); - ecol = at91_emac_read(AT91_EMAC_ECOL); - lp->stats.tx_window_errors += lcol; /* Late collisions */ - lp->stats.tx_aborted_errors += ecol; /* 16 collisions */ - - lp->stats.collisions += (at91_emac_read(AT91_EMAC_SCOL) + at91_emac_read(AT91_EMAC_MCOL) + lcol + ecol); - } - return &lp->stats; -} - -/* - * Extract received frame from buffer descriptors and sent to upper layers. - * (Called from interrupt context) - */ -static void at91ether_rx(struct net_device *dev) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - struct recv_desc_bufs *dlist; - unsigned char *p_recv; - struct sk_buff *skb; - unsigned int pktlen; - - dlist = lp->dlist; - while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) { - p_recv = dlist->recv_buf[lp->rxBuffIndex]; - pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff; /* Length of frame including FCS */ - skb = alloc_skb(pktlen + 2, GFP_ATOMIC); - if (skb != NULL) { - skb_reserve(skb, 2); - memcpy(skb_put(skb, pktlen), p_recv, pktlen); - - skb->dev = dev; - skb->protocol = eth_type_trans(skb, dev); - skb->len = pktlen; - dev->last_rx = jiffies; - lp->stats.rx_bytes += pktlen; - netif_rx(skb); - } - else { - lp->stats.rx_dropped += 1; - printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); - } - - if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST) - lp->stats.multicast++; - - dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE; /* reset ownership bit */ - if (lp->rxBuffIndex == MAX_RX_DESCR-1) /* wrap after last buffer */ - lp->rxBuffIndex = 0; - else - lp->rxBuffIndex++; - } -} - -/* - * MAC interrupt handler - */ -static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct at91_private *lp = (struct at91_private *) dev->priv; - unsigned long intstatus, ctl; - - /* MAC Interrupt Status register indicates what interrupts are pending. - It is automatically cleared once read. */ - intstatus = at91_emac_read(AT91_EMAC_ISR); - - if (intstatus & AT91_EMAC_RCOM) /* Receive complete */ - at91ether_rx(dev); - - if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ - /* The TCOM bit is set even if the transmission failed. */ - if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY)) - lp->stats.tx_errors += 1; - - if (lp->skb) { - dev_kfree_skb_irq(lp->skb); - lp->skb = NULL; - dma_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, DMA_TO_DEVICE); - } - netif_wake_queue(dev); - } - - /* Work-around for Errata #11 */ - if (intstatus & AT91_EMAC_RBNA) { - ctl = at91_emac_read(AT91_EMAC_CTL); - at91_emac_write(AT91_EMAC_CTL, ctl & ~AT91_EMAC_RE); - at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_RE); - } - - if (intstatus & AT91_EMAC_ROVR) - printk("%s: ROVR error\n", dev->name); - - return IRQ_HANDLED; -} - -/* - * Initialize the ethernet interface - */ -static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, struct platform_device *pdev) -{ - struct at91_eth_data *board_data = pdev->dev.platform_data; - struct net_device *dev; - struct at91_private *lp; - unsigned int val; - int res; - - if (at91_dev) /* already initialized */ - return 0; - - dev = alloc_etherdev(sizeof(struct at91_private)); - if (!dev) - return -ENOMEM; - - dev->base_addr = AT91_VA_BASE_EMAC; - dev->irq = AT91_ID_EMAC; - SET_MODULE_OWNER(dev); - - /* Install the interrupt handler */ - if (request_irq(dev->irq, at91ether_interrupt, 0, dev->name, dev)) { - free_netdev(dev); - return -EBUSY; - } - - /* Allocate memory for DMA Receive descriptors */ - lp = (struct at91_private *)dev->priv; - lp->dlist = (struct recv_desc_bufs *) dma_alloc_coherent(NULL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys, GFP_KERNEL); - if (lp->dlist == NULL) { - free_irq(dev->irq, dev); - free_netdev(dev); - return -ENOMEM; - } - lp->board_data = *board_data; - platform_set_drvdata(pdev, dev); - - spin_lock_init(&lp->lock); - - ether_setup(dev); - dev->open = at91ether_open; - dev->stop = at91ether_close; - dev->hard_start_xmit = at91ether_tx; - dev->get_stats = at91ether_stats; - dev->set_multicast_list = at91ether_set_rx_mode; - dev->set_mac_address = set_mac_address; - dev->ethtool_ops = &at91ether_ethtool_ops; - - SET_NETDEV_DEV(dev, &pdev->dev); - - get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */ - update_mac_address(dev); /* Program ethernet address into MAC */ - - at91_emac_write(AT91_EMAC_CTL, 0); - - if (lp->board_data.is_rmii) - at91_emac_write(AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG | AT91_EMAC_RMII); - else - at91_emac_write(AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG); - - /* Perform PHY-specific initialization */ - spin_lock_irq(&lp->lock); - enable_mdi(); - if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { - read_phy(phy_address, MII_DSCR_REG, &val); - if ((val & (1 << 10)) == 0) /* DSCR bit 10 is 0 -- fiber mode */ - lp->phy_media = PORT_FIBRE; - } else if (machine_is_csb337()) { - /* mix link activity status into LED2 link state */ - write_phy(phy_address, MII_LEDCTRL_REG, 0x0d22); - } - disable_mdi(); - spin_unlock_irq(&lp->lock); - - lp->mii.dev = dev; /* Support for ethtool */ - lp->mii.mdio_read = mdio_read; - lp->mii.mdio_write = mdio_write; - - lp->phy_type = phy_type; /* Type of PHY connected */ - lp->phy_address = phy_address; /* MDI address of PHY */ - - /* Register the network interface */ - res = register_netdev(dev); - if (res) { - free_irq(dev->irq, dev); - free_netdev(dev); - dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); - return res; - } - at91_dev = dev; - - /* Determine current link speed */ - spin_lock_irq(&lp->lock); - enable_mdi(); - update_linkspeed(dev); - disable_mdi(); - spin_unlock_irq(&lp->lock); - netif_carrier_off(dev); /* will be enabled in open() */ - - /* Display ethernet banner */ - printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", - dev->name, (uint) dev->base_addr, dev->irq, - at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_SPD ? "100-" : "10-", - at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_FD ? "FullDuplex" : "HalfDuplex", - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) - printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); - else if (phy_type == MII_LXT971A_ID) - printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name); - else if (phy_type == MII_RTL8201_ID) - printk(KERN_INFO "%s: Realtek RTL8201(B)L PHY\n", dev->name); - else if (phy_type == MII_BCM5221_ID) - printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name); - else if (phy_type == MII_DP83847_ID) - printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name); - else if (phy_type == MII_AC101L_ID) - printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name); - else if (phy_type == MII_KS8721_ID) - printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name); - - return 0; -} - -/* - * Detect MAC and PHY and perform initialization - */ -static int __init at91ether_probe(struct platform_device *pdev) -{ - unsigned int phyid1, phyid2; - int detected = -1; - unsigned long phy_id; - unsigned short phy_address = 0; - - ether_clk = clk_get(&pdev->dev, "ether_clk"); - if (!ether_clk) { - printk(KERN_ERR "at91_ether: no clock defined\n"); - return -ENODEV; - } - clk_enable(ether_clk); /* Enable Peripheral clock */ - - while ((detected != 0) && (phy_address < 32)) { - /* Read the PHY ID registers */ - enable_mdi(); - read_phy(phy_address, MII_PHYSID1, &phyid1); - read_phy(phy_address, MII_PHYSID2, &phyid2); - disable_mdi(); - - phy_id = (phyid1 << 16) | (phyid2 & 0xfff0); - switch (phy_id) { - case MII_DM9161_ID: /* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */ - case MII_DM9161A_ID: /* Davicom 9161A: PHY_ID1 = 0x181, PHY_ID2 = B8A0 */ - case MII_LXT971A_ID: /* Intel LXT971A: PHY_ID1 = 0x13, PHY_ID2 = 78E0 */ - case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */ - case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */ - case MII_DP83847_ID: /* National Semiconductor DP83847: */ - case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ - case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ - detected = at91ether_setup(phy_id, phy_address, pdev); - break; - } - - phy_address++; - } - - clk_disable(ether_clk); /* Disable Peripheral clock */ - - return detected; -} - -static int __devexit at91ether_remove(struct platform_device *pdev) -{ - struct at91_private *lp = (struct at91_private *) at91_dev->priv; - - unregister_netdev(at91_dev); - free_irq(at91_dev->irq, at91_dev); - dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); - clk_put(ether_clk); - - free_netdev(at91_dev); - at91_dev = NULL; - return 0; -} - -static struct platform_driver at91ether_driver = { - .probe = at91ether_probe, - .remove = __devexit_p(at91ether_remove), - /* FIXME: support suspend and resume */ - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init at91ether_init(void) -{ - return platform_driver_register(&at91ether_driver); -} - -static void __exit at91ether_exit(void) -{ - platform_driver_unregister(&at91ether_driver); -} - -module_init(at91ether_init) -module_exit(at91ether_exit) - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver"); -MODULE_AUTHOR("Andrew Victor"); diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h deleted file mode 100644 index 9885735c9..000000000 --- a/drivers/net/arm/at91_ether.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Ethernet driver for the Atmel AT91RM9200 (Thunder) - * - * Copyright (C) SAN People (Pty) Ltd - * - * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc. - * Initial version by Rick Bronson. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 AT91_ETHERNET -#define AT91_ETHERNET - - -/* Davicom 9161 PHY */ -#define MII_DM9161_ID 0x0181b880 -#define MII_DM9161A_ID 0x0181b8a0 - -/* Davicom specific registers */ -#define MII_DSCR_REG 16 -#define MII_DSCSR_REG 17 -#define MII_DSINTR_REG 21 - -/* Intel LXT971A PHY */ -#define MII_LXT971A_ID 0x001378E0 - -/* Intel specific registers */ -#define MII_ISINTE_REG 18 -#define MII_ISINTS_REG 19 -#define MII_LEDCTRL_REG 20 - -/* Realtek RTL8201 PHY */ -#define MII_RTL8201_ID 0x00008200 - -/* Broadcom BCM5221 PHY */ -#define MII_BCM5221_ID 0x004061e0 - -/* Broadcom specific registers */ -#define MII_BCMINTR_REG 26 - -/* National Semiconductor DP83847 */ -#define MII_DP83847_ID 0x20005c30 - -/* Altima AC101L PHY */ -#define MII_AC101L_ID 0x00225520 - -/* Micrel KS8721 PHY */ -#define MII_KS8721_ID 0x00221610 - -/* ........................................................................ */ - -#define MAX_RBUFF_SZ 0x600 /* 1518 rounded up */ -#define MAX_RX_DESCR 9 /* max number of receive buffers */ - -#define EMAC_DESC_DONE 0x00000001 /* bit for if DMA is done */ -#define EMAC_DESC_WRAP 0x00000002 /* bit for wrap */ - -#define EMAC_BROADCAST 0x80000000 /* broadcast address */ -#define EMAC_MULTICAST 0x40000000 /* multicast address */ -#define EMAC_UNICAST 0x20000000 /* unicast address */ - -struct rbf_t -{ - unsigned int addr; - unsigned long size; -}; - -struct recv_desc_bufs -{ - struct rbf_t descriptors[MAX_RX_DESCR]; /* must be on sizeof (rbf_t) boundary */ - char recv_buf[MAX_RX_DESCR][MAX_RBUFF_SZ]; /* must be on long boundary */ -}; - -struct at91_private -{ - struct net_device_stats stats; - struct mii_if_info mii; /* ethtool support */ - struct at91_eth_data board_data; /* board-specific configuration */ - - /* PHY */ - unsigned long phy_type; /* type of PHY (PHY_ID) */ - spinlock_t lock; /* lock for MDI interface */ - short phy_media; /* media interface type */ - unsigned short phy_address; /* 5-bit MDI address of PHY (0..31) */ - - /* Transmit */ - struct sk_buff *skb; /* holds skb until xmit interrupt completes */ - dma_addr_t skb_physaddr; /* phys addr from pci_map_single */ - int skb_length; /* saved skb length for pci_unmap_single */ - - /* Receive */ - int rxBuffIndex; /* index into receive descriptor list */ - struct recv_desc_bufs *dlist; /* descriptor list address */ - struct recv_desc_bufs *dlist_phys; /* descriptor list physical address */ -}; - -#endif diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index d52deb8d2..6a93b666e 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -356,7 +355,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf dma_start = jiffies; while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_ERR "%s: timeout waiting for TX RDC\n", dev->name); etherh_reset (dev); diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c index 5e5f80b99..0095384ff 100644 --- a/drivers/net/atari_bionet.c +++ b/drivers/net/atari_bionet.c @@ -123,7 +123,7 @@ static char version[] = * Global variable 'bionet_debug'. Can be set at load time by 'insmod' */ unsigned int bionet_debug = NET_DEBUG; -module_param(bionet_debug, int, 0); +MODULE_PARM(bionet_debug, "i"); MODULE_PARM_DESC(bionet_debug, "bionet debug level (0-2)"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c index d6039e62d..8b997809f 100644 --- a/drivers/net/atari_pamsnet.c +++ b/drivers/net/atari_pamsnet.c @@ -119,7 +119,7 @@ static char *version = * Global variable 'pamsnet_debug'. Can be set at load time by 'insmod' */ unsigned int pamsnet_debug = NET_DEBUG; -module_param(pamsnet_debug, int, 0); +MODULE_PARM(pamsnet_debug, "i"); MODULE_PARM_DESC(pamsnet_debug, "pamsnet debug enable (0-1)"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 442b2cbeb..e01b6a78e 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -78,7 +78,7 @@ static int lance_debug = LANCE_DEBUG; #else static int lance_debug = 1; #endif -module_param(lance_debug, int, 0); +MODULE_PARM(lance_debug, "i"); MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 14dbad14a..cd0b1dccf 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include @@ -91,6 +90,8 @@ static void au1000_tx_timeout(struct net_device *); static int au1000_set_config(struct net_device *dev, struct ifmap *map); static void set_rx_mode(struct net_device *); static struct net_device_stats *au1000_get_stats(struct net_device *); +static inline void update_tx_stats(struct net_device *, u32, u32); +static inline void update_rx_stats(struct net_device *, u32); static void au1000_timer(unsigned long); static int au1000_ioctl(struct net_device *, struct ifreq *, int); static int mdio_read(struct net_device *, int, int); @@ -1824,11 +1825,16 @@ static void __exit au1000_cleanup_module(void) } } -static void update_tx_stats(struct net_device *dev, u32 status) + +static inline void +update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len) { struct au1000_private *aup = (struct au1000_private *) dev->priv; struct net_device_stats *ps = &aup->stats; + ps->tx_packets++; + ps->tx_bytes += pkt_len; + if (status & TX_FRAME_ABORTED) { if (dev->if_port == IF_PORT_100BASEFX) { if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { @@ -1861,7 +1867,7 @@ static void au1000_tx_ack(struct net_device *dev) ptxd = aup->tx_dma_ring[aup->tx_tail]; while (ptxd->buff_stat & TX_T_DONE) { - update_tx_stats(dev, ptxd->status); + update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff); ptxd->buff_stat &= ~TX_T_DONE; ptxd->len = 0; au_sync(); @@ -1883,7 +1889,6 @@ static void au1000_tx_ack(struct net_device *dev) static int au1000_tx(struct sk_buff *skb, struct net_device *dev) { struct au1000_private *aup = (struct au1000_private *) dev->priv; - struct net_device_stats *ps = &aup->stats; volatile tx_dma_t *ptxd; u32 buff_stat; db_dest_t *pDB; @@ -1903,7 +1908,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev) return 1; } else if (buff_stat & TX_T_DONE) { - update_tx_stats(dev, ptxd->status); + update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff); ptxd->len = 0; } @@ -1923,9 +1928,6 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev) else ptxd->len = skb->len; - ps->tx_packets++; - ps->tx_bytes += ptxd->len; - ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; au_sync(); dev_kfree_skb(skb); @@ -1934,6 +1936,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev) return 0; } + static inline void update_rx_stats(struct net_device *dev, u32 status) { struct au1000_private *aup = (struct au1000_private *) dev->priv; @@ -2071,6 +2074,23 @@ static void au1000_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } + +static unsigned const ethernet_polynomial = 0x04c11db7U; +static inline u32 ether_crc(int length, unsigned char *data) +{ + int crc = -1; + + while(--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 0; bit < 8; bit++, current_octet >>= 1) + crc = (crc << 1) ^ + ((crc < 0) ^ (current_octet & 1) ? + ethernet_polynomial : 0); + } + return crc; +} + static void set_rx_mode(struct net_device *dev) { struct au1000_private *aup = (struct au1000_private *) dev->priv; diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 6e3e5a297..c3267e4e1 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2,7 +2,6 @@ * * Copyright (C) 2002 David S. Miller (davem@redhat.com) * Fixed by Pekka Pietikainen (pp@ee.oulu.fi) - * Copyright (C) 2006 Broadcom Corporation. * * Distribute under GPL. */ @@ -29,8 +28,8 @@ #define DRV_MODULE_NAME "b44" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.00" -#define DRV_MODULE_RELDATE "Apr 7, 2006" +#define DRV_MODULE_VERSION "0.97" +#define DRV_MODULE_RELDATE "Nov 30, 2005" #define B44_DEF_MSG_ENABLE \ (NETIF_MSG_DRV | \ @@ -86,7 +85,6 @@ MODULE_VERSION(DRV_MODULE_VERSION); static int b44_debug = -1; /* -1 == use B44_DEF_MSG_ENABLE as value */ module_param(b44_debug, int, 0); MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value"); -MODULE_VERSION(DRV_MODULE_VERSION); static struct pci_device_id b44_pci_tbl[] = { { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401, @@ -138,7 +136,7 @@ static inline unsigned long br32(const struct b44 *bp, unsigned long reg) return readl(bp->regs + reg); } -static inline void bw32(const struct b44 *bp, +static inline void bw32(const struct b44 *bp, unsigned long reg, unsigned long val) { writel(val, bp->regs + reg); @@ -288,13 +286,13 @@ static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index) val |= ((u32) data[4]) << 8; val |= ((u32) data[5]) << 0; bw32(bp, B44_CAM_DATA_LO, val); - val = (CAM_DATA_HI_VALID | + val = (CAM_DATA_HI_VALID | (((u32) data[0]) << 8) | (((u32) data[1]) << 0)); bw32(bp, B44_CAM_DATA_HI, val); bw32(bp, B44_CAM_CTRL, (CAM_CTRL_WRITE | (index << CAM_CTRL_INDEX_SHIFT))); - b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1); + b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1); } static inline void __b44_disable_ints(struct b44 *bp) @@ -412,18 +410,25 @@ static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags) static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) { - u32 pause_enab = 0; + u32 pause_enab = bp->flags & (B44_FLAG_TX_PAUSE | + B44_FLAG_RX_PAUSE); - /* The driver supports only rx pause by default because - the b44 mac tx pause mechanism generates excessive - pause frames. - Use ethtool to turn on b44 tx pause if necessary. - */ - if ((local & ADVERTISE_PAUSE_CAP) && - (local & ADVERTISE_PAUSE_ASYM)){ - if ((remote & LPA_PAUSE_ASYM) && - !(remote & LPA_PAUSE_CAP)) - pause_enab |= B44_FLAG_RX_PAUSE; + if (local & ADVERTISE_PAUSE_CAP) { + if (local & ADVERTISE_PAUSE_ASYM) { + if (remote & LPA_PAUSE_CAP) + pause_enab |= (B44_FLAG_TX_PAUSE | + B44_FLAG_RX_PAUSE); + else if (remote & LPA_PAUSE_ASYM) + pause_enab |= B44_FLAG_RX_PAUSE; + } else { + if (remote & LPA_PAUSE_CAP) + pause_enab |= (B44_FLAG_TX_PAUSE | + B44_FLAG_RX_PAUSE); + } + } else if (local & ADVERTISE_PAUSE_ASYM) { + if ((remote & LPA_PAUSE_CAP) && + (remote & LPA_PAUSE_ASYM)) + pause_enab |= B44_FLAG_TX_PAUSE; } __b44_set_flow_ctrl(bp, pause_enab); @@ -603,7 +608,8 @@ static void b44_tx(struct b44 *bp) struct ring_info *rp = &bp->tx_buffers[cons]; struct sk_buff *skb = rp->skb; - BUG_ON(skb == NULL); + if (unlikely(skb == NULL)) + BUG(); pci_unmap_single(bp->pdev, pci_unmap_addr(rp, mapping), @@ -651,11 +657,9 @@ 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 (dma_mapping_error(mapping) || - mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { + if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { /* Sigh... */ - if (!dma_mapping_error(mapping)) - pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); + pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA); if (skb == NULL) @@ -663,10 +667,8 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) mapping = pci_map_single(bp->pdev, skb->data, RX_PKT_BUF_SZ, PCI_DMA_FROMDEVICE); - if (dma_mapping_error(mapping) || - mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { - if (!dma_mapping_error(mapping)) - pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); + if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { + pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); return -ENOMEM; } @@ -972,10 +974,9 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) } mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); - if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) { + if (mapping + len > B44_DMA_MASK) { /* Chip can't handle DMA to/from >1GB, use bounce buffer */ - if (!dma_mapping_error(mapping)) - pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); + pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); @@ -984,9 +985,8 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) mapping = pci_map_single(bp->pdev, bounce_skb->data, len, PCI_DMA_TODEVICE); - if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) { - if (!dma_mapping_error(mapping)) - pci_unmap_single(bp->pdev, mapping, + if (mapping + len > B44_DMA_MASK) { + pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); dev_kfree_skb_any(bounce_skb); goto err_out; @@ -1064,7 +1064,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu) spin_unlock_irq(&bp->lock); b44_enable_ints(bp); - + return 0; } @@ -1210,8 +1210,7 @@ static int b44_alloc_consistent(struct b44 *bp) DMA_TABLE_BYTES, DMA_BIDIRECTIONAL); - if (dma_mapping_error(rx_ring_dma) || - rx_ring_dma + size > B44_DMA_MASK) { + if (rx_ring_dma + size > B44_DMA_MASK) { kfree(rx_ring); goto out_err; } @@ -1237,8 +1236,7 @@ static int b44_alloc_consistent(struct b44 *bp) DMA_TABLE_BYTES, DMA_TO_DEVICE); - if (dma_mapping_error(tx_ring_dma) || - tx_ring_dma + size > B44_DMA_MASK) { + if (tx_ring_dma + size > B44_DMA_MASK) { kfree(tx_ring); goto out_err; } @@ -1341,9 +1339,6 @@ static int b44_set_mac_addr(struct net_device *dev, void *p) if (netif_running(dev)) return -EBUSY; - if (!is_valid_ether_addr(addr->sa_data)) - return -EINVAL; - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); spin_lock_irq(&bp->lock); @@ -1384,7 +1379,7 @@ static void b44_init_hw(struct b44 *bp) bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); bw32(bp, B44_DMARX_PTR, bp->rx_pending); - bp->rx_prod = bp->rx_pending; + bp->rx_prod = bp->rx_pending; bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); @@ -1556,9 +1551,9 @@ static void __b44_set_rx_mode(struct net_device *dev) val |= RXCONFIG_ALLMULTI; else i = __b44_load_mcast(bp, dev); - + for (; i < 64; i++) { - __b44_cam_write(bp, zero, i); + __b44_cam_write(bp, zero, i); } bw32(bp, B44_RXCONFIG, val); val = br32(bp, B44_CAM_CTRL); @@ -1740,7 +1735,7 @@ static int b44_set_ringparam(struct net_device *dev, spin_unlock_irq(&bp->lock); b44_enable_ints(bp); - + return 0; } @@ -1785,7 +1780,7 @@ static int b44_set_pauseparam(struct net_device *dev, spin_unlock_irq(&bp->lock); b44_enable_ints(bp); - + return 0; } @@ -1881,12 +1876,6 @@ static int __devinit b44_get_invariants(struct b44 *bp) bp->dev->dev_addr[3] = eeprom[80]; bp->dev->dev_addr[4] = eeprom[83]; bp->dev->dev_addr[5] = eeprom[82]; - - if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){ - printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n"); - return -EINVAL; - } - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len); bp->phy_addr = eeprom[90] & 0x1f; @@ -1901,7 +1890,7 @@ static int __devinit b44_get_invariants(struct b44 *bp) bp->core_unit = ssb_core_unit(bp); bp->dma_offset = SB_PCI_DMA; - /* XXX - really required? + /* XXX - really required? bp->flags |= B44_FLAG_BUGGY_TXPTR; */ out: @@ -1949,7 +1938,7 @@ static int __devinit b44_init_one(struct pci_dev *pdev, "aborting.\n"); goto err_out_free_res; } - + err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); if (err) { printk(KERN_ERR PFX "No usable DMA configuration, " @@ -2044,11 +2033,6 @@ static int __devinit b44_init_one(struct pci_dev *pdev, pci_save_state(bp->pdev); - /* Chip reset provides power to the b44 MAC & PCI cores, which - * is necessary for MAC register access. - */ - b44_chip_reset(bp); - printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], @@ -2094,10 +2078,10 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state) del_timer_sync(&bp->timer); - spin_lock_irq(&bp->lock); + spin_lock_irq(&bp->lock); b44_halt(bp); - netif_carrier_off(bp->dev); + netif_carrier_off(bp->dev); netif_device_detach(bp->dev); b44_free_rings(bp); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index a8f95e511..a24200d0a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -9,61 +9,20 @@ * Written by: Michael Chan (mchan@broadcom.com) */ -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef NETIF_F_HW_VLAN_TX -#include -#define BCM_VLAN 1 -#endif -#ifdef NETIF_F_TSO -#include -#include -#include -#define BCM_TSO 1 -#endif -#include -#include -#include -#include - #include "bnx2.h" #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.4.40" -#define DRV_MODULE_RELDATE "May 22, 2006" +#define DRV_MODULE_VERSION "1.4.31" +#define DRV_MODULE_RELDATE "January 19, 2006" #define RUN_AT(x) (jiffies + (x)) /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (5*HZ) -static const char version[] __devinitdata = +static char version[] __devinitdata = "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Michael Chan "); @@ -87,7 +46,7 @@ typedef enum { } board_t; /* indexed by board_t, above */ -static const struct { +static struct { char *name; } board_info[] __devinitdata = { { "Broadcom NetXtreme II BCM5706 1000Base-T" }, @@ -354,6 +313,8 @@ bnx2_disable_int(struct bnx2 *bp) static void bnx2_enable_int(struct bnx2 *bp) { + u32 val; + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx); @@ -361,7 +322,8 @@ bnx2_enable_int(struct bnx2 *bp) REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx); - REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW); + val = REG_RD(bp, BNX2_HC_COMMAND); + REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW); } static void @@ -398,13 +360,15 @@ bnx2_netif_start(struct bnx2 *bp) static void bnx2_free_mem(struct bnx2 *bp) { - int i; - + if (bp->stats_blk) { + pci_free_consistent(bp->pdev, sizeof(struct statistics_block), + bp->stats_blk, bp->stats_blk_mapping); + bp->stats_blk = NULL; + } if (bp->status_blk) { - pci_free_consistent(bp->pdev, bp->status_stats_size, + pci_free_consistent(bp->pdev, sizeof(struct status_block), bp->status_blk, bp->status_blk_mapping); bp->status_blk = NULL; - bp->stats_blk = NULL; } if (bp->tx_desc_ring) { pci_free_consistent(bp->pdev, @@ -414,28 +378,25 @@ bnx2_free_mem(struct bnx2 *bp) } kfree(bp->tx_buf_ring); bp->tx_buf_ring = NULL; - for (i = 0; i < bp->rx_max_ring; i++) { - if (bp->rx_desc_ring[i]) - pci_free_consistent(bp->pdev, - sizeof(struct rx_bd) * RX_DESC_CNT, - bp->rx_desc_ring[i], - bp->rx_desc_mapping[i]); - bp->rx_desc_ring[i] = NULL; - } - vfree(bp->rx_buf_ring); + if (bp->rx_desc_ring) { + pci_free_consistent(bp->pdev, + sizeof(struct rx_bd) * RX_DESC_CNT, + bp->rx_desc_ring, bp->rx_desc_mapping); + bp->rx_desc_ring = NULL; + } + kfree(bp->rx_buf_ring); bp->rx_buf_ring = NULL; } static int bnx2_alloc_mem(struct bnx2 *bp) { - int i, status_blk_size; - - bp->tx_buf_ring = kzalloc(sizeof(struct sw_bd) * TX_DESC_CNT, - GFP_KERNEL); + bp->tx_buf_ring = kmalloc(sizeof(struct sw_bd) * TX_DESC_CNT, + GFP_KERNEL); if (bp->tx_buf_ring == NULL) return -ENOMEM; + memset(bp->tx_buf_ring, 0, sizeof(struct sw_bd) * TX_DESC_CNT); bp->tx_desc_ring = pci_alloc_consistent(bp->pdev, sizeof(struct tx_bd) * TX_DESC_CNT, @@ -443,40 +404,34 @@ bnx2_alloc_mem(struct bnx2 *bp) if (bp->tx_desc_ring == NULL) goto alloc_mem_err; - bp->rx_buf_ring = vmalloc(sizeof(struct sw_bd) * RX_DESC_CNT * - bp->rx_max_ring); + bp->rx_buf_ring = kmalloc(sizeof(struct sw_bd) * RX_DESC_CNT, + GFP_KERNEL); if (bp->rx_buf_ring == NULL) goto alloc_mem_err; - memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT * - bp->rx_max_ring); - - for (i = 0; i < bp->rx_max_ring; i++) { - bp->rx_desc_ring[i] = - pci_alloc_consistent(bp->pdev, - sizeof(struct rx_bd) * RX_DESC_CNT, - &bp->rx_desc_mapping[i]); - if (bp->rx_desc_ring[i] == NULL) - goto alloc_mem_err; - - } - - /* Combine status and statistics blocks into one allocation. */ - status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block)); - bp->status_stats_size = status_blk_size + - sizeof(struct statistics_block); + memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT); + bp->rx_desc_ring = pci_alloc_consistent(bp->pdev, + sizeof(struct rx_bd) * + RX_DESC_CNT, + &bp->rx_desc_mapping); + if (bp->rx_desc_ring == NULL) + goto alloc_mem_err; - bp->status_blk = pci_alloc_consistent(bp->pdev, bp->status_stats_size, + bp->status_blk = pci_alloc_consistent(bp->pdev, + sizeof(struct status_block), &bp->status_blk_mapping); if (bp->status_blk == NULL) goto alloc_mem_err; - memset(bp->status_blk, 0, bp->status_stats_size); + memset(bp->status_blk, 0, sizeof(struct status_block)); - bp->stats_blk = (void *) ((unsigned long) bp->status_blk + - status_blk_size); + bp->stats_blk = pci_alloc_consistent(bp->pdev, + sizeof(struct statistics_block), + &bp->stats_blk_mapping); + if (bp->stats_blk == NULL) + goto alloc_mem_err; - bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size; + memset(bp->stats_blk, 0, sizeof(struct statistics_block)); return 0; @@ -1565,7 +1520,7 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index) struct sk_buff *skb; struct sw_bd *rx_buf = &bp->rx_buf_ring[index]; dma_addr_t mapping; - struct rx_bd *rxbd = &bp->rx_desc_ring[RX_RING(index)][RX_IDX(index)]; + struct rx_bd *rxbd = &bp->rx_desc_ring[index]; unsigned long align; skb = dev_alloc_skb(bp->rx_buf_size); @@ -1638,7 +1593,7 @@ bnx2_tx_int(struct bnx2 *bp) skb = tx_buf->skb; #ifdef BCM_TSO /* partial BD completions possible with TSO packets */ - if (skb_is_gso(skb)) { + if (skb_shinfo(skb)->tso_size) { u16 last_idx, last_ring_idx; last_idx = sw_cons + @@ -1701,30 +1656,23 @@ static inline void bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb, u16 cons, u16 prod) { - struct sw_bd *cons_rx_buf, *prod_rx_buf; - struct rx_bd *cons_bd, *prod_bd; - - cons_rx_buf = &bp->rx_buf_ring[cons]; - prod_rx_buf = &bp->rx_buf_ring[prod]; + struct sw_bd *cons_rx_buf = &bp->rx_buf_ring[cons]; + struct sw_bd *prod_rx_buf = &bp->rx_buf_ring[prod]; + struct rx_bd *cons_bd = &bp->rx_desc_ring[cons]; + struct rx_bd *prod_bd = &bp->rx_desc_ring[prod]; pci_dma_sync_single_for_device(bp->pdev, pci_unmap_addr(cons_rx_buf, mapping), bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE); - bp->rx_prod_bseq += bp->rx_buf_use_size; - - prod_rx_buf->skb = skb; - - if (cons == prod) - return; - + prod_rx_buf->skb = cons_rx_buf->skb; pci_unmap_addr_set(prod_rx_buf, mapping, pci_unmap_addr(cons_rx_buf, mapping)); - cons_bd = &bp->rx_desc_ring[RX_RING(cons)][RX_IDX(cons)]; - prod_bd = &bp->rx_desc_ring[RX_RING(prod)][RX_IDX(prod)]; - prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi; - prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo; + memcpy(prod_bd, cons_bd, 8); + + bp->rx_prod_bseq += bp->rx_buf_use_size; + } static int @@ -1751,19 +1699,14 @@ bnx2_rx_int(struct bnx2 *bp, int budget) u32 status; struct sw_bd *rx_buf; struct sk_buff *skb; - dma_addr_t dma_addr; sw_ring_cons = RX_RING_IDX(sw_cons); sw_ring_prod = RX_RING_IDX(sw_prod); rx_buf = &bp->rx_buf_ring[sw_ring_cons]; skb = rx_buf->skb; - - rx_buf->skb = NULL; - - dma_addr = pci_unmap_addr(rx_buf, mapping); - - pci_dma_sync_single_for_cpu(bp->pdev, dma_addr, + pci_dma_sync_single_for_cpu(bp->pdev, + pci_unmap_addr(rx_buf, mapping), bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE); rx_hdr = (struct l2_fhdr *) skb->data; @@ -1804,7 +1747,8 @@ bnx2_rx_int(struct bnx2 *bp, int budget) skb = new_skb; } else if (bnx2_alloc_rx_skb(bp, sw_ring_prod) == 0) { - pci_unmap_single(bp->pdev, dma_addr, + pci_unmap_single(bp->pdev, + pci_unmap_addr(rx_buf, mapping), bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); skb_reserve(skb, bp->rx_offset); @@ -1850,6 +1794,8 @@ reuse_rx: rx_pkt++; next_rx: + rx_buf->skb = NULL; + sw_cons = NEXT_RX_BD(sw_cons); sw_prod = NEXT_RX_BD(sw_prod); @@ -1960,13 +1906,6 @@ bnx2_poll(struct net_device *dev, int *budget) spin_lock(&bp->phy_lock); bnx2_phy_int(bp); spin_unlock(&bp->phy_lock); - - /* This is needed to take care of transient status - * during link changes. - */ - REG_WR(bp, BNX2_HC_COMMAND, - bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); - REG_RD(bp, BNX2_HC_COMMAND); } if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) @@ -2009,7 +1948,7 @@ bnx2_poll(struct net_device *dev, int *budget) return 1; } -/* Called with rtnl_lock from vlan functions and also netif_tx_lock +/* Called with rtnl_lock from vlan functions and also dev->xmit_lock * from set_multicast. */ static void @@ -2945,7 +2884,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, int buf_size) { u32 written, offset32, len32; - u8 *buf, start[4], end[4], *flash_buffer = NULL; + u8 *buf, start[4], end[4]; int rc = 0; int align_start, align_end; @@ -2985,19 +2924,12 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, memcpy(buf + align_start, data_buf, buf_size); } - if (bp->flash_info->buffered == 0) { - flash_buffer = kmalloc(264, GFP_KERNEL); - if (flash_buffer == NULL) { - rc = -ENOMEM; - goto nvram_write_end; - } - } - written = 0; while ((written < len32) && (rc == 0)) { u32 page_start, page_end, data_start, data_end; u32 addr, cmd_flags; int i; + u8 flash_buffer[264]; /* Find the page_start addr */ page_start = offset32 + written; @@ -3068,7 +3000,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, } /* Loop to write the new data from data_start to data_end */ - for (addr = data_start; addr < data_end; addr += 4, i += 4) { + for (addr = data_start; addr < data_end; addr += 4, i++) { if ((addr == page_end - 4) || ((bp->flash_info->buffered) && (addr == data_end - 4))) { @@ -3116,9 +3048,6 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, } nvram_write_end: - if (bp->flash_info->buffered == 0) - kfree(flash_buffer); - if (align_start || align_end) kfree(buf); return rc; @@ -3358,8 +3287,6 @@ bnx2_init_chip(struct bnx2 *bp) udelay(20); - bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND); - return rc; } @@ -3413,35 +3340,27 @@ bnx2_init_rx_ring(struct bnx2 *bp) bp->hw_rx_cons = 0; bp->rx_prod_bseq = 0; - for (i = 0; i < bp->rx_max_ring; i++) { - int j; - - rxbd = &bp->rx_desc_ring[i][0]; - for (j = 0; j < MAX_RX_DESC_CNT; j++, rxbd++) { - rxbd->rx_bd_len = bp->rx_buf_use_size; - rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; - } - if (i == (bp->rx_max_ring - 1)) - j = 0; - else - j = i + 1; - rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping[j] >> 32; - rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping[j] & - 0xffffffff; + rxbd = &bp->rx_desc_ring[0]; + for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { + rxbd->rx_bd_len = bp->rx_buf_use_size; + rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; } + rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping >> 32; + rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff; + val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE; val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; val |= 0x02 << 8; CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val); - val = (u64) bp->rx_desc_mapping[0] >> 32; + val = (u64) bp->rx_desc_mapping >> 32; CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val); - val = (u64) bp->rx_desc_mapping[0] & 0xffffffff; + val = (u64) bp->rx_desc_mapping & 0xffffffff; CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val); - for (i = 0; i < bp->rx_ring_size; i++) { + for ( ;ring_prod < bp->rx_ring_size; ) { if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) { break; } @@ -3455,29 +3374,6 @@ bnx2_init_rx_ring(struct bnx2 *bp) REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq); } -static void -bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size) -{ - u32 num_rings, max; - - bp->rx_ring_size = size; - num_rings = 1; - while (size > MAX_RX_DESC_CNT) { - size -= MAX_RX_DESC_CNT; - num_rings++; - } - /* round to next power of 2 */ - max = MAX_RX_RINGS; - while ((max & num_rings) == 0) - max >>= 1; - - if (num_rings != max) - max <<= 1; - - bp->rx_max_ring = max; - bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1; -} - static void bnx2_free_tx_skbs(struct bnx2 *bp) { @@ -3523,7 +3419,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp) if (bp->rx_buf_ring == NULL) return; - for (i = 0; i < bp->rx_max_ring_idx; i++) { + for (i = 0; i < RX_DESC_CNT; i++) { struct sw_bd *rx_buf = &bp->rx_buf_ring[i]; struct sk_buff *skb = rx_buf->skb; @@ -3580,7 +3476,7 @@ bnx2_test_registers(struct bnx2 *bp) { int ret; int i; - static const struct { + static struct { u16 offset; u16 flags; u32 rw_mask; @@ -3610,9 +3506,74 @@ bnx2_test_registers(struct bnx2 *bp) { 0x0c00, 0, 0x00000000, 0x00000001 }, { 0x0c04, 0, 0x00000000, 0x03ff0001 }, { 0x0c08, 0, 0x0f0ff073, 0x00000000 }, + { 0x0c0c, 0, 0x00ffffff, 0x00000000 }, + { 0x0c30, 0, 0x00000000, 0xffffffff }, + { 0x0c34, 0, 0x00000000, 0xffffffff }, + { 0x0c38, 0, 0x00000000, 0xffffffff }, + { 0x0c3c, 0, 0x00000000, 0xffffffff }, + { 0x0c40, 0, 0x00000000, 0xffffffff }, + { 0x0c44, 0, 0x00000000, 0xffffffff }, + { 0x0c48, 0, 0x00000000, 0x0007ffff }, + { 0x0c4c, 0, 0x00000000, 0xffffffff }, + { 0x0c50, 0, 0x00000000, 0xffffffff }, + { 0x0c54, 0, 0x00000000, 0xffffffff }, + { 0x0c58, 0, 0x00000000, 0xffffffff }, + { 0x0c5c, 0, 0x00000000, 0xffffffff }, + { 0x0c60, 0, 0x00000000, 0xffffffff }, + { 0x0c64, 0, 0x00000000, 0xffffffff }, + { 0x0c68, 0, 0x00000000, 0xffffffff }, + { 0x0c6c, 0, 0x00000000, 0xffffffff }, + { 0x0c70, 0, 0x00000000, 0xffffffff }, + { 0x0c74, 0, 0x00000000, 0xffffffff }, + { 0x0c78, 0, 0x00000000, 0xffffffff }, + { 0x0c7c, 0, 0x00000000, 0xffffffff }, + { 0x0c80, 0, 0x00000000, 0xffffffff }, + { 0x0c84, 0, 0x00000000, 0xffffffff }, + { 0x0c88, 0, 0x00000000, 0xffffffff }, + { 0x0c8c, 0, 0x00000000, 0xffffffff }, + { 0x0c90, 0, 0x00000000, 0xffffffff }, + { 0x0c94, 0, 0x00000000, 0xffffffff }, + { 0x0c98, 0, 0x00000000, 0xffffffff }, + { 0x0c9c, 0, 0x00000000, 0xffffffff }, + { 0x0ca0, 0, 0x00000000, 0xffffffff }, + { 0x0ca4, 0, 0x00000000, 0xffffffff }, + { 0x0ca8, 0, 0x00000000, 0x0007ffff }, + { 0x0cac, 0, 0x00000000, 0xffffffff }, + { 0x0cb0, 0, 0x00000000, 0xffffffff }, + { 0x0cb4, 0, 0x00000000, 0xffffffff }, + { 0x0cb8, 0, 0x00000000, 0xffffffff }, + { 0x0cbc, 0, 0x00000000, 0xffffffff }, + { 0x0cc0, 0, 0x00000000, 0xffffffff }, + { 0x0cc4, 0, 0x00000000, 0xffffffff }, + { 0x0cc8, 0, 0x00000000, 0xffffffff }, + { 0x0ccc, 0, 0x00000000, 0xffffffff }, + { 0x0cd0, 0, 0x00000000, 0xffffffff }, + { 0x0cd4, 0, 0x00000000, 0xffffffff }, + { 0x0cd8, 0, 0x00000000, 0xffffffff }, + { 0x0cdc, 0, 0x00000000, 0xffffffff }, + { 0x0ce0, 0, 0x00000000, 0xffffffff }, + { 0x0ce4, 0, 0x00000000, 0xffffffff }, + { 0x0ce8, 0, 0x00000000, 0xffffffff }, + { 0x0cec, 0, 0x00000000, 0xffffffff }, + { 0x0cf0, 0, 0x00000000, 0xffffffff }, + { 0x0cf4, 0, 0x00000000, 0xffffffff }, + { 0x0cf8, 0, 0x00000000, 0xffffffff }, + { 0x0cfc, 0, 0x00000000, 0xffffffff }, + { 0x0d00, 0, 0x00000000, 0xffffffff }, + { 0x0d04, 0, 0x00000000, 0xffffffff }, { 0x1000, 0, 0x00000000, 0x00000001 }, { 0x1004, 0, 0x00000000, 0x000f0001 }, + { 0x1044, 0, 0x00000000, 0xffc003ff }, + { 0x1080, 0, 0x00000000, 0x0001ffff }, + { 0x1084, 0, 0x00000000, 0xffffffff }, + { 0x1088, 0, 0x00000000, 0xffffffff }, + { 0x108c, 0, 0x00000000, 0xffffffff }, + { 0x1090, 0, 0x00000000, 0xffffffff }, + { 0x1094, 0, 0x00000000, 0xffffffff }, + { 0x1098, 0, 0x00000000, 0xffffffff }, + { 0x109c, 0, 0x00000000, 0xffffffff }, + { 0x10a0, 0, 0x00000000, 0xffffffff }, { 0x1408, 0, 0x01c00800, 0x00000000 }, { 0x149c, 0, 0x8000ffff, 0x00000000 }, @@ -3624,9 +3585,111 @@ bnx2_test_registers(struct bnx2 *bp) { 0x14c4, 0, 0x00003fff, 0x00000000 }, { 0x14cc, 0, 0x00000000, 0x00000001 }, { 0x14d0, 0, 0xffffffff, 0x00000000 }, + { 0x1500, 0, 0x00000000, 0xffffffff }, + { 0x1504, 0, 0x00000000, 0xffffffff }, + { 0x1508, 0, 0x00000000, 0xffffffff }, + { 0x150c, 0, 0x00000000, 0xffffffff }, + { 0x1510, 0, 0x00000000, 0xffffffff }, + { 0x1514, 0, 0x00000000, 0xffffffff }, + { 0x1518, 0, 0x00000000, 0xffffffff }, + { 0x151c, 0, 0x00000000, 0xffffffff }, + { 0x1520, 0, 0x00000000, 0xffffffff }, + { 0x1524, 0, 0x00000000, 0xffffffff }, + { 0x1528, 0, 0x00000000, 0xffffffff }, + { 0x152c, 0, 0x00000000, 0xffffffff }, + { 0x1530, 0, 0x00000000, 0xffffffff }, + { 0x1534, 0, 0x00000000, 0xffffffff }, + { 0x1538, 0, 0x00000000, 0xffffffff }, + { 0x153c, 0, 0x00000000, 0xffffffff }, + { 0x1540, 0, 0x00000000, 0xffffffff }, + { 0x1544, 0, 0x00000000, 0xffffffff }, + { 0x1548, 0, 0x00000000, 0xffffffff }, + { 0x154c, 0, 0x00000000, 0xffffffff }, + { 0x1550, 0, 0x00000000, 0xffffffff }, + { 0x1554, 0, 0x00000000, 0xffffffff }, + { 0x1558, 0, 0x00000000, 0xffffffff }, + { 0x1600, 0, 0x00000000, 0xffffffff }, + { 0x1604, 0, 0x00000000, 0xffffffff }, + { 0x1608, 0, 0x00000000, 0xffffffff }, + { 0x160c, 0, 0x00000000, 0xffffffff }, + { 0x1610, 0, 0x00000000, 0xffffffff }, + { 0x1614, 0, 0x00000000, 0xffffffff }, + { 0x1618, 0, 0x00000000, 0xffffffff }, + { 0x161c, 0, 0x00000000, 0xffffffff }, + { 0x1620, 0, 0x00000000, 0xffffffff }, + { 0x1624, 0, 0x00000000, 0xffffffff }, + { 0x1628, 0, 0x00000000, 0xffffffff }, + { 0x162c, 0, 0x00000000, 0xffffffff }, + { 0x1630, 0, 0x00000000, 0xffffffff }, + { 0x1634, 0, 0x00000000, 0xffffffff }, + { 0x1638, 0, 0x00000000, 0xffffffff }, + { 0x163c, 0, 0x00000000, 0xffffffff }, + { 0x1640, 0, 0x00000000, 0xffffffff }, + { 0x1644, 0, 0x00000000, 0xffffffff }, + { 0x1648, 0, 0x00000000, 0xffffffff }, + { 0x164c, 0, 0x00000000, 0xffffffff }, + { 0x1650, 0, 0x00000000, 0xffffffff }, + { 0x1654, 0, 0x00000000, 0xffffffff }, { 0x1800, 0, 0x00000000, 0x00000001 }, { 0x1804, 0, 0x00000000, 0x00000003 }, + { 0x1840, 0, 0x00000000, 0xffffffff }, + { 0x1844, 0, 0x00000000, 0xffffffff }, + { 0x1848, 0, 0x00000000, 0xffffffff }, + { 0x184c, 0, 0x00000000, 0xffffffff }, + { 0x1850, 0, 0x00000000, 0xffffffff }, + { 0x1900, 0, 0x7ffbffff, 0x00000000 }, + { 0x1904, 0, 0xffffffff, 0x00000000 }, + { 0x190c, 0, 0xffffffff, 0x00000000 }, + { 0x1914, 0, 0xffffffff, 0x00000000 }, + { 0x191c, 0, 0xffffffff, 0x00000000 }, + { 0x1924, 0, 0xffffffff, 0x00000000 }, + { 0x192c, 0, 0xffffffff, 0x00000000 }, + { 0x1934, 0, 0xffffffff, 0x00000000 }, + { 0x193c, 0, 0xffffffff, 0x00000000 }, + { 0x1944, 0, 0xffffffff, 0x00000000 }, + { 0x194c, 0, 0xffffffff, 0x00000000 }, + { 0x1954, 0, 0xffffffff, 0x00000000 }, + { 0x195c, 0, 0xffffffff, 0x00000000 }, + { 0x1964, 0, 0xffffffff, 0x00000000 }, + { 0x196c, 0, 0xffffffff, 0x00000000 }, + { 0x1974, 0, 0xffffffff, 0x00000000 }, + { 0x197c, 0, 0xffffffff, 0x00000000 }, + { 0x1980, 0, 0x0700ffff, 0x00000000 }, + + { 0x1c00, 0, 0x00000000, 0x00000001 }, + { 0x1c04, 0, 0x00000000, 0x00000003 }, + { 0x1c08, 0, 0x0000000f, 0x00000000 }, + { 0x1c40, 0, 0x00000000, 0xffffffff }, + { 0x1c44, 0, 0x00000000, 0xffffffff }, + { 0x1c48, 0, 0x00000000, 0xffffffff }, + { 0x1c4c, 0, 0x00000000, 0xffffffff }, + { 0x1c50, 0, 0x00000000, 0xffffffff }, + { 0x1d00, 0, 0x7ffbffff, 0x00000000 }, + { 0x1d04, 0, 0xffffffff, 0x00000000 }, + { 0x1d0c, 0, 0xffffffff, 0x00000000 }, + { 0x1d14, 0, 0xffffffff, 0x00000000 }, + { 0x1d1c, 0, 0xffffffff, 0x00000000 }, + { 0x1d24, 0, 0xffffffff, 0x00000000 }, + { 0x1d2c, 0, 0xffffffff, 0x00000000 }, + { 0x1d34, 0, 0xffffffff, 0x00000000 }, + { 0x1d3c, 0, 0xffffffff, 0x00000000 }, + { 0x1d44, 0, 0xffffffff, 0x00000000 }, + { 0x1d4c, 0, 0xffffffff, 0x00000000 }, + { 0x1d54, 0, 0xffffffff, 0x00000000 }, + { 0x1d5c, 0, 0xffffffff, 0x00000000 }, + { 0x1d64, 0, 0xffffffff, 0x00000000 }, + { 0x1d6c, 0, 0xffffffff, 0x00000000 }, + { 0x1d74, 0, 0xffffffff, 0x00000000 }, + { 0x1d7c, 0, 0xffffffff, 0x00000000 }, + { 0x1d80, 0, 0x0700ffff, 0x00000000 }, + + { 0x2004, 0, 0x00000000, 0x0337000f }, + { 0x2008, 0, 0xffffffff, 0x00000000 }, + { 0x200c, 0, 0xffffffff, 0x00000000 }, + { 0x2010, 0, 0xffffffff, 0x00000000 }, + { 0x2014, 0, 0x801fff80, 0x00000000 }, + { 0x2018, 0, 0x000003ff, 0x00000000 }, { 0x2800, 0, 0x00000000, 0x00000001 }, { 0x2804, 0, 0x00000000, 0x00003f01 }, @@ -3644,6 +3707,16 @@ bnx2_test_registers(struct bnx2 *bp) { 0x2c00, 0, 0x00000000, 0x00000011 }, { 0x2c04, 0, 0x00000000, 0x00030007 }, + { 0x3000, 0, 0x00000000, 0x00000001 }, + { 0x3004, 0, 0x00000000, 0x007007ff }, + { 0x3008, 0, 0x00000003, 0x00000000 }, + { 0x300c, 0, 0xffffffff, 0x00000000 }, + { 0x3010, 0, 0xffffffff, 0x00000000 }, + { 0x3014, 0, 0xffffffff, 0x00000000 }, + { 0x3034, 0, 0xffffffff, 0x00000000 }, + { 0x3038, 0, 0xffffffff, 0x00000000 }, + { 0x3050, 0, 0x00000001, 0x00000000 }, + { 0x3c00, 0, 0x00000000, 0x00000001 }, { 0x3c04, 0, 0x00000000, 0x00070000 }, { 0x3c08, 0, 0x00007f71, 0x07f00000 }, @@ -3653,11 +3726,88 @@ bnx2_test_registers(struct bnx2 *bp) { 0x3c18, 0, 0x00000000, 0xffffffff }, { 0x3c1c, 0, 0xfffff000, 0x00000000 }, { 0x3c20, 0, 0xffffff00, 0x00000000 }, + { 0x3c24, 0, 0xffffffff, 0x00000000 }, + { 0x3c28, 0, 0xffffffff, 0x00000000 }, + { 0x3c2c, 0, 0xffffffff, 0x00000000 }, + { 0x3c30, 0, 0xffffffff, 0x00000000 }, + { 0x3c34, 0, 0xffffffff, 0x00000000 }, + { 0x3c38, 0, 0xffffffff, 0x00000000 }, + { 0x3c3c, 0, 0xffffffff, 0x00000000 }, + { 0x3c40, 0, 0xffffffff, 0x00000000 }, + { 0x3c44, 0, 0xffffffff, 0x00000000 }, + { 0x3c48, 0, 0xffffffff, 0x00000000 }, + { 0x3c4c, 0, 0xffffffff, 0x00000000 }, + { 0x3c50, 0, 0xffffffff, 0x00000000 }, + { 0x3c54, 0, 0xffffffff, 0x00000000 }, + { 0x3c58, 0, 0xffffffff, 0x00000000 }, + { 0x3c5c, 0, 0xffffffff, 0x00000000 }, + { 0x3c60, 0, 0xffffffff, 0x00000000 }, + { 0x3c64, 0, 0xffffffff, 0x00000000 }, + { 0x3c68, 0, 0xffffffff, 0x00000000 }, + { 0x3c6c, 0, 0xffffffff, 0x00000000 }, + { 0x3c70, 0, 0xffffffff, 0x00000000 }, + { 0x3c74, 0, 0x0000003f, 0x00000000 }, + { 0x3c78, 0, 0x00000000, 0x00000000 }, + { 0x3c7c, 0, 0x00000000, 0x00000000 }, + { 0x3c80, 0, 0x3fffffff, 0x00000000 }, + { 0x3c84, 0, 0x0000003f, 0x00000000 }, + { 0x3c88, 0, 0x00000000, 0xffffffff }, + { 0x3c8c, 0, 0x00000000, 0xffffffff }, + + { 0x4000, 0, 0x00000000, 0x00000001 }, + { 0x4004, 0, 0x00000000, 0x00030000 }, + { 0x4008, 0, 0x00000ff0, 0x00000000 }, + { 0x400c, 0, 0xffffffff, 0x00000000 }, + { 0x4088, 0, 0x00000000, 0x00070303 }, + + { 0x4400, 0, 0x00000000, 0x00000001 }, + { 0x4404, 0, 0x00000000, 0x00003f01 }, + { 0x4408, 0, 0x7fff00ff, 0x00000000 }, + { 0x440c, 0, 0xffffffff, 0x00000000 }, + { 0x4410, 0, 0xffff, 0x0000 }, + { 0x4414, 0, 0xffff, 0x0000 }, + { 0x4418, 0, 0xffff, 0x0000 }, + { 0x441c, 0, 0xffff, 0x0000 }, + { 0x4428, 0, 0xffffffff, 0x00000000 }, + { 0x442c, 0, 0xffffffff, 0x00000000 }, + { 0x4430, 0, 0xffffffff, 0x00000000 }, + { 0x4434, 0, 0xffffffff, 0x00000000 }, + { 0x4438, 0, 0xffffffff, 0x00000000 }, + { 0x443c, 0, 0xffffffff, 0x00000000 }, + { 0x4440, 0, 0xffffffff, 0x00000000 }, + { 0x4444, 0, 0xffffffff, 0x00000000 }, + + { 0x4c00, 0, 0x00000000, 0x00000001 }, + { 0x4c04, 0, 0x00000000, 0x0000003f }, + { 0x4c08, 0, 0xffffffff, 0x00000000 }, + { 0x4c0c, 0, 0x0007fc00, 0x00000000 }, + { 0x4c10, 0, 0x80003fe0, 0x00000000 }, + { 0x4c14, 0, 0xffffffff, 0x00000000 }, + { 0x4c44, 0, 0x00000000, 0x9fff9fff }, + { 0x4c48, 0, 0x00000000, 0xb3009fff }, + { 0x4c4c, 0, 0x00000000, 0x77f33b30 }, + { 0x4c50, 0, 0x00000000, 0xffffffff }, { 0x5004, 0, 0x00000000, 0x0000007f }, { 0x5008, 0, 0x0f0007ff, 0x00000000 }, { 0x500c, 0, 0xf800f800, 0x07ff07ff }, + { 0x5400, 0, 0x00000008, 0x00000001 }, + { 0x5404, 0, 0x00000000, 0x0000003f }, + { 0x5408, 0, 0x0000001f, 0x00000000 }, + { 0x540c, 0, 0xffffffff, 0x00000000 }, + { 0x5410, 0, 0xffffffff, 0x00000000 }, + { 0x5414, 0, 0x0000ffff, 0x00000000 }, + { 0x5418, 0, 0x0000ffff, 0x00000000 }, + { 0x541c, 0, 0x0000ffff, 0x00000000 }, + { 0x5420, 0, 0x0000ffff, 0x00000000 }, + { 0x5428, 0, 0x000000ff, 0x00000000 }, + { 0x542c, 0, 0xff00ffff, 0x00000000 }, + { 0x5430, 0, 0x001fff80, 0x00000000 }, + { 0x5438, 0, 0xffffffff, 0x00000000 }, + { 0x543c, 0, 0xffffffff, 0x00000000 }, + { 0x5440, 0, 0xf800f800, 0x07ff07ff }, + { 0x5c00, 0, 0x00000000, 0x00000001 }, { 0x5c04, 0, 0x00000000, 0x0003000f }, { 0x5c08, 0, 0x00000003, 0x00000000 }, @@ -3741,7 +3891,7 @@ reg_test_err: static int bnx2_do_mem_test(struct bnx2 *bp, u32 start, u32 size) { - static const u32 test_pattern[] = { 0x00000000, 0xffffffff, 0x55555555, + static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0x55555555, 0xaaaaaaaa , 0xaa55aa55, 0x55aa55aa }; int i; @@ -3766,7 +3916,7 @@ bnx2_test_memory(struct bnx2 *bp) { int ret = 0; int i; - static const struct { + static struct { u32 offset; u32 len; } mem_tbl[] = { @@ -3799,6 +3949,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) struct sk_buff *skb, *rx_skb; unsigned char *packet; u16 rx_start_idx, rx_idx; + u32 val; dma_addr_t map; struct tx_bd *txbd; struct sw_bd *rx_buf; @@ -3829,9 +3980,8 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) map = pci_map_single(bp->pdev, skb->data, pkt_size, PCI_DMA_TODEVICE); - REG_WR(bp, BNX2_HC_COMMAND, - bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); - + val = REG_RD(bp, BNX2_HC_COMMAND); + REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT); REG_RD(bp, BNX2_HC_COMMAND); udelay(5); @@ -3855,9 +4005,8 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) udelay(100); - REG_WR(bp, BNX2_HC_COMMAND, - bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); - + val = REG_RD(bp, BNX2_HC_COMMAND); + REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT); REG_RD(bp, BNX2_HC_COMMAND); udelay(5); @@ -3993,6 +4142,7 @@ static int bnx2_test_intr(struct bnx2 *bp) { int i; + u32 val; u16 status_idx; if (!netif_running(bp->dev)) @@ -4001,7 +4151,8 @@ bnx2_test_intr(struct bnx2 *bp) status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff; /* This register is not touched during run-time. */ - REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW); + val = REG_RD(bp, BNX2_HC_COMMAND); + REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW); REG_RD(bp, BNX2_HC_COMMAND); for (i = 0; i < 10; i++) { @@ -4252,7 +4403,7 @@ bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) } #endif -/* Called with netif_tx_lock. +/* Called with dev->xmit_lock. * hard_start_xmit is pseudo-lockless - a lock is only required when * the tx queue is full. This way, we get the benefit of lockless * operations most of the time without the complexities to handle @@ -4290,7 +4441,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } #ifdef BCM_TSO - if ((mss = skb_shinfo(skb)->gso_size) && + if ((mss = skb_shinfo(skb)->tso_size) && (skb->len > (bp->dev->mtu + ETH_HLEN))) { u32 tcp_opt_len, ip_tcp_len; @@ -4643,64 +4794,6 @@ bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) info->fw_version[5] = 0; } -#define BNX2_REGDUMP_LEN (32 * 1024) - -static int -bnx2_get_regs_len(struct net_device *dev) -{ - return BNX2_REGDUMP_LEN; -} - -static void -bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) -{ - u32 *p = _p, i, offset; - u8 *orig_p = _p; - struct bnx2 *bp = netdev_priv(dev); - u32 reg_boundaries[] = { 0x0000, 0x0098, 0x0400, 0x045c, - 0x0800, 0x0880, 0x0c00, 0x0c10, - 0x0c30, 0x0d08, 0x1000, 0x101c, - 0x1040, 0x1048, 0x1080, 0x10a4, - 0x1400, 0x1490, 0x1498, 0x14f0, - 0x1500, 0x155c, 0x1580, 0x15dc, - 0x1600, 0x1658, 0x1680, 0x16d8, - 0x1800, 0x1820, 0x1840, 0x1854, - 0x1880, 0x1894, 0x1900, 0x1984, - 0x1c00, 0x1c0c, 0x1c40, 0x1c54, - 0x1c80, 0x1c94, 0x1d00, 0x1d84, - 0x2000, 0x2030, 0x23c0, 0x2400, - 0x2800, 0x2820, 0x2830, 0x2850, - 0x2b40, 0x2c10, 0x2fc0, 0x3058, - 0x3c00, 0x3c94, 0x4000, 0x4010, - 0x4080, 0x4090, 0x43c0, 0x4458, - 0x4c00, 0x4c18, 0x4c40, 0x4c54, - 0x4fc0, 0x5010, 0x53c0, 0x5444, - 0x5c00, 0x5c18, 0x5c80, 0x5c90, - 0x5fc0, 0x6000, 0x6400, 0x6428, - 0x6800, 0x6848, 0x684c, 0x6860, - 0x6888, 0x6910, 0x8000 }; - - regs->version = 0; - - memset(p, 0, BNX2_REGDUMP_LEN); - - if (!netif_running(bp->dev)) - return; - - i = 0; - offset = reg_boundaries[0]; - p += offset; - while (offset < BNX2_REGDUMP_LEN) { - *p++ = REG_RD(bp, offset); - offset += 4; - if (offset == reg_boundaries[i + 1]) { - offset = reg_boundaries[i + 2]; - p = (u32 *) (orig_p + offset); - i += 2; - } - } -} - static void bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { @@ -4886,7 +4979,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { struct bnx2 *bp = netdev_priv(dev); - ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT; + ering->rx_max_pending = MAX_RX_DESC_CNT; ering->rx_mini_max_pending = 0; ering->rx_jumbo_max_pending = 0; @@ -4903,28 +4996,17 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { struct bnx2 *bp = netdev_priv(dev); - if ((ering->rx_pending > MAX_TOTAL_RX_DESC_CNT) || + if ((ering->rx_pending > MAX_RX_DESC_CNT) || (ering->tx_pending > MAX_TX_DESC_CNT) || (ering->tx_pending <= MAX_SKB_FRAGS)) { return -EINVAL; } - if (netif_running(bp->dev)) { - bnx2_netif_stop(bp); - bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); - bnx2_free_skbs(bp); - bnx2_free_mem(bp); - } - - bnx2_set_rx_ring_size(bp, ering->rx_pending); + bp->rx_ring_size = ering->rx_pending; bp->tx_ring_size = ering->tx_pending; if (netif_running(bp->dev)) { - int rc; - - rc = bnx2_alloc_mem(bp); - if (rc) - return rc; + bnx2_netif_stop(bp); bnx2_init_nic(bp); bnx2_netif_start(bp); } @@ -5040,7 +5122,7 @@ static struct { #define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4) -static const unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = { +static unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = { STATS_OFFSET32(stat_IfHCInOctets_hi), STATS_OFFSET32(stat_IfHCInBadOctets_hi), STATS_OFFSET32(stat_IfHCOutOctets_hi), @@ -5278,8 +5360,6 @@ static struct ethtool_ops bnx2_ethtool_ops = { .get_settings = bnx2_get_settings, .set_settings = bnx2_set_settings, .get_drvinfo = bnx2_get_drvinfo, - .get_regs_len = bnx2_get_regs_len, - .get_regs = bnx2_get_regs, .get_wol = bnx2_get_wol, .set_wol = bnx2_set_wol, .nway_reset = bnx2_nway_reset, @@ -5598,7 +5678,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->mac_addr[5] = (u8) reg; bp->tx_ring_size = MAX_TX_DESC_CNT; - bnx2_set_rx_ring_size(bp, 100); + bp->rx_ring_size = 100; bp->rx_csum = 1; @@ -5817,7 +5897,6 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) if (!netif_running(dev)) return 0; - flush_scheduled_work(); bnx2_netif_stop(bp); netif_device_detach(dev); del_timer_sync(&bp->timer); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index b87925f6a..9f691cbd6 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -13,6 +13,45 @@ #ifndef BNX2_H #define BNX2_H +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef NETIF_F_HW_VLAN_TX +#include +#define BCM_VLAN 1 +#endif +#ifdef NETIF_F_TSO +#include +#include +#include +#define BCM_TSO 1 +#endif +#include +#include +#include + /* Hardware data structures and register definitions automatically * generated from RTL code. Do not modify. */ @@ -3753,10 +3792,8 @@ struct l2_fhdr { #define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct tx_bd)) #define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) -#define MAX_RX_RINGS 4 #define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd)) #define MAX_RX_DESC_CNT (RX_DESC_CNT - 1) -#define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS) #define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \ (MAX_TX_DESC_CNT - 1)) ? \ @@ -3768,10 +3805,8 @@ struct l2_fhdr { (MAX_RX_DESC_CNT - 1)) ? \ (x) + 2 : (x) + 1 -#define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx) +#define RX_RING_IDX(x) ((x) & MAX_RX_DESC_CNT) -#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> 8) -#define RX_IDX(x) ((x) & MAX_RX_DESC_CNT) /* Context size. */ #define CTX_SHIFT 7 @@ -3868,26 +3903,15 @@ struct bnx2 { struct status_block *status_blk; u32 last_status_idx; - u32 flags; -#define PCIX_FLAG 1 -#define PCI_32BIT_FLAG 2 -#define ONE_TDMA_FLAG 4 /* no longer used */ -#define NO_WOL_FLAG 8 -#define USING_DAC_FLAG 0x10 -#define USING_MSI_FLAG 0x20 -#define ASF_ENABLE_FLAG 0x40 - - /* Put tx producer and consumer fields in separate cache lines. */ + struct tx_bd *tx_desc_ring; + struct sw_bd *tx_buf_ring; + u32 tx_prod_bseq; + u16 tx_prod; + u16 tx_cons; + int tx_ring_size; - u32 tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES))); - u16 tx_prod; - - struct tx_bd *tx_desc_ring; - struct sw_bd *tx_buf_ring; - int tx_ring_size; - - u16 tx_cons __attribute__((aligned(L1_CACHE_BYTES))); - u16 hw_tx_cons; + u16 hw_tx_cons; + u16 hw_rx_cons; #ifdef BCM_VLAN struct vlan_group *vlgrp; @@ -3896,23 +3920,19 @@ struct bnx2 { u32 rx_offset; u32 rx_buf_use_size; /* useable size */ u32 rx_buf_size; /* with alignment */ - u32 rx_max_ring_idx; - + struct rx_bd *rx_desc_ring; + struct sw_bd *rx_buf_ring; u32 rx_prod_bseq; u16 rx_prod; u16 rx_cons; - u16 hw_rx_cons; u32 rx_csum; - struct sw_bd *rx_buf_ring; - struct rx_bd *rx_desc_ring[MAX_RX_RINGS]; - /* Only used to synchronize netif_stop_queue/wake_queue when tx */ /* ring is full */ spinlock_t tx_lock; - /* End of fields used in the performance code paths. */ + /* End of fileds used in the performance code paths. */ char *name; @@ -3925,6 +3945,15 @@ struct bnx2 { /* Used to synchronize phy accesses. */ spinlock_t phy_lock; + u32 flags; +#define PCIX_FLAG 1 +#define PCI_32BIT_FLAG 2 +#define ONE_TDMA_FLAG 4 /* no longer used */ +#define NO_WOL_FLAG 8 +#define USING_DAC_FLAG 0x10 +#define USING_MSI_FLAG 0x20 +#define ASF_ENABLE_FLAG 0x40 + u32 phy_flags; #define PHY_SERDES_FLAG 1 #define PHY_CRC_FIX_FLAG 2 @@ -3975,9 +4004,8 @@ struct bnx2 { dma_addr_t tx_desc_mapping; - int rx_max_ring; int rx_ring_size; - dma_addr_t rx_desc_mapping[MAX_RX_RINGS]; + dma_addr_t rx_desc_mapping; u16 tx_quick_cons_trip; u16 tx_quick_cons_trip_int; @@ -4001,7 +4029,6 @@ struct bnx2 { struct statistics_block *stats_blk; dma_addr_t stats_blk_mapping; - u32 hc_cmd; u32 rx_mode; u16 req_line_speed; @@ -4046,8 +4073,6 @@ struct bnx2 { struct flash_spec *flash_info; u32 flash_size; - - int status_stats_size; }; static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset); diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h index 8158974c3..0c21bd849 100644 --- a/drivers/net/bnx2_fw.h +++ b/drivers/net/bnx2_fw.h @@ -14,20 +14,20 @@ * accompanying it. */ -static const int bnx2_COM_b06FwReleaseMajor = 0x1; -static const int bnx2_COM_b06FwReleaseMinor = 0x0; -static const int bnx2_COM_b06FwReleaseFix = 0x0; -static const u32 bnx2_COM_b06FwStartAddr = 0x080008b4; -static const u32 bnx2_COM_b06FwTextAddr = 0x08000000; -static const int bnx2_COM_b06FwTextLen = 0x57bc; -static const u32 bnx2_COM_b06FwDataAddr = 0x08005840; -static const int bnx2_COM_b06FwDataLen = 0x0; -static const u32 bnx2_COM_b06FwRodataAddr = 0x080057c0; -static const int bnx2_COM_b06FwRodataLen = 0x58; -static const u32 bnx2_COM_b06FwBssAddr = 0x08005860; -static const int bnx2_COM_b06FwBssLen = 0x88; -static const u32 bnx2_COM_b06FwSbssAddr = 0x08005840; -static const int bnx2_COM_b06FwSbssLen = 0x1c; +static int bnx2_COM_b06FwReleaseMajor = 0x1; +static int bnx2_COM_b06FwReleaseMinor = 0x0; +static int bnx2_COM_b06FwReleaseFix = 0x0; +static u32 bnx2_COM_b06FwStartAddr = 0x080008b4; +static u32 bnx2_COM_b06FwTextAddr = 0x08000000; +static int bnx2_COM_b06FwTextLen = 0x57bc; +static u32 bnx2_COM_b06FwDataAddr = 0x08005840; +static int bnx2_COM_b06FwDataLen = 0x0; +static u32 bnx2_COM_b06FwRodataAddr = 0x080057c0; +static int bnx2_COM_b06FwRodataLen = 0x58; +static u32 bnx2_COM_b06FwBssAddr = 0x08005860; +static int bnx2_COM_b06FwBssLen = 0x88; +static u32 bnx2_COM_b06FwSbssAddr = 0x08005840; +static int bnx2_COM_b06FwSbssLen = 0x1c; static u32 bnx2_COM_b06FwText[(0x57bc/4) + 1] = { 0x0a00022d, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x322e352e, 0x38000000, 0x02050802, 0x00000000, 0x00000003, 0x00000014, 0x00000032, @@ -2325,20 +2325,20 @@ static u32 bnx2_rv2p_proc2[] = { 0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000, 0x00000018, 0x00570000 }; -static const int bnx2_TPAT_b06FwReleaseMajor = 0x1; -static const int bnx2_TPAT_b06FwReleaseMinor = 0x0; -static const int bnx2_TPAT_b06FwReleaseFix = 0x0; -static const u32 bnx2_TPAT_b06FwStartAddr = 0x08000860; -static const u32 bnx2_TPAT_b06FwTextAddr = 0x08000800; -static const int bnx2_TPAT_b06FwTextLen = 0x122c; -static const u32 bnx2_TPAT_b06FwDataAddr = 0x08001a60; -static const int bnx2_TPAT_b06FwDataLen = 0x0; -static const u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000; -static const int bnx2_TPAT_b06FwRodataLen = 0x0; -static const u32 bnx2_TPAT_b06FwBssAddr = 0x08001aa0; -static const int bnx2_TPAT_b06FwBssLen = 0x250; -static const u32 bnx2_TPAT_b06FwSbssAddr = 0x08001a60; -static const int bnx2_TPAT_b06FwSbssLen = 0x34; +static int bnx2_TPAT_b06FwReleaseMajor = 0x1; +static int bnx2_TPAT_b06FwReleaseMinor = 0x0; +static int bnx2_TPAT_b06FwReleaseFix = 0x0; +static u32 bnx2_TPAT_b06FwStartAddr = 0x08000860; +static u32 bnx2_TPAT_b06FwTextAddr = 0x08000800; +static int bnx2_TPAT_b06FwTextLen = 0x122c; +static u32 bnx2_TPAT_b06FwDataAddr = 0x08001a60; +static int bnx2_TPAT_b06FwDataLen = 0x0; +static u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000; +static int bnx2_TPAT_b06FwRodataLen = 0x0; +static u32 bnx2_TPAT_b06FwBssAddr = 0x08001aa0; +static int bnx2_TPAT_b06FwBssLen = 0x250; +static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001a60; +static int bnx2_TPAT_b06FwSbssLen = 0x34; static u32 bnx2_TPAT_b06FwText[(0x122c/4) + 1] = { 0x0a000218, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20322e35, 0x2e313100, 0x02050b01, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -2540,20 +2540,20 @@ static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 }; static u32 bnx2_TPAT_b06FwBss[(0x250/4) + 1] = { 0x0 }; static u32 bnx2_TPAT_b06FwSbss[(0x34/4) + 1] = { 0x0 }; -static const int bnx2_TXP_b06FwReleaseMajor = 0x1; -static const int bnx2_TXP_b06FwReleaseMinor = 0x0; -static const int bnx2_TXP_b06FwReleaseFix = 0x0; -static const u32 bnx2_TXP_b06FwStartAddr = 0x080034b0; -static const u32 bnx2_TXP_b06FwTextAddr = 0x08000000; -static const int bnx2_TXP_b06FwTextLen = 0x5748; -static const u32 bnx2_TXP_b06FwDataAddr = 0x08005760; -static const int bnx2_TXP_b06FwDataLen = 0x0; -static const u32 bnx2_TXP_b06FwRodataAddr = 0x00000000; -static const int bnx2_TXP_b06FwRodataLen = 0x0; -static const u32 bnx2_TXP_b06FwBssAddr = 0x080057a0; -static const int bnx2_TXP_b06FwBssLen = 0x1c4; -static const u32 bnx2_TXP_b06FwSbssAddr = 0x08005760; -static const int bnx2_TXP_b06FwSbssLen = 0x38; +static int bnx2_TXP_b06FwReleaseMajor = 0x1; +static int bnx2_TXP_b06FwReleaseMinor = 0x0; +static int bnx2_TXP_b06FwReleaseFix = 0x0; +static u32 bnx2_TXP_b06FwStartAddr = 0x080034b0; +static u32 bnx2_TXP_b06FwTextAddr = 0x08000000; +static int bnx2_TXP_b06FwTextLen = 0x5748; +static u32 bnx2_TXP_b06FwDataAddr = 0x08005760; +static int bnx2_TXP_b06FwDataLen = 0x0; +static u32 bnx2_TXP_b06FwRodataAddr = 0x00000000; +static int bnx2_TXP_b06FwRodataLen = 0x0; +static u32 bnx2_TXP_b06FwBssAddr = 0x080057a0; +static int bnx2_TXP_b06FwBssLen = 0x1c4; +static u32 bnx2_TXP_b06FwSbssAddr = 0x08005760; +static int bnx2_TXP_b06FwSbssLen = 0x38; static u32 bnx2_TXP_b06FwText[(0x5748/4) + 1] = { 0x0a000d2c, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x322e352e, 0x38000000, 0x02050800, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000, diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 6a407070c..f3f582546 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2294,34 +2294,6 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) port->sm_vars |= AD_PORT_BEGIN; } -/* - * set link state for bonding master: if we have an active partnered - * aggregator, we're up, if not, we're down. Presumes that we cannot - * have an active aggregator if there are no slaves with link up. - * - * Called by bond_set_carrier(). Return zero if carrier state does not - * change, nonzero if it does. - */ -int bond_3ad_set_carrier(struct bonding *bond) -{ - struct aggregator *agg; - - agg = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator)); - if (agg && MAC_ADDRESS_COMPARE(&agg->partner_system, &null_mac_addr)) { - if (!netif_carrier_ok(bond->dev)) { - netif_carrier_on(bond->dev); - return 1; - } - return 0; - } - - if (netif_carrier_ok(bond->dev)) { - netif_carrier_off(bond->dev); - return 1; - } - return 0; -} - /** * bond_3ad_get_active_agg_info - get information of the active aggregator * @bond: bonding struct to work on diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 6ad5ad6e6..5ee2cef5b 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -283,6 +283,5 @@ void bond_3ad_handle_link_change(struct slave *slave, char link); int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev); -int bond_3ad_set_carrier(struct bonding *bond); #endif //__BOND_3AD_H__ diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index e83bc825f..f2a63186a 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -1261,7 +1261,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) struct ethhdr *eth_data; struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); struct slave *tx_slave = NULL; - static const u32 ip_bcast = 0xffffffff; + static u32 ip_bcast = 0xffffffff; int hash_size = 0; int do_tx_balance = 1; u32 hash_index = 0; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8171cae06..bcf9f17da 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -131,7 +131,7 @@ MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); /*----------------------------- Global variables ----------------------------*/ -static const char * const version = +static const char *version = DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; LIST_HEAD(bond_dev_list); @@ -558,42 +558,6 @@ out: /*------------------------------- Link status -------------------------------*/ -/* - * Set the carrier state for the master according to the state of its - * slaves. If any slaves are up, the master is up. In 802.3ad mode, - * do special 802.3ad magic. - * - * Returns zero if carrier state does not change, nonzero if it does. - */ -static int bond_set_carrier(struct bonding *bond) -{ - struct slave *slave; - int i; - - if (bond->slave_cnt == 0) - goto down; - - if (bond->params.mode == BOND_MODE_8023AD) - return bond_3ad_set_carrier(bond); - - bond_for_each_slave(bond, slave, i) { - if (slave->link == BOND_LINK_UP) { - if (!netif_carrier_ok(bond->dev)) { - netif_carrier_on(bond->dev); - return 1; - } - return 0; - } - } - -down: - if (netif_carrier_ok(bond->dev)) { - netif_carrier_off(bond->dev); - return 1; - } - return 0; -} - /* * Get link speed and duplex from the slave's base driver * using ethtool. If for some reason the call fails or the @@ -1076,10 +1040,6 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) if ((bond->params.mode == BOND_MODE_TLB) || (bond->params.mode == BOND_MODE_ALB)) { bond_alb_handle_active_change(bond, new_active); - if (old_active) - bond_set_slave_inactive_flags(old_active); - if (new_active) - bond_set_slave_active_flags(new_active); } else { bond->curr_active_slave = new_active; } @@ -1110,24 +1070,10 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) void bond_select_active_slave(struct bonding *bond) { struct slave *best_slave; - int rv; best_slave = bond_find_best_slave(bond); if (best_slave != bond->curr_active_slave) { bond_change_active_slave(bond, best_slave); - rv = bond_set_carrier(bond); - if (!rv) - return; - - if (netif_carrier_ok(bond->dev)) { - printk(KERN_INFO DRV_NAME - ": %s: first active interface up!\n", - bond->dev->name); - } else { - printk(KERN_INFO DRV_NAME ": %s: " - "now running without any active interface !\n", - bond->dev->name); - } } } @@ -1199,7 +1145,8 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev) } #define BOND_INTERSECT_FEATURES \ - (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO) + (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\ + NETIF_F_TSO|NETIF_F_UFO) /* * Compute the common dev->feature set available to all slaves. Some @@ -1217,7 +1164,9 @@ static int bond_compute_features(struct bonding *bond) features &= (slave->dev->features & BOND_INTERSECT_FEATURES); if ((features & NETIF_F_SG) && - !(features & NETIF_F_ALL_CSUM)) + !(features & (NETIF_F_IP_CSUM | + NETIF_F_NO_CSUM | + NETIF_F_HW_CSUM))) features &= ~NETIF_F_SG; /* @@ -1494,25 +1443,20 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) switch (bond->params.mode) { case BOND_MODE_ACTIVEBACKUP: - /* if we're in active-backup mode, we need one and - * only one active interface. The backup interfaces - * will have their SLAVE_INACTIVE flag set because we - * need them to be drop all packets. Thus, since we - * guarantee that curr_active_slave always point to - * the last usable interface, we just have to verify - * this interface's flag. + /* if we're in active-backup mode, we need one and only one active + * interface. The backup interfaces will have their NOARP flag set + * because we need them to be completely deaf and not to respond to + * any ARP request on the network to avoid fooling a switch. Thus, + * since we guarantee that curr_active_slave always point to the last + * usable interface, we just have to verify this interface's flag. */ if (((!bond->curr_active_slave) || - (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) && + (bond->curr_active_slave->dev->flags & IFF_NOARP)) && (new_slave->link != BOND_LINK_DOWN)) { + dprintk("This is the first active slave\n"); /* first slave or no active slave yet, and this link is OK, so make this interface the active one */ bond_change_active_slave(bond, new_slave); - printk(KERN_INFO DRV_NAME - ": %s: first active interface up!\n", - bond->dev->name); - netif_carrier_on(bond->dev); - } else { dprintk("This is just a backup slave\n"); bond_set_slave_inactive_flags(new_slave); @@ -1548,8 +1492,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) * is OK, so make this interface the active one */ bond_change_active_slave(bond, new_slave); - } else { - bond_set_slave_inactive_flags(new_slave); } break; default: @@ -1568,8 +1510,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) break; } /* switch(bond_mode) */ - bond_set_carrier(bond); - write_unlock_bh(&bond->lock); res = bond_create_slave_symlinks(bond_dev, slave_dev); @@ -1709,12 +1649,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) bond_alb_deinit_slave(bond, slave); } - if (oldcurrent == slave) + if (oldcurrent == slave) { bond_select_active_slave(bond); - if (bond->slave_cnt == 0) { - bond_set_carrier(bond); + if (!bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + } + if (bond->slave_cnt == 0) { /* if the last slave was removed, zero the mac address * of the master so it will be set by the application * to the mac address of the first slave @@ -1778,8 +1724,13 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) addr.sa_family = slave_dev->type; dev_set_mac_address(slave_dev, &addr); - slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | - IFF_SLAVE_INACTIVE); + /* restore the original state of the + * IFF_NOARP flag that might have been + * set by bond_set_slave_inactive_flags() + */ + if ((slave->original_flags & IFF_NOARP) == 0) { + slave_dev->flags &= ~IFF_NOARP; + } kfree(slave); @@ -1798,8 +1749,6 @@ static int bond_release_all(struct net_device *bond_dev) write_lock_bh(&bond->lock); - netif_carrier_off(bond_dev); - if (bond->slave_cnt == 0) { goto out; } @@ -1867,8 +1816,12 @@ static int bond_release_all(struct net_device *bond_dev) addr.sa_family = slave_dev->type; dev_set_mac_address(slave_dev, &addr); - slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | - IFF_SLAVE_INACTIVE); + /* restore the original state of the IFF_NOARP flag that might have + * been set by bond_set_slave_inactive_flags() + */ + if ((slave->original_flags & IFF_NOARP) == 0) { + slave_dev->flags &= ~IFF_NOARP; + } kfree(slave); @@ -2236,9 +2189,15 @@ void bond_mii_monitor(struct net_device *bond_dev) bond_select_active_slave(bond); + if (oldcurrent && !bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + write_unlock(&bond->curr_slave_lock); - } else - bond_set_carrier(bond); + } re_arm: if (bond->params.miimon) { @@ -2542,6 +2501,13 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev) bond_select_active_slave(bond); + if (oldcurrent && !bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + write_unlock(&bond->curr_slave_lock); } @@ -2615,15 +2581,12 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) bond->current_arp_slave = NULL; } - bond_set_carrier(bond); - if (slave == bond->curr_active_slave) { printk(KERN_INFO DRV_NAME ": %s: %s is up and now the " "active interface\n", bond_dev->name, slave->dev->name); - netif_carrier_on(bond->dev); } else { printk(KERN_INFO DRV_NAME ": %s: backup interface %s is " @@ -2883,8 +2846,7 @@ static void bond_info_show_master(struct seq_file *seq) (curr) ? curr->dev->name : "None"); } - seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ? - "up" : "down"); + seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down"); seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon); seq_printf(seq, "Up Delay (ms): %d\n", bond->params.updelay * bond->params.miimon); @@ -3199,7 +3161,7 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave * bond_netdev_event: handle netdev notifier chain events. * * This function receives events for the netdev chain. The caller (an - * ioctl handler calling blocking_notifier_call_chain) holds the necessary + * ioctl handler calling notifier_call_chain) holds the necessary * locks for us to safely manipulate the slave devices (RTNL lock, * dev_probe_lock). */ @@ -4099,17 +4061,14 @@ void bond_set_mode_ops(struct bonding *bond, int mode) bond_dev->hard_start_xmit = bond_xmit_broadcast; break; case BOND_MODE_8023AD: - bond_set_master_3ad_flags(bond); bond_dev->hard_start_xmit = bond_3ad_xmit_xor; if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) bond->xmit_hash_policy = bond_xmit_hash_policy_l34; else bond->xmit_hash_policy = bond_xmit_hash_policy_l2; break; - case BOND_MODE_ALB: - bond_set_master_alb_flags(bond); - /* FALLTHRU */ case BOND_MODE_TLB: + case BOND_MODE_ALB: bond_dev->hard_start_xmit = bond_alb_xmit; bond_dev->set_mac_address = bond_alb_set_mac_address; break; @@ -4188,7 +4147,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) */ bond_dev->features |= NETIF_F_VLAN_CHALLENGED; - /* don't acquire bond device's netif_tx_lock when + /* don't acquire bond device's xmit_lock when * transmitting */ bond_dev->features |= NETIF_F_LLTX; @@ -4571,8 +4530,6 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond if (newbond) *newbond = bond_dev->priv; - netif_carrier_off(bond_dev); - rtnl_unlock(); /* allows sysfs registration of net device */ res = bond_create_sysfs_entry(bond_dev->priv); goto done; diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 5a9bd9588..041bcc583 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -424,12 +424,6 @@ static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size ret = -EINVAL; goto out; } else { - if (bond->params.mode == BOND_MODE_8023AD) - bond_unset_master_3ad_flags(bond); - - if (bond->params.mode == BOND_MODE_ALB) - bond_unset_master_alb_flags(bond); - bond->params.mode = new_value; bond_set_mode_ops(bond, bond->params.mode); printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n", diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 0bdfe2c71..3dd78d048 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -22,8 +22,8 @@ #include "bond_3ad.h" #include "bond_alb.h" -#define DRV_VERSION "3.0.3" -#define DRV_RELDATE "March 23, 2006" +#define DRV_VERSION "3.0.1" +#define DRV_RELDATE "January 9, 2006" #define DRV_NAME "bonding" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" @@ -230,37 +230,14 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) static inline void bond_set_slave_inactive_flags(struct slave *slave) { - struct bonding *bond = slave->dev->master->priv; - if (bond->params.mode != BOND_MODE_TLB && - bond->params.mode != BOND_MODE_ALB) - slave->state = BOND_STATE_BACKUP; - slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; + slave->state = BOND_STATE_BACKUP; + slave->dev->flags |= IFF_NOARP; } static inline void bond_set_slave_active_flags(struct slave *slave) { slave->state = BOND_STATE_ACTIVE; - slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; -} - -static inline void bond_set_master_3ad_flags(struct bonding *bond) -{ - bond->dev->priv_flags |= IFF_MASTER_8023AD; -} - -static inline void bond_unset_master_3ad_flags(struct bonding *bond) -{ - bond->dev->priv_flags &= ~IFF_MASTER_8023AD; -} - -static inline void bond_set_master_alb_flags(struct bonding *bond) -{ - bond->dev->priv_flags |= IFF_MASTER_ALB; -} - -static inline void bond_unset_master_alb_flags(struct bonding *bond) -{ - bond->dev->priv_flags &= ~IFF_MASTER_ALB; + slave->dev->flags &= ~IFF_NOARP; } struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index ac48f7543..6e295fce5 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -91,7 +91,6 @@ #include #include #include -#include #include @@ -192,15 +191,12 @@ static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; -static int cassini_debug = -1; /* -1 == use CAS_DEF_MSG_ENABLE as value */ -static int link_mode; - MODULE_AUTHOR("Adrian Sun (asun@darksunrising.com)"); MODULE_DESCRIPTION("Sun Cassini(+) ethernet driver"); MODULE_LICENSE("GPL"); -module_param(cassini_debug, int, 0); +MODULE_PARM(cassini_debug, "i"); MODULE_PARM_DESC(cassini_debug, "Cassini bitmapped debugging message enable value"); -module_param(link_mode, int, 0); +MODULE_PARM(link_mode, "i"); MODULE_PARM_DESC(link_mode, "default link mode"); /* @@ -212,7 +208,7 @@ MODULE_PARM_DESC(link_mode, "default link mode"); * Value in seconds, for user input. */ static int linkdown_timeout = DEFAULT_LINKDOWN_TIMEOUT; -module_param(linkdown_timeout, int, 0); +MODULE_PARM(linkdown_timeout, "i"); MODULE_PARM_DESC(linkdown_timeout, "min reset interval in sec. for PCS linkdown issue; disabled if not positive"); @@ -224,6 +220,8 @@ MODULE_PARM_DESC(linkdown_timeout, static int link_transition_timeout; +static int cassini_debug = -1; /* -1 == use CAS_DEF_MSG_ENABLE as value */ +static int link_mode; static u16 link_modes[] __devinitdata = { BMCR_ANENABLE, /* 0 : autoneg */ @@ -3894,7 +3892,7 @@ static void cas_reset(struct cas *cp, int blkflag) spin_unlock(&cp->stat_lock[N_TX_RINGS]); } -/* Shut down the chip, must be called with pm_mutex held. */ +/* Shut down the chip, must be called with pm_sem held. */ static void cas_shutdown(struct cas *cp) { unsigned long flags; @@ -4313,11 +4311,11 @@ static int cas_open(struct net_device *dev) int hw_was_up, err; unsigned long flags; - mutex_lock(&cp->pm_mutex); + down(&cp->pm_sem); hw_was_up = cp->hw_running; - /* The power-management mutex protects the hw_running + /* The power-management semaphore protects the hw_running * etc. state so it is safe to do this bit without cp->lock */ if (!cp->hw_running) { @@ -4366,7 +4364,7 @@ static int cas_open(struct net_device *dev) cas_unlock_all_restore(cp, flags); netif_start_queue(dev); - mutex_unlock(&cp->pm_mutex); + up(&cp->pm_sem); return 0; err_spare: @@ -4374,7 +4372,7 @@ err_spare: cas_free_rxds(cp); err_tx_tiny: cas_tx_tiny_free(cp); - mutex_unlock(&cp->pm_mutex); + up(&cp->pm_sem); return err; } @@ -4384,7 +4382,7 @@ static int cas_close(struct net_device *dev) struct cas *cp = netdev_priv(dev); /* Make sure we don't get distracted by suspend/resume */ - mutex_lock(&cp->pm_mutex); + down(&cp->pm_sem); netif_stop_queue(dev); @@ -4401,7 +4399,7 @@ static int cas_close(struct net_device *dev) cas_spare_free(cp); cas_free_rxds(cp); cas_tx_tiny_free(cp); - mutex_unlock(&cp->pm_mutex); + up(&cp->pm_sem); return 0; } @@ -4836,10 +4834,10 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) unsigned long flags; int rc = -EOPNOTSUPP; - /* Hold the PM mutex while doing ioctl's or we may collide + /* Hold the PM semaphore while doing ioctl's or we may collide * with open/close and power management and oops. */ - mutex_lock(&cp->pm_mutex); + down(&cp->pm_sem); switch (cmd) { case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = cp->phy_addr; @@ -4869,7 +4867,7 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; }; - mutex_unlock(&cp->pm_mutex); + up(&cp->pm_sem); return rc; } @@ -4996,7 +4994,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, spin_lock_init(&cp->tx_lock[i]); } spin_lock_init(&cp->stat_lock[N_TX_RINGS]); - mutex_init(&cp->pm_mutex); + init_MUTEX(&cp->pm_sem); init_timer(&cp->link_timer); cp->link_timer.function = cas_link_timer; @@ -5118,10 +5116,10 @@ err_out_free_consistent: cp->init_block, cp->block_dvma); err_out_iounmap: - mutex_lock(&cp->pm_mutex); + down(&cp->pm_sem); if (cp->hw_running) cas_shutdown(cp); - mutex_unlock(&cp->pm_mutex); + up(&cp->pm_sem); iounmap(cp->regs); @@ -5154,11 +5152,11 @@ static void __devexit cas_remove_one(struct pci_dev *pdev) cp = netdev_priv(dev); unregister_netdev(dev); - mutex_lock(&cp->pm_mutex); + down(&cp->pm_sem); flush_scheduled_work(); if (cp->hw_running) cas_shutdown(cp); - mutex_unlock(&cp->pm_mutex); + up(&cp->pm_sem); #if 1 if (cp->orig_cacheline_size) { @@ -5185,7 +5183,10 @@ static int cas_suspend(struct pci_dev *pdev, pm_message_t state) struct cas *cp = netdev_priv(dev); unsigned long flags; - mutex_lock(&cp->pm_mutex); + /* We hold the PM semaphore during entire driver + * sleep time + */ + down(&cp->pm_sem); /* If the driver is opened, we stop the DMA */ if (cp->opened) { @@ -5205,7 +5206,6 @@ static int cas_suspend(struct pci_dev *pdev, pm_message_t state) if (cp->hw_running) cas_shutdown(cp); - mutex_unlock(&cp->pm_mutex); return 0; } @@ -5217,7 +5217,6 @@ static int cas_resume(struct pci_dev *pdev) printk(KERN_INFO "%s: resuming\n", dev->name); - mutex_lock(&cp->pm_mutex); cas_hard_reset(cp); if (cp->opened) { unsigned long flags; @@ -5230,7 +5229,7 @@ static int cas_resume(struct pci_dev *pdev) netif_device_attach(dev); } - mutex_unlock(&cp->pm_mutex); + up(&cp->pm_sem); return 0; } #endif /* CONFIG_PM */ diff --git a/drivers/net/cassini.h b/drivers/net/cassini.h index ab55c7ee1..88063ef16 100644 --- a/drivers/net/cassini.h +++ b/drivers/net/cassini.h @@ -4284,7 +4284,7 @@ struct cas { * (ie. not power managed) */ int hw_running; int opened; - struct mutex pm_mutex; /* open/close/suspend/resume */ + struct semaphore pm_sem; /* open/close/suspend/resume */ struct cas_init_block *init_block; struct cas_tx_desc *init_txds[MAX_TX_RINGS]; diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile index 54c78d94f..91e927827 100644 --- a/drivers/net/chelsio/Makefile +++ b/drivers/net/chelsio/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_CHELSIO_T1) += cxgb.o -EXTRA_CFLAGS += -Idrivers/net/chelsio $(DEBUG_FLAGS) +EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/chelsio $(DEBUG_FLAGS) cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index 7fe2638ae..349ebe783 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -124,7 +124,7 @@ MODULE_LICENSE("GPL"); static int dflt_msg_enable = DFLT_MSG_ENABLE; -module_param(dflt_msg_enable, int, 0); +MODULE_PARM(dflt_msg_enable, "i"); MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 message enable bitmap"); diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c index 542e5e065..e824acaf1 100644 --- a/drivers/net/chelsio/espi.c +++ b/drivers/net/chelsio/espi.c @@ -87,9 +87,15 @@ static int tricn_write(adapter_t *adapter, int bundle_addr, int module_addr, static int tricn_init(adapter_t *adapter) { int i = 0; + int sme = 1; int stat = 0; int timeout = 0; int is_ready = 0; + int dynamic_deskew = 0; + + if (dynamic_deskew) + sme = 0; + /* 1 */ timeout=1000; @@ -107,9 +113,11 @@ static int tricn_init(adapter_t *adapter) } /* 2 */ - tricn_write(adapter, 0, 0, 0, TRICN_CNFG, 0x81); - tricn_write(adapter, 0, 1, 0, TRICN_CNFG, 0x81); - tricn_write(adapter, 0, 2, 0, TRICN_CNFG, 0x81); + if (sme) { + tricn_write(adapter, 0, 0, 0, TRICN_CNFG, 0x81); + tricn_write(adapter, 0, 1, 0, TRICN_CNFG, 0x81); + tricn_write(adapter, 0, 2, 0, TRICN_CNFG, 0x81); + } for (i=1; i<= 8; i++) tricn_write(adapter, 0, 0, i, TRICN_CNFG, 0xf1); for (i=1; i<= 2; i++) tricn_write(adapter, 0, 1, i, TRICN_CNFG, 0xf1); for (i=1; i<= 3; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1); diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 722be62f3..30ff8ea1a 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1093,7 +1093,8 @@ static int process_responses(struct adapter *adapter, int budget) if (likely(e->DataValid)) { struct freelQ *fl = &sge->freelQ[e->FreelistQid]; - BUG_ON(!e->Sop || !e->Eop); + if (unlikely(!e->Sop || !e->Eop)) + BUG(); if (unlikely(e->Offload)) unexpected_offload(adapter, fl); else @@ -1418,7 +1419,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) struct cpl_tx_pkt *cpl; #ifdef NETIF_F_TSO - if (skb_is_gso(skb)) { + if (skb_shinfo(skb)->tso_size) { int eth_type; struct cpl_tx_pkt_lso *hdr; @@ -1433,7 +1434,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) hdr->ip_hdr_words = skb->nh.iph->ihl; hdr->tcp_hdr_words = skb->h.th->doff; hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type, - skb_shinfo(skb)->gso_size)); + skb_shinfo(skb)->tso_size)); hdr->len = htonl(skb->len - sizeof(*hdr)); cpl = (struct cpl_tx_pkt *)hdr; sge->stats.tx_lso_pkts++; diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c index 12e4e96db..1ebb5d149 100644 --- a/drivers/net/chelsio/subr.c +++ b/drivers/net/chelsio/subr.c @@ -686,7 +686,7 @@ int t1_init_hw_modules(adapter_t *adapter) */ static void __devinit get_pci_mode(adapter_t *adapter, struct chelsio_pci_params *p) { - static const unsigned short speed_map[] = { 33, 66, 100, 133 }; + static unsigned short speed_map[] = { 33, 66, 100, 133 }; u32 pci_mode; pci_read_config_dword(adapter->pdev, A_PCICFG_MODE, &pci_mode); diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 0941d40f0..03804cc38 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -1412,7 +1412,7 @@ static int __init depca_mca_probe(struct device *device) irq = 11; break; default: - printk("%s: mca_probe IRQ error. You should never get here (%d).\n", mdev->name, where); + printk("%s: mca_probe IRQ error. You should never get here (%d).\n", dev->name, where); return -EINVAL; } diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index e175d4876..70b47e4c4 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -993,7 +993,7 @@ dgrs_download(struct net_device *dev0) int is; unsigned long i; - static const int iv2is[16] = { + static int iv2is[16] = { 0, 0, 0, ES4H_IS_INT3, 0, ES4H_IS_INT5, 0, ES4H_IS_INT7, 0, 0, ES4H_IS_INT10, ES4H_IS_INT11, @@ -1551,7 +1551,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi- static int __init dgrs_init_module (void) { int i; - int err; + int cardcount = 0; /* * Command line variable overrides @@ -1593,13 +1593,13 @@ static int __init dgrs_init_module (void) * Find and configure all the cards */ #ifdef CONFIG_EISA - err = eisa_driver_register(&dgrs_eisa_driver); - if (err) - return err; + cardcount = eisa_driver_register(&dgrs_eisa_driver); + if (cardcount < 0) + return cardcount; #endif - err = pci_register_driver(&dgrs_pci_driver); - if (err) - return err; + cardcount = pci_register_driver(&dgrs_pci_driver); + if (cardcount) + return cardcount; return 0; } diff --git a/drivers/net/dgrs_firmware.c b/drivers/net/dgrs_firmware.c index 8c20d4c99..1e49e1e1f 100644 --- a/drivers/net/dgrs_firmware.c +++ b/drivers/net/dgrs_firmware.c @@ -1,4 +1,4 @@ -static const int dgrs_firmnum = 550; +static int dgrs_firmnum = 550; static char dgrs_firmver[] = "$Version$"; static char dgrs_firmdate[] = "11/16/96 03:45:15"; static unsigned char dgrs_code[] __initdata = { @@ -9963,4 +9963,4 @@ static unsigned char dgrs_code[] __initdata = { 109,46,99,0,114,99,0,0,48,120,0,0, 0,0,0,0,0,0,0,0,0,0,0,0 } ; -static const int dgrs_ncode = 119520 ; +static int dgrs_ncode = 119520 ; diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 038447fb5..fb9dae302 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -53,7 +53,6 @@ #define DRV_VERSION "v1.17b" #define DRV_RELDATE "2006/03/10" #include "dl2k.h" -#include static char version[] __devinitdata = KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n"; @@ -91,8 +90,8 @@ module_param(tx_coalesce, int, 0); /* HW xmit count each TxDMAComplete */ #define EnableInt() \ writew(DEFAULT_INTR, ioaddr + IntEnable) -static const int max_intrloop = 50; -static const int multicast_filter_limit = 0x40; +static int max_intrloop = 50; +static int multicast_filter_limit = 0x40; static int rio_open (struct net_device *dev); static void rio_timer (unsigned long data); @@ -766,7 +765,7 @@ rio_free_tx (struct net_device *dev, int irq) break; skb = np->tx_skbuff[entry]; pci_unmap_single (np->pdev, - np->tx_ring[entry].fraginfo & DMA_48BIT_MASK, + np->tx_ring[entry].fraginfo & 0xffffffffffff, skb->len, PCI_DMA_TODEVICE); if (irq) dev_kfree_skb_irq (skb); @@ -894,7 +893,7 @@ receive_packet (struct net_device *dev) /* Small skbuffs for short packets */ if (pkt_len > copy_thresh) { pci_unmap_single (np->pdev, - desc->fraginfo & DMA_48BIT_MASK, + desc->fraginfo & 0xffffffffffff, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb_put (skb = np->rx_skbuff[entry], pkt_len); @@ -902,7 +901,7 @@ receive_packet (struct net_device *dev) } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) { pci_dma_sync_single_for_cpu(np->pdev, desc->fraginfo & - DMA_48BIT_MASK, + 0xffffffffffff, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; @@ -914,7 +913,7 @@ receive_packet (struct net_device *dev) skb_put (skb, pkt_len); pci_dma_sync_single_for_device(np->pdev, desc->fraginfo & - DMA_48BIT_MASK, + 0xffffffffffff, np->rx_buf_sz, PCI_DMA_FROMDEVICE); } @@ -1801,7 +1800,7 @@ rio_close (struct net_device *dev) skb = np->rx_skbuff[i]; if (skb) { pci_unmap_single(np->pdev, - np->rx_ring[i].fraginfo & DMA_48BIT_MASK, + np->rx_ring[i].fraginfo & 0xffffffffffff, skb->len, PCI_DMA_FROMDEVICE); dev_kfree_skb (skb); np->rx_skbuff[i] = NULL; @@ -1811,7 +1810,7 @@ rio_close (struct net_device *dev) skb = np->tx_skbuff[i]; if (skb) { pci_unmap_single(np->pdev, - np->tx_ring[i].fraginfo & DMA_48BIT_MASK, + np->tx_ring[i].fraginfo & 0xffffffffffff, skb->len, PCI_DMA_TODEVICE); dev_kfree_skb (skb); np->tx_skbuff[i] = NULL; diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 31ac001f5..f57a85fed 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -598,8 +598,8 @@ static void e100_enable_irq(struct nic *nic) spin_lock_irqsave(&nic->cmd_lock, flags); writeb(irq_mask_none, &nic->csr->scb.cmd_hi); - e100_write_flush(nic); spin_unlock_irqrestore(&nic->cmd_lock, flags); + e100_write_flush(nic); } static void e100_disable_irq(struct nic *nic) @@ -608,8 +608,8 @@ static void e100_disable_irq(struct nic *nic) spin_lock_irqsave(&nic->cmd_lock, flags); writeb(irq_mask_all, &nic->csr->scb.cmd_hi); - e100_write_flush(nic); spin_unlock_irqrestore(&nic->cmd_lock, flags); + e100_write_flush(nic); } static void e100_hw_reset(struct nic *nic) @@ -1582,8 +1582,8 @@ static void e100_watchdog(unsigned long data) * interrupt mask bit and the SW Interrupt generation bit */ spin_lock_irq(&nic->cmd_lock); writeb(readb(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi); - e100_write_flush(nic); spin_unlock_irq(&nic->cmd_lock); + e100_write_flush(nic); e100_update_stats(nic); e100_adjust_adaptive_ifs(nic, cmd.speed, cmd.duplex); diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 281de41d0..99baf0e09 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -83,6 +83,10 @@ struct e1000_adapter; #include "e1000_hw.h" +#ifdef CONFIG_E1000_MQ +#include +#include +#endif #ifdef DBG #define E1000_DBG(args...) printk(KERN_DEBUG "e1000: " args) @@ -165,6 +169,12 @@ struct e1000_buffer { uint16_t next_to_watch; }; +#ifdef CONFIG_E1000_MQ +struct e1000_queue_stats { + uint64_t packets; + uint64_t bytes; +}; +#endif struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; }; struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; }; @@ -188,7 +198,12 @@ struct e1000_tx_ring { spinlock_t tx_lock; uint16_t tdh; uint16_t tdt; + boolean_t last_tx_tso; + +#ifdef CONFIG_E1000_MQ + struct e1000_queue_stats tx_stats; +#endif }; struct e1000_rx_ring { @@ -215,6 +230,9 @@ struct e1000_rx_ring { uint16_t rdh; uint16_t rdt; +#ifdef CONFIG_E1000_MQ + struct e1000_queue_stats rx_stats; +#endif }; #define E1000_DESC_UNUSED(R) \ @@ -242,7 +260,6 @@ struct e1000_adapter { uint32_t rx_buffer_len; uint32_t part_num; uint32_t wol; - uint32_t ksp3_port_a; uint32_t smartspeed; uint32_t en_mng_pt; uint16_t link_speed; @@ -252,8 +269,8 @@ struct e1000_adapter { spinlock_t tx_queue_lock; #endif atomic_t irq_sem; + struct work_struct tx_timeout_task; struct work_struct watchdog_task; - struct work_struct reset_task; uint8_t fc_autoneg; struct timer_list blink_timer; @@ -261,6 +278,9 @@ struct e1000_adapter { /* TX */ struct e1000_tx_ring *tx_ring; /* One per active queue */ +#ifdef CONFIG_E1000_MQ + struct e1000_tx_ring **cpu_tx_ring; /* per-cpu */ +#endif unsigned long tx_queue_len; uint32_t txd_cmd; uint32_t tx_int_delay; @@ -281,18 +301,23 @@ struct e1000_adapter { /* RX */ #ifdef CONFIG_E1000_NAPI boolean_t (*clean_rx) (struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int *work_done, int work_to_do); + struct e1000_rx_ring *rx_ring, + int *work_done, int work_to_do); #else boolean_t (*clean_rx) (struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring); + struct e1000_rx_ring *rx_ring); #endif void (*alloc_rx_buf) (struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int cleaned_count); + struct e1000_rx_ring *rx_ring, + int cleaned_count); struct e1000_rx_ring *rx_ring; /* One per active queue */ #ifdef CONFIG_E1000_NAPI struct net_device *polling_netdev; /* One per active queue */ +#endif +#ifdef CONFIG_E1000_MQ + struct net_device **cpu_netdev; /* per-cpu */ + struct call_async_data_struct rx_sched_call_data; + cpumask_t cpumask; #endif int num_tx_queues; int num_rx_queues; @@ -328,37 +353,10 @@ struct e1000_adapter { struct e1000_rx_ring test_rx_ring; - uint32_t *config_space; + u32 *config_space; int msg_enable; #ifdef CONFIG_PCI_MSI boolean_t have_msi; -#endif - /* to not mess up cache alignment, always add to the bottom */ - boolean_t txb2b; -#ifdef NETIF_F_TSO - boolean_t tso_force; #endif }; - - -/* e1000_main.c */ -extern char e1000_driver_name[]; -extern char e1000_driver_version[]; -int e1000_up(struct e1000_adapter *adapter); -void e1000_down(struct e1000_adapter *adapter); -void e1000_reset(struct e1000_adapter *adapter); -int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); -void e1000_free_all_tx_resources(struct e1000_adapter *adapter); -int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); -void e1000_free_all_rx_resources(struct e1000_adapter *adapter); -void e1000_update_stats(struct e1000_adapter *adapter); -int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx); - -/* e1000_ethtool.c */ -void e1000_set_ethtool_ops(struct net_device *netdev); - -/* e1000_param.c */ -void e1000_check_options(struct e1000_adapter *adapter); - - #endif /* _E1000_H_ */ diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index d1c705b41..5cedc8178 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -32,6 +32,19 @@ #include +extern char e1000_driver_name[]; +extern char e1000_driver_version[]; + +extern int e1000_up(struct e1000_adapter *adapter); +extern void e1000_down(struct e1000_adapter *adapter); +extern void e1000_reset(struct e1000_adapter *adapter); +extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx); +extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); +extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); +extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter); +extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter); +extern void e1000_update_stats(struct e1000_adapter *adapter); + struct e1000_stats { char stat_string[ETH_GSTRING_LEN]; int sizeof_stat; @@ -47,6 +60,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "tx_bytes", E1000_STAT(net_stats.tx_bytes) }, { "rx_errors", E1000_STAT(net_stats.rx_errors) }, { "tx_errors", E1000_STAT(net_stats.tx_errors) }, + { "rx_dropped", E1000_STAT(net_stats.rx_dropped) }, { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, { "multicast", E1000_STAT(net_stats.multicast) }, { "collisions", E1000_STAT(net_stats.collisions) }, @@ -54,6 +68,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, + { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) }, { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, @@ -82,7 +97,14 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) }, }; +#ifdef CONFIG_E1000_MQ +#define E1000_QUEUE_STATS_LEN \ + (((struct e1000_adapter *)netdev->priv)->num_tx_queues + \ + ((struct e1000_adapter *)netdev->priv)->num_rx_queues) \ + * (sizeof(struct e1000_queue_stats) / sizeof(uint64_t)) +#else #define E1000_QUEUE_STATS_LEN 0 +#endif #define E1000_GLOBAL_STATS_LEN \ sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats) #define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN + E1000_QUEUE_STATS_LEN) @@ -324,9 +346,6 @@ e1000_set_tso(struct net_device *netdev, uint32_t data) netdev->features |= NETIF_F_TSO; else netdev->features &= ~NETIF_F_TSO; - - DPRINTK(PROBE, INFO, "TSO is %s\n", data ? "Enabled" : "Disabled"); - adapter->tso_force = TRUE; return 0; } #endif /* NETIF_F_TSO */ @@ -575,7 +594,6 @@ e1000_get_drvinfo(struct net_device *netdev, case e1000_82571: case e1000_82572: case e1000_82573: - case e1000_80003es2lan: sprintf(firmware_version, "%d.%d-%d", (eeprom_data & 0xF000) >> 12, (eeprom_data & 0x0FF0) >> 4, @@ -624,9 +642,6 @@ e1000_set_ringparam(struct net_device *netdev, struct e1000_rx_ring *rxdr, *rx_old, *rx_new; int i, err, tx_ring_size, rx_ring_size; - if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) - return -EINVAL; - tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues; rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues; @@ -654,6 +669,9 @@ e1000_set_ringparam(struct net_device *netdev, txdr = adapter->tx_ring; rxdr = adapter->rx_ring; + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + return -EINVAL; + rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD); rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ? E1000_MAX_RXD : E1000_MAX_82544_RXD)); @@ -749,7 +767,6 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) /* there are several bits on newer hardware that are r/w */ case e1000_82571: case e1000_82572: - case e1000_80003es2lan: toggle = 0x7FFFF3FF; break; case e1000_82573: @@ -870,16 +887,13 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) *data = 0; /* Hook up test interrupt handler just for this test */ - if (!request_irq(irq, &e1000_test_intr, SA_PROBEIRQ, netdev->name, - netdev)) { + if (!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { shared_int = FALSE; } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)){ *data = 1; return -1; } - DPRINTK(PROBE,INFO, "testing %s interrupt\n", - (shared_int ? "shared" : "unshared")); /* Disable all the interrupts */ E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); @@ -1242,10 +1256,6 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter) e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140); /* autoneg off */ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140); - } else if (adapter->hw.phy_type == e1000_phy_gg82563) { - e1000_write_phy_reg(&adapter->hw, - GG82563_PHY_KMRN_MODE_CTRL, - 0x1CE); } /* force 1000, set loopback */ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140); @@ -1315,7 +1325,6 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter) case e1000_82571: case e1000_82572: case e1000_82573: - case e1000_80003es2lan: return e1000_integrated_phy_loopback(adapter); break; @@ -1396,11 +1405,6 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter) case e1000_82546_rev_3: default: hw->autoneg = TRUE; - if (hw->phy_type == e1000_phy_gg82563) { - e1000_write_phy_reg(hw, - GG82563_PHY_KMRN_MODE_CTRL, - 0x180); - } e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg); if (phy_reg & MII_CR_LOOPBACK) { phy_reg &= ~MII_CR_LOOPBACK; @@ -1636,26 +1640,10 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) case E1000_DEV_ID_82546EB_QUAD_COPPER: case E1000_DEV_ID_82545EM_FIBER: case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82546GB_QUAD_COPPER: wol->supported = 0; wol->wolopts = 0; return; - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - /* device id 10B5 port-A supports wol */ - if (!adapter->ksp3_port_a) { - wol->supported = 0; - return; - } - /* KSP3 does not suppport UCAST wake-ups for any interface */ - wol->supported = WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; - - if (adapter->wol & E1000_WUFC_EX) - DPRINTK(DRV, ERR, "Interface does not support " - "directed (unicast) frame wake-up packets\n"); - wol->wolopts = 0; - goto do_defaults; - case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546GB_FIBER: case E1000_DEV_ID_82571EB_FIBER: @@ -1670,9 +1658,8 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) default: wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; - wol->wolopts = 0; -do_defaults: + wol->wolopts = 0; if (adapter->wol & E1000_WUFC_EX) wol->wolopts |= WAKE_UCAST; if (adapter->wol & E1000_WUFC_MC) @@ -1697,22 +1684,10 @@ e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) case E1000_DEV_ID_82543GC_COPPER: case E1000_DEV_ID_82544EI_FIBER: case E1000_DEV_ID_82546EB_QUAD_COPPER: - case E1000_DEV_ID_82546GB_QUAD_COPPER: case E1000_DEV_ID_82545EM_FIBER: case E1000_DEV_ID_82545EM_COPPER: return wol->wolopts ? -EOPNOTSUPP : 0; - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - /* device id 10B5 port-A supports wol */ - if (!adapter->ksp3_port_a) - return wol->wolopts ? -EOPNOTSUPP : 0; - - if (wol->wolopts & WAKE_UCAST) { - DPRINTK(DRV, ERR, "Interface does not support " - "directed (unicast) frame wake-up packets\n"); - return -EOPNOTSUPP; - } - case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546GB_FIBER: case E1000_DEV_ID_82571EB_FIBER: @@ -1824,6 +1799,11 @@ e1000_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, uint64_t *data) { struct e1000_adapter *adapter = netdev_priv(netdev); +#ifdef CONFIG_E1000_MQ + uint64_t *queue_stat; + int stat_count = sizeof(struct e1000_queue_stats) / sizeof(uint64_t); + int j, k; +#endif int i; e1000_update_stats(adapter); @@ -1832,12 +1812,29 @@ e1000_get_ethtool_stats(struct net_device *netdev, data[i] = (e1000_gstrings_stats[i].sizeof_stat == sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p; } +#ifdef CONFIG_E1000_MQ + for (j = 0; j < adapter->num_tx_queues; j++) { + queue_stat = (uint64_t *)&adapter->tx_ring[j].tx_stats; + for (k = 0; k < stat_count; k++) + data[i + k] = queue_stat[k]; + i += k; + } + for (j = 0; j < adapter->num_rx_queues; j++) { + queue_stat = (uint64_t *)&adapter->rx_ring[j].rx_stats; + for (k = 0; k < stat_count; k++) + data[i + k] = queue_stat[k]; + i += k; + } +#endif /* BUG_ON(i != E1000_STATS_LEN); */ } static void e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) { +#ifdef CONFIG_E1000_MQ + struct e1000_adapter *adapter = netdev_priv(netdev); +#endif uint8_t *p = data; int i; @@ -1852,6 +1849,20 @@ e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) ETH_GSTRING_LEN); p += ETH_GSTRING_LEN; } +#ifdef CONFIG_E1000_MQ + for (i = 0; i < adapter->num_tx_queues; i++) { + sprintf(p, "tx_queue_%u_packets", i); + p += ETH_GSTRING_LEN; + sprintf(p, "tx_queue_%u_bytes", i); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < adapter->num_rx_queues; i++) { + sprintf(p, "rx_queue_%u_packets", i); + p += ETH_GSTRING_LEN; + sprintf(p, "rx_queue_%u_bytes", i); + p += ETH_GSTRING_LEN; + } +#endif /* BUG_ON(p - data != E1000_STATS_LEN * ETH_GSTRING_LEN); */ break; } diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index c5e702349..beeec0fbb 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -100,8 +100,6 @@ static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, #define E1000_WRITE_REG_IO(a, reg, val) \ e1000_write_reg_io((a), E1000_##reg, val) -static int32_t e1000_configure_kmrn_for_10_100(struct e1000_hw *hw); -static int32_t e1000_configure_kmrn_for_1000(struct e1000_hw *hw); /* IGP cable length table */ static const @@ -155,11 +153,6 @@ e1000_set_phy_type(struct e1000_hw *hw) hw->phy_type = e1000_phy_igp; break; } - case GG82563_E_PHY_ID: - if (hw->mac_type == e1000_80003es2lan) { - hw->phy_type = e1000_phy_gg82563; - break; - } /* Fall Through */ default: /* Should never have loaded on this device */ @@ -353,7 +346,6 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82572EI_COPPER: case E1000_DEV_ID_82572EI_FIBER: case E1000_DEV_ID_82572EI_SERDES: - case E1000_DEV_ID_82572EI: hw->mac_type = e1000_82572; break; case E1000_DEV_ID_82573E: @@ -361,19 +353,12 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82573L: hw->mac_type = e1000_82573; break; - case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: - hw->mac_type = e1000_80003es2lan; - break; default: /* Should never have loaded on this device */ return -E1000_ERR_MAC_TYPE; } switch(hw->mac_type) { - case e1000_80003es2lan: - hw->swfw_sync_present = TRUE; - /* fall through */ case e1000_82571: case e1000_82572: case e1000_82573: @@ -414,7 +399,6 @@ e1000_set_media_type(struct e1000_hw *hw) case E1000_DEV_ID_82546GB_SERDES: case E1000_DEV_ID_82571EB_SERDES: case E1000_DEV_ID_82572EI_SERDES: - case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: hw->media_type = e1000_media_type_internal_serdes; break; default: @@ -591,7 +575,6 @@ e1000_reset_hw(struct e1000_hw *hw) /* fall through */ case e1000_82571: case e1000_82572: - case e1000_80003es2lan: ret_val = e1000_get_auto_rd_done(hw); if(ret_val) /* We don't want to continue accessing MAC registers. */ @@ -658,7 +641,6 @@ e1000_init_hw(struct e1000_hw *hw) uint16_t cmd_mmrbc; uint16_t stat_mmrbc; uint32_t mta_size; - uint32_t reg_data; uint32_t ctrl_ext; DEBUGFUNC("e1000_init_hw"); @@ -757,7 +739,6 @@ e1000_init_hw(struct e1000_hw *hw) case e1000_82571: case e1000_82572: case e1000_82573: - case e1000_80003es2lan: ctrl |= E1000_TXDCTL_COUNT_DESC; break; } @@ -771,34 +752,12 @@ e1000_init_hw(struct e1000_hw *hw) switch (hw->mac_type) { default: break; - case e1000_80003es2lan: - /* Enable retransmit on late collisions */ - reg_data = E1000_READ_REG(hw, TCTL); - reg_data |= E1000_TCTL_RTLC; - E1000_WRITE_REG(hw, TCTL, reg_data); - - /* Configure Gigabit Carry Extend Padding */ - reg_data = E1000_READ_REG(hw, TCTL_EXT); - reg_data &= ~E1000_TCTL_EXT_GCEX_MASK; - reg_data |= DEFAULT_80003ES2LAN_TCTL_EXT_GCEX; - E1000_WRITE_REG(hw, TCTL_EXT, reg_data); - - /* Configure Transmit Inter-Packet Gap */ - reg_data = E1000_READ_REG(hw, TIPG); - reg_data &= ~E1000_TIPG_IPGT_MASK; - reg_data |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000; - E1000_WRITE_REG(hw, TIPG, reg_data); - - reg_data = E1000_READ_REG_ARRAY(hw, FFLT, 0x0001); - reg_data &= ~0x00100000; - E1000_WRITE_REG_ARRAY(hw, FFLT, 0x0001, reg_data); - /* Fall through */ case e1000_82571: case e1000_82572: ctrl = E1000_READ_REG(hw, TXDCTL1); - ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; - if(hw->mac_type >= e1000_82571) - ctrl |= E1000_TXDCTL_COUNT_DESC; + ctrl &= ~E1000_TXDCTL_WTHRESH; + ctrl |= E1000_TXDCTL_COUNT_DESC | E1000_TXDCTL_FULL_TX_DESC_WB; + ctrl |= (1 << 22); E1000_WRITE_REG(hw, TXDCTL1, ctrl); break; } @@ -947,13 +906,7 @@ e1000_setup_link(struct e1000_hw *hw) * signal detection. So this should be done before e1000_setup_pcs_link() * or e1000_phy_setup() is called. */ - if (hw->mac_type == e1000_82543) { - ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, - 1, &eeprom_data); - if (ret_val) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; - } + if(hw->mac_type == e1000_82543) { ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) << SWDPIO__EXT_SHIFT); E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); @@ -1355,154 +1308,6 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw) return E1000_SUCCESS; } -/******************************************************************** -* Copper link setup for e1000_phy_gg82563 series. -* -* hw - Struct containing variables accessed by shared code -*********************************************************************/ -static int32_t -e1000_copper_link_ggp_setup(struct e1000_hw *hw) -{ - int32_t ret_val; - uint16_t phy_data; - uint32_t reg_data; - - DEBUGFUNC("e1000_copper_link_ggp_setup"); - - if(!hw->phy_reset_disable) { - - /* Enable CRS on TX for half-duplex operation. */ - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, - &phy_data); - if(ret_val) - return ret_val; - - phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; - /* Use 25MHz for both link down and 1000BASE-T for Tx clock */ - phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ; - - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, - phy_data); - if(ret_val) - return ret_val; - - /* Options: - * MDI/MDI-X = 0 (default) - * 0 - Auto for all speeds - * 1 - MDI mode - * 2 - MDI-X mode - * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) - */ - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL, &phy_data); - if(ret_val) - return ret_val; - - phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; - - switch (hw->mdix) { - case 1: - phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI; - break; - case 2: - phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; - break; - case 0: - default: - phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; - break; - } - - /* Options: - * disable_polarity_correction = 0 (default) - * Automatic Correction for Reversed Cable Polarity - * 0 - Disabled - * 1 - Enabled - */ - phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - if(hw->disable_polarity_correction == 1) - phy_data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); - - if(ret_val) - return ret_val; - - /* SW Reset the PHY so all changes take effect */ - ret_val = e1000_phy_reset(hw); - if (ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } - } /* phy_reset_disable */ - - if (hw->mac_type == e1000_80003es2lan) { - /* Bypass RX and TX FIFO's */ - ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL, - E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS | - E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS); - if (ret_val) - return ret_val; - - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, phy_data); - - if (ret_val) - return ret_val; - - reg_data = E1000_READ_REG(hw, CTRL_EXT); - reg_data &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); - E1000_WRITE_REG(hw, CTRL_EXT, reg_data); - - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, - &phy_data); - if (ret_val) - return ret_val; - - /* Do not init these registers when the HW is in IAMT mode, since the - * firmware will have already initialized them. We only initialize - * them if the HW is not in IAMT mode. - */ - if (e1000_check_mng_mode(hw) == FALSE) { - /* Enable Electrical Idle on the PHY */ - phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, - phy_data); - if (ret_val) - return ret_val; - - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - &phy_data); - if (ret_val) - return ret_val; - - /* Enable Pass False Carrier on the PHY */ - phy_data |= GG82563_KMCR_PASS_FALSE_CARRIER; - - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - phy_data); - if (ret_val) - return ret_val; - } - - /* Workaround: Disable padding in Kumeran interface in the MAC - * and in the PHY to avoid CRC errors. - */ - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_INBAND_CTRL, - &phy_data); - if (ret_val) - return ret_val; - phy_data |= GG82563_ICR_DIS_PADDING; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_INBAND_CTRL, - phy_data); - if (ret_val) - return ret_val; - } - - return E1000_SUCCESS; -} /******************************************************************** * Copper link setup for e1000_phy_m88 series. @@ -1713,7 +1518,6 @@ e1000_setup_copper_link(struct e1000_hw *hw) int32_t ret_val; uint16_t i; uint16_t phy_data; - uint16_t reg_data; DEBUGFUNC("e1000_setup_copper_link"); @@ -1722,22 +1526,6 @@ e1000_setup_copper_link(struct e1000_hw *hw) if(ret_val) return ret_val; - switch (hw->mac_type) { - case e1000_80003es2lan: - ret_val = e1000_read_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_INB_CTRL, - ®_data); - if (ret_val) - return ret_val; - reg_data |= E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING; - ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_INB_CTRL, - reg_data); - if (ret_val) - return ret_val; - break; - default: - break; - } - if (hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) { ret_val = e1000_copper_link_igp_setup(hw); @@ -1747,10 +1535,6 @@ e1000_setup_copper_link(struct e1000_hw *hw) ret_val = e1000_copper_link_mgp_setup(hw); if(ret_val) return ret_val; - } else if (hw->phy_type == e1000_phy_gg82563) { - ret_val = e1000_copper_link_ggp_setup(hw); - if(ret_val) - return ret_val; } if(hw->autoneg) { @@ -1797,59 +1581,6 @@ e1000_setup_copper_link(struct e1000_hw *hw) return E1000_SUCCESS; } -/****************************************************************************** -* Configure the MAC-to-PHY interface for 10/100Mbps -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -static int32_t -e1000_configure_kmrn_for_10_100(struct e1000_hw *hw) -{ - int32_t ret_val = E1000_SUCCESS; - uint32_t tipg; - uint16_t reg_data; - - DEBUGFUNC("e1000_configure_kmrn_for_10_100"); - - reg_data = E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT; - ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_HD_CTRL, - reg_data); - if (ret_val) - return ret_val; - - /* Configure Transmit Inter-Packet Gap */ - tipg = E1000_READ_REG(hw, TIPG); - tipg &= ~E1000_TIPG_IPGT_MASK; - tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100; - E1000_WRITE_REG(hw, TIPG, tipg); - - return ret_val; -} - -static int32_t -e1000_configure_kmrn_for_1000(struct e1000_hw *hw) -{ - int32_t ret_val = E1000_SUCCESS; - uint16_t reg_data; - uint32_t tipg; - - DEBUGFUNC("e1000_configure_kmrn_for_1000"); - - reg_data = E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT; - ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_HD_CTRL, - reg_data); - if (ret_val) - return ret_val; - - /* Configure Transmit Inter-Packet Gap */ - tipg = E1000_READ_REG(hw, TIPG); - tipg &= ~E1000_TIPG_IPGT_MASK; - tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000; - E1000_WRITE_REG(hw, TIPG, tipg); - - return ret_val; -} - /****************************************************************************** * Configures PHY autoneg and flow control advertisement settings * @@ -2071,8 +1802,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) /* Write the configured values back to the Device Control Reg. */ E1000_WRITE_REG(hw, CTRL, ctrl); - if ((hw->phy_type == e1000_phy_m88) || - (hw->phy_type == e1000_phy_gg82563)) { + if (hw->phy_type == e1000_phy_m88) { ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if(ret_val) return ret_val; @@ -2141,8 +1871,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) msec_delay(100); } if((i == 0) && - ((hw->phy_type == e1000_phy_m88) || - (hw->phy_type == e1000_phy_gg82563))) { + (hw->phy_type == e1000_phy_m88)) { /* We didn't get link. Reset the DSP and wait again for link. */ ret_val = e1000_phy_reset_dsp(hw); if(ret_val) { @@ -2201,27 +1930,6 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) if(ret_val) return ret_val; } - } else if (hw->phy_type == e1000_phy_gg82563) { - /* The TX_CLK of the Extended PHY Specific Control Register defaults - * to 2.5MHz on a reset. We need to re-force it back to 25MHz, if - * we're not in a forced 10/duplex configuration. */ - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~GG82563_MSCR_TX_CLK_MASK; - if ((hw->forced_speed_duplex == e1000_10_full) || - (hw->forced_speed_duplex == e1000_10_half)) - phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ; - else - phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25MHZ; - - /* Also due to the reset, we need to enable CRS on Tx. */ - phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; - - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data); - if (ret_val) - return ret_val; } return E1000_SUCCESS; } @@ -2884,16 +2592,6 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw, } } - if ((hw->mac_type == e1000_80003es2lan) && - (hw->media_type == e1000_media_type_copper)) { - if (*speed == SPEED_1000) - ret_val = e1000_configure_kmrn_for_1000(hw); - else - ret_val = e1000_configure_kmrn_for_10_100(hw); - if (ret_val) - return ret_val; - } - return E1000_SUCCESS; } @@ -3069,72 +2767,6 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw) return data; } -int32_t -e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) -{ - uint32_t swfw_sync = 0; - uint32_t swmask = mask; - uint32_t fwmask = mask << 16; - int32_t timeout = 200; - - DEBUGFUNC("e1000_swfw_sync_acquire"); - - if (!hw->swfw_sync_present) - return e1000_get_hw_eeprom_semaphore(hw); - - while(timeout) { - if (e1000_get_hw_eeprom_semaphore(hw)) - return -E1000_ERR_SWFW_SYNC; - - swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC); - if (!(swfw_sync & (fwmask | swmask))) { - break; - } - - /* firmware currently using resource (fwmask) */ - /* or other software thread currently using resource (swmask) */ - e1000_put_hw_eeprom_semaphore(hw); - msec_delay_irq(5); - timeout--; - } - - if (!timeout) { - DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); - return -E1000_ERR_SWFW_SYNC; - } - - swfw_sync |= swmask; - E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync); - - e1000_put_hw_eeprom_semaphore(hw); - return E1000_SUCCESS; -} - -void -e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask) -{ - uint32_t swfw_sync; - uint32_t swmask = mask; - - DEBUGFUNC("e1000_swfw_sync_release"); - - if (!hw->swfw_sync_present) { - e1000_put_hw_eeprom_semaphore(hw); - return; - } - - /* if (e1000_get_hw_eeprom_semaphore(hw)) - * return -E1000_ERR_SWFW_SYNC; */ - while (e1000_get_hw_eeprom_semaphore(hw) != E1000_SUCCESS); - /* empty */ - - swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC); - swfw_sync &= ~swmask; - E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync); - - e1000_put_hw_eeprom_semaphore(hw); -} - /***************************************************************************** * Reads the value from a PHY register, if the value is on a specific non zero * page, sets the page first. @@ -3147,55 +2779,22 @@ e1000_read_phy_reg(struct e1000_hw *hw, uint16_t *phy_data) { uint32_t ret_val; - uint16_t swfw; DEBUGFUNC("e1000_read_phy_reg"); - if ((hw->mac_type == e1000_80003es2lan) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { - swfw = E1000_SWFW_PHY1_SM; - } else { - swfw = E1000_SWFW_PHY0_SM; - } - if (e1000_swfw_sync_acquire(hw, swfw)) - return -E1000_ERR_SWFW_SYNC; - if((hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, (uint16_t)reg_addr); if(ret_val) { - e1000_swfw_sync_release(hw, swfw); return ret_val; } - } else if (hw->phy_type == e1000_phy_gg82563) { - if (((reg_addr & MAX_PHY_REG_ADDRESS) > MAX_PHY_MULTI_PAGE_REG) || - (hw->mac_type == e1000_80003es2lan)) { - /* Select Configuration Page */ - if ((reg_addr & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { - ret_val = e1000_write_phy_reg_ex(hw, GG82563_PHY_PAGE_SELECT, - (uint16_t)((uint16_t)reg_addr >> GG82563_PAGE_SHIFT)); - } else { - /* Use Alternative Page Select register to access - * registers 30 and 31 - */ - ret_val = e1000_write_phy_reg_ex(hw, - GG82563_PHY_PAGE_SELECT_ALT, - (uint16_t)((uint16_t)reg_addr >> GG82563_PAGE_SHIFT)); - } - - if (ret_val) { - e1000_swfw_sync_release(hw, swfw); - return ret_val; - } - } } ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, phy_data); - e1000_swfw_sync_release(hw, swfw); return ret_val; } @@ -3286,55 +2885,22 @@ e1000_write_phy_reg(struct e1000_hw *hw, uint16_t phy_data) { uint32_t ret_val; - uint16_t swfw; DEBUGFUNC("e1000_write_phy_reg"); - if ((hw->mac_type == e1000_80003es2lan) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { - swfw = E1000_SWFW_PHY1_SM; - } else { - swfw = E1000_SWFW_PHY0_SM; - } - if (e1000_swfw_sync_acquire(hw, swfw)) - return -E1000_ERR_SWFW_SYNC; - if((hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, (uint16_t)reg_addr); if(ret_val) { - e1000_swfw_sync_release(hw, swfw); return ret_val; } - } else if (hw->phy_type == e1000_phy_gg82563) { - if (((reg_addr & MAX_PHY_REG_ADDRESS) > MAX_PHY_MULTI_PAGE_REG) || - (hw->mac_type == e1000_80003es2lan)) { - /* Select Configuration Page */ - if ((reg_addr & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { - ret_val = e1000_write_phy_reg_ex(hw, GG82563_PHY_PAGE_SELECT, - (uint16_t)((uint16_t)reg_addr >> GG82563_PAGE_SHIFT)); - } else { - /* Use Alternative Page Select register to access - * registers 30 and 31 - */ - ret_val = e1000_write_phy_reg_ex(hw, - GG82563_PHY_PAGE_SELECT_ALT, - (uint16_t)((uint16_t)reg_addr >> GG82563_PAGE_SHIFT)); - } - - if (ret_val) { - e1000_swfw_sync_release(hw, swfw); - return ret_val; - } - } } ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, phy_data); - e1000_swfw_sync_release(hw, swfw); return ret_val; } @@ -3401,65 +2967,6 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, return E1000_SUCCESS; } -int32_t -e1000_read_kmrn_reg(struct e1000_hw *hw, - uint32_t reg_addr, - uint16_t *data) -{ - uint32_t reg_val; - uint16_t swfw; - DEBUGFUNC("e1000_read_kmrn_reg"); - - if ((hw->mac_type == e1000_80003es2lan) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { - swfw = E1000_SWFW_PHY1_SM; - } else { - swfw = E1000_SWFW_PHY0_SM; - } - if (e1000_swfw_sync_acquire(hw, swfw)) - return -E1000_ERR_SWFW_SYNC; - - /* Write register address */ - reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) & - E1000_KUMCTRLSTA_OFFSET) | - E1000_KUMCTRLSTA_REN; - E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val); - udelay(2); - - /* Read the data returned */ - reg_val = E1000_READ_REG(hw, KUMCTRLSTA); - *data = (uint16_t)reg_val; - - e1000_swfw_sync_release(hw, swfw); - return E1000_SUCCESS; -} - -int32_t -e1000_write_kmrn_reg(struct e1000_hw *hw, - uint32_t reg_addr, - uint16_t data) -{ - uint32_t reg_val; - uint16_t swfw; - DEBUGFUNC("e1000_write_kmrn_reg"); - - if ((hw->mac_type == e1000_80003es2lan) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { - swfw = E1000_SWFW_PHY1_SM; - } else { - swfw = E1000_SWFW_PHY0_SM; - } - if (e1000_swfw_sync_acquire(hw, swfw)) - return -E1000_ERR_SWFW_SYNC; - - reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) & - E1000_KUMCTRLSTA_OFFSET) | data; - E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val); - udelay(2); - - e1000_swfw_sync_release(hw, swfw); - return E1000_SUCCESS; -} /****************************************************************************** * Returns the PHY to the power-on reset state @@ -3472,7 +2979,6 @@ e1000_phy_hw_reset(struct e1000_hw *hw) uint32_t ctrl, ctrl_ext; uint32_t led_ctrl; int32_t ret_val; - uint16_t swfw; DEBUGFUNC("e1000_phy_hw_reset"); @@ -3485,21 +2991,11 @@ e1000_phy_hw_reset(struct e1000_hw *hw) DEBUGOUT("Resetting Phy...\n"); if(hw->mac_type > e1000_82543) { - if ((hw->mac_type == e1000_80003es2lan) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { - swfw = E1000_SWFW_PHY1_SM; - } else { - swfw = E1000_SWFW_PHY0_SM; - } - if (e1000_swfw_sync_acquire(hw, swfw)) { - e1000_release_software_semaphore(hw); - return -E1000_ERR_SWFW_SYNC; - } /* Read the device control register and assert the E1000_CTRL_PHY_RST * bit. Then, take it out of reset. * For pre-e1000_82571 hardware, we delay for 10ms between the assert * and deassert. For e1000_82571 hardware and later, we instead delay - * for 50us between and 10ms after the deassertion. + * for 10ms after the deassertion. */ ctrl = E1000_READ_REG(hw, CTRL); E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); @@ -3515,7 +3011,6 @@ e1000_phy_hw_reset(struct e1000_hw *hw) if (hw->mac_type >= e1000_82571) msec_delay(10); - e1000_swfw_sync_release(hw, swfw); } else { /* Read the Extended Device Control Register, assert the PHY_RESET_DIR * bit to put the PHY into reset. Then, take it out of reset. @@ -3542,7 +3037,6 @@ e1000_phy_hw_reset(struct e1000_hw *hw) /* Wait for FW to finish PHY configuration. */ ret_val = e1000_get_phy_cfg_done(hw); - e1000_release_software_semaphore(hw); return ret_val; } @@ -3620,15 +3114,6 @@ e1000_detect_gig_phy(struct e1000_hw *hw) return E1000_SUCCESS; } - /* ESB-2 PHY reads require e1000_phy_gg82563 to be set because of a work- - * around that forces PHY page 0 to be set or the reads fail. The rest of - * the code in this routine uses e1000_read_phy_reg to read the PHY ID. - * So for ESB-2 we need to have this set so our reads won't fail. If the - * attached PHY is not a e1000_phy_gg82563, the routines below will figure - * this out as well. */ - if (hw->mac_type == e1000_80003es2lan) - hw->phy_type = e1000_phy_gg82563; - /* Read the PHY ID Registers to identify which PHY is onboard. */ ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high); if(ret_val) @@ -3666,9 +3151,6 @@ e1000_detect_gig_phy(struct e1000_hw *hw) case e1000_82573: if(hw->phy_id == M88E1111_I_PHY_ID) match = TRUE; break; - case e1000_80003es2lan: - if (hw->phy_id == GG82563_E_PHY_ID) match = TRUE; - break; default: DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type); return -E1000_ERR_CONFIG; @@ -3695,10 +3177,8 @@ e1000_phy_reset_dsp(struct e1000_hw *hw) DEBUGFUNC("e1000_phy_reset_dsp"); do { - if (hw->phy_type != e1000_phy_gg82563) { - ret_val = e1000_write_phy_reg(hw, 29, 0x001d); - if(ret_val) break; - } + ret_val = e1000_write_phy_reg(hw, 29, 0x001d); + if(ret_val) break; ret_val = e1000_write_phy_reg(hw, 30, 0x00c1); if(ret_val) break; ret_val = e1000_write_phy_reg(hw, 30, 0x0000); @@ -3830,17 +3310,8 @@ e1000_phy_m88_get_info(struct e1000_hw *hw, /* Cable Length Estimation and Local/Remote Receiver Information * are only valid at 1000 Mbps. */ - if (hw->phy_type != e1000_phy_gg82563) { - phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> - M88E1000_PSSR_CABLE_LENGTH_SHIFT); - } else { - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE, - &phy_data); - if (ret_val) - return ret_val; - - phy_info->cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH; - } + phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> + M88E1000_PSSR_CABLE_LENGTH_SHIFT); ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); if(ret_val) @@ -3921,8 +3392,7 @@ e1000_validate_mdi_setting(struct e1000_hw *hw) /****************************************************************************** * Sets up eeprom variables in the hw struct. Must be called after mac_type - * is configured. Additionally, if this is ICH8, the flash controller GbE - * registers must be mapped, or this will crash. + * is configured. * * hw - Struct containing variables accessed by shared code *****************************************************************************/ @@ -4035,20 +3505,6 @@ e1000_init_eeprom_params(struct e1000_hw *hw) E1000_WRITE_REG(hw, EECD, eecd); } break; - case e1000_80003es2lan: - eeprom->type = e1000_eeprom_spi; - eeprom->opcode_bits = 8; - eeprom->delay_usec = 1; - if (eecd & E1000_EECD_ADDR_BITS) { - eeprom->page_size = 32; - eeprom->address_bits = 16; - } else { - eeprom->page_size = 8; - eeprom->address_bits = 8; - } - eeprom->use_eerd = TRUE; - eeprom->use_eewr = FALSE; - break; default: break; } @@ -4229,8 +3685,9 @@ e1000_acquire_eeprom(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_eeprom"); - if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM)) - return -E1000_ERR_SWFW_SYNC; + if(e1000_get_hw_eeprom_semaphore(hw)) + return -E1000_ERR_EEPROM; + eecd = E1000_READ_REG(hw, EECD); if (hw->mac_type != e1000_82573) { @@ -4249,7 +3706,7 @@ e1000_acquire_eeprom(struct e1000_hw *hw) eecd &= ~E1000_EECD_REQ; E1000_WRITE_REG(hw, EECD, eecd); DEBUGOUT("Could not acquire EEPROM grant\n"); - e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM); + e1000_put_hw_eeprom_semaphore(hw); return -E1000_ERR_EEPROM; } } @@ -4372,7 +3829,7 @@ e1000_release_eeprom(struct e1000_hw *hw) E1000_WRITE_REG(hw, EECD, eecd); } - e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM); + e1000_put_hw_eeprom_semaphore(hw); } /****************************************************************************** @@ -4451,8 +3908,6 @@ e1000_read_eeprom(struct e1000_hw *hw, if (e1000_is_onboard_nvm_eeprom(hw) == TRUE && hw->eeprom.use_eerd == FALSE) { switch (hw->mac_type) { - case e1000_80003es2lan: - break; default: /* Prepare the EEPROM for reading */ if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) @@ -4570,9 +4025,6 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw, uint32_t i = 0; int32_t error = 0; - if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM)) - return -E1000_ERR_SWFW_SYNC; - for (i = 0; i < words; i++) { register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) | ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) | @@ -4592,7 +4044,6 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw, } } - e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM); return error; } @@ -4634,8 +4085,6 @@ e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw) { uint32_t eecd = 0; - DEBUGFUNC("e1000_is_onboard_nvm_eeprom"); - if(hw->mac_type == e1000_82573) { eecd = E1000_READ_REG(hw, EECD); @@ -5062,7 +4511,6 @@ e1000_read_mac_addr(struct e1000_hw * hw) case e1000_82546: case e1000_82546_rev_3: case e1000_82571: - case e1000_80003es2lan: if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) hw->perm_mac_addr[5] ^= 0x01; break; @@ -5301,37 +4749,8 @@ e1000_rar_set(struct e1000_hw *hw, rar_low = ((uint32_t) addr[0] | ((uint32_t) addr[1] << 8) | ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24)); - rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8)); - /* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx - * unit hang. - * - * Description: - * If there are any Rx frames queued up or otherwise present in the HW - * before RSS is enabled, and then we enable RSS, the HW Rx unit will - * hang. To work around this issue, we have to disable receives and - * flush out all Rx frames before we enable RSS. To do so, we modify we - * redirect all Rx traffic to manageability and then reset the HW. - * This flushes away Rx frames, and (since the redirections to - * manageability persists across resets) keeps new ones from coming in - * while we work. Then, we clear the Address Valid AV bit for all MAC - * addresses and undo the re-direction to manageability. - * Now, frames are coming in again, but the MAC won't accept them, so - * far so good. We now proceed to initialize RSS (if necessary) and - * configure the Rx unit. Last, we re-enable the AV bits and continue - * on our merry way. - */ - switch (hw->mac_type) { - case e1000_82571: - case e1000_82572: - case e1000_80003es2lan: - if (hw->leave_av_bit_off == TRUE) - break; - default: - /* Indicate to hardware the Address is Valid. */ - rar_high |= E1000_RAH_AV; - break; - } + rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8) | E1000_RAH_AV); E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low); E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high); @@ -5911,7 +5330,6 @@ e1000_get_bus_info(struct e1000_hw *hw) hw->bus_width = e1000_bus_width_pciex_1; break; case e1000_82571: - case e1000_80003es2lan: hw->bus_type = e1000_bus_type_pci_express; hw->bus_speed = e1000_bus_speed_2500; hw->bus_width = e1000_bus_width_pciex_4; @@ -6057,34 +5475,6 @@ e1000_get_cable_length(struct e1000_hw *hw, return -E1000_ERR_PHY; break; } - } else if (hw->phy_type == e1000_phy_gg82563) { - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE, - &phy_data); - if (ret_val) - return ret_val; - cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH; - - switch (cable_length) { - case e1000_gg_cable_length_60: - *min_length = 0; - *max_length = e1000_igp_cable_length_60; - break; - case e1000_gg_cable_length_60_115: - *min_length = e1000_igp_cable_length_60; - *max_length = e1000_igp_cable_length_115; - break; - case e1000_gg_cable_length_115_150: - *min_length = e1000_igp_cable_length_115; - *max_length = e1000_igp_cable_length_150; - break; - case e1000_gg_cable_length_150: - *min_length = e1000_igp_cable_length_150; - *max_length = e1000_igp_cable_length_180; - break; - default: - return -E1000_ERR_PHY; - break; - } } else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */ uint16_t agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {IGP01E1000_PHY_AGC_A, @@ -6194,8 +5584,7 @@ e1000_check_polarity(struct e1000_hw *hw, DEBUGFUNC("e1000_check_polarity"); - if ((hw->phy_type == e1000_phy_m88) || - (hw->phy_type == e1000_phy_gg82563)) { + if(hw->phy_type == e1000_phy_m88) { /* return the Polarity bit in the Status register. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); @@ -6264,8 +5653,7 @@ e1000_check_downshift(struct e1000_hw *hw) return ret_val; hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0; - } else if ((hw->phy_type == e1000_phy_m88) || - (hw->phy_type == e1000_phy_gg82563)) { + } else if(hw->phy_type == e1000_phy_m88) { ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if(ret_val) @@ -7298,7 +6686,6 @@ e1000_get_auto_rd_done(struct e1000_hw *hw) case e1000_82571: case e1000_82572: case e1000_82573: - case e1000_80003es2lan: while(timeout) { if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break; else msec_delay(1); @@ -7342,11 +6729,6 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw) default: msec_delay(10); break; - case e1000_80003es2lan: - /* Separate *_CFG_DONE_* bit for each port */ - if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) - cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1; - /* Fall Through */ case e1000_82571: case e1000_82572: while (timeout) { @@ -7364,6 +6746,12 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw) break; } + /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high. + * Need to wait for PHY configuration completion before accessing NVM + * and PHY. */ + if (hw->mac_type == e1000_82573) + msec_delay(25); + return E1000_SUCCESS; } @@ -7389,11 +6777,6 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) if(!hw->eeprom_semaphore_present) return E1000_SUCCESS; - if (hw->mac_type == e1000_80003es2lan) { - /* Get the SW semaphore. */ - if (e1000_get_software_semaphore(hw) != E1000_SUCCESS) - return -E1000_ERR_EEPROM; - } /* Get the FW semaphore. */ timeout = hw->eeprom.word_size + 1; @@ -7439,75 +6822,10 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) return; swsm = E1000_READ_REG(hw, SWSM); - if (hw->mac_type == e1000_80003es2lan) { - /* Release both semaphores. */ - swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); - } else swsm &= ~(E1000_SWSM_SWESMBI); E1000_WRITE_REG(hw, SWSM, swsm); } -/*************************************************************************** - * - * Obtaining software semaphore bit (SMBI) before resetting PHY. - * - * hw: Struct containing variables accessed by shared code - * - * returns: - E1000_ERR_RESET if fail to obtain semaphore. - * E1000_SUCCESS at any other case. - * - ***************************************************************************/ -int32_t -e1000_get_software_semaphore(struct e1000_hw *hw) -{ - int32_t timeout = hw->eeprom.word_size + 1; - uint32_t swsm; - - DEBUGFUNC("e1000_get_software_semaphore"); - - if (hw->mac_type != e1000_80003es2lan) - return E1000_SUCCESS; - - while(timeout) { - swsm = E1000_READ_REG(hw, SWSM); - /* If SMBI bit cleared, it is now set and we hold the semaphore */ - if(!(swsm & E1000_SWSM_SMBI)) - break; - msec_delay_irq(1); - timeout--; - } - - if(!timeout) { - DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); - return -E1000_ERR_RESET; - } - - return E1000_SUCCESS; -} - -/*************************************************************************** - * - * Release semaphore bit (SMBI). - * - * hw: Struct containing variables accessed by shared code - * - ***************************************************************************/ -void -e1000_release_software_semaphore(struct e1000_hw *hw) -{ - uint32_t swsm; - - DEBUGFUNC("e1000_release_software_semaphore"); - - if (hw->mac_type != e1000_80003es2lan) - return; - - swsm = E1000_READ_REG(hw, SWSM); - /* Release the SW semaphores.*/ - swsm &= ~E1000_SWSM_SMBI; - E1000_WRITE_REG(hw, SWSM, swsm); -} - /****************************************************************************** * Checks if PHY reset is blocked due to SOL/IDER session, for example. * Returning E1000_BLK_PHY_RESET isn't necessarily an error. But it's up to @@ -7544,7 +6862,6 @@ e1000_arc_subsystem_valid(struct e1000_hw *hw) case e1000_82571: case e1000_82572: case e1000_82573: - case e1000_80003es2lan: fwsm = E1000_READ_REG(hw, FWSM); if((fwsm & E1000_FWSM_MODE_MASK) != 0) return TRUE; diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index c01e5d2e5..f1219dd9d 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -60,7 +60,6 @@ typedef enum { e1000_82571, e1000_82572, e1000_82573, - e1000_80003es2lan, e1000_num_macs } e1000_mac_type; @@ -139,13 +138,6 @@ typedef enum { e1000_cable_length_undefined = 0xFF } e1000_cable_length; -typedef enum { - e1000_gg_cable_length_60 = 0, - e1000_gg_cable_length_60_115 = 1, - e1000_gg_cable_length_115_150 = 2, - e1000_gg_cable_length_150 = 4 -} e1000_gg_cable_length; - typedef enum { e1000_igp_cable_length_10 = 10, e1000_igp_cable_length_20 = 20, @@ -216,7 +208,6 @@ typedef enum { e1000_phy_m88 = 0, e1000_phy_igp, e1000_phy_igp_2, - e1000_phy_gg82563, e1000_phy_undefined = 0xFF } e1000_phy_type; @@ -290,7 +281,6 @@ typedef enum { #define E1000_ERR_MASTER_REQUESTS_PENDING 10 #define E1000_ERR_HOST_INTERFACE_COMMAND 11 #define E1000_BLK_PHY_RESET 12 -#define E1000_ERR_SWFW_SYNC 13 /* Function prototypes */ /* Initialization */ @@ -314,8 +304,6 @@ int32_t e1000_phy_hw_reset(struct e1000_hw *hw); int32_t e1000_phy_reset(struct e1000_hw *hw); int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info); int32_t e1000_validate_mdi_setting(struct e1000_hw *hw); -int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data); -int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data); /* EEPROM Functions */ int32_t e1000_init_eeprom_params(struct e1000_hw *hw); @@ -462,13 +450,10 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); #define E1000_DEV_ID_82572EI_COPPER 0x107D #define E1000_DEV_ID_82572EI_FIBER 0x107E #define E1000_DEV_ID_82572EI_SERDES 0x107F -#define E1000_DEV_ID_82572EI 0x10B9 #define E1000_DEV_ID_82573E 0x108B #define E1000_DEV_ID_82573E_IAMT 0x108C #define E1000_DEV_ID_82573L 0x109A #define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 -#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 -#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 #define NODE_ADDRESS_SIZE 6 @@ -865,7 +850,6 @@ struct e1000_ffvt_entry { #define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ #define E1000_RXCW 0x00180 /* RX Configuration Word - RO */ #define E1000_TCTL 0x00400 /* TX Control - RW */ -#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */ #define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */ #define E1000_TBT 0x00448 /* TX Burst Timer - RW */ #define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ @@ -1012,11 +996,6 @@ struct e1000_ffvt_entry { #define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ #define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ -#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */ -#define E1000_MDPHYA 0x0003C /* PHY address - RW */ -#define E1000_MANC2H 0x05860 /* Managment Control To Host - RW */ -#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ - #define E1000_GCR 0x05B00 /* PCI-Ex Control */ #define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ #define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ @@ -1086,7 +1065,6 @@ struct e1000_ffvt_entry { #define E1000_82542_RXCW E1000_RXCW #define E1000_82542_MTA 0x00200 #define E1000_82542_TCTL E1000_TCTL -#define E1000_82542_TCTL_EXT E1000_TCTL_EXT #define E1000_82542_TIPG E1000_TIPG #define E1000_82542_TDBAL 0x00420 #define E1000_82542_TDBAH 0x00424 @@ -1234,8 +1212,6 @@ struct e1000_ffvt_entry { #define E1000_82542_RSSRK E1000_RSSRK #define E1000_82542_RSSIM E1000_RSSIM #define E1000_82542_RSSIR E1000_RSSIR -#define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA -#define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC /* Statistics counters collected by the MAC */ struct e1000_hw_stats { @@ -1327,7 +1303,6 @@ struct e1000_hw { e1000_ffe_config ffe_config_state; uint32_t asf_firmware_present; uint32_t eeprom_semaphore_present; - uint32_t swfw_sync_present; unsigned long io_base; uint32_t phy_id; uint32_t phy_revision; @@ -1386,7 +1361,6 @@ struct e1000_hw { boolean_t ifs_params_forced; boolean_t in_ifs_mode; boolean_t mng_reg_access_disabled; - boolean_t leave_av_bit_off; }; @@ -1419,8 +1393,6 @@ struct e1000_hw { #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ #define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */ #define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */ -#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */ -#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ #define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ @@ -1457,16 +1429,6 @@ struct e1000_hw { #define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ #define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */ #define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */ -#define E1000_STATUS_BMC_SKU_0 0x00100000 /* BMC USB redirect disabled */ -#define E1000_STATUS_BMC_SKU_1 0x00200000 /* BMC SRAM disabled */ -#define E1000_STATUS_BMC_SKU_2 0x00400000 /* BMC SDRAM disabled */ -#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */ -#define E1000_STATUS_BMC_LITE 0x01000000 /* BMC external code execution disabled */ -#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */ -#define E1000_STATUS_FUSE_8 0x04000000 -#define E1000_STATUS_FUSE_9 0x08000000 -#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */ -#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */ /* Constants used to intrepret the masked PCI-X bus speed. */ #define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */ @@ -1544,8 +1506,6 @@ struct e1000_hw { #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000 #define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000 -#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000 -#define E1000_CTRL_EXT_LINK_MODE_SERDES 0x00C00000 #define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000 #define E1000_CTRL_EXT_WR_WMARK_256 0x00000000 #define E1000_CTRL_EXT_WR_WMARK_320 0x01000000 @@ -1555,9 +1515,6 @@ struct e1000_hw { #define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ #define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ #define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ -#define E1000_CRTL_EXT_PB_PAREN 0x01000000 /* packet buffer parity error detection enabled */ -#define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity error detection enable */ -#define E1000_CTRL_EXT_GHOST_PAREN 0x40000000 /* MDI Control */ #define E1000_MDIC_DATA_MASK 0x0000FFFF @@ -1571,32 +1528,6 @@ struct e1000_hw { #define E1000_MDIC_INT_EN 0x20000000 #define E1000_MDIC_ERROR 0x40000000 -#define E1000_KUMCTRLSTA_MASK 0x0000FFFF -#define E1000_KUMCTRLSTA_OFFSET 0x001F0000 -#define E1000_KUMCTRLSTA_OFFSET_SHIFT 16 -#define E1000_KUMCTRLSTA_REN 0x00200000 - -#define E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL 0x00000000 -#define E1000_KUMCTRLSTA_OFFSET_CTRL 0x00000001 -#define E1000_KUMCTRLSTA_OFFSET_INB_CTRL 0x00000002 -#define E1000_KUMCTRLSTA_OFFSET_DIAG 0x00000003 -#define E1000_KUMCTRLSTA_OFFSET_TIMEOUTS 0x00000004 -#define E1000_KUMCTRLSTA_OFFSET_INB_PARAM 0x00000009 -#define E1000_KUMCTRLSTA_OFFSET_HD_CTRL 0x00000010 -#define E1000_KUMCTRLSTA_OFFSET_M2P_SERDES 0x0000001E -#define E1000_KUMCTRLSTA_OFFSET_M2P_MODES 0x0000001F - -/* FIFO Control */ -#define E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS 0x00000008 -#define E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS 0x00000800 - -/* In-Band Control */ -#define E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING 0x00000010 - -/* Half-Duplex Control */ -#define E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004 -#define E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT 0x00000000 - /* LED Control */ #define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F #define E1000_LEDCTL_LED0_MODE_SHIFT 0 @@ -1659,13 +1590,6 @@ struct e1000_hw { #define E1000_ICR_MNG 0x00040000 /* Manageability event */ #define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */ #define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ -#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO parity error */ -#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO parity error */ -#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity error */ -#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */ -#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO parity error */ -#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO parity error */ -#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */ /* Interrupt Cause Set */ #define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1686,12 +1610,6 @@ struct e1000_hw { #define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ #define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */ #define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */ -#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */ -#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */ -#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */ -#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */ -#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */ -#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */ /* Interrupt Mask Set */ #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1712,12 +1630,6 @@ struct e1000_hw { #define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ #define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */ #define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */ -#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */ -#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */ -#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */ -#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */ -#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */ -#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */ /* Interrupt Mask Clear */ #define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1738,12 +1650,6 @@ struct e1000_hw { #define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */ #define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */ #define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */ -#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */ -#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */ -#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */ -#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */ -#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */ -#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */ /* Receive Control */ #define E1000_RCTL_RST 0x00000001 /* Software reset */ @@ -1813,12 +1719,6 @@ struct e1000_hw { #define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */ #define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */ -/* SW_W_SYNC definitions */ -#define E1000_SWFW_EEP_SM 0x0001 -#define E1000_SWFW_PHY0_SM 0x0002 -#define E1000_SWFW_PHY1_SM 0x0004 -#define E1000_SWFW_MAC_CSR_SM 0x0008 - /* Receive Descriptor */ #define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */ #define E1000_RDT_FPDB 0x80000000 /* Flush descriptor block */ @@ -1897,11 +1797,6 @@ struct e1000_hw { #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ #define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ #define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ -/* Extended Transmit Control */ -#define E1000_TCTL_EXT_BST_MASK 0x000003FF /* Backoff Slot Time */ -#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ - -#define DEFAULT_80003ES2LAN_TCTL_EXT_GCEX 0x00010000 /* Receive Checksum Control */ #define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */ @@ -1979,7 +1874,6 @@ struct e1000_hw { #define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ #define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ -#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */ #define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ #define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address * filtering */ @@ -2068,19 +1962,19 @@ struct e1000_host_command_info { /* PCI-Ex registers */ /* PCI-Ex Control Register */ -#define E1000_GCR_RXD_NO_SNOOP 0x00000001 -#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002 -#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004 -#define E1000_GCR_TXD_NO_SNOOP 0x00000008 -#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010 -#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020 - -#define PCI_EX_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \ - E1000_GCR_RXDSCW_NO_SNOOP | \ - E1000_GCR_RXDSCR_NO_SNOOP | \ - E1000_GCR_TXD_NO_SNOOP | \ - E1000_GCR_TXDSCW_NO_SNOOP | \ - E1000_GCR_TXDSCR_NO_SNOOP) +#define E1000_GCR_RXD_NO_SNOOP 0x00000001 +#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002 +#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004 +#define E1000_GCR_TXD_NO_SNOOP 0x00000008 +#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010 +#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020 + +#define PCI_EX_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \ + E1000_GCR_RXDSCW_NO_SNOOP | \ + E1000_GCR_RXDSCR_NO_SNOOP | \ + E1000_GCR TXD_NO_SNOOP | \ + E1000_GCR_TXDSCW_NO_SNOOP | \ + E1000_GCR_TXDSCR_NO_SNOOP) #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 /* Function Active and Power State to MNG */ @@ -2141,14 +2035,12 @@ struct e1000_host_command_info { #define EEPROM_INIT_CONTROL1_REG 0x000A #define EEPROM_INIT_CONTROL2_REG 0x000F #define EEPROM_INIT_CONTROL3_PORT_B 0x0014 -#define EEPROM_INIT_3GIO_3 0x001A #define EEPROM_INIT_CONTROL3_PORT_A 0x0024 #define EEPROM_CFG 0x0012 #define EEPROM_FLASH_VERSION 0x0032 #define EEPROM_CHECKSUM_REG 0x003F #define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */ -#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */ /* Word definitions for ID LED Settings */ #define ID_LED_RESERVED_0000 0x0000 @@ -2192,9 +2084,6 @@ struct e1000_host_command_info { #define EEPROM_WORD0F_ANE 0x0800 #define EEPROM_WORD0F_SWPDIO_EXT 0x00F0 -/* Mask bits for fields in Word 0x1a of the EEPROM */ -#define EEPROM_WORD1A_ASPM_MASK 0x000C - /* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */ #define EEPROM_SUM 0xBABA @@ -2237,11 +2126,8 @@ struct e1000_host_command_info { #define DEFAULT_82542_TIPG_IPGR2 10 #define DEFAULT_82543_TIPG_IPGR2 6 -#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7 #define E1000_TIPG_IPGR2_SHIFT 20 -#define DEFAULT_80003ES2LAN_TIPG_IPGT_10_100 0x00000009 -#define DEFAULT_80003ES2LAN_TIPG_IPGT_1000 0x00000008 #define E1000_TXDMAC_DPP 0x00000001 /* Adaptive IFS defines */ @@ -2482,78 +2368,6 @@ struct e1000_host_command_info { #define IGP01E1000_ANALOG_REGS_PAGE 0x20C0 -/* Bits... - * 15-5: page - * 4-0: register offset - */ -#define GG82563_PAGE_SHIFT 5 -#define GG82563_REG(page, reg) \ - (((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS)) -#define GG82563_MIN_ALT_REG 30 - -/* GG82563 Specific Registers */ -#define GG82563_PHY_SPEC_CTRL \ - GG82563_REG(0, 16) /* PHY Specific Control */ -#define GG82563_PHY_SPEC_STATUS \ - GG82563_REG(0, 17) /* PHY Specific Status */ -#define GG82563_PHY_INT_ENABLE \ - GG82563_REG(0, 18) /* Interrupt Enable */ -#define GG82563_PHY_SPEC_STATUS_2 \ - GG82563_REG(0, 19) /* PHY Specific Status 2 */ -#define GG82563_PHY_RX_ERR_CNTR \ - GG82563_REG(0, 21) /* Receive Error Counter */ -#define GG82563_PHY_PAGE_SELECT \ - GG82563_REG(0, 22) /* Page Select */ -#define GG82563_PHY_SPEC_CTRL_2 \ - GG82563_REG(0, 26) /* PHY Specific Control 2 */ -#define GG82563_PHY_PAGE_SELECT_ALT \ - GG82563_REG(0, 29) /* Alternate Page Select */ -#define GG82563_PHY_TEST_CLK_CTRL \ - GG82563_REG(0, 30) /* Test Clock Control (use reg. 29 to select) */ - -#define GG82563_PHY_MAC_SPEC_CTRL \ - GG82563_REG(2, 21) /* MAC Specific Control Register */ -#define GG82563_PHY_MAC_SPEC_CTRL_2 \ - GG82563_REG(2, 26) /* MAC Specific Control 2 */ - -#define GG82563_PHY_DSP_DISTANCE \ - GG82563_REG(5, 26) /* DSP Distance */ - -/* Page 193 - Port Control Registers */ -#define GG82563_PHY_KMRN_MODE_CTRL \ - GG82563_REG(193, 16) /* Kumeran Mode Control */ -#define GG82563_PHY_PORT_RESET \ - GG82563_REG(193, 17) /* Port Reset */ -#define GG82563_PHY_REVISION_ID \ - GG82563_REG(193, 18) /* Revision ID */ -#define GG82563_PHY_DEVICE_ID \ - GG82563_REG(193, 19) /* Device ID */ -#define GG82563_PHY_PWR_MGMT_CTRL \ - GG82563_REG(193, 20) /* Power Management Control */ -#define GG82563_PHY_RATE_ADAPT_CTRL \ - GG82563_REG(193, 25) /* Rate Adaptation Control */ - -/* Page 194 - KMRN Registers */ -#define GG82563_PHY_KMRN_FIFO_CTRL_STAT \ - GG82563_REG(194, 16) /* FIFO's Control/Status */ -#define GG82563_PHY_KMRN_CTRL \ - GG82563_REG(194, 17) /* Control */ -#define GG82563_PHY_INBAND_CTRL \ - GG82563_REG(194, 18) /* Inband Control */ -#define GG82563_PHY_KMRN_DIAGNOSTIC \ - GG82563_REG(194, 19) /* Diagnostic */ -#define GG82563_PHY_ACK_TIMEOUTS \ - GG82563_REG(194, 20) /* Acknowledge Timeouts */ -#define GG82563_PHY_ADV_ABILITY \ - GG82563_REG(194, 21) /* Advertised Ability */ -#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY \ - GG82563_REG(194, 23) /* Link Partner Advertised Ability */ -#define GG82563_PHY_ADV_NEXT_PAGE \ - GG82563_REG(194, 24) /* Advertised Next Page */ -#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE \ - GG82563_REG(194, 25) /* Link Partner Advertised Next page */ -#define GG82563_PHY_KMRN_MISC \ - GG82563_REG(194, 26) /* Misc. */ /* PHY Control Register */ #define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ @@ -2867,113 +2681,6 @@ struct e1000_host_command_info { #define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080 #define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500 -/* GG82563 PHY Specific Status Register (Page 0, Register 16 */ -#define GG82563_PSCR_DISABLE_JABBER 0x0001 /* 1=Disable Jabber */ -#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Polarity Reversal Disabled */ -#define GG82563_PSCR_POWER_DOWN 0x0004 /* 1=Power Down */ -#define GG82563_PSCR_COPPER_TRANSMITER_DISABLE 0x0008 /* 1=Transmitter Disabled */ -#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060 -#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI configuration */ -#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX configuration */ -#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Automatic crossover */ -#define GG82563_PSCR_ENALBE_EXTENDED_DISTANCE 0x0080 /* 1=Enable Extended Distance */ -#define GG82563_PSCR_ENERGY_DETECT_MASK 0x0300 -#define GG82563_PSCR_ENERGY_DETECT_OFF 0x0000 /* 00,01=Off */ -#define GG82563_PSCR_ENERGY_DETECT_RX 0x0200 /* 10=Sense on Rx only (Energy Detect) */ -#define GG82563_PSCR_ENERGY_DETECT_RX_TM 0x0300 /* 11=Sense and Tx NLP */ -#define GG82563_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force Link Good */ -#define GG82563_PSCR_DOWNSHIFT_ENABLE 0x0800 /* 1=Enable Downshift */ -#define GG82563_PSCR_DOWNSHIFT_COUNTER_MASK 0x7000 -#define GG82563_PSCR_DOWNSHIFT_COUNTER_SHIFT 12 - -/* PHY Specific Status Register (Page 0, Register 17) */ -#define GG82563_PSSR_JABBER 0x0001 /* 1=Jabber */ -#define GG82563_PSSR_POLARITY 0x0002 /* 1=Polarity Reversed */ -#define GG82563_PSSR_LINK 0x0008 /* 1=Link is Up */ -#define GG82563_PSSR_ENERGY_DETECT 0x0010 /* 1=Sleep, 0=Active */ -#define GG82563_PSSR_DOWNSHIFT 0x0020 /* 1=Downshift */ -#define GG82563_PSSR_CROSSOVER_STATUS 0x0040 /* 1=MDIX, 0=MDI */ -#define GG82563_PSSR_RX_PAUSE_ENABLED 0x0100 /* 1=Receive Pause Enabled */ -#define GG82563_PSSR_TX_PAUSE_ENABLED 0x0200 /* 1=Transmit Pause Enabled */ -#define GG82563_PSSR_LINK_UP 0x0400 /* 1=Link Up */ -#define GG82563_PSSR_SPEED_DUPLEX_RESOLVED 0x0800 /* 1=Resolved */ -#define GG82563_PSSR_PAGE_RECEIVED 0x1000 /* 1=Page Received */ -#define GG82563_PSSR_DUPLEX 0x2000 /* 1-Full-Duplex */ -#define GG82563_PSSR_SPEED_MASK 0xC000 -#define GG82563_PSSR_SPEED_10MBPS 0x0000 /* 00=10Mbps */ -#define GG82563_PSSR_SPEED_100MBPS 0x4000 /* 01=100Mbps */ -#define GG82563_PSSR_SPEED_1000MBPS 0x8000 /* 10=1000Mbps */ - -/* PHY Specific Status Register 2 (Page 0, Register 19) */ -#define GG82563_PSSR2_JABBER 0x0001 /* 1=Jabber */ -#define GG82563_PSSR2_POLARITY_CHANGED 0x0002 /* 1=Polarity Changed */ -#define GG82563_PSSR2_ENERGY_DETECT_CHANGED 0x0010 /* 1=Energy Detect Changed */ -#define GG82563_PSSR2_DOWNSHIFT_INTERRUPT 0x0020 /* 1=Downshift Detected */ -#define GG82563_PSSR2_MDI_CROSSOVER_CHANGE 0x0040 /* 1=Crossover Changed */ -#define GG82563_PSSR2_FALSE_CARRIER 0x0100 /* 1=False Carrier */ -#define GG82563_PSSR2_SYMBOL_ERROR 0x0200 /* 1=Symbol Error */ -#define GG82563_PSSR2_LINK_STATUS_CHANGED 0x0400 /* 1=Link Status Changed */ -#define GG82563_PSSR2_AUTO_NEG_COMPLETED 0x0800 /* 1=Auto-Neg Completed */ -#define GG82563_PSSR2_PAGE_RECEIVED 0x1000 /* 1=Page Received */ -#define GG82563_PSSR2_DUPLEX_CHANGED 0x2000 /* 1=Duplex Changed */ -#define GG82563_PSSR2_SPEED_CHANGED 0x4000 /* 1=Speed Changed */ -#define GG82563_PSSR2_AUTO_NEG_ERROR 0x8000 /* 1=Auto-Neg Error */ - -/* PHY Specific Control Register 2 (Page 0, Register 26) */ -#define GG82563_PSCR2_10BT_POLARITY_FORCE 0x0002 /* 1=Force Negative Polarity */ -#define GG82563_PSCR2_1000MB_TEST_SELECT_MASK 0x000C -#define GG82563_PSCR2_1000MB_TEST_SELECT_NORMAL 0x0000 /* 00,01=Normal Operation */ -#define GG82563_PSCR2_1000MB_TEST_SELECT_112NS 0x0008 /* 10=Select 112ns Sequence */ -#define GG82563_PSCR2_1000MB_TEST_SELECT_16NS 0x000C /* 11=Select 16ns Sequence */ -#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Negotiation */ -#define GG82563_PSCR2_1000BT_DISABLE 0x4000 /* 1=Disable 1000BASE-T */ -#define GG82563_PSCR2_TRANSMITER_TYPE_MASK 0x8000 -#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_B 0x0000 /* 0=Class B */ -#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_A 0x8000 /* 1=Class A */ - -/* MAC Specific Control Register (Page 2, Register 21) */ -/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */ -#define GG82563_MSCR_TX_CLK_MASK 0x0007 -#define GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ 0x0004 -#define GG82563_MSCR_TX_CLK_100MBPS_25MHZ 0x0005 -#define GG82563_MSCR_TX_CLK_1000MBPS_2_5MHZ 0x0006 -#define GG82563_MSCR_TX_CLK_1000MBPS_25MHZ 0x0007 - -#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */ - -/* DSP Distance Register (Page 5, Register 26) */ -#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M; - 1 = 50-80M; - 2 = 80-110M; - 3 = 110-140M; - 4 = >140M */ - -/* Kumeran Mode Control Register (Page 193, Register 16) */ -#define GG82563_KMCR_PHY_LEDS_EN 0x0020 /* 1=PHY LEDs, 0=Kumeran Inband LEDs */ -#define GG82563_KMCR_FORCE_LINK_UP 0x0040 /* 1=Force Link Up */ -#define GG82563_KMCR_SUPPRESS_SGMII_EPD_EXT 0x0080 -#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT_MASK 0x0400 -#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT 0x0400 /* 1=6.25MHz, 0=0.8MHz */ -#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 - -/* Power Management Control Register (Page 193, Register 20) */ -#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 /* 1=Enalbe SERDES Electrical Idle */ -#define GG82563_PMCR_DISABLE_PORT 0x0002 /* 1=Disable Port */ -#define GG82563_PMCR_DISABLE_SERDES 0x0004 /* 1=Disable SERDES */ -#define GG82563_PMCR_REVERSE_AUTO_NEG 0x0008 /* 1=Enable Reverse Auto-Negotiation */ -#define GG82563_PMCR_DISABLE_1000_NON_D0 0x0010 /* 1=Disable 1000Mbps Auto-Neg in non D0 */ -#define GG82563_PMCR_DISABLE_1000 0x0020 /* 1=Disable 1000Mbps Auto-Neg Always */ -#define GG82563_PMCR_REVERSE_AUTO_NEG_D0A 0x0040 /* 1=Enable D0a Reverse Auto-Negotiation */ -#define GG82563_PMCR_FORCE_POWER_STATE 0x0080 /* 1=Force Power State */ -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_MASK 0x0300 -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_DR 0x0000 /* 00=Dr */ -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0U 0x0100 /* 01=D0u */ -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0A 0x0200 /* 10=D0a */ -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D3 0x0300 /* 11=D3 */ - -/* In-Band Control Register (Page 194, Register 18) */ -#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding Use */ - /* Bit definitions for valid PHY IDs. */ /* I = Integrated @@ -2988,7 +2695,6 @@ struct e1000_host_command_info { #define M88E1011_I_REV_4 0x04 #define M88E1111_I_PHY_ID 0x01410CC0 #define L1LXT971A_PHY_ID 0x001378E0 -#define GG82563_E_PHY_ID 0x01410CA0 /* Miscellaneous PHY bit definitions. */ #define PHY_PREAMBLE 0xFFFFFFFF diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 43e647284..fa2940260 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -29,23 +29,6 @@ #include "e1000.h" /* Change Log - * 7.0.33 3-Feb-2006 - * o Added another fix for the pass false carrier bit - * 7.0.32 24-Jan-2006 - * o Need to rebuild with noew version number for the pass false carrier - * fix in e1000_hw.c - * 7.0.30 18-Jan-2006 - * o fixup for tso workaround to disable it for pci-x - * o fix mem leak on 82542 - * o fixes for 10 Mb/s connections and incorrect stats - * 7.0.28 01/06/2006 - * o hardware workaround to only set "speed mode" bit for 1G link. - * 7.0.26 12/23/2005 - * o wake on lan support modified for device ID 10B5 - * o fix dhcp + vlan issue not making it to the iAMT firmware - * 7.0.24 12/9/2005 - * o New hardware support for the Gigabit NIC embedded in the south bridge - * o Fixes to the recycling logic (skb->tail) from IBM LTC * 6.3.9 12/16/2005 * o incorporate fix for recycled skbs from IBM LTC * 6.3.7 11/18/2005 @@ -63,8 +46,54 @@ * rx_buffer_len * 6.3.1 9/19/05 * o Use adapter->tx_timeout_factor in Tx Hung Detect logic - * (e1000_clean_tx_irq) + (e1000_clean_tx_irq) * o Support for 8086:10B5 device (Quad Port) + * 6.2.14 9/15/05 + * o In AMT enabled configurations, set/reset DRV_LOAD bit on interface + * open/close + * 6.2.13 9/14/05 + * o Invoke e1000_check_mng_mode only for 8257x controllers since it + * accesses the FWSM that is not supported in other controllers + * 6.2.12 9/9/05 + * o Add support for device id E1000_DEV_ID_82546GB_QUAD_COPPER + * o set RCTL:SECRC only for controllers newer than 82543. + * o When the n/w interface comes down reset DRV_LOAD bit to notify f/w. + * This code was moved from e1000_remove to e1000_close + * 6.2.10 9/6/05 + * o Fix error in updating RDT in el1000_alloc_rx_buffers[_ps] -- one off. + * o Enable fc by default on 82573 controllers (do not read eeprom) + * o Fix rx_errors statistic not to include missed_packet_count + * o Fix rx_dropped statistic not to include missed_packet_count + (Padraig Brady) + * 6.2.9 8/30/05 + * o Remove call to update statistics from the controller ib e1000_get_stats + * 6.2.8 8/30/05 + * o Improved algorithm for rx buffer allocation/rdt update + * o Flow control watermarks relative to rx PBA size + * o Simplified 'Tx Hung' detect logic + * 6.2.7 8/17/05 + * o Report rx buffer allocation failures and tx timeout counts in stats + * 6.2.6 8/16/05 + * o Implement workaround for controller erratum -- linear non-tso packet + * following a TSO gets written back prematurely + * 6.2.5 8/15/05 + * o Set netdev->tx_queue_len based on link speed/duplex settings. + * o Fix net_stats.rx_fifo_errors + * o Do not power off PHY if SoL/IDER session is active + * 6.2.4 8/10/05 + * o Fix loopback test setup/cleanup for 82571/3 controllers + * o Fix parsing of outgoing packets (e1000_transfer_dhcp_info) to treat + * all packets as raw + * o Prevent operations that will cause the PHY to be reset if SoL/IDER + * sessions are active and log a message + * 6.2.2 7/21/05 + * o used fixed size descriptors for all MTU sizes, reduces memory load + * 6.1.2 4/13/05 + * o Fixed ethtool diagnostics + * o Enabled flow control to take default eeprom settings + * o Added stats_lock around e1000_read_phy_reg commands to avoid concurrent + * calls, one from mii_ioctl and other from within update_stats while + * processing MIIREG ioctl. */ char e1000_driver_name[] = "e1000"; @@ -74,7 +103,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "7.0.33-k2"DRIVERNAPI +#define DRV_VERSION "6.3.9-k4"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; @@ -128,26 +157,32 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x108A), INTEL_E1000_ETHERNET_DEVICE(0x108B), INTEL_E1000_ETHERNET_DEVICE(0x108C), - INTEL_E1000_ETHERNET_DEVICE(0x1096), - INTEL_E1000_ETHERNET_DEVICE(0x1098), INTEL_E1000_ETHERNET_DEVICE(0x1099), INTEL_E1000_ETHERNET_DEVICE(0x109A), INTEL_E1000_ETHERNET_DEVICE(0x10B5), - INTEL_E1000_ETHERNET_DEVICE(0x10B9), /* required last entry */ {0,} }; MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); +int e1000_up(struct e1000_adapter *adapter); +void e1000_down(struct e1000_adapter *adapter); +void e1000_reset(struct e1000_adapter *adapter); +int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx); +int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); +int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); +void e1000_free_all_tx_resources(struct e1000_adapter *adapter); +void e1000_free_all_rx_resources(struct e1000_adapter *adapter); static int e1000_setup_tx_resources(struct e1000_adapter *adapter, - struct e1000_tx_ring *txdr); + struct e1000_tx_ring *txdr); static int e1000_setup_rx_resources(struct e1000_adapter *adapter, - struct e1000_rx_ring *rxdr); + struct e1000_rx_ring *rxdr); static void e1000_free_tx_resources(struct e1000_adapter *adapter, - struct e1000_tx_ring *tx_ring); + struct e1000_tx_ring *tx_ring); static void e1000_free_rx_resources(struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring); + struct e1000_rx_ring *rx_ring); +void e1000_update_stats(struct e1000_adapter *adapter); /* Local Function Prototypes */ @@ -156,6 +191,9 @@ static void e1000_exit_module(void); static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent); static void __devexit e1000_remove(struct pci_dev *pdev); static int e1000_alloc_queues(struct e1000_adapter *adapter); +#ifdef CONFIG_E1000_MQ +static void e1000_setup_queue_mapping(struct e1000_adapter *adapter); +#endif static int e1000_sw_init(struct e1000_adapter *adapter); static int e1000_open(struct net_device *netdev); static int e1000_close(struct net_device *netdev); @@ -203,10 +241,11 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); +void e1000_set_ethtool_ops(struct net_device *netdev); static void e1000_enter_82542_rst(struct e1000_adapter *adapter); static void e1000_leave_82542_rst(struct e1000_adapter *adapter); static void e1000_tx_timeout(struct net_device *dev); -static void e1000_reset_task(struct net_device *dev); +static void e1000_tx_timeout_task(struct net_device *dev); static void e1000_smartspeed(struct e1000_adapter *adapter); static inline int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb); @@ -220,13 +259,20 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter); static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); static int e1000_resume(struct pci_dev *pdev); #endif -static void e1000_shutdown(struct pci_dev *pdev); #ifdef CONFIG_NET_POLL_CONTROLLER /* for netdump / net console */ static void e1000_netpoll (struct net_device *netdev); #endif +#ifdef CONFIG_E1000_MQ +/* for multiple Rx queues */ +void e1000_rx_schedule(void *data); +#endif + +/* Exported from other modules */ + +extern void e1000_check_options(struct e1000_adapter *adapter); static struct pci_driver e1000_driver = { .name = e1000_driver_name, @@ -236,9 +282,8 @@ static struct pci_driver e1000_driver = { /* Power Managment Hooks */ #ifdef CONFIG_PM .suspend = e1000_suspend, - .resume = e1000_resume, + .resume = e1000_resume #endif - .shutdown = e1000_shutdown }; MODULE_AUTHOR("Intel Corporation, "); @@ -335,8 +380,7 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter) (vid != old_vid) && !adapter->vlgrp->vlan_devices[old_vid]) e1000_vlan_rx_kill_vid(netdev, old_vid); - } else - adapter->mng_vlan_id = vid; + } } } @@ -458,6 +502,10 @@ e1000_up(struct e1000_adapter *adapter) return err; } +#ifdef CONFIG_E1000_MQ + e1000_setup_queue_mapping(adapter); +#endif + adapter->tx_queue_len = netdev->tx_queue_len; mod_timer(&adapter->watchdog_timer, jiffies); @@ -478,7 +526,9 @@ e1000_down(struct e1000_adapter *adapter) e1000_check_mng_mode(&adapter->hw); e1000_irq_disable(adapter); - +#ifdef CONFIG_E1000_MQ + while (atomic_read(&adapter->rx_sched_call_data.count) != 0); +#endif free_irq(adapter->pdev->irq, netdev); #ifdef CONFIG_PCI_MSI if (adapter->hw.mac_type > e1000_82547_rev_2 && @@ -537,7 +587,6 @@ e1000_reset(struct e1000_adapter *adapter) break; case e1000_82571: case e1000_82572: - case e1000_80003es2lan: pba = E1000_PBA_38K; break; case e1000_82573: @@ -570,10 +619,7 @@ e1000_reset(struct e1000_adapter *adapter) adapter->hw.fc_high_water = fc_high_water_mark; adapter->hw.fc_low_water = fc_high_water_mark - 8; - if (adapter->hw.mac_type == e1000_80003es2lan) - adapter->hw.fc_pause_time = 0xFFFF; - else - adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME; + adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME; adapter->hw.fc_send_xon = 1; adapter->hw.fc = adapter->hw.original_fc; @@ -617,7 +663,6 @@ e1000_probe(struct pci_dev *pdev, unsigned long mmio_start, mmio_len; static int cards_found = 0; - static int e1000_ksp3_port_a = 0; /* global ksp3 port a indication */ int i, err, pci_using_dac; uint16_t eeprom_data; uint16_t eeprom_apme_mask = E1000_EEPROM_APME; @@ -710,15 +755,6 @@ e1000_probe(struct pci_dev *pdev, if ((err = e1000_check_phy_reset_block(&adapter->hw))) DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n"); - /* if ksp3, indicate if it's port a being setup */ - if (pdev->device == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 && - e1000_ksp3_port_a == 0) - adapter->ksp3_port_a = 1; - e1000_ksp3_port_a++; - /* Reset for multiple KP3 adapters */ - if (e1000_ksp3_port_a == 4) - e1000_ksp3_port_a = 0; - if (adapter->hw.mac_type >= e1000_82543) { netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | @@ -790,8 +826,8 @@ e1000_probe(struct pci_dev *pdev, adapter->phy_info_timer.function = &e1000_update_phy_info; adapter->phy_info_timer.data = (unsigned long) adapter; - INIT_WORK(&adapter->reset_task, - (void (*)(void *))e1000_reset_task, netdev); + INIT_WORK(&adapter->tx_timeout_task, + (void (*)(void *))e1000_tx_timeout_task, netdev); /* we're going to reset, so assume we have no link for now */ @@ -818,7 +854,6 @@ e1000_probe(struct pci_dev *pdev, case e1000_82546: case e1000_82546_rev_3: case e1000_82571: - case e1000_80003es2lan: if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1){ e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); @@ -922,7 +957,7 @@ e1000_remove(struct pci_dev *pdev) unregister_netdev(netdev); #ifdef CONFIG_E1000_NAPI for (i = 0; i < adapter->num_rx_queues; i++) - dev_put(&adapter->polling_netdev[i]); + __dev_put(&adapter->polling_netdev[i]); #endif if (!e1000_check_phy_reset_block(&adapter->hw)) @@ -937,6 +972,10 @@ e1000_remove(struct pci_dev *pdev) iounmap(adapter->hw.hw_addr); pci_release_regions(pdev); +#ifdef CONFIG_E1000_MQ + free_percpu(adapter->cpu_netdev); + free_percpu(adapter->cpu_tx_ring); +#endif free_netdev(netdev); pci_disable_device(pdev); @@ -1017,8 +1056,40 @@ e1000_sw_init(struct e1000_adapter *adapter) hw->master_slave = E1000_MASTER_SLAVE; } +#ifdef CONFIG_E1000_MQ + /* Number of supported queues */ + switch (hw->mac_type) { + case e1000_82571: + case e1000_82572: + /* These controllers support 2 tx queues, but with a single + * qdisc implementation, multiple tx queues aren't quite as + * interesting. If we can find a logical way of mapping + * flows to a queue, then perhaps we can up the num_tx_queue + * count back to its default. Until then, we run the risk of + * terrible performance due to SACK overload. */ + adapter->num_tx_queues = 1; + adapter->num_rx_queues = 2; + break; + default: + adapter->num_tx_queues = 1; + adapter->num_rx_queues = 1; + break; + } + adapter->num_rx_queues = min(adapter->num_rx_queues, num_online_cpus()); + adapter->num_tx_queues = min(adapter->num_tx_queues, num_online_cpus()); + DPRINTK(DRV, INFO, "Multiqueue Enabled: Rx Queue count = %u %s\n", + adapter->num_rx_queues, + ((adapter->num_rx_queues == 1) + ? ((num_online_cpus() > 1) + ? "(due to unsupported feature in current adapter)" + : "(due to unsupported system configuration)") + : "")); + DPRINTK(DRV, INFO, "Multiqueue Enabled: Tx Queue count = %u\n", + adapter->num_tx_queues); +#else adapter->num_tx_queues = 1; adapter->num_rx_queues = 1; +#endif if (e1000_alloc_queues(adapter)) { DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n"); @@ -1081,9 +1152,51 @@ e1000_alloc_queues(struct e1000_adapter *adapter) memset(adapter->polling_netdev, 0, size); #endif +#ifdef CONFIG_E1000_MQ + adapter->rx_sched_call_data.func = e1000_rx_schedule; + adapter->rx_sched_call_data.info = adapter->netdev; + + adapter->cpu_netdev = alloc_percpu(struct net_device *); + adapter->cpu_tx_ring = alloc_percpu(struct e1000_tx_ring *); +#endif + return E1000_SUCCESS; } +#ifdef CONFIG_E1000_MQ +static void __devinit +e1000_setup_queue_mapping(struct e1000_adapter *adapter) +{ + int i, cpu; + + adapter->rx_sched_call_data.func = e1000_rx_schedule; + adapter->rx_sched_call_data.info = adapter->netdev; + cpus_clear(adapter->rx_sched_call_data.cpumask); + + adapter->cpu_netdev = alloc_percpu(struct net_device *); + adapter->cpu_tx_ring = alloc_percpu(struct e1000_tx_ring *); + + lock_cpu_hotplug(); + i = 0; + for_each_online_cpu(cpu) { + *per_cpu_ptr(adapter->cpu_tx_ring, cpu) = &adapter->tx_ring[i % adapter->num_tx_queues]; + /* This is incomplete because we'd like to assign separate + * physical cpus to these netdev polling structures and + * avoid saturating a subset of cpus. + */ + if (i < adapter->num_rx_queues) { + *per_cpu_ptr(adapter->cpu_netdev, cpu) = &adapter->polling_netdev[i]; + adapter->rx_ring[i].cpu = cpu; + cpu_set(cpu, adapter->cpumask); + } else + *per_cpu_ptr(adapter->cpu_netdev, cpu) = NULL; + + i++; + } + unlock_cpu_hotplug(); +} +#endif + /** * e1000_open - Called when a network interface is made active * @netdev: network interface device structure @@ -1322,6 +1435,18 @@ e1000_configure_tx(struct e1000_adapter *adapter) /* Setup the HW Tx Head and Tail descriptor pointers */ switch (adapter->num_tx_queues) { + case 2: + tdba = adapter->tx_ring[1].dma; + tdlen = adapter->tx_ring[1].count * + sizeof(struct e1000_tx_desc); + E1000_WRITE_REG(hw, TDBAL1, (tdba & 0x00000000ffffffffULL)); + E1000_WRITE_REG(hw, TDBAH1, (tdba >> 32)); + E1000_WRITE_REG(hw, TDLEN1, tdlen); + E1000_WRITE_REG(hw, TDH1, 0); + E1000_WRITE_REG(hw, TDT1, 0); + adapter->tx_ring[1].tdh = E1000_TDH1; + adapter->tx_ring[1].tdt = E1000_TDT1; + /* Fall Through */ case 1: default: tdba = adapter->tx_ring[0].dma; @@ -1352,10 +1477,6 @@ e1000_configure_tx(struct e1000_adapter *adapter) ipgr1 = DEFAULT_82542_TIPG_IPGR1; ipgr2 = DEFAULT_82542_TIPG_IPGR2; break; - case e1000_80003es2lan: - ipgr1 = DEFAULT_82543_TIPG_IPGR1; - ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; - break; default: ipgr1 = DEFAULT_82543_TIPG_IPGR1; ipgr2 = DEFAULT_82543_TIPG_IPGR2; @@ -1376,13 +1497,10 @@ e1000_configure_tx(struct e1000_adapter *adapter) tctl = E1000_READ_REG(hw, TCTL); tctl &= ~E1000_TCTL_CT; - tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | + tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_RTLC | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); -#ifdef DISABLE_MULR - /* disable Multiple Reads for debugging */ - tctl &= ~E1000_TCTL_MULR; -#endif + E1000_WRITE_REG(hw, TCTL, tctl); if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) { tarc = E1000_READ_REG(hw, TARC0); @@ -1395,15 +1513,6 @@ e1000_configure_tx(struct e1000_adapter *adapter) else tarc |= (1 << 28); E1000_WRITE_REG(hw, TARC1, tarc); - } else if (hw->mac_type == e1000_80003es2lan) { - tarc = E1000_READ_REG(hw, TARC0); - tarc |= 1; - if (hw->media_type == e1000_media_type_internal_serdes) - tarc |= (1 << 20); - E1000_WRITE_REG(hw, TARC0, tarc); - tarc = E1000_READ_REG(hw, TARC1); - tarc |= 1; - E1000_WRITE_REG(hw, TARC1, tarc); } e1000_config_collision_dist(hw); @@ -1422,9 +1531,6 @@ e1000_configure_tx(struct e1000_adapter *adapter) if (hw->mac_type == e1000_82544 && hw->bus_type == e1000_bus_type_pcix) adapter->pcix_82544 = 1; - - E1000_WRITE_REG(hw, TCTL, tctl); - } /** @@ -1684,9 +1790,12 @@ e1000_configure_rx(struct e1000_adapter *adapter) uint64_t rdba; struct e1000_hw *hw = &adapter->hw; uint32_t rdlen, rctl, rxcsum, ctrl_ext; +#ifdef CONFIG_E1000_MQ + uint32_t reta, mrqc; + int i; +#endif if (adapter->rx_ps_pages) { - /* this is a 32 byte descriptor */ rdlen = adapter->rx_ring[0].count * sizeof(union e1000_rx_desc_packet_split); adapter->clean_rx = e1000_clean_rx_irq_ps; @@ -1728,6 +1837,18 @@ e1000_configure_rx(struct e1000_adapter *adapter) /* Setup the HW Rx Head and Tail Descriptor Pointers and * the Base and Length of the Rx Descriptor Ring */ switch (adapter->num_rx_queues) { +#ifdef CONFIG_E1000_MQ + case 2: + rdba = adapter->rx_ring[1].dma; + E1000_WRITE_REG(hw, RDBAL1, (rdba & 0x00000000ffffffffULL)); + E1000_WRITE_REG(hw, RDBAH1, (rdba >> 32)); + E1000_WRITE_REG(hw, RDLEN1, rdlen); + E1000_WRITE_REG(hw, RDH1, 0); + E1000_WRITE_REG(hw, RDT1, 0); + adapter->rx_ring[1].rdh = E1000_RDH1; + adapter->rx_ring[1].rdt = E1000_RDT1; + /* Fall Through */ +#endif case 1: default: rdba = adapter->rx_ring[0].dma; @@ -1741,6 +1862,46 @@ e1000_configure_rx(struct e1000_adapter *adapter) break; } +#ifdef CONFIG_E1000_MQ + if (adapter->num_rx_queues > 1) { + uint32_t random[10]; + + get_random_bytes(&random[0], 40); + + if (hw->mac_type <= e1000_82572) { + E1000_WRITE_REG(hw, RSSIR, 0); + E1000_WRITE_REG(hw, RSSIM, 0); + } + + switch (adapter->num_rx_queues) { + case 2: + default: + reta = 0x00800080; + mrqc = E1000_MRQC_ENABLE_RSS_2Q; + break; + } + + /* Fill out redirection table */ + for (i = 0; i < 32; i++) + E1000_WRITE_REG_ARRAY(hw, RETA, i, reta); + /* Fill out hash function seeds */ + for (i = 0; i < 10; i++) + E1000_WRITE_REG_ARRAY(hw, RSSRK, i, random[i]); + + mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 | + E1000_MRQC_RSS_FIELD_IPV4_TCP); + E1000_WRITE_REG(hw, MRQC, mrqc); + } + + /* Multiqueue and packet checksumming are mutually exclusive. */ + if (hw->mac_type >= e1000_82571) { + rxcsum = E1000_READ_REG(hw, RXCSUM); + rxcsum |= E1000_RXCSUM_PCSD; + E1000_WRITE_REG(hw, RXCSUM, rxcsum); + } + +#else + /* Enable 82543 Receive Checksum Offload for TCP and UDP */ if (hw->mac_type >= e1000_82543) { rxcsum = E1000_READ_REG(hw, RXCSUM); @@ -1759,6 +1920,7 @@ e1000_configure_rx(struct e1000_adapter *adapter) } E1000_WRITE_REG(hw, RXCSUM, rxcsum); } +#endif /* CONFIG_E1000_MQ */ if (hw->mac_type == e1000_82573) E1000_WRITE_REG(hw, ERT, 0x0100); @@ -2230,7 +2392,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; struct e1000_tx_ring *txdr = adapter->tx_ring; - uint32_t link, tctl; + uint32_t link; e1000_check_for_link(&adapter->hw); if (adapter->hw.mac_type == e1000_82573) { @@ -2256,61 +2418,20 @@ e1000_watchdog_task(struct e1000_adapter *adapter) adapter->link_duplex == FULL_DUPLEX ? "Full Duplex" : "Half Duplex"); - /* tweak tx_queue_len according to speed/duplex - * and adjust the timeout factor */ + /* tweak tx_queue_len according to speed/duplex */ netdev->tx_queue_len = adapter->tx_queue_len; adapter->tx_timeout_factor = 1; - adapter->txb2b = 1; - switch (adapter->link_speed) { - case SPEED_10: - adapter->txb2b = 0; - netdev->tx_queue_len = 10; - adapter->tx_timeout_factor = 8; - break; - case SPEED_100: - adapter->txb2b = 0; - netdev->tx_queue_len = 100; - /* maybe add some timeout factor ? */ - break; - } - - if ((adapter->hw.mac_type == e1000_82571 || - adapter->hw.mac_type == e1000_82572) && - adapter->txb2b == 0) { -#define SPEED_MODE_BIT (1 << 21) - uint32_t tarc0; - tarc0 = E1000_READ_REG(&adapter->hw, TARC0); - tarc0 &= ~SPEED_MODE_BIT; - E1000_WRITE_REG(&adapter->hw, TARC0, tarc0); - } - -#ifdef NETIF_F_TSO - /* disable TSO for pcie and 10/100 speeds, to avoid - * some hardware issues */ - if (!adapter->tso_force && - adapter->hw.bus_type == e1000_bus_type_pci_express){ + if (adapter->link_duplex == HALF_DUPLEX) { switch (adapter->link_speed) { case SPEED_10: - case SPEED_100: - DPRINTK(PROBE,INFO, - "10/100 speed: disabling TSO\n"); - netdev->features &= ~NETIF_F_TSO; - break; - case SPEED_1000: - netdev->features |= NETIF_F_TSO; + netdev->tx_queue_len = 10; + adapter->tx_timeout_factor = 8; break; - default: - /* oops */ + case SPEED_100: + netdev->tx_queue_len = 100; break; } } -#endif - - /* enable transmits in the hardware, need to do this - * after setting TARC0 */ - tctl = E1000_READ_REG(&adapter->hw, TCTL); - tctl |= E1000_TCTL_EN; - E1000_WRITE_REG(&adapter->hw, TCTL, tctl); netif_carrier_on(netdev); netif_wake_queue(netdev); @@ -2325,16 +2446,6 @@ e1000_watchdog_task(struct e1000_adapter *adapter) netif_carrier_off(netdev); netif_stop_queue(netdev); mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); - - /* 80003ES2LAN workaround-- - * For packet buffer work-around on link down event; - * disable receives in the ISR and - * reset device here in the watchdog - */ - if (adapter->hw.mac_type == e1000_80003es2lan) { - /* reset device */ - schedule_work(&adapter->reset_task); - } } e1000_smartspeed(adapter); @@ -2354,14 +2465,16 @@ e1000_watchdog_task(struct e1000_adapter *adapter) e1000_update_adaptive(&adapter->hw); +#ifdef CONFIG_E1000_MQ + txdr = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id()); +#endif if (!netif_carrier_ok(netdev)) { if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) { /* 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); + schedule_work(&adapter->tx_timeout_task); } } @@ -2413,7 +2526,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, uint8_t ipcss, ipcso, tucss, tucso, hdr_len; int err; - if (skb_is_gso(skb)) { + if (skb_shinfo(skb)->tso_size) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -2421,7 +2534,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, } hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; if (skb->protocol == ntohs(ETH_P_IP)) { skb->nh.iph->tot_len = 0; skb->nh.iph->check = 0; @@ -2536,9 +2649,9 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, /* Workaround for Controller erratum -- * descriptor for non-tso packet in a linear SKB that follows a * tso gets written back prematurely before the data is fully - * DMA'd to the controller */ + * DMAd to the controller */ if (!skb->data_len && tx_ring->last_tx_tso && - !skb_is_gso(skb)) { + !skb_shinfo(skb)->tso_size) { tx_ring->last_tx_tso = 0; size -= 4; } @@ -2727,7 +2840,7 @@ e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb) E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) ) return 0; } - if (skb->len > MINIMUM_DHCP_PACKET_SIZE) { + if ((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) { struct ethhdr *eth = (struct ethhdr *) skb->data; if ((htons(ETH_P_IP) == eth->h_proto)) { const struct iphdr *ip = @@ -2768,7 +2881,11 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) unsigned int f; len -= skb->data_len; +#ifdef CONFIG_E1000_MQ + tx_ring = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id()); +#else tx_ring = adapter->tx_ring; +#endif if (unlikely(skb->len <= 0)) { dev_kfree_skb_any(skb); @@ -2776,7 +2893,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } #ifdef NETIF_F_TSO - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; /* The controller does a simple calculation to * make sure there is enough room in the FIFO before * initiating the DMA for each buffer. The calc is: @@ -2788,29 +2905,21 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) max_per_txd = min(mss << 2, max_per_txd); max_txd_pwr = fls(max_per_txd) - 1; - /* TSO Workaround for 82571/2/3 Controllers -- if skb->data + /* TSO Workaround for 82571/2 Controllers -- if skb->data * points to just header, pull a few bytes of payload from * frags into skb->data */ hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) { - switch (adapter->hw.mac_type) { - unsigned int pull_size; - case e1000_82571: - case e1000_82572: - case e1000_82573: - pull_size = min((unsigned int)4, skb->data_len); - if (!__pskb_pull_tail(skb, pull_size)) { - printk(KERN_ERR - "__pskb_pull_tail failed.\n"); - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - len = skb->len - skb->data_len; - break; - default: - /* do nothing */ - break; + if (skb->data_len && (hdr_len == (skb->len - skb->data_len)) && + (adapter->hw.mac_type == e1000_82571 || + adapter->hw.mac_type == e1000_82572)) { + unsigned int pull_size; + pull_size = min((unsigned int)4, skb->data_len); + if (!__pskb_pull_tail(skb, pull_size)) { + printk(KERN_ERR "__pskb_pull_tail failed.\n"); + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; } + len = skb->len - skb->data_len; } } @@ -2825,7 +2934,8 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) #ifdef NETIF_F_TSO /* Controller Erratum workaround */ - if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb)) + if (!skb->data_len && tx_ring->last_tx_tso && + !skb_shinfo(skb)->tso_size) count++; #endif @@ -2848,9 +2958,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (adapter->pcix_82544) count += nr_frags; - - if (adapter->hw.tx_pkt_filtering && - (adapter->hw.mac_type == e1000_82573)) + if (adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) ) e1000_transfer_dhcp_info(adapter, skb); local_irq_save(flags); @@ -2928,15 +3036,15 @@ e1000_tx_timeout(struct net_device *netdev) struct e1000_adapter *adapter = netdev_priv(netdev); /* Do the reset outside of interrupt context */ - adapter->tx_timeout_count++; - schedule_work(&adapter->reset_task); + schedule_work(&adapter->tx_timeout_task); } static void -e1000_reset_task(struct net_device *netdev) +e1000_tx_timeout_task(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); + adapter->tx_timeout_count++; e1000_down(adapter); e1000_up(adapter); } @@ -2971,7 +3079,6 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) { struct e1000_adapter *adapter = netdev_priv(netdev); int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - uint16_t eeprom_data = 0; if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || (max_frame > MAX_JUMBO_FRAME_SIZE)) { @@ -2983,28 +3090,14 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) switch (adapter->hw.mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: + case e1000_82573: if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) { DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n"); return -EINVAL; } break; - case e1000_82573: - /* only enable jumbo frames if ASPM is disabled completely - * this means both bits must be zero in 0x1A bits 3:2 */ - e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1, - &eeprom_data); - if (eeprom_data & EEPROM_WORD1A_ASPM_MASK) { - if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) { - DPRINTK(PROBE, ERR, - "Jumbo Frames not supported.\n"); - return -EINVAL; - } - break; - } - /* fall through to get support */ case e1000_82571: case e1000_82572: - case e1000_80003es2lan: #define MAX_STD_JUMBO_FRAME_SIZE 9234 if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n"); @@ -3158,15 +3251,11 @@ e1000_update_stats(struct e1000_adapter *adapter) /* Rx Errors */ - /* RLEC on some newer hardware can be incorrect so build - * our own version based on RUC and ROC */ adapter->net_stats.rx_errors = adapter->stats.rxerrc + adapter->stats.crcerrs + adapter->stats.algnerrc + - adapter->stats.ruc + adapter->stats.roc + - adapter->stats.cexterr; + adapter->stats.rlec + adapter->stats.cexterr; adapter->net_stats.rx_dropped = 0; - adapter->net_stats.rx_length_errors = adapter->stats.ruc + - adapter->stats.roc; + adapter->net_stats.rx_length_errors = adapter->stats.rlec; adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc; adapter->net_stats.rx_missed_errors = adapter->stats.mpc; @@ -3199,6 +3288,29 @@ e1000_update_stats(struct e1000_adapter *adapter) spin_unlock_irqrestore(&adapter->stats_lock, flags); } +#ifdef CONFIG_E1000_MQ +void +e1000_rx_schedule(void *data) +{ + struct net_device *poll_dev, *netdev = data; + struct e1000_adapter *adapter = netdev->priv; + int this_cpu = get_cpu(); + + poll_dev = *per_cpu_ptr(adapter->cpu_netdev, this_cpu); + if (poll_dev == NULL) { + put_cpu(); + return; + } + + if (likely(netif_rx_schedule_prep(poll_dev))) + __netif_rx_schedule(poll_dev); + else + e1000_irq_enable(adapter); + + put_cpu(); +} +#endif + /** * e1000_intr - Interrupt Handler * @irq: interrupt number @@ -3212,7 +3324,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) struct net_device *netdev = data; struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - uint32_t rctl, icr = E1000_READ_REG(hw, ICR); + uint32_t icr = E1000_READ_REG(hw, ICR); #ifndef CONFIG_E1000_NAPI int i; #else @@ -3234,17 +3346,6 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { hw->get_link_status = 1; - /* 80003ES2LAN workaround-- - * For packet buffer work-around on link down event; - * disable receives here in the ISR and - * reset adapter in watchdog - */ - if (netif_carrier_ok(netdev) && - (adapter->hw.mac_type == e1000_80003es2lan)) { - /* disable receives */ - rctl = E1000_READ_REG(hw, RCTL); - E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); - } mod_timer(&adapter->watchdog_timer, jiffies); } @@ -3254,11 +3355,26 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) E1000_WRITE_REG(hw, IMC, ~0); E1000_WRITE_FLUSH(hw); } +#ifdef CONFIG_E1000_MQ + if (atomic_read(&adapter->rx_sched_call_data.count) == 0) { + /* We must setup the cpumask once count == 0 since + * each cpu bit is cleared when the work is done. */ + adapter->rx_sched_call_data.cpumask = adapter->cpumask; + atomic_add(adapter->num_rx_queues - 1, &adapter->irq_sem); + atomic_set(&adapter->rx_sched_call_data.count, + adapter->num_rx_queues); + smp_call_async_mask(&adapter->rx_sched_call_data); + } else { + printk("call_data.count == %u\n", atomic_read(&adapter->rx_sched_call_data.count)); + } +#else /* if !CONFIG_E1000_MQ */ if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0]))) __netif_rx_schedule(&adapter->polling_netdev[0]); else e1000_irq_enable(adapter); -#else +#endif /* CONFIG_E1000_MQ */ + +#else /* if !CONFIG_E1000_NAPI */ /* Writing IMC and IMS is needed for 82547. * Due to Hub Link bus being occupied, an interrupt * de-assertion message is not able to be sent. @@ -3282,7 +3398,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) e1000_irq_enable(adapter); -#endif +#endif /* CONFIG_E1000_NAPI */ return IRQ_HANDLED; } @@ -3309,7 +3425,8 @@ e1000_clean(struct net_device *poll_dev, int *budget) while (poll_dev != &adapter->polling_netdev[i]) { i++; - BUG_ON(i == adapter->num_rx_queues); + if (unlikely(i == adapter->num_rx_queues)) + BUG(); } if (likely(adapter->num_tx_queues == 1)) { @@ -3357,9 +3474,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, struct e1000_tx_desc *tx_desc, *eop_desc; struct e1000_buffer *buffer_info; unsigned int i, eop; -#ifdef CONFIG_E1000_NAPI - unsigned int count = 0; -#endif boolean_t cleaned = FALSE; i = tx_ring->next_to_clean; @@ -3372,20 +3486,21 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, buffer_info = &tx_ring->buffer_info[i]; cleaned = (i == eop); +#ifdef CONFIG_E1000_MQ + tx_ring->tx_stats.bytes += buffer_info->length; +#endif e1000_unmap_and_free_tx_resource(adapter, buffer_info); memset(tx_desc, 0, sizeof(struct e1000_tx_desc)); if (unlikely(++i == tx_ring->count)) i = 0; } +#ifdef CONFIG_E1000_MQ + tx_ring->tx_stats.packets++; +#endif eop = tx_ring->buffer_info[i].next_to_watch; eop_desc = E1000_TX_DESC(*tx_ring, eop); -#ifdef CONFIG_E1000_NAPI -#define E1000_TX_WEIGHT 64 - /* weight of a sort for tx, to avoid endless transmit cleanup */ - if (count++ == E1000_TX_WEIGHT) break; -#endif } tx_ring->next_to_clean = i; @@ -3404,7 +3519,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, adapter->detect_tx_hung = FALSE; if (tx_ring->buffer_info[eop].dma && time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + - (adapter->tx_timeout_factor * HZ)) + adapter->tx_timeout_factor * HZ) && !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF)) { @@ -3518,7 +3633,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, buffer_info = &rx_ring->buffer_info[i]; while (rx_desc->status & E1000_RXD_STAT_DD) { - struct sk_buff *skb; + struct sk_buff *skb, *next_skb; u8 status; #ifdef CONFIG_E1000_NAPI if (*work_done >= work_to_do) @@ -3529,13 +3644,10 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, skb = buffer_info->skb; buffer_info->skb = NULL; - prefetch(skb->data - NET_IP_ALIGN); - if (++i == rx_ring->count) i = 0; next_rxd = E1000_RX_DESC(*rx_ring, i); - prefetch(next_rxd); - next_buffer = &rx_ring->buffer_info[i]; + next_skb = next_buffer->skb; cleaned = TRUE; cleaned_count++; @@ -3621,6 +3733,10 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, } #endif /* CONFIG_E1000_NAPI */ netdev->last_rx = jiffies; +#ifdef CONFIG_E1000_MQ + rx_ring->rx_stats.packets++; + rx_ring->rx_stats.bytes += length; +#endif next_desc: rx_desc->status = 0; @@ -3631,7 +3747,6 @@ next_desc: cleaned_count = 0; } - /* use prefetched values */ rx_desc = next_rxd; buffer_info = next_buffer; } @@ -3665,7 +3780,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info, *next_buffer; struct e1000_ps_page *ps_page; struct e1000_ps_page_dma *ps_page_dma; - struct sk_buff *skb; + struct sk_buff *skb, *next_skb; unsigned int i, j; uint32_t length, staterr; int cleaned_count = 0; @@ -3674,9 +3789,9 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC_PS(*rx_ring, i); staterr = le32_to_cpu(rx_desc->wb.middle.status_error); + buffer_info = &rx_ring->buffer_info[i]; while (staterr & E1000_RXD_STAT_DD) { - buffer_info = &rx_ring->buffer_info[i]; ps_page = &rx_ring->ps_page[i]; ps_page_dma = &rx_ring->ps_page_dma[i]; #ifdef CONFIG_E1000_NAPI @@ -3686,14 +3801,10 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, #endif skb = buffer_info->skb; - /* in the packet split case this is header only */ - prefetch(skb->data - NET_IP_ALIGN); - if (++i == rx_ring->count) i = 0; next_rxd = E1000_RX_DESC_PS(*rx_ring, i); - prefetch(next_rxd); - next_buffer = &rx_ring->buffer_info[i]; + next_skb = next_buffer->skb; cleaned = TRUE; cleaned_count++; @@ -3725,50 +3836,24 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, /* Good Receive */ skb_put(skb, length); - { - /* this looks ugly, but it seems compiler issues make it - more efficient than reusing j */ - int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]); - - /* page alloc/put takes too long and effects small packet - * throughput, so unsplit small packets and save the alloc/put*/ - if (l1 && ((length + l1) < E1000_CB_LENGTH)) { - u8 *vaddr; - /* there is no documentation about how to call - * kmap_atomic, so we can't hold the mapping - * very long */ - pci_dma_sync_single_for_cpu(pdev, - ps_page_dma->ps_page_dma[0], - PAGE_SIZE, - PCI_DMA_FROMDEVICE); - vaddr = kmap_atomic(ps_page->ps_page[0], - KM_SKB_DATA_SOFTIRQ); - memcpy(skb->tail, vaddr, l1); - kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); - pci_dma_sync_single_for_device(pdev, - ps_page_dma->ps_page_dma[0], - PAGE_SIZE, PCI_DMA_FROMDEVICE); - skb_put(skb, l1); - length += l1; - goto copydone; - } /* if */ - } - for (j = 0; j < adapter->rx_ps_pages; j++) { - if (!(length= le16_to_cpu(rx_desc->wb.upper.length[j]))) + if (!(length = le16_to_cpu(rx_desc->wb.upper.length[j]))) break; + pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j], PAGE_SIZE, PCI_DMA_FROMDEVICE); ps_page_dma->ps_page_dma[j] = 0; - skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0, - length); + skb_shinfo(skb)->frags[j].page = + ps_page->ps_page[j]; ps_page->ps_page[j] = NULL; + skb_shinfo(skb)->frags[j].page_offset = 0; + skb_shinfo(skb)->frags[j].size = length; + skb_shinfo(skb)->nr_frags++; skb->len += length; skb->data_len += length; skb->truesize += length; } -copydone: e1000_rx_checksum(adapter, staterr, le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); skb->protocol = eth_type_trans(skb, netdev); @@ -3794,6 +3879,10 @@ copydone: } #endif /* CONFIG_E1000_NAPI */ netdev->last_rx = jiffies; +#ifdef CONFIG_E1000_MQ + rx_ring->rx_stats.packets++; + rx_ring->rx_stats.bytes += length; +#endif next_desc: rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF); @@ -3805,7 +3894,6 @@ next_desc: cleaned_count = 0; } - /* use prefetched values */ rx_desc = next_rxd; buffer_info = next_buffer; @@ -3849,6 +3937,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, goto map_skb; } + if (unlikely(!skb)) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; @@ -4154,7 +4243,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) spin_unlock_irqrestore(&adapter->stats_lock, flags); return -EIO; } - if (adapter->hw.phy_type == e1000_media_type_copper) { + if (adapter->hw.phy_type == e1000_phy_m88) { switch (data->reg_num) { case PHY_CTRL: if (mii_reg & MII_CR_POWER_DOWN) @@ -4170,8 +4259,8 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) else spddplx = SPEED_10; spddplx += (mii_reg & 0x100) - ? DUPLEX_FULL : - DUPLEX_HALF; + ? FULL_DUPLEX : + HALF_DUPLEX; retval = e1000_set_spd_dplx(adapter, spddplx); if (retval) { @@ -4401,8 +4490,8 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx) } #ifdef CONFIG_PM -/* Save/restore 16 or 64 dwords of PCI config space depending on which - * bus we're on (PCI(X) vs. PCI-E) +/* these functions save and restore 16 or 64 dwords (64-256 bytes) of config + * space versus the 64 bytes that pci_[save|restore]_state handle */ #define PCIE_CONFIG_SPACE_LEN 256 #define PCI_CONFIG_SPACE_LEN 64 @@ -4412,7 +4501,6 @@ e1000_pci_save_state(struct e1000_adapter *adapter) struct pci_dev *dev = adapter->pdev; int size; int i; - if (adapter->hw.mac_type >= e1000_82571) size = PCIE_CONFIG_SPACE_LEN; else @@ -4436,10 +4524,8 @@ e1000_pci_restore_state(struct e1000_adapter *adapter) struct pci_dev *dev = adapter->pdev; int size; int i; - if (adapter->config_space == NULL) return; - if (adapter->hw.mac_type >= e1000_82571) size = PCIE_CONFIG_SPACE_LEN; else @@ -4467,8 +4553,8 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) e1000_down(adapter); #ifdef CONFIG_PM - /* Implement our own version of pci_save_state(pdev) because pci- - * express adapters have 256-byte config spaces. */ + /* implement our own version of pci_save_state(pdev) because pci + * express adapters have larger 256 byte config spaces */ retval = e1000_pci_save_state(adapter); if (retval) return retval; @@ -4525,7 +4611,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) retval = pci_enable_wake(pdev, PCI_D3hot, 0); if (retval) DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 0); + retval = pci_enable_wake(pdev, PCI_D3cold, 0); /* 4 == D3 cold */ if (retval) DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); } @@ -4541,8 +4627,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); retval = pci_enable_wake(pdev, PCI_D3cold, 1); if (retval) - DPRINTK(PROBE, ERR, - "Error enabling D3 cold wake\n"); + DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); } } @@ -4608,12 +4693,6 @@ e1000_resume(struct pci_dev *pdev) return 0; } #endif - -static void e1000_shutdown(struct pci_dev *pdev) -{ - e1000_suspend(pdev, PMSG_SUSPEND); -} - #ifdef CONFIG_NET_POLL_CONTROLLER /* * Polling 'interrupt' - used by things like netconsole to send skbs diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c index e0a4d37d1..3768d83cd 100644 --- a/drivers/net/e1000/e1000_param.c +++ b/drivers/net/e1000/e1000_param.c @@ -268,7 +268,7 @@ e1000_validate_option(int *value, struct e1000_option *opt, BUG(); } - DPRINTK(PROBE, INFO, "Invalid %s value specified (%i) %s\n", + DPRINTK(PROBE, INFO, "Invalid %s specified (%i) %s\n", opt->name, *value, opt->err); *value = opt->def; return -1; diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 467fc8613..8c62ced2c 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -27,7 +27,7 @@ rx_align support: enables rx DMA without causing unaligned accesses. */ -static const char * const version = +static const char *version = "eepro100.c:v1.09j-t 9/29/99 Donald Becker http://www.scyld.com/network/eepro100.html\n" "eepro100.c: $Revision: 1.36 $ 2000/11/17 Modified by Andrey V. Savochkin and others\n"; @@ -469,7 +469,7 @@ static const char i82558_config_cmd[CONFIG_DATA_SIZE] = { 0x31, 0x05, }; /* PHY media interface chips. */ -static const char * const phys[] = { +static const char *phys[] = { "None", "i82553-A/B", "i82553-C", "i82503", "DP83840", "80c240", "80c24", "i82555", "unknown-8", "unknown-9", "DP83840A", "unknown-11", diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 2f7b86837..f119ec4e8 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -225,7 +225,7 @@ struct epic_chip_info { /* indexed by chip_t */ -static const struct epic_chip_info pci_id_tbl[] = { +static struct epic_chip_info pci_id_tbl[] = { { "SMSC EPIC/100 83c170", EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN }, { "SMSC EPIC/100 83c170", @@ -291,7 +291,7 @@ enum CommandBits { RxDone | RxStarted | RxEarlyWarn | RxOverflow | RxFull) #define EpicNormalEvent (0x0000ffff & ~EpicNapiEvent) -static const u16 media2miictl[16] = { +static u16 media2miictl[16] = { 0, 0x0C00, 0x0C00, 0x2000, 0x0100, 0x2100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/drivers/net/eql.c b/drivers/net/eql.c index 815436c61..aa1569182 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -203,7 +203,8 @@ static int eql_open(struct net_device *dev) printk(KERN_INFO "%s: remember to turn off Van-Jacobson compression on " "your slave devices.\n", dev->name); - BUG_ON(!list_empty(&eql->queue.all_slaves)); + if (!list_empty(&eql->queue.all_slaves)) + BUG(); eql->min_slaves = 1; eql->max_slaves = EQL_DEFAULT_MAX_SLAVES; /* 4 usually... */ diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index b67545be2..f32a6b3ac 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -161,7 +161,6 @@ static char *version = #include #include #include -#include #include #include @@ -755,7 +754,7 @@ static void eth16i_set_port(int ioaddr, int porttype) static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l) { - unsigned long starttime; + int starttime; outb(0xff, ioaddr + TX_STATUS_REG); @@ -766,7 +765,7 @@ static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l) outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) { - if( time_after(jiffies, starttime + TX_TIMEOUT)) { + if( (jiffies - starttime) > TX_TIMEOUT) { return -1; } } @@ -776,18 +775,18 @@ static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l) static int eth16i_receive_probe_packet(int ioaddr) { - unsigned long starttime; + int starttime; starttime = jiffies; while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) { - if( time_after(jiffies, starttime + TX_TIMEOUT)) { + if( (jiffies - starttime) > TX_TIMEOUT) { if(eth16i_debug > 1) printk(KERN_DEBUG "Timeout occurred waiting transmit packet received\n"); starttime = jiffies; while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) { - if( time_after(jiffies, starttime + TX_TIMEOUT)) { + if( (jiffies - starttime) > TX_TIMEOUT) { if(eth16i_debug > 1) printk(KERN_DEBUG "Timeout occurred waiting receive packet\n"); return -1; diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index a8449265e..55dbe9a3f 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -160,7 +160,7 @@ struct chip_info { int flags; }; -static const struct chip_info skel_netdrv_tbl[] = { +static struct chip_info skel_netdrv_tbl[] = { {"100/10M Ethernet PCI Adapter", 136, HAS_MII_XCVR}, {"100/10M Ethernet PCI Adapter", 136, HAS_CHIP_XCVR}, {"1000/100/10M Ethernet PCI Adapter", 136, HAS_MII_XCVR}, diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c index 7e4338097..b4f3a9f8a 100644 --- a/drivers/net/fec_8xx/fec_main.c +++ b/drivers/net/fec_8xx/fec_main.c @@ -55,11 +55,11 @@ MODULE_AUTHOR("Pantelis Antoniou "); MODULE_DESCRIPTION("Motorola 8xx FEC ethernet driver"); MODULE_LICENSE("GPL"); -int fec_8xx_debug = -1; /* -1 == use FEC_8XX_DEF_MSG_ENABLE as value */ -module_param(fec_8xx_debug, int, 0); +MODULE_PARM(fec_8xx_debug, "i"); MODULE_PARM_DESC(fec_8xx_debug, "FEC 8xx bitmapped debugging message enable value"); +int fec_8xx_debug = -1; /* -1 == use FEC_8XX_DEF_MSG_ENABLE as value */ /*************************************************/ diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 1a556957d..3682ec61e 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -102,11 +102,6 @@ * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan. * 0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single * 0.49: 10 Dec 2005: Fix tso for large buffers. - * 0.50: 20 Jan 2006: Add 8021pq tagging support. - * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings. - * 0.52: 20 Jan 2006: Add MSI/MSIX support. - * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. - * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -118,7 +113,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.54" +#define FORCEDETH_VERSION "0.49" #define DRV_NAME "forcedeth" #include @@ -136,7 +131,6 @@ #include #include #include -#include #include #include @@ -159,10 +153,6 @@ #define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */ #define DEV_HAS_HIGH_DMA 0x0008 /* device supports 64bit dma */ #define DEV_HAS_CHECKSUM 0x0010 /* device supports tx and rx checksum offloads */ -#define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */ -#define DEV_HAS_MSI 0x0040 /* device supports MSI */ -#define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ -#define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ enum { NvRegIrqStatus = 0x000, @@ -176,17 +166,14 @@ enum { #define NVREG_IRQ_TX_OK 0x0010 #define NVREG_IRQ_TIMER 0x0020 #define NVREG_IRQ_LINK 0x0040 -#define NVREG_IRQ_RX_FORCED 0x0080 -#define NVREG_IRQ_TX_FORCED 0x0100 +#define NVREG_IRQ_TX_ERROR 0x0080 +#define NVREG_IRQ_TX1 0x0100 #define NVREG_IRQMASK_THROUGHPUT 0x00df #define NVREG_IRQMASK_CPU 0x0040 -#define NVREG_IRQ_TX_ALL (NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED) -#define NVREG_IRQ_RX_ALL (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED) -#define NVREG_IRQ_OTHER (NVREG_IRQ_TIMER|NVREG_IRQ_LINK) #define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \ - NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RX_FORCED| \ - NVREG_IRQ_TX_FORCED)) + NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX_ERROR| \ + NVREG_IRQ_TX1)) NvRegUnknownSetupReg6 = 0x008, #define NVREG_UNKSETUP6_VAL 3 @@ -198,16 +185,10 @@ enum { NvRegPollingInterval = 0x00c, #define NVREG_POLL_DEFAULT_THROUGHPUT 970 #define NVREG_POLL_DEFAULT_CPU 13 - NvRegMSIMap0 = 0x020, - NvRegMSIMap1 = 0x024, - NvRegMSIIrqMask = 0x030, -#define NVREG_MSI_VECTOR_0_ENABLED 0x01 NvRegMisc1 = 0x080, #define NVREG_MISC1_HD 0x02 #define NVREG_MISC1_FORCE 0x3b0f3c - NvRegMacReset = 0x3c, -#define NVREG_MAC_RESET_ASSERT 0x0F3 NvRegTransmitterControl = 0x084, #define NVREG_XMITCTL_START 0x01 NvRegTransmitterStatus = 0x088, @@ -273,10 +254,6 @@ enum { #define NVREG_TXRXCTL_DESC_1 0 #define NVREG_TXRXCTL_DESC_2 0x02100 #define NVREG_TXRXCTL_DESC_3 0x02200 -#define NVREG_TXRXCTL_VLANSTRIP 0x00040 -#define NVREG_TXRXCTL_VLANINS 0x00080 - NvRegTxRingPhysAddrHigh = 0x148, - NvRegRxRingPhysAddrHigh = 0x14C, NvRegMIIStatus = 0x180, #define NVREG_MIISTAT_ERROR 0x0001 #define NVREG_MIISTAT_LINKCHANGE 0x0008 @@ -326,15 +303,6 @@ enum { #define NVREG_POWERSTATE_D1 0x0001 #define NVREG_POWERSTATE_D2 0x0002 #define NVREG_POWERSTATE_D3 0x0003 - NvRegVlanControl = 0x300, -#define NVREG_VLANCONTROL_ENABLE 0x2000 - NvRegMSIXMap0 = 0x3e0, - NvRegMSIXMap1 = 0x3e4, - NvRegMSIXIrqStatus = 0x3f0, - - NvRegPowerState2 = 0x600, -#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11 -#define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001 }; /* Big endian: should work, but is untested */ @@ -346,7 +314,7 @@ struct ring_desc { struct ring_desc_ex { u32 PacketBufferHigh; u32 PacketBufferLow; - u32 TxVlan; + u32 Reserved; u32 FlagLen; }; @@ -387,8 +355,6 @@ typedef union _ring_type { #define NV_TX2_CHECKSUM_L3 (1<<27) #define NV_TX2_CHECKSUM_L4 (1<<26) -#define NV_TX3_VLAN_TAG_PRESENT (1<<18) - #define NV_RX_DESCRIPTORVALID (1<<16) #define NV_RX_MISSEDFRAME (1<<17) #define NV_RX_SUBSTRACT1 (1<<18) @@ -419,12 +385,8 @@ typedef union _ring_type { #define NV_RX2_ERROR (1<<30) #define NV_RX2_AVAIL (1<<31) -#define NV_RX3_VLAN_TAG_PRESENT (1<<16) -#define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) - /* Miscelaneous hardware related defines: */ -#define NV_PCI_REGSZ_VER1 0x270 -#define NV_PCI_REGSZ_VER2 0x604 +#define NV_PCI_REGSZ 0x270 /* various timeout delays: all in usec */ #define NV_TXRX_RESET_DELAY 4 @@ -441,7 +403,6 @@ typedef union _ring_type { #define NV_MIIBUSY_DELAY 50 #define NV_MIIPHY_DELAY 10 #define NV_MIIPHY_DELAYMAX 10000 -#define NV_MAC_RESET_DELAY 64 #define NV_WAKEUPPATTERNS 5 #define NV_WAKEUPMASKENTRIES 4 @@ -514,18 +475,6 @@ typedef union _ring_type { #define LPA_1000FULL 0x0800 #define LPA_1000HALF 0x0400 -/* MSI/MSI-X defines */ -#define NV_MSI_X_MAX_VECTORS 8 -#define NV_MSI_X_VECTORS_MASK 0x000f -#define NV_MSI_CAPABLE 0x0010 -#define NV_MSI_X_CAPABLE 0x0020 -#define NV_MSI_ENABLED 0x0040 -#define NV_MSI_X_ENABLED 0x0080 - -#define NV_MSI_X_VECTOR_ALL 0x0 -#define NV_MSI_X_VECTOR_RX 0x0 -#define NV_MSI_X_VECTOR_TX 0x1 -#define NV_MSI_X_VECTOR_OTHER 0x2 /* * SMP locking: @@ -533,9 +482,9 @@ typedef union _ring_type { * critical parts: * - rx is (pseudo-) lockless: it relies on the single-threading provided * by the arch code for interrupts. - * - tx setup is lockless: it relies on netif_tx_lock. Actual submission + * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission * needs dev->priv->lock :-( - * - set_multicast_list: preparation lockless, relies on netif_tx_lock. + * - set_multicast_list: preparation lockless, relies on dev->xmit_lock. */ /* in dev: base, irq */ @@ -562,9 +511,6 @@ struct fe_priv { u32 irqmask; u32 desc_ver; u32 txrxctl_bits; - u32 vlanctl_bits; - u32 driver_data; - u32 register_size; void __iomem *base; @@ -579,7 +525,6 @@ struct fe_priv { unsigned int pkt_limit; struct timer_list oom_kick; struct timer_list nic_poll; - u32 nic_poll_irq; /* media detection workaround. * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); @@ -595,13 +540,6 @@ struct fe_priv { dma_addr_t tx_dma[TX_RING]; unsigned int tx_dma_len[TX_RING]; u32 tx_flags; - - /* vlan fields */ - struct vlan_group *vlangrp; - - /* msi/msi-x fields */ - u32 msi_flags; - struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS]; }; /* @@ -629,16 +567,6 @@ static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT; */ static int poll_interval = -1; -/* - * Disable MSI interrupts - */ -static int disable_msi = 0; - -/* - * Disable MSIX interrupts - */ -static int disable_msix = 0; - static inline struct fe_priv *get_nvpriv(struct net_device *dev) { return netdev_priv(dev); @@ -684,99 +612,6 @@ static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, return 0; } -#define NV_SETUP_RX_RING 0x01 -#define NV_SETUP_TX_RING 0x02 - -static void setup_hw_rings(struct net_device *dev, int rxtx_flags) -{ - struct fe_priv *np = get_nvpriv(dev); - u8 __iomem *base = get_hwbase(dev); - - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - if (rxtx_flags & NV_SETUP_RX_RING) { - writel((u32) cpu_to_le64(np->ring_addr), base + NvRegRxRingPhysAddr); - } - if (rxtx_flags & NV_SETUP_TX_RING) { - writel((u32) cpu_to_le64(np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); - } - } else { - if (rxtx_flags & NV_SETUP_RX_RING) { - writel((u32) cpu_to_le64(np->ring_addr), base + NvRegRxRingPhysAddr); - writel((u32) (cpu_to_le64(np->ring_addr) >> 32), base + NvRegRxRingPhysAddrHigh); - } - if (rxtx_flags & NV_SETUP_TX_RING) { - writel((u32) cpu_to_le64(np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); - writel((u32) (cpu_to_le64(np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)) >> 32), base + NvRegTxRingPhysAddrHigh); - } - } -} - -static int using_multi_irqs(struct net_device *dev) -{ - struct fe_priv *np = get_nvpriv(dev); - - if (!(np->msi_flags & NV_MSI_X_ENABLED) || - ((np->msi_flags & NV_MSI_X_ENABLED) && - ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) - return 0; - else - return 1; -} - -static void nv_enable_irq(struct net_device *dev) -{ - struct fe_priv *np = get_nvpriv(dev); - - if (!using_multi_irqs(dev)) { - if (np->msi_flags & NV_MSI_X_ENABLED) - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); - else - enable_irq(dev->irq); - } else { - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); - } -} - -static void nv_disable_irq(struct net_device *dev) -{ - struct fe_priv *np = get_nvpriv(dev); - - if (!using_multi_irqs(dev)) { - if (np->msi_flags & NV_MSI_X_ENABLED) - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); - else - disable_irq(dev->irq); - } else { - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); - } -} - -/* In MSIX mode, a write to irqmask behaves as XOR */ -static void nv_enable_hw_interrupts(struct net_device *dev, u32 mask) -{ - u8 __iomem *base = get_hwbase(dev); - - writel(mask, base + NvRegIrqMask); -} - -static void nv_disable_hw_interrupts(struct net_device *dev, u32 mask) -{ - struct fe_priv *np = get_nvpriv(dev); - u8 __iomem *base = get_hwbase(dev); - - if (np->msi_flags & NV_MSI_X_ENABLED) { - writel(mask, base + NvRegIrqMask); - } else { - if (np->msi_flags & NV_MSI_ENABLED) - writel(0, base + NvRegMSIIrqMask); - writel(0, base + NvRegIrqMask); - } -} - #define MII_READ (-1) /* mii_rw: read/write a register on the PHY. * @@ -998,24 +833,6 @@ static void nv_txrx_reset(struct net_device *dev) pci_push(base); } -static void nv_mac_reset(struct net_device *dev) -{ - struct fe_priv *np = netdev_priv(dev); - u8 __iomem *base = get_hwbase(dev); - - dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name); - writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); - pci_push(base); - writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset); - pci_push(base); - udelay(NV_MAC_RESET_DELAY); - writel(0, base + NvRegMacReset); - pci_push(base); - udelay(NV_MAC_RESET_DELAY); - writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl); - pci_push(base); -} - /* * nv_get_stats: dev->get_stats function * Get latest stats value from the nic. @@ -1086,28 +903,14 @@ static void nv_do_rx_refill(unsigned long data) struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); - if (!using_multi_irqs(dev)) { - if (np->msi_flags & NV_MSI_X_ENABLED) - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); - else - disable_irq(dev->irq); - } else { - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); - } + disable_irq(dev->irq); if (nv_alloc_rx(dev)) { - spin_lock_irq(&np->lock); + spin_lock(&np->lock); if (!np->in_shutdown) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock_irq(&np->lock); - } - if (!using_multi_irqs(dev)) { - if (np->msi_flags & NV_MSI_X_ENABLED) - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); - else - enable_irq(dev->irq); - } else { - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); + spin_unlock(&np->lock); } + enable_irq(dev->irq); } static void nv_init_rx(struct net_device *dev) @@ -1162,7 +965,7 @@ static int nv_release_txskb(struct net_device *dev, unsigned int skbnr) } if (np->tx_skbuff[skbnr]) { - dev_kfree_skb_any(np->tx_skbuff[skbnr]); + dev_kfree_skb_irq(np->tx_skbuff[skbnr]); np->tx_skbuff[skbnr] = NULL; return 1; } else { @@ -1213,7 +1016,7 @@ static void drain_ring(struct net_device *dev) /* * nv_start_xmit: dev->hard_start_xmit function - * Called with netif_tx_lock held. + * Called with dev->xmit_lock held. */ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -1228,7 +1031,6 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 bcnt; u32 size = skb->len-skb->data_len; u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); - u32 tx_flags_vlan = 0; /* add fragments to entries count */ for (i = 0; i < fragments; i++) { @@ -1303,22 +1105,16 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) np->tx_skbuff[nr] = skb; #ifdef NETIF_F_TSO - if (skb_is_gso(skb)) - tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); + if (skb_shinfo(skb)->tso_size) + tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT); else #endif tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); - /* vlan tag */ - if (np->vlangrp && vlan_tx_tag_present(skb)) { - tx_flags_vlan = NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb); - } - /* set tx flags */ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { np->tx_ring.orig[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra); } else { - np->tx_ring.ex[start_nr].TxVlan = cpu_to_le32(tx_flags_vlan); np->tx_ring.ex[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra); } @@ -1407,20 +1203,15 @@ static void nv_tx_done(struct net_device *dev) /* * nv_tx_timeout: dev->tx_timeout function - * Called with netif_tx_lock held. + * Called with dev->xmit_lock held. */ static void nv_tx_timeout(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - u32 status; - - if (np->msi_flags & NV_MSI_X_ENABLED) - status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; - else - status = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; - printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name, status); + printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name, + readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK); { int i; @@ -1429,7 +1220,7 @@ static void nv_tx_timeout(struct net_device *dev) dev->name, (unsigned long)np->ring_addr, np->next_tx, np->nic_tx); printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); - for (i=0;i<=np->register_size;i+= 32) { + for (i=0;i<0x400;i+= 32) { printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", i, readl(base + i + 0), readl(base + i + 4), @@ -1482,7 +1273,10 @@ static void nv_tx_timeout(struct net_device *dev) printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name); nv_drain_tx(dev); np->next_tx = np->nic_tx = 0; - setup_hw_rings(dev, NV_SETUP_TX_RING); + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) + writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); + else + writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); netif_wake_queue(dev); } @@ -1548,8 +1342,6 @@ static void nv_rx_process(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); u32 Flags; - u32 vlanflags = 0; - for (;;) { struct sk_buff *skb; @@ -1565,7 +1357,6 @@ static void nv_rx_process(struct net_device *dev) } else { Flags = le32_to_cpu(np->rx_ring.ex[i].FlagLen); len = nv_descr_getlength_ex(&np->rx_ring.ex[i], np->desc_ver); - vlanflags = le32_to_cpu(np->rx_ring.ex[i].PacketBufferLow); } dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", @@ -1683,11 +1474,7 @@ static void nv_rx_process(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); dprintk(KERN_DEBUG "%s: nv_rx_process: packet %d with %d bytes, proto %d accepted.\n", dev->name, np->cur_rx, len, skb->protocol); - if (np->vlangrp && (vlanflags & NV_RX3_VLAN_TAG_PRESENT)) { - vlan_hwaccel_rx(skb, np->vlangrp, vlanflags & NV_RX3_VLAN_TAG_MASK); - } else { - netif_rx(skb); - } + netif_rx(skb); dev->last_rx = jiffies; np->stats.rx_packets++; np->stats.rx_bytes += len; @@ -1737,7 +1524,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) * Changing the MTU is a rare event, it shouldn't matter. */ disable_irq(dev->irq); - netif_tx_lock_bh(dev); + spin_lock_bh(&dev->xmit_lock); spin_lock(&np->lock); /* stop engines */ nv_stop_rx(dev); @@ -1757,7 +1544,11 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) } /* reinit nic view of the rx queue */ writel(np->rx_buf_sz, base + NvRegOffloadConfig); - setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); + writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) + writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); + else + writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); pci_push(base); @@ -1768,7 +1559,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) nv_start_rx(dev); nv_start_tx(dev); spin_unlock(&np->lock); - netif_tx_unlock_bh(dev); + spin_unlock_bh(&dev->xmit_lock); enable_irq(dev->irq); } return 0; @@ -1803,7 +1594,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN); if (netif_running(dev)) { - netif_tx_lock_bh(dev); + spin_lock_bh(&dev->xmit_lock); spin_lock_irq(&np->lock); /* stop rx engine */ @@ -1815,7 +1606,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) /* restart rx engine */ nv_start_rx(dev); spin_unlock_irq(&np->lock); - netif_tx_unlock_bh(dev); + spin_unlock_bh(&dev->xmit_lock); } else { nv_copy_mac_to_hw(dev); } @@ -1824,7 +1615,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) /* * nv_set_multicast: dev->set_multicast function - * Called with netif_tx_lock held. + * Called with dev->xmit_lock held. */ static void nv_set_multicast(struct net_device *dev) { @@ -2075,13 +1866,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name); for (i=0; ; i++) { - if (!(np->msi_flags & NV_MSI_X_ENABLED)) { - events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; - writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); - } else { - events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; - writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); - } + events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; + writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); if (!(events & np->irqmask)) @@ -2121,16 +1907,11 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) if (i > max_interrupt_work) { spin_lock(&np->lock); /* disable interrupts on the nic */ - if (!(np->msi_flags & NV_MSI_X_ENABLED)) - writel(0, base + NvRegIrqMask); - else - writel(np->irqmask, base + NvRegIrqMask); + writel(0, base + NvRegIrqMask); pci_push(base); - if (!np->in_shutdown) { - np->nic_poll_irq = np->irqmask; + if (!np->in_shutdown) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); - } printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); break; @@ -2142,214 +1923,22 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) return IRQ_RETVAL(i); } -static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *) data; - struct fe_priv *np = netdev_priv(dev); - u8 __iomem *base = get_hwbase(dev); - u32 events; - int i; - - dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name); - - for (i=0; ; i++) { - events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; - writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus); - pci_push(base); - dprintk(KERN_DEBUG "%s: tx irq: %08x\n", dev->name, events); - if (!(events & np->irqmask)) - break; - - spin_lock_irq(&np->lock); - nv_tx_done(dev); - spin_unlock_irq(&np->lock); - - if (events & (NVREG_IRQ_TX_ERR)) { - dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", - dev->name, events); - } - if (i > max_interrupt_work) { - spin_lock_irq(&np->lock); - /* disable interrupts on the nic */ - writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask); - pci_push(base); - - if (!np->in_shutdown) { - np->nic_poll_irq |= NVREG_IRQ_TX_ALL; - mod_timer(&np->nic_poll, jiffies + POLL_WAIT); - } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); - spin_unlock_irq(&np->lock); - break; - } - - } - dprintk(KERN_DEBUG "%s: nv_nic_irq_tx completed\n", dev->name); - - return IRQ_RETVAL(i); -} - -static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *) data; - struct fe_priv *np = netdev_priv(dev); - u8 __iomem *base = get_hwbase(dev); - u32 events; - int i; - - dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name); - - for (i=0; ; i++) { - events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; - writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); - pci_push(base); - dprintk(KERN_DEBUG "%s: rx irq: %08x\n", dev->name, events); - if (!(events & np->irqmask)) - break; - - nv_rx_process(dev); - if (nv_alloc_rx(dev)) { - spin_lock_irq(&np->lock); - if (!np->in_shutdown) - mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock_irq(&np->lock); - } - - if (i > max_interrupt_work) { - spin_lock_irq(&np->lock); - /* disable interrupts on the nic */ - writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); - pci_push(base); - - if (!np->in_shutdown) { - np->nic_poll_irq |= NVREG_IRQ_RX_ALL; - mod_timer(&np->nic_poll, jiffies + POLL_WAIT); - } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); - spin_unlock_irq(&np->lock); - break; - } - - } - dprintk(KERN_DEBUG "%s: nv_nic_irq_rx completed\n", dev->name); - - return IRQ_RETVAL(i); -} - -static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *) data; - struct fe_priv *np = netdev_priv(dev); - u8 __iomem *base = get_hwbase(dev); - u32 events; - int i; - - dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name); - - for (i=0; ; i++) { - events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; - writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus); - pci_push(base); - dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); - if (!(events & np->irqmask)) - break; - - if (events & NVREG_IRQ_LINK) { - spin_lock_irq(&np->lock); - nv_link_irq(dev); - spin_unlock_irq(&np->lock); - } - if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { - spin_lock_irq(&np->lock); - nv_linkchange(dev); - spin_unlock_irq(&np->lock); - np->link_timeout = jiffies + LINK_TIMEOUT; - } - if (events & (NVREG_IRQ_UNKNOWN)) { - printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", - dev->name, events); - } - if (i > max_interrupt_work) { - spin_lock_irq(&np->lock); - /* disable interrupts on the nic */ - writel(NVREG_IRQ_OTHER, base + NvRegIrqMask); - pci_push(base); - - if (!np->in_shutdown) { - np->nic_poll_irq |= NVREG_IRQ_OTHER; - mod_timer(&np->nic_poll, jiffies + POLL_WAIT); - } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); - spin_unlock_irq(&np->lock); - break; - } - - } - dprintk(KERN_DEBUG "%s: nv_nic_irq_other completed\n", dev->name); - - return IRQ_RETVAL(i); -} - static void nv_do_nic_poll(unsigned long data) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - u32 mask = 0; + disable_irq(dev->irq); + /* FIXME: Do we need synchronize_irq(dev->irq) here? */ /* - * First disable irq(s) and then * reenable interrupts on the nic, we have to do this before calling * nv_nic_irq because that may decide to do otherwise */ - - if (!using_multi_irqs(dev)) { - if (np->msi_flags & NV_MSI_X_ENABLED) - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); - else - disable_irq(dev->irq); - mask = np->irqmask; - } else { - if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); - mask |= NVREG_IRQ_RX_ALL; - } - if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); - mask |= NVREG_IRQ_TX_ALL; - } - if (np->nic_poll_irq & NVREG_IRQ_OTHER) { - disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); - mask |= NVREG_IRQ_OTHER; - } - } - np->nic_poll_irq = 0; - - /* FIXME: Do we need synchronize_irq(dev->irq) here? */ - - writel(mask, base + NvRegIrqMask); + writel(np->irqmask, base + NvRegIrqMask); pci_push(base); - - if (!using_multi_irqs(dev)) { - nv_nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL); - if (np->msi_flags & NV_MSI_X_ENABLED) - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); - else - enable_irq(dev->irq); - } else { - if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { - nv_nic_irq_rx((int) 0, (void *) data, (struct pt_regs *) NULL); - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); - } - if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { - nv_nic_irq_tx((int) 0, (void *) data, (struct pt_regs *) NULL); - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); - } - if (np->nic_poll_irq & NVREG_IRQ_OTHER) { - nv_nic_irq_other((int) 0, (void *) data, (struct pt_regs *) NULL); - enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); - } - } + nv_nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL); + enable_irq(dev->irq); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -2572,11 +2161,11 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } #define FORCEDETH_REGS_VER 1 +#define FORCEDETH_REGS_SIZE 0x400 /* 256 32-bit registers */ static int nv_get_regs_len(struct net_device *dev) { - struct fe_priv *np = netdev_priv(dev); - return np->register_size; + return FORCEDETH_REGS_SIZE; } static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) @@ -2588,7 +2177,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void regs->version = FORCEDETH_REGS_VER; spin_lock_irq(&np->lock); - for (i = 0;i <= np->register_size/sizeof(u32); i++) + for (i=0;ilock); } @@ -2615,18 +2204,6 @@ static int nv_nway_reset(struct net_device *dev) return ret; } -#ifdef NETIF_F_TSO -static int nv_set_tso(struct net_device *dev, u32 value) -{ - struct fe_priv *np = netdev_priv(dev); - - if ((np->driver_data & DEV_HAS_CHECKSUM)) - return ethtool_op_set_tso(dev, value); - else - return value ? -EOPNOTSUPP : 0; -} -#endif - static struct ethtool_ops ops = { .get_drvinfo = nv_get_drvinfo, .get_link = ethtool_op_get_link, @@ -2638,185 +2215,17 @@ static struct ethtool_ops ops = { .get_regs = nv_get_regs, .nway_reset = nv_nway_reset, .get_perm_addr = ethtool_op_get_perm_addr, -#ifdef NETIF_F_TSO - .get_tso = ethtool_op_get_tso, - .set_tso = nv_set_tso -#endif }; -static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct fe_priv *np = get_nvpriv(dev); - - spin_lock_irq(&np->lock); - - /* save vlan group */ - np->vlangrp = grp; - - if (grp) { - /* enable vlan on MAC */ - np->txrxctl_bits |= NVREG_TXRXCTL_VLANSTRIP | NVREG_TXRXCTL_VLANINS; - } else { - /* disable vlan on MAC */ - np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANSTRIP; - np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANINS; - } - - writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); - - spin_unlock_irq(&np->lock); -}; - -static void nv_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -{ - /* nothing to do */ -}; - -static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask) -{ - u8 __iomem *base = get_hwbase(dev); - int i; - u32 msixmap = 0; - - /* Each interrupt bit can be mapped to a MSIX vector (4 bits). - * MSIXMap0 represents the first 8 interrupts and MSIXMap1 represents - * the remaining 8 interrupts. - */ - for (i = 0; i < 8; i++) { - if ((irqmask >> i) & 0x1) { - msixmap |= vector << (i << 2); - } - } - writel(readl(base + NvRegMSIXMap0) | msixmap, base + NvRegMSIXMap0); - - msixmap = 0; - for (i = 0; i < 8; i++) { - if ((irqmask >> (i + 8)) & 0x1) { - msixmap |= vector << (i << 2); - } - } - writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1); -} - -static int nv_request_irq(struct net_device *dev) -{ - struct fe_priv *np = get_nvpriv(dev); - u8 __iomem *base = get_hwbase(dev); - int ret = 1; - int i; - - if (np->msi_flags & NV_MSI_X_CAPABLE) { - for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { - np->msi_x_entry[i].entry = i; - } - if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) { - np->msi_flags |= NV_MSI_X_ENABLED; - if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) { - /* Request irq for rx handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret); - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - goto out_err; - } - /* Request irq for tx handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret); - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - goto out_free_rx; - } - /* Request irq for link and timer handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret); - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - goto out_free_tx; - } - /* map interrupts to their respective vector */ - writel(0, base + NvRegMSIXMap0); - writel(0, base + NvRegMSIXMap1); - set_msix_vector_map(dev, NV_MSI_X_VECTOR_RX, NVREG_IRQ_RX_ALL); - set_msix_vector_map(dev, NV_MSI_X_VECTOR_TX, NVREG_IRQ_TX_ALL); - set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER); - } else { - /* Request irq for all interrupts */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - goto out_err; - } - - /* map interrupts to vector 0 */ - writel(0, base + NvRegMSIXMap0); - writel(0, base + NvRegMSIXMap1); - } - } - } - if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { - if ((ret = pci_enable_msi(np->pci_dev)) == 0) { - np->msi_flags |= NV_MSI_ENABLED; - if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) { - printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); - pci_disable_msi(np->pci_dev); - np->msi_flags &= ~NV_MSI_ENABLED; - goto out_err; - } - - /* map interrupts to vector 0 */ - writel(0, base + NvRegMSIMap0); - writel(0, base + NvRegMSIMap1); - /* enable msi vector 0 */ - writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); - } - } - if (ret != 0) { - if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) - goto out_err; - } - - return 0; -out_free_tx: - free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, dev); -out_free_rx: - free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, dev); -out_err: - return 1; -} - -static void nv_free_irq(struct net_device *dev) -{ - struct fe_priv *np = get_nvpriv(dev); - int i; - - if (np->msi_flags & NV_MSI_X_ENABLED) { - for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { - free_irq(np->msi_x_entry[i].vector, dev); - } - pci_disable_msix(np->pci_dev); - np->msi_flags &= ~NV_MSI_X_ENABLED; - } else { - free_irq(np->pci_dev->irq, dev); - if (np->msi_flags & NV_MSI_ENABLED) { - pci_disable_msi(np->pci_dev); - np->msi_flags &= ~NV_MSI_ENABLED; - } - } -} - static int nv_open(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - int ret = 1; - int oom, i; + int ret, oom, i; dprintk(KERN_DEBUG "nv_open: begin\n"); /* 1) erase previous misconfiguration */ - if (np->driver_data & DEV_HAS_POWER_CNTRL) - nv_mac_reset(dev); /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */ writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); writel(0, base + NvRegMulticastAddrB); @@ -2844,7 +2253,11 @@ static int nv_open(struct net_device *dev) nv_copy_mac_to_hw(dev); /* 4) give hw rings */ - setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); + writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) + writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); + else + writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); @@ -2852,7 +2265,6 @@ static int nv_open(struct net_device *dev) writel(np->linkspeed, base + NvRegLinkSpeed); writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3); writel(np->txrxctl_bits, base + NvRegTxRxControl); - writel(np->vlanctl_bits, base + NvRegVlanControl); pci_push(base); writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl); reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, @@ -2897,18 +2309,18 @@ static int nv_open(struct net_device *dev) udelay(10); writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState); - nv_disable_hw_interrupts(dev, np->irqmask); + writel(0, base + NvRegIrqMask); pci_push(base); writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); - if (nv_request_irq(dev)) { + ret = request_irq(dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev); + if (ret) goto out_drain; - } /* ask for interrupts */ - nv_enable_hw_interrupts(dev, np->irqmask); + writel(np->irqmask, base + NvRegIrqMask); spin_lock_irq(&np->lock); writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); @@ -2969,13 +2381,13 @@ static int nv_close(struct net_device *dev) /* disable interrupts on the nic or we will lock up */ base = get_hwbase(dev); - nv_disable_hw_interrupts(dev, np->irqmask); + writel(0, base + NvRegIrqMask); pci_push(base); dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name); spin_unlock_irq(&np->lock); - nv_free_irq(dev); + free_irq(dev->irq, dev); drain_ring(dev); @@ -3000,7 +2412,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i unsigned long addr; u8 __iomem *base; int err, i; - u32 powerstate; dev = alloc_etherdev(sizeof(struct fe_priv)); err = -ENOMEM; @@ -3033,11 +2444,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (err < 0) goto out_disable; - if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL)) - np->register_size = NV_PCI_REGSZ_VER2; - else - np->register_size = NV_PCI_REGSZ_VER1; - err = -EINVAL; addr = 0; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { @@ -3046,7 +2452,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i pci_resource_len(pci_dev, i), pci_resource_flags(pci_dev, i)); if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && - pci_resource_len(pci_dev, i) >= np->register_size) { + pci_resource_len(pci_dev, i) >= NV_PCI_REGSZ) { addr = pci_resource_start(pci_dev, i); break; } @@ -3057,25 +2463,17 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i goto out_relreg; } - /* copy of driver data */ - np->driver_data = id->driver_data; - /* handle different descriptor versions */ if (id->driver_data & DEV_HAS_HIGH_DMA) { /* packet format 3: supports 40-bit addressing */ np->desc_ver = DESC_VER_3; - np->txrxctl_bits = NVREG_TXRXCTL_DESC_3; - if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) { + if (pci_set_dma_mask(pci_dev, 0x0000007fffffffffULL)) { printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n", pci_name(pci_dev)); } else { dev->features |= NETIF_F_HIGHDMA; - printk(KERN_INFO "forcedeth: using HIGHDMA\n"); - } - if (pci_set_consistent_dma_mask(pci_dev, 0x0000007fffffffffULL)) { - printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed for device %s.\n", - pci_name(pci_dev)); } + np->txrxctl_bits = NVREG_TXRXCTL_DESC_3; } else if (id->driver_data & DEV_HAS_LARGEDESC) { /* packet format 2: supports jumbo frames */ np->desc_ver = DESC_VER_2; @@ -3098,24 +2496,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i #endif } - np->vlanctl_bits = 0; - if (id->driver_data & DEV_HAS_VLAN) { - np->vlanctl_bits = NVREG_VLANCONTROL_ENABLE; - dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX; - dev->vlan_rx_register = nv_vlan_rx_register; - dev->vlan_rx_kill_vid = nv_vlan_rx_kill_vid; - } - - np->msi_flags = 0; - if ((id->driver_data & DEV_HAS_MSI) && !disable_msi) { - np->msi_flags |= NV_MSI_CAPABLE; - } - if ((id->driver_data & DEV_HAS_MSI_X) && !disable_msix) { - np->msi_flags |= NV_MSI_X_CAPABLE; - } - err = -ENOMEM; - np->base = ioremap(addr, np->register_size); + np->base = ioremap(addr, NV_PCI_REGSZ); if (!np->base) goto out_relreg; dev->base_addr = (unsigned long)np->base; @@ -3191,34 +2573,15 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; - if (id->driver_data & DEV_HAS_POWER_CNTRL) { - u8 revision_id; - pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id); - - /* take phy and nic out of low power mode */ - powerstate = readl(base + NvRegPowerState2); - powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; - if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 || - id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) && - revision_id >= 0xA3) - powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; - writel(powerstate, base + NvRegPowerState2); - } - if (np->desc_ver == DESC_VER_1) { np->tx_flags = NV_TX_VALID; } else { np->tx_flags = NV_TX2_VALID; } - if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) { + if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) np->irqmask = NVREG_IRQMASK_THROUGHPUT; - if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */ - np->msi_flags |= 0x0003; - } else { + else np->irqmask = NVREG_IRQMASK_CPU; - if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */ - np->msi_flags |= 0x0001; - } if (id->driver_data & DEV_NEED_TIMERIRQ) np->irqmask |= NVREG_IRQ_TIMER; @@ -3366,19 +2729,19 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA, }, {0,}, }; @@ -3408,10 +2771,6 @@ module_param(optimization_mode, int, 0); MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer."); module_param(poll_interval, int, 0); MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535."); -module_param(disable_msi, int, 0); -MODULE_PARM_DESC(disable_msi, "Disable MSI interrupts by setting to 1."); -module_param(disable_msix, int, 0); -MODULE_PARM_DESC(disable_msix, "Disable MSIX interrupts by setting to 1."); MODULE_AUTHOR("Manfred Spraul "); MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 196298f33..f5d49a110 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -58,11 +58,11 @@ MODULE_DESCRIPTION("Freescale Ethernet Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); -int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */ -module_param(fs_enet_debug, int, 0); +MODULE_PARM(fs_enet_debug, "i"); MODULE_PARM_DESC(fs_enet_debug, "Freescale bitmapped debugging message enable value"); +int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */ static void fs_set_multicast_list(struct net_device *dev) { diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 95e2bb8dd..e67b1d066 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -118,8 +118,6 @@ static int do_pd_setup(struct fs_enet_private *fep) /* Fill out IRQ field */ fep->interrupt = platform_get_irq(pdev, 0); - if (fep->interrupt < 0) - return -EINVAL; /* Attach the memory for the FCC Parameter RAM */ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram"); diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index 3dad69dfd..2e8f44469 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -144,8 +144,6 @@ static int do_pd_setup(struct fs_enet_private *fep) /* Fill out IRQ field */ fep->interrupt = platform_get_irq_byname(pdev,"interrupt"); - if (fep->interrupt < 0) - return -EINVAL; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); fep->fec.fecp =(void*)r->start; diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index a772b286f..a3897fda7 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -118,8 +118,6 @@ static int do_pd_setup(struct fs_enet_private *fep) /* Fill out IRQ field */ fep->interrupt = platform_get_irq_byname(pdev, "interrupt"); - if (fep->interrupt < 0) - return -EINVAL; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); fep->scc.sccp = (void *)r->start; diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 218d31764..0e8e3fcde 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -193,12 +193,8 @@ static int gfar_probe(struct platform_device *pdev) priv->interruptTransmit = platform_get_irq_byname(pdev, "tx"); priv->interruptReceive = platform_get_irq_byname(pdev, "rx"); priv->interruptError = platform_get_irq_byname(pdev, "error"); - if (priv->interruptTransmit < 0 || priv->interruptReceive < 0 || priv->interruptError < 0) - goto regs_fail; } else { priv->interruptTransmit = platform_get_irq(pdev, 0); - if (priv->interruptTransmit < 0) - goto regs_fail; } /* get a pointer to the register memory */ @@ -210,8 +206,7 @@ static int gfar_probe(struct platform_device *pdev) goto regs_fail; } - spin_lock_init(&priv->txlock); - spin_lock_init(&priv->rxlock); + spin_lock_init(&priv->lock); platform_set_drvdata(pdev, dev); @@ -516,13 +511,11 @@ void stop_gfar(struct net_device *dev) phy_stop(priv->phydev); /* Lock it down */ - spin_lock_irqsave(&priv->txlock, flags); - spin_lock(&priv->rxlock); + spin_lock_irqsave(&priv->lock, flags); gfar_halt(dev); - spin_unlock(&priv->rxlock); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); /* Free the IRQs */ if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { @@ -608,15 +601,14 @@ void gfar_start(struct net_device *dev) tempval |= DMACTRL_INIT_SETTINGS; gfar_write(&priv->regs->dmactrl, tempval); + /* Clear THLT, so that the DMA starts polling now */ + gfar_write(®s->tstat, TSTAT_CLEAR_THALT); + /* Make sure we aren't stopped */ tempval = gfar_read(&priv->regs->dmactrl); tempval &= ~(DMACTRL_GRS | DMACTRL_GTS); gfar_write(&priv->regs->dmactrl, tempval); - /* Clear THLT/RHLT, so that the DMA starts polling now */ - gfar_write(®s->tstat, TSTAT_CLEAR_THALT); - gfar_write(®s->rstat, RSTAT_CLEAR_RHALT); - /* Unmask the interrupts we look for */ gfar_write(®s->imask, IMASK_DEFAULT); } @@ -932,13 +924,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) struct txfcb *fcb = NULL; struct txbd8 *txbdp; u16 status; - unsigned long flags; /* Update transmit stats */ priv->stats.tx_bytes += skb->len; /* Lock priv now */ - spin_lock_irqsave(&priv->txlock, flags); + spin_lock_irq(&priv->lock); /* Point at the first free tx descriptor */ txbdp = priv->cur_tx; @@ -1009,7 +1000,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT); /* Unlock priv */ - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irq(&priv->lock); return 0; } @@ -1054,7 +1045,7 @@ static void gfar_vlan_rx_register(struct net_device *dev, unsigned long flags; u32 tempval; - spin_lock_irqsave(&priv->rxlock, flags); + spin_lock_irqsave(&priv->lock, flags); priv->vlgrp = grp; @@ -1081,7 +1072,7 @@ static void gfar_vlan_rx_register(struct net_device *dev, gfar_write(&priv->regs->rctrl, tempval); } - spin_unlock_irqrestore(&priv->rxlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); } @@ -1090,12 +1081,12 @@ static void gfar_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) struct gfar_private *priv = netdev_priv(dev); unsigned long flags; - spin_lock_irqsave(&priv->rxlock, flags); + spin_lock_irqsave(&priv->lock, flags); if (priv->vlgrp) priv->vlgrp->vlan_devices[vid] = NULL; - spin_unlock_irqrestore(&priv->rxlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); } @@ -1184,7 +1175,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs) gfar_write(&priv->regs->ievent, IEVENT_TX_MASK); /* Lock priv */ - spin_lock(&priv->txlock); + spin_lock(&priv->lock); bdp = priv->dirty_tx; while ((bdp->status & TXBD_READY) == 0) { /* If dirty_tx and cur_tx are the same, then either the */ @@ -1229,7 +1220,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs) else gfar_write(&priv->regs->txic, 0); - spin_unlock(&priv->txlock); + spin_unlock(&priv->lock); return IRQ_HANDLED; } @@ -1310,10 +1301,9 @@ irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct gfar_private *priv = netdev_priv(dev); + #ifdef CONFIG_GFAR_NAPI u32 tempval; -#else - unsigned long flags; #endif /* Clear IEVENT, so rx interrupt isn't called again @@ -1336,7 +1326,7 @@ irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs) } #else - spin_lock_irqsave(&priv->rxlock, flags); + spin_lock(&priv->lock); gfar_clean_rx_ring(dev, priv->rx_ring_size); /* If we are coalescing interrupts, update the timer */ @@ -1347,7 +1337,7 @@ irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs) else gfar_write(&priv->regs->rxic, 0); - spin_unlock_irqrestore(&priv->rxlock, flags); + spin_unlock(&priv->lock); #endif return IRQ_HANDLED; @@ -1496,6 +1486,13 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) /* Update the current rxbd pointer to be the next one */ priv->cur_rx = bdp; + /* If no packets have arrived since the + * last one we processed, clear the IEVENT RX and + * BSY bits so that another interrupt won't be + * generated when we set IMASK */ + if (bdp->status & RXBD_EMPTY) + gfar_write(&priv->regs->ievent, IEVENT_RX_MASK); + return howmany; } @@ -1515,7 +1512,7 @@ static int gfar_poll(struct net_device *dev, int *budget) rx_work_limit -= howmany; *budget -= howmany; - if (rx_work_limit > 0) { + if (rx_work_limit >= 0) { netif_rx_complete(dev); /* Clear the halt bit in RSTAT */ @@ -1532,8 +1529,7 @@ static int gfar_poll(struct net_device *dev, int *budget) gfar_write(&priv->regs->rxic, 0); } - /* Return 1 if there's more work to do */ - return (rx_work_limit > 0) ? 0 : 1; + return (rx_work_limit < 0) ? 1 : 0; } #endif @@ -1629,7 +1625,7 @@ static void adjust_link(struct net_device *dev) struct phy_device *phydev = priv->phydev; int new_state = 0; - spin_lock_irqsave(&priv->txlock, flags); + spin_lock_irqsave(&priv->lock, flags); if (phydev->link) { u32 tempval = gfar_read(®s->maccfg2); u32 ecntrl = gfar_read(®s->ecntrl); @@ -1694,7 +1690,7 @@ static void adjust_link(struct net_device *dev) if (new_state && netif_msg_link(priv)) phy_print_status(phydev); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); } /* Update the hash table based on the current list of multicast diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 127c98cf3..d37d5401b 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -656,62 +656,43 @@ struct gfar { * the buffer descriptor determines the actual condition. */ struct gfar_private { - /* Fields controlled by TX lock */ - spinlock_t txlock; - - /* Pointer to the array of skbuffs */ + /* pointers to arrays of skbuffs for tx and rx */ struct sk_buff ** tx_skbuff; + struct sk_buff ** rx_skbuff; - /* next free skb in the array */ + /* indices pointing to the next free sbk in skb arrays */ u16 skb_curtx; + u16 skb_currx; - /* First skb in line to be transmitted */ + /* index of the first skb which hasn't been transmitted + * yet. */ u16 skb_dirtytx; /* Configuration info for the coalescing features */ unsigned char txcoalescing; unsigned short txcount; unsigned short txtime; - - /* Buffer descriptor pointers */ - struct txbd8 *tx_bd_base; /* First tx buffer descriptor */ - struct txbd8 *cur_tx; /* Next free ring entry */ - struct txbd8 *dirty_tx; /* First buffer in line - to be transmitted */ - unsigned int tx_ring_size; - - /* RX Locked fields */ - spinlock_t rxlock; - - /* skb array and index */ - struct sk_buff ** rx_skbuff; - u16 skb_currx; - - /* RX Coalescing values */ unsigned char rxcoalescing; unsigned short rxcount; unsigned short rxtime; - struct rxbd8 *rx_bd_base; /* First Rx buffers */ + /* GFAR addresses */ + struct rxbd8 *rx_bd_base; /* Base addresses of Rx and Tx Buffers */ + struct txbd8 *tx_bd_base; struct rxbd8 *cur_rx; /* Next free rx ring entry */ - - /* RX parameters */ - unsigned int rx_ring_size; + struct txbd8 *cur_tx; /* Next free ring entry */ + struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ + struct gfar __iomem *regs; /* Pointer to the GFAR memory mapped Registers */ + u32 __iomem *hash_regs[16]; + int hash_width; + struct net_device_stats stats; /* linux network statistics */ + struct gfar_extra_stats extra_stats; + spinlock_t lock; unsigned int rx_buffer_size; unsigned int rx_stash_size; unsigned int rx_stash_index; - - struct vlan_group *vlgrp; - - /* Unprotected fields */ - /* Pointer to the GFAR memory mapped Registers */ - struct gfar __iomem *regs; - - /* Hash registers and their width */ - u32 __iomem *hash_regs[16]; - int hash_width; - - /* global parameters */ + unsigned int tx_ring_size; + unsigned int rx_ring_size; unsigned int fifo_threshold; unsigned int fifo_starve; unsigned int fifo_starve_off; @@ -721,15 +702,13 @@ struct gfar_private { extended_hash:1, bd_stash_en:1; unsigned short padding; - + struct vlan_group *vlgrp; + /* Info structure initialized by board setup code */ unsigned int interruptTransmit; unsigned int interruptReceive; unsigned int interruptError; - - /* info structure initialized by platform code */ struct gianfar_platform_data *einfo; - /* PHY stuff */ struct phy_device *phydev; struct mii_bus *mii_bus; int oldspeed; @@ -737,10 +716,6 @@ struct gfar_private { int oldlink; uint32_t msg_enable; - - /* Network Statistics */ - struct net_device_stats stats; - struct gfar_extra_stats extra_stats; }; static inline u32 gfar_read(volatile unsigned __iomem *addr) diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index d69698c69..5de7b2e25 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -455,14 +455,10 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva /* Halt TX and RX, and process the frames which * have already been received */ - spin_lock_irqsave(&priv->txlock, flags); - spin_lock(&priv->rxlock); - + spin_lock_irqsave(&priv->lock, flags); gfar_halt(dev); gfar_clean_rx_ring(dev, priv->rx_ring_size); - - spin_unlock(&priv->rxlock); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); /* Now we take down the rings to rebuild them */ stop_gfar(dev); @@ -492,14 +488,10 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) /* Halt TX and RX, and process the frames which * have already been received */ - spin_lock_irqsave(&priv->txlock, flags); - spin_lock(&priv->rxlock); - + spin_lock_irqsave(&priv->lock, flags); gfar_halt(dev); gfar_clean_rx_ring(dev, priv->rx_ring_size); - - spin_unlock(&priv->rxlock); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); /* Now we take down the rings to rebuild them */ stop_gfar(dev); @@ -531,7 +523,7 @@ static int gfar_set_tx_csum(struct net_device *dev, uint32_t data) if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) return -EOPNOTSUPP; - spin_lock_irqsave(&priv->txlock, flags); + spin_lock_irqsave(&priv->lock, flags); gfar_halt(dev); if (data) @@ -540,7 +532,7 @@ static int gfar_set_tx_csum(struct net_device *dev, uint32_t data) dev->features &= ~NETIF_F_IP_CSUM; gfar_start(dev); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); return 0; } diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c index a6d5c4319..51ef181b1 100644 --- a/drivers/net/gianfar_sysfs.c +++ b/drivers/net/gianfar_sysfs.c @@ -82,7 +82,7 @@ static ssize_t gfar_set_bd_stash(struct class_device *cdev, else return count; - spin_lock_irqsave(&priv->rxlock, flags); + spin_lock_irqsave(&priv->lock, flags); /* Set the new stashing value */ priv->bd_stash_en = new_setting; @@ -96,7 +96,7 @@ static ssize_t gfar_set_bd_stash(struct class_device *cdev, gfar_write(&priv->regs->attr, temp); - spin_unlock_irqrestore(&priv->rxlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); return count; } @@ -118,7 +118,7 @@ static ssize_t gfar_set_rx_stash_size(struct class_device *cdev, u32 temp; unsigned long flags; - spin_lock_irqsave(&priv->rxlock, flags); + spin_lock_irqsave(&priv->lock, flags); if (length > priv->rx_buffer_size) return count; @@ -142,7 +142,7 @@ static ssize_t gfar_set_rx_stash_size(struct class_device *cdev, gfar_write(&priv->regs->attr, temp); - spin_unlock_irqrestore(&priv->rxlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); return count; } @@ -166,7 +166,7 @@ static ssize_t gfar_set_rx_stash_index(struct class_device *cdev, u32 temp; unsigned long flags; - spin_lock_irqsave(&priv->rxlock, flags); + spin_lock_irqsave(&priv->lock, flags); if (index > priv->rx_stash_size) return count; @@ -180,7 +180,7 @@ static ssize_t gfar_set_rx_stash_index(struct class_device *cdev, temp |= ATTRELI_EI(index); gfar_write(&priv->regs->attreli, flags); - spin_unlock_irqrestore(&priv->rxlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); return count; } @@ -205,7 +205,7 @@ static ssize_t gfar_set_fifo_threshold(struct class_device *cdev, if (length > GFAR_MAX_FIFO_THRESHOLD) return count; - spin_lock_irqsave(&priv->txlock, flags); + spin_lock_irqsave(&priv->lock, flags); priv->fifo_threshold = length; @@ -214,7 +214,7 @@ static ssize_t gfar_set_fifo_threshold(struct class_device *cdev, temp |= length; gfar_write(&priv->regs->fifo_tx_thr, temp); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); return count; } @@ -240,7 +240,7 @@ static ssize_t gfar_set_fifo_starve(struct class_device *cdev, if (num > GFAR_MAX_FIFO_STARVE) return count; - spin_lock_irqsave(&priv->txlock, flags); + spin_lock_irqsave(&priv->lock, flags); priv->fifo_starve = num; @@ -249,7 +249,7 @@ static ssize_t gfar_set_fifo_starve(struct class_device *cdev, temp |= num; gfar_write(&priv->regs->fifo_tx_starve, temp); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); return count; } @@ -274,7 +274,7 @@ static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev, if (num > GFAR_MAX_FIFO_STARVE_OFF) return count; - spin_lock_irqsave(&priv->txlock, flags); + spin_lock_irqsave(&priv->lock, flags); priv->fifo_starve_off = num; @@ -283,7 +283,7 @@ static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev, temp |= num; gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock_irqrestore(&priv->lock, flags); return count; } diff --git a/drivers/net/gt96100eth.c b/drivers/net/gt96100eth.c index 2d2435404..5958a6314 100644 --- a/drivers/net/gt96100eth.c +++ b/drivers/net/gt96100eth.c @@ -114,8 +114,8 @@ static int max_interrupt_work = 32; static char mac0[18] = "00.02.03.04.05.06"; static char mac1[18] = "00.01.02.03.04.05"; -module_param_string(mac0, mac0, 18, 0); -module_param_string(mac1, mac0, 18, 0); +MODULE_PARM(mac0, "c18"); +MODULE_PARM(mac1, "c18"); MODULE_PARM_DESC(mac0, "MAC address for GT96100 ethernet port 0"); MODULE_PARM_DESC(mac1, "MAC address for GT96100 ethernet port 1"); diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 0ea4cb4a0..bc9a3bf8d 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -427,7 +427,7 @@ that case. static void hamachi_timer(unsigned long data); enum capability_flags {CanHaveMII=1, }; -static const struct chip_info { +static struct chip_info { u16 vendor_id, device_id, device_id_mask, pad; const char *name; void (*media_timer)(unsigned long data); diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index d12605f0a..d1f689586 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr_ax25 *sa = addr; - netif_tx_lock_bh(dev); + spin_lock_irq(&dev->xmit_lock); memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); - netif_tx_unlock_bh(dev); + spin_unlock_irq(&dev->xmit_lock); return 0; } @@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file, break; } - netif_tx_lock_bh(dev); + spin_lock_irq(&dev->xmit_lock); memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN); - netif_tx_unlock_bh(dev); + spin_unlock_irq(&dev->xmit_lock); err = 0; break; @@ -915,7 +915,7 @@ static void decode_prio_command(struct sixpack *sp, unsigned char cmd) printk(KERN_DEBUG "6pack: protocol violation\n"); else sp->status = 0; - cmd &= !SIXP_RX_DCD_MASK; + cmd &= ~SIXP_RX_DCD_MASK; } sp->status = cmd & SIXP_PRIO_DATA_MASK; } else { /* output watchdog char if idle */ diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 9220de9f4..e4188d082 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -905,7 +905,7 @@ static int epp_open(struct net_device *dev) /* autoprobe baud rate */ tstart = jiffies; i = 0; - while (time_before(jiffies, tstart + HZ/3)) { + while ((signed)(jiffies-tstart-HZ/3) < 0) { if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) goto epptimeout; if ((stat & (EPP_NRAEF|EPP_NRHF)) == EPP_NRHF) { diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 0d5fccc98..c8dc40214 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -280,7 +280,7 @@ static unsigned long rand; MODULE_AUTHOR("Klaus Kudielka"); MODULE_DESCRIPTION("Driver for high-speed SCC boards"); -module_param_array(io, int, NULL, 0); +MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i"); MODULE_LICENSE("GPL"); static void __exit dmascc_exit(void) @@ -582,6 +582,7 @@ static int __init setup_adapter(int card_base, int type, int n) INIT_WORK(&priv->rx_work, rx_bh, priv); dev->priv = priv; sprintf(dev->name, "dmascc%i", 2 * n + i); + SET_MODULE_OWNER(dev); dev->base_addr = card_base; dev->irq = irq; dev->open = scc_open; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 3ebbbe56b..dc5e9d59d 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr_ax25 *sa = addr; - netif_tx_lock_bh(dev); + spin_lock_irq(&dev->xmit_lock); memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); - netif_tx_unlock_bh(dev); + spin_unlock_irq(&dev->xmit_lock); return 0; } @@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file, break; } - netif_tx_lock_bh(dev); + spin_lock_irq(&dev->xmit_lock); memcpy(dev->dev_addr, addr, AX25_ADDR_LEN); - netif_tx_unlock_bh(dev); + spin_unlock_irq(&dev->xmit_lock); err = 0; break; @@ -1012,7 +1012,7 @@ static void __exit mkiss_exit_driver(void) MODULE_AUTHOR("Ralf Baechle DL5RB "); MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); -module_param(crc_force, int, 0); +MODULE_PARM(crc_force, "i"); MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]"); MODULE_LICENSE("GPL"); MODULE_ALIAS_LDISC(N_AX25); diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 5927784df..6ace0e914 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -1550,6 +1550,7 @@ static unsigned char ax25_nocall[AX25_ADDR_LEN] = static void scc_net_setup(struct net_device *dev) { + SET_MODULE_OWNER(dev); dev->tx_queue_len = 16; /* should be enough... */ dev->open = scc_net_open; diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index b49884048..fe22479eb 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -1098,6 +1098,7 @@ static void yam_setup(struct net_device *dev) dev->base_addr = yp->iobase; dev->irq = yp->irq; + SET_MODULE_OWNER(dev); dev->open = yam_open; dev->stop = yam_close; diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 0d7a6250e..74e167e7d 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -250,12 +250,6 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) ei_status.block_output = &hpp_mem_block_output; ei_status.get_8390_hdr = &hpp_mem_get_8390_hdr; dev->mem_start = mem_start; - ei_status.mem = ioremap(mem_start, - (HP_STOP_PG - HP_START_PG)*256); - if (!ei_status.mem) { - retval = -ENOMEM; - goto out; - } ei_status.rmem_start = dev->mem_start + TX_PAGES/2*256; dev->mem_end = ei_status.rmem_end = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256; @@ -268,10 +262,8 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) retval = register_netdev(dev); if (retval) - goto out1; + goto out; return 0; -out1: - iounmap(ei_status.mem); out: release_region(ioaddr, HP_IO_EXTENT); return retval; @@ -380,7 +372,7 @@ hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring outw((ring_page<<8), ioaddr + HPP_IN_ADDR); outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION); - memcpy_fromio(hdr, ei_status.mem, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, dev->mem_start, sizeof(struct e8390_pkt_hdr)); outw(option_reg, ioaddr + HPP_OPTION); hdr->count = (le16_to_cpu(hdr->count) + 3) & ~3; /* Round up allocation. */ } @@ -399,7 +391,7 @@ hpp_mem_block_input(struct net_device *dev, int count, struct sk_buff *skb, int Also note that we *can't* use eth_io_copy_and_sum() because it will not always copy "count" bytes (e.g. padded IP). */ - memcpy_fromio(skb->data, ei_status.mem, count); + isa_memcpy_fromio(skb->data, dev->mem_start, count); outw(option_reg, ioaddr + HPP_OPTION); } @@ -424,7 +416,7 @@ hpp_mem_block_output(struct net_device *dev, int count, outw(start_page << 8, ioaddr + HPP_OUT_ADDR); outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION); - memcpy_toio(ei_status.mem, buf, (count + 3) & ~3); + isa_memcpy_toio(dev->mem_start, buf, (count + 3) & ~3); outw(option_reg, ioaddr + HPP_OPTION); return; @@ -478,7 +470,6 @@ init_module(void) static void cleanup_card(struct net_device *dev) { /* NB: hpp_close() handles free_irq */ - iounmap(ei_status.mem); release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); } diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 247c8ca86..55c7ed608 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -115,7 +115,6 @@ #include #include #include -#include #include @@ -1500,7 +1499,7 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) printk("hp100: %s: start_xmit_bm: No TX PDL available.\n", dev->name); #endif /* not waited long enough since last tx? */ - if (time_before(jiffies, dev->trans_start + HZ)) + if (jiffies - dev->trans_start < HZ) return -EAGAIN; if (hp100_check_lan(dev)) @@ -1653,7 +1652,7 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) printk("hp100: %s: start_xmit: tx free mem = 0x%x\n", dev->name, i); #endif /* not waited long enough since last failed tx try? */ - if (time_before(jiffies, dev->trans_start + HZ)) { + if (jiffies - dev->trans_start < HZ) { #ifdef HP100_DEBUG printk("hp100: %s: trans_start timing problem\n", dev->name); @@ -1719,10 +1718,17 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) hp100_outw(i, FRAGMENT_LEN); /* and first/only fragment length */ if (lp->mode == 2) { /* memory mapped */ - /* Note: The J2585B needs alignment to 32bits here! */ - memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3); - if (!ok_flag) - memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len); + if (lp->mem_ptr_virt) { /* high pci memory was remapped */ + /* Note: The J2585B needs alignment to 32bits here! */ + memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3); + if (!ok_flag) + memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len); + } else { + /* Note: The J2585B needs alignment to 32bits here! */ + isa_memcpy_toio(lp->mem_ptr_phys, skb->data, (skb->len + 3) & ~3); + if (!ok_flag) + isa_memset_io(lp->mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb->len); + } } else { /* programmed i/o */ outsl(ioaddr + HP100_REG_DATA32, skb->data, (skb->len + 3) >> 2); @@ -1792,7 +1798,10 @@ static void hp100_rx(struct net_device *dev) /* First we get the header, which contains information about the */ /* actual length of the received packet. */ if (lp->mode == 2) { /* memory mapped mode */ - header = readl(lp->mem_ptr_virt); + if (lp->mem_ptr_virt) /* if memory was remapped */ + header = readl(lp->mem_ptr_virt); + else + header = isa_readl(lp->mem_ptr_phys); } else /* programmed i/o */ header = hp100_inl(DATA32); @@ -1824,9 +1833,13 @@ static void hp100_rx(struct net_device *dev) ptr = skb->data; /* Now transfer the data from the card into that area */ - if (lp->mode == 2) - memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len); - else /* io mapped */ + if (lp->mode == 2) { + if (lp->mem_ptr_virt) + memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len); + /* Note alignment to 32bit transfers */ + else + isa_memcpy_fromio(ptr, lp->mem_ptr_phys, pkt_len); + } else /* io mapped */ insl(ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2); skb->protocol = eth_type_trans(skb, dev); diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c index 685693464..d8410634b 100644 --- a/drivers/net/hplance.c +++ b/drivers/net/hplance.c @@ -217,7 +217,7 @@ static int hplance_close(struct net_device *dev) int __init hplance_init_module(void) { - return dio_register_driver(&hplance_driver); + return dio_module_init(&hplance_driver); } void __exit hplance_cleanup_module(void) diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index d9fb8e74e..6e0ca7340 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -242,7 +242,7 @@ static void __devexit hydra_remove_one(struct zorro_dev *z) static int __init hydra_init_module(void) { - return zorro_register_driver(&hydra_driver); + return zorro_module_init(&hydra_driver); } static void __exit hydra_cleanup_module(void) diff --git a/drivers/net/hydra.h b/drivers/net/hydra.h new file mode 100644 index 000000000..374141462 --- /dev/null +++ b/drivers/net/hydra.h @@ -0,0 +1,177 @@ +/* $Linux: hydra.h,v 1.0 1994/10/26 02:03:47 cgd Exp $ */ + +/* + * Copyright (c) 1994 Timo Rossi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Timo Rossi + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * The Hydra Systems card uses the National Semiconductor + * 8390 NIC (Network Interface Controller) chip, located + * at card base address + 0xffe1. NIC registers are accessible + * only at odd byte addresses, so the register offsets must + * be multiplied by two. + * + * Card address PROM is located at card base + 0xffc0 (even byte addresses) + * + * RAM starts at the card base address, and is 16K or 64K. + * The current Amiga NetBSD hydra driver is hardwired for 16K. + * It seems that the RAM should be accessed as words or longwords only. + * + */ + +/* adapted for Linux by Topi Kanerva 03/29/95 + with original author's permission */ + +#define HYDRA_NIC_BASE 0xffe1 + +/* Page0 registers */ + +#define NIC_CR 0 /* Command register */ +#define NIC_PSTART (1*2) /* Page start (write) */ +#define NIC_PSTOP (2*2) /* Page stop (write) */ +#define NIC_BNDRY (3*2) /* Boundary pointer */ +#define NIC_TSR (4*2) /* Transmit status (read) */ +#define NIC_TPSR (4*2) /* Transmit page start (write) */ +#define NIC_NCR (5*2) /* Number of collisions, read */ +#define NIC_TBCR0 (5*2) /* Transmit byte count low (write) */ +#define NIC_FIFO (6*2) /* FIFO reg. (read) */ +#define NIC_TBCR1 (6*2) /* Transmit byte count high (write) */ +#define NIC_ISR (7*2) /* Interrupt status register */ +#define NIC_RBCR0 (0xa*2) /* Remote byte count low (write) */ +#define NIC_RBCR1 (0xb*2) /* Remote byte count high (write) */ +#define NIC_RSR (0xc*2) /* Receive status (read) */ +#define NIC_RCR (0xc*2) /* Receive config (write) */ +#define NIC_CNTR0 (0xd*2) /* Frame alignment error count (read) */ +#define NIC_TCR (0xd*2) /* Transmit config (write) */ +#define NIC_CNTR1 (0xe*2) /* CRC error counter (read) */ +#define NIC_DCR (0xe*2) /* Data config (write) */ +#define NIC_CNTR2 (0xf*2) /* missed packet counter (read) */ +#define NIC_IMR (0xf*2) /* Interrupt mask reg. (write) */ + +/* Page1 registers */ + +#define NIC_PAR0 (1*2) /* Physical address */ +#define NIC_PAR1 (2*2) +#define NIC_PAR2 (3*2) +#define NIC_PAR3 (4*2) +#define NIC_PAR4 (5*2) +#define NIC_PAR5 (6*2) +#define NIC_CURR (7*2) /* Current RX ring-buffer page */ +#define NIC_MAR0 (8*2) /* Multicast address */ +#define NIC_MAR1 (9*2) +#define NIC_MAR2 (0xa*2) +#define NIC_MAR3 (0xb*2) +#define NIC_MAR4 (0xc*2) +#define NIC_MAR5 (0xd*2) +#define NIC_MAR6 (0xe*2) +#define NIC_MAR7 (0xf*2) + +/* Command register definitions */ + +#define CR_STOP 0x01 /* Stop -- software reset command */ +#define CR_START 0x02 /* Start */ +#define CR_TXP 0x04 /* Transmit packet */ + +#define CR_RD0 0x08 /* Remote DMA cmd */ +#define CR_RD1 0x10 +#define CR_RD2 0x20 + +#define CR_NODMA CR_RD2 + +#define CR_PS0 0x40 /* Page select */ +#define CR_PS1 0x80 + +#define CR_PAGE0 0 +#define CR_PAGE1 CR_PS0 +#define CR_PAGE2 CR_PS1 + +/* Interrupt status reg. definitions */ + +#define ISR_PRX 0x01 /* Packet received without errors */ +#define ISR_PTX 0x02 /* Packet transmitted without errors */ +#define ISR_RXE 0x04 /* Receive error */ +#define ISR_TXE 0x08 /* Transmit error */ +#define ISR_OVW 0x10 /* Ring buffer overrun */ +#define ISR_CNT 0x20 /* Counter overflow */ +#define ISR_RDC 0x40 /* Remote DMA compile */ +#define ISR_RST 0x80 /* Reset status */ + +/* Data config reg. definitions */ + +#define DCR_WTS 0x01 /* Word transfer select */ +#define DCR_BOS 0x02 /* Byte order select */ +#define DCR_LAS 0x04 /* Long address select */ +#define DCR_LS 0x08 /* Loopback select */ +#define DCR_AR 0x10 /* Auto-init remote */ +#define DCR_FT0 0x20 /* FIFO threshold select */ +#define DCR_FT1 0x40 + +/* Transmit config reg. definitions */ + +#define TCR_CRC 0x01 /* Inhibit CRC */ +#define TCR_LB0 0x02 /* Loopback control */ +#define TCR_LB1 0x04 +#define TCR_ATD 0x08 /* Auto transmit disable */ +#define TCR_OFST 0x10 /* Collision offset enable */ + +/* Transmit status reg. definitions */ + +#define TSR_PTX 0x01 /* Packet transmitted */ +#define TSR_COL 0x04 /* Transmit collided */ +#define TSR_ABT 0x08 /* Transmit aborted */ +#define TSR_CRS 0x10 /* Carrier sense lost */ +#define TSR_FU 0x20 /* FIFO underrun */ +#define TSR_CDH 0x40 /* CD Heartbeat */ +#define TSR_OWC 0x80 /* Out of Window Collision */ + +/* Receiver config register definitions */ + +#define RCR_SEP 0x01 /* Save errored packets */ +#define RCR_AR 0x02 /* Accept runt packets */ +#define RCR_AB 0x04 /* Accept broadcast */ +#define RCR_AM 0x08 /* Accept multicast */ +#define RCR_PRO 0x10 /* Promiscuous mode */ +#define RCR_MON 0x20 /* Monitor mode */ + +/* Receiver status register definitions */ + +#define RSR_PRX 0x01 /* Packet received without error */ +#define RSR_CRC 0x02 /* CRC error */ +#define RSR_FAE 0x04 /* Frame alignment error */ +#define RSR_FO 0x08 /* FIFO overrun */ +#define RSR_MPA 0x10 /* Missed packet */ +#define RSR_PHY 0x20 /* Physical address */ +#define RSR_DIS 0x40 /* Received disabled */ +#define RSR_DFR 0x80 /* Deferring (jabber) */ + +/* Hydra System card address PROM offset */ + +#define HYDRA_ADDRPROM 0xffc0 + + diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 7e49522b8..591c5864f 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -204,7 +204,7 @@ static inline int emac_phy_gpcs(int phy_mode) static inline void emac_tx_enable(struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; unsigned long flags; u32 r; @@ -220,7 +220,7 @@ static inline void emac_tx_enable(struct ocp_enet_private *dev) static void emac_tx_disable(struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; unsigned long flags; u32 r; @@ -244,7 +244,7 @@ static void emac_tx_disable(struct ocp_enet_private *dev) static void emac_rx_enable(struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; unsigned long flags; u32 r; @@ -275,7 +275,7 @@ static void emac_rx_enable(struct ocp_enet_private *dev) static void emac_rx_disable(struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; unsigned long flags; u32 r; @@ -299,7 +299,7 @@ static void emac_rx_disable(struct ocp_enet_private *dev) static inline void emac_rx_disable_async(struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; unsigned long flags; u32 r; @@ -315,7 +315,7 @@ static inline void emac_rx_disable_async(struct ocp_enet_private *dev) static int emac_reset(struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; unsigned long flags; int n = 20; @@ -348,7 +348,7 @@ static int emac_reset(struct ocp_enet_private *dev) static void emac_hash_mc(struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; u16 gaht[4] = { 0 }; struct dev_mc_list *dmi; @@ -393,7 +393,7 @@ static inline int emac_opb_mhz(void) /* BHs disabled */ static int emac_configure(struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; struct net_device *ndev = dev->ndev; int gige; u32 r; @@ -555,7 +555,7 @@ static void emac_full_tx_reset(struct net_device *ndev) static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; u32 r; int n; @@ -604,7 +604,7 @@ static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg, u16 val) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; int n; DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg, @@ -666,7 +666,7 @@ static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val) static void emac_set_multicast_list(struct net_device *ndev) { struct ocp_enet_private *dev = ndev->priv; - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; u32 rmr = emac_iff2rmr(ndev); DBG("%d: multicast %08x" NL, dev->def->index, rmr); @@ -825,7 +825,7 @@ static void emac_clean_rx_ring(struct ocp_enet_private *dev) } static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot, - gfp_t flags) + int flags) { struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags); if (unlikely(!skb)) @@ -1047,7 +1047,7 @@ static inline u16 emac_tx_csum(struct ocp_enet_private *dev, static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; struct net_device *ndev = dev->ndev; /* Send the packet out */ @@ -1519,7 +1519,7 @@ static void emac_rxde(void *param) static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs) { struct ocp_enet_private *dev = dev_instance; - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; struct ibm_emac_error_stats *st = &dev->estats; u32 isr = in_be32(&p->isr); @@ -1619,17 +1619,17 @@ static void emac_remove(struct ocp_device *ocpdev) DBG("%d: remove" NL, dev->def->index); - ocp_set_drvdata(ocpdev, NULL); + ocp_set_drvdata(ocpdev, 0); unregister_netdev(dev->ndev); tah_fini(dev->tah_dev); rgmii_fini(dev->rgmii_dev, dev->rgmii_input); zmii_fini(dev->zmii_dev, dev->zmii_input); - emac_dbg_register(dev->def->index, NULL); + emac_dbg_register(dev->def->index, 0); mal_unregister_commac(dev->mal, &dev->commac); - iounmap(dev->emacp); + iounmap((void *)dev->emacp); kfree(dev->ndev); } @@ -2048,7 +2048,9 @@ static int __init emac_probe(struct ocp_device *ocpdev) goto out4; /* Map EMAC regs */ - dev->emacp = ioremap(dev->def->paddr, sizeof(struct emac_regs)); + dev->emacp = + (struct emac_regs *)ioremap(dev->def->paddr, + sizeof(struct emac_regs)); if (!dev->emacp) { printk(KERN_ERR "emac%d: could not ioremap device registers!\n", dev->def->index); @@ -2208,7 +2210,7 @@ static int __init emac_probe(struct ocp_device *ocpdev) return 0; out6: - iounmap(dev->emacp); + iounmap((void *)dev->emacp); out5: tah_fini(dev->tah_dev); out4: diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h index f61273b2e..911abbaf4 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.h +++ b/drivers/net/ibm_emac/ibm_emac_core.h @@ -155,7 +155,7 @@ struct ibm_emac_error_stats { struct ocp_enet_private { struct net_device *ndev; /* 0 */ - struct emac_regs __iomem *emacp; + struct emac_regs *emacp; struct mal_descriptor *tx_desc; int tx_cnt; diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c index c7e1ecfa0..75d3b8639 100644 --- a/drivers/net/ibm_emac/ibm_emac_debug.c +++ b/drivers/net/ibm_emac/ibm_emac_debug.c @@ -58,7 +58,7 @@ static void emac_desc_dump(int idx, struct ocp_enet_private *p) static void emac_mac_dump(int idx, struct ocp_enet_private *dev) { - struct emac_regs __iomem *p = dev->emacp; + struct emac_regs *p = dev->emacp; printk("** EMAC%d registers **\n" "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h index 7f03d536c..a1ffb8a44 100644 --- a/drivers/net/ibm_emac/ibm_emac_rgmii.h +++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h @@ -31,7 +31,7 @@ struct rgmii_regs { /* RGMII device */ struct ibm_ocp_rgmii { - struct rgmii_regs __iomem *base; + struct rgmii_regs *base; int users; /* number of EMACs using this RGMII bridge */ }; diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c index e129e0aaa..35c118507 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.c +++ b/drivers/net/ibm_emac/ibm_emac_zmii.c @@ -80,7 +80,7 @@ static inline u32 zmii_mode_mask(int mode, int input) static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode) { struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); - struct zmii_regs __iomem *p; + struct zmii_regs *p; ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode); @@ -94,7 +94,8 @@ static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode) } dev->mode = PHY_MODE_NA; - p = ioremap(ocpdev->def->paddr, sizeof(struct zmii_regs)); + p = (struct zmii_regs *)ioremap(ocpdev->def->paddr, + sizeof(struct zmii_regs)); if (!p) { printk(KERN_ERR "zmii%d: could not ioremap device registers!\n", @@ -230,7 +231,7 @@ void __exit __zmii_fini(struct ocp_device *ocpdev, int input) if (!--dev->users) { /* Free everything if this is the last user */ ocp_set_drvdata(ocpdev, NULL); - iounmap(dev->base); + iounmap((void *)dev->base); kfree(dev); } } diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h index 92c854410..0bb26062c 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.h +++ b/drivers/net/ibm_emac/ibm_emac_zmii.h @@ -32,7 +32,7 @@ struct zmii_regs { /* ZMII device */ struct ibm_ocp_zmii { - struct zmii_regs __iomem *base; + struct zmii_regs *base; int mode; /* subset of PHY_MODE_XXXX */ int users; /* number of EMACs using this ZMII bridge */ u32 fer_save; /* FER value left by firmware */ diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 52d01027d..ceb98fd39 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -235,7 +235,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); - if(lpar_rc != H_SUCCESS) { + if(lpar_rc != H_Success) { pool->free_map[free_index] = index; pool->skbuff[index] = NULL; pool->consumer_index--; @@ -373,7 +373,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); - if(lpar_rc != H_SUCCESS) { + if(lpar_rc != H_Success) { ibmveth_debug_printk("h_add_logical_lan_buffer failed during recycle rc=%ld", lpar_rc); ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); } @@ -511,7 +511,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->filter_list_dma, mac_address); - if(lpar_rc != H_SUCCESS) { + if(lpar_rc != H_Success) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n", adapter->buffer_list_dma, @@ -527,7 +527,7 @@ static int ibmveth_open(struct net_device *netdev) ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc); do { rc = h_free_logical_lan(adapter->vdev->unit_address); - } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); + } while (H_isLongBusy(rc) || (rc == H_Busy)); ibmveth_cleanup(adapter); return rc; @@ -556,9 +556,9 @@ static int ibmveth_close(struct net_device *netdev) do { lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); - } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY)); + } while (H_isLongBusy(lpar_rc) || (lpar_rc == H_Busy)); - if(lpar_rc != H_SUCCESS) + if(lpar_rc != H_Success) { ibmveth_error_printk("h_free_logical_lan failed with %lx, continuing with close\n", lpar_rc); @@ -693,9 +693,9 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) desc[4].desc, desc[5].desc, correlator); - } while ((lpar_rc == H_BUSY) && (retry_count--)); + } while ((lpar_rc == H_Busy) && (retry_count--)); - if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { + if(lpar_rc != H_Success && lpar_rc != H_Dropped) { int i; ibmveth_error_printk("tx: h_send_logical_lan failed with rc=%ld\n", lpar_rc); for(i = 0; i < 6; i++) { @@ -786,14 +786,14 @@ static int ibmveth_poll(struct net_device *netdev, int *budget) /* we think we are done - reenable interrupts, then check once more to make sure we are done */ lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_ENABLE); - ibmveth_assert(lpar_rc == H_SUCCESS); + ibmveth_assert(lpar_rc == H_Success); netif_rx_complete(netdev); if(ibmveth_rxq_pending_buffer(adapter) && netif_rx_reschedule(netdev, frames_processed)) { lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); - ibmveth_assert(lpar_rc == H_SUCCESS); + ibmveth_assert(lpar_rc == H_Success); more_work = 1; goto restart_poll; } @@ -813,7 +813,7 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs if(netif_rx_schedule_prep(netdev)) { lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); - ibmveth_assert(lpar_rc == H_SUCCESS); + ibmveth_assert(lpar_rc == H_Success); __netif_rx_schedule(netdev); } return IRQ_HANDLED; @@ -835,7 +835,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastEnableRecv | IbmVethMcastDisableFiltering, 0); - if(lpar_rc != H_SUCCESS) { + if(lpar_rc != H_Success) { ibmveth_error_printk("h_multicast_ctrl rc=%ld when entering promisc mode\n", lpar_rc); } } else { @@ -847,7 +847,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastDisableFiltering | IbmVethMcastClearFilterTable, 0); - if(lpar_rc != H_SUCCESS) { + if(lpar_rc != H_Success) { ibmveth_error_printk("h_multicast_ctrl rc=%ld when attempting to clear filter table\n", lpar_rc); } /* add the addresses to the filter table */ @@ -858,7 +858,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastAddFilter, mcast_addr); - if(lpar_rc != H_SUCCESS) { + if(lpar_rc != H_Success) { ibmveth_error_printk("h_multicast_ctrl rc=%ld when adding an entry to the filter table\n", lpar_rc); } } @@ -867,7 +867,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastEnableFiltering, 0); - if(lpar_rc != H_SUCCESS) { + if(lpar_rc != H_Success) { ibmveth_error_printk("h_multicast_ctrl rc=%ld when enabling filtering\n", lpar_rc); } } diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 2e222ef91..31fb2d75d 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -76,13 +76,13 @@ static void ri_tasklet(unsigned long dev) dp->st_task_enter++; if ((skb = skb_peek(&dp->tq)) == NULL) { dp->st_txq_refl_try++; - if (netif_tx_trylock(_dev)) { + if (spin_trylock(&_dev->xmit_lock)) { dp->st_rxq_enter++; while ((skb = skb_dequeue(&dp->rq)) != NULL) { skb_queue_tail(&dp->tq, skb); dp->st_rx2tx_tran++; } - netif_tx_unlock(_dev); + spin_unlock(&_dev->xmit_lock); } else { /* reschedule */ dp->st_rxq_notenter++; @@ -110,7 +110,7 @@ static void ri_tasklet(unsigned long dev) } } - if (netif_tx_trylock(_dev)) { + if (spin_trylock(&_dev->xmit_lock)) { dp->st_rxq_check++; if ((skb = skb_peek(&dp->rq)) == NULL) { dp->tasklet_pending = 0; @@ -118,10 +118,10 @@ static void ri_tasklet(unsigned long dev) netif_wake_queue(_dev); } else { dp->st_rxq_rsch++; - netif_tx_unlock(_dev); + spin_unlock(&_dev->xmit_lock); goto resched; } - netif_tx_unlock(_dev); + spin_unlock(&_dev->xmit_lock); } else { resched: dp->tasklet_pending = 1; diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index ae71ed57c..9b8295ee0 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -44,7 +44,6 @@ #include #include #include -#include #ifdef CONFIG_SERIAL_8250 #include @@ -1196,17 +1195,17 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int err, pci_using_dac; /* Configure DMA attributes. */ - err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); + err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); if (!err) { pci_using_dac = 1; - err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); + err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); 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, 0xffffffffULL); if (err) { printk(KERN_ERR "%s: No usable DMA configuration, " "aborting.\n", pci_name(pdev)); diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index cff8598aa..7a081346f 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -33,7 +33,7 @@ config DONGLE config ESI_DONGLE tristate "ESI JetEye PC dongle" - depends on IRTTY_SIR && DONGLE && IRDA + depends on DONGLE && IRDA help Say Y here if you want to build support for the Extended Systems JetEye PC dongle. To compile it as a module, choose M here. The ESI @@ -44,7 +44,7 @@ config ESI_DONGLE config ACTISYS_DONGLE tristate "ACTiSYS IR-220L and IR220L+ dongle" - depends on IRTTY_SIR && DONGLE && IRDA + depends on DONGLE && IRDA help Say Y here if you want to build support for the ACTiSYS IR-220L and IR220L+ dongles. To compile it as a module, choose M here. The @@ -55,7 +55,7 @@ config ACTISYS_DONGLE config TEKRAM_DONGLE tristate "Tekram IrMate 210B dongle" - depends on IRTTY_SIR && DONGLE && IRDA + depends on DONGLE && IRDA help Say Y here if you want to build support for the Tekram IrMate 210B dongle. To compile it as a module, choose M here. The Tekram dongle @@ -64,17 +64,9 @@ config TEKRAM_DONGLE dongles you will have to start irattach like this: "irattach -d tekram". -config TOIM3232_DONGLE - tristate "TOIM3232 IrDa dongle" - depends on IRTTY_SIR && DONGLE && IRDA - help - Say Y here if you want to build support for the Vishay/Temic - TOIM3232 and TOIM4232 based dongles. - To compile it as a module, choose M here. - config LITELINK_DONGLE tristate "Parallax LiteLink dongle" - depends on IRTTY_SIR && DONGLE && IRDA + depends on DONGLE && IRDA help Say Y here if you want to build support for the Parallax Litelink dongle. To compile it as a module, choose M here. The Parallax @@ -85,7 +77,7 @@ config LITELINK_DONGLE config MA600_DONGLE tristate "Mobile Action MA600 dongle" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on DONGLE && IRDA && EXPERIMENTAL help Say Y here if you want to build support for the Mobile Action MA600 dongle. To compile it as a module, choose M here. The MA600 dongle @@ -98,7 +90,7 @@ config MA600_DONGLE config GIRBIL_DONGLE tristate "Greenwich GIrBIL dongle" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on DONGLE && IRDA && EXPERIMENTAL help Say Y here if you want to build support for the Greenwich GIrBIL dongle. If you want to compile it as a module, choose M here. @@ -109,7 +101,7 @@ config GIRBIL_DONGLE config MCP2120_DONGLE tristate "Microchip MCP2120" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on DONGLE && IRDA && EXPERIMENTAL help Say Y here if you want to build support for the Microchip MCP2120 dongle. If you want to compile it as a module, choose M here. @@ -123,7 +115,7 @@ config MCP2120_DONGLE config OLD_BELKIN_DONGLE tristate "Old Belkin dongle" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on DONGLE && IRDA && EXPERIMENTAL help Say Y here if you want to build support for the Adaptec Airport 1000 and 2000 dongles. If you want to compile it as a module, choose @@ -132,7 +124,7 @@ config OLD_BELKIN_DONGLE config ACT200L_DONGLE tristate "ACTiSYS IR-200L dongle" - depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL + depends on DONGLE && IRDA && EXPERIMENTAL help Say Y here if you want to build support for the ACTiSYS IR-200L dongle. If you want to compile it as a module, choose M here. @@ -291,7 +283,7 @@ config USB_IRDA Say Y here if you want to build support for the USB IrDA FIR Dongle device driver. To compile it as a module, choose M here: the module will be called irda-usb. IrDA-USB support the various IrDA USB - dongles available and most of their peculiarities. Those dongles + dongles available and most of their pecularities. Those dongles plug in the USB port of your computer, are plug and play, and support SIR and FIR (4Mbps) speeds. On the other hand, those dongles tend to be less efficient than a FIR chipset. @@ -368,7 +360,7 @@ config ALI_FIR help Say Y here if you want to build support for the ALi M5123 FIR Controller. The ALi M5123 FIR Controller is embedded in ALi M1543C, - M1535, M1535D, M1535+, M1535D South Bridge. This driver supports + M1535, M1535D, M1535+, M1535D Sourth Bridge. This driver supports SIR, MIR and FIR (4Mbps) speeds. To compile it as a module, choose M here: the module will be called diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index c1ce2398e..72cbfdc9c 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_OLD_BELKIN_DONGLE) += old_belkin-sir.o obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o -obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o # The SIR helper module -sir-dev-objs := sir_dev.o sir_dongle.o +sir-dev-objs := sir_dev.o sir_dongle.o sir_kthread.o diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 910c0cab3..3137592d6 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -1778,7 +1778,7 @@ static struct pci_driver donauboe_pci_driver = { static int __init donauboe_init (void) { - return pci_register_driver(&donauboe_pci_driver); + return pci_module_init(&donauboe_pci_driver); } static void __exit diff --git a/drivers/net/irda/ep7211_ir.c b/drivers/net/irda/ep7211_ir.c index 4cba38f7e..31896262d 100644 --- a/drivers/net/irda/ep7211_ir.c +++ b/drivers/net/irda/ep7211_ir.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -24,8 +23,6 @@ static void ep7211_ir_close(dongle_t *self); static int ep7211_ir_change_speed(struct irda_task *task); static int ep7211_ir_reset(struct irda_task *task); -static DEFINE_SPINLOCK(ep7211_lock); - static struct dongle_reg dongle = { .type = IRDA_EP7211_IR, .open = ep7211_ir_open, @@ -39,7 +36,7 @@ static void ep7211_ir_open(dongle_t *self, struct qos_info *qos) { unsigned int syscon1, flags; - spin_lock_irqsave(&ep7211_lock, flags); + save_flags(flags); cli(); /* Turn on the SIR encoder. */ syscon1 = clps_readl(SYSCON1); @@ -49,14 +46,14 @@ static void ep7211_ir_open(dongle_t *self, struct qos_info *qos) /* XXX: We should disable modem status interrupts on the first UART (interrupt #14). */ - spin_unlock_irqrestore(&ep7211_lock, flags); + restore_flags(flags); } static void ep7211_ir_close(dongle_t *self) { unsigned int syscon1, flags; - spin_lock_irqsave(&ep7211_lock, flags); + save_flags(flags); cli(); /* Turn off the SIR encoder. */ syscon1 = clps_readl(SYSCON1); @@ -66,7 +63,7 @@ static void ep7211_ir_close(dongle_t *self) /* XXX: If we've disabled the modem status interrupts, we should reset them back to their original state. */ - spin_unlock_irqrestore(&ep7211_lock, flags); + restore_flags(flags); } /* diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index cd87593e4..6e2ec56cd 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1,7 +1,7 @@ /***************************************************************************** * * Filename: irda-usb.c - * Version: 0.10 + * Version: 0.9b * Description: IrDA-USB Driver * Status: Experimental * Author: Dag Brattli @@ -9,9 +9,6 @@ * Copyright (C) 2000, Roman Weissgaerber * Copyright (C) 2001, Dag Brattli * Copyright (C) 2001, Jean Tourrilhes - * Copyright (C) 2004, SigmaTel, Inc. - * Copyright (C) 2005, Milan Beno - * Copyright (C) 2006, Nick Fedchik * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,7 +61,6 @@ #include #include #include -#include #include "irda-usb.h" @@ -82,12 +78,8 @@ static struct usb_device_id dongles[] = { { USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, - /* SigmaTel STIR4210/4220/4116 USB IrDA (VFIR) Bridge */ - { USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, - { USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, - { USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, + USB_DEVICE_ID_MATCH_INT_SUBCLASS, .bInterfaceClass = USB_CLASS_APP_SPEC, .bInterfaceSubClass = USB_CLASS_IRDA, .driver_info = IUC_DEFAULT, }, @@ -107,7 +99,6 @@ MODULE_DEVICE_TABLE(usb, dongles); /*------------------------------------------------------------------*/ -static void irda_usb_init_qos(struct irda_usb_cb *self) ; static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf); static void irda_usb_disconnect(struct usb_interface *intf); static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); @@ -150,24 +141,7 @@ static void irda_usb_build_header(struct irda_usb_cb *self, __u8 *header, int force) { - /* Here we check if we have an STIR421x chip, - * and if either speed or xbofs (or both) needs - * to be changed. - */ - if (self->capability & IUC_STIR_4210 && - ((self->new_speed != -1) || (self->new_xbofs != -1))) { - - /* With STIR421x, speed and xBOFs must be set at the same - * time, even if only one of them changes. - */ - if (self->new_speed == -1) - self->new_speed = self->speed ; - - if (self->new_xbofs == -1) - self->new_xbofs = self->xbofs ; - } - - /* Set the link speed */ + /* Set the negotiated link speed */ if (self->new_speed != -1) { /* Hum... Ugly hack :-( * Some device are not compliant with the spec and change @@ -217,11 +191,7 @@ static void irda_usb_build_header(struct irda_usb_cb *self, *header = SPEED_4000000; self->new_xbofs = 0; break; - case 16000000: - *header = SPEED_16000000; - self->new_xbofs = 0; - break; - } + } } else /* No change */ *header = 0; @@ -265,32 +235,6 @@ static void irda_usb_build_header(struct irda_usb_cb *self, } } -/* -* calculate turnaround time for SigmaTel header -*/ -static __u8 get_turnaround_time(struct sk_buff *skb) -{ - int turnaround_time = irda_get_mtt(skb); - - if ( turnaround_time == 0 ) - return 0; - else if ( turnaround_time <= 10 ) - return 1; - else if ( turnaround_time <= 50 ) - return 2; - else if ( turnaround_time <= 100 ) - return 3; - else if ( turnaround_time <= 500 ) - return 4; - else if ( turnaround_time <= 1000 ) - return 5; - else if ( turnaround_time <= 5000 ) - return 6; - else - return 7; -} - - /*------------------------------------------------------------------*/ /* * Send a command to change the speed of the dongle @@ -318,18 +262,12 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) /* Set the new speed and xbofs in this fake frame */ irda_usb_build_header(self, frame, 1); - if ( self->capability & IUC_STIR_4210 ) { - if (frame[0] == 0) return ; // do nothing if no change - frame[1] = 0; // other parameters don't change here - frame[2] = 0; - } - /* Submit the 0 length IrDA frame to trigger new speed settings */ usb_fill_bulk_urb(urb, self->usbdev, usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), frame, IRDA_USB_SPEED_MTU, speed_bulk_callback, self); - urb->transfer_buffer_length = self->header_length; + urb->transfer_buffer_length = USB_IRDA_HEADER; urb->transfer_flags = 0; /* Irq disabled -> GFP_ATOMIC */ @@ -445,35 +383,16 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) * allocation will be done lower in skb_push(). * Also, we don't use directly skb_cow(), because it require * headroom >= 16, which force unnecessary copies - Jean II */ - if (skb_headroom(skb) < self->header_length) { + if (skb_headroom(skb) < USB_IRDA_HEADER) { IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); - if (skb_cow(skb, self->header_length)) { + if (skb_cow(skb, USB_IRDA_HEADER)) { IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); goto drop; } } /* Change setting for next frame */ - - if ( self->capability & IUC_STIR_4210 ) { - __u8 turnaround_time; - __u8* frame; - turnaround_time = get_turnaround_time( skb ); - frame= skb_push(skb, self->header_length); - irda_usb_build_header(self, frame, 0); - frame[2] = turnaround_time; - if ((skb->len != 0) && - ((skb->len % 128) == 0) && - ((skb->len % 512) != 0)) { - /* add extra byte for special SigmaTel feature */ - frame[1] = 1; - skb_put(skb, 1); - } else { - frame[1] = 0; - } - } else { - irda_usb_build_header(self, skb_push(skb, self->header_length), 0); - } + irda_usb_build_header(self, skb_push(skb, USB_IRDA_HEADER), 0); /* FIXME: Make macro out of this one */ ((struct irda_skb_cb *)skb->cb)->context = self; @@ -876,7 +795,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) } /* Check for empty frames */ - if (urb->actual_length <= self->header_length) { + if (urb->actual_length <= USB_IRDA_HEADER) { IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); goto done; } @@ -897,11 +816,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); /* Allocate a new skb */ - if ( self->capability & IUC_STIR_4210 ) - newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU + USB_IRDA_SIGMATEL_HEADER); - else - newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); - + newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); if (!newskb) { self->stats.rx_dropped++; /* We could deliver the current skb, but this would stall @@ -930,7 +845,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) /* Set proper length on skb & remove USB-IrDA header */ skb_put(dataskb, urb->actual_length); - skb_pull(dataskb, self->header_length); + skb_pull(dataskb, USB_IRDA_HEADER); /* Ask the networking layer to queue the packet for the IrDA stack */ dataskb->dev = self->netdev; @@ -1022,191 +937,6 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self) return 0; /* For now */ } - -#define STIR421X_PATCH_PRODUCT_VERSION_STR "Product Version: " -#define STIR421X_PATCH_COMPONENT_VERSION_STR "Component Version: " -#define STIR421X_PATCH_DATA_TAG_STR "STMP" -#define STIR421X_PATCH_FILE_VERSION_MAX_OFFSET 512 /* version info is before here */ -#define STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET 512 /* patch image starts before here */ -#define STIR421X_PATCH_FILE_END_OF_HEADER_TAG 0x1A /* marks end of patch file header (PC DOS text file EOF character) */ - -/* - * Known firmware patches for STIR421x dongles - */ -static char * stir421x_patches[] = { - "42101001.sb", - "42101002.sb", -}; - -static int stir421x_get_patch_version(unsigned char * patch, const unsigned long patch_len) -{ - unsigned int version_offset; - unsigned long version_major, version_minor, version_build; - unsigned char * version_start; - int version_found = 0; - - for (version_offset = 0; - version_offset < STIR421X_PATCH_FILE_END_OF_HEADER_TAG; - version_offset++) { - if (!memcmp(patch + version_offset, - STIR421X_PATCH_PRODUCT_VERSION_STR, - sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1)) { - version_found = 1; - version_start = patch + - version_offset + - sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1; - break; - } - } - - /* We couldn't find a product version on this patch */ - if (!version_found) - return -EINVAL; - - /* Let's check if the product version is dotted */ - if (version_start[3] != '.' || - version_start[7] != '.') - return -EINVAL; - - version_major = simple_strtoul(version_start, NULL, 10); - version_minor = simple_strtoul(version_start + 4, NULL, 10); - version_build = simple_strtoul(version_start + 8, NULL, 10); - - IRDA_DEBUG(2, "%s(), Major: %ld Minor: %ld Build: %ld\n", - __FUNCTION__, - version_major, version_minor, version_build); - - return (((version_major) << 12) + - ((version_minor) << 8) + - ((version_build / 10) << 4) + - (version_build % 10)); - -} - - -static int stir421x_upload_patch (struct irda_usb_cb *self, - unsigned char * patch, - const unsigned int patch_len) -{ - int retval = 0; - int actual_len; - unsigned int i = 0, download_amount = 0; - unsigned char * patch_chunk; - - IRDA_DEBUG (2, "%s(), Uploading STIR421x Patch\n", __FUNCTION__); - - patch_chunk = kzalloc(STIR421X_MAX_PATCH_DOWNLOAD_SIZE, GFP_KERNEL); - if (patch_chunk == NULL) - return -ENOMEM; - - /* break up patch into 1023-byte sections */ - for (i = 0; retval >= 0 && i < patch_len; i += download_amount) { - download_amount = patch_len - i; - if (download_amount > STIR421X_MAX_PATCH_DOWNLOAD_SIZE) - download_amount = STIR421X_MAX_PATCH_DOWNLOAD_SIZE; - - /* download the patch section */ - memcpy(patch_chunk, patch + i, download_amount); - - retval = usb_bulk_msg (self->usbdev, - usb_sndbulkpipe (self->usbdev, - self->bulk_out_ep), - patch_chunk, download_amount, - &actual_len, msecs_to_jiffies (500)); - IRDA_DEBUG (2, "%s(), Sent %u bytes\n", __FUNCTION__, - actual_len); - if (retval == 0) - mdelay(10); - } - - kfree(patch_chunk); - - if (i != patch_len) { - IRDA_ERROR ("%s(), Pushed %d bytes (!= patch_len (%d))\n", - __FUNCTION__, i, patch_len); - retval = -EIO; - } - - if (retval < 0) - /* todo - mark device as not ready */ - IRDA_ERROR ("%s(), STIR421x patch upload failed (%d)\n", - __FUNCTION__, retval); - - return retval; -} - - -static int stir421x_patch_device(struct irda_usb_cb *self) -{ - unsigned int i, patch_found = 0, data_found = 0, data_offset; - int patch_version, ret = 0; - const struct firmware *fw_entry; - - for (i = 0; i < ARRAY_SIZE(stir421x_patches); i++) { - if(request_firmware(&fw_entry, stir421x_patches[i], &self->usbdev->dev) != 0) { - IRDA_ERROR( "%s(), Patch %s is not available\n", __FUNCTION__, stir421x_patches[i]); - continue; - } - - /* We found a patch from userspace */ - patch_version = stir421x_get_patch_version (fw_entry->data, fw_entry->size); - - if (patch_version < 0) { - /* Couldn't fetch a version, let's move on to the next file */ - IRDA_ERROR("%s(), version parsing failed\n", __FUNCTION__); - ret = patch_version; - release_firmware(fw_entry); - continue; - } - - if (patch_version != self->usbdev->descriptor.bcdDevice) { - /* Patch version and device don't match */ - IRDA_ERROR ("%s(), wrong patch version (%d <-> %d)\n", - __FUNCTION__, - patch_version, self->usbdev->descriptor.bcdDevice); - ret = -EINVAL; - release_firmware(fw_entry); - continue; - } - - /* If we're here, we've found a correct patch */ - patch_found = 1; - break; - - } - - /* We couldn't find a valid firmware, let's leave */ - if (!patch_found) - return ret; - - /* The actual image starts after the "STMP" keyword */ - for (data_offset = 0; data_offset < STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET; data_offset++) { - if (!memcmp(fw_entry->data + data_offset, - STIR421X_PATCH_DATA_TAG_STR, - sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))) { - IRDA_DEBUG(2, "%s(), found patch data for STIR421x at offset %d\n", - __FUNCTION__, data_offset); - data_found = 1; - break; - } - } - - /* We couldn't find "STMP" from the header */ - if (!data_found) - return -EINVAL; - - /* Let's upload the patch to the target */ - ret = stir421x_upload_patch(self, - &fw_entry->data[data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET)], - fw_entry->size - (data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))); - - release_firmware(fw_entry); - - return ret; - -} - - /********************** IRDA DEVICE CALLBACKS **********************/ /* * Main calls from the IrDA/Network subsystem. @@ -1242,11 +972,6 @@ static int irda_usb_net_open(struct net_device *netdev) return -1; } - if(self->needspatch) { - IRDA_WARNING("%s(), device needs patch\n", __FUNCTION__) ; - return -EIO ; - } - /* Initialise default speed and xbofs value * (IrLAP will change that soon) */ self->speed = -1; @@ -1325,7 +1050,7 @@ static int irda_usb_net_close(struct net_device *netdev) del_timer(&self->rx_defer_timer); /* Deallocate all the Rx path buffers (URBs and skb) */ - for (i = 0; i < self->max_rx_urb; i++) { + for (i = 0; i < IU_MAX_RX_URBS; i++) { struct urb *urb = self->rx_urb[i]; struct sk_buff *skb = (struct sk_buff *) urb->context; /* Cancel the receive command */ @@ -1701,22 +1426,8 @@ static int irda_usb_probe(struct usb_interface *intf, spin_lock_init(&self->lock); init_timer(&self->rx_defer_timer); - self->capability = id->driver_info; - self->needspatch = ((self->capability & IUC_STIR_4210) != 0) ; - /* Create all of the needed urbs */ - if (self->capability & IUC_STIR_4210) { - self->max_rx_urb = IU_SIGMATEL_MAX_RX_URBS; - self->header_length = USB_IRDA_SIGMATEL_HEADER; - } else { - self->max_rx_urb = IU_MAX_RX_URBS; - self->header_length = USB_IRDA_HEADER; - } - - self->rx_urb = kzalloc(self->max_rx_urb * sizeof(struct urb *), - GFP_KERNEL); - - for (i = 0; i < self->max_rx_urb; i++) { + for (i = 0; i < IU_MAX_RX_URBS; i++) { self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); if (!self->rx_urb[i]) { goto err_out_1; @@ -1768,28 +1479,17 @@ static int irda_usb_probe(struct usb_interface *intf, goto err_out_3; } - self->usbdev = dev; - /* Find IrDA class descriptor */ irda_desc = irda_usb_find_class_desc(intf); ret = -ENODEV; if (irda_desc == NULL) goto err_out_3; - if (self->needspatch) { - ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0), - 0x02, 0x40, 0, 0, NULL, 0, 500); - if (ret < 0) { - IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret); - goto err_out_3; - } else { - mdelay(10); - } - } - self->irda_desc = irda_desc; self->present = 1; self->netopen = 0; + self->capability = id->driver_info; + self->usbdev = dev; self->usbintf = intf; /* Allocate the buffer for speed changes */ @@ -1808,32 +1508,8 @@ static int irda_usb_probe(struct usb_interface *intf, IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); usb_set_intfdata(intf, self); - - if (self->needspatch) { - /* Now we fetch and upload the firmware patch */ - ret = stir421x_patch_device(self); - self->needspatch = (ret < 0); - if (ret < 0) { - printk("patch_device failed\n"); - goto err_out_5; - } - - /* replace IrDA class descriptor with what patched device is now reporting */ - irda_desc = irda_usb_find_class_desc (self->usbintf); - if (irda_desc == NULL) { - ret = -ENODEV; - goto err_out_5; - } - if (self->irda_desc) - kfree (self->irda_desc); - self->irda_desc = irda_desc; - irda_usb_init_qos(self); - } - return 0; -err_out_5: - unregister_netdev(self->netdev); err_out_4: kfree(self->speed_buff); err_out_3: @@ -1842,7 +1518,7 @@ err_out_3: err_out_2: usb_free_urb(self->tx_urb); err_out_1: - for (i = 0; i < self->max_rx_urb; i++) { + for (i = 0; i < IU_MAX_RX_URBS; i++) { if (self->rx_urb[i]) usb_free_urb(self->rx_urb[i]); } @@ -1895,7 +1571,7 @@ static void irda_usb_disconnect(struct usb_interface *intf) /*netif_device_detach(self->netdev);*/ netif_stop_queue(self->netdev); /* Stop all the receive URBs. Must be synchronous. */ - for (i = 0; i < self->max_rx_urb; i++) + for (i = 0; i < IU_MAX_RX_URBS; i++) usb_kill_urb(self->rx_urb[i]); /* Cancel Tx and speed URB. * Make sure it's synchronous to avoid races. */ @@ -1910,9 +1586,8 @@ static void irda_usb_disconnect(struct usb_interface *intf) self->usbintf = NULL; /* Clean up our urbs */ - for (i = 0; i < self->max_rx_urb; i++) + for (i = 0; i < IU_MAX_RX_URBS; i++) usb_free_urb(self->rx_urb[i]); - kfree(self->rx_urb); /* Clean up Tx and speed URB */ usb_free_urb(self->tx_urb); usb_free_urb(self->speed_urb); @@ -1973,6 +1648,6 @@ module_exit(usb_irda_cleanup); */ module_param(qos_mtt_bits, int, 0); MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); -MODULE_AUTHOR("Roman Weissgaerber , Dag Brattli , Jean Tourrilhes and Nick Fedchik "); -MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); +MODULE_AUTHOR("Roman Weissgaerber , Dag Brattli and Jean Tourrilhes "); +MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index d833db52c..4026af42d 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h @@ -1,7 +1,7 @@ /***************************************************************************** * * Filename: irda-usb.h - * Version: 0.10 + * Version: 0.9b * Description: IrDA-USB Driver * Status: Experimental * Author: Dag Brattli @@ -9,9 +9,6 @@ * Copyright (C) 2001, Roman Weissgaerber * Copyright (C) 2000, Dag Brattli * Copyright (C) 2001, Jean Tourrilhes - * Copyright (C) 2004, SigmaTel, Inc. - * Copyright (C) 2005, Milan Beno - * Copyright (C) 2006, Nick FEdchik * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,9 +31,6 @@ #include #include /* struct irlap_cb */ -#define PATCH_FILE_SIZE_MAX 65536 -#define PATCH_FILE_SIZE_MIN 80 - #define RX_COPY_THRESHOLD 200 #define IRDA_USB_MAX_MTU 2051 #define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ @@ -85,16 +79,15 @@ /* Inbound header */ #define MEDIA_BUSY 0x80 -#define SPEED_2400 0x01 -#define SPEED_9600 0x02 -#define SPEED_19200 0x03 -#define SPEED_38400 0x04 -#define SPEED_57600 0x05 -#define SPEED_115200 0x06 -#define SPEED_576000 0x07 -#define SPEED_1152000 0x08 -#define SPEED_4000000 0x09 -#define SPEED_16000000 0x0a +#define SPEED_2400 0x01 +#define SPEED_9600 0x02 +#define SPEED_19200 0x03 +#define SPEED_38400 0x04 +#define SPEED_57600 0x05 +#define SPEED_115200 0x06 +#define SPEED_576000 0x07 +#define SPEED_1152000 0x08 +#define SPEED_4000000 0x09 /* Basic capabilities */ #define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ @@ -107,14 +100,11 @@ #define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ #define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ #define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ -#define IUC_STIR_4210 0x80 /* SigmaTel 4210/4220/4116 VFIR */ /* USB class definitions */ -#define USB_IRDA_HEADER 0x01 -#define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ -#define USB_DT_IRDA 0x21 -#define USB_IRDA_SIGMATEL_HEADER 0x03 -#define IU_SIGMATEL_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + USB_IRDA_SIGMATEL_HEADER) +#define USB_IRDA_HEADER 0x01 +#define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ +#define USB_DT_IRDA 0x21 struct irda_class_desc { __u8 bLength; @@ -133,7 +123,6 @@ struct irda_class_desc { * (6.2.5, USB-IrDA class spec 1.0) */ #define IU_REQ_GET_CLASS_DESC 0x06 -#define STIR421X_MAX_PATCH_DOWNLOAD_SIZE 1023 struct irda_usb_cb { struct irda_class_desc *irda_desc; @@ -147,8 +136,7 @@ struct irda_usb_cb { __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ - __u8 max_rx_urb; - struct urb **rx_urb; /* URBs used to receive data frames */ + struct urb *rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ struct urb *tx_urb; /* URB used to send data frames */ struct urb *speed_urb; /* URB used to send speed commands */ @@ -169,9 +157,6 @@ struct irda_usb_cb { __u32 speed; /* Current speed */ __s32 new_speed; /* speed we need to set */ - __u8 header_length; /* USB-IrDA frame header size */ - int needspatch; /* device needs firmware patch */ - struct timer_list rx_defer_timer; /* Wait for Rx error to clear */ }; diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 98fa5319e..6070195b8 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -1118,9 +1118,9 @@ static void __exit irport_cleanup(void) } } -module_param_array(io, int, NULL, 0); +MODULE_PARM(io, "1-4i"); MODULE_PARM_DESC(io, "Base I/O addresses"); -module_param_array(irq, int, NULL, 0); +MODULE_PARM(irq, "1-4i"); MODULE_PARM_DESC(irq, "IRQ lines"); MODULE_AUTHOR("Dag Brattli "); diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 6a98b7ae4..101750bf2 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -339,7 +338,7 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop) /*****************************************************************/ /* serialize ldisc open/close with sir_dev */ -static DEFINE_MUTEX(irtty_mutex); +static DECLARE_MUTEX(irtty_sem); /* notifier from sir_dev when irda% device gets opened (ifup) */ @@ -349,11 +348,11 @@ static int irtty_start_dev(struct sir_dev *dev) struct tty_struct *tty; /* serialize with ldisc open/close */ - mutex_lock(&irtty_mutex); + down(&irtty_sem); priv = dev->priv; if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) { - mutex_unlock(&irtty_mutex); + up(&irtty_sem); return -ESTALE; } @@ -364,7 +363,7 @@ static int irtty_start_dev(struct sir_dev *dev) /* Make sure we can receive more data */ irtty_stop_receiver(tty, FALSE); - mutex_unlock(&irtty_mutex); + up(&irtty_sem); return 0; } @@ -376,11 +375,11 @@ static int irtty_stop_dev(struct sir_dev *dev) struct tty_struct *tty; /* serialize with ldisc open/close */ - mutex_lock(&irtty_mutex); + down(&irtty_sem); priv = dev->priv; if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) { - mutex_unlock(&irtty_mutex); + up(&irtty_sem); return -ESTALE; } @@ -391,7 +390,7 @@ static int irtty_stop_dev(struct sir_dev *dev) if (tty->driver->stop) tty->driver->stop(tty); - mutex_unlock(&irtty_mutex); + up(&irtty_sem); return 0; } @@ -515,13 +514,13 @@ static int irtty_open(struct tty_struct *tty) priv->dev = dev; /* serialize with start_dev - in case we were racing with ifup */ - mutex_lock(&irtty_mutex); + down(&irtty_sem); dev->priv = priv; tty->disc_data = priv; tty->receive_room = 65536; - mutex_unlock(&irtty_mutex); + up(&irtty_sem); IRDA_DEBUG(0, "%s - %s: irda line discipline opened\n", __FUNCTION__, tty->name); diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index cc7ff8f00..ee717d0e9 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -12,7 +12,6 @@ * Copyright (c) 1998-2000 Dag Brattli * Copyright (c) 1998 Lichen Wang, * Copyright (c) 1998 Actisys Corp., www.actisys.com - * Copyright (c) 2000-2004 Jean Tourrilhes * All Rights Reserved * * This program is free software; you can redistribute it and/or @@ -54,13 +53,14 @@ #include #include #include -#include -#include #include #include #include +#include +#include + #include #include #include @@ -72,27 +72,14 @@ static char *driver_name = "nsc-ircc"; -/* Power Management */ -#define NSC_IRCC_DRIVER_NAME "nsc-ircc" -static int nsc_ircc_suspend(struct platform_device *dev, pm_message_t state); -static int nsc_ircc_resume(struct platform_device *dev); - -static struct platform_driver nsc_ircc_driver = { - .suspend = nsc_ircc_suspend, - .resume = nsc_ircc_resume, - .driver = { - .name = NSC_IRCC_DRIVER_NAME, - }, -}; - /* Module parameters */ static int qos_mtt_bits = 0x07; /* 1 ms or more */ static int dongle_id; /* Use BIOS settions by default, but user may supply module parameters */ -static unsigned int io[] = { ~0, ~0, ~0, ~0, ~0 }; -static unsigned int irq[] = { 0, 0, 0, 0, 0 }; -static unsigned int dma[] = { 0, 0, 0, 0, 0 }; +static unsigned int io[] = { ~0, ~0, ~0, ~0 }; +static unsigned int irq[] = { 0, 0, 0, 0, 0 }; +static unsigned int dma[] = { 0, 0, 0, 0, 0 }; static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info); @@ -100,7 +87,6 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); -static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id); /* These are the known NSC chips */ static nsc_chip_t chips[] = { @@ -115,12 +101,11 @@ static nsc_chip_t chips[] = { /* Contributed by Jan Frey - IBM A30/A31 */ { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, nsc_ircc_probe_39x, nsc_ircc_init_39x }, - { "IBM", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff, - nsc_ircc_probe_39x, nsc_ircc_init_39x }, { NULL } }; -static struct nsc_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL, NULL }; +/* Max 4 instances for now */ +static struct nsc_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL }; static char *dongle_types[] = { "Differential serial interface", @@ -141,24 +126,8 @@ static char *dongle_types[] = { "No dongle connected", }; -/* PNP probing */ -static chipio_t pnp_info; -static const struct pnp_device_id nsc_ircc_pnp_table[] = { - { .id = "NSC6001", .driver_data = 0 }, - { .id = "IBM0071", .driver_data = 0 }, - { } -}; - -MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table); - -static struct pnp_driver nsc_ircc_pnp_driver = { - .name = "nsc-ircc", - .id_table = nsc_ircc_pnp_table, - .probe = nsc_ircc_pnp_probe, -}; - /* Some prototypes */ -static int nsc_ircc_open(chipio_t *info); +static int nsc_ircc_open(int i, chipio_t *info); static int nsc_ircc_close(struct nsc_ircc_cb *self); static int nsc_ircc_setup(chipio_t *info); static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self); @@ -177,10 +146,7 @@ static int nsc_ircc_net_open(struct net_device *dev); static int nsc_ircc_net_close(struct net_device *dev); static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev); - -/* Globals */ -static int pnp_registered; -static int pnp_succeeded; +static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data); /* * Function nsc_ircc_init () @@ -192,36 +158,28 @@ static int __init nsc_ircc_init(void) { chipio_t info; nsc_chip_t *chip; - int ret; + int ret = -ENODEV; int cfg_base; int cfg, id; int reg; int i = 0; - ret = platform_driver_register(&nsc_ircc_driver); - if (ret) { - IRDA_ERROR("%s, Can't register driver!\n", driver_name); - return ret; - } - - /* Register with PnP subsystem to detect disable ports */ - ret = pnp_register_driver(&nsc_ircc_pnp_driver); - - if (!ret) - pnp_registered = 1; - - ret = -ENODEV; - /* Probe for all the NSC chipsets we know about */ - for (chip = chips; chip->name ; chip++) { + for (chip=chips; chip->name ; chip++) { IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__, chip->name); /* Try all config registers for this chip */ - for (cfg = 0; cfg < ARRAY_SIZE(chip->cfg); cfg++) { + for (cfg=0; cfg<3; cfg++) { cfg_base = chip->cfg[cfg]; if (!cfg_base) continue; + + memset(&info, 0, sizeof(chipio_t)); + info.cfg_base = cfg_base; + info.fir_base = io[i]; + info.dma = dma[i]; + info.irq = irq[i]; /* Read index register */ reg = inb(cfg_base); @@ -236,65 +194,24 @@ static int __init nsc_ircc_init(void) if ((id & chip->cid_mask) == chip->cid_value) { IRDA_DEBUG(2, "%s() Found %s chip, revision=%d\n", __FUNCTION__, chip->name, id & ~chip->cid_mask); + /* + * If the user supplies the base address, then + * we init the chip, if not we probe the values + * set by the BIOS + */ + if (io[i] < 0x2000) { + chip->init(chip, &info); + } else + chip->probe(chip, &info); - /* - * If we found a correct PnP setting, - * we first try it. - */ - if (pnp_succeeded) { - memset(&info, 0, sizeof(chipio_t)); - info.cfg_base = cfg_base; - info.fir_base = pnp_info.fir_base; - info.dma = pnp_info.dma; - info.irq = pnp_info.irq; - - if (info.fir_base < 0x2000) { - IRDA_MESSAGE("%s, chip->init\n", driver_name); - chip->init(chip, &info); - } else - chip->probe(chip, &info); - - if (nsc_ircc_open(&info) >= 0) - ret = 0; - } - - /* - * Opening based on PnP values failed. - * Let's fallback to user values, or probe - * the chip. - */ - if (ret) { - IRDA_DEBUG(2, "%s, PnP init failed\n", driver_name); - memset(&info, 0, sizeof(chipio_t)); - info.cfg_base = cfg_base; - info.fir_base = io[i]; - info.dma = dma[i]; - info.irq = irq[i]; - - /* - * If the user supplies the base address, then - * we init the chip, if not we probe the values - * set by the BIOS - */ - if (io[i] < 0x2000) { - chip->init(chip, &info); - } else - chip->probe(chip, &info); - - if (nsc_ircc_open(&info) >= 0) - ret = 0; - } + if (nsc_ircc_open(i, &info) == 0) + ret = 0; i++; } else { IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __FUNCTION__, id); } } - } - - if (ret) { - platform_driver_unregister(&nsc_ircc_driver); - pnp_unregister_driver(&nsc_ircc_pnp_driver); - pnp_registered = 0; + } return ret; @@ -310,17 +227,12 @@ static void __exit nsc_ircc_cleanup(void) { int i; - for (i = 0; i < ARRAY_SIZE(dev_self); i++) { + pm_unregister_all(nsc_ircc_pmproc); + + for (i=0; i < 4; i++) { if (dev_self[i]) nsc_ircc_close(dev_self[i]); } - - platform_driver_unregister(&nsc_ircc_driver); - - if (pnp_registered) - pnp_unregister_driver(&nsc_ircc_pnp_driver); - - pnp_registered = 0; } /* @@ -329,26 +241,16 @@ static void __exit nsc_ircc_cleanup(void) * Open driver instance * */ -static int __init nsc_ircc_open(chipio_t *info) +static int __init nsc_ircc_open(int i, chipio_t *info) { struct net_device *dev; struct nsc_ircc_cb *self; + struct pm_dev *pmdev; void *ret; - int err, chip_index; + int err; IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - for (chip_index = 0; chip_index < ARRAY_SIZE(dev_self); chip_index++) { - if (!dev_self[chip_index]) - break; - } - - if (chip_index == ARRAY_SIZE(dev_self)) { - IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __FUNCTION__); - return -ENOMEM; - } - IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name, info->cfg_base); @@ -369,8 +271,8 @@ static int __init nsc_ircc_open(chipio_t *info) spin_lock_init(&self->lock); /* Need to store self somewhere */ - dev_self[chip_index] = self; - self->index = chip_index; + dev_self[i] = self; + self->index = i; /* Initialize IO */ self->io.cfg_base = info->cfg_base; @@ -449,7 +351,7 @@ static int __init nsc_ircc_open(chipio_t *info) /* Check if user has supplied a valid dongle id or not */ if ((dongle_id <= 0) || - (dongle_id >= ARRAY_SIZE(dongle_types))) { + (dongle_id >= (sizeof(dongle_types) / sizeof(dongle_types[0]))) ) { dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base); IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name, @@ -462,18 +364,11 @@ static int __init nsc_ircc_open(chipio_t *info) self->io.dongle_id = dongle_id; nsc_ircc_init_dongle_interface(self->io.fir_base, dongle_id); - self->pldev = platform_device_register_simple(NSC_IRCC_DRIVER_NAME, - self->index, NULL, 0); - if (IS_ERR(self->pldev)) { - err = PTR_ERR(self->pldev); - goto out5; - } - platform_set_drvdata(self->pldev, self); + pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, nsc_ircc_pmproc); + if (pmdev) + pmdev->data = self; - return chip_index; - - out5: - unregister_netdev(dev); + return 0; out4: dma_free_coherent(NULL, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); @@ -484,7 +379,7 @@ static int __init nsc_ircc_open(chipio_t *info) release_region(self->io.fir_base, self->io.fir_ext); out1: free_netdev(dev); - dev_self[chip_index] = NULL; + dev_self[i] = NULL; return err; } @@ -504,8 +399,6 @@ static int __exit nsc_ircc_close(struct nsc_ircc_cb *self) iobase = self->io.fir_base; - platform_device_unregister(self->pldev); - /* Remove netdevice */ unregister_netdev(self->netdev); @@ -812,7 +705,7 @@ static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info) int cfg_base = info->cfg_base; int enabled; - /* User is sure about his config... accept it. */ + /* User is shure about his config... accept it. */ IRDA_DEBUG(2, "%s(): nsc_ircc_init_39x (user settings): " "io=0x%04x, irq=%d, dma=%d\n", __FUNCTION__, info->fir_base, info->irq, info->dma); @@ -913,43 +806,6 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) return 0; } -/* PNP probing */ -static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) -{ - memset(&pnp_info, 0, sizeof(chipio_t)); - pnp_info.irq = -1; - pnp_info.dma = -1; - pnp_succeeded = 1; - - /* There don't seem to be any way to get the cfg_base. - * On my box, cfg_base is in the PnP descriptor of the - * motherboard. Oh well... Jean II */ - - if (pnp_port_valid(dev, 0) && - !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) - pnp_info.fir_base = pnp_port_start(dev, 0); - - if (pnp_irq_valid(dev, 0) && - !(pnp_irq_flags(dev, 0) & IORESOURCE_DISABLED)) - pnp_info.irq = pnp_irq(dev, 0); - - if (pnp_dma_valid(dev, 0) && - !(pnp_dma_flags(dev, 0) & IORESOURCE_DISABLED)) - pnp_info.dma = pnp_dma(dev, 0); - - IRDA_DEBUG(0, "%s() : From PnP, found firbase 0x%03X ; irq %d ; dma %d.\n", - __FUNCTION__, pnp_info.fir_base, pnp_info.irq, pnp_info.dma); - - if((pnp_info.fir_base == 0) || - (pnp_info.irq == -1) || (pnp_info.dma == -1)) { - /* Returning an error will disable the device. Yuck ! */ - //return -EINVAL; - pnp_succeeded = 0; - } - - return 0; -} - /* * Function nsc_ircc_setup (info) * @@ -2305,83 +2161,45 @@ static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev) return &self->stats; } -static int nsc_ircc_suspend(struct platform_device *dev, pm_message_t state) +static void nsc_ircc_suspend(struct nsc_ircc_cb *self) { - struct nsc_ircc_cb *self = platform_get_drvdata(dev); - int bank; - unsigned long flags; - int iobase = self->io.fir_base; + IRDA_MESSAGE("%s, Suspending\n", driver_name); if (self->io.suspended) - return 0; + return; - IRDA_DEBUG(1, "%s, Suspending\n", driver_name); + nsc_ircc_net_close(self->netdev); - rtnl_lock(); - if (netif_running(self->netdev)) { - netif_device_detach(self->netdev); - spin_lock_irqsave(&self->lock, flags); - /* Save current bank */ - bank = inb(iobase+BSR); - - /* Disable interrupts */ - switch_bank(iobase, BANK0); - outb(0, iobase+IER); - - /* Restore bank register */ - outb(bank, iobase+BSR); - - spin_unlock_irqrestore(&self->lock, flags); - free_irq(self->io.irq, self->netdev); - disable_dma(self->io.dma); - } self->io.suspended = 1; - rtnl_unlock(); - - return 0; } -static int nsc_ircc_resume(struct platform_device *dev) +static void nsc_ircc_wakeup(struct nsc_ircc_cb *self) { - struct nsc_ircc_cb *self = platform_get_drvdata(dev); - unsigned long flags; - if (!self->io.suspended) - return 0; + return; - IRDA_DEBUG(1, "%s, Waking up\n", driver_name); - - rtnl_lock(); nsc_ircc_setup(&self->io); - nsc_ircc_init_dongle_interface(self->io.fir_base, self->io.dongle_id); - - if (netif_running(self->netdev)) { - if (request_irq(self->io.irq, nsc_ircc_interrupt, 0, - self->netdev->name, self->netdev)) { - IRDA_WARNING("%s, unable to allocate irq=%d\n", - driver_name, self->io.irq); - - /* - * Don't fail resume process, just kill this - * network interface - */ - unregister_netdevice(self->netdev); - } else { - spin_lock_irqsave(&self->lock, flags); - nsc_ircc_change_speed(self, self->io.speed); - spin_unlock_irqrestore(&self->lock, flags); - netif_device_attach(self->netdev); - } + nsc_ircc_net_open(self->netdev); + + IRDA_MESSAGE("%s, Waking up\n", driver_name); - } else { - spin_lock_irqsave(&self->lock, flags); - nsc_ircc_change_speed(self, 9600); - spin_unlock_irqrestore(&self->lock, flags); - } self->io.suspended = 0; - rtnl_unlock(); +} - return 0; +static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data) +{ + struct nsc_ircc_cb *self = (struct nsc_ircc_cb*) dev->data; + if (self) { + switch (rqst) { + case PM_SUSPEND: + nsc_ircc_suspend(self); + break; + case PM_RESUME: + nsc_ircc_wakeup(self); + break; + } + } + return 0; } MODULE_AUTHOR("Dag Brattli "); diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h index dacf671ab..6edf7e514 100644 --- a/drivers/net/irda/nsc-ircc.h +++ b/drivers/net/irda/nsc-ircc.h @@ -269,7 +269,7 @@ struct nsc_ircc_cb { __u32 new_speed; int index; /* Instance index */ - struct platform_device *pldev; + struct pm_dev *dev; }; static inline void switch_bank(int iobase, int bank) diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index f530686bd..63d38fbbd 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -695,7 +695,8 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) /* * We must not be transmitting... */ - BUG_ON(si->txskb); + if (si->txskb) + BUG(); netif_stop_queue(dev); diff --git a/drivers/net/irda/sir-dev.h b/drivers/net/irda/sir-dev.h index 9fa294a54..f69fb4cec 100644 --- a/drivers/net/irda/sir-dev.h +++ b/drivers/net/irda/sir-dev.h @@ -15,14 +15,23 @@ #define IRDA_SIR_H #include -#include #include #include // iobuff_t +/* FIXME: unify irda_request with sir_fsm! */ + +struct irda_request { + struct list_head lh_request; + unsigned long pending; + void (*func)(void *); + void *data; + struct timer_list timer; +}; + struct sir_fsm { struct semaphore sem; - struct work_struct work; + struct irda_request rq; unsigned state, substate; int param; int result; diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 3b5854d10..ea7c9464d 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -23,298 +23,6 @@ #include "sir-dev.h" - -static struct workqueue_struct *irda_sir_wq; - -/* STATE MACHINE */ - -/* substate handler of the config-fsm to handle the cases where we want - * to wait for transmit completion before changing the port configuration - */ - -static int sirdev_tx_complete_fsm(struct sir_dev *dev) -{ - struct sir_fsm *fsm = &dev->fsm; - unsigned next_state, delay; - unsigned bytes_left; - - do { - next_state = fsm->substate; /* default: stay in current substate */ - delay = 0; - - switch(fsm->substate) { - - case SIRDEV_STATE_WAIT_XMIT: - if (dev->drv->chars_in_buffer) - bytes_left = dev->drv->chars_in_buffer(dev); - else - bytes_left = 0; - if (!bytes_left) { - next_state = SIRDEV_STATE_WAIT_UNTIL_SENT; - break; - } - - if (dev->speed > 115200) - delay = (bytes_left*8*10000) / (dev->speed/100); - else if (dev->speed > 0) - delay = (bytes_left*10*10000) / (dev->speed/100); - else - delay = 0; - /* expected delay (usec) until remaining bytes are sent */ - if (delay < 100) { - udelay(delay); - delay = 0; - break; - } - /* sleep some longer delay (msec) */ - delay = (delay+999) / 1000; - break; - - case SIRDEV_STATE_WAIT_UNTIL_SENT: - /* block until underlaying hardware buffer are empty */ - if (dev->drv->wait_until_sent) - dev->drv->wait_until_sent(dev); - next_state = SIRDEV_STATE_TX_DONE; - break; - - case SIRDEV_STATE_TX_DONE: - return 0; - - default: - IRDA_ERROR("%s - undefined state\n", __FUNCTION__); - return -EINVAL; - } - fsm->substate = next_state; - } while (delay == 0); - return delay; -} - -/* - * Function sirdev_config_fsm - * - * State machine to handle the configuration of the device (and attached dongle, if any). - * This handler is scheduled for execution in kIrDAd context, so we can sleep. - * however, kIrDAd is shared by all sir_dev devices so we better don't sleep there too - * long. Instead, for longer delays we start a timer to reschedule us later. - * On entry, fsm->sem is always locked and the netdev xmit queue stopped. - * Both must be unlocked/restarted on completion - but only on final exit. - */ - -static void sirdev_config_fsm(void *data) -{ - struct sir_dev *dev = data; - struct sir_fsm *fsm = &dev->fsm; - int next_state; - int ret = -1; - unsigned delay; - - IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); - - do { - IRDA_DEBUG(3, "%s - state=0x%04x / substate=0x%04x\n", - __FUNCTION__, fsm->state, fsm->substate); - - next_state = fsm->state; - delay = 0; - - switch(fsm->state) { - - case SIRDEV_STATE_DONGLE_OPEN: - if (dev->dongle_drv != NULL) { - ret = sirdev_put_dongle(dev); - if (ret) { - fsm->result = -EINVAL; - next_state = SIRDEV_STATE_ERROR; - break; - } - } - - /* Initialize dongle */ - ret = sirdev_get_dongle(dev, fsm->param); - if (ret) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - - /* Dongles are powered through the modem control lines which - * were just set during open. Before resetting, let's wait for - * the power to stabilize. This is what some dongle drivers did - * in open before, while others didn't - should be safe anyway. - */ - - delay = 50; - fsm->substate = SIRDEV_STATE_DONGLE_RESET; - next_state = SIRDEV_STATE_DONGLE_RESET; - - fsm->param = 9600; - - break; - - case SIRDEV_STATE_DONGLE_CLOSE: - /* shouldn't we just treat this as success=? */ - if (dev->dongle_drv == NULL) { - fsm->result = -EINVAL; - next_state = SIRDEV_STATE_ERROR; - break; - } - - ret = sirdev_put_dongle(dev); - if (ret) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - next_state = SIRDEV_STATE_DONE; - break; - - case SIRDEV_STATE_SET_DTR_RTS: - ret = sirdev_set_dtr_rts(dev, - (fsm->param&0x02) ? TRUE : FALSE, - (fsm->param&0x01) ? TRUE : FALSE); - next_state = SIRDEV_STATE_DONE; - break; - - case SIRDEV_STATE_SET_SPEED: - fsm->substate = SIRDEV_STATE_WAIT_XMIT; - next_state = SIRDEV_STATE_DONGLE_CHECK; - break; - - case SIRDEV_STATE_DONGLE_CHECK: - ret = sirdev_tx_complete_fsm(dev); - if (ret < 0) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - if ((delay=ret) != 0) - break; - - if (dev->dongle_drv) { - fsm->substate = SIRDEV_STATE_DONGLE_RESET; - next_state = SIRDEV_STATE_DONGLE_RESET; - } - else { - dev->speed = fsm->param; - next_state = SIRDEV_STATE_PORT_SPEED; - } - break; - - case SIRDEV_STATE_DONGLE_RESET: - if (dev->dongle_drv->reset) { - ret = dev->dongle_drv->reset(dev); - if (ret < 0) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - } - else - ret = 0; - if ((delay=ret) == 0) { - /* set serial port according to dongle default speed */ - if (dev->drv->set_speed) - dev->drv->set_speed(dev, dev->speed); - fsm->substate = SIRDEV_STATE_DONGLE_SPEED; - next_state = SIRDEV_STATE_DONGLE_SPEED; - } - break; - - case SIRDEV_STATE_DONGLE_SPEED: - if (dev->dongle_drv->reset) { - ret = dev->dongle_drv->set_speed(dev, fsm->param); - if (ret < 0) { - fsm->result = ret; - next_state = SIRDEV_STATE_ERROR; - break; - } - } - else - ret = 0; - if ((delay=ret) == 0) - next_state = SIRDEV_STATE_PORT_SPEED; - break; - - case SIRDEV_STATE_PORT_SPEED: - /* Finally we are ready to change the serial port speed */ - if (dev->drv->set_speed) - dev->drv->set_speed(dev, dev->speed); - dev->new_speed = 0; - next_state = SIRDEV_STATE_DONE; - break; - - case SIRDEV_STATE_DONE: - /* Signal network layer so it can send more frames */ - netif_wake_queue(dev->netdev); - next_state = SIRDEV_STATE_COMPLETE; - break; - - default: - IRDA_ERROR("%s - undefined state\n", __FUNCTION__); - fsm->result = -EINVAL; - /* fall thru */ - - case SIRDEV_STATE_ERROR: - IRDA_ERROR("%s - error: %d\n", __FUNCTION__, fsm->result); - -#if 0 /* don't enable this before we have netdev->tx_timeout to recover */ - netif_stop_queue(dev->netdev); -#else - netif_wake_queue(dev->netdev); -#endif - /* fall thru */ - - case SIRDEV_STATE_COMPLETE: - /* config change finished, so we are not busy any longer */ - sirdev_enable_rx(dev); - up(&fsm->sem); - return; - } - fsm->state = next_state; - } while(!delay); - - queue_delayed_work(irda_sir_wq, &fsm->work, msecs_to_jiffies(delay)); -} - -/* schedule some device configuration task for execution by kIrDAd - * on behalf of the above state machine. - * can be called from process or interrupt/tasklet context. - */ - -int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned param) -{ - struct sir_fsm *fsm = &dev->fsm; - - IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, initial_state, param); - - if (down_trylock(&fsm->sem)) { - if (in_interrupt() || in_atomic() || irqs_disabled()) { - IRDA_DEBUG(1, "%s(), state machine busy!\n", __FUNCTION__); - return -EWOULDBLOCK; - } else - down(&fsm->sem); - } - - if (fsm->state == SIRDEV_STATE_DEAD) { - /* race with sirdev_close should never happen */ - IRDA_ERROR("%s(), instance staled!\n", __FUNCTION__); - up(&fsm->sem); - return -ESTALE; /* or better EPIPE? */ - } - - netif_stop_queue(dev->netdev); - atomic_set(&dev->enable_rx, 0); - - fsm->state = initial_state; - fsm->param = param; - fsm->result = 0; - - INIT_WORK(&fsm->work, sirdev_config_fsm, dev); - queue_work(irda_sir_wq, &fsm->work); - return 0; -} - - /***************************************************************************/ void sirdev_enable_rx(struct sir_dev *dev) @@ -911,6 +619,10 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n spin_lock_init(&dev->tx_lock); init_MUTEX(&dev->fsm.sem); + INIT_LIST_HEAD(&dev->fsm.rq.lh_request); + dev->fsm.rq.pending = 0; + init_timer(&dev->fsm.rq.timer); + dev->drv = drv; dev->netdev = ndev; @@ -970,22 +682,3 @@ int sirdev_put_instance(struct sir_dev *dev) } EXPORT_SYMBOL(sirdev_put_instance); -static int __init sir_wq_init(void) -{ - irda_sir_wq = create_singlethread_workqueue("irda_sir_wq"); - if (!irda_sir_wq) - return -ENOMEM; - return 0; -} - -static void __exit sir_wq_exit(void) -{ - destroy_workqueue(irda_sir_wq); -} - -module_init(sir_wq_init); -module_exit(sir_wq_exit); - -MODULE_AUTHOR("Martin Diehl "); -MODULE_DESCRIPTION("IrDA SIR core"); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c index d7e32d955..8d225921a 100644 --- a/drivers/net/irda/sir_dongle.c +++ b/drivers/net/irda/sir_dongle.c @@ -16,7 +16,6 @@ #include #include #include -#include #include @@ -29,7 +28,7 @@ */ static LIST_HEAD(dongle_list); /* list of registered dongle drivers */ -static DEFINE_MUTEX(dongle_list_lock); /* protects the list */ +static DECLARE_MUTEX(dongle_list_lock); /* protects the list */ int irda_register_dongle(struct dongle_driver *new) { @@ -39,25 +38,25 @@ int irda_register_dongle(struct dongle_driver *new) IRDA_DEBUG(0, "%s : registering dongle \"%s\" (%d).\n", __FUNCTION__, new->driver_name, new->type); - mutex_lock(&dongle_list_lock); + down(&dongle_list_lock); list_for_each(entry, &dongle_list) { drv = list_entry(entry, struct dongle_driver, dongle_list); if (new->type == drv->type) { - mutex_unlock(&dongle_list_lock); + up(&dongle_list_lock); return -EEXIST; } } list_add(&new->dongle_list, &dongle_list); - mutex_unlock(&dongle_list_lock); + up(&dongle_list_lock); return 0; } EXPORT_SYMBOL(irda_register_dongle); int irda_unregister_dongle(struct dongle_driver *drv) { - mutex_lock(&dongle_list_lock); + down(&dongle_list_lock); list_del(&drv->dongle_list); - mutex_unlock(&dongle_list_lock); + up(&dongle_list_lock); return 0; } EXPORT_SYMBOL(irda_unregister_dongle); @@ -76,7 +75,7 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type) return -EBUSY; /* serialize access to the list of registered dongles */ - mutex_lock(&dongle_list_lock); + down(&dongle_list_lock); list_for_each(entry, &dongle_list) { drv = list_entry(entry, struct dongle_driver, dongle_list); @@ -110,14 +109,14 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type) if (!drv->open || (err=drv->open(dev))!=0) goto out_reject; /* failed to open driver */ - mutex_unlock(&dongle_list_lock); + up(&dongle_list_lock); return 0; out_reject: dev->dongle_drv = NULL; module_put(drv->owner); out_unlock: - mutex_unlock(&dongle_list_lock); + up(&dongle_list_lock); return err; } diff --git a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c new file mode 100644 index 000000000..e3904d6bf --- /dev/null +++ b/drivers/net/irda/sir_kthread.c @@ -0,0 +1,508 @@ +/********************************************************************* + * + * sir_kthread.c: dedicated thread to process scheduled + * sir device setup requests + * + * Copyright (c) 2002 Martin Diehl + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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 +#include +#include +#include +#include +#include +#include + +#include + +#include "sir-dev.h" + +/************************************************************************** + * + * kIrDAd kernel thread and config state machine + * + */ + +struct irda_request_queue { + struct list_head request_list; + spinlock_t lock; + task_t *thread; + struct completion exit; + wait_queue_head_t kick, done; + atomic_t num_pending; +}; + +static struct irda_request_queue irda_rq_queue; + +static int irda_queue_request(struct irda_request *rq) +{ + int ret = 0; + unsigned long flags; + + if (!test_and_set_bit(0, &rq->pending)) { + spin_lock_irqsave(&irda_rq_queue.lock, flags); + list_add_tail(&rq->lh_request, &irda_rq_queue.request_list); + wake_up(&irda_rq_queue.kick); + atomic_inc(&irda_rq_queue.num_pending); + spin_unlock_irqrestore(&irda_rq_queue.lock, flags); + ret = 1; + } + return ret; +} + +static void irda_request_timer(unsigned long data) +{ + struct irda_request *rq = (struct irda_request *)data; + unsigned long flags; + + spin_lock_irqsave(&irda_rq_queue.lock, flags); + list_add_tail(&rq->lh_request, &irda_rq_queue.request_list); + wake_up(&irda_rq_queue.kick); + spin_unlock_irqrestore(&irda_rq_queue.lock, flags); +} + +static int irda_queue_delayed_request(struct irda_request *rq, unsigned long delay) +{ + int ret = 0; + struct timer_list *timer = &rq->timer; + + if (!test_and_set_bit(0, &rq->pending)) { + timer->expires = jiffies + delay; + timer->function = irda_request_timer; + timer->data = (unsigned long)rq; + atomic_inc(&irda_rq_queue.num_pending); + add_timer(timer); + ret = 1; + } + return ret; +} + +static void run_irda_queue(void) +{ + unsigned long flags; + struct list_head *entry, *tmp; + struct irda_request *rq; + + spin_lock_irqsave(&irda_rq_queue.lock, flags); + list_for_each_safe(entry, tmp, &irda_rq_queue.request_list) { + rq = list_entry(entry, struct irda_request, lh_request); + list_del_init(entry); + spin_unlock_irqrestore(&irda_rq_queue.lock, flags); + + clear_bit(0, &rq->pending); + rq->func(rq->data); + + if (atomic_dec_and_test(&irda_rq_queue.num_pending)) + wake_up(&irda_rq_queue.done); + + spin_lock_irqsave(&irda_rq_queue.lock, flags); + } + spin_unlock_irqrestore(&irda_rq_queue.lock, flags); +} + +static int irda_thread(void *startup) +{ + DECLARE_WAITQUEUE(wait, current); + + daemonize("kIrDAd"); + + irda_rq_queue.thread = current; + + complete((struct completion *)startup); + + while (irda_rq_queue.thread != NULL) { + + /* We use TASK_INTERRUPTIBLE, rather than + * TASK_UNINTERRUPTIBLE. Andrew Morton made this + * change ; he told me that it is safe, because "signal + * blocking is now handled in daemonize()", he added + * that the problem is that "uninterruptible sleep + * contributes to load average", making user worry. + * Jean II */ + set_task_state(current, TASK_INTERRUPTIBLE); + add_wait_queue(&irda_rq_queue.kick, &wait); + if (list_empty(&irda_rq_queue.request_list)) + schedule(); + else + __set_task_state(current, TASK_RUNNING); + remove_wait_queue(&irda_rq_queue.kick, &wait); + + /* make swsusp happy with our thread */ + try_to_freeze(); + + run_irda_queue(); + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,35) + reparent_to_init(); +#endif + complete_and_exit(&irda_rq_queue.exit, 0); + /* never reached */ + return 0; +} + + +static void flush_irda_queue(void) +{ + if (atomic_read(&irda_rq_queue.num_pending)) { + + DECLARE_WAITQUEUE(wait, current); + + if (!list_empty(&irda_rq_queue.request_list)) + run_irda_queue(); + + set_task_state(current, TASK_UNINTERRUPTIBLE); + add_wait_queue(&irda_rq_queue.done, &wait); + if (atomic_read(&irda_rq_queue.num_pending)) + schedule(); + else + __set_task_state(current, TASK_RUNNING); + remove_wait_queue(&irda_rq_queue.done, &wait); + } +} + +/* substate handler of the config-fsm to handle the cases where we want + * to wait for transmit completion before changing the port configuration + */ + +static int irda_tx_complete_fsm(struct sir_dev *dev) +{ + struct sir_fsm *fsm = &dev->fsm; + unsigned next_state, delay; + unsigned bytes_left; + + do { + next_state = fsm->substate; /* default: stay in current substate */ + delay = 0; + + switch(fsm->substate) { + + case SIRDEV_STATE_WAIT_XMIT: + if (dev->drv->chars_in_buffer) + bytes_left = dev->drv->chars_in_buffer(dev); + else + bytes_left = 0; + if (!bytes_left) { + next_state = SIRDEV_STATE_WAIT_UNTIL_SENT; + break; + } + + if (dev->speed > 115200) + delay = (bytes_left*8*10000) / (dev->speed/100); + else if (dev->speed > 0) + delay = (bytes_left*10*10000) / (dev->speed/100); + else + delay = 0; + /* expected delay (usec) until remaining bytes are sent */ + if (delay < 100) { + udelay(delay); + delay = 0; + break; + } + /* sleep some longer delay (msec) */ + delay = (delay+999) / 1000; + break; + + case SIRDEV_STATE_WAIT_UNTIL_SENT: + /* block until underlaying hardware buffer are empty */ + if (dev->drv->wait_until_sent) + dev->drv->wait_until_sent(dev); + next_state = SIRDEV_STATE_TX_DONE; + break; + + case SIRDEV_STATE_TX_DONE: + return 0; + + default: + IRDA_ERROR("%s - undefined state\n", __FUNCTION__); + return -EINVAL; + } + fsm->substate = next_state; + } while (delay == 0); + return delay; +} + +/* + * Function irda_config_fsm + * + * State machine to handle the configuration of the device (and attached dongle, if any). + * This handler is scheduled for execution in kIrDAd context, so we can sleep. + * however, kIrDAd is shared by all sir_dev devices so we better don't sleep there too + * long. Instead, for longer delays we start a timer to reschedule us later. + * On entry, fsm->sem is always locked and the netdev xmit queue stopped. + * Both must be unlocked/restarted on completion - but only on final exit. + */ + +static void irda_config_fsm(void *data) +{ + struct sir_dev *dev = data; + struct sir_fsm *fsm = &dev->fsm; + int next_state; + int ret = -1; + unsigned delay; + + IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); + + do { + IRDA_DEBUG(3, "%s - state=0x%04x / substate=0x%04x\n", + __FUNCTION__, fsm->state, fsm->substate); + + next_state = fsm->state; + delay = 0; + + switch(fsm->state) { + + case SIRDEV_STATE_DONGLE_OPEN: + if (dev->dongle_drv != NULL) { + ret = sirdev_put_dongle(dev); + if (ret) { + fsm->result = -EINVAL; + next_state = SIRDEV_STATE_ERROR; + break; + } + } + + /* Initialize dongle */ + ret = sirdev_get_dongle(dev, fsm->param); + if (ret) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + + /* Dongles are powered through the modem control lines which + * were just set during open. Before resetting, let's wait for + * the power to stabilize. This is what some dongle drivers did + * in open before, while others didn't - should be safe anyway. + */ + + delay = 50; + fsm->substate = SIRDEV_STATE_DONGLE_RESET; + next_state = SIRDEV_STATE_DONGLE_RESET; + + fsm->param = 9600; + + break; + + case SIRDEV_STATE_DONGLE_CLOSE: + /* shouldn't we just treat this as success=? */ + if (dev->dongle_drv == NULL) { + fsm->result = -EINVAL; + next_state = SIRDEV_STATE_ERROR; + break; + } + + ret = sirdev_put_dongle(dev); + if (ret) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + next_state = SIRDEV_STATE_DONE; + break; + + case SIRDEV_STATE_SET_DTR_RTS: + ret = sirdev_set_dtr_rts(dev, + (fsm->param&0x02) ? TRUE : FALSE, + (fsm->param&0x01) ? TRUE : FALSE); + next_state = SIRDEV_STATE_DONE; + break; + + case SIRDEV_STATE_SET_SPEED: + fsm->substate = SIRDEV_STATE_WAIT_XMIT; + next_state = SIRDEV_STATE_DONGLE_CHECK; + break; + + case SIRDEV_STATE_DONGLE_CHECK: + ret = irda_tx_complete_fsm(dev); + if (ret < 0) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + if ((delay=ret) != 0) + break; + + if (dev->dongle_drv) { + fsm->substate = SIRDEV_STATE_DONGLE_RESET; + next_state = SIRDEV_STATE_DONGLE_RESET; + } + else { + dev->speed = fsm->param; + next_state = SIRDEV_STATE_PORT_SPEED; + } + break; + + case SIRDEV_STATE_DONGLE_RESET: + if (dev->dongle_drv->reset) { + ret = dev->dongle_drv->reset(dev); + if (ret < 0) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + } + else + ret = 0; + if ((delay=ret) == 0) { + /* set serial port according to dongle default speed */ + if (dev->drv->set_speed) + dev->drv->set_speed(dev, dev->speed); + fsm->substate = SIRDEV_STATE_DONGLE_SPEED; + next_state = SIRDEV_STATE_DONGLE_SPEED; + } + break; + + case SIRDEV_STATE_DONGLE_SPEED: + if (dev->dongle_drv->reset) { + ret = dev->dongle_drv->set_speed(dev, fsm->param); + if (ret < 0) { + fsm->result = ret; + next_state = SIRDEV_STATE_ERROR; + break; + } + } + else + ret = 0; + if ((delay=ret) == 0) + next_state = SIRDEV_STATE_PORT_SPEED; + break; + + case SIRDEV_STATE_PORT_SPEED: + /* Finally we are ready to change the serial port speed */ + if (dev->drv->set_speed) + dev->drv->set_speed(dev, dev->speed); + dev->new_speed = 0; + next_state = SIRDEV_STATE_DONE; + break; + + case SIRDEV_STATE_DONE: + /* Signal network layer so it can send more frames */ + netif_wake_queue(dev->netdev); + next_state = SIRDEV_STATE_COMPLETE; + break; + + default: + IRDA_ERROR("%s - undefined state\n", __FUNCTION__); + fsm->result = -EINVAL; + /* fall thru */ + + case SIRDEV_STATE_ERROR: + IRDA_ERROR("%s - error: %d\n", __FUNCTION__, fsm->result); + +#if 0 /* don't enable this before we have netdev->tx_timeout to recover */ + netif_stop_queue(dev->netdev); +#else + netif_wake_queue(dev->netdev); +#endif + /* fall thru */ + + case SIRDEV_STATE_COMPLETE: + /* config change finished, so we are not busy any longer */ + sirdev_enable_rx(dev); + up(&fsm->sem); + return; + } + fsm->state = next_state; + } while(!delay); + + irda_queue_delayed_request(&fsm->rq, msecs_to_jiffies(delay)); +} + +/* schedule some device configuration task for execution by kIrDAd + * on behalf of the above state machine. + * can be called from process or interrupt/tasklet context. + */ + +int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned param) +{ + struct sir_fsm *fsm = &dev->fsm; + int xmit_was_down; + + IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, initial_state, param); + + if (down_trylock(&fsm->sem)) { + if (in_interrupt() || in_atomic() || irqs_disabled()) { + IRDA_DEBUG(1, "%s(), state machine busy!\n", __FUNCTION__); + return -EWOULDBLOCK; + } else + down(&fsm->sem); + } + + if (fsm->state == SIRDEV_STATE_DEAD) { + /* race with sirdev_close should never happen */ + IRDA_ERROR("%s(), instance staled!\n", __FUNCTION__); + up(&fsm->sem); + return -ESTALE; /* or better EPIPE? */ + } + + xmit_was_down = netif_queue_stopped(dev->netdev); + netif_stop_queue(dev->netdev); + atomic_set(&dev->enable_rx, 0); + + fsm->state = initial_state; + fsm->param = param; + fsm->result = 0; + + INIT_LIST_HEAD(&fsm->rq.lh_request); + fsm->rq.pending = 0; + fsm->rq.func = irda_config_fsm; + fsm->rq.data = dev; + + if (!irda_queue_request(&fsm->rq)) { /* returns 0 on error! */ + atomic_set(&dev->enable_rx, 1); + if (!xmit_was_down) + netif_wake_queue(dev->netdev); + up(&fsm->sem); + return -EAGAIN; + } + return 0; +} + +static int __init irda_thread_create(void) +{ + struct completion startup; + int pid; + + spin_lock_init(&irda_rq_queue.lock); + irda_rq_queue.thread = NULL; + INIT_LIST_HEAD(&irda_rq_queue.request_list); + init_waitqueue_head(&irda_rq_queue.kick); + init_waitqueue_head(&irda_rq_queue.done); + atomic_set(&irda_rq_queue.num_pending, 0); + + init_completion(&startup); + pid = kernel_thread(irda_thread, &startup, CLONE_FS|CLONE_FILES); + if (pid <= 0) + return -EAGAIN; + else + wait_for_completion(&startup); + + return 0; +} + +static void __exit irda_thread_join(void) +{ + if (irda_rq_queue.thread) { + flush_irda_queue(); + init_completion(&irda_rq_queue.exit); + irda_rq_queue.thread = NULL; + wake_up(&irda_rq_queue.kick); + wait_for_completion(&irda_rq_queue.exit); + } +} + +module_init(irda_thread_create); +module_exit(irda_thread_join); + +MODULE_AUTHOR("Martin Diehl "); +MODULE_DESCRIPTION("IrDA SIR core"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index a4674044b..ec94ecdb1 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -11,7 +11,6 @@ * Copyright (c) 2002 Daniele Peri * All Rights Reserved. * Copyright (c) 2002 Jean Tourrilhes - * Copyright (c) 2006 Linus Walleij * * * Based on smc-ircc.c: @@ -54,7 +53,6 @@ #include #include #include -#include #include #include @@ -63,9 +61,6 @@ #include #include -#ifdef CONFIG_PCI -#include -#endif #include #include @@ -105,22 +100,6 @@ MODULE_PARM_DESC(ircc_transceiver, "Transceiver type"); /* Types */ -#ifdef CONFIG_PCI -struct smsc_ircc_subsystem_configuration { - unsigned short vendor; /* PCI vendor ID */ - unsigned short device; /* PCI vendor ID */ - unsigned short subvendor; /* PCI subsystem vendor ID */ - unsigned short subdevice; /* PCI sybsystem device ID */ - unsigned short sir_io; /* I/O port for SIR */ - unsigned short fir_io; /* I/O port for FIR */ - unsigned char fir_irq; /* FIR IRQ */ - unsigned char fir_dma; /* FIR DMA */ - unsigned short cfg_base; /* I/O port for chip configuration */ - int (*preconfigure)(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); /* Preconfig function */ - const char *name; /* name shown as info */ -}; -#endif - struct smsc_transceiver { char *name; void (*set_for_speed)(int fir_base, u32 speed); @@ -223,18 +202,6 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); static int __init smsc_superio_fdc(unsigned short cfg_base); static int __init smsc_superio_lpc(unsigned short cfg_base); -#ifdef CONFIG_PCI -static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); -static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); -static void __init preconfigure_ali_port(struct pci_dev *dev, - unsigned short port); -static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); -static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, - unsigned short ircc_fir, - unsigned short ircc_sir, - unsigned char ircc_dma, - unsigned char ircc_irq); -#endif /* Transceivers specific functions */ @@ -359,16 +326,6 @@ static inline void register_bank(int iobase, int bank) iobase + IRCC_MASTER); } -#ifdef CONFIG_PNP -/* PNP hotplug support */ -static const struct pnp_device_id smsc_ircc_pnp_table[] = { - { .id = "SMCf010", .driver_data = 0 }, - /* and presumably others */ - { } -}; -MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); -#endif - /******************************************************************************* * @@ -396,13 +353,6 @@ static int __init smsc_ircc_init(void) return ret; } -#ifdef CONFIG_PCI - if (smsc_ircc_preconfigure_subsystems(ircc_cfg, ircc_fir, ircc_sir, ircc_dma, ircc_irq) < 0) { - /* Ignore errors from preconfiguration */ - IRDA_ERROR("%s, Preconfiguration failed !\n", driver_name); - } -#endif - dev_count = 0; if (ircc_fir > 0 && ircc_sir > 0) { @@ -2083,8 +2033,7 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self) /* PROBING * - * REVISIT we can be told about the device by PNP, and should use that info - * instead of probing hardware and creating a platform_device ... + * */ static int __init smsc_ircc_look_for_chips(void) @@ -2336,490 +2285,6 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) return ret; } -/* - * Look for some specific subsystem setups that need - * pre-configuration not properly done by the BIOS (especially laptops) - * This code is based in part on smcinit.c, tosh1800-smcinit.c - * and tosh2450-smcinit.c. The table lists the device entries - * for ISA bridges with an LPC (Low Pin Count) controller which - * handles the communication with the SMSC device. After the LPC - * controller is initialized through PCI, the SMSC device is initialized - * through a dedicated port in the ISA port-mapped I/O area, this latter - * area is used to configure the SMSC device with default - * SIR and FIR I/O ports, DMA and IRQ. Different vendors have - * used different sets of parameters and different control port - * addresses making a subsystem device table necessary. - */ -#ifdef CONFIG_PCI -#define PCIID_VENDOR_INTEL 0x8086 -#define PCIID_VENDOR_ALI 0x10b9 -static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitdata = { - { - .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ - .device = 0x24cc, - .subvendor = 0x103c, - .subdevice = 0x088c, - /* Quite certain these are the same for nc8000 as for nc6000 */ - .sir_io = 0x02f8, - .fir_io = 0x0130, - .fir_irq = 0x05, - .fir_dma = 0x03, - .cfg_base = 0x004e, - .preconfigure = preconfigure_through_82801, - .name = "HP nc8000", - }, - { - .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ - .device = 0x24cc, - .subvendor = 0x103c, - .subdevice = 0x0890, - .sir_io = 0x02f8, - .fir_io = 0x0130, - .fir_irq = 0x05, - .fir_dma = 0x03, - .cfg_base = 0x004e, - .preconfigure = preconfigure_through_82801, - .name = "HP nc6000", - }, - { - /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ - .vendor = PCIID_VENDOR_INTEL, - .device = 0x24c0, - .subvendor = 0x1179, - .subdevice = 0xffff, /* 0xffff is "any" */ - .sir_io = 0x03f8, - .fir_io = 0x0130, - .fir_irq = 0x07, - .fir_dma = 0x01, - .cfg_base = 0x002e, - .preconfigure = preconfigure_through_82801, - .name = "Toshiba laptop with Intel 82801DB/DBL LPC bridge", - }, - { - .vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ - .device = 0x248c, - .subvendor = 0x1179, - .subdevice = 0xffff, /* 0xffff is "any" */ - .sir_io = 0x03f8, - .fir_io = 0x0130, - .fir_irq = 0x03, - .fir_dma = 0x03, - .cfg_base = 0x002e, - .preconfigure = preconfigure_through_82801, - .name = "Toshiba laptop with Intel 82801CAM ISA bridge", - }, - { - /* 82801DBM (ICH4-M) LPC Interface Bridge */ - .vendor = PCIID_VENDOR_INTEL, - .device = 0x24cc, - .subvendor = 0x1179, - .subdevice = 0xffff, /* 0xffff is "any" */ - .sir_io = 0x03f8, - .fir_io = 0x0130, - .fir_irq = 0x03, - .fir_dma = 0x03, - .cfg_base = 0x002e, - .preconfigure = preconfigure_through_82801, - .name = "Toshiba laptop with Intel 8281DBM LPC bridge", - }, - { - /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ - .vendor = PCIID_VENDOR_ALI, - .device = 0x1533, - .subvendor = 0x1179, - .subdevice = 0xffff, /* 0xffff is "any" */ - .sir_io = 0x02e8, - .fir_io = 0x02f8, - .fir_irq = 0x07, - .fir_dma = 0x03, - .cfg_base = 0x002e, - .preconfigure = preconfigure_through_ali, - .name = "Toshiba laptop with ALi ISA bridge", - }, - { } // Terminator -}; - - -/* - * This sets up the basic SMSC parameters - * (FIR port, SIR port, FIR DMA, FIR IRQ) - * through the chip configuration port. - */ -static int __init preconfigure_smsc_chip(struct - smsc_ircc_subsystem_configuration - *conf) -{ - unsigned short iobase = conf->cfg_base; - unsigned char tmpbyte; - - outb(LPC47N227_CFGACCESSKEY, iobase); // enter configuration state - outb(SMSCSIOFLAT_DEVICEID_REG, iobase); // set for device ID - tmpbyte = inb(iobase +1); // Read device ID - IRDA_DEBUG(0, - "Detected Chip id: 0x%02x, setting up registers...\n", - tmpbyte); - - /* Disable UART1 and set up SIR I/O port */ - outb(0x24, iobase); // select CR24 - UART1 base addr - outb(0x00, iobase + 1); // disable UART1 - outb(SMSCSIOFLAT_UART2BASEADDR_REG, iobase); // select CR25 - UART2 base addr - outb( (conf->sir_io >> 2), iobase + 1); // bits 2-9 of 0x3f8 - tmpbyte = inb(iobase + 1); - if (tmpbyte != (conf->sir_io >> 2) ) { - IRDA_WARNING("ERROR: could not configure SIR ioport.\n"); - IRDA_WARNING("Try to supply ircc_cfg argument.\n"); - return -ENXIO; - } - - /* Set up FIR IRQ channel for UART2 */ - outb(SMSCSIOFLAT_UARTIRQSELECT_REG, iobase); // select CR28 - UART1,2 IRQ select - tmpbyte = inb(iobase + 1); - tmpbyte &= SMSCSIOFLAT_UART1IRQSELECT_MASK; // Do not touch the UART1 portion - tmpbyte |= (conf->fir_irq & SMSCSIOFLAT_UART2IRQSELECT_MASK); - outb(tmpbyte, iobase + 1); - tmpbyte = inb(iobase + 1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; - if (tmpbyte != conf->fir_irq) { - IRDA_WARNING("ERROR: could not configure FIR IRQ channel.\n"); - return -ENXIO; - } - - /* Set up FIR I/O port */ - outb(SMSCSIOFLAT_FIRBASEADDR_REG, iobase); // CR2B - SCE (FIR) base addr - outb((conf->fir_io >> 3), iobase + 1); - tmpbyte = inb(iobase + 1); - if (tmpbyte != (conf->fir_io >> 3) ) { - IRDA_WARNING("ERROR: could not configure FIR I/O port.\n"); - return -ENXIO; - } - - /* Set up FIR DMA channel */ - outb(SMSCSIOFLAT_FIRDMASELECT_REG, iobase); // CR2C - SCE (FIR) DMA select - outb((conf->fir_dma & LPC47N227_FIRDMASELECT_MASK), iobase + 1); // DMA - tmpbyte = inb(iobase + 1) & LPC47N227_FIRDMASELECT_MASK; - if (tmpbyte != (conf->fir_dma & LPC47N227_FIRDMASELECT_MASK)) { - IRDA_WARNING("ERROR: could not configure FIR DMA channel.\n"); - return -ENXIO; - } - - outb(SMSCSIOFLAT_UARTMODE0C_REG, iobase); // CR0C - UART mode - tmpbyte = inb(iobase + 1); - tmpbyte &= ~SMSCSIOFLAT_UART2MODE_MASK | - SMSCSIOFLAT_UART2MODE_VAL_IRDA; - outb(tmpbyte, iobase + 1); // enable IrDA (HPSIR) mode, high speed - - outb(LPC47N227_APMBOOTDRIVE_REG, iobase); // CR07 - Auto Pwr Mgt/boot drive sel - tmpbyte = inb(iobase + 1); - outb(tmpbyte | LPC47N227_UART2AUTOPWRDOWN_MASK, iobase + 1); // enable UART2 autopower down - - /* This one was not part of tosh1800 */ - outb(0x0a, iobase); // CR0a - ecp fifo / ir mux - tmpbyte = inb(iobase + 1); - outb(tmpbyte | 0x40, iobase + 1); // send active device to ir port - - outb(LPC47N227_UART12POWER_REG, iobase); // CR02 - UART 1,2 power - tmpbyte = inb(iobase + 1); - outb(tmpbyte | LPC47N227_UART2POWERDOWN_MASK, iobase + 1); // UART2 power up mode, UART1 power down - - outb(LPC47N227_FDCPOWERVALIDCONF_REG, iobase); // CR00 - FDC Power/valid config cycle - tmpbyte = inb(iobase + 1); - outb(tmpbyte | LPC47N227_VALID_MASK, iobase + 1); // valid config cycle done - - outb(LPC47N227_CFGEXITKEY, iobase); // Exit configuration - - return 0; -} - -/* 82801CAM generic registers */ -#define VID 0x00 -#define DID 0x02 -#define PIRQ_A_D_ROUT 0x60 -#define SIRQ_CNTL 0x64 -#define PIRQ_E_H_ROUT 0x68 -#define PCI_DMA_C 0x90 -/* LPC-specific registers */ -#define COM_DEC 0xe0 -#define GEN1_DEC 0xe4 -#define LPC_EN 0xe6 -#define GEN2_DEC 0xec -/* - * Sets up the I/O range using the 82801CAM ISA bridge, 82801DBM LPC bridge - * or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. - * They all work the same way! - */ -static int __init preconfigure_through_82801(struct pci_dev *dev, - struct - smsc_ircc_subsystem_configuration - *conf) -{ - unsigned short tmpword; - unsigned char tmpbyte; - - IRDA_MESSAGE("Setting up Intel 82801 controller and SMSC device\n"); - /* - * Select the range for the COMA COM port (SIR) - * Register COM_DEC: - * Bit 7: reserved - * Bit 6-4, COMB decode range - * Bit 3: reserved - * Bit 2-0, COMA decode range - * - * Decode ranges: - * 000 = 0x3f8-0x3ff (COM1) - * 001 = 0x2f8-0x2ff (COM2) - * 010 = 0x220-0x227 - * 011 = 0x228-0x22f - * 100 = 0x238-0x23f - * 101 = 0x2e8-0x2ef (COM4) - * 110 = 0x338-0x33f - * 111 = 0x3e8-0x3ef (COM3) - */ - pci_read_config_byte(dev, COM_DEC, &tmpbyte); - tmpbyte &= 0xf8; /* mask COMA bits */ - switch(conf->sir_io) { - case 0x3f8: - tmpbyte |= 0x00; - break; - case 0x2f8: - tmpbyte |= 0x01; - break; - case 0x220: - tmpbyte |= 0x02; - break; - case 0x228: - tmpbyte |= 0x03; - break; - case 0x238: - tmpbyte |= 0x04; - break; - case 0x2e8: - tmpbyte |= 0x05; - break; - case 0x338: - tmpbyte |= 0x06; - break; - case 0x3e8: - tmpbyte |= 0x07; - break; - default: - tmpbyte |= 0x01; /* COM2 default */ - } - IRDA_DEBUG(1, "COM_DEC (write): 0x%02x\n", tmpbyte); - pci_write_config_byte(dev, COM_DEC, tmpbyte); - - /* Enable Low Pin Count interface */ - pci_read_config_word(dev, LPC_EN, &tmpword); - /* These seem to be set up at all times, - * just make sure it is properly set. - */ - switch(conf->cfg_base) { - case 0x04e: - tmpword |= 0x2000; - break; - case 0x02e: - tmpword |= 0x1000; - break; - case 0x062: - tmpword |= 0x0800; - break; - case 0x060: - tmpword |= 0x0400; - break; - default: - IRDA_WARNING("Uncommon I/O base address: 0x%04x\n", - conf->cfg_base); - break; - } - tmpword &= 0xfffd; /* disable LPC COMB */ - tmpword |= 0x0001; /* set bit 0 : enable LPC COMA addr range (GEN2) */ - IRDA_DEBUG(1, "LPC_EN (write): 0x%04x\n", tmpword); - pci_write_config_word(dev, LPC_EN, tmpword); - - /* - * Configure LPC DMA channel - * PCI_DMA_C bits: - * Bit 15-14: DMA channel 7 select - * Bit 13-12: DMA channel 6 select - * Bit 11-10: DMA channel 5 select - * Bit 9-8: Reserved - * Bit 7-6: DMA channel 3 select - * Bit 5-4: DMA channel 2 select - * Bit 3-2: DMA channel 1 select - * Bit 1-0: DMA channel 0 select - * 00 = Reserved value - * 01 = PC/PCI DMA - * 10 = Reserved value - * 11 = LPC I/F DMA - */ - pci_read_config_word(dev, PCI_DMA_C, &tmpword); - switch(conf->fir_dma) { - case 0x07: - tmpword |= 0xc000; - break; - case 0x06: - tmpword |= 0x3000; - break; - case 0x05: - tmpword |= 0x0c00; - break; - case 0x03: - tmpword |= 0x00c0; - break; - case 0x02: - tmpword |= 0x0030; - break; - case 0x01: - tmpword |= 0x000c; - break; - case 0x00: - tmpword |= 0x0003; - break; - default: - break; /* do not change settings */ - } - IRDA_DEBUG(1, "PCI_DMA_C (write): 0x%04x\n", tmpword); - pci_write_config_word(dev, PCI_DMA_C, tmpword); - - /* - * GEN2_DEC bits: - * Bit 15-4: Generic I/O range - * Bit 3-1: reserved (read as 0) - * Bit 0: enable GEN2 range on LPC I/F - */ - tmpword = conf->fir_io & 0xfff8; - tmpword |= 0x0001; - IRDA_DEBUG(1, "GEN2_DEC (write): 0x%04x\n", tmpword); - pci_write_config_word(dev, GEN2_DEC, tmpword); - - /* Pre-configure chip */ - return preconfigure_smsc_chip(conf); -} - -/* - * Pre-configure a certain port on the ALi 1533 bridge. - * This is based on reverse-engineering since ALi does not - * provide any data sheet for the 1533 chip. - */ -static void __init preconfigure_ali_port(struct pci_dev *dev, - unsigned short port) -{ - unsigned char reg; - /* These bits obviously control the different ports */ - unsigned char mask; - unsigned char tmpbyte; - - switch(port) { - case 0x0130: - case 0x0178: - reg = 0xb0; - mask = 0x80; - break; - case 0x03f8: - reg = 0xb4; - mask = 0x80; - break; - case 0x02f8: - reg = 0xb4; - mask = 0x30; - break; - case 0x02e8: - reg = 0xb4; - mask = 0x08; - break; - default: - IRDA_ERROR("Failed to configure unsupported port on ALi 1533 bridge: 0x%04x\n", port); - return; - } - - pci_read_config_byte(dev, reg, &tmpbyte); - /* Turn on the right bits */ - tmpbyte |= mask; - pci_write_config_byte(dev, reg, tmpbyte); - IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port); - return; -} - -static int __init preconfigure_through_ali(struct pci_dev *dev, - struct - smsc_ircc_subsystem_configuration - *conf) -{ - /* Configure the two ports on the ALi 1533 */ - preconfigure_ali_port(dev, conf->sir_io); - preconfigure_ali_port(dev, conf->fir_io); - - /* Pre-configure chip */ - return preconfigure_smsc_chip(conf); -} - -static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, - unsigned short ircc_fir, - unsigned short ircc_sir, - unsigned char ircc_dma, - unsigned char ircc_irq) -{ - struct pci_dev *dev = NULL; - unsigned short ss_vendor = 0x0000; - unsigned short ss_device = 0x0000; - int ret = 0; - - dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); - - while (dev != NULL) { - struct smsc_ircc_subsystem_configuration *conf; - - /* - * Cache the subsystem vendor/device: - * some manufacturers fail to set this for all components, - * so we save it in case there is just 0x0000 0x0000 on the - * device we want to check. - */ - if (dev->subsystem_vendor != 0x0000U) { - ss_vendor = dev->subsystem_vendor; - ss_device = dev->subsystem_device; - } - conf = subsystem_configurations; - for( ; conf->subvendor; conf++) { - if(conf->vendor == dev->vendor && - conf->device == dev->device && - conf->subvendor == ss_vendor && - /* Sometimes these are cached values */ - (conf->subdevice == ss_device || - conf->subdevice == 0xffff)) { - struct smsc_ircc_subsystem_configuration - tmpconf; - - memcpy(&tmpconf, conf, - sizeof(struct smsc_ircc_subsystem_configuration)); - - /* - * Override the default values with anything - * passed in as parameter - */ - if (ircc_cfg != 0) - tmpconf.cfg_base = ircc_cfg; - if (ircc_fir != 0) - tmpconf.fir_io = ircc_fir; - if (ircc_sir != 0) - tmpconf.sir_io = ircc_sir; - if (ircc_dma != 0xff) - tmpconf.fir_dma = ircc_dma; - if (ircc_irq != 0xff) - tmpconf.fir_irq = ircc_irq; - - IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); - if (conf->preconfigure) - ret = conf->preconfigure(dev, &tmpconf); - else - ret = -ENODEV; - } - } - dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); - } - - return ret; -} -#endif // CONFIG_PCI - /************************************************ * * Transceivers specific functions diff --git a/drivers/net/irda/toim3232-sir.c b/drivers/net/irda/toim3232-sir.c deleted file mode 100644 index aa1a9b0ed..000000000 --- a/drivers/net/irda/toim3232-sir.c +++ /dev/null @@ -1,375 +0,0 @@ -/********************************************************************* - * - * Filename: toim3232-sir.c - * Version: 1.0 - * Description: Implementation of dongles based on the Vishay/Temic - * TOIM3232 SIR Endec chipset. Currently only the - * IRWave IR320ST-2 is tested, although it should work - * with any TOIM3232 or TOIM4232 chipset based RS232 - * dongle with minimal modification. - * Based heavily on the Tekram driver (tekram.c), - * with thanks to Dag Brattli and Martin Diehl. - * Status: Experimental. - * Author: David Basden - * Created at: Thu Feb 09 23:47:32 2006 - * - * Copyright (c) 2006 David Basden. - * Copyright (c) 1998-1999 Dag Brattli, - * Copyright (c) 2002 Martin Diehl, - * 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. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -/* - * This driver has currently only been tested on the IRWave IR320ST-2 - * - * PROTOCOL: - * - * The protocol for talking to the TOIM3232 is quite easy, and is - * designed to interface with RS232 with only level convertors. The - * BR/~D line on the chip is brought high to signal 'command mode', - * where a command byte is sent to select the baudrate of the RS232 - * interface and the pulse length of the IRDA output. When BR/~D - * is brought low, the dongle then changes to the selected baudrate, - * and the RS232 interface is used for data until BR/~D is brought - * high again. The initial speed for the TOIMx323 after RESET is - * 9600 baud. The baudrate for command-mode is the last selected - * baud-rate, or 9600 after a RESET. - * - * The dongle I have (below) adds some extra hardware on the front end, - * but this is mostly directed towards pariasitic power from the RS232 - * line rather than changing very much about how to communicate with - * the TOIM3232. - * - * The protocol to talk to the TOIM4232 chipset seems to be almost - * identical to the TOIM3232 (and the 4232 datasheet is more detailed) - * so this code will probably work on that as well, although I haven't - * tested it on that hardware. - * - * Target dongle variations that might be common: - * - * DTR and RTS function: - * The data sheet for the 4232 has a sample implementation that hooks the - * DTR and RTS lines to the RESET and BaudRate/~Data lines of the - * chip (through line-converters). Given both DTR and RTS would have to - * be held low in normal operation, and the TOIMx232 requires +5V to - * signal ground, most dongle designers would almost certainly choose - * an implementation that kept at least one of DTR or RTS high in - * normal operation to provide power to the dongle, but will likely - * vary between designs. - * - * User specified command bits: - * There are two user-controllable output lines from the TOIMx232 that - * can be set low or high by setting the appropriate bits in the - * high-nibble of the command byte (when setting speed and pulse length). - * These might be used to switch on and off added hardware or extra - * dongle features. - * - * - * Target hardware: IRWave IR320ST-2 - * - * The IRWave IR320ST-2 is a simple dongle based on the Vishay/Temic - * TOIM3232 SIR Endec and the Vishay/Temic TFDS4500 SIR IRDA transciever. - * It uses a hex inverter and some discrete components to buffer and - * line convert the RS232 down to 5V. - * - * The dongle is powered through a voltage regulator, fed by a large - * capacitor. To switch the dongle on, DTR is brought high to charge - * the capacitor and drive the voltage regulator. DTR isn't associated - * with any control lines on the TOIM3232. Parisitic power is also taken - * from the RTS, TD and RD lines when brought high, but through resistors. - * When DTR is low, the circuit might lose power even with RTS high. - * - * RTS is inverted and attached to the BR/~D input pin. When RTS - * is high, BR/~D is low, and the TOIM3232 is in the normal 'data' mode. - * RTS is brought low, BR/~D is high, and the TOIM3232 is in 'command - * mode'. - * - * For some unknown reason, the RESET line isn't actually connected - * to anything. This means to reset the dongle to get it to a known - * state (9600 baud) you must drop DTR and RTS low, wait for the power - * capacitor to discharge, and then bring DTR (and RTS for data mode) - * high again, and wait for the capacitor to charge, the power supply - * to stabilise, and the oscillator clock to stabilise. - * - * Fortunately, if the current baudrate is known, the chipset can - * easily change speed by entering command mode without having to - * reset the dongle first. - * - * Major Components: - * - * - Vishay/Temic TOIM3232 SIR Endec to change RS232 pulse timings - * to IRDA pulse timings - * - 3.6864MHz crystal to drive TOIM3232 clock oscillator - * - DM74lS04M Inverting Hex line buffer for RS232 input buffering - * and level conversion - * - PJ2951AC 150mA voltage regulator - * - Vishay/Temic TFDS4500 SIR IRDA front-end transceiver - * - */ - -#include -#include -#include - -#include - -#include "sir-dev.h" - -static int toim3232delay = 150; /* default is 150 ms */ -module_param(toim3232delay, int, 0); -MODULE_PARM_DESC(toim3232delay, "toim3232 dongle write complete delay"); - -#if 0 -static int toim3232flipdtr = 0; /* default is DTR high to reset */ -module_param(toim3232flipdtr, int, 0); -MODULE_PARM_DESC(toim3232flipdtr, "toim3232 dongle invert DTR (Reset)"); - -static int toim3232fliprts = 0; /* default is RTS high for baud change */ -module_param(toim3232fliptrs, int, 0); -MODULE_PARM_DESC(toim3232fliprts, "toim3232 dongle invert RTS (BR/D)"); -#endif - -static int toim3232_open(struct sir_dev *); -static int toim3232_close(struct sir_dev *); -static int toim3232_change_speed(struct sir_dev *, unsigned); -static int toim3232_reset(struct sir_dev *); - -#define TOIM3232_115200 0x00 -#define TOIM3232_57600 0x01 -#define TOIM3232_38400 0x02 -#define TOIM3232_19200 0x03 -#define TOIM3232_9600 0x06 -#define TOIM3232_2400 0x0A - -#define TOIM3232_PW 0x10 /* Pulse select bit */ - -static struct dongle_driver toim3232 = { - .owner = THIS_MODULE, - .driver_name = "Vishay TOIM3232", - .type = IRDA_TOIM3232_DONGLE, - .open = toim3232_open, - .close = toim3232_close, - .reset = toim3232_reset, - .set_speed = toim3232_change_speed, -}; - -static int __init toim3232_sir_init(void) -{ - if (toim3232delay < 1 || toim3232delay > 500) - toim3232delay = 200; - IRDA_DEBUG(1, "%s - using %d ms delay\n", - toim3232.driver_name, toim3232delay); - return irda_register_dongle(&toim3232); -} - -static void __exit toim3232_sir_cleanup(void) -{ - irda_unregister_dongle(&toim3232); -} - -static int toim3232_open(struct sir_dev *dev) -{ - struct qos_info *qos = &dev->qos; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - /* Pull the lines high to start with. - * - * For the IR320ST-2, we need to charge the main supply capacitor to - * switch the device on. We keep DTR high throughout to do this. - * When RTS, TD and RD are high, they will also trickle-charge the - * cap. RTS is high for data transmission, and low for baud rate select. - * -- DGB - */ - sirdev_set_dtr_rts(dev, TRUE, TRUE); - - /* The TOI3232 supports many speeds between 1200bps and 115000bps. - * We really only care about those supported by the IRDA spec, but - * 38400 seems to be implemented in many places */ - qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - - /* From the tekram driver. Not sure what a reasonable value is -- DGB */ - qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */ - irda_qos_bits_to_value(qos); - - /* irda thread waits 50 msec for power settling */ - - return 0; -} - -static int toim3232_close(struct sir_dev *dev) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - /* Power off dongle */ - sirdev_set_dtr_rts(dev, FALSE, FALSE); - - return 0; -} - -/* - * Function toim3232change_speed (dev, state, speed) - * - * Set the speed for the TOIM3232 based dongle. Warning, this - * function must be called with a process context! - * - * Algorithm - * 1. keep DTR high but clear RTS to bring into baud programming mode - * 2. wait at least 7us to enter programming mode - * 3. send control word to set baud rate and timing - * 4. wait at least 1us - * 5. bring RTS high to enter DATA mode (RS232 is passed through to transceiver) - * 6. should take effect immediately (although probably worth waiting) - */ - -#define TOIM3232_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1) - -static int toim3232_change_speed(struct sir_dev *dev, unsigned speed) -{ - unsigned state = dev->fsm.substate; - unsigned delay = 0; - u8 byte; - static int ret = 0; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - switch(state) { - case SIRDEV_STATE_DONGLE_SPEED: - - /* Figure out what we are going to send as a control byte */ - switch (speed) { - case 2400: - byte = TOIM3232_PW|TOIM3232_2400; - break; - default: - speed = 9600; - ret = -EINVAL; - /* fall thru */ - case 9600: - byte = TOIM3232_PW|TOIM3232_9600; - break; - case 19200: - byte = TOIM3232_PW|TOIM3232_19200; - break; - case 38400: - byte = TOIM3232_PW|TOIM3232_38400; - break; - case 57600: - byte = TOIM3232_PW|TOIM3232_57600; - break; - case 115200: - byte = TOIM3232_115200; - break; - } - - /* Set DTR, Clear RTS: Go into baud programming mode */ - sirdev_set_dtr_rts(dev, TRUE, FALSE); - - /* Wait at least 7us */ - udelay(14); - - /* Write control byte */ - sirdev_raw_write(dev, &byte, 1); - - dev->speed = speed; - - state = TOIM3232_STATE_WAIT_SPEED; - delay = toim3232delay; - break; - - case TOIM3232_STATE_WAIT_SPEED: - /* Have transmitted control byte * Wait for 'at least 1us' */ - udelay(14); - - /* Set DTR, Set RTS: Go into normal data mode */ - sirdev_set_dtr_rts(dev, TRUE, TRUE); - - /* Wait (TODO: check this is needed) */ - udelay(50); - break; - - default: - printk(KERN_ERR "%s - undefined state %d\n", __FUNCTION__, state); - ret = -EINVAL; - break; - } - - dev->fsm.substate = state; - return (delay > 0) ? delay : ret; -} - -/* - * Function toim3232reset (driver) - * - * This function resets the toim3232 dongle. Warning, this function - * must be called with a process context!! - * - * What we should do is: - * 0. Pull RESET high - * 1. Wait for at least 7us - * 2. Pull RESET low - * 3. Wait for at least 7us - * 4. Pull BR/~D high - * 5. Wait for at least 7us - * 6. Send control byte to set baud rate - * 7. Wait at least 1us after stop bit - * 8. Pull BR/~D low - * 9. Should then be in data mode - * - * Because the IR320ST-2 doesn't have the RESET line connected for some reason, - * we'll have to do something else. - * - * The default speed after a RESET is 9600, so lets try just bringing it up in - * data mode after switching it off, waiting for the supply capacitor to - * discharge, and then switch it back on. This isn't actually pulling RESET - * high, but it seems to have the same effect. - * - * This behaviour will probably work on dongles that have the RESET line connected, - * but if not, add a flag for the IR320ST-2, and implment the above-listed proper - * behaviour. - * - * RTS is inverted and then fed to BR/~D, so to put it in programming mode, we - * need to have pull RTS low - */ - -static int toim3232_reset(struct sir_dev *dev) -{ - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - - /* Switch off both DTR and RTS to switch off dongle */ - sirdev_set_dtr_rts(dev, FALSE, FALSE); - - /* Should sleep a while. This might be evil doing it this way.*/ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(50)); - - /* Set DTR, Set RTS (data mode) */ - sirdev_set_dtr_rts(dev, TRUE, TRUE); - - /* Wait at least 10 ms for power to stabilize again */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(10)); - - /* Speed should now be 9600 */ - dev->speed = 9600; - - return 0; -} - -MODULE_AUTHOR("David Basden "); -MODULE_DESCRIPTION("Vishay/Temic TOIM3232 based dongle driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("irda-dongle-12"); /* IRDA_TOIM3232_DONGLE */ - -module_init(toim3232_sir_init); -module_exit(toim3232_sir_cleanup); diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index d70b9e8d6..a9f49f058 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -959,7 +959,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) || (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec)) break; udelay(100); - /* must not sleep here - called under netif_tx_lock! */ + /* must not sleep here - we are called under xmit_lock! */ } } @@ -1887,7 +1887,7 @@ static int __init vlsi_mod_init(void) vlsi_proc_root->owner = THIS_MODULE; } - ret = pci_register_driver(&vlsi_irda_driver); + ret = pci_module_init(&vlsi_irda_driver); if (ret && vlsi_proc_root) remove_proc_entry(PROC_DIR, NULL); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 83852450a..f9f77e4f5 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -357,20 +357,18 @@ ixgb_probe(struct pci_dev *pdev, if((err = pci_enable_device(pdev))) 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_64BIT_MASK))) { 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_32BIT_MASK))) { IXGB_ERR("No usable DMA configuration, aborting\n"); - goto err_dma_mask; + return err; } pci_using_dac = 0; } if((err = pci_request_regions(pdev, ixgb_driver_name))) - goto err_request_regions; + return err; pci_set_master(pdev); @@ -504,9 +502,6 @@ err_ioremap: free_netdev(netdev); err_alloc_etherdev: pci_release_regions(pdev); -err_request_regions: -err_dma_mask: - pci_disable_device(pdev); return err; } @@ -1168,7 +1163,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) uint16_t ipcse, tucse, mss; int err; - if (likely(skb_is_gso(skb))) { + if(likely(skb_shinfo(skb)->tso_size)) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -1176,7 +1171,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) } hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; skb->nh.iph->tot_len = 0; skb->nh.iph->check = 0; skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c index b67f586d7..d82651a97 100644 --- a/drivers/net/ixp2000/enp2611.c +++ b/drivers/net/ixp2000/enp2611.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include "ixpdev.h" @@ -149,8 +149,6 @@ static void enp2611_check_link_status(unsigned long __dummy) int status; dev = nds[i]; - if (dev == NULL) - continue; status = pm3386_is_link_up(i); if (status && !netif_carrier_ok(dev)) { @@ -193,7 +191,6 @@ static void enp2611_set_port_admin_status(int port, int up) static int __init enp2611_init_module(void) { - int ports; int i; if (!machine_is_enp2611()) @@ -202,8 +199,7 @@ static int __init enp2611_init_module(void) caleb_reset(); pm3386_reset(); - ports = pm3386_port_count(); - for (i = 0; i < ports; i++) { + for (i = 0; i < 3; i++) { nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv)); if (nds[i] == NULL) { while (--i >= 0) @@ -219,10 +215,9 @@ static int __init enp2611_init_module(void) ixp2400_msf_init(&enp2611_msf_parameters); - if (ixpdev_init(ports, nds, enp2611_set_port_admin_status)) { - for (i = 0; i < ports; i++) - if (nds[i]) - free_netdev(nds[i]); + if (ixpdev_init(3, nds, enp2611_set_port_admin_status)) { + for (i = 0; i < 3; i++) + free_netdev(nds[i]); return -EINVAL; } diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index fbc2d2102..09f03f493 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include "ixp2400_rx.ucode" @@ -299,7 +299,10 @@ int ixpdev_init(int __nds_count, struct net_device **__nds, int i; int err; - BUILD_BUG_ON(RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192); + if (RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192) { + static void __too_many_rx_or_tx_buffers(void); + __too_many_rx_or_tx_buffers(); + } printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION); diff --git a/drivers/net/ixp2000/pm3386.c b/drivers/net/ixp2000/pm3386.c index 5224651c9..5c7ab7564 100644 --- a/drivers/net/ixp2000/pm3386.c +++ b/drivers/net/ixp2000/pm3386.c @@ -86,53 +86,40 @@ static void pm3386_port_reg_write(int port, int _reg, int spacing, u16 value) pm3386_reg_write(port >> 1, reg, value); } -int pm3386_secondary_present(void) -{ - return pm3386_reg_read(1, 0) == 0x3386; -} void pm3386_reset(void) { u8 mac[3][6]; - int secondary; - - secondary = pm3386_secondary_present(); /* Save programmed MAC addresses. */ pm3386_get_mac(0, mac[0]); pm3386_get_mac(1, mac[1]); - if (secondary) - pm3386_get_mac(2, mac[2]); + pm3386_get_mac(2, mac[2]); /* Assert analog and digital reset. */ pm3386_reg_write(0, 0x002, 0x0060); - if (secondary) - pm3386_reg_write(1, 0x002, 0x0060); + pm3386_reg_write(1, 0x002, 0x0060); mdelay(1); /* Deassert analog reset. */ pm3386_reg_write(0, 0x002, 0x0062); - if (secondary) - pm3386_reg_write(1, 0x002, 0x0062); + pm3386_reg_write(1, 0x002, 0x0062); mdelay(10); /* Deassert digital reset. */ pm3386_reg_write(0, 0x002, 0x0063); - if (secondary) - pm3386_reg_write(1, 0x002, 0x0063); + pm3386_reg_write(1, 0x002, 0x0063); mdelay(10); /* Restore programmed MAC addresses. */ pm3386_set_mac(0, mac[0]); pm3386_set_mac(1, mac[1]); - if (secondary) - pm3386_set_mac(2, mac[2]); + pm3386_set_mac(2, mac[2]); /* Disable carrier on all ports. */ pm3386_set_carrier(0, 0); pm3386_set_carrier(1, 0); - if (secondary) - pm3386_set_carrier(2, 0); + pm3386_set_carrier(2, 0); } static u16 swaph(u16 x) @@ -140,11 +127,6 @@ static u16 swaph(u16 x) return ((x << 8) | (x >> 8)) & 0xffff; } -int pm3386_port_count(void) -{ - return 2 + pm3386_secondary_present(); -} - void pm3386_init_port(int port) { int pm = port >> 1; diff --git a/drivers/net/ixp2000/pm3386.h b/drivers/net/ixp2000/pm3386.h index cc4183dca..fe92bb056 100644 --- a/drivers/net/ixp2000/pm3386.h +++ b/drivers/net/ixp2000/pm3386.h @@ -13,7 +13,6 @@ #define __PM3386_H void pm3386_reset(void); -int pm3386_port_count(void); void pm3386_init_port(int port); void pm3386_get_mac(int port, u8 *mac); void pm3386_set_mac(int port, u8 *mac); diff --git a/drivers/net/lance.c b/drivers/net/lance.c index bb5ad4792..d1d714faa 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -464,25 +464,20 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int static int did_version; /* Already printed version info. */ unsigned long flags; int err = -ENOMEM; - void __iomem *bios; /* First we look for special cases. Check for HP's on-board ethernet by looking for 'HP' in the BIOS. There are two HP versions, check the BIOS for the configuration port. This method provided by L. Julliard, Laurent_Julliard@grenoble.hp.com. */ - bios = ioremap(0xf00f0, 0x14); - if (!bios) - return -ENOMEM; - if (readw(bios + 0x12) == 0x5048) { + if (isa_readw(0x000f0102) == 0x5048) { static const short ioaddr_table[] = { 0x300, 0x320, 0x340, 0x360}; - int hp_port = (readl(bios + 1) & 1) ? 0x499 : 0x99; + int hp_port = (isa_readl(0x000f00f1) & 1) ? 0x499 : 0x99; /* We can have boards other than the built-in! Verify this is on-board. */ if ((inb(hp_port) & 0xc0) == 0x80 && ioaddr_table[inb(hp_port) & 3] == ioaddr) hp_builtin = hp_port; } - iounmap(bios); /* We also recognize the HP Vectra on-board here, but check below. */ hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00 && inb(ioaddr+2) == 0x09); diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 957888de3..f7b7238d8 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -177,7 +177,7 @@ static int i596_debug = (DEB_SERIOUS|DEB_PROBE); MODULE_AUTHOR("Richard Hirst"); MODULE_DESCRIPTION("i82596 driver"); MODULE_LICENSE("GPL"); -module_param(i596_debug, int, 0); +MODULE_PARM(i596_debug, "i"); MODULE_PARM_DESC(i596_debug, "lasi_82596 debug mask"); /* Copy frames shorter than rx_copybreak, otherwise pass on up in @@ -1520,9 +1520,9 @@ static void set_multicast_list(struct net_device *dev) } } -static int debug = -1; -module_param(debug, int, 0); +MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "lasi_82596 debug mask"); +static int debug = -1; static int num_drivers; static struct net_device *netdevs[MAX_DRIVERS]; diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 997cbce9a..690a1aae0 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -74,7 +74,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) struct iphdr *iph = skb->nh.iph; struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4)); unsigned int doffset = (iph->ihl + th->doff) * 4; - unsigned int mtu = skb_shinfo(skb)->gso_size + doffset; + unsigned int mtu = skb_shinfo(skb)->tso_size + doffset; unsigned int offset = 0; u32 seq = ntohl(th->seq); u16 id = ntohs(iph->id); @@ -139,7 +139,7 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) #endif #ifdef LOOPBACK_TSO - if (skb_is_gso(skb)) { + if (skb_shinfo(skb)->tso_size) { BUG_ON(skb->protocol != htons(ETH_P_IP)); BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); @@ -172,9 +172,11 @@ static struct net_device_stats *get_stats(struct net_device *dev) memset(stats, 0, sizeof(struct net_device_stats)); - for_each_possible_cpu(i) { + for (i=0; i < NR_CPUS; i++) { struct net_device_stats *lb_stats; + if (!cpu_possible(i)) + continue; lb_stats = &per_cpu(loopback_stats, i); stats->rx_bytes += lb_stats->rx_bytes; stats->tx_bytes += lb_stats->tx_bytes; diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index cd3c9a5a9..f65b0db11 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c @@ -629,7 +629,7 @@ static int set_mac_address(struct net_device *dev, void *addr) static struct net_device *dev_cs89x0; static int debug; -module_param(debug, int, 0); +MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 77792b286..2a5add257 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -1042,7 +1042,7 @@ static void __exit mace_cleanup(void) MODULE_AUTHOR("Paul Mackerras"); MODULE_DESCRIPTION("PowerMac MACE driver."); -module_param(port_aaui, int, 0); +MODULE_PARM(port_aaui, "i"); MODULE_PARM_DESC(port_aaui, "MACE uses AAUI port (0-1)"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index f6f3dafe8..02d5c6822 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -622,7 +622,7 @@ static int __init mac_sonic_init_module(void) return 0; out_unregister: - platform_driver_unregister(&mac_sonic_driver); + driver_unregister(&mac_sonic_driver); return -ENOMEM; } diff --git a/drivers/net/mambonet.c b/drivers/net/mambonet.c deleted file mode 100644 index 1ef4b6a90..000000000 --- a/drivers/net/mambonet.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Bogus Network Driver for PowerPC Full System Simulator - * - * (C) Copyright IBM Corporation 2003-2005 - * - * Bogus Network Driver - * - * Author: JimiX - * Maintained By: Eric Van Hensbergen - * - * inspired by drivers/net/ibmveth.c - * written by Dave Larson - * - * Some code is from the IBM Full System Simulator Group in ARL - * Author: Patrick Bohrer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to: - * Free Software Foundation - * 51 Franklin Street, Fifth Floor - * Boston, MA 02111-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include /* For the statistics structure. */ -#include /* For ARPHRD_ETHER */ -#include -#include -#include -#include - -#define MAMBO_BOGUS_NET_PROBE 119 -#define MAMBO_BOGUS_NET_SEND 120 -#define MAMBO_BOGUS_NET_RECV 121 - -static inline int MamboBogusNetProbe(int devno, void *buf) -{ - return callthru2(MAMBO_BOGUS_NET_PROBE, - (unsigned long)devno, (unsigned long)buf); -} - -static inline int MamboBogusNetSend(int devno, void *buf, ulong size) -{ - return callthru3(MAMBO_BOGUS_NET_SEND, - (unsigned long)devno, - (unsigned long)buf, (unsigned long)size); -} - -static inline int MamboBogusNetRecv(int devno, void *buf, ulong size) -{ - return callthru3(MAMBO_BOGUS_NET_RECV, - (unsigned long)devno, - (unsigned long)buf, (unsigned long)size); -} - -static irqreturn_t -mambonet_interrupt(int irq, void *dev_instance, struct pt_regs *regs); - -#define INIT_BOTTOM_HALF(x,y,z) INIT_WORK(x, y, (void*)z) -#define SCHEDULE_BOTTOM_HALF(x) schedule_delayed_work(x, 1) -#define KILL_BOTTOM_HALF(x) cancel_delayed_work(x); flush_scheduled_work() - -#define MAMBO_MTU 1500 - -struct netdev_private { - int devno; - int closing; - struct work_struct poll_task; - struct net_device_stats stats; -}; - -static int mambonet_probedev(int devno, void *buf) -{ - struct device_node *mambo; - struct device_node *net; - unsigned int *reg; - - mambo = find_path_device("/mambo"); - - if (mambo == NULL) { - return -1; - } - net = find_path_device("/mambo/bogus-net@0"); - if (net == NULL) { - return -1; - } - reg = (unsigned int *)get_property(net, "reg", 0); - - if (*reg != devno) { - return -1; - } - - return MamboBogusNetProbe(devno, buf); -} - -static int mambonet_send(int devno, void *buf, ulong size) -{ - return MamboBogusNetSend(devno, buf, size); -} - -static int mambonet_recv(int devno, void *buf, ulong size) -{ - return MamboBogusNetRecv(devno, buf, size); -} - -static int mambonet_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct netdev_private *priv = (struct netdev_private *)dev->priv; - int devno = priv->devno; - - skb->dev = dev; - - /* we might need to checksum or something */ - mambonet_send(devno, skb->data, skb->len); - - dev->last_rx = jiffies; - priv->stats.rx_bytes += skb->len; - priv->stats.tx_bytes += skb->len; - priv->stats.rx_packets++; - priv->stats.tx_packets++; - - dev_kfree_skb(skb); - - return (0); -} - -static int mambonet_poll(struct net_device *dev, int *budget) -{ - struct netdev_private *np = dev->priv; - int devno = np->devno; - char buffer[1600]; - int ns; - struct sk_buff *skb; - int frames = 0; - int max_frames = min(*budget, dev->quota); - int ret = 0; - - while ((ns = mambonet_recv(devno, buffer, 1600)) > 0) { - if ((skb = dev_alloc_skb(ns + 2)) != NULL) { - skb->dev = dev; - skb_reserve(skb, 2); /* 16 byte align the IP - * header */ -#ifdef HAS_IP_COPYSUM - eth_copy_and_sum(skb, buffer, ns, 0); - skb_put(skb, ns); -#else - memcpy(skb_put(skb, ns), buffer, ns); -#endif - skb->protocol = eth_type_trans(skb, dev); - - if (dev->irq) - netif_receive_skb(skb); - else - netif_rx(skb); - - dev->last_rx = jiffies; - np->stats.rx_packets++; - np->stats.rx_bytes += ns; - } else { - printk("Failed to allocated skbuff, " - "dropping packet\n"); - np->stats.rx_dropped++; - /* wait for another cycle */ - return 1; - } - ++frames; - if (frames > max_frames) { - ret = 1; - break; - } - } - *budget -= frames; - dev->quota -= frames; - - if ((!ret) && (dev->irq)) - netif_rx_complete(dev); - - return ret; -} - -static void mambonet_timer(struct net_device *dev) -{ - int budget = 16; - struct netdev_private *priv = (struct netdev_private *)dev->priv; - - mambonet_poll(dev, &budget); - - if (!priv->closing) { - SCHEDULE_BOTTOM_HALF(&priv->poll_task); - } -} - -static struct net_device_stats *get_stats(struct net_device *dev) -{ - struct netdev_private *priv = (struct netdev_private *)dev->priv; - return (struct net_device_stats *)&(priv->stats); -} - -static irqreturn_t -mambonet_interrupt(int irq, void *dev_instance, struct pt_regs *regs) -{ - struct net_device *dev = dev_instance; - if (netif_rx_schedule_prep(dev)) { - __netif_rx_schedule(dev); - } - return IRQ_HANDLED; -} - -static int mambonet_open(struct net_device *dev) -{ - struct netdev_private *priv; - int ret = 0; - - priv = dev->priv; - - /* - * we can't start polling in mambonet_init, because I don't think - * workqueues are usable that early. so start polling now. - */ - - if (dev->irq) { - ret = request_irq(dev->irq, &mambonet_interrupt, 0, - dev->name, dev); - - if (ret == 0) { - netif_start_queue(dev); - } else { - printk(KERN_ERR "mambonet: request irq failed\n"); - } - - MamboBogusNetProbe(priv->devno, NULL); /* probe with NULL to activate interrupts */ - } else { - mambonet_timer(dev); - } - - return ret; -} - -static int mambonet_close(struct net_device *dev) -{ - struct netdev_private *priv; - - netif_stop_queue(dev); - - if (dev->irq) - free_irq(dev->irq, dev); - - priv = dev->priv; - priv->closing = 1; - if (dev->irq == 0) { - KILL_BOTTOM_HALF(&priv->poll_task); - } - - kfree(priv); - - return 0; -} - -static struct net_device_stats mambonet_stats; - -static struct net_device_stats *mambonet_get_stats(struct net_device *dev) -{ - return &mambonet_stats; -} - -static int mambonet_set_mac_address(struct net_device *dev, void *p) -{ - return -EOPNOTSUPP; -} -static int mambonet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - return -EOPNOTSUPP; -} -static int nextdevno = 0; /* running count of device numbers */ - -/* Initialize the rest of the device. */ -int __init do_mambonet_probe(struct net_device *dev) -{ - struct netdev_private *priv; - int devno = nextdevno++; - int irq; - - printk("eth%d: bogus network driver initialization\n", devno); - - irq = mambonet_probedev(devno, dev->dev_addr); - - if (irq < 0) { - printk("No IRQ retreived\n"); - return (-ENODEV); - } - - printk("%s: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", dev->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - - SET_MODULE_OWNER(dev); - - dev->irq = irq; - dev->mtu = MAMBO_MTU; - dev->open = mambonet_open; - dev->poll = mambonet_poll; - dev->weight = 16; - dev->stop = mambonet_close; - dev->hard_start_xmit = mambonet_start_xmit; - dev->get_stats = mambonet_get_stats; - dev->set_mac_address = mambonet_set_mac_address; - dev->do_ioctl = mambonet_ioctl; - - dev->priv = kmalloc(sizeof(struct netdev_private), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - memset(dev->priv, 0, sizeof(struct netdev_private)); - - priv = dev->priv; - priv->devno = devno; - priv->closing = 0; - dev->get_stats = get_stats; - - if (dev->irq == 0) { - INIT_BOTTOM_HALF(&priv->poll_task, (void *)mambonet_timer, - (void *)dev); - } - - return (0); -}; - -struct net_device *__init mambonet_probe(int unit) -{ - struct net_device *dev = alloc_etherdev(0); - int err; - - if (!dev) - return ERR_PTR(-ENODEV); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - - err = do_mambonet_probe(dev); - - if (err) - goto out; - - err = register_netdev(dev); - if (err) - goto out; - - return dev; - - out: - free_netdev(dev); - return ERR_PTR(err); -} - -int __init init_mambonet(void) -{ - mambonet_probe(0); - return 0; -} - -module_init(init_mambonet); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/meth.c b/drivers/net/meth.c index d644bf3a9..e23655f50 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -62,7 +62,7 @@ MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver"); #ifdef HAVE_TX_TIMEOUT static int timeout = TX_TIMEOUT; -module_param(timeout, int, 0); +MODULE_PARM(timeout, "i"); #endif /* diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 625ff61c9..c0998ef93 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -10,7 +10,7 @@ * * Copyright (C) 2003 Ralf Baechle * - * Copyright (C) 2004-2006 MontaVista Software, Inc. + * Copyright (C) 2004-2005 MontaVista Software, Inc. * Dale Farnsworth * * Copyright (C) 2004 Steven J. Hill @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include #include @@ -50,16 +52,39 @@ #include #include "mv643xx_eth.h" +/* + * The first part is the high level driver of the gigE ethernet ports. + */ + +/* Constants */ +#define VLAN_HLEN 4 +#define FCS_LEN 4 +#define DMA_ALIGN 8 /* hw requires 8-byte alignment */ +#define HW_IP_ALIGN 2 /* hw aligns IP header */ +#define WRAP HW_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN +#define RX_SKB_SIZE ((dev->mtu + WRAP + 7) & ~0x7) + +#define INT_UNMASK_ALL 0x0007ffff +#define INT_UNMASK_ALL_EXT 0x0011ffff +#define INT_MASK_ALL 0x00000000 +#define INT_MASK_ALL_EXT 0x00000000 +#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL +#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT + +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX +#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1) +#else +#define MAX_DESCS_PER_SKB 1 +#endif + +#define PHY_WAIT_ITERATIONS 1000 /* 1000 iterations * 10uS = 10mS max */ +#define PHY_WAIT_MICRO_SECONDS 10 + /* Static function declarations */ +static int eth_port_link_is_up(unsigned int eth_port_num); static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *MacAddr); static void eth_port_set_multicast_list(struct net_device *); -static void mv643xx_eth_port_enable_tx(unsigned int port_num, - unsigned int queues); -static void mv643xx_eth_port_enable_rx(unsigned int port_num, - unsigned int queues); -static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num); -static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num); static int mv643xx_eth_open(struct net_device *); static int mv643xx_eth_stop(struct net_device *); static int mv643xx_eth_change_mtu(struct net_device *, int); @@ -68,12 +93,8 @@ static void eth_port_init_mac_tables(unsigned int eth_port_num); #ifdef MV643XX_NAPI static int mv643xx_poll(struct net_device *dev, int *budget); #endif -static int ethernet_phy_get(unsigned int eth_port_num); static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); static int ethernet_phy_detect(unsigned int eth_port_num); -static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location); -static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val); -static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static struct ethtool_ops mv643xx_ethtool_ops; static char mv643xx_driver_name[] = "mv643xx_eth"; @@ -132,53 +153,67 @@ static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) } /* - * mv643xx_eth_rx_refill_descs + * mv643xx_eth_rx_task * * Fills / refills RX queue on a certain gigabit ethernet port * * Input : pointer to ethernet interface network device structure * Output : N/A */ -static void mv643xx_eth_rx_refill_descs(struct net_device *dev) +static void mv643xx_eth_rx_task(void *data) { + struct net_device *dev = (struct net_device *)data; struct mv643xx_private *mp = netdev_priv(dev); struct pkt_info pkt_info; struct sk_buff *skb; int unaligned; - while (mp->rx_desc_count < mp->rx_ring_size) { - skb = dev_alloc_skb(ETH_RX_SKB_SIZE + ETH_DMA_ALIGN); + if (test_and_set_bit(0, &mp->rx_task_busy)) + panic("%s: Error in test_set_bit / clear_bit", dev->name); + + while (mp->rx_ring_skbs < (mp->rx_ring_size - 5)) { + skb = dev_alloc_skb(RX_SKB_SIZE + DMA_ALIGN); if (!skb) break; - mp->rx_desc_count++; - unaligned = (u32)skb->data & (ETH_DMA_ALIGN - 1); + mp->rx_ring_skbs++; + unaligned = (u32)skb->data & (DMA_ALIGN - 1); if (unaligned) - skb_reserve(skb, ETH_DMA_ALIGN - unaligned); + skb_reserve(skb, DMA_ALIGN - unaligned); pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT; - pkt_info.byte_cnt = ETH_RX_SKB_SIZE; - pkt_info.buf_ptr = dma_map_single(NULL, skb->data, - ETH_RX_SKB_SIZE, DMA_FROM_DEVICE); + pkt_info.byte_cnt = RX_SKB_SIZE; + pkt_info.buf_ptr = dma_map_single(NULL, skb->data, RX_SKB_SIZE, + DMA_FROM_DEVICE); pkt_info.return_info = skb; if (eth_rx_return_buff(mp, &pkt_info) != ETH_OK) { printk(KERN_ERR "%s: Error allocating RX Ring\n", dev->name); break; } - skb_reserve(skb, ETH_HW_IP_ALIGN); + skb_reserve(skb, HW_IP_ALIGN); } + clear_bit(0, &mp->rx_task_busy); /* * If RX ring is empty of SKB, set a timer to try allocating - * again at a later time. + * again in a later time . */ - if (mp->rx_desc_count == 0) { + if ((mp->rx_ring_skbs == 0) && (mp->rx_timer_flag == 0)) { printk(KERN_INFO "%s: Rx ring is empty\n", dev->name); - mp->timeout.expires = jiffies + (HZ / 10); /* 100 mSec */ + /* After 100mSec */ + mp->timeout.expires = jiffies + (HZ / 10); add_timer(&mp->timeout); + mp->rx_timer_flag = 1; + } +#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK + else { + /* Return interrupts */ + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(mp->port_num), + INT_UNMASK_ALL); } +#endif } /* - * mv643xx_eth_rx_refill_descs_timer_wrapper + * mv643xx_eth_rx_task_timer_wrapper * * Timer routine to wake up RX queue filling task. This function is * used only in case the RX queue is empty, and all alloc_skb has @@ -187,9 +222,13 @@ static void mv643xx_eth_rx_refill_descs(struct net_device *dev) * Input : pointer to ethernet interface network device structure * Output : N/A */ -static inline void mv643xx_eth_rx_refill_descs_timer_wrapper(unsigned long data) +static void mv643xx_eth_rx_task_timer_wrapper(unsigned long data) { - mv643xx_eth_rx_refill_descs((struct net_device *)data); + struct net_device *dev = (struct net_device *)data; + struct mv643xx_private *mp = netdev_priv(dev); + + mp->rx_timer_flag = 0; + mv643xx_eth_rx_task((void *)data); } /* @@ -206,7 +245,8 @@ static void mv643xx_eth_update_mac_address(struct net_device *dev) unsigned int port_num = mp->port_num; eth_port_init_mac_tables(port_num); - eth_port_uc_addr_set(port_num, dev->dev_addr); + memcpy(mp->port_mac_addr, dev->dev_addr, 6); + eth_port_uc_addr_set(port_num, mp->port_mac_addr); } /* @@ -220,14 +260,13 @@ static void mv643xx_eth_update_mac_address(struct net_device *dev) static void mv643xx_eth_set_rx_mode(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); - u32 config_reg; - config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num)); if (dev->flags & IFF_PROMISC) - config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; + mp->port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; else - config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; - mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), config_reg); + mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; + + mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config); eth_port_set_multicast_list(dev); } @@ -281,90 +320,55 @@ static void mv643xx_eth_tx_timeout_task(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); - if (!netif_running(dev)) - return; - - netif_stop_queue(dev); - + netif_device_detach(dev); eth_port_reset(mp->port_num); - eth_port_start(dev); - - if (mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB) - netif_wake_queue(dev); + eth_port_start(mp); + netif_device_attach(dev); } -/** - * mv643xx_eth_free_tx_descs - Free the tx desc data for completed descriptors +/* + * mv643xx_eth_free_tx_queue + * + * Input : dev - a pointer to the required interface * - * If force is non-zero, frees uncompleted descriptors as well + * Output : 0 if was able to release skb , nonzero otherwise */ -int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) +static int mv643xx_eth_free_tx_queue(struct net_device *dev, + unsigned int eth_int_cause_ext) { struct mv643xx_private *mp = netdev_priv(dev); - struct eth_tx_desc *desc; - u32 cmd_sts; - struct sk_buff *skb; - unsigned long flags; - int tx_index; - dma_addr_t addr; - int count; - int released = 0; - - while (mp->tx_desc_count > 0) { - spin_lock_irqsave(&mp->lock, flags); - tx_index = mp->tx_used_desc_q; - desc = &mp->p_tx_desc_area[tx_index]; - cmd_sts = desc->cmd_sts; - - if (!force && (cmd_sts & ETH_BUFFER_OWNED_BY_DMA)) { - spin_unlock_irqrestore(&mp->lock, flags); - return released; - } - - mp->tx_used_desc_q = (tx_index + 1) % mp->tx_ring_size; - mp->tx_desc_count--; - - addr = desc->buf_ptr; - count = desc->byte_cnt; - skb = mp->tx_skb[tx_index]; - if (skb) - mp->tx_skb[tx_index] = NULL; + struct net_device_stats *stats = &mp->stats; + struct pkt_info pkt_info; + int released = 1; - spin_unlock_irqrestore(&mp->lock, flags); + if (!(eth_int_cause_ext & (BIT0 | BIT8))) + return released; - if (cmd_sts & ETH_ERROR_SUMMARY) { + /* Check only queue 0 */ + while (eth_tx_return_desc(mp, &pkt_info) == ETH_OK) { + if (pkt_info.cmd_sts & BIT0) { printk("%s: Error in TX\n", dev->name); - mp->stats.tx_errors++; + stats->tx_errors++; } - if (cmd_sts & ETH_TX_FIRST_DESC) - dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); + if (pkt_info.cmd_sts & ETH_TX_FIRST_DESC) + dma_unmap_single(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, + DMA_TO_DEVICE); else - dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE); - - if (skb) - dev_kfree_skb_irq(skb); + dma_unmap_page(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, + DMA_TO_DEVICE); - released = 1; + if (pkt_info.return_info) { + dev_kfree_skb_irq(pkt_info.return_info); + released = 0; + } } return released; } -static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - if (mv643xx_eth_free_tx_descs(dev, 0) && - mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB) - netif_wake_queue(dev); -} - -static void mv643xx_eth_free_all_tx_descs(struct net_device *dev) -{ - mv643xx_eth_free_tx_descs(dev, 1); -} - /* * mv643xx_eth_receive * @@ -376,7 +380,11 @@ static void mv643xx_eth_free_all_tx_descs(struct net_device *dev) * * Output : number of served packets */ +#ifdef MV643XX_NAPI static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) +#else +static int mv643xx_eth_receive_queue(struct net_device *dev) +#endif { struct mv643xx_private *mp = netdev_priv(dev); struct net_device_stats *stats = &mp->stats; @@ -384,14 +392,15 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) struct sk_buff *skb; struct pkt_info pkt_info; +#ifdef MV643XX_NAPI while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) { - mp->rx_desc_count--; +#else + while (eth_port_receive(mp, &pkt_info) == ETH_OK) { +#endif + mp->rx_ring_skbs--; received_packets++; - /* - * Update statistics. - * Note byte count includes 4 byte CRC count - */ + /* Update statistics. Note byte count includes 4 byte CRC count */ stats->rx_packets++; stats->rx_bytes += pkt_info.byte_cnt; skb = pkt_info.return_info; @@ -439,61 +448,10 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) } dev->last_rx = jiffies; } - mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ return received_packets; } -/* Set the mv643xx port configuration register for the speed/duplex mode. */ -static void mv643xx_eth_update_pscr(struct net_device *dev, - struct ethtool_cmd *ecmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - int port_num = mp->port_num; - u32 o_pscr, n_pscr; - unsigned int queues; - - o_pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); - n_pscr = o_pscr; - - /* clear speed, duplex and rx buffer size fields */ - n_pscr &= ~(MV643XX_ETH_SET_MII_SPEED_TO_100 | - MV643XX_ETH_SET_GMII_SPEED_TO_1000 | - MV643XX_ETH_SET_FULL_DUPLEX_MODE | - MV643XX_ETH_MAX_RX_PACKET_MASK); - - if (ecmd->duplex == DUPLEX_FULL) - n_pscr |= MV643XX_ETH_SET_FULL_DUPLEX_MODE; - - if (ecmd->speed == SPEED_1000) - n_pscr |= MV643XX_ETH_SET_GMII_SPEED_TO_1000 | - MV643XX_ETH_MAX_RX_PACKET_9700BYTE; - else { - if (ecmd->speed == SPEED_100) - n_pscr |= MV643XX_ETH_SET_MII_SPEED_TO_100; - n_pscr |= MV643XX_ETH_MAX_RX_PACKET_1522BYTE; - } - - if (n_pscr != o_pscr) { - if ((o_pscr & MV643XX_ETH_SERIAL_PORT_ENABLE) == 0) - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - n_pscr); - else { - queues = mv643xx_eth_port_disable_tx(port_num); - - o_pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE; - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - o_pscr); - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - n_pscr); - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - n_pscr); - if (queues) - mv643xx_eth_port_enable_tx(port_num, queues); - } - } -} - /* * mv643xx_eth_int_handler * @@ -515,52 +473,78 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, /* Read interrupt cause registers */ eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) & - ETH_INT_UNMASK_ALL; - if (eth_int_cause & ETH_INT_CAUSE_EXT) { + INT_UNMASK_ALL; + + if (eth_int_cause & BIT1) eth_int_cause_ext = mv_read( MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) & - ETH_INT_UNMASK_ALL_EXT; - mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), - ~eth_int_cause_ext); - } + INT_UNMASK_ALL_EXT; - /* PHY status changed */ - if (eth_int_cause_ext & ETH_INT_CAUSE_PHY) { - struct ethtool_cmd cmd; - - if (mii_link_ok(&mp->mii)) { - mii_ethtool_gset(&mp->mii, &cmd); - mv643xx_eth_update_pscr(dev, &cmd); - mv643xx_eth_port_enable_tx(port_num, - ETH_TX_QUEUES_ENABLED); - if (!netif_carrier_ok(dev)) { - netif_carrier_on(dev); - if (mp->tx_ring_size - mp->tx_desc_count >= - MAX_DESCS_PER_SKB) - netif_wake_queue(dev); - } - } else if (netif_carrier_ok(dev)) { - netif_stop_queue(dev); - netif_carrier_off(dev); +#ifdef MV643XX_NAPI + if (!(eth_int_cause & 0x0007fffd)) { + /* Dont ack the Rx interrupt */ +#endif + /* + * Clear specific ethernet port intrerrupt registers by + * acknowleding relevant bits. + */ + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), + ~eth_int_cause); + if (eth_int_cause_ext != 0x0) + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG + (port_num), ~eth_int_cause_ext); + + /* UDP change : We may need this */ + if ((eth_int_cause_ext & 0x0000ffff) && + (mv643xx_eth_free_tx_queue(dev, eth_int_cause_ext) == 0) && + (mp->tx_ring_size > mp->tx_ring_skbs + MAX_DESCS_PER_SKB)) + netif_wake_queue(dev); +#ifdef MV643XX_NAPI + } else { + if (netif_rx_schedule_prep(dev)) { + /* Mask all the interrupts */ + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), + INT_MASK_ALL); + /* wait for previous write to complete */ + mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); + __netif_rx_schedule(dev); } - } +#else + if (eth_int_cause & (BIT2 | BIT11)) + mv643xx_eth_receive_queue(dev, 0); -#ifdef MV643XX_NAPI - if (eth_int_cause & ETH_INT_CAUSE_RX) { - /* schedule the NAPI poll routine to maintain port */ + /* + * After forwarded received packets to upper layer, add a task + * in an interrupts enabled context that refills the RX ring + * with skb's. + */ +#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK + /* Mask all interrupts on ethernet port */ mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), - ETH_INT_MASK_ALL); - /* wait for previous write to complete */ + INT_MASK_ALL); + /* wait for previous write to take effect */ mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); - netif_rx_schedule(dev); - } + queue_task(&mp->rx_task, &tq_immediate); + mark_bh(IMMEDIATE_BH); #else - if (eth_int_cause & ETH_INT_CAUSE_RX) - mv643xx_eth_receive_queue(dev, INT_MAX); + mp->rx_task.func(dev); #endif - if (eth_int_cause_ext & ETH_INT_CAUSE_TX) - mv643xx_eth_free_completed_tx_descs(dev); +#endif + } + /* PHY status changed */ + if (eth_int_cause_ext & (BIT16 | BIT20)) { + if (eth_port_link_is_up(port_num)) { + netif_carrier_on(dev); + netif_wake_queue(dev); + /* Start TX queue */ + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG + (port_num), 1); + } else { + netif_carrier_off(dev); + netif_stop_queue(dev); + } + } /* * If no real interrupt occured, exit. @@ -686,6 +670,9 @@ static void ether_init_rx_desc_ring(struct mv643xx_private *mp) mp->rx_used_desc_q = 0; mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc); + + /* Add the queue to the list of RX queues of this port */ + mp->port_rx_queue_command |= 1; } /* @@ -725,36 +712,14 @@ static void ether_init_tx_desc_ring(struct mv643xx_private *mp) mp->tx_curr_desc_q = 0; mp->tx_used_desc_q = 0; +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX + mp->tx_first_desc_q = 0; +#endif mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc); -} - -static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - int err; - - spin_lock_irq(&mp->lock); - err = mii_ethtool_sset(&mp->mii, cmd); - spin_unlock_irq(&mp->lock); - - return err; -} - -static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - int err; - - spin_lock_irq(&mp->lock); - err = mii_ethtool_gset(&mp->mii, cmd); - spin_unlock_irq(&mp->lock); - - /* The PHY may support 1000baseT_Half, but the mv643xx does not */ - cmd->supported &= ~SUPPORTED_1000baseT_Half; - cmd->advertising &= ~ADVERTISED_1000baseT_Half; - return err; + /* Add the queue to the list of Tx queues of this port */ + mp->port_tx_queue_command |= 1; } /* @@ -785,12 +750,23 @@ static int mv643xx_eth_open(struct net_device *dev) return -EAGAIN; } + /* Stop RX Queues */ + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); + + /* Set the MAC Address */ + memcpy(mp->port_mac_addr, dev->dev_addr, 6); + eth_port_init(mp); + INIT_WORK(&mp->rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev); + memset(&mp->timeout, 0, sizeof(struct timer_list)); - mp->timeout.function = mv643xx_eth_rx_refill_descs_timer_wrapper; + mp->timeout.function = mv643xx_eth_rx_task_timer_wrapper; mp->timeout.data = (unsigned long)dev; + mp->rx_task_busy = 0; + mp->rx_timer_flag = 0; + /* Allocate RX and TX skb rings */ mp->rx_skb = kmalloc(sizeof(*mp->rx_skb) * mp->rx_ring_size, GFP_KERNEL); @@ -808,7 +784,7 @@ static int mv643xx_eth_open(struct net_device *dev) } /* Allocate TX ring */ - mp->tx_desc_count = 0; + mp->tx_ring_skbs = 0; size = mp->tx_ring_size * sizeof(struct eth_tx_desc); mp->tx_desc_area_size = size; @@ -833,7 +809,7 @@ static int mv643xx_eth_open(struct net_device *dev) ether_init_tx_desc_ring(mp); /* Allocate RX ring */ - mp->rx_desc_count = 0; + mp->rx_ring_skbs = 0; size = mp->rx_ring_size * sizeof(struct eth_rx_desc); mp->rx_desc_area_size = size; @@ -863,13 +839,9 @@ static int mv643xx_eth_open(struct net_device *dev) ether_init_rx_desc_ring(mp); - mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ - - /* Clear any pending ethernet port interrupts */ - mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); - mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); + mv643xx_eth_rx_task(dev); /* Fill RX ring with skb's */ - eth_port_start(dev); + eth_port_start(mp); /* Interrupt Coalescing */ @@ -881,13 +853,16 @@ static int mv643xx_eth_open(struct net_device *dev) mp->tx_int_coal = eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL); + /* Clear any pending ethernet port interrupts */ + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); + /* Unmask phy and link status changes interrupts */ mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), - ETH_INT_UNMASK_ALL_EXT); + INT_UNMASK_ALL_EXT); /* Unmask RX buffer and TX end interrupt */ - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); - + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL); return 0; out_free_tx_skb: @@ -903,14 +878,25 @@ out_free_irq: static void mv643xx_eth_free_tx_rings(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); + unsigned int port_num = mp->port_num; + unsigned int curr; + struct sk_buff *skb; /* Stop Tx Queues */ - mv643xx_eth_port_disable_tx(mp->port_num); - - /* Free outstanding skb's on TX ring */ - mv643xx_eth_free_all_tx_descs(dev); - - BUG_ON(mp->tx_used_desc_q != mp->tx_curr_desc_q); + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0x0000ff00); + + /* Free outstanding skb's on TX rings */ + for (curr = 0; mp->tx_ring_skbs && curr < mp->tx_ring_size; curr++) { + skb = mp->tx_skb[curr]; + if (skb) { + mp->tx_ring_skbs -= skb_shinfo(skb)->nr_frags; + dev_kfree_skb(skb); + mp->tx_ring_skbs--; + } + } + if (mp->tx_ring_skbs) + printk("%s: Error on Tx descriptor free - could not free %d" + " descriptors\n", dev->name, mp->tx_ring_skbs); /* Free TX ring */ if (mp->tx_sram_size) @@ -927,21 +913,21 @@ static void mv643xx_eth_free_rx_rings(struct net_device *dev) int curr; /* Stop RX Queues */ - mv643xx_eth_port_disable_rx(port_num); + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); /* Free preallocated skb's on RX rings */ - for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) { + for (curr = 0; mp->rx_ring_skbs && curr < mp->rx_ring_size; curr++) { if (mp->rx_skb[curr]) { dev_kfree_skb(mp->rx_skb[curr]); - mp->rx_desc_count--; + mp->rx_ring_skbs--; } } - if (mp->rx_desc_count) + if (mp->rx_ring_skbs) printk(KERN_ERR "%s: Error in freeing Rx Ring. %d skb's still" " stuck in RX Ring - ignoring them\n", dev->name, - mp->rx_desc_count); + mp->rx_ring_skbs); /* Free RX ring */ if (mp->rx_sram_size) iounmap(mp->p_rx_desc_area); @@ -966,7 +952,7 @@ static int mv643xx_eth_stop(struct net_device *dev) unsigned int port_num = mp->port_num; /* Mask all interrupts on ethernet port */ - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL); + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL); /* wait for previous write to complete */ mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); @@ -991,6 +977,30 @@ static int mv643xx_eth_stop(struct net_device *dev) } #ifdef MV643XX_NAPI +static void mv643xx_tx(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); + struct pkt_info pkt_info; + + while (eth_tx_return_desc(mp, &pkt_info) == ETH_OK) { + if (pkt_info.cmd_sts & ETH_TX_FIRST_DESC) + dma_unmap_single(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, + DMA_TO_DEVICE); + else + dma_unmap_page(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, + DMA_TO_DEVICE); + + if (pkt_info.return_info) + dev_kfree_skb_irq(pkt_info.return_info); + } + + if (netif_queue_stopped(dev) && + mp->tx_ring_size > mp->tx_ring_skbs + MAX_DESCS_PER_SKB) + netif_wake_queue(dev); +} + /* * mv643xx_poll * @@ -1004,7 +1014,7 @@ static int mv643xx_poll(struct net_device *dev, int *budget) #ifdef MV643XX_TX_FAST_REFILL if (++mp->tx_clean_threshold > 5) { - mv643xx_eth_free_completed_tx_descs(dev); + mv643xx_tx(dev); mp->tx_clean_threshold = 0; } #endif @@ -1015,6 +1025,7 @@ static int mv643xx_poll(struct net_device *dev, int *budget) if (orig_budget > dev->quota) orig_budget = dev->quota; work_done = mv643xx_eth_receive_queue(dev, orig_budget); + mp->rx_task.func(dev); *budget -= work_done; dev->quota -= work_done; if (work_done >= orig_budget) @@ -1026,17 +1037,14 @@ static int mv643xx_poll(struct net_device *dev, int *budget) mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), - ETH_INT_UNMASK_ALL); + INT_UNMASK_ALL); } return done ? 0 : 1; } #endif -/** - * has_tiny_unaligned_frags - check if skb has any small, unaligned fragments - * - * Hardware can't handle unaligned fragments smaller than 9 bytes. +/* Hardware can't handle unaligned fragments smaller than 9 bytes. * This helper function detects that case. */ @@ -1053,154 +1061,53 @@ static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) return 0; } -/** - * eth_alloc_tx_desc_index - return the index of the next available tx desc - */ -static int eth_alloc_tx_desc_index(struct mv643xx_private *mp) -{ - int tx_desc_curr; - - BUG_ON(mp->tx_desc_count >= mp->tx_ring_size); - - tx_desc_curr = mp->tx_curr_desc_q; - mp->tx_curr_desc_q = (tx_desc_curr + 1) % mp->tx_ring_size; - - BUG_ON(mp->tx_curr_desc_q == mp->tx_used_desc_q); - return tx_desc_curr; -} - -/** - * eth_tx_fill_frag_descs - fill tx hw descriptors for an skb's fragments. +/* + * mv643xx_eth_start_xmit * - * Ensure the data for each fragment to be transmitted is mapped properly, - * then fill in descriptors in the tx hw queue. - */ -static void eth_tx_fill_frag_descs(struct mv643xx_private *mp, - struct sk_buff *skb) -{ - int frag; - int tx_index; - struct eth_tx_desc *desc; - - for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; - - tx_index = eth_alloc_tx_desc_index(mp); - desc = &mp->p_tx_desc_area[tx_index]; - - desc->cmd_sts = ETH_BUFFER_OWNED_BY_DMA; - /* Last Frag enables interrupt and frees the skb */ - if (frag == (skb_shinfo(skb)->nr_frags - 1)) { - desc->cmd_sts |= ETH_ZERO_PADDING | - ETH_TX_LAST_DESC | - ETH_TX_ENABLE_INTERRUPT; - mp->tx_skb[tx_index] = skb; - } else - mp->tx_skb[tx_index] = 0; - - desc = &mp->p_tx_desc_area[tx_index]; - desc->l4i_chk = 0; - desc->byte_cnt = this_frag->size; - desc->buf_ptr = dma_map_page(NULL, this_frag->page, - this_frag->page_offset, - this_frag->size, - DMA_TO_DEVICE); - } -} - -/** - * eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw + * This function is queues a packet in the Tx descriptor for + * required port. * - * Ensure the data for an skb to be transmitted is mapped properly, - * then fill in descriptors in the tx hw queue and start the hardware. - */ -static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp, - struct sk_buff *skb) -{ - int tx_index; - struct eth_tx_desc *desc; - u32 cmd_sts; - int length; - int nr_frags = skb_shinfo(skb)->nr_frags; - - cmd_sts = ETH_TX_FIRST_DESC | ETH_GEN_CRC | ETH_BUFFER_OWNED_BY_DMA; - - tx_index = eth_alloc_tx_desc_index(mp); - desc = &mp->p_tx_desc_area[tx_index]; - - if (nr_frags) { - eth_tx_fill_frag_descs(mp, skb); - - length = skb_headlen(skb); - mp->tx_skb[tx_index] = 0; - } else { - cmd_sts |= ETH_ZERO_PADDING | - ETH_TX_LAST_DESC | - ETH_TX_ENABLE_INTERRUPT; - length = skb->len; - mp->tx_skb[tx_index] = skb; - } - - desc->byte_cnt = length; - desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); - - if (skb->ip_summed == CHECKSUM_HW) { - BUG_ON(skb->protocol != ETH_P_IP); - - cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | - ETH_GEN_IP_V_4_CHECKSUM | - skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; - - switch (skb->nh.iph->protocol) { - case IPPROTO_UDP: - cmd_sts |= ETH_UDP_FRAME; - desc->l4i_chk = skb->h.uh->check; - break; - case IPPROTO_TCP: - desc->l4i_chk = skb->h.th->check; - break; - default: - BUG(); - } - } else { - /* Errata BTS #50, IHL must be 5 if no HW checksum */ - cmd_sts |= 5 << ETH_TX_IHL_SHIFT; - desc->l4i_chk = 0; - } - - /* ensure all other descriptors are written before first cmd_sts */ - wmb(); - desc->cmd_sts = cmd_sts; - - /* ensure all descriptors are written before poking hardware */ - wmb(); - mv643xx_eth_port_enable_tx(mp->port_num, ETH_TX_QUEUES_ENABLED); - - mp->tx_desc_count += nr_frags + 1; -} - -/** - * mv643xx_eth_start_xmit - queue an skb to the hardware for transmission + * Input : skb - a pointer to socket buffer + * dev - a pointer to the required port * + * Output : zero upon success */ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); struct net_device_stats *stats = &mp->stats; + ETH_FUNC_RET_STATUS status; unsigned long flags; + struct pkt_info pkt_info; - BUG_ON(netif_queue_stopped(dev)); - BUG_ON(skb == NULL); + if (netif_queue_stopped(dev)) { + printk(KERN_ERR + "%s: Tried sending packet when interface is stopped\n", + dev->name); + return 1; + } - if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) { - printk(KERN_ERR "%s: transmit with queue full\n", dev->name); + /* This is a hard error, log it. */ + if ((mp->tx_ring_size - mp->tx_ring_skbs) <= + (skb_shinfo(skb)->nr_frags + 1)) { netif_stop_queue(dev); + printk(KERN_ERR + "%s: Bug in mv643xx_eth - Trying to transmit when" + " queue full !\n", dev->name); + return 1; + } + + /* Paranoid check - this shouldn't happen */ + if (skb == NULL) { + stats->tx_dropped++; + printk(KERN_ERR "mv64320_eth paranoid check failed\n"); return 1; } +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX if (has_tiny_unaligned_frags(skb)) { - if (__skb_linearize(skb)) { + if ((skb_linearize(skb, GFP_ATOMIC) != 0)) { stats->tx_dropped++; printk(KERN_DEBUG "%s: failed to linearize tiny " "unaligned fragment\n", dev->name); @@ -1210,14 +1117,167 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&mp->lock, flags); - eth_tx_submit_descs_for_skb(mp, skb); - stats->tx_bytes = skb->len; - stats->tx_packets++; - dev->trans_start = jiffies; + if (!skb_shinfo(skb)->nr_frags) { + if (skb->ip_summed != CHECKSUM_HW) { + /* Errata BTS #50, IHL must be 5 if no HW checksum */ + pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | + ETH_TX_FIRST_DESC | + ETH_TX_LAST_DESC | + 5 << ETH_TX_IHL_SHIFT; + pkt_info.l4i_chk = 0; + } else { + pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | + ETH_TX_FIRST_DESC | + ETH_TX_LAST_DESC | + ETH_GEN_TCP_UDP_CHECKSUM | + ETH_GEN_IP_V_4_CHECKSUM | + skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; + /* CPU already calculated pseudo header checksum. */ + if ((skb->protocol == ETH_P_IP) && + (skb->nh.iph->protocol == IPPROTO_UDP) ) { + pkt_info.cmd_sts |= ETH_UDP_FRAME; + pkt_info.l4i_chk = skb->h.uh->check; + } else if ((skb->protocol == ETH_P_IP) && + (skb->nh.iph->protocol == IPPROTO_TCP)) + pkt_info.l4i_chk = skb->h.th->check; + else { + printk(KERN_ERR + "%s: chksum proto != IPv4 TCP or UDP\n", + dev->name); + spin_unlock_irqrestore(&mp->lock, flags); + return 1; + } + } + pkt_info.byte_cnt = skb->len; + pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len, + DMA_TO_DEVICE); + pkt_info.return_info = skb; + status = eth_port_send(mp, &pkt_info); + if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) + printk(KERN_ERR "%s: Error on transmitting packet\n", + dev->name); + stats->tx_bytes += pkt_info.byte_cnt; + } else { + unsigned int frag; + + /* first frag which is skb header */ + pkt_info.byte_cnt = skb_headlen(skb); + pkt_info.buf_ptr = dma_map_single(NULL, skb->data, + skb_headlen(skb), + DMA_TO_DEVICE); + pkt_info.l4i_chk = 0; + pkt_info.return_info = 0; + + if (skb->ip_summed != CHECKSUM_HW) + /* Errata BTS #50, IHL must be 5 if no HW checksum */ + pkt_info.cmd_sts = ETH_TX_FIRST_DESC | + 5 << ETH_TX_IHL_SHIFT; + else { + pkt_info.cmd_sts = ETH_TX_FIRST_DESC | + ETH_GEN_TCP_UDP_CHECKSUM | + ETH_GEN_IP_V_4_CHECKSUM | + skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; + /* CPU already calculated pseudo header checksum. */ + if ((skb->protocol == ETH_P_IP) && + (skb->nh.iph->protocol == IPPROTO_UDP)) { + pkt_info.cmd_sts |= ETH_UDP_FRAME; + pkt_info.l4i_chk = skb->h.uh->check; + } else if ((skb->protocol == ETH_P_IP) && + (skb->nh.iph->protocol == IPPROTO_TCP)) + pkt_info.l4i_chk = skb->h.th->check; + else { + printk(KERN_ERR + "%s: chksum proto != IPv4 TCP or UDP\n", + dev->name); + spin_unlock_irqrestore(&mp->lock, flags); + return 1; + } + } + + status = eth_port_send(mp, &pkt_info); + if (status != ETH_OK) { + if ((status == ETH_ERROR)) + printk(KERN_ERR + "%s: Error on transmitting packet\n", + dev->name); + if (status == ETH_QUEUE_FULL) + printk("Error on Queue Full \n"); + if (status == ETH_QUEUE_LAST_RESOURCE) + printk("Tx resource error \n"); + } + stats->tx_bytes += pkt_info.byte_cnt; + + /* Check for the remaining frags */ + for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { + skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; + pkt_info.l4i_chk = 0x0000; + pkt_info.cmd_sts = 0x00000000; + + /* Last Frag enables interrupt and frees the skb */ + if (frag == (skb_shinfo(skb)->nr_frags - 1)) { + pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT | + ETH_TX_LAST_DESC; + pkt_info.return_info = skb; + } else { + pkt_info.return_info = 0; + } + pkt_info.l4i_chk = 0; + pkt_info.byte_cnt = this_frag->size; + + pkt_info.buf_ptr = dma_map_page(NULL, this_frag->page, + this_frag->page_offset, + this_frag->size, + DMA_TO_DEVICE); + + status = eth_port_send(mp, &pkt_info); + + if (status != ETH_OK) { + if ((status == ETH_ERROR)) + printk(KERN_ERR "%s: Error on " + "transmitting packet\n", + dev->name); + + if (status == ETH_QUEUE_LAST_RESOURCE) + printk("Tx resource error \n"); + + if (status == ETH_QUEUE_FULL) + printk("Queue is full \n"); + } + stats->tx_bytes += pkt_info.byte_cnt; + } + } +#else + spin_lock_irqsave(&mp->lock, flags); + + pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | ETH_TX_FIRST_DESC | + ETH_TX_LAST_DESC; + pkt_info.l4i_chk = 0; + pkt_info.byte_cnt = skb->len; + pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len, + DMA_TO_DEVICE); + pkt_info.return_info = skb; + status = eth_port_send(mp, &pkt_info); + if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) + printk(KERN_ERR "%s: Error on transmitting packet\n", + dev->name); + stats->tx_bytes += pkt_info.byte_cnt; +#endif - if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) + /* Check if TX queue can handle another skb. If not, then + * signal higher layers to stop requesting TX + */ + if (mp->tx_ring_size <= (mp->tx_ring_skbs + MAX_DESCS_PER_SKB)) + /* + * Stop getting skb's from upper layers. + * Getting skb's from upper layers will be enabled again after + * packets are released. + */ netif_stop_queue(dev); + /* Update statistics and start of transmittion time */ + stats->tx_packets++; + dev->trans_start = jiffies; + spin_unlock_irqrestore(&mp->lock, flags); return 0; /* success */ @@ -1246,45 +1306,16 @@ static void mv643xx_netpoll(struct net_device *netdev) struct mv643xx_private *mp = netdev_priv(netdev); int port_num = mp->port_num; - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL); + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL); /* wait for previous write to complete */ mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); mv643xx_eth_int_handler(netdev->irq, netdev, NULL); - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL); } #endif -static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address, - int speed, int duplex, - struct ethtool_cmd *cmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - memset(cmd, 0, sizeof(*cmd)); - - cmd->port = PORT_MII; - cmd->transceiver = XCVR_INTERNAL; - cmd->phy_address = phy_address; - - if (speed == 0) { - cmd->autoneg = AUTONEG_ENABLE; - /* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */ - cmd->speed = SPEED_100; - cmd->advertising = ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full; - if (mp->mii.supports_gmii) - cmd->advertising |= ADVERTISED_1000baseT_Full; - } else { - cmd->autoneg = AUTONEG_DISABLE; - cmd->speed = speed; - cmd->duplex = duplex; - } -} - /*/ * mv643xx_eth_probe * @@ -1305,9 +1336,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) u8 *p; struct resource *res; int err; - struct ethtool_cmd cmd; - int duplex = DUPLEX_HALF; - int speed = 0; /* default to auto-negotiation */ dev = alloc_etherdev(sizeof(struct mv643xx_private)); if (!dev) @@ -1345,7 +1373,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) dev->tx_queue_len = mp->tx_ring_size; dev->base_addr = 0; dev->change_mtu = mv643xx_eth_change_mtu; - dev->do_ioctl = mv643xx_eth_do_ioctl; SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops); #ifdef MV643XX_CHECKSUM_OFFLOAD_TX @@ -1366,17 +1393,33 @@ static int mv643xx_eth_probe(struct platform_device *pdev) /* set default config values */ eth_port_uc_addr_get(dev, dev->dev_addr); + mp->port_config = MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE; + mp->port_config_extend = MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE; + mp->port_sdma_config = MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE; + mp->port_serial_control = MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE; mp->rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE; mp->tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE; pd = pdev->dev.platform_data; if (pd) { - if (pd->mac_addr) + if (pd->mac_addr != NULL) memcpy(dev->dev_addr, pd->mac_addr, 6); if (pd->phy_addr || pd->force_phy_addr) ethernet_phy_set(port_num, pd->phy_addr); + if (pd->port_config || pd->force_port_config) + mp->port_config = pd->port_config; + + if (pd->port_config_extend || pd->force_port_config_extend) + mp->port_config_extend = pd->port_config_extend; + + if (pd->port_sdma_config || pd->force_port_sdma_config) + mp->port_sdma_config = pd->port_sdma_config; + + if (pd->port_serial_control || pd->force_port_serial_control) + mp->port_serial_control = pd->port_serial_control; + if (pd->rx_queue_size) mp->rx_ring_size = pd->rx_queue_size; @@ -1392,35 +1435,16 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->rx_sram_size = pd->rx_sram_size; mp->rx_sram_addr = pd->rx_sram_addr; } - - duplex = pd->duplex; - speed = pd->speed; } - /* Hook up MII support for ethtool */ - mp->mii.dev = dev; - mp->mii.mdio_read = mv643xx_mdio_read; - mp->mii.mdio_write = mv643xx_mdio_write; - mp->mii.phy_id = ethernet_phy_get(port_num); - mp->mii.phy_id_mask = 0x3f; - mp->mii.reg_num_mask = 0x1f; - err = ethernet_phy_detect(port_num); if (err) { pr_debug("MV643xx ethernet port %d: " "No PHY detected at addr %d\n", port_num, ethernet_phy_get(port_num)); - goto out; + return err; } - ethernet_phy_reset(port_num); - mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii); - mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, speed, duplex, &cmd); - mv643xx_eth_update_pscr(dev, &cmd); - mv643xx_set_settings(dev, &cmd); - - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &pdev->dev); err = register_netdev(dev); if (err) goto out; @@ -1665,9 +1689,26 @@ MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); * to the Rx descriptor ring to enable the reuse of this source. * Return Rx resource is done using the eth_rx_return_buff API. * + * Transmit operation: + * The eth_port_send API supports Scatter-Gather which enables to + * send a packet spanned over multiple buffers. This means that + * for each packet info structure given by the user and put into + * the Tx descriptors ring, will be transmitted only if the 'LAST' + * bit will be set in the packet info command status field. This + * API also consider restriction regarding buffer alignments and + * sizes. + * The user must return a Tx resource after ensuring the buffer + * has been transmitted to enable the Tx ring indexes to update. + * + * BOARD LAYOUT + * This device is on-board. No jumper diagram is necessary. + * + * EXTERNAL INTERFACE + * * Prior to calling the initialization routine eth_port_init() the user * must set the following fields under mv643xx_private struct: * port_num User Ethernet port number. + * port_mac_addr[6] User defined port MAC address. * port_config User port configuration value. * port_config_extend User port config extend value. * port_sdma_config User port SDMA config value. @@ -1684,12 +1725,20 @@ MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); * return_info Tx/Rx user resource return information. */ +/* defines */ +/* SDMA command macros */ +#define ETH_ENABLE_TX_QUEUE(eth_port) \ + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), 1) + +/* locals */ + /* PHY routines */ static int ethernet_phy_get(unsigned int eth_port_num); static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); /* Ethernet Port routines */ -static void eth_port_set_filter_table_entry(int table, unsigned char entry); +static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble, + int option); /* * eth_port_init - Initialize the Ethernet port driver @@ -1717,11 +1766,17 @@ static void eth_port_set_filter_table_entry(int table, unsigned char entry); */ static void eth_port_init(struct mv643xx_private *mp) { + mp->port_rx_queue_command = 0; + mp->port_tx_queue_command = 0; + mp->rx_resource_err = 0; + mp->tx_resource_err = 0; eth_port_reset(mp->port_num); eth_port_init_mac_tables(mp->port_num); + + ethernet_phy_reset(mp->port_num); } /* @@ -1743,7 +1798,7 @@ static void eth_port_init(struct mv643xx_private *mp) * and ether_init_rx_desc_ring for Rx queues). * * INPUT: - * dev - a pointer to the required interface + * struct mv643xx_private *mp Ethernet port control struct * * OUTPUT: * Ethernet port is ready to receive and transmit. @@ -1751,13 +1806,10 @@ static void eth_port_init(struct mv643xx_private *mp) * RETURN: * None. */ -static void eth_port_start(struct net_device *dev) +static void eth_port_start(struct mv643xx_private *mp) { - struct mv643xx_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; int tx_curr_desc, rx_curr_desc; - u32 pscr; - struct ethtool_cmd ethtool_cmd; /* Assignment of Tx CTRP of given queue */ tx_curr_desc = mp->tx_curr_desc_q; @@ -1770,45 +1822,37 @@ static void eth_port_start(struct net_device *dev) (u32)((struct eth_rx_desc *)mp->rx_desc_dma + rx_curr_desc)); /* Add the assigned Ethernet address to the port's address table */ - eth_port_uc_addr_set(port_num, dev->dev_addr); + eth_port_uc_addr_set(port_num, mp->port_mac_addr); /* Assign port configuration and command. */ - mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), - MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE); + mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), mp->port_config); mv_write(MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port_num), - MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE); - - pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); + mp->port_config_extend); - pscr &= ~(MV643XX_ETH_SERIAL_PORT_ENABLE | MV643XX_ETH_FORCE_LINK_PASS); - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); - pscr |= MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL | - MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII | - MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX | - MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL | - MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED; - - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); + /* Increase the Rx side buffer size if supporting GigE */ + if (mp->port_serial_control & MV643XX_ETH_SET_GMII_SPEED_TO_1000) + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), + (mp->port_serial_control & 0xfff1ffff) | (0x5 << 17)); + else + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), + mp->port_serial_control); - pscr |= MV643XX_ETH_SERIAL_PORT_ENABLE; - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), + mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)) | + MV643XX_ETH_SERIAL_PORT_ENABLE); /* Assign port SDMA configuration */ mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num), - MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE); + mp->port_sdma_config); /* Enable port Rx. */ - mv643xx_eth_port_enable_rx(port_num, ETH_RX_QUEUES_ENABLED); + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), + mp->port_rx_queue_command); /* Disable port bandwidth limits by clearing MTU register */ mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0); - - /* save phy settings across reset */ - mv643xx_get_settings(dev, ðtool_cmd); - ethernet_phy_reset(mp->port_num); - mv643xx_set_settings(dev, ðtool_cmd); } /* @@ -1822,9 +1866,8 @@ static void eth_port_start(struct net_device *dev) * char * p_addr Address to be set * * OUTPUT: - * Set MAC address low and high registers. also calls - * eth_port_set_filter_table_entry() to set the unicast - * table with the proper information. + * Set MAC address low and high registers. also calls eth_port_uc_addr() + * To set the unicast table with the proper information. * * RETURN: * N/A. @@ -1835,7 +1878,6 @@ static void eth_port_uc_addr_set(unsigned int eth_port_num, { unsigned int mac_h; unsigned int mac_l; - int table; mac_l = (p_addr[4] << 8) | (p_addr[5]); mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) | @@ -1845,8 +1887,9 @@ static void eth_port_uc_addr_set(unsigned int eth_port_num, mv_write(MV643XX_ETH_MAC_ADDR_HIGH(eth_port_num), mac_h); /* Accept frames of this address */ - table = MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(eth_port_num); - eth_port_set_filter_table_entry(table, p_addr[5] & 0x0f); + eth_port_uc_addr(eth_port_num, p_addr[5], ACCEPT_MAC_ADDR); + + return; } /* @@ -1884,6 +1927,72 @@ static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *p_addr) p_addr[5] = mac_l & 0xff; } +/* + * eth_port_uc_addr - This function Set the port unicast address table + * + * DESCRIPTION: + * This function locates the proper entry in the Unicast table for the + * specified MAC nibble and sets its properties according to function + * parameters. + * + * INPUT: + * unsigned int eth_port_num Port number. + * unsigned char uc_nibble Unicast MAC Address last nibble. + * int option 0 = Add, 1 = remove address. + * + * OUTPUT: + * This function add/removes MAC addresses from the port unicast address + * table. + * + * RETURN: + * true is output succeeded. + * false if option parameter is invalid. + * + */ +static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble, + int option) +{ + unsigned int unicast_reg; + unsigned int tbl_offset; + unsigned int reg_offset; + + /* Locate the Unicast table entry */ + uc_nibble = (0xf & uc_nibble); + tbl_offset = (uc_nibble / 4) * 4; /* Register offset from unicast table base */ + reg_offset = uc_nibble % 4; /* Entry offset within the above register */ + + switch (option) { + case REJECT_MAC_ADDR: + /* Clear accepts frame bit at given unicast DA table entry */ + unicast_reg = mv_read((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + tbl_offset)); + + unicast_reg &= (0x0E << (8 * reg_offset)); + + mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + tbl_offset), unicast_reg); + break; + + case ACCEPT_MAC_ADDR: + /* Set accepts frame bit at unicast DA filter table entry */ + unicast_reg = + mv_read((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + tbl_offset)); + + unicast_reg |= (0x01 << (8 * reg_offset)); + + mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + tbl_offset), unicast_reg); + + break; + + default: + return 0; + } + + return 1; +} + /* * The entries in each table are indexed by a hash of a packet's MAC * address. One bit in each entry determines whether the packet is @@ -2096,8 +2205,8 @@ static void eth_port_init_mac_tables(unsigned int eth_port_num) /* Clear DA filter unicast table (Ex_dFUT) */ for (table_index = 0; table_index <= 0xC; table_index += 4) - mv_write(MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE - (eth_port_num) + table_index, 0); + mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + table_index), 0); for (table_index = 0; table_index <= 0xFC; table_index += 4) { /* Clear DA filter special multicast table (Ex_dFSMT) */ @@ -2280,73 +2389,6 @@ static void ethernet_phy_reset(unsigned int eth_port_num) eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data); phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */ eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data); - - /* wait for PHY to come out of reset */ - do { - udelay(1); - eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data); - } while (phy_reg_data & 0x8000); -} - -static void mv643xx_eth_port_enable_tx(unsigned int port_num, - unsigned int queues) -{ - mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), queues); -} - -static void mv643xx_eth_port_enable_rx(unsigned int port_num, - unsigned int queues) -{ - mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), queues); -} - -static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num) -{ - u32 queues; - - /* Stop Tx port activity. Check port Tx activity. */ - queues = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) - & 0xFF; - if (queues) { - /* Issue stop command for active queues only */ - mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), - (queues << 8)); - - /* Wait for all Tx activity to terminate. */ - /* Check port cause register that all Tx queues are stopped */ - while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) - & 0xFF) - udelay(PHY_WAIT_MICRO_SECONDS); - - /* Wait for Tx FIFO to empty */ - while (mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num)) & - ETH_PORT_TX_FIFO_EMPTY) - udelay(PHY_WAIT_MICRO_SECONDS); - } - - return queues; -} - -static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num) -{ - u32 queues; - - /* Stop Rx port activity. Check port Rx activity. */ - queues = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)) - & 0xFF; - if (queues) { - /* Issue stop command for active queues only */ - mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), - (queues << 8)); - - /* Wait for all Rx activity to terminate. */ - /* Check port cause register that all Rx queues are stopped */ - while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)) - & 0xFF) - udelay(PHY_WAIT_MICRO_SECONDS); - } - - return queues; } /* @@ -2371,21 +2413,70 @@ static void eth_port_reset(unsigned int port_num) { unsigned int reg_data; - mv643xx_eth_port_disable_tx(port_num); - mv643xx_eth_port_disable_rx(port_num); + /* Stop Tx port activity. Check port Tx activity. */ + reg_data = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)); + + if (reg_data & 0xFF) { + /* Issue stop command for active channels only */ + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), + (reg_data << 8)); + + /* Wait for all Tx activity to terminate. */ + /* Check port cause register that all Tx queues are stopped */ + while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) + & 0xFF) + udelay(10); + } + + /* Stop Rx port activity. Check port Rx activity. */ + reg_data = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)); + + if (reg_data & 0xFF) { + /* Issue stop command for active channels only */ + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), + (reg_data << 8)); + + /* Wait for all Rx activity to terminate. */ + /* Check port cause register that all Rx queues are stopped */ + while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)) + & 0xFF) + udelay(10); + } /* Clear all MIB counters */ eth_clear_mib_counters(port_num); /* Reset the Enable bit in the Configuration Register */ reg_data = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); - reg_data &= ~(MV643XX_ETH_SERIAL_PORT_ENABLE | - MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL | - MV643XX_ETH_FORCE_LINK_PASS); + reg_data &= ~MV643XX_ETH_SERIAL_PORT_ENABLE; mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data); } +static int eth_port_autoneg_supported(unsigned int eth_port_num) +{ + unsigned int phy_reg_data0; + + eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data0); + + return phy_reg_data0 & 0x1000; +} + +static int eth_port_link_is_up(unsigned int eth_port_num) +{ + unsigned int phy_reg_data1; + + eth_port_read_smi_reg(eth_port_num, 1, &phy_reg_data1); + + if (eth_port_autoneg_supported(eth_port_num)) { + if (phy_reg_data1 & 0x20) /* auto-neg complete */ + return 1; + } else if (phy_reg_data1 & 0x4) /* link up */ + return 1; + + return 0; +} + /* * eth_port_read_smi_reg - Read PHY registers * @@ -2491,21 +2582,250 @@ out: } /* - * Wrappers for MII support library. + * eth_port_send - Send an Ethernet packet + * + * DESCRIPTION: + * This routine send a given packet described by p_pktinfo parameter. It + * supports transmitting of a packet spaned over multiple buffers. The + * routine updates 'curr' and 'first' indexes according to the packet + * segment passed to the routine. In case the packet segment is first, + * the 'first' index is update. In any case, the 'curr' index is updated. + * If the routine get into Tx resource error it assigns 'curr' index as + * 'first'. This way the function can abort Tx process of multiple + * descriptors per packet. + * + * INPUT: + * struct mv643xx_private *mp Ethernet Port Control srtuct. + * struct pkt_info *p_pkt_info User packet buffer. + * + * OUTPUT: + * Tx ring 'curr' and 'first' indexes are updated. + * + * RETURN: + * ETH_QUEUE_FULL in case of Tx resource error. + * ETH_ERROR in case the routine can not access Tx desc ring. + * ETH_QUEUE_LAST_RESOURCE if the routine uses the last Tx resource. + * ETH_OK otherwise. + * + */ +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX +/* + * Modified to include the first descriptor pointer in case of SG */ -static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location) +static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, + struct pkt_info *p_pkt_info) { - int val; - struct mv643xx_private *mp = netdev_priv(dev); + int tx_desc_curr, tx_desc_used, tx_first_desc, tx_next_desc; + struct eth_tx_desc *current_descriptor; + struct eth_tx_desc *first_descriptor; + u32 command; + + /* Do not process Tx ring in case of Tx ring resource error */ + if (mp->tx_resource_err) + return ETH_QUEUE_FULL; + + /* + * The hardware requires that each buffer that is <= 8 bytes + * in length must be aligned on an 8 byte boundary. + */ + if (p_pkt_info->byte_cnt <= 8 && p_pkt_info->buf_ptr & 0x7) { + printk(KERN_ERR + "mv643xx_eth port %d: packet size <= 8 problem\n", + mp->port_num); + return ETH_ERROR; + } - eth_port_read_smi_reg(mp->port_num, location, &val); - return val; + mp->tx_ring_skbs++; + BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); + + /* Get the Tx Desc ring indexes */ + tx_desc_curr = mp->tx_curr_desc_q; + tx_desc_used = mp->tx_used_desc_q; + + current_descriptor = &mp->p_tx_desc_area[tx_desc_curr]; + + tx_next_desc = (tx_desc_curr + 1) % mp->tx_ring_size; + + current_descriptor->buf_ptr = p_pkt_info->buf_ptr; + current_descriptor->byte_cnt = p_pkt_info->byte_cnt; + current_descriptor->l4i_chk = p_pkt_info->l4i_chk; + mp->tx_skb[tx_desc_curr] = p_pkt_info->return_info; + + command = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC | + ETH_BUFFER_OWNED_BY_DMA; + if (command & ETH_TX_FIRST_DESC) { + tx_first_desc = tx_desc_curr; + mp->tx_first_desc_q = tx_first_desc; + first_descriptor = current_descriptor; + mp->tx_first_command = command; + } else { + tx_first_desc = mp->tx_first_desc_q; + first_descriptor = &mp->p_tx_desc_area[tx_first_desc]; + BUG_ON(first_descriptor == NULL); + current_descriptor->cmd_sts = command; + } + + if (command & ETH_TX_LAST_DESC) { + wmb(); + first_descriptor->cmd_sts = mp->tx_first_command; + + wmb(); + ETH_ENABLE_TX_QUEUE(mp->port_num); + + /* + * Finish Tx packet. Update first desc in case of Tx resource + * error */ + tx_first_desc = tx_next_desc; + mp->tx_first_desc_q = tx_first_desc; + } + + /* Check for ring index overlap in the Tx desc ring */ + if (tx_next_desc == tx_desc_used) { + mp->tx_resource_err = 1; + mp->tx_curr_desc_q = tx_first_desc; + + return ETH_QUEUE_LAST_RESOURCE; + } + + mp->tx_curr_desc_q = tx_next_desc; + + return ETH_OK; +} +#else +static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, + struct pkt_info *p_pkt_info) +{ + int tx_desc_curr; + int tx_desc_used; + struct eth_tx_desc *current_descriptor; + unsigned int command_status; + + /* Do not process Tx ring in case of Tx ring resource error */ + if (mp->tx_resource_err) + return ETH_QUEUE_FULL; + + mp->tx_ring_skbs++; + BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); + + /* Get the Tx Desc ring indexes */ + tx_desc_curr = mp->tx_curr_desc_q; + tx_desc_used = mp->tx_used_desc_q; + current_descriptor = &mp->p_tx_desc_area[tx_desc_curr]; + + command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC; + current_descriptor->buf_ptr = p_pkt_info->buf_ptr; + current_descriptor->byte_cnt = p_pkt_info->byte_cnt; + mp->tx_skb[tx_desc_curr] = p_pkt_info->return_info; + + /* Set last desc with DMA ownership and interrupt enable. */ + wmb(); + current_descriptor->cmd_sts = command_status | + ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT; + + wmb(); + ETH_ENABLE_TX_QUEUE(mp->port_num); + + /* Finish Tx packet. Update first desc in case of Tx resource error */ + tx_desc_curr = (tx_desc_curr + 1) % mp->tx_ring_size; + + /* Update the current descriptor */ + mp->tx_curr_desc_q = tx_desc_curr; + + /* Check for ring index overlap in the Tx desc ring */ + if (tx_desc_curr == tx_desc_used) { + mp->tx_resource_err = 1; + return ETH_QUEUE_LAST_RESOURCE; + } + + return ETH_OK; } +#endif -static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val) +/* + * eth_tx_return_desc - Free all used Tx descriptors + * + * DESCRIPTION: + * This routine returns the transmitted packet information to the caller. + * It uses the 'first' index to support Tx desc return in case a transmit + * of a packet spanned over multiple buffer still in process. + * In case the Tx queue was in "resource error" condition, where there are + * no available Tx resources, the function resets the resource error flag. + * + * INPUT: + * struct mv643xx_private *mp Ethernet Port Control srtuct. + * struct pkt_info *p_pkt_info User packet buffer. + * + * OUTPUT: + * Tx ring 'first' and 'used' indexes are updated. + * + * RETURN: + * ETH_OK on success + * ETH_ERROR otherwise. + * + */ +static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp, + struct pkt_info *p_pkt_info) { - struct mv643xx_private *mp = netdev_priv(dev); - eth_port_write_smi_reg(mp->port_num, location, val); + int tx_desc_used; + int tx_busy_desc; + struct eth_tx_desc *p_tx_desc_used; + unsigned int command_status; + unsigned long flags; + int err = ETH_OK; + + spin_lock_irqsave(&mp->lock, flags); + +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX + tx_busy_desc = mp->tx_first_desc_q; +#else + tx_busy_desc = mp->tx_curr_desc_q; +#endif + + /* Get the Tx Desc ring indexes */ + tx_desc_used = mp->tx_used_desc_q; + + p_tx_desc_used = &mp->p_tx_desc_area[tx_desc_used]; + + /* Sanity check */ + if (p_tx_desc_used == NULL) { + err = ETH_ERROR; + goto out; + } + + /* Stop release. About to overlap the current available Tx descriptor */ + if (tx_desc_used == tx_busy_desc && !mp->tx_resource_err) { + err = ETH_ERROR; + goto out; + } + + command_status = p_tx_desc_used->cmd_sts; + + /* Still transmitting... */ + if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) { + err = ETH_ERROR; + goto out; + } + + /* Pass the packet information to the caller */ + p_pkt_info->cmd_sts = command_status; + p_pkt_info->return_info = mp->tx_skb[tx_desc_used]; + p_pkt_info->buf_ptr = p_tx_desc_used->buf_ptr; + p_pkt_info->byte_cnt = p_tx_desc_used->byte_cnt; + mp->tx_skb[tx_desc_used] = NULL; + + /* Update the next descriptor to release. */ + mp->tx_used_desc_q = (tx_desc_used + 1) % mp->tx_ring_size; + + /* Any Tx return cancels the Tx resource error status */ + mp->tx_resource_err = 0; + + BUG_ON(mp->tx_ring_skbs == 0); + mp->tx_ring_skbs--; + +out: + spin_unlock_irqrestore(&mp->lock, flags); + + return err; } /* @@ -2697,6 +3017,111 @@ static const struct mv643xx_stats mv643xx_gstrings_stats[] = { #define MV643XX_STATS_LEN \ sizeof(mv643xx_gstrings_stats) / sizeof(struct mv643xx_stats) +static int +mv643xx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +{ + struct mv643xx_private *mp = netdev->priv; + int port_num = mp->port_num; + int autoneg = eth_port_autoneg_supported(port_num); + int mode_10_bit; + int auto_duplex; + int half_duplex = 0; + int full_duplex = 0; + int auto_speed; + int speed_10 = 0; + int speed_100 = 0; + int speed_1000 = 0; + + u32 pcs = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); + u32 psr = mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num)); + + mode_10_bit = psr & MV643XX_ETH_PORT_STATUS_MODE_10_BIT; + + if (mode_10_bit) { + ecmd->supported = SUPPORTED_10baseT_Half; + } else { + ecmd->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + (autoneg ? SUPPORTED_Autoneg : 0) | + SUPPORTED_TP); + + auto_duplex = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX); + auto_speed = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII); + + ecmd->advertising = ADVERTISED_TP; + + if (autoneg) { + ecmd->advertising |= ADVERTISED_Autoneg; + + if (auto_duplex) { + half_duplex = 1; + full_duplex = 1; + } else { + if (pcs & MV643XX_ETH_SET_FULL_DUPLEX_MODE) + full_duplex = 1; + else + half_duplex = 1; + } + + if (auto_speed) { + speed_10 = 1; + speed_100 = 1; + speed_1000 = 1; + } else { + if (pcs & MV643XX_ETH_SET_GMII_SPEED_TO_1000) + speed_1000 = 1; + else if (pcs & MV643XX_ETH_SET_MII_SPEED_TO_100) + speed_100 = 1; + else + speed_10 = 1; + } + + if (speed_10 & half_duplex) + ecmd->advertising |= ADVERTISED_10baseT_Half; + if (speed_10 & full_duplex) + ecmd->advertising |= ADVERTISED_10baseT_Full; + if (speed_100 & half_duplex) + ecmd->advertising |= ADVERTISED_100baseT_Half; + if (speed_100 & full_duplex) + ecmd->advertising |= ADVERTISED_100baseT_Full; + if (speed_1000) + ecmd->advertising |= ADVERTISED_1000baseT_Full; + } + } + + ecmd->port = PORT_TP; + ecmd->phy_address = ethernet_phy_get(port_num); + + ecmd->transceiver = XCVR_EXTERNAL; + + if (netif_carrier_ok(netdev)) { + if (mode_10_bit) + ecmd->speed = SPEED_10; + else { + if (psr & MV643XX_ETH_PORT_STATUS_GMII_1000) + ecmd->speed = SPEED_1000; + else if (psr & MV643XX_ETH_PORT_STATUS_MII_100) + ecmd->speed = SPEED_100; + else + ecmd->speed = SPEED_10; + } + + if (psr & MV643XX_ETH_PORT_STATUS_FULL_DUPLEX) + ecmd->duplex = DUPLEX_FULL; + else + ecmd->duplex = DUPLEX_HALF; + } else { + ecmd->speed = -1; + ecmd->duplex = -1; + } + + ecmd->autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE; + return 0; +} + static void mv643xx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) { @@ -2743,41 +3168,15 @@ static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, } } -static u32 mv643xx_eth_get_link(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - return mii_link_ok(&mp->mii); -} - -static int mv643xx_eth_nway_restart(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - return mii_nway_restart(&mp->mii); -} - -static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL); -} - static struct ethtool_ops mv643xx_ethtool_ops = { .get_settings = mv643xx_get_settings, - .set_settings = mv643xx_set_settings, .get_drvinfo = mv643xx_get_drvinfo, - .get_link = mv643xx_eth_get_link, + .get_link = ethtool_op_get_link, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_strings = mv643xx_get_strings, .get_stats_count = mv643xx_get_stats_count, .get_ethtool_stats = mv643xx_get_ethtool_stats, - .get_strings = mv643xx_get_strings, - .get_stats_count = mv643xx_get_stats_count, - .get_ethtool_stats = mv643xx_get_ethtool_stats, - .nway_reset = mv643xx_eth_nway_restart, }; /************* End ethtool support *************************/ diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h index 4262c1da6..f769f9b62 100644 --- a/drivers/net/mv643xx_eth.h +++ b/drivers/net/mv643xx_eth.h @@ -5,16 +5,53 @@ #include #include #include -#include #include +#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 + +/* + * The first part is the high level driver of the gigE ethernet ports. + */ + /* Checksum offload for Tx works for most packets, but * fails if previous packet sent did not use hw csum */ #define MV643XX_CHECKSUM_OFFLOAD_TX #define MV643XX_NAPI #define MV643XX_TX_FAST_REFILL +#undef MV643XX_RX_QUEUE_FILL_ON_TASK /* Does not work, yet */ #undef MV643XX_COAL /* @@ -36,50 +73,25 @@ #define MV643XX_RX_COAL 100 #endif -#ifdef MV643XX_CHECKSUM_OFFLOAD_TX -#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1) -#else -#define MAX_DESCS_PER_SKB 1 -#endif - /* - * The MV643XX HW requires 8-byte alignment. However, when I/O - * is non-cache-coherent, we need to ensure that the I/O buffers - * we use don't share cache lines with other data. + * The second part is the low level driver of the gigE ethernet ports. */ -#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_NOT_COHERENT_CACHE) -#define ETH_DMA_ALIGN L1_CACHE_BYTES -#else -#define ETH_DMA_ALIGN 8 -#endif - -#define ETH_VLAN_HLEN 4 -#define ETH_FCS_LEN 4 -#define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */ -#define ETH_WRAPPER_LEN (ETH_HW_IP_ALIGN + ETH_HLEN + \ - ETH_VLAN_HLEN + ETH_FCS_LEN) -#define ETH_RX_SKB_SIZE (dev->mtu + ETH_WRAPPER_LEN + ETH_DMA_ALIGN) - -#define ETH_RX_QUEUES_ENABLED (1 << 0) /* use only Q0 for receive */ -#define ETH_TX_QUEUES_ENABLED (1 << 0) /* use only Q0 for transmit */ - -#define ETH_INT_CAUSE_RX_DONE (ETH_RX_QUEUES_ENABLED << 2) -#define ETH_INT_CAUSE_RX_ERROR (ETH_RX_QUEUES_ENABLED << 9) -#define ETH_INT_CAUSE_RX (ETH_INT_CAUSE_RX_DONE | ETH_INT_CAUSE_RX_ERROR) -#define ETH_INT_CAUSE_EXT 0x00000002 -#define ETH_INT_UNMASK_ALL (ETH_INT_CAUSE_RX | ETH_INT_CAUSE_EXT) -#define ETH_INT_CAUSE_TX_DONE (ETH_TX_QUEUES_ENABLED << 0) -#define ETH_INT_CAUSE_TX_ERROR (ETH_TX_QUEUES_ENABLED << 8) -#define ETH_INT_CAUSE_TX (ETH_INT_CAUSE_TX_DONE | ETH_INT_CAUSE_TX_ERROR) -#define ETH_INT_CAUSE_PHY 0x00010000 -#define ETH_INT_UNMASK_ALL_EXT (ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY) - -#define ETH_INT_MASK_ALL 0x00000000 -#define ETH_INT_MASK_ALL_EXT 0x00000000 +/* + * Header File for : MV-643xx network interface header + * + * DESCRIPTION: + * This header file contains macros typedefs and function declaration for + * the Marvell Gig Bit Ethernet Controller. + * + * DEPENDENCIES: + * None. + * + */ -#define PHY_WAIT_ITERATIONS 1000 /* 1000 iterations * 10uS = 10mS max */ -#define PHY_WAIT_MICRO_SECONDS 10 +/* MAC accepet/reject macros */ +#define ACCEPT_MAC_ADDR 0 +#define REJECT_MAC_ADDR 1 /* Buffer offset from buffer pointer */ #define RX_BUF_OFFSET 0x2 @@ -121,71 +133,88 @@ #define ETH_MIB_LATE_COLLISION 0x7c /* Port serial status reg (PSR) */ -#define ETH_INTERFACE_PCM 0x00000001 -#define ETH_LINK_IS_UP 0x00000002 -#define ETH_PORT_AT_FULL_DUPLEX 0x00000004 -#define ETH_RX_FLOW_CTRL_ENABLED 0x00000008 -#define ETH_GMII_SPEED_1000 0x00000010 -#define ETH_MII_SPEED_100 0x00000020 -#define ETH_TX_IN_PROGRESS 0x00000080 -#define ETH_BYPASS_ACTIVE 0x00000100 -#define ETH_PORT_AT_PARTITION_STATE 0x00000200 -#define ETH_PORT_TX_FIFO_EMPTY 0x00000400 +#define ETH_INTERFACE_GMII_MII 0 +#define ETH_INTERFACE_PCM BIT0 +#define ETH_LINK_IS_DOWN 0 +#define ETH_LINK_IS_UP BIT1 +#define ETH_PORT_AT_HALF_DUPLEX 0 +#define ETH_PORT_AT_FULL_DUPLEX BIT2 +#define ETH_RX_FLOW_CTRL_DISABLED 0 +#define ETH_RX_FLOW_CTRL_ENBALED BIT3 +#define ETH_GMII_SPEED_100_10 0 +#define ETH_GMII_SPEED_1000 BIT4 +#define ETH_MII_SPEED_10 0 +#define ETH_MII_SPEED_100 BIT5 +#define ETH_NO_TX 0 +#define ETH_TX_IN_PROGRESS BIT7 +#define ETH_BYPASS_NO_ACTIVE 0 +#define ETH_BYPASS_ACTIVE BIT8 +#define ETH_PORT_NOT_AT_PARTITION_STATE 0 +#define ETH_PORT_AT_PARTITION_STATE BIT9 +#define ETH_PORT_TX_FIFO_NOT_EMPTY 0 +#define ETH_PORT_TX_FIFO_EMPTY BIT10 + +#define ETH_DEFAULT_RX_BPDU_QUEUE_3 (BIT23 | BIT22) +#define ETH_DEFAULT_RX_BPDU_QUEUE_4 BIT24 +#define ETH_DEFAULT_RX_BPDU_QUEUE_5 (BIT24 | BIT22) +#define ETH_DEFAULT_RX_BPDU_QUEUE_6 (BIT24 | BIT23) +#define ETH_DEFAULT_RX_BPDU_QUEUE_7 (BIT24 | BIT23 | BIT22) /* SMI reg */ -#define ETH_SMI_BUSY 0x10000000 /* 0 - Write, 1 - Read */ -#define ETH_SMI_READ_VALID 0x08000000 /* 0 - Write, 1 - Read */ -#define ETH_SMI_OPCODE_WRITE 0 /* Completion of Read */ -#define ETH_SMI_OPCODE_READ 0x04000000 /* Operation is in progress */ - -/* Interrupt Cause Register Bit Definitions */ +#define ETH_SMI_BUSY BIT28 /* 0 - Write, 1 - Read */ +#define ETH_SMI_READ_VALID BIT27 /* 0 - Write, 1 - Read */ +#define ETH_SMI_OPCODE_WRITE 0 /* Completion of Read operation */ +#define ETH_SMI_OPCODE_READ BIT26 /* Operation is in progress */ /* SDMA command status fields macros */ /* Tx & Rx descriptors status */ -#define ETH_ERROR_SUMMARY 0x00000001 +#define ETH_ERROR_SUMMARY (BIT0) /* Tx & Rx descriptors command */ -#define ETH_BUFFER_OWNED_BY_DMA 0x80000000 +#define ETH_BUFFER_OWNED_BY_DMA (BIT31) /* Tx descriptors status */ -#define ETH_LC_ERROR 0 -#define ETH_UR_ERROR 0x00000002 -#define ETH_RL_ERROR 0x00000004 -#define ETH_LLC_SNAP_FORMAT 0x00000200 +#define ETH_LC_ERROR (0 ) +#define ETH_UR_ERROR (BIT1 ) +#define ETH_RL_ERROR (BIT2 ) +#define ETH_LLC_SNAP_FORMAT (BIT9 ) /* Rx descriptors status */ -#define ETH_OVERRUN_ERROR 0x00000002 -#define ETH_MAX_FRAME_LENGTH_ERROR 0x00000004 -#define ETH_RESOURCE_ERROR 0x00000006 -#define ETH_VLAN_TAGGED 0x00080000 -#define ETH_BPDU_FRAME 0x00100000 -#define ETH_UDP_FRAME_OVER_IP_V_4 0x00200000 -#define ETH_OTHER_FRAME_TYPE 0x00400000 -#define ETH_LAYER_2_IS_ETH_V_2 0x00800000 -#define ETH_FRAME_TYPE_IP_V_4 0x01000000 -#define ETH_FRAME_HEADER_OK 0x02000000 -#define ETH_RX_LAST_DESC 0x04000000 -#define ETH_RX_FIRST_DESC 0x08000000 -#define ETH_UNKNOWN_DESTINATION_ADDR 0x10000000 -#define ETH_RX_ENABLE_INTERRUPT 0x20000000 -#define ETH_LAYER_4_CHECKSUM_OK 0x40000000 +#define ETH_CRC_ERROR (0 ) +#define ETH_OVERRUN_ERROR (BIT1 ) +#define ETH_MAX_FRAME_LENGTH_ERROR (BIT2 ) +#define ETH_RESOURCE_ERROR ((BIT2 | BIT1)) +#define ETH_VLAN_TAGGED (BIT19) +#define ETH_BPDU_FRAME (BIT20) +#define ETH_TCP_FRAME_OVER_IP_V_4 (0 ) +#define ETH_UDP_FRAME_OVER_IP_V_4 (BIT21) +#define ETH_OTHER_FRAME_TYPE (BIT22) +#define ETH_LAYER_2_IS_ETH_V_2 (BIT23) +#define ETH_FRAME_TYPE_IP_V_4 (BIT24) +#define ETH_FRAME_HEADER_OK (BIT25) +#define ETH_RX_LAST_DESC (BIT26) +#define ETH_RX_FIRST_DESC (BIT27) +#define ETH_UNKNOWN_DESTINATION_ADDR (BIT28) +#define ETH_RX_ENABLE_INTERRUPT (BIT29) +#define ETH_LAYER_4_CHECKSUM_OK (BIT30) /* Rx descriptors byte count */ -#define ETH_FRAME_FRAGMENTED 0x00000004 +#define ETH_FRAME_FRAGMENTED (BIT2) /* Tx descriptors command */ -#define ETH_LAYER_4_CHECKSUM_FIRST_DESC 0x00000400 -#define ETH_FRAME_SET_TO_VLAN 0x00008000 -#define ETH_UDP_FRAME 0x00010000 -#define ETH_GEN_TCP_UDP_CHECKSUM 0x00020000 -#define ETH_GEN_IP_V_4_CHECKSUM 0x00040000 -#define ETH_ZERO_PADDING 0x00080000 -#define ETH_TX_LAST_DESC 0x00100000 -#define ETH_TX_FIRST_DESC 0x00200000 -#define ETH_GEN_CRC 0x00400000 -#define ETH_TX_ENABLE_INTERRUPT 0x00800000 -#define ETH_AUTO_MODE 0x40000000 +#define ETH_LAYER_4_CHECKSUM_FIRST_DESC (BIT10) +#define ETH_FRAME_SET_TO_VLAN (BIT15) +#define ETH_TCP_FRAME (0 ) +#define ETH_UDP_FRAME (BIT16) +#define ETH_GEN_TCP_UDP_CHECKSUM (BIT17) +#define ETH_GEN_IP_V_4_CHECKSUM (BIT18) +#define ETH_ZERO_PADDING (BIT19) +#define ETH_TX_LAST_DESC (BIT20) +#define ETH_TX_FIRST_DESC (BIT21) +#define ETH_GEN_CRC (BIT22) +#define ETH_TX_ENABLE_INTERRUPT (BIT23) +#define ETH_AUTO_MODE (BIT30) #define ETH_TX_IHL_SHIFT 11 @@ -295,6 +324,13 @@ struct mv643xx_mib_counters { struct mv643xx_private { int port_num; /* User Ethernet port number */ + u8 port_mac_addr[6]; /* User defined port MAC address.*/ + u32 port_config; /* User port configuration value*/ + u32 port_config_extend; /* User port config extend value*/ + u32 port_sdma_config; /* User port SDMA config value */ + u32 port_serial_control; /* User port serial control value */ + u32 port_tx_queue_command; /* Port active Tx queues summary*/ + u32 port_rx_queue_command; /* Port active Rx queues summary*/ u32 rx_sram_addr; /* Base address of rx sram area */ u32 rx_sram_size; /* Size of rx sram area */ @@ -302,6 +338,7 @@ struct mv643xx_private { u32 tx_sram_size; /* Size of tx sram area */ int rx_resource_err; /* Rx ring resource error flag */ + int tx_resource_err; /* Tx ring resource error flag */ /* Tx/Rx rings managment indexes fields. For driver use */ @@ -310,6 +347,10 @@ struct mv643xx_private { /* Next available and first returning Tx resource */ int tx_curr_desc_q, tx_used_desc_q; +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX + int tx_first_desc_q; + u32 tx_first_command; +#endif #ifdef MV643XX_TX_FAST_REFILL u32 tx_clean_threshold; @@ -317,43 +358,54 @@ struct mv643xx_private { struct eth_rx_desc *p_rx_desc_area; dma_addr_t rx_desc_dma; - int rx_desc_area_size; + unsigned int rx_desc_area_size; struct sk_buff **rx_skb; struct eth_tx_desc *p_tx_desc_area; dma_addr_t tx_desc_dma; - int tx_desc_area_size; + unsigned int tx_desc_area_size; struct sk_buff **tx_skb; struct work_struct tx_timeout_task; + /* + * Former struct mv643xx_eth_priv members start here + */ struct net_device_stats stats; struct mv643xx_mib_counters mib_counters; spinlock_t lock; /* Size of Tx Ring per queue */ - int tx_ring_size; - /* Number of tx descriptors in use */ - int tx_desc_count; + unsigned int tx_ring_size; + /* Ammont of SKBs outstanding on Tx queue */ + unsigned int tx_ring_skbs; /* Size of Rx Ring per queue */ - int rx_ring_size; - /* Number of rx descriptors in use */ - int rx_desc_count; + unsigned int rx_ring_size; + /* Ammount of SKBs allocated to Rx Ring per queue */ + unsigned int rx_ring_skbs; + + /* + * rx_task used to fill RX ring out of bottom half context + */ + struct work_struct rx_task; /* * Used in case RX Ring is empty, which can be caused when * system does not have resources (skb's) */ struct timer_list timeout; + long rx_task_busy __attribute__ ((aligned(SMP_CACHE_BYTES))); + unsigned rx_timer_flag; u32 rx_int_coal; u32 tx_int_coal; - struct mii_if_info mii; }; +/* ethernet.h API list */ + /* Port operation control routines */ static void eth_port_init(struct mv643xx_private *mp); static void eth_port_reset(unsigned int eth_port_num); -static void eth_port_start(struct net_device *dev); +static void eth_port_start(struct mv643xx_private *mp); /* Port MAC address routines */ static void eth_port_uc_addr_set(unsigned int eth_port_num, @@ -371,6 +423,10 @@ static void eth_port_read_smi_reg(unsigned int eth_port_num, static void eth_clear_mib_counters(unsigned int eth_port_num); /* Port data flow control routines */ +static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, + struct pkt_info *p_pkt_info); +static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp, + struct pkt_info *p_pkt_info); static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp, struct pkt_info *p_pkt_info); static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp, diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 2e4ecedba..9d6d2548c 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -3,7 +3,6 @@ Written/copyright 1999-2001 by Donald Becker. Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com) Portions copyright 2001,2002 Manfred Spraul (manfred@colorfullife.com) - Portions copyright 2004 Harald Welte This software may be used and distributed according to the terms of the GNU General Public License (GPL), incorporated herein by reference. @@ -136,6 +135,8 @@ TODO: * big endian support with CFG:BEM instead of cpu_to_le32 + * support for an external PHY + * NAPI */ #include @@ -159,7 +160,6 @@ #include #include #include -#include #include /* Processor type for cache alignment. */ #include #include @@ -183,11 +183,13 @@ NETIF_MSG_TX_ERR) static int debug = -1; +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ +static int max_interrupt_work = 20; static int mtu; /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). This chip uses a 512 element hash table based on the Ethernet CRC. */ -static const int multicast_filter_limit = 100; +static int multicast_filter_limit = 100; /* Set the copy breakpoint for the copy-only-tiny-frames scheme. Setting to > 1518 effectively disables this feature. */ @@ -226,7 +228,7 @@ static int full_duplex[MAX_UNITS]; NATSEMI_PG1_NREGS) #define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ #define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) -#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */ +#define NATSEMI_EEPROM_SIZE 24 /* 12 16-bit values */ /* Buffer sizes: * The nic writes 32-bit values, even if the upper bytes of @@ -238,7 +240,7 @@ static int full_duplex[MAX_UNITS]; #define NATSEMI_RX_LIMIT 2046 /* maximum supported by hardware */ /* These identify the driver base version and may not be removed. */ -static const char version[] __devinitdata = +static char version[] __devinitdata = KERN_INFO DRV_NAME " dp8381x driver, version " DRV_VERSION ", " DRV_RELDATE "\n" KERN_INFO " originally by Donald Becker \n" @@ -249,11 +251,14 @@ MODULE_AUTHOR("Donald Becker "); MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver"); MODULE_LICENSE("GPL"); +module_param(max_interrupt_work, int, 0); module_param(mtu, int, 0); module_param(debug, int, 0); module_param(rx_copybreak, int, 0); module_param_array(options, int, NULL, 0); module_param_array(full_duplex, int, NULL, 0); +MODULE_PARM_DESC(max_interrupt_work, + "DP8381x maximum events handled per interrupt"); MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)"); MODULE_PARM_DESC(debug, "DP8381x default debug level"); MODULE_PARM_DESC(rx_copybreak, @@ -318,12 +323,12 @@ performance critical codepaths: The rx process only runs in the interrupt handler. Access from outside the interrupt handler is only permitted after disable_irq(). -The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap +The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap is set, then access is permitted under spin_lock_irq(&np->lock). Thus configuration functions that want to access everything must call disable_irq(dev->irq); - netif_tx_lock_bh(dev); + spin_lock_bh(dev->xmit_lock); spin_lock_irq(&np->lock); IV. Notes @@ -369,7 +374,7 @@ enum pcistuff { /* array of board data directly indexed by pci_tbl[x].driver_data */ -static const struct { +static struct { const char *name; unsigned long flags; } natsemi_pci_info[] __devinitdata = { @@ -686,8 +691,6 @@ struct netdev_private { /* Based on MTU+slack. */ unsigned int rx_buf_sz; int oom; - /* Interrupt status */ - u32 intr_status; /* Do not touch the nic registers */ int hands_off; /* external phy that is used: only valid if dev->if_port != PORT_TP */ @@ -714,8 +717,6 @@ struct netdev_private { unsigned int iosize; spinlock_t lock; u32 msg_enable; - /* EEPROM data */ - int eeprom_size; }; static void move_int_phy(struct net_device *dev, int addr); @@ -747,8 +748,7 @@ static void init_registers(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void netdev_error(struct net_device *dev, int intr_status); -static int natsemi_poll(struct net_device *dev, int *budget); -static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do); +static void netdev_rx(struct net_device *dev); static void netdev_tx_done(struct net_device *dev); static int natsemi_change_mtu(struct net_device *dev, int new_mtu); #ifdef CONFIG_NET_POLL_CONTROLLER @@ -776,18 +776,6 @@ static inline void __iomem *ns_ioaddr(struct net_device *dev) return (void __iomem *) dev->base_addr; } -static inline void natsemi_irq_enable(struct net_device *dev) -{ - writel(1, ns_ioaddr(dev) + IntrEnable); - readl(ns_ioaddr(dev) + IntrEnable); -} - -static inline void natsemi_irq_disable(struct net_device *dev) -{ - writel(0, ns_ioaddr(dev) + IntrEnable); - readl(ns_ioaddr(dev) + IntrEnable); -} - static void move_int_phy(struct net_device *dev, int addr) { struct netdev_private *np = netdev_priv(dev); @@ -891,8 +879,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, spin_lock_init(&np->lock); np->msg_enable = (debug >= 0) ? (1<hands_off = 0; - np->intr_status = 0; - np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE; /* Initial port: * - If the nic was configured to use an external phy and if find_mii @@ -946,9 +932,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, dev->do_ioctl = &netdev_ioctl; dev->tx_timeout = &tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - dev->poll = natsemi_poll; - dev->weight = 64; - #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = &natsemi_poll_controller; #endif @@ -1501,31 +1484,6 @@ static void natsemi_reset(struct net_device *dev) writel(rfcr, ioaddr + RxFilterAddr); } -static void reset_rx(struct net_device *dev) -{ - int i; - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = ns_ioaddr(dev); - - np->intr_status &= ~RxResetDone; - - writel(RxReset, ioaddr + ChipCmd); - - for (i=0;iintr_status |= readl(ioaddr + IntrStatus); - if (np->intr_status & RxResetDone) - break; - udelay(15); - } - if (i==NATSEMI_HW_TIMEOUT) { - printk(KERN_WARNING "%s: RX reset did not complete in %d usec.\n", - dev->name, i*15); - } else if (netif_msg_hw(np)) { - printk(KERN_WARNING "%s: RX reset took %d usec.\n", - dev->name, i*15); - } -} - static void natsemi_reload_eeprom(struct net_device *dev) { struct netdev_private *np = netdev_priv(dev); @@ -2200,92 +2158,68 @@ static void netdev_tx_done(struct net_device *dev) } } -/* The interrupt handler doesn't actually handle interrupts itself, it - * schedules a NAPI poll if there is anything to do. */ +/* The interrupt handler does all of the Rx thread work and cleans up + after the Tx thread. */ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; struct netdev_private *np = netdev_priv(dev); void __iomem * ioaddr = ns_ioaddr(dev); + int boguscnt = max_interrupt_work; + unsigned int handled = 0; if (np->hands_off) return IRQ_NONE; - - /* Reading automatically acknowledges. */ - np->intr_status = readl(ioaddr + IntrStatus); - - if (netif_msg_intr(np)) - printk(KERN_DEBUG - "%s: Interrupt, status %#08x, mask %#08x.\n", - dev->name, np->intr_status, - readl(ioaddr + IntrMask)); - - if (!np->intr_status) - return IRQ_NONE; - - prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]); + do { + /* Reading automatically acknowledges all int sources. */ + u32 intr_status = readl(ioaddr + IntrStatus); - if (netif_rx_schedule_prep(dev)) { - /* Disable interrupts and register for poll */ - natsemi_irq_disable(dev); - __netif_rx_schedule(dev); - } - return IRQ_HANDLED; -} + if (netif_msg_intr(np)) + printk(KERN_DEBUG + "%s: Interrupt, status %#08x, mask %#08x.\n", + dev->name, intr_status, + readl(ioaddr + IntrMask)); -/* This is the NAPI poll routine. As well as the standard RX handling - * it also handles all other interrupts that the chip might raise. - */ -static int natsemi_poll(struct net_device *dev, int *budget) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem * ioaddr = ns_ioaddr(dev); + if (intr_status == 0) + break; + handled = 1; - int work_to_do = min(*budget, dev->quota); - int work_done = 0; + if (intr_status & + (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | + IntrRxErr | IntrRxOverrun)) { + netdev_rx(dev); + } - do { - if (np->intr_status & - (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) { + if (intr_status & + (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) { spin_lock(&np->lock); netdev_tx_done(dev); spin_unlock(&np->lock); } /* Abnormal error summary/uncommon events handlers. */ - if (np->intr_status & IntrAbnormalSummary) - netdev_error(dev, np->intr_status); - - if (np->intr_status & - (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | - IntrRxErr | IntrRxOverrun)) { - netdev_rx(dev, &work_done, work_to_do); + if (intr_status & IntrAbnormalSummary) + netdev_error(dev, intr_status); + + if (--boguscnt < 0) { + if (netif_msg_intr(np)) + printk(KERN_WARNING + "%s: Too much work at interrupt, " + "status=%#08x.\n", + dev->name, intr_status); + break; } - - *budget -= work_done; - dev->quota -= work_done; - - if (work_done >= work_to_do) - return 1; - - np->intr_status = readl(ioaddr + IntrStatus); - } while (np->intr_status); + } while (1); - netif_rx_complete(dev); - - /* Reenable interrupts providing nothing is trying to shut - * the chip down. */ - spin_lock(&np->lock); - if (!np->hands_off && netif_running(dev)) - natsemi_irq_enable(dev); - spin_unlock(&np->lock); + if (netif_msg_intr(np)) + printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name); - return 0; + return IRQ_RETVAL(handled); } /* This routine is logically part of the interrupt handler, but separated for clarity and better register allocation. */ -static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) +static void netdev_rx(struct net_device *dev) { struct netdev_private *np = netdev_priv(dev); int entry = np->cur_rx % RX_RING_SIZE; @@ -2303,12 +2237,6 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) entry, desc_status); if (--boguscnt < 0) break; - - if (*work_done >= work_to_do) - break; - - (*work_done)++; - pkt_len = (desc_status & DescSizeMask) - 4; if ((desc_status&(DescMore|DescPktOK|DescRxLong)) != DescPktOK){ if (desc_status & DescMore) { @@ -2320,23 +2248,6 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) "status %#08x.\n", dev->name, np->cur_rx, desc_status); np->stats.rx_length_errors++; - - /* The RX state machine has probably - * locked up beneath us. Follow the - * reset procedure documented in - * AN-1287. */ - - spin_lock_irq(&np->lock); - reset_rx(dev); - reinit_rx(dev); - writel(np->ring_dma, ioaddr + RxRingPtr); - check_link(dev); - spin_unlock_irq(&np->lock); - - /* We'll enable RX on exit from this - * function. */ - break; - } else { /* There was an error. */ np->stats.rx_errors++; @@ -2382,7 +2293,7 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) np->rx_skbuff[entry] = NULL; } skb->protocol = eth_type_trans(skb, dev); - netif_receive_skb(skb); + netif_rx(skb); dev->last_rx = jiffies; np->stats.rx_packets++; np->stats.rx_bytes += pkt_len; @@ -2585,8 +2496,7 @@ static int get_regs_len(struct net_device *dev) static int get_eeprom_len(struct net_device *dev) { - struct netdev_private *np = netdev_priv(dev); - return np->eeprom_size; + return NATSEMI_EEPROM_SIZE; } static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) @@ -2673,20 +2583,15 @@ static u32 get_link(struct net_device *dev) static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { struct netdev_private *np = netdev_priv(dev); - u8 *eebuf; + u8 eebuf[NATSEMI_EEPROM_SIZE]; int res; - eebuf = kmalloc(np->eeprom_size, GFP_KERNEL); - if (!eebuf) - return -ENOMEM; - eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16); spin_lock_irq(&np->lock); res = netdev_get_eeprom(dev, eebuf); spin_unlock_irq(&np->lock); if (!res) memcpy(data, eebuf+eeprom->offset, eeprom->len); - kfree(eebuf); return res; } @@ -3042,10 +2947,9 @@ static int netdev_get_eeprom(struct net_device *dev, u8 *buf) int i; u16 *ebuf = (u16 *)buf; void __iomem * ioaddr = ns_ioaddr(dev); - struct netdev_private *np = netdev_priv(dev); /* eeprom_read reads 16 bits, and indexes by 16 bits */ - for (i = 0; i < np->eeprom_size/2; i++) { + for (i = 0; i < NATSEMI_EEPROM_SIZE/2; i++) { ebuf[i] = eeprom_read(ioaddr, i); /* The EEPROM itself stores data bit-swapped, but eeprom_read * reads it back "sanely". So we swap it back here in order to @@ -3170,7 +3074,9 @@ static int netdev_close(struct net_device *dev) del_timer_sync(&np->timer); disable_irq(dev->irq); spin_lock_irq(&np->lock); - natsemi_irq_disable(dev); + /* Disable interrupts, and flush posted writes */ + writel(0, ioaddr + IntrEnable); + readl(ioaddr + IntrEnable); np->hands_off = 1; spin_unlock_irq(&np->lock); enable_irq(dev->irq); @@ -3252,9 +3158,6 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev) * * netdev_timer: timer stopped by natsemi_suspend. * * intr_handler: doesn't acquire the spinlock. suspend calls * disable_irq() to enforce synchronization. - * * natsemi_poll: checks before reenabling interrupts. suspend - * sets hands_off, disables interrupts and then waits with - * netif_poll_disable(). * * Interrupts must be disabled, otherwise hands_off can cause irq storms. */ @@ -3280,8 +3183,6 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state) spin_unlock_irq(&np->lock); enable_irq(dev->irq); - netif_poll_disable(dev); - /* Update the error counts. */ __get_stats(dev); @@ -3334,7 +3235,6 @@ static int natsemi_resume (struct pci_dev *pdev) mod_timer(&np->timer, jiffies + 1*HZ); } netif_device_attach(dev); - netif_poll_enable(dev); out: rtnl_unlock(); return 0; diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c index 84e291e24..8f40368cf 100644 --- a/drivers/net/ne-h8300.c +++ b/drivers/net/ne-h8300.c @@ -180,12 +180,7 @@ struct net_device * __init ne_probe(int unit) err = do_ne_probe(dev); if (err) goto out; - err = register_netdev(dev); - if (err) - goto out1; return dev; -out1: - cleanup_card(dev); out: free_netdev(dev); return ERR_PTR(err); @@ -325,8 +320,13 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) dev->poll_controller = ei_poll; #endif NS8390_init(dev, 0); - return 0; + ret = register_netdev(dev); + if (ret) + goto out_irq; + return 0; +out_irq: + free_irq(dev->irq, dev); err_out: release_region(ioaddr, NE_IO_EXTENT); return ret; @@ -633,11 +633,8 @@ int init_module(void) err = init_reg_offset(dev, dev->base_addr); if (!err) { if (do_ne_probe(dev) == 0) { - if (register_netdev(dev) == 0) { - dev_ne[found++] = dev; - continue; - } - cleanup_card(dev); + dev_ne[found++] = dev; + continue; } } free_netdev(dev); diff --git a/drivers/net/ne.c b/drivers/net/ne.c index b32765215..94f782d51 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -50,7 +50,6 @@ static const char version2[] = #include #include #include -#include #include #include @@ -139,9 +138,8 @@ bad_clone_list[] __initdata = { #if defined(CONFIG_PLAT_MAPPI) # define DCR_VAL 0x4b -#elif defined(CONFIG_PLAT_OAKS32R) || \ - defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) -# define DCR_VAL 0x48 /* 8-bit mode */ +#elif defined(CONFIG_PLAT_OAKS32R) +# define DCR_VAL 0x48 #else # define DCR_VAL 0x49 #endif @@ -227,7 +225,7 @@ struct net_device * __init ne_probe(int unit) netdev_boot_setup_check(dev); #ifdef CONFIG_TOSHIBA_RBTX4938 - dev->base_addr = RBTX4938_RTL_8019_BASE; + dev->base_addr = 0x07f20280; dev->irq = RBTX4938_RTL_8019_IRQ; #endif err = do_ne_probe(dev); @@ -343,7 +341,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { if (bad_card) { printk(" (warning: no reset ack)"); break; @@ -397,22 +395,10 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) /* We must set the 8390 for word mode. */ outb_p(DCR_VAL, ioaddr + EN0_DCFG); start_page = NESM_START_PG; - - /* - * Realtek RTL8019AS datasheet says that the PSTOP register - * shouldn't exceed 0x60 in 8-bit mode. - * This chip can be identified by reading the signature from - * the remote byte count registers (otherwise write-only)... - */ - if ((DCR_VAL & 0x01) == 0 && /* 8-bit mode */ - inb(ioaddr + EN0_RCNTLO) == 0x50 && - inb(ioaddr + EN0_RCNTHI) == 0x70) - stop_page = 0x60; - else - stop_page = NESM_STOP_PG; + stop_page = NESM_STOP_PG; } else { start_page = NE1SM_START_PG; - stop_page = NE1SM_STOP_PG; + stop_page = NE1SM_STOP_PG; } #if defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R) @@ -522,9 +508,15 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) ei_status.name = name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; +#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) + wordlength = 1; +#endif - /* Use 16-bit mode only if this wasn't overridden by DCR_VAL */ - ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01)); +#ifdef CONFIG_PLAT_OAKS32R + ei_status.word16 = 0; +#else + ei_status.word16 = (wordlength == 2); +#endif ei_status.rx_start_page = start_page + TX_PAGES; #ifdef PACKETBUF_MEMSIZE @@ -588,7 +580,7 @@ static void ne_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); break; } @@ -795,7 +787,7 @@ retry: #endif while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); ne_reset_8390(dev); NS8390_init(dev,1); diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c index 2aa7b77f8..e6df375a1 100644 --- a/drivers/net/ne2.c +++ b/drivers/net/ne2.c @@ -75,7 +75,6 @@ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon #include #include -#include #include #include @@ -396,7 +395,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot) outb(inb(base_addr + NE_RESET), base_addr + NE_RESET); while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(" not found (no reset ack).\n"); retval = -ENODEV; goto out; @@ -549,7 +548,7 @@ static void ne_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk("%s: ne_reset_8390() did not complete.\n", dev->name); break; @@ -750,7 +749,7 @@ retry: #endif while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk("%s: timeout waiting for Tx RDC.\n", dev->name); ne_reset_8390(dev); NS8390_init(dev,1); diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index ced9fdb83..d11821dd8 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -645,7 +645,9 @@ static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - BUG_ON(!dev); + if (!dev) + BUG(); + unregister_netdev(dev); release_region(dev->base_addr, NE_IO_EXTENT); free_netdev(dev); diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index bf58db29e..edd1b5306 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -87,7 +87,6 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) } static struct console netconsole = { - .name = "netcon", .flags = CON_ENABLED | CON_PRINTBUFFER, .write = write_msg }; @@ -95,7 +94,7 @@ static struct console netconsole = { static int option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); - return 1; + return 0; } __setup("netconsole=", option_setup); @@ -107,7 +106,7 @@ static int init_netconsole(void) if(!configured) { printk("netconsole: not configured, aborting\n"); - return 0; + return -EINVAL; } if(netpoll_setup(&np)) diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index a68bf474f..2ab01a5d1 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c @@ -766,8 +766,8 @@ static void ni5010_show_registers(struct net_device *dev) #ifdef MODULE static struct net_device *dev_ni5010; -module_param(io, int, 0); -module_param(irq, int, 0); +MODULE_PARM(io, "i"); +MODULE_PARM(irq, "i"); MODULE_PARM_DESC(io, "ni5010 I/O base address"); MODULE_PARM_DESC(irq, "ni5010 IRQ number"); diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index b6427a81b..b0c3b6ab6 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -116,7 +116,6 @@ #include #include #include -#include #include #include @@ -568,7 +567,8 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb) #endif sg = dev->rx_info.descs + (next_empty * DESC_SIZE); - BUG_ON(NULL != dev->rx_info.skbs[next_empty]); + if (unlikely(NULL != dev->rx_info.skbs[next_empty])) + BUG(); dev->rx_info.skbs[next_empty] = skb; dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC; @@ -651,7 +651,7 @@ static void FASTCALL(phy_intr(struct net_device *ndev)); static void fastcall phy_intr(struct net_device *ndev) { struct ns83820 *dev = PRIV(ndev); - static const char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" }; + static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" }; u32 cfg, new_cfg; u32 tbisr, tanar, tanlpar; int speed, fullduplex, newlinkstate; @@ -1607,7 +1607,7 @@ static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enab { struct ns83820 *dev = PRIV(ndev); int timed_out = 0; - unsigned long start; + long start; u32 status; int loops = 0; @@ -1625,7 +1625,7 @@ static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enab break; if (status & fail) break; - if (time_after_eq(jiffies, start + HZ)) { + if ((jiffies - start) >= HZ) { timed_out = 1; break; } @@ -1827,10 +1827,10 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ int using_dac = 0; /* 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)) { + if (sizeof(dma_addr_t) == 8 && + !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) { using_dac = 1; - } else if (!pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { + } else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) { using_dac = 0; } else { printk(KERN_WARNING "ns83820.c: pci_set_dma_mask failed!\n"); @@ -2187,7 +2187,6 @@ static void __exit ns83820_exit(void) MODULE_AUTHOR("Benjamin LaHaise "); MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(VERSION); MODULE_DEVICE_TABLE(pci, ns83820_pci_tbl); diff --git a/drivers/net/oaknet.c b/drivers/net/oaknet.c index d0f686d6e..62167a29d 100644 --- a/drivers/net/oaknet.c +++ b/drivers/net/oaknet.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -607,7 +606,7 @@ retry: #endif while ((ei_ibp(base + EN0_ISR) & ENISR_RDC) == 0) { - if (time_after(jiffies, start + OAKNET_WAIT)) { + if (jiffies - start > OAKNET_WAIT) { printk("%s: timeout waiting for Tx RDC.\n", dev->name); oaknet_reset_8390(dev); NS8390_init(dev, TRUE); diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index fab93360f..48774efee 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -204,7 +204,7 @@ enum Window4 { /* Window 4: Xcvr/media bits. */ #define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ struct el3_private { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct net_device_stats stats; u16 advertising, partner; /* NWay media advertisement */ @@ -225,8 +225,8 @@ static char mii_preamble_required = 0; /* Index of functions. */ -static int tc574_config(struct pcmcia_device *link); -static void tc574_release(struct pcmcia_device *link); +static void tc574_config(dev_link_t *link); +static void tc574_release(dev_link_t *link); static void mdio_sync(kio_addr_t ioaddr, int bits); static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); @@ -256,9 +256,10 @@ static void tc574_detach(struct pcmcia_device *p_dev); with Card Services. */ -static int tc574_probe(struct pcmcia_device *link) +static int tc574_attach(struct pcmcia_device *p_dev) { struct el3_private *lp; + dev_link_t *link; struct net_device *dev; DEBUG(0, "3c574_attach()\n"); @@ -268,8 +269,8 @@ static int tc574_probe(struct pcmcia_device *link) if (!dev) return -ENOMEM; lp = netdev_priv(dev); + link = &lp->link; link->priv = dev; - lp->p_dev = link; spin_lock_init(&lp->window_lock); link->io.NumPorts1 = 32; @@ -279,6 +280,7 @@ static int tc574_probe(struct pcmcia_device *link) link->irq.Handler = &el3_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -296,7 +298,13 @@ static int tc574_probe(struct pcmcia_device *link) dev->watchdog_timeo = TX_TIMEOUT; #endif - return tc574_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + tc574_config(link); + + return 0; } /* tc574_attach */ /* @@ -308,16 +316,18 @@ static int tc574_probe(struct pcmcia_device *link) */ -static void tc574_detach(struct pcmcia_device *link) +static void tc574_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "3c574_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - tc574_release(link); + if (link->state & DEV_CONFIG) + tc574_release(link); free_netdev(dev); } /* tc574_detach */ @@ -331,10 +341,11 @@ static void tc574_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; +static char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; -static int tc574_config(struct pcmcia_device *link) +static void tc574_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); tuple_t tuple; @@ -352,27 +363,30 @@ static int tc574_config(struct pcmcia_device *link) tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); goto failed; } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -383,8 +397,8 @@ static int tc574_config(struct pcmcia_device *link) the hardware address. The future products may include a modem chip and put the address in the CIS. */ tuple.DesiredTuple = 0x88; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { - pcmcia_get_tuple_data(link, &tuple); + if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) { + pcmcia_get_tuple_data(handle, &tuple); for (i = 0; i < 3; i++) phys_addr[i] = htons(buf[i]); } else { @@ -398,9 +412,9 @@ static int tc574_config(struct pcmcia_device *link) } } tuple.DesiredTuple = CISTPL_VERS_1; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS && - pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS && - pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) { + if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS && + pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS && + pcmcia_parse_tuple(handle, &tuple, &parse) == CS_SUCCESS) { cardname = parse.version_1.str + parse.version_1.ofs[1]; } else cardname = "3Com 3c574"; @@ -459,12 +473,13 @@ static int tc574_config(struct pcmcia_device *link) } } - link->dev_node = &lp->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->state &= ~DEV_CONFIG_PENDING; + link->dev = &lp->node; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto failed; } @@ -478,13 +493,13 @@ static int tc574_config(struct pcmcia_device *link) 8 << config.u.ram_size, ram_split[config.u.ram_split], config.u.autoselect ? "autoselect " : ""); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: tc574_release(link); - return -ENODEV; + return; } /* tc574_config */ @@ -494,28 +509,44 @@ failed: still open, this will be postponed until it is closed. */ -static void tc574_release(struct pcmcia_device *link) +static void tc574_release(dev_link_t *link) { - pcmcia_disable_device(link); + DEBUG(0, "3c574_release(0x%p)\n", link); + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; } -static int tc574_suspend(struct pcmcia_device *link) +static int tc574_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int tc574_resume(struct pcmcia_device *link) +static int tc574_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - tc574_reset(dev); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + tc574_reset(dev); + netif_device_attach(dev); + } } return 0; @@ -726,9 +757,9 @@ static void tc574_reset(struct net_device *dev) static int el3_open(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; link->open++; @@ -1172,11 +1203,11 @@ static int el3_close(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; struct el3_private *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; DEBUG(2, "%s: shutting down ethercard.\n", dev->name); - if (pcmcia_dev_present(link)) { + if (DEV_OK(link)) { unsigned long flags; /* Turn off statistics ASAP. We update lp->stats below. */ @@ -1215,7 +1246,7 @@ static struct pcmcia_driver tc574_driver = { .drv = { .name = "3c574_cs", }, - .probe = tc574_probe, + .probe = tc574_attach, .remove = tc574_detach, .id_table = tc574_ids, .suspend = tc574_suspend, diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 875a0fe25..1c3c9c666 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include @@ -105,7 +104,7 @@ enum RxFilter { #define TX_TIMEOUT ((400*HZ)/1000) struct el3_private { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct net_device_stats stats; /* For transceiver monitoring */ @@ -116,7 +115,7 @@ struct el3_private { spinlock_t lock; }; -static const char *if_names[] = { "auto", "10baseT", "10base2", "AUI" }; +static char *if_names[] = { "auto", "10baseT", "10base2", "AUI" }; /*====================================================================*/ @@ -142,8 +141,8 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)"; /*====================================================================*/ -static int tc589_config(struct pcmcia_device *link); -static void tc589_release(struct pcmcia_device *link); +static void tc589_config(dev_link_t *link); +static void tc589_release(dev_link_t *link); static u16 read_eeprom(kio_addr_t ioaddr, int index); static void tc589_reset(struct net_device *dev); @@ -170,9 +169,10 @@ static void tc589_detach(struct pcmcia_device *p_dev); ======================================================================*/ -static int tc589_probe(struct pcmcia_device *link) +static int tc589_attach(struct pcmcia_device *p_dev) { struct el3_private *lp; + dev_link_t *link; struct net_device *dev; DEBUG(0, "3c589_attach()\n"); @@ -182,8 +182,8 @@ static int tc589_probe(struct pcmcia_device *link) if (!dev) return -ENOMEM; lp = netdev_priv(dev); + link = &lp->link; link->priv = dev; - lp->p_dev = link; spin_lock_init(&lp->lock); link->io.NumPorts1 = 16; @@ -193,6 +193,7 @@ static int tc589_probe(struct pcmcia_device *link) link->irq.Handler = &el3_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -211,7 +212,13 @@ static int tc589_probe(struct pcmcia_device *link) #endif SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - return tc589_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + tc589_config(link); + + return 0; } /* tc589_attach */ /*====================================================================== @@ -223,16 +230,18 @@ static int tc589_probe(struct pcmcia_device *link) ======================================================================*/ -static void tc589_detach(struct pcmcia_device *link) +static void tc589_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "3c589_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - tc589_release(link); + if (link->state & DEV_CONFIG) + tc589_release(link); free_netdev(dev); } /* tc589_detach */ @@ -248,8 +257,9 @@ static void tc589_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int tc589_config(struct pcmcia_device *link) +static void tc589_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); tuple_t tuple; @@ -264,40 +274,43 @@ static int tc589_config(struct pcmcia_device *link) phys_addr = (u16 *)dev->dev_addr; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Is this a 3c562? */ tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; - if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && - (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) { + if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) { if (le16_to_cpu(buf[0]) != MANFID_3COM) printk(KERN_INFO "3c589_cs: hmmm, is this really a " "3Com card??\n"); multi = (le16_to_cpu(buf[1]) == PRODID_3COM_3C562); } + + /* Configure card */ + link->state |= DEV_CONFIG; /* For the 3c562, the base address must be xx00-xx7f */ link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x10) { if (multi && (j & 0x80)) continue; link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); goto failed; } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -307,8 +320,8 @@ static int tc589_config(struct pcmcia_device *link) /* The 3c589 has an extra EEPROM for configuration info, including the hardware address. The 3c562 puts the address in the CIS. */ tuple.DesiredTuple = 0x88; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { - pcmcia_get_tuple_data(link, &tuple); + if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) { + pcmcia_get_tuple_data(handle, &tuple); for (i = 0; i < 3; i++) phys_addr[i] = htons(buf[i]); } else { @@ -332,12 +345,13 @@ static int tc589_config(struct pcmcia_device *link) else printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); - link->dev_node = &lp->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &lp->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if (register_netdev(dev) != 0) { printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto failed; } @@ -351,13 +365,14 @@ static int tc589_config(struct pcmcia_device *link) printk(KERN_INFO " %dK FIFO split %s Rx:Tx, %s xcvr\n", (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3], if_names[dev->if_port]); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: tc589_release(link); - return -ENODEV; + return; + } /* tc589_config */ /*====================================================================== @@ -368,28 +383,44 @@ failed: ======================================================================*/ -static void tc589_release(struct pcmcia_device *link) +static void tc589_release(dev_link_t *link) { - pcmcia_disable_device(link); + DEBUG(0, "3c589_release(0x%p)\n", link); + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; } -static int tc589_suspend(struct pcmcia_device *link) +static int tc589_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int tc589_resume(struct pcmcia_device *link) +static int tc589_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - tc589_reset(dev); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + tc589_reset(dev); + netif_device_attach(dev); + } } return 0; @@ -555,9 +586,9 @@ static int el3_config(struct net_device *dev, struct ifmap *map) static int el3_open(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; link->open++; @@ -765,7 +796,7 @@ static void media_check(unsigned long arg) media = inw(ioaddr+WN4_MEDIA) & 0xc810; /* Ignore collisions unless we've had no irq's recently */ - if (time_before(jiffies, lp->last_irq + HZ)) { + if (jiffies - lp->last_irq < HZ) { media &= ~0x0010; } else { /* Try harder to detect carrier errors */ @@ -816,9 +847,9 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); unsigned long flags; - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; - if (pcmcia_dev_present(link)) { + if (DEV_OK(link)) { spin_lock_irqsave(&lp->lock, flags); update_stats(dev); spin_unlock_irqrestore(&lp->lock, flags); @@ -918,11 +949,11 @@ static int el3_rx(struct net_device *dev) static void set_multicast_list(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; kio_addr_t ioaddr = dev->base_addr; u16 opts = SetRxFilter | RxStation | RxBroadcast; - if (!pcmcia_dev_present(link)) return; + if (!(DEV_OK(link))) return; if (dev->flags & IFF_PROMISC) opts |= RxMulticast | RxProm; else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) @@ -933,12 +964,12 @@ static void set_multicast_list(struct net_device *dev) static int el3_close(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; kio_addr_t ioaddr = dev->base_addr; DEBUG(1, "%s: shutting down ethercard.\n", dev->name); - if (pcmcia_dev_present(link)) { + if (DEV_OK(link)) { /* Turn off statistics ASAP. We update lp->stats below. */ outw(StatsDisable, ioaddr + EL3_CMD); @@ -988,7 +1019,7 @@ static struct pcmcia_driver tc589_driver = { .drv = { .name = "3c589_cs", }, - .probe = tc589_probe, + .probe = tc589_attach, .remove = tc589_detach, .id_table = tc589_ids, .suspend = tc589_suspend, diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 2ea66aca6..aa5581369 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "../8390.h" #include @@ -86,8 +85,8 @@ static char *version = /*====================================================================*/ -static int axnet_config(struct pcmcia_device *link); -static void axnet_release(struct pcmcia_device *link); +static void axnet_config(dev_link_t *link); +static void axnet_release(dev_link_t *link); static int axnet_open(struct net_device *dev); static int axnet_close(struct net_device *dev); static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -117,7 +116,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs *regs); /*====================================================================*/ typedef struct axnet_dev_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; caddr_t base; struct timer_list watchdog; @@ -142,9 +141,10 @@ static inline axnet_dev_t *PRIV(struct net_device *dev) ======================================================================*/ -static int axnet_probe(struct pcmcia_device *link) +static int axnet_attach(struct pcmcia_device *p_dev) { axnet_dev_t *info; + dev_link_t *link; struct net_device *dev; DEBUG(0, "axnet_attach()\n"); @@ -156,7 +156,7 @@ static int axnet_probe(struct pcmcia_device *link) return -ENOMEM; info = PRIV(dev); - info->p_dev = link; + link = &info->link; link->priv = dev; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; @@ -168,7 +168,13 @@ static int axnet_probe(struct pcmcia_device *link) dev->do_ioctl = &axnet_ioctl; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - return axnet_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + axnet_config(link); + + return 0; } /* axnet_attach */ /*====================================================================== @@ -180,16 +186,18 @@ static int axnet_probe(struct pcmcia_device *link) ======================================================================*/ -static void axnet_detach(struct pcmcia_device *link) +static void axnet_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "axnet_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - axnet_release(link); + if (link->state & DEV_CONFIG) + axnet_release(link); free_netdev(dev); } /* axnet_detach */ @@ -200,7 +208,7 @@ static void axnet_detach(struct pcmcia_device *link) ======================================================================*/ -static int get_prom(struct pcmcia_device *link) +static int get_prom(dev_link_t *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -254,7 +262,7 @@ static int get_prom(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int try_io_port(struct pcmcia_device *link) +static int try_io_port(dev_link_t *link) { int j, ret; if (link->io.NumPorts1 == 32) { @@ -275,23 +283,25 @@ static int try_io_port(struct pcmcia_device *link) for (j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link->handle, &link->io); if (ret == CS_SUCCESS) return ret; } return ret; } else { - return pcmcia_request_io(link, &link->io); + return pcmcia_request_io(link->handle, &link->io); } } -static int axnet_config(struct pcmcia_device *link) +static void axnet_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; axnet_dev_t *info = PRIV(dev); tuple_t tuple; cisparse_t parse; int i, j, last_ret, last_fn; u_short buf[64]; + config_info_t conf; DEBUG(0, "axnet_config(0x%p)\n", link); @@ -300,22 +310,29 @@ static int axnet_config(struct pcmcia_device *link) tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Look up current Vcc */ + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0 || + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; @@ -337,21 +354,21 @@ static int axnet_config(struct pcmcia_device *link) if (last_ret == CS_SUCCESS) break; } next_entry: - last_ret = pcmcia_get_next_tuple(link, &tuple); + last_ret = pcmcia_get_next_tuple(handle, &tuple); } if (last_ret != CS_SUCCESS) { - cs_error(link, RequestIO, last_ret); + cs_error(handle, RequestIO, last_ret); goto failed; } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); if (link->io.NumPorts2 == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; } - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -388,7 +405,7 @@ static int axnet_config(struct pcmcia_device *link) Bit 2 of CCSR is active low. */ if (i == 32) { conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 }; - pcmcia_access_configuration_register(link, ®); + pcmcia_access_configuration_register(link->handle, ®); for (i = 0; i < 32; i++) { j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); if ((j != 0) && (j != 0xffff)) break; @@ -396,12 +413,13 @@ static int axnet_config(struct pcmcia_device *link) } info->phy_id = (i < 32) ? i : -1; - link->dev_node = &info->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &info->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto failed; } @@ -417,13 +435,14 @@ static int axnet_config(struct pcmcia_device *link) } else { printk(KERN_NOTICE " No MII transceivers found!\n"); } - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: axnet_release(link); - return -ENODEV; + link->state &= ~DEV_CONFIG_PENDING; + return; } /* axnet_config */ /*====================================================================== @@ -434,29 +453,45 @@ failed: ======================================================================*/ -static void axnet_release(struct pcmcia_device *link) +static void axnet_release(dev_link_t *link) { - pcmcia_disable_device(link); + DEBUG(0, "axnet_release(0x%p)\n", link); + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; } -static int axnet_suspend(struct pcmcia_device *link) +static int axnet_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int axnet_resume(struct pcmcia_device *link) +static int axnet_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - axnet_reset_8390(dev); - AX88190_init(dev, 1); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + axnet_reset_8390(dev); + AX88190_init(dev, 1); + netif_device_attach(dev); + } } return 0; @@ -526,11 +561,11 @@ static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value) static int axnet_open(struct net_device *dev) { axnet_dev_t *info = PRIV(dev); - struct pcmcia_device *link = info->p_dev; + dev_link_t *link = &info->link; DEBUG(2, "axnet_open('%s')\n", dev->name); - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; link->open++; @@ -552,7 +587,7 @@ static int axnet_open(struct net_device *dev) static int axnet_close(struct net_device *dev) { axnet_dev_t *info = PRIV(dev); - struct pcmcia_device *link = info->p_dev; + dev_link_t *link = &info->link; DEBUG(2, "axnet_close('%s')\n", dev->name); @@ -797,7 +832,7 @@ static struct pcmcia_driver axnet_cs_driver = { .drv = { .name = "axnet_cs", }, - .probe = axnet_probe, + .probe = axnet_attach, .remove = axnet_detach, .id_table = axnet_ids, .suspend = axnet_suspend, @@ -1560,7 +1595,7 @@ static void ei_receive(struct net_device *dev) static void ei_rx_overrun(struct net_device *dev) { - axnet_dev_t *info = PRIV(dev); + axnet_dev_t *info = (axnet_dev_t *)dev; long e8390_base = dev->base_addr; unsigned char was_txing, must_resend = 0; struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); @@ -1647,56 +1682,17 @@ static struct net_device_stats *get_stats(struct net_device *dev) return &ei_local->stat; } -/* - * Form the 64 bit 8390 multicast table from the linked list of addresses - * associated with this dev structure. - */ - -static inline void make_mc_bits(u8 *bits, struct net_device *dev) -{ - struct dev_mc_list *dmi; - u32 crc; - - for (dmi=dev->mc_list; dmi; dmi=dmi->next) { - - crc = ether_crc(ETH_ALEN, dmi->dmi_addr); - /* - * The 8390 uses the 6 most significant bits of the - * CRC to index the multicast table. - */ - bits[crc>>29] |= (1<<((crc>>26)&7)); - } -} - /** * do_set_multicast_list - set/clear multicast filter * @dev: net device for which multicast filter is adjusted * - * Set or clear the multicast filter for this adaptor. - * Must be called with lock held. + * Set or clear the multicast filter for this adaptor. May be called + * from a BH in 2.1.x. Must be called with lock held. */ static void do_set_multicast_list(struct net_device *dev) { long e8390_base = dev->base_addr; - int i; - struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev); - - if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { - memset(ei_local->mcfilter, 0, 8); - if (dev->mc_list) - make_mc_bits(ei_local->mcfilter, dev); - } else { - /* set to accept-all */ - memset(ei_local->mcfilter, 0xFF, 8); - } - - outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); - for(i = 0; i < 8; i++) - { - outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); - } - outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); if(dev->flags&IFF_PROMISC) outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR); @@ -1704,8 +1700,6 @@ static void do_set_multicast_list(struct net_device *dev) outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR); else outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR); - - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); } /* @@ -1800,6 +1794,12 @@ static void AX88190_init(struct net_device *dev, int startp) if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) printk(KERN_ERR "Hw. address read/write mismap %d\n",i); } + /* + * Initialize the multicast list to accept-all. If we enable multicast + * the higher levels can do the filtering. + */ + for (i = 0; i < 8; i++) + outb_p(0xff, e8390_base + EN1_MULT + i); outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 441de824a..2827a48ea 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -118,8 +118,8 @@ MODULE_LICENSE("GPL"); /*====================================================================*/ -static int com20020_config(struct pcmcia_device *link); -static void com20020_release(struct pcmcia_device *link); +static void com20020_config(dev_link_t *link); +static void com20020_release(dev_link_t *link); static void com20020_detach(struct pcmcia_device *p_dev); @@ -138,8 +138,9 @@ typedef struct com20020_dev_t { ======================================================================*/ -static int com20020_probe(struct pcmcia_device *p_dev) +static int com20020_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; com20020_dev_t *info; struct net_device *dev; struct arcnet_local *lp; @@ -147,6 +148,10 @@ static int com20020_probe(struct pcmcia_device *p_dev) DEBUG(0, "com20020_attach()\n"); /* Create new network device */ + link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); + if (!link) + return -ENOMEM; + info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL); if (!info) goto fail_alloc_info; @@ -156,6 +161,7 @@ static int com20020_probe(struct pcmcia_device *p_dev) goto fail_alloc_dev; memset(info, 0, sizeof(struct com20020_dev_t)); + memset(link, 0, sizeof(struct dev_link_t)); lp = dev->priv; lp->timeout = timeout; lp->backplane = backplane; @@ -166,23 +172,28 @@ static int com20020_probe(struct pcmcia_device *p_dev) /* fill in our module parameters as defaults */ dev->dev_addr[0] = node; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.NumPorts1 = 16; - p_dev->io.IOAddrLines = 16; - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; - p_dev->conf.Attributes = CONF_ENABLE_IRQ; - p_dev->conf.IntType = INT_MEMORY_AND_IO; - p_dev->conf.Present = PRESENT_OPTION; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.NumPorts1 = 16; + link->io.IOAddrLines = 16; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.Present = PRESENT_OPTION; + + link->irq.Instance = info->dev = dev; + link->priv = info; - p_dev->irq.Instance = info->dev = dev; - p_dev->priv = info; + link->state |= DEV_PRESENT; + com20020_config(link); - return com20020_config(p_dev); + return 0; fail_alloc_dev: kfree(info); fail_alloc_info: + kfree(link); return -ENOMEM; } /* com20020_attach */ @@ -195,8 +206,9 @@ fail_alloc_info: ======================================================================*/ -static void com20020_detach(struct pcmcia_device *link) +static void com20020_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct com20020_dev_t *info = link->priv; struct net_device *dev = info->dev; @@ -204,7 +216,7 @@ static void com20020_detach(struct pcmcia_device *link) DEBUG(0, "com20020_detach(0x%p)\n", link); - if (link->dev_node) { + if (link->dev) { DEBUG(1,"unregister...\n"); unregister_netdev(dev); @@ -217,7 +229,8 @@ static void com20020_detach(struct pcmcia_device *link) free_irq(dev->irq, dev); } - com20020_release(link); + if (link->state & DEV_CONFIG) + com20020_release(link); /* Unlink device structure, free bits */ DEBUG(1,"unlinking...\n"); @@ -232,6 +245,8 @@ static void com20020_detach(struct pcmcia_device *link) DEBUG(1,"kfree2...\n"); kfree(info); } + DEBUG(1,"kfree3...\n"); + kfree(link); } /* com20020_detach */ @@ -246,9 +261,10 @@ static void com20020_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int com20020_config(struct pcmcia_device *link) +static void com20020_config(dev_link_t *link) { struct arcnet_local *lp; + client_handle_t handle; tuple_t tuple; cisparse_t parse; com20020_dev_t *info; @@ -257,6 +273,7 @@ static int com20020_config(struct pcmcia_device *link) u_char buf[64]; int ioaddr; + handle = link->handle; info = link->priv; dev = info->dev; @@ -269,11 +286,14 @@ static int com20020_config(struct pcmcia_device *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; + /* Configure card */ + link->state |= DEV_CONFIG; + DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1); i = !CS_SUCCESS; if (!link->io.BasePort1) @@ -281,13 +301,13 @@ static int com20020_config(struct pcmcia_device *link) for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10) { link->io.BasePort1 = ioaddr; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } } else - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i != CS_SUCCESS) { @@ -301,7 +321,7 @@ static int com20020_config(struct pcmcia_device *link) DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n", link->irq.AssignedIRQ, link->irq.IRQInfo1, link->irq.IRQInfo2); - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { DEBUG(1,"arcnet: requestIRQ failed totally!\n"); @@ -310,7 +330,7 @@ static int com20020_config(struct pcmcia_device *link) dev->irq = link->irq.AssignedIRQ; - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); if (com20020_check(dev)) { @@ -322,14 +342,15 @@ static int com20020_config(struct pcmcia_device *link) lp->card_name = "PCMCIA COM20020"; lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */ - link->dev_node = &info->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &info->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); i = com20020_found(dev, 0); /* calls register_netdev */ if (i != 0) { DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto failed; } @@ -337,14 +358,13 @@ static int com20020_config(struct pcmcia_device *link) DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n", dev->name, dev->base_addr, dev->irq); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: DEBUG(1,"com20020_config failed...\n"); com20020_release(link); - return -ENODEV; } /* com20020_config */ /*====================================================================== @@ -355,33 +375,52 @@ failed: ======================================================================*/ -static void com20020_release(struct pcmcia_device *link) +static void com20020_release(dev_link_t *link) { - DEBUG(0, "com20020_release(0x%p)\n", link); - pcmcia_disable_device(link); + + DEBUG(1,"release...\n"); + + DEBUG(0, "com20020_release(0x%p)\n", link); + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING); } -static int com20020_suspend(struct pcmcia_device *link) +static int com20020_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); com20020_dev_t *info = link->priv; struct net_device *dev = info->dev; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) { + netif_device_detach(dev); + } + pcmcia_release_configuration(link->handle); + } return 0; } -static int com20020_resume(struct pcmcia_device *link) +static int com20020_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); com20020_dev_t *info = link->priv; struct net_device *dev = info->dev; - if (link->open) { - int ioaddr = dev->base_addr; - struct arcnet_local *lp = dev->priv; - ARCRESET; - } + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + int ioaddr = dev->base_addr; + struct arcnet_local *lp = dev->priv; + ARCRESET; + } + } return 0; } @@ -397,7 +436,7 @@ static struct pcmcia_driver com20020_cs_driver = { .drv = { .name = "com20020_cs", }, - .probe = com20020_probe, + .probe = com20020_attach, .remove = com20020_detach, .id_table = com20020_ids, .suspend = com20020_suspend, diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 09b11761c..28fe2fb4d 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -84,10 +84,10 @@ static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23"; /* PCMCIA event handlers */ -static int fmvj18x_config(struct pcmcia_device *link); -static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id); -static int fmvj18x_setup_mfc(struct pcmcia_device *link); -static void fmvj18x_release(struct pcmcia_device *link); +static void fmvj18x_config(dev_link_t *link); +static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id); +static int fmvj18x_setup_mfc(dev_link_t *link); +static void fmvj18x_release(dev_link_t *link); static void fmvj18x_detach(struct pcmcia_device *p_dev); /* @@ -116,7 +116,7 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN, driver specific data structure */ typedef struct local_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct net_device_stats stats; long open_time; @@ -228,9 +228,10 @@ typedef struct local_info_t { #define BANK_1U 0x24 /* bank 1 (CONFIG_1) */ #define BANK_2U 0x28 /* bank 2 (CONFIG_1) */ -static int fmvj18x_probe(struct pcmcia_device *link) +static int fmvj18x_attach(struct pcmcia_device *p_dev) { local_info_t *lp; + dev_link_t *link; struct net_device *dev; DEBUG(0, "fmvj18x_attach()\n"); @@ -240,8 +241,8 @@ static int fmvj18x_probe(struct pcmcia_device *link) if (!dev) return -ENOMEM; lp = netdev_priv(dev); + link = &lp->link; link->priv = dev; - lp->p_dev = link; /* The io structure describes IO port mapping */ link->io.NumPorts1 = 32; @@ -256,6 +257,7 @@ static int fmvj18x_probe(struct pcmcia_device *link) /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; /* The FMVJ18x specific entries in the device structure. */ @@ -272,21 +274,29 @@ static int fmvj18x_probe(struct pcmcia_device *link) #endif SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - return fmvj18x_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + fmvj18x_config(link); + + return 0; } /* fmvj18x_attach */ /*====================================================================*/ -static void fmvj18x_detach(struct pcmcia_device *link) +static void fmvj18x_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "fmvj18x_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - fmvj18x_release(link); + if (link->state & DEV_CONFIG) + fmvj18x_release(link); free_netdev(dev); } /* fmvj18x_detach */ @@ -296,10 +306,10 @@ static void fmvj18x_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int mfc_try_io_port(struct pcmcia_device *link) +static int mfc_try_io_port(dev_link_t *link) { int i, ret; - static const kio_addr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; + static kio_addr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; for (i = 0; i < 5; i++) { link->io.BasePort2 = serial_base[i]; @@ -308,13 +318,13 @@ static int mfc_try_io_port(struct pcmcia_device *link) link->io.NumPorts2 = 0; printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n"); } - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link->handle, &link->io); if (ret == CS_SUCCESS) return ret; } return ret; } -static int ungermann_try_io_port(struct pcmcia_device *link) +static int ungermann_try_io_port(dev_link_t *link) { int ret; kio_addr_t ioaddr; @@ -324,7 +334,7 @@ static int ungermann_try_io_port(struct pcmcia_device *link) */ for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) { link->io.BasePort1 = ioaddr; - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link->handle, &link->io); if (ret == CS_SUCCESS) { /* calculate ConfigIndex value */ link->conf.ConfigIndex = @@ -335,8 +345,9 @@ static int ungermann_try_io_port(struct pcmcia_device *link) return ret; /* RequestIO failed */ } -static int fmvj18x_config(struct pcmcia_device *link) +static void fmvj18x_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; local_info_t *lp = netdev_priv(dev); tuple_t tuple; @@ -355,34 +366,42 @@ static int fmvj18x_config(struct pcmcia_device *link) registers. */ tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); tuple.TupleData = (u_char *)buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + + /* Configure card */ + link->state |= DEV_CONFIG; link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; tuple.DesiredTuple = CISTPL_FUNCE; tuple.TupleOffset = 0; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { + if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) { /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigIndex = parse.cftable_entry.index; tuple.DesiredTuple = CISTPL_MANFID; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); else buf[0] = 0xffff; switch (le16_to_cpu(buf[0])) { case MANFID_TDK: cardtype = TDK; - if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410 + if (le16_to_cpu(buf[1]) == PRODID_TDK_CF010) { + cs_status_t status; + pcmcia_get_status(handle, &status); + if (status.CardState & CS_EVENT_3VCARD) + link->conf.Vcc = 33; /* inserted in 3.3V slot */ + } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410 || le16_to_cpu(buf[1]) == PRODID_TDK_NP9610 || le16_to_cpu(buf[1]) == PRODID_TDK_MN3200) { /* MultiFunction Card */ @@ -410,8 +429,8 @@ static int fmvj18x_config(struct pcmcia_device *link) } else { /* old type card */ tuple.DesiredTuple = CISTPL_MANFID; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); else buf[0] = 0xffff; switch (le16_to_cpu(buf[0])) { @@ -442,10 +461,10 @@ static int fmvj18x_config(struct pcmcia_device *link) ret = ungermann_try_io_port(link); if (ret != CS_SUCCESS) goto cs_failed; } else { - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); + CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -474,17 +493,17 @@ static int fmvj18x_config(struct pcmcia_device *link) case CONTEC: tuple.DesiredTuple = CISTPL_FUNCE; tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); if (cardtype == MBH10304) { /* MBH10304's CIS_FUNCE is corrupted */ node_id = &(tuple.TupleData[5]); card_name = "FMV-J182"; } else { while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) { - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); } node_id = &(tuple.TupleData[2]); if( cardtype == TDK ) { @@ -526,12 +545,13 @@ static int fmvj18x_config(struct pcmcia_device *link) } lp->cardtype = cardtype; - link->dev_node = &lp->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &lp->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto failed; } @@ -544,18 +564,19 @@ static int fmvj18x_config(struct pcmcia_device *link) for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return 0; + return; cs_failed: /* All Card Services errors end up here */ - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: fmvj18x_release(link); - return -ENODEV; + link->state &= ~DEV_CONFIG_PENDING; + } /* fmvj18x_config */ /*====================================================================*/ -static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) +static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id) { win_req_t req; memreq_t mem; @@ -566,9 +587,9 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link, &req, &link->win); + i = pcmcia_request_window(&link->handle, &req, &link->win); if (i != CS_SUCCESS) { - cs_error(link, RequestWindow, i); + cs_error(link->handle, RequestWindow, i); return -1; } @@ -602,13 +623,13 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) iounmap(base); j = pcmcia_release_window(link->win); if (j != CS_SUCCESS) - cs_error(link, ReleaseWindow, j); + cs_error(link->handle, ReleaseWindow, j); return (i != 0x200) ? 0 : -1; } /* fmvj18x_get_hwinfo */ /*====================================================================*/ -static int fmvj18x_setup_mfc(struct pcmcia_device *link) +static int fmvj18x_setup_mfc(dev_link_t *link) { win_req_t req; memreq_t mem; @@ -621,9 +642,9 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link, &req, &link->win); + i = pcmcia_request_window(&link->handle, &req, &link->win); if (i != CS_SUCCESS) { - cs_error(link, RequestWindow, i); + cs_error(link->handle, RequestWindow, i); return -1; } @@ -645,35 +666,54 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) iounmap(base); j = pcmcia_release_window(link->win); if (j != CS_SUCCESS) - cs_error(link, ReleaseWindow, j); + cs_error(link->handle, ReleaseWindow, j); return 0; } /*====================================================================*/ -static void fmvj18x_release(struct pcmcia_device *link) +static void fmvj18x_release(dev_link_t *link) { - DEBUG(0, "fmvj18x_release(0x%p)\n", link); - pcmcia_disable_device(link); + + DEBUG(0, "fmvj18x_release(0x%p)\n", link); + + /* Don't bother checking to see if these succeed or not */ + pcmcia_release_window(link->win); + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; } -static int fmvj18x_suspend(struct pcmcia_device *link) +static int fmvj18x_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } + return 0; } -static int fmvj18x_resume(struct pcmcia_device *link) +static int fmvj18x_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - fjn_reset(dev); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + fjn_reset(dev); + netif_device_attach(dev); + } } return 0; @@ -711,7 +751,7 @@ static struct pcmcia_driver fmvj18x_cs_driver = { .drv = { .name = "fmvj18x_cs", }, - .probe = fmvj18x_probe, + .probe = fmvj18x_attach, .remove = fmvj18x_detach, .id_table = fmvj18x_ids, .suspend = fmvj18x_suspend, @@ -1108,11 +1148,11 @@ static int fjn_config(struct net_device *dev, struct ifmap *map){ static int fjn_open(struct net_device *dev) { struct local_info_t *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; DEBUG(4, "fjn_open('%s').\n", dev->name); - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; link->open++; @@ -1133,7 +1173,7 @@ static int fjn_open(struct net_device *dev) static int fjn_close(struct net_device *dev) { struct local_info_t *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; kio_addr_t ioaddr = dev->base_addr; DEBUG(4, "fjn_close('%s').\n", dev->name); diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index b8fe70b85..b9c7e3957 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -105,15 +105,15 @@ MODULE_LICENSE("GPL"); /*====================================================================*/ -static int ibmtr_config(struct pcmcia_device *link); +static void ibmtr_config(dev_link_t *link); static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase); -static void ibmtr_release(struct pcmcia_device *link); +static void ibmtr_release(dev_link_t *link); static void ibmtr_detach(struct pcmcia_device *p_dev); /*====================================================================*/ typedef struct ibmtr_dev_t { - struct pcmcia_device *p_dev; + dev_link_t link; struct net_device *dev; dev_node_t node; window_handle_t sram_win_handle; @@ -138,11 +138,12 @@ static struct ethtool_ops netdev_ethtool_ops = { ======================================================================*/ -static int ibmtr_attach(struct pcmcia_device *link) +static int ibmtr_attach(struct pcmcia_device *p_dev) { ibmtr_dev_t *info; + dev_link_t *link; struct net_device *dev; - + DEBUG(0, "ibmtr_attach()\n"); /* Create new token-ring device */ @@ -155,7 +156,7 @@ static int ibmtr_attach(struct pcmcia_device *link) return -ENOMEM; } - info->p_dev = link; + link = &info->link; link->priv = info; info->ti = netdev_priv(dev); @@ -166,14 +167,21 @@ static int ibmtr_attach(struct pcmcia_device *link) link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = &tok_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; link->irq.Instance = info->dev = dev; - + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - return ibmtr_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT; + ibmtr_config(link); + + return 0; } /* ibmtr_attach */ /*====================================================================== @@ -185,22 +193,23 @@ static int ibmtr_attach(struct pcmcia_device *link) ======================================================================*/ -static void ibmtr_detach(struct pcmcia_device *link) +static void ibmtr_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; DEBUG(0, "ibmtr_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); { struct tok_info *ti = netdev_priv(dev); del_timer_sync(&(ti->tr_timer)); } - - ibmtr_release(link); + if (link->state & DEV_CONFIG) + ibmtr_release(link); free_netdev(dev); kfree(info); @@ -217,8 +226,9 @@ static void ibmtr_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int ibmtr_config(struct pcmcia_device *link) +static void ibmtr_config(dev_link_t *link) { + client_handle_t handle = link->handle; ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; struct tok_info *ti = netdev_priv(dev); @@ -236,25 +246,29 @@ static int ibmtr_config(struct pcmcia_device *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; + + /* Configure card */ + link->state |= DEV_CONFIG; + link->conf.ConfigIndex = 0x61; /* Determine if this is PRIMARY or ALTERNATE. */ /* Try PRIMARY card at 0xA20-0xA23 */ link->io.BasePort1 = 0xA20; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i != CS_SUCCESS) { /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ link->io.BasePort1 = 0xA24; - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); + CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); } dev->base_addr = link->io.BasePort1; - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); dev->irq = link->irq.AssignedIRQ; ti->irq = link->irq.AssignedIRQ; ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); @@ -265,7 +279,7 @@ static int ibmtr_config(struct pcmcia_device *link) req.Base = 0; req.Size = 0x2000; req.AccessSpeed = 250; - CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); mem.CardOffset = mmiobase; mem.Page = 0; @@ -278,7 +292,7 @@ static int ibmtr_config(struct pcmcia_device *link) req.Base = 0; req.Size = sramsize * 1024; req.AccessSpeed = 250; - CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle)); mem.CardOffset = srambase; mem.Page = 0; @@ -288,20 +302,21 @@ static int ibmtr_config(struct pcmcia_device *link) ti->sram_virt = ioremap(req.Base, req.Size); ti->sram_phys = req.Base; - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); /* Set up the Token-Ring Controller Configuration Register and turn on the card. Check the "Local Area Network Credit Card Adapters Technical Reference" SC30-3585 for this info. */ ibmtr_hw_setup(dev, mmiobase); - link->dev_node = &info->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &info->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); i = ibmtr_probe_card(dev); if (i != 0) { printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto failed; } @@ -315,13 +330,12 @@ static int ibmtr_config(struct pcmcia_device *link) for (i = 0; i < TR_ALEN; i++) printk("%02X", dev->dev_addr[i]); printk("\n"); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: ibmtr_release(link); - return -ENODEV; } /* ibmtr_config */ /*====================================================================== @@ -332,41 +346,56 @@ failed: ======================================================================*/ -static void ibmtr_release(struct pcmcia_device *link) +static void ibmtr_release(dev_link_t *link) { - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + + DEBUG(0, "ibmtr_release(0x%p)\n", link); - DEBUG(0, "ibmtr_release(0x%p)\n", link); + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + if (link->win) { + struct tok_info *ti = netdev_priv(dev); + iounmap(ti->mmio); + pcmcia_release_window(link->win); + pcmcia_release_window(info->sram_win_handle); + } - if (link->win) { - struct tok_info *ti = netdev_priv(dev); - iounmap(ti->mmio); - pcmcia_release_window(info->sram_win_handle); - } - pcmcia_disable_device(link); + link->state &= ~DEV_CONFIG; } -static int ibmtr_suspend(struct pcmcia_device *link) +static int ibmtr_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int ibmtr_resume(struct pcmcia_device *link) +static int ibmtr_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; - if (link->open) { - ibmtr_probe(dev); /* really? */ - netif_device_attach(dev); - } + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + ibmtr_probe(dev); /* really? */ + netif_device_attach(dev); + } + } return 0; } diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index a8f6bfc96..4a232254a 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -362,7 +362,7 @@ typedef struct _mace_statistics { } mace_statistics; typedef struct _mace_private { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct net_device_stats linux_stats; /* Linux statistics counters */ mace_statistics mace_stats; /* MACE chip statistics counters */ @@ -388,7 +388,7 @@ static char *version = DRV_NAME " " DRV_VERSION " (Roger C. Pao)"; #endif -static const char *if_names[]={ +static char *if_names[]={ "Auto", "10baseT", "BNC", }; @@ -417,8 +417,8 @@ INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); Function Prototypes ---------------------------------------------------------------------------- */ -static int nmclan_config(struct pcmcia_device *link); -static void nmclan_release(struct pcmcia_device *link); +static void nmclan_config(dev_link_t *link); +static void nmclan_release(dev_link_t *link); static void nmclan_reset(struct net_device *dev); static int mace_config(struct net_device *dev, struct ifmap *map); @@ -443,9 +443,10 @@ nmclan_attach Services. ---------------------------------------------------------------------------- */ -static int nmclan_probe(struct pcmcia_device *link) +static int nmclan_attach(struct pcmcia_device *p_dev) { mace_private *lp; + dev_link_t *link; struct net_device *dev; DEBUG(0, "nmclan_attach()\n"); @@ -456,7 +457,7 @@ static int nmclan_probe(struct pcmcia_device *link) if (!dev) return -ENOMEM; lp = netdev_priv(dev); - lp->p_dev = link; + link = &lp->link; link->priv = dev; spin_lock_init(&lp->bank_lock); @@ -468,6 +469,7 @@ static int nmclan_probe(struct pcmcia_device *link) link->irq.Handler = &mace_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -487,7 +489,13 @@ static int nmclan_probe(struct pcmcia_device *link) dev->watchdog_timeo = TX_TIMEOUT; #endif - return nmclan_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + nmclan_config(link); + + return 0; } /* nmclan_attach */ /* ---------------------------------------------------------------------------- @@ -498,16 +506,18 @@ nmclan_detach when the device is released. ---------------------------------------------------------------------------- */ -static void nmclan_detach(struct pcmcia_device *link) +static void nmclan_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "nmclan_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - nmclan_release(link); + if (link->state & DEV_CONFIG) + nmclan_release(link); free_netdev(dev); } /* nmclan_detach */ @@ -651,8 +661,9 @@ nmclan_config #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int nmclan_config(struct pcmcia_device *link) +static void nmclan_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; mace_private *lp = netdev_priv(dev); tuple_t tuple; @@ -668,14 +679,17 @@ static int nmclan_config(struct pcmcia_device *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + /* Configure card */ + link->state |= DEV_CONFIG; + + CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -686,8 +700,8 @@ static int nmclan_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN); /* Verify configuration by reading the MACE ID. */ @@ -702,7 +716,8 @@ static int nmclan_config(struct pcmcia_device *link) } else { printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should" " be 0x40 0x?9\n", sig[0], sig[1]); - return -ENODEV; + link->state &= ~DEV_CONFIG_PENDING; + return; } } @@ -715,13 +730,14 @@ static int nmclan_config(struct pcmcia_device *link) else printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); - link->dev_node = &lp->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &lp->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); i = register_netdev(dev); if (i != 0) { printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto failed; } @@ -731,13 +747,14 @@ static int nmclan_config(struct pcmcia_device *link) dev->name, dev->base_addr, dev->irq, if_names[dev->if_port]); for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: - nmclan_release(link); - return -ENODEV; + nmclan_release(link); + return; + } /* nmclan_config */ /* ---------------------------------------------------------------------------- @@ -746,29 +763,46 @@ nmclan_release net device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. ---------------------------------------------------------------------------- */ -static void nmclan_release(struct pcmcia_device *link) +static void nmclan_release(dev_link_t *link) { - DEBUG(0, "nmclan_release(0x%p)\n", link); - pcmcia_disable_device(link); + + DEBUG(0, "nmclan_release(0x%p)\n", link); + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; } -static int nmclan_suspend(struct pcmcia_device *link) +static int nmclan_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } + return 0; } -static int nmclan_resume(struct pcmcia_device *link) +static int nmclan_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - nmclan_reset(dev); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + nmclan_reset(dev); + netif_device_attach(dev); + } } return 0; @@ -784,7 +818,7 @@ static void nmclan_reset(struct net_device *dev) mace_private *lp = netdev_priv(dev); #if RESET_XILINX - struct pcmcia_device *link = &lp->link; + dev_link_t *link = &lp->link; conf_reg_t reg; u_long OrigCorValue; @@ -793,7 +827,7 @@ static void nmclan_reset(struct net_device *dev) reg.Action = CS_READ; reg.Offset = CISREG_COR; reg.Value = 0; - pcmcia_access_configuration_register(link, ®); + pcmcia_access_configuration_register(link->handle, ®); OrigCorValue = reg.Value; /* Reset Xilinx */ @@ -802,12 +836,12 @@ static void nmclan_reset(struct net_device *dev) DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n", OrigCorValue); reg.Value = COR_SOFT_RESET; - pcmcia_access_configuration_register(link, ®); + pcmcia_access_configuration_register(link->handle, ®); /* Need to wait for 20 ms for PCMCIA to finish reset. */ /* Restore original COR configuration index */ reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK); - pcmcia_access_configuration_register(link, ®); + pcmcia_access_configuration_register(link->handle, ®); /* Xilinx is now completely reset along with the MACE chip. */ lp->tx_free_frames=AM2150_MAX_TX_FRAMES; @@ -851,9 +885,9 @@ static int mace_open(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; mace_private *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; link->open++; @@ -874,7 +908,7 @@ static int mace_close(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; mace_private *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; DEBUG(2, "%s: shutting down ethercard.\n", dev->name); @@ -929,12 +963,12 @@ mace_start_xmit static void mace_tx_timeout(struct net_device *dev) { mace_private *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name); #if RESET_ON_TIMEOUT printk("resetting card\n"); - pcmcia_reset_card(link, NULL); + pcmcia_reset_card(link->handle, NULL); #else /* #if RESET_ON_TIMEOUT */ printk("NOT resetting card\n"); #endif /* #if RESET_ON_TIMEOUT */ @@ -1204,7 +1238,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt) dev->last_rx = jiffies; lp->linux_stats.rx_packets++; - lp->linux_stats.rx_bytes += pkt_len; + lp->linux_stats.rx_bytes += skb->len; outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */ continue; } else { @@ -1601,7 +1635,7 @@ static struct pcmcia_driver nmclan_cs_driver = { .drv = { .name = "nmclan_cs", }, - .probe = nmclan_probe, + .probe = nmclan_attach, .remove = nmclan_detach, .id_table = nmclan_ids, .suspend = nmclan_suspend, diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index d090df413..d85b758f3 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -66,7 +66,7 @@ #define PCNET_RDC_TIMEOUT (2*HZ/100) /* Max wait in jiffies for Tx RDC */ -static const char *if_names[] = { "auto", "10baseT", "10base2"}; +static char *if_names[] = { "auto", "10baseT", "10base2"}; #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; @@ -103,8 +103,8 @@ module_param_array(hw_addr, int, NULL, 0); /*====================================================================*/ static void mii_phy_probe(struct net_device *dev); -static int pcnet_config(struct pcmcia_device *link); -static void pcnet_release(struct pcmcia_device *link); +static void pcnet_config(dev_link_t *link); +static void pcnet_release(dev_link_t *link); static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -113,9 +113,9 @@ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); static void pcnet_reset_8390(struct net_device *dev); static int set_config(struct net_device *dev, struct ifmap *map); -static int setup_shmem_window(struct pcmcia_device *link, int start_pg, +static int setup_shmem_window(dev_link_t *link, int start_pg, int stop_pg, int cm_offset); -static int setup_dma_config(struct pcmcia_device *link, int start_pg, +static int setup_dma_config(dev_link_t *link, int start_pg, int stop_pg); static void pcnet_detach(struct pcmcia_device *p_dev); @@ -214,7 +214,7 @@ static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII }; static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII }; typedef struct pcnet_dev_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; u_int flags; void __iomem *base; @@ -240,9 +240,10 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev) ======================================================================*/ -static int pcnet_probe(struct pcmcia_device *link) +static int pcnet_probe(struct pcmcia_device *p_dev) { pcnet_dev_t *info; + dev_link_t *link; struct net_device *dev; DEBUG(0, "pcnet_attach()\n"); @@ -251,7 +252,7 @@ static int pcnet_probe(struct pcmcia_device *link) dev = __alloc_ei_netdev(sizeof(pcnet_dev_t)); if (!dev) return -ENOMEM; info = PRIV(dev); - info->p_dev = link; + link = &info->link; link->priv = dev; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -264,7 +265,13 @@ static int pcnet_probe(struct pcmcia_device *link) dev->stop = &pcnet_close; dev->set_config = &set_config; - return pcnet_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + pcnet_config(link); + + return 0; } /* pcnet_attach */ /*====================================================================== @@ -276,16 +283,18 @@ static int pcnet_probe(struct pcmcia_device *link) ======================================================================*/ -static void pcnet_detach(struct pcmcia_device *link) +static void pcnet_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "pcnet_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - pcnet_release(link); + if (link->state & DEV_CONFIG) + pcnet_release(link); free_netdev(dev); } /* pcnet_detach */ @@ -297,7 +306,7 @@ static void pcnet_detach(struct pcmcia_device *link) ======================================================================*/ -static hw_info_t *get_hwinfo(struct pcmcia_device *link) +static hw_info_t *get_hwinfo(dev_link_t *link) { struct net_device *dev = link->priv; win_req_t req; @@ -309,9 +318,9 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link, &req, &link->win); + i = pcmcia_request_window(&link->handle, &req, &link->win); if (i != CS_SUCCESS) { - cs_error(link, RequestWindow, i); + cs_error(link->handle, RequestWindow, i); return NULL; } @@ -334,7 +343,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) iounmap(virt); j = pcmcia_release_window(link->win); if (j != CS_SUCCESS) - cs_error(link, ReleaseWindow, j); + cs_error(link->handle, ReleaseWindow, j); return (i < NR_INFO) ? hw_info+i : NULL; } /* get_hwinfo */ @@ -346,7 +355,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) ======================================================================*/ -static hw_info_t *get_prom(struct pcmcia_device *link) +static hw_info_t *get_prom(dev_link_t *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -400,7 +409,7 @@ static hw_info_t *get_prom(struct pcmcia_device *link) ======================================================================*/ -static hw_info_t *get_dl10019(struct pcmcia_device *link) +static hw_info_t *get_dl10019(dev_link_t *link) { struct net_device *dev = link->priv; int i; @@ -422,7 +431,7 @@ static hw_info_t *get_dl10019(struct pcmcia_device *link) ======================================================================*/ -static hw_info_t *get_ax88190(struct pcmcia_device *link) +static hw_info_t *get_ax88190(dev_link_t *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -455,7 +464,7 @@ static hw_info_t *get_ax88190(struct pcmcia_device *link) ======================================================================*/ -static hw_info_t *get_hwired(struct pcmcia_device *link) +static hw_info_t *get_hwired(dev_link_t *link) { struct net_device *dev = link->priv; int i; @@ -482,7 +491,7 @@ static hw_info_t *get_hwired(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int try_io_port(struct pcmcia_device *link) +static int try_io_port(dev_link_t *link) { int j, ret; if (link->io.NumPorts1 == 32) { @@ -503,17 +512,18 @@ static int try_io_port(struct pcmcia_device *link) for (j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; - ret = pcmcia_request_io(link, &link->io); + ret = pcmcia_request_io(link->handle, &link->io); if (ret == CS_SUCCESS) return ret; } return ret; } else { - return pcmcia_request_io(link, &link->io); + return pcmcia_request_io(link->handle, &link->io); } } -static int pcnet_config(struct pcmcia_device *link) +static void pcnet_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); tuple_t tuple; @@ -521,6 +531,7 @@ static int pcnet_config(struct pcmcia_device *link) int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; int manfid = 0, prodid = 0, has_shmem = 0; u_short buf[64]; + config_info_t conf; hw_info_t *hw_info; DEBUG(0, "pcnet_config(0x%p)\n", link); @@ -530,29 +541,36 @@ static int pcnet_config(struct pcmcia_device *link) tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Look up current Vcc */ + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; + tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; - if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && - (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) { + if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) { manfid = le16_to_cpu(buf[0]); prodid = le16_to_cpu(buf[1]); } tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0 || + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; @@ -576,14 +594,14 @@ static int pcnet_config(struct pcmcia_device *link) if (last_ret == CS_SUCCESS) break; } next_entry: - last_ret = pcmcia_get_next_tuple(link, &tuple); + last_ret = pcmcia_get_next_tuple(handle, &tuple); } if (last_ret != CS_SUCCESS) { - cs_error(link, RequestIO, last_ret); + cs_error(handle, RequestIO, last_ret); goto failed; } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); if (link->io.NumPorts2 == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; @@ -593,7 +611,7 @@ static int pcnet_config(struct pcmcia_device *link) (prodid == PRODID_IBM_HOME_AND_AWAY)) link->conf.ConfigIndex |= 0x10; - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; if (info->flags & HAS_MISC_REG) { @@ -661,8 +679,9 @@ static int pcnet_config(struct pcmcia_device *link) info->eth_phy = 0; } - link->dev_node = &info->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &info->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = ei_poll; @@ -670,7 +689,7 @@ static int pcnet_config(struct pcmcia_device *link) if (register_netdev(dev) != 0) { printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto failed; } @@ -693,13 +712,14 @@ static int pcnet_config(struct pcmcia_device *link) printk(" hw_addr "); for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: pcnet_release(link); - return -ENODEV; + link->state &= ~DEV_CONFIG_PENDING; + return; } /* pcnet_config */ /*====================================================================== @@ -710,16 +730,21 @@ failed: ======================================================================*/ -static void pcnet_release(struct pcmcia_device *link) +static void pcnet_release(dev_link_t *link) { - pcnet_dev_t *info = PRIV(link->priv); + pcnet_dev_t *info = PRIV(link->priv); - DEBUG(0, "pcnet_release(0x%p)\n", link); + DEBUG(0, "pcnet_release(0x%p)\n", link); - if (info->flags & USE_SHMEM) - iounmap(info->base); + if (info->flags & USE_SHMEM) { + iounmap(info->base); + pcmcia_release_window(link->win); + } + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); - pcmcia_disable_device(link); + link->state &= ~DEV_CONFIG; } /*====================================================================== @@ -731,24 +756,34 @@ static void pcnet_release(struct pcmcia_device *link) ======================================================================*/ -static int pcnet_suspend(struct pcmcia_device *link) +static int pcnet_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int pcnet_resume(struct pcmcia_device *link) +static int pcnet_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - pcnet_reset_8390(dev); - NS8390_init(dev, 1); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + pcnet_reset_8390(dev); + NS8390_init(dev, 1); + netif_device_attach(dev); + } } return 0; @@ -988,11 +1023,11 @@ static void mii_phy_probe(struct net_device *dev) static int pcnet_open(struct net_device *dev) { pcnet_dev_t *info = PRIV(dev); - struct pcmcia_device *link = info->p_dev; - + dev_link_t *link = &info->link; + DEBUG(2, "pcnet_open('%s')\n", dev->name); - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; link->open++; @@ -1016,7 +1051,7 @@ static int pcnet_open(struct net_device *dev) static int pcnet_close(struct net_device *dev) { pcnet_dev_t *info = PRIV(dev); - struct pcmcia_device *link = info->p_dev; + dev_link_t *link = &info->link; DEBUG(2, "pcnet_close('%s')\n", dev->name); @@ -1394,7 +1429,7 @@ static void dma_block_output(struct net_device *dev, int count, /*====================================================================*/ -static int setup_dma_config(struct pcmcia_device *link, int start_pg, +static int setup_dma_config(dev_link_t *link, int start_pg, int stop_pg) { struct net_device *dev = link->priv; @@ -1497,7 +1532,7 @@ static void shmem_block_output(struct net_device *dev, int count, /*====================================================================*/ -static int setup_shmem_window(struct pcmcia_device *link, int start_pg, +static int setup_shmem_window(dev_link_t *link, int start_pg, int stop_pg, int cm_offset) { struct net_device *dev = link->priv; @@ -1519,7 +1554,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, req.Attributes |= WIN_USE_WAIT; req.Base = 0; req.Size = window_size; req.AccessSpeed = mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); mem.CardOffset = (start_pg << 8) + cm_offset; offset = mem.CardOffset % window_size; @@ -1560,7 +1595,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, return 0; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: return 1; } @@ -1639,7 +1674,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722), PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd), - PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d), PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9), @@ -1693,7 +1727,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9), PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline + 10/100 Network PC Card (PCM100H1)", 0x733cc81, 0x7a3e5c3a), PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737), - PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TE", 0x88fcdeda, 0x0e714bee), PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922), PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0), PCMCIA_DEVICE_PROD_ID12("MACNICA", "ME1-JEIDA", 0x20841b68, 0xaf8a3578), diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index e74bf5014..0122415df 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include @@ -60,7 +59,7 @@ /*====================================================================*/ -static const char *if_names[] = { "auto", "10baseT", "10base2"}; +static char *if_names[] = { "auto", "10baseT", "10base2"}; /* Module parameters */ @@ -104,7 +103,7 @@ static const char *version = #define MEMORY_WAIT_TIME 8 struct smc_private { - struct pcmcia_device *p_dev; + dev_link_t link; spinlock_t lock; u_short manfid; u_short cardid; @@ -279,8 +278,8 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002, /*====================================================================*/ static void smc91c92_detach(struct pcmcia_device *p_dev); -static int smc91c92_config(struct pcmcia_device *link); -static void smc91c92_release(struct pcmcia_device *link); +static void smc91c92_config(dev_link_t *link); +static void smc91c92_release(dev_link_t *link); static int smc_open(struct net_device *dev); static int smc_close(struct net_device *dev); @@ -309,9 +308,10 @@ static struct ethtool_ops ethtool_ops; ======================================================================*/ -static int smc91c92_probe(struct pcmcia_device *link) +static int smc91c92_attach(struct pcmcia_device *p_dev) { struct smc_private *smc; + dev_link_t *link; struct net_device *dev; DEBUG(0, "smc91c92_attach()\n"); @@ -321,7 +321,7 @@ static int smc91c92_probe(struct pcmcia_device *link) if (!dev) return -ENOMEM; smc = netdev_priv(dev); - smc->p_dev = link; + link = &smc->link; link->priv = dev; spin_lock_init(&smc->lock); @@ -333,6 +333,7 @@ static int smc91c92_probe(struct pcmcia_device *link) link->irq.Handler = &smc_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; /* The SMC91c92-specific entries in the device structure. */ @@ -356,7 +357,13 @@ static int smc91c92_probe(struct pcmcia_device *link) smc->mii_if.phy_id_mask = 0x1f; smc->mii_if.reg_num_mask = 0x1f; - return smc91c92_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + smc91c92_config(link); + + return 0; } /* smc91c92_attach */ /*====================================================================== @@ -368,16 +375,18 @@ static int smc91c92_probe(struct pcmcia_device *link) ======================================================================*/ -static void smc91c92_detach(struct pcmcia_device *link) +static void smc91c92_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "smc91c92_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - smc91c92_release(link); + if (link->state & DEV_CONFIG) + smc91c92_release(link); free_netdev(dev); } /* smc91c92_detach */ @@ -405,7 +414,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s) /*====================================================================*/ -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -416,7 +425,7 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -438,7 +447,7 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, ======================================================================*/ -static int mhz_3288_power(struct pcmcia_device *link) +static int mhz_3288_power(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -460,7 +469,7 @@ static int mhz_3288_power(struct pcmcia_device *link) return 0; } -static int mhz_mfc_config(struct pcmcia_device *link) +static int mhz_mfc_config(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -495,7 +504,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) tuple->TupleDataMax = 255; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link, tuple, parse); + i = first_tuple(link->handle, tuple, parse); /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ while (i == CS_SUCCESS) { @@ -504,11 +513,11 @@ static int mhz_mfc_config(struct pcmcia_device *link) for (k = 0; k < 0x400; k += 0x10) { if (k & 0x80) continue; link->io.BasePort1 = k ^ 0x300; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i == CS_SUCCESS) break; - i = next_tuple(link, tuple, parse); + i = next_tuple(link->handle, tuple, parse); } if (i != CS_SUCCESS) goto free_cfg_mem; @@ -518,7 +527,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link, &req, &link->win); + i = pcmcia_request_window(&link->handle, &req, &link->win); if (i != CS_SUCCESS) goto free_cfg_mem; smc->base = ioremap(req.Base, req.Size); @@ -537,8 +546,9 @@ free_cfg_mem: return i; } -static int mhz_setup(struct pcmcia_device *link) +static int mhz_setup(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -561,13 +571,13 @@ static int mhz_setup(struct pcmcia_device *link) /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + if (first_tuple(handle, tuple, parse) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ - if (next_tuple(link, tuple, parse) != CS_SUCCESS) - first_tuple(link, tuple, parse); + if (next_tuple(handle, tuple, parse) != CS_SUCCESS) + first_tuple(handle, tuple, parse); if (parse->version_1.ns > 3) { station_addr = parse->version_1.str + parse->version_1.ofs[3]; if (cvt_ascii_address(dev, station_addr) == 0) { @@ -578,11 +588,11 @@ static int mhz_setup(struct pcmcia_device *link) /* Another possibility: for the EM3288, in a special tuple */ tuple->DesiredTuple = 0x81; - if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) { + if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } - if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) { + if (pcmcia_get_tuple_data(handle, tuple) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } @@ -606,7 +616,7 @@ free_cfg_mem: ======================================================================*/ -static void mot_config(struct pcmcia_device *link) +static void mot_config(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -627,7 +637,7 @@ static void mot_config(struct pcmcia_device *link) mdelay(100); } -static int mot_setup(struct pcmcia_device *link) +static int mot_setup(dev_link_t *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -661,7 +671,7 @@ static int mot_setup(struct pcmcia_device *link) /*====================================================================*/ -static int smc_config(struct pcmcia_device *link) +static int smc_config(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; @@ -686,16 +696,16 @@ static int smc_config(struct pcmcia_device *link) tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; link->io.NumPorts1 = 16; - i = first_tuple(link, tuple, parse); + i = first_tuple(link->handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i == CS_SUCCESS) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } - i = next_tuple(link, tuple, parse); + i = next_tuple(link->handle, tuple, parse); } if (i == CS_SUCCESS) dev->base_addr = link->io.BasePort1; @@ -704,8 +714,9 @@ static int smc_config(struct pcmcia_device *link) return i; } -static int smc_setup(struct pcmcia_device *link) +static int smc_setup(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -728,11 +739,11 @@ static int smc_setup(struct pcmcia_device *link) /* Check for a LAN function extension tuple */ tuple->DesiredTuple = CISTPL_FUNCE; - i = first_tuple(link, tuple, parse); + i = first_tuple(handle, tuple, parse); while (i == CS_SUCCESS) { if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID) break; - i = next_tuple(link, tuple, parse); + i = next_tuple(handle, tuple, parse); } if (i == CS_SUCCESS) { node_id = (cistpl_lan_node_id_t *)parse->funce.data; @@ -745,7 +756,7 @@ static int smc_setup(struct pcmcia_device *link) } /* Try the third string in the Version 1 Version/ID tuple. */ tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + if (first_tuple(handle, tuple, parse) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } @@ -763,10 +774,10 @@ free_cfg_mem: /*====================================================================*/ -static int osi_config(struct pcmcia_device *link) +static int osi_config(dev_link_t *link) { struct net_device *dev = link->priv; - static const kio_addr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; + static kio_addr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; int i, j; link->conf.Attributes |= CONF_ENABLE_SPKR; @@ -783,21 +794,22 @@ static int osi_config(struct pcmcia_device *link) for (i = j = 0; j < 4; j++) { link->io.BasePort2 = com[j]; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { /* Fallback: turn off hard decode */ link->conf.ConfigIndex = 0x03; link->io.NumPorts2 = 0; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); } dev->base_addr = link->io.BasePort1 + 0x10; return i; } -static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) +static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -818,12 +830,12 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) /* Read the station address from tuple 0x90, subtuple 0x04 */ tuple->DesiredTuple = 0x90; - i = pcmcia_get_first_tuple(link, tuple); + i = pcmcia_get_first_tuple(handle, tuple); while (i == CS_SUCCESS) { - i = pcmcia_get_tuple_data(link, tuple); + i = pcmcia_get_tuple_data(handle, tuple); if ((i != CS_SUCCESS) || (buf[0] == 0x04)) break; - i = pcmcia_get_next_tuple(link, tuple); + i = pcmcia_get_next_tuple(handle, tuple); } if (i != CS_SUCCESS) { rc = -1; @@ -856,46 +868,56 @@ free_cfg_mem: return rc; } -static int smc91c92_suspend(struct pcmcia_device *link) +static int smc91c92_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int smc91c92_resume(struct pcmcia_device *link) +static int smc91c92_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); int i; - if ((smc->manfid == MANFID_MEGAHERTZ) && - (smc->cardid == PRODID_MEGAHERTZ_EM3288)) - mhz_3288_power(link); - if (smc->manfid == MANFID_MOTOROLA) - mot_config(link); - if ((smc->manfid == MANFID_OSITECH) && - (smc->cardid != PRODID_OSITECH_SEVEN)) { - /* Power up the card and enable interrupts */ - set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR); - set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR); - } - if (((smc->manfid == MANFID_OSITECH) && - (smc->cardid == PRODID_OSITECH_SEVEN)) || - ((smc->manfid == MANFID_PSION) && - (smc->cardid == PRODID_PSION_NET100))) { - /* Download the Seven of Diamonds firmware */ - for (i = 0; i < sizeof(__Xilinx7OD); i++) { - outb(__Xilinx7OD[i], link->io.BasePort1+2); - udelay(50); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if ((smc->manfid == MANFID_MEGAHERTZ) && + (smc->cardid == PRODID_MEGAHERTZ_EM3288)) + mhz_3288_power(link); + pcmcia_request_configuration(link->handle, &link->conf); + if (smc->manfid == MANFID_MOTOROLA) + mot_config(link); + if ((smc->manfid == MANFID_OSITECH) && + (smc->cardid != PRODID_OSITECH_SEVEN)) { + /* Power up the card and enable interrupts */ + set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR); + set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR); + } + if (((smc->manfid == MANFID_OSITECH) && + (smc->cardid == PRODID_OSITECH_SEVEN)) || + ((smc->manfid == MANFID_PSION) && + (smc->cardid == PRODID_PSION_NET100))) { + /* Download the Seven of Diamonds firmware */ + for (i = 0; i < sizeof(__Xilinx7OD); i++) { + outb(__Xilinx7OD[i], link->io.BasePort1+2); + udelay(50); + } + } + if (link->open) { + smc_reset(dev); + netif_device_attach(dev); } - } - if (link->open) { - smc_reset(dev); - netif_device_attach(dev); } return 0; @@ -909,7 +931,7 @@ static int smc91c92_resume(struct pcmcia_device *link) ======================================================================*/ -static int check_sig(struct pcmcia_device *link) +static int check_sig(dev_link_t *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -942,15 +964,13 @@ static int check_sig(struct pcmcia_device *link) } if (width) { - modconf_t mod = { - .Attributes = CONF_IO_CHANGE_WIDTH, - }; - printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); - - smc91c92_suspend(link); - pcmcia_modify_configuration(link, &mod); - smc91c92_resume(link); - return check_sig(link); + printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); + smc91c92_suspend(link->handle); + pcmcia_release_io(link->handle, &link->io); + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + pcmcia_request_io(link->handle, &link->io); + smc91c92_resume(link->handle); + return check_sig(link); } return -ENODEV; } @@ -964,10 +984,11 @@ static int check_sig(struct pcmcia_device *link) ======================================================================*/ #define CS_EXIT_TEST(ret, svc, label) \ -if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; } +if (ret != CS_SUCCESS) { cs_error(link->handle, svc, ret); goto label; } -static int smc91c92_config(struct pcmcia_device *link) +static void smc91c92_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); struct smc_cfg_mem *cfg_mem; @@ -994,18 +1015,21 @@ static int smc91c92_config(struct pcmcia_device *link) tuple->TupleDataMax = 64; tuple->DesiredTuple = CISTPL_CONFIG; - i = first_tuple(link, tuple, parse); + i = first_tuple(handle, tuple, parse); CS_EXIT_TEST(i, ParseTuple, config_failed); link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; tuple->DesiredTuple = CISTPL_MANFID; tuple->Attributes = TUPLE_RETURN_COMMON; - if (first_tuple(link, tuple, parse) == CS_SUCCESS) { + if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { smc->manfid = parse->manfid.manf; smc->cardid = parse->manfid.card; } + /* Configure card */ + link->state |= DEV_CONFIG; + if ((smc->manfid == MANFID_OSITECH) && (smc->cardid != PRODID_OSITECH_SEVEN)) { i = osi_config(link); @@ -1019,9 +1043,9 @@ static int smc91c92_config(struct pcmcia_device *link) } CS_EXIT_TEST(i, RequestIO, config_failed); - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); CS_EXIT_TEST(i, RequestIRQ, config_failed); - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); CS_EXIT_TEST(i, RequestConfiguration, config_failed); if (smc->manfid == MANFID_MOTOROLA) @@ -1100,12 +1124,13 @@ static int smc91c92_config(struct pcmcia_device *link) SMC_SELECT_BANK(0); } - link->dev_node = &smc->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &smc->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if (register_netdev(dev) != 0) { printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto config_undo; } @@ -1135,14 +1160,15 @@ static int smc91c92_config(struct pcmcia_device *link) } } kfree(cfg_mem); - return 0; + return; config_undo: unregister_netdev(dev); config_failed: /* CS_EXIT_TEST() calls jump to here... */ smc91c92_release(link); + link->state &= ~DEV_CONFIG_PENDING; kfree(cfg_mem); - return -ENODEV; + } /* smc91c92_config */ /*====================================================================== @@ -1153,15 +1179,22 @@ config_failed: /* CS_EXIT_TEST() calls jump to here... */ ======================================================================*/ -static void smc91c92_release(struct pcmcia_device *link) +static void smc91c92_release(dev_link_t *link) { - DEBUG(0, "smc91c92_release(0x%p)\n", link); - if (link->win) { - struct net_device *dev = link->priv; - struct smc_private *smc = netdev_priv(dev); - iounmap(smc->base); - } - pcmcia_disable_device(link); + + DEBUG(0, "smc91c92_release(0x%p)\n", link); + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + if (link->win) { + struct net_device *dev = link->priv; + struct smc_private *smc = netdev_priv(dev); + iounmap(smc->base); + pcmcia_release_window(link->win); + } + + link->state &= ~DEV_CONFIG; } /*====================================================================== @@ -1250,7 +1283,7 @@ static void smc_dump(struct net_device *dev) static int smc_open(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - struct pcmcia_device *link = smc->p_dev; + dev_link_t *link = &smc->link; #ifdef PCMCIA_DEBUG DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n", @@ -1259,7 +1292,7 @@ static int smc_open(struct net_device *dev) #endif /* Check that the PCMCIA card is still here. */ - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; /* Physical device present signature. */ if (check_sig(link) < 0) { @@ -1287,7 +1320,7 @@ static int smc_open(struct net_device *dev) static int smc_close(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - struct pcmcia_device *link = smc->p_dev; + dev_link_t *link = &smc->link; kio_addr_t ioaddr = dev->base_addr; DEBUG(0, "%s: smc_close(), status %4.4x.\n", @@ -2278,7 +2311,7 @@ static struct pcmcia_driver smc91c92_cs_driver = { .drv = { .name = "smc91c92_cs", }, - .probe = smc91c92_probe, + .probe = smc91c92_attach, .remove = smc91c92_detach, .id_table = smc91c92_ids, .suspend = smc91c92_suspend, diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 71f45056a..14a523c44 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -208,7 +208,7 @@ enum xirc_cmd { /* Commands */ #define XIRCREG45_REV 15 /* Revision Register (rd) */ #define XIRCREG50_IA 8 /* Individual Address (8-13) */ -static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" }; +static char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" }; /**************** * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If @@ -289,9 +289,9 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, * and ejection events. They are invoked from the event handler. */ -static int has_ce2_string(struct pcmcia_device * link); -static int xirc2ps_config(struct pcmcia_device * link); -static void xirc2ps_release(struct pcmcia_device * link); +static int has_ce2_string(dev_link_t * link); +static void xirc2ps_config(dev_link_t * link); +static void xirc2ps_release(dev_link_t * link); /**************** * The attach() and detach() entry points are used to create and destroy @@ -313,10 +313,10 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs /**************** * A linked list of "instances" of the device. Each actual * PCMCIA card corresponds to one device instance, and is described - * by one struct pcmcia_device structure (defined in ds.h). + * by one dev_link_t structure (defined in ds.h). * * You may not want to use a linked list for this -- for example, the - * memory card driver uses an array of struct pcmcia_device pointers, where minor + * memory card driver uses an array of dev_link_t pointers, where minor * device numbers are used to derive the corresponding array index. */ @@ -326,13 +326,13 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs * example, ethernet cards, modems). In other cases, there may be * many actual or logical devices (SCSI adapters, memory cards with * multiple partitions). The dev_node_t structures need to be kept - * in a linked list starting at the 'dev' field of a struct pcmcia_device + * in a linked list starting at the 'dev' field of a dev_link_t * structure. We allocate them in the card's private data structure, * because they generally can't be allocated dynamically. */ typedef struct local_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct net_device_stats stats; int card_type; @@ -345,6 +345,7 @@ typedef struct local_info_t { void __iomem *dingo_ccr; /* only used for CEM56 cards */ unsigned last_ptr_value; /* last packets transmitted value */ const char *manf_str; + struct work_struct tx_timeout_task; } local_info_t; /**************** @@ -352,10 +353,11 @@ typedef struct local_info_t { */ static int do_start_xmit(struct sk_buff *skb, struct net_device *dev); static void do_tx_timeout(struct net_device *dev); +static void xirc2ps_tx_timeout_task(void *data); static struct net_device_stats *do_get_stats(struct net_device *dev); static void set_addresses(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int set_card_type(struct pcmcia_device *link, const void *s); +static int set_card_type(dev_link_t *link, const void *s); static int do_config(struct net_device *dev, struct ifmap *map); static int do_open(struct net_device *dev); static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -368,7 +370,7 @@ static int do_stop(struct net_device *dev); /*=============== Helper functions =========================*/ static int -first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int err; @@ -379,7 +381,7 @@ first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) } static int -next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int err; @@ -553,8 +555,9 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len) */ static int -xirc2ps_probe(struct pcmcia_device *link) +xirc2ps_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; struct net_device *dev; local_info_t *local; @@ -565,11 +568,12 @@ xirc2ps_probe(struct pcmcia_device *link) if (!dev) return -ENOMEM; local = netdev_priv(dev); - local->p_dev = link; + link = &local->link; link->priv = dev; /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -589,9 +593,16 @@ xirc2ps_probe(struct pcmcia_device *link) #ifdef HAVE_TX_TIMEOUT dev->tx_timeout = do_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; + INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task, dev); #endif - return xirc2ps_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + xirc2ps_config(link); + + return 0; } /* xirc2ps_attach */ /**************** @@ -602,16 +613,18 @@ xirc2ps_probe(struct pcmcia_device *link) */ static void -xirc2ps_detach(struct pcmcia_device *link) +xirc2ps_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - xirc2ps_release(link); + if (link->state & DEV_CONFIG) + xirc2ps_release(link); free_netdev(dev); } /* xirc2ps_detach */ @@ -635,7 +648,7 @@ xirc2ps_detach(struct pcmcia_device *link) * */ static int -set_card_type(struct pcmcia_device *link, const void *s) +set_card_type(dev_link_t *link, const void *s) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); @@ -704,8 +717,9 @@ set_card_type(struct pcmcia_device *link, const void *s) * Returns: true if this is a CE2 */ static int -has_ce2_string(struct pcmcia_device * link) +has_ce2_string(dev_link_t * link) { + client_handle_t handle = link->handle; tuple_t tuple; cisparse_t parse; u_char buf[256]; @@ -715,7 +729,7 @@ has_ce2_string(struct pcmcia_device * link) tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; - if (!first_tuple(link, &tuple, &parse) && parse.version_1.ns > 2) { + if (!first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 2) { if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2")) return 1; } @@ -727,9 +741,10 @@ has_ce2_string(struct pcmcia_device * link) * is received, to configure the PCMCIA socket, and to make the * ethernet device available to the system. */ -static int -xirc2ps_config(struct pcmcia_device * link) +static void +xirc2ps_config(dev_link_t * link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); tuple_t tuple; @@ -755,7 +770,7 @@ xirc2ps_config(struct pcmcia_device * link) /* Is this a valid card */ tuple.DesiredTuple = CISTPL_MANFID; - if ((err=first_tuple(link, &tuple, &parse))) { + if ((err=first_tuple(handle, &tuple, &parse))) { printk(KNOT_XIRC "manfid not found in CIS\n"); goto failure; } @@ -791,15 +806,15 @@ xirc2ps_config(struct pcmcia_device * link) /* get configuration stuff */ tuple.DesiredTuple = CISTPL_CONFIG; - if ((err=first_tuple(link, &tuple, &parse))) + if ((err=first_tuple(handle, &tuple, &parse))) goto cis_error; link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* get the ethernet address from the CIS */ tuple.DesiredTuple = CISTPL_FUNCE; - for (err = first_tuple(link, &tuple, &parse); !err; - err = next_tuple(link, &tuple, &parse)) { + for (err = first_tuple(handle, &tuple, &parse); !err; + err = next_tuple(handle, &tuple, &parse)) { /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries: * the first one with a length of zero the second correct - * so I skip all entries with length 0 */ @@ -809,8 +824,8 @@ xirc2ps_config(struct pcmcia_device * link) } if (err) { /* not found: try to get the node-id from tuple 0x89 */ tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */ - if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 && - (err = pcmcia_get_tuple_data(link, &tuple)) == 0) { + if ((err = pcmcia_get_first_tuple(handle, &tuple)) == 0 && + (err = pcmcia_get_tuple_data(handle, &tuple)) == 0) { if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID) memcpy(&parse, buf, 8); else @@ -819,8 +834,8 @@ xirc2ps_config(struct pcmcia_device * link) } if (err) { /* another try (James Lehmer's CE2 version 4.1)*/ tuple.DesiredTuple = CISTPL_FUNCE; - for (err = first_tuple(link, &tuple, &parse); !err; - err = next_tuple(link, &tuple, &parse)) { + for (err = first_tuple(handle, &tuple, &parse); !err; + err = next_tuple(handle, &tuple, &parse)) { if (parse.funce.type == 0x02 && parse.funce.data[0] == 1 && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) { buf[1] = 4; @@ -841,6 +856,9 @@ xirc2ps_config(struct pcmcia_device * link) for (i=0; i < 6; i++) dev->dev_addr[i] = node_id->id[i]; + /* Configure card */ + link->state |= DEV_CONFIG; + link->io.IOAddrLines =10; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->irq.Attributes = IRQ_HANDLE_PRESENT; @@ -860,14 +878,14 @@ xirc2ps_config(struct pcmcia_device * link) * Ethernet port */ link->io.NumPorts1 = 16; /* no Mako stuff anymore */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (err = first_tuple(link, &tuple, &parse); !err; - err = next_tuple(link, &tuple, &parse)) { + for (err = first_tuple(handle, &tuple, &parse); !err; + err = next_tuple(handle, &tuple, &parse)) { if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = ioaddr; - if (!(err=pcmcia_request_io(link, &link->io))) + if (!(err=pcmcia_request_io(link->handle, &link->io))) goto port_found; } } @@ -881,15 +899,15 @@ xirc2ps_config(struct pcmcia_device * link) */ for (pass=0; pass < 2; pass++) { tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (err = first_tuple(link, &tuple, &parse); !err; - err = next_tuple(link, &tuple, &parse)){ + for (err = first_tuple(handle, &tuple, &parse); !err; + err = next_tuple(handle, &tuple, &parse)){ if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){ link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = link->io.BasePort2 + (pass ? (cf->index & 0x20 ? -24:8) : (cf->index & 0x20 ? 8:-24)); - if (!(err=pcmcia_request_io(link, &link->io))) + if (!(err=pcmcia_request_io(link->handle, &link->io))) goto port_found; } } @@ -904,12 +922,12 @@ xirc2ps_config(struct pcmcia_device * link) link->io.NumPorts1 = 16; for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->io.BasePort1 = ioaddr; - if (!(err=pcmcia_request_io(link, &link->io))) + if (!(err=pcmcia_request_io(link->handle, &link->io))) goto port_found; } link->io.BasePort1 = 0; /* let CS decide */ - if ((err=pcmcia_request_io(link, &link->io))) { - cs_error(link, RequestIO, err); + if ((err=pcmcia_request_io(link->handle, &link->io))) { + cs_error(link->handle, RequestIO, err); goto config_error; } } @@ -921,8 +939,8 @@ xirc2ps_config(struct pcmcia_device * link) * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - if ((err=pcmcia_request_irq(link, &link->irq))) { - cs_error(link, RequestIRQ, err); + if ((err=pcmcia_request_irq(link->handle, &link->irq))) { + cs_error(link->handle, RequestIRQ, err); goto config_error; } @@ -930,8 +948,8 @@ xirc2ps_config(struct pcmcia_device * link) * This actually configures the PCMCIA socket -- setting up * the I/O windows and the interrupt mapping. */ - if ((err=pcmcia_request_configuration(link, &link->conf))) { - cs_error(link, RequestConfiguration, err); + if ((err=pcmcia_request_configuration(link->handle, &link->conf))) { + cs_error(link->handle, RequestConfiguration, err); goto config_error; } @@ -948,15 +966,15 @@ xirc2ps_config(struct pcmcia_device * link) reg.Action = CS_WRITE; reg.Offset = CISREG_IOBASE_0; reg.Value = link->io.BasePort2 & 0xff; - if ((err = pcmcia_access_configuration_register(link, ®))) { - cs_error(link, AccessConfigurationRegister, err); + if ((err = pcmcia_access_configuration_register(link->handle, ®))) { + cs_error(link->handle, AccessConfigurationRegister, err); goto config_error; } reg.Action = CS_WRITE; reg.Offset = CISREG_IOBASE_1; reg.Value = (link->io.BasePort2 >> 8) & 0xff; - if ((err = pcmcia_access_configuration_register(link, ®))) { - cs_error(link, AccessConfigurationRegister, err); + if ((err = pcmcia_access_configuration_register(link->handle, ®))) { + cs_error(link->handle, AccessConfigurationRegister, err); goto config_error; } @@ -967,15 +985,15 @@ xirc2ps_config(struct pcmcia_device * link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = 0; - if ((err = pcmcia_request_window(&link, &req, &link->win))) { - cs_error(link, RequestWindow, err); + if ((err = pcmcia_request_window(&link->handle, &req, &link->win))) { + cs_error(link->handle, RequestWindow, err); goto config_error; } local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800; mem.CardOffset = 0x0; mem.Page = 0; if ((err = pcmcia_map_mem_page(link->win, &mem))) { - cs_error(link, MapMemPage, err); + cs_error(link->handle, MapMemPage, err); goto config_error; } @@ -1035,12 +1053,13 @@ xirc2ps_config(struct pcmcia_device * link) if (local->dingo) do_reset(dev, 1); /* a kludge to make the cem56 work */ - link->dev_node = &local->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &local->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if ((err=register_netdev(dev))) { printk(KNOT_XIRC "register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto config_error; } @@ -1053,16 +1072,17 @@ xirc2ps_config(struct pcmcia_device * link) printk("%c%02X", i?':':' ', dev->dev_addr[i]); printk("\n"); - return 0; + return; config_error: + link->state &= ~DEV_CONFIG_PENDING; xirc2ps_release(link); - return -ENODEV; + return; cis_error: printk(KNOT_XIRC "unable to parse CIS\n"); failure: - return -ENODEV; + link->state &= ~DEV_CONFIG_PENDING; } /* xirc2ps_config */ /**************** @@ -1071,41 +1091,57 @@ xirc2ps_config(struct pcmcia_device * link) * still open, this will be postponed until it is closed. */ static void -xirc2ps_release(struct pcmcia_device *link) +xirc2ps_release(dev_link_t *link) { - DEBUG(0, "release(0x%p)\n", link); - if (link->win) { - struct net_device *dev = link->priv; - local_info_t *local = netdev_priv(dev); - if (local->dingo) - iounmap(local->dingo_ccr - 0x0800); - } - pcmcia_disable_device(link); + DEBUG(0, "release(0x%p)\n", link); + + if (link->win) { + struct net_device *dev = link->priv; + local_info_t *local = netdev_priv(dev); + if (local->dingo) + iounmap(local->dingo_ccr - 0x0800); + pcmcia_release_window(link->win); + } + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; + } /* xirc2ps_release */ /*====================================================================*/ -static int xirc2ps_suspend(struct pcmcia_device *link) +static int xirc2ps_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - netif_device_detach(dev); - do_powerdown(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) { + netif_device_detach(dev); + do_powerdown(dev); + } + pcmcia_release_configuration(link->handle); } return 0; } -static int xirc2ps_resume(struct pcmcia_device *link) +static int xirc2ps_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - do_reset(dev,1); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + do_reset(dev,1); + netif_device_attach(dev); + } } return 0; @@ -1341,17 +1377,24 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs) /*====================================================================*/ static void -do_tx_timeout(struct net_device *dev) +xirc2ps_tx_timeout_task(void *data) { - local_info_t *lp = netdev_priv(dev); - printk(KERN_NOTICE "%s: transmit timed out\n", dev->name); - lp->stats.tx_errors++; + struct net_device *dev = data; /* reset the card */ do_reset(dev,1); dev->trans_start = jiffies; netif_wake_queue(dev); } +static void +do_tx_timeout(struct net_device *dev) +{ + local_info_t *lp = netdev_priv(dev); + lp->stats.tx_errors++; + printk(KERN_NOTICE "%s: transmit timed out\n", dev->name); + schedule_work(&lp->tx_timeout_task); +} + static int do_start_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -1519,13 +1562,13 @@ static int do_open(struct net_device *dev) { local_info_t *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; DEBUG(0, "do_open(%p)\n", dev); /* Check that the PCMCIA card is still here. */ /* Physical device present signature. */ - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; /* okay */ @@ -1849,7 +1892,7 @@ do_stop(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; local_info_t *lp = netdev_priv(dev); - struct pcmcia_device *link = lp->p_dev; + dev_link_t *link = &lp->link; DEBUG(0, "do_stop(%p)\n", dev); @@ -1902,7 +1945,7 @@ static struct pcmcia_driver xirc2ps_cs_driver = { .drv = { .name = "xirc2ps_cs", }, - .probe = xirc2ps_probe, + .probe = xirc2ps_attach, .remove = xirc2ps_detach, .id_table = xirc2ps_ids, .suspend = xirc2ps_suspend, @@ -1940,7 +1983,7 @@ static int __init setup_xirc2ps_cs(char *str) MAYBE_SET(lockup_hack, 6); #undef MAYBE_SET - return 1; + return 0; } __setup("xirc2ps_cs=", setup_xirc2ps_cs); diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index fc08c4af5..8f6cf8c89 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -22,12 +22,12 @@ *************************************************************************/ #define DRV_NAME "pcnet32" -#define DRV_VERSION "1.32" -#define DRV_RELDATE "18.Mar.2006" +#define DRV_VERSION "1.31c" +#define DRV_RELDATE "01.Nov.2005" #define PFX DRV_NAME ": " -static const char *const version = - DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " tsbogend@alpha.franken.de\n"; +static const char *version = +DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " tsbogend@alpha.franken.de\n"; #include #include @@ -58,23 +58,18 @@ static const char *const version = * PCI device identifiers for "new style" Linux PCI Device Drivers */ static struct pci_device_id pcnet32_pci_tbl[] = { - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - - /* - * Adapters that were sold with IBM's RS/6000 or pSeries hardware have - * the incorrect vendor id. - */ - { PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_AMD_LANCE, - PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, 0}, - - { } /* terminate list */ + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + /* + * Adapters that were sold with IBM's RS/6000 or pSeries hardware have + * the incorrect vendor id. + */ + { PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_AMD_LANCE, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, 0 }, + { 0, } }; -MODULE_DEVICE_TABLE(pci, pcnet32_pci_tbl); +MODULE_DEVICE_TABLE (pci, pcnet32_pci_tbl); static int cards_found; @@ -82,11 +77,13 @@ static int cards_found; * VLB I/O addresses */ static unsigned int pcnet32_portlist[] __initdata = - { 0x300, 0x320, 0x340, 0x360, 0 }; + { 0x300, 0x320, 0x340, 0x360, 0 }; + + static int pcnet32_debug = 0; -static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */ -static int pcnet32vlb; /* check for VLB cards ? */ +static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */ +static int pcnet32vlb; /* check for VLB cards ? */ static struct net_device *pcnet32_dev; @@ -112,35 +109,33 @@ static int rx_copybreak = 200; * table to translate option values from tulip * to internal options */ -static const unsigned char options_mapping[] = { - PCNET32_PORT_ASEL, /* 0 Auto-select */ - PCNET32_PORT_AUI, /* 1 BNC/AUI */ - PCNET32_PORT_AUI, /* 2 AUI/BNC */ - PCNET32_PORT_ASEL, /* 3 not supported */ - PCNET32_PORT_10BT | PCNET32_PORT_FD, /* 4 10baseT-FD */ - PCNET32_PORT_ASEL, /* 5 not supported */ - PCNET32_PORT_ASEL, /* 6 not supported */ - PCNET32_PORT_ASEL, /* 7 not supported */ - PCNET32_PORT_ASEL, /* 8 not supported */ - PCNET32_PORT_MII, /* 9 MII 10baseT */ - PCNET32_PORT_MII | PCNET32_PORT_FD, /* 10 MII 10baseT-FD */ - PCNET32_PORT_MII, /* 11 MII (autosel) */ - PCNET32_PORT_10BT, /* 12 10BaseT */ - PCNET32_PORT_MII | PCNET32_PORT_100, /* 13 MII 100BaseTx */ - /* 14 MII 100BaseTx-FD */ - PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD, - PCNET32_PORT_ASEL /* 15 not supported */ +static unsigned char options_mapping[] = { + PCNET32_PORT_ASEL, /* 0 Auto-select */ + PCNET32_PORT_AUI, /* 1 BNC/AUI */ + PCNET32_PORT_AUI, /* 2 AUI/BNC */ + PCNET32_PORT_ASEL, /* 3 not supported */ + PCNET32_PORT_10BT | PCNET32_PORT_FD, /* 4 10baseT-FD */ + PCNET32_PORT_ASEL, /* 5 not supported */ + PCNET32_PORT_ASEL, /* 6 not supported */ + PCNET32_PORT_ASEL, /* 7 not supported */ + PCNET32_PORT_ASEL, /* 8 not supported */ + PCNET32_PORT_MII, /* 9 MII 10baseT */ + PCNET32_PORT_MII | PCNET32_PORT_FD, /* 10 MII 10baseT-FD */ + PCNET32_PORT_MII, /* 11 MII (autosel) */ + PCNET32_PORT_10BT, /* 12 10BaseT */ + PCNET32_PORT_MII | PCNET32_PORT_100, /* 13 MII 100BaseTx */ + PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD, /* 14 MII 100BaseTx-FD */ + PCNET32_PORT_ASEL /* 15 not supported */ }; static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = { - "Loopback test (offline)" + "Loopback test (offline)" }; - #define PCNET32_TEST_LEN (sizeof(pcnet32_gstrings_test) / ETH_GSTRING_LEN) -#define PCNET32_NUM_REGS 136 +#define PCNET32_NUM_REGS 168 -#define MAX_UNITS 8 /* More are supported, limit only on options */ +#define MAX_UNITS 8 /* More are supported, limit only on options */ static int options[MAX_UNITS]; static int full_duplex[MAX_UNITS]; static int homepna[MAX_UNITS]; @@ -155,6 +150,124 @@ static int homepna[MAX_UNITS]; * 16MB limitation and we don't need bounce buffers. */ +/* + * History: + * v0.01: Initial version + * only tested on Alpha Noname Board + * v0.02: changed IRQ handling for new interrupt scheme (dev_id) + * tested on a ASUS SP3G + * v0.10: fixed an odd problem with the 79C974 in a Compaq Deskpro XL + * looks like the 974 doesn't like stopping and restarting in a + * short period of time; now we do a reinit of the lance; the + * bug was triggered by doing ifconfig eth0 broadcast + * and hangs the machine (thanks to Klaus Liedl for debugging) + * v0.12: by suggestion from Donald Becker: Renamed driver to pcnet32, + * made it standalone (no need for lance.c) + * v0.13: added additional PCI detecting for special PCI devices (Compaq) + * v0.14: stripped down additional PCI probe (thanks to David C Niemi + * and sveneric@xs4all.nl for testing this on their Compaq boxes) + * v0.15: added 79C965 (VLB) probe + * added interrupt sharing for PCI chips + * v0.16: fixed set_multicast_list on Alpha machines + * v0.17: removed hack from dev.c; now pcnet32 uses ethif_probe in Space.c + * v0.19: changed setting of autoselect bit + * v0.20: removed additional Compaq PCI probe; there is now a working one + * in arch/i386/bios32.c + * v0.21: added endian conversion for ppc, from work by cort@cs.nmt.edu + * v0.22: added printing of status to ring dump + * v0.23: changed enet_statistics to net_devive_stats + * v0.90: added multicast filter + * added module support + * changed irq probe to new style + * added PCnetFast chip id + * added fix for receive stalls with Intel saturn chipsets + * added in-place rx skbs like in the tulip driver + * minor cleanups + * v0.91: added PCnetFast+ chip id + * back port to 2.0.x + * v1.00: added some stuff from Donald Becker's 2.0.34 version + * added support for byte counters in net_dev_stats + * v1.01: do ring dumps, only when debugging the driver + * increased the transmit timeout + * v1.02: fixed memory leak in pcnet32_init_ring() + * v1.10: workaround for stopped transmitter + * added port selection for modules + * detect special T1/E1 WAN card and setup port selection + * v1.11: fixed wrong checking of Tx errors + * v1.20: added check of return value kmalloc (cpeterso@cs.washington.edu) + * added save original kmalloc addr for freeing (mcr@solidum.com) + * added support for PCnetHome chip (joe@MIT.EDU) + * rewritten PCI card detection + * added dwio mode to get driver working on some PPC machines + * v1.21: added mii selection and mii ioctl + * v1.22: changed pci scanning code to make PPC people happy + * fixed switching to 32bit mode in pcnet32_open() (thanks + * to Michael Richard for noticing this one) + * added sub vendor/device id matching (thanks again to + * Michael Richard ) + * added chip id for 79c973/975 (thanks to Zach Brown ) + * v1.23 fixed small bug, when manual selecting MII speed/duplex + * v1.24 Applied Thomas' patch to use TxStartPoint and thus decrease TxFIFO + * underflows. Added tx_start_pt module parameter. Increased + * TX_RING_SIZE from 16 to 32. Added #ifdef'd code to use DXSUFLO + * for FAST[+] chipsets. + * v1.24ac Added SMP spinlocking - Alan Cox + * v1.25kf Added No Interrupt on successful Tx for some Tx's + * v1.26 Converted to pci_alloc_consistent, Jamey Hicks / George France + * + * - Fixed a few bugs, related to running the controller in 32bit mode. + * 23 Oct, 2000. Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * v1.26p Fix oops on rmmod+insmod; plug i/o resource leak - Paul Gortmaker + * v1.27 improved CSR/PROM address detection, lots of cleanups, + * new pcnet32vlb module option, HP-PARISC support, + * added module parameter descriptions, + * initial ethtool support - Helge Deller + * v1.27a Sun Feb 10 2002 Go Taniguchi + * use alloc_etherdev and register_netdev + * fix pci probe not increment cards_found + * FD auto negotiate error workaround for xSeries250 + * clean up and using new mii module + * v1.27b Sep 30 2002 Kent Yoder + * Added timer for cable connection state changes. + * v1.28 20 Feb 2004 Don Fry + * Jon Mason , Chinmay Albal + * Now uses ethtool_ops, netif_msg_* and generic_mii_ioctl. + * Fixes bogus 'Bus master arbitration failure', pci_[un]map_single + * length errors, and transmit hangs. Cleans up after errors in open. + * Jim Lewis added ethernet loopback test. + * Thomas Munck Steenholdt non-mii ioctl corrections. + * v1.29 6 Apr 2004 Jim Lewis added physical + * identification code (blink led's) and register dump. + * Don Fry added timer for 971/972 so skbufs don't remain on tx ring + * forever. + * v1.30 18 May 2004 Don Fry removed timer and Last Transmit Interrupt + * (ltint) as they added complexity and didn't give good throughput. + * v1.30a 22 May 2004 Don Fry limit frames received during interrupt. + * v1.30b 24 May 2004 Don Fry fix bogus tx carrier errors with 79c973, + * assisted by Bruce Penrod . + * v1.30c 25 May 2004 Don Fry added netif_wake_queue after pcnet32_restart. + * v1.30d 01 Jun 2004 Don Fry discard oversize rx packets. + * v1.30e 11 Jun 2004 Don Fry recover after fifo error and rx hang. + * v1.30f 16 Jun 2004 Don Fry cleanup IRQ to allow 0 and 1 for PCI, + * expanding on suggestions from Ralf Baechle , + * and Brian Murphy . + * v1.30g 22 Jun 2004 Patrick Simmons added option + * homepna for selecting HomePNA mode for PCNet/Home 79C978. + * v1.30h 24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32. + * v1.30i 28 Jun 2004 Don Fry change to use module_param. + * v1.30j 29 Apr 2005 Don Fry fix skb/map leak with loopback test. + * v1.31 02 Sep 2005 Hubert WS Lin added set_ringparam(). + * v1.31a 12 Sep 2005 Hubert WS Lin set min ring size to 4 + * to allow loopback test to work unchanged. + * v1.31b 06 Oct 2005 Don Fry changed alloc_ring to show name of device + * if allocation fails + * v1.31c 01 Nov 2005 Don Fry Allied Telesyn 2700/2701 FX are 100Mbit only. + * Force 100Mbit FD if Auto (ASEL) is selected. + * See Bugzilla 2669 and 4551. + */ + + /* * Set the number of Tx and Rx buffers, using Log_2(# buffers). * Reasonable default values are 4 Tx buffers, and 16 Rx buffers. @@ -190,42 +303,42 @@ static int homepna[MAX_UNITS]; /* The PCNET32 Rx and Tx ring descriptors. */ struct pcnet32_rx_head { - u32 base; - s16 buf_length; - s16 status; - u32 msg_length; - u32 reserved; + u32 base; + s16 buf_length; + s16 status; + u32 msg_length; + u32 reserved; }; struct pcnet32_tx_head { - u32 base; - s16 length; - s16 status; - u32 misc; - u32 reserved; + u32 base; + s16 length; + s16 status; + u32 misc; + u32 reserved; }; /* The PCNET32 32-Bit initialization block, described in databook. */ struct pcnet32_init_block { - u16 mode; - u16 tlen_rlen; - u8 phys_addr[6]; - u16 reserved; - u32 filter[2]; - /* Receive and transmit ring base, along with extra bits. */ - u32 rx_ring; - u32 tx_ring; + u16 mode; + u16 tlen_rlen; + u8 phys_addr[6]; + u16 reserved; + u32 filter[2]; + /* Receive and transmit ring base, along with extra bits. */ + u32 rx_ring; + u32 tx_ring; }; /* PCnet32 access functions */ struct pcnet32_access { - u16 (*read_csr) (unsigned long, int); - void (*write_csr) (unsigned long, int, u16); - u16 (*read_bcr) (unsigned long, int); - void (*write_bcr) (unsigned long, int, u16); - u16 (*read_rap) (unsigned long); - void (*write_rap) (unsigned long, u16); - void (*reset) (unsigned long); + u16 (*read_csr)(unsigned long, int); + void (*write_csr)(unsigned long, int, u16); + u16 (*read_bcr)(unsigned long, int); + void (*write_bcr)(unsigned long, int, u16); + u16 (*read_rap)(unsigned long); + void (*write_rap)(unsigned long, u16); + void (*reset)(unsigned long); }; /* @@ -233,794 +346,760 @@ struct pcnet32_access { * so the structure should be allocated using pci_alloc_consistent(). */ struct pcnet32_private { - struct pcnet32_init_block init_block; - /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */ - struct pcnet32_rx_head *rx_ring; - struct pcnet32_tx_head *tx_ring; - dma_addr_t dma_addr;/* DMA address of beginning of this - object, returned by pci_alloc_consistent */ - struct pci_dev *pci_dev; - const char *name; - /* The saved address of a sent-in-place packet/buffer, for skfree(). */ - struct sk_buff **tx_skbuff; - struct sk_buff **rx_skbuff; - dma_addr_t *tx_dma_addr; - dma_addr_t *rx_dma_addr; - struct pcnet32_access a; - spinlock_t lock; /* Guard lock */ - unsigned int cur_rx, cur_tx; /* The next free ring entry */ - unsigned int rx_ring_size; /* current rx ring size */ - unsigned int tx_ring_size; /* current tx ring size */ - unsigned int rx_mod_mask; /* rx ring modular mask */ - unsigned int tx_mod_mask; /* tx ring modular mask */ - unsigned short rx_len_bits; - unsigned short tx_len_bits; - dma_addr_t rx_ring_dma_addr; - dma_addr_t tx_ring_dma_addr; - unsigned int dirty_rx, /* ring entries to be freed. */ - dirty_tx; - - struct net_device_stats stats; - char tx_full; - char phycount; /* number of phys found */ - int options; - unsigned int shared_irq:1, /* shared irq possible */ - dxsuflo:1, /* disable transmit stop on uflo */ - mii:1; /* mii port available */ - struct net_device *next; - struct mii_if_info mii_if; - struct timer_list watchdog_timer; - struct timer_list blink_timer; - u32 msg_enable; /* debug message level */ - - /* each bit indicates an available PHY */ - u32 phymask; + struct pcnet32_init_block init_block; + /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */ + struct pcnet32_rx_head *rx_ring; + struct pcnet32_tx_head *tx_ring; + dma_addr_t dma_addr; /* DMA address of beginning of this + object, returned by + pci_alloc_consistent */ + struct pci_dev *pci_dev; /* Pointer to the associated pci device + structure */ + const char *name; + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ + struct sk_buff **tx_skbuff; + struct sk_buff **rx_skbuff; + dma_addr_t *tx_dma_addr; + dma_addr_t *rx_dma_addr; + struct pcnet32_access a; + spinlock_t lock; /* Guard lock */ + unsigned int cur_rx, cur_tx; /* The next free ring entry */ + unsigned int rx_ring_size; /* current rx ring size */ + unsigned int tx_ring_size; /* current tx ring size */ + unsigned int rx_mod_mask; /* rx ring modular mask */ + unsigned int tx_mod_mask; /* tx ring modular mask */ + unsigned short rx_len_bits; + unsigned short tx_len_bits; + dma_addr_t rx_ring_dma_addr; + dma_addr_t tx_ring_dma_addr; + unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ + struct net_device_stats stats; + char tx_full; + int options; + unsigned int shared_irq:1, /* shared irq possible */ + dxsuflo:1, /* disable transmit stop on uflo */ + mii:1; /* mii port available */ + struct net_device *next; + struct mii_if_info mii_if; + struct timer_list watchdog_timer; + struct timer_list blink_timer; + u32 msg_enable; /* debug message level */ }; static void pcnet32_probe_vlbus(void); -static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); -static int pcnet32_probe1(unsigned long, int, struct pci_dev *); -static int pcnet32_open(struct net_device *); -static int pcnet32_init_ring(struct net_device *); -static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); -static int pcnet32_rx(struct net_device *); -static void pcnet32_tx_timeout(struct net_device *dev); +static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); +static int pcnet32_probe1(unsigned long, int, struct pci_dev *); +static int pcnet32_open(struct net_device *); +static int pcnet32_init_ring(struct net_device *); +static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); +static int pcnet32_rx(struct net_device *); +static void pcnet32_tx_timeout (struct net_device *dev); static irqreturn_t pcnet32_interrupt(int, void *, struct pt_regs *); -static int pcnet32_close(struct net_device *); +static int pcnet32_close(struct net_device *); static struct net_device_stats *pcnet32_get_stats(struct net_device *); static void pcnet32_load_multicast(struct net_device *dev); static void pcnet32_set_multicast_list(struct net_device *); -static int pcnet32_ioctl(struct net_device *, struct ifreq *, int); +static int pcnet32_ioctl(struct net_device *, struct ifreq *, int); static void pcnet32_watchdog(struct net_device *); static int mdio_read(struct net_device *dev, int phy_id, int reg_num); -static void mdio_write(struct net_device *dev, int phy_id, int reg_num, - int val); +static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val); static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits); static void pcnet32_ethtool_test(struct net_device *dev, - struct ethtool_test *eth_test, u64 * data); -static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1); + struct ethtool_test *eth_test, u64 *data); +static int pcnet32_loopback_test(struct net_device *dev, uint64_t *data1); static int pcnet32_phys_id(struct net_device *dev, u32 data); static void pcnet32_led_blink_callback(struct net_device *dev); static int pcnet32_get_regs_len(struct net_device *dev); static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, - void *ptr); + void *ptr); static void pcnet32_purge_tx_ring(struct net_device *dev); static int pcnet32_alloc_ring(struct net_device *dev, char *name); static void pcnet32_free_ring(struct net_device *dev); -static void pcnet32_check_media(struct net_device *dev, int verbose); + enum pci_flags_bit { - PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, - PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2 = - 0x10 << 2, PCI_ADDR3 = 0x10 << 3, + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, }; -static u16 pcnet32_wio_read_csr(unsigned long addr, int index) + +static u16 pcnet32_wio_read_csr (unsigned long addr, int index) { - outw(index, addr + PCNET32_WIO_RAP); - return inw(addr + PCNET32_WIO_RDP); + outw (index, addr+PCNET32_WIO_RAP); + return inw (addr+PCNET32_WIO_RDP); } -static void pcnet32_wio_write_csr(unsigned long addr, int index, u16 val) +static void pcnet32_wio_write_csr (unsigned long addr, int index, u16 val) { - outw(index, addr + PCNET32_WIO_RAP); - outw(val, addr + PCNET32_WIO_RDP); + outw (index, addr+PCNET32_WIO_RAP); + outw (val, addr+PCNET32_WIO_RDP); } -static u16 pcnet32_wio_read_bcr(unsigned long addr, int index) +static u16 pcnet32_wio_read_bcr (unsigned long addr, int index) { - outw(index, addr + PCNET32_WIO_RAP); - return inw(addr + PCNET32_WIO_BDP); + outw (index, addr+PCNET32_WIO_RAP); + return inw (addr+PCNET32_WIO_BDP); } -static void pcnet32_wio_write_bcr(unsigned long addr, int index, u16 val) +static void pcnet32_wio_write_bcr (unsigned long addr, int index, u16 val) { - outw(index, addr + PCNET32_WIO_RAP); - outw(val, addr + PCNET32_WIO_BDP); + outw (index, addr+PCNET32_WIO_RAP); + outw (val, addr+PCNET32_WIO_BDP); } -static u16 pcnet32_wio_read_rap(unsigned long addr) +static u16 pcnet32_wio_read_rap (unsigned long addr) { - return inw(addr + PCNET32_WIO_RAP); + return inw (addr+PCNET32_WIO_RAP); } -static void pcnet32_wio_write_rap(unsigned long addr, u16 val) +static void pcnet32_wio_write_rap (unsigned long addr, u16 val) { - outw(val, addr + PCNET32_WIO_RAP); + outw (val, addr+PCNET32_WIO_RAP); } -static void pcnet32_wio_reset(unsigned long addr) +static void pcnet32_wio_reset (unsigned long addr) { - inw(addr + PCNET32_WIO_RESET); + inw (addr+PCNET32_WIO_RESET); } -static int pcnet32_wio_check(unsigned long addr) +static int pcnet32_wio_check (unsigned long addr) { - outw(88, addr + PCNET32_WIO_RAP); - return (inw(addr + PCNET32_WIO_RAP) == 88); + outw (88, addr+PCNET32_WIO_RAP); + return (inw (addr+PCNET32_WIO_RAP) == 88); } static struct pcnet32_access pcnet32_wio = { - .read_csr = pcnet32_wio_read_csr, - .write_csr = pcnet32_wio_write_csr, - .read_bcr = pcnet32_wio_read_bcr, - .write_bcr = pcnet32_wio_write_bcr, - .read_rap = pcnet32_wio_read_rap, - .write_rap = pcnet32_wio_write_rap, - .reset = pcnet32_wio_reset + .read_csr = pcnet32_wio_read_csr, + .write_csr = pcnet32_wio_write_csr, + .read_bcr = pcnet32_wio_read_bcr, + .write_bcr = pcnet32_wio_write_bcr, + .read_rap = pcnet32_wio_read_rap, + .write_rap = pcnet32_wio_write_rap, + .reset = pcnet32_wio_reset }; -static u16 pcnet32_dwio_read_csr(unsigned long addr, int index) +static u16 pcnet32_dwio_read_csr (unsigned long addr, int index) { - outl(index, addr + PCNET32_DWIO_RAP); - return (inl(addr + PCNET32_DWIO_RDP) & 0xffff); + outl (index, addr+PCNET32_DWIO_RAP); + return (inl (addr+PCNET32_DWIO_RDP) & 0xffff); } -static void pcnet32_dwio_write_csr(unsigned long addr, int index, u16 val) +static void pcnet32_dwio_write_csr (unsigned long addr, int index, u16 val) { - outl(index, addr + PCNET32_DWIO_RAP); - outl(val, addr + PCNET32_DWIO_RDP); + outl (index, addr+PCNET32_DWIO_RAP); + outl (val, addr+PCNET32_DWIO_RDP); } -static u16 pcnet32_dwio_read_bcr(unsigned long addr, int index) +static u16 pcnet32_dwio_read_bcr (unsigned long addr, int index) { - outl(index, addr + PCNET32_DWIO_RAP); - return (inl(addr + PCNET32_DWIO_BDP) & 0xffff); + outl (index, addr+PCNET32_DWIO_RAP); + return (inl (addr+PCNET32_DWIO_BDP) & 0xffff); } -static void pcnet32_dwio_write_bcr(unsigned long addr, int index, u16 val) +static void pcnet32_dwio_write_bcr (unsigned long addr, int index, u16 val) { - outl(index, addr + PCNET32_DWIO_RAP); - outl(val, addr + PCNET32_DWIO_BDP); + outl (index, addr+PCNET32_DWIO_RAP); + outl (val, addr+PCNET32_DWIO_BDP); } -static u16 pcnet32_dwio_read_rap(unsigned long addr) +static u16 pcnet32_dwio_read_rap (unsigned long addr) { - return (inl(addr + PCNET32_DWIO_RAP) & 0xffff); + return (inl (addr+PCNET32_DWIO_RAP) & 0xffff); } -static void pcnet32_dwio_write_rap(unsigned long addr, u16 val) +static void pcnet32_dwio_write_rap (unsigned long addr, u16 val) { - outl(val, addr + PCNET32_DWIO_RAP); + outl (val, addr+PCNET32_DWIO_RAP); } -static void pcnet32_dwio_reset(unsigned long addr) +static void pcnet32_dwio_reset (unsigned long addr) { - inl(addr + PCNET32_DWIO_RESET); + inl (addr+PCNET32_DWIO_RESET); } -static int pcnet32_dwio_check(unsigned long addr) +static int pcnet32_dwio_check (unsigned long addr) { - outl(88, addr + PCNET32_DWIO_RAP); - return ((inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88); + outl (88, addr+PCNET32_DWIO_RAP); + return ((inl (addr+PCNET32_DWIO_RAP) & 0xffff) == 88); } static struct pcnet32_access pcnet32_dwio = { - .read_csr = pcnet32_dwio_read_csr, - .write_csr = pcnet32_dwio_write_csr, - .read_bcr = pcnet32_dwio_read_bcr, - .write_bcr = pcnet32_dwio_write_bcr, - .read_rap = pcnet32_dwio_read_rap, - .write_rap = pcnet32_dwio_write_rap, - .reset = pcnet32_dwio_reset + .read_csr = pcnet32_dwio_read_csr, + .write_csr = pcnet32_dwio_write_csr, + .read_bcr = pcnet32_dwio_read_bcr, + .write_bcr = pcnet32_dwio_write_bcr, + .read_rap = pcnet32_dwio_read_rap, + .write_rap = pcnet32_dwio_write_rap, + .reset = pcnet32_dwio_reset }; #ifdef CONFIG_NET_POLL_CONTROLLER static void pcnet32_poll_controller(struct net_device *dev) { - disable_irq(dev->irq); - pcnet32_interrupt(0, dev, NULL); - enable_irq(dev->irq); + disable_irq(dev->irq); + pcnet32_interrupt(0, dev, NULL); + enable_irq(dev->irq); } #endif + static int pcnet32_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct pcnet32_private *lp = dev->priv; - unsigned long flags; - int r = -EOPNOTSUPP; - - if (lp->mii) { - spin_lock_irqsave(&lp->lock, flags); - mii_ethtool_gset(&lp->mii_if, cmd); - spin_unlock_irqrestore(&lp->lock, flags); - r = 0; - } - return r; + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int r = -EOPNOTSUPP; + + if (lp->mii) { + spin_lock_irqsave(&lp->lock, flags); + mii_ethtool_gset(&lp->mii_if, cmd); + spin_unlock_irqrestore(&lp->lock, flags); + r = 0; + } + return r; } static int pcnet32_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct pcnet32_private *lp = dev->priv; - unsigned long flags; - int r = -EOPNOTSUPP; + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int r = -EOPNOTSUPP; - if (lp->mii) { - spin_lock_irqsave(&lp->lock, flags); - r = mii_ethtool_sset(&lp->mii_if, cmd); - spin_unlock_irqrestore(&lp->lock, flags); - } - return r; + if (lp->mii) { + spin_lock_irqsave(&lp->lock, flags); + r = mii_ethtool_sset(&lp->mii_if, cmd); + spin_unlock_irqrestore(&lp->lock, flags); + } + return r; } -static void pcnet32_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) +static void pcnet32_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct pcnet32_private *lp = dev->priv; - - strcpy(info->driver, DRV_NAME); - strcpy(info->version, DRV_VERSION); - if (lp->pci_dev) - strcpy(info->bus_info, pci_name(lp->pci_dev)); - else - sprintf(info->bus_info, "VLB 0x%lx", dev->base_addr); + struct pcnet32_private *lp = dev->priv; + + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + if (lp->pci_dev) + strcpy (info->bus_info, pci_name(lp->pci_dev)); + else + sprintf(info->bus_info, "VLB 0x%lx", dev->base_addr); } static u32 pcnet32_get_link(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - unsigned long flags; - int r; - - spin_lock_irqsave(&lp->lock, flags); - if (lp->mii) { - r = mii_link_ok(&lp->mii_if); - } else { - ulong ioaddr = dev->base_addr; /* card base I/O address */ - r = (lp->a.read_bcr(ioaddr, 4) != 0xc0); - } - spin_unlock_irqrestore(&lp->lock, flags); + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int r; + + spin_lock_irqsave(&lp->lock, flags); + if (lp->mii) { + r = mii_link_ok(&lp->mii_if); + } else { + ulong ioaddr = dev->base_addr; /* card base I/O address */ + r = (lp->a.read_bcr(ioaddr, 4) != 0xc0); + } + spin_unlock_irqrestore(&lp->lock, flags); - return r; + return r; } static u32 pcnet32_get_msglevel(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - return lp->msg_enable; + struct pcnet32_private *lp = dev->priv; + return lp->msg_enable; } static void pcnet32_set_msglevel(struct net_device *dev, u32 value) { - struct pcnet32_private *lp = dev->priv; - lp->msg_enable = value; + struct pcnet32_private *lp = dev->priv; + lp->msg_enable = value; } static int pcnet32_nway_reset(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - unsigned long flags; - int r = -EOPNOTSUPP; + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int r = -EOPNOTSUPP; - if (lp->mii) { - spin_lock_irqsave(&lp->lock, flags); - r = mii_nway_restart(&lp->mii_if); - spin_unlock_irqrestore(&lp->lock, flags); - } - return r; + if (lp->mii) { + spin_lock_irqsave(&lp->lock, flags); + r = mii_nway_restart(&lp->mii_if); + spin_unlock_irqrestore(&lp->lock, flags); + } + return r; } -static void pcnet32_get_ringparam(struct net_device *dev, - struct ethtool_ringparam *ering) +static void pcnet32_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { - struct pcnet32_private *lp = dev->priv; + struct pcnet32_private *lp = dev->priv; - ering->tx_max_pending = TX_MAX_RING_SIZE - 1; - ering->tx_pending = lp->tx_ring_size - 1; - ering->rx_max_pending = RX_MAX_RING_SIZE - 1; - ering->rx_pending = lp->rx_ring_size - 1; + ering->tx_max_pending = TX_MAX_RING_SIZE - 1; + ering->tx_pending = lp->tx_ring_size - 1; + ering->rx_max_pending = RX_MAX_RING_SIZE - 1; + ering->rx_pending = lp->rx_ring_size - 1; } -static int pcnet32_set_ringparam(struct net_device *dev, - struct ethtool_ringparam *ering) +static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { - struct pcnet32_private *lp = dev->priv; - unsigned long flags; - int i; - - if (ering->rx_mini_pending || ering->rx_jumbo_pending) - return -EINVAL; - - if (netif_running(dev)) - pcnet32_close(dev); - - spin_lock_irqsave(&lp->lock, flags); + struct pcnet32_private *lp = dev->priv; + unsigned long flags; + int i; + + if (ering->rx_mini_pending || ering->rx_jumbo_pending) + return -EINVAL; + + if (netif_running(dev)) + pcnet32_close(dev); + + spin_lock_irqsave(&lp->lock, flags); + pcnet32_free_ring(dev); + lp->tx_ring_size = min(ering->tx_pending, (unsigned int) TX_MAX_RING_SIZE); + lp->rx_ring_size = min(ering->rx_pending, (unsigned int) RX_MAX_RING_SIZE); + + /* set the minimum ring size to 4, to allow the loopback test to work + * unchanged. + */ + for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) { + if (lp->tx_ring_size <= (1 << i)) + break; + } + lp->tx_ring_size = (1 << i); + lp->tx_mod_mask = lp->tx_ring_size - 1; + lp->tx_len_bits = (i << 12); + + for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) { + if (lp->rx_ring_size <= (1 << i)) + break; + } + lp->rx_ring_size = (1 << i); + lp->rx_mod_mask = lp->rx_ring_size - 1; + lp->rx_len_bits = (i << 4); + + if (pcnet32_alloc_ring(dev, dev->name)) { pcnet32_free_ring(dev); - lp->tx_ring_size = - min(ering->tx_pending, (unsigned int)TX_MAX_RING_SIZE); - lp->rx_ring_size = - min(ering->rx_pending, (unsigned int)RX_MAX_RING_SIZE); - - /* set the minimum ring size to 4, to allow the loopback test to work - * unchanged. - */ - for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) { - if (lp->tx_ring_size <= (1 << i)) - break; - } - lp->tx_ring_size = (1 << i); - lp->tx_mod_mask = lp->tx_ring_size - 1; - lp->tx_len_bits = (i << 12); - - for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) { - if (lp->rx_ring_size <= (1 << i)) - break; - } - lp->rx_ring_size = (1 << i); - lp->rx_mod_mask = lp->rx_ring_size - 1; - lp->rx_len_bits = (i << 4); - - if (pcnet32_alloc_ring(dev, dev->name)) { - pcnet32_free_ring(dev); - spin_unlock_irqrestore(&lp->lock, flags); - return -ENOMEM; - } - spin_unlock_irqrestore(&lp->lock, flags); + return -ENOMEM; + } - if (pcnet32_debug & NETIF_MSG_DRV) - printk(KERN_INFO PFX - "%s: Ring Param Settings: RX: %d, TX: %d\n", dev->name, - lp->rx_ring_size, lp->tx_ring_size); + spin_unlock_irqrestore(&lp->lock, flags); - if (netif_running(dev)) - pcnet32_open(dev); + if (pcnet32_debug & NETIF_MSG_DRV) + printk(KERN_INFO PFX "%s: Ring Param Settings: RX: %d, TX: %d\n", + dev->name, lp->rx_ring_size, lp->tx_ring_size); - return 0; + if (netif_running(dev)) + pcnet32_open(dev); + + return 0; } -static void pcnet32_get_strings(struct net_device *dev, u32 stringset, - u8 * data) +static void pcnet32_get_strings(struct net_device *dev, u32 stringset, u8 *data) { - memcpy(data, pcnet32_gstrings_test, sizeof(pcnet32_gstrings_test)); + memcpy(data, pcnet32_gstrings_test, sizeof(pcnet32_gstrings_test)); } static int pcnet32_self_test_count(struct net_device *dev) { - return PCNET32_TEST_LEN; + return PCNET32_TEST_LEN; } static void pcnet32_ethtool_test(struct net_device *dev, - struct ethtool_test *test, u64 * data) + struct ethtool_test *test, u64 *data) { - struct pcnet32_private *lp = dev->priv; - int rc; - - if (test->flags == ETH_TEST_FL_OFFLINE) { - rc = pcnet32_loopback_test(dev, data); - if (rc) { - if (netif_msg_hw(lp)) - printk(KERN_DEBUG "%s: Loopback test failed.\n", - dev->name); - test->flags |= ETH_TEST_FL_FAILED; - } else if (netif_msg_hw(lp)) - printk(KERN_DEBUG "%s: Loopback test passed.\n", - dev->name); + struct pcnet32_private *lp = dev->priv; + int rc; + + if (test->flags == ETH_TEST_FL_OFFLINE) { + rc = pcnet32_loopback_test(dev, data); + if (rc) { + if (netif_msg_hw(lp)) + printk(KERN_DEBUG "%s: Loopback test failed.\n", dev->name); + test->flags |= ETH_TEST_FL_FAILED; } else if (netif_msg_hw(lp)) - printk(KERN_DEBUG - "%s: No tests to run (specify 'Offline' on ethtool).", - dev->name); -} /* end pcnet32_ethtool_test */ + printk(KERN_DEBUG "%s: Loopback test passed.\n", dev->name); + } else if (netif_msg_hw(lp)) + printk(KERN_DEBUG "%s: No tests to run (specify 'Offline' on ethtool).", dev->name); +} /* end pcnet32_ethtool_test */ -static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) +static int pcnet32_loopback_test(struct net_device *dev, uint64_t *data1) { - struct pcnet32_private *lp = dev->priv; - struct pcnet32_access *a = &lp->a; /* access to registers */ - ulong ioaddr = dev->base_addr; /* card base I/O address */ - struct sk_buff *skb; /* sk buff */ - int x, i; /* counters */ - int numbuffs = 4; /* number of TX/RX buffers and descs */ - u16 status = 0x8300; /* TX ring status */ - u16 teststatus; /* test of ring status */ - int rc; /* return code */ - int size; /* size of packets */ - unsigned char *packet; /* source packet data */ - static const int data_len = 60; /* length of source packets */ - unsigned long flags; - unsigned long ticks; - - *data1 = 1; /* status of test, default to fail */ - rc = 1; /* default to fail */ - - if (netif_running(dev)) - pcnet32_close(dev); - - spin_lock_irqsave(&lp->lock, flags); - - /* Reset the PCNET32 */ - lp->a.reset(ioaddr); - - /* switch pcnet32 to 32bit mode */ - lp->a.write_bcr(ioaddr, 20, 2); - - lp->init_block.mode = - le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); - lp->init_block.filter[0] = 0; - lp->init_block.filter[1] = 0; - - /* purge & init rings but don't actually restart */ - pcnet32_restart(dev, 0x0000); - - lp->a.write_csr(ioaddr, 0, 0x0004); /* Set STOP bit */ - - /* Initialize Transmit buffers. */ - size = data_len + 15; - for (x = 0; x < numbuffs; x++) { - if (!(skb = dev_alloc_skb(size))) { - if (netif_msg_hw(lp)) - printk(KERN_DEBUG - "%s: Cannot allocate skb at line: %d!\n", - dev->name, __LINE__); - goto clean_up; - } else { - packet = skb->data; - skb_put(skb, size); /* create space for data */ - lp->tx_skbuff[x] = skb; - lp->tx_ring[x].length = le16_to_cpu(-skb->len); - lp->tx_ring[x].misc = 0; - - /* put DA and SA into the skb */ - for (i = 0; i < 6; i++) - *packet++ = dev->dev_addr[i]; - for (i = 0; i < 6; i++) - *packet++ = dev->dev_addr[i]; - /* type */ - *packet++ = 0x08; - *packet++ = 0x06; - /* packet number */ - *packet++ = x; - /* fill packet with data */ - for (i = 0; i < data_len; i++) - *packet++ = i; - - lp->tx_dma_addr[x] = - pci_map_single(lp->pci_dev, skb->data, skb->len, - PCI_DMA_TODEVICE); - lp->tx_ring[x].base = - (u32) le32_to_cpu(lp->tx_dma_addr[x]); - wmb(); /* Make sure owner changes after all others are visible */ - lp->tx_ring[x].status = le16_to_cpu(status); - } - } - - x = a->read_bcr(ioaddr, 32); /* set internal loopback in BSR32 */ - x = x | 0x0002; - a->write_bcr(ioaddr, 32, x); - - lp->a.write_csr(ioaddr, 15, 0x0044); /* set int loopback in CSR15 */ - - teststatus = le16_to_cpu(0x8000); - lp->a.write_csr(ioaddr, 0, 0x0002); /* Set STRT bit */ - - /* Check status of descriptors */ - for (x = 0; x < numbuffs; x++) { - ticks = 0; - rmb(); - while ((lp->rx_ring[x].status & teststatus) && (ticks < 200)) { - spin_unlock_irqrestore(&lp->lock, flags); - mdelay(1); - spin_lock_irqsave(&lp->lock, flags); - rmb(); - ticks++; - } - if (ticks == 200) { - if (netif_msg_hw(lp)) - printk("%s: Desc %d failed to reset!\n", - dev->name, x); - break; - } - } - - lp->a.write_csr(ioaddr, 0, 0x0004); /* Set STOP bit */ - wmb(); - if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) { - printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name); - - for (x = 0; x < numbuffs; x++) { - printk(KERN_DEBUG "%s: Packet %d:\n", dev->name, x); - skb = lp->rx_skbuff[x]; - for (i = 0; i < size; i++) { - printk("%02x ", *(skb->data + i)); - } - printk("\n"); - } - } - - x = 0; - rc = 0; - while (x < numbuffs && !rc) { - skb = lp->rx_skbuff[x]; - packet = lp->tx_skbuff[x]->data; - for (i = 0; i < size; i++) { - if (*(skb->data + i) != packet[i]) { - if (netif_msg_hw(lp)) - printk(KERN_DEBUG - "%s: Error in compare! %2x - %02x %02x\n", - dev->name, i, *(skb->data + i), - packet[i]); - rc = 1; - break; - } - } - x++; - } - if (!rc) { - *data1 = 0; + struct pcnet32_private *lp = dev->priv; + struct pcnet32_access *a = &lp->a; /* access to registers */ + ulong ioaddr = dev->base_addr; /* card base I/O address */ + struct sk_buff *skb; /* sk buff */ + int x, i; /* counters */ + int numbuffs = 4; /* number of TX/RX buffers and descs */ + u16 status = 0x8300; /* TX ring status */ + u16 teststatus; /* test of ring status */ + int rc; /* return code */ + int size; /* size of packets */ + unsigned char *packet; /* source packet data */ + static int data_len = 60; /* length of source packets */ + unsigned long flags; + unsigned long ticks; + + *data1 = 1; /* status of test, default to fail */ + rc = 1; /* default to fail */ + + if (netif_running(dev)) + pcnet32_close(dev); + + spin_lock_irqsave(&lp->lock, flags); + + /* Reset the PCNET32 */ + lp->a.reset (ioaddr); + + /* switch pcnet32 to 32bit mode */ + lp->a.write_bcr (ioaddr, 20, 2); + + lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); + lp->init_block.filter[0] = 0; + lp->init_block.filter[1] = 0; + + /* purge & init rings but don't actually restart */ + pcnet32_restart(dev, 0x0000); + + lp->a.write_csr(ioaddr, 0, 0x0004); /* Set STOP bit */ + + /* Initialize Transmit buffers. */ + size = data_len + 15; + for (x=0; xname, __LINE__); + goto clean_up; + } else { + packet = skb->data; + skb_put(skb, size); /* create space for data */ + lp->tx_skbuff[x] = skb; + lp->tx_ring[x].length = le16_to_cpu(-skb->len); + lp->tx_ring[x].misc = 0; + + /* put DA and SA into the skb */ + for (i=0; i<6; i++) + *packet++ = dev->dev_addr[i]; + for (i=0; i<6; i++) + *packet++ = dev->dev_addr[i]; + /* type */ + *packet++ = 0x08; + *packet++ = 0x06; + /* packet number */ + *packet++ = x; + /* fill packet with data */ + for (i=0; itx_dma_addr[x] = pci_map_single(lp->pci_dev, skb->data, + skb->len, PCI_DMA_TODEVICE); + lp->tx_ring[x].base = (u32)le32_to_cpu(lp->tx_dma_addr[x]); + wmb(); /* Make sure owner changes after all others are visible */ + lp->tx_ring[x].status = le16_to_cpu(status); + } + } + + x = a->read_bcr(ioaddr, 32); /* set internal loopback in BSR32 */ + x = x | 0x0002; + a->write_bcr(ioaddr, 32, x); + + lp->a.write_csr (ioaddr, 15, 0x0044); /* set int loopback in CSR15 */ + + teststatus = le16_to_cpu(0x8000); + lp->a.write_csr(ioaddr, 0, 0x0002); /* Set STRT bit */ + + /* Check status of descriptors */ + for (x=0; xrx_ring[x].status & teststatus) && (ticks < 200)) { + spin_unlock_irqrestore(&lp->lock, flags); + mdelay(1); + spin_lock_irqsave(&lp->lock, flags); + rmb(); + ticks++; + } + if (ticks == 200) { + if (netif_msg_hw(lp)) + printk("%s: Desc %d failed to reset!\n",dev->name,x); + break; + } + } + + lp->a.write_csr(ioaddr, 0, 0x0004); /* Set STOP bit */ + wmb(); + if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) { + printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name); + + for (x=0; xname, x); + skb = lp->rx_skbuff[x]; + for (i=0; idata+i)); + } + printk("\n"); + } + } + + x = 0; + rc = 0; + while (xrx_skbuff[x]; + packet = lp->tx_skbuff[x]->data; + for (i=0; idata+i) != packet[i]) { + if (netif_msg_hw(lp)) + printk(KERN_DEBUG "%s: Error in compare! %2x - %02x %02x\n", + dev->name, i, *(skb->data+i), packet[i]); + rc = 1; + break; + } } + x++; + } + if (!rc) { + *data1 = 0; + } - clean_up: - pcnet32_purge_tx_ring(dev); - x = a->read_csr(ioaddr, 15) & 0xFFFF; - a->write_csr(ioaddr, 15, (x & ~0x0044)); /* reset bits 6 and 2 */ +clean_up: + pcnet32_purge_tx_ring(dev); + x = a->read_csr(ioaddr, 15) & 0xFFFF; + a->write_csr(ioaddr, 15, (x & ~0x0044)); /* reset bits 6 and 2 */ - x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ - x = x & ~0x0002; - a->write_bcr(ioaddr, 32, x); + x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ + x = x & ~0x0002; + a->write_bcr(ioaddr, 32, x); - spin_unlock_irqrestore(&lp->lock, flags); + spin_unlock_irqrestore(&lp->lock, flags); - if (netif_running(dev)) { - pcnet32_open(dev); - } else { - lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ - } + if (netif_running(dev)) { + pcnet32_open(dev); + } else { + lp->a.write_bcr (ioaddr, 20, 4); /* return to 16bit mode */ + } - return (rc); -} /* end pcnet32_loopback_test */ + return(rc); +} /* end pcnet32_loopback_test */ static void pcnet32_led_blink_callback(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - struct pcnet32_access *a = &lp->a; - ulong ioaddr = dev->base_addr; - unsigned long flags; - int i; - - spin_lock_irqsave(&lp->lock, flags); - for (i = 4; i < 8; i++) { - a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000); - } - spin_unlock_irqrestore(&lp->lock, flags); - - mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT); + struct pcnet32_private *lp = dev->priv; + struct pcnet32_access *a = &lp->a; + ulong ioaddr = dev->base_addr; + unsigned long flags; + int i; + + spin_lock_irqsave(&lp->lock, flags); + for (i=4; i<8; i++) { + a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000); + } + spin_unlock_irqrestore(&lp->lock, flags); + + mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT); } static int pcnet32_phys_id(struct net_device *dev, u32 data) { - struct pcnet32_private *lp = dev->priv; - struct pcnet32_access *a = &lp->a; - ulong ioaddr = dev->base_addr; - unsigned long flags; - int i, regs[4]; - - if (!lp->blink_timer.function) { - init_timer(&lp->blink_timer); - lp->blink_timer.function = (void *)pcnet32_led_blink_callback; - lp->blink_timer.data = (unsigned long)dev; - } - - /* Save the current value of the bcrs */ - spin_lock_irqsave(&lp->lock, flags); - for (i = 4; i < 8; i++) { - regs[i - 4] = a->read_bcr(ioaddr, i); - } - spin_unlock_irqrestore(&lp->lock, flags); - - mod_timer(&lp->blink_timer, jiffies); - set_current_state(TASK_INTERRUPTIBLE); - - if ((!data) || (data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))) - data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ); - - msleep_interruptible(data * 1000); - del_timer_sync(&lp->blink_timer); - - /* Restore the original value of the bcrs */ - spin_lock_irqsave(&lp->lock, flags); - for (i = 4; i < 8; i++) { - a->write_bcr(ioaddr, i, regs[i - 4]); - } - spin_unlock_irqrestore(&lp->lock, flags); - - return 0; + struct pcnet32_private *lp = dev->priv; + struct pcnet32_access *a = &lp->a; + ulong ioaddr = dev->base_addr; + unsigned long flags; + int i, regs[4]; + + if (!lp->blink_timer.function) { + init_timer(&lp->blink_timer); + lp->blink_timer.function = (void *) pcnet32_led_blink_callback; + lp->blink_timer.data = (unsigned long) dev; + } + + /* Save the current value of the bcrs */ + spin_lock_irqsave(&lp->lock, flags); + for (i=4; i<8; i++) { + regs[i-4] = a->read_bcr(ioaddr, i); + } + spin_unlock_irqrestore(&lp->lock, flags); + + mod_timer(&lp->blink_timer, jiffies); + set_current_state(TASK_INTERRUPTIBLE); + + if ((!data) || (data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))) + data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); + + msleep_interruptible(data * 1000); + del_timer_sync(&lp->blink_timer); + + /* Restore the original value of the bcrs */ + spin_lock_irqsave(&lp->lock, flags); + for (i=4; i<8; i++) { + a->write_bcr(ioaddr, i, regs[i-4]); + } + spin_unlock_irqrestore(&lp->lock, flags); + + return 0; } -#define PCNET32_REGS_PER_PHY 32 -#define PCNET32_MAX_PHYS 32 static int pcnet32_get_regs_len(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - int j = lp->phycount * PCNET32_REGS_PER_PHY; - - return ((PCNET32_NUM_REGS + j) * sizeof(u16)); + return(PCNET32_NUM_REGS * sizeof(u16)); } static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, - void *ptr) + void *ptr) { - int i, csr0; - u16 *buff = ptr; - struct pcnet32_private *lp = dev->priv; - struct pcnet32_access *a = &lp->a; - ulong ioaddr = dev->base_addr; - int ticks; - unsigned long flags; - - spin_lock_irqsave(&lp->lock, flags); - - csr0 = a->read_csr(ioaddr, 0); - if (!(csr0 & 0x0004)) { /* If not stopped */ - /* set SUSPEND (SPND) - CSR5 bit 0 */ - a->write_csr(ioaddr, 5, 0x0001); - - /* poll waiting for bit to be set */ - ticks = 0; - while (!(a->read_csr(ioaddr, 5) & 0x0001)) { - spin_unlock_irqrestore(&lp->lock, flags); - mdelay(1); - spin_lock_irqsave(&lp->lock, flags); - ticks++; - if (ticks > 200) { - if (netif_msg_hw(lp)) - printk(KERN_DEBUG - "%s: Error getting into suspend!\n", - dev->name); - break; - } - } + int i, csr0; + u16 *buff = ptr; + struct pcnet32_private *lp = dev->priv; + struct pcnet32_access *a = &lp->a; + ulong ioaddr = dev->base_addr; + int ticks; + unsigned long flags; + + spin_lock_irqsave(&lp->lock, flags); + + csr0 = a->read_csr(ioaddr, 0); + if (!(csr0 & 0x0004)) { /* If not stopped */ + /* set SUSPEND (SPND) - CSR5 bit 0 */ + a->write_csr(ioaddr, 5, 0x0001); + + /* poll waiting for bit to be set */ + ticks = 0; + while (!(a->read_csr(ioaddr, 5) & 0x0001)) { + spin_unlock_irqrestore(&lp->lock, flags); + mdelay(1); + spin_lock_irqsave(&lp->lock, flags); + ticks++; + if (ticks > 200) { + if (netif_msg_hw(lp)) + printk(KERN_DEBUG "%s: Error getting into suspend!\n", + dev->name); + break; + } } + } - /* read address PROM */ - for (i = 0; i < 16; i += 2) - *buff++ = inw(ioaddr + i); + /* read address PROM */ + for (i=0; i<16; i += 2) + *buff++ = inw(ioaddr + i); - /* read control and status registers */ - for (i = 0; i < 90; i++) { - *buff++ = a->read_csr(ioaddr, i); - } + /* read control and status registers */ + for (i=0; i<90; i++) { + *buff++ = a->read_csr(ioaddr, i); + } - *buff++ = a->read_csr(ioaddr, 112); - *buff++ = a->read_csr(ioaddr, 114); + *buff++ = a->read_csr(ioaddr, 112); + *buff++ = a->read_csr(ioaddr, 114); - /* read bus configuration registers */ - for (i = 0; i < 30; i++) { - *buff++ = a->read_bcr(ioaddr, i); - } - *buff++ = 0; /* skip bcr30 so as not to hang 79C976 */ - for (i = 31; i < 36; i++) { - *buff++ = a->read_bcr(ioaddr, i); - } + /* read bus configuration registers */ + for (i=0; i<30; i++) { + *buff++ = a->read_bcr(ioaddr, i); + } + *buff++ = 0; /* skip bcr30 so as not to hang 79C976 */ + for (i=31; i<36; i++) { + *buff++ = a->read_bcr(ioaddr, i); + } - /* read mii phy registers */ - if (lp->mii) { - int j; - for (j = 0; j < PCNET32_MAX_PHYS; j++) { - if (lp->phymask & (1 << j)) { - for (i = 0; i < PCNET32_REGS_PER_PHY; i++) { - lp->a.write_bcr(ioaddr, 33, - (j << 5) | i); - *buff++ = lp->a.read_bcr(ioaddr, 34); - } - } - } + /* read mii phy registers */ + if (lp->mii) { + for (i=0; i<32; i++) { + lp->a.write_bcr(ioaddr, 33, ((lp->mii_if.phy_id) << 5) | i); + *buff++ = lp->a.read_bcr(ioaddr, 34); } + } - if (!(csr0 & 0x0004)) { /* If not stopped */ - /* clear SUSPEND (SPND) - CSR5 bit 0 */ - a->write_csr(ioaddr, 5, 0x0000); - } + if (!(csr0 & 0x0004)) { /* If not stopped */ + /* clear SUSPEND (SPND) - CSR5 bit 0 */ + a->write_csr(ioaddr, 5, 0x0000); + } - spin_unlock_irqrestore(&lp->lock, flags); + i = buff - (u16 *)ptr; + for (; i < PCNET32_NUM_REGS; i++) + *buff++ = 0; + + spin_unlock_irqrestore(&lp->lock, flags); } static struct ethtool_ops pcnet32_ethtool_ops = { - .get_settings = pcnet32_get_settings, - .set_settings = pcnet32_set_settings, - .get_drvinfo = pcnet32_get_drvinfo, - .get_msglevel = pcnet32_get_msglevel, - .set_msglevel = pcnet32_set_msglevel, - .nway_reset = pcnet32_nway_reset, - .get_link = pcnet32_get_link, - .get_ringparam = pcnet32_get_ringparam, - .set_ringparam = pcnet32_set_ringparam, - .get_tx_csum = ethtool_op_get_tx_csum, - .get_sg = ethtool_op_get_sg, - .get_tso = ethtool_op_get_tso, - .get_strings = pcnet32_get_strings, - .self_test_count = pcnet32_self_test_count, - .self_test = pcnet32_ethtool_test, - .phys_id = pcnet32_phys_id, - .get_regs_len = pcnet32_get_regs_len, - .get_regs = pcnet32_get_regs, - .get_perm_addr = ethtool_op_get_perm_addr, + .get_settings = pcnet32_get_settings, + .set_settings = pcnet32_set_settings, + .get_drvinfo = pcnet32_get_drvinfo, + .get_msglevel = pcnet32_get_msglevel, + .set_msglevel = pcnet32_set_msglevel, + .nway_reset = pcnet32_nway_reset, + .get_link = pcnet32_get_link, + .get_ringparam = pcnet32_get_ringparam, + .set_ringparam = pcnet32_set_ringparam, + .get_tx_csum = ethtool_op_get_tx_csum, + .get_sg = ethtool_op_get_sg, + .get_tso = ethtool_op_get_tso, + .get_strings = pcnet32_get_strings, + .self_test_count = pcnet32_self_test_count, + .self_test = pcnet32_ethtool_test, + .phys_id = pcnet32_phys_id, + .get_regs_len = pcnet32_get_regs_len, + .get_regs = pcnet32_get_regs, + .get_perm_addr = ethtool_op_get_perm_addr, }; /* only probes for non-PCI devices, the rest are handled by * pci_register_driver via pcnet32_probe_pci */ -static void __devinit pcnet32_probe_vlbus(void) +static void __devinit +pcnet32_probe_vlbus(void) { - unsigned int *port, ioaddr; - - /* search for PCnet32 VLB cards at known addresses */ - for (port = pcnet32_portlist; (ioaddr = *port); port++) { - if (request_region - (ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_vlbus")) { - /* check if there is really a pcnet chip on that ioaddr */ - if ((inb(ioaddr + 14) == 0x57) - && (inb(ioaddr + 15) == 0x57)) { - pcnet32_probe1(ioaddr, 0, NULL); - } else { - release_region(ioaddr, PCNET32_TOTAL_SIZE); - } - } - } + unsigned int *port, ioaddr; + + /* search for PCnet32 VLB cards at known addresses */ + for (port = pcnet32_portlist; (ioaddr = *port); port++) { + if (request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_vlbus")) { + /* check if there is really a pcnet chip on that ioaddr */ + if ((inb(ioaddr + 14) == 0x57) && (inb(ioaddr + 15) == 0x57)) { + pcnet32_probe1(ioaddr, 0, NULL); + } else { + release_region(ioaddr, PCNET32_TOTAL_SIZE); + } + } + } } + static int __devinit pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent) { - unsigned long ioaddr; - int err; - - err = pci_enable_device(pdev); - if (err < 0) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_ERR PFX - "failed to enable device -- err=%d\n", err); - return err; - } - pci_set_master(pdev); - - ioaddr = pci_resource_start(pdev, 0); - if (!ioaddr) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_ERR PFX - "card has no PCI IO resources, aborting\n"); - return -ENODEV; - } - - if (!pci_dma_supported(pdev, PCNET32_DMA_MASK)) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_ERR PFX - "architecture does not support 32bit PCI busmaster DMA\n"); - return -ENODEV; - } - if (request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci") == - NULL) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_ERR PFX - "io address range already allocated\n"); - return -EBUSY; - } + unsigned long ioaddr; + int err; - err = pcnet32_probe1(ioaddr, 1, pdev); - if (err < 0) { - pci_disable_device(pdev); - } + err = pci_enable_device(pdev); + if (err < 0) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_ERR PFX "failed to enable device -- err=%d\n", err); return err; + } + pci_set_master(pdev); + + ioaddr = pci_resource_start (pdev, 0); + if (!ioaddr) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk (KERN_ERR PFX "card has no PCI IO resources, aborting\n"); + return -ENODEV; + } + + if (!pci_dma_supported(pdev, PCNET32_DMA_MASK)) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_ERR PFX "architecture does not support 32bit PCI busmaster DMA\n"); + return -ENODEV; + } + if (request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci") == NULL) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_ERR PFX "io address range already allocated\n"); + return -EBUSY; + } + + err = pcnet32_probe1(ioaddr, 1, pdev); + if (err < 0) { + pci_disable_device(pdev); + } + return err; } + /* pcnet32_probe1 * Called from both pcnet32_probe_vlbus and pcnet_probe_pci. * pdev will be NULL when called from pcnet32_probe_vlbus. @@ -1028,762 +1107,630 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent) static int __devinit pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) { - struct pcnet32_private *lp; - dma_addr_t lp_dma_addr; - int i, media; - int fdx, mii, fset, dxsuflo; - int chip_version; - char *chipname; - struct net_device *dev; - struct pcnet32_access *a = NULL; - u8 promaddr[6]; - int ret = -ENODEV; - - /* reset the chip */ - pcnet32_wio_reset(ioaddr); - - /* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */ - if (pcnet32_wio_read_csr(ioaddr, 0) == 4 && pcnet32_wio_check(ioaddr)) { - a = &pcnet32_wio; - } else { - pcnet32_dwio_reset(ioaddr); - if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 - && pcnet32_dwio_check(ioaddr)) { - a = &pcnet32_dwio; - } else - goto err_release_region; - } - - chip_version = - a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16); - if ((pcnet32_debug & NETIF_MSG_PROBE) && (pcnet32_debug & NETIF_MSG_HW)) - printk(KERN_INFO " PCnet chip version is %#x.\n", - chip_version); - if ((chip_version & 0xfff) != 0x003) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_INFO PFX "Unsupported chip version.\n"); - goto err_release_region; - } - - /* initialize variables */ - fdx = mii = fset = dxsuflo = 0; - chip_version = (chip_version >> 12) & 0xffff; - - switch (chip_version) { - case 0x2420: - chipname = "PCnet/PCI 79C970"; /* PCI */ - break; - case 0x2430: - if (shared) - chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */ - else - chipname = "PCnet/32 79C965"; /* 486/VL bus */ - break; - case 0x2621: - chipname = "PCnet/PCI II 79C970A"; /* PCI */ - fdx = 1; - break; - case 0x2623: - chipname = "PCnet/FAST 79C971"; /* PCI */ - fdx = 1; - mii = 1; - fset = 1; - break; - case 0x2624: - chipname = "PCnet/FAST+ 79C972"; /* PCI */ - fdx = 1; - mii = 1; - fset = 1; - break; - case 0x2625: - chipname = "PCnet/FAST III 79C973"; /* PCI */ - fdx = 1; - mii = 1; - break; - case 0x2626: - chipname = "PCnet/Home 79C978"; /* PCI */ - fdx = 1; - /* - * This is based on specs published at www.amd.com. This section - * assumes that a card with a 79C978 wants to go into standard - * ethernet mode. The 79C978 can also go into 1Mb HomePNA mode, - * and the module option homepna=1 can select this instead. - */ - media = a->read_bcr(ioaddr, 49); - media &= ~3; /* default to 10Mb ethernet */ - if (cards_found < MAX_UNITS && homepna[cards_found]) - media |= 1; /* switch to home wiring mode */ - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_DEBUG PFX "media set to %sMbit mode.\n", - (media & 1) ? "1" : "10"); - a->write_bcr(ioaddr, 49, media); - break; - case 0x2627: - chipname = "PCnet/FAST III 79C975"; /* PCI */ - fdx = 1; - mii = 1; - break; - case 0x2628: - chipname = "PCnet/PRO 79C976"; - fdx = 1; - mii = 1; - break; - default: - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_INFO PFX - "PCnet version %#x, no PCnet32 chip.\n", - chip_version); - goto err_release_region; - } - + struct pcnet32_private *lp; + dma_addr_t lp_dma_addr; + int i, media; + int fdx, mii, fset, dxsuflo; + int chip_version; + char *chipname; + struct net_device *dev; + struct pcnet32_access *a = NULL; + u8 promaddr[6]; + int ret = -ENODEV; + + /* reset the chip */ + pcnet32_wio_reset(ioaddr); + + /* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */ + if (pcnet32_wio_read_csr(ioaddr, 0) == 4 && pcnet32_wio_check(ioaddr)) { + a = &pcnet32_wio; + } else { + pcnet32_dwio_reset(ioaddr); + if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) { + a = &pcnet32_dwio; + } else + goto err_release_region; + } + + chip_version = a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr,89) << 16); + if ((pcnet32_debug & NETIF_MSG_PROBE) && (pcnet32_debug & NETIF_MSG_HW)) + printk(KERN_INFO " PCnet chip version is %#x.\n", chip_version); + if ((chip_version & 0xfff) != 0x003) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_INFO PFX "Unsupported chip version.\n"); + goto err_release_region; + } + + /* initialize variables */ + fdx = mii = fset = dxsuflo = 0; + chip_version = (chip_version >> 12) & 0xffff; + + switch (chip_version) { + case 0x2420: + chipname = "PCnet/PCI 79C970"; /* PCI */ + break; + case 0x2430: + if (shared) + chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */ + else + chipname = "PCnet/32 79C965"; /* 486/VL bus */ + break; + case 0x2621: + chipname = "PCnet/PCI II 79C970A"; /* PCI */ + fdx = 1; + break; + case 0x2623: + chipname = "PCnet/FAST 79C971"; /* PCI */ + fdx = 1; mii = 1; fset = 1; + break; + case 0x2624: + chipname = "PCnet/FAST+ 79C972"; /* PCI */ + fdx = 1; mii = 1; fset = 1; + break; + case 0x2625: + chipname = "PCnet/FAST III 79C973"; /* PCI */ + fdx = 1; mii = 1; + break; + case 0x2626: + chipname = "PCnet/Home 79C978"; /* PCI */ + fdx = 1; /* - * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit - * starting until the packet is loaded. Strike one for reliability, lose - * one for latency - although on PCI this isnt a big loss. Older chips - * have FIFO's smaller than a packet, so you can't do this. - * Turn on BCR18:BurstRdEn and BCR18:BurstWrEn. + * This is based on specs published at www.amd.com. This section + * assumes that a card with a 79C978 wants to go into standard + * ethernet mode. The 79C978 can also go into 1Mb HomePNA mode, + * and the module option homepna=1 can select this instead. */ - - if (fset) { - a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0860)); - a->write_csr(ioaddr, 80, - (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); - dxsuflo = 1; - } - - dev = alloc_etherdev(0); - if (!dev) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_ERR PFX "Memory allocation failed.\n"); - ret = -ENOMEM; - goto err_release_region; - } - SET_NETDEV_DEV(dev, &pdev->dev); - + media = a->read_bcr(ioaddr, 49); + media &= ~3; /* default to 10Mb ethernet */ + if (cards_found < MAX_UNITS && homepna[cards_found]) + media |= 1; /* switch to home wiring mode */ if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_INFO PFX "%s at %#3lx,", chipname, ioaddr); - - /* In most chips, after a chip reset, the ethernet address is read from the - * station address PROM at the base address and programmed into the - * "Physical Address Registers" CSR12-14. - * As a precautionary measure, we read the PROM values and complain if - * they disagree with the CSRs. If they miscompare, and the PROM addr - * is valid, then the PROM addr is used. - */ - for (i = 0; i < 3; i++) { - unsigned int val; - val = a->read_csr(ioaddr, i + 12) & 0x0ffff; - /* There may be endianness issues here. */ - dev->dev_addr[2 * i] = val & 0x0ff; - dev->dev_addr[2 * i + 1] = (val >> 8) & 0x0ff; - } - - /* read PROM address and compare with CSR address */ + printk(KERN_DEBUG PFX "media set to %sMbit mode.\n", + (media & 1) ? "1" : "10"); + a->write_bcr(ioaddr, 49, media); + break; + case 0x2627: + chipname = "PCnet/FAST III 79C975"; /* PCI */ + fdx = 1; mii = 1; + break; + case 0x2628: + chipname = "PCnet/PRO 79C976"; + fdx = 1; mii = 1; + break; + default: + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_INFO PFX "PCnet version %#x, no PCnet32 chip.\n", + chip_version); + goto err_release_region; + } + + /* + * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit + * starting until the packet is loaded. Strike one for reliability, lose + * one for latency - although on PCI this isnt a big loss. Older chips + * have FIFO's smaller than a packet, so you can't do this. + * Turn on BCR18:BurstRdEn and BCR18:BurstWrEn. + */ + + if (fset) { + a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0860)); + a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); + dxsuflo = 1; + } + + dev = alloc_etherdev(0); + if (!dev) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_ERR PFX "Memory allocation failed.\n"); + ret = -ENOMEM; + goto err_release_region; + } + SET_NETDEV_DEV(dev, &pdev->dev); + + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_INFO PFX "%s at %#3lx,", chipname, ioaddr); + + /* In most chips, after a chip reset, the ethernet address is read from the + * station address PROM at the base address and programmed into the + * "Physical Address Registers" CSR12-14. + * As a precautionary measure, we read the PROM values and complain if + * they disagree with the CSRs. Either way, we use the CSR values, and + * double check that they are valid. + */ + for (i = 0; i < 3; i++) { + unsigned int val; + val = a->read_csr(ioaddr, i+12) & 0x0ffff; + /* There may be endianness issues here. */ + dev->dev_addr[2*i] = val & 0x0ff; + dev->dev_addr[2*i+1] = (val >> 8) & 0x0ff; + } + + /* read PROM address and compare with CSR address */ + for (i = 0; i < 6; i++) + promaddr[i] = inb(ioaddr + i); + + if (memcmp(promaddr, dev->dev_addr, 6) + || !is_valid_ether_addr(dev->dev_addr)) { + if (is_valid_ether_addr(promaddr)) { + if (pcnet32_debug & NETIF_MSG_PROBE) { + printk(" warning: CSR address invalid,\n"); + printk(KERN_INFO " using instead PROM address of"); + } + memcpy(dev->dev_addr, promaddr, 6); + } + } + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); + + /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ + if (!is_valid_ether_addr(dev->perm_addr)) + memset(dev->dev_addr, 0, sizeof(dev->dev_addr)); + + if (pcnet32_debug & NETIF_MSG_PROBE) { for (i = 0; i < 6; i++) - promaddr[i] = inb(ioaddr + i); - - if (memcmp(promaddr, dev->dev_addr, 6) - || !is_valid_ether_addr(dev->dev_addr)) { - if (is_valid_ether_addr(promaddr)) { - if (pcnet32_debug & NETIF_MSG_PROBE) { - printk(" warning: CSR address invalid,\n"); - printk(KERN_INFO - " using instead PROM address of"); - } - memcpy(dev->dev_addr, promaddr, 6); - } - } - memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - - /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ - if (!is_valid_ether_addr(dev->perm_addr)) - memset(dev->dev_addr, 0, sizeof(dev->dev_addr)); - - if (pcnet32_debug & NETIF_MSG_PROBE) { - for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i]); - - /* Version 0x2623 and 0x2624 */ - if (((chip_version + 1) & 0xfffe) == 0x2624) { - i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */ - printk("\n" KERN_INFO " tx_start_pt(0x%04x):", i); - switch (i >> 10) { - case 0: - printk(" 20 bytes,"); - break; - case 1: - printk(" 64 bytes,"); - break; - case 2: - printk(" 128 bytes,"); - break; - case 3: - printk("~220 bytes,"); - break; - } - i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */ - printk(" BCR18(%x):", i & 0xffff); - if (i & (1 << 5)) - printk("BurstWrEn "); - if (i & (1 << 6)) - printk("BurstRdEn "); - if (i & (1 << 7)) - printk("DWordIO "); - if (i & (1 << 11)) - printk("NoUFlow "); - i = a->read_bcr(ioaddr, 25); - printk("\n" KERN_INFO " SRAMSIZE=0x%04x,", i << 8); - i = a->read_bcr(ioaddr, 26); - printk(" SRAM_BND=0x%04x,", i << 8); - i = a->read_bcr(ioaddr, 27); - if (i & (1 << 14)) - printk("LowLatRx"); - } - } - - dev->base_addr = ioaddr; - /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ - if ((lp = - pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_ERR PFX - "Consistent memory allocation failed.\n"); - ret = -ENOMEM; - goto err_free_netdev; - } - - memset(lp, 0, sizeof(*lp)); - lp->dma_addr = lp_dma_addr; - lp->pci_dev = pdev; - - spin_lock_init(&lp->lock); - - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &pdev->dev); - dev->priv = lp; - lp->name = chipname; - lp->shared_irq = shared; - lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */ - lp->rx_ring_size = RX_RING_SIZE; /* default rx ring size */ - lp->tx_mod_mask = lp->tx_ring_size - 1; - lp->rx_mod_mask = lp->rx_ring_size - 1; - lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12); - lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4); - lp->mii_if.full_duplex = fdx; - lp->mii_if.phy_id_mask = 0x1f; - lp->mii_if.reg_num_mask = 0x1f; - lp->dxsuflo = dxsuflo; - lp->mii = mii; - lp->msg_enable = pcnet32_debug; - if ((cards_found >= MAX_UNITS) - || (options[cards_found] > sizeof(options_mapping))) - lp->options = PCNET32_PORT_ASEL; - else - lp->options = options_mapping[options[cards_found]]; - lp->mii_if.dev = dev; - lp->mii_if.mdio_read = mdio_read; - lp->mii_if.mdio_write = mdio_write; - - if (fdx && !(lp->options & PCNET32_PORT_ASEL) && - ((cards_found >= MAX_UNITS) || full_duplex[cards_found])) - lp->options |= PCNET32_PORT_FD; - - if (!a) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_ERR PFX "No access methods\n"); - ret = -ENODEV; - goto err_free_consistent; - } - lp->a = *a; - - /* prior to register_netdev, dev->name is not yet correct */ - if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) { - ret = -ENOMEM; - goto err_free_ring; - } - /* detect special T1/E1 WAN card by checking for MAC address */ - if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 + printk(" %2.2x", dev->dev_addr[i]); + + /* Version 0x2623 and 0x2624 */ + if (((chip_version + 1) & 0xfffe) == 0x2624) { + i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */ + printk("\n" KERN_INFO " tx_start_pt(0x%04x):",i); + switch(i>>10) { + case 0: printk(" 20 bytes,"); break; + case 1: printk(" 64 bytes,"); break; + case 2: printk(" 128 bytes,"); break; + case 3: printk("~220 bytes,"); break; + } + i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */ + printk(" BCR18(%x):",i&0xffff); + if (i & (1<<5)) printk("BurstWrEn "); + if (i & (1<<6)) printk("BurstRdEn "); + if (i & (1<<7)) printk("DWordIO "); + if (i & (1<<11)) printk("NoUFlow "); + i = a->read_bcr(ioaddr, 25); + printk("\n" KERN_INFO " SRAMSIZE=0x%04x,",i<<8); + i = a->read_bcr(ioaddr, 26); + printk(" SRAM_BND=0x%04x,",i<<8); + i = a->read_bcr(ioaddr, 27); + if (i & (1<<14)) printk("LowLatRx"); + } + } + + dev->base_addr = ioaddr; + /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ + if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_ERR PFX "Consistent memory allocation failed.\n"); + ret = -ENOMEM; + goto err_free_netdev; + } + + memset(lp, 0, sizeof(*lp)); + lp->dma_addr = lp_dma_addr; + lp->pci_dev = pdev; + + spin_lock_init(&lp->lock); + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); + dev->priv = lp; + lp->name = chipname; + lp->shared_irq = shared; + lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */ + lp->rx_ring_size = RX_RING_SIZE; /* default rx ring size */ + lp->tx_mod_mask = lp->tx_ring_size - 1; + lp->rx_mod_mask = lp->rx_ring_size - 1; + lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12); + lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4); + lp->mii_if.full_duplex = fdx; + lp->mii_if.phy_id_mask = 0x1f; + lp->mii_if.reg_num_mask = 0x1f; + lp->dxsuflo = dxsuflo; + lp->mii = mii; + lp->msg_enable = pcnet32_debug; + if ((cards_found >= MAX_UNITS) || (options[cards_found] > sizeof(options_mapping))) + lp->options = PCNET32_PORT_ASEL; + else + lp->options = options_mapping[options[cards_found]]; + lp->mii_if.dev = dev; + lp->mii_if.mdio_read = mdio_read; + lp->mii_if.mdio_write = mdio_write; + + if (fdx && !(lp->options & PCNET32_PORT_ASEL) && + ((cards_found>=MAX_UNITS) || full_duplex[cards_found])) + lp->options |= PCNET32_PORT_FD; + + if (!a) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_ERR PFX "No access methods\n"); + ret = -ENODEV; + goto err_free_consistent; + } + lp->a = *a; + + /* prior to register_netdev, dev->name is not yet correct */ + if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) { + ret = -ENOMEM; + goto err_free_ring; + } + /* detect special T1/E1 WAN card by checking for MAC address */ + if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 && dev->dev_addr[2] == 0x75) - lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI; + lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI; + + lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ + lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); + for (i = 0; i < 6; i++) + lp->init_block.phys_addr[i] = dev->dev_addr[i]; + lp->init_block.filter[0] = 0x00000000; + lp->init_block.filter[1] = 0x00000000; + lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr); + lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr); + + /* switch pcnet32 to 32bit mode */ + a->write_bcr(ioaddr, 20, 2); + + a->write_csr(ioaddr, 1, (lp->dma_addr + offsetof(struct pcnet32_private, + init_block)) & 0xffff); + a->write_csr(ioaddr, 2, (lp->dma_addr + offsetof(struct pcnet32_private, + init_block)) >> 16); + + if (pdev) { /* use the IRQ provided by PCI */ + dev->irq = pdev->irq; + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(" assigned IRQ %d.\n", dev->irq); + } else { + unsigned long irq_mask = probe_irq_on(); - lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ - lp->init_block.tlen_rlen = - le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); - for (i = 0; i < 6; i++) - lp->init_block.phys_addr[i] = dev->dev_addr[i]; - lp->init_block.filter[0] = 0x00000000; - lp->init_block.filter[1] = 0x00000000; - lp->init_block.rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr); - lp->init_block.tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr); - - /* switch pcnet32 to 32bit mode */ - a->write_bcr(ioaddr, 20, 2); - - a->write_csr(ioaddr, 1, (lp->dma_addr + offsetof(struct pcnet32_private, - init_block)) & 0xffff); - a->write_csr(ioaddr, 2, (lp->dma_addr + offsetof(struct pcnet32_private, - init_block)) >> 16); - - if (pdev) { /* use the IRQ provided by PCI */ - dev->irq = pdev->irq; - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(" assigned IRQ %d.\n", dev->irq); - } else { - unsigned long irq_mask = probe_irq_on(); - - /* - * To auto-IRQ we enable the initialization-done and DMA error - * interrupts. For ISA boards we get a DMA error, but VLB and PCI - * boards will work. - */ - /* Trigger an initialization just for the interrupt. */ - a->write_csr(ioaddr, 0, 0x41); - mdelay(1); - - dev->irq = probe_irq_off(irq_mask); - if (!dev->irq) { - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(", failed to detect IRQ line.\n"); - ret = -ENODEV; - goto err_free_ring; - } - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(", probed IRQ %d.\n", dev->irq); - } + /* + * To auto-IRQ we enable the initialization-done and DMA error + * interrupts. For ISA boards we get a DMA error, but VLB and PCI + * boards will work. + */ + /* Trigger an initialization just for the interrupt. */ + a->write_csr (ioaddr, 0, 0x41); + mdelay (1); - /* Set the mii phy_id so that we can query the link state */ - if (lp->mii) { - /* lp->phycount and lp->phymask are set to 0 by memset above */ - - lp->mii_if.phy_id = ((lp->a.read_bcr(ioaddr, 33)) >> 5) & 0x1f; - /* scan for PHYs */ - for (i = 0; i < PCNET32_MAX_PHYS; i++) { - unsigned short id1, id2; - - id1 = mdio_read(dev, i, MII_PHYSID1); - if (id1 == 0xffff) - continue; - id2 = mdio_read(dev, i, MII_PHYSID2); - if (id2 == 0xffff) - continue; - if (i == 31 && ((chip_version + 1) & 0xfffe) == 0x2624) - continue; /* 79C971 & 79C972 have phantom phy at id 31 */ - lp->phycount++; - lp->phymask |= (1 << i); - lp->mii_if.phy_id = i; - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_INFO PFX - "Found PHY %04x:%04x at address %d.\n", - id1, id2, i); - } - lp->a.write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5); - if (lp->phycount > 1) { - lp->options |= PCNET32_PORT_MII; - } + dev->irq = probe_irq_off (irq_mask); + if (!dev->irq) { + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(", failed to detect IRQ line.\n"); + ret = -ENODEV; + goto err_free_ring; } - - init_timer(&lp->watchdog_timer); - lp->watchdog_timer.data = (unsigned long)dev; - lp->watchdog_timer.function = (void *)&pcnet32_watchdog; - - /* The PCNET32-specific entries in the device structure. */ - dev->open = &pcnet32_open; - dev->hard_start_xmit = &pcnet32_start_xmit; - dev->stop = &pcnet32_close; - dev->get_stats = &pcnet32_get_stats; - dev->set_multicast_list = &pcnet32_set_multicast_list; - dev->do_ioctl = &pcnet32_ioctl; - dev->ethtool_ops = &pcnet32_ethtool_ops; - dev->tx_timeout = pcnet32_tx_timeout; - dev->watchdog_timeo = (5 * HZ); + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(", probed IRQ %d.\n", dev->irq); + } + + /* Set the mii phy_id so that we can query the link state */ + if (lp->mii) + lp->mii_if.phy_id = ((lp->a.read_bcr (ioaddr, 33)) >> 5) & 0x1f; + + init_timer (&lp->watchdog_timer); + lp->watchdog_timer.data = (unsigned long) dev; + lp->watchdog_timer.function = (void *) &pcnet32_watchdog; + + /* The PCNET32-specific entries in the device structure. */ + dev->open = &pcnet32_open; + dev->hard_start_xmit = &pcnet32_start_xmit; + dev->stop = &pcnet32_close; + dev->get_stats = &pcnet32_get_stats; + dev->set_multicast_list = &pcnet32_set_multicast_list; + dev->do_ioctl = &pcnet32_ioctl; + dev->ethtool_ops = &pcnet32_ethtool_ops; + dev->tx_timeout = pcnet32_tx_timeout; + dev->watchdog_timeo = (5*HZ); #ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = pcnet32_poll_controller; + dev->poll_controller = pcnet32_poll_controller; #endif - /* Fill in the generic fields of the device structure. */ - if (register_netdev(dev)) - goto err_free_ring; - - if (pdev) { - pci_set_drvdata(pdev, dev); - } else { - lp->next = pcnet32_dev; - pcnet32_dev = dev; - } - - if (pcnet32_debug & NETIF_MSG_PROBE) - printk(KERN_INFO "%s: registered as %s\n", dev->name, lp->name); - cards_found++; - - /* enable LED writes */ - a->write_bcr(ioaddr, 2, a->read_bcr(ioaddr, 2) | 0x1000); - - return 0; - - err_free_ring: - pcnet32_free_ring(dev); - err_free_consistent: - pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - err_free_netdev: - free_netdev(dev); - err_release_region: - release_region(ioaddr, PCNET32_TOTAL_SIZE); - return ret; + /* Fill in the generic fields of the device structure. */ + if (register_netdev(dev)) + goto err_free_ring; + + if (pdev) { + pci_set_drvdata(pdev, dev); + } else { + lp->next = pcnet32_dev; + pcnet32_dev = dev; + } + + if (pcnet32_debug & NETIF_MSG_PROBE) + printk(KERN_INFO "%s: registered as %s\n", dev->name, lp->name); + cards_found++; + + /* enable LED writes */ + a->write_bcr(ioaddr, 2, a->read_bcr(ioaddr, 2) | 0x1000); + + return 0; + +err_free_ring: + pcnet32_free_ring(dev); +err_free_consistent: + pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); +err_free_netdev: + free_netdev(dev); +err_release_region: + release_region(ioaddr, PCNET32_TOTAL_SIZE); + return ret; } + /* if any allocation fails, caller must also call pcnet32_free_ring */ static int pcnet32_alloc_ring(struct net_device *dev, char *name) { - struct pcnet32_private *lp = dev->priv; - - lp->tx_ring = pci_alloc_consistent(lp->pci_dev, - sizeof(struct pcnet32_tx_head) * - lp->tx_ring_size, - &lp->tx_ring_dma_addr); - if (lp->tx_ring == NULL) { - if (pcnet32_debug & NETIF_MSG_DRV) - printk("\n" KERN_ERR PFX - "%s: Consistent memory allocation failed.\n", - name); - return -ENOMEM; - } + struct pcnet32_private *lp = dev->priv; - lp->rx_ring = pci_alloc_consistent(lp->pci_dev, - sizeof(struct pcnet32_rx_head) * - lp->rx_ring_size, - &lp->rx_ring_dma_addr); - if (lp->rx_ring == NULL) { - if (pcnet32_debug & NETIF_MSG_DRV) - printk("\n" KERN_ERR PFX - "%s: Consistent memory allocation failed.\n", - name); - return -ENOMEM; - } - - lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, - GFP_ATOMIC); - if (!lp->tx_dma_addr) { - if (pcnet32_debug & NETIF_MSG_DRV) - printk("\n" KERN_ERR PFX - "%s: Memory allocation failed.\n", name); - return -ENOMEM; - } - memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size); - - lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, - GFP_ATOMIC); - if (!lp->rx_dma_addr) { - if (pcnet32_debug & NETIF_MSG_DRV) - printk("\n" KERN_ERR PFX - "%s: Memory allocation failed.\n", name); - return -ENOMEM; - } - memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size); - - lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, - GFP_ATOMIC); - if (!lp->tx_skbuff) { - if (pcnet32_debug & NETIF_MSG_DRV) - printk("\n" KERN_ERR PFX - "%s: Memory allocation failed.\n", name); - return -ENOMEM; - } - memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size); - - lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, - GFP_ATOMIC); - if (!lp->rx_skbuff) { - if (pcnet32_debug & NETIF_MSG_DRV) - printk("\n" KERN_ERR PFX - "%s: Memory allocation failed.\n", name); - return -ENOMEM; - } - memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size); + lp->tx_ring = pci_alloc_consistent(lp->pci_dev, + sizeof(struct pcnet32_tx_head) * lp->tx_ring_size, + &lp->tx_ring_dma_addr); + if (lp->tx_ring == NULL) { + if (pcnet32_debug & NETIF_MSG_DRV) + printk("\n" KERN_ERR PFX "%s: Consistent memory allocation failed.\n", + name); + return -ENOMEM; + } + + lp->rx_ring = pci_alloc_consistent(lp->pci_dev, + sizeof(struct pcnet32_rx_head) * lp->rx_ring_size, + &lp->rx_ring_dma_addr); + if (lp->rx_ring == NULL) { + if (pcnet32_debug & NETIF_MSG_DRV) + printk("\n" KERN_ERR PFX "%s: Consistent memory allocation failed.\n", + name); + return -ENOMEM; + } + + lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, + GFP_ATOMIC); + if (!lp->tx_dma_addr) { + if (pcnet32_debug & NETIF_MSG_DRV) + printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name); + return -ENOMEM; + } + memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size); + + lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, + GFP_ATOMIC); + if (!lp->rx_dma_addr) { + if (pcnet32_debug & NETIF_MSG_DRV) + printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name); + return -ENOMEM; + } + memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size); + + lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, + GFP_ATOMIC); + if (!lp->tx_skbuff) { + if (pcnet32_debug & NETIF_MSG_DRV) + printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name); + return -ENOMEM; + } + memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size); + + lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, + GFP_ATOMIC); + if (!lp->rx_skbuff) { + if (pcnet32_debug & NETIF_MSG_DRV) + printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name); + return -ENOMEM; + } + memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size); - return 0; + return 0; } + static void pcnet32_free_ring(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; + struct pcnet32_private *lp = dev->priv; - kfree(lp->tx_skbuff); - lp->tx_skbuff = NULL; + kfree(lp->tx_skbuff); + lp->tx_skbuff = NULL; - kfree(lp->rx_skbuff); - lp->rx_skbuff = NULL; + kfree(lp->rx_skbuff); + lp->rx_skbuff = NULL; - kfree(lp->tx_dma_addr); - lp->tx_dma_addr = NULL; + kfree(lp->tx_dma_addr); + lp->tx_dma_addr = NULL; - kfree(lp->rx_dma_addr); - lp->rx_dma_addr = NULL; + kfree(lp->rx_dma_addr); + lp->rx_dma_addr = NULL; - if (lp->tx_ring) { - pci_free_consistent(lp->pci_dev, - sizeof(struct pcnet32_tx_head) * - lp->tx_ring_size, lp->tx_ring, - lp->tx_ring_dma_addr); - lp->tx_ring = NULL; - } + if (lp->tx_ring) { + pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size, + lp->tx_ring, lp->tx_ring_dma_addr); + lp->tx_ring = NULL; + } - if (lp->rx_ring) { - pci_free_consistent(lp->pci_dev, - sizeof(struct pcnet32_rx_head) * - lp->rx_ring_size, lp->rx_ring, - lp->rx_ring_dma_addr); - lp->rx_ring = NULL; - } + if (lp->rx_ring) { + pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size, + lp->rx_ring, lp->rx_ring_dma_addr); + lp->rx_ring = NULL; + } } -static int pcnet32_open(struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; - u16 val; - int i; - int rc; - unsigned long flags; - - if (request_irq(dev->irq, &pcnet32_interrupt, - lp->shared_irq ? SA_SHIRQ : 0, dev->name, - (void *)dev)) { - return -EAGAIN; - } - - spin_lock_irqsave(&lp->lock, flags); - /* Check for a valid station address */ - if (!is_valid_ether_addr(dev->dev_addr)) { - rc = -EINVAL; - goto err_free_irq; - } - - /* Reset the PCNET32 */ - lp->a.reset(ioaddr); - - /* switch pcnet32 to 32bit mode */ - lp->a.write_bcr(ioaddr, 20, 2); - if (netif_msg_ifup(lp)) - printk(KERN_DEBUG - "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n", - dev->name, dev->irq, (u32) (lp->tx_ring_dma_addr), - (u32) (lp->rx_ring_dma_addr), - (u32) (lp->dma_addr + - offsetof(struct pcnet32_private, init_block))); - - /* set/reset autoselect bit */ - val = lp->a.read_bcr(ioaddr, 2) & ~2; - if (lp->options & PCNET32_PORT_ASEL) +static int +pcnet32_open(struct net_device *dev) +{ + struct pcnet32_private *lp = dev->priv; + unsigned long ioaddr = dev->base_addr; + u16 val; + int i; + int rc; + unsigned long flags; + + if (request_irq(dev->irq, &pcnet32_interrupt, + lp->shared_irq ? SA_SHIRQ : 0, dev->name, (void *)dev)) { + return -EAGAIN; + } + + spin_lock_irqsave(&lp->lock, flags); + /* Check for a valid station address */ + if (!is_valid_ether_addr(dev->dev_addr)) { + rc = -EINVAL; + goto err_free_irq; + } + + /* Reset the PCNET32 */ + lp->a.reset (ioaddr); + + /* switch pcnet32 to 32bit mode */ + lp->a.write_bcr (ioaddr, 20, 2); + + if (netif_msg_ifup(lp)) + printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n", + dev->name, dev->irq, + (u32) (lp->tx_ring_dma_addr), + (u32) (lp->rx_ring_dma_addr), + (u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block))); + + /* set/reset autoselect bit */ + val = lp->a.read_bcr (ioaddr, 2) & ~2; + if (lp->options & PCNET32_PORT_ASEL) + val |= 2; + lp->a.write_bcr (ioaddr, 2, val); + + /* handle full duplex setting */ + if (lp->mii_if.full_duplex) { + val = lp->a.read_bcr (ioaddr, 9) & ~3; + if (lp->options & PCNET32_PORT_FD) { + val |= 1; + if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI)) val |= 2; - lp->a.write_bcr(ioaddr, 2, val); - - /* handle full duplex setting */ - if (lp->mii_if.full_duplex) { - val = lp->a.read_bcr(ioaddr, 9) & ~3; - if (lp->options & PCNET32_PORT_FD) { - val |= 1; - if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI)) - val |= 2; - } else if (lp->options & PCNET32_PORT_ASEL) { - /* workaround of xSeries250, turn on for 79C975 only */ - i = ((lp->a.read_csr(ioaddr, 88) | - (lp->a. - read_csr(ioaddr, 89) << 16)) >> 12) & 0xffff; - if (i == 0x2627) - val |= 3; - } - lp->a.write_bcr(ioaddr, 9, val); - } - - /* set/reset GPSI bit in test register */ - val = lp->a.read_csr(ioaddr, 124) & ~0x10; - if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI) - val |= 0x10; - lp->a.write_csr(ioaddr, 124, val); - - /* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */ - if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT && + } else if (lp->options & PCNET32_PORT_ASEL) { + /* workaround of xSeries250, turn on for 79C975 only */ + i = ((lp->a.read_csr(ioaddr, 88) | + (lp->a.read_csr(ioaddr,89) << 16)) >> 12) & 0xffff; + if (i == 0x2627) + val |= 3; + } + lp->a.write_bcr (ioaddr, 9, val); + } + + /* set/reset GPSI bit in test register */ + val = lp->a.read_csr (ioaddr, 124) & ~0x10; + if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI) + val |= 0x10; + lp->a.write_csr (ioaddr, 124, val); + + /* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */ + if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT && (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX || lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) { - if (lp->options & PCNET32_PORT_ASEL) { - lp->options = PCNET32_PORT_FD | PCNET32_PORT_100; - if (netif_msg_link(lp)) - printk(KERN_DEBUG - "%s: Setting 100Mb-Full Duplex.\n", - dev->name); - } - } - if (lp->phycount < 2) { - /* - * 24 Jun 2004 according AMD, in order to change the PHY, - * DANAS (or DISPM for 79C976) must be set; then select the speed, - * duplex, and/or enable auto negotiation, and clear DANAS - */ - if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) { - lp->a.write_bcr(ioaddr, 32, - lp->a.read_bcr(ioaddr, 32) | 0x0080); - /* disable Auto Negotiation, set 10Mpbs, HD */ - val = lp->a.read_bcr(ioaddr, 32) & ~0xb8; - if (lp->options & PCNET32_PORT_FD) - val |= 0x10; - if (lp->options & PCNET32_PORT_100) - val |= 0x08; - lp->a.write_bcr(ioaddr, 32, val); - } else { - if (lp->options & PCNET32_PORT_ASEL) { - lp->a.write_bcr(ioaddr, 32, - lp->a.read_bcr(ioaddr, - 32) | 0x0080); - /* enable auto negotiate, setup, disable fd */ - val = lp->a.read_bcr(ioaddr, 32) & ~0x98; - val |= 0x20; - lp->a.write_bcr(ioaddr, 32, val); - } - } + if (lp->options & PCNET32_PORT_ASEL) { + lp->options = PCNET32_PORT_FD | PCNET32_PORT_100; + if (netif_msg_link(lp)) + printk(KERN_DEBUG "%s: Setting 100Mb-Full Duplex.\n", + dev->name); + } + } + { + /* + * 24 Jun 2004 according AMD, in order to change the PHY, + * DANAS (or DISPM for 79C976) must be set; then select the speed, + * duplex, and/or enable auto negotiation, and clear DANAS + */ + if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) { + lp->a.write_bcr(ioaddr, 32, + lp->a.read_bcr(ioaddr, 32) | 0x0080); + /* disable Auto Negotiation, set 10Mpbs, HD */ + val = lp->a.read_bcr(ioaddr, 32) & ~0xb8; + if (lp->options & PCNET32_PORT_FD) + val |= 0x10; + if (lp->options & PCNET32_PORT_100) + val |= 0x08; + lp->a.write_bcr (ioaddr, 32, val); } else { - int first_phy = -1; - u16 bmcr; - u32 bcr9; - struct ethtool_cmd ecmd; - - /* - * There is really no good other way to handle multiple PHYs - * other than turning off all automatics - */ - val = lp->a.read_bcr(ioaddr, 2); - lp->a.write_bcr(ioaddr, 2, val & ~2); - val = lp->a.read_bcr(ioaddr, 32); - lp->a.write_bcr(ioaddr, 32, val & ~(1 << 7)); /* stop MII manager */ - - if (!(lp->options & PCNET32_PORT_ASEL)) { - /* setup ecmd */ - ecmd.port = PORT_MII; - ecmd.transceiver = XCVR_INTERNAL; - ecmd.autoneg = AUTONEG_DISABLE; - ecmd.speed = - lp-> - options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10; - bcr9 = lp->a.read_bcr(ioaddr, 9); - - if (lp->options & PCNET32_PORT_FD) { - ecmd.duplex = DUPLEX_FULL; - bcr9 |= (1 << 0); - } else { - ecmd.duplex = DUPLEX_HALF; - bcr9 |= ~(1 << 0); - } - lp->a.write_bcr(ioaddr, 9, bcr9); - } - - for (i = 0; i < PCNET32_MAX_PHYS; i++) { - if (lp->phymask & (1 << i)) { - /* isolate all but the first PHY */ - bmcr = mdio_read(dev, i, MII_BMCR); - if (first_phy == -1) { - first_phy = i; - mdio_write(dev, i, MII_BMCR, - bmcr & ~BMCR_ISOLATE); - } else { - mdio_write(dev, i, MII_BMCR, - bmcr | BMCR_ISOLATE); - } - /* use mii_ethtool_sset to setup PHY */ - lp->mii_if.phy_id = i; - ecmd.phy_address = i; - if (lp->options & PCNET32_PORT_ASEL) { - mii_ethtool_gset(&lp->mii_if, &ecmd); - ecmd.autoneg = AUTONEG_ENABLE; - } - mii_ethtool_sset(&lp->mii_if, &ecmd); - } - } - lp->mii_if.phy_id = first_phy; - if (netif_msg_link(lp)) - printk(KERN_INFO "%s: Using PHY number %d.\n", - dev->name, first_phy); + if (lp->options & PCNET32_PORT_ASEL) { + lp->a.write_bcr(ioaddr, 32, + lp->a.read_bcr(ioaddr, 32) | 0x0080); + /* enable auto negotiate, setup, disable fd */ + val = lp->a.read_bcr(ioaddr, 32) & ~0x98; + val |= 0x20; + lp->a.write_bcr(ioaddr, 32, val); + } } + } #ifdef DO_DXSUFLO - if (lp->dxsuflo) { /* Disable transmit stop on underflow */ - val = lp->a.read_csr(ioaddr, 3); - val |= 0x40; - lp->a.write_csr(ioaddr, 3, val); - } + if (lp->dxsuflo) { /* Disable transmit stop on underflow */ + val = lp->a.read_csr (ioaddr, 3); + val |= 0x40; + lp->a.write_csr (ioaddr, 3, val); + } #endif - lp->init_block.mode = - le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); - pcnet32_load_multicast(dev); - - if (pcnet32_init_ring(dev)) { - rc = -ENOMEM; - goto err_free_ring; - } - - /* Re-initialize the PCNET32, and start it when done. */ - lp->a.write_csr(ioaddr, 1, (lp->dma_addr + - offsetof(struct pcnet32_private, - init_block)) & 0xffff); - lp->a.write_csr(ioaddr, 2, - (lp->dma_addr + - offsetof(struct pcnet32_private, init_block)) >> 16); - - lp->a.write_csr(ioaddr, 4, 0x0915); - lp->a.write_csr(ioaddr, 0, 0x0001); - - netif_start_queue(dev); - - /* Print the link status and start the watchdog */ - pcnet32_check_media(dev, 1); - mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); - - i = 0; - while (i++ < 100) - if (lp->a.read_csr(ioaddr, 0) & 0x0100) - break; - /* - * We used to clear the InitDone bit, 0x0100, here but Mark Stockton - * reports that doing so triggers a bug in the '974. - */ - lp->a.write_csr(ioaddr, 0, 0x0042); - - if (netif_msg_ifup(lp)) - printk(KERN_DEBUG - "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n", - dev->name, i, - (u32) (lp->dma_addr + - offsetof(struct pcnet32_private, init_block)), - lp->a.read_csr(ioaddr, 0)); - - spin_unlock_irqrestore(&lp->lock, flags); - - return 0; /* Always succeed */ - - err_free_ring: - /* free any allocated skbuffs */ - for (i = 0; i < lp->rx_ring_size; i++) { - lp->rx_ring[i].status = 0; - if (lp->rx_skbuff[i]) { - pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], - PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); - dev_kfree_skb(lp->rx_skbuff[i]); - } - lp->rx_skbuff[i] = NULL; - lp->rx_dma_addr[i] = 0; - } - - /* - * Switch back to 16bit mode to avoid problems with dumb - * DOS packet driver after a warm reboot - */ - lp->a.write_bcr(ioaddr, 20, 4); - - err_free_irq: - spin_unlock_irqrestore(&lp->lock, flags); - free_irq(dev->irq, dev); - return rc; + lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); + pcnet32_load_multicast(dev); + + if (pcnet32_init_ring(dev)) { + rc = -ENOMEM; + goto err_free_ring; + } + + /* Re-initialize the PCNET32, and start it when done. */ + lp->a.write_csr (ioaddr, 1, (lp->dma_addr + + offsetof(struct pcnet32_private, init_block)) & 0xffff); + lp->a.write_csr (ioaddr, 2, (lp->dma_addr + + offsetof(struct pcnet32_private, init_block)) >> 16); + + lp->a.write_csr (ioaddr, 4, 0x0915); + lp->a.write_csr (ioaddr, 0, 0x0001); + + netif_start_queue(dev); + + /* If we have mii, print the link status and start the watchdog */ + if (lp->mii) { + mii_check_media (&lp->mii_if, netif_msg_link(lp), 1); + mod_timer (&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); + } + + i = 0; + while (i++ < 100) + if (lp->a.read_csr (ioaddr, 0) & 0x0100) + break; + /* + * We used to clear the InitDone bit, 0x0100, here but Mark Stockton + * reports that doing so triggers a bug in the '974. + */ + lp->a.write_csr (ioaddr, 0, 0x0042); + + if (netif_msg_ifup(lp)) + printk(KERN_DEBUG "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n", + dev->name, i, (u32) (lp->dma_addr + + offsetof(struct pcnet32_private, init_block)), + lp->a.read_csr(ioaddr, 0)); + + spin_unlock_irqrestore(&lp->lock, flags); + + return 0; /* Always succeed */ + +err_free_ring: + /* free any allocated skbuffs */ + for (i = 0; i < lp->rx_ring_size; i++) { + lp->rx_ring[i].status = 0; + if (lp->rx_skbuff[i]) { + pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); + dev_kfree_skb(lp->rx_skbuff[i]); + } + lp->rx_skbuff[i] = NULL; + lp->rx_dma_addr[i] = 0; + } + + pcnet32_free_ring(dev); + + /* + * Switch back to 16bit mode to avoid problems with dumb + * DOS packet driver after a warm reboot + */ + lp->a.write_bcr (ioaddr, 20, 4); + +err_free_irq: + spin_unlock_irqrestore(&lp->lock, flags); + free_irq(dev->irq, dev); + return rc; } /* @@ -1799,893 +1746,727 @@ static int pcnet32_open(struct net_device *dev) * restarting the chip, but I'm too lazy to do so right now. dplatt@3do.com */ -static void pcnet32_purge_tx_ring(struct net_device *dev) +static void +pcnet32_purge_tx_ring(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - int i; - - for (i = 0; i < lp->tx_ring_size; i++) { - lp->tx_ring[i].status = 0; /* CPU owns buffer */ - wmb(); /* Make sure adapter sees owner change */ - if (lp->tx_skbuff[i]) { - pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], - lp->tx_skbuff[i]->len, - PCI_DMA_TODEVICE); - dev_kfree_skb_any(lp->tx_skbuff[i]); - } - lp->tx_skbuff[i] = NULL; - lp->tx_dma_addr[i] = 0; - } + struct pcnet32_private *lp = dev->priv; + int i; + + for (i = 0; i < lp->tx_ring_size; i++) { + lp->tx_ring[i].status = 0; /* CPU owns buffer */ + wmb(); /* Make sure adapter sees owner change */ + if (lp->tx_skbuff[i]) { + pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], + lp->tx_skbuff[i]->len, PCI_DMA_TODEVICE); + dev_kfree_skb_any(lp->tx_skbuff[i]); + } + lp->tx_skbuff[i] = NULL; + lp->tx_dma_addr[i] = 0; + } } + /* Initialize the PCNET32 Rx and Tx rings. */ -static int pcnet32_init_ring(struct net_device *dev) +static int +pcnet32_init_ring(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - int i; - - lp->tx_full = 0; - lp->cur_rx = lp->cur_tx = 0; - lp->dirty_rx = lp->dirty_tx = 0; - - for (i = 0; i < lp->rx_ring_size; i++) { - struct sk_buff *rx_skbuff = lp->rx_skbuff[i]; - if (rx_skbuff == NULL) { - if (! - (rx_skbuff = lp->rx_skbuff[i] = - dev_alloc_skb(PKT_BUF_SZ))) { - /* there is not much, we can do at this point */ - if (pcnet32_debug & NETIF_MSG_DRV) - printk(KERN_ERR - "%s: pcnet32_init_ring dev_alloc_skb failed.\n", - dev->name); - return -1; - } - skb_reserve(rx_skbuff, 2); - } - - rmb(); - if (lp->rx_dma_addr[i] == 0) - lp->rx_dma_addr[i] = - pci_map_single(lp->pci_dev, rx_skbuff->data, - PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); - lp->rx_ring[i].base = (u32) le32_to_cpu(lp->rx_dma_addr[i]); - lp->rx_ring[i].buf_length = le16_to_cpu(2 - PKT_BUF_SZ); - wmb(); /* Make sure owner changes after all others are visible */ - lp->rx_ring[i].status = le16_to_cpu(0x8000); - } - /* The Tx buffer address is filled in as needed, but we do need to clear - * the upper ownership bit. */ - for (i = 0; i < lp->tx_ring_size; i++) { - lp->tx_ring[i].status = 0; /* CPU owns buffer */ - wmb(); /* Make sure adapter sees owner change */ - lp->tx_ring[i].base = 0; - lp->tx_dma_addr[i] = 0; - } - - lp->init_block.tlen_rlen = - le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); - for (i = 0; i < 6; i++) - lp->init_block.phys_addr[i] = dev->dev_addr[i]; - lp->init_block.rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr); - lp->init_block.tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr); - wmb(); /* Make sure all changes are visible */ - return 0; + struct pcnet32_private *lp = dev->priv; + int i; + + lp->tx_full = 0; + lp->cur_rx = lp->cur_tx = 0; + lp->dirty_rx = lp->dirty_tx = 0; + + for (i = 0; i < lp->rx_ring_size; i++) { + struct sk_buff *rx_skbuff = lp->rx_skbuff[i]; + if (rx_skbuff == NULL) { + if (!(rx_skbuff = lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) { + /* there is not much, we can do at this point */ + if (pcnet32_debug & NETIF_MSG_DRV) + printk(KERN_ERR "%s: pcnet32_init_ring dev_alloc_skb failed.\n", + dev->name); + return -1; + } + skb_reserve (rx_skbuff, 2); + } + + rmb(); + if (lp->rx_dma_addr[i] == 0) + lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data, + PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); + lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); + lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ); + wmb(); /* Make sure owner changes after all others are visible */ + lp->rx_ring[i].status = le16_to_cpu(0x8000); + } + /* The Tx buffer address is filled in as needed, but we do need to clear + * the upper ownership bit. */ + for (i = 0; i < lp->tx_ring_size; i++) { + lp->tx_ring[i].status = 0; /* CPU owns buffer */ + wmb(); /* Make sure adapter sees owner change */ + lp->tx_ring[i].base = 0; + lp->tx_dma_addr[i] = 0; + } + + lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); + for (i = 0; i < 6; i++) + lp->init_block.phys_addr[i] = dev->dev_addr[i]; + lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr); + lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr); + wmb(); /* Make sure all changes are visible */ + return 0; } /* the pcnet32 has been issued a stop or reset. Wait for the stop bit * then flush the pending transmit operations, re-initialize the ring, * and tell the chip to initialize. */ -static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits) +static void +pcnet32_restart(struct net_device *dev, unsigned int csr0_bits) { - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; - int i; + struct pcnet32_private *lp = dev->priv; + unsigned long ioaddr = dev->base_addr; + int i; - /* wait for stop */ - for (i = 0; i < 100; i++) - if (lp->a.read_csr(ioaddr, 0) & 0x0004) - break; + /* wait for stop */ + for (i=0; i<100; i++) + if (lp->a.read_csr(ioaddr, 0) & 0x0004) + break; - if (i >= 100 && netif_msg_drv(lp)) - printk(KERN_ERR - "%s: pcnet32_restart timed out waiting for stop.\n", - dev->name); + if (i >= 100 && netif_msg_drv(lp)) + printk(KERN_ERR "%s: pcnet32_restart timed out waiting for stop.\n", + dev->name); - pcnet32_purge_tx_ring(dev); - if (pcnet32_init_ring(dev)) - return; + pcnet32_purge_tx_ring(dev); + if (pcnet32_init_ring(dev)) + return; - /* ReInit Ring */ - lp->a.write_csr(ioaddr, 0, 1); - i = 0; - while (i++ < 1000) - if (lp->a.read_csr(ioaddr, 0) & 0x0100) - break; + /* ReInit Ring */ + lp->a.write_csr (ioaddr, 0, 1); + i = 0; + while (i++ < 1000) + if (lp->a.read_csr (ioaddr, 0) & 0x0100) + break; - lp->a.write_csr(ioaddr, 0, csr0_bits); + lp->a.write_csr (ioaddr, 0, csr0_bits); } -static void pcnet32_tx_timeout(struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr, flags; - - spin_lock_irqsave(&lp->lock, flags); - /* Transmitter timeout, serious problems. */ - if (pcnet32_debug & NETIF_MSG_DRV) - printk(KERN_ERR - "%s: transmit timed out, status %4.4x, resetting.\n", - dev->name, lp->a.read_csr(ioaddr, 0)); - lp->a.write_csr(ioaddr, 0, 0x0004); - lp->stats.tx_errors++; - if (netif_msg_tx_err(lp)) { - int i; - printk(KERN_DEBUG - " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.", - lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "", - lp->cur_rx); - for (i = 0; i < lp->rx_ring_size; i++) - printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ", - le32_to_cpu(lp->rx_ring[i].base), - (-le16_to_cpu(lp->rx_ring[i].buf_length)) & - 0xffff, le32_to_cpu(lp->rx_ring[i].msg_length), - le16_to_cpu(lp->rx_ring[i].status)); - for (i = 0; i < lp->tx_ring_size; i++) - printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ", - le32_to_cpu(lp->tx_ring[i].base), - (-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff, - le32_to_cpu(lp->tx_ring[i].misc), - le16_to_cpu(lp->tx_ring[i].status)); - printk("\n"); - } - pcnet32_restart(dev, 0x0042); - - dev->trans_start = jiffies; - netif_wake_queue(dev); - spin_unlock_irqrestore(&lp->lock, flags); +static void +pcnet32_tx_timeout (struct net_device *dev) +{ + struct pcnet32_private *lp = dev->priv; + unsigned long ioaddr = dev->base_addr, flags; + + spin_lock_irqsave(&lp->lock, flags); + /* Transmitter timeout, serious problems. */ + if (pcnet32_debug & NETIF_MSG_DRV) + printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n", + dev->name, lp->a.read_csr(ioaddr, 0)); + lp->a.write_csr (ioaddr, 0, 0x0004); + lp->stats.tx_errors++; + if (netif_msg_tx_err(lp)) { + int i; + printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.", + lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "", + lp->cur_rx); + for (i = 0 ; i < lp->rx_ring_size; i++) + printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ", + le32_to_cpu(lp->rx_ring[i].base), + (-le16_to_cpu(lp->rx_ring[i].buf_length)) & 0xffff, + le32_to_cpu(lp->rx_ring[i].msg_length), + le16_to_cpu(lp->rx_ring[i].status)); + for (i = 0 ; i < lp->tx_ring_size; i++) + printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ", + le32_to_cpu(lp->tx_ring[i].base), + (-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff, + le32_to_cpu(lp->tx_ring[i].misc), + le16_to_cpu(lp->tx_ring[i].status)); + printk("\n"); + } + pcnet32_restart(dev, 0x0042); + + dev->trans_start = jiffies; + netif_wake_queue(dev); + + spin_unlock_irqrestore(&lp->lock, flags); } -static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) + +static int +pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; - u16 status; - int entry; - unsigned long flags; + struct pcnet32_private *lp = dev->priv; + unsigned long ioaddr = dev->base_addr; + u16 status; + int entry; + unsigned long flags; - spin_lock_irqsave(&lp->lock, flags); + spin_lock_irqsave(&lp->lock, flags); - if (netif_msg_tx_queued(lp)) { - printk(KERN_DEBUG - "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n", - dev->name, lp->a.read_csr(ioaddr, 0)); - } + if (netif_msg_tx_queued(lp)) { + printk(KERN_DEBUG "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n", + dev->name, lp->a.read_csr(ioaddr, 0)); + } - /* Default status -- will not enable Successful-TxDone - * interrupt when that option is available to us. - */ - status = 0x8300; + /* Default status -- will not enable Successful-TxDone + * interrupt when that option is available to us. + */ + status = 0x8300; - /* Fill in a Tx ring entry */ + /* Fill in a Tx ring entry */ - /* Mask to ring buffer boundary. */ - entry = lp->cur_tx & lp->tx_mod_mask; + /* Mask to ring buffer boundary. */ + entry = lp->cur_tx & lp->tx_mod_mask; - /* Caution: the write order is important here, set the status - * with the "ownership" bits last. */ + /* Caution: the write order is important here, set the status + * with the "ownership" bits last. */ - lp->tx_ring[entry].length = le16_to_cpu(-skb->len); + lp->tx_ring[entry].length = le16_to_cpu(-skb->len); - lp->tx_ring[entry].misc = 0x00000000; + lp->tx_ring[entry].misc = 0x00000000; - lp->tx_skbuff[entry] = skb; - lp->tx_dma_addr[entry] = - pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); - lp->tx_ring[entry].base = (u32) le32_to_cpu(lp->tx_dma_addr[entry]); - wmb(); /* Make sure owner changes after all others are visible */ - lp->tx_ring[entry].status = le16_to_cpu(status); + lp->tx_skbuff[entry] = skb; + lp->tx_dma_addr[entry] = pci_map_single(lp->pci_dev, skb->data, skb->len, + PCI_DMA_TODEVICE); + lp->tx_ring[entry].base = (u32)le32_to_cpu(lp->tx_dma_addr[entry]); + wmb(); /* Make sure owner changes after all others are visible */ + lp->tx_ring[entry].status = le16_to_cpu(status); - lp->cur_tx++; - lp->stats.tx_bytes += skb->len; + lp->cur_tx++; + lp->stats.tx_bytes += skb->len; - /* Trigger an immediate send poll. */ - lp->a.write_csr(ioaddr, 0, 0x0048); + /* Trigger an immediate send poll. */ + lp->a.write_csr (ioaddr, 0, 0x0048); - dev->trans_start = jiffies; + dev->trans_start = jiffies; - if (lp->tx_ring[(entry + 1) & lp->tx_mod_mask].base != 0) { - lp->tx_full = 1; - netif_stop_queue(dev); - } - spin_unlock_irqrestore(&lp->lock, flags); - return 0; + if (lp->tx_ring[(entry+1) & lp->tx_mod_mask].base != 0) { + lp->tx_full = 1; + netif_stop_queue(dev); + } + spin_unlock_irqrestore(&lp->lock, flags); + return 0; } /* The PCNET32 interrupt handler. */ static irqreturn_t -pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs) +pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct net_device *dev = dev_id; - struct pcnet32_private *lp; - unsigned long ioaddr; - u16 csr0, rap; - int boguscnt = max_interrupt_work; - int must_restart; - - if (!dev) { - if (pcnet32_debug & NETIF_MSG_INTR) - printk(KERN_DEBUG "%s(): irq %d for unknown device\n", - __FUNCTION__, irq); - return IRQ_NONE; - } - - ioaddr = dev->base_addr; - lp = dev->priv; + struct net_device *dev = dev_id; + struct pcnet32_private *lp; + unsigned long ioaddr; + u16 csr0,rap; + int boguscnt = max_interrupt_work; + int must_restart; - spin_lock(&lp->lock); + if (!dev) { + if (pcnet32_debug & NETIF_MSG_INTR) + printk (KERN_DEBUG "%s(): irq %d for unknown device\n", + __FUNCTION__, irq); + return IRQ_NONE; + } - rap = lp->a.read_rap(ioaddr); - while ((csr0 = lp->a.read_csr(ioaddr, 0)) & 0x8f00 && --boguscnt >= 0) { - if (csr0 == 0xffff) { - break; /* PCMCIA remove happened */ - } - /* Acknowledge all of the current interrupt sources ASAP. */ - lp->a.write_csr(ioaddr, 0, csr0 & ~0x004f); - - must_restart = 0; - - if (netif_msg_intr(lp)) - printk(KERN_DEBUG - "%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n", - dev->name, csr0, lp->a.read_csr(ioaddr, 0)); - - if (csr0 & 0x0400) /* Rx interrupt */ - pcnet32_rx(dev); - - if (csr0 & 0x0200) { /* Tx-done interrupt */ - unsigned int dirty_tx = lp->dirty_tx; - int delta; - - while (dirty_tx != lp->cur_tx) { - int entry = dirty_tx & lp->tx_mod_mask; - int status = - (short)le16_to_cpu(lp->tx_ring[entry]. - status); - - if (status < 0) - break; /* It still hasn't been Txed */ - - lp->tx_ring[entry].base = 0; - - if (status & 0x4000) { - /* There was an major error, log it. */ - int err_status = - le32_to_cpu(lp->tx_ring[entry]. - misc); - lp->stats.tx_errors++; - if (netif_msg_tx_err(lp)) - printk(KERN_ERR - "%s: Tx error status=%04x err_status=%08x\n", - dev->name, status, - err_status); - if (err_status & 0x04000000) - lp->stats.tx_aborted_errors++; - if (err_status & 0x08000000) - lp->stats.tx_carrier_errors++; - if (err_status & 0x10000000) - lp->stats.tx_window_errors++; -#ifndef DO_DXSUFLO - if (err_status & 0x40000000) { - lp->stats.tx_fifo_errors++; - /* Ackk! On FIFO errors the Tx unit is turned off! */ - /* Remove this verbosity later! */ - if (netif_msg_tx_err(lp)) - printk(KERN_ERR - "%s: Tx FIFO error! CSR0=%4.4x\n", - dev->name, csr0); - must_restart = 1; - } -#else - if (err_status & 0x40000000) { - lp->stats.tx_fifo_errors++; - if (!lp->dxsuflo) { /* If controller doesn't recover ... */ - /* Ackk! On FIFO errors the Tx unit is turned off! */ - /* Remove this verbosity later! */ - if (netif_msg_tx_err - (lp)) - printk(KERN_ERR - "%s: Tx FIFO error! CSR0=%4.4x\n", - dev-> - name, - csr0); - must_restart = 1; - } - } -#endif - } else { - if (status & 0x1800) - lp->stats.collisions++; - lp->stats.tx_packets++; - } - - /* We must free the original skb */ - if (lp->tx_skbuff[entry]) { - pci_unmap_single(lp->pci_dev, - lp->tx_dma_addr[entry], - lp->tx_skbuff[entry]-> - len, PCI_DMA_TODEVICE); - dev_kfree_skb_irq(lp->tx_skbuff[entry]); - lp->tx_skbuff[entry] = NULL; - lp->tx_dma_addr[entry] = 0; - } - dirty_tx++; - } - - delta = - (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + - lp->tx_ring_size); - if (delta > lp->tx_ring_size) { - if (netif_msg_drv(lp)) - printk(KERN_ERR - "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n", - dev->name, dirty_tx, lp->cur_tx, - lp->tx_full); - dirty_tx += lp->tx_ring_size; - delta -= lp->tx_ring_size; - } + ioaddr = dev->base_addr; + lp = dev->priv; - if (lp->tx_full && - netif_queue_stopped(dev) && - delta < lp->tx_ring_size - 2) { - /* The ring is no longer full, clear tbusy. */ - lp->tx_full = 0; - netif_wake_queue(dev); - } - lp->dirty_tx = dirty_tx; - } + spin_lock(&lp->lock); - /* Log misc errors. */ - if (csr0 & 0x4000) - lp->stats.tx_errors++; /* Tx babble. */ - if (csr0 & 0x1000) { - /* - * this happens when our receive ring is full. This shouldn't - * be a problem as we will see normal rx interrupts for the frames - * in the receive ring. But there are some PCI chipsets (I can - * reproduce this on SP3G with Intel saturn chipset) which have - * sometimes problems and will fill up the receive ring with - * error descriptors. In this situation we don't get a rx - * interrupt, but a missed frame interrupt sooner or later. - * So we try to clean up our receive ring here. - */ - pcnet32_rx(dev); - lp->stats.rx_errors++; /* Missed a Rx frame. */ - } - if (csr0 & 0x0800) { - if (netif_msg_drv(lp)) - printk(KERN_ERR - "%s: Bus master arbitration failure, status %4.4x.\n", - dev->name, csr0); - /* unlike for the lance, there is no restart needed */ - } - - if (must_restart) { - /* reset the chip to clear the error condition, then restart */ - lp->a.reset(ioaddr); - lp->a.write_csr(ioaddr, 4, 0x0915); - pcnet32_restart(dev, 0x0002); - netif_wake_queue(dev); - } + rap = lp->a.read_rap(ioaddr); + while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8f00 && --boguscnt >= 0) { + if (csr0 == 0xffff) { + break; /* PCMCIA remove happened */ } + /* Acknowledge all of the current interrupt sources ASAP. */ + lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f); - /* Set interrupt enable. */ - lp->a.write_csr(ioaddr, 0, 0x0040); - lp->a.write_rap(ioaddr, rap); + must_restart = 0; if (netif_msg_intr(lp)) - printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", - dev->name, lp->a.read_csr(ioaddr, 0)); - - spin_unlock(&lp->lock); + printk(KERN_DEBUG "%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n", + dev->name, csr0, lp->a.read_csr (ioaddr, 0)); + + if (csr0 & 0x0400) /* Rx interrupt */ + pcnet32_rx(dev); + + if (csr0 & 0x0200) { /* Tx-done interrupt */ + unsigned int dirty_tx = lp->dirty_tx; + int delta; + + while (dirty_tx != lp->cur_tx) { + int entry = dirty_tx & lp->tx_mod_mask; + int status = (short)le16_to_cpu(lp->tx_ring[entry].status); + + if (status < 0) + break; /* It still hasn't been Txed */ + + lp->tx_ring[entry].base = 0; + + if (status & 0x4000) { + /* There was an major error, log it. */ + int err_status = le32_to_cpu(lp->tx_ring[entry].misc); + lp->stats.tx_errors++; + if (netif_msg_tx_err(lp)) + printk(KERN_ERR "%s: Tx error status=%04x err_status=%08x\n", + dev->name, status, err_status); + if (err_status & 0x04000000) lp->stats.tx_aborted_errors++; + if (err_status & 0x08000000) lp->stats.tx_carrier_errors++; + if (err_status & 0x10000000) lp->stats.tx_window_errors++; +#ifndef DO_DXSUFLO + if (err_status & 0x40000000) { + lp->stats.tx_fifo_errors++; + /* Ackk! On FIFO errors the Tx unit is turned off! */ + /* Remove this verbosity later! */ + if (netif_msg_tx_err(lp)) + printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n", + dev->name, csr0); + must_restart = 1; + } +#else + if (err_status & 0x40000000) { + lp->stats.tx_fifo_errors++; + if (! lp->dxsuflo) { /* If controller doesn't recover ... */ + /* Ackk! On FIFO errors the Tx unit is turned off! */ + /* Remove this verbosity later! */ + if (netif_msg_tx_err(lp)) + printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n", + dev->name, csr0); + must_restart = 1; + } + } +#endif + } else { + if (status & 0x1800) + lp->stats.collisions++; + lp->stats.tx_packets++; + } - return IRQ_HANDLED; + /* We must free the original skb */ + if (lp->tx_skbuff[entry]) { + pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[entry], + lp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE); + dev_kfree_skb_irq(lp->tx_skbuff[entry]); + lp->tx_skbuff[entry] = NULL; + lp->tx_dma_addr[entry] = 0; + } + dirty_tx++; + } + + delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size); + if (delta > lp->tx_ring_size) { + if (netif_msg_drv(lp)) + printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n", + dev->name, dirty_tx, lp->cur_tx, lp->tx_full); + dirty_tx += lp->tx_ring_size; + delta -= lp->tx_ring_size; + } + + if (lp->tx_full && + netif_queue_stopped(dev) && + delta < lp->tx_ring_size - 2) { + /* The ring is no longer full, clear tbusy. */ + lp->tx_full = 0; + netif_wake_queue (dev); + } + lp->dirty_tx = dirty_tx; + } + + /* Log misc errors. */ + if (csr0 & 0x4000) lp->stats.tx_errors++; /* Tx babble. */ + if (csr0 & 0x1000) { + /* + * this happens when our receive ring is full. This shouldn't + * be a problem as we will see normal rx interrupts for the frames + * in the receive ring. But there are some PCI chipsets (I can + * reproduce this on SP3G with Intel saturn chipset) which have + * sometimes problems and will fill up the receive ring with + * error descriptors. In this situation we don't get a rx + * interrupt, but a missed frame interrupt sooner or later. + * So we try to clean up our receive ring here. + */ + pcnet32_rx(dev); + lp->stats.rx_errors++; /* Missed a Rx frame. */ + } + if (csr0 & 0x0800) { + if (netif_msg_drv(lp)) + printk(KERN_ERR "%s: Bus master arbitration failure, status %4.4x.\n", + dev->name, csr0); + /* unlike for the lance, there is no restart needed */ + } + + if (must_restart) { + /* reset the chip to clear the error condition, then restart */ + lp->a.reset(ioaddr); + lp->a.write_csr(ioaddr, 4, 0x0915); + pcnet32_restart(dev, 0x0002); + netif_wake_queue(dev); + } + } + + /* Set interrupt enable. */ + lp->a.write_csr (ioaddr, 0, 0x0040); + lp->a.write_rap (ioaddr,rap); + + if (netif_msg_intr(lp)) + printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", + dev->name, lp->a.read_csr (ioaddr, 0)); + + spin_unlock(&lp->lock); + + return IRQ_HANDLED; } -static int pcnet32_rx(struct net_device *dev) +static int +pcnet32_rx(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - int entry = lp->cur_rx & lp->rx_mod_mask; - int boguscnt = lp->rx_ring_size / 2; - - /* If we own the next entry, it's a new packet. Send it up. */ - while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) { - int status = (short)le16_to_cpu(lp->rx_ring[entry].status) >> 8; - - if (status != 0x03) { /* There was an error. */ - /* - * There is a tricky error noted by John Murphy, - * to Russ Nelson: Even with full-sized - * buffers it's possible for a jabber packet to use two - * buffers, with only the last correctly noting the error. - */ - if (status & 0x01) /* Only count a general error at the */ - lp->stats.rx_errors++; /* end of a packet. */ - if (status & 0x20) - lp->stats.rx_frame_errors++; - if (status & 0x10) - lp->stats.rx_over_errors++; - if (status & 0x08) - lp->stats.rx_crc_errors++; - if (status & 0x04) - lp->stats.rx_fifo_errors++; - lp->rx_ring[entry].status &= le16_to_cpu(0x03ff); + struct pcnet32_private *lp = dev->priv; + int entry = lp->cur_rx & lp->rx_mod_mask; + int boguscnt = lp->rx_ring_size / 2; + + /* If we own the next entry, it's a new packet. Send it up. */ + while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) { + int status = (short)le16_to_cpu(lp->rx_ring[entry].status) >> 8; + + if (status != 0x03) { /* There was an error. */ + /* + * There is a tricky error noted by John Murphy, + * to Russ Nelson: Even with full-sized + * buffers it's possible for a jabber packet to use two + * buffers, with only the last correctly noting the error. + */ + if (status & 0x01) /* Only count a general error at the */ + lp->stats.rx_errors++; /* end of a packet.*/ + if (status & 0x20) lp->stats.rx_frame_errors++; + if (status & 0x10) lp->stats.rx_over_errors++; + if (status & 0x08) lp->stats.rx_crc_errors++; + if (status & 0x04) lp->stats.rx_fifo_errors++; + lp->rx_ring[entry].status &= le16_to_cpu(0x03ff); + } else { + /* Malloc up new buffer, compatible with net-2e. */ + short pkt_len = (le32_to_cpu(lp->rx_ring[entry].msg_length) & 0xfff)-4; + struct sk_buff *skb; + + /* Discard oversize frames. */ + if (unlikely(pkt_len > PKT_BUF_SZ - 2)) { + if (netif_msg_drv(lp)) + printk(KERN_ERR "%s: Impossible packet size %d!\n", + dev->name, pkt_len); + lp->stats.rx_errors++; + } else if (pkt_len < 60) { + if (netif_msg_rx_err(lp)) + printk(KERN_ERR "%s: Runt packet!\n", dev->name); + lp->stats.rx_errors++; + } else { + int rx_in_place = 0; + + if (pkt_len > rx_copybreak) { + struct sk_buff *newskb; + + if ((newskb = dev_alloc_skb(PKT_BUF_SZ))) { + skb_reserve (newskb, 2); + skb = lp->rx_skbuff[entry]; + pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[entry], + PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); + skb_put (skb, pkt_len); + lp->rx_skbuff[entry] = newskb; + newskb->dev = dev; + lp->rx_dma_addr[entry] = + pci_map_single(lp->pci_dev, newskb->data, + PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); + lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]); + rx_in_place = 1; + } else + skb = NULL; } else { - /* Malloc up new buffer, compatible with net-2e. */ - short pkt_len = - (le32_to_cpu(lp->rx_ring[entry].msg_length) & 0xfff) - - 4; - struct sk_buff *skb; - - /* Discard oversize frames. */ - if (unlikely(pkt_len > PKT_BUF_SZ - 2)) { - if (netif_msg_drv(lp)) - printk(KERN_ERR - "%s: Impossible packet size %d!\n", - dev->name, pkt_len); - lp->stats.rx_errors++; - } else if (pkt_len < 60) { - if (netif_msg_rx_err(lp)) - printk(KERN_ERR "%s: Runt packet!\n", - dev->name); - lp->stats.rx_errors++; - } else { - int rx_in_place = 0; - - if (pkt_len > rx_copybreak) { - struct sk_buff *newskb; - - if ((newskb = - dev_alloc_skb(PKT_BUF_SZ))) { - skb_reserve(newskb, 2); - skb = lp->rx_skbuff[entry]; - pci_unmap_single(lp->pci_dev, - lp-> - rx_dma_addr - [entry], - PKT_BUF_SZ - 2, - PCI_DMA_FROMDEVICE); - skb_put(skb, pkt_len); - lp->rx_skbuff[entry] = newskb; - newskb->dev = dev; - lp->rx_dma_addr[entry] = - pci_map_single(lp->pci_dev, - newskb->data, - PKT_BUF_SZ - - 2, - PCI_DMA_FROMDEVICE); - lp->rx_ring[entry].base = - le32_to_cpu(lp-> - rx_dma_addr - [entry]); - rx_in_place = 1; - } else - skb = NULL; - } else { - skb = dev_alloc_skb(pkt_len + 2); - } - - if (skb == NULL) { - int i; - if (netif_msg_drv(lp)) - printk(KERN_ERR - "%s: Memory squeeze, deferring packet.\n", - dev->name); - for (i = 0; i < lp->rx_ring_size; i++) - if ((short) - le16_to_cpu(lp-> - rx_ring[(entry + - i) - & lp-> - rx_mod_mask]. - status) < 0) - break; - - if (i > lp->rx_ring_size - 2) { - lp->stats.rx_dropped++; - lp->rx_ring[entry].status |= - le16_to_cpu(0x8000); - wmb(); /* Make sure adapter sees owner change */ - lp->cur_rx++; - } - break; - } - skb->dev = dev; - if (!rx_in_place) { - skb_reserve(skb, 2); /* 16 byte align */ - skb_put(skb, pkt_len); /* Make room */ - pci_dma_sync_single_for_cpu(lp->pci_dev, - lp-> - rx_dma_addr - [entry], - PKT_BUF_SZ - - 2, - PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, - (unsigned char *)(lp-> - rx_skbuff - [entry]-> - data), - pkt_len, 0); - pci_dma_sync_single_for_device(lp-> - pci_dev, - lp-> - rx_dma_addr - [entry], - PKT_BUF_SZ - - 2, - PCI_DMA_FROMDEVICE); - } - lp->stats.rx_bytes += skb->len; - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - dev->last_rx = jiffies; - lp->stats.rx_packets++; - } + skb = dev_alloc_skb(pkt_len+2); } - /* - * The docs say that the buffer length isn't touched, but Andrew Boyd - * of QNX reports that some revs of the 79C965 clear it. - */ - lp->rx_ring[entry].buf_length = le16_to_cpu(2 - PKT_BUF_SZ); - wmb(); /* Make sure owner changes after all others are visible */ - lp->rx_ring[entry].status |= le16_to_cpu(0x8000); - entry = (++lp->cur_rx) & lp->rx_mod_mask; - if (--boguscnt <= 0) - break; /* don't stay in loop forever */ - } - return 0; + if (skb == NULL) { + int i; + if (netif_msg_drv(lp)) + printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n", + dev->name); + for (i = 0; i < lp->rx_ring_size; i++) + if ((short)le16_to_cpu(lp->rx_ring[(entry+i) + & lp->rx_mod_mask].status) < 0) + break; + + if (i > lp->rx_ring_size -2) { + lp->stats.rx_dropped++; + lp->rx_ring[entry].status |= le16_to_cpu(0x8000); + wmb(); /* Make sure adapter sees owner change */ + lp->cur_rx++; + } + break; + } + skb->dev = dev; + if (!rx_in_place) { + skb_reserve(skb,2); /* 16 byte align */ + skb_put(skb,pkt_len); /* Make room */ + pci_dma_sync_single_for_cpu(lp->pci_dev, + lp->rx_dma_addr[entry], + PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); + eth_copy_and_sum(skb, + (unsigned char *)(lp->rx_skbuff[entry]->data), + pkt_len,0); + pci_dma_sync_single_for_device(lp->pci_dev, + lp->rx_dma_addr[entry], + PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); + } + lp->stats.rx_bytes += skb->len; + skb->protocol=eth_type_trans(skb,dev); + netif_rx(skb); + dev->last_rx = jiffies; + lp->stats.rx_packets++; + } + } + /* + * The docs say that the buffer length isn't touched, but Andrew Boyd + * of QNX reports that some revs of the 79C965 clear it. + */ + lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ); + wmb(); /* Make sure owner changes after all others are visible */ + lp->rx_ring[entry].status |= le16_to_cpu(0x8000); + entry = (++lp->cur_rx) & lp->rx_mod_mask; + if (--boguscnt <= 0) break; /* don't stay in loop forever */ + } + + return 0; } -static int pcnet32_close(struct net_device *dev) +static int +pcnet32_close(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; - struct pcnet32_private *lp = dev->priv; - int i; - unsigned long flags; + unsigned long ioaddr = dev->base_addr; + struct pcnet32_private *lp = dev->priv; + int i; + unsigned long flags; - del_timer_sync(&lp->watchdog_timer); + del_timer_sync(&lp->watchdog_timer); - netif_stop_queue(dev); + netif_stop_queue(dev); - spin_lock_irqsave(&lp->lock, flags); + spin_lock_irqsave(&lp->lock, flags); - lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112); + lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112); - if (netif_msg_ifdown(lp)) - printk(KERN_DEBUG - "%s: Shutting down ethercard, status was %2.2x.\n", - dev->name, lp->a.read_csr(ioaddr, 0)); + if (netif_msg_ifdown(lp)) + printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", + dev->name, lp->a.read_csr (ioaddr, 0)); - /* We stop the PCNET32 here -- it occasionally polls memory if we don't. */ - lp->a.write_csr(ioaddr, 0, 0x0004); + /* We stop the PCNET32 here -- it occasionally polls memory if we don't. */ + lp->a.write_csr (ioaddr, 0, 0x0004); - /* - * Switch back to 16bit mode to avoid problems with dumb - * DOS packet driver after a warm reboot - */ - lp->a.write_bcr(ioaddr, 20, 4); + /* + * Switch back to 16bit mode to avoid problems with dumb + * DOS packet driver after a warm reboot + */ + lp->a.write_bcr (ioaddr, 20, 4); - spin_unlock_irqrestore(&lp->lock, flags); + spin_unlock_irqrestore(&lp->lock, flags); - free_irq(dev->irq, dev); + free_irq(dev->irq, dev); - spin_lock_irqsave(&lp->lock, flags); + spin_lock_irqsave(&lp->lock, flags); - /* free all allocated skbuffs */ - for (i = 0; i < lp->rx_ring_size; i++) { - lp->rx_ring[i].status = 0; - wmb(); /* Make sure adapter sees owner change */ - if (lp->rx_skbuff[i]) { - pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], - PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); - dev_kfree_skb(lp->rx_skbuff[i]); - } - lp->rx_skbuff[i] = NULL; - lp->rx_dma_addr[i] = 0; + /* free all allocated skbuffs */ + for (i = 0; i < lp->rx_ring_size; i++) { + lp->rx_ring[i].status = 0; + wmb(); /* Make sure adapter sees owner change */ + if (lp->rx_skbuff[i]) { + pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); + dev_kfree_skb(lp->rx_skbuff[i]); } + lp->rx_skbuff[i] = NULL; + lp->rx_dma_addr[i] = 0; + } - for (i = 0; i < lp->tx_ring_size; i++) { - lp->tx_ring[i].status = 0; /* CPU owns buffer */ - wmb(); /* Make sure adapter sees owner change */ - if (lp->tx_skbuff[i]) { - pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], - lp->tx_skbuff[i]->len, - PCI_DMA_TODEVICE); - dev_kfree_skb(lp->tx_skbuff[i]); - } - lp->tx_skbuff[i] = NULL; - lp->tx_dma_addr[i] = 0; + for (i = 0; i < lp->tx_ring_size; i++) { + lp->tx_ring[i].status = 0; /* CPU owns buffer */ + wmb(); /* Make sure adapter sees owner change */ + if (lp->tx_skbuff[i]) { + pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], + lp->tx_skbuff[i]->len, PCI_DMA_TODEVICE); + dev_kfree_skb(lp->tx_skbuff[i]); } + lp->tx_skbuff[i] = NULL; + lp->tx_dma_addr[i] = 0; + } - spin_unlock_irqrestore(&lp->lock, flags); + spin_unlock_irqrestore(&lp->lock, flags); - return 0; + return 0; } -static struct net_device_stats *pcnet32_get_stats(struct net_device *dev) +static struct net_device_stats * +pcnet32_get_stats(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; - u16 saved_addr; - unsigned long flags; - - spin_lock_irqsave(&lp->lock, flags); - saved_addr = lp->a.read_rap(ioaddr); - lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112); - lp->a.write_rap(ioaddr, saved_addr); - spin_unlock_irqrestore(&lp->lock, flags); - - return &lp->stats; + struct pcnet32_private *lp = dev->priv; + unsigned long ioaddr = dev->base_addr; + u16 saved_addr; + unsigned long flags; + + spin_lock_irqsave(&lp->lock, flags); + saved_addr = lp->a.read_rap(ioaddr); + lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112); + lp->a.write_rap(ioaddr, saved_addr); + spin_unlock_irqrestore(&lp->lock, flags); + + return &lp->stats; } /* taken from the sunlance driver, which it took from the depca driver */ -static void pcnet32_load_multicast(struct net_device *dev) +static void pcnet32_load_multicast (struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - volatile struct pcnet32_init_block *ib = &lp->init_block; - volatile u16 *mcast_table = (u16 *) & ib->filter; - struct dev_mc_list *dmi = dev->mc_list; - char *addrs; - int i; - u32 crc; - - /* set all multicast bits */ - if (dev->flags & IFF_ALLMULTI) { - ib->filter[0] = 0xffffffff; - ib->filter[1] = 0xffffffff; - return; - } - /* clear the multicast filter */ - ib->filter[0] = 0; - ib->filter[1] = 0; - - /* Add addresses */ - for (i = 0; i < dev->mc_count; i++) { - addrs = dmi->dmi_addr; - dmi = dmi->next; - - /* multicast address? */ - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); - crc = crc >> 26; - mcast_table[crc >> 4] = - le16_to_cpu(le16_to_cpu(mcast_table[crc >> 4]) | - (1 << (crc & 0xf))); - } + struct pcnet32_private *lp = dev->priv; + volatile struct pcnet32_init_block *ib = &lp->init_block; + volatile u16 *mcast_table = (u16 *)&ib->filter; + struct dev_mc_list *dmi=dev->mc_list; + char *addrs; + int i; + u32 crc; + + /* set all multicast bits */ + if (dev->flags & IFF_ALLMULTI) { + ib->filter[0] = 0xffffffff; + ib->filter[1] = 0xffffffff; return; + } + /* clear the multicast filter */ + ib->filter[0] = 0; + ib->filter[1] = 0; + + /* Add addresses */ + for (i = 0; i < dev->mc_count; i++) { + addrs = dmi->dmi_addr; + dmi = dmi->next; + + /* multicast address? */ + if (!(*addrs & 1)) + continue; + + crc = ether_crc_le(6, addrs); + crc = crc >> 26; + mcast_table [crc >> 4] = le16_to_cpu( + le16_to_cpu(mcast_table [crc >> 4]) | (1 << (crc & 0xf))); + } + return; } + /* * Set or clear the multicast filter for this adaptor. */ static void pcnet32_set_multicast_list(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr, flags; - struct pcnet32_private *lp = dev->priv; - - spin_lock_irqsave(&lp->lock, flags); - if (dev->flags & IFF_PROMISC) { - /* Log any net taps. */ - if (netif_msg_hw(lp)) - printk(KERN_INFO "%s: Promiscuous mode enabled.\n", - dev->name); - lp->init_block.mode = - le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) << - 7); - } else { - lp->init_block.mode = - le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); - pcnet32_load_multicast(dev); - } - - lp->a.write_csr(ioaddr, 0, 0x0004); /* Temporarily stop the lance. */ - pcnet32_restart(dev, 0x0042); /* Resume normal operation */ - netif_wake_queue(dev); - - spin_unlock_irqrestore(&lp->lock, flags); + unsigned long ioaddr = dev->base_addr, flags; + struct pcnet32_private *lp = dev->priv; + + spin_lock_irqsave(&lp->lock, flags); + if (dev->flags&IFF_PROMISC) { + /* Log any net taps. */ + if (netif_msg_hw(lp)) + printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name); + lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) << 7); + } else { + lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); + pcnet32_load_multicast (dev); + } + + lp->a.write_csr (ioaddr, 0, 0x0004); /* Temporarily stop the lance. */ + pcnet32_restart(dev, 0x0042); /* Resume normal operation */ + netif_wake_queue(dev); + + spin_unlock_irqrestore(&lp->lock, flags); } /* This routine assumes that the lp->lock is held */ static int mdio_read(struct net_device *dev, int phy_id, int reg_num) { - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; - u16 val_out; + struct pcnet32_private *lp = dev->priv; + unsigned long ioaddr = dev->base_addr; + u16 val_out; - if (!lp->mii) - return 0; + if (!lp->mii) + return 0; - lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); - val_out = lp->a.read_bcr(ioaddr, 34); + lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); + val_out = lp->a.read_bcr(ioaddr, 34); - return val_out; + return val_out; } /* This routine assumes that the lp->lock is held */ static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val) { - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; + struct pcnet32_private *lp = dev->priv; + unsigned long ioaddr = dev->base_addr; - if (!lp->mii) - return; + if (!lp->mii) + return; - lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); - lp->a.write_bcr(ioaddr, 34, val); + lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); + lp->a.write_bcr(ioaddr, 34, val); } static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct pcnet32_private *lp = dev->priv; - int rc; - unsigned long flags; - - /* SIOC[GS]MIIxxx ioctls */ - if (lp->mii) { - spin_lock_irqsave(&lp->lock, flags); - rc = generic_mii_ioctl(&lp->mii_if, if_mii(rq), cmd, NULL); - spin_unlock_irqrestore(&lp->lock, flags); - } else { - rc = -EOPNOTSUPP; - } - - return rc; -} - -static int pcnet32_check_otherphy(struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - struct mii_if_info mii = lp->mii_if; - u16 bmcr; - int i; - - for (i = 0; i < PCNET32_MAX_PHYS; i++) { - if (i == lp->mii_if.phy_id) - continue; /* skip active phy */ - if (lp->phymask & (1 << i)) { - mii.phy_id = i; - if (mii_link_ok(&mii)) { - /* found PHY with active link */ - if (netif_msg_link(lp)) - printk(KERN_INFO - "%s: Using PHY number %d.\n", - dev->name, i); - - /* isolate inactive phy */ - bmcr = - mdio_read(dev, lp->mii_if.phy_id, MII_BMCR); - mdio_write(dev, lp->mii_if.phy_id, MII_BMCR, - bmcr | BMCR_ISOLATE); - - /* de-isolate new phy */ - bmcr = mdio_read(dev, i, MII_BMCR); - mdio_write(dev, i, MII_BMCR, - bmcr & ~BMCR_ISOLATE); - - /* set new phy address */ - lp->mii_if.phy_id = i; - return 1; - } - } - } - return 0; -} - -/* - * Show the status of the media. Similar to mii_check_media however it - * correctly shows the link speed for all (tested) pcnet32 variants. - * Devices with no mii just report link state without speed. - * - * Caller is assumed to hold and release the lp->lock. - */ + struct pcnet32_private *lp = dev->priv; + int rc; + unsigned long flags; -static void pcnet32_check_media(struct net_device *dev, int verbose) -{ - struct pcnet32_private *lp = dev->priv; - int curr_link; - int prev_link = netif_carrier_ok(dev) ? 1 : 0; - u32 bcr9; + /* SIOC[GS]MIIxxx ioctls */ + if (lp->mii) { + spin_lock_irqsave(&lp->lock, flags); + rc = generic_mii_ioctl(&lp->mii_if, if_mii(rq), cmd, NULL); + spin_unlock_irqrestore(&lp->lock, flags); + } else { + rc = -EOPNOTSUPP; + } - if (lp->mii) { - curr_link = mii_link_ok(&lp->mii_if); - } else { - ulong ioaddr = dev->base_addr; /* card base I/O address */ - curr_link = (lp->a.read_bcr(ioaddr, 4) != 0xc0); - } - if (!curr_link) { - if (prev_link || verbose) { - netif_carrier_off(dev); - if (netif_msg_link(lp)) - printk(KERN_INFO "%s: link down\n", dev->name); - } - if (lp->phycount > 1) { - curr_link = pcnet32_check_otherphy(dev); - prev_link = 0; - } - } else if (verbose || !prev_link) { - netif_carrier_on(dev); - if (lp->mii) { - if (netif_msg_link(lp)) { - struct ethtool_cmd ecmd; - mii_ethtool_gset(&lp->mii_if, &ecmd); - printk(KERN_INFO - "%s: link up, %sMbps, %s-duplex\n", - dev->name, - (ecmd.speed == SPEED_100) ? "100" : "10", - (ecmd.duplex == - DUPLEX_FULL) ? "full" : "half"); - } - bcr9 = lp->a.read_bcr(dev->base_addr, 9); - if ((bcr9 & (1 << 0)) != lp->mii_if.full_duplex) { - if (lp->mii_if.full_duplex) - bcr9 |= (1 << 0); - else - bcr9 &= ~(1 << 0); - lp->a.write_bcr(dev->base_addr, 9, bcr9); - } - } else { - if (netif_msg_link(lp)) - printk(KERN_INFO "%s: link up\n", dev->name); - } - } + return rc; } -/* - * Check for loss of link and link establishment. - * Can not use mii_check_media because it does nothing if mode is forced. - */ - static void pcnet32_watchdog(struct net_device *dev) { - struct pcnet32_private *lp = dev->priv; - unsigned long flags; + struct pcnet32_private *lp = dev->priv; + unsigned long flags; - /* Print the link status if it has changed */ + /* Print the link status if it has changed */ + if (lp->mii) { spin_lock_irqsave(&lp->lock, flags); - pcnet32_check_media(dev, 0); + mii_check_media (&lp->mii_if, netif_msg_link(lp), 0); spin_unlock_irqrestore(&lp->lock, flags); + } - mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); + mod_timer (&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); } static void __devexit pcnet32_remove_one(struct pci_dev *pdev) { - struct net_device *dev = pci_get_drvdata(pdev); - - if (dev) { - struct pcnet32_private *lp = dev->priv; - - unregister_netdev(dev); - pcnet32_free_ring(dev); - release_region(dev->base_addr, PCNET32_TOTAL_SIZE); - pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - free_netdev(dev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - } + struct net_device *dev = pci_get_drvdata(pdev); + + if (dev) { + struct pcnet32_private *lp = dev->priv; + + unregister_netdev(dev); + pcnet32_free_ring(dev); + release_region(dev->base_addr, PCNET32_TOTAL_SIZE); + pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); + free_netdev(dev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + } } static struct pci_driver pcnet32_driver = { - .name = DRV_NAME, - .probe = pcnet32_probe_pci, - .remove = __devexit_p(pcnet32_remove_one), - .id_table = pcnet32_pci_tbl, + .name = DRV_NAME, + .probe = pcnet32_probe_pci, + .remove = __devexit_p(pcnet32_remove_one), + .id_table = pcnet32_pci_tbl, }; /* An additional parameter that may be passed in... */ @@ -2696,11 +2477,9 @@ static int pcnet32_have_pci; module_param(debug, int, 0); MODULE_PARM_DESC(debug, DRV_NAME " debug level"); module_param(max_interrupt_work, int, 0); -MODULE_PARM_DESC(max_interrupt_work, - DRV_NAME " maximum events handled per interrupt"); +MODULE_PARM_DESC(max_interrupt_work, DRV_NAME " maximum events handled per interrupt"); module_param(rx_copybreak, int, 0); -MODULE_PARM_DESC(rx_copybreak, - DRV_NAME " copy breakpoint for copy-only-tiny-frames"); +MODULE_PARM_DESC(rx_copybreak, DRV_NAME " copy breakpoint for copy-only-tiny-frames"); module_param(tx_start_pt, int, 0); MODULE_PARM_DESC(tx_start_pt, DRV_NAME " transmit start point (0-3)"); module_param(pcnet32vlb, int, 0); @@ -2711,9 +2490,7 @@ module_param_array(full_duplex, int, NULL, 0); MODULE_PARM_DESC(full_duplex, DRV_NAME " full duplex setting(s) (1)"); /* Module Parameter for HomePNA cards added by Patrick Simmons, 2004 */ module_param_array(homepna, int, NULL, 0); -MODULE_PARM_DESC(homepna, - DRV_NAME - " mode for 79C978 cards (1 for HomePNA, 0 for Ethernet, default Ethernet"); +MODULE_PARM_DESC(homepna, DRV_NAME " mode for 79C978 cards (1 for HomePNA, 0 for Ethernet, default Ethernet"); MODULE_AUTHOR("Thomas Bogendoerfer"); MODULE_DESCRIPTION("Driver for PCnet32 and PCnetPCI based ethercards"); @@ -2723,44 +2500,44 @@ MODULE_LICENSE("GPL"); static int __init pcnet32_init_module(void) { - printk(KERN_INFO "%s", version); + printk(KERN_INFO "%s", version); - pcnet32_debug = netif_msg_init(debug, PCNET32_MSG_DEFAULT); + pcnet32_debug = netif_msg_init(debug, PCNET32_MSG_DEFAULT); - if ((tx_start_pt >= 0) && (tx_start_pt <= 3)) - tx_start = tx_start_pt; + if ((tx_start_pt >= 0) && (tx_start_pt <= 3)) + tx_start = tx_start_pt; - /* find the PCI devices */ - if (!pci_module_init(&pcnet32_driver)) - pcnet32_have_pci = 1; + /* find the PCI devices */ + if (!pci_module_init(&pcnet32_driver)) + pcnet32_have_pci = 1; - /* should we find any remaining VLbus devices ? */ - if (pcnet32vlb) - pcnet32_probe_vlbus(); + /* should we find any remaining VLbus devices ? */ + if (pcnet32vlb) + pcnet32_probe_vlbus(); - if (cards_found && (pcnet32_debug & NETIF_MSG_PROBE)) - printk(KERN_INFO PFX "%d cards_found.\n", cards_found); + if (cards_found && (pcnet32_debug & NETIF_MSG_PROBE)) + printk(KERN_INFO PFX "%d cards_found.\n", cards_found); - return (pcnet32_have_pci + cards_found) ? 0 : -ENODEV; + return (pcnet32_have_pci + cards_found) ? 0 : -ENODEV; } static void __exit pcnet32_cleanup_module(void) { - struct net_device *next_dev; - - while (pcnet32_dev) { - struct pcnet32_private *lp = pcnet32_dev->priv; - next_dev = lp->next; - unregister_netdev(pcnet32_dev); - pcnet32_free_ring(pcnet32_dev); - release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); - pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - free_netdev(pcnet32_dev); - pcnet32_dev = next_dev; - } + struct net_device *next_dev; + + while (pcnet32_dev) { + struct pcnet32_private *lp = pcnet32_dev->priv; + next_dev = lp->next; + unregister_netdev(pcnet32_dev); + pcnet32_free_ring(pcnet32_dev); + release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); + pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); + free_netdev(pcnet32_dev); + pcnet32_dev = next_dev; + } - if (pcnet32_have_pci) - pci_unregister_driver(&pcnet32_driver); + if (pcnet32_have_pci) + pci_unregister_driver(&pcnet32_driver); } module_init(pcnet32_init_module); diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 1b236bdf6..459443b57 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -60,10 +60,8 @@ int mdiobus_register(struct mii_bus *bus) for (i = 0; i < PHY_MAX_ADDR; i++) { struct phy_device *phydev; - if (bus->phy_mask & (1 << i)) { - bus->phy_map[i] = NULL; + if (bus->phy_mask & (1 << i)) continue; - } phydev = get_phy_device(bus, i); diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 33cec2dab..1474b7c5a 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -132,7 +132,7 @@ struct phy_setting { }; /* A mapping of all SUPPORTED settings to speed/duplex */ -static const struct phy_setting settings[] = { +static struct phy_setting settings[] = { { .speed = 10000, .duplex = DUPLEX_FULL, diff --git a/drivers/net/plip.c b/drivers/net/plip.c index d4449d6d1..87ee3271b 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -123,7 +123,7 @@ static const char version[] = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n" #ifndef NET_DEBUG #define NET_DEBUG 1 #endif -static const unsigned int net_debug = NET_DEBUG; +static unsigned int net_debug = NET_DEBUG; #define ENABLE(irq) if (irq != -1) enable_irq(irq) #define DISABLE(irq) if (irq != -1) disable_irq(irq) @@ -351,7 +351,7 @@ static int plip_bh_timeout_error(struct net_device *dev, struct net_local *nl, typedef int (*plip_func)(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv); -static const plip_func connection_state_table[] = +static plip_func connection_state_table[] = { plip_none, plip_receive_packet, diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 23659fd7c..aa6540b39 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -571,7 +570,7 @@ ppp_async_encode(struct asyncppp *ap) * character if necessary. */ if (islcp || flag_time == 0 - || time_after_eq(jiffies, ap->last_xmit + flag_time)) + || jiffies - ap->last_xmit >= flag_time) *buf++ = PPP_FLAG; ap->last_xmit = jiffies; fcs = PPP_INITFCS; diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index b2073fce8..0245e40b5 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -199,11 +198,11 @@ static unsigned int cardmap_find_first_free(struct cardmap *map); static void cardmap_destroy(struct cardmap **map); /* - * all_ppp_mutex protects the all_ppp_units mapping. + * all_ppp_sem protects the all_ppp_units mapping. * It also ensures that finding a ppp unit in the all_ppp_units map * and updating its file.refcnt field is atomic. */ -static DEFINE_MUTEX(all_ppp_mutex); +static DECLARE_MUTEX(all_ppp_sem); static struct cardmap *all_ppp_units; static atomic_t ppp_unit_count = ATOMIC_INIT(0); @@ -805,7 +804,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, /* Attach to an existing ppp unit */ if (get_user(unit, p)) break; - mutex_lock(&all_ppp_mutex); + down(&all_ppp_sem); err = -ENXIO; ppp = ppp_find_unit(unit); if (ppp != 0) { @@ -813,7 +812,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, file->private_data = &ppp->file; err = 0; } - mutex_unlock(&all_ppp_mutex); + up(&all_ppp_sem); break; case PPPIOCATTCHAN: @@ -1692,8 +1691,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) || ppp->npmode[npi] != NPMODE_PASS) { kfree_skb(skb); } else { - /* chop off protocol */ - skb_pull_rcsum(skb, 2); + skb_pull(skb, 2); /* chop off protocol */ + skb_postpull_rcsum(skb, skb->data - 2, 2); skb->dev = ppp->dev; skb->protocol = htons(npindex_to_ethertype[npi]); skb->mac.raw = skb->data; @@ -2447,7 +2446,7 @@ ppp_create_interface(int unit, int *retp) dev->do_ioctl = ppp_net_ioctl; ret = -EEXIST; - mutex_lock(&all_ppp_mutex); + down(&all_ppp_sem); if (unit < 0) unit = cardmap_find_first_free(all_ppp_units); else if (cardmap_get(all_ppp_units, unit) != NULL) @@ -2466,12 +2465,12 @@ ppp_create_interface(int unit, int *retp) atomic_inc(&ppp_unit_count); cardmap_set(&all_ppp_units, unit, ppp); - mutex_unlock(&all_ppp_mutex); + up(&all_ppp_sem); *retp = 0; return ppp; out2: - mutex_unlock(&all_ppp_mutex); + up(&all_ppp_sem); free_netdev(dev); out1: kfree(ppp); @@ -2501,7 +2500,7 @@ static void ppp_shutdown_interface(struct ppp *ppp) { struct net_device *dev; - mutex_lock(&all_ppp_mutex); + down(&all_ppp_sem); ppp_lock(ppp); dev = ppp->dev; ppp->dev = NULL; @@ -2515,7 +2514,7 @@ static void ppp_shutdown_interface(struct ppp *ppp) ppp->file.dead = 1; ppp->owner = NULL; wake_up_interruptible(&ppp->file.rwait); - mutex_unlock(&all_ppp_mutex); + up(&all_ppp_sem); } /* @@ -2557,7 +2556,7 @@ static void ppp_destroy_interface(struct ppp *ppp) /* * Locate an existing ppp unit. - * The caller should have locked the all_ppp_mutex. + * The caller should have locked the all_ppp_sem. */ static struct ppp * ppp_find_unit(int unit) @@ -2602,7 +2601,7 @@ ppp_connect_channel(struct channel *pch, int unit) int ret = -ENXIO; int hdrlen; - mutex_lock(&all_ppp_mutex); + down(&all_ppp_sem); ppp = ppp_find_unit(unit); if (ppp == 0) goto out; @@ -2627,7 +2626,7 @@ ppp_connect_channel(struct channel *pch, int unit) outl: write_unlock_bh(&pch->upl); out: - mutex_unlock(&all_ppp_mutex); + up(&all_ppp_sem); return ret; } diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 33255fe80..33cb8254e 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -108,7 +108,7 @@ static void ppp_print_hex (register __u8 * out, const __u8 * in, int count) { register __u8 next_ch; - static const char hex[] = "0123456789ABCDEF"; + static char hex[] = "0123456789ABCDEF"; while (count-- > 0) { next_ch = *in++; diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 0d101a180..e023b38e3 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -337,7 +337,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) if (sk->sk_state & PPPOX_BOUND) { struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw; int len = ntohs(ph->length); - skb_pull_rcsum(skb, sizeof(struct pppoe_hdr)); + skb_pull(skb, sizeof(struct pppoe_hdr)); + skb_postpull_rcsum(skb, ph, sizeof(*ph)); if (pskb_trim_rcsum(skb, len)) goto abort_kfree; @@ -600,6 +601,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.hdrlen = (sizeof(struct pppoe_hdr) + dev->hard_header_len); + po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr); po->chan.private = sk; po->chan.ops = &pppoe_chan_ops; @@ -861,9 +863,6 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) * give dev_queue_xmit something it can free. */ skb2 = skb_clone(skb, GFP_ATOMIC); - - if (skb2 == NULL) - goto abort; } ph = (struct pppoe_hdr *) skb_push(skb2, sizeof(struct pppoe_hdr)); diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 43641dd2c..78c532df4 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -113,11 +113,11 @@ static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; static int num_media = 0; /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ -static const int max_interrupt_work = 20; +static int max_interrupt_work = 20; /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). The RTL chips use a 64 element hash table based on the Ethernet CRC. */ -static const int multicast_filter_limit = 32; +static int multicast_filter_limit = 32; /* MAC address length */ #define MAC_ADDR_LEN 6 @@ -194,6 +194,7 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); static int rx_copybreak = 200; static int use_dac; +static int ignore_parity_err; static struct { u32 msg_enable; } debug = { -1 }; @@ -256,10 +257,11 @@ enum RTL8169_register_content { RxOK = 0x01, /* RxStatusDesc */ - RxRES = 0x00200000, - RxCRC = 0x00080000, - RxRUNT = 0x00100000, - RxRWT = 0x00400000, + RxFOVF = (1 << 23), + RxRWT = (1 << 22), + RxRES = (1 << 21), + RxRUNT = (1 << 20), + RxCRC = (1 << 19), /* ChipCmdBits */ CmdReset = 0x10, @@ -460,6 +462,8 @@ module_param(use_dac, int, 0); MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); module_param_named(debug, debug.msg_enable, int, 0); MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); +module_param_named(ignore_parity_err, ignore_parity_err, bool, 0); +MODULE_PARM_DESC(ignore_parity_err, "Ignore PCI parity error as target. Default: false"); MODULE_LICENSE("GPL"); MODULE_VERSION(RTL8169_VERSION); @@ -2171,7 +2175,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) { if (dev->features & NETIF_F_TSO) { - u32 mss = skb_shinfo(skb)->gso_size; + u32 mss = skb_shinfo(skb)->tso_size; if (mss) return LargeSend | ((mss & MSSMask) << MSSShift); @@ -2288,12 +2292,17 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) /* * The recovery sequence below admits a very elaborated explanation: * - it seems to work; - * - I did not see what else could be done. + * - I did not see what else could be done; + * - it makes iop3xx happy. * * Feel free to adjust to your needs. */ - pci_write_config_word(pdev, PCI_COMMAND, - pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY); + if (ignore_parity_err) + pci_cmd &= ~PCI_COMMAND_PARITY; + else + pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY; + + pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); pci_write_config_word(pdev, PCI_STATUS, pci_status & (PCI_STATUS_DETECTED_PARITY | @@ -2307,10 +2316,11 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) tp->cp_cmd &= ~PCIDAC; RTL_W16(CPlusCmd, tp->cp_cmd); dev->features &= ~NETIF_F_HIGHDMA; - rtl8169_schedule_work(dev, rtl8169_reinit_task); } rtl8169_hw_reset(ioaddr); + + rtl8169_schedule_work(dev, rtl8169_reinit_task); } static void @@ -2435,6 +2445,10 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, tp->stats.rx_length_errors++; if (status & RxCRC) tp->stats.rx_crc_errors++; + if (status & RxFOVF) { + rtl8169_schedule_work(dev, rtl8169_reset_task); + tp->stats.rx_fifo_errors++; + } rtl8169_mark_to_asic(desc, tp->rx_buf_sz); } else { struct sk_buff *skb = tp->Rx_skbuff[entry]; @@ -2614,6 +2628,7 @@ static void rtl8169_down(struct net_device *dev) struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; unsigned int poll_locked = 0; + unsigned int intrmask; rtl8169_delete_timer(dev); @@ -2652,8 +2667,11 @@ core_down: * 2) dev->change_mtu * -> rtl8169_poll can not be issued again and re-enable the * interruptions. Let's simply issue the IRQ down sequence again. + * + * No loop if hotpluged or major error (0xffff). */ - if (RTL_R16(IntrMask)) + intrmask = RTL_R16(IntrMask); + if (intrmask && (intrmask != 0xffff)) goto core_down; rtl8169_tx_clear(tp); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 0ad01f07e..b7f00d6eb 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -57,27 +57,23 @@ #include #include #include -#include -#include -#include #include #include #include -#include /* local include */ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.11.2" +#define DRV_VERSION "Version 2.0.9.4" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; static char s2io_driver_version[] = DRV_VERSION; -static int rxd_size[4] = {32,48,48,64}; -static int rxd_count[4] = {127,85,85,63}; +int rxd_size[4] = {32,48,48,64}; +int rxd_count[4] = {127,85,85,63}; static inline int RXD_IS_UP2DT(RxD_t *rxdp) { @@ -172,11 +168,6 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { {"\n DRIVER STATISTICS"}, {"single_bit_ecc_errs"}, {"double_bit_ecc_errs"}, - ("lro_aggregated_pkts"), - ("lro_flush_both_count"), - ("lro_out_of_sequence_pkts"), - ("lro_flush_due_to_max_pkts"), - ("lro_avg_aggr_pkts"), }; #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN @@ -223,7 +214,7 @@ static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) #define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL #define END_SIGN 0x0 -static const u64 herc_act_dtx_cfg[] = { +static u64 herc_act_dtx_cfg[] = { /* Set address */ 0x8000051536750000ULL, 0x80000515367500E0ULL, /* Write data */ @@ -244,7 +235,7 @@ static const u64 herc_act_dtx_cfg[] = { END_SIGN }; -static const u64 xena_mdio_cfg[] = { +static u64 xena_mdio_cfg[] = { /* Reset PMA PLL */ 0xC001010000000000ULL, 0xC0010100000000E0ULL, 0xC0010100008000E4ULL, @@ -254,7 +245,7 @@ static const u64 xena_mdio_cfg[] = { END_SIGN }; -static const u64 xena_dtx_cfg[] = { +static u64 xena_dtx_cfg[] = { 0x8000051500000000ULL, 0x80000515000000E0ULL, 0x80000515D93500E4ULL, 0x8001051500000000ULL, 0x80010515000000E0ULL, 0x80010515001E00E4ULL, @@ -282,7 +273,7 @@ static const u64 xena_dtx_cfg[] = { * Constants for Fixing the MacAddress problem seen mostly on * Alpha machines. */ -static const u64 fix_mac[] = { +static u64 fix_mac[] = { 0x0060000000000000ULL, 0x0060600000000000ULL, 0x0040600000000000ULL, 0x0000600000000000ULL, 0x0020600000000000ULL, 0x0060600000000000ULL, @@ -326,12 +317,6 @@ static unsigned int indicate_max_pkts; static unsigned int rxsync_frequency = 3; /* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ static unsigned int intr_type = 0; -/* Large receive offload feature */ -static unsigned int lro = 0; -/* Max pkts to be aggregated by LRO at one time. If not specified, - * aggregation happens until we hit max IP pkt size(64K) - */ -static unsigned int lro_max_pkts = 0xFFFF; /* * S2IO device table. @@ -1491,19 +1476,6 @@ static int init_nic(struct s2io_nic *nic) writel((u32) (val64 >> 32), (add + 4)); val64 = readq(&bar0->mac_cfg); - /* Enable FCS stripping by adapter */ - add = &bar0->mac_cfg; - val64 = readq(&bar0->mac_cfg); - val64 |= MAC_CFG_RMAC_STRIP_FCS; - if (nic->device_type == XFRAME_II_DEVICE) - writeq(val64, &bar0->mac_cfg); - else { - writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); - writel((u32) (val64), add); - writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); - writel((u32) (val64 >> 32), (add + 4)); - } - /* * Set the time value to be inserted in the pause frame * generated by xena. @@ -2155,7 +2127,7 @@ static void stop_nic(struct s2io_nic *nic) } } -static int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) +int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) { struct net_device *dev = nic->dev; struct sk_buff *frag_list; @@ -2597,8 +2569,6 @@ static void rx_intr_handler(ring_info_t *ring_data) #ifndef CONFIG_S2IO_NAPI int pkt_cnt = 0; #endif - int i; - spin_lock(&nic->rx_lock); if (atomic_read(&nic->card_state) == CARD_DOWN) { DBG_PRINT(INTR_DBG, "%s: %s going down for reset\n", @@ -2691,18 +2661,6 @@ static void rx_intr_handler(ring_info_t *ring_data) break; #endif } - if (nic->lro) { - /* Clear all LRO sessions before exiting */ - for (i=0; ilro0_n[i]; - if (lro->in_use) { - update_L3L4_header(nic, lro); - queue_rx_frame(lro->parent); - clear_lro_session(lro); - } - } - } - spin_unlock(&nic->rx_lock); } @@ -2894,7 +2852,7 @@ static int wait_for_cmd_complete(nic_t * sp) * void. */ -static void s2io_reset(nic_t * sp) +void s2io_reset(nic_t * sp) { XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64; @@ -2982,7 +2940,7 @@ static void s2io_reset(nic_t * sp) * SUCCESS on success and FAILURE on failure. */ -static int s2io_set_swapper(nic_t * sp) +int s2io_set_swapper(nic_t * sp) { struct net_device *dev = sp->dev; XENA_dev_config_t __iomem *bar0 = sp->bar0; @@ -3131,7 +3089,7 @@ static int wait_for_msix_trans(nic_t *nic, int i) return ret; } -static void restore_xmsi_data(nic_t *nic) +void restore_xmsi_data(nic_t *nic) { XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64; @@ -3222,7 +3180,7 @@ int s2io_enable_msi(nic_t *nic) return 0; } -static int s2io_enable_msi_x(nic_t *nic) +int s2io_enable_msi_x(nic_t *nic) { XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 tx_mat, rx_mat; @@ -3564,8 +3522,8 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Control_1 = 0; txdp->Control_2 = 0; #ifdef NETIF_F_TSO - mss = skb_shinfo(skb)->gso_size; - if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) { + mss = skb_shinfo(skb)->tso_size; + if (mss) { txdp->Control_1 |= TXD_TCP_LSO_EN; txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); } @@ -3585,10 +3543,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) } frg_len = skb->len - skb->data_len; - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) { + if (skb_shinfo(skb)->ufo_size) { int ufo_size; - ufo_size = skb_shinfo(skb)->gso_size; + ufo_size = skb_shinfo(skb)->ufo_size; ufo_size &= ~7; txdp->Control_1 |= TXD_UFO_EN; txdp->Control_1 |= TXD_UFO_MSS(ufo_size); @@ -3614,7 +3572,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) + if (skb_shinfo(skb)->ufo_size) txdp->Control_1 |= TXD_UFO_EN; frg_cnt = skb_shinfo(skb)->nr_frags; @@ -3629,12 +3587,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) (sp->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) + if (skb_shinfo(skb)->ufo_size) txdp->Control_1 |= TXD_UFO_EN; } txdp->Control_1 |= TXD_GATHER_CODE_LAST; - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) + if (skb_shinfo(skb)->ufo_size) frg_cnt++; /* as Txd0 was used for inband header */ tx_fifo = mac_control->tx_FIFO_start[queue]; @@ -3648,7 +3606,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) if (mss) val64 |= TX_FIFO_SPECIAL_FUNC; #endif - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) + if (skb_shinfo(skb)->ufo_size) val64 |= TX_FIFO_SPECIAL_FUNC; writeq(val64, &tx_fifo->List_Control); @@ -3710,32 +3668,23 @@ s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) * else schedule a tasklet to reallocate the buffers. */ for (i = 0; i < config->rx_ring_num; i++) { - if (!sp->lro) { - int rxb_size = atomic_read(&sp->rx_bufs_left[i]); - int level = rx_buffer_level(sp, rxb_size, i); - - if ((level == PANIC) && (!TASKLET_IN_USE)) { - DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", - dev->name); - DBG_PRINT(INTR_DBG, "PANIC levels\n"); - if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", - dev->name); - DBG_PRINT(ERR_DBG, " in ISR!!\n"); - clear_bit(0, (&sp->tasklet_status)); - atomic_dec(&sp->isr_cnt); - return IRQ_HANDLED; - } + int rxb_size = atomic_read(&sp->rx_bufs_left[i]); + int level = rx_buffer_level(sp, rxb_size, i); + + if ((level == PANIC) && (!TASKLET_IN_USE)) { + DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name); + DBG_PRINT(INTR_DBG, "PANIC levels\n"); + if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", + dev->name); + DBG_PRINT(ERR_DBG, " in ISR!!\n"); clear_bit(0, (&sp->tasklet_status)); - } else if (level == LOW) { - tasklet_schedule(&sp->task); + atomic_dec(&sp->isr_cnt); + return IRQ_HANDLED; } - } - else if (fill_rx_buffers(sp, i) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", - dev->name); - DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); - break; + clear_bit(0, (&sp->tasklet_status)); + } else if (level == LOW) { + tasklet_schedule(&sp->task); } } @@ -3748,37 +3697,29 @@ s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs) { ring_info_t *ring = (ring_info_t *)dev_id; nic_t *sp = ring->nic; - struct net_device *dev = (struct net_device *) dev_id; int rxb_size, level, rng_n; atomic_inc(&sp->isr_cnt); rx_intr_handler(ring); rng_n = ring->ring_no; - if (!sp->lro) { - rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); - level = rx_buffer_level(sp, rxb_size, rng_n); - - if ((level == PANIC) && (!TASKLET_IN_USE)) { - int ret; - DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); - DBG_PRINT(INTR_DBG, "PANIC levels\n"); - if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "Out of memory in %s", - __FUNCTION__); - clear_bit(0, (&sp->tasklet_status)); - return IRQ_HANDLED; - } + rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); + level = rx_buffer_level(sp, rxb_size, rng_n); + + if ((level == PANIC) && (!TASKLET_IN_USE)) { + int ret; + DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); + DBG_PRINT(INTR_DBG, "PANIC levels\n"); + if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "Out of memory in %s", + __FUNCTION__); clear_bit(0, (&sp->tasklet_status)); - } else if (level == LOW) { - tasklet_schedule(&sp->task); + return IRQ_HANDLED; } + clear_bit(0, (&sp->tasklet_status)); + } else if (level == LOW) { + tasklet_schedule(&sp->task); } - else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); - DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); - } - atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; @@ -3934,33 +3875,24 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) */ #ifndef CONFIG_S2IO_NAPI for (i = 0; i < config->rx_ring_num; i++) { - if (!sp->lro) { - int ret; - int rxb_size = atomic_read(&sp->rx_bufs_left[i]); - int level = rx_buffer_level(sp, rxb_size, i); - - if ((level == PANIC) && (!TASKLET_IN_USE)) { - DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", - dev->name); - DBG_PRINT(INTR_DBG, "PANIC levels\n"); - if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", - dev->name); - DBG_PRINT(ERR_DBG, " in ISR!!\n"); - clear_bit(0, (&sp->tasklet_status)); - atomic_dec(&sp->isr_cnt); - return IRQ_HANDLED; - } + int ret; + int rxb_size = atomic_read(&sp->rx_bufs_left[i]); + int level = rx_buffer_level(sp, rxb_size, i); + + if ((level == PANIC) && (!TASKLET_IN_USE)) { + DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name); + DBG_PRINT(INTR_DBG, "PANIC levels\n"); + if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", + dev->name); + DBG_PRINT(ERR_DBG, " in ISR!!\n"); clear_bit(0, (&sp->tasklet_status)); - } else if (level == LOW) { - tasklet_schedule(&sp->task); + atomic_dec(&sp->isr_cnt); + return IRQ_HANDLED; } - } - else if (fill_rx_buffers(sp, i) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", - dev->name); - DBG_PRINT(ERR_DBG, " in Rx intr!!\n"); - break; + clear_bit(0, (&sp->tasklet_status)); + } else if (level == LOW) { + tasklet_schedule(&sp->task); } } #endif @@ -4197,7 +4129,7 @@ static void s2io_set_multicast(struct net_device *dev) * as defined in errno.h file on failure. */ -static int s2io_set_mac_addr(struct net_device *dev, u8 * addr) +int s2io_set_mac_addr(struct net_device *dev, u8 * addr) { nic_t *sp = dev->priv; XENA_dev_config_t __iomem *bar0 = sp->bar0; @@ -5112,7 +5044,6 @@ static void s2io_get_ethtool_stats(struct net_device *dev, int i = 0; nic_t *sp = dev->priv; StatInfo_t *stat_info = sp->mac_control.stats_info; - u64 tmp; s2io_updt_stats(sp); tmp_stats[i++] = @@ -5204,16 +5135,6 @@ static void s2io_get_ethtool_stats(struct net_device *dev, tmp_stats[i++] = 0; tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs; tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; - tmp_stats[i++] = stat_info->sw_stat.clubbed_frms_cnt; - tmp_stats[i++] = stat_info->sw_stat.sending_both; - tmp_stats[i++] = stat_info->sw_stat.outof_sequence_pkts; - tmp_stats[i++] = stat_info->sw_stat.flush_max_pkts; - tmp = 0; - if (stat_info->sw_stat.num_aggregations) { - tmp = stat_info->sw_stat.sum_avg_pkts_aggregated; - do_div(tmp, stat_info->sw_stat.num_aggregations); - } - tmp_stats[i++] = tmp; } static int s2io_ethtool_get_regs_len(struct net_device *dev) @@ -5595,14 +5516,6 @@ static int s2io_card_up(nic_t * sp) /* Setting its receive mode */ s2io_set_multicast(dev); - if (sp->lro) { - /* Initialize max aggregatable pkts based on MTU */ - sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; - /* Check if we can use(if specified) user provided value */ - if (lro_max_pkts < sp->lro_max_aggr_per_sess) - sp->lro_max_aggr_per_sess = lro_max_pkts; - } - /* Enable tasklet for the device */ tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev); @@ -5695,7 +5608,6 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) ((unsigned long) rxdp->Host_Control); int ring_no = ring_data->ring_no; u16 l3_csum, l4_csum; - lro_t *lro; skb->dev = dev; if (rxdp->Control_1 & RXD_T_CODE) { @@ -5744,8 +5656,7 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) skb_put(skb, buf2_len); } - if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!sp->lro) || - (sp->lro && (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG)))) && + if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && (sp->rx_csum)) { l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1); l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1); @@ -5756,54 +5667,6 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) * a flag in the RxD. */ skb->ip_summed = CHECKSUM_UNNECESSARY; - if (sp->lro) { - u32 tcp_len; - u8 *tcp; - int ret = 0; - - ret = s2io_club_tcp_session(skb->data, &tcp, - &tcp_len, &lro, rxdp, sp); - switch (ret) { - case 3: /* Begin anew */ - lro->parent = skb; - goto aggregate; - case 1: /* Aggregate */ - { - lro_append_pkt(sp, lro, - skb, tcp_len); - goto aggregate; - } - case 4: /* Flush session */ - { - lro_append_pkt(sp, lro, - skb, tcp_len); - queue_rx_frame(lro->parent); - clear_lro_session(lro); - sp->mac_control.stats_info-> - sw_stat.flush_max_pkts++; - goto aggregate; - } - case 2: /* Flush both */ - lro->parent->data_len = - lro->frags_len; - sp->mac_control.stats_info-> - sw_stat.sending_both++; - queue_rx_frame(lro->parent); - clear_lro_session(lro); - goto send_up; - case 0: /* sessions exceeded */ - case 5: /* - * First pkt in session not - * L3/L4 aggregatable - */ - break; - default: - DBG_PRINT(ERR_DBG, - "%s: Samadhana!!\n", - __FUNCTION__); - BUG(); - } - } } else { /* * Packet with erroneous checksum, let the @@ -5815,31 +5678,25 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) skb->ip_summed = CHECKSUM_NONE; } - if (!sp->lro) { - skb->protocol = eth_type_trans(skb, dev); + skb->protocol = eth_type_trans(skb, dev); #ifdef CONFIG_S2IO_NAPI - if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { - /* Queueing the vlan frame to the upper layer */ - vlan_hwaccel_receive_skb(skb, sp->vlgrp, - RXD_GET_VLAN_TAG(rxdp->Control_2)); - } else { - netif_receive_skb(skb); - } + if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { + /* Queueing the vlan frame to the upper layer */ + vlan_hwaccel_receive_skb(skb, sp->vlgrp, + RXD_GET_VLAN_TAG(rxdp->Control_2)); + } else { + netif_receive_skb(skb); + } #else - if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { - /* Queueing the vlan frame to the upper layer */ - vlan_hwaccel_rx(skb, sp->vlgrp, - RXD_GET_VLAN_TAG(rxdp->Control_2)); - } else { - netif_rx(skb); - } -#endif + if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { + /* Queueing the vlan frame to the upper layer */ + vlan_hwaccel_rx(skb, sp->vlgrp, + RXD_GET_VLAN_TAG(rxdp->Control_2)); } else { -send_up: - queue_rx_frame(skb); - } + netif_rx(skb); + } +#endif dev->last_rx = jiffies; -aggregate: atomic_dec(&sp->rx_bufs_left[ring_no]); return SUCCESS; } @@ -5857,7 +5714,7 @@ aggregate: * void. */ -static void s2io_link(nic_t * sp, int link) +void s2io_link(nic_t * sp, int link) { struct net_device *dev = (struct net_device *) sp->dev; @@ -5882,7 +5739,7 @@ static void s2io_link(nic_t * sp, int link) * returns the revision ID of the device. */ -static int get_xena_rev_id(struct pci_dev *pdev) +int get_xena_rev_id(struct pci_dev *pdev) { u8 id = 0; int ret; @@ -5951,8 +5808,6 @@ module_param(indicate_max_pkts, int, 0); #endif module_param(rxsync_frequency, int, 0); module_param(intr_type, int, 0); -module_param(lro, int, 0); -module_param(lro_max_pkts, int, 0); /** * s2io_init_nic - Initialization of the adapter . @@ -6084,7 +5939,6 @@ Defaulting to INTA\n"); else sp->device_type = XFRAME_I_DEVICE; - sp->lro = lro; /* Initialize some PCI/PCI-X fields of the NIC. */ s2io_init_pci(sp); @@ -6388,10 +6242,6 @@ Defaulting to INTA\n"); DBG_PRINT(ERR_DBG, "%s: 3-Buffer mode support has been " "enabled\n",dev->name); - if (sp->lro) - DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", - dev->name); - /* Initialize device name */ strcpy(sp->name, dev->name); if (sp->device_type & XFRAME_II_DEVICE) @@ -6494,7 +6344,7 @@ int __init s2io_starter(void) * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. */ -static void s2io_closer(void) +void s2io_closer(void) { pci_unregister_driver(&s2io_driver); DBG_PRINT(INIT_DBG, "cleanup done\n"); @@ -6502,318 +6352,3 @@ static void s2io_closer(void) module_init(s2io_starter); module_exit(s2io_closer); - -static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, - struct tcphdr **tcp, RxD_t *rxdp) -{ - int ip_off; - u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len; - - if (!(rxdp->Control_1 & RXD_FRAME_PROTO_TCP)) { - DBG_PRINT(INIT_DBG,"%s: Non-TCP frames not supported for LRO\n", - __FUNCTION__); - return -1; - } - - /* TODO: - * By default the VLAN field in the MAC is stripped by the card, if this - * feature is turned off in rx_pa_cfg register, then the ip_off field - * has to be shifted by a further 2 bytes - */ - switch (l2_type) { - case 0: /* DIX type */ - case 4: /* DIX type with VLAN */ - ip_off = HEADER_ETHERNET_II_802_3_SIZE; - break; - /* LLC, SNAP etc are considered non-mergeable */ - default: - return -1; - } - - *ip = (struct iphdr *)((u8 *)buffer + ip_off); - ip_len = (u8)((*ip)->ihl); - ip_len <<= 2; - *tcp = (struct tcphdr *)((unsigned long)*ip + ip_len); - - return 0; -} - -static int check_for_socket_match(lro_t *lro, struct iphdr *ip, - struct tcphdr *tcp) -{ - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); - if ((lro->iph->saddr != ip->saddr) || (lro->iph->daddr != ip->daddr) || - (lro->tcph->source != tcp->source) || (lro->tcph->dest != tcp->dest)) - return -1; - return 0; -} - -static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp) -{ - return(ntohs(ip->tot_len) - (ip->ihl << 2) - (tcp->doff << 2)); -} - -static void initiate_new_session(lro_t *lro, u8 *l2h, - struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len) -{ - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); - lro->l2h = l2h; - lro->iph = ip; - lro->tcph = tcp; - lro->tcp_next_seq = tcp_pyld_len + ntohl(tcp->seq); - lro->tcp_ack = ntohl(tcp->ack_seq); - lro->sg_num = 1; - lro->total_len = ntohs(ip->tot_len); - lro->frags_len = 0; - /* - * check if we saw TCP timestamp. Other consistency checks have - * already been done. - */ - if (tcp->doff == 8) { - u32 *ptr; - ptr = (u32 *)(tcp+1); - lro->saw_ts = 1; - lro->cur_tsval = *(ptr+1); - lro->cur_tsecr = *(ptr+2); - } - lro->in_use = 1; -} - -static void update_L3L4_header(nic_t *sp, lro_t *lro) -{ - struct iphdr *ip = lro->iph; - struct tcphdr *tcp = lro->tcph; - u16 nchk; - StatInfo_t *statinfo = sp->mac_control.stats_info; - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); - - /* Update L3 header */ - ip->tot_len = htons(lro->total_len); - ip->check = 0; - nchk = ip_fast_csum((u8 *)lro->iph, ip->ihl); - ip->check = nchk; - - /* Update L4 header */ - tcp->ack_seq = lro->tcp_ack; - tcp->window = lro->window; - - /* Update tsecr field if this session has timestamps enabled */ - if (lro->saw_ts) { - u32 *ptr = (u32 *)(tcp + 1); - *(ptr+2) = lro->cur_tsecr; - } - - /* Update counters required for calculation of - * average no. of packets aggregated. - */ - statinfo->sw_stat.sum_avg_pkts_aggregated += lro->sg_num; - statinfo->sw_stat.num_aggregations++; -} - -static void aggregate_new_rx(lro_t *lro, struct iphdr *ip, - struct tcphdr *tcp, u32 l4_pyld) -{ - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); - lro->total_len += l4_pyld; - lro->frags_len += l4_pyld; - lro->tcp_next_seq += l4_pyld; - lro->sg_num++; - - /* Update ack seq no. and window ad(from this pkt) in LRO object */ - lro->tcp_ack = tcp->ack_seq; - lro->window = tcp->window; - - if (lro->saw_ts) { - u32 *ptr; - /* Update tsecr and tsval from this packet */ - ptr = (u32 *) (tcp + 1); - lro->cur_tsval = *(ptr + 1); - lro->cur_tsecr = *(ptr + 2); - } -} - -static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, - struct tcphdr *tcp, u32 tcp_pyld_len) -{ - u8 *ptr; - - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); - - if (!tcp_pyld_len) { - /* Runt frame or a pure ack */ - return -1; - } - - if (ip->ihl != 5) /* IP has options */ - return -1; - - if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin || - !tcp->ack) { - /* - * Currently recognize only the ack control word and - * any other control field being set would result in - * flushing the LRO session - */ - return -1; - } - - /* - * Allow only one TCP timestamp option. Don't aggregate if - * any other options are detected. - */ - if (tcp->doff != 5 && tcp->doff != 8) - return -1; - - if (tcp->doff == 8) { - ptr = (u8 *)(tcp + 1); - while (*ptr == TCPOPT_NOP) - ptr++; - if (*ptr != TCPOPT_TIMESTAMP || *(ptr+1) != TCPOLEN_TIMESTAMP) - return -1; - - /* Ensure timestamp value increases monotonically */ - if (l_lro) - if (l_lro->cur_tsval > *((u32 *)(ptr+2))) - return -1; - - /* timestamp echo reply should be non-zero */ - if (*((u32 *)(ptr+6)) == 0) - return -1; - } - - return 0; -} - -static int -s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, lro_t **lro, - RxD_t *rxdp, nic_t *sp) -{ - struct iphdr *ip; - struct tcphdr *tcph; - int ret = 0, i; - - if (!(ret = check_L2_lro_capable(buffer, &ip, (struct tcphdr **)tcp, - rxdp))) { - DBG_PRINT(INFO_DBG,"IP Saddr: %x Daddr: %x\n", - ip->saddr, ip->daddr); - } else { - return ret; - } - - tcph = (struct tcphdr *)*tcp; - *tcp_len = get_l4_pyld_length(ip, tcph); - for (i=0; ilro0_n[i]; - if (l_lro->in_use) { - if (check_for_socket_match(l_lro, ip, tcph)) - continue; - /* Sock pair matched */ - *lro = l_lro; - - if ((*lro)->tcp_next_seq != ntohl(tcph->seq)) { - DBG_PRINT(INFO_DBG, "%s:Out of order. expected " - "0x%x, actual 0x%x\n", __FUNCTION__, - (*lro)->tcp_next_seq, - ntohl(tcph->seq)); - - sp->mac_control.stats_info-> - sw_stat.outof_sequence_pkts++; - ret = 2; - break; - } - - if (!verify_l3_l4_lro_capable(l_lro, ip, tcph,*tcp_len)) - ret = 1; /* Aggregate */ - else - ret = 2; /* Flush both */ - break; - } - } - - if (ret == 0) { - /* Before searching for available LRO objects, - * check if the pkt is L3/L4 aggregatable. If not - * don't create new LRO session. Just send this - * packet up. - */ - if (verify_l3_l4_lro_capable(NULL, ip, tcph, *tcp_len)) { - return 5; - } - - for (i=0; ilro0_n[i]; - if (!(l_lro->in_use)) { - *lro = l_lro; - ret = 3; /* Begin anew */ - break; - } - } - } - - if (ret == 0) { /* sessions exceeded */ - DBG_PRINT(INFO_DBG,"%s:All LRO sessions already in use\n", - __FUNCTION__); - *lro = NULL; - return ret; - } - - switch (ret) { - case 3: - initiate_new_session(*lro, buffer, ip, tcph, *tcp_len); - break; - case 2: - update_L3L4_header(sp, *lro); - break; - case 1: - aggregate_new_rx(*lro, ip, tcph, *tcp_len); - if ((*lro)->sg_num == sp->lro_max_aggr_per_sess) { - update_L3L4_header(sp, *lro); - ret = 4; /* Flush the LRO */ - } - break; - default: - DBG_PRINT(ERR_DBG,"%s:Dont know, can't say!!\n", - __FUNCTION__); - break; - } - - return ret; -} - -static void clear_lro_session(lro_t *lro) -{ - static u16 lro_struct_size = sizeof(lro_t); - - memset(lro, 0, lro_struct_size); -} - -static void queue_rx_frame(struct sk_buff *skb) -{ - struct net_device *dev = skb->dev; - - skb->protocol = eth_type_trans(skb, dev); -#ifdef CONFIG_S2IO_NAPI - netif_receive_skb(skb); -#else - netif_rx(skb); -#endif -} - -static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, - u32 tcp_len) -{ - struct sk_buff *tmp, *first = lro->parent; - - first->len += tcp_len; - first->data_len = lro->frags_len; - skb_pull(skb, (skb->len - tcp_len)); - if ((tmp = skb_shinfo(first)->frag_list)) { - while (tmp->next) - tmp = tmp->next; - tmp->next = skb; - } - else - skb_shinfo(first)->frag_list = skb; - sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; - return; -} diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 0a0b5b29d..852a6a899 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -64,7 +64,7 @@ typedef enum xena_max_outstanding_splits { #define INTR_DBG 4 /* Global variable that defines the present debug level of the driver. */ -static int debug_level = ERR_DBG; +int debug_level = ERR_DBG; /* Default level. */ /* DEBUG message print. */ #define DBG_PRINT(dbg_level, args...) if(!(debug_level -#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) -#include -#include -#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) +#include #include -#include -#else -#error invalid SiByte MAC configuation -#endif -#include #include #include +#include +#include -#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) -#define UNIT_INT(n) (K_BCM1480_INT_MAC_0 + ((n) * 2)) -#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) -#define UNIT_INT(n) (K_INT_MAC_0 + (n)) -#else -#error invalid SiByte MAC configuation -#endif /********************************************************************** * Simple types @@ -1490,10 +1476,10 @@ static void sbmac_channel_start(struct sbmac_softc *s) * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above * Use a larger RD_THRSH for gigabit */ - if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) - th_value = 28; - else + if (periph_rev >= 2) th_value = 64; + else + th_value = 28; fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ ((s->sbm_speed == sbmac_speed_1000) @@ -1603,17 +1589,13 @@ static void sbmac_channel_start(struct sbmac_softc *s) * Turn on the rest of the bits in the enable register */ -#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) - __raw_writeq(M_MAC_RXDMA_EN0 | - M_MAC_TXDMA_EN0, s->sbm_macenable); -#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) __raw_writeq(M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0 | M_MAC_RX_ENABLE | M_MAC_TX_ENABLE, s->sbm_macenable); -#else -#error invalid SiByte MAC configuation -#endif + + + #ifdef CONFIG_SBMAC_COALESCE /* @@ -1804,12 +1786,11 @@ static void sbmac_set_iphdr_offset(struct sbmac_softc *sc) reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15); __raw_writeq(reg, sc->sbm_rxfilter); - /* BCM1250 pass1 didn't have hardware checksum. Everything - later does. */ - if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) { - sc->rx_hw_checksum = DISABLE; - } else { + /* read system identification to determine revision */ + if (periph_rev >= 2) { sc->rx_hw_checksum = ENABLE; + } else { + sc->rx_hw_checksum = DISABLE; } } @@ -2239,7 +2220,7 @@ static void sbmac_setmulti(struct sbmac_softc *sc) -#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR) +#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) /********************************************************************** * SBMAC_PARSE_XDIGIT(str) * @@ -2811,7 +2792,7 @@ static int sbmac_close(struct net_device *dev) -#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR) +#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) static void sbmac_setup_hwaddr(int chan,char *addr) { @@ -2837,7 +2818,25 @@ sbmac_init_module(void) unsigned long port; int chip_max_units; - /* Set the number of available units based on the SOC type. */ + /* + * For bringup when not using the firmware, we can pre-fill + * the MAC addresses using the environment variables + * specified in this file (or maybe from the config file?) + */ +#ifdef SBMAC_ETH0_HWADDR + sbmac_setup_hwaddr(0,SBMAC_ETH0_HWADDR); +#endif +#ifdef SBMAC_ETH1_HWADDR + sbmac_setup_hwaddr(1,SBMAC_ETH1_HWADDR); +#endif +#ifdef SBMAC_ETH2_HWADDR + sbmac_setup_hwaddr(2,SBMAC_ETH2_HWADDR); +#endif + + /* + * Walk through the Ethernet controllers and find + * those who have their MAC addresses set. + */ switch (soc_type) { case K_SYS_SOC_TYPE_BCM1250: case K_SYS_SOC_TYPE_BCM1250_ALT: @@ -2849,10 +2848,6 @@ sbmac_init_module(void) case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ chip_max_units = 2; break; - case K_SYS_SOC_TYPE_BCM1x55: - case K_SYS_SOC_TYPE_BCM1x80: - chip_max_units = 4; - break; default: chip_max_units = 0; break; @@ -2860,32 +2855,6 @@ sbmac_init_module(void) if (chip_max_units > MAX_UNITS) chip_max_units = MAX_UNITS; - /* - * For bringup when not using the firmware, we can pre-fill - * the MAC addresses using the environment variables - * specified in this file (or maybe from the config file?) - */ -#ifdef SBMAC_ETH0_HWADDR - if (chip_max_units > 0) - sbmac_setup_hwaddr(0,SBMAC_ETH0_HWADDR); -#endif -#ifdef SBMAC_ETH1_HWADDR - if (chip_max_units > 1) - sbmac_setup_hwaddr(1,SBMAC_ETH1_HWADDR); -#endif -#ifdef SBMAC_ETH2_HWADDR - if (chip_max_units > 2) - sbmac_setup_hwaddr(2,SBMAC_ETH2_HWADDR); -#endif -#ifdef SBMAC_ETH3_HWADDR - if (chip_max_units > 3) - sbmac_setup_hwaddr(3,SBMAC_ETH3_HWADDR); -#endif - - /* - * Walk through the Ethernet controllers and find - * those who have their MAC addresses set. - */ for (idx = 0; idx < chip_max_units; idx++) { /* @@ -2917,7 +2886,7 @@ sbmac_init_module(void) printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); - dev->irq = UNIT_INT(idx); + dev->irq = K_INT_MAC_0 + idx; dev->base_addr = port; dev->mem_end = 0; if (sbmac_init(dev, idx)) { diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index bcef03feb..79dca398f 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -46,7 +46,6 @@ static const char version[] = #include #include #include -#include #include #include @@ -700,7 +699,7 @@ static void hardware_send_packet(struct net_device * dev, char *buf, int length) int ioaddr = dev->base_addr; int status = inw(SEEQ_STATUS); int transmit_ptr = 0; - unsigned long tmp; + int tmp; if (net_debug>4) { printk("%s: send 0x%04x\n",dev->name,length); @@ -725,7 +724,7 @@ static void hardware_send_packet(struct net_device * dev, char *buf, int length) /* drain FIFO */ tmp = jiffies; - while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ)) + while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && (jiffies - tmp < HZ)) mb(); /* doit ! */ diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index f95a5b022..a4614df38 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -3,9 +3,6 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ - -#undef DEBUG - #include #include #include @@ -62,6 +59,8 @@ static char *sgiseeqstr = "SGI Seeq8003"; sp->tx_old + (SEEQ_TX_BUFFERS - 1) - sp->tx_new : \ sp->tx_old - sp->tx_new - 1) +#define DEBUG + struct sgiseeq_rx_desc { volatile struct hpc_dma_desc rdma; volatile signed int buf_vaddr; @@ -210,7 +209,7 @@ static int seeq_init_ring(struct net_device *dev) static struct sgiseeq_private *gpriv; static struct net_device *gdev; -static void sgiseeq_dump_rings(void) +void sgiseeq_dump_rings(void) { static int once; struct sgiseeq_rx_desc *r = gpriv->rx_desc; @@ -312,9 +311,9 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp struct sgiseeq_regs *sregs) { struct sgiseeq_rx_desc *rd; - struct sk_buff *skb = NULL; + struct sk_buff *skb = 0; unsigned char pkt_status; - unsigned char *pkt_pointer = NULL; + unsigned char *pkt_pointer = 0; int len = 0; unsigned int orig_end = PREV_RX(sp->rx_new); @@ -516,6 +515,12 @@ static inline int sgiseeq_reset(struct net_device *dev) return 0; } +void sgiseeq_my_reset(void) +{ + printk("RESET!\n"); + sgiseeq_reset(gdev); +} + static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sgiseeq_private *sp = netdev_priv(dev); diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 88e212043..221354eea 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -83,7 +83,6 @@ #include #include #include -#include #include #include @@ -169,7 +168,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) /* * Queue over time. Spill packet. */ - if(time_after(SHAPERCB(skb)->shapeclock,jiffies + SHAPER_LATENCY)) { + if(SHAPERCB(skb)->shapeclock-jiffies > SHAPER_LATENCY) { dev_kfree_skb(skb); shaper->stats.tx_dropped++; } else diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 31dd3f036..ed4bc9163 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -366,7 +366,7 @@ static const u32 sis190_intr_mask = * Maximum number of multicast addresses to filter (vs. Rx-all-multicast). * The chips use a 64 element hash table based on the Ethernet CRC. */ -static const int multicast_filter_limit = 32; +static int multicast_filter_limit = 32; static void __mdio_cmd(void __iomem *ioaddr, u32 ctl) { diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index f5a3bf4d9..f185b4cf7 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -100,7 +100,7 @@ enum { SIS_900 = 0, SIS_7016 }; -static const char * card_names[] = { +static char * card_names[] = { "SiS 900 PCI Fast Ethernet", "SiS 7016 PCI Fast Ethernet" }; @@ -115,7 +115,7 @@ MODULE_DEVICE_TABLE (pci, sis900_pci_tbl); static void sis900_read_mode(struct net_device *net_dev, int *speed, int *duplex); -static const struct mii_chip_info { +static struct mii_chip_info { const char * name; u16 phy_id0; u16 phy_id1; @@ -127,12 +127,12 @@ static const struct mii_chip_info { } mii_chip_table[] = { { "SiS 900 Internal MII PHY", 0x001d, 0x8000, LAN }, { "SiS 7014 Physical Layer Solution", 0x0016, 0xf830, LAN }, - { "SiS 900 on Foxconn 661 7MI", 0x0143, 0xBC70, LAN }, { "Altimata AC101LF PHY", 0x0022, 0x5520, LAN }, { "ADM 7001 LAN PHY", 0x002e, 0xcc60, LAN }, { "AMD 79C901 10BASE-T PHY", 0x0000, 0x6B70, LAN }, { "AMD 79C901 HomePNA PHY", 0x0000, 0x6B90, HOME}, { "ICS LAN PHY", 0x0015, 0xF440, LAN }, + { "ICS LAN PHY", 0x0143, 0xBC70, LAN }, { "NS 83851 PHY", 0x2000, 0x5C20, MIX }, { "NS 83847 PHY", 0x2000, 0x5C30, MIX }, { "Realtek RTL8201 PHY", 0x0000, 0x8200, LAN }, @@ -402,7 +402,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, void *ring_space; long ioaddr; int i, ret; - const char *card_name = card_names[pci_id->driver_data]; + char *card_name = card_names[pci_id->driver_data]; const char *dev_name = pci_name(pci_dev); /* when built into the kernel, we only print version if device is found */ @@ -1277,7 +1277,7 @@ static void sis900_timer(unsigned long data) struct net_device *net_dev = (struct net_device *)data; struct sis900_private *sis_priv = net_dev->priv; struct mii_phy *mii_phy = sis_priv->mii; - static const int next_tick = 5*HZ; + static int next_tick = 5*HZ; u16 status; if (!sis_priv->autong_complete){ @@ -1694,7 +1694,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs * * Process receive interrupt events, * put buffer to higher layer and refill buffer pool - * Note: This function is called by interrupt handler, + * Note: This fucntion is called by interrupt handler, * don't do "too much" work here */ @@ -1841,7 +1841,7 @@ static int sis900_rx(struct net_device *net_dev) * * Check for error condition and free socket buffer etc * schedule for more transmission as needed - * Note: This function is called by interrupt handler, + * Note: This fucntion is called by interrupt handler, * don't do "too much" work here */ @@ -2284,7 +2284,7 @@ static void set_rx_mode(struct net_device *net_dev) int i, table_entries; u32 rx_mode; - /* 635 Hash Table entries = 256(2^16) */ + /* 635 Hash Table entires = 256(2^16) */ if((sis_priv->chipset_rev >= SIS635A_900_REV) || (sis_priv->chipset_rev == SIS900B_900_REV)) table_entries = 16; diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h index 423ad063d..3a2ea4a4b 100644 --- a/drivers/net/sk98lin/h/skaddr.h +++ b/drivers/net/sk98lin/h/skaddr.h @@ -236,6 +236,18 @@ extern int SkAddrMcClear( SK_U32 PortNumber, int Flags); +extern int SkAddrXmacMcClear( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int Flags); + +extern int SkAddrGmacMcClear( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int Flags); + extern int SkAddrMcAdd( SK_AC *pAC, SK_IOC IoC, @@ -243,11 +255,35 @@ extern int SkAddrMcAdd( SK_MAC_ADDR *pMc, int Flags); +extern int SkAddrXmacMcAdd( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + SK_MAC_ADDR *pMc, + int Flags); + +extern int SkAddrGmacMcAdd( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + SK_MAC_ADDR *pMc, + int Flags); + extern int SkAddrMcUpdate( SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); +extern int SkAddrXmacMcUpdate( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber); + +extern int SkAddrGmacMcUpdate( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber); + extern int SkAddrOverride( SK_AC *pAC, SK_IOC IoC, @@ -261,6 +297,18 @@ extern int SkAddrPromiscuousChange( SK_U32 PortNumber, int NewPromMode); +extern int SkAddrXmacPromiscuousChange( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int NewPromMode); + +extern int SkAddrGmacPromiscuousChange( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int NewPromMode); + #ifndef SK_SLIM extern int SkAddrSwap( SK_AC *pAC, diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h index 6e256bd9a..2b94adb93 100644 --- a/drivers/net/sk98lin/h/skcsum.h +++ b/drivers/net/sk98lin/h/skcsum.h @@ -203,6 +203,12 @@ extern SKCS_STATUS SkCsGetReceiveInfo( unsigned Checksum2, int NetNumber); +extern void SkCsGetSendInfo( + SK_AC *pAc, + void *pIpHeader, + SKCS_PACKET_INFO *pPacketInfo, + int NetNumber); + extern void SkCsSetReceiveFlags( SK_AC *pAc, unsigned ReceiveFlags, diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h index 143e635ec..184f47c5a 100644 --- a/drivers/net/sk98lin/h/skgeinit.h +++ b/drivers/net/sk98lin/h/skgeinit.h @@ -464,6 +464,12 @@ typedef struct s_GeInit { /* * public functions in skgeinit.c */ +extern void SkGePollRxD( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL PollRxD); + extern void SkGePollTxD( SK_AC *pAC, SK_IOC IoC, @@ -516,6 +522,10 @@ extern void SkGeXmitLED( int Led, int Mode); +extern void SkGeInitRamIface( + SK_AC *pAC, + SK_IOC IoC); + extern int SkGeInitAssignRamToQueues( SK_AC *pAC, int ActivePort, @@ -539,6 +549,11 @@ extern void SkMacHardRst( SK_IOC IoC, int Port); +extern void SkMacClearRst( + SK_AC *pAC, + SK_IOC IoC, + int Port); + extern void SkXmInitMac( SK_AC *pAC, SK_IOC IoC, @@ -565,6 +580,11 @@ extern void SkMacFlushTxFifo( SK_IOC IoC, int Port); +extern void SkMacFlushRxFifo( + SK_AC *pAC, + SK_IOC IoC, + int Port); + extern void SkMacIrq( SK_AC *pAC, SK_IOC IoC, @@ -581,6 +601,12 @@ extern void SkMacAutoNegLipaPhy( int Port, SK_U16 IStatus); +extern void SkMacSetRxTxEn( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Para); + extern int SkMacRxTxEnable( SK_AC *pAC, SK_IOC IoC, @@ -633,6 +659,16 @@ extern void SkXmClrExactAddr( int StartNum, int StopNum); +extern void SkXmInitDupMd( + SK_AC *pAC, + SK_IOC IoC, + int Port); + +extern void SkXmInitPauseMd( + SK_AC *pAC, + SK_IOC IoC, + int Port); + extern void SkXmAutoNegLipaXmac( SK_AC *pAC, SK_IOC IoC, @@ -693,6 +729,17 @@ extern int SkGmCableDiagStatus( int Port, SK_BOOL StartTest); +extern int SkGmEnterLowPowerMode( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_U8 Mode); + +extern int SkGmLeaveLowPowerMode( + SK_AC *pAC, + SK_IOC IoC, + int Port); + #ifdef SK_DIAG extern void SkGePhyRead( SK_AC *pAC, @@ -735,6 +782,7 @@ extern void SkXmSendCont( /* * public functions in skgeinit.c */ +extern void SkGePollRxD(); extern void SkGePollTxD(); extern void SkGeYellowLED(); extern int SkGeCfgSync(); @@ -744,6 +792,7 @@ extern int SkGeInit(); extern void SkGeDeInit(); extern int SkGeInitPort(); extern void SkGeXmitLED(); +extern void SkGeInitRamIface(); extern int SkGeInitAssignRamToQueues(); /* @@ -752,15 +801,18 @@ extern int SkGeInitAssignRamToQueues(); extern void SkMacRxTxDisable(); extern void SkMacSoftRst(); extern void SkMacHardRst(); +extern void SkMacClearRst(); extern void SkMacInitPhy(); extern int SkMacRxTxEnable(); extern void SkMacPromiscMode(); extern void SkMacHashing(); extern void SkMacIrqDisable(); extern void SkMacFlushTxFifo(); +extern void SkMacFlushRxFifo(); extern void SkMacIrq(); extern int SkMacAutoNegDone(); extern void SkMacAutoNegLipaPhy(); +extern void SkMacSetRxTxEn(); extern void SkXmInitMac(); extern void SkXmPhyRead(); extern void SkXmPhyWrite(); @@ -768,6 +820,8 @@ extern void SkGmInitMac(); extern void SkGmPhyRead(); extern void SkGmPhyWrite(); extern void SkXmClrExactAddr(); +extern void SkXmInitDupMd(); +extern void SkXmInitPauseMd(); extern void SkXmAutoNegLipaXmac(); extern int SkXmUpdateStats(); extern int SkGmUpdateStats(); @@ -778,6 +832,8 @@ extern int SkGmResetCounter(); extern int SkXmOverflowStatus(); extern int SkGmOverflowStatus(); extern int SkGmCableDiagStatus(); +extern int SkGmEnterLowPowerMode(); +extern int SkGmLeaveLowPowerMode(); #ifdef SK_DIAG extern void SkGePhyRead(); diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h index 1ed214ccb..3b2773e6f 100644 --- a/drivers/net/sk98lin/h/skgepnmi.h +++ b/drivers/net/sk98lin/h/skgepnmi.h @@ -946,6 +946,10 @@ typedef struct s_PnmiData { * Function prototypes */ extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, + unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex); +extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, + void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h index 3eec6274e..b486bd9b6 100644 --- a/drivers/net/sk98lin/h/skgesirq.h +++ b/drivers/net/sk98lin/h/skgesirq.h @@ -105,6 +105,7 @@ extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); +extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port); extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port); #endif /* _INC_SKGESIRQ_H_ */ diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h index 6a63f4a15..598bb42cc 100644 --- a/drivers/net/sk98lin/h/ski2c.h +++ b/drivers/net/sk98lin/h/ski2c.h @@ -162,6 +162,9 @@ typedef struct s_I2c { } SK_I2C; extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size, + int Reg, int Burst); +extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); #ifdef SK_DIAG extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, int Burst); diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h index fdd9e48e8..daa9a8d15 100644 --- a/drivers/net/sk98lin/h/skvpd.h +++ b/drivers/net/sk98lin/h/skvpd.h @@ -183,6 +183,14 @@ extern SK_U32 VpdReadDWord( int addr); #endif /* SKDIAG */ +extern int VpdSetupPara( + SK_AC *pAC, + const char *key, + const char *buf, + int len, + int type, + int op); + extern SK_VPD_STATUS *VpdStat( SK_AC *pAC, SK_IOC IoC); @@ -219,6 +227,11 @@ extern int VpdUpdate( SK_AC *pAC, SK_IOC IoC); +extern void VpdErrLog( + SK_AC *pAC, + SK_IOC IoC, + char *msg); + #ifdef SKDIAG extern int VpdReadBlock( SK_AC *pAC, @@ -236,6 +249,7 @@ extern int VpdWriteBlock( #endif /* SKDIAG */ #else /* SK_KR_PROTO */ extern SK_U32 VpdReadDWord(); +extern int VpdSetupPara(); extern SK_VPD_STATUS *VpdStat(); extern int VpdKeys(); extern int VpdRead(); @@ -243,6 +257,7 @@ extern SK_BOOL VpdMayWrite(); extern int VpdWrite(); extern int VpdDelete(); extern int VpdUpdate(); +extern void VpdErrLog(); #endif /* SK_KR_PROTO */ #endif /* __INC_SKVPD_H_ */ diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c index 6e6c56aa6..a7e25edc7 100644 --- a/drivers/net/sk98lin/skaddr.c +++ b/drivers/net/sk98lin/skaddr.c @@ -87,21 +87,6 @@ static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; static int Next0[SK_MAX_MACS] = {0}; #endif /* DEBUG */ -static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - SK_MAC_ADDR *pMc, int Flags); -static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - int Flags); -static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); -static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, - SK_U32 PortNumber, int NewPromMode); -static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - SK_MAC_ADDR *pMc, int Flags); -static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - int Flags); -static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); -static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, - SK_U32 PortNumber, int NewPromMode); - /* functions ******************************************************************/ /****************************************************************************** @@ -387,7 +372,7 @@ int Flags) /* permanent/non-perm, sw-only */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrXmacMcClear( +int SkAddrXmacMcClear( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Index of affected port */ @@ -444,7 +429,7 @@ int Flags) /* permanent/non-perm, sw-only */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrGmacMcClear( +int SkAddrGmacMcClear( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Index of affected port */ @@ -534,7 +519,7 @@ int Flags) /* permanent/non-perm, sw-only */ * Returns: * Hash value of multicast address. */ -static SK_U32 SkXmacMcHash( +SK_U32 SkXmacMcHash( unsigned char *pMc) /* Multicast address */ { SK_U32 Idx; @@ -572,7 +557,7 @@ unsigned char *pMc) /* Multicast address */ * Returns: * Hash value of multicast address. */ -static SK_U32 SkGmacMcHash( +SK_U32 SkGmacMcHash( unsigned char *pMc) /* Multicast address */ { SK_U32 Data; @@ -687,7 +672,7 @@ int Flags) /* permanent/non-permanent */ * SK_MC_ILLEGAL_ADDRESS * SK_MC_RLMT_OVERFLOW */ -static int SkAddrXmacMcAdd( +int SkAddrXmacMcAdd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Port Number */ @@ -793,7 +778,7 @@ int Flags) /* permanent/non-permanent */ * SK_MC_FILTERING_INEXACT * SK_MC_ILLEGAL_ADDRESS */ -static int SkAddrGmacMcAdd( +int SkAddrGmacMcAdd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Port Number */ @@ -952,7 +937,7 @@ SK_U32 PortNumber) /* Port Number */ * SK_MC_FILTERING_INEXACT * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrXmacMcUpdate( +int SkAddrXmacMcUpdate( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ @@ -1097,7 +1082,7 @@ SK_U32 PortNumber) /* Port Number */ * SK_MC_FILTERING_INEXACT * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrGmacMcUpdate( +int SkAddrGmacMcUpdate( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ @@ -1483,7 +1468,7 @@ int NewPromMode) /* new promiscuous mode */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrXmacPromiscuousChange( +int SkAddrXmacPromiscuousChange( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* port whose promiscuous mode changes */ @@ -1600,7 +1585,7 @@ int NewPromMode) /* new promiscuous mode */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrGmacPromiscuousChange( +int SkAddrGmacPromiscuousChange( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* port whose promiscuous mode changes */ diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index 38a26df40..a5f2b1ee0 100644 --- a/drivers/net/sk98lin/skge.c +++ b/drivers/net/sk98lin/skge.c @@ -1727,7 +1727,7 @@ struct sk_buff *pMessage) /* pointer to send-message */ pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); pTxd->pMBuf = pMessage; - pTxd->TBControl = Control | BMU_OWN | sk_frag->size; + pTxd->TBControl = Control | BMU_OWN | sk_frag->size;; /* ** Do we have the last fragment? diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c index 67f1d6a5c..6cb49dd02 100644 --- a/drivers/net/sk98lin/skgeinit.c +++ b/drivers/net/sk98lin/skgeinit.c @@ -57,6 +57,34 @@ static struct s_Config OemConfig = { #endif }; +/****************************************************************************** + * + * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring + * + * Description: + * Enable or disable the descriptor polling of the receive descriptor + * ring (RxD) for port 'Port'. + * The new configuration is *not* saved over any SkGeStopPort() and + * SkGeInitPort() calls. + * + * Returns: + * nothing + */ +void SkGePollRxD( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ +{ + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; + + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ? + CSR_ENA_POL : CSR_DIS_POL); +} /* SkGePollRxD */ + + /****************************************************************************** * * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings @@ -924,7 +952,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkGeInitRamIface( +void SkGeInitRamIface( SK_AC *pAC, /* adapter context */ SK_IOC IoC) /* IO context */ { @@ -1381,6 +1409,83 @@ SK_IOC IoC) /* IO context */ } /* SkGeInit0*/ +#ifdef SK_PCI_RESET + +/****************************************************************************** + * + * SkGePciReset() - Reset PCI interface + * + * Description: + * o Read PCI configuration. + * o Change power state to 3. + * o Change power state to 0. + * o Restore PCI configuration. + * + * Returns: + * 0: Success. + * 1: Power state could not be changed to 3. + */ +static int SkGePciReset( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC) /* IO context */ +{ + int i; + SK_U16 PmCtlSts; + SK_U32 Bp1; + SK_U32 Bp2; + SK_U16 PciCmd; + SK_U8 Cls; + SK_U8 Lat; + SK_U8 ConfigSpace[PCI_CFG_SIZE]; + + /* + * Note: Switching to D3 state is like a software reset. + * Switching from D3 to D0 is a hardware reset. + * We have to save and restore the configuration space. + */ + for (i = 0; i < PCI_CFG_SIZE; i++) { + SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]); + } + + /* We know the RAM Interface Arbiter is enabled. */ + SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3); + SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); + + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) { + return(1); + } + + /* Return to D0 state. */ + SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0); + + /* Check for D0 state. */ + SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); + + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) { + return(1); + } + + /* Check PCI Config Registers. */ + SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd); + SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls); + SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1); + SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2); + SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat); + + if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 || + (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) { + return(1); + } + + /* Restore PCI Config Space. */ + for (i = 0; i < PCI_CFG_SIZE; i++) { + SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]); + } + + return(0); +} /* SkGePciReset */ + +#endif /* SK_PCI_RESET */ /****************************************************************************** * @@ -1419,6 +1524,10 @@ SK_IOC IoC) /* IO context */ /* save CLK_RUN bits (YUKON-Lite) */ SK_IN16(IoC, B0_CTST, &CtrlStat); +#ifdef SK_PCI_RESET + (void)SkGePciReset(pAC, IoC); +#endif /* SK_PCI_RESET */ + /* do the SW-reset */ SK_OUT8(IoC, B0_CTST, CS_RST_SET); @@ -1882,6 +1991,11 @@ SK_IOC IoC) /* IO context */ int i; SK_U16 Word; +#ifdef SK_PHY_LP_MODE + SK_U8 Byte; + SK_U16 PmCtlSts; +#endif /* SK_PHY_LP_MODE */ + #if (!defined(SK_SLIM) && !defined(VCPU)) /* ensure I2C is ready */ SkI2cWaitIrq(pAC, IoC); @@ -1896,6 +2010,38 @@ SK_IOC IoC) /* IO context */ } } +#ifdef SK_PHY_LP_MODE + /* + * for power saving purposes within mobile environments + * we set the PHY to coma mode and switch to D3 power state. + */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { + + /* for all ports switch PHY to coma mode */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); + } + + if (pAC->GIni.GIVauxAvail) { + /* switch power to VAUX */ + Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF; + + SK_OUT8(IoC, B0_POWER_CTRL, Byte); + } + + /* switch to D3 state */ + SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts); + + PmCtlSts |= PCI_PM_STATE_D3; + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts); + } +#endif /* SK_PHY_LP_MODE */ + /* Reset all bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c index 0a6f67a7a..2991bc85c 100644 --- a/drivers/net/sk98lin/skgemib.c +++ b/drivers/net/sk98lin/skgemib.c @@ -871,6 +871,13 @@ PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = { sizeof(SK_PNMI_CONF), SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), SK_PNMI_RO, MacPrivateConf, 0}, +#ifdef SK_PHY_LP_MODE + {OID_SKGE_PHY_LP_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode), + SK_PNMI_RW, MacPrivateConf, 0}, +#endif {OID_SKGE_LINK_CAP, SK_PNMI_MAC_ENTRIES, sizeof(SK_PNMI_CONF), diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c index b36dd9ac6..a38617210 100644 --- a/drivers/net/sk98lin/skgepnmi.c +++ b/drivers/net/sk98lin/skgepnmi.c @@ -56,6 +56,10 @@ static const char SysKonnectFileId[] = * Public Function prototypes */ int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level); +int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, + unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, + unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, @@ -583,7 +587,7 @@ int Level) /* Initialization level */ * exist (e.g. port instance 3 on a two port * adapter. */ -static int SkPnmiGetVar( +int SkPnmiGetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ @@ -625,7 +629,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ * exist (e.g. port instance 3 on a two port * adapter. */ -static int SkPnmiPreSetVar( +int SkPnmiPreSetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ @@ -5058,6 +5062,9 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ case OID_SKGE_SPEED_CAP: case OID_SKGE_SPEED_MODE: case OID_SKGE_SPEED_STATUS: +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: +#endif if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); @@ -5133,6 +5140,28 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ Offset += sizeof(SK_U32); break; +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + continue; + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + *pBufPtr = Val8; + } + } + else { /* DualNetMode */ + + Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + *pBufPtr = Val8; + } + Offset += sizeof(SK_U8); + break; +#endif + case OID_SKGE_LINK_CAP: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { @@ -5449,6 +5478,16 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ } break; +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (*pLen < Limit - LogPortIndex) { + + *pLen = Limit - LogPortIndex; + return (SK_PNMI_ERR_TOO_SHORT); + } + break; +#endif + case OID_SKGE_MTU: if (*pLen < sizeof(SK_U32)) { @@ -5806,6 +5845,116 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ Offset += sizeof(SK_U32); break; +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + /* The preset ends here */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + Offset = 0; + continue; + } + else { + /* Set value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + switch (*(pBuf + Offset)) { + case 0: + /* If LowPowerMode is active, we can leave it. */ + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + case 1: + case 2: + case 3: + case 4: + /* If no LowPowerMode is active, we can enter it. */ + if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + if ((*(pBuf + Offset)) < 3) { + + SkDrvDeInitAdapter(pAC); + } + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + } + else { /* DualNetMode */ + + switch (*(pBuf + Offset)) { + case 0: + /* If we are in a LowPowerMode, we can leave it. */ + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + case 1: + case 2: + case 3: + case 4: + /* If we are not already in LowPowerMode, we can enter it. */ + if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + if ((*(pBuf + Offset)) < 3) { + + SkDrvDeInitAdapter(pAC); + } + else { + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + Offset += sizeof(SK_U8); + break; +#endif + default: SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, ("MacPrivateConf: Unknown OID should be handled before set")); diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c index ab66d80a4..87520f005 100644 --- a/drivers/net/sk98lin/skgesirq.c +++ b/drivers/net/sk98lin/skgesirq.c @@ -265,7 +265,7 @@ int Port) /* Port Index (MAC_1 + n) */ * * Returns: N/A */ -static void SkHWLinkUp( +void SkHWLinkUp( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -612,6 +612,14 @@ SK_U32 Istatus) /* Interrupt status word */ * we ignore those */ pPrt->HalfDupTimerActive = SK_TRUE; +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 0), + pAC->Rlmt.Port[0].Net->NetNumber); + + pPrt->LastOctets = Octets; +#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, 0); @@ -645,6 +653,14 @@ SK_U32 Istatus) /* Interrupt status word */ pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && !pPrt->HalfDupTimerActive) { pPrt->HalfDupTimerActive = SK_TRUE; +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 1), + pAC->Rlmt.Port[1].Net->NetNumber); + + pPrt->LastOctets = Octets; +#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, 1); @@ -2069,6 +2085,12 @@ SK_EVPARA Para) /* Event specific Parameter */ pPrt->HalfDupTimerActive = SK_FALSE; if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), + pAC->Rlmt.Port[Port].Net->NetNumber); +#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, Port); diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c index 79bf57cb5..075a0464e 100644 --- a/drivers/net/sk98lin/ski2c.c +++ b/drivers/net/sk98lin/ski2c.c @@ -396,7 +396,7 @@ int Rw) /* Read / Write Flag */ * 1: error, transfer does not complete, I2C transfer * killed, wait loop terminated. */ -static int SkI2cWait( +int SkI2cWait( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ @@ -481,7 +481,7 @@ SK_IOC IoC) /* I/O Context */ * returns 0: success * 1: error */ -static int SkI2cWrite( +int SkI2cWrite( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 I2cData, /* I2C Data to write */ @@ -538,7 +538,7 @@ int I2cBurst) /* I2C Burst Flag */ * 1 if the read is completed * 0 if the read must be continued (I2C Bus still allocated) */ -static int SkI2cReadSensor( +int SkI2cReadSensor( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_SENSOR *pSen) /* Sensor to be read */ diff --git a/drivers/net/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c index a204f5bb5..68292d181 100644 --- a/drivers/net/sk98lin/sklm80.c +++ b/drivers/net/sk98lin/sklm80.c @@ -34,7 +34,79 @@ static const char SysKonnectFileId[] = #include "h/lm80.h" #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ +#ifdef SK_DIAG +#define BREAK_OR_WAIT(pAC,IoC,Event) SkI2cWait(pAC,IoC,Event) +#else /* nSK_DIAG */ #define BREAK_OR_WAIT(pAC,IoC,Event) break +#endif /* nSK_DIAG */ + +#ifdef SK_DIAG +/* + * read the register 'Reg' from the device 'Dev' + * + * return read error -1 + * success the read value + */ +int SkLm80RcvReg( +SK_IOC IoC, /* Adapter Context */ +int Dev, /* I2C device address */ +int Reg) /* register to read */ +{ + int Val = 0; + int TempExt; + + /* Signal device number */ + if (SkI2cSndDev(IoC, Dev, I2C_WRITE)) { + return(-1); + } + + if (SkI2cSndByte(IoC, Reg)) { + return(-1); + } + + /* repeat start */ + if (SkI2cSndDev(IoC, Dev, I2C_READ)) { + return(-1); + } + + switch (Reg) { + case LM80_TEMP_IN: + Val = (int)SkI2cRcvByte(IoC, 1); + + /* First: correct the value: it might be negative */ + if ((Val & 0x80) != 0) { + /* Value is negative */ + Val = Val - 256; + } + Val = Val * SK_LM80_TEMP_LSB; + SkI2cStop(IoC); + + TempExt = (int)SkLm80RcvReg(IoC, LM80_ADDR, LM80_TEMP_CTRL); + + if (Val > 0) { + Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); + } + else { + Val -= ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); + } + return(Val); + break; + case LM80_VT0_IN: + case LM80_VT1_IN: + case LM80_VT2_IN: + case LM80_VT3_IN: + Val = (int)SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB; + break; + + default: + Val = (int)SkI2cRcvByte(IoC, 1); + break; + } + + SkI2cStop(IoC); + return(Val); +} +#endif /* SK_DIAG */ /* * read a sensors value (LM80 specific) diff --git a/drivers/net/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c index be8d1ccdd..9ea11ab22 100644 --- a/drivers/net/sk98lin/skrlmt.c +++ b/drivers/net/sk98lin/skrlmt.c @@ -282,6 +282,7 @@ typedef struct s_SpTreeRlmtPacket { SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}}; SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}}; +SK_MAC_ADDR BcAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; /* local variables ************************************************************/ diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c index 17786056c..eb3c8988c 100644 --- a/drivers/net/sk98lin/skvpd.c +++ b/drivers/net/sk98lin/skvpd.c @@ -132,6 +132,65 @@ int addr) /* VPD address */ #endif /* SKDIAG */ +#if 0 + +/* + Write the dword 'data' at address 'addr' into the VPD EEPROM, and + verify that the data is written. + + Needed Time: + +. MIN MAX +. ------------------------------------------------------------------- +. write 1.8 ms 3.6 ms +. internal write cyles 0.7 ms 7.0 ms +. ------------------------------------------------------------------- +. over all program time 2.5 ms 10.6 ms +. read 1.3 ms 2.6 ms +. ------------------------------------------------------------------- +. over all 3.8 ms 13.2 ms +. + + + Returns 0: success + 1: error, I2C transfer does not terminate + 2: error, data verify error + + */ +static int VpdWriteDWord( +SK_AC *pAC, /* pAC pointer */ +SK_IOC IoC, /* IO Context */ +int addr, /* VPD address */ +SK_U32 data) /* VPD data to write */ +{ + /* start VPD write */ + /* Don't swap here, it's a data stream of bytes */ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD write dword at addr 0x%x, data = 0x%x\n",addr,data)); + VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data); + /* But do it here */ + addr |= VPD_WRITE; + + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE)); + + /* this may take up to 10,6 ms */ + if (VpdWait(pAC, IoC, VPD_WRITE)) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Write Timed Out\n")); + return(1); + }; + + /* verify data */ + if (VpdReadDWord(pAC, IoC, addr) != data) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Data Verify Error\n")); + return(2); + } + return(0); +} /* VpdWriteDWord */ + +#endif /* 0 */ + /* * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from * or to the I2C EEPROM. @@ -669,7 +728,7 @@ char *etp) /* end pointer input position */ * 6: fatal VPD error * */ -static int VpdSetupPara( +int VpdSetupPara( SK_AC *pAC, /* common data base */ const char *key, /* keyword to insert */ const char *buf, /* buffer with the keyword value */ @@ -1089,3 +1148,50 @@ SK_IOC IoC) /* IO Context */ return(0); } + + +/* + * Read the contents of the VPD EEPROM and copy it to the VPD buffer + * if not already done. If the keyword "VF" is not present it will be + * created and the error log message will be stored to this keyword. + * If "VF" is not present the error log message will be stored to the + * keyword "VL". "VL" will created or overwritten if "VF" is present. + * The VPD read/write area is saved to the VPD EEPROM. + * + * returns nothing, errors will be ignored. + */ +void VpdErrLog( +SK_AC *pAC, /* common data base */ +SK_IOC IoC, /* IO Context */ +char *msg) /* error log message */ +{ + SK_VPD_PARA *v, vf; /* VF */ + int len; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, + ("VPD error log msg %s\n", msg)); + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD init error\n")); + return; + } + } + + len = strlen(msg); + if (len > VPD_MAX_LEN) { + /* cut it */ + len = VPD_MAX_LEN; + } + if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n")); + (void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY); + } + else { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n")); + (void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY); + } + + (void)VpdUpdate(pAC, IoC); +} + diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c index b4e75022a..42d2d9631 100644 --- a/drivers/net/sk98lin/skxmac2.c +++ b/drivers/net/sk98lin/skxmac2.c @@ -41,13 +41,13 @@ static const char SysKonnectFileId[] = #endif #ifdef GENESIS -static BCOM_HACK BcomRegA1Hack[] = { +BCOM_HACK BcomRegA1Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 }, { 0, 0 } }; -static BCOM_HACK BcomRegC0Hack[] = { +BCOM_HACK BcomRegC0Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, { 0, 0 } @@ -790,7 +790,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkMacFlushRxFifo( +void SkMacFlushRxFifo( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1231,6 +1231,38 @@ int Port) /* Port Index (MAC_1 + n) */ } /* SkMacHardRst */ +/****************************************************************************** + * + * SkMacClearRst() - Clear the MAC reset + * + * Description: calls a clear MAC reset routine dep. on board type + * + * Returns: + * nothing + */ +void SkMacClearRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + SkXmClearRst(pAC, IoC, Port); + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + SkGmClearRst(pAC, IoC, Port); + } +#endif /* YUKON */ + +} /* SkMacClearRst */ + + #ifdef GENESIS /****************************************************************************** * @@ -1681,7 +1713,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkXmInitDupMd( +void SkXmInitDupMd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1729,7 +1761,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkXmInitPauseMd( +void SkXmInitPauseMd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -2044,7 +2076,283 @@ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ } /* SkXmInitPhyBcom */ #endif /* GENESIS */ + #ifdef YUKON +#ifndef SK_SLIM +/****************************************************************************** + * + * SkGmEnterLowPowerMode() + * + * Description: + * This function sets the Marvell Alaska PHY to the low power mode + * given by parameter mode. + * The following low power modes are available: + * + * - Coma Mode (Deep Sleep): + * Power consumption: ~15 - 30 mW + * The PHY cannot wake up on its own. + * + * - IEEE 22.2.4.1.5 compatible power down mode + * Power consumption: ~240 mW + * The PHY cannot wake up on its own. + * + * - energy detect mode + * Power consumption: ~160 mW + * The PHY can wake up on its own by detecting activity + * on the CAT 5 cable. + * + * - energy detect plus mode + * Power consumption: ~150 mW + * The PHY can wake up on its own by detecting activity + * on the CAT 5 cable. + * Connected devices can be woken up by sending normal link + * pulses every one second. + * + * Note: + * + * Returns: + * 0: ok + * 1: error + */ +int SkGmEnterLowPowerMode( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (e.g. MAC_1) */ +SK_U8 Mode) /* low power mode */ +{ + SK_U16 Word; + SK_U32 DWord; + SK_U8 LastMode; + int Ret = 0; + + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { + + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = Mode; + + switch (Mode) { + /* coma mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + /* setup General Purpose Control Register */ + GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS | + GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); + + /* apply COMA mode workaround */ + SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f); + SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3); + + SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + /* Set PHY to Coma Mode */ + SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + /* + * - disable MAC 125 MHz clock + * - allow MAC power down + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word |= PHY_M_PC_DIS_125CLK; + Word &= ~PHY_M_PC_MAC_POW_UP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * register changes must be followed by a software + * reset to take effect + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + /* switch IEEE compatible power down mode on */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* + * - disable MAC 125 MHz clock + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word |= PHY_M_PC_DIS_125CLK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* activate energy detect mode 1 */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + + /* energy detect mode */ + if (Mode == PHY_PM_ENERGY_DETECT) { + Word |= PHY_M_PC_EN_DET; + } + /* energy detect plus mode */ + else { + Word |= PHY_M_PC_EN_DET_PLUS; + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * reinitialize the PHY to force a software reset + * which is necessary after the register settings + * for the energy detect modes. + * Furthermore reinitialisation prevents that the + * PHY is running out of a stable state. + */ + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; + Ret = 1; + break; + } + } + /* low power modes are not supported by this chip */ + else { + Ret = 1; + } + + return(Ret); + +} /* SkGmEnterLowPowerMode */ + +/****************************************************************************** + * + * SkGmLeaveLowPowerMode() + * + * Description: + * Leave the current low power mode and switch to normal mode + * + * Note: + * + * Returns: + * 0: ok + * 1: error + */ +int SkGmLeaveLowPowerMode( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (e.g. MAC_1) */ +{ + SK_U32 DWord; + SK_U16 Word; + SK_U8 LastMode; + int Ret = 0; + + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { + + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; + + switch (LastMode) { + /* coma mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + /* Release PHY from Coma Mode */ + SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + SK_IN32(IoC, B2_GP_IO, &DWord); + + /* set to output */ + DWord |= (GP_DIR_9 | GP_IO_9); + + /* set PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + + DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ + + /* clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + /* + * - enable MAC 125 MHz clock + * - set MAC power up + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; + Word |= PHY_M_PC_MAC_POW_UP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * register changes must be followed by a software + * reset to take effect + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + /* switch IEEE compatible power down mode off */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word &= ~PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* + * - enable MAC 125 MHz clock + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* disable energy detect mode */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_EN_DET_MSK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * reinitialize the PHY to force a software reset + * which is necessary after the register settings + * for the energy detect modes. + * Furthermore reinitialisation prevents that the + * PHY is running out of a stable state. + */ + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; + Ret = 1; + break; + } + } + /* low power modes are not supported by this chip */ + else { + Ret = 1; + } + + return(Ret); + +} /* SkGmLeaveLowPowerMode */ +#endif /* !SK_SLIM */ + + /****************************************************************************** * * SkGmInitPhyMarv() - Initialize the Marvell Phy registers @@ -3112,6 +3420,145 @@ int Port) /* Port Index (MAC_1 + n) */ } /* SkMacAutoNegDone */ +#ifdef GENESIS +/****************************************************************************** + * + * SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC + * + * Description: + * sets MAC or PHY LoopBack and Duplex Mode in the MMU Command Reg. + * enables Rx/Tx + * + * Returns: N/A + */ +static void SkXmSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */ +{ + SK_U16 Word; + + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + + switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { + case SK_MAC_LOOPB_ON: + Word |= XM_MMU_MAC_LB; + break; + case SK_MAC_LOOPB_OFF: + Word &= ~XM_MMU_MAC_LB; + break; + } + + switch (Para & (SK_PHY_LOOPB_ON | SK_PHY_LOOPB_OFF)) { + case SK_PHY_LOOPB_ON: + Word |= XM_MMU_GMII_LOOP; + break; + case SK_PHY_LOOPB_OFF: + Word &= ~XM_MMU_GMII_LOOP; + break; + } + + switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { + case SK_PHY_FULLD_ON: + Word |= XM_MMU_GMII_FD; + break; + case SK_PHY_FULLD_OFF: + Word &= ~XM_MMU_GMII_FD; + break; + } + + XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX); + + /* dummy read to ensure writing */ + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + +} /* SkXmSetRxTxEn */ +#endif /* GENESIS */ + + +#ifdef YUKON +/****************************************************************************** + * + * SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC + * + * Description: + * sets MAC LoopBack and Duplex Mode in the General Purpose Control Reg. + * enables Rx/Tx + * + * Returns: N/A + */ +static void SkGmSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) /* Parameter to set: MAC LoopBack, Duplex Mode */ +{ + SK_U16 Ctrl; + + GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); + + switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { + case SK_MAC_LOOPB_ON: + Ctrl |= GM_GPCR_LOOP_ENA; + break; + case SK_MAC_LOOPB_OFF: + Ctrl &= ~GM_GPCR_LOOP_ENA; + break; + } + + switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { + case SK_PHY_FULLD_ON: + Ctrl |= GM_GPCR_DUP_FULL; + break; + case SK_PHY_FULLD_OFF: + Ctrl &= ~GM_GPCR_DUP_FULL; + break; + } + + GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Ctrl | GM_GPCR_RX_ENA | + GM_GPCR_TX_ENA)); + + /* dummy read to ensure writing */ + GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); + +} /* SkGmSetRxTxEn */ +#endif /* YUKON */ + + +#ifndef SK_SLIM +/****************************************************************************** + * + * SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters + * + * Description: calls the Special Set Rx/Tx Enable routines dep. on board type + * + * Returns: N/A + */ +void SkMacSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) +{ +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + SkXmSetRxTxEn(pAC, IoC, Port, Para); + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + SkGmSetRxTxEn(pAC, IoC, Port, Para); + } +#endif /* YUKON */ + +} /* SkMacSetRxTxEn */ +#endif /* !SK_SLIM */ + + /****************************************************************************** * * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up @@ -3529,7 +3976,7 @@ SK_U16 PhyStat) /* PHY Status word to analyse */ * Returns: * nothing */ -static void SkXmIrq( +void SkXmIrq( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -3665,7 +4112,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkGmIrq( +void SkGmIrq( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c index 0784f558c..a2ed47f1c 100644 --- a/drivers/net/skfp/fplustm.c +++ b/drivers/net/skfp/fplustm.c @@ -89,21 +89,21 @@ static const u_short my_sagp = 0xffff ; /* short group address (n.u.) */ /* * useful interrupt bits */ -static const int mac_imsk1u = FM_STXABRS | FM_STXABRA0 | FM_SXMTABT ; -static const int mac_imsk1l = FM_SQLCKS | FM_SQLCKA0 | FM_SPCEPDS | FM_SPCEPDA0| +static int mac_imsk1u = FM_STXABRS | FM_STXABRA0 | FM_SXMTABT ; +static int mac_imsk1l = FM_SQLCKS | FM_SQLCKA0 | FM_SPCEPDS | FM_SPCEPDA0| FM_STBURS | FM_STBURA0 ; /* delete FM_SRBFL after tests */ -static const int mac_imsk2u = FM_SERRSF | FM_SNFSLD | FM_SRCVOVR | FM_SRBFL | +static int mac_imsk2u = FM_SERRSF | FM_SNFSLD | FM_SRCVOVR | FM_SRBFL | FM_SMYCLM ; -static const int mac_imsk2l = FM_STRTEXR | FM_SDUPCLM | FM_SFRMCTR | +static int mac_imsk2l = FM_STRTEXR | FM_SDUPCLM | FM_SFRMCTR | FM_SERRCTR | FM_SLSTCTR | FM_STRTEXP | FM_SMULTDA | FM_SRNGOP ; -static const int mac_imsk3u = FM_SRCVOVR2 | FM_SRBFL2 ; -static const int mac_imsk3l = FM_SRPERRQ2 | FM_SRPERRQ1 ; +static int mac_imsk3u = FM_SRCVOVR2 | FM_SRBFL2 ; +static int mac_imsk3l = FM_SRPERRQ2 | FM_SRPERRQ1 ; -static const int mac_beacon_imsk2u = FM_SOTRBEC | FM_SMYBEC | FM_SBEC | +static int mac_beacon_imsk2u = FM_SOTRBEC | FM_SMYBEC | FM_SBEC | FM_SLOCLM | FM_SHICLM | FM_SMYCLM | FM_SCLM ; @@ -549,12 +549,12 @@ void formac_tx_restart(struct s_smc *smc) static void enable_formac(struct s_smc *smc) { /* set formac IMSK : 0 enables irq */ - outpw(FM_A(FM_IMSK1U),(unsigned short)~mac_imsk1u); - outpw(FM_A(FM_IMSK1L),(unsigned short)~mac_imsk1l); - outpw(FM_A(FM_IMSK2U),(unsigned short)~mac_imsk2u); - outpw(FM_A(FM_IMSK2L),(unsigned short)~mac_imsk2l); - outpw(FM_A(FM_IMSK3U),(unsigned short)~mac_imsk3u); - outpw(FM_A(FM_IMSK3L),(unsigned short)~mac_imsk3l); + outpw(FM_A(FM_IMSK1U),~mac_imsk1u) ; + outpw(FM_A(FM_IMSK1L),~mac_imsk1l) ; + outpw(FM_A(FM_IMSK2U),~mac_imsk2u) ; + outpw(FM_A(FM_IMSK2L),~mac_imsk2l) ; + outpw(FM_A(FM_IMSK3U),~mac_imsk3u) ; + outpw(FM_A(FM_IMSK3L),~mac_imsk3l) ; } #if 0 /* Removed because the driver should use the ASICs TX complete IRQ. */ diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c index 74e129f3c..cd0aa4c15 100644 --- a/drivers/net/skfp/pcmplc.c +++ b/drivers/net/skfp/pcmplc.c @@ -186,7 +186,7 @@ static const struct plt { * Do we need the EBUF error during signaling, too, to detect SUPERNET_3 * PLL bug? */ -static const int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK | +static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK | PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR; #else /* SUPERNET_3 */ /* @@ -195,7 +195,7 @@ static const int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK | static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK | PL_PCM_ENABLED | PL_SELF_TEST ; #endif /* SUPERNET_3 */ -static const int plc_imsk_act = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK | +static int plc_imsk_act = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK | PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR; /* external functions */ diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index c7fb61330..4b5ed2c63 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -67,7 +67,7 @@ /* each new release!!! */ #define VERSION "2.07" -static const char * const boot_msg = +static const char *boot_msg = "SysKonnect FDDI PCI Adapter driver v" VERSION " for\n" " SK-55xx/SK-58xx adapters (SK-NET FDDI-FP/UP/LP)"; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 5ca5a1b54..25e028b7c 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -44,7 +44,7 @@ #include "skge.h" #define DRV_NAME "skge" -#define DRV_VERSION "1.5" +#define DRV_VERSION "1.3" #define PFX DRV_NAME " " #define DEFAULT_TX_RING_SIZE 128 @@ -78,7 +78,6 @@ static const struct pci_device_id skge_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, /* DGE-530T */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, @@ -105,6 +104,7 @@ static const int txqaddr[] = { Q_XA1, Q_XA2 }; static const int rxqaddr[] = { Q_R1, Q_R2 }; static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; +static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 }; static int skge_get_regs_len(struct net_device *dev) { @@ -358,7 +358,7 @@ static struct net_device_stats *skge_get_stats(struct net_device *dev) skge->net_stats.rx_bytes = data[1]; skge->net_stats.tx_packets = data[2] + data[4] + data[6]; skge->net_stats.rx_packets = data[3] + data[5] + data[7]; - skge->net_stats.multicast = data[3] + data[5]; + skge->net_stats.multicast = data[5] + data[7]; skge->net_stats.collisions = data[10]; skge->net_stats.tx_aborted_errors = data[12]; @@ -401,7 +401,7 @@ static int skge_set_ring_param(struct net_device *dev, int err; if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE || - p->tx_pending < MAX_SKB_FRAGS+1 || p->tx_pending > MAX_TX_RING_SIZE) + p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE) return -EINVAL; skge->rx_ring.count = p->rx_pending; @@ -728,18 +728,19 @@ static struct ethtool_ops skge_ethtool_ops = { * Allocate ring elements and chain them together * One-to-one association of board descriptors with ring elements */ -static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base) +static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base) { struct skge_tx_desc *d; struct skge_element *e; int i; - ring->start = kcalloc(sizeof(*e), ring->count, GFP_KERNEL); + ring->start = kmalloc(sizeof(*e)*ring->count, GFP_KERNEL); if (!ring->start) return -ENOMEM; for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) { e->desc = d; + e->skb = NULL; if (i == ring->count - 1) { e->next = ring->start; d->next_offset = base; @@ -782,7 +783,7 @@ static void skge_rx_setup(struct skge_port *skge, struct skge_element *e, * Note: DMA address is not changed by chip. * MTU not changed while receiver active. */ -static inline void skge_rx_reuse(struct skge_element *e, unsigned int size) +static void skge_rx_reuse(struct skge_element *e, unsigned int size) { struct skge_rx_desc *rd = e->desc; @@ -830,7 +831,7 @@ static int skge_rx_fill(struct skge_port *skge) do { struct sk_buff *skb; - skb = alloc_skb(skge->rx_buf_size + NET_IP_ALIGN, GFP_KERNEL); + skb = dev_alloc_skb(skge->rx_buf_size + NET_IP_ALIGN); if (!skb) return -ENOMEM; @@ -848,7 +849,8 @@ static void skge_link_up(struct skge_port *skge) LED_BLK_OFF|LED_SYNC_OFF|LED_ON); netif_carrier_on(skge->netdev); - netif_wake_queue(skge->netdev); + if (skge->tx_avail > MAX_SKB_FRAGS + 1) + netif_wake_queue(skge->netdev); if (netif_msg_link(skge)) printk(KERN_INFO PFX @@ -2155,7 +2157,7 @@ static int skge_up(struct net_device *dev) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); if (dev->mtu > RX_BUF_SIZE) - skge->rx_buf_size = dev->mtu + ETH_HLEN; + skge->rx_buf_size = dev->mtu + ETH_HLEN + NET_IP_ALIGN; else skge->rx_buf_size = RX_BUF_SIZE; @@ -2167,29 +2169,27 @@ static int skge_up(struct net_device *dev) if (!skge->mem) return -ENOMEM; - BUG_ON(skge->dma & 7); - - if ((u64)skge->dma >> 32 != ((u64) skge->dma + skge->mem_size) >> 32) { - printk(KERN_ERR PFX "pci_alloc_consistent region crosses 4G boundary\n"); - err = -EINVAL; - goto free_pci_mem; - } - memset(skge->mem, 0, skge->mem_size); - err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma); - if (err) + if ((err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma))) goto free_pci_mem; err = skge_rx_fill(skge); if (err) goto free_rx_ring; - err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size, - skge->dma + rx_size); - if (err) + if ((err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size, + skge->dma + rx_size))) goto free_rx_ring; + skge->tx_avail = skge->tx_ring.count - 1; + + /* Enable IRQ from port */ + spin_lock_irq(&hw->hw_lock); + hw->intr_mask |= portirqmask[port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); + /* Initialize MAC */ spin_lock_bh(&hw->phy_lock); if (hw->chip_id == CHIP_ID_GENESIS) @@ -2246,6 +2246,11 @@ static int skge_down(struct net_device *dev) else yukon_stop(skge); + spin_lock_irq(&hw->hw_lock); + hw->intr_mask &= ~portirqmask[skge->port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); + /* Stop transmitter */ skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), @@ -2292,12 +2297,6 @@ static int skge_down(struct net_device *dev) return 0; } -static inline int skge_avail(const struct skge_ring *ring) -{ - return ((ring->to_clean > ring->to_use) ? 0 : ring->count) - + (ring->to_clean - ring->to_use) - 1; -} - static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) { struct skge_port *skge = netdev_priv(dev); @@ -2308,24 +2307,27 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) int i; u32 control, len; u64 map; + unsigned long flags; skb = skb_padto(skb, ETH_ZLEN); if (!skb) return NETDEV_TX_OK; + local_irq_save(flags); if (!spin_trylock(&skge->tx_lock)) { - /* Collision - tell upper layer to requeue */ - return NETDEV_TX_LOCKED; - } + /* Collision - tell upper layer to requeue */ + local_irq_restore(flags); + return NETDEV_TX_LOCKED; + } - if (unlikely(skge_avail(&skge->tx_ring) < skb_shinfo(skb)->nr_frags + 1)) { + if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) { if (!netif_queue_stopped(dev)) { netif_stop_queue(dev); printk(KERN_WARNING PFX "%s: ring full when queue awake!\n", dev->name); } - spin_unlock(&skge->tx_lock); + spin_unlock_irqrestore(&skge->tx_lock, flags); return NETDEV_TX_BUSY; } @@ -2394,51 +2396,49 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) dev->name, e - ring->start, skb->len); ring->to_use = e->next; - if (skge_avail(&skge->tx_ring) <= MAX_SKB_FRAGS + 1) { + skge->tx_avail -= skb_shinfo(skb)->nr_frags + 1; + if (skge->tx_avail <= MAX_SKB_FRAGS + 1) { pr_debug("%s: transmit queue full\n", dev->name); netif_stop_queue(dev); } - mmiowb(); - spin_unlock(&skge->tx_lock); - dev->trans_start = jiffies; + spin_unlock_irqrestore(&skge->tx_lock, flags); return NETDEV_TX_OK; } -static void skge_tx_complete(struct skge_port *skge, struct skge_element *last) +static inline void skge_tx_free(struct skge_hw *hw, struct skge_element *e) { - struct pci_dev *pdev = skge->hw->pdev; - struct skge_element *e; - - for (e = skge->tx_ring.to_clean; e != last; e = e->next) { - struct sk_buff *skb = e->skb; - int i; - + /* This ring element can be skb or fragment */ + if (e->skb) { + pci_unmap_single(hw->pdev, + pci_unmap_addr(e, mapaddr), + pci_unmap_len(e, maplen), + PCI_DMA_TODEVICE); + dev_kfree_skb_any(e->skb); e->skb = NULL; - pci_unmap_single(pdev, pci_unmap_addr(e, mapaddr), - skb_headlen(skb), PCI_DMA_TODEVICE); - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - e = e->next; - pci_unmap_page(pdev, pci_unmap_addr(e, mapaddr), - skb_shinfo(skb)->frags[i].size, - PCI_DMA_TODEVICE); - } - - dev_kfree_skb(skb); + } else { + pci_unmap_page(hw->pdev, + pci_unmap_addr(e, mapaddr), + pci_unmap_len(e, maplen), + PCI_DMA_TODEVICE); } - skge->tx_ring.to_clean = e; } static void skge_tx_clean(struct skge_port *skge) { + struct skge_ring *ring = &skge->tx_ring; + struct skge_element *e; + unsigned long flags; - spin_lock_bh(&skge->tx_lock); - skge_tx_complete(skge, skge->tx_ring.to_use); - netif_wake_queue(skge->netdev); - spin_unlock_bh(&skge->tx_lock); + spin_lock_irqsave(&skge->tx_lock, flags); + for (e = ring->to_clean; e != ring->to_use; e = e->next) { + ++skge->tx_avail; + skge_tx_free(skge->hw, e); + } + ring->to_clean = e; + spin_unlock_irqrestore(&skge->tx_lock, flags); } static void skge_tx_timeout(struct net_device *dev) @@ -2597,7 +2597,7 @@ static inline struct sk_buff *skge_rx_get(struct skge_port *skge, goto error; if (len < RX_COPY_THRESHOLD) { - skb = alloc_skb(len + 2, GFP_ATOMIC); + skb = dev_alloc_skb(len + 2); if (!skb) goto resubmit; @@ -2612,11 +2612,10 @@ static inline struct sk_buff *skge_rx_get(struct skge_port *skge, skge_rx_reuse(e, skge->rx_buf_size); } else { struct sk_buff *nskb; - nskb = alloc_skb(skge->rx_buf_size + NET_IP_ALIGN, GFP_ATOMIC); + nskb = dev_alloc_skb(skge->rx_buf_size + NET_IP_ALIGN); if (!nskb) goto resubmit; - skb_reserve(nskb, NET_IP_ALIGN); pci_unmap_single(skge->hw->pdev, pci_unmap_addr(e, mapaddr), pci_unmap_len(e, maplen), @@ -2664,36 +2663,6 @@ resubmit: return NULL; } -static void skge_tx_done(struct skge_port *skge) -{ - struct skge_ring *ring = &skge->tx_ring; - struct skge_element *e, *last; - - spin_lock(&skge->tx_lock); - last = ring->to_clean; - for (e = ring->to_clean; e != ring->to_use; e = e->next) { - struct skge_tx_desc *td = e->desc; - - if (td->control & BMU_OWN) - break; - - if (td->control & BMU_EOF) { - last = e->next; - if (unlikely(netif_msg_tx_done(skge))) - printk(KERN_DEBUG PFX "%s: tx done slot %td\n", - skge->netdev->name, e - ring->start); - } - } - - skge_tx_complete(skge, last); - - skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F); - - if (skge_avail(&skge->tx_ring) > MAX_SKB_FRAGS + 1) - netif_wake_queue(skge->netdev); - - spin_unlock(&skge->tx_lock); -} static int skge_poll(struct net_device *dev, int *budget) { @@ -2701,10 +2670,8 @@ static int skge_poll(struct net_device *dev, int *budget) struct skge_hw *hw = skge->hw; struct skge_ring *ring = &skge->rx_ring; struct skge_element *e; - int to_do = min(dev->quota, *budget); - int work_done = 0; - - skge_tx_done(skge); + unsigned int to_do = min(dev->quota, *budget); + unsigned int work_done = 0; for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) { struct skge_rx_desc *rd = e->desc; @@ -2716,13 +2683,15 @@ static int skge_poll(struct net_device *dev, int *budget) if (control & BMU_OWN) break; - skb = skge_rx_get(skge, e, control, rd->status, rd->csum2); + skb = skge_rx_get(skge, e, control, rd->status, + le16_to_cpu(rd->csum2)); if (likely(skb)) { dev->last_rx = jiffies; netif_receive_skb(skb); ++work_done; - } + } else + skge_rx_reuse(e, skge->rx_buf_size); } ring->to_clean = e; @@ -2736,15 +2705,49 @@ static int skge_poll(struct net_device *dev, int *budget) if (work_done >= to_do) return 1; /* not done */ - netif_rx_complete(dev); - mmiowb(); - - hw->intr_mask |= skge->port == 0 ? (IS_R1_F|IS_XA1_F) : (IS_R2_F|IS_XA2_F); + spin_lock_irq(&hw->hw_lock); + __netif_rx_complete(dev); + hw->intr_mask |= portirqmask[skge->port]; skge_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); return 0; } +static inline void skge_tx_intr(struct net_device *dev) +{ + struct skge_port *skge = netdev_priv(dev); + struct skge_hw *hw = skge->hw; + struct skge_ring *ring = &skge->tx_ring; + struct skge_element *e; + + spin_lock(&skge->tx_lock); + for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) { + struct skge_tx_desc *td = e->desc; + u32 control; + + rmb(); + control = td->control; + if (control & BMU_OWN) + break; + + if (unlikely(netif_msg_tx_done(skge))) + printk(KERN_DEBUG PFX "%s: tx done slot %td status 0x%x\n", + dev->name, e - ring->start, td->status); + + skge_tx_free(hw, e); + e->skb = NULL; + ++skge->tx_avail; + } + ring->to_clean = e; + skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F); + + if (skge->tx_avail > MAX_SKB_FRAGS + 1) + netif_wake_queue(dev); + + spin_unlock(&skge->tx_lock); +} + /* Parity errors seem to happen when Genesis is connected to a switch * with no other ports present. Heartbeat error?? */ @@ -2767,6 +2770,17 @@ static void skge_mac_parity(struct skge_hw *hw, int port) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE); } +static void skge_pci_clear(struct skge_hw *hw) +{ + u16 status; + + pci_read_config_word(hw->pdev, PCI_STATUS, &status); + skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); + pci_write_config_word(hw->pdev, PCI_STATUS, + status | PCI_STATUS_ERROR_BITS); + skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); +} + static void skge_mac_intr(struct skge_hw *hw, int port) { if (hw->chip_id == CHIP_ID_GENESIS) @@ -2808,39 +2822,23 @@ static void skge_error_irq(struct skge_hw *hw) if (hwstatus & IS_M2_PAR_ERR) skge_mac_parity(hw, 1); - if (hwstatus & IS_R1_PAR_ERR) { - printk(KERN_ERR PFX "%s: receive queue parity error\n", - hw->dev[0]->name); + if (hwstatus & IS_R1_PAR_ERR) skge_write32(hw, B0_R1_CSR, CSR_IRQ_CL_P); - } - if (hwstatus & IS_R2_PAR_ERR) { - printk(KERN_ERR PFX "%s: receive queue parity error\n", - hw->dev[1]->name); + if (hwstatus & IS_R2_PAR_ERR) skge_write32(hw, B0_R2_CSR, CSR_IRQ_CL_P); - } if (hwstatus & (IS_IRQ_MST_ERR|IS_IRQ_STAT)) { - u16 pci_status, pci_cmd; + printk(KERN_ERR PFX "hardware error detected (status 0x%x)\n", + hwstatus); - pci_read_config_word(hw->pdev, PCI_COMMAND, &pci_cmd); - pci_read_config_word(hw->pdev, PCI_STATUS, &pci_status); - - printk(KERN_ERR PFX "%s: PCI error cmd=%#x status=%#x\n", - pci_name(hw->pdev), pci_cmd, pci_status); - - /* Write the error bits back to clear them. */ - pci_status &= PCI_STATUS_ERROR_BITS; - skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - pci_write_config_word(hw->pdev, PCI_COMMAND, - pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY); - pci_write_config_word(hw->pdev, PCI_STATUS, pci_status); - skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + skge_pci_clear(hw); /* if error still set then just ignore it */ hwstatus = skge_read32(hw, B0_HWE_ISRC); if (hwstatus & IS_IRQ_STAT) { - printk(KERN_INFO PFX "unable to clear error (so ignoring them)\n"); + pr_debug("IRQ status %x: still set ignoring hardware errors\n", + hwstatus); hw->intr_mask &= ~IS_HW_ERR; } } @@ -2857,11 +2855,12 @@ static void skge_extirq(unsigned long data) int port; spin_lock(&hw->phy_lock); - for (port = 0; port < hw->ports; port++) { + for (port = 0; port < 2; port++) { struct net_device *dev = hw->dev[port]; - struct skge_port *skge = netdev_priv(dev); - if (netif_running(dev)) { + if (dev && netif_running(dev)) { + struct skge_port *skge = netdev_priv(dev); + if (hw->chip_id != CHIP_ID_GENESIS) yukon_phy_intr(skge); else @@ -2870,39 +2869,38 @@ static void skge_extirq(unsigned long data) } spin_unlock(&hw->phy_lock); + spin_lock_irq(&hw->hw_lock); hw->intr_mask |= IS_EXT_REG; skge_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); } static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) { struct skge_hw *hw = dev_id; - u32 status; + u32 status = skge_read32(hw, B0_SP_ISRC); - /* Reading this register masks IRQ */ - status = skge_read32(hw, B0_SP_ISRC); - if (status == 0) + if (status == 0 || status == ~0) /* hotplug or shared irq */ return IRQ_NONE; - if (status & IS_EXT_REG) { - hw->intr_mask &= ~IS_EXT_REG; - tasklet_schedule(&hw->ext_tasklet); - } - - if (status & (IS_R1_F|IS_XA1_F)) { + spin_lock(&hw->hw_lock); + if (status & IS_R1_F) { skge_write8(hw, Q_ADDR(Q_R1, Q_CSR), CSR_IRQ_CL_F); - hw->intr_mask &= ~(IS_R1_F|IS_XA1_F); + hw->intr_mask &= ~IS_R1_F; netif_rx_schedule(hw->dev[0]); } - if (status & (IS_R2_F|IS_XA2_F)) { + if (status & IS_R2_F) { skge_write8(hw, Q_ADDR(Q_R2, Q_CSR), CSR_IRQ_CL_F); - hw->intr_mask &= ~(IS_R2_F|IS_XA2_F); + hw->intr_mask &= ~IS_R2_F; netif_rx_schedule(hw->dev[1]); } - if (likely((status & hw->intr_mask) == 0)) - return IRQ_HANDLED; + if (status & IS_XA1_F) + skge_tx_intr(hw->dev[0]); + + if (status & IS_XA2_F) + skge_tx_intr(hw->dev[1]); if (status & IS_PA_TO_RX1) { struct skge_port *skge = netdev_priv(hw->dev[0]); @@ -2931,7 +2929,13 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) if (status & IS_HW_ERR) skge_error_irq(hw); + if (status & IS_EXT_REG) { + hw->intr_mask &= ~IS_EXT_REG; + tasklet_schedule(&hw->ext_tasklet); + } + skge_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock(&hw->hw_lock); return IRQ_HANDLED; } @@ -3006,7 +3010,7 @@ static const char *skge_board_name(const struct skge_hw *hw) static int skge_reset(struct skge_hw *hw) { u32 reg; - u16 ctst, pci_status; + u16 ctst; u8 t8, mac_cfg, pmd_type, phy_type; int i; @@ -3017,13 +3021,8 @@ static int skge_reset(struct skge_hw *hw) skge_write8(hw, B0_CTST, CS_RST_CLR); /* clear PCI errors, if any */ - skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - skge_write8(hw, B2_TST_CTRL2, 0); + skge_pci_clear(hw); - pci_read_config_word(hw->pdev, PCI_STATUS, &pci_status); - pci_write_config_word(hw->pdev, PCI_STATUS, - pci_status | PCI_STATUS_ERROR_BITS); - skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); skge_write8(hw, B0_CTST, CS_MRST_CLR); /* restore CLK_RUN bits (for Yukon-Lite) */ @@ -3082,10 +3081,7 @@ static int skge_reset(struct skge_hw *hw) else hw->ram_size = t8 * 4096; - hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; - if (hw->ports > 1) - hw->intr_mask |= IS_PORT_2; - + hw->intr_mask = IS_HW_ERR | IS_EXT_REG; if (hw->chip_id == CHIP_ID_GENESIS) genesis_init(hw); else { @@ -3255,15 +3251,13 @@ static int __devinit skge_probe(struct pci_dev *pdev, struct skge_hw *hw; int err, using_dac = 0; - err = pci_enable_device(pdev); - if (err) { + if ((err = pci_enable_device(pdev))) { printk(KERN_ERR PFX "%s cannot enable PCI device\n", pci_name(pdev)); goto err_out; } - err = pci_request_regions(pdev, DRV_NAME); - if (err) { + if ((err = pci_request_regions(pdev, DRV_NAME))) { printk(KERN_ERR PFX "%s cannot obtain PCI resources\n", pci_name(pdev)); goto err_out_disable_pdev; @@ -3271,18 +3265,22 @@ static int __devinit skge_probe(struct pci_dev *pdev, pci_set_master(pdev); - if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { + if (sizeof(dma_addr_t) > sizeof(u32) && + !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { using_dac = 1; err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); - } else if (!(err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) { - using_dac = 0; - err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); - } - - if (err) { - printk(KERN_ERR PFX "%s no usable DMA configuration\n", - pci_name(pdev)); - goto err_out_free_regions; + if (err < 0) { + printk(KERN_ERR PFX "%s unable to obtain 64 bit DMA " + "for consistent allocations\n", pci_name(pdev)); + goto err_out_free_regions; + } + } else { + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (err) { + printk(KERN_ERR PFX "%s no usable DMA configuration\n", + pci_name(pdev)); + goto err_out_free_regions; + } } #ifdef __BIG_ENDIAN @@ -3306,6 +3304,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, hw->pdev = pdev; spin_lock_init(&hw->phy_lock); + spin_lock_init(&hw->hw_lock); tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); @@ -3315,8 +3314,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, goto err_out_free_hw; } - err = request_irq(pdev->irq, skge_intr, SA_SHIRQ, DRV_NAME, hw); - if (err) { + if ((err = request_irq(pdev->irq, skge_intr, SA_SHIRQ, DRV_NAME, hw))) { printk(KERN_ERR PFX "%s: cannot assign irq %d\n", pci_name(pdev), pdev->irq); goto err_out_iounmap; @@ -3334,8 +3332,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) goto err_out_led_off; - err = register_netdev(dev); - if (err) { + if ((err = register_netdev(dev))) { printk(KERN_ERR PFX "%s: cannot register net device\n", pci_name(pdev)); goto err_out_free_netdev; @@ -3390,6 +3387,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) skge_write32(hw, B0_IMSK, 0); skge_write16(hw, B0_LED, LED_STAT_OFF); + skge_pci_clear(hw); skge_write8(hw, B0_CTST, CS_RST_SET); tasklet_kill(&hw->ext_tasklet); diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 1f1ce88c8..941f12a33 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -2402,6 +2402,7 @@ struct skge_hw { struct tasklet_struct ext_tasklet; spinlock_t phy_lock; + spinlock_t hw_lock; }; enum { @@ -2418,6 +2419,7 @@ struct skge_port { int port; spinlock_t tx_lock; + u32 tx_avail; struct skge_ring tx_ring; struct skge_ring rx_ring; diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 4103e304f..d77358649 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -51,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.6.1" +#define DRV_VERSION "0.15" #define PFX DRV_NAME " " /* @@ -61,6 +61,10 @@ * a receive requires one (or two if using 64 bit dma). */ +#define is_ec_a1(hw) \ + unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \ + (hw)->chip_rev == CHIP_REV_YU_EC_A1) + #define RX_LE_SIZE 512 #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) #define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) @@ -79,8 +83,6 @@ #define NAPI_WEIGHT 64 #define PHY_RETRIES 1000 -#define RING_NEXT(x,s) (((x)+1) & ((s)-1)) - static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR @@ -94,18 +96,11 @@ static int copybreak __read_mostly = 256; module_param(copybreak, int, 0); MODULE_PARM_DESC(copybreak, "Receive copy threshold"); -static int disable_msi = 0; -module_param(disable_msi, int, 0); -MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); - -static int idle_timeout = 100; -module_param(idle_timeout, int, 0); -MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)"); - static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */ + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, @@ -129,7 +124,6 @@ MODULE_DEVICE_TABLE(pci, sky2_id_table); /* Avoid conditionals by using array */ static const unsigned txqaddr[] = { Q_XA1, Q_XA2 }; static const unsigned rxqaddr[] = { Q_R1, Q_R2 }; -static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 }; /* This driver supports yukon2 chipset only */ static const char *yukon2_name[] = { @@ -187,11 +181,12 @@ static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) return v; } -static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) +static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) { u16 power_control; u32 reg1; int vaux; + int ret = 0; pr_debug("sky2_set_power_state %d\n", state); sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); @@ -233,11 +228,8 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) if (hw->ports > 1) reg1 |= PCI_Y2_PHY2_COMA; } - sky2_pci_write32(hw, PCI_DEV_REG1, reg1); - udelay(100); if (hw->chip_id == CHIP_ID_YUKON_EC_U) { - sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON); sky2_pci_write32(hw, PCI_DEV_REG3, 0); reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); reg1 &= P_ASPM_CONTROL_MSK; @@ -245,6 +237,8 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) sky2_pci_write32(hw, PCI_DEV_REG5, 0); } + sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + break; case PCI_D3hot: @@ -274,10 +268,12 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) break; default: printk(KERN_ERR PFX "Unknown power state %d\n", state); + ret = -1; } sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + return ret; } static void sky2_phy_reset(struct sky2_hw *hw, unsigned port) @@ -304,8 +300,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) struct sky2_port *sky2 = netdev_priv(hw->dev[port]); u16 ctrl, ct1000, adv, pg, ledctrl, ledover; - if (sky2->autoneg == AUTONEG_ENABLE && - !(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { + if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) { u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | @@ -333,7 +328,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); if (sky2->autoneg == AUTONEG_ENABLE && - (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { + hw->chip_id == CHIP_ID_YUKON_XL) { ctrl &= ~PHY_M_PC_DSC_MSK; ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; } @@ -465,11 +460,10 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); /* set LED Function Control register */ - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, - (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ - PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ - PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ - PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ + PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ + PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ + PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ /* set Polarity Control register */ gm_phy_write(hw, port, PHY_MARV_PHY_STAT, @@ -483,25 +477,6 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* restore page register */ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); break; - case CHIP_ID_YUKON_EC_U: - pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - - /* select page 3 to access LED control register */ - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - - /* set LED Function Control register */ - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, - (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ - PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */ - PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ - PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */ - - /* set Blink Rate in LED Timer Control Register */ - gm_phy_write(hw, port, PHY_MARV_INT_MASK, - ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS)); - /* restore page register */ - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - break; default: /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ @@ -510,21 +485,19 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); } - if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) { + if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { /* apply fixes in PHY AFE */ - pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255); - + gm_phy_write(hw, port, 22, 255); /* increase differential signal amplitude in 10BASE-T */ - gm_phy_write(hw, port, 0x18, 0xaa99); - gm_phy_write(hw, port, 0x17, 0x2011); + gm_phy_write(hw, port, 24, 0xaa99); + gm_phy_write(hw, port, 23, 0x2011); /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ - gm_phy_write(hw, port, 0x18, 0xa204); - gm_phy_write(hw, port, 0x17, 0x2002); + gm_phy_write(hw, port, 24, 0xa204); + gm_phy_write(hw, port, 23, 0x2002); /* set page register to 0 */ - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); + gm_phy_write(hw, port, 22, 0); } else { gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); @@ -547,9 +520,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* Force a renegotiation */ static void sky2_phy_reinit(struct sky2_port *sky2) { - spin_lock_bh(&sky2->phy_lock); + down(&sky2->phy_sema); sky2_phy_init(sky2->hw, sky2->port); - spin_unlock_bh(&sky2->phy_lock); + up(&sky2->phy_sema); } static void sky2_mac_init(struct sky2_hw *hw, unsigned port) @@ -598,11 +571,6 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) if (sky2->duplex == DUPLEX_FULL) reg |= GM_GPCR_DUP_FULL; - - /* turn off pause in 10/100mbps half duplex */ - else if (sky2->speed != SPEED_1000 && - hw->chip_id != CHIP_ID_YUKON_EC_U) - sky2->tx_pause = sky2->rx_pause = 0; } else reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; @@ -619,9 +587,9 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); - spin_lock_bh(&sky2->phy_lock); + down(&sky2->phy_sema); sky2_phy_init(hw, port); - spin_unlock_bh(&sky2->phy_lock); + up(&sky2->phy_sema); /* MIB clear */ reg = gma_read16(hw, port, GM_PHY_ADDR); @@ -769,15 +737,41 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2) { struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod; - sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE); + sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE; return le; } -/* Update chip's next pointer */ -static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) +/* + * This is a workaround code taken from SysKonnect sk98lin driver + * to deal with chip bug on Yukon EC rev 0 in the wraparound case. + */ +static void sky2_put_idx(struct sky2_hw *hw, unsigned q, + u16 idx, u16 *last, u16 size) { wmb(); - sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); + if (is_ec_a1(hw) && idx < *last) { + u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX)); + + if (hwget == 0) { + /* Start prefetching again */ + sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0); + goto setnew; + } + + if (hwget == size - 1) { + /* set watermark to one list element */ + sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8); + + /* set put index to first list element */ + sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0); + } else /* have hardware go to end of list */ + sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), + size - 1); + } else { +setnew: + sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); + } + *last = idx; mmiowb(); } @@ -785,7 +779,7 @@ static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2) { struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put; - sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE); + sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE; return le; } @@ -900,7 +894,7 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!netif_running(dev)) return -ENODEV; /* Phy still in reset */ - switch (cmd) { + switch(cmd) { case SIOCGMIIPHY: data->phy_id = PHY_ADDR_MARV; @@ -908,9 +902,9 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: { u16 val = 0; - spin_lock_bh(&sky2->phy_lock); + down(&sky2->phy_sema); err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val); - spin_unlock_bh(&sky2->phy_lock); + up(&sky2->phy_sema); data->val_out = val; break; @@ -920,10 +914,10 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!capable(CAP_NET_ADMIN)) return -EPERM; - spin_lock_bh(&sky2->phy_lock); + down(&sky2->phy_sema); err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f, data->val_in); - spin_unlock_bh(&sky2->phy_lock); + up(&sky2->phy_sema); break; } return err; @@ -975,7 +969,8 @@ static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask) skb = __dev_alloc_skb(size + RX_SKB_ALIGN, gfp_mask); if (likely(skb)) { unsigned long p = (unsigned long) skb->data; - skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); + skb_reserve(skb, + ((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p); } return skb; @@ -992,7 +987,6 @@ static int sky2_rx_start(struct sky2_port *sky2) struct sky2_hw *hw = sky2->hw; unsigned rxq = rxqaddr[sky2->port]; int i; - unsigned thresh; sky2->rx_put = sky2->rx_next = 0; sky2_qset(hw, rxq); @@ -1017,24 +1011,13 @@ static int sky2_rx_start(struct sky2_port *sky2) sky2_rx_add(sky2, re->mapaddr); } - - /* - * The receiver hangs if it receives frames larger than the - * packet buffer. As a workaround, truncate oversize frames, but - * the register is limited to 9 bits, so if you do frames > 2052 - * you better get the MTU right! - */ - thresh = (sky2->rx_bufsize - 8) / sizeof(u32); - if (thresh > 0x1ff) - sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF); - else { - sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), thresh); - sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); - } - + /* Truncate oversize frames */ + sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8); + sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); /* Tell chip about available buffers */ sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); + sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); return 0; nomem: sky2_rx_clean(sky2); @@ -1047,26 +1030,8 @@ static int sky2_up(struct net_device *dev) struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; - u32 ramsize, rxspace, imask; - int cap, err = -ENOMEM; - struct net_device *otherdev = hw->dev[sky2->port^1]; - - /* - * On dual port PCI-X card, there is an problem where status - * can be received out of order due to split transactions - */ - if (otherdev && netif_running(otherdev) && - (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) { - struct sky2_port *osky2 = netdev_priv(otherdev); - u16 cmd; - - cmd = sky2_pci_read16(hw, cap + PCI_X_CMD); - cmd &= ~PCI_X_CMD_MAX_SPLIT; - sky2_pci_write16(hw, cap + PCI_X_CMD, cmd); - - sky2->rx_csum = 0; - osky2->rx_csum = 0; - } + u32 ramsize, rxspace; + int err = -ENOMEM; if (netif_msg_ifup(sky2)) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); @@ -1130,10 +1095,10 @@ static int sky2_up(struct net_device *dev) goto err_out; /* Enable interrupts from phy/mac for port */ - imask = sky2_read32(hw, B0_IMSK); - imask |= portirq_msk[port]; - sky2_write32(hw, B0_IMSK, imask); - + spin_lock_irq(&hw->hw_lock); + hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; + sky2_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); return 0; err_out: @@ -1159,7 +1124,7 @@ err_out: /* Modular subtraction in ring */ static inline int tx_dist(unsigned tail, unsigned head) { - return (head - tail) & (TX_RING_SIZE - 1); + return (head - tail) % TX_RING_SIZE; } /* Number of list elements available for next tx */ @@ -1176,7 +1141,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) count = sizeof(dma_addr_t) / sizeof(u32); count += skb_shinfo(skb)->nr_frags * count; - if (skb_is_gso(skb)) + if (skb_shinfo(skb)->tso_size) ++count; if (skb->ip_summed == CHECKSUM_HW) @@ -1248,12 +1213,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) } /* Check for TCP Segmentation Offload */ - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; if (mss != 0) { /* just drop the packet if non-linear expansion fails */ if (skb_header_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); goto out_unlock; } @@ -1336,7 +1301,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) le->opcode = OP_BUFFER | HW_OWNER; fre = sky2->tx_ring - + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); + + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE; pci_unmap_addr_set(fre, mapaddr, mapping); } @@ -1350,7 +1315,8 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); } - sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); + sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, + &sky2->tx_last_put, TX_RING_SIZE); out_unlock: spin_unlock(&sky2->tx_lock); @@ -1382,7 +1348,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) struct tx_ring_info *re = sky2->tx_ring + put; struct sk_buff *skb = re->skb; - nxt = re->idx; + nxt = re->idx; BUG_ON(nxt >= TX_RING_SIZE); prefetch(sky2->tx_ring + nxt); @@ -1396,17 +1362,17 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { struct tx_ring_info *fre; - fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE); + fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE; pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr), - skb_shinfo(skb)->frags[i].size, + skb_shinfo(skb)->frags[i].size, PCI_DMA_TODEVICE); } - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); } sky2->tx_cons = put; - if (tx_avail(sky2) > MAX_SKB_TX_LE) + if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE) netif_wake_queue(dev); } @@ -1425,7 +1391,6 @@ static int sky2_down(struct net_device *dev) struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; u16 ctrl; - u32 imask; /* Never really got started! */ if (!sky2->tx_le) @@ -1437,6 +1402,14 @@ static int sky2_down(struct net_device *dev) /* Stop more packets from being queued */ netif_stop_queue(dev); + /* Disable port IRQ */ + spin_lock_irq(&hw->hw_lock); + hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); + sky2_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); + + flush_scheduled_work(); + sky2_phy_reset(hw, port); /* Stop transmitter */ @@ -1480,11 +1453,6 @@ static int sky2_down(struct net_device *dev) sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); - /* Disable port IRQ */ - imask = sky2_read32(hw, B0_IMSK); - imask &= ~portirq_msk[port]; - sky2_write32(hw, B0_IMSK, imask); - /* turn off LED's */ sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); @@ -1579,26 +1547,17 @@ static void sky2_link_up(struct sky2_port *sky2) sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); - if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) { + if (hw->chip_id == CHIP_ID_YUKON_XL) { u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ - - switch(sky2->speed) { - case SPEED_10: - led |= PHY_M_LEDC_INIT_CTRL(7); - break; - - case SPEED_100: - led |= PHY_M_LEDC_STA1_CTRL(7); - break; - - case SPEED_1000: - led |= PHY_M_LEDC_STA0_CTRL(7); - break; - } gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led); + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ + PHY_M_LEDC_INIT_CTRL(sky2->speed == + SPEED_10 ? 7 : 0) | + PHY_M_LEDC_STA1_CTRL(sky2->speed == + SPEED_100 ? 7 : 0) | + PHY_M_LEDC_STA0_CTRL(sky2->speed == + SPEED_1000 ? 7 : 0)); gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); } @@ -1673,7 +1632,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) sky2->speed = sky2_phy_speed(hw, aux); /* Pause bits are offset (9..8) */ - if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) + if (hw->chip_id == CHIP_ID_YUKON_XL) aux >>= 6; sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; @@ -1688,19 +1647,20 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) return 0; } -/* Interrupt from PHY */ -static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) +/* + * Interrupt from PHY are handled outside of interrupt context + * because accessing phy registers requires spin wait which might + * cause excess interrupt latency. + */ +static void sky2_phy_task(void *arg) { - struct net_device *dev = hw->dev[port]; - struct sky2_port *sky2 = netdev_priv(dev); + struct sky2_port *sky2 = arg; + struct sky2_hw *hw = sky2->hw; u16 istatus, phystat; - spin_lock(&sky2->phy_lock); - istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); - phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); - - if (!netif_running(dev)) - goto out; + down(&sky2->phy_sema); + istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT); + phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT); if (netif_msg_intr(sky2)) printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", @@ -1726,7 +1686,12 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) sky2_link_down(sky2); } out: - spin_unlock(&sky2->phy_lock); + up(&sky2->phy_sema); + + spin_lock_irq(&hw->hw_lock); + hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2; + sky2_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); } @@ -1738,49 +1703,41 @@ static void sky2_tx_timeout(struct net_device *dev) struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; unsigned txq = txqaddr[sky2->port]; - u16 report, done; - - if (netif_msg_timer(sky2)) - printk(KERN_ERR PFX "%s: tx timeout\n", dev->name); + u16 ridx; - report = sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX); - done = sky2_read16(hw, Q_ADDR(txq, Q_DONE)); - - printk(KERN_DEBUG PFX "%s: transmit ring %u .. %u report=%u done=%u\n", - dev->name, - sky2->tx_cons, sky2->tx_prod, report, done); - - if (report != done) { - printk(KERN_INFO PFX "status burst pending (irq moderation?)\n"); + /* Maybe we just missed an status interrupt */ + spin_lock(&sky2->tx_lock); + ridx = sky2_read16(hw, + sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX); + sky2_tx_complete(sky2, ridx); + spin_unlock(&sky2->tx_lock); - sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); - sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); - } else if (report != sky2->tx_cons) { - printk(KERN_INFO PFX "status report lost?\n"); + if (!netif_queue_stopped(dev)) { + if (net_ratelimit()) + pr_info(PFX "transmit interrupt missed? recovered\n"); + return; + } - spin_lock_bh(&sky2->tx_lock); - sky2_tx_complete(sky2, report); - spin_unlock_bh(&sky2->tx_lock); - } else { - printk(KERN_INFO PFX "hardware hung? flushing\n"); + if (netif_msg_timer(sky2)) + printk(KERN_ERR PFX "%s: tx timeout\n", dev->name); - sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP); - sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); + sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP); + sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); - sky2_tx_clean(sky2); + sky2_tx_clean(sky2); - sky2_qset(hw, txq); - sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1); - } + sky2_qset(hw, txq); + sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1); } +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* Want receive buffer size to be multiple of 64 bits * and incl room for vlan and truncation */ static inline unsigned sky2_buf_size(int mtu) { - return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; + return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; } static int sky2_change_mtu(struct net_device *dev, int new_mtu) @@ -1789,7 +1746,6 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) struct sky2_hw *hw = sky2->hw; int err; u16 ctl, mode; - u32 imask; if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) return -EINVAL; @@ -1802,15 +1758,12 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) return 0; } - imask = sky2_read32(hw, B0_IMSK); sky2_write32(hw, B0_IMSK, 0); dev->trans_start = jiffies; /* prevent tx timeout */ netif_stop_queue(dev); netif_poll_disable(hw->dev[0]); - synchronize_irq(hw->pdev->irq); - ctl = gma_read16(hw, sky2->port, GM_GP_CTRL); gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); sky2_rx_stop(sky2); @@ -1829,7 +1782,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD); err = sky2_rx_start(sky2); - sky2_write32(hw, B0_IMSK, imask); + sky2_write32(hw, B0_IMSK, hw->intr_mask); if (err) dev_close(dev); @@ -1906,7 +1859,8 @@ resubmit: sky2_rx_add(sky2, re->mapaddr); /* Tell receiver about new buffers. */ - sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put); + sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put, + &sky2->rx_last_put, RX_LE_SIZE); return skb; @@ -1933,33 +1887,55 @@ error: goto resubmit; } -/* Transmit complete */ -static inline void sky2_tx_done(struct net_device *dev, u16 last) +/* + * Check for transmit complete + */ +#define TX_NO_STATUS 0xffff + +static void sky2_tx_check(struct sky2_hw *hw, int port, u16 last) { - struct sky2_port *sky2 = netdev_priv(dev); + if (last != TX_NO_STATUS) { + struct net_device *dev = hw->dev[port]; + if (dev && netif_running(dev)) { + struct sky2_port *sky2 = netdev_priv(dev); - if (netif_running(dev)) { - spin_lock(&sky2->tx_lock); - sky2_tx_complete(sky2, last); - spin_unlock(&sky2->tx_lock); + spin_lock(&sky2->tx_lock); + sky2_tx_complete(sky2, last); + spin_unlock(&sky2->tx_lock); + } } } -/* Is status ring empty or is there more to do? */ -static inline int sky2_more_work(const struct sky2_hw *hw) +/* + * Both ports share the same status interrupt, therefore there is only + * one poll routine. + */ +static int sky2_poll(struct net_device *dev0, int *budget) { - return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX)); -} + struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; + unsigned int to_do = min(dev0->quota, *budget); + unsigned int work_done = 0; + u16 hwidx; + u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; -/* Process status response ring */ -static int sky2_status_intr(struct sky2_hw *hw, int to_do) -{ - int work_done = 0; - u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); + sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); + /* + * Kick the STAT_LEV_TIMER_CTRL timer. + * This fixes my hangs on Yukon-EC (0xb6) rev 1. + * The if clause is there to start the timer only if it has been + * configured correctly and not been disabled via ethtool. + */ + if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) { + sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP); + sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START); + } + + hwidx = sky2_read16(hw, STAT_PUT_IDX); + BUG_ON(hwidx >= STATUS_RING_SIZE); rmb(); - while (hw->st_idx != hwidx) { + while (hwidx != hw->st_idx) { struct sky2_status_le *le = hw->st_le + hw->st_idx; struct net_device *dev; struct sky2_port *sky2; @@ -1967,14 +1943,18 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) u32 status; u16 length; - hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); + le = hw->st_le + hw->st_idx; + hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE; + prefetch(hw->st_le + hw->st_idx); BUG_ON(le->link >= 2); dev = hw->dev[le->link]; + if (dev == NULL || !netif_running(dev)) + continue; sky2 = netdev_priv(dev); - length = le->length; - status = le->status; + status = le32_to_cpu(le->status); + length = le16_to_cpu(le->length); switch (le->opcode & ~HW_OWNER) { case OP_RXSTAT: @@ -2016,27 +1996,42 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) case OP_TXINDEXLE: /* TX index reports status for both ports */ - BUILD_BUG_ON(TX_RING_SIZE > 0x1000); - sky2_tx_done(hw->dev[0], status & 0xfff); - if (hw->dev[1]) - sky2_tx_done(hw->dev[1], - ((status >> 24) & 0xff) - | (u16)(length & 0xf) << 8); + tx_done[0] = status & 0xffff; + tx_done[1] = ((status >> 24) & 0xff) + | (u16)(length & 0xf) << 8; break; default: if (net_ratelimit()) printk(KERN_WARNING PFX "unknown status opcode 0x%x\n", le->opcode); - goto exit_loop; + break; } } - /* Fully processed status ring so clear irq */ - sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); - exit_loop: - return work_done; + sky2_tx_check(hw, 0, tx_done[0]); + sky2_tx_check(hw, 1, tx_done[1]); + + if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); + } + + if (likely(work_done < to_do)) { + spin_lock_irq(&hw->hw_lock); + __netif_rx_complete(dev0); + + hw->intr_mask |= Y2_IS_STAT_BMU; + sky2_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); + + return 0; + } else { + *budget -= work_done; + dev0->quota -= work_done; + return 1; + } } static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status) @@ -2155,60 +2150,42 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port) } } -/* This should never happen it is a fatal situation */ -static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, - const char *rxtx, u32 mask) +static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) { struct net_device *dev = hw->dev[port]; struct sky2_port *sky2 = netdev_priv(dev); - u32 imask; - - printk(KERN_ERR PFX "%s: %s descriptor error (hardware problem)\n", - dev ? dev->name : "", rxtx); - imask = sky2_read32(hw, B0_IMSK); - imask &= ~mask; - sky2_write32(hw, B0_IMSK, imask); - - if (dev) { - spin_lock(&sky2->phy_lock); - sky2_link_down(sky2); - spin_unlock(&sky2->phy_lock); - } -} + hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); + sky2_write32(hw, B0_IMSK, hw->intr_mask); -/* If idle then force a fake soft NAPI poll once a second - * to work around cases where sharing an edge triggered interrupt. - */ -static inline void sky2_idle_start(struct sky2_hw *hw) -{ - if (idle_timeout > 0) - mod_timer(&hw->idle_timer, - jiffies + msecs_to_jiffies(idle_timeout)); + schedule_work(&sky2->phy_task); } -static void sky2_idle(unsigned long arg) +static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct sky2_hw *hw = (struct sky2_hw *) arg; - struct net_device *dev = hw->dev[0]; - - if (__netif_rx_schedule_prep(dev)) - __netif_rx_schedule(dev); - - mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout)); -} - + struct sky2_hw *hw = dev_id; + struct net_device *dev0 = hw->dev[0]; + u32 status; -static int sky2_poll(struct net_device *dev0, int *budget) -{ - struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; - int work_limit = min(dev0->quota, *budget); - int work_done = 0; - u32 status = sky2_read32(hw, B0_Y2_SP_EISR); + status = sky2_read32(hw, B0_Y2_SP_ISRC2); + if (status == 0 || status == ~0) + return IRQ_NONE; + spin_lock(&hw->hw_lock); if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); + /* Do NAPI for Rx and Tx status */ + if (status & Y2_IS_STAT_BMU) { + hw->intr_mask &= ~Y2_IS_STAT_BMU; + sky2_write32(hw, B0_IMSK, hw->intr_mask); + + if (likely(__netif_rx_schedule_prep(dev0))) { + prefetch(&hw->st_le[hw->st_idx]); + __netif_rx_schedule(dev0); + } + } + if (status & Y2_IS_IRQ_PHY1) sky2_phy_intr(hw, 0); @@ -2221,45 +2198,9 @@ static int sky2_poll(struct net_device *dev0, int *budget) if (status & Y2_IS_IRQ_MAC2) sky2_mac_intr(hw, 1); - if (status & Y2_IS_CHK_RX1) - sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1); - - if (status & Y2_IS_CHK_RX2) - sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2); - - if (status & Y2_IS_CHK_TXA1) - sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1); - - if (status & Y2_IS_CHK_TXA2) - sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); - - work_done = sky2_status_intr(hw, work_limit); - *budget -= work_done; - dev0->quota -= work_done; - - if (sky2_more_work(hw)) - return 1; - - netif_rx_complete(dev0); - - sky2_read32(hw, B0_Y2_SP_LISR); - return 0; -} - -static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) -{ - struct sky2_hw *hw = dev_id; - struct net_device *dev0 = hw->dev[0]; - u32 status; - - /* Reading this mask interrupts as side effect */ - status = sky2_read32(hw, B0_Y2_SP_ISRC2); - if (status == 0 || status == ~0) - return IRQ_NONE; + sky2_write32(hw, B0_Y2_SP_ICR, 2); - prefetch(&hw->st_le[hw->st_idx]); - if (likely(__netif_rx_schedule_prep(dev0))) - __netif_rx_schedule(dev0); + spin_unlock(&hw->hw_lock); return IRQ_HANDLED; } @@ -2268,10 +2209,8 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) static void sky2_netpoll(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); - struct net_device *dev0 = sky2->hw->dev[0]; - if (netif_running(dev) && __netif_rx_schedule_prep(dev0)) - __netif_rx_schedule(dev0); + sky2_intr(sky2->hw->pdev->irq, sky2->hw, NULL); } #endif @@ -2300,7 +2239,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) } -static int __devinit sky2_reset(struct sky2_hw *hw) +static int sky2_reset(struct sky2_hw *hw) { u16 status; u8 t8; @@ -2315,16 +2254,6 @@ static int __devinit sky2_reset(struct sky2_hw *hw) return -EOPNOTSUPP; } - hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; - - /* This rev is really old, and requires untested workarounds */ - if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == CHIP_REV_YU_EC_A1) { - printk(KERN_ERR PFX "%s: unsupported revision Yukon-%s (0x%x) rev %d\n", - pci_name(hw->pdev), yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], - hw->chip_id, hw->chip_rev); - return -EOPNOTSUPP; - } - /* disable ASF */ if (hw->chip_id <= CHIP_ID_YUKON_EC) { sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); @@ -2345,7 +2274,7 @@ static int __devinit sky2_reset(struct sky2_hw *hw) sky2_write8(hw, B0_CTST, CS_MRST_CLR); /* clear any PEX errors */ - if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) + if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); @@ -2356,6 +2285,7 @@ static int __devinit sky2_reset(struct sky2_hw *hw) if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC)) ++hw->ports; } + hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; sky2_set_power_state(hw, PCI_D0); @@ -2421,18 +2351,30 @@ static int __devinit sky2_reset(struct sky2_hw *hw) /* Set the list last index */ sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); - sky2_write16(hw, STAT_TX_IDX_TH, 10); - sky2_write8(hw, STAT_FIFO_WM, 16); + /* These status setup values are copied from SysKonnect's driver */ + if (is_ec_a1(hw)) { + /* WA for dev. #4.3 */ + sky2_write16(hw, STAT_TX_IDX_TH, 0xfff); /* Tx Threshold */ - /* set Status-FIFO ISR watermark */ - if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0) - sky2_write8(hw, STAT_FIFO_ISR_WM, 4); - else - sky2_write8(hw, STAT_FIFO_ISR_WM, 16); + /* set Status-FIFO watermark */ + sky2_write8(hw, STAT_FIFO_WM, 0x21); /* WA for dev. #4.18 */ - sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); - sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20)); - sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100)); + /* set Status-FIFO ISR watermark */ + sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07); /* WA for dev. #4.18 */ + sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000)); + } else { + sky2_write16(hw, STAT_TX_IDX_TH, 10); + sky2_write8(hw, STAT_FIFO_WM, 16); + + /* set Status-FIFO ISR watermark */ + if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0) + sky2_write8(hw, STAT_FIFO_ISR_WM, 4); + else + sky2_write8(hw, STAT_FIFO_ISR_WM, 16); + + sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); + sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7)); + } /* enable status unit */ sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON); @@ -2577,34 +2519,17 @@ static const struct sky2_stat { { "rx_unicast", GM_RXF_UC_OK }, { "tx_mac_pause", GM_TXF_MPAUSE }, { "rx_mac_pause", GM_RXF_MPAUSE }, - { "collisions", GM_TXF_COL }, + { "collisions", GM_TXF_SNG_COL }, { "late_collision",GM_TXF_LAT_COL }, { "aborted", GM_TXF_ABO_COL }, - { "single_collisions", GM_TXF_SNG_COL }, { "multi_collisions", GM_TXF_MUL_COL }, - - { "rx_short", GM_RXF_SHT }, + { "fifo_underrun", GM_TXE_FIFO_UR }, + { "fifo_overflow", GM_RXE_FIFO_OV }, + { "rx_toolong", GM_RXF_LNG_ERR }, + { "rx_jabber", GM_RXF_JAB_PKT }, { "rx_runt", GM_RXE_FRAG }, - { "rx_64_byte_packets", GM_RXF_64B }, - { "rx_65_to_127_byte_packets", GM_RXF_127B }, - { "rx_128_to_255_byte_packets", GM_RXF_255B }, - { "rx_256_to_511_byte_packets", GM_RXF_511B }, - { "rx_512_to_1023_byte_packets", GM_RXF_1023B }, - { "rx_1024_to_1518_byte_packets", GM_RXF_1518B }, - { "rx_1518_to_max_byte_packets", GM_RXF_MAX_SZ }, { "rx_too_long", GM_RXF_LNG_ERR }, - { "rx_fifo_overflow", GM_RXE_FIFO_OV }, - { "rx_jabber", GM_RXF_JAB_PKT }, { "rx_fcs_error", GM_RXF_FCS_ERR }, - - { "tx_64_byte_packets", GM_TXF_64B }, - { "tx_65_to_127_byte_packets", GM_TXF_127B }, - { "tx_128_to_255_byte_packets", GM_TXF_255B }, - { "tx_256_to_511_byte_packets", GM_TXF_511B }, - { "tx_512_to_1023_byte_packets", GM_TXF_1023B }, - { "tx_1024_to_1518_byte_packets", GM_TXF_1518B }, - { "tx_1519_to_max_byte_packets", GM_TXF_MAX_SZ }, - { "tx_fifo_underrun", GM_TXE_FIFO_UR }, }; static u32 sky2_get_rx_csum(struct net_device *dev) @@ -2706,7 +2631,7 @@ static struct net_device_stats *sky2_get_stats(struct net_device *dev) sky2->net_stats.rx_bytes = data[1]; sky2->net_stats.tx_packets = data[2] + data[4] + data[6]; sky2->net_stats.rx_packets = data[3] + data[5] + data[7]; - sky2->net_stats.multicast = data[3] + data[5]; + sky2->net_stats.multicast = data[5] + data[7]; sky2->net_stats.collisions = data[10]; sky2->net_stats.tx_aborted_errors = data[12]; @@ -2835,7 +2760,7 @@ static int sky2_phys_id(struct net_device *dev, u32 data) ms = data * 1000; /* save initial values */ - spin_lock_bh(&sky2->phy_lock); + down(&sky2->phy_sema); if (hw->chip_id == CHIP_ID_YUKON_XL) { u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); @@ -2851,9 +2776,9 @@ static int sky2_phys_id(struct net_device *dev, u32 data) sky2_led(hw, port, onoff); onoff = !onoff; - spin_unlock_bh(&sky2->phy_lock); + up(&sky2->phy_sema); interrupted = msleep_interruptible(250); - spin_lock_bh(&sky2->phy_lock); + down(&sky2->phy_sema); ms -= 250; } @@ -2868,7 +2793,7 @@ static int sky2_phys_id(struct net_device *dev, u32 data) gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); } - spin_unlock_bh(&sky2->phy_lock); + up(&sky2->phy_sema); return 0; } @@ -2898,6 +2823,38 @@ static int sky2_set_pauseparam(struct net_device *dev, return err; } +#ifdef CONFIG_PM +static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct sky2_port *sky2 = netdev_priv(dev); + + wol->supported = WAKE_MAGIC; + wol->wolopts = sky2->wol ? WAKE_MAGIC : 0; +} + +static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct sky2_port *sky2 = netdev_priv(dev); + struct sky2_hw *hw = sky2->hw; + + if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) + return -EOPNOTSUPP; + + sky2->wol = wol->wolopts == WAKE_MAGIC; + + if (sky2->wol) { + memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN); + + sky2_write16(hw, WOL_CTRL_STAT, + WOL_CTL_ENA_PME_ON_MAGIC_PKT | + WOL_CTL_ENA_MAGIC_PKT_UNIT); + } else + sky2_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT); + + return 0; +} +#endif + static int sky2_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ecmd) { @@ -2938,11 +2895,19 @@ static int sky2_set_coalesce(struct net_device *dev, { struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; - const u32 tmax = sky2_clk2us(hw, 0x0ffffff); + const u32 tmin = sky2_clk2us(hw, 1); + const u32 tmax = 5000; + + if (ecmd->tx_coalesce_usecs != 0 && + (ecmd->tx_coalesce_usecs < tmin || ecmd->tx_coalesce_usecs > tmax)) + return -EINVAL; - if (ecmd->tx_coalesce_usecs > tmax || - ecmd->rx_coalesce_usecs > tmax || - ecmd->rx_coalesce_usecs_irq > tmax) + if (ecmd->rx_coalesce_usecs != 0 && + (ecmd->rx_coalesce_usecs < tmin || ecmd->rx_coalesce_usecs > tmax)) + return -EINVAL; + + if (ecmd->rx_coalesce_usecs_irq != 0 && + (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax)) return -EINVAL; if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1) @@ -3077,6 +3042,10 @@ static struct ethtool_ops sky2_ethtool_ops = { .set_ringparam = sky2_set_ringparam, .get_pauseparam = sky2_get_pauseparam, .set_pauseparam = sky2_set_pauseparam, +#ifdef CONFIG_PM + .get_wol = sky2_get_wol, + .set_wol = sky2_set_wol, +#endif .phys_id = sky2_phys_id, .get_stats_count = sky2_get_stats_count, .get_ethtool_stats = sky2_get_ethtool_stats, @@ -3129,11 +3098,17 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->duplex = -1; sky2->speed = -1; sky2->advertising = sky2_supported_modes(hw); - sky2->rx_csum = 1; - spin_lock_init(&sky2->phy_lock); + /* Receive checksum disabled for Yukon XL + * because of observed problems with incorrect + * values when multiple packets are received in one interrupt + */ + sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); + + INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2); + init_MUTEX(&sky2->phy_sema); sky2->tx_pending = TX_DEF_PENDING; - sky2->rx_pending = RX_DEF_PENDING; + sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING; sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN); hw->dev[port] = dev; @@ -3175,66 +3150,6 @@ static void __devinit sky2_show_addr(struct net_device *dev) dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); } -/* Handle software interrupt used during MSI test */ -static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id, - struct pt_regs *regs) -{ - struct sky2_hw *hw = dev_id; - u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2); - - if (status == 0) - return IRQ_NONE; - - if (status & Y2_IS_IRQ_SW) { - hw->msi_detected = 1; - wake_up(&hw->msi_wait); - sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); - } - sky2_write32(hw, B0_Y2_SP_ICR, 2); - - return IRQ_HANDLED; -} - -/* Test interrupt path by forcing a a software IRQ */ -static int __devinit sky2_test_msi(struct sky2_hw *hw) -{ - struct pci_dev *pdev = hw->pdev; - int err; - - init_waitqueue_head (&hw->msi_wait); - - sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); - - err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw); - if (err) { - printk(KERN_ERR PFX "%s: cannot assign irq %d\n", - pci_name(pdev), pdev->irq); - return err; - } - - sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); - sky2_read8(hw, B0_CTST); - - wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); - - if (!hw->msi_detected) { - /* MSI test failed, go back to INTx mode */ - printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, " - "switching to INTx mode. Please report this failure to " - "the PCI maintainer and include system chipset information.\n", - pci_name(pdev)); - - err = -EOPNOTSUPP; - sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); - } - - sky2_write32(hw, B0_IMSK, 0); - - free_irq(pdev->irq, hw); - - return err; -} - static int __devinit sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -3303,6 +3218,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_free_hw; } hw->pm_cap = pm_cap; + spin_lock_init(&hw->hw_lock); #ifdef __BIG_ENDIAN /* byte swap descriptors in hardware */ @@ -3355,32 +3271,21 @@ static int __devinit sky2_probe(struct pci_dev *pdev, } } - if (!disable_msi && pci_enable_msi(pdev) == 0) { - err = sky2_test_msi(hw); - if (err == -EOPNOTSUPP) - pci_disable_msi(pdev); - else if (err) - goto err_out_unregister; - } - - err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); + err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); if (err) { printk(KERN_ERR PFX "%s: cannot assign irq %d\n", pci_name(pdev), pdev->irq); goto err_out_unregister; } - sky2_write32(hw, B0_IMSK, Y2_IS_BASE); - - setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); - sky2_idle_start(hw); + hw->intr_mask = Y2_IS_BASE; + sky2_write32(hw, B0_IMSK, hw->intr_mask); pci_set_drvdata(pdev, hw); return 0; err_out_unregister: - pci_disable_msi(pdev); if (dev1) { unregister_netdev(dev1); free_netdev(dev1); @@ -3410,24 +3315,19 @@ static void __devexit sky2_remove(struct pci_dev *pdev) if (!hw) return; - del_timer_sync(&hw->idle_timer); - - sky2_write32(hw, B0_IMSK, 0); - synchronize_irq(hw->pdev->irq); - dev0 = hw->dev[0]; dev1 = hw->dev[1]; if (dev1) unregister_netdev(dev1); unregister_netdev(dev0); + sky2_write32(hw, B0_IMSK, 0); sky2_set_power_state(hw, PCI_D3hot); sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); sky2_write8(hw, B0_CTST, CS_RST_SET); sky2_read8(hw, B0_CTST); free_irq(pdev->irq, hw); - pci_disable_msi(pdev); pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); pci_release_regions(pdev); pci_disable_device(pdev); @@ -3446,14 +3346,8 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) { struct sky2_hw *hw = pci_get_drvdata(pdev); int i; - pci_power_t pstate = pci_choose_state(pdev, state); - - if (!(pstate == PCI_D3hot || pstate == PCI_D3cold)) - return -EINVAL; - del_timer_sync(&hw->idle_timer); - - for (i = 0; i < hw->ports; i++) { + for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; if (dev) { @@ -3462,14 +3356,10 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) sky2_down(dev); netif_device_detach(dev); - netif_poll_disable(dev); } } - sky2_write32(hw, B0_IMSK, 0); - pci_save_state(pdev); - sky2_set_power_state(hw, pstate); - return 0; + return sky2_set_power_state(hw, pci_choose_state(pdev, state)); } static int sky2_resume(struct pci_dev *pdev) @@ -3479,31 +3369,27 @@ static int sky2_resume(struct pci_dev *pdev) pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D0, 0); - sky2_set_power_state(hw, PCI_D0); + err = sky2_set_power_state(hw, PCI_D0); + if (err) + goto out; err = sky2_reset(hw); if (err) goto out; - sky2_write32(hw, B0_IMSK, Y2_IS_BASE); - - for (i = 0; i < hw->ports; i++) { + for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; if (dev && netif_running(dev)) { netif_device_attach(dev); - netif_poll_enable(dev); - err = sky2_up(dev); if (err) { printk(KERN_ERR PFX "%s: could not up: %d\n", dev->name, err); dev_close(dev); - goto out; + break; } } } - - sky2_idle_start(hw); out: return err; } diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 9516c1f39..b5163ab87 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -214,8 +214,6 @@ enum csr_regs { enum { Y2_VMAIN_AVAIL = 1<<17,/* VMAIN available (YUKON-2 only) */ Y2_VAUX_AVAIL = 1<<16,/* VAUX available (YUKON-2 only) */ - Y2_HW_WOL_ON = 1<<15,/* HW WOL On (Yukon-EC Ultra A1 only) */ - Y2_HW_WOL_OFF = 1<<14,/* HW WOL On (Yukon-EC Ultra A1 only) */ Y2_ASF_ENABLE = 1<<13,/* ASF Unit Enable (YUKON-2 only) */ Y2_ASF_DISABLE = 1<<12,/* ASF Unit Disable (YUKON-2 only) */ Y2_CLK_RUN_ENA = 1<<11,/* CLK_RUN Enable (YUKON-2 only) */ @@ -280,11 +278,13 @@ enum { Y2_IS_CHK_TXS1 = 1<<1, /* Descriptor error TXS 1 */ Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */ - Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU, - Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 - | Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1, - Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 - | Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2, + Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU | + Y2_IS_POLL_CHK | Y2_IS_TWSI_RDY | + Y2_IS_IRQ_SW | Y2_IS_TIMINT, + Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 | + Y2_IS_CHK_RX1 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXS1, + Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 | + Y2_IS_CHK_RX2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_TXS2, }; /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ @@ -380,9 +380,6 @@ enum { CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */ CHIP_REV_YU_EC_A2 = 1, /* Chip Rev. for Yukon-EC A2 */ CHIP_REV_YU_EC_A3 = 2, /* Chip Rev. for Yukon-EC A3 */ - - CHIP_REV_YU_EC_U_A0 = 0, - CHIP_REV_YU_EC_U_A1 = 1, }; /* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ @@ -1386,23 +1383,24 @@ enum { GM_SMI_CTRL = 0x0080, /* 16 bit r/w SMI Control Register */ GM_SMI_DATA = 0x0084, /* 16 bit r/w SMI Data Register */ GM_PHY_ADDR = 0x0088, /* 16 bit r/w GPHY Address Register */ -/* MIB Counters */ - GM_MIB_CNT_BASE = 0x0100, /* Base Address of MIB Counters */ - GM_MIB_CNT_END = 0x025C, /* Last MIB counter */ }; +/* MIB Counters */ +#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */ +#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */ +#define GM_MIB_CNT_END 0x025C /* Last MIB counter */ /* * MIB Counters base address definitions (low word) - * use offset 4 for access to high word (32 bit r/o) */ enum { - GM_RXF_UC_OK = GM_MIB_CNT_BASE + 0, /* Unicast Frames Received OK */ + GM_RXF_UC_OK = GM_MIB_CNT_BASE + 0, /* Unicast Frames Received OK */ GM_RXF_BC_OK = GM_MIB_CNT_BASE + 8, /* Broadcast Frames Received OK */ GM_RXF_MPAUSE = GM_MIB_CNT_BASE + 16, /* Pause MAC Ctrl Frames Received */ GM_RXF_MC_OK = GM_MIB_CNT_BASE + 24, /* Multicast Frames Received OK */ GM_RXF_FCS_ERR = GM_MIB_CNT_BASE + 32, /* Rx Frame Check Seq. Error */ - + /* GM_MIB_CNT_BASE + 40: reserved */ GM_RXO_OK_LO = GM_MIB_CNT_BASE + 48, /* Octets Received OK Low */ GM_RXO_OK_HI = GM_MIB_CNT_BASE + 56, /* Octets Received OK High */ GM_RXO_ERR_LO = GM_MIB_CNT_BASE + 64, /* Octets Received Invalid Low */ @@ -1410,36 +1408,37 @@ enum { GM_RXF_SHT = GM_MIB_CNT_BASE + 80, /* Frames <64 Byte Received OK */ GM_RXE_FRAG = GM_MIB_CNT_BASE + 88, /* Frames <64 Byte Received with FCS Err */ GM_RXF_64B = GM_MIB_CNT_BASE + 96, /* 64 Byte Rx Frame */ - GM_RXF_127B = GM_MIB_CNT_BASE + 104,/* 65-127 Byte Rx Frame */ - GM_RXF_255B = GM_MIB_CNT_BASE + 112,/* 128-255 Byte Rx Frame */ - GM_RXF_511B = GM_MIB_CNT_BASE + 120,/* 256-511 Byte Rx Frame */ - GM_RXF_1023B = GM_MIB_CNT_BASE + 128,/* 512-1023 Byte Rx Frame */ - GM_RXF_1518B = GM_MIB_CNT_BASE + 136,/* 1024-1518 Byte Rx Frame */ - GM_RXF_MAX_SZ = GM_MIB_CNT_BASE + 144,/* 1519-MaxSize Byte Rx Frame */ - GM_RXF_LNG_ERR = GM_MIB_CNT_BASE + 152,/* Rx Frame too Long Error */ - GM_RXF_JAB_PKT = GM_MIB_CNT_BASE + 160,/* Rx Jabber Packet Frame */ - - GM_RXE_FIFO_OV = GM_MIB_CNT_BASE + 176,/* Rx FIFO overflow Event */ - GM_TXF_UC_OK = GM_MIB_CNT_BASE + 192,/* Unicast Frames Xmitted OK */ - GM_TXF_BC_OK = GM_MIB_CNT_BASE + 200,/* Broadcast Frames Xmitted OK */ - GM_TXF_MPAUSE = GM_MIB_CNT_BASE + 208,/* Pause MAC Ctrl Frames Xmitted */ - GM_TXF_MC_OK = GM_MIB_CNT_BASE + 216,/* Multicast Frames Xmitted OK */ - GM_TXO_OK_LO = GM_MIB_CNT_BASE + 224,/* Octets Transmitted OK Low */ - GM_TXO_OK_HI = GM_MIB_CNT_BASE + 232,/* Octets Transmitted OK High */ - GM_TXF_64B = GM_MIB_CNT_BASE + 240,/* 64 Byte Tx Frame */ - GM_TXF_127B = GM_MIB_CNT_BASE + 248,/* 65-127 Byte Tx Frame */ - GM_TXF_255B = GM_MIB_CNT_BASE + 256,/* 128-255 Byte Tx Frame */ - GM_TXF_511B = GM_MIB_CNT_BASE + 264,/* 256-511 Byte Tx Frame */ - GM_TXF_1023B = GM_MIB_CNT_BASE + 272,/* 512-1023 Byte Tx Frame */ - GM_TXF_1518B = GM_MIB_CNT_BASE + 280,/* 1024-1518 Byte Tx Frame */ - GM_TXF_MAX_SZ = GM_MIB_CNT_BASE + 288,/* 1519-MaxSize Byte Tx Frame */ - - GM_TXF_COL = GM_MIB_CNT_BASE + 304,/* Tx Collision */ - GM_TXF_LAT_COL = GM_MIB_CNT_BASE + 312,/* Tx Late Collision */ - GM_TXF_ABO_COL = GM_MIB_CNT_BASE + 320,/* Tx aborted due to Exces. Col. */ - GM_TXF_MUL_COL = GM_MIB_CNT_BASE + 328,/* Tx Multiple Collision */ - GM_TXF_SNG_COL = GM_MIB_CNT_BASE + 336,/* Tx Single Collision */ - GM_TXE_FIFO_UR = GM_MIB_CNT_BASE + 344,/* Tx FIFO Underrun Event */ + GM_RXF_127B = GM_MIB_CNT_BASE + 104, /* 65-127 Byte Rx Frame */ + GM_RXF_255B = GM_MIB_CNT_BASE + 112, /* 128-255 Byte Rx Frame */ + GM_RXF_511B = GM_MIB_CNT_BASE + 120, /* 256-511 Byte Rx Frame */ + GM_RXF_1023B = GM_MIB_CNT_BASE + 128, /* 512-1023 Byte Rx Frame */ + GM_RXF_1518B = GM_MIB_CNT_BASE + 136, /* 1024-1518 Byte Rx Frame */ + GM_RXF_MAX_SZ = GM_MIB_CNT_BASE + 144, /* 1519-MaxSize Byte Rx Frame */ + GM_RXF_LNG_ERR = GM_MIB_CNT_BASE + 152, /* Rx Frame too Long Error */ + GM_RXF_JAB_PKT = GM_MIB_CNT_BASE + 160, /* Rx Jabber Packet Frame */ + /* GM_MIB_CNT_BASE + 168: reserved */ + GM_RXE_FIFO_OV = GM_MIB_CNT_BASE + 176, /* Rx FIFO overflow Event */ + /* GM_MIB_CNT_BASE + 184: reserved */ + GM_TXF_UC_OK = GM_MIB_CNT_BASE + 192, /* Unicast Frames Xmitted OK */ + GM_TXF_BC_OK = GM_MIB_CNT_BASE + 200, /* Broadcast Frames Xmitted OK */ + GM_TXF_MPAUSE = GM_MIB_CNT_BASE + 208, /* Pause MAC Ctrl Frames Xmitted */ + GM_TXF_MC_OK = GM_MIB_CNT_BASE + 216, /* Multicast Frames Xmitted OK */ + GM_TXO_OK_LO = GM_MIB_CNT_BASE + 224, /* Octets Transmitted OK Low */ + GM_TXO_OK_HI = GM_MIB_CNT_BASE + 232, /* Octets Transmitted OK High */ + GM_TXF_64B = GM_MIB_CNT_BASE + 240, /* 64 Byte Tx Frame */ + GM_TXF_127B = GM_MIB_CNT_BASE + 248, /* 65-127 Byte Tx Frame */ + GM_TXF_255B = GM_MIB_CNT_BASE + 256, /* 128-255 Byte Tx Frame */ + GM_TXF_511B = GM_MIB_CNT_BASE + 264, /* 256-511 Byte Tx Frame */ + GM_TXF_1023B = GM_MIB_CNT_BASE + 272, /* 512-1023 Byte Tx Frame */ + GM_TXF_1518B = GM_MIB_CNT_BASE + 280, /* 1024-1518 Byte Tx Frame */ + GM_TXF_MAX_SZ = GM_MIB_CNT_BASE + 288, /* 1519-MaxSize Byte Tx Frame */ + + GM_TXF_COL = GM_MIB_CNT_BASE + 304, /* Tx Collision */ + GM_TXF_LAT_COL = GM_MIB_CNT_BASE + 312, /* Tx Late Collision */ + GM_TXF_ABO_COL = GM_MIB_CNT_BASE + 320, /* Tx aborted due to Exces. Col. */ + GM_TXF_MUL_COL = GM_MIB_CNT_BASE + 328, /* Tx Multiple Collision */ + GM_TXF_SNG_COL = GM_MIB_CNT_BASE + 336, /* Tx Single Collision */ + GM_TXE_FIFO_UR = GM_MIB_CNT_BASE + 344, /* Tx FIFO Underrun Event */ }; /* GMAC Bit Definitions */ @@ -1817,7 +1816,7 @@ struct sky2_rx_le { __le16 length; u8 ctrl; u8 opcode; -} __attribute((packed)); +} __attribute((packed));; struct sky2_status_le { __le32 status; /* also checksum */ @@ -1842,7 +1841,6 @@ struct sky2_port { struct net_device *netdev; unsigned port; u32 msg_enable; - spinlock_t phy_lock; spinlock_t tx_lock ____cacheline_aligned_in_smp; struct tx_ring_info *tx_ring; @@ -1851,6 +1849,7 @@ struct sky2_port { u16 tx_prod; /* next le to use */ u32 tx_addr64; u16 tx_pending; + u16 tx_last_put; u16 tx_last_mss; struct ring_info *rx_ring ____cacheline_aligned_in_smp; @@ -1859,6 +1858,7 @@ struct sky2_port { u16 rx_next; /* next re to check */ u16 rx_put; /* next le index to use */ u16 rx_pending; + u16 rx_last_put; u16 rx_bufsize; #ifdef SKY2_VLAN_TAG_USED u16 rx_tag; @@ -1874,15 +1874,20 @@ struct sky2_port { u8 rx_pause; u8 tx_pause; u8 rx_csum; + u8 wol; struct net_device_stats net_stats; + struct work_struct phy_task; + struct semaphore phy_sema; }; struct sky2_hw { void __iomem *regs; struct pci_dev *pdev; struct net_device *dev[2]; + spinlock_t hw_lock; + u32 intr_mask; int pm_cap; u8 chip_id; @@ -1893,10 +1898,6 @@ struct sky2_hw { struct sky2_status_le *st_le; u32 st_idx; dma_addr_t st_dma; - - struct timer_list idle_timer; - int msi_detected; - wait_queue_head_t msi_wait; }; static inline int sky2_is_copper(const struct sky2_hw *hw) diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 0e9833adf..7ec08127c 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -215,12 +215,15 @@ struct smc_local { spinlock_t lock; +#ifdef SMC_CAN_USE_DATACS + u32 __iomem *datacs; +#endif + #ifdef SMC_USE_PXA_DMA /* DMA needs the physical address of the chip */ u_long physaddr; #endif void __iomem *base; - void __iomem *datacs; }; #if SMC_DEBUG > 0 @@ -2101,8 +2104,9 @@ static int smc_enable_device(struct platform_device *pdev) * Set the appropriate byte/word mode. */ ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; - if (!SMC_CAN_USE_16BIT) - ecsr |= ECSR_IOIS8; +#ifndef SMC_CAN_USE_16BIT + ecsr |= ECSR_IOIS8; +#endif writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); local_irq_restore(flags); @@ -2139,39 +2143,40 @@ static void smc_release_attrib(struct platform_device *pdev) release_mem_region(res->start, ATTRIB_SIZE); } -static inline void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) +#ifdef SMC_CAN_USE_DATACS +static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) { - if (SMC_CAN_USE_DATACS) { - struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); - struct smc_local *lp = netdev_priv(ndev); - - if (!res) - return; + struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); + struct smc_local *lp = netdev_priv(ndev); - if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { - printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); - return; - } + if (!res) + return; - lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); + if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { + printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); + return; } + + lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); } static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) { - if (SMC_CAN_USE_DATACS) { - struct smc_local *lp = netdev_priv(ndev); - struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); + struct smc_local *lp = netdev_priv(ndev); + struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); - if (lp->datacs) - iounmap(lp->datacs); + if (lp->datacs) + iounmap(lp->datacs); - lp->datacs = NULL; + lp->datacs = NULL; - if (res) - release_mem_region(res->start, SMC_DATA_EXTENT); - } + if (res) + release_mem_region(res->start, SMC_DATA_EXTENT); } +#else +static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) {} +static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) {} +#endif /* * smc_init(void) @@ -2216,10 +2221,6 @@ static int smc_drv_probe(struct platform_device *pdev) ndev->dma = (unsigned char)-1; ndev->irq = platform_get_irq(pdev, 0); - if (ndev->irq < 0) { - ret = -ENODEV; - goto out_free_netdev; - } ret = smc_request_attrib(pdev); if (ret) diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index e1be1af51..e0efd1964 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -275,10 +275,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_insw(a,r,p,l) readsw ((void*) ((a) + (r)), p, l) #define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; }) -#define SMC_outsw LPD7A40X_SMC_outsw - -static inline void LPD7A40X_SMC_outsw(unsigned long a, int r, - unsigned char* p, int l) +static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) { unsigned short* ps = (unsigned short*) p; while (l-- > 0) { @@ -345,6 +342,10 @@ static inline void LPD7A40X_SMC_outsw(unsigned long a, int r, #endif +#ifndef SMC_IRQ_FLAGS +#define SMC_IRQ_FLAGS SA_TRIGGER_RISING +#endif + #ifdef SMC_USE_PXA_DMA /* * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is @@ -440,85 +441,10 @@ smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs) #endif /* SMC_USE_PXA_DMA */ -/* - * Everything a particular hardware setup needs should have been defined - * at this point. Add stubs for the undefined cases, mainly to avoid - * compilation warnings since they'll be optimized away, or to prevent buggy - * use of them. - */ - -#if ! SMC_CAN_USE_32BIT -#define SMC_inl(ioaddr, reg) ({ BUG(); 0; }) -#define SMC_outl(x, ioaddr, reg) BUG() -#define SMC_insl(a, r, p, l) BUG() -#define SMC_outsl(a, r, p, l) BUG() -#endif - -#if !defined(SMC_insl) || !defined(SMC_outsl) -#define SMC_insl(a, r, p, l) BUG() -#define SMC_outsl(a, r, p, l) BUG() -#endif - -#if ! SMC_CAN_USE_16BIT - -/* - * Any 16-bit access is performed with two 8-bit accesses if the hardware - * can't do it directly. Most registers are 16-bit so those are mandatory. - */ -#define SMC_outw(x, ioaddr, reg) \ - do { \ - unsigned int __val16 = (x); \ - SMC_outb( __val16, ioaddr, reg ); \ - SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ - } while (0) -#define SMC_inw(ioaddr, reg) \ - ({ \ - unsigned int __val16; \ - __val16 = SMC_inb( ioaddr, reg ); \ - __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ - __val16; \ - }) - -#define SMC_insw(a, r, p, l) BUG() -#define SMC_outsw(a, r, p, l) BUG() - -#endif - -#if !defined(SMC_insw) || !defined(SMC_outsw) -#define SMC_insw(a, r, p, l) BUG() -#define SMC_outsw(a, r, p, l) BUG() -#endif - -#if ! SMC_CAN_USE_8BIT -#define SMC_inb(ioaddr, reg) ({ BUG(); 0; }) -#define SMC_outb(x, ioaddr, reg) BUG() -#define SMC_insb(a, r, p, l) BUG() -#define SMC_outsb(a, r, p, l) BUG() -#endif - -#if !defined(SMC_insb) || !defined(SMC_outsb) -#define SMC_insb(a, r, p, l) BUG() -#define SMC_outsb(a, r, p, l) BUG() -#endif - -#ifndef SMC_CAN_USE_DATACS -#define SMC_CAN_USE_DATACS 0 -#endif - +/* Because of bank switching, the LAN91x uses only 16 I/O ports */ #ifndef SMC_IO_SHIFT #define SMC_IO_SHIFT 0 #endif - -#ifndef SMC_IRQ_FLAGS -#define SMC_IRQ_FLAGS SA_TRIGGER_RISING -#endif - -#ifndef SMC_INTERRUPT_PREAMBLE -#define SMC_INTERRUPT_PREAMBLE -#endif - - -/* Because of bank switching, the LAN91x uses only 16 I/O ports */ #define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) #define SMC_DATA_EXTENT (4) @@ -891,11 +817,6 @@ static const char * chip_ids[ 16 ] = { * Note: the following macros do *not* select the bank -- this must * be done separately as needed in the main code. The SMC_REG() macro * only uses the bank argument for debugging purposes (when enabled). - * - * Note: despite inline functions being safer, everything leading to this - * should preferably be macros to let BUG() display the line number in - * the core source code since we're interested in the top call site - * not in any inline function location. */ #if SMC_DEBUG > 0 @@ -913,142 +834,62 @@ static const char * chip_ids[ 16 ] = { #define SMC_REG(reg, bank) (reg<> 8) ) - -#define SMC_GET_TXFIFO() \ - ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, TXFIFO_REG)) \ - : (SMC_inw(ioaddr, TXFIFO_REG) & 0xFF) ) - -#define SMC_GET_RXFIFO() \ - ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, RXFIFO_REG)) \ - : (SMC_inw(ioaddr, TXFIFO_REG) >> 8) ) - -#define SMC_GET_INT() \ - ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, INT_REG)) \ - : (SMC_inw(ioaddr, INT_REG) & 0xFF) ) - +#if SMC_CAN_USE_8BIT +#define SMC_GET_PN() SMC_inb( ioaddr, PN_REG ) +#define SMC_SET_PN(x) SMC_outb( x, ioaddr, PN_REG ) +#define SMC_GET_AR() SMC_inb( ioaddr, AR_REG ) +#define SMC_GET_TXFIFO() SMC_inb( ioaddr, TXFIFO_REG ) +#define SMC_GET_RXFIFO() SMC_inb( ioaddr, RXFIFO_REG ) +#define SMC_GET_INT() SMC_inb( ioaddr, INT_REG ) +#define SMC_ACK_INT(x) SMC_outb( x, ioaddr, INT_REG ) +#define SMC_GET_INT_MASK() SMC_inb( ioaddr, IM_REG ) +#define SMC_SET_INT_MASK(x) SMC_outb( x, ioaddr, IM_REG ) +#else +#define SMC_GET_PN() (SMC_inw( ioaddr, PN_REG ) & 0xFF) +#define SMC_SET_PN(x) SMC_outw( x, ioaddr, PN_REG ) +#define SMC_GET_AR() (SMC_inw( ioaddr, PN_REG ) >> 8) +#define SMC_GET_TXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF) +#define SMC_GET_RXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) >> 8) +#define SMC_GET_INT() (SMC_inw( ioaddr, INT_REG ) & 0xFF) #define SMC_ACK_INT(x) \ do { \ - if (SMC_CAN_USE_8BIT) \ - SMC_outb(x, ioaddr, INT_REG); \ - else { \ - unsigned long __flags; \ - int __mask; \ - local_irq_save(__flags); \ - __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ - SMC_outw( __mask | (x), ioaddr, INT_REG ); \ - local_irq_restore(__flags); \ - } \ - } while (0) - -#define SMC_GET_INT_MASK() \ - ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, IM_REG)) \ - : (SMC_inw( ioaddr, INT_REG ) >> 8) ) - -#define SMC_SET_INT_MASK(x) \ - do { \ - if (SMC_CAN_USE_8BIT) \ - SMC_outb(x, ioaddr, IM_REG); \ - else \ - SMC_outw((x) << 8, ioaddr, INT_REG); \ - } while (0) - -#define SMC_CURRENT_BANK() SMC_inw(ioaddr, BANK_SELECT) - -#define SMC_SELECT_BANK(x) \ - do { \ - if (SMC_MUST_ALIGN_WRITE) \ - SMC_outl((x)<<16, ioaddr, 12<> 8) +#define SMC_SET_INT_MASK(x) SMC_outw( (x) << 8, ioaddr, INT_REG ) +#endif -#define SMC_GET_BASE() SMC_inw(ioaddr, BASE_REG) - -#define SMC_SET_BASE(x) SMC_outw(x, ioaddr, BASE_REG) - -#define SMC_GET_CONFIG() SMC_inw(ioaddr, CONFIG_REG) - -#define SMC_SET_CONFIG(x) SMC_outw(x, ioaddr, CONFIG_REG) - -#define SMC_GET_COUNTER() SMC_inw(ioaddr, COUNTER_REG) - -#define SMC_GET_CTL() SMC_inw(ioaddr, CTL_REG) - -#define SMC_SET_CTL(x) SMC_outw(x, ioaddr, CTL_REG) - -#define SMC_GET_MII() SMC_inw(ioaddr, MII_REG) - -#define SMC_SET_MII(x) SMC_outw(x, ioaddr, MII_REG) - -#define SMC_GET_MIR() SMC_inw(ioaddr, MIR_REG) - -#define SMC_SET_MIR(x) SMC_outw(x, ioaddr, MIR_REG) - -#define SMC_GET_MMU_CMD() SMC_inw(ioaddr, MMU_CMD_REG) - -#define SMC_SET_MMU_CMD(x) SMC_outw(x, ioaddr, MMU_CMD_REG) - -#define SMC_GET_FIFO() SMC_inw(ioaddr, FIFO_REG) - -#define SMC_GET_PTR() SMC_inw(ioaddr, PTR_REG) - -#define SMC_SET_PTR(x) \ - do { \ - if (SMC_MUST_ALIGN_WRITE) \ - SMC_outl((x)<<16, ioaddr, SMC_REG(4, 2)); \ - else \ - SMC_outw(x, ioaddr, PTR_REG); \ - } while (0) - -#define SMC_GET_EPH_STATUS() SMC_inw(ioaddr, EPH_STATUS_REG) - -#define SMC_GET_RCR() SMC_inw(ioaddr, RCR_REG) - -#define SMC_SET_RCR(x) SMC_outw(x, ioaddr, RCR_REG) - -#define SMC_GET_REV() SMC_inw(ioaddr, REV_REG) - -#define SMC_GET_RPC() SMC_inw(ioaddr, RPC_REG) - -#define SMC_SET_RPC(x) \ - do { \ - if (SMC_MUST_ALIGN_WRITE) \ - SMC_outl((x)<<16, ioaddr, SMC_REG(8, 0)); \ - else \ - SMC_outw(x, ioaddr, RPC_REG); \ - } while (0) - -#define SMC_GET_TCR() SMC_inw(ioaddr, TCR_REG) - -#define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_REG) +#define SMC_CURRENT_BANK() SMC_inw( ioaddr, BANK_SELECT ) +#define SMC_SELECT_BANK(x) SMC_outw( x, ioaddr, BANK_SELECT ) +#define SMC_GET_BASE() SMC_inw( ioaddr, BASE_REG ) +#define SMC_SET_BASE(x) SMC_outw( x, ioaddr, BASE_REG ) +#define SMC_GET_CONFIG() SMC_inw( ioaddr, CONFIG_REG ) +#define SMC_SET_CONFIG(x) SMC_outw( x, ioaddr, CONFIG_REG ) +#define SMC_GET_COUNTER() SMC_inw( ioaddr, COUNTER_REG ) +#define SMC_GET_CTL() SMC_inw( ioaddr, CTL_REG ) +#define SMC_SET_CTL(x) SMC_outw( x, ioaddr, CTL_REG ) +#define SMC_GET_MII() SMC_inw( ioaddr, MII_REG ) +#define SMC_SET_MII(x) SMC_outw( x, ioaddr, MII_REG ) +#define SMC_GET_MIR() SMC_inw( ioaddr, MIR_REG ) +#define SMC_SET_MIR(x) SMC_outw( x, ioaddr, MIR_REG ) +#define SMC_GET_MMU_CMD() SMC_inw( ioaddr, MMU_CMD_REG ) +#define SMC_SET_MMU_CMD(x) SMC_outw( x, ioaddr, MMU_CMD_REG ) +#define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG ) +#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG ) +#define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG ) +#define SMC_GET_EPH_STATUS() SMC_inw( ioaddr, EPH_STATUS_REG ) +#define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG ) +#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG ) +#define SMC_GET_REV() SMC_inw( ioaddr, REV_REG ) +#define SMC_GET_RPC() SMC_inw( ioaddr, RPC_REG ) +#define SMC_SET_RPC(x) SMC_outw( x, ioaddr, RPC_REG ) +#define SMC_GET_TCR() SMC_inw( ioaddr, TCR_REG ) +#define SMC_SET_TCR(x) SMC_outw( x, ioaddr, TCR_REG ) #ifndef SMC_GET_MAC_ADDR #define SMC_GET_MAC_ADDR(addr) \ @@ -1079,84 +920,151 @@ static const char * chip_ids[ 16 ] = { SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \ } while (0) +#if SMC_CAN_USE_32BIT +/* + * Some setups just can't write 8 or 16 bits reliably when not aligned + * to a 32 bit boundary. I tell you that exists! + * We re-do the ones here that can be easily worked around if they can have + * their low parts written to 0 without adverse effects. + */ +#undef SMC_SELECT_BANK +#define SMC_SELECT_BANK(x) SMC_outl( (x)<<16, ioaddr, 12<> 16; \ + } while (0) +#else +#define SMC_PUT_PKT_HDR(status, length) \ + do { \ + SMC_outw( status, ioaddr, DATA_REG ); \ + SMC_outw( length, ioaddr, DATA_REG ); \ } while (0) - #define SMC_GET_PKT_HDR(status, length) \ do { \ - if (SMC_CAN_USE_32BIT) { \ - unsigned int __val = SMC_inl(ioaddr, DATA_REG); \ - (status) = __val & 0xffff; \ - (length) = __val >> 16; \ - } else { \ - (status) = SMC_inw(ioaddr, DATA_REG); \ - (length) = SMC_inw(ioaddr, DATA_REG); \ + (status) = SMC_inw( ioaddr, DATA_REG ); \ + (length) = SMC_inw( ioaddr, DATA_REG ); \ + } while (0) +#endif + +#if SMC_CAN_USE_32BIT +#define _SMC_PUSH_DATA(p, l) \ + do { \ + char *__ptr = (p); \ + int __len = (l); \ + if (__len >= 2 && (unsigned long)__ptr & 2) { \ + __len -= 2; \ + SMC_outw( *(u16 *)__ptr, ioaddr, DATA_REG ); \ + __ptr += 2; \ + } \ + SMC_outsl( ioaddr, DATA_REG, __ptr, __len >> 2); \ + if (__len & 2) { \ + __ptr += (__len & ~3); \ + SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ } \ } while (0) +#define _SMC_PULL_DATA(p, l) \ + do { \ + char *__ptr = (p); \ + int __len = (l); \ + if ((unsigned long)__ptr & 2) { \ + /* \ + * We want 32bit alignment here. \ + * Since some buses perform a full 32bit \ + * fetch even for 16bit data we can't use \ + * SMC_inw() here. Back both source (on chip \ + * and destination) pointers of 2 bytes. \ + */ \ + __ptr -= 2; \ + __len += 2; \ + SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ + } \ + __len += 2; \ + SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \ + } while (0) +#elif SMC_CAN_USE_16BIT +#define _SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 ) +#define _SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 ) +#elif SMC_CAN_USE_8BIT +#define _SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l ) +#define _SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l ) +#endif -#define SMC_PUSH_DATA(p, l) \ +#if ! SMC_CAN_USE_16BIT +#define SMC_outw(x, ioaddr, reg) \ do { \ - if (SMC_CAN_USE_32BIT) { \ - void *__ptr = (p); \ - int __len = (l); \ - void *__ioaddr = ioaddr; \ - if (__len >= 2 && (unsigned long)__ptr & 2) { \ - __len -= 2; \ - SMC_outw(*(u16 *)__ptr, ioaddr, DATA_REG); \ - __ptr += 2; \ - } \ - if (SMC_CAN_USE_DATACS && lp->datacs) \ - __ioaddr = lp->datacs; \ - SMC_outsl(__ioaddr, DATA_REG, __ptr, __len>>2); \ - if (__len & 2) { \ - __ptr += (__len & ~3); \ - SMC_outw(*((u16 *)__ptr), ioaddr, DATA_REG); \ - } \ - } else if (SMC_CAN_USE_16BIT) \ - SMC_outsw(ioaddr, DATA_REG, p, (l) >> 1); \ - else if (SMC_CAN_USE_8BIT) \ - SMC_outsb(ioaddr, DATA_REG, p, l); \ + unsigned int __val16 = (x); \ + SMC_outb( __val16, ioaddr, reg ); \ + SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ } while (0) +#define SMC_inw(ioaddr, reg) \ + ({ \ + unsigned int __val16; \ + __val16 = SMC_inb( ioaddr, reg ); \ + __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ + __val16; \ + }) +#endif + +#ifdef SMC_CAN_USE_DATACS +#define SMC_PUSH_DATA(p, l) \ + if ( lp->datacs ) { \ + unsigned char *__ptr = (p); \ + int __len = (l); \ + if (__len >= 2 && (unsigned long)__ptr & 2) { \ + __len -= 2; \ + SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ + __ptr += 2; \ + } \ + outsl(lp->datacs, __ptr, __len >> 2); \ + if (__len & 2) { \ + __ptr += (__len & ~3); \ + SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ + } \ + } else { \ + _SMC_PUSH_DATA(p, l); \ + } #define SMC_PULL_DATA(p, l) \ - do { \ - if (SMC_CAN_USE_32BIT) { \ - void *__ptr = (p); \ - int __len = (l); \ - void *__ioaddr = ioaddr; \ - if ((unsigned long)__ptr & 2) { \ - /* \ - * We want 32bit alignment here. \ - * Since some buses perform a full \ - * 32bit fetch even for 16bit data \ - * we can't use SMC_inw() here. \ - * Back both source (on-chip) and \ - * destination pointers of 2 bytes. \ - * This is possible since the call to \ - * SMC_GET_PKT_HDR() already advanced \ - * the source pointer of 4 bytes, and \ - * the skb_reserve(skb, 2) advanced \ - * the destination pointer of 2 bytes. \ - */ \ - __ptr -= 2; \ - __len += 2; \ - SMC_SET_PTR(2|PTR_READ|PTR_RCV|PTR_AUTOINC); \ - } \ - if (SMC_CAN_USE_DATACS && lp->datacs) \ - __ioaddr = lp->datacs; \ + if ( lp->datacs ) { \ + unsigned char *__ptr = (p); \ + int __len = (l); \ + if ((unsigned long)__ptr & 2) { \ + /* \ + * We want 32bit alignment here. \ + * Since some buses perform a full 32bit \ + * fetch even for 16bit data we can't use \ + * SMC_inw() here. Back both source (on chip \ + * and destination) pointers of 2 bytes. \ + */ \ + __ptr -= 2; \ __len += 2; \ - SMC_insl(__ioaddr, DATA_REG, __ptr, __len>>2); \ - } else if (SMC_CAN_USE_16BIT) \ - SMC_insw(ioaddr, DATA_REG, p, (l) >> 1); \ - else if (SMC_CAN_USE_8BIT) \ - SMC_insb(ioaddr, DATA_REG, p, l); \ - } while (0) + SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ + } \ + __len += 2; \ + insl( lp->datacs, __ptr, __len >> 2); \ + } else { \ + _SMC_PULL_DATA(p, l); \ + } +#else +#define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l) +#define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l) +#endif + +#if !defined (SMC_INTERRUPT_PREAMBLE) +# define SMC_INTERRUPT_PREAMBLE +#endif #endif /* _SMC91X_H_ */ diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 394339d5e..1f5975a61 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1442,7 +1442,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) case SPIDER_NET_GRFAFLLINT: /* fallthrough */ case SPIDER_NET_GRMFLLINT: if (netif_msg_intr(card) && net_ratelimit()) - pr_debug("Spider RX RAM full, incoming packets " + pr_err("Spider RX RAM full, incoming packets " "might be discarded!\n"); spider_net_rx_irq_off(card); tasklet_schedule(&card->rxram_full_tl); @@ -1652,8 +1652,6 @@ spider_net_enable_card(struct spider_net_card *card) { SPIDER_NET_GFTRESTRT, SPIDER_NET_RESTART_VALUE }, { SPIDER_NET_GMRWOLCTRL, 0 }, - { SPIDER_NET_GTESTMD, 0x10000000 }, - { SPIDER_NET_GTTQMSK, 0x00400040 }, { SPIDER_NET_GTESTMD, 0 }, { SPIDER_NET_GMACINTEN, 0 }, @@ -1794,7 +1792,15 @@ spider_net_setup_phy(struct spider_net_card *card) if (phy->def->ops->setup_forced) phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL); - phy->def->ops->enable_fiber(phy); + /* the following two writes could be moved to sungem_phy.c */ + /* enable fiber mode */ + spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x9020); + /* LEDs active in both modes, autosense prio = fiber */ + spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x945f); + + /* switch off fibre autoneg */ + spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0xfc01); + spider_net_write_phy(card->netdev, 1, 0x0b, 0x0004); phy->def->ops->read_link(phy); pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name, @@ -2080,7 +2086,7 @@ spider_net_setup_netdev(struct spider_net_card *card) spider_net_setup_netdev_ops(netdev); - netdev->features = NETIF_F_HW_CSUM; + netdev->features = 0; /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | * NETIF_F_HW_VLAN_FILTER */ diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index 3b8d951cf..5922b529a 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h @@ -120,8 +120,6 @@ extern char spider_net_driver_name[]; #define SPIDER_NET_GMRUAFILnR 0x00000500 #define SPIDER_NET_GMRUA0FIL15R 0x00000578 -#define SPIDER_NET_GTTQMSK 0x00000934 - /* RX DMA controller registers, all 0x00000a.. are for DMA controller A, * 0x00000b.. for DMA controller B, etc. */ #define SPIDER_NET_GDADCHA 0x00000a00 diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 9b7805be2..d167deda9 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -201,7 +201,7 @@ static int max_interrupt_work = 20; static int mtu; /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). The Starfire has a 512 element hash table based on the Ethernet CRC. */ -static const int multicast_filter_limit = 512; +static int multicast_filter_limit = 512; /* Whether to do TCP/UDP checksums in hardware */ static int enable_hw_cksum = 1; @@ -335,7 +335,7 @@ do { \ /* These identify the driver base version and may not be removed. */ -static const char version[] __devinitdata = +static char version[] __devinitdata = KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker \n" KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n"; @@ -463,7 +463,7 @@ static struct pci_device_id starfire_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, starfire_pci_tbl); /* A chip capabilities table, matching the CH_xxx entries in xxx_pci_tbl[] above. */ -static const struct chip_info { +static struct chip_info { const char *name; int drv_flags; } netdrv_tbl[] __devinitdata = { @@ -2084,45 +2084,14 @@ static int netdev_close(struct net_device *dev) return 0; } -#ifdef CONFIG_PM -static int starfire_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (netif_running(dev)) { - netif_device_detach(dev); - netdev_close(dev); - } - - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev,state)); - - return 0; -} - -static int starfire_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - if (netif_running(dev)) { - netdev_open(dev); - netif_device_attach(dev); - } - - return 0; -} -#endif /* CONFIG_PM */ - static void __devexit starfire_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct netdev_private *np = netdev_priv(dev); - BUG_ON(!dev); + if (!dev) + BUG(); unregister_netdev(dev); @@ -2146,10 +2115,6 @@ static struct pci_driver starfire_driver = { .name = DRV_NAME, .probe = starfire_init_one, .remove = __devexit_p(starfire_remove_one), -#ifdef CONFIG_PM - .suspend = starfire_suspend, - .resume = starfire_resume, -#endif /* CONFIG_PM */ .id_table = starfire_pci_tbl, }; diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index d4c0002b4..01bdb2334 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -71,7 +71,7 @@ static int lance_debug = LANCE_DEBUG; #else static int lance_debug = 1; #endif -module_param(lance_debug, int, 0); +MODULE_PARM(lance_debug, "i"); MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 406b46c48..0ab9c38b4 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -106,7 +106,7 @@ static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). Typical is a 64 element hash table based on the Ethernet CRC. */ -static const int multicast_filter_limit = 32; +static int multicast_filter_limit = 32; /* Set the copy breakpoint for the copy-only-tiny-frames scheme. Setting to > 1518 effectively disables this feature. @@ -287,7 +287,6 @@ static struct pci_device_id sundance_pci_tbl[] = { {0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3}, {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, - {0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, {0,} }; MODULE_DEVICE_TABLE(pci, sundance_pci_tbl); @@ -299,14 +298,13 @@ enum { struct pci_id_info { const char *name; }; -static const struct pci_id_info pci_id_tbl[] = { +static struct pci_id_info pci_id_tbl[] = { {"D-Link DFE-550TX FAST Ethernet Adapter"}, {"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"}, {"D-Link DFE-580TX 4 port Server Adapter"}, {"D-Link DFE-530TXS FAST Ethernet Adapter"}, {"D-Link DL10050-based FAST Ethernet Adapter"}, - {"IC Plus IP100 Fast Ethernet Adapter"}, - {"IC Plus IP100A Fast Ethernet Adapter" }, + {"Sundance Technology Alta"}, {NULL,}, /* 0 terminated list. */ }; @@ -635,13 +633,9 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, np->phys[0] = 1; /* Default setting */ np->mii_preamble_required++; - /* - * It seems some phys doesn't deal well with address 0 being accessed - * first, so leave address zero to the end of the loop (32 & 31). - */ for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) { + int mii_status = mdio_read(dev, phy, MII_BMSR); int phyx = phy & 0x1f; - int mii_status = mdio_read(dev, phyx, MII_BMSR); if (mii_status != 0xffff && mii_status != 0x0000) { np->phys[phy_idx++] = phyx; np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE); diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 38cd30cb7..28ce47a02 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include @@ -2285,7 +2284,7 @@ static void gem_reset_task(void *data) { struct gem *gp = (struct gem *) data; - mutex_lock(&gp->pm_mutex); + down(&gp->pm_sem); netif_poll_disable(gp->dev); @@ -2312,7 +2311,7 @@ static void gem_reset_task(void *data) netif_poll_enable(gp->dev); - mutex_unlock(&gp->pm_mutex); + up(&gp->pm_sem); } @@ -2321,14 +2320,14 @@ static int gem_open(struct net_device *dev) struct gem *gp = dev->priv; int rc = 0; - mutex_lock(&gp->pm_mutex); + down(&gp->pm_sem); /* We need the cell enabled */ if (!gp->asleep) rc = gem_do_start(dev); gp->opened = (rc == 0); - mutex_unlock(&gp->pm_mutex); + up(&gp->pm_sem); return rc; } @@ -2341,13 +2340,13 @@ static int gem_close(struct net_device *dev) * our caller (dev_close) already did it for us */ - mutex_lock(&gp->pm_mutex); + down(&gp->pm_sem); gp->opened = 0; if (!gp->asleep) gem_do_stop(dev, 0); - mutex_unlock(&gp->pm_mutex); + up(&gp->pm_sem); return 0; } @@ -2359,7 +2358,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) struct gem *gp = dev->priv; unsigned long flags; - mutex_lock(&gp->pm_mutex); + down(&gp->pm_sem); netif_poll_disable(dev); @@ -2392,11 +2391,11 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) /* Stop the link timer */ del_timer_sync(&gp->link_timer); - /* Now we release the mutex to not block the reset task who + /* Now we release the semaphore to not block the reset task who * can take it too. We are marked asleep, so there will be no * conflict here */ - mutex_unlock(&gp->pm_mutex); + up(&gp->pm_sem); /* Wait for a pending reset task to complete */ while (gp->reset_task_pending) @@ -2425,7 +2424,7 @@ static int gem_resume(struct pci_dev *pdev) printk(KERN_INFO "%s: resuming\n", dev->name); - mutex_lock(&gp->pm_mutex); + down(&gp->pm_sem); /* Keep the cell enabled during the entire operation, no need to * take a lock here tho since nothing else can happen while we are @@ -2441,7 +2440,7 @@ static int gem_resume(struct pci_dev *pdev) * still asleep, a new sleep cycle may bring it back */ gem_put_cell(gp); - mutex_unlock(&gp->pm_mutex); + up(&gp->pm_sem); return 0; } pci_set_master(gp->pdev); @@ -2487,7 +2486,7 @@ static int gem_resume(struct pci_dev *pdev) netif_poll_enable(dev); - mutex_unlock(&gp->pm_mutex); + up(&gp->pm_sem); return 0; } @@ -2592,7 +2591,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu) return 0; } - mutex_lock(&gp->pm_mutex); + down(&gp->pm_sem); spin_lock_irq(&gp->lock); spin_lock(&gp->tx_lock); dev->mtu = new_mtu; @@ -2603,7 +2602,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu) } spin_unlock(&gp->tx_lock); spin_unlock_irq(&gp->lock); - mutex_unlock(&gp->pm_mutex); + up(&gp->pm_sem); return 0; } @@ -2772,10 +2771,10 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) int rc = -EOPNOTSUPP; unsigned long flags; - /* Hold the PM mutex while doing ioctl's or we may collide + /* Hold the PM semaphore while doing ioctl's or we may collide * with power management. */ - mutex_lock(&gp->pm_mutex); + down(&gp->pm_sem); spin_lock_irqsave(&gp->lock, flags); gem_get_cell(gp); @@ -2813,7 +2812,7 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) gem_put_cell(gp); spin_unlock_irqrestore(&gp->lock, flags); - mutex_unlock(&gp->pm_mutex); + up(&gp->pm_sem); return rc; } @@ -3034,7 +3033,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, spin_lock_init(&gp->lock); spin_lock_init(&gp->tx_lock); - mutex_init(&gp->pm_mutex); + init_MUTEX(&gp->pm_sem); init_timer(&gp->link_timer); gp->link_timer.function = gem_link_timer; diff --git a/drivers/net/sungem.h b/drivers/net/sungem.h index 89847215d..13006d759 100644 --- a/drivers/net/sungem.h +++ b/drivers/net/sungem.h @@ -980,15 +980,15 @@ struct gem { int tx_new, tx_old; unsigned int has_wol : 1; /* chip supports wake-on-lan */ - unsigned int asleep : 1; /* chip asleep, protected by pm_mutex */ + unsigned int asleep : 1; /* chip asleep, protected by pm_sem */ unsigned int asleep_wol : 1; /* was asleep with WOL enabled */ - unsigned int opened : 1; /* driver opened, protected by pm_mutex */ + unsigned int opened : 1; /* driver opened, protected by pm_sem */ unsigned int running : 1; /* chip running, protected by lock */ /* cell enable count, protected by lock */ int cell_enabled; - struct mutex pm_mutex; + struct semaphore pm_sem; u32 msg_enable; u32 status; diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c index b2ddd5e79..d3ddb41d6 100644 --- a/drivers/net/sungem_phy.c +++ b/drivers/net/sungem_phy.c @@ -39,7 +39,7 @@ #include "sungem_phy.h" /* Link modes of the BCM5400 PHY */ -static const int phy_BCM5400_link_table[8][3] = { +static int phy_BCM5400_link_table[8][3] = { { 0, 0, 0 }, /* No link */ { 0, 0, 0 }, /* 10BT Half Duplex */ { 1, 0, 0 }, /* 10BT Full Duplex */ @@ -275,7 +275,7 @@ static int bcm5411_init(struct mii_phy* phy) return 0; } -static int generic_suspend(struct mii_phy* phy) +static int bcm5411_suspend(struct mii_phy* phy) { phy_write(phy, MII_BMCR, BMCR_PDOWN); @@ -329,30 +329,6 @@ static int bcm5421_init(struct mii_phy* phy) return 0; } -static int bcm5421_enable_fiber(struct mii_phy* phy) -{ - /* enable fiber mode */ - phy_write(phy, MII_NCONFIG, 0x9020); - /* LEDs active in both modes, autosense prio = fiber */ - phy_write(phy, MII_NCONFIG, 0x945f); - - /* switch off fibre autoneg */ - phy_write(phy, MII_NCONFIG, 0xfc01); - phy_write(phy, 0x0b, 0x0004); - - return 0; -} - -static int bcm5461_enable_fiber(struct mii_phy* phy) -{ - phy_write(phy, MII_NCONFIG, 0xfc0c); - phy_write(phy, MII_BMCR, 0x4140); - phy_write(phy, MII_NCONFIG, 0xfc0b); - phy_write(phy, MII_BMCR, 0x0140); - - return 0; -} - static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise) { u16 ctl, adv; @@ -762,7 +738,7 @@ static struct mii_phy_def bcm5401_phy_def = { /* Broadcom BCM 5411 */ static struct mii_phy_ops bcm5411_phy_ops = { .init = bcm5411_init, - .suspend = generic_suspend, + .suspend = bcm5411_suspend, .setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, @@ -781,12 +757,11 @@ static struct mii_phy_def bcm5411_phy_def = { /* Broadcom BCM 5421 */ static struct mii_phy_ops bcm5421_phy_ops = { .init = bcm5421_init, - .suspend = generic_suspend, + .suspend = bcm5411_suspend, .setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, .read_link = bcm54xx_read_link, - .enable_fiber = bcm5421_enable_fiber, }; static struct mii_phy_def bcm5421_phy_def = { @@ -801,7 +776,7 @@ static struct mii_phy_def bcm5421_phy_def = { /* Broadcom BCM 5421 built-in K2 */ static struct mii_phy_ops bcm5421k2_phy_ops = { .init = bcm5421_init, - .suspend = generic_suspend, + .suspend = bcm5411_suspend, .setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, @@ -817,29 +792,10 @@ static struct mii_phy_def bcm5421k2_phy_def = { .ops = &bcm5421k2_phy_ops }; -static struct mii_phy_ops bcm5461_phy_ops = { - .init = bcm5421_init, - .suspend = generic_suspend, - .setup_aneg = bcm54xx_setup_aneg, - .setup_forced = bcm54xx_setup_forced, - .poll_link = genmii_poll_link, - .read_link = bcm54xx_read_link, - .enable_fiber = bcm5461_enable_fiber, -}; - -static struct mii_phy_def bcm5461_phy_def = { - .phy_id = 0x002060c0, - .phy_id_mask = 0xfffffff0, - .name = "BCM5461", - .features = MII_GBIT_FEATURES, - .magic_aneg = 1, - .ops = &bcm5461_phy_ops -}; - /* Broadcom BCM 5462 built-in Vesta */ static struct mii_phy_ops bcm5462V_phy_ops = { .init = bcm5421_init, - .suspend = generic_suspend, + .suspend = bcm5411_suspend, .setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, @@ -860,7 +816,6 @@ static struct mii_phy_def bcm5462V_phy_def = { * would be useful here) --BenH. */ static struct mii_phy_ops marvell_phy_ops = { - .suspend = generic_suspend, .setup_aneg = marvell_setup_aneg, .setup_forced = marvell_setup_forced, .poll_link = genmii_poll_link, @@ -901,7 +856,6 @@ static struct mii_phy_def* mii_phy_table[] = { &bcm5411_phy_def, &bcm5421_phy_def, &bcm5421k2_phy_def, - &bcm5461_phy_def, &bcm5462V_phy_def, &marvell_phy_def, &genmii_phy_def, diff --git a/drivers/net/sungem_phy.h b/drivers/net/sungem_phy.h index 69e125197..430544496 100644 --- a/drivers/net/sungem_phy.h +++ b/drivers/net/sungem_phy.h @@ -12,7 +12,6 @@ struct mii_phy_ops int (*setup_forced)(struct mii_phy *phy, int speed, int fd); int (*poll_link)(struct mii_phy *phy); int (*read_link)(struct mii_phy *phy); - int (*enable_fiber)(struct mii_phy *phy); }; /* Structure used to statically define an mii/gii based PHY */ diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 09a6b8e6d..6d638361d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -69,8 +69,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.59.1" -#define DRV_MODULE_RELDATE "August 25, 2006" +#define DRV_MODULE_VERSION "3.49" +#define DRV_MODULE_RELDATE "Feb 2, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -221,26 +221,10 @@ static struct pci_device_id tg3_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715S, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S, @@ -497,40 +481,33 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) unsigned long flags; spin_lock_irqsave(&tp->indirect_lock, flags); - if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - - /* Always leave this as zero. */ - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); - } else { - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); - tw32_f(TG3PCI_MEM_WIN_DATA, val); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - /* Always leave this as zero. */ - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); - } + /* Always leave this as zero. */ + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); spin_unlock_irqrestore(&tp->indirect_lock, flags); } +static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) +{ + /* If no workaround is needed, write to mem space directly */ + if (tp->write32 != tg3_write_indirect_reg32) + tw32(NIC_SRAM_WIN_BASE + off, val); + else + tg3_write_mem(tp, off, val); +} + static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) { unsigned long flags; spin_lock_irqsave(&tp->indirect_lock, flags); - if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); - pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - - /* Always leave this as zero. */ - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); - } else { - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); - *val = tr32(TG3PCI_MEM_WIN_DATA); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); + pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - /* Always leave this as zero. */ - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); - } + /* Always leave this as zero. */ + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); spin_unlock_irqrestore(&tp->indirect_lock, flags); } @@ -557,9 +534,6 @@ static void tg3_enable_ints(struct tg3 *tp) (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, (tp->last_tag << 24)); - if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) - tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - (tp->last_tag << 24)); tg3_cond_int(tp); } @@ -974,8 +948,6 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) return err; } -static void tg3_link_report(struct tg3 *); - /* This will reset the tigon3 PHY if there is no valid * link unless the FORCE argument is non-zero. */ @@ -989,11 +961,6 @@ static int tg3_phy_reset(struct tg3 *tp) if (err != 0) return -EBUSY; - if (netif_running(tp->dev) && netif_carrier_ok(tp->dev)) { - netif_carrier_off(tp->dev); - tg3_link_report(tp); - } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { @@ -1030,12 +997,6 @@ out: tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x14e2); tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); } - else if (tp->tg3_flags2 & TG3_FLG2_PHY_JITTER_BUG) { - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); - tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); - tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); - } /* Set Extended packet length bit (bit 14) on all chips that */ /* support jumbo frames */ if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { @@ -1077,11 +1038,9 @@ static void tg3_frob_aux_power(struct tg3 *tp) struct net_device *dev_peer; dev_peer = pci_get_drvdata(tp->pdev_peer); - /* remove_one() may have been run on the peer. */ if (!dev_peer) - tp_peer = tp; - else - tp_peer = netdev_priv(dev_peer); + BUG(); + tp_peer = netdev_priv(dev_peer); } if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || @@ -1172,20 +1131,7 @@ static int tg3_halt_cpu(struct tg3 *, u32); static int tg3_nvram_lock(struct tg3 *); static void tg3_nvram_unlock(struct tg3 *); -static void tg3_power_down_phy(struct tg3 *tp) -{ - /* The PHY should not be powered down on some chips because - * of bugs. - */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 && - (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))) - return; - tg3_writephy(tp, MII_BMCR, BMCR_PDOWN); -} - -static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) +static int tg3_set_power_state(struct tg3 *tp, int state) { u32 misc_host_ctrl; u16 power_control, power_caps; @@ -1204,7 +1150,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) power_control |= PCI_PM_CTRL_PME_STATUS; power_control &= ~(PCI_PM_CTRL_STATE_MASK); switch (state) { - case PCI_D0: + case 0: power_control |= 0; pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, @@ -1217,15 +1163,15 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) return 0; - case PCI_D1: + case 1: power_control |= 1; break; - case PCI_D2: + case 2: power_control |= 2; break; - case PCI_D3hot: + case 3: power_control |= 3; break; @@ -1364,7 +1310,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) tg3_writephy(tp, MII_TG3_EXT_CTRL, MII_TG3_EXT_CTRL_FORCE_LED_OFF); tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); - tg3_power_down_phy(tp); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) + tg3_writephy(tp, MII_BMCR, BMCR_PDOWN); } } @@ -1387,12 +1334,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) } } - tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); - /* Finally, set the new power state. */ pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); udelay(100); /* Delay after power state change */ + tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); + return 0; } @@ -2733,12 +2680,6 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) err |= tg3_readphy(tp, MII_BMSR, &bmsr); err |= tg3_readphy(tp, MII_BMSR, &bmsr); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { - if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP) - bmsr |= BMSR_LSTATUS; - else - bmsr &= ~BMSR_LSTATUS; - } err |= tg3_readphy(tp, MII_BMCR, &bmcr); @@ -2807,13 +2748,6 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) bmcr = new_bmcr; err |= tg3_readphy(tp, MII_BMSR, &bmsr); err |= tg3_readphy(tp, MII_BMSR, &bmsr); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == - ASIC_REV_5714) { - if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP) - bmsr |= BMSR_LSTATUS; - else - bmsr &= ~BMSR_LSTATUS; - } tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } } @@ -2979,7 +2913,9 @@ static void tg3_tx(struct tg3 *tp) struct sk_buff *skb = ri->skb; int i; - BUG_ON(skb == NULL); + if (unlikely(skb == NULL)) + BUG(); + pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping), skb_headlen(skb), @@ -2990,10 +2926,12 @@ static void tg3_tx(struct tg3 *tp) sw_idx = NEXT_TX(sw_idx); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - BUG_ON(sw_idx == hw_idx); + if (unlikely(sw_idx == hw_idx)) + BUG(); ri = &tp->tx_buffers[sw_idx]; - BUG_ON(ri->skb != NULL); + if (unlikely(ri->skb != NULL)) + BUG(); pci_unmap_page(tp->pdev, pci_unmap_addr(ri, mapping), @@ -3400,23 +3338,6 @@ static inline void tg3_full_unlock(struct tg3 *tp) spin_unlock_bh(&tp->lock); } -/* One-shot MSI handler - Chip automatically disables interrupt - * after sending MSI so driver doesn't have to do it. - */ -static irqreturn_t tg3_msi_1shot(int irq, void *dev_id, struct pt_regs *regs) -{ - struct net_device *dev = dev_id; - struct tg3 *tp = netdev_priv(dev); - - prefetch(tp->hw_status); - prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); - - if (likely(!tg3_irq_sync(tp))) - netif_rx_schedule(dev); /* schedule NAPI poll */ - - return IRQ_HANDLED; -} - /* MSI ISR - No need to check for interrupt sharing and no need to * flush status block and interrupt mailbox. PCI ordering rules * guarantee that MSI will arrive after the status block. @@ -3544,7 +3465,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, return IRQ_RETVAL(0); } -static int tg3_init_hw(struct tg3 *, int); +static int tg3_init_hw(struct tg3 *); static int tg3_halt(struct tg3 *, int, int); #ifdef CONFIG_NET_POLL_CONTROLLER @@ -3580,7 +3501,7 @@ static void tg3_reset_task(void *_data) tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); - tg3_init_hw(tp, 1); + tg3_init_hw(tp); tg3_netif_start(tp); @@ -3616,7 +3537,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, int len) { #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) - if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) return (((u64) mapping + len) > DMA_40BIT_MASK); return 0; #else @@ -3707,135 +3628,7 @@ static void tg3_set_txd(struct tg3 *tp, int entry, txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT; } -/* hard_start_xmit for devices that don't have any bugs and - * support TG3_FLG2_HW_TSO_2 only. - */ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct tg3 *tp = netdev_priv(dev); - dma_addr_t mapping; - u32 len, entry, base_flags, mss; - - len = skb_headlen(skb); - - /* No BH disabling for tx_lock here. We are running in BH disabled - * context and TX reclaim runs via tp->poll inside of a software - * interrupt. Furthermore, IRQ processing runs lockless so we have - * no IRQ context deadlocks to worry about either. Rejoice! - */ - if (!spin_trylock(&tp->tx_lock)) - return NETDEV_TX_LOCKED; - - if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { - if (!netif_queue_stopped(dev)) { - netif_stop_queue(dev); - - /* This is a hard error, log it. */ - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " - "queue awake!\n", dev->name); - } - spin_unlock(&tp->tx_lock); - return NETDEV_TX_BUSY; - } - - entry = tp->tx_prod; - base_flags = 0; -#if TG3_TSO_SUPPORT != 0 - mss = 0; - if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->gso_size) != 0) { - int tcp_opt_len, ip_tcp_len; - - if (skb_header_cloned(skb) && - pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { - dev_kfree_skb(skb); - goto out_unlock; - } - - tcp_opt_len = ((skb->h.th->doff - 5) * 4); - ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); - - base_flags |= (TXD_FLAG_CPU_PRE_DMA | - TXD_FLAG_CPU_POST_DMA); - - skb->nh.iph->check = 0; - skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); - - skb->h.th->check = 0; - - mss |= (ip_tcp_len + tcp_opt_len) << 9; - } - else if (skb->ip_summed == CHECKSUM_HW) - base_flags |= TXD_FLAG_TCPUDP_CSUM; -#else - mss = 0; - if (skb->ip_summed == CHECKSUM_HW) - base_flags |= TXD_FLAG_TCPUDP_CSUM; -#endif -#if TG3_VLAN_TAG_USED - if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) - base_flags |= (TXD_FLAG_VLAN | - (vlan_tx_tag_get(skb) << 16)); -#endif - - /* Queue skb data, a.k.a. the main skb fragment. */ - mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE); - - tp->tx_buffers[entry].skb = skb; - pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping); - - tg3_set_txd(tp, entry, mapping, len, base_flags, - (skb_shinfo(skb)->nr_frags == 0) | (mss << 1)); - - entry = NEXT_TX(entry); - - /* Now loop through additional data fragments, and queue them. */ - if (skb_shinfo(skb)->nr_frags > 0) { - unsigned int i, last; - - last = skb_shinfo(skb)->nr_frags - 1; - for (i = 0; i <= last; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - len = frag->size; - mapping = pci_map_page(tp->pdev, - frag->page, - frag->page_offset, - len, PCI_DMA_TODEVICE); - - tp->tx_buffers[entry].skb = NULL; - pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping); - - tg3_set_txd(tp, entry, mapping, len, - base_flags, (i == last) | (mss << 1)); - - entry = NEXT_TX(entry); - } - } - - /* Packets are ready, update Tx producer idx local and on card. */ - tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); - - tp->tx_prod = entry; - if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) { - netif_stop_queue(dev); - if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH) - netif_wake_queue(tp->dev); - } - -out_unlock: - mmiowb(); - spin_unlock(&tp->tx_lock); - - dev->trans_start = jiffies; - - return NETDEV_TX_OK; -} - -/* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and - * support TG3_FLG2_HW_TSO_1 or firmware TSO only. - */ -static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); dma_addr_t mapping; @@ -3871,7 +3664,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) #if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->gso_size) != 0) { + (mss = skb_shinfo(skb)->tso_size) != 0) { int tcp_opt_len, ip_tcp_len; if (skb_header_cloned(skb) && @@ -4055,7 +3848,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) tg3_set_mtu(dev, tp, new_mtu); - tg3_init_hw(tp, 0); + tg3_init_hw(tp); tg3_netif_start(tp); @@ -4485,8 +4278,9 @@ static void tg3_disable_nvram_access(struct tg3 *tp) /* tp->lock is held. */ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind) { - tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, - NIC_SRAM_FIRMWARE_MBOX_MAGIC1); + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) + tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, + NIC_SRAM_FIRMWARE_MBOX_MAGIC1); if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) { switch (kind) { @@ -4567,17 +4361,13 @@ static int tg3_chip_reset(struct tg3 *tp) void (*write_op)(struct tg3 *, u32, u32); int i; - tg3_nvram_lock(tp); - - /* No matching tg3_nvram_unlock() after this because - * chip reset below will undo the nvram lock. - */ - tp->nvram_lock_cnt = 0; - - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) - tw32(GRC_FASTBOOT_PC, 0); + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { + tg3_nvram_lock(tp); + /* No matching tg3_nvram_unlock() after this because + * chip reset below will undo the nvram lock. + */ + tp->nvram_lock_cnt = 0; + } /* * We must avoid the readl() that normally takes place. @@ -4725,25 +4515,20 @@ static int tg3_chip_reset(struct tg3 *tp) tw32_f(MAC_MODE, 0); udelay(40); - /* Wait for firmware initialization to complete. */ - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - - /* Chip might not be fitted with firmare. Some Sun onboard - * parts are configured like that. So don't signal the timeout - * of the above loop as an error, but do report the lack of - * running firmware once. - */ - if (i >= 100000 && - !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { - tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; - - printk(KERN_INFO PFX "%s: No firmware running.\n", - tp->dev->name); + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { + /* Wait for firmware initialization to complete. */ + for (i = 0; i < 100000; i++) { + tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + udelay(10); + } + if (i >= 100000) { + printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " + "firmware will not restart magic=%08x\n", + tp->dev->name, val); + return -ENODEV; + } } if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && @@ -4947,8 +4732,9 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset) { int i; - BUG_ON(offset == TX_CPU_BASE && - (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)); + if (offset == TX_CPU_BASE && + (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) + BUG(); if (offset == RX_CPU_BASE) { for (i = 0; i < 10000; i++) { @@ -5732,26 +5518,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - if (!netif_running(dev)) - return 0; - - if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { - /* Reset chip so that ASF can re-init any MAC addresses it - * needs. - */ - tg3_netif_stop(tp); - tg3_full_lock(tp, 1); - - tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - tg3_init_hw(tp, 0); - - tg3_netif_start(tp); - tg3_full_unlock(tp); - } else { - spin_lock_bh(&tp->lock); - __tg3_set_mac_addr(tp); - spin_unlock_bh(&tp->lock); - } + spin_lock_bh(&tp->lock); + __tg3_set_mac_addr(tp); + spin_unlock_bh(&tp->lock); return 0; } @@ -5801,7 +5570,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) } /* tp->lock is held. */ -static int tg3_reset_hw(struct tg3 *tp, int reset_phy) +static int tg3_reset_hw(struct tg3 *tp) { u32 val, rdmac_mode; int i, err, limit; @@ -5816,9 +5585,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tg3_abort_hw(tp, 1); } - if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && reset_phy) - tg3_phy_reset(tp); - err = tg3_chip_reset(tp); if (err) return err; @@ -5865,14 +5631,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GRC_MODE_NO_TX_PHDR_CSUM | GRC_MODE_NO_RX_PHDR_CSUM); tp->grc_mode |= GRC_MODE_HOST_SENDBDS; - - /* Pseudo-header checksum is done by hardware logic and not - * the offload processers, so make the chip do the pseudo- - * header checksums on receive. For transmit it is more - * convenient to do the pseudo-header checksum in software - * as Linux does that on transmit for us in all cases. - */ - tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; + if (tp->tg3_flags & TG3_FLAG_NO_TX_PSEUDO_CSUM) + tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; + if (tp->tg3_flags & TG3_FLAG_NO_RX_PSEUDO_CSUM) + tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM; tw32(GRC_MODE, tp->grc_mode | @@ -6193,9 +5955,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) gpio_mask |= GRC_LCLCTRL_GPIO_OE3 | GRC_LCLCTRL_GPIO_OUTPUT3; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) - gpio_mask |= GRC_LCLCTRL_GPIO_UART_SEL; - tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask; /* GPIO1 must be driven high for eeprom write protect */ @@ -6234,11 +5993,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) } } - /* Enable host coalescing bug fix */ - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)) - val |= (1 << 29); - tw32_f(WDMAC_MODE, val); udelay(40); @@ -6294,9 +6048,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(100); tp->rx_mode = RX_MODE_ENABLE; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) - tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE; - tw32_f(MAC_RX_MODE, tp->rx_mode); udelay(10); @@ -6346,18 +6097,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG; } - if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) { - u32 tmp; - - tmp = tr32(SERDES_RX_CTRL); - tw32(SERDES_RX_CTRL, tmp | SERDES_RX_SIG_DETECT); - tp->grc_local_ctrl &= ~GRC_LCLCTRL_USE_EXT_SIG_DETECT; - tp->grc_local_ctrl |= GRC_LCLCTRL_USE_SIG_DETECT; - tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); - } - - err = tg3_setup_phy(tp, reset_phy); + err = tg3_setup_phy(tp, 1); if (err) return err; @@ -6430,12 +6170,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) /* Called at device open time to get the chip ready for * packet processing. Invoked with tp->lock held. */ -static int tg3_init_hw(struct tg3 *tp, int reset_phy) +static int tg3_init_hw(struct tg3 *tp) { int err; /* Force the chip into D0. */ - err = tg3_set_power_state(tp, PCI_D0); + err = tg3_set_power_state(tp, 0); if (err) goto out; @@ -6443,7 +6183,7 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy) tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); - err = tg3_reset_hw(tp, reset_phy); + err = tg3_reset_hw(tp); out: return err; @@ -6491,19 +6231,12 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp) TG3_STAT_ADD32(&sp->rx_frame_too_long_errors, MAC_RX_STATS_FRAME_TOO_LONG); TG3_STAT_ADD32(&sp->rx_jabbers, MAC_RX_STATS_JABBERS); TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE); - - TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT); - TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT); - TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT); } static void tg3_timer(unsigned long __opaque) { struct tg3 *tp = (struct tg3 *) __opaque; - if (tp->irq_sync) - goto restart_timer; - spin_lock(&tp->lock); if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { @@ -6580,11 +6313,11 @@ static void tg3_timer(unsigned long __opaque) if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { u32 val; - tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, - FWCMD_NICDRV_ALIVE2); - tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, + FWCMD_NICDRV_ALIVE2); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); /* 5 seconds timeout */ - tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); val = tr32(GRC_RX_CPU_EVENT); val |= (1 << 14); tw32(GRC_RX_CPU_EVENT, val); @@ -6594,31 +6327,10 @@ static void tg3_timer(unsigned long __opaque) spin_unlock(&tp->lock); -restart_timer: tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); } -static int tg3_request_irq(struct tg3 *tp) -{ - irqreturn_t (*fn)(int, void *, struct pt_regs *); - unsigned long flags; - struct net_device *dev = tp->dev; - - if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { - fn = tg3_msi; - if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) - fn = tg3_msi_1shot; - flags = SA_SAMPLE_RANDOM; - } else { - fn = tg3_interrupt; - if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) - fn = tg3_interrupt_tagged; - flags = SA_SHIRQ | SA_SAMPLE_RANDOM; - } - return (request_irq(tp->pdev->irq, fn, flags, dev->name, dev)); -} - static int tg3_test_interrupt(struct tg3 *tp) { struct net_device *dev = tp->dev; @@ -6655,7 +6367,16 @@ static int tg3_test_interrupt(struct tg3 *tp) free_irq(tp->pdev->irq, dev); - err = tg3_request_irq(tp); + if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) + err = request_irq(tp->pdev->irq, tg3_msi, + SA_SAMPLE_RANDOM, dev->name, dev); + else { + irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + fn = tg3_interrupt_tagged; + err = request_irq(tp->pdev->irq, fn, + SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + } if (err) return err; @@ -6707,7 +6428,14 @@ static int tg3_test_msi(struct tg3 *tp) tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; - err = tg3_request_irq(tp); + { + irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + fn = tg3_interrupt_tagged; + + err = request_irq(tp->pdev->irq, fn, + SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + } if (err) return err; @@ -6717,7 +6445,7 @@ static int tg3_test_msi(struct tg3 *tp) tg3_full_lock(tp, 1); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - err = tg3_init_hw(tp, 1); + err = tg3_init_hw(tp); tg3_full_unlock(tp); @@ -6734,10 +6462,6 @@ static int tg3_open(struct net_device *dev) tg3_full_lock(tp, 0); - err = tg3_set_power_state(tp, PCI_D0); - if (err) - return err; - tg3_disable_ints(tp); tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; @@ -6752,9 +6476,7 @@ static int tg3_open(struct net_device *dev) if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) && - (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX) && - !((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) && - (tp->pdev_peer == tp->pdev))) { + (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) { /* All MSI supporting chips should support tagged * status. Assert that this is the case. */ @@ -6769,7 +6491,17 @@ static int tg3_open(struct net_device *dev) tp->tg3_flags2 |= TG3_FLG2_USING_MSI; } } - err = tg3_request_irq(tp); + if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) + err = request_irq(tp->pdev->irq, tg3_msi, + SA_SAMPLE_RANDOM, dev->name, dev); + else { + irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + fn = tg3_interrupt_tagged; + + err = request_irq(tp->pdev->irq, fn, + SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + } if (err) { if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { @@ -6782,7 +6514,7 @@ static int tg3_open(struct net_device *dev) tg3_full_lock(tp, 0); - err = tg3_init_hw(tp, 1); + err = tg3_init_hw(tp); if (err) { tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_free_rings(tp); @@ -6834,14 +6566,6 @@ static int tg3_open(struct net_device *dev) return err; } - - if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { - if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) { - u32 val = tr32(0x7c04); - - tw32(0x7c04, val | (1 << 29)); - } - } } tg3_full_lock(tp, 0); @@ -7115,6 +6839,7 @@ static int tg3_close(struct net_device *dev) tp->tg3_flags &= ~(TG3_FLAG_INIT_COMPLETE | TG3_FLAG_GOT_SERDES_FLOWCTL); + netif_carrier_off(tp->dev); tg3_full_unlock(tp); @@ -7131,10 +6856,6 @@ static int tg3_close(struct net_device *dev) tg3_free_consistent(tp); - tg3_set_power_state(tp, PCI_D3hot); - - netif_carrier_off(tp->dev); - return 0; } @@ -7429,9 +7150,6 @@ static void tg3_set_rx_mode(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); - if (!netif_running(dev)) - return; - tg3_full_lock(tp, 0); __tg3_set_rx_mode(dev); tg3_full_unlock(tp); @@ -7456,9 +7174,6 @@ static void tg3_get_regs(struct net_device *dev, memset(p, 0, TG3_REGDUMP_LEN); - if (tp->link_config.phy_is_low_power) - return; - tg3_full_lock(tp, 0); #define __GET_REG32(reg) (*(p)++ = tr32(reg)) @@ -7525,7 +7240,6 @@ static int tg3_get_eeprom_len(struct net_device *dev) } static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val); -static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val); static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { @@ -7534,9 +7248,6 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *pd; u32 i, offset, len, val, b_offset, b_count; - if (tp->link_config.phy_is_low_power) - return -EAGAIN; - offset = eeprom->offset; len = eeprom->len; eeprom->len = 0; @@ -7598,9 +7309,6 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u32 offset, len, b_offset, odd_len, start, end; u8 *buf; - if (tp->link_config.phy_is_low_power) - return -EAGAIN; - if (eeprom->magic != TG3_EEPROM_MAGIC) return -EINVAL; @@ -7736,7 +7444,6 @@ static void tg3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info strcpy(info->driver, DRV_MODULE_NAME); strcpy(info->version, DRV_MODULE_VERSION); - strcpy(info->fw_version, tp->fw_ver); strcpy(info->bus_info, pci_name(tp->pdev)); } @@ -7831,20 +7538,11 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * ering->rx_max_pending = TG3_RX_RING_SIZE - 1; ering->rx_mini_max_pending = 0; - if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) - ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1; - else - ering->rx_jumbo_max_pending = 0; - - ering->tx_max_pending = TG3_TX_RING_SIZE - 1; + ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1; ering->rx_pending = tp->rx_pending; ering->rx_mini_pending = 0; - if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) - ering->rx_jumbo_pending = tp->rx_jumbo_pending; - else - ering->rx_jumbo_pending = 0; - + ering->rx_jumbo_pending = tp->rx_jumbo_pending; ering->tx_pending = tp->tx_pending; } @@ -7875,7 +7573,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e if (netif_running(dev)) { tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - tg3_init_hw(tp, 1); + tg3_init_hw(tp); tg3_netif_start(tp); } @@ -7920,7 +7618,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam if (netif_running(dev)) { tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - tg3_init_hw(tp, 1); + tg3_init_hw(tp); tg3_netif_start(tp); } @@ -7965,11 +7663,10 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data) return 0; } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) - ethtool_op_set_tx_hw_csum(dev, data); + if (data) + dev->features |= NETIF_F_IP_CSUM; else - ethtool_op_set_tx_csum(dev, data); + dev->features &= ~NETIF_F_IP_CSUM; return 0; } @@ -8039,56 +7736,29 @@ static void tg3_get_ethtool_stats (struct net_device *dev, } #define NVRAM_TEST_SIZE 0x100 -#define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14 static int tg3_test_nvram(struct tg3 *tp) { - u32 *buf, csum, magic; - int i, j, err = 0, size; - - if (tg3_nvram_read_swab(tp, 0, &magic) != 0) - return -EIO; - - if (magic == TG3_EEPROM_MAGIC) - size = NVRAM_TEST_SIZE; - else if ((magic & 0xff000000) == 0xa5000000) { - if ((magic & 0xe00000) == 0x200000) - size = NVRAM_SELFBOOT_FORMAT1_SIZE; - else - return 0; - } else - return -EIO; + u32 *buf, csum; + int i, j, err = 0; - buf = kmalloc(size, GFP_KERNEL); + buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - err = -EIO; - for (i = 0, j = 0; i < size; i += 4, j++) { + for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) { u32 val; if ((err = tg3_nvram_read(tp, i, &val)) != 0) break; buf[j] = cpu_to_le32(val); } - if (i < size) + if (i < NVRAM_TEST_SIZE) goto out; - /* Selfboot format */ - if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) { - u8 *buf8 = (u8 *) buf, csum8 = 0; - - for (i = 0; i < size; i++) - csum8 += buf8[i]; - - if (csum8 == 0) { - err = 0; - goto out; - } - - err = -EIO; + err = -EIO; + if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) goto out; - } /* Bootstrap checksum at offset 0x10 */ csum = calc_crc((unsigned char *) buf, 0x10); @@ -8348,7 +8018,7 @@ out: static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len) { - static const u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a }; + static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a }; int i; u32 j; @@ -8382,25 +8052,14 @@ static int tg3_test_memory(struct tg3 *tp) { 0x00008000, 0x02000}, { 0x00010000, 0x0e000}, { 0xffffffff, 0x00000} - }, mem_tbl_5755[] = { - { 0x00000200, 0x00008}, - { 0x00004000, 0x00800}, - { 0x00006000, 0x00800}, - { 0x00008000, 0x02000}, - { 0x00010000, 0x0c000}, - { 0xffffffff, 0x00000} }; struct mem_entry *mem_tbl; int err = 0; int i; - if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) - mem_tbl = mem_tbl_5755; - else - mem_tbl = mem_tbl_5705; - } else + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) + mem_tbl = mem_tbl_5705; + else mem_tbl = mem_tbl_570x; for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { @@ -8449,11 +8108,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) } mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; - if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) mac_mode &= ~MAC_MODE_LINK_POLARITY; - tg3_writephy(tp, MII_TG3_EXT_CTRL, - MII_TG3_EXT_CTRL_LNK3_LED_MODE); - } tw32(MAC_MODE, mac_mode); } else @@ -8463,9 +8119,6 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) tx_len = 1514; skb = dev_alloc_skb(tx_len); - if (!skb) - return -ENOMEM; - tx_data = skb_put(skb, tx_len); memcpy(tx_data, tp->dev->dev_addr, 6); memset(tx_data + 6, 0x0, 8); @@ -8561,7 +8214,7 @@ static int tg3_test_loopback(struct tg3 *tp) if (!netif_running(tp->dev)) return TG3_LOOPBACK_FAILED; - tg3_reset_hw(tp, 1); + tg3_reset_hw(tp); if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) err |= TG3_MAC_LOOPBACK_FAILED; @@ -8578,9 +8231,6 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, { struct tg3 *tp = netdev_priv(dev); - if (tp->link_config.phy_is_low_power) - tg3_set_power_state(tp, PCI_D0); - memset(data, 0, sizeof(u64) * TG3_NUM_TEST); if (tg3_test_nvram(tp) != 0) { @@ -8609,9 +8259,6 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, if (!err) tg3_nvram_unlock(tp); - if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) - tg3_phy_reset(tp); - if (tg3_test_registers(tp) != 0) { etest->flags |= ETH_TEST_FL_FAILED; data[2] = 1; @@ -8635,15 +8282,12 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); if (netif_running(dev)) { tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - tg3_init_hw(tp, 1); + tg3_init_hw(tp); tg3_netif_start(tp); } tg3_full_unlock(tp); } - if (tp->link_config.phy_is_low_power) - tg3_set_power_state(tp, PCI_D3hot); - } static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -8663,9 +8307,6 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) break; /* We have no PHY */ - if (tp->link_config.phy_is_low_power) - return -EAGAIN; - spin_lock_bh(&tp->lock); err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval); spin_unlock_bh(&tp->lock); @@ -8682,9 +8323,6 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (tp->link_config.phy_is_low_power) - return -EAGAIN; - spin_lock_bh(&tp->lock); err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in); spin_unlock_bh(&tp->lock); @@ -8828,14 +8466,14 @@ static struct ethtool_ops tg3_ethtool_ops = { static void __devinit tg3_get_eeprom_size(struct tg3 *tp) { - u32 cursize, val, magic; + u32 cursize, val; tp->nvram_size = EEPROM_CHIP_SIZE; - if (tg3_nvram_read_swab(tp, 0, &magic) != 0) + if (tg3_nvram_read(tp, 0, &val) != 0) return; - if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000)) + if (swab32(val) != TG3_EEPROM_MAGIC) return; /* @@ -8843,13 +8481,13 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp) * When we encounter our validation signature, we know the addressing * has wrapped around, and thus have our chip size. */ - cursize = 0x10; + cursize = 0x800; while (cursize < tp->nvram_size) { - if (tg3_nvram_read_swab(tp, cursize, &val) != 0) + if (tg3_nvram_read(tp, cursize, &val) != 0) return; - if (val == magic) + if (swab32(val) == TG3_EEPROM_MAGIC) break; cursize <<= 1; @@ -8862,15 +8500,6 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp) { u32 val; - if (tg3_nvram_read_swab(tp, 0, &val) != 0) - return; - - /* Selfboot format */ - if (val != TG3_EEPROM_MAGIC) { - tg3_get_eeprom_size(tp); - return; - } - if (tg3_nvram_read(tp, 0xf0, &val) == 0) { if (val != 0) { tp->nvram_size = (val >> 16) * 1024; @@ -8994,90 +8623,14 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp) } } -static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp) -{ - u32 nvcfg1; - - nvcfg1 = tr32(NVRAM_CFG1); - - /* NVRAM protection for TPM */ - if (nvcfg1 & (1 << 27)) - tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM; - - switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { - case FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ: - case FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ: - tp->nvram_jedecnum = JEDEC_ATMEL; - tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; - tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; - - nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; - tw32(NVRAM_CFG1, nvcfg1); - break; - case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: - case FLASH_5755VENDOR_ATMEL_FLASH_1: - case FLASH_5755VENDOR_ATMEL_FLASH_2: - case FLASH_5755VENDOR_ATMEL_FLASH_3: - case FLASH_5755VENDOR_ATMEL_FLASH_4: - tp->nvram_jedecnum = JEDEC_ATMEL; - tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; - tp->tg3_flags2 |= TG3_FLG2_FLASH; - tp->nvram_pagesize = 264; - break; - case FLASH_5752VENDOR_ST_M45PE10: - case FLASH_5752VENDOR_ST_M45PE20: - case FLASH_5752VENDOR_ST_M45PE40: - tp->nvram_jedecnum = JEDEC_ST; - tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; - tp->tg3_flags2 |= TG3_FLG2_FLASH; - tp->nvram_pagesize = 256; - break; - } -} - -static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp) -{ - u32 nvcfg1; - - nvcfg1 = tr32(NVRAM_CFG1); - - switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { - case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ: - case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ: - case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ: - case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ: - tp->nvram_jedecnum = JEDEC_ATMEL; - tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; - tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; - - nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; - tw32(NVRAM_CFG1, nvcfg1); - break; - case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: - case FLASH_5755VENDOR_ATMEL_FLASH_1: - case FLASH_5755VENDOR_ATMEL_FLASH_2: - case FLASH_5755VENDOR_ATMEL_FLASH_3: - tp->nvram_jedecnum = JEDEC_ATMEL; - tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; - tp->tg3_flags2 |= TG3_FLG2_FLASH; - tp->nvram_pagesize = 264; - break; - case FLASH_5752VENDOR_ST_M45PE10: - case FLASH_5752VENDOR_ST_M45PE20: - case FLASH_5752VENDOR_ST_M45PE40: - tp->nvram_jedecnum = JEDEC_ST; - tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; - tp->tg3_flags2 |= TG3_FLG2_FLASH; - tp->nvram_pagesize = 256; - break; - } -} - /* Chips other than 5700/5701 use the NVRAM for fetching info. */ static void __devinit tg3_nvram_init(struct tg3 *tp) { int j; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) + return; + tw32_f(GRC_EEPROM_ADDR, (EEPROM_ADDR_FSM_RESET | (EEPROM_DEFAULT_CLOCK_PERIOD << @@ -9105,10 +8658,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) tg3_get_5752_nvram_info(tp); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) - tg3_get_5755_nvram_info(tp); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) - tg3_get_5787_nvram_info(tp); else tg3_get_nvram_info(tp); @@ -9178,42 +8727,26 @@ static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd) return 0; } -static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr) -{ - if ((tp->tg3_flags & TG3_FLAG_NVRAM) && - (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) && - (tp->tg3_flags2 & TG3_FLG2_FLASH) && - (tp->nvram_jedecnum == JEDEC_ATMEL)) - - addr = ((addr / tp->nvram_pagesize) << - ATMEL_AT45DB0X1B_PAGE_POS) + - (addr % tp->nvram_pagesize); - - return addr; -} - -static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr) -{ - if ((tp->tg3_flags & TG3_FLAG_NVRAM) && - (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) && - (tp->tg3_flags2 & TG3_FLG2_FLASH) && - (tp->nvram_jedecnum == JEDEC_ATMEL)) - - addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) * - tp->nvram_pagesize) + - (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1)); - - return addr; -} - static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) { int ret; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n"); + return -EINVAL; + } + if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) return tg3_nvram_read_using_eeprom(tp, offset, val); - offset = tg3_nvram_phys_addr(tp, offset); + if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) && + (tp->tg3_flags2 & TG3_FLG2_FLASH) && + (tp->nvram_jedecnum == JEDEC_ATMEL)) { + + offset = ((offset / tp->nvram_pagesize) << + ATMEL_AT45DB0X1B_PAGE_POS) + + (offset % tp->nvram_pagesize); + } if (offset > NVRAM_ADDR_MSK) return -EINVAL; @@ -9238,16 +8771,6 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) return ret; } -static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val) -{ - int err; - u32 tmp; - - err = tg3_nvram_read(tp, offset, &tmp); - *val = swab32(tmp); - return err; -} - static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp, u32 offset, u32 len, u8 *buf) { @@ -9400,7 +8923,15 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, page_off = offset % tp->nvram_pagesize; - phy_addr = tg3_nvram_phys_addr(tp, offset); + if ((tp->tg3_flags2 & TG3_FLG2_FLASH) && + (tp->nvram_jedecnum == JEDEC_ATMEL)) { + + phy_addr = ((offset / tp->nvram_pagesize) << + ATMEL_AT45DB0X1B_PAGE_POS) + page_off; + } + else { + phy_addr = offset; + } tw32(NVRAM_ADDR, phy_addr); @@ -9408,15 +8939,13 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, if ((page_off == 0) || (i == 0)) nvram_cmd |= NVRAM_CMD_FIRST; - if (page_off == (tp->nvram_pagesize - 4)) + else if (page_off == (tp->nvram_pagesize - 4)) nvram_cmd |= NVRAM_CMD_LAST; if (i == (len - 4)) nvram_cmd |= NVRAM_CMD_LAST; if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) && - (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) && - (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) && (tp->nvram_jedecnum == JEDEC_ST) && (nvram_cmd & NVRAM_CMD_FIRST)) { @@ -9442,6 +8971,11 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) { int ret; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + printk(KERN_ERR PFX "Attempt to do nvram_write on Sun 570X\n"); + return -EINVAL; + } + if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl & ~GRC_LCLCTRL_GPIO_OUTPUT1); @@ -9549,18 +9083,12 @@ static inline struct subsys_tbl_ent *lookup_by_subsys(struct tg3 *tp) return NULL; } +/* Since this function may be called in D3-hot power state during + * tg3_init_one(), only config cycles are allowed. + */ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) { u32 val; - u16 pmcsr; - - /* On some early chips the SRAM cannot be accessed in D3hot state, - * so need make sure we're in D0. - */ - pci_read_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, &pmcsr); - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pci_write_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, pmcsr); - msleep(1); /* Make sure register accesses (indirect or otherwise) * will function correctly. @@ -9568,20 +9096,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); - /* The memory arbiter has to be enabled in order for SRAM accesses - * to succeed. Normally on powerup the tg3 chip firmware will make - * sure it is enabled, but other entities such as system netboot - * code might disable it. - */ - val = tr32(MEMARB_MODE); - tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); - tp->phy_id = PHY_ID_INVALID; tp->led_ctrl = LED_CTRL_MODE_PHY_1; - /* Assume an onboard device by default. */ - tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; - tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); if (val == NIC_SRAM_DATA_SIG_MAGIC) { u32 nic_cfg, led_cfg; @@ -9678,10 +9195,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) tp->led_ctrl = LED_CTRL_MODE_PHY_2; - if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) + if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) && + (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; - else - tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; @@ -9827,55 +9344,32 @@ skip_phy_reset: static void __devinit tg3_read_partno(struct tg3 *tp) { unsigned char vpd_data[256]; - int i; - u32 magic; - - if (tg3_nvram_read_swab(tp, 0x0, &magic)) - goto out_not_found; + unsigned int i; - if (magic == TG3_EEPROM_MAGIC) { - for (i = 0; i < 256; i += 4) { - u32 tmp; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + /* Sun decided not to put the necessary bits in the + * NVRAM of their onboard tg3 parts :( + */ + strcpy(tp->board_part_number, "Sun 570X"); + return; + } - if (tg3_nvram_read(tp, 0x100 + i, &tmp)) - goto out_not_found; + for (i = 0; i < 256; i += 4) { + u32 tmp; - vpd_data[i + 0] = ((tmp >> 0) & 0xff); - vpd_data[i + 1] = ((tmp >> 8) & 0xff); - vpd_data[i + 2] = ((tmp >> 16) & 0xff); - vpd_data[i + 3] = ((tmp >> 24) & 0xff); - } - } else { - int vpd_cap; - - vpd_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_VPD); - for (i = 0; i < 256; i += 4) { - u32 tmp, j = 0; - u16 tmp16; - - pci_write_config_word(tp->pdev, vpd_cap + PCI_VPD_ADDR, - i); - while (j++ < 100) { - pci_read_config_word(tp->pdev, vpd_cap + - PCI_VPD_ADDR, &tmp16); - if (tmp16 & 0x8000) - break; - msleep(1); - } - if (!(tmp16 & 0x8000)) - goto out_not_found; + if (tg3_nvram_read(tp, 0x100 + i, &tmp)) + goto out_not_found; - pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA, - &tmp); - tmp = cpu_to_le32(tmp); - memcpy(&vpd_data[i], &tmp, 4); - } + vpd_data[i + 0] = ((tmp >> 0) & 0xff); + vpd_data[i + 1] = ((tmp >> 8) & 0xff); + vpd_data[i + 2] = ((tmp >> 16) & 0xff); + vpd_data[i + 3] = ((tmp >> 24) & 0xff); } /* Now parse and find the part number. */ - for (i = 0; i < 256; ) { + for (i = 0; i < 254; ) { unsigned char val = vpd_data[i]; - int block_end; + unsigned int block_end; if (val == 0x82 || val == 0x91) { i = (i + 3 + @@ -9891,21 +9385,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp) (vpd_data[i + 1] + (vpd_data[i + 2] << 8))); i += 3; - while (i < block_end) { + + if (block_end > 256) + goto out_not_found; + + while (i < (block_end - 2)) { if (vpd_data[i + 0] == 'P' && vpd_data[i + 1] == 'N') { int partno_len = vpd_data[i + 2]; - if (partno_len > 24) + i += 3; + if (partno_len > 24 || (partno_len + i) > 256) goto out_not_found; memcpy(tp->board_part_number, - &vpd_data[i + 3], - partno_len); + &vpd_data[i], partno_len); /* Success. */ return; } + i += 3 + vpd_data[i + 2]; } /* Part number not found. */ @@ -9916,45 +9415,36 @@ out_not_found: strcpy(tp->board_part_number, "none"); } -static void __devinit tg3_read_fw_ver(struct tg3 *tp) +#ifdef CONFIG_SPARC64 +static int __devinit tg3_is_sun_570X(struct tg3 *tp) { - u32 val, offset, start; - - if (tg3_nvram_read_swab(tp, 0, &val)) - return; - - if (val != TG3_EEPROM_MAGIC) - return; - - if (tg3_nvram_read_swab(tp, 0xc, &offset) || - tg3_nvram_read_swab(tp, 0x4, &start)) - return; - - offset = tg3_nvram_logical_addr(tp, offset); - if (tg3_nvram_read_swab(tp, offset, &val)) - return; - - if ((val & 0xfc000000) == 0x0c000000) { - u32 ver_offset, addr; - int i; - - if (tg3_nvram_read_swab(tp, offset + 4, &val) || - tg3_nvram_read_swab(tp, offset + 8, &ver_offset)) - return; - - if (val != 0) - return; + struct pci_dev *pdev = tp->pdev; + struct pcidev_cookie *pcp = pdev->sysdata; - addr = offset + ver_offset - start; - for (i = 0; i < 16; i += 4) { - if (tg3_nvram_read(tp, addr + i, &val)) - return; + if (pcp != NULL) { + int node = pcp->prom_node; + u32 venid; + int err; - val = cpu_to_le32(val); - memcpy(tp->fw_ver + i, &val, 4); - } + err = prom_getproperty(node, "subsystem-vendor-id", + (char *) &venid, sizeof(venid)); + if (err == 0 || err == -1) + return 0; + if (venid == PCI_VENDOR_ID_SUN) + return 1; + + /* TG3 chips onboard the SunBlade-2500 don't have the + * subsystem-vendor-id set to PCI_VENDOR_ID_SUN but they + * are distinguishable from non-Sun variants by being + * named "network" by the firmware. Non-Sun cards will + * show up as being named "ethernet". + */ + if (!strcmp(pcp->prom_name, "network")) + return 1; } + return 0; } +#endif static int __devinit tg3_get_invariants(struct tg3 *tp) { @@ -9972,6 +9462,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) u16 pci_cmd; int err; +#ifdef CONFIG_SPARC64 + if (tg3_is_sun_570X(tp)) + tp->tg3_flags2 |= TG3_FLG2_SUN_570X; +#endif + /* Force memory write invalidate off. If we leave it on, * then on 5700_BX chips we have to enable a workaround. * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary @@ -10111,8 +9606,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) tp->tg3_flags2 |= TG3_FLG2_5750_PLUS; @@ -10120,20 +9613,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)) tp->tg3_flags2 |= TG3_FLG2_5705_PLUS; - if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) { - tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2; - tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; - } else - tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1; - } + if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) + tp->tg3_flags2 |= TG3_FLG2_HW_TSO; if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0) @@ -10264,12 +9749,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); } - if (tp->write32 == tg3_write_indirect_reg32 || - ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701))) - tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; - /* Get eeprom hw config before calling tg3_set_power_state(). * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be * determined before calling tg3_set_power_state() so that @@ -10295,11 +9774,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) - tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; - /* Force the chip into D0. */ - err = tg3_set_power_state(tp, PCI_D0); + err = tg3_set_power_state(tp, 0); if (err) { printk(KERN_ERR PFX "(%s) transition to D0 failed\n", pci_name(tp->pdev)); @@ -10312,6 +9788,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; + /* Pseudo-header checksum is done by hardware logic and not + * the offload processers, so make the chip do the pseudo- + * header checksums on receive. For transmit it is more + * convenient to do the pseudo-header checksum in software + * as Linux does that on transmit for us in all cases. + */ + tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM; + tp->tg3_flags &= ~TG3_FLAG_NO_RX_PSEUDO_CSUM; + /* Derive initial jumbo mode from MTU assigned in * ether_setup() via the alloc_etherdev() call */ @@ -10343,13 +9828,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG; - if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) - tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; - else - tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; - } + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) + tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; tp->coalesce_mode = 0; if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX && @@ -10448,7 +9928,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } tg3_read_partno(tp); - tg3_read_fw_ver(tp); if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT; @@ -10484,14 +9963,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) else tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; - /* All chips before 5787 can get confused if TX buffers + /* It seems all chips can get confused if TX buffers * straddle the 4GB address boundary in some cases. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) - tp->dev->hard_start_xmit = tg3_start_xmit; - else - tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug; + tp->dev->hard_start_xmit = tg3_start_xmit; tp->rx_offset = 2; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && @@ -10540,7 +10015,6 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) { struct net_device *dev = tp->dev; u32 hi, lo, mac_offset; - int addr_ok = 0; #ifdef CONFIG_SPARC64 if (!tg3_get_macaddr_sparc(tp)) @@ -10548,7 +10022,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) #endif mac_offset = 0x7c; - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && + !(tp->tg3_flags & TG3_FLG2_SUN_570X)) || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) mac_offset = 0xcc; @@ -10569,33 +10044,29 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) dev->dev_addr[3] = (lo >> 16) & 0xff; dev->dev_addr[4] = (lo >> 8) & 0xff; dev->dev_addr[5] = (lo >> 0) & 0xff; + } + /* Next, try NVRAM. */ + else if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && + !tg3_nvram_read(tp, mac_offset + 0, &hi) && + !tg3_nvram_read(tp, mac_offset + 4, &lo)) { + dev->dev_addr[0] = ((hi >> 16) & 0xff); + dev->dev_addr[1] = ((hi >> 24) & 0xff); + dev->dev_addr[2] = ((lo >> 0) & 0xff); + dev->dev_addr[3] = ((lo >> 8) & 0xff); + dev->dev_addr[4] = ((lo >> 16) & 0xff); + dev->dev_addr[5] = ((lo >> 24) & 0xff); + } + /* Finally just fetch it out of the MAC control regs. */ + else { + hi = tr32(MAC_ADDR_0_HIGH); + lo = tr32(MAC_ADDR_0_LOW); - /* Some old bootcode may report a 0 MAC address in SRAM */ - addr_ok = is_valid_ether_addr(&dev->dev_addr[0]); - } - if (!addr_ok) { - /* Next, try NVRAM. */ - if (!tg3_nvram_read(tp, mac_offset + 0, &hi) && - !tg3_nvram_read(tp, mac_offset + 4, &lo)) { - dev->dev_addr[0] = ((hi >> 16) & 0xff); - dev->dev_addr[1] = ((hi >> 24) & 0xff); - dev->dev_addr[2] = ((lo >> 0) & 0xff); - dev->dev_addr[3] = ((lo >> 8) & 0xff); - dev->dev_addr[4] = ((lo >> 16) & 0xff); - dev->dev_addr[5] = ((lo >> 24) & 0xff); - } - /* Finally just fetch it out of the MAC control regs. */ - else { - hi = tr32(MAC_ADDR_0_HIGH); - lo = tr32(MAC_ADDR_0_LOW); - - dev->dev_addr[5] = lo & 0xff; - dev->dev_addr[4] = (lo >> 8) & 0xff; - dev->dev_addr[3] = (lo >> 16) & 0xff; - dev->dev_addr[2] = (lo >> 24) & 0xff; - dev->dev_addr[1] = hi & 0xff; - dev->dev_addr[0] = (hi >> 8) & 0xff; - } + dev->dev_addr[5] = lo & 0xff; + dev->dev_addr[4] = (lo >> 8) & 0xff; + dev->dev_addr[3] = (lo >> 16) & 0xff; + dev->dev_addr[2] = (lo >> 24) & 0xff; + dev->dev_addr[1] = hi & 0xff; + dev->dev_addr[0] = (hi >> 8) & 0xff; } if (!is_valid_ether_addr(&dev->dev_addr[0])) { @@ -11023,6 +10494,7 @@ static void __devinit tg3_init_link_config(struct tg3 *tp) tp->link_config.speed = SPEED_INVALID; tp->link_config.duplex = DUPLEX_INVALID; tp->link_config.autoneg = AUTONEG_ENABLE; + netif_carrier_off(tp->dev); tp->link_config.active_speed = SPEED_INVALID; tp->link_config.active_duplex = DUPLEX_INVALID; tp->link_config.phy_is_low_power = 0; @@ -11081,8 +10553,6 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) case PHY_ID_BCM5752: return "5752"; case PHY_ID_BCM5714: return "5714"; case PHY_ID_BCM5780: return "5780"; - case PHY_ID_BCM5755: return "5755"; - case PHY_ID_BCM5787: return "5787"; case PHY_ID_BCM8002: return "8002/serdes"; case 0: return "serdes"; default: return "unknown"; @@ -11381,16 +10851,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; } - /* TSO is on by default on chips that support HW_TSO_2. - * Some HW_TSO_1 capable chips have bugs that can lead to - * tx timeouts in some cases when TSO is enabled. - * Firmware TSO on older chips gives lower performance, so it - * is off by default, but can be enabled using ethtool. - */ - if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 && - tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)) + /* TSO is off by default, user can enable using ethtool. */ +#if 0 + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) dev->features |= NETIF_F_TSO; +#endif #endif @@ -11434,12 +10899,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, * checksumming. */ if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) - dev->features |= NETIF_F_HW_CSUM; - else - dev->features |= NETIF_F_IP_CSUM; - dev->features |= NETIF_F_SG; + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; } else tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; @@ -11492,8 +10952,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, (pdev->dma_mask == DMA_32BIT_MASK) ? 32 : (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64)); - netif_carrier_off(tp->dev); - return 0; err_out_iounmap: @@ -11564,7 +11022,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) tg3_full_lock(tp, 0); tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - tg3_init_hw(tp, 1); + tg3_init_hw(tp); tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); @@ -11589,7 +11047,7 @@ static int tg3_resume(struct pci_dev *pdev) pci_restore_state(tp->pdev); - err = tg3_set_power_state(tp, PCI_D0); + err = tg3_set_power_state(tp, 0); if (err) return err; @@ -11598,7 +11056,7 @@ static int tg3_resume(struct pci_dev *pdev) tg3_full_lock(tp, 0); tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - tg3_init_hw(tp, 1); + tg3_init_hw(tp); tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index cd68f4688..7e3b613af 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -125,7 +125,6 @@ #define CHIPREV_ID_5750_A0 0x4000 #define CHIPREV_ID_5750_A1 0x4001 #define CHIPREV_ID_5750_A3 0x4003 -#define CHIPREV_ID_5750_C2 0x4202 #define CHIPREV_ID_5752_A0_HW 0x5000 #define CHIPREV_ID_5752_A0 0x6000 #define CHIPREV_ID_5752_A1 0x6001 @@ -139,8 +138,6 @@ #define ASIC_REV_5752 0x06 #define ASIC_REV_5780 0x08 #define ASIC_REV_5714 0x09 -#define ASIC_REV_5755 0x0a -#define ASIC_REV_5787 0x0b #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) #define CHIPREV_5700_AX 0x70 #define CHIPREV_5700_BX 0x71 @@ -458,7 +455,6 @@ #define RX_MODE_PROMISC 0x00000100 #define RX_MODE_NO_CRC_CHECK 0x00000200 #define RX_MODE_KEEP_VLAN_TAG 0x00000400 -#define RX_MODE_IPV6_CSUM_ENABLE 0x01000000 #define MAC_RX_STATUS 0x0000046c #define RX_STATUS_REMOTE_TX_XOFFED 0x00000001 #define RX_STATUS_XOFF_RCVD 0x00000002 @@ -1343,7 +1339,6 @@ #define GRC_LCLCTRL_CLEARINT 0x00000002 #define GRC_LCLCTRL_SETINT 0x00000004 #define GRC_LCLCTRL_INT_ON_ATTN 0x00000008 -#define GRC_LCLCTRL_GPIO_UART_SEL 0x00000010 /* 5755 only */ #define GRC_LCLCTRL_USE_SIG_DETECT 0x00000010 /* 5714/5780 only */ #define GRC_LCLCTRL_USE_EXT_SIG_DETECT 0x00000020 /* 5714/5780 only */ #define GRC_LCLCTRL_GPIO_INPUT3 0x00000020 @@ -1398,7 +1393,6 @@ #define GRC_MDI_CTRL 0x00006844 #define GRC_SEEPROM_DELAY 0x00006848 /* 0x684c --> 0x6c00 unused */ -#define GRC_FASTBOOT_PC 0x00006894 /* 5752, 5755, 5787 */ /* 0x6c00 --> 0x7000 unused */ @@ -1442,16 +1436,6 @@ #define FLASH_5752VENDOR_ST_M45PE10 0x02400000 #define FLASH_5752VENDOR_ST_M45PE20 0x02400002 #define FLASH_5752VENDOR_ST_M45PE40 0x02400001 -#define FLASH_5755VENDOR_ATMEL_FLASH_1 0x03400001 -#define FLASH_5755VENDOR_ATMEL_FLASH_2 0x03400002 -#define FLASH_5755VENDOR_ATMEL_FLASH_3 0x03400000 -#define FLASH_5755VENDOR_ATMEL_FLASH_4 0x00000003 -#define FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ 0x03c00003 -#define FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ 0x03c00002 -#define FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ 0x03000003 -#define FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ 0x03000002 -#define FLASH_5787VENDOR_MICRO_EEPROM_64KHZ 0x03000000 -#define FLASH_5787VENDOR_MICRO_EEPROM_376KHZ 0x02000000 #define NVRAM_CFG1_5752PAGE_SIZE_MASK 0x70000000 #define FLASH_5752PAGE_SIZE_256 0x00000000 #define FLASH_5752PAGE_SIZE_512 0x10000000 @@ -2172,7 +2156,8 @@ struct tg3 { #define TG3_FLAG_PCIX_MODE 0x00020000 #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 #define TG3_FLAG_PCI_32BIT 0x00080000 -#define TG3_FLAG_SRAM_USE_CONFIG 0x00100000 +#define TG3_FLAG_NO_TX_PSEUDO_CSUM 0x00100000 +#define TG3_FLAG_NO_RX_PSEUDO_CSUM 0x00200000 #define TG3_FLAG_SERDES_WOL_CAP 0x00400000 #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 #define TG3_FLAG_10_100_ONLY 0x01000000 @@ -2185,7 +2170,7 @@ struct tg3 { #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 -/* 0x00000002 available */ +#define TG3_FLG2_SUN_570X 0x00000002 #define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 #define TG3_FLG2_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 @@ -2200,7 +2185,7 @@ struct tg3 { #define TG3_FLG2_PHY_SERDES 0x00002000 #define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000 #define TG3_FLG2_FLASH 0x00008000 -#define TG3_FLG2_HW_TSO_1 0x00010000 +#define TG3_FLG2_HW_TSO 0x00010000 #define TG3_FLG2_SERDES_PREEMPHASIS 0x00020000 #define TG3_FLG2_5705_PLUS 0x00040000 #define TG3_FLG2_5750_PLUS 0x00080000 @@ -2213,11 +2198,6 @@ struct tg3 { #define TG3_FLG2_PARALLEL_DETECT 0x01000000 #define TG3_FLG2_ICH_WORKAROUND 0x02000000 #define TG3_FLG2_5780_CLASS 0x04000000 -#define TG3_FLG2_HW_TSO_2 0x08000000 -#define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2) -#define TG3_FLG2_1SHOT_MSI 0x10000000 -#define TG3_FLG2_PHY_JITTER_BUG 0x20000000 -#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 @@ -2267,8 +2247,6 @@ struct tg3 { #define PHY_ID_BCM5752 0x60008100 #define PHY_ID_BCM5714 0x60008340 #define PHY_ID_BCM5780 0x60008350 -#define PHY_ID_BCM5755 0xbc050cc0 -#define PHY_ID_BCM5787 0xbc050ce0 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_INVALID 0xffffffff #define PHY_ID_REV_MASK 0x0000000f @@ -2280,7 +2258,6 @@ struct tg3 { u32 led_ctrl; char board_part_number[24]; - char fw_ver[16]; u32 nic_sram_data_cfg; u32 pci_clock_ctrl; struct pci_dev *pdev_peer; @@ -2294,8 +2271,7 @@ struct tg3 { (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \ (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \ - (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \ - (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM8002) + (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM8002) struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig index 99c4c1922..e4cfc80b2 100644 --- a/drivers/net/tokenring/Kconfig +++ b/drivers/net/tokenring/Kconfig @@ -3,7 +3,7 @@ # menu "Token Ring devices" - depends on NETDEVICES && !UML + depends on NETDEVICES # So far, we only have PCI, ISA, and MCA token ring devices config TR diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c index 649d8ea35..9345e68c4 100644 --- a/drivers/net/tokenring/abyss.c +++ b/drivers/net/tokenring/abyss.c @@ -438,7 +438,8 @@ static void __devexit abyss_detach (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - BUG_ON(!dev); + if (!dev) + BUG(); unregister_netdev(dev); release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT); free_irq(dev->irq, dev); diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 5cffb1765..4470025ff 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -140,7 +140,7 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */ /* version and credits */ #ifndef PCMCIA -static char version[] __initdata = +static char version[] __devinitdata = "\nibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n" " v2.1.125 10/20/98 Paul Norton \n" " v2.2.0 12/30/98 Joel Sloan \n" @@ -216,7 +216,7 @@ static int __devinitdata turbo_irq[IBMTR_MAX_ADAPTERS] = {0}; static int __devinitdata turbo_searched = 0; #ifndef PCMCIA -static __u32 ibmtr_mem_base __initdata = 0xd0000; +static __u32 ibmtr_mem_base __devinitdata = 0xd0000; #endif static void __devinit PrtChanID(char *pcid, short stride) @@ -845,8 +845,6 @@ static int tok_init_card(struct net_device *dev) struct tok_info *ti; short PIOaddr; unsigned long i; - wait_queue_t __wait; - init_waitqueue_entry(&__wait, current); PIOaddr = dev->base_addr; ti = (struct tok_info *) dev->priv; @@ -858,18 +856,13 @@ static int tok_init_card(struct net_device *dev) schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */ - add_wait_queue(&ti->wait_for_reset, &__wait); - set_current_state(TASK_UNINTERRUPTIBLE); outb(0, PIOaddr + ADAPTRESETREL); #ifdef ENABLE_PAGING if (ti->page_mask) writeb(SRPR_ENABLE_PAGING,ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN); #endif writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); - #warning pci posting bug - i = schedule_timeout(4 * HZ); - current->state = TASK_RUNNING; - remove_wait_queue(&ti->wait_for_reset, &__wait); + i = sleep_on_timeout(&ti->wait_for_reset, 4 * HZ); return i? 0 : -EAGAIN; } diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index c58a4c31d..97712c3c4 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -122,7 +122,6 @@ #include #include #include -#include #include @@ -513,7 +512,7 @@ static int streamer_reset(struct net_device *dev) while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) { msleep_interruptible(100); - if (time_after(jiffies, t + 40 * HZ)) { + if (jiffies - t > 40 * HZ) { printk(KERN_ERR "IBM PCI tokenring card not responding\n"); release_region(dev->base_addr, STREAMER_IO_SPACE); diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 19e6f4dfd..3a25d191e 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -735,7 +735,8 @@ static int __devexit madgemc_remove(struct device *device) struct net_local *tp; struct card_info *card; - BUG_ON(!dev); + if (!dev) + BUG(); tp = dev->priv; card = tp->tmspriv; diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c index 23032a7bc..05477d24f 100644 --- a/drivers/net/tokenring/olympic.c +++ b/drivers/net/tokenring/olympic.c @@ -100,7 +100,6 @@ #include #include #include -#include #include @@ -308,7 +307,7 @@ static int __devinit olympic_init(struct net_device *dev) t=jiffies; while((readl(olympic_mmio+BCTL)) & BCTL_SOFTRESET) { schedule(); - if(time_after(jiffies, t + 40*HZ)) { + if(jiffies-t > 40*HZ) { printk(KERN_ERR "IBM PCI tokenring card not responding.\n"); return -ENODEV; } @@ -360,7 +359,7 @@ static int __devinit olympic_init(struct net_device *dev) t=jiffies; while (!readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE) { schedule() ; - if(time_after(jiffies, t + 2*HZ)) { + if(jiffies-t > 2*HZ) { printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ; return -ENODEV; } @@ -374,7 +373,7 @@ static int __devinit olympic_init(struct net_device *dev) t=jiffies; while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) { schedule(); - if(time_after(jiffies, t + 15*HZ)) { + if(jiffies-t > 15*HZ) { printk(KERN_ERR "IBM PCI tokenring card not responding.\n"); return -ENODEV; } @@ -520,7 +519,7 @@ static int olympic_open(struct net_device *dev) olympic_priv->srb_queued=0; break; } - if (time_after(jiffies, t + 10*HZ)) { + if ((jiffies-t) > 10*HZ) { printk(KERN_WARNING "%s: SRB timed out. \n",dev->name) ; olympic_priv->srb_queued=0; break ; diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index e3dd144d3..2d0cfbcee 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -402,7 +402,8 @@ static void de_rx (struct de_private *de) unsigned copying_skb, buflen; skb = de->rx_skb[rx_tail].skb; - BUG_ON(!skb); + if (!skb) + BUG(); rmb(); status = le32_to_cpu(de->rx_ring[rx_tail].opts1); if (status & DescOwn) @@ -544,7 +545,8 @@ static void de_tx (struct de_private *de) break; skb = de->tx_skb[tx_tail].skb; - BUG_ON(!skb); + if (!skb) + BUG(); if (unlikely(skb == DE_DUMMY_SKB)) goto next; @@ -787,7 +789,8 @@ static void __de_set_rx_mode (struct net_device *dev) de->tx_head = NEXT_TX(entry); - BUG_ON(TX_BUFFS_AVAIL(de) < 0); + if (TX_BUFFS_AVAIL(de) < 0) + BUG(); if (TX_BUFFS_AVAIL(de) == 0) netif_stop_queue(dev); @@ -913,7 +916,8 @@ static void de_set_media (struct de_private *de) unsigned media = de->media_type; u32 macmode = dr32(MacMode); - BUG_ON(de_is_running(de)); + if (de_is_running(de)) + BUG(); if (de->de21040) dw32(CSR11, FULL_DUPLEX_MAGIC); @@ -1149,7 +1153,8 @@ static void de_media_interrupt (struct de_private *de, u32 status) return; } - BUG_ON(!(status & LinkFail)); + if (!(status & LinkFail)) + BUG(); if (netif_carrier_ok(de->dev)) { de_link_down(de); @@ -1327,11 +1332,11 @@ static void de_clean_rings (struct de_private *de) struct sk_buff *skb = de->tx_skb[i].skb; if ((skb) && (skb != DE_DUMMY_SKB)) { if (skb != DE_SETUP_SKB) { + dev_kfree_skb(skb); de->net_stats.tx_dropped++; pci_unmap_single(de->pdev, de->tx_skb[i].mapping, skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb(skb); } else { pci_unmap_single(de->pdev, de->tx_skb[i].mapping, @@ -2087,7 +2092,8 @@ static void __exit de_remove_one (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct de_private *de = dev->priv; - BUG_ON(!dev); + if (!dev) + BUG(); unregister_netdev(dev); kfree(de->ee_data); iounmap(de->regs); diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index f56094102..ee48bfd67 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -513,7 +513,7 @@ struct mii_phy { u_char *rst; /* Start of reset sequence in SROM */ u_int mc; /* Media Capabilities */ u_int ana; /* NWay Advertisement */ - u_int fdx; /* Full DupleX capabilities for each media */ + u_int fdx; /* Full DupleX capabilites for each media */ u_int ttm; /* Transmit Threshold Mode for each media */ u_int mci; /* 21142 MII Connector Interrupt info */ }; @@ -4160,7 +4160,7 @@ get_hw_addr(struct net_device *dev) ** If the address starts with 00 a0, we have to bit-reverse ** each byte of the address. */ - if ( machine_is(powermac) && + if ( (_machine & _MACH_Pmac) && (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0xa0) ) { diff --git a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c index ca7e53246..d9980bde7 100644 --- a/drivers/net/tulip/pnic.c +++ b/drivers/net/tulip/pnic.c @@ -16,7 +16,6 @@ #include #include -#include #include "tulip.h" @@ -69,7 +68,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5) */ if (tulip_media_cap[dev->if_port] & MediaIsMII) return; - if (! tp->nwayset || time_after(jiffies, dev->trans_start + 1*HZ)) { + if (! tp->nwayset || jiffies - dev->trans_start > 1*HZ) { tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff); iowrite32(tp->csr6, ioaddr + CSR6); iowrite32(0x30, ioaddr + CSR12); diff --git a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c index ab985023f..55f4a9a63 100644 --- a/drivers/net/tulip/pnic2.c +++ b/drivers/net/tulip/pnic2.c @@ -199,7 +199,7 @@ void pnic2_lnk_change(struct net_device *dev, int csr5) /* negotiation ended successfully */ /* get the link partners reply and mask out all but - * bits 24-21 which show the partners capabilities + * bits 24-21 which show the partners capabilites * and match those to what we advertised * * then begin to interpret the results of the negotiation. diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 56d86c7c0..5b1af3986 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -850,7 +850,7 @@ static void init_rxtx_rings(struct net_device *dev) break; skb->dev = dev; /* Mark as being used by this device. */ np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data, - np->rx_buf_sz,PCI_DMA_FROMDEVICE); + skb->len,PCI_DMA_FROMDEVICE); np->rx_ring[i].buffer1 = np->rx_addr[i]; np->rx_ring[i].status = DescOwn; @@ -1316,7 +1316,7 @@ static int netdev_rx(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ np->rx_addr[entry] = pci_map_single(np->pci_dev, skb->data, - np->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->len, PCI_DMA_FROMDEVICE); np->rx_ring[entry].buffer1 = np->rx_addr[entry]; } wmb(); @@ -1605,11 +1605,11 @@ static void __devexit w840_remove1 (struct pci_dev *pdev) * - get_stats: * spin_lock_irq(np->lock), doesn't touch hw if not present * - hard_start_xmit: - * synchronize_irq + netif_tx_disable; + * netif_stop_queue + spin_unlock_wait(&dev->xmit_lock); * - tx_timeout: - * netif_device_detach + netif_tx_disable; + * netif_device_detach + spin_unlock_wait(&dev->xmit_lock); * - set_multicast_list - * netif_device_detach + netif_tx_disable; + * netif_device_detach + spin_unlock_wait(&dev->xmit_lock); * - interrupt handler * doesn't touch hw if not present, synchronize_irq waits for * running instances of the interrupt handler. @@ -1635,16 +1635,17 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state) netif_device_detach(dev); update_csr6(dev, 0); iowrite32(0, ioaddr + IntrEnable); + netif_stop_queue(dev); spin_unlock_irq(&np->lock); + spin_unlock_wait(&dev->xmit_lock); synchronize_irq(dev->irq); - netif_tx_disable(dev); np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff; /* no more hardware accesses behind this line. */ - BUG_ON(np->csr6); + if (np->csr6) BUG(); if (ioread32(ioaddr + IntrEnable)) BUG(); /* pci_power_off(pdev, -1); */ diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index 56344103a..60d1e05ab 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -32,9 +32,6 @@ #include #include -#ifdef CONFIG_NET_POLL_CONTROLLER -#include -#endif #ifdef DEBUG #define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__) @@ -601,8 +598,10 @@ static void setup_descriptors(struct xircom_private *card) enter("setup_descriptors"); - BUG_ON(card->rx_buffer == NULL); - BUG_ON(card->tx_buffer == NULL); + if (card->rx_buffer == NULL) + BUG(); + if (card->tx_buffer == NULL) + BUG(); /* Receive descriptors */ memset(card->rx_buffer, 0, 128); /* clear the descriptors */ diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 389d19fb5..4c76cb794 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -134,7 +134,7 @@ static const int multicast_filter_limit = 32; #include "typhoon.h" #include "typhoon-firmware.h" -static const char version[] __devinitdata = +static char version[] __devinitdata = "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("David Dillow "); @@ -178,7 +178,7 @@ enum typhoon_cards { }; /* directly indexed by enum typhoon_cards, above */ -static const struct typhoon_card_info typhoon_card_info[] __devinitdata = { +static struct typhoon_card_info typhoon_card_info[] __devinitdata = { { "3Com Typhoon (3C990-TX)", TYPHOON_CRYPTO_NONE}, { "3Com Typhoon (3CR990-TX-95)", @@ -208,7 +208,7 @@ static const struct typhoon_card_info typhoon_card_info[] __devinitdata = { }; /* Notes on the new subsystem numbering scheme: - * bits 0-1 indicate crypto capabilities: (0) variable, (1) DES, or (2) 3DES + * bits 0-1 indicate crypto capabilites: (0) variable, (1) DES, or (2) 3DES * bit 4 indicates if this card has secured firmware (we don't support it) * bit 8 indicates if this is a (0) copper or (1) fiber card * bits 12-16 indicate card type: (0) client and (1) server @@ -340,7 +340,7 @@ enum state_values { #endif #if defined(NETIF_F_TSO) -#define skb_tso_size(x) (skb_shinfo(x)->gso_size) +#define skb_tso_size(x) (skb_shinfo(x)->tso_size) #define TSO_NUM_DESCRIPTORS 2 #define TSO_OFFLOAD_ON TYPHOON_OFFLOAD_TCP_SEGMENT #else @@ -788,7 +788,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) /* we have two rings to choose from, but we only use txLo for now * If we start using the Hi ring as well, we'll need to update * typhoon_stop_runtime(), typhoon_interrupt(), typhoon_num_free_tx(), - * and TXHI_ENTRIES to match, as well as update the TSO code below + * and TXHI_ENTIRES to match, as well as update the TSO code below * to get the right DMA address */ txRing = &tp->txLoRing; @@ -805,7 +805,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) * If problems develop with TSO, check this first. */ numDesc = skb_shinfo(skb)->nr_frags + 1; - if (skb_is_gso(skb)) + if(skb_tso_size(skb)) numDesc++; /* When checking for free space in the ring, we need to also @@ -845,7 +845,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) TYPHOON_TX_PF_VLAN_TAG_SHIFT); } - if (skb_is_gso(skb)) { + if(skb_tso_size(skb)) { first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT; first_txd->numDesc++; diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index fdc21037f..56864ff3f 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -470,7 +470,7 @@ struct rhine_private { struct sk_buff *tx_skbuff[TX_RING_SIZE]; dma_addr_t tx_skbuff_dma[TX_RING_SIZE]; - /* Tx bounce buffers (Rhine-I only) */ + /* Tx bounce buffers */ unsigned char *tx_buf[TX_RING_SIZE]; unsigned char *tx_bufs; dma_addr_t tx_bufs_dma; @@ -491,6 +491,8 @@ struct rhine_private { u8 tx_thresh, rx_thresh; struct mii_if_info mii_if; + struct work_struct tx_timeout_task; + struct work_struct check_media_task; void __iomem *base; }; @@ -498,6 +500,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *dev, int phy_id, int location, int value); static int rhine_open(struct net_device *dev); static void rhine_tx_timeout(struct net_device *dev); +static void rhine_tx_timeout_task(struct net_device *dev); +static void rhine_check_media_task(struct net_device *dev); static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev); static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void rhine_tx(struct net_device *dev); @@ -852,6 +856,12 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, if (rp->quirks & rqRhineI) dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; + INIT_WORK(&rp->tx_timeout_task, + (void (*)(void *))rhine_tx_timeout_task, dev); + + INIT_WORK(&rp->check_media_task, + (void (*)(void *))rhine_check_media_task, dev); + /* dev->name not defined before register_netdev()! */ rc = register_netdev(dev); if (rc) @@ -1034,8 +1044,7 @@ static void alloc_tbufs(struct net_device* dev) rp->tx_ring[i].desc_length = cpu_to_le32(TXDESC); next += sizeof(struct tx_desc); rp->tx_ring[i].next_desc = cpu_to_le32(next); - if (rp->quirks & rqRhineI) - rp->tx_buf[i] = &rp->tx_bufs[i * PKT_BUF_SZ]; + rp->tx_buf[i] = &rp->tx_bufs[i * PKT_BUF_SZ]; } rp->tx_ring[i-1].next_desc = cpu_to_le32(rp->tx_ring_dma); @@ -1077,25 +1086,11 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media) else iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex, ioaddr + ChipCmd1); - if (debug > 1) - printk(KERN_INFO "%s: force_media %d, carrier %d\n", dev->name, - rp->mii_if.force_media, netif_carrier_ok(dev)); } -/* Called after status of force_media possibly changed */ -static void rhine_set_carrier(struct mii_if_info *mii) +static void rhine_check_media_task(struct net_device *dev) { - if (mii->force_media) { - /* autoneg is off: Link is always assumed to be up */ - if (!netif_carrier_ok(mii->dev)) - netif_carrier_on(mii->dev); - } - else /* Let MMI library update carrier status */ - rhine_check_media(mii->dev, 0); - if (debug > 1) - printk(KERN_INFO "%s: force_media %d, carrier %d\n", - mii->dev->name, mii->force_media, - netif_carrier_ok(mii->dev)); + rhine_check_media(dev, 0); } static void init_registers(struct net_device *dev) @@ -1151,8 +1146,8 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks) if (quirks & rqRhineI) { iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR - /* Can be called from ISR. Evil. */ - mdelay(1); + /* Do not call from ISR! */ + msleep(1); /* 0x80 must be set immediately before turning it off */ iowrite8(0x80, ioaddr + MIICmd); @@ -1240,6 +1235,16 @@ static int rhine_open(struct net_device *dev) } static void rhine_tx_timeout(struct net_device *dev) +{ + struct rhine_private *rp = netdev_priv(dev); + + /* + * Move bulk of work outside of interrupt context + */ + schedule_work(&rp->tx_timeout_task); +} + +static void rhine_tx_timeout_task(struct net_device *dev) { struct rhine_private *rp = netdev_priv(dev); void __iomem *ioaddr = rp->base; @@ -1652,7 +1657,7 @@ static void rhine_error(struct net_device *dev, int intr_status) spin_lock(&rp->lock); if (intr_status & IntrLinkChange) - rhine_check_media(dev, 0); + schedule_work(&rp->check_media_task); if (intr_status & IntrStatsMax) { rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs); rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed); @@ -1783,7 +1788,6 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) spin_lock_irq(&rp->lock); rc = mii_ethtool_sset(&rp->mii_if, cmd); spin_unlock_irq(&rp->lock); - rhine_set_carrier(&rp->mii_if); return rc; } @@ -1871,7 +1875,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) spin_lock_irq(&rp->lock); rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL); spin_unlock_irq(&rp->lock); - rhine_set_carrier(&rp->mii_if); return rc; } @@ -1902,6 +1905,9 @@ static int rhine_close(struct net_device *dev) spin_unlock_irq(&rp->lock); free_irq(rp->pdev->irq, dev); + + flush_scheduled_work(); + free_rbufs(dev); free_tbufs(dev); free_ring(dev); diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 09e05fe40..fb44006dd 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1905,13 +1905,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) int pktlen = skb->len; -#ifdef VELOCITY_ZERO_COPY_SUPPORT - if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) { - kfree_skb(skb); - return 0; - } -#endif - spin_lock_irqsave(&vptr->lock, flags); index = vptr->td_curr[qnum]; @@ -1927,6 +1920,8 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) */ if (pktlen < ETH_ZLEN) { /* Cannot occur until ZC support */ + if(skb_linearize(skb, GFP_ATOMIC)) + return 0; pktlen = ETH_ZLEN; memcpy(tdinfo->buf, skb->data, skb->len); memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); @@ -1944,6 +1939,7 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) int nfrags = skb_shinfo(skb)->nr_frags; tdinfo->skb = skb; if (nfrags > 6) { + skb_linearize(skb, GFP_ATOMIC); memcpy(tdinfo->buf, skb->data, skb->len); tdinfo->skb_dma[0] = tdinfo->buf_dma; td_ptr->tdesc0.pktsize = @@ -2746,7 +2742,7 @@ static u32 check_connection_type(struct mac_regs __iomem * regs) if (PHYSR0 & PHYSR0_SPDG) status |= VELOCITY_SPEED_1000; - if (PHYSR0 & PHYSR0_SPD10) + else if (PHYSR0 & PHYSR0_SPD10) status |= VELOCITY_SPEED_10; else status |= VELOCITY_SPEED_100; @@ -2855,8 +2851,17 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd u32 status; status = check_connection_type(vptr->mac_regs); - cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; - if (status & VELOCITY_SPEED_100) + cmd->supported = SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full; + if (status & VELOCITY_SPEED_1000) + cmd->speed = SPEED_1000; + else if (status & VELOCITY_SPEED_100) cmd->speed = SPEED_100; else cmd->speed = SPEED_10; @@ -2900,7 +2905,7 @@ static u32 velocity_get_link(struct net_device *dev) { struct velocity_info *vptr = dev->priv; struct mac_regs __iomem * regs = vptr->mac_regs; - return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 0 : 1; + return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 1 : 0; } static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index b5328b0ff..18c27e1e7 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig @@ -410,6 +410,103 @@ config WAN_ROUTER_DRIVERS If unsure, say N. +config VENDOR_SANGOMA + tristate "Sangoma WANPIPE(tm) multiprotocol cards" + depends on WAN_ROUTER_DRIVERS && WAN_ROUTER && (PCI || ISA) && BROKEN + ---help--- + Driver for S514-PCI/ISA Synchronous Data Link Adapters (SDLA). + + WANPIPE from Sangoma Technologies Inc. + is a family of intelligent multiprotocol WAN adapters with data + transfer rates up to 4Mbps. Cards support: + + - X.25, Frame Relay, PPP, Cisco HDLC protocols. + + - API for protocols like HDLC (LAPB), HDLC Streaming, X.25, + Frame Relay and BiSync. + + - Ethernet Bridging over Frame Relay protocol. + + - MULTILINK PPP + + - Async PPP (Modem Dialup) + + The next questions will ask you about the protocols you want + the driver to support. + + If you have one or more of these cards, say M to this option; + and read . + + To compile this driver as a module, choose M here: the + module will be called wanpipe. + +config WANPIPE_CHDLC + bool "WANPIPE Cisco HDLC support" + depends on VENDOR_SANGOMA + ---help--- + Connect a WANPIPE card to a leased line using the Cisco HDLC. + + - Supports Dual Port Cisco HDLC on the S514-PCI/S508-ISA cards + which allows user to build applications using the HDLC streaming API. + + - CHDLC Streaming MULTILINK PPP that can bind multiple WANPIPE T1 + cards into a single logical channel. + + Say Y and the Cisco HDLC support, HDLC streaming API and + MULTILINK PPP will be included in the driver. + +config WANPIPE_FR + bool "WANPIPE Frame Relay support" + depends on VENDOR_SANGOMA + help + Connect a WANPIPE card to a Frame Relay network, or use Frame Felay + API to develop custom applications. + + Contains the Ethernet Bridging over Frame Relay feature, where + a WANPIPE frame relay link can be directly connected to the Linux + kernel bridge. The Frame Relay option is supported on S514-PCI + and S508-ISA cards. + + Say Y and the Frame Relay support will be included in the driver. + +config WANPIPE_X25 + bool "WANPIPE X.25 support" + depends on VENDOR_SANGOMA + help + Connect a WANPIPE card to an X.25 network. + + Includes the X.25 API support for custom applications over the + X.25 protocol. The X.25 option is supported on S514-PCI and + S508-ISA cards. + + Say Y and the X.25 support will be included in the driver. + +config WANPIPE_PPP + bool "WANPIPE PPP support" + depends on VENDOR_SANGOMA + help + Connect a WANPIPE card to a leased line using Point-to-Point + Protocol (PPP). + + The PPP option is supported on S514-PCI/S508-ISA cards. + + Say Y and the PPP support will be included in the driver. + +config WANPIPE_MULTPPP + bool "WANPIPE Multi-Port PPP support" + depends on VENDOR_SANGOMA + help + Connect a WANPIPE card to a leased line using Point-to-Point + Protocol (PPP). + + Uses in-kernel SyncPPP protocol over the Sangoma HDLC Streaming + adapter. In this case each Sangoma adapter port can support an + independent PPP connection. For example, a single Quad-Port PCI + adapter can support up to four independent PPP links. The PPP + option is supported on S514-PCI/S508-ISA cards. + + Say Y and the Multi-Port PPP support will be included in the driver. + config CYCLADES_SYNC tristate "Cyclom 2X(tm) cards (EXPERIMENTAL)" depends on WAN_ROUTER_DRIVERS && (PCI || ISA) diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile index 823c6d5ab..ce6c56b90 100644 --- a/drivers/net/wan/Makefile +++ b/drivers/net/wan/Makefile @@ -5,6 +5,14 @@ # Rewritten to use lists instead of if-statements. # +wanpipe-y := sdlamain.o sdla_ft1.o +wanpipe-$(CONFIG_WANPIPE_X25) += sdla_x25.o +wanpipe-$(CONFIG_WANPIPE_FR) += sdla_fr.o +wanpipe-$(CONFIG_WANPIPE_CHDLC) += sdla_chdlc.o +wanpipe-$(CONFIG_WANPIPE_PPP) += sdla_ppp.o +wanpipe-$(CONFIG_WANPIPE_MULTPPP) += wanpipe_multppp.o +wanpipe-objs := $(wanpipe-y) + cyclomx-y := cycx_main.o cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o cyclomx-objs := $(cyclomx-y) @@ -35,6 +43,11 @@ obj-$(CONFIG_LANMEDIA) += lmc/ obj-$(CONFIG_DLCI) += dlci.o obj-$(CONFIG_SDLA) += sdla.o +ifeq ($(CONFIG_WANPIPE_MULTPPP),y) + obj-$(CONFIG_VENDOR_SANGOMA) += sdladrv.o wanpipe.o syncppp.o +else + obj-$(CONFIG_VENDOR_SANGOMA) += sdladrv.o wanpipe.o +endif obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o obj-$(CONFIG_LAPBETHER) += lapbether.o obj-$(CONFIG_SBNI) += sbni.o diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 4505540e3..1ff5de076 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -105,7 +105,6 @@ #include #include #include -#include /* Version */ static const char version[] = "$Id: dscc4.c,v 1.173 2003/09/20 23:55:34 romieu Exp $ for Linux\n"; @@ -113,7 +112,7 @@ static int debug; static int quartz; #ifdef CONFIG_DSCC4_PCI_RST -static DEFINE_MUTEX(dscc4_mutex); +static DECLARE_MUTEX(dscc4_sem); static u32 dscc4_pci_config_store[16]; #endif @@ -1019,7 +1018,7 @@ static void dscc4_pci_reset(struct pci_dev *pdev, void __iomem *ioaddr) { int i; - mutex_lock(&dscc4_mutex); + down(&dscc4_sem); for (i = 0; i < 16; i++) pci_read_config_dword(pdev, i << 2, dscc4_pci_config_store + i); @@ -1040,7 +1039,7 @@ static void dscc4_pci_reset(struct pci_dev *pdev, void __iomem *ioaddr) for (i = 0; i < 16; i++) pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]); - mutex_unlock(&dscc4_mutex); + up(&dscc4_sem); } #else #define dscc4_pci_reset(pdev,ioaddr) do {} while (0) diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index cf5c80545..7db1d1d0b 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 175ba13bc..db2c798ba 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -1495,7 +1495,8 @@ module_param(skip_pci_probe, bool, 0); MODULE_LICENSE("GPL"); -int __init init_module( void ) +int +init_module( void ) { struct net_device *dev; int err; diff --git a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c new file mode 100644 index 000000000..496d29237 --- /dev/null +++ b/drivers/net/wan/sdla_chdlc.c @@ -0,0 +1,4428 @@ +/***************************************************************************** +* sdla_chdlc.c WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module. +* +* Authors: Nenad Corbic +* Gideon Hack +* +* Copyright: (c) 1995-2001 Sangoma 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. +* ============================================================================ +* Feb 28, 2001 Nenad Corbic Updated if_tx_timeout() routine for +* 2.4.X kernels. +* Jan 25, 2001 Nenad Corbic Added a TTY Sync serial driver over the +* HDLC streaming protocol +* Added a TTY Async serial driver over the +* Async protocol. +* Dec 15, 2000 Nenad Corbic Updated for 2.4.X Kernel support +* Nov 13, 2000 Nenad Corbic Added true interface type encoding option. +* Tcpdump doesn't support CHDLC inteface +* types, to fix this "true type" option will set +* the interface type to RAW IP mode. +* Nov 07, 2000 Nenad Corbic Added security features for UDP debugging: +* Deny all and specify allowed requests. +* Jun 20, 2000 Nenad Corbic Fixed the API IP ERROR bug. Caused by the +* latest update. +* May 09, 2000 Nenad Corbic Option to bring down an interface +* upon disconnect. +* Mar 23, 2000 Nenad Corbic Improved task queue, bh handling. +* Mar 16, 2000 Nenad Corbic Fixed the SLARP Dynamic IP addressing. +* Mar 06, 2000 Nenad Corbic Bug Fix: corrupted mbox recovery. +* Feb 10, 2000 Gideon Hack Added ASYNC support. +* Feb 09, 2000 Nenad Corbic Fixed two shutdown bugs in update() and +* if_stats() functions. +* Jan 24, 2000 Nenad Corbic Fixed a startup wanpipe state racing, +* condition between if_open and isr. +* Jan 10, 2000 Nenad Corbic Added new socket API support. +* Dev 15, 1999 Nenad Corbic Fixed up header files for 2.0.X kernels +* Nov 20, 1999 Nenad Corbic Fixed zero length API bug. +* Sep 30, 1999 Nenad Corbic Fixed dynamic IP and route setup. +* Sep 23, 1999 Nenad Corbic Added SMP support, fixed tracing +* Sep 13, 1999 Nenad Corbic Split up Port 0 and 1 into separate devices. +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. +* Oct 30, 1998 Jaspreet Singh Added Support for CHDLC API (HDLC STREAMING). +* Oct 28, 1998 Jaspreet Singh Added Support for Dual Port CHDLC. +* Aug 07, 1998 David Fong Initial version. +*****************************************************************************/ + +#include +#include /* printk(), and other useful stuff */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include /* kmalloc(), kfree() */ +#include /* WAN router definitions */ +#include /* WANPIPE common user API definitions */ +#include /* ARPHRD_* defines */ + + +#include +#include +#include + +#include /* sockaddr_in */ +#include +#include +#include /* htons(), etc. */ +#include +#include + +#include /* CHDLC firmware API definitions */ +#include /* CHDLC (async) API definitions */ + +#include /* Socket Driver common area */ +#include + +/* TTY Includes */ +#include +#include +#include + + +/****** Defines & Macros ****************************************************/ + +/* reasons for enabling the timer interrupt on the adapter */ +#define TMR_INT_ENABLED_UDP 0x01 +#define TMR_INT_ENABLED_UPDATE 0x02 +#define TMR_INT_ENABLED_CONFIG 0x10 + +#define MAX_IP_ERRORS 10 + +#define TTY_CHDLC_MAX_MTU 2000 +#define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */ +#define CHDLC_HDR_LEN 1 + +#define CHDLC_API 0x01 + +#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) +#define MAX_BH_BUFF 10 + +//#define PRINT_DEBUG +#ifdef PRINT_DEBUG +#define dbg_printk(format, a...) printk(format, ## a) +#else +#define dbg_printk(format, a...) +#endif + +/******Data Structures*****************************************************/ + +/* This structure is placed in the private data area of the device structure. + * The card structure used to occupy the private area but now the following + * structure will incorporate the card structure along with CHDLC specific data + */ + +typedef struct chdlc_private_area +{ + wanpipe_common_t common; + sdla_t *card; + int TracingEnabled; /* For enabling Tracing */ + unsigned long curr_trace_addr; /* Used for Tracing */ + unsigned long start_trace_addr; + unsigned long end_trace_addr; + unsigned long base_addr_trace_buffer; + unsigned long end_addr_trace_buffer; + unsigned short number_trace_elements; + unsigned available_buffer_space; + unsigned long router_start_time; + unsigned char route_status; + unsigned char route_removed; + unsigned long tick_counter; /* For 5s timeout counter */ + unsigned long router_up_time; + u32 IP_address; /* IP addressing */ + u32 IP_netmask; + u32 ip_local; + u32 ip_remote; + u32 ip_local_tmp; + u32 ip_remote_tmp; + u8 ip_error; + u8 config_chdlc; + u8 config_chdlc_timeout; + unsigned char mc; /* Mulitcast support on/off */ + unsigned short udp_pkt_lgth; /* udp packet processing */ + char udp_pkt_src; + char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT]; + unsigned short timer_int_enabled; + char update_comms_stats; /* updating comms stats */ + + bh_data_t *bh_head; /* Circular buffer for chdlc_bh */ + unsigned long tq_working; + volatile int bh_write; + volatile int bh_read; + atomic_t bh_buff_used; + + unsigned char interface_down; + + /* Polling work queue entry. Each interface + * has its own work queue entry, which is used + * to defer events from the interrupt */ + struct work_struct poll_work; + struct timer_list poll_delay_timer; + + u8 gateway; + u8 true_if_encoding; + //FIXME: add driver stats as per frame relay! + +} chdlc_private_area_t; + +/* Route Status options */ +#define NO_ROUTE 0x00 +#define ADD_ROUTE 0x01 +#define ROUTE_ADDED 0x02 +#define REMOVE_ROUTE 0x03 + + +/* variable for keeping track of enabling/disabling FT1 monitor status */ +static int rCount = 0; + +/* variable for tracking how many interfaces to open for WANPIPE on the + two ports */ + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +/****** Function Prototypes *************************************************/ +/* WAN link driver entry points. These are called by the WAN router module. */ +static int update(struct wan_device* wandev); +static int new_if(struct wan_device* wandev, struct net_device* dev, + wanif_conf_t* conf); + +/* Network device interface */ +static int if_init(struct net_device* dev); +static int if_open(struct net_device* dev); +static int if_close(struct net_device* dev); +static int if_header(struct sk_buff* skb, struct net_device* dev, + unsigned short type, void* daddr, void* saddr, + unsigned len); + +static int if_rebuild_hdr (struct sk_buff *skb); +static struct net_device_stats* if_stats(struct net_device* dev); + +static int if_send(struct sk_buff* skb, struct net_device* dev); + +/* CHDLC Firmware interface functions */ +static int chdlc_configure (sdla_t* card, void* data); +static int chdlc_comm_enable (sdla_t* card); +static int chdlc_read_version (sdla_t* card, char* str); +static int chdlc_set_intr_mode (sdla_t* card, unsigned mode); +static int chdlc_send (sdla_t* card, void* data, unsigned len); +static int chdlc_read_comm_err_stats (sdla_t* card); +static int chdlc_read_op_stats (sdla_t* card); +static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb); + + +static int chdlc_disable_comm_shutdown (sdla_t *card); +static void if_tx_timeout(struct net_device *dev); + +/* Miscellaneous CHDLC Functions */ +static int set_chdlc_config (sdla_t* card); +static void init_chdlc_tx_rx_buff( sdla_t* card); +static int process_chdlc_exception(sdla_t *card); +static int process_global_exception(sdla_t *card); +static int update_comms_stats(sdla_t* card, + chdlc_private_area_t* chdlc_priv_area); +static int configure_ip (sdla_t* card); +static int unconfigure_ip (sdla_t* card); +static void process_route(sdla_t *card); +static void port_set_state (sdla_t *card, int); +static int config_chdlc (sdla_t *card); +static void disable_comm (sdla_t *card); + +static void trigger_chdlc_poll(struct net_device *dev); +static void chdlc_poll(struct net_device *dev); +static void chdlc_poll_delay (unsigned long dev_ptr); + + +/* Miscellaneous asynchronous interface Functions */ +static int set_asy_config (sdla_t* card); +static int asy_comm_enable (sdla_t* card); + +/* Interrupt handlers */ +static void wpc_isr (sdla_t* card); +static void rx_intr (sdla_t* card); +static void timer_intr(sdla_t *); + +/* Bottom half handlers */ +static void chdlc_work(struct net_device *dev); +static int chdlc_work_cleanup(struct net_device *dev); +static int bh_enqueue(struct net_device *dev, struct sk_buff *skb); + +/* Miscellaneous functions */ +static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev, + struct sk_buff *skb); +static int reply_udp( unsigned char *data, unsigned int mbox_len ); +static int intr_test( sdla_t* card); +static int udp_pkt_type( struct sk_buff *skb , sdla_t* card); +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area); +static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area); +static unsigned short calc_checksum (char *, int); +static void s508_lock (sdla_t *card, unsigned long *smp_flags); +static void s508_unlock (sdla_t *card, unsigned long *smp_flags); + + +static int Intr_test_counter; + +/* TTY Global Definitions */ + +#define NR_PORTS 4 +#define WAN_TTY_MAJOR 226 +#define WAN_TTY_MINOR 0 + +#define WAN_CARD(port) (tty_card_map[port]) +#define MIN_PORT 0 +#define MAX_PORT NR_PORTS-1 + +#define CRC_LENGTH 2 + +static int wanpipe_tty_init(sdla_t *card); +static void wanpipe_tty_receive(sdla_t *, unsigned, unsigned int); +static void wanpipe_tty_trigger_poll(sdla_t *card); + +static struct tty_driver serial_driver; +static int tty_init_cnt=0; + +static struct serial_state rs_table[NR_PORTS]; + +static char tty_driver_mode=WANOPT_TTY_SYNC; + +static char *opt_decode[] = {"NONE","CRTSCTS","XONXOFF-RX", + "CRTSCTS XONXOFF-RX","XONXOFF-TX", + "CRTSCTS XONXOFF-TX","CRTSCTS XONXOFF"}; +static char *p_decode[] = {"NONE","ODD","EVEN"}; + +static void* tty_card_map[NR_PORTS] = {NULL,NULL,NULL,NULL}; + + +/****** Public Functions ****************************************************/ + +/*============================================================================ + * Cisco HDLC protocol initialization routine. + * + * This routine is called by the main WANPIPE module during setup. At this + * point adapter is completely initialized and firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the adapter data space. + * + * Return: 0 o.k. + * < 0 failure. + */ +int wpc_init (sdla_t* card, wandev_conf_t* conf) +{ + unsigned char port_num; + int err; + unsigned long max_permitted_baud = 0; + SHARED_MEMORY_INFO_STRUCT *flags; + + union + { + char str[80]; + } u; + volatile CHDLC_MAILBOX_STRUCT* mb; + CHDLC_MAILBOX_STRUCT* mb1; + unsigned long timeout; + + /* Verify configuration ID */ + if (conf->config_id != WANCONFIG_CHDLC) { + printk(KERN_INFO "%s: invalid configuration ID %u!\n", + card->devname, conf->config_id); + return -EINVAL; + } + + /* Find out which Port to use */ + if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){ + if (card->next){ + + if (conf->comm_port != card->next->u.c.comm_port){ + card->u.c.comm_port = conf->comm_port; + }else{ + printk(KERN_INFO "%s: ERROR - %s port used!\n", + card->wandev.name, PORT(conf->comm_port)); + return -EINVAL; + } + }else{ + card->u.c.comm_port = conf->comm_port; + } + }else{ + printk(KERN_INFO "%s: ERROR - Invalid Port Selected!\n", + card->wandev.name); + return -EINVAL; + } + + + /* Initialize protocol-specific fields */ + if(card->hw.type != SDLA_S514){ + + if (card->u.c.comm_port == WANOPT_PRI){ + card->mbox = (void *) card->hw.dpmbase; + }else{ + card->mbox = (void *) card->hw.dpmbase + + SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT; + } + }else{ + /* for a S514 adapter, set a pointer to the actual mailbox in the */ + /* allocated virtual memory area */ + if (card->u.c.comm_port == WANOPT_PRI){ + card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT; + }else{ + card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT; + } + } + + mb = mb1 = card->mbox; + + if (!card->configured){ + + /* The board will place an 'I' in the return code to indicate that it is + ready to accept commands. We expect this to be completed in less + than 1 second. */ + + timeout = jiffies; + while (mb->return_code != 'I') /* Wait 1s for board to initialize */ + if ((jiffies - timeout) > 1*HZ) break; + + if (mb->return_code != 'I') { + printk(KERN_INFO + "%s: Initialization not completed by adapter\n", + card->devname); + printk(KERN_INFO "Please contact Sangoma representative.\n"); + return -EIO; + } + } + + /* Read firmware version. Note that when adapter initializes, it + * clears the mailbox, so it may appear that the first command was + * executed successfully when in fact it was merely erased. To work + * around this, we execute the first command twice. + */ + + if (chdlc_read_version(card, u.str)) + return -EIO; + + printk(KERN_INFO "%s: Running Cisco HDLC firmware v%s\n", + card->devname, u.str); + + card->isr = &wpc_isr; + card->poll = NULL; + card->exec = NULL; + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = NULL; + card->wandev.udp_port = conf->udp_port; + card->disable_comm = &disable_comm; + card->wandev.new_if_cnt = 0; + + /* reset the number of times the 'update()' proc has been called */ + card->u.c.update_call_count = 0; + + card->wandev.ttl = conf->ttl; + card->wandev.interface = conf->interface; + + if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&& + card->hw.type != SDLA_S514){ + printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n", + card->devname, PORT(card->u.c.comm_port)); + return -EIO; + } + + card->wandev.clocking = conf->clocking; + + port_num = card->u.c.comm_port; + + /* in API mode, we can configure for "receive only" buffering */ + if(card->hw.type == SDLA_S514) { + card->u.c.receive_only = conf->receive_only; + if(conf->receive_only) { + printk(KERN_INFO + "%s: Configured for 'receive only' mode\n", + card->devname); + } + } + + /* Setup Port Bps */ + + if(card->wandev.clocking) { + if((port_num == WANOPT_PRI) || card->u.c.receive_only) { + /* For Primary Port 0 */ + max_permitted_baud = + (card->hw.type == SDLA_S514) ? + PRI_MAX_BAUD_RATE_S514 : + PRI_MAX_BAUD_RATE_S508; + + }else if(port_num == WANOPT_SEC) { + /* For Secondary Port 1 */ + max_permitted_baud = + (card->hw.type == SDLA_S514) ? + SEC_MAX_BAUD_RATE_S514 : + SEC_MAX_BAUD_RATE_S508; + } + + if(conf->bps > max_permitted_baud) { + conf->bps = max_permitted_baud; + printk(KERN_INFO "%s: Baud too high!\n", + card->wandev.name); + printk(KERN_INFO "%s: Baud rate set to %lu bps\n", + card->wandev.name, max_permitted_baud); + } + card->wandev.bps = conf->bps; + }else{ + card->wandev.bps = 0; + } + + /* Setup the Port MTU */ + if((port_num == WANOPT_PRI) || card->u.c.receive_only) { + + /* For Primary Port 0 */ + card->wandev.mtu = + (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ? + min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) : + CHDLC_DFLT_DATA_LEN; + } else if(port_num == WANOPT_SEC) { + /* For Secondary Port 1 */ + card->wandev.mtu = + (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ? + min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) : + CHDLC_DFLT_DATA_LEN; + } + + /* Set up the interrupt status area */ + /* Read the CHDLC Configuration and obtain: + * Ptr to shared memory infor struct + * Use this pointer to calculate the value of card->u.c.flags ! + */ + mb1->buffer_length = 0; + mb1->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT; + if(err != COMMAND_OK) { + if(card->hw.type != SDLA_S514) + enable_irq(card->hw.irq); + + chdlc_error(card, err, mb1); + return -EIO; + } + + if(card->hw.type == SDLA_S514){ + card->u.c.flags = (void *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)-> + ptr_shared_mem_info_struct)); + }else{ + card->u.c.flags = (void *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)-> + ptr_shared_mem_info_struct % SDLA_WINDOWSIZE)); + } + + flags = card->u.c.flags; + + /* This is for the ports link state */ + card->wandev.state = WAN_DUALPORT; + card->u.c.state = WAN_DISCONNECTED; + + + if (!card->wandev.piggyback){ + int err; + + /* Perform interrupt testing */ + err = intr_test(card); + + if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { + printk(KERN_INFO "%s: Interrupt test failed (%i)\n", + card->devname, Intr_test_counter); + printk(KERN_INFO "%s: Please choose another interrupt\n", + card->devname); + return -EIO; + } + + printk(KERN_INFO "%s: Interrupt test passed (%i)\n", + card->devname, Intr_test_counter); + card->configured = 1; + } + + if ((card->tty_opt=conf->tty) == WANOPT_YES){ + int err; + card->tty_minor = conf->tty_minor; + + /* On ASYNC connections internal clocking + * is mandatory */ + if ((card->u.c.async_mode = conf->tty_mode)){ + card->wandev.clocking = 1; + } + err=wanpipe_tty_init(card); + if (err){ + return err; + } + }else{ + + + if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){ + printk (KERN_INFO "%s: " + "Failed to set interrupt triggers!\n", + card->devname); + return -EIO; + } + + /* Mask the Timer interrupt */ + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TIMER; + } + + /* If we are using CHDLC in backup mode, this flag will + * indicate not to look for IP addresses in config_chdlc()*/ + card->u.c.backup = conf->backup; + + printk(KERN_INFO "\n"); + + return 0; +} + +/******* WAN Device Driver Entry Points *************************************/ + +/*============================================================================ + * Update device status & statistics + * This procedure is called when updating the PROC file system and returns + * various communications statistics. These statistics are accumulated from 3 + * different locations: + * 1) The 'if_stats' recorded for the device. + * 2) Communication error statistics on the adapter. + * 3) CHDLC operational statistics on the adapter. + * The board level statistics are read during a timer interrupt. Note that we + * read the error and operational statistics during consecitive timer ticks so + * as to minimize the time that we are inside the interrupt handler. + * + */ +static int update(struct wan_device* wandev) +{ + sdla_t* card = wandev->private; + struct net_device* dev; + volatile chdlc_private_area_t* chdlc_priv_area; + SHARED_MEMORY_INFO_STRUCT *flags; + unsigned long timeout; + + /* sanity checks */ + if((wandev == NULL) || (wandev->private == NULL)) + return -EFAULT; + + if(wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + /* more sanity checks */ + if(!card->u.c.flags) + return -ENODEV; + + if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) + return -EAGAIN; + + if((dev=card->wandev.dev) == NULL) + return -ENODEV; + + if((chdlc_priv_area=dev->priv) == NULL) + return -ENODEV; + + flags = card->u.c.flags; + if(chdlc_priv_area->update_comms_stats){ + return -EAGAIN; + } + + /* we will need 2 timer interrupts to complete the */ + /* reading of the statistics */ + chdlc_priv_area->update_comms_stats = 2; + flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER; + chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE; + + /* wait a maximum of 1 second for the statistics to be updated */ + timeout = jiffies; + for(;;) { + if(chdlc_priv_area->update_comms_stats == 0) + break; + if ((jiffies - timeout) > (1 * HZ)){ + chdlc_priv_area->update_comms_stats = 0; + chdlc_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + return -EAGAIN; + } + } + + return 0; +} + + +/*============================================================================ + * Create new logical channel. + * This routine is called by the router when ROUTER_IFNEW IOCTL is being + * handled. + * o parse media- and hardware-specific configuration + * o make sure that a new channel can be created + * o allocate resources, if necessary + * o prepare network device structure for registaration. + * + * Return: 0 o.k. + * < 0 failure (channel will not be created) + */ +static int new_if(struct wan_device* wandev, struct net_device* dev, + wanif_conf_t* conf) +{ + sdla_t* card = wandev->private; + chdlc_private_area_t* chdlc_priv_area; + + + printk(KERN_INFO "%s: Configuring Interface: %s\n", + card->devname, conf->name); + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { + printk(KERN_INFO "%s: Invalid interface name!\n", + card->devname); + return -EINVAL; + } + + /* allocate and initialize private data */ + chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL); + + if(chdlc_priv_area == NULL) + return -ENOMEM; + + memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t)); + + chdlc_priv_area->card = card; + chdlc_priv_area->common.sk = NULL; + chdlc_priv_area->common.func = NULL; + + /* initialize data */ + strcpy(card->u.c.if_name, conf->name); + + if(card->wandev.new_if_cnt > 0) { + kfree(chdlc_priv_area); + return -EEXIST; + } + + card->wandev.new_if_cnt++; + + chdlc_priv_area->TracingEnabled = 0; + chdlc_priv_area->route_status = NO_ROUTE; + chdlc_priv_area->route_removed = 0; + + card->u.c.async_mode = conf->async_mode; + + /* setup for asynchronous mode */ + if(conf->async_mode) { + printk(KERN_INFO "%s: Configuring for asynchronous mode\n", + wandev->name); + + if(card->u.c.comm_port == WANOPT_PRI) { + printk(KERN_INFO + "%s:Asynchronous mode on secondary port only\n", + wandev->name); + kfree(chdlc_priv_area); + return -EINVAL; + } + + if(strcmp(conf->usedby, "WANPIPE") == 0) { + printk(KERN_INFO + "%s: Running in WANIPE Async Mode\n", wandev->name); + card->u.c.usedby = WANPIPE; + }else{ + card->u.c.usedby = API; + } + + if(!card->wandev.clocking) { + printk(KERN_INFO + "%s: Asynch. clocking must be 'Internal'\n", + wandev->name); + kfree(chdlc_priv_area); + return -EINVAL; + } + + if((card->wandev.bps < MIN_ASY_BAUD_RATE) || + (card->wandev.bps > MAX_ASY_BAUD_RATE)) { + printk(KERN_INFO "%s: Selected baud rate is invalid.\n", + wandev->name); + printk(KERN_INFO "Must be between %u and %u bps.\n", + MIN_ASY_BAUD_RATE, MAX_ASY_BAUD_RATE); + kfree(chdlc_priv_area); + return -EINVAL; + } + + card->u.c.api_options = 0; + if (conf->asy_data_trans == WANOPT_YES) { + card->u.c.api_options |= ASY_RX_DATA_TRANSPARENT; + } + + card->u.c.protocol_options = 0; + if (conf->rts_hs_for_receive == WANOPT_YES) { + card->u.c.protocol_options |= ASY_RTS_HS_FOR_RX; + } + if (conf->xon_xoff_hs_for_receive == WANOPT_YES) { + card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_RX; + } + if (conf->xon_xoff_hs_for_transmit == WANOPT_YES) { + card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_TX; + } + if (conf->dcd_hs_for_transmit == WANOPT_YES) { + card->u.c.protocol_options |= ASY_DCD_HS_FOR_TX; + } + if (conf->cts_hs_for_transmit == WANOPT_YES) { + card->u.c.protocol_options |= ASY_CTS_HS_FOR_TX; + } + + card->u.c.tx_bits_per_char = conf->tx_bits_per_char; + card->u.c.rx_bits_per_char = conf->rx_bits_per_char; + card->u.c.stop_bits = conf->stop_bits; + card->u.c.parity = conf->parity; + card->u.c.break_timer = conf->break_timer; + card->u.c.inter_char_timer = conf->inter_char_timer; + card->u.c.rx_complete_length = conf->rx_complete_length; + card->u.c.xon_char = conf->xon_char; + + } else { /* setup for synchronous mode */ + + card->u.c.protocol_options = 0; + if (conf->ignore_dcd == WANOPT_YES){ + card->u.c.protocol_options |= IGNORE_DCD_FOR_LINK_STAT; + } + if (conf->ignore_cts == WANOPT_YES){ + card->u.c.protocol_options |= IGNORE_CTS_FOR_LINK_STAT; + } + + if (conf->ignore_keepalive == WANOPT_YES) { + card->u.c.protocol_options |= + IGNORE_KPALV_FOR_LINK_STAT; + card->u.c.kpalv_tx = MIN_Tx_KPALV_TIMER; + card->u.c.kpalv_rx = MIN_Rx_KPALV_TIMER; + card->u.c.kpalv_err = MIN_KPALV_ERR_TOL; + + } else { /* Do not ignore keepalives */ + card->u.c.kpalv_tx = + ((conf->keepalive_tx_tmr - MIN_Tx_KPALV_TIMER) + >= 0) ? + min_t(unsigned int, conf->keepalive_tx_tmr,MAX_Tx_KPALV_TIMER) : + DEFAULT_Tx_KPALV_TIMER; + + card->u.c.kpalv_rx = + ((conf->keepalive_rx_tmr - MIN_Rx_KPALV_TIMER) + >= 0) ? + min_t(unsigned int, conf->keepalive_rx_tmr,MAX_Rx_KPALV_TIMER) : + DEFAULT_Rx_KPALV_TIMER; + + card->u.c.kpalv_err = + ((conf->keepalive_err_margin-MIN_KPALV_ERR_TOL) + >= 0) ? + min_t(unsigned int, conf->keepalive_err_margin, + MAX_KPALV_ERR_TOL) : + DEFAULT_KPALV_ERR_TOL; + } + + /* Setup slarp timer to control delay between slarps */ + card->u.c.slarp_timer = + ((conf->slarp_timer - MIN_SLARP_REQ_TIMER) >= 0) ? + min_t(unsigned int, conf->slarp_timer, MAX_SLARP_REQ_TIMER) : + DEFAULT_SLARP_REQ_TIMER; + + if (conf->hdlc_streaming == WANOPT_YES) { + printk(KERN_INFO "%s: Enabling HDLC STREAMING Mode\n", + wandev->name); + card->u.c.protocol_options = HDLC_STREAMING_MODE; + } + + if ((chdlc_priv_area->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){ + printk(KERN_INFO + "%s: Enabling, true interface type encoding.\n", + card->devname); + } + + /* Setup wanpipe as a router (WANPIPE) or as an API */ + if( strcmp(conf->usedby, "WANPIPE") == 0) { + + printk(KERN_INFO "%s: Running in WANPIPE mode!\n", + wandev->name); + card->u.c.usedby = WANPIPE; + + /* Option to bring down the interface when + * the link goes down */ + if (conf->if_down){ + set_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down); + printk(KERN_INFO + "%s: Dynamic interface configuration enabled\n", + card->devname); + } + + } else if( strcmp(conf->usedby, "API") == 0) { + card->u.c.usedby = API; + printk(KERN_INFO "%s: Running in API mode !\n", + wandev->name); + } + } + + /* Tells us that if this interface is a + * gateway or not */ + if ((chdlc_priv_area->gateway = conf->gateway) == WANOPT_YES){ + printk(KERN_INFO "%s: Interface %s is set as a gateway.\n", + card->devname,card->u.c.if_name); + } + + /* Get Multicast Information */ + chdlc_priv_area->mc = conf->mc; + + /* prepare network device data space for registration */ + strcpy(dev->name,card->u.c.if_name); + + dev->init = &if_init; + dev->priv = chdlc_priv_area; + + /* Initialize the polling work routine */ + INIT_WORK(&chdlc_priv_area->poll_work, (void*)(void*)chdlc_poll, dev); + + /* Initialize the polling delay timer */ + init_timer(&chdlc_priv_area->poll_delay_timer); + chdlc_priv_area->poll_delay_timer.data = (unsigned long)dev; + chdlc_priv_area->poll_delay_timer.function = chdlc_poll_delay; + + printk(KERN_INFO "\n"); + + return 0; +} + + +/****** Network Device Interface ********************************************/ + +/*============================================================================ + * Initialize Linux network interface. + * + * This routine is called only once for each interface, during Linux network + * interface registration. Returning anything but zero will fail interface + * registration. + */ +static int if_init(struct net_device* dev) +{ + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + struct wan_device* wandev = &card->wandev; + + /* Initialize device driver entry points */ + dev->open = &if_open; + dev->stop = &if_close; + dev->hard_header = &if_header; + dev->rebuild_header = &if_rebuild_hdr; + dev->hard_start_xmit = &if_send; + dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + /* Initialize media-specific parameters */ + dev->flags |= IFF_POINTOPOINT; + dev->flags |= IFF_NOARP; + + /* Enable Mulitcasting if user selected */ + if (chdlc_priv_area->mc == WANOPT_YES){ + dev->flags |= IFF_MULTICAST; + } + + if (chdlc_priv_area->true_if_encoding){ + dev->type = ARPHRD_HDLC; /* This breaks the tcpdump */ + }else{ + dev->type = ARPHRD_PPP; + } + + dev->mtu = card->wandev.mtu; + /* for API usage, add the API header size to the requested MTU size */ + if(card->u.c.usedby == API) { + dev->mtu += sizeof(api_tx_hdr_t); + } + + dev->hard_header_len = CHDLC_HDR_LEN; + + /* Initialize hardware parameters */ + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + dev->mem_start = wandev->maddr; + dev->mem_end = wandev->maddr + wandev->msize - 1; + + /* Set transmit buffer queue length + * If too low packets will not be retransmitted + * by stack. + */ + dev->tx_queue_len = 100; + SET_MODULE_OWNER(dev); + + return 0; +} + +/*============================================================================ + * Open network interface. + * o enable communications and interrupts. + * o prevent module from unloading by incrementing use count + * + * Return 0 if O.k. or errno. + */ +static int if_open(struct net_device* dev) +{ + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + struct timeval tv; + int err = 0; + + /* Only one open per interface is allowed */ + + if (netif_running(dev)) + return -EBUSY; + + /* Initialize the work queue entry */ + chdlc_priv_area->tq_working=0; + + INIT_WORK(&chdlc_priv_area->common.wanpipe_work, + (void *)(void *)chdlc_work, dev); + + /* Allocate and initialize BH circular buffer */ + /* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */ + chdlc_priv_area->bh_head = kmalloc((sizeof(bh_data_t)*(MAX_BH_BUFF+1)),GFP_ATOMIC); + memset(chdlc_priv_area->bh_head,0,(sizeof(bh_data_t)*(MAX_BH_BUFF+1))); + atomic_set(&chdlc_priv_area->bh_buff_used, 0); + + do_gettimeofday(&tv); + chdlc_priv_area->router_start_time = tv.tv_sec; + + netif_start_queue(dev); + + wanpipe_open(card); + + /* TTY is configured during wanpipe_set_termios + * call, not here */ + if (card->tty_opt) + return err; + + set_bit(0,&chdlc_priv_area->config_chdlc); + chdlc_priv_area->config_chdlc_timeout=jiffies; + + /* Start the CHDLC configuration after 1sec delay. + * This will give the interface initilization time + * to finish its configuration */ + mod_timer(&chdlc_priv_area->poll_delay_timer, jiffies + HZ); + return err; +} + +/*============================================================================ + * Close network interface. + * o if this is the last close, then disable communications and interrupts. + * o reset flags. + */ +static int if_close(struct net_device* dev) +{ + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + + if (chdlc_priv_area->bh_head){ + int i; + struct sk_buff *skb; + + for (i=0; i<(MAX_BH_BUFF+1); i++){ + skb = ((bh_data_t *)&chdlc_priv_area->bh_head[i])->skb; + if (skb != NULL){ + dev_kfree_skb_any(skb); + } + } + kfree(chdlc_priv_area->bh_head); + chdlc_priv_area->bh_head=NULL; + } + + netif_stop_queue(dev); + wanpipe_close(card); + del_timer(&chdlc_priv_area->poll_delay_timer); + return 0; +} + +static void disable_comm (sdla_t *card) +{ + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + + if (card->u.c.comm_enabled){ + chdlc_disable_comm_shutdown (card); + }else{ + flags->interrupt_info_struct.interrupt_permission = 0; + } + + if (!tty_init_cnt) + return; + + if (card->tty_opt){ + struct serial_state * state; + if (!(--tty_init_cnt)){ + int e1; + serial_driver.refcount=0; + + if ((e1 = tty_unregister_driver(&serial_driver))) + printk("SERIAL: failed to unregister serial driver (%d)\n", + e1); + printk(KERN_INFO "%s: Unregistering TTY Driver, Major %i\n", + card->devname,WAN_TTY_MAJOR); + } + card->tty=NULL; + tty_card_map[card->tty_minor]=NULL; + state = &rs_table[card->tty_minor]; + memset(state, 0, sizeof(*state)); + } + return; +} + + +/*============================================================================ + * Build media header. + * + * The trick here is to put packet type (Ethertype) into 'protocol' field of + * the socket buffer, so that we don't forget it. If packet type is not + * supported, set skb->protocol to 0 and discard packet later. + * + * Return: media header length. + */ +static int if_header(struct sk_buff* skb, struct net_device* dev, + unsigned short type, void* daddr, void* saddr, + unsigned len) +{ + skb->protocol = htons(type); + + return CHDLC_HDR_LEN; +} + + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout(struct net_device *dev) +{ + chdlc_private_area_t* chan = dev->priv; + sdla_t *card = chan->card; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + ++card->wandev.stats.collisions; + + printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name); + netif_wake_queue (dev); +} + + + +/*============================================================================ + * Re-build media header. + * + * Return: 1 physical address resolved. + * 0 physical address not resolved + */ +static int if_rebuild_hdr (struct sk_buff *skb) +{ + return 1; +} + + +/*============================================================================ + * Send a packet on a network interface. + * o set tbusy flag (marks start of the transmission) to block a timer-based + * transmit from overlapping. + * o check link state. If link is not up, then drop the packet. + * o execute adapter send command. + * o free socket buffer + * + * Return: 0 complete (socket buffer must be freed) + * non-0 packet may be re-transmitted (tbusy must be set) + * + * Notes: + * 1. This routine is called either by the protocol stack or by the "net + * bottom half" (with interrupts enabled). + * 2. Setting tbusy flag will inhibit further transmit requests from the + * protocol stack and can be used for flow control with protocol layer. + */ +static int if_send(struct sk_buff* skb, struct net_device* dev) +{ + chdlc_private_area_t *chdlc_priv_area = dev->priv; + sdla_t *card = chdlc_priv_area->card; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct; + int udp_type = 0; + unsigned long smp_flags; + int err=0; + + netif_stop_queue(dev); + + if (skb == NULL){ + /* If we get here, some higher layer thinks we've missed an + * tx-done interrupt. + */ + printk(KERN_INFO "%s: interface %s got kicked!\n", + card->devname, dev->name); + + netif_wake_queue(dev); + return 0; + } + + if (ntohs(skb->protocol) != htons(PVC_PROT)){ + + /* check the udp packet type */ + + udp_type = udp_pkt_type(skb, card); + + if (udp_type == UDP_CPIPE_TYPE){ + if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev, + chdlc_priv_area)){ + chdlc_int->interrupt_permission |= + APP_INT_ON_TIMER; + } + netif_start_queue(dev); + return 0; + } + + /* check to see if the source IP address is a broadcast or */ + /* multicast IP address */ + if(chk_bcast_mcast_addr(card, dev, skb)){ + ++card->wandev.stats.tx_dropped; + dev_kfree_skb_any(skb); + netif_start_queue(dev); + return 0; + } + } + + /* Lock the 508 Card: SMP is supported */ + if(card->hw.type != SDLA_S514){ + s508_lock(card,&smp_flags); + } + + if(test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) { + + printk(KERN_INFO "%s: Critical in if_send: %lx\n", + card->wandev.name,card->wandev.critical); + ++card->wandev.stats.tx_dropped; + netif_start_queue(dev); + goto if_send_exit_crit; + } + + if(card->u.c.state != WAN_CONNECTED){ + ++card->wandev.stats.tx_dropped; + netif_start_queue(dev); + + }else if(!skb->protocol){ + ++card->wandev.stats.tx_errors; + netif_start_queue(dev); + + }else { + void* data = skb->data; + unsigned len = skb->len; + unsigned char attr; + + /* If it's an API packet pull off the API + * header. Also check that the packet size + * is larger than the API header + */ + if (card->u.c.usedby == API){ + api_tx_hdr_t* api_tx_hdr; + + /* discard the frame if we are configured for */ + /* 'receive only' mode or if there is no data */ + if (card->u.c.receive_only || + (len <= sizeof(api_tx_hdr_t))) { + + ++card->wandev.stats.tx_dropped; + netif_start_queue(dev); + goto if_send_exit_crit; + } + + api_tx_hdr = (api_tx_hdr_t *)data; + attr = api_tx_hdr->attr; + data += sizeof(api_tx_hdr_t); + len -= sizeof(api_tx_hdr_t); + } + + if(chdlc_send(card, data, len)) { + netif_stop_queue(dev); + }else{ + ++card->wandev.stats.tx_packets; + card->wandev.stats.tx_bytes += len; + + netif_start_queue(dev); + + dev->trans_start = jiffies; + } + } + +if_send_exit_crit: + + if (!(err=netif_queue_stopped(dev))) { + dev_kfree_skb_any(skb); + }else{ + chdlc_priv_area->tick_counter = jiffies; + chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME; + } + + clear_bit(SEND_CRIT, (void*)&card->wandev.critical); + if(card->hw.type != SDLA_S514){ + s508_unlock(card,&smp_flags); + } + + return err; +} + + +/*============================================================================ + * Check to see if the packet to be transmitted contains a broadcast or + * multicast source IP address. + */ + +static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, + struct sk_buff *skb) +{ + u32 src_ip_addr; + u32 broadcast_ip_addr = 0; + struct in_device *in_dev; + + /* read the IP source address from the outgoing packet */ + src_ip_addr = *(u32 *)(skb->data + 12); + + /* read the IP broadcast address for the device */ + in_dev = dev->ip_ptr; + if(in_dev != NULL) { + struct in_ifaddr *ifa= in_dev->ifa_list; + if(ifa != NULL) + broadcast_ip_addr = ifa->ifa_broadcast; + else + return 0; + } + + /* check if the IP Source Address is a Broadcast address */ + if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) { + printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n", + card->devname); + return 1; + } + + /* check if the IP Source Address is a Multicast address */ + if((ntohl(src_ip_addr) >= 0xE0000001) && + (ntohl(src_ip_addr) <= 0xFFFFFFFE)) { + printk(KERN_INFO "%s: Multicast Source Address silently discarded\n", + card->devname); + return 1; + } + + return 0; +} + + +/*============================================================================ + * Reply to UDP Management system. + * Return length of reply. + */ +static int reply_udp( unsigned char *data, unsigned int mbox_len ) +{ + + unsigned short len, udp_length, temp, ip_length; + unsigned long ip_temp; + int even_bound = 0; + chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data; + + /* Set length of packet */ + len = sizeof(ip_pkt_t)+ + sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + sizeof(trace_info_t)+ + mbox_len; + + /* fill in UDP reply */ + c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; + + /* fill in UDP length */ + udp_length = sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + sizeof(trace_info_t)+ + mbox_len; + + /* put it on an even boundary */ + if ( udp_length & 0x0001 ) { + udp_length += 1; + len += 1; + even_bound = 1; + } + + temp = (udp_length<<8)|(udp_length>>8); + c_udp_pkt->udp_pkt.udp_length = temp; + + /* swap UDP ports */ + temp = c_udp_pkt->udp_pkt.udp_src_port; + c_udp_pkt->udp_pkt.udp_src_port = + c_udp_pkt->udp_pkt.udp_dst_port; + c_udp_pkt->udp_pkt.udp_dst_port = temp; + + /* add UDP pseudo header */ + temp = 0x1100; + *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp; + temp = (udp_length<<8)|(udp_length>>8); + *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp; + + + /* calculate UDP checksum */ + c_udp_pkt->udp_pkt.udp_checksum = 0; + c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET); + + /* fill in IP length */ + ip_length = len; + temp = (ip_length<<8)|(ip_length>>8); + c_udp_pkt->ip_pkt.total_length = temp; + + /* swap IP addresses */ + ip_temp = c_udp_pkt->ip_pkt.ip_src_address; + c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address; + c_udp_pkt->ip_pkt.ip_dst_address = ip_temp; + + /* fill in IP checksum */ + c_udp_pkt->ip_pkt.hdr_checksum = 0; + c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t)); + + return len; + +} /* reply_udp */ + +unsigned short calc_checksum (char *data, int len) +{ + unsigned short temp; + unsigned long sum=0; + int i; + + for( i = 0; i > 16 ) { + sum = (sum & 0xffffUL) + (sum >> 16); + } + + temp = (unsigned short)sum; + temp = ~temp; + + if( temp == 0 ) + temp = 0xffff; + + return temp; +} + + +/*============================================================================ + * Get ethernet-style interface statistics. + * Return a pointer to struct enet_statistics. + */ +static struct net_device_stats* if_stats(struct net_device* dev) +{ + sdla_t *my_card; + chdlc_private_area_t* chdlc_priv_area; + + if ((chdlc_priv_area=dev->priv) == NULL) + return NULL; + + my_card = chdlc_priv_area->card; + return &my_card->wandev.stats; +} + + +/****** Cisco HDLC Firmware Interface Functions *******************************/ + +/*============================================================================ + * Read firmware code version. + * Put code version as ASCII string in str. + */ +static int chdlc_read_version (sdla_t* card, char* str) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int len; + char err; + mb->buffer_length = 0; + mb->command = READ_CHDLC_CODE_VERSION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + chdlc_error(card,err,mb); + } + else if (str) { /* is not null */ + len = mb->buffer_length; + memcpy(str, mb->data, len); + str[len] = '\0'; + } + return (err); +} + +/*----------------------------------------------------------------------------- + * Configure CHDLC firmware. + */ +static int chdlc_configure (sdla_t* card, void* data) +{ + int err; + CHDLC_MAILBOX_STRUCT *mailbox = card->mbox; + int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT); + + mailbox->buffer_length = data_length; + memcpy(mailbox->data, data, data_length); + mailbox->command = SET_CHDLC_CONFIGURATION; + err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT; + + if (err != COMMAND_OK) chdlc_error (card, err, mailbox); + + return err; +} + + +/*============================================================================ + * Set interrupt mode -- HDLC Version. + */ + +static int chdlc_set_intr_mode (sdla_t* card, unsigned mode) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_INT_TRIGGERS_STRUCT* int_data = + (CHDLC_INT_TRIGGERS_STRUCT *)mb->data; + int err; + + int_data->CHDLC_interrupt_triggers = mode; + int_data->IRQ = card->hw.irq; + int_data->interrupt_timer = 1; + + mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT); + mb->command = SET_CHDLC_INTERRUPT_TRIGGERS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error (card, err, mb); + return err; +} + + +/*=========================================================== + * chdlc_disable_comm_shutdown + * + * Shutdown() disables the communications. We must + * have a sparate functions, because we must not + * call chdlc_error() hander since the private + * area has already been replaced */ + +static int chdlc_disable_comm_shutdown (sdla_t *card) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_INT_TRIGGERS_STRUCT* int_data = + (CHDLC_INT_TRIGGERS_STRUCT *)mb->data; + int err; + + /* Disable Interrutps */ + int_data->CHDLC_interrupt_triggers = 0; + int_data->IRQ = card->hw.irq; + int_data->interrupt_timer = 1; + + mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT); + mb->command = SET_CHDLC_INTERRUPT_TRIGGERS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + /* Disable Communications */ + + if (card->u.c.async_mode) { + mb->command = DISABLE_ASY_COMMUNICATIONS; + }else{ + mb->command = DISABLE_CHDLC_COMMUNICATIONS; + } + + mb->buffer_length = 0; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + card->u.c.comm_enabled = 0; + + return 0; +} + +/*============================================================================ + * Enable communications. + */ + +static int chdlc_comm_enable (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = ENABLE_CHDLC_COMMUNICATIONS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card, err, mb); + else + card->u.c.comm_enabled = 1; + + return err; +} + +/*============================================================================ + * Read communication error statistics. + */ +static int chdlc_read_comm_err_stats (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = READ_COMMS_ERROR_STATS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + return err; +} + + +/*============================================================================ + * Read CHDLC operational statistics. + */ +static int chdlc_read_op_stats (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_OPERATIONAL_STATS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + return err; +} + + +/*============================================================================ + * Update communications error and general packet statistics. + */ +static int update_comms_stats(sdla_t* card, + chdlc_private_area_t* chdlc_priv_area) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + COMMS_ERROR_STATS_STRUCT* err_stats; + CHDLC_OPERATIONAL_STATS_STRUCT *op_stats; + + /* on the first timer interrupt, read the comms error statistics */ + if(chdlc_priv_area->update_comms_stats == 2) { + if(chdlc_read_comm_err_stats(card)) + return 1; + err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data; + card->wandev.stats.rx_over_errors = + err_stats->Rx_overrun_err_count; + card->wandev.stats.rx_crc_errors = + err_stats->CRC_err_count; + card->wandev.stats.rx_frame_errors = + err_stats->Rx_abort_count; + card->wandev.stats.rx_fifo_errors = + err_stats->Rx_dis_pri_bfrs_full_count; + card->wandev.stats.rx_missed_errors = + card->wandev.stats.rx_fifo_errors; + card->wandev.stats.tx_aborted_errors = + err_stats->sec_Tx_abort_count; + } + + /* on the second timer interrupt, read the operational statistics */ + else { + if(chdlc_read_op_stats(card)) + return 1; + op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data; + card->wandev.stats.rx_length_errors = + (op_stats->Rx_Data_discard_short_count + + op_stats->Rx_Data_discard_long_count); + } + + return 0; +} + +/*============================================================================ + * Send packet. + * Return: 0 - o.k. + * 1 - no transmit buffers available + */ +static int chdlc_send (sdla_t* card, void* data, unsigned len) +{ + CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf; + + if (txbuf->opp_flag) + return 1; + + sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len); + + txbuf->frame_length = len; + txbuf->opp_flag = 1; /* start transmission */ + + /* Update transmit buffer control fields */ + card->u.c.txbuf = ++txbuf; + + if ((void*)txbuf > card->u.c.txbuf_last) + card->u.c.txbuf = card->u.c.txbuf_base; + + return 0; +} + +/****** Firmware Error Handler **********************************************/ + +/*============================================================================ + * Firmware error handler. + * This routine is called whenever firmware command returns non-zero + * return code. + * + * Return zero if previous command has to be cancelled. + */ +static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb) +{ + unsigned cmd = mb->command; + + switch (err) { + + case CMD_TIMEOUT: + printk(KERN_INFO "%s: command 0x%02X timed out!\n", + card->devname, cmd); + break; + + case S514_BOTH_PORTS_SAME_CLK_MODE: + if(cmd == SET_CHDLC_CONFIGURATION) { + printk(KERN_INFO + "%s: Configure both ports for the same clock source\n", + card->devname); + break; + } + + default: + printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n", + card->devname, cmd, err); + } + + return 0; +} + + +/********** Bottom Half Handlers ********************************************/ + +/* NOTE: There is no API, BH support for Kernels lower than 2.2.X. + * DO NOT INSERT ANY CODE HERE, NOTICE THE + * PREPROCESSOR STATEMENT ABOVE, UNLESS YOU KNOW WHAT YOU ARE + * DOING */ + +static void chdlc_work(struct net_device * dev) +{ + chdlc_private_area_t* chan = dev->priv; + sdla_t *card = chan->card; + struct sk_buff *skb; + + if (atomic_read(&chan->bh_buff_used) == 0){ + clear_bit(0, &chan->tq_working); + return; + } + + while (atomic_read(&chan->bh_buff_used)){ + + skb = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb; + + if (skb != NULL){ + + if (chan->common.sk == NULL || chan->common.func == NULL){ + ++card->wandev.stats.rx_dropped; + dev_kfree_skb_any(skb); + chdlc_work_cleanup(dev); + continue; + } + + if (chan->common.func(skb,dev,chan->common.sk) != 0){ + /* Sock full cannot send, queue us for another + * try */ + atomic_set(&chan->common.receive_block,1); + return; + }else{ + chdlc_work_cleanup(dev); + } + }else{ + chdlc_work_cleanup(dev); + } + } + clear_bit(0, &chan->tq_working); + + return; +} + +static int chdlc_work_cleanup(struct net_device *dev) +{ + chdlc_private_area_t* chan = dev->priv; + + ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL; + + if (chan->bh_read == MAX_BH_BUFF){ + chan->bh_read=0; + }else{ + ++chan->bh_read; + } + + atomic_dec(&chan->bh_buff_used); + return 0; +} + + + +static int bh_enqueue(struct net_device *dev, struct sk_buff *skb) +{ + /* Check for full */ + chdlc_private_area_t* chan = dev->priv; + sdla_t *card = chan->card; + + if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){ + ++card->wandev.stats.rx_dropped; + dev_kfree_skb_any(skb); + return 1; + } + + ((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb; + + if (chan->bh_write == MAX_BH_BUFF){ + chan->bh_write=0; + }else{ + ++chan->bh_write; + } + + atomic_inc(&chan->bh_buff_used); + + return 0; +} + +/* END OF API BH Support */ + + +/****** Interrupt Handlers **************************************************/ + +/*============================================================================ + * Cisco HDLC interrupt service routine. + */ +static void wpc_isr (sdla_t* card) +{ + struct net_device* dev; + SHARED_MEMORY_INFO_STRUCT* flags = NULL; + int i; + sdla_t *my_card; + + + /* Check for which port the interrupt has been generated + * Since Secondary Port is piggybacking on the Primary + * the check must be done here. + */ + + flags = card->u.c.flags; + if (!flags->interrupt_info_struct.interrupt_type){ + /* Check for a second port (piggybacking) */ + if ((my_card = card->next)){ + flags = my_card->u.c.flags; + if (flags->interrupt_info_struct.interrupt_type){ + card = my_card; + card->isr(card); + return; + } + } + } + + flags = card->u.c.flags; + card->in_isr = 1; + dev = card->wandev.dev; + + /* If we get an interrupt with no network device, stop the interrupts + * and issue an error */ + if (!card->tty_opt && !dev && + flags->interrupt_info_struct.interrupt_type != + COMMAND_COMPLETE_APP_INT_PEND){ + + goto isr_done; + } + + /* if critical due to peripheral operations + * ie. update() or getstats() then reset the interrupt and + * wait for the board to retrigger. + */ + if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) { + printk(KERN_INFO "ISR CRIT TO PERI\n"); + goto isr_done; + } + + /* On a 508 Card, if critical due to if_send + * Major Error !!! */ + if(card->hw.type != SDLA_S514) { + if(test_bit(SEND_CRIT, (void*)&card->wandev.critical)) { + printk(KERN_INFO "%s: Critical while in ISR: %lx\n", + card->devname, card->wandev.critical); + card->in_isr = 0; + flags->interrupt_info_struct.interrupt_type = 0; + return; + } + } + + switch(flags->interrupt_info_struct.interrupt_type) { + + case RX_APP_INT_PEND: /* 0x01: receive interrupt */ + rx_intr(card); + break; + + case TX_APP_INT_PEND: /* 0x02: transmit interrupt */ + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TX_FRAME; + + if (card->tty_opt){ + wanpipe_tty_trigger_poll(card); + break; + } + + if (dev && netif_queue_stopped(dev)){ + if (card->u.c.usedby == API){ + netif_start_queue(dev); + wakeup_sk_bh(dev); + }else{ + netif_wake_queue(dev); + } + } + break; + + case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */ + ++ Intr_test_counter; + break; + + case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */ + process_chdlc_exception(card); + break; + + case GLOBAL_EXCEP_COND_APP_INT_PEND: + process_global_exception(card); + break; + + case TIMER_APP_INT_PEND: + timer_intr(card); + break; + + default: + printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", + card->devname, + flags->interrupt_info_struct.interrupt_type); + printk(KERN_INFO "Code name: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codename[i]); + printk(KERN_INFO "\nCode version: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codeversion[i]); + printk(KERN_INFO "\n"); + break; + } + +isr_done: + + card->in_isr = 0; + flags->interrupt_info_struct.interrupt_type = 0; + return; +} + +/*============================================================================ + * Receive interrupt handler. + */ +static void rx_intr (sdla_t* card) +{ + struct net_device *dev; + chdlc_private_area_t *chdlc_priv_area; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb; + struct sk_buff *skb; + unsigned len; + unsigned addr = rxbuf->ptr_data_bfr; + void *buf; + int i,udp_type; + + if (rxbuf->opp_flag != 0x01) { + printk(KERN_INFO + "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", + card->devname, (unsigned)rxbuf, rxbuf->opp_flag); + printk(KERN_INFO "Code name: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codename[i]); + printk(KERN_INFO "\nCode version: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codeversion[i]); + printk(KERN_INFO "\n"); + + + /* Bug Fix: Mar 6 2000 + * If we get a corrupted mailbox, it measn that driver + * is out of sync with the firmware. There is no recovery. + * If we don't turn off all interrupts for this card + * the machine will crash. + */ + printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname); + printk(KERN_INFO "Please contact Sangoma Technologies !\n"); + chdlc_set_intr_mode(card,0); + return; + } + + len = rxbuf->frame_length; + + if (card->tty_opt){ + + if (rxbuf->error_flag){ + goto rx_exit; + } + + if (len <= CRC_LENGTH){ + goto rx_exit; + } + + if (!card->u.c.async_mode){ + len -= CRC_LENGTH; + } + + wanpipe_tty_receive(card,addr,len); + goto rx_exit; + } + + dev = card->wandev.dev; + + if (!dev){ + goto rx_exit; + } + + if (!netif_running(dev)) + goto rx_exit; + + chdlc_priv_area = dev->priv; + + + /* Allocate socket buffer */ + skb = dev_alloc_skb(len); + + if (skb == NULL) { + printk(KERN_INFO "%s: no socket buffers available!\n", + card->devname); + ++card->wandev.stats.rx_dropped; + goto rx_exit; + } + + /* Copy data to the socket buffer */ + if((addr + len) > card->u.c.rx_top + 1) { + unsigned tmp = card->u.c.rx_top - addr + 1; + buf = skb_put(skb, tmp); + sdla_peek(&card->hw, addr, buf, tmp); + addr = card->u.c.rx_base; + len -= tmp; + } + + buf = skb_put(skb, len); + sdla_peek(&card->hw, addr, buf, len); + + skb->protocol = htons(ETH_P_IP); + + card->wandev.stats.rx_packets ++; + card->wandev.stats.rx_bytes += skb->len; + udp_type = udp_pkt_type( skb, card ); + + if(udp_type == UDP_CPIPE_TYPE) { + if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, + card, skb, dev, chdlc_priv_area)) { + flags->interrupt_info_struct. + interrupt_permission |= + APP_INT_ON_TIMER; + } + } else if(card->u.c.usedby == API) { + + api_rx_hdr_t* api_rx_hdr; + skb_push(skb, sizeof(api_rx_hdr_t)); + api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00]; + api_rx_hdr->error_flag = rxbuf->error_flag; + api_rx_hdr->time_stamp = rxbuf->time_stamp; + + skb->protocol = htons(PVC_PROT); + skb->mac.raw = skb->data; + skb->dev = dev; + skb->pkt_type = WAN_PACKET_DATA; + + bh_enqueue(dev, skb); + + if (!test_and_set_bit(0,&chdlc_priv_area->tq_working)) + wanpipe_queue_work(&chdlc_priv_area->common.wanpipe_work); + }else{ + /* FIXME: we should check to see if the received packet is a + multicast packet so that we can increment the multicast + statistic + ++ chdlc_priv_area->if_stats.multicast; + */ + /* Pass it up the protocol stack */ + + skb->dev = dev; + skb->mac.raw = skb->data; + netif_rx(skb); + dev->last_rx = jiffies; + } + +rx_exit: + /* Release buffer element and calculate a pointer to the next one */ + rxbuf->opp_flag = 0x00; + card->u.c.rxmb = ++ rxbuf; + if((void*)rxbuf > card->u.c.rxbuf_last){ + card->u.c.rxmb = card->u.c.rxbuf_base; + } +} + +/*============================================================================ + * Timer interrupt handler. + * The timer interrupt is used for two purposes: + * 1) Processing udp calls from 'cpipemon'. + * 2) Reading board-level statistics for updating the proc file system. + */ +void timer_intr(sdla_t *card) +{ + struct net_device* dev; + chdlc_private_area_t* chdlc_priv_area = NULL; + SHARED_MEMORY_INFO_STRUCT* flags = NULL; + + if ((dev = card->wandev.dev)==NULL){ + flags = card->u.c.flags; + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TIMER; + return; + } + + chdlc_priv_area = dev->priv; + + if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) { + if (!config_chdlc(card)){ + chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG; + } + } + + /* process a udp call if pending */ + if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) { + process_udp_mgmt_pkt(card, dev, + chdlc_priv_area); + chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP; + } + + /* read the communications statistics if required */ + if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) { + update_comms_stats(card, chdlc_priv_area); + if(!(-- chdlc_priv_area->update_comms_stats)) { + chdlc_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + } + } + + /* only disable the timer interrupt if there are no udp or statistic */ + /* updates pending */ + if(!chdlc_priv_area->timer_int_enabled) { + flags = card->u.c.flags; + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TIMER; + } +} + +/*------------------------------------------------------------------------------ + Miscellaneous Functions + - set_chdlc_config() used to set configuration options on the board +------------------------------------------------------------------------------*/ + +static int set_chdlc_config(sdla_t* card) +{ + CHDLC_CONFIGURATION_STRUCT cfg; + + memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT)); + + if(card->wandev.clocking){ + cfg.baud_rate = card->wandev.bps; + } + + cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; + + cfg.modem_config_options = 0; + cfg.modem_status_timer = 100; + + cfg.CHDLC_protocol_options = card->u.c.protocol_options; + + if (card->tty_opt){ + cfg.CHDLC_API_options = DISCARD_RX_ERROR_FRAMES; + } + + cfg.percent_data_buffer_for_Tx = (card->u.c.receive_only) ? 0 : 50; + cfg.CHDLC_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT | + CHDLC_RX_DATA_BYTE_COUNT_STAT); + + if (card->tty_opt){ + card->wandev.mtu = TTY_CHDLC_MAX_MTU; + } + cfg.max_CHDLC_data_field_length = card->wandev.mtu; + cfg.transmit_keepalive_timer = card->u.c.kpalv_tx; + cfg.receive_keepalive_timer = card->u.c.kpalv_rx; + cfg.keepalive_error_tolerance = card->u.c.kpalv_err; + cfg.SLARP_request_timer = card->u.c.slarp_timer; + + if (cfg.SLARP_request_timer) { + cfg.IP_address = 0; + cfg.IP_netmask = 0; + + }else if (card->wandev.dev){ + struct net_device *dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area = dev->priv; + + struct in_device *in_dev = dev->ip_ptr; + + if(in_dev != NULL) { + struct in_ifaddr *ifa = in_dev->ifa_list; + + if (ifa != NULL ) { + cfg.IP_address = ntohl(ifa->ifa_local); + cfg.IP_netmask = ntohl(ifa->ifa_mask); + chdlc_priv_area->IP_address = ntohl(ifa->ifa_local); + chdlc_priv_area->IP_netmask = ntohl(ifa->ifa_mask); + } + } + + /* FIXME: We must re-think this message in next release + if((cfg.IP_address & 0x000000FF) > 2) { + printk(KERN_WARNING "\n"); + printk(KERN_WARNING " WARNING:%s configured with an\n", + card->devname); + printk(KERN_WARNING " invalid local IP address.\n"); + printk(KERN_WARNING " Slarp pragmatics will fail.\n"); + printk(KERN_WARNING " IP address should be of the\n"); + printk(KERN_WARNING " format A.B.C.1 or A.B.C.2.\n"); + } + */ + } + + return chdlc_configure(card, &cfg); +} + + +/*----------------------------------------------------------------------------- + set_asy_config() used to set asynchronous configuration options on the board +------------------------------------------------------------------------------*/ + +static int set_asy_config(sdla_t* card) +{ + + ASY_CONFIGURATION_STRUCT cfg; + CHDLC_MAILBOX_STRUCT *mailbox = card->mbox; + int err; + + memset(&cfg, 0, sizeof(ASY_CONFIGURATION_STRUCT)); + + if(card->wandev.clocking) + cfg.baud_rate = card->wandev.bps; + + cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; + + cfg.modem_config_options = 0; + cfg.asy_API_options = card->u.c.api_options; + cfg.asy_protocol_options = card->u.c.protocol_options; + cfg.Tx_bits_per_char = card->u.c.tx_bits_per_char; + cfg.Rx_bits_per_char = card->u.c.rx_bits_per_char; + cfg.stop_bits = card->u.c.stop_bits; + cfg.parity = card->u.c.parity; + cfg.break_timer = card->u.c.break_timer; + cfg.asy_Rx_inter_char_timer = card->u.c.inter_char_timer; + cfg.asy_Rx_complete_length = card->u.c.rx_complete_length; + cfg.XON_char = card->u.c.xon_char; + cfg.XOFF_char = card->u.c.xoff_char; + cfg.asy_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT | + CHDLC_RX_DATA_BYTE_COUNT_STAT); + + mailbox->buffer_length = sizeof(ASY_CONFIGURATION_STRUCT); + memcpy(mailbox->data, &cfg, mailbox->buffer_length); + mailbox->command = SET_ASY_CONFIGURATION; + err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error (card, err, mailbox); + return err; +} + +/*============================================================================ + * Enable asynchronous communications. + */ + +static int asy_comm_enable (sdla_t* card) +{ + + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = ENABLE_ASY_COMMUNICATIONS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK && card->wandev.dev) + chdlc_error(card, err, mb); + + if (!err) + card->u.c.comm_enabled = 1; + + return err; +} + +/*============================================================================ + * Process global exception condition + */ +static int process_global_exception(sdla_t *card) +{ + CHDLC_MAILBOX_STRUCT* mbox = card->mbox; + int err; + + mbox->buffer_length = 0; + mbox->command = READ_GLOBAL_EXCEPTION_CONDITION; + err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT; + + if(err != CMD_TIMEOUT ){ + + switch(mbox->return_code) { + + case EXCEP_MODEM_STATUS_CHANGE: + + printk(KERN_INFO "%s: Modem status change\n", + card->devname); + + switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) { + case (DCD_HIGH): + printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname); + break; + case (CTS_HIGH): + printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname); + break; + case ((DCD_HIGH | CTS_HIGH)): + printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname); + break; + default: + printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname); + break; + } + break; + + case EXCEP_TRC_DISABLED: + printk(KERN_INFO "%s: Line trace disabled\n", + card->devname); + break; + + case EXCEP_IRQ_TIMEOUT: + printk(KERN_INFO "%s: IRQ timeout occurred\n", + card->devname); + break; + + case 0x17: + if (card->tty_opt){ + if (card->tty && card->tty_open){ + printk(KERN_INFO + "%s: Modem Hangup Exception: Hanging Up!\n", + card->devname); + tty_hangup(card->tty); + } + break; + } + + /* If TTY is not used just drop throught */ + + default: + printk(KERN_INFO "%s: Global exception %x\n", + card->devname, mbox->return_code); + break; + } + } + return 0; +} + + +/*============================================================================ + * Process chdlc exception condition + */ +static int process_chdlc_exception(sdla_t *card) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int err; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_EXCEPTION_CONDITION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if(err != CMD_TIMEOUT) { + + switch (err) { + + case EXCEP_LINK_ACTIVE: + port_set_state(card, WAN_CONNECTED); + trigger_chdlc_poll(card->wandev.dev); + break; + + case EXCEP_LINK_INACTIVE_MODEM: + port_set_state(card, WAN_DISCONNECTED); + unconfigure_ip(card); + trigger_chdlc_poll(card->wandev.dev); + break; + + case EXCEP_LINK_INACTIVE_KPALV: + port_set_state(card, WAN_DISCONNECTED); + printk(KERN_INFO "%s: Keepalive timer expired.\n", + card->devname); + unconfigure_ip(card); + trigger_chdlc_poll(card->wandev.dev); + break; + + case EXCEP_IP_ADDRESS_DISCOVERED: + if (configure_ip(card)) + return -1; + break; + + case EXCEP_LOOPBACK_CONDITION: + printk(KERN_INFO "%s: Loopback Condition Detected.\n", + card->devname); + break; + + case NO_CHDLC_EXCEP_COND_TO_REPORT: + printk(KERN_INFO "%s: No exceptions reported.\n", + card->devname); + break; + } + + } + return 0; +} + + +/*============================================================================ + * Configure IP from SLARP negotiation + * This adds dynamic routes when SLARP has provided valid addresses + */ + +static int configure_ip (sdla_t* card) +{ + struct net_device *dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area; + char err; + + if (!dev) + return 0; + + chdlc_priv_area = dev->priv; + + + /* set to discover */ + if(card->u.c.slarp_timer != 0x00) { + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_CONFIGURATION_STRUCT *cfg; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + chdlc_error(card,err,mb); + return -1; + } + + cfg = (CHDLC_CONFIGURATION_STRUCT *)mb->data; + chdlc_priv_area->IP_address = cfg->IP_address; + chdlc_priv_area->IP_netmask = cfg->IP_netmask; + + /* Set flag to add route */ + chdlc_priv_area->route_status = ADD_ROUTE; + + /* The idea here is to add the route in the poll routine. + This way, we aren't in interrupt context when adding routes */ + trigger_chdlc_poll(dev); + } + + return 0; +} + + +/*============================================================================ + * Un-Configure IP negotiated by SLARP + * This removes dynamic routes when the link becomes inactive. + */ + +static int unconfigure_ip (sdla_t* card) +{ + struct net_device *dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area; + + if (!dev) + return 0; + + chdlc_priv_area= dev->priv; + + if (chdlc_priv_area->route_status == ROUTE_ADDED) { + + /* Note: If this function is called, the + * port state has been DISCONNECTED. This state + * change will trigger a poll_disconnected + * function, that will check for this condition. + */ + chdlc_priv_area->route_status = REMOVE_ROUTE; + + } + return 0; +} + +/*============================================================================ + * Routine to add/remove routes + * Called like a polling routine when Routes are flagged to be added/removed. + */ + +static void process_route (sdla_t *card) +{ + struct net_device *dev = card->wandev.dev; + unsigned char port_num; + chdlc_private_area_t *chdlc_priv_area = NULL; + u32 local_IP_addr = 0; + u32 remote_IP_addr = 0; + u32 IP_netmask, IP_addr; + int err = 0; + struct in_device *in_dev; + mm_segment_t fs; + struct ifreq if_info; + struct sockaddr_in *if_data1, *if_data2; + + chdlc_priv_area = dev->priv; + port_num = card->u.c.comm_port; + + /* Bug Fix Mar 16 2000 + * AND the IP address to the Mask before checking + * the last two bits. */ + + if((chdlc_priv_area->route_status == ADD_ROUTE) && + ((chdlc_priv_area->IP_address & ~chdlc_priv_area->IP_netmask) > 2)) { + + printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname); + + if(card->u.c.slarp_timer) { + u32 addr_net = htonl(chdlc_priv_area->IP_address); + + printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u received\n", + card->devname, + NIPQUAD(addr_net)); + printk(KERN_INFO "%s: from remote station.\n", + card->devname); + + }else{ + u32 addr_net = htonl(chdlc_priv_area->IP_address); + + printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u issued\n", + card->devname, + NIPQUAD(addr_net)); + printk(KERN_INFO "%s: to remote station. Local\n", + card->devname); + printk(KERN_INFO "%s: IP address must be A.B.C.1\n", + card->devname); + printk(KERN_INFO "%s: or A.B.C.2.\n",card->devname); + } + + /* remove the route due to the IP address error condition */ + chdlc_priv_area->route_status = REMOVE_ROUTE; + err = 1; + } + + /* If we are removing a route with bad IP addressing, then use the */ + /* locally configured IP addresses */ + if((chdlc_priv_area->route_status == REMOVE_ROUTE) && err) { + + /* do not remove a bad route that has already been removed */ + if(chdlc_priv_area->route_removed) { + return; + } + + in_dev = dev->ip_ptr; + + if(in_dev != NULL) { + struct in_ifaddr *ifa = in_dev->ifa_list; + if (ifa != NULL ) { + local_IP_addr = ifa->ifa_local; + IP_netmask = ifa->ifa_mask; + } + } + }else{ + /* According to Cisco HDLC, if the point-to-point address is + A.B.C.1, then we are the opposite (A.B.C.2), and vice-versa. + */ + IP_netmask = ntohl(chdlc_priv_area->IP_netmask); + remote_IP_addr = ntohl(chdlc_priv_area->IP_address); + + + /* If Netmask is 255.255.255.255 the local address + * calculation will fail. Default it back to 255.255.255.0 */ + if (IP_netmask == 0xffffffff) + IP_netmask &= 0x00ffffff; + + /* Bug Fix Mar 16 2000 + * AND the Remote IP address with IP netmask, instead + * of static netmask of 255.255.255.0 */ + local_IP_addr = (remote_IP_addr & IP_netmask) + + (~remote_IP_addr & ntohl(0x0003)); + + if(!card->u.c.slarp_timer) { + IP_addr = local_IP_addr; + local_IP_addr = remote_IP_addr; + remote_IP_addr = IP_addr; + } + } + + fs = get_fs(); /* Save file system */ + set_fs(get_ds()); /* Get user space block */ + + /* Setup a structure for adding/removing routes */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + switch (chdlc_priv_area->route_status) { + + case ADD_ROUTE: + + if(!card->u.c.slarp_timer) { + if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data2->sin_addr.s_addr = remote_IP_addr; + if_data2->sin_family = AF_INET; + err = devinet_ioctl(SIOCSIFDSTADDR, &if_info); + } else { + if_data1 = (struct sockaddr_in *)&if_info.ifr_addr; + if_data1->sin_addr.s_addr = local_IP_addr; + if_data1->sin_family = AF_INET; + if(!(err = devinet_ioctl(SIOCSIFADDR, &if_info))){ + if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data2->sin_addr.s_addr = remote_IP_addr; + if_data2->sin_family = AF_INET; + err = devinet_ioctl(SIOCSIFDSTADDR, &if_info); + } + } + + if(err) { + printk(KERN_INFO "%s: Add route %u.%u.%u.%u failed (%d)\n", + card->devname, NIPQUAD(remote_IP_addr), err); + } else { + ((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED; + printk(KERN_INFO "%s: Dynamic route added.\n", + card->devname); + printk(KERN_INFO "%s: Local IP addr : %u.%u.%u.%u\n", + card->devname, NIPQUAD(local_IP_addr)); + printk(KERN_INFO "%s: Remote IP addr: %u.%u.%u.%u\n", + card->devname, NIPQUAD(remote_IP_addr)); + chdlc_priv_area->route_removed = 0; + } + break; + + + case REMOVE_ROUTE: + + /* Change the local ip address of the interface to 0. + * This will also delete the destination route. + */ + if(!card->u.c.slarp_timer) { + if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data2->sin_addr.s_addr = 0; + if_data2->sin_family = AF_INET; + err = devinet_ioctl(SIOCSIFDSTADDR, &if_info); + } else { + if_data1 = (struct sockaddr_in *)&if_info.ifr_addr; + if_data1->sin_addr.s_addr = 0; + if_data1->sin_family = AF_INET; + err = devinet_ioctl(SIOCSIFADDR,&if_info); + + } + if(err) { + printk(KERN_INFO + "%s: Remove route %u.%u.%u.%u failed, (err %d)\n", + card->devname, NIPQUAD(remote_IP_addr), + err); + } else { + ((chdlc_private_area_t *)dev->priv)->route_status = + NO_ROUTE; + printk(KERN_INFO "%s: Dynamic route removed: %u.%u.%u.%u\n", + card->devname, NIPQUAD(local_IP_addr)); + chdlc_priv_area->route_removed = 1; + } + break; + } + + set_fs(fs); /* Restore file system */ + +} + + +/*============================================================================= + * Store a UDP management packet for later processing. + */ + +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area) +{ + int udp_pkt_stored = 0; + + if(!chdlc_priv_area->udp_pkt_lgth && + (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) { + chdlc_priv_area->udp_pkt_lgth = skb->len; + chdlc_priv_area->udp_pkt_src = udp_pkt_src; + memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len); + chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP; + udp_pkt_stored = 1; + } + + if(udp_pkt_src == UDP_PKT_FRM_STACK){ + dev_kfree_skb_any(skb); + }else{ + dev_kfree_skb_any(skb); + } + + return(udp_pkt_stored); +} + + +/*============================================================================= + * Process UDP management packet. + */ + +static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area ) +{ + unsigned char *buf; + unsigned int frames, len; + struct sk_buff *new_skb; + unsigned short buffer_length, real_len; + unsigned long data_ptr; + unsigned data_length; + int udp_mgmt_req_valid = 1; + CHDLC_MAILBOX_STRUCT *mb = card->mbox; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + chdlc_udp_pkt_t *chdlc_udp_pkt; + struct timeval tv; + int err; + char ut_char; + + chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data; + + if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){ + + /* Only these commands are support for remote debugging. + * All others are not */ + switch(chdlc_udp_pkt->cblock.command) { + + case READ_GLOBAL_STATISTICS: + case READ_MODEM_STATUS: + case READ_CHDLC_LINK_STATUS: + case CPIPE_ROUTER_UP_TIME: + case READ_COMMS_ERROR_STATS: + case READ_CHDLC_OPERATIONAL_STATS: + + /* These two commands are executed for + * each request */ + case READ_CHDLC_CONFIGURATION: + case READ_CHDLC_CODE_VERSION: + udp_mgmt_req_valid = 1; + break; + default: + udp_mgmt_req_valid = 0; + break; + } + } + + if(!udp_mgmt_req_valid) { + + /* set length to 0 */ + chdlc_udp_pkt->cblock.buffer_length = 0; + + /* set return code */ + chdlc_udp_pkt->cblock.return_code = 0xCD; + + if (net_ratelimit()){ + printk(KERN_INFO + "%s: Warning, Illegal UDP command attempted from network: %x\n", + card->devname,chdlc_udp_pkt->cblock.command); + } + + } else { + unsigned long trace_status_cfg_addr = 0; + TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct; + TRACE_STATUS_ELEMENT_STRUCT trace_element_struct; + + switch(chdlc_udp_pkt->cblock.command) { + + case CPIPE_ENABLE_TRACING: + if (!chdlc_priv_area->TracingEnabled) { + + /* OPERATE_DATALINE_MONITOR */ + + mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT); + mb->command = SET_TRACE_CONFIGURATION; + + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_config = TRACE_ACTIVE; + /* Trace delay mode is not used because it slows + down transfer and results in a standoff situation + when there is a lot of data */ + + /* Configure the Trace based on user inputs */ + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= + chdlc_udp_pkt->data[0]; + + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_deactivation_timer = 4000; + + + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) { + chdlc_error(card,err,mb); + card->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = err; + mb->buffer_length = 0; + break; + } + + /* Get the base address of the trace element list */ + mb->buffer_length = 0; + mb->command = READ_TRACE_CONFIGURATION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if (err != COMMAND_OK) { + chdlc_error(card,err,mb); + chdlc_priv_area->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = err; + mb->buffer_length = 0; + break; + } + + trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *) + mb->data) -> ptr_trace_stat_el_cfg_struct; + + sdla_peek(&card->hw, trace_status_cfg_addr, + &trace_cfg_struct, sizeof(trace_cfg_struct)); + + chdlc_priv_area->start_trace_addr = trace_cfg_struct. + base_addr_trace_status_elements; + + chdlc_priv_area->number_trace_elements = + trace_cfg_struct.number_trace_status_elements; + + chdlc_priv_area->end_trace_addr = (unsigned long) + ((TRACE_STATUS_ELEMENT_STRUCT *) + chdlc_priv_area->start_trace_addr + + (chdlc_priv_area->number_trace_elements - 1)); + + chdlc_priv_area->base_addr_trace_buffer = + trace_cfg_struct.base_addr_trace_buffer; + + chdlc_priv_area->end_addr_trace_buffer = + trace_cfg_struct.end_addr_trace_buffer; + + chdlc_priv_area->curr_trace_addr = + trace_cfg_struct.next_trace_element_to_use; + + chdlc_priv_area->available_buffer_space = 2000 - + sizeof(ip_pkt_t) - + sizeof(udp_pkt_t) - + sizeof(wp_mgmt_t) - + sizeof(cblock_t) - + sizeof(trace_info_t); + } + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + mb->buffer_length = 0; + chdlc_priv_area->TracingEnabled = 1; + break; + + + case CPIPE_DISABLE_TRACING: + if (chdlc_priv_area->TracingEnabled) { + + /* OPERATE_DATALINE_MONITOR */ + mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT); + mb->command = SET_TRACE_CONFIGURATION; + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_config = TRACE_INACTIVE; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + } + + chdlc_priv_area->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + mb->buffer_length = 0; + break; + + + case CPIPE_GET_TRACE_INFO: + + if (!chdlc_priv_area->TracingEnabled) { + chdlc_udp_pkt->cblock.return_code = 1; + mb->buffer_length = 0; + break; + } + + chdlc_udp_pkt->trace_info.ismoredata = 0x00; + buffer_length = 0; /* offset of packet already occupied */ + + for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){ + + trace_pkt_t *trace_pkt = (trace_pkt_t *) + &chdlc_udp_pkt->data[buffer_length]; + + sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr, + (unsigned char *)&trace_element_struct, + sizeof(TRACE_STATUS_ELEMENT_STRUCT)); + + if (trace_element_struct.opp_flag == 0x00) { + break; + } + + /* get pointer to real data */ + data_ptr = trace_element_struct.ptr_data_bfr; + + /* See if there is actual data on the trace buffer */ + if (data_ptr){ + data_length = trace_element_struct.trace_length; + }else{ + data_length = 0; + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + } + + if( (chdlc_priv_area->available_buffer_space - buffer_length) + < ( sizeof(trace_pkt_t) + data_length) ) { + + /* indicate there are more frames on board & exit */ + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + break; + } + + trace_pkt->status = trace_element_struct.trace_type; + + trace_pkt->time_stamp = + trace_element_struct.trace_time_stamp; + + trace_pkt->real_length = + trace_element_struct.trace_length; + + /* see if we can fit the frame into the user buffer */ + real_len = trace_pkt->real_length; + + if (data_ptr == 0) { + trace_pkt->data_avail = 0x00; + } else { + unsigned tmp = 0; + + /* get the data from circular buffer + must check for end of buffer */ + trace_pkt->data_avail = 0x01; + + if ((data_ptr + real_len) > + chdlc_priv_area->end_addr_trace_buffer + 1){ + + tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1; + sdla_peek(&card->hw, data_ptr, + trace_pkt->data,tmp); + data_ptr = chdlc_priv_area->base_addr_trace_buffer; + } + + sdla_peek(&card->hw, data_ptr, + &trace_pkt->data[tmp], real_len - tmp); + } + + /* zero the opp flag to show we got the frame */ + ut_char = 0x00; + sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1); + + /* now move onto the next frame */ + chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT); + + /* check if we went over the last address */ + if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) { + chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr; + } + + if(trace_pkt->data_avail == 0x01) { + buffer_length += real_len - 1; + } + + /* for the header */ + buffer_length += sizeof(trace_pkt_t); + + } /* For Loop */ + + if (frames == chdlc_priv_area->number_trace_elements){ + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + } + chdlc_udp_pkt->trace_info.num_frames = frames; + + mb->buffer_length = buffer_length; + chdlc_udp_pkt->cblock.buffer_length = buffer_length; + + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + + break; + + + case CPIPE_FT1_READ_STATUS: + ((unsigned char *)chdlc_udp_pkt->data )[0] = + flags->FT1_info_struct.parallel_port_A_input; + + ((unsigned char *)chdlc_udp_pkt->data )[1] = + flags->FT1_info_struct.parallel_port_B_input; + + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + chdlc_udp_pkt->cblock.buffer_length = 2; + mb->buffer_length = 2; + break; + + case CPIPE_ROUTER_UP_TIME: + do_gettimeofday( &tv ); + chdlc_priv_area->router_up_time = tv.tv_sec - + chdlc_priv_area->router_start_time; + *(unsigned long *)&chdlc_udp_pkt->data = + chdlc_priv_area->router_up_time; + mb->buffer_length = sizeof(unsigned long); + chdlc_udp_pkt->cblock.buffer_length = sizeof(unsigned long); + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + break; + + case FT1_MONITOR_STATUS_CTRL: + /* Enable FT1 MONITOR STATUS */ + if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) || + (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) { + + if( rCount++ != 0 ) { + chdlc_udp_pkt->cblock. + return_code = COMMAND_OK; + mb->buffer_length = 1; + break; + } + } + + /* Disable FT1 MONITOR STATUS */ + if( chdlc_udp_pkt->data[0] == 0) { + + if( --rCount != 0) { + chdlc_udp_pkt->cblock. + return_code = COMMAND_OK; + mb->buffer_length = 1; + break; + } + } + goto dflt_1; + + default: +dflt_1: + /* it's a board command */ + mb->command = chdlc_udp_pkt->cblock.command; + mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length; + if (mb->buffer_length) { + memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt-> + data, mb->buffer_length); + } + /* run the command on the board */ + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) { + break; + } + + /* copy the result back to our buffer */ + memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t)); + + if (mb->buffer_length) { + memcpy(&chdlc_udp_pkt->data, &mb->data, + mb->buffer_length); + } + + } /* end of switch */ + } /* end of else */ + + /* Fill UDP TTL */ + chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl; + + len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length); + + + if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){ + + /* Must check if we interrupted if_send() routine. The + * tx buffers might be used. If so drop the packet */ + if (!test_bit(SEND_CRIT,&card->wandev.critical)) { + + if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) { + ++ card->wandev.stats.tx_packets; + card->wandev.stats.tx_bytes += len; + } + } + } else { + + /* Pass it up the stack + Allocate socket buffer */ + if ((new_skb = dev_alloc_skb(len)) != NULL) { + /* copy data into new_skb */ + + buf = skb_put(new_skb, len); + memcpy(buf, chdlc_priv_area->udp_pkt_data, len); + + /* Decapsulate pkt and pass it up the protocol stack */ + new_skb->protocol = htons(ETH_P_IP); + new_skb->dev = dev; + new_skb->mac.raw = new_skb->data; + + netif_rx(new_skb); + dev->last_rx = jiffies; + } else { + + printk(KERN_INFO "%s: no socket buffers available!\n", + card->devname); + } + } + + chdlc_priv_area->udp_pkt_lgth = 0; + + return 0; +} + +/*============================================================================ + * Initialize Receive and Transmit Buffers. + */ + +static void init_chdlc_tx_rx_buff( sdla_t* card) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config; + CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config; + char err; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + if (card->wandev.dev){ + chdlc_error(card,err,mb); + } + return; + } + + if(card->hw.type == SDLA_S514) { + tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Tx_stat_el_cfg_struct)); + rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Rx_stat_el_cfg_struct)); + + /* Setup Head and Tails for buffers */ + card->u.c.txbuf_base = (void *)(card->hw.dpmbase + + tx_config->base_addr_Tx_status_elements); + card->u.c.txbuf_last = + (CHDLC_DATA_TX_STATUS_EL_STRUCT *) + card->u.c.txbuf_base + + (tx_config->number_Tx_status_elements - 1); + + card->u.c.rxbuf_base = (void *)(card->hw.dpmbase + + rx_config->base_addr_Rx_status_elements); + card->u.c.rxbuf_last = + (CHDLC_DATA_RX_STATUS_EL_STRUCT *) + card->u.c.rxbuf_base + + (rx_config->number_Rx_status_elements - 1); + + /* Set up next pointer to be used */ + card->u.c.txbuf = (void *)(card->hw.dpmbase + + tx_config->next_Tx_status_element_to_use); + card->u.c.rxmb = (void *)(card->hw.dpmbase + + rx_config->next_Rx_status_element_to_use); + } + else { + tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE)); + + rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE)); + + /* Setup Head and Tails for buffers */ + card->u.c.txbuf_base = (void *)(card->hw.dpmbase + + (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE)); + card->u.c.txbuf_last = + (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base + + (tx_config->number_Tx_status_elements - 1); + card->u.c.rxbuf_base = (void *)(card->hw.dpmbase + + (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE)); + card->u.c.rxbuf_last = + (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base + + (rx_config->number_Rx_status_elements - 1); + + /* Set up next pointer to be used */ + card->u.c.txbuf = (void *)(card->hw.dpmbase + + (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE)); + card->u.c.rxmb = (void *)(card->hw.dpmbase + + (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE)); + } + + /* Setup Actual Buffer Start and end addresses */ + card->u.c.rx_base = rx_config->base_addr_Rx_buffer; + card->u.c.rx_top = rx_config->end_addr_Rx_buffer; + +} + +/*============================================================================= + * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR + * _TEST_COUNTER times. + */ +static int intr_test( sdla_t* card) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int err,i; + + Intr_test_counter = 0; + + err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE); + + if (err == CMD_OK) { + for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) { + mb->buffer_length = 0; + mb->command = READ_CHDLC_CODE_VERSION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != CMD_OK) + chdlc_error(card, err, mb); + } + } + else { + return err; + } + + err = chdlc_set_intr_mode(card, 0); + + if (err != CMD_OK) + return err; + + return 0; +} + +/*============================================================================== + * Determine what type of UDP call it is. CPIPEAB ? + */ +static int udp_pkt_type(struct sk_buff *skb, sdla_t* card) +{ + chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data; + +#ifdef _WAN_UDP_DEBUG + printk(KERN_INFO "SIG %s = %s\n\ + UPP %x = %x\n\ + PRT %x = %x\n\ + REQ %i = %i\n\ + 36 th = %x 37th = %x\n", + chdlc_udp_pkt->wp_mgmt.signature, + UDPMGMT_SIGNATURE, + chdlc_udp_pkt->udp_pkt.udp_dst_port, + ntohs(card->wandev.udp_port), + chdlc_udp_pkt->ip_pkt.protocol, + UDPMGMT_UDP_PROTOCOL, + chdlc_udp_pkt->wp_mgmt.request_reply, + UDPMGMT_REQUEST, + skb->data[36], skb->data[37]); +#endif + + if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) && + (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) && + (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) && + (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) { + + return UDP_CPIPE_TYPE; + + }else{ + return UDP_INVALID_TYPE; + } +} + +/*============================================================================ + * Set PORT state. + */ +static void port_set_state (sdla_t *card, int state) +{ + if (card->u.c.state != state) + { + switch (state) + { + case WAN_CONNECTED: + printk (KERN_INFO "%s: Link connected!\n", + card->devname); + break; + + case WAN_CONNECTING: + printk (KERN_INFO "%s: Link connecting...\n", + card->devname); + break; + + case WAN_DISCONNECTED: + printk (KERN_INFO "%s: Link disconnected!\n", + card->devname); + break; + } + + card->wandev.state = card->u.c.state = state; + if (card->wandev.dev){ + struct net_device *dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area = dev->priv; + chdlc_priv_area->common.state = state; + } + } +} + +/*=========================================================================== + * config_chdlc + * + * Configure the chdlc protocol and enable communications. + * + * The if_open() function binds this function to the poll routine. + * Therefore, this function will run every time the chdlc interface + * is brought up. We cannot run this function from the if_open + * because if_open does not have access to the remote IP address. + * + * If the communications are not enabled, proceed to configure + * the card and enable communications. + * + * If the communications are enabled, it means that the interface + * was shutdown by ether the user or driver. In this case, we + * have to check that the IP addresses have not changed. If + * the IP addresses have changed, we have to reconfigure the firmware + * and update the changed IP addresses. Otherwise, just exit. + * + */ + +static int config_chdlc (sdla_t *card) +{ + struct net_device *dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area = dev->priv; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + + if (card->u.c.comm_enabled){ + + /* Jun 20. 2000: NC + * IP addresses are not used in the API mode */ + + if ((chdlc_priv_area->ip_local_tmp != chdlc_priv_area->ip_local || + chdlc_priv_area->ip_remote_tmp != chdlc_priv_area->ip_remote) && + card->u.c.usedby == WANPIPE) { + + /* The IP addersses have changed, we must + * stop the communications and reconfigure + * the card. Reason: the firmware must know + * the local and remote IP addresses. */ + disable_comm(card); + port_set_state(card, WAN_DISCONNECTED); + printk(KERN_INFO + "%s: IP addresses changed!\n", + card->devname); + printk(KERN_INFO + "%s: Restarting communications ...\n", + card->devname); + }else{ + /* IP addresses are the same and the link is up, + * we don't have to do anything here. Therefore, exit */ + return 0; + } + } + + chdlc_priv_area->ip_local = chdlc_priv_area->ip_local_tmp; + chdlc_priv_area->ip_remote = chdlc_priv_area->ip_remote_tmp; + + + /* Setup the Board for asynchronous mode */ + if (card->u.c.async_mode){ + + if (set_asy_config(card)) { + printk (KERN_INFO "%s: Failed CHDLC Async configuration!\n", + card->devname); + return 0; + } + }else{ + /* Setup the Board for CHDLC */ + if (set_chdlc_config(card)) { + printk (KERN_INFO "%s: Failed CHDLC configuration!\n", + card->devname); + return 0; + } + } + + /* Set interrupt mode and mask */ + if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME | + APP_INT_ON_GLOBAL_EXCEP_COND | + APP_INT_ON_TX_FRAME | + APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){ + printk (KERN_INFO "%s: Failed to set interrupt triggers!\n", + card->devname); + return 0; + } + + + /* Mask the Transmit and Timer interrupt */ + flags->interrupt_info_struct.interrupt_permission &= + ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER); + + /* In TTY mode, receive interrupt will be enabled during + * wanpipe_tty_open() operation */ + if (card->tty_opt){ + flags->interrupt_info_struct.interrupt_permission &= ~APP_INT_ON_RX_FRAME; + } + + /* Enable communications */ + if (card->u.c.async_mode){ + if (asy_comm_enable(card) != 0) { + printk(KERN_INFO "%s: Failed to enable async commnunication!\n", + card->devname); + flags->interrupt_info_struct.interrupt_permission = 0; + card->u.c.comm_enabled=0; + chdlc_set_intr_mode(card,0); + return 0; + } + }else{ + if (chdlc_comm_enable(card) != 0) { + printk(KERN_INFO "%s: Failed to enable chdlc communications!\n", + card->devname); + flags->interrupt_info_struct.interrupt_permission = 0; + card->u.c.comm_enabled=0; + chdlc_set_intr_mode(card,0); + return 0; + } + } + + /* Initialize Rx/Tx buffer control fields */ + init_chdlc_tx_rx_buff(card); + port_set_state(card, WAN_CONNECTING); + return 0; +} + + +/*============================================================ + * chdlc_poll + * + * Rationale: + * We cannot manipulate the routing tables, or + * ip addresses withing the interrupt. Therefore + * we must perform such actons outside an interrupt + * at a later time. + * + * Description: + * CHDLC polling routine, responsible for + * shutting down interfaces upon disconnect + * and adding/removing routes. + * + * Usage: + * This function is executed for each CHDLC + * interface through a tq_schedule bottom half. + * + * trigger_chdlc_poll() function is used to kick + * the chldc_poll routine. + */ + +static void chdlc_poll(struct net_device *dev) +{ + chdlc_private_area_t *chdlc_priv_area; + sdla_t *card; + u8 check_gateway=0; + SHARED_MEMORY_INFO_STRUCT* flags; + + + if (!dev || (chdlc_priv_area=dev->priv) == NULL) + return; + + card = chdlc_priv_area->card; + flags = card->u.c.flags; + + /* (Re)Configuraiton is in progress, stop what you are + * doing and get out */ + if (test_bit(PERI_CRIT,&card->wandev.critical)){ + clear_bit(POLL_CRIT,&card->wandev.critical); + return; + } + + /* if_open() function has triggered the polling routine + * to determine the configured IP addresses. Once the + * addresses are found, trigger the chdlc configuration */ + if (test_bit(0,&chdlc_priv_area->config_chdlc)){ + + chdlc_priv_area->ip_local_tmp = get_ip_address(dev,WAN_LOCAL_IP); + chdlc_priv_area->ip_remote_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP); + + /* Jun 20. 2000 Bug Fix + * Only perform this check in WANPIPE mode, since + * IP addresses are not used in the API mode. */ + + if (chdlc_priv_area->ip_local_tmp == chdlc_priv_area->ip_remote_tmp && + card->u.c.slarp_timer == 0x00 && + !card->u.c.backup && + card->u.c.usedby == WANPIPE){ + + if (++chdlc_priv_area->ip_error > MAX_IP_ERRORS){ + printk(KERN_INFO "\n%s: --- WARNING ---\n", + card->devname); + printk(KERN_INFO + "%s: The local IP address is the same as the\n", + card->devname); + printk(KERN_INFO + "%s: Point-to-Point IP address.\n", + card->devname); + printk(KERN_INFO "%s: --- WARNING ---\n\n", + card->devname); + }else{ + clear_bit(POLL_CRIT,&card->wandev.critical); + chdlc_priv_area->poll_delay_timer.expires = jiffies+HZ; + add_timer(&chdlc_priv_area->poll_delay_timer); + return; + } + } + + clear_bit(0,&chdlc_priv_area->config_chdlc); + clear_bit(POLL_CRIT,&card->wandev.critical); + + chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG; + flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER; + return; + } + /* Dynamic interface implementation, as well as dynamic + * routing. */ + + switch (card->u.c.state){ + + case WAN_DISCONNECTED: + + /* If the dynamic interface configuration is on, and interface + * is up, then bring down the netowrk interface */ + + if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) && + !test_bit(DEV_DOWN, &chdlc_priv_area->interface_down) && + card->wandev.dev->flags & IFF_UP){ + + printk(KERN_INFO "%s: Interface %s down.\n", + card->devname,card->wandev.dev->name); + change_dev_flags(card->wandev.dev,(card->wandev.dev->flags&~IFF_UP)); + set_bit(DEV_DOWN,&chdlc_priv_area->interface_down); + chdlc_priv_area->route_status = NO_ROUTE; + + }else{ + /* We need to check if the local IP address is + * zero. If it is, we shouldn't try to remove it. + */ + + if (card->wandev.dev->flags & IFF_UP && + get_ip_address(card->wandev.dev,WAN_LOCAL_IP) && + chdlc_priv_area->route_status != NO_ROUTE && + card->u.c.slarp_timer){ + + process_route(card); + } + } + break; + + case WAN_CONNECTED: + + /* In SMP machine this code can execute before the interface + * comes up. In this case, we must make sure that we do not + * try to bring up the interface before dev_open() is finished */ + + + /* DEV_DOWN will be set only when we bring down the interface + * for the very first time. This way we know that it was us + * that brought the interface down */ + + if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) && + test_bit(DEV_DOWN, &chdlc_priv_area->interface_down) && + !(card->wandev.dev->flags & IFF_UP)){ + + printk(KERN_INFO "%s: Interface %s up.\n", + card->devname,card->wandev.dev->name); + change_dev_flags(card->wandev.dev,(card->wandev.dev->flags|IFF_UP)); + clear_bit(DEV_DOWN,&chdlc_priv_area->interface_down); + check_gateway=1; + } + + if (chdlc_priv_area->route_status == ADD_ROUTE && + card->u.c.slarp_timer){ + + process_route(card); + check_gateway=1; + } + + if (chdlc_priv_area->gateway && check_gateway) + add_gateway(card,dev); + + break; + } + + clear_bit(POLL_CRIT,&card->wandev.critical); +} + +/*============================================================ + * trigger_chdlc_poll + * + * Description: + * Add a chdlc_poll() work entry into the keventd work queue + * for a specific dlci/interface. This will kick + * the fr_poll() routine at a later time. + * + * Usage: + * Interrupts use this to defer a taks to + * a polling routine. + * + */ +static void trigger_chdlc_poll(struct net_device *dev) +{ + chdlc_private_area_t *chdlc_priv_area; + sdla_t *card; + + if (!dev) + return; + + if ((chdlc_priv_area = dev->priv)==NULL) + return; + + card = chdlc_priv_area->card; + + if (test_and_set_bit(POLL_CRIT,&card->wandev.critical)){ + return; + } + if (test_bit(PERI_CRIT,&card->wandev.critical)){ + return; + } + schedule_work(&chdlc_priv_area->poll_work); +} + + +static void chdlc_poll_delay (unsigned long dev_ptr) +{ + struct net_device *dev = (struct net_device *)dev_ptr; + trigger_chdlc_poll(dev); +} + + +void s508_lock (sdla_t *card, unsigned long *smp_flags) +{ + spin_lock_irqsave(&card->wandev.lock, *smp_flags); + if (card->next){ + spin_lock(&card->next->wandev.lock); + } +} + +void s508_unlock (sdla_t *card, unsigned long *smp_flags) +{ + if (card->next){ + spin_unlock(&card->next->wandev.lock); + } + spin_unlock_irqrestore(&card->wandev.lock, *smp_flags); +} + +//*********** TTY SECTION **************** + +static void wanpipe_tty_trigger_tx_irq(sdla_t *card) +{ + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct; + chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME; +} + +static void wanpipe_tty_trigger_poll(sdla_t *card) +{ + schedule_work(&card->tty_work); +} + +static void tty_poll_work (void* data) +{ + sdla_t *card = (sdla_t*)data; + struct tty_struct *tty; + + if ((tty=card->tty)==NULL) + return; + + tty_wakeup(tty); +#if defined(SERIAL_HAVE_POLL_WAIT) + wake_up_interruptible(&tty->poll_wait); +#endif + return; +} + +static void wanpipe_tty_close(struct tty_struct *tty, struct file * filp) +{ + sdla_t *card; + unsigned long smp_flags; + + if (!tty || !tty->driver_data){ + return; + } + + card = (sdla_t*)tty->driver_data; + + if (!card) + return; + + printk(KERN_INFO "%s: Closing TTY Driver!\n", + card->devname); + + /* Sanity Check */ + if (!card->tty_open) + return; + + wanpipe_close(card); + if (--card->tty_open == 0){ + + lock_adapter_irq(&card->wandev.lock,&smp_flags); + card->tty=NULL; + chdlc_disable_comm_shutdown(card); + unlock_adapter_irq(&card->wandev.lock,&smp_flags); + + kfree(card->tty_buf); + card->tty_buf = NULL; + kfree(card->tty_rx); + card->tty_rx = NULL; + } + return; +} +static int wanpipe_tty_open(struct tty_struct *tty, struct file * filp) +{ + unsigned long smp_flags; + sdla_t *card; + + if (!tty){ + return -ENODEV; + } + + if (!tty->driver_data){ + int port; + port = tty->index; + if ((port < 0) || (port >= NR_PORTS)) + return -ENODEV; + + tty->driver_data = WAN_CARD(port); + if (!tty->driver_data) + return -ENODEV; + } + + card = (sdla_t*)tty->driver_data; + + if (!card){ + lock_adapter_irq(&card->wandev.lock,&smp_flags); + card->tty=NULL; + unlock_adapter_irq(&card->wandev.lock,&smp_flags); + return -ENODEV; + } + + printk(KERN_INFO "%s: Opening TTY Driver!\n", + card->devname); + + if (card->tty_open == 0){ + lock_adapter_irq(&card->wandev.lock,&smp_flags); + card->tty=tty; + unlock_adapter_irq(&card->wandev.lock,&smp_flags); + + if (!card->tty_buf){ + card->tty_buf = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL); + if (!card->tty_buf){ + card->tty_buf=NULL; + card->tty=NULL; + return -ENOMEM; + } + } + + if (!card->tty_rx){ + card->tty_rx = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL); + if (!card->tty_rx){ + /* Free the buffer above */ + kfree(card->tty_buf); + card->tty_buf=NULL; + card->tty=NULL; + return -ENOMEM; + } + } + } + + ++card->tty_open; + wanpipe_open(card); + return 0; +} + +static int wanpipe_tty_write(struct tty_struct * tty, const unsigned char *buf, int count) +{ + unsigned long smp_flags=0; + sdla_t *card=NULL; + + if (!tty){ + dbg_printk(KERN_INFO "NO TTY in Write\n"); + return -ENODEV; + } + + card = (sdla_t *)tty->driver_data; + + if (!card){ + dbg_printk(KERN_INFO "No Card in TTY Write\n"); + return -ENODEV; + } + + if (count > card->wandev.mtu){ + dbg_printk(KERN_INFO "Frame too big in Write %i Max: %i\n", + count,card->wandev.mtu); + return -EINVAL; + } + + if (card->wandev.state != WAN_CONNECTED){ + dbg_printk(KERN_INFO "Card not connected in TTY Write\n"); + return -EINVAL; + } + + /* Lock the 508 Card: SMP is supported */ + if(card->hw.type != SDLA_S514){ + s508_lock(card,&smp_flags); + } + + if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){ + printk(KERN_INFO "%s: Critical in TTY Write\n", + card->devname); + + /* Lock the 508 Card: SMP is supported */ + if(card->hw.type != SDLA_S514) + s508_unlock(card,&smp_flags); + + return -EINVAL; + } + + if (chdlc_send(card,(void*)buf,count)){ + dbg_printk(KERN_INFO "%s: Failed to send, retry later: kernel!\n", + card->devname); + clear_bit(SEND_CRIT,(void*)&card->wandev.critical); + + wanpipe_tty_trigger_tx_irq(card); + + if(card->hw.type != SDLA_S514) + s508_unlock(card,&smp_flags); + return 0; + } + dbg_printk(KERN_INFO "%s: Packet sent OK: %i\n",card->devname,count); + clear_bit(SEND_CRIT,(void*)&card->wandev.critical); + + if(card->hw.type != SDLA_S514) + s508_unlock(card,&smp_flags); + + return count; +} + +static void wanpipe_tty_receive(sdla_t *card, unsigned addr, unsigned int len) +{ + unsigned offset=0; + unsigned olen=len; + char fp=0; + struct tty_struct *tty; + int i; + struct tty_ldisc *ld; + + if (!card->tty_open){ + dbg_printk(KERN_INFO "%s: TTY not open during receive\n", + card->devname); + return; + } + + if ((tty=card->tty) == NULL){ + dbg_printk(KERN_INFO "%s: No TTY on receive\n", + card->devname); + return; + } + + if (!tty->driver_data){ + dbg_printk(KERN_INFO "%s: No Driver Data, or Flip on receive\n", + card->devname); + return; + } + + + if (card->u.c.async_mode){ + if ((tty->flip.count+len) >= TTY_FLIPBUF_SIZE){ + if (net_ratelimit()){ + printk(KERN_INFO + "%s: Received packet size too big: %i bytes, Max: %i!\n", + card->devname,len,TTY_FLIPBUF_SIZE); + } + return; + } + + + if((addr + len) > card->u.c.rx_top + 1) { + offset = card->u.c.rx_top - addr + 1; + + sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, offset); + + addr = card->u.c.rx_base; + len -= offset; + + tty->flip.char_buf_ptr+=offset; + tty->flip.count+=offset; + for (i=0;iflip.flag_buf_ptr = 0; + tty->flip.flag_buf_ptr++; + } + } + + sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, len); + + tty->flip.char_buf_ptr+=len; + card->tty->flip.count+=len; + for (i=0;iflip.flag_buf_ptr = 0; + tty->flip.flag_buf_ptr++; + } + + tty->low_latency=1; + tty_flip_buffer_push(tty); + }else{ + if (!card->tty_rx){ + if (net_ratelimit()){ + printk(KERN_INFO + "%s: Receive sync buffer not available!\n", + card->devname); + } + return; + } + + if (len > TTY_CHDLC_MAX_MTU){ + if (net_ratelimit()){ + printk(KERN_INFO + "%s: Received packet size too big: %i bytes, Max: %i!\n", + card->devname,len,TTY_FLIPBUF_SIZE); + } + return; + } + + + if((addr + len) > card->u.c.rx_top + 1) { + offset = card->u.c.rx_top - addr + 1; + + sdla_peek(&card->hw, addr, card->tty_rx, offset); + + addr = card->u.c.rx_base; + len -= offset; + } + sdla_peek(&card->hw, addr, card->tty_rx+offset, len); + ld = tty_ldisc_ref(tty); + if (ld) { + if (ld->receive_buf) + ld->receive_buf(tty,card->tty_rx,&fp,olen); + tty_ldisc_deref(ld); + }else{ + if (net_ratelimit()){ + printk(KERN_INFO + "%s: NO TTY Sync line discipline!\n", + card->devname); + } + } + } + + dbg_printk(KERN_INFO "%s: Received Data %i\n",card->devname,olen); + return; +} + +#if 0 +static int wanpipe_tty_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} +#endif + +static void wanpipe_tty_stop(struct tty_struct *tty) +{ + return; +} + +static void wanpipe_tty_start(struct tty_struct *tty) +{ + return; +} + +static int config_tty (sdla_t *card) +{ + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + + /* Setup the Board for asynchronous mode */ + if (card->u.c.async_mode){ + + if (set_asy_config(card)) { + printk (KERN_INFO "%s: Failed CHDLC Async configuration!\n", + card->devname); + return -EINVAL; + } + }else{ + /* Setup the Board for CHDLC */ + if (set_chdlc_config(card)) { + printk (KERN_INFO "%s: Failed CHDLC configuration!\n", + card->devname); + return -EINVAL; + } + } + + /* Set interrupt mode and mask */ + if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME | + APP_INT_ON_GLOBAL_EXCEP_COND | + APP_INT_ON_TX_FRAME | + APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){ + printk (KERN_INFO "%s: Failed to set interrupt triggers!\n", + card->devname); + return -EINVAL; + } + + + /* Mask the Transmit and Timer interrupt */ + flags->interrupt_info_struct.interrupt_permission &= + ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER); + + + /* Enable communications */ + if (card->u.c.async_mode){ + if (asy_comm_enable(card) != 0) { + printk(KERN_INFO "%s: Failed to enable async commnunication!\n", + card->devname); + flags->interrupt_info_struct.interrupt_permission = 0; + card->u.c.comm_enabled=0; + chdlc_set_intr_mode(card,0); + return -EINVAL; + } + }else{ + if (chdlc_comm_enable(card) != 0) { + printk(KERN_INFO "%s: Failed to enable chdlc communications!\n", + card->devname); + flags->interrupt_info_struct.interrupt_permission = 0; + card->u.c.comm_enabled=0; + chdlc_set_intr_mode(card,0); + return -EINVAL; + } + } + + /* Initialize Rx/Tx buffer control fields */ + init_chdlc_tx_rx_buff(card); + port_set_state(card, WAN_CONNECTING); + return 0; +} + + +static int change_speed(sdla_t *card, struct tty_struct *tty, + struct termios *old_termios) +{ + int baud, ret=0; + unsigned cflag; + int dbits,sbits,parity,handshaking; + + cflag = tty->termios->c_cflag; + + /* There is always one stop bit */ + sbits=WANOPT_ONE; + + /* Parity is defaulted to NONE */ + parity = WANOPT_NONE; + + handshaking=0; + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS5: dbits = 5; break; + case CS6: dbits = 6; break; + case CS7: dbits = 7; break; + case CS8: dbits = 8; break; + /* Never happens, but GCC is too dumb to figure it out */ + default: dbits = 8; break; + } + + /* One more stop bit should be supported, thus increment + * the number of stop bits Max=2 */ + if (cflag & CSTOPB) { + sbits = WANOPT_TWO; + } + if (cflag & PARENB) { + parity = WANOPT_EVEN; + } + if (cflag & PARODD){ + parity = WANOPT_ODD; + } + + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(tty); + + if (!baud) + baud = 9600; /* B0 transition handled in rs_set_termios */ + + if (cflag & CRTSCTS) { + handshaking|=ASY_RTS_HS_FOR_RX; + } + + if (I_IGNPAR(tty)) + parity = WANOPT_NONE; + + if (I_IXOFF(tty)){ + handshaking|=ASY_XON_XOFF_HS_FOR_RX; + handshaking|=ASY_XON_XOFF_HS_FOR_TX; + } + + if (I_IXON(tty)){ + handshaking|=ASY_XON_XOFF_HS_FOR_RX; + handshaking|=ASY_XON_XOFF_HS_FOR_TX; + } + + if (card->u.c.async_mode){ + if (card->wandev.bps != baud) + ret=1; + card->wandev.bps = baud; + } + + if (card->u.c.async_mode){ + if (card->u.c.protocol_options != handshaking) + ret=1; + card->u.c.protocol_options = handshaking; + + if (card->u.c.tx_bits_per_char != dbits) + ret=1; + card->u.c.tx_bits_per_char = dbits; + + if (card->u.c.rx_bits_per_char != dbits) + ret=1; + card->u.c.rx_bits_per_char = dbits; + + if (card->u.c.stop_bits != sbits) + ret=1; + card->u.c.stop_bits = sbits; + + if (card->u.c.parity != parity) + ret=1; + card->u.c.parity = parity; + + card->u.c.break_timer = 50; + card->u.c.inter_char_timer = 10; + card->u.c.rx_complete_length = 100; + card->u.c.xon_char = 0xFE; + }else{ + card->u.c.protocol_options = HDLC_STREAMING_MODE; + } + + return ret; +} + + +static void wanpipe_tty_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + sdla_t *card; + int err=1; + + if (!tty){ + return; + } + + card = (sdla_t *)tty->driver_data; + + if (!card) + return; + + if (change_speed(card, tty, old_termios) || !card->u.c.comm_enabled){ + unsigned long smp_flags; + + if (card->u.c.comm_enabled){ + lock_adapter_irq(&card->wandev.lock,&smp_flags); + chdlc_disable_comm_shutdown(card); + unlock_adapter_irq(&card->wandev.lock,&smp_flags); + } + lock_adapter_irq(&card->wandev.lock,&smp_flags); + err = config_tty(card); + unlock_adapter_irq(&card->wandev.lock,&smp_flags); + if (card->u.c.async_mode){ + printk(KERN_INFO "%s: TTY Async Configuration:\n" + " Baud =%i\n" + " Handshaking =%s\n" + " Tx Dbits =%i\n" + " Rx Dbits =%i\n" + " Parity =%s\n" + " Stop Bits =%i\n", + card->devname, + card->wandev.bps, + opt_decode[card->u.c.protocol_options], + card->u.c.tx_bits_per_char, + card->u.c.rx_bits_per_char, + p_decode[card->u.c.parity] , + card->u.c.stop_bits); + }else{ + printk(KERN_INFO "%s: TTY Sync Configuration:\n" + " Baud =%i\n" + " Protocol =HDLC_STREAMING\n", + card->devname,card->wandev.bps); + } + if (!err){ + port_set_state(card,WAN_CONNECTED); + }else{ + port_set_state(card,WAN_DISCONNECTED); + } + } + return; +} + +static void wanpipe_tty_put_char(struct tty_struct *tty, unsigned char ch) +{ + sdla_t *card; + unsigned long smp_flags=0; + + if (!tty){ + return; + } + + card = (sdla_t *)tty->driver_data; + + if (!card) + return; + + if (card->wandev.state != WAN_CONNECTED) + return; + + if(card->hw.type != SDLA_S514) + s508_lock(card,&smp_flags); + + if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){ + + wanpipe_tty_trigger_tx_irq(card); + + if(card->hw.type != SDLA_S514) + s508_unlock(card,&smp_flags); + return; + } + + if (chdlc_send(card,(void*)&ch,1)){ + wanpipe_tty_trigger_tx_irq(card); + dbg_printk("%s: Failed to TX char!\n",card->devname); + } + + dbg_printk("%s: Char TX OK\n",card->devname); + + clear_bit(SEND_CRIT,(void*)&card->wandev.critical); + + if(card->hw.type != SDLA_S514) + s508_unlock(card,&smp_flags); + + return; +} + +static void wanpipe_tty_flush_chars(struct tty_struct *tty) +{ + return; +} + +static void wanpipe_tty_flush_buffer(struct tty_struct *tty) +{ + if (!tty) + return; + +#if defined(SERIAL_HAVE_POLL_WAIT) + wake_up_interruptible(&tty->poll_wait); +#endif + tty_wakeup(tty); + return; +} + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void wanpipe_tty_send_xchar(struct tty_struct *tty, char ch) +{ + return; +} + + +static int wanpipe_tty_chars_in_buffer(struct tty_struct *tty) +{ + return 0; +} + + +static int wanpipe_tty_write_room(struct tty_struct *tty) +{ + sdla_t *card; + + printk(KERN_INFO "TTY Write Room\n"); + + if (!tty){ + return 0; + } + + card = (sdla_t *)tty->driver_data; + if (!card) + return 0; + + if (card->wandev.state != WAN_CONNECTED) + return 0; + + return SEC_MAX_NO_DATA_BYTES_IN_FRAME; +} + + +static int set_modem_status(sdla_t *card, unsigned char data) +{ + CHDLC_MAILBOX_STRUCT *mb = card->mbox; + int err; + + mb->buffer_length=1; + mb->command=SET_MODEM_STATUS; + mb->data[0]=data; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error (card, err, mb); + + return err; +} + +static void wanpipe_tty_hangup(struct tty_struct *tty) +{ + sdla_t *card; + unsigned long smp_flags; + + printk(KERN_INFO "TTY Hangup!\n"); + + if (!tty){ + return; + } + + card = (sdla_t *)tty->driver_data; + if (!card) + return; + + lock_adapter_irq(&card->wandev.lock,&smp_flags); + set_modem_status(card,0); + unlock_adapter_irq(&card->wandev.lock,&smp_flags); + return; +} + +static void wanpipe_tty_break(struct tty_struct *tty, int break_state) +{ + return; +} + +static void wanpipe_tty_wait_until_sent(struct tty_struct *tty, int timeout) +{ + return; +} + +static void wanpipe_tty_throttle(struct tty_struct * tty) +{ + return; +} + +static void wanpipe_tty_unthrottle(struct tty_struct * tty) +{ + return; +} + +int wanpipe_tty_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + return 0; +} + +/* + * The serial driver boot-time initialization code! + */ +int wanpipe_tty_init(sdla_t *card) +{ + struct serial_state * state; + + /* Initialize the tty_driver structure */ + + if (card->tty_minor < 0 || card->tty_minor > NR_PORTS){ + printk(KERN_INFO "%s: Illegal Minor TTY number (0-4): %i\n", + card->devname,card->tty_minor); + return -EINVAL; + } + + if (WAN_CARD(card->tty_minor)){ + printk(KERN_INFO "%s: TTY Minor %i, already in use\n", + card->devname,card->tty_minor); + return -EBUSY; + } + + if (tty_init_cnt==0){ + + printk(KERN_INFO "%s: TTY %s Driver Init: Major %i, Minor Range %i-%i\n", + card->devname, + card->u.c.async_mode ? "ASYNC" : "SYNC", + WAN_TTY_MAJOR,MIN_PORT,MAX_PORT); + + tty_driver_mode = card->u.c.async_mode; + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; + serial_driver.owner = THIS_MODULE; + serial_driver.driver_name = "wanpipe_tty"; + serial_driver.name = "ttyW"; + serial_driver.major = WAN_TTY_MAJOR; + serial_driver.minor_start = WAN_TTY_MINOR; + serial_driver.num = NR_PORTS; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + + serial_driver.init_termios = tty_std_termios; + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW; + + serial_driver.refcount = 1; /* !@!@^#^&!! */ + + serial_driver.open = wanpipe_tty_open; + serial_driver.close = wanpipe_tty_close; + serial_driver.write = wanpipe_tty_write; + + serial_driver.put_char = wanpipe_tty_put_char; + serial_driver.flush_chars = wanpipe_tty_flush_chars; + serial_driver.write_room = wanpipe_tty_write_room; + serial_driver.chars_in_buffer = wanpipe_tty_chars_in_buffer; + serial_driver.flush_buffer = wanpipe_tty_flush_buffer; + //serial_driver.ioctl = wanpipe_tty_ioctl; + serial_driver.throttle = wanpipe_tty_throttle; + serial_driver.unthrottle = wanpipe_tty_unthrottle; + serial_driver.send_xchar = wanpipe_tty_send_xchar; + serial_driver.set_termios = wanpipe_tty_set_termios; + serial_driver.stop = wanpipe_tty_stop; + serial_driver.start = wanpipe_tty_start; + serial_driver.hangup = wanpipe_tty_hangup; + serial_driver.break_ctl = wanpipe_tty_break; + serial_driver.wait_until_sent = wanpipe_tty_wait_until_sent; + serial_driver.read_proc = wanpipe_tty_read_proc; + + if (tty_register_driver(&serial_driver)){ + printk(KERN_INFO "%s: Failed to register serial driver!\n", + card->devname); + } + } + + + /* The subsequent ports must comply to the initial configuration */ + if (tty_driver_mode != card->u.c.async_mode){ + printk(KERN_INFO "%s: Error: TTY Driver operation mode mismatch!\n", + card->devname); + printk(KERN_INFO "%s: The TTY driver is configured for %s!\n", + card->devname, tty_driver_mode ? "ASYNC" : "SYNC"); + return -EINVAL; + } + + tty_init_cnt++; + + printk(KERN_INFO "%s: Initializing TTY %s Driver Minor %i\n", + card->devname, + tty_driver_mode ? "ASYNC" : "SYNC", + card->tty_minor); + + tty_card_map[card->tty_minor] = card; + state = &rs_table[card->tty_minor]; + + state->magic = SSTATE_MAGIC; + state->line = 0; + state->type = PORT_UNKNOWN; + state->custom_divisor = 0; + state->close_delay = 5*HZ/10; + state->closing_wait = 30*HZ; + state->icount.cts = state->icount.dsr = + state->icount.rng = state->icount.dcd = 0; + state->icount.rx = state->icount.tx = 0; + state->icount.frame = state->icount.parity = 0; + state->icount.overrun = state->icount.brk = 0; + state->irq = card->wandev.irq; + + INIT_WORK(&card->tty_work, tty_poll_work, (void*)card); + return 0; +} + + +MODULE_LICENSE("GPL"); + +/****** End ****************************************************************/ diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c new file mode 100644 index 000000000..7f1ce9d43 --- /dev/null +++ b/drivers/net/wan/sdla_fr.c @@ -0,0 +1,5061 @@ +/***************************************************************************** +* sdla_fr.c WANPIPE(tm) Multiprotocol WAN Link Driver. Frame relay module. +* +* Author(s): Nenad Corbic +* Gideon Hack +* +* Copyright: (c) 1995-2001 Sangoma 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. +* ============================================================================ +* Nov 23, 2000 Nenad Corbic o Added support for 2.4.X kernels +* Nov 15, 2000 David Rokavarg +* Nenad Corbic o Added frame relay bridging support. +* Original code from Mark Wells and Kristian Hoffmann has +* been integrated into the frame relay driver. +* Nov 13, 2000 Nenad Corbic o Added true interface type encoding option. +* Tcpdump doesn't support Frame Relay inteface +* types, to fix this true type option will set +* the interface type to RAW IP mode. +* Nov 07, 2000 Nenad Corbic o Added security features for UDP debugging: +* Deny all and specify allowed requests. +* Nov 06, 2000 Nenad Corbic o Wanpipe interfaces conform to raw packet interfaces. +* Moved the if_header into the if_send() routine. +* The if_header() was breaking the libpcap +* support. i.e. support for tcpdump, ethereal ... +* Oct 12. 2000 Nenad Corbic o Added error message in fr_configure +* Jul 31, 2000 Nenad Corbic o Fixed the Router UP Time. +* Apr 28, 2000 Nenad Corbic o Added the option to shutdown an interface +* when the channel gets disconnected. +* Apr 28, 2000 Nenad Corbic o Added M.Grants patch: disallow duplicate +* interface setups. +* Apr 25, 2000 Nenad Corbic o Added M.Grants patch: dynamically add/remove +* new dlcis/interfaces. +* Mar 23, 2000 Nenad Corbic o Improved task queue, bh handling. +* Mar 16, 2000 Nenad Corbic o Added Inverse ARP support +* Mar 13, 2000 Nenad Corbic o Added new socket API support. +* Mar 06, 2000 Nenad Corbic o Bug Fix: corrupted mbox recovery. +* Feb 24, 2000 Nenad Corbic o Fixed up FT1 UDP debugging problem. +* Dev 15, 1999 Nenad Corbic o Fixed up header files for 2.0.X kernels +* +* Nov 08, 1999 Nenad Corbic o Combined all debug UDP calls into one function +* o Removed the ARP support. This has to be done +* in the next version. +* o Only a Node can implement NO signalling. +* Initialize DLCI during if_open() if NO +* signalling. +* o Took out IPX support, implement in next +* version +* Sep 29, 1999 Nenad Corbic o Added SMP support and changed the update +* function to use timer interrupt. +* o Fixed the CIR bug: Set the value of BC +* to CIR when the CIR is enabled. +* o Updated comments, statistics and tracing. +* Jun 02, 1999 Gideon Hack o Updated for S514 support. +* Sep 18, 1998 Jaspreet Singh o Updated for 2.2.X kernels. +* Jul 31, 1998 Jaspreet Singh o Removed wpf_poll routine. The channel/DLCI +* status is received through an event interrupt. +* Jul 08, 1998 David Fong o Added inverse ARP support. +* Mar 26, 1997 Jaspreet Singh o Returning return codes for failed UDP cmds. +* Jan 28, 1997 Jaspreet Singh o Improved handling of inactive DLCIs. +* Dec 30, 1997 Jaspreet Singh o Replaced dev_tint() with mark_bh(NET_BH) +* Dec 16, 1997 Jaspreet Singh o Implemented Multiple IPX support. +* Nov 26, 1997 Jaspreet Singh o Improved load sharing with multiple boards +* o Added Cli() to protect enabling of interrupts +* while polling is called. +* Nov 24, 1997 Jaspreet Singh o Added counters to avoid enabling of interrupts +* when they have been disabled by another +* interface or routine (eg. wpf_poll). +* Nov 06, 1997 Jaspreet Singh o Added INTR_TEST_MODE to avoid polling +* routine disable interrupts during interrupt +* testing. +* Oct 20, 1997 Jaspreet Singh o Added hooks in for Router UP time. +* Oct 16, 1997 Jaspreet Singh o The critical flag is used to maintain flow +* control by avoiding RACE conditions. The +* cli() and restore_flags() are taken out. +* The fr_channel structure is appended for +* Driver Statistics. +* Oct 15, 1997 Farhan Thawar o updated if_send() and receive for IPX +* Aug 29, 1997 Farhan Thawar o Removed most of the cli() and sti() +* o Abstracted the UDP management stuff +* o Now use tbusy and critical more intelligently +* Jul 21, 1997 Jaspreet Singh o Can configure T391, T392, N391, N392 & N393 +* through router.conf. +* o Protected calls to sdla_peek() by adDing +* save_flags(), cli() and restore_flags(). +* o Added error message for Inactive DLCIs in +* fr_event() and update_chan_state(). +* o Fixed freeing up of buffers using kfree() +* when packets are received. +* Jul 07, 1997 Jaspreet Singh o Added configurable TTL for UDP packets +* o Added ability to discard multicast and +* broadcast source addressed packets +* Jun 27, 1997 Jaspreet Singh o Added FT1 monitor capabilities +* New case (0x44) statement in if_send routine +* Added a global variable rCount to keep track +* of FT1 status enabled on the board. +* May 29, 1997 Jaspreet Singh o Fixed major Flow Control Problem +* With multiple boards a problem was seen where +* the second board always stopped transmitting +* packet after running for a while. The code +* got into a stage where the interrupts were +* disabled and dev->tbusy was set to 1. +* This caused the If_send() routine to get into +* the if clause for it(0,dev->tbusy) +* forever. +* The code got into this stage due to an +* interrupt occurring within the if clause for +* set_bit(0,dev->tbusy). Since an interrupt +* disables furhter transmit interrupt and +* makes dev->tbusy = 0, this effect was undone +* by making dev->tbusy = 1 in the if clause. +* The Fix checks to see if Transmit interrupts +* are disabled then do not make dev->tbusy = 1 +* Introduced a global variable: int_occur and +* added tx_int_enabled in the wan_device +* structure. +* May 21, 1997 Jaspreet Singh o Fixed UDP Management for multiple +* boards. +* +* Apr 25, 1997 Farhan Thawar o added UDP Management stuff +* o fixed bug in if_send() and tx_intr() to +* sleep and wakeup all devices +* Mar 11, 1997 Farhan Thawar Version 3.1.1 +* o fixed (+1) bug in fr508_rx_intr() +* o changed if_send() to return 0 if +* wandev.critical() is true +* o free socket buffer in if_send() if +* returning 0 +* o added tx_intr() routine +* Jan 30, 1997 Gene Kozin Version 3.1.0 +* o implemented exec() entry point +* o fixed a bug causing driver configured as +* a FR switch to be stuck in WAN_ +* mode +* Jan 02, 1997 Gene Kozin Initial version. +*****************************************************************************/ + +#include +#include /* printk(), and other useful stuff */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include /* kmalloc(), kfree() */ +#include /* WAN router definitions */ +#include /* WANPIPE common user API definitions */ +#include +#include /* ARPHRD_* defines */ +#include /* htons(), etc. */ +#include /* for inb(), outb(), etc. */ +#include /* for do_gettimeofday */ +#include /* sockaddr_in */ +#include /* time_after() macro */ +#include + +#include +#include + +#include /* Wanpipe Socket */ +#include + +#include /* frame relay firmware API definitions */ + +#include +#include +#include + +#include /* Dynamic Route Creation */ +#include /* eth_type_trans() used for bridging */ +#include + +/****** Defines & Macros ****************************************************/ + +#define MAX_CMD_RETRY 10 /* max number of firmware retries */ + +#define FR_HEADER_LEN 8 /* max encapsulation header size */ +#define FR_CHANNEL_MTU 1500 /* unfragmented logical channel MTU */ + +/* Q.922 frame types */ +#define Q922_UI 0x03 /* Unnumbered Info frame */ +#define Q922_XID 0xAF + +/* DLCI configured or not */ +#define DLCI_NOT_CONFIGURED 0x00 +#define DLCI_CONFIG_PENDING 0x01 +#define DLCI_CONFIGURED 0x02 + +/* CIR enabled or not */ +#define CIR_ENABLED 0x00 +#define CIR_DISABLED 0x01 + +#define FRAME_RELAY_API 1 +#define MAX_BH_BUFF 10 + +/* For handle_IPXWAN() */ +#define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b))) + +/****** Data Structures *****************************************************/ + +/* This is an extention of the 'struct device' we create for each network + * interface to keep the rest of channel-specific data. + */ +typedef struct fr_channel +{ + wanpipe_common_t common; + char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ + unsigned dlci_configured ; /* check whether configured or not */ + unsigned cir_status; /* check whether CIR enabled or not */ + unsigned dlci; /* logical channel number */ + unsigned cir; /* committed information rate */ + unsigned bc; /* committed burst size */ + unsigned be; /* excess burst size */ + unsigned mc; /* multicast support on or off */ + unsigned tx_int_status; /* Transmit Interrupt Status */ + unsigned short pkt_length; /* Packet Length */ + unsigned long router_start_time;/* Router start time in seconds */ + unsigned long tick_counter; /* counter for transmit time out */ + char dev_pending_devtint; /* interface pending dev_tint() */ + void *dlci_int_interface; /* pointer to the DLCI Interface */ + unsigned long IB_addr; /* physical address of Interface Byte */ + unsigned long state_tick; /* time of the last state change */ + unsigned char enable_IPX; /* Enable/Disable the use of IPX */ + unsigned long network_number; /* Internal Network Number for IPX*/ + sdla_t *card; /* -> owner */ + unsigned route_flag; /* Add/Rem dest addr in route tables */ + unsigned inarp; /* Inverse Arp Request status */ + long inarp_ready; /* Ready to send requests */ + int inarp_interval; /* Time between InArp Requests */ + unsigned long inarp_tick; /* InArp jiffies tick counter */ + long interface_down; /* Bring interface down on disconnect */ + struct net_device_stats ifstats; /* interface statistics */ + if_send_stat_t drvstats_if_send; + rx_intr_stat_t drvstats_rx_intr; + pipe_mgmt_stat_t drvstats_gen; + unsigned long router_up_time; + + unsigned short transmit_length; + struct sk_buff *delay_skb; + + bh_data_t *bh_head; /* Circular buffer for chdlc_bh */ + unsigned long tq_working; + volatile int bh_write; + volatile int bh_read; + atomic_t bh_buff_used; + + /* Polling task queue. Each interface + * has its own task queue, which is used + * to defer events from the interrupt */ + struct work_struct fr_poll_work; + struct timer_list fr_arp_timer; + + u32 ip_local; + u32 ip_remote; + long config_dlci; + long unconfig_dlci; + + /* Whether this interface should be setup as a gateway. + * Used by dynamic route setup code */ + u8 gateway; + + /* True interface type */ + u8 true_if_encoding; + u8 fr_header[FR_HEADER_LEN]; + char fr_header_len; + +} fr_channel_t; + +/* Route Flag options */ +#define NO_ROUTE 0x00 +#define ADD_ROUTE 0x01 +#define ROUTE_ADDED 0x02 +#define REMOVE_ROUTE 0x03 +#define ARP_REQ 0x04 + +/* inarp options */ +#define INARP_NONE 0x00 +#define INARP_REQUEST 0x01 +#define INARP_CONFIGURED 0x02 + +/* reasons for enabling the timer interrupt on the adapter */ +#define TMR_INT_ENABLED_UDP 0x01 +#define TMR_INT_ENABLED_UPDATE 0x02 +#define TMR_INT_ENABLED_ARP 0x04 +#define TMR_INT_ENABLED_UPDATE_STATE 0x08 +#define TMR_INT_ENABLED_CONFIG 0x10 +#define TMR_INT_ENABLED_UNCONFIG 0x20 + + +typedef struct dlci_status +{ + unsigned short dlci PACKED; + unsigned char state PACKED; +} dlci_status_t; + +typedef struct dlci_IB_mapping +{ + unsigned short dlci PACKED; + unsigned long addr_value PACKED; +} dlci_IB_mapping_t; + +/* This structure is used for DLCI list Tx interrupt mode. It is used to + enable interrupt bit and set the packet length for transmission + */ +typedef struct fr_dlci_interface +{ + unsigned char gen_interrupt PACKED; + unsigned short packet_length PACKED; + unsigned char reserved PACKED; +} fr_dlci_interface_t; + +/* variable for keeping track of enabling/disabling FT1 monitor status */ +static int rCount = 0; + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +/* variable for keeping track of number of interrupts generated during + * interrupt test routine + */ +static int Intr_test_counter; + +/****** Function Prototypes *************************************************/ + +/* WAN link driver entry points. These are called by the WAN router module. */ +static int update(struct wan_device *wandev); +static int new_if(struct wan_device *wandev, struct net_device *dev, + wanif_conf_t *conf); +static int del_if(struct wan_device *wandev, struct net_device *dev); +static void disable_comm (sdla_t *card); + +/* WANPIPE-specific entry points */ +static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data); + +/* Network device interface */ +static int if_init(struct net_device *dev); +static int if_open(struct net_device *dev); +static int if_close(struct net_device *dev); + +static void if_tx_timeout(struct net_device *dev); + +static int if_rebuild_hdr (struct sk_buff *skb); + +static int if_send(struct sk_buff *skb, struct net_device *dev); +static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, + struct sk_buff *skb); +static struct net_device_stats *if_stats(struct net_device *dev); + +/* Interrupt handlers */ +static void fr_isr(sdla_t *card); +static void rx_intr(sdla_t *card); +static void tx_intr(sdla_t *card); +static void timer_intr(sdla_t *card); +static void spur_intr(sdla_t *card); + +/* Frame relay firmware interface functions */ +static int fr_read_version(sdla_t *card, char *str); +static int fr_configure(sdla_t *card, fr_conf_t *conf); +static int fr_dlci_configure(sdla_t *card, fr_dlc_conf_t *conf, unsigned dlci); +static int fr_init_dlci (sdla_t *card, fr_channel_t *chan); +static int fr_set_intr_mode (sdla_t *card, unsigned mode, unsigned mtu, unsigned short timeout); +static int fr_comm_enable(sdla_t *card); +static void fr_comm_disable(sdla_t *card); +static int fr_get_err_stats(sdla_t *card); +static int fr_get_stats(sdla_t *card); +static int fr_add_dlci(sdla_t *card, int dlci); +static int fr_activate_dlci(sdla_t *card, int dlci); +static int fr_delete_dlci (sdla_t* card, int dlci); +static int fr_issue_isf(sdla_t *card, int isf); +static int fr_send(sdla_t *card, int dlci, unsigned char attr, int len, + void *buf); +static int fr_send_data_header(sdla_t *card, int dlci, unsigned char attr, int len, + void *buf,unsigned char hdr_len); +static unsigned int fr_send_hdr(sdla_t *card, int dlci, unsigned int offset); + +static int check_dlci_config (sdla_t *card, fr_channel_t *chan); +static void initialize_rx_tx_buffers (sdla_t *card); + + +/* Firmware asynchronous event handlers */ +static int fr_event(sdla_t *card, int event, fr_mbox_t *mbox); +static int fr_modem_failure(sdla_t *card, fr_mbox_t *mbox); +static int fr_dlci_change(sdla_t *card, fr_mbox_t *mbox); + +/* Miscellaneous functions */ +static int update_chan_state(struct net_device *dev); +static void set_chan_state(struct net_device *dev, int state); +static struct net_device *find_channel(sdla_t *card, unsigned dlci); +static int is_tx_ready(sdla_t *card, fr_channel_t *chan); +static unsigned int dec_to_uint(unsigned char *str, int len); +static int reply_udp( unsigned char *data, unsigned int mbox_len ); + +static int intr_test( sdla_t* card ); +static void init_chan_statistics( fr_channel_t* chan ); +static void init_global_statistics( sdla_t* card ); +static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan ); +static int setup_for_delayed_transmit(struct net_device* dev, + struct sk_buff *skb); + +struct net_device *move_dev_to_next(sdla_t *card, struct net_device *dev); +static int check_tx_status(sdla_t *card, struct net_device *dev); + +/* Frame Relay Socket API */ +static void trigger_fr_bh (fr_channel_t *); +static void fr_bh(struct net_device *dev); +static int fr_bh_cleanup(struct net_device *dev); +static int bh_enqueue(struct net_device *dev, struct sk_buff *skb); + +static void trigger_fr_poll(struct net_device *dev); +static void fr_poll(struct net_device *dev); +//static void add_gateway(struct net_device *dev); + +static void trigger_unconfig_fr(struct net_device *dev); +static void unconfig_fr (sdla_t *); + +static void trigger_config_fr (sdla_t *); +static void config_fr (sdla_t *); + + +/* Inverse ARP and Dynamic routing functions */ +int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device *dev); +int is_arp(void *buf); +int send_inarp_request(sdla_t *card, struct net_device *dev); + +static void trigger_fr_arp(struct net_device *dev); +static void fr_arp (unsigned long data); + + +/* Udp management functions */ +static int process_udp_mgmt_pkt(sdla_t *card); +static int udp_pkt_type( struct sk_buff *skb, sdla_t *card ); +static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, int dlci); + +/* IPX functions */ +static void switch_net_numbers(unsigned char *sendpacket, + unsigned long network_number, unsigned char incoming); + +static int handle_IPXWAN(unsigned char *sendpacket, char *devname, + unsigned char enable_IPX, unsigned long network_number); + +/* Lock Functions: SMP supported */ +void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags); +void s508_s514_lock(sdla_t *card, unsigned long *smp_flags); + +unsigned short calc_checksum (char *, int); +static int setup_fr_header(struct sk_buff *skb, + struct net_device* dev, char op_mode); + + +/****** Public Functions ****************************************************/ + +/*============================================================================ + * Frame relay protocol initialization routine. + * + * This routine is called by the main WANPIPE module during setup. At this + * point adapter is completely initialized and firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the adapter data space. + * + * Return: 0 o.k. + * < 0 failure. + */ +int wpf_init(sdla_t *card, wandev_conf_t *conf) +{ + + int err; + fr508_flags_t* flags; + + union + { + char str[80]; + fr_conf_t cfg; + } u; + + fr_buf_info_t* buf_info; + int i; + + + printk(KERN_INFO "\n"); + + /* Verify configuration ID */ + if (conf->config_id != WANCONFIG_FR) { + + printk(KERN_INFO "%s: invalid configuration ID %u!\n", + card->devname, conf->config_id); + return -EINVAL; + + } + + /* Initialize protocol-specific fields of adapter data space */ + switch (card->hw.fwid) { + + case SFID_FR508: + card->mbox = (void*)(card->hw.dpmbase + + FR508_MBOX_OFFS); + card->flags = (void*)(card->hw.dpmbase + + FR508_FLAG_OFFS); + if(card->hw.type == SDLA_S514) { + card->mbox += FR_MB_VECTOR; + card->flags += FR_MB_VECTOR; + } + card->isr = &fr_isr; + break; + + default: + return -EINVAL; + } + + flags = card->flags; + + /* Read firmware version. Note that when adapter initializes, it + * clears the mailbox, so it may appear that the first command was + * executed successfully when in fact it was merely erased. To work + * around this, we execute the first command twice. + */ + + if (fr_read_version(card, NULL) || fr_read_version(card, u.str)) + return -EIO; + + printk(KERN_INFO "%s: running frame relay firmware v%s\n", + card->devname, u.str); + + /* Adjust configuration */ + conf->mtu += FR_HEADER_LEN; + conf->mtu = (conf->mtu >= MIN_LGTH_FR_DATA_CFG) ? + min_t(unsigned int, conf->mtu, FR_MAX_NO_DATA_BYTES_IN_FRAME) : + FR_CHANNEL_MTU + FR_HEADER_LEN; + + conf->bps = min_t(unsigned int, conf->bps, 2048000); + + /* Initialze the configuration structure sent to the board to zero */ + memset(&u.cfg, 0, sizeof(u.cfg)); + + memset(card->u.f.dlci_to_dev_map, 0, sizeof(card->u.f.dlci_to_dev_map)); + + /* Configure adapter firmware */ + + u.cfg.mtu = conf->mtu; + u.cfg.kbps = conf->bps / 1000; + + u.cfg.cir_fwd = u.cfg.cir_bwd = 16; + u.cfg.bc_fwd = u.cfg.bc_bwd = 16; + + u.cfg.options = 0x0000; + printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname); + + switch (conf->u.fr.signalling) { + + case WANOPT_FR_ANSI: + u.cfg.options = 0x0000; + break; + + case WANOPT_FR_Q933: + u.cfg.options |= 0x0200; + break; + + case WANOPT_FR_LMI: + u.cfg.options |= 0x0400; + break; + + case WANOPT_NO: + u.cfg.options |= 0x0800; + break; + default: + printk(KERN_INFO "%s: Illegal Signalling option\n", + card->wandev.name); + return -EINVAL; + } + + + card->wandev.signalling = conf->u.fr.signalling; + + if (conf->station == WANOPT_CPE) { + + + if (conf->u.fr.signalling == WANOPT_NO){ + printk(KERN_INFO + "%s: ERROR - For NO signalling, station must be set to Node!", + card->devname); + return -EINVAL; + } + + u.cfg.station = 0; + u.cfg.options |= 0x8000; /* auto config DLCI */ + card->u.f.dlci_num = 0; + + } else { + + u.cfg.station = 1; /* switch emulation mode */ + + /* For switch emulation we have to create a list of dlci(s) + * that will be sent to be global SET_DLCI_CONFIGURATION + * command in fr_configure() routine. + */ + + card->u.f.dlci_num = min_t(unsigned int, max_t(unsigned int, conf->u.fr.dlci_num, 1), 100); + + for ( i = 0; i < card->u.f.dlci_num; i++) { + + card->u.f.node_dlci[i] = (unsigned short) + conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16; + + } + } + + if (conf->clocking == WANOPT_INTERNAL) + u.cfg.port |= 0x0001; + + if (conf->interface == WANOPT_RS232) + u.cfg.port |= 0x0002; + + if (conf->u.fr.t391) + u.cfg.t391 = min_t(unsigned int, conf->u.fr.t391, 30); + else + u.cfg.t391 = 5; + + if (conf->u.fr.t392) + u.cfg.t392 = min_t(unsigned int, conf->u.fr.t392, 30); + else + u.cfg.t392 = 15; + + if (conf->u.fr.n391) + u.cfg.n391 = min_t(unsigned int, conf->u.fr.n391, 255); + else + u.cfg.n391 = 2; + + if (conf->u.fr.n392) + u.cfg.n392 = min_t(unsigned int, conf->u.fr.n392, 10); + else + u.cfg.n392 = 3; + + if (conf->u.fr.n393) + u.cfg.n393 = min_t(unsigned int, conf->u.fr.n393, 10); + else + u.cfg.n393 = 4; + + if (fr_configure(card, &u.cfg)) + return -EIO; + + if (card->hw.type == SDLA_S514) { + + buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR + + FR508_RXBC_OFFS); + + card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase); + + card->u.f.rxmb_base = + (void*)(buf_info->rse_base + card->hw.dpmbase); + + card->u.f.rxmb_last = + (void*)(buf_info->rse_base + + (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) + + card->hw.dpmbase); + }else{ + buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS); + + card->rxmb = (void*)(buf_info->rse_next - + FR_MB_VECTOR + card->hw.dpmbase); + + card->u.f.rxmb_base = + (void*)(buf_info->rse_base - + FR_MB_VECTOR + card->hw.dpmbase); + + card->u.f.rxmb_last = + (void*)(buf_info->rse_base + + (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) - + FR_MB_VECTOR + card->hw.dpmbase); + } + + card->u.f.rx_base = buf_info->buf_base; + card->u.f.rx_top = buf_info->buf_top; + + card->u.f.tx_interrupts_pending = 0; + + card->wandev.mtu = conf->mtu; + card->wandev.bps = conf->bps; + card->wandev.interface = conf->interface; + card->wandev.clocking = conf->clocking; + card->wandev.station = conf->station; + card->poll = NULL; + card->exec = &wpf_exec; + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + card->wandev.state = WAN_DISCONNECTED; + card->wandev.ttl = conf->ttl; + card->wandev.udp_port = conf->udp_port; + card->disable_comm = &disable_comm; + card->u.f.arp_dev = NULL; + + /* Intialize global statistics for a card */ + init_global_statistics( card ); + + card->TracingEnabled = 0; + + /* Interrupt Test */ + Intr_test_counter = 0; + card->intr_mode = INTR_TEST_MODE; + err = intr_test( card ); + + printk(KERN_INFO "%s: End of Interrupt Test rc=0x%x count=%i\n", + card->devname,err,Intr_test_counter); + + if (err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { + printk(KERN_ERR "%s: Interrupt Test Failed, Counter: %i\n", + card->devname, Intr_test_counter); + printk(KERN_ERR "Please choose another interrupt\n"); + err = -EIO; + return err; + } + + printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", + card->devname, Intr_test_counter); + + + /* Apr 28 2000. Nenad Corbic + * Enable commnunications here, not in if_open or new_if, since + * interfaces come down when the link is disconnected. + */ + + /* If you enable comms and then set ints, you get a Tx int as you + * perform the SET_INT_TRIGGERS command. So, we only set int + * triggers and then adjust the interrupt mask (to disable Tx ints) + * before enabling comms. + */ + if (fr_set_intr_mode(card, (FR_INTR_RXRDY | FR_INTR_TXRDY | + FR_INTR_DLC | FR_INTR_TIMER | FR_INTR_TX_MULT_DLCIs) , + card->wandev.mtu, 0)) { + return -EIO; + } + + flags->imask &= ~(FR_INTR_TXRDY | FR_INTR_TIMER); + + if (fr_comm_enable(card)) { + return -EIO; + } + wanpipe_set_state(card, WAN_CONNECTED); + spin_lock_init(&card->u.f.if_send_lock); + + printk(KERN_INFO "\n"); + + return 0; +} + +/******* WAN Device Driver Entry Points *************************************/ + +/*============================================================================ + * Update device status & statistics. + */ +static int update(struct wan_device* wandev) +{ + volatile sdla_t* card; + unsigned long timeout; + fr508_flags_t* flags; + + /* sanity checks */ + if ((wandev == NULL) || (wandev->private == NULL)) + return -EFAULT; + + if (wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + card = wandev->private; + flags = card->flags; + + + card->u.f.update_comms_stats = 1; + card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE; + flags->imask |= FR_INTR_TIMER; + timeout = jiffies; + for(;;) { + if(card->u.f.update_comms_stats == 0) + break; + if (time_after(jiffies, timeout + 1 * HZ)){ + card->u.f.update_comms_stats = 0; + return -EAGAIN; + } + } + + return 0; +} + +/*============================================================================ + * Create new logical channel. + * This routine is called by the router when ROUTER_IFNEW IOCTL is being + * handled. + * o parse media- and hardware-specific configuration + * o make sure that a new channel can be created + * o allocate resources, if necessary + * o prepare network device structure for registaration. + * + * Return: 0 o.k. + * < 0 failure (channel will not be created) + */ +static int new_if(struct wan_device* wandev, struct net_device* dev, + wanif_conf_t* conf) +{ + sdla_t* card = wandev->private; + fr_channel_t* chan; + int dlci = 0; + int err = 0; + + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { + + printk(KERN_INFO "%s: Invalid interface name!\n", + card->devname); + return -EINVAL; + } + + /* allocate and initialize private data */ + chan = kmalloc(sizeof(fr_channel_t), GFP_KERNEL); + + if (chan == NULL) + return -ENOMEM; + + memset(chan, 0, sizeof(fr_channel_t)); + strcpy(chan->name, conf->name); + chan->card = card; + + /* verify media address */ + if (isdigit(conf->addr[0])) { + + dlci = dec_to_uint(conf->addr, 0); + + if (dlci && (dlci <= HIGHEST_VALID_DLCI)) { + + chan->dlci = dlci; + + } else { + + printk(KERN_ERR + "%s: Invalid DLCI %u on interface %s!\n", + wandev->name, dlci, chan->name); + err = -EINVAL; + } + + } else { + printk(KERN_ERR + "%s: Invalid media address on interface %s!\n", + wandev->name, chan->name); + err = -EINVAL; + } + + if ((chan->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){ + printk(KERN_INFO + "%s: Enabling, true interface type encoding.\n", + card->devname); + } + + + + /* Setup wanpipe as a router (WANPIPE) even if it is + * a bridged DLCI, or as an API + */ + if (strcmp(conf->usedby, "WANPIPE") == 0 || + strcmp(conf->usedby, "BRIDGE") == 0 || + strcmp(conf->usedby, "BRIDGE_N") == 0){ + + if(strcmp(conf->usedby, "WANPIPE") == 0){ + chan->common.usedby = WANPIPE; + + printk(KERN_INFO "%s: Running in WANPIPE mode.\n", + card->devname); + + }else if(strcmp(conf->usedby, "BRIDGE") == 0){ + + chan->common.usedby = BRIDGE; + + printk(KERN_INFO "%s: Running in WANPIPE (BRIDGE) mode.\n", + card->devname); + }else if( strcmp(conf->usedby, "BRIDGE_N") == 0 ){ + + chan->common.usedby = BRIDGE_NODE; + + printk(KERN_INFO "%s: Running in WANPIPE (BRIDGE_NODE) mode.\n", + card->devname); + } + + if (!err){ + /* Dynamic interface configuration option. + * On disconnect, if the options is selected, + * the interface will be brought down */ + if (conf->if_down == WANOPT_YES){ + set_bit(DYN_OPT_ON,&chan->interface_down); + printk(KERN_INFO + "%s: Dynamic interface configuration enabled.\n", + card->devname); + } + } + + } else if(strcmp(conf->usedby, "API") == 0){ + + chan->common.usedby = API; + printk(KERN_INFO "%s: Running in API mode.\n", + wandev->name); + } + + if (err) { + + kfree(chan); + return err; + } + + /* place cir,be,bc and other channel specific information into the + * chan structure + */ + if (conf->cir) { + + chan->cir = max_t(unsigned int, 1, + min_t(unsigned int, conf->cir, 512)); + chan->cir_status = CIR_ENABLED; + + + /* If CIR is enabled, force BC to equal CIR + * this solves number of potential problems if CIR is + * set and BC is not + */ + chan->bc = chan->cir; + + if (conf->be){ + chan->be = max_t(unsigned int, + 0, min_t(unsigned int, conf->be, 511)); + }else{ + conf->be = 0; + } + + printk (KERN_INFO "%s: CIR enabled for DLCI %i \n", + wandev->name,chan->dlci); + printk (KERN_INFO "%s: CIR = %i ; BC = %i ; BE = %i\n", + wandev->name,chan->cir,chan->bc,chan->be); + + + }else{ + chan->cir_status = CIR_DISABLED; + printk (KERN_INFO "%s: CIR disabled for DLCI %i\n", + wandev->name,chan->dlci); + } + + chan->mc = conf->mc; + + if (conf->inarp == WANOPT_YES){ + printk(KERN_INFO "%s: Inverse ARP Support Enabled\n",card->devname); + chan->inarp = conf->inarp ? INARP_REQUEST : INARP_NONE; + chan->inarp_interval = conf->inarp_interval ? conf->inarp_interval : 10; + }else{ + printk(KERN_INFO "%s: Inverse ARP Support Disabled\n",card->devname); + chan->inarp = INARP_NONE; + chan->inarp_interval = 10; + } + + + chan->dlci_configured = DLCI_NOT_CONFIGURED; + + + /*FIXME: IPX disabled in this WANPIPE version */ + if (conf->enable_IPX == WANOPT_YES){ + printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support IPX\n", + card->devname); + kfree(chan); + return -EINVAL; + }else{ + chan->enable_IPX = WANOPT_NO; + } + + if (conf->network_number){ + chan->network_number = conf->network_number; + }else{ + chan->network_number = 0xDEADBEEF; + } + + chan->route_flag = NO_ROUTE; + + init_chan_statistics(chan); + + chan->transmit_length = 0; + + /* prepare network device data space for registration */ + strcpy(dev->name,chan->name); + + dev->init = &if_init; + dev->priv = chan; + + /* Initialize FR Polling Task Queue + * We need a poll routine for each network + * interface. + */ + INIT_WORK(&chan->fr_poll_work, (void *)fr_poll, dev); + + init_timer(&chan->fr_arp_timer); + chan->fr_arp_timer.data=(unsigned long)dev; + chan->fr_arp_timer.function = fr_arp; + + wandev->new_if_cnt++; + + /* Tells us that if this interface is a + * gateway or not */ + if ((chan->gateway = conf->gateway) == WANOPT_YES){ + printk(KERN_INFO "%s: Interface %s is set as a gateway.\n", + card->devname,dev->name); + } + + /* M. Grant Patch Apr 28 2000 + * Disallow duplicate dlci configurations. */ + if (card->u.f.dlci_to_dev_map[chan->dlci] != NULL) { + kfree(chan); + return -EBUSY; + } + + /* Configure this dlci at a later date, when + * the interface comes up. i.e. when if_open() + * executes */ + set_bit(0,&chan->config_dlci); + + printk(KERN_INFO "\n"); + + return 0; +} + +/*============================================================================ + * Delete logical channel. + */ +static int del_if(struct wan_device* wandev, struct net_device* dev) +{ + fr_channel_t* chan = dev->priv; + unsigned long smp_flags=0; + + /* This interface is dead, make sure the + * ARP timer is stopped */ + del_timer(&chan->fr_arp_timer); + + /* If we are a NODE, we must unconfigure this DLCI + * Trigger an unconfigure command that will + * be executed in timer interrupt. We must wait + * for the command to complete. */ + trigger_unconfig_fr(dev); + + lock_adapter_irq(&wandev->lock, &smp_flags); + wandev->new_if_cnt--; + unlock_adapter_irq(&wandev->lock, &smp_flags); + + return 0; +} + + +/*===================================================================== + * disable_comm + * + * Description: + * Disable communications. + * This code runs in shutdown (sdlamain.c) + * under critical flag. Therefore it is not + * necessary to set a critical flag here + * + * Usage: + * Commnunications are disabled only on a card + * shutdown. + */ + +static void disable_comm (sdla_t *card) +{ + printk(KERN_INFO "%s: Disabling Communications!\n", + card->devname); + fr_comm_disable(card); +} + +/****** WANPIPE-specific entry points ***************************************/ + +/*============================================================================ + * Execute adapter interface command. + */ +static int wpf_exec (struct sdla* card, void* u_cmd, void* u_data) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err, len; + fr_cmd_t cmd; + + if(copy_from_user((void*)&cmd, u_cmd, sizeof(cmd))) + return -EFAULT; + + /* execute command */ + do + { + memcpy(&mbox->cmd, &cmd, sizeof(cmd)); + + if (cmd.length){ + if( copy_from_user((void*)&mbox->data, u_data, cmd.length)) + return -EFAULT; + } + + if (sdla_exec(mbox)) + err = mbox->cmd.result; + + else return -EIO; + + } while (err && retry-- && fr_event(card, err, mbox)); + + /* return result */ + if (copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(fr_cmd_t))) + return -EFAULT; + + len = mbox->cmd.length; + + if (len && u_data && !copy_to_user(u_data, (void*)&mbox->data, len)) + return -EFAULT; + return 0; +} + +/****** Network Device Interface ********************************************/ + +/*============================================================================ + * Initialize Linux network interface. + * + * This routine is called only once for each interface, during Linux network + * interface registration. Returning anything but zero will fail interface + * registration. + */ +static int if_init(struct net_device* dev) +{ + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + struct wan_device* wandev = &card->wandev; + + /* Initialize device driver entry points */ + dev->open = &if_open; + dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = &if_rebuild_hdr; + dev->hard_start_xmit = &if_send; + dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + if (chan->common.usedby == WANPIPE || chan->common.usedby == API){ + + /* Initialize media-specific parameters */ + if (chan->true_if_encoding){ + dev->type = ARPHRD_DLCI; /* This breaks tcpdump */ + }else{ + dev->type = ARPHRD_PPP; /* ARP h/w type */ + } + + dev->flags |= IFF_POINTOPOINT; + dev->flags |= IFF_NOARP; + + /* Enable Multicast addressing */ + if (chan->mc == WANOPT_YES){ + dev->flags |= IFF_MULTICAST; + } + + dev->mtu = wandev->mtu - FR_HEADER_LEN; + /* For an API, the maximum number of bytes that the stack will pass + to the driver is (dev->mtu + dev->hard_header_len). So, adjust the + mtu so that a frame of maximum size can be transmitted by the API. + */ + if(chan->common.usedby == API) { + dev->mtu += (sizeof(api_tx_hdr_t) - FR_HEADER_LEN); + } + + dev->hard_header_len = FR_HEADER_LEN;/* media header length */ + dev->addr_len = 2; /* hardware address length */ + *(unsigned short*)dev->dev_addr = htons(chan->dlci); + + /* Set transmit buffer queue length */ + dev->tx_queue_len = 100; + + }else{ + + /* Setup the interface for Bridging */ + int hw_addr=0; + ether_setup(dev); + + /* Use a random number to generate the MAC address */ + memcpy(dev->dev_addr, "\xFE\xFC\x00\x00\x00\x00", 6); + get_random_bytes(&hw_addr, sizeof(hw_addr)); + *(int *)(dev->dev_addr + 2) += hw_addr; + } + + /* Initialize hardware parameters (just for reference) */ + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + dev->mem_start = wandev->maddr; + dev->mem_end = wandev->maddr + wandev->msize - 1; + SET_MODULE_OWNER(dev); + + return 0; +} + +/*============================================================================ + * Open network interface. + * o if this is the first open, then enable communications and interrupts. + * o prevent module from unloading by incrementing use count + * + * Return 0 if O.k. or errno. + */ +static int if_open(struct net_device* dev) +{ + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + int err = 0; + struct timeval tv; + + if (netif_running(dev)) + return -EBUSY; + + /* Initialize the task queue */ + chan->tq_working=0; + + INIT_WORK(&chan->common.wanpipe_work, (void *)fr_bh, dev); + + /* Allocate and initialize BH circular buffer */ + chan->bh_head = kmalloc((sizeof(bh_data_t)*MAX_BH_BUFF),GFP_ATOMIC); + memset(chan->bh_head,0,(sizeof(bh_data_t)*MAX_BH_BUFF)); + atomic_set(&chan->bh_buff_used, 0); + + netif_start_queue(dev); + + wanpipe_open(card); + do_gettimeofday( &tv ); + chan->router_start_time = tv.tv_sec; + + if (test_bit(0,&chan->config_dlci)){ + trigger_config_fr (card); + }else if (chan->inarp == INARP_REQUEST){ + trigger_fr_arp(dev); + } + + return err; +} + +/*============================================================================ + * Close network interface. + * o if this is the last open, then disable communications and interrupts. + * o reset flags. + */ +static int if_close(struct net_device* dev) +{ + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + + if (chan->inarp == INARP_CONFIGURED) { + chan->inarp = INARP_REQUEST; + } + + netif_stop_queue(dev); + wanpipe_close(card); + + return 0; +} + +/*============================================================================ + * Re-build media header. + * + * Return: 1 physical address resolved. + * 0 physical address not resolved + */ +static int if_rebuild_hdr (struct sk_buff* skb) +{ + struct net_device *dev = skb->dev; + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + + printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", + card->devname, dev->name); + return 1; +} + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout(struct net_device *dev) +{ + fr_channel_t* chan = dev->priv; + sdla_t *card = chan->card; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + chan->drvstats_if_send.if_send_tbusy++; + ++chan->ifstats.collisions; + + printk (KERN_INFO "%s: Transmit timed out on %s\n", + card->devname, dev->name); + chan->drvstats_if_send.if_send_tbusy_timeout++; + netif_wake_queue (dev); + +} + + +/*============================================================================ + * Send a packet on a network interface. + * o set tbusy flag (marks start of the transmission) to block a timer-based + * transmit from overlapping. + * o set critical flag when accessing board. + * o check link state. If link is not up, then drop the packet. + * o check channel status. If it's down then initiate a call. + * o pass a packet to corresponding WAN device. + * o free socket buffer + * + * Return: 0 complete (socket buffer must be freed) + * non-0 packet may be re-transmitted (tbusy must be set) + * + * Notes: + * 1. This routine is called either by the protocol stack or by the "net + * bottom half" (with interrupts enabled). + * + * 2. Using netif_start_queue() and netif_stop_queue() + * will inhibit further transmit requests from the protocol stack + * and can be used for flow control with protocol layer. + */ +static int if_send(struct sk_buff* skb, struct net_device* dev) +{ + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + int err; + unsigned char *sendpacket; + fr508_flags_t* adptr_flags = card->flags; + int udp_type; + long delay_tx_queued = 0; + unsigned long smp_flags=0; + unsigned char attr = 0; + + chan->drvstats_if_send.if_send_entry++; + + netif_stop_queue(dev); + + if (skb == NULL) { + /* if we get here, some higher layer thinks we've missed an + * tx-done interrupt. + */ + printk(KERN_INFO "%s: interface %s got kicked!\n", + card->devname, dev->name); + chan->drvstats_if_send.if_send_skb_null ++; + + netif_wake_queue(dev); + return 0; + } + + /* If a peripheral task is running just drop packets */ + if (test_bit(PERI_CRIT, &card->wandev.critical)){ + + printk(KERN_INFO "%s: Critical in if_send(): Peripheral running!\n", + card->devname); + + dev_kfree_skb_any(skb); + netif_start_queue(dev); + return 0; + } + + /* We must set the 'tbusy' flag if we already have a packet queued for + transmission in the transmit interrupt handler. However, we must + ensure that the transmit interrupt does not reset the 'tbusy' flag + just before we set it, as this will result in a "transmit timeout". + */ + set_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical); + if(chan->transmit_length) { + netif_stop_queue(dev); + chan->tick_counter = jiffies; + clear_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical); + return 1; + } + clear_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical); + + /* Move the if_header() code to here. By inserting frame + * relay header in if_header() we would break the + * tcpdump and other packet sniffers */ + chan->fr_header_len = setup_fr_header(skb,dev,chan->common.usedby); + if (chan->fr_header_len < 0 ){ + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + + dev_kfree_skb_any(skb); + netif_start_queue(dev); + return 0; + } + + sendpacket = skb->data; + + udp_type = udp_pkt_type(skb, card); + + if(udp_type != UDP_INVALID_TYPE) { + if(store_udp_mgmt_pkt(udp_type, UDP_PKT_FRM_STACK, card, skb, + chan->dlci)) { + adptr_flags->imask |= FR_INTR_TIMER; + if (udp_type == UDP_FPIPE_TYPE){ + chan->drvstats_if_send. + if_send_PIPE_request ++; + } + } + netif_start_queue(dev); + return 0; + } + + //FIXME: can we do better than sendpacket[2]? + if ((chan->common.usedby == WANPIPE) && (sendpacket[2] == 0x45)) { + + /* check to see if the source IP address is a broadcast or */ + /* multicast IP address */ + if(chk_bcast_mcast_addr(card, dev, skb)){ + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + dev_kfree_skb_any(skb); + netif_start_queue(dev); + return 0; + } + } + + + /* Lock the S514/S508 card: SMP Supported */ + s508_s514_lock(card,&smp_flags); + + if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) { + + chan->drvstats_if_send.if_send_critical_non_ISR ++; + chan->ifstats.tx_dropped ++; + printk(KERN_INFO "%s Critical in IF_SEND: if_send() already running!\n", + card->devname); + goto if_send_start_and_exit; + } + + /* API packet check: minimum packet size must be greater than + * 16 byte API header */ + if((chan->common.usedby == API) && (skb->len <= sizeof(api_tx_hdr_t))) { + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + + + goto if_send_start_and_exit; + + }else{ + /* During API transmission, get rid of the API header */ + if (chan->common.usedby == API) { + api_tx_hdr_t* api_tx_hdr; + api_tx_hdr = (api_tx_hdr_t*)&skb->data[0x00]; + attr = api_tx_hdr->attr; + skb_pull(skb,sizeof(api_tx_hdr_t)); + } + } + + if (card->wandev.state != WAN_CONNECTED) { + chan->drvstats_if_send.if_send_wan_disconnected ++; + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + + } else if (chan->common.state != WAN_CONNECTED) { + chan->drvstats_if_send.if_send_dlci_disconnected ++; + + /* Update the DLCI state in timer interrupt */ + card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE_STATE; + adptr_flags->imask |= FR_INTR_TIMER; + + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + + } else if (!is_tx_ready(card, chan)) { + /* No tx buffers available, store for delayed transmit */ + if (!setup_for_delayed_transmit(dev, skb)){ + set_bit(1,&delay_tx_queued); + } + chan->drvstats_if_send.if_send_no_bfrs++; + + } else if (!skb->protocol) { + /* No protocols drop packet */ + chan->drvstats_if_send.if_send_protocol_error ++; + ++card->wandev.stats.tx_errors; + + } else if (test_bit(ARP_CRIT,&card->wandev.critical)){ + /* We are trying to send an ARP Packet, block IP data until + * ARP is sent */ + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + + } else { + //FIXME: IPX is not implemented in this version of Frame Relay ? + if((chan->common.usedby == WANPIPE) && + sendpacket[1] == 0x00 && + sendpacket[2] == 0x80 && + sendpacket[6] == 0x81 && + sendpacket[7] == 0x37) { + + if( chan->enable_IPX ) { + switch_net_numbers(sendpacket, + chan->network_number, 0); + } else { + //FIXME: Take this out when IPX is fixed + printk(KERN_INFO + "%s: WARNING: Unsupported IPX data in send, packet dropped\n", + card->devname); + } + + }else{ + err = fr_send_data_header(card, chan->dlci, attr, skb->len, skb->data, chan->fr_header_len); + if (err) { + switch(err) { + case FRRES_CIR_OVERFLOW: + case FRRES_BUFFER_OVERFLOW: + if (!setup_for_delayed_transmit(dev, skb)){ + set_bit(1,&delay_tx_queued); + } + chan->drvstats_if_send. + if_send_adptr_bfrs_full ++; + break; + + case FRRES_TOO_LONG: + if (net_ratelimit()){ + printk(KERN_INFO + "%s: Error: Frame too long, transmission failed %i\n", + card->devname, (unsigned int)skb->len); + } + /* Drop down to default */ + default: + chan->drvstats_if_send. + if_send_dlci_disconnected ++; + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + break; + } + } else { + chan->drvstats_if_send. + if_send_bfr_passed_to_adptr++; + ++chan->ifstats.tx_packets; + ++card->wandev.stats.tx_packets; + + chan->ifstats.tx_bytes += skb->len; + card->wandev.stats.tx_bytes += skb->len; + dev->trans_start = jiffies; + } + } + } + +if_send_start_and_exit: + + netif_start_queue(dev); + + /* If we queued the packet for transmission, we must not + * deallocate it. The packet is unlinked from the IP stack + * not copied. Therefore, we must keep the original packet */ + if (!test_bit(1,&delay_tx_queued)) { + dev_kfree_skb_any(skb); + }else{ + adptr_flags->imask |= FR_INTR_TXRDY; + card->u.f.tx_interrupts_pending ++; + } + + clear_bit(SEND_CRIT, (void*)&card->wandev.critical); + + s508_s514_unlock(card,&smp_flags); + + return 0; +} + + + +/*============================================================================ + * Setup so that a frame can be transmitted on the occurrence of a transmit + * interrupt. + */ +static int setup_for_delayed_transmit(struct net_device* dev, + struct sk_buff *skb) +{ + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + fr_dlci_interface_t* dlci_interface; + int len = skb->len; + + /* Check that the dlci is properly configured, + * before using tx interrupt */ + if (!chan->dlci_int_interface){ + if (net_ratelimit()){ + printk(KERN_INFO + "%s: ERROR on DLCI %i: Not configured properly !\n", + card->devname, chan->dlci); + printk(KERN_INFO "%s: Please contact Sangoma Technologies\n", + card->devname); + } + return 1; + } + + dlci_interface = chan->dlci_int_interface; + + if(chan->transmit_length) { + printk(KERN_INFO "%s: Big mess in setup_for_del...\n", + card->devname); + return 1; + } + + if(len > FR_MAX_NO_DATA_BYTES_IN_FRAME) { + //FIXME: increment some statistic */ + return 1; + } + + chan->transmit_length = len; + chan->delay_skb = skb; + + dlci_interface->gen_interrupt |= FR_INTR_TXRDY; + dlci_interface->packet_length = len; + + /* Turn on TX interrupt at the end of if_send */ + return 0; +} + + +/*============================================================================ + * Check to see if the packet to be transmitted contains a broadcast or + * multicast source IP address. + * Return 0 if not broadcast/multicast address, otherwise return 1. + */ + +static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, + struct sk_buff *skb) +{ + u32 src_ip_addr; + u32 broadcast_ip_addr = 0; + struct in_device *in_dev; + fr_channel_t* chan = dev->priv; + + /* read the IP source address from the outgoing packet */ + src_ip_addr = *(u32 *)(skb->data + 14); + + /* read the IP broadcast address for the device */ + in_dev = dev->ip_ptr; + if(in_dev != NULL) { + struct in_ifaddr *ifa= in_dev->ifa_list; + if(ifa != NULL) + broadcast_ip_addr = ifa->ifa_broadcast; + else + return 0; + } + + /* check if the IP Source Address is a Broadcast address */ + if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) { + printk(KERN_INFO + "%s: Broadcast Source Address silently discarded\n", + card->devname); + return 1; + } + + /* check if the IP Source Address is a Multicast address */ + if((chan->mc == WANOPT_NO) && (ntohl(src_ip_addr) >= 0xE0000001) && + (ntohl(src_ip_addr) <= 0xFFFFFFFE)) { + printk(KERN_INFO + "%s: Multicast Source Address silently discarded\n", + card->devname); + return 1; + } + + return 0; +} + +/*============================================================================ + * Reply to UDP Management system. + * Return nothing. + */ +static int reply_udp( unsigned char *data, unsigned int mbox_len ) +{ + unsigned short len, udp_length, temp, ip_length; + unsigned long ip_temp; + int even_bound = 0; + + + fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)data; + + /* Set length of packet */ + len = //sizeof(fr_encap_hdr_t)+ + sizeof(ip_pkt_t)+ + sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + + /* fill in UDP reply */ + fr_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; + + /* fill in UDP length */ + udp_length = sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + + /* put it on an even boundary */ + if ( udp_length & 0x0001 ) { + udp_length += 1; + len += 1; + even_bound = 1; + } + + temp = (udp_length<<8)|(udp_length>>8); + fr_udp_pkt->udp_pkt.udp_length = temp; + + /* swap UDP ports */ + temp = fr_udp_pkt->udp_pkt.udp_src_port; + fr_udp_pkt->udp_pkt.udp_src_port = + fr_udp_pkt->udp_pkt.udp_dst_port; + fr_udp_pkt->udp_pkt.udp_dst_port = temp; + + + + /* add UDP pseudo header */ + temp = 0x1100; + *((unsigned short *) + (fr_udp_pkt->data+mbox_len+even_bound)) = temp; + temp = (udp_length<<8)|(udp_length>>8); + *((unsigned short *) + (fr_udp_pkt->data+mbox_len+even_bound+2)) = temp; + + /* calculate UDP checksum */ + fr_udp_pkt->udp_pkt.udp_checksum = 0; + + fr_udp_pkt->udp_pkt.udp_checksum = + calc_checksum(&data[UDP_OFFSET/*+sizeof(fr_encap_hdr_t)*/], + udp_length+UDP_OFFSET); + + /* fill in IP length */ + ip_length = udp_length + sizeof(ip_pkt_t); + temp = (ip_length<<8)|(ip_length>>8); + fr_udp_pkt->ip_pkt.total_length = temp; + + /* swap IP addresses */ + ip_temp = fr_udp_pkt->ip_pkt.ip_src_address; + fr_udp_pkt->ip_pkt.ip_src_address = + fr_udp_pkt->ip_pkt.ip_dst_address; + fr_udp_pkt->ip_pkt.ip_dst_address = ip_temp; + + + /* fill in IP checksum */ + fr_udp_pkt->ip_pkt.hdr_checksum = 0; + fr_udp_pkt->ip_pkt.hdr_checksum = + calc_checksum(&data[/*sizeof(fr_encap_hdr_t)*/0], + sizeof(ip_pkt_t)); + + return len; +} /* reply_udp */ + +unsigned short calc_checksum (char *data, int len) +{ + unsigned short temp; + unsigned long sum=0; + int i; + + for( i = 0; i > 16 ) { + sum = (sum & 0xffffUL) + (sum >> 16); + } + + temp = (unsigned short)sum; + temp = ~temp; + + if( temp == 0 ) + temp = 0xffff; + + return temp; +} + +/* + If incoming is 0 (outgoing)- if the net numbers is ours make it 0 + if incoming is 1 - if the net number is 0 make it ours + +*/ +static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming) +{ + unsigned long pnetwork_number; + + pnetwork_number = (unsigned long)((sendpacket[14] << 24) + + (sendpacket[15] << 16) + (sendpacket[16] << 8) + + sendpacket[17]); + + if (!incoming) { + /* If the destination network number is ours, make it 0 */ + if( pnetwork_number == network_number) { + sendpacket[14] = sendpacket[15] = sendpacket[16] = + sendpacket[17] = 0x00; + } + } else { + /* If the incoming network is 0, make it ours */ + if( pnetwork_number == 0) { + sendpacket[14] = (unsigned char)(network_number >> 24); + sendpacket[15] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[16] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[17] = (unsigned char)(network_number & + 0x000000FF); + } + } + + + pnetwork_number = (unsigned long)((sendpacket[26] << 24) + + (sendpacket[27] << 16) + (sendpacket[28] << 8) + + sendpacket[29]); + + if( !incoming ) { + /* If the source network is ours, make it 0 */ + if( pnetwork_number == network_number) { + sendpacket[26] = sendpacket[27] = sendpacket[28] = + sendpacket[29] = 0x00; + } + } else { + /* If the source network is 0, make it ours */ + if( pnetwork_number == 0 ) { + sendpacket[26] = (unsigned char)(network_number >> 24); + sendpacket[27] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[28] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[29] = (unsigned char)(network_number & + 0x000000FF); + } + } +} /* switch_net_numbers */ + +/*============================================================================ + * Get ethernet-style interface statistics. + * Return a pointer to struct enet_statistics. + */ +static struct net_device_stats *if_stats(struct net_device *dev) +{ + fr_channel_t* chan = dev->priv; + + if(chan == NULL) + return NULL; + + return &chan->ifstats; +} + +/****** Interrupt Handlers **************************************************/ + +/*============================================================================ + * fr_isr: S508 frame relay interrupt service routine. + * + * Description: + * Frame relay main interrupt service route. This + * function check the interrupt type and takes + * the appropriate action. + */ +static void fr_isr (sdla_t* card) +{ + fr508_flags_t* flags = card->flags; + char *ptr = &flags->iflag; + int i,err; + fr_mbox_t* mbox = card->mbox; + + /* This flag prevents nesting of interrupts. See sdla_isr() routine + * in sdlamain.c. */ + card->in_isr = 1; + + ++card->statistics.isr_entry; + + + /* All peripheral (configuraiton, re-configuration) events + * take presidence over the ISR. Thus, retrigger */ + if (test_bit(PERI_CRIT, (void*)&card->wandev.critical)) { + ++card->statistics.isr_already_critical; + goto fr_isr_exit; + } + + if(card->hw.type != SDLA_S514) { + if (test_bit(SEND_CRIT, (void*)&card->wandev.critical)) { + printk(KERN_INFO "%s: Critical while in ISR: If Send Running!\n", + card->devname); + ++card->statistics.isr_already_critical; + goto fr_isr_exit; + } + } + + switch (flags->iflag) { + + case FR_INTR_RXRDY: /* receive interrupt */ + ++card->statistics.isr_rx; + rx_intr(card); + break; + + + case FR_INTR_TXRDY: /* transmit interrupt */ + ++ card->statistics.isr_tx; + tx_intr(card); + break; + + case FR_INTR_READY: + Intr_test_counter++; + ++card->statistics.isr_intr_test; + break; + + case FR_INTR_DLC: /* Event interrupt occurred */ + mbox->cmd.command = FR_READ_STATUS; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err) + fr_event(card, err, mbox); + break; + + case FR_INTR_TIMER: /* Timer interrupt */ + timer_intr(card); + break; + + default: + ++card->statistics.isr_spurious; + spur_intr(card); + printk(KERN_INFO "%s: Interrupt Type 0x%02X!\n", + card->devname, flags->iflag); + + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + for(i = 0; i < 8; i ++) + printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); + printk(KERN_INFO "\n"); + + break; + } + +fr_isr_exit: + + card->in_isr = 0; + flags->iflag = 0; + return; +} + + + +/*=========================================================== + * rx_intr Receive interrupt handler. + * + * Description + * Upon receiveing an interrupt: + * 1. Check that the firmware is in sync with + * the driver. + * 2. Find an appropriate network interface + * based on the received dlci number. + * 3. Check that the netowrk interface exists + * and that it's setup properly. + * 4. Copy the data into an skb buffer. + * 5. Check the packet type and take + * appropriate acton: UPD, API, ARP or Data. + */ + +static void rx_intr (sdla_t* card) +{ + fr_rx_buf_ctl_t* frbuf = card->rxmb; + fr508_flags_t* flags = card->flags; + fr_channel_t* chan; + char *ptr = &flags->iflag; + struct sk_buff* skb; + struct net_device* dev; + void* buf; + unsigned dlci, len, offs, len_incl_hdr; + int i, udp_type; + + + /* Check that firmware buffers are in sync */ + if (frbuf->flag != 0x01) { + + printk(KERN_INFO + "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", + card->devname, (unsigned)frbuf, frbuf->flag); + + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + for(i = 0; i < 8; i ++) + printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); + printk(KERN_INFO "\n"); + + ++card->statistics.rx_intr_corrupt_rx_bfr; + + /* Bug Fix: Mar 6 2000 + * If we get a corrupted mailbox, it means that driver + * is out of sync with the firmware. There is no recovery. + * If we don't turn off all interrupts for this card + * the machine will crash. + */ + printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname); + printk(KERN_INFO "Please contact Sangoma Technologies !\n"); + fr_set_intr_mode(card, 0, 0, 0); + return; + } + + len = frbuf->length; + dlci = frbuf->dlci; + offs = frbuf->offset; + + /* Find the network interface for this packet */ + dev = find_channel(card, dlci); + + + /* Check that the network interface is active and + * properly setup */ + if (dev == NULL) { + if( net_ratelimit()) { + printk(KERN_INFO "%s: received data on unconfigured DLCI %d!\n", + card->devname, dlci); + } + ++card->statistics.rx_intr_on_orphaned_DLCI; + ++card->wandev.stats.rx_dropped; + goto rx_done; + } + + if ((chan = dev->priv) == NULL){ + if( net_ratelimit()) { + printk(KERN_INFO "%s: received data on unconfigured DLCI %d!\n", + card->devname, dlci); + } + ++card->statistics.rx_intr_on_orphaned_DLCI; + ++card->wandev.stats.rx_dropped; + goto rx_done; + } + + skb = dev_alloc_skb(len); + + if (!netif_running(dev) || (skb == NULL)){ + + ++chan->ifstats.rx_dropped; + + if(skb == NULL) { + if (net_ratelimit()) { + printk(KERN_INFO + "%s: no socket buffers available!\n", + card->devname); + } + chan->drvstats_rx_intr.rx_intr_no_socket ++; + } + + if (!netif_running(dev)){ + chan->drvstats_rx_intr. + rx_intr_dev_not_started ++; + if (skb){ + dev_kfree_skb_any(skb); + } + } + goto rx_done; + } + + /* Copy data from the board into the socket buffer */ + if ((offs + len) > card->u.f.rx_top + 1) { + unsigned tmp = card->u.f.rx_top - offs + 1; + + buf = skb_put(skb, tmp); + sdla_peek(&card->hw, offs, buf, tmp); + offs = card->u.f.rx_base; + len -= tmp; + } + + buf = skb_put(skb, len); + sdla_peek(&card->hw, offs, buf, len); + + + /* We got the packet from the bard. + * Check the packet type and take appropriate action */ + + udp_type = udp_pkt_type( skb, card ); + + if(udp_type != UDP_INVALID_TYPE) { + + /* UDP Debug packet received, store the + * packet and handle it in timer interrupt */ + + skb_pull(skb, 1); + if (wanrouter_type_trans(skb, dev)){ + if(store_udp_mgmt_pkt(udp_type,UDP_PKT_FRM_NETWORK,card,skb,dlci)){ + + flags->imask |= FR_INTR_TIMER; + + if (udp_type == UDP_FPIPE_TYPE){ + ++chan->drvstats_rx_intr.rx_intr_PIPE_request; + } + } + } + + }else if (chan->common.usedby == API) { + + /* We are in API mode. + * Add an API header to the RAW packet + * and queue it into a circular buffer. + * Then kick the fr_bh() bottom half handler */ + + api_rx_hdr_t* api_rx_hdr; + chan->drvstats_rx_intr.rx_intr_bfr_passed_to_stack ++; + chan->ifstats.rx_packets ++; + card->wandev.stats.rx_packets ++; + + chan->ifstats.rx_bytes += skb->len; + card->wandev.stats.rx_bytes += skb->len; + + skb_push(skb, sizeof(api_rx_hdr_t)); + api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00]; + api_rx_hdr->attr = frbuf->attr; + api_rx_hdr->time_stamp = frbuf->tmstamp; + + skb->protocol = htons(ETH_P_IP); + skb->mac.raw = skb->data; + skb->dev = dev; + skb->pkt_type = WAN_PACKET_DATA; + + bh_enqueue(dev, skb); + + trigger_fr_bh(chan); + + }else if (handle_IPXWAN(skb->data,chan->name,chan->enable_IPX, chan->network_number)){ + + //FIXME: Frame Relay IPX is not supported, Yet ! + //if (chan->enable_IPX) { + // fr_send(card, dlci, 0, skb->len,skb->data); + //} + dev_kfree_skb_any(skb); + + } else if (is_arp(skb->data)) { + + /* ARP support enabled Mar 16 2000 + * Process incoming ARP reply/request, setup + * dynamic routes. */ + + if (process_ARP((arphdr_1490_t *)skb->data, card, dev)) { + if (net_ratelimit()){ + printk (KERN_INFO + "%s: Error processing ARP Packet.\n", + card->devname); + } + } + dev_kfree_skb_any(skb); + + } else if (skb->data[0] != 0x03) { + + if (net_ratelimit()) { + printk(KERN_INFO "%s: Non IETF packet discarded.\n", + card->devname); + } + dev_kfree_skb_any(skb); + + } else { + + len_incl_hdr = skb->len; + /* Decapsulate packet and pass it up the + protocol stack */ + skb->dev = dev; + + if (chan->common.usedby == BRIDGE || chan->common.usedby == BRIDGE_NODE){ + + /* Make sure it's an Ethernet frame, otherwise drop it */ + if (!memcmp(skb->data, "\x03\x00\x80\x00\x80\xC2\x00\x07", 8)) { + skb_pull(skb, 8); + skb->protocol=eth_type_trans(skb,dev); + }else{ + ++chan->drvstats_rx_intr.rx_intr_bfr_not_passed_to_stack; + ++chan->ifstats.rx_errors; + ++card->wandev.stats.rx_errors; + goto rx_done; + } + }else{ + + /* remove hardware header */ + buf = skb_pull(skb, 1); + + if (!wanrouter_type_trans(skb, dev)) { + + /* can't decapsulate packet */ + dev_kfree_skb_any(skb); + + ++chan->drvstats_rx_intr.rx_intr_bfr_not_passed_to_stack; + ++chan->ifstats.rx_errors; + ++card->wandev.stats.rx_errors; + goto rx_done; + } + skb->mac.raw = skb->data; + } + + + /* Send a packet up the IP stack */ + skb->dev->last_rx = jiffies; + netif_rx(skb); + ++chan->drvstats_rx_intr.rx_intr_bfr_passed_to_stack; + ++chan->ifstats.rx_packets; + ++card->wandev.stats.rx_packets; + + chan->ifstats.rx_bytes += len_incl_hdr; + card->wandev.stats.rx_bytes += len_incl_hdr; + } + +rx_done: + + /* Release buffer element and calculate a pointer to the next one */ + frbuf->flag = 0; + card->rxmb = ++frbuf; + if ((void*)frbuf > card->u.f.rxmb_last) + card->rxmb = card->u.f.rxmb_base; + +} + +/*================================================================== + * tx_intr: Transmit interrupt handler. + * + * Rationale: + * If the board is busy transmitting, if_send() will + * buffers a single packet and turn on + * the tx interrupt. Tx interrupt will be called + * by the board, once the firmware can send more + * data. Thus, no polling is required. + * + * Description: + * Tx interrupt is called for each + * configured dlci channel. Thus: + * 1. Obtain the netowrk interface based on the + * dlci number. + * 2. Check that network interface is up and + * properly setup. + * 3. Check for a buffered packet. + * 4. Transmit the packet. + * 5. If we are in WANPIPE mode, mark the + * NET_BH handler. + * 6. If we are in API mode, kick + * the AF_WANPIPE socket for more data. + * + */ +static void tx_intr(sdla_t *card) +{ + fr508_flags_t* flags = card->flags; + fr_tx_buf_ctl_t* bctl; + struct net_device* dev; + fr_channel_t* chan; + + if(card->hw.type == SDLA_S514){ + bctl = (void*)(flags->tse_offs + card->hw.dpmbase); + }else{ + bctl = (void*)(flags->tse_offs - FR_MB_VECTOR + + card->hw.dpmbase); + } + + /* Find the structure and make it unbusy */ + dev = find_channel(card, flags->dlci); + if (dev == NULL){ + printk(KERN_INFO "NO DEV IN TX Interrupt\n"); + goto end_of_tx_intr; + } + + if ((chan = dev->priv) == NULL){ + printk(KERN_INFO "NO CHAN IN TX Interrupt\n"); + goto end_of_tx_intr; + } + + if(!chan->transmit_length || !chan->delay_skb) { + printk(KERN_INFO "%s: tx int error - transmit length zero\n", + card->wandev.name); + goto end_of_tx_intr; + } + + /* If the 'if_send()' procedure is currently checking the 'tbusy' + status, then we cannot transmit. Instead, we configure the microcode + so as to re-issue this transmit interrupt at a later stage. + */ + if (test_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical)) { + + fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface; + bctl->flag = 0xA0; + dlci_interface->gen_interrupt |= FR_INTR_TXRDY; + return; + + }else{ + bctl->dlci = flags->dlci; + bctl->length = chan->transmit_length+chan->fr_header_len; + sdla_poke(&card->hw, + fr_send_hdr(card,bctl->dlci,bctl->offset), + chan->delay_skb->data, + chan->delay_skb->len); + bctl->flag = 0xC0; + + ++chan->ifstats.tx_packets; + ++card->wandev.stats.tx_packets; + chan->ifstats.tx_bytes += chan->transmit_length; + card->wandev.stats.tx_bytes += chan->transmit_length; + + /* We must free an sk buffer, which we used + * for delayed transmission; Otherwise, the sock + * will run out of memory */ + dev_kfree_skb_any(chan->delay_skb); + + chan->delay_skb = NULL; + chan->transmit_length = 0; + + dev->trans_start = jiffies; + + if (netif_queue_stopped(dev)){ + /* If using API, than wakeup socket BH handler */ + if (chan->common.usedby == API){ + netif_start_queue(dev); + wakeup_sk_bh(dev); + }else{ + netif_wake_queue(dev); + } + } + } + +end_of_tx_intr: + + /* if any other interfaces have transmit interrupts pending, + * do not disable the global transmit interrupt */ + if(!(-- card->u.f.tx_interrupts_pending)) + flags->imask &= ~FR_INTR_TXRDY; + + +} + + +/*============================================================================ + * timer_intr: Timer interrupt handler. + * + * Rationale: + * All commans must be executed within the timer + * interrupt since no two commands should execute + * at the same time. + * + * Description: + * The timer interrupt is used to: + * 1. Processing udp calls from 'fpipemon'. + * 2. Processing update calls from /proc file system + * 3. Reading board-level statistics for + * updating the proc file system. + * 4. Sending inverse ARP request packets. + * 5. Configure a dlci/channel. + * 6. Unconfigure a dlci/channel. (Node only) + */ + +static void timer_intr(sdla_t *card) +{ + fr508_flags_t* flags = card->flags; + + /* UDP Debuging: fpipemon call */ + if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_UDP) { + if(card->u.f.udp_type == UDP_FPIPE_TYPE) { + if(process_udp_mgmt_pkt(card)) { + card->u.f.timer_int_enabled &= + ~TMR_INT_ENABLED_UDP; + } + } + } + + /* /proc update call : triggered from update() */ + if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_UPDATE) { + fr_get_err_stats(card); + fr_get_stats(card); + card->u.f.update_comms_stats = 0; + card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE; + } + + /* Update the channel state call. This is call is + * triggered by if_send() function */ + if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_UPDATE_STATE){ + struct net_device *dev; + if (card->wandev.state == WAN_CONNECTED){ + for (dev = card->wandev.dev; dev; + dev = *((struct net_device **)dev->priv)){ + fr_channel_t *chan = dev->priv; + if (chan->common.state != WAN_CONNECTED){ + update_chan_state(dev); + } + } + } + card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE_STATE; + } + + /* configure a dlci/channel */ + if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_CONFIG){ + config_fr(card); + card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG; + } + + /* unconfigure a dlci/channel */ + if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_UNCONFIG){ + unconfig_fr(card); + card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UNCONFIG; + } + + + /* Transmit ARP packets */ + if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_ARP){ + int i=0; + struct net_device *dev; + + if (card->u.f.arp_dev == NULL) + card->u.f.arp_dev = card->wandev.dev; + + dev = card->u.f.arp_dev; + + for (;;){ + + fr_channel_t *chan = dev->priv; + + /* If the interface is brought down cancel sending In-ARPs */ + if (!(dev->flags&IFF_UP)){ + clear_bit(0,&chan->inarp_ready); + } + + if (test_bit(0,&chan->inarp_ready)){ + + if (check_tx_status(card,dev)){ + set_bit(ARP_CRIT,&card->wandev.critical); + break; + } + + if (!send_inarp_request(card,dev)){ + trigger_fr_arp(dev); + chan->inarp_tick = jiffies; + } + + clear_bit(0,&chan->inarp_ready); + dev = move_dev_to_next(card,dev); + break; + } + dev = move_dev_to_next(card,dev); + + if (++i == card->wandev.new_if_cnt){ + card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_ARP; + break; + } + } + card->u.f.arp_dev = dev; + } + + if(!card->u.f.timer_int_enabled) + flags->imask &= ~FR_INTR_TIMER; +} + + +/*============================================================================ + * spur_intr: Spurious interrupt handler. + * + * Description: + * We don't know this interrupt. + * Print a warning. + */ + +static void spur_intr (sdla_t* card) +{ + if (net_ratelimit()){ + printk(KERN_INFO "%s: spurious interrupt!\n", card->devname); + } +} + + +//FIXME: Fix the IPX in next version +/*=========================================================================== + * Return 0 for non-IPXWAN packet + * 1 for IPXWAN packet or IPX is not enabled! + * FIXME: Use a IPX structure here not offsets + */ +static int handle_IPXWAN(unsigned char *sendpacket, + char *devname, unsigned char enable_IPX, + unsigned long network_number) +{ + int i; + + if( sendpacket[1] == 0x00 && sendpacket[2] == 0x80 && + sendpacket[6] == 0x81 && sendpacket[7] == 0x37) { + + /* It's an IPX packet */ + if (!enable_IPX){ + /* Return 1 so we don't pass it up the stack. */ + //FIXME: Take this out when IPX is fixed + if (net_ratelimit()){ + printk (KERN_INFO + "%s: WARNING: Unsupported IPX packet received and dropped\n", + devname); + } + return 1; + } + } else { + /* It's not IPX so return and pass it up the stack. */ + return 0; + } + + if( sendpacket[24] == 0x90 && sendpacket[25] == 0x04){ + /* It's IPXWAN */ + + if( sendpacket[10] == 0x02 && sendpacket[42] == 0x00){ + + /* It's a timer request packet */ + printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n", + devname); + + /* Go through the routing options and answer no to every + * option except Unnumbered RIP/SAP + */ + for(i = 49; sendpacket[i] == 0x00; i += 5){ + /* 0x02 is the option for Unnumbered RIP/SAP */ + if( sendpacket[i + 4] != 0x02){ + sendpacket[i + 1] = 0; + } + } + + /* Skip over the extended Node ID option */ + if( sendpacket[i] == 0x04 ){ + i += 8; + } + + /* We also want to turn off all header compression opt. + */ + for(; sendpacket[i] == 0x80 ;){ + sendpacket[i + 1] = 0; + i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4; + } + + /* Set the packet type to timer response */ + sendpacket[42] = 0x01; + + printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n", + devname); + + } else if( sendpacket[42] == 0x02 ){ + + /* This is an information request packet */ + printk(KERN_INFO + "%s: Received IPXWAN Information Request packet\n", + devname); + + /* Set the packet type to information response */ + sendpacket[42] = 0x03; + + /* Set the router name */ + sendpacket[59] = 'F'; + sendpacket[60] = 'P'; + sendpacket[61] = 'I'; + sendpacket[62] = 'P'; + sendpacket[63] = 'E'; + sendpacket[64] = '-'; + sendpacket[65] = CVHexToAscii(network_number >> 28); + sendpacket[66] = CVHexToAscii((network_number & 0x0F000000)>> 24); + sendpacket[67] = CVHexToAscii((network_number & 0x00F00000)>> 20); + sendpacket[68] = CVHexToAscii((network_number & 0x000F0000)>> 16); + sendpacket[69] = CVHexToAscii((network_number & 0x0000F000)>> 12); + sendpacket[70] = CVHexToAscii((network_number & 0x00000F00)>> 8); + sendpacket[71] = CVHexToAscii((network_number & 0x000000F0)>> 4); + sendpacket[72] = CVHexToAscii(network_number & 0x0000000F); + for(i = 73; i < 107; i+= 1) + { + sendpacket[i] = 0; + } + + printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n", + devname); + } else { + + printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname); + return 0; + } + + /* Set the WNodeID to our network address */ + sendpacket[43] = (unsigned char)(network_number >> 24); + sendpacket[44] = (unsigned char)((network_number & 0x00FF0000) >> 16); + sendpacket[45] = (unsigned char)((network_number & 0x0000FF00) >> 8); + sendpacket[46] = (unsigned char)(network_number & 0x000000FF); + + return 1; + } + + /* If we get here, it's an IPX-data packet so it'll get passed up the + * stack. + * switch the network numbers + */ + switch_net_numbers(sendpacket, network_number ,1); + return 0; +} +/*============================================================================ + * process_route + * + * Rationale: + * If the interface goes down, or we receive an ARP request, + * we have to change the network interface ip addresses. + * This cannot be done within the interrupt. + * + * Description: + * + * This routine is called as a polling routine to dynamically + * add/delete routes negotiated by inverse ARP. It is in this + * "task" because we don't want routes to be added while in + * interrupt context. + * + * Usage: + * This function is called by fr_poll() polling funtion. + */ + +static void process_route(struct net_device *dev) +{ + fr_channel_t *chan = dev->priv; + sdla_t *card = chan->card; + + struct ifreq if_info; + struct sockaddr_in *if_data; + mm_segment_t fs = get_fs(); + u32 ip_tmp; + int err; + + + switch(chan->route_flag){ + + case ADD_ROUTE: + + /* Set remote addresses */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + set_fs(get_ds()); /* get user space block */ + + if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data->sin_addr.s_addr = chan->ip_remote; + if_data->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFDSTADDR, &if_info ); + + set_fs(fs); /* restore old block */ + + if (err) { + printk(KERN_INFO + "%s: Route Add failed. Error: %d\n", + card->devname,err); + printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n", + chan->name, NIPQUAD(chan->ip_remote)); + + }else { + printk(KERN_INFO "%s: Route Added Successfully: %u.%u.%u.%u\n", + card->devname,NIPQUAD(chan->ip_remote)); + chan->route_flag = ROUTE_ADDED; + } + break; + + case REMOVE_ROUTE: + + /* Set remote addresses */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + ip_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP); + + set_fs(get_ds()); /* get user space block */ + + if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data->sin_addr.s_addr = 0; + if_data->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFDSTADDR, &if_info ); + + set_fs(fs); + + if (err) { + printk(KERN_INFO + "%s: Deleting of route failed. Error: %d\n", + card->devname,err); + printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n", + dev->name,NIPQUAD(chan->ip_remote) ); + + } else { + printk(KERN_INFO "%s: Route Removed Sucessfuly: %u.%u.%u.%u\n", + card->devname,NIPQUAD(ip_tmp)); + chan->route_flag = NO_ROUTE; + } + break; + + } /* Case Statement */ + +} + + + +/****** Frame Relay Firmware-Specific Functions *****************************/ + +/*============================================================================ + * Read firmware code version. + * o fill string str with firmware version info. + */ +static int fr_read_version (sdla_t* card, char* str) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + mbox->cmd.command = FR_READ_CODE_VERSION; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err && str) { + int len = mbox->cmd.length; + memcpy(str, mbox->data, len); + str[len] = '\0'; + } + return err; +} + +/*============================================================================ + * Set global configuration. + */ +static int fr_configure (sdla_t* card, fr_conf_t *conf) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int dlci_num = card->u.f.dlci_num; + int err, i; + + do + { + memcpy(mbox->data, conf, sizeof(fr_conf_t)); + + if (dlci_num) for (i = 0; i < dlci_num; ++i) + ((fr_conf_t*)mbox->data)->dlci[i] = + card->u.f.node_dlci[i]; + + mbox->cmd.command = FR_SET_CONFIG; + mbox->cmd.length = + sizeof(fr_conf_t) + dlci_num * sizeof(short); + + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + } while (err && retry-- && fr_event(card, err, mbox)); + + /*NC Oct 12 2000 */ + if (err != CMD_OK){ + printk(KERN_ERR "%s: Frame Relay Configuration Failed: rc=0x%x\n", + card->devname,err); + } + + return err; +} + +/*============================================================================ + * Set DLCI configuration. + */ +static int fr_dlci_configure (sdla_t* card, fr_dlc_conf_t *conf, unsigned dlci) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memcpy(mbox->data, conf, sizeof(fr_dlc_conf_t)); + mbox->cmd.dlci = (unsigned short) dlci; + mbox->cmd.command = FR_SET_CONFIG; + mbox->cmd.length = sizeof(fr_dlc_conf_t); + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry--); + + return err; +} +/*============================================================================ + * Set interrupt mode. + */ +static int fr_set_intr_mode (sdla_t* card, unsigned mode, unsigned mtu, + unsigned short timeout) +{ + fr_mbox_t* mbox = card->mbox; + fr508_intr_ctl_t* ictl = (void*)mbox->data; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(ictl, 0, sizeof(fr508_intr_ctl_t)); + ictl->mode = mode; + ictl->tx_len = mtu; + ictl->irq = card->hw.irq; + + /* indicate timeout on timer */ + if (mode & 0x20) ictl->timeout = timeout; + + mbox->cmd.length = sizeof(fr508_intr_ctl_t); + mbox->cmd.command = FR_SET_INTR_MODE; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + } while (err && retry-- && fr_event(card, err, mbox)); + + return err; +} + +/*============================================================================ + * Enable communications. + */ +static int fr_comm_enable (sdla_t* card) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + mbox->cmd.command = FR_COMM_ENABLE; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + return err; +} + +/*============================================================================ + * fr_comm_disable + * + * Warning: This functin is called by the shutdown() procedure. It is void + * since dev->priv are has already been deallocated and no + * error checking is possible using fr_event() function. + */ +static void fr_comm_disable (sdla_t* card) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do { + mbox->cmd.command = FR_SET_MODEM_STATUS; + mbox->cmd.length = 1; + mbox->data[0] = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry--); + + retry = MAX_CMD_RETRY; + + do + { + mbox->cmd.command = FR_COMM_DISABLE; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry--); + + return; +} + + + +/*============================================================================ + * Get communications error statistics. + */ +static int fr_get_err_stats (sdla_t* card) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + + do + { + mbox->cmd.command = FR_READ_ERROR_STATS; + mbox->cmd.length = 0; + mbox->cmd.dlci = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err) { + fr_comm_stat_t* stats = (void*)mbox->data; + card->wandev.stats.rx_over_errors = stats->rx_overruns; + card->wandev.stats.rx_crc_errors = stats->rx_bad_crc; + card->wandev.stats.rx_missed_errors = stats->rx_aborts; + card->wandev.stats.rx_length_errors = stats->rx_too_long; + card->wandev.stats.tx_aborted_errors = stats->tx_aborts; + + } + + return err; +} + +/*============================================================================ + * Get statistics. + */ +static int fr_get_stats (sdla_t* card) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + + do + { + mbox->cmd.command = FR_READ_STATISTICS; + mbox->cmd.length = 0; + mbox->cmd.dlci = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err) { + fr_link_stat_t* stats = (void*)mbox->data; + card->wandev.stats.rx_frame_errors = stats->rx_bad_format; + card->wandev.stats.rx_dropped = + stats->rx_dropped + stats->rx_dropped2; + } + + return err; +} + +/*============================================================================ + * Add DLCI(s) (Access Node only!). + * This routine will perform the ADD_DLCIs command for the specified DLCI. + */ +static int fr_add_dlci (sdla_t* card, int dlci) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + unsigned short* dlci_list = (void*)mbox->data; + + mbox->cmd.length = sizeof(short); + dlci_list[0] = dlci; + mbox->cmd.command = FR_ADD_DLCI; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + } while (err && retry-- && fr_event(card, err, mbox)); + + return err; +} + +/*============================================================================ + * Activate DLCI(s) (Access Node only!). + * This routine will perform the ACTIVATE_DLCIs command with a DLCI number. + */ +static int fr_activate_dlci (sdla_t* card, int dlci) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + unsigned short* dlci_list = (void*)mbox->data; + + mbox->cmd.length = sizeof(short); + dlci_list[0] = dlci; + mbox->cmd.command = FR_ACTIVATE_DLCI; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + } while (err && retry-- && fr_event(card, err, mbox)); + + return err; +} + +/*============================================================================ + * Delete DLCI(s) (Access Node only!). + * This routine will perform the DELETE_DLCIs command with a DLCI number. + */ +static int fr_delete_dlci (sdla_t* card, int dlci) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + unsigned short* dlci_list = (void*)mbox->data; + + mbox->cmd.length = sizeof(short); + dlci_list[0] = dlci; + mbox->cmd.command = FR_DELETE_DLCI; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + } while (err && retry-- && fr_event(card, err, mbox)); + + return err; +} + + + +/*============================================================================ + * Issue in-channel signalling frame. + */ +static int fr_issue_isf (sdla_t* card, int isf) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + mbox->data[0] = isf; + mbox->cmd.length = 1; + mbox->cmd.command = FR_ISSUE_IS_FRAME; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + return err; +} + + +static unsigned int fr_send_hdr (sdla_t*card, int dlci, unsigned int offset) +{ + struct net_device *dev = find_channel(card,dlci); + fr_channel_t *chan; + + if (!dev || !(chan=dev->priv)) + return offset; + + if (chan->fr_header_len){ + sdla_poke(&card->hw, offset, chan->fr_header, chan->fr_header_len); + } + + return offset+chan->fr_header_len; +} + +/*============================================================================ + * Send a frame on a selected DLCI. + */ +static int fr_send_data_header (sdla_t* card, int dlci, unsigned char attr, int len, + void *buf, unsigned char hdr_len) +{ + fr_mbox_t* mbox = card->mbox + 0x800; + int retry = MAX_CMD_RETRY; + int err; + + do + { + mbox->cmd.dlci = dlci; + mbox->cmd.attr = attr; + mbox->cmd.length = len+hdr_len; + mbox->cmd.command = FR_WRITE; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err) { + fr_tx_buf_ctl_t* frbuf; + + if(card->hw.type == SDLA_S514) + frbuf = (void*)(*(unsigned long*)mbox->data + + card->hw.dpmbase); + else + frbuf = (void*)(*(unsigned long*)mbox->data - + FR_MB_VECTOR + card->hw.dpmbase); + + sdla_poke(&card->hw, fr_send_hdr(card,dlci,frbuf->offset), buf, len); + frbuf->flag = 0x01; + } + + return err; +} + +static int fr_send (sdla_t* card, int dlci, unsigned char attr, int len, + void *buf) +{ + fr_mbox_t* mbox = card->mbox + 0x800; + int retry = MAX_CMD_RETRY; + int err; + + do + { + mbox->cmd.dlci = dlci; + mbox->cmd.attr = attr; + mbox->cmd.length = len; + mbox->cmd.command = FR_WRITE; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err) { + fr_tx_buf_ctl_t* frbuf; + + if(card->hw.type == SDLA_S514) + frbuf = (void*)(*(unsigned long*)mbox->data + + card->hw.dpmbase); + else + frbuf = (void*)(*(unsigned long*)mbox->data - + FR_MB_VECTOR + card->hw.dpmbase); + + sdla_poke(&card->hw, frbuf->offset, buf, len); + frbuf->flag = 0x01; + } + + return err; +} + + +/****** Firmware Asynchronous Event Handlers ********************************/ + +/*============================================================================ + * Main asyncronous event/error handler. + * This routine is called whenever firmware command returns non-zero + * return code. + * + * Return zero if previous command has to be cancelled. + */ +static int fr_event (sdla_t *card, int event, fr_mbox_t* mbox) +{ + fr508_flags_t* flags = card->flags; + char *ptr = &flags->iflag; + int i; + + switch (event) { + + case FRRES_MODEM_FAILURE: + return fr_modem_failure(card, mbox); + + case FRRES_CHANNEL_DOWN: { + struct net_device *dev; + + /* Remove all routes from associated DLCI's */ + for (dev = card->wandev.dev; dev; + dev = *((struct net_device **)dev->priv)) { + fr_channel_t *chan = dev->priv; + if (chan->route_flag == ROUTE_ADDED) { + chan->route_flag = REMOVE_ROUTE; + } + + if (chan->inarp == INARP_CONFIGURED) { + chan->inarp = INARP_REQUEST; + } + + /* If the link becomes disconnected then, + * all channels will be disconnected + * as well. + */ + set_chan_state(dev,WAN_DISCONNECTED); + } + + wanpipe_set_state(card, WAN_DISCONNECTED); + return 1; + } + + case FRRES_CHANNEL_UP: { + struct net_device *dev; + + /* FIXME: Only startup devices that are on the list */ + + for (dev = card->wandev.dev; dev; + dev = *((struct net_device **)dev->priv)) { + + set_chan_state(dev,WAN_CONNECTED); + } + + wanpipe_set_state(card, WAN_CONNECTED); + return 1; + } + + case FRRES_DLCI_CHANGE: + return fr_dlci_change(card, mbox); + + case FRRES_DLCI_MISMATCH: + printk(KERN_INFO "%s: DLCI list mismatch!\n", + card->devname); + return 1; + + case CMD_TIMEOUT: + printk(KERN_ERR "%s: command 0x%02X timed out!\n", + card->devname, mbox->cmd.command); + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + for(i = 0; i < 8; i ++) + printk(KERN_INFO "0x%02X ", *(ptr + 0x18 + i)); + printk(KERN_INFO "\n"); + + break; + + case FRRES_DLCI_INACTIVE: + break; + + case FRRES_CIR_OVERFLOW: + break; + + case FRRES_BUFFER_OVERFLOW: + break; + + default: + printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n" + , card->devname, mbox->cmd.command, event); + } + + return 0; +} + +/*============================================================================ + * Handle modem error. + * + * Return zero if previous command has to be cancelled. + */ +static int fr_modem_failure (sdla_t *card, fr_mbox_t* mbox) +{ + printk(KERN_INFO "%s: physical link down! (modem error 0x%02X)\n", + card->devname, mbox->data[0]); + + switch (mbox->cmd.command){ + case FR_WRITE: + + case FR_READ: + return 0; + } + + return 1; +} + +/*============================================================================ + * Handle DLCI status change. + * + * Return zero if previous command has to be cancelled. + */ +static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox) +{ + dlci_status_t* status = (void*)mbox->data; + int cnt = mbox->cmd.length / sizeof(dlci_status_t); + fr_channel_t *chan; + struct net_device* dev2; + + + for (; cnt; --cnt, ++status) { + + unsigned short dlci= status->dlci; + struct net_device* dev = find_channel(card, dlci); + + if (dev == NULL){ + printk(KERN_INFO + "%s: CPE contains unconfigured DLCI= %d\n", + card->devname, dlci); + + printk(KERN_INFO + "%s: unconfigured DLCI %d reported by network\n" + , card->devname, dlci); + + }else{ + if (status->state == FR_LINK_INOPER) { + printk(KERN_INFO + "%s: DLCI %u is inactive!\n", + card->devname, dlci); + + if (dev && netif_running(dev)) + set_chan_state(dev, WAN_DISCONNECTED); + } + + if (status->state & FR_DLCI_DELETED) { + + printk(KERN_INFO + "%s: DLCI %u has been deleted!\n", + card->devname, dlci); + + if (dev && netif_running(dev)){ + + fr_channel_t *chan = dev->priv; + + if (chan->route_flag == ROUTE_ADDED) { + chan->route_flag = REMOVE_ROUTE; + /* The state change will trigger + * the fr polling routine */ + } + + if (chan->inarp == INARP_CONFIGURED) { + chan->inarp = INARP_REQUEST; + } + + set_chan_state(dev, WAN_DISCONNECTED); + } + + } else if (status->state & FR_DLCI_ACTIVE) { + + chan = dev->priv; + + /* This flag is used for configuring specific + DLCI(s) when they become active. + */ + chan->dlci_configured = DLCI_CONFIG_PENDING; + + set_chan_state(dev, WAN_CONNECTED); + + } + } + } + + for (dev2 = card->wandev.dev; dev2; + dev2 = *((struct net_device **)dev2->priv)){ + + chan = dev2->priv; + + if (chan->dlci_configured == DLCI_CONFIG_PENDING) { + if (fr_init_dlci(card, chan)){ + return 1; + } + } + + } + return 1; +} + + +static int fr_init_dlci (sdla_t *card, fr_channel_t *chan) +{ + fr_dlc_conf_t cfg; + + memset(&cfg, 0, sizeof(cfg)); + + if ( chan->cir_status == CIR_DISABLED) { + + cfg.cir_fwd = cfg.cir_bwd = 16; + cfg.bc_fwd = cfg.bc_bwd = 16; + cfg.conf_flags = 0x0001; + + }else if (chan->cir_status == CIR_ENABLED) { + + cfg.cir_fwd = cfg.cir_bwd = chan->cir; + cfg.bc_fwd = cfg.bc_bwd = chan->bc; + cfg.be_fwd = cfg.be_bwd = chan->be; + cfg.conf_flags = 0x0000; + } + + if (fr_dlci_configure( card, &cfg , chan->dlci)){ + printk(KERN_INFO + "%s: DLCI Configure failed for %d\n", + card->devname, chan->dlci); + return 1; + } + + chan->dlci_configured = DLCI_CONFIGURED; + + /* Read the interface byte mapping into the channel + * structure. + */ + read_DLCI_IB_mapping( card, chan ); + + return 0; +} +/******* Miscellaneous ******************************************************/ + +/*============================================================================ + * Update channel state. + */ +static int update_chan_state(struct net_device* dev) +{ + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + mbox->cmd.command = FR_LIST_ACTIVE_DLCI; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err) { + + unsigned short* list = (void*)mbox->data; + int cnt = mbox->cmd.length / sizeof(short); + + err=1; + + for (; cnt; --cnt, ++list) { + + if (*list == chan->dlci) { + set_chan_state(dev, WAN_CONNECTED); + + + /* May 23 2000. NC + * When a dlci is added or restarted, + * the dlci_int_interface pointer must + * be reinitialized. */ + if (!chan->dlci_int_interface){ + err=fr_init_dlci (card,chan); + } + break; + } + } + } + + return err; +} + +/*============================================================================ + * Set channel state. + */ +static void set_chan_state(struct net_device* dev, int state) +{ + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + + if (chan->common.state != state) { + + switch (state) { + + case WAN_CONNECTED: + printk(KERN_INFO + "%s: Interface %s: DLCI %d connected\n", + card->devname, dev->name, chan->dlci); + + /* If the interface was previoulsy down, + * bring it up, since the channel is active */ + + trigger_fr_poll (dev); + trigger_fr_arp (dev); + break; + + case WAN_CONNECTING: + printk(KERN_INFO + "%s: Interface %s: DLCI %d connecting\n", + card->devname, dev->name, chan->dlci); + break; + + case WAN_DISCONNECTED: + printk (KERN_INFO + "%s: Interface %s: DLCI %d disconnected!\n", + card->devname, dev->name, chan->dlci); + + /* If the interface is up, bring it down, + * since the channel is now disconnected */ + trigger_fr_poll (dev); + break; + } + + chan->common.state = state; + } + + chan->state_tick = jiffies; +} + +/*============================================================================ + * Find network device by its channel number. + * + * We need this critical flag because we change + * the dlci_to_dev_map outside the interrupt. + * + * NOTE: del_if() functions updates this array, it uses + * the spin locks to avoid corruption. + */ +static struct net_device* find_channel(sdla_t* card, unsigned dlci) +{ + if(dlci > HIGHEST_VALID_DLCI) + return NULL; + + return(card->u.f.dlci_to_dev_map[dlci]); +} + +/*============================================================================ + * Check to see if a frame can be sent. If no transmit buffers available, + * enable transmit interrupts. + * + * Return: 1 - Tx buffer(s) available + * 0 - no buffers available + */ +static int is_tx_ready (sdla_t* card, fr_channel_t* chan) +{ + unsigned char sb; + + if(card->hw.type == SDLA_S514) + return 1; + + sb = inb(card->hw.port); + if (sb & 0x02) + return 1; + + return 0; +} + +/*============================================================================ + * Convert decimal string to unsigned integer. + * If len != 0 then only 'len' characters of the string are converted. + */ +static unsigned int dec_to_uint (unsigned char* str, int len) +{ + unsigned val; + + if (!len) + len = strlen(str); + + for (val = 0; len && isdigit(*str); ++str, --len) + val = (val * 10) + (*str - (unsigned)'0'); + + return val; +} + + + +/*============================================================================= + * Store a UDP management packet for later processing. + */ + +static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, int dlci) +{ + int udp_pkt_stored = 0; + + struct net_device *dev = find_channel(card, dlci); + fr_channel_t *chan; + + if (!dev || !(chan=dev->priv)) + return 1; + + if(!card->u.f.udp_pkt_lgth && (skb->len <= MAX_LGTH_UDP_MGNT_PKT)){ + card->u.f.udp_pkt_lgth = skb->len + chan->fr_header_len; + card->u.f.udp_type = udp_type; + card->u.f.udp_pkt_src = udp_pkt_src; + card->u.f.udp_dlci = dlci; + memcpy(card->u.f.udp_pkt_data, skb->data, skb->len); + card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UDP; + udp_pkt_stored = 1; + + }else{ + printk(KERN_INFO "ERROR: UDP packet not stored for DLCI %d\n", + dlci); + } + + if(udp_pkt_src == UDP_PKT_FRM_STACK){ + dev_kfree_skb_any(skb); + }else{ + dev_kfree_skb_any(skb); + } + + return(udp_pkt_stored); +} + + +/*============================================================================== + * Process UDP call of type FPIPE8ND + */ +static int process_udp_mgmt_pkt(sdla_t* card) +{ + + int c_retry = MAX_CMD_RETRY; + unsigned char *buf; + unsigned char frames; + unsigned int len; + unsigned short buffer_length; + struct sk_buff *new_skb; + fr_mbox_t* mbox = card->mbox; + int err; + struct timeval tv; + int udp_mgmt_req_valid = 1; + struct net_device* dev; + fr_channel_t* chan; + fr_udp_pkt_t *fr_udp_pkt; + unsigned short num_trc_els; + fr_trc_el_t* ptr_trc_el; + fr_trc_el_t trc_el; + fpipemon_trc_t* fpipemon_trc; + + char udp_pkt_src = card->u.f.udp_pkt_src; + int dlci = card->u.f.udp_dlci; + + /* Find network interface for this packet */ + dev = find_channel(card, dlci); + if (!dev){ + card->u.f.udp_pkt_lgth = 0; + return 1; + } + if ((chan = dev->priv) == NULL){ + card->u.f.udp_pkt_lgth = 0; + return 1; + } + + /* If the UDP packet is from the network, we are going to have to + transmit a response. Before doing so, we must check to see that + we are not currently transmitting a frame (in 'if_send()') and + that we are not already in a 'delayed transmit' state. + */ + if(udp_pkt_src == UDP_PKT_FRM_NETWORK) { + if (check_tx_status(card,dev)){ + card->u.f.udp_pkt_lgth = 0; + return 1; + } + } + + fr_udp_pkt = (fr_udp_pkt_t *)card->u.f.udp_pkt_data; + + if(udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + switch(fr_udp_pkt->cblock.command) { + + case FR_READ_MODEM_STATUS: + case FR_READ_STATUS: + case FPIPE_ROUTER_UP_TIME: + case FR_READ_ERROR_STATS: + case FPIPE_DRIVER_STAT_GEN: + case FR_READ_STATISTICS: + case FR_READ_ADD_DLC_STATS: + case FR_READ_CONFIG: + case FR_READ_CODE_VERSION: + udp_mgmt_req_valid = 1; + break; + default: + udp_mgmt_req_valid = 0; + break; + } + } + + if(!udp_mgmt_req_valid) { + /* set length to 0 */ + fr_udp_pkt->cblock.length = 0; + /* set return code */ + fr_udp_pkt->cblock.result = 0xCD; + + chan->drvstats_gen.UDP_PIPE_mgmt_direction_err ++; + + if (net_ratelimit()){ + printk(KERN_INFO + "%s: Warning, Illegal UDP command attempted from network: %x\n", + card->devname,fr_udp_pkt->cblock.command); + } + + } else { + + switch(fr_udp_pkt->cblock.command) { + + case FPIPE_ENABLE_TRACING: + if(!card->TracingEnabled) { + do { + mbox->cmd.command = FR_SET_TRACE_CONFIG; + mbox->cmd.length = 1; + mbox->cmd.dlci = 0x00; + mbox->data[0] = fr_udp_pkt->data[0] | + RESET_TRC; + err = sdla_exec(mbox) ? + mbox->cmd.result : CMD_TIMEOUT; + } while (err && c_retry-- && fr_event(card, err, + mbox)); + + if(err) { + card->TracingEnabled = 0; + /* set the return code */ + fr_udp_pkt->cblock.result = + mbox->cmd.result; + mbox->cmd.length = 0; + break; + } + + sdla_peek(&card->hw, NO_TRC_ELEMENTS_OFF, + &num_trc_els, 2); + sdla_peek(&card->hw, BASE_TRC_ELEMENTS_OFF, + &card->u.f.trc_el_base, 4); + card->u.f.curr_trc_el = card->u.f.trc_el_base; + card->u.f.trc_el_last = card->u.f.curr_trc_el + + ((num_trc_els - 1) * + sizeof(fr_trc_el_t)); + + /* Calculate the maximum trace data area in */ + /* the UDP packet */ + card->u.f.trc_bfr_space=(MAX_LGTH_UDP_MGNT_PKT - + //sizeof(fr_encap_hdr_t) - + sizeof(ip_pkt_t) - + sizeof(udp_pkt_t) - + sizeof(wp_mgmt_t) - + sizeof(cblock_t)); + + /* set return code */ + fr_udp_pkt->cblock.result = 0; + + } else { + /* set return code to line trace already + enabled */ + fr_udp_pkt->cblock.result = 1; + } + + mbox->cmd.length = 0; + card->TracingEnabled = 1; + break; + + + case FPIPE_DISABLE_TRACING: + if(card->TracingEnabled) { + + do { + mbox->cmd.command = FR_SET_TRACE_CONFIG; + mbox->cmd.length = 1; + mbox->cmd.dlci = 0x00; + mbox->data[0] = ~ACTIVATE_TRC; + err = sdla_exec(mbox) ? + mbox->cmd.result : CMD_TIMEOUT; + } while (err && c_retry-- && fr_event(card, err, mbox)); + } + + /* set return code */ + fr_udp_pkt->cblock.result = 0; + mbox->cmd.length = 0; + card->TracingEnabled = 0; + break; + + case FPIPE_GET_TRACE_INFO: + + /* Line trace cannot be performed on the 502 */ + if(!card->TracingEnabled) { + /* set return code */ + fr_udp_pkt->cblock.result = 1; + mbox->cmd.length = 0; + break; + } + + ptr_trc_el = (void *)card->u.f.curr_trc_el; + + buffer_length = 0; + fr_udp_pkt->data[0x00] = 0x00; + + for(frames = 0; frames < MAX_FRMS_TRACED; frames ++) { + + sdla_peek(&card->hw, (unsigned long)ptr_trc_el, + (void *)&trc_el.flag, + sizeof(fr_trc_el_t)); + if(trc_el.flag == 0x00) { + break; + } + if((card->u.f.trc_bfr_space - buffer_length) + < sizeof(fpipemon_trc_hdr_t)) { + fr_udp_pkt->data[0x00] |= MORE_TRC_DATA; + break; + } + + fpipemon_trc = + (fpipemon_trc_t *)&fr_udp_pkt->data[buffer_length]; + fpipemon_trc->fpipemon_trc_hdr.status = + trc_el.attr; + fpipemon_trc->fpipemon_trc_hdr.tmstamp = + trc_el.tmstamp; + fpipemon_trc->fpipemon_trc_hdr.length = + trc_el.length; + + if(!trc_el.offset || !trc_el.length) { + + fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00; + + }else if((trc_el.length + sizeof(fpipemon_trc_hdr_t) + 1) > + (card->u.f.trc_bfr_space - buffer_length)){ + + fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00; + fr_udp_pkt->data[0x00] |= MORE_TRC_DATA; + + }else { + fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x01; + sdla_peek(&card->hw, trc_el.offset, + fpipemon_trc->data, + trc_el.length); + } + + trc_el.flag = 0x00; + sdla_poke(&card->hw, (unsigned long)ptr_trc_el, + &trc_el.flag, 1); + + ptr_trc_el ++; + if((void *)ptr_trc_el > card->u.f.trc_el_last) + ptr_trc_el = (void*)card->u.f.trc_el_base; + + buffer_length += sizeof(fpipemon_trc_hdr_t); + if(fpipemon_trc->fpipemon_trc_hdr.data_passed) { + buffer_length += trc_el.length; + } + + if(fr_udp_pkt->data[0x00] & MORE_TRC_DATA) { + break; + } + } + + if(frames == MAX_FRMS_TRACED) { + fr_udp_pkt->data[0x00] |= MORE_TRC_DATA; + } + + card->u.f.curr_trc_el = (void *)ptr_trc_el; + + /* set the total number of frames passed */ + fr_udp_pkt->data[0x00] |= + ((frames << 1) & (MAX_FRMS_TRACED << 1)); + + /* set the data length and return code */ + fr_udp_pkt->cblock.length = mbox->cmd.length = buffer_length; + fr_udp_pkt->cblock.result = 0; + break; + + case FPIPE_FT1_READ_STATUS: + sdla_peek(&card->hw, 0xF020, + &fr_udp_pkt->data[0x00] , 2); + fr_udp_pkt->cblock.length = mbox->cmd.length = 2; + fr_udp_pkt->cblock.result = 0; + break; + + case FPIPE_FLUSH_DRIVER_STATS: + init_chan_statistics(chan); + init_global_statistics(card); + mbox->cmd.length = 0; + break; + + case FPIPE_ROUTER_UP_TIME: + do_gettimeofday(&tv); + chan->router_up_time = tv.tv_sec - + chan->router_start_time; + *(unsigned long *)&fr_udp_pkt->data = + chan->router_up_time; + mbox->cmd.length = fr_udp_pkt->cblock.length = 4; + fr_udp_pkt->cblock.result = 0; + break; + + case FPIPE_DRIVER_STAT_IFSEND: + memcpy(fr_udp_pkt->data, + &chan->drvstats_if_send.if_send_entry, + sizeof(if_send_stat_t)); + mbox->cmd.length = fr_udp_pkt->cblock.length =sizeof(if_send_stat_t); + fr_udp_pkt->cblock.result = 0; + break; + + case FPIPE_DRIVER_STAT_INTR: + + memcpy(fr_udp_pkt->data, + &card->statistics.isr_entry, + sizeof(global_stats_t)); + + memcpy(&fr_udp_pkt->data[sizeof(global_stats_t)], + &chan->drvstats_rx_intr.rx_intr_no_socket, + sizeof(rx_intr_stat_t)); + + mbox->cmd.length = fr_udp_pkt->cblock.length = + sizeof(global_stats_t) + + sizeof(rx_intr_stat_t); + fr_udp_pkt->cblock.result = 0; + break; + + case FPIPE_DRIVER_STAT_GEN: + memcpy(fr_udp_pkt->data, + &chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err, + sizeof(pipe_mgmt_stat_t)); + + memcpy(&fr_udp_pkt->data[sizeof(pipe_mgmt_stat_t)], + &card->statistics, sizeof(global_stats_t)); + + mbox->cmd.length = fr_udp_pkt->cblock.length = sizeof(global_stats_t)+ + sizeof(rx_intr_stat_t); + fr_udp_pkt->cblock.result = 0; + break; + + + case FR_FT1_STATUS_CTRL: + if(fr_udp_pkt->data[0] == 1) { + if(rCount++ != 0 ){ + fr_udp_pkt->cblock.result = 0; + mbox->cmd.length = 1; + break; + } + } + + /* Disable FT1 MONITOR STATUS */ + if(fr_udp_pkt->data[0] == 0) { + if( --rCount != 0) { + fr_udp_pkt->cblock.result = 0; + mbox->cmd.length = 1; + break; + } + } + goto udp_mgmt_dflt; + + + default: +udp_mgmt_dflt: + do { + memcpy(&mbox->cmd, + &fr_udp_pkt->cblock.command, + sizeof(fr_cmd_t)); + if(mbox->cmd.length) { + memcpy(&mbox->data, + (char *)fr_udp_pkt->data, + mbox->cmd.length); + } + + err = sdla_exec(mbox) ? mbox->cmd.result : + CMD_TIMEOUT; + } while (err && c_retry-- && fr_event(card, err, mbox)); + + if(!err) + chan->drvstats_gen. + UDP_PIPE_mgmt_adptr_cmnd_OK ++; + else + chan->drvstats_gen. + UDP_PIPE_mgmt_adptr_cmnd_timeout ++; + + /* copy the result back to our buffer */ + memcpy(&fr_udp_pkt->cblock.command, + &mbox->cmd, sizeof(fr_cmd_t)); + + if(mbox->cmd.length) { + memcpy(&fr_udp_pkt->data, + &mbox->data, mbox->cmd.length); + } + } + } + + /* Fill UDP TTL */ + fr_udp_pkt->ip_pkt.ttl = card->wandev.ttl; + len = reply_udp(card->u.f.udp_pkt_data, mbox->cmd.length); + + if(udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + chan->fr_header_len=2; + chan->fr_header[0]=Q922_UI; + chan->fr_header[1]=NLPID_IP; + + err = fr_send_data_header(card, dlci, 0, len, + card->u.f.udp_pkt_data,chan->fr_header_len); + if (err){ + chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_passed ++; + }else{ + chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_failed ++; + } + + } else { + /* Allocate socket buffer */ + if((new_skb = dev_alloc_skb(len)) != NULL) { + + /* copy data into new_skb */ + buf = skb_put(new_skb, len); + memcpy(buf, card->u.f.udp_pkt_data, len); + + chan->drvstats_gen. + UDP_PIPE_mgmt_passed_to_stack ++; + new_skb->dev = dev; + new_skb->protocol = htons(ETH_P_IP); + new_skb->mac.raw = new_skb->data; + netif_rx(new_skb); + + } else { + chan->drvstats_gen.UDP_PIPE_mgmt_no_socket ++; + printk(KERN_INFO + "%s: UDP mgmt cmnd, no socket buffers available!\n", + card->devname); + } + } + + card->u.f.udp_pkt_lgth = 0; + + return 1; +} + +/*============================================================================== + * Send Inverse ARP Request + */ + +int send_inarp_request(sdla_t *card, struct net_device *dev) +{ + int err=0; + + arphdr_1490_t *ArpPacket; + arphdr_fr_t *arphdr; + fr_channel_t *chan = dev->priv; + struct in_device *in_dev; + + in_dev = dev->ip_ptr; + + if(in_dev != NULL ) { + + ArpPacket = kmalloc(sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t), GFP_ATOMIC); + /* SNAP Header indicating ARP */ + ArpPacket->control = 0x03; + ArpPacket->pad = 0x00; + ArpPacket->NLPID = 0x80; + ArpPacket->OUI[0] = 0; + ArpPacket->OUI[1] = 0; + ArpPacket->OUI[2] = 0; + ArpPacket->PID = 0x0608; + + arphdr = (arphdr_fr_t *)(ArpPacket + 1); // Go to ARP Packet + + /* InARP request */ + arphdr->ar_hrd = 0x0F00; /* Frame Relay HW type */ + arphdr->ar_pro = 0x0008; /* IP Protocol */ + arphdr->ar_hln = 2; /* HW addr length */ + arphdr->ar_pln = 4; /* IP addr length */ + arphdr->ar_op = htons(0x08); /* InARP Request */ + arphdr->ar_sha = 0; /* src HW DLCI - Doesn't matter */ + if(in_dev->ifa_list != NULL) + arphdr->ar_sip = in_dev->ifa_list->ifa_local; /* Local Address */else + arphdr->ar_sip = 0; + arphdr->ar_tha = 0; /* dst HW DLCI - Doesn't matter */ + arphdr->ar_tip = 0; /* Remote Address -- what we want */ + + err = fr_send(card, chan->dlci, 0, sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t), + (void *)ArpPacket); + + if (!err){ + printk(KERN_INFO "\n%s: Sending InARP request on DLCI %d.\n", + card->devname, chan->dlci); + clear_bit(ARP_CRIT,&card->wandev.critical); + } + + kfree(ArpPacket); + }else{ + printk(KERN_INFO "%s: INARP ERROR: %s doesn't have a local IP address!\n", + card->devname,dev->name); + return 1; + } + + return 0; +} + + +/*============================================================================== + * Check packet for ARP Type + */ + +int is_arp(void *buf) +{ + arphdr_1490_t *arphdr = (arphdr_1490_t *)buf; + + if (arphdr->pad == 0x00 && + arphdr->NLPID == 0x80 && + arphdr->PID == 0x0608) + return 1; + else return 0; +} + +/*============================================================================== + * Process ARP Packet Type + */ + +int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device* dev) +{ + + + arphdr_fr_t *arphdr = (arphdr_fr_t *)(ArpPacket + 1); /* Skip header */ + fr_rx_buf_ctl_t* frbuf = card->rxmb; + struct in_device *in_dev; + fr_channel_t *chan = dev->priv; + + /* Before we transmit ARP packet, we must check + * to see that we are not currently transmitting a + * frame (in 'if_send()') and that we are not + * already in a 'delayed transmit' state. */ + if (check_tx_status(card,dev)){ + if (net_ratelimit()){ + printk(KERN_INFO "%s: Disabling comminication to process ARP\n", + card->devname); + } + set_bit(ARP_CRIT,&card->wandev.critical); + return 0; + } + + in_dev = dev->ip_ptr; + + /* Check that IP addresses exist for our network address */ + if (in_dev == NULL || in_dev->ifa_list == NULL) + return -1; + + switch (ntohs(arphdr->ar_op)) { + + case 0x08: // Inverse ARP request -- Send Reply, add route. + + /* Check for valid Address */ + printk(KERN_INFO "%s: Recvd PtP addr -InArp Req: %u.%u.%u.%u\n", + card->devname, NIPQUAD(arphdr->ar_sip)); + + + /* Check that the network address is the same as ours, only + * if the netowrk mask is not 255.255.255.255. Otherwise + * this check would not make sense */ + + if (in_dev->ifa_list->ifa_mask != 0xFFFFFFFF && + (in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != + (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)){ + printk(KERN_INFO + "%s: Invalid PtP address. %u.%u.%u.%u InARP ignored.\n", + card->devname,NIPQUAD(arphdr->ar_sip)); + + printk(KERN_INFO "%s: mask %u.%u.%u.%u\n", + card->devname, NIPQUAD(in_dev->ifa_list->ifa_mask)); + printk(KERN_INFO "%s: local %u.%u.%u.%u\n", + card->devname,NIPQUAD(in_dev->ifa_list->ifa_local)); + return -1; + } + + if (in_dev->ifa_list->ifa_local == arphdr->ar_sip){ + printk(KERN_INFO + "%s: Local addr = PtP addr. InARP ignored.\n", + card->devname); + return -1; + } + + arphdr->ar_op = htons(0x09); /* InARP Reply */ + + /* Set addresses */ + arphdr->ar_tip = arphdr->ar_sip; + arphdr->ar_sip = in_dev->ifa_list->ifa_local; + + chan->ip_local = in_dev->ifa_list->ifa_local; + chan->ip_remote = arphdr->ar_sip; + + fr_send(card, frbuf->dlci, 0, frbuf->length, (void *)ArpPacket); + + if (test_bit(ARP_CRIT,&card->wandev.critical)){ + if (net_ratelimit()){ + printk(KERN_INFO "%s: ARP Processed Enabling Communication!\n", + card->devname); + } + } + clear_bit(ARP_CRIT,&card->wandev.critical); + + chan->ip_local = in_dev->ifa_list->ifa_local; + chan->ip_remote = arphdr->ar_sip; + + /* Add Route Flag */ + /* The route will be added in the polling routine so + that it is not interrupt context. */ + + chan->route_flag = ADD_ROUTE; + trigger_fr_poll (dev); + + break; + + case 0x09: // Inverse ARP reply + + /* Check for valid Address */ + printk(KERN_INFO "%s: Recvd PtP addr %u.%u.%u.%u -InArp Reply\n", + card->devname, NIPQUAD(arphdr->ar_sip)); + + + /* Compare network addresses, only if network mask + * is not 255.255.255.255 It would not make sense + * to perform this test if the mask was all 1's */ + + if (in_dev->ifa_list->ifa_mask != 0xffffffff && + (in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != + (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)) { + + printk(KERN_INFO "%s: Invalid PtP address. InARP ignored.\n", + card->devname); + return -1; + } + + /* Make sure that the received IP address is not + * the same as our own local address */ + if (in_dev->ifa_list->ifa_local == arphdr->ar_sip) { + printk(KERN_INFO "%s: Local addr = PtP addr. InARP ignored.\n", + card->devname); + return -1; + } + + chan->ip_local = in_dev->ifa_list->ifa_local; + chan->ip_remote = arphdr->ar_sip; + + /* Add Route Flag */ + /* The route will be added in the polling routine so + that it is not interrupt context. */ + + chan->route_flag = ADD_ROUTE; + chan->inarp = INARP_CONFIGURED; + trigger_fr_poll(dev); + + break; + default: + break; // ARP's and RARP's -- Shouldn't happen. + } + + return 0; +} + + +/*============================================================ + * trigger_fr_arp + * + * Description: + * Add an fr_arp() task into a arp + * timer handler for a specific dlci/interface. + * This will kick the fr_arp() routine + * within the specified time interval. + * + * Usage: + * This timer is used to send ARP requests at + * certain time intervals. + * Called by an interrupt to request an action + * at a later date. + */ + +static void trigger_fr_arp(struct net_device *dev) +{ + fr_channel_t* chan = dev->priv; + + mod_timer(&chan->fr_arp_timer, jiffies + chan->inarp_interval * HZ); + return; +} + + + +/*============================================================================== + * ARP Request Action + * + * This funciton is called by timer interrupt to send an arp request + * to the remote end. + */ + +static void fr_arp (unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + fr_channel_t *chan = dev->priv; + volatile sdla_t *card = chan->card; + fr508_flags_t* flags = card->flags; + + /* Send ARP packets for all devs' until + * ARP state changes to CONFIGURED */ + + if (chan->inarp == INARP_REQUEST && + chan->common.state == WAN_CONNECTED && + card->wandev.state == WAN_CONNECTED){ + set_bit(0,&chan->inarp_ready); + card->u.f.timer_int_enabled |= TMR_INT_ENABLED_ARP; + flags->imask |= FR_INTR_TIMER; + } + + return; +} + + +/*============================================================================== + * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR_ + * TEST_COUNTER times. + */ +static int intr_test( sdla_t* card ) +{ + fr_mbox_t* mb = card->mbox; + int err,i; + + err = fr_set_intr_mode(card, FR_INTR_READY, card->wandev.mtu, 0 ); + + if (err == CMD_OK) { + + for ( i = 0; i < MAX_INTR_TEST_COUNTER; i++ ) { + /* Run command READ_CODE_VERSION */ + mb->cmd.length = 0; + mb->cmd.command = FR_READ_CODE_VERSION; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + if (err != CMD_OK) + fr_event(card, err, mb); + } + + } else { + return err; + } + + err = fr_set_intr_mode( card, 0, card->wandev.mtu, 0 ); + + if( err != CMD_OK ) + return err; + + return 0; +} + +/*============================================================================== + * Determine what type of UDP call it is. FPIPE8ND ? + */ +static int udp_pkt_type( struct sk_buff *skb, sdla_t* card ) +{ + fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)skb->data; + + /* Quick HACK */ + + + if((fr_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) && + (fr_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45) && + (fr_udp_pkt->udp_pkt.udp_dst_port == + ntohs(card->wandev.udp_port)) && + (fr_udp_pkt->wp_mgmt.request_reply == + UDPMGMT_REQUEST)) { + if(!strncmp(fr_udp_pkt->wp_mgmt.signature, + UDPMGMT_FPIPE_SIGNATURE, 8)){ + return UDP_FPIPE_TYPE; + } + } + return UDP_INVALID_TYPE; +} + + +/*============================================================================== + * Initializes the Statistics values in the fr_channel structure. + */ +void init_chan_statistics( fr_channel_t* chan) +{ + memset(&chan->drvstats_if_send.if_send_entry, 0, + sizeof(if_send_stat_t)); + memset(&chan->drvstats_rx_intr.rx_intr_no_socket, 0, + sizeof(rx_intr_stat_t)); + memset(&chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err, 0, + sizeof(pipe_mgmt_stat_t)); +} + +/*============================================================================== + * Initializes the Statistics values in the Sdla_t structure. + */ +void init_global_statistics( sdla_t* card ) +{ + /* Intialize global statistics for a card */ + memset(&card->statistics.isr_entry, 0, sizeof(global_stats_t)); +} + +static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan ) +{ + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + dlci_IB_mapping_t* result; + int err, counter, found; + + do { + mbox->cmd.command = FR_READ_DLCI_IB_MAPPING; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + if( mbox->cmd.result != 0){ + printk(KERN_INFO "%s: Read DLCI IB Mapping failed\n", + chan->name); + } + + counter = mbox->cmd.length / sizeof(dlci_IB_mapping_t); + result = (void *)mbox->data; + + found = 0; + for (; counter; --counter, ++result) { + if ( result->dlci == chan->dlci ) { + chan->IB_addr = result->addr_value; + if(card->hw.type == SDLA_S514){ + chan->dlci_int_interface = + (void*)(card->hw.dpmbase + + chan->IB_addr); + }else{ + chan->dlci_int_interface = + (void*)(card->hw.dpmbase + + (chan->IB_addr & 0x00001FFF)); + + } + found = 1; + break; + } + } + if (!found) + printk( KERN_INFO "%s: DLCI %d not found by IB MAPPING cmd\n", + card->devname, chan->dlci); +} + + + +void s508_s514_lock(sdla_t *card, unsigned long *smp_flags) +{ + if (card->hw.type != SDLA_S514){ + + spin_lock_irqsave(&card->wandev.lock, *smp_flags); + }else{ + spin_lock(&card->u.f.if_send_lock); + } + return; +} + + +void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags) +{ + if (card->hw.type != SDLA_S514){ + + spin_unlock_irqrestore (&card->wandev.lock, *smp_flags); + }else{ + spin_unlock(&card->u.f.if_send_lock); + } + return; +} + + + +/*---------------------------------------------------------------------- + RECEIVE INTERRUPT: BOTTOM HALF HANDLERS + ----------------------------------------------------------------------*/ + + +/*======================================================== + * bh_enqueue + * + * Description: + * Insert a received packet into a circular + * rx queue. This packet will be picked up + * by fr_bh() and sent up the stack to the + * user. + * + * Usage: + * This function is called by rx interrupt, + * in API mode. + * + */ + +static int bh_enqueue(struct net_device *dev, struct sk_buff *skb) +{ + /* Check for full */ + fr_channel_t* chan = dev->priv; + sdla_t *card = chan->card; + + + if (atomic_read(&chan->bh_buff_used) == MAX_BH_BUFF){ + ++card->wandev.stats.rx_dropped; + dev_kfree_skb_any(skb); + return 1; + } + + ((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb; + + if (chan->bh_write == (MAX_BH_BUFF-1)){ + chan->bh_write=0; + }else{ + ++chan->bh_write; + } + + atomic_inc(&chan->bh_buff_used); + + return 0; +} + + +/*======================================================== + * trigger_fr_bh + * + * Description: + * Kick the fr_bh() handler + * + * Usage: + * rx interrupt calls this function during + * the API mode. + */ + +static void trigger_fr_bh (fr_channel_t *chan) +{ + if (!test_and_set_bit(0,&chan->tq_working)){ + wanpipe_queue_work(&chan->common.wanpipe_work); + } +} + + +/*======================================================== + * fr_bh + * + * Description: + * Frame relay receive BH handler. + * Dequeue data from the BH circular + * buffer and pass it up the API sock. + * + * Rationale: + * This fuction is used to offload the + * rx_interrupt during API operation mode. + * The fr_bh() function executes for each + * dlci/interface. + * + * Once receive interrupt copies data from the + * card into an skb buffer, the skb buffer + * is appended to a circular BH buffer. + * Then the interrupt kicks fr_bh() to finish the + * job at a later time (not within the interrupt). + * + * Usage: + * Interrupts use this to defer a task to + * a polling routine. + * + */ + +static void fr_bh(struct net_device * dev) +{ + fr_channel_t* chan = dev->priv; + sdla_t *card = chan->card; + struct sk_buff *skb; + + if (atomic_read(&chan->bh_buff_used) == 0){ + clear_bit(0, &chan->tq_working); + return; + } + + while (atomic_read(&chan->bh_buff_used)){ + + if (chan->common.sk == NULL || chan->common.func == NULL){ + clear_bit(0, &chan->tq_working); + return; + } + + skb = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb; + + if (skb != NULL){ + + if (chan->common.sk == NULL || chan->common.func == NULL){ + ++card->wandev.stats.rx_dropped; + ++chan->ifstats.rx_dropped; + dev_kfree_skb_any(skb); + fr_bh_cleanup(dev); + continue; + } + + if (chan->common.func(skb,dev,chan->common.sk) != 0){ + /* Sock full cannot send, queue us for + * another try */ + atomic_set(&chan->common.receive_block,1); + return; + }else{ + fr_bh_cleanup(dev); + } + }else{ + fr_bh_cleanup(dev); + } + } + clear_bit(0, &chan->tq_working); + + return; +} + +static int fr_bh_cleanup(struct net_device *dev) +{ + fr_channel_t* chan = dev->priv; + + ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL; + + if (chan->bh_read == (MAX_BH_BUFF-1)){ + chan->bh_read=0; + }else{ + ++chan->bh_read; + } + + atomic_dec(&chan->bh_buff_used); + return 0; +} + + +/*---------------------------------------------------------------------- + POLL BH HANDLERS AND KICK ROUTINES + ----------------------------------------------------------------------*/ + +/*============================================================ + * trigger_fr_poll + * + * Description: + * Add a fr_poll() task into a tq_scheduler bh handler + * for a specific dlci/interface. This will kick + * the fr_poll() routine at a later time. + * + * Usage: + * Interrupts use this to defer a taks to + * a polling routine. + * + */ +static void trigger_fr_poll(struct net_device *dev) +{ + fr_channel_t* chan = dev->priv; + schedule_work(&chan->fr_poll_work); + return; +} + + +/*============================================================ + * fr_poll + * + * Rationale: + * We cannot manipulate the routing tables, or + * ip addresses withing the interrupt. Therefore + * we must perform such actons outside an interrupt + * at a later time. + * + * Description: + * Frame relay polling routine, responsible for + * shutting down interfaces upon disconnect + * and adding/removing routes. + * + * Usage: + * This function is executed for each frame relay + * dlci/interface through a tq_schedule bottom half. + * + * trigger_fr_poll() function is used to kick + * the fr_poll routine. + */ + +static void fr_poll(struct net_device *dev) +{ + + fr_channel_t* chan; + sdla_t *card; + u8 check_gateway=0; + + if (!dev || (chan = dev->priv) == NULL) + return; + + card = chan->card; + + /* (Re)Configuraiton is in progress, stop what you are + * doing and get out */ + if (test_bit(PERI_CRIT,&card->wandev.critical)){ + return; + } + + switch (chan->common.state){ + + case WAN_DISCONNECTED: + + if (test_bit(DYN_OPT_ON,&chan->interface_down) && + !test_bit(DEV_DOWN, &chan->interface_down) && + dev->flags&IFF_UP){ + + printk(KERN_INFO "%s: Interface %s is Down.\n", + card->devname,dev->name); + change_dev_flags(dev,dev->flags&~IFF_UP); + set_bit(DEV_DOWN, &chan->interface_down); + chan->route_flag = NO_ROUTE; + + }else{ + if (chan->inarp != INARP_NONE) + process_route(dev); + } + break; + + case WAN_CONNECTED: + + if (test_bit(DYN_OPT_ON,&chan->interface_down) && + test_bit(DEV_DOWN, &chan->interface_down) && + !(dev->flags&IFF_UP)){ + + printk(KERN_INFO "%s: Interface %s is Up.\n", + card->devname,dev->name); + + change_dev_flags(dev,dev->flags|IFF_UP); + clear_bit(DEV_DOWN, &chan->interface_down); + check_gateway=1; + } + + if (chan->inarp != INARP_NONE){ + process_route(dev); + check_gateway=1; + } + + if (chan->gateway && check_gateway) + add_gateway(card,dev); + + break; + + } + + return; +} + +/*============================================================== + * check_tx_status + * + * Rationale: + * We cannot transmit from an interrupt while + * the if_send is transmitting data. Therefore, + * we must check whether the tx buffers are + * begin used, before we transmit from an + * interrupt. + * + * Description: + * Checks whether it's safe to use the transmit + * buffers. + * + * Usage: + * ARP and UDP handling routines use this function + * because, they need to transmit data during + * an interrupt. + */ + +static int check_tx_status(sdla_t *card, struct net_device *dev) +{ + + if (card->hw.type == SDLA_S514){ + if (test_bit(SEND_CRIT, (void*)&card->wandev.critical) || + test_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical)) { + return 1; + } + } + + if (netif_queue_stopped(dev) || (card->u.f.tx_interrupts_pending)) + return 1; + + return 0; +} + +/*=============================================================== + * move_dev_to_next + * + * Description: + * Move the dev pointer to the next location in the + * link list. Check if we are at the end of the + * list, if so start from the begining. + * + * Usage: + * Timer interrupt uses this function to efficiently + * step through the devices that need to send ARP data. + * + */ + +struct net_device *move_dev_to_next(sdla_t *card, struct net_device *dev) +{ + if (card->wandev.new_if_cnt != 1){ + if (!*((struct net_device **)dev->priv)) + return card->wandev.dev; + else + return *((struct net_device **)dev->priv); + } + return dev; +} + +/*============================================================== + * trigger_config_fr + * + * Rationale: + * All commands must be performed inside of a + * interrupt. + * + * Description: + * Kick the config_fr() routine throught the + * timer interrupt. + */ + + +static void trigger_config_fr (sdla_t *card) +{ + fr508_flags_t* flags = card->flags; + + card->u.f.timer_int_enabled |= TMR_INT_ENABLED_CONFIG; + flags->imask |= FR_INTR_TIMER; +} + + +/*============================================================== + * config_fr + * + * Rationale: + * All commands must be performed inside of a + * interrupt. + & + * Description: + * Configure a DLCI. This function is executed + * by a timer_interrupt. The if_open() function + * triggers it. + * + * Usage: + * new_if() collects all data necessary to + * configure the DLCI. It sets the chan->dlci_ready + * bit. When the if_open() function is executed + * it checks this bit, and if its set it triggers + * the timer interrupt to execute the config_fr() + * function. + */ + +static void config_fr (sdla_t *card) +{ + struct net_device *dev; + fr_channel_t *chan; + + for (dev = card->wandev.dev; dev; + dev = *((struct net_device **)dev->priv)) { + + if ((chan=dev->priv) == NULL) + continue; + + if (!test_bit(0,&chan->config_dlci)) + continue; + + clear_bit(0,&chan->config_dlci); + + /* If signalling is set to NO, then setup + * DLCI addresses right away. Don't have to wait for + * link to connect. + */ + if (card->wandev.signalling == WANOPT_NO){ + printk(KERN_INFO "%s: Signalling set to NO: Mapping DLCI's\n", + card->wandev.name); + if (fr_init_dlci(card,chan)){ + printk(KERN_INFO "%s: ERROR: Failed to configure DLCI %i !\n", + card->devname, chan->dlci); + return; + } + } + + if (card->wandev.station == WANOPT_CPE) { + + update_chan_state(dev); + + /* CPE: issue full status enquiry */ + fr_issue_isf(card, FR_ISF_FSE); + + } else { + /* FR switch: activate DLCI(s) */ + + /* For Switch emulation we have to ADD and ACTIVATE + * the DLCI(s) that were configured with the SET_DLCI_ + * CONFIGURATION command. Add and Activate will fail if + * DLCI specified is not included in the list. + * + * Also If_open is called once for each interface. But + * it does not get in here for all the interface. So + * we have to pass the entire list of DLCI(s) to add + * activate routines. + */ + + if (!check_dlci_config (card, chan)){ + fr_add_dlci(card, chan->dlci); + fr_activate_dlci(card, chan->dlci); + } + } + + card->u.f.dlci_to_dev_map[chan->dlci] = dev; + } + return; +} + + +/*============================================================== + * config_fr + * + * Rationale: + * All commands must be executed during an interrupt. + * + * Description: + * Trigger uncofig_fr() function through + * the timer interrupt. + * + */ + +static void trigger_unconfig_fr(struct net_device *dev) +{ + fr_channel_t *chan = dev->priv; + volatile sdla_t *card = chan->card; + unsigned long timeout; + fr508_flags_t* flags = card->flags; + int reset_critical=0; + + if (test_bit(PERI_CRIT,(void*)&card->wandev.critical)){ + clear_bit(PERI_CRIT,(void*)&card->wandev.critical); + reset_critical=1; + } + + /* run unconfig_dlci() function + * throught the timer interrupt */ + set_bit(0,(void*)&chan->unconfig_dlci); + card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UNCONFIG; + flags->imask |= FR_INTR_TIMER; + + /* Wait for the command to complete */ + timeout = jiffies; + for(;;) { + + if(!(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UNCONFIG)) + break; + + if (time_after(jiffies, timeout + 1 * HZ)){ + card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UNCONFIG; + printk(KERN_INFO "%s: Failed to delete DLCI %i\n", + card->devname,chan->dlci); + break; + } + } + + if (reset_critical){ + set_bit(PERI_CRIT,(void*)&card->wandev.critical); + } +} + +/*============================================================== + * unconfig_fr + * + * Rationale: + * All commands must be executed during an interrupt. + * + * Description: + * Remove the dlci from firmware. + * This funciton is used in NODE shutdown. + */ + +static void unconfig_fr (sdla_t *card) +{ + struct net_device *dev; + fr_channel_t *chan; + + for (dev = card->wandev.dev; dev; + dev = *((struct net_device **)dev->priv)){ + + if ((chan=dev->priv) == NULL) + continue; + + if (!test_bit(0,&chan->unconfig_dlci)) + continue; + + clear_bit(0,&chan->unconfig_dlci); + + if (card->wandev.station == WANOPT_NODE){ + printk(KERN_INFO "%s: Unconfiguring DLCI %i\n", + card->devname,chan->dlci); + fr_delete_dlci(card,chan->dlci); + } + card->u.f.dlci_to_dev_map[chan->dlci] = NULL; + } +} + +static int setup_fr_header(struct sk_buff *skb, struct net_device* dev, + char op_mode) +{ + fr_channel_t *chan=dev->priv; + + if (op_mode == WANPIPE) { + chan->fr_header[0]=Q922_UI; + + switch (htons(skb->protocol)){ + case ETH_P_IP: + chan->fr_header[1]=NLPID_IP; + break; + default: + return -EINVAL; + } + + return 2; + } + + /* If we are in bridging mode, we must apply + * an Ethernet header + */ + if (op_mode == BRIDGE || op_mode == BRIDGE_NODE) { + /* Encapsulate the packet as a bridged Ethernet frame. */ +#ifdef DEBUG + printk(KERN_INFO "%s: encapsulating skb for frame relay\n", + dev->name); +#endif + chan->fr_header[0] = 0x03; + chan->fr_header[1] = 0x00; + chan->fr_header[2] = 0x80; + chan->fr_header[3] = 0x00; + chan->fr_header[4] = 0x80; + chan->fr_header[5] = 0xC2; + chan->fr_header[6] = 0x00; + chan->fr_header[7] = 0x07; + + /* Yuck. */ + skb->protocol = ETH_P_802_3; + return 8; + } + + return 0; +} + + +static int check_dlci_config (sdla_t *card, fr_channel_t *chan) +{ + fr_mbox_t* mbox = card->mbox; + int err=0; + fr_conf_t *conf=NULL; + unsigned short dlci_num = chan->dlci; + int dlci_offset=0; + struct net_device *dev = NULL; + + mbox->cmd.command = FR_READ_CONFIG; + mbox->cmd.length = 0; + mbox->cmd.dlci = dlci_num; + + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + if (err == CMD_OK){ + return 0; + } + + for (dev = card->wandev.dev; dev; + dev=*((struct net_device **)dev->priv)) + set_chan_state(dev,WAN_DISCONNECTED); + + printk(KERN_INFO "DLCI %i Not configured, configuring\n",dlci_num); + + mbox->cmd.command = FR_COMM_DISABLE; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err != CMD_OK){ + fr_event(card, err, mbox); + return 2; + } + + printk(KERN_INFO "Disabled Communications \n"); + + mbox->cmd.command = FR_READ_CONFIG; + mbox->cmd.length = 0; + mbox->cmd.dlci = 0; + + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK){ + fr_event(card, err, mbox); + return 2; + } + + conf = (fr_conf_t *)mbox->data; + + dlci_offset=0; + for (dev = card->wandev.dev; dev; + dev = *((struct net_device **)dev->priv)) { + fr_channel_t *chan_tmp = dev->priv; + conf->dlci[dlci_offset] = chan_tmp->dlci; + dlci_offset++; + } + + printk(KERN_INFO "Got Fr configuration Buffer Length is %x Dlci %i Dlci Off %i\n", + mbox->cmd.length, + mbox->cmd.length > 0x20 ? conf->dlci[0] : -1, + dlci_offset ); + + mbox->cmd.length = 0x20 + dlci_offset*2; + + mbox->cmd.command = FR_SET_CONFIG; + mbox->cmd.dlci = 0; + + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK){ + fr_event(card, err, mbox); + return 2; + } + + initialize_rx_tx_buffers (card); + + + printk(KERN_INFO "Configuraiton Succeded for new DLCI %i\n",dlci_num); + + if (fr_comm_enable (card)){ + return 2; + } + + printk(KERN_INFO "Enabling Communications \n"); + + for (dev = card->wandev.dev; dev; + dev = *((struct net_device **)dev->priv)) { + fr_channel_t *chan_tmp = dev->priv; + fr_init_dlci(card,chan_tmp); + fr_add_dlci(card, chan_tmp->dlci); + fr_activate_dlci(card, chan_tmp->dlci); + } + + printk(KERN_INFO "END OF CONFIGURAITON %i\n",dlci_num); + + return 1; +} + +static void initialize_rx_tx_buffers (sdla_t *card) +{ + fr_buf_info_t* buf_info; + + if (card->hw.type == SDLA_S514) { + + buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR + + FR508_RXBC_OFFS); + + card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase); + + card->u.f.rxmb_base = + (void*)(buf_info->rse_base + card->hw.dpmbase); + + card->u.f.rxmb_last = + (void*)(buf_info->rse_base + + (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) + + card->hw.dpmbase); + }else{ + buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS); + + card->rxmb = (void*)(buf_info->rse_next - + FR_MB_VECTOR + card->hw.dpmbase); + + card->u.f.rxmb_base = + (void*)(buf_info->rse_base - + FR_MB_VECTOR + card->hw.dpmbase); + + card->u.f.rxmb_last = + (void*)(buf_info->rse_base + + (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) - + FR_MB_VECTOR + card->hw.dpmbase); + } + + card->u.f.rx_base = buf_info->buf_base; + card->u.f.rx_top = buf_info->buf_top; + + card->u.f.tx_interrupts_pending = 0; + + return; +} + + + +MODULE_LICENSE("GPL"); + +/****** End *****************************************************************/ diff --git a/drivers/net/wan/sdla_ft1.c b/drivers/net/wan/sdla_ft1.c new file mode 100644 index 000000000..9d6528a50 --- /dev/null +++ b/drivers/net/wan/sdla_ft1.c @@ -0,0 +1,345 @@ +/***************************************************************************** +* sdla_chdlc.c WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module. +* +* Authors: Nenad Corbic +* Gideon Hack +* +* Copyright: (c) 1995-1999 Sangoma 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. +* ============================================================================ +* Sep 30, 1999 Nenad Corbic Fixed dynamic IP and route setup. +* Sep 23, 1999 Nenad Corbic Added SMP support, fixed tracing +* Sep 13, 1999 Nenad Corbic Split up Port 0 and 1 into separate devices. +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. +* Oct 30, 1998 Jaspreet Singh Added Support for CHDLC API (HDLC STREAMING). +* Oct 28, 1998 Jaspreet Singh Added Support for Dual Port CHDLC. +* Aug 07, 1998 David Fong Initial version. +*****************************************************************************/ + +#include +#include /* printk(), and other useful stuff */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include /* kmalloc(), kfree() */ +#include /* WAN router definitions */ +#include /* WANPIPE common user API definitions */ +#include /* ARPHRD_* defines */ +#include /* time_after() macro */ + +#include +#include + +#include /* sockaddr_in */ +#include +#include +#include /* htons(), etc. */ +#include +#include + +#include /* CHDLC firmware API definitions */ + +/****** Defines & Macros ****************************************************/ + +/* reasons for enabling the timer interrupt on the adapter */ +#define TMR_INT_ENABLED_UDP 0x0001 +#define TMR_INT_ENABLED_UPDATE 0x0002 + +#define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */ +#define CHDLC_HDR_LEN 1 + +#define IFF_POINTTOPOINT 0x10 + +#define WANPIPE 0x00 +#define API 0x01 +#define CHDLC_API 0x01 + +#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) + + +/******Data Structures*****************************************************/ + +/* This structure is placed in the private data area of the device structure. + * The card structure used to occupy the private area but now the following + * structure will incorporate the card structure along with CHDLC specific data + */ + +typedef struct chdlc_private_area +{ + struct net_device *slave; + sdla_t *card; + int TracingEnabled; /* For enabling Tracing */ + unsigned long curr_trace_addr; /* Used for Tracing */ + unsigned long start_trace_addr; + unsigned long end_trace_addr; + unsigned long base_addr_trace_buffer; + unsigned long end_addr_trace_buffer; + unsigned short number_trace_elements; + unsigned available_buffer_space; + unsigned long router_start_time; + unsigned char route_status; + unsigned char route_removed; + unsigned long tick_counter; /* For 5s timeout counter */ + unsigned long router_up_time; + u32 IP_address; /* IP addressing */ + u32 IP_netmask; + unsigned char mc; /* Mulitcast support on/off */ + unsigned short udp_pkt_lgth; /* udp packet processing */ + char udp_pkt_src; + char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT]; + unsigned short timer_int_enabled; + char update_comms_stats; /* updating comms stats */ + //FIXME: add driver stats as per frame relay! + +} chdlc_private_area_t; + +/* Route Status options */ +#define NO_ROUTE 0x00 +#define ADD_ROUTE 0x01 +#define ROUTE_ADDED 0x02 +#define REMOVE_ROUTE 0x03 + + +/****** Function Prototypes *************************************************/ +/* WAN link driver entry points. These are called by the WAN router module. */ +static int wpft1_exec (struct sdla *card, void *u_cmd, void *u_data); +static int chdlc_read_version (sdla_t* card, char* str); +static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb); + +/****** Public Functions ****************************************************/ + +/*============================================================================ + * Cisco HDLC protocol initialization routine. + * + * This routine is called by the main WANPIPE module during setup. At this + * point adapter is completely initialized and firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the adapter data space. + * + * Return: 0 o.k. + * < 0 failure. + */ +int wpft1_init (sdla_t* card, wandev_conf_t* conf) +{ + unsigned char port_num; + int err; + + union + { + char str[80]; + } u; + volatile CHDLC_MAILBOX_STRUCT* mb; + CHDLC_MAILBOX_STRUCT* mb1; + unsigned long timeout; + + /* Verify configuration ID */ + if (conf->config_id != WANCONFIG_CHDLC) { + printk(KERN_INFO "%s: invalid configuration ID %u!\n", + card->devname, conf->config_id); + return -EINVAL; + } + + /* Use primary port */ + card->u.c.comm_port = 0; + + + /* Initialize protocol-specific fields */ + if(card->hw.type != SDLA_S514){ + card->mbox = (void *) card->hw.dpmbase; + }else{ + card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT; + } + + mb = mb1 = card->mbox; + + if (!card->configured){ + + /* The board will place an 'I' in the return code to indicate that it is + ready to accept commands. We expect this to be completed in less + than 1 second. */ + + timeout = jiffies; + while (mb->return_code != 'I') /* Wait 1s for board to initialize */ + if (time_after(jiffies, timeout + 1*HZ)) break; + + if (mb->return_code != 'I') { + printk(KERN_INFO + "%s: Initialization not completed by adapter\n", + card->devname); + printk(KERN_INFO "Please contact Sangoma representative.\n"); + return -EIO; + } + } + + /* Read firmware version. Note that when adapter initializes, it + * clears the mailbox, so it may appear that the first command was + * executed successfully when in fact it was merely erased. To work + * around this, we execute the first command twice. + */ + + if (chdlc_read_version(card, u.str)) + return -EIO; + + printk(KERN_INFO "%s: Running FT1 Configuration firmware v%s\n", + card->devname, u.str); + + card->isr = NULL; + card->poll = NULL; + card->exec = &wpft1_exec; + card->wandev.update = NULL; + card->wandev.new_if = NULL; + card->wandev.del_if = NULL; + card->wandev.state = WAN_DUALPORT; + card->wandev.udp_port = conf->udp_port; + + card->wandev.new_if_cnt = 0; + + /* This is for the ports link state */ + card->u.c.state = WAN_DISCONNECTED; + + /* reset the number of times the 'update()' proc has been called */ + card->u.c.update_call_count = 0; + + card->wandev.ttl = 0x7F; + card->wandev.interface = 0; + + card->wandev.clocking = 0; + + port_num = card->u.c.comm_port; + + /* Setup Port Bps */ + + card->wandev.bps = 0; + + card->wandev.mtu = MIN_LGTH_CHDLC_DATA_CFG; + + /* Set up the interrupt status area */ + /* Read the CHDLC Configuration and obtain: + * Ptr to shared memory infor struct + * Use this pointer to calculate the value of card->u.c.flags ! + */ + mb1->buffer_length = 0; + mb1->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT; + if(err != COMMAND_OK) { + chdlc_error(card, err, mb1); + return -EIO; + } + + if(card->hw.type == SDLA_S514){ + card->u.c.flags = (void *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)-> + ptr_shared_mem_info_struct)); + }else{ + card->u.c.flags = (void *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)-> + ptr_shared_mem_info_struct % SDLA_WINDOWSIZE)); + } + + card->wandev.state = WAN_FT1_READY; + printk(KERN_INFO "%s: FT1 Config Ready !\n",card->devname); + + return 0; +} + +static int wpft1_exec(sdla_t *card, void *u_cmd, void *u_data) +{ + CHDLC_MAILBOX_STRUCT* mbox = card->mbox; + int len; + + if (copy_from_user((void*)&mbox->command, u_cmd, sizeof(ft1_exec_cmd_t))){ + return -EFAULT; + } + + len = mbox->buffer_length; + + if (len) { + if( copy_from_user((void*)&mbox->data, u_data, len)){ + return -EFAULT; + } + } + + /* execute command */ + if (!sdla_exec(mbox)){ + return -EIO; + } + + /* return result */ + if( copy_to_user(u_cmd, (void*)&mbox->command, sizeof(ft1_exec_cmd_t))){ + return -EFAULT; + } + + len = mbox->buffer_length; + + if (len && u_data && copy_to_user(u_data, (void*)&mbox->data, len)){ + return -EFAULT; + } + + return 0; + +} + +/*============================================================================ + * Read firmware code version. + * Put code version as ASCII string in str. + */ +static int chdlc_read_version (sdla_t* card, char* str) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int len; + char err; + mb->buffer_length = 0; + mb->command = READ_CHDLC_CODE_VERSION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + chdlc_error(card,err,mb); + } + else if (str) { /* is not null */ + len = mb->buffer_length; + memcpy(str, mb->data, len); + str[len] = '\0'; + } + return (err); +} + +/*============================================================================ + * Firmware error handler. + * This routine is called whenever firmware command returns non-zero + * return code. + * + * Return zero if previous command has to be cancelled. + */ +static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb) +{ + unsigned cmd = mb->command; + + switch (err) { + + case CMD_TIMEOUT: + printk(KERN_ERR "%s: command 0x%02X timed out!\n", + card->devname, cmd); + break; + + case S514_BOTH_PORTS_SAME_CLK_MODE: + if(cmd == SET_CHDLC_CONFIGURATION) { + printk(KERN_INFO + "%s: Configure both ports for the same clock source\n", + card->devname); + break; + } + + default: + printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n", + card->devname, cmd, err); + } + + return 0; +} + +MODULE_LICENSE("GPL"); diff --git a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c new file mode 100644 index 000000000..a4b489ccc --- /dev/null +++ b/drivers/net/wan/sdla_ppp.c @@ -0,0 +1,3430 @@ +/***************************************************************************** +* sdla_ppp.c WANPIPE(tm) Multiprotocol WAN Link Driver. PPP module. +* +* Author: Nenad Corbic +* +* Copyright: (c) 1995-2001 Sangoma 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. +* ============================================================================ +* Feb 28, 2001 Nenad Corbic o Updated if_tx_timeout() routine for +* 2.4.X kernels. +* Nov 29, 2000 Nenad Corbic o Added the 2.4.x kernel support: +* get_ip_address() function has moved +* into the ppp_poll() routine. It cannot +* be called from an interrupt. +* Nov 07, 2000 Nenad Corbic o Added security features for UDP debugging: +* Deny all and specify allowed requests. +* May 02, 2000 Nenad Corbic o Added the dynamic interface shutdown +* option. When the link goes down, the +* network interface IFF_UP flag is reset. +* Mar 06, 2000 Nenad Corbic o Bug Fix: corrupted mbox recovery. +* Feb 25, 2000 Nenad Corbic o Fixed the FT1 UDP debugger problem. +* Feb 09, 2000 Nenad Coribc o Shutdown bug fix. update() was called +* with NULL dev pointer: no check. +* Jan 24, 2000 Nenad Corbic o Disabled use of CMD complete inter. +* Dev 15, 1999 Nenad Corbic o Fixed up header files for 2.0.X kernels +* Oct 25, 1999 Nenad Corbic o Support for 2.0.X kernels +* Moved dynamic route processing into +* a polling routine. +* Oct 07, 1999 Nenad Corbic o Support for S514 PCI card. +* Gideon Hack o UPD and Updates executed using timer interrupt +* Sep 10, 1999 Nenad Corbic o Fixed up the /proc statistics +* Jul 20, 1999 Nenad Corbic o Remove the polling routines and use +* interrupts instead. +* Sep 17, 1998 Jaspreet Singh o Updates for 2.2.X Kernels. +* Aug 13, 1998 Jaspreet Singh o Improved Line Tracing. +* Jun 22, 1998 David Fong o Added remote IP address assignment +* Mar 15, 1998 Alan Cox o 2.1.8x basic port. +* Apr 16, 1998 Jaspreet Singh o using htons() for the IPX protocol. +* Dec 09, 1997 Jaspreet Singh o Added PAP and CHAP. +* o Implemented new routines like +* ppp_set_inbnd_auth(), ppp_set_outbnd_auth(), +* tokenize() and strstrip(). +* Nov 27, 1997 Jaspreet Singh o Added protection against enabling of irqs +* while they have been disabled. +* Nov 24, 1997 Jaspreet Singh o Fixed another RACE condition caused by +* disabling and enabling of irqs. +* o Added new counters for stats on disable/enable +* IRQs. +* Nov 10, 1997 Jaspreet Singh o Initialized 'skb->mac.raw' to 'skb->data' +* before every netif_rx(). +* o Free up the device structure in del_if(). +* Nov 07, 1997 Jaspreet Singh o Changed the delay to zero for Line tracing +* command. +* Oct 20, 1997 Jaspreet Singh o Added hooks in for Router UP time. +* Oct 16, 1997 Jaspreet Singh o The critical flag is used to maintain flow +* control by avoiding RACE conditions. The +* cli() and restore_flags() are taken out. +* A new structure, "ppp_private_area", is added +* to provide Driver Statistics. +* Jul 21, 1997 Jaspreet Singh o Protected calls to sdla_peek() by adding +* save_flags(), cli() and restore_flags(). +* Jul 07, 1997 Jaspreet Singh o Added configurable TTL for UDP packets +* o Added ability to discard mulitcast and +* broacast source addressed packets. +* Jun 27, 1997 Jaspreet Singh o Added FT1 monitor capabilities +* New case (0x25) statement in if_send routine. +* Added a global variable rCount to keep track +* of FT1 status enabled on the board. +* May 22, 1997 Jaspreet Singh o Added change in the PPP_SET_CONFIG command for +* 508 card to reflect changes in the new +* ppp508.sfm for supporting:continous transmission +* of Configure-Request packets without receiving a +* reply +* OR-ed 0x300 to conf_flags +* o Changed connect_tmout from 900 to 0 +* May 21, 1997 Jaspreet Singh o Fixed UDP Management for multiple boards +* Apr 25, 1997 Farhan Thawar o added UDP Management stuff +* Mar 11, 1997 Farhan Thawar Version 3.1.1 +* o fixed (+1) bug in rx_intr() +* o changed if_send() to return 0 if +* wandev.critical() is true +* o free socket buffer in if_send() if +* returning 0 +* Jan 15, 1997 Gene Kozin Version 3.1.0 +* o implemented exec() entry point +* Jan 06, 1997 Gene Kozin Initial version. +*****************************************************************************/ + +#include +#include /* printk(), and other useful stuff */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include /* kmalloc(), kfree() */ +#include /* WAN router definitions */ +#include /* WANPIPE common user API definitions */ +#include /* ARPHRD_* defines */ +#include /* htons(), etc. */ +#include /* sockaddr_in */ +#include /* time_after() macro */ + + +#include +#include +#include + +#include +#include /* PPP firmware API definitions */ +#include /* S514 Type Definition */ +/****** Defines & Macros ****************************************************/ + +#define PPP_DFLT_MTU 1500 /* default MTU */ +#define PPP_MAX_MTU 4000 /* maximum MTU */ +#define PPP_HDR_LEN 1 + +#define MAX_IP_ERRORS 100 + +#define CONNECT_TIMEOUT (90*HZ) /* link connection timeout */ +#define HOLD_DOWN_TIME (5*HZ) /* link hold down time : Changed from 30 to 5 */ + +/* For handle_IPXWAN() */ +#define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b))) + +/* Macro for enabling/disabling debugging comments */ +//#define NEX_DEBUG +#ifdef NEX_DEBUG +#define NEX_PRINTK(format, a...) printk(format, ## a) +#else +#define NEX_PRINTK(format, a...) +#endif /* NEX_DEBUG */ + +#define DCD(a) ( a & 0x08 ? "HIGH" : "LOW" ) +#define CTS(a) ( a & 0x20 ? "HIGH" : "LOW" ) +#define LCP(a) ( a == 0x09 ? "OPEN" : "CLOSED" ) +#define IP(a) ( a == 0x09 ? "ENABLED" : "DISABLED" ) + +#define TMR_INT_ENABLED_UPDATE 0x01 +#define TMR_INT_ENABLED_PPP_EVENT 0x02 +#define TMR_INT_ENABLED_UDP 0x04 +#define TMR_INT_ENABLED_CONFIG 0x20 + +/* Set Configuraton Command Definitions */ +#define PERCENT_TX_BUFF 60 +#define TIME_BETWEEN_CONF_REQ 30 +#define TIME_BETWEEN_PAP_CHAP_REQ 30 +#define WAIT_PAP_CHAP_WITHOUT_REPLY 300 +#define WAIT_AFTER_DCD_CTS_LOW 5 +#define TIME_DCD_CTS_LOW_AFTER_LNK_DOWN 10 +#define WAIT_DCD_HIGH_AFTER_ENABLE_COMM 900 +#define MAX_CONF_REQ_WITHOUT_REPLY 10 +#define MAX_TERM_REQ_WITHOUT_REPLY 2 +#define NUM_CONF_NAK_WITHOUT_REPLY 5 +#define NUM_AUTH_REQ_WITHOUT_REPLY 10 + +#define END_OFFSET 0x1F0 + + +/******Data Structures*****************************************************/ + +/* This structure is placed in the private data area of the device structure. + * The card structure used to occupy the private area but now the following + * structure will incorporate the card structure along with PPP specific data + */ + +typedef struct ppp_private_area +{ + struct net_device *slave; + sdla_t* card; + unsigned long router_start_time; /*router start time in sec */ + unsigned long tick_counter; /*used for 5 second counter*/ + unsigned mc; /*multicast support on or off*/ + unsigned char enable_IPX; + unsigned long network_number; + unsigned char pap; + unsigned char chap; + unsigned char sysname[31]; /* system name for in-bnd auth*/ + unsigned char userid[511]; /* list of user ids */ + unsigned char passwd[511]; /* list of passwords */ + unsigned protocol; /* SKB Protocol */ + u32 ip_local; /* Local IP Address */ + u32 ip_remote; /* remote IP Address */ + + u32 ip_local_tmp; + u32 ip_remote_tmp; + + unsigned char timer_int_enabled; /* Who enabled the timer inter*/ + unsigned char update_comms_stats; /* Used by update function */ + unsigned long curr_trace_addr; /* Trace information */ + unsigned long start_trace_addr; + unsigned long end_trace_addr; + + unsigned char interface_down; /* Brind down interface when channel + goes down */ + unsigned long config_wait_timeout; /* After if_open() if in dynamic if mode, + wait a few seconds before configuring */ + + unsigned short udp_pkt_lgth; + char udp_pkt_src; + char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT]; + + /* PPP specific statistics */ + + if_send_stat_t if_send_stat; + rx_intr_stat_t rx_intr_stat; + pipe_mgmt_stat_t pipe_mgmt_stat; + + unsigned long router_up_time; + + /* Polling work queue entry. Each interface + * has its own work queue entry, which is used + * to defer events from the interrupt */ + struct work_struct poll_work; + struct timer_list poll_delay_timer; + + u8 gateway; + u8 config_ppp; + u8 ip_error; + +}ppp_private_area_t; + +/* variable for keeping track of enabling/disabling FT1 monitor status */ +static int rCount = 0; + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +/****** Function Prototypes *************************************************/ + +/* WAN link driver entry points. These are called by the WAN router module. */ +static int update(struct wan_device *wandev); +static int new_if(struct wan_device *wandev, struct net_device *dev, + wanif_conf_t *conf); +static int del_if(struct wan_device *wandev, struct net_device *dev); + +/* WANPIPE-specific entry points */ +static int wpp_exec (struct sdla *card, void *u_cmd, void *u_data); + +/* Network device interface */ +static int if_init(struct net_device *dev); +static int if_open(struct net_device *dev); +static int if_close(struct net_device *dev); +static int if_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + void *daddr, void *saddr, unsigned len); + +static void if_tx_timeout(struct net_device *dev); + +static int if_rebuild_hdr(struct sk_buff *skb); +static struct net_device_stats *if_stats(struct net_device *dev); +static int if_send(struct sk_buff *skb, struct net_device *dev); + + +/* PPP firmware interface functions */ +static int ppp_read_version(sdla_t *card, char *str); +static int ppp_set_outbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area); +static int ppp_set_inbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area); +static int ppp_configure(sdla_t *card, void *data); +static int ppp_set_intr_mode(sdla_t *card, unsigned char mode); +static int ppp_comm_enable(sdla_t *card); +static int ppp_comm_disable(sdla_t *card); +static int ppp_comm_disable_shutdown(sdla_t *card); +static int ppp_get_err_stats(sdla_t *card); +static int ppp_send(sdla_t *card, void *data, unsigned len, unsigned proto); +static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb); + +static void wpp_isr(sdla_t *card); +static void rx_intr(sdla_t *card); +static void event_intr(sdla_t *card); +static void timer_intr(sdla_t *card); + +/* Background polling routines */ +static void process_route(sdla_t *card); +static void retrigger_comm(sdla_t *card); + +/* Miscellaneous functions */ +static int read_info( sdla_t *card ); +static int read_connection_info (sdla_t *card); +static void remove_route( sdla_t *card ); +static int config508(struct net_device *dev, sdla_t *card); +static void show_disc_cause(sdla_t * card, unsigned cause); +static int reply_udp( unsigned char *data, unsigned int mbox_len ); +static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev, + ppp_private_area_t *ppp_priv_area); +static void init_ppp_tx_rx_buff( sdla_t *card ); +static int intr_test( sdla_t *card ); +static int udp_pkt_type( struct sk_buff *skb , sdla_t *card); +static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area); +static void init_global_statistics( sdla_t *card ); +static int tokenize(char *str, char **tokens); +static char* strstrip(char *str, char *s); +static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev, + struct sk_buff *skb); + +static int config_ppp (sdla_t *); +static void ppp_poll(struct net_device *dev); +static void trigger_ppp_poll(struct net_device *dev); +static void ppp_poll_delay (unsigned long dev_ptr); + + +static int Read_connection_info; +static int Intr_test_counter; +static unsigned short available_buffer_space; + + +/* IPX functions */ +static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, + unsigned char incoming); +static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_PX, + unsigned long network_number, unsigned short proto); + +/* Lock Functions */ +static void s508_lock (sdla_t *card, unsigned long *smp_flags); +static void s508_unlock (sdla_t *card, unsigned long *smp_flags); + +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + ppp_private_area_t* ppp_priv_area ); +static unsigned short calc_checksum (char *data, int len); +static void disable_comm (sdla_t *card); +static int detect_and_fix_tx_bug (sdla_t *card); + +/****** Public Functions ****************************************************/ + +/*============================================================================ + * PPP protocol initialization routine. + * + * This routine is called by the main WANPIPE module during setup. At this + * point adapter is completely initialized and firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the adapter data space. + * + * Return: 0 o.k. + * < 0 failure. + */ +int wpp_init(sdla_t *card, wandev_conf_t *conf) +{ + ppp_flags_t *flags; + union + { + char str[80]; + } u; + + /* Verify configuration ID */ + if (conf->config_id != WANCONFIG_PPP) { + + printk(KERN_INFO "%s: invalid configuration ID %u!\n", + card->devname, conf->config_id); + return -EINVAL; + + } + + /* Initialize miscellaneous pointers to structures on the adapter */ + switch (card->hw.type) { + + case SDLA_S508: + card->mbox =(void*)(card->hw.dpmbase + PPP508_MB_OFFS); + card->flags=(void*)(card->hw.dpmbase + PPP508_FLG_OFFS); + break; + + case SDLA_S514: + card->mbox =(void*)(card->hw.dpmbase + PPP514_MB_OFFS); + card->flags=(void*)(card->hw.dpmbase + PPP514_FLG_OFFS); + break; + + default: + return -EINVAL; + + } + flags = card->flags; + + /* Read firmware version. Note that when adapter initializes, it + * clears the mailbox, so it may appear that the first command was + * executed successfully when in fact it was merely erased. To work + * around this, we execute the first command twice. + */ + if (ppp_read_version(card, NULL) || ppp_read_version(card, u.str)) + return -EIO; + + printk(KERN_INFO "%s: running PPP firmware v%s\n",card->devname, u.str); + /* Adjust configuration and set defaults */ + card->wandev.mtu = (conf->mtu) ? + min_t(unsigned int, conf->mtu, PPP_MAX_MTU) : PPP_DFLT_MTU; + + card->wandev.bps = conf->bps; + card->wandev.interface = conf->interface; + card->wandev.clocking = conf->clocking; + card->wandev.station = conf->station; + card->isr = &wpp_isr; + card->poll = NULL; + card->exec = &wpp_exec; + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + card->wandev.udp_port = conf->udp_port; + card->wandev.ttl = conf->ttl; + card->wandev.state = WAN_DISCONNECTED; + card->disable_comm = &disable_comm; + card->irq_dis_if_send_count = 0; + card->irq_dis_poll_count = 0; + card->u.p.authenticator = conf->u.ppp.authenticator; + card->u.p.ip_mode = conf->u.ppp.ip_mode ? + conf->u.ppp.ip_mode : WANOPT_PPP_STATIC; + card->TracingEnabled = 0; + Read_connection_info = 1; + + /* initialize global statistics */ + init_global_statistics( card ); + + + + if (!card->configured){ + int err; + + Intr_test_counter = 0; + err = intr_test(card); + + if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { + printk("%s: Interrupt Test Failed, Counter: %i\n", + card->devname, Intr_test_counter); + printk( "%s: Please choose another interrupt\n",card->devname); + return -EIO; + } + + printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", + card->devname, Intr_test_counter); + card->configured = 1; + } + + ppp_set_intr_mode(card, PPP_INTR_TIMER); + + /* Turn off the transmit and timer interrupt */ + flags->imask &= ~PPP_INTR_TIMER; + + printk(KERN_INFO "\n"); + + return 0; +} + +/******* WAN Device Driver Entry Points *************************************/ + +/*============================================================================ + * Update device status & statistics. + */ +static int update(struct wan_device *wandev) +{ + sdla_t* card = wandev->private; + struct net_device* dev; + volatile ppp_private_area_t *ppp_priv_area; + ppp_flags_t *flags = card->flags; + unsigned long timeout; + + /* sanity checks */ + if ((wandev == NULL) || (wandev->private == NULL)) + return -EFAULT; + + if (wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + /* Shutdown bug fix. This function can be + * called with NULL dev pointer during + * shutdown + */ + if ((dev=card->wandev.dev) == NULL){ + return -ENODEV; + } + + if ((ppp_priv_area=dev->priv) == NULL){ + return -ENODEV; + } + + ppp_priv_area->update_comms_stats = 2; + ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE; + flags->imask |= PPP_INTR_TIMER; + + /* wait a maximum of 1 second for the statistics to be updated */ + timeout = jiffies; + for(;;) { + if(ppp_priv_area->update_comms_stats == 0){ + break; + } + if (time_after(jiffies, timeout + 1 * HZ)){ + ppp_priv_area->update_comms_stats = 0; + ppp_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + return -EAGAIN; + } + } + + return 0; +} + +/*============================================================================ + * Create new logical channel. + * This routine is called by the router when ROUTER_IFNEW IOCTL is being + * handled. + * o parse media- and hardware-specific configuration + * o make sure that a new channel can be created + * o allocate resources, if necessary + * o prepare network device structure for registaration. + * + * Return: 0 o.k. + * < 0 failure (channel will not be created) + */ +static int new_if(struct wan_device *wandev, struct net_device *dev, + wanif_conf_t *conf) +{ + sdla_t *card = wandev->private; + ppp_private_area_t *ppp_priv_area; + + if (wandev->ndev) + return -EEXIST; + + + printk(KERN_INFO "%s: Configuring Interface: %s\n", + card->devname, conf->name); + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { + + printk(KERN_INFO "%s: Invalid interface name!\n", + card->devname); + return -EINVAL; + + } + + /* allocate and initialize private data */ + ppp_priv_area = kmalloc(sizeof(ppp_private_area_t), GFP_KERNEL); + + if( ppp_priv_area == NULL ) + return -ENOMEM; + + memset(ppp_priv_area, 0, sizeof(ppp_private_area_t)); + + ppp_priv_area->card = card; + + /* initialize data */ + strcpy(card->u.p.if_name, conf->name); + + /* initialize data in ppp_private_area structure */ + + init_ppp_priv_struct( ppp_priv_area ); + + ppp_priv_area->mc = conf->mc; + ppp_priv_area->pap = conf->pap; + ppp_priv_area->chap = conf->chap; + + /* Option to bring down the interface when + * the link goes down */ + if (conf->if_down){ + set_bit(DYN_OPT_ON,&ppp_priv_area->interface_down); + printk("%s: Dynamic interface configuration enabled\n", + card->devname); + } + + /* If no user ids are specified */ + if(!strlen(conf->userid) && (ppp_priv_area->pap||ppp_priv_area->chap)){ + kfree(ppp_priv_area); + return -EINVAL; + } + + /* If no passwords are specified */ + if(!strlen(conf->passwd) && (ppp_priv_area->pap||ppp_priv_area->chap)){ + kfree(ppp_priv_area); + return -EINVAL; + } + + if(strlen(conf->sysname) > 31){ + kfree(ppp_priv_area); + return -EINVAL; + } + + /* If no system name is specified */ + if(!strlen(conf->sysname) && (card->u.p.authenticator)){ + kfree(ppp_priv_area); + return -EINVAL; + } + + /* copy the data into the ppp private structure */ + memcpy(ppp_priv_area->userid, conf->userid, strlen(conf->userid)); + memcpy(ppp_priv_area->passwd, conf->passwd, strlen(conf->passwd)); + memcpy(ppp_priv_area->sysname, conf->sysname, strlen(conf->sysname)); + + + ppp_priv_area->enable_IPX = conf->enable_IPX; + if (conf->network_number){ + ppp_priv_area->network_number = conf->network_number; + }else{ + ppp_priv_area->network_number = 0xDEADBEEF; + } + + /* Tells us that if this interface is a + * gateway or not */ + if ((ppp_priv_area->gateway = conf->gateway) == WANOPT_YES){ + printk(KERN_INFO "%s: Interface %s is set as a gateway.\n", + card->devname,card->u.p.if_name); + } + + /* prepare network device data space for registration */ + strcpy(dev->name,card->u.p.if_name); + + dev->init = &if_init; + dev->priv = ppp_priv_area; + dev->mtu = min_t(unsigned int, dev->mtu, card->wandev.mtu); + + /* Initialize the polling work routine */ + INIT_WORK(&ppp_priv_area->poll_work, (void*)(void*)ppp_poll, dev); + + /* Initialize the polling delay timer */ + init_timer(&ppp_priv_area->poll_delay_timer); + ppp_priv_area->poll_delay_timer.data = (unsigned long)dev; + ppp_priv_area->poll_delay_timer.function = ppp_poll_delay; + + + /* Since we start with dummy IP addresses we can say + * that route exists */ + printk(KERN_INFO "\n"); + + return 0; +} + +/*============================================================================ + * Delete logical channel. + */ +static int del_if(struct wan_device *wandev, struct net_device *dev) +{ + return 0; +} + +static void disable_comm (sdla_t *card) +{ + ppp_comm_disable_shutdown(card); + return; +} + +/****** WANPIPE-specific entry points ***************************************/ + +/*============================================================================ + * Execute adapter interface command. + */ + +//FIXME: Why do we need this ???? +static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data) +{ + ppp_mbox_t *mbox = card->mbox; + int len; + + if (copy_from_user((void*)&mbox->cmd, u_cmd, sizeof(ppp_cmd_t))) + return -EFAULT; + + len = mbox->cmd.length; + + if (len) { + + if( copy_from_user((void*)&mbox->data, u_data, len)) + return -EFAULT; + + } + + /* execute command */ + if (!sdla_exec(mbox)) + return -EIO; + + /* return result */ + if( copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(ppp_cmd_t))) + return -EFAULT; + len = mbox->cmd.length; + + if (len && u_data && copy_to_user(u_data, (void*)&mbox->data, len)) + return -EFAULT; + + return 0; +} + +/****** Network Device Interface ********************************************/ + +/*============================================================================ + * Initialize Linux network interface. + * + * This routine is called only once for each interface, during Linux network + * interface registration. Returning anything but zero will fail interface + * registration. + */ +static int if_init(struct net_device *dev) +{ + ppp_private_area_t *ppp_priv_area = dev->priv; + sdla_t *card = ppp_priv_area->card; + struct wan_device *wandev = &card->wandev; + + /* Initialize device driver entry points */ + dev->open = &if_open; + dev->stop = &if_close; + dev->hard_header = &if_header; + dev->rebuild_header = &if_rebuild_hdr; + dev->hard_start_xmit = &if_send; + dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + /* Initialize media-specific parameters */ + dev->type = ARPHRD_PPP; /* ARP h/w type */ + dev->flags |= IFF_POINTOPOINT; + dev->flags |= IFF_NOARP; + + /* Enable Mulitcasting if specified by user*/ + if (ppp_priv_area->mc == WANOPT_YES){ + dev->flags |= IFF_MULTICAST; + } + + dev->mtu = wandev->mtu; + dev->hard_header_len = PPP_HDR_LEN; /* media header length */ + + /* Initialize hardware parameters (just for reference) */ + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + dev->mem_start = wandev->maddr; + dev->mem_end = wandev->maddr + wandev->msize - 1; + + /* Set transmit buffer queue length */ + dev->tx_queue_len = 100; + SET_MODULE_OWNER(dev); + + return 0; +} + +/*============================================================================ + * Open network interface. + * o enable communications and interrupts. + * o prevent module from unloading by incrementing use count + * + * Return 0 if O.k. or errno. + */ +static int if_open(struct net_device *dev) +{ + ppp_private_area_t *ppp_priv_area = dev->priv; + sdla_t *card = ppp_priv_area->card; + struct timeval tv; + //unsigned long smp_flags; + + if (netif_running(dev)) + return -EBUSY; + + wanpipe_open(card); + + netif_start_queue(dev); + + do_gettimeofday( &tv ); + ppp_priv_area->router_start_time = tv.tv_sec; + + /* We cannot configure the card here because we don't + * have access to the interface IP addresses. + * Once the interface initilization is complete, we will be + * able to access the IP addresses. Therefore, + * configure the ppp link in the poll routine */ + set_bit(0,&ppp_priv_area->config_ppp); + ppp_priv_area->config_wait_timeout=jiffies; + + /* Start the PPP configuration after 1sec delay. + * This will give the interface initilization time + * to finish its configuration */ + mod_timer(&ppp_priv_area->poll_delay_timer, jiffies + HZ); + return 0; +} + +/*============================================================================ + * Close network interface. + * o if this is the last open, then disable communications and interrupts. + * o reset flags. + */ +static int if_close(struct net_device *dev) +{ + ppp_private_area_t *ppp_priv_area = dev->priv; + sdla_t *card = ppp_priv_area->card; + + netif_stop_queue(dev); + wanpipe_close(card); + + del_timer (&ppp_priv_area->poll_delay_timer); + return 0; +} + +/*============================================================================ + * Build media header. + * + * The trick here is to put packet type (Ethertype) into 'protocol' field of + * the socket buffer, so that we don't forget it. If packet type is not + * supported, set skb->protocol to 0 and discard packet later. + * + * Return: media header length. + */ +static int if_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) +{ + switch (type) + { + case ETH_P_IP: + case ETH_P_IPX: + skb->protocol = htons(type); + break; + + default: + skb->protocol = 0; + } + + return PPP_HDR_LEN; +} + +/*============================================================================ + * Re-build media header. + * + * Return: 1 physical address resolved. + * 0 physical address not resolved + */ +static int if_rebuild_hdr (struct sk_buff *skb) +{ + struct net_device *dev = skb->dev; + ppp_private_area_t *ppp_priv_area = dev->priv; + sdla_t *card = ppp_priv_area->card; + + printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", + card->devname, dev->name); + return 1; +} + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout(struct net_device *dev) +{ + ppp_private_area_t* chan = dev->priv; + sdla_t *card = chan->card; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + ++ chan->if_send_stat.if_send_tbusy; + ++card->wandev.stats.collisions; + + printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name); + ++chan->if_send_stat.if_send_tbusy_timeout; + netif_wake_queue (dev); +} + + + +/*============================================================================ + * Send a packet on a network interface. + * o set tbusy flag (marks start of the transmission) to block a timer-based + * transmit from overlapping. + * o check link state. If link is not up, then drop the packet. + * o execute adapter send command. + * o free socket buffer + * + * Return: 0 complete (socket buffer must be freed) + * non-0 packet may be re-transmitted (tbusy must be set) + * + * Notes: + * 1. This routine is called either by the protocol stack or by the "net + * bottom half" (with interrupts enabled). + * 2. Setting tbusy flag will inhibit further transmit requests from the + * protocol stack and can be used for flow control with protocol layer. + */ +static int if_send (struct sk_buff *skb, struct net_device *dev) +{ + ppp_private_area_t *ppp_priv_area = dev->priv; + sdla_t *card = ppp_priv_area->card; + unsigned char *sendpacket; + unsigned long smp_flags; + ppp_flags_t *flags = card->flags; + int udp_type; + int err=0; + + ++ppp_priv_area->if_send_stat.if_send_entry; + + netif_stop_queue(dev); + + if (skb == NULL) { + + /* If we get here, some higher layer thinks we've missed an + * tx-done interrupt. + */ + printk(KERN_INFO "%s: interface %s got kicked!\n", + card->devname, dev->name); + + ++ppp_priv_area->if_send_stat.if_send_skb_null; + + netif_wake_queue(dev); + return 0; + } + + sendpacket = skb->data; + + udp_type = udp_pkt_type( skb, card ); + + + if (udp_type == UDP_PTPIPE_TYPE){ + if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev, + ppp_priv_area)){ + flags->imask |= PPP_INTR_TIMER; + } + ++ppp_priv_area->if_send_stat.if_send_PIPE_request; + netif_start_queue(dev); + return 0; + } + + /* Check for broadcast and multicast addresses + * If found, drop (deallocate) a packet and return. + */ + if(chk_bcast_mcast_addr(card, dev, skb)){ + ++card->wandev.stats.tx_dropped; + dev_kfree_skb_any(skb); + netif_start_queue(dev); + return 0; + } + + + if(card->hw.type != SDLA_S514){ + s508_lock(card,&smp_flags); + } + + if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) { + + printk(KERN_INFO "%s: Critical in if_send: %lx\n", + card->wandev.name,card->wandev.critical); + + ++card->wandev.stats.tx_dropped; + ++ppp_priv_area->if_send_stat.if_send_critical_non_ISR; + netif_start_queue(dev); + goto if_send_exit_crit; + } + + if (card->wandev.state != WAN_CONNECTED) { + + ++ppp_priv_area->if_send_stat.if_send_wan_disconnected; + ++card->wandev.stats.tx_dropped; + netif_start_queue(dev); + + } else if (!skb->protocol) { + ++ppp_priv_area->if_send_stat.if_send_protocol_error; + ++card->wandev.stats.tx_errors; + netif_start_queue(dev); + + } else { + + /*If it's IPX change the network numbers to 0 if they're ours.*/ + if( skb->protocol == htons(ETH_P_IPX) ) { + if(ppp_priv_area->enable_IPX) { + switch_net_numbers( skb->data, + ppp_priv_area->network_number, 0); + } else { + ++card->wandev.stats.tx_dropped; + netif_start_queue(dev); + goto if_send_exit_crit; + } + } + + if (ppp_send(card, skb->data, skb->len, skb->protocol)) { + netif_stop_queue(dev); + ++ppp_priv_area->if_send_stat.if_send_adptr_bfrs_full; + ++ppp_priv_area->if_send_stat.if_send_tx_int_enabled; + } else { + ++ppp_priv_area->if_send_stat.if_send_bfr_passed_to_adptr; + ++card->wandev.stats.tx_packets; + card->wandev.stats.tx_bytes += skb->len; + netif_start_queue(dev); + dev->trans_start = jiffies; + } + } + +if_send_exit_crit: + + if (!(err=netif_queue_stopped(dev))){ + dev_kfree_skb_any(skb); + }else{ + ppp_priv_area->tick_counter = jiffies; + flags->imask |= PPP_INTR_TXRDY; /* unmask Tx interrupts */ + } + + clear_bit(SEND_CRIT,&card->wandev.critical); + if(card->hw.type != SDLA_S514){ + s508_unlock(card,&smp_flags); + } + + return err; +} + + +/*============================================================================= + * Store a UDP management packet for later processing. + */ + +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + ppp_private_area_t* ppp_priv_area ) +{ + int udp_pkt_stored = 0; + + if(!ppp_priv_area->udp_pkt_lgth && (skb->len<=MAX_LGTH_UDP_MGNT_PKT)){ + ppp_priv_area->udp_pkt_lgth = skb->len; + ppp_priv_area->udp_pkt_src = udp_pkt_src; + memcpy(ppp_priv_area->udp_pkt_data, skb->data, skb->len); + ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UDP; + ppp_priv_area->protocol = skb->protocol; + udp_pkt_stored = 1; + }else{ + if (skb->len > MAX_LGTH_UDP_MGNT_PKT){ + printk(KERN_INFO "%s: PIPEMON UDP request too long : %i\n", + card->devname, skb->len); + }else{ + printk(KERN_INFO "%s: PIPEMON UPD request already pending\n", + card->devname); + } + ppp_priv_area->udp_pkt_lgth = 0; + } + + if(udp_pkt_src == UDP_PKT_FRM_STACK){ + dev_kfree_skb_any(skb); + }else{ + dev_kfree_skb_any(skb); + } + + return(udp_pkt_stored); +} + + + +/*============================================================================ + * Reply to UDP Management system. + * Return length of reply. + */ +static int reply_udp( unsigned char *data, unsigned int mbox_len ) +{ + unsigned short len, udp_length, temp, ip_length; + unsigned long ip_temp; + int even_bound = 0; + ppp_udp_pkt_t *p_udp_pkt = (ppp_udp_pkt_t *)data; + + /* Set length of packet */ + len = sizeof(ip_pkt_t)+ + sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + /* fill in UDP reply */ + p_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; + + /* fill in UDP length */ + udp_length = sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + + /* put it on an even boundary */ + if ( udp_length & 0x0001 ) { + udp_length += 1; + len += 1; + even_bound=1; + } + + temp = (udp_length<<8)|(udp_length>>8); + p_udp_pkt->udp_pkt.udp_length = temp; + + + /* swap UDP ports */ + temp = p_udp_pkt->udp_pkt.udp_src_port; + p_udp_pkt->udp_pkt.udp_src_port = + p_udp_pkt->udp_pkt.udp_dst_port; + p_udp_pkt->udp_pkt.udp_dst_port = temp; + + + /* add UDP pseudo header */ + temp = 0x1100; + *((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound)) = temp; + temp = (udp_length<<8)|(udp_length>>8); + *((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound+2)) = temp; + + /* calculate UDP checksum */ + p_udp_pkt->udp_pkt.udp_checksum = 0; + p_udp_pkt->udp_pkt.udp_checksum = + calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET); + + /* fill in IP length */ + ip_length = udp_length + sizeof(ip_pkt_t); + temp = (ip_length<<8)|(ip_length>>8); + p_udp_pkt->ip_pkt.total_length = temp; + + /* swap IP addresses */ + ip_temp = p_udp_pkt->ip_pkt.ip_src_address; + p_udp_pkt->ip_pkt.ip_src_address = p_udp_pkt->ip_pkt.ip_dst_address; + p_udp_pkt->ip_pkt.ip_dst_address = ip_temp; + + /* fill in IP checksum */ + p_udp_pkt->ip_pkt.hdr_checksum = 0; + p_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t)); + + return len; + +} /* reply_udp */ + +unsigned short calc_checksum (char *data, int len) +{ + unsigned short temp; + unsigned long sum=0; + int i; + + for( i = 0; i > 16 ) { + sum = (sum & 0xffffUL) + (sum >> 16); + } + + temp = (unsigned short)sum; + temp = ~temp; + + if( temp == 0 ) + temp = 0xffff; + + return temp; +} + +/* + If incoming is 0 (outgoing)- if the net numbers is ours make it 0 + if incoming is 1 - if the net number is 0 make it ours + +*/ +static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming) +{ + unsigned long pnetwork_number; + + pnetwork_number = (unsigned long)((sendpacket[6] << 24) + + (sendpacket[7] << 16) + (sendpacket[8] << 8) + + sendpacket[9]); + + if (!incoming) { + //If the destination network number is ours, make it 0 + if( pnetwork_number == network_number) { + sendpacket[6] = sendpacket[7] = sendpacket[8] = + sendpacket[9] = 0x00; + } + } else { + //If the incoming network is 0, make it ours + if( pnetwork_number == 0) { + sendpacket[6] = (unsigned char)(network_number >> 24); + sendpacket[7] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[8] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[9] = (unsigned char)(network_number & + 0x000000FF); + } + } + + + pnetwork_number = (unsigned long)((sendpacket[18] << 24) + + (sendpacket[19] << 16) + (sendpacket[20] << 8) + + sendpacket[21]); + + if( !incoming ) { + //If the source network is ours, make it 0 + if( pnetwork_number == network_number) { + sendpacket[18] = sendpacket[19] = sendpacket[20] = + sendpacket[21] = 0x00; + } + } else { + //If the source network is 0, make it ours + if( pnetwork_number == 0 ) { + sendpacket[18] = (unsigned char)(network_number >> 24); + sendpacket[19] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[20] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[21] = (unsigned char)(network_number & + 0x000000FF); + } + } +} /* switch_net_numbers */ + +/*============================================================================ + * Get ethernet-style interface statistics. + * Return a pointer to struct net_device_stats. + */ +static struct net_device_stats *if_stats(struct net_device *dev) +{ + + ppp_private_area_t *ppp_priv_area = dev->priv; + sdla_t* card; + + if( ppp_priv_area == NULL ) + return NULL; + + card = ppp_priv_area->card; + return &card->wandev.stats; +} + +/****** PPP Firmware Interface Functions ************************************/ + +/*============================================================================ + * Read firmware code version. + * Put code version as ASCII string in str. + */ +static int ppp_read_version(sdla_t *card, char *str) +{ + ppp_mbox_t *mb = card->mbox; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + mb->cmd.command = PPP_READ_CODE_VERSION; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) + + ppp_error(card, err, mb); + + else if (str) { + + int len = mb->cmd.length; + + memcpy(str, mb->data, len); + str[len] = '\0'; + + } + + return err; +} +/*=========================================================================== + * Set Out-Bound Authentication. +*/ +static int ppp_set_outbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area) +{ + ppp_mbox_t *mb = card->mbox; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + memset(&mb->data, 0, (strlen(ppp_priv_area->userid) + + strlen(ppp_priv_area->passwd) + 2 ) ); + memcpy(mb->data, ppp_priv_area->userid, strlen(ppp_priv_area->userid)); + memcpy((mb->data + strlen(ppp_priv_area->userid) + 1), + ppp_priv_area->passwd, strlen(ppp_priv_area->passwd)); + + mb->cmd.length = strlen(ppp_priv_area->userid) + + strlen(ppp_priv_area->passwd) + 2 ; + + mb->cmd.command = PPP_SET_OUTBOUND_AUTH; + + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) + ppp_error(card, err, mb); + + return err; +} + +/*=========================================================================== + * Set In-Bound Authentication. +*/ +static int ppp_set_inbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area) +{ + ppp_mbox_t *mb = card->mbox; + int err, i; + char* user_tokens[32]; + char* pass_tokens[32]; + int userids, passwds; + int add_ptr; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + memset(&mb->data, 0, 1008); + memcpy(mb->data, ppp_priv_area->sysname, + strlen(ppp_priv_area->sysname)); + + /* Parse the userid string and the password string and build a string + to copy it to the data area of the command structure. The string + will look like "SYS_NAMEUSER1PASS1USER2PASS2 + .... " + */ + userids = tokenize( ppp_priv_area->userid, user_tokens); + passwds = tokenize( ppp_priv_area->passwd, pass_tokens); + + if (userids != passwds){ + printk(KERN_INFO "%s: Number of passwords does not equal the number of user ids\n", card->devname); + return 1; + } + + add_ptr = strlen(ppp_priv_area->sysname) + 1; + for (i=0; idata + add_ptr), user_tokens[i], + strlen(user_tokens[i])); + memcpy((mb->data + add_ptr + strlen(user_tokens[i]) + 1), + pass_tokens[i], strlen(pass_tokens[i])); + add_ptr = add_ptr + strlen(user_tokens[i]) + 1 + + strlen(pass_tokens[i]) + 1; + } + + mb->cmd.length = add_ptr + 1; + mb->cmd.command = PPP_SET_INBOUND_AUTH; + + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) + ppp_error(card, err, mb); + + return err; +} + + +/*============================================================================ + * Tokenize string. + * Parse a string of the following syntax: + * ,,... + * and fill array of tokens with pointers to string elements. + * + */ +static int tokenize (char *str, char **tokens) +{ + int cnt = 0; + + tokens[0] = strsep(&str, "/"); + while (tokens[cnt] && (cnt < 32 - 1)) + { + tokens[cnt] = strstrip(tokens[cnt], " \t"); + tokens[++cnt] = strsep(&str, "/"); + } + return cnt; +} + +/*============================================================================ + * Strip leading and trailing spaces off the string str. + */ +static char* strstrip (char *str, char* s) +{ + char *eos = str + strlen(str); /* -> end of string */ + + while (*str && strchr(s, *str)) + ++str /* strip leading spaces */ + ; + while ((eos > str) && strchr(s, *(eos - 1))) + --eos /* strip trailing spaces */ + ; + *eos = '\0'; + return str; +} +/*============================================================================ + * Configure PPP firmware. + */ +static int ppp_configure(sdla_t *card, void *data) +{ + ppp_mbox_t *mb = card->mbox; + int data_len = sizeof(ppp508_conf_t); + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + memcpy(mb->data, data, data_len); + mb->cmd.length = data_len; + mb->cmd.command = PPP_SET_CONFIG; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) + ppp_error(card, err, mb); + + return err; +} + +/*============================================================================ + * Set interrupt mode. + */ +static int ppp_set_intr_mode(sdla_t *card, unsigned char mode) +{ + ppp_mbox_t *mb = card->mbox; + ppp_intr_info_t *ppp_intr_data = (ppp_intr_info_t *) &mb->data[0]; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + ppp_intr_data->i_enable = mode; + + ppp_intr_data->irq = card->hw.irq; + mb->cmd.length = 2; + + /* If timer has been enabled, set the timer delay to 1sec */ + if (mode & 0x80){ + ppp_intr_data->timer_len = 250; //5;//100; //250; + mb->cmd.length = 4; + } + + mb->cmd.command = PPP_SET_INTR_FLAGS; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) + ppp_error(card, err, mb); + + + return err; +} + +/*============================================================================ + * Enable communications. + */ +static int ppp_comm_enable(sdla_t *card) +{ + ppp_mbox_t *mb = card->mbox; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + mb->cmd.command = PPP_COMM_ENABLE; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) + ppp_error(card, err, mb); + else + card->u.p.comm_enabled = 1; + + return err; +} + +/*============================================================================ + * Disable communications. + */ +static int ppp_comm_disable(sdla_t *card) +{ + ppp_mbox_t *mb = card->mbox; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + mb->cmd.command = PPP_COMM_DISABLE; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + if (err != CMD_OK) + ppp_error(card, err, mb); + else + card->u.p.comm_enabled = 0; + + return err; +} + +static int ppp_comm_disable_shutdown(sdla_t *card) +{ + ppp_mbox_t *mb = card->mbox; + ppp_intr_info_t *ppp_intr_data; + int err; + + if (!mb){ + return 1; + } + + ppp_intr_data = (ppp_intr_info_t *) &mb->data[0]; + + /* Disable all interrupts */ + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + ppp_intr_data->i_enable = 0; + + ppp_intr_data->irq = card->hw.irq; + mb->cmd.length = 2; + + mb->cmd.command = PPP_SET_INTR_FLAGS; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + /* Disable communicatinons */ + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + mb->cmd.command = PPP_COMM_DISABLE; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + card->u.p.comm_enabled = 0; + + return 0; +} + + + +/*============================================================================ + * Get communications error statistics. + */ +static int ppp_get_err_stats(sdla_t *card) +{ + ppp_mbox_t *mb = card->mbox; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + mb->cmd.command = PPP_READ_ERROR_STATS; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err == CMD_OK) { + + ppp_err_stats_t* stats = (void*)mb->data; + card->wandev.stats.rx_over_errors = stats->rx_overrun; + card->wandev.stats.rx_crc_errors = stats->rx_bad_crc; + card->wandev.stats.rx_missed_errors = stats->rx_abort; + card->wandev.stats.rx_length_errors = stats->rx_lost; + card->wandev.stats.tx_aborted_errors = stats->tx_abort; + + } else + ppp_error(card, err, mb); + + return err; +} + +/*============================================================================ + * Send packet. + * Return: 0 - o.k. + * 1 - no transmit buffers available + */ +static int ppp_send (sdla_t *card, void *data, unsigned len, unsigned proto) +{ + ppp_buf_ctl_t *txbuf = card->u.p.txbuf; + + if (txbuf->flag) + return 1; + + sdla_poke(&card->hw, txbuf->buf.ptr, data, len); + + txbuf->length = len; /* frame length */ + + if (proto == htons(ETH_P_IPX)) + txbuf->proto = 0x01; /* protocol ID */ + else + txbuf->proto = 0x00; /* protocol ID */ + + txbuf->flag = 1; /* start transmission */ + + /* Update transmit buffer control fields */ + card->u.p.txbuf = ++txbuf; + + if ((void*)txbuf > card->u.p.txbuf_last) + card->u.p.txbuf = card->u.p.txbuf_base; + + return 0; +} + +/****** Firmware Error Handler **********************************************/ + +/*============================================================================ + * Firmware error handler. + * This routine is called whenever firmware command returns non-zero + * return code. + * + * Return zero if previous command has to be cancelled. + */ +static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb) +{ + unsigned cmd = mb->cmd.command; + + switch (err) { + + case CMD_TIMEOUT: + printk(KERN_ERR "%s: command 0x%02X timed out!\n", + card->devname, cmd); + break; + + default: + printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n" + , card->devname, cmd, err); + } + + return 0; +} + +/****** Interrupt Handlers **************************************************/ + +/*============================================================================ + * PPP interrupt service routine. + */ +static void wpp_isr (sdla_t *card) +{ + ppp_flags_t *flags = card->flags; + char *ptr = &flags->iflag; + struct net_device *dev = card->wandev.dev; + int i; + + card->in_isr = 1; + ++card->statistics.isr_entry; + + if (!dev && flags->iflag != PPP_INTR_CMD){ + card->in_isr = 0; + flags->iflag = 0; + return; + } + + if (test_bit(PERI_CRIT, (void*)&card->wandev.critical)) { + card->in_isr = 0; + flags->iflag = 0; + return; + } + + + if(card->hw.type != SDLA_S514){ + if (test_bit(SEND_CRIT, (void*)&card->wandev.critical)) { + ++card->statistics.isr_already_critical; + printk (KERN_INFO "%s: Critical while in ISR!\n", + card->devname); + card->in_isr = 0; + flags->iflag = 0; + return; + } + } + + switch (flags->iflag) { + + case PPP_INTR_RXRDY: /* receive interrupt 0x01 (bit 0)*/ + ++card->statistics.isr_rx; + rx_intr(card); + break; + + case PPP_INTR_TXRDY: /* transmit interrupt 0x02 (bit 1)*/ + ++card->statistics.isr_tx; + flags->imask &= ~PPP_INTR_TXRDY; + netif_wake_queue(dev); + break; + + case PPP_INTR_CMD: /* interface command completed */ + ++Intr_test_counter; + ++card->statistics.isr_intr_test; + break; + + case PPP_INTR_MODEM: /* modem status change (DCD, CTS) 0x04 (bit 2)*/ + case PPP_INTR_DISC: /* Data link disconnected 0x10 (bit 4)*/ + case PPP_INTR_OPEN: /* Data link open 0x20 (bit 5)*/ + case PPP_INTR_DROP_DTR: /* DTR drop timeout expired 0x40 bit 6 */ + event_intr(card); + break; + + case PPP_INTR_TIMER: + timer_intr(card); + break; + + default: /* unexpected interrupt */ + ++card->statistics.isr_spurious; + printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", + card->devname, flags->iflag); + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + for(i = 0; i < 8; i ++) + printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); + printk(KERN_INFO "\n"); + } + + card->in_isr = 0; + flags->iflag = 0; + return; +} + +/*============================================================================ + * Receive interrupt handler. + */ +static void rx_intr(sdla_t *card) +{ + ppp_buf_ctl_t *rxbuf = card->rxmb; + struct net_device *dev = card->wandev.dev; + ppp_private_area_t *ppp_priv_area; + struct sk_buff *skb; + unsigned len; + void *buf; + int i; + ppp_flags_t *flags = card->flags; + char *ptr = &flags->iflag; + int udp_type; + + + if (rxbuf->flag != 0x01) { + + printk(KERN_INFO + "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", + card->devname, (unsigned)rxbuf, rxbuf->flag); + + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + + for(i = 0; i < 8; i ++) + printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); + printk(KERN_INFO "\n"); + + ++card->statistics.rx_intr_corrupt_rx_bfr; + + + /* Bug Fix: Mar 6 2000 + * If we get a corrupted mailbox, it means that driver + * is out of sync with the firmware. There is no recovery. + * If we don't turn off all interrupts for this card + * the machine will crash. + */ + printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname); + printk(KERN_INFO "Please contact Sangoma Technologies !\n"); + ppp_set_intr_mode(card,0); + return; + } + + if (dev && netif_running(dev) && dev->priv){ + + len = rxbuf->length; + ppp_priv_area = dev->priv; + + /* Allocate socket buffer */ + skb = dev_alloc_skb(len); + + if (skb != NULL) { + + /* Copy data to the socket buffer */ + unsigned addr = rxbuf->buf.ptr; + + if ((addr + len) > card->u.p.rx_top + 1) { + + unsigned tmp = card->u.p.rx_top - addr + 1; + buf = skb_put(skb, tmp); + sdla_peek(&card->hw, addr, buf, tmp); + addr = card->u.p.rx_base; + len -= tmp; + } + buf = skb_put(skb, len); + sdla_peek(&card->hw, addr, buf, len); + + /* Decapsulate packet */ + switch (rxbuf->proto) { + + case 0x00: + skb->protocol = htons(ETH_P_IP); + break; + + case 0x01: + skb->protocol = htons(ETH_P_IPX); + break; + } + + udp_type = udp_pkt_type( skb, card ); + + if (udp_type == UDP_PTPIPE_TYPE){ + + /* Handle a UDP Request in Timer Interrupt */ + if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, card, skb, dev, + ppp_priv_area)){ + flags->imask |= PPP_INTR_TIMER; + } + ++ppp_priv_area->rx_intr_stat.rx_intr_PIPE_request; + + + } else if (handle_IPXWAN(skb->data,card->devname, + ppp_priv_area->enable_IPX, + ppp_priv_area->network_number, + skb->protocol)) { + + /* Handle an IPXWAN packet */ + if( ppp_priv_area->enable_IPX) { + + /* Make sure we are not already sending */ + if (!test_bit(SEND_CRIT, &card->wandev.critical)){ + ppp_send(card, skb->data, skb->len, htons(ETH_P_IPX)); + } + dev_kfree_skb_any(skb); + + } else { + ++card->wandev.stats.rx_dropped; + } + } else { + /* Pass data up the protocol stack */ + skb->dev = dev; + skb->mac.raw = skb->data; + + ++card->wandev.stats.rx_packets; + card->wandev.stats.rx_bytes += skb->len; + ++ppp_priv_area->rx_intr_stat.rx_intr_bfr_passed_to_stack; + netif_rx(skb); + dev->last_rx = jiffies; + } + + } else { + + if (net_ratelimit()){ + printk(KERN_INFO "%s: no socket buffers available!\n", + card->devname); + } + ++card->wandev.stats.rx_dropped; + ++ppp_priv_area->rx_intr_stat.rx_intr_no_socket; + } + + } else { + ++card->statistics.rx_intr_dev_not_started; + } + + /* Release buffer element and calculate a pointer to the next one */ + rxbuf->flag = 0x00; + card->rxmb = ++rxbuf; + if ((void*)rxbuf > card->u.p.rxbuf_last) + card->rxmb = card->u.p.rxbuf_base; +} + + +void event_intr (sdla_t *card) +{ + + struct net_device* dev = card->wandev.dev; + ppp_private_area_t* ppp_priv_area = dev->priv; + volatile ppp_flags_t *flags = card->flags; + + switch (flags->iflag){ + + case PPP_INTR_MODEM: /* modem status change (DCD, CTS) 0x04 (bit 2)*/ + + if (net_ratelimit()){ + printk (KERN_INFO "%s: Modem status: DCD=%s CTS=%s\n", + card->devname, DCD(flags->mstatus), CTS(flags->mstatus)); + } + break; + + case PPP_INTR_DISC: /* Data link disconnected 0x10 (bit 4)*/ + + NEX_PRINTK (KERN_INFO "Data link disconnected intr Cause %X\n", + flags->disc_cause); + + if (flags->disc_cause & + (PPP_LOCAL_TERMINATION | PPP_DCD_CTS_DROP | + PPP_REMOTE_TERMINATION)) { + + if (card->u.p.ip_mode == WANOPT_PPP_PEER) { + set_bit(0,&Read_connection_info); + } + wanpipe_set_state(card, WAN_DISCONNECTED); + + show_disc_cause(card, flags->disc_cause); + ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT; + flags->imask |= PPP_INTR_TIMER; + trigger_ppp_poll(dev); + } + break; + + case PPP_INTR_OPEN: /* Data link open 0x20 (bit 5)*/ + + NEX_PRINTK (KERN_INFO "%s: PPP Link Open, LCP=%s IP=%s\n", + card->devname,LCP(flags->lcp_state), + IP(flags->ip_state)); + + if (flags->lcp_state == 0x09 && + (flags->ip_state == 0x09 || flags->ipx_state == 0x09)){ + + /* Initialize the polling timer and set the state + * to WAN_CONNNECTED */ + + + /* BUG FIX: When the protocol restarts, during heavy + * traffic, board tx buffers and driver tx buffers + * can go out of sync. This checks the condition + * and if the tx buffers are out of sync, the + * protocols are restarted. + * I don't know why the board tx buffer is out + * of sync. It could be that a packets is tx + * while the link is down, but that is not + * possible. The other possiblility is that the + * firmware doesn't reinitialize properly. + * FIXME: A better fix should be found. + */ + if (detect_and_fix_tx_bug(card)){ + + ppp_comm_disable(card); + + wanpipe_set_state(card, WAN_DISCONNECTED); + + ppp_priv_area->timer_int_enabled |= + TMR_INT_ENABLED_PPP_EVENT; + flags->imask |= PPP_INTR_TIMER; + break; + } + + card->state_tick = jiffies; + wanpipe_set_state(card, WAN_CONNECTED); + + NEX_PRINTK(KERN_INFO "CON: L Tx: %lx B Tx: %lx || L Rx %lx B Rx %lx\n", + (unsigned long)card->u.p.txbuf, *card->u.p.txbuf_next, + (unsigned long)card->rxmb, *card->u.p.rxbuf_next); + + /* Tell timer interrupt that PPP event occurred */ + ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT; + flags->imask |= PPP_INTR_TIMER; + + /* If we are in PEER mode, we must first obtain the + * IP information and then go into the poll routine */ + if (card->u.p.ip_mode != WANOPT_PPP_PEER){ + trigger_ppp_poll(dev); + } + } + break; + + case PPP_INTR_DROP_DTR: /* DTR drop timeout expired 0x40 bit 6 */ + + NEX_PRINTK(KERN_INFO "DTR Drop Timeout Interrrupt \n"); + + if (card->u.p.ip_mode == WANOPT_PPP_PEER) { + set_bit(0,&Read_connection_info); + } + + wanpipe_set_state(card, WAN_DISCONNECTED); + + show_disc_cause(card, flags->disc_cause); + ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT; + flags->imask |= PPP_INTR_TIMER; + trigger_ppp_poll(dev); + break; + + default: + printk(KERN_INFO "%s: Error, Invalid PPP Event\n",card->devname); + } +} + + + +/* TIMER INTERRUPT */ + +void timer_intr (sdla_t *card) +{ + + struct net_device* dev = card->wandev.dev; + ppp_private_area_t* ppp_priv_area = dev->priv; + ppp_flags_t *flags = card->flags; + + + if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG){ + if (!config_ppp(card)){ + ppp_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_CONFIG; + } + } + + /* Update statistics */ + if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE){ + ppp_get_err_stats(card); + if(!(--ppp_priv_area->update_comms_stats)){ + ppp_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + } + } + + /* PPIPEMON UDP request */ + + if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP){ + process_udp_mgmt_pkt(card,dev, ppp_priv_area); + ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP; + } + + /* PPP Event */ + if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_PPP_EVENT){ + + if (card->wandev.state == WAN_DISCONNECTED){ + retrigger_comm(card); + } + + /* If the state is CONNECTING, it means that communicatins were + * enabled. When the remote side enables its comminication we + * should get an interrupt PPP_INTR_OPEN, thus turn off polling + */ + + else if (card->wandev.state == WAN_CONNECTING){ + /* Turn off the timer interrupt */ + ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT; + } + + /* If state is connected and we are in PEER mode + * poll for an IP address which will be provided by remote end. + */ + else if ((card->wandev.state == WAN_CONNECTED && + card->u.p.ip_mode == WANOPT_PPP_PEER) && + test_bit(0,&Read_connection_info)){ + + card->state_tick = jiffies; + if (read_connection_info (card)){ + printk(KERN_INFO "%s: Failed to read PEER IP Addresses\n", + card->devname); + }else{ + clear_bit(0,&Read_connection_info); + set_bit(1,&Read_connection_info); + trigger_ppp_poll(dev); + } + }else{ + //FIXME Put the comment back int + ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT; + } + + }/* End of PPP_EVENT */ + + + /* Only disable the timer interrupt if there are no udp, statistic */ + /* updates or events pending */ + if(!ppp_priv_area->timer_int_enabled) { + flags->imask &= ~PPP_INTR_TIMER; + } +} + + +static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto) +{ + int i; + + if( proto == htons(ETH_P_IPX) ) { + //It's an IPX packet + if(!enable_IPX) { + //Return 1 so we don't pass it up the stack. + return 1; + } + } else { + //It's not IPX so pass it up the stack. + return 0; + } + + if( sendpacket[16] == 0x90 && + sendpacket[17] == 0x04) + { + //It's IPXWAN + + if( sendpacket[2] == 0x02 && + sendpacket[34] == 0x00) + { + //It's a timer request packet + printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname); + + //Go through the routing options and answer no to every + //option except Unnumbered RIP/SAP + for(i = 41; sendpacket[i] == 0x00; i += 5) + { + //0x02 is the option for Unnumbered RIP/SAP + if( sendpacket[i + 4] != 0x02) + { + sendpacket[i + 1] = 0; + } + } + + //Skip over the extended Node ID option + if( sendpacket[i] == 0x04 ) + { + i += 8; + } + + //We also want to turn off all header compression opt. + for(; sendpacket[i] == 0x80 ;) + { + sendpacket[i + 1] = 0; + i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4; + } + + //Set the packet type to timer response + sendpacket[34] = 0x01; + + printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname); + } + else if( sendpacket[34] == 0x02 ) + { + //This is an information request packet + printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname); + + //Set the packet type to information response + sendpacket[34] = 0x03; + + //Set the router name + sendpacket[51] = 'P'; + sendpacket[52] = 'T'; + sendpacket[53] = 'P'; + sendpacket[54] = 'I'; + sendpacket[55] = 'P'; + sendpacket[56] = 'E'; + sendpacket[57] = '-'; + sendpacket[58] = CVHexToAscii(network_number >> 28); + sendpacket[59] = CVHexToAscii((network_number & 0x0F000000)>> 24); + sendpacket[60] = CVHexToAscii((network_number & 0x00F00000)>> 20); + sendpacket[61] = CVHexToAscii((network_number & 0x000F0000)>> 16); + sendpacket[62] = CVHexToAscii((network_number & 0x0000F000)>> 12); + sendpacket[63] = CVHexToAscii((network_number & 0x00000F00)>> 8); + sendpacket[64] = CVHexToAscii((network_number & 0x000000F0)>> 4); + sendpacket[65] = CVHexToAscii(network_number & 0x0000000F); + for(i = 66; i < 99; i+= 1) + { + sendpacket[i] = 0; + } + + printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname); + } + else + { + printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname); + return 0; + } + + //Set the WNodeID to our network address + sendpacket[35] = (unsigned char)(network_number >> 24); + sendpacket[36] = (unsigned char)((network_number & 0x00FF0000) >> 16); + sendpacket[37] = (unsigned char)((network_number & 0x0000FF00) >> 8); + sendpacket[38] = (unsigned char)(network_number & 0x000000FF); + + return 1; + } else { + //If we get here it's an IPX-data packet, so it'll get passed up the stack. + + //switch the network numbers + switch_net_numbers(sendpacket, network_number, 1); + return 0; + } +} + +/****** Background Polling Routines ****************************************/ + +/* All polling functions are invoked by the TIMER interrupt in the wpp_isr + * routine. + */ + +/*============================================================================ + * Monitor active link phase. + */ +static void process_route (sdla_t *card) +{ + ppp_flags_t *flags = card->flags; + struct net_device *dev = card->wandev.dev; + ppp_private_area_t *ppp_priv_area = dev->priv; + + if ((card->u.p.ip_mode == WANOPT_PPP_PEER) && + (flags->ip_state == 0x09)){ + + /* We get ip_local from the firmware in PEER mode. + * Therefore, if ip_local is 0, we failed to obtain + * the remote IP address. */ + if (ppp_priv_area->ip_local == 0) + return; + + printk(KERN_INFO "%s: IPCP State Opened.\n", card->devname); + if (read_info( card )) { + printk(KERN_INFO + "%s: An error occurred in IP assignment.\n", + card->devname); + } else { + struct in_device *in_dev = dev->ip_ptr; + if (in_dev != NULL ) { + struct in_ifaddr *ifa = in_dev->ifa_list; + + printk(KERN_INFO "%s: Assigned Lcl. Addr: %u.%u.%u.%u\n", + card->devname, NIPQUAD(ifa->ifa_local)); + printk(KERN_INFO "%s: Assigned Rmt. Addr: %u.%u.%u.%u\n", + card->devname, NIPQUAD(ifa->ifa_address)); + }else{ + printk(KERN_INFO + "%s: Error: Failed to add a route for PPP interface %s\n", + card->devname,dev->name); + } + } + } +} + +/*============================================================================ + * Monitor physical link disconnected phase. + * o if interface is up and the hold-down timeout has expired, then retry + * connection. + */ +static void retrigger_comm(sdla_t *card) +{ + struct net_device *dev = card->wandev.dev; + + if (dev && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) { + + wanpipe_set_state(card, WAN_CONNECTING); + + if(ppp_comm_enable(card) == CMD_OK){ + init_ppp_tx_rx_buff( card ); + } + } +} + +/****** Miscellaneous Functions *********************************************/ + +/*============================================================================ + * Configure S508 adapter. + */ +static int config508(struct net_device *dev, sdla_t *card) +{ + ppp508_conf_t cfg; + struct in_device *in_dev = dev->ip_ptr; + ppp_private_area_t *ppp_priv_area = dev->priv; + + /* Prepare PPP configuration structure */ + memset(&cfg, 0, sizeof(ppp508_conf_t)); + + if (card->wandev.clocking) + cfg.line_speed = card->wandev.bps; + + if (card->wandev.interface == WANOPT_RS232) + cfg.conf_flags |= INTERFACE_LEVEL_RS232; + + + cfg.conf_flags |= DONT_TERMINATE_LNK_MAX_CONFIG; /*send Configure-Request packets forever*/ + cfg.txbuf_percent = PERCENT_TX_BUFF; /* % of Tx bufs */ + cfg.mtu_local = card->wandev.mtu; + cfg.mtu_remote = card->wandev.mtu; /* Default */ + cfg.restart_tmr = TIME_BETWEEN_CONF_REQ; /* 30 = 3sec */ + cfg.auth_rsrt_tmr = TIME_BETWEEN_PAP_CHAP_REQ; /* 30 = 3sec */ + cfg.auth_wait_tmr = WAIT_PAP_CHAP_WITHOUT_REPLY; /* 300 = 30s */ + cfg.mdm_fail_tmr = WAIT_AFTER_DCD_CTS_LOW; /* 5 = 0.5s */ + cfg.dtr_drop_tmr = TIME_DCD_CTS_LOW_AFTER_LNK_DOWN; /* 10 = 1s */ + cfg.connect_tmout = WAIT_DCD_HIGH_AFTER_ENABLE_COMM; /* 900 = 90s */ + cfg.conf_retry = MAX_CONF_REQ_WITHOUT_REPLY; /* 10 = 1s */ + cfg.term_retry = MAX_TERM_REQ_WITHOUT_REPLY; /* 2 times */ + cfg.fail_retry = NUM_CONF_NAK_WITHOUT_REPLY; /* 5 times */ + cfg.auth_retry = NUM_AUTH_REQ_WITHOUT_REPLY; /* 10 times */ + + + if( !card->u.p.authenticator ) { + printk(KERN_INFO "%s: Device is not configured as an authenticator\n", + card->devname); + cfg.auth_options = NO_AUTHENTICATION; + }else{ + printk(KERN_INFO "%s: Device is configured as an authenticator\n", + card->devname); + cfg.auth_options = INBOUND_AUTH; + } + + if( ppp_priv_area->pap == WANOPT_YES){ + cfg.auth_options |=PAP_AUTH; + printk(KERN_INFO "%s: Pap enabled\n", card->devname); + } + if( ppp_priv_area->chap == WANOPT_YES){ + cfg.auth_options |= CHAP_AUTH; + printk(KERN_INFO "%s: Chap enabled\n", card->devname); + } + + + if (ppp_priv_area->enable_IPX == WANOPT_YES){ + printk(KERN_INFO "%s: Enabling IPX Protocol\n",card->devname); + cfg.ipx_options = ENABLE_IPX | ROUTING_PROT_DEFAULT; + }else{ + cfg.ipx_options = DISABLE_IPX; + } + + switch (card->u.p.ip_mode) { + + case WANOPT_PPP_STATIC: + + printk(KERN_INFO "%s: PPP IP Mode: STATIC\n",card->devname); + cfg.ip_options = L_AND_R_IP_NO_ASSIG | + ENABLE_IP; + cfg.ip_local = in_dev->ifa_list->ifa_local; + cfg.ip_remote = in_dev->ifa_list->ifa_address; + /* Debugging code used to check that IP addresses + * obtained from the kernel are correct */ + + NEX_PRINTK(KERN_INFO "Local %u.%u.%u.%u Remote %u.%u.%u.%u Name %s\n", + NIPQUAD(ip_local),NIPQUAD(ip_remote), dev->name); + break; + + case WANOPT_PPP_HOST: + + printk(KERN_INFO "%s: PPP IP Mode: HOST\n",card->devname); + cfg.ip_options = L_IP_LOCAL_ASSIG | + R_IP_LOCAL_ASSIG | + ENABLE_IP; + cfg.ip_local = in_dev->ifa_list->ifa_local; + cfg.ip_remote = in_dev->ifa_list->ifa_address; + /* Debugging code used to check that IP addresses + * obtained from the kernel are correct */ + NEX_PRINTK (KERN_INFO "Local %u.%u.%u.%u Remote %u.%u.%u.%u Name %s\n", + NIPQUAD(ip_local),NIPQUAD(ip_remote), dev->name); + + break; + + case WANOPT_PPP_PEER: + + printk(KERN_INFO "%s: PPP IP Mode: PEER\n",card->devname); + cfg.ip_options = L_IP_REMOTE_ASSIG | + R_IP_REMOTE_ASSIG | + ENABLE_IP; + cfg.ip_local = 0x00; + cfg.ip_remote = 0x00; + break; + + default: + printk(KERN_INFO "%s: ERROR: Unsupported PPP Mode Selected\n", + card->devname); + printk(KERN_INFO "%s: PPP IP Modes: STATIC, PEER or HOST\n", + card->devname); + return 1; + } + + return ppp_configure(card, &cfg); +} + +/*============================================================================ + * Show disconnection cause. + */ +static void show_disc_cause(sdla_t *card, unsigned cause) +{ + if (cause & 0x0802) + + printk(KERN_INFO "%s: link terminated by peer\n", + card->devname); + + else if (cause & 0x0004) + + printk(KERN_INFO "%s: link terminated by user\n", + card->devname); + + else if (cause & 0x0008) + + printk(KERN_INFO "%s: authentication failed\n", card->devname); + + else if (cause & 0x0010) + + printk(KERN_INFO + "%s: authentication protocol negotiation failed\n", + card->devname); + + else if (cause & 0x0020) + + printk(KERN_INFO + "%s: peer's request for authentication rejected\n", + card->devname); + + else if (cause & 0x0040) + + printk(KERN_INFO "%s: MRU option rejected by peer\n", + card->devname); + + else if (cause & 0x0080) + + printk(KERN_INFO "%s: peer's MRU was too small\n", + card->devname); + + else if (cause & 0x0100) + + printk(KERN_INFO "%s: failed to negotiate peer's LCP options\n", + card->devname); + + else if (cause & 0x0200) + + printk(KERN_INFO "%s: failed to negotiate peer's IPCP options\n" + , card->devname); + + else if (cause & 0x0400) + + printk(KERN_INFO + "%s: failed to negotiate peer's IPXCP options\n", + card->devname); +} + +/*============================================================================= + * Process UDP call of type PTPIPEAB. + */ +static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev, + ppp_private_area_t *ppp_priv_area ) +{ + unsigned char buf2[5]; + unsigned char *buf; + unsigned int frames, len; + struct sk_buff *new_skb; + unsigned short data_length, buffer_length, real_len; + unsigned long data_ptr; + int udp_mgmt_req_valid = 1; + ppp_mbox_t *mbox = card->mbox; + struct timeval tv; + int err; + ppp_udp_pkt_t *ppp_udp_pkt = (ppp_udp_pkt_t*)&ppp_priv_area->udp_pkt_data; + + memcpy(&buf2, &card->wandev.udp_port, 2 ); + + + if(ppp_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + switch(ppp_udp_pkt->cblock.command) { + + case PPIPE_GET_IBA_DATA: + case PPP_READ_CONFIG: + case PPP_GET_CONNECTION_INFO: + case PPIPE_ROUTER_UP_TIME: + case PPP_READ_STATISTICS: + case PPP_READ_ERROR_STATS: + case PPP_READ_PACKET_STATS: + case PPP_READ_LCP_STATS: + case PPP_READ_IPCP_STATS: + case PPP_READ_IPXCP_STATS: + case PPP_READ_PAP_STATS: + case PPP_READ_CHAP_STATS: + case PPP_READ_CODE_VERSION: + udp_mgmt_req_valid = 1; + break; + + default: + udp_mgmt_req_valid = 0; + break; + } + } + + if(!udp_mgmt_req_valid) { + + /* set length to 0 */ + ppp_udp_pkt->cblock.length = 0x00; + + /* set return code */ + ppp_udp_pkt->cblock.result = 0xCD; + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_direction_err; + + if (net_ratelimit()){ + printk(KERN_INFO + "%s: Warning, Illegal UDP command attempted from network: %x\n", + card->devname,ppp_udp_pkt->cblock.command); + } + } else { + /* Initialize the trace element */ + trace_element_t trace_element; + + switch (ppp_udp_pkt->cblock.command){ + + /* PPIPE_ENABLE_TRACING */ + case PPIPE_ENABLE_TRACING: + if (!card->TracingEnabled) { + + /* OPERATE_DATALINE_MONITOR */ + mbox->cmd.command = PPP_DATALINE_MONITOR; + mbox->cmd.length = 0x01; + mbox->data[0] = ppp_udp_pkt->data[0]; + err = sdla_exec(mbox) ? + mbox->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) { + + ppp_error(card, err, mbox); + card->TracingEnabled = 0; + + /* set the return code */ + + ppp_udp_pkt->cblock.result = mbox->cmd.result; + mbox->cmd.length = 0; + break; + } + + sdla_peek(&card->hw, 0xC000, &buf2, 2); + + ppp_priv_area->curr_trace_addr = 0; + memcpy(&ppp_priv_area->curr_trace_addr, &buf2, 2); + ppp_priv_area->start_trace_addr = + ppp_priv_area->curr_trace_addr; + ppp_priv_area->end_trace_addr = + ppp_priv_area->start_trace_addr + END_OFFSET; + + /* MAX_SEND_BUFFER_SIZE - 28 (IP header) + - 32 (ppipemon CBLOCK) */ + available_buffer_space = MAX_LGTH_UDP_MGNT_PKT - + sizeof(ip_pkt_t)- + sizeof(udp_pkt_t)- + sizeof(wp_mgmt_t)- + sizeof(cblock_t); + } + ppp_udp_pkt->cblock.result = 0; + mbox->cmd.length = 0; + card->TracingEnabled = 1; + break; + + /* PPIPE_DISABLE_TRACING */ + case PPIPE_DISABLE_TRACING: + + if(card->TracingEnabled) { + + /* OPERATE_DATALINE_MONITOR */ + mbox->cmd.command = 0x33; + mbox->cmd.length = 1; + mbox->data[0] = 0x00; + err = sdla_exec(mbox) ? + mbox->cmd.result : CMD_TIMEOUT; + + } + + /*set return code*/ + ppp_udp_pkt->cblock.result = 0; + mbox->cmd.length = 0; + card->TracingEnabled = 0; + break; + + /* PPIPE_GET_TRACE_INFO */ + case PPIPE_GET_TRACE_INFO: + + if(!card->TracingEnabled) { + /* set return code */ + ppp_udp_pkt->cblock.result = 1; + mbox->cmd.length = 0; + } + + buffer_length = 0; + + /* frames < 62, where 62 is the number of trace + information elements. There is in total 496 + bytes of space and each trace information + element is 8 bytes. + */ + for ( frames=0; frames<62; frames++) { + + trace_pkt_t *trace_pkt = (trace_pkt_t *) + &ppp_udp_pkt->data[buffer_length]; + + /* Read the whole trace packet */ + sdla_peek(&card->hw, ppp_priv_area->curr_trace_addr, + &trace_element, sizeof(trace_element_t)); + + /* no data on board so exit */ + if( trace_element.opp_flag == 0x00 ) + break; + + data_ptr = trace_element.trace_data_ptr; + + /* See if there is actual data on the trace buffer */ + if (data_ptr){ + data_length = trace_element.trace_length; + }else{ + data_length = 0; + ppp_udp_pkt->data[0] |= 0x02; + } + + //FIXME: Do we need this check + if ((available_buffer_space - buffer_length) + < (sizeof(trace_element_t)+1)){ + + /*indicate we have more frames + * on board and exit + */ + ppp_udp_pkt->data[0] |= 0x02; + break; + } + + trace_pkt->status = trace_element.trace_type; + trace_pkt->time_stamp = trace_element.trace_time_stamp; + trace_pkt->real_length = trace_element.trace_length; + + real_len = trace_element.trace_length; + + if(data_ptr == 0){ + trace_pkt->data_avail = 0x00; + }else{ + /* we can take it next time */ + if ((available_buffer_space - buffer_length)< + (real_len + sizeof(trace_pkt_t))){ + + ppp_udp_pkt->data[0] |= 0x02; + break; + } + trace_pkt->data_avail = 0x01; + + /* get the data */ + sdla_peek(&card->hw, data_ptr, + &trace_pkt->data, + real_len); + } + /* zero the opp flag to + show we got the frame */ + buf2[0] = 0x00; + sdla_poke(&card->hw, ppp_priv_area->curr_trace_addr, + &buf2, 1); + + /* now move onto the next + frame */ + ppp_priv_area->curr_trace_addr += 8; + + /* check if we passed the last address */ + if ( ppp_priv_area->curr_trace_addr >= + ppp_priv_area->end_trace_addr){ + + ppp_priv_area->curr_trace_addr = + ppp_priv_area->start_trace_addr; + } + + /* update buffer length and make sure its even */ + + if ( trace_pkt->data_avail == 0x01 ) { + buffer_length += real_len - 1; + } + + /* for the header */ + buffer_length += 8; + + if( buffer_length & 0x0001 ) + buffer_length += 1; + } + + /* ok now set the total number of frames passed + in the high 5 bits */ + ppp_udp_pkt->data[0] |= (frames << 2); + + /* set the data length */ + mbox->cmd.length = buffer_length; + ppp_udp_pkt->cblock.length = buffer_length; + + /* set return code */ + ppp_udp_pkt->cblock.result = 0; + break; + + /* PPIPE_GET_IBA_DATA */ + case PPIPE_GET_IBA_DATA: + + mbox->cmd.length = 0x09; + + sdla_peek(&card->hw, 0xF003, &ppp_udp_pkt->data, + mbox->cmd.length); + + /* set the length of the data */ + ppp_udp_pkt->cblock.length = 0x09; + + /* set return code */ + ppp_udp_pkt->cblock.result = 0x00; + ppp_udp_pkt->cblock.result = 0; + break; + + /* PPIPE_FT1_READ_STATUS */ + case PPIPE_FT1_READ_STATUS: + sdla_peek(&card->hw, 0xF020, &ppp_udp_pkt->data[0], 2); + ppp_udp_pkt->cblock.length = mbox->cmd.length = 2; + ppp_udp_pkt->cblock.result = 0; + break; + + case PPIPE_FLUSH_DRIVER_STATS: + init_ppp_priv_struct( ppp_priv_area ); + init_global_statistics( card ); + mbox->cmd.length = 0; + ppp_udp_pkt->cblock.result = 0; + break; + + + case PPIPE_ROUTER_UP_TIME: + + do_gettimeofday( &tv ); + ppp_priv_area->router_up_time = tv.tv_sec - + ppp_priv_area->router_start_time; + *(unsigned long *)&ppp_udp_pkt->data = ppp_priv_area->router_up_time; + mbox->cmd.length = 4; + ppp_udp_pkt->cblock.result = 0; + break; + + /* PPIPE_DRIVER_STATISTICS */ + case PPIPE_DRIVER_STAT_IFSEND: + memcpy(&ppp_udp_pkt->data, &ppp_priv_area->if_send_stat, + sizeof(if_send_stat_t)); + + + ppp_udp_pkt->cblock.result = 0; + ppp_udp_pkt->cblock.length = sizeof(if_send_stat_t); + mbox->cmd.length = sizeof(if_send_stat_t); + break; + + case PPIPE_DRIVER_STAT_INTR: + memcpy(&ppp_udp_pkt->data, &card->statistics, + sizeof(global_stats_t)); + + memcpy(&ppp_udp_pkt->data+sizeof(global_stats_t), + &ppp_priv_area->rx_intr_stat, + sizeof(rx_intr_stat_t)); + + ppp_udp_pkt->cblock.result = 0; + ppp_udp_pkt->cblock.length = sizeof(global_stats_t)+ + sizeof(rx_intr_stat_t); + mbox->cmd.length = ppp_udp_pkt->cblock.length; + break; + + case PPIPE_DRIVER_STAT_GEN: + memcpy( &ppp_udp_pkt->data, + &ppp_priv_area->pipe_mgmt_stat, + sizeof(pipe_mgmt_stat_t)); + + memcpy(&ppp_udp_pkt->data+sizeof(pipe_mgmt_stat_t), + &card->statistics, sizeof(global_stats_t)); + + ppp_udp_pkt->cblock.result = 0; + ppp_udp_pkt->cblock.length = sizeof(global_stats_t)+ + sizeof(rx_intr_stat_t); + mbox->cmd.length = ppp_udp_pkt->cblock.length; + break; + + + /* FT1 MONITOR STATUS */ + case FT1_MONITOR_STATUS_CTRL: + + /* Enable FT1 MONITOR STATUS */ + if( ppp_udp_pkt->data[0] == 1) { + + if( rCount++ != 0 ) { + ppp_udp_pkt->cblock.result = 0; + mbox->cmd.length = 1; + break; + } + } + + /* Disable FT1 MONITOR STATUS */ + if( ppp_udp_pkt->data[0] == 0) { + + if( --rCount != 0) { + ppp_udp_pkt->cblock.result = 0; + mbox->cmd.length = 1; + break; + } + } + goto udp_dflt_cmd; + + /* WARNING: FIXME: This should be fixed. + * The FT1 Status Ctrl doesn't have a break + * statment. Thus, no code must be inserted + * HERE: between default and above case statement */ + + default: +udp_dflt_cmd: + + /* it's a board command */ + mbox->cmd.command = ppp_udp_pkt->cblock.command; + mbox->cmd.length = ppp_udp_pkt->cblock.length; + + if(mbox->cmd.length) { + memcpy(&mbox->data,(unsigned char *)ppp_udp_pkt->data, + mbox->cmd.length); + } + + /* run the command on the board */ + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) { + + ppp_error(card, err, mbox); + ++ppp_priv_area->pipe_mgmt_stat. + UDP_PIPE_mgmt_adptr_cmnd_timeout; + break; + } + + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_cmnd_OK; + + /* copy the result back to our buffer */ + memcpy(&ppp_udp_pkt->cblock,mbox, sizeof(cblock_t)); + + if(mbox->cmd.length) { + memcpy(&ppp_udp_pkt->data,&mbox->data,mbox->cmd.length); + } + + } /* end of switch */ + } /* end of else */ + + /* Fill UDP TTL */ + ppp_udp_pkt->ip_pkt.ttl = card->wandev.ttl; + len = reply_udp(ppp_priv_area->udp_pkt_data, mbox->cmd.length); + + if (ppp_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + /* Make sure we are not already sending */ + if (!test_bit(SEND_CRIT,&card->wandev.critical)){ + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_adptr; + ppp_send(card,ppp_priv_area->udp_pkt_data,len,ppp_priv_area->protocol); + } + + } else { + + /* Pass it up the stack + Allocate socket buffer */ + if ((new_skb = dev_alloc_skb(len)) != NULL) { + + /* copy data into new_skb */ + + buf = skb_put(new_skb, len); + memcpy(buf,ppp_priv_area->udp_pkt_data, len); + + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_stack; + + /* Decapsulate packet and pass it up the protocol + stack */ + new_skb->protocol = htons(ETH_P_IP); + new_skb->dev = dev; + new_skb->mac.raw = new_skb->data; + netif_rx(new_skb); + dev->last_rx = jiffies; + + } else { + + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_no_socket; + printk(KERN_INFO "no socket buffers available!\n"); + } + } + + ppp_priv_area->udp_pkt_lgth = 0; + + return; +} + +/*============================================================================= + * Initial the ppp_private_area structure. + */ +static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area ) +{ + + memset(&ppp_priv_area->if_send_stat, 0, sizeof(if_send_stat_t)); + memset(&ppp_priv_area->rx_intr_stat, 0, sizeof(rx_intr_stat_t)); + memset(&ppp_priv_area->pipe_mgmt_stat, 0, sizeof(pipe_mgmt_stat_t)); +} + +/*============================================================================ + * Initialize Global Statistics + */ +static void init_global_statistics( sdla_t *card ) +{ + memset(&card->statistics, 0, sizeof(global_stats_t)); +} + +/*============================================================================ + * Initialize Receive and Transmit Buffers. + */ +static void init_ppp_tx_rx_buff( sdla_t *card ) +{ + ppp508_buf_info_t* info; + + if (card->hw.type == SDLA_S514) { + + info = (void*)(card->hw.dpmbase + PPP514_BUF_OFFS); + + card->u.p.txbuf_base = (void*)(card->hw.dpmbase + + info->txb_ptr); + + card->u.p.txbuf_last = (ppp_buf_ctl_t*)card->u.p.txbuf_base + + (info->txb_num - 1); + + card->u.p.rxbuf_base = (void*)(card->hw.dpmbase + + info->rxb_ptr); + + card->u.p.rxbuf_last = (ppp_buf_ctl_t*)card->u.p.rxbuf_base + + (info->rxb_num - 1); + + } else { + + info = (void*)(card->hw.dpmbase + PPP508_BUF_OFFS); + + card->u.p.txbuf_base = (void*)(card->hw.dpmbase + + (info->txb_ptr - PPP508_MB_VECT)); + + card->u.p.txbuf_last = (ppp_buf_ctl_t*)card->u.p.txbuf_base + + (info->txb_num - 1); + + card->u.p.rxbuf_base = (void*)(card->hw.dpmbase + + (info->rxb_ptr - PPP508_MB_VECT)); + + card->u.p.rxbuf_last = (ppp_buf_ctl_t*)card->u.p.rxbuf_base + + (info->rxb_num - 1); + } + + card->u.p.txbuf_next = (unsigned long*)&info->txb_nxt; + card->u.p.rxbuf_next = (unsigned long*)&info->rxb1_ptr; + + card->u.p.rx_base = info->rxb_base; + card->u.p.rx_top = info->rxb_end; + + card->u.p.txbuf = card->u.p.txbuf_base; + card->rxmb = card->u.p.rxbuf_base; + +} + +/*============================================================================= + * Read Connection Information (ie for Remote IP address assginment). + * Called when ppp interface connected. + */ +static int read_info( sdla_t *card ) +{ + struct net_device *dev = card->wandev.dev; + ppp_private_area_t *ppp_priv_area = dev->priv; + int err; + + struct ifreq if_info; + struct sockaddr_in *if_data1, *if_data2; + mm_segment_t fs; + + /* Set Local and remote addresses */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + + fs = get_fs(); + set_fs(get_ds()); /* get user space block */ + + /* Change the local and remote ip address of the interface. + * This will also add in the destination route. + */ + if_data1 = (struct sockaddr_in *)&if_info.ifr_addr; + if_data1->sin_addr.s_addr = ppp_priv_area->ip_local; + if_data1->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFADDR, &if_info ); + if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data2->sin_addr.s_addr = ppp_priv_area->ip_remote; + if_data2->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFDSTADDR, &if_info ); + + set_fs(fs); /* restore old block */ + + if (err) { + printk (KERN_INFO "%s: Adding of route failed: %i\n", + card->devname,err); + printk (KERN_INFO "%s: Local : %u.%u.%u.%u\n", + card->devname,NIPQUAD(ppp_priv_area->ip_local)); + printk (KERN_INFO "%s: Remote: %u.%u.%u.%u\n", + card->devname,NIPQUAD(ppp_priv_area->ip_remote)); + } + return err; +} + +/*============================================================================= + * Remove Dynamic Route. + * Called when ppp interface disconnected. + */ + +static void remove_route( sdla_t *card ) +{ + + struct net_device *dev = card->wandev.dev; + long ip_addr; + int err; + + mm_segment_t fs; + struct ifreq if_info; + struct sockaddr_in *if_data1; + struct in_device *in_dev = dev->ip_ptr; + struct in_ifaddr *ifa = in_dev->ifa_list; + + ip_addr = ifa->ifa_local; + + /* Set Local and remote addresses */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + fs = get_fs(); + set_fs(get_ds()); /* get user space block */ + + /* Change the local ip address of the interface to 0. + * This will also delete the destination route. + */ + if_data1 = (struct sockaddr_in *)&if_info.ifr_addr; + if_data1->sin_addr.s_addr = 0; + if_data1->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFADDR, &if_info ); + + set_fs(fs); /* restore old block */ + + + if (err) { + printk (KERN_INFO "%s: Deleting dynamic route failed %d!\n", + card->devname, err); + return; + }else{ + printk (KERN_INFO "%s: PPP Deleting dynamic route %u.%u.%u.%u successfuly\n", + card->devname, NIPQUAD(ip_addr)); + } + return; +} + +/*============================================================================= + * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR + * _TEST_COUNTER times. + */ +static int intr_test( sdla_t *card ) +{ + ppp_mbox_t *mb = card->mbox; + int err,i; + + err = ppp_set_intr_mode( card, 0x08 ); + + if (err == CMD_OK) { + + for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) { + /* Run command READ_CODE_VERSION */ + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + mb->cmd.length = 0; + mb->cmd.command = PPP_READ_CODE_VERSION; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + if (err != CMD_OK) + ppp_error(card, err, mb); + } + } + else return err; + + err = ppp_set_intr_mode( card, 0 ); + if (err != CMD_OK) + return err; + + return 0; +} + +/*============================================================================== + * Determine what type of UDP call it is. DRVSTATS or PTPIPEAB ? + */ +static int udp_pkt_type( struct sk_buff *skb, sdla_t *card ) +{ + unsigned char *sendpacket; + unsigned char buf2[5]; + ppp_udp_pkt_t *ppp_udp_pkt = (ppp_udp_pkt_t *)skb->data; + + sendpacket = skb->data; + memcpy(&buf2, &card->wandev.udp_port, 2); + + if( ppp_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45 && /* IP packet */ + sendpacket[9] == 0x11 && /* UDP packet */ + sendpacket[22] == buf2[1] && /* UDP Port */ + sendpacket[23] == buf2[0] && + sendpacket[36] == 0x01 ) { + + if ( sendpacket[28] == 0x50 && /* PTPIPEAB: Signature */ + sendpacket[29] == 0x54 && + sendpacket[30] == 0x50 && + sendpacket[31] == 0x49 && + sendpacket[32] == 0x50 && + sendpacket[33] == 0x45 && + sendpacket[34] == 0x41 && + sendpacket[35] == 0x42 ){ + + return UDP_PTPIPE_TYPE; + + } else if(sendpacket[28] == 0x44 && /* DRVSTATS: Signature */ + sendpacket[29] == 0x52 && + sendpacket[30] == 0x56 && + sendpacket[31] == 0x53 && + sendpacket[32] == 0x54 && + sendpacket[33] == 0x41 && + sendpacket[34] == 0x54 && + sendpacket[35] == 0x53 ){ + + return UDP_DRVSTATS_TYPE; + + } else + return UDP_INVALID_TYPE; + + } else + return UDP_INVALID_TYPE; + +} + +/*============================================================================ + * Check to see if the packet to be transmitted contains a broadcast or + * multicast source IP address. + */ + +static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, + struct sk_buff *skb) +{ + u32 src_ip_addr; + u32 broadcast_ip_addr = 0; + struct in_device *in_dev; + + /* read the IP source address from the outgoing packet */ + src_ip_addr = *(u32 *)(skb->data + 12); + + /* read the IP broadcast address for the device */ + in_dev = dev->ip_ptr; + if(in_dev != NULL) { + struct in_ifaddr *ifa= in_dev->ifa_list; + if(ifa != NULL) + broadcast_ip_addr = ifa->ifa_broadcast; + else + return 0; + } + + /* check if the IP Source Address is a Broadcast address */ + if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) { + printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n", + card->devname); + return 1; + } + + /* check if the IP Source Address is a Multicast address */ + if((ntohl(src_ip_addr) >= 0xE0000001) && + (ntohl(src_ip_addr) <= 0xFFFFFFFE)) { + printk(KERN_INFO "%s: Multicast Source Address silently discarded\n", + card->devname); + return 1; + } + + return 0; +} + +void s508_lock (sdla_t *card, unsigned long *smp_flags) +{ + spin_lock_irqsave(&card->wandev.lock, *smp_flags); +} + +void s508_unlock (sdla_t *card, unsigned long *smp_flags) +{ + spin_unlock_irqrestore(&card->wandev.lock, *smp_flags); +} + +static int read_connection_info (sdla_t *card) +{ + ppp_mbox_t *mb = card->mbox; + struct net_device *dev = card->wandev.dev; + ppp_private_area_t *ppp_priv_area = dev->priv; + ppp508_connect_info_t *ppp508_connect_info; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + mb->cmd.length = 0; + mb->cmd.command = PPP_GET_CONNECTION_INFO; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) { + ppp_error(card, err, mb); + ppp_priv_area->ip_remote = 0; + ppp_priv_area->ip_local = 0; + } + else { + ppp508_connect_info = (ppp508_connect_info_t *)mb->data; + ppp_priv_area->ip_remote = ppp508_connect_info->ip_remote; + ppp_priv_area->ip_local = ppp508_connect_info->ip_local; + + NEX_PRINTK(KERN_INFO "READ CONNECTION GOT IP ADDRESS %x, %x\n", + ppp_priv_area->ip_remote, + ppp_priv_area->ip_local); + } + + return err; +} + +/*=============================================================================== + * config_ppp + * + * Configure the ppp protocol and enable communications. + * + * The if_open function binds this function to the poll routine. + * Therefore, this function will run every time the ppp interface + * is brought up. + * + * If the communications are not enabled, proceed to configure + * the card and enable communications. + * + * If the communications are enabled, it means that the interface + * was shutdown by ether the user or driver. In this case, we + * have to check that the IP addresses have not changed. If + * the IP addresses changed, we have to reconfigure the firmware + * and update the changed IP addresses. Otherwise, just exit. + */ +static int config_ppp (sdla_t *card) +{ + + struct net_device *dev = card->wandev.dev; + ppp_flags_t *flags = card->flags; + ppp_private_area_t *ppp_priv_area = dev->priv; + + if (card->u.p.comm_enabled){ + + if (ppp_priv_area->ip_local_tmp != ppp_priv_area->ip_local || + ppp_priv_area->ip_remote_tmp != ppp_priv_area->ip_remote){ + + /* The IP addersses have changed, we must + * stop the communications and reconfigure + * the card. Reason: the firmware must know + * the local and remote IP addresses. */ + disable_comm(card); + wanpipe_set_state(card, WAN_DISCONNECTED); + printk(KERN_INFO + "%s: IP addresses changed!\n", + card->devname); + printk(KERN_INFO "%s: Restarting communications ...\n", + card->devname); + }else{ + /* IP addresses are the same and the link is up, + * we don't have to do anything here. Therefore, exit */ + return 0; + } + } + + /* Record the new IP addreses */ + ppp_priv_area->ip_local = ppp_priv_area->ip_local_tmp; + ppp_priv_area->ip_remote = ppp_priv_area->ip_remote_tmp; + + if (config508(dev, card)){ + printk(KERN_INFO "%s: Failed to configure PPP device\n", + card->devname); + return 0; + } + + if (ppp_set_intr_mode(card, PPP_INTR_RXRDY| + PPP_INTR_TXRDY| + PPP_INTR_MODEM| + PPP_INTR_DISC | + PPP_INTR_OPEN | + PPP_INTR_DROP_DTR | + PPP_INTR_TIMER)) { + + printk(KERN_INFO "%s: Failed to configure board interrupts !\n", + card->devname); + return 0; + } + + /* Turn off the transmit and timer interrupt */ + flags->imask &= ~(PPP_INTR_TXRDY | PPP_INTR_TIMER) ; + + + /* If you are not the authenticator and any one of the protocol is + * enabled then we call the set_out_bound_authentication. + */ + if ( !card->u.p.authenticator && (ppp_priv_area->pap || ppp_priv_area->chap)) { + if ( ppp_set_outbnd_auth(card, ppp_priv_area) ){ + printk(KERN_INFO "%s: Outbound authentication failed !\n", + card->devname); + return 0; + } + } + + /* If you are the authenticator and any one of the protocol is enabled + * then we call the set_in_bound_authentication. + */ + if (card->u.p.authenticator && (ppp_priv_area->pap || ppp_priv_area->chap)){ + if (ppp_set_inbnd_auth(card, ppp_priv_area)){ + printk(KERN_INFO "%s: Inbound authentication failed !\n", + card->devname); + return 0; + } + } + + /* If we fail to enable communications here it's OK, + * since the DTR timer will cause a disconnected, which + * will retrigger communication in timer_intr() */ + if (ppp_comm_enable(card) == CMD_OK) { + wanpipe_set_state(card, WAN_CONNECTING); + init_ppp_tx_rx_buff(card); + } + + return 0; +} + +/*============================================================ + * ppp_poll + * + * Rationale: + * We cannot manipulate the routing tables, or + * ip addresses withing the interrupt. Therefore + * we must perform such actons outside an interrupt + * at a later time. + * + * Description: + * PPP polling routine, responsible for + * shutting down interfaces upon disconnect + * and adding/removing routes. + * + * Usage: + * This function is executed for each ppp + * interface through a tq_schedule bottom half. + * + * trigger_ppp_poll() function is used to kick + * the ppp_poll routine. + */ +static void ppp_poll(struct net_device *dev) +{ + ppp_private_area_t *ppp_priv_area; + sdla_t *card; + u8 check_gateway=0; + ppp_flags_t *flags; + + if (!dev || (ppp_priv_area = dev->priv) == NULL) + return; + + card = ppp_priv_area->card; + flags = card->flags; + + /* Shutdown is in progress, stop what you are + * doing and get out */ + if (test_bit(PERI_CRIT,&card->wandev.critical)){ + clear_bit(POLL_CRIT,&card->wandev.critical); + return; + } + + /* if_open() function has triggered the polling routine + * to determine the configured IP addresses. Once the + * addresses are found, trigger the chdlc configuration */ + if (test_bit(0,&ppp_priv_area->config_ppp)){ + + ppp_priv_area->ip_local_tmp = get_ip_address(dev,WAN_LOCAL_IP); + ppp_priv_area->ip_remote_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP); + + if (ppp_priv_area->ip_local_tmp == ppp_priv_area->ip_remote_tmp && + card->u.p.ip_mode == WANOPT_PPP_HOST){ + + if (++ppp_priv_area->ip_error > MAX_IP_ERRORS){ + printk(KERN_INFO "\n%s: --- WARNING ---\n", + card->devname); + printk(KERN_INFO "%s: The local IP address is the same as the\n", + card->devname); + printk(KERN_INFO "%s: Point-to-Point IP address.\n", + card->devname); + printk(KERN_INFO "%s: --- WARNING ---\n\n", + card->devname); + }else{ + clear_bit(POLL_CRIT,&card->wandev.critical); + ppp_priv_area->poll_delay_timer.expires = jiffies+HZ; + add_timer(&ppp_priv_area->poll_delay_timer); + return; + } + } + + ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG; + flags->imask |= PPP_INTR_TIMER; + ppp_priv_area->ip_error=0; + + clear_bit(0,&ppp_priv_area->config_ppp); + clear_bit(POLL_CRIT,&card->wandev.critical); + return; + } + + /* Dynamic interface implementation, as well as dynamic + * routing. */ + + switch (card->wandev.state) { + + case WAN_DISCONNECTED: + + /* If the dynamic interface configuration is on, and interface + * is up, then bring down the netowrk interface */ + + if (test_bit(DYN_OPT_ON,&ppp_priv_area->interface_down) && + !test_bit(DEV_DOWN,&ppp_priv_area->interface_down) && + card->wandev.dev->flags & IFF_UP){ + + printk(KERN_INFO "%s: Interface %s down.\n", + card->devname,card->wandev.dev->name); + change_dev_flags(card->wandev.dev, + (card->wandev.dev->flags&~IFF_UP)); + set_bit(DEV_DOWN,&ppp_priv_area->interface_down); + }else{ + /* We need to check if the local IP address is + * zero. If it is, we shouldn't try to remove it. + * For some reason the kernel crashes badly if + * we try to remove the route twice */ + + if (card->wandev.dev->flags & IFF_UP && + get_ip_address(card->wandev.dev,WAN_LOCAL_IP) && + card->u.p.ip_mode == WANOPT_PPP_PEER){ + + remove_route(card); + } + } + break; + + case WAN_CONNECTED: + + /* In SMP machine this code can execute before the interface + * comes up. In this case, we must make sure that we do not + * try to bring up the interface before dev_open() is finished */ + + + /* DEV_DOWN will be set only when we bring down the interface + * for the very first time. This way we know that it was us + * that brought the interface down */ + + if (test_bit(DYN_OPT_ON,&ppp_priv_area->interface_down) && + test_bit(DEV_DOWN, &ppp_priv_area->interface_down) && + !(card->wandev.dev->flags & IFF_UP)){ + + printk(KERN_INFO "%s: Interface %s up.\n", + card->devname,card->wandev.dev->name); + + change_dev_flags(card->wandev.dev,(card->wandev.dev->flags|IFF_UP)); + clear_bit(DEV_DOWN,&ppp_priv_area->interface_down); + check_gateway=1; + } + + if ((card->u.p.ip_mode == WANOPT_PPP_PEER) && + test_bit(1,&Read_connection_info)) { + + process_route(card); + clear_bit(1,&Read_connection_info); + check_gateway=1; + } + + if (ppp_priv_area->gateway && check_gateway) + add_gateway(card,dev); + + break; + } + clear_bit(POLL_CRIT,&card->wandev.critical); + return; +} + +/*============================================================ + * trigger_ppp_poll + * + * Description: + * Add a ppp_poll() task into a tq_scheduler bh handler + * for a specific interface. This will kick + * the ppp_poll() routine at a later time. + * + * Usage: + * Interrupts use this to defer a taks to + * a polling routine. + * + */ + +static void trigger_ppp_poll(struct net_device *dev) +{ + ppp_private_area_t *ppp_priv_area; + if ((ppp_priv_area=dev->priv) != NULL){ + + sdla_t *card = ppp_priv_area->card; + + if (test_bit(PERI_CRIT,&card->wandev.critical)){ + return; + } + + if (test_and_set_bit(POLL_CRIT,&card->wandev.critical)){ + return; + } + + schedule_work(&ppp_priv_area->poll_work); + } + return; +} + +static void ppp_poll_delay (unsigned long dev_ptr) +{ + struct net_device *dev = (struct net_device *)dev_ptr; + trigger_ppp_poll(dev); +} + +/*============================================================ + * detect_and_fix_tx_bug + * + * Description: + * On connect, if the board tx buffer ptr is not the same + * as the driver tx buffer ptr, we found a firmware bug. + * Report the bug to the above layer. To fix the + * error restart communications again. + * + * Usage: + * + */ + +static int detect_and_fix_tx_bug (sdla_t *card) +{ + if (((unsigned long)card->u.p.txbuf_base&0xFFF) != ((*card->u.p.txbuf_next)&0xFFF)){ + NEX_PRINTK(KERN_INFO "Major Error, Fix the bug\n"); + return 1; + } + return 0; +} + +MODULE_LICENSE("GPL"); + +/****** End *****************************************************************/ diff --git a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c new file mode 100644 index 000000000..63f846d6f --- /dev/null +++ b/drivers/net/wan/sdla_x25.c @@ -0,0 +1,5497 @@ +/***************************************************************************** +* sdla_x25.c WANPIPE(tm) Multiprotocol WAN Link Driver. X.25 module. +* +* Author: Nenad Corbic +* +* Copyright: (c) 1995-2001 Sangoma 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. +* ============================================================================ +* Apr 03, 2001 Nenad Corbic o Fixed the rx_skb=NULL bug in x25 in rx_intr(). +* Dec 26, 2000 Nenad Corbic o Added a new polling routine, that uses +* a kernel timer (more efficient). +* Dec 25, 2000 Nenad Corbic o Updated for 2.4.X kernel +* Jul 26, 2000 Nenad Corbic o Increased the local packet buffering +* for API to 4096+header_size. +* Jul 17, 2000 Nenad Corbic o Fixed the x25 startup bug. Enable +* communications only after all interfaces +* come up. HIGH SVC/PVC is used to calculate +* the number of channels. +* Enable protocol only after all interfaces +* are enabled. +* Jul 10, 2000 Nenad Corbic o Fixed the M_BIT bug. +* Apr 25, 2000 Nenad Corbic o Pass Modem messages to the API. +* Disable idle timeout in X25 API. +* Apr 14, 2000 Nenad Corbic o Fixed: Large LCN number support. +* Maximum LCN number is 4095. +* Maximum number of X25 channels is 255. +* Apr 06, 2000 Nenad Corbic o Added SMP Support. +* Mar 29, 2000 Nenad Corbic o Added support for S514 PCI Card +* Mar 23, 2000 Nenad Corbic o Improved task queue, BH handling. +* Mar 14, 2000 Nenad Corbic o Updated Protocol Violation handling +* routines. Bug Fix. +* Mar 10, 2000 Nenad Corbic o Bug Fix: corrupted mbox recovery. +* Mar 09, 2000 Nenad Corbic o Fixed the auto HDLC bug. +* Mar 08, 2000 Nenad Corbic o Fixed LAPB HDLC startup problems. +* Application must bring the link up +* before tx/rx, and bring the +* link down on close(). +* Mar 06, 2000 Nenad Corbic o Added an option for logging call setup +* information. +* Feb 29, 2000 Nenad Corbic o Added support for LAPB HDLC API +* Feb 25, 2000 Nenad Corbic o Fixed the modem failure handling. +* No Modem OOB message will be passed +* to the user. +* Feb 21, 2000 Nenad Corbic o Added Xpipemon Debug Support +* Dec 30, 1999 Nenad Corbic o Socket based X25API +* Sep 17, 1998 Jaspreet Singh o Updates for 2.2.X kernel +* Mar 15, 1998 Alan Cox o 2.1.x porting +* Dec 19, 1997 Jaspreet Singh o Added multi-channel IPX support +* Nov 27, 1997 Jaspreet Singh o Added protection against enabling of irqs +* when they are disabled. +* Nov 17, 1997 Farhan Thawar o Added IPX support +* o Changed if_send() to now buffer packets when +* the board is busy +* o Removed queueing of packets via the polling +* routing +* o Changed if_send() critical flags to properly +* handle race conditions +* Nov 06, 1997 Farhan Thawar o Added support for SVC timeouts +* o Changed PVC encapsulation to ETH_P_IP +* Jul 21, 1997 Jaspreet Singh o Fixed freeing up of buffers using kfree() +* when packets are received. +* Mar 11, 1997 Farhan Thawar Version 3.1.1 +* o added support for V35 +* o changed if_send() to return 0 if +* wandev.critical() is true +* o free socket buffer in if_send() if +* returning 0 +* o added support for single '@' address to +* accept all incoming calls +* o fixed bug in set_chan_state() to disconnect +* Jan 15, 1997 Gene Kozin Version 3.1.0 +* o implemented exec() entry point +* Jan 07, 1997 Gene Kozin Initial version. +*****************************************************************************/ + +/*====================================================== + * Includes + *=====================================================*/ + +#include +#include /* printk(), and other useful stuff */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include +#include /* kmalloc(), kfree() */ +#include /* WAN router definitions */ +#include /* WANPIPE common user API definitions */ +#include +#include /* time_after() macro */ +#include /* htons(), etc. */ +#include +#include /* Experimental delay */ + +#include + +#include +#include +#include /* X.25 firmware API definitions */ +#include +#include + + +/*====================================================== + * Defines & Macros + *=====================================================*/ + + +#define CMD_OK 0 /* normal firmware return code */ +#define CMD_TIMEOUT 0xFF /* firmware command timed out */ +#define MAX_CMD_RETRY 10 /* max number of firmware retries */ + +#define X25_CHAN_MTU 4096 /* unfragmented logical channel MTU */ +#define X25_HRDHDR_SZ 7 /* max encapsulation header size */ +#define X25_CONCT_TMOUT (90*HZ) /* link connection timeout */ +#define X25_RECON_TMOUT (10*HZ) /* link connection timeout */ +#define CONNECT_TIMEOUT (90*HZ) /* link connection timeout */ +#define HOLD_DOWN_TIME (30*HZ) /* link hold down time */ +#define MAX_BH_BUFF 10 +#define M_BIT 0x01 + +//#define PRINT_DEBUG 1 +#ifdef PRINT_DEBUG +#define DBG_PRINTK(format, a...) printk(format, ## a) +#else +#define DBG_PRINTK(format, a...) +#endif + +#define TMR_INT_ENABLED_POLL_ACTIVE 0x01 +#define TMR_INT_ENABLED_POLL_CONNECT_ON 0x02 +#define TMR_INT_ENABLED_POLL_CONNECT_OFF 0x04 +#define TMR_INT_ENABLED_POLL_DISCONNECT 0x08 +#define TMR_INT_ENABLED_CMD_EXEC 0x10 +#define TMR_INT_ENABLED_UPDATE 0x20 +#define TMR_INT_ENABLED_UDP_PKT 0x40 + +#define MAX_X25_ADDR_SIZE 16 +#define MAX_X25_DATA_SIZE 129 +#define MAX_X25_FACL_SIZE 110 + +#define TRY_CMD_AGAIN 2 +#define DELAY_RESULT 1 +#define RETURN_RESULT 0 + +#define DCD(x) (x & 0x03 ? "HIGH" : "LOW") +#define CTS(x) (x & 0x05 ? "HIGH" : "LOW") + + +/* Driver will not write log messages about + * modem status if defined.*/ +#define MODEM_NOT_LOG 1 + +/*==================================================== + * For IPXWAN + *===================================================*/ + +#define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b))) + + +/*==================================================== + * MEMORY DEBUGGING FUNCTION + *==================================================== + +#define KMEM_SAFETYZONE 8 + +static void * dbg_kmalloc(unsigned int size, int prio, int line) { + int i = 0; + void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio); + char * c1 = v; + c1 += sizeof(unsigned int); + *((unsigned int *)v) = size; + + for (i = 0; i < KMEM_SAFETYZONE; i++) { + c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D'; + c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F'; + c1 += 8; + } + c1 += size; + for (i = 0; i < KMEM_SAFETYZONE; i++) { + c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G'; + c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L'; + c1 += 8; + } + v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8; + printk(KERN_INFO "line %d kmalloc(%d,%d) = %p\n",line,size,prio,v); + return v; +} +static void dbg_kfree(void * v, int line) { + unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8)); + unsigned int size = *sp; + char * c1 = ((char *)v) - KMEM_SAFETYZONE*8; + int i = 0; + for (i = 0; i < KMEM_SAFETYZONE; i++) { + if ( c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D' + || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') { + printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v); + printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8, + c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] ); + } + c1 += 8; + } + c1 += size; + for (i = 0; i < KMEM_SAFETYZONE; i++) { + if ( c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G' + || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L' + ) { + printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v); + printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8, + c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] ); + } + c1 += 8; + } + printk(KERN_INFO "line %d kfree(%p)\n",line,v); + v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8); + kfree(v); +} + +#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__) +#define kfree(x) dbg_kfree(x,__LINE__) + +==============================================================*/ + + + +/*=============================================== + * Data Structures + *===============================================*/ + + +/*======================================================== + * Name: x25_channel + * + * Purpose: To hold private informaton for each + * logical channel. + * + * Rationale: Per-channel debugging is possible if each + * channel has its own private area. + * + * Assumptions: + * + * Description: This is an extention of the struct net_device + * we create for each network interface to keep + * the rest of X.25 channel-specific data. + * + * Construct: Typedef + */ +typedef struct x25_channel +{ + wanpipe_common_t common; /* common area for x25api and socket */ + char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ + char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */ + unsigned tx_pkt_size; + unsigned short protocol; /* ethertype, 0 - multiplexed */ + char drop_sequence; /* mark sequence for dropping */ + unsigned long state_tick; /* time of the last state change */ + unsigned idle_timeout; /* sec, before disconnecting */ + unsigned long i_timeout_sofar; /* # of sec's we've been idle */ + unsigned hold_timeout; /* sec, before re-connecting */ + unsigned long tick_counter; /* counter for transmit time out */ + char devtint; /* Weather we should dev_tint() */ + struct sk_buff* rx_skb; /* receive socket buffer */ + struct sk_buff* tx_skb; /* transmit socket buffer */ + + bh_data_t *bh_head; /* Circular buffer for x25api_bh */ + unsigned long tq_working; + volatile int bh_write; + volatile int bh_read; + atomic_t bh_buff_used; + + sdla_t* card; /* -> owner */ + struct net_device *dev; /* -> bound devce */ + + int ch_idx; + unsigned char enable_IPX; + unsigned long network_number; + struct net_device_stats ifstats; /* interface statistics */ + unsigned short transmit_length; + unsigned short tx_offset; + char transmit_buffer[X25_CHAN_MTU+sizeof(x25api_hdr_t)]; + + if_send_stat_t if_send_stat; + rx_intr_stat_t rx_intr_stat; + pipe_mgmt_stat_t pipe_mgmt_stat; + + unsigned long router_start_time; /* Router start time in seconds */ + unsigned long router_up_time; + +} x25_channel_t; + +/* FIXME Take this out */ + +#ifdef NEX_OLD_CALL_INFO +typedef struct x25_call_info +{ + char dest[17]; PACKED;/* ASCIIZ destination address */ + char src[17]; PACKED;/* ASCIIZ source address */ + char nuser; PACKED;/* number of user data bytes */ + unsigned char user[127]; PACKED;/* user data */ + char nfacil; PACKED;/* number of facilities */ + struct + { + unsigned char code; PACKED; + unsigned char parm; PACKED; + } facil[64]; /* facilities */ +} x25_call_info_t; +#else +typedef struct x25_call_info +{ + char dest[MAX_X25_ADDR_SIZE] PACKED;/* ASCIIZ destination address */ + char src[MAX_X25_ADDR_SIZE] PACKED;/* ASCIIZ source address */ + unsigned char nuser PACKED; + unsigned char user[MAX_X25_DATA_SIZE] PACKED;/* user data */ + unsigned char nfacil PACKED; + unsigned char facil[MAX_X25_FACL_SIZE] PACKED; + unsigned short lcn PACKED; +} x25_call_info_t; +#endif + + + +/*=============================================== + * Private Function Prototypes + *==============================================*/ + + +/*================================================= + * WAN link driver entry points. These are + * called by the WAN router module. + */ +static int update(struct wan_device* wandev); +static int new_if(struct wan_device* wandev, struct net_device* dev, + wanif_conf_t* conf); +static int del_if(struct wan_device* wandev, struct net_device* dev); +static void disable_comm (sdla_t* card); +static void disable_comm_shutdown(sdla_t *card); + + + +/*================================================= + * WANPIPE-specific entry points + */ +static int wpx_exec (struct sdla* card, void* u_cmd, void* u_data); +static void x25api_bh(struct net_device *dev); +static int x25api_bh_cleanup(struct net_device *dev); +static int bh_enqueue(struct net_device *dev, struct sk_buff *skb); + + +/*================================================= + * Network device interface + */ +static int if_init(struct net_device* dev); +static int if_open(struct net_device* dev); +static int if_close(struct net_device* dev); +static int if_header(struct sk_buff* skb, struct net_device* dev, + unsigned short type, void* daddr, void* saddr, unsigned len); +static int if_rebuild_hdr (struct sk_buff* skb); +static int if_send(struct sk_buff* skb, struct net_device* dev); +static struct net_device_stats *if_stats(struct net_device* dev); + +static void if_tx_timeout(struct net_device *dev); + +/*================================================= + * Interrupt handlers + */ +static void wpx_isr (sdla_t *); +static void rx_intr (sdla_t *); +static void tx_intr (sdla_t *); +static void status_intr (sdla_t *); +static void event_intr (sdla_t *); +static void spur_intr (sdla_t *); +static void timer_intr (sdla_t *); + +static int tx_intr_send(sdla_t *card, struct net_device *dev); +static struct net_device *move_dev_to_next(sdla_t *card, + struct net_device *dev); + +/*================================================= + * Background polling routines + */ +static void wpx_poll (sdla_t* card); +static void poll_disconnected (sdla_t* card); +static void poll_connecting (sdla_t* card); +static void poll_active (sdla_t* card); +static void trigger_x25_poll(sdla_t *card); +static void x25_timer_routine(unsigned long data); + + + +/*================================================= + * X.25 firmware interface functions + */ +static int x25_get_version (sdla_t* card, char* str); +static int x25_configure (sdla_t* card, TX25Config* conf); +static int hdlc_configure (sdla_t* card, TX25Config* conf); +static int set_hdlc_level (sdla_t* card); +static int x25_get_err_stats (sdla_t* card); +static int x25_get_stats (sdla_t* card); +static int x25_set_intr_mode (sdla_t* card, int mode); +static int x25_close_hdlc (sdla_t* card); +static int x25_open_hdlc (sdla_t* card); +static int x25_setup_hdlc (sdla_t* card); +static int x25_set_dtr (sdla_t* card, int dtr); +static int x25_get_chan_conf (sdla_t* card, x25_channel_t* chan); +static int x25_place_call (sdla_t* card, x25_channel_t* chan); +static int x25_accept_call (sdla_t* card, int lcn, int qdm); +static int x25_clear_call (sdla_t* card, int lcn, int cause, int diagn); +static int x25_send (sdla_t* card, int lcn, int qdm, int len, void* buf); +static int x25_fetch_events (sdla_t* card); +static int x25_error (sdla_t* card, int err, int cmd, int lcn); + +/*================================================= + * X.25 asynchronous event handlers + */ +static int incoming_call (sdla_t* card, int cmd, int lcn, TX25Mbox* mb); +static int call_accepted (sdla_t* card, int cmd, int lcn, TX25Mbox* mb); +static int call_cleared (sdla_t* card, int cmd, int lcn, TX25Mbox* mb); +static int timeout_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb); +static int restart_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb); + + +/*================================================= + * Miscellaneous functions + */ +static int connect (sdla_t* card); +static int disconnect (sdla_t* card); +static struct net_device* get_dev_by_lcn(struct wan_device* wandev, + unsigned lcn); +static int chan_connect(struct net_device* dev); +static int chan_disc(struct net_device* dev); +static void set_chan_state(struct net_device* dev, int state); +static int chan_send(struct net_device *dev, void* buff, unsigned data_len, + unsigned char tx_intr); +static unsigned char bps_to_speed_code (unsigned long bps); +static unsigned int dec_to_uint (unsigned char* str, int len); +static unsigned int hex_to_uint (unsigned char*, int); +static void parse_call_info (unsigned char*, x25_call_info_t*); +static struct net_device *find_channel(sdla_t *card, unsigned lcn); +static void bind_lcn_to_dev(sdla_t *card, struct net_device *dev, unsigned lcn); +static void setup_for_delayed_transmit(struct net_device *dev, + void *buf, unsigned len); + + +/*================================================= + * X25 API Functions + */ +static int wanpipe_pull_data_in_skb(sdla_t *card, struct net_device *dev, + struct sk_buff **); +static void timer_intr_exec(sdla_t *, unsigned char); +static int execute_delayed_cmd(sdla_t *card, struct net_device *dev, + mbox_cmd_t *usr_cmd, char bad_cmd); +static int api_incoming_call (sdla_t*, TX25Mbox *, int); +static int alloc_and_init_skb_buf (sdla_t *,struct sk_buff **, int); +static void send_delayed_cmd_result(sdla_t *card, struct net_device *dev, + TX25Mbox* mbox); +static int clear_confirm_event (sdla_t *, TX25Mbox*); +static void send_oob_msg (sdla_t *card, struct net_device *dev, TX25Mbox *mbox); +static int timer_intr_cmd_exec(sdla_t *card); +static void api_oob_event (sdla_t *card,TX25Mbox *mbox); +static int check_bad_command(sdla_t *card, struct net_device *dev); +static int channel_disconnect(sdla_t* card, struct net_device *dev); +static void hdlc_link_down (sdla_t*); + +/*================================================= + * XPIPEMON Functions + */ +static int process_udp_mgmt_pkt(sdla_t *); +static int udp_pkt_type( struct sk_buff *, sdla_t*); +static int reply_udp( unsigned char *, unsigned int); +static void init_x25_channel_struct( x25_channel_t *); +static void init_global_statistics( sdla_t *); +static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t *card, + struct net_device *dev, + struct sk_buff *skb, int lcn); +static unsigned short calc_checksum (char *, int); + + + +/*================================================= + * IPX functions + */ +static void switch_net_numbers(unsigned char *, unsigned long, unsigned char); +static int handle_IPXWAN(unsigned char *, char *, unsigned char , + unsigned long , unsigned short ); + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +static void S508_S514_lock(sdla_t *, unsigned long *); +static void S508_S514_unlock(sdla_t *, unsigned long *); + + +/*================================================= + * Global Variables + *=================================================*/ + + + +/*================================================= + * Public Functions + *=================================================*/ + + + + +/*=================================================================== + * wpx_init: X.25 Protocol Initialization routine. + * + * Purpose: To initialize the protocol/firmware. + * + * Rationale: This function is called by setup() function, in + * sdlamain.c, to dynamically setup the x25 protocol. + * This is the first protocol specific function, which + * executes once on startup. + * + * Description: This procedure initializes the x25 firmware and + * sets up the mailbox, transmit and receive buffer + * pointers. It also initializes all debugging structures + * and sets up the X25 environment. + * + * Sets up hardware options defined by user in [wanpipe#] + * section of wanpipe#.conf configuration file. + * + * At this point adapter is completely initialized + * and X.25 firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the + * adapter data space. + * + * Called by: setup() function in sdlamain.c + * + * Assumptions: None + * + * Warnings: None + * + * Return: 0 o.k. + * < 0 failure. + */ + +int wpx_init (sdla_t* card, wandev_conf_t* conf) +{ + union{ + char str[80]; + TX25Config cfg; + } u; + + /* Verify configuration ID */ + if (conf->config_id != WANCONFIG_X25){ + printk(KERN_INFO "%s: invalid configuration ID %u!\n", + card->devname, conf->config_id) + ; + return -EINVAL; + } + + /* Initialize protocol-specific fields */ + card->mbox = (void*)(card->hw.dpmbase + X25_MBOX_OFFS); + card->rxmb = (void*)(card->hw.dpmbase + X25_RXMBOX_OFFS); + card->flags = (void*)(card->hw.dpmbase + X25_STATUS_OFFS); + + /* Initialize for S514 Card */ + if(card->hw.type == SDLA_S514) { + card->mbox += X25_MB_VECTOR; + card->flags += X25_MB_VECTOR; + card->rxmb += X25_MB_VECTOR; + } + + + /* Read firmware version. Note that when adapter initializes, it + * clears the mailbox, so it may appear that the first command was + * executed successfully when in fact it was merely erased. To work + * around this, we execute the first command twice. + */ + if (x25_get_version(card, NULL) || x25_get_version(card, u.str)) + return -EIO; + + + /* X25 firmware can run ether in X25 or LAPB HDLC mode. + * Check the user defined option and configure accordingly */ + if (conf->u.x25.LAPB_hdlc_only == WANOPT_YES){ + if (set_hdlc_level(card) != CMD_OK){ + return -EIO; + }else{ + printk(KERN_INFO "%s: running LAP_B HDLC firmware v%s\n", + card->devname, u.str); + } + card->u.x.LAPB_hdlc = 1; + }else{ + printk(KERN_INFO "%s: running X.25 firmware v%s\n", + card->devname, u.str); + card->u.x.LAPB_hdlc = 0; + } + + /* Configure adapter. Here we set resonable defaults, then parse + * device configuration structure and set configuration options. + * Most configuration options are verified and corrected (if + * necessary) since we can't rely on the adapter to do so. + */ + memset(&u.cfg, 0, sizeof(u.cfg)); + u.cfg.t1 = 3; + u.cfg.n2 = 10; + u.cfg.autoHdlc = 1; /* automatic HDLC connection */ + u.cfg.hdlcWindow = 7; + u.cfg.pktWindow = 2; + u.cfg.station = 1; /* DTE */ + u.cfg.options = 0x0090; /* disable D-bit pragmatics */ + u.cfg.ccittCompat = 1988; + u.cfg.t10t20 = 30; + u.cfg.t11t21 = 30; + u.cfg.t12t22 = 30; + u.cfg.t13t23 = 30; + u.cfg.t16t26 = 30; + u.cfg.t28 = 30; + u.cfg.r10r20 = 5; + u.cfg.r12r22 = 5; + u.cfg.r13r23 = 5; + u.cfg.responseOpt = 1; /* RR's after every packet */ + + if (card->u.x.LAPB_hdlc){ + u.cfg.hdlcMTU = 1027; + } + + if (conf->u.x25.x25_conf_opt){ + u.cfg.options = conf->u.x25.x25_conf_opt; + } + + if (conf->clocking != WANOPT_EXTERNAL) + u.cfg.baudRate = bps_to_speed_code(conf->bps); + + if (conf->station != WANOPT_DTE){ + u.cfg.station = 0; /* DCE mode */ + } + + if (conf->interface != WANOPT_RS232 ){ + u.cfg.hdlcOptions |= 0x80; /* V35 mode */ + } + + /* adjust MTU */ + if (!conf->mtu || (conf->mtu >= 1024)) + card->wandev.mtu = 1024; + else if (conf->mtu >= 512) + card->wandev.mtu = 512; + else if (conf->mtu >= 256) + card->wandev.mtu = 256; + else if (conf->mtu >= 128) + card->wandev.mtu = 128; + else + card->wandev.mtu = 64; + + u.cfg.defPktSize = u.cfg.pktMTU = card->wandev.mtu; + + if (conf->u.x25.hi_pvc){ + card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, MAX_LCN_NUM); + card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc); + } + + if (conf->u.x25.hi_svc){ + card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, MAX_LCN_NUM); + card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc); + } + + /* Figure out the total number of channels to configure */ + card->u.x.num_of_ch = 0; + if (card->u.x.hi_svc != 0){ + card->u.x.num_of_ch = (card->u.x.hi_svc - card->u.x.lo_svc) + 1; + } + if (card->u.x.hi_pvc != 0){ + card->u.x.num_of_ch += (card->u.x.hi_pvc - card->u.x.lo_pvc) + 1; + } + + if (card->u.x.num_of_ch == 0){ + printk(KERN_INFO "%s: ERROR, Minimum number of PVC/SVC channels is 1 !\n" + "%s: Please set the Lowest/Highest PVC/SVC values !\n", + card->devname,card->devname); + return -ECHRNG; + } + + u.cfg.loPVC = card->u.x.lo_pvc; + u.cfg.hiPVC = card->u.x.hi_pvc; + u.cfg.loTwoWaySVC = card->u.x.lo_svc; + u.cfg.hiTwoWaySVC = card->u.x.hi_svc; + + if (conf->u.x25.hdlc_window) + u.cfg.hdlcWindow = min_t(unsigned int, conf->u.x25.hdlc_window, 7); + if (conf->u.x25.pkt_window) + u.cfg.pktWindow = min_t(unsigned int, conf->u.x25.pkt_window, 7); + + if (conf->u.x25.t1) + u.cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30); + if (conf->u.x25.t2) + u.cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 29); + if (conf->u.x25.t4) + u.cfg.t4 = min_t(unsigned int, conf->u.x25.t4, 240); + if (conf->u.x25.n2) + u.cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30); + + if (conf->u.x25.t10_t20) + u.cfg.t10t20 = min_t(unsigned int, conf->u.x25.t10_t20,255); + if (conf->u.x25.t11_t21) + u.cfg.t11t21 = min_t(unsigned int, conf->u.x25.t11_t21,255); + if (conf->u.x25.t12_t22) + u.cfg.t12t22 = min_t(unsigned int, conf->u.x25.t12_t22,255); + if (conf->u.x25.t13_t23) + u.cfg.t13t23 = min_t(unsigned int, conf->u.x25.t13_t23,255); + if (conf->u.x25.t16_t26) + u.cfg.t16t26 = min_t(unsigned int, conf->u.x25.t16_t26, 255); + if (conf->u.x25.t28) + u.cfg.t28 = min_t(unsigned int, conf->u.x25.t28, 255); + + if (conf->u.x25.r10_r20) + u.cfg.r10r20 = min_t(unsigned int, conf->u.x25.r10_r20,250); + if (conf->u.x25.r12_r22) + u.cfg.r12r22 = min_t(unsigned int, conf->u.x25.r12_r22,250); + if (conf->u.x25.r13_r23) + u.cfg.r13r23 = min_t(unsigned int, conf->u.x25.r13_r23,250); + + + if (conf->u.x25.ccitt_compat) + u.cfg.ccittCompat = conf->u.x25.ccitt_compat; + + /* initialize adapter */ + if (card->u.x.LAPB_hdlc){ + if (hdlc_configure(card, &u.cfg) != CMD_OK) + return -EIO; + }else{ + if (x25_configure(card, &u.cfg) != CMD_OK) + return -EIO; + } + + if ((x25_close_hdlc(card) != CMD_OK) || /* close HDLC link */ + (x25_set_dtr(card, 0) != CMD_OK)) /* drop DTR */ + return -EIO; + + /* Initialize protocol-specific fields of adapter data space */ + card->wandev.bps = conf->bps; + card->wandev.interface = conf->interface; + card->wandev.clocking = conf->clocking; + card->wandev.station = conf->station; + card->isr = &wpx_isr; + card->poll = NULL; //&wpx_poll; + card->disable_comm = &disable_comm; + card->exec = &wpx_exec; + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + + /* WARNING: This function cannot exit with an error + * after the change of state */ + card->wandev.state = WAN_DISCONNECTED; + + card->wandev.enable_tx_int = 0; + card->irq_dis_if_send_count = 0; + card->irq_dis_poll_count = 0; + card->u.x.tx_dev = NULL; + card->u.x.no_dev = 0; + + + /* Configure for S514 PCI Card */ + if (card->hw.type == SDLA_S514) { + card->u.x.hdlc_buf_status = + (volatile unsigned char *) + (card->hw.dpmbase + X25_MB_VECTOR+ X25_MISC_HDLC_BITS); + }else{ + card->u.x.hdlc_buf_status = + (volatile unsigned char *)(card->hw.dpmbase + X25_MISC_HDLC_BITS); + } + + card->u.x.poll_device=NULL; + card->wandev.udp_port = conf->udp_port; + + /* Enable or disable call setup logging */ + if (conf->u.x25.logging == WANOPT_YES){ + printk(KERN_INFO "%s: Enabling Call Logging.\n", + card->devname); + card->u.x.logging = 1; + }else{ + card->u.x.logging = 0; + } + + /* Enable or disable modem status reporting */ + if (conf->u.x25.oob_on_modem == WANOPT_YES){ + printk(KERN_INFO "%s: Enabling OOB on Modem change.\n", + card->devname); + card->u.x.oob_on_modem = 1; + }else{ + card->u.x.oob_on_modem = 0; + } + + init_global_statistics(card); + + INIT_WORK(&card->u.x.x25_poll_work, (void *)wpx_poll, card); + + init_timer(&card->u.x.x25_timer); + card->u.x.x25_timer.data = (unsigned long)card; + card->u.x.x25_timer.function = x25_timer_routine; + + return 0; +} + +/*========================================================= + * WAN Device Driver Entry Points + *========================================================*/ + +/*============================================================ + * Name: update(), Update device status & statistics. + * + * Purpose: To provide debugging and statitical + * information to the /proc file system. + * /proc/net/wanrouter/wanpipe# + * + * Rationale: The /proc file system is used to collect + * information about the kernel and drivers. + * Using the /proc file system the user + * can see exactly what the sangoma drivers are + * doing. And in what state they are in. + * + * Description: Collect all driver statistical information + * and pass it to the top laywer. + * + * Since we have to execute a debugging command, + * to obtain firmware statitics, we trigger a + * UPDATE function within the timer interrtup. + * We wait until the timer update is complete. + * Once complete return the appropriate return + * code to indicate that the update was successful. + * + * Called by: device_stat() in wanmain.c + * + * Assumptions: + * + * Warnings: This function will degrade the performance + * of the router, since it uses the mailbox. + * + * Return: 0 OK + * <0 Failed (or busy). + */ + +static int update(struct wan_device* wandev) +{ + volatile sdla_t* card; + TX25Status* status; + unsigned long timeout; + + /* sanity checks */ + if ((wandev == NULL) || (wandev->private == NULL)) + return -EFAULT; + + if (wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + if (test_bit(SEND_CRIT, (void*)&wandev->critical)) + return -EAGAIN; + + if (!wandev->dev) + return -ENODEV; + + card = wandev->private; + status = card->flags; + + card->u.x.timer_int_enabled |= TMR_INT_ENABLED_UPDATE; + status->imask |= INTR_ON_TIMER; + timeout = jiffies; + + for (;;){ + if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_UPDATE)){ + break; + } + if (time_after(jiffies, timeout + 1*HZ)){ + card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE; + return -EAGAIN; + } + } + return 0; +} + + +/*=================================================================== + * Name: new_if + * + * Purpose: To allocate and initialize resources for a + * new logical channel. + * + * Rationale: A new channel can be added dynamically via + * ioctl call. + * + * Description: Allocate a private channel structure, x25_channel_t. + * Parse the user interface options from wanpipe#.conf + * configuration file. + * Bind the private are into the network device private + * area pointer (dev->priv). + * Prepare the network device structure for registration. + * + * Called by: ROUTER_IFNEW Ioctl call, from wanrouter_ioctl() + * (wanmain.c) + * + * Assumptions: None + * + * Warnings: None + * + * Return: 0 Ok + * <0 Failed (channel will not be created) + */ +static int new_if(struct wan_device* wandev, struct net_device* dev, + wanif_conf_t* conf) +{ + sdla_t* card = wandev->private; + x25_channel_t* chan; + int err = 0; + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)){ + printk(KERN_INFO "%s: invalid interface name!\n", + card->devname); + return -EINVAL; + } + + if(card->wandev.new_if_cnt++ > 0 && card->u.x.LAPB_hdlc) { + printk(KERN_INFO "%s: Error: Running LAPB HDLC Mode !\n", + card->devname); + printk(KERN_INFO + "%s: Maximum number of network interfaces must be one !\n", + card->devname); + return -EEXIST; + } + + /* allocate and initialize private data */ + chan = kmalloc(sizeof(x25_channel_t), GFP_ATOMIC); + if (chan == NULL){ + return -ENOMEM; + } + + memset(chan, 0, sizeof(x25_channel_t)); + + /* Bug Fix: Seg Err on PVC startup + * It must be here since bind_lcn_to_dev expects + * it bellow */ + dev->priv = chan; + + strcpy(chan->name, conf->name); + chan->card = card; + chan->dev = dev; + chan->common.sk = NULL; + chan->common.func = NULL; + chan->common.rw_bind = 0; + chan->tx_skb = chan->rx_skb = NULL; + + /* verify media address */ + if (conf->addr[0] == '@'){ /* SVC */ + chan->common.svc = 1; + strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ); + + /* Set channel timeouts (default if not specified) */ + chan->idle_timeout = (conf->idle_timeout) ? + conf->idle_timeout : 90; + chan->hold_timeout = (conf->hold_timeout) ? + conf->hold_timeout : 10; + + }else if (isdigit(conf->addr[0])){ /* PVC */ + int lcn = dec_to_uint(conf->addr, 0); + + if ((lcn >= card->u.x.lo_pvc) && (lcn <= card->u.x.hi_pvc)){ + bind_lcn_to_dev (card, dev, lcn); + }else{ + printk(KERN_ERR + "%s: PVC %u is out of range on interface %s!\n", + wandev->name, lcn, chan->name); + err = -EINVAL; + } + }else{ + printk(KERN_ERR + "%s: invalid media address on interface %s!\n", + wandev->name, chan->name); + err = -EINVAL; + } + + if(strcmp(conf->usedby, "WANPIPE") == 0){ + printk(KERN_INFO "%s: Running in WANPIPE mode %s\n", + wandev->name, chan->name); + chan->common.usedby = WANPIPE; + chan->protocol = htons(ETH_P_IP); + + }else if(strcmp(conf->usedby, "API") == 0){ + chan->common.usedby = API; + printk(KERN_INFO "%s: Running in API mode %s\n", + wandev->name, chan->name); + chan->protocol = htons(X25_PROT); + } + + + if (err){ + kfree(chan); + dev->priv = NULL; + return err; + } + + chan->enable_IPX = conf->enable_IPX; + + if (chan->enable_IPX) + chan->protocol = htons(ETH_P_IPX); + + if (conf->network_number) + chan->network_number = conf->network_number; + else + chan->network_number = 0xDEADBEEF; + + /* prepare network device data space for registration */ + strcpy(dev->name,chan->name); + + dev->init = &if_init; + + init_x25_channel_struct(chan); + + return 0; +} + +/*=================================================================== + * Name: del_if(), Remove a logical channel. + * + * Purpose: To dynamically remove a logical channel. + * + * Rationale: Each logical channel should be dynamically + * removable. This functin is called by an + * IOCTL_IFDEL ioctl call or shutdown(). + * + * Description: Do nothing. + * + * Called by: IOCTL_IFDEL : wanrouter_ioctl() from wanmain.c + * shutdown() from sdlamain.c + * + * Assumptions: + * + * Warnings: + * + * Return: 0 Ok. Void function. + */ + +//FIXME Del IF Should be taken out now. + +static int del_if(struct wan_device* wandev, struct net_device* dev) +{ + return 0; +} + + +/*============================================================ + * Name: wpx_exec + * + * Description: Execute adapter interface command. + * This option is currently dissabled. + *===========================================================*/ + +static int wpx_exec (struct sdla* card, void* u_cmd, void* u_data) +{ + return 0; +} + +/*============================================================ + * Name: disable_comm + * + * Description: Disable communications during shutdown. + * Dont check return code because there is + * nothing we can do about it. + * + * Warning: Dev and private areas are gone at this point. + *===========================================================*/ + +static void disable_comm(sdla_t* card) +{ + disable_comm_shutdown(card); + del_timer(&card->u.x.x25_timer); + return; +} + + +/*============================================================ + * Network Device Interface + *===========================================================*/ + +/*=================================================================== + * Name: if_init(), Netowrk Interface Initialization + * + * Purpose: To initialize a network interface device structure. + * + * Rationale: During network interface startup, the if_init + * is called by the kernel to initialize the + * netowrk device structure. Thus a driver + * can customze a network device. + * + * Description: Initialize the netowrk device call back + * routines. This is where we tell the kernel + * which function to use when it wants to send + * via our interface. + * Furthermore, we initialize the device flags, + * MTU and physical address of the board. + * + * Called by: Kernel (/usr/src/linux/net/core/dev.c) + * (dev->init()) + * + * Assumptions: None + * + * Warnings: None + * + * Return: 0 Ok : Void function. + */ +static int if_init(struct net_device* dev) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + struct wan_device* wandev = &card->wandev; + + /* Initialize device driver entry points */ + dev->open = &if_open; + dev->stop = &if_close; + dev->hard_header = &if_header; + dev->rebuild_header = &if_rebuild_hdr; + dev->hard_start_xmit = &if_send; + dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + /* Initialize media-specific parameters */ + dev->type = ARPHRD_PPP; /* ARP h/w type */ + dev->flags |= IFF_POINTOPOINT; + dev->flags |= IFF_NOARP; + + if (chan->common.usedby == API){ + dev->mtu = X25_CHAN_MTU+sizeof(x25api_hdr_t); + }else{ + dev->mtu = card->wandev.mtu; + } + + dev->hard_header_len = X25_HRDHDR_SZ; /* media header length */ + dev->addr_len = 2; /* hardware address length */ + + if (!chan->common.svc){ + *(unsigned short*)dev->dev_addr = htons(chan->common.lcn); + } + + /* Initialize hardware parameters (just for reference) */ + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + dev->mem_start = (unsigned long)wandev->maddr; + dev->mem_end = wandev->maddr + wandev->msize - 1; + + /* Set transmit buffer queue length */ + dev->tx_queue_len = 100; + SET_MODULE_OWNER(dev); + + /* FIXME Why are we doing this */ + set_chan_state(dev, WAN_DISCONNECTED); + return 0; +} + + +/*=================================================================== + * Name: if_open(), Open/Bring up the Netowrk Interface + * + * Purpose: To bring up a network interface. + * + * Rationale: + * + * Description: Open network interface. + * o prevent module from unloading by incrementing use count + * o if link is disconnected then initiate connection + * + * Called by: Kernel (/usr/src/linux/net/core/dev.c) + * (dev->open()) + * + * Assumptions: None + * + * Warnings: None + * + * Return: 0 Ok + * <0 Failure: Interface will not come up. + */ + +static int if_open(struct net_device* dev) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + struct timeval tv; + unsigned long smp_flags; + + if (netif_running(dev)) + return -EBUSY; + + chan->tq_working = 0; + + /* Initialize the workqueue */ + INIT_WORK(&chan->common.wanpipe_work, (void *)x25api_bh, dev); + + /* Allocate and initialize BH circular buffer */ + /* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */ + chan->bh_head = kmalloc((sizeof(bh_data_t)*(MAX_BH_BUFF+1)),GFP_ATOMIC); + + if (chan->bh_head == NULL){ + printk(KERN_INFO "%s: ERROR, failed to allocate memory ! BH_BUFFERS !\n", + card->devname); + + return -ENOBUFS; + } + memset(chan->bh_head,0,(sizeof(bh_data_t)*(MAX_BH_BUFF+1))); + atomic_set(&chan->bh_buff_used, 0); + + /* Increment the number of interfaces */ + ++card->u.x.no_dev; + + wanpipe_open(card); + + /* LAPB protocol only uses one interface, thus + * start the protocol after it comes up. */ + if (card->u.x.LAPB_hdlc){ + if (card->open_cnt == 1){ + TX25Status* status = card->flags; + S508_S514_lock(card, &smp_flags); + x25_set_intr_mode(card, INTR_ON_TIMER); + status->imask &= ~INTR_ON_TIMER; + S508_S514_unlock(card, &smp_flags); + } + }else{ + /* X25 can have multiple interfaces thus, start the + * protocol once all interfaces are up */ + + //FIXME: There is a bug here. If interface is + //brought down and up, it will try to enable comm. + if (card->open_cnt == card->u.x.num_of_ch){ + + S508_S514_lock(card, &smp_flags); + connect(card); + S508_S514_unlock(card, &smp_flags); + + mod_timer(&card->u.x.x25_timer, jiffies + HZ); + } + } + /* Device is not up until the we are in connected state */ + do_gettimeofday( &tv ); + chan->router_start_time = tv.tv_sec; + + netif_start_queue(dev); + + return 0; +} + +/*=================================================================== + * Name: if_close(), Close/Bring down the Netowrk Interface + * + * Purpose: To bring down a network interface. + * + * Rationale: + * + * Description: Close network interface. + * o decrement use module use count + * + * Called by: Kernel (/usr/src/linux/net/core/dev.c) + * (dev->close()) + * ifconfig down: will trigger the kernel + * which will call this function. + * + * Assumptions: None + * + * Warnings: None + * + * Return: 0 Ok + * <0 Failure: Interface will not exit properly. + */ +static int if_close(struct net_device* dev) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + unsigned long smp_flags; + + netif_stop_queue(dev); + + if ((chan->common.state == WAN_CONNECTED) || + (chan->common.state == WAN_CONNECTING)){ + S508_S514_lock(card, &smp_flags); + chan_disc(dev); + S508_S514_unlock(card, &smp_flags); + } + + wanpipe_close(card); + + S508_S514_lock(card, &smp_flags); + if (chan->bh_head){ + int i; + struct sk_buff *skb; + + for (i=0; i<(MAX_BH_BUFF+1); i++){ + skb = ((bh_data_t *)&chan->bh_head[i])->skb; + if (skb != NULL){ + dev_kfree_skb_any(skb); + } + } + kfree(chan->bh_head); + chan->bh_head=NULL; + } + S508_S514_unlock(card, &smp_flags); + + /* If this is the last close, disconnect physical link */ + if (!card->open_cnt){ + S508_S514_lock(card, &smp_flags); + disconnect(card); + x25_set_intr_mode(card, 0); + S508_S514_unlock(card, &smp_flags); + } + + /* Decrement the number of interfaces */ + --card->u.x.no_dev; + return 0; +} + +/*====================================================================== + * Build media header. + * o encapsulate packet according to encapsulation type. + * + * The trick here is to put packet type (Ethertype) into 'protocol' + * field of the socket buffer, so that we don't forget it. + * If encapsulation fails, set skb->protocol to 0 and discard + * packet later. + * + * Return: media header length. + *======================================================================*/ + +static int if_header(struct sk_buff* skb, struct net_device* dev, + unsigned short type, void* daddr, void* saddr, + unsigned len) +{ + x25_channel_t* chan = dev->priv; + int hdr_len = dev->hard_header_len; + + skb->protocol = htons(type); + if (!chan->protocol){ + hdr_len = wanrouter_encapsulate(skb, dev, type); + if (hdr_len < 0){ + hdr_len = 0; + skb->protocol = htons(0); + } + } + return hdr_len; +} + +/*=============================================================== + * Re-build media header. + * + * Return: 1 physical address resolved. + * 0 physical address not resolved + *==============================================================*/ + +static int if_rebuild_hdr (struct sk_buff* skb) +{ + struct net_device *dev = skb->dev; + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + + printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", + card->devname, dev->name); + return 1; +} + + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout(struct net_device *dev) +{ + x25_channel_t* chan = dev->priv; + sdla_t *card = chan->card; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + ++chan->if_send_stat.if_send_tbusy_timeout; + printk (KERN_INFO "%s: Transmit timed out on %s\n", + card->devname, dev->name); + netif_wake_queue (dev); +} + + +/*========================================================================= + * Send a packet on a network interface. + * o set tbusy flag (marks start of the transmission). + * o check link state. If link is not up, then drop the packet. + * o check channel status. If it's down then initiate a call. + * o pass a packet to corresponding WAN device. + * o free socket buffer + * + * Return: 0 complete (socket buffer must be freed) + * non-0 packet may be re-transmitted (tbusy must be set) + * + * Notes: + * 1. This routine is called either by the protocol stack or by the "net + * bottom half" (with interrupts enabled). + * 2. Setting tbusy flag will inhibit further transmit requests from the + * protocol stack and can be used for flow control with protocol layer. + * + *========================================================================*/ + +static int if_send(struct sk_buff* skb, struct net_device* dev) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + TX25Status* status = card->flags; + int udp_type; + unsigned long smp_flags=0; + + ++chan->if_send_stat.if_send_entry; + + netif_stop_queue(dev); + + /* No need to check frame length, since socket code + * will perform the check for us */ + + chan->tick_counter = jiffies; + + /* Critical region starts here */ + S508_S514_lock(card, &smp_flags); + + if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)){ + printk(KERN_INFO "Hit critical in if_send()! %lx\n",card->wandev.critical); + goto if_send_crit_exit; + } + + udp_type = udp_pkt_type(skb, card); + + if(udp_type != UDP_INVALID_TYPE) { + + if(store_udp_mgmt_pkt(udp_type, UDP_PKT_FRM_STACK, card, dev, skb, + chan->common.lcn)) { + + status->imask |= INTR_ON_TIMER; + if (udp_type == UDP_XPIPE_TYPE){ + chan->if_send_stat.if_send_PIPE_request++; + } + } + netif_start_queue(dev); + clear_bit(SEND_CRIT,(void*)&card->wandev.critical); + S508_S514_unlock(card, &smp_flags); + return 0; + } + + if (chan->transmit_length){ + //FIXME: This check doesn't make sense any more + if (chan->common.state != WAN_CONNECTED){ + chan->transmit_length=0; + atomic_set(&chan->common.driver_busy,0); + }else{ + netif_stop_queue(dev); + ++card->u.x.tx_interrupts_pending; + status->imask |= INTR_ON_TX_FRAME; + clear_bit(SEND_CRIT,(void*)&card->wandev.critical); + S508_S514_unlock(card, &smp_flags); + return 1; + } + } + + if (card->wandev.state != WAN_CONNECTED){ + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + ++chan->if_send_stat.if_send_wan_disconnected; + + }else if ( chan->protocol && (chan->protocol != skb->protocol)){ + printk(KERN_INFO + "%s: unsupported Ethertype 0x%04X on interface %s!\n", + chan->name, htons(skb->protocol), dev->name); + + printk(KERN_INFO "PROTO %Xn", htons(chan->protocol)); + ++chan->ifstats.tx_errors; + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + ++chan->if_send_stat.if_send_protocol_error; + + }else switch (chan->common.state){ + + case WAN_DISCONNECTED: + /* Try to establish connection. If succeded, then start + * transmission, else drop a packet. + */ + if (chan->common.usedby == API){ + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + break; + }else{ + if (chan_connect(dev) != 0){ + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + break; + } + } + /* fall through */ + + case WAN_CONNECTED: + if( skb->protocol == htons(ETH_P_IPX)) { + if(chan->enable_IPX) { + switch_net_numbers( skb->data, + chan->network_number, 0); + } else { + ++card->wandev.stats.tx_dropped; + ++chan->ifstats.tx_dropped; + ++chan->if_send_stat.if_send_protocol_error; + goto if_send_crit_exit; + } + } + /* We never drop here, if cannot send than, copy + * a packet into a transmit buffer + */ + chan_send(dev, skb->data, skb->len, 0); + break; + + default: + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + break; + } + + +if_send_crit_exit: + + dev_kfree_skb_any(skb); + + netif_start_queue(dev); + clear_bit(SEND_CRIT,(void*)&card->wandev.critical); + S508_S514_unlock(card, &smp_flags); + return 0; +} + +/*============================================================================ + * Setup so that a frame can be transmitted on the occurrence of a transmit + * interrupt. + *===========================================================================*/ + +static void setup_for_delayed_transmit(struct net_device* dev, void* buf, + unsigned len) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + TX25Status* status = card->flags; + + ++chan->if_send_stat.if_send_adptr_bfrs_full; + + if(chan->transmit_length) { + printk(KERN_INFO "%s: Error, transmit length set in delayed transmit!\n", + card->devname); + return; + } + + if (chan->common.usedby == API){ + if (len > X25_CHAN_MTU+sizeof(x25api_hdr_t)) { + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + printk(KERN_INFO "%s: Length is too big for delayed transmit\n", + card->devname); + return; + } + }else{ + if (len > X25_MAX_DATA) { + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + printk(KERN_INFO "%s: Length is too big for delayed transmit\n", + card->devname); + return; + } + } + + chan->transmit_length = len; + atomic_set(&chan->common.driver_busy,1); + memcpy(chan->transmit_buffer, buf, len); + + ++chan->if_send_stat.if_send_tx_int_enabled; + + /* Enable Transmit Interrupt */ + ++card->u.x.tx_interrupts_pending; + status->imask |= INTR_ON_TX_FRAME; +} + + +/*=============================================================== + * net_device_stats + * + * Get ethernet-style interface statistics. + * Return a pointer to struct enet_statistics. + * + *==============================================================*/ +static struct net_device_stats *if_stats(struct net_device* dev) +{ + x25_channel_t *chan = dev->priv; + + if(chan == NULL) + return NULL; + + return &chan->ifstats; +} + + +/* + * Interrupt Handlers + */ + +/* + * X.25 Interrupt Service Routine. + */ + +static void wpx_isr (sdla_t* card) +{ + TX25Status* status = card->flags; + + card->in_isr = 1; + ++card->statistics.isr_entry; + + if (test_bit(PERI_CRIT,(void*)&card->wandev.critical)){ + card->in_isr=0; + status->iflags = 0; + return; + } + + if (test_bit(SEND_CRIT, (void*)&card->wandev.critical)){ + + printk(KERN_INFO "%s: wpx_isr: wandev.critical set to 0x%02lx, int type = 0x%02x\n", + card->devname, card->wandev.critical, status->iflags); + card->in_isr = 0; + status->iflags = 0; + return; + } + + /* For all interrupts set the critical flag to CRITICAL_RX_INTR. + * If the if_send routine is called with this flag set it will set + * the enable transmit flag to 1. (for a delayed interrupt) + */ + switch (status->iflags){ + + case RX_INTR_PENDING: /* receive interrupt */ + rx_intr(card); + break; + + case TX_INTR_PENDING: /* transmit interrupt */ + tx_intr(card); + break; + + case MODEM_INTR_PENDING: /* modem status interrupt */ + status_intr(card); + break; + + case X25_ASY_TRANS_INTR_PENDING: /* network event interrupt */ + event_intr(card); + break; + + case TIMER_INTR_PENDING: + timer_intr(card); + break; + + default: /* unwanted interrupt */ + spur_intr(card); + } + + card->in_isr = 0; + status->iflags = 0; /* clear interrupt condition */ +} + +/* + * Receive interrupt handler. + * This routine handles fragmented IP packets using M-bit according to the + * RFC1356. + * o map ligical channel number to network interface. + * o allocate socket buffer or append received packet to the existing one. + * o if M-bit is reset (i.e. it's the last packet in a sequence) then + * decapsulate packet and pass socket buffer to the protocol stack. + * + * Notes: + * 1. When allocating a socket buffer, if M-bit is set then more data is + * coming and we have to allocate buffer for the maximum IP packet size + * expected on this channel. + * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no + * socket buffers available) the whole packet sequence must be discarded. + */ + +static void rx_intr (sdla_t* card) +{ + TX25Mbox* rxmb = card->rxmb; + unsigned lcn = rxmb->cmd.lcn; + struct net_device* dev = find_channel(card,lcn); + x25_channel_t* chan; + struct sk_buff* skb=NULL; + + if (dev == NULL){ + /* Invalid channel, discard packet */ + printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n", + card->devname, lcn); + return; + } + + chan = dev->priv; + chan->i_timeout_sofar = jiffies; + + + /* Copy the data from the board, into an + * skb buffer + */ + if (wanpipe_pull_data_in_skb(card,dev,&skb)){ + ++chan->ifstats.rx_dropped; + ++card->wandev.stats.rx_dropped; + ++chan->rx_intr_stat.rx_intr_no_socket; + ++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack; + return; + } + + dev->last_rx = jiffies; /* timestamp */ + + + /* ------------ API ----------------*/ + + if (chan->common.usedby == API){ + + if (bh_enqueue(dev, skb)){ + ++chan->ifstats.rx_dropped; + ++card->wandev.stats.rx_dropped; + ++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack; + dev_kfree_skb_any(skb); + return; + } + + ++chan->ifstats.rx_packets; + chan->ifstats.rx_bytes += skb->len; + + + chan->rx_skb = NULL; + if (!test_and_set_bit(0, &chan->tq_working)){ + wanpipe_queue_work(&chan->common.wanpipe_work); + } + return; + } + + + /* ------------- WANPIPE -------------------*/ + + /* set rx_skb to NULL so we won't access it later when kernel already owns it */ + chan->rx_skb=NULL; + + /* Decapsulate packet, if necessary */ + if (!skb->protocol && !wanrouter_type_trans(skb, dev)){ + /* can't decapsulate packet */ + dev_kfree_skb_any(skb); + ++chan->ifstats.rx_errors; + ++chan->ifstats.rx_dropped; + ++card->wandev.stats.rx_dropped; + ++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack; + + }else{ + if( handle_IPXWAN(skb->data, chan->name, + chan->enable_IPX, chan->network_number, + skb->protocol)){ + + if( chan->enable_IPX ){ + if(chan_send(dev, skb->data, skb->len,0)){ + chan->tx_skb = skb; + }else{ + dev_kfree_skb_any(skb); + ++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack; + } + }else{ + /* increment IPX packet dropped statistic */ + ++chan->ifstats.rx_dropped; + ++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack; + } + }else{ + skb->mac.raw = skb->data; + chan->ifstats.rx_bytes += skb->len; + ++chan->ifstats.rx_packets; + ++chan->rx_intr_stat.rx_intr_bfr_passed_to_stack; + netif_rx(skb); + } + } + + return; +} + + +static int wanpipe_pull_data_in_skb(sdla_t *card, struct net_device *dev, + struct sk_buff **skb) +{ + void *bufptr; + TX25Mbox* rxmb = card->rxmb; + unsigned len = rxmb->cmd.length; /* packet length */ + unsigned qdm = rxmb->cmd.qdm; /* Q,D and M bits */ + x25_channel_t *chan = dev->priv; + struct sk_buff *new_skb = *skb; + + if (chan->common.usedby == WANPIPE){ + if (chan->drop_sequence){ + if (!(qdm & 0x01)){ + chan->drop_sequence = 0; + } + return 1; + } + new_skb = chan->rx_skb; + }else{ + /* Add on the API header to the received + * data + */ + len += sizeof(x25api_hdr_t); + } + + if (new_skb == NULL){ + int bufsize; + + if (chan->common.usedby == WANPIPE){ + bufsize = (qdm & 0x01) ? dev->mtu : len; + }else{ + bufsize = len; + } + + /* Allocate new socket buffer */ + new_skb = dev_alloc_skb(bufsize + dev->hard_header_len); + if (new_skb == NULL){ + printk(KERN_INFO "%s: no socket buffers available!\n", + card->devname); + chan->drop_sequence = 1; /* set flag */ + ++chan->ifstats.rx_dropped; + return 1; + } + } + + if (skb_tailroom(new_skb) < len){ + /* No room for the packet. Call off the whole thing! */ + dev_kfree_skb_any(new_skb); + if (chan->common.usedby == WANPIPE){ + chan->rx_skb = NULL; + if (qdm & 0x01){ + chan->drop_sequence = 1; + } + } + + printk(KERN_INFO "%s: unexpectedly long packet sequence " + "on interface %s!\n", card->devname, dev->name); + ++chan->ifstats.rx_length_errors; + return 1; + } + + bufptr = skb_put(new_skb,len); + + + if (chan->common.usedby == API){ + /* Fill in the x25api header + */ + x25api_t * api_data = (x25api_t*)bufptr; + api_data->hdr.qdm = rxmb->cmd.qdm; + api_data->hdr.cause = rxmb->cmd.cause; + api_data->hdr.diagn = rxmb->cmd.diagn; + api_data->hdr.length = rxmb->cmd.length; + memcpy(api_data->data, rxmb->data, rxmb->cmd.length); + }else{ + memcpy(bufptr, rxmb->data, len); + } + + new_skb->dev = dev; + + if (chan->common.usedby == API){ + new_skb->mac.raw = new_skb->data; + new_skb->protocol = htons(X25_PROT); + new_skb->pkt_type = WAN_PACKET_DATA; + }else{ + new_skb->protocol = chan->protocol; + chan->rx_skb = new_skb; + } + + /* If qdm bit is set, more data is coming + * thus, exit and wait for more data before + * sending the packet up. (Used by router only) + */ + if ((qdm & 0x01) && (chan->common.usedby == WANPIPE)) + return 1; + + *skb = new_skb; + + return 0; +} + +/*=============================================================== + * tx_intr + * + * Transmit interrupt handler. + * For each dev, check that there is something to send. + * If data available, transmit. + * + *===============================================================*/ + +static void tx_intr (sdla_t* card) +{ + struct net_device *dev; + TX25Status* status = card->flags; + unsigned char more_to_tx=0; + x25_channel_t *chan=NULL; + int i=0; + + if (card->u.x.tx_dev == NULL){ + card->u.x.tx_dev = card->wandev.dev; + } + + dev = card->u.x.tx_dev; + + for (;;){ + + chan = dev->priv; + if (chan->transmit_length){ + /* Device was set to transmit, check if the TX + * buffers are available + */ + if (chan->common.state != WAN_CONNECTED){ + chan->transmit_length = 0; + atomic_set(&chan->common.driver_busy,0); + chan->tx_offset=0; + if (netif_queue_stopped(dev)){ + if (chan->common.usedby == API){ + netif_start_queue(dev); + wakeup_sk_bh(dev); + }else{ + netif_wake_queue(dev); + } + } + dev = move_dev_to_next(card,dev); + break; + } + + if ((status->cflags[chan->ch_idx] & 0x40 || card->u.x.LAPB_hdlc) && + (*card->u.x.hdlc_buf_status & 0x40) ){ + /* Tx buffer available, we can send */ + + if (tx_intr_send(card, dev)){ + more_to_tx=1; + } + + /* If more than one interface present, move the + * device pointer to the next interface, so on the + * next TX interrupt we will try sending from it. + */ + dev = move_dev_to_next(card,dev); + break; + }else{ + /* Tx buffers not available, but device set + * the TX interrupt. Set more_to_tx and try + * to transmit for other devices. + */ + more_to_tx=1; + dev = move_dev_to_next(card,dev); + } + + }else{ + /* This device was not set to transmit, + * go to next + */ + dev = move_dev_to_next(card,dev); + } + + if (++i == card->u.x.no_dev){ + if (!more_to_tx){ + DBG_PRINTK(KERN_INFO "%s: Nothing to Send in TX INTR\n", + card->devname); + } + break; + } + + } //End of FOR + + card->u.x.tx_dev = dev; + + if (!more_to_tx){ + /* if any other interfaces have transmit interrupts pending, */ + /* do not disable the global transmit interrupt */ + if (!(--card->u.x.tx_interrupts_pending)){ + status->imask &= ~INTR_ON_TX_FRAME; + } + } + return; +} + +/*=============================================================== + * move_dev_to_next + * + * + *===============================================================*/ + + +struct net_device *move_dev_to_next(sdla_t *card, struct net_device *dev) +{ + if (card->u.x.no_dev != 1){ + if (!*((struct net_device **)dev->priv)) + return card->wandev.dev; + else + return *((struct net_device **)dev->priv); + } + return dev; +} + +/*=============================================================== + * tx_intr_send + * + * + *===============================================================*/ + +static int tx_intr_send(sdla_t *card, struct net_device *dev) +{ + x25_channel_t* chan = dev->priv; + + if (chan_send (dev,chan->transmit_buffer,chan->transmit_length,1)){ + + /* Packet was split up due to its size, do not disable + * tx_intr + */ + return 1; + } + + chan->transmit_length=0; + atomic_set(&chan->common.driver_busy,0); + chan->tx_offset=0; + + /* If we are in API mode, wakeup the + * sock BH handler, not the NET_BH */ + if (netif_queue_stopped(dev)){ + if (chan->common.usedby == API){ + netif_start_queue(dev); + wakeup_sk_bh(dev); + }else{ + netif_wake_queue(dev); + } + } + return 0; +} + + +/*=============================================================== + * timer_intr + * + * Timer interrupt handler. + * Check who called the timer interrupt and perform + * action accordingly. + * + *===============================================================*/ + +static void timer_intr (sdla_t *card) +{ + TX25Status* status = card->flags; + + if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_CMD_EXEC){ + + if (timer_intr_cmd_exec(card) == 0){ + card->u.x.timer_int_enabled &= + ~TMR_INT_ENABLED_CMD_EXEC; + } + + }else if(card->u.x.timer_int_enabled & TMR_INT_ENABLED_UDP_PKT) { + + if ((*card->u.x.hdlc_buf_status & 0x40) && + card->u.x.udp_type == UDP_XPIPE_TYPE){ + + if(process_udp_mgmt_pkt(card)) { + card->u.x.timer_int_enabled &= + ~TMR_INT_ENABLED_UDP_PKT; + } + } + + }else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_POLL_ACTIVE) { + + struct net_device *dev = card->u.x.poll_device; + x25_channel_t *chan = NULL; + + if (!dev){ + card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_ACTIVE; + return; + } + chan = dev->priv; + + printk(KERN_INFO + "%s: Closing down Idle link %s on LCN %d\n", + card->devname,chan->name,chan->common.lcn); + chan->i_timeout_sofar = jiffies; + chan_disc(dev); + card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_ACTIVE; + card->u.x.poll_device=NULL; + + }else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_POLL_CONNECT_ON) { + + wanpipe_set_state(card, WAN_CONNECTED); + if (card->u.x.LAPB_hdlc){ + struct net_device *dev = card->wandev.dev; + set_chan_state(dev,WAN_CONNECTED); + send_delayed_cmd_result(card,dev,card->mbox); + } + + /* 0x8F enable all interrupts */ + x25_set_intr_mode(card, INTR_ON_RX_FRAME| + INTR_ON_TX_FRAME| + INTR_ON_MODEM_STATUS_CHANGE| + //INTR_ON_COMMAND_COMPLETE| + X25_ASY_TRANS_INTR_PENDING | + INTR_ON_TIMER | + DIRECT_RX_INTR_USAGE + ); + + status->imask &= ~INTR_ON_TX_FRAME; /* mask Tx interrupts */ + card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_CONNECT_ON; + + }else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_POLL_CONNECT_OFF) { + + //printk(KERN_INFO "Poll connect, Turning OFF\n"); + disconnect(card); + card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_CONNECT_OFF; + + }else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_POLL_DISCONNECT) { + + //printk(KERN_INFO "POll disconnect, trying to connect\n"); + connect(card); + card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_DISCONNECT; + + }else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_UPDATE){ + + if (*card->u.x.hdlc_buf_status & 0x40){ + x25_get_err_stats(card); + x25_get_stats(card); + card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE; + } + } + + if(!card->u.x.timer_int_enabled){ + //printk(KERN_INFO "Turning Timer Off \n"); + status->imask &= ~INTR_ON_TIMER; + } +} + +/*==================================================================== + * Modem status interrupt handler. + *===================================================================*/ +static void status_intr (sdla_t* card) +{ + + /* Added to avoid Modem status message flooding */ + static TX25ModemStatus last_stat; + + TX25Mbox* mbox = card->mbox; + TX25ModemStatus *modem_status; + struct net_device *dev; + x25_channel_t *chan; + int err; + + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_READ_MODEM_STATUS; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err){ + x25_error(card, err, X25_READ_MODEM_STATUS, 0); + }else{ + + modem_status = (TX25ModemStatus*)mbox->data; + + /* Check if the last status was the same + * if it was, do NOT print message again */ + + if (last_stat.status != modem_status->status){ + + printk(KERN_INFO "%s: Modem Status Change: DCD=%s, CTS=%s\n", + card->devname,DCD(modem_status->status),CTS(modem_status->status)); + + last_stat.status = modem_status->status; + + if (card->u.x.oob_on_modem){ + + mbox->cmd.pktType = mbox->cmd.command; + mbox->cmd.result = 0x08; + + /* Send a OOB to all connected sockets */ + for (dev = card->wandev.dev; dev; + dev = *((struct net_device**)dev->priv)) { + chan=dev->priv; + if (chan->common.usedby == API){ + send_oob_msg(card,dev,mbox); + } + } + + /* The modem OOB message will probably kill the + * the link. If we don't clear the flag here, + * a deadlock could occur */ + if (atomic_read(&card->u.x.command_busy)){ + atomic_set(&card->u.x.command_busy,0); + } + } + } + } + + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_HDLC_LINK_STATUS; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err){ + x25_error(card, err, X25_HDLC_LINK_STATUS, 0); + } + +} + +/*==================================================================== + * Network event interrupt handler. + *===================================================================*/ +static void event_intr (sdla_t* card) +{ + x25_fetch_events(card); +} + +/*==================================================================== + * Spurious interrupt handler. + * o print a warning + * o + *====================================================================*/ + +static void spur_intr (sdla_t* card) +{ + printk(KERN_INFO "%s: spurious interrupt!\n", card->devname); +} + + +/* + * Background Polling Routines + */ + +/*==================================================================== + * Main polling routine. + * This routine is repeatedly called by the WANPIPE 'thread' to allow for + * time-dependent housekeeping work. + * + * Notes: + * 1. This routine may be called on interrupt context with all interrupts + * enabled. Beware! + *====================================================================*/ + +static void wpx_poll (sdla_t *card) +{ + if (!card->wandev.dev){ + goto wpx_poll_exit; + } + + if (card->open_cnt != card->u.x.num_of_ch){ + goto wpx_poll_exit; + } + + if (test_bit(PERI_CRIT,&card->wandev.critical)){ + goto wpx_poll_exit; + } + + if (test_bit(SEND_CRIT,&card->wandev.critical)){ + goto wpx_poll_exit; + } + + switch(card->wandev.state){ + case WAN_CONNECTED: + poll_active(card); + break; + + case WAN_CONNECTING: + poll_connecting(card); + break; + + case WAN_DISCONNECTED: + poll_disconnected(card); + break; + } + +wpx_poll_exit: + clear_bit(POLL_CRIT,&card->wandev.critical); + return; +} + +static void trigger_x25_poll(sdla_t *card) +{ + schedule_work(&card->u.x.x25_poll_work); +} + +/*==================================================================== + * Handle physical link establishment phase. + * o if connection timed out, disconnect the link. + *===================================================================*/ + +static void poll_connecting (sdla_t* card) +{ + volatile TX25Status* status = card->flags; + + if (status->gflags & X25_HDLC_ABM){ + + timer_intr_exec (card, TMR_INT_ENABLED_POLL_CONNECT_ON); + + }else if ((jiffies - card->state_tick) > CONNECT_TIMEOUT){ + + timer_intr_exec (card, TMR_INT_ENABLED_POLL_CONNECT_OFF); + + } +} + +/*==================================================================== + * Handle physical link disconnected phase. + * o if hold-down timeout has expired and there are open interfaces, + * connect link. + *===================================================================*/ + +static void poll_disconnected (sdla_t* card) +{ + struct net_device *dev; + x25_channel_t *chan; + TX25Status* status = card->flags; + + if (!card->u.x.LAPB_hdlc && card->open_cnt && + ((jiffies - card->state_tick) > HOLD_DOWN_TIME)){ + timer_intr_exec(card, TMR_INT_ENABLED_POLL_DISCONNECT); + } + + + if ((dev=card->wandev.dev) == NULL) + return; + + if ((chan=dev->priv) == NULL) + return; + + if (chan->common.usedby == API && + atomic_read(&chan->common.command) && + card->u.x.LAPB_hdlc){ + + if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_CMD_EXEC)) + card->u.x.timer_int_enabled |= TMR_INT_ENABLED_CMD_EXEC; + + if (!(status->imask & INTR_ON_TIMER)) + status->imask |= INTR_ON_TIMER; + } + +} + +/*==================================================================== + * Handle active link phase. + * o fetch X.25 asynchronous events. + * o kick off transmission on all interfaces. + *===================================================================*/ + +static void poll_active (sdla_t* card) +{ + struct net_device* dev; + TX25Status* status = card->flags; + + for (dev = card->wandev.dev; dev; + dev = *((struct net_device **)dev->priv)){ + x25_channel_t* chan = dev->priv; + + /* If SVC has been idle long enough, close virtual circuit */ + if ( chan->common.svc && + chan->common.state == WAN_CONNECTED && + chan->common.usedby == WANPIPE ){ + + if( (jiffies - chan->i_timeout_sofar) / HZ > chan->idle_timeout ){ + /* Close svc */ + card->u.x.poll_device=dev; + timer_intr_exec (card, TMR_INT_ENABLED_POLL_ACTIVE); + } + } + +#ifdef PRINT_DEBUG + chan->ifstats.tx_compressed = atomic_read(&chan->common.command); + chan->ifstats.tx_errors = chan->common.state; + chan->ifstats.rx_fifo_errors = atomic_read(&card->u.x.command_busy); + ++chan->ifstats.tx_bytes; + + chan->ifstats.rx_fifo_errors=atomic_read(&chan->common.disconnect); + chan->ifstats.multicast=atomic_read(&chan->bh_buff_used); + chan->ifstats.rx_length_errors=*card->u.x.hdlc_buf_status; +#endif + + if (chan->common.usedby == API && + atomic_read(&chan->common.command) && + !card->u.x.LAPB_hdlc){ + + if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_CMD_EXEC)) + card->u.x.timer_int_enabled |= TMR_INT_ENABLED_CMD_EXEC; + + if (!(status->imask & INTR_ON_TIMER)) + status->imask |= INTR_ON_TIMER; + } + + if ((chan->common.usedby == API) && + atomic_read(&chan->common.disconnect)){ + + if (chan->common.state == WAN_DISCONNECTED){ + atomic_set(&chan->common.disconnect,0); + return; + } + + atomic_set(&chan->common.command,X25_CLEAR_CALL); + if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_CMD_EXEC)) + card->u.x.timer_int_enabled |= TMR_INT_ENABLED_CMD_EXEC; + + if (!(status->imask & INTR_ON_TIMER)) + status->imask |= INTR_ON_TIMER; + } + } +} + +static void timer_intr_exec(sdla_t *card, unsigned char TYPE) +{ + TX25Status* status = card->flags; + card->u.x.timer_int_enabled |= TYPE; + if (!(status->imask & INTR_ON_TIMER)) + status->imask |= INTR_ON_TIMER; +} + + +/*==================================================================== + * SDLA Firmware-Specific Functions + * + * Almost all X.25 commands can unexpetedly fail due to so called 'X.25 + * asynchronous events' such as restart, interrupt, incoming call request, + * call clear request, etc. They can't be ignored and have to be delt with + * immediately. To tackle with this problem we execute each interface + * command in a loop until good return code is received or maximum number + * of retries is reached. Each interface command returns non-zero return + * code, an asynchronous event/error handler x25_error() is called. + *====================================================================*/ + +/*==================================================================== + * Read X.25 firmware version. + * Put code version as ASCII string in str. + *===================================================================*/ + +static int x25_get_version (sdla_t* card, char* str) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_READ_CODE_VERSION; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && + x25_error(card, err, X25_READ_CODE_VERSION, 0)); + + if (!err && str) + { + int len = mbox->cmd.length; + + memcpy(str, mbox->data, len); + str[len] = '\0'; + } + return err; +} + +/*==================================================================== + * Configure adapter. + *===================================================================*/ + +static int x25_configure (sdla_t* card, TX25Config* conf) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do{ + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + memcpy(mbox->data, (void*)conf, sizeof(TX25Config)); + mbox->cmd.length = sizeof(TX25Config); + mbox->cmd.command = X25_SET_CONFIGURATION; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_SET_CONFIGURATION, 0)); + return err; +} + +/*==================================================================== + * Configure adapter for HDLC only. + *===================================================================*/ + +static int hdlc_configure (sdla_t* card, TX25Config* conf) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do{ + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + memcpy(mbox->data, (void*)conf, sizeof(TX25Config)); + mbox->cmd.length = sizeof(TX25Config); + mbox->cmd.command = X25_HDLC_SET_CONFIG; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_SET_CONFIGURATION, 0)); + + return err; +} + +static int set_hdlc_level (sdla_t* card) +{ + + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do{ + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = SET_PROTOCOL_LEVEL; + mbox->cmd.length = 1; + mbox->data[0] = HDLC_LEVEL; //| DO_HDLC_LEVEL_ERROR_CHECKING; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, SET_PROTOCOL_LEVEL, 0)); + + return err; +} + + + +/*==================================================================== + * Get communications error statistics. + *====================================================================*/ + +static int x25_get_err_stats (sdla_t* card) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_HDLC_READ_COMM_ERR; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_HDLC_READ_COMM_ERR, 0)); + + if (!err) + { + THdlcCommErr* stats = (void*)mbox->data; + + card->wandev.stats.rx_over_errors = stats->rxOverrun; + card->wandev.stats.rx_crc_errors = stats->rxBadCrc; + card->wandev.stats.rx_missed_errors = stats->rxAborted; + card->wandev.stats.tx_aborted_errors = stats->txAborted; + } + return err; +} + +/*==================================================================== + * Get protocol statistics. + *===================================================================*/ + +static int x25_get_stats (sdla_t* card) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_READ_STATISTICS; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_READ_STATISTICS, 0)) ; + + if (!err) + { + TX25Stats* stats = (void*)mbox->data; + + card->wandev.stats.rx_packets = stats->rxData; + card->wandev.stats.tx_packets = stats->txData; + } + return err; +} + +/*==================================================================== + * Close HDLC link. + *===================================================================*/ + +static int x25_close_hdlc (sdla_t* card) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_HDLC_LINK_CLOSE; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_HDLC_LINK_CLOSE, 0)); + + return err; +} + + +/*==================================================================== + * Open HDLC link. + *===================================================================*/ + +static int x25_open_hdlc (sdla_t* card) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_HDLC_LINK_OPEN; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_HDLC_LINK_OPEN, 0)); + + return err; +} + +/*===================================================================== + * Setup HDLC link. + *====================================================================*/ +static int x25_setup_hdlc (sdla_t* card) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_HDLC_LINK_SETUP; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_HDLC_LINK_SETUP, 0)); + + return err; +} + +/*==================================================================== + * Set (raise/drop) DTR. + *===================================================================*/ + +static int x25_set_dtr (sdla_t* card, int dtr) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->data[0] = 0; + mbox->data[2] = 0; + mbox->data[1] = dtr ? 0x02 : 0x01; + mbox->cmd.length = 3; + mbox->cmd.command = X25_SET_GLOBAL_VARS; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_SET_GLOBAL_VARS, 0)); + + return err; +} + +/*==================================================================== + * Set interrupt mode. + *===================================================================*/ + +static int x25_set_intr_mode (sdla_t* card, int mode) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->data[0] = mode; + if (card->hw.fwid == SFID_X25_508){ + mbox->data[1] = card->hw.irq; + mbox->data[2] = 2; + mbox->cmd.length = 3; + }else { + mbox->cmd.length = 1; + } + mbox->cmd.command = X25_SET_INTERRUPT_MODE; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_SET_INTERRUPT_MODE, 0)); + + return err; +} + +/*==================================================================== + * Read X.25 channel configuration. + *===================================================================*/ + +static int x25_get_chan_conf (sdla_t* card, x25_channel_t* chan) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int lcn = chan->common.lcn; + int err; + + do{ + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.lcn = lcn; + mbox->cmd.command = X25_READ_CHANNEL_CONFIG; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_READ_CHANNEL_CONFIG, lcn)); + + if (!err) + { + TX25Status* status = card->flags; + + /* calculate an offset into the array of status bytes */ + if (card->u.x.hi_svc <= X25_MAX_CHAN){ + + chan->ch_idx = lcn - 1; + + }else{ + int offset; + + /* FIX: Apr 14 2000 : Nenad Corbic + * The data field was being compared to 0x1F using + * '&&' instead of '&'. + * This caused X25API to fail for LCNs greater than 255. + */ + switch (mbox->data[0] & 0x1F) + { + case 0x01: + offset = status->pvc_map; break; + case 0x03: + offset = status->icc_map; break; + case 0x07: + offset = status->twc_map; break; + case 0x0B: + offset = status->ogc_map; break; + default: + offset = 0; + } + chan->ch_idx = lcn - 1 - offset; + } + + /* get actual transmit packet size on this channel */ + switch(mbox->data[1] & 0x38) + { + case 0x00: + chan->tx_pkt_size = 16; + break; + case 0x08: + chan->tx_pkt_size = 32; + break; + case 0x10: + chan->tx_pkt_size = 64; + break; + case 0x18: + chan->tx_pkt_size = 128; + break; + case 0x20: + chan->tx_pkt_size = 256; + break; + case 0x28: + chan->tx_pkt_size = 512; + break; + case 0x30: + chan->tx_pkt_size = 1024; + break; + } + if (card->u.x.logging) + printk(KERN_INFO "%s: X.25 packet size on LCN %d is %d.\n", + card->devname, lcn, chan->tx_pkt_size); + } + return err; +} + +/*==================================================================== + * Place X.25 call. + *====================================================================*/ + +static int x25_place_call (sdla_t* card, x25_channel_t* chan) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + char str[64]; + + + if (chan->protocol == htons(ETH_P_IP)){ + sprintf(str, "-d%s -uCC", chan->addr); + + }else if (chan->protocol == htons(ETH_P_IPX)){ + sprintf(str, "-d%s -u800000008137", chan->addr); + + } + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + strcpy(mbox->data, str); + mbox->cmd.length = strlen(str); + mbox->cmd.command = X25_PLACE_CALL; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_PLACE_CALL, 0)); + + if (!err){ + bind_lcn_to_dev (card, chan->dev, mbox->cmd.lcn); + } + return err; +} + +/*==================================================================== + * Accept X.25 call. + *====================================================================*/ + +static int x25_accept_call (sdla_t* card, int lcn, int qdm) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.lcn = lcn; + mbox->cmd.qdm = qdm; + mbox->cmd.command = X25_ACCEPT_CALL; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_ACCEPT_CALL, lcn)); + + return err; +} + +/*==================================================================== + * Clear X.25 call. + *====================================================================*/ + +static int x25_clear_call (sdla_t* card, int lcn, int cause, int diagn) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.lcn = lcn; + mbox->cmd.cause = cause; + mbox->cmd.diagn = diagn; + mbox->cmd.command = X25_CLEAR_CALL; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, X25_CLEAR_CALL, lcn)); + + return err; +} + +/*==================================================================== + * Send X.25 data packet. + *====================================================================*/ + +static int x25_send (sdla_t* card, int lcn, int qdm, int len, void* buf) +{ + TX25Mbox* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + int err; + unsigned char cmd; + + if (card->u.x.LAPB_hdlc) + cmd = X25_HDLC_WRITE; + else + cmd = X25_WRITE; + + do + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + memcpy(mbox->data, buf, len); + mbox->cmd.length = len; + mbox->cmd.lcn = lcn; + + if (card->u.x.LAPB_hdlc){ + mbox->cmd.pf = qdm; + }else{ + mbox->cmd.qdm = qdm; + } + + mbox->cmd.command = cmd; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && x25_error(card, err, cmd , lcn)); + + + /* If buffers are busy the return code for LAPB HDLC is + * 1. The above functions are looking for return code + * of X25RES_NOT_READY if busy. */ + + if (card->u.x.LAPB_hdlc && err == 1){ + err = X25RES_NOT_READY; + } + + return err; +} + +/*==================================================================== + * Fetch X.25 asynchronous events. + *===================================================================*/ + +static int x25_fetch_events (sdla_t* card) +{ + TX25Status* status = card->flags; + TX25Mbox* mbox = card->mbox; + int err = 0; + + if (status->gflags & 0x20) + { + memset(&mbox->cmd, 0, sizeof(TX25Cmd)); + mbox->cmd.command = X25_IS_DATA_AVAILABLE; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err) x25_error(card, err, X25_IS_DATA_AVAILABLE, 0); + } + return err; +} + +/*==================================================================== + * X.25 asynchronous event/error handler. + * This routine is called each time interface command returns + * non-zero return code to handle X.25 asynchronous events and + * common errors. Return non-zero to repeat command or zero to + * cancel it. + * + * Notes: + * 1. This function may be called recursively, as handling some of the + * asynchronous events (e.g. call request) requires execution of the + * interface command(s) that, in turn, may also return asynchronous + * events. To avoid re-entrancy problems we copy mailbox to dynamically + * allocated memory before processing events. + *====================================================================*/ + +static int x25_error (sdla_t* card, int err, int cmd, int lcn) +{ + int retry = 1; + unsigned dlen = ((TX25Mbox*)card->mbox)->cmd.length; + TX25Mbox* mb; + + mb = kmalloc(sizeof(TX25Mbox) + dlen, GFP_ATOMIC); + if (mb == NULL) + { + printk(KERN_ERR "%s: x25_error() out of memory!\n", + card->devname); + return 0; + } + memcpy(mb, card->mbox, sizeof(TX25Mbox) + dlen); + switch (err){ + + case X25RES_ASYNC_PACKET: /* X.25 asynchronous packet was received */ + + mb->data[dlen] = '\0'; + + switch (mb->cmd.pktType & 0x7F){ + + case ASE_CALL_RQST: /* incoming call */ + retry = incoming_call(card, cmd, lcn, mb); + break; + + case ASE_CALL_ACCEPTED: /* connected */ + retry = call_accepted(card, cmd, lcn, mb); + break; + + case ASE_CLEAR_RQST: /* call clear request */ + retry = call_cleared(card, cmd, lcn, mb); + break; + + case ASE_RESET_RQST: /* reset request */ + printk(KERN_INFO "%s: X.25 reset request on LCN %d! " + "Cause:0x%02X Diagn:0x%02X\n", + card->devname, mb->cmd.lcn, mb->cmd.cause, + mb->cmd.diagn); + api_oob_event (card,mb); + break; + + case ASE_RESTART_RQST: /* restart request */ + retry = restart_event(card, cmd, lcn, mb); + break; + + case ASE_CLEAR_CONFRM: + if (clear_confirm_event (card,mb)) + break; + + /* I use the goto statement here so if + * somebody inserts code between the + * case and default, we will not have + * ghost problems */ + + goto dflt_1; + + default: +dflt_1: + printk(KERN_INFO "%s: X.25 event 0x%02X on LCN %d! " + "Cause:0x%02X Diagn:0x%02X\n", + card->devname, mb->cmd.pktType, + mb->cmd.lcn, mb->cmd.cause, mb->cmd.diagn); + } + break; + + case X25RES_PROTO_VIOLATION: /* X.25 protocol violation indication */ + + /* Bug Fix: Mar 14 2000 + * The Protocol violation error conditions were + * not handled previously */ + + switch (mb->cmd.pktType & 0x7F){ + + case PVE_CLEAR_RQST: /* Clear request */ + retry = call_cleared(card, cmd, lcn, mb); + break; + + case PVE_RESET_RQST: /* Reset request */ + printk(KERN_INFO "%s: X.25 reset request on LCN %d! " + "Cause:0x%02X Diagn:0x%02X\n", + card->devname, mb->cmd.lcn, mb->cmd.cause, + mb->cmd.diagn); + api_oob_event (card,mb); + break; + + case PVE_RESTART_RQST: /* Restart request */ + retry = restart_event(card, cmd, lcn, mb); + break; + + default : + printk(KERN_INFO + "%s: X.25 protocol violation on LCN %d! " + "Packet:0x%02X Cause:0x%02X Diagn:0x%02X\n", + card->devname, mb->cmd.lcn, + mb->cmd.pktType & 0x7F, mb->cmd.cause, mb->cmd.diagn); + api_oob_event(card,mb); + } + break; + + case 0x42: /* X.25 timeout */ + retry = timeout_event(card, cmd, lcn, mb); + break; + + case 0x43: /* X.25 retry limit exceeded */ + printk(KERN_INFO + "%s: exceeded X.25 retry limit on LCN %d! " + "Packet:0x%02X Diagn:0x%02X\n", card->devname, + mb->cmd.lcn, mb->cmd.pktType, mb->cmd.diagn) + ; + break; + + case 0x08: /* modem failure */ +#ifndef MODEM_NOT_LOG + printk(KERN_INFO "%s: modem failure!\n", card->devname); +#endif /* MODEM_NOT_LOG */ + api_oob_event(card,mb); + break; + + case 0x09: /* N2 retry limit */ + printk(KERN_INFO "%s: exceeded HDLC retry limit!\n", + card->devname); + api_oob_event(card,mb); + break; + + case 0x06: /* unnumbered frame was received while in ABM */ + printk(KERN_INFO "%s: received Unnumbered frame 0x%02X!\n", + card->devname, mb->data[0]); + api_oob_event(card,mb); + break; + + case CMD_TIMEOUT: + printk(KERN_ERR "%s: command 0x%02X timed out!\n", + card->devname, cmd) + ; + retry = 0; /* abort command */ + break; + + case X25RES_NOT_READY: + retry = 1; + break; + + case 0x01: + if (card->u.x.LAPB_hdlc) + break; + + if (mb->cmd.command == 0x16) + break; + /* I use the goto statement here so if + * somebody inserts code between the + * case and default, we will not have + * ghost problems */ + goto dflt_2; + + default: +dflt_2: + printk(KERN_INFO "%s: command 0x%02X returned 0x%02X! Lcn %i\n", + card->devname, cmd, err, mb->cmd.lcn) + ; + retry = 0; /* abort command */ + } + kfree(mb); + return retry; +} + +/*==================================================================== + * X.25 Asynchronous Event Handlers + * These functions are called by the x25_error() and should return 0, if + * the command resulting in the asynchronous event must be aborted. + *====================================================================*/ + + + +/*==================================================================== + *Handle X.25 incoming call request. + * RFC 1356 establishes the following rules: + * 1. The first octet in the Call User Data (CUD) field of the call + * request packet contains NLPID identifying protocol encapsulation + * 2. Calls MUST NOT be accepted unless router supports requested + * protocol encapsulation. + * 3. A diagnostic code 249 defined by ISO/IEC 8208 may be used + * when clearing a call because protocol encapsulation is not + * supported. + * 4. If an incoming call is received while a call request is + * pending (i.e. call collision has occurred), the incoming call + * shall be rejected and call request shall be retried. + *====================================================================*/ + +static int incoming_call (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) +{ + struct wan_device* wandev = &card->wandev; + int new_lcn = mb->cmd.lcn; + struct net_device* dev = get_dev_by_lcn(wandev, new_lcn); + x25_channel_t* chan = NULL; + int accept = 0; /* set to '1' if o.k. to accept call */ + unsigned int user_data; + x25_call_info_t* info; + + /* Make sure there is no call collision */ + if (dev != NULL) + { + printk(KERN_INFO + "%s: X.25 incoming call collision on LCN %d!\n", + card->devname, new_lcn); + + x25_clear_call(card, new_lcn, 0, 0); + return 1; + } + + /* Make sure D bit is not set in call request */ +//FIXME: THIS IS NOT TURE !!!! TAKE IT OUT +// if (mb->cmd.qdm & 0x02) +// { +// printk(KERN_INFO +// "%s: X.25 incoming call on LCN %d with D-bit set!\n", +// card->devname, new_lcn); +// +// x25_clear_call(card, new_lcn, 0, 0); +// return 1; +// } + + /* Parse call request data */ + info = kmalloc(sizeof(x25_call_info_t), GFP_ATOMIC); + if (info == NULL) + { + printk(KERN_ERR + "%s: not enough memory to parse X.25 incoming call " + "on LCN %d!\n", card->devname, new_lcn); + x25_clear_call(card, new_lcn, 0, 0); + return 1; + } + + parse_call_info(mb->data, info); + + if (card->u.x.logging) + printk(KERN_INFO "\n%s: X.25 incoming call on LCN %d!\n", + card->devname, new_lcn); + + /* Conver the first two ASCII characters into an + * interger. Used to check the incoming protocol + */ + user_data = hex_to_uint(info->user,2); + + /* Find available channel */ + for (dev = wandev->dev; dev; dev = *((struct net_device **)dev->priv)) { + chan = dev->priv; + + if (chan->common.usedby == API) + continue; + + if (!chan->common.svc || (chan->common.state != WAN_DISCONNECTED)) + continue; + + if (user_data == NLPID_IP && chan->protocol != htons(ETH_P_IP)){ + printk(KERN_INFO "IP packet but configured for IPX : %x, %x\n", + htons(chan->protocol), info->user[0]); + continue; + } + + if (user_data == NLPID_SNAP && chan->protocol != htons(ETH_P_IPX)){ + printk(KERN_INFO "IPX packet but configured for IP: %x\n", + htons(chan->protocol)); + continue; + } + if (strcmp(info->src, chan->addr) == 0) + break; + + /* If just an '@' is specified, accept all incoming calls */ + if (strcmp(chan->addr, "") == 0) + break; + } + + if (dev == NULL){ + + /* If the call is not for any WANPIPE interfaces + * check to see if there is an API listening queue + * waiting for data. If there is send the packet + * up the stack. + */ + if (card->sk != NULL && card->func != NULL){ + if (api_incoming_call(card,mb,new_lcn)){ + x25_clear_call(card, new_lcn, 0, 0); + } + accept = 0; + }else{ + printk(KERN_INFO "%s: no channels available!\n", + card->devname); + + x25_clear_call(card, new_lcn, 0, 0); + } + + }else if (info->nuser == 0){ + + printk(KERN_INFO + "%s: no user data in incoming call on LCN %d!\n", + card->devname, new_lcn) + ; + x25_clear_call(card, new_lcn, 0, 0); + + }else switch (info->user[0]){ + + case 0: /* multiplexed */ + chan->protocol = htons(0); + accept = 1; + break; + + case NLPID_IP: /* IP datagrams */ + accept = 1; + break; + + case NLPID_SNAP: /* IPX datagrams */ + accept = 1; + break; + + default: + printk(KERN_INFO + "%s: unsupported NLPID 0x%02X in incoming call " + "on LCN %d!\n", card->devname, info->user[0], new_lcn); + x25_clear_call(card, new_lcn, 0, 249); + } + + if (accept && (x25_accept_call(card, new_lcn, 0) == CMD_OK)){ + + bind_lcn_to_dev (card, chan->dev, new_lcn); + + if (x25_get_chan_conf(card, chan) == CMD_OK) + set_chan_state(dev, WAN_CONNECTED); + else + x25_clear_call(card, new_lcn, 0, 0); + } + kfree(info); + return 1; +} + +/*==================================================================== + * Handle accepted call. + *====================================================================*/ + +static int call_accepted (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) +{ + unsigned new_lcn = mb->cmd.lcn; + struct net_device* dev = find_channel(card, new_lcn); + x25_channel_t* chan; + + if (dev == NULL){ + printk(KERN_INFO + "%s: clearing orphaned connection on LCN %d!\n", + card->devname, new_lcn); + x25_clear_call(card, new_lcn, 0, 0); + return 1; + } + + if (card->u.x.logging) + printk(KERN_INFO "%s: X.25 call accepted on Dev %s and LCN %d!\n", + card->devname, dev->name, new_lcn); + + /* Get channel configuration and notify router */ + chan = dev->priv; + if (x25_get_chan_conf(card, chan) != CMD_OK) + { + x25_clear_call(card, new_lcn, 0, 0); + return 1; + } + + set_chan_state(dev, WAN_CONNECTED); + + if (chan->common.usedby == API){ + send_delayed_cmd_result(card,dev,mb); + bind_lcn_to_dev (card, dev, new_lcn); + } + + return 1; +} + +/*==================================================================== + * Handle cleared call. + *====================================================================*/ + +static int call_cleared (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) +{ + unsigned new_lcn = mb->cmd.lcn; + struct net_device* dev = find_channel(card, new_lcn); + x25_channel_t *chan; + unsigned char old_state; + + if (card->u.x.logging){ + printk(KERN_INFO "%s: X.25 clear request on LCN %d! Cause:0x%02X " + "Diagn:0x%02X\n", + card->devname, new_lcn, mb->cmd.cause, mb->cmd.diagn); + } + + if (dev == NULL){ + printk(KERN_INFO "%s: X.25 clear request : No device for clear\n", + card->devname); + return 1; + } + + chan=dev->priv; + + old_state = chan->common.state; + + set_chan_state(dev, WAN_DISCONNECTED); + + if (chan->common.usedby == API){ + + switch (old_state){ + + case WAN_CONNECTING: + send_delayed_cmd_result(card,dev,mb); + break; + case WAN_CONNECTED: + send_oob_msg(card,dev,mb); + break; + } + } + + return ((cmd == X25_WRITE) && (lcn == new_lcn)) ? 0 : 1; +} + +/*==================================================================== + * Handle X.25 restart event. + *====================================================================*/ + +static int restart_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) +{ + struct wan_device* wandev = &card->wandev; + struct net_device* dev; + x25_channel_t *chan; + unsigned char old_state; + + printk(KERN_INFO + "%s: X.25 restart request! Cause:0x%02X Diagn:0x%02X\n", + card->devname, mb->cmd.cause, mb->cmd.diagn); + + /* down all logical channels */ + for (dev = wandev->dev; dev; dev = *((struct net_device **)dev->priv)) { + chan=dev->priv; + old_state = chan->common.state; + + set_chan_state(dev, WAN_DISCONNECTED); + + if (chan->common.usedby == API){ + switch (old_state){ + + case WAN_CONNECTING: + send_delayed_cmd_result(card,dev,mb); + break; + case WAN_CONNECTED: + send_oob_msg(card,dev,mb); + break; + } + } + } + return (cmd == X25_WRITE) ? 0 : 1; +} + +/*==================================================================== + * Handle timeout event. + *====================================================================*/ + +static int timeout_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) +{ + unsigned new_lcn = mb->cmd.lcn; + + if (mb->cmd.pktType == 0x05) /* call request time out */ + { + struct net_device* dev = find_channel(card,new_lcn); + + printk(KERN_INFO "%s: X.25 call timed timeout on LCN %d!\n", + card->devname, new_lcn); + + if (dev){ + x25_channel_t *chan = dev->priv; + set_chan_state(dev, WAN_DISCONNECTED); + + if (chan->common.usedby == API){ + send_delayed_cmd_result(card,dev,card->mbox); + } + } + }else{ + printk(KERN_INFO "%s: X.25 packet 0x%02X timeout on LCN %d!\n", + card->devname, mb->cmd.pktType, new_lcn); + } + return 1; +} + +/* + * Miscellaneous + */ + +/*==================================================================== + * Establish physical connection. + * o open HDLC and raise DTR + * + * Return: 0 connection established + * 1 connection is in progress + * <0 error + *===================================================================*/ + +static int connect (sdla_t* card) +{ + TX25Status* status = card->flags; + + if (x25_open_hdlc(card) || x25_setup_hdlc(card)) + return -EIO; + + wanpipe_set_state(card, WAN_CONNECTING); + + x25_set_intr_mode(card, INTR_ON_TIMER); + status->imask &= ~INTR_ON_TIMER; + + return 1; +} + +/* + * Tear down physical connection. + * o close HDLC link + * o drop DTR + * + * Return: 0 + * <0 error + */ + +static int disconnect (sdla_t* card) +{ + wanpipe_set_state(card, WAN_DISCONNECTED); + x25_set_intr_mode(card, INTR_ON_TIMER); /* disable all interrupt except timer */ + x25_close_hdlc(card); /* close HDLC link */ + x25_set_dtr(card, 0); /* drop DTR */ + return 0; +} + +/* + * Find network device by its channel number. + */ + +static struct net_device* get_dev_by_lcn(struct wan_device* wandev, + unsigned lcn) +{ + struct net_device* dev; + + for (dev = wandev->dev; dev; dev = *((struct net_device **)dev->priv)) + if (((x25_channel_t*)dev->priv)->common.lcn == lcn) + break; + return dev; +} + +/* + * Initiate connection on the logical channel. + * o for PVC we just get channel configuration + * o for SVCs place an X.25 call + * + * Return: 0 connected + * >0 connection in progress + * <0 failure + */ + +static int chan_connect(struct net_device* dev) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + + if (chan->common.svc && chan->common.usedby == WANPIPE){ + if (!chan->addr[0]){ + printk(KERN_INFO "%s: No Destination Address\n", + card->devname); + return -EINVAL; /* no destination address */ + } + printk(KERN_INFO "%s: placing X.25 call to %s ...\n", + card->devname, chan->addr); + + if (x25_place_call(card, chan) != CMD_OK) + return -EIO; + + set_chan_state(dev, WAN_CONNECTING); + return 1; + }else{ + if (x25_get_chan_conf(card, chan) != CMD_OK) + return -EIO; + + set_chan_state(dev, WAN_CONNECTED); + } + return 0; +} + +/* + * Disconnect logical channel. + * o if SVC then clear X.25 call + */ + +static int chan_disc(struct net_device* dev) +{ + x25_channel_t* chan = dev->priv; + + if (chan->common.svc){ + x25_clear_call(chan->card, chan->common.lcn, 0, 0); + + /* For API we disconnect on clear + * confirmation. + */ + if (chan->common.usedby == API) + return 0; + } + + set_chan_state(dev, WAN_DISCONNECTED); + + return 0; +} + +/* + * Set logical channel state. + */ + +static void set_chan_state(struct net_device* dev, int state) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + unsigned long flags; + + save_flags(flags); + cli(); + if (chan->common.state != state) + { + switch (state) + { + case WAN_CONNECTED: + if (card->u.x.logging){ + printk (KERN_INFO + "%s: interface %s connected, lcn %i !\n", + card->devname, dev->name,chan->common.lcn); + } + *(unsigned short*)dev->dev_addr = htons(chan->common.lcn); + chan->i_timeout_sofar = jiffies; + + /* LAPB is PVC Based */ + if (card->u.x.LAPB_hdlc) + chan->common.svc=0; + break; + + case WAN_CONNECTING: + if (card->u.x.logging){ + printk (KERN_INFO + "%s: interface %s connecting, lcn %i ...\n", + card->devname, dev->name, chan->common.lcn); + } + break; + + case WAN_DISCONNECTED: + if (card->u.x.logging){ + printk (KERN_INFO + "%s: interface %s disconnected, lcn %i !\n", + card->devname, dev->name,chan->common.lcn); + } + atomic_set(&chan->common.disconnect,0); + + if (chan->common.svc) { + *(unsigned short*)dev->dev_addr = 0; + card->u.x.svc_to_dev_map[(chan->common.lcn%X25_MAX_CHAN)]=NULL; + chan->common.lcn = 0; + } + + if (chan->transmit_length){ + chan->transmit_length=0; + atomic_set(&chan->common.driver_busy,0); + chan->tx_offset=0; + if (netif_queue_stopped(dev)){ + netif_wake_queue(dev); + } + } + atomic_set(&chan->common.command,0); + break; + + case WAN_DISCONNECTING: + if (card->u.x.logging){ + printk (KERN_INFO + "\n%s: interface %s disconnecting, lcn %i ...\n", + card->devname, dev->name,chan->common.lcn); + } + atomic_set(&chan->common.disconnect,0); + break; + } + chan->common.state = state; + } + chan->state_tick = jiffies; + restore_flags(flags); +} + +/* + * Send packet on a logical channel. + * When this function is called, tx_skb field of the channel data + * space points to the transmit socket buffer. When transmission + * is complete, release socket buffer and reset 'tbusy' flag. + * + * Return: 0 - transmission complete + * 1 - busy + * + * Notes: + * 1. If packet length is greater than MTU for this channel, we'll fragment + * the packet into 'complete sequence' using M-bit. + * 2. When transmission is complete, an event notification should be issued + * to the router. + */ + +static int chan_send(struct net_device* dev, void* buff, unsigned data_len, + unsigned char tx_intr) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + TX25Status* status = card->flags; + unsigned len=0, qdm=0, res=0, orig_len = 0; + void *data; + + /* Check to see if channel is ready */ + if ((!(status->cflags[chan->ch_idx] & 0x40) && !card->u.x.LAPB_hdlc) || + !(*card->u.x.hdlc_buf_status & 0x40)){ + + if (!tx_intr){ + setup_for_delayed_transmit (dev, buff, data_len); + return 0; + }else{ + /* By returning 0 to tx_intr the packet will be dropped */ + ++card->wandev.stats.tx_dropped; + ++chan->ifstats.tx_dropped; + printk(KERN_INFO "%s: ERROR, Tx intr could not send, dropping %s:\n", + card->devname,dev->name); + ++chan->if_send_stat.if_send_bfr_not_passed_to_adptr; + return 0; + } + } + + if (chan->common.usedby == API){ + /* Remove the API Header */ + x25api_hdr_t *api_data = (x25api_hdr_t *)buff; + + /* Set the qdm bits from the packet header + * User has the option to set the qdm bits + */ + qdm = api_data->qdm; + + orig_len = len = data_len - sizeof(x25api_hdr_t); + data = (unsigned char*)buff + sizeof(x25api_hdr_t); + }else{ + data = buff; + orig_len = len = data_len; + } + + if (tx_intr){ + /* We are in tx_intr, minus the tx_offset from + * the total length. The tx_offset part of the + * data has already been sent. Also, move the + * data pointer to proper offset location. + */ + len -= chan->tx_offset; + data = (unsigned char*)data + chan->tx_offset; + } + + /* Check if the packet length is greater than MTU + * If YES: Cut the len to MTU and set the M bit + */ + if (len > chan->tx_pkt_size && !card->u.x.LAPB_hdlc){ + len = chan->tx_pkt_size; + qdm |= M_BIT; + } + + + /* Pass only first three bits of the qdm byte to the send + * routine. In case user sets any other bit which might + * cause errors. + */ + + switch(x25_send(card, chan->common.lcn, (qdm&0x07), len, data)){ + case 0x00: /* success */ + chan->i_timeout_sofar = jiffies; + + dev->trans_start=jiffies; + + if ((qdm & M_BIT) && !card->u.x.LAPB_hdlc){ + if (!tx_intr){ + /* The M bit was set, which means that part of the + * packet has been sent. Copy the packet into a buffer + * and set the offset to len, so on next tx_inter + * the packet will be sent using the below offset. + */ + chan->tx_offset += len; + + ++chan->ifstats.tx_packets; + chan->ifstats.tx_bytes += len; + + if (chan->tx_offset < orig_len){ + setup_for_delayed_transmit (dev, buff, data_len); + } + res=0; + }else{ + /* We are already in tx_inter, thus data is already + * in the buffer. Update the offset and wait for + * next tx_intr. We add on to the offset, since data can + * be X number of times larger than max data size. + */ + ++chan->ifstats.tx_packets; + chan->ifstats.tx_bytes += len; + + ++chan->if_send_stat.if_send_bfr_passed_to_adptr; + chan->tx_offset += len; + + /* The user can set the qdm bit as well. + * If the entire packet was sent and qdm is still + * set, than it's the user who has set the M bit. In that, + * case indicate that the packet was send by returning + * 0 and wait for a new packet. Otherwise, wait for next + * tx interrupt to send the rest of the packet */ + + if (chan->tx_offset < orig_len){ + res=1; + }else{ + res=0; + } + } + }else{ + ++chan->ifstats.tx_packets; + chan->ifstats.tx_bytes += len; + ++chan->if_send_stat.if_send_bfr_passed_to_adptr; + res=0; + } + break; + + case 0x33: /* Tx busy */ + if (tx_intr){ + printk(KERN_INFO "%s: Tx_intr: Big Error dropping packet %s\n", + card->devname,dev->name); + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + ++chan->if_send_stat.if_send_bfr_not_passed_to_adptr; + res=0; + }else{ + DBG_PRINTK(KERN_INFO + "%s: Send: Big Error should have tx: storring %s\n", + card->devname,dev->name); + setup_for_delayed_transmit (dev, buff, data_len); + res=1; + } + break; + + default: /* failure */ + ++chan->ifstats.tx_errors; + if (tx_intr){ + printk(KERN_INFO "%s: Tx_intr: Failure to send, dropping %s\n", + card->devname,dev->name); + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + ++chan->if_send_stat.if_send_bfr_not_passed_to_adptr; + res=0; + }else{ + DBG_PRINTK(KERN_INFO "%s: Send: Failure to send !!!, storing %s\n", + card->devname,dev->name); + setup_for_delayed_transmit (dev, buff, data_len); + res=1; + } + break; + } + return res; +} + + +/* + * Parse X.25 call request data and fill x25_call_info_t structure. + */ + +static void parse_call_info (unsigned char* str, x25_call_info_t* info) +{ + memset(info, 0, sizeof(x25_call_info_t)); + for (; *str; ++str) + { + int i; + unsigned char ch; + + if (*str == '-') switch (str[1]) { + + /* Take minus 2 off the maximum size so that + * last byte is 0. This way we can use string + * manipulaton functions on call information. + */ + + case 'd': /* destination address */ + for (i = 0; i < (MAX_X25_ADDR_SIZE-2); ++i){ + ch = str[2+i]; + if (isspace(ch)) break; + info->dest[i] = ch; + } + break; + + case 's': /* source address */ + for (i = 0; i < (MAX_X25_ADDR_SIZE-2); ++i){ + ch = str[2+i]; + if (isspace(ch)) break; + info->src[i] = ch; + } + break; + + case 'u': /* user data */ + for (i = 0; i < (MAX_X25_DATA_SIZE-2); ++i){ + ch = str[2+i]; + if (isspace(ch)) break; + info->user[i] = ch; + } + info->nuser = i; + break; + + case 'f': /* facilities */ + for (i = 0; i < (MAX_X25_FACL_SIZE-2); ++i){ + ch = str[2+i]; + if (isspace(ch)) break; + info->facil[i] = ch; + } + info->nfacil = i; + break; + } + } +} + +/* + * Convert line speed in bps to a number used by S502 code. + */ + +static unsigned char bps_to_speed_code (unsigned long bps) +{ + unsigned char number; + + if (bps <= 1200) number = 0x01; + else if (bps <= 2400) number = 0x02; + else if (bps <= 4800) number = 0x03; + else if (bps <= 9600) number = 0x04; + else if (bps <= 19200) number = 0x05; + else if (bps <= 38400) number = 0x06; + else if (bps <= 45000) number = 0x07; + else if (bps <= 56000) number = 0x08; + else if (bps <= 64000) number = 0x09; + else if (bps <= 74000) number = 0x0A; + else if (bps <= 112000) number = 0x0B; + else if (bps <= 128000) number = 0x0C; + else number = 0x0D; + + return number; +} + +/* + * Convert decimal string to unsigned integer. + * If len != 0 then only 'len' characters of the string are converted. + */ + +static unsigned int dec_to_uint (unsigned char* str, int len) +{ + unsigned val; + + if (!len) + len = strlen(str); + + for (val = 0; len && isdigit(*str); ++str, --len) + val = (val * 10) + (*str - (unsigned)'0'); + + return val; +} + +/* + * Convert hex string to unsigned integer. + * If len != 0 then only 'len' characters of the string are conferted. + */ + +static unsigned int hex_to_uint (unsigned char* str, int len) +{ + unsigned val, ch; + + if (!len) + len = strlen(str); + + for (val = 0; len; ++str, --len) + { + ch = *str; + if (isdigit(ch)) + val = (val << 4) + (ch - (unsigned)'0'); + else if (isxdigit(ch)) + val = (val << 4) + ((ch & 0xDF) - (unsigned)'A' + 10); + else break; + } + return val; +} + + +static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto) +{ + int i; + + if( proto == ETH_P_IPX) { + /* It's an IPX packet */ + if(!enable_IPX) { + /* Return 1 so we don't pass it up the stack. */ + return 1; + } + } else { + /* It's not IPX so pass it up the stack.*/ + return 0; + } + + if( sendpacket[16] == 0x90 && + sendpacket[17] == 0x04) + { + /* It's IPXWAN */ + + if( sendpacket[2] == 0x02 && + sendpacket[34] == 0x00) + { + /* It's a timer request packet */ + printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname); + + /* Go through the routing options and answer no to every + * option except Unnumbered RIP/SAP + */ + for(i = 41; sendpacket[i] == 0x00; i += 5) + { + /* 0x02 is the option for Unnumbered RIP/SAP */ + if( sendpacket[i + 4] != 0x02) + { + sendpacket[i + 1] = 0; + } + } + + /* Skip over the extended Node ID option */ + if( sendpacket[i] == 0x04 ) + { + i += 8; + } + + /* We also want to turn off all header compression opt. */ + for(; sendpacket[i] == 0x80 ;) + { + sendpacket[i + 1] = 0; + i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4; + } + + /* Set the packet type to timer response */ + sendpacket[34] = 0x01; + + printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname); + } + else if( sendpacket[34] == 0x02 ) + { + /* This is an information request packet */ + printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname); + + /* Set the packet type to information response */ + sendpacket[34] = 0x03; + + /* Set the router name */ + sendpacket[51] = 'X'; + sendpacket[52] = 'T'; + sendpacket[53] = 'P'; + sendpacket[54] = 'I'; + sendpacket[55] = 'P'; + sendpacket[56] = 'E'; + sendpacket[57] = '-'; + sendpacket[58] = CVHexToAscii(network_number >> 28); + sendpacket[59] = CVHexToAscii((network_number & 0x0F000000)>> 24); + sendpacket[60] = CVHexToAscii((network_number & 0x00F00000)>> 20); + sendpacket[61] = CVHexToAscii((network_number & 0x000F0000)>> 16); + sendpacket[62] = CVHexToAscii((network_number & 0x0000F000)>> 12); + sendpacket[63] = CVHexToAscii((network_number & 0x00000F00)>> 8); + sendpacket[64] = CVHexToAscii((network_number & 0x000000F0)>> 4); + sendpacket[65] = CVHexToAscii(network_number & 0x0000000F); + for(i = 66; i < 99; i+= 1) + { + sendpacket[i] = 0; + } + + printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname); + } + else + { + printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname); + return 0; + } + + /* Set the WNodeID to our network address */ + sendpacket[35] = (unsigned char)(network_number >> 24); + sendpacket[36] = (unsigned char)((network_number & 0x00FF0000) >> 16); + sendpacket[37] = (unsigned char)((network_number & 0x0000FF00) >> 8); + sendpacket[38] = (unsigned char)(network_number & 0x000000FF); + + return 1; + } else { + /*If we get here it's an IPX-data packet, so it'll get passed up the stack. + */ + /* switch the network numbers */ + switch_net_numbers(sendpacket, network_number, 1); + return 0; + } +} + +/* + * If incoming is 0 (outgoing)- if the net numbers is ours make it 0 + * if incoming is 1 - if the net number is 0 make it ours + */ + +static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming) +{ + unsigned long pnetwork_number; + + pnetwork_number = (unsigned long)((sendpacket[6] << 24) + + (sendpacket[7] << 16) + (sendpacket[8] << 8) + + sendpacket[9]); + + + if (!incoming) { + /*If the destination network number is ours, make it 0 */ + if( pnetwork_number == network_number) { + sendpacket[6] = sendpacket[7] = sendpacket[8] = + sendpacket[9] = 0x00; + } + } else { + /* If the incoming network is 0, make it ours */ + if( pnetwork_number == 0) { + sendpacket[6] = (unsigned char)(network_number >> 24); + sendpacket[7] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[8] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[9] = (unsigned char)(network_number & + 0x000000FF); + } + } + + + pnetwork_number = (unsigned long)((sendpacket[18] << 24) + + (sendpacket[19] << 16) + (sendpacket[20] << 8) + + sendpacket[21]); + + + if( !incoming ) { + /* If the source network is ours, make it 0 */ + if( pnetwork_number == network_number) { + sendpacket[18] = sendpacket[19] = sendpacket[20] = + sendpacket[21] = 0x00; + } + } else { + /* If the source network is 0, make it ours */ + if( pnetwork_number == 0 ) { + sendpacket[18] = (unsigned char)(network_number >> 24); + sendpacket[19] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[20] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[21] = (unsigned char)(network_number & + 0x000000FF); + } + } +} /* switch_net_numbers */ + + + + +/********************* X25API SPECIFIC FUNCTIONS ****************/ + + +/*=============================================================== + * find_channel + * + * Manages the lcn to device map. It increases performance + * because it eliminates the need to search through the link + * list for a device which is bounded to a specific lcn. + * + *===============================================================*/ + + +struct net_device *find_channel(sdla_t *card, unsigned lcn) +{ + if (card->u.x.LAPB_hdlc){ + + return card->wandev.dev; + + }else{ + /* We don't know whether the incoming lcn + * is a PVC or an SVC channel. But we do know that + * the lcn cannot be for both the PVC and the SVC + * channel. + + * If the lcn number is greater or equal to 255, + * take the modulo 255 of that number. We only have + * 255 locations, thus higher numbers must be mapped + * to a number between 0 and 245. + + * We must separate pvc's and svc's since two don't + * have to be contiguous. Meaning pvc's can start + * from 1 to 10 and svc's can start from 256 to 266. + * But 256%255 is 1, i.e. CONFLICT. + */ + + + /* Highest LCN number must be less or equal to 4096 */ + if ((lcn <= MAX_LCN_NUM) && (lcn > 0)){ + + if (lcn < X25_MAX_CHAN){ + if (card->u.x.svc_to_dev_map[lcn]) + return card->u.x.svc_to_dev_map[lcn]; + + if (card->u.x.pvc_to_dev_map[lcn]) + return card->u.x.pvc_to_dev_map[lcn]; + + }else{ + int new_lcn = lcn%X25_MAX_CHAN; + if (card->u.x.svc_to_dev_map[new_lcn]) + return card->u.x.svc_to_dev_map[new_lcn]; + + if (card->u.x.pvc_to_dev_map[new_lcn]) + return card->u.x.pvc_to_dev_map[new_lcn]; + } + } + return NULL; + } +} + +void bind_lcn_to_dev(sdla_t *card, struct net_device *dev, unsigned lcn) +{ + x25_channel_t *chan = dev->priv; + + /* Modulo the lcn number by X25_MAX_CHAN (255) + * because the lcn number can be greater than 255 + * + * We need to split svc and pvc since they don't have + * to be contigous. + */ + + if (chan->common.svc){ + card->u.x.svc_to_dev_map[(lcn % X25_MAX_CHAN)] = dev; + }else{ + card->u.x.pvc_to_dev_map[(lcn % X25_MAX_CHAN)] = dev; + } + chan->common.lcn = lcn; +} + + + +/*=============================================================== + * x25api_bh + * + * + *==============================================================*/ + +static void x25api_bh(struct net_device* dev) +{ + x25_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + struct sk_buff *skb; + + if (atomic_read(&chan->bh_buff_used) == 0){ + printk(KERN_INFO "%s: BH Buffer Empty in BH\n", + card->devname); + clear_bit(0, &chan->tq_working); + return; + } + + while (atomic_read(&chan->bh_buff_used)){ + + /* If the sock is in the process of unlinking the + * driver from the socket, we must get out. + * This never happends but is a sanity check. */ + if (test_bit(0,&chan->common.common_critical)){ + clear_bit(0, &chan->tq_working); + return; + } + + /* If LAPB HDLC, do not drop packets if socket is + * not connected. Let the buffer fill up and + * turn off rx interrupt */ + if (card->u.x.LAPB_hdlc){ + if (chan->common.sk == NULL || chan->common.func == NULL){ + clear_bit(0, &chan->tq_working); + return; + } + } + + skb = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb; + + if (skb == NULL){ + printk(KERN_INFO "%s: BH Skb empty for read %i\n", + card->devname,chan->bh_read); + }else{ + + if (chan->common.sk == NULL || chan->common.func == NULL){ + printk(KERN_INFO "%s: BH: Socket disconnected, dropping\n", + card->devname); + dev_kfree_skb_any(skb); + x25api_bh_cleanup(dev); + ++chan->ifstats.rx_dropped; + ++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack; + continue; + } + + + if (chan->common.func(skb,dev,chan->common.sk) != 0){ + /* Sock full cannot send, queue us for another + * try + */ + printk(KERN_INFO "%s: BH: !!! Packet failed to send !!!!! \n", + card->devname); + atomic_set(&chan->common.receive_block,1); + return; + }else{ + x25api_bh_cleanup(dev); + ++chan->rx_intr_stat.rx_intr_bfr_passed_to_stack; + } + } + } + clear_bit(0, &chan->tq_working); + + return; +} + +/*=============================================================== + * x25api_bh_cleanup + * + * + *==============================================================*/ + +static int x25api_bh_cleanup(struct net_device *dev) +{ + x25_channel_t* chan = dev->priv; + sdla_t *card = chan->card; + TX25Status* status = card->flags; + + + ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL; + + if (chan->bh_read == MAX_BH_BUFF){ + chan->bh_read=0; + }else{ + ++chan->bh_read; + } + + /* If the Receive interrupt was off, it means + * that we filled up our circular buffer. Check + * that we have space in the buffer. If so + * turn the RX interrupt back on. + */ + if (!(status->imask & INTR_ON_RX_FRAME)){ + if (atomic_read(&chan->bh_buff_used) < (MAX_BH_BUFF+1)){ + printk(KERN_INFO "%s: BH: Turning on the interrupt\n", + card->devname); + status->imask |= INTR_ON_RX_FRAME; + } + } + + atomic_dec(&chan->bh_buff_used); + return 0; +} + + +/*=============================================================== + * bh_enqueue + * + * + *==============================================================*/ + +static int bh_enqueue(struct net_device *dev, struct sk_buff *skb) +{ + x25_channel_t* chan = dev->priv; + sdla_t *card = chan->card; + TX25Status* status = card->flags; + + if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){ + printk(KERN_INFO "%s: Bottom half buffer FULL\n", + card->devname); + return 1; + } + + ((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb; + + if (chan->bh_write == MAX_BH_BUFF){ + chan->bh_write=0; + }else{ + ++chan->bh_write; + } + + atomic_inc(&chan->bh_buff_used); + + if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){ + printk(KERN_INFO "%s: Buffer is now full, Turning off RX Intr\n", + card->devname); + status->imask &= ~INTR_ON_RX_FRAME; + } + + return 0; +} + + +/*=============================================================== + * timer_intr_cmd_exec + * + * Called by timer interrupt to execute a command + *===============================================================*/ + +static int timer_intr_cmd_exec (sdla_t* card) +{ + struct net_device *dev; + unsigned char more_to_exec=0; + volatile x25_channel_t *chan=NULL; + int i=0,bad_cmd=0,err=0; + + if (card->u.x.cmd_dev == NULL){ + card->u.x.cmd_dev = card->wandev.dev; + } + + dev = card->u.x.cmd_dev; + + for (;;){ + + chan = dev->priv; + + if (atomic_read(&chan->common.command)){ + + bad_cmd = check_bad_command(card,dev); + + if ((!chan->common.mbox || atomic_read(&chan->common.disconnect)) && + !bad_cmd){ + + /* Socket has died or exited, We must bring the + * channel down before anybody else tries to + * use it */ + err = channel_disconnect(card,dev); + }else{ + err = execute_delayed_cmd(card, dev, + (mbox_cmd_t*)chan->common.mbox, + bad_cmd); + } + + switch (err){ + + case RETURN_RESULT: + + /* Return the result to the socket without + * delay. NO_WAIT Command */ + atomic_set(&chan->common.command,0); + if (atomic_read(&card->u.x.command_busy)) + atomic_set(&card->u.x.command_busy,0); + + send_delayed_cmd_result(card,dev,card->mbox); + + more_to_exec=0; + break; + case DELAY_RESULT: + + /* Wait for the remote to respond, before + * sending the result up to the socket. + * WAIT command */ + if (atomic_read(&card->u.x.command_busy)) + atomic_set(&card->u.x.command_busy,0); + + atomic_set(&chan->common.command,0); + more_to_exec=0; + break; + default: + + /* If command could not be executed for + * some reason (i.e return code 0x33 busy) + * set the more_to_exec bit which will + * indicate that this command must be exectued + * again during next timer interrupt + */ + more_to_exec=1; + if (atomic_read(&card->u.x.command_busy) == 0) + atomic_set(&card->u.x.command_busy,1); + break; + } + + bad_cmd=0; + + /* If flags is set, there are no hdlc buffers, + * thus, wait for the next pass and try the + * same command again. Otherwise, start searching + * from next device on the next pass. + */ + if (!more_to_exec){ + dev = move_dev_to_next(card,dev); + } + break; + }else{ + /* This device has nothing to execute, + * go to next. + */ + if (atomic_read(&card->u.x.command_busy)) + atomic_set(&card->u.x.command_busy,0); + dev = move_dev_to_next(card,dev); + } + + if (++i == card->u.x.no_dev){ + if (!more_to_exec){ + DBG_PRINTK(KERN_INFO "%s: Nothing to execute in Timer\n", + card->devname); + if (atomic_read(&card->u.x.command_busy)){ + atomic_set(&card->u.x.command_busy,0); + } + } + break; + } + + } //End of FOR + + card->u.x.cmd_dev = dev; + + if (more_to_exec){ + /* If more commands are pending, do not turn off timer + * interrupt */ + return 1; + }else{ + /* No more commands, turn off timer interrupt */ + return 0; + } +} + +/*=============================================================== + * execute_delayed_cmd + * + * Execute an API command which was passed down from the + * sock. Sock is very limited in which commands it can + * execute. Wait and No Wait commands are supported. + * Place Call, Clear Call and Reset wait commands, where + * Accept Call is a no_wait command. + * + *===============================================================*/ + +static int execute_delayed_cmd(sdla_t* card, struct net_device *dev, + mbox_cmd_t *usr_cmd, char bad_cmd) +{ + TX25Mbox* mbox = card->mbox; + int err; + x25_channel_t *chan = dev->priv; + int delay=RETURN_RESULT; + + if (!(*card->u.x.hdlc_buf_status & 0x40) && !bad_cmd){ + return TRY_CMD_AGAIN; + } + + /* This way a command is guaranteed to be executed for + * a specific lcn, the network interface is bound to. */ + usr_cmd->cmd.lcn = chan->common.lcn; + + + /* If channel is pvc, instead of place call + * run x25_channel configuration. If running LAPB HDLC + * enable communications. + */ + if ((!chan->common.svc) && (usr_cmd->cmd.command == X25_PLACE_CALL)){ + + if (card->u.x.LAPB_hdlc){ + DBG_PRINTK(KERN_INFO "LAPB: Connecting\n"); + connect(card); + set_chan_state(dev,WAN_CONNECTING); + return DELAY_RESULT; + }else{ + DBG_PRINTK(KERN_INFO "%s: PVC is CONNECTING\n",card->devname); + if (x25_get_chan_conf(card, chan) == CMD_OK){ + set_chan_state(dev, WAN_CONNECTED); + }else{ + set_chan_state(dev, WAN_DISCONNECTED); + } + return RETURN_RESULT; + } + } + + /* Copy the socket mbox command onto the board */ + + memcpy(&mbox->cmd, &usr_cmd->cmd, sizeof(TX25Cmd)); + if (usr_cmd->cmd.length){ + memcpy(mbox->data, usr_cmd->data, usr_cmd->cmd.length); + } + + /* Check if command is bad. We need to copy the cmd into + * the buffer regardless since we return the, mbox to + * the user */ + if (bad_cmd){ + mbox->cmd.result=0x01; + return RETURN_RESULT; + } + + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK && err != X25RES_NOT_READY) + x25_error(card, err, usr_cmd->cmd.command, usr_cmd->cmd.lcn); + + if (mbox->cmd.result == X25RES_NOT_READY){ + return TRY_CMD_AGAIN; + } + + switch (mbox->cmd.command){ + + case X25_PLACE_CALL: + + switch (mbox->cmd.result){ + + case CMD_OK: + + /* Check if Place call is a wait command or a + * no wait command */ + if (atomic_read(&chan->common.command) & 0x80) + delay=RETURN_RESULT; + else + delay=DELAY_RESULT; + + + DBG_PRINTK(KERN_INFO "\n%s: PLACE CALL Binding dev %s to lcn %i\n", + card->devname,dev->name, mbox->cmd.lcn); + + bind_lcn_to_dev (card, dev, mbox->cmd.lcn); + set_chan_state(dev, WAN_CONNECTING); + break; + + + default: + delay=RETURN_RESULT; + set_chan_state(dev, WAN_DISCONNECTED); + break; + } + break; + + case X25_ACCEPT_CALL: + + switch (mbox->cmd.result){ + + case CMD_OK: + + DBG_PRINTK(KERN_INFO "\n%s: ACCEPT Binding dev %s to lcn %i\n", + card->devname,dev->name,mbox->cmd.lcn); + + bind_lcn_to_dev (card, dev, mbox->cmd.lcn); + + if (x25_get_chan_conf(card, chan) == CMD_OK){ + + set_chan_state(dev, WAN_CONNECTED); + delay=RETURN_RESULT; + + }else{ + if (x25_clear_call(card, usr_cmd->cmd.lcn, 0, 0) == CMD_OK){ + /* if clear is successful, wait for clear confirm + */ + delay=DELAY_RESULT; + }else{ + /* Do not change the state here. If we fail + * the accept the return code is send up + *the stack, which will ether retry + * or clear the call + */ + DBG_PRINTK(KERN_INFO + "%s: ACCEPT: STATE MAY BE CURRUPTED 2 !!!!!\n", + card->devname); + delay=RETURN_RESULT; + } + } + break; + + + case X25RES_ASYNC_PACKET: + delay=TRY_CMD_AGAIN; + break; + + default: + DBG_PRINTK(KERN_INFO "%s: ACCEPT FAILED\n",card->devname); + if (x25_clear_call(card, usr_cmd->cmd.lcn, 0, 0) == CMD_OK){ + delay=DELAY_RESULT; + }else{ + /* Do not change the state here. If we fail the accept. The + * return code is send up the stack, which will ether retry + * or clear the call */ + DBG_PRINTK(KERN_INFO + "%s: ACCEPT: STATE MAY BE CORRUPTED 1 !!!!!\n", + card->devname); + delay=RETURN_RESULT; + } + } + break; + + case X25_CLEAR_CALL: + + switch (mbox->cmd.result){ + + case CMD_OK: + DBG_PRINTK(KERN_INFO + "CALL CLEAR OK: Dev %s Mbox Lcn %i Chan Lcn %i\n", + dev->name,mbox->cmd.lcn,chan->common.lcn); + set_chan_state(dev, WAN_DISCONNECTING); + delay = DELAY_RESULT; + break; + + case X25RES_CHANNEL_IN_USE: + case X25RES_ASYNC_PACKET: + delay = TRY_CMD_AGAIN; + break; + + case X25RES_LINK_NOT_IN_ABM: + case X25RES_INVAL_LCN: + case X25RES_INVAL_STATE: + set_chan_state(dev, WAN_DISCONNECTED); + delay = RETURN_RESULT; + break; + + default: + /* If command did not execute because of user + * fault, do not change the state. This will + * signal the socket that clear command failed. + * User can retry or close the socket. + * When socket gets killed, it will set the + * chan->disconnect which will signal + * driver to clear the call */ + printk(KERN_INFO "%s: Clear Command Failed, Rc %x\n", + card->devname,mbox->cmd.command); + delay = RETURN_RESULT; + } + break; + } + + return delay; +} + +/*=============================================================== + * api_incoming_call + * + * Pass an incoming call request up the listening + * sock. If the API sock is not listening reject the + * call. + * + *===============================================================*/ + +static int api_incoming_call (sdla_t* card, TX25Mbox *mbox, int lcn) +{ + struct sk_buff *skb; + int len = sizeof(TX25Cmd)+mbox->cmd.length; + + if (alloc_and_init_skb_buf(card, &skb, len)){ + printk(KERN_INFO "%s: API incoming call, no memory\n",card->devname); + return 1; + } + + memcpy(skb_put(skb,len),&mbox->cmd,len); + + skb->mac.raw = skb->data; + skb->protocol = htons(X25_PROT); + skb->pkt_type = WAN_PACKET_ASYNC; + + if (card->func(skb,card->sk) < 0){ + printk(KERN_INFO "%s: MAJOR ERROR: Failed to send up place call \n",card->devname); + dev_kfree_skb_any(skb); + return 1; + } + + return 0; +} + +/*=============================================================== + * send_delayed_cmd_result + * + * Wait commands like PLEACE CALL or CLEAR CALL must wait + * until the result arrives. This function passes + * the result to a waiting sock. + * + *===============================================================*/ +static void send_delayed_cmd_result(sdla_t *card, struct net_device *dev, + TX25Mbox* mbox) +{ + x25_channel_t *chan = dev->priv; + mbox_cmd_t *usr_cmd = (mbox_cmd_t *)chan->common.mbox; + struct sk_buff *skb; + int len=sizeof(unsigned char); + + atomic_set(&chan->common.command,0); + + /* If the sock is in the process of unlinking the + * driver from the socket, we must get out. + * This never happends but is a sanity check. */ + if (test_bit(0,&chan->common.common_critical)){ + return; + } + + if (!usr_cmd || !chan->common.sk || !chan->common.func){ + DBG_PRINTK(KERN_INFO "Delay result: Sock not bounded sk: %u, func: %u, mbox: %u\n", + (unsigned int)chan->common.sk, + (unsigned int)chan->common.func, + (unsigned int)usr_cmd); + return; + } + + memcpy(&usr_cmd->cmd, &mbox->cmd, sizeof(TX25Cmd)); + if (mbox->cmd.length > 0){ + memcpy(usr_cmd->data, mbox->data, mbox->cmd.length); + } + + if (alloc_and_init_skb_buf(card,&skb,len)){ + printk(KERN_INFO "Delay result: No sock buffers\n"); + return; + } + + memcpy(skb_put(skb,len),&mbox->cmd.command,len); + + skb->mac.raw = skb->data; + skb->pkt_type = WAN_PACKET_CMD; + + chan->common.func(skb,dev,chan->common.sk); +} + +/*=============================================================== + * clear_confirm_event + * + * Pass the clear confirmation event up the sock. The + * API will disconnect only after the clear confirmation + * has been received. + * + * Depending on the state, clear confirmation could + * be an OOB event, or a result of an API command. + *===============================================================*/ + +static int clear_confirm_event (sdla_t *card, TX25Mbox* mb) +{ + struct net_device *dev; + x25_channel_t *chan; + unsigned char old_state; + + dev = find_channel(card,mb->cmd.lcn); + if (!dev){ + DBG_PRINTK(KERN_INFO "%s: *** GOT CLEAR BUT NO DEV %i\n", + card->devname,mb->cmd.lcn); + return 0; + } + + chan=dev->priv; + DBG_PRINTK(KERN_INFO "%s: GOT CLEAR CONFIRM %s: Mbox lcn %i Chan lcn %i\n", + card->devname, dev->name, mb->cmd.lcn, chan->common.lcn); + + /* If not API fall through to default. + * If API, send the result to a waiting + * socket. + */ + + old_state = chan->common.state; + set_chan_state(dev, WAN_DISCONNECTED); + + if (chan->common.usedby == API){ + switch (old_state) { + + case WAN_DISCONNECTING: + case WAN_CONNECTING: + send_delayed_cmd_result(card,dev,mb); + break; + case WAN_CONNECTED: + send_oob_msg(card,dev,mb); + break; + } + return 1; + } + + return 0; +} + +/*=============================================================== + * send_oob_msg + * + * Construct an NEM Message and pass it up the connected + * sock. If the sock is not bounded discard the NEM. + * + *===============================================================*/ + +static void send_oob_msg(sdla_t *card, struct net_device *dev, TX25Mbox *mbox) +{ + x25_channel_t *chan = dev->priv; + mbox_cmd_t *usr_cmd = (mbox_cmd_t *)chan->common.mbox; + struct sk_buff *skb; + int len=sizeof(x25api_hdr_t)+mbox->cmd.length; + x25api_t *api_hdr; + + /* If the sock is in the process of unlinking the + * driver from the socket, we must get out. + * This never happends but is a sanity check. */ + if (test_bit(0,&chan->common.common_critical)){ + return; + } + + if (!usr_cmd || !chan->common.sk || !chan->common.func){ + DBG_PRINTK(KERN_INFO "OOB MSG: Sock not bounded\n"); + return; + } + + memcpy(&usr_cmd->cmd, &mbox->cmd, sizeof(TX25Cmd)); + if (mbox->cmd.length > 0){ + memcpy(usr_cmd->data, mbox->data, mbox->cmd.length); + } + + if (alloc_and_init_skb_buf(card,&skb,len)){ + printk(KERN_INFO "%s: OOB MSG: No sock buffers\n",card->devname); + return; + } + + api_hdr = (x25api_t*)skb_put(skb,len); + api_hdr->hdr.pktType = mbox->cmd.pktType & 0x7F; + api_hdr->hdr.qdm = mbox->cmd.qdm; + api_hdr->hdr.cause = mbox->cmd.cause; + api_hdr->hdr.diagn = mbox->cmd.diagn; + api_hdr->hdr.length = mbox->cmd.length; + api_hdr->hdr.result = mbox->cmd.result; + api_hdr->hdr.lcn = mbox->cmd.lcn; + + if (mbox->cmd.length > 0){ + memcpy(api_hdr->data,mbox->data,mbox->cmd.length); + } + + skb->mac.raw = skb->data; + skb->pkt_type = WAN_PACKET_ERR; + + if (chan->common.func(skb,dev,chan->common.sk) < 0){ + if (bh_enqueue(dev,skb)){ + printk(KERN_INFO "%s: Dropping OOB MSG\n",card->devname); + dev_kfree_skb_any(skb); + } + } + + DBG_PRINTK(KERN_INFO "%s: OOB MSG OK, %s, lcn %i\n", + card->devname, dev->name, mbox->cmd.lcn); +} + +/*=============================================================== + * alloc_and_init_skb_buf + * + * Allocate and initialize an skb buffer. + * + *===============================================================*/ + +static int alloc_and_init_skb_buf (sdla_t *card, struct sk_buff **skb, int len) +{ + struct sk_buff *new_skb = *skb; + + new_skb = dev_alloc_skb(len + X25_HRDHDR_SZ); + if (new_skb == NULL){ + printk(KERN_INFO "%s: no socket buffers available!\n", + card->devname); + return 1; + } + + if (skb_tailroom(new_skb) < len){ + /* No room for the packet. Call off the whole thing! */ + dev_kfree_skb_any(new_skb); + printk(KERN_INFO "%s: Listen: unexpectedly long packet sequence\n" + ,card->devname); + *skb = NULL; + return 1; + } + + *skb = new_skb; + return 0; + +} + +/*=============================================================== + * api_oob_event + * + * Send an OOB event up to the sock + * + *===============================================================*/ + +static void api_oob_event (sdla_t *card,TX25Mbox *mbox) +{ + struct net_device *dev = find_channel(card, mbox->cmd.lcn); + x25_channel_t *chan; + + if (!dev) + return; + + chan=dev->priv; + + if (chan->common.usedby == API) + send_oob_msg(card,dev,mbox); + +} + + + + +static int channel_disconnect(sdla_t* card, struct net_device *dev) +{ + + int err; + x25_channel_t *chan = dev->priv; + + DBG_PRINTK(KERN_INFO "%s: TIMER: %s, Device down disconnecting\n", + card->devname,dev->name); + + if (chan->common.svc){ + err = x25_clear_call(card,chan->common.lcn,0,0); + }else{ + /* If channel is PVC or LAPB HDLC, there is no call + * to be cleared, thus drop down to the default + * area + */ + err = 1; + } + + switch (err){ + + case X25RES_CHANNEL_IN_USE: + case X25RES_NOT_READY: + err = TRY_CMD_AGAIN; + break; + case CMD_OK: + DBG_PRINTK(KERN_INFO "CALL CLEAR OK: Dev %s Chan Lcn %i\n", + dev->name,chan->common.lcn); + + set_chan_state(dev,WAN_DISCONNECTING); + atomic_set(&chan->common.command,0); + err = DELAY_RESULT; + break; + default: + /* If LAPB HDLC protocol, bring the whole link down + * once the application terminates + */ + + set_chan_state(dev,WAN_DISCONNECTED); + + if (card->u.x.LAPB_hdlc){ + DBG_PRINTK(KERN_INFO "LAPB: Disconnecting Link\n"); + hdlc_link_down (card); + } + atomic_set(&chan->common.command,0); + err = RETURN_RESULT; + break; + } + + return err; +} + +static void hdlc_link_down (sdla_t *card) +{ + TX25Mbox* mbox = card->mbox; + int retry = 5; + int err=0; + + do { + memset(mbox,0,sizeof(TX25Mbox)); + mbox->cmd.command = X25_HDLC_LINK_DISC; + mbox->cmd.length = 1; + mbox->data[0]=0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + + } while (err && retry-- && x25_error(card, err, X25_HDLC_LINK_DISC, 0)); + + if (err) + printk(KERN_INFO "%s: Hdlc Link Down Failed %x\n",card->devname,err); + + disconnect (card); + +} + +static int check_bad_command(sdla_t* card, struct net_device *dev) +{ + x25_channel_t *chan = dev->priv; + int bad_cmd = 0; + + switch (atomic_read(&chan->common.command)&0x7F){ + + case X25_PLACE_CALL: + if (chan->common.state != WAN_DISCONNECTED) + bad_cmd=1; + break; + case X25_CLEAR_CALL: + if (chan->common.state == WAN_DISCONNECTED) + bad_cmd=1; + break; + case X25_ACCEPT_CALL: + if (chan->common.state != WAN_CONNECTING) + bad_cmd=1; + break; + case X25_RESET: + if (chan->common.state != WAN_CONNECTED) + bad_cmd=1; + break; + default: + bad_cmd=1; + break; + } + + if (bad_cmd){ + printk(KERN_INFO "%s: Invalid State, BAD Command %x, dev %s, lcn %i, st %i\n", + card->devname,atomic_read(&chan->common.command),dev->name, + chan->common.lcn, chan->common.state); + } + + return bad_cmd; +} + + + +/*************************** XPIPEMON FUNCTIONS **************************/ + +/*============================================================================== + * Process UDP call of type XPIPE + */ + +static int process_udp_mgmt_pkt(sdla_t *card) +{ + int c_retry = MAX_CMD_RETRY; + unsigned int len; + struct sk_buff *new_skb; + TX25Mbox *mbox = card->mbox; + int err; + int udp_mgmt_req_valid = 1; + struct net_device *dev; + x25_channel_t *chan; + unsigned short lcn; + struct timeval tv; + + + x25_udp_pkt_t *x25_udp_pkt; + x25_udp_pkt = (x25_udp_pkt_t *)card->u.x.udp_pkt_data; + + dev = card->u.x.udp_dev; + chan = dev->priv; + lcn = chan->common.lcn; + + switch(x25_udp_pkt->cblock.command) { + + /* XPIPE_ENABLE_TRACE */ + case XPIPE_ENABLE_TRACING: + + /* XPIPE_GET_TRACE_INFO */ + case XPIPE_GET_TRACE_INFO: + + /* SET FT1 MODE */ + case XPIPE_SET_FT1_MODE: + + if(card->u.x.udp_pkt_src == UDP_PKT_FRM_NETWORK) { + ++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_direction_err; + udp_mgmt_req_valid = 0; + break; + } + + /* XPIPE_FT1_READ_STATUS */ + case XPIPE_FT1_READ_STATUS: + + /* FT1 MONITOR STATUS */ + case XPIPE_FT1_STATUS_CTRL: + if(card->hw.fwid != SFID_X25_508) { + ++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_type_err; + udp_mgmt_req_valid = 0; + break; + } + default: + break; + } + + if(!udp_mgmt_req_valid) { + /* set length to 0 */ + x25_udp_pkt->cblock.length = 0; + /* set return code */ + x25_udp_pkt->cblock.result = (card->hw.fwid != SFID_X25_508) ? 0x1F : 0xCD; + + } else { + + switch (x25_udp_pkt->cblock.command) { + + + case XPIPE_FLUSH_DRIVER_STATS: + init_x25_channel_struct(chan); + init_global_statistics(card); + mbox->cmd.length = 0; + break; + + + case XPIPE_DRIVER_STAT_IFSEND: + memcpy(x25_udp_pkt->data, &chan->if_send_stat, sizeof(if_send_stat_t)); + mbox->cmd.length = sizeof(if_send_stat_t); + x25_udp_pkt->cblock.length = mbox->cmd.length; + break; + + case XPIPE_DRIVER_STAT_INTR: + memcpy(&x25_udp_pkt->data[0], &card->statistics, sizeof(global_stats_t)); + memcpy(&x25_udp_pkt->data[sizeof(global_stats_t)], + &chan->rx_intr_stat, sizeof(rx_intr_stat_t)); + + mbox->cmd.length = sizeof(global_stats_t) + + sizeof(rx_intr_stat_t); + x25_udp_pkt->cblock.length = mbox->cmd.length; + break; + + case XPIPE_DRIVER_STAT_GEN: + memcpy(x25_udp_pkt->data, + &chan->pipe_mgmt_stat.UDP_PIPE_mgmt_kmalloc_err, + sizeof(pipe_mgmt_stat_t)); + + memcpy(&x25_udp_pkt->data[sizeof(pipe_mgmt_stat_t)], + &card->statistics, sizeof(global_stats_t)); + + x25_udp_pkt->cblock.result = 0; + x25_udp_pkt->cblock.length = sizeof(global_stats_t)+ + sizeof(rx_intr_stat_t); + mbox->cmd.length = x25_udp_pkt->cblock.length; + break; + + case XPIPE_ROUTER_UP_TIME: + do_gettimeofday(&tv); + chan->router_up_time = tv.tv_sec - chan->router_start_time; + *(unsigned long *)&x25_udp_pkt->data = chan->router_up_time; + x25_udp_pkt->cblock.length = mbox->cmd.length = 4; + x25_udp_pkt->cblock.result = 0; + break; + + default : + + do { + memcpy(&mbox->cmd, &x25_udp_pkt->cblock.command, sizeof(TX25Cmd)); + if(mbox->cmd.length){ + memcpy(&mbox->data, + (char *)x25_udp_pkt->data, + mbox->cmd.length); + } + + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && c_retry-- && x25_error(card, err, mbox->cmd.command, 0)); + + + if ( err == CMD_OK || + (err == 1 && + (mbox->cmd.command == 0x06 || + mbox->cmd.command == 0x16) ) ){ + + ++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_cmnd_OK; + } else { + ++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_cmnd_timeout; + } + + /* copy the result back to our buffer */ + memcpy(&x25_udp_pkt->cblock.command, &mbox->cmd, sizeof(TX25Cmd)); + + if(mbox->cmd.length) { + memcpy(&x25_udp_pkt->data, &mbox->data, mbox->cmd.length); + } + break; + + } //switch + + } + + /* Fill UDP TTL */ + + x25_udp_pkt->ip_pkt.ttl = card->wandev.ttl; + len = reply_udp(card->u.x.udp_pkt_data, mbox->cmd.length); + + + if(card->u.x.udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + err = x25_send(card, lcn, 0, len, card->u.x.udp_pkt_data); + if (!err) + ++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_send_passed; + else + ++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_send_failed; + + } else { + + /* Allocate socket buffer */ + if((new_skb = dev_alloc_skb(len)) != NULL) { + void *buf; + + /* copy data into new_skb */ + buf = skb_put(new_skb, len); + memcpy(buf, card->u.x.udp_pkt_data, len); + + /* Decapsulate packet and pass it up the protocol + stack */ + new_skb->dev = dev; + + if (chan->common.usedby == API) + new_skb->protocol = htons(X25_PROT); + else + new_skb->protocol = htons(ETH_P_IP); + + new_skb->mac.raw = new_skb->data; + + netif_rx(new_skb); + ++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_stack; + + } else { + ++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_no_socket; + printk(KERN_INFO + "%s: UDP mgmt cmnd, no socket buffers available!\n", + card->devname); + } + } + + card->u.x.udp_pkt_lgth = 0; + + return 1; +} + + +/*============================================================================== + * Determine what type of UDP call it is. DRVSTATS or XPIPE8ND ? + */ +static int udp_pkt_type( struct sk_buff *skb, sdla_t* card ) +{ + x25_udp_pkt_t *x25_udp_pkt = (x25_udp_pkt_t *)skb->data; + + if((x25_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) && + (x25_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45) && + (x25_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) && + (x25_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) { + + if(!strncmp(x25_udp_pkt->wp_mgmt.signature, + UDPMGMT_XPIPE_SIGNATURE, 8)){ + return UDP_XPIPE_TYPE; + }else{ + printk(KERN_INFO "%s: UDP Packet, Failed Signature !\n", + card->devname); + } + } + + return UDP_INVALID_TYPE; +} + + +/*============================================================================ + * Reply to UDP Management system. + * Return nothing. + */ +static int reply_udp( unsigned char *data, unsigned int mbox_len ) +{ + unsigned short len, udp_length, temp, ip_length; + unsigned long ip_temp; + int even_bound = 0; + + + x25_udp_pkt_t *x25_udp_pkt = (x25_udp_pkt_t *)data; + + /* Set length of packet */ + len = sizeof(ip_pkt_t)+ + sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + + /* fill in UDP reply */ + x25_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; + + /* fill in UDP length */ + udp_length = sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + + /* put it on an even boundary */ + if ( udp_length & 0x0001 ) { + udp_length += 1; + len += 1; + even_bound = 1; + } + + temp = (udp_length<<8)|(udp_length>>8); + x25_udp_pkt->udp_pkt.udp_length = temp; + + /* swap UDP ports */ + temp = x25_udp_pkt->udp_pkt.udp_src_port; + x25_udp_pkt->udp_pkt.udp_src_port = + x25_udp_pkt->udp_pkt.udp_dst_port; + x25_udp_pkt->udp_pkt.udp_dst_port = temp; + + + + /* add UDP pseudo header */ + temp = 0x1100; + *((unsigned short *) + (x25_udp_pkt->data+mbox_len+even_bound)) = temp; + temp = (udp_length<<8)|(udp_length>>8); + *((unsigned short *) + (x25_udp_pkt->data+mbox_len+even_bound+2)) = temp; + + /* calculate UDP checksum */ + x25_udp_pkt->udp_pkt.udp_checksum = 0; + + x25_udp_pkt->udp_pkt.udp_checksum = + calc_checksum(&data[UDP_OFFSET], udp_length+UDP_OFFSET); + + /* fill in IP length */ + ip_length = len; + temp = (ip_length<<8)|(ip_length>>8); + x25_udp_pkt->ip_pkt.total_length = temp; + + /* swap IP addresses */ + ip_temp = x25_udp_pkt->ip_pkt.ip_src_address; + x25_udp_pkt->ip_pkt.ip_src_address = + x25_udp_pkt->ip_pkt.ip_dst_address; + x25_udp_pkt->ip_pkt.ip_dst_address = ip_temp; + + + /* fill in IP checksum */ + x25_udp_pkt->ip_pkt.hdr_checksum = 0; + x25_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data, sizeof(ip_pkt_t)); + + return len; +} /* reply_udp */ + +unsigned short calc_checksum (char *data, int len) +{ + unsigned short temp; + unsigned long sum=0; + int i; + + for( i = 0; i > 16 ) { + sum = (sum & 0xffffUL) + (sum >> 16); + } + + temp = (unsigned short)sum; + temp = ~temp; + + if( temp == 0 ) + temp = 0xffff; + + return temp; +} + +/*============================================================================= + * Store a UDP management packet for later processing. + */ + +static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card, + struct net_device *dev, struct sk_buff *skb, + int lcn) +{ + int udp_pkt_stored = 0; + + if(!card->u.x.udp_pkt_lgth && (skb->len <= MAX_LGTH_UDP_MGNT_PKT)){ + card->u.x.udp_pkt_lgth = skb->len; + card->u.x.udp_type = udp_type; + card->u.x.udp_pkt_src = udp_pkt_src; + card->u.x.udp_lcn = lcn; + card->u.x.udp_dev = dev; + memcpy(card->u.x.udp_pkt_data, skb->data, skb->len); + card->u.x.timer_int_enabled |= TMR_INT_ENABLED_UDP_PKT; + udp_pkt_stored = 1; + + }else{ + printk(KERN_INFO "%s: ERROR: UDP packet not stored for LCN %d\n", + card->devname,lcn); + } + + if(udp_pkt_src == UDP_PKT_FRM_STACK){ + dev_kfree_skb_any(skb); + }else{ + dev_kfree_skb_any(skb); + } + + return(udp_pkt_stored); +} + + + +/*============================================================================= + * Initial the ppp_private_area structure. + */ +static void init_x25_channel_struct( x25_channel_t *chan ) +{ + memset(&chan->if_send_stat.if_send_entry,0,sizeof(if_send_stat_t)); + memset(&chan->rx_intr_stat.rx_intr_no_socket,0,sizeof(rx_intr_stat_t)); + memset(&chan->pipe_mgmt_stat.UDP_PIPE_mgmt_kmalloc_err,0,sizeof(pipe_mgmt_stat_t)); +} + +/*============================================================================ + * Initialize Global Statistics + */ +static void init_global_statistics( sdla_t *card ) +{ + memset(&card->statistics.isr_entry,0,sizeof(global_stats_t)); +} + + +/*=============================================================== + * SMP Support + * ==============================================================*/ + +static void S508_S514_lock(sdla_t *card, unsigned long *smp_flags) +{ + spin_lock_irqsave(&card->wandev.lock, *smp_flags); +} +static void S508_S514_unlock(sdla_t *card, unsigned long *smp_flags) +{ + spin_unlock_irqrestore(&card->wandev.lock, *smp_flags); +} + +/*=============================================================== + * x25_timer_routine + * + * A more efficient polling routine. Each half a second + * queue a polling task. We want to do the polling in a + * task not timer, because timer runs in interrupt time. + * + * FIXME Polling should be rethinked. + *==============================================================*/ + +static void x25_timer_routine(unsigned long data) +{ + sdla_t *card = (sdla_t*)data; + + if (!card->wandev.dev){ + printk(KERN_INFO "%s: Stopping the X25 Poll Timer: No Dev.\n", + card->devname); + return; + } + + if (card->open_cnt != card->u.x.num_of_ch){ + printk(KERN_INFO "%s: Stopping the X25 Poll Timer: Interface down.\n", + card->devname); + return; + } + + if (test_bit(PERI_CRIT,&card->wandev.critical)){ + printk(KERN_INFO "%s: Stopping the X25 Poll Timer: Shutting down.\n", + card->devname); + return; + } + + if (!test_and_set_bit(POLL_CRIT,&card->wandev.critical)){ + trigger_x25_poll(card); + } + + card->u.x.x25_timer.expires=jiffies+(HZ>>1); + add_timer(&card->u.x.x25_timer); + return; +} + +void disable_comm_shutdown(sdla_t *card) +{ + TX25Mbox* mbox = card->mbox; + int err; + + /* Turn of interrutps */ + mbox->data[0] = 0; + if (card->hw.fwid == SFID_X25_508){ + mbox->data[1] = card->hw.irq; + mbox->data[2] = 2; + mbox->cmd.length = 3; + }else { + mbox->cmd.length = 1; + } + mbox->cmd.command = X25_SET_INTERRUPT_MODE; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err) + printk(KERN_INFO "INTERRUPT OFF FAIED %x\n",err); + + /* Bring down HDLC */ + mbox->cmd.command = X25_HDLC_LINK_CLOSE; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err) + printk(KERN_INFO "LINK CLOSED FAILED %x\n",err); + + + /* Brind down DTR */ + mbox->data[0] = 0; + mbox->data[2] = 0; + mbox->data[1] = 0x01; + mbox->cmd.length = 3; + mbox->cmd.command = X25_SET_GLOBAL_VARS; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err) + printk(KERN_INFO "DTR DOWN FAILED %x\n",err); + +} + +MODULE_LICENSE("GPL"); + +/****** End *****************************************************************/ diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c new file mode 100644 index 000000000..032c0f819 --- /dev/null +++ b/drivers/net/wan/sdladrv.c @@ -0,0 +1,2314 @@ +/***************************************************************************** +* sdladrv.c SDLA Support Module. Main module. +* +* This module is a library of common hardware-specific functions +* used by all Sangoma drivers. +* +* Author: Gideon Hack +* +* Copyright: (c) 1995-2000 Sangoma 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. +* ============================================================================ +* Mar 20, 2001 Nenad Corbic Added the auto_pci_cfg filed, to support +* the PCISLOT #0. +* Apr 04, 2000 Nenad Corbic Fixed the auto memory detection code. +* The memory test at address 0xC8000. +* Mar 09, 2000 Nenad Corbic Added Gideon's Bug Fix: clear pci +* interrupt flags on initial load. +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. +* Updates for Linux 2.2.X kernels. +* Sep 17, 1998 Jaspreet Singh Updates for linux 2.2.X kernels +* Dec 20, 1996 Gene Kozin Version 3.0.0. Complete overhaul. +* Jul 12, 1996 Gene Kozin Changes for Linux 2.0 compatibility. +* Jun 12, 1996 Gene Kozin Added support for S503 card. +* Apr 30, 1996 Gene Kozin SDLA hardware interrupt is acknowledged before +* calling protocolspecific ISR. +* Register I/O ports with Linux kernel. +* Miscellaneous bug fixes. +* Dec 20, 1995 Gene Kozin Fixed a bug in interrupt routine. +* Oct 14, 1995 Gene Kozin Initial version. +*****************************************************************************/ + +/***************************************************************************** + * Notes: + * ------ + * 1. This code is ment to be system-independent (as much as possible). To + * achive this, various macros are used to hide system-specific interfaces. + * To compile this code, one of the following constants must be defined: + * + * Platform Define + * -------- ------ + * Linux _LINUX_ + * SCO Unix _SCO_UNIX_ + * + * 2. Supported adapter types: + * + * S502A + * ES502A (S502E) + * S503 + * S507 + * S508 (S509) + * + * 3. S502A Notes: + * + * There is no separate DPM window enable/disable control in S502A. It + * opens immediately after a window number it written to the HMCR + * register. To close the window, HMCR has to be written a value + * ????1111b (e.g. 0x0F or 0xFF). + * + * S502A DPM window cannot be located at offset E000 (e.g. 0xAE000). + * + * There should be a delay of ??? before reading back S502A status + * register. + * + * 4. S502E Notes: + * + * S502E has a h/w bug: although default IRQ line state is HIGH, enabling + * interrupts by setting bit 1 of the control register (BASE) to '1' + * causes it to go LOW! Therefore, disabling interrupts by setting that + * bit to '0' causes low-to-high transition on IRQ line (ghosty + * interrupt). The same occurs when disabling CPU by resetting bit 0 of + * CPU control register (BASE+3) - see the next note. + * + * S502E CPU and DPM control is limited: + * + * o CPU cannot be stopped independently. Resetting bit 0 of the CPUi + * control register (BASE+3) shuts the board down entirely, including + * DPM; + * + * o DPM access cannot be controlled dynamically. Ones CPU is started, + * bit 1 of the control register (BASE) is used to enable/disable IRQ, + * so that access to shared memory cannot be disabled while CPU is + * running. + ****************************************************************************/ + +#define _LINUX_ + +#if defined(_LINUX_) /****** Linux *******************************/ + +#include +#include /* printk(), and other useful stuff */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include /* support for loadable modules */ +#include /* for jiffies, HZ, etc. */ +#include /* API definitions */ +#include /* SDLA firmware module definitions */ +#include /* SDLA PCI hardware definitions */ +#include /* PCI defines and function prototypes */ +#include /* for inb(), outb(), etc. */ + +#define _INB(port) (inb(port)) +#define _OUTB(port, byte) (outb((byte),(port))) +#define SYSTEM_TICK jiffies + +#include + + +#elif defined(_SCO_UNIX_) /****** SCO Unix ****************************/ + +#if !defined(INKERNEL) +#error This code MUST be compiled in kernel mode! +#endif +#include /* API definitions */ +#include /* SDLA firmware module definitions */ +#include /* for inb(), outb(), etc. */ +#define _INB(port) (inb(port)) +#define _OUTB(port, byte) (outb((port),(byte))) +#define SYSTEM_TICK lbolt + +#else +#error Unknown system type! +#endif + +#define MOD_VERSION 3 +#define MOD_RELEASE 0 + +#define SDLA_IODELAY 100 /* I/O Rd/Wr delay, 10 works for 486DX2-66 */ +#define EXEC_DELAY 20 /* shared memory access delay, mks */ +#define EXEC_TIMEOUT (HZ*2) /* command timeout, in ticks */ + +/* I/O port address range */ +#define S502A_IORANGE 3 +#define S502E_IORANGE 4 +#define S503_IORANGE 3 +#define S507_IORANGE 4 +#define S508_IORANGE 4 + +/* Maximum amount of memory */ +#define S502_MAXMEM 0x10000L +#define S503_MAXMEM 0x10000L +#define S507_MAXMEM 0x40000L +#define S508_MAXMEM 0x40000L + +/* Minimum amount of memory */ +#define S502_MINMEM 0x8000L +#define S503_MINMEM 0x8000L +#define S507_MINMEM 0x20000L +#define S508_MINMEM 0x20000L +#define NO_PORT -1 + + + + + +/****** Function Prototypes *************************************************/ + +/* Hardware-specific functions */ +static int sdla_detect (sdlahw_t* hw); +static int sdla_autodpm (sdlahw_t* hw); +static int sdla_setdpm (sdlahw_t* hw); +static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len); +static int sdla_init (sdlahw_t* hw); +static unsigned long sdla_memtest (sdlahw_t* hw); +static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo); +static unsigned char make_config_byte (sdlahw_t* hw); +static int sdla_start (sdlahw_t* hw, unsigned addr); + +static int init_s502a (sdlahw_t* hw); +static int init_s502e (sdlahw_t* hw); +static int init_s503 (sdlahw_t* hw); +static int init_s507 (sdlahw_t* hw); +static int init_s508 (sdlahw_t* hw); + +static int detect_s502a (int port); +static int detect_s502e (int port); +static int detect_s503 (int port); +static int detect_s507 (int port); +static int detect_s508 (int port); +static int detect_s514 (sdlahw_t* hw); +static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card); + +/* Miscellaneous functions */ +static void peek_by_4 (unsigned long src, void* buf, unsigned len); +static void poke_by_4 (unsigned long dest, void* buf, unsigned len); +static int calibrate_delay (int mks); +static int get_option_index (unsigned* optlist, unsigned optval); +static unsigned check_memregion (void* ptr, unsigned len); +static unsigned test_memregion (void* ptr, unsigned len); +static unsigned short checksum (unsigned char* buf, unsigned len); +static int init_pci_slot(sdlahw_t *); + +static int pci_probe(sdlahw_t *hw); + +/****** Global Data ********************************************************** + * Note: All data must be explicitly initialized!!! + */ + +static struct pci_device_id sdladrv_pci_tbl[] = { + { V3_VENDOR_ID, V3_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(pci, sdladrv_pci_tbl); + +MODULE_LICENSE("GPL"); + +/* private data */ +static char modname[] = "sdladrv"; +static char fullname[] = "SDLA Support Module"; +static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc."; +static unsigned exec_idle; + +/* Hardware configuration options. + * These are arrays of configuration options used by verification routines. + * The first element of each array is its size (i.e. number of options). + */ +static unsigned s502_port_options[] = + { 4, 0x250, 0x300, 0x350, 0x360 } +; +static unsigned s503_port_options[] = + { 8, 0x250, 0x254, 0x300, 0x304, 0x350, 0x354, 0x360, 0x364 } +; +static unsigned s508_port_options[] = + { 8, 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390 } +; + +static unsigned s502a_irq_options[] = { 0 }; +static unsigned s502e_irq_options[] = { 4, 2, 3, 5, 7 }; +static unsigned s503_irq_options[] = { 5, 2, 3, 4, 5, 7 }; +static unsigned s508_irq_options[] = { 8, 3, 4, 5, 7, 10, 11, 12, 15 }; + +static unsigned s502a_dpmbase_options[] = +{ + 28, + 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, + 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, + 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, + 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, +}; +static unsigned s507_dpmbase_options[] = +{ + 32, + 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, + 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000, + 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000, + 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000, +}; +static unsigned s508_dpmbase_options[] = /* incl. S502E and S503 */ +{ + 32, + 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, + 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000, + 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000, + 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000, +}; + +/* +static unsigned s502_dpmsize_options[] = { 2, 0x2000, 0x10000 }; +static unsigned s507_dpmsize_options[] = { 2, 0x2000, 0x4000 }; +static unsigned s508_dpmsize_options[] = { 1, 0x2000 }; +*/ + +static unsigned s502a_pclk_options[] = { 2, 3600, 7200 }; +static unsigned s502e_pclk_options[] = { 5, 3600, 5000, 7200, 8000, 10000 }; +static unsigned s503_pclk_options[] = { 3, 7200, 8000, 10000 }; +static unsigned s507_pclk_options[] = { 1, 12288 }; +static unsigned s508_pclk_options[] = { 1, 16000 }; + +/* Host memory control register masks */ +static unsigned char s502a_hmcr[] = +{ + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, /* A0000 - AC000 */ + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, /* C0000 - CC000 */ + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, /* D0000 - DC000 */ + 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, /* E0000 - EC000 */ +}; +static unsigned char s502e_hmcr[] = +{ + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, /* A0000 - AE000 */ + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, /* C0000 - CE000 */ + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* D0000 - DE000 */ + 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, /* E0000 - EE000 */ +}; +static unsigned char s507_hmcr[] = +{ + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* A0000 - AE000 */ + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, /* B0000 - BE000 */ + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, /* C0000 - CE000 */ + 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, /* E0000 - EE000 */ +}; +static unsigned char s508_hmcr[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* A0000 - AE000 */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* C0000 - CE000 */ + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* D0000 - DE000 */ + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* E0000 - EE000 */ +}; + +static unsigned char s507_irqmask[] = +{ + 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0 +}; + +static int pci_slot_ar[MAX_S514_CARDS]; + +/******* Kernel Loadable Module Entry Points ********************************/ + +/*============================================================================ + * Module 'insert' entry point. + * o print announcement + * o initialize static data + * o calibrate SDLA shared memory access delay. + * + * Return: 0 Ok + * < 0 error. + * Context: process + */ + +static int __init sdladrv_init(void) +{ + int i=0; + + printk(KERN_INFO "%s v%u.%u %s\n", + fullname, MOD_VERSION, MOD_RELEASE, copyright); + exec_idle = calibrate_delay(EXEC_DELAY); +#ifdef WANDEBUG + printk(KERN_DEBUG "%s: exec_idle = %d\n", modname, exec_idle); +#endif + + /* Initialize the PCI Card array, which + * will store flags, used to mark + * card initialization state */ + for (i=0; itype != SDLA_S514) + printk(KERN_INFO "%s: no SDLA card found at port 0x%X\n", + modname, hw->port); + return -EINVAL; + } + + if(hw->type != SDLA_S514) { + printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n", + modname, hw->type, hw->port); + + hw->dpmsize = SDLA_WINDOWSIZE; + switch (hw->type) { + case SDLA_S502A: + hw->io_range = S502A_IORANGE; + irq_opt = s502a_irq_options; + dpmbase_opt = s502a_dpmbase_options; + pclk_opt = s502a_pclk_options; + break; + + case SDLA_S502E: + hw->io_range = S502E_IORANGE; + irq_opt = s502e_irq_options; + dpmbase_opt = s508_dpmbase_options; + pclk_opt = s502e_pclk_options; + break; + + case SDLA_S503: + hw->io_range = S503_IORANGE; + irq_opt = s503_irq_options; + dpmbase_opt = s508_dpmbase_options; + pclk_opt = s503_pclk_options; + break; + + case SDLA_S507: + hw->io_range = S507_IORANGE; + irq_opt = s508_irq_options; + dpmbase_opt = s507_dpmbase_options; + pclk_opt = s507_pclk_options; + break; + + case SDLA_S508: + hw->io_range = S508_IORANGE; + irq_opt = s508_irq_options; + dpmbase_opt = s508_dpmbase_options; + pclk_opt = s508_pclk_options; + break; + } + + /* Verify IRQ configuration options */ + if (!get_option_index(irq_opt, hw->irq)) { + printk(KERN_INFO "%s: IRQ %d is invalid!\n", + modname, hw->irq); + return -EINVAL; + } + + /* Verify CPU clock rate configuration options */ + if (hw->pclk == 0) + hw->pclk = pclk_opt[1]; /* use default */ + + else if (!get_option_index(pclk_opt, hw->pclk)) { + printk(KERN_INFO "%s: CPU clock %u is invalid!\n", + modname, hw->pclk); + return -EINVAL; + } + printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n", + modname, hw->pclk); + + /* Setup adapter dual-port memory window and test memory */ + if (hw->dpmbase == 0) { + err = sdla_autodpm(hw); + if (err) { + printk(KERN_INFO + "%s: can't find available memory region!\n", + modname); + return err; + } + } + else if (!get_option_index(dpmbase_opt, + virt_to_phys(hw->dpmbase))) { + printk(KERN_INFO + "%s: memory address 0x%lX is invalid!\n", + modname, virt_to_phys(hw->dpmbase)); + return -EINVAL; + } + else if (sdla_setdpm(hw)) { + printk(KERN_INFO + "%s: 8K memory region at 0x%lX is not available!\n", + modname, virt_to_phys(hw->dpmbase)); + return -EINVAL; + } + printk(KERN_INFO + "%s: dual-port memory window is set at 0x%lX.\n", + modname, virt_to_phys(hw->dpmbase)); + + + /* If we find memory in 0xE**** Memory region, + * warn the user to disable the SHADOW RAM. + * Since memory corruption can occur if SHADOW is + * enabled. This can causes random crashes ! */ + if (virt_to_phys(hw->dpmbase) >= 0xE0000){ + printk(KERN_WARNING "\n%s: !!!!!!!! WARNING !!!!!!!!\n",modname); + printk(KERN_WARNING "%s: WANPIPE is using 0x%lX memory region !!!\n", + modname, virt_to_phys(hw->dpmbase)); + printk(KERN_WARNING " Please disable the SHADOW RAM, otherwise\n"); + printk(KERN_WARNING " your system might crash randomly from time to time !\n"); + printk(KERN_WARNING "%s: !!!!!!!! WARNING !!!!!!!!\n\n",modname); + } + } + + else { + hw->memory = test_memregion((void*)hw->dpmbase, + MAX_SIZEOF_S514_MEMORY); + if(hw->memory < (256 * 1024)) { + printk(KERN_INFO + "%s: error in testing S514 memory (0x%lX)\n", + modname, hw->memory); + sdla_down(hw); + return -EINVAL; + } + } + + printk(KERN_INFO "%s: found %luK bytes of on-board memory\n", + modname, hw->memory / 1024); + + /* Load firmware. If loader fails then shut down adapter */ + err = sdla_load(hw, sfm, len); + if (err) sdla_down(hw); /* shutdown adapter */ + + return err; +} + +/*============================================================================ + * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc. + */ + +EXPORT_SYMBOL(sdla_down); + +int sdla_down (sdlahw_t* hw) +{ + unsigned port = hw->port; + int i; + unsigned char CPU_no; + u32 int_config, int_status; + + if(!port && (hw->type != SDLA_S514)) + return -EFAULT; + + switch (hw->type) { + case SDLA_S502A: + _OUTB(port, 0x08); /* halt CPU */ + _OUTB(port, 0x08); + _OUTB(port, 0x08); + hw->regs[0] = 0x08; + _OUTB(port + 1, 0xFF); /* close memory window */ + hw->regs[1] = 0xFF; + break; + + case SDLA_S502E: + _OUTB(port + 3, 0); /* stop CPU */ + _OUTB(port, 0); /* reset board */ + for (i = 0; i < S502E_IORANGE; ++i) + hw->regs[i] = 0 + ; + break; + + case SDLA_S503: + case SDLA_S507: + case SDLA_S508: + _OUTB(port, 0); /* reset board logic */ + hw->regs[0] = 0; + break; + + case SDLA_S514: + /* halt the adapter */ + *(char *)hw->vector = S514_CPU_HALT; + CPU_no = hw->S514_cpu_no[0]; + + /* disable the PCI IRQ and disable memory access */ + pci_read_config_dword(hw->pci_dev, PCI_INT_CONFIG, &int_config); + int_config &= (CPU_no == S514_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A : ~PCI_DISABLE_IRQ_CPU_B; + pci_write_config_dword(hw->pci_dev, PCI_INT_CONFIG, int_config); + read_S514_int_stat(hw, &int_status); + S514_intack(hw, int_status); + if(CPU_no == S514_CPU_A) + pci_write_config_dword(hw->pci_dev, PCI_MAP0_DWORD, + PCI_CPU_A_MEM_DISABLE); + else + pci_write_config_dword(hw->pci_dev, PCI_MAP1_DWORD, + PCI_CPU_B_MEM_DISABLE); + + /* free up the allocated virtual memory */ + iounmap((void *)hw->dpmbase); + iounmap((void *)hw->vector); + break; + + + default: + return -EINVAL; + } + return 0; +} + +/*============================================================================ + * Map shared memory window into SDLA address space. + */ + +EXPORT_SYMBOL(sdla_mapmem); + +int sdla_mapmem (sdlahw_t* hw, unsigned long addr) +{ + unsigned port = hw->port; + register int tmp; + + switch (hw->type) { + case SDLA_S502A: + case SDLA_S502E: + if (addr < S502_MAXMEM) { /* verify parameter */ + tmp = addr >> 13; /* convert to register mask */ + _OUTB(port + 2, tmp); + hw->regs[2] = tmp; + } + else return -EINVAL; + break; + + case SDLA_S503: + if (addr < S503_MAXMEM) { /* verify parameter */ + tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70); + _OUTB(port, tmp); + hw->regs[0] = tmp; + } + else return -EINVAL; + break; + + case SDLA_S507: + if (addr < S507_MAXMEM) { + if (!(_INB(port) & 0x02)) + return -EIO; + tmp = addr >> 13; /* convert to register mask */ + _OUTB(port + 2, tmp); + hw->regs[2] = tmp; + } + else return -EINVAL; + break; + + case SDLA_S508: + if (addr < S508_MAXMEM) { + tmp = addr >> 13; /* convert to register mask */ + _OUTB(port + 2, tmp); + hw->regs[2] = tmp; + } + else return -EINVAL; + break; + + case SDLA_S514: + return 0; + + default: + return -EINVAL; + } + hw->vector = addr & 0xFFFFE000L; + return 0; +} + +/*============================================================================ + * Enable interrupt generation. + */ + +static int sdla_inten (sdlahw_t* hw) +{ + unsigned port = hw->port; + int tmp, i; + + switch (hw->type) { + case SDLA_S502E: + /* Note thar interrupt control operations on S502E are allowed + * only if CPU is enabled (bit 0 of status register is set). + */ + if (_INB(port) & 0x01) { + _OUTB(port, 0x02); /* bit1 = 1, bit2 = 0 */ + _OUTB(port, 0x06); /* bit1 = 1, bit2 = 1 */ + hw->regs[0] = 0x06; + } + else return -EIO; + break; + + case SDLA_S503: + tmp = hw->regs[0] | 0x04; + _OUTB(port, tmp); + hw->regs[0] = tmp; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (!(_INB(port) & 0x02)) /* verify */ + return -EIO; + break; + + case SDLA_S508: + tmp = hw->regs[0] | 0x10; + _OUTB(port, tmp); + hw->regs[0] = tmp; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (!(_INB(port + 1) & 0x10)) /* verify */ + return -EIO; + break; + + case SDLA_S502A: + case SDLA_S507: + break; + + case SDLA_S514: + break; + + default: + return -EINVAL; + + } + return 0; +} + +/*============================================================================ + * Disable interrupt generation. + */ + +#if 0 +int sdla_intde (sdlahw_t* hw) +{ + unsigned port = hw->port; + int tmp, i; + + switch (hw->type) { + case SDLA_S502E: + /* Notes: + * 1) interrupt control operations are allowed only if CPU is + * enabled (bit 0 of status register is set). + * 2) disabling interrupts using bit 1 of control register + * causes IRQ line go high, therefore we are going to use + * 0x04 instead: lower it to inhibit interrupts to PC. + */ + if (_INB(port) & 0x01) { + _OUTB(port, hw->regs[0] & ~0x04); + hw->regs[0] &= ~0x04; + } + else return -EIO; + break; + + case SDLA_S503: + tmp = hw->regs[0] & ~0x04; + _OUTB(port, tmp); + hw->regs[0] = tmp; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) & 0x02) /* verify */ + return -EIO; + break; + + case SDLA_S508: + tmp = hw->regs[0] & ~0x10; + _OUTB(port, tmp); + hw->regs[0] = tmp; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) & 0x10) /* verify */ + return -EIO; + break; + + case SDLA_S502A: + case SDLA_S507: + break; + + default: + return -EINVAL; + } + return 0; +} +#endif /* 0 */ + +/*============================================================================ + * Acknowledge SDLA hardware interrupt. + */ + +static int sdla_intack (sdlahw_t* hw) +{ + unsigned port = hw->port; + int tmp; + + switch (hw->type) { + case SDLA_S502E: + /* To acknoledge hardware interrupt we have to toggle bit 3 of + * control register: \_/ + * Note that interrupt control operations on S502E are allowed + * only if CPU is enabled (bit 1 of status register is set). + */ + if (_INB(port) & 0x01) { + tmp = hw->regs[0] & ~0x04; + _OUTB(port, tmp); + tmp |= 0x04; + _OUTB(port, tmp); + hw->regs[0] = tmp; + } + else return -EIO; + break; + + case SDLA_S503: + if (_INB(port) & 0x04) { + tmp = hw->regs[0] & ~0x08; + _OUTB(port, tmp); + tmp |= 0x08; + _OUTB(port, tmp); + hw->regs[0] = tmp; + } + break; + + case SDLA_S502A: + case SDLA_S507: + case SDLA_S508: + break; + + default: + return -EINVAL; + } + return 0; +} + + +/*============================================================================ + * Acknowledge S514 hardware interrupt. + */ + +EXPORT_SYMBOL(S514_intack); + +void S514_intack (sdlahw_t* hw, u32 int_status) +{ + pci_write_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status); +} + + +/*============================================================================ + * Read the S514 hardware interrupt status. + */ + +EXPORT_SYMBOL(read_S514_int_stat); + +void read_S514_int_stat (sdlahw_t* hw, u32* int_status) +{ + pci_read_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status); +} + + +/*============================================================================ + * Generate an interrupt to adapter's CPU. + */ + +#if 0 +int sdla_intr (sdlahw_t* hw) +{ + unsigned port = hw->port; + + switch (hw->type) { + case SDLA_S502A: + if (!(_INB(port) & 0x40)) { + _OUTB(port, 0x10); /* issue NMI to CPU */ + hw->regs[0] = 0x10; + } + else return -EIO; + break; + + case SDLA_S507: + if ((_INB(port) & 0x06) == 0x06) { + _OUTB(port + 3, 0); + } + else return -EIO; + break; + + case SDLA_S508: + if (_INB(port + 1) & 0x02) { + _OUTB(port, 0x08); + } + else return -EIO; + break; + + case SDLA_S502E: + case SDLA_S503: + default: + return -EINVAL; + } + return 0; +} +#endif /* 0 */ + +/*============================================================================ + * Execute Adapter Command. + * o Set exec flag. + * o Busy-wait until flag is reset. + * o Return number of loops made, or 0 if command timed out. + */ + +EXPORT_SYMBOL(sdla_exec); + +int sdla_exec (void* opflag) +{ + volatile unsigned char* flag = opflag; + unsigned long tstop; + int nloops; + + if(readb(flag) != 0x00) { + printk(KERN_INFO + "WANPIPE: opp flag set on entry to sdla_exec\n"); + return 0; + } + + writeb(0x01, flag); + + tstop = SYSTEM_TICK + EXEC_TIMEOUT; + + for (nloops = 1; (readb(flag) == 0x01); ++ nloops) { + unsigned delay = exec_idle; + while (-- delay); /* delay */ + if (SYSTEM_TICK > tstop) return 0; /* time is up! */ + } + return nloops; +} + +/*============================================================================ + * Read absolute adapter memory. + * Transfer data from adapter's memory to data buffer. + * + * Note: + * Care should be taken when crossing dual-port memory window boundary. + * This function is not atomic, so caller must disable interrupt if + * interrupt routines are accessing adapter shared memory. + */ + +EXPORT_SYMBOL(sdla_peek); + +int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len) +{ + + if (addr + len > hw->memory) /* verify arguments */ + return -EINVAL; + + if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */ + peek_by_4 ((unsigned long)hw->dpmbase + addr, buf, len); + return 0; + } + + else { /* copy data for the S508 adapter */ + unsigned long oldvec = hw->vector; + unsigned winsize = hw->dpmsize; + unsigned curpos, curlen; /* current offset and block size */ + unsigned long curvec; /* current DPM window vector */ + int err = 0; + + while (len && !err) { + curpos = addr % winsize; /* current window offset */ + curvec = addr - curpos; /* current window vector */ + curlen = (len > (winsize - curpos)) ? + (winsize - curpos) : len; + /* Relocate window and copy block of data */ + err = sdla_mapmem(hw, curvec); + peek_by_4 ((unsigned long)hw->dpmbase + curpos, buf, + curlen); + addr += curlen; + buf = (char*)buf + curlen; + len -= curlen; + } + + /* Restore DPM window position */ + sdla_mapmem(hw, oldvec); + return err; + } +} + + +/*============================================================================ + * Read data from adapter's memory to a data buffer in 4-byte chunks. + * Note that we ensure that the SDLA memory address is on a 4-byte boundary + * before we begin moving the data in 4-byte chunks. +*/ + +static void peek_by_4 (unsigned long src, void* buf, unsigned len) +{ + + /* byte copy data until we get to a 4-byte boundary */ + while (len && (src & 0x03)) { + *(char *)buf ++ = readb(src ++); + len --; + } + + /* copy data in 4-byte chunks */ + while (len >= 4) { + *(unsigned long *)buf = readl(src); + buf += 4; + src += 4; + len -= 4; + } + + /* byte copy any remaining data */ + while (len) { + *(char *)buf ++ = readb(src ++); + len --; + } +} + + +/*============================================================================ + * Write Absolute Adapter Memory. + * Transfer data from data buffer to adapter's memory. + * + * Note: + * Care should be taken when crossing dual-port memory window boundary. + * This function is not atomic, so caller must disable interrupt if + * interrupt routines are accessing adapter shared memory. + */ + +EXPORT_SYMBOL(sdla_poke); + +int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len) +{ + + if (addr + len > hw->memory) /* verify arguments */ + return -EINVAL; + + if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */ + poke_by_4 ((unsigned long)hw->dpmbase + addr, buf, len); + return 0; + } + + else { /* copy data for the S508 adapter */ + unsigned long oldvec = hw->vector; + unsigned winsize = hw->dpmsize; + unsigned curpos, curlen; /* current offset and block size */ + unsigned long curvec; /* current DPM window vector */ + int err = 0; + + while (len && !err) { + curpos = addr % winsize; /* current window offset */ + curvec = addr - curpos; /* current window vector */ + curlen = (len > (winsize - curpos)) ? + (winsize - curpos) : len; + /* Relocate window and copy block of data */ + sdla_mapmem(hw, curvec); + poke_by_4 ((unsigned long)hw->dpmbase + curpos, buf, + curlen); + addr += curlen; + buf = (char*)buf + curlen; + len -= curlen; + } + + /* Restore DPM window position */ + sdla_mapmem(hw, oldvec); + return err; + } +} + + +/*============================================================================ + * Write from a data buffer to adapter's memory in 4-byte chunks. + * Note that we ensure that the SDLA memory address is on a 4-byte boundary + * before we begin moving the data in 4-byte chunks. +*/ + +static void poke_by_4 (unsigned long dest, void* buf, unsigned len) +{ + + /* byte copy data until we get to a 4-byte boundary */ + while (len && (dest & 0x03)) { + writeb (*(char *)buf ++, dest ++); + len --; + } + + /* copy data in 4-byte chunks */ + while (len >= 4) { + writel (*(unsigned long *)buf, dest); + dest += 4; + buf += 4; + len -= 4; + } + + /* byte copy any remaining data */ + while (len) { + writeb (*(char *)buf ++ , dest ++); + len --; + } +} + + +#ifdef DONT_COMPIPLE_THIS +#endif /* DONT_COMPIPLE_THIS */ + +/****** Hardware-Specific Functions *****************************************/ + +/*============================================================================ + * Detect adapter type. + * o if adapter type is specified then call detection routine for that adapter + * type. Otherwise call detection routines for every adapter types until + * adapter is detected. + * + * Notes: + * 1) Detection tests are destructive! Adapter will be left in shutdown state + * after the test. + */ +static int sdla_detect (sdlahw_t* hw) +{ + unsigned port = hw->port; + int err = 0; + + if (!port && (hw->type != SDLA_S514)) + return -EFAULT; + + switch (hw->type) { + case SDLA_S502A: + if (!detect_s502a(port)) err = -ENODEV; + break; + + case SDLA_S502E: + if (!detect_s502e(port)) err = -ENODEV; + break; + + case SDLA_S503: + if (!detect_s503(port)) err = -ENODEV; + break; + + case SDLA_S507: + if (!detect_s507(port)) err = -ENODEV; + break; + + case SDLA_S508: + if (!detect_s508(port)) err = -ENODEV; + break; + + case SDLA_S514: + if (!detect_s514(hw)) err = -ENODEV; + break; + + default: + if (detect_s502a(port)) + hw->type = SDLA_S502A; + else if (detect_s502e(port)) + hw->type = SDLA_S502E; + else if (detect_s503(port)) + hw->type = SDLA_S503; + else if (detect_s507(port)) + hw->type = SDLA_S507; + else if (detect_s508(port)) + hw->type = SDLA_S508; + else err = -ENODEV; + } + return err; +} + +/*============================================================================ + * Autoselect memory region. + * o try all available DMP address options from the top down until success. + */ +static int sdla_autodpm (sdlahw_t* hw) +{ + int i, err = -EINVAL; + unsigned* opt; + + switch (hw->type) { + case SDLA_S502A: + opt = s502a_dpmbase_options; + break; + + case SDLA_S502E: + case SDLA_S503: + case SDLA_S508: + opt = s508_dpmbase_options; + break; + + case SDLA_S507: + opt = s507_dpmbase_options; + break; + + default: + return -EINVAL; + } + + /* Start testing from 8th position, address + * 0xC8000 from the 508 address table. + * We don't want to test A**** addresses, since + * they are usually used for Video */ + for (i = 8; i <= opt[0] && err; i++) { + hw->dpmbase = phys_to_virt(opt[i]); + err = sdla_setdpm(hw); + } + return err; +} + +/*============================================================================ + * Set up adapter dual-port memory window. + * o shut down adapter + * o make sure that no physical memory exists in this region, i.e entire + * region reads 0xFF and is not writable when adapter is shut down. + * o initialize adapter hardware + * o make sure that region is usable with SDLA card, i.e. we can write to it + * when adapter is configured. + */ +static int sdla_setdpm (sdlahw_t* hw) +{ + int err; + + /* Shut down card and verify memory region */ + sdla_down(hw); + if (check_memregion(hw->dpmbase, hw->dpmsize)) + return -EINVAL; + + /* Initialize adapter and test on-board memory segment by segment. + * If memory size appears to be less than shared memory window size, + * assume that memory region is unusable. + */ + err = sdla_init(hw); + if (err) return err; + + if (sdla_memtest(hw) < hw->dpmsize) { /* less than window size */ + sdla_down(hw); + return -EIO; + } + sdla_mapmem(hw, 0L); /* set window vector at bottom */ + return 0; +} + +/*============================================================================ + * Load adapter from the memory image of the SDLA firmware module. + * o verify firmware integrity and compatibility + * o start adapter up + */ +static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len) +{ + + int i; + + /* Verify firmware signature */ + if (strcmp(sfm->signature, SFM_SIGNATURE)) { + printk(KERN_INFO "%s: not SDLA firmware!\n", + modname); + return -EINVAL; + } + + /* Verify firmware module format version */ + if (sfm->version != SFM_VERSION) { + printk(KERN_INFO + "%s: firmware format %u rejected! Expecting %u.\n", + modname, sfm->version, SFM_VERSION); + return -EINVAL; + } + + /* Verify firmware module length and checksum */ + if ((len - offsetof(sfm_t, image) != sfm->info.codesize) || + (checksum((void*)&sfm->info, + sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum)) { + printk(KERN_INFO "%s: firmware corrupted!\n", modname); + return -EINVAL; + } + + /* Announce */ + printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname, + (sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware", + sfm->info.codeid); + + if(hw->type == SDLA_S514) + printk(KERN_INFO "%s: loading S514 adapter, CPU %c\n", + modname, hw->S514_cpu_no[0]); + + /* Scan through the list of compatible adapters and make sure our + * adapter type is listed. + */ + for (i = 0; + (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type); + ++i); + + if (i == SFM_MAX_SDLA) { + printk(KERN_INFO "%s: firmware is not compatible with S%u!\n", + modname, hw->type); + return -EINVAL; + } + + + /* Make sure there is enough on-board memory */ + if (hw->memory < sfm->info.memsize) { + printk(KERN_INFO + "%s: firmware needs %lu bytes of on-board memory!\n", + modname, sfm->info.memsize); + return -EINVAL; + } + + /* Move code onto adapter */ + if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize)) { + printk(KERN_INFO "%s: failed to load code segment!\n", + modname); + return -EIO; + } + + /* Prepare boot-time configuration data and kick-off CPU */ + sdla_bootcfg(hw, &sfm->info); + if (sdla_start(hw, sfm->info.startoffs)) { + printk(KERN_INFO "%s: Damn... Adapter won't start!\n", + modname); + return -EIO; + } + + /* position DPM window over the mailbox and enable interrupts */ + if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw)) { + printk(KERN_INFO "%s: adapter hardware failure!\n", + modname); + return -EIO; + } + hw->fwid = sfm->info.codeid; /* set firmware ID */ + return 0; +} + +/*============================================================================ + * Initialize SDLA hardware: setup memory window, IRQ, etc. + */ +static int sdla_init (sdlahw_t* hw) +{ + int i; + + for (i = 0; i < SDLA_MAXIORANGE; ++i) + hw->regs[i] = 0; + + switch (hw->type) { + case SDLA_S502A: return init_s502a(hw); + case SDLA_S502E: return init_s502e(hw); + case SDLA_S503: return init_s503(hw); + case SDLA_S507: return init_s507(hw); + case SDLA_S508: return init_s508(hw); + } + return -EINVAL; +} + +/*============================================================================ + * Test adapter on-board memory. + * o slide DPM window from the bottom up and test adapter memory segment by + * segment. + * Return adapter memory size. + */ +static unsigned long sdla_memtest (sdlahw_t* hw) +{ + unsigned long memsize; + unsigned winsize; + + for (memsize = 0, winsize = hw->dpmsize; + !sdla_mapmem(hw, memsize) && + (test_memregion(hw->dpmbase, winsize) == winsize) + ; + memsize += winsize) + ; + hw->memory = memsize; + return memsize; +} + +/*============================================================================ + * Prepare boot-time firmware configuration data. + * o position DPM window + * o initialize configuration data area + */ +static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo) +{ + unsigned char* data; + + if (!sfminfo->datasize) return 0; /* nothing to do */ + + if (sdla_mapmem(hw, sfminfo->dataoffs) != 0) + return -EIO; + + if(hw->type == SDLA_S514) + data = (void*)(hw->dpmbase + sfminfo->dataoffs); + else + data = (void*)((u8 *)hw->dpmbase + + (sfminfo->dataoffs - hw->vector)); + + memset_io (data, 0, sfminfo->datasize); + + writeb (make_config_byte(hw), &data[0x00]); + + switch (sfminfo->codeid) { + case SFID_X25_502: + case SFID_X25_508: + writeb (3, &data[0x01]); /* T1 timer */ + writeb (10, &data[0x03]); /* N2 */ + writeb (7, &data[0x06]); /* HDLC window size */ + writeb (1, &data[0x0B]); /* DTE */ + writeb (2, &data[0x0C]); /* X.25 packet window size */ + writew (128, &data[0x0D]); /* default X.25 data size */ + writew (128, &data[0x0F]); /* maximum X.25 data size */ + break; + } + return 0; +} + +/*============================================================================ + * Prepare configuration byte identifying adapter type and CPU clock rate. + */ +static unsigned char make_config_byte (sdlahw_t* hw) +{ + unsigned char byte = 0; + + switch (hw->pclk) { + case 5000: byte = 0x01; break; + case 7200: byte = 0x02; break; + case 8000: byte = 0x03; break; + case 10000: byte = 0x04; break; + case 16000: byte = 0x05; break; + } + + switch (hw->type) { + case SDLA_S502E: byte |= 0x80; break; + case SDLA_S503: byte |= 0x40; break; + } + return byte; +} + +/*============================================================================ + * Start adapter's CPU. + * o calculate a pointer to adapter's cold boot entry point + * o position DPM window + * o place boot instruction (jp addr) at cold boot entry point + * o start CPU + */ +static int sdla_start (sdlahw_t* hw, unsigned addr) +{ + unsigned port = hw->port; + unsigned char *bootp; + int err, tmp, i; + + if (!port && (hw->type != SDLA_S514)) return -EFAULT; + + switch (hw->type) { + case SDLA_S502A: + bootp = hw->dpmbase; + bootp += 0x66; + break; + + case SDLA_S502E: + case SDLA_S503: + case SDLA_S507: + case SDLA_S508: + case SDLA_S514: + bootp = hw->dpmbase; + break; + + default: + return -EINVAL; + } + + err = sdla_mapmem(hw, 0); + if (err) return err; + + writeb (0xC3, bootp); /* Z80: 'jp' opcode */ + bootp ++; + writew (addr, bootp); + + switch (hw->type) { + case SDLA_S502A: + _OUTB(port, 0x10); /* issue NMI to CPU */ + hw->regs[0] = 0x10; + break; + + case SDLA_S502E: + _OUTB(port + 3, 0x01); /* start CPU */ + hw->regs[3] = 0x01; + for (i = 0; i < SDLA_IODELAY; ++i); + if (_INB(port) & 0x01) { /* verify */ + /* + * Enabling CPU changes functionality of the + * control register, so we have to reset its + * mirror. + */ + _OUTB(port, 0); /* disable interrupts */ + hw->regs[0] = 0; + } + else return -EIO; + break; + + case SDLA_S503: + tmp = hw->regs[0] | 0x09; /* set bits 0 and 3 */ + _OUTB(port, tmp); + hw->regs[0] = tmp; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); + if (!(_INB(port) & 0x01)) /* verify */ + return -EIO; + break; + + case SDLA_S507: + tmp = hw->regs[0] | 0x02; + _OUTB(port, tmp); + hw->regs[0] = tmp; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); + if (!(_INB(port) & 0x04)) /* verify */ + return -EIO; + break; + + case SDLA_S508: + tmp = hw->regs[0] | 0x02; + _OUTB(port, tmp); + hw->regs[0] = tmp; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); + if (!(_INB(port + 1) & 0x02)) /* verify */ + return -EIO; + break; + + case SDLA_S514: + writeb (S514_CPU_START, hw->vector); + break; + + default: + return -EINVAL; + } + return 0; +} + +/*============================================================================ + * Initialize S502A adapter. + */ +static int init_s502a (sdlahw_t* hw) +{ + unsigned port = hw->port; + int tmp, i; + + if (!detect_s502a(port)) + return -ENODEV; + + hw->regs[0] = 0x08; + hw->regs[1] = 0xFF; + + /* Verify configuration options */ + i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase)); + if (i == 0) + return -EINVAL; + + tmp = s502a_hmcr[i - 1]; + switch (hw->dpmsize) { + case 0x2000: + tmp |= 0x01; + break; + + case 0x10000L: + break; + + default: + return -EINVAL; + } + + /* Setup dual-port memory window (this also enables memory access) */ + _OUTB(port + 1, tmp); + hw->regs[1] = tmp; + hw->regs[0] = 0x08; + return 0; +} + +/*============================================================================ + * Initialize S502E adapter. + */ +static int init_s502e (sdlahw_t* hw) +{ + unsigned port = hw->port; + int tmp, i; + + if (!detect_s502e(port)) + return -ENODEV; + + /* Verify configuration options */ + i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); + if (i == 0) + return -EINVAL; + + tmp = s502e_hmcr[i - 1]; + switch (hw->dpmsize) { + case 0x2000: + tmp |= 0x01; + break; + + case 0x10000L: + break; + + default: + return -EINVAL; + } + + /* Setup dual-port memory window */ + _OUTB(port + 1, tmp); + hw->regs[1] = tmp; + + /* Enable memory access */ + _OUTB(port, 0x02); + hw->regs[0] = 0x02; + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + return (_INB(port) & 0x02) ? 0 : -EIO; +} + +/*============================================================================ + * Initialize S503 adapter. + * --------------------------------------------------------------------------- + */ +static int init_s503 (sdlahw_t* hw) +{ + unsigned port = hw->port; + int tmp, i; + + if (!detect_s503(port)) + return -ENODEV; + + /* Verify configuration options */ + i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); + if (i == 0) + return -EINVAL; + + tmp = s502e_hmcr[i - 1]; + switch (hw->dpmsize) { + case 0x2000: + tmp |= 0x01; + break; + + case 0x10000L: + break; + + default: + return -EINVAL; + } + + /* Setup dual-port memory window */ + _OUTB(port + 1, tmp); + hw->regs[1] = tmp; + + /* Enable memory access */ + _OUTB(port, 0x02); + hw->regs[0] = 0x02; /* update mirror */ + return 0; +} + +/*============================================================================ + * Initialize S507 adapter. + */ +static int init_s507 (sdlahw_t* hw) +{ + unsigned port = hw->port; + int tmp, i; + + if (!detect_s507(port)) + return -ENODEV; + + /* Verify configuration options */ + i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase)); + if (i == 0) + return -EINVAL; + + tmp = s507_hmcr[i - 1]; + switch (hw->dpmsize) { + case 0x2000: + tmp |= 0x01; + break; + + case 0x10000L: + break; + + default: + return -EINVAL; + } + + /* Enable adapter's logic */ + _OUTB(port, 0x01); + hw->regs[0] = 0x01; + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (!(_INB(port) & 0x20)) + return -EIO; + + /* Setup dual-port memory window */ + _OUTB(port + 1, tmp); + hw->regs[1] = tmp; + + /* Enable memory access */ + tmp = hw->regs[0] | 0x04; + if (hw->irq) { + i = get_option_index(s508_irq_options, hw->irq); + if (i) tmp |= s507_irqmask[i - 1]; + } + _OUTB(port, tmp); + hw->regs[0] = tmp; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + return (_INB(port) & 0x08) ? 0 : -EIO; +} + +/*============================================================================ + * Initialize S508 adapter. + */ +static int init_s508 (sdlahw_t* hw) +{ + unsigned port = hw->port; + int tmp, i; + + if (!detect_s508(port)) + return -ENODEV; + + /* Verify configuration options */ + i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); + if (i == 0) + return -EINVAL; + + /* Setup memory configuration */ + tmp = s508_hmcr[i - 1]; + _OUTB(port + 1, tmp); + hw->regs[1] = tmp; + + /* Enable memory access */ + _OUTB(port, 0x04); + hw->regs[0] = 0x04; /* update mirror */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + return (_INB(port + 1) & 0x04) ? 0 : -EIO; +} + +/*============================================================================ + * Detect S502A adapter. + * Following tests are used to detect S502A adapter: + * 1. All registers other than status (BASE) should read 0xFF + * 2. After writing 00001000b to control register, status register should + * read 01000000b. + * 3. After writing 0 to control register, status register should still + * read 01000000b. + * 4. After writing 00000100b to control register, status register should + * read 01000100b. + * Return 1 if detected o.k. or 0 if failed. + * Note: This test is destructive! Adapter will be left in shutdown + * state after the test. + */ +static int detect_s502a (int port) +{ + int i, j; + + if (!get_option_index(s502_port_options, port)) + return 0; + + for (j = 1; j < SDLA_MAXIORANGE; ++j) { + if (_INB(port + j) != 0xFF) + return 0; + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + } + + _OUTB(port, 0x08); /* halt CPU */ + _OUTB(port, 0x08); + _OUTB(port, 0x08); + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) != 0x40) + return 0; + _OUTB(port, 0x00); + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) != 0x40) + return 0; + _OUTB(port, 0x04); + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) != 0x44) + return 0; + + /* Reset adapter */ + _OUTB(port, 0x08); + _OUTB(port, 0x08); + _OUTB(port, 0x08); + _OUTB(port + 1, 0xFF); + return 1; +} + +/*============================================================================ + * Detect S502E adapter. + * Following tests are used to verify adapter presence: + * 1. All registers other than status (BASE) should read 0xFF. + * 2. After writing 0 to CPU control register (BASE+3), status register + * (BASE) should read 11111000b. + * 3. After writing 00000100b to port BASE (set bit 2), status register + * (BASE) should read 11111100b. + * Return 1 if detected o.k. or 0 if failed. + * Note: This test is destructive! Adapter will be left in shutdown + * state after the test. + */ +static int detect_s502e (int port) +{ + int i, j; + + if (!get_option_index(s502_port_options, port)) + return 0; + for (j = 1; j < SDLA_MAXIORANGE; ++j) { + if (_INB(port + j) != 0xFF) + return 0; + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + } + + _OUTB(port + 3, 0); /* CPU control reg. */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) != 0xF8) /* read status */ + return 0; + _OUTB(port, 0x04); /* set bit 2 */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) != 0xFC) /* verify */ + return 0; + + /* Reset adapter */ + _OUTB(port, 0); + return 1; +} + +/*============================================================================ + * Detect s503 adapter. + * Following tests are used to verify adapter presence: + * 1. All registers other than status (BASE) should read 0xFF. + * 2. After writing 0 to control register (BASE), status register (BASE) + * should read 11110000b. + * 3. After writing 00000100b (set bit 2) to control register (BASE), + * status register should read 11110010b. + * Return 1 if detected o.k. or 0 if failed. + * Note: This test is destructive! Adapter will be left in shutdown + * state after the test. + */ +static int detect_s503 (int port) +{ + int i, j; + + if (!get_option_index(s503_port_options, port)) + return 0; + for (j = 1; j < SDLA_MAXIORANGE; ++j) { + if (_INB(port + j) != 0xFF) + return 0; + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + } + + _OUTB(port, 0); /* reset control reg.*/ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) != 0xF0) /* read status */ + return 0; + _OUTB(port, 0x04); /* set bit 2 */ + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if (_INB(port) != 0xF2) /* verify */ + return 0; + + /* Reset adapter */ + _OUTB(port, 0); + return 1; +} + +/*============================================================================ + * Detect s507 adapter. + * Following tests are used to detect s507 adapter: + * 1. All ports should read the same value. + * 2. After writing 0x00 to control register, status register should read + * ?011000?b. + * 3. After writing 0x01 to control register, status register should read + * ?011001?b. + * Return 1 if detected o.k. or 0 if failed. + * Note: This test is destructive! Adapter will be left in shutdown + * state after the test. + */ +static int detect_s507 (int port) +{ + int tmp, i, j; + + if (!get_option_index(s508_port_options, port)) + return 0; + tmp = _INB(port); + for (j = 1; j < S507_IORANGE; ++j) { + if (_INB(port + j) != tmp) + return 0; + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + } + + _OUTB(port, 0x00); + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if ((_INB(port) & 0x7E) != 0x30) + return 0; + _OUTB(port, 0x01); + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if ((_INB(port) & 0x7E) != 0x32) + return 0; + + /* Reset adapter */ + _OUTB(port, 0x00); + return 1; +} + +/*============================================================================ + * Detect s508 adapter. + * Following tests are used to detect s508 adapter: + * 1. After writing 0x00 to control register, status register should read + * ??000000b. + * 2. After writing 0x10 to control register, status register should read + * ??010000b + * Return 1 if detected o.k. or 0 if failed. + * Note: This test is destructive! Adapter will be left in shutdown + * state after the test. + */ +static int detect_s508 (int port) +{ + int i; + + if (!get_option_index(s508_port_options, port)) + return 0; + _OUTB(port, 0x00); + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if ((_INB(port + 1) & 0x3F) != 0x00) + return 0; + _OUTB(port, 0x10); + for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ + if ((_INB(port + 1) & 0x3F) != 0x10) + return 0; + + /* Reset adapter */ + _OUTB(port, 0x00); + return 1; +} + +/*============================================================================ + * Detect s514 PCI adapter. + * Return 1 if detected o.k. or 0 if failed. + * Note: This test is destructive! Adapter will be left in shutdown + * state after the test. + */ +static int detect_s514 (sdlahw_t* hw) +{ + unsigned char CPU_no, slot_no, auto_slot_cfg; + int number_S514_cards = 0; + u32 S514_mem_base_addr = 0; + u32 ut_u32; + struct pci_dev *pci_dev; + + +#ifndef CONFIG_PCI + printk(KERN_INFO "%s: Linux not compiled for PCI usage!\n", modname); + return 0; +#endif + + /* + The 'setup()' procedure in 'sdlamain.c' passes the CPU number and the + slot number defined in 'router.conf' via the 'port' definition. + */ + CPU_no = hw->S514_cpu_no[0]; + slot_no = hw->S514_slot_no; + auto_slot_cfg = hw->auto_pci_cfg; + + if (auto_slot_cfg){ + printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot=Auto\n", + modname, CPU_no); + + }else{ + printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot #%d\n", + modname, CPU_no, slot_no); + } + + /* check to see that CPU A or B has been selected in 'router.conf' */ + switch(CPU_no) { + case S514_CPU_A: + case S514_CPU_B: + break; + + default: + printk(KERN_INFO "%s: S514 CPU definition invalid.\n", + modname); + printk(KERN_INFO "Must be 'A' or 'B'\n"); + return 0; + } + + number_S514_cards = find_s514_adapter(hw, 0); + if(!number_S514_cards) + return 0; + + /* we are using a single S514 adapter with a slot of 0 so re-read the */ + /* location of this adapter */ + if((number_S514_cards == 1) && auto_slot_cfg) { + number_S514_cards = find_s514_adapter(hw, 1); + if(!number_S514_cards) { + printk(KERN_INFO "%s: Error finding PCI card\n", + modname); + return 0; + } + } + + pci_dev = hw->pci_dev; + /* read the physical memory base address */ + S514_mem_base_addr = (CPU_no == S514_CPU_A) ? + (pci_dev->resource[1].start) : + (pci_dev->resource[2].start); + + printk(KERN_INFO "%s: S514 PCI memory at 0x%X\n", + modname, S514_mem_base_addr); + if(!S514_mem_base_addr) { + if(CPU_no == S514_CPU_B) + printk(KERN_INFO "%s: CPU #B not present on the card\n", modname); + else + printk(KERN_INFO "%s: No PCI memory allocated to card\n", modname); + return 0; + } + + /* enable the PCI memory */ + pci_read_config_dword(pci_dev, + (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD, + &ut_u32); + pci_write_config_dword(pci_dev, + (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD, + (ut_u32 | PCI_MEMORY_ENABLE)); + + /* check the IRQ allocated and enable IRQ usage */ + if(!(hw->irq = pci_dev->irq)) { + printk(KERN_INFO "%s: IRQ not allocated to S514 adapter\n", + modname); + return 0; + } + + /* BUG FIX : Mar 6 2000 + * On a initial loading of the card, we must check + * and clear PCI interrupt bits, due to a reset + * problem on some other boards. i.e. An interrupt + * might be pending, even after system bootup, + * in which case, when starting wanrouter the machine + * would crash. + */ + if (init_pci_slot(hw)) + return 0; + + pci_read_config_dword(pci_dev, PCI_INT_CONFIG, &ut_u32); + ut_u32 |= (CPU_no == S514_CPU_A) ? + PCI_ENABLE_IRQ_CPU_A : PCI_ENABLE_IRQ_CPU_B; + pci_write_config_dword(pci_dev, PCI_INT_CONFIG, ut_u32); + + printk(KERN_INFO "%s: IRQ %d allocated to the S514 card\n", + modname, hw->irq); + + /* map the physical PCI memory to virtual memory */ + hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr, + (unsigned long)MAX_SIZEOF_S514_MEMORY); + /* map the physical control register memory to virtual memory */ + hw->vector = (unsigned long)ioremap( + (unsigned long)(S514_mem_base_addr + S514_CTRL_REG_BYTE), + (unsigned long)16); + + if(!hw->dpmbase || !hw->vector) { + printk(KERN_INFO "%s: PCI virtual memory allocation failed\n", + modname); + return 0; + } + + /* halt the adapter */ + writeb (S514_CPU_HALT, hw->vector); + + return 1; +} + +/*============================================================================ + * Find the S514 PCI adapter in the PCI bus. + * Return the number of S514 adapters found (0 if no adapter found). + */ +static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card) +{ + unsigned char slot_no; + int number_S514_cards = 0; + char S514_found_in_slot = 0; + u16 PCI_subsys_vendor; + + struct pci_dev *pci_dev = NULL; + + slot_no = hw->S514_slot_no; + + while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev)) + != NULL) { + + pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD, + &PCI_subsys_vendor); + + if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR) + continue; + + hw->pci_dev = pci_dev; + + if(find_first_S514_card) + return(1); + + number_S514_cards ++; + + printk(KERN_INFO + "%s: S514 card found, slot #%d (devfn 0x%X)\n", + modname, ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->devfn); + + if (hw->auto_pci_cfg){ + hw->S514_slot_no = ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK); + slot_no = hw->S514_slot_no; + + }else if (((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK) == slot_no){ + S514_found_in_slot = 1; + break; + } + } + + /* if no S514 adapter has been found, then exit */ + if (!number_S514_cards) { + printk(KERN_INFO "%s: Error, no S514 adapters found\n", modname); + return 0; + } + /* if more than one S514 card has been found, then the user must have */ /* defined a slot number so that the correct adapter is used */ + else if ((number_S514_cards > 1) && hw->auto_pci_cfg) { + printk(KERN_INFO "%s: Error, PCI Slot autodetect Failed! \n" + "%s: More than one S514 adapter found.\n" + "%s: Disable the Autodetect feature and supply\n" + "%s: the PCISLOT numbers for each card.\n", + modname,modname,modname,modname); + return 0; + } + /* if the user has specified a slot number and the S514 adapter has */ + /* not been found in that slot, then exit */ + else if (!hw->auto_pci_cfg && !S514_found_in_slot) { + printk(KERN_INFO + "%s: Error, S514 card not found in specified slot #%d\n", + modname, slot_no); + return 0; + } + + return (number_S514_cards); +} + + + +/******* Miscellaneous ******************************************************/ + +/*============================================================================ + * Calibrate SDLA memory access delay. + * Count number of idle loops made within 1 second and then calculate the + * number of loops that should be made to achive desired delay. + */ +static int calibrate_delay (int mks) +{ + unsigned int delay; + unsigned long stop; + + for (delay = 0, stop = SYSTEM_TICK + HZ; SYSTEM_TICK < stop; ++delay); + return (delay/(1000000L/mks) + 1); +} + +/*============================================================================ + * Get option's index into the options list. + * Return option's index (1 .. N) or zero if option is invalid. + */ +static int get_option_index (unsigned* optlist, unsigned optval) +{ + int i; + + for (i = 1; i <= optlist[0]; ++i) + if ( optlist[i] == optval) + return i; + return 0; +} + +/*============================================================================ + * Check memory region to see if it's available. + * Return: 0 ok. + */ +static unsigned check_memregion (void* ptr, unsigned len) +{ + volatile unsigned char* p = ptr; + + for (; len && (readb (p) == 0xFF); --len, ++p) { + writeb (0, p); /* attempt to write 0 */ + if (readb(p) != 0xFF) { /* still has to read 0xFF */ + writeb (0xFF, p);/* restore original value */ + break; /* not good */ + } + } + + return len; +} + +/*============================================================================ + * Test memory region. + * Return: size of the region that passed the test. + * Note: Region size must be multiple of 2 ! + */ +static unsigned test_memregion (void* ptr, unsigned len) +{ + volatile unsigned short* w_ptr; + unsigned len_w = len >> 1; /* region len in words */ + unsigned i; + + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + writew (0xAA55, w_ptr); + + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + if (readw (w_ptr) != 0xAA55) { + len_w = i; + break; + } + + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + writew (0x55AA, w_ptr); + + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + if (readw(w_ptr) != 0x55AA) { + len_w = i; + break; + } + + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + writew (0, w_ptr); + + return len_w << 1; +} + +/*============================================================================ + * Calculate 16-bit CRC using CCITT polynomial. + */ +static unsigned short checksum (unsigned char* buf, unsigned len) +{ + unsigned short crc = 0; + unsigned mask, flag; + + for (; len; --len, ++buf) { + for (mask = 0x80; mask; mask >>= 1) { + flag = (crc & 0x8000); + crc <<= 1; + crc |= ((*buf & mask) ? 1 : 0); + if (flag) crc ^= 0x1021; + } + } + return crc; +} + +static int init_pci_slot(sdlahw_t *hw) +{ + + u32 int_status; + int volatile found=0; + int i=0; + + /* Check if this is a very first load for a specific + * pci card. If it is, clear the interrput bits, and + * set the flag indicating that this card was initialized. + */ + + for (i=0; (iS514_slot_no){ + found=1; + break; + } + if (pci_slot_ar[i] == 0xFF){ + break; + } + } + + if (!found){ + read_S514_int_stat(hw,&int_status); + S514_intack(hw,int_status); + if (i == MAX_S514_CARDS){ + printk(KERN_INFO "%s: Critical Error !!!\n",modname); + printk(KERN_INFO + "%s: Number of Sangoma PCI cards exceeded maximum limit.\n", + modname); + printk(KERN_INFO "Please contact Sangoma Technologies\n"); + return 1; + } + pci_slot_ar[i] = hw->S514_slot_no; + } + return 0; +} + +static int pci_probe(sdlahw_t *hw) +{ + + unsigned char slot_no; + int number_S514_cards = 0; + u16 PCI_subsys_vendor; + u16 PCI_card_type; + + struct pci_dev *pci_dev = NULL; + struct pci_bus *bus = NULL; + + slot_no = 0; + + while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev)) + != NULL) { + + pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD, + &PCI_subsys_vendor); + + if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR) + continue; + + pci_read_config_word(pci_dev, PCI_CARD_TYPE, + &PCI_card_type); + + bus = pci_dev->bus; + + /* A dual cpu card can support up to 4 physical connections, + * where a single cpu card can support up to 2 physical + * connections. The FT1 card can only support a single + * connection, however we cannot distinguish between a Single + * CPU card and an FT1 card. */ + if (PCI_card_type == S514_DUAL_CPU){ + number_S514_cards += 4; + printk(KERN_INFO + "wanpipe: S514-PCI card found, cpu(s) 2, bus #%d, slot #%d, irq #%d\n", + bus->number,((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->irq); + }else{ + number_S514_cards += 2; + printk(KERN_INFO + "wanpipe: S514-PCI card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n", + bus->number,((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->irq); + } + } + + return number_S514_cards; + +} + + + +EXPORT_SYMBOL(wanpipe_hw_probe); + +unsigned wanpipe_hw_probe(void) +{ + sdlahw_t hw; + unsigned* opt = s508_port_options; + unsigned cardno=0; + int i; + + memset(&hw, 0, sizeof(hw)); + + for (i = 1; i <= opt[0]; i++) { + if (detect_s508(opt[i])){ + /* S508 card can support up to two physical links */ + cardno+=2; + printk(KERN_INFO "wanpipe: S508-ISA card found, port 0x%x\n",opt[i]); + } + } + + #ifdef CONFIG_PCI + hw.S514_slot_no = 0; + cardno += pci_probe(&hw); + #else + printk(KERN_INFO "wanpipe: Warning, Kernel not compiled for PCI support!\n"); + printk(KERN_INFO "wanpipe: PCI Hardware Probe Failed!\n"); + #endif + + return cardno; +} + +/****** End *****************************************************************/ diff --git a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c new file mode 100644 index 000000000..7a8b22a7e --- /dev/null +++ b/drivers/net/wan/sdlamain.c @@ -0,0 +1,1346 @@ +/**************************************************************************** +* sdlamain.c WANPIPE(tm) Multiprotocol WAN Link Driver. Main module. +* +* Author: Nenad Corbic +* Gideon Hack +* +* Copyright: (c) 1995-2000 Sangoma 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. +* ============================================================================ +* Dec 22, 2000 Nenad Corbic Updated for 2.4.X kernels. +* Removed the polling routine. +* Nov 13, 2000 Nenad Corbic Added hw probing on module load and dynamic +* device allocation. +* Nov 7, 2000 Nenad Corbic Fixed the Multi-Port PPP for kernels +* 2.2.16 and above. +* Aug 2, 2000 Nenad Corbic Block the Multi-Port PPP from running on +* kernels 2.2.16 or greater. The SyncPPP +* has changed. +* Jul 25, 2000 Nenad Corbic Updated the Piggiback support for MultPPPP. +* Jul 13, 2000 Nenad Corbic Added Multi-PPP support. +* Feb 02, 2000 Nenad Corbic Fixed up piggyback probing and selection. +* Sep 23, 1999 Nenad Corbic Added support for SMP +* Sep 13, 1999 Nenad Corbic Each port is treated as a separate device. +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. +* Updates for Linux 2.2.X kernels. +* Sep 17, 1998 Jaspreet Singh Updated for 2.1.121+ kernel +* Nov 28, 1997 Jaspreet Singh Changed DRV_RELEASE to 1 +* Nov 10, 1997 Jaspreet Singh Changed sti() to restore_flags(); +* Nov 06, 1997 Jaspreet Singh Changed DRV_VERSION to 4 and DRV_RELEASE to 0 +* Oct 20, 1997 Jaspreet Singh Modified sdla_isr routine so that card->in_isr +* assignments are taken out and placed in the +* sdla_ppp.c, sdla_fr.c and sdla_x25.c isr +* routines. Took out 'wandev->tx_int_enabled' and +* replaced it with 'wandev->enable_tx_int'. +* May 29, 1997 Jaspreet Singh Flow Control Problem +* added "wandev->tx_int_enabled=1" line in the +* init module. This line initializes the flag for +* preventing Interrupt disabled with device set to +* busy +* Jan 15, 1997 Gene Kozin Version 3.1.0 +* o added UDP management stuff +* Jan 02, 1997 Gene Kozin Initial version. +*****************************************************************************/ + +#include /* OS configuration options */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include +#include /* kmalloc(), kfree() */ +#include /* printk(), and other useful stuff */ +#include /* support for loadable modules */ +#include /* request_region(), release_region() */ +#include /* WAN router definitions */ +#include /* WANPIPE common user API definitions */ +#include + +#include +#include /* phys_to_virt() */ +#include +#include +#include + +#include /* kernel <-> user copy */ +#include + +#include +#include + +#define KMEM_SAFETYZONE 8 + + +#ifndef CONFIG_WANPIPE_FR + #define wpf_init(a,b) (-EPROTONOSUPPORT) +#endif + +#ifndef CONFIG_WANPIPE_CHDLC + #define wpc_init(a,b) (-EPROTONOSUPPORT) +#endif + +#ifndef CONFIG_WANPIPE_X25 + #define wpx_init(a,b) (-EPROTONOSUPPORT) +#endif + +#ifndef CONFIG_WANPIPE_PPP + #define wpp_init(a,b) (-EPROTONOSUPPORT) +#endif + +#ifndef CONFIG_WANPIPE_MULTPPP + #define wsppp_init(a,b) (-EPROTONOSUPPORT) +#endif + + +/***********FOR DEBUGGING PURPOSES********************************************* +static void * dbg_kmalloc(unsigned int size, int prio, int line) { + int i = 0; + void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio); + char * c1 = v; + c1 += sizeof(unsigned int); + *((unsigned int *)v) = size; + + for (i = 0; i < KMEM_SAFETYZONE; i++) { + c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D'; + c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F'; + c1 += 8; + } + c1 += size; + for (i = 0; i < KMEM_SAFETYZONE; i++) { + c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G'; + c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L'; + c1 += 8; + } + v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8; + printk(KERN_INFO "line %d kmalloc(%d,%d) = %p\n",line,size,prio,v); + return v; +} +static void dbg_kfree(void * v, int line) { + unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8)); + unsigned int size = *sp; + char * c1 = ((char *)v) - KMEM_SAFETYZONE*8; + int i = 0; + for (i = 0; i < KMEM_SAFETYZONE; i++) { + if ( c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D' + || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') { + printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v); + printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8, + c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] ); + } + c1 += 8; + } + c1 += size; + for (i = 0; i < KMEM_SAFETYZONE; i++) { + if ( c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G' + || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L' + ) { + printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v); + printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8, + c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] ); + } + c1 += 8; + } + printk(KERN_INFO "line %d kfree(%p)\n",line,v); + v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8); + kfree(v); +} + +#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__) +#define kfree(x) dbg_kfree(x,__LINE__) +******************************************************************************/ + + + +/****** Defines & Macros ****************************************************/ + +#ifdef _DEBUG_ +#define STATIC +#else +#define STATIC static +#endif + +#define DRV_VERSION 5 /* version number */ +#define DRV_RELEASE 0 /* release (minor version) number */ +#define MAX_CARDS 16 /* max number of adapters */ + +#ifndef CONFIG_WANPIPE_CARDS /* configurable option */ +#define CONFIG_WANPIPE_CARDS 1 +#endif + +#define CMD_OK 0 /* normal firmware return code */ +#define CMD_TIMEOUT 0xFF /* firmware command timed out */ +#define MAX_CMD_RETRY 10 /* max number of firmware retries */ +/****** Function Prototypes *************************************************/ + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +/* WAN link driver entry points */ +static int setup(struct wan_device* wandev, wandev_conf_t* conf); +static int shutdown(struct wan_device* wandev); +static int ioctl(struct wan_device* wandev, unsigned cmd, unsigned long arg); + +/* IOCTL handlers */ +static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump); +static int ioctl_exec (sdla_t* card, sdla_exec_t* u_exec, int); + +/* Miscellaneous functions */ +STATIC irqreturn_t sdla_isr (int irq, void* dev_id, struct pt_regs *regs); +static void release_hw (sdla_t *card); + +static int check_s508_conflicts (sdla_t* card,wandev_conf_t* conf, int*); +static int check_s514_conflicts (sdla_t* card,wandev_conf_t* conf, int*); + + +/****** Global Data ********************************************************** + * Note: All data must be explicitly initialized!!! + */ + +/* private data */ +static char drvname[] = "wanpipe"; +static char fullname[] = "WANPIPE(tm) Multiprotocol Driver"; +static char copyright[] = "(c) 1995-2000 Sangoma Technologies Inc."; +static int ncards; +static sdla_t* card_array; /* adapter data space */ + +/* Wanpipe's own workqueue, used for all API's. + * All protocol specific tasks will be inserted + * into the "wanpipe_wq" workqueue. + + * The kernel workqueue mechanism will execute + * all pending tasks in the "wanpipe_wq" workqueue. + */ + +struct workqueue_struct *wanpipe_wq; +DECLARE_WORK(wanpipe_work, NULL, NULL); + +static int wanpipe_bh_critical; + +/******* Kernel Loadable Module Entry Points ********************************/ + +/*============================================================================ + * Module 'insert' entry point. + * o print announcement + * o allocate adapter data space + * o initialize static data + * o register all cards with WAN router + * o calibrate SDLA shared memory access delay. + * + * Return: 0 Ok + * < 0 error. + * Context: process + */ + +static int __init wanpipe_init(void) +{ + int cnt, err = 0; + + printk(KERN_INFO "%s v%u.%u %s\n", + fullname, DRV_VERSION, DRV_RELEASE, copyright); + + wanpipe_wq = create_workqueue("wanpipe_wq"); + if (!wanpipe_wq) + return -ENOMEM; + + /* Probe for wanpipe cards and return the number found */ + printk(KERN_INFO "wanpipe: Probing for WANPIPE hardware.\n"); + ncards = wanpipe_hw_probe(); + if (ncards){ + printk(KERN_INFO "wanpipe: Allocating maximum %i devices: wanpipe%i - wanpipe%i.\n",ncards,1,ncards); + }else{ + printk(KERN_INFO "wanpipe: No S514/S508 cards found, unloading modules!\n"); + destroy_workqueue(wanpipe_wq); + return -ENODEV; + } + + /* Verify number of cards and allocate adapter data space */ + card_array = kmalloc(sizeof(sdla_t) * ncards, GFP_KERNEL); + if (card_array == NULL) { + destroy_workqueue(wanpipe_wq); + return -ENOMEM; + } + + memset(card_array, 0, sizeof(sdla_t) * ncards); + + /* Register adapters with WAN router */ + for (cnt = 0; cnt < ncards; ++ cnt) { + sdla_t* card = &card_array[cnt]; + struct wan_device* wandev = &card->wandev; + + card->next = NULL; + sprintf(card->devname, "%s%d", drvname, cnt + 1); + wandev->magic = ROUTER_MAGIC; + wandev->name = card->devname; + wandev->private = card; + wandev->enable_tx_int = 0; + wandev->setup = &setup; + wandev->shutdown = &shutdown; + wandev->ioctl = &ioctl; + err = register_wan_device(wandev); + if (err) { + printk(KERN_INFO + "%s: %s registration failed with error %d!\n", + drvname, card->devname, err); + break; + } + } + if (cnt){ + ncards = cnt; /* adjust actual number of cards */ + }else { + kfree(card_array); + destroy_workqueue(wanpipe_wq); + printk(KERN_INFO "IN Init Module: NO Cards registered\n"); + err = -ENODEV; + } + + return err; +} + +/*============================================================================ + * Module 'remove' entry point. + * o unregister all adapters from the WAN router + * o release all remaining system resources + */ +static void __exit wanpipe_cleanup(void) +{ + int i; + + if (!ncards) + return; + + for (i = 0; i < ncards; ++i) { + sdla_t* card = &card_array[i]; + unregister_wan_device(card->devname); + } + destroy_workqueue(wanpipe_wq); + kfree(card_array); + + printk(KERN_INFO "\nwanpipe: WANPIPE Modules Unloaded.\n"); +} + +module_init(wanpipe_init); +module_exit(wanpipe_cleanup); + +/******* WAN Device Driver Entry Points *************************************/ + +/*============================================================================ + * Setup/configure WAN link driver. + * o check adapter state + * o make sure firmware is present in configuration + * o make sure I/O port and IRQ are specified + * o make sure I/O region is available + * o allocate interrupt vector + * o setup SDLA hardware + * o call appropriate routine to perform protocol-specific initialization + * o mark I/O region as used + * o if this is the first active card, then schedule background task + * + * This function is called when router handles ROUTER_SETUP IOCTL. The + * configuration structure is in kernel memory (including extended data, if + * any). + */ + +static int setup(struct wan_device* wandev, wandev_conf_t* conf) +{ + sdla_t* card; + int err = 0; + int irq=0; + + /* Sanity checks */ + if ((wandev == NULL) || (wandev->private == NULL) || (conf == NULL)){ + printk(KERN_INFO + "%s: Failed Sdlamain Setup wandev %u, card %u, conf %u !\n", + wandev->name, + (unsigned int)wandev,(unsigned int)wandev->private, + (unsigned int)conf); + return -EFAULT; + } + + printk(KERN_INFO "%s: Starting WAN Setup\n", wandev->name); + + card = wandev->private; + if (wandev->state != WAN_UNCONFIGURED){ + printk(KERN_INFO "%s: failed sdlamain setup, busy!\n", + wandev->name); + return -EBUSY; /* already configured */ + } + + printk(KERN_INFO "\nProcessing WAN device %s...\n", wandev->name); + + /* Initialize the counters for each wandev + * Used for counting number of times new_if and + * del_if get called. + */ + wandev->del_if_cnt = 0; + wandev->new_if_cnt = 0; + wandev->config_id = conf->config_id; + + if (!conf->data_size || (conf->data == NULL)) { + printk(KERN_INFO + "%s: firmware not found in configuration data!\n", + wandev->name); + return -EINVAL; + } + + /* Check for resource conflicts and setup the + * card for piggibacking if necessary */ + if(!conf->S514_CPU_no[0]) { + if ((err=check_s508_conflicts(card,conf,&irq)) != 0){ + return err; + } + }else { + if ((err=check_s514_conflicts(card,conf,&irq)) != 0){ + return err; + } + } + + /* If the current card has already been configured + * or it's a piggyback card, do not try to allocate + * resources. + */ + if (!card->wandev.piggyback && !card->configured){ + + /* Configure hardware, load firmware, etc. */ + memset(&card->hw, 0, sizeof(sdlahw_t)); + + /* for an S514 adapter, pass the CPU number and the slot number read */ + /* from 'router.conf' to the 'sdla_setup()' function via the 'port' */ + /* parameter */ + if (conf->S514_CPU_no[0]){ + + card->hw.S514_cpu_no[0] = conf->S514_CPU_no[0]; + card->hw.S514_slot_no = conf->PCI_slot_no; + card->hw.auto_pci_cfg = conf->auto_pci_cfg; + + if (card->hw.auto_pci_cfg == WANOPT_YES){ + printk(KERN_INFO "%s: Setting CPU to %c and Slot to Auto\n", + card->devname, card->hw.S514_cpu_no[0]); + }else{ + printk(KERN_INFO "%s: Setting CPU to %c and Slot to %i\n", + card->devname, card->hw.S514_cpu_no[0], card->hw.S514_slot_no); + } + + }else{ + /* 508 Card io port and irq initialization */ + card->hw.port = conf->ioport; + card->hw.irq = (conf->irq == 9) ? 2 : conf->irq; + } + + + /* Compute the virtual address of the card in kernel space */ + if(conf->maddr){ + card->hw.dpmbase = phys_to_virt(conf->maddr); + }else{ + card->hw.dpmbase = (void *)conf->maddr; + } + + card->hw.dpmsize = SDLA_WINDOWSIZE; + + /* set the adapter type if using an S514 adapter */ + card->hw.type = (conf->S514_CPU_no[0]) ? SDLA_S514 : conf->hw_opt[0]; + card->hw.pclk = conf->hw_opt[1]; + + err = sdla_setup(&card->hw, conf->data, conf->data_size); + if (err){ + printk(KERN_INFO "%s: Hardware setup Failed %i\n", + card->devname,err); + return err; + } + + if(card->hw.type != SDLA_S514) + irq = (conf->irq == 2) ? 9 : conf->irq; /* IRQ2 -> IRQ9 */ + else + irq = card->hw.irq; + + /* request an interrupt vector - note that interrupts may be shared */ + /* when using the S514 PCI adapter */ + + if(request_irq(irq, sdla_isr, + (card->hw.type == SDLA_S514) ? SA_SHIRQ : 0, + wandev->name, card)){ + + printk(KERN_INFO "%s: Can't reserve IRQ %d!\n", wandev->name, irq); + return -EINVAL; + } + + }else{ + printk(KERN_INFO "%s: Card Configured %lu or Piggybacking %i!\n", + wandev->name,card->configured,card->wandev.piggyback); + } + + + if (!card->configured){ + + /* Initialize the Spin lock */ + printk(KERN_INFO "%s: Initializing for SMP\n",wandev->name); + + /* Piggyback spin lock has already been initialized, + * in check_s514/s508_conflicts() */ + if (!card->wandev.piggyback){ + spin_lock_init(&card->wandev.lock); + } + + /* Intialize WAN device data space */ + wandev->irq = irq; + wandev->dma = 0; + if(card->hw.type != SDLA_S514){ + wandev->ioport = card->hw.port; + }else{ + wandev->S514_cpu_no[0] = card->hw.S514_cpu_no[0]; + wandev->S514_slot_no = card->hw.S514_slot_no; + } + wandev->maddr = (unsigned long)card->hw.dpmbase; + wandev->msize = card->hw.dpmsize; + wandev->hw_opt[0] = card->hw.type; + wandev->hw_opt[1] = card->hw.pclk; + wandev->hw_opt[2] = card->hw.memory; + wandev->hw_opt[3] = card->hw.fwid; + } + + /* Protocol-specific initialization */ + switch (card->hw.fwid) { + + case SFID_X25_502: + case SFID_X25_508: + printk(KERN_INFO "%s: Starting X.25 Protocol Init.\n", + card->devname); + err = wpx_init(card, conf); + break; + case SFID_FR502: + case SFID_FR508: + printk(KERN_INFO "%s: Starting Frame Relay Protocol Init.\n", + card->devname); + err = wpf_init(card, conf); + break; + case SFID_PPP502: + case SFID_PPP508: + printk(KERN_INFO "%s: Starting PPP Protocol Init.\n", + card->devname); + err = wpp_init(card, conf); + break; + + case SFID_CHDLC508: + case SFID_CHDLC514: + if (conf->ft1){ + printk(KERN_INFO "%s: Starting FT1 CSU/DSU Config Driver.\n", + card->devname); + err = wpft1_init(card, conf); + break; + + }else if (conf->config_id == WANCONFIG_MPPP){ + printk(KERN_INFO "%s: Starting Multi-Port PPP Protocol Init.\n", + card->devname); + err = wsppp_init(card,conf); + break; + + }else{ + printk(KERN_INFO "%s: Starting CHDLC Protocol Init.\n", + card->devname); + err = wpc_init(card, conf); + break; + } + default: + printk(KERN_INFO "%s: Error, Firmware is not supported %X %X!\n", + wandev->name,card->hw.fwid,SFID_CHDLC508); + err = -EPROTONOSUPPORT; + } + + if (err != 0){ + if (err == -EPROTONOSUPPORT){ + printk(KERN_INFO + "%s: Error, Protocol selected has not been compiled!\n", + card->devname); + printk(KERN_INFO + "%s: Re-configure the kernel and re-build the modules!\n", + card->devname); + } + + release_hw(card); + wandev->state = WAN_UNCONFIGURED; + return err; + } + + + /* Reserve I/O region and schedule background task */ + if(card->hw.type != SDLA_S514 && !card->wandev.piggyback) + if (!request_region(card->hw.port, card->hw.io_range, + wandev->name)) { + printk(KERN_WARNING "port 0x%04x busy\n", card->hw.port); + release_hw(card); + wandev->state = WAN_UNCONFIGURED; + return -EBUSY; + } + + /* Only use the polling routine for the X25 protocol */ + + card->wandev.critical=0; + return 0; +} + +/*================================================================== + * configure_s508_card + * + * For a S508 adapter, check for a possible configuration error in that + * we are loading an adapter in the same IO port as a previously loaded S508 + * card. + */ + +static int check_s508_conflicts (sdla_t* card,wandev_conf_t* conf, int *irq) +{ + unsigned long smp_flags; + int i; + + if (conf->ioport <= 0) { + printk(KERN_INFO + "%s: can't configure without I/O port address!\n", + card->wandev.name); + return -EINVAL; + } + + if (conf->irq <= 0) { + printk(KERN_INFO "%s: can't configure without IRQ!\n", + card->wandev.name); + return -EINVAL; + } + + if (test_bit(0,&card->configured)) + return 0; + + + /* Check for already loaded card with the same IO port and IRQ + * If found, copy its hardware configuration and use its + * resources (i.e. piggybacking) + */ + + for (i = 0; i < ncards; i++) { + sdla_t *nxt_card = &card_array[i]; + + /* Skip the current card ptr */ + if (nxt_card == card) + continue; + + + /* Find a card that is already configured with the + * same IO Port */ + if ((nxt_card->hw.type == SDLA_S508) && + (nxt_card->hw.port == conf->ioport) && + (nxt_card->next == NULL)){ + + /* We found a card the card that has same configuration + * as us. This means, that we must setup this card in + * piggibacking mode. However, only CHDLC and MPPP protocol + * support this setup */ + + if ((conf->config_id == WANCONFIG_CHDLC || + conf->config_id == WANCONFIG_MPPP) && + (nxt_card->wandev.config_id == WANCONFIG_CHDLC || + nxt_card->wandev.config_id == WANCONFIG_MPPP)){ + + *irq = nxt_card->hw.irq; + memcpy(&card->hw, &nxt_card->hw, sizeof(sdlahw_t)); + + /* The master could already be running, we must + * set this as a critical area */ + lock_adapter_irq(&nxt_card->wandev.lock, &smp_flags); + + nxt_card->next = card; + card->next = nxt_card; + + card->wandev.piggyback = WANOPT_YES; + + /* We must initialise the piggiback spin lock here + * since isr will try to lock card->next if it + * exists */ + spin_lock_init(&card->wandev.lock); + + unlock_adapter_irq(&nxt_card->wandev.lock, &smp_flags); + break; + }else{ + /* Trying to run piggibacking with a wrong protocol */ + printk(KERN_INFO "%s: ERROR: Resource busy, ioport: 0x%x\n" + "%s: This protocol doesn't support\n" + "%s: multi-port operation!\n", + card->devname,nxt_card->hw.port, + card->devname,card->devname); + return -EEXIST; + } + } + } + + + /* Make sure I/O port region is available only if we are the + * master device. If we are running in piggybacking mode, + * we will use the resources of the master card. */ + if (!card->wandev.piggyback) { + struct resource *rr = + request_region(conf->ioport, SDLA_MAXIORANGE, "sdlamain"); + release_region(conf->ioport, SDLA_MAXIORANGE); + + if (!rr) { + printk(KERN_INFO + "%s: I/O region 0x%X - 0x%X is in use!\n", + card->wandev.name, conf->ioport, + conf->ioport + SDLA_MAXIORANGE - 1); + return -EINVAL; + } + } + + return 0; +} + +/*================================================================== + * configure_s514_card + * + * For a S514 adapter, check for a possible configuration error in that + * we are loading an adapter in the same slot as a previously loaded S514 + * card. + */ + + +static int check_s514_conflicts(sdla_t* card,wandev_conf_t* conf, int *irq) +{ + unsigned long smp_flags; + int i; + + if (test_bit(0,&card->configured)) + return 0; + + + /* Check for already loaded card with the same IO port and IRQ + * If found, copy its hardware configuration and use its + * resources (i.e. piggybacking) + */ + + for (i = 0; i < ncards; i ++) { + + sdla_t* nxt_card = &card_array[i]; + if(nxt_card == card) + continue; + + if((nxt_card->hw.type == SDLA_S514) && + (nxt_card->hw.S514_slot_no == conf->PCI_slot_no) && + (nxt_card->hw.S514_cpu_no[0] == conf->S514_CPU_no[0])&& + (nxt_card->next == NULL)){ + + + if ((conf->config_id == WANCONFIG_CHDLC || + conf->config_id == WANCONFIG_MPPP) && + (nxt_card->wandev.config_id == WANCONFIG_CHDLC || + nxt_card->wandev.config_id == WANCONFIG_MPPP)){ + + *irq = nxt_card->hw.irq; + memcpy(&card->hw, &nxt_card->hw, sizeof(sdlahw_t)); + + /* The master could already be running, we must + * set this as a critical area */ + lock_adapter_irq(&nxt_card->wandev.lock,&smp_flags); + nxt_card->next = card; + card->next = nxt_card; + + card->wandev.piggyback = WANOPT_YES; + + /* We must initialise the piggiback spin lock here + * since isr will try to lock card->next if it + * exists */ + spin_lock_init(&card->wandev.lock); + + unlock_adapter_irq(&nxt_card->wandev.lock,&smp_flags); + + }else{ + /* Trying to run piggibacking with a wrong protocol */ + printk(KERN_INFO "%s: ERROR: Resource busy: CPU %c PCISLOT %i\n" + "%s: This protocol doesn't support\n" + "%s: multi-port operation!\n", + card->devname, + conf->S514_CPU_no[0],conf->PCI_slot_no, + card->devname,card->devname); + return -EEXIST; + } + } + } + + return 0; +} + + + +/*============================================================================ + * Shut down WAN link driver. + * o shut down adapter hardware + * o release system resources. + * + * This function is called by the router when device is being unregistered or + * when it handles ROUTER_DOWN IOCTL. + */ +static int shutdown(struct wan_device* wandev) +{ + sdla_t *card; + int err=0; + + /* sanity checks */ + if ((wandev == NULL) || (wandev->private == NULL)){ + return -EFAULT; + } + + if (wandev->state == WAN_UNCONFIGURED){ + return 0; + } + + card = wandev->private; + + if (card->tty_opt){ + if (card->tty_open){ + printk(KERN_INFO + "%s: Shutdown Failed: TTY is still open\n", + card->devname); + return -EBUSY; + } + } + + wandev->state = WAN_UNCONFIGURED; + + set_bit(PERI_CRIT,(void*)&wandev->critical); + + /* In case of piggibacking, make sure that + * we never try to shutdown both devices at the same + * time, because they depend on one another */ + + if (card->disable_comm){ + card->disable_comm(card); + } + + /* Release Resources */ + release_hw(card); + + /* only free the allocated I/O range if not an S514 adapter */ + if (wandev->hw_opt[0] != SDLA_S514 && !card->configured){ + release_region(card->hw.port, card->hw.io_range); + } + + if (!card->configured){ + memset(&card->hw, 0, sizeof(sdlahw_t)); + if (card->next){ + memset(&card->next->hw, 0, sizeof(sdlahw_t)); + } + } + + + clear_bit(PERI_CRIT,(void*)&wandev->critical); + return err; +} + +static void release_hw (sdla_t *card) +{ + sdla_t *nxt_card; + + + /* Check if next device exists */ + if (card->next){ + nxt_card = card->next; + /* If next device is down then release resources */ + if (nxt_card->wandev.state == WAN_UNCONFIGURED){ + if (card->wandev.piggyback){ + /* If this device is piggyback then use + * information of the master device + */ + printk(KERN_INFO "%s: Piggyback shutting down\n",card->devname); + sdla_down(&card->next->hw); + free_irq(card->wandev.irq, card->next); + card->configured = 0; + card->next->configured = 0; + card->wandev.piggyback = 0; + }else{ + /* Master device shutting down */ + printk(KERN_INFO "%s: Master shutting down\n",card->devname); + sdla_down(&card->hw); + free_irq(card->wandev.irq, card); + card->configured = 0; + card->next->configured = 0; + } + }else{ + printk(KERN_INFO "%s: Device still running %i\n", + nxt_card->devname,nxt_card->wandev.state); + + card->configured = 1; + } + }else{ + printk(KERN_INFO "%s: Master shutting down\n",card->devname); + sdla_down(&card->hw); + free_irq(card->wandev.irq, card); + card->configured = 0; + } + return; +} + + +/*============================================================================ + * Driver I/O control. + * o verify arguments + * o perform requested action + * + * This function is called when router handles one of the reserved user + * IOCTLs. Note that 'arg' stil points to user address space. + */ +static int ioctl(struct wan_device* wandev, unsigned cmd, unsigned long arg) +{ + sdla_t* card; + int err; + + /* sanity checks */ + if ((wandev == NULL) || (wandev->private == NULL)) + return -EFAULT; + if (wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + card = wandev->private; + + if(card->hw.type != SDLA_S514){ + disable_irq(card->hw.irq); + } + + if (test_bit(SEND_CRIT, (void*)&wandev->critical)) { + return -EAGAIN; + } + + switch (cmd) { + case WANPIPE_DUMP: + err = ioctl_dump(wandev->private, (void*)arg); + break; + + case WANPIPE_EXEC: + err = ioctl_exec(wandev->private, (void*)arg, cmd); + break; + default: + err = -EINVAL; + } + + return err; +} + +/****** Driver IOCTL Handlers ***********************************************/ + +/*============================================================================ + * Dump adapter memory to user buffer. + * o verify request structure + * o copy request structure to kernel data space + * o verify length/offset + * o verify user buffer + * o copy adapter memory image to user buffer + * + * Note: when dumping memory, this routine switches curent dual-port memory + * vector, so care must be taken to avoid racing conditions. + */ +static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump) +{ + sdla_dump_t dump; + unsigned winsize; + unsigned long oldvec; /* DPM window vector */ + unsigned long smp_flags; + int err = 0; + + if(copy_from_user((void*)&dump, (void*)u_dump, sizeof(sdla_dump_t))) + return -EFAULT; + + if ((dump.magic != WANPIPE_MAGIC) || + (dump.offset + dump.length > card->hw.memory)) + return -EINVAL; + + winsize = card->hw.dpmsize; + + if(card->hw.type != SDLA_S514) { + + lock_adapter_irq(&card->wandev.lock, &smp_flags); + + oldvec = card->hw.vector; + while (dump.length) { + /* current offset */ + unsigned pos = dump.offset % winsize; + /* current vector */ + unsigned long vec = dump.offset - pos; + unsigned len = (dump.length > (winsize - pos)) ? + (winsize - pos) : dump.length; + /* relocate window */ + if (sdla_mapmem(&card->hw, vec) != 0) { + err = -EIO; + break; + } + + if(copy_to_user((void *)dump.ptr, + (u8 *)card->hw.dpmbase + pos, len)){ + + unlock_adapter_irq(&card->wandev.lock, &smp_flags); + return -EFAULT; + } + + dump.length -= len; + dump.offset += len; + dump.ptr = (char*)dump.ptr + len; + } + + sdla_mapmem(&card->hw, oldvec);/* restore DPM window position */ + unlock_adapter_irq(&card->wandev.lock, &smp_flags); + + }else { + + if(copy_to_user((void *)dump.ptr, + (u8 *)card->hw.dpmbase + dump.offset, dump.length)){ + return -EFAULT; + } + } + + return err; +} + +/*============================================================================ + * Execute adapter firmware command. + * o verify request structure + * o copy request structure to kernel data space + * o call protocol-specific 'exec' function + */ +static int ioctl_exec (sdla_t* card, sdla_exec_t* u_exec, int cmd) +{ + sdla_exec_t exec; + int err=0; + + if (card->exec == NULL && cmd == WANPIPE_EXEC){ + return -ENODEV; + } + + if(copy_from_user((void*)&exec, (void*)u_exec, sizeof(sdla_exec_t))) + return -EFAULT; + + if ((exec.magic != WANPIPE_MAGIC) || (exec.cmd == NULL)) + return -EINVAL; + + switch (cmd) { + case WANPIPE_EXEC: + err = card->exec(card, exec.cmd, exec.data); + break; + } + return err; +} + +/******* Miscellaneous ******************************************************/ + +/*============================================================================ + * SDLA Interrupt Service Routine. + * o acknowledge SDLA hardware interrupt. + * o call protocol-specific interrupt service routine, if any. + */ +STATIC irqreturn_t sdla_isr (int irq, void* dev_id, struct pt_regs *regs) +{ +#define card ((sdla_t*)dev_id) + + if(card->hw.type == SDLA_S514) { /* handle interrrupt on S514 */ + u32 int_status; + unsigned char CPU_no = card->hw.S514_cpu_no[0]; + unsigned char card_found_for_IRQ; + u8 IRQ_count = 0; + + for(;;) { + + read_S514_int_stat(&card->hw, &int_status); + + /* check if the interrupt is for this device */ + if(!((unsigned char)int_status & + (IRQ_CPU_A | IRQ_CPU_B))) + return IRQ_HANDLED; + + /* if the IRQ is for both CPUs on the same adapter, */ + /* then alter the interrupt status so as to handle */ + /* one CPU at a time */ + if(((unsigned char)int_status & (IRQ_CPU_A | IRQ_CPU_B)) + == (IRQ_CPU_A | IRQ_CPU_B)) { + int_status &= (CPU_no == S514_CPU_A) ? + ~IRQ_CPU_B : ~IRQ_CPU_A; + } + + card_found_for_IRQ = 0; + + /* check to see that the CPU number for this device */ + /* corresponds to the interrupt status read */ + switch (CPU_no) { + case S514_CPU_A: + if((unsigned char)int_status & + IRQ_CPU_A) + card_found_for_IRQ = 1; + break; + + case S514_CPU_B: + if((unsigned char)int_status & + IRQ_CPU_B) + card_found_for_IRQ = 1; + break; + } + + /* exit if the interrupt is for another CPU on the */ + /* same IRQ */ + if(!card_found_for_IRQ) + return IRQ_HANDLED; + + if (!card || + (card->wandev.state == WAN_UNCONFIGURED && !card->configured)){ + printk(KERN_INFO + "Received IRQ %d for CPU #%c\n", + irq, CPU_no); + printk(KERN_INFO + "IRQ for unconfigured adapter\n"); + S514_intack(&card->hw, int_status); + return IRQ_HANDLED; + } + + if (card->in_isr) { + printk(KERN_INFO + "%s: interrupt re-entrancy on IRQ %d\n", + card->devname, card->wandev.irq); + S514_intack(&card->hw, int_status); + return IRQ_HANDLED; + } + + spin_lock(&card->wandev.lock); + if (card->next){ + spin_lock(&card->next->wandev.lock); + } + + S514_intack(&card->hw, int_status); + if (card->isr) + card->isr(card); + + if (card->next){ + spin_unlock(&card->next->wandev.lock); + } + spin_unlock(&card->wandev.lock); + + /* handle a maximum of two interrupts (one for each */ + /* CPU on the adapter) before returning */ + if((++ IRQ_count) == 2) + return IRQ_HANDLED; + } + } + + else { /* handle interrupt on S508 adapter */ + + if (!card || ((card->wandev.state == WAN_UNCONFIGURED) && !card->configured)) + return IRQ_HANDLED; + + if (card->in_isr) { + printk(KERN_INFO + "%s: interrupt re-entrancy on IRQ %d!\n", + card->devname, card->wandev.irq); + return IRQ_HANDLED; + } + + spin_lock(&card->wandev.lock); + if (card->next){ + spin_lock(&card->next->wandev.lock); + } + + sdla_intack(&card->hw); + if (card->isr) + card->isr(card); + + if (card->next){ + spin_unlock(&card->next->wandev.lock); + } + spin_unlock(&card->wandev.lock); + + } + return IRQ_HANDLED; +#undef card +} + +/*============================================================================ + * This routine is called by the protocol-specific modules when network + * interface is being open. The only reason we need this, is because we + * have to call MOD_INC_USE_COUNT, but cannot include 'module.h' where it's + * defined more than once into the same kernel module. + */ +void wanpipe_open (sdla_t* card) +{ + ++card->open_cnt; +} + +/*============================================================================ + * This routine is called by the protocol-specific modules when network + * interface is being closed. The only reason we need this, is because we + * have to call MOD_DEC_USE_COUNT, but cannot include 'module.h' where it's + * defined more than once into the same kernel module. + */ +void wanpipe_close (sdla_t* card) +{ + --card->open_cnt; +} + +/*============================================================================ + * Set WAN device state. + */ +void wanpipe_set_state (sdla_t* card, int state) +{ + if (card->wandev.state != state) { + switch (state) { + case WAN_CONNECTED: + printk (KERN_INFO "%s: link connected!\n", + card->devname); + break; + + case WAN_CONNECTING: + printk (KERN_INFO "%s: link connecting...\n", + card->devname); + break; + + case WAN_DISCONNECTED: + printk (KERN_INFO "%s: link disconnected!\n", + card->devname); + break; + } + card->wandev.state = state; + } + card->state_tick = jiffies; +} + +sdla_t * wanpipe_find_card (char *name) +{ + int cnt; + for (cnt = 0; cnt < ncards; ++ cnt) { + sdla_t* card = &card_array[cnt]; + if (!strcmp(card->devname,name)) + return card; + } + return NULL; +} + +sdla_t * wanpipe_find_card_num (int num) +{ + if (num < 1 || num > ncards) + return NULL; + num--; + return &card_array[num]; +} + +/* + * @work_pointer: work_struct to be done; + * should already have PREPARE_WORK() or + * INIT_WORK() done on it by caller; + */ +void wanpipe_queue_work (struct work_struct *work_pointer) +{ + if (test_and_set_bit(1, (void*)&wanpipe_bh_critical)) + printk(KERN_INFO "CRITICAL IN QUEUING WORK\n"); + + queue_work(wanpipe_wq, work_pointer); + clear_bit(1,(void*)&wanpipe_bh_critical); +} + +void wakeup_sk_bh(struct net_device *dev) +{ + wanpipe_common_t *chan = dev->priv; + + if (test_bit(0,&chan->common_critical)) + return; + + if (chan->sk && chan->tx_timer){ + chan->tx_timer->expires=jiffies+1; + add_timer(chan->tx_timer); + } +} + +int change_dev_flags(struct net_device *dev, unsigned flags) +{ + struct ifreq if_info; + mm_segment_t fs = get_fs(); + int err; + + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + if_info.ifr_flags = flags; + + set_fs(get_ds()); /* get user space block */ + err = devinet_ioctl(SIOCSIFFLAGS, &if_info); + set_fs(fs); + + return err; +} + +unsigned long get_ip_address(struct net_device *dev, int option) +{ + + struct in_ifaddr *ifaddr; + struct in_device *in_dev; + unsigned long addr = 0; + + rcu_read_lock(); + if ((in_dev = __in_dev_get_rcu(dev)) == NULL){ + goto out; + } + + if ((ifaddr = in_dev->ifa_list)== NULL ){ + goto out; + } + + switch (option){ + + case WAN_LOCAL_IP: + addr = ifaddr->ifa_local; + break; + + case WAN_POINTOPOINT_IP: + addr = ifaddr->ifa_address; + break; + + case WAN_NETMASK_IP: + addr = ifaddr->ifa_mask; + break; + + case WAN_BROADCAST_IP: + addr = ifaddr->ifa_broadcast; + break; + default: + break; + } + +out: + rcu_read_unlock(); + return addr; +} + +void add_gateway(sdla_t *card, struct net_device *dev) +{ + mm_segment_t oldfs; + struct rtentry route; + int res; + + memset((char*)&route,0,sizeof(struct rtentry)); + + ((struct sockaddr_in *) + &(route.rt_dst))->sin_addr.s_addr = 0; + ((struct sockaddr_in *) + &(route.rt_dst))->sin_family = AF_INET; + + ((struct sockaddr_in *) + &(route.rt_genmask))->sin_addr.s_addr = 0; + ((struct sockaddr_in *) + &(route.rt_genmask)) ->sin_family = AF_INET; + + + route.rt_flags = 0; + route.rt_dev = dev->name; + + oldfs = get_fs(); + set_fs(get_ds()); + res = ip_rt_ioctl(SIOCADDRT,&route); + set_fs(oldfs); + + if (res == 0){ + printk(KERN_INFO "%s: Gateway added for %s\n", + card->devname,dev->name); + } + + return; +} + +MODULE_LICENSE("GPL"); + +/****** End *********************************************************/ diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 050e854e7..5380ddfcd 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wan/wanpipe_multppp.c b/drivers/net/wan/wanpipe_multppp.c new file mode 100644 index 000000000..812a1183c --- /dev/null +++ b/drivers/net/wan/wanpipe_multppp.c @@ -0,0 +1,2358 @@ +/***************************************************************************** +* wanpipe_multppp.c Multi-Port PPP driver module. +* +* Authors: Nenad Corbic +* +* Copyright: (c) 1995-2001 Sangoma 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. +* ============================================================================ +* Dec 15 2000 Updated for 2.4.X kernel +* Nov 15 2000 Fixed the SyncPPP support for kernels 2.2.16 and higher. +* The pppstruct has changed. +* Jul 13 2000 Using the kernel Syncppp module on top of RAW Wanpipe CHDLC +* module. +*****************************************************************************/ + +#include +#include /* printk(), and other useful stuff */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include /* kmalloc(), kfree() */ +#include /* WAN router definitions */ +#include /* WANPIPE common user API definitions */ +#include /* ARPHRD_* defines */ +#include /* time_after() macro */ + +#include /* sockaddr_in */ +#include +#include +#include /* htons(), etc. */ +#include +#include + +#include /* CHDLC firmware API definitions */ +#include /* CHDLC (async) API definitions */ + +#include /* Socket Driver common area */ +#include + + +#include +#include + +#include + + +/****** Defines & Macros ****************************************************/ + +#ifdef _DEBUG_ +#define STATIC +#else +#define STATIC static +#endif + +/* reasons for enabling the timer interrupt on the adapter */ +#define TMR_INT_ENABLED_UDP 0x01 +#define TMR_INT_ENABLED_UPDATE 0x02 +#define TMR_INT_ENABLED_CONFIG 0x04 + +#define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */ +#define CHDLC_HDR_LEN 1 + +#define IFF_POINTTOPOINT 0x10 + +#define CHDLC_API 0x01 + +#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) +#define MAX_BH_BUFF 10 + +#define CRC_LENGTH 2 +#define PPP_HEADER_LEN 4 + +/******Data Structures*****************************************************/ + +/* This structure is placed in the private data area of the device structure. + * The card structure used to occupy the private area but now the following + * structure will incorporate the card structure along with CHDLC specific data + */ + +typedef struct chdlc_private_area +{ + void *if_ptr; /* General Pointer used by SPPP */ + wanpipe_common_t common; + sdla_t *card; + int TracingEnabled; /* For enabling Tracing */ + unsigned long curr_trace_addr; /* Used for Tracing */ + unsigned long start_trace_addr; + unsigned long end_trace_addr; + unsigned long base_addr_trace_buffer; + unsigned long end_addr_trace_buffer; + unsigned short number_trace_elements; + unsigned available_buffer_space; + unsigned long router_start_time; + unsigned char route_status; + unsigned char route_removed; + unsigned long tick_counter; /* For 5s timeout counter */ + unsigned long router_up_time; + u32 IP_address; /* IP addressing */ + u32 IP_netmask; + unsigned char mc; /* Mulitcast support on/off */ + unsigned short udp_pkt_lgth; /* udp packet processing */ + char udp_pkt_src; + char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT]; + unsigned short timer_int_enabled; + char update_comms_stats; /* updating comms stats */ + + //FIXME: add driver stats as per frame relay! + +} chdlc_private_area_t; + +/* Route Status options */ +#define NO_ROUTE 0x00 +#define ADD_ROUTE 0x01 +#define ROUTE_ADDED 0x02 +#define REMOVE_ROUTE 0x03 + + +/* variable for keeping track of enabling/disabling FT1 monitor status */ +static int rCount = 0; + +/* variable for tracking how many interfaces to open for WANPIPE on the + two ports */ + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +/****** Function Prototypes *************************************************/ +/* WAN link driver entry points. These are called by the WAN router module. */ +static int update(struct wan_device* wandev); +static int new_if(struct wan_device* wandev, struct net_device* dev, + wanif_conf_t* conf); +static int del_if(struct wan_device* wandev, struct net_device* dev); + +/* Network device interface */ +static int if_init(struct net_device* dev); +static int if_open(struct net_device* dev); +static int if_close(struct net_device* dev); +static int if_send(struct sk_buff* skb, struct net_device* dev); +static struct net_device_stats* if_stats(struct net_device* dev); + +static void if_tx_timeout(struct net_device *dev); + +/* CHDLC Firmware interface functions */ +static int chdlc_configure (sdla_t* card, void* data); +static int chdlc_comm_enable (sdla_t* card); +static int chdlc_comm_disable (sdla_t* card); +static int chdlc_read_version (sdla_t* card, char* str); +static int chdlc_set_intr_mode (sdla_t* card, unsigned mode); +static int chdlc_send (sdla_t* card, void* data, unsigned len); +static int chdlc_read_comm_err_stats (sdla_t* card); +static int chdlc_read_op_stats (sdla_t* card); +static int config_chdlc (sdla_t *card); + + +/* Miscellaneous CHDLC Functions */ +static int set_chdlc_config (sdla_t* card); +static void init_chdlc_tx_rx_buff(sdla_t* card, struct net_device *dev); +static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb); +static int process_chdlc_exception(sdla_t *card); +static int process_global_exception(sdla_t *card); +static int update_comms_stats(sdla_t* card, + chdlc_private_area_t* chdlc_priv_area); +static void port_set_state (sdla_t *card, int); + +/* Interrupt handlers */ +static void wsppp_isr (sdla_t* card); +static void rx_intr (sdla_t* card); +static void timer_intr(sdla_t *); + +/* Miscellaneous functions */ +static int reply_udp( unsigned char *data, unsigned int mbox_len ); +static int intr_test( sdla_t* card); +static int udp_pkt_type( struct sk_buff *skb , sdla_t* card); +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area); +static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area); +static unsigned short calc_checksum (char *, int); +static void s508_lock (sdla_t *card, unsigned long *smp_flags); +static void s508_unlock (sdla_t *card, unsigned long *smp_flags); +static void send_ppp_term_request(struct net_device *dev); + + +static int Intr_test_counter; +/****** Public Functions ****************************************************/ + +/*============================================================================ + * Cisco HDLC protocol initialization routine. + * + * This routine is called by the main WANPIPE module during setup. At this + * point adapter is completely initialized and firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the adapter data space. + * + * Return: 0 o.k. + * < 0 failure. + */ +int wsppp_init (sdla_t* card, wandev_conf_t* conf) +{ + unsigned char port_num; + int err; + unsigned long max_permitted_baud = 0; + SHARED_MEMORY_INFO_STRUCT *flags; + + union + { + char str[80]; + } u; + volatile CHDLC_MAILBOX_STRUCT* mb; + CHDLC_MAILBOX_STRUCT* mb1; + unsigned long timeout; + + /* Verify configuration ID */ + if (conf->config_id != WANCONFIG_MPPP) { + printk(KERN_INFO "%s: invalid configuration ID %u!\n", + card->devname, conf->config_id); + return -EINVAL; + } + + /* Find out which Port to use */ + if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){ + if (card->next){ + + if (conf->comm_port != card->next->u.c.comm_port){ + card->u.c.comm_port = conf->comm_port; + }else{ + printk(KERN_ERR "%s: ERROR - %s port used!\n", + card->wandev.name, PORT(conf->comm_port)); + return -EINVAL; + } + }else{ + card->u.c.comm_port = conf->comm_port; + } + }else{ + printk(KERN_ERR "%s: ERROR - Invalid Port Selected!\n", + card->wandev.name); + return -EINVAL; + } + + + /* Initialize protocol-specific fields */ + if(card->hw.type != SDLA_S514){ + + if (card->u.c.comm_port == WANOPT_PRI){ + card->mbox = (void *) card->hw.dpmbase; + }else{ + card->mbox = (void *) card->hw.dpmbase + + SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT; + } + }else{ + /* for a S514 adapter, set a pointer to the actual mailbox in the */ + /* allocated virtual memory area */ + if (card->u.c.comm_port == WANOPT_PRI){ + card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT; + }else{ + card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT; + } + } + + mb = mb1 = card->mbox; + + if (!card->configured){ + + /* The board will place an 'I' in the return code to indicate that it is + ready to accept commands. We expect this to be completed in less + than 1 second. */ + + timeout = jiffies + 1 * HZ; + while (mb->return_code != 'I') /* Wait 1s for board to initialize */ + if (time_after(jiffies, timeout)) break; + + if (mb->return_code != 'I') { + printk(KERN_INFO + "%s: Initialization not completed by adapter\n", + card->devname); + printk(KERN_INFO "Please contact Sangoma representative.\n"); + return -EIO; + } + } + + /* Read firmware version. Note that when adapter initializes, it + * clears the mailbox, so it may appear that the first command was + * executed successfully when in fact it was merely erased. To work + * around this, we execute the first command twice. + */ + + if (chdlc_read_version(card, u.str)) + return -EIO; + + printk(KERN_INFO "%s: Running Raw CHDLC firmware v%s\n" + "%s: for Multi-Port PPP protocol.\n", + card->devname,u.str,card->devname); + + card->isr = &wsppp_isr; + card->poll = NULL; + card->exec = NULL; + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + card->wandev.udp_port = conf->udp_port; + + card->wandev.new_if_cnt = 0; + + /* reset the number of times the 'update()' proc has been called */ + card->u.c.update_call_count = 0; + + card->wandev.ttl = conf->ttl; + card->wandev.interface = conf->interface; + + if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&& + card->hw.type != SDLA_S514){ + printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n", + card->devname, PORT(card->u.c.comm_port)); + return -EIO; + } + + + card->wandev.clocking = conf->clocking; + + port_num = card->u.c.comm_port; + + /* Setup Port Bps */ + + if(card->wandev.clocking) { + if((port_num == WANOPT_PRI) || card->u.c.receive_only) { + /* For Primary Port 0 */ + max_permitted_baud = + (card->hw.type == SDLA_S514) ? + PRI_MAX_BAUD_RATE_S514 : + PRI_MAX_BAUD_RATE_S508; + } + else if(port_num == WANOPT_SEC) { + /* For Secondary Port 1 */ + max_permitted_baud = + (card->hw.type == SDLA_S514) ? + SEC_MAX_BAUD_RATE_S514 : + SEC_MAX_BAUD_RATE_S508; + } + + if(conf->bps > max_permitted_baud) { + conf->bps = max_permitted_baud; + printk(KERN_INFO "%s: Baud too high!\n", + card->wandev.name); + printk(KERN_INFO "%s: Baud rate set to %lu bps\n", + card->wandev.name, max_permitted_baud); + } + + card->wandev.bps = conf->bps; + }else{ + card->wandev.bps = 0; + } + + /* Setup the Port MTU */ + if((port_num == WANOPT_PRI) || card->u.c.receive_only) { + + /* For Primary Port 0 */ + card->wandev.mtu = + (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ? + min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) : + CHDLC_DFLT_DATA_LEN; + } else if(port_num == WANOPT_SEC) { + /* For Secondary Port 1 */ + card->wandev.mtu = + (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ? + min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) : + CHDLC_DFLT_DATA_LEN; + } + + /* Add on a PPP Header */ + card->wandev.mtu += PPP_HEADER_LEN; + + /* Set up the interrupt status area */ + /* Read the CHDLC Configuration and obtain: + * Ptr to shared memory infor struct + * Use this pointer to calculate the value of card->u.c.flags ! + */ + mb1->buffer_length = 0; + mb1->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT; + if(err != COMMAND_OK) { + clear_bit(1, (void*)&card->wandev.critical); + + if(card->hw.type != SDLA_S514) + enable_irq(card->hw.irq); + + chdlc_error(card, err, mb1); + return -EIO; + } + + if(card->hw.type == SDLA_S514){ + card->u.c.flags = (void *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)-> + ptr_shared_mem_info_struct)); + }else{ + card->u.c.flags = (void *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)-> + ptr_shared_mem_info_struct % SDLA_WINDOWSIZE)); + } + + flags = card->u.c.flags; + + /* This is for the ports link state */ + card->wandev.state = WAN_DUALPORT; + card->u.c.state = WAN_DISCONNECTED; + + + if (!card->wandev.piggyback){ + err = intr_test(card); + + if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { + printk(KERN_ERR "%s: Interrupt test failed (%i)\n", + card->devname, Intr_test_counter); + printk(KERN_ERR "%s: Please choose another interrupt\n", + card->devname); + return -EIO; + } + + printk(KERN_INFO "%s: Interrupt test passed (%i)\n", + card->devname, Intr_test_counter); + } + + + if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){ + printk (KERN_INFO "%s: Failed to set interrupt triggers!\n", + card->devname); + return -EIO; + } + + /* Mask the Timer interrupt */ + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TIMER; + + printk(KERN_INFO "\n"); + + return 0; +} + +/******* WAN Device Driver Entry Points *************************************/ + +/*============================================================================ + * Update device status & statistics + * This procedure is called when updating the PROC file system and returns + * various communications statistics. These statistics are accumulated from 3 + * different locations: + * 1) The 'if_stats' recorded for the device. + * 2) Communication error statistics on the adapter. + * 3) CHDLC operational statistics on the adapter. + * The board level statistics are read during a timer interrupt. Note that we + * read the error and operational statistics during consecitive timer ticks so + * as to minimize the time that we are inside the interrupt handler. + * + */ +static int update(struct wan_device* wandev) +{ + sdla_t* card = wandev->private; + struct net_device* dev; + volatile chdlc_private_area_t* chdlc_priv_area; + SHARED_MEMORY_INFO_STRUCT *flags; + unsigned long timeout; + + /* sanity checks */ + if((wandev == NULL) || (wandev->private == NULL)) + return -EFAULT; + + if(wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + /* more sanity checks */ + if(!card->u.c.flags) + return -ENODEV; + + if((dev=card->wandev.dev) == NULL) + return -ENODEV; + + if((chdlc_priv_area=dev->priv) == NULL) + return -ENODEV; + + flags = card->u.c.flags; + + if(chdlc_priv_area->update_comms_stats){ + return -EAGAIN; + } + + /* we will need 2 timer interrupts to complete the */ + /* reading of the statistics */ + chdlc_priv_area->update_comms_stats = 2; + flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER; + chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE; + + /* wait a maximum of 1 second for the statistics to be updated */ + timeout = jiffies + 1 * HZ; + for(;;) { + if(chdlc_priv_area->update_comms_stats == 0) + break; + if (time_after(jiffies, timeout)){ + chdlc_priv_area->update_comms_stats = 0; + chdlc_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + return -EAGAIN; + } + } + + return 0; +} + + +/*============================================================================ + * Create new logical channel. + * This routine is called by the router when ROUTER_IFNEW IOCTL is being + * handled. + * o parse media- and hardware-specific configuration + * o make sure that a new channel can be created + * o allocate resources, if necessary + * o prepare network device structure for registaration. + * + * Return: 0 o.k. + * < 0 failure (channel will not be created) + */ +static int new_if(struct wan_device* wandev, struct net_device* pdev, + wanif_conf_t* conf) +{ + + struct ppp_device *pppdev = (struct ppp_device *)pdev; + struct net_device *dev = NULL; + struct sppp *sp; + sdla_t* card = wandev->private; + chdlc_private_area_t* chdlc_priv_area; + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { + printk(KERN_INFO "%s: invalid interface name!\n", + card->devname); + return -EINVAL; + } + + /* allocate and initialize private data */ + chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL); + + if(chdlc_priv_area == NULL) + return -ENOMEM; + + memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t)); + + chdlc_priv_area->card = card; + + /* initialize data */ + strcpy(card->u.c.if_name, conf->name); + + if(card->wandev.new_if_cnt > 0) { + kfree(chdlc_priv_area); + return -EEXIST; + } + + card->wandev.new_if_cnt++; + + chdlc_priv_area->TracingEnabled = 0; + + //We don't need this any more + chdlc_priv_area->route_status = NO_ROUTE; + chdlc_priv_area->route_removed = 0; + + printk(KERN_INFO "%s: Firmware running in HDLC STREAMING Mode\n", + wandev->name); + + /* Setup wanpipe as a router (WANPIPE) or as an API */ + if( strcmp(conf->usedby, "WANPIPE") == 0) { + printk(KERN_INFO "%s: Driver running in WANPIPE mode!\n", + wandev->name); + card->u.c.usedby = WANPIPE; + } else { + printk(KERN_INFO + "%s: API Mode is not supported for SyncPPP!\n", + wandev->name); + kfree(chdlc_priv_area); + return -EINVAL; + } + + /* Get Multicast Information */ + chdlc_priv_area->mc = conf->mc; + + + chdlc_priv_area->if_ptr = pppdev; + + /* prepare network device data space for registration */ + + strcpy(dev->name,card->u.c.if_name); + + /* Attach PPP protocol layer to pppdev + * The sppp_attach() will initilize the dev structure + * and setup ppp layer protocols. + * All we have to do is to bind in: + * if_open(), if_close(), if_send() and get_stats() functions. + */ + sppp_attach(pppdev); + dev = pppdev->dev; + sp = &pppdev->sppp; + + /* Enable PPP Debugging */ + // FIXME Fix this up somehow + //sp->pp_flags |= PP_DEBUG; + sp->pp_flags &= ~PP_CISCO; + + dev->init = &if_init; + dev->priv = chdlc_priv_area; + + return 0; +} + + + + +/*============================================================================ + * Delete logical channel. + */ +static int del_if(struct wan_device* wandev, struct net_device* dev) +{ + chdlc_private_area_t *chdlc_priv_area = dev->priv; + sdla_t *card = chdlc_priv_area->card; + unsigned long smp_lock; + + /* Detach the PPP layer */ + printk(KERN_INFO "%s: Detaching SyncPPP Module from %s\n", + wandev->name,dev->name); + + lock_adapter_irq(&wandev->lock,&smp_lock); + + sppp_detach(dev); + chdlc_priv_area->if_ptr=NULL; + + chdlc_set_intr_mode(card, 0); + if (card->u.c.comm_enabled) + chdlc_comm_disable(card); + unlock_adapter_irq(&wandev->lock,&smp_lock); + + port_set_state(card, WAN_DISCONNECTED); + + return 0; +} + + +/****** Network Device Interface ********************************************/ + +/*============================================================================ + * Initialize Linux network interface. + * + * This routine is called only once for each interface, during Linux network + * interface registration. Returning anything but zero will fail interface + * registration. + */ +static int if_init(struct net_device* dev) +{ + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + struct wan_device* wandev = &card->wandev; + + /* NOTE: Most of the dev initialization was + * done in sppp_attach(), called by new_if() + * function. All we have to do here is + * to link four major routines below. + */ + + /* Initialize device driver entry points */ + dev->open = &if_open; + dev->stop = &if_close; + dev->hard_start_xmit = &if_send; + dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + + /* Initialize hardware parameters */ + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + dev->mem_start = wandev->maddr; + dev->mem_end = wandev->maddr + wandev->msize - 1; + + /* Set transmit buffer queue length + * If we over fill this queue the packets will + * be droped by the kernel. + * sppp_attach() sets this to 10, but + * 100 will give us more room at low speeds. + */ + dev->tx_queue_len = 100; + + return 0; +} + + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout(struct net_device *dev) +{ + chdlc_private_area_t* chan = dev->priv; + sdla_t *card = chan->card; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + ++card->wandev.stats.collisions; + + printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name); + netif_wake_queue (dev); +} + + +/*============================================================================ + * Open network interface. + * o enable communications and interrupts. + * o prevent module from unloading by incrementing use count + * + * Return 0 if O.k. or errno. + */ +static int if_open(struct net_device* dev) +{ + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + struct timeval tv; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + + /* Only one open per interface is allowed */ + if (netif_running(dev)) + return -EBUSY; + + /* Start PPP Layer */ + if (sppp_open(dev)){ + return -EIO; + } + + do_gettimeofday(&tv); + chdlc_priv_area->router_start_time = tv.tv_sec; + + netif_start_queue(dev); + + wanpipe_open(card); + + chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG; + flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER; + return 0; +} + +/*============================================================================ + * Close network interface. + * o if this is the last close, then disable communications and interrupts. + * o reset flags. + */ +static int if_close(struct net_device* dev) +{ + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + + /* Stop the PPP Layer */ + sppp_close(dev); + netif_stop_queue(dev); + + wanpipe_close(card); + + return 0; +} + +/*============================================================================ + * Send a packet on a network interface. + * o set tbusy flag (marks start of the transmission) to block a timer-based + * transmit from overlapping. + * o check link state. If link is not up, then drop the packet. + * o execute adapter send command. + * o free socket buffer + * + * Return: 0 complete (socket buffer must be freed) + * non-0 packet may be re-transmitted (tbusy must be set) + * + * Notes: + * 1. This routine is called either by the protocol stack or by the "net + * bottom half" (with interrupts enabled). + * 2. Setting tbusy flag will inhibit further transmit requests from the + * protocol stack and can be used for flow control with protocol layer. + */ +static int if_send(struct sk_buff* skb, struct net_device* dev) +{ + chdlc_private_area_t *chdlc_priv_area = dev->priv; + sdla_t *card = chdlc_priv_area->card; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct; + int udp_type = 0; + unsigned long smp_flags; + int err=0; + + netif_stop_queue(dev); + + + if (skb == NULL){ + /* If we get here, some higher layer thinks we've missed an + * tx-done interrupt. + */ + printk(KERN_INFO "%s: Received NULL skb buffer! interface %s got kicked!\n", + card->devname, dev->name); + + netif_wake_queue(dev); + return 0; + } + + if (ntohs(skb->protocol) != htons(PVC_PROT)){ + /* check the udp packet type */ + + udp_type = udp_pkt_type(skb, card); + if (udp_type == UDP_CPIPE_TYPE){ + if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev, + chdlc_priv_area)){ + chdlc_int->interrupt_permission |= + APP_INT_ON_TIMER; + } + netif_start_queue(dev); + return 0; + } + } + + /* Lock the 508 Card: SMP is supported */ + if(card->hw.type != SDLA_S514){ + s508_lock(card,&smp_flags); + } + + if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)){ + + printk(KERN_INFO "%s: Critical in if_send: %lx\n", + card->wandev.name,card->wandev.critical); + ++card->wandev.stats.tx_dropped; + netif_start_queue(dev); + goto if_send_crit_exit; + } + + if (card->wandev.state != WAN_CONNECTED){ + ++card->wandev.stats.tx_dropped; + netif_start_queue(dev); + goto if_send_crit_exit; + } + + if (chdlc_send(card, skb->data, skb->len)){ + netif_stop_queue(dev); + + }else{ + ++card->wandev.stats.tx_packets; + card->wandev.stats.tx_bytes += skb->len; + dev->trans_start = jiffies; + netif_start_queue(dev); + } + +if_send_crit_exit: + if (!(err=netif_queue_stopped(dev))){ + dev_kfree_skb_any(skb); + }else{ + chdlc_priv_area->tick_counter = jiffies; + chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME; + } + + clear_bit(SEND_CRIT, (void*)&card->wandev.critical); + if(card->hw.type != SDLA_S514){ + s508_unlock(card,&smp_flags); + } + + return err; +} + + +/*============================================================================ + * Reply to UDP Management system. + * Return length of reply. + */ +static int reply_udp( unsigned char *data, unsigned int mbox_len ) +{ + + unsigned short len, udp_length, temp, ip_length; + unsigned long ip_temp; + int even_bound = 0; + chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data; + + /* Set length of packet */ + len = sizeof(ip_pkt_t)+ + sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + sizeof(trace_info_t)+ + mbox_len; + + /* fill in UDP reply */ + c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; + + /* fill in UDP length */ + udp_length = sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + sizeof(trace_info_t)+ + mbox_len; + + /* put it on an even boundary */ + if ( udp_length & 0x0001 ) { + udp_length += 1; + len += 1; + even_bound = 1; + } + + temp = (udp_length<<8)|(udp_length>>8); + c_udp_pkt->udp_pkt.udp_length = temp; + + /* swap UDP ports */ + temp = c_udp_pkt->udp_pkt.udp_src_port; + c_udp_pkt->udp_pkt.udp_src_port = + c_udp_pkt->udp_pkt.udp_dst_port; + c_udp_pkt->udp_pkt.udp_dst_port = temp; + + /* add UDP pseudo header */ + temp = 0x1100; + *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp; + temp = (udp_length<<8)|(udp_length>>8); + *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp; + + + /* calculate UDP checksum */ + c_udp_pkt->udp_pkt.udp_checksum = 0; + c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET); + + /* fill in IP length */ + ip_length = len; + temp = (ip_length<<8)|(ip_length>>8); + c_udp_pkt->ip_pkt.total_length = temp; + + /* swap IP addresses */ + ip_temp = c_udp_pkt->ip_pkt.ip_src_address; + c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address; + c_udp_pkt->ip_pkt.ip_dst_address = ip_temp; + + /* fill in IP checksum */ + c_udp_pkt->ip_pkt.hdr_checksum = 0; + c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t)); + + return len; + +} /* reply_udp */ + +unsigned short calc_checksum (char *data, int len) +{ + unsigned short temp; + unsigned long sum=0; + int i; + + for( i = 0; i > 16 ) { + sum = (sum & 0xffffUL) + (sum >> 16); + } + + temp = (unsigned short)sum; + temp = ~temp; + + if( temp == 0 ) + temp = 0xffff; + + return temp; +} + + +/*============================================================================ + * Get ethernet-style interface statistics. + * Return a pointer to struct enet_statistics. + */ +static struct net_device_stats* if_stats(struct net_device* dev) +{ + sdla_t *my_card; + chdlc_private_area_t* chdlc_priv_area; + + /* Shutdown bug fix. In del_if() we kill + * dev->priv pointer. This function, gets + * called after del_if(), thus check + * if pointer has been deleted */ + if ((chdlc_priv_area=dev->priv) == NULL) + return NULL; + + my_card = chdlc_priv_area->card; + return &my_card->wandev.stats; +} + + +/****** Cisco HDLC Firmware Interface Functions *******************************/ + +/*============================================================================ + * Read firmware code version. + * Put code version as ASCII string in str. + */ +static int chdlc_read_version (sdla_t* card, char* str) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int len; + char err; + mb->buffer_length = 0; + mb->command = READ_CHDLC_CODE_VERSION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + chdlc_error(card,err,mb); + } + else if (str) { /* is not null */ + len = mb->buffer_length; + memcpy(str, mb->data, len); + str[len] = '\0'; + } + return (err); +} + +/*----------------------------------------------------------------------------- + * Configure CHDLC firmware. + */ +static int chdlc_configure (sdla_t* card, void* data) +{ + int err; + CHDLC_MAILBOX_STRUCT *mailbox = card->mbox; + int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT); + + mailbox->buffer_length = data_length; + memcpy(mailbox->data, data, data_length); + mailbox->command = SET_CHDLC_CONFIGURATION; + err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT; + + if (err != COMMAND_OK) chdlc_error (card, err, mailbox); + + return err; +} + + +/*============================================================================ + * Set interrupt mode -- HDLC Version. + */ + +static int chdlc_set_intr_mode (sdla_t* card, unsigned mode) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_INT_TRIGGERS_STRUCT* int_data = + (CHDLC_INT_TRIGGERS_STRUCT *)mb->data; + int err; + + int_data->CHDLC_interrupt_triggers = mode; + int_data->IRQ = card->hw.irq; + int_data->interrupt_timer = 1; + + mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT); + mb->command = SET_CHDLC_INTERRUPT_TRIGGERS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error (card, err, mb); + return err; +} + + +/*============================================================================ + * Enable communications. + */ + +static int chdlc_comm_enable (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = ENABLE_CHDLC_COMMUNICATIONS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card, err, mb); + else + card->u.c.comm_enabled=1; + + return err; +} + +/*============================================================================ + * Disable communications and Drop the Modem lines (DCD and RTS). + */ +static int chdlc_comm_disable (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = DISABLE_CHDLC_COMMUNICATIONS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + + return err; +} + +/*============================================================================ + * Read communication error statistics. + */ +static int chdlc_read_comm_err_stats (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = READ_COMMS_ERROR_STATS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + return err; +} + + +/*============================================================================ + * Read CHDLC operational statistics. + */ +static int chdlc_read_op_stats (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_OPERATIONAL_STATS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + return err; +} + + +/*============================================================================ + * Update communications error and general packet statistics. + */ +static int update_comms_stats(sdla_t* card, + chdlc_private_area_t* chdlc_priv_area) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + COMMS_ERROR_STATS_STRUCT* err_stats; + CHDLC_OPERATIONAL_STATS_STRUCT *op_stats; + + /* on the first timer interrupt, read the comms error statistics */ + if(chdlc_priv_area->update_comms_stats == 2) { + if(chdlc_read_comm_err_stats(card)) + return 1; + err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data; + card->wandev.stats.rx_over_errors = + err_stats->Rx_overrun_err_count; + card->wandev.stats.rx_crc_errors = + err_stats->CRC_err_count; + card->wandev.stats.rx_frame_errors = + err_stats->Rx_abort_count; + card->wandev.stats.rx_fifo_errors = + err_stats->Rx_dis_pri_bfrs_full_count; + card->wandev.stats.rx_missed_errors = + card->wandev.stats.rx_fifo_errors; + card->wandev.stats.tx_aborted_errors = + err_stats->sec_Tx_abort_count; + } + + /* on the second timer interrupt, read the operational statistics */ + else { + if(chdlc_read_op_stats(card)) + return 1; + op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data; + card->wandev.stats.rx_length_errors = + (op_stats->Rx_Data_discard_short_count + + op_stats->Rx_Data_discard_long_count); + } + + return 0; +} + +/*============================================================================ + * Send packet. + * Return: 0 - o.k. + * 1 - no transmit buffers available + */ +static int chdlc_send (sdla_t* card, void* data, unsigned len) +{ + CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf; + + if (txbuf->opp_flag) + return 1; + + sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len); + + txbuf->frame_length = len; + txbuf->opp_flag = 1; /* start transmission */ + + /* Update transmit buffer control fields */ + card->u.c.txbuf = ++txbuf; + + if ((void*)txbuf > card->u.c.txbuf_last) + card->u.c.txbuf = card->u.c.txbuf_base; + + return 0; +} + +/****** Firmware Error Handler **********************************************/ + +/*============================================================================ + * Firmware error handler. + * This routine is called whenever firmware command returns non-zero + * return code. + * + * Return zero if previous command has to be cancelled. + */ +static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb) +{ + unsigned cmd = mb->command; + + switch (err) { + + case CMD_TIMEOUT: + printk(KERN_ERR "%s: command 0x%02X timed out!\n", + card->devname, cmd); + break; + + case S514_BOTH_PORTS_SAME_CLK_MODE: + if(cmd == SET_CHDLC_CONFIGURATION) { + printk(KERN_INFO + "%s: Configure both ports for the same clock source\n", + card->devname); + break; + } + + default: + printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n", + card->devname, cmd, err); + } + + return 0; +} + +/****** Interrupt Handlers **************************************************/ + +/*============================================================================ + * Cisco HDLC interrupt service routine. + */ +STATIC void wsppp_isr (sdla_t* card) +{ + struct net_device* dev; + SHARED_MEMORY_INFO_STRUCT* flags = NULL; + int i; + sdla_t *my_card; + + + /* Check for which port the interrupt has been generated + * Since Secondary Port is piggybacking on the Primary + * the check must be done here. + */ + + flags = card->u.c.flags; + if (!flags->interrupt_info_struct.interrupt_type){ + /* Check for a second port (piggybacking) */ + if((my_card = card->next)){ + flags = my_card->u.c.flags; + if (flags->interrupt_info_struct.interrupt_type){ + card = my_card; + card->isr(card); + return; + } + } + } + + dev = card->wandev.dev; + card->in_isr = 1; + flags = card->u.c.flags; + + /* If we get an interrupt with no network device, stop the interrupts + * and issue an error */ + if ((!dev || !dev->priv) && flags->interrupt_info_struct.interrupt_type != + COMMAND_COMPLETE_APP_INT_PEND){ + goto isr_done; + } + + + /* if critical due to peripheral operations + * ie. update() or getstats() then reset the interrupt and + * wait for the board to retrigger. + */ + if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) { + flags->interrupt_info_struct. + interrupt_type = 0; + goto isr_done; + } + + + /* On a 508 Card, if critical due to if_send + * Major Error !!! + */ + if(card->hw.type != SDLA_S514) { + if(test_bit(0, (void*)&card->wandev.critical)) { + printk(KERN_INFO "%s: Critical while in ISR: %lx\n", + card->devname, card->wandev.critical); + goto isr_done; + } + } + + switch(flags->interrupt_info_struct.interrupt_type) { + + case RX_APP_INT_PEND: /* 0x01: receive interrupt */ + rx_intr(card); + break; + + case TX_APP_INT_PEND: /* 0x02: transmit interrupt */ + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TX_FRAME; + + netif_wake_queue(dev); + break; + + case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */ + ++ Intr_test_counter; + break; + + case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */ + process_chdlc_exception(card); + break; + + case GLOBAL_EXCEP_COND_APP_INT_PEND: + process_global_exception(card); + break; + + case TIMER_APP_INT_PEND: + timer_intr(card); + break; + + default: + printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", + card->devname, + flags->interrupt_info_struct.interrupt_type); + printk(KERN_INFO "Code name: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codename[i]); + printk(KERN_INFO "\nCode version: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codeversion[i]); + printk(KERN_INFO "\n"); + break; + } + +isr_done: + card->in_isr = 0; + flags->interrupt_info_struct.interrupt_type = 0; +} + +/*============================================================================ + * Receive interrupt handler. + */ +static void rx_intr (sdla_t* card) +{ + struct net_device *dev; + chdlc_private_area_t *chdlc_priv_area; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb; + struct sk_buff *skb; + unsigned len; + unsigned addr = rxbuf->ptr_data_bfr; + void *buf; + int i,udp_type; + + if (rxbuf->opp_flag != 0x01) { + printk(KERN_INFO + "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", + card->devname, (unsigned)rxbuf, rxbuf->opp_flag); + printk(KERN_INFO "Code name: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codename[i]); + printk(KERN_INFO "\nCode version: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codeversion[i]); + printk(KERN_INFO "\n"); + + + /* Bug Fix: Mar 6 2000 + * If we get a corrupted mailbox, it measn that driver + * is out of sync with the firmware. There is no recovery. + * If we don't turn off all interrupts for this card + * the machine will crash. + */ + printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname); + printk(KERN_INFO "Please contact Sangoma Technologies !\n"); + chdlc_set_intr_mode(card,0); + return; + } + + dev = card->wandev.dev; + + if (!dev){ + goto rx_exit; + } + + if (!netif_running(dev)){ + goto rx_exit; + } + + chdlc_priv_area = dev->priv; + + if (rxbuf->error_flag){ + goto rx_exit; + } + /* Take off two CRC bytes */ + + if (rxbuf->frame_length < 7 || rxbuf->frame_length > 1506 ){ + goto rx_exit; + } + + len = rxbuf->frame_length - CRC_LENGTH; + + /* Allocate socket buffer */ + skb = dev_alloc_skb(len); + + if (skb == NULL) { + if (net_ratelimit()){ + printk(KERN_INFO "%s: no socket buffers available!\n", + card->devname); + } + ++card->wandev.stats.rx_dropped; + goto rx_exit; + } + + /* Copy data to the socket buffer */ + if((addr + len) > card->u.c.rx_top + 1) { + unsigned tmp = card->u.c.rx_top - addr + 1; + buf = skb_put(skb, tmp); + sdla_peek(&card->hw, addr, buf, tmp); + addr = card->u.c.rx_base; + len -= tmp; + } + + buf = skb_put(skb, len); + sdla_peek(&card->hw, addr, buf, len); + + skb->protocol = htons(ETH_P_WAN_PPP); + + card->wandev.stats.rx_packets ++; + card->wandev.stats.rx_bytes += skb->len; + udp_type = udp_pkt_type( skb, card ); + + if(udp_type == UDP_CPIPE_TYPE) { + if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, + card, skb, dev, chdlc_priv_area)) { + flags->interrupt_info_struct. + interrupt_permission |= + APP_INT_ON_TIMER; + } + }else{ + /* Pass it up the protocol stack */ + skb->dev = dev; + skb->mac.raw = skb->data; + netif_rx(skb); + dev->last_rx = jiffies; + } + +rx_exit: + /* Release buffer element and calculate a pointer to the next one */ + rxbuf->opp_flag = 0x00; + card->u.c.rxmb = ++ rxbuf; + if((void*)rxbuf > card->u.c.rxbuf_last){ + card->u.c.rxmb = card->u.c.rxbuf_base; + } +} + +/*============================================================================ + * Timer interrupt handler. + * The timer interrupt is used for two purposes: + * 1) Processing udp calls from 'cpipemon'. + * 2) Reading board-level statistics for updating the proc file system. + */ +void timer_intr(sdla_t *card) +{ + struct net_device* dev; + chdlc_private_area_t* chdlc_priv_area = NULL; + SHARED_MEMORY_INFO_STRUCT* flags = NULL; + + dev = card->wandev.dev; + chdlc_priv_area = dev->priv; + + if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) { + if (!config_chdlc(card)){ + chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG; + } + } + + /* process a udp call if pending */ + if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) { + process_udp_mgmt_pkt(card, dev, + chdlc_priv_area); + chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP; + } + + + /* read the communications statistics if required */ + if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) { + update_comms_stats(card, chdlc_priv_area); + if(!(-- chdlc_priv_area->update_comms_stats)) { + chdlc_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + } + } + + /* only disable the timer interrupt if there are no udp or statistic */ + /* updates pending */ + if(!chdlc_priv_area->timer_int_enabled) { + flags = card->u.c.flags; + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TIMER; + } +} + +/*------------------------------------------------------------------------------ + Miscellaneous Functions + - set_chdlc_config() used to set configuration options on the board +------------------------------------------------------------------------------*/ + +static int set_chdlc_config(sdla_t* card) +{ + + CHDLC_CONFIGURATION_STRUCT cfg; + + memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT)); + + if(card->wandev.clocking) + cfg.baud_rate = card->wandev.bps; + + cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; + + cfg.modem_config_options = 0; + //API OPTIONS + cfg.CHDLC_API_options = DISCARD_RX_ERROR_FRAMES; + cfg.modem_status_timer = 100; + cfg.CHDLC_protocol_options = HDLC_STREAMING_MODE; + cfg.percent_data_buffer_for_Tx = 50; + cfg.CHDLC_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT | + CHDLC_RX_DATA_BYTE_COUNT_STAT); + cfg.max_CHDLC_data_field_length = card->wandev.mtu; + + cfg.transmit_keepalive_timer = 0; + cfg.receive_keepalive_timer = 0; + cfg.keepalive_error_tolerance = 0; + cfg.SLARP_request_timer = 0; + + cfg.IP_address = 0; + cfg.IP_netmask = 0; + + return chdlc_configure(card, &cfg); +} + +/*============================================================================ + * Process global exception condition + */ +static int process_global_exception(sdla_t *card) +{ + CHDLC_MAILBOX_STRUCT* mbox = card->mbox; + int err; + + mbox->buffer_length = 0; + mbox->command = READ_GLOBAL_EXCEPTION_CONDITION; + err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT; + + if(err != CMD_TIMEOUT ){ + + switch(mbox->return_code) { + + case EXCEP_MODEM_STATUS_CHANGE: + + printk(KERN_INFO "%s: Modem status change\n", + card->devname); + + switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) { + case (DCD_HIGH): + printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname); + break; + case (CTS_HIGH): + printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname); + break; + case ((DCD_HIGH | CTS_HIGH)): + printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname); + break; + default: + printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname); + break; + } + + if (!(mbox->data[0] & DCD_HIGH) || !(mbox->data[0] & DCD_HIGH)){ + //printk(KERN_INFO "Sending TERM Request Manually !\n"); + send_ppp_term_request(card->wandev.dev); + } + break; + + case EXCEP_TRC_DISABLED: + printk(KERN_INFO "%s: Line trace disabled\n", + card->devname); + break; + + case EXCEP_IRQ_TIMEOUT: + printk(KERN_INFO "%s: IRQ timeout occurred\n", + card->devname); + break; + + default: + printk(KERN_INFO "%s: Global exception %x\n", + card->devname, mbox->return_code); + break; + } + } + return 0; +} + + +/*============================================================================ + * Process chdlc exception condition + */ +static int process_chdlc_exception(sdla_t *card) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int err; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_EXCEPTION_CONDITION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if(err != CMD_TIMEOUT) { + + switch (err) { + + case EXCEP_LINK_ACTIVE: + port_set_state(card, WAN_CONNECTED); + break; + + case EXCEP_LINK_INACTIVE_MODEM: + port_set_state(card, WAN_DISCONNECTED); + break; + + case EXCEP_LOOPBACK_CONDITION: + printk(KERN_INFO "%s: Loopback Condition Detected.\n", + card->devname); + break; + + case NO_CHDLC_EXCEP_COND_TO_REPORT: + printk(KERN_INFO "%s: No exceptions reported.\n", + card->devname); + break; + default: + printk(KERN_INFO "%s: Exception Condition %x!\n", + card->devname,err); + break; + } + + } + return 0; +} + + +/*============================================================================= + * Store a UDP management packet for later processing. + */ + +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area ) +{ + int udp_pkt_stored = 0; + + if(!chdlc_priv_area->udp_pkt_lgth && + (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) { + chdlc_priv_area->udp_pkt_lgth = skb->len; + chdlc_priv_area->udp_pkt_src = udp_pkt_src; + memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len); + chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP; + udp_pkt_stored = 1; + } + + if(udp_pkt_src == UDP_PKT_FRM_STACK) + dev_kfree_skb_any(skb); + else + dev_kfree_skb_any(skb); + + return(udp_pkt_stored); +} + + +/*============================================================================= + * Process UDP management packet. + */ + +static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area ) +{ + unsigned char *buf; + unsigned int frames, len; + struct sk_buff *new_skb; + unsigned short buffer_length, real_len; + unsigned long data_ptr; + unsigned data_length; + int udp_mgmt_req_valid = 1; + CHDLC_MAILBOX_STRUCT *mb = card->mbox; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + chdlc_udp_pkt_t *chdlc_udp_pkt; + struct timeval tv; + int err; + char ut_char; + + chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data; + + if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + switch(chdlc_udp_pkt->cblock.command) { + case READ_GLOBAL_STATISTICS: + case READ_MODEM_STATUS: + case READ_CHDLC_LINK_STATUS: + case CPIPE_ROUTER_UP_TIME: + case READ_COMMS_ERROR_STATS: + case READ_CHDLC_OPERATIONAL_STATS: + + /* These two commands are executed for + * each request */ + case READ_CHDLC_CONFIGURATION: + case READ_CHDLC_CODE_VERSION: + udp_mgmt_req_valid = 1; + break; + default: + udp_mgmt_req_valid = 0; + break; + } + } + + if(!udp_mgmt_req_valid) { + + /* set length to 0 */ + chdlc_udp_pkt->cblock.buffer_length = 0; + + /* set return code */ + chdlc_udp_pkt->cblock.return_code = 0xCD; + + if (net_ratelimit()){ + printk(KERN_INFO + "%s: Warning, Illegal UDP command attempted from network: %x\n", + card->devname,chdlc_udp_pkt->cblock.command); + } + + } else { + unsigned long trace_status_cfg_addr = 0; + TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct; + TRACE_STATUS_ELEMENT_STRUCT trace_element_struct; + + switch(chdlc_udp_pkt->cblock.command) { + + case CPIPE_ENABLE_TRACING: + if (!chdlc_priv_area->TracingEnabled) { + + /* OPERATE_DATALINE_MONITOR */ + + mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT); + mb->command = SET_TRACE_CONFIGURATION; + + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_config = TRACE_ACTIVE; + /* Trace delay mode is not used because it slows + down transfer and results in a standoff situation + when there is a lot of data */ + + /* Configure the Trace based on user inputs */ + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= + chdlc_udp_pkt->data[0]; + + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_deactivation_timer = 4000; + + + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) { + chdlc_error(card,err,mb); + card->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = err; + mb->buffer_length = 0; + break; + } + + /* Get the base address of the trace element list */ + mb->buffer_length = 0; + mb->command = READ_TRACE_CONFIGURATION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if (err != COMMAND_OK) { + chdlc_error(card,err,mb); + chdlc_priv_area->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = err; + mb->buffer_length = 0; + break; + } + + trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *) + mb->data) -> ptr_trace_stat_el_cfg_struct; + + sdla_peek(&card->hw, trace_status_cfg_addr, + &trace_cfg_struct, sizeof(trace_cfg_struct)); + + chdlc_priv_area->start_trace_addr = trace_cfg_struct. + base_addr_trace_status_elements; + + chdlc_priv_area->number_trace_elements = + trace_cfg_struct.number_trace_status_elements; + + chdlc_priv_area->end_trace_addr = (unsigned long) + ((TRACE_STATUS_ELEMENT_STRUCT *) + chdlc_priv_area->start_trace_addr + + (chdlc_priv_area->number_trace_elements - 1)); + + chdlc_priv_area->base_addr_trace_buffer = + trace_cfg_struct.base_addr_trace_buffer; + + chdlc_priv_area->end_addr_trace_buffer = + trace_cfg_struct.end_addr_trace_buffer; + + chdlc_priv_area->curr_trace_addr = + trace_cfg_struct.next_trace_element_to_use; + + chdlc_priv_area->available_buffer_space = 2000 - + sizeof(ip_pkt_t) - + sizeof(udp_pkt_t) - + sizeof(wp_mgmt_t) - + sizeof(cblock_t) - + sizeof(trace_info_t); + } + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + mb->buffer_length = 0; + chdlc_priv_area->TracingEnabled = 1; + break; + + + case CPIPE_DISABLE_TRACING: + if (chdlc_priv_area->TracingEnabled) { + + /* OPERATE_DATALINE_MONITOR */ + mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT); + mb->command = SET_TRACE_CONFIGURATION; + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_config = TRACE_INACTIVE; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + } + + chdlc_priv_area->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + mb->buffer_length = 0; + break; + + + case CPIPE_GET_TRACE_INFO: + + if (!chdlc_priv_area->TracingEnabled) { + chdlc_udp_pkt->cblock.return_code = 1; + mb->buffer_length = 0; + break; + } + + chdlc_udp_pkt->trace_info.ismoredata = 0x00; + buffer_length = 0; /* offset of packet already occupied */ + + for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){ + + trace_pkt_t *trace_pkt = (trace_pkt_t *) + &chdlc_udp_pkt->data[buffer_length]; + + sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr, + (unsigned char *)&trace_element_struct, + sizeof(TRACE_STATUS_ELEMENT_STRUCT)); + + if (trace_element_struct.opp_flag == 0x00) { + break; + } + + /* get pointer to real data */ + data_ptr = trace_element_struct.ptr_data_bfr; + + /* See if there is actual data on the trace buffer */ + if (data_ptr){ + data_length = trace_element_struct.trace_length; + }else{ + data_length = 0; + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + } + + if( (chdlc_priv_area->available_buffer_space - buffer_length) + < ( sizeof(trace_pkt_t) + data_length) ) { + + /* indicate there are more frames on board & exit */ + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + break; + } + + trace_pkt->status = trace_element_struct.trace_type; + + trace_pkt->time_stamp = + trace_element_struct.trace_time_stamp; + + trace_pkt->real_length = + trace_element_struct.trace_length; + + /* see if we can fit the frame into the user buffer */ + real_len = trace_pkt->real_length; + + if (data_ptr == 0) { + trace_pkt->data_avail = 0x00; + } else { + unsigned tmp = 0; + + /* get the data from circular buffer + must check for end of buffer */ + trace_pkt->data_avail = 0x01; + + if ((data_ptr + real_len) > + chdlc_priv_area->end_addr_trace_buffer + 1){ + + tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1; + sdla_peek(&card->hw, data_ptr, + trace_pkt->data,tmp); + data_ptr = chdlc_priv_area->base_addr_trace_buffer; + } + + sdla_peek(&card->hw, data_ptr, + &trace_pkt->data[tmp], real_len - tmp); + } + + /* zero the opp flag to show we got the frame */ + ut_char = 0x00; + sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1); + + /* now move onto the next frame */ + chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT); + + /* check if we went over the last address */ + if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) { + chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr; + } + + if(trace_pkt->data_avail == 0x01) { + buffer_length += real_len - 1; + } + + /* for the header */ + buffer_length += sizeof(trace_pkt_t); + + } /* For Loop */ + + if (frames == chdlc_priv_area->number_trace_elements){ + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + } + chdlc_udp_pkt->trace_info.num_frames = frames; + + mb->buffer_length = buffer_length; + chdlc_udp_pkt->cblock.buffer_length = buffer_length; + + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + + break; + + + case CPIPE_FT1_READ_STATUS: + ((unsigned char *)chdlc_udp_pkt->data )[0] = + flags->FT1_info_struct.parallel_port_A_input; + + ((unsigned char *)chdlc_udp_pkt->data )[1] = + flags->FT1_info_struct.parallel_port_B_input; + + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + mb->buffer_length = 2; + break; + + case CPIPE_ROUTER_UP_TIME: + do_gettimeofday( &tv ); + chdlc_priv_area->router_up_time = tv.tv_sec - + chdlc_priv_area->router_start_time; + *(unsigned long *)&chdlc_udp_pkt->data = + chdlc_priv_area->router_up_time; + mb->buffer_length = sizeof(unsigned long); + break; + + case FT1_MONITOR_STATUS_CTRL: + /* Enable FT1 MONITOR STATUS */ + if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) || + (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) { + + if( rCount++ != 0 ) { + chdlc_udp_pkt->cblock. + return_code = COMMAND_OK; + mb->buffer_length = 1; + break; + } + } + + /* Disable FT1 MONITOR STATUS */ + if( chdlc_udp_pkt->data[0] == 0) { + + if( --rCount != 0) { + chdlc_udp_pkt->cblock. + return_code = COMMAND_OK; + mb->buffer_length = 1; + break; + } + } + + default: + /* it's a board command */ + mb->command = chdlc_udp_pkt->cblock.command; + mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length; + if (mb->buffer_length) { + memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt-> + data, mb->buffer_length); + } + /* run the command on the board */ + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) { + break; + } + + /* copy the result back to our buffer */ + memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t)); + + if (mb->buffer_length) { + memcpy(&chdlc_udp_pkt->data, &mb->data, + mb->buffer_length); + } + + } /* end of switch */ + } /* end of else */ + + /* Fill UDP TTL */ + chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl; + + len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length); + + if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) { + if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) { + ++ card->wandev.stats.tx_packets; + card->wandev.stats.tx_bytes += len; + } + } else { + + /* Pass it up the stack + Allocate socket buffer */ + if ((new_skb = dev_alloc_skb(len)) != NULL) { + /* copy data into new_skb */ + + buf = skb_put(new_skb, len); + memcpy(buf, chdlc_priv_area->udp_pkt_data, len); + + /* Decapsulate pkt and pass it up the protocol stack */ + new_skb->protocol = htons(ETH_P_IP); + new_skb->dev = dev; + new_skb->mac.raw = new_skb->data; + + netif_rx(new_skb); + dev->last_rx = jiffies; + } else { + + printk(KERN_INFO "%s: no socket buffers available!\n", + card->devname); + } + } + + chdlc_priv_area->udp_pkt_lgth = 0; + + return 0; +} + +/*============================================================================ + * Initialize Receive and Transmit Buffers. + */ + +static void init_chdlc_tx_rx_buff(sdla_t* card, struct net_device *dev) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config; + CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config; + char err; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + chdlc_error(card,err,mb); + return; + } + + if(card->hw.type == SDLA_S514) { + tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Tx_stat_el_cfg_struct)); + rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Rx_stat_el_cfg_struct)); + + /* Setup Head and Tails for buffers */ + card->u.c.txbuf_base = (void *)(card->hw.dpmbase + + tx_config->base_addr_Tx_status_elements); + card->u.c.txbuf_last = + (CHDLC_DATA_TX_STATUS_EL_STRUCT *) + card->u.c.txbuf_base + + (tx_config->number_Tx_status_elements - 1); + + card->u.c.rxbuf_base = (void *)(card->hw.dpmbase + + rx_config->base_addr_Rx_status_elements); + card->u.c.rxbuf_last = + (CHDLC_DATA_RX_STATUS_EL_STRUCT *) + card->u.c.rxbuf_base + + (rx_config->number_Rx_status_elements - 1); + + /* Set up next pointer to be used */ + card->u.c.txbuf = (void *)(card->hw.dpmbase + + tx_config->next_Tx_status_element_to_use); + card->u.c.rxmb = (void *)(card->hw.dpmbase + + rx_config->next_Rx_status_element_to_use); + } + else { + tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE)); + + rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE)); + + /* Setup Head and Tails for buffers */ + card->u.c.txbuf_base = (void *)(card->hw.dpmbase + + (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE)); + card->u.c.txbuf_last = + (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base + + (tx_config->number_Tx_status_elements - 1); + card->u.c.rxbuf_base = (void *)(card->hw.dpmbase + + (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE)); + card->u.c.rxbuf_last = + (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base + + (rx_config->number_Rx_status_elements - 1); + + /* Set up next pointer to be used */ + card->u.c.txbuf = (void *)(card->hw.dpmbase + + (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE)); + card->u.c.rxmb = (void *)(card->hw.dpmbase + + (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE)); + } + + /* Setup Actual Buffer Start and end addresses */ + card->u.c.rx_base = rx_config->base_addr_Rx_buffer; + card->u.c.rx_top = rx_config->end_addr_Rx_buffer; + +} + +/*============================================================================= + * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR + * _TEST_COUNTER times. + */ +static int intr_test( sdla_t* card) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int err,i; + + Intr_test_counter = 0; + + /* The critical flag is unset because during initialization (if_open) + * we want the interrupts to be enabled so that when the wpc_isr is + * called it does not exit due to critical flag set. + */ + + err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE); + + if (err == CMD_OK) { + for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) { + mb->buffer_length = 0; + mb->command = READ_CHDLC_CODE_VERSION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + } + } + else { + return err; + } + + err = chdlc_set_intr_mode(card, 0); + + if (err != CMD_OK) + return err; + + return 0; +} + +/*============================================================================== + * Determine what type of UDP call it is. CPIPEAB ? + */ +static int udp_pkt_type(struct sk_buff *skb, sdla_t* card) +{ + chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data; + + if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) && + (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) && + (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) && + (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) { + return UDP_CPIPE_TYPE; + } + else return UDP_INVALID_TYPE; +} + +/*============================================================================ + * Set PORT state. + */ +static void port_set_state (sdla_t *card, int state) +{ + struct net_device *dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area = dev->priv; + + if (card->u.c.state != state) + { + switch (state) + { + case WAN_CONNECTED: + printk (KERN_INFO "%s: HDLC link connected!\n", + card->devname); + break; + + case WAN_CONNECTING: + printk (KERN_INFO "%s: HDLC link connecting...\n", + card->devname); + break; + + case WAN_DISCONNECTED: + printk (KERN_INFO "%s: HDLC link disconnected!\n", + card->devname); + break; + } + + card->wandev.state = card->u.c.state = state; + chdlc_priv_area->common.state = state; + } +} + +void s508_lock (sdla_t *card, unsigned long *smp_flags) +{ + spin_lock_irqsave(&card->wandev.lock, *smp_flags); + if (card->next){ + /* It is ok to use spin_lock here, since we + * already turned off interrupts */ + spin_lock(&card->next->wandev.lock); + } +} + +void s508_unlock (sdla_t *card, unsigned long *smp_flags) +{ + if (card->next){ + spin_unlock(&card->next->wandev.lock); + } + spin_unlock_irqrestore(&card->wandev.lock, *smp_flags); +} + + + +/*=========================================================================== + * config_chdlc + * + * Configure the chdlc protocol and enable communications. + * + * The if_open() function binds this function to the poll routine. + * Therefore, this function will run every time the chdlc interface + * is brought up. We cannot run this function from the if_open + * because if_open does not have access to the remote IP address. + * + * If the communications are not enabled, proceed to configure + * the card and enable communications. + * + * If the communications are enabled, it means that the interface + * was shutdown by ether the user or driver. In this case, we + * have to check that the IP addresses have not changed. If + * the IP addresses have changed, we have to reconfigure the firmware + * and update the changed IP addresses. Otherwise, just exit. + * + */ + +static int config_chdlc (sdla_t *card) +{ + struct net_device *dev = card->wandev.dev; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + + if (card->u.c.comm_enabled){ + chdlc_comm_disable(card); + port_set_state(card, WAN_DISCONNECTED); + } + + if (set_chdlc_config(card)) { + printk(KERN_INFO "%s: CHDLC Configuration Failed!\n", + card->devname); + return 0; + } + init_chdlc_tx_rx_buff(card, dev); + + /* Set interrupt mode and mask */ + if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME | + APP_INT_ON_GLOBAL_EXCEP_COND | + APP_INT_ON_TX_FRAME | + APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){ + printk (KERN_INFO "%s: Failed to set interrupt triggers!\n", + card->devname); + return 0; + } + + + /* Mask the Transmit and Timer interrupt */ + flags->interrupt_info_struct.interrupt_permission &= + ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER); + + + if (chdlc_comm_enable(card) != 0) { + printk(KERN_INFO "%s: Failed to enable chdlc communications!\n", + card->devname); + flags->interrupt_info_struct.interrupt_permission = 0; + card->u.c.comm_enabled=0; + chdlc_set_intr_mode(card,0); + return 0; + } + + /* Initialize Rx/Tx buffer control fields */ + port_set_state(card, WAN_CONNECTING); + return 0; +} + + +static void send_ppp_term_request(struct net_device *dev) +{ + struct sk_buff *new_skb; + unsigned char *buf; + + if ((new_skb = dev_alloc_skb(8)) != NULL) { + /* copy data into new_skb */ + + buf = skb_put(new_skb, 8); + sprintf(buf,"%c%c%c%c%c%c%c%c", 0xFF,0x03,0xC0,0x21,0x05,0x98,0x00,0x07); + + /* Decapsulate pkt and pass it up the protocol stack */ + new_skb->protocol = htons(ETH_P_WAN_PPP); + new_skb->dev = dev; + new_skb->mac.raw = new_skb->data; + + netif_rx(new_skb); + dev->last_rx = jiffies; + } +} + + +MODULE_LICENSE("GPL"); + +/****** End ****************************************************************/ diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 29a756dd9..9d3b51c3e 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -577,8 +577,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, 0x0FFFFFFF) || + pci_set_dma_mask(pdev, 0x0FFFFFFF)) { printk(KERN_ERR "wanXL: No usable DMA configuration\n"); return -EIO; } diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index ec37df734..8101657da 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -7,7 +7,6 @@ menu "Wireless LAN (non-hamradio)" config NET_RADIO bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions" - select WIRELESS_EXT ---help--- Support for wireless LANs and everything having to do with radio, but not with amateur radio or FM broadcasting. @@ -25,16 +24,6 @@ config NET_RADIO the tools from . -config NET_WIRELESS_RTNETLINK - bool "Wireless Extension API over RtNetlink" - depends on NET_RADIO - ---help--- - Support the Wireless Extension API over the RtNetlink socket - in addition to the traditional ioctl interface (selected above). - - For now, few tools use this facility, but it might grow in the - future. The only downside is that it adds 4.5 kB to your kernel. - # Note : the cards are obsolete (can't buy them anymore), but the drivers # are not, as people are still using them... comment "Obsolete Wireless cards support (pre-802.11)" @@ -146,9 +135,8 @@ comment "Wireless 802.11b ISA/PCI cards support" config IPW2100 tristate "Intel PRO/Wireless 2100 Network Connection" - depends on NET_RADIO && PCI + depends on NET_RADIO && PCI && IEEE80211 select FW_LOADER - select IEEE80211 ---help--- A driver for the Intel PRO/Wireless 2100 Network Connection 802.11b wireless network adapter. @@ -200,9 +188,8 @@ config IPW2100_DEBUG config IPW2200 tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" - depends on NET_RADIO && PCI + depends on NET_RADIO && IEEE80211 && PCI select FW_LOADER - select IEEE80211 ---help--- A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network Connection adapters. @@ -214,7 +201,7 @@ config IPW2200 In order to use this driver, you will need a firmware image for it. You can obtain the firmware from . See the above referenced README.ipw2200 - for information on where to install the firmware images. + for information on where to install the firmare images. You will also very likely need the Wireless Tools in order to configure your card: @@ -226,19 +213,6 @@ config IPW2200 say M here and read . The module will be called ipw2200.ko. -config IPW2200_MONITOR - bool "Enable promiscuous mode" - depends on IPW2200 - ---help--- - Enables promiscuous/monitor mode support for the ipw2200 driver. - With this feature compiled into the driver, you can switch to - promiscuous mode via the Wireless Tool's Monitor mode. While in this - mode, no packets can be sent. - -config IPW_QOS - bool "Enable QoS support" - depends on IPW2200 && EXPERIMENTAL - config IPW2200_DEBUG bool "Enable full debugging output in IPW2200 module." depends on IPW2200 @@ -263,15 +237,6 @@ config IPW2200_DEBUG If you are not trying to debug or develop the IPW2200 driver, you most likely want to say N here. -config IPW2200_MONITOR - bool "Enable promiscuous mode" - depends on IPW2200 - ---help--- - Enables promiscuous/monitor mode support for the ipw2200 driver. - With this feature compiled into the driver, you can switch to - promiscuous mode via the Wireless Tool's Monitor mode. While in this - mode, no packets can be sent. - config AIRO tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN) @@ -281,7 +246,7 @@ config AIRO PCI 802.11 wireless cards. It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X - with or without encryption) as well as card before the Cisco - acquisition (Aironet 4500, Aironet 4800, Aironet 4800B). + aquisition (Aironet 4500, Aironet 4800, Aironet 4800B). This driver support both the standard Linux Wireless Extensions and Cisco proprietary API, so both the Linux Wireless Tools and the @@ -318,10 +283,7 @@ config APPLE_AIRPORT Say Y here to support the Airport 802.11b wireless Ethernet hardware built into the Macintosh iBook and other recent PowerPC-based Macintosh machines. This is essentially a Lucent Orinoco card with - a non-standard interface. - - This driver does not support the Airport Extreme (802.11b/g). Use - the BCM43xx driver for Airport Extreme cards. + a non-standard interface config PLX_HERMES tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)" @@ -365,7 +327,7 @@ config PCI_HERMES config ATMEL tristate "Atmel at76c50x chipset 802.11b support" - depends on NET_RADIO && (PCI || PCMCIA) + depends on NET_RADIO select FW_LOADER select CRC32 ---help--- @@ -434,7 +396,7 @@ config AIRO_CS driver part of the Linux Pcmcia package. It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X - with or without encryption) as well as card before the Cisco - acquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also + aquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also supports OEM of Cisco such as the DELL TrueMobile 4800 and Xircom 802.11b cards. @@ -513,7 +475,6 @@ config PRISM54 will be called prism54.ko. source "drivers/net/wireless/hostap/Kconfig" -source "drivers/net/wireless/bcm43xx/Kconfig" # yes, this works even when no drivers are selected config NET_WIRELESS diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index c86779879..3a6f7ba32 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -35,7 +35,6 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o obj-$(CONFIG_PRISM54) += prism54/ obj-$(CONFIG_HOSTAP) += hostap/ -obj-$(CONFIG_BCM43XX) += bcm43xx/ # 16-bit wireless PCMCIA client drivers obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 00764ddd7..a4c7ae946 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -88,6 +87,14 @@ static struct pci_driver airo_driver = { #include #endif +/* Support Cisco MIC feature */ +#define MICSUPPORT + +#if defined(MICSUPPORT) && !defined(CONFIG_CRYPTO) +#warning MIC support requires Crypto API +#undef MICSUPPORT +#endif + /* Hack to do some power saving */ #define POWER_ON_DOWN @@ -769,11 +776,6 @@ typedef struct { u16 atimWindow; } BSSListRid; -typedef struct { - BSSListRid bss; - struct list_head list; -} BSSListElement; - typedef struct { u8 rssipct; u8 rssidBm; @@ -907,7 +909,6 @@ static char swversion[] = "2.1"; #define NUM_MODULES 2 #define MIC_MSGLEN_MAX 2400 #define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX -#define AIRO_DEF_MTU 2312 typedef struct { u32 size; // size @@ -1117,6 +1118,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp); static int writerids(struct net_device *dev, aironet_ioctl *comp); static int flashcard(struct net_device *dev, aironet_ioctl *comp); #endif /* CISCO_EXT */ +#ifdef MICSUPPORT static void micinit(struct airo_info *ai); static int micsetup(struct airo_info *ai); static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); @@ -1125,7 +1127,8 @@ static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi); static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm); -static void airo_networks_free(struct airo_info *ai); +#include +#endif struct airo_info { struct net_device_stats stats; @@ -1158,7 +1161,7 @@ struct airo_info { #define FLAG_COMMIT 13 #define FLAG_RESET 14 #define FLAG_FLASHING 15 -#define JOB_MASK 0x2ff0000 +#define JOB_MASK 0x1ff0000 #define JOB_DIE 16 #define JOB_XMIT 17 #define JOB_XMIT11 18 @@ -1168,7 +1171,6 @@ struct airo_info { #define JOB_EVENT 22 #define JOB_AUTOWEP 23 #define JOB_WSTATS 24 -#define JOB_SCAN_RESULTS 25 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen, int whichbap); unsigned short *flash; @@ -1185,13 +1187,15 @@ struct airo_info { } xmit, xmit11; struct net_device *wifidev; struct iw_statistics wstats; // wireless stats - unsigned long scan_timeout; /* Time scan should be read */ + unsigned long scan_timestamp; /* Time started to scan */ struct iw_spy_data spy_data; struct iw_public_data wireless_data; +#ifdef MICSUPPORT /* MIC stuff */ struct crypto_tfm *tfm; mic_module mod[2]; mic_statistics micstats; +#endif HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors HostTxDesc txfids[MPI_MAX_FIDS]; HostRidDesc config_desc; @@ -1207,10 +1211,6 @@ struct airo_info { APListRid *APList; #define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE char proc_name[IFNAMSIZ]; - - struct list_head network_list; - struct list_head network_free_list; - BSSListElement *networks; }; static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen, @@ -1229,22 +1229,7 @@ static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime); static int flashputbuf(struct airo_info *ai); static int flashrestart(struct airo_info *ai,struct net_device *dev); -#define airo_print(type, name, fmt, args...) \ - { printk(type "airo(%s): " fmt "\n", name, ##args); } - -#define airo_print_info(name, fmt, args...) \ - airo_print(KERN_INFO, name, fmt, ##args) - -#define airo_print_dbg(name, fmt, args...) \ - airo_print(KERN_DEBUG, name, fmt, ##args) - -#define airo_print_warn(name, fmt, args...) \ - airo_print(KERN_WARNING, name, fmt, ##args) - -#define airo_print_err(name, fmt, args...) \ - airo_print(KERN_ERR, name, fmt, ##args) - - +#ifdef MICSUPPORT /*********************************************************************** * MIC ROUTINES * *********************************************************************** @@ -1323,7 +1308,7 @@ static int micsetup(struct airo_info *ai) { ai->tfm = crypto_alloc_tfm("aes", CRYPTO_TFM_REQ_MAY_SLEEP); if (ai->tfm == NULL) { - airo_print_err(ai->dev->name, "failed to load transform for AES"); + printk(KERN_ERR "airo: failed to load transform for AES\n"); return ERROR; } @@ -1701,6 +1686,7 @@ static void emmh32_final(emmh32_context *context, u8 digest[4]) digest[2] = (val>>8) & 0xFF; digest[3] = val & 0xFF; } +#endif static int readBSSListRid(struct airo_info *ai, int first, BSSListRid *list) { @@ -1755,11 +1741,11 @@ static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lo wkr.kindex = cpu_to_le16(wkr.kindex); wkr.klen = cpu_to_le16(wkr.klen); rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock); - if (rc!=SUCCESS) airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc); + if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc); if (perm) { rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock); if (rc!=SUCCESS) { - airo_print_err(ai->dev->name, "WEP_PERM set %x", rc); + printk(KERN_ERR "airo: WEP_PERM set %x\n", rc); } } return rc; @@ -1938,7 +1924,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct airo_info *ai = dev->priv; if (!skb) { - airo_print_err(dev->name, "%s: skb == NULL!",__FUNCTION__); + printk(KERN_ERR "airo: %s: skb==NULL\n",__FUNCTION__); return 0; } npacks = skb_queue_len (&ai->txq); @@ -1984,8 +1970,8 @@ static int mpi_send_packet (struct net_device *dev) /* get a packet to send */ if ((skb = skb_dequeue(&ai->txq)) == 0) { - airo_print_err(dev->name, - "%s: Dequeue'd zero in send_packet()", + printk (KERN_ERR + "airo: %s: Dequeue'd zero in send_packet()\n", __FUNCTION__); return 0; } @@ -2019,6 +2005,7 @@ static int mpi_send_packet (struct net_device *dev) * Firmware automaticly puts 802 header on so * we don't need to account for it in the length */ +#ifdef MICSUPPORT if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && (ntohs(((u16 *)buffer)[6]) != 0x888E)) { MICBuffer pMic; @@ -2035,7 +2022,9 @@ static int mpi_send_packet (struct net_device *dev) memcpy (sendbuf, &pMic, sizeof(pMic)); sendbuf += sizeof(pMic); memcpy (sendbuf, buffer, len - sizeof(etherHead)); - } else { + } else +#endif + { *payloadLen = cpu_to_le16(len - sizeof(etherHead)); dev->trans_start = jiffies; @@ -2137,7 +2126,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { u32 *fids = priv->fids; if ( skb == NULL ) { - airo_print_err(dev->name, "%s: skb == NULL!", __FUNCTION__); + printk( KERN_ERR "airo: skb == NULL!!!\n" ); return 0; } @@ -2208,7 +2197,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { } if ( skb == NULL ) { - airo_print_err(dev->name, "%s: skb == NULL!", __FUNCTION__); + printk( KERN_ERR "airo: skb == NULL!!!\n" ); return 0; } @@ -2393,8 +2382,6 @@ void stop_airo_card( struct net_device *dev, int freeres ) dev_kfree_skb(skb); } - airo_networks_free (ai); - kfree(ai->flash); kfree(ai->rssi); kfree(ai->APList); @@ -2413,7 +2400,9 @@ void stop_airo_card( struct net_device *dev, int freeres ) ai->shared, ai->shared_dma); } } +#ifdef MICSUPPORT crypto_free_tfm(ai->tfm); +#endif del_airo_dev( dev ); free_netdev( dev ); } @@ -2465,7 +2454,7 @@ static int mpi_init_descriptors (struct airo_info *ai) cmd.parm2 = MPI_MAX_FIDS; rc=issuecommand(ai, &cmd, &rsp); if (rc != SUCCESS) { - airo_print_err(ai->dev->name, "Couldn't allocate RX FID"); + printk(KERN_ERR "airo: Couldn't allocate RX FID\n"); return rc; } @@ -2493,7 +2482,7 @@ static int mpi_init_descriptors (struct airo_info *ai) rc=issuecommand(ai, &cmd, &rsp); if (rc != SUCCESS) { - airo_print_err(ai->dev->name, "Couldn't allocate TX FID"); + printk(KERN_ERR "airo: Couldn't allocate TX FID\n"); return rc; } @@ -2507,7 +2496,7 @@ static int mpi_init_descriptors (struct airo_info *ai) cmd.parm2 = 1; /* Magic number... */ rc=issuecommand(ai, &cmd, &rsp); if (rc != SUCCESS) { - airo_print_err(ai->dev->name, "Couldn't allocate RID"); + printk(KERN_ERR "airo: Couldn't allocate RID\n"); return rc; } @@ -2539,25 +2528,25 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci, aux_len = AUXMEMSIZE; if (!request_mem_region(mem_start, mem_len, name)) { - airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s", + printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n", (int)mem_start, (int)mem_len, name); goto out; } if (!request_mem_region(aux_start, aux_len, name)) { - airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s", + printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n", (int)aux_start, (int)aux_len, name); goto free_region1; } ai->pcimem = ioremap(mem_start, mem_len); if (!ai->pcimem) { - airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s", + printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n", (int)mem_start, (int)mem_len, name); goto free_region2; } ai->pciaux = ioremap(aux_start, aux_len); if (!ai->pciaux) { - airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s", + printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n", (int)aux_start, (int)aux_len, name); goto free_memmap; } @@ -2565,7 +2554,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci, /* Reserve PKTSIZE for each fid and 2K for the Rids */ ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma); if (!ai->shared) { - airo_print_err(ai->dev->name, "Couldn't alloc_consistent %d", + printk(KERN_ERR "airo: Couldn't alloc_consistent %d\n", PCI_SHARED_LEN); goto free_auxmap; } @@ -2657,7 +2646,7 @@ static void wifi_setup(struct net_device *dev) dev->type = ARPHRD_IEEE80211; dev->hard_header_len = ETH_HLEN; - dev->mtu = AIRO_DEF_MTU; + dev->mtu = 2312; dev->addr_len = ETH_ALEN; dev->tx_queue_len = 100; @@ -2701,42 +2690,6 @@ static int reset_card( struct net_device *dev , int lock) { return 0; } -#define MAX_NETWORK_COUNT 64 -static int airo_networks_allocate(struct airo_info *ai) -{ - if (ai->networks) - return 0; - - ai->networks = - kzalloc(MAX_NETWORK_COUNT * sizeof(BSSListElement), - GFP_KERNEL); - if (!ai->networks) { - airo_print_warn(ai->dev->name, "Out of memory allocating beacons"); - return -ENOMEM; - } - - return 0; -} - -static void airo_networks_free(struct airo_info *ai) -{ - if (!ai->networks) - return; - kfree(ai->networks); - ai->networks = NULL; -} - -static void airo_networks_initialize(struct airo_info *ai) -{ - int i; - - INIT_LIST_HEAD(&ai->network_free_list); - INIT_LIST_HEAD(&ai->network_list); - for (i = 0; i < MAX_NETWORK_COUNT; i++) - list_add_tail(&ai->networks[i].list, - &ai->network_free_list); -} - static struct net_device *_init_airo_card( unsigned short irq, int port, int is_pcmcia, struct pci_dev *pci, struct device *dmdev ) @@ -2748,22 +2701,22 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, /* Create the network device object. */ dev = alloc_etherdev(sizeof(*ai)); if (!dev) { - airo_print_err("", "Couldn't alloc_etherdev"); + printk(KERN_ERR "airo: Couldn't alloc_etherdev\n"); return NULL; } if (dev_alloc_name(dev, dev->name) < 0) { - airo_print_err("", "Couldn't get name!"); + printk(KERN_ERR "airo: Couldn't get name!\n"); goto err_out_free; } ai = dev->priv; ai->wifidev = NULL; ai->flags = 0; - ai->dev = dev; if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) { - airo_print_dbg(dev->name, "Found an MPI350 card"); + printk(KERN_DEBUG "airo: Found an MPI350 card\n"); set_bit(FLAG_MPI, &ai->flags); } + ai->dev = dev; spin_lock_init(&ai->aux_lock); sema_init(&ai->sem, 1); ai->config.len = 0; @@ -2773,15 +2726,13 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); if (ai->thr_pid < 0) goto err_out_free; +#ifdef MICSUPPORT ai->tfm = NULL; +#endif rc = add_airo_dev( dev ); if (rc) goto err_out_thr; - if (airo_networks_allocate (ai)) - goto err_out_unlink; - airo_networks_initialize (ai); - /* The Airo-specific entries in the device structure. */ if (test_bit(FLAG_MPI,&ai->flags)) { skb_queue_head_init (&ai->txq); @@ -2803,33 +2754,33 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, SET_NETDEV_DEV(dev, dmdev); + reset_card (dev, 1); msleep(400); rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev ); if (rc) { - airo_print_err(dev->name, "register interrupt %d failed, rc %d", - irq, rc); + printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc ); goto err_out_unlink; } if (!is_pcmcia) { if (!request_region( dev->base_addr, 64, dev->name )) { rc = -EBUSY; - airo_print_err(dev->name, "Couldn't request region"); + printk(KERN_ERR "airo: Couldn't request region\n"); goto err_out_irq; } } if (test_bit(FLAG_MPI,&ai->flags)) { if (mpi_map_card(ai, pci, dev->name)) { - airo_print_err(dev->name, "Could not map memory"); + printk(KERN_ERR "airo: Could not map memory\n"); goto err_out_res; } } if (probe) { if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) { - airo_print_err(dev->name, "MAC could not be enabled" ); + printk( KERN_ERR "airo: MAC could not be enabled\n" ); rc = -EIO; goto err_out_map; } @@ -2840,20 +2791,21 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, rc = register_netdev(dev); if (rc) { - airo_print_err(dev->name, "Couldn't register_netdev"); + printk(KERN_ERR "airo: Couldn't register_netdev\n"); goto err_out_map; } ai->wifidev = init_wifidev(ai, dev); set_bit(FLAG_REGISTERED,&ai->flags); - airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", + printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", + dev->name, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] ); /* Allocate the transmit buffers */ if (probe && !test_bit(FLAG_MPI,&ai->flags)) for( i = 0; i < MAX_FIDS; i++ ) - ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2); + ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2); setup_proc_entry( dev, dev->priv ); /* XXX check for failure */ netif_start_queue(dev); @@ -2910,16 +2862,16 @@ int reset_airo_card( struct net_device *dev ) return -1; if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) { - airo_print_err(dev->name, "MAC could not be enabled"); + printk( KERN_ERR "airo: MAC could not be enabled\n" ); return -1; } - airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", + printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", dev->name, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); /* Allocate the transmit buffers if needed */ if (!test_bit(FLAG_MPI,&ai->flags)) for( i = 0; i < MAX_FIDS; i++ ) - ai->fids[i] = transmit_allocate (ai,AIRO_DEF_MTU,i>=MAX_FIDS/2); + ai->fids[i] = transmit_allocate (ai,2312,i>=MAX_FIDS/2); enable_interrupts( ai ); netif_wake_queue(dev); @@ -2945,65 +2897,6 @@ static void airo_send_event(struct net_device *dev) { wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); } -static void airo_process_scan_results (struct airo_info *ai) { - union iwreq_data wrqu; - BSSListRid BSSList; - int rc; - BSSListElement * loop_net; - BSSListElement * tmp_net; - - /* Blow away current list of scan results */ - list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) { - list_move_tail (&loop_net->list, &ai->network_free_list); - /* Don't blow away ->list, just BSS data */ - memset (loop_net, 0, sizeof (loop_net->bss)); - } - - /* Try to read the first entry of the scan result */ - rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 0); - if((rc) || (BSSList.index == 0xffff)) { - /* No scan results */ - goto out; - } - - /* Read and parse all entries */ - tmp_net = NULL; - while((!rc) && (BSSList.index != 0xffff)) { - /* Grab a network off the free list */ - if (!list_empty(&ai->network_free_list)) { - tmp_net = list_entry(ai->network_free_list.next, - BSSListElement, list); - list_del(ai->network_free_list.next); - } - - if (tmp_net != NULL) { - memcpy(tmp_net, &BSSList, sizeof(tmp_net->bss)); - list_add_tail(&tmp_net->list, &ai->network_list); - tmp_net = NULL; - } - - /* Read next entry */ - rc = PC4500_readrid(ai, RID_BSSLISTNEXT, - &BSSList, sizeof(BSSList), 0); - } - -out: - ai->scan_timeout = 0; - clear_bit(JOB_SCAN_RESULTS, &ai->flags); - up(&ai->sem); - - /* Send an empty event to user space. - * We don't send the received data on - * the event because it would require - * us to do complex transcoding, and - * we want to minimise the work done in - * the irq handler. Use a request to - * extract the data - Jean II */ - wrqu.data.length = 0; - wrqu.data.flags = 0; - wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL); -} - static int airo_thread(void *data) { struct net_device *dev = data; struct airo_info *ai = dev->priv; @@ -3033,26 +2926,13 @@ static int airo_thread(void *data) { set_current_state(TASK_INTERRUPTIBLE); if (ai->flags & JOB_MASK) break; - if (ai->expires || ai->scan_timeout) { - if (ai->scan_timeout && - time_after_eq(jiffies,ai->scan_timeout)){ - set_bit(JOB_SCAN_RESULTS,&ai->flags); - break; - } else if (ai->expires && - time_after_eq(jiffies,ai->expires)){ + if (ai->expires) { + if (time_after_eq(jiffies,ai->expires)){ set_bit(JOB_AUTOWEP,&ai->flags); break; } if (!signal_pending(current)) { - unsigned long wake_at; - if (!ai->expires || !ai->scan_timeout) { - wake_at = max(ai->expires, - ai->scan_timeout); - } else { - wake_at = min(ai->expires, - ai->scan_timeout); - } - schedule_timeout(wake_at - jiffies); + schedule_timeout(ai->expires - jiffies); continue; } } else if (!signal_pending(current)) { @@ -3089,16 +2969,14 @@ static int airo_thread(void *data) { airo_read_wireless_stats(ai); else if (test_bit(JOB_PROMISC, &ai->flags)) airo_set_promisc(ai); +#ifdef MICSUPPORT else if (test_bit(JOB_MIC, &ai->flags)) micinit(ai); +#endif else if (test_bit(JOB_EVENT, &ai->flags)) airo_send_event(dev); else if (test_bit(JOB_AUTOWEP, &ai->flags)) timer_func(dev); - else if (test_bit(JOB_SCAN_RESULTS, &ai->flags)) - airo_process_scan_results(ai); - else /* Shouldn't get here, but we make sure to unlock */ - up(&ai->sem); } complete_and_exit (&ai->thr_exited, 0); } @@ -3132,14 +3010,15 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) if ( status & EV_MIC ) { OUT4500( apriv, EVACK, EV_MIC ); +#ifdef MICSUPPORT if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { set_bit(JOB_MIC, &apriv->flags); wake_up_interruptible(&apriv->thr_wait); } +#endif } if ( status & EV_LINK ) { union iwreq_data wrqu; - int scan_forceloss = 0; /* The link status has changed, if you want to put a monitor hook in, do it here. (Remember that interrupts are still disabled!) @@ -3158,8 +3037,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) code) */ #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason code) */ -#define ASSOCIATED 0x0400 /* Associated */ -#define REASSOCIATED 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */ +#define ASSOCIATED 0x0400 /* Assocatied */ #define RC_RESERVED 0 /* Reserved return code */ #define RC_NOREASON 1 /* Unspecified reason */ #define RC_AUTHINV 2 /* Previous authentication invalid */ @@ -3176,30 +3054,48 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) leaving BSS */ #define RC_NOAUTH 9 /* Station requesting (Re)Association is not Authenticated with the responding station */ - if (newStatus == FORCELOSS && apriv->scan_timeout > 0) - scan_forceloss = 1; - if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) { + if (newStatus != ASSOCIATED) { + if (auto_wep && !apriv->expires) { + apriv->expires = RUN_AT(3*HZ); + wake_up_interruptible(&apriv->thr_wait); + } + } else { + struct task_struct *task = apriv->task; if (auto_wep) apriv->expires = 0; - if (apriv->task) - wake_up_process (apriv->task); + if (task) + wake_up_process (task); set_bit(FLAG_UPDATE_UNI, &apriv->flags); set_bit(FLAG_UPDATE_MULTI, &apriv->flags); - + } + /* Question : is ASSOCIATED the only status + * that is valid ? We want to catch handover + * and reassociations as valid status + * Jean II */ + if(newStatus == ASSOCIATED) { + if (apriv->scan_timestamp) { + /* Send an empty event to user space. + * We don't send the received data on + * the event because it would require + * us to do complex transcoding, and + * we want to minimise the work done in + * the irq handler. Use a request to + * extract the data - Jean II */ + wrqu.data.length = 0; + wrqu.data.flags = 0; + wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); + apriv->scan_timestamp = 0; + } if (down_trylock(&apriv->sem) != 0) { set_bit(JOB_EVENT, &apriv->flags); wake_up_interruptible(&apriv->thr_wait); } else airo_send_event(dev); - } else if (!scan_forceloss) { - if (auto_wep && !apriv->expires) { - apriv->expires = RUN_AT(3*HZ); - wake_up_interruptible(&apriv->thr_wait); - } - - /* Send event to user space */ + } else { memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; + + /* Send event to user space */ wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL); } } @@ -3247,8 +3143,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) } len = le16_to_cpu(hdr.len); - if (len > AIRO_DEF_MTU) { - airo_print_err(apriv->dev->name, "Bad size %d", len); + if (len > 2312) { + printk( KERN_ERR "airo: Bad size %d\n", len ); goto badrx; } if (len == 0) @@ -3291,17 +3187,18 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) bap_read (apriv, &gap, sizeof(gap), BAP0); gap = le16_to_cpu(gap); if (gap) { - if (gap <= 8) { + if (gap <= 8) bap_read (apriv, tmpbuf, gap, BAP0); - } else { - airo_print_err(apriv->dev->name, "gaplen too " - "big. Problems will follow..."); - } + else + printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n"); } bap_read (apriv, buffer + hdrlen/2, len, BAP0); } else { +#ifdef MICSUPPORT MICBuffer micbuf; +#endif bap_read (apriv, buffer, ETH_ALEN*2, BAP0); +#ifdef MICSUPPORT if (apriv->micstats.enabled) { bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0); if (ntohs(micbuf.typelen) > 0x05DC) @@ -3314,10 +3211,15 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) skb_trim (skb, len + hdrlen); } } +#endif bap_read(apriv,buffer+ETH_ALEN,len,BAP0); +#ifdef MICSUPPORT if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { badmic: dev_kfree_skb_irq (skb); +#else + if (0) { +#endif badrx: OUT4500( apriv, EVACK, EV_RX); goto exitrx; @@ -3413,13 +3315,12 @@ exitrx: } } else { OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC)); - airo_print_err(apriv->dev->name, "Unallocated FID was " - "used to xmit" ); + printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" ); } } exittx: if ( status & ~STATUS_INTS & ~IGNORE_INTS ) - airo_print_warn(apriv->dev->name, "Got weird status %x", + printk( KERN_WARNING "airo: Got weird status %x\n", status & ~STATUS_INTS & ~IGNORE_INTS ); } @@ -3492,8 +3393,8 @@ static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) { up(&ai->sem); if (rc) - airo_print_err(ai->dev->name, "%s: Cannot enable MAC, err=%d", - __FUNCTION__, rc); + printk(KERN_ERR "%s: Cannot enable MAC, err=%d\n", + __FUNCTION__,rc); return rc; } @@ -3529,8 +3430,10 @@ static void mpi_receive_802_3(struct airo_info *ai) int len = 0; struct sk_buff *skb; char *buffer; +#ifdef MICSUPPORT int off = 0; MICBuffer micbuf; +#endif memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd)); /* Make sure we got something */ @@ -3545,6 +3448,7 @@ static void mpi_receive_802_3(struct airo_info *ai) goto badrx; } buffer = skb_put(skb,len); +#ifdef MICSUPPORT memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2); if (ai->micstats.enabled) { memcpy(&micbuf, @@ -3566,6 +3470,9 @@ badmic: dev_kfree_skb_irq (skb); goto badrx; } +#else + memcpy(buffer, ai->rxfids[0].virtual_host_addr, len); +#endif #ifdef WIRELESS_SPY if (ai->spy_data.spy_number > 0) { char *sa; @@ -3622,8 +3529,8 @@ void mpi_receive_802_11 (struct airo_info *ai) if (ai->wifidev == NULL) hdr.len = 0; len = le16_to_cpu(hdr.len); - if (len > AIRO_DEF_MTU) { - airo_print_err(ai->dev->name, "Bad size %d", len); + if (len > 2312) { + printk( KERN_ERR "airo: Bad size %d\n", len ); goto badrx; } if (len == 0) @@ -3664,8 +3571,8 @@ void mpi_receive_802_11 (struct airo_info *ai) if (gap <= 8) ptr += gap; else - airo_print_err(ai->dev->name, - "gaplen too big. Problems will follow..."); + printk(KERN_ERR + "airo: gaplen too big. Problems will follow...\n"); } memcpy ((char *)buffer + hdrlen, ptr, len); ptr += len; @@ -3737,15 +3644,15 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) if (issuecommand(ai, &cmd, &rsp) != SUCCESS) { if (lock) up(&ai->sem); - airo_print_err(ai->dev->name, "Error checking for AUX port"); + printk(KERN_ERR "airo: Error checking for AUX port\n"); return ERROR; } if (!aux_bap || rsp.status & 0xff00) { ai->bap_read = fast_bap_read; - airo_print_dbg(ai->dev->name, "Doing fast bap_reads"); + printk(KERN_DEBUG "airo: Doing fast bap_reads\n"); } else { ai->bap_read = aux_bap_read; - airo_print_dbg(ai->dev->name, "Doing AUX bap_reads"); + printk(KERN_DEBUG "airo: Doing AUX bap_reads\n"); } } if (lock) @@ -3776,18 +3683,19 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) if (cap_rid.softCap & 8) ai->config.rmode |= RXMODE_NORMALIZED_RSSI; else - airo_print_warn(ai->dev->name, "unknown received signal " - "level scale"); + printk(KERN_WARNING "airo: unknown received signal level scale\n"); } ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS; ai->config.authType = AUTH_OPEN; ai->config.modulation = MOD_CCK; +#ifdef MICSUPPORT if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) && (micsetup(ai) == SUCCESS)) { ai->config.opmode |= MODE_MIC; set_bit(FLAG_MIC_CAPABLE, &ai->flags); } +#endif /* Save off the MAC */ for( i = 0; i < ETH_ALEN; i++ ) { @@ -3840,8 +3748,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) status = enable_MAC(ai, &rsp, lock); if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) { - airo_print_err(ai->dev->name, "Bad MAC enable reason = %x, rid = %x," - " offset = %d", rsp.rsp0, rsp.rsp1, rsp.rsp2 ); + printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 ); return ERROR; } @@ -3884,8 +3791,8 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { } if ( max_tries == -1 ) { - airo_print_err(ai->dev->name, - "Max tries exceeded when issueing command"); + printk( KERN_ERR + "airo: Max tries exceeded when issueing command\n" ); if (IN4500(ai, COMMAND) & COMMAND_BUSY) OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); return ERROR; @@ -3897,11 +3804,11 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { pRsp->rsp1 = IN4500(ai, RESP1); pRsp->rsp2 = IN4500(ai, RESP2); if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) { - airo_print_err(ai->dev->name, "cmd= %x\n", pCmd->cmd); - airo_print_err(ai->dev->name, "status= %x\n", pRsp->status); - airo_print_err(ai->dev->name, "Rsp0= %x\n", pRsp->rsp0); - airo_print_err(ai->dev->name, "Rsp1= %x\n", pRsp->rsp1); - airo_print_err(ai->dev->name, "Rsp2= %x\n", pRsp->rsp2); + printk (KERN_ERR "airo: cmd= %x\n", pCmd->cmd); + printk (KERN_ERR "airo: status= %x\n", pRsp->status); + printk (KERN_ERR "airo: Rsp0= %x\n", pRsp->rsp0); + printk (KERN_ERR "airo: Rsp1= %x\n", pRsp->rsp1); + printk (KERN_ERR "airo: Rsp2= %x\n", pRsp->rsp2); } // clear stuck command busy if necessary @@ -3934,15 +3841,15 @@ static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap ) } } else if ( status & BAP_ERR ) { /* invalid rid or offset */ - airo_print_err(ai->dev->name, "BAP error %x %d", + printk( KERN_ERR "airo: BAP error %x %d\n", status, whichbap ); return ERROR; } else if (status & BAP_DONE) { // success return SUCCESS; } if ( !(max_tries--) ) { - airo_print_err(ai->dev->name, - "airo: BAP setup error too many retries\n"); + printk( KERN_ERR + "airo: BAP setup error too many retries\n" ); return ERROR; } // -- PC4500 missed it, try again @@ -4097,8 +4004,8 @@ static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, in len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2; if ( len <= 2 ) { - airo_print_err(ai->dev->name, - "Rid %x has a length of %d which is too short", + printk( KERN_ERR + "airo: Rid %x has a length of %d which is too short\n", (int)rid, (int)len ); rc = ERROR; goto done; @@ -4131,8 +4038,8 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid, Resp rsp; if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid)) - airo_print_err(ai->dev->name, - "%s: MAC should be disabled (rid=%04x)", + printk(KERN_ERR + "%s: MAC should be disabled (rid=%04x)\n", __FUNCTION__, rid); memset(&cmd, 0, sizeof(cmd)); memset(&rsp, 0, sizeof(rsp)); @@ -4148,7 +4055,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid, &ai->config_desc.rid_desc, sizeof(Rid)); if (len < 4 || len > 2047) { - airo_print_err(ai->dev->name, "%s: len=%d", __FUNCTION__, len); + printk(KERN_ERR "%s: len=%d\n",__FUNCTION__,len); rc = -1; } else { memcpy((char *)ai->config_desc.virtual_host_addr, @@ -4156,10 +4063,10 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid, rc = issuecommand(ai, &cmd, &rsp); if ((rc & 0xff00) != 0) { - airo_print_err(ai->dev->name, "%s: Write rid Error %d", - __FUNCTION__, rc); - airo_print_err(ai->dev->name, "%s: Cmd=%04x", - __FUNCTION__, cmd.cmd); + printk(KERN_ERR "%s: Write rid Error %d\n", + __FUNCTION__,rc); + printk(KERN_ERR "%s: Cmd=%04x\n", + __FUNCTION__,cmd.cmd); } if ((rsp.status & 0x7f00)) @@ -4258,17 +4165,20 @@ static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket) len >>= 16; if (len <= ETH_ALEN * 2) { - airo_print_warn(ai->dev->name, "Short packet %d", len); + printk( KERN_WARNING "Short packet %d\n", len ); return ERROR; } len -= ETH_ALEN * 2; +#ifdef MICSUPPORT if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && (ntohs(((u16 *)pPacket)[6]) != 0x888E)) { if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS) return ERROR; miclen = sizeof(pMic); } +#endif + // packet is destination[6], source[6], payload[len-12] // write the payload length and dst/src/payload if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR; @@ -4322,7 +4232,7 @@ static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket) } if (len < hdrlen) { - airo_print_warn(ai->dev->name, "Short packet %d", len); + printk( KERN_WARNING "Short packet %d\n", len ); return ERROR; } @@ -4719,14 +4629,15 @@ static int proc_stats_rid_open( struct inode *inode, i*44096) { - airo_print_warn(apriv->dev->name, - "Potentially disasterous buffer overflow averted!"); + printk(KERN_WARNING + "airo: Potentially disasterous buffer overflow averted!\n"); break; } j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]); } if (i*4>=stats.len){ - airo_print_warn(apriv->dev->name, "Got a short rid"); + printk(KERN_WARNING + "airo: Got a short rid\n"); } data->readlen = j; return 0; @@ -4888,7 +4799,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) { line += 14; v = get_dec_u16(line, &i, 4); - v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v); + v = (v<0) ? 0 : ((v>2312) ? 2312 : v); ai->config.rtsThres = (u16)v; set_bit (FLAG_COMMIT, &ai->flags); } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) { @@ -4922,7 +4833,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) { line += 15; v = get_dec_u16(line, &i, 4); - v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v); + v = (v<256) ? 256 : ((v>2312) ? 2312 : v); v = v & 0xfffe; /* Make sure its even */ ai->config.fragThresh = (u16)v; set_bit (FLAG_COMMIT, &ai->flags); @@ -4932,7 +4843,8 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) { case 'd': ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break; case 'c': ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break; case 'm': ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break; - default: airo_print_warn(ai->dev->name, "Unknown modulation"); + default: + printk( KERN_WARNING "airo: Unknown modulation\n" ); } } else if (!strncmp(line, "Preamble: ", 10)) { line += 10; @@ -4940,10 +4852,10 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) { case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break; case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break; case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break; - default: airo_print_warn(ai->dev->name, "Unknown preamble"); + default: printk(KERN_WARNING "airo: Unknown preamble\n"); } } else { - airo_print_warn(ai->dev->name, "Couldn't figure out %s", line); + printk( KERN_WARNING "Couldn't figure out %s\n", line ); } while( line[0] && line[0] != '\n' ) line++; if ( line[0] ) line++; @@ -5169,6 +5081,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, wkr.len = sizeof(wkr); wkr.kindex = 0xffff; wkr.mac[0] = (char)index; + if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index); if (perm) ai->defindex = (char)index; } else { // We are actually setting the key @@ -5177,6 +5090,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, wkr.klen = keylen; memcpy( wkr.key, key, keylen ); memcpy( wkr.mac, macaddr, ETH_ALEN ); + printk(KERN_INFO "Setting key %d\n", index); } if (perm) disable_MAC(ai, lock); @@ -5209,7 +5123,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { } j = 2; } else { - airo_print_err(ai->dev->name, "WepKey passed invalid key index"); + printk(KERN_ERR "airo: WepKey passed invalid key index\n"); return; } @@ -5622,16 +5536,17 @@ static int __init airo_init_module( void ) airo_entry->gid = proc_gid; for( i = 0; i < 4 && io[i] && irq[i]; i++ ) { - airo_print_info("", "Trying to configure ISA adapter at irq=%d " - "io=0x%x", irq[i], io[i] ); + printk( KERN_INFO + "airo: Trying to configure ISA adapter at irq=%d io=0x%x\n", + irq[i], io[i] ); if (init_airo_card( irq[i], io[i], 0, NULL )) have_isa_dev = 1; } #ifdef CONFIG_PCI - airo_print_info("", "Probing for PCI adapters"); + printk( KERN_INFO "airo: Probing for PCI adapters\n" ); pci_register_driver(&airo_driver); - airo_print_info("", "Finished probing for PCI adapters"); + printk( KERN_INFO "airo: Finished probing for PCI adapters\n" ); #endif /* Always exit with success, as we are a library module @@ -5643,7 +5558,7 @@ static int __init airo_init_module( void ) static void __exit airo_cleanup_module( void ) { while( airo_devices ) { - airo_print_info(airo_devices->dev->name, "Unregistering...\n"); + printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name ); stop_airo_card( airo_devices->dev, 1 ); } #ifdef CONFIG_PCI @@ -5754,8 +5669,7 @@ static int airo_set_freq(struct net_device *dev, /* We should do a better check than that, * based on the card capability !!! */ if((channel < 1) || (channel > 14)) { - airo_print_dbg(dev->name, "New channel value of %d is invalid!", - fwrq->m); + printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m); rc = -EINVAL; } else { readConfigRid(local, 1); @@ -5887,13 +5801,11 @@ static int airo_set_wap(struct net_device *dev, Cmd cmd; Resp rsp; APListRid APList_rid; - static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 }; if (awrq->sa_family != ARPHRD_ETHER) return -EINVAL; - else if (!memcmp(any, awrq->sa_data, ETH_ALEN) || - !memcmp(off, awrq->sa_data, ETH_ALEN)) { + else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) { memset(&cmd, 0, sizeof(cmd)); cmd.cmd=CMD_LOSE_SYNC; if (down_interruptible(&local->sem)) @@ -6079,8 +5991,8 @@ static int airo_set_rts(struct net_device *dev, int rthr = vwrq->value; if(vwrq->disabled) - rthr = AIRO_DEF_MTU; - if((rthr < 0) || (rthr > AIRO_DEF_MTU)) { + rthr = 2312; + if((rthr < 0) || (rthr > 2312)) { return -EINVAL; } readConfigRid(local, 1); @@ -6103,7 +6015,7 @@ static int airo_get_rts(struct net_device *dev, readConfigRid(local, 1); vwrq->value = local->config.rtsThres; - vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU); + vwrq->disabled = (vwrq->value >= 2312); vwrq->fixed = 1; return 0; @@ -6122,8 +6034,8 @@ static int airo_set_frag(struct net_device *dev, int fthr = vwrq->value; if(vwrq->disabled) - fthr = AIRO_DEF_MTU; - if((fthr < 256) || (fthr > AIRO_DEF_MTU)) { + fthr = 2312; + if((fthr < 256) || (fthr > 2312)) { return -EINVAL; } fthr &= ~0x1; /* Get an even value - is it really needed ??? */ @@ -6147,7 +6059,7 @@ static int airo_get_frag(struct net_device *dev, readConfigRid(local, 1); vwrq->value = local->config.fragThresh; - vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU); + vwrq->disabled = (vwrq->value >= 2312); vwrq->fixed = 1; return 0; @@ -6382,272 +6294,6 @@ static int airo_get_encode(struct net_device *dev, return 0; } -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set extended Encryption parameters - */ -static int airo_set_encodeext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - struct airo_info *local = dev->priv; - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - CapabilityRid cap_rid; /* Card capability info */ - int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 ); - u16 currentAuthType = local->config.authType; - int idx, key_len, alg = ext->alg, set_key = 1; - wep_key_t key; - - /* Is WEP supported ? */ - readCapabilityRid(local, &cap_rid, 1); - /* Older firmware doesn't support this... - if(!(cap_rid.softCap & 2)) { - return -EOPNOTSUPP; - } */ - readConfigRid(local, 1); - - /* Determine and validate the key index */ - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) { - if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1)) - return -EINVAL; - idx--; - } else - idx = get_wep_key(local, 0xffff); - - if (encoding->flags & IW_ENCODE_DISABLED) - alg = IW_ENCODE_ALG_NONE; - - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - /* Only set transmit key index here, actual - * key is set below if needed. - */ - set_wep_key(local, idx, NULL, 0, perm, 1); - set_key = ext->key_len > 0 ? 1 : 0; - } - - if (set_key) { - /* Set the requested key first */ - memset(key.key, 0, MAX_KEY_SIZE); - switch (alg) { - case IW_ENCODE_ALG_NONE: - key.len = 0; - break; - case IW_ENCODE_ALG_WEP: - if (ext->key_len > MIN_KEY_SIZE) { - key.len = MAX_KEY_SIZE; - } else if (ext->key_len > 0) { - key.len = MIN_KEY_SIZE; - } else { - return -EINVAL; - } - key_len = min (ext->key_len, key.len); - memcpy(key.key, ext->key, key_len); - break; - default: - return -EINVAL; - } - /* Send the key to the card */ - set_wep_key(local, idx, key.key, key.len, perm, 1); - } - - /* Read the flags */ - if(encoding->flags & IW_ENCODE_DISABLED) - local->config.authType = AUTH_OPEN; // disable encryption - if(encoding->flags & IW_ENCODE_RESTRICTED) - local->config.authType = AUTH_SHAREDKEY; // Only Both - if(encoding->flags & IW_ENCODE_OPEN) - local->config.authType = AUTH_ENCRYPT; // Only Wep - /* Commit the changes to flags if needed */ - if (local->config.authType != currentAuthType) - set_bit (FLAG_COMMIT, &local->flags); - - return -EINPROGRESS; -} - - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get extended Encryption parameters - */ -static int airo_get_encodeext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - struct airo_info *local = dev->priv; - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - CapabilityRid cap_rid; /* Card capability info */ - int idx, max_key_len; - - /* Is it supported ? */ - readCapabilityRid(local, &cap_rid, 1); - if(!(cap_rid.softCap & 2)) { - return -EOPNOTSUPP; - } - readConfigRid(local, 1); - - 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 > ((cap_rid.softCap & 0x80) ? 4:1)) - return -EINVAL; - idx--; - } else - idx = get_wep_key(local, 0xffff); - - encoding->flags = idx + 1; - memset(ext, 0, sizeof(*ext)); - - /* Check encryption mode */ - switch(local->config.authType) { - case AUTH_ENCRYPT: - encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED; - break; - case AUTH_SHAREDKEY: - encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED; - break; - default: - case AUTH_OPEN: - encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED; - break; - } - /* We can't return the key, so set the proper flag and return zero */ - encoding->flags |= IW_ENCODE_NOKEY; - memset(extra, 0, 16); - - /* Copy the key to the user buffer */ - ext->key_len = get_wep_key(local, idx); - if (ext->key_len > 16) { - ext->key_len=0; - } - - return 0; -} - - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set extended authentication parameters - */ -static int airo_set_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct airo_info *local = dev->priv; - struct iw_param *param = &wrqu->param; - u16 currentAuthType = local->config.authType; - - switch (param->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_KEY_MGMT: - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - case IW_AUTH_PRIVACY_INVOKED: - /* - * airo does not use these parameters - */ - break; - - case IW_AUTH_DROP_UNENCRYPTED: - if (param->value) { - /* Only change auth type if unencrypted */ - if (currentAuthType == AUTH_OPEN) - local->config.authType = AUTH_ENCRYPT; - } else { - local->config.authType = AUTH_OPEN; - } - - /* Commit the changes to flags if needed */ - if (local->config.authType != currentAuthType) - set_bit (FLAG_COMMIT, &local->flags); - break; - - case IW_AUTH_80211_AUTH_ALG: { - /* FIXME: What about AUTH_OPEN? This API seems to - * disallow setting our auth to AUTH_OPEN. - */ - if (param->value & IW_AUTH_ALG_SHARED_KEY) { - local->config.authType = AUTH_SHAREDKEY; - } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { - local->config.authType = AUTH_ENCRYPT; - } else - return -EINVAL; - break; - - /* Commit the changes to flags if needed */ - if (local->config.authType != currentAuthType) - set_bit (FLAG_COMMIT, &local->flags); - } - - case IW_AUTH_WPA_ENABLED: - /* Silently accept disable of WPA */ - if (param->value > 0) - return -EOPNOTSUPP; - break; - - default: - return -EOPNOTSUPP; - } - return -EINPROGRESS; -} - - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get extended authentication parameters - */ -static int airo_get_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct airo_info *local = dev->priv; - struct iw_param *param = &wrqu->param; - u16 currentAuthType = local->config.authType; - - switch (param->flags & IW_AUTH_INDEX) { - case IW_AUTH_DROP_UNENCRYPTED: - switch (currentAuthType) { - case AUTH_SHAREDKEY: - case AUTH_ENCRYPT: - param->value = 1; - break; - default: - param->value = 0; - break; - } - break; - - case IW_AUTH_80211_AUTH_ALG: - switch (currentAuthType) { - case AUTH_SHAREDKEY: - param->value = IW_AUTH_ALG_SHARED_KEY; - break; - case AUTH_ENCRYPT: - default: - param->value = IW_AUTH_ALG_OPEN_SYSTEM; - break; - } - break; - - case IW_AUTH_WPA_ENABLED: - param->value = 0; - break; - - default: - return -EOPNOTSUPP; - } - return 0; -} - - /*------------------------------------------------------------------*/ /* * Wireless Handler : set Tx-Power @@ -6842,9 +6488,9 @@ static int airo_get_range(struct net_device *dev, range->throughput = 1500 * 1000; range->min_rts = 0; - range->max_rts = AIRO_DEF_MTU; + range->max_rts = 2312; range->min_frag = 256; - range->max_frag = AIRO_DEF_MTU; + range->max_frag = 2312; if(cap_rid.softCap & 2) { // WEP: RC4 40 bits @@ -7105,7 +6751,6 @@ static int airo_set_scan(struct net_device *dev, struct airo_info *ai = dev->priv; Cmd cmd; Resp rsp; - int wake = 0; /* Note : you may have realised that, as this is a SET operation, * this is privileged and therefore a normal user can't @@ -7115,25 +6760,17 @@ static int airo_set_scan(struct net_device *dev, * Jean II */ if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN; - if (down_interruptible(&ai->sem)) - return -ERESTARTSYS; - - /* If there's already a scan in progress, don't - * trigger another one. */ - if (ai->scan_timeout > 0) - goto out; - /* Initiate a scan command */ - ai->scan_timeout = RUN_AT(3*HZ); memset(&cmd, 0, sizeof(cmd)); cmd.cmd=CMD_LISTBSS; + if (down_interruptible(&ai->sem)) + return -ERESTARTSYS; issuecommand(ai, &cmd, &rsp); - wake = 1; - -out: + ai->scan_timestamp = jiffies; up(&ai->sem); - if (wake) - wake_up_interruptible(&ai->thr_wait); + + /* At this point, just return to the user. */ + return 0; } @@ -7253,38 +6890,59 @@ static int airo_get_scan(struct net_device *dev, char *extra) { struct airo_info *ai = dev->priv; - BSSListElement *net; - int err = 0; + BSSListRid BSSList; + int rc; char *current_ev = extra; - /* If a scan is in-progress, return -EAGAIN */ - if (ai->scan_timeout > 0) + /* When we are associated again, the scan has surely finished. + * Just in case, let's make sure enough time has elapsed since + * we started the scan. - Javier */ + if(ai->scan_timestamp && time_before(jiffies,ai->scan_timestamp+3*HZ)) { + /* Important note : we don't want to block the caller + * until results are ready for various reasons. + * First, managing wait queues is complex and racy + * (there may be multiple simultaneous callers). + * Second, we grab some rtnetlink lock before comming + * here (in dev_ioctl()). + * Third, the caller can wait on the Wireless Event + * - Jean II */ return -EAGAIN; + } + ai->scan_timestamp = 0; - if (down_interruptible(&ai->sem)) - return -EAGAIN; + /* There's only a race with proc_BSSList_open(), but its + * consequences are begnign. So I don't bother fixing it - Javier */ - list_for_each_entry (net, &ai->network_list, list) { + /* Try to read the first entry of the scan result */ + rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 1); + if((rc) || (BSSList.index == 0xffff)) { + /* Client error, no scan results... + * The caller need to restart the scan. */ + return -ENODATA; + } + + /* Read and parse all entries */ + while((!rc) && (BSSList.index != 0xffff)) { /* Translate to WE format this entry */ current_ev = airo_translate_scan(dev, current_ev, extra + dwrq->length, - &net->bss); + &BSSList); /* Check if there is space for one more entry */ if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) { /* Ask user space to try again with a bigger buffer */ - err = -E2BIG; - goto out; + return -E2BIG; } - } + /* Read next entry */ + rc = PC4500_readrid(ai, RID_BSSLISTNEXT, + &BSSList, sizeof(BSSList), 1); + } /* Length of data */ dwrq->length = (current_ev - extra); dwrq->flags = 0; /* todo */ -out: - up(&ai->sem); - return err; + return 0; } /*------------------------------------------------------------------*/ @@ -7392,15 +7050,6 @@ static const iw_handler airo_handler[] = (iw_handler) airo_get_encode, /* SIOCGIWENCODE */ (iw_handler) airo_set_power, /* SIOCSIWPOWER */ (iw_handler) airo_get_power, /* SIOCGIWPOWER */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWGENIE */ - (iw_handler) NULL, /* SIOCGIWGENIE */ - (iw_handler) airo_set_auth, /* SIOCSIWAUTH */ - (iw_handler) airo_get_auth, /* SIOCGIWAUTH */ - (iw_handler) airo_set_encodeext, /* SIOCSIWENCODEEXT */ - (iw_handler) airo_get_encodeext, /* SIOCGIWENCODEEXT */ - (iw_handler) NULL, /* SIOCSIWPMKSA */ }; /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here. @@ -7621,11 +7270,13 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) { case AIROGSTAT: ridcode = RID_STATUS; break; case AIROGSTATSD32: ridcode = RID_STATSDELTA; break; case AIROGSTATSC32: ridcode = RID_STATS; break; +#ifdef MICSUPPORT case AIROGMICSTATS: if (copy_to_user(comp->data, &ai->micstats, min((int)comp->len,(int)sizeof(ai->micstats)))) return -EFAULT; return 0; +#endif case AIRORRID: ridcode = comp->ridnum; break; default: return -EINVAL; @@ -7657,7 +7308,9 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) { static int writerids(struct net_device *dev, aironet_ioctl *comp) { struct airo_info *ai = dev->priv; int ridcode; +#ifdef MICSUPPORT int enabled; +#endif Resp rsp; static int (* writer)(struct airo_info *, u16 rid, const void *, int, int); unsigned char *iobuf; @@ -7714,9 +7367,11 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) { PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1); +#ifdef MICSUPPORT enabled = ai->micstats.enabled; memset(&ai->micstats,0,sizeof(ai->micstats)); ai->micstats.enabled = enabled; +#endif if (copy_to_user(comp->data, iobuf, min((int)comp->len, (int)RIDSIZE))) { @@ -7832,7 +7487,7 @@ static int cmdreset(struct airo_info *ai) { disable_MAC(ai, 1); if(!waitbusy (ai)){ - airo_print_info(ai->dev->name, "Waitbusy hang before RESET"); + printk(KERN_INFO "Waitbusy hang before RESET\n"); return -EBUSY; } @@ -7841,7 +7496,7 @@ static int cmdreset(struct airo_info *ai) { ssleep(1); /* WAS 600 12/7/00 */ if(!waitbusy (ai)){ - airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET"); + printk(KERN_INFO "Waitbusy hang AFTER RESET\n"); return -EBUSY; } return 0; @@ -7869,7 +7524,7 @@ static int setflashmode (struct airo_info *ai) { if(!waitbusy(ai)) { clear_bit (FLAG_FLASHING, &ai->flags); - airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode"); + printk(KERN_INFO "Waitbusy hang after setflash mode\n"); return -EIO; } return 0; @@ -7898,7 +7553,7 @@ static int flashpchar(struct airo_info *ai,int byte,int dwelltime) { /* timeout for busy clear wait */ if(waittime <= 0 ){ - airo_print_info(ai->dev->name, "flash putchar busywait timeout!"); + printk(KERN_INFO "flash putchar busywait timeout! \n"); return -EBUSY; } @@ -7987,7 +7642,7 @@ static int flashrestart(struct airo_info *ai,struct net_device *dev){ if (!test_bit(FLAG_MPI,&ai->flags)) for( i = 0; i < MAX_FIDS; i++ ) { ai->fids[i] = transmit_allocate - ( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 ); + ( ai, 2312, i >= MAX_FIDS / 2 ); } ssleep(1); /* Added 12/7/00 */ diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index af0cbb6c5..a496460ce 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -80,8 +80,8 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards"); event handler. */ -static int airo_config(struct pcmcia_device *link); -static void airo_release(struct pcmcia_device *link); +static void airo_config(dev_link_t *link); +static void airo_release(dev_link_t *link); /* The attach() and detach() entry points are used to create and destroy @@ -101,10 +101,10 @@ static void airo_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the aironet device. Each actual PCMCIA card corresponds to one device instance, and is described - by one struct pcmcia_device structure (defined in ds.h). + by one dev_link_t structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of struct pcmcia_device pointers, where minor + memory card driver uses an array of dev_link_t pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -114,7 +114,7 @@ static void airo_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device + in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. @@ -141,16 +141,24 @@ typedef struct local_info_t { ======================================================================*/ -static int airo_probe(struct pcmcia_device *p_dev) +static int airo_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; local_info_t *local; DEBUG(0, "airo_attach()\n"); + /* Initialize the dev_link_t structure */ + link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); + if (!link) { + printk(KERN_ERR "airo_cs: no memory for new device\n"); + return -ENOMEM; + } + /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; - p_dev->irq.Handler = NULL; + 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 @@ -159,18 +167,26 @@ static int airo_probe(struct pcmcia_device *p_dev) and attributes of IO windows) are fixed by the nature of the device, and can be hard-wired here. */ - p_dev->conf.Attributes = 0; - p_dev->conf.IntType = INT_MEMORY_AND_IO; + link->conf.Attributes = 0; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; /* Allocate space for private device-specific data */ local = kzalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) { printk(KERN_ERR "airo_cs: no memory for new device\n"); + kfree (link); return -ENOMEM; } - p_dev->priv = local; + link->priv = local; - return airo_config(p_dev); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + airo_config(link); + + return 0; } /* airo_attach */ /*====================================================================== @@ -182,11 +198,14 @@ static int airo_probe(struct pcmcia_device *p_dev) ======================================================================*/ -static void airo_detach(struct pcmcia_device *link) +static void airo_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + DEBUG(0, "airo_detach(0x%p)\n", link); - airo_release(link); + if (link->state & DEV_CONFIG) + airo_release(link); if ( ((local_info_t*)link->priv)->eth_dev ) { stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 ); @@ -194,6 +213,7 @@ static void airo_detach(struct pcmcia_device *link) ((local_info_t*)link->priv)->eth_dev = NULL; kfree(link->priv); + kfree(link); } /* airo_detach */ /*====================================================================== @@ -207,8 +227,9 @@ static void airo_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int airo_config(struct pcmcia_device *link) +static void airo_config(dev_link_t *link) { + client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; @@ -216,7 +237,8 @@ static int airo_config(struct pcmcia_device *link) u_char buf[64]; win_req_t req; memreq_t map; - + + handle = link->handle; dev = link->priv; DEBUG(0, "airo_config(0x%p)\n", link); @@ -230,12 +252,15 @@ static int airo_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - + + /* Configure card */ + link->state |= DEV_CONFIG; + /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including @@ -249,12 +274,12 @@ static int airo_config(struct pcmcia_device *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; @@ -269,11 +294,16 @@ static int airo_config(struct pcmcia_device *link) /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1<conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000; + else if (dflt.vcc.present & (1<conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000; + if (cfg->vpp1.present & (1<conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* Do we need to allocate an interrupt? */ @@ -299,12 +329,12 @@ static int airo_config(struct pcmcia_device *link) } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; /* Now set up a common memory window, if needed. There is room - in the struct pcmcia_device structure for one memory window handle, + in the dev_link_t structure for one memory window handle, but if the base addresses need to be saved, or if multiple windows are needed, the info should go in the private data structure for this device. @@ -320,7 +350,7 @@ static int airo_config(struct pcmcia_device *link) req.Base = mem->win[0].host_addr; req.Size = mem->win[0].len; req.AccessSpeed = 0; - if (pcmcia_request_window(&link, &req, &link->win) != 0) + if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(link->win, &map) != 0) @@ -330,7 +360,7 @@ static int airo_config(struct pcmcia_device *link) break; next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } /* @@ -339,32 +369,33 @@ static int airo_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); ((local_info_t*)link->priv)->eth_dev = init_airo_card( link->irq.AssignedIRQ, - link->io.BasePort1, 1, &handle_to_dev(link) ); + link->io.BasePort1, 1, &handle_to_dev(handle) ); if (!((local_info_t*)link->priv)->eth_dev) 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_node. + initialized and arranged in a linked list at link->dev. */ strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name ); dev->node.major = dev->node.minor = 0; - link->dev_node = &dev->node; + link->dev = &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.Vpp) - printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", + dev->node.dev_name, link->conf.ConfigIndex, + link->conf.Vcc/10, link->conf.Vcc%10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -377,12 +408,14 @@ static int airo_config(struct pcmcia_device *link) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base+req.Size-1); printk("\n"); - return 0; - + + link->state &= ~DEV_CONFIG_PENDING; + return; + cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); airo_release(link); - return -ENODEV; + } /* airo_config */ /*====================================================================== @@ -393,26 +426,51 @@ static int airo_config(struct pcmcia_device *link) ======================================================================*/ -static void airo_release(struct pcmcia_device *link) +static void airo_release(dev_link_t *link) { DEBUG(0, "airo_release(0x%p)\n", link); - pcmcia_disable_device(link); + + /* Unlink the device chain */ + link->dev = NULL; + + /* + In a normal driver, additional code may be needed to release + other kernel data structures associated with this device. + */ + + /* Don't bother checking to see if these succeed or not */ + if (link->win) + pcmcia_release_window(link->win); + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } -static int airo_suspend(struct pcmcia_device *link) +static int airo_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); local_info_t *local = link->priv; - netif_device_detach(local->eth_dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + netif_device_detach(local->eth_dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int airo_resume(struct pcmcia_device *link) +static int airo_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); local_info_t *local = link->priv; - if (link->open) { + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); reset_airo_card(local->eth_dev); netif_device_attach(local->eth_dev); } @@ -434,7 +492,7 @@ static struct pcmcia_driver airo_driver = { .drv = { .name = "airo_cs", }, - .probe = airo_probe, + .probe = airo_attach, .remove = airo_detach, .id_table = airo_ids, .suspend = airo_suspend, diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c index bed6823d9..0e1ac338c 100644 --- a/drivers/net/wireless/arlan-main.c +++ b/drivers/net/wireless/arlan-main.c @@ -1838,7 +1838,7 @@ struct net_device * __init arlan_probe(int unit) } #ifdef MODULE -int __init init_module(void) +int init_module(void) { int i = 0; @@ -1860,7 +1860,7 @@ int __init init_module(void) } -void __exit cleanup_module(void) +void cleanup_module(void) { int i = 0; struct net_device *dev; diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 8606c8888..dfc24016b 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -137,6 +137,44 @@ static struct { #define MAC_BOOT_COMPLETE 0x0010 // MAC boot has been completed #define MAC_INIT_OK 0x0002 // MAC boot has been completed +#define C80211_SUBTYPE_MGMT_ASS_REQUEST 0x00 +#define C80211_SUBTYPE_MGMT_ASS_RESPONSE 0x10 +#define C80211_SUBTYPE_MGMT_REASS_REQUEST 0x20 +#define C80211_SUBTYPE_MGMT_REASS_RESPONSE 0x30 +#define C80211_SUBTYPE_MGMT_ProbeRequest 0x40 +#define C80211_SUBTYPE_MGMT_ProbeResponse 0x50 +#define C80211_SUBTYPE_MGMT_BEACON 0x80 +#define C80211_SUBTYPE_MGMT_ATIM 0x90 +#define C80211_SUBTYPE_MGMT_DISASSOSIATION 0xA0 +#define C80211_SUBTYPE_MGMT_Authentication 0xB0 +#define C80211_SUBTYPE_MGMT_Deauthentication 0xC0 + +#define C80211_MGMT_AAN_OPENSYSTEM 0x0000 +#define C80211_MGMT_AAN_SHAREDKEY 0x0001 + +#define C80211_MGMT_CAPABILITY_ESS 0x0001 // see 802.11 p.58 +#define C80211_MGMT_CAPABILITY_IBSS 0x0002 // - " - +#define C80211_MGMT_CAPABILITY_CFPollable 0x0004 // - " - +#define C80211_MGMT_CAPABILITY_CFPollRequest 0x0008 // - " - +#define C80211_MGMT_CAPABILITY_Privacy 0x0010 // - " - + +#define C80211_MGMT_SC_Success 0 +#define C80211_MGMT_SC_Unspecified 1 +#define C80211_MGMT_SC_SupportCapabilities 10 +#define C80211_MGMT_SC_ReassDenied 11 +#define C80211_MGMT_SC_AssDenied 12 +#define C80211_MGMT_SC_AuthAlgNotSupported 13 +#define C80211_MGMT_SC_AuthTransSeqNumError 14 +#define C80211_MGMT_SC_AuthRejectChallenge 15 +#define C80211_MGMT_SC_AuthRejectTimeout 16 +#define C80211_MGMT_SC_AssDeniedHandleAP 17 +#define C80211_MGMT_SC_AssDeniedBSSRate 18 + +#define C80211_MGMT_ElementID_SSID 0 +#define C80211_MGMT_ElementID_SupportedRates 1 +#define C80211_MGMT_ElementID_ChallengeText 16 +#define C80211_MGMT_CAPABILITY_ShortPreamble 0x0020 + #define MIB_MAX_DATA_BYTES 212 #define MIB_HEADER_SIZE 4 /* first four fields */ @@ -2797,7 +2835,7 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 channel) { int rejoin = 0; - int new = capability & MFIE_TYPE_POWER_CONSTRAINT ? + int new = capability & C80211_MGMT_CAPABILITY_ShortPreamble ? SHORT_PREAMBLE : LONG_PREAMBLE; if (priv->preamble != new) { @@ -2883,11 +2921,11 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) memcpy(header.addr2, priv->dev->dev_addr, 6); memcpy(header.addr3, priv->CurrentBSSID, 6); - body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS); + body.capability = cpu_to_le16(C80211_MGMT_CAPABILITY_ESS); if (priv->wep_is_on) - body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_Privacy); if (priv->preamble == SHORT_PREAMBLE) - body.capability |= cpu_to_le16(MFIE_TYPE_POWER_CONSTRAINT); + body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_ShortPreamble); body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period); @@ -2901,10 +2939,10 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) bodysize = 12 + priv->SSID_size; } - ssid_el_p[0] = MFIE_TYPE_SSID; + ssid_el_p[0] = C80211_MGMT_ElementID_SSID; ssid_el_p[1] = priv->SSID_size; memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size); - ssid_el_p[2 + priv->SSID_size] = MFIE_TYPE_RATES; + ssid_el_p[2 + priv->SSID_size] = C80211_MGMT_ElementID_SupportedRates; ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */ memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4); @@ -2966,7 +3004,7 @@ static void store_bss_info(struct atmel_private *priv, u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len, u8 *ssid, int is_beacon) { - u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3; + u8 *bss = capability & C80211_MGMT_CAPABILITY_ESS ? header->addr2 : header->addr3; int i, index; for (index = -1, i = 0; i < priv->BSS_list_entries; i++) @@ -2992,16 +3030,16 @@ static void store_bss_info(struct atmel_private *priv, priv->BSSinfo[index].channel = channel; priv->BSSinfo[index].beacon_period = beacon_period; - priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY; + priv->BSSinfo[index].UsingWEP = capability & C80211_MGMT_CAPABILITY_Privacy; memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len); priv->BSSinfo[index].SSIDsize = ssid_len; - if (capability & WLAN_CAPABILITY_IBSS) + if (capability & C80211_MGMT_CAPABILITY_IBSS) priv->BSSinfo[index].BSStype = IW_MODE_ADHOC; - else if (capability & WLAN_CAPABILITY_ESS) + else if (capability & C80211_MGMT_CAPABILITY_ESS) priv->BSSinfo[index].BSStype =IW_MODE_INFRA; - priv->BSSinfo[index].preamble = capability & MFIE_TYPE_POWER_CONSTRAINT ? + priv->BSSinfo[index].preamble = capability & C80211_MGMT_CAPABILITY_ShortPreamble ? SHORT_PREAMBLE : LONG_PREAMBLE; } @@ -3012,7 +3050,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len) u16 trans_seq_no = le16_to_cpu(auth->trans_seq); u16 system = le16_to_cpu(auth->alg); - if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) { + if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) { /* no WEP */ if (priv->station_was_associated) { atmel_enter_state(priv, STATION_STATE_REASSOCIATING); @@ -3025,19 +3063,19 @@ static void authenticate(struct atmel_private *priv, u16 frame_len) } } - if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) { + if (status == C80211_MGMT_SC_Success && priv->wep_is_on) { int should_associate = 0; /* WEP */ if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum) return; - if (system == WLAN_AUTH_OPEN) { + if (system == C80211_MGMT_AAN_OPENSYSTEM) { if (trans_seq_no == 0x0002) { should_associate = 1; } - } else if (system == WLAN_AUTH_SHARED_KEY) { + } else if (system == C80211_MGMT_AAN_SHAREDKEY) { if (trans_seq_no == 0x0002 && - auth->el_id == MFIE_TYPE_CHALLENGE) { + auth->el_id == C80211_MGMT_ElementID_ChallengeText) { send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len); return; } else if (trans_seq_no == 0x0004) { @@ -3102,8 +3140,8 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype) if (frame_len < 8 + rates_len) return; - if (status == WLAN_STATUS_SUCCESS) { - if (subtype == IEEE80211_STYPE_ASSOC_RESP) + if (status == C80211_MGMT_SC_Success) { + if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE) priv->AssociationRequestRetryCnt = 0; else priv->ReAssociationRequestRetryCnt = 0; @@ -3140,9 +3178,9 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype) return; } - if (subtype == IEEE80211_STYPE_ASSOC_RESP && - status != WLAN_STATUS_ASSOC_DENIED_RATES && - status != WLAN_STATUS_CAPS_UNSUPPORTED && + if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE && + status != C80211_MGMT_SC_AssDeniedBSSRate && + status != C80211_MGMT_SC_SupportCapabilities && priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) { mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); priv->AssociationRequestRetryCnt++; @@ -3150,9 +3188,9 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype) return; } - if (subtype == IEEE80211_STYPE_REASSOC_RESP && - status != WLAN_STATUS_ASSOC_DENIED_RATES && - status != WLAN_STATUS_CAPS_UNSUPPORTED && + if (subtype == C80211_SUBTYPE_MGMT_REASS_RESPONSE && + status != C80211_MGMT_SC_AssDeniedBSSRate && + status != C80211_MGMT_SC_SupportCapabilities && priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) { mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); priv->ReAssociationRequestRetryCnt++; @@ -3287,8 +3325,8 @@ static void atmel_management_frame(struct atmel_private *priv, subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE; switch (subtype) { - case IEEE80211_STYPE_BEACON: - case IEEE80211_STYPE_PROBE_RESP: + case C80211_SUBTYPE_MGMT_BEACON: + case C80211_SUBTYPE_MGMT_ProbeResponse: /* beacon frame has multiple variable-length fields - never let an engineer loose with a data structure design. */ @@ -3346,19 +3384,19 @@ static void atmel_management_frame(struct atmel_private *priv, beacon_interval, channel, rssi, ssid_length, &beacon->rates_el_id, - subtype == IEEE80211_STYPE_BEACON); + subtype == C80211_SUBTYPE_MGMT_BEACON); } break; - case IEEE80211_STYPE_AUTH: + case C80211_SUBTYPE_MGMT_Authentication: if (priv->station_state == STATION_STATE_AUTHENTICATING) authenticate(priv, frame_len); break; - case IEEE80211_STYPE_ASSOC_RESP: - case IEEE80211_STYPE_REASSOC_RESP: + case C80211_SUBTYPE_MGMT_ASS_RESPONSE: + case C80211_SUBTYPE_MGMT_REASS_RESPONSE: if (priv->station_state == STATION_STATE_ASSOCIATING || priv->station_state == STATION_STATE_REASSOCIATING) @@ -3366,7 +3404,7 @@ static void atmel_management_frame(struct atmel_private *priv, break; - case IEEE80211_STYPE_DISASSOC: + case C80211_SUBTYPE_MGMT_DISASSOSIATION: if (priv->station_is_associated && priv->operating_mode == IW_MODE_INFRA && is_frame_from_current_bss(priv, header)) { @@ -3379,7 +3417,7 @@ static void atmel_management_frame(struct atmel_private *priv, break; - case IEEE80211_STYPE_DEAUTH: + case C80211_SUBTYPE_MGMT_Deauthentication: if (priv->operating_mode == IW_MODE_INFRA && is_frame_from_current_bss(priv, header)) { priv->station_was_associated = 0; @@ -3415,12 +3453,12 @@ static void atmel_management_timer(u_long a) priv->AuthenticationRequestRetryCnt = 0; restart_search(priv); } else { - int auth = WLAN_AUTH_OPEN; + int auth = C80211_MGMT_AAN_OPENSYSTEM; priv->AuthenticationRequestRetryCnt++; priv->CurrentAuthentTransactionSeqNum = 0x0001; mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); if (priv->wep_is_on && priv->exclude_unencrypted) - auth = WLAN_AUTH_SHARED_KEY; + auth = C80211_MGMT_AAN_SHAREDKEY; send_authentication_request(priv, auth, NULL, 0); } break; @@ -3463,7 +3501,6 @@ static void atmel_command_irq(struct atmel_private *priv) u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET)); u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET)); int fast_scan; - union iwreq_data wrqu; if (status == CMD_STATUS_IDLE || status == CMD_STATUS_IN_PROGRESS) @@ -3488,7 +3525,6 @@ static void atmel_command_irq(struct atmel_private *priv) atmel_scan(priv, 1); } else { int bss_index = retrieve_bss(priv); - int notify_scan_complete = 1; if (bss_index != -1) { atmel_join_bss(priv, bss_index); } else if (priv->operating_mode == IW_MODE_ADHOC && @@ -3497,14 +3533,8 @@ static void atmel_command_irq(struct atmel_private *priv) } else { priv->fast_scan = !fast_scan; atmel_scan(priv, 1); - notify_scan_complete = 0; } priv->site_survey_state = SITE_SURVEY_COMPLETED; - if (notify_scan_complete) { - wrqu.data.length = 0; - wrqu.data.flags = 0; - wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); - } } break; @@ -3517,9 +3547,6 @@ static void atmel_command_irq(struct atmel_private *priv) priv->site_survey_state = SITE_SURVEY_COMPLETED; if (priv->station_is_associated) { atmel_enter_state(priv, STATION_STATE_READY); - wrqu.data.length = 0; - wrqu.data.flags = 0; - wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); } else { atmel_scan(priv, 1); } @@ -3531,14 +3558,14 @@ static void atmel_command_irq(struct atmel_private *priv) priv->station_was_associated = priv->station_is_associated; atmel_enter_state(priv, STATION_STATE_READY); } else { - int auth = WLAN_AUTH_OPEN; + int auth = C80211_MGMT_AAN_OPENSYSTEM; priv->AuthenticationRequestRetryCnt = 0; atmel_enter_state(priv, STATION_STATE_AUTHENTICATING); mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); priv->CurrentAuthentTransactionSeqNum = 0x0001; if (priv->wep_is_on && priv->exclude_unencrypted) - auth = WLAN_AUTH_SHARED_KEY; + auth = C80211_MGMT_AAN_SHAREDKEY; send_authentication_request(priv, auth, NULL, 0); } return; diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 26bf11275..d6f4a5a3e 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -91,8 +91,8 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards"); event handler. */ -static int atmel_config(struct pcmcia_device *link); -static void atmel_release(struct pcmcia_device *link); +static void atmel_config(dev_link_t *link); +static void atmel_release(dev_link_t *link); /* The attach() and detach() entry points are used to create and destroy @@ -112,10 +112,10 @@ static void atmel_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the atmelnet device. Each actual PCMCIA card corresponds to one device instance, and is described - by one struct pcmcia_device structure (defined in ds.h). + by one dev_link_t structure (defined in ds.h). You may not want to use a linked list for this -- for example, the - memory card driver uses an array of struct pcmcia_device pointers, where minor + memory card driver uses an array of dev_link_t pointers, where minor device numbers are used to derive the corresponding array index. */ @@ -125,7 +125,7 @@ static void atmel_detach(struct pcmcia_device *p_dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device + in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally shouldn't be allocated dynamically. @@ -152,16 +152,24 @@ typedef struct local_info_t { ======================================================================*/ -static int atmel_probe(struct pcmcia_device *p_dev) +static int atmel_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; local_info_t *local; DEBUG(0, "atmel_attach()\n"); + /* Initialize the dev_link_t structure */ + link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); + if (!link) { + printk(KERN_ERR "atmel_cs: no memory for new device\n"); + return -ENOMEM; + } + /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; - p_dev->irq.Handler = NULL; + 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 @@ -170,18 +178,26 @@ static int atmel_probe(struct pcmcia_device *p_dev) and attributes of IO windows) are fixed by the nature of the device, and can be hard-wired here. */ - p_dev->conf.Attributes = 0; - p_dev->conf.IntType = INT_MEMORY_AND_IO; + link->conf.Attributes = 0; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; /* Allocate space for private device-specific data */ local = kzalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) { printk(KERN_ERR "atmel_cs: no memory for new device\n"); + kfree (link); return -ENOMEM; } - p_dev->priv = local; + link->priv = local; - return atmel_config(p_dev); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + atmel_config(link); + + return 0; } /* atmel_attach */ /*====================================================================== @@ -193,13 +209,17 @@ static int atmel_probe(struct pcmcia_device *p_dev) ======================================================================*/ -static void atmel_detach(struct pcmcia_device *link) +static void atmel_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + DEBUG(0, "atmel_detach(0x%p)\n", link); - atmel_release(link); + if (link->state & DEV_CONFIG) + atmel_release(link); kfree(link->priv); + kfree(link); } /*====================================================================== @@ -216,17 +236,19 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) /* Call-back function to interrogate PCMCIA-specific information about the current existance of the card */ static int card_present(void *arg) -{ - struct pcmcia_device *link = (struct pcmcia_device *)arg; - - if (pcmcia_dev_present(link)) +{ + dev_link_t *link = (dev_link_t *)arg; + if (link->state & DEV_SUSPEND) + return 0; + else if (link->state & DEV_PRESENT) return 1; - + return 0; } -static int atmel_config(struct pcmcia_device *link) +static void atmel_config(dev_link_t *link) { + client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; @@ -234,8 +256,9 @@ static int atmel_config(struct pcmcia_device *link) u_char buf[64]; struct pcmcia_device_id *did; + handle = link->handle; dev = link->priv; - did = handle_to_dev(link).driver_data; + did = handle_to_dev(handle).driver_data; DEBUG(0, "atmel_config(0x%p)\n", link); @@ -249,12 +272,15 @@ static int atmel_config(struct pcmcia_device *link) registers. */ tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - + + /* Configure card */ + link->state |= DEV_CONFIG; + /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including @@ -268,12 +294,12 @@ static int atmel_config(struct pcmcia_device *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; @@ -288,11 +314,16 @@ static int atmel_config(struct pcmcia_device *link) /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1<conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000; + else if (dflt.vcc.present & (1<conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000; + if (cfg->vpp1.present & (1<conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* Do we need to allocate an interrupt? */ @@ -318,14 +349,14 @@ static int atmel_config(struct pcmcia_device *link) } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; /* If we got this far, we're cool! */ break; next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } /* @@ -334,14 +365,14 @@ static int atmel_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); if (link->irq.AssignedIRQ == 0) { printk(KERN_ALERT @@ -353,7 +384,7 @@ static int atmel_config(struct pcmcia_device *link) init_atmel_card(link->irq.AssignedIRQ, link->io.BasePort1, did ? did->driver_info : ATMEL_FW_TYPE_NONE, - &handle_to_dev(link), + &handle_to_dev(handle), card_present, link); if (!((local_info_t*)link->priv)->eth_dev) @@ -362,18 +393,18 @@ static int atmel_config(struct pcmcia_device *link) /* At this point, the dev_node_t structure(s) need to be - initialized and arranged in a linked list at link->dev_node. + initialized and arranged in a linked list at link->dev. */ strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name ); dev->node.major = dev->node.minor = 0; - link->dev_node = &dev->node; - - return 0; - + link->dev = &dev->node; + + link->state &= ~DEV_CONFIG_PENDING; + return; + cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); atmel_release(link); - return -ENODEV; } /*====================================================================== @@ -384,34 +415,53 @@ static int atmel_config(struct pcmcia_device *link) ======================================================================*/ -static void atmel_release(struct pcmcia_device *link) +static void atmel_release(dev_link_t *link) { struct net_device *dev = ((local_info_t*)link->priv)->eth_dev; - + DEBUG(0, "atmel_release(0x%p)\n", link); - - if (dev) + + /* Unlink the device chain */ + link->dev = NULL; + + if (dev) stop_atmel_card(dev); - ((local_info_t*)link->priv)->eth_dev = NULL; - - pcmcia_disable_device(link); + ((local_info_t*)link->priv)->eth_dev = NULL; + + /* Don't bother checking to see if these succeed or not */ + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } -static int atmel_suspend(struct pcmcia_device *link) +static int atmel_suspend(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); local_info_t *local = link->priv; - netif_device_detach(local->eth_dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + netif_device_detach(local->eth_dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int atmel_resume(struct pcmcia_device *link) +static int atmel_resume(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); local_info_t *local = link->priv; - atmel_open(local->eth_dev); - netif_device_attach(local->eth_dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + atmel_open(local->eth_dev); + netif_device_attach(local->eth_dev); + } return 0; } @@ -465,7 +515,7 @@ static struct pcmcia_driver atmel_driver = { .drv = { .name = "atmel_cs", }, - .probe = atmel_probe, + .probe = atmel_attach, .remove = atmel_detach, .id_table = atmel_ids, .suspend = atmel_suspend, diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig deleted file mode 100644 index 25ea4748f..000000000 --- a/drivers/net/wireless/bcm43xx/Kconfig +++ /dev/null @@ -1,65 +0,0 @@ -config BCM43XX - tristate "Broadcom BCM43xx wireless support" - depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL - select FW_LOADER - ---help--- - This is an experimental driver for the Broadcom 43xx wireless chip, - found in the Apple Airport Extreme and various other devices. - -config BCM43XX_DEBUG - bool "Broadcom BCM43xx debugging (RECOMMENDED)" - depends on BCM43XX - default y - ---help--- - Broadcom 43xx debugging messages. - Say Y, because the driver is still very experimental and - this will help you get it running. - -config BCM43XX_DMA - bool - depends on BCM43XX - -config BCM43XX_PIO - bool - depends on BCM43XX - -choice - prompt "BCM43xx data transfer mode" - depends on BCM43XX - default BCM43XX_DMA_AND_PIO_MODE - -config BCM43XX_DMA_AND_PIO_MODE - bool "DMA + PIO" - select BCM43XX_DMA - select BCM43XX_PIO - ---help--- - Include both, Direct Memory Access (DMA) and Programmed I/O (PIO) - data transfer modes. - The actually used mode is selectable through the module - parameter "pio". If the module parameter is pio=0, DMA is used. - Otherwise PIO is used. DMA is default. - - If unsure, choose this option. - -config BCM43XX_DMA_MODE - bool "DMA (Direct Memory Access) only" - select BCM43XX_DMA - ---help--- - Only include Direct Memory Access (DMA). - This reduces the size of the driver module, by omitting the PIO code. - -config BCM43XX_PIO_MODE - bool "PIO (Programmed I/O) only" - select BCM43XX_PIO - ---help--- - Only include Programmed I/O (PIO). - This reduces the size of the driver module, by omitting the DMA code. - Please note that PIO transfers are slow (compared to DMA). - - Also note that not all devices of the 43xx series support PIO. - The 4306 (Apple Airport Extreme and others) supports PIO, while - the 4318 is known to _not_ support PIO. - - Only use PIO, if DMA does not work for you. - -endchoice diff --git a/drivers/net/wireless/bcm43xx/Makefile b/drivers/net/wireless/bcm43xx/Makefile deleted file mode 100644 index bb5220c62..000000000 --- a/drivers/net/wireless/bcm43xx/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -obj-$(CONFIG_BCM43XX) += bcm43xx.o -bcm43xx-obj-$(CONFIG_BCM43XX_DEBUG) += bcm43xx_debugfs.o - -bcm43xx-obj-$(CONFIG_BCM43XX_DMA) += bcm43xx_dma.o -bcm43xx-obj-$(CONFIG_BCM43XX_PIO) += bcm43xx_pio.o - -bcm43xx-objs := bcm43xx_main.o bcm43xx_ilt.o \ - bcm43xx_radio.o bcm43xx_phy.o \ - bcm43xx_power.o bcm43xx_wx.o \ - bcm43xx_leds.o bcm43xx_ethtool.o \ - bcm43xx_xmit.o bcm43xx_sysfs.o \ - $(bcm43xx-obj-y) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h deleted file mode 100644 index 2e8308393..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ /dev/null @@ -1,937 +0,0 @@ -#ifndef BCM43xx_H_ -#define BCM43xx_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "bcm43xx_debugfs.h" -#include "bcm43xx_leds.h" - - -#define PFX KBUILD_MODNAME ": " - -#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50 -#define BCM43xx_IRQWAIT_MAX_RETRIES 50 - -#define BCM43xx_IO_SIZE 8192 - -/* Active Core PCI Configuration Register. */ -#define BCM43xx_PCICFG_ACTIVE_CORE 0x80 -/* SPROM control register. */ -#define BCM43xx_PCICFG_SPROMCTL 0x88 -/* Interrupt Control PCI Configuration Register. (Only on PCI cores with rev >= 6) */ -#define BCM43xx_PCICFG_ICR 0x94 - -/* MMIO offsets */ -#define BCM43xx_MMIO_DMA1_REASON 0x20 -#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x24 -#define BCM43xx_MMIO_DMA2_REASON 0x28 -#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x2C -#define BCM43xx_MMIO_DMA3_REASON 0x30 -#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x34 -#define BCM43xx_MMIO_DMA4_REASON 0x38 -#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x3C -#define BCM43xx_MMIO_STATUS_BITFIELD 0x120 -#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124 -#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128 -#define BCM43xx_MMIO_GEN_IRQ_MASK 0x12C -#define BCM43xx_MMIO_RAM_CONTROL 0x130 -#define BCM43xx_MMIO_RAM_DATA 0x134 -#define BCM43xx_MMIO_PS_STATUS 0x140 -#define BCM43xx_MMIO_RADIO_HWENABLED_HI 0x158 -#define BCM43xx_MMIO_SHM_CONTROL 0x160 -#define BCM43xx_MMIO_SHM_DATA 0x164 -#define BCM43xx_MMIO_SHM_DATA_UNALIGNED 0x166 -#define BCM43xx_MMIO_XMITSTAT_0 0x170 -#define BCM43xx_MMIO_XMITSTAT_1 0x174 -#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */ -#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */ -#define BCM43xx_MMIO_DMA1_BASE 0x200 -#define BCM43xx_MMIO_DMA2_BASE 0x220 -#define BCM43xx_MMIO_DMA3_BASE 0x240 -#define BCM43xx_MMIO_DMA4_BASE 0x260 -#define BCM43xx_MMIO_PIO1_BASE 0x300 -#define BCM43xx_MMIO_PIO2_BASE 0x310 -#define BCM43xx_MMIO_PIO3_BASE 0x320 -#define BCM43xx_MMIO_PIO4_BASE 0x330 -#define BCM43xx_MMIO_PHY_VER 0x3E0 -#define BCM43xx_MMIO_PHY_RADIO 0x3E2 -#define BCM43xx_MMIO_ANTENNA 0x3E8 -#define BCM43xx_MMIO_CHANNEL 0x3F0 -#define BCM43xx_MMIO_CHANNEL_EXT 0x3F4 -#define BCM43xx_MMIO_RADIO_CONTROL 0x3F6 -#define BCM43xx_MMIO_RADIO_DATA_HIGH 0x3F8 -#define BCM43xx_MMIO_RADIO_DATA_LOW 0x3FA -#define BCM43xx_MMIO_PHY_CONTROL 0x3FC -#define BCM43xx_MMIO_PHY_DATA 0x3FE -#define BCM43xx_MMIO_MACFILTER_CONTROL 0x420 -#define BCM43xx_MMIO_MACFILTER_DATA 0x422 -#define BCM43xx_MMIO_RADIO_HWENABLED_LO 0x49A -#define BCM43xx_MMIO_GPIO_CONTROL 0x49C -#define BCM43xx_MMIO_GPIO_MASK 0x49E -#define BCM43xx_MMIO_TSF_0 0x632 /* core rev < 3 only */ -#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */ -#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */ -#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */ -#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8 - -/* SPROM offsets. */ -#define BCM43xx_SPROM_BASE 0x1000 -#define BCM43xx_SPROM_BOARDFLAGS2 0x1c -#define BCM43xx_SPROM_IL0MACADDR 0x24 -#define BCM43xx_SPROM_ET0MACADDR 0x27 -#define BCM43xx_SPROM_ET1MACADDR 0x2a -#define BCM43xx_SPROM_ETHPHY 0x2d -#define BCM43xx_SPROM_BOARDREV 0x2e -#define BCM43xx_SPROM_PA0B0 0x2f -#define BCM43xx_SPROM_PA0B1 0x30 -#define BCM43xx_SPROM_PA0B2 0x31 -#define BCM43xx_SPROM_WL0GPIO0 0x32 -#define BCM43xx_SPROM_WL0GPIO2 0x33 -#define BCM43xx_SPROM_MAXPWR 0x34 -#define BCM43xx_SPROM_PA1B0 0x35 -#define BCM43xx_SPROM_PA1B1 0x36 -#define BCM43xx_SPROM_PA1B2 0x37 -#define BCM43xx_SPROM_IDL_TSSI_TGT 0x38 -#define BCM43xx_SPROM_BOARDFLAGS 0x39 -#define BCM43xx_SPROM_ANTENNA_GAIN 0x3a -#define BCM43xx_SPROM_VERSION 0x3f - -/* BCM43xx_SPROM_BOARDFLAGS values */ -#define BCM43xx_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */ -#define BCM43xx_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */ -#define BCM43xx_BFL_AIRLINEMODE 0x0004 /* implements GPIO 13 radio disable indication */ -#define BCM43xx_BFL_RSSI 0x0008 /* software calculates nrssi slope. */ -#define BCM43xx_BFL_ENETSPI 0x0010 /* has ephy roboswitch spi */ -#define BCM43xx_BFL_XTAL_NOSLOW 0x0020 /* no slow clock available */ -#define BCM43xx_BFL_CCKHIPWR 0x0040 /* can do high power CCK transmission */ -#define BCM43xx_BFL_ENETADM 0x0080 /* has ADMtek switch */ -#define BCM43xx_BFL_ENETVLAN 0x0100 /* can do vlan */ -#define BCM43xx_BFL_AFTERBURNER 0x0200 /* supports Afterburner mode */ -#define BCM43xx_BFL_NOPCI 0x0400 /* leaves PCI floating */ -#define BCM43xx_BFL_FEM 0x0800 /* supports the Front End Module */ -#define BCM43xx_BFL_EXTLNA 0x1000 /* has an external LNA */ -#define BCM43xx_BFL_HGPA 0x2000 /* had high gain PA */ -#define BCM43xx_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */ -#define BCM43xx_BFL_ALTIQ 0x8000 /* alternate I/Q settings */ - -/* GPIO register offset, in both ChipCommon and PCI core. */ -#define BCM43xx_GPIO_CONTROL 0x6c - -/* SHM Routing */ -#define BCM43xx_SHM_SHARED 0x0001 -#define BCM43xx_SHM_WIRELESS 0x0002 -#define BCM43xx_SHM_PCM 0x0003 -#define BCM43xx_SHM_HWMAC 0x0004 -#define BCM43xx_SHM_UCODE 0x0300 - -/* MacFilter offsets. */ -#define BCM43xx_MACFILTER_SELF 0x0000 -#define BCM43xx_MACFILTER_ASSOC 0x0003 - -/* Chipcommon registers. */ -#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04 -#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0 -#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4 -#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8 -#define BCM43xx_CHIPCOMMON_SYSCLKCTL 0xC0 - -/* PCI core specific registers. */ -#define BCM43xx_PCICORE_BCAST_ADDR 0x50 -#define BCM43xx_PCICORE_BCAST_DATA 0x54 -#define BCM43xx_PCICORE_SBTOPCI2 0x108 - -/* SBTOPCI2 values. */ -#define BCM43xx_SBTOPCI2_PREFETCH 0x4 -#define BCM43xx_SBTOPCI2_BURST 0x8 - -/* Chipcommon capabilities. */ -#define BCM43xx_CAPABILITIES_PCTL 0x00040000 -#define BCM43xx_CAPABILITIES_PLLMASK 0x00030000 -#define BCM43xx_CAPABILITIES_PLLSHIFT 16 -#define BCM43xx_CAPABILITIES_FLASHMASK 0x00000700 -#define BCM43xx_CAPABILITIES_FLASHSHIFT 8 -#define BCM43xx_CAPABILITIES_EXTBUSPRESENT 0x00000040 -#define BCM43xx_CAPABILITIES_UARTGPIO 0x00000020 -#define BCM43xx_CAPABILITIES_UARTCLOCKMASK 0x00000018 -#define BCM43xx_CAPABILITIES_UARTCLOCKSHIFT 3 -#define BCM43xx_CAPABILITIES_MIPSBIGENDIAN 0x00000004 -#define BCM43xx_CAPABILITIES_NRUARTSMASK 0x00000003 - -/* PowerControl */ -#define BCM43xx_PCTL_IN 0xB0 -#define BCM43xx_PCTL_OUT 0xB4 -#define BCM43xx_PCTL_OUTENABLE 0xB8 -#define BCM43xx_PCTL_XTAL_POWERUP 0x40 -#define BCM43xx_PCTL_PLL_POWERDOWN 0x80 - -/* PowerControl Clock Modes */ -#define BCM43xx_PCTL_CLK_FAST 0x00 -#define BCM43xx_PCTL_CLK_SLOW 0x01 -#define BCM43xx_PCTL_CLK_DYNAMIC 0x02 - -#define BCM43xx_PCTL_FORCE_SLOW 0x0800 -#define BCM43xx_PCTL_FORCE_PLL 0x1000 -#define BCM43xx_PCTL_DYN_XTAL 0x2000 - -/* COREIDs */ -#define BCM43xx_COREID_CHIPCOMMON 0x800 -#define BCM43xx_COREID_ILINE20 0x801 -#define BCM43xx_COREID_SDRAM 0x803 -#define BCM43xx_COREID_PCI 0x804 -#define BCM43xx_COREID_MIPS 0x805 -#define BCM43xx_COREID_ETHERNET 0x806 -#define BCM43xx_COREID_V90 0x807 -#define BCM43xx_COREID_USB11_HOSTDEV 0x80a -#define BCM43xx_COREID_IPSEC 0x80b -#define BCM43xx_COREID_PCMCIA 0x80d -#define BCM43xx_COREID_EXT_IF 0x80f -#define BCM43xx_COREID_80211 0x812 -#define BCM43xx_COREID_MIPS_3302 0x816 -#define BCM43xx_COREID_USB11_HOST 0x817 -#define BCM43xx_COREID_USB11_DEV 0x818 -#define BCM43xx_COREID_USB20_HOST 0x819 -#define BCM43xx_COREID_USB20_DEV 0x81a -#define BCM43xx_COREID_SDIO_HOST 0x81b - -/* Core Information Registers */ -#define BCM43xx_CIR_BASE 0xf00 -#define BCM43xx_CIR_SBTPSFLAG (BCM43xx_CIR_BASE + 0x18) -#define BCM43xx_CIR_SBIMSTATE (BCM43xx_CIR_BASE + 0x90) -#define BCM43xx_CIR_SBINTVEC (BCM43xx_CIR_BASE + 0x94) -#define BCM43xx_CIR_SBTMSTATELOW (BCM43xx_CIR_BASE + 0x98) -#define BCM43xx_CIR_SBTMSTATEHIGH (BCM43xx_CIR_BASE + 0x9c) -#define BCM43xx_CIR_SBIMCONFIGLOW (BCM43xx_CIR_BASE + 0xa8) -#define BCM43xx_CIR_SB_ID_HI (BCM43xx_CIR_BASE + 0xfc) - -/* Mask to get the Backplane Flag Number from SBTPSFLAG. */ -#define BCM43xx_BACKPLANE_FLAG_NR_MASK 0x3f - -/* SBIMCONFIGLOW values/masks. */ -#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK 0x00000007 -#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT 0 -#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK 0x00000070 -#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT 4 -#define BCM43xx_SBIMCONFIGLOW_CONNID_MASK 0x00ff0000 -#define BCM43xx_SBIMCONFIGLOW_CONNID_SHIFT 16 - -/* sbtmstatelow state flags */ -#define BCM43xx_SBTMSTATELOW_RESET 0x01 -#define BCM43xx_SBTMSTATELOW_REJECT 0x02 -#define BCM43xx_SBTMSTATELOW_CLOCK 0x10000 -#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000 - -/* sbtmstatehigh state flags */ -#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1 -#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4 - -/* sbimstate flags */ -#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000 -#define BCM43xx_SBIMSTATE_TIMEOUT 0x40000 - -/* PHYVersioning */ -#define BCM43xx_PHYTYPE_A 0x00 -#define BCM43xx_PHYTYPE_B 0x01 -#define BCM43xx_PHYTYPE_G 0x02 - -/* PHYRegisters */ -#define BCM43xx_PHY_ILT_A_CTRL 0x0072 -#define BCM43xx_PHY_ILT_A_DATA1 0x0073 -#define BCM43xx_PHY_ILT_A_DATA2 0x0074 -#define BCM43xx_PHY_G_LO_CONTROL 0x0810 -#define BCM43xx_PHY_ILT_G_CTRL 0x0472 -#define BCM43xx_PHY_ILT_G_DATA1 0x0473 -#define BCM43xx_PHY_ILT_G_DATA2 0x0474 -#define BCM43xx_PHY_A_PCTL 0x007B -#define BCM43xx_PHY_G_PCTL 0x0029 -#define BCM43xx_PHY_A_CRS 0x0029 -#define BCM43xx_PHY_RADIO_BITFIELD 0x0401 -#define BCM43xx_PHY_G_CRS 0x0429 -#define BCM43xx_PHY_NRSSILT_CTRL 0x0803 -#define BCM43xx_PHY_NRSSILT_DATA 0x0804 - -/* RadioRegisters */ -#define BCM43xx_RADIOCTL_ID 0x01 - -/* StatusBitField */ -#define BCM43xx_SBF_MAC_ENABLED 0x00000001 -#define BCM43xx_SBF_2 0x00000002 /*FIXME: fix name*/ -#define BCM43xx_SBF_CORE_READY 0x00000004 -#define BCM43xx_SBF_400 0x00000400 /*FIXME: fix name*/ -#define BCM43xx_SBF_4000 0x00004000 /*FIXME: fix name*/ -#define BCM43xx_SBF_8000 0x00008000 /*FIXME: fix name*/ -#define BCM43xx_SBF_XFER_REG_BYTESWAP 0x00010000 -#define BCM43xx_SBF_MODE_NOTADHOC 0x00020000 -#define BCM43xx_SBF_MODE_AP 0x00040000 -#define BCM43xx_SBF_RADIOREG_LOCK 0x00080000 -#define BCM43xx_SBF_MODE_MONITOR 0x00400000 -#define BCM43xx_SBF_MODE_PROMISC 0x01000000 -#define BCM43xx_SBF_PS1 0x02000000 -#define BCM43xx_SBF_PS2 0x04000000 -#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000 -#define BCM43xx_SBF_TIME_UPDATE 0x10000000 -#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/ - -/* MicrocodeFlagsBitfield (addr + lo-word values?)*/ -#define BCM43xx_UCODEFLAGS_OFFSET 0x005E - -#define BCM43xx_UCODEFLAG_AUTODIV 0x0001 -#define BCM43xx_UCODEFLAG_UNKBGPHY 0x0002 -#define BCM43xx_UCODEFLAG_UNKBPHY 0x0004 -#define BCM43xx_UCODEFLAG_UNKGPHY 0x0020 -#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040 -#define BCM43xx_UCODEFLAG_JAPAN 0x0080 - -/* Generic-Interrupt reasons. */ -#define BCM43xx_IRQ_READY (1 << 0) -#define BCM43xx_IRQ_BEACON (1 << 1) -#define BCM43xx_IRQ_PS (1 << 2) -#define BCM43xx_IRQ_REG124 (1 << 5) -#define BCM43xx_IRQ_PMQ (1 << 6) -#define BCM43xx_IRQ_PIO_WORKAROUND (1 << 8) -#define BCM43xx_IRQ_XMIT_ERROR (1 << 11) -#define BCM43xx_IRQ_RX (1 << 15) -#define BCM43xx_IRQ_SCAN (1 << 16) -#define BCM43xx_IRQ_NOISE (1 << 18) -#define BCM43xx_IRQ_XMIT_STATUS (1 << 29) - -#define BCM43xx_IRQ_ALL 0xffffffff -#define BCM43xx_IRQ_INITIAL (BCM43xx_IRQ_PS | \ - BCM43xx_IRQ_REG124 | \ - BCM43xx_IRQ_PMQ | \ - BCM43xx_IRQ_XMIT_ERROR | \ - BCM43xx_IRQ_RX | \ - BCM43xx_IRQ_SCAN | \ - BCM43xx_IRQ_NOISE | \ - BCM43xx_IRQ_XMIT_STATUS) - - -/* Initial default iw_mode */ -#define BCM43xx_INITIAL_IWMODE IW_MODE_INFRA - -/* Bus type PCI. */ -#define BCM43xx_BUSTYPE_PCI 0 -/* Bus type Silicone Backplane Bus. */ -#define BCM43xx_BUSTYPE_SB 1 -/* Bus type PCMCIA. */ -#define BCM43xx_BUSTYPE_PCMCIA 2 - -/* Threshold values. */ -#define BCM43xx_MIN_RTS_THRESHOLD 1U -#define BCM43xx_MAX_RTS_THRESHOLD 2304U -#define BCM43xx_DEFAULT_RTS_THRESHOLD BCM43xx_MAX_RTS_THRESHOLD - -#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7 -#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4 - -/* Max size of a security key */ -#define BCM43xx_SEC_KEYSIZE 16 -/* Security algorithms. */ -enum { - BCM43xx_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */ - BCM43xx_SEC_ALGO_WEP, - BCM43xx_SEC_ALGO_UNKNOWN, - BCM43xx_SEC_ALGO_AES, - BCM43xx_SEC_ALGO_WEP104, - BCM43xx_SEC_ALGO_TKIP, -}; - -#ifdef assert -# undef assert -#endif -#ifdef CONFIG_BCM43XX_DEBUG -#define assert(expr) \ - do { \ - if (unlikely(!(expr))) { \ - printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \ - #expr, __FILE__, __LINE__, __FUNCTION__); \ - } \ - } while (0) -#else -#define assert(expr) do { /* nothing */ } while (0) -#endif - -/* rate limited printk(). */ -#ifdef printkl -# undef printkl -#endif -#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0) -/* rate limited printk() for debugging */ -#ifdef dprintkl -# undef dprintkl -#endif -#ifdef CONFIG_BCM43XX_DEBUG -# define dprintkl printkl -#else -# define dprintkl(f, x...) do { /* nothing */ } while (0) -#endif - -/* Helper macro for if branches. - * An if branch marked with this macro is only taken in DEBUG mode. - * Example: - * if (DEBUG_ONLY(foo == bar)) { - * do something - * } - * In DEBUG mode, the branch will be taken if (foo == bar). - * In non-DEBUG mode, the branch will never be taken. - */ -#ifdef DEBUG_ONLY -# undef DEBUG_ONLY -#endif -#ifdef CONFIG_BCM43XX_DEBUG -# define DEBUG_ONLY(x) (x) -#else -# define DEBUG_ONLY(x) 0 -#endif - -/* debugging printk() */ -#ifdef dprintk -# undef dprintk -#endif -#ifdef CONFIG_BCM43XX_DEBUG -# define dprintk(f, x...) do { printk(f ,##x); } while (0) -#else -# define dprintk(f, x...) do { /* nothing */ } while (0) -#endif - - -struct net_device; -struct pci_dev; -struct bcm43xx_dmaring; -struct bcm43xx_pioqueue; - -struct bcm43xx_initval { - u16 offset; - u16 size; - u32 value; -} __attribute__((__packed__)); - -/* Values for bcm430x_sprominfo.locale */ -enum { - BCM43xx_LOCALE_WORLD = 0, - BCM43xx_LOCALE_THAILAND, - BCM43xx_LOCALE_ISRAEL, - BCM43xx_LOCALE_JORDAN, - BCM43xx_LOCALE_CHINA, - BCM43xx_LOCALE_JAPAN, - BCM43xx_LOCALE_USA_CANADA_ANZ, - BCM43xx_LOCALE_EUROPE, - BCM43xx_LOCALE_USA_LOW, - BCM43xx_LOCALE_JAPAN_HIGH, - BCM43xx_LOCALE_ALL, - BCM43xx_LOCALE_NONE, -}; - -#define BCM43xx_SPROM_SIZE 64 /* in 16-bit words. */ -struct bcm43xx_sprominfo { - u16 boardflags2; - u8 il0macaddr[6]; - u8 et0macaddr[6]; - u8 et1macaddr[6]; - u8 et0phyaddr:5; - u8 et1phyaddr:5; - u8 et0mdcport:1; - u8 et1mdcport:1; - u8 boardrev; - u8 locale:4; - u8 antennas_aphy:2; - u8 antennas_bgphy:2; - u16 pa0b0; - u16 pa0b1; - u16 pa0b2; - u8 wl0gpio0; - u8 wl0gpio1; - u8 wl0gpio2; - u8 wl0gpio3; - u8 maxpower_aphy; - u8 maxpower_bgphy; - u16 pa1b0; - u16 pa1b1; - u16 pa1b2; - u8 idle_tssi_tgt_aphy; - u8 idle_tssi_tgt_bgphy; - u16 boardflags; - u16 antennagain_aphy; - u16 antennagain_bgphy; -}; - -/* Value pair to measure the LocalOscillator. */ -struct bcm43xx_lopair { - s8 low; - s8 high; - u8 used:1; -}; -#define BCM43xx_LO_COUNT (14*4) - -struct bcm43xx_phyinfo { - /* Hardware Data */ - u8 version; - u8 type; - u8 rev; - u16 antenna_diversity; - u16 savedpctlreg; - u16 minlowsig[2]; - u16 minlowsigpos[2]; - u8 connected:1, - calibrated:1, - is_locked:1, /* used in bcm43xx_phy_{un}lock() */ - dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */ - /* LO Measurement Data. - * Use bcm43xx_get_lopair() to get a value. - */ - struct bcm43xx_lopair *_lo_pairs; - - /* TSSI to dBm table in use */ - const s8 *tssi2dbm; - /* idle TSSI value */ - s8 idle_tssi; - - /* Values from bcm43xx_calc_loopback_gain() */ - u16 loopback_gain[2]; - - /* PHY lock for core.rev < 3 - * This lock is only used by bcm43xx_phy_{un}lock() - */ - spinlock_t lock; -}; - - -struct bcm43xx_radioinfo { - u16 manufact; - u16 version; - u8 revision; - - /* Desired TX power in dBm Q5.2 */ - u16 txpower_desired; - /* TX Power control values. */ - union { - /* B/G PHY */ - struct { - u16 baseband_atten; - u16 radio_atten; - u16 txctl1; - u16 txctl2; - }; - /* A PHY */ - struct { - u16 txpwr_offset; - }; - }; - - /* Current Interference Mitigation mode */ - int interfmode; - /* Stack of saved values from the Interference Mitigation code. - * Each value in the stack is layed out as follows: - * bit 0-11: offset - * bit 12-15: register ID - * bit 16-32: value - * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT - */ -#define BCM43xx_INTERFSTACK_SIZE 26 - u32 interfstack[BCM43xx_INTERFSTACK_SIZE]; - - /* Saved values from the NRSSI Slope calculation */ - s16 nrssi[2]; - s32 nrssislope; - /* In memory nrssi lookup table. */ - s8 nrssi_lt[64]; - - /* current channel */ - u8 channel; - u8 initial_channel; - - u16 lofcal; - - u16 initval; - - u8 enabled:1; - /* ACI (adjacent channel interference) flags. */ - u8 aci_enable:1, - aci_wlan_automatic:1, - aci_hw_rssi:1; -}; - -/* Data structures for DMA transmission, per 80211 core. */ -struct bcm43xx_dma { - struct bcm43xx_dmaring *tx_ring0; - struct bcm43xx_dmaring *tx_ring1; - struct bcm43xx_dmaring *tx_ring2; - struct bcm43xx_dmaring *tx_ring3; - struct bcm43xx_dmaring *rx_ring0; - struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */ -}; - -/* Data structures for PIO transmission, per 80211 core. */ -struct bcm43xx_pio { - struct bcm43xx_pioqueue *queue0; - struct bcm43xx_pioqueue *queue1; - struct bcm43xx_pioqueue *queue2; - struct bcm43xx_pioqueue *queue3; -}; - -#define BCM43xx_MAX_80211_CORES 2 - -#ifdef CONFIG_BCM947XX -#define core_offset(bcm) (bcm)->current_core_offset -#else -#define core_offset(bcm) 0 -#endif - -/* Generic information about a core. */ -struct bcm43xx_coreinfo { - u8 available:1, - enabled:1, - initialized:1; - /** core_id ID number */ - u16 id; - /** core_rev revision number */ - u8 rev; - /** Index number for _switch_core() */ - u8 index; -}; - -/* Additional information for each 80211 core. */ -struct bcm43xx_coreinfo_80211 { - /* PHY device. */ - struct bcm43xx_phyinfo phy; - /* Radio device. */ - struct bcm43xx_radioinfo radio; - union { - /* DMA context. */ - struct bcm43xx_dma dma; - /* PIO context. */ - struct bcm43xx_pio pio; - }; -}; - -/* Context information for a noise calculation (Link Quality). */ -struct bcm43xx_noise_calculation { - struct bcm43xx_coreinfo *core_at_start; - u8 channel_at_start; - u8 calculation_running:1; - u8 nr_samples; - s8 samples[8][4]; -}; - -struct bcm43xx_stats { - u8 link_quality; - u8 noise; - struct iw_statistics wstats; - /* Store the last TX/RX times here for updating the leds. */ - unsigned long last_tx; - unsigned long last_rx; -}; - -struct bcm43xx_key { - u8 enabled:1; - u8 algorithm; -}; - -struct bcm43xx_private { - struct ieee80211_device *ieee; - struct ieee80211softmac_device *softmac; - - struct net_device *net_dev; - struct pci_dev *pci_dev; - unsigned int irq; - - void __iomem *mmio_addr; - unsigned int mmio_len; - - /* Do not use the lock directly. Use the bcm43xx_lock* helper - * functions, to be MMIO-safe. */ - spinlock_t _lock; - - /* Driver status flags. */ - u32 initialized:1, /* init_board() succeed */ - was_initialized:1, /* for PCI suspend/resume. */ - shutting_down:1, /* free_board() in progress */ - __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ - bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ - reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ - powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */ - short_preamble:1, /* TRUE, if short preamble is enabled. */ - firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ - - struct bcm43xx_stats stats; - - /* Bus type we are connected to. - * This is currently always BCM43xx_BUSTYPE_PCI - */ - u8 bustype; - - u16 board_vendor; - u16 board_type; - u16 board_revision; - - u16 chip_id; - u8 chip_rev; - u8 chip_package; - - struct bcm43xx_sprominfo sprom; -#define BCM43xx_NR_LEDS 4 - struct bcm43xx_led leds[BCM43xx_NR_LEDS]; - - /* The currently active core. */ - struct bcm43xx_coreinfo *current_core; -#ifdef CONFIG_BCM947XX - /** current core memory offset */ - u32 current_core_offset; -#endif - struct bcm43xx_coreinfo *active_80211_core; - /* coreinfo structs for all possible cores follow. - * Note that a core might not exist. - * So check the coreinfo flags before using it. - */ - struct bcm43xx_coreinfo core_chipcommon; - struct bcm43xx_coreinfo core_pci; - struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ]; - /* Additional information, specific to the 80211 cores. */ - struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ]; - /* Index of the current 80211 core. If current_core is not - * an 80211 core, this is -1. - */ - int current_80211_core_idx; - /* Number of available 80211 cores. */ - int nr_80211_available; - - u32 chipcommon_capabilities; - - /* Reason code of the last interrupt. */ - u32 irq_reason; - u32 dma_reason[4]; - /* saved irq enable/disable state bitfield. */ - u32 irq_savedstate; - /* Link Quality calculation context. */ - struct bcm43xx_noise_calculation noisecalc; - - /* Threshold values. */ - //TODO: The RTS thr has to be _used_. Currently, it is only set via WX. - u32 rts_threshold; - - /* Interrupt Service Routine tasklet (bottom-half) */ - struct tasklet_struct isr_tasklet; - - /* Periodic tasks */ - struct timer_list periodic_tasks; - unsigned int periodic_state; - - struct work_struct restart_work; - - /* Informational stuff. */ - char nick[IW_ESSID_MAX_SIZE + 1]; - - /* encryption/decryption */ - u16 security_offset; - struct bcm43xx_key key[54]; - u8 default_key_idx; - - /* Firmware. */ - const struct firmware *ucode; - const struct firmware *pcm; - const struct firmware *initvals0; - const struct firmware *initvals1; - - /* Debugging stuff follows. */ -#ifdef CONFIG_BCM43XX_DEBUG - struct bcm43xx_dfsentry *dfsentry; -#endif -}; - -/* bcm43xx_(un)lock() protect struct bcm43xx_private. - * Note that _NO_ MMIO writes are allowed. If you want to - * write to the device through MMIO in the critical section, use - * the *_mmio lock functions. - * MMIO read-access is allowed, though. - */ -#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags) -#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags) -/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO. - * MMIO write-access to the device is allowed. - * All MMIO writes are flushed on unlock, so it is guaranteed to not - * interfere with other threads writing MMIO registers. - */ -#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags) -#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0) - -static inline -struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) -{ - return ieee80211softmac_priv(dev); -} - -struct device; - -static inline -struct bcm43xx_private * dev_to_bcm(struct device *dev) -{ - struct net_device *net_dev; - struct bcm43xx_private *bcm; - - net_dev = dev_get_drvdata(dev); - bcm = bcm43xx_priv(net_dev); - - return bcm; -} - - -/* Helper function, which returns a boolean. - * TRUE, if PIO is used; FALSE, if DMA is used. - */ -#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO) -static inline -int bcm43xx_using_pio(struct bcm43xx_private *bcm) -{ - return bcm->__using_pio; -} -#elif defined(CONFIG_BCM43XX_DMA) -static inline -int bcm43xx_using_pio(struct bcm43xx_private *bcm) -{ - return 0; -} -#elif defined(CONFIG_BCM43XX_PIO) -static inline -int bcm43xx_using_pio(struct bcm43xx_private *bcm) -{ - return 1; -} -#else -# error "Using neither DMA nor PIO? Confused..." -#endif - -/* Helper functions to access data structures private to the 80211 cores. - * Note that we _must_ have an 80211 core mapped when calling - * any of these functions. - */ -static inline -struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm) -{ - assert(bcm43xx_using_pio(bcm)); - assert(bcm->current_80211_core_idx >= 0); - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES); - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio); -} -static inline -struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm) -{ - assert(!bcm43xx_using_pio(bcm)); - assert(bcm->current_80211_core_idx >= 0); - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES); - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma); -} -static inline -struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm) -{ - assert(bcm->current_80211_core_idx >= 0); - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES); - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy); -} -static inline -struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) -{ - assert(bcm->current_80211_core_idx >= 0); - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES); - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio); -} - -/* Are we running in init_board() context? */ -static inline -int bcm43xx_is_initializing(struct bcm43xx_private *bcm) -{ - if (bcm->initialized) - return 0; - if (bcm->shutting_down) - return 0; - return 1; -} - -static inline -struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, - u16 radio_attenuation, - u16 baseband_attenuation) -{ - return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2)); -} - - -static inline -u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset) -{ - return ioread16(bcm->mmio_addr + core_offset(bcm) + offset); -} - -static inline -void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value) -{ - iowrite16(value, bcm->mmio_addr + core_offset(bcm) + offset); -} - -static inline -u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset) -{ - return ioread32(bcm->mmio_addr + core_offset(bcm) + offset); -} - -static inline -void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value) -{ - iowrite32(value, bcm->mmio_addr + core_offset(bcm) + offset); -} - -static inline -int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value) -{ - return pci_read_config_word(bcm->pci_dev, offset, value); -} - -static inline -int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value) -{ - return pci_read_config_dword(bcm->pci_dev, offset, value); -} - -static inline -int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value) -{ - return pci_write_config_word(bcm->pci_dev, offset, value); -} - -static inline -int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value) -{ - return pci_write_config_dword(bcm->pci_dev, offset, value); -} - -/** Limit a value between two limits */ -#ifdef limit_value -# undef limit_value -#endif -#define limit_value(value, min, max) \ - ({ \ - typeof(value) __value = (value); \ - typeof(value) __min = (min); \ - typeof(value) __max = (max); \ - if (__value < __min) \ - __value = __min; \ - else if (__value > __max) \ - __value = __max; \ - __value; \ - }) - -/** Helpers to print MAC addresses. */ -#define BCM43xx_MACFMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define BCM43xx_MACARG(x) ((u8*)(x))[0], ((u8*)(x))[1], \ - ((u8*)(x))[2], ((u8*)(x))[3], \ - ((u8*)(x))[4], ((u8*)(x))[5] - -#endif /* BCM43xx_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c deleted file mode 100644 index 35a4fcb6d..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - debugfs driver debugging code - - Copyright (c) 2005 Michael Buesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - - - -#include -#include -#include -#include -#include -#include - -#include "bcm43xx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_debugfs.h" -#include "bcm43xx_dma.h" -#include "bcm43xx_pio.h" -#include "bcm43xx_xmit.h" - -#define REALLY_BIG_BUFFER_SIZE (1024*256) - -static struct bcm43xx_debugfs fs; -static char really_big_buffer[REALLY_BIG_BUFFER_SIZE]; -static DECLARE_MUTEX(big_buffer_sem); - - -static ssize_t write_file_dummy(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - return count; -} - -static int open_file_generic(struct inode *inode, struct file *file) -{ - file->private_data = inode->u.generic_ip; - return 0; -} - -#define fappend(fmt, x...) pos += snprintf(buf + pos, len - pos, fmt , ##x) - -static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - struct net_device *net_dev; - struct pci_dev *pci_dev; - unsigned long flags; - u16 tmp16; - int i; - - down(&big_buffer_sem); - - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { - fappend("Board not initialized.\n"); - goto out; - } - net_dev = bcm->net_dev; - pci_dev = bcm->pci_dev; - - /* This is where the information is written to the "devinfo" file */ - fappend("*** %s devinfo ***\n", net_dev->name); - fappend("vendor: 0x%04x device: 0x%04x\n", - pci_dev->vendor, pci_dev->device); - fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n", - pci_dev->subsystem_vendor, pci_dev->subsystem_device); - fappend("IRQ: %d\n", bcm->irq); - fappend("mmio_addr: 0x%p mmio_len: %u\n", bcm->mmio_addr, bcm->mmio_len); - fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev); - if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16))) - fappend("Radio disabled by hardware!\n"); - if ((bcm->core_80211[0].rev < 3) && !(bcm43xx_read16(bcm, 0x049A) & (1 << 4))) - fappend("Radio disabled by hardware!\n"); - fappend("board_vendor: 0x%04x board_type: 0x%04x\n", bcm->board_vendor, - bcm->board_type); - - fappend("\nCores:\n"); -#define fappend_core(name, info) fappend("core \"" name "\" %s, %s, id: 0x%04x, " \ - "rev: 0x%02x, index: 0x%02x\n", \ - (info).available \ - ? "available" : "nonavailable", \ - (info).enabled \ - ? "enabled" : "disabled", \ - (info).id, (info).rev, (info).index) - fappend_core("CHIPCOMMON", bcm->core_chipcommon); - fappend_core("PCI", bcm->core_pci); - fappend_core("first 80211", bcm->core_80211[0]); - fappend_core("second 80211", bcm->core_80211[1]); -#undef fappend_core - tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - fappend("LEDs: "); - for (i = 0; i < BCM43xx_NR_LEDS; i++) - fappend("%d ", !!(tmp16 & (1 << i))); - fappend("\n"); - -out: - bcm43xx_unlock_mmio(bcm, flags); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - up(&big_buffer_sem); - return res; -} - -static ssize_t drvinfo_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - - down(&big_buffer_sem); - - /* This is where the information is written to the "driver" file */ - fappend(KBUILD_MODNAME " driver\n"); - fappend("Compiled at: %s %s\n", __DATE__, __TIME__); - - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - up(&big_buffer_sem); - return res; -} - -static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - unsigned long flags; - - down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { - fappend("Board not initialized.\n"); - goto out; - } - - /* This is where the information is written to the "sprom_dump" file */ - fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); - -out: - bcm43xx_unlock_mmio(bcm, flags); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - up(&big_buffer_sem); - return res; -} - -static ssize_t tsf_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - unsigned long flags; - u64 tsf; - - down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { - fappend("Board not initialized.\n"); - goto out; - } - bcm43xx_tsf_read(bcm, &tsf); - fappend("0x%08x%08x\n", - (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32), - (unsigned int)(tsf & 0xFFFFFFFFULL)); - -out: - bcm43xx_unlock_mmio(bcm, flags); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - up(&big_buffer_sem); - return res; -} - -static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - ssize_t buf_size; - ssize_t res; - unsigned long flags; - u64 tsf; - - buf_size = min(count, sizeof (really_big_buffer) - 1); - down(&big_buffer_sem); - if (copy_from_user(buf, user_buf, buf_size)) { - res = -EFAULT; - goto out_up; - } - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { - printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); - res = -EFAULT; - goto out_unlock; - } - if (sscanf(buf, "%lli", &tsf) != 1) { - printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n"); - res = -EINVAL; - goto out_unlock; - } - bcm43xx_tsf_write(bcm, tsf); - res = buf_size; - -out_unlock: - bcm43xx_unlock_mmio(bcm, flags); -out_up: - up(&big_buffer_sem); - return res; -} - -static ssize_t txstat_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - unsigned long flags; - struct bcm43xx_dfsentry *e; - struct bcm43xx_xmitstatus *status; - int i, cnt, j = 0; - - down(&big_buffer_sem); - bcm43xx_lock(bcm, flags); - - fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", - BCM43xx_NR_LOGGED_XMITSTATUS); - e = bcm->dfsentry; - if (e->xmitstatus_printing == 0) { - /* At the beginning, make a copy of all data to avoid - * concurrency, as this function is called multiple - * times for big logs. Without copying, the data might - * change between reads. This would result in total trash. - */ - e->xmitstatus_printing = 1; - e->saved_xmitstatus_ptr = e->xmitstatus_ptr; - e->saved_xmitstatus_cnt = e->xmitstatus_cnt; - memcpy(e->xmitstatus_print_buffer, e->xmitstatus_buffer, - BCM43xx_NR_LOGGED_XMITSTATUS * sizeof(*(e->xmitstatus_buffer))); - } - i = e->saved_xmitstatus_ptr - 1; - if (i < 0) - i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; - cnt = e->saved_xmitstatus_cnt; - while (cnt) { - status = e->xmitstatus_print_buffer + i; - fappend("0x%02x: cookie: 0x%04x, flags: 0x%02x, " - "cnt1: 0x%02x, cnt2: 0x%02x, seq: 0x%04x, " - "unk: 0x%04x\n", j, - status->cookie, status->flags, - status->cnt1, status->cnt2, status->seq, - status->unknown); - j++; - cnt--; - i--; - if (i < 0) - i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; - } - - bcm43xx_unlock(bcm, flags); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - bcm43xx_lock(bcm, flags); - if (*ppos == pos) { - /* Done. Drop the copied data. */ - e->xmitstatus_printing = 0; - } - bcm43xx_unlock(bcm, flags); - up(&big_buffer_sem); - return res; -} - -#undef fappend - - -static struct file_operations devinfo_fops = { - .read = devinfo_read_file, - .write = write_file_dummy, - .open = open_file_generic, -}; - -static struct file_operations spromdump_fops = { - .read = spromdump_read_file, - .write = write_file_dummy, - .open = open_file_generic, -}; - -static struct file_operations drvinfo_fops = { - .read = drvinfo_read_file, - .write = write_file_dummy, - .open = open_file_generic, -}; - -static struct file_operations tsf_fops = { - .read = tsf_read_file, - .write = tsf_write_file, - .open = open_file_generic, -}; - -static struct file_operations txstat_fops = { - .read = txstat_read_file, - .write = write_file_dummy, - .open = open_file_generic, -}; - - -void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) -{ - struct bcm43xx_dfsentry *e; - char devdir[IFNAMSIZ]; - - assert(bcm); - e = kzalloc(sizeof(*e), GFP_KERNEL); - if (!e) { - printk(KERN_ERR PFX "out of memory\n"); - return; - } - e->bcm = bcm; - e->xmitstatus_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS - * sizeof(*(e->xmitstatus_buffer)), - GFP_KERNEL); - if (!e->xmitstatus_buffer) { - printk(KERN_ERR PFX "out of memory\n"); - kfree(e); - return; - } - e->xmitstatus_print_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS - * sizeof(*(e->xmitstatus_buffer)), - GFP_KERNEL); - if (!e->xmitstatus_print_buffer) { - printk(KERN_ERR PFX "out of memory\n"); - kfree(e); - return; - } - - - bcm->dfsentry = e; - - strncpy(devdir, bcm->net_dev->name, ARRAY_SIZE(devdir)); - e->subdir = debugfs_create_dir(devdir, fs.root); - e->dentry_devinfo = debugfs_create_file("devinfo", 0444, e->subdir, - bcm, &devinfo_fops); - if (!e->dentry_devinfo) - printk(KERN_ERR PFX "debugfs: creating \"devinfo\" for \"%s\" failed!\n", devdir); - e->dentry_spromdump = debugfs_create_file("sprom_dump", 0444, e->subdir, - bcm, &spromdump_fops); - if (!e->dentry_spromdump) - printk(KERN_ERR PFX "debugfs: creating \"sprom_dump\" for \"%s\" failed!\n", devdir); - e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir, - bcm, &tsf_fops); - if (!e->dentry_tsf) - printk(KERN_ERR PFX "debugfs: creating \"tsf\" for \"%s\" failed!\n", devdir); - e->dentry_txstat = debugfs_create_file("tx_status", 0444, e->subdir, - bcm, &txstat_fops); - if (!e->dentry_txstat) - printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir); -} - -void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) -{ - struct bcm43xx_dfsentry *e; - - if (!bcm) - return; - - e = bcm->dfsentry; - assert(e); - debugfs_remove(e->dentry_spromdump); - debugfs_remove(e->dentry_devinfo); - debugfs_remove(e->dentry_tsf); - debugfs_remove(e->dentry_txstat); - debugfs_remove(e->subdir); - kfree(e->xmitstatus_buffer); - kfree(e->xmitstatus_print_buffer); - kfree(e); -} - -void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ - struct bcm43xx_dfsentry *e; - struct bcm43xx_xmitstatus *savedstatus; - - /* This is protected by bcm->_lock */ - e = bcm->dfsentry; - assert(e); - savedstatus = e->xmitstatus_buffer + e->xmitstatus_ptr; - memcpy(savedstatus, status, sizeof(*status)); - e->xmitstatus_ptr++; - if (e->xmitstatus_ptr >= BCM43xx_NR_LOGGED_XMITSTATUS) - e->xmitstatus_ptr = 0; - if (e->xmitstatus_cnt < BCM43xx_NR_LOGGED_XMITSTATUS) - e->xmitstatus_cnt++; -} - -void bcm43xx_debugfs_init(void) -{ - memset(&fs, 0, sizeof(fs)); - fs.root = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!fs.root) - printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "\" subdir failed!\n"); - fs.dentry_driverinfo = debugfs_create_file("driver", 0444, fs.root, NULL, &drvinfo_fops); - if (!fs.dentry_driverinfo) - printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "/driver\" failed!\n"); -} - -void bcm43xx_debugfs_exit(void) -{ - debugfs_remove(fs.dentry_driverinfo); - debugfs_remove(fs.root); -} - -void bcm43xx_printk_dump(const char *data, - size_t size, - const char *description) -{ - size_t i; - char c; - - printk(KERN_INFO PFX "Data dump (%s, %zd bytes):", - description, size); - for (i = 0; i < size; i++) { - c = data[i]; - if (i % 8 == 0) - printk("\n" KERN_INFO PFX "0x%08zx: 0x%02x, ", i, c & 0xff); - else - printk("0x%02x, ", c & 0xff); - } - printk("\n"); -} - -void bcm43xx_printk_bitdump(const unsigned char *data, - size_t bytes, int msb_to_lsb, - const char *description) -{ - size_t i; - int j; - const unsigned char *d; - - printk(KERN_INFO PFX "*** Bitdump (%s, %zd bytes, %s) ***", - description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB"); - for (i = 0; i < bytes; i++) { - d = data + i; - if (i % 8 == 0) - printk("\n" KERN_INFO PFX "0x%08zx: ", i); - if (msb_to_lsb) { - for (j = 7; j >= 0; j--) { - if (*d & (1 << j)) - printk("1"); - else - printk("0"); - } - } else { - for (j = 0; j < 8; j++) { - if (*d & (1 << j)) - printk("1"); - else - printk("0"); - } - } - printk(" "); - } - printk("\n"); -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h deleted file mode 100644 index 50ce267f7..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef BCM43xx_DEBUGFS_H_ -#define BCM43xx_DEBUGFS_H_ - -struct bcm43xx_private; -struct bcm43xx_xmitstatus; - -#ifdef CONFIG_BCM43XX_DEBUG - -#include -#include - -struct dentry; - -/* limited by the size of the "really_big_buffer" */ -#define BCM43xx_NR_LOGGED_XMITSTATUS 100 - -struct bcm43xx_dfsentry { - struct dentry *subdir; - struct dentry *dentry_devinfo; - struct dentry *dentry_spromdump; - struct dentry *dentry_tsf; - struct dentry *dentry_txstat; - - struct bcm43xx_private *bcm; - - /* saved xmitstatus. */ - struct bcm43xx_xmitstatus *xmitstatus_buffer; - int xmitstatus_ptr; - int xmitstatus_cnt; - /* We need a seperate buffer while printing to avoid - * concurrency issues. (New xmitstatus can arrive - * while we are printing). - */ - struct bcm43xx_xmitstatus *xmitstatus_print_buffer; - int saved_xmitstatus_ptr; - int saved_xmitstatus_cnt; - int xmitstatus_printing; -}; - -struct bcm43xx_debugfs { - struct dentry *root; - struct dentry *dentry_driverinfo; -}; - -void bcm43xx_debugfs_init(void); -void bcm43xx_debugfs_exit(void); -void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm); -void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm); -void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status); - -/* Debug helper: Dump binary data through printk. */ -void bcm43xx_printk_dump(const char *data, - size_t size, - const char *description); -/* Debug helper: Dump bitwise binary data through printk. */ -void bcm43xx_printk_bitdump(const unsigned char *data, - size_t bytes, int msb_to_lsb, - const char *description); -#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \ - do { \ - bcm43xx_printk_bitdump((const unsigned char *)(pointer), \ - sizeof(*(pointer)), \ - (msb_to_lsb), \ - (description)); \ - } while (0) - -#else /* CONFIG_BCM43XX_DEBUG*/ - -static inline -void bcm43xx_debugfs_init(void) { } -static inline -void bcm43xx_debugfs_exit(void) { } -static inline -void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { } -static inline -void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { } -static inline -void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) { } - -static inline -void bcm43xx_printk_dump(const char *data, - size_t size, - const char *description) -{ -} -static inline -void bcm43xx_printk_bitdump(const unsigned char *data, - size_t bytes, int msb_to_lsb, - const char *description) -{ -} -#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0) - -#endif /* CONFIG_BCM43XX_DEBUG*/ - -/* Ugly helper macros to make incomplete code more verbose on runtime */ -#ifdef TODO -# undef TODO -#endif -#define TODO() \ - do { \ - printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \ - __FUNCTION__, __FILE__, __LINE__); \ - } while (0) - -#ifdef FIXME -# undef FIXME -#endif -#define FIXME() \ - do { \ - printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \ - __FUNCTION__, __FILE__, __LINE__); \ - } while (0) - -#endif /* BCM43xx_DEBUGFS_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c deleted file mode 100644 index d0318e525..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ /dev/null @@ -1,982 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - DMA ringbuffer and descriptor allocation/management - - Copyright (c) 2005 Michael Buesch - - Some code in this file is derived from the b44.c driver - Copyright (C) 2002 David S. Miller - Copyright (C) Pekka Pietikainen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx.h" -#include "bcm43xx_dma.h" -#include "bcm43xx_main.h" -#include "bcm43xx_debugfs.h" -#include "bcm43xx_power.h" -#include "bcm43xx_xmit.h" - -#include -#include -#include -#include - - -static inline int free_slots(struct bcm43xx_dmaring *ring) -{ - return (ring->nr_slots - ring->used_slots); -} - -static inline int next_slot(struct bcm43xx_dmaring *ring, int slot) -{ - assert(slot >= -1 && slot <= ring->nr_slots - 1); - if (slot == ring->nr_slots - 1) - return 0; - return slot + 1; -} - -static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot) -{ - assert(slot >= 0 && slot <= ring->nr_slots - 1); - if (slot == 0) - return ring->nr_slots - 1; - return slot - 1; -} - -/* Request a slot for usage. */ -static inline -int request_slot(struct bcm43xx_dmaring *ring) -{ - int slot; - - assert(ring->tx); - assert(!ring->suspended); - assert(free_slots(ring) != 0); - - slot = next_slot(ring, ring->current_slot); - ring->current_slot = slot; - ring->used_slots++; - - /* Check the number of available slots and suspend TX, - * if we are running low on free slots. - */ - if (unlikely(free_slots(ring) < ring->suspend_mark)) { - netif_stop_queue(ring->bcm->net_dev); - ring->suspended = 1; - } -#ifdef CONFIG_BCM43XX_DEBUG - if (ring->used_slots > ring->max_used_slots) - ring->max_used_slots = ring->used_slots; -#endif /* CONFIG_BCM43XX_DEBUG*/ - - return slot; -} - -/* Return a slot to the free slots. */ -static inline -void return_slot(struct bcm43xx_dmaring *ring, int slot) -{ - assert(ring->tx); - - ring->used_slots--; - - /* Check if TX is suspended and check if we have - * enough free slots to resume it again. - */ - if (unlikely(ring->suspended)) { - if (free_slots(ring) >= ring->resume_mark) { - ring->suspended = 0; - netif_wake_queue(ring->bcm->net_dev); - } - } -} - -static inline -dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring, - unsigned char *buf, - size_t len, - int tx) -{ - dma_addr_t dmaaddr; - - if (tx) { - dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev, - buf, len, - DMA_TO_DEVICE); - } else { - dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev, - buf, len, - DMA_FROM_DEVICE); - } - - return dmaaddr; -} - -static inline -void unmap_descbuffer(struct bcm43xx_dmaring *ring, - dma_addr_t addr, - size_t len, - int tx) -{ - if (tx) { - dma_unmap_single(&ring->bcm->pci_dev->dev, - addr, len, - DMA_TO_DEVICE); - } else { - dma_unmap_single(&ring->bcm->pci_dev->dev, - addr, len, - DMA_FROM_DEVICE); - } -} - -static inline -void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring, - dma_addr_t addr, - size_t len) -{ - assert(!ring->tx); - - dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev, - addr, len, DMA_FROM_DEVICE); -} - -static inline -void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring, - dma_addr_t addr, - size_t len) -{ - assert(!ring->tx); - - dma_sync_single_for_device(&ring->bcm->pci_dev->dev, - addr, len, DMA_FROM_DEVICE); -} - -/* Unmap and free a descriptor buffer. */ -static inline -void free_descriptor_buffer(struct bcm43xx_dmaring *ring, - struct bcm43xx_dmadesc *desc, - struct bcm43xx_dmadesc_meta *meta, - int irq_context) -{ - assert(meta->skb); - if (irq_context) - dev_kfree_skb_irq(meta->skb); - else - dev_kfree_skb(meta->skb); - meta->skb = NULL; -} - -static int alloc_ringmemory(struct bcm43xx_dmaring *ring) -{ - struct device *dev = &(ring->bcm->pci_dev->dev); - - ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, - &(ring->dmabase), GFP_KERNEL); - if (!ring->vbase) { - printk(KERN_ERR PFX "DMA ringmemory allocation failed\n"); - return -ENOMEM; - } - if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) { - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G " - "(0x%llx, len: %lu)\n", - (unsigned long long)ring->dmabase, - BCM43xx_DMA_RINGMEMSIZE); - dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, - ring->vbase, ring->dmabase); - return -ENOMEM; - } - assert(!(ring->dmabase & 0x000003FF)); - memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE); - - return 0; -} - -static void free_ringmemory(struct bcm43xx_dmaring *ring) -{ - struct device *dev = &(ring->bcm->pci_dev->dev); - - dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, - ring->vbase, ring->dmabase); -} - -/* Reset the RX DMA channel */ -int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, - u16 mmio_base) -{ - int i; - u32 value; - - bcm43xx_write32(bcm, - mmio_base + BCM43xx_DMA_RX_CONTROL, - 0x00000000); - for (i = 0; i < 1000; i++) { - value = bcm43xx_read32(bcm, - mmio_base + BCM43xx_DMA_RX_STATUS); - value &= BCM43xx_DMA_RXSTAT_STAT_MASK; - if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) { - i = -1; - break; - } - udelay(10); - } - if (i != -1) { - printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n"); - return -ENODEV; - } - - return 0; -} - -/* Reset the RX DMA channel */ -int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, - u16 mmio_base) -{ - int i; - u32 value; - - for (i = 0; i < 1000; i++) { - value = bcm43xx_read32(bcm, - mmio_base + BCM43xx_DMA_TX_STATUS); - value &= BCM43xx_DMA_TXSTAT_STAT_MASK; - if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED || - value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT || - value == BCM43xx_DMA_TXSTAT_STAT_STOPPED) - break; - udelay(10); - } - bcm43xx_write32(bcm, - mmio_base + BCM43xx_DMA_TX_CONTROL, - 0x00000000); - for (i = 0; i < 1000; i++) { - value = bcm43xx_read32(bcm, - mmio_base + BCM43xx_DMA_TX_STATUS); - value &= BCM43xx_DMA_TXSTAT_STAT_MASK; - if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) { - i = -1; - break; - } - udelay(10); - } - if (i != -1) { - printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n"); - return -ENODEV; - } - /* ensure the reset is completed. */ - udelay(300); - - return 0; -} - -static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring, - struct bcm43xx_dmadesc *desc, - struct bcm43xx_dmadesc_meta *meta, - gfp_t gfp_flags) -{ - struct bcm43xx_rxhdr *rxhdr; - dma_addr_t dmaaddr; - u32 desc_addr; - u32 desc_ctl; - const int slot = (int)(desc - ring->vbase); - struct sk_buff *skb; - - assert(slot >= 0 && slot < ring->nr_slots); - assert(!ring->tx); - - skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); - if (unlikely(!skb)) - return -ENOMEM; - dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); - if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) { - unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); - dev_kfree_skb_any(skb); - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G " - "(0x%llx, len: %u)\n", - (unsigned long long)dmaaddr, ring->rx_buffersize); - return -ENOMEM; - } - meta->skb = skb; - meta->dmaaddr = dmaaddr; - skb->dev = ring->bcm->net_dev; - desc_addr = (u32)(dmaaddr + ring->memoffset); - desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK & - (u32)(ring->rx_buffersize - ring->frameoffset)); - if (slot == ring->nr_slots - 1) - desc_ctl |= BCM43xx_DMADTOR_DTABLEEND; - set_desc_addr(desc, desc_addr); - set_desc_ctl(desc, desc_ctl); - - rxhdr = (struct bcm43xx_rxhdr *)(skb->data); - rxhdr->frame_length = 0; - rxhdr->flags1 = 0; - - return 0; -} - -/* Allocate the initial descbuffers. - * This is used for an RX ring only. - */ -static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring) -{ - int i, err = -ENOMEM; - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - - for (i = 0; i < ring->nr_slots; i++) { - desc = ring->vbase + i; - meta = ring->meta + i; - - err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL); - if (err) - goto err_unwind; - } - ring->used_slots = ring->nr_slots; - err = 0; -out: - return err; - -err_unwind: - for (i--; i >= 0; i--) { - desc = ring->vbase + i; - meta = ring->meta + i; - - unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0); - dev_kfree_skb(meta->skb); - } - goto out; -} - -/* Do initial setup of the DMA controller. - * Reset the controller, write the ring busaddress - * and switch the "enable" bit on. - */ -static int dmacontroller_setup(struct bcm43xx_dmaring *ring) -{ - int err = 0; - u32 value; - - if (ring->tx) { - /* Set Transmit Control register to "transmit enable" */ - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, - BCM43xx_DMA_TXCTRL_ENABLE); - /* Set Transmit Descriptor ring address. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, - ring->dmabase + ring->memoffset); - } else { - err = alloc_initial_descbuffers(ring); - if (err) - goto out; - /* Set Receive Control "receive enable" and frame offset */ - value = (ring->frameoffset << BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT); - value |= BCM43xx_DMA_RXCTRL_ENABLE; - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value); - /* Set Receive Descriptor ring address. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, - ring->dmabase + ring->memoffset); - /* Init the descriptor pointer. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200); - } - -out: - return err; -} - -/* Shutdown the DMA controller. */ -static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring) -{ - if (ring->tx) { - bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base); - /* Zero out Transmit Descriptor ring address. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0); - } else { - bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base); - /* Zero out Receive Descriptor ring address. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0); - } -} - -static void free_all_descbuffers(struct bcm43xx_dmaring *ring) -{ - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - int i; - - if (!ring->used_slots) - return; - for (i = 0; i < ring->nr_slots; i++) { - desc = ring->vbase + i; - meta = ring->meta + i; - - if (!meta->skb) { - assert(ring->tx); - continue; - } - if (ring->tx) { - unmap_descbuffer(ring, meta->dmaaddr, - meta->skb->len, 1); - } else { - unmap_descbuffer(ring, meta->dmaaddr, - ring->rx_buffersize, 0); - } - free_descriptor_buffer(ring, desc, meta, 0); - } -} - -/* Main initialization function. */ -static -struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm, - u16 dma_controller_base, - int nr_descriptor_slots, - int tx) -{ - struct bcm43xx_dmaring *ring; - int err; - - ring = kzalloc(sizeof(*ring), GFP_KERNEL); - if (!ring) - goto out; - - ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots, - GFP_KERNEL); - if (!ring->meta) - goto err_kfree_ring; - - ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET; -#ifdef CONFIG_BCM947XX - if (bcm->pci_dev->bus->number == 0) - ring->memoffset = 0; -#endif - - ring->bcm = bcm; - ring->nr_slots = nr_descriptor_slots; - ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100; - ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100; - assert(ring->suspend_mark < ring->resume_mark); - ring->mmio_base = dma_controller_base; - if (tx) { - ring->tx = 1; - ring->current_slot = -1; - } else { - switch (dma_controller_base) { - case BCM43xx_MMIO_DMA1_BASE: - ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE; - ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET; - break; - case BCM43xx_MMIO_DMA4_BASE: - ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE; - ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET; - break; - default: - assert(0); - } - } - - err = alloc_ringmemory(ring); - if (err) - goto err_kfree_meta; - err = dmacontroller_setup(ring); - if (err) - goto err_free_ringmemory; - -out: - return ring; - -err_free_ringmemory: - free_ringmemory(ring); -err_kfree_meta: - kfree(ring->meta); -err_kfree_ring: - kfree(ring); - ring = NULL; - goto out; -} - -/* Main cleanup function. */ -static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring) -{ - if (!ring) - return; - - dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n", - ring->mmio_base, - (ring->tx) ? "TX" : "RX", - ring->max_used_slots, ring->nr_slots); - /* Device IRQs are disabled prior entering this function, - * so no need to take care of concurrency with rx handler stuff. - */ - dmacontroller_cleanup(ring); - free_all_descbuffers(ring); - free_ringmemory(ring); - - kfree(ring->meta); - kfree(ring); -} - -void bcm43xx_dma_free(struct bcm43xx_private *bcm) -{ - struct bcm43xx_dma *dma; - - if (bcm43xx_using_pio(bcm)) - return; - dma = bcm43xx_current_dma(bcm); - - bcm43xx_destroy_dmaring(dma->rx_ring1); - dma->rx_ring1 = NULL; - bcm43xx_destroy_dmaring(dma->rx_ring0); - dma->rx_ring0 = NULL; - bcm43xx_destroy_dmaring(dma->tx_ring3); - dma->tx_ring3 = NULL; - bcm43xx_destroy_dmaring(dma->tx_ring2); - dma->tx_ring2 = NULL; - bcm43xx_destroy_dmaring(dma->tx_ring1); - dma->tx_ring1 = NULL; - bcm43xx_destroy_dmaring(dma->tx_ring0); - dma->tx_ring0 = NULL; -} - -int bcm43xx_dma_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm); - struct bcm43xx_dmaring *ring; - int err = -ENOMEM; - - /* setup TX DMA channels. */ - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE, - BCM43xx_TXRING_SLOTS, 1); - if (!ring) - goto out; - dma->tx_ring0 = ring; - - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE, - BCM43xx_TXRING_SLOTS, 1); - if (!ring) - goto err_destroy_tx0; - dma->tx_ring1 = ring; - - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE, - BCM43xx_TXRING_SLOTS, 1); - if (!ring) - goto err_destroy_tx1; - dma->tx_ring2 = ring; - - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE, - BCM43xx_TXRING_SLOTS, 1); - if (!ring) - goto err_destroy_tx2; - dma->tx_ring3 = ring; - - /* setup RX DMA channels. */ - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE, - BCM43xx_RXRING_SLOTS, 0); - if (!ring) - goto err_destroy_tx3; - dma->rx_ring0 = ring; - - if (bcm->current_core->rev < 5) { - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE, - BCM43xx_RXRING_SLOTS, 0); - if (!ring) - goto err_destroy_rx0; - dma->rx_ring1 = ring; - } - - dprintk(KERN_INFO PFX "DMA initialized\n"); - err = 0; -out: - return err; - -err_destroy_rx0: - bcm43xx_destroy_dmaring(dma->rx_ring0); - dma->rx_ring0 = NULL; -err_destroy_tx3: - bcm43xx_destroy_dmaring(dma->tx_ring3); - dma->tx_ring3 = NULL; -err_destroy_tx2: - bcm43xx_destroy_dmaring(dma->tx_ring2); - dma->tx_ring2 = NULL; -err_destroy_tx1: - bcm43xx_destroy_dmaring(dma->tx_ring1); - dma->tx_ring1 = NULL; -err_destroy_tx0: - bcm43xx_destroy_dmaring(dma->tx_ring0); - dma->tx_ring0 = NULL; - goto out; -} - -/* Generate a cookie for the TX header. */ -static u16 generate_cookie(struct bcm43xx_dmaring *ring, - int slot) -{ - u16 cookie = 0xF000; - - /* Use the upper 4 bits of the cookie as - * DMA controller ID and store the slot number - * in the lower 12 bits. - * Note that the cookie must never be 0, as this - * is a special value used in RX path. - */ - switch (ring->mmio_base) { - default: - assert(0); - case BCM43xx_MMIO_DMA1_BASE: - cookie = 0xA000; - break; - case BCM43xx_MMIO_DMA2_BASE: - cookie = 0xB000; - break; - case BCM43xx_MMIO_DMA3_BASE: - cookie = 0xC000; - break; - case BCM43xx_MMIO_DMA4_BASE: - cookie = 0xD000; - break; - } - assert(((u16)slot & 0xF000) == 0x0000); - cookie |= (u16)slot; - - return cookie; -} - -/* Inspect a cookie and find out to which controller/slot it belongs. */ -static -struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm, - u16 cookie, int *slot) -{ - struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm); - struct bcm43xx_dmaring *ring = NULL; - - switch (cookie & 0xF000) { - case 0xA000: - ring = dma->tx_ring0; - break; - case 0xB000: - ring = dma->tx_ring1; - break; - case 0xC000: - ring = dma->tx_ring2; - break; - case 0xD000: - ring = dma->tx_ring3; - break; - default: - assert(0); - } - *slot = (cookie & 0x0FFF); - assert(*slot >= 0 && *slot < ring->nr_slots); - - return ring; -} - -static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring, - int slot) -{ - /* Everything is ready to start. Buffers are DMA mapped and - * associated with slots. - * "slot" is the last slot of the new frame we want to transmit. - * Close your seat belts now, please. - */ - wmb(); - slot = next_slot(ring, slot); - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX, - (u32)(slot * sizeof(struct bcm43xx_dmadesc))); -} - -static int dma_tx_fragment(struct bcm43xx_dmaring *ring, - struct sk_buff *skb, - u8 cur_frag) -{ - int slot; - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - u32 desc_ctl; - u32 desc_addr; - - assert(skb_shinfo(skb)->nr_frags == 0); - - slot = request_slot(ring); - desc = ring->vbase + slot; - meta = ring->meta + slot; - - /* Add a device specific TX header. */ - assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr)); - /* Reserve enough headroom for the device tx header. */ - __skb_push(skb, sizeof(struct bcm43xx_txhdr)); - /* Now calculate and add the tx header. - * The tx header includes the PLCP header. - */ - bcm43xx_generate_txhdr(ring->bcm, - (struct bcm43xx_txhdr *)skb->data, - skb->data + sizeof(struct bcm43xx_txhdr), - skb->len - sizeof(struct bcm43xx_txhdr), - (cur_frag == 0), - generate_cookie(ring, slot)); - - meta->skb = skb; - meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); - if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) { - return_slot(ring, slot); - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G " - "(0x%llx, len: %u)\n", - (unsigned long long)meta->dmaaddr, skb->len); - return -ENOMEM; - } - - desc_addr = (u32)(meta->dmaaddr + ring->memoffset); - desc_ctl = BCM43xx_DMADTOR_FRAMESTART | BCM43xx_DMADTOR_FRAMEEND; - desc_ctl |= BCM43xx_DMADTOR_COMPIRQ; - desc_ctl |= (BCM43xx_DMADTOR_BYTECNT_MASK & - (u32)(meta->skb->len - ring->frameoffset)); - if (slot == ring->nr_slots - 1) - desc_ctl |= BCM43xx_DMADTOR_DTABLEEND; - - set_desc_ctl(desc, desc_ctl); - set_desc_addr(desc, desc_addr); - /* Now transfer the whole frame. */ - dmacontroller_poke_tx(ring, slot); - - return 0; -} - -int bcm43xx_dma_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - /* We just received a packet from the kernel network subsystem. - * Add headers and DMA map the memory. Poke - * the device to send the stuff. - * Note that this is called from atomic context. - */ - struct bcm43xx_dmaring *ring = bcm43xx_current_dma(bcm)->tx_ring1; - u8 i; - struct sk_buff *skb; - - assert(ring->tx); - if (unlikely(free_slots(ring) < txb->nr_frags)) { - /* The queue should be stopped, - * if we are low on free slots. - * If this ever triggers, we have to lower the suspend_mark. - */ - dprintkl(KERN_ERR PFX "Out of DMA descriptor slots!\n"); - return -ENOMEM; - } - - for (i = 0; i < txb->nr_frags; i++) { - skb = txb->fragments[i]; - /* Take skb from ieee80211_txb_free */ - txb->fragments[i] = NULL; - dma_tx_fragment(ring, skb, i); - //TODO: handle failure of dma_tx_fragment - } - ieee80211_txb_free(txb); - - return 0; -} - -void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ - struct bcm43xx_dmaring *ring; - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - int is_last_fragment; - int slot; - - ring = parse_cookie(bcm, status->cookie, &slot); - assert(ring); - assert(ring->tx); - assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART); - while (1) { - assert(slot >= 0 && slot < ring->nr_slots); - desc = ring->vbase + slot; - meta = ring->meta + slot; - - is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND); - unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); - free_descriptor_buffer(ring, desc, meta, 1); - /* Everything belonging to the slot is unmapped - * and freed, so we can return it. - */ - return_slot(ring, slot); - - if (is_last_fragment) - break; - slot = next_slot(ring, slot); - } - bcm->stats.last_tx = jiffies; -} - -static void dma_rx(struct bcm43xx_dmaring *ring, - int *slot) -{ - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - struct bcm43xx_rxhdr *rxhdr; - struct sk_buff *skb; - u16 len; - int err; - dma_addr_t dmaaddr; - - desc = ring->vbase + *slot; - meta = ring->meta + *slot; - - sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize); - skb = meta->skb; - - if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) { - /* We received an xmit status. */ - struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; - struct bcm43xx_xmitstatus stat; - int i = 0; - - stat.cookie = le16_to_cpu(hw->cookie); - while (stat.cookie == 0) { - if (unlikely(++i >= 10000)) { - assert(0); - break; - } - udelay(2); - barrier(); - stat.cookie = le16_to_cpu(hw->cookie); - } - stat.flags = hw->flags; - stat.cnt1 = hw->cnt1; - stat.cnt2 = hw->cnt2; - stat.seq = le16_to_cpu(hw->seq); - stat.unknown = le16_to_cpu(hw->unknown); - - bcm43xx_debugfs_log_txstat(ring->bcm, &stat); - bcm43xx_dma_handle_xmitstatus(ring->bcm, &stat); - /* recycle the descriptor buffer. */ - sync_descbuffer_for_device(ring, meta->dmaaddr, ring->rx_buffersize); - - return; - } - rxhdr = (struct bcm43xx_rxhdr *)skb->data; - len = le16_to_cpu(rxhdr->frame_length); - if (len == 0) { - int i = 0; - - do { - udelay(2); - barrier(); - len = le16_to_cpu(rxhdr->frame_length); - } while (len == 0 && i++ < 5); - if (unlikely(len == 0)) { - /* recycle the descriptor buffer. */ - sync_descbuffer_for_device(ring, meta->dmaaddr, - ring->rx_buffersize); - goto drop; - } - } - if (unlikely(len > ring->rx_buffersize)) { - /* The data did not fit into one descriptor buffer - * and is split over multiple buffers. - * This should never happen, as we try to allocate buffers - * big enough. So simply ignore this packet. - */ - int cnt = 0; - s32 tmp = len; - - while (1) { - desc = ring->vbase + *slot; - meta = ring->meta + *slot; - /* recycle the descriptor buffer. */ - sync_descbuffer_for_device(ring, meta->dmaaddr, - ring->rx_buffersize); - *slot = next_slot(ring, *slot); - cnt++; - tmp -= ring->rx_buffersize; - if (tmp <= 0) - break; - } - printkl(KERN_ERR PFX "DMA RX buffer too small " - "(len: %u, buffer: %u, nr-dropped: %d)\n", - len, ring->rx_buffersize, cnt); - goto drop; - } - len -= IEEE80211_FCS_LEN; - - dmaaddr = meta->dmaaddr; - err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC); - if (unlikely(err)) { - dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n"); - sync_descbuffer_for_device(ring, dmaaddr, - ring->rx_buffersize); - goto drop; - } - - unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); - skb_put(skb, len + ring->frameoffset); - skb_pull(skb, ring->frameoffset); - - err = bcm43xx_rx(ring->bcm, skb, rxhdr); - if (err) { - dev_kfree_skb_irq(skb); - goto drop; - } - -drop: - return; -} - -void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) -{ - u32 status; - u16 descptr; - int slot, current_slot; -#ifdef CONFIG_BCM43XX_DEBUG - int used_slots = 0; -#endif - - assert(!ring->tx); - status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS); - descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK); - current_slot = descptr / sizeof(struct bcm43xx_dmadesc); - assert(current_slot >= 0 && current_slot < ring->nr_slots); - - slot = ring->current_slot; - for ( ; slot != current_slot; slot = next_slot(ring, slot)) { - dma_rx(ring, &slot); -#ifdef CONFIG_BCM43XX_DEBUG - if (++used_slots > ring->max_used_slots) - ring->max_used_slots = used_slots; -#endif - } - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, - (u32)(slot * sizeof(struct bcm43xx_dmadesc))); - ring->current_slot = slot; -} - -void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring) -{ - assert(ring->tx); - bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1); - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, - bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL) - | BCM43xx_DMA_TXCTRL_SUSPEND); -} - -void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring) -{ - assert(ring->tx); - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, - bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL) - & ~BCM43xx_DMA_TXCTRL_SUSPEND); - bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1); -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h deleted file mode 100644 index b7d77638b..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef BCM43xx_DMA_H_ -#define BCM43xx_DMA_H_ - -#include -#include -#include -#include -#include - - -/* DMA-Interrupt reasons. */ -#define BCM43xx_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ - | (1 << 14) | (1 << 15)) -#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13) -#define BCM43xx_DMAIRQ_RX_DONE (1 << 16) - -/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */ -#define BCM43xx_DMA_TX_CONTROL 0x00 -#define BCM43xx_DMA_TX_DESC_RING 0x04 -#define BCM43xx_DMA_TX_DESC_INDEX 0x08 -#define BCM43xx_DMA_TX_STATUS 0x0c -#define BCM43xx_DMA_RX_CONTROL 0x10 -#define BCM43xx_DMA_RX_DESC_RING 0x14 -#define BCM43xx_DMA_RX_DESC_INDEX 0x18 -#define BCM43xx_DMA_RX_STATUS 0x1c - -/* DMA controller channel control word values. */ -#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0) -#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1) -#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2) -#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4) -#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0) -#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe -#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1 -#define BCM43xx_DMA_RXCTRL_PIO (1 << 8) -/* DMA controller channel status word values. */ -#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff -#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000 -#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000 -#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000 -#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000 -#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000 -#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000 -#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000 -#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20) -#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff -#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000 -#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000 -#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000 -#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000 -#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000 -#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000 -#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000 - -/* DMA descriptor control field values. */ -#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff -#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */ -#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */ -#define BCM43xx_DMADTOR_FRAMEEND (1 << 30) -#define BCM43xx_DMADTOR_FRAMESTART (1 << 31) - -/* Misc DMA constants */ -#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE -#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF -#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30) -#define BCM43xx_DMA1_RX_FRAMEOFFSET 30 -#define BCM43xx_DMA4_RX_FRAMEOFFSET 0 - -/* DMA engine tuning knobs */ -#define BCM43xx_TXRING_SLOTS 512 -#define BCM43xx_RXRING_SLOTS 64 -#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100) -#define BCM43xx_DMA4_RXBUFFERSIZE 16 -/* Suspend the tx queue, if less than this percent slots are free. */ -#define BCM43xx_TXSUSPEND_PERCENT 20 -/* Resume the tx queue, if more than this percent slots are free. */ -#define BCM43xx_TXRESUME_PERCENT 50 - - - -#ifdef CONFIG_BCM43XX_DMA - - -struct sk_buff; -struct bcm43xx_private; -struct bcm43xx_xmitstatus; - - -struct bcm43xx_dmadesc { - __le32 _control; - __le32 _address; -} __attribute__((__packed__)); - -/* Macros to access the bcm43xx_dmadesc struct */ -#define get_desc_ctl(desc) le32_to_cpu((desc)->_control) -#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0) -#define get_desc_addr(desc) le32_to_cpu((desc)->_address) -#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0) - -struct bcm43xx_dmadesc_meta { - /* The kernel DMA-able buffer. */ - struct sk_buff *skb; - /* DMA base bus-address of the descriptor buffer. */ - dma_addr_t dmaaddr; -}; - -struct bcm43xx_dmaring { - struct bcm43xx_private *bcm; - /* Kernel virtual base address of the ring memory. */ - struct bcm43xx_dmadesc *vbase; - /* DMA memory offset */ - dma_addr_t memoffset; - /* (Unadjusted) DMA base bus-address of the ring memory. */ - dma_addr_t dmabase; - /* Meta data about all descriptors. */ - struct bcm43xx_dmadesc_meta *meta; - /* Number of descriptor slots in the ring. */ - int nr_slots; - /* Number of used descriptor slots. */ - int used_slots; - /* Currently used slot in the ring. */ - int current_slot; - /* Marks to suspend/resume the queue. */ - int suspend_mark; - int resume_mark; - /* Frameoffset in octets. */ - u32 frameoffset; - /* Descriptor buffer size. */ - u16 rx_buffersize; - /* The MMIO base register of the DMA controller, this - * ring is posted to. - */ - u16 mmio_base; - u8 tx:1, /* TRUE, if this is a TX ring. */ - suspended:1; /* TRUE, if transfers are suspended on this ring. */ -#ifdef CONFIG_BCM43XX_DEBUG - /* Maximum number of used slots. */ - int max_used_slots; -#endif /* CONFIG_BCM43XX_DEBUG*/ -}; - - -static inline -u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring, - u16 offset) -{ - return bcm43xx_read32(ring->bcm, ring->mmio_base + offset); -} - -static inline -void bcm43xx_dma_write(struct bcm43xx_dmaring *ring, - u16 offset, u32 value) -{ - bcm43xx_write32(ring->bcm, ring->mmio_base + offset, value); -} - - -int bcm43xx_dma_init(struct bcm43xx_private *bcm); -void bcm43xx_dma_free(struct bcm43xx_private *bcm); - -int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, - u16 dmacontroller_mmio_base); -int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, - u16 dmacontroller_mmio_base); - -void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring); -void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring); - -void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status); - -int bcm43xx_dma_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb); -void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); - - -#else /* CONFIG_BCM43XX_DMA */ - - -static inline -int bcm43xx_dma_init(struct bcm43xx_private *bcm) -{ - return 0; -} -static inline -void bcm43xx_dma_free(struct bcm43xx_private *bcm) -{ -} -static inline -int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, - u16 dmacontroller_mmio_base) -{ - return 0; -} -static inline -int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, - u16 dmacontroller_mmio_base) -{ - return 0; -} -static inline -int bcm43xx_dma_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - return 0; -} -static inline -void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ -} -static inline -void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) -{ -} -static inline -void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring) -{ -} -static inline -void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring) -{ -} - -#endif /* CONFIG_BCM43XX_DMA */ -#endif /* BCM43xx_DMA_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c deleted file mode 100644 index b3ffcf501..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - ethtool support - - Copyright (c) 2006 Jason Lunz - - Some code in this file is derived from the 8139too.c driver - Copyright (C) 2002 Jeff Garzik - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx.h" -#include "bcm43xx_ethtool.h" - -#include -#include -#include -#include - - -static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(dev); - - strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); - strncpy(info->version, UTS_RELEASE, sizeof(info->version)); - strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN); -} - -struct ethtool_ops bcm43xx_ethtool_ops = { - .get_drvinfo = bcm43xx_get_drvinfo, - .get_link = ethtool_op_get_link, -}; diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h deleted file mode 100644 index 813704991..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef BCM43xx_ETHTOOL_H_ -#define BCM43xx_ETHTOOL_H_ - -#include - -extern struct ethtool_ops bcm43xx_ethtool_ops; - -#endif /* BCM43xx_ETHTOOL_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c deleted file mode 100644 index ad8e569d1..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx.h" -#include "bcm43xx_ilt.h" -#include "bcm43xx_phy.h" - - -/**** Initial Internal Lookup Tables ****/ - -const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE] = { - 0xFEB93FFD, 0xFEC63FFD, /* 0 */ - 0xFED23FFD, 0xFEDF3FFD, - 0xFEEC3FFE, 0xFEF83FFE, - 0xFF053FFE, 0xFF113FFE, - 0xFF1E3FFE, 0xFF2A3FFF, /* 8 */ - 0xFF373FFF, 0xFF443FFF, - 0xFF503FFF, 0xFF5D3FFF, - 0xFF693FFF, 0xFF763FFF, - 0xFF824000, 0xFF8F4000, /* 16 */ - 0xFF9B4000, 0xFFA84000, - 0xFFB54000, 0xFFC14000, - 0xFFCE4000, 0xFFDA4000, - 0xFFE74000, 0xFFF34000, /* 24 */ - 0x00004000, 0x000D4000, - 0x00194000, 0x00264000, - 0x00324000, 0x003F4000, - 0x004B4000, 0x00584000, /* 32 */ - 0x00654000, 0x00714000, - 0x007E4000, 0x008A3FFF, - 0x00973FFF, 0x00A33FFF, - 0x00B03FFF, 0x00BC3FFF, /* 40 */ - 0x00C93FFF, 0x00D63FFF, - 0x00E23FFE, 0x00EF3FFE, - 0x00FB3FFE, 0x01083FFE, - 0x01143FFE, 0x01213FFD, /* 48 */ - 0x012E3FFD, 0x013A3FFD, - 0x01473FFD, -}; - -const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE] = { - 0xDB93CB87, 0xD666CF64, /* 0 */ - 0xD1FDD358, 0xCDA6D826, - 0xCA38DD9F, 0xC729E2B4, - 0xC469E88E, 0xC26AEE2B, - 0xC0DEF46C, 0xC073FA62, /* 8 */ - 0xC01D00D5, 0xC0760743, - 0xC1560D1E, 0xC2E51369, - 0xC4ED18FF, 0xC7AC1ED7, - 0xCB2823B2, 0xCEFA28D9, /* 16 */ - 0xD2F62D3F, 0xD7BB3197, - 0xDCE53568, 0xE1FE3875, - 0xE7D13B35, 0xED663D35, - 0xF39B3EC4, 0xF98E3FA7, /* 24 */ - 0x00004000, 0x06723FA7, - 0x0C653EC4, 0x129A3D35, - 0x182F3B35, 0x1E023875, - 0x231B3568, 0x28453197, /* 32 */ - 0x2D0A2D3F, 0x310628D9, - 0x34D823B2, 0x38541ED7, - 0x3B1318FF, 0x3D1B1369, - 0x3EAA0D1E, 0x3F8A0743, /* 40 */ - 0x3FE300D5, 0x3F8DFA62, - 0x3F22F46C, 0x3D96EE2B, - 0x3B97E88E, 0x38D7E2B4, - 0x35C8DD9F, 0x325AD826, /* 48 */ - 0x2E03D358, 0x299ACF64, - 0x246DCB87, -}; - -const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE] = { - 0x0082, 0x0082, 0x0102, 0x0182, /* 0 */ - 0x0202, 0x0282, 0x0302, 0x0382, - 0x0402, 0x0482, 0x0502, 0x0582, - 0x05E2, 0x0662, 0x06E2, 0x0762, - 0x07E2, 0x0842, 0x08C2, 0x0942, /* 16 */ - 0x09C2, 0x0A22, 0x0AA2, 0x0B02, - 0x0B82, 0x0BE2, 0x0C62, 0x0CC2, - 0x0D42, 0x0DA2, 0x0E02, 0x0E62, - 0x0EE2, 0x0F42, 0x0FA2, 0x1002, /* 32 */ - 0x1062, 0x10C2, 0x1122, 0x1182, - 0x11E2, 0x1242, 0x12A2, 0x12E2, - 0x1342, 0x13A2, 0x1402, 0x1442, - 0x14A2, 0x14E2, 0x1542, 0x1582, /* 48 */ - 0x15E2, 0x1622, 0x1662, 0x16C1, - 0x1701, 0x1741, 0x1781, 0x17E1, - 0x1821, 0x1861, 0x18A1, 0x18E1, - 0x1921, 0x1961, 0x19A1, 0x19E1, /* 64 */ - 0x1A21, 0x1A61, 0x1AA1, 0x1AC1, - 0x1B01, 0x1B41, 0x1B81, 0x1BA1, - 0x1BE1, 0x1C21, 0x1C41, 0x1C81, - 0x1CA1, 0x1CE1, 0x1D01, 0x1D41, /* 80 */ - 0x1D61, 0x1DA1, 0x1DC1, 0x1E01, - 0x1E21, 0x1E61, 0x1E81, 0x1EA1, - 0x1EE1, 0x1F01, 0x1F21, 0x1F41, - 0x1F81, 0x1FA1, 0x1FC1, 0x1FE1, /* 96 */ - 0x2001, 0x2041, 0x2061, 0x2081, - 0x20A1, 0x20C1, 0x20E1, 0x2101, - 0x2121, 0x2141, 0x2161, 0x2181, - 0x21A1, 0x21C1, 0x21E1, 0x2201, /* 112 */ - 0x2221, 0x2241, 0x2261, 0x2281, - 0x22A1, 0x22C1, 0x22C1, 0x22E1, - 0x2301, 0x2321, 0x2341, 0x2361, - 0x2361, 0x2381, 0x23A1, 0x23C1, /* 128 */ - 0x23E1, 0x23E1, 0x2401, 0x2421, - 0x2441, 0x2441, 0x2461, 0x2481, - 0x2481, 0x24A1, 0x24C1, 0x24C1, - 0x24E1, 0x2501, 0x2501, 0x2521, /* 144 */ - 0x2541, 0x2541, 0x2561, 0x2561, - 0x2581, 0x25A1, 0x25A1, 0x25C1, - 0x25C1, 0x25E1, 0x2601, 0x2601, - 0x2621, 0x2621, 0x2641, 0x2641, /* 160 */ - 0x2661, 0x2661, 0x2681, 0x2681, - 0x26A1, 0x26A1, 0x26C1, 0x26C1, - 0x26E1, 0x26E1, 0x2701, 0x2701, - 0x2721, 0x2721, 0x2740, 0x2740, /* 176 */ - 0x2760, 0x2760, 0x2780, 0x2780, - 0x2780, 0x27A0, 0x27A0, 0x27C0, - 0x27C0, 0x27E0, 0x27E0, 0x27E0, - 0x2800, 0x2800, 0x2820, 0x2820, /* 192 */ - 0x2820, 0x2840, 0x2840, 0x2840, - 0x2860, 0x2860, 0x2880, 0x2880, - 0x2880, 0x28A0, 0x28A0, 0x28A0, - 0x28C0, 0x28C0, 0x28C0, 0x28E0, /* 208 */ - 0x28E0, 0x28E0, 0x2900, 0x2900, - 0x2900, 0x2920, 0x2920, 0x2920, - 0x2940, 0x2940, 0x2940, 0x2960, - 0x2960, 0x2960, 0x2960, 0x2980, /* 224 */ - 0x2980, 0x2980, 0x29A0, 0x29A0, - 0x29A0, 0x29A0, 0x29C0, 0x29C0, - 0x29C0, 0x29E0, 0x29E0, 0x29E0, - 0x29E0, 0x2A00, 0x2A00, 0x2A00, /* 240 */ - 0x2A00, 0x2A20, 0x2A20, 0x2A20, - 0x2A20, 0x2A40, 0x2A40, 0x2A40, - 0x2A40, 0x2A60, 0x2A60, 0x2A60, -}; - -const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE] = { - 0x0089, 0x02E9, 0x0409, 0x04E9, /* 0 */ - 0x05A9, 0x0669, 0x0709, 0x0789, - 0x0829, 0x08A9, 0x0929, 0x0989, - 0x0A09, 0x0A69, 0x0AC9, 0x0B29, - 0x0BA9, 0x0BE9, 0x0C49, 0x0CA9, /* 16 */ - 0x0D09, 0x0D69, 0x0DA9, 0x0E09, - 0x0E69, 0x0EA9, 0x0F09, 0x0F49, - 0x0FA9, 0x0FE9, 0x1029, 0x1089, - 0x10C9, 0x1109, 0x1169, 0x11A9, /* 32 */ - 0x11E9, 0x1229, 0x1289, 0x12C9, - 0x1309, 0x1349, 0x1389, 0x13C9, - 0x1409, 0x1449, 0x14A9, 0x14E9, - 0x1529, 0x1569, 0x15A9, 0x15E9, /* 48 */ - 0x1629, 0x1669, 0x16A9, 0x16E8, - 0x1728, 0x1768, 0x17A8, 0x17E8, - 0x1828, 0x1868, 0x18A8, 0x18E8, - 0x1928, 0x1968, 0x19A8, 0x19E8, /* 64 */ - 0x1A28, 0x1A68, 0x1AA8, 0x1AE8, - 0x1B28, 0x1B68, 0x1BA8, 0x1BE8, - 0x1C28, 0x1C68, 0x1CA8, 0x1CE8, - 0x1D28, 0x1D68, 0x1DC8, 0x1E08, /* 80 */ - 0x1E48, 0x1E88, 0x1EC8, 0x1F08, - 0x1F48, 0x1F88, 0x1FE8, 0x2028, - 0x2068, 0x20A8, 0x2108, 0x2148, - 0x2188, 0x21C8, 0x2228, 0x2268, /* 96 */ - 0x22C8, 0x2308, 0x2348, 0x23A8, - 0x23E8, 0x2448, 0x24A8, 0x24E8, - 0x2548, 0x25A8, 0x2608, 0x2668, - 0x26C8, 0x2728, 0x2787, 0x27E7, /* 112 */ - 0x2847, 0x28C7, 0x2947, 0x29A7, - 0x2A27, 0x2AC7, 0x2B47, 0x2BE7, - 0x2CA7, 0x2D67, 0x2E47, 0x2F67, - 0x3247, 0x3526, 0x3646, 0x3726, /* 128 */ - 0x3806, 0x38A6, 0x3946, 0x39E6, - 0x3A66, 0x3AE6, 0x3B66, 0x3BC6, - 0x3C45, 0x3CA5, 0x3D05, 0x3D85, - 0x3DE5, 0x3E45, 0x3EA5, 0x3EE5, /* 144 */ - 0x3F45, 0x3FA5, 0x4005, 0x4045, - 0x40A5, 0x40E5, 0x4145, 0x4185, - 0x41E5, 0x4225, 0x4265, 0x42C5, - 0x4305, 0x4345, 0x43A5, 0x43E5, /* 160 */ - 0x4424, 0x4464, 0x44C4, 0x4504, - 0x4544, 0x4584, 0x45C4, 0x4604, - 0x4644, 0x46A4, 0x46E4, 0x4724, - 0x4764, 0x47A4, 0x47E4, 0x4824, /* 176 */ - 0x4864, 0x48A4, 0x48E4, 0x4924, - 0x4964, 0x49A4, 0x49E4, 0x4A24, - 0x4A64, 0x4AA4, 0x4AE4, 0x4B23, - 0x4B63, 0x4BA3, 0x4BE3, 0x4C23, /* 192 */ - 0x4C63, 0x4CA3, 0x4CE3, 0x4D23, - 0x4D63, 0x4DA3, 0x4DE3, 0x4E23, - 0x4E63, 0x4EA3, 0x4EE3, 0x4F23, - 0x4F63, 0x4FC3, 0x5003, 0x5043, /* 208 */ - 0x5083, 0x50C3, 0x5103, 0x5143, - 0x5183, 0x51E2, 0x5222, 0x5262, - 0x52A2, 0x52E2, 0x5342, 0x5382, - 0x53C2, 0x5402, 0x5462, 0x54A2, /* 224 */ - 0x5502, 0x5542, 0x55A2, 0x55E2, - 0x5642, 0x5682, 0x56E2, 0x5722, - 0x5782, 0x57E1, 0x5841, 0x58A1, - 0x5901, 0x5961, 0x59C1, 0x5A21, /* 240 */ - 0x5AA1, 0x5B01, 0x5B81, 0x5BE1, - 0x5C61, 0x5D01, 0x5D80, 0x5E20, - 0x5EE0, 0x5FA0, 0x6080, 0x61C0, -}; - -const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE] = { - 0x0001, 0x0001, 0x0001, 0xFFFE, - 0xFFFE, 0x3FFF, 0x1000, 0x0393, -}; - -const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE] = { - 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, - 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, -}; - -const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE] = { - 0x013C, 0x01F5, 0x031A, 0x0631, - 0x0001, 0x0001, 0x0001, 0x0001, -}; - -const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE] = { - 0x5484, 0x3C40, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, -}; - -const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE] = { - 0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */ - 0x2F2D, 0x2A2A, 0x2527, 0x1F21, - 0x1A1D, 0x1719, 0x1616, 0x1414, - 0x1414, 0x1400, 0x1414, 0x1614, - 0x1716, 0x1A19, 0x1F1D, 0x2521, /* 16 */ - 0x2A27, 0x2F2A, 0x332D, 0x3B35, - 0x5140, 0x6C62, 0x0077, -}; - -const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE] = { - 0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */ - 0xB2B0, 0xADAD, 0xA7A9, 0x9FA1, - 0x969B, 0x9195, 0x8F8F, 0x8A8A, - 0x8A8A, 0x8A00, 0x8A8A, 0x8F8A, - 0x918F, 0x9695, 0x9F9B, 0xA7A1, /* 16 */ - 0xADA9, 0xB2AD, 0xB6B0, 0xBCB7, - 0xCBC0, 0xD8D4, 0x00DD, -}; - -const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE] = { - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 0 */ - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, - 0xA4A4, 0xA400, 0xA4A4, 0xA4A4, - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 16 */ - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, - 0xA4A4, 0xA4A4, 0x00A4, -}; - -const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE] = { - 0x007A, 0x0075, 0x0071, 0x006C, /* 0 */ - 0x0067, 0x0063, 0x005E, 0x0059, - 0x0054, 0x0050, 0x004B, 0x0046, - 0x0042, 0x003D, 0x003D, 0x003D, - 0x003D, 0x003D, 0x003D, 0x003D, /* 16 */ - 0x003D, 0x003D, 0x003D, 0x003D, - 0x003D, 0x003D, 0x0000, 0x003D, - 0x003D, 0x003D, 0x003D, 0x003D, - 0x003D, 0x003D, 0x003D, 0x003D, /* 32 */ - 0x003D, 0x003D, 0x003D, 0x003D, - 0x0042, 0x0046, 0x004B, 0x0050, - 0x0054, 0x0059, 0x005E, 0x0063, - 0x0067, 0x006C, 0x0071, 0x0075, /* 48 */ - 0x007A, -}; - -const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = { - 0x00DE, 0x00DC, 0x00DA, 0x00D8, /* 0 */ - 0x00D6, 0x00D4, 0x00D2, 0x00CF, - 0x00CD, 0x00CA, 0x00C7, 0x00C4, - 0x00C1, 0x00BE, 0x00BE, 0x00BE, - 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 16 */ - 0x00BE, 0x00BE, 0x00BE, 0x00BE, - 0x00BE, 0x00BE, 0x0000, 0x00BE, - 0x00BE, 0x00BE, 0x00BE, 0x00BE, - 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 32 */ - 0x00BE, 0x00BE, 0x00BE, 0x00BE, - 0x00C1, 0x00C4, 0x00C7, 0x00CA, - 0x00CD, 0x00CF, 0x00D2, 0x00D4, - 0x00D6, 0x00D8, 0x00DA, 0x00DC, /* 48 */ - 0x00DE, -}; - -/**** Helper functions to access the device Internal Lookup Tables ****/ - -void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset); - mmiowb(); - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val); - } else { - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset); - mmiowb(); - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val); - } -} - -u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset); - return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1); - } else { - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset); - return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1); - } -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h deleted file mode 100644 index 464521abf..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef BCM43xx_ILT_H_ -#define BCM43xx_ILT_H_ - -#define BCM43xx_ILT_ROTOR_SIZE 53 -extern const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE]; -#define BCM43xx_ILT_RETARD_SIZE 53 -extern const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE]; -#define BCM43xx_ILT_FINEFREQA_SIZE 256 -extern const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE]; -#define BCM43xx_ILT_FINEFREQG_SIZE 256 -extern const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE]; -#define BCM43xx_ILT_NOISEA2_SIZE 8 -extern const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE]; -#define BCM43xx_ILT_NOISEA3_SIZE 8 -extern const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE]; -#define BCM43xx_ILT_NOISEG1_SIZE 8 -extern const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE]; -#define BCM43xx_ILT_NOISEG2_SIZE 8 -extern const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE]; -#define BCM43xx_ILT_NOISESCALEG_SIZE 27 -extern const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE]; -extern const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE]; -extern const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE]; -#define BCM43xx_ILT_SIGMASQR_SIZE 53 -extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE]; -extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE]; - - -void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val); -u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset); - -#endif /* BCM43xx_ILT_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c deleted file mode 100644 index 4b2c02c0b..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx_leds.h" -#include "bcm43xx.h" - -#include - - -static void bcm43xx_led_changestate(struct bcm43xx_led *led) -{ - struct bcm43xx_private *bcm = led->bcm; - const int index = bcm43xx_led_index(led); - const u16 mask = (1 << index); - u16 ledctl; - - assert(index >= 0 && index < BCM43xx_NR_LEDS); - assert(led->blink_interval); - ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask); - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); -} - -static void bcm43xx_led_blink(unsigned long d) -{ - struct bcm43xx_led *led = (struct bcm43xx_led *)d; - struct bcm43xx_private *bcm = led->bcm; - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - if (led->blink_interval) { - bcm43xx_led_changestate(led); - mod_timer(&led->blink_timer, jiffies + led->blink_interval); - } - bcm43xx_unlock_mmio(bcm, flags); -} - -static void bcm43xx_led_blink_start(struct bcm43xx_led *led, - unsigned long interval) -{ - if (led->blink_interval) - return; - led->blink_interval = interval; - bcm43xx_led_changestate(led); - led->blink_timer.expires = jiffies + interval; - add_timer(&led->blink_timer); -} - -static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync) -{ - struct bcm43xx_private *bcm = led->bcm; - const int index = bcm43xx_led_index(led); - u16 ledctl; - - if (!led->blink_interval) - return; - if (unlikely(sync)) - del_timer_sync(&led->blink_timer); - else - del_timer(&led->blink_timer); - led->blink_interval = 0; - - /* Make sure the LED is turned off. */ - assert(index >= 0 && index < BCM43xx_NR_LEDS); - ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - if (led->activelow) - ledctl |= (1 << index); - else - ledctl &= ~(1 << index); - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); -} - -static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm, - struct bcm43xx_led *led, - int led_index) -{ - /* This function is called, if the behaviour (and activelow) - * information for a LED is missing in the SPROM. - * We hardcode the behaviour values for various devices here. - * Note that the BCM43xx_LED_TEST_XXX behaviour values can - * be used to figure out which led is mapped to which index. - */ - - switch (led_index) { - case 0: - led->behaviour = BCM43xx_LED_ACTIVITY; - if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ) - led->behaviour = BCM43xx_LED_RADIO_ALL; - break; - case 1: - led->behaviour = BCM43xx_LED_RADIO_B; - if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK) - led->behaviour = BCM43xx_LED_ASSOC; - break; - case 2: - led->behaviour = BCM43xx_LED_RADIO_A; - break; - case 3: - led->behaviour = BCM43xx_LED_OFF; - break; - default: - assert(0); - } -} - -int bcm43xx_leds_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_led *led; - u8 sprom[4]; - int i; - - sprom[0] = bcm->sprom.wl0gpio0; - sprom[1] = bcm->sprom.wl0gpio1; - sprom[2] = bcm->sprom.wl0gpio2; - sprom[3] = bcm->sprom.wl0gpio3; - - for (i = 0; i < BCM43xx_NR_LEDS; i++) { - led = &(bcm->leds[i]); - led->bcm = bcm; - setup_timer(&led->blink_timer, - bcm43xx_led_blink, - (unsigned long)led); - - if (sprom[i] == 0xFF) { - bcm43xx_led_init_hardcoded(bcm, led, i); - } else { - led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR; - led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW); - } - } - - return 0; -} - -void bcm43xx_leds_exit(struct bcm43xx_private *bcm) -{ - struct bcm43xx_led *led; - int i; - - for (i = 0; i < BCM43xx_NR_LEDS; i++) { - led = &(bcm->leds[i]); - bcm43xx_led_blink_stop(led, 1); - } - bcm43xx_leds_switch_all(bcm, 0); -} - -void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) -{ - struct bcm43xx_led *led; - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES; - int i, turn_on; - unsigned long interval = 0; - u16 ledctl; - - ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - for (i = 0; i < BCM43xx_NR_LEDS; i++) { - led = &(bcm->leds[i]); - - turn_on = 0; - switch (led->behaviour) { - case BCM43xx_LED_INACTIVE: - continue; - case BCM43xx_LED_OFF: - break; - case BCM43xx_LED_ON: - turn_on = 1; - break; - case BCM43xx_LED_ACTIVITY: - turn_on = activity; - break; - case BCM43xx_LED_RADIO_ALL: - turn_on = radio->enabled; - break; - case BCM43xx_LED_RADIO_A: - turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); - break; - case BCM43xx_LED_RADIO_B: - turn_on = (radio->enabled && - (phy->type == BCM43xx_PHYTYPE_B || - phy->type == BCM43xx_PHYTYPE_G)); - break; - case BCM43xx_LED_MODE_BG: - if (phy->type == BCM43xx_PHYTYPE_G && - 1/*FIXME: using G rates.*/) - turn_on = 1; - break; - case BCM43xx_LED_TRANSFER: - if (transferring) - bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM); - else - bcm43xx_led_blink_stop(led, 0); - continue; - case BCM43xx_LED_APTRANSFER: - if (bcm->ieee->iw_mode == IW_MODE_MASTER) { - if (transferring) { - interval = BCM43xx_LEDBLINK_FAST; - turn_on = 1; - } - } else { - turn_on = 1; - if (0/*TODO: not assoc*/) - interval = BCM43xx_LEDBLINK_SLOW; - else if (transferring) - interval = BCM43xx_LEDBLINK_FAST; - else - turn_on = 0; - } - if (turn_on) - bcm43xx_led_blink_start(led, interval); - else - bcm43xx_led_blink_stop(led, 0); - continue; - case BCM43xx_LED_WEIRD: - //TODO - break; - case BCM43xx_LED_ASSOC: - if (bcm->softmac->associated) - turn_on = 1; - break; -#ifdef CONFIG_BCM43XX_DEBUG - case BCM43xx_LED_TEST_BLINKSLOW: - bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_SLOW); - continue; - case BCM43xx_LED_TEST_BLINKMEDIUM: - bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM); - continue; - case BCM43xx_LED_TEST_BLINKFAST: - bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_FAST); - continue; -#endif /* CONFIG_BCM43XX_DEBUG */ - default: - assert(0); - }; - - if (led->activelow) - turn_on = !turn_on; - if (turn_on) - ledctl |= (1 << i); - else - ledctl &= ~(1 << i); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); -} - -void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on) -{ - struct bcm43xx_led *led; - u16 ledctl; - int i; - int bit_on; - - ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - for (i = 0; i < BCM43xx_NR_LEDS; i++) { - led = &(bcm->leds[i]); - if (led->behaviour == BCM43xx_LED_INACTIVE) - continue; - if (on) - bit_on = led->activelow ? 0 : 1; - else - bit_on = led->activelow ? 1 : 0; - if (bit_on) - ledctl |= (1 << i); - else - ledctl &= ~(1 << i); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h deleted file mode 100644 index d3716cf3a..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BCM43xx_LEDS_H_ -#define BCM43xx_LEDS_H_ - -#include -#include - - -struct bcm43xx_led { - u8 behaviour:7; - u8 activelow:1; - - struct bcm43xx_private *bcm; - struct timer_list blink_timer; - unsigned long blink_interval; -}; -#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds)) - -/* Delay between state changes when blinking in jiffies */ -#define BCM43xx_LEDBLINK_SLOW (HZ / 1) -#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4) -#define BCM43xx_LEDBLINK_FAST (HZ / 8) - -#define BCM43xx_LED_XFER_THRES (HZ / 100) - -#define BCM43xx_LED_BEHAVIOUR 0x7F -#define BCM43xx_LED_ACTIVELOW 0x80 -enum { /* LED behaviour values */ - BCM43xx_LED_OFF, - BCM43xx_LED_ON, - BCM43xx_LED_ACTIVITY, - BCM43xx_LED_RADIO_ALL, - BCM43xx_LED_RADIO_A, - BCM43xx_LED_RADIO_B, - BCM43xx_LED_MODE_BG, - BCM43xx_LED_TRANSFER, - BCM43xx_LED_APTRANSFER, - BCM43xx_LED_WEIRD,//FIXME - BCM43xx_LED_ASSOC, - BCM43xx_LED_INACTIVE, - - /* Behaviour values for testing. - * With these values it is easier to figure out - * the real behaviour of leds, in case the SPROM - * is missing information. - */ - BCM43xx_LED_TEST_BLINKSLOW, - BCM43xx_LED_TEST_BLINKMEDIUM, - BCM43xx_LED_TEST_BLINKFAST, -}; - -int bcm43xx_leds_init(struct bcm43xx_private *bcm); -void bcm43xx_leds_exit(struct bcm43xx_private *bcm); -void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity); -void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on); - -#endif /* BCM43xx_LEDS_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c deleted file mode 100644 index 513fc759f..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ /dev/null @@ -1,3984 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bcm43xx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_debugfs.h" -#include "bcm43xx_radio.h" -#include "bcm43xx_phy.h" -#include "bcm43xx_dma.h" -#include "bcm43xx_pio.h" -#include "bcm43xx_power.h" -#include "bcm43xx_wx.h" -#include "bcm43xx_ethtool.h" -#include "bcm43xx_xmit.h" -#include "bcm43xx_sysfs.h" - - -MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver"); -MODULE_AUTHOR("Martin Langer"); -MODULE_AUTHOR("Stefano Brivio"); -MODULE_AUTHOR("Michael Buesch"); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_BCM947XX -extern char *nvram_get(char *name); -#endif - -#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO) -static int modparam_pio; -module_param_named(pio, modparam_pio, int, 0444); -MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode"); -#elif defined(CONFIG_BCM43XX_DMA) -# define modparam_pio 0 -#elif defined(CONFIG_BCM43XX_PIO) -# define modparam_pio 1 -#endif - -static int modparam_bad_frames_preempt; -module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); -MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames Preemption"); - -static int modparam_short_retry = BCM43xx_DEFAULT_SHORT_RETRY_LIMIT; -module_param_named(short_retry, modparam_short_retry, int, 0444); -MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)"); - -static int modparam_long_retry = BCM43xx_DEFAULT_LONG_RETRY_LIMIT; -module_param_named(long_retry, modparam_long_retry, int, 0444); -MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)"); - -static int modparam_locale = -1; -module_param_named(locale, modparam_locale, int, 0444); -MODULE_PARM_DESC(country, "Select LocaleCode 0-11 (For travelers)"); - -static int modparam_noleds; -module_param_named(noleds, modparam_noleds, int, 0444); -MODULE_PARM_DESC(noleds, "Turn off all LED activity"); - -#ifdef CONFIG_BCM43XX_DEBUG -static char modparam_fwpostfix[64]; -module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444); -MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging."); -#else -# define modparam_fwpostfix "" -#endif /* CONFIG_BCM43XX_DEBUG*/ - - -/* If you want to debug with just a single device, enable this, - * where the string is the pci device ID (as given by the kernel's - * pci_name function) of the device to be used. - */ -//#define DEBUG_SINGLE_DEVICE_ONLY "0001:11:00.0" - -/* If you want to enable printing of each MMIO access, enable this. */ -//#define DEBUG_ENABLE_MMIO_PRINT - -/* If you want to enable printing of MMIO access within - * ucode/pcm upload, initvals write, enable this. - */ -//#define DEBUG_ENABLE_UCODE_MMIO_PRINT - -/* If you want to enable printing of PCI Config Space access, enable this */ -//#define DEBUG_ENABLE_PCILOG - - -/* Detailed list maintained at: - * http://openfacts.berlios.de/index-en.phtml?title=Bcm43xxDevices - */ - static struct pci_device_id bcm43xx_pci_tbl[] = { - /* Broadcom 4303 802.11b */ - { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4307 802.11b */ - { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4318 802.11b/g */ - { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4306 802.11b/g */ - { PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4306 802.11a */ -// { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4309 802.11a/b/g */ - { PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 43XG 802.11b/g */ - { PCI_VENDOR_ID_BROADCOM, 0x4325, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -#ifdef CONFIG_BCM947XX - /* SB bus on BCM947xx */ - { PCI_VENDOR_ID_BROADCOM, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -#endif - { 0 }, -}; -MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl); - -static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val) -{ - u32 status; - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP)) - val = swab32(val); - - bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset); - mmiowb(); - bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val); -} - -static inline -void bcm43xx_shm_control_word(struct bcm43xx_private *bcm, - u16 routing, u16 offset) -{ - u32 control; - - /* "offset" is the WORD offset. */ - - control = routing; - control <<= 16; - control |= offset; - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_CONTROL, control); -} - -u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm, - u16 routing, u16 offset) -{ - u32 ret; - - if (routing == BCM43xx_SHM_SHARED) { - if (offset & 0x0003) { - /* Unaligned access */ - bcm43xx_shm_control_word(bcm, routing, offset >> 2); - ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED); - ret <<= 16; - bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1); - ret |= bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA); - - return ret; - } - offset >>= 2; - } - bcm43xx_shm_control_word(bcm, routing, offset); - ret = bcm43xx_read32(bcm, BCM43xx_MMIO_SHM_DATA); - - return ret; -} - -u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm, - u16 routing, u16 offset) -{ - u16 ret; - - if (routing == BCM43xx_SHM_SHARED) { - if (offset & 0x0003) { - /* Unaligned access */ - bcm43xx_shm_control_word(bcm, routing, offset >> 2); - ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED); - - return ret; - } - offset >>= 2; - } - bcm43xx_shm_control_word(bcm, routing, offset); - ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA); - - return ret; -} - -void bcm43xx_shm_write32(struct bcm43xx_private *bcm, - u16 routing, u16 offset, - u32 value) -{ - if (routing == BCM43xx_SHM_SHARED) { - if (offset & 0x0003) { - /* Unaligned access */ - bcm43xx_shm_control_word(bcm, routing, offset >> 2); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED, - (value >> 16) & 0xffff); - mmiowb(); - bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, - value & 0xffff); - return; - } - offset >>= 2; - } - bcm43xx_shm_control_word(bcm, routing, offset); - mmiowb(); - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value); -} - -void bcm43xx_shm_write16(struct bcm43xx_private *bcm, - u16 routing, u16 offset, - u16 value) -{ - if (routing == BCM43xx_SHM_SHARED) { - if (offset & 0x0003) { - /* Unaligned access */ - bcm43xx_shm_control_word(bcm, routing, offset >> 2); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED, - value); - return; - } - offset >>= 2; - } - bcm43xx_shm_control_word(bcm, routing, offset); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value); -} - -void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf) -{ - /* We need to be careful. As we read the TSF from multiple - * registers, we should take care of register overflows. - * In theory, the whole tsf read process should be atomic. - * We try to be atomic here, by restaring the read process, - * if any of the high registers changed (overflew). - */ - if (bcm->current_core->rev >= 3) { - u32 low, high, high2; - - do { - high = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH); - low = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW); - high2 = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH); - } while (unlikely(high != high2)); - - *tsf = high; - *tsf <<= 32; - *tsf |= low; - } else { - u64 tmp; - u16 v0, v1, v2, v3; - u16 test1, test2, test3; - - do { - v3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3); - v2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2); - v1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1); - v0 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_0); - - test3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3); - test2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2); - test1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1); - } while (v3 != test3 || v2 != test2 || v1 != test1); - - *tsf = v3; - *tsf <<= 48; - tmp = v2; - tmp <<= 32; - *tsf |= tmp; - tmp = v1; - tmp <<= 16; - *tsf |= tmp; - *tsf |= v0; - } -} - -void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf) -{ - u32 status; - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - status |= BCM43xx_SBF_TIME_UPDATE; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - mmiowb(); - - /* Be careful with the in-progress timer. - * First zero out the low register, so we have a full - * register-overflow duration to complete the operation. - */ - if (bcm->current_core->rev >= 3) { - u32 lo = (tsf & 0x00000000FFFFFFFFULL); - u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32; - - bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0); - mmiowb(); - bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi); - mmiowb(); - bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo); - } else { - u16 v0 = (tsf & 0x000000000000FFFFULL); - u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16; - u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32; - u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48; - - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0); - } - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - status &= ~BCM43xx_SBF_TIME_UPDATE; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); -} - -static -void bcm43xx_macfilter_set(struct bcm43xx_private *bcm, - u16 offset, - const u8 *mac) -{ - u16 data; - - offset |= 0x0020; - bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_CONTROL, offset); - - data = mac[0]; - data |= mac[1] << 8; - bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data); - data = mac[2]; - data |= mac[3] << 8; - bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data); - data = mac[4]; - data |= mac[5] << 8; - bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data); -} - -static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm, - u16 offset) -{ - const u8 zero_addr[ETH_ALEN] = { 0 }; - - bcm43xx_macfilter_set(bcm, offset, zero_addr); -} - -static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm) -{ - const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr); - const u8 *bssid = (const u8 *)(bcm->ieee->bssid); - u8 mac_bssid[ETH_ALEN * 2]; - int i; - - memcpy(mac_bssid, mac, ETH_ALEN); - memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN); - - /* Write our MAC address and BSSID to template ram */ - for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) - bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i))); - for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) - bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i))); - for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) - bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i))); -} - -//FIXME: Well, we should probably call them from somewhere. -#if 0 -static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time) -{ - /* slot_time is in usec. */ - if (bcm43xx_current_phy(bcm)->type != BCM43xx_PHYTYPE_G) - return; - bcm43xx_write16(bcm, 0x684, 510 + slot_time); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0010, slot_time); -} - -static void bcm43xx_short_slot_timing_enable(struct bcm43xx_private *bcm) -{ - bcm43xx_set_slot_time(bcm, 9); -} - -static void bcm43xx_short_slot_timing_disable(struct bcm43xx_private *bcm) -{ - bcm43xx_set_slot_time(bcm, 20); -} -#endif - -/* FIXME: To get the MAC-filter working, we need to implement the - * following functions (and rename them :) - */ -#if 0 -static void bcm43xx_disassociate(struct bcm43xx_private *bcm) -{ - bcm43xx_mac_suspend(bcm); - bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); - - bcm43xx_ram_write(bcm, 0x0026, 0x0000); - bcm43xx_ram_write(bcm, 0x0028, 0x0000); - bcm43xx_ram_write(bcm, 0x007E, 0x0000); - bcm43xx_ram_write(bcm, 0x0080, 0x0000); - bcm43xx_ram_write(bcm, 0x047E, 0x0000); - bcm43xx_ram_write(bcm, 0x0480, 0x0000); - - if (bcm->current_core->rev < 3) { - bcm43xx_write16(bcm, 0x0610, 0x8000); - bcm43xx_write16(bcm, 0x060E, 0x0000); - } else - bcm43xx_write32(bcm, 0x0188, 0x80000000); - - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff); - - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G && - ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate)) - bcm43xx_short_slot_timing_enable(bcm); - - bcm43xx_mac_enable(bcm); -} - -static void bcm43xx_associate(struct bcm43xx_private *bcm, - const u8 *mac) -{ - memcpy(bcm->ieee->bssid, mac, ETH_ALEN); - - bcm43xx_mac_suspend(bcm); - bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac); - bcm43xx_write_mac_bssid_templates(bcm); - bcm43xx_mac_enable(bcm); -} -#endif - -/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. - * Returns the _previously_ enabled IRQ mask. - */ -static inline u32 bcm43xx_interrupt_enable(struct bcm43xx_private *bcm, u32 mask) -{ - u32 old_mask; - - old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask | mask); - - return old_mask; -} - -/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable. - * Returns the _previously_ enabled IRQ mask. - */ -static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mask) -{ - u32 old_mask; - - old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask & ~mask); - - return old_mask; -} - -/* Make sure we don't receive more data from the device. */ -static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate) -{ - u32 old; - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { - bcm43xx_unlock_mmio(bcm, flags); - return -EBUSY; - } - old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - tasklet_disable(&bcm->isr_tasklet); - bcm43xx_unlock_mmio(bcm, flags); - if (oldstate) - *oldstate = old; - - return 0; -} - -static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u32 radio_id; - u16 manufact; - u16 version; - u8 revision; - s8 i; - - if (bcm->chip_id == 0x4317) { - if (bcm->chip_rev == 0x00) - radio_id = 0x3205017F; - else if (bcm->chip_rev == 0x01) - radio_id = 0x4205017F; - else - radio_id = 0x5205017F; - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID); - radio_id = bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_HIGH); - radio_id <<= 16; - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID); - radio_id |= bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW); - } - - manufact = (radio_id & 0x00000FFF); - version = (radio_id & 0x0FFFF000) >> 12; - revision = (radio_id & 0xF0000000) >> 28; - - dprintk(KERN_INFO PFX "Detected Radio: ID: %x (Manuf: %x Ver: %x Rev: %x)\n", - radio_id, manufact, version, revision); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - if ((version != 0x2060) || (revision != 1) || (manufact != 0x17f)) - goto err_unsupported_radio; - break; - case BCM43xx_PHYTYPE_B: - if ((version & 0xFFF0) != 0x2050) - goto err_unsupported_radio; - break; - case BCM43xx_PHYTYPE_G: - if (version != 0x2050) - goto err_unsupported_radio; - break; - } - - radio->manufact = manufact; - radio->version = version; - radio->revision = revision; - - /* Set default attenuation values. */ - radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm); - radio->radio_atten = bcm43xx_default_radio_attenuation(bcm); - radio->txctl1 = bcm43xx_default_txctl1(bcm); - radio->txctl2 = 0xFFFF; - if (phy->type == BCM43xx_PHYTYPE_A) - radio->txpower_desired = bcm->sprom.maxpower_aphy; - else - radio->txpower_desired = bcm->sprom.maxpower_bgphy; - - /* Initialize the in-memory nrssi Lookup Table. */ - for (i = 0; i < 64; i++) - radio->nrssi_lt[i] = i; - - return 0; - -err_unsupported_radio: - printk(KERN_ERR PFX "Unsupported Radio connected to the PHY!\n"); - return -ENODEV; -} - -static const char * bcm43xx_locale_iso(u8 locale) -{ - /* ISO 3166-1 country codes. - * Note that there aren't ISO 3166-1 codes for - * all or locales. (Not all locales are countries) - */ - switch (locale) { - case BCM43xx_LOCALE_WORLD: - case BCM43xx_LOCALE_ALL: - return "XX"; - case BCM43xx_LOCALE_THAILAND: - return "TH"; - case BCM43xx_LOCALE_ISRAEL: - return "IL"; - case BCM43xx_LOCALE_JORDAN: - return "JO"; - case BCM43xx_LOCALE_CHINA: - return "CN"; - case BCM43xx_LOCALE_JAPAN: - case BCM43xx_LOCALE_JAPAN_HIGH: - return "JP"; - case BCM43xx_LOCALE_USA_CANADA_ANZ: - case BCM43xx_LOCALE_USA_LOW: - return "US"; - case BCM43xx_LOCALE_EUROPE: - return "EU"; - case BCM43xx_LOCALE_NONE: - return " "; - } - assert(0); - return " "; -} - -static const char * bcm43xx_locale_string(u8 locale) -{ - switch (locale) { - case BCM43xx_LOCALE_WORLD: - return "World"; - case BCM43xx_LOCALE_THAILAND: - return "Thailand"; - case BCM43xx_LOCALE_ISRAEL: - return "Israel"; - case BCM43xx_LOCALE_JORDAN: - return "Jordan"; - case BCM43xx_LOCALE_CHINA: - return "China"; - case BCM43xx_LOCALE_JAPAN: - return "Japan"; - case BCM43xx_LOCALE_USA_CANADA_ANZ: - return "USA/Canada/ANZ"; - case BCM43xx_LOCALE_EUROPE: - return "Europe"; - case BCM43xx_LOCALE_USA_LOW: - return "USAlow"; - case BCM43xx_LOCALE_JAPAN_HIGH: - return "JapanHigh"; - case BCM43xx_LOCALE_ALL: - return "All"; - case BCM43xx_LOCALE_NONE: - return "None"; - } - assert(0); - return ""; -} - -static inline u8 bcm43xx_crc8(u8 crc, u8 data) -{ - static const u8 t[] = { - 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, - 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, - 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, - 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, - 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, - 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, - 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, - 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, - 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, - 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, - 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, - 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, - 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, - 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, - 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, - 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, - 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, - 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, - 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, - 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, - 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, - 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, - 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, - 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, - 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, - 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, - 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, - 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, - 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, - 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, - 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, - 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F, - }; - return t[crc ^ data]; -} - -static u8 bcm43xx_sprom_crc(const u16 *sprom) -{ - int word; - u8 crc = 0xFF; - - for (word = 0; word < BCM43xx_SPROM_SIZE - 1; word++) { - crc = bcm43xx_crc8(crc, sprom[word] & 0x00FF); - crc = bcm43xx_crc8(crc, (sprom[word] & 0xFF00) >> 8); - } - crc = bcm43xx_crc8(crc, sprom[BCM43xx_SPROM_VERSION] & 0x00FF); - crc ^= 0xFF; - - return crc; -} - -int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom) -{ - int i; - u8 crc, expected_crc; - - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) - sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2)); - /* CRC-8 check. */ - crc = bcm43xx_sprom_crc(sprom); - expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; - if (crc != expected_crc) { - printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum " - "(0x%02X, expected: 0x%02X)\n", - crc, expected_crc); - return -EINVAL; - } - - return 0; -} - -int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) -{ - int i, err; - u8 crc, expected_crc; - u32 spromctl; - - /* CRC-8 validation of the input data. */ - crc = bcm43xx_sprom_crc(sprom); - expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; - if (crc != expected_crc) { - printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n"); - return -EINVAL; - } - - printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl); - if (err) - goto err_ctlreg; - spromctl |= 0x10; /* SPROM WRITE enable. */ - bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); - if (err) - goto err_ctlreg; - /* We must burn lots of CPU cycles here, but that does not - * really matter as one does not write the SPROM every other minute... - */ - printk(KERN_INFO PFX "[ 0%%"); - mdelay(500); - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - if (i == 16) - printk("25%%"); - else if (i == 32) - printk("50%%"); - else if (i == 48) - printk("75%%"); - else if (i % 2) - printk("."); - bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]); - mmiowb(); - mdelay(20); - } - spromctl &= ~0x10; /* SPROM WRITE enable. */ - bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); - if (err) - goto err_ctlreg; - mdelay(500); - printk("100%% ]\n"); - printk(KERN_INFO PFX "SPROM written.\n"); - bcm43xx_controller_restart(bcm, "SPROM update"); - - return 0; -err_ctlreg: - printk(KERN_ERR PFX "Could not access SPROM control register.\n"); - return -ENODEV; -} - -static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm) -{ - u16 value; - u16 *sprom; -#ifdef CONFIG_BCM947XX - char *c; -#endif - - sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16), - GFP_KERNEL); - if (!sprom) { - printk(KERN_ERR PFX "sprom_extract OOM\n"); - return -ENOMEM; - } -#ifdef CONFIG_BCM947XX - sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2")); - sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags")); - - if ((c = nvram_get("il0macaddr")) != NULL) - e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR])); - - if ((c = nvram_get("et1macaddr")) != NULL) - e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR])); - - sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0")); - sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1")); - sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2")); - - sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0")); - sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1")); - sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2")); - - sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev")); -#else - bcm43xx_sprom_read(bcm, sprom); -#endif - - /* boardflags2 */ - value = sprom[BCM43xx_SPROM_BOARDFLAGS2]; - bcm->sprom.boardflags2 = value; - - /* il0macaddr */ - value = sprom[BCM43xx_SPROM_IL0MACADDR + 0]; - *(((u16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_IL0MACADDR + 1]; - *(((u16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_IL0MACADDR + 2]; - *(((u16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value); - - /* et0macaddr */ - value = sprom[BCM43xx_SPROM_ET0MACADDR + 0]; - *(((u16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_ET0MACADDR + 1]; - *(((u16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_ET0MACADDR + 2]; - *(((u16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value); - - /* et1macaddr */ - value = sprom[BCM43xx_SPROM_ET1MACADDR + 0]; - *(((u16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_ET1MACADDR + 1]; - *(((u16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_ET1MACADDR + 2]; - *(((u16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value); - - /* ethernet phy settings */ - value = sprom[BCM43xx_SPROM_ETHPHY]; - bcm->sprom.et0phyaddr = (value & 0x001F); - bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5; - bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14; - bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15; - - /* boardrev, antennas, locale */ - value = sprom[BCM43xx_SPROM_BOARDREV]; - bcm->sprom.boardrev = (value & 0x00FF); - bcm->sprom.locale = (value & 0x0F00) >> 8; - bcm->sprom.antennas_aphy = (value & 0x3000) >> 12; - bcm->sprom.antennas_bgphy = (value & 0xC000) >> 14; - if (modparam_locale != -1) { - if (modparam_locale >= 0 && modparam_locale <= 11) { - bcm->sprom.locale = modparam_locale; - printk(KERN_WARNING PFX "Operating with modified " - "LocaleCode %u (%s)\n", - bcm->sprom.locale, - bcm43xx_locale_string(bcm->sprom.locale)); - } else { - printk(KERN_WARNING PFX "Module parameter \"locale\" " - "invalid value. (0 - 11)\n"); - } - } - - /* pa0b* */ - value = sprom[BCM43xx_SPROM_PA0B0]; - bcm->sprom.pa0b0 = value; - value = sprom[BCM43xx_SPROM_PA0B1]; - bcm->sprom.pa0b1 = value; - value = sprom[BCM43xx_SPROM_PA0B2]; - bcm->sprom.pa0b2 = value; - - /* wl0gpio* */ - value = sprom[BCM43xx_SPROM_WL0GPIO0]; - if (value == 0x0000) - value = 0xFFFF; - bcm->sprom.wl0gpio0 = value & 0x00FF; - bcm->sprom.wl0gpio1 = (value & 0xFF00) >> 8; - value = sprom[BCM43xx_SPROM_WL0GPIO2]; - if (value == 0x0000) - value = 0xFFFF; - bcm->sprom.wl0gpio2 = value & 0x00FF; - bcm->sprom.wl0gpio3 = (value & 0xFF00) >> 8; - - /* maxpower */ - value = sprom[BCM43xx_SPROM_MAXPWR]; - bcm->sprom.maxpower_aphy = (value & 0xFF00) >> 8; - bcm->sprom.maxpower_bgphy = value & 0x00FF; - - /* pa1b* */ - value = sprom[BCM43xx_SPROM_PA1B0]; - bcm->sprom.pa1b0 = value; - value = sprom[BCM43xx_SPROM_PA1B1]; - bcm->sprom.pa1b1 = value; - value = sprom[BCM43xx_SPROM_PA1B2]; - bcm->sprom.pa1b2 = value; - - /* idle tssi target */ - value = sprom[BCM43xx_SPROM_IDL_TSSI_TGT]; - bcm->sprom.idle_tssi_tgt_aphy = value & 0x00FF; - bcm->sprom.idle_tssi_tgt_bgphy = (value & 0xFF00) >> 8; - - /* boardflags */ - value = sprom[BCM43xx_SPROM_BOARDFLAGS]; - if (value == 0xFFFF) - value = 0x0000; - bcm->sprom.boardflags = value; - /* boardflags workarounds */ - if (bcm->board_vendor == PCI_VENDOR_ID_DELL && - bcm->chip_id == 0x4301 && - bcm->board_revision == 0x74) - bcm->sprom.boardflags |= BCM43xx_BFL_BTCOEXIST; - if (bcm->board_vendor == PCI_VENDOR_ID_APPLE && - bcm->board_type == 0x4E && - bcm->board_revision > 0x40) - bcm->sprom.boardflags |= BCM43xx_BFL_PACTRL; - - /* antenna gain */ - value = sprom[BCM43xx_SPROM_ANTENNA_GAIN]; - if (value == 0x0000 || value == 0xFFFF) - value = 0x0202; - /* convert values to Q5.2 */ - bcm->sprom.antennagain_aphy = ((value & 0xFF00) >> 8) * 4; - bcm->sprom.antennagain_bgphy = (value & 0x00FF) * 4; - - kfree(sprom); - - return 0; -} - -static int bcm43xx_geo_init(struct bcm43xx_private *bcm) -{ - struct ieee80211_geo *geo; - struct ieee80211_channel *chan; - int have_a = 0, have_bg = 0; - int i; - u8 channel; - struct bcm43xx_phyinfo *phy; - const char *iso_country; - - geo = kzalloc(sizeof(*geo), GFP_KERNEL); - if (!geo) - return -ENOMEM; - - for (i = 0; i < bcm->nr_80211_available; i++) { - phy = &(bcm->core_80211_ext[i].phy); - switch (phy->type) { - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - have_bg = 1; - break; - case BCM43xx_PHYTYPE_A: - have_a = 1; - break; - default: - assert(0); - } - } - iso_country = bcm43xx_locale_iso(bcm->sprom.locale); - - if (have_a) { - for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL; - channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) { - chan = &geo->a[i++]; - chan->freq = bcm43xx_channel_to_freq_a(channel); - chan->channel = channel; - } - geo->a_channels = i; - } - if (have_bg) { - for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL; - channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) { - chan = &geo->bg[i++]; - chan->freq = bcm43xx_channel_to_freq_bg(channel); - chan->channel = channel; - } - geo->bg_channels = i; - } - memcpy(geo->name, iso_country, 2); - if (0 /*TODO: Outdoor use only */) - geo->name[2] = 'O'; - else if (0 /*TODO: Indoor use only */) - geo->name[2] = 'I'; - else - geo->name[2] = ' '; - geo->name[3] = '\0'; - - ieee80211_set_geo(bcm->ieee, geo); - kfree(geo); - - return 0; -} - -/* DummyTransmission function, as documented on - * http://bcm-specs.sipsolutions.net/DummyTransmission - */ -void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - unsigned int i, max_loop; - u16 value = 0; - u32 buffer[5] = { - 0x00000000, - 0x0000D400, - 0x00000000, - 0x00000001, - 0x00000000, - }; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - max_loop = 0x1E; - buffer[0] = 0xCC010200; - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - max_loop = 0xFA; - buffer[0] = 0x6E840B00; - break; - default: - assert(0); - return; - } - - for (i = 0; i < 5; i++) - bcm43xx_ram_write(bcm, i * 4, buffer[i]); - - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ - - bcm43xx_write16(bcm, 0x0568, 0x0000); - bcm43xx_write16(bcm, 0x07C0, 0x0000); - bcm43xx_write16(bcm, 0x050C, ((phy->type == BCM43xx_PHYTYPE_A) ? 1 : 0)); - bcm43xx_write16(bcm, 0x0508, 0x0000); - bcm43xx_write16(bcm, 0x050A, 0x0000); - bcm43xx_write16(bcm, 0x054C, 0x0000); - bcm43xx_write16(bcm, 0x056A, 0x0014); - bcm43xx_write16(bcm, 0x0568, 0x0826); - bcm43xx_write16(bcm, 0x0500, 0x0000); - bcm43xx_write16(bcm, 0x0502, 0x0030); - - if (radio->version == 0x2050 && radio->revision <= 0x5) - bcm43xx_radio_write16(bcm, 0x0051, 0x0017); - for (i = 0x00; i < max_loop; i++) { - value = bcm43xx_read16(bcm, 0x050E); - if (value & 0x0080) - break; - udelay(10); - } - for (i = 0x00; i < 0x0A; i++) { - value = bcm43xx_read16(bcm, 0x050E); - if (value & 0x0400) - break; - udelay(10); - } - for (i = 0x00; i < 0x0A; i++) { - value = bcm43xx_read16(bcm, 0x0690); - if (!(value & 0x0100)) - break; - udelay(10); - } - if (radio->version == 0x2050 && radio->revision <= 0x5) - bcm43xx_radio_write16(bcm, 0x0051, 0x0037); -} - -static void key_write(struct bcm43xx_private *bcm, - u8 index, u8 algorithm, const u16 *key) -{ - unsigned int i, basic_wep = 0; - u32 offset; - u16 value; - - /* Write associated key information */ - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x100 + (index * 2), - ((index << 4) | (algorithm & 0x0F))); - - /* The first 4 WEP keys need extra love */ - if (((algorithm == BCM43xx_SEC_ALGO_WEP) || - (algorithm == BCM43xx_SEC_ALGO_WEP104)) && (index < 4)) - basic_wep = 1; - - /* Write key payload, 8 little endian words */ - offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE); - for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) { - value = cpu_to_le16(key[i]); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, - offset + (i * 2), value); - - if (!basic_wep) - continue; - - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, - offset + (i * 2) + 4 * BCM43xx_SEC_KEYSIZE, - value); - } -} - -static void keymac_write(struct bcm43xx_private *bcm, - u8 index, const u32 *addr) -{ - /* for keys 0-3 there is no associated mac address */ - if (index < 4) - return; - - index -= 4; - if (bcm->current_core->rev >= 5) { - bcm43xx_shm_write32(bcm, - BCM43xx_SHM_HWMAC, - index * 2, - cpu_to_be32(*addr)); - bcm43xx_shm_write16(bcm, - BCM43xx_SHM_HWMAC, - (index * 2) + 1, - cpu_to_be16(*((u16 *)(addr + 1)))); - } else { - if (index < 8) { - TODO(); /* Put them in the macaddress filter */ - } else { - TODO(); - /* Put them BCM43xx_SHM_SHARED, stating index 0x0120. - Keep in mind to update the count of keymacs in 0x003E as well! */ - } - } -} - -static int bcm43xx_key_write(struct bcm43xx_private *bcm, - u8 index, u8 algorithm, - const u8 *_key, int key_len, - const u8 *mac_addr) -{ - u8 key[BCM43xx_SEC_KEYSIZE] = { 0 }; - - if (index >= ARRAY_SIZE(bcm->key)) - return -EINVAL; - if (key_len > ARRAY_SIZE(key)) - return -EINVAL; - if (algorithm < 1 || algorithm > 5) - return -EINVAL; - - memcpy(key, _key, key_len); - key_write(bcm, index, algorithm, (const u16 *)key); - keymac_write(bcm, index, (const u32 *)mac_addr); - - bcm->key[index].algorithm = algorithm; - - return 0; -} - -static void bcm43xx_clear_keys(struct bcm43xx_private *bcm) -{ - static const u32 zero_mac[2] = { 0 }; - unsigned int i,j, nr_keys = 54; - u16 offset; - - if (bcm->current_core->rev < 5) - nr_keys = 16; - assert(nr_keys <= ARRAY_SIZE(bcm->key)); - - for (i = 0; i < nr_keys; i++) { - bcm->key[i].enabled = 0; - /* returns for i < 4 immediately */ - keymac_write(bcm, i, zero_mac); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, - 0x100 + (i * 2), 0x0000); - for (j = 0; j < 8; j++) { - offset = bcm->security_offset + (j * 4) + (i * BCM43xx_SEC_KEYSIZE); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, - offset, 0x0000); - } - } - dprintk(KERN_INFO PFX "Keys cleared\n"); -} - -/* Lowlevel core-switch function. This is only to be used in - * bcm43xx_switch_core() and bcm43xx_probe_cores() - */ -static int _switch_core(struct bcm43xx_private *bcm, int core) -{ - int err; - int attempts = 0; - u32 current_core; - - assert(core >= 0); - while (1) { - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE, - (core * 0x1000) + 0x18000000); - if (unlikely(err)) - goto error; - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE, - ¤t_core); - if (unlikely(err)) - goto error; - current_core = (current_core - 0x18000000) / 0x1000; - if (current_core == core) - break; - - if (unlikely(attempts++ > BCM43xx_SWITCH_CORE_MAX_RETRIES)) - goto error; - udelay(10); - } -#ifdef CONFIG_BCM947XX - if (bcm->pci_dev->bus->number == 0) - bcm->current_core_offset = 0x1000 * core; - else - bcm->current_core_offset = 0; -#endif - - return 0; -error: - printk(KERN_ERR PFX "Failed to switch to core %d\n", core); - return -ENODEV; -} - -int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core) -{ - int err; - - if (unlikely(!new_core)) - return 0; - if (!new_core->available) - return -ENODEV; - if (bcm->current_core == new_core) - return 0; - err = _switch_core(bcm, new_core->index); - if (unlikely(err)) - goto out; - - bcm->current_core = new_core; - bcm->current_80211_core_idx = -1; - if (new_core->id == BCM43xx_COREID_80211) - bcm->current_80211_core_idx = (int)(new_core - &(bcm->core_80211[0])); - -out: - return err; -} - -static int bcm43xx_core_enabled(struct bcm43xx_private *bcm) -{ - u32 value; - - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - value &= BCM43xx_SBTMSTATELOW_CLOCK | BCM43xx_SBTMSTATELOW_RESET - | BCM43xx_SBTMSTATELOW_REJECT; - - return (value == BCM43xx_SBTMSTATELOW_CLOCK); -} - -/* disable current core */ -static int bcm43xx_core_disable(struct bcm43xx_private *bcm, u32 core_flags) -{ - u32 sbtmstatelow; - u32 sbtmstatehigh; - int i; - - /* fetch sbtmstatelow from core information registers */ - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - - /* core is already in reset */ - if (sbtmstatelow & BCM43xx_SBTMSTATELOW_RESET) - goto out; - - if (sbtmstatelow & BCM43xx_SBTMSTATELOW_CLOCK) { - sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | - BCM43xx_SBTMSTATELOW_REJECT; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - - for (i = 0; i < 1000; i++) { - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - if (sbtmstatelow & BCM43xx_SBTMSTATELOW_REJECT) { - i = -1; - break; - } - udelay(10); - } - if (i != -1) { - printk(KERN_ERR PFX "Error: core_disable() REJECT timeout!\n"); - return -EBUSY; - } - - for (i = 0; i < 1000; i++) { - sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (!(sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_BUSY)) { - i = -1; - break; - } - udelay(10); - } - if (i != -1) { - printk(KERN_ERR PFX "Error: core_disable() BUSY timeout!\n"); - return -EBUSY; - } - - sbtmstatelow = BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK | - BCM43xx_SBTMSTATELOW_REJECT | - BCM43xx_SBTMSTATELOW_RESET | - BCM43xx_SBTMSTATELOW_CLOCK | - core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(10); - } - - sbtmstatelow = BCM43xx_SBTMSTATELOW_RESET | - BCM43xx_SBTMSTATELOW_REJECT | - core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - -out: - bcm->current_core->enabled = 0; - - return 0; -} - -/* enable (reset) current core */ -static int bcm43xx_core_enable(struct bcm43xx_private *bcm, u32 core_flags) -{ - u32 sbtmstatelow; - u32 sbtmstatehigh; - u32 sbimstate; - int err; - - err = bcm43xx_core_disable(bcm, core_flags); - if (err) - goto out; - - sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | - BCM43xx_SBTMSTATELOW_RESET | - BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK | - core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - - sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_SERROR) { - sbtmstatehigh = 0x00000000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATEHIGH, sbtmstatehigh); - } - - sbimstate = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMSTATE); - if (sbimstate & (BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT)) { - sbimstate &= ~(BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT); - bcm43xx_write32(bcm, BCM43xx_CIR_SBIMSTATE, sbimstate); - } - - sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | - BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK | - core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - - sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - - bcm->current_core->enabled = 1; - assert(err == 0); -out: - return err; -} - -/* http://bcm-specs.sipsolutions.net/80211CoreReset */ -void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy) -{ - u32 flags = 0x00040000; - - if ((bcm43xx_core_enabled(bcm)) && - !bcm43xx_using_pio(bcm)) { -//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here? -#ifndef CONFIG_BCM947XX - /* reset all used DMA controllers. */ - bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE); - bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA2_BASE); - bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA3_BASE); - bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); - bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE); - if (bcm->current_core->rev < 5) - bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); -#endif - } - if (bcm->shutting_down) { - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); - } else { - if (connect_phy) - flags |= 0x20000000; - bcm43xx_phy_connect(bcm, connect_phy); - bcm43xx_core_enable(bcm, flags); - bcm43xx_write16(bcm, 0x03E6, 0x0000); - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - | BCM43xx_SBF_400); - } -} - -static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm) -{ - bcm43xx_radio_turn_off(bcm); - bcm43xx_write16(bcm, 0x03E6, 0x00F4); - bcm43xx_core_disable(bcm, 0); -} - -/* Mark the current 80211 core inactive. - * "active_80211_core" is the other 80211 core, which is used. - */ -static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm, - struct bcm43xx_coreinfo *active_80211_core) -{ - u32 sbtmstatelow; - struct bcm43xx_coreinfo *old_core; - int err = 0; - - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_radio_turn_off(bcm); - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - sbtmstatelow &= ~0x200a0000; - sbtmstatelow |= 0xa0000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - sbtmstatelow &= ~0xa0000; - sbtmstatelow |= 0x80000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G) { - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, active_80211_core); - if (err) - goto out; - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - sbtmstatelow &= ~0x20000000; - sbtmstatelow |= 0x20000000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - err = bcm43xx_switch_core(bcm, old_core); - } - -out: - return err; -} - -static void handle_irq_transmit_status(struct bcm43xx_private *bcm) -{ - u32 v0, v1; - u16 tmp; - struct bcm43xx_xmitstatus stat; - - while (1) { - v0 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0); - if (!v0) - break; - v1 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1); - - stat.cookie = (v0 >> 16) & 0x0000FFFF; - tmp = (u16)((v0 & 0xFFF0) | ((v0 & 0xF) >> 1)); - stat.flags = tmp & 0xFF; - stat.cnt1 = (tmp & 0x0F00) >> 8; - stat.cnt2 = (tmp & 0xF000) >> 12; - stat.seq = (u16)(v1 & 0xFFFF); - stat.unknown = (u16)((v1 >> 16) & 0xFF); - - bcm43xx_debugfs_log_txstat(bcm, &stat); - - if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE) - continue; - if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) { - //TODO: packet was not acked (was lost) - } - //TODO: There are more (unknown) flags to test. see bcm43xx_main.h - - if (bcm43xx_using_pio(bcm)) - bcm43xx_pio_handle_xmitstatus(bcm, &stat); - else - bcm43xx_dma_handle_xmitstatus(bcm, &stat); - } -} - -static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm) -{ - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x40A, 0x7F7F); - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) | (1 << 4)); - assert(bcm->noisecalc.core_at_start == bcm->current_core); - assert(bcm->noisecalc.channel_at_start == bcm43xx_current_radio(bcm)->channel); -} - -static void bcm43xx_calculate_link_quality(struct bcm43xx_private *bcm) -{ - /* Top half of Link Quality calculation. */ - - if (bcm->noisecalc.calculation_running) - return; - bcm->noisecalc.core_at_start = bcm->current_core; - bcm->noisecalc.channel_at_start = bcm43xx_current_radio(bcm)->channel; - bcm->noisecalc.calculation_running = 1; - bcm->noisecalc.nr_samples = 0; - - bcm43xx_generate_noise_sample(bcm); -} - -static void handle_irq_noise(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 tmp; - u8 noise[4]; - u8 i, j; - s32 average; - - /* Bottom half of Link Quality calculation. */ - - assert(bcm->noisecalc.calculation_running); - if (bcm->noisecalc.core_at_start != bcm->current_core || - bcm->noisecalc.channel_at_start != radio->channel) - goto drop_calculation; - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x408); - noise[0] = (tmp & 0x00FF); - noise[1] = (tmp & 0xFF00) >> 8; - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40A); - noise[2] = (tmp & 0x00FF); - noise[3] = (tmp & 0xFF00) >> 8; - if (noise[0] == 0x7F || noise[1] == 0x7F || - noise[2] == 0x7F || noise[3] == 0x7F) - goto generate_new; - - /* Get the noise samples. */ - assert(bcm->noisecalc.nr_samples <= 8); - i = bcm->noisecalc.nr_samples; - noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(radio->nrssi_lt) - 1); - noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(radio->nrssi_lt) - 1); - noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(radio->nrssi_lt) - 1); - noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(radio->nrssi_lt) - 1); - bcm->noisecalc.samples[i][0] = radio->nrssi_lt[noise[0]]; - bcm->noisecalc.samples[i][1] = radio->nrssi_lt[noise[1]]; - bcm->noisecalc.samples[i][2] = radio->nrssi_lt[noise[2]]; - bcm->noisecalc.samples[i][3] = radio->nrssi_lt[noise[3]]; - bcm->noisecalc.nr_samples++; - if (bcm->noisecalc.nr_samples == 8) { - /* Calculate the Link Quality by the noise samples. */ - average = 0; - for (i = 0; i < 8; i++) { - for (j = 0; j < 4; j++) - average += bcm->noisecalc.samples[i][j]; - } - average /= (8 * 4); - average *= 125; - average += 64; - average /= 128; - - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C); - tmp = (tmp / 128) & 0x1F; - if (tmp >= 8) - average += 2; - else - average -= 25; - if (tmp == 8) - average -= 72; - else - average -= 48; - -/* FIXME: This is wrong, but people want fancy stats. well... */ -bcm->stats.noise = average; - if (average > -65) - bcm->stats.link_quality = 0; - else if (average > -75) - bcm->stats.link_quality = 1; - else if (average > -85) - bcm->stats.link_quality = 2; - else - bcm->stats.link_quality = 3; -// dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average); -drop_calculation: - bcm->noisecalc.calculation_running = 0; - return; - } -generate_new: - bcm43xx_generate_noise_sample(bcm); -} - -static void handle_irq_ps(struct bcm43xx_private *bcm) -{ - if (bcm->ieee->iw_mode == IW_MODE_MASTER) { - ///TODO: PS TBTT - } else { - if (1/*FIXME: the last PSpoll frame was sent successfully */) - bcm43xx_power_saving_ctl_bits(bcm, -1, -1); - } - if (bcm->ieee->iw_mode == IW_MODE_ADHOC) - bcm->reg124_set_0x4 = 1; - //FIXME else set to false? -} - -static void handle_irq_reg124(struct bcm43xx_private *bcm) -{ - if (!bcm->reg124_set_0x4) - return; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) - | 0x4); - //FIXME: reset reg124_set_0x4 to false? -} - -static void handle_irq_pmq(struct bcm43xx_private *bcm) -{ - u32 tmp; - - //TODO: AP mode. - - while (1) { - tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_PS_STATUS); - if (!(tmp & 0x00000008)) - break; - } - /* 16bit write is odd, but correct. */ - bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002); -} - -static void bcm43xx_generate_beacon_template(struct bcm43xx_private *bcm, - u16 ram_offset, u16 shm_size_offset) -{ - u32 value; - u16 size = 0; - - /* Timestamp. */ - //FIXME: assumption: The chip sets the timestamp - value = 0; - bcm43xx_ram_write(bcm, ram_offset++, value); - bcm43xx_ram_write(bcm, ram_offset++, value); - size += 8; - - /* Beacon Interval / Capability Information */ - value = 0x0000;//FIXME: Which interval? - value |= (1 << 0) << 16; /* ESS */ - value |= (1 << 2) << 16; /* CF Pollable */ //FIXME? - value |= (1 << 3) << 16; /* CF Poll Request */ //FIXME? - if (!bcm->ieee->open_wep) - value |= (1 << 4) << 16; /* Privacy */ - bcm43xx_ram_write(bcm, ram_offset++, value); - size += 4; - - /* SSID */ - //TODO - - /* FH Parameter Set */ - //TODO - - /* DS Parameter Set */ - //TODO - - /* CF Parameter Set */ - //TODO - - /* TIM */ - //TODO - - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size); -} - -static void handle_irq_beacon(struct bcm43xx_private *bcm) -{ - u32 status; - - bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON; - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD); - - if ((status & 0x1) && (status & 0x2)) { - /* ACK beacon IRQ. */ - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, - BCM43xx_IRQ_BEACON); - bcm->irq_savedstate |= BCM43xx_IRQ_BEACON; - return; - } - if (!(status & 0x1)) { - bcm43xx_generate_beacon_template(bcm, 0x68, 0x18); - status |= 0x1; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status); - } - if (!(status & 0x2)) { - bcm43xx_generate_beacon_template(bcm, 0x468, 0x1A); - status |= 0x2; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status); - } -} - -/* Interrupt handler bottom-half */ -static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) -{ - u32 reason; - u32 dma_reason[4]; - int activity = 0; - unsigned long flags; - -#ifdef CONFIG_BCM43XX_DEBUG - u32 _handled = 0x00000000; -# define bcmirq_handled(irq) do { _handled |= (irq); } while (0) -#else -# define bcmirq_handled(irq) do { /* nothing */ } while (0) -#endif /* CONFIG_BCM43XX_DEBUG*/ - - bcm43xx_lock_mmio(bcm, flags); - reason = bcm->irq_reason; - dma_reason[0] = bcm->dma_reason[0]; - dma_reason[1] = bcm->dma_reason[1]; - dma_reason[2] = bcm->dma_reason[2]; - dma_reason[3] = bcm->dma_reason[3]; - - if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) { - /* TX error. We get this when Template Ram is written in wrong endianess - * in dummy_tx(). We also get this if something is wrong with the TX header - * on DMA or PIO queues. - * Maybe we get this in other error conditions, too. - */ - printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n"); - bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR); - } - if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) | - (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) | - (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) | - (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) { - printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: " - "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3]); - bcm43xx_controller_restart(bcm, "DMA error"); - bcm43xx_unlock_mmio(bcm, flags); - return; - } - if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | - (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) | - (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) | - (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) { - printkl(KERN_ERR PFX "DMA error: " - "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3]); - } - - if (reason & BCM43xx_IRQ_PS) { - handle_irq_ps(bcm); - bcmirq_handled(BCM43xx_IRQ_PS); - } - - if (reason & BCM43xx_IRQ_REG124) { - handle_irq_reg124(bcm); - bcmirq_handled(BCM43xx_IRQ_REG124); - } - - if (reason & BCM43xx_IRQ_BEACON) { - if (bcm->ieee->iw_mode == IW_MODE_MASTER) - handle_irq_beacon(bcm); - bcmirq_handled(BCM43xx_IRQ_BEACON); - } - - if (reason & BCM43xx_IRQ_PMQ) { - handle_irq_pmq(bcm); - bcmirq_handled(BCM43xx_IRQ_PMQ); - } - - if (reason & BCM43xx_IRQ_SCAN) { - /*TODO*/ - //bcmirq_handled(BCM43xx_IRQ_SCAN); - } - - if (reason & BCM43xx_IRQ_NOISE) { - handle_irq_noise(bcm); - bcmirq_handled(BCM43xx_IRQ_NOISE); - } - - /* Check the DMA reason registers for received data. */ - assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE)); - assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE)); - if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) { - if (bcm43xx_using_pio(bcm)) - bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0); - else - bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0); - /* We intentionally don't set "activity" to 1, here. */ - } - if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) { - if (bcm43xx_using_pio(bcm)) - bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3); - else - bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1); - activity = 1; - } - bcmirq_handled(BCM43xx_IRQ_RX); - - if (reason & BCM43xx_IRQ_XMIT_STATUS) { - handle_irq_transmit_status(bcm); - activity = 1; - //TODO: In AP mode, this also causes sending of powersave responses. - bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS); - } - - /* IRQ_PIO_WORKAROUND is handled in the top-half. */ - bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND); -#ifdef CONFIG_BCM43XX_DEBUG - if (unlikely(reason & ~_handled)) { - printkl(KERN_WARNING PFX - "Unhandled IRQ! Reason: 0x%08x, Unhandled: 0x%08x, " - "DMA: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - reason, (reason & ~_handled), - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3]); - } -#endif -#undef bcmirq_handled - - if (!modparam_noleds) - bcm43xx_leds_update(bcm, activity); - bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); - bcm43xx_unlock_mmio(bcm, flags); -} - -static void pio_irq_workaround(struct bcm43xx_private *bcm, - u16 base, int queueidx) -{ - u16 rxctl; - - rxctl = bcm43xx_read16(bcm, base + BCM43xx_PIO_RXCTL); - if (rxctl & BCM43xx_PIO_RXCTL_DATAAVAILABLE) - bcm->dma_reason[queueidx] |= BCM43xx_DMAIRQ_RX_DONE; - else - bcm->dma_reason[queueidx] &= ~BCM43xx_DMAIRQ_RX_DONE; -} - -static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason) -{ - if (bcm43xx_using_pio(bcm) && - (bcm->current_core->rev < 3) && - (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) { - /* Apply a PIO specific workaround to the dma_reasons */ - pio_irq_workaround(bcm, BCM43xx_MMIO_PIO1_BASE, 0); - pio_irq_workaround(bcm, BCM43xx_MMIO_PIO2_BASE, 1); - pio_irq_workaround(bcm, BCM43xx_MMIO_PIO3_BASE, 2); - pio_irq_workaround(bcm, BCM43xx_MMIO_PIO4_BASE, 3); - } - - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason); - - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON, - bcm->dma_reason[0]); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON, - bcm->dma_reason[1]); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON, - bcm->dma_reason[2]); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON, - bcm->dma_reason[3]); -} - -/* Interrupt handler top-half */ -static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - irqreturn_t ret = IRQ_HANDLED; - struct bcm43xx_private *bcm = dev_id; - u32 reason; - - if (!bcm) - return IRQ_NONE; - - spin_lock(&bcm->_lock); - - /* Only accept IRQs, if we are initialized properly. - * This avoids an RX race while initializing. - * We should probably not enable IRQs before we are initialized - * completely, but some careful work is needed to fix this. I think it - * is best to stay with this cheap workaround for now... . - */ - if (unlikely(!bcm->initialized)) - goto out; - - reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - if (reason == 0xffffffff) { - /* irq not for us (shared irq) */ - ret = IRQ_NONE; - goto out; - } - reason &= bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); - if (!reason) - goto out; - - bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON) - & 0x0001dc00; - bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON) - & 0x0000dc00; - bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON) - & 0x0000dc00; - bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON) - & 0x0001dc00; - - bcm43xx_interrupt_ack(bcm, reason); - - /* disable all IRQs. They are enabled again in the bottom half. */ - bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - /* save the reason code and call our bottom half. */ - bcm->irq_reason = reason; - tasklet_schedule(&bcm->isr_tasklet); -out: - mmiowb(); - spin_unlock(&bcm->_lock); - - return ret; -} - -static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force) -{ - if (bcm->firmware_norelease && !force) - return; /* Suspending or controller reset. */ - release_firmware(bcm->ucode); - bcm->ucode = NULL; - release_firmware(bcm->pcm); - bcm->pcm = NULL; - release_firmware(bcm->initvals0); - bcm->initvals0 = NULL; - release_firmware(bcm->initvals1); - bcm->initvals1 = NULL; -} - -static int bcm43xx_request_firmware(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u8 rev = bcm->current_core->rev; - int err = 0; - int nr; - char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 }; - - if (!bcm->ucode) { - snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw", - (rev >= 5 ? 5 : rev), - modparam_fwpostfix); - err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev); - if (err) { - printk(KERN_ERR PFX - "Error: Microcode \"%s\" not available or load failed.\n", - buf); - goto error; - } - } - - if (!bcm->pcm) { - snprintf(buf, ARRAY_SIZE(buf), - "bcm43xx_pcm%d%s.fw", - (rev < 5 ? 4 : 5), - modparam_fwpostfix); - err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev); - if (err) { - printk(KERN_ERR PFX - "Error: PCM \"%s\" not available or load failed.\n", - buf); - goto error; - } - } - - if (!bcm->initvals0) { - if (rev == 2 || rev == 4) { - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - nr = 3; - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - nr = 1; - break; - default: - goto err_noinitval; - } - - } else if (rev >= 5) { - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - nr = 7; - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - nr = 5; - break; - default: - goto err_noinitval; - } - } else - goto err_noinitval; - snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw", - nr, modparam_fwpostfix); - - err = request_firmware(&bcm->initvals0, buf, &bcm->pci_dev->dev); - if (err) { - printk(KERN_ERR PFX - "Error: InitVals \"%s\" not available or load failed.\n", - buf); - goto error; - } - if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) { - printk(KERN_ERR PFX "InitVals fileformat error.\n"); - goto error; - } - } - - if (!bcm->initvals1) { - if (rev >= 5) { - u32 sbtmstatehigh; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (sbtmstatehigh & 0x00010000) - nr = 9; - else - nr = 10; - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - nr = 6; - break; - default: - goto err_noinitval; - } - snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw", - nr, modparam_fwpostfix); - - err = request_firmware(&bcm->initvals1, buf, &bcm->pci_dev->dev); - if (err) { - printk(KERN_ERR PFX - "Error: InitVals \"%s\" not available or load failed.\n", - buf); - goto error; - } - if (bcm->initvals1->size % sizeof(struct bcm43xx_initval)) { - printk(KERN_ERR PFX "InitVals fileformat error.\n"); - goto error; - } - } - } - -out: - return err; -error: - bcm43xx_release_firmware(bcm, 1); - goto out; -err_noinitval: - printk(KERN_ERR PFX "Error: No InitVals available!\n"); - err = -ENOENT; - goto error; -} - -static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm) -{ - const u32 *data; - unsigned int i, len; - - /* Upload Microcode. */ - data = (u32 *)(bcm->ucode->data); - len = bcm->ucode->size / sizeof(u32); - bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000); - for (i = 0; i < len; i++) { - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, - be32_to_cpu(data[i])); - udelay(10); - } - - /* Upload PCM data. */ - data = (u32 *)(bcm->pcm->data); - len = bcm->pcm->size / sizeof(u32); - bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea); - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000); - bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb); - for (i = 0; i < len; i++) { - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, - be32_to_cpu(data[i])); - udelay(10); - } -} - -static int bcm43xx_write_initvals(struct bcm43xx_private *bcm, - const struct bcm43xx_initval *data, - const unsigned int len) -{ - u16 offset, size; - u32 value; - unsigned int i; - - for (i = 0; i < len; i++) { - offset = be16_to_cpu(data[i].offset); - size = be16_to_cpu(data[i].size); - value = be32_to_cpu(data[i].value); - - if (unlikely(offset >= 0x1000)) - goto err_format; - if (size == 2) { - if (unlikely(value & 0xFFFF0000)) - goto err_format; - bcm43xx_write16(bcm, offset, (u16)value); - } else if (size == 4) { - bcm43xx_write32(bcm, offset, value); - } else - goto err_format; - } - - return 0; - -err_format: - printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. " - "Please fix your bcm43xx firmware files.\n"); - return -EPROTO; -} - -static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm) -{ - int err; - - err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data, - bcm->initvals0->size / sizeof(struct bcm43xx_initval)); - if (err) - goto out; - if (bcm->initvals1) { - err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data, - bcm->initvals1->size / sizeof(struct bcm43xx_initval)); - if (err) - goto out; - } -out: - return err; -} - -static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) -{ - int res; - unsigned int i; - u32 data; - - bcm->irq = bcm->pci_dev->irq; -#ifdef CONFIG_BCM947XX - if (bcm->pci_dev->bus->number == 0) { - struct pci_dev *d = NULL; - /* FIXME: we will probably need more device IDs here... */ - d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL); - if (d != NULL) { - bcm->irq = d->irq; - } - } -#endif - res = request_irq(bcm->irq, bcm43xx_interrupt_handler, - SA_SHIRQ, KBUILD_MODNAME, bcm); - if (res) { - printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq); - return -ENODEV; - } - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff); - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402); - i = 0; - while (1) { - data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - if (data == BCM43xx_IRQ_READY) - break; - i++; - if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) { - printk(KERN_ERR PFX "Card IRQ register not responding. " - "Giving up.\n"); - free_irq(bcm->irq, bcm); - return -ENODEV; - } - udelay(10); - } - // dummy read - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - - return 0; -} - -/* Switch to the core used to write the GPIO register. - * This is either the ChipCommon, or the PCI core. - */ -static int switch_to_gpio_core(struct bcm43xx_private *bcm) -{ - int err; - - /* Where to find the GPIO register depends on the chipset. - * If it has a ChipCommon, its register at offset 0x6c is the GPIO - * control register. Otherwise the register at offset 0x6c in the - * PCI core is the GPIO control register. - */ - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err == -ENODEV) { - err = bcm43xx_switch_core(bcm, &bcm->core_pci); - if (unlikely(err == -ENODEV)) { - printk(KERN_ERR PFX "gpio error: " - "Neither ChipCommon nor PCI core available!\n"); - } - } - - return err; -} - -/* Initialize the GPIOs - * http://bcm-specs.sipsolutions.net/GPIO - */ -static int bcm43xx_gpio_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_coreinfo *old_core; - int err; - u32 mask, set; - - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - & 0xFFFF3FFF); - - bcm43xx_leds_switch_all(bcm, 0); - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK, - bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F); - - mask = 0x0000001F; - set = 0x0000000F; - if (bcm->chip_id == 0x4301) { - mask |= 0x0060; - set |= 0x0060; - } - if (0 /* FIXME: conditional unknown */) { - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK, - bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) - | 0x0100); - mask |= 0x0180; - set |= 0x0180; - } - if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) { - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK, - bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) - | 0x0200); - mask |= 0x0200; - set |= 0x0200; - } - if (bcm->current_core->rev >= 2) - mask |= 0x0010; /* FIXME: This is redundant. */ - - old_core = bcm->current_core; - err = switch_to_gpio_core(bcm); - if (err) - goto out; - bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, - (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | set); - err = bcm43xx_switch_core(bcm, old_core); -out: - return err; -} - -/* Turn off all GPIO stuff. Call this on module unload, for example. */ -static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm) -{ - struct bcm43xx_coreinfo *old_core; - int err; - - old_core = bcm->current_core; - err = switch_to_gpio_core(bcm); - if (err) - return err; - bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, 0x00000000); - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - - return 0; -} - -/* http://bcm-specs.sipsolutions.net/EnableMac */ -void bcm43xx_mac_enable(struct bcm43xx_private *bcm) -{ - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - | BCM43xx_SBF_MAC_ENABLED); - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY); - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ - bcm43xx_power_saving_ctl_bits(bcm, -1, -1); -} - -/* http://bcm-specs.sipsolutions.net/SuspendMAC */ -void bcm43xx_mac_suspend(struct bcm43xx_private *bcm) -{ - int i; - u32 tmp; - - bcm43xx_power_saving_ctl_bits(bcm, -1, 1); - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - & ~BCM43xx_SBF_MAC_ENABLED); - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ - for (i = 100000; i; i--) { - tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - if (tmp & BCM43xx_IRQ_READY) - return; - udelay(10); - } - printkl(KERN_ERR PFX "MAC suspend failed\n"); -} - -void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, - int iw_mode) -{ - unsigned long flags; - struct net_device *net_dev = bcm->net_dev; - u32 status; - u16 value; - - spin_lock_irqsave(&bcm->ieee->lock, flags); - bcm->ieee->iw_mode = iw_mode; - spin_unlock_irqrestore(&bcm->ieee->lock, flags); - if (iw_mode == IW_MODE_MONITOR) - net_dev->type = ARPHRD_IEEE80211; - else - net_dev->type = ARPHRD_ETHER; - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - /* Reset status to infrastructured mode */ - status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR); - status &= ~BCM43xx_SBF_MODE_PROMISC; - status |= BCM43xx_SBF_MODE_NOTADHOC; - -/* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */ -status |= BCM43xx_SBF_MODE_PROMISC; - - switch (iw_mode) { - case IW_MODE_MONITOR: - status |= BCM43xx_SBF_MODE_MONITOR; - status |= BCM43xx_SBF_MODE_PROMISC; - break; - case IW_MODE_ADHOC: - status &= ~BCM43xx_SBF_MODE_NOTADHOC; - break; - case IW_MODE_MASTER: - status |= BCM43xx_SBF_MODE_AP; - break; - case IW_MODE_SECOND: - case IW_MODE_REPEAT: - TODO(); /* TODO */ - break; - case IW_MODE_INFRA: - /* nothing to be done here... */ - break; - default: - dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode); - } - if (net_dev->flags & IFF_PROMISC) - status |= BCM43xx_SBF_MODE_PROMISC; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - - value = 0x0002; - if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) { - if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3) - value = 0x0064; - else - value = 0x0032; - } - bcm43xx_write16(bcm, 0x0612, value); -} - -/* This is the opposite of bcm43xx_chip_init() */ -static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm) -{ - bcm43xx_radio_turn_off(bcm); - if (!modparam_noleds) - bcm43xx_leds_exit(bcm); - bcm43xx_gpio_cleanup(bcm); - free_irq(bcm->irq, bcm); - bcm43xx_release_firmware(bcm, 0); -} - -/* Initialize the chip - * http://bcm-specs.sipsolutions.net/ChipInit - */ -static int bcm43xx_chip_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - int err; - int tmp; - u32 value32; - u16 value16; - - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - BCM43xx_SBF_CORE_READY - | BCM43xx_SBF_400); - - err = bcm43xx_request_firmware(bcm); - if (err) - goto out; - bcm43xx_upload_microcode(bcm); - - err = bcm43xx_initialize_irq(bcm); - if (err) - goto err_release_fw; - - err = bcm43xx_gpio_init(bcm); - if (err) - goto err_free_irq; - - err = bcm43xx_upload_initvals(bcm); - if (err) - goto err_gpio_cleanup; - bcm43xx_radio_turn_on(bcm); - - bcm43xx_write16(bcm, 0x03E6, 0x0000); - err = bcm43xx_phy_init(bcm); - if (err) - goto err_radio_off; - - /* Select initial Interference Mitigation. */ - tmp = radio->interfmode; - radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE; - bcm43xx_radio_set_interference_mitigation(bcm, tmp); - - bcm43xx_phy_set_antenna_diversity(bcm); - bcm43xx_radio_set_txantenna(bcm, BCM43xx_RADIO_TXANTENNA_DEFAULT); - if (phy->type == BCM43xx_PHYTYPE_B) { - value16 = bcm43xx_read16(bcm, 0x005E); - value16 |= 0x0004; - bcm43xx_write16(bcm, 0x005E, value16); - } - bcm43xx_write32(bcm, 0x0100, 0x01000000); - if (bcm->current_core->rev < 5) - bcm43xx_write32(bcm, 0x010C, 0x01000000); - - value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - value32 &= ~ BCM43xx_SBF_MODE_NOTADHOC; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32); - value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - value32 |= BCM43xx_SBF_MODE_NOTADHOC; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32); - - value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - value32 |= 0x100000; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32); - - if (bcm43xx_using_pio(bcm)) { - bcm43xx_write32(bcm, 0x0210, 0x00000100); - bcm43xx_write32(bcm, 0x0230, 0x00000100); - bcm43xx_write32(bcm, 0x0250, 0x00000100); - bcm43xx_write32(bcm, 0x0270, 0x00000100); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0034, 0x0000); - } - - /* Probe Response Timeout value */ - /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */ - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000); - - /* Initially set the wireless operation mode. */ - bcm43xx_set_iwmode(bcm, bcm->ieee->iw_mode); - - if (bcm->current_core->rev < 3) { - bcm43xx_write16(bcm, 0x060E, 0x0000); - bcm43xx_write16(bcm, 0x0610, 0x8000); - bcm43xx_write16(bcm, 0x0604, 0x0000); - bcm43xx_write16(bcm, 0x0606, 0x0200); - } else { - bcm43xx_write32(bcm, 0x0188, 0x80000000); - bcm43xx_write32(bcm, 0x018C, 0x02000000); - } - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00); - - value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - value32 |= 0x00100000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, value32); - - bcm43xx_write16(bcm, BCM43xx_MMIO_POWERUP_DELAY, bcm43xx_pctl_powerup_delay(bcm)); - - assert(err == 0); - dprintk(KERN_INFO PFX "Chip initialized\n"); -out: - return err; - -err_radio_off: - bcm43xx_radio_turn_off(bcm); -err_gpio_cleanup: - bcm43xx_gpio_cleanup(bcm); -err_free_irq: - free_irq(bcm->irq, bcm); -err_release_fw: - bcm43xx_release_firmware(bcm, 1); - goto out; -} - -/* Validate chip access - * http://bcm-specs.sipsolutions.net/ValidateChipAccess */ -static int bcm43xx_validate_chip(struct bcm43xx_private *bcm) -{ - u32 value; - u32 shm_backup; - - shm_backup = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0xAA5555AA); - if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0xAA5555AA) - goto error; - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0x55AAAA55); - if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0x55AAAA55) - goto error; - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, shm_backup); - - value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - if ((value | 0x80000000) != 0x80000400) - goto error; - - value = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - if (value != 0x00000000) - goto error; - - return 0; -error: - printk(KERN_ERR PFX "Failed to validate the chipaccess\n"); - return -ENODEV; -} - -static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy) -{ - /* Initialize a "phyinfo" structure. The structure is already - * zeroed out. - */ - phy->antenna_diversity = 0xFFFF; - phy->savedpctlreg = 0xFFFF; - phy->minlowsig[0] = 0xFFFF; - phy->minlowsig[1] = 0xFFFF; - spin_lock_init(&phy->lock); -} - -static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio) -{ - /* Initialize a "radioinfo" structure. The structure is already - * zeroed out. - */ - radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE; - radio->channel = 0xFF; - radio->initial_channel = 0xFF; - radio->lofcal = 0xFFFF; - radio->initval = 0xFFFF; - radio->nrssi[0] = -1000; - radio->nrssi[1] = -1000; -} - -static int bcm43xx_probe_cores(struct bcm43xx_private *bcm) -{ - int err, i; - int current_core; - u32 core_vendor, core_id, core_rev; - u32 sb_id_hi, chip_id_32 = 0; - u16 pci_device, chip_id_16; - u8 core_count; - - memset(&bcm->core_chipcommon, 0, sizeof(struct bcm43xx_coreinfo)); - memset(&bcm->core_pci, 0, sizeof(struct bcm43xx_coreinfo)); - memset(&bcm->core_80211, 0, sizeof(struct bcm43xx_coreinfo) - * BCM43xx_MAX_80211_CORES); - memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211) - * BCM43xx_MAX_80211_CORES); - bcm->current_80211_core_idx = -1; - bcm->nr_80211_available = 0; - bcm->current_core = NULL; - bcm->active_80211_core = NULL; - - /* map core 0 */ - err = _switch_core(bcm, 0); - if (err) - goto out; - - /* fetch sb_id_hi from core information registers */ - sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); - - core_id = (sb_id_hi & 0xFFF0) >> 4; - core_rev = (sb_id_hi & 0xF); - core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; - - /* if present, chipcommon is always core 0; read the chipid from it */ - if (core_id == BCM43xx_COREID_CHIPCOMMON) { - chip_id_32 = bcm43xx_read32(bcm, 0); - chip_id_16 = chip_id_32 & 0xFFFF; - bcm->core_chipcommon.available = 1; - bcm->core_chipcommon.id = core_id; - bcm->core_chipcommon.rev = core_rev; - bcm->core_chipcommon.index = 0; - /* While we are at it, also read the capabilities. */ - bcm->chipcommon_capabilities = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_CAPABILITIES); - } else { - /* without a chipCommon, use a hard coded table. */ - pci_device = bcm->pci_dev->device; - if (pci_device == 0x4301) - chip_id_16 = 0x4301; - else if ((pci_device >= 0x4305) && (pci_device <= 0x4307)) - chip_id_16 = 0x4307; - else if ((pci_device >= 0x4402) && (pci_device <= 0x4403)) - chip_id_16 = 0x4402; - else if ((pci_device >= 0x4610) && (pci_device <= 0x4615)) - chip_id_16 = 0x4610; - else if ((pci_device >= 0x4710) && (pci_device <= 0x4715)) - chip_id_16 = 0x4710; -#ifdef CONFIG_BCM947XX - else if ((pci_device >= 0x4320) && (pci_device <= 0x4325)) - chip_id_16 = 0x4309; -#endif - else { - printk(KERN_ERR PFX "Could not determine Chip ID\n"); - return -ENODEV; - } - } - - /* ChipCommon with Core Rev >=4 encodes number of cores, - * otherwise consult hardcoded table */ - if ((core_id == BCM43xx_COREID_CHIPCOMMON) && (core_rev >= 4)) { - core_count = (chip_id_32 & 0x0F000000) >> 24; - } else { - switch (chip_id_16) { - case 0x4610: - case 0x4704: - case 0x4710: - core_count = 9; - break; - case 0x4310: - core_count = 8; - break; - case 0x5365: - core_count = 7; - break; - case 0x4306: - core_count = 6; - break; - case 0x4301: - case 0x4307: - core_count = 5; - break; - case 0x4402: - core_count = 3; - break; - default: - /* SOL if we get here */ - assert(0); - core_count = 1; - } - } - - bcm->chip_id = chip_id_16; - bcm->chip_rev = (chip_id_32 & 0x000F0000) >> 16; - bcm->chip_package = (chip_id_32 & 0x00F00000) >> 20; - - dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n", - bcm->chip_id, bcm->chip_rev); - dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count); - if (bcm->core_chipcommon.available) { - dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n", - core_id, core_rev, core_vendor, - bcm43xx_core_enabled(bcm) ? "enabled" : "disabled"); - } - - if (bcm->core_chipcommon.available) - current_core = 1; - else - current_core = 0; - for ( ; current_core < core_count; current_core++) { - struct bcm43xx_coreinfo *core; - struct bcm43xx_coreinfo_80211 *ext_80211; - - err = _switch_core(bcm, current_core); - if (err) - goto out; - /* Gather information */ - /* fetch sb_id_hi from core information registers */ - sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); - - /* extract core_id, core_rev, core_vendor */ - core_id = (sb_id_hi & 0xFFF0) >> 4; - core_rev = (sb_id_hi & 0xF); - core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; - - dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n", - current_core, core_id, core_rev, core_vendor, - bcm43xx_core_enabled(bcm) ? "enabled" : "disabled" ); - - core = NULL; - switch (core_id) { - case BCM43xx_COREID_PCI: - core = &bcm->core_pci; - if (core->available) { - printk(KERN_WARNING PFX "Multiple PCI cores found.\n"); - continue; - } - break; - case BCM43xx_COREID_80211: - for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { - core = &(bcm->core_80211[i]); - ext_80211 = &(bcm->core_80211_ext[i]); - if (!core->available) - break; - core = NULL; - } - if (!core) { - printk(KERN_WARNING PFX "More than %d cores of type 802.11 found.\n", - BCM43xx_MAX_80211_CORES); - continue; - } - if (i != 0) { - /* More than one 80211 core is only supported - * by special chips. - * There are chips with two 80211 cores, but with - * dangling pins on the second core. Be careful - * and ignore these cores here. - */ - if (bcm->pci_dev->device != 0x4324) { - dprintk(KERN_INFO PFX "Ignoring additional 802.11 core.\n"); - continue; - } - } - switch (core_rev) { - case 2: - case 4: - case 5: - case 6: - case 7: - case 9: - break; - default: - printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n", - core_rev); - err = -ENODEV; - goto out; - } - bcm->nr_80211_available++; - bcm43xx_init_struct_phyinfo(&ext_80211->phy); - bcm43xx_init_struct_radioinfo(&ext_80211->radio); - break; - case BCM43xx_COREID_CHIPCOMMON: - printk(KERN_WARNING PFX "Multiple CHIPCOMMON cores found.\n"); - break; - } - if (core) { - core->available = 1; - core->id = core_id; - core->rev = core_rev; - core->index = current_core; - } - } - - if (!bcm->core_80211[0].available) { - printk(KERN_ERR PFX "Error: No 80211 core found!\n"); - err = -ENODEV; - goto out; - } - - err = bcm43xx_switch_core(bcm, &bcm->core_80211[0]); - - assert(err == 0); -out: - return err; -} - -static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm) -{ - const u8 *mac = (const u8*)(bcm->net_dev->dev_addr); - u8 *bssid = bcm->ieee->bssid; - - switch (bcm->ieee->iw_mode) { - case IW_MODE_ADHOC: - random_ether_addr(bssid); - break; - case IW_MODE_MASTER: - case IW_MODE_INFRA: - case IW_MODE_REPEAT: - case IW_MODE_SECOND: - case IW_MODE_MONITOR: - memcpy(bssid, mac, ETH_ALEN); - break; - default: - assert(0); - } -} - -static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm, - u16 rate, - int is_ofdm) -{ - u16 offset; - - if (is_ofdm) { - offset = 0x480; - offset += (bcm43xx_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2; - } - else { - offset = 0x4C0; - offset += (bcm43xx_plcp_get_ratecode_cck(rate) & 0x000F) * 2; - } - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, offset + 0x20, - bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, offset)); -} - -static void bcm43xx_rate_memory_init(struct bcm43xx_private *bcm) -{ - switch (bcm43xx_current_phy(bcm)->type) { - case BCM43xx_PHYTYPE_A: - case BCM43xx_PHYTYPE_G: - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_6MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_12MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_18MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_24MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_36MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_48MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_54MB, 1); - case BCM43xx_PHYTYPE_B: - bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_1MB, 0); - bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_2MB, 0); - bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_5MB, 0); - bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_11MB, 0); - break; - default: - assert(0); - } -} - -static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm) -{ - bcm43xx_chip_cleanup(bcm); - bcm43xx_pio_free(bcm); - bcm43xx_dma_free(bcm); - - bcm->current_core->initialized = 0; -} - -/* http://bcm-specs.sipsolutions.net/80211Init */ -static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u32 ucodeflags; - int err; - u32 sbimconfiglow; - u8 limit; - - if (bcm->chip_rev < 5) { - sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); - sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; - sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; - if (bcm->bustype == BCM43xx_BUSTYPE_PCI) - sbimconfiglow |= 0x32; - else if (bcm->bustype == BCM43xx_BUSTYPE_SB) - sbimconfiglow |= 0x53; - else - assert(0); - bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow); - } - - bcm43xx_phy_calibrate(bcm); - err = bcm43xx_chip_init(bcm); - if (err) - goto out; - - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0016, bcm->current_core->rev); - ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET); - - if (0 /*FIXME: which condition has to be used here? */) - ucodeflags |= 0x00000010; - - /* HW decryption needs to be set now */ - ucodeflags |= 0x40000000; - - if (phy->type == BCM43xx_PHYTYPE_G) { - ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY; - if (phy->rev == 1) - ucodeflags |= BCM43xx_UCODEFLAG_UNKGPHY; - if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) - ucodeflags |= BCM43xx_UCODEFLAG_UNKPACTRL; - } else if (phy->type == BCM43xx_PHYTYPE_B) { - ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY; - if (phy->rev >= 2 && radio->version == 0x2050) - ucodeflags &= ~BCM43xx_UCODEFLAG_UNKGPHY; - } - - if (ucodeflags != bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET)) { - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, ucodeflags); - } - - /* Short/Long Retry Limit. - * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing - * the chip-internal counter. - */ - limit = limit_value(modparam_short_retry, 0, 0xF); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0006, limit); - limit = limit_value(modparam_long_retry, 0, 0xF); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0007, limit); - - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0044, 3); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0046, 2); - - bcm43xx_rate_memory_init(bcm); - - /* Minimum Contention Window */ - if (phy->type == BCM43xx_PHYTYPE_B) - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000001f); - else - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000000f); - /* Maximum Contention Window */ - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff); - - bcm43xx_gen_bssid(bcm); - bcm43xx_write_mac_bssid_templates(bcm); - - if (bcm->current_core->rev >= 5) - bcm43xx_write16(bcm, 0x043C, 0x000C); - - if (bcm43xx_using_pio(bcm)) - err = bcm43xx_pio_init(bcm); - else - err = bcm43xx_dma_init(bcm); - if (err) - goto err_chip_cleanup; - bcm43xx_write16(bcm, 0x0612, 0x0050); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4); - - bcm43xx_mac_enable(bcm); - bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); - - bcm->current_core->initialized = 1; -out: - return err; - -err_chip_cleanup: - bcm43xx_chip_cleanup(bcm); - goto out; -} - -static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm) -{ - int err; - u16 pci_status; - - err = bcm43xx_pctl_set_crystal(bcm, 1); - if (err) - goto out; - bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status); - bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT); - -out: - return err; -} - -static void bcm43xx_chipset_detach(struct bcm43xx_private *bcm) -{ - bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW); - bcm43xx_pctl_set_crystal(bcm, 0); -} - -static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm, - u32 address, - u32 data) -{ - bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_ADDR, address); - bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_DATA, data); -} - -static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) -{ - int err; - struct bcm43xx_coreinfo *old_core; - - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_pci); - if (err) - goto out; - - bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); - - bcm43xx_switch_core(bcm, old_core); - assert(err == 0); -out: - return err; -} - -/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable. - * To enable core 0, pass a core_mask of 1<<0 - */ -static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm, - u32 core_mask) -{ - u32 backplane_flag_nr; - u32 value; - struct bcm43xx_coreinfo *old_core; - int err = 0; - - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTPSFLAG); - backplane_flag_nr = value & BCM43xx_BACKPLANE_FLAG_NR_MASK; - - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_pci); - if (err) - goto out; - - if (bcm->core_pci.rev < 6) { - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC); - value |= (1 << backplane_flag_nr); - bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value); - } else { - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ICR, &value); - if (err) { - printk(KERN_ERR PFX "Error: ICR setup failure!\n"); - goto out_switch_back; - } - value |= core_mask << 8; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ICR, value); - if (err) { - printk(KERN_ERR PFX "Error: ICR setup failure!\n"); - goto out_switch_back; - } - } - - value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); - value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST; - bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); - - if (bcm->core_pci.rev < 5) { - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); - value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT) - & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; - value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT) - & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; - bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value); - err = bcm43xx_pcicore_commit_settings(bcm); - assert(err == 0); - } - -out_switch_back: - err = bcm43xx_switch_core(bcm, old_core); -out: - return err; -} - -static void bcm43xx_softmac_init(struct bcm43xx_private *bcm) -{ - ieee80211softmac_start(bcm->net_dev); -} - -static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (phy->type != BCM43xx_PHYTYPE_G || phy->rev < 2) - return; - - bcm43xx_mac_suspend(bcm); - bcm43xx_phy_lo_g_measure(bcm); - bcm43xx_mac_enable(bcm); -} - -static void bcm43xx_periodic_every60sec(struct bcm43xx_private *bcm) -{ - bcm43xx_phy_lo_mark_all_unused(bcm); - if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { - bcm43xx_mac_suspend(bcm); - bcm43xx_calc_nrssi_slope(bcm); - bcm43xx_mac_enable(bcm); - } -} - -static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm) -{ - /* Update device statistics. */ - bcm43xx_calculate_link_quality(bcm); -} - -static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (phy->type == BCM43xx_PHYTYPE_G) { - //TODO: update_aci_moving_average - if (radio->aci_enable && radio->aci_wlan_automatic) { - bcm43xx_mac_suspend(bcm); - if (!radio->aci_enable && 1 /*TODO: not scanning? */) { - if (0 /*TODO: bunch of conditions*/) { - bcm43xx_radio_set_interference_mitigation(bcm, - BCM43xx_RADIO_INTERFMODE_MANUALWLAN); - } - } else if (1/*TODO*/) { - /* - if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) { - bcm43xx_radio_set_interference_mitigation(bcm, - BCM43xx_RADIO_INTERFMODE_NONE); - } - */ - } - bcm43xx_mac_enable(bcm); - } else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN && - phy->rev == 1) { - //TODO: implement rev1 workaround - } - } - bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning? - //TODO for APHY (temperature?) -} - -static void bcm43xx_periodic_task_handler(unsigned long d) -{ - struct bcm43xx_private *bcm = (struct bcm43xx_private *)d; - unsigned long flags; - unsigned int state; - - bcm43xx_lock_mmio(bcm, flags); - - assert(bcm->initialized); - state = bcm->periodic_state; - if (state % 8 == 0) - bcm43xx_periodic_every120sec(bcm); - if (state % 4 == 0) - bcm43xx_periodic_every60sec(bcm); - if (state % 2 == 0) - bcm43xx_periodic_every30sec(bcm); - bcm43xx_periodic_every15sec(bcm); - bcm->periodic_state = state + 1; - - mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); - - bcm43xx_unlock_mmio(bcm, flags); -} - -static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) -{ - del_timer_sync(&bcm->periodic_tasks); -} - -static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) -{ - struct timer_list *timer = &(bcm->periodic_tasks); - - assert(bcm->initialized); - setup_timer(timer, - bcm43xx_periodic_task_handler, - (unsigned long)bcm); - timer->expires = jiffies; - add_timer(timer); -} - -static void bcm43xx_security_init(struct bcm43xx_private *bcm) -{ - bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, - 0x0056) * 2; - bcm43xx_clear_keys(bcm); -} - -/* This is the opposite of bcm43xx_init_board() */ -static void bcm43xx_free_board(struct bcm43xx_private *bcm) -{ - int i, err; - unsigned long flags; - - bcm43xx_sysfs_unregister(bcm); - - bcm43xx_periodic_tasks_delete(bcm); - - bcm43xx_lock(bcm, flags); - bcm->initialized = 0; - bcm->shutting_down = 1; - bcm43xx_unlock(bcm, flags); - - for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { - if (!bcm->core_80211[i].available) - continue; - if (!bcm->core_80211[i].initialized) - continue; - - err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); - assert(err == 0); - bcm43xx_wireless_core_cleanup(bcm); - } - - bcm43xx_pctl_set_crystal(bcm, 0); - - bcm43xx_lock(bcm, flags); - bcm->shutting_down = 0; - bcm43xx_unlock(bcm, flags); -} - -static int bcm43xx_init_board(struct bcm43xx_private *bcm) -{ - int i, err; - int connect_phy; - unsigned long flags; - - might_sleep(); - - bcm43xx_lock(bcm, flags); - bcm->initialized = 0; - bcm->shutting_down = 0; - bcm43xx_unlock(bcm, flags); - - err = bcm43xx_pctl_set_crystal(bcm, 1); - if (err) - goto out; - err = bcm43xx_pctl_init(bcm); - if (err) - goto err_crystal_off; - err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST); - if (err) - goto err_crystal_off; - - tasklet_enable(&bcm->isr_tasklet); - for (i = 0; i < bcm->nr_80211_available; i++) { - err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); - assert(err != -ENODEV); - if (err) - goto err_80211_unwind; - - /* Enable the selected wireless core. - * Connect PHY only on the first core. - */ - if (!bcm43xx_core_enabled(bcm)) { - if (bcm->nr_80211_available == 1) { - connect_phy = bcm43xx_current_phy(bcm)->connected; - } else { - if (i == 0) - connect_phy = 1; - else - connect_phy = 0; - } - bcm43xx_wireless_core_reset(bcm, connect_phy); - } - - if (i != 0) - bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]); - - err = bcm43xx_wireless_core_init(bcm); - if (err) - goto err_80211_unwind; - - if (i != 0) { - bcm43xx_mac_suspend(bcm); - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_radio_turn_off(bcm); - } - } - bcm->active_80211_core = &bcm->core_80211[0]; - if (bcm->nr_80211_available >= 2) { - bcm43xx_switch_core(bcm, &bcm->core_80211[0]); - bcm43xx_mac_enable(bcm); - } - bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); - bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); - dprintk(KERN_INFO PFX "80211 cores initialized\n"); - bcm43xx_security_init(bcm); - bcm43xx_softmac_init(bcm); - - bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC); - - if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) { - bcm43xx_mac_suspend(bcm); - bcm43xx_radio_selectchannel(bcm, bcm43xx_current_radio(bcm)->initial_channel, 0); - bcm43xx_mac_enable(bcm); - } - - /* Initialization of the board is done. Flag it as such. */ - bcm43xx_lock(bcm, flags); - bcm->initialized = 1; - bcm43xx_unlock(bcm, flags); - - bcm43xx_periodic_tasks_setup(bcm); - bcm43xx_sysfs_register(bcm); - //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though... - - /*FIXME: This should be handled by softmac instead. */ - schedule_work(&bcm->softmac->associnfo.work); - - assert(err == 0); -out: - return err; - -err_80211_unwind: - tasklet_disable(&bcm->isr_tasklet); - /* unwind all 80211 initialization */ - for (i = 0; i < bcm->nr_80211_available; i++) { - if (!bcm->core_80211[i].initialized) - continue; - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_wireless_core_cleanup(bcm); - } -err_crystal_off: - bcm43xx_pctl_set_crystal(bcm, 0); - goto out; -} - -static void bcm43xx_detach_board(struct bcm43xx_private *bcm) -{ - struct pci_dev *pci_dev = bcm->pci_dev; - int i; - - bcm43xx_chipset_detach(bcm); - /* Do _not_ access the chip, after it is detached. */ - iounmap(bcm->mmio_addr); - - pci_release_regions(pci_dev); - pci_disable_device(pci_dev); - - /* Free allocated structures/fields */ - for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { - kfree(bcm->core_80211_ext[i].phy._lo_pairs); - if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl) - kfree(bcm->core_80211_ext[i].phy.tssi2dbm); - } -} - -static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 value; - u8 phy_version; - u8 phy_type; - u8 phy_rev; - int phy_rev_ok = 1; - void *p; - - value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER); - - phy_version = (value & 0xF000) >> 12; - phy_type = (value & 0x0F00) >> 8; - phy_rev = (value & 0x000F); - - dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n", - phy_version, phy_type, phy_rev); - - switch (phy_type) { - case BCM43xx_PHYTYPE_A: - if (phy_rev >= 4) - phy_rev_ok = 0; - /*FIXME: We need to switch the ieee->modulation, etc.. flags, - * if we switch 80211 cores after init is done. - * As we do not implement on the fly switching between - * wireless cores, I will leave this as a future task. - */ - bcm->ieee->modulation = IEEE80211_OFDM_MODULATION; - bcm->ieee->mode = IEEE_A; - bcm->ieee->freq_band = IEEE80211_52GHZ_BAND | - IEEE80211_24GHZ_BAND; - break; - case BCM43xx_PHYTYPE_B: - if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7) - phy_rev_ok = 0; - bcm->ieee->modulation = IEEE80211_CCK_MODULATION; - bcm->ieee->mode = IEEE_B; - bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; - break; - case BCM43xx_PHYTYPE_G: - if (phy_rev > 7) - phy_rev_ok = 0; - bcm->ieee->modulation = IEEE80211_OFDM_MODULATION | - IEEE80211_CCK_MODULATION; - bcm->ieee->mode = IEEE_G; - bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; - break; - default: - printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n", - phy_type); - return -ENODEV; - }; - if (!phy_rev_ok) { - printk(KERN_WARNING PFX "Invalid PHY Revision %x\n", - phy_rev); - } - - phy->version = phy_version; - phy->type = phy_type; - phy->rev = phy_rev; - if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) { - p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT, - GFP_KERNEL); - if (!p) - return -ENOMEM; - phy->_lo_pairs = p; - } - - return 0; -} - -static int bcm43xx_attach_board(struct bcm43xx_private *bcm) -{ - struct pci_dev *pci_dev = bcm->pci_dev; - struct net_device *net_dev = bcm->net_dev; - int err; - int i; - unsigned long mmio_start, mmio_flags, mmio_len; - u32 coremask; - - err = pci_enable_device(pci_dev); - if (err) { - printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err); - goto out; - } - mmio_start = pci_resource_start(pci_dev, 0); - mmio_flags = pci_resource_flags(pci_dev, 0); - mmio_len = pci_resource_len(pci_dev, 0); - if (!(mmio_flags & IORESOURCE_MEM)) { - printk(KERN_ERR PFX - "%s, region #0 not an MMIO resource, aborting\n", - pci_name(pci_dev)); - err = -ENODEV; - goto err_pci_disable; - } - err = pci_request_regions(pci_dev, KBUILD_MODNAME); - if (err) { - printk(KERN_ERR PFX - "could not access PCI resources (%i)\n", err); - goto err_pci_disable; - } - /* enable PCI bus-mastering */ - pci_set_master(pci_dev); - bcm->mmio_addr = ioremap(mmio_start, mmio_len); - if (!bcm->mmio_addr) { - printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", - pci_name(pci_dev)); - err = -EIO; - goto err_pci_release; - } - bcm->mmio_len = mmio_len; - net_dev->base_addr = (unsigned long)bcm->mmio_addr; - - bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID, - &bcm->board_vendor); - bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID, - &bcm->board_type); - bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID, - &bcm->board_revision); - - err = bcm43xx_chipset_attach(bcm); - if (err) - goto err_iounmap; - err = bcm43xx_pctl_init(bcm); - if (err) - goto err_chipset_detach; - err = bcm43xx_probe_cores(bcm); - if (err) - goto err_chipset_detach; - - /* Attach all IO cores to the backplane. */ - coremask = 0; - for (i = 0; i < bcm->nr_80211_available; i++) - coremask |= (1 << bcm->core_80211[i].index); - //FIXME: Also attach some non80211 cores? - err = bcm43xx_setup_backplane_pci_connection(bcm, coremask); - if (err) { - printk(KERN_ERR PFX "Backplane->PCI connection failed!\n"); - goto err_chipset_detach; - } - - err = bcm43xx_sprom_extract(bcm); - if (err) - goto err_chipset_detach; - err = bcm43xx_leds_init(bcm); - if (err) - goto err_chipset_detach; - - for (i = 0; i < bcm->nr_80211_available; i++) { - err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); - assert(err != -ENODEV); - if (err) - goto err_80211_unwind; - - /* Enable the selected wireless core. - * Connect PHY only on the first core. - */ - bcm43xx_wireless_core_reset(bcm, (i == 0)); - - err = bcm43xx_read_phyinfo(bcm); - if (err && (i == 0)) - goto err_80211_unwind; - - err = bcm43xx_read_radioinfo(bcm); - if (err && (i == 0)) - goto err_80211_unwind; - - err = bcm43xx_validate_chip(bcm); - if (err && (i == 0)) - goto err_80211_unwind; - - bcm43xx_radio_turn_off(bcm); - err = bcm43xx_phy_init_tssi2dbm_table(bcm); - if (err) - goto err_80211_unwind; - bcm43xx_wireless_core_disable(bcm); - } - err = bcm43xx_geo_init(bcm); - if (err) - goto err_80211_unwind; - bcm43xx_pctl_set_crystal(bcm, 0); - - /* Set the MAC address in the networking subsystem */ - if (is_valid_ether_addr(bcm->sprom.et1macaddr)) - memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6); - else - memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6); - - snprintf(bcm->nick, IW_ESSID_MAX_SIZE, - "Broadcom %04X", bcm->chip_id); - - assert(err == 0); -out: - return err; - -err_80211_unwind: - for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { - kfree(bcm->core_80211_ext[i].phy._lo_pairs); - if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl) - kfree(bcm->core_80211_ext[i].phy.tssi2dbm); - } -err_chipset_detach: - bcm43xx_chipset_detach(bcm); -err_iounmap: - iounmap(bcm->mmio_addr); -err_pci_release: - pci_release_regions(pci_dev); -err_pci_disable: - pci_disable_device(pci_dev); - goto out; -} - -/* Do the Hardware IO operations to send the txb */ -static inline int bcm43xx_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - int err = -ENODEV; - - if (bcm43xx_using_pio(bcm)) - err = bcm43xx_pio_tx(bcm, txb); - else - err = bcm43xx_dma_tx(bcm, txb); - bcm->net_dev->trans_start = jiffies; - - return err; -} - -static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, - u8 channel) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct bcm43xx_radioinfo *radio; - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { - bcm43xx_mac_suspend(bcm); - bcm43xx_radio_selectchannel(bcm, channel, 0); - bcm43xx_mac_enable(bcm); - } else { - radio = bcm43xx_current_radio(bcm); - radio->initial_channel = channel; - } - bcm43xx_unlock_mmio(bcm, flags); -} - -/* set_security() callback in struct ieee80211_device */ -static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, - struct ieee80211_security *sec) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct ieee80211_security *secinfo = &bcm->ieee->sec; - unsigned long flags; - int keyidx; - - dprintk(KERN_INFO PFX "set security called\n"); - - bcm43xx_lock_mmio(bcm, flags); - - for (keyidx = 0; keyidxflags & (1<encode_alg[keyidx] = sec->encode_alg[keyidx]; - secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx]; - memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN); - } - - if (sec->flags & SEC_ACTIVE_KEY) { - secinfo->active_key = sec->active_key; - dprintk(KERN_INFO PFX " .active_key = %d\n", sec->active_key); - } - if (sec->flags & SEC_UNICAST_GROUP) { - secinfo->unicast_uses_group = sec->unicast_uses_group; - dprintk(KERN_INFO PFX " .unicast_uses_group = %d\n", sec->unicast_uses_group); - } - if (sec->flags & SEC_LEVEL) { - secinfo->level = sec->level; - dprintk(KERN_INFO PFX " .level = %d\n", sec->level); - } - if (sec->flags & SEC_ENABLED) { - secinfo->enabled = sec->enabled; - dprintk(KERN_INFO PFX " .enabled = %d\n", sec->enabled); - } - if (sec->flags & SEC_ENCRYPT) { - secinfo->encrypt = sec->encrypt; - dprintk(KERN_INFO PFX " .encrypt = %d\n", sec->encrypt); - } - if (bcm->initialized && !bcm->ieee->host_encrypt) { - if (secinfo->enabled) { - /* upload WEP keys to hardware */ - char null_address[6] = { 0 }; - u8 algorithm = 0; - for (keyidx = 0; keyidxflags & (1<encode_alg[keyidx]) { - case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break; - case SEC_ALG_WEP: - algorithm = BCM43xx_SEC_ALGO_WEP; - if (secinfo->key_sizes[keyidx] == 13) - algorithm = BCM43xx_SEC_ALGO_WEP104; - break; - case SEC_ALG_TKIP: - FIXME(); - algorithm = BCM43xx_SEC_ALGO_TKIP; - break; - case SEC_ALG_CCMP: - FIXME(); - algorithm = BCM43xx_SEC_ALGO_AES; - break; - default: - assert(0); - break; - } - bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]); - bcm->key[keyidx].enabled = 1; - bcm->key[keyidx].algorithm = algorithm; - } - } else - bcm43xx_clear_keys(bcm); - } - bcm43xx_unlock_mmio(bcm, flags); -} - -/* hard_start_xmit() callback in struct ieee80211_device */ -static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb, - struct net_device *net_dev, - int pri) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = -ENODEV; - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - if (likely(bcm->initialized)) - err = bcm43xx_tx(bcm, txb); - bcm43xx_unlock_mmio(bcm, flags); - - return err; -} - -static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev) -{ - return &(bcm43xx_priv(net_dev)->ieee->stats); -} - -static void bcm43xx_net_tx_timeout(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - bcm43xx_controller_restart(bcm, "TX timeout"); - bcm43xx_unlock_mmio(bcm, flags); -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void bcm43xx_net_poll_controller(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - local_irq_save(flags); - bcm43xx_interrupt_handler(bcm->irq, bcm, NULL); - local_irq_restore(flags); -} -#endif /* CONFIG_NET_POLL_CONTROLLER */ - -static int bcm43xx_net_open(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - - return bcm43xx_init_board(bcm); -} - -static int bcm43xx_net_stop(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - - ieee80211softmac_stop(net_dev); - bcm43xx_disable_interrupts_sync(bcm, NULL); - bcm43xx_free_board(bcm); - - return 0; -} - -static int bcm43xx_init_private(struct bcm43xx_private *bcm, - struct net_device *net_dev, - struct pci_dev *pci_dev) -{ - int err; - - bcm->ieee = netdev_priv(net_dev); - bcm->softmac = ieee80211_priv(net_dev); - bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; - - bcm->irq_savedstate = BCM43xx_IRQ_INITIAL; - bcm->pci_dev = pci_dev; - bcm->net_dev = net_dev; - bcm->bad_frames_preempt = modparam_bad_frames_preempt; - spin_lock_init(&bcm->_lock); - tasklet_init(&bcm->isr_tasklet, - (void (*)(unsigned long))bcm43xx_interrupt_tasklet, - (unsigned long)bcm); - tasklet_disable_nosync(&bcm->isr_tasklet); - if (modparam_pio) { - bcm->__using_pio = 1; - } else { - err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK); - err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK); - if (err) { -#ifdef CONFIG_BCM43XX_PIO - printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n"); - bcm->__using_pio = 1; -#else - printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " - "Recompile the driver with PIO support, please.\n"); - return -ENODEV; -#endif /* CONFIG_BCM43XX_PIO */ - } - } - bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; - - /* default to sw encryption for now */ - bcm->ieee->host_build_iv = 0; - bcm->ieee->host_encrypt = 1; - bcm->ieee->host_decrypt = 1; - - bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE; - bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr); - bcm->ieee->set_security = bcm43xx_ieee80211_set_security; - bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit; - - return 0; -} - -static int __devinit bcm43xx_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *net_dev; - struct bcm43xx_private *bcm; - int err; - -#ifdef CONFIG_BCM947XX - if ((pdev->bus->number == 0) && (pdev->device != 0x0800)) - return -ENODEV; -#endif - -#ifdef DEBUG_SINGLE_DEVICE_ONLY - if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY)) - return -ENODEV; -#endif - - net_dev = alloc_ieee80211softmac(sizeof(*bcm)); - if (!net_dev) { - printk(KERN_ERR PFX - "could not allocate ieee80211 device %s\n", - pci_name(pdev)); - err = -ENOMEM; - goto out; - } - /* initialize the net_device struct */ - SET_MODULE_OWNER(net_dev); - SET_NETDEV_DEV(net_dev, &pdev->dev); - - net_dev->open = bcm43xx_net_open; - net_dev->stop = bcm43xx_net_stop; - net_dev->get_stats = bcm43xx_net_get_stats; - net_dev->tx_timeout = bcm43xx_net_tx_timeout; -#ifdef CONFIG_NET_POLL_CONTROLLER - net_dev->poll_controller = bcm43xx_net_poll_controller; -#endif - net_dev->wireless_handlers = &bcm43xx_wx_handlers_def; - net_dev->irq = pdev->irq; - SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops); - - /* initialize the bcm43xx_private struct */ - bcm = bcm43xx_priv(net_dev); - memset(bcm, 0, sizeof(*bcm)); - err = bcm43xx_init_private(bcm, net_dev, pdev); - if (err) - goto err_free_netdev; - - pci_set_drvdata(pdev, net_dev); - - err = bcm43xx_attach_board(bcm); - if (err) - goto err_free_netdev; - - err = register_netdev(net_dev); - if (err) { - printk(KERN_ERR PFX "Cannot register net device, " - "aborting.\n"); - err = -ENOMEM; - goto err_detach_board; - } - - bcm43xx_debugfs_add_device(bcm); - - assert(err == 0); -out: - return err; - -err_detach_board: - bcm43xx_detach_board(bcm); -err_free_netdev: - free_ieee80211softmac(net_dev); - goto out; -} - -static void __devexit bcm43xx_remove_one(struct pci_dev *pdev) -{ - struct net_device *net_dev = pci_get_drvdata(pdev); - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - - bcm43xx_debugfs_remove_device(bcm); - unregister_netdev(net_dev); - bcm43xx_detach_board(bcm); - assert(bcm->ucode == NULL); - free_ieee80211softmac(net_dev); -} - -/* Hard-reset the chip. Do not call this directly. - * Use bcm43xx_controller_restart() - */ -static void bcm43xx_chip_reset(void *_bcm) -{ - struct bcm43xx_private *bcm = _bcm; - struct net_device *net_dev = bcm->net_dev; - struct pci_dev *pci_dev = bcm->pci_dev; - int err; - int was_initialized = bcm->initialized; - - netif_stop_queue(bcm->net_dev); - tasklet_disable(&bcm->isr_tasklet); - - bcm->firmware_norelease = 1; - if (was_initialized) - bcm43xx_free_board(bcm); - bcm->firmware_norelease = 0; - bcm43xx_detach_board(bcm); - err = bcm43xx_init_private(bcm, net_dev, pci_dev); - if (err) - goto failure; - err = bcm43xx_attach_board(bcm); - if (err) - goto failure; - if (was_initialized) { - err = bcm43xx_init_board(bcm); - if (err) - goto failure; - } - netif_wake_queue(bcm->net_dev); - printk(KERN_INFO PFX "Controller restarted\n"); - - return; -failure: - printk(KERN_ERR PFX "Controller restart failed\n"); -} - -/* Hard-reset the chip. - * This can be called from interrupt or process context. - * Make sure to _not_ re-enable device interrupts after this has been called. -*/ -void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) -{ - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ - printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); - INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm); - schedule_work(&bcm->restart_work); -} - -#ifdef CONFIG_PM - -static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *net_dev = pci_get_drvdata(pdev); - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int try_to_shutdown = 0, err; - - dprintk(KERN_INFO PFX "Suspending...\n"); - - bcm43xx_lock(bcm, flags); - bcm->was_initialized = bcm->initialized; - if (bcm->initialized) - try_to_shutdown = 1; - bcm43xx_unlock(bcm, flags); - - netif_device_detach(net_dev); - if (try_to_shutdown) { - ieee80211softmac_stop(net_dev); - err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate); - if (unlikely(err)) { - dprintk(KERN_ERR PFX "Suspend failed.\n"); - return -EAGAIN; - } - bcm->firmware_norelease = 1; - bcm43xx_free_board(bcm); - bcm->firmware_norelease = 0; - } - bcm43xx_chipset_detach(bcm); - - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - - dprintk(KERN_INFO PFX "Device suspended.\n"); - - return 0; -} - -static int bcm43xx_resume(struct pci_dev *pdev) -{ - struct net_device *net_dev = pci_get_drvdata(pdev); - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = 0; - - dprintk(KERN_INFO PFX "Resuming...\n"); - - pci_set_power_state(pdev, 0); - pci_enable_device(pdev); - pci_restore_state(pdev); - - bcm43xx_chipset_attach(bcm); - if (bcm->was_initialized) { - bcm->irq_savedstate = BCM43xx_IRQ_INITIAL; - err = bcm43xx_init_board(bcm); - } - if (err) { - printk(KERN_ERR PFX "Resume failed!\n"); - return err; - } - - netif_device_attach(net_dev); - - dprintk(KERN_INFO PFX "Device resumed.\n"); - - return 0; -} - -#endif /* CONFIG_PM */ - -static struct pci_driver bcm43xx_pci_driver = { - .name = KBUILD_MODNAME, - .id_table = bcm43xx_pci_tbl, - .probe = bcm43xx_init_one, - .remove = __devexit_p(bcm43xx_remove_one), -#ifdef CONFIG_PM - .suspend = bcm43xx_suspend, - .resume = bcm43xx_resume, -#endif /* CONFIG_PM */ -}; - -static int __init bcm43xx_init(void) -{ - printk(KERN_INFO KBUILD_MODNAME " driver\n"); - bcm43xx_debugfs_init(); - return pci_register_driver(&bcm43xx_pci_driver); -} - -static void __exit bcm43xx_exit(void) -{ - pci_unregister_driver(&bcm43xx_pci_driver); - bcm43xx_debugfs_exit(); -} - -module_init(bcm43xx_init) -module_exit(bcm43xx_exit) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h deleted file mode 100644 index 30a202b25..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_MAIN_H_ -#define BCM43xx_MAIN_H_ - -#include "bcm43xx.h" - -#ifdef CONFIG_BCM947XX -#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0) - -static inline void e_aton(char *str, char *dest) -{ - int i = 0; - u16 *d = (u16 *) dest; - - for (;;) { - dest[i++] = (char) simple_strtoul(str, NULL, 16); - str += 2; - if (!*str++ || i == 6) - break; - } - for (i = 0; i < 3; i++) - d[i] = cpu_to_be16(d[i]); -} -#endif - -#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes] -#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes) -/* Magic helper macro to pad structures. Ignore those above. It's magic. */ -#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) - - -/* Lightweight function to convert a frequency (in Mhz) to a channel number. */ -static inline -u8 bcm43xx_freq_to_channel_a(int freq) -{ - return ((freq - 5000) / 5); -} -static inline -u8 bcm43xx_freq_to_channel_bg(int freq) -{ - u8 channel; - - if (freq == 2484) - channel = 14; - else - channel = (freq - 2407) / 5; - - return channel; -} -static inline -u8 bcm43xx_freq_to_channel(struct bcm43xx_private *bcm, - int freq) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) - return bcm43xx_freq_to_channel_a(freq); - return bcm43xx_freq_to_channel_bg(freq); -} - -/* Lightweight function to convert a channel number to a frequency (in Mhz). */ -static inline -int bcm43xx_channel_to_freq_a(u8 channel) -{ - return (5000 + (5 * channel)); -} -static inline -int bcm43xx_channel_to_freq_bg(u8 channel) -{ - int freq; - - if (channel == 14) - freq = 2484; - else - freq = 2407 + (5 * channel); - - return freq; -} -static inline -int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm, - u8 channel) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) - return bcm43xx_channel_to_freq_a(channel); - return bcm43xx_channel_to_freq_bg(channel); -} - -/* Lightweight function to check if a channel number is valid. - * Note that this does _NOT_ check for geographical restrictions! - */ -static inline -int bcm43xx_is_valid_channel_a(u8 channel) -{ - return (channel >= IEEE80211_52GHZ_MIN_CHANNEL - && channel <= IEEE80211_52GHZ_MAX_CHANNEL); -} -static inline -int bcm43xx_is_valid_channel_bg(u8 channel) -{ - return (channel >= IEEE80211_24GHZ_MIN_CHANNEL - && channel <= IEEE80211_24GHZ_MAX_CHANNEL); -} -static inline -int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm, - u8 channel) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) - return bcm43xx_is_valid_channel_a(channel); - return bcm43xx_is_valid_channel_bg(channel); -} - -void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf); -void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf); - -void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, - int iw_mode); - -u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm, - u16 routing, u16 offset); -u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm, - u16 routing, u16 offset); -void bcm43xx_shm_write32(struct bcm43xx_private *bcm, - u16 routing, u16 offset, - u32 value); -void bcm43xx_shm_write16(struct bcm43xx_private *bcm, - u16 routing, u16 offset, - u16 value); - -void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm); - -int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core); - -void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy); - -void bcm43xx_mac_suspend(struct bcm43xx_private *bcm); -void bcm43xx_mac_enable(struct bcm43xx_private *bcm); - -void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); - -int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom); -int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom); - -#endif /* BCM43xx_MAIN_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c deleted file mode 100644 index b0abac515..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ /dev/null @@ -1,2346 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include -#include -#include - -#include "bcm43xx.h" -#include "bcm43xx_phy.h" -#include "bcm43xx_main.h" -#include "bcm43xx_radio.h" -#include "bcm43xx_ilt.h" -#include "bcm43xx_power.h" - - -static const s8 bcm43xx_tssi2dbm_b_table[] = { - 0x4D, 0x4C, 0x4B, 0x4A, - 0x4A, 0x49, 0x48, 0x47, - 0x47, 0x46, 0x45, 0x45, - 0x44, 0x43, 0x42, 0x42, - 0x41, 0x40, 0x3F, 0x3E, - 0x3D, 0x3C, 0x3B, 0x3A, - 0x39, 0x38, 0x37, 0x36, - 0x35, 0x34, 0x32, 0x31, - 0x30, 0x2F, 0x2D, 0x2C, - 0x2B, 0x29, 0x28, 0x26, - 0x25, 0x23, 0x21, 0x1F, - 0x1D, 0x1A, 0x17, 0x14, - 0x10, 0x0C, 0x06, 0x00, - -7, -7, -7, -7, - -7, -7, -7, -7, - -7, -7, -7, -7, -}; - -static const s8 bcm43xx_tssi2dbm_g_table[] = { - 77, 77, 77, 76, - 76, 76, 75, 75, - 74, 74, 73, 73, - 73, 72, 72, 71, - 71, 70, 70, 69, - 68, 68, 67, 67, - 66, 65, 65, 64, - 63, 63, 62, 61, - 60, 59, 58, 57, - 56, 55, 54, 53, - 52, 50, 49, 47, - 45, 43, 40, 37, - 33, 28, 22, 14, - 5, -7, -20, -20, - -20, -20, -20, -20, - -20, -20, -20, -20, -}; - -static void bcm43xx_phy_initg(struct bcm43xx_private *bcm); - - -void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - assert(irqs_disabled()); - if (bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) == 0x00000000) { - phy->is_locked = 0; - return; - } - if (bcm->current_core->rev < 3) { - bcm43xx_mac_suspend(bcm); - spin_lock(&phy->lock); - } else { - if (bcm->ieee->iw_mode != IW_MODE_MASTER) - bcm43xx_power_saving_ctl_bits(bcm, -1, 1); - } - phy->is_locked = 1; -} - -void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - assert(irqs_disabled()); - if (bcm->current_core->rev < 3) { - if (phy->is_locked) { - spin_unlock(&phy->lock); - bcm43xx_mac_enable(bcm); - } - } else { - if (bcm->ieee->iw_mode != IW_MODE_MASTER) - bcm43xx_power_saving_ctl_bits(bcm, -1, -1); - } - phy->is_locked = 0; -} - -u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset) -{ - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset); - return bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_DATA); -} - -void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val) -{ - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_DATA, val); -} - -void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - unsigned long flags; - - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */ - if (phy->calibrated) - return; - if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) { - /* We do not want to be preempted while calibrating - * the hardware. - */ - local_irq_save(flags); - - bcm43xx_wireless_core_reset(bcm, 0); - bcm43xx_phy_initg(bcm); - bcm43xx_wireless_core_reset(bcm, 1); - - local_irq_restore(flags); - } - phy->calibrated = 1; -} - -/* Connect the PHY - * http://bcm-specs.sipsolutions.net/SetPHY - */ -int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u32 flags; - - if (bcm->current_core->rev < 5) - goto out; - - flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (connect) { - if (!(flags & 0x00010000)) - return -ENODEV; - flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - flags |= (0x800 << 18); - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags); - } else { - if (!(flags & 0x00020000)) - return -ENODEV; - flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - flags &= ~(0x800 << 18); - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags); - } -out: - phy->connected = connect; - if (connect) - dprintk(KERN_INFO PFX "PHY connected\n"); - else - dprintk(KERN_INFO PFX "PHY disconnected\n"); - - return 0; -} - -/* intialize B PHY power control - * as described in http://bcm-specs.sipsolutions.net/InitPowerControl - */ -static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 saved_batt = 0, saved_ratt = 0, saved_txctl1 = 0; - int must_reset_txpower = 0; - - assert(phy->type != BCM43xx_PHYTYPE_A); - if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) && - (bcm->board_type == 0x0416)) - return; - - bcm43xx_write16(bcm, 0x03E6, bcm43xx_read16(bcm, 0x03E6) & 0xFFDF); - bcm43xx_phy_write(bcm, 0x0028, 0x8018); - - if (phy->type == BCM43xx_PHYTYPE_G) { - if (!phy->connected) - return; - bcm43xx_phy_write(bcm, 0x047A, 0xC111); - } - if (phy->savedpctlreg != 0xFFFF) - return; - - if (phy->type == BCM43xx_PHYTYPE_B && - phy->rev >= 2 && - radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0076, - bcm43xx_radio_read16(bcm, 0x0076) | 0x0084); - } else { - saved_batt = radio->baseband_atten; - saved_ratt = radio->radio_atten; - saved_txctl1 = radio->txctl1; - if ((radio->revision >= 6) && (radio->revision <= 8) - && /*FIXME: incomplete specs for 5 < revision < 9 */ 0) - bcm43xx_radio_set_txpower_bg(bcm, 0xB, 0x1F, 0); - else - bcm43xx_radio_set_txpower_bg(bcm, 0xB, 9, 0); - must_reset_txpower = 1; - } - bcm43xx_dummy_transmission(bcm); - - phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_PCTL); - - if (must_reset_txpower) - bcm43xx_radio_set_txpower_bg(bcm, saved_batt, saved_ratt, saved_txctl1); - else - bcm43xx_radio_write16(bcm, 0x0076, bcm43xx_radio_read16(bcm, 0x0076) & 0xFF7B); - bcm43xx_radio_clear_tssi(bcm); -} - -static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 offset = 0x0000; - - if (phy->rev == 1) - offset = 0x4C00; - - bcm43xx_ilt_write(bcm, offset, 0x00FE); - bcm43xx_ilt_write(bcm, offset + 1, 0x000D); - bcm43xx_ilt_write(bcm, offset + 2, 0x0013); - bcm43xx_ilt_write(bcm, offset + 3, 0x0019); - - if (phy->rev == 1) { - bcm43xx_ilt_write(bcm, 0x1800, 0x2710); - bcm43xx_ilt_write(bcm, 0x1801, 0x9B83); - bcm43xx_ilt_write(bcm, 0x1802, 0x9B83); - bcm43xx_ilt_write(bcm, 0x1803, 0x0F8D); - bcm43xx_phy_write(bcm, 0x0455, 0x0004); - } - - bcm43xx_phy_write(bcm, 0x04A5, (bcm43xx_phy_read(bcm, 0x04A5) & 0x00FF) | 0x5700); - bcm43xx_phy_write(bcm, 0x041A, (bcm43xx_phy_read(bcm, 0x041A) & 0xFF80) | 0x000F); - bcm43xx_phy_write(bcm, 0x041A, (bcm43xx_phy_read(bcm, 0x041A) & 0xC07F) | 0x2B80); - bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C) & 0xF0FF) | 0x0300); - - bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0008); - - bcm43xx_phy_write(bcm, 0x04A0, (bcm43xx_phy_read(bcm, 0x04A0) & 0xFFF0) | 0x0008); - bcm43xx_phy_write(bcm, 0x04A1, (bcm43xx_phy_read(bcm, 0x04A1) & 0xF0FF) | 0x0600); - bcm43xx_phy_write(bcm, 0x04A2, (bcm43xx_phy_read(bcm, 0x04A2) & 0xF0FF) | 0x0700); - bcm43xx_phy_write(bcm, 0x04A0, (bcm43xx_phy_read(bcm, 0x04A0) & 0xF0FF) | 0x0100); - - if (phy->rev == 1) - bcm43xx_phy_write(bcm, 0x04A2, (bcm43xx_phy_read(bcm, 0x04A2) & 0xFFF0) | 0x0007); - - bcm43xx_phy_write(bcm, 0x0488, (bcm43xx_phy_read(bcm, 0x0488) & 0xFF00) | 0x001C); - bcm43xx_phy_write(bcm, 0x0488, (bcm43xx_phy_read(bcm, 0x0488) & 0xC0FF) | 0x0200); - bcm43xx_phy_write(bcm, 0x0496, (bcm43xx_phy_read(bcm, 0x0496) & 0xFF00) | 0x001C); - bcm43xx_phy_write(bcm, 0x0489, (bcm43xx_phy_read(bcm, 0x0489) & 0xFF00) | 0x0020); - bcm43xx_phy_write(bcm, 0x0489, (bcm43xx_phy_read(bcm, 0x0489) & 0xC0FF) | 0x0200); - bcm43xx_phy_write(bcm, 0x0482, (bcm43xx_phy_read(bcm, 0x0482) & 0xFF00) | 0x002E); - bcm43xx_phy_write(bcm, 0x0496, (bcm43xx_phy_read(bcm, 0x0496) & 0x00FF) | 0x1A00); - bcm43xx_phy_write(bcm, 0x0481, (bcm43xx_phy_read(bcm, 0x0481) & 0xFF00) | 0x0028); - bcm43xx_phy_write(bcm, 0x0481, (bcm43xx_phy_read(bcm, 0x0481) & 0x00FF) | 0x2C00); - - if (phy->rev == 1) { - bcm43xx_phy_write(bcm, 0x0430, 0x092B); - bcm43xx_phy_write(bcm, 0x041B, (bcm43xx_phy_read(bcm, 0x041B) & 0xFFE1) | 0x0002); - } else { - bcm43xx_phy_write(bcm, 0x041B, bcm43xx_phy_read(bcm, 0x041B) & 0xFFE1); - bcm43xx_phy_write(bcm, 0x041F, 0x287A); - bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420) & 0xFFF0) | 0x0004); - } - - if (phy->rev > 2) { - bcm43xx_phy_write(bcm, 0x0422, 0x287A); - bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420) & 0x0FFF) | 0x3000); - } - - bcm43xx_phy_write(bcm, 0x04A8, (bcm43xx_phy_read(bcm, 0x04A8) & 0x8080) | 0x7874); - bcm43xx_phy_write(bcm, 0x048E, 0x1C00); - - if (phy->rev == 1) { - bcm43xx_phy_write(bcm, 0x04AB, (bcm43xx_phy_read(bcm, 0x04AB) & 0xF0FF) | 0x0600); - bcm43xx_phy_write(bcm, 0x048B, 0x005E); - bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C) & 0xFF00) | 0x001E); - bcm43xx_phy_write(bcm, 0x048D, 0x0002); - } - - bcm43xx_ilt_write(bcm, offset + 0x0800, 0); - bcm43xx_ilt_write(bcm, offset + 0x0801, 7); - bcm43xx_ilt_write(bcm, offset + 0x0802, 16); - bcm43xx_ilt_write(bcm, offset + 0x0803, 28); -} - -static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 i; - - assert(phy->type == BCM43xx_PHYTYPE_G); - if (phy->rev == 1) { - bcm43xx_phy_write(bcm, 0x0406, 0x4F19); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0xFC3F) | 0x0340); - bcm43xx_phy_write(bcm, 0x042C, 0x005A); - bcm43xx_phy_write(bcm, 0x0427, 0x001A); - - for (i = 0; i < BCM43xx_ILT_FINEFREQG_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqg[i]); - for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]); - for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]); - } else { - /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */ - bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654); - - if (phy->rev == 2) { - bcm43xx_phy_write(bcm, 0x04C0, 0x1861); - bcm43xx_phy_write(bcm, 0x04C1, 0x0271); - } else if (phy->rev > 2) { - bcm43xx_phy_write(bcm, 0x04C0, 0x0098); - bcm43xx_phy_write(bcm, 0x04C1, 0x0070); - bcm43xx_phy_write(bcm, 0x04C9, 0x0080); - } - bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x800); - - for (i = 0; i < 64; i++) - bcm43xx_ilt_write(bcm, 0x4000 + i, i); - for (i = 0; i < BCM43xx_ILT_NOISEG2_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg2[i]); - } - - if (phy->rev <= 2) - for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]); - else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200)) - for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]); - else - for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg2[i]); - - if (phy->rev == 2) - for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); - else if ((phy->rev > 2) && (phy->rev <= 7)) - for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]); - - if (phy->rev == 1) { - for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]); - for (i = 0; i < 4; i++) { - bcm43xx_ilt_write(bcm, 0x5404 + i, 0x0020); - bcm43xx_ilt_write(bcm, 0x5408 + i, 0x0020); - bcm43xx_ilt_write(bcm, 0x540C + i, 0x0020); - bcm43xx_ilt_write(bcm, 0x5410 + i, 0x0020); - } - bcm43xx_phy_agcsetup(bcm); - - if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) && - (bcm->board_type == 0x0416) && - (bcm->board_revision == 0x0017)) - return; - - bcm43xx_ilt_write(bcm, 0x5001, 0x0002); - bcm43xx_ilt_write(bcm, 0x5002, 0x0001); - } else { - for (i = 0; i <= 0x2F; i++) - bcm43xx_ilt_write(bcm, 0x1000 + i, 0x0820); - bcm43xx_phy_agcsetup(bcm); - bcm43xx_phy_read(bcm, 0x0400); /* dummy read */ - bcm43xx_phy_write(bcm, 0x0403, 0x1000); - bcm43xx_ilt_write(bcm, 0x3C02, 0x000F); - bcm43xx_ilt_write(bcm, 0x3C03, 0x0014); - - if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) && - (bcm->board_type == 0x0416) && - (bcm->board_revision == 0x0017)) - return; - - bcm43xx_ilt_write(bcm, 0x0401, 0x0002); - bcm43xx_ilt_write(bcm, 0x0402, 0x0001); - } -} - -/* Initialize the noisescaletable for APHY */ -static void bcm43xx_phy_init_noisescaletbl(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - int i; - - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, 0x1400); - for (i = 0; i < 12; i++) { - if (phy->rev == 2) - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6767); - else - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2323); - } - if (phy->rev == 2) - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6700); - else - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2300); - for (i = 0; i < 11; i++) { - if (phy->rev == 2) - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6767); - else - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2323); - } - if (phy->rev == 2) - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x0067); - else - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x0023); -} - -static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 i; - - assert(phy->type == BCM43xx_PHYTYPE_A); - switch (phy->rev) { - case 2: - bcm43xx_phy_write(bcm, 0x008E, 0x3800); - bcm43xx_phy_write(bcm, 0x0035, 0x03FF); - bcm43xx_phy_write(bcm, 0x0036, 0x0400); - - bcm43xx_ilt_write(bcm, 0x3807, 0x0051); - - bcm43xx_phy_write(bcm, 0x001C, 0x0FF9); - bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F); - bcm43xx_ilt_write(bcm, 0x3C0C, 0x07BF); - bcm43xx_radio_write16(bcm, 0x0002, 0x07BF); - - bcm43xx_phy_write(bcm, 0x0024, 0x4680); - bcm43xx_phy_write(bcm, 0x0020, 0x0003); - bcm43xx_phy_write(bcm, 0x001D, 0x0F40); - bcm43xx_phy_write(bcm, 0x001F, 0x1C00); - - bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400); - bcm43xx_phy_write(bcm, 0x002B, bcm43xx_phy_read(bcm, 0x002B) & 0xFBFF); - bcm43xx_phy_write(bcm, 0x008E, 0x58C1); - - bcm43xx_ilt_write(bcm, 0x0803, 0x000F); - bcm43xx_ilt_write(bcm, 0x0804, 0x001F); - bcm43xx_ilt_write(bcm, 0x0805, 0x002A); - bcm43xx_ilt_write(bcm, 0x0805, 0x0030); - bcm43xx_ilt_write(bcm, 0x0807, 0x003A); - - bcm43xx_ilt_write(bcm, 0x0000, 0x0013); - bcm43xx_ilt_write(bcm, 0x0001, 0x0013); - bcm43xx_ilt_write(bcm, 0x0002, 0x0013); - bcm43xx_ilt_write(bcm, 0x0003, 0x0013); - bcm43xx_ilt_write(bcm, 0x0004, 0x0015); - bcm43xx_ilt_write(bcm, 0x0005, 0x0015); - bcm43xx_ilt_write(bcm, 0x0006, 0x0019); - - bcm43xx_ilt_write(bcm, 0x0404, 0x0003); - bcm43xx_ilt_write(bcm, 0x0405, 0x0003); - bcm43xx_ilt_write(bcm, 0x0406, 0x0007); - - for (i = 0; i < 16; i++) - bcm43xx_ilt_write(bcm, 0x4000 + i, (0x8 + i) & 0x000F); - - bcm43xx_ilt_write(bcm, 0x3003, 0x1044); - bcm43xx_ilt_write(bcm, 0x3004, 0x7201); - bcm43xx_ilt_write(bcm, 0x3006, 0x0040); - bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008); - - for (i = 0; i < BCM43xx_ILT_FINEFREQA_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqa[i]); - for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]); - for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]); - bcm43xx_phy_init_noisescaletbl(bcm); - for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]); - break; - case 3: - for (i = 0; i < 64; i++) - bcm43xx_ilt_write(bcm, 0x4000 + i, i); - - bcm43xx_ilt_write(bcm, 0x3807, 0x0051); - - bcm43xx_phy_write(bcm, 0x001C, 0x0FF9); - bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F); - bcm43xx_radio_write16(bcm, 0x0002, 0x07BF); - - bcm43xx_phy_write(bcm, 0x0024, 0x4680); - bcm43xx_phy_write(bcm, 0x0020, 0x0003); - bcm43xx_phy_write(bcm, 0x001D, 0x0F40); - bcm43xx_phy_write(bcm, 0x001F, 0x1C00); - bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400); - - bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008); - for (i = 0; i < BCM43xx_ILT_NOISEA3_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea3[i]); - bcm43xx_phy_init_noisescaletbl(bcm); - for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); - - bcm43xx_phy_write(bcm, 0x0003, 0x1808); - - bcm43xx_ilt_write(bcm, 0x0803, 0x000F); - bcm43xx_ilt_write(bcm, 0x0804, 0x001F); - bcm43xx_ilt_write(bcm, 0x0805, 0x002A); - bcm43xx_ilt_write(bcm, 0x0805, 0x0030); - bcm43xx_ilt_write(bcm, 0x0807, 0x003A); - - bcm43xx_ilt_write(bcm, 0x0000, 0x0013); - bcm43xx_ilt_write(bcm, 0x0001, 0x0013); - bcm43xx_ilt_write(bcm, 0x0002, 0x0013); - bcm43xx_ilt_write(bcm, 0x0003, 0x0013); - bcm43xx_ilt_write(bcm, 0x0004, 0x0015); - bcm43xx_ilt_write(bcm, 0x0005, 0x0015); - bcm43xx_ilt_write(bcm, 0x0006, 0x0019); - - bcm43xx_ilt_write(bcm, 0x0404, 0x0003); - bcm43xx_ilt_write(bcm, 0x0405, 0x0003); - bcm43xx_ilt_write(bcm, 0x0406, 0x0007); - - bcm43xx_ilt_write(bcm, 0x3C02, 0x000F); - bcm43xx_ilt_write(bcm, 0x3C03, 0x0014); - break; - default: - assert(0); - } -} - -/* Initialize APHY. This is also called for the GPHY in some cases. */ -static void bcm43xx_phy_inita(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 tval; - - if (phy->type == BCM43xx_PHYTYPE_A) { - bcm43xx_phy_setupa(bcm); - } else { - bcm43xx_phy_setupg(bcm); - if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) - bcm43xx_phy_write(bcm, 0x046E, 0x03CF); - return; - } - - bcm43xx_phy_write(bcm, BCM43xx_PHY_A_CRS, - (bcm43xx_phy_read(bcm, BCM43xx_PHY_A_CRS) & 0xF83C) | 0x0340); - bcm43xx_phy_write(bcm, 0x0034, 0x0001); - - TODO();//TODO: RSSI AGC - bcm43xx_phy_write(bcm, BCM43xx_PHY_A_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_A_CRS) | (1 << 14)); - bcm43xx_radio_init2060(bcm); - - if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) - && ((bcm->board_type == 0x0416) || (bcm->board_type == 0x040A))) { - if (radio->lofcal == 0xFFFF) { - TODO();//TODO: LOF Cal - bcm43xx_radio_set_tx_iq(bcm); - } else - bcm43xx_radio_write16(bcm, 0x001E, radio->lofcal); - } - - bcm43xx_phy_write(bcm, 0x007A, 0xF111); - - if (phy->savedpctlreg == 0xFFFF) { - bcm43xx_radio_write16(bcm, 0x0019, 0x0000); - bcm43xx_radio_write16(bcm, 0x0017, 0x0020); - - tval = bcm43xx_ilt_read(bcm, 0x3001); - if (phy->rev == 1) { - bcm43xx_ilt_write(bcm, 0x3001, - (bcm43xx_ilt_read(bcm, 0x3001) & 0xFF87) - | 0x0058); - } else { - bcm43xx_ilt_write(bcm, 0x3001, - (bcm43xx_ilt_read(bcm, 0x3001) & 0xFFC3) - | 0x002C); - } - bcm43xx_dummy_transmission(bcm); - phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_A_PCTL); - bcm43xx_ilt_write(bcm, 0x3001, tval); - - bcm43xx_radio_set_txpower_a(bcm, 0x0018); - } - bcm43xx_radio_clear_tssi(bcm); -} - -static void bcm43xx_phy_initb2(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 offset, val; - - bcm43xx_write16(bcm, 0x03EC, 0x3F22); - bcm43xx_phy_write(bcm, 0x0020, 0x301C); - bcm43xx_phy_write(bcm, 0x0026, 0x0000); - bcm43xx_phy_write(bcm, 0x0030, 0x00C6); - bcm43xx_phy_write(bcm, 0x0088, 0x3E00); - val = 0x3C3D; - for (offset = 0x0089; offset < 0x00A7; offset++) { - bcm43xx_phy_write(bcm, offset, val); - val -= 0x0202; - } - bcm43xx_phy_write(bcm, 0x03E4, 0x3000); - if (radio->channel == 0xFF) - bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); - else - bcm43xx_radio_selectchannel(bcm, radio->channel, 0); - if (radio->version != 0x2050) { - bcm43xx_radio_write16(bcm, 0x0075, 0x0080); - bcm43xx_radio_write16(bcm, 0x0079, 0x0081); - } - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x0050, 0x0023); - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x005A, 0x0070); - bcm43xx_radio_write16(bcm, 0x005B, 0x007B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); - bcm43xx_radio_write16(bcm, 0x007A, 0x000F); - bcm43xx_phy_write(bcm, 0x0038, 0x0677); - bcm43xx_radio_init2050(bcm); - } - bcm43xx_phy_write(bcm, 0x0014, 0x0080); - bcm43xx_phy_write(bcm, 0x0032, 0x00CA); - bcm43xx_phy_write(bcm, 0x0032, 0x00CC); - bcm43xx_phy_write(bcm, 0x0035, 0x07C2); - bcm43xx_phy_lo_b_measure(bcm); - bcm43xx_phy_write(bcm, 0x0026, 0xCC00); - if (radio->version != 0x2050) - bcm43xx_phy_write(bcm, 0x0026, 0xCE00); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x1000); - bcm43xx_phy_write(bcm, 0x002A, 0x88A3); - if (radio->version != 0x2050) - bcm43xx_phy_write(bcm, 0x002A, 0x88C2); - bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); - bcm43xx_phy_init_pctl(bcm); -} - -static void bcm43xx_phy_initb4(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 offset, val; - - bcm43xx_write16(bcm, 0x03EC, 0x3F22); - bcm43xx_phy_write(bcm, 0x0020, 0x301C); - bcm43xx_phy_write(bcm, 0x0026, 0x0000); - bcm43xx_phy_write(bcm, 0x0030, 0x00C6); - bcm43xx_phy_write(bcm, 0x0088, 0x3E00); - val = 0x3C3D; - for (offset = 0x0089; offset < 0x00A7; offset++) { - bcm43xx_phy_write(bcm, offset, val); - val -= 0x0202; - } - bcm43xx_phy_write(bcm, 0x03E4, 0x3000); - if (radio->channel == 0xFF) - bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); - else - bcm43xx_radio_selectchannel(bcm, radio->channel, 0); - if (radio->version != 0x2050) { - bcm43xx_radio_write16(bcm, 0x0075, 0x0080); - bcm43xx_radio_write16(bcm, 0x0079, 0x0081); - } - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x0050, 0x0023); - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x005A, 0x0070); - bcm43xx_radio_write16(bcm, 0x005B, 0x007B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); - bcm43xx_radio_write16(bcm, 0x007A, 0x000F); - bcm43xx_phy_write(bcm, 0x0038, 0x0677); - bcm43xx_radio_init2050(bcm); - } - bcm43xx_phy_write(bcm, 0x0014, 0x0080); - bcm43xx_phy_write(bcm, 0x0032, 0x00CA); - if (radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x0032, 0x00E0); - bcm43xx_phy_write(bcm, 0x0035, 0x07C2); - - bcm43xx_phy_lo_b_measure(bcm); - - bcm43xx_phy_write(bcm, 0x0026, 0xCC00); - if (radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x0026, 0xCE00); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x1100); - bcm43xx_phy_write(bcm, 0x002A, 0x88A3); - if (radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x002A, 0x88C2); - bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); - if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { - bcm43xx_calc_nrssi_slope(bcm); - bcm43xx_calc_nrssi_threshold(bcm); - } - bcm43xx_phy_init_pctl(bcm); -} - -static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 offset; - - if (phy->version == 1 && - radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) - | 0x0050); - } - if ((bcm->board_vendor != PCI_VENDOR_ID_BROADCOM) && - (bcm->board_type != 0x0416)) { - for (offset = 0x00A8 ; offset < 0x00C7; offset++) { - bcm43xx_phy_write(bcm, offset, - (bcm43xx_phy_read(bcm, offset) + 0x2020) - & 0x3F3F); - } - } - bcm43xx_phy_write(bcm, 0x0035, - (bcm43xx_phy_read(bcm, 0x0035) & 0xF0FF) - | 0x0700); - if (radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x0038, 0x0667); - - if (phy->connected) { - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) - | 0x0020); - bcm43xx_radio_write16(bcm, 0x0051, - bcm43xx_radio_read16(bcm, 0x0051) - | 0x0004); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO, 0x0000); - - bcm43xx_phy_write(bcm, 0x0802, bcm43xx_phy_read(bcm, 0x0802) | 0x0100); - bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x2000); - - bcm43xx_phy_write(bcm, 0x001C, 0x186A); - - bcm43xx_phy_write(bcm, 0x0013, (bcm43xx_phy_read(bcm, 0x0013) & 0x00FF) | 0x1900); - bcm43xx_phy_write(bcm, 0x0035, (bcm43xx_phy_read(bcm, 0x0035) & 0xFFC0) | 0x0064); - bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D) & 0xFF80) | 0x000A); - } - - if (bcm->bad_frames_preempt) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, - bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | (1 << 11)); - } - - if (phy->version == 1 && radio->version == 0x2050) { - bcm43xx_phy_write(bcm, 0x0026, 0xCE00); - bcm43xx_phy_write(bcm, 0x0021, 0x3763); - bcm43xx_phy_write(bcm, 0x0022, 0x1BC3); - bcm43xx_phy_write(bcm, 0x0023, 0x06F9); - bcm43xx_phy_write(bcm, 0x0024, 0x037E); - } else - bcm43xx_phy_write(bcm, 0x0026, 0xCC00); - bcm43xx_phy_write(bcm, 0x0030, 0x00C6); - bcm43xx_write16(bcm, 0x03EC, 0x3F22); - - if (phy->version == 1 && radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x0020, 0x3E1C); - else - bcm43xx_phy_write(bcm, 0x0020, 0x301C); - - if (phy->version == 0) - bcm43xx_write16(bcm, 0x03E4, 0x3000); - - /* Force to channel 7, even if not supported. */ - bcm43xx_radio_selectchannel(bcm, 7, 0); - - if (radio->version != 0x2050) { - bcm43xx_radio_write16(bcm, 0x0075, 0x0080); - bcm43xx_radio_write16(bcm, 0x0079, 0x0081); - } - - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x0050, 0x0023); - - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x005A, 0x0070); - } - - bcm43xx_radio_write16(bcm, 0x005B, 0x007B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); - - bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0007); - - bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); - - bcm43xx_phy_write(bcm, 0x0014, 0x0080); - bcm43xx_phy_write(bcm, 0x0032, 0x00CA); - bcm43xx_phy_write(bcm, 0x88A3, 0x002A); - - bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); - - if (radio->version == 0x2050) - bcm43xx_radio_write16(bcm, 0x005D, 0x000D); - - bcm43xx_write16(bcm, 0x03E4, (bcm43xx_read16(bcm, 0x03E4) & 0xFFC0) | 0x0004); -} - -static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 offset, val; - - bcm43xx_phy_write(bcm, 0x003E, 0x817A); - bcm43xx_radio_write16(bcm, 0x007A, - (bcm43xx_radio_read16(bcm, 0x007A) | 0x0058)); - if ((radio->manufact == 0x17F) && - (radio->version == 0x2050) && - (radio->revision == 3 || - radio->revision == 4 || - radio->revision == 5)) { - bcm43xx_radio_write16(bcm, 0x0051, 0x001F); - bcm43xx_radio_write16(bcm, 0x0052, 0x0040); - bcm43xx_radio_write16(bcm, 0x0053, 0x005B); - bcm43xx_radio_write16(bcm, 0x0054, 0x0098); - bcm43xx_radio_write16(bcm, 0x005A, 0x0088); - bcm43xx_radio_write16(bcm, 0x005B, 0x0088); - bcm43xx_radio_write16(bcm, 0x005D, 0x0088); - bcm43xx_radio_write16(bcm, 0x005E, 0x0088); - bcm43xx_radio_write16(bcm, 0x007D, 0x0088); - } - if ((radio->manufact == 0x17F) && - (radio->version == 0x2050) && - (radio->revision == 6)) { - bcm43xx_radio_write16(bcm, 0x0051, 0x0000); - bcm43xx_radio_write16(bcm, 0x0052, 0x0040); - bcm43xx_radio_write16(bcm, 0x0053, 0x00B7); - bcm43xx_radio_write16(bcm, 0x0054, 0x0098); - bcm43xx_radio_write16(bcm, 0x005A, 0x0088); - bcm43xx_radio_write16(bcm, 0x005B, 0x008B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B5); - bcm43xx_radio_write16(bcm, 0x005D, 0x0088); - bcm43xx_radio_write16(bcm, 0x005E, 0x0088); - bcm43xx_radio_write16(bcm, 0x007D, 0x0088); - bcm43xx_radio_write16(bcm, 0x007C, 0x0001); - bcm43xx_radio_write16(bcm, 0x007E, 0x0008); - } - if ((radio->manufact == 0x17F) && - (radio->version == 0x2050) && - (radio->revision == 7)) { - bcm43xx_radio_write16(bcm, 0x0051, 0x0000); - bcm43xx_radio_write16(bcm, 0x0052, 0x0040); - bcm43xx_radio_write16(bcm, 0x0053, 0x00B7); - bcm43xx_radio_write16(bcm, 0x0054, 0x0098); - bcm43xx_radio_write16(bcm, 0x005A, 0x0088); - bcm43xx_radio_write16(bcm, 0x005B, 0x00A8); - bcm43xx_radio_write16(bcm, 0x005C, 0x0075); - bcm43xx_radio_write16(bcm, 0x005D, 0x00F5); - bcm43xx_radio_write16(bcm, 0x005E, 0x00B8); - bcm43xx_radio_write16(bcm, 0x007D, 0x00E8); - bcm43xx_radio_write16(bcm, 0x007C, 0x0001); - bcm43xx_radio_write16(bcm, 0x007E, 0x0008); - bcm43xx_radio_write16(bcm, 0x007B, 0x0000); - } - if ((radio->manufact == 0x17F) && - (radio->version == 0x2050) && - (radio->revision == 8)) { - bcm43xx_radio_write16(bcm, 0x0051, 0x0000); - bcm43xx_radio_write16(bcm, 0x0052, 0x0040); - bcm43xx_radio_write16(bcm, 0x0053, 0x00B7); - bcm43xx_radio_write16(bcm, 0x0054, 0x0098); - bcm43xx_radio_write16(bcm, 0x005A, 0x0088); - bcm43xx_radio_write16(bcm, 0x005B, 0x006B); - bcm43xx_radio_write16(bcm, 0x005C, 0x000F); - if (bcm->sprom.boardflags & 0x8000) { - bcm43xx_radio_write16(bcm, 0x005D, 0x00FA); - bcm43xx_radio_write16(bcm, 0x005E, 0x00D8); - } else { - bcm43xx_radio_write16(bcm, 0x005D, 0x00F5); - bcm43xx_radio_write16(bcm, 0x005E, 0x00B8); - } - bcm43xx_radio_write16(bcm, 0x0073, 0x0003); - bcm43xx_radio_write16(bcm, 0x007D, 0x00A8); - bcm43xx_radio_write16(bcm, 0x007C, 0x0001); - bcm43xx_radio_write16(bcm, 0x007E, 0x0008); - } - val = 0x1E1F; - for (offset = 0x0088; offset < 0x0098; offset++) { - bcm43xx_phy_write(bcm, offset, val); - val -= 0x0202; - } - val = 0x3E3F; - for (offset = 0x0098; offset < 0x00A8; offset++) { - bcm43xx_phy_write(bcm, offset, val); - val -= 0x0202; - } - val = 0x2120; - for (offset = 0x00A8; offset < 0x00C8; offset++) { - bcm43xx_phy_write(bcm, offset, (val & 0x3F3F)); - val += 0x0202; - } - if (phy->type == BCM43xx_PHYTYPE_G) { - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0020); - bcm43xx_radio_write16(bcm, 0x0051, - bcm43xx_radio_read16(bcm, 0x0051) | 0x0004); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) | 0x0100); - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) | 0x2000); - } - - /* Force to channel 7, even if not supported. */ - bcm43xx_radio_selectchannel(bcm, 7, 0); - - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x0050, 0x0023); - udelay(40); - bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C) | 0x0002)); - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - if (radio->manufact == 0x17F && - radio->version == 0x2050 && - radio->revision <= 2) { - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x005A, 0x0070); - bcm43xx_radio_write16(bcm, 0x005B, 0x007B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); - } - bcm43xx_radio_write16(bcm, 0x007A, - (bcm43xx_radio_read16(bcm, 0x007A) & 0x00F8) | 0x0007); - - bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); - - bcm43xx_phy_write(bcm, 0x0014, 0x0200); - if (radio->version == 0x2050){ - if (radio->revision == 3 || - radio->revision == 4 || - radio->revision == 5) - bcm43xx_phy_write(bcm, 0x002A, 0x8AC0); - else - bcm43xx_phy_write(bcm, 0x002A, 0x88C2); - } - bcm43xx_phy_write(bcm, 0x0038, 0x0668); - bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); - if (radio->version == 0x2050) { - if (radio->revision == 3 || - radio->revision == 4 || - radio->revision == 5) - bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003); - else if (radio->revision <= 2) - bcm43xx_radio_write16(bcm, 0x005D, 0x000D); - } - - if (phy->rev == 4) - bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004); - else - bcm43xx_write16(bcm, 0x03E4, 0x0009); - if (phy->type == BCM43xx_PHYTYPE_B) { - bcm43xx_write16(bcm, 0x03E6, 0x8140); - bcm43xx_phy_write(bcm, 0x0016, 0x0410); - bcm43xx_phy_write(bcm, 0x0017, 0x0820); - bcm43xx_phy_write(bcm, 0x0062, 0x0007); - (void) bcm43xx_radio_calibrationvalue(bcm); - bcm43xx_phy_lo_b_measure(bcm); - if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { - bcm43xx_calc_nrssi_slope(bcm); - bcm43xx_calc_nrssi_threshold(bcm); - } - bcm43xx_phy_init_pctl(bcm); - } else - bcm43xx_write16(bcm, 0x03E6, 0x0); -} - -static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 backup_phy[15]; - u16 backup_radio[3]; - u16 backup_bband; - u16 i; - u16 loop1_cnt, loop1_done, loop1_omitted; - u16 loop2_done; - - backup_phy[0] = bcm43xx_phy_read(bcm, 0x0429); - backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001); - backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811); - backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812); - backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814); - backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815); - backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A); - backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059); - backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058); - backup_phy[9] = bcm43xx_phy_read(bcm, 0x000A); - backup_phy[10] = bcm43xx_phy_read(bcm, 0x0003); - backup_phy[11] = bcm43xx_phy_read(bcm, 0x080F); - backup_phy[12] = bcm43xx_phy_read(bcm, 0x0810); - backup_phy[13] = bcm43xx_phy_read(bcm, 0x002B); - backup_phy[14] = bcm43xx_phy_read(bcm, 0x0015); - bcm43xx_phy_read(bcm, 0x002D); /* dummy read */ - backup_bband = radio->baseband_atten; - backup_radio[0] = bcm43xx_radio_read16(bcm, 0x0052); - backup_radio[1] = bcm43xx_radio_read16(bcm, 0x0043); - backup_radio[2] = bcm43xx_radio_read16(bcm, 0x007A); - - bcm43xx_phy_write(bcm, 0x0429, - bcm43xx_phy_read(bcm, 0x0429) & 0x3FFF); - bcm43xx_phy_write(bcm, 0x0001, - bcm43xx_phy_read(bcm, 0x0001) & 0x8000); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x0002); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) & 0xFFFD); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x0001); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE); - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0001); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE); - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0002); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x000C); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) | 0x000C); - - bcm43xx_phy_write(bcm, 0x0811, - (bcm43xx_phy_read(bcm, 0x0811) - & 0xFFCF) | 0x0030); - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) - & 0xFFCF) | 0x0010); - - bcm43xx_phy_write(bcm, 0x005A, 0x0780); - bcm43xx_phy_write(bcm, 0x0059, 0xC810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - if (phy->version == 0) { - bcm43xx_phy_write(bcm, 0x0003, 0x0122); - } else { - bcm43xx_phy_write(bcm, 0x000A, - bcm43xx_phy_read(bcm, 0x000A) - | 0x2000); - } - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0004); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB); - bcm43xx_phy_write(bcm, 0x0003, - (bcm43xx_phy_read(bcm, 0x0003) - & 0xFF9F) | 0x0040); - if (radio->version == 0x2050 && radio->revision == 2) { - bcm43xx_radio_write16(bcm, 0x0052, 0x0000); - bcm43xx_radio_write16(bcm, 0x0043, - (bcm43xx_radio_read16(bcm, 0x0043) - & 0xFFF0) | 0x0009); - loop1_cnt = 9; - } else if (radio->revision == 8) { - bcm43xx_radio_write16(bcm, 0x0043, 0x000F); - loop1_cnt = 15; - } else - loop1_cnt = 0; - - bcm43xx_phy_set_baseband_attenuation(bcm, 11); - - if (phy->rev >= 3) - bcm43xx_phy_write(bcm, 0x080F, 0xC020); - else - bcm43xx_phy_write(bcm, 0x080F, 0x8020); - bcm43xx_phy_write(bcm, 0x0810, 0x0000); - - bcm43xx_phy_write(bcm, 0x002B, - (bcm43xx_phy_read(bcm, 0x002B) - & 0xFFC0) | 0x0001); - bcm43xx_phy_write(bcm, 0x002B, - (bcm43xx_phy_read(bcm, 0x002B) - & 0xC0FF) | 0x0800); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x0100); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) & 0xCFFF); - if (bcm->sprom.boardflags & BCM43xx_BFL_EXTLNA) { - if (phy->rev >= 7) { - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) - | 0x0800); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) - | 0x8000); - } - } - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) - & 0x00F7); - - for (i = 0; i < loop1_cnt; i++) { - bcm43xx_radio_write16(bcm, 0x0043, loop1_cnt); - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) - & 0xF0FF) | (i << 8)); - bcm43xx_phy_write(bcm, 0x0015, - (bcm43xx_phy_read(bcm, 0x0015) - & 0x0FFF) | 0xA000); - bcm43xx_phy_write(bcm, 0x0015, - (bcm43xx_phy_read(bcm, 0x0015) - & 0x0FFF) | 0xF000); - udelay(20); - if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC) - break; - } - loop1_done = i; - loop1_omitted = loop1_cnt - loop1_done; - - loop2_done = 0; - if (loop1_done >= 8) { - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) - | 0x0030); - for (i = loop1_done - 8; i < 16; i++) { - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) - & 0xF0FF) | (i << 8)); - bcm43xx_phy_write(bcm, 0x0015, - (bcm43xx_phy_read(bcm, 0x0015) - & 0x0FFF) | 0xA000); - bcm43xx_phy_write(bcm, 0x0015, - (bcm43xx_phy_read(bcm, 0x0015) - & 0x0FFF) | 0xF000); - udelay(20); - if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC) - break; - } - } - - bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]); - bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]); - bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]); - bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]); - bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]); - bcm43xx_phy_write(bcm, 0x000A, backup_phy[9]); - bcm43xx_phy_write(bcm, 0x0003, backup_phy[10]); - bcm43xx_phy_write(bcm, 0x080F, backup_phy[11]); - bcm43xx_phy_write(bcm, 0x0810, backup_phy[12]); - bcm43xx_phy_write(bcm, 0x002B, backup_phy[13]); - bcm43xx_phy_write(bcm, 0x0015, backup_phy[14]); - - bcm43xx_phy_set_baseband_attenuation(bcm, backup_bband); - - bcm43xx_radio_write16(bcm, 0x0052, backup_radio[0]); - bcm43xx_radio_write16(bcm, 0x0043, backup_radio[1]); - bcm43xx_radio_write16(bcm, 0x007A, backup_radio[2]); - - bcm43xx_phy_write(bcm, 0x0811, backup_phy[2] | 0x0003); - udelay(10); - bcm43xx_phy_write(bcm, 0x0811, backup_phy[2]); - bcm43xx_phy_write(bcm, 0x0812, backup_phy[3]); - bcm43xx_phy_write(bcm, 0x0429, backup_phy[0]); - bcm43xx_phy_write(bcm, 0x0001, backup_phy[1]); - - phy->loopback_gain[0] = ((loop1_done * 6) - (loop1_omitted * 4)) - 11; - phy->loopback_gain[1] = (24 - (3 * loop2_done)) * 2; -} - -static void bcm43xx_phy_initg(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 tmp; - - if (phy->rev == 1) - bcm43xx_phy_initb5(bcm); - else if (phy->rev >= 2 && phy->rev <= 7) - bcm43xx_phy_initb6(bcm); - if (phy->rev >= 2 || phy->connected) - bcm43xx_phy_inita(bcm); - - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0814, 0x0000); - bcm43xx_phy_write(bcm, 0x0815, 0x0000); - if (phy->rev == 2) - bcm43xx_phy_write(bcm, 0x0811, 0x0000); - else if (phy->rev >= 3) - bcm43xx_phy_write(bcm, 0x0811, 0x0400); - bcm43xx_phy_write(bcm, 0x0015, 0x00C0); - if (phy->connected) { - tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF; - if (tmp < 6) { - bcm43xx_phy_write(bcm, 0x04C2, 0x1816); - bcm43xx_phy_write(bcm, 0x04C3, 0x8006); - if (tmp != 3) { - bcm43xx_phy_write(bcm, 0x04CC, - (bcm43xx_phy_read(bcm, 0x04CC) - & 0x00FF) | 0x1F00); - } - } - } - } - if (phy->rev < 3 && phy->connected) - bcm43xx_phy_write(bcm, 0x047E, 0x0078); - if (phy->rev >= 6 && phy->rev <= 8) { - bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080); - bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004); - } - if (phy->rev >= 2 && phy->connected) - bcm43xx_calc_loopback_gain(bcm); - if (radio->revision != 8) { - if (radio->initval == 0xFFFF) - radio->initval = bcm43xx_radio_init2050(bcm); - else - bcm43xx_radio_write16(bcm, 0x0078, radio->initval); - } - if (radio->txctl2 == 0xFFFF) { - bcm43xx_phy_lo_g_measure(bcm); - } else { - if (radio->version == 0x2050 && radio->revision == 8) { - //FIXME - } else { - bcm43xx_radio_write16(bcm, 0x0052, - (bcm43xx_radio_read16(bcm, 0x0052) - & 0xFFF0) | radio->txctl1); - } - if (phy->rev >= 6) { - /* - bcm43xx_phy_write(bcm, 0x0036, - (bcm43xx_phy_read(bcm, 0x0036) - & 0xF000) | (FIXME << 12)); - */ - } - if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) - bcm43xx_phy_write(bcm, 0x002E, 0x8075); - else - bcm43xx_phy_write(bcm, 0x003E, 0x807F); - if (phy->rev < 2) - bcm43xx_phy_write(bcm, 0x002F, 0x0101); - else - bcm43xx_phy_write(bcm, 0x002F, 0x0202); - } - if (phy->connected) { - bcm43xx_phy_lo_adjust(bcm, 0); - bcm43xx_phy_write(bcm, 0x080F, 0x8078); - } - - if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) { - /* The specs state to update the NRSSI LT with - * the value 0x7FFFFFFF here. I think that is some weird - * compiler optimization in the original driver. - * Essentially, what we do here is resetting all NRSSI LT - * entries to -32 (see the limit_value() in nrssi_hw_update()) - */ - bcm43xx_nrssi_hw_update(bcm, 0xFFFF); - bcm43xx_calc_nrssi_threshold(bcm); - } else if (phy->connected) { - if (radio->nrssi[0] == -1000) { - assert(radio->nrssi[1] == -1000); - bcm43xx_calc_nrssi_slope(bcm); - } else { - assert(radio->nrssi[1] != -1000); - bcm43xx_calc_nrssi_threshold(bcm); - } - } - if (radio->revision == 8) - bcm43xx_phy_write(bcm, 0x0805, 0x3230); - bcm43xx_phy_init_pctl(bcm); - if (bcm->chip_id == 0x4306 && bcm->chip_package == 2) { - bcm43xx_phy_write(bcm, 0x0429, - bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF); - bcm43xx_phy_write(bcm, 0x04C3, - bcm43xx_phy_read(bcm, 0x04C3) & 0x7FFF); - } -} - -static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm) -{ - int i; - u16 ret = 0; - - for (i = 0; i < 10; i++){ - bcm43xx_phy_write(bcm, 0x0015, 0xAFA0); - udelay(1); - bcm43xx_phy_write(bcm, 0x0015, 0xEFA0); - udelay(10); - bcm43xx_phy_write(bcm, 0x0015, 0xFFA0); - udelay(40); - ret += bcm43xx_phy_read(bcm, 0x002C); - } - - return ret; -} - -void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 regstack[12] = { 0 }; - u16 mls; - u16 fval; - int i, j; - - regstack[0] = bcm43xx_phy_read(bcm, 0x0015); - regstack[1] = bcm43xx_radio_read16(bcm, 0x0052) & 0xFFF0; - - if (radio->version == 0x2053) { - regstack[2] = bcm43xx_phy_read(bcm, 0x000A); - regstack[3] = bcm43xx_phy_read(bcm, 0x002A); - regstack[4] = bcm43xx_phy_read(bcm, 0x0035); - regstack[5] = bcm43xx_phy_read(bcm, 0x0003); - regstack[6] = bcm43xx_phy_read(bcm, 0x0001); - regstack[7] = bcm43xx_phy_read(bcm, 0x0030); - - regstack[8] = bcm43xx_radio_read16(bcm, 0x0043); - regstack[9] = bcm43xx_radio_read16(bcm, 0x007A); - regstack[10] = bcm43xx_read16(bcm, 0x03EC); - regstack[11] = bcm43xx_radio_read16(bcm, 0x0052) & 0x00F0; - - bcm43xx_phy_write(bcm, 0x0030, 0x00FF); - bcm43xx_write16(bcm, 0x03EC, 0x3F3F); - bcm43xx_phy_write(bcm, 0x0035, regstack[4] & 0xFF7F); - bcm43xx_radio_write16(bcm, 0x007A, regstack[9] & 0xFFF0); - } - bcm43xx_phy_write(bcm, 0x0015, 0xB000); - bcm43xx_phy_write(bcm, 0x002B, 0x0004); - - if (radio->version == 0x2053) { - bcm43xx_phy_write(bcm, 0x002B, 0x0203); - bcm43xx_phy_write(bcm, 0x002A, 0x08A3); - } - - phy->minlowsig[0] = 0xFFFF; - - for (i = 0; i < 4; i++) { - bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | i); - bcm43xx_phy_lo_b_r15_loop(bcm); - } - for (i = 0; i < 10; i++) { - bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | i); - mls = bcm43xx_phy_lo_b_r15_loop(bcm) / 10; - if (mls < phy->minlowsig[0]) { - phy->minlowsig[0] = mls; - phy->minlowsigpos[0] = i; - } - } - bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | phy->minlowsigpos[0]); - - phy->minlowsig[1] = 0xFFFF; - - for (i = -4; i < 5; i += 2) { - for (j = -4; j < 5; j += 2) { - if (j < 0) - fval = (0x0100 * i) + j + 0x0100; - else - fval = (0x0100 * i) + j; - bcm43xx_phy_write(bcm, 0x002F, fval); - mls = bcm43xx_phy_lo_b_r15_loop(bcm) / 10; - if (mls < phy->minlowsig[1]) { - phy->minlowsig[1] = mls; - phy->minlowsigpos[1] = fval; - } - } - } - phy->minlowsigpos[1] += 0x0101; - - bcm43xx_phy_write(bcm, 0x002F, phy->minlowsigpos[1]); - if (radio->version == 0x2053) { - bcm43xx_phy_write(bcm, 0x000A, regstack[2]); - bcm43xx_phy_write(bcm, 0x002A, regstack[3]); - bcm43xx_phy_write(bcm, 0x0035, regstack[4]); - bcm43xx_phy_write(bcm, 0x0003, regstack[5]); - bcm43xx_phy_write(bcm, 0x0001, regstack[6]); - bcm43xx_phy_write(bcm, 0x0030, regstack[7]); - - bcm43xx_radio_write16(bcm, 0x0043, regstack[8]); - bcm43xx_radio_write16(bcm, 0x007A, regstack[9]); - - bcm43xx_radio_write16(bcm, 0x0052, - (bcm43xx_radio_read16(bcm, 0x0052) & 0x000F) - | regstack[11]); - - bcm43xx_write16(bcm, 0x03EC, regstack[10]); - } - bcm43xx_phy_write(bcm, 0x0015, regstack[0]); -} - -static inline -u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x15, 0xE300); - control <<= 8; - bcm43xx_phy_write(bcm, 0x0812, control | 0x00B0); - udelay(5); - bcm43xx_phy_write(bcm, 0x0812, control | 0x00B2); - udelay(2); - bcm43xx_phy_write(bcm, 0x0812, control | 0x00B3); - udelay(4); - bcm43xx_phy_write(bcm, 0x0015, 0xF300); - udelay(8); - } else { - bcm43xx_phy_write(bcm, 0x0015, control | 0xEFA0); - udelay(2); - bcm43xx_phy_write(bcm, 0x0015, control | 0xEFE0); - udelay(4); - bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0); - udelay(8); - } - - return bcm43xx_phy_read(bcm, 0x002D); -} - -static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control) -{ - int i; - u32 ret = 0; - - for (i = 0; i < 8; i++) - ret += bcm43xx_phy_lo_g_deviation_subval(bcm, control); - - return ret; -} - -/* Write the LocalOscillator CONTROL */ -static inline -void bcm43xx_lo_write(struct bcm43xx_private *bcm, - struct bcm43xx_lopair *pair) -{ - u16 value; - - value = (u8)(pair->low); - value |= ((u8)(pair->high)) << 8; - -#ifdef CONFIG_BCM43XX_DEBUG - /* Sanity check. */ - if (pair->low < -8 || pair->low > 8 || - pair->high < -8 || pair->high > 8) { - printk(KERN_WARNING PFX - "WARNING: Writing invalid LOpair " - "(low: %d, high: %d, index: %lu)\n", - pair->low, pair->high, - (unsigned long)(pair - bcm43xx_current_phy(bcm)->_lo_pairs)); - dump_stack(); - } -#endif - - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, value); -} - -static inline -struct bcm43xx_lopair * bcm43xx_find_lopair(struct bcm43xx_private *bcm, - u16 baseband_attenuation, - u16 radio_attenuation, - u16 tx) -{ - static const u8 dict[10] = { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 }; - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (baseband_attenuation > 6) - baseband_attenuation = 6; - assert(radio_attenuation < 10); - - if (tx == 3) { - return bcm43xx_get_lopair(phy, - radio_attenuation, - baseband_attenuation); - } - return bcm43xx_get_lopair(phy, dict[radio_attenuation], baseband_attenuation); -} - -static inline -struct bcm43xx_lopair * bcm43xx_current_lopair(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - return bcm43xx_find_lopair(bcm, - radio->baseband_atten, - radio->radio_atten, - radio->txctl1); -} - -/* Adjust B/G LO */ -void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed) -{ - struct bcm43xx_lopair *pair; - - if (fixed) { - /* Use fixed values. Only for initialization. */ - pair = bcm43xx_find_lopair(bcm, 2, 3, 0); - } else - pair = bcm43xx_current_lopair(bcm); - bcm43xx_lo_write(bcm, pair); -} - -static void bcm43xx_phy_lo_g_measure_txctl2(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 txctl2 = 0, i; - u32 smallest, tmp; - - bcm43xx_radio_write16(bcm, 0x0052, 0x0000); - udelay(10); - smallest = bcm43xx_phy_lo_g_singledeviation(bcm, 0); - for (i = 0; i < 16; i++) { - bcm43xx_radio_write16(bcm, 0x0052, i); - udelay(10); - tmp = bcm43xx_phy_lo_g_singledeviation(bcm, 0); - if (tmp < smallest) { - smallest = tmp; - txctl2 = i; - } - } - radio->txctl2 = txctl2; -} - -static -void bcm43xx_phy_lo_g_state(struct bcm43xx_private *bcm, - const struct bcm43xx_lopair *in_pair, - struct bcm43xx_lopair *out_pair, - u16 r27) -{ - static const struct bcm43xx_lopair transitions[8] = { - { .high = 1, .low = 1, }, - { .high = 1, .low = 0, }, - { .high = 1, .low = -1, }, - { .high = 0, .low = -1, }, - { .high = -1, .low = -1, }, - { .high = -1, .low = 0, }, - { .high = -1, .low = 1, }, - { .high = 0, .low = 1, }, - }; - struct bcm43xx_lopair lowest_transition = { - .high = in_pair->high, - .low = in_pair->low, - }; - struct bcm43xx_lopair tmp_pair; - struct bcm43xx_lopair transition; - int i = 12; - int state = 0; - int found_lower; - int j, begin, end; - u32 lowest_deviation; - u32 tmp; - - /* Note that in_pair and out_pair can point to the same pair. Be careful. */ - - bcm43xx_lo_write(bcm, &lowest_transition); - lowest_deviation = bcm43xx_phy_lo_g_singledeviation(bcm, r27); - do { - found_lower = 0; - assert(state >= 0 && state <= 8); - if (state == 0) { - begin = 1; - end = 8; - } else if (state % 2 == 0) { - begin = state - 1; - end = state + 1; - } else { - begin = state - 2; - end = state + 2; - } - if (begin < 1) - begin += 8; - if (end > 8) - end -= 8; - - j = begin; - tmp_pair.high = lowest_transition.high; - tmp_pair.low = lowest_transition.low; - while (1) { - assert(j >= 1 && j <= 8); - transition.high = tmp_pair.high + transitions[j - 1].high; - transition.low = tmp_pair.low + transitions[j - 1].low; - if ((abs(transition.low) < 9) && (abs(transition.high) < 9)) { - bcm43xx_lo_write(bcm, &transition); - tmp = bcm43xx_phy_lo_g_singledeviation(bcm, r27); - if (tmp < lowest_deviation) { - lowest_deviation = tmp; - state = j; - found_lower = 1; - - lowest_transition.high = transition.high; - lowest_transition.low = transition.low; - } - } - if (j == end) - break; - if (j == 8) - j = 1; - else - j++; - } - } while (i-- && found_lower); - - out_pair->high = lowest_transition.high; - out_pair->low = lowest_transition.low; -} - -/* Set the baseband attenuation value on chip. */ -void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, - u16 baseband_attenuation) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 value; - - if (phy->version == 0) { - value = (bcm43xx_read16(bcm, 0x03E6) & 0xFFF0); - value |= (baseband_attenuation & 0x000F); - bcm43xx_write16(bcm, 0x03E6, value); - return; - } - - if (phy->version > 1) { - value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C; - value |= (baseband_attenuation << 2) & 0x003C; - } else { - value = bcm43xx_phy_read(bcm, 0x0060) & ~0x0078; - value |= (baseband_attenuation << 3) & 0x0078; - } - bcm43xx_phy_write(bcm, 0x0060, value); -} - -/* http://bcm-specs.sipsolutions.net/LocalOscillator/Measure */ -void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) -{ - static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 }; - const int is_initializing = bcm43xx_is_initializing(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 h, i, oldi = 0, j; - struct bcm43xx_lopair control; - struct bcm43xx_lopair *tmp_control; - u16 tmp; - u16 regstack[16] = { 0 }; - u8 oldchannel; - - //XXX: What are these? - u8 r27 = 0, r31; - - oldchannel = radio->channel; - /* Setup */ - if (phy->connected) { - regstack[0] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS); - regstack[1] = bcm43xx_phy_read(bcm, 0x0802); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0] & 0x7FFF); - bcm43xx_phy_write(bcm, 0x0802, regstack[1] & 0xFFFC); - } - regstack[3] = bcm43xx_read16(bcm, 0x03E2); - bcm43xx_write16(bcm, 0x03E2, regstack[3] | 0x8000); - regstack[4] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); - regstack[5] = bcm43xx_phy_read(bcm, 0x15); - regstack[6] = bcm43xx_phy_read(bcm, 0x2A); - regstack[7] = bcm43xx_phy_read(bcm, 0x35); - regstack[8] = bcm43xx_phy_read(bcm, 0x60); - regstack[9] = bcm43xx_radio_read16(bcm, 0x43); - regstack[10] = bcm43xx_radio_read16(bcm, 0x7A); - regstack[11] = bcm43xx_radio_read16(bcm, 0x52); - if (phy->connected) { - regstack[12] = bcm43xx_phy_read(bcm, 0x0811); - regstack[13] = bcm43xx_phy_read(bcm, 0x0812); - regstack[14] = bcm43xx_phy_read(bcm, 0x0814); - regstack[15] = bcm43xx_phy_read(bcm, 0x0815); - } - bcm43xx_radio_selectchannel(bcm, 6, 0); - if (phy->connected) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0] & 0x7FFF); - bcm43xx_phy_write(bcm, 0x0802, regstack[1] & 0xFFFC); - bcm43xx_dummy_transmission(bcm); - } - bcm43xx_radio_write16(bcm, 0x0043, 0x0006); - - bcm43xx_phy_set_baseband_attenuation(bcm, 2); - - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x0000); - bcm43xx_phy_write(bcm, 0x002E, 0x007F); - bcm43xx_phy_write(bcm, 0x080F, 0x0078); - bcm43xx_phy_write(bcm, 0x0035, regstack[7] & ~(1 << 7)); - bcm43xx_radio_write16(bcm, 0x007A, regstack[10] & 0xFFF0); - bcm43xx_phy_write(bcm, 0x002B, 0x0203); - bcm43xx_phy_write(bcm, 0x002A, 0x08A3); - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x0814, regstack[14] | 0x0003); - bcm43xx_phy_write(bcm, 0x0815, regstack[15] & 0xFFFC); - bcm43xx_phy_write(bcm, 0x0811, 0x01B3); - bcm43xx_phy_write(bcm, 0x0812, 0x00B2); - } - if (is_initializing) - bcm43xx_phy_lo_g_measure_txctl2(bcm); - bcm43xx_phy_write(bcm, 0x080F, 0x8078); - - /* Measure */ - control.low = 0; - control.high = 0; - for (h = 0; h < 10; h++) { - /* Loop over each possible RadioAttenuation (0-9) */ - i = pairorder[h]; - if (is_initializing) { - if (i == 3) { - control.low = 0; - control.high = 0; - } else if (((i % 2 == 1) && (oldi % 2 == 1)) || - ((i % 2 == 0) && (oldi % 2 == 0))) { - tmp_control = bcm43xx_get_lopair(phy, oldi, 0); - memcpy(&control, tmp_control, sizeof(control)); - } else { - tmp_control = bcm43xx_get_lopair(phy, 3, 0); - memcpy(&control, tmp_control, sizeof(control)); - } - } - /* Loop over each possible BasebandAttenuation/2 */ - for (j = 0; j < 4; j++) { - if (is_initializing) { - tmp = i * 2 + j; - r27 = 0; - r31 = 0; - if (tmp > 14) { - r31 = 1; - if (tmp > 17) - r27 = 1; - if (tmp > 19) - r27 = 2; - } - } else { - tmp_control = bcm43xx_get_lopair(phy, i, j * 2); - if (!tmp_control->used) - continue; - memcpy(&control, tmp_control, sizeof(control)); - r27 = 3; - r31 = 0; - } - bcm43xx_radio_write16(bcm, 0x43, i); - bcm43xx_radio_write16(bcm, 0x52, radio->txctl2); - udelay(10); - - bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); - - tmp = (regstack[10] & 0xFFF0); - if (r31) - tmp |= 0x0008; - bcm43xx_radio_write16(bcm, 0x007A, tmp); - - tmp_control = bcm43xx_get_lopair(phy, i, j * 2); - bcm43xx_phy_lo_g_state(bcm, &control, tmp_control, r27); - } - oldi = i; - } - /* Loop over each possible RadioAttenuation (10-13) */ - for (i = 10; i < 14; i++) { - /* Loop over each possible BasebandAttenuation/2 */ - for (j = 0; j < 4; j++) { - if (is_initializing) { - tmp_control = bcm43xx_get_lopair(phy, i - 9, j * 2); - memcpy(&control, tmp_control, sizeof(control)); - tmp = (i - 9) * 2 + j - 5;//FIXME: This is wrong, as the following if statement can never trigger. - r27 = 0; - r31 = 0; - if (tmp > 14) { - r31 = 1; - if (tmp > 17) - r27 = 1; - if (tmp > 19) - r27 = 2; - } - } else { - tmp_control = bcm43xx_get_lopair(phy, i - 9, j * 2); - if (!tmp_control->used) - continue; - memcpy(&control, tmp_control, sizeof(control)); - r27 = 3; - r31 = 0; - } - bcm43xx_radio_write16(bcm, 0x43, i - 9); - bcm43xx_radio_write16(bcm, 0x52, - radio->txctl2 - | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above? - udelay(10); - - bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); - - tmp = (regstack[10] & 0xFFF0); - if (r31) - tmp |= 0x0008; - bcm43xx_radio_write16(bcm, 0x7A, tmp); - - tmp_control = bcm43xx_get_lopair(phy, i, j * 2); - bcm43xx_phy_lo_g_state(bcm, &control, tmp_control, r27); - } - } - - /* Restoration */ - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x0015, 0xE300); - bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA0); - udelay(5); - bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2); - udelay(2); - bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3); - } else - bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0); - bcm43xx_phy_lo_adjust(bcm, is_initializing); - bcm43xx_phy_write(bcm, 0x002E, 0x807F); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x002F, 0x0202); - else - bcm43xx_phy_write(bcm, 0x002F, 0x0101); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, regstack[4]); - bcm43xx_phy_write(bcm, 0x0015, regstack[5]); - bcm43xx_phy_write(bcm, 0x002A, regstack[6]); - bcm43xx_phy_write(bcm, 0x0035, regstack[7]); - bcm43xx_phy_write(bcm, 0x0060, regstack[8]); - bcm43xx_radio_write16(bcm, 0x0043, regstack[9]); - bcm43xx_radio_write16(bcm, 0x007A, regstack[10]); - regstack[11] &= 0x00F0; - regstack[11] |= (bcm43xx_radio_read16(bcm, 0x52) & 0x000F); - bcm43xx_radio_write16(bcm, 0x52, regstack[11]); - bcm43xx_write16(bcm, 0x03E2, regstack[3]); - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x0811, regstack[12]); - bcm43xx_phy_write(bcm, 0x0812, regstack[13]); - bcm43xx_phy_write(bcm, 0x0814, regstack[14]); - bcm43xx_phy_write(bcm, 0x0815, regstack[15]); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0]); - bcm43xx_phy_write(bcm, 0x0802, regstack[1]); - } - bcm43xx_radio_selectchannel(bcm, oldchannel, 1); - -#ifdef CONFIG_BCM43XX_DEBUG - { - /* Sanity check for all lopairs. */ - for (i = 0; i < BCM43xx_LO_COUNT; i++) { - tmp_control = phy->_lo_pairs + i; - if (tmp_control->low < -8 || tmp_control->low > 8 || - tmp_control->high < -8 || tmp_control->high > 8) { - printk(KERN_WARNING PFX - "WARNING: Invalid LOpair (low: %d, high: %d, index: %d)\n", - tmp_control->low, tmp_control->high, i); - } - } - } -#endif /* CONFIG_BCM43XX_DEBUG */ -} - -static -void bcm43xx_phy_lo_mark_current_used(struct bcm43xx_private *bcm) -{ - struct bcm43xx_lopair *pair; - - pair = bcm43xx_current_lopair(bcm); - pair->used = 1; -} - -void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_lopair *pair; - int i; - - for (i = 0; i < BCM43xx_LO_COUNT; i++) { - pair = phy->_lo_pairs + i; - pair->used = 0; - } -} - -/* http://bcm-specs.sipsolutions.net/EstimatePowerOut - * This function converts a TSSI value to dBm in Q5.2 - */ -static s8 bcm43xx_phy_estimate_power_out(struct bcm43xx_private *bcm, s8 tssi) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - s8 dbm = 0; - s32 tmp; - - tmp = phy->idle_tssi; - tmp += tssi; - tmp -= phy->savedpctlreg; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - tmp += 0x80; - tmp = limit_value(tmp, 0x00, 0xFF); - dbm = phy->tssi2dbm[tmp]; - TODO(); //TODO: There's a FIXME on the specs - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - tmp = limit_value(tmp, 0x00, 0x3F); - dbm = phy->tssi2dbm[tmp]; - break; - default: - assert(0); - } - - return dbm; -} - -/* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */ -void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (phy->savedpctlreg == 0xFFFF) - return; - if ((bcm->board_type == 0x0416) && - (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM)) - return; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: { - - TODO(); //TODO: Nothing for A PHYs yet :-/ - - break; - } - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: { - u16 tmp; - u16 txpower; - s8 v0, v1, v2, v3; - s8 average; - u8 max_pwr; - s16 desired_pwr, estimated_pwr, pwr_adjust; - s16 radio_att_delta, baseband_att_delta; - s16 radio_attenuation, baseband_attenuation; - unsigned long phylock_flags; - - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0058); - v0 = (s8)(tmp & 0x00FF); - v1 = (s8)((tmp & 0xFF00) >> 8); - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x005A); - v2 = (s8)(tmp & 0x00FF); - v3 = (s8)((tmp & 0xFF00) >> 8); - tmp = 0; - - if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F) { - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0070); - v0 = (s8)(tmp & 0x00FF); - v1 = (s8)((tmp & 0xFF00) >> 8); - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0072); - v2 = (s8)(tmp & 0x00FF); - v3 = (s8)((tmp & 0xFF00) >> 8); - if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F) - return; - v0 = (v0 + 0x20) & 0x3F; - v1 = (v1 + 0x20) & 0x3F; - v2 = (v2 + 0x20) & 0x3F; - v3 = (v3 + 0x20) & 0x3F; - tmp = 1; - } - bcm43xx_radio_clear_tssi(bcm); - - average = (v0 + v1 + v2 + v3 + 2) / 4; - - if (tmp && (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x005E) & 0x8)) - average -= 13; - - estimated_pwr = bcm43xx_phy_estimate_power_out(bcm, average); - - max_pwr = bcm->sprom.maxpower_bgphy; - - if ((bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) && - (phy->type == BCM43xx_PHYTYPE_G)) - max_pwr -= 0x3; - - /*TODO: - max_pwr = min(REG - bcm->sprom.antennagain_bgphy - 0x6, max_pwr) - where REG is the max power as per the regulatory domain - */ - - desired_pwr = limit_value(radio->txpower_desired, 0, max_pwr); - /* Check if we need to adjust the current power. */ - pwr_adjust = desired_pwr - estimated_pwr; - radio_att_delta = -(pwr_adjust + 7) >> 3; - baseband_att_delta = -(pwr_adjust >> 1) - (4 * radio_att_delta); - if ((radio_att_delta == 0) && (baseband_att_delta == 0)) { - bcm43xx_phy_lo_mark_current_used(bcm); - return; - } - - /* Calculate the new attenuation values. */ - baseband_attenuation = radio->baseband_atten; - baseband_attenuation += baseband_att_delta; - radio_attenuation = radio->radio_atten; - radio_attenuation += radio_att_delta; - - /* Get baseband and radio attenuation values into their permitted ranges. - * baseband 0-11, radio 0-9. - * Radio attenuation affects power level 4 times as much as baseband. - */ - if (radio_attenuation < 0) { - baseband_attenuation -= (4 * -radio_attenuation); - radio_attenuation = 0; - } else if (radio_attenuation > 9) { - baseband_attenuation += (4 * (radio_attenuation - 9)); - radio_attenuation = 9; - } else { - while (baseband_attenuation < 0 && radio_attenuation > 0) { - baseband_attenuation += 4; - radio_attenuation--; - } - while (baseband_attenuation > 11 && radio_attenuation < 9) { - baseband_attenuation -= 4; - radio_attenuation++; - } - } - baseband_attenuation = limit_value(baseband_attenuation, 0, 11); - - txpower = radio->txctl1; - if ((radio->version == 0x2050) && (radio->revision == 2)) { - if (radio_attenuation <= 1) { - if (txpower == 0) { - txpower = 3; - radio_attenuation += 2; - baseband_attenuation += 2; - } else if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) { - baseband_attenuation += 4 * (radio_attenuation - 2); - radio_attenuation = 2; - } - } else if (radio_attenuation > 4 && txpower != 0) { - txpower = 0; - if (baseband_attenuation < 3) { - radio_attenuation -= 3; - baseband_attenuation += 2; - } else { - radio_attenuation -= 2; - baseband_attenuation -= 2; - } - } - } - radio->txctl1 = txpower; - baseband_attenuation = limit_value(baseband_attenuation, 0, 11); - radio_attenuation = limit_value(radio_attenuation, 0, 9); - - bcm43xx_phy_lock(bcm, phylock_flags); - bcm43xx_radio_lock(bcm); - bcm43xx_radio_set_txpower_bg(bcm, baseband_attenuation, - radio_attenuation, txpower); - bcm43xx_phy_lo_mark_current_used(bcm); - bcm43xx_radio_unlock(bcm); - bcm43xx_phy_unlock(bcm, phylock_flags); - break; - } - default: - assert(0); - } -} - -static inline -s32 bcm43xx_tssi2dbm_ad(s32 num, s32 den) -{ - if (num < 0) - return num/den; - else - return (num+den/2)/den; -} - -static inline -s8 bcm43xx_tssi2dbm_entry(s8 entry [], u8 index, s16 pab0, s16 pab1, s16 pab2) -{ - s32 m1, m2, f = 256, q, delta; - s8 i = 0; - - m1 = bcm43xx_tssi2dbm_ad(16 * pab0 + index * pab1, 32); - m2 = max(bcm43xx_tssi2dbm_ad(32768 + index * pab2, 256), 1); - do { - if (i > 15) - return -EINVAL; - q = bcm43xx_tssi2dbm_ad(f * 4096 - - bcm43xx_tssi2dbm_ad(m2 * f, 16) * f, 2048); - delta = abs(q - f); - f = q; - i++; - } while (delta >= 2); - entry[index] = limit_value(bcm43xx_tssi2dbm_ad(m1 * f, 8192), -127, 128); - return 0; -} - -/* http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table */ -int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - s16 pab0, pab1, pab2; - u8 idx; - s8 *dyn_tssi2dbm; - - if (phy->type == BCM43xx_PHYTYPE_A) { - pab0 = (s16)(bcm->sprom.pa1b0); - pab1 = (s16)(bcm->sprom.pa1b1); - pab2 = (s16)(bcm->sprom.pa1b2); - } else { - pab0 = (s16)(bcm->sprom.pa0b0); - pab1 = (s16)(bcm->sprom.pa0b1); - pab2 = (s16)(bcm->sprom.pa0b2); - } - - if ((bcm->chip_id == 0x4301) && (radio->version != 0x2050)) { - phy->idle_tssi = 0x34; - phy->tssi2dbm = bcm43xx_tssi2dbm_b_table; - return 0; - } - - if (pab0 != 0 && pab1 != 0 && pab2 != 0 && - pab0 != -1 && pab1 != -1 && pab2 != -1) { - /* The pabX values are set in SPROM. Use them. */ - if (phy->type == BCM43xx_PHYTYPE_A) { - if ((s8)bcm->sprom.idle_tssi_tgt_aphy != 0 && - (s8)bcm->sprom.idle_tssi_tgt_aphy != -1) - phy->idle_tssi = (s8)(bcm->sprom.idle_tssi_tgt_aphy); - else - phy->idle_tssi = 62; - } else { - if ((s8)bcm->sprom.idle_tssi_tgt_bgphy != 0 && - (s8)bcm->sprom.idle_tssi_tgt_bgphy != -1) - phy->idle_tssi = (s8)(bcm->sprom.idle_tssi_tgt_bgphy); - else - phy->idle_tssi = 62; - } - dyn_tssi2dbm = kmalloc(64, GFP_KERNEL); - if (dyn_tssi2dbm == NULL) { - printk(KERN_ERR PFX "Could not allocate memory" - "for tssi2dbm table\n"); - return -ENOMEM; - } - for (idx = 0; idx < 64; idx++) - if (bcm43xx_tssi2dbm_entry(dyn_tssi2dbm, idx, pab0, pab1, pab2)) { - phy->tssi2dbm = NULL; - printk(KERN_ERR PFX "Could not generate " - "tssi2dBm table\n"); - kfree(dyn_tssi2dbm); - return -ENODEV; - } - phy->tssi2dbm = dyn_tssi2dbm; - phy->dyn_tssi_tbl = 1; - } else { - /* pabX values not set in SPROM. */ - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - /* APHY needs a generated table. */ - phy->tssi2dbm = NULL; - printk(KERN_ERR PFX "Could not generate tssi2dBm " - "table (wrong SPROM info)!\n"); - return -ENODEV; - case BCM43xx_PHYTYPE_B: - phy->idle_tssi = 0x34; - phy->tssi2dbm = bcm43xx_tssi2dbm_b_table; - break; - case BCM43xx_PHYTYPE_G: - phy->idle_tssi = 0x34; - phy->tssi2dbm = bcm43xx_tssi2dbm_g_table; - break; - } - } - - return 0; -} - -int bcm43xx_phy_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - int err = -ENODEV; - unsigned long flags; - - /* We do not want to be preempted while calibrating - * the hardware. - */ - local_irq_save(flags); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - if (phy->rev == 2 || phy->rev == 3) { - bcm43xx_phy_inita(bcm); - err = 0; - } - break; - case BCM43xx_PHYTYPE_B: - switch (phy->rev) { - case 2: - bcm43xx_phy_initb2(bcm); - err = 0; - break; - case 4: - bcm43xx_phy_initb4(bcm); - err = 0; - break; - case 5: - bcm43xx_phy_initb5(bcm); - err = 0; - break; - case 6: - bcm43xx_phy_initb6(bcm); - err = 0; - break; - } - break; - case BCM43xx_PHYTYPE_G: - bcm43xx_phy_initg(bcm); - err = 0; - break; - } - local_irq_restore(flags); - if (err) - printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n"); - - return err; -} - -void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 antennadiv; - u16 offset; - u16 value; - u32 ucodeflags; - - antennadiv = phy->antenna_diversity; - - if (antennadiv == 0xFFFF) - antennadiv = 3; - assert(antennadiv <= 3); - - ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - ucodeflags & ~BCM43xx_UCODEFLAG_AUTODIV); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - case BCM43xx_PHYTYPE_G: - if (phy->type == BCM43xx_PHYTYPE_A) - offset = 0x0000; - else - offset = 0x0400; - - if (antennadiv == 2) - value = (3/*automatic*/ << 7); - else - value = (antennadiv << 7); - bcm43xx_phy_write(bcm, offset + 1, - (bcm43xx_phy_read(bcm, offset + 1) - & 0x7E7F) | value); - - if (antennadiv >= 2) { - if (antennadiv == 2) - value = (antennadiv << 7); - else - value = (0/*force0*/ << 7); - bcm43xx_phy_write(bcm, offset + 0x2B, - (bcm43xx_phy_read(bcm, offset + 0x2B) - & 0xFEFF) | value); - } - - if (phy->type == BCM43xx_PHYTYPE_G) { - if (antennadiv >= 2) - bcm43xx_phy_write(bcm, 0x048C, - bcm43xx_phy_read(bcm, 0x048C) - | 0x2000); - else - bcm43xx_phy_write(bcm, 0x048C, - bcm43xx_phy_read(bcm, 0x048C) - & ~0x2000); - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0461, - bcm43xx_phy_read(bcm, 0x0461) - | 0x0010); - bcm43xx_phy_write(bcm, 0x04AD, - (bcm43xx_phy_read(bcm, 0x04AD) - & 0x00FF) | 0x0015); - if (phy->rev == 2) - bcm43xx_phy_write(bcm, 0x0427, 0x0008); - else - bcm43xx_phy_write(bcm, 0x0427, - (bcm43xx_phy_read(bcm, 0x0427) - & 0x00FF) | 0x0008); - } - else if (phy->rev >= 6) - bcm43xx_phy_write(bcm, 0x049B, 0x00DC); - } else { - if (phy->rev < 3) - bcm43xx_phy_write(bcm, 0x002B, - (bcm43xx_phy_read(bcm, 0x002B) - & 0x00FF) | 0x0024); - else { - bcm43xx_phy_write(bcm, 0x0061, - bcm43xx_phy_read(bcm, 0x0061) - | 0x0010); - if (phy->rev == 3) { - bcm43xx_phy_write(bcm, 0x0093, 0x001D); - bcm43xx_phy_write(bcm, 0x0027, 0x0008); - } else { - bcm43xx_phy_write(bcm, 0x0093, 0x003A); - bcm43xx_phy_write(bcm, 0x0027, - (bcm43xx_phy_read(bcm, 0x0027) - & 0x00FF) | 0x0008); - } - } - } - break; - case BCM43xx_PHYTYPE_B: - if (bcm->current_core->rev == 2) - value = (3/*automatic*/ << 7); - else - value = (antennadiv << 7); - bcm43xx_phy_write(bcm, 0x03E2, - (bcm43xx_phy_read(bcm, 0x03E2) - & 0xFE7F) | value); - break; - default: - assert(0); - } - - if (antennadiv >= 2) { - ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - ucodeflags | BCM43xx_UCODEFLAG_AUTODIV); - } - - phy->antenna_diversity = antennadiv; -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.h b/drivers/net/wireless/bcm43xx/bcm43xx_phy.h deleted file mode 100644 index 1f321ef42..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_PHY_H_ -#define BCM43xx_PHY_H_ - -#include - -struct bcm43xx_private; - -void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm); -#define bcm43xx_phy_lock(bcm, flags) \ - do { \ - local_irq_save(flags); \ - bcm43xx_raw_phy_lock(bcm); \ - } while (0) -void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm); -#define bcm43xx_phy_unlock(bcm, flags) \ - do { \ - bcm43xx_raw_phy_unlock(bcm); \ - local_irq_restore(flags); \ - } while (0) - -u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset); -void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val); - -int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm); -int bcm43xx_phy_init(struct bcm43xx_private *bcm); - -void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm); -void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm); -int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect); - -void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm); -void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm); -void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm); - -/* Adjust the LocalOscillator to the saved values. - * "fixed" is only set to 1 once in initialization. Set to 0 otherwise. - */ -void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed); -void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm); - -void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, - u16 baseband_attenuation); - -#endif /* BCM43xx_PHY_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c deleted file mode 100644 index 0aa1bd269..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - PIO Transmission - - Copyright (c) 2005 Michael Buesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx.h" -#include "bcm43xx_pio.h" -#include "bcm43xx_main.h" -#include "bcm43xx_xmit.h" -#include "bcm43xx_power.h" - -#include - - -static void tx_start(struct bcm43xx_pioqueue *queue) -{ - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_INIT); -} - -static void tx_octet(struct bcm43xx_pioqueue *queue, - u8 octet) -{ - if (queue->need_workarounds) { - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, - octet); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_WRITELO); - } else { - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_WRITELO); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, - octet); - } -} - -static u16 tx_get_next_word(struct bcm43xx_txhdr *txhdr, - const u8 *packet, - unsigned int *pos) -{ - const u8 *source; - unsigned int i = *pos; - u16 ret; - - if (i < sizeof(*txhdr)) { - source = (const u8 *)txhdr; - } else { - source = packet; - i -= sizeof(*txhdr); - } - ret = le16_to_cpu( *((u16 *)(source + i)) ); - *pos += 2; - - return ret; -} - -static void tx_data(struct bcm43xx_pioqueue *queue, - struct bcm43xx_txhdr *txhdr, - const u8 *packet, - unsigned int octets) -{ - u16 data; - unsigned int i = 0; - - if (queue->need_workarounds) { - data = tx_get_next_word(txhdr, packet, &i); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data); - } - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_WRITELO | - BCM43xx_PIO_TXCTL_WRITEHI); - while (i < octets - 1) { - data = tx_get_next_word(txhdr, packet, &i); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data); - } - if (octets % 2) - tx_octet(queue, packet[octets - sizeof(*txhdr) - 1]); -} - -static void tx_complete(struct bcm43xx_pioqueue *queue, - struct sk_buff *skb) -{ - if (queue->need_workarounds) { - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, - skb->data[skb->len - 1]); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_WRITELO | - BCM43xx_PIO_TXCTL_COMPLETE); - } else { - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_COMPLETE); - } -} - -static u16 generate_cookie(struct bcm43xx_pioqueue *queue, - struct bcm43xx_pio_txpacket *packet) -{ - u16 cookie = 0x0000; - int packetindex; - - /* We use the upper 4 bits for the PIO - * controller ID and the lower 12 bits - * for the packet index (in the cache). - */ - switch (queue->mmio_base) { - case BCM43xx_MMIO_PIO1_BASE: - break; - case BCM43xx_MMIO_PIO2_BASE: - cookie = 0x1000; - break; - case BCM43xx_MMIO_PIO3_BASE: - cookie = 0x2000; - break; - case BCM43xx_MMIO_PIO4_BASE: - cookie = 0x3000; - break; - default: - assert(0); - } - packetindex = pio_txpacket_getindex(packet); - assert(((u16)packetindex & 0xF000) == 0x0000); - cookie |= (u16)packetindex; - - return cookie; -} - -static -struct bcm43xx_pioqueue * parse_cookie(struct bcm43xx_private *bcm, - u16 cookie, - struct bcm43xx_pio_txpacket **packet) -{ - struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm); - struct bcm43xx_pioqueue *queue = NULL; - int packetindex; - - switch (cookie & 0xF000) { - case 0x0000: - queue = pio->queue0; - break; - case 0x1000: - queue = pio->queue1; - break; - case 0x2000: - queue = pio->queue2; - break; - case 0x3000: - queue = pio->queue3; - break; - default: - assert(0); - } - packetindex = (cookie & 0x0FFF); - assert(packetindex >= 0 && packetindex < BCM43xx_PIO_MAXTXPACKETS); - *packet = &(queue->tx_packets_cache[packetindex]); - - return queue; -} - -static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue, - struct sk_buff *skb, - struct bcm43xx_pio_txpacket *packet) -{ - struct bcm43xx_txhdr txhdr; - unsigned int octets; - - assert(skb_shinfo(skb)->nr_frags == 0); - bcm43xx_generate_txhdr(queue->bcm, - &txhdr, skb->data, skb->len, - (packet->xmitted_frags == 0), - generate_cookie(queue, packet)); - - tx_start(queue); - octets = skb->len + sizeof(txhdr); - if (queue->need_workarounds) - octets--; - tx_data(queue, &txhdr, (u8 *)skb->data, octets); - tx_complete(queue, skb); -} - -static void free_txpacket(struct bcm43xx_pio_txpacket *packet, - int irq_context) -{ - struct bcm43xx_pioqueue *queue = packet->queue; - - ieee80211_txb_free(packet->txb); - list_move(&packet->list, &queue->txfree); - queue->nr_txfree++; - - assert(queue->tx_devq_used >= packet->xmitted_octets); - assert(queue->tx_devq_packets >= packet->xmitted_frags); - queue->tx_devq_used -= packet->xmitted_octets; - queue->tx_devq_packets -= packet->xmitted_frags; -} - -static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet) -{ - struct bcm43xx_pioqueue *queue = packet->queue; - struct ieee80211_txb *txb = packet->txb; - struct sk_buff *skb; - u16 octets; - int i; - - for (i = packet->xmitted_frags; i < txb->nr_frags; i++) { - skb = txb->fragments[i]; - - octets = (u16)skb->len + sizeof(struct bcm43xx_txhdr); - assert(queue->tx_devq_size >= octets); - assert(queue->tx_devq_packets <= BCM43xx_PIO_MAXTXDEVQPACKETS); - assert(queue->tx_devq_used <= queue->tx_devq_size); - /* Check if there is sufficient free space on the device - * TX queue. If not, return and let the TX tasklet - * retry later. - */ - if (queue->tx_devq_packets == BCM43xx_PIO_MAXTXDEVQPACKETS) - return -EBUSY; - if (queue->tx_devq_used + octets > queue->tx_devq_size) - return -EBUSY; - /* Now poke the device. */ - pio_tx_write_fragment(queue, skb, packet); - - /* Account for the packet size. - * (We must not overflow the device TX queue) - */ - queue->tx_devq_packets++; - queue->tx_devq_used += octets; - - assert(packet->xmitted_frags < packet->txb->nr_frags); - packet->xmitted_frags++; - packet->xmitted_octets += octets; - } - list_move_tail(&packet->list, &queue->txrunning); - - return 0; -} - -static void tx_tasklet(unsigned long d) -{ - struct bcm43xx_pioqueue *queue = (struct bcm43xx_pioqueue *)d; - struct bcm43xx_private *bcm = queue->bcm; - unsigned long flags; - struct bcm43xx_pio_txpacket *packet, *tmp_packet; - int err; - u16 txctl; - - bcm43xx_lock_mmio(bcm, flags); - - txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); - if (txctl & BCM43xx_PIO_TXCTL_SUSPEND) - goto out_unlock; - - list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { - assert(packet->xmitted_frags < packet->txb->nr_frags); - if (packet->xmitted_frags == 0) { - int i; - struct sk_buff *skb; - - /* Check if the device queue is big - * enough for every fragment. If not, drop the - * whole packet. - */ - for (i = 0; i < packet->txb->nr_frags; i++) { - skb = packet->txb->fragments[i]; - if (unlikely(skb->len > queue->tx_devq_size)) { - dprintkl(KERN_ERR PFX "PIO TX device queue too small. " - "Dropping packet.\n"); - free_txpacket(packet, 1); - goto next_packet; - } - } - } - /* Try to transmit the packet. - * This may not completely succeed. - */ - err = pio_tx_packet(packet); - if (err) - break; - next_packet: - continue; - } -out_unlock: - bcm43xx_unlock_mmio(bcm, flags); -} - -static void setup_txqueues(struct bcm43xx_pioqueue *queue) -{ - struct bcm43xx_pio_txpacket *packet; - int i; - - queue->nr_txfree = BCM43xx_PIO_MAXTXPACKETS; - for (i = 0; i < BCM43xx_PIO_MAXTXPACKETS; i++) { - packet = &(queue->tx_packets_cache[i]); - - packet->queue = queue; - INIT_LIST_HEAD(&packet->list); - - list_add(&packet->list, &queue->txfree); - } -} - -static -struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm, - u16 pio_mmio_base) -{ - struct bcm43xx_pioqueue *queue; - u32 value; - u16 qsize; - - queue = kzalloc(sizeof(*queue), GFP_KERNEL); - if (!queue) - goto out; - - queue->bcm = bcm; - queue->mmio_base = pio_mmio_base; - queue->need_workarounds = (bcm->current_core->rev < 3); - - INIT_LIST_HEAD(&queue->txfree); - INIT_LIST_HEAD(&queue->txqueue); - INIT_LIST_HEAD(&queue->txrunning); - tasklet_init(&queue->txtask, tx_tasklet, - (unsigned long)queue); - - value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - value &= ~BCM43xx_SBF_XFER_REG_BYTESWAP; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value); - - qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE); - if (qsize == 0) { - printk(KERN_ERR PFX "ERROR: This card does not support PIO " - "operation mode. Please use DMA mode " - "(module parameter pio=0).\n"); - goto err_freequeue; - } - if (qsize <= BCM43xx_PIO_TXQADJUST) { - printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", - qsize); - goto err_freequeue; - } - qsize -= BCM43xx_PIO_TXQADJUST; - queue->tx_devq_size = qsize; - - setup_txqueues(queue); - -out: - return queue; - -err_freequeue: - kfree(queue); - queue = NULL; - goto out; -} - -static void cancel_transfers(struct bcm43xx_pioqueue *queue) -{ - struct bcm43xx_pio_txpacket *packet, *tmp_packet; - - netif_tx_disable(queue->bcm->net_dev); - assert(queue->bcm->shutting_down); - tasklet_disable(&queue->txtask); - - list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) - free_txpacket(packet, 0); - list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) - free_txpacket(packet, 0); -} - -static void bcm43xx_destroy_pioqueue(struct bcm43xx_pioqueue *queue) -{ - if (!queue) - return; - - cancel_transfers(queue); - kfree(queue); -} - -void bcm43xx_pio_free(struct bcm43xx_private *bcm) -{ - struct bcm43xx_pio *pio; - - if (!bcm43xx_using_pio(bcm)) - return; - pio = bcm43xx_current_pio(bcm); - - bcm43xx_destroy_pioqueue(pio->queue3); - pio->queue3 = NULL; - bcm43xx_destroy_pioqueue(pio->queue2); - pio->queue2 = NULL; - bcm43xx_destroy_pioqueue(pio->queue1); - pio->queue1 = NULL; - bcm43xx_destroy_pioqueue(pio->queue0); - pio->queue0 = NULL; -} - -int bcm43xx_pio_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm); - struct bcm43xx_pioqueue *queue; - int err = -ENOMEM; - - queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO1_BASE); - if (!queue) - goto out; - pio->queue0 = queue; - - queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO2_BASE); - if (!queue) - goto err_destroy0; - pio->queue1 = queue; - - queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO3_BASE); - if (!queue) - goto err_destroy1; - pio->queue2 = queue; - - queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO4_BASE); - if (!queue) - goto err_destroy2; - pio->queue3 = queue; - - if (bcm->current_core->rev < 3) - bcm->irq_savedstate |= BCM43xx_IRQ_PIO_WORKAROUND; - - dprintk(KERN_INFO PFX "PIO initialized\n"); - err = 0; -out: - return err; - -err_destroy2: - bcm43xx_destroy_pioqueue(pio->queue2); - pio->queue2 = NULL; -err_destroy1: - bcm43xx_destroy_pioqueue(pio->queue1); - pio->queue1 = NULL; -err_destroy0: - bcm43xx_destroy_pioqueue(pio->queue0); - pio->queue0 = NULL; - goto out; -} - -int bcm43xx_pio_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1; - struct bcm43xx_pio_txpacket *packet; - - assert(!queue->tx_suspended); - assert(!list_empty(&queue->txfree)); - - packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list); - packet->txb = txb; - packet->xmitted_frags = 0; - packet->xmitted_octets = 0; - list_move_tail(&packet->list, &queue->txqueue); - queue->nr_txfree--; - assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS); - - /* Suspend TX, if we are out of packets in the "free" queue. */ - if (list_empty(&queue->txfree)) { - netif_stop_queue(queue->bcm->net_dev); - queue->tx_suspended = 1; - } - - tasklet_schedule(&queue->txtask); - - return 0; -} - -void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ - struct bcm43xx_pioqueue *queue; - struct bcm43xx_pio_txpacket *packet; - - queue = parse_cookie(bcm, status->cookie, &packet); - assert(queue); - - free_txpacket(packet, 1); - if (queue->tx_suspended) { - queue->tx_suspended = 0; - netif_wake_queue(queue->bcm->net_dev); - } - /* If there are packets on the txqueue, poke the tasklet - * to transmit them. - */ - if (!list_empty(&queue->txqueue)) - tasklet_schedule(&queue->txtask); -} - -static void pio_rx_error(struct bcm43xx_pioqueue *queue, - int clear_buffers, - const char *error) -{ - int i; - - printkl("PIO RX error: %s\n", error); - bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, - BCM43xx_PIO_RXCTL_READY); - if (clear_buffers) { - assert(queue->mmio_base == BCM43xx_MMIO_PIO1_BASE); - for (i = 0; i < 15; i++) { - /* Dummy read. */ - bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); - } - } -} - -void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) -{ - u16 preamble[21] = { 0 }; - struct bcm43xx_rxhdr *rxhdr; - u16 tmp, len, rxflags2; - int i, preamble_readwords; - struct sk_buff *skb; - - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); - if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) - return; - bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, - BCM43xx_PIO_RXCTL_DATAAVAILABLE); - - for (i = 0; i < 10; i++) { - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); - if (tmp & BCM43xx_PIO_RXCTL_READY) - goto data_ready; - udelay(10); - } - dprintkl(KERN_ERR PFX "PIO RX timed out\n"); - return; -data_ready: - - len = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); - if (unlikely(len > 0x700)) { - pio_rx_error(queue, 0, "len > 0x700"); - return; - } - if (unlikely(len == 0 && queue->mmio_base != BCM43xx_MMIO_PIO4_BASE)) { - pio_rx_error(queue, 0, "len == 0"); - return; - } - preamble[0] = cpu_to_le16(len); - if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE) - preamble_readwords = 14 / sizeof(u16); - else - preamble_readwords = 18 / sizeof(u16); - for (i = 0; i < preamble_readwords; i++) { - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); - preamble[i + 1] = cpu_to_le16(tmp); - } - rxhdr = (struct bcm43xx_rxhdr *)preamble; - rxflags2 = le16_to_cpu(rxhdr->flags2); - if (unlikely(rxflags2 & BCM43xx_RXHDR_FLAGS2_INVALIDFRAME)) { - pio_rx_error(queue, - (queue->mmio_base == BCM43xx_MMIO_PIO1_BASE), - "invalid frame"); - return; - } - if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE) { - /* We received an xmit status. */ - struct bcm43xx_hwxmitstatus *hw; - struct bcm43xx_xmitstatus stat; - - hw = (struct bcm43xx_hwxmitstatus *)(preamble + 1); - stat.cookie = le16_to_cpu(hw->cookie); - stat.flags = hw->flags; - stat.cnt1 = hw->cnt1; - stat.cnt2 = hw->cnt2; - stat.seq = le16_to_cpu(hw->seq); - stat.unknown = le16_to_cpu(hw->unknown); - - bcm43xx_debugfs_log_txstat(queue->bcm, &stat); - bcm43xx_pio_handle_xmitstatus(queue->bcm, &stat); - - return; - } - - skb = dev_alloc_skb(len); - if (unlikely(!skb)) { - pio_rx_error(queue, 1, "OOM"); - return; - } - skb_put(skb, len); - for (i = 0; i < len - 1; i += 2) { - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); - *((u16 *)(skb->data + i)) = cpu_to_le16(tmp); - } - if (len % 2) { - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); - skb->data[len - 1] = (tmp & 0x00FF); -/* The specs say the following is required, but - * it is wrong and corrupts the PLCP. If we don't do - * this, the PLCP seems to be correct. So ifdef it out for now. - */ -#if 0 - if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) - skb->data[2] = (tmp & 0xFF00) >> 8; - else - skb->data[0] = (tmp & 0xFF00) >> 8; -#endif - } - skb_trim(skb, len - IEEE80211_FCS_LEN); - bcm43xx_rx(queue->bcm, skb, rxhdr); -} - -void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue) -{ - bcm43xx_power_saving_ctl_bits(queue->bcm, -1, 1); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) - | BCM43xx_PIO_TXCTL_SUSPEND); -} - -void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) -{ - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) - & ~BCM43xx_PIO_TXCTL_SUSPEND); - bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1); - tasklet_schedule(&queue->txtask); -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h deleted file mode 100644 index dfc78209e..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef BCM43xx_PIO_H_ -#define BCM43xx_PIO_H_ - -#include "bcm43xx.h" - -#include -#include -#include - - -#define BCM43xx_PIO_TXCTL 0x00 -#define BCM43xx_PIO_TXDATA 0x02 -#define BCM43xx_PIO_TXQBUFSIZE 0x04 -#define BCM43xx_PIO_RXCTL 0x08 -#define BCM43xx_PIO_RXDATA 0x0A - -#define BCM43xx_PIO_TXCTL_WRITELO (1 << 0) -#define BCM43xx_PIO_TXCTL_WRITEHI (1 << 1) -#define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2) -#define BCM43xx_PIO_TXCTL_INIT (1 << 3) -#define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7) - -#define BCM43xx_PIO_RXCTL_DATAAVAILABLE (1 << 0) -#define BCM43xx_PIO_RXCTL_READY (1 << 1) - -/* PIO constants */ -#define BCM43xx_PIO_MAXTXDEVQPACKETS 31 -#define BCM43xx_PIO_TXQADJUST 80 - -/* PIO tuning knobs */ -#define BCM43xx_PIO_MAXTXPACKETS 256 - - - -#ifdef CONFIG_BCM43XX_PIO - - -struct bcm43xx_pioqueue; -struct bcm43xx_xmitstatus; - -struct bcm43xx_pio_txpacket { - struct bcm43xx_pioqueue *queue; - struct ieee80211_txb *txb; - struct list_head list; - - u8 xmitted_frags; - u16 xmitted_octets; -}; - -#define pio_txpacket_getindex(packet) ((int)((packet) - (packet)->queue->tx_packets_cache)) - -struct bcm43xx_pioqueue { - struct bcm43xx_private *bcm; - u16 mmio_base; - - u8 tx_suspended:1, - need_workarounds:1; /* Workarounds needed for core.rev < 3 */ - - /* Adjusted size of the device internal TX buffer. */ - u16 tx_devq_size; - /* Used octets of the device internal TX buffer. */ - u16 tx_devq_used; - /* Used packet slots in the device internal TX buffer. */ - u8 tx_devq_packets; - /* Packets from the txfree list can - * be taken on incoming TX requests. - */ - struct list_head txfree; - unsigned int nr_txfree; - /* Packets on the txqueue are queued, - * but not completely written to the chip, yet. - */ - struct list_head txqueue; - /* Packets on the txrunning queue are completely - * posted to the device. We are waiting for the txstatus. - */ - struct list_head txrunning; - /* Total number or packets sent. - * (This counter can obviously wrap). - */ - unsigned int nr_tx_packets; - struct tasklet_struct txtask; - struct bcm43xx_pio_txpacket tx_packets_cache[BCM43xx_PIO_MAXTXPACKETS]; -}; - -static inline -u16 bcm43xx_pio_read(struct bcm43xx_pioqueue *queue, - u16 offset) -{ - return bcm43xx_read16(queue->bcm, queue->mmio_base + offset); -} - -static inline -void bcm43xx_pio_write(struct bcm43xx_pioqueue *queue, - u16 offset, u16 value) -{ - bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value); - mmiowb(); -} - - -int bcm43xx_pio_init(struct bcm43xx_private *bcm); -void bcm43xx_pio_free(struct bcm43xx_private *bcm); - -int bcm43xx_pio_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb); -void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status); -void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); - -void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue); -void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue); - -#else /* CONFIG_BCM43XX_PIO */ - -static inline -int bcm43xx_pio_init(struct bcm43xx_private *bcm) -{ - return 0; -} -static inline -void bcm43xx_pio_free(struct bcm43xx_private *bcm) -{ -} -static inline -int bcm43xx_pio_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - return 0; -} -static inline -void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ -} -static inline -void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) -{ -} -static inline -void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue) -{ -} -static inline -void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) -{ -} - -#endif /* CONFIG_BCM43XX_PIO */ -#endif /* BCM43xx_PIO_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c deleted file mode 100644 index 6569da3a7..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_power.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include - -#include "bcm43xx.h" -#include "bcm43xx_power.h" -#include "bcm43xx_main.h" - - -/* Get the Slow Clock Source */ -static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm) -{ - u32 tmp; - int err; - - assert(bcm->current_core == &bcm->core_chipcommon); - if (bcm->current_core->rev < 6) { - if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA || - bcm->bustype == BCM43xx_BUSTYPE_SB) - return BCM43xx_PCTL_CLKSRC_XTALOS; - if (bcm->bustype == BCM43xx_BUSTYPE_PCI) { - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); - assert(!err); - if (tmp & 0x10) - return BCM43xx_PCTL_CLKSRC_PCI; - return BCM43xx_PCTL_CLKSRC_XTALOS; - } - } - if (bcm->current_core->rev < 10) { - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - tmp &= 0x7; - if (tmp == 0) - return BCM43xx_PCTL_CLKSRC_LOPWROS; - if (tmp == 1) - return BCM43xx_PCTL_CLKSRC_XTALOS; - if (tmp == 2) - return BCM43xx_PCTL_CLKSRC_PCI; - } - - return BCM43xx_PCTL_CLKSRC_XTALOS; -} - -/* Get max/min slowclock frequency - * as described in http://bcm-specs.sipsolutions.net/PowerControl - */ -static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, - int get_max) -{ - int limit; - int clocksrc; - int divisor; - u32 tmp; - - assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL); - assert(bcm->current_core == &bcm->core_chipcommon); - - clocksrc = bcm43xx_pctl_get_slowclksrc(bcm); - if (bcm->current_core->rev < 6) { - switch (clocksrc) { - case BCM43xx_PCTL_CLKSRC_PCI: - divisor = 64; - break; - case BCM43xx_PCTL_CLKSRC_XTALOS: - divisor = 32; - break; - default: - assert(0); - divisor = 1; - } - } else if (bcm->current_core->rev < 10) { - switch (clocksrc) { - case BCM43xx_PCTL_CLKSRC_LOPWROS: - divisor = 1; - break; - case BCM43xx_PCTL_CLKSRC_XTALOS: - case BCM43xx_PCTL_CLKSRC_PCI: - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - divisor = ((tmp & 0xFFFF0000) >> 16) + 1; - divisor *= 4; - break; - default: - assert(0); - divisor = 1; - } - } else { - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL); - divisor = ((tmp & 0xFFFF0000) >> 16) + 1; - divisor *= 4; - } - - switch (clocksrc) { - case BCM43xx_PCTL_CLKSRC_LOPWROS: - if (get_max) - limit = 43000; - else - limit = 25000; - break; - case BCM43xx_PCTL_CLKSRC_XTALOS: - if (get_max) - limit = 20200000; - else - limit = 19800000; - break; - case BCM43xx_PCTL_CLKSRC_PCI: - if (get_max) - limit = 34000000; - else - limit = 25000000; - break; - default: - assert(0); - limit = 0; - } - limit /= divisor; - - return limit; -} - - -/* init power control - * as described in http://bcm-specs.sipsolutions.net/PowerControl - */ -int bcm43xx_pctl_init(struct bcm43xx_private *bcm) -{ - int err, maxfreq; - struct bcm43xx_coreinfo *old_core; - - if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) - return 0; - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err == -ENODEV) - return 0; - if (err) - goto out; - - maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1); - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY, - (maxfreq * 150 + 999999) / 1000000); - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY, - (maxfreq * 15 + 999999) / 1000000); - - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - -out: - return err; -} - -u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm) -{ - u16 delay = 0; - int err; - u32 pll_on_delay; - struct bcm43xx_coreinfo *old_core; - int minfreq; - - if (bcm->bustype != BCM43xx_BUSTYPE_PCI) - goto out; - if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) - goto out; - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err == -ENODEV) - goto out; - - minfreq = bcm43xx_pctl_clockfreqlimit(bcm, 0); - pll_on_delay = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY); - delay = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq; - - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - -out: - return delay; -} - -/* set the powercontrol clock - * as described in http://bcm-specs.sipsolutions.net/PowerControl - */ -int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode) -{ - int err; - struct bcm43xx_coreinfo *old_core; - u32 tmp; - - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err == -ENODEV) - return 0; - if (err) - goto out; - - if (bcm->core_chipcommon.rev < 6) { - if (mode == BCM43xx_PCTL_CLK_FAST) { - err = bcm43xx_pctl_set_crystal(bcm, 1); - if (err) - goto out; - } - } else { - if ((bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) && - (bcm->core_chipcommon.rev < 10)) { - switch (mode) { - case BCM43xx_PCTL_CLK_FAST: - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - tmp = (tmp & ~BCM43xx_PCTL_FORCE_SLOW) | BCM43xx_PCTL_FORCE_PLL; - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp); - break; - case BCM43xx_PCTL_CLK_SLOW: - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - tmp |= BCM43xx_PCTL_FORCE_SLOW; - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp); - break; - case BCM43xx_PCTL_CLK_DYNAMIC: - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - tmp &= ~BCM43xx_PCTL_FORCE_SLOW; - tmp |= BCM43xx_PCTL_FORCE_PLL; - tmp &= ~BCM43xx_PCTL_DYN_XTAL; - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp); - } - } - } - - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - -out: - return err; -} - -int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on) -{ - int err; - u32 in, out, outenable; - - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_IN, &in); - if (err) - goto err_pci; - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &out); - if (err) - goto err_pci; - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUTENABLE, &outenable); - if (err) - goto err_pci; - - outenable |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN); - - if (on) { - if (in & 0x40) - return 0; - - out |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN); - - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out); - if (err) - goto err_pci; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable); - if (err) - goto err_pci; - udelay(1000); - - out &= ~BCM43xx_PCTL_PLL_POWERDOWN; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out); - if (err) - goto err_pci; - udelay(5000); - } else { - if (bcm->current_core->rev < 5) - return 0; - if (bcm->sprom.boardflags & BCM43xx_BFL_XTAL_NOSLOW) - return 0; - -/* XXX: Why BCM43xx_MMIO_RADIO_HWENABLED_xx can't be read at this time? - * err = bcm43xx_switch_core(bcm, bcm->active_80211_core); - * if (err) - * return err; - * if (((bcm->current_core->rev >= 3) && - * (bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI) & (1 << 16))) || - * ((bcm->current_core->rev < 3) && - * !(bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO) & (1 << 4)))) - * return 0; - * err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - * if (err) - * return err; - */ - - err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW); - if (err) - goto out; - out &= ~BCM43xx_PCTL_XTAL_POWERUP; - out |= BCM43xx_PCTL_PLL_POWERDOWN; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out); - if (err) - goto err_pci; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable); - if (err) - goto err_pci; - } - -out: - return err; - -err_pci: - printk(KERN_ERR PFX "Error: pctl_set_clock() could not access PCI config space!\n"); - err = -EBUSY; - goto out; -} - -/* Set the PowerSavingControlBits. - * Bitvalues: - * 0 => unset the bit - * 1 => set the bit - * -1 => calculate the bit - */ -void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm, - int bit25, int bit26) -{ - int i; - u32 status; - -//FIXME: Force 25 to off and 26 to on for now: -bit25 = 0; -bit26 = 1; - - if (bit25 == -1) { - //TODO: If powersave is not off and FIXME is not set and we are not in adhoc - // and thus is not an AP and we are associated, set bit 25 - } - if (bit26 == -1) { - //TODO: If the device is awake or this is an AP, or we are scanning, or FIXME, - // or we are associated, or FIXME, or the latest PS-Poll packet sent was - // successful, set bit26 - } - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - if (bit25) - status |= BCM43xx_SBF_PS1; - else - status &= ~BCM43xx_SBF_PS1; - if (bit26) - status |= BCM43xx_SBF_PS2; - else - status &= ~BCM43xx_SBF_PS2; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - if (bit26 && bcm->current_core->rev >= 5) { - for (i = 0; i < 100; i++) { - if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0040) != 4) - break; - udelay(10); - } - } -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.h b/drivers/net/wireless/bcm43xx/bcm43xx_power.h deleted file mode 100644 index c966ab3a5..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_power.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_POWER_H_ -#define BCM43xx_POWER_H_ - -#include - -/* Clock sources */ -enum { - /* PCI clock */ - BCM43xx_PCTL_CLKSRC_PCI, - /* Crystal slow clock oscillator */ - BCM43xx_PCTL_CLKSRC_XTALOS, - /* Low power oscillator */ - BCM43xx_PCTL_CLKSRC_LOPWROS, -}; - -struct bcm43xx_private; - -int bcm43xx_pctl_init(struct bcm43xx_private *bcm); -int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode); -int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on); -u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm); - -void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm, - int bit25, int bit26); - -#endif /* BCM43xx_POWER_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c deleted file mode 100644 index af5c0bff1..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c +++ /dev/null @@ -1,2026 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include - -#include "bcm43xx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_phy.h" -#include "bcm43xx_radio.h" -#include "bcm43xx_ilt.h" - - -/* Table for bcm43xx_radio_calibrationvalue() */ -static const u16 rcc_table[16] = { - 0x0002, 0x0003, 0x0001, 0x000F, - 0x0006, 0x0007, 0x0005, 0x000F, - 0x000A, 0x000B, 0x0009, 0x000F, - 0x000E, 0x000F, 0x000D, 0x000F, -}; - -/* Reverse the bits of a 4bit value. - * Example: 1101 is flipped 1011 - */ -static u16 flip_4bit(u16 value) -{ - u16 flipped = 0x0000; - - assert((value & ~0x000F) == 0x0000); - - flipped |= (value & 0x0001) << 3; - flipped |= (value & 0x0002) << 1; - flipped |= (value & 0x0004) >> 1; - flipped |= (value & 0x0008) >> 3; - - return flipped; -} - -/* Get the freq, as it has to be written to the device. */ -static inline -u16 channel2freq_bg(u8 channel) -{ - /* Frequencies are given as frequencies_bg[index] + 2.4GHz - * Starting with channel 1 - */ - static const u16 frequencies_bg[14] = { - 12, 17, 22, 27, - 32, 37, 42, 47, - 52, 57, 62, 67, - 72, 84, - }; - - assert(channel >= 1 && channel <= 14); - - return frequencies_bg[channel - 1]; -} - -/* Get the freq, as it has to be written to the device. */ -static inline -u16 channel2freq_a(u8 channel) -{ - assert(channel <= 200); - - return (5000 + 5 * channel); -} - -void bcm43xx_radio_lock(struct bcm43xx_private *bcm) -{ - u32 status; - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - status |= BCM43xx_SBF_RADIOREG_LOCK; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - mmiowb(); - udelay(10); -} - -void bcm43xx_radio_unlock(struct bcm43xx_private *bcm) -{ - u32 status; - - bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER); /* dummy read */ - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - status &= ~BCM43xx_SBF_RADIOREG_LOCK; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - mmiowb(); -} - -u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - offset |= 0x0040; - break; - case BCM43xx_PHYTYPE_B: - if (radio->version == 0x2053) { - if (offset < 0x70) - offset += 0x80; - else if (offset < 0x80) - offset += 0x70; - } else if (radio->version == 0x2050) { - offset |= 0x80; - } else - assert(0); - break; - case BCM43xx_PHYTYPE_G: - offset |= 0x80; - break; - } - - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset); - return bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW); -} - -void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val) -{ - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW, val); -} - -static void bcm43xx_set_all_gains(struct bcm43xx_private *bcm, - s16 first, s16 second, s16 third) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 i; - u16 start = 0x08, end = 0x18; - u16 offset = 0x0400; - u16 tmp; - - if (phy->rev <= 1) { - offset = 0x5000; - start = 0x10; - end = 0x20; - } - - for (i = 0; i < 4; i++) - bcm43xx_ilt_write(bcm, offset + i, first); - - for (i = start; i < end; i++) - bcm43xx_ilt_write(bcm, offset + i, second); - - if (third != -1) { - tmp = ((u16)third << 14) | ((u16)third << 6); - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | tmp); - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) & 0xBFBF) | tmp); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) & 0xBFBF) | tmp); - } - bcm43xx_dummy_transmission(bcm); -} - -static void bcm43xx_set_original_gains(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 i, tmp; - u16 offset = 0x0400; - u16 start = 0x0008, end = 0x0018; - - if (phy->rev <= 1) { - offset = 0x5000; - start = 0x0010; - end = 0x0020; - } - - for (i = 0; i < 4; i++) { - tmp = (i & 0xFFFC); - tmp |= (i & 0x0001) << 1; - tmp |= (i & 0x0002) >> 1; - - bcm43xx_ilt_write(bcm, offset + i, tmp); - } - - for (i = start; i < end; i++) - bcm43xx_ilt_write(bcm, offset + i, i - start); - - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | 0x4040); - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) & 0xBFBF) | 0x4040); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) & 0xBFBF) | 0x4000); - bcm43xx_dummy_transmission(bcm); -} - -/* Synthetic PU workaround */ -static void bcm43xx_synth_pu_workaround(struct bcm43xx_private *bcm, u8 channel) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (radio->version != 0x2050 || radio->revision >= 6) { - /* We do not need the workaround. */ - return; - } - - if (channel <= 10) { - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL, - channel2freq_bg(channel + 4)); - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL, - channel2freq_bg(1)); - } - udelay(100); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL, - channel2freq_bg(channel)); -} - -u8 bcm43xx_radio_aci_detect(struct bcm43xx_private *bcm, u8 channel) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u8 ret = 0; - u16 saved, rssi, temp; - int i, j = 0; - - saved = bcm43xx_phy_read(bcm, 0x0403); - bcm43xx_radio_selectchannel(bcm, channel, 0); - bcm43xx_phy_write(bcm, 0x0403, (saved & 0xFFF8) | 5); - if (radio->aci_hw_rssi) - rssi = bcm43xx_phy_read(bcm, 0x048A) & 0x3F; - else - rssi = saved & 0x3F; - /* clamp temp to signed 5bit */ - if (rssi > 32) - rssi -= 64; - for (i = 0;i < 100; i++) { - temp = (bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x3F; - if (temp > 32) - temp -= 64; - if (temp < rssi) - j++; - if (j >= 20) - ret = 1; - } - bcm43xx_phy_write(bcm, 0x0403, saved); - - return ret; -} - -u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u8 ret[13]; - unsigned int channel = radio->channel; - unsigned int i, j, start, end; - unsigned long phylock_flags; - - if (!((phy->type == BCM43xx_PHYTYPE_G) && (phy->rev > 0))) - return 0; - - bcm43xx_phy_lock(bcm, phylock_flags); - bcm43xx_radio_lock(bcm); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF); - bcm43xx_set_all_gains(bcm, 3, 8, 1); - - start = (channel - 5 > 0) ? channel - 5 : 1; - end = (channel + 5 < 14) ? channel + 5 : 13; - - for (i = start; i <= end; i++) { - if (abs(channel - i) > 2) - ret[i-1] = bcm43xx_radio_aci_detect(bcm, i); - } - bcm43xx_radio_selectchannel(bcm, channel, 0); - bcm43xx_phy_write(bcm, 0x0802, - (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC) | 0x0003); - bcm43xx_phy_write(bcm, 0x0403, - bcm43xx_phy_read(bcm, 0x0403) & 0xFFF8); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x8000); - bcm43xx_set_original_gains(bcm); - for (i = 0; i < 13; i++) { - if (!ret[i]) - continue; - end = (i + 5 < 13) ? i + 5 : 13; - for (j = i; j < end; j++) - ret[j] = 1; - } - bcm43xx_radio_unlock(bcm); - bcm43xx_phy_unlock(bcm, phylock_flags); - - return ret[channel - 1]; -} - -/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ -void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val) -{ - bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset); - mmiowb(); - bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_DATA, (u16)val); -} - -/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ -s16 bcm43xx_nrssi_hw_read(struct bcm43xx_private *bcm, u16 offset) -{ - u16 val; - - bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset); - val = bcm43xx_phy_read(bcm, BCM43xx_PHY_NRSSILT_DATA); - - return (s16)val; -} - -/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ -void bcm43xx_nrssi_hw_update(struct bcm43xx_private *bcm, u16 val) -{ - u16 i; - s16 tmp; - - for (i = 0; i < 64; i++) { - tmp = bcm43xx_nrssi_hw_read(bcm, i); - tmp -= val; - tmp = limit_value(tmp, -32, 31); - bcm43xx_nrssi_hw_write(bcm, i, tmp); - } -} - -/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ -void bcm43xx_nrssi_mem_update(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - s16 i, delta; - s32 tmp; - - delta = 0x1F - radio->nrssi[0]; - for (i = 0; i < 64; i++) { - tmp = (i - delta) * radio->nrssislope; - tmp /= 0x10000; - tmp += 0x3A; - tmp = limit_value(tmp, 0, 0x3F); - radio->nrssi_lt[i] = tmp; - } -} - -static void bcm43xx_calc_nrssi_offset(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 backup[20] = { 0 }; - s16 v47F; - u16 i; - u16 saved = 0xFFFF; - - backup[0] = bcm43xx_phy_read(bcm, 0x0001); - backup[1] = bcm43xx_phy_read(bcm, 0x0811); - backup[2] = bcm43xx_phy_read(bcm, 0x0812); - backup[3] = bcm43xx_phy_read(bcm, 0x0814); - backup[4] = bcm43xx_phy_read(bcm, 0x0815); - backup[5] = bcm43xx_phy_read(bcm, 0x005A); - backup[6] = bcm43xx_phy_read(bcm, 0x0059); - backup[7] = bcm43xx_phy_read(bcm, 0x0058); - backup[8] = bcm43xx_phy_read(bcm, 0x000A); - backup[9] = bcm43xx_phy_read(bcm, 0x0003); - backup[10] = bcm43xx_radio_read16(bcm, 0x007A); - backup[11] = bcm43xx_radio_read16(bcm, 0x0043); - - bcm43xx_phy_write(bcm, 0x0429, - bcm43xx_phy_read(bcm, 0x0429) & 0x7FFF); - bcm43xx_phy_write(bcm, 0x0001, - (bcm43xx_phy_read(bcm, 0x0001) & 0x3FFF) | 0x4000); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x000C); - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) & 0xFFF3) | 0x0004); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) & ~(0x1 | 0x2)); - if (phy->rev >= 6) { - backup[12] = bcm43xx_phy_read(bcm, 0x002E); - backup[13] = bcm43xx_phy_read(bcm, 0x002F); - backup[14] = bcm43xx_phy_read(bcm, 0x080F); - backup[15] = bcm43xx_phy_read(bcm, 0x0810); - backup[16] = bcm43xx_phy_read(bcm, 0x0801); - backup[17] = bcm43xx_phy_read(bcm, 0x0060); - backup[18] = bcm43xx_phy_read(bcm, 0x0014); - backup[19] = bcm43xx_phy_read(bcm, 0x0478); - - bcm43xx_phy_write(bcm, 0x002E, 0); - bcm43xx_phy_write(bcm, 0x002F, 0); - bcm43xx_phy_write(bcm, 0x080F, 0); - bcm43xx_phy_write(bcm, 0x0810, 0); - bcm43xx_phy_write(bcm, 0x0478, - bcm43xx_phy_read(bcm, 0x0478) | 0x0100); - bcm43xx_phy_write(bcm, 0x0801, - bcm43xx_phy_read(bcm, 0x0801) | 0x0040); - bcm43xx_phy_write(bcm, 0x0060, - bcm43xx_phy_read(bcm, 0x0060) | 0x0040); - bcm43xx_phy_write(bcm, 0x0014, - bcm43xx_phy_read(bcm, 0x0014) | 0x0200); - } - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0070); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0080); - udelay(30); - - v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (v47F >= 0x20) - v47F -= 0x40; - if (v47F == 31) { - for (i = 7; i >= 4; i--) { - bcm43xx_radio_write16(bcm, 0x007B, i); - udelay(20); - v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (v47F >= 0x20) - v47F -= 0x40; - if (v47F < 31 && saved == 0xFFFF) - saved = i; - } - if (saved == 0xFFFF) - saved = 4; - } else { - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) & 0x007F); - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0001); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x000C); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) | 0x000C); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x0030); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) | 0x0030); - bcm43xx_phy_write(bcm, 0x005A, 0x0480); - bcm43xx_phy_write(bcm, 0x0059, 0x0810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - if (phy->rev == 0) { - bcm43xx_phy_write(bcm, 0x0003, 0x0122); - } else { - bcm43xx_phy_write(bcm, 0x000A, - bcm43xx_phy_read(bcm, 0x000A) - | 0x2000); - } - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0004); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB); - bcm43xx_phy_write(bcm, 0x0003, - (bcm43xx_phy_read(bcm, 0x0003) & 0xFF9F) - | 0x0040); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x000F); - bcm43xx_set_all_gains(bcm, 3, 0, 1); - bcm43xx_radio_write16(bcm, 0x0043, - (bcm43xx_radio_read16(bcm, 0x0043) - & 0x00F0) | 0x000F); - udelay(30); - v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (v47F >= 0x20) - v47F -= 0x40; - if (v47F == -32) { - for (i = 0; i < 4; i++) { - bcm43xx_radio_write16(bcm, 0x007B, i); - udelay(20); - v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (v47F >= 0x20) - v47F -= 0x40; - if (v47F > -31 && saved == 0xFFFF) - saved = i; - } - if (saved == 0xFFFF) - saved = 3; - } else - saved = 0; - } - bcm43xx_radio_write16(bcm, 0x007B, saved); - - if (phy->rev >= 6) { - bcm43xx_phy_write(bcm, 0x002E, backup[12]); - bcm43xx_phy_write(bcm, 0x002F, backup[13]); - bcm43xx_phy_write(bcm, 0x080F, backup[14]); - bcm43xx_phy_write(bcm, 0x0810, backup[15]); - } - bcm43xx_phy_write(bcm, 0x0814, backup[3]); - bcm43xx_phy_write(bcm, 0x0815, backup[4]); - bcm43xx_phy_write(bcm, 0x005A, backup[5]); - bcm43xx_phy_write(bcm, 0x0059, backup[6]); - bcm43xx_phy_write(bcm, 0x0058, backup[7]); - bcm43xx_phy_write(bcm, 0x000A, backup[8]); - bcm43xx_phy_write(bcm, 0x0003, backup[9]); - bcm43xx_radio_write16(bcm, 0x0043, backup[11]); - bcm43xx_radio_write16(bcm, 0x007A, backup[10]); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) | 0x1 | 0x2); - bcm43xx_phy_write(bcm, 0x0429, - bcm43xx_phy_read(bcm, 0x0429) | 0x8000); - bcm43xx_set_original_gains(bcm); - if (phy->rev >= 6) { - bcm43xx_phy_write(bcm, 0x0801, backup[16]); - bcm43xx_phy_write(bcm, 0x0060, backup[17]); - bcm43xx_phy_write(bcm, 0x0014, backup[18]); - bcm43xx_phy_write(bcm, 0x0478, backup[19]); - } - bcm43xx_phy_write(bcm, 0x0001, backup[0]); - bcm43xx_phy_write(bcm, 0x0812, backup[2]); - bcm43xx_phy_write(bcm, 0x0811, backup[1]); -} - -void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 backup[18] = { 0 }; - u16 tmp; - s16 nrssi0, nrssi1; - - switch (phy->type) { - case BCM43xx_PHYTYPE_B: - backup[0] = bcm43xx_radio_read16(bcm, 0x007A); - backup[1] = bcm43xx_radio_read16(bcm, 0x0052); - backup[2] = bcm43xx_radio_read16(bcm, 0x0043); - backup[3] = bcm43xx_phy_read(bcm, 0x0030); - backup[4] = bcm43xx_phy_read(bcm, 0x0026); - backup[5] = bcm43xx_phy_read(bcm, 0x0015); - backup[6] = bcm43xx_phy_read(bcm, 0x002A); - backup[7] = bcm43xx_phy_read(bcm, 0x0020); - backup[8] = bcm43xx_phy_read(bcm, 0x005A); - backup[9] = bcm43xx_phy_read(bcm, 0x0059); - backup[10] = bcm43xx_phy_read(bcm, 0x0058); - backup[11] = bcm43xx_read16(bcm, 0x03E2); - backup[12] = bcm43xx_read16(bcm, 0x03E6); - backup[13] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); - - tmp = bcm43xx_radio_read16(bcm, 0x007A); - tmp &= (phy->rev >= 5) ? 0x007F : 0x000F; - bcm43xx_radio_write16(bcm, 0x007A, tmp); - bcm43xx_phy_write(bcm, 0x0030, 0x00FF); - bcm43xx_write16(bcm, 0x03EC, 0x7F7F); - bcm43xx_phy_write(bcm, 0x0026, 0x0000); - bcm43xx_phy_write(bcm, 0x0015, - bcm43xx_phy_read(bcm, 0x0015) | 0x0020); - bcm43xx_phy_write(bcm, 0x002A, 0x08A3); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0080); - - nrssi0 = (s16)bcm43xx_phy_read(bcm, 0x0027); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) & 0x007F); - if (phy->rev >= 2) { - bcm43xx_write16(bcm, 0x03E6, 0x0040); - } else if (phy->rev == 0) { - bcm43xx_write16(bcm, 0x03E6, 0x0122); - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) & 0x2000); - } - bcm43xx_phy_write(bcm, 0x0020, 0x3F3F); - bcm43xx_phy_write(bcm, 0x0015, 0xF330); - bcm43xx_radio_write16(bcm, 0x005A, 0x0060); - bcm43xx_radio_write16(bcm, 0x0043, - bcm43xx_radio_read16(bcm, 0x0043) & 0x00F0); - bcm43xx_phy_write(bcm, 0x005A, 0x0480); - bcm43xx_phy_write(bcm, 0x0059, 0x0810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - udelay(20); - - nrssi1 = (s16)bcm43xx_phy_read(bcm, 0x0027); - bcm43xx_phy_write(bcm, 0x0030, backup[3]); - bcm43xx_radio_write16(bcm, 0x007A, backup[0]); - bcm43xx_write16(bcm, 0x03E2, backup[11]); - bcm43xx_phy_write(bcm, 0x0026, backup[4]); - bcm43xx_phy_write(bcm, 0x0015, backup[5]); - bcm43xx_phy_write(bcm, 0x002A, backup[6]); - bcm43xx_synth_pu_workaround(bcm, radio->channel); - if (phy->rev != 0) - bcm43xx_write16(bcm, 0x03F4, backup[13]); - - bcm43xx_phy_write(bcm, 0x0020, backup[7]); - bcm43xx_phy_write(bcm, 0x005A, backup[8]); - bcm43xx_phy_write(bcm, 0x0059, backup[9]); - bcm43xx_phy_write(bcm, 0x0058, backup[10]); - bcm43xx_radio_write16(bcm, 0x0052, backup[1]); - bcm43xx_radio_write16(bcm, 0x0043, backup[2]); - - if (nrssi0 == nrssi1) - radio->nrssislope = 0x00010000; - else - radio->nrssislope = 0x00400000 / (nrssi0 - nrssi1); - - if (nrssi0 <= -4) { - radio->nrssi[0] = nrssi0; - radio->nrssi[1] = nrssi1; - } - break; - case BCM43xx_PHYTYPE_G: - if (radio->revision >= 9) - return; - if (radio->revision == 8) - bcm43xx_calc_nrssi_offset(bcm); - - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC); - backup[7] = bcm43xx_read16(bcm, 0x03E2); - bcm43xx_write16(bcm, 0x03E2, - bcm43xx_read16(bcm, 0x03E2) | 0x8000); - backup[0] = bcm43xx_radio_read16(bcm, 0x007A); - backup[1] = bcm43xx_radio_read16(bcm, 0x0052); - backup[2] = bcm43xx_radio_read16(bcm, 0x0043); - backup[3] = bcm43xx_phy_read(bcm, 0x0015); - backup[4] = bcm43xx_phy_read(bcm, 0x005A); - backup[5] = bcm43xx_phy_read(bcm, 0x0059); - backup[6] = bcm43xx_phy_read(bcm, 0x0058); - backup[8] = bcm43xx_read16(bcm, 0x03E6); - backup[9] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); - if (phy->rev >= 3) { - backup[10] = bcm43xx_phy_read(bcm, 0x002E); - backup[11] = bcm43xx_phy_read(bcm, 0x002F); - backup[12] = bcm43xx_phy_read(bcm, 0x080F); - backup[13] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_LO_CONTROL); - backup[14] = bcm43xx_phy_read(bcm, 0x0801); - backup[15] = bcm43xx_phy_read(bcm, 0x0060); - backup[16] = bcm43xx_phy_read(bcm, 0x0014); - backup[17] = bcm43xx_phy_read(bcm, 0x0478); - bcm43xx_phy_write(bcm, 0x002E, 0); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, 0); - switch (phy->rev) { - case 4: case 6: case 7: - bcm43xx_phy_write(bcm, 0x0478, - bcm43xx_phy_read(bcm, 0x0478) - | 0x0100); - bcm43xx_phy_write(bcm, 0x0801, - bcm43xx_phy_read(bcm, 0x0801) - | 0x0040); - break; - case 3: case 5: - bcm43xx_phy_write(bcm, 0x0801, - bcm43xx_phy_read(bcm, 0x0801) - & 0xFFBF); - break; - } - bcm43xx_phy_write(bcm, 0x0060, - bcm43xx_phy_read(bcm, 0x0060) - | 0x0040); - bcm43xx_phy_write(bcm, 0x0014, - bcm43xx_phy_read(bcm, 0x0014) - | 0x0200); - } - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0070); - bcm43xx_set_all_gains(bcm, 0, 8, 0); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) & 0x00F7); - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0811, - (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0030); - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0010); - } - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0080); - udelay(20); - - nrssi0 = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (nrssi0 >= 0x0020) - nrssi0 -= 0x0040; - - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) & 0x007F); - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0003, - (bcm43xx_phy_read(bcm, 0x0003) - & 0xFF9F) | 0x0040); - } - - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) - | 0x2000); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x000F); - bcm43xx_phy_write(bcm, 0x0015, 0xF330); - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0020); - bcm43xx_phy_write(bcm, 0x0811, - (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0020); - } - - bcm43xx_set_all_gains(bcm, 3, 0, 1); - if (radio->revision == 8) { - bcm43xx_radio_write16(bcm, 0x0043, 0x001F); - } else { - tmp = bcm43xx_radio_read16(bcm, 0x0052) & 0xFF0F; - bcm43xx_radio_write16(bcm, 0x0052, tmp | 0x0060); - tmp = bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0; - bcm43xx_radio_write16(bcm, 0x0043, tmp | 0x0009); - } - bcm43xx_phy_write(bcm, 0x005A, 0x0480); - bcm43xx_phy_write(bcm, 0x0059, 0x0810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - udelay(20); - nrssi1 = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (nrssi1 >= 0x0020) - nrssi1 -= 0x0040; - if (nrssi0 == nrssi1) - radio->nrssislope = 0x00010000; - else - radio->nrssislope = 0x00400000 / (nrssi0 - nrssi1); - if (nrssi0 >= -4) { - radio->nrssi[0] = nrssi1; - radio->nrssi[1] = nrssi0; - } - if (phy->rev >= 3) { - bcm43xx_phy_write(bcm, 0x002E, backup[10]); - bcm43xx_phy_write(bcm, 0x002F, backup[11]); - bcm43xx_phy_write(bcm, 0x080F, backup[12]); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, backup[13]); - } - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF); - } - - bcm43xx_radio_write16(bcm, 0x007A, backup[0]); - bcm43xx_radio_write16(bcm, 0x0052, backup[1]); - bcm43xx_radio_write16(bcm, 0x0043, backup[2]); - bcm43xx_write16(bcm, 0x03E2, backup[7]); - bcm43xx_write16(bcm, 0x03E6, backup[8]); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[9]); - bcm43xx_phy_write(bcm, 0x0015, backup[3]); - bcm43xx_phy_write(bcm, 0x005A, backup[4]); - bcm43xx_phy_write(bcm, 0x0059, backup[5]); - bcm43xx_phy_write(bcm, 0x0058, backup[6]); - bcm43xx_synth_pu_workaround(bcm, radio->channel); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) | (0x0001 | 0x0002)); - bcm43xx_set_original_gains(bcm); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x8000); - if (phy->rev >= 3) { - bcm43xx_phy_write(bcm, 0x0801, backup[14]); - bcm43xx_phy_write(bcm, 0x0060, backup[15]); - bcm43xx_phy_write(bcm, 0x0014, backup[16]); - bcm43xx_phy_write(bcm, 0x0478, backup[17]); - } - bcm43xx_nrssi_mem_update(bcm); - bcm43xx_calc_nrssi_threshold(bcm); - break; - default: - assert(0); - } -} - -void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - s32 threshold; - s32 a, b; - s16 tmp16; - u16 tmp_u16; - - switch (phy->type) { - case BCM43xx_PHYTYPE_B: { - if (radio->version != 0x2050) - return; - if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) - return; - - if (radio->revision >= 6) { - threshold = (radio->nrssi[1] - radio->nrssi[0]) * 32; - threshold += 20 * (radio->nrssi[0] + 1); - threshold /= 40; - } else - threshold = radio->nrssi[1] - 5; - - threshold = limit_value(threshold, 0, 0x3E); - bcm43xx_phy_read(bcm, 0x0020); /* dummy read */ - bcm43xx_phy_write(bcm, 0x0020, (((u16)threshold) << 8) | 0x001C); - - if (radio->revision >= 6) { - bcm43xx_phy_write(bcm, 0x0087, 0x0E0D); - bcm43xx_phy_write(bcm, 0x0086, 0x0C0B); - bcm43xx_phy_write(bcm, 0x0085, 0x0A09); - bcm43xx_phy_write(bcm, 0x0084, 0x0808); - bcm43xx_phy_write(bcm, 0x0083, 0x0808); - bcm43xx_phy_write(bcm, 0x0082, 0x0604); - bcm43xx_phy_write(bcm, 0x0081, 0x0302); - bcm43xx_phy_write(bcm, 0x0080, 0x0100); - } - break; - } - case BCM43xx_PHYTYPE_G: - if (!phy->connected || - !(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) { - tmp16 = bcm43xx_nrssi_hw_read(bcm, 0x20); - if (tmp16 >= 0x20) - tmp16 -= 0x40; - if (tmp16 < 3) { - bcm43xx_phy_write(bcm, 0x048A, - (bcm43xx_phy_read(bcm, 0x048A) - & 0xF000) | 0x09EB); - } else { - bcm43xx_phy_write(bcm, 0x048A, - (bcm43xx_phy_read(bcm, 0x048A) - & 0xF000) | 0x0AED); - } - } else { - if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN) { - a = 0xE; - b = 0xA; - } else if (!radio->aci_wlan_automatic && radio->aci_enable) { - a = 0x13; - b = 0x12; - } else { - a = 0xE; - b = 0x11; - } - - a = a * (radio->nrssi[1] - radio->nrssi[0]); - a += (radio->nrssi[0] << 6); - if (a < 32) - a += 31; - else - a += 32; - a = a >> 6; - a = limit_value(a, -31, 31); - - b = b * (radio->nrssi[1] - radio->nrssi[0]); - b += (radio->nrssi[0] << 6); - if (b < 32) - b += 31; - else - b += 32; - b = b >> 6; - b = limit_value(b, -31, 31); - - tmp_u16 = bcm43xx_phy_read(bcm, 0x048A) & 0xF000; - tmp_u16 |= ((u32)b & 0x0000003F); - tmp_u16 |= (((u32)a & 0x0000003F) << 6); - bcm43xx_phy_write(bcm, 0x048A, tmp_u16); - } - break; - default: - assert(0); - } -} - -/* Stack implementation to save/restore values from the - * interference mitigation code. - * It is save to restore values in random order. - */ -static void _stack_save(u32 *_stackptr, size_t *stackidx, - u8 id, u16 offset, u16 value) -{ - u32 *stackptr = &(_stackptr[*stackidx]); - - assert((offset & 0xF000) == 0x0000); - assert((id & 0xF0) == 0x00); - *stackptr = offset; - *stackptr |= ((u32)id) << 12; - *stackptr |= ((u32)value) << 16; - (*stackidx)++; - assert(*stackidx < BCM43xx_INTERFSTACK_SIZE); -} - -static u16 _stack_restore(u32 *stackptr, - u8 id, u16 offset) -{ - size_t i; - - assert((offset & 0xF000) == 0x0000); - assert((id & 0xF0) == 0x00); - for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) { - if ((*stackptr & 0x00000FFF) != offset) - continue; - if (((*stackptr & 0x0000F000) >> 12) != id) - continue; - return ((*stackptr & 0xFFFF0000) >> 16); - } - assert(0); - - return 0; -} - -#define phy_stacksave(offset) \ - do { \ - _stack_save(stack, &stackidx, 0x1, (offset), \ - bcm43xx_phy_read(bcm, (offset))); \ - } while (0) -#define phy_stackrestore(offset) \ - do { \ - bcm43xx_phy_write(bcm, (offset), \ - _stack_restore(stack, 0x1, \ - (offset))); \ - } while (0) -#define radio_stacksave(offset) \ - do { \ - _stack_save(stack, &stackidx, 0x2, (offset), \ - bcm43xx_radio_read16(bcm, (offset))); \ - } while (0) -#define radio_stackrestore(offset) \ - do { \ - bcm43xx_radio_write16(bcm, (offset), \ - _stack_restore(stack, 0x2, \ - (offset))); \ - } while (0) -#define ilt_stacksave(offset) \ - do { \ - _stack_save(stack, &stackidx, 0x3, (offset), \ - bcm43xx_ilt_read(bcm, (offset))); \ - } while (0) -#define ilt_stackrestore(offset) \ - do { \ - bcm43xx_ilt_write(bcm, (offset), \ - _stack_restore(stack, 0x3, \ - (offset))); \ - } while (0) - -static void -bcm43xx_radio_interference_mitigation_enable(struct bcm43xx_private *bcm, - int mode) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 tmp, flipped; - u32 tmp32; - size_t stackidx = 0; - u32 *stack = radio->interfstack; - - switch (mode) { - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - if (phy->rev != 1) { - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) | 0x0800); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & ~0x4000); - break; - } - radio_stacksave(0x0078); - tmp = (bcm43xx_radio_read16(bcm, 0x0078) & 0x001E); - flipped = flip_4bit(tmp); - if (flipped < 10 && flipped >= 8) - flipped = 7; - else if (flipped >= 10) - flipped -= 3; - flipped = flip_4bit(flipped); - flipped = (flipped << 1) | 0x0020; - bcm43xx_radio_write16(bcm, 0x0078, flipped); - - bcm43xx_calc_nrssi_threshold(bcm); - - phy_stacksave(0x0406); - bcm43xx_phy_write(bcm, 0x0406, 0x7E28); - - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) | 0x0800); - bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, - bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | 0x1000); - - phy_stacksave(0x04A0); - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) & 0xC0C0) | 0x0008); - phy_stacksave(0x04A1); - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) & 0xC0C0) | 0x0605); - phy_stacksave(0x04A2); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) & 0xC0C0) | 0x0204); - phy_stacksave(0x04A8); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) & 0xC0C0) | 0x0803); - phy_stacksave(0x04AB); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) & 0xC0C0) | 0x0605); - - phy_stacksave(0x04A7); - bcm43xx_phy_write(bcm, 0x04A7, 0x0002); - phy_stacksave(0x04A3); - bcm43xx_phy_write(bcm, 0x04A3, 0x287A); - phy_stacksave(0x04A9); - bcm43xx_phy_write(bcm, 0x04A9, 0x2027); - phy_stacksave(0x0493); - bcm43xx_phy_write(bcm, 0x0493, 0x32F5); - phy_stacksave(0x04AA); - bcm43xx_phy_write(bcm, 0x04AA, 0x2027); - phy_stacksave(0x04AC); - bcm43xx_phy_write(bcm, 0x04AC, 0x32F5); - break; - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - if (bcm43xx_phy_read(bcm, 0x0033) & 0x0800) - break; - - radio->aci_enable = 1; - - phy_stacksave(BCM43xx_PHY_RADIO_BITFIELD); - phy_stacksave(BCM43xx_PHY_G_CRS); - if (phy->rev < 2) { - phy_stacksave(0x0406); - } else { - phy_stacksave(0x04C0); - phy_stacksave(0x04C1); - } - phy_stacksave(0x0033); - phy_stacksave(0x04A7); - phy_stacksave(0x04A3); - phy_stacksave(0x04A9); - phy_stacksave(0x04AA); - phy_stacksave(0x04AC); - phy_stacksave(0x0493); - phy_stacksave(0x04A1); - phy_stacksave(0x04A0); - phy_stacksave(0x04A2); - phy_stacksave(0x048A); - phy_stacksave(0x04A8); - phy_stacksave(0x04AB); - if (phy->rev == 2) { - phy_stacksave(0x04AD); - phy_stacksave(0x04AE); - } else if (phy->rev >= 3) { - phy_stacksave(0x04AD); - phy_stacksave(0x0415); - phy_stacksave(0x0416); - phy_stacksave(0x0417); - ilt_stacksave(0x1A00 + 0x2); - ilt_stacksave(0x1A00 + 0x3); - } - phy_stacksave(0x042B); - phy_stacksave(0x048C); - - bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, - bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) - & ~0x1000); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) - & 0xFFFC) | 0x0002); - - bcm43xx_phy_write(bcm, 0x0033, 0x0800); - bcm43xx_phy_write(bcm, 0x04A3, 0x2027); - bcm43xx_phy_write(bcm, 0x04A9, 0x1CA8); - bcm43xx_phy_write(bcm, 0x0493, 0x287A); - bcm43xx_phy_write(bcm, 0x04AA, 0x1CA8); - bcm43xx_phy_write(bcm, 0x04AC, 0x287A); - - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) - & 0xFFC0) | 0x001A); - bcm43xx_phy_write(bcm, 0x04A7, 0x000D); - - if (phy->rev < 2) { - bcm43xx_phy_write(bcm, 0x0406, 0xFF0D); - } else if (phy->rev == 2) { - bcm43xx_phy_write(bcm, 0x04C0, 0xFFFF); - bcm43xx_phy_write(bcm, 0x04C1, 0x00A9); - } else { - bcm43xx_phy_write(bcm, 0x04C0, 0x00C1); - bcm43xx_phy_write(bcm, 0x04C1, 0x0059); - } - - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) - & 0xC0FF) | 0x1800); - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) - & 0xFFC0) | 0x0015); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) - & 0xCFFF) | 0x1000); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) - & 0xF0FF) | 0x0A00); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) - & 0xCFFF) | 0x1000); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) - & 0xF0FF) | 0x0800); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) - & 0xFFCF) | 0x0010); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) - & 0xFFF0) | 0x0005); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) - & 0xFFCF) | 0x0010); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) - & 0xFFF0) | 0x0006); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) - & 0xF0FF) | 0x0800); - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) - & 0xF0FF) | 0x0500); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) - & 0xFFF0) | 0x000B); - - if (phy->rev >= 3) { - bcm43xx_phy_write(bcm, 0x048A, - bcm43xx_phy_read(bcm, 0x048A) - & ~0x8000); - bcm43xx_phy_write(bcm, 0x0415, - (bcm43xx_phy_read(bcm, 0x0415) - & 0x8000) | 0x36D8); - bcm43xx_phy_write(bcm, 0x0416, - (bcm43xx_phy_read(bcm, 0x0416) - & 0x8000) | 0x36D8); - bcm43xx_phy_write(bcm, 0x0417, - (bcm43xx_phy_read(bcm, 0x0417) - & 0xFE00) | 0x016D); - } else { - bcm43xx_phy_write(bcm, 0x048A, - bcm43xx_phy_read(bcm, 0x048A) - | 0x1000); - bcm43xx_phy_write(bcm, 0x048A, - (bcm43xx_phy_read(bcm, 0x048A) - & 0x9FFF) | 0x2000); - tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET); - if (!(tmp32 & 0x800)) { - tmp32 |= 0x800; - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - tmp32); - } - } - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) - | 0x0800); - } - bcm43xx_phy_write(bcm, 0x048C, - (bcm43xx_phy_read(bcm, 0x048C) - & 0xF0FF) | 0x0200); - if (phy->rev == 2) { - bcm43xx_phy_write(bcm, 0x04AE, - (bcm43xx_phy_read(bcm, 0x04AE) - & 0xFF00) | 0x007F); - bcm43xx_phy_write(bcm, 0x04AD, - (bcm43xx_phy_read(bcm, 0x04AD) - & 0x00FF) | 0x1300); - } else if (phy->rev >= 6) { - bcm43xx_ilt_write(bcm, 0x1A00 + 0x3, 0x007F); - bcm43xx_ilt_write(bcm, 0x1A00 + 0x2, 0x007F); - bcm43xx_phy_write(bcm, 0x04AD, - bcm43xx_phy_read(bcm, 0x04AD) - & 0x00FF); - } - bcm43xx_calc_nrssi_slope(bcm); - break; - default: - assert(0); - } -} - -static void -bcm43xx_radio_interference_mitigation_disable(struct bcm43xx_private *bcm, - int mode) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u32 tmp32; - u32 *stack = radio->interfstack; - - switch (mode) { - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - if (phy->rev != 1) { - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) & ~0x0800); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000); - break; - } - phy_stackrestore(0x0078); - bcm43xx_calc_nrssi_threshold(bcm); - phy_stackrestore(0x0406); - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) & ~0x0800); - if (!bcm->bad_frames_preempt) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, - bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) - & ~(1 << 11)); - } - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000); - phy_stackrestore(0x04A0); - phy_stackrestore(0x04A1); - phy_stackrestore(0x04A2); - phy_stackrestore(0x04A8); - phy_stackrestore(0x04AB); - phy_stackrestore(0x04A7); - phy_stackrestore(0x04A3); - phy_stackrestore(0x04A9); - phy_stackrestore(0x0493); - phy_stackrestore(0x04AA); - phy_stackrestore(0x04AC); - break; - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - if (!(bcm43xx_phy_read(bcm, 0x0033) & 0x0800)) - break; - - radio->aci_enable = 0; - - phy_stackrestore(BCM43xx_PHY_RADIO_BITFIELD); - phy_stackrestore(BCM43xx_PHY_G_CRS); - phy_stackrestore(0x0033); - phy_stackrestore(0x04A3); - phy_stackrestore(0x04A9); - phy_stackrestore(0x0493); - phy_stackrestore(0x04AA); - phy_stackrestore(0x04AC); - phy_stackrestore(0x04A0); - phy_stackrestore(0x04A7); - if (phy->rev >= 2) { - phy_stackrestore(0x04C0); - phy_stackrestore(0x04C1); - } else - phy_stackrestore(0x0406); - phy_stackrestore(0x04A1); - phy_stackrestore(0x04AB); - phy_stackrestore(0x04A8); - if (phy->rev == 2) { - phy_stackrestore(0x04AD); - phy_stackrestore(0x04AE); - } else if (phy->rev >= 3) { - phy_stackrestore(0x04AD); - phy_stackrestore(0x0415); - phy_stackrestore(0x0416); - phy_stackrestore(0x0417); - ilt_stackrestore(0x1A00 + 0x2); - ilt_stackrestore(0x1A00 + 0x3); - } - phy_stackrestore(0x04A2); - phy_stackrestore(0x04A8); - phy_stackrestore(0x042B); - phy_stackrestore(0x048C); - tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET); - if (tmp32 & 0x800) { - tmp32 &= ~0x800; - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - tmp32); - } - bcm43xx_calc_nrssi_slope(bcm); - break; - default: - assert(0); - } -} - -#undef phy_stacksave -#undef phy_stackrestore -#undef radio_stacksave -#undef radio_stackrestore -#undef ilt_stacksave -#undef ilt_stackrestore - -int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm, - int mode) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - int currentmode; - - if ((phy->type != BCM43xx_PHYTYPE_G) || - (phy->rev == 0) || - (!phy->connected)) - return -ENODEV; - - radio->aci_wlan_automatic = 0; - switch (mode) { - case BCM43xx_RADIO_INTERFMODE_AUTOWLAN: - radio->aci_wlan_automatic = 1; - if (radio->aci_enable) - mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN; - else - mode = BCM43xx_RADIO_INTERFMODE_NONE; - break; - case BCM43xx_RADIO_INTERFMODE_NONE: - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - break; - default: - return -EINVAL; - } - - currentmode = radio->interfmode; - if (currentmode == mode) - return 0; - if (currentmode != BCM43xx_RADIO_INTERFMODE_NONE) - bcm43xx_radio_interference_mitigation_disable(bcm, currentmode); - - if (mode == BCM43xx_RADIO_INTERFMODE_NONE) { - radio->aci_enable = 0; - radio->aci_hw_rssi = 0; - } else - bcm43xx_radio_interference_mitigation_enable(bcm, mode); - radio->interfmode = mode; - - return 0; -} - -u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm) -{ - u16 reg, index, ret; - - reg = bcm43xx_radio_read16(bcm, 0x0060); - index = (reg & 0x001E) >> 1; - ret = rcc_table[index] << 1; - ret |= (reg & 0x0001); - ret |= 0x0020; - - return ret; -} - -u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 backup[19] = { 0 }; - u16 ret; - u16 i, j; - u32 tmp1 = 0, tmp2 = 0; - - backup[0] = bcm43xx_radio_read16(bcm, 0x0043); - backup[14] = bcm43xx_radio_read16(bcm, 0x0051); - backup[15] = bcm43xx_radio_read16(bcm, 0x0052); - backup[1] = bcm43xx_phy_read(bcm, 0x0015); - backup[16] = bcm43xx_phy_read(bcm, 0x005A); - backup[17] = bcm43xx_phy_read(bcm, 0x0059); - backup[18] = bcm43xx_phy_read(bcm, 0x0058); - if (phy->type == BCM43xx_PHYTYPE_B) { - backup[2] = bcm43xx_phy_read(bcm, 0x0030); - backup[3] = bcm43xx_read16(bcm, 0x03EC); - bcm43xx_phy_write(bcm, 0x0030, 0x00FF); - bcm43xx_write16(bcm, 0x03EC, 0x3F3F); - } else { - if (phy->connected) { - backup[4] = bcm43xx_phy_read(bcm, 0x0811); - backup[5] = bcm43xx_phy_read(bcm, 0x0812); - backup[6] = bcm43xx_phy_read(bcm, 0x0814); - backup[7] = bcm43xx_phy_read(bcm, 0x0815); - backup[8] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS); - backup[9] = bcm43xx_phy_read(bcm, 0x0802); - bcm43xx_phy_write(bcm, 0x0814, - (bcm43xx_phy_read(bcm, 0x0814) | 0x0003)); - bcm43xx_phy_write(bcm, 0x0815, - (bcm43xx_phy_read(bcm, 0x0815) & 0xFFFC)); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF)); - bcm43xx_phy_write(bcm, 0x0802, - (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC)); - bcm43xx_phy_write(bcm, 0x0811, 0x01B3); - bcm43xx_phy_write(bcm, 0x0812, 0x0FB2); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO, - (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) | 0x8000)); - } - backup[10] = bcm43xx_phy_read(bcm, 0x0035); - bcm43xx_phy_write(bcm, 0x0035, - (bcm43xx_phy_read(bcm, 0x0035) & 0xFF7F)); - backup[11] = bcm43xx_read16(bcm, 0x03E6); - backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); - - // Initialization - if (phy->version == 0) { - bcm43xx_write16(bcm, 0x03E6, 0x0122); - } else { - if (phy->version >= 2) - bcm43xx_write16(bcm, 0x03E6, 0x0040); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000)); - } - - ret = bcm43xx_radio_calibrationvalue(bcm); - - if (phy->type == BCM43xx_PHYTYPE_B) - bcm43xx_radio_write16(bcm, 0x0078, 0x0003); - - bcm43xx_phy_write(bcm, 0x0015, 0xBFAF); - bcm43xx_phy_write(bcm, 0x002B, 0x1403); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x00B2); - bcm43xx_phy_write(bcm, 0x0015, 0xBFA0); - bcm43xx_radio_write16(bcm, 0x0051, - (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004)); - bcm43xx_radio_write16(bcm, 0x0052, 0x0000); - bcm43xx_radio_write16(bcm, 0x0043, - bcm43xx_radio_read16(bcm, 0x0043) | 0x0009); - bcm43xx_phy_write(bcm, 0x0058, 0x0000); - - for (i = 0; i < 16; i++) { - bcm43xx_phy_write(bcm, 0x005A, 0x0480); - bcm43xx_phy_write(bcm, 0x0059, 0xC810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); - udelay(10); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xEFB0); - udelay(10); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xFFF0); - udelay(10); - tmp1 += bcm43xx_phy_read(bcm, 0x002D); - bcm43xx_phy_write(bcm, 0x0058, 0x0000); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); - } - - tmp1++; - tmp1 >>= 9; - udelay(10); - bcm43xx_phy_write(bcm, 0x0058, 0x0000); - - for (i = 0; i < 16; i++) { - bcm43xx_radio_write16(bcm, 0x0078, (flip_4bit(i) << 1) | 0x0020); - backup[13] = bcm43xx_radio_read16(bcm, 0x0078); - udelay(10); - for (j = 0; j < 16; j++) { - bcm43xx_phy_write(bcm, 0x005A, 0x0D80); - bcm43xx_phy_write(bcm, 0x0059, 0xC810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); - udelay(10); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xEFB0); - udelay(10); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B3); /* 0x30B3 is not a typo */ - bcm43xx_phy_write(bcm, 0x0015, 0xFFF0); - udelay(10); - tmp2 += bcm43xx_phy_read(bcm, 0x002D); - bcm43xx_phy_write(bcm, 0x0058, 0x0000); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); - } - tmp2++; - tmp2 >>= 8; - if (tmp1 < tmp2) - break; - } - - /* Restore the registers */ - bcm43xx_phy_write(bcm, 0x0015, backup[1]); - bcm43xx_radio_write16(bcm, 0x0051, backup[14]); - bcm43xx_radio_write16(bcm, 0x0052, backup[15]); - bcm43xx_radio_write16(bcm, 0x0043, backup[0]); - bcm43xx_phy_write(bcm, 0x005A, backup[16]); - bcm43xx_phy_write(bcm, 0x0059, backup[17]); - bcm43xx_phy_write(bcm, 0x0058, backup[18]); - bcm43xx_write16(bcm, 0x03E6, backup[11]); - if (phy->version != 0) - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]); - bcm43xx_phy_write(bcm, 0x0035, backup[10]); - bcm43xx_radio_selectchannel(bcm, radio->channel, 1); - if (phy->type == BCM43xx_PHYTYPE_B) { - bcm43xx_phy_write(bcm, 0x0030, backup[2]); - bcm43xx_write16(bcm, 0x03EC, backup[3]); - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO, - (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) & 0x7FFF)); - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x0811, backup[4]); - bcm43xx_phy_write(bcm, 0x0812, backup[5]); - bcm43xx_phy_write(bcm, 0x0814, backup[6]); - bcm43xx_phy_write(bcm, 0x0815, backup[7]); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, backup[8]); - bcm43xx_phy_write(bcm, 0x0802, backup[9]); - } - } - if (i >= 15) - ret = backup[13]; - - return ret; -} - -void bcm43xx_radio_init2060(struct bcm43xx_private *bcm) -{ - int err; - - bcm43xx_radio_write16(bcm, 0x0004, 0x00C0); - bcm43xx_radio_write16(bcm, 0x0005, 0x0008); - bcm43xx_radio_write16(bcm, 0x0009, 0x0040); - bcm43xx_radio_write16(bcm, 0x0005, 0x00AA); - bcm43xx_radio_write16(bcm, 0x0032, 0x008F); - bcm43xx_radio_write16(bcm, 0x0006, 0x008F); - bcm43xx_radio_write16(bcm, 0x0034, 0x008F); - bcm43xx_radio_write16(bcm, 0x002C, 0x0007); - bcm43xx_radio_write16(bcm, 0x0082, 0x0080); - bcm43xx_radio_write16(bcm, 0x0080, 0x0000); - bcm43xx_radio_write16(bcm, 0x003F, 0x00DA); - bcm43xx_radio_write16(bcm, 0x0005, bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008); - bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0010); - bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020); - bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020); - udelay(400); - - bcm43xx_radio_write16(bcm, 0x0081, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020) | 0x0010); - udelay(400); - - bcm43xx_radio_write16(bcm, 0x0005, (bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008) | 0x0008); - bcm43xx_radio_write16(bcm, 0x0085, bcm43xx_radio_read16(bcm, 0x0085) & ~0x0010); - bcm43xx_radio_write16(bcm, 0x0005, bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008); - bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0040); - bcm43xx_radio_write16(bcm, 0x0081, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0040) | 0x0040); - bcm43xx_radio_write16(bcm, 0x0005, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0008) | 0x0008); - bcm43xx_phy_write(bcm, 0x0063, 0xDDC6); - bcm43xx_phy_write(bcm, 0x0069, 0x07BE); - bcm43xx_phy_write(bcm, 0x006A, 0x0000); - - err = bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_A, 0); - assert(err == 0); - udelay(1000); -} - -static inline -u16 freq_r3A_value(u16 frequency) -{ - u16 value; - - if (frequency < 5091) - value = 0x0040; - else if (frequency < 5321) - value = 0x0000; - else if (frequency < 5806) - value = 0x0080; - else - value = 0x0040; - - return value; -} - -void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm) -{ - static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 }; - static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A }; - u16 tmp = bcm43xx_radio_read16(bcm, 0x001E); - int i, j; - - for (i = 0; i < 5; i++) { - for (j = 0; j < 5; j++) { - if (tmp == (data_high[i] << 4 | data_low[j])) { - bcm43xx_phy_write(bcm, 0x0069, (i - j) << 8 | 0x00C0); - return; - } - } - } -} - -int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, - u8 channel, - int synthetic_pu_workaround) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 r8, tmp; - u16 freq; - - if ((radio->manufact == 0x17F) && - (radio->version == 0x2060) && - (radio->revision == 1)) { - if (channel > 200) - return -EINVAL; - freq = channel2freq_a(channel); - - r8 = bcm43xx_radio_read16(bcm, 0x0008); - bcm43xx_write16(bcm, 0x03F0, freq); - bcm43xx_radio_write16(bcm, 0x0008, r8); - - TODO();//TODO: write max channel TX power? to Radio 0x2D - tmp = bcm43xx_radio_read16(bcm, 0x002E); - tmp &= 0x0080; - TODO();//TODO: OR tmp with the Power out estimation for this channel? - bcm43xx_radio_write16(bcm, 0x002E, tmp); - - if (freq >= 4920 && freq <= 5500) { - /* - * r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F; - * = (freq * 0.025862069 - */ - r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */ - } - bcm43xx_radio_write16(bcm, 0x0007, (r8 << 4) | r8); - bcm43xx_radio_write16(bcm, 0x0020, (r8 << 4) | r8); - bcm43xx_radio_write16(bcm, 0x0021, (r8 << 4) | r8); - bcm43xx_radio_write16(bcm, 0x0022, - (bcm43xx_radio_read16(bcm, 0x0022) - & 0x000F) | (r8 << 4)); - bcm43xx_radio_write16(bcm, 0x002A, (r8 << 4)); - bcm43xx_radio_write16(bcm, 0x002B, (r8 << 4)); - bcm43xx_radio_write16(bcm, 0x0008, - (bcm43xx_radio_read16(bcm, 0x0008) - & 0x00F0) | (r8 << 4)); - bcm43xx_radio_write16(bcm, 0x0029, - (bcm43xx_radio_read16(bcm, 0x0029) - & 0xFF0F) | 0x00B0); - bcm43xx_radio_write16(bcm, 0x0035, 0x00AA); - bcm43xx_radio_write16(bcm, 0x0036, 0x0085); - bcm43xx_radio_write16(bcm, 0x003A, - (bcm43xx_radio_read16(bcm, 0x003A) - & 0xFF20) | freq_r3A_value(freq)); - bcm43xx_radio_write16(bcm, 0x003D, - bcm43xx_radio_read16(bcm, 0x003D) & 0x00FF); - bcm43xx_radio_write16(bcm, 0x0081, - (bcm43xx_radio_read16(bcm, 0x0081) - & 0xFF7F) | 0x0080); - bcm43xx_radio_write16(bcm, 0x0035, - bcm43xx_radio_read16(bcm, 0x0035) & 0xFFEF); - bcm43xx_radio_write16(bcm, 0x0035, - (bcm43xx_radio_read16(bcm, 0x0035) - & 0xFFEF) | 0x0010); - bcm43xx_radio_set_tx_iq(bcm); - TODO(); //TODO: TSSI2dbm workaround - bcm43xx_phy_xmitpower(bcm);//FIXME correct? - } else { - if ((channel < 1) || (channel > 14)) - return -EINVAL; - - if (synthetic_pu_workaround) - bcm43xx_synth_pu_workaround(bcm, channel); - - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL, - channel2freq_bg(channel)); - - if (channel == 14) { - if (bcm->sprom.locale == BCM43xx_LOCALE_JAPAN) { - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET) - & ~(1 << 7)); - } else { - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET) - | (1 << 7)); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) - | (1 << 11)); - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) - & 0xF7BF); - } - } - - radio->channel = channel; - //XXX: Using the longer of 2 timeouts (8000 vs 2000 usecs). Specs states - // that 2000 usecs might suffice. - udelay(8000); - - return 0; -} - -void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val) -{ - u16 tmp; - - val <<= 8; - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0022) & 0xFCFF; - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0022, tmp | val); - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x03A8) & 0xFCFF; - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x03A8, tmp | val); - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0054) & 0xFCFF; - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0054, tmp | val); -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */ -static u16 bcm43xx_get_txgain_base_band(u16 txpower) -{ - u16 ret; - - assert(txpower <= 63); - - if (txpower >= 54) - ret = 2; - else if (txpower >= 49) - ret = 4; - else if (txpower >= 44) - ret = 5; - else - ret = 6; - - return ret; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */ -static u16 bcm43xx_get_txgain_freq_power_amp(u16 txpower) -{ - u16 ret; - - assert(txpower <= 63); - - if (txpower >= 32) - ret = 0; - else if (txpower >= 25) - ret = 1; - else if (txpower >= 20) - ret = 2; - else if (txpower >= 12) - ret = 3; - else - ret = 4; - - return ret; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */ -static u16 bcm43xx_get_txgain_dac(u16 txpower) -{ - u16 ret; - - assert(txpower <= 63); - - if (txpower >= 54) - ret = txpower - 53; - else if (txpower >= 49) - ret = txpower - 42; - else if (txpower >= 44) - ret = txpower - 37; - else if (txpower >= 32) - ret = txpower - 32; - else if (txpower >= 25) - ret = txpower - 20; - else if (txpower >= 20) - ret = txpower - 13; - else if (txpower >= 12) - ret = txpower - 8; - else - ret = txpower; - - return ret; -} - -void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 pamp, base, dac, ilt; - - txpower = limit_value(txpower, 0, 63); - - pamp = bcm43xx_get_txgain_freq_power_amp(txpower); - pamp <<= 5; - pamp &= 0x00E0; - bcm43xx_phy_write(bcm, 0x0019, pamp); - - base = bcm43xx_get_txgain_base_band(txpower); - base &= 0x000F; - bcm43xx_phy_write(bcm, 0x0017, base | 0x0020); - - ilt = bcm43xx_ilt_read(bcm, 0x3001); - ilt &= 0x0007; - - dac = bcm43xx_get_txgain_dac(txpower); - dac <<= 3; - dac |= ilt; - - bcm43xx_ilt_write(bcm, 0x3001, dac); - - radio->txpwr_offset = txpower; - - TODO(); - //TODO: FuncPlaceholder (Adjust BB loft cancel) -} - -void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm, - u16 baseband_attenuation, u16 radio_attenuation, - u16 txpower) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (baseband_attenuation == 0xFFFF) - baseband_attenuation = radio->baseband_atten; - if (radio_attenuation == 0xFFFF) - radio_attenuation = radio->radio_atten; - if (txpower == 0xFFFF) - txpower = radio->txctl1; - radio->baseband_atten = baseband_attenuation; - radio->radio_atten = radio_attenuation; - radio->txctl1 = txpower; - - assert(/*baseband_attenuation >= 0 &&*/ baseband_attenuation <= 11); - if (radio->revision < 6) - assert(/*radio_attenuation >= 0 &&*/ radio_attenuation <= 9); - else - assert(/* radio_attenuation >= 0 &&*/ radio_attenuation <= 31); - assert(/*txpower >= 0 &&*/ txpower <= 7); - - bcm43xx_phy_set_baseband_attenuation(bcm, baseband_attenuation); - bcm43xx_radio_write16(bcm, 0x0043, radio_attenuation); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0064, radio_attenuation); - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0052, - (bcm43xx_radio_read16(bcm, 0x0052) & ~0x0070) - | ((txpower << 4) & 0x0070)); - } - //FIXME: The spec is very weird and unclear here. - if (phy->type == BCM43xx_PHYTYPE_G) - bcm43xx_phy_lo_adjust(bcm, 0); -} - -u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (radio->version == 0x2050 && radio->revision < 6) - return 0; - return 2; -} - -u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 att = 0xFFFF; - - if (phy->type == BCM43xx_PHYTYPE_A) - return 0x60; - - switch (radio->version) { - case 0x2053: - switch (radio->revision) { - case 1: - att = 6; - break; - } - break; - case 0x2050: - switch (radio->revision) { - case 0: - att = 5; - break; - case 1: - if (phy->type == BCM43xx_PHYTYPE_G) { - if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x421 && - bcm->board_revision >= 30) - att = 3; - else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x416) - att = 3; - else - att = 1; - } else { - if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x421 && - bcm->board_revision >= 30) - att = 7; - else - att = 6; - } - break; - case 2: - if (phy->type == BCM43xx_PHYTYPE_G) { - if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x421 && - bcm->board_revision >= 30) - att = 3; - else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x416) - att = 5; - else if (bcm->chip_id == 0x4320) - att = 4; - else - att = 3; - } else - att = 6; - break; - case 3: - att = 5; - break; - case 4: - case 5: - att = 1; - break; - case 6: - case 7: - att = 5; - break; - case 8: - att = 0x1A; - break; - case 9: - default: - att = 5; - } - } - if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x421) { - if (bcm->board_revision < 0x43) - att = 2; - else if (bcm->board_revision < 0x51) - att = 3; - } - if (att == 0xFFFF) - att = 5; - - return att; -} - -u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (radio->version != 0x2050) - return 0; - if (radio->revision == 1) - return 3; - if (radio->revision < 6) - return 2; - if (radio->revision == 8) - return 1; - return 0; -} - -void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - int err; - - if (radio->enabled) - return; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - bcm43xx_radio_write16(bcm, 0x0004, 0x00C0); - bcm43xx_radio_write16(bcm, 0x0005, 0x0008); - bcm43xx_phy_write(bcm, 0x0010, bcm43xx_phy_read(bcm, 0x0010) & 0xFFF7); - bcm43xx_phy_write(bcm, 0x0011, bcm43xx_phy_read(bcm, 0x0011) & 0xFFF7); - bcm43xx_radio_init2060(bcm); - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - bcm43xx_phy_write(bcm, 0x0015, 0x8000); - bcm43xx_phy_write(bcm, 0x0015, 0xCC00); - bcm43xx_phy_write(bcm, 0x0015, (phy->connected ? 0x00C0 : 0x0000)); - err = bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 1); - assert(err == 0); - break; - default: - assert(0); - } - radio->enabled = 1; - dprintk(KERN_INFO PFX "Radio turned on\n"); -} - -void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (phy->type == BCM43xx_PHYTYPE_A) { - bcm43xx_radio_write16(bcm, 0x0004, 0x00FF); - bcm43xx_radio_write16(bcm, 0x0005, 0x00FB); - bcm43xx_phy_write(bcm, 0x0010, bcm43xx_phy_read(bcm, 0x0010) | 0x0008); - bcm43xx_phy_write(bcm, 0x0011, bcm43xx_phy_read(bcm, 0x0011) | 0x0008); - } - if (phy->type == BCM43xx_PHYTYPE_G && bcm->current_core->rev >= 5) { - bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x008C); - bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) & 0xFF73); - } else - bcm43xx_phy_write(bcm, 0x0015, 0xAA00); - radio->enabled = 0; - dprintk(KERN_INFO PFX "Radio turned off\n"); -} - -void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0068, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x006a, 0x7F7F); - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0058, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x005a, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0070, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0072, 0x7F7F); - break; - } -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.h b/drivers/net/wireless/bcm43xx/bcm43xx_radio.h deleted file mode 100644 index 9ed18039f..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_RADIO_H_ -#define BCM43xx_RADIO_H_ - -#include "bcm43xx.h" - - -#define BCM43xx_RADIO_DEFAULT_CHANNEL_A 36 -#define BCM43xx_RADIO_DEFAULT_CHANNEL_BG 6 - -/* Force antenna 0. */ -#define BCM43xx_RADIO_TXANTENNA_0 0 -/* Force antenna 1. */ -#define BCM43xx_RADIO_TXANTENNA_1 1 -/* Use the RX antenna, that was selected for the most recently - * received good PLCP header. - */ -#define BCM43xx_RADIO_TXANTENNA_LASTPLCP 3 -#define BCM43xx_RADIO_TXANTENNA_DEFAULT BCM43xx_RADIO_TXANTENNA_LASTPLCP - -#define BCM43xx_RADIO_INTERFMODE_NONE 0 -#define BCM43xx_RADIO_INTERFMODE_NONWLAN 1 -#define BCM43xx_RADIO_INTERFMODE_MANUALWLAN 2 -#define BCM43xx_RADIO_INTERFMODE_AUTOWLAN 3 - - -void bcm43xx_radio_lock(struct bcm43xx_private *bcm); -void bcm43xx_radio_unlock(struct bcm43xx_private *bcm); - -u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset); -void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val); - -u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm); -void bcm43xx_radio_init2060(struct bcm43xx_private *bcm); - -void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm); -void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm); - -int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, u8 channel, - int synthetic_pu_workaround); - -void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower); -void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm, - u16 baseband_attenuation, u16 attenuation, - u16 txpower); - -u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm); -u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm); -u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm); - -void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val); - -void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm); - -u8 bcm43xx_radio_aci_detect(struct bcm43xx_private *bcm, u8 channel); -u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm); - -int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm, int mode); - -void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm); -void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm); -s16 bcm43xx_nrssi_hw_read(struct bcm43xx_private *bcm, u16 offset); -void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val); -void bcm43xx_nrssi_hw_update(struct bcm43xx_private *bcm, u16 val); -void bcm43xx_nrssi_mem_update(struct bcm43xx_private *bcm); - -void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm); -u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm); - -#endif /* BCM43xx_RADIO_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c deleted file mode 100644 index b438f48e8..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - SYSFS support routines - - Copyright (c) 2006 Michael Buesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx_sysfs.h" -#include "bcm43xx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_radio.h" - -#include - - -#define GENERIC_FILESIZE 64 - - -static int get_integer(const char *buf, size_t count) -{ - char tmp[10 + 1] = { 0 }; - int ret = -EINVAL; - - if (count == 0) - goto out; - count = min(count, (size_t)10); - memcpy(tmp, buf, count); - ret = simple_strtol(tmp, NULL, 10); -out: - return ret; -} - -static int get_boolean(const char *buf, size_t count) -{ - if (count != 0) { - if (buf[0] == '1') - return 1; - if (buf[0] == '0') - return 0; - if (count >= 4 && memcmp(buf, "true", 4) == 0) - return 1; - if (count >= 5 && memcmp(buf, "false", 5) == 0) - return 0; - if (count >= 3 && memcmp(buf, "yes", 3) == 0) - return 1; - if (count >= 2 && memcmp(buf, "no", 2) == 0) - return 0; - if (count >= 2 && memcmp(buf, "on", 2) == 0) - return 1; - if (count >= 3 && memcmp(buf, "off", 3) == 0) - return 0; - } - return -EINVAL; -} - -static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len) -{ - int i, pos = 0; - - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - pos += snprintf(buf + pos, buf_len - pos - 1, - "%04X", swab16(sprom[i]) & 0xFFFF); - } - pos += snprintf(buf + pos, buf_len - pos - 1, "\n"); - - return pos + 1; -} - -static int hex2sprom(u16 *sprom, const char *dump, size_t len) -{ - char tmp[5] = { 0 }; - int cnt = 0; - unsigned long parsed; - - if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) - return -EINVAL; - - while (cnt < BCM43xx_SPROM_SIZE) { - memcpy(tmp, dump, 4); - dump += 4; - parsed = simple_strtoul(tmp, NULL, 16); - sprom[cnt++] = swab16((u16)parsed); - } - - return 0; -} - -static ssize_t bcm43xx_attr_sprom_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct bcm43xx_private *bcm = dev_to_bcm(dev); - u16 *sprom; - unsigned long flags; - int err; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - assert(BCM43xx_SPROM_SIZE * sizeof(u16) <= PAGE_SIZE); - sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), - GFP_KERNEL); - if (!sprom) - return -ENOMEM; - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); - err = bcm43xx_sprom_read(bcm, sprom); - if (!err) - err = sprom2hex(sprom, buf, PAGE_SIZE); - bcm43xx_unlock_mmio(bcm, flags); - kfree(sprom); - - return err; -} - -static ssize_t bcm43xx_attr_sprom_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct bcm43xx_private *bcm = dev_to_bcm(dev); - u16 *sprom; - unsigned long flags; - int err; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), - GFP_KERNEL); - if (!sprom) - return -ENOMEM; - err = hex2sprom(sprom, buf, count); - if (err) - goto out_kfree; - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); - err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); -out_kfree: - kfree(sprom); - - return err ? err : count; - -} - -static DEVICE_ATTR(sprom, 0600, - bcm43xx_attr_sprom_show, - bcm43xx_attr_sprom_store); - -static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct bcm43xx_private *bcm = dev_to_bcm(dev); - unsigned long flags; - int err; - ssize_t count = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); - - switch (bcm43xx_current_radio(bcm)->interfmode) { - case BCM43xx_RADIO_INTERFMODE_NONE: - count = snprintf(buf, PAGE_SIZE, "0 (No Interference Mitigation)\n"); - break; - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - count = snprintf(buf, PAGE_SIZE, "1 (Non-WLAN Interference Mitigation)\n"); - break; - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - count = snprintf(buf, PAGE_SIZE, "2 (WLAN Interference Mitigation)\n"); - break; - default: - assert(0); - } - err = 0; - - bcm43xx_unlock(bcm, flags); - - return err ? err : count; - -} - -static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct bcm43xx_private *bcm = dev_to_bcm(dev); - unsigned long flags; - int err; - int mode; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - mode = get_integer(buf, count); - switch (mode) { - case 0: - mode = BCM43xx_RADIO_INTERFMODE_NONE; - break; - case 1: - mode = BCM43xx_RADIO_INTERFMODE_NONWLAN; - break; - case 2: - mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN; - break; - case 3: - mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN; - break; - default: - return -EINVAL; - } - - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); - - err = bcm43xx_radio_set_interference_mitigation(bcm, mode); - if (err) { - printk(KERN_ERR PFX "Interference Mitigation not " - "supported by device\n"); - } - - bcm43xx_unlock_mmio(bcm, flags); - - return err ? err : count; -} - -static DEVICE_ATTR(interference, 0644, - bcm43xx_attr_interfmode_show, - bcm43xx_attr_interfmode_store); - -static ssize_t bcm43xx_attr_preamble_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct bcm43xx_private *bcm = dev_to_bcm(dev); - unsigned long flags; - int err; - ssize_t count; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); - - if (bcm->short_preamble) - count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); - else - count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); - - err = 0; - bcm43xx_unlock(bcm, flags); - - return err ? err : count; -} - -static ssize_t bcm43xx_attr_preamble_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct bcm43xx_private *bcm = dev_to_bcm(dev); - unsigned long flags; - int err; - int value; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - value = get_boolean(buf, count); - if (value < 0) - return value; - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); - - bcm->short_preamble = !!value; - - err = 0; - bcm43xx_unlock(bcm, flags); - - return err ? err : count; -} - -static DEVICE_ATTR(shortpreamble, 0644, - bcm43xx_attr_preamble_show, - bcm43xx_attr_preamble_store); - -int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) -{ - struct device *dev = &bcm->pci_dev->dev; - int err; - - assert(bcm->initialized); - - err = device_create_file(dev, &dev_attr_sprom); - if (err) - goto out; - err = device_create_file(dev, &dev_attr_interference); - if (err) - goto err_remove_sprom; - err = device_create_file(dev, &dev_attr_shortpreamble); - if (err) - goto err_remove_interfmode; - -out: - return err; -err_remove_interfmode: - device_remove_file(dev, &dev_attr_interference); -err_remove_sprom: - device_remove_file(dev, &dev_attr_sprom); - goto out; -} - -void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm) -{ - struct device *dev = &bcm->pci_dev->dev; - - device_remove_file(dev, &dev_attr_shortpreamble); - device_remove_file(dev, &dev_attr_interference); - device_remove_file(dev, &dev_attr_sprom); -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h deleted file mode 100644 index cc701df71..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef BCM43xx_SYSFS_H_ -#define BCM43xx_SYSFS_H_ - -struct bcm43xx_private; - -int bcm43xx_sysfs_register(struct bcm43xx_private *bcm); -void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm); - -#endif /* BCM43xx_SYSFS_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c deleted file mode 100644 index b45063974..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ /dev/null @@ -1,1005 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include -#include -#include -#include -#include -#include /* for capable() */ -#include - -#include "bcm43xx.h" -#include "bcm43xx_wx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_radio.h" -#include "bcm43xx_phy.h" - - -/* The WIRELESS_EXT version, which is implemented by this driver. */ -#define BCM43xx_WX_VERSION 18 - -#define MAX_WX_STRING 80 - - -static int bcm43xx_wx_get_name(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int i; - struct bcm43xx_phyinfo *phy; - char suffix[7] = { 0 }; - int have_a = 0, have_b = 0, have_g = 0; - - bcm43xx_lock(bcm, flags); - for (i = 0; i < bcm->nr_80211_available; i++) { - phy = &(bcm->core_80211_ext[i].phy); - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - have_a = 1; - break; - case BCM43xx_PHYTYPE_G: - have_g = 1; - case BCM43xx_PHYTYPE_B: - have_b = 1; - break; - default: - assert(0); - } - } - bcm43xx_unlock(bcm, flags); - - i = 0; - if (have_a) { - suffix[i++] = 'a'; - suffix[i++] = '/'; - } - if (have_b) { - suffix[i++] = 'b'; - suffix[i++] = '/'; - } - if (have_g) { - suffix[i++] = 'g'; - suffix[i++] = '/'; - } - if (i != 0) - suffix[i - 1] = '\0'; - - snprintf(data->name, IFNAMSIZ, "IEEE 802.11%s", suffix); - - return 0; -} - -static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - u8 channel; - int freq; - int err = -EINVAL; - - bcm43xx_lock_mmio(bcm, flags); - if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { - channel = data->freq.m; - freq = bcm43xx_channel_to_freq(bcm, channel); - } else { - channel = bcm43xx_freq_to_channel(bcm, data->freq.m); - freq = data->freq.m; - } - if (!bcm43xx_is_valid_channel(bcm, channel)) - goto out_unlock; - if (bcm->initialized) { - //ieee80211softmac_disassoc(softmac, $REASON); - bcm43xx_mac_suspend(bcm); - err = bcm43xx_radio_selectchannel(bcm, channel, 0); - bcm43xx_mac_enable(bcm); - } else { - bcm43xx_current_radio(bcm)->initial_channel = channel; - err = 0; - } -out_unlock: - bcm43xx_unlock_mmio(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct bcm43xx_radioinfo *radio; - unsigned long flags; - int err = -ENODEV; - u16 channel; - - bcm43xx_lock(bcm, flags); - radio = bcm43xx_current_radio(bcm); - channel = radio->channel; - if (channel == 0xFF) { - assert(!bcm->initialized); - channel = radio->initial_channel; - if (channel == 0xFF) - goto out_unlock; - } - assert(channel > 0 && channel <= 1000); - data->freq.e = 1; - data->freq.m = bcm43xx_channel_to_freq(bcm, channel) * 100000; - data->freq.flags = 1; - - err = 0; -out_unlock: - bcm43xx_unlock(bcm, flags); - - return err; -} - -static int bcm43xx_wx_set_mode(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int mode; - - mode = data->mode; - if (mode == IW_MODE_AUTO) - mode = BCM43xx_INITIAL_IWMODE; - - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { - if (bcm->ieee->iw_mode != mode) - bcm43xx_set_iwmode(bcm, mode); - } else - bcm->ieee->iw_mode = mode; - bcm43xx_unlock_mmio(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_mode(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - bcm43xx_lock(bcm, flags); - data->mode = bcm->ieee->iw_mode; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct iw_range *range = (struct iw_range *)extra; - const struct ieee80211_geo *geo; - unsigned long flags; - int i, j; - struct bcm43xx_phyinfo *phy; - - data->data.length = sizeof(*range); - memset(range, 0, sizeof(*range)); - - //TODO: What about 802.11b? - /* 54Mb/s == ~27Mb/s payload throughput (802.11g) */ - range->throughput = 27 * 1000 * 1000; - - range->max_qual.qual = 100; - /* TODO: Real max RSSI */ - range->max_qual.level = 3; - range->max_qual.noise = 100; - range->max_qual.updated = 7; - - range->avg_qual.qual = 70; - range->avg_qual.level = 2; - range->avg_qual.noise = 40; - range->avg_qual.updated = 7; - - range->min_rts = BCM43xx_MIN_RTS_THRESHOLD; - range->max_rts = BCM43xx_MAX_RTS_THRESHOLD; - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->encoding_size[0] = 5; - range->encoding_size[1] = 13; - range->num_encoding_sizes = 2; - range->max_encoding_tokens = WEP_KEYS; - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = BCM43xx_WX_VERSION; - - range->enc_capa = IW_ENC_CAPA_WPA | - IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | - IW_ENC_CAPA_CIPHER_CCMP; - - bcm43xx_lock(bcm, flags); - phy = bcm43xx_current_phy(bcm); - - range->num_bitrates = 0; - i = 0; - if (phy->type == BCM43xx_PHYTYPE_A || - phy->type == BCM43xx_PHYTYPE_G) { - range->num_bitrates = 8; - range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_12MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_18MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_24MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_36MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB; - } - if (phy->type == BCM43xx_PHYTYPE_B || - phy->type == BCM43xx_PHYTYPE_G) { - range->num_bitrates += 4; - range->bitrate[i++] = IEEE80211_CCK_RATE_1MB; - range->bitrate[i++] = IEEE80211_CCK_RATE_2MB; - range->bitrate[i++] = IEEE80211_CCK_RATE_5MB; - range->bitrate[i++] = IEEE80211_CCK_RATE_11MB; - } - - geo = ieee80211_get_geo(bcm->ieee); - range->num_channels = geo->a_channels + geo->bg_channels; - j = 0; - for (i = 0; i < geo->a_channels; i++) { - if (j == IW_MAX_FREQUENCIES) - break; - range->freq[j].i = j + 1; - range->freq[j].m = geo->a[i].freq;//FIXME? - range->freq[j].e = 1; - j++; - } - for (i = 0; i < geo->bg_channels; i++) { - if (j == IW_MAX_FREQUENCIES) - break; - range->freq[j].i = j + 1; - range->freq[j].m = geo->bg[i].freq;//FIXME? - range->freq[j].e = 1; - j++; - } - range->num_frequency = j; - - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_set_nick(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - size_t len; - - bcm43xx_lock(bcm, flags); - len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); - memcpy(bcm->nick, extra, len); - bcm->nick[len] = '\0'; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_nick(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - size_t len; - - bcm43xx_lock(bcm, flags); - len = strlen(bcm->nick) + 1; - memcpy(extra, bcm->nick, len); - data->data.length = (__u16)len; - data->data.flags = 1; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_set_rts(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int err = -EINVAL; - - bcm43xx_lock(bcm, flags); - if (data->rts.disabled) { - bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; - err = 0; - } else { - if (data->rts.value >= BCM43xx_MIN_RTS_THRESHOLD && - data->rts.value <= BCM43xx_MAX_RTS_THRESHOLD) { - bcm->rts_threshold = data->rts.value; - err = 0; - } - } - bcm43xx_unlock(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_rts(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - bcm43xx_lock(bcm, flags); - data->rts.value = bcm->rts_threshold; - data->rts.fixed = 0; - data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_set_frag(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int err = -EINVAL; - - bcm43xx_lock(bcm, flags); - if (data->frag.disabled) { - bcm->ieee->fts = MAX_FRAG_THRESHOLD; - err = 0; - } else { - if (data->frag.value >= MIN_FRAG_THRESHOLD && - data->frag.value <= MAX_FRAG_THRESHOLD) { - bcm->ieee->fts = data->frag.value & ~0x1; - err = 0; - } - } - bcm43xx_unlock(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_frag(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - bcm43xx_lock(bcm, flags); - data->frag.value = bcm->ieee->fts; - data->frag.fixed = 0; - data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct bcm43xx_radioinfo *radio; - struct bcm43xx_phyinfo *phy; - unsigned long flags; - int err = -ENODEV; - u16 maxpower; - - if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) { - printk(PFX KERN_ERR "TX power not in dBm.\n"); - return -EOPNOTSUPP; - } - - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) - goto out_unlock; - radio = bcm43xx_current_radio(bcm); - phy = bcm43xx_current_phy(bcm); - if (data->txpower.disabled != (!(radio->enabled))) { - if (data->txpower.disabled) - bcm43xx_radio_turn_off(bcm); - else - bcm43xx_radio_turn_on(bcm); - } - if (data->txpower.value > 0) { - /* desired and maxpower dBm values are in Q5.2 */ - if (phy->type == BCM43xx_PHYTYPE_A) - maxpower = bcm->sprom.maxpower_aphy; - else - maxpower = bcm->sprom.maxpower_bgphy; - radio->txpower_desired = limit_value(data->txpower.value << 2, - 0, maxpower); - bcm43xx_phy_xmitpower(bcm); - } - err = 0; - -out_unlock: - bcm43xx_unlock_mmio(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct bcm43xx_radioinfo *radio; - unsigned long flags; - int err = -ENODEV; - - bcm43xx_lock(bcm, flags); - if (!bcm->initialized) - goto out_unlock; - radio = bcm43xx_current_radio(bcm); - /* desired dBm value is in Q5.2 */ - data->txpower.value = radio->txpower_desired >> 2; - data->txpower.fixed = 1; - data->txpower.flags = IW_TXPOW_DBM; - data->txpower.disabled = !(radio->enabled); - - err = 0; -out_unlock: - bcm43xx_unlock(bcm, flags); - - return err; -} - -static int bcm43xx_wx_set_encoding(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; - - err = ieee80211_wx_set_encode(bcm->ieee, info, data, extra); - - return err; -} - -static int bcm43xx_wx_set_encodingext(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; - - err = ieee80211_wx_set_encodeext(bcm->ieee, info, data, extra); - - return err; -} - -static int bcm43xx_wx_get_encoding(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; - - err = ieee80211_wx_get_encode(bcm->ieee, info, data, extra); - - return err; -} - -static int bcm43xx_wx_get_encodingext(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; - - err = ieee80211_wx_get_encodeext(bcm->ieee, info, data, extra); - - return err; -} - -static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int mode, err = 0; - - mode = *((int *)extra); - switch (mode) { - case 0: - mode = BCM43xx_RADIO_INTERFMODE_NONE; - break; - case 1: - mode = BCM43xx_RADIO_INTERFMODE_NONWLAN; - break; - case 2: - mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN; - break; - case 3: - mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN; - break; - default: - printk(KERN_ERR PFX "set_interfmode allowed parameters are: " - "0 => None, 1 => Non-WLAN, 2 => WLAN, " - "3 => Auto-WLAN\n"); - return -EINVAL; - } - - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { - err = bcm43xx_radio_set_interference_mitigation(bcm, mode); - if (err) { - printk(KERN_ERR PFX "Interference Mitigation not " - "supported by device\n"); - } - } else { - if (mode == BCM43xx_RADIO_INTERFMODE_AUTOWLAN) { - printk(KERN_ERR PFX "Interference Mitigation mode Auto-WLAN " - "not supported while the interface is down.\n"); - err = -ENODEV; - } else - bcm43xx_current_radio(bcm)->interfmode = mode; - } - bcm43xx_unlock_mmio(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_interfmode(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int mode; - - bcm43xx_lock(bcm, flags); - mode = bcm43xx_current_radio(bcm)->interfmode; - bcm43xx_unlock(bcm, flags); - - switch (mode) { - case BCM43xx_RADIO_INTERFMODE_NONE: - strncpy(extra, "0 (No Interference Mitigation)", MAX_WX_STRING); - break; - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - strncpy(extra, "1 (Non-WLAN Interference Mitigation)", MAX_WX_STRING); - break; - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - strncpy(extra, "2 (WLAN Interference Mitigation)", MAX_WX_STRING); - break; - default: - assert(0); - } - data->data.length = strlen(extra) + 1; - - return 0; -} - -static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int on; - - on = *((int *)extra); - bcm43xx_lock(bcm, flags); - bcm->short_preamble = !!on; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int on; - - bcm43xx_lock(bcm, flags); - on = bcm->short_preamble; - bcm43xx_unlock(bcm, flags); - - if (on) - strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); - else - strncpy(extra, "0 (Short Preamble disabled)", MAX_WX_STRING); - data->data.length = strlen(extra) + 1; - - return 0; -} - -static int bcm43xx_wx_set_swencryption(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int on; - - on = *((int *)extra); - - bcm43xx_lock(bcm, flags); - bcm->ieee->host_encrypt = !!on; - bcm->ieee->host_decrypt = !!on; - bcm->ieee->host_build_iv = !on; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_swencryption(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int on; - - bcm43xx_lock(bcm, flags); - on = bcm->ieee->host_encrypt; - bcm43xx_unlock(bcm, flags); - - if (on) - strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); - else - strncpy(extra, "0 (SW encryption disabled) ", MAX_WX_STRING); - data->data.length = strlen(extra + 1); - - return 0; -} - -/* Enough buffer to hold a hexdump of the sprom data. */ -#define SPROM_BUFFERSIZE 512 - -static int sprom2hex(const u16 *sprom, char *dump) -{ - int i, pos = 0; - - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - pos += snprintf(dump + pos, SPROM_BUFFERSIZE - pos - 1, - "%04X", swab16(sprom[i]) & 0xFFFF); - } - - return pos + 1; -} - -static int hex2sprom(u16 *sprom, const char *dump, unsigned int len) -{ - char tmp[5] = { 0 }; - int cnt = 0; - unsigned long parsed; - - if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) - return -EINVAL; - while (cnt < BCM43xx_SPROM_SIZE) { - memcpy(tmp, dump, 4); - dump += 4; - parsed = simple_strtoul(tmp, NULL, 16); - sprom[cnt++] = swab16((u16)parsed); - } - - return 0; -} - -static int bcm43xx_wx_sprom_read(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = -EPERM; - u16 *sprom; - unsigned long flags; - - if (!capable(CAP_SYS_RAWIO)) - goto out; - - err = -ENOMEM; - sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), - GFP_KERNEL); - if (!sprom) - goto out; - - bcm43xx_lock_mmio(bcm, flags); - err = -ENODEV; - if (bcm->initialized) - err = bcm43xx_sprom_read(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); - if (!err) - data->data.length = sprom2hex(sprom, extra); - kfree(sprom); -out: - return err; -} - -static int bcm43xx_wx_sprom_write(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = -EPERM; - u16 *sprom; - unsigned long flags; - char *input; - unsigned int len; - - if (!capable(CAP_SYS_RAWIO)) - goto out; - - err = -ENOMEM; - sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), - GFP_KERNEL); - if (!sprom) - goto out; - - len = data->data.length; - extra[len - 1] = '\0'; - input = strchr(extra, ':'); - if (input) { - input++; - len -= input - extra; - } else - input = extra; - err = hex2sprom(sprom, input, len); - if (err) - goto out_kfree; - - bcm43xx_lock_mmio(bcm, flags); - err = -ENODEV; - if (bcm->initialized) - err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); -out_kfree: - kfree(sprom); -out: - return err; -} - -/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ - -static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); - struct iw_statistics *wstats; - - wstats = &bcm->stats.wstats; - if (!mac->associated) { - wstats->miss.beacon = 0; -// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? - wstats->discard.retries = 0; -// bcm->ieee->ieee_stats.tx_discards_wrong_sa = 0; // FIXME: same question - wstats->discard.nwid = 0; -// bcm->ieee->ieee_stats.rx_discards_undecryptable = 0; // FIXME: ditto - wstats->discard.code = 0; -// bcm->ieee->ieee_stats.rx_fragments = 0; // FIXME: same here - wstats->discard.fragment = 0; - wstats->discard.misc = 0; - wstats->qual.qual = 0; - wstats->qual.level = 0; - wstats->qual.noise = 0; - wstats->qual.updated = 7; - wstats->qual.updated |= IW_QUAL_NOISE_INVALID | - IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; - return wstats; - } - /* fill in the real statistics when iface associated */ - wstats->qual.qual = 100; // TODO: get the real signal quality - wstats->qual.level = 3 - bcm->stats.link_quality; - wstats->qual.noise = bcm->stats.noise; - wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | - IW_QUAL_NOISE_UPDATED; - wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable; - wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded; - wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa; - wstats->discard.fragment = bcm->ieee->ieee_stats.rx_fragments; - wstats->discard.misc = 0; // FIXME - wstats->miss.beacon = 0; // FIXME - return wstats; -} - - -#ifdef WX -# undef WX -#endif -#define WX(ioctl) [(ioctl) - SIOCSIWCOMMIT] -static const iw_handler bcm43xx_wx_handlers[] = { - /* Wireless Identification */ - WX(SIOCGIWNAME) = bcm43xx_wx_get_name, - /* Basic operations */ - WX(SIOCSIWFREQ) = bcm43xx_wx_set_channelfreq, - WX(SIOCGIWFREQ) = bcm43xx_wx_get_channelfreq, - WX(SIOCSIWMODE) = bcm43xx_wx_set_mode, - WX(SIOCGIWMODE) = bcm43xx_wx_get_mode, - /* Informative stuff */ - WX(SIOCGIWRANGE) = bcm43xx_wx_get_rangeparams, - /* Access Point manipulation */ - WX(SIOCSIWAP) = ieee80211softmac_wx_set_wap, - WX(SIOCGIWAP) = ieee80211softmac_wx_get_wap, - WX(SIOCSIWSCAN) = ieee80211softmac_wx_trigger_scan, - WX(SIOCGIWSCAN) = ieee80211softmac_wx_get_scan_results, - /* 802.11 specific support */ - WX(SIOCSIWESSID) = ieee80211softmac_wx_set_essid, - WX(SIOCGIWESSID) = ieee80211softmac_wx_get_essid, - WX(SIOCSIWNICKN) = bcm43xx_wx_set_nick, - WX(SIOCGIWNICKN) = bcm43xx_wx_get_nick, - /* Other parameters */ - WX(SIOCSIWRATE) = ieee80211softmac_wx_set_rate, - WX(SIOCGIWRATE) = ieee80211softmac_wx_get_rate, - WX(SIOCSIWRTS) = bcm43xx_wx_set_rts, - WX(SIOCGIWRTS) = bcm43xx_wx_get_rts, - WX(SIOCSIWFRAG) = bcm43xx_wx_set_frag, - WX(SIOCGIWFRAG) = bcm43xx_wx_get_frag, - WX(SIOCSIWTXPOW) = bcm43xx_wx_set_xmitpower, - WX(SIOCGIWTXPOW) = bcm43xx_wx_get_xmitpower, -//TODO WX(SIOCSIWRETRY) = bcm43xx_wx_set_retry, -//TODO WX(SIOCGIWRETRY) = bcm43xx_wx_get_retry, - /* Encoding */ - WX(SIOCSIWENCODE) = bcm43xx_wx_set_encoding, - WX(SIOCGIWENCODE) = bcm43xx_wx_get_encoding, - WX(SIOCSIWENCODEEXT) = bcm43xx_wx_set_encodingext, - WX(SIOCGIWENCODEEXT) = bcm43xx_wx_get_encodingext, - /* Power saving */ -//TODO WX(SIOCSIWPOWER) = bcm43xx_wx_set_power, -//TODO WX(SIOCGIWPOWER) = bcm43xx_wx_get_power, - WX(SIOCSIWGENIE) = ieee80211softmac_wx_set_genie, - WX(SIOCGIWGENIE) = ieee80211softmac_wx_get_genie, - WX(SIOCSIWAUTH) = ieee80211_wx_set_auth, - WX(SIOCGIWAUTH) = ieee80211_wx_get_auth, -}; -#undef WX - -static const iw_handler bcm43xx_priv_wx_handlers[] = { - /* Set Interference Mitigation Mode. */ - bcm43xx_wx_set_interfmode, - /* Get Interference Mitigation Mode. */ - bcm43xx_wx_get_interfmode, - /* Enable/Disable Short Preamble mode. */ - bcm43xx_wx_set_shortpreamble, - /* Get Short Preamble mode. */ - bcm43xx_wx_get_shortpreamble, - /* Enable/Disable Software Encryption mode */ - bcm43xx_wx_set_swencryption, - /* Get Software Encryption mode */ - bcm43xx_wx_get_swencryption, - /* Write SRPROM data. */ - bcm43xx_wx_sprom_write, - /* Read SPROM data. */ - bcm43xx_wx_sprom_read, -}; - -#define PRIV_WX_SET_INTERFMODE (SIOCIWFIRSTPRIV + 0) -#define PRIV_WX_GET_INTERFMODE (SIOCIWFIRSTPRIV + 1) -#define PRIV_WX_SET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 2) -#define PRIV_WX_GET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 3) -#define PRIV_WX_SET_SWENCRYPTION (SIOCIWFIRSTPRIV + 4) -#define PRIV_WX_GET_SWENCRYPTION (SIOCIWFIRSTPRIV + 5) -#define PRIV_WX_SPROM_WRITE (SIOCIWFIRSTPRIV + 6) -#define PRIV_WX_SPROM_READ (SIOCIWFIRSTPRIV + 7) - -#define PRIV_WX_DUMMY(ioctl) \ - { \ - .cmd = (ioctl), \ - .name = "__unused" \ - } - -static const struct iw_priv_args bcm43xx_priv_wx_args[] = { - { - .cmd = PRIV_WX_SET_INTERFMODE, - .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - .name = "set_interfmode", - }, - { - .cmd = PRIV_WX_GET_INTERFMODE, - .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - .name = "get_interfmode", - }, - { - .cmd = PRIV_WX_SET_SHORTPREAMBLE, - .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - .name = "set_shortpreamb", - }, - { - .cmd = PRIV_WX_GET_SHORTPREAMBLE, - .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - .name = "get_shortpreamb", - }, - { - .cmd = PRIV_WX_SET_SWENCRYPTION, - .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - .name = "set_swencrypt", - }, - { - .cmd = PRIV_WX_GET_SWENCRYPTION, - .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - .name = "get_swencrypt", - }, - { - .cmd = PRIV_WX_SPROM_WRITE, - .set_args = IW_PRIV_TYPE_CHAR | SPROM_BUFFERSIZE, - .name = "write_sprom", - }, - { - .cmd = PRIV_WX_SPROM_READ, - .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | SPROM_BUFFERSIZE, - .name = "read_sprom", - }, -}; - -const struct iw_handler_def bcm43xx_wx_handlers_def = { - .standard = bcm43xx_wx_handlers, - .num_standard = ARRAY_SIZE(bcm43xx_wx_handlers), - .num_private = ARRAY_SIZE(bcm43xx_priv_wx_handlers), - .num_private_args = ARRAY_SIZE(bcm43xx_priv_wx_args), - .private = bcm43xx_priv_wx_handlers, - .private_args = bcm43xx_priv_wx_args, - .get_wireless_stats = bcm43xx_get_wireless_stats, -}; diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.h b/drivers/net/wireless/bcm43xx/bcm43xx_wx.h deleted file mode 100644 index 1f29ff3aa..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel 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; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_WX_H_ -#define BCM43xx_WX_H_ - -extern const struct iw_handler_def bcm43xx_wx_handlers_def; - -#endif /* BCM43xx_WX_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c deleted file mode 100644 index d8ece28c0..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Transmission (TX/RX) related functions. - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx_xmit.h" - -#include - - -/* Extract the bitrate out of a CCK PLCP header. */ -static u8 bcm43xx_plcp_get_bitrate_cck(struct bcm43xx_plcp_hdr4 *plcp) -{ - switch (plcp->raw[0]) { - case 0x0A: - return IEEE80211_CCK_RATE_1MB; - case 0x14: - return IEEE80211_CCK_RATE_2MB; - case 0x37: - return IEEE80211_CCK_RATE_5MB; - case 0x6E: - return IEEE80211_CCK_RATE_11MB; - } - assert(0); - return 0; -} - -/* Extract the bitrate out of an OFDM PLCP header. */ -static u8 bcm43xx_plcp_get_bitrate_ofdm(struct bcm43xx_plcp_hdr4 *plcp) -{ - switch (plcp->raw[0] & 0xF) { - case 0xB: - return IEEE80211_OFDM_RATE_6MB; - case 0xF: - return IEEE80211_OFDM_RATE_9MB; - case 0xA: - return IEEE80211_OFDM_RATE_12MB; - case 0xE: - return IEEE80211_OFDM_RATE_18MB; - case 0x9: - return IEEE80211_OFDM_RATE_24MB; - case 0xD: - return IEEE80211_OFDM_RATE_36MB; - case 0x8: - return IEEE80211_OFDM_RATE_48MB; - case 0xC: - return IEEE80211_OFDM_RATE_54MB; - } - assert(0); - return 0; -} - -u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate) -{ - switch (bitrate) { - case IEEE80211_CCK_RATE_1MB: - return 0x0A; - case IEEE80211_CCK_RATE_2MB: - return 0x14; - case IEEE80211_CCK_RATE_5MB: - return 0x37; - case IEEE80211_CCK_RATE_11MB: - return 0x6E; - } - assert(0); - return 0; -} - -u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate) -{ - switch (bitrate) { - case IEEE80211_OFDM_RATE_6MB: - return 0xB; - case IEEE80211_OFDM_RATE_9MB: - return 0xF; - case IEEE80211_OFDM_RATE_12MB: - return 0xA; - case IEEE80211_OFDM_RATE_18MB: - return 0xE; - case IEEE80211_OFDM_RATE_24MB: - return 0x9; - case IEEE80211_OFDM_RATE_36MB: - return 0xD; - case IEEE80211_OFDM_RATE_48MB: - return 0x8; - case IEEE80211_OFDM_RATE_54MB: - return 0xC; - } - assert(0); - return 0; -} - -static void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp, - const u16 octets, const u8 bitrate, - const int ofdm_modulation) -{ - __le32 *data = &(plcp->data); - __u8 *raw = plcp->raw; - - if (ofdm_modulation) { - *data = bcm43xx_plcp_get_ratecode_ofdm(bitrate); - assert(!(octets & 0xF000)); - *data |= (octets << 5); - *data = cpu_to_le32(*data); - } else { - u32 plen; - - plen = octets * 16 / bitrate; - if ((octets * 16 % bitrate) > 0) { - plen++; - if ((bitrate == IEEE80211_CCK_RATE_11MB) - && ((octets * 8 % 11) < 4)) { - raw[1] = 0x84; - } else - raw[1] = 0x04; - } else - raw[1] = 0x04; - *data |= cpu_to_le32(plen << 16); - raw[0] = bcm43xx_plcp_get_ratecode_cck(bitrate); - } -} - -static u8 bcm43xx_calc_fallback_rate(u8 bitrate) -{ - switch (bitrate) { - case IEEE80211_CCK_RATE_1MB: - return IEEE80211_CCK_RATE_1MB; - case IEEE80211_CCK_RATE_2MB: - return IEEE80211_CCK_RATE_1MB; - case IEEE80211_CCK_RATE_5MB: - return IEEE80211_CCK_RATE_2MB; - case IEEE80211_CCK_RATE_11MB: - return IEEE80211_CCK_RATE_5MB; - case IEEE80211_OFDM_RATE_6MB: - return IEEE80211_CCK_RATE_5MB; - case IEEE80211_OFDM_RATE_9MB: - return IEEE80211_OFDM_RATE_6MB; - case IEEE80211_OFDM_RATE_12MB: - return IEEE80211_OFDM_RATE_9MB; - case IEEE80211_OFDM_RATE_18MB: - return IEEE80211_OFDM_RATE_12MB; - case IEEE80211_OFDM_RATE_24MB: - return IEEE80211_OFDM_RATE_18MB; - case IEEE80211_OFDM_RATE_36MB: - return IEEE80211_OFDM_RATE_24MB; - case IEEE80211_OFDM_RATE_48MB: - return IEEE80211_OFDM_RATE_36MB; - case IEEE80211_OFDM_RATE_54MB: - return IEEE80211_OFDM_RATE_48MB; - } - assert(0); - return 0; -} - -static -__le16 bcm43xx_calc_duration_id(const struct ieee80211_hdr *wireless_header, - u8 bitrate) -{ - const u16 frame_ctl = le16_to_cpu(wireless_header->frame_ctl); - __le16 duration_id = wireless_header->duration_id; - - switch (WLAN_FC_GET_TYPE(frame_ctl)) { - case IEEE80211_FTYPE_DATA: - case IEEE80211_FTYPE_MGMT: - //TODO: Steal the code from ieee80211, once it is completed there. - break; - case IEEE80211_FTYPE_CTL: - /* Use the original duration/id. */ - break; - default: - assert(0); - } - - return duration_id; -} - -static inline -u16 ceiling_div(u16 dividend, u16 divisor) -{ - return ((dividend + divisor - 1) / divisor); -} - -static void bcm43xx_generate_rts(const struct bcm43xx_phyinfo *phy, - struct bcm43xx_txhdr *txhdr, - u16 *flags, - u8 bitrate, - const struct ieee80211_hdr_4addr *wlhdr) -{ - u16 fctl; - u16 dur; - u8 fallback_bitrate; - int ofdm_modulation; - int fallback_ofdm_modulation; -// u8 *sa, *da; - u16 flen; - -//FIXME sa = ieee80211_get_SA((struct ieee80211_hdr *)wlhdr); -//FIXME da = ieee80211_get_DA((struct ieee80211_hdr *)wlhdr); - fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate); - ofdm_modulation = !(ieee80211_is_cck_rate(bitrate)); - fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate)); - - flen = sizeof(u16) + sizeof(u16) + ETH_ALEN + ETH_ALEN + IEEE80211_FCS_LEN, - bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_plcp), - flen, bitrate, - !ieee80211_is_cck_rate(bitrate)); - bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_fallback_plcp), - flen, fallback_bitrate, - !ieee80211_is_cck_rate(fallback_bitrate)); - fctl = IEEE80211_FTYPE_CTL; - fctl |= IEEE80211_STYPE_RTS; - dur = le16_to_cpu(wlhdr->duration_id); -/*FIXME: should we test for dur==0 here and let it unmodified in this case? - * The following assert checks for this case... - */ -assert(dur); -/*FIXME: The duration calculation is not really correct. - * I am not 100% sure which bitrate to use. We use the RTS rate here, - * but this is likely to be wrong. - */ - if (phy->type == BCM43xx_PHYTYPE_A) { - /* Three times SIFS */ - dur += 16 * 3; - /* Add ACK duration. */ - dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10, - bitrate * 4); - /* Add CTS duration. */ - dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10, - bitrate * 4); - } else { - /* Three times SIFS */ - dur += 10 * 3; - /* Add ACK duration. */ - dur += ceiling_div(8 * (14 /*bytes*/) * 10, - bitrate); - /* Add CTS duration. */ - dur += ceiling_div(8 * (14 /*bytes*/) * 10, - bitrate); - } - - txhdr->rts_cts_frame_control = cpu_to_le16(fctl); - txhdr->rts_cts_dur = cpu_to_le16(dur); -//printk(BCM43xx_MACFMT " " BCM43xx_MACFMT " " BCM43xx_MACFMT "\n", BCM43xx_MACARG(wlhdr->addr1), BCM43xx_MACARG(wlhdr->addr2), BCM43xx_MACARG(wlhdr->addr3)); -//printk(BCM43xx_MACFMT " " BCM43xx_MACFMT "\n", BCM43xx_MACARG(sa), BCM43xx_MACARG(da)); - memcpy(txhdr->rts_cts_mac1, wlhdr->addr1, ETH_ALEN);//FIXME! -// memcpy(txhdr->rts_cts_mac2, sa, ETH_ALEN); - - *flags |= BCM43xx_TXHDRFLAG_RTSCTS; - *flags |= BCM43xx_TXHDRFLAG_RTS; - if (ofdm_modulation) - *flags |= BCM43xx_TXHDRFLAG_RTSCTS_OFDM; - if (fallback_ofdm_modulation) - *flags |= BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM; -} - -void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm, - struct bcm43xx_txhdr *txhdr, - const unsigned char *fragment_data, - const unsigned int fragment_len, - const int is_first_fragment, - const u16 cookie) -{ - const struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - const struct ieee80211_hdr_4addr *wireless_header = (const struct ieee80211_hdr_4addr *)fragment_data; - const struct ieee80211_security *secinfo = &bcm->ieee->sec; - u8 bitrate; - u8 fallback_bitrate; - int ofdm_modulation; - int fallback_ofdm_modulation; - u16 plcp_fragment_len = fragment_len; - u16 flags = 0; - u16 control = 0; - u16 wsec_rate = 0; - u16 encrypt_frame; - - /* Now construct the TX header. */ - memset(txhdr, 0, sizeof(*txhdr)); - - bitrate = bcm->softmac->txrates.default_rate; - ofdm_modulation = !(ieee80211_is_cck_rate(bitrate)); - fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate); - fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate)); - - /* Set Frame Control from 80211 header. */ - txhdr->frame_control = wireless_header->frame_ctl; - /* Copy address1 from 80211 header. */ - memcpy(txhdr->mac1, wireless_header->addr1, 6); - /* Set the fallback duration ID. */ - txhdr->fallback_dur_id = bcm43xx_calc_duration_id((const struct ieee80211_hdr *)wireless_header, - fallback_bitrate); - /* Set the cookie (used as driver internal ID for the frame) */ - txhdr->cookie = cpu_to_le16(cookie); - - /* Hardware appends FCS. */ - plcp_fragment_len += IEEE80211_FCS_LEN; - - /* Hardware encryption. */ - encrypt_frame = le16_to_cpup(&wireless_header->frame_ctl) & IEEE80211_FCTL_PROTECTED; - if (encrypt_frame && !bcm->ieee->host_encrypt) { - const struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)wireless_header; - memcpy(txhdr->wep_iv, hdr->payload, 4); - /* Hardware appends ICV. */ - plcp_fragment_len += 4; - - wsec_rate |= (bcm->key[secinfo->active_key].algorithm << BCM43xx_TXHDR_WSEC_ALGO_SHIFT) - & BCM43xx_TXHDR_WSEC_ALGO_MASK; - wsec_rate |= (secinfo->active_key << BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT) - & BCM43xx_TXHDR_WSEC_KEYINDEX_MASK; - } - - /* Generate the PLCP header and the fallback PLCP header. */ - bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->plcp), - plcp_fragment_len, - bitrate, ofdm_modulation); - bcm43xx_generate_plcp_hdr(&txhdr->fallback_plcp, plcp_fragment_len, - fallback_bitrate, fallback_ofdm_modulation); - - /* Set the CONTROL field */ - if (ofdm_modulation) - control |= BCM43xx_TXHDRCTL_OFDM; - if (bcm->short_preamble) //FIXME: could be the other way around, please test - control |= BCM43xx_TXHDRCTL_SHORT_PREAMBLE; - control |= (phy->antenna_diversity << BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT) - & BCM43xx_TXHDRCTL_ANTENNADIV_MASK; - - /* Set the FLAGS field */ - if (!is_multicast_ether_addr(wireless_header->addr1) && - !is_broadcast_ether_addr(wireless_header->addr1)) - flags |= BCM43xx_TXHDRFLAG_EXPECTACK; - if (1 /* FIXME: PS poll?? */) - flags |= 0x10; // FIXME: unknown meaning. - if (fallback_ofdm_modulation) - flags |= BCM43xx_TXHDRFLAG_FALLBACKOFDM; - if (is_first_fragment) - flags |= BCM43xx_TXHDRFLAG_FIRSTFRAGMENT; - - /* Set WSEC/RATE field */ - wsec_rate |= (txhdr->plcp.raw[0] << BCM43xx_TXHDR_RATE_SHIFT) - & BCM43xx_TXHDR_RATE_MASK; - - /* Generate the RTS/CTS packet, if required. */ - /* FIXME: We should first try with CTS-to-self, - * if we are on 80211g. If we get too many - * failures (hidden nodes), we should switch back to RTS/CTS. - */ - if (0/*FIXME txctl->use_rts_cts*/) { - bcm43xx_generate_rts(phy, txhdr, &flags, - 0/*FIXME txctl->rts_cts_rate*/, - wireless_header); - } - - txhdr->flags = cpu_to_le16(flags); - txhdr->control = cpu_to_le16(control); - txhdr->wsec_rate = cpu_to_le16(wsec_rate); -} - -static s8 bcm43xx_rssi_postprocess(struct bcm43xx_private *bcm, - u8 in_rssi, int ofdm, - int adjust_2053, int adjust_2050) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - s32 tmp; - - switch (radio->version) { - case 0x2050: - if (ofdm) { - tmp = in_rssi; - if (tmp > 127) - tmp -= 256; - tmp *= 73; - tmp /= 64; - if (adjust_2050) - tmp += 25; - else - tmp -= 3; - } else { - if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { - if (in_rssi > 63) - in_rssi = 63; - tmp = radio->nrssi_lt[in_rssi]; - tmp = 31 - tmp; - tmp *= -131; - tmp /= 128; - tmp -= 57; - } else { - tmp = in_rssi; - tmp = 31 - tmp; - tmp *= -149; - tmp /= 128; - tmp -= 68; - } - if (phy->type == BCM43xx_PHYTYPE_G && - adjust_2050) - tmp += 25; - } - break; - case 0x2060: - if (in_rssi > 127) - tmp = in_rssi - 256; - else - tmp = in_rssi; - break; - default: - tmp = in_rssi; - tmp -= 11; - tmp *= 103; - tmp /= 64; - if (adjust_2053) - tmp -= 109; - else - tmp -= 83; - } - - return (s8)tmp; -} - -//TODO -#if 0 -static s8 bcm43xx_rssinoise_postprocess(struct bcm43xx_private *bcm, - u8 in_rssi) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - s8 ret; - - if (phy->type == BCM43xx_PHYTYPE_A) { - //TODO: Incomplete specs. - ret = 0; - } else - ret = bcm43xx_rssi_postprocess(bcm, in_rssi, 0, 1, 1); - - return ret; -} -#endif - -int bcm43xx_rx(struct bcm43xx_private *bcm, - struct sk_buff *skb, - struct bcm43xx_rxhdr *rxhdr) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_plcp_hdr4 *plcp; - struct ieee80211_rx_stats stats; - struct ieee80211_hdr_4addr *wlhdr; - u16 frame_ctl; - int is_packet_for_us = 0; - int err = -EINVAL; - const u16 rxflags1 = le16_to_cpu(rxhdr->flags1); - const u16 rxflags2 = le16_to_cpu(rxhdr->flags2); - const u16 rxflags3 = le16_to_cpu(rxhdr->flags3); - const int is_ofdm = !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_OFDM); - - if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) { - plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data + 2); - /* Skip two unknown bytes and the PLCP header. */ - skb_pull(skb, 2 + sizeof(struct bcm43xx_plcp_hdr6)); - } else { - plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data); - /* Skip the PLCP header. */ - skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6)); - } - /* The SKB contains the PAYLOAD (wireless header + data) - * at this point. The FCS at the end is stripped. - */ - - memset(&stats, 0, sizeof(stats)); - stats.mac_time = le16_to_cpu(rxhdr->mactime); - stats.rssi = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm, - !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ), - !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ)); - stats.signal = rxhdr->signal_quality; //FIXME -//TODO stats.noise = - if (is_ofdm) - stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp); - else - stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp); -//printk("RX ofdm %d, rate == %u\n", is_ofdm, stats.rate); - stats.received_channel = radio->channel; -//TODO stats.control = - stats.mask = IEEE80211_STATMASK_SIGNAL | -//TODO IEEE80211_STATMASK_NOISE | - IEEE80211_STATMASK_RATE | - IEEE80211_STATMASK_RSSI; - if (phy->type == BCM43xx_PHYTYPE_A) - stats.freq = IEEE80211_52GHZ_BAND; - else - stats.freq = IEEE80211_24GHZ_BAND; - stats.len = skb->len; - - bcm->stats.last_rx = jiffies; - if (bcm->ieee->iw_mode == IW_MODE_MONITOR) { - err = ieee80211_rx(bcm->ieee, skb, &stats); - return (err == 0) ? -EINVAL : 0; - } - - wlhdr = (struct ieee80211_hdr_4addr *)(skb->data); - - switch (bcm->ieee->iw_mode) { - case IW_MODE_ADHOC: - if (memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 || - memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 || - is_broadcast_ether_addr(wlhdr->addr1) || - is_multicast_ether_addr(wlhdr->addr1) || - bcm->net_dev->flags & IFF_PROMISC) - is_packet_for_us = 1; - break; - case IW_MODE_INFRA: - default: - /* When receiving multicast or broadcast packets, filter out - the packets we send ourself; we shouldn't see those */ - if (memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 || - memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 || - (memcmp(wlhdr->addr3, bcm->net_dev->dev_addr, ETH_ALEN) && - (is_broadcast_ether_addr(wlhdr->addr1) || - is_multicast_ether_addr(wlhdr->addr1) || - bcm->net_dev->flags & IFF_PROMISC))) - is_packet_for_us = 1; - break; - } - - frame_ctl = le16_to_cpu(wlhdr->frame_ctl); - if ((frame_ctl & IEEE80211_FCTL_PROTECTED) && !bcm->ieee->host_decrypt) { - frame_ctl &= ~IEEE80211_FCTL_PROTECTED; - wlhdr->frame_ctl = cpu_to_le16(frame_ctl); - /* trim IV and ICV */ - /* FIXME: this must be done only for WEP encrypted packets */ - if (skb->len < 32) { - dprintkl(KERN_ERR PFX "RX packet dropped (PROTECTED flag " - "set and length < 32)\n"); - return -EINVAL; - } else { - memmove(skb->data + 4, skb->data, 24); - skb_pull(skb, 4); - skb_trim(skb, skb->len - 4); - stats.len -= 8; - } - wlhdr = (struct ieee80211_hdr_4addr *)(skb->data); - } - - switch (WLAN_FC_GET_TYPE(frame_ctl)) { - case IEEE80211_FTYPE_MGMT: - ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats); - break; - case IEEE80211_FTYPE_DATA: - if (is_packet_for_us) { - err = ieee80211_rx(bcm->ieee, skb, &stats); - err = (err == 0) ? -EINVAL : 0; - } - break; - case IEEE80211_FTYPE_CTL: - break; - default: - assert(0); - return -EINVAL; - } - - return err; -} diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h deleted file mode 100644 index 2aed19e35..000000000 --- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef BCM43xx_XMIT_H_ -#define BCM43xx_XMIT_H_ - -#include "bcm43xx_main.h" - - -#define _bcm43xx_declare_plcp_hdr(size) \ - struct bcm43xx_plcp_hdr##size { \ - union { \ - __le32 data; \ - __u8 raw[size]; \ - } __attribute__((__packed__)); \ - } __attribute__((__packed__)) - -/* struct bcm43xx_plcp_hdr4 */ -_bcm43xx_declare_plcp_hdr(4); -/* struct bcm43xx_plcp_hdr6 */ -_bcm43xx_declare_plcp_hdr(6); - -#undef _bcm43xx_declare_plcp_hdr - -/* Device specific TX header. To be prepended to TX frames. */ -struct bcm43xx_txhdr { - union { - struct { - __le16 flags; - __le16 wsec_rate; - __le16 frame_control; - u16 unknown_zeroed_0; - __le16 control; - u8 wep_iv[10]; - u8 unknown_wsec_tkip_data[3]; //FIXME - PAD_BYTES(3); - u8 mac1[6]; - u16 unknown_zeroed_1; - struct bcm43xx_plcp_hdr4 rts_cts_fallback_plcp; - __le16 rts_cts_dur_fallback; - struct bcm43xx_plcp_hdr4 fallback_plcp; - __le16 fallback_dur_id; - PAD_BYTES(2); - __le16 cookie; - __le16 unknown_scb_stuff; //FIXME - struct bcm43xx_plcp_hdr6 rts_cts_plcp; - __le16 rts_cts_frame_control; - __le16 rts_cts_dur; - u8 rts_cts_mac1[6]; - u8 rts_cts_mac2[6]; - PAD_BYTES(2); - struct bcm43xx_plcp_hdr6 plcp; - } __attribute__((__packed__)); - u8 raw[82]; - } __attribute__((__packed__)); -} __attribute__((__packed__)); - -/* Values/Masks for the device TX header */ -#define BCM43xx_TXHDRFLAG_EXPECTACK 0x0001 -#define BCM43xx_TXHDRFLAG_RTSCTS 0x0002 -#define BCM43xx_TXHDRFLAG_RTS 0x0004 -#define BCM43xx_TXHDRFLAG_FIRSTFRAGMENT 0x0008 -#define BCM43xx_TXHDRFLAG_DESTPSMODE 0x0020 -#define BCM43xx_TXHDRFLAG_RTSCTS_OFDM 0x0080 -#define BCM43xx_TXHDRFLAG_FALLBACKOFDM 0x0100 -#define BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM 0x0200 -#define BCM43xx_TXHDRFLAG_CTS 0x0400 -#define BCM43xx_TXHDRFLAG_FRAMEBURST 0x0800 - -#define BCM43xx_TXHDRCTL_OFDM 0x0001 -#define BCM43xx_TXHDRCTL_SHORT_PREAMBLE 0x0010 -#define BCM43xx_TXHDRCTL_ANTENNADIV_MASK 0x0030 -#define BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT 8 - -#define BCM43xx_TXHDR_RATE_MASK 0x0F00 -#define BCM43xx_TXHDR_RATE_SHIFT 8 -#define BCM43xx_TXHDR_RTSRATE_MASK 0xF000 -#define BCM43xx_TXHDR_RTSRATE_SHIFT 12 -#define BCM43xx_TXHDR_WSEC_KEYINDEX_MASK 0x00F0 -#define BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT 4 -#define BCM43xx_TXHDR_WSEC_ALGO_MASK 0x0003 -#define BCM43xx_TXHDR_WSEC_ALGO_SHIFT 0 - -void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm, - struct bcm43xx_txhdr *txhdr, - const unsigned char *fragment_data, - const unsigned int fragment_len, - const int is_first_fragment, - const u16 cookie); - -/* RX header as received from the hardware. */ -struct bcm43xx_rxhdr { - /* Frame Length. Must be generated explicitely in PIO mode. */ - __le16 frame_length; - PAD_BYTES(2); - /* Flags field 1 */ - __le16 flags1; - u8 rssi; - u8 signal_quality; - PAD_BYTES(2); - /* Flags field 3 */ - __le16 flags3; - /* Flags field 2 */ - __le16 flags2; - /* Lower 16bits of the TSF at the time the frame started. */ - __le16 mactime; - PAD_BYTES(14); -} __attribute__((__packed__)); - -#define BCM43xx_RXHDR_FLAGS1_OFDM (1 << 0) -/*#define BCM43xx_RXHDR_FLAGS1_SIGNAL??? (1 << 3) FIXME */ -#define BCM43xx_RXHDR_FLAGS1_SHORTPREAMBLE (1 << 7) -#define BCM43xx_RXHDR_FLAGS1_2053RSSIADJ (1 << 14) - -#define BCM43xx_RXHDR_FLAGS2_INVALIDFRAME (1 << 0) -#define BCM43xx_RXHDR_FLAGS2_TYPE2FRAME (1 << 2) -/*FIXME: WEP related flags */ - -#define BCM43xx_RXHDR_FLAGS3_2050RSSIADJ (1 << 10) - -/* Transmit Status as received from the hardware. */ -struct bcm43xx_hwxmitstatus { - PAD_BYTES(4); - __le16 cookie; - u8 flags; - u8 cnt1:4, - cnt2:4; - PAD_BYTES(2); - __le16 seq; - __le16 unknown; //FIXME -} __attribute__((__packed__)); - -/* Transmit Status in CPU byteorder. */ -struct bcm43xx_xmitstatus { - u16 cookie; - u8 flags; - u8 cnt1:4, - cnt2:4; - u16 seq; - u16 unknown; //FIXME -}; - -#define BCM43xx_TXSTAT_FLAG_ACK 0x01 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x02 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x04 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x08 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x10 -#define BCM43xx_TXSTAT_FLAG_IGNORE 0x20 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x40 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x80 - -u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate); -u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate); - -int bcm43xx_rx(struct bcm43xx_private *bcm, - struct sk_buff *skb, - struct bcm43xx_rxhdr *rxhdr); - -#endif /* BCM43xx_XMIT_H_ */ diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h index cc1ee7f4f..1fc72fe51 100644 --- a/drivers/net/wireless/hostap/hostap_80211.h +++ b/drivers/net/wireless/hostap/hostap_80211.h @@ -92,6 +92,8 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, void hostap_dump_tx_80211(const char *name, struct sk_buff *skb); int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev); int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); +struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, + struct ieee80211_crypt_data *crypt); int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev); #endif /* HOSTAP_80211_H */ diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c index 06a521414..5f398bd83 100644 --- a/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/drivers/net/wireless/hostap/hostap_80211_tx.c @@ -299,8 +299,8 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Called only from software IRQ */ -static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, - struct ieee80211_crypt_data *crypt) +struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, + struct ieee80211_crypt_data *crypt) { struct hostap_interface *iface; local_info_t *local; @@ -317,7 +317,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, } if (local->tkip_countermeasures && - strcmp(crypt->ops->name, "TKIP") == 0) { + crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { hdr = (struct ieee80211_hdr_4addr *) skb->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " @@ -535,4 +535,5 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) EXPORT_SYMBOL(hostap_dump_tx_80211); +EXPORT_SYMBOL(hostap_tx_encrypt); EXPORT_SYMBOL(hostap_master_start_xmit); diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 06c3fa32b..753a1de66 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -3141,7 +3141,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr) if (ret == 1) { sta = ap_add_sta(ap, sta_addr); if (!sta) - return -1; + ret = -1; sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; sta->ap = 1; memset(sta->supported_rates, 0, sizeof(sta->supported_rates)); diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 55bed923f..f8f450347 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -42,7 +42,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry"); /* struct local_info::hw_priv */ struct hostap_cs_priv { dev_node_t node; - struct pcmcia_device *link; + dev_link_t *link; int sandisk_connectplus; }; @@ -204,13 +204,15 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) static void prism2_detach(struct pcmcia_device *p_dev); static void prism2_release(u_long arg); -static int prism2_config(struct pcmcia_device *link); +static int prism2_config(dev_link_t *link); static int prism2_pccard_card_present(local_info_t *local) { struct hostap_cs_priv *hw_priv = local->hw_priv; - if (hw_priv != NULL && hw_priv->link != NULL && pcmcia_dev_present(hw_priv->link)) + if (hw_priv != NULL && hw_priv->link != NULL && + ((hw_priv->link->state & (DEV_PRESENT | DEV_CONFIG)) == + (DEV_PRESENT | DEV_CONFIG))) return 1; return 0; } @@ -235,7 +237,7 @@ static void sandisk_set_iobase(local_info_t *local) reg.Action = CS_WRITE; reg.Offset = 0x10; /* 0x3f0 IO base 1 */ reg.Value = hw_priv->link->io.BasePort1 & 0x00ff; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" @@ -247,7 +249,7 @@ static void sandisk_set_iobase(local_info_t *local) reg.Action = CS_WRITE; reg.Offset = 0x12; /* 0x3f2 IO base 2 */ reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" @@ -299,9 +301,9 @@ static int sandisk_enable_wireless(struct net_device *dev) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || - pcmcia_get_tuple_data(hw_priv->link, &tuple) || - pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || + if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) || + pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) || + pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) || parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) { /* No SanDisk manfid found */ ret = -ENODEV; @@ -309,9 +311,9 @@ static int sandisk_enable_wireless(struct net_device *dev) } tuple.DesiredTuple = CISTPL_LONGLINK_MFC; - if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || - pcmcia_get_tuple_data(hw_priv->link, &tuple) || - pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || + if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) || + pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) || + pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) || parse->longlink_mfc.nfn < 2) { /* No multi-function links found */ ret = -ENODEV; @@ -326,7 +328,7 @@ static int sandisk_enable_wireless(struct net_device *dev) reg.Action = CS_WRITE; reg.Offset = CISREG_COR; reg.Value = COR_SOFT_RESET; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", @@ -343,7 +345,7 @@ static int sandisk_enable_wireless(struct net_device *dev) * will be enabled during the first cor_sreset call. */ reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", @@ -378,7 +380,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Action = CS_READ; reg.Offset = CISREG_COR; reg.Value = 0; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n", @@ -390,7 +392,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Action = CS_WRITE; reg.Value |= COR_SOFT_RESET; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n", @@ -403,7 +405,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Value &= ~COR_SOFT_RESET; if (hw_priv->sandisk_connectplus) reg.Value |= COR_IREQ_ENA; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n", @@ -437,7 +439,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Action = CS_READ; reg.Offset = CISREG_COR; reg.Value = 0; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " @@ -450,7 +452,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Action = CS_WRITE; reg.Value |= COR_SOFT_RESET; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " @@ -464,7 +466,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Action = CS_WRITE; reg.Value = hcr; reg.Offset = CISREG_CCSR; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " @@ -476,7 +478,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Action = CS_WRITE; reg.Offset = CISREG_COR; reg.Value = old_cor & ~COR_SOFT_RESET; - res = pcmcia_access_configuration_register(hw_priv->link, + res = pcmcia_access_configuration_register(hw_priv->link->handle, ®); if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " @@ -499,27 +501,40 @@ static struct prism2_helper_functions prism2_pccard_funcs = /* allocate local data and register with CardServices * initialize dev_link structure, but do not configure the card yet */ -static int hostap_cs_probe(struct pcmcia_device *p_dev) +static int prism2_attach(struct pcmcia_device *p_dev) { - int ret; + dev_link_t *link; + + link = kmalloc(sizeof(dev_link_t), GFP_KERNEL); + if (link == NULL) + return -ENOMEM; + + memset(link, 0, sizeof(dev_link_t)); PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info); - p_dev->conf.IntType = INT_MEMORY_AND_IO; + link->conf.Vcc = 33; + link->conf.IntType = INT_MEMORY_AND_IO; + + link->handle = p_dev; + p_dev->instance = link; - ret = prism2_config(p_dev); - if (ret) { + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + if (prism2_config(link)) PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); - } - return ret; + return 0; } -static void prism2_detach(struct pcmcia_device *link) +static void prism2_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + PDEBUG(DEBUG_FLOW, "prism2_detach\n"); - prism2_release((u_long)link); + if (link->state & DEV_CONFIG) { + prism2_release((u_long)link); + } /* release net devices */ if (link->priv) { @@ -532,6 +547,7 @@ static void prism2_detach(struct pcmcia_device *link) prism2_free_local_data(dev); kfree(hw_priv); } + kfree(link); } @@ -542,7 +558,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) do { int ret = (retf); \ if (ret != 0) { \ PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \ - cs_error(link, fn, ret); \ + cs_error(link->handle, fn, ret); \ goto next_entry; \ } \ } while (0) @@ -550,7 +566,7 @@ if (ret != 0) { \ /* run after a CARD_INSERTION event is received to configure the PCMCIA * socket and make the device available to the system */ -static int prism2_config(struct pcmcia_device *link) +static int prism2_config(dev_link_t *link) { struct net_device *dev; struct hostap_interface *iface; @@ -569,6 +585,8 @@ static int prism2_config(struct pcmcia_device *link) parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL); if (parse == NULL || hw_priv == NULL) { + kfree(parse); + kfree(hw_priv); ret = -ENOMEM; goto failed; } @@ -579,24 +597,27 @@ static int prism2_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link->handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link->handle, &tuple, parse)); link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); + pcmcia_get_configuration_info(link->handle, &conf)); + PDEBUG(DEBUG_HW, "%s: %s Vcc=%d (from config)\n", dev_info, + ignore_cis_vcc ? "ignoring" : "setting", conf.Vcc); + link->conf.Vcc = conf.Vcc; /* Look for an appropriate configuration table entry in the CIS */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple)); for (;;) { cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); CFG_CHECK2(GetTupleData, - pcmcia_get_tuple_data(link, &tuple)); + pcmcia_get_tuple_data(link->handle, &tuple)); CFG_CHECK2(ParseTuple, - pcmcia_parse_tuple(link, &tuple, parse)); + pcmcia_parse_tuple(link->handle, &tuple, parse)); if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; @@ -631,10 +652,10 @@ static int prism2_config(struct pcmcia_device *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; /* Do we need to allocate an interrupt? */ @@ -676,19 +697,19 @@ static int prism2_config(struct pcmcia_device *link) /* This reserves IO space but doesn't actually enable it */ CFG_CHECK2(RequestIO, - pcmcia_request_io(link, &link->io)); + pcmcia_request_io(link->handle, &link->io)); /* This configuration table entry is OK */ break; next_entry: CS_CHECK(GetNextTuple, - pcmcia_get_next_tuple(link, &tuple)); + pcmcia_get_next_tuple(link->handle, &tuple)); } /* Need to allocate net_device before requesting IRQ handler */ dev = prism2_init_local_data(&prism2_pccard_funcs, 0, - &handle_to_dev(link)); + &handle_to_dev(link->handle)); if (dev == NULL) goto failed; link->priv = dev; @@ -698,7 +719,7 @@ static int prism2_config(struct pcmcia_device *link) local->hw_priv = hw_priv; hw_priv->link = link; strcpy(hw_priv->node.dev_name, dev->name); - link->dev_node = &hw_priv->node; + link->dev = &hw_priv->node; /* * Allocate an interrupt line. Note that this does not assign a @@ -711,7 +732,7 @@ static int prism2_config(struct pcmcia_device *link) link->irq.Handler = prism2_interrupt; link->irq.Instance = dev; CS_CHECK(RequestIRQ, - pcmcia_request_irq(link, &link->irq)); + pcmcia_request_irq(link->handle, &link->irq)); } /* @@ -720,17 +741,18 @@ static int prism2_config(struct pcmcia_device *link) * card and host interface into "Memory and IO" mode. */ CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link, &link->conf)); + pcmcia_request_configuration(link->handle, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x: ", - dev_info, link->conf.ConfigIndex); - if (link->conf.Vpp) - printk(", Vpp %d.%d", link->conf.Vpp / 10, - link->conf.Vpp % 10); + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", + dev_info, link->conf.ConfigIndex, + link->conf.Vcc / 10, link->conf.Vcc % 10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1 / 10, + link->conf.Vpp1 % 10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) @@ -741,6 +763,9 @@ static int prism2_config(struct pcmcia_device *link) link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); + link->state |= DEV_CONFIG; + link->state &= ~DEV_CONFIG_PENDING; + local->shutdown = 0; sandisk_enable_wireless(dev); @@ -755,7 +780,7 @@ static int prism2_config(struct pcmcia_device *link) return ret; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: kfree(parse); @@ -767,7 +792,7 @@ static int prism2_config(struct pcmcia_device *link) static void prism2_release(u_long arg) { - struct pcmcia_device *link = (struct pcmcia_device *)arg; + dev_link_t *link = (dev_link_t *)arg; PDEBUG(DEBUG_FLOW, "prism2_release\n"); @@ -776,54 +801,71 @@ static void prism2_release(u_long arg) struct hostap_interface *iface; iface = netdev_priv(dev); - prism2_hw_shutdown(dev, 0); + if (link->state & DEV_CONFIG) + prism2_hw_shutdown(dev, 0); iface->local->shutdown = 1; } - pcmcia_disable_device(link); + if (link->win) + pcmcia_release_window(link->win); + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; + PDEBUG(DEBUG_FLOW, "release - done\n"); } -static int hostap_cs_suspend(struct pcmcia_device *link) +static int hostap_cs_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = (struct net_device *) link->priv; int dev_open = 0; - struct hostap_interface *iface = NULL; - - if (dev) - iface = netdev_priv(dev); PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); - if (iface && iface->local) - dev_open = iface->local->num_dev_open > 0; - if (dev_open) { - netif_stop_queue(dev); - netif_device_detach(dev); + + link->state |= DEV_SUSPEND; + + if (link->state & DEV_CONFIG) { + struct hostap_interface *iface = netdev_priv(dev); + if (iface && iface->local) + dev_open = iface->local->num_dev_open > 0; + if (dev_open) { + netif_stop_queue(dev); + netif_device_detach(dev); + } + prism2_suspend(dev); + pcmcia_release_configuration(link->handle); } - prism2_suspend(dev); return 0; } -static int hostap_cs_resume(struct pcmcia_device *link) +static int hostap_cs_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = (struct net_device *) link->priv; int dev_open = 0; - struct hostap_interface *iface = NULL; - - if (dev) - iface = netdev_priv(dev); PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); - if (iface && iface->local) - dev_open = iface->local->num_dev_open > 0; + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + struct hostap_interface *iface = netdev_priv(dev); + if (iface && iface->local) + dev_open = iface->local->num_dev_open > 0; - prism2_hw_shutdown(dev, 1); - prism2_hw_config(dev, dev_open ? 0 : 1); - if (dev_open) { - netif_device_attach(dev); - netif_start_queue(dev); + pcmcia_request_configuration(link->handle, &link->conf); + + prism2_hw_shutdown(dev, 1); + prism2_hw_config(dev, dev_open ? 0 : 1); + if (dev_open) { + netif_device_attach(dev); + netif_start_queue(dev); + } } return 0; @@ -890,7 +932,7 @@ static struct pcmcia_driver hostap_driver = { .drv = { .name = "hostap_cs", }, - .probe = hostap_cs_probe, + .probe = prism2_attach, .remove = prism2_detach, .owner = THIS_MODULE, .id_table = hostap_cs_ids, diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 328e9a1d1..b1f142d9e 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -928,16 +928,16 @@ static int hfa384x_set_rid(struct net_device *dev, u16 rid, void *buf, int len) res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL); up(&local->rid_bap_sem); - if (res) { printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE " "failed (res=%d, rid=%04x, len=%d)\n", dev->name, res, rid, len); - - if (res == -ETIMEDOUT) - prism2_hw_reset(dev); + return res; } + if (res == -ETIMEDOUT) + prism2_hw_reset(dev); + return res; } diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 8399de581..f3e0ce1ee 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -1860,7 +1860,7 @@ static char * __prism2_translate_scan(local_info_t *local, memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; if (scan) { - chan = le16_to_cpu(scan->chid); + chan = scan->chid; } else if (bss) { chan = bss->chan; } else { @@ -1868,7 +1868,7 @@ static char * __prism2_translate_scan(local_info_t *local, } if (chan > 0) { - iwe.u.freq.m = freq_list[chan - 1] * 100000; + iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000; iwe.u.freq.e = 1; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); @@ -3358,6 +3358,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { if (!sta_ptr) local->tx_keyidx = i; + else if (i) { + ret = -EINVAL; + goto done; + } } diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c index 194f07097..2e85bdced 100644 --- a/drivers/net/wireless/hostap/hostap_pci.c +++ b/drivers/net/wireless/hostap/hostap_pci.c @@ -307,7 +307,7 @@ static int prism2_pci_probe(struct pci_dev *pdev, memset(hw_priv, 0, sizeof(*hw_priv)); if (pci_enable_device(pdev)) - goto err_out_free; + return -EIO; phymem = pci_resource_start(pdev, 0); @@ -368,8 +368,6 @@ static int prism2_pci_probe(struct pci_dev *pdev, err_out_disable: pci_disable_device(pdev); prism2_free_local_data(dev); - - err_out_free: kfree(hw_priv); return -ENODEV; diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index edaaa943e..94fe2449f 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c @@ -368,7 +368,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, switch (cis[pos]) { case CISTPL_CONFIG: - if (cis[pos + 1] < 2) + if (cis[pos + 1] < 1) goto cis_error; rmsz = (cis[pos + 2] & 0x3c) >> 2; rasz = cis[pos + 2] & 0x03; @@ -390,7 +390,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, break; case CISTPL_MANFID: - if (cis[pos + 1] < 5) + if (cis[pos + 1] < 4) goto cis_error; manfid1 = cis[pos + 2] + (cis[pos + 3] << 8); manfid2 = cis[pos + 4] + (cis[pos + 5] << 8); @@ -452,7 +452,7 @@ static int prism2_plx_probe(struct pci_dev *pdev, memset(hw_priv, 0, sizeof(*hw_priv)); if (pci_enable_device(pdev)) - goto err_out_free; + return -EIO; /* National Datacomm NCP130 based on TMD7160, not PLX9052. */ tmd7160 = (pdev->vendor == 0x15e8) && (pdev->device == 0x0131); @@ -567,6 +567,9 @@ static int prism2_plx_probe(struct pci_dev *pdev, return hostap_hw_ready(dev); fail: + prism2_free_local_data(dev); + kfree(hw_priv); + if (irq_registered && dev) free_irq(dev->irq, dev); @@ -574,10 +577,6 @@ static int prism2_plx_probe(struct pci_dev *pdev, iounmap(attr_mem); pci_disable_device(pdev); - prism2_free_local_data(dev); - - err_out_free: - kfree(hw_priv); return -ENODEV; } diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 72335c8eb..6290c9f7e 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -167,12 +167,12 @@ that only one external action is invoked at a time. #include "ipw2100.h" -#define IPW2100_VERSION "git-1.2.2" +#define IPW2100_VERSION "1.1.3" #define DRV_NAME "ipw2100" #define DRV_VERSION IPW2100_VERSION #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" -#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation" /* Debugging stuff */ #ifdef CONFIG_IPW2100_DEBUG @@ -1418,7 +1418,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv) if (priv->status & STATUS_ENABLED) return 0; - mutex_lock(&priv->adapter_mutex); + down(&priv->adapter_sem); if (rf_kill_active(priv)) { IPW_DEBUG_HC("Command aborted due to RF kill active.\n"); @@ -1444,7 +1444,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv) } fail_up: - mutex_unlock(&priv->adapter_mutex); + up(&priv->adapter_sem); return err; } @@ -1576,7 +1576,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv) cancel_delayed_work(&priv->hang_check); } - mutex_lock(&priv->adapter_mutex); + down(&priv->adapter_sem); err = ipw2100_hw_send_command(priv, &cmd); if (err) { @@ -1595,7 +1595,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv) IPW_DEBUG_INFO("TODO: implement scan state machine\n"); fail_up: - mutex_unlock(&priv->adapter_mutex); + up(&priv->adapter_sem); return err; } @@ -1672,18 +1672,6 @@ static int ipw2100_start_scan(struct ipw2100_priv *priv) return err; } -static const struct ieee80211_geo ipw_geos[] = { - { /* Restricted */ - "---", - .bg_channels = 14, - .bg = {{2412, 1}, {2417, 2}, {2422, 3}, - {2427, 4}, {2432, 5}, {2437, 6}, - {2442, 7}, {2447, 8}, {2452, 9}, - {2457, 10}, {2462, 11}, {2467, 12}, - {2472, 13}, {2484, 14}}, - }, -}; - static int ipw2100_up(struct ipw2100_priv *priv, int deferred) { unsigned long flags; @@ -1739,13 +1727,6 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) goto exit; } - /* Initialize the geo */ - if (ieee80211_set_geo(priv->ieee, &ipw_geos[0])) { - printk(KERN_WARNING DRV_NAME "Could not set geo\n"); - return 0; - } - priv->ieee->freq_band = IEEE80211_24GHZ_BAND; - lock = LOCK_NONE; if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) { printk(KERN_ERR DRV_NAME @@ -1888,7 +1869,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv) priv->status |= STATUS_RESET_PENDING; spin_unlock_irqrestore(&priv->low_lock, flags); - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); /* stop timed checks so that they don't interfere with reset */ priv->stop_hang_check = 1; cancel_delayed_work(&priv->hang_check); @@ -1898,7 +1879,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv) wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); ipw2100_up(priv, 0); - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); } @@ -2390,6 +2371,15 @@ static void isr_rx(struct ipw2100_priv *priv, int i, IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); return; } +#ifdef CONFIG_IPW2100_MONITOR + if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR && + priv->config & CFG_CRC_CHECK && + status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { + IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); + priv->ieee->stats.rx_errors++; + return; + } +#endif if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR && !(priv->status & STATUS_ASSOCIATED))) { @@ -2437,89 +2427,6 @@ static void isr_rx(struct ipw2100_priv *priv, int i, priv->rx_queue.drv[i].host_addr = packet->dma_addr; } -#ifdef CONFIG_IPW2100_MONITOR - -static void isr_rx_monitor(struct ipw2100_priv *priv, int i, - struct ieee80211_rx_stats *stats) -{ - struct ipw2100_status *status = &priv->status_queue.drv[i]; - struct ipw2100_rx_packet *packet = &priv->rx_buffers[i]; - - /* Magic struct that slots into the radiotap header -- no reason - * to build this manually element by element, we can write it much - * more efficiently than we can parse it. ORDER MATTERS HERE */ - struct ipw_rt_hdr { - struct ieee80211_radiotap_header rt_hdr; - s8 rt_dbmsignal; /* signal in dbM, kluged to signed */ - } *ipw_rt; - - IPW_DEBUG_RX("Handler...\n"); - - if (unlikely(status->frame_size > skb_tailroom(packet->skb) - - sizeof(struct ipw_rt_hdr))) { - IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!" - " Dropping.\n", - priv->net_dev->name, - status->frame_size, - skb_tailroom(packet->skb)); - priv->ieee->stats.rx_errors++; - return; - } - - if (unlikely(!netif_running(priv->net_dev))) { - priv->ieee->stats.rx_errors++; - priv->wstats.discard.misc++; - IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); - return; - } - - if (unlikely(priv->config & CFG_CRC_CHECK && - status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { - IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); - priv->ieee->stats.rx_errors++; - return; - } - - pci_unmap_single(priv->pci_dev, packet->dma_addr, - sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE); - memmove(packet->skb->data + sizeof(struct ipw_rt_hdr), - packet->skb->data, status->frame_size); - - ipw_rt = (struct ipw_rt_hdr *) packet->skb->data; - - ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; - ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */ - ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total hdr+data */ - - ipw_rt->rt_hdr.it_present = 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL; - - ipw_rt->rt_dbmsignal = status->rssi + IPW2100_RSSI_TO_DBM; - - skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr)); - - if (!ieee80211_rx(priv->ieee, packet->skb, stats)) { - priv->ieee->stats.rx_errors++; - - /* ieee80211_rx failed, so it didn't free the SKB */ - dev_kfree_skb_any(packet->skb); - packet->skb = NULL; - } - - /* We need to allocate a new SKB and attach it to the RDB. */ - if (unlikely(ipw2100_alloc_skb(priv, packet))) { - IPW_DEBUG_WARNING( - "%s: Unable to allocate SKB onto RBD ring - disabling " - "adapter.\n", priv->net_dev->name); - /* TODO: schedule adapter shutdown */ - IPW_DEBUG_INFO("TODO: Shutdown adapter...\n"); - } - - /* Update the RDB entry */ - priv->rx_queue.drv[i].host_addr = packet->dma_addr; -} - -#endif - static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i) { struct ipw2100_status *status = &priv->status_queue.drv[i]; @@ -2651,7 +2558,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv) case P8023_DATA_VAL: #ifdef CONFIG_IPW2100_MONITOR if (priv->ieee->iw_mode == IW_MODE_MONITOR) { - isr_rx_monitor(priv, i, &stats); + isr_rx(priv, i, &stats); break; } #endif @@ -3843,7 +3750,7 @@ static ssize_t store_memory(struct device *d, struct device_attribute *attr, struct net_device *dev = priv->net_dev; const char *p = buf; - (void)dev; /* kill unused-var warning for debug-only code */ + (void) dev; /* kill unused-var warning for debug-only code */ if (count < 1) return count; @@ -3956,7 +3863,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) #ifdef CONFIG_IPW2100_MONITOR case IW_MODE_MONITOR: priv->last_mode = priv->ieee->iw_mode; - priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP; + priv->net_dev->type = ARPHRD_IEEE80211; break; #endif /* CONFIG_IPW2100_MONITOR */ } @@ -4163,7 +4070,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, unsigned long val; char *p = buffer; - (void)dev; /* kill unused-var warning for debug-only code */ + (void) dev; /* kill unused-var warning for debug-only code */ IPW_DEBUG_INFO("enter\n"); @@ -4212,7 +4119,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio) IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", disable_radio ? "OFF" : "ON"); - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (disable_radio) { priv->status |= STATUS_RF_KILL_SW; @@ -4230,7 +4137,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio) schedule_reset(priv); } - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return 1; } @@ -5200,13 +5107,12 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power) .host_command_length = 4 }; int err = 0; - u32 tmp = tx_power; if (tx_power != IPW_TX_POWER_DEFAULT) - tmp = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 / - (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM); + tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 / + (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM); - cmd.host_command_parameters[0] = tmp; + cmd.host_command_parameters[0] = tx_power; if (priv->ieee->iw_mode == IW_MODE_ADHOC) err = ipw2100_hw_send_command(priv, &cmd); @@ -5459,12 +5365,9 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode) SEC_LEVEL_0, 0, 1); } else { auth_mode = IPW_AUTH_OPEN; - if (priv->ieee->sec.flags & SEC_AUTH_MODE) { - if (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY) - auth_mode = IPW_AUTH_SHARED; - else if (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP) - auth_mode = IPW_AUTH_LEAP_CISCO_ID; - } + if ((priv->ieee->sec.flags & SEC_AUTH_MODE) && + (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) + auth_mode = IPW_AUTH_SHARED; sec_level = SEC_LEVEL_0; if (priv->ieee->sec.flags & SEC_LEVEL) @@ -5534,7 +5437,7 @@ static void shim__set_security(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int i, force_update = 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) goto done; @@ -5607,7 +5510,7 @@ static void shim__set_security(struct net_device *dev, if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) ipw2100_configure_security(priv, 0); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); } static int ipw2100_adapter_setup(struct ipw2100_priv *priv) @@ -5731,7 +5634,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); priv->config |= CFG_CUSTOM_MAC; memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); @@ -5741,12 +5644,12 @@ static int ipw2100_set_address(struct net_device *dev, void *p) goto done; priv->reset_backoff = 0; - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); ipw2100_reset_adapter(priv); return 0; done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -5857,9 +5760,6 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) { sec.auth_mode = WLAN_AUTH_OPEN; ieee->open_wep = 1; - } else if (value & IW_AUTH_ALG_LEAP) { - sec.auth_mode = WLAN_AUTH_LEAP; - ieee->open_wep = 1; } else return -EINVAL; @@ -5871,8 +5771,8 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) return ret; } -static void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, - char *wpa_ie, int wpa_ie_len) +void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, + char *wpa_ie, int wpa_ie_len) { struct ipw2100_wpa_assoc_frame frame; @@ -6089,8 +5989,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, strcpy(priv->nick, "ipw2100"); spin_lock_init(&priv->low_lock); - mutex_init(&priv->action_mutex); - mutex_init(&priv->adapter_mutex); + sema_init(&priv->action_sem, 1); + sema_init(&priv->adapter_sem, 1); init_waitqueue_head(&priv->wait_command_queue); @@ -6255,7 +6155,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, * member to call a function that then just turns and calls ipw2100_up. * net_dev->init is called after name allocation but before the * notifier chain is called */ - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); err = register_netdev(dev); if (err) { printk(KERN_WARNING DRV_NAME @@ -6291,12 +6191,12 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, priv->status |= STATUS_INITIALIZED; - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return 0; fail_unlock: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); fail: if (dev) { @@ -6336,7 +6236,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) struct net_device *dev; if (priv) { - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); priv->status &= ~STATUS_INITIALIZED; @@ -6351,9 +6251,9 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) /* Take down the hardware */ ipw2100_down(priv); - /* Release the mutex so that the network subsystem can + /* Release the semaphore so that the network subsystem can * complete any needed calls into the driver... */ - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); /* Unregister the device first - this results in close() * being called if the device is open. If we free storage @@ -6392,7 +6292,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name); - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (priv->status & STATUS_INITIALIZED) { /* Take down the device; powers it off, etc. */ ipw2100_down(priv); @@ -6405,7 +6305,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) pci_disable_device(pci_dev); pci_set_power_state(pci_dev, PCI_D3hot); - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return 0; } @@ -6419,7 +6319,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev) if (IPW2100_PM_DISABLED) return 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name); @@ -6445,7 +6345,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev) if (!(priv->status & STATUS_RF_KILL_SW)) ipw2100_up(priv, 0); - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return 0; } @@ -6609,7 +6509,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev, if (priv->ieee->iw_mode == IW_MODE_INFRA) return -EOPNOTSUPP; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -6640,7 +6540,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev, } done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -6681,7 +6581,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev, if (wrqu->mode == priv->ieee->iw_mode) return 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -6704,7 +6604,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev, } done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -6886,7 +6786,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev, if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) return -EINVAL; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -6915,7 +6815,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev, wrqu->ap_addr.sa_data[5] & 0xff); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -6951,7 +6851,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, int length = 0; int err = 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -6988,7 +6888,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, err = ipw2100_set_essid(priv, essid, length, 0); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7069,7 +6969,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev, u32 rate; int err = 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7096,7 +6996,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev, IPW_DEBUG_WX("SET Rate -> %04X \n", rate); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7116,7 +7016,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev, return 0; } - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7148,7 +7048,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev, IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7163,7 +7063,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev, if (wrqu->rts.fixed == 0) return -EINVAL; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7183,7 +7083,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev, IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7234,7 +7134,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev, value = wrqu->txpower.value; } - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7245,7 +7145,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev, IPW_DEBUG_WX("SET TX Power -> %d \n", value); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7337,7 +7237,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev, if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) return 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7364,7 +7264,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev, IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7407,7 +7307,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err = 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7422,7 +7322,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev, } done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7472,7 +7372,7 @@ static int ipw2100_wx_set_power(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err = 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7505,7 +7405,7 @@ static int ipw2100_wx_set_power(struct net_device *dev, IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7809,7 +7709,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev, int enable = (parms[0] > 0); int err = 0; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7827,7 +7727,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev, err = ipw2100_switch_mode(priv, priv->last_mode); } done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7850,7 +7750,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err = 0, mode = *(int *)extra; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7862,7 +7762,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev, if (priv->power_mode != mode) err = ipw2100_set_power_mode(priv, mode); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7914,7 +7814,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err, mode = *(int *)extra; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7932,7 +7832,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev, err = ipw2100_system_config(priv, 0); done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -7962,7 +7862,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err, mode = *(int *)extra; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7979,7 +7879,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev, err = 0; done: - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); return err; } @@ -8284,11 +8184,11 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv) if (priv->status & STATUS_STOPPING) return; - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); IPW_DEBUG_WX("enter\n"); - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -8311,7 +8211,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv) if (!(priv->status & STATUS_ASSOCIATED)) { IPW_DEBUG_WX("Configuring ESSID\n"); - mutex_lock(&priv->action_mutex); + down(&priv->action_sem); /* This is a disassociation event, so kick the firmware to * look for another AP */ if (priv->config & CFG_STATIC_ESSID) @@ -8319,7 +8219,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv) 0); else ipw2100_set_essid(priv, NULL, 0, 0); - mutex_unlock(&priv->action_mutex); + up(&priv->action_sem); } wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h index 55b722719..f6c51441f 100644 --- a/drivers/net/wireless/ipw2100.h +++ b/drivers/net/wireless/ipw2100.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -41,12 +41,7 @@ #include -#ifdef CONFIG_IPW2100_MONITOR -#include -#endif - #include -#include struct ipw2100_priv; struct ipw2100_tx_packet; @@ -397,10 +392,8 @@ struct ipw2100_notification { #define IPW_WEP104_CIPHER (1<<5) #define IPW_CKIP_CIPHER (1<<6) -#define IPW_AUTH_OPEN 0 -#define IPW_AUTH_SHARED 1 -#define IPW_AUTH_LEAP 2 -#define IPW_AUTH_LEAP_CISCO_ID 0x80 +#define IPW_AUTH_OPEN 0 +#define IPW_AUTH_SHARED 1 struct statistic { int value; @@ -595,8 +588,8 @@ struct ipw2100_priv { int inta_other; spinlock_t low_lock; - struct mutex action_mutex; - struct mutex adapter_mutex; + struct semaphore action_sem; + struct semaphore adapter_sem; wait_queue_head_t wait_command_queue; }; diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index bca89cff8..f42e51a7b 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 802.11 status code portion of this file from ethereal-0.10.6: Copyright 2000, Axis Communications AB @@ -33,9 +33,9 @@ #include "ipw2200.h" #include -#define IPW2200_VERSION "git-1.1.1" +#define IPW2200_VERSION "git-1.0.8" #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" -#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation" #define DRV_VERSION IPW2200_VERSION #define ETH_P_80211_STATS (ETH_P_80211_RAW + 1) @@ -55,9 +55,7 @@ static int associate = 1; static int auto_create = 1; static int led = 0; static int disable = 0; -static int bt_coexist = 0; -static int hwcrypto = 0; -static int roaming = 1; +static int hwcrypto = 1; static const char ipw_modes[] = { 'a', 'b', 'g', '?' }; @@ -153,6 +151,12 @@ static int init_supported_rates(struct ipw_priv *priv, static void ipw_set_hwcrypto_keys(struct ipw_priv *); static void ipw_send_wep_keys(struct ipw_priv *, int); +static int ipw_is_valid_channel(struct ieee80211_device *, u8); +static int ipw_channel_to_index(struct ieee80211_device *, u8); +static u8 ipw_freq_to_channel(struct ieee80211_device *, u32); +static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *); +static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *); + static int snprint_line(char *buf, size_t count, const u8 * data, u32 len, u32 ofs) { @@ -223,15 +227,12 @@ static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len) return total; } -/* alias for 32-bit indirect read (for SRAM/reg above 4K), with debug wrapper */ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg); #define ipw_read_reg32(a, b) _ipw_read_reg32(a, b) -/* alias for 8-bit indirect read (for SRAM/reg above 4K), with debug wrapper */ static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg); #define ipw_read_reg8(a, b) _ipw_read_reg8(a, b) -/* 8-bit indirect write (for SRAM/reg above 4K), with debug wrapper */ static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value); static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c) { @@ -240,7 +241,6 @@ static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c) _ipw_write_reg8(a, b, c); } -/* 16-bit indirect write (for SRAM/reg above 4K), with debug wrapper */ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value); static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c) { @@ -249,7 +249,6 @@ static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c) _ipw_write_reg16(a, b, c); } -/* 32-bit indirect write (for SRAM/reg above 4K), with debug wrapper */ static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value); static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) { @@ -258,70 +257,48 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) _ipw_write_reg32(a, b, c); } -/* 8-bit direct write (low 4K) */ #define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs)) - -/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */ #define ipw_write8(ipw, ofs, val) \ IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ _ipw_write8(ipw, ofs, val) -/* 16-bit direct write (low 4K) */ #define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs)) - -/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */ #define ipw_write16(ipw, ofs, val) \ IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ _ipw_write16(ipw, ofs, val) -/* 32-bit direct write (low 4K) */ #define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs)) - -/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */ #define ipw_write32(ipw, ofs, val) \ IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ _ipw_write32(ipw, ofs, val) -/* 8-bit direct read (low 4K) */ #define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs)) - -/* 8-bit direct read (low 4K), with debug wrapper */ static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs)); return _ipw_read8(ipw, ofs); } -/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */ #define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs) -/* 16-bit direct read (low 4K) */ #define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs)) - -/* 16-bit direct read (low 4K), with debug wrapper */ static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs)); return _ipw_read16(ipw, ofs); } -/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */ #define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs) -/* 32-bit direct read (low 4K) */ #define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs)) - -/* 32-bit direct read (low 4K), with debug wrapper */ static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs)); return _ipw_read32(ipw, ofs); } -/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */ #define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) -/* multi-byte read (above 4K), with debug wrapper */ static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); static inline void __ipw_read_indirect(const char *f, int l, struct ipw_priv *a, u32 b, u8 * c, int d) @@ -331,17 +308,15 @@ static inline void __ipw_read_indirect(const char *f, int l, _ipw_read_indirect(a, b, c, d); } -/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */ #define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d) -/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data, int num); #define ipw_write_indirect(a, b, c, d) \ IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ _ipw_write_indirect(a, b, c, d) -/* 32-bit indirect write (above 4K) */ +/* indirect write s */ static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) { IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); @@ -349,29 +324,22 @@ static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) _ipw_write32(priv, IPW_INDIRECT_DATA, value); } -/* 8-bit indirect write (above 4K) */ static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) { - u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */ - u32 dif_len = reg - aligned_addr; - IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); - _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); - _ipw_write8(priv, IPW_INDIRECT_DATA + dif_len, value); + _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK); + _ipw_write8(priv, IPW_INDIRECT_DATA, value); } -/* 16-bit indirect write (above 4K) */ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value) { - u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */ - u32 dif_len = (reg - aligned_addr) & (~0x1ul); - IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); - _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); - _ipw_write16(priv, IPW_INDIRECT_DATA + dif_len, value); + _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK); + _ipw_write16(priv, IPW_INDIRECT_DATA, value); } -/* 8-bit indirect read (above 4K) */ +/* indirect read s */ + static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) { u32 word; @@ -381,7 +349,6 @@ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) return (word >> ((reg & 0x3) * 8)) & 0xff; } -/* 32-bit indirect read (above 4K) */ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg) { u32 value; @@ -394,12 +361,11 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg) return value; } -/* General purpose, no alignment requirement, iterative (multi-byte) read, */ -/* for area above 1st 4K of SRAM/reg space */ +/* iterative/auto-increment 32 bit reads and writes */ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, int num) { - u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */ + u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; u32 dif_len = addr - aligned_addr; u32 i; @@ -409,7 +375,7 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, return; } - /* Read the first dword (or portion) byte by byte */ + /* Read the first nibble byte by byte */ if (unlikely(dif_len)) { _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); /* Start reading at aligned_addr + dif_len */ @@ -418,12 +384,11 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, aligned_addr += 4; } - /* Read all of the middle dwords as dwords, with auto-increment */ _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr); for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4) *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA); - /* Read the last dword (or portion) byte by byte */ + /* Copy the last nibble */ if (unlikely(num)) { _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); for (i = 0; num > 0; i++, num--) @@ -431,12 +396,10 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, } } -/* General purpose, no alignment requirement, iterative (multi-byte) write, */ -/* for area above 1st 4K of SRAM/reg space */ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, int num) { - u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */ + u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; u32 dif_len = addr - aligned_addr; u32 i; @@ -446,21 +409,20 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, return; } - /* Write the first dword (or portion) byte by byte */ + /* Write the first nibble byte by byte */ if (unlikely(dif_len)) { _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); - /* Start writing at aligned_addr + dif_len */ + /* Start reading at aligned_addr + dif_len */ for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++) _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf); aligned_addr += 4; } - /* Write all of the middle dwords as dwords, with auto-increment */ _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr); for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4) _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf); - /* Write the last dword (or portion) byte by byte */ + /* Copy the last nibble */ if (unlikely(num)) { _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); for (i = 0; num > 0; i++, num--, buf++) @@ -468,21 +430,17 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, } } -/* General purpose, no alignment requirement, iterative (multi-byte) write, */ -/* for 1st 4K of SRAM/regs space */ static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, int num) { memcpy_toio((priv->hw_base + addr), buf, num); } -/* Set bit(s) in low 4K of SRAM/regs */ static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask) { ipw_write32(priv, reg, ipw_read32(priv, reg) | mask); } -/* Clear bit(s) in low 4K of SRAM/regs */ static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask) { ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); @@ -743,7 +701,7 @@ static void ipw_init_ordinals(struct ipw_priv *priv) } -static u32 ipw_register_toggle(u32 reg) +u32 ipw_register_toggle(u32 reg) { reg &= ~IPW_START_STANDBY; if (reg & IPW_GATE_ODMA) @@ -764,11 +722,11 @@ static u32 ipw_register_toggle(u32 reg) * - On radio OFF, turn off any LEDs started during radio on * */ -#define LD_TIME_LINK_ON msecs_to_jiffies(300) -#define LD_TIME_LINK_OFF msecs_to_jiffies(2700) -#define LD_TIME_ACT_ON msecs_to_jiffies(250) +#define LD_TIME_LINK_ON 300 +#define LD_TIME_LINK_OFF 2700 +#define LD_TIME_ACT_ON 250 -static void ipw_led_link_on(struct ipw_priv *priv) +void ipw_led_link_on(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -806,12 +764,12 @@ static void ipw_led_link_on(struct ipw_priv *priv) static void ipw_bg_led_link_on(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_led_link_on(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } -static void ipw_led_link_off(struct ipw_priv *priv) +void ipw_led_link_off(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -850,9 +808,9 @@ static void ipw_led_link_off(struct ipw_priv *priv) static void ipw_bg_led_link_off(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_led_link_off(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static void __ipw_led_activity_on(struct ipw_priv *priv) @@ -889,7 +847,6 @@ static void __ipw_led_activity_on(struct ipw_priv *priv) } } -#if 0 void ipw_led_activity_on(struct ipw_priv *priv) { unsigned long flags; @@ -897,9 +854,8 @@ void ipw_led_activity_on(struct ipw_priv *priv) __ipw_led_activity_on(priv); spin_unlock_irqrestore(&priv->lock, flags); } -#endif /* 0 */ -static void ipw_led_activity_off(struct ipw_priv *priv) +void ipw_led_activity_off(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -929,12 +885,12 @@ static void ipw_led_activity_off(struct ipw_priv *priv) static void ipw_bg_led_activity_off(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_led_activity_off(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } -static void ipw_led_band_on(struct ipw_priv *priv) +void ipw_led_band_on(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -969,7 +925,7 @@ static void ipw_led_band_on(struct ipw_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void ipw_led_band_off(struct ipw_priv *priv) +void ipw_led_band_off(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -992,24 +948,24 @@ static void ipw_led_band_off(struct ipw_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void ipw_led_radio_on(struct ipw_priv *priv) +void ipw_led_radio_on(struct ipw_priv *priv) { ipw_led_link_on(priv); } -static void ipw_led_radio_off(struct ipw_priv *priv) +void ipw_led_radio_off(struct ipw_priv *priv) { ipw_led_activity_off(priv); ipw_led_link_off(priv); } -static void ipw_led_link_up(struct ipw_priv *priv) +void ipw_led_link_up(struct ipw_priv *priv) { /* Set the Link Led on for all nic types */ ipw_led_link_on(priv); } -static void ipw_led_link_down(struct ipw_priv *priv) +void ipw_led_link_down(struct ipw_priv *priv) { ipw_led_activity_off(priv); ipw_led_link_off(priv); @@ -1018,7 +974,7 @@ static void ipw_led_link_down(struct ipw_priv *priv) ipw_led_radio_off(priv); } -static void ipw_led_init(struct ipw_priv *priv) +void ipw_led_init(struct ipw_priv *priv) { priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE]; @@ -1069,7 +1025,7 @@ static void ipw_led_init(struct ipw_priv *priv) } } -static void ipw_led_shutdown(struct ipw_priv *priv) +void ipw_led_shutdown(struct ipw_priv *priv) { ipw_led_activity_off(priv); ipw_led_link_off(priv); @@ -1118,7 +1074,6 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, static inline u32 ipw_get_event_log_len(struct ipw_priv *priv) { - /* length = 1st dword in log */ return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG)); } @@ -1648,7 +1603,7 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr, break; } - if (ieee80211_is_valid_channel(priv->ieee, channel)) + if (ipw_is_valid_channel(priv->ieee, channel)) priv->speed_scan[pos++] = channel; else IPW_WARNING("Skipping invalid channel request: %d\n", @@ -1796,9 +1751,9 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) } if (inta & IPW_INTA_BIT_FATAL_ERROR) { - IPW_WARNING("Firmware error detected. Restarting.\n"); + IPW_ERROR("Firmware error detected. Restarting.\n"); if (priv->error) { - IPW_DEBUG_FW("Sysfs 'error' log already exists.\n"); + IPW_ERROR("Sysfs 'error' log already exists.\n"); #ifdef CONFIG_IPW2200_DEBUG if (ipw_debug_level & IPW_DL_FW_ERRORS) { struct ipw_fw_error *error = @@ -1811,10 +1766,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) } else { priv->error = ipw_alloc_error_log(priv); if (priv->error) - IPW_DEBUG_FW("Sysfs 'error' log captured.\n"); + IPW_ERROR("Sysfs 'error' log captured.\n"); else - IPW_DEBUG_FW("Error allocating sysfs 'error' " - "log.\n"); + IPW_ERROR("Error allocating sysfs 'error' " + "log.\n"); #ifdef CONFIG_IPW2200_DEBUG if (ipw_debug_level & IPW_DL_FW_ERRORS) ipw_dump_error_log(priv, priv->error); @@ -1915,8 +1870,7 @@ static char *get_cmd_string(u8 cmd) } #define HOST_COMPLETE_TIMEOUT HZ - -static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) +static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) { int rc = 0; unsigned long flags; @@ -1943,15 +1897,9 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n", get_cmd_string(cmd->cmd), cmd->cmd, cmd->len, priv->status); + printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); -#ifndef DEBUG_CMD_WEP_KEY - if (cmd->cmd == IPW_CMD_WEP_KEY) - IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n"); - else -#endif - printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); - - rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0); + rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); if (rc) { priv->status &= ~STATUS_HCMD_ACTIVE; IPW_ERROR("Failed to send %s: Reason %d\n", @@ -1994,62 +1942,61 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) return rc; } -static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command) -{ - struct host_cmd cmd = { - .cmd = command, - }; - - return __ipw_send_cmd(priv, &cmd); -} - -static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len, - void *data) +static int ipw_send_host_complete(struct ipw_priv *priv) { struct host_cmd cmd = { - .cmd = command, - .len = len, - .param = data, + .cmd = IPW_CMD_HOST_COMPLETE, + .len = 0 }; - return __ipw_send_cmd(priv, &cmd); -} - -static int ipw_send_host_complete(struct ipw_priv *priv) -{ if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_system_config(struct ipw_priv *priv, struct ipw_sys_config *config) { + struct host_cmd cmd = { + .cmd = IPW_CMD_SYSTEM_CONFIG, + .len = sizeof(*config) + }; + if (!priv || !config) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, sizeof(*config), - config); + memcpy(cmd.param, config, sizeof(*config)); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) { + struct host_cmd cmd = { + .cmd = IPW_CMD_SSID, + .len = min(len, IW_ESSID_MAX_SIZE) + }; + if (!priv || !ssid) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE), - ssid); + memcpy(cmd.param, ssid, cmd.len); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) { + struct host_cmd cmd = { + .cmd = IPW_CMD_ADAPTER_ADDRESS, + .len = ETH_ALEN + }; + if (!priv || !mac) { IPW_ERROR("Invalid args\n"); return -1; @@ -2058,7 +2005,8 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n", priv->net_dev->name, MAC_ARG(mac)); - return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac); + memcpy(cmd.param, mac, ETH_ALEN); + return ipw_send_cmd(priv, &cmd); } /* @@ -2088,9 +2036,9 @@ static void ipw_adapter_restart(void *adapter) static void ipw_bg_adapter_restart(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_adapter_restart(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } #define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) @@ -2100,8 +2048,8 @@ static void ipw_scan_check(void *data) struct ipw_priv *priv = data; if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { IPW_DEBUG_SCAN("Scan completion watchdog resetting " - "adapter after (%dms).\n", - jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG)); + "adapter (%dms).\n", + IPW_SCAN_CHECK_WATCHDOG / 100); queue_work(priv->workqueue, &priv->adapter_restart); } } @@ -2109,48 +2057,59 @@ static void ipw_scan_check(void *data) static void ipw_bg_scan_check(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_scan_check(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static int ipw_send_scan_request_ext(struct ipw_priv *priv, struct ipw_scan_request_ext *request) { - return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT, - sizeof(*request), request); + struct host_cmd cmd = { + .cmd = IPW_CMD_SCAN_REQUEST_EXT, + .len = sizeof(*request) + }; + + memcpy(cmd.param, request, sizeof(*request)); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_scan_abort(struct ipw_priv *priv) { + struct host_cmd cmd = { + .cmd = IPW_CMD_SCAN_ABORT, + .len = 0 + }; + if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT); + return ipw_send_cmd(priv, &cmd); } static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) { - struct ipw_sensitivity_calib calib = { - .beacon_rssi_raw = sens, + struct host_cmd cmd = { + .cmd = IPW_CMD_SENSITIVITY_CALIB, + .len = sizeof(struct ipw_sensitivity_calib) }; - - return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib), - &calib); + struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) + &cmd.param; + calib->beacon_rssi_raw = sens; + return ipw_send_cmd(priv, &cmd); } static int ipw_send_associate(struct ipw_priv *priv, struct ipw_associate *associate) { - struct ipw_associate tmp_associate; - - if (!priv || !associate) { - IPW_ERROR("Invalid args\n"); - return -1; - } + struct host_cmd cmd = { + .cmd = IPW_CMD_ASSOCIATE, + .len = sizeof(*associate) + }; + struct ipw_associate tmp_associate; memcpy(&tmp_associate, associate, sizeof(*associate)); tmp_associate.policy_support = cpu_to_le16(tmp_associate.policy_support); @@ -2163,60 +2122,85 @@ static int ipw_send_associate(struct ipw_priv *priv, cpu_to_le16(tmp_associate.beacon_interval); tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window); - return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(tmp_associate), - &tmp_associate); + if (!priv || !associate) { + IPW_ERROR("Invalid args\n"); + return -1; + } + + memcpy(cmd.param, &tmp_associate, sizeof(*associate)); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_supported_rates(struct ipw_priv *priv, struct ipw_supported_rates *rates) { + struct host_cmd cmd = { + .cmd = IPW_CMD_SUPPORTED_RATES, + .len = sizeof(*rates) + }; + if (!priv || !rates) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates), - rates); + memcpy(cmd.param, rates, sizeof(*rates)); + return ipw_send_cmd(priv, &cmd); } static int ipw_set_random_seed(struct ipw_priv *priv) { - u32 val; + struct host_cmd cmd = { + .cmd = IPW_CMD_SEED_NUMBER, + .len = sizeof(u32) + }; if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - get_random_bytes(&val, sizeof(val)); + get_random_bytes(&cmd.param, sizeof(u32)); - return ipw_send_cmd_pdu(priv, IPW_CMD_SEED_NUMBER, sizeof(val), &val); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) { + struct host_cmd cmd = { + .cmd = IPW_CMD_CARD_DISABLE, + .len = sizeof(u32) + }; + if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off), - &phy_off); + *((u32 *) & cmd.param) = phy_off; + + return ipw_send_cmd(priv, &cmd); } static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) { + struct host_cmd cmd = { + .cmd = IPW_CMD_TX_POWER, + .len = sizeof(*power) + }; + if (!priv || !power) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_pdu(priv, IPW_CMD_TX_POWER, sizeof(*power), power); + memcpy(cmd.param, power, sizeof(*power)); + return ipw_send_cmd(priv, &cmd); } static int ipw_set_tx_power(struct ipw_priv *priv) { - const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); + const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); struct ipw_tx_power tx_power; s8 max_power; int i; @@ -2263,14 +2247,18 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) struct ipw_rts_threshold rts_threshold = { .rts_threshold = rts, }; + struct host_cmd cmd = { + .cmd = IPW_CMD_RTS_THRESHOLD, + .len = sizeof(rts_threshold) + }; if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_pdu(priv, IPW_CMD_RTS_THRESHOLD, - sizeof(rts_threshold), &rts_threshold); + memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold)); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) @@ -2278,19 +2266,27 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) struct ipw_frag_threshold frag_threshold = { .frag_threshold = frag, }; + struct host_cmd cmd = { + .cmd = IPW_CMD_FRAG_THRESHOLD, + .len = sizeof(frag_threshold) + }; if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_pdu(priv, IPW_CMD_FRAG_THRESHOLD, - sizeof(frag_threshold), &frag_threshold); + memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold)); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) { - u32 param; + struct host_cmd cmd = { + .cmd = IPW_CMD_POWER_MODE, + .len = sizeof(u32) + }; + u32 *param = (u32 *) (&cmd.param); if (!priv) { IPW_ERROR("Invalid args\n"); @@ -2301,18 +2297,17 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) * level */ switch (mode) { case IPW_POWER_BATTERY: - param = IPW_POWER_INDEX_3; + *param = IPW_POWER_INDEX_3; break; case IPW_POWER_AC: - param = IPW_POWER_MODE_CAM; + *param = IPW_POWER_MODE_CAM; break; default: - param = mode; + *param = mode; break; } - return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), - ¶m); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit) @@ -2321,14 +2316,18 @@ static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit) .short_retry_limit = slimit, .long_retry_limit = llimit }; + struct host_cmd cmd = { + .cmd = IPW_CMD_RETRY_LIMIT, + .len = sizeof(retry_limit) + }; if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd_pdu(priv, IPW_CMD_RETRY_LIMIT, sizeof(retry_limit), - &retry_limit); + memcpy(cmd.param, &retry_limit, sizeof(retry_limit)); + return ipw_send_cmd(priv, &cmd); } /* @@ -2455,7 +2454,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv) /* If the data looks correct, then copy it to our private copy. Otherwise let the firmware know to perform the operation - on its own. + on it's own */ if (priv->eeprom[EEPROM_VERSION] != 0) { IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); @@ -2708,25 +2707,22 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, static int ipw_fw_dma_wait(struct ipw_priv *priv) { - u32 current_index = 0, previous_index; + u32 current_index = 0; u32 watchdog = 0; IPW_DEBUG_FW(">> : \n"); current_index = ipw_fw_dma_command_block_index(priv); - IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n", + IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n", (int)priv->sram_desc.last_cb_index); while (current_index < priv->sram_desc.last_cb_index) { udelay(50); - previous_index = current_index; current_index = ipw_fw_dma_command_block_index(priv); - if (previous_index < current_index) { - watchdog = 0; - continue; - } - if (++watchdog > 400) { + watchdog++; + + if (watchdog > 400) { IPW_DEBUG_FW_INFO("Timeout\n"); ipw_fw_dma_dump_command_block(priv); ipw_fw_dma_abort(priv); @@ -2776,7 +2772,6 @@ static inline int ipw_alive(struct ipw_priv *priv) return ipw_read32(priv, 0x90) == 0xd55555d5; } -/* timeout in msec, attempted in 10-msec quanta */ static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask, int timeout) { @@ -2805,11 +2800,10 @@ static int ipw_stop_master(struct ipw_priv *priv) /* stop master. typical delay - 0 */ ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER); - /* timeout is in msec, polled in 10-msec quanta */ rc = ipw_poll_bit(priv, IPW_RESET_REG, IPW_RESET_REG_MASTER_DISABLED, 100); if (rc < 0) { - IPW_ERROR("wait for stop master failed after 100ms\n"); + IPW_ERROR("stop master failed in 10ms\n"); return -1; } @@ -2829,11 +2823,33 @@ static void ipw_arc_release(struct ipw_priv *priv) mdelay(5); } +struct fw_header { + u32 version; + u32 mode; +}; + struct fw_chunk { u32 address; u32 length; }; +#define IPW_FW_MAJOR_VERSION 2 +#define IPW_FW_MINOR_VERSION 4 + +#define IPW_FW_MINOR(x) ((x & 0xff) >> 8) +#define IPW_FW_MAJOR(x) (x & 0xff) + +#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION) + +#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \ +"." __stringify(IPW_FW_MINOR_VERSION) "-" + +#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0 +#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw" +#else +#define IPW_FW_NAME(x) "ipw2200_" x ".fw" +#endif + static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) { int rc = 0, i, addr; @@ -2874,8 +2890,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) mdelay(1); /* enable ucode store */ - ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0x0); - ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_CS); + ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0); + ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS); mdelay(1); /* write ucode */ @@ -3020,7 +3036,7 @@ static int ipw_stop_nic(struct ipw_priv *priv) rc = ipw_poll_bit(priv, IPW_RESET_REG, IPW_RESET_REG_MASTER_DISABLED, 500); if (rc < 0) { - IPW_ERROR("wait for reg master disabled failed after 500ms\n"); + IPW_ERROR("wait for reg master disabled failed\n"); return rc; } @@ -3102,47 +3118,33 @@ static int ipw_reset_nic(struct ipw_priv *priv) return rc; } - -struct ipw_fw { - u32 ver; - u32 boot_size; - u32 ucode_size; - u32 fw_size; - u8 data[0]; -}; - static int ipw_get_fw(struct ipw_priv *priv, - const struct firmware **raw, const char *name) + const struct firmware **fw, const char *name) { - struct ipw_fw *fw; + struct fw_header *header; int rc; /* ask firmware_class module to get the boot firmware off disk */ - rc = request_firmware(raw, name, &priv->pci_dev->dev); + rc = request_firmware(fw, name, &priv->pci_dev->dev); if (rc < 0) { - IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc); + IPW_ERROR("%s load failed: Reason %d\n", name, rc); return rc; } - if ((*raw)->size < sizeof(*fw)) { - IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size); - return -EINVAL; - } - - fw = (void *)(*raw)->data; - - if ((*raw)->size < sizeof(*fw) + - fw->boot_size + fw->ucode_size + fw->fw_size) { - IPW_ERROR("%s is too small or corrupt (%zd)\n", - name, (*raw)->size); + header = (struct fw_header *)(*fw)->data; + if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) { + IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n", + name, + IPW_FW_MAJOR(le32_to_cpu(header->version)), + IPW_FW_MAJOR_VERSION); return -EINVAL; } - IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n", + IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", name, - le32_to_cpu(fw->ver) >> 16, - le32_to_cpu(fw->ver) & 0xff, - (*raw)->size - sizeof(*fw)); + IPW_FW_MAJOR(le32_to_cpu(header->version)), + IPW_FW_MINOR(le32_to_cpu(header->version)), + (*fw)->size - sizeof(struct fw_header)); return 0; } @@ -3182,13 +3184,17 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv, #ifdef CONFIG_PM static int fw_loaded = 0; -static const struct firmware *raw = NULL; +static const struct firmware *bootfw = NULL; +static const struct firmware *firmware = NULL; +static const struct firmware *ucode = NULL; static void free_firmware(void) { if (fw_loaded) { - release_firmware(raw); - raw = NULL; + release_firmware(bootfw); + release_firmware(ucode); + release_firmware(firmware); + bootfw = ucode = firmware = NULL; fw_loaded = 0; } } @@ -3199,50 +3205,60 @@ static void free_firmware(void) static int ipw_load(struct ipw_priv *priv) { #ifndef CONFIG_PM - const struct firmware *raw = NULL; + const struct firmware *bootfw = NULL; + const struct firmware *firmware = NULL; + const struct firmware *ucode = NULL; #endif - struct ipw_fw *fw; - u8 *boot_img, *ucode_img, *fw_img; - u8 *name = NULL; int rc = 0, retries = 3; - switch (priv->ieee->iw_mode) { - case IW_MODE_ADHOC: - name = "ipw2200-ibss.fw"; - break; -#ifdef CONFIG_IPW2200_MONITOR - case IW_MODE_MONITOR: - name = "ipw2200-sniffer.fw"; - break; +#ifdef CONFIG_PM + if (!fw_loaded) { #endif - case IW_MODE_INFRA: - name = "ipw2200-bss.fw"; - break; - } + rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot")); + if (rc) + goto error; - if (!name) { - rc = -EINVAL; - goto error; - } + switch (priv->ieee->iw_mode) { + case IW_MODE_ADHOC: + rc = ipw_get_fw(priv, &ucode, + IPW_FW_NAME("ibss_ucode")); + if (rc) + goto error; -#ifdef CONFIG_PM - if (!fw_loaded) { + rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); + break; + +#ifdef CONFIG_IPW2200_MONITOR + case IW_MODE_MONITOR: + rc = ipw_get_fw(priv, &ucode, + IPW_FW_NAME("sniffer_ucode")); + if (rc) + goto error; + + rc = ipw_get_fw(priv, &firmware, + IPW_FW_NAME("sniffer")); + break; #endif - rc = ipw_get_fw(priv, &raw, name); - if (rc < 0) + case IW_MODE_INFRA: + rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode")); + if (rc) + goto error; + + rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss")); + break; + + default: + rc = -EINVAL; + } + + if (rc) goto error; + #ifdef CONFIG_PM + fw_loaded = 1; } #endif - fw = (void *)raw->data; - boot_img = &fw->data[0]; - ucode_img = &fw->data[fw->boot_size]; - fw_img = &fw->data[fw->boot_size + fw->ucode_size]; - - if (rc < 0) - goto error; - if (!priv->rxq) priv->rxq = ipw_rx_queue_alloc(priv); else @@ -3263,7 +3279,7 @@ static int ipw_load(struct ipw_priv *priv) ipw_stop_nic(priv); rc = ipw_reset_nic(priv); - if (rc < 0) { + if (rc) { IPW_ERROR("Unable to reset NIC\n"); goto error; } @@ -3272,7 +3288,8 @@ static int ipw_load(struct ipw_priv *priv) IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND); /* DMA the initial boot firmware into the device */ - rc = ipw_load_firmware(priv, boot_img, fw->boot_size); + rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), + bootfw->size - sizeof(struct fw_header)); if (rc < 0) { IPW_ERROR("Unable to load boot firmware: %d\n", rc); goto error; @@ -3281,7 +3298,7 @@ static int ipw_load(struct ipw_priv *priv) /* kick start the device */ ipw_start_nic(priv); - /* wait for the device to finish its initial startup sequence */ + /* wait for the device to finish it's initial startup sequence */ rc = ipw_poll_bit(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500); if (rc < 0) { @@ -3294,7 +3311,8 @@ static int ipw_load(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); /* DMA the ucode into the device */ - rc = ipw_load_ucode(priv, ucode_img, fw->ucode_size); + rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), + ucode->size - sizeof(struct fw_header)); if (rc < 0) { IPW_ERROR("Unable to load ucode: %d\n", rc); goto error; @@ -3304,19 +3322,18 @@ static int ipw_load(struct ipw_priv *priv) ipw_stop_nic(priv); /* DMA bss firmware into the device */ - rc = ipw_load_firmware(priv, fw_img, fw->fw_size); + rc = ipw_load_firmware(priv, firmware->data + + sizeof(struct fw_header), + firmware->size - sizeof(struct fw_header)); if (rc < 0) { IPW_ERROR("Unable to load firmware: %d\n", rc); goto error; } -#ifdef CONFIG_PM - fw_loaded = 1; -#endif ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0); rc = ipw_queue_reset(priv); - if (rc < 0) { + if (rc) { IPW_ERROR("Unable to initialize queues\n"); goto error; } @@ -3345,7 +3362,7 @@ static int ipw_load(struct ipw_priv *priv) rc = ipw_poll_bit(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500); if (rc < 0) { - IPW_ERROR("device failed to start within 500ms\n"); + IPW_ERROR("device failed to start after 500ms\n"); goto error; } IPW_DEBUG_INFO("device response after %dms\n", rc); @@ -3369,7 +3386,9 @@ static int ipw_load(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL); #ifndef CONFIG_PM - release_firmware(raw); + release_firmware(bootfw); + release_firmware(ucode); + release_firmware(firmware); #endif return 0; @@ -3379,11 +3398,15 @@ static int ipw_load(struct ipw_priv *priv) priv->rxq = NULL; } ipw_tx_queue_free(priv); - if (raw) - release_firmware(raw); + if (bootfw) + release_firmware(bootfw); + if (ucode) + release_firmware(ucode); + if (firmware) + release_firmware(firmware); #ifdef CONFIG_PM fw_loaded = 0; - raw = NULL; + bootfw = ucode = firmware = NULL; #endif return rc; @@ -3692,9 +3715,9 @@ static int ipw_disassociate(void *data) static void ipw_bg_disassociate(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_disassociate(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static void ipw_system_config(void *data) @@ -4054,9 +4077,9 @@ static void ipw_gather_stats(struct ipw_priv *priv) static void ipw_bg_gather_stats(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_gather_stats(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } /* Missed beacon behavior: @@ -4098,9 +4121,8 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, return; } - if (roaming && - (missed_count > priv->roaming_threshold && - missed_count <= priv->disassociate_threshold)) { + if (missed_count > priv->roaming_threshold && + missed_count <= priv->disassociate_threshold) { /* If we are not already roaming, set the ROAM * bit in the status and kick off a scan. * This can happen several times before we reach @@ -4128,6 +4150,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, } IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count); + } /** @@ -4504,9 +4527,10 @@ static void ipw_rx_notification(struct ipw_priv *priv, if (notif->size == sizeof(*x)) { IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, - "link deterioration: type %d, cnt %d\n", - x->silence_notification_type, - x->silence_count); + "link deterioration: '%s' " MAC_FMT + " \n", escape_essid(priv->essid, + priv->essid_len), + MAC_ARG(priv->bssid)); memcpy(&priv->last_link_deterioration, x, sizeof(*x)); } else { @@ -4887,13 +4911,13 @@ static void ipw_rx_queue_replenish(void *data) static void ipw_bg_rx_queue_replenish(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_rx_queue_replenish(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } /* Assumes that the skb field of the buffers in 'pool' is kept accurate. - * If an SKB has been detached, the POOL needs to have its SKB set to NULL + * If an SKB has been detached, the POOL needs to have it's SKB set to NULL * This free routine walks the list of POOL entries and if SKB is set to * non NULL it is unmapped and freed */ @@ -5233,11 +5257,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, if (priv->ieee->scan_age != 0 && time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " - "because of age: %ums.\n", + "because of age: %lums.\n", escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid), - jiffies_to_msecs(jiffies - - network->last_scanned)); + 1000 * (jiffies - network->last_scanned) / HZ); return 0; } @@ -5346,7 +5369,7 @@ static void ipw_merge_adhoc_network(void *data) return; } - mutex_lock(&priv->mutex); + down(&priv->sem); if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { IPW_DEBUG_MERGE("remove network %s\n", escape_essid(priv->essid, @@ -5356,7 +5379,7 @@ static void ipw_merge_adhoc_network(void *data) ipw_disassociate(priv); priv->assoc_network = match.network; - mutex_unlock(&priv->mutex); + up(&priv->sem); return; } } @@ -5444,12 +5467,11 @@ static int ipw_best_network(struct ipw_priv *priv, if (network->last_associate && time_after(network->last_associate + (HZ * 3UL), jiffies)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " - "because of storming (%ums since last " + "because of storming (%lus since last " "assoc attempt).\n", escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid), - jiffies_to_msecs(jiffies - - network->last_associate)); + (jiffies - network->last_associate) / HZ); return 0; } @@ -5457,11 +5479,10 @@ static int ipw_best_network(struct ipw_priv *priv, if (priv->ieee->scan_age != 0 && time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " - "because of age: %ums.\n", + "because of age: %lums.\n", escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid), - jiffies_to_msecs(jiffies - - network->last_scanned)); + 1000 * (jiffies - network->last_scanned) / HZ); return 0; } @@ -5489,6 +5510,15 @@ static int ipw_best_network(struct ipw_priv *priv, return 0; } + if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 || + network->rsn_ie_len > 0)) { + IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + "because of WPA capability mismatch.\n", + escape_essid(network->ssid, network->ssid_len), + MAC_ARG(network->bssid)); + return 0; + } + if ((priv->config & CFG_STATIC_BSSID) && memcmp(network->bssid, priv->bssid, ETH_ALEN)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " @@ -5509,7 +5539,7 @@ static int ipw_best_network(struct ipw_priv *priv, } /* Filter out invalid channel in current GEO */ - if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) { + if (!ipw_is_valid_channel(priv->ieee, network->channel)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " "because of invalid channel in current GEO\n", escape_essid(network->ssid, network->ssid_len), @@ -5554,7 +5584,7 @@ static int ipw_best_network(struct ipw_priv *priv, static void ipw_adhoc_create(struct ipw_priv *priv, struct ieee80211_network *network) { - const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); + const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); int i; /* @@ -5569,11 +5599,12 @@ static void ipw_adhoc_create(struct ipw_priv *priv, * FW fatal error. * */ - switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) { + switch (ipw_is_valid_channel(priv->ieee, priv->channel)) { case IEEE80211_52GHZ_BAND: network->mode = IEEE_A; - i = ieee80211_channel_to_index(priv->ieee, priv->channel); - BUG_ON(i == -1); + i = ipw_channel_to_index(priv->ieee, priv->channel); + if (i == -1) + BUG(); if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) { IPW_WARNING("Overriding invalid channel\n"); priv->channel = geo->a[0].channel; @@ -5585,8 +5616,9 @@ static void ipw_adhoc_create(struct ipw_priv *priv, network->mode = IEEE_G; else network->mode = IEEE_B; - i = ieee80211_channel_to_index(priv->ieee, priv->channel); - BUG_ON(i == -1); + i = ipw_channel_to_index(priv->ieee, priv->channel); + if (i == -1) + BUG(); if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) { IPW_WARNING("Overriding invalid channel\n"); priv->channel = geo->bg[0].channel; @@ -5639,44 +5671,54 @@ static void ipw_adhoc_create(struct ipw_priv *priv, static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index) { - struct ipw_tgi_tx_key key; + struct ipw_tgi_tx_key *key; + struct host_cmd cmd = { + .cmd = IPW_CMD_TGI_TX_KEY, + .len = sizeof(*key) + }; if (!(priv->ieee->sec.flags & (1 << index))) return; - key.key_id = index; - memcpy(key.key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH); - key.security_type = type; - key.station_index = 0; /* always 0 for BSS */ - key.flags = 0; + key = (struct ipw_tgi_tx_key *)&cmd.param; + key->key_id = index; + memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH); + key->security_type = type; + key->station_index = 0; /* always 0 for BSS */ + key->flags = 0; /* 0 for new key; previous value of counter (after fatal error) */ - key.tx_counter[0] = 0; - key.tx_counter[1] = 0; + key->tx_counter[0] = 0; + key->tx_counter[1] = 0; - ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key); + ipw_send_cmd(priv, &cmd); } static void ipw_send_wep_keys(struct ipw_priv *priv, int type) { - struct ipw_wep_key key; + struct ipw_wep_key *key; int i; + struct host_cmd cmd = { + .cmd = IPW_CMD_WEP_KEY, + .len = sizeof(*key) + }; - key.cmd_id = DINO_CMD_WEP_KEY; - key.seq_num = 0; + key = (struct ipw_wep_key *)&cmd.param; + key->cmd_id = DINO_CMD_WEP_KEY; + key->seq_num = 0; /* Note: AES keys cannot be set for multiple times. * Only set it at the first time. */ for (i = 0; i < 4; i++) { - key.key_index = i | type; + key->key_index = i | type; if (!(priv->ieee->sec.flags & (1 << i))) { - key.key_size = 0; + key->key_size = 0; continue; } - key.key_size = priv->ieee->sec.key_sizes[i]; - memcpy(key.key, priv->ieee->sec.keys[i], key.key_size); + key->key_size = priv->ieee->sec.key_sizes[i]; + memcpy(key->key, priv->ieee->sec.keys[i], key->key_size); - ipw_send_cmd_pdu(priv, IPW_CMD_WEP_KEY, sizeof(key), &key); + ipw_send_cmd(priv, &cmd); } } @@ -5780,9 +5822,9 @@ static void ipw_adhoc_check(void *data) static void ipw_bg_adhoc_check(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_adhoc_check(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } #ifdef CONFIG_IPW2200_DEBUG @@ -5908,7 +5950,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv, const struct ieee80211_geo *geo; int i; - geo = ieee80211_get_geo(priv->ieee); + geo = ipw_get_geo(priv->ieee); if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { int start = channel_index; @@ -5968,7 +6010,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv, channel_index++; scan->channels_list[channel_index] = channel; index = - ieee80211_channel_to_index(priv->ieee, channel); + ipw_channel_to_index(priv->ieee, channel); ipw_set_scan_type(scan, channel_index, geo->bg[index]. flags & @@ -6009,7 +6051,7 @@ static int ipw_request_scan(struct ipw_priv *priv) (priv->status & STATUS_EXIT_PENDING)) return 0; - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->status & STATUS_SCANNING) { IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n"); @@ -6050,7 +6092,7 @@ static int ipw_request_scan(struct ipw_priv *priv) u8 channel; u8 band = 0; - switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) { + switch (ipw_is_valid_channel(priv->ieee, priv->channel)) { case IEEE80211_52GHZ_BAND: band = (u8) (IPW_A_MODE << 6) | 1; channel = priv->channel; @@ -6117,16 +6159,16 @@ static int ipw_request_scan(struct ipw_priv *priv) queue_delayed_work(priv->workqueue, &priv->scan_check, IPW_SCAN_CHECK_WATCHDOG); done: - mutex_unlock(&priv->mutex); + up(&priv->sem); return err; } static void ipw_bg_abort_scan(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_abort_scan(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static int ipw_wpa_enable(struct ipw_priv *priv, int value) @@ -6151,9 +6193,6 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value) } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) { sec.auth_mode = WLAN_AUTH_OPEN; ieee->open_wep = 1; - } else if (value & IW_AUTH_ALG_LEAP) { - sec.auth_mode = WLAN_AUTH_LEAP; - ieee->open_wep = 1; } else return -EINVAL; @@ -6165,8 +6204,7 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value) return ret; } -static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, - int wpa_ie_len) +void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len) { /* make sure WPA is enabled */ ipw_wpa_enable(priv, 1); @@ -6177,10 +6215,15 @@ static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, static int ipw_set_rsn_capa(struct ipw_priv *priv, char *capabilities, int length) { + struct host_cmd cmd = { + .cmd = IPW_CMD_RSN_CAPABILITIES, + .len = length, + }; + IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n"); - return ipw_send_cmd_pdu(priv, IPW_CMD_RSN_CAPABILITIES, length, - capabilities); + memcpy(cmd.param, capabilities, length); + return ipw_send_cmd(priv, &cmd); } /* @@ -6201,7 +6244,7 @@ static int ipw_wx_set_genie(struct net_device *dev, (wrqu->data.length && extra == NULL)) return -EINVAL; - //mutex_lock(&priv->mutex); + //down(&priv->sem); //if (!ieee->wpa_enabled) { // err = -EOPNOTSUPP; @@ -6227,7 +6270,7 @@ static int ipw_wx_set_genie(struct net_device *dev, ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); out: - //mutex_unlock(&priv->mutex); + //up(&priv->sem); return err; } @@ -6240,7 +6283,7 @@ static int ipw_wx_get_genie(struct net_device *dev, struct ieee80211_device *ieee = priv->ieee; int err = 0; - //mutex_lock(&priv->mutex); + //down(&priv->sem); //if (!ieee->wpa_enabled) { // err = -EOPNOTSUPP; @@ -6261,7 +6304,7 @@ static int ipw_wx_get_genie(struct net_device *dev, memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); out: - //mutex_unlock(&priv->mutex); + //up(&priv->sem); return err; } @@ -6513,7 +6556,7 @@ static int ipw_wx_set_mlme(struct net_device *dev, * get the modulation type of the current network or * the card current mode */ -static u8 ipw_qos_current_mode(struct ipw_priv * priv) +u8 ipw_qos_current_mode(struct ipw_priv * priv) { u8 mode = 0; @@ -6713,7 +6756,8 @@ static int ipw_qos_association(struct ipw_priv *priv, switch (priv->ieee->iw_mode) { case IW_MODE_ADHOC: - BUG_ON(!(network->capability & WLAN_CAPABILITY_IBSS)); + if (!(network->capability & WLAN_CAPABILITY_IBSS)) + BUG(); qos_data = &ibss_data; break; @@ -6920,12 +6964,12 @@ static void ipw_bg_qos_activate(void *data) if (priv == NULL) return; - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->status & STATUS_ASSOCIATED) ipw_qos_activate(priv, &(priv->assoc_network->qos_data)); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static int ipw_handle_probe_response(struct net_device *dev, @@ -6966,15 +7010,25 @@ static int ipw_handle_assoc_response(struct net_device *dev, static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters *qos_param) { - return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS, - sizeof(*qos_param) * 3, qos_param); + struct host_cmd cmd = { + .cmd = IPW_CMD_QOS_PARAMETERS, + .len = (sizeof(struct ieee80211_qos_parameters) * 3) + }; + + memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3); + return ipw_send_cmd(priv, &cmd); } static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element *qos_param) { - return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param), - qos_param); + struct host_cmd cmd = { + .cmd = IPW_CMD_WME_INFO, + .len = sizeof(*qos_param) + }; + + memcpy(cmd.param, qos_param, sizeof(*qos_param)); + return ipw_send_cmd(priv, &cmd); } #endif /* CONFIG_IPW_QOS */ @@ -6998,21 +7052,19 @@ static int ipw_associate_network(struct ipw_priv *priv, memset(&priv->assoc_request, 0, sizeof(priv->assoc_request)); priv->assoc_request.channel = network->channel; - priv->assoc_request.auth_key = 0; - if ((priv->capability & CAP_PRIVACY_ON) && - (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) { + (priv->capability & CAP_SHARED_KEY)) { priv->assoc_request.auth_type = AUTH_SHARED_KEY; priv->assoc_request.auth_key = priv->ieee->sec.active_key; - if (priv->ieee->sec.level == SEC_LEVEL_1) + if ((priv->capability & CAP_PRIVACY_ON) && + (priv->ieee->sec.level == SEC_LEVEL_1) && + !(priv->ieee->host_encrypt || priv->ieee->host_decrypt)) ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP); - - } else if ((priv->capability & CAP_PRIVACY_ON) && - (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP)) - priv->assoc_request.auth_type = AUTH_LEAP; - else + } else { priv->assoc_request.auth_type = AUTH_OPEN; + priv->assoc_request.auth_key = 0; + } if (priv->ieee->wpa_ie_len) { priv->assoc_request.policy_support = 0x02; /* RSN active */ @@ -7226,9 +7278,9 @@ static void ipw_roam(void *data) static void ipw_bg_roam(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_roam(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static int ipw_associate(void *data) @@ -7323,9 +7375,9 @@ static int ipw_associate(void *data) static void ipw_bg_associate(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_associate(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv, @@ -7759,10 +7811,12 @@ static void ipw_rx(struct ipw_priv *priv) while (i != r) { rxb = priv->rxq->queue[i]; +#ifdef CONFIG_IPW2200_DEBUG if (unlikely(rxb == NULL)) { printk(KERN_CRIT "Queue not allocated!\n"); break; } +#endif priv->rxq->queue[i] = NULL; pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, @@ -7781,8 +7835,7 @@ static void ipw_rx(struct ipw_priv *priv) le16_to_cpu(pkt->u.frame.rssi_dbm) - IPW_RSSI_TO_DBM, .signal = - le16_to_cpu(pkt->u.frame.rssi_dbm) - - IPW_RSSI_TO_DBM + 0x100, + le16_to_cpu(pkt->u.frame.signal), .noise = le16_to_cpu(pkt->u.frame.noise), .rate = pkt->u.frame.rate, @@ -7846,8 +7899,7 @@ static void ipw_rx(struct ipw_priv *priv) le16_to_cpu(pkt->u.frame.length)); if (le16_to_cpu(pkt->u.frame.length) < - ieee80211_get_hdrlen(le16_to_cpu( - header->frame_ctl))) { + frame_hdr_len(header)) { IPW_DEBUG_DROP ("Received packet is too small. " "Dropping.\n"); @@ -7937,14 +7989,7 @@ static void ipw_rx(struct ipw_priv *priv) #define DEFAULT_SHORT_RETRY_LIMIT 7U #define DEFAULT_LONG_RETRY_LIMIT 4U -/** - * ipw_sw_reset - * @option: options to control different reset behaviour - * 0 = reset everything except the 'disable' module_param - * 1 = reset everything and print out driver info (for probe only) - * 2 = reset everything - */ -static int ipw_sw_reset(struct ipw_priv *priv, int option) +static int ipw_sw_reset(struct ipw_priv *priv, int init) { int band, modulation; int old_mode = priv->ieee->iw_mode; @@ -7971,7 +8016,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option) priv->essid_len = 0; memset(priv->essid, 0, IW_ESSID_MAX_SIZE); - if (disable && option) { + if (disable) { priv->status |= STATUS_RF_KILL_SW; IPW_DEBUG_INFO("Radio disabled.\n"); } @@ -8023,7 +8068,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option) if ((priv->pci_dev->device == 0x4223) || (priv->pci_dev->device == 0x4224)) { - if (option == 1) + if (init) printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2915ABG Network " "Connection\n"); @@ -8034,7 +8079,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option) priv->adapter = IPW_2915ABG; priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B; } else { - if (option == 1) + if (init) printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2200BG Network " "Connection\n"); @@ -8081,7 +8126,7 @@ static int ipw_wx_get_name(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->status & STATUS_RF_KILL_MASK) strcpy(wrqu->name, "radio off"); else if (!(priv->status & STATUS_ASSOCIATED)) @@ -8090,7 +8135,7 @@ static int ipw_wx_get_name(struct net_device *dev, snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", ipw_modes[priv->assoc_request.ieee_mode]); IPW_DEBUG_WX("Name: %s\n", wrqu->name); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8151,7 +8196,7 @@ static int ipw_wx_set_freq(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); + const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); struct iw_freq *fwrq = &wrqu->freq; int ret = 0, i; u8 channel, flags; @@ -8159,24 +8204,24 @@ static int ipw_wx_set_freq(struct net_device *dev, if (fwrq->m == 0) { IPW_DEBUG_WX("SET Freq/Channel -> any\n"); - mutex_lock(&priv->mutex); + down(&priv->sem); ret = ipw_set_channel(priv, 0); - mutex_unlock(&priv->mutex); + up(&priv->sem); return ret; } /* if setting by freq convert to channel */ if (fwrq->e == 1) { - channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m); + channel = ipw_freq_to_channel(priv->ieee, fwrq->m); if (channel == 0) return -EINVAL; } else channel = fwrq->m; - if (!(band = ieee80211_is_valid_channel(priv->ieee, channel))) + if (!(band = ipw_is_valid_channel(priv->ieee, channel))) return -EINVAL; if (priv->ieee->iw_mode == IW_MODE_ADHOC) { - i = ieee80211_channel_to_index(priv->ieee, channel); + i = ipw_channel_to_index(priv->ieee, channel); if (i == -1) return -EINVAL; @@ -8189,9 +8234,9 @@ static int ipw_wx_set_freq(struct net_device *dev, } IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); - mutex_lock(&priv->mutex); + down(&priv->sem); ret = ipw_set_channel(priv, channel); - mutex_unlock(&priv->mutex); + up(&priv->sem); return ret; } @@ -8205,14 +8250,14 @@ static int ipw_wx_get_freq(struct net_device *dev, /* If we are associated, trying to associate, or have a statically * configured CHANNEL then return that; otherwise return ANY */ - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->config & CFG_STATIC_CHANNEL || priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) wrqu->freq.m = priv->channel; else wrqu->freq.m = 0; - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); return 0; } @@ -8242,7 +8287,7 @@ static int ipw_wx_set_mode(struct net_device *dev, if (wrqu->mode == priv->ieee->iw_mode) return 0; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_sw_reset(priv, 0); @@ -8265,7 +8310,7 @@ static int ipw_wx_set_mode(struct net_device *dev, priv->ieee->iw_mode = wrqu->mode; queue_work(priv->workqueue, &priv->adapter_restart); - mutex_unlock(&priv->mutex); + up(&priv->sem); return err; } @@ -8274,10 +8319,10 @@ static int ipw_wx_get_mode(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); wrqu->mode = priv->ieee->iw_mode; IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8304,7 +8349,7 @@ static int ipw_wx_get_range(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); struct iw_range *range = (struct iw_range *)extra; - const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); + const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); int i = 0, j; wrqu->data.length = sizeof(*range); @@ -8316,7 +8361,7 @@ static int ipw_wx_get_range(struct net_device *dev, range->max_qual.qual = 100; /* TODO: Find real max RSSI and stick here */ range->max_qual.level = 0; - range->max_qual.noise = 0; + range->max_qual.noise = priv->ieee->worst_rssi + 0x100; range->max_qual.updated = 7; /* Updated all three */ range->avg_qual.qual = 70; @@ -8324,7 +8369,7 @@ static int ipw_wx_get_range(struct net_device *dev, range->avg_qual.level = 0; /* FIXME to real average level */ range->avg_qual.noise = 0; range->avg_qual.updated = 7; /* Updated all three */ - mutex_lock(&priv->mutex); + down(&priv->sem); range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES); for (i = 0; i < range->num_bitrates; i++) @@ -8342,7 +8387,7 @@ static int ipw_wx_get_range(struct net_device *dev, /* Set the Wireless Extension versions */ range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 18; + range->we_version_source = 16; i = 0; if (priv->ieee->mode & (IEEE_B | IEEE_G)) { @@ -8374,7 +8419,7 @@ static int ipw_wx_get_range(struct net_device *dev, range->num_channels = i; range->num_frequency = i; - mutex_unlock(&priv->mutex); + up(&priv->sem); /* Event capability (kernel + driver) */ range->event_capa[0] = (IW_EVENT_CAPA_K_0 | @@ -8382,9 +8427,6 @@ static int ipw_wx_get_range(struct net_device *dev, IW_EVENT_CAPA_MASK(SIOCGIWAP)); range->event_capa[1] = IW_EVENT_CAPA_K_1; - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - IPW_DEBUG_WX("GET Range\n"); return 0; } @@ -8404,7 +8446,7 @@ static int ipw_wx_set_wap(struct net_device *dev, if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) return -EINVAL; - mutex_lock(&priv->mutex); + down(&priv->sem); if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) { /* we disable mandatory BSSID association */ @@ -8413,14 +8455,14 @@ static int ipw_wx_set_wap(struct net_device *dev, IPW_DEBUG_ASSOC("Attempting to associate with new " "parameters.\n"); ipw_associate(priv); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } priv->config |= CFG_STATIC_BSSID; if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { IPW_DEBUG_WX("BSSID set to current BSSID.\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8434,7 +8476,7 @@ static int ipw_wx_set_wap(struct net_device *dev, if (!ipw_disassociate(priv)) ipw_associate(priv); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8445,7 +8487,7 @@ static int ipw_wx_get_wap(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); /* If we are associated, trying to associate, or have a statically * configured BSSID then return that; otherwise return ANY */ - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->config & CFG_STATIC_BSSID || priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { wrqu->ap_addr.sa_family = ARPHRD_ETHER; @@ -8455,7 +8497,7 @@ static int ipw_wx_get_wap(struct net_device *dev, IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", MAC_ARG(wrqu->ap_addr.sa_data)); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8466,7 +8508,7 @@ static int ipw_wx_set_essid(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); char *essid = ""; /* ANY */ int length = 0; - mutex_lock(&priv->mutex); + down(&priv->sem); if (wrqu->essid.flags && wrqu->essid.length) { length = wrqu->essid.length - 1; essid = extra; @@ -8481,7 +8523,7 @@ static int ipw_wx_set_essid(struct net_device *dev, priv->config &= ~CFG_STATIC_ESSID; ipw_associate(priv); } - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8491,7 +8533,7 @@ static int ipw_wx_set_essid(struct net_device *dev, if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { IPW_DEBUG_WX("ESSID set to current ESSID.\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8506,7 +8548,7 @@ static int ipw_wx_set_essid(struct net_device *dev, if (!ipw_disassociate(priv)) ipw_associate(priv); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8518,7 +8560,7 @@ static int ipw_wx_get_essid(struct net_device *dev, /* If we are associated, trying to associate, or have a statically * configured ESSID then return that; otherwise return ANY */ - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->config & CFG_STATIC_ESSID || priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { IPW_DEBUG_WX("Getting essid: '%s'\n", @@ -8531,7 +8573,7 @@ static int ipw_wx_get_essid(struct net_device *dev, wrqu->essid.length = 0; wrqu->essid.flags = 0; /* active */ } - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8544,12 +8586,12 @@ static int ipw_wx_set_nick(struct net_device *dev, IPW_DEBUG_WX("Setting nick to '%s'\n", extra); if (wrqu->data.length > IW_ESSID_MAX_SIZE) return -E2BIG; - mutex_lock(&priv->mutex); + down(&priv->sem); wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); memset(priv->nick, 0, sizeof(priv->nick)); memcpy(priv->nick, extra, wrqu->data.length); IPW_DEBUG_TRACE("<<\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8560,57 +8602,11 @@ static int ipw_wx_get_nick(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); IPW_DEBUG_WX("Getting nick\n"); - mutex_lock(&priv->mutex); + down(&priv->sem); wrqu->data.length = strlen(priv->nick) + 1; memcpy(extra, priv->nick, wrqu->data.length); wrqu->data.flags = 1; /* active */ - mutex_unlock(&priv->mutex); - return 0; -} - -static int ipw_wx_set_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct ipw_priv *priv = ieee80211_priv(dev); - int err = 0; - - IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value); - IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value); - mutex_lock(&priv->mutex); - - if (wrqu->sens.fixed == 0) - { - priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT; - priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT; - goto out; - } - if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) || - (wrqu->sens.value < IPW_MB_ROAMING_THRESHOLD_MIN)) { - err = -EINVAL; - goto out; - } - - priv->roaming_threshold = wrqu->sens.value; - priv->disassociate_threshold = 3*wrqu->sens.value; - out: - mutex_unlock(&priv->mutex); - return err; -} - -static int ipw_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); - wrqu->sens.fixed = 1; - wrqu->sens.value = priv->roaming_threshold; - mutex_unlock(&priv->mutex); - - IPW_DEBUG_WX("GET roaming threshold -> %s %d \n", - wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); - + up(&priv->sem); return 0; } @@ -8703,7 +8699,7 @@ static int ipw_wx_set_rate(struct net_device *dev, apply: IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n", mask, fixed ? "fixed" : "sub-rates"); - mutex_lock(&priv->mutex); + down(&priv->sem); if (mask == IEEE80211_DEFAULT_RATES_MASK) { priv->config &= ~CFG_FIXED_RATE; ipw_set_fixed_rate(priv, priv->ieee->mode); @@ -8712,7 +8708,7 @@ static int ipw_wx_set_rate(struct net_device *dev, if (priv->rates_mask == mask) { IPW_DEBUG_WX("Mask set to current mask.\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8723,7 +8719,7 @@ static int ipw_wx_set_rate(struct net_device *dev, if (!ipw_disassociate(priv)) ipw_associate(priv); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -8732,9 +8728,9 @@ static int ipw_wx_get_rate(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); wrqu->bitrate.value = priv->last_rate; - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); return 0; } @@ -8744,20 +8740,20 @@ static int ipw_wx_set_rts(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); if (wrqu->rts.disabled) priv->rts_threshold = DEFAULT_RTS_THRESHOLD; else { if (wrqu->rts.value < MIN_RTS_THRESHOLD || wrqu->rts.value > MAX_RTS_THRESHOLD) { - mutex_unlock(&priv->mutex); + up(&priv->sem); return -EINVAL; } priv->rts_threshold = wrqu->rts.value; } ipw_send_rts_threshold(priv, priv->rts_threshold); - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); return 0; } @@ -8767,11 +8763,11 @@ static int ipw_wx_get_rts(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); wrqu->rts.value = priv->rts_threshold; wrqu->rts.fixed = 0; /* no auto select */ wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); return 0; } @@ -8783,7 +8779,7 @@ static int ipw_wx_set_txpow(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); int err = 0; - mutex_lock(&priv->mutex); + down(&priv->sem); if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) { err = -EINPROGRESS; goto out; @@ -8806,7 +8802,7 @@ static int ipw_wx_set_txpow(struct net_device *dev, priv->tx_power = wrqu->power.value; err = ipw_set_tx_power(priv); out: - mutex_unlock(&priv->mutex); + up(&priv->sem); return err; } @@ -8815,12 +8811,12 @@ static int ipw_wx_get_txpow(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); wrqu->power.value = priv->tx_power; wrqu->power.fixed = 1; wrqu->power.flags = IW_TXPOW_DBM; wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("GET TX Power -> %s %d \n", wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); @@ -8833,13 +8829,13 @@ static int ipw_wx_set_frag(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); if (wrqu->frag.disabled) priv->ieee->fts = DEFAULT_FTS; else { if (wrqu->frag.value < MIN_FRAG_THRESHOLD || wrqu->frag.value > MAX_FRAG_THRESHOLD) { - mutex_unlock(&priv->mutex); + up(&priv->sem); return -EINVAL; } @@ -8847,7 +8843,7 @@ static int ipw_wx_set_frag(struct net_device *dev, } ipw_send_frag_threshold(priv, wrqu->frag.value); - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); return 0; } @@ -8857,11 +8853,11 @@ static int ipw_wx_get_frag(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); wrqu->frag.value = priv->ieee->fts; wrqu->frag.fixed = 0; /* no auto select */ wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); return 0; @@ -8882,7 +8878,7 @@ static int ipw_wx_set_retry(struct net_device *dev, if (wrqu->retry.value < 0 || wrqu->retry.value > 255) return -EINVAL; - mutex_lock(&priv->mutex); + down(&priv->sem); if (wrqu->retry.flags & IW_RETRY_MIN) priv->short_retry_limit = (u8) wrqu->retry.value; else if (wrqu->retry.flags & IW_RETRY_MAX) @@ -8894,7 +8890,7 @@ static int ipw_wx_set_retry(struct net_device *dev, ipw_send_retry_limit(priv, priv->short_retry_limit, priv->long_retry_limit); - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n", priv->short_retry_limit, priv->long_retry_limit); return 0; @@ -8906,11 +8902,11 @@ static int ipw_wx_get_retry(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); wrqu->retry.disabled = 0; if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { - mutex_unlock(&priv->mutex); + up(&priv->sem); return -EINVAL; } @@ -8924,7 +8920,7 @@ static int ipw_wx_get_retry(struct net_device *dev, wrqu->retry.flags = IW_RETRY_LIMIT; wrqu->retry.value = priv->short_retry_limit; } - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value); @@ -8941,7 +8937,7 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, (priv->status & STATUS_EXIT_PENDING)) return 0; - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->status & STATUS_RF_KILL_MASK) { IPW_DEBUG_HC("Aborting scan due to RF kill activation\n"); @@ -8993,7 +8989,7 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, priv->status |= STATUS_SCANNING; done: - mutex_unlock(&priv->mutex); + up(&priv->sem); return err; } @@ -9036,7 +9032,7 @@ static int ipw_wx_set_encode(struct net_device *dev, int ret; u32 cap = priv->capability; - mutex_lock(&priv->mutex); + down(&priv->sem); ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); /* In IBSS mode, we need to notify the firmware to update @@ -9046,7 +9042,7 @@ static int ipw_wx_set_encode(struct net_device *dev, priv->status & STATUS_ASSOCIATED) ipw_disassociate(priv); - mutex_unlock(&priv->mutex); + up(&priv->sem); return ret; } @@ -9064,17 +9060,17 @@ static int ipw_wx_set_power(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); int err; - mutex_lock(&priv->mutex); + down(&priv->sem); if (wrqu->power.disabled) { priv->power_mode = IPW_POWER_LEVEL(priv->power_mode); err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM); if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return err; } IPW_DEBUG_WX("SET Power Management Mode -> off\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9086,7 +9082,7 @@ static int ipw_wx_set_power(struct net_device *dev, default: /* Otherwise we don't support it */ IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", wrqu->power.flags); - mutex_unlock(&priv->mutex); + up(&priv->sem); return -EOPNOTSUPP; } @@ -9099,12 +9095,12 @@ static int ipw_wx_set_power(struct net_device *dev, err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return err; } IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9113,13 +9109,13 @@ static int ipw_wx_get_power(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); if (!(priv->power_mode & IPW_POWER_ENABLED)) wrqu->power.disabled = 1; else wrqu->power.disabled = 0; - mutex_unlock(&priv->mutex); + up(&priv->sem); IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); return 0; @@ -9132,7 +9128,7 @@ static int ipw_wx_set_powermode(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); int mode = *(int *)extra; int err; - mutex_lock(&priv->mutex); + down(&priv->sem); if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { mode = IPW_POWER_AC; priv->power_mode = mode; @@ -9145,11 +9141,11 @@ static int ipw_wx_set_powermode(struct net_device *dev, if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return err; } } - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9198,7 +9194,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode); return -EINVAL; } - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->adapter == IPW_2915ABG) { priv->ieee->abg_true = 1; if (mode & IEEE_A) { @@ -9210,7 +9206,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, if (mode & IEEE_A) { IPW_WARNING("Attempt to set 2200BG into " "802.11a mode\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return -EINVAL; } @@ -9247,7 +9243,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", mode & IEEE_A ? 'a' : '.', mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9256,7 +9252,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); switch (priv->ieee->mode) { case IEEE_A: strncpy(extra, "802.11a (1)", MAX_WX_STRING); @@ -9287,7 +9283,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); wrqu->data.length = strlen(extra) + 1; - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9298,7 +9294,7 @@ static int ipw_wx_set_preamble(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); int mode = *(int *)extra; - mutex_lock(&priv->mutex); + down(&priv->sem); /* Switching from SHORT -> LONG requires a disassociation */ if (mode == 1) { if (!(priv->config & CFG_PREAMBLE_LONG)) { @@ -9317,11 +9313,11 @@ static int ipw_wx_set_preamble(struct net_device *dev, priv->config &= ~CFG_PREAMBLE_LONG; goto done; } - mutex_unlock(&priv->mutex); + up(&priv->sem); return -EINVAL; done: - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9330,12 +9326,12 @@ static int ipw_wx_get_preamble(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); if (priv->config & CFG_PREAMBLE_LONG) snprintf(wrqu->name, IFNAMSIZ, "long (1)"); else snprintf(wrqu->name, IFNAMSIZ, "auto (0)"); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9347,7 +9343,7 @@ static int ipw_wx_set_monitor(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); int *parms = (int *)extra; int enable = (parms[0] > 0); - mutex_lock(&priv->mutex); + down(&priv->sem); IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]); if (enable) { if (priv->ieee->iw_mode != IW_MODE_MONITOR) { @@ -9362,13 +9358,13 @@ static int ipw_wx_set_monitor(struct net_device *dev, ipw_set_channel(priv, parms[1]); } else { if (priv->ieee->iw_mode != IW_MODE_MONITOR) { - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } priv->net_dev->type = ARPHRD_ETHER; queue_work(priv->workqueue, &priv->adapter_restart); } - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9398,9 +9394,9 @@ static int ipw_wx_sw_reset(struct net_device *dev, IPW_DEBUG_WX("SW_RESET\n"); - mutex_lock(&priv->mutex); + down(&priv->sem); - ret = ipw_sw_reset(priv, 2); + ret = ipw_sw_reset(priv, 0); if (!ret) { free_firmware(); ipw_adapter_restart(priv); @@ -9410,9 +9406,9 @@ static int ipw_wx_sw_reset(struct net_device *dev, * module parameter, so take appropriate action */ ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW); - mutex_unlock(&priv->mutex); + up(&priv->sem); ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL); - mutex_lock(&priv->mutex); + down(&priv->sem); if (!(priv->status & STATUS_RF_KILL_MASK)) { /* Configuration likely changed -- force [re]association */ @@ -9422,7 +9418,7 @@ static int ipw_wx_sw_reset(struct net_device *dev, ipw_associate(priv); } - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9435,8 +9431,6 @@ static iw_handler ipw_wx_handlers[] = { IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, - IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens, - IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens, IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, @@ -9582,7 +9576,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev) wstats->qual.level = average_value(&priv->average_rssi); wstats->qual.noise = average_value(&priv->average_noise); wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | - IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; + IW_QUAL_NOISE_UPDATED; wstats->miss.beacon = average_value(&priv->average_missed_beacons); wstats->discard.retries = priv->last_tx_failures; @@ -9600,7 +9594,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev) static void init_sys_config(struct ipw_sys_config *sys_config) { memset(sys_config, 0, sizeof(struct ipw_sys_config)); - sys_config->bt_coexistence = 0; + sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */ sys_config->answer_broadcast_ssid_probe = 0; sys_config->accept_all_data_frames = 0; sys_config->accept_non_directed_frames = 1; @@ -9608,13 +9602,12 @@ static void init_sys_config(struct ipw_sys_config *sys_config) sys_config->disable_unicast_decryption = 1; sys_config->exclude_multicast_unencrypted = 0; sys_config->disable_multicast_decryption = 1; - sys_config->antenna_diversity = CFG_SYS_ANTENNA_SLOW_DIV; + sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH; sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */ sys_config->dot11g_auto_detection = 0; sys_config->enable_cts_to_self = 0; sys_config->bt_coexist_collision_thr = 0; sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256 - sys_config->silence_threshold = 0x1e; } static int ipw_net_open(struct net_device *dev) @@ -9622,11 +9615,11 @@ static int ipw_net_open(struct net_device *dev) struct ipw_priv *priv = ieee80211_priv(dev); IPW_DEBUG_INFO("dev->open\n"); /* we should be verifying the device is ready to be opened */ - mutex_lock(&priv->mutex); + down(&priv->sem); if (!(priv->status & STATUS_RF_KILL_MASK) && (priv->status & STATUS_ASSOCIATED)) netif_start_queue(dev); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9662,6 +9655,11 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, u16 remaining_bytes; int fc; + /* If there isn't room in the queue, we return busy and let the + * network stack requeue the packet for us */ + if (ipw_queue_space(q) < q->high_mark) + return NETDEV_TX_BUSY; + switch (priv->ieee->iw_mode) { case IW_MODE_ADHOC: hdr_len = IEEE80211_3ADDR_LEN; @@ -9827,9 +9825,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); ipw_write32(priv, q->reg_w, q->first_empty); - if (ipw_queue_space(q) < q->high_mark) - netif_stop_queue(priv->net_dev); - return NETDEV_TX_OK; drop: @@ -9903,13 +9898,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p) struct sockaddr *addr = p; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - mutex_lock(&priv->mutex); + down(&priv->sem); priv->config |= CFG_CUSTOM_MAC; memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", priv->net_dev->name, MAC_ARG(priv->mac_addr)); queue_work(priv->workqueue, &priv->adapter_restart); - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -9953,9 +9948,9 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev, if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE) return -EINVAL; - mutex_lock(&p->mutex); + down(&p->sem); memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len); - mutex_unlock(&p->mutex); + up(&p->sem); return 0; } @@ -9967,11 +9962,11 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev, if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE) return -EINVAL; - mutex_lock(&p->mutex); + down(&p->sem); memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++) ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]); - mutex_unlock(&p->mutex); + up(&p->sem); return 0; } @@ -10066,12 +10061,12 @@ static void ipw_rf_kill(void *adapter) static void ipw_bg_rf_kill(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_rf_kill(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } -static void ipw_link_up(struct ipw_priv *priv) +void ipw_link_up(struct ipw_priv *priv) { priv->last_seq_num = -1; priv->last_frag_num = -1; @@ -10101,12 +10096,12 @@ static void ipw_link_up(struct ipw_priv *priv) static void ipw_bg_link_up(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_link_up(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } -static void ipw_link_down(struct ipw_priv *priv) +void ipw_link_down(struct ipw_priv *priv) { ipw_led_link_down(priv); netif_carrier_off(priv->net_dev); @@ -10129,9 +10124,9 @@ static void ipw_link_down(struct ipw_priv *priv) static void ipw_bg_link_down(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_link_down(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static int ipw_setup_deferred_work(struct ipw_priv *priv) @@ -10304,20 +10299,6 @@ static int ipw_config(struct ipw_priv *priv) /* set basic system config settings */ init_sys_config(&priv->sys_config); - - /* Support Bluetooth if we have BT h/w on board, and user wants to. - * Does not support BT priority yet (don't abort or defer our Tx) */ - if (bt_coexist) { - unsigned char bt_caps = priv->eeprom[EEPROM_SKU_CAPABILITY]; - - if (bt_caps & EEPROM_SKU_CAP_BT_CHANNEL_SIG) - priv->sys_config.bt_coexistence - |= CFG_BT_COEXISTENCE_SIGNAL_CHNL; - if (bt_caps & EEPROM_SKU_CAP_BT_OOB) - priv->sys_config.bt_coexistence - |= CFG_BT_COEXISTENCE_OOB; - } - if (priv->ieee->iw_mode == IW_MODE_ADHOC) priv->sys_config.answer_broadcast_ssid_probe = 1; else @@ -10375,9 +10356,6 @@ static int ipw_config(struct ipw_priv *priv) * not intended for resale of the above mentioned Intel adapters has * not been tested. * - * Remember to update the table in README.ipw2200 when changing this - * table. - * */ static const struct ieee80211_geo ipw_geos[] = { { /* Restricted */ @@ -10625,6 +10603,96 @@ static const struct ieee80211_geo ipw_geos[] = { } }; +/* GEO code borrowed from ieee80211_geo.c */ +static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel) +{ + int i; + + /* Driver needs to initialize the geography map before using + * these helper functions */ + BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + + if (ieee->freq_band & IEEE80211_24GHZ_BAND) + for (i = 0; i < ieee->geo.bg_channels; i++) + /* NOTE: If G mode is currently supported but + * this is a B only channel, we don't see it + * as valid. */ + if ((ieee->geo.bg[i].channel == channel) && + (!(ieee->mode & IEEE_G) || + !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY))) + return IEEE80211_24GHZ_BAND; + + if (ieee->freq_band & IEEE80211_52GHZ_BAND) + for (i = 0; i < ieee->geo.a_channels; i++) + if (ieee->geo.a[i].channel == channel) + return IEEE80211_52GHZ_BAND; + + return 0; +} + +static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel) +{ + int i; + + /* Driver needs to initialize the geography map before using + * these helper functions */ + BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + + if (ieee->freq_band & IEEE80211_24GHZ_BAND) + for (i = 0; i < ieee->geo.bg_channels; i++) + if (ieee->geo.bg[i].channel == channel) + return i; + + if (ieee->freq_band & IEEE80211_52GHZ_BAND) + for (i = 0; i < ieee->geo.a_channels; i++) + if (ieee->geo.a[i].channel == channel) + return i; + + return -1; +} + +static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq) +{ + int i; + + /* Driver needs to initialize the geography map before using + * these helper functions */ + BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + + freq /= 100000; + + if (ieee->freq_band & IEEE80211_24GHZ_BAND) + for (i = 0; i < ieee->geo.bg_channels; i++) + if (ieee->geo.bg[i].freq == freq) + return ieee->geo.bg[i].channel; + + if (ieee->freq_band & IEEE80211_52GHZ_BAND) + for (i = 0; i < ieee->geo.a_channels; i++) + if (ieee->geo.a[i].freq == freq) + return ieee->geo.a[i].channel; + + return 0; +} + +static int ipw_set_geo(struct ieee80211_device *ieee, + const struct ieee80211_geo *geo) +{ + memcpy(ieee->geo.name, geo->name, 3); + ieee->geo.name[3] = '\0'; + ieee->geo.bg_channels = geo->bg_channels; + ieee->geo.a_channels = geo->a_channels; + memcpy(ieee->geo.bg, geo->bg, geo->bg_channels * + sizeof(struct ieee80211_channel)); + memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * + sizeof(struct ieee80211_channel)); + return 0; +} + +static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee) +{ + return &ieee->geo; +} + #define MAX_HW_RESTARTS 5 static int ipw_up(struct ipw_priv *priv) { @@ -10671,11 +10739,14 @@ static int ipw_up(struct ipw_priv *priv) priv->eeprom[EEPROM_COUNTRY_CODE + 2]); j = 0; } - if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) { + if (ipw_set_geo(priv->ieee, &ipw_geos[j])) { IPW_WARNING("Could not set geography."); return 0; } + IPW_DEBUG_INFO("Geography %03d [%s] detected.\n", + j, priv->ieee->geo.name); + if (priv->status & STATUS_RF_KILL_SW) { IPW_WARNING("Radio disabled by module parameter.\n"); return 0; @@ -10718,9 +10789,9 @@ static int ipw_up(struct ipw_priv *priv) static void ipw_bg_up(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_up(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } static void ipw_deinit(struct ipw_priv *priv) @@ -10789,23 +10860,23 @@ static void ipw_down(struct ipw_priv *priv) static void ipw_bg_down(void *data) { struct ipw_priv *priv = data; - mutex_lock(&priv->mutex); + down(&priv->sem); ipw_down(data); - mutex_unlock(&priv->mutex); + up(&priv->sem); } /* Called by register_netdev() */ static int ipw_net_init(struct net_device *dev) { struct ipw_priv *priv = ieee80211_priv(dev); - mutex_lock(&priv->mutex); + down(&priv->sem); if (ipw_up(priv)) { - mutex_unlock(&priv->mutex); + up(&priv->sem); return -EIO; } - mutex_unlock(&priv->mutex); + up(&priv->sem); return 0; } @@ -10895,7 +10966,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); - mutex_init(&priv->mutex); + init_MUTEX(&priv->sem); if (pci_enable_device(pdev)) { err = -ENODEV; goto out_free_ieee80211; @@ -10953,7 +11024,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) SET_MODULE_OWNER(net_dev); SET_NETDEV_DEV(net_dev, &pdev->dev); - mutex_lock(&priv->mutex); + down(&priv->sem); priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; priv->ieee->set_security = shim__set_security; @@ -10986,22 +11057,16 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group); if (err) { IPW_ERROR("failed to create sysfs device attributes\n"); - mutex_unlock(&priv->mutex); + up(&priv->sem); goto out_release_irq; } - mutex_unlock(&priv->mutex); + up(&priv->sem); err = register_netdev(net_dev); if (err) { IPW_ERROR("failed to register network device\n"); goto out_remove_sysfs; } - - printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg " - "channels, %d 802.11a channels)\n", - priv->ieee->geo.name, priv->ieee->geo.bg_channels, - priv->ieee->geo.a_channels); - return 0; out_remove_sysfs: @@ -11033,13 +11098,13 @@ static void ipw_pci_remove(struct pci_dev *pdev) if (!priv) return; - mutex_lock(&priv->mutex); + down(&priv->sem); priv->status |= STATUS_EXIT_PENDING; ipw_down(priv); sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); - mutex_unlock(&priv->mutex); + up(&priv->sem); unregister_netdev(priv->net_dev); @@ -11192,10 +11257,8 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); module_param(led, int, 0444); MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); -#ifdef CONFIG_IPW2200_DEBUG module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); -#endif module_param(channel, int, 0444); MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); @@ -11225,18 +11288,12 @@ module_param(mode, int, 0444); MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)"); #endif -module_param(bt_coexist, int, 0444); -MODULE_PARM_DESC(bt_coexist, "enable bluetooth coexistence (default off)"); - module_param(hwcrypto, int, 0444); -MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default off)"); +MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)"); module_param(cmdlog, int, 0444); MODULE_PARM_DESC(cmdlog, "allocate a ring buffer for logging firmware commands"); -module_param(roaming, int, 0444); -MODULE_PARM_DESC(roaming, "enable roaming support (default on)"); - module_exit(ipw_exit); module_init(ipw_init); diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index 4b9804900..e65620a4d 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -47,7 +46,6 @@ #include #include #include -#include #include #include @@ -246,10 +244,8 @@ enum connection_manager_assoc_states { #define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31 #define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1 -#define IPW_MB_ROAMING_THRESHOLD_MIN 1 +#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 24 #define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8 -#define IPW_MB_ROAMING_THRESHOLD_MAX 30 -#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 3*IPW_MB_ROAMING_THRESHOLD_DEFAULT #define IPW_REAL_RATE_RX_PACKET_THRESHOLD 300 #define MACADRR_BYTE_LEN 6 @@ -620,16 +616,13 @@ struct notif_tgi_tx_key { u8 reserved; } __attribute__ ((packed)); -#define SILENCE_OVER_THRESH (1) -#define SILENCE_UNDER_THRESH (2) - struct notif_link_deterioration { struct ipw_cmd_stats stats; u8 rate; u8 modulation; struct rate_histogram histogram; - u8 silence_notification_type; /* SILENCE_OVER/UNDER_THRESH */ - u16 silence_count; + u8 reserved1; + u16 reserved2; } __attribute__ ((packed)); struct notif_association { @@ -787,7 +780,7 @@ struct ipw_sys_config { u8 enable_cts_to_self; u8 enable_multicast_filtering; u8 bt_coexist_collision_thr; - u8 silence_threshold; + u8 reserved2; u8 accept_all_mgmt_bcpr; u8 accept_all_mgtm_frames; u8 pass_noise_stats_to_host; @@ -859,7 +852,7 @@ struct ipw_scan_request_ext { u16 dwell_time[IPW_SCAN_TYPES]; } __attribute__ ((packed)); -static inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) +extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) { if (index % 2) return scan->scan_type[index / 2] & 0x0F; @@ -867,7 +860,7 @@ static inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) return (scan->scan_type[index / 2] & 0xF0) >> 4; } -static inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan, +extern inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan, u8 index, u8 scan_type) { if (index % 2) @@ -1127,7 +1120,7 @@ struct ipw_priv { struct ieee80211_device *ieee; spinlock_t lock; - struct mutex mutex; + struct semaphore sem; /* basic pci-network driver stuff */ struct pci_dev *pci_dev; @@ -1413,6 +1406,13 @@ do { if (ipw_debug_level & (level)) \ * Register bit definitions */ +/* Dino control registers bits */ + +#define DINO_ENABLE_SYSTEM 0x80 +#define DINO_ENABLE_CS 0x40 +#define DINO_RXFIFO_DATA 0x01 +#define DINO_CONTROL_REG 0x00200000 + #define IPW_INTA_RW 0x00000008 #define IPW_INTA_MASK_R 0x0000000C #define IPW_INDIRECT_ADDR 0x00000010 @@ -1459,11 +1459,6 @@ do { if (ipw_debug_level & (level)) \ #define IPW_DOMAIN_0_END 0x1000 #define CLX_MEM_BAR_SIZE 0x1000 -/* Dino/baseband control registers bits */ - -#define DINO_ENABLE_SYSTEM 0x80 /* 1 = baseband processor on, 0 = reset */ -#define DINO_ENABLE_CS 0x40 /* 1 = enable ucode load */ -#define DINO_RXFIFO_DATA 0x01 /* 1 = data available */ #define IPW_BASEBAND_CONTROL_STATUS 0X00200000 #define IPW_BASEBAND_TX_FIFO_WRITE 0X00200004 #define IPW_BASEBAND_RX_FIFO_READ 0X00200004 @@ -1572,18 +1567,13 @@ do { if (ipw_debug_level & (level)) \ #define EEPROM_BSS_CHANNELS_BG (GET_EEPROM_ADDR(0x2c,LSB)) /* 2 bytes */ #define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ -/* NIC type as found in the one byte EEPROM_NIC_TYPE offset */ +/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ #define EEPROM_NIC_TYPE_0 0 #define EEPROM_NIC_TYPE_1 1 #define EEPROM_NIC_TYPE_2 2 #define EEPROM_NIC_TYPE_3 3 #define EEPROM_NIC_TYPE_4 4 -/* Bluetooth Coexistence capabilities as found in EEPROM_SKU_CAPABILITY */ -#define EEPROM_SKU_CAP_BT_CHANNEL_SIG 0x01 /* we can tell BT our channel # */ -#define EEPROM_SKU_CAP_BT_PRIORITY 0x02 /* BT can take priority over us */ -#define EEPROM_SKU_CAP_BT_OOB 0x04 /* we can signal BT out-of-band */ - #define FW_MEM_REG_LOWER_BOUND 0x00300000 #define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) #define IPW_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04) @@ -1668,10 +1658,9 @@ enum { IPW_FW_ERROR_FATAL_ERROR }; -#define AUTH_OPEN 0 -#define AUTH_SHARED_KEY 1 -#define AUTH_LEAP 2 -#define AUTH_IGNORE 3 +#define AUTH_OPEN 0 +#define AUTH_SHARED_KEY 1 +#define AUTH_IGNORE 3 #define HC_ASSOCIATE 0 #define HC_REASSOCIATE 1 @@ -1871,7 +1860,7 @@ struct host_cmd { u8 cmd; u8 len; u16 reserved; - u32 *param; + u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; } __attribute__ ((packed)); struct ipw_cmd_log { @@ -1880,24 +1869,21 @@ struct ipw_cmd_log { struct host_cmd cmd; }; -/* SysConfig command parameters ... */ -/* bt_coexistence param */ -#define CFG_BT_COEXISTENCE_SIGNAL_CHNL 0x01 /* tell BT our chnl # */ -#define CFG_BT_COEXISTENCE_DEFER 0x02 /* defer our Tx if BT traffic */ -#define CFG_BT_COEXISTENCE_KILL 0x04 /* kill our Tx if BT traffic */ -#define CFG_BT_COEXISTENCE_WME_OVER_BT 0x08 /* multimedia extensions */ -#define CFG_BT_COEXISTENCE_OOB 0x10 /* signal BT via out-of-band */ - -/* clear-to-send to self param */ -#define CFG_CTS_TO_ITSELF_ENABLED_MIN 0x00 -#define CFG_CTS_TO_ITSELF_ENABLED_MAX 0x01 +#define CFG_BT_COEXISTENCE_MIN 0x00 +#define CFG_BT_COEXISTENCE_DEFER 0x02 +#define CFG_BT_COEXISTENCE_KILL 0x04 +#define CFG_BT_COEXISTENCE_WME_OVER_BT 0x08 +#define CFG_BT_COEXISTENCE_OOB 0x10 +#define CFG_BT_COEXISTENCE_MAX 0xFF +#define CFG_BT_COEXISTENCE_DEF 0x80 /* read Bt from EEPROM */ + +#define CFG_CTS_TO_ITSELF_ENABLED_MIN 0x0 +#define CFG_CTS_TO_ITSELF_ENABLED_MAX 0x1 #define CFG_CTS_TO_ITSELF_ENABLED_DEF CFG_CTS_TO_ITSELF_ENABLED_MIN -/* Antenna diversity param (h/w can select best antenna, based on signal) */ -#define CFG_SYS_ANTENNA_BOTH 0x00 /* NIC selects best antenna */ -#define CFG_SYS_ANTENNA_A 0x01 /* force antenna A */ -#define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ -#define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */ +#define CFG_SYS_ANTENNA_BOTH 0x000 +#define CFG_SYS_ANTENNA_A 0x001 +#define CFG_SYS_ANTENNA_B 0x003 /* * The definitions below were lifted off the ipw2100 driver, which only @@ -1913,4 +1899,27 @@ struct ipw_cmd_log { #define IPW_MAX_CONFIG_RETRIES 10 +static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr) +{ + u32 retval; + u16 fc; + + retval = sizeof(struct ieee80211_hdr_3addr); + fc = le16_to_cpu(hdr->frame_ctl); + + /* + * Function ToDS FromDS + * IBSS 0 0 + * To AP 1 0 + * From AP 0 1 + * WDS (bridge) 1 1 + * + * Only WDS frames use Address4 among them. --YZ + */ + if (!(fc & IEEE80211_FCTL_TODS) || !(fc & IEEE80211_FCTL_FROMDS)) + retval -= ETH_ALEN; + + return retval; +} + #endif /* __ipw2200_h__ */ diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 9343d9705..bf6271ee3 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -55,8 +55,10 @@ #include #include #include +#ifdef CONFIG_NET_RADIO #include #include +#endif #include #include @@ -190,8 +192,8 @@ module_param(mem_speed, int, 0); /*====================================================================*/ /* PCMCIA (Card Services) related functions */ -static void netwave_release(struct pcmcia_device *link); /* Card removal */ -static int netwave_pcmcia_config(struct pcmcia_device *arg); /* Runs after card +static void netwave_release(dev_link_t *link); /* Card removal */ +static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card insertion */ static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */ @@ -221,10 +223,10 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); /* - A struct pcmcia_device structure has fields for most things that are needed + A dev_link_t structure has fields for most things that are needed to keep track of a socket, but there will usually be some device specific information that also needs to be kept track of. The - 'priv' pointer in a struct pcmcia_device structure can be used to point to + 'priv' pointer in a dev_link_t structure can be used to point to a device-specific private data structure, like this. A driver needs to provide a dev_node_t structure for each device @@ -232,7 +234,7 @@ static void set_multicast_list(struct net_device *dev); example, ethernet cards, modems). In other cases, there may be many actual or logical devices (SCSI adapters, memory cards with multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device + in a linked list starting at the 'dev' field of a dev_link_t structure. We allocate them in the card's private data structure, because they generally can't be allocated dynamically. */ @@ -268,7 +270,7 @@ struct site_survey { }; typedef struct netwave_private { - struct pcmcia_device *p_dev; + dev_link_t link; spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ dev_node_t node; u_char __iomem *ramBase; @@ -376,19 +378,20 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev) * configure the card at this point -- we wait until we receive a * card insertion event. */ -static int netwave_probe(struct pcmcia_device *link) +static int netwave_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; struct net_device *dev; netwave_private *priv; DEBUG(0, "netwave_attach()\n"); - /* Initialize the struct pcmcia_device structure */ + /* Initialize the dev_link_t structure */ dev = alloc_etherdev(sizeof(netwave_private)); if (!dev) return -ENOMEM; priv = netdev_priv(dev); - priv->p_dev = link; + link = &priv->link; link->priv = dev; /* The io structure describes IO port mapping */ @@ -405,6 +408,7 @@ static int netwave_probe(struct pcmcia_device *link) /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -428,7 +432,13 @@ static int netwave_probe(struct pcmcia_device *link) dev->stop = &netwave_close; link->irq.Instance = dev; - return netwave_pcmcia_config( link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + netwave_pcmcia_config( link); + + return 0; } /* netwave_attach */ /* @@ -439,15 +449,17 @@ static int netwave_probe(struct pcmcia_device *link) * structures are freed. Otherwise, the structures will be freed * when the device is released. */ -static void netwave_detach(struct pcmcia_device *link) +static void netwave_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "netwave_detach(0x%p)\n", link); - netwave_release(link); + if (link->state & DEV_CONFIG) + netwave_release(link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); free_netdev(dev); @@ -733,7 +745,8 @@ static const struct iw_handler_def netwave_handler_def = #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int netwave_pcmcia_config(struct pcmcia_device *link) { +static void netwave_pcmcia_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; netwave_private *priv = netdev_priv(dev); tuple_t tuple; @@ -755,12 +768,15 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + /* * Try allocating IO ports. This tries a few fixed addresses. * If you want, you can also read the card's config table to @@ -768,11 +784,11 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { */ for (i = j = 0x0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); goto failed; } @@ -780,16 +796,16 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); /* * This actually configures the PCMCIA socket -- setting up * the I/O windows and the interrupt mapping. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); /* - * Allocate a 32K memory window. Note that the struct pcmcia_device + * Allocate a 32K memory window. Note that the dev_link_t * structure provides space for one window handle -- if your * device needs several windows, you'll need to keep track of * the handles in your private data structure, dev->priv. @@ -799,7 +815,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE; req.Base = 0; req.Size = 0x8000; req.AccessSpeed = mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); mem.CardOffset = 0x20000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); @@ -809,7 +825,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if (register_netdev(dev) != 0) { printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n"); @@ -817,7 +833,8 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { } strcpy(priv->node.dev_name, dev->name); - link->dev_node = &priv->node; + link->dev = &priv->node; + link->state &= ~DEV_CONFIG_PENDING; /* Reset card before reading physical address */ netwave_doreset(dev->base_addr, ramBase); @@ -837,13 +854,12 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n", get_uint16(ramBase + NETWAVE_EREG_ARW), get_uint16(ramBase + NETWAVE_EREG_ARW+2)); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: netwave_release(link); - return -ENODEV; } /* netwave_pcmcia_config */ /* @@ -853,35 +869,52 @@ failed: * device, and release the PCMCIA configuration. If the device is * still open, this will be postponed until it is closed. */ -static void netwave_release(struct pcmcia_device *link) +static void netwave_release(dev_link_t *link) { - struct net_device *dev = link->priv; - netwave_private *priv = netdev_priv(dev); + struct net_device *dev = link->priv; + netwave_private *priv = netdev_priv(dev); - DEBUG(0, "netwave_release(0x%p)\n", link); + DEBUG(0, "netwave_release(0x%p)\n", link); - pcmcia_disable_device(link); - if (link->win) - iounmap(priv->ramBase); + /* Don't bother checking to see if these succeed or not */ + if (link->win) { + iounmap(priv->ramBase); + pcmcia_release_window(link->win); + } + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; } -static int netwave_suspend(struct pcmcia_device *link) +static int netwave_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int netwave_resume(struct pcmcia_device *link) +static int netwave_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - netwave_reset(dev); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + netwave_reset(dev); + netif_device_attach(dev); + } } return 0; @@ -1088,7 +1121,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs u_char __iomem *ramBase; struct net_device *dev = (struct net_device *)dev_id; struct netwave_private *priv = netdev_priv(dev); - struct pcmcia_device *link = priv->p_dev; + dev_link_t *link = &priv->link; int i; if (!netif_device_present(dev)) @@ -1107,7 +1140,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs status = inb(iobase + NETWAVE_REG_ASR); - if (!pcmcia_dev_present(link)) { + if (!DEV_OK(link)) { DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x " "from removed or suspended card!\n", status); break; @@ -1342,11 +1375,11 @@ static int netwave_rx(struct net_device *dev) static int netwave_open(struct net_device *dev) { netwave_private *priv = netdev_priv(dev); - struct pcmcia_device *link = priv->p_dev; + dev_link_t *link = &priv->link; DEBUG(1, "netwave_open: starting.\n"); - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; link->open++; @@ -1359,7 +1392,7 @@ static int netwave_open(struct net_device *dev) { static int netwave_close(struct net_device *dev) { netwave_private *priv = netdev_priv(dev); - struct pcmcia_device *link = priv->p_dev; + dev_link_t *link = &priv->link; DEBUG(1, "netwave_close: finishing.\n"); @@ -1380,7 +1413,7 @@ static struct pcmcia_driver netwave_driver = { .drv = { .name = "netwave_cs", }, - .probe = netwave_probe, + .probe = netwave_attach, .remove = netwave_detach, .id_table = netwave_ids, .suspend = netwave_suspend, diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index a5fcfcde6..6fd0bf736 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -390,7 +390,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) } } else { struct { - __le16 qual, signal, noise, unused; + __le16 qual, signal, noise; } __attribute__ ((packed)) cq; err = HERMES_READ_RECORD(hw, USER_BAP, @@ -812,6 +812,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, if (datalen > IEEE80211_DATA_LEN + 12) { printk(KERN_DEBUG "%s: oversized monitor frame, " "data length = %d\n", dev->name, datalen); + err = -EIO; stats->rx_length_errors++; goto update_stats; } @@ -820,7 +821,8 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, if (!skb) { printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n", dev->name); - goto update_stats; + err = -ENOMEM; + goto drop; } /* Copy the 802.11 header to the skb */ @@ -1833,9 +1835,7 @@ static int __orinoco_program_rids(struct net_device *dev) /* Set promiscuity / multicast*/ priv->promiscuous = 0; priv->mc_count = 0; - - /* FIXME: what about netif_tx_lock */ - __orinoco_set_multicast_list(dev); + __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */ return 0; } @@ -3858,7 +3858,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev, unsigned long flags; /* Note : you may have realised that, as this is a SET operation, - * this is privileged and therefore a normal user can't + * this is priviledged and therefore a normal user can't * perform scanning. * This is not an error, while the device perform scanning, * traffic doesn't flow, so it's a perfect DoS... diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 434f7d7ad..ec6f2a488 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c @@ -49,7 +49,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket /* PCMCIA specific device information (goes in the card field of * struct orinoco_private */ struct orinoco_pccard { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; /* Used to handle hard reset */ @@ -63,8 +63,8 @@ struct orinoco_pccard { /* Function prototypes */ /********************************************************************/ -static int orinoco_cs_config(struct pcmcia_device *link); -static void orinoco_cs_release(struct pcmcia_device *link); +static void orinoco_cs_config(dev_link_t *link); +static void orinoco_cs_release(dev_link_t *link); static void orinoco_cs_detach(struct pcmcia_device *p_dev); /********************************************************************/ @@ -75,13 +75,13 @@ static int orinoco_cs_hard_reset(struct orinoco_private *priv) { struct orinoco_pccard *card = priv->card; - struct pcmcia_device *link = card->p_dev; + dev_link_t *link = &card->link; int err; /* We need atomic ops here, because we're not holding the lock */ set_bit(0, &card->hard_reset_in_progress); - err = pcmcia_reset_card(link, NULL); + err = pcmcia_reset_card(link->handle, NULL); if (err) return err; @@ -104,11 +104,12 @@ orinoco_cs_hard_reset(struct orinoco_private *priv) * configure the card at this point -- we wait until we receive a card * insertion event. */ static int -orinoco_cs_probe(struct pcmcia_device *link) +orinoco_cs_attach(struct pcmcia_device *p_dev) { struct net_device *dev; struct orinoco_private *priv; struct orinoco_pccard *card; + dev_link_t *link; dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset); if (! dev) @@ -117,7 +118,7 @@ orinoco_cs_probe(struct pcmcia_device *link) card = priv->card; /* Link both structures together */ - card->p_dev = link; + link = &card->link; link->priv = dev; /* Interrupt setup */ @@ -134,7 +135,16 @@ orinoco_cs_probe(struct pcmcia_device *link) link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY_AND_IO; - return orinoco_cs_config(link); + /* Register with Card Services */ + link->next = NULL; + + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + orinoco_cs_config(link); + + return 0; } /* orinoco_cs_attach */ /* @@ -143,14 +153,16 @@ orinoco_cs_probe(struct pcmcia_device *link) * are freed. Otherwise, the structures will be freed when the device * is released. */ -static void orinoco_cs_detach(struct pcmcia_device *link) +static void orinoco_cs_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - orinoco_cs_release(link); + if (link->state & DEV_CONFIG) + orinoco_cs_release(link); - DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node); - if (link->dev_node) { + DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); + if (link->dev) { DEBUG(0, PFX "About to unregister net device %p\n", dev); unregister_netdev(dev); @@ -168,10 +180,11 @@ static void orinoco_cs_detach(struct pcmcia_device *link) last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \ } while (0) -static int -orinoco_cs_config(struct pcmcia_device *link) +static void +orinoco_cs_config(dev_link_t *link) { struct net_device *dev = link->priv; + client_handle_t handle = link->handle; struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; @@ -183,7 +196,7 @@ orinoco_cs_config(struct pcmcia_device *link) cisparse_t parse; void __iomem *mem; - CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info)); + CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info)); /* * This reads the card's CONFIG tuple to find its @@ -194,15 +207,19 @@ orinoco_cs_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); + pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; /* * In this loop, we scan the CIS for configuration table @@ -219,13 +236,13 @@ orinoco_cs_config(struct pcmcia_device *link) * implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_cftable_entry_t dflt = { .index = 0 }; - if ( (pcmcia_get_tuple_data(link, &tuple) != 0) - || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) + if ( (pcmcia_get_tuple_data(handle, &tuple) != 0) + || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0)) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) @@ -257,10 +274,10 @@ orinoco_cs_config(struct pcmcia_device *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; /* Do we need to allocate an interrupt? */ @@ -290,7 +307,7 @@ orinoco_cs_config(struct pcmcia_device *link) } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; } @@ -300,8 +317,9 @@ orinoco_cs_config(struct pcmcia_device *link) break; next_entry: - pcmcia_disable_device(link); - last_ret = pcmcia_get_next_tuple(link, &tuple); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + last_ret = pcmcia_get_next_tuple(handle, &tuple); if (last_ret == CS_NO_MORE_ITEMS) { printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " @@ -315,7 +333,7 @@ orinoco_cs_config(struct pcmcia_device *link) * a handler to the interrupt, unless the 'Handler' member of * the irq structure is initialized. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); /* We initialize the hermes structure before completing PCMCIA * configuration just in case the interrupt handler gets @@ -332,7 +350,7 @@ orinoco_cs_config(struct pcmcia_device *link) * card and host interface into "Memory and IO" mode. */ CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link, &link->conf)); + pcmcia_request_configuration(link->handle, &link->conf)); /* Ok, we have the configuration, prepare to register the netdev */ dev->base_addr = link->io.BasePort1; @@ -340,7 +358,7 @@ orinoco_cs_config(struct pcmcia_device *link) SET_MODULE_OWNER(dev); card->node.major = card->node.minor = 0; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); /* Tell the stack we exist */ if (register_netdev(dev) != 0) { printk(KERN_ERR PFX "register_netdev() failed\n"); @@ -348,18 +366,20 @@ orinoco_cs_config(struct pcmcia_device *link) } /* At this point, the dev_node_t structure(s) needs to be - * initialized and arranged in a linked list at link->dev_node. */ + * initialized and arranged in a linked list at link->dev. */ strcpy(card->node.dev_name, dev->name); - link->dev_node = &card->node; /* link->dev_node being non-NULL is also + link->dev = &card->node; /* link->dev being non-NULL is also used to indicate that the net_device has been registered */ + link->state &= ~DEV_CONFIG_PENDING; /* Finally, report what we've done */ - printk(KERN_DEBUG "%s: index 0x%02x: ", - dev->name, link->conf.ConfigIndex); - if (link->conf.Vpp) - printk(", Vpp %d.%d", link->conf.Vpp / 10, - link->conf.Vpp % 10); + printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d", + dev->name, link->conf.ConfigIndex, + link->conf.Vcc / 10, link->conf.Vcc % 10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1 / 10, + link->conf.Vpp1 % 10); printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, @@ -369,14 +389,13 @@ orinoco_cs_config(struct pcmcia_device *link) link->io.BasePort2 + link->io.NumPorts2 - 1); printk("\n"); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: orinoco_cs_release(link); - return -ENODEV; } /* orinoco_cs_config */ /* @@ -385,7 +404,7 @@ orinoco_cs_config(struct pcmcia_device *link) * still open, this will be postponed until it is closed. */ static void -orinoco_cs_release(struct pcmcia_device *link) +orinoco_cs_release(dev_link_t *link) { struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); @@ -397,68 +416,88 @@ orinoco_cs_release(struct pcmcia_device *link) priv->hw_unavailable++; spin_unlock_irqrestore(&priv->lock, flags); - pcmcia_disable_device(link); + /* Don't bother checking to see if these succeed or not */ + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; if (priv->hw.iobase) ioport_unmap(priv->hw.iobase); } /* orinoco_cs_release */ -static int orinoco_cs_suspend(struct pcmcia_device *link) +static int orinoco_cs_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; int err = 0; unsigned long flags; - /* This is probably racy, but I can't think of - a better way, short of rewriting the PCMCIA - layer to not suck :-( */ - if (! test_bit(0, &card->hard_reset_in_progress)) { - spin_lock_irqsave(&priv->lock, flags); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + /* This is probably racy, but I can't think of + a better way, short of rewriting the PCMCIA + layer to not suck :-( */ + if (! test_bit(0, &card->hard_reset_in_progress)) { + spin_lock_irqsave(&priv->lock, flags); - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: Error %d downing interface\n", - dev->name, err); + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: Error %d downing interface\n", + dev->name, err); - netif_device_detach(dev); - priv->hw_unavailable++; + netif_device_detach(dev); + priv->hw_unavailable++; - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); + } + + pcmcia_release_configuration(link->handle); } return 0; } -static int orinoco_cs_resume(struct pcmcia_device *link) +static int orinoco_cs_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; int err = 0; unsigned long flags; - if (! test_bit(0, &card->hard_reset_in_progress)) { - err = orinoco_reinit_firmware(dev); - if (err) { - printk(KERN_ERR "%s: Error %d re-initializing firmware\n", - dev->name, err); - return -EIO; - } + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + /* FIXME: should we double check that this is + * the same card as we had before */ + pcmcia_request_configuration(link->handle, &link->conf); - spin_lock_irqsave(&priv->lock, flags); + if (! test_bit(0, &card->hard_reset_in_progress)) { + err = orinoco_reinit_firmware(dev); + if (err) { + printk(KERN_ERR "%s: Error %d re-initializing firmware\n", + dev->name, err); + return -EIO; + } - netif_device_attach(dev); - priv->hw_unavailable--; + spin_lock_irqsave(&priv->lock, flags); - if (priv->open && ! priv->hw_unavailable) { - err = __orinoco_up(dev); - if (err) - printk(KERN_ERR "%s: Error %d restarting card\n", - dev->name, err); - } + netif_device_attach(dev); + priv->hw_unavailable--; - spin_unlock_irqrestore(&priv->lock, flags); + if (priv->open && ! priv->hw_unavailable) { + err = __orinoco_up(dev); + if (err) + printk(KERN_ERR "%s: Error %d restarting card\n", + dev->name, err); + } + + spin_unlock_irqrestore(&priv->lock, flags); + } } return 0; @@ -565,7 +604,7 @@ static struct pcmcia_driver orinoco_driver = { .drv = { .name = DRIVER_NAME, }, - .probe = orinoco_cs_probe, + .probe = orinoco_cs_attach, .remove = orinoco_cs_detach, .id_table = orinoco_cs_ids, .suspend = orinoco_cs_suspend, diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 989599ad3..e5bb9f5ae 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -747,7 +747,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, if (essid->length) { dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ - /* if it is too big, trunk it */ + /* if it is to big, trunk it */ dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length); } else { dwrq->flags = 0; diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c index bfa0cc319..b41d666fe 100644 --- a/drivers/net/wireless/prism54/islpci_hotplug.c +++ b/drivers/net/wireless/prism54/islpci_hotplug.c @@ -22,7 +22,6 @@ #include #include #include /* For __init, __exit */ -#include #include "prismcompat.h" #include "islpci_dev.h" @@ -125,7 +124,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, 0xffffffff)) { printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME); goto do_pci_disable_device; } diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c index ebb238785..eea2f04c8 100644 --- a/drivers/net/wireless/prism54/oid_mgt.c +++ b/drivers/net/wireless/prism54/oid_mgt.c @@ -332,7 +332,7 @@ mgt_le_to_cpu(int type, void *data) case OID_TYPE_ATTACH:{ struct obj_attachment *attach = data; attach->id = le16_to_cpu(attach->id); - attach->size = le16_to_cpu(attach->size); + attach->size = le16_to_cpu(attach->size);; break; } case OID_TYPE_SSID: @@ -401,7 +401,7 @@ mgt_cpu_to_le(int type, void *data) case OID_TYPE_ATTACH:{ struct obj_attachment *attach = data; attach->id = cpu_to_le16(attach->id); - attach->size = cpu_to_le16(attach->size); + attach->size = cpu_to_le16(attach->size);; break; } case OID_TYPE_SSID: diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 879eb4276..7880d8c31 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -90,8 +90,8 @@ module_param(pc_debug, int, 0); #define DEBUG(n, args...) #endif /** Prototypes based on PCMCIA skeleton driver *******************************/ -static int ray_config(struct pcmcia_device *link); -static void ray_release(struct pcmcia_device *link); +static void ray_config(dev_link_t *link); +static void ray_release(dev_link_t *link); static void ray_detach(struct pcmcia_device *p_dev); /***** Prototypes indicated by device structure ******************************/ @@ -190,17 +190,20 @@ static int bc; static char *phy_addr = NULL; -/* A struct pcmcia_device structure has fields for most things that are needed +/* A linked list of "instances" of the ray device. Each actual + PCMCIA card corresponds to one device instance, and is described + by one dev_link_t structure (defined in ds.h). +*/ +static dev_link_t *dev_list = NULL; + +/* A dev_link_t structure has fields for most things that are needed to keep track of a socket, but there will usually be some device specific information that also needs to be kept track of. The - 'priv' pointer in a struct pcmcia_device structure can be used to point to + 'priv' pointer in a dev_link_t structure can be used to point to a device-specific private data structure, like this. */ static unsigned int ray_mem_speed = 500; -/* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */ -static struct pcmcia_device *this_device = NULL; - MODULE_AUTHOR("Corey Thomas "); MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver"); MODULE_LICENSE("GPL"); @@ -303,46 +306,56 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey priv; - local->finder = p_dev; + + memset(link, 0, sizeof(struct dev_link_t)); /* The io structure describes IO port mapping. None used here */ - p_dev->io.NumPorts1 = 0; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = 5; + link->io.NumPorts1 = 0; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = 5; /* Interrupt setup. For PCMCIA, driver takes what's given */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; - p_dev->irq.Handler = &ray_interrupt; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->irq.Handler = &ray_interrupt; /* General socket configuration */ - p_dev->conf.Attributes = CONF_ENABLE_IRQ; - p_dev->conf.IntType = INT_MEMORY_AND_IO; - p_dev->conf.ConfigIndex = 1; - p_dev->conf.Present = PRESENT_OPTION; - - p_dev->priv = dev; - p_dev->irq.Instance = dev; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; + + link->priv = dev; + link->irq.Instance = dev; - local->finder = p_dev; + local->finder = link; local->card_status = CARD_INSERTED; local->authentication_state = UNAUTHENTICATED; local->num_multi = 0; - DEBUG(2,"ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n", - p_dev,dev,local,&ray_interrupt); + DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n", + link,dev,local,&ray_interrupt); /* Raylink entries in the device structure */ dev->hard_start_xmit = &ray_dev_start_xmit; @@ -366,10 +379,16 @@ static int ray_probe(struct pcmcia_device *p_dev) init_timer(&local->timer); - this_device = p_dev; - return ray_config(p_dev); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + ray_config(link); + + return 0; fail_alloc_dev: + kfree(link); return -ENOMEM; } /* ray_attach */ /*============================================================================= @@ -378,25 +397,37 @@ fail_alloc_dev: structures are freed. Otherwise, the structures will be freed when the device is released. =============================================================================*/ -static void ray_detach(struct pcmcia_device *link) +static void ray_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + dev_link_t **linkp; struct net_device *dev; ray_dev_t *local; DEBUG(1, "ray_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; + if (*linkp == NULL) + return; - this_device = NULL; dev = link->priv; - ray_release(link); + if (link->state & DEV_CONFIG) { + ray_release(link); - local = (ray_dev_t *)dev->priv; - del_timer(&local->timer); + local = (ray_dev_t *)dev->priv; + del_timer(&local->timer); + } + /* Unlink device structure, free pieces */ + *linkp = link->next; if (link->priv) { - if (link->dev_node) unregister_netdev(dev); + if (link->dev) unregister_netdev(dev); free_netdev(dev); } + kfree(link); DEBUG(2,"ray_cs ray_detach ending\n"); } /* ray_detach */ /*============================================================================= @@ -407,8 +438,9 @@ static void ray_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) #define MAX_TUPLE_SIZE 128 -static int ray_config(struct pcmcia_device *link) +static void ray_config(dev_link_t *link) { + client_handle_t handle = link->handle; tuple_t tuple; cisparse_t parse; int last_fn = 0, last_ret = 0; @@ -423,45 +455,48 @@ static int ray_config(struct pcmcia_device *link) /* This reads the card's CONFIG tuple to find its configuration regs */ tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); tuple.TupleData = buf; tuple.TupleDataMax = MAX_TUPLE_SIZE; tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Determine card type and firmware version */ buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0; tuple.DesiredTuple = CISTPL_VERS_1; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); tuple.TupleData = buf; tuple.TupleDataMax = MAX_TUPLE_SIZE; tuple.TupleOffset = 2; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); for (i=0; istate |= DEV_CONFIG; + /* Now allocate an interrupt line. Note that this does not actually assign a handler to the interrupt. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); dev->irq = link->irq.AssignedIRQ; /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); /*** Set up 32k window for shared memory (transmit and control) ************/ req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; req.Base = 0; req.Size = 0x8000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win)); mem.CardOffset = 0x0000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); local->sram = ioremap(req.Base,req.Size); @@ -471,7 +506,7 @@ static int ray_config(struct pcmcia_device *link) req.Base = 0; req.Size = 0x4000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->rmem_handle)); mem.CardOffset = 0x8000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem)); local->rmem = ioremap(req.Base,req.Size); @@ -481,7 +516,7 @@ static int ray_config(struct pcmcia_device *link) req.Base = 0; req.Size = 0x1000; req.AccessSpeed = ray_mem_speed; - CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle)); + CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->amem_handle)); mem.CardOffset = 0x0000; mem.Page = 0; CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem)); local->amem = ioremap(req.Base,req.Size); @@ -491,32 +526,32 @@ static int ray_config(struct pcmcia_device *link) DEBUG(3,"ray_config amem=%p\n",local->amem); if (ray_init(dev) < 0) { ray_release(link); - return -ENODEV; + return; } - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); i = register_netdev(dev); if (i != 0) { printk("ray_config register_netdev() failed\n"); ray_release(link); - return i; + return; } strcpy(local->node.dev_name, dev->name); - link->dev_node = &local->node; + link->dev = &local->node; + link->state &= ~DEV_CONFIG_PENDING; printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ", dev->name, dev->irq); for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); ray_release(link); - return -ENODEV; } /* ray_config */ static inline struct ccs __iomem *ccs_base(ray_dev_t *dev) @@ -543,9 +578,9 @@ static int ray_init(struct net_device *dev) UCHAR *p; struct ccs __iomem *pccs; ray_dev_t *local = (ray_dev_t *)dev->priv; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; DEBUG(1, "ray_init(0x%p)\n", dev); - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(0,"ray_init - device not present\n"); return -1; } @@ -605,10 +640,10 @@ static int dl_startup_params(struct net_device *dev) int ccsindex; ray_dev_t *local = (ray_dev_t *)dev->priv; struct ccs __iomem *pccs; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; DEBUG(1,"dl_startup_params entered\n"); - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs dl_startup_params - device not present\n"); return -1; } @@ -712,9 +747,9 @@ static void verify_dl_startup(u_long data) ray_dev_t *local = (ray_dev_t *)data; struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs; UCHAR status; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs verify_dl_startup - device not present\n"); return; } @@ -752,8 +787,8 @@ static void start_net(u_long data) ray_dev_t *local = (ray_dev_t *)data; struct ccs __iomem *pccs; int ccsindex; - struct pcmcia_device *link = local->finder; - if (!(pcmcia_dev_present(link))) { + dev_link_t *link = local->finder; + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs start_net - device not present\n"); return; } @@ -779,9 +814,9 @@ static void join_net(u_long data) struct ccs __iomem *pccs; int ccsindex; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs join_net - device not present\n"); return; } @@ -805,7 +840,7 @@ static void join_net(u_long data) device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. =============================================================================*/ -static void ray_release(struct pcmcia_device *link) +static void ray_release(dev_link_t *link) { struct net_device *dev = link->priv; ray_dev_t *local = dev->priv; @@ -814,38 +849,56 @@ static void ray_release(struct pcmcia_device *link) DEBUG(1, "ray_release(0x%p)\n", link); del_timer(&local->timer); + link->state &= ~DEV_CONFIG; iounmap(local->sram); iounmap(local->rmem); iounmap(local->amem); /* Do bother checking to see if these succeed or not */ + i = pcmcia_release_window(link->win); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i); i = pcmcia_release_window(local->amem_handle); if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i); i = pcmcia_release_window(local->rmem_handle); if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i); - pcmcia_disable_device(link); + i = pcmcia_release_configuration(link->handle); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i); + i = pcmcia_release_irq(link->handle, &link->irq); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i); DEBUG(2,"ray_release ending\n"); } -static int ray_suspend(struct pcmcia_device *link) +static int ray_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + + pcmcia_release_configuration(link->handle); + } + return 0; } -static int ray_resume(struct pcmcia_device *link) +static int ray_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) { - ray_reset(dev); - netif_device_attach(dev); - } + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + ray_reset(dev); + netif_device_attach(dev); + } + } return 0; } @@ -857,10 +910,10 @@ int ray_dev_init(struct net_device *dev) int i; #endif /* RAY_IMMEDIATE_INIT */ ray_dev_t *local = dev->priv; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; DEBUG(1,"ray_dev_init(dev=%p)\n",dev); - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_dev_init - device not present\n"); return -1; } @@ -891,10 +944,10 @@ int ray_dev_init(struct net_device *dev) static int ray_dev_config(struct net_device *dev, struct ifmap *map) { ray_dev_t *local = dev->priv; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; /* Dummy routine to satisfy device structure */ DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map); - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_dev_config - device not present\n"); return -1; } @@ -905,10 +958,10 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map) static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) { ray_dev_t *local = dev->priv; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; short length = skb->len; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_dev_start_xmit - device not present\n"); return -1; } @@ -1517,7 +1570,7 @@ static int ray_commit(struct net_device *dev, static iw_stats * ray_get_wireless_stats(struct net_device * dev) { ray_dev_t * local = (ray_dev_t *) dev->priv; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; struct status __iomem *p = local->sram + STATUS_BASE; if(local == (ray_dev_t *) NULL) @@ -1535,7 +1588,7 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev) } #endif /* WIRELESS_SPY */ - if(pcmcia_dev_present(link)) { + if((link->state & DEV_PRESENT)) { local->wstats.qual.noise = readb(&p->rxnoise); local->wstats.qual.updated |= 4; } @@ -1604,14 +1657,18 @@ static const struct iw_handler_def ray_handler_def = /*===========================================================================*/ static int ray_open(struct net_device *dev) { + dev_link_t *link; ray_dev_t *local = (ray_dev_t *)dev->priv; - struct pcmcia_device *link; - link = local->finder; DEBUG(1, "ray_open('%s')\n", dev->name); - if (link->open == 0) - local->num_multi = 0; + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (!DEV_OK(link)) { + return -ENODEV; + } + + if (link->open == 0) local->num_multi = 0; link->open++; /* If the card is not started, time to start it ! - Jean II */ @@ -1638,12 +1695,15 @@ static int ray_open(struct net_device *dev) /*===========================================================================*/ static int ray_dev_close(struct net_device *dev) { - ray_dev_t *local = (ray_dev_t *)dev->priv; - struct pcmcia_device *link; - link = local->finder; + dev_link_t *link; DEBUG(1, "ray_dev_close('%s')\n", dev->name); + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (link == NULL) + return -ENODEV; + link->open--; netif_stop_queue(dev); @@ -1665,9 +1725,9 @@ static void ray_reset(struct net_device *dev) { static int interrupt_ecf(ray_dev_t *local, int ccs) { int i = 50; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs interrupt_ecf - device not present\n"); return -1; } @@ -1692,9 +1752,9 @@ static int get_free_tx_ccs(ray_dev_t *local) { int i; struct ccs __iomem *pccs = ccs_base(local); - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n"); return ECARDGONE; } @@ -1723,9 +1783,9 @@ static int get_free_ccs(ray_dev_t *local) { int i; struct ccs __iomem *pccs = ccs_base(local); - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs get_free_ccs - device not present\n"); return ECARDGONE; } @@ -1798,9 +1858,9 @@ static int parse_addr(char *in_str, UCHAR *out) static struct net_device_stats *ray_get_stats(struct net_device *dev) { ray_dev_t *local = (ray_dev_t *)dev->priv; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; struct status __iomem *p = local->sram + STATUS_BASE; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs net_device_stats - device not present\n"); return &local->stats; } @@ -1828,12 +1888,12 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev) static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len) { ray_dev_t *local = (ray_dev_t *)dev->priv; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; int ccsindex; int i; struct ccs __iomem *pccs; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_update_parm - device not present\n"); return; } @@ -1865,10 +1925,10 @@ static void ray_update_multi_list(struct net_device *dev, int all) struct ccs __iomem *pccs; int i = 0; ray_dev_t *local = (ray_dev_t *)dev->priv; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; void __iomem *p = local->sram + HOST_TO_ECF_BASE; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_update_multi_list - device not present\n"); return; } @@ -1945,7 +2005,7 @@ static void set_multicast_list(struct net_device *dev) static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = (struct net_device *)dev_id; - struct pcmcia_device *link; + dev_link_t *link; ray_dev_t *local; struct ccs __iomem *pccs; struct rcs __iomem *prcs; @@ -1960,8 +2020,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev); local = (ray_dev_t *)dev->priv; - link = (struct pcmcia_device *)local->finder; - if (!pcmcia_dev_present(link)) { + link = (dev_link_t *)local->finder; + if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) { DEBUG(2,"ray_cs interrupt from device not present or suspended.\n"); return IRQ_NONE; } @@ -2480,9 +2540,9 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs) /*===========================================================================*/ static void authenticate(ray_dev_t *local) { - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; DEBUG(0,"ray_cs Starting authentication.\n"); - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs authenticate - device not present\n"); return; } @@ -2546,10 +2606,10 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs, static void associate(ray_dev_t *local) { struct ccs __iomem *pccs; - struct pcmcia_device *link = local->finder; + dev_link_t *link = local->finder; struct net_device *dev = link->priv; int ccsindex; - if (!(pcmcia_dev_present(link))) { + if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_cs associate - device not present\n"); return; } @@ -2629,14 +2689,14 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len) * eg ifconfig */ int i; - struct pcmcia_device *link; + dev_link_t *link; struct net_device *dev; ray_dev_t *local; UCHAR *p; struct freq_hop_element *pfh; UCHAR c[33]; - link = this_device; + link = dev_list; if (!link) return 0; dev = (struct net_device *)link->priv; @@ -2838,7 +2898,7 @@ static struct pcmcia_driver ray_driver = { .drv = { .name = "ray_cs", }, - .probe = ray_probe, + .probe = ray_attach, .remove = ray_detach, .id_table = ray_ids, .suspend = ray_suspend, @@ -2880,6 +2940,7 @@ static void __exit exit_ray_cs(void) #endif pcmcia_unregister_driver(&ray_driver); + BUG_ON(dev_list != NULL); } /* exit_ray_cs */ module_init(init_ray_cs); diff --git a/drivers/net/wireless/ray_cs.h b/drivers/net/wireless/ray_cs.h index bd73ebf03..42660fe64 100644 --- a/drivers/net/wireless/ray_cs.h +++ b/drivers/net/wireless/ray_cs.h @@ -31,7 +31,7 @@ typedef struct ray_dev_t { void __iomem *sram; /* pointer to beginning of shared RAM */ void __iomem *amem; /* pointer to attribute mem window */ void __iomem *rmem; /* pointer to receive buffer window */ - struct pcmcia_device *finder; /* pointer back to struct pcmcia_device for card */ + dev_link_t *finder; /* pointer back to dev_link_t for card */ struct timer_list timer; long tx_ccs_lock; long ccs_lock; diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index 54fe4e4ea..fee4be1ce 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c @@ -63,7 +63,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket /* PCMCIA specific device information (goes in the card field of * struct orinoco_private */ struct orinoco_pccard { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; }; @@ -71,8 +71,8 @@ struct orinoco_pccard { /* Function prototypes */ /********************************************************************/ -static int spectrum_cs_config(struct pcmcia_device *link); -static void spectrum_cs_release(struct pcmcia_device *link); +static void spectrum_cs_config(dev_link_t *link); +static void spectrum_cs_release(dev_link_t *link); /********************************************************************/ /* Firmware downloader */ @@ -147,7 +147,7 @@ struct pdi { __le16 _len; /* length of ID and data, in words */ __le16 _id; /* record ID */ char data[0]; /* plug data */ -} __attribute__ ((packed)); +} __attribute__ ((packed));; /* Functions for access to little-endian data */ @@ -238,14 +238,14 @@ spectrum_aux_open(hermes_t *hw) * If IDLE is 1, stop the firmware, so that it can be safely rewritten. */ static int -spectrum_reset(struct pcmcia_device *link, int idle) +spectrum_reset(dev_link_t *link, int idle) { int last_ret, last_fn; conf_reg_t reg; u_int save_cor; /* Doing it if hardware is gone is guaranteed crash */ - if (!pcmcia_dev_present(link)) + if (!(link->state & DEV_CONFIG)) return -ENODEV; /* Save original COR value */ @@ -253,7 +253,7 @@ spectrum_reset(struct pcmcia_device *link, int idle) reg.Action = CS_READ; reg.Offset = CISREG_COR; CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link, ®)); + pcmcia_access_configuration_register(link->handle, ®)); save_cor = reg.Value; /* Soft-Reset card */ @@ -261,14 +261,14 @@ spectrum_reset(struct pcmcia_device *link, int idle) reg.Offset = CISREG_COR; reg.Value = (save_cor | COR_SOFT_RESET); CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link, ®)); + pcmcia_access_configuration_register(link->handle, ®)); udelay(1000); /* Read CCSR */ reg.Action = CS_READ; reg.Offset = CISREG_CCSR; CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link, ®)); + pcmcia_access_configuration_register(link->handle, ®)); /* * Start or stop the firmware. Memory width bit should be @@ -278,7 +278,7 @@ spectrum_reset(struct pcmcia_device *link, int idle) reg.Offset = CISREG_CCSR; reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16); CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link, ®)); + pcmcia_access_configuration_register(link->handle, ®)); udelay(1000); /* Restore original COR configuration index */ @@ -286,12 +286,12 @@ spectrum_reset(struct pcmcia_device *link, int idle) reg.Offset = CISREG_COR; reg.Value = (save_cor & ~COR_SOFT_RESET); CS_CHECK(AccessConfigurationRegister, - pcmcia_access_configuration_register(link, ®)); + pcmcia_access_configuration_register(link->handle, ®)); udelay(1000); return 0; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); return -ENODEV; } @@ -441,7 +441,7 @@ spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block) * care of the PDA - read it and then write it on top of the firmware. */ static int -spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link, +spectrum_dl_image(hermes_t *hw, dev_link_t *link, const unsigned char *image) { int ret; @@ -505,13 +505,14 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link, * reset on the card, to make sure it's in a sane state. */ static int -spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link) +spectrum_dl_firmware(hermes_t *hw, dev_link_t *link) { int ret; + client_handle_t handle = link->handle; const struct firmware *fw_entry; if (request_firmware(&fw_entry, primary_fw_name, - &handle_to_dev(link)) == 0) { + &handle_to_dev(handle)) == 0) { primsym = fw_entry->data; } else { printk(KERN_ERR PFX "Cannot find firmware: %s\n", @@ -520,7 +521,7 @@ spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link) } if (request_firmware(&fw_entry, secondary_fw_name, - &handle_to_dev(link)) == 0) { + &handle_to_dev(handle)) == 0) { secsym = fw_entry->data; } else { printk(KERN_ERR PFX "Cannot find firmware: %s\n", @@ -553,12 +554,12 @@ static int spectrum_cs_hard_reset(struct orinoco_private *priv) { struct orinoco_pccard *card = priv->card; - struct pcmcia_device *link = card->p_dev; + dev_link_t *link = &card->link; int err; if (!hermes_present(&priv->hw)) { /* The firmware needs to be reloaded */ - if (spectrum_dl_firmware(&priv->hw, link) != 0) { + if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) { printk(KERN_ERR PFX "Firmware download failed\n"); err = -ENODEV; } @@ -583,11 +584,12 @@ spectrum_cs_hard_reset(struct orinoco_private *priv) * configure the card at this point -- we wait until we receive a card * insertion event. */ static int -spectrum_cs_probe(struct pcmcia_device *link) +spectrum_cs_attach(struct pcmcia_device *p_dev) { struct net_device *dev; struct orinoco_private *priv; struct orinoco_pccard *card; + dev_link_t *link; dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset); if (! dev) @@ -596,7 +598,7 @@ spectrum_cs_probe(struct pcmcia_device *link) card = priv->card; /* Link both structures together */ - card->p_dev = link; + link = &card->link; link->priv = dev; /* Interrupt setup */ @@ -613,7 +615,13 @@ spectrum_cs_probe(struct pcmcia_device *link) link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY_AND_IO; - return spectrum_cs_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + spectrum_cs_config(link); + + return 0; } /* spectrum_cs_attach */ /* @@ -622,14 +630,16 @@ spectrum_cs_probe(struct pcmcia_device *link) * are freed. Otherwise, the structures will be freed when the device * is released. */ -static void spectrum_cs_detach(struct pcmcia_device *link) +static void spectrum_cs_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - spectrum_cs_release(link); + if (link->state & DEV_CONFIG) + spectrum_cs_release(link); - DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node); - if (link->dev_node) { + DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); + if (link->dev) { DEBUG(0, PFX "About to unregister net device %p\n", dev); unregister_netdev(dev); @@ -643,10 +653,11 @@ static void spectrum_cs_detach(struct pcmcia_device *link) * device available to the system. */ -static int -spectrum_cs_config(struct pcmcia_device *link) +static void +spectrum_cs_config(dev_link_t *link) { struct net_device *dev = link->priv; + client_handle_t handle = link->handle; struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; @@ -658,7 +669,7 @@ spectrum_cs_config(struct pcmcia_device *link) cisparse_t parse; void __iomem *mem; - CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info)); + CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info)); /* * This reads the card's CONFIG tuple to find its @@ -669,15 +680,19 @@ spectrum_cs_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); + pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; /* * In this loop, we scan the CIS for configuration table @@ -694,13 +709,13 @@ spectrum_cs_config(struct pcmcia_device *link) * implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_cftable_entry_t dflt = { .index = 0 }; - if ( (pcmcia_get_tuple_data(link, &tuple) != 0) - || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) + if ( (pcmcia_get_tuple_data(handle, &tuple) != 0) + || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0)) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) @@ -732,10 +747,10 @@ spectrum_cs_config(struct pcmcia_device *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; /* Do we need to allocate an interrupt? */ @@ -765,7 +780,7 @@ spectrum_cs_config(struct pcmcia_device *link) } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; } @@ -775,8 +790,9 @@ spectrum_cs_config(struct pcmcia_device *link) break; next_entry: - pcmcia_disable_device(link); - last_ret = pcmcia_get_next_tuple(link, &tuple); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + last_ret = pcmcia_get_next_tuple(handle, &tuple); if (last_ret == CS_NO_MORE_ITEMS) { printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " @@ -790,7 +806,7 @@ spectrum_cs_config(struct pcmcia_device *link) * a handler to the interrupt, unless the 'Handler' member of * the irq structure is initialized. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); /* We initialize the hermes structure before completing PCMCIA * configuration just in case the interrupt handler gets @@ -807,7 +823,7 @@ spectrum_cs_config(struct pcmcia_device *link) * card and host interface into "Memory and IO" mode. */ CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link, &link->conf)); + pcmcia_request_configuration(link->handle, &link->conf)); /* Ok, we have the configuration, prepare to register the netdev */ dev->base_addr = link->io.BasePort1; @@ -820,7 +836,7 @@ spectrum_cs_config(struct pcmcia_device *link) goto failed; } - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); /* Tell the stack we exist */ if (register_netdev(dev) != 0) { printk(KERN_ERR PFX "register_netdev() failed\n"); @@ -828,18 +844,20 @@ spectrum_cs_config(struct pcmcia_device *link) } /* At this point, the dev_node_t structure(s) needs to be - * initialized and arranged in a linked list at link->dev_node. */ + * initialized and arranged in a linked list at link->dev. */ strcpy(card->node.dev_name, dev->name); - link->dev_node = &card->node; /* link->dev_node being non-NULL is also + link->dev = &card->node; /* link->dev being non-NULL is also used to indicate that the net_device has been registered */ + link->state &= ~DEV_CONFIG_PENDING; /* Finally, report what we've done */ - printk(KERN_DEBUG "%s: index 0x%02x: ", - dev->name, link->conf.ConfigIndex); - if (link->conf.Vpp) - printk(", Vpp %d.%d", link->conf.Vpp / 10, - link->conf.Vpp % 10); + printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d", + dev->name, link->conf.ConfigIndex, + link->conf.Vcc / 10, link->conf.Vcc % 10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1 / 10, + link->conf.Vpp1 % 10); printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, @@ -849,14 +867,13 @@ spectrum_cs_config(struct pcmcia_device *link) link->io.BasePort2 + link->io.NumPorts2 - 1); printk("\n"); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: spectrum_cs_release(link); - return -ENODEV; } /* spectrum_cs_config */ /* @@ -865,7 +882,7 @@ spectrum_cs_config(struct pcmcia_device *link) * still open, this will be postponed until it is closed. */ static void -spectrum_cs_release(struct pcmcia_device *link) +spectrum_cs_release(dev_link_t *link) { struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); @@ -877,46 +894,64 @@ spectrum_cs_release(struct pcmcia_device *link) priv->hw_unavailable++; spin_unlock_irqrestore(&priv->lock, flags); - pcmcia_disable_device(link); + /* Don't bother checking to see if these succeed or not */ + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; if (priv->hw.iobase) ioport_unmap(priv->hw.iobase); } /* spectrum_cs_release */ static int -spectrum_cs_suspend(struct pcmcia_device *link) +spectrum_cs_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); unsigned long flags; int err = 0; + link->state |= DEV_SUSPEND; /* Mark the device as stopped, to block IO until later */ - spin_lock_irqsave(&priv->lock, flags); + if (link->state & DEV_CONFIG) { + spin_lock_irqsave(&priv->lock, flags); - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: Error %d downing interface\n", - dev->name, err); + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: Error %d downing interface\n", + dev->name, err); - netif_device_detach(dev); - priv->hw_unavailable++; + netif_device_detach(dev); + priv->hw_unavailable++; - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); + + pcmcia_release_configuration(link->handle); + } return 0; } static int -spectrum_cs_resume(struct pcmcia_device *link) +spectrum_cs_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); - netif_device_attach(dev); - priv->hw_unavailable--; - schedule_work(&priv->reset_work); - + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + /* FIXME: should we double check that this is + * the same card as we had before */ + pcmcia_request_configuration(link->handle, &link->conf); + netif_device_attach(dev); + priv->hw_unavailable--; + schedule_work(&priv->reset_work); + } return 0; } @@ -944,7 +979,7 @@ static struct pcmcia_driver orinoco_driver = { .drv = { .name = DRIVER_NAME, }, - .probe = spectrum_cs_probe, + .probe = spectrum_cs_attach, .remove = spectrum_cs_detach, .suspend = spectrum_cs_suspend, .resume = spectrum_cs_resume, diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 18a44580b..18baacfc5 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -112,7 +112,7 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE"; #include #include #include -#include + /************************************************************************/ /* Useful structures and definitions */ @@ -1569,7 +1569,7 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev) del_timer(&strip_info->idle_timer); - if (time_after(jiffies, strip_info->pps_timer + HZ)) { + if (jiffies - strip_info->pps_timer > HZ) { unsigned long t = jiffies - strip_info->pps_timer; unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t; unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t; diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c index dade4b903..ff192e962 100644 --- a/drivers/net/wireless/wavelan.c +++ b/drivers/net/wireless/wavelan.c @@ -4306,7 +4306,7 @@ out: * Insertion of the module * I'm now quite proud of the multi-device support. */ -int __init init_module(void) +int init_module(void) { int ret = -EIO; /* Return error if no cards found */ int i; diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h index 5cb0bc8bb..166e28b9a 100644 --- a/drivers/net/wireless/wavelan.p.h +++ b/drivers/net/wireless/wavelan.p.h @@ -98,7 +98,11 @@ * characteristics of the hardware. Applications such as mobile IP may * take advantage of it. * - * It might be a good idea as well to fetch the wireless tools to + * You will need to enable the CONFIG_NET_RADIO define in the kernel + * configuration to enable the wireless extensions (this is the one + * giving access to the radio network device choice). + * + * It might also be a good idea as well to fetch the wireless tools to * configure the device and play a bit. */ diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index f7724eb2f..98122f3a4 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -1005,7 +1005,7 @@ static inline void wv_82593_reconfig(struct net_device * dev) { net_local * lp = netdev_priv(dev); - struct pcmcia_device * link = lp->link; + dev_link_t * link = lp->link; unsigned long flags; /* Arm the flag, will be cleard in wv_82593_config() */ @@ -3744,16 +3744,16 @@ wv_pcmcia_reset(struct net_device * dev) { int i; conf_reg_t reg = { 0, CS_READ, CISREG_COR, 0 }; - struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link; + dev_link_t * link = ((net_local *)netdev_priv(dev))->link; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name); #endif - i = pcmcia_access_configuration_register(link, ®); + i = pcmcia_access_configuration_register(link->handle, ®); if(i != CS_SUCCESS) { - cs_error(link, AccessConfigurationRegister, i); + cs_error(link->handle, AccessConfigurationRegister, i); return FALSE; } @@ -3764,19 +3764,19 @@ wv_pcmcia_reset(struct net_device * dev) reg.Action = CS_WRITE; reg.Value = reg.Value | COR_SW_RESET; - i = pcmcia_access_configuration_register(link, ®); + i = pcmcia_access_configuration_register(link->handle, ®); if(i != CS_SUCCESS) { - cs_error(link, AccessConfigurationRegister, i); + cs_error(link->handle, AccessConfigurationRegister, i); return FALSE; } reg.Action = CS_WRITE; reg.Value = COR_LEVEL_IRQ | COR_CONFIG; - i = pcmcia_access_configuration_register(link, ®); + i = pcmcia_access_configuration_register(link->handle, ®); if(i != CS_SUCCESS) { - cs_error(link, AccessConfigurationRegister, i); + cs_error(link->handle, AccessConfigurationRegister, i); return FALSE; } @@ -3940,8 +3940,9 @@ wv_hw_reset(struct net_device * dev) * (called by wavelan_event()) */ static inline int -wv_pcmcia_config(struct pcmcia_device * link) +wv_pcmcia_config(dev_link_t * link) { + client_handle_t handle = link->handle; tuple_t tuple; cisparse_t parse; struct net_device * dev = (struct net_device *) link->priv; @@ -3964,16 +3965,16 @@ wv_pcmcia_config(struct pcmcia_device * link) { tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - i = pcmcia_get_first_tuple(link, &tuple); + i = pcmcia_get_first_tuple(handle, &tuple); if(i != CS_SUCCESS) break; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - i = pcmcia_get_tuple_data(link, &tuple); + i = pcmcia_get_tuple_data(handle, &tuple); if(i != CS_SUCCESS) break; - i = pcmcia_parse_tuple(link, &tuple, &parse); + i = pcmcia_parse_tuple(handle, &tuple, &parse); if(i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; @@ -3982,16 +3983,19 @@ wv_pcmcia_config(struct pcmcia_device * link) while(0); if(i != CS_SUCCESS) { - cs_error(link, ParseTuple, i); + cs_error(link->handle, ParseTuple, i); + link->state &= ~DEV_CONFIG_PENDING; return FALSE; } - + + /* Configure card */ + link->state |= DEV_CONFIG; do { - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if(i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); break; } @@ -3999,10 +4003,10 @@ wv_pcmcia_config(struct pcmcia_device * link) * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); if(i != CS_SUCCESS) { - cs_error(link, RequestIRQ, i); + cs_error(link->handle, RequestIRQ, i); break; } @@ -4011,15 +4015,15 @@ wv_pcmcia_config(struct pcmcia_device * link) * the I/O windows and the interrupt mapping. */ link->conf.ConfigIndex = 1; - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); if(i != CS_SUCCESS) { - cs_error(link, RequestConfiguration, i); + cs_error(link->handle, RequestConfiguration, i); break; } /* - * Allocate a small memory window. Note that the struct pcmcia_device + * Allocate a small memory window. Note that the dev_link_t * structure provides space for one window handle -- if your * device needs several windows, you'll need to keep track of * the handles in your private data structure, link->priv. @@ -4027,10 +4031,10 @@ wv_pcmcia_config(struct pcmcia_device * link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = mem_speed; - i = pcmcia_request_window(&link, &req, &link->win); + i = pcmcia_request_window(&link->handle, &req, &link->win); if(i != CS_SUCCESS) { - cs_error(link, RequestWindow, i); + cs_error(link->handle, RequestWindow, i); break; } @@ -4042,7 +4046,7 @@ wv_pcmcia_config(struct pcmcia_device * link) i = pcmcia_map_mem_page(link->win, &mem); if(i != CS_SUCCESS) { - cs_error(link, MapMemPage, i); + cs_error(link->handle, MapMemPage, i); break; } @@ -4056,7 +4060,7 @@ wv_pcmcia_config(struct pcmcia_device * link) lp->mem, dev->irq, (u_int) dev->base_addr); #endif - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); i = register_netdev(dev); if(i != 0) { @@ -4068,6 +4072,7 @@ wv_pcmcia_config(struct pcmcia_device * link) } while(0); /* Humm... Disguised goto !!! */ + link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if(i != 0) { @@ -4076,7 +4081,7 @@ wv_pcmcia_config(struct pcmcia_device * link) } strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name); - link->dev_node = &((net_local *) netdev_priv(dev))->node; + link->dev = &((net_local *) netdev_priv(dev))->node; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "<-wv_pcmcia_config()\n"); @@ -4091,20 +4096,26 @@ wv_pcmcia_config(struct pcmcia_device * link) * still open, this will be postponed until it is closed. */ static void -wv_pcmcia_release(struct pcmcia_device *link) +wv_pcmcia_release(dev_link_t *link) { - struct net_device * dev = (struct net_device *) link->priv; - net_local * lp = netdev_priv(dev); + struct net_device * dev = (struct net_device *) link->priv; + net_local * lp = netdev_priv(dev); #ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link); + printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link); #endif - iounmap(lp->mem); - pcmcia_disable_device(link); + /* Don't bother checking to see if these succeed or not */ + iounmap(lp->mem); + pcmcia_release_window(link->win); + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; #ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name); + printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name); #endif } @@ -4468,7 +4479,7 @@ static int wavelan_open(struct net_device * dev) { net_local * lp = netdev_priv(dev); - struct pcmcia_device * link = lp->link; + dev_link_t * link = lp->link; kio_addr_t base = dev->base_addr; #ifdef DEBUG_CALLBACK_TRACE @@ -4522,7 +4533,7 @@ wavelan_open(struct net_device * dev) static int wavelan_close(struct net_device * dev) { - struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link; + dev_link_t * link = ((net_local *)netdev_priv(dev))->link; kio_addr_t base = dev->base_addr; #ifdef DEBUG_CALLBACK_TRACE @@ -4576,36 +4587,45 @@ wavelan_close(struct net_device * dev) * card insertion event. */ static int -wavelan_probe(struct pcmcia_device *p_dev) +wavelan_attach(struct pcmcia_device *p_dev) { + dev_link_t * link; /* Info for cardmgr */ struct net_device * dev; /* Interface generic data */ net_local * lp; /* Interface specific data */ - int ret; #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "-> wavelan_attach()\n"); #endif + /* Initialize the dev_link_t structure */ + link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); + if (!link) return -ENOMEM; + /* The io structure describes IO port mapping */ - p_dev->io.NumPorts1 = 8; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = 3; + link->io.NumPorts1 = 8; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = 3; /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; - p_dev->irq.Handler = wavelan_interrupt; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->irq.Handler = wavelan_interrupt; /* General socket configuration */ - p_dev->conf.Attributes = CONF_ENABLE_IRQ; - p_dev->conf.IntType = INT_MEMORY_AND_IO; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + + /* Chain drivers */ + link->next = NULL; /* Allocate the generic data structure */ dev = alloc_etherdev(sizeof(net_local)); - if (!dev) + if (!dev) { + kfree(link); return -ENOMEM; - - p_dev->priv = p_dev->irq.Instance = dev; + } + link->priv = link->irq.Instance = dev; lp = netdev_priv(dev); @@ -4622,6 +4642,7 @@ wavelan_probe(struct pcmcia_device *p_dev) spin_lock_init(&lp->spinlock); /* back links */ + lp->link = link; lp->dev = dev; /* wavelan NET3 callbacks */ @@ -4647,18 +4668,15 @@ wavelan_probe(struct pcmcia_device *p_dev) /* Other specific data */ dev->mtu = WAVELAN_MTU; - ret = wv_pcmcia_config(p_dev); - if (ret) - return ret; + link->handle = p_dev; + p_dev->instance = link; - ret = wv_hw_config(dev); - if (ret) { + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + if(wv_pcmcia_config(link) && + wv_hw_config(dev)) + wv_init_info(dev); + else dev->irq = 0; - pcmcia_disable_device(p_dev); - return ret; - } - - wv_init_info(dev); #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "<- wavelan_attach()\n"); @@ -4675,14 +4693,25 @@ wavelan_probe(struct pcmcia_device *p_dev) * is released. */ static void -wavelan_detach(struct pcmcia_device *link) +wavelan_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link); #endif - /* Some others haven't done their job : give them another chance */ - wv_pcmcia_release(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->state & DEV_CONFIG) + { + /* Some others haven't done their job : give them another chance */ + wv_pcmcia_release(link); + } /* Free pieces */ if(link->priv) @@ -4691,21 +4720,23 @@ wavelan_detach(struct pcmcia_device *link) /* Remove ourselves from the kernel list of ethernet devices */ /* Warning : can't be called from interrupt, timer or wavelan_close() */ - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - link->dev_node = NULL; + link->dev = NULL; ((net_local *)netdev_priv(dev))->link = NULL; ((net_local *)netdev_priv(dev))->dev = NULL; free_netdev(dev); } + kfree(link); #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "<- wavelan_detach()\n"); #endif } -static int wavelan_suspend(struct pcmcia_device *link) +static int wavelan_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device * dev = (struct net_device *) link->priv; /* NB: wavelan_close will be called, but too late, so we are @@ -4717,22 +4748,36 @@ static int wavelan_suspend(struct pcmcia_device *link) /* Stop receiving new messages and wait end of transmission */ wv_ru_stop(dev); - if (link->open) - netif_device_detach(dev); - /* Power down the module */ hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT)); + /* The card is now suspended */ + link->state |= DEV_SUSPEND; + + if(link->state & DEV_CONFIG) + { + if(link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } + return 0; } -static int wavelan_resume(struct pcmcia_device *link) +static int wavelan_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device * dev = (struct net_device *) link->priv; - if (link->open) { - wv_hw_reset(dev); - netif_device_attach(dev); + link->state &= ~DEV_SUSPEND; + if(link->state & DEV_CONFIG) + { + pcmcia_request_configuration(link->handle, &link->conf); + if(link->open) /* If RESET -> True, If RESUME -> False ? */ + { + wv_hw_reset(dev); + netif_device_attach(dev); + } } return 0; @@ -4753,7 +4798,7 @@ static struct pcmcia_driver wavelan_driver = { .drv = { .name = "wavelan_cs", }, - .probe = wavelan_probe, + .probe = wavelan_attach, .remove = wavelan_detach, .id_table = wavelan_ids, .suspend = wavelan_suspend, diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h index c65fe7a39..f2d597568 100644 --- a/drivers/net/wireless/wavelan_cs.p.h +++ b/drivers/net/wireless/wavelan_cs.p.h @@ -99,7 +99,11 @@ * caracteristics of the hardware in a standard way and support for * applications for taking advantage of it (like Mobile IP). * - * It might be a good idea as well to fetch the wireless tools to + * You will need to enable the CONFIG_NET_RADIO define in the kernel + * configuration to enable the wireless extensions (this is the one + * giving access to the radio network device choice). + * + * It might also be a good idea as well to fetch the wireless tools to * configure the device and play a bit. */ @@ -436,8 +440,11 @@ #include #include #include + +#ifdef CONFIG_NET_RADIO #include /* Wireless extensions */ #include /* New driver API */ +#endif /* Pcmcia headers that we need */ #include @@ -602,7 +609,7 @@ struct net_local dev_node_t node; /* ???? What is this stuff ???? */ struct net_device * dev; /* Reverse link... */ spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ - struct pcmcia_device * link; /* pcmcia structure */ + dev_link_t * link; /* pcmcia structure */ en_stats stats; /* Ethernet interface statistics */ int nresets; /* Number of hw resets */ u_char configured; /* If it is configured */ @@ -733,9 +740,9 @@ static int static inline void wv_hw_reset(struct net_device *); /* Same, + start receiver unit */ static inline int - wv_pcmcia_config(struct pcmcia_device *); /* Configure the pcmcia interface */ + wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */ static void - wv_pcmcia_release(struct pcmcia_device *);/* Remove a device */ + wv_pcmcia_release(dev_link_t *);/* Remove a device */ /* ---------------------- INTERRUPT HANDLING ---------------------- */ static irqreturn_t wavelan_interrupt(int, /* Interrupt handler */ diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h index 65ceb088f..4303c50c2 100644 --- a/drivers/net/wireless/wl3501.h +++ b/drivers/net/wireless/wl3501.h @@ -611,6 +611,5 @@ struct wl3501_card { struct iw_spy_data spy_data; struct iw_public_data wireless_data; struct dev_node_t node; - struct pcmcia_device *p_dev; }; #endif diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index e52a650f6..48e10b0c7 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -103,8 +103,8 @@ module_param(pc_debug, int, 0); * release a socket, in response to card insertion and ejection events. They * are invoked from the wl24 event handler. */ -static int wl3501_config(struct pcmcia_device *link); -static void wl3501_release(struct pcmcia_device *link); +static void wl3501_config(dev_link_t *link); +static void wl3501_release(dev_link_t *link); /* * The dev_info variable is the "key" that is used to match up this @@ -226,6 +226,17 @@ static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to, iw_set_mgmt_info_element(from->id, to, from->data, from->len); } +/* + * A linked list of "instances" of the wl24 device. Each actual PCMCIA card + * corresponds to one device instance, and is described by one dev_link_t + * structure (defined in ds.h). + * + * You may not want to use a linked list for this -- for example, the memory + * card driver uses an array of dev_link_t pointers, where minor device numbers + * are used to derive the corresponding array index. + */ +static dev_link_t *wl3501_dev_list; + static inline void wl3501_switch_page(struct wl3501_card *this, u8 page) { wl3501_outb(page, this->base_addr + WL3501_NIC_BSS); @@ -1270,10 +1281,15 @@ static int wl3501_close(struct net_device *dev) struct wl3501_card *this = dev->priv; int rc = -ENODEV; unsigned long flags; - struct pcmcia_device *link; - link = this->p_dev; + dev_link_t *link; spin_lock_irqsave(&this->lock, flags); + /* Check if the device is in wl3501_dev_list */ + for (link = wl3501_dev_list; link; link = link->next) + if (link->priv == dev) + break; + if (!link) + goto out; link->open--; /* Stop wl3501_hard_start_xmit() from now on */ @@ -1285,6 +1301,7 @@ static int wl3501_close(struct net_device *dev) rc = 0; printk(KERN_INFO "%s: WL3501 closed\n", dev->name); +out: spin_unlock_irqrestore(&this->lock, flags); return rc; } @@ -1383,11 +1400,14 @@ static int wl3501_open(struct net_device *dev) int rc = -ENODEV; struct wl3501_card *this = dev->priv; unsigned long flags; - struct pcmcia_device *link; - link = this->p_dev; + dev_link_t *link; spin_lock_irqsave(&this->lock, flags); - if (!pcmcia_dev_present(link)) + /* Check if the device is in wl3501_dev_list */ + for (link = wl3501_dev_list; link; link = link->next) + if (link->priv == dev) + break; + if (!DEV_OK(link)) goto out; netif_device_attach(dev); link->open++; @@ -1477,23 +1497,38 @@ static struct ethtool_ops ops = { * 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 wl3501_detach(struct pcmcia_device *link) +static void wl3501_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + dev_link_t **linkp; struct net_device *dev = link->priv; + /* Locate device structure */ + for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) + break; + if (!*linkp) + goto out; + /* 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(). */ - while (link->open > 0) - wl3501_close(dev); + if (link->state & DEV_CONFIG) { + while (link->open > 0) + wl3501_close(dev); - netif_device_detach(dev); - wl3501_release(link); + netif_device_detach(dev); + wl3501_release(link); + } + + /* Unlink device structure, free pieces */ + *linkp = link->next; if (link->priv) free_netdev(link->priv); - + kfree(link); +out: return; } @@ -1918,26 +1953,33 @@ static const struct iw_handler_def wl3501_handler_def = { * 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 wl3501_probe(struct pcmcia_device *p_dev) +static int wl3501_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; struct net_device *dev; struct wl3501_card *this; + /* Initialize the dev_link_t structure */ + link = kzalloc(sizeof(*link), GFP_KERNEL); + if (!link) + return -ENOMEM; + /* The io structure describes IO port mapping */ - p_dev->io.NumPorts1 = 16; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = 5; + link->io.NumPorts1 = 16; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = 5; /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; - p_dev->irq.Handler = wl3501_interrupt; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->irq.Handler = wl3501_interrupt; /* General socket configuration */ - p_dev->conf.Attributes = CONF_ENABLE_IRQ; - p_dev->conf.IntType = INT_MEMORY_AND_IO; - p_dev->conf.ConfigIndex = 1; - p_dev->conf.Present = PRESENT_OPTION; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; dev = alloc_etherdev(sizeof(struct wl3501_card)); if (!dev) @@ -1950,15 +1992,22 @@ static int wl3501_probe(struct pcmcia_device *p_dev) dev->get_stats = wl3501_get_stats; this = dev->priv; this->wireless_data.spy_data = &this->spy_data; - this->p_dev = p_dev; dev->wireless_data = &this->wireless_data; dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def; SET_ETHTOOL_OPS(dev, &ops); netif_stop_queue(dev); - p_dev->priv = p_dev->irq.Instance = dev; + link->priv = link->irq.Instance = dev; + + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + wl3501_config(link); - return wl3501_config(p_dev); + return 0; out_link: + kfree(link); + link = NULL; return -ENOMEM; } @@ -1973,10 +2022,11 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) * received, to configure the PCMCIA socket, and to make the ethernet device * available to the system. */ -static int wl3501_config(struct pcmcia_device *link) +static void wl3501_config(dev_link_t *link) { tuple_t tuple; cisparse_t parse; + client_handle_t handle = link->handle; struct net_device *dev = link->priv; int i = 0, j, last_fn, last_ret; unsigned char bf[64]; @@ -1985,15 +2035,18 @@ static int wl3501_config(struct pcmcia_device *link) /* This reads the card's CONFIG tuple to find its config registers. */ tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); tuple.TupleData = bf; tuple.TupleDataMax = sizeof(bf); tuple.TupleOffset = 0; - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + /* Try allocating IO ports. This tries a few fixed addresses. If you * want, you can also read the card's config table to pick addresses -- * see the serial driver for an example. */ @@ -2003,28 +2056,28 @@ static int wl3501_config(struct pcmcia_device *link) * 0x200-0x2ff, and so on, because this seems safer */ link->io.BasePort1 = j; link->io.BasePort2 = link->io.BasePort1 + 0x10; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); goto failed; } /* Now allocate an interrupt line. Note that this does not actually * assign a handler to the interrupt. */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O * windows and the interrupt mapping. */ - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if (register_netdev(dev)) { printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n"); goto failed; @@ -2035,9 +2088,10 @@ static int wl3501_config(struct pcmcia_device *link) this = dev->priv; /* * At this point, the dev_node_t structure(s) should be initialized and - * arranged in a linked list at link->dev_node. + * arranged in a linked list at link->dev. */ - link->dev_node = &this->node; + link->dev = &this->node; + link->state &= ~DEV_CONFIG_PENDING; this->base_addr = dev->base_addr; @@ -2073,13 +2127,13 @@ static int wl3501_config(struct pcmcia_device *link) spin_lock_init(&this->lock); init_waitqueue_head(&this->wait); netif_start_queue(dev); - return 0; - + goto out; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: wl3501_release(link); - return -ENODEV; +out: + return; } /** @@ -2090,36 +2144,52 @@ failed: * and release the PCMCIA configuration. If the device is still open, this * will be postponed until it is closed. */ -static void wl3501_release(struct pcmcia_device *link) +static void wl3501_release(dev_link_t *link) { struct net_device *dev = link->priv; /* Unlink the device chain */ - if (link->dev_node) + if (link->dev) { unregister_netdev(dev); + link->dev = NULL; + } - pcmcia_disable_device(link); + /* Don't bother checking to see if these succeed or not */ + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } -static int wl3501_suspend(struct pcmcia_device *link) +static int wl3501_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; + link->state |= DEV_SUSPEND; + wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); - if (link->open) - netif_device_detach(dev); + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int wl3501_resume(struct pcmcia_device *link) +static int wl3501_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; wl3501_pwr_mgmt(dev->priv, WL3501_RESUME); - if (link->open) { - wl3501_reset(dev); - netif_device_attach(dev); + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + wl3501_reset(dev); + netif_device_attach(dev); + } } return 0; @@ -2137,7 +2207,7 @@ static struct pcmcia_driver wl3501_driver = { .drv = { .name = "wl3501_cs", }, - .probe = wl3501_probe, + .probe = wl3501_attach, .remove = wl3501_detach, .id_table = wl3501_ids, .suspend = wl3501_suspend, @@ -2151,7 +2221,9 @@ static int __init wl3501_init_module(void) static void __exit wl3501_exit_module(void) { + dprintk(0, ": unloading"); pcmcia_unregister_driver(&wl3501_driver); + BUG_ON(wl3501_dev_list != NULL); } module_init(wl3501_init_module); diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index fd0f43b7d..1c2506535 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -69,8 +69,8 @@ static int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */ static int dma_ctrl = 0x00CAC277; /* Override when loading module! */ static int fifo_cfg = 0x0028; #else -static const int dma_ctrl = 0x004A0263; /* Constrained by errata */ -static const int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */ +static int dma_ctrl = 0x004A0263; /* Constrained by errata */ +static int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */ #endif /* Set the copy breakpoint for the copy-only-tiny-frames scheme. @@ -266,7 +266,7 @@ struct pci_id_info { int drv_flags; /* Driver use, intended as capability flags. */ }; -static const struct pci_id_info pci_id_tbl[] = { +static struct pci_id_info pci_id_tbl[] = { {"Yellowfin G-NIC Gigabit Ethernet", { 0x07021000, 0xffffffff}, PCI_IOTYPE, YELLOWFIN_SIZE, FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug | DontUseEeprom}, @@ -1441,7 +1441,8 @@ static void __devexit yellowfin_remove_one (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct yellowfin_private *np; - BUG_ON(!dev); + if (!dev) + BUG(); np = netdev_priv(dev); pci_free_consistent(pdev, STATUS_TOTAL_SIZE, np->tx_status, diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c index 8037e5806..8ab6e1215 100644 --- a/drivers/net/zorro8390.c +++ b/drivers/net/zorro8390.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -152,7 +151,7 @@ static int __devinit zorro8390_init(struct net_device *dev, z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(KERN_WARNING " not found (no reset ack).\n"); return -ENODEV; } @@ -274,7 +273,7 @@ static void zorro8390_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((z_readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); break; @@ -401,7 +400,7 @@ static void zorro8390_block_output(struct net_device *dev, int count, dma_start = jiffies; while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_ERR "%s: timeout waiting for Tx RDC.\n", dev->name); zorro8390_reset_8390(dev); @@ -426,7 +425,7 @@ static void __devexit zorro8390_remove_one(struct zorro_dev *z) static int __init zorro8390_init_module(void) { - return zorro_register_driver(&zorro8390_driver); + return zorro_module_init(&zorro8390_driver); } static void __exit zorro8390_cleanup_module(void) diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index a647d3982..b2e8e49c8 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c @@ -6,10 +6,6 @@ * * @author John Levon * - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - * * This is the core of the buffer management. Each * CPU buffer is processed and entered into the * global event buffer. Such processing is necessary @@ -279,31 +275,15 @@ static void add_cpu_switch(int i) last_cookie = INVALID_COOKIE; } -static void add_cpu_mode_switch(unsigned int cpu_mode) +static void add_kernel_ctx_switch(unsigned int in_kernel) { add_event_entry(ESCAPE_CODE); - switch (cpu_mode) { - case CPU_MODE_USER: - add_event_entry(USER_ENTER_SWITCH_CODE); - break; - case CPU_MODE_KERNEL: - add_event_entry(KERNEL_ENTER_SWITCH_CODE); - break; - case CPU_MODE_XEN: - add_event_entry(XEN_ENTER_SWITCH_CODE); - break; - default: - break; - } -} - -static void add_domain_switch(unsigned long domain_id) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(DOMAIN_SWITCH_CODE); - add_event_entry(domain_id); + if (in_kernel) + add_event_entry(KERNEL_ENTER_SWITCH_CODE); + else + add_event_entry(KERNEL_EXIT_SWITCH_CODE); } - + static void add_user_ctx_switch(struct task_struct const * task, unsigned long cookie) { @@ -368,9 +348,9 @@ static int add_us_sample(struct mm_struct * mm, struct op_sample * s) * for later lookup from userspace. */ static int -add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode) +add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel) { - if (cpu_mode >= CPU_MODE_KERNEL) { + if (in_kernel) { add_sample_entry(s->eip, s->event); return 1; } else if (mm) { @@ -516,11 +496,10 @@ void sync_buffer(int cpu) struct mm_struct *mm = NULL; struct task_struct * new; unsigned long cookie = 0; - int cpu_mode = 1; + int in_kernel = 1; unsigned int i; sync_buffer_state state = sb_buffer_start; unsigned long available; - int domain_switch = 0; down(&buffer_sem); @@ -533,18 +512,16 @@ void sync_buffer(int cpu) for (i = 0; i < available; ++i) { struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos]; - if (is_code(s->eip) && !domain_switch) { - if (s->event <= CPU_MODE_XEN) { - /* xen/kernel/userspace switch */ - cpu_mode = s->event; + if (is_code(s->eip)) { + if (s->event <= CPU_IS_KERNEL) { + /* kernel/userspace switch */ + in_kernel = s->event; if (state == sb_buffer_start) state = sb_sample_start; - add_cpu_mode_switch(s->event); + add_kernel_ctx_switch(s->event); } else if (s->event == CPU_TRACE_BEGIN) { state = sb_bt_start; add_trace_begin(); - } else if (s->event == CPU_DOMAIN_SWITCH) { - domain_switch = 1; } else { struct mm_struct * oldmm = mm; @@ -558,16 +535,11 @@ void sync_buffer(int cpu) add_user_ctx_switch(new, cookie); } } else { - if (domain_switch) { - add_domain_switch(s->eip); - domain_switch = 0; - } else { - if (state >= sb_bt_start && - !add_sample(mm, s, cpu_mode)) { - if (state == sb_bt_start) { - state = sb_bt_ignore; - atomic_inc(&oprofile_stats.bt_lost_no_mapping); - } + if (state >= sb_bt_start && + !add_sample(mm, s, in_kernel)) { + if (state == sb_bt_start) { + state = sb_bt_ignore; + atomic_inc(&oprofile_stats.bt_lost_no_mapping); } } } diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index a59878e14..78193e4bb 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c @@ -6,10 +6,6 @@ * * @author John Levon * - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - * * Each CPU has a local buffer that stores PC value/event * pairs. We also log context switches when we notice them. * Eventually each CPU's buffer is processed into the global @@ -38,14 +34,13 @@ static void wq_sync_buffer(void *); #define DEFAULT_TIMER_EXPIRE (HZ / 10) static int work_enabled; -static int32_t current_domain = COORDINATOR_DOMAIN; - void free_cpu_buffers(void) { int i; - for_each_online_cpu(i) + for_each_online_cpu(i) { vfree(cpu_buffer[i].buffer); + } } int alloc_cpu_buffers(void) @@ -63,7 +58,7 @@ int alloc_cpu_buffers(void) goto fail; b->last_task = NULL; - b->last_cpu_mode = -1; + b->last_is_kernel = -1; b->tracing = 0; b->buffer_size = buffer_size; b->tail_pos = 0; @@ -119,7 +114,7 @@ void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf) * collected will populate the buffer with proper * values to initialize the buffer */ - cpu_buf->last_cpu_mode = -1; + cpu_buf->last_is_kernel = -1; cpu_buf->last_task = NULL; } @@ -169,13 +164,13 @@ add_code(struct oprofile_cpu_buffer * buffer, unsigned long value) * because of the head/tail separation of the writer and reader * of the CPU buffer. * - * cpu_mode is needed because on some architectures you cannot + * is_kernel is needed because on some architectures you cannot * tell if you are in kernel or user space simply by looking at - * pc. We tag this in the buffer by generating kernel/user (and xen) - * enter events whenever cpu_mode changes + * pc. We tag this in the buffer by generating kernel enter/exit + * events whenever is_kernel changes */ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, - int cpu_mode, unsigned long event) + int is_kernel, unsigned long event) { struct task_struct * task; @@ -186,20 +181,18 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, return 0; } - WARN_ON(cpu_mode > CPU_MODE_XEN); + is_kernel = !!is_kernel; task = current; /* notice a switch from user->kernel or vice versa */ - if (cpu_buf->last_cpu_mode != cpu_mode) { - cpu_buf->last_cpu_mode = cpu_mode; - add_code(cpu_buf, cpu_mode); + if (cpu_buf->last_is_kernel != is_kernel) { + cpu_buf->last_is_kernel = is_kernel; + add_code(cpu_buf, is_kernel); } - + /* notice a task switch */ - /* if not processing other domain samples */ - if ((cpu_buf->last_task != task) && - (current_domain == COORDINATOR_DOMAIN)) { + if (cpu_buf->last_task != task) { cpu_buf->last_task = task; add_code(cpu_buf, (unsigned long)task); } @@ -225,10 +218,11 @@ static void oprofile_end_trace(struct oprofile_cpu_buffer * cpu_buf) cpu_buf->tracing = 0; } -void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel) +void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) { struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()]; + unsigned long pc = profile_pc(regs); + int is_kernel = !user_mode(regs); if (!backtrace_depth) { log_sample(cpu_buf, pc, is_kernel, event); @@ -245,14 +239,6 @@ void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, oprofile_end_trace(cpu_buf); } -void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) -{ - int is_kernel = !user_mode(regs); - unsigned long pc = profile_pc(regs); - - oprofile_add_ext_sample(pc, regs, event, is_kernel); -} - void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event) { struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()]; @@ -283,25 +269,6 @@ void oprofile_add_trace(unsigned long pc) add_sample(cpu_buf, pc, 0); } -int oprofile_add_domain_switch(int32_t domain_id) -{ - struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()]; - - /* should have space for switching into and out of domain - (2 slots each) plus one sample and one cpu mode switch */ - if (((nr_available_slots(cpu_buf) < 6) && - (domain_id != COORDINATOR_DOMAIN)) || - (nr_available_slots(cpu_buf) < 2)) - return 0; - - add_code(cpu_buf, CPU_DOMAIN_SWITCH); - add_sample(cpu_buf, domain_id, 0); - - current_domain = domain_id; - - return 1; -} - /* * This serves to avoid cpu buffer overflow, and makes sure * the task mortuary progresses diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index cd94735be..09abb80e0 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h @@ -36,7 +36,7 @@ struct oprofile_cpu_buffer { volatile unsigned long tail_pos; unsigned long buffer_size; struct task_struct * last_task; - int last_cpu_mode; + int last_is_kernel; int tracing; struct op_sample * buffer; unsigned long sample_received; @@ -51,10 +51,7 @@ extern struct oprofile_cpu_buffer cpu_buffer[]; void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf); /* transient events for the CPU buffer -> event buffer */ -#define CPU_MODE_USER 0 -#define CPU_MODE_KERNEL 1 -#define CPU_MODE_XEN 2 -#define CPU_TRACE_BEGIN 3 -#define CPU_DOMAIN_SWITCH 4 +#define CPU_IS_KERNEL 1 +#define CPU_TRACE_BEGIN 2 #endif /* OPROFILE_CPU_BUFFER_H */ diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h index 0c33ee71e..018023630 100644 --- a/drivers/oprofile/event_buffer.h +++ b/drivers/oprofile/event_buffer.h @@ -29,20 +29,15 @@ void wake_up_buffer_waiter(void); #define CPU_SWITCH_CODE 2 #define COOKIE_SWITCH_CODE 3 #define KERNEL_ENTER_SWITCH_CODE 4 -#define USER_ENTER_SWITCH_CODE 5 +#define KERNEL_EXIT_SWITCH_CODE 5 #define MODULE_LOADED_CODE 6 #define CTX_TGID_CODE 7 #define TRACE_BEGIN_CODE 8 #define TRACE_END_CODE 9 -#define XEN_ENTER_SWITCH_CODE 10 -#define DOMAIN_SWITCH_CODE 11 #define INVALID_COOKIE ~0UL #define NO_COOKIE 0UL -/* Constant used to refer to coordinator domain (Xen) */ -#define COORDINATOR_DOMAIN -1 - /* add data to the event buffer */ void add_event_entry(unsigned long data); diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index 76bac8dfe..b3f1cd6a2 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c @@ -5,10 +5,6 @@ * @remark Read the file COPYING * * @author John Levon - * - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. */ #include @@ -23,7 +19,7 @@ #include "cpu_buffer.h" #include "buffer_sync.h" #include "oprofile_stats.h" - + struct oprofile_operations oprofile_ops; unsigned long oprofile_started; @@ -37,34 +33,6 @@ static DECLARE_MUTEX(start_sem); */ static int timer = 0; -#ifdef CONFIG_XEN -int oprofile_set_active(int active_domains[], unsigned int adomains) -{ - int err; - - if (!oprofile_ops.set_active) - return -EINVAL; - - down(&start_sem); - err = oprofile_ops.set_active(active_domains, adomains); - up(&start_sem); - return err; -} - -int oprofile_set_passive(int passive_domains[], unsigned int pdomains) -{ - int err; - - if (!oprofile_ops.set_passive) - return -EINVAL; - - down(&start_sem); - err = oprofile_ops.set_passive(passive_domains, pdomains); - up(&start_sem); - return err; -} -#endif - int oprofile_setup(void) { int err; diff --git a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h index 587db2b0a..183236508 100644 --- a/drivers/oprofile/oprof.h +++ b/drivers/oprofile/oprof.h @@ -35,10 +35,5 @@ void oprofile_create_files(struct super_block * sb, struct dentry * root); void oprofile_timer_init(struct oprofile_operations * ops); int oprofile_set_backtrace(unsigned long depth); - -#ifdef CONFIG_XEN -int oprofile_set_active(int active_domains[], unsigned int adomains); -int oprofile_set_passive(int passive_domains[], unsigned int pdomains); -#endif - + #endif /* OPROF_H */ diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c index 388846526..a72006c08 100644 --- a/drivers/oprofile/oprofile_files.c +++ b/drivers/oprofile/oprofile_files.c @@ -5,21 +5,15 @@ * @remark Read the file COPYING * * @author John Levon - * - * Modified by Aravind Menon for Xen - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. */ #include #include -#include -#include #include "event_buffer.h" #include "oprofile_stats.h" #include "oprof.h" - + unsigned long fs_buffer_size = 131072; unsigned long fs_cpu_buffer_size = 8192; unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */ @@ -123,206 +117,11 @@ static ssize_t dump_write(struct file * file, char const __user * buf, size_t co static struct file_operations dump_fops = { .write = dump_write, }; - -#define TMPBUFSIZE 512 - -#ifdef CONFIG_XEN -static unsigned int adomains = 0; -static int active_domains[MAX_OPROF_DOMAINS + 1]; -static DEFINE_MUTEX(adom_mutex); - -static ssize_t adomain_write(struct file * file, char const __user * buf, - size_t count, loff_t * offset) -{ - char *tmpbuf; - char *startp, *endp; - int i; - unsigned long val; - ssize_t retval = count; - - if (*offset) - return -EINVAL; - if (count > TMPBUFSIZE - 1) - return -EINVAL; - - if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(tmpbuf, buf, count)) { - kfree(tmpbuf); - return -EFAULT; - } - tmpbuf[count] = 0; - - mutex_lock(&adom_mutex); - - startp = tmpbuf; - /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */ - for (i = 0; i <= MAX_OPROF_DOMAINS; i++) { - val = simple_strtoul(startp, &endp, 0); - if (endp == startp) - break; - while (ispunct(*endp) || isspace(*endp)) - endp++; - active_domains[i] = val; - if (active_domains[i] != val) - /* Overflow, force error below */ - i = MAX_OPROF_DOMAINS + 1; - startp = endp; - } - /* Force error on trailing junk */ - adomains = *startp ? MAX_OPROF_DOMAINS + 1 : i; - - kfree(tmpbuf); - - if (adomains > MAX_OPROF_DOMAINS - || oprofile_set_active(active_domains, adomains)) { - adomains = 0; - retval = -EINVAL; - } - - mutex_unlock(&adom_mutex); - return retval; -} - -static ssize_t adomain_read(struct file * file, char __user * buf, - size_t count, loff_t * offset) -{ - char * tmpbuf; - size_t len; - int i; - ssize_t retval; - - if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) - return -ENOMEM; - - mutex_lock(&adom_mutex); - - len = 0; - for (i = 0; i < adomains; i++) - len += snprintf(tmpbuf + len, - len < TMPBUFSIZE ? TMPBUFSIZE - len : 0, - "%u ", active_domains[i]); - WARN_ON(len > TMPBUFSIZE); - if (len != 0 && len <= TMPBUFSIZE) - tmpbuf[len-1] = '\n'; - - mutex_unlock(&adom_mutex); - - retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len); - - kfree(tmpbuf); - return retval; -} - - -static struct file_operations active_domain_ops = { - .read = adomain_read, - .write = adomain_write, -}; - -static unsigned int pdomains = 0; -static int passive_domains[MAX_OPROF_DOMAINS]; -static DEFINE_MUTEX(pdom_mutex); - -static ssize_t pdomain_write(struct file * file, char const __user * buf, - size_t count, loff_t * offset) -{ - char *tmpbuf; - char *startp, *endp; - int i; - unsigned long val; - ssize_t retval = count; - - if (*offset) - return -EINVAL; - if (count > TMPBUFSIZE - 1) - return -EINVAL; - - if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(tmpbuf, buf, count)) { - kfree(tmpbuf); - return -EFAULT; - } - tmpbuf[count] = 0; - - mutex_lock(&pdom_mutex); - - startp = tmpbuf; - /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */ - for (i = 0; i <= MAX_OPROF_DOMAINS; i++) { - val = simple_strtoul(startp, &endp, 0); - if (endp == startp) - break; - while (ispunct(*endp) || isspace(*endp)) - endp++; - passive_domains[i] = val; - if (passive_domains[i] != val) - /* Overflow, force error below */ - i = MAX_OPROF_DOMAINS + 1; - startp = endp; - } - /* Force error on trailing junk */ - pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i; - - kfree(tmpbuf); - - if (pdomains > MAX_OPROF_DOMAINS - || oprofile_set_passive(passive_domains, pdomains)) { - pdomains = 0; - retval = -EINVAL; - } - - mutex_unlock(&pdom_mutex); - return retval; -} - -static ssize_t pdomain_read(struct file * file, char __user * buf, - size_t count, loff_t * offset) -{ - char * tmpbuf; - size_t len; - int i; - ssize_t retval; - - if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) - return -ENOMEM; - - mutex_lock(&pdom_mutex); - - len = 0; - for (i = 0; i < pdomains; i++) - len += snprintf(tmpbuf + len, - len < TMPBUFSIZE ? TMPBUFSIZE - len : 0, - "%u ", passive_domains[i]); - WARN_ON(len > TMPBUFSIZE); - if (len != 0 && len <= TMPBUFSIZE) - tmpbuf[len-1] = '\n'; - - mutex_unlock(&pdom_mutex); - - retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len); - - kfree(tmpbuf); - return retval; -} - -static struct file_operations passive_domain_ops = { - .read = pdomain_read, - .write = pdomain_write, -}; -#endif /* CONFIG_XEN */ - + void oprofile_create_files(struct super_block * sb, struct dentry * root) { oprofilefs_create_file(sb, root, "enable", &enable_fops); oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); -#ifdef CONFIG_XEN - oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops); - oprofilefs_create_file(sb, root, "passive_domains", &passive_domain_ops); -#endif oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops); oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c index f0acb661c..e94b1e4a2 100644 --- a/drivers/oprofile/oprofile_stats.c +++ b/drivers/oprofile/oprofile_stats.c @@ -22,7 +22,7 @@ void oprofile_reset_stats(void) struct oprofile_cpu_buffer * cpu_buf; int i; - for_each_possible_cpu(i) { + for_each_cpu(i) { cpu_buf = &cpu_buffer[i]; cpu_buf->sample_received = 0; cpu_buf->sample_lost_overflow = 0; @@ -46,7 +46,7 @@ void oprofile_create_stats_files(struct super_block * sb, struct dentry * root) if (!dir) return; - for_each_possible_cpu(i) { + for_each_cpu(i) { cpu_buf = &cpu_buffer[i]; snprintf(buf, 10, "cpu%d", i); cpudir = oprofilefs_mkdir(sb, dir, buf); diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index b62da9b0c..d6bae6997 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c @@ -130,7 +130,7 @@ static struct file_operations ulong_ro_fops = { static struct dentry * __oprofilefs_create_file(struct super_block * sb, - struct dentry * root, char const * name, const struct file_operations * fops, + struct dentry * root, char const * name, struct file_operations * fops, int perm) { struct dentry * dentry; @@ -203,7 +203,7 @@ int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, int oprofilefs_create_file(struct super_block * sb, struct dentry * root, - char const * name, const struct file_operations * fops) + char const * name, struct file_operations * fops) { if (!__oprofilefs_create_file(sb, root, name, fops, 0644)) return -EFAULT; @@ -212,7 +212,7 @@ int oprofilefs_create_file(struct super_block * sb, struct dentry * root, int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, - char const * name, const struct file_operations * fops, int perm) + char const * name, struct file_operations * fops, int perm) { if (!__oprofilefs_create_file(sb, root, name, fops, perm)) return -EFAULT; diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index a5d826237..93f8a8fa8 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -1560,7 +1560,7 @@ static int ccio_probe(struct parisc_device *dev) *ioc_p = ioc; ioc->hw_path = dev->hw_path; - ioc->ioc_regs = ioremap_nocache(dev->hpa.start, 4096); + ioc->ioc_regs = ioremap(dev->hpa.start, 4096); ccio_ioc_init(ioc); ccio_init_resources(ioc); hppa_dma_ops = &ccio_ops; diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 6e8ed0c81..3d1a7f98c 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -5,7 +5,6 @@ ** (c) Copyright 1999 SuSE GmbH ** (c) Copyright 1999,2000 Hewlett-Packard Company ** (c) Copyright 2000 Grant Grundler -** (c) Copyright 2006 Helge Deller ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by @@ -786,7 +785,7 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name) if((io_addr & (1 << i)) == 0) continue; - start = F_EXTEND(0xf0000000UL) | (i << 23); + start = (unsigned long)(signed int)(0xf0000000 | (i << 23)); end = start + 8 * 1024 * 1024 - 1; DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count, @@ -997,7 +996,7 @@ static int __init dino_probe(struct parisc_device *dev) } dino_dev->hba.dev = dev; - dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096); + dino_dev->hba.base_addr = ioremap(hpa, 4096); dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ spin_lock_init(&dino_dev->dinosaur_pen); dino_dev->hba.iommu = ccio_get_iommu(dev); diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 9d3bd15bf..3d94d86c1 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c @@ -366,7 +366,7 @@ static int __devinit eisa_probe(struct parisc_device *dev) eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR; } } - eisa_eeprom_addr = ioremap_nocache(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); + eisa_eeprom_addr = ioremap(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, &eisa_dev.hba.lmmio_space); init_eisa_pic(); diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 7a458d5bc..8d7a36392 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -879,7 +879,7 @@ void *iosapic_register(unsigned long hpa) return NULL; } - isi->addr = ioremap_nocache(hpa, 4096); + isi->addr = ioremap(hpa, 4096); isi->isi_hpa = hpa; isi->isi_version = iosapic_rd_version(isi); isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 3fe4a77fa..e8a2a4a85 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1213,7 +1213,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) ** Postable I/O port space is per PCI host adapter. ** base of 64MB PIOP region */ - lba_dev->iop_base = ioremap_nocache(p->start, 64 * 1024 * 1024); + lba_dev->iop_base = ioremap(p->start, 64 * 1024 * 1024); sprintf(lba_dev->hba.io_name, "PCI%02lx Ports", lba_dev->hba.bus_num.start); @@ -1525,7 +1525,7 @@ lba_driver_probe(struct parisc_device *dev) u32 func_class; void *tmp_obj; char *version; - void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096); + void __iomem *addr = ioremap(dev->hpa.start, 4096); /* Read HW Rev First */ func_class = READ_REG32(addr + LBA_FCLASS); @@ -1619,7 +1619,7 @@ lba_driver_probe(struct parisc_device *dev) } else { if (!astro_iop_base) { /* Sprockets PDC uses NPIOP region */ - astro_iop_base = ioremap_nocache(LBA_PORT_BASE, 64 * 1024); + astro_iop_base = ioremap(LBA_PORT_BASE, 64 * 1024); pci_port = &lba_astro_port_ops; } @@ -1700,7 +1700,7 @@ void __init lba_init(void) */ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) { - void __iomem * base_addr = ioremap_nocache(lba->hpa.start, 4096); + void __iomem * base_addr = ioremap(lba->hpa.start, 4096); imask <<= 2; /* adjust for hints - 2 more bits */ diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 298f2ddb2..3627a2d7f 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -499,16 +499,11 @@ static int led_halt(struct notifier_block *, unsigned long, void *); static struct notifier_block led_notifier = { .notifier_call = led_halt, }; -static int notifier_disabled = 0; static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) { char *txt; - - if (notifier_disabled) - return NOTIFY_OK; - - notifier_disabled = 1; + switch (event) { case SYS_RESTART: txt = "SYSTEM RESTART"; break; @@ -532,6 +527,7 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) if (led_func_ptr) led_func_ptr(0xff); /* turn all LEDs ON */ + unregister_reboot_notifier(&led_notifier); return NOTIFY_OK; } @@ -762,12 +758,6 @@ not_found: return 1; } -static void __exit led_exit(void) -{ - unregister_reboot_notifier(&led_notifier); - return; -} - #ifdef CONFIG_PROC_FS module_init(led_create_procfs) #endif diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index bbeabe3fc..a28e17898 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -4,8 +4,9 @@ * Copyright (C) 2005-2006 Thibaut VARENE * * 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. + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -535,7 +536,7 @@ pdcs_auto_read(struct subsystem *entry, char *buf, int knob) { char *out = buf; struct pdcspath_entry *pathentry; - + if (!entry || !buf) return -EINVAL; diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c index 0bcab83b4..54b2b7f20 100644 --- a/drivers/parisc/power.c +++ b/drivers/parisc/power.c @@ -251,8 +251,7 @@ static int __init power_init(void) } /* Register a call for panic conditions. */ - atomic_notifier_chain_register(&panic_notifier_list, - &parisc_panic_block); + notifier_chain_register(&panic_notifier_list, &parisc_panic_block); tasklet_enable(&power_tasklet); @@ -265,8 +264,7 @@ static void __exit power_exit(void) return; tasklet_disable(&power_tasklet); - atomic_notifier_chain_unregister(&panic_notifier_list, - &parisc_panic_block); + notifier_chain_unregister(&panic_notifier_list, &parisc_panic_block); power_tasklet.func = NULL; pdc_soft_power_button(0); } diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 278f32502..5d47c5965 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -178,11 +178,6 @@ extern struct proc_dir_entry * proc_mckinley_root; #define ROPE6_CTL 0x230 #define ROPE7_CTL 0x238 -#define IOC_ROPE0_CFG 0x500 /* pluto only */ -#define IOC_ROPE_AO 0x10 /* Allow "Relaxed Ordering" */ - - - #define HF_ENABLE 0x40 @@ -1647,9 +1642,9 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ** **************************************************************************/ -static void __iomem *ioc_remap(struct sba_device *sba_dev, unsigned int offset) +static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset) { - return ioremap_nocache(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE); + return ioremap(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE); } static void sba_hw_init(struct sba_device *sba_dev) @@ -1729,7 +1724,9 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, sba_dev->chip_resv.start = PCI_F_EXTEND | 0xfef00000UL; sba_dev->chip_resv.end = PCI_F_EXTEND | (0xff000000UL - 1) ; err = request_resource(&iomem_resource, &(sba_dev->chip_resv)); - BUG_ON(err < 0); + if (err < 0) { + BUG(); + } } else if (IS_PLUTO(sba_dev->iodc)) { int err; @@ -1764,33 +1761,19 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, sba_dev->num_ioc = num_ioc; for (i = 0; i < num_ioc; i++) { - unsigned long ioc_hpa = sba_dev->ioc[i].ioc_hpa; - unsigned int j; - - for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { - - /* - * Clear ROPE(N)_CONFIG AO bit. - * Disables "NT Ordering" (~= !"Relaxed Ordering") - * Overrides bit 1 in DMA Hint Sets. - * Improves netperf UDP_STREAM by ~10% for bcm5701. - */ - if (IS_PLUTO(sba_dev->iodc)) { - unsigned long rope_cfg, cfg_val; - - rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; - cfg_val = READ_REG(rope_cfg); - cfg_val &= ~IOC_ROPE_AO; - WRITE_REG(cfg_val, rope_cfg); - } - - /* - ** Make sure the box crashes on rope errors. - */ - WRITE_REG(HF_ENABLE, ioc_hpa + ROPE0_CTL + j); - } - - /* flush out the last writes */ + /* + ** Make sure the box crashes if we get any errors on a rope. + */ + WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE0_CTL); + WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE1_CTL); + WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE2_CTL); + WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE3_CTL); + WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE4_CTL); + WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE5_CTL); + WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE6_CTL); + WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE7_CTL); + + /* flush out the writes */ READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL); DBG_INIT(" ioc[%d] ROPE_CFG 0x%Lx ROPE_DBG 0x%Lx\n", @@ -2059,7 +2042,7 @@ sba_driver_callback(struct parisc_device *dev) u32 func_class; int i; char *version; - void __iomem *sba_addr = ioremap_nocache(dev->hpa.start, SBA_FUNC_SIZE); + void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); struct proc_dir_entry *info_entry, *bitmap_entry, *root; sba_dump_ranges(sba_addr); @@ -2202,7 +2185,8 @@ void sba_directed_lmmio(struct parisc_device *pci_hba, struct resource *r) int i; int rope = (pci_hba->hw_path & (ROPES_PER_IOC-1)); /* rope # */ - BUG_ON((t!=HPHW_IOA) && (t!=HPHW_BCPORT)); + if ((t!=HPHW_IOA) && (t!=HPHW_BCPORT)) + BUG(); r->start = r->end = 0; @@ -2244,7 +2228,8 @@ void sba_distributed_lmmio(struct parisc_device *pci_hba, struct resource *r ) int base, size; int rope = (pci_hba->hw_path & (ROPES_PER_IOC-1)); /* rope # */ - BUG_ON((t!=HPHW_IOA) && (t!=HPHW_BCPORT)); + if ((t!=HPHW_IOA) && (t!=HPHW_BCPORT)) + BUG(); r->start = r->end = 0; diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 828eb4506..ba971fecd 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -12,7 +12,6 @@ * (C) Copyright 2001 John Marvin * (C) Copyright 2003 Grant Grundler * (C) Copyright 2005 Kyle McMartin - * (C) Copyright 2006 Helge Deller * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -155,11 +154,11 @@ superio_init(struct pci_dev *pcidev) struct pci_dev *pdev = sio->lio_pdev; u16 word; - if (sio->suckyio_irq_enabled) + if (sio->suckyio_irq_enabled) return; - BUG_ON(!pdev); - BUG_ON(!sio->usb_pdev); + if (!pdev) BUG(); + if (!sio->usb_pdev) BUG(); /* use the IRQ iosapic found for USB INT D... */ pdev->irq = sio->usb_pdev->irq; @@ -194,7 +193,7 @@ superio_init(struct pci_dev *pcidev) request_region (sio->acpi_base, 0x1f, "acpi"); /* Enable the legacy I/O function */ - pci_read_config_word (pdev, PCI_COMMAND, &word); + pci_read_config_word (pdev, PCI_COMMAND, &word); word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO; pci_write_config_word (pdev, PCI_COMMAND, word); @@ -389,34 +388,43 @@ int superio_fixup_irq(struct pci_dev *pcidev) return local_irq; } +static struct uart_port serial[] = { + { + .iotype = UPIO_PORT, + .line = 0, + .type = PORT_16550A, + .uartclk = 115200*16, + .fifosize = 16, + }, + { + .iotype = UPIO_PORT, + .line = 1, + .type = PORT_16550A, + .uartclk = 115200*16, + .fifosize = 16, + } +}; + static void __devinit superio_serial_init(void) { #ifdef CONFIG_SERIAL_8250 int retval; - struct uart_port serial_port; - - memset(&serial_port, 0, sizeof(serial_port)); - serial_port.iotype = UPIO_PORT; - serial_port.type = PORT_16550A; - serial_port.uartclk = 115200*16; - serial_port.fifosize = 16; - spin_lock_init(&serial_port.lock); - - /* serial port #1 */ - serial_port.iobase = sio_dev.sp1_base; - serial_port.irq = SP1_IRQ; - serial_port.line = 0; - retval = early_serial_setup(&serial_port); + + serial[0].iobase = sio_dev.sp1_base; + serial[0].irq = SP1_IRQ; + spin_lock_init(&serial[0].lock); + + retval = early_serial_setup(&serial[0]); if (retval < 0) { printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); return; } - /* serial port #2 */ - serial_port.iobase = sio_dev.sp2_base; - serial_port.irq = SP2_IRQ; - serial_port.line = 1; - retval = early_serial_setup(&serial_port); + serial[1].iobase = sio_dev.sp2_base; + serial[1].irq = SP2_IRQ; + spin_lock_init(&serial[1].lock); + retval = early_serial_setup(&serial[1]); + if (retval < 0) printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); #endif /* CONFIG_SERIAL_8250 */ @@ -466,7 +474,8 @@ superio_probe(struct pci_dev *dev, const struct pci_device_id *id) dev->subsystem_vendor, dev->subsystem_device, dev->class); - BUG_ON(!sio->suckyio_irq_enabled); /* Enabled by PCI_FIXUP_FINAL */ + if (!sio->suckyio_irq_enabled) + BUG(); /* Enabled by PCI_FIXUP_FINAL */ if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) { /* Function 1 */ superio_parport_init(); diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index 6c8452ede..f63c38797 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig @@ -48,7 +48,7 @@ config PARPORT_PC config PARPORT_SERIAL tristate "Multi-IO cards (parallel and serial)" - depends on SERIAL_8250_PCI && PARPORT_PC && PCI + depends on SERIAL_8250 && PARPORT_PC && PCI help This adds support for multi-IO PCI cards that have parallel and serial ports. You should say Y or M here. If you say M, the module diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index b953d5907..158d92563 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -81,15 +81,15 @@ static char *version = #define FORCE_EPP_MODE 0x08 typedef struct parport_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; int ndev; dev_node_t node; struct parport *port; } parport_info_t; static void parport_detach(struct pcmcia_device *p_dev); -static int parport_config(struct pcmcia_device *link); -static void parport_cs_release(struct pcmcia_device *); +static void parport_config(dev_link_t *link); +static void parport_cs_release(dev_link_t *); /*====================================================================== @@ -99,9 +99,10 @@ static void parport_cs_release(struct pcmcia_device *); ======================================================================*/ -static int parport_probe(struct pcmcia_device *link) +static int parport_attach(struct pcmcia_device *p_dev) { parport_info_t *info; + dev_link_t *link; DEBUG(0, "parport_attach()\n"); @@ -109,17 +110,23 @@ static int parport_probe(struct pcmcia_device *link) info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; memset(info, 0, sizeof(*info)); - link->priv = info; - info->p_dev = link; + link = &info->link; link->priv = info; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - return parport_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + parport_config(link); + + return 0; } /* parport_attach */ /*====================================================================== @@ -131,11 +138,14 @@ static int parport_probe(struct pcmcia_device *link) ======================================================================*/ -static void parport_detach(struct pcmcia_device *link) +static void parport_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + DEBUG(0, "parport_detach(0x%p)\n", link); - parport_cs_release(link); + if (link->state & DEV_CONFIG) + parport_cs_release(link); kfree(link->priv); } /* parport_detach */ @@ -151,12 +161,14 @@ static void parport_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int parport_config(struct pcmcia_device *link) +void parport_config(dev_link_t *link) { + client_handle_t handle = link->handle; parport_info_t *info = link->priv; tuple_t tuple; u_short buf[128]; cisparse_t parse; + config_info_t conf; cistpl_cftable_entry_t *cfg = &parse.cftable_entry; cistpl_cftable_entry_t dflt = { 0 }; struct parport *p; @@ -168,18 +180,24 @@ static int parport_config(struct pcmcia_device *link) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + /* Not sure if this is right... look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { @@ -194,7 +212,7 @@ static int parport_config(struct pcmcia_device *link) link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; } - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; /* If we've got this far, we're done */ break; @@ -202,12 +220,15 @@ static int parport_config(struct pcmcia_device *link) next_entry: if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + release_region(link->io.BasePort1, link->io.NumPorts1); + if (link->io.NumPorts2) + release_region(link->io.BasePort2, link->io.NumPorts2); p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, link->irq.AssignedIRQ, PARPORT_DMA_NONE, NULL); @@ -226,15 +247,17 @@ static int parport_config(struct pcmcia_device *link) info->node.minor = p->number; info->port = p; strcpy(info->node.dev_name, p->name); - link->dev_node = &info->node; - - return 0; + link->dev = &info->node; + link->state &= ~DEV_CONFIG_PENDING; + return; + cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: parport_cs_release(link); - return -ENODEV; + link->state &= ~DEV_CONFIG_PENDING; + } /* parport_config */ /*====================================================================== @@ -245,21 +268,53 @@ failed: ======================================================================*/ -void parport_cs_release(struct pcmcia_device *link) +void parport_cs_release(dev_link_t *link) +{ + parport_info_t *info = link->priv; + + DEBUG(0, "parport_release(0x%p)\n", link); + + if (info->ndev) { + struct parport *p = info->port; + parport_pc_unregister_port(p); + request_region(link->io.BasePort1, link->io.NumPorts1, + info->node.dev_name); + if (link->io.NumPorts2) + request_region(link->io.BasePort2, link->io.NumPorts2, + info->node.dev_name); + } + info->ndev = 0; + link->dev = NULL; + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; + +} /* parport_cs_release */ + +static int parport_suspend(struct pcmcia_device *dev) { - parport_info_t *info = link->priv; + dev_link_t *link = dev_to_instance(dev); - DEBUG(0, "parport_release(0x%p)\n", link); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); - if (info->ndev) { - struct parport *p = info->port; - parport_pc_unregister_port(p); - } - info->ndev = 0; + return 0; +} - pcmcia_disable_device(link); -} /* parport_cs_release */ +static int parport_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (DEV_OK(link)) + pcmcia_request_configuration(link->handle, &link->conf); + return 0; +} static struct pcmcia_device_id parport_ids[] = { PCMCIA_DEVICE_FUNC_ID(3), @@ -273,9 +328,11 @@ static struct pcmcia_driver parport_cs_driver = { .drv = { .name = "parport_cs", }, - .probe = parport_probe, + .probe = parport_attach, .remove = parport_detach, .id_table = parport_ids, + .suspend = parport_suspend, + .resume = parport_resume, }; static int __init init_parport_cs(void) diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 48bbf32fd..9302b8fd7 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -97,7 +97,7 @@ static struct superio_struct { /* For Super-IO chips autodetection */ int io; int irq; int dma; -} superios[NR_SUPERIOS] = { {0,},}; +} superios[NR_SUPERIOS] __devinitdata = { {0,},}; static int user_specified; #if defined(CONFIG_PARPORT_PC_SUPERIO) || \ @@ -1557,7 +1557,7 @@ static int __devinit get_superio_dma (struct parport *p) return PARPORT_DMA_NONE; } -static int get_superio_irq (struct parport *p) +static int __devinit get_superio_irq (struct parport *p) { int i=0; while( (superios[i].io != p->base) && (iprivate_data; unsigned char r = 0xc; @@ -1712,7 +1712,7 @@ static int parport_ECR_present(struct parport *pb) * be misdetected here is rather academic. */ -static int parport_PS2_supported(struct parport *pb) +static int __devinit parport_PS2_supported(struct parport *pb) { int ok = 0; @@ -1868,7 +1868,7 @@ static int __devinit parport_ECP_supported(struct parport *pb) } #endif -static int parport_ECPPS2_supported(struct parport *pb) +static int __devinit parport_ECPPS2_supported(struct parport *pb) { const struct parport_pc_private *priv = pb->private_data; int result; @@ -1886,7 +1886,7 @@ static int parport_ECPPS2_supported(struct parport *pb) /* EPP mode detection */ -static int parport_EPP_supported(struct parport *pb) +static int __devinit parport_EPP_supported(struct parport *pb) { const struct parport_pc_private *priv = pb->private_data; @@ -1931,7 +1931,7 @@ static int parport_EPP_supported(struct parport *pb) return 1; } -static int parport_ECPEPP_supported(struct parport *pb) +static int __devinit parport_ECPEPP_supported(struct parport *pb) { struct parport_pc_private *priv = pb->private_data; int result; @@ -2073,7 +2073,7 @@ static int __devinit irq_probe_SPP(struct parport *pb) * When ECP is available we can autoprobe for IRQs. * NOTE: If we can autoprobe it, we can register the IRQ. */ -static int parport_irq_probe(struct parport *pb) +static int __devinit parport_irq_probe(struct parport *pb) { struct parport_pc_private *priv = pb->private_data; @@ -2779,7 +2779,7 @@ static struct parport_pc_pci { /* If set, this is called after probing for ports. If 'failed' * is non-zero we couldn't use any of the ports. */ void (*postinit_hook) (struct pci_dev *pdev, int failed); -} cards[] = { +} cards[] __devinitdata = { /* siig_1p_10x */ { 1, { { 2, 3 }, } }, /* siig_2p_10x */ { 2, { { 2, 3 }, { 4, 5 }, } }, /* siig_1p_20x */ { 1, { { 0, 1 }, } }, @@ -3126,9 +3126,9 @@ parport_pc_find_isa_ports (int autoirq, int autodma) * autoirq is PARPORT_IRQ_NONE, PARPORT_IRQ_AUTO, or PARPORT_IRQ_PROBEONLY * autodma is PARPORT_DMA_NONE or PARPORT_DMA_AUTO */ -static void __init parport_pc_find_ports (int autoirq, int autodma) +static int __init parport_pc_find_ports (int autoirq, int autodma) { - int count = 0, err; + int count = 0, r; #ifdef CONFIG_PARPORT_PC_SUPERIO detect_and_report_winbond (); @@ -3140,17 +3140,23 @@ static void __init parport_pc_find_ports (int autoirq, int autodma) /* PnP ports, skip detection if SuperIO already found them */ if (!count) { - err = pnp_register_driver (&parport_pc_pnp_driver); - if (!err) + r = pnp_register_driver (&parport_pc_pnp_driver); + if (r >= 0) { pnp_registered_parport = 1; + count += r; + } } /* ISA ports and whatever (see asm/parport.h). */ - parport_pc_find_nonpci_ports (autoirq, autodma); + count += parport_pc_find_nonpci_ports (autoirq, autodma); + + r = pci_register_driver (&parport_pc_pci_driver); + if (r) + return r; + pci_registered_parport = 1; + count += 1; - err = pci_register_driver (&parport_pc_pci_driver); - if (!err) - pci_registered_parport = 1; + return count; } /* @@ -3375,6 +3381,8 @@ __setup("parport_init_mode=",parport_init_mode_setup); static int __init parport_pc_init(void) { + int count = 0; + if (parse_parport_params()) return -EINVAL; @@ -3387,11 +3395,12 @@ static int __init parport_pc_init(void) break; 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); + if (parport_pc_probe_port(io[i], io_hi[i], + irqval[i], dmaval[i], NULL)) + count++; } } else - parport_pc_find_ports (irqval[0], dmaval[0]); + count += parport_pc_find_ports (irqval[0], dmaval[0]); return 0; } diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 98b83a85c..10845253c 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -31,8 +31,14 @@ enum parport_pc_pci_cards { netmos_9xx5_combo, netmos_9855, avlab_1s1p, + avlab_1s1p_650, + avlab_1s1p_850, avlab_1s2p, + avlab_1s2p_650, + avlab_1s2p_850, avlab_2s1p, + avlab_2s1p_650, + avlab_2s1p_850, siig_1s1p_10x, siig_2s1p_10x, siig_2p1s_20x, @@ -79,8 +85,14 @@ static struct parport_pc_pci cards[] __devinitdata = { /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init }, /* avlab_1s1p */ { 1, { { 1, 2}, } }, + /* avlab_1s1p_650 */ { 1, { { 1, 2}, } }, + /* avlab_1s1p_850 */ { 1, { { 1, 2}, } }, /* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} }, + /* avlab_1s2p_650 */ { 2, { { 1, 2}, { 3, 4 },} }, + /* avlab_1s2p_850 */ { 2, { { 1, 2}, { 3, 4 },} }, /* avlab_2s1p */ { 1, { { 2, 3}, } }, + /* avlab_2s1p_650 */ { 1, { { 2, 3}, } }, + /* avlab_2s1p_850 */ { 1, { { 2, 3}, } }, /* siig_1s1p_10x */ { 1, { { 3, 4 }, } }, /* siig_2s1p_10x */ { 1, { { 4, 5 }, } }, /* siig_2p1s_20x */ { 2, { { 1, 2 }, { 3, 4 }, } }, @@ -100,29 +112,22 @@ static struct pci_device_id parport_serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ - { PCI_VENDOR_ID_AFAVLAB, 0x2110, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p }, - { PCI_VENDOR_ID_AFAVLAB, 0x2111, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p }, - { PCI_VENDOR_ID_AFAVLAB, 0x2112, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p }, - { PCI_VENDOR_ID_AFAVLAB, 0x2140, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p }, - { PCI_VENDOR_ID_AFAVLAB, 0x2141, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p }, - { PCI_VENDOR_ID_AFAVLAB, 0x2142, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p }, - { PCI_VENDOR_ID_AFAVLAB, 0x2160, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p }, - { PCI_VENDOR_ID_AFAVLAB, 0x2161, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p }, - { PCI_VENDOR_ID_AFAVLAB, 0x2162, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p }, + { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p}, + { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650}, + { 0x14db, 0x2112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_850}, + { 0x14db, 0x2140, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p}, + { 0x14db, 0x2141, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p_650}, + { 0x14db, 0x2142, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p_850}, + { 0x14db, 0x2160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p}, + { 0x14db, 0x2161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p_650}, + { 0x14db, 0x2162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p_850}, { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x }, { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650, @@ -196,18 +201,54 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { .base_baud = 115200, .uart_offset = 8, }, + [avlab_1s1p_650] = { /* nt */ + .flags = FL_BASE0 | FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, + [avlab_1s1p_850] = { /* nt */ + .flags = FL_BASE0 | FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, [avlab_1s2p] = { /* n/t */ .flags = FL_BASE0 | FL_BASE_BARS, .num_ports = 1, .base_baud = 115200, .uart_offset = 8, }, + [avlab_1s2p_650] = { /* nt */ + .flags = FL_BASE0 | FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, + [avlab_1s2p_850] = { /* nt */ + .flags = FL_BASE0 | FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, [avlab_2s1p] = { /* n/t */ .flags = FL_BASE0 | FL_BASE_BARS, .num_ports = 2, .base_baud = 115200, .uart_offset = 8, }, + [avlab_2s1p_650] = { /* nt */ + .flags = FL_BASE0 | FL_BASE_BARS, + .num_ports = 2, + .base_baud = 115200, + .uart_offset = 8, + }, + [avlab_2s1p_850] = { /* nt */ + .flags = FL_BASE0 | FL_BASE_BARS, + .num_ports = 2, + .base_baud = 115200, + .uart_offset = 8, + }, [siig_1s1p_10x] = { .flags = FL_BASE2, .num_ports = 1, diff --git a/drivers/parport/share.c b/drivers/parport/share.c index bbbfd79ad..ea62bed6b 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -32,7 +32,6 @@ #include #include -#include #include #undef PARPORT_PARANOID @@ -51,7 +50,7 @@ static DEFINE_SPINLOCK(full_list_lock); static LIST_HEAD(drivers); -static DEFINE_MUTEX(registration_lock); +static DECLARE_MUTEX(registration_lock); /* What you can do to a port that's gone away.. */ static void dead_write_lines (struct parport *p, unsigned char b){} @@ -159,11 +158,11 @@ int parport_register_driver (struct parport_driver *drv) if (list_empty(&portlist)) get_lowlevel_driver (); - mutex_lock(®istration_lock); + down(®istration_lock); list_for_each_entry(port, &portlist, list) drv->attach(port); list_add(&drv->list, &drivers); - mutex_unlock(®istration_lock); + up(®istration_lock); return 0; } @@ -189,11 +188,11 @@ void parport_unregister_driver (struct parport_driver *drv) { struct parport *port; - mutex_lock(®istration_lock); + down(®istration_lock); list_del_init(&drv->list); list_for_each_entry(port, &portlist, list) drv->detach(port); - mutex_unlock(®istration_lock); + up(®istration_lock); } static void free_port (struct parport *port) @@ -367,7 +366,7 @@ void parport_announce_port (struct parport *port) #endif parport_proc_register(port); - mutex_lock(®istration_lock); + down(®istration_lock); spin_lock_irq(&parportlist_lock); list_add_tail(&port->list, &portlist); for (i = 1; i < 3; i++) { @@ -384,7 +383,7 @@ void parport_announce_port (struct parport *port) if (slave) attach_driver_chain(slave); } - mutex_unlock(®istration_lock); + up(®istration_lock); } /** @@ -410,7 +409,7 @@ void parport_remove_port(struct parport *port) { int i; - mutex_lock(®istration_lock); + down(®istration_lock); /* Spread the word. */ detach_driver_chain (port); @@ -437,7 +436,7 @@ void parport_remove_port(struct parport *port) } spin_unlock(&parportlist_lock); - mutex_unlock(®istration_lock); + up(®istration_lock); parport_proc_unregister(port); diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 065ea43aa..f187fd8ae 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -5,19 +5,31 @@ config PCI_MSI bool "Message Signaled Interrupts (MSI and MSI-X)" depends on PCI depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 - depends on !XEN help This allows device drivers to enable MSI (Message Signaled Interrupts). Message Signaled Interrupts enable a device to generate an interrupt using an inbound Memory Write on its PCI bus instead of asserting a device IRQ pin. - Use of PCI MSI interrupts can be disabled at kernel boot time - by using the 'pci=nomsi' option. This disables MSI for the - entire system. - If you don't know what to do here, say N. +config PCI_LEGACY_PROC + bool "Legacy /proc/pci interface" + depends on PCI + ---help--- + This feature enables a procfs file -- /proc/pci -- that provides a + summary of PCI devices in the system. + + This feature has been deprecated as of v2.5.53, in favor of using the + tool lspci(8). This feature may be removed at a future date. + + lspci can provide the same data, as well as much more. lspci is a part of + the pci-utils package, which should be installed by your distribution. + See for information on where to get the latest + version. + + When in doubt, say N. + config PCI_DEBUG bool "PCI Debugging" depends on PCI && DEBUG_KERNEL diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 421cfffb1..3c71e3077 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile @@ -22,9 +22,6 @@ ifdef CONFIG_HOTPLUG_PCI_CPCI pci_hotplug-objs += cpci_hotplug_core.o \ cpci_hotplug_pci.o endif -ifdef CONFIG_ACPI -pci_hotplug-objs += acpi_pcihp.o -endif cpqphp-objs := cpqphp_core.o \ cpqphp_ctrl.o \ @@ -40,8 +37,7 @@ ibmphp-objs := ibmphp_core.o \ ibmphp_hpc.o acpiphp-objs := acpiphp_core.o \ - acpiphp_glue.o \ - acpiphp_dock.o + acpiphp_glue.o rpaphp-objs := rpaphp_core.o \ rpaphp_pci.o \ @@ -54,9 +50,23 @@ pciehp-objs := pciehp_core.o \ pciehp_ctrl.o \ pciehp_pci.o \ pciehp_hpc.o +ifdef CONFIG_ACPI + pciehp-objs += pciehprm_acpi.o +else + pciehp-objs += pciehprm_nonacpi.o +endif shpchp-objs := shpchp_core.o \ shpchp_ctrl.o \ shpchp_pci.o \ shpchp_sysfs.o \ shpchp_hpc.o +ifdef CONFIG_ACPI + shpchp-objs += shpchprm_acpi.o +else + ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY + shpchp-objs += shpchprm_legacy.o + else + shpchp-objs += shpchprm_nonacpi.o + endif +endif diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 467ac70a4..293603e1b 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -37,7 +37,6 @@ #include #include /* for KOBJ_NAME_LEN */ -#include #include "pci_hotplug.h" #define dbg(format, arg...) \ @@ -60,10 +59,26 @@ struct acpiphp_slot; * struct slot - slot information for each *physical* slot */ struct slot { + u8 number; struct hotplug_slot *hotplug_slot; + struct list_head slot_list; + struct acpiphp_slot *acpi_slot; }; +/** + * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters + * @cache_line_size in DWORD + * @latency_timer in PCI clock + * @enable_SERR 0 or 1 + * @enable_PERR 0 or 1 + */ +struct hpp_param { + u8 cache_line_size; + u8 latency_timer; + u8 enable_SERR; + u8 enable_PERR; +}; /** @@ -87,7 +102,7 @@ struct acpiphp_bridge { struct pci_dev *pci_dev; /* ACPI 2.0 _HPP parameters */ - struct hotplug_params hpp; + struct hpp_param hpp; spinlock_t res_lock; }; @@ -103,9 +118,9 @@ struct acpiphp_slot { struct acpiphp_bridge *bridge; /* parent */ struct list_head funcs; /* one slot may have different objects (i.e. for each function) */ - struct slot *slot; - struct mutex crit_sect; + struct semaphore crit_sect; + u32 id; /* slot id (serial #) for hotplug core */ u8 device; /* pci device# */ u32 sun; /* ACPI _SUN (slot unique number) */ @@ -145,25 +160,6 @@ struct acpiphp_attention_info struct module *owner; }; - -struct dependent_device { - struct list_head device_list; - struct list_head pci_list; - acpi_handle handle; - struct acpiphp_func *func; -}; - - -struct acpiphp_dock_station { - acpi_handle handle; - u32 last_dock_time; - u32 flags; - struct acpiphp_func *dock_bridge; - struct list_head dependent_devices; - struct list_head pci_dependent_devices; -}; - - /* PCI bus bridge HID */ #define ACPI_PCI_HOST_HID "PNP0A03" @@ -201,27 +197,19 @@ struct acpiphp_dock_station { #define FUNC_HAS_PS1 (0x00000020) #define FUNC_HAS_PS2 (0x00000040) #define FUNC_HAS_PS3 (0x00000080) -#define FUNC_HAS_DCK (0x00000100) -#define FUNC_IS_DD (0x00000200) - -/* dock station flags */ -#define DOCK_DOCKING (0x00000001) -#define DOCK_HAS_BRIDGE (0x00000002) /* function prototypes */ /* acpiphp_core.c */ extern int acpiphp_register_attention(struct acpiphp_attention_info*info); extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info); -extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); -extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); /* acpiphp_glue.c */ extern int acpiphp_glue_init (void); extern void acpiphp_glue_exit (void); extern int acpiphp_get_num_slots (void); +extern struct acpiphp_slot *get_slot_from_id (int id); typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); -void handle_hotplug_event_func(acpi_handle, u32, void*); extern int acpiphp_enable_slot (struct acpiphp_slot *slot); extern int acpiphp_disable_slot (struct acpiphp_slot *slot); @@ -231,16 +219,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); extern u32 acpiphp_get_address (struct acpiphp_slot *slot); -/* acpiphp_dock.c */ -extern int find_dock_station(void); -extern void remove_dock_station(void); -extern void add_dependent_device(struct dependent_device *new_dd); -extern void add_pci_dependent_device(struct dependent_device *new_dd); -extern struct dependent_device *get_dependent_device(acpi_handle handle); -extern int is_dependent_device(acpi_handle handle); -extern int detect_dependent_devices(acpi_handle *bridge_handle); -extern struct dependent_device *alloc_dependent_device(acpi_handle handle); - /* variables */ extern int acpiphp_debug; diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 4f1b0da8e..60c4c3804 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -44,6 +44,8 @@ #include "pci_hotplug.h" #include "acpiphp.h" +static LIST_HEAD(slot_list); + #define MY_NAME "acpiphp" static int debug; @@ -339,53 +341,62 @@ static void release_slot(struct hotplug_slot *hotplug_slot) kfree(slot); } -/* callback routine to initialize 'struct slot' for each slot */ -int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) +/** + * init_slots - initialize 'struct slot' structures for each slot + * + */ +static int __init init_slots(void) { struct slot *slot; - struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *hotplug_slot_info; int retval = -ENOMEM; - - slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) - goto error; - - slot->hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); - if (!slot->hotplug_slot) - goto error_slot; - - slot->hotplug_slot->info = kzalloc(sizeof(*hotplug_slot_info), - GFP_KERNEL); - if (!slot->hotplug_slot->info) - goto error_hpslot; - - slot->hotplug_slot->name = kzalloc(SLOT_NAME_SIZE, GFP_KERNEL); - if (!slot->hotplug_slot->name) - goto error_info; - - slot->hotplug_slot->private = slot; - slot->hotplug_slot->release = &release_slot; - slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; - - slot->acpi_slot = acpiphp_slot; - slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot); - slot->hotplug_slot->info->attention_status = 0; - slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); - slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); - slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; - slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; - - acpiphp_slot->slot = slot; - make_slot_name(slot); - - retval = pci_hp_register(slot->hotplug_slot); - if (retval) { - err("pci_hp_register failed with error %d\n", retval); - goto error_name; - } - - info("Slot [%s] registered\n", slot->hotplug_slot->name); + int i; + + for (i = 0; i < num_slots; ++i) { + slot = kmalloc(sizeof(struct slot), GFP_KERNEL); + if (!slot) + goto error; + memset(slot, 0, sizeof(struct slot)); + + slot->hotplug_slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL); + if (!slot->hotplug_slot) + goto error_slot; + memset(slot->hotplug_slot, 0, sizeof(struct hotplug_slot)); + + slot->hotplug_slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); + if (!slot->hotplug_slot->info) + goto error_hpslot; + memset(slot->hotplug_slot->info, 0, sizeof(struct hotplug_slot_info)); + + slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); + if (!slot->hotplug_slot->name) + goto error_info; + + slot->number = i; + + slot->hotplug_slot->private = slot; + slot->hotplug_slot->release = &release_slot; + slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; + + slot->acpi_slot = get_slot_from_id(i); + slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot); + slot->hotplug_slot->info->attention_status = 0; + slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); + slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); + slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; + slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; + + make_slot_name(slot); + + retval = pci_hp_register(slot->hotplug_slot); + if (retval) { + err("pci_hp_register failed with error %d\n", retval); + goto error_name; + } + + /* add slot to our internal list */ + list_add(&slot->slot_list, &slot_list); + info("Slot [%s] registered\n", slot->hotplug_slot->name); + } return 0; error_name: @@ -401,51 +412,42 @@ error: } -void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) +static void __exit cleanup_slots (void) { - struct slot *slot = acpiphp_slot->slot; - int retval = 0; - - info ("Slot [%s] unregistered\n", slot->hotplug_slot->name); + struct list_head *tmp, *n; + struct slot *slot; - retval = pci_hp_deregister(slot->hotplug_slot); - if (retval) - err("pci_hp_deregister failed with error %d\n", retval); + list_for_each_safe (tmp, n, &slot_list) { + /* memory will be freed in release_slot callback */ + slot = list_entry(tmp, struct slot, slot_list); + list_del(&slot->slot_list); + pci_hp_deregister(slot->hotplug_slot); + } } static int __init acpiphp_init(void) { int retval; - int docking_station; info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); acpiphp_debug = debug; - docking_station = find_dock_station(); - /* read all the ACPI info from the system */ retval = init_acpi(); - - /* if we have found a docking station, we should - * go ahead and load even if init_acpi has found - * no slots. This handles the case when the _DCK - * method not defined under the actual dock bridge - */ - if (docking_station) - return 0; - else + if (retval) return retval; + + return init_slots(); } static void __exit acpiphp_exit(void) { + cleanup_slots(); /* deallocate internal data structures etc. */ acpiphp_glue_exit(); - - remove_dock_station(); } module_init(acpiphp_init); diff --git a/drivers/pci/hotplug/acpiphp_dock.c b/drivers/pci/hotplug/acpiphp_dock.c deleted file mode 100644 index 4f1aaf128..000000000 --- a/drivers/pci/hotplug/acpiphp_dock.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * ACPI PCI HotPlug dock functions to ACPI CA subsystem - * - * Copyright (C) 2006 Kristen Carlson Accardi (kristen.c.accardi@intel.com) - * Copyright (C) 2006 Intel Corporation - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to - * - */ -#include -#include - -#include -#include -#include -#include - -#include "../pci.h" -#include "pci_hotplug.h" -#include "acpiphp.h" - -static struct acpiphp_dock_station *ds; -#define MY_NAME "acpiphp_dock" - - -int is_dependent_device(acpi_handle handle) -{ - return (get_dependent_device(handle) ? 1 : 0); -} - - -static acpi_status -find_dependent_device(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - int *count = (int *)context; - - if (is_dependent_device(handle)) { - (*count)++; - return AE_CTRL_TERMINATE; - } else { - return AE_OK; - } -} - - - - -void add_dependent_device(struct dependent_device *new_dd) -{ - list_add_tail(&new_dd->device_list, &ds->dependent_devices); -} - - -void add_pci_dependent_device(struct dependent_device *new_dd) -{ - list_add_tail(&new_dd->pci_list, &ds->pci_dependent_devices); -} - - - -struct dependent_device * get_dependent_device(acpi_handle handle) -{ - struct dependent_device *dd; - - if (!ds) - return NULL; - - list_for_each_entry(dd, &ds->dependent_devices, device_list) { - if (handle == dd->handle) - return dd; - } - return NULL; -} - - - -struct dependent_device *alloc_dependent_device(acpi_handle handle) -{ - struct dependent_device *dd; - - dd = kzalloc(sizeof(*dd), GFP_KERNEL); - if (dd) { - INIT_LIST_HEAD(&dd->pci_list); - INIT_LIST_HEAD(&dd->device_list); - dd->handle = handle; - } - return dd; -} - - - -static int is_dock(acpi_handle handle) -{ - acpi_status status; - acpi_handle tmp; - - status = acpi_get_handle(handle, "_DCK", &tmp); - if (ACPI_FAILURE(status)) { - return 0; - } - return 1; -} - - - -static int dock_present(void) -{ - unsigned long sta; - acpi_status status; - - if (ds) { - status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta); - if (ACPI_SUCCESS(status) && sta) - return 1; - } - return 0; -} - - - -static void eject_dock(void) -{ - struct acpi_object_list arg_list; - union acpi_object arg; - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - - if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0", - &arg_list, NULL)) || dock_present()) - warn("%s: failed to eject dock!\n", __FUNCTION__); - - return; -} - - - - -static acpi_status handle_dock(int dock) -{ - acpi_status status; - struct acpi_object_list arg_list; - union acpi_object arg; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - - dbg("%s: %s\n", __FUNCTION__, dock ? "docking" : "undocking"); - - /* _DCK method has one argument */ - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = dock; - status = acpi_evaluate_object(ds->handle, "_DCK", - &arg_list, &buffer); - if (ACPI_FAILURE(status)) - err("%s: failed to execute _DCK\n", __FUNCTION__); - acpi_os_free(buffer.pointer); - - return status; -} - - - -static inline void dock(void) -{ - handle_dock(1); -} - - - -static inline void undock(void) -{ - handle_dock(0); -} - - - -/* - * the _DCK method can do funny things... and sometimes not - * hah-hah funny. - * - * TBD - figure out a way to only call fixups for - * systems that require them. - */ -static void post_dock_fixups(void) -{ - struct pci_bus *bus; - u32 buses; - struct dependent_device *dd; - - list_for_each_entry(dd, &ds->pci_dependent_devices, pci_list) { - bus = dd->func->slot->bridge->pci_bus; - - /* fixup bad _DCK function that rewrites - * secondary bridge on slot - */ - pci_read_config_dword(bus->self, - PCI_PRIMARY_BUS, - &buses); - - if (((buses >> 8) & 0xff) != bus->secondary) { - buses = (buses & 0xff000000) - | ((unsigned int)(bus->primary) << 0) - | ((unsigned int)(bus->secondary) << 8) - | ((unsigned int)(bus->subordinate) << 16); - pci_write_config_dword(bus->self, - PCI_PRIMARY_BUS, - buses); - } - } -} - - - -static void hotplug_pci(u32 type) -{ - struct dependent_device *dd; - - list_for_each_entry(dd, &ds->pci_dependent_devices, pci_list) - handle_hotplug_event_func(dd->handle, type, dd->func); -} - - - -static inline void begin_dock(void) -{ - ds->flags |= DOCK_DOCKING; -} - - -static inline void complete_dock(void) -{ - ds->flags &= ~(DOCK_DOCKING); - ds->last_dock_time = jiffies; -} - - -static int dock_in_progress(void) -{ - if (ds->flags & DOCK_DOCKING || - ds->last_dock_time == jiffies) { - dbg("dock in progress\n"); - return 1; - } - return 0; -} - - - -static void -handle_hotplug_event_dock(acpi_handle handle, u32 type, void *context) -{ - dbg("%s: enter\n", __FUNCTION__); - - switch (type) { - case ACPI_NOTIFY_BUS_CHECK: - dbg("BUS Check\n"); - if (!dock_in_progress() && dock_present()) { - begin_dock(); - dock(); - if (!dock_present()) { - err("Unable to dock!\n"); - break; - } - post_dock_fixups(); - hotplug_pci(type); - complete_dock(); - } - break; - case ACPI_NOTIFY_EJECT_REQUEST: - dbg("EJECT request\n"); - if (!dock_in_progress() && dock_present()) { - hotplug_pci(type); - undock(); - eject_dock(); - if (dock_present()) - err("Unable to undock!\n"); - } - break; - } -} - - - - -static acpi_status -find_dock_ejd(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - acpi_status status; - acpi_handle tmp; - acpi_handle dck_handle = (acpi_handle) context; - char objname[64]; - struct acpi_buffer buffer = { .length = sizeof(objname), - .pointer = objname }; - struct acpi_buffer ejd_buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *ejd_obj; - - status = acpi_get_handle(handle, "_EJD", &tmp); - if (ACPI_FAILURE(status)) - return AE_OK; - - /* make sure we are dependent on the dock device, - * by executing the _EJD method, then getting a handle - * to the device referenced by that name. If that - * device handle is the same handle as the dock station - * handle, then we are a device dependent on the dock station - */ - acpi_get_name(dck_handle, ACPI_FULL_PATHNAME, &buffer); - status = acpi_evaluate_object(handle, "_EJD", NULL, &ejd_buffer); - if (ACPI_FAILURE(status)) { - err("Unable to execute _EJD!\n"); - goto find_ejd_out; - } - ejd_obj = ejd_buffer.pointer; - status = acpi_get_handle(NULL, ejd_obj->string.pointer, &tmp); - if (ACPI_FAILURE(status)) - goto find_ejd_out; - - if (tmp == dck_handle) { - struct dependent_device *dd; - dbg("%s: found device dependent on dock\n", __FUNCTION__); - dd = alloc_dependent_device(handle); - if (!dd) { - err("Can't allocate memory for dependent device!\n"); - goto find_ejd_out; - } - add_dependent_device(dd); - } - -find_ejd_out: - acpi_os_free(ejd_buffer.pointer); - return AE_OK; -} - - - -int detect_dependent_devices(acpi_handle *bridge_handle) -{ - acpi_status status; - int count; - - count = 0; - - status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, - (u32)1, find_dependent_device, - (void *)&count, NULL); - - return count; -} - - - - - -static acpi_status -find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - int *count = (int *)context; - - if (is_dock(handle)) { - dbg("%s: found dock\n", __FUNCTION__); - ds = kzalloc(sizeof(*ds), GFP_KERNEL); - ds->handle = handle; - INIT_LIST_HEAD(&ds->dependent_devices); - INIT_LIST_HEAD(&ds->pci_dependent_devices); - - /* look for devices dependent on dock station */ - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_dock_ejd, handle, NULL); - - acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_dock, ds); - (*count)++; - } - - return AE_OK; -} - - - - -int find_dock_station(void) -{ - int num = 0; - - ds = NULL; - - /* start from the root object, because some laptops define - * _DCK methods outside the scope of PCI (IBM x-series laptop) - */ - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_dock, &num, NULL); - - return num; -} - - - -void remove_dock_station(void) -{ - struct dependent_device *dd, *tmp; - if (ds) { - if (ACPI_FAILURE(acpi_remove_notify_handler(ds->handle, - ACPI_SYSTEM_NOTIFY, handle_hotplug_event_dock))) - err("failed to remove dock notify handler\n"); - - /* free all dependent devices */ - list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, - device_list) - kfree(dd); - - /* no need to touch the pci_dependent_device list, - * cause all memory was freed above - */ - kfree(ds); - } -} - - diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 053ee8438..509a5b3ae 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include "../pci.h" #include "pci_hotplug.h" @@ -57,6 +57,7 @@ static LIST_HEAD(bridge_list); #define MY_NAME "acpiphp_glue" static void handle_hotplug_event_bridge (acpi_handle, u32, void *); +static void handle_hotplug_event_func (acpi_handle, u32, void *); static void acpiphp_sanitize_bus(struct pci_bus *bus); static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus); @@ -124,11 +125,11 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context; struct acpiphp_slot *slot; struct acpiphp_func *newfunc; - struct dependent_device *dd; acpi_handle tmp; acpi_status status = AE_OK; unsigned long adr, sun; - int device, function, retval; + int device, function; + static int num_slots = 0; /* XXX if we support I/O node hotplug... */ status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); @@ -137,21 +138,21 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) status = acpi_get_handle(handle, "_EJ0", &tmp); - if (ACPI_FAILURE(status) && !(is_dependent_device(handle))) + if (ACPI_FAILURE(status)) return AE_OK; device = (adr >> 16) & 0xffff; function = adr & 0xffff; - newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); + newfunc = kmalloc(sizeof(struct acpiphp_func), GFP_KERNEL); if (!newfunc) return AE_NO_MEMORY; + memset(newfunc, 0, sizeof(struct acpiphp_func)); INIT_LIST_HEAD(&newfunc->sibling); newfunc->handle = handle; newfunc->function = function; - if (ACPI_SUCCESS(status)) - newfunc->flags = FUNC_HAS_EJ0; + newfunc->flags = FUNC_HAS_EJ0; if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp))) newfunc->flags |= FUNC_HAS_STA; @@ -162,19 +163,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp))) newfunc->flags |= FUNC_HAS_PS3; - if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp))) { - newfunc->flags |= FUNC_HAS_DCK; - /* add to devices dependent on dock station, - * because this may actually be the dock bridge - */ - dd = alloc_dependent_device(handle); - if (!dd) - err("Can't allocate memory for " - "new dependent device!\n"); - else - add_dependent_device(dd); - } - status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun); if (ACPI_FAILURE(status)) sun = -1; @@ -188,17 +176,19 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) } if (!slot) { - slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); + slot = kmalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); if (!slot) { kfree(newfunc); return AE_NO_MEMORY; } + memset(slot, 0, sizeof(struct acpiphp_slot)); slot->bridge = bridge; + slot->id = num_slots++; slot->device = device; slot->sun = sun; INIT_LIST_HEAD(&slot->funcs); - mutex_init(&slot->crit_sect); + init_MUTEX(&slot->crit_sect); slot->next = bridge->slots; bridge->slots = slot; @@ -208,11 +198,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n", slot->sun, pci_domain_nr(bridge->pci_bus), bridge->pci_bus->number, slot->device); - retval = acpiphp_register_hotplug_slot(slot); - if (retval) { - warn("acpiphp_register_hotplug_slot failed(err code = 0x%x)\n", retval); - goto err_exit; - } } newfunc->slot = slot; @@ -225,41 +210,16 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); } - /* if this is a device dependent on a dock station, - * associate the acpiphp_func to the dependent_device - * struct. - */ - if ((dd = get_dependent_device(handle))) { - newfunc->flags |= FUNC_IS_DD; - /* - * we don't want any devices which is dependent - * on the dock to have it's _EJ0 method executed. - * because we need to run _DCK first. - */ - newfunc->flags &= ~FUNC_HAS_EJ0; - dd->func = newfunc; - add_pci_dependent_device(dd); - } - /* install notify handler */ - if (!(newfunc->flags & FUNC_HAS_DCK)) { - status = acpi_install_notify_handler(handle, + status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_func, newfunc); - if (ACPI_FAILURE(status)) - err("failed to register interrupt notify handler\n"); - } else - status = AE_OK; - - return status; - - err_exit: - bridge->nr_slots--; - bridge->slots = slot->next; - kfree(slot); - kfree(newfunc); + if (ACPI_FAILURE(status)) { + err("failed to register interrupt notify handler\n"); + return status; + } return AE_OK; } @@ -285,17 +245,55 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle) static void decode_hpp(struct acpiphp_bridge *bridge) { acpi_status status; + struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, + .pointer = NULL}; + union acpi_object *package; + int i; + + /* default numbers */ + bridge->hpp.cache_line_size = 0x10; + bridge->hpp.latency_timer = 0x40; + bridge->hpp.enable_SERR = 0; + bridge->hpp.enable_PERR = 0; + + status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer); - status = acpi_get_hp_params_from_firmware(bridge->pci_dev, &bridge->hpp); if (ACPI_FAILURE(status)) { - /* use default numbers */ - bridge->hpp.cache_line_size = 0x10; - bridge->hpp.latency_timer = 0x40; - bridge->hpp.enable_serr = 0; - bridge->hpp.enable_perr = 0; + dbg("_HPP evaluation failed\n"); + return; } -} + package = (union acpi_object *) buffer.pointer; + + if (!package || package->type != ACPI_TYPE_PACKAGE || + package->package.count != 4 || !package->package.elements) { + err("invalid _HPP object; ignoring\n"); + goto err_exit; + } + + for (i = 0; i < 4; i++) { + if (package->package.elements[i].type != ACPI_TYPE_INTEGER) { + err("invalid _HPP parameter type; ignoring\n"); + goto err_exit; + } + } + + bridge->hpp.cache_line_size = package->package.elements[0].integer.value; + bridge->hpp.latency_timer = package->package.elements[1].integer.value; + bridge->hpp.enable_SERR = package->package.elements[2].integer.value; + bridge->hpp.enable_PERR = package->package.elements[3].integer.value; + + dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n", + bridge->hpp.cache_line_size, + bridge->hpp.latency_timer, + bridge->hpp.enable_SERR, + bridge->hpp.enable_PERR); + + bridge->flags |= BRIDGE_HAS_HPP; + + err_exit: + kfree(buffer.pointer); +} /* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */ @@ -306,16 +304,9 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) /* decode ACPI 2.0 _HPP (hot plug parameters) */ decode_hpp(bridge); - /* must be added to the list prior to calling register_slot */ - list_add(&bridge->list, &bridge_list); - /* register all slot objects under this bridge */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, register_slot, bridge, NULL); - if (ACPI_FAILURE(status)) { - list_del(&bridge->list); - return; - } /* install notify handler */ if (bridge->type != BRIDGE_TYPE_HOST) { @@ -328,6 +319,8 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) err("failed to register interrupt notify handler\n"); } } + + list_add(&bridge->list, &bridge_list); } @@ -336,10 +329,12 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) { struct acpiphp_bridge *bridge; - bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); + bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); if (bridge == NULL) return; + memset(bridge, 0, sizeof(struct acpiphp_bridge)); + bridge->type = BRIDGE_TYPE_HOST; bridge->handle = handle; @@ -356,12 +351,14 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) { struct acpiphp_bridge *bridge; - bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); + bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); if (bridge == NULL) { err("out of memory\n"); return; } + memset(bridge, 0, sizeof(struct acpiphp_bridge)); + bridge->type = BRIDGE_TYPE_P2P; bridge->handle = handle; @@ -413,18 +410,11 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) goto out; /* check if this bridge has ejectable slots */ - if ((detect_ejectable_slots(handle) > 0) || - (detect_dependent_devices(handle) > 0)) { + if (detect_ejectable_slots(handle) > 0) { dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); add_p2p_bridge(handle, dev); } - /* search P2P bridges under this p2p bridge */ - status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, - find_p2p_bridge, dev->subordinate, NULL); - if (ACPI_FAILURE(status)) - warn("find_p2p_bridge faied (error code = 0x%x)\n", status); - out: pci_dev_put(dev); return AE_OK; @@ -522,19 +512,15 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) list_for_each_safe (list, tmp, &slot->funcs) { struct acpiphp_func *func; func = list_entry(list, struct acpiphp_func, sibling); - if (!(func->flags & FUNC_HAS_DCK)) { - status = acpi_remove_notify_handler(func->handle, + status = acpi_remove_notify_handler(func->handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_func); - if (ACPI_FAILURE(status)) - err("failed to remove notify handler\n"); - } + if (ACPI_FAILURE(status)) + err("failed to remove notify handler\n"); pci_dev_put(func->pci_dev); list_del(list); kfree(func); } - acpiphp_unregister_hotplug_slot(slot); - list_del(&slot->funcs); kfree(slot); slot = next; } @@ -565,8 +551,7 @@ static void remove_bridge(acpi_handle handle) } else { /* clean-up p2p bridges under this host bridge */ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, - ACPI_UINT32_MAX, cleanup_p2p_bridge, - NULL, NULL); + (u32)1, cleanup_p2p_bridge, NULL, NULL); } } @@ -766,113 +751,6 @@ static int power_off_slot(struct acpiphp_slot *slot) } - -/** - * acpiphp_max_busnr - return the highest reserved bus number under - * the given bus. - * @bus: bus to start search with - * - */ -static unsigned char acpiphp_max_busnr(struct pci_bus *bus) -{ - struct list_head *tmp; - unsigned char max, n; - - /* - * pci_bus_max_busnr will return the highest - * reserved busnr for all these children. - * that is equivalent to the bus->subordinate - * value. We don't want to use the parent's - * bus->subordinate value because it could have - * padding in it. - */ - max = bus->secondary; - - list_for_each(tmp, &bus->children) { - n = pci_bus_max_busnr(pci_bus_b(tmp)); - if (n > max) - max = n; - } - return max; -} - - - -/** - * get_func - get a pointer to acpiphp_func given a slot, device - * @slot: slot to search - * @dev: pci_dev struct to match. - * - * This function will increase the reference count of pci_dev, - * so callers should call pci_dev_put when complete. - * - */ -static struct acpiphp_func * -get_func(struct acpiphp_slot *slot, struct pci_dev *dev) -{ - struct acpiphp_func *func = NULL; - struct pci_bus *bus = slot->bridge->pci_bus; - struct pci_dev *pdev; - - list_for_each_entry(func, &slot->funcs, sibling) { - pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, - func->function)); - if (pdev) { - if (pdev == dev) - break; - pci_dev_put(pdev); - } - } - return func; -} - - -/** - * acpiphp_bus_add - add a new bus to acpi subsystem - * @func: acpiphp_func of the bridge - * - */ -static int acpiphp_bus_add(struct acpiphp_func *func) -{ - acpi_handle phandle; - struct acpi_device *device, *pdevice; - int ret_val; - - acpi_get_parent(func->handle, &phandle); - if (acpi_bus_get_device(phandle, &pdevice)) { - dbg("no parent device, assuming NULL\n"); - pdevice = NULL; - } - if (!acpi_bus_get_device(func->handle, &device)) { - dbg("bus exists... trim\n"); - /* this shouldn't be in here, so remove - * the bus then re-add it... - */ - ret_val = acpi_bus_trim(device, 1); - dbg("acpi_bus_trim return %x\n", ret_val); - } - - ret_val = acpi_bus_add(&device, pdevice, func->handle, - ACPI_BUS_TYPE_DEVICE); - if (ret_val) { - dbg("error adding bus, %x\n", - -ret_val); - goto acpiphp_bus_add_out; - } - /* - * try to start anyway. We could have failed to add - * simply because this bus had previously been added - * on another add. Don't bother with the return value - * we just keep going. - */ - ret_val = acpi_bus_start(device); - -acpiphp_bus_add_out: - return ret_val; -} - - - /** * enable_device - enable, configure a slot * @slot: slot to be enabled @@ -910,7 +788,7 @@ static int enable_device(struct acpiphp_slot *slot) goto err_exit; } - max = acpiphp_max_busnr(bus); + max = bus->secondary; for (pass = 0; pass < 2; pass++) { list_for_each_entry(dev, &bus->devices, bus_list) { if (PCI_SLOT(dev->devfn) != slot->device) @@ -918,15 +796,8 @@ static int enable_device(struct acpiphp_slot *slot) if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { max = pci_scan_bridge(bus, dev, max, pass); - if (pass && dev->subordinate) { + if (pass && dev->subordinate) pci_bus_size_bridges(dev->subordinate); - func = get_func(slot, dev); - if (func) { - acpiphp_bus_add(func); - /* side effect of get_func */ - pci_dev_put(dev); - } - } } } } @@ -935,8 +806,8 @@ static int enable_device(struct acpiphp_slot *slot) acpiphp_sanitize_bus(bus); pci_enable_bridges(bus); pci_bus_add_devices(bus); - acpiphp_set_hpp_values(slot->bridge->handle, bus); - acpiphp_configure_ioapics(slot->bridge->handle); + acpiphp_set_hpp_values(DEVICE_ACPI_HANDLE(&bus->self->dev), bus); + acpiphp_configure_ioapics(DEVICE_ACPI_HANDLE(&bus->self->dev)); /* associate pci_dev to our representation */ list_for_each (l, &slot->funcs) { @@ -1116,11 +987,11 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) pci_write_config_byte(dev, PCI_LATENCY_TIMER, bridge->hpp.latency_timer); pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); - if (bridge->hpp.enable_serr) + if (bridge->hpp.enable_SERR) pci_cmd |= PCI_COMMAND_SERR; else pci_cmd &= ~PCI_COMMAND_SERR; - if (bridge->hpp.enable_perr) + if (bridge->hpp.enable_PERR) pci_cmd |= PCI_COMMAND_PARITY; else pci_cmd &= ~PCI_COMMAND_PARITY; @@ -1131,11 +1002,11 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, bridge->hpp.latency_timer); pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); - if (bridge->hpp.enable_serr) + if (bridge->hpp.enable_SERR) pci_bctl |= PCI_BRIDGE_CTL_SERR; else pci_bctl &= ~PCI_BRIDGE_CTL_SERR; - if (bridge->hpp.enable_perr) + if (bridge->hpp.enable_PERR) pci_bctl |= PCI_BRIDGE_CTL_PARITY; else pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; @@ -1155,7 +1026,6 @@ static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus) memset(&bridge, 0, sizeof(bridge)); bridge.handle = handle; - bridge.pci_dev = bus->self; decode_hpp(&bridge); list_for_each_entry(dev, &bus->devices, bus_list) program_hpp(dev, &bridge); @@ -1330,7 +1200,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont * handles ACPI event notification on slots * */ -void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context) +static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context) { struct acpiphp_func *func; char objname[64]; @@ -1372,13 +1242,41 @@ void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context) } } +static int is_root_bridge(acpi_handle handle) +{ + acpi_status status; + struct acpi_device_info *info; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + int i; + + status = acpi_get_object_info(handle, &buffer); + if (ACPI_SUCCESS(status)) { + info = buffer.pointer; + if ((info->valid & ACPI_VALID_HID) && + !strcmp(PCI_ROOT_HID_STRING, + info->hardware_id.value)) { + acpi_os_free(buffer.pointer); + return 1; + } + if (info->valid & ACPI_VALID_CID) { + for (i=0; i < info->compatibility_id.count; i++) { + if (!strcmp(PCI_ROOT_HID_STRING, + info->compatibility_id.id[i].value)) { + acpi_os_free(buffer.pointer); + return 1; + } + } + } + } + return 0; +} static acpi_status find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) { int *count = (int *)context; - if (acpi_root_bridge(handle)) { + if (is_root_bridge(handle)) { acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_bridge, NULL); (*count)++; @@ -1475,6 +1373,26 @@ static int acpiphp_for_each_slot(acpiphp_callback fn, void *data) } #endif +/* search matching slot from id */ +struct acpiphp_slot *get_slot_from_id(int id) +{ + struct list_head *node; + struct acpiphp_bridge *bridge; + struct acpiphp_slot *slot; + + list_for_each (node, &bridge_list) { + bridge = (struct acpiphp_bridge *)node; + for (slot = bridge->slots; slot; slot = slot->next) + if (slot->id == id) + return slot; + } + + /* should never happen! */ + err("%s: no object for id %d\n", __FUNCTION__, id); + WARN_ON(1); + return NULL; +} + /** * acpiphp_enable_slot - power on slot @@ -1483,7 +1401,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot) { int retval; - mutex_lock(&slot->crit_sect); + down(&slot->crit_sect); /* wake up all functions */ retval = power_on_slot(slot); @@ -1495,7 +1413,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot) retval = enable_device(slot); err_exit: - mutex_unlock(&slot->crit_sect); + up(&slot->crit_sect); return retval; } @@ -1506,7 +1424,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) { int retval = 0; - mutex_lock(&slot->crit_sect); + down(&slot->crit_sect); /* unconfigure all functions */ retval = disable_device(slot); @@ -1519,7 +1437,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) goto err_exit; err_exit: - mutex_unlock(&slot->crit_sect); + up(&slot->crit_sect); return retval; } diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 037ce4c91..30af10527 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -248,19 +248,22 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) * with the pci_hotplug subsystem. */ for (i = first; i <= last; ++i) { - slot = kzalloc(sizeof (struct slot), GFP_KERNEL); + slot = kmalloc(sizeof (struct slot), GFP_KERNEL); if (!slot) goto error; + memset(slot, 0, sizeof (struct slot)); hotplug_slot = - kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL); + kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL); if (!hotplug_slot) goto error_slot; + memset(hotplug_slot, 0, sizeof (struct hotplug_slot)); slot->hotplug_slot = hotplug_slot; - info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL); + info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL); if (!info) goto error_hpslot; + memset(info, 0, sizeof (struct hotplug_slot_info)); hotplug_slot->info = info; name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index c74e9e37e..cb88404c8 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h @@ -32,7 +32,6 @@ #include #include /* for read? and write? functions */ #include /* for delays */ -#include #define MY_NAME "cpqphp" @@ -287,7 +286,7 @@ struct event_info { struct controller { struct controller *next; u32 ctrl_int_comp; - struct mutex crit_sect; /* critical section mutex */ + struct semaphore crit_sect; /* critical section semaphore */ void __iomem *hpc_reg; /* cookie for our pci controller location */ struct pci_resource *mem_head; struct pci_resource *p_mem_head; diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 9bc1deb8d..b3659ffcc 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -347,22 +347,26 @@ static int ctrl_slot_setup(struct controller *ctrl, slot_number = ctrl->first_slot; while (number_of_slots) { - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kmalloc(sizeof(*slot), GFP_KERNEL); if (!slot) goto error; - slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)), + memset(slot, 0, sizeof(struct slot)); + slot->hotplug_slot = kmalloc(sizeof(*(slot->hotplug_slot)), GFP_KERNEL); if (!slot->hotplug_slot) goto error_slot; hotplug_slot = slot->hotplug_slot; + memset(hotplug_slot, 0, sizeof(struct hotplug_slot)); hotplug_slot->info = - kzalloc(sizeof(*(hotplug_slot->info)), + kmalloc(sizeof(*(hotplug_slot->info)), GFP_KERNEL); if (!hotplug_slot->info) goto error_hpslot; hotplug_slot_info = hotplug_slot->info; + memset(hotplug_slot_info, 0, + sizeof(struct hotplug_slot_info)); hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); if (!hotplug_slot->name) @@ -595,7 +599,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func, hp_slot = func->device - ctrl->slot_device_offset; // Wait for exclusive access to hardware - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); if (status == 1) { amber_LED_on (ctrl, hp_slot); @@ -603,7 +607,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func, amber_LED_off (ctrl, hp_slot); } else { // Done with exclusive hardware access - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return(1); } @@ -613,7 +617,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func, wait_for_ctrl_irq (ctrl); // Done with exclusive hardware access - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return(0); } @@ -850,12 +854,13 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_disable_device; } - ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL); + ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL); if (!ctrl) { err("%s : out of memory\n", __FUNCTION__); rc = -ENOMEM; goto err_disable_device; } + memset(ctrl, 0, sizeof(struct controller)); rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid); if (rc) { @@ -1079,7 +1084,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dbg("bus device function rev: %d %d %d %d\n", ctrl->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev); - mutex_init(&ctrl->crit_sect); + init_MUTEX(&ctrl->crit_sect); init_waitqueue_head(&ctrl->queue); /* initialize our threads if they haven't already been started up */ @@ -1218,7 +1223,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) // turn off empty slots here unless command line option "ON" set // Wait for exclusive access to hardware - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F; @@ -1265,12 +1270,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) rc = init_SERR(ctrl); if (rc) { err("init_SERR failed\n"); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); goto err_free_irq; } // Done with exclusive hardware access - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); cpqhp_create_debugfs_files(ctrl); diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 55d2dc7e3..771ed34b1 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1282,7 +1282,9 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) u8 hp_slot; u8 temp_byte; u8 adapter_speed; + u32 index; u32 rc = 0; + u32 src = 8; hp_slot = func->device - ctrl->slot_device_offset; @@ -1297,7 +1299,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) **********************************/ rc = CARD_FUNCTIONING; } else { - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); /* turn on board without attaching to the bus */ enable_slot_power (ctrl, hp_slot); @@ -1331,12 +1333,12 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); if (rc) return rc; - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); slot_enable (ctrl, hp_slot); green_LED_blink (ctrl, hp_slot); @@ -1348,7 +1350,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); /* Wait for ~1 second because of hot plug spec */ long_delay(1*HZ); @@ -1366,30 +1368,76 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) rc = cpqhp_configure_board(ctrl, func); - /* If configuration fails, turn it off - * Get slot won't work for devices behind - * bridges, but in this case it will always be - * called for the "base" bus/dev/func of an - * adapter. */ + if (rc || src) { + /* If configuration fails, turn it off + * Get slot won't work for devices behind + * bridges, but in this case it will always be + * called for the "base" bus/dev/func of an + * adapter. */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); - amber_LED_on (ctrl, hp_slot); - green_LED_off (ctrl, hp_slot); - slot_disable (ctrl, hp_slot); + amber_LED_on (ctrl, hp_slot); + green_LED_off (ctrl, hp_slot); + slot_disable (ctrl, hp_slot); - set_SOGO(ctrl); + set_SOGO(ctrl); - /* Wait for SOBS to be unset */ - wait_for_ctrl_irq (ctrl); + /* Wait for SOBS to be unset */ + wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); + + if (rc) + return rc; + else + return 1; + } + + func->status = 0; + func->switch_save = 0x10; + + index = 1; + while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) { + rc |= cpqhp_configure_board(ctrl, func); + index++; + } + + if (rc) { + /* If configuration fails, turn it off + * Get slot won't work for devices behind + * bridges, but in this case it will always be + * called for the "base" bus/dev/func of an + * adapter. */ + + down(&ctrl->crit_sect); + + amber_LED_on (ctrl, hp_slot); + green_LED_off (ctrl, hp_slot); + slot_disable (ctrl, hp_slot); + + set_SOGO(ctrl); + + /* Wait for SOBS to be unset */ + wait_for_ctrl_irq (ctrl); + + up(&ctrl->crit_sect); - if (rc) return rc; - else - return 1; + } + /* Done configuring so turn LED on full time */ + + down(&ctrl->crit_sect); + + green_LED_on (ctrl, hp_slot); + + set_SOGO(ctrl); + + /* Wait for SOBS to be unset */ + wait_for_ctrl_irq (ctrl); + up(&ctrl->crit_sect); + rc = 0; } else { /* Something is wrong @@ -1397,7 +1445,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) * in this case it will always be called for the "base" * bus/dev/func of an adapter. */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); amber_LED_on (ctrl, hp_slot); green_LED_off (ctrl, hp_slot); @@ -1408,7 +1456,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); } } @@ -1440,7 +1488,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot); - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); /* turn on board without attaching to the bus */ enable_slot_power(ctrl, hp_slot); @@ -1474,7 +1522,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq(ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); if (rc) return rc; @@ -1484,7 +1532,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) /* turn on board and blink green LED */ dbg("%s: before down\n", __FUNCTION__); - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); dbg("%s: after down\n", __FUNCTION__); dbg("%s: before slot_enable\n", __FUNCTION__); @@ -1505,7 +1553,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__); dbg("%s: before up\n", __FUNCTION__); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); dbg("%s: after up\n", __FUNCTION__); /* Wait for ~1 second because of hot plug spec */ @@ -1559,7 +1607,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) cpqhp_resource_sort_and_combine(&(ctrl->bus_head)); if (rc) { - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); amber_LED_on (ctrl, hp_slot); green_LED_off (ctrl, hp_slot); @@ -1570,7 +1618,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return rc; } else { cpqhp_save_slot_config(ctrl, func); @@ -1592,7 +1640,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) } } while (new_slot); - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); green_LED_on (ctrl, hp_slot); @@ -1601,9 +1649,9 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); } else { - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); amber_LED_on (ctrl, hp_slot); green_LED_off (ctrl, hp_slot); @@ -1614,7 +1662,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return rc; } @@ -1673,7 +1721,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control func->status = 0x01; func->configured = 0; - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); green_LED_off (ctrl, hp_slot); slot_disable (ctrl, hp_slot); @@ -1688,7 +1736,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); if (!replace_flag && ctrl->add_support) { while (func) { @@ -1851,7 +1899,7 @@ static void interrupt_event_handler(struct controller *ctrl) dbg("button cancel\n"); del_timer(&p_slot->task_event); - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); if (p_slot->state == BLINKINGOFF_STATE) { /* slot is on */ @@ -1874,7 +1922,7 @@ static void interrupt_event_handler(struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); } /*** button Released (No action on press...) */ else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) { @@ -1889,7 +1937,7 @@ static void interrupt_event_handler(struct controller *ctrl) p_slot->state = BLINKINGON_STATE; info(msg_button_on, p_slot->number); } - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); dbg("blink green LED and turn off amber\n"); @@ -1901,7 +1949,7 @@ static void interrupt_event_handler(struct controller *ctrl) /* Wait for SOBS to be unset */ wait_for_ctrl_irq (ctrl); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); init_timer(&p_slot->task_event); p_slot->hp_slot = hp_slot; p_slot->ctrl = ctrl; diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 71b80c23e..060d74775 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c @@ -95,13 +95,15 @@ static int add_slot(struct pci_dev *dev) struct hotplug_slot *slot; int retval = -ENOMEM; - slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); + slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL); if (!slot) goto error; + memset(slot, 0, sizeof(*slot)); - slot->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); + slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); if (!slot->info) goto error_slot; + memset(slot->info, 0, sizeof(struct hotplug_slot_info)); slot->info->power_status = 1; slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; @@ -225,10 +227,11 @@ static void pci_rescan_bus(const struct pci_bus *bus) { unsigned int devfn; struct pci_dev *dev; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) return; + memset(dev, 0, sizeof(dev)); dev->bus = (struct pci_bus*)bus; dev->sysdata = bus->sysdata; for (devfn = 0; devfn < 0x100; devfn += 8) { diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index dba6d8ca9..c22e0284d 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h @@ -406,6 +406,8 @@ extern void ibmphp_hpc_stop_poll_thread (void); //---------------------------------------------------------------------------- // HPC return codes //---------------------------------------------------------------------------- +#define FALSE 0x00 +#define TRUE 0x01 #define HPC_ERROR 0xFF //----------------------------------------------------------------------------- diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index e13d5b872..dc59da675 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -1141,7 +1141,7 @@ static int enable_slot(struct hotplug_slot *hs) goto error_power; } - slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL); + slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL); if (!slot_cur->func) { /* We cannot do update_slot_info here, since no memory for * kmalloc n.e.ways, and update_slot_info allocates some */ @@ -1149,6 +1149,7 @@ static int enable_slot(struct hotplug_slot *hs) rc = -ENOMEM; goto error_power; } + memset(slot_cur->func, 0, sizeof(struct pci_func)); slot_cur->func->busno = slot_cur->bus; slot_cur->func->device = slot_cur->device; for (i = 0; i < 4; i++) @@ -1239,9 +1240,9 @@ int ibmphp_do_disable_slot(struct slot *slot_cur) } flag = slot_cur->flag; - slot_cur->flag = 1; + slot_cur->flag = TRUE; - if (flag == 1) { + if (flag == TRUE) { rc = validate(slot_cur, DISABLE); /* checking if powered off already & valid slot # */ if (rc) @@ -1251,12 +1252,13 @@ int ibmphp_do_disable_slot(struct slot *slot_cur) if (slot_cur->func == NULL) { /* We need this for fncs's that were there on bootup */ - slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL); + slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL); if (!slot_cur->func) { err("out of system memory\n"); rc = -ENOMEM; goto error; } + memset(slot_cur->func, 0, sizeof(struct pci_func)); slot_cur->func->busno = slot_cur->bus; slot_cur->func->device = slot_cur->device; } diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 05e4f5a19..aea1187c7 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -72,7 +72,13 @@ static int ebda_rio_table (void); static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void) { - return kzalloc(sizeof(struct ebda_hpc_list), GFP_KERNEL); + struct ebda_hpc_list *list; + + list = kmalloc (sizeof (struct ebda_hpc_list), GFP_KERNEL); + if (!list) + return NULL; + memset (list, 0, sizeof (*list)); + return list; } static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count) @@ -81,18 +87,21 @@ static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count) struct ebda_hpc_slot *slots; struct ebda_hpc_bus *buses; - controller = kzalloc(sizeof(struct controller), GFP_KERNEL); + controller = kmalloc (sizeof (struct controller), GFP_KERNEL); if (!controller) goto error; + memset (controller, 0, sizeof (*controller)); - slots = kcalloc(slot_count, sizeof(struct ebda_hpc_slot), GFP_KERNEL); + slots = kmalloc (sizeof (struct ebda_hpc_slot) * slot_count, GFP_KERNEL); if (!slots) goto error_contr; + memset (slots, 0, sizeof (*slots) * slot_count); controller->slots = slots; - buses = kcalloc(bus_count, sizeof(struct ebda_hpc_bus), GFP_KERNEL); + buses = kmalloc (sizeof (struct ebda_hpc_bus) * bus_count, GFP_KERNEL); if (!buses) goto error_slots; + memset (buses, 0, sizeof (*buses) * bus_count); controller->buses = buses; return controller; @@ -113,12 +122,24 @@ static void free_ebda_hpc (struct controller *controller) static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void) { - return kzalloc(sizeof(struct ebda_rsrc_list), GFP_KERNEL); + struct ebda_rsrc_list *list; + + list = kmalloc (sizeof (struct ebda_rsrc_list), GFP_KERNEL); + if (!list) + return NULL; + memset (list, 0, sizeof (*list)); + return list; } static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void) { - return kzalloc(sizeof(struct ebda_pci_rsrc), GFP_KERNEL); + struct ebda_pci_rsrc *resource; + + resource = kmalloc (sizeof (struct ebda_pci_rsrc), GFP_KERNEL); + if (!resource) + return NULL; + memset (resource, 0, sizeof (*resource)); + return resource; } static void __init print_bus_info (void) @@ -369,9 +390,10 @@ int __init ibmphp_access_ebda (void) debug ("now enter io table ---\n"); debug ("rio blk id: %x\n", blk_id); - rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL); + rio_table_ptr = kmalloc (sizeof (struct rio_table_hdr), GFP_KERNEL); if (!rio_table_ptr) return -ENOMEM; + memset (rio_table_ptr, 0, sizeof (struct rio_table_hdr) ); rio_table_ptr->ver_num = readb (io_mem + offset); rio_table_ptr->scal_count = readb (io_mem + offset + 1); rio_table_ptr->riodev_count = readb (io_mem + offset + 2); @@ -423,9 +445,10 @@ static int __init ebda_rio_table (void) // we do concern about rio details for (i = 0; i < rio_table_ptr->riodev_count; i++) { - rio_detail_ptr = kzalloc(sizeof(struct rio_detail), GFP_KERNEL); + rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL); if (!rio_detail_ptr) return -ENOMEM; + memset (rio_detail_ptr, 0, sizeof (struct rio_detail)); rio_detail_ptr->rio_node_id = readb (io_mem + offset); rio_detail_ptr->bbar = readl (io_mem + offset + 1); rio_detail_ptr->rio_type = readb (io_mem + offset + 5); @@ -480,9 +503,10 @@ static int __init combine_wpg_for_chassis (void) rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list); opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num); if (!opt_rio_ptr) { - opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL); + opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL); if (!opt_rio_ptr) return -ENOMEM; + memset (opt_rio_ptr, 0, sizeof (struct opt_rio)); opt_rio_ptr->rio_type = rio_detail_ptr->rio_type; opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num; opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num; @@ -522,9 +546,10 @@ static int combine_wpg_for_expansion (void) rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list); opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num); if (!opt_rio_lo_ptr) { - opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL); + opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL); if (!opt_rio_lo_ptr) return -ENOMEM; + memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo)); opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type; opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num; opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num; @@ -817,11 +842,12 @@ static int __init ebda_rsrc_controller (void) bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num); if (!bus_info_ptr2) { - bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL); + bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL); if (!bus_info_ptr1) { rc = -ENOMEM; goto error_no_hp_slot; } + memset (bus_info_ptr1, 0, sizeof (struct bus_info)); bus_info_ptr1->slot_min = slot_ptr->slot_num; bus_info_ptr1->slot_max = slot_ptr->slot_num; bus_info_ptr1->slot_count += 1; @@ -920,17 +946,19 @@ static int __init ebda_rsrc_controller (void) // register slots with hpc core as well as create linked list of ibm slot for (index = 0; index < hpc_ptr->slot_count; index++) { - hp_slot_ptr = kzalloc(sizeof(*hp_slot_ptr), GFP_KERNEL); + hp_slot_ptr = kmalloc(sizeof(*hp_slot_ptr), GFP_KERNEL); if (!hp_slot_ptr) { rc = -ENOMEM; goto error_no_hp_slot; } + memset(hp_slot_ptr, 0, sizeof(*hp_slot_ptr)); - hp_slot_ptr->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); + hp_slot_ptr->info = kmalloc (sizeof(struct hotplug_slot_info), GFP_KERNEL); if (!hp_slot_ptr->info) { rc = -ENOMEM; goto error_no_hp_info; } + memset(hp_slot_ptr->info, 0, sizeof(struct hotplug_slot_info)); hp_slot_ptr->name = kmalloc(30, GFP_KERNEL); if (!hp_slot_ptr->name) { @@ -938,13 +966,14 @@ static int __init ebda_rsrc_controller (void) goto error_no_hp_name; } - tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL); + tmp_slot = kmalloc(sizeof(*tmp_slot), GFP_KERNEL); if (!tmp_slot) { rc = -ENOMEM; goto error_no_slot; } + memset(tmp_slot, 0, sizeof(*tmp_slot)); - tmp_slot->flag = 1; + tmp_slot->flag = TRUE; tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap; if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX) diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index c3ac98a0a..1a3eb8d3d 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c @@ -34,11 +34,9 @@ #include #include #include -#include - #include "ibmphp.h" -static int to_debug = 0; +static int to_debug = FALSE; #define debug_polling(fmt, arg...) do { if (to_debug) debug (fmt, arg); } while (0) //---------------------------------------------------------------------------- @@ -95,15 +93,15 @@ static int to_debug = 0; //---------------------------------------------------------------------------- // macro utilities //---------------------------------------------------------------------------- -// if bits 20,22,25,26,27,29,30 are OFF return 1 -#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? 0 : 1)) +// if bits 20,22,25,26,27,29,30 are OFF return TRUE +#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? FALSE : TRUE)) //---------------------------------------------------------------------------- // global variables //---------------------------------------------------------------------------- static int ibmphp_shutdown; static int tid_poll; -static struct mutex sem_hpcaccess; // lock access to HPC +static struct semaphore sem_hpcaccess; // lock access to HPC static struct semaphore semOperations; // lock all operations and // access to data structures static struct semaphore sem_exit; // make sure polling thread goes away @@ -133,11 +131,11 @@ void __init ibmphp_hpc_initvars (void) { debug ("%s - Entry\n", __FUNCTION__); - mutex_init(&sem_hpcaccess); + init_MUTEX (&sem_hpcaccess); init_MUTEX (&semOperations); init_MUTEX_LOCKED (&sem_exit); - to_debug = 0; - ibmphp_shutdown = 0; + to_debug = FALSE; + ibmphp_shutdown = FALSE; tid_poll = 0; debug ("%s - Exit\n", __FUNCTION__); @@ -739,21 +737,21 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) // check controller is still not working on the command //-------------------------------------------------------------------- timeout = CMD_COMPLETE_TOUT_SEC; - done = 0; + done = FALSE; while (!done) { rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { if (NEEDTOCHECK_CMDSTATUS (cmd)) { if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES) - done = 1; + done = TRUE; } else - done = 1; + done = TRUE; } if (!done) { msleep(1000); if (timeout < 1) { - done = 1; + done = TRUE; err ("%s - Error command complete timeout\n", __FUNCTION__); rc = -EFAULT; } else @@ -780,7 +778,7 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) *---------------------------------------------------------------------*/ static void get_hpc_access (void) { - mutex_lock(&sem_hpcaccess); + down (&sem_hpcaccess); } /*---------------------------------------------------------------------- @@ -788,7 +786,7 @@ static void get_hpc_access (void) *---------------------------------------------------------------------*/ void free_hpc_access (void) { - mutex_unlock(&sem_hpcaccess); + up (&sem_hpcaccess); } /*---------------------------------------------------------------------- @@ -799,7 +797,7 @@ void free_hpc_access (void) void ibmphp_lock_operations (void) { down (&semOperations); - to_debug = 1; + to_debug = TRUE; } /*---------------------------------------------------------------------- @@ -809,7 +807,7 @@ void ibmphp_unlock_operations (void) { debug ("%s - Entry\n", __FUNCTION__); up (&semOperations); - to_debug = 0; + to_debug = FALSE; debug ("%s - Exit\n", __FUNCTION__); } @@ -937,40 +935,40 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot) { u8 status; int rc = 0; - u8 disable = 0; - u8 update = 0; + u8 disable = FALSE; + u8 update = FALSE; debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot); // bit 0 - HPC_SLOT_POWER if ((pslot->status & 0x01) != (poldslot->status & 0x01)) - update = 1; + update = TRUE; // bit 1 - HPC_SLOT_CONNECT // ignore // bit 2 - HPC_SLOT_ATTN if ((pslot->status & 0x04) != (poldslot->status & 0x04)) - update = 1; + update = TRUE; // bit 3 - HPC_SLOT_PRSNT2 // bit 4 - HPC_SLOT_PRSNT1 if (((pslot->status & 0x08) != (poldslot->status & 0x08)) || ((pslot->status & 0x10) != (poldslot->status & 0x10))) - update = 1; + update = TRUE; // bit 5 - HPC_SLOT_PWRGD if ((pslot->status & 0x20) != (poldslot->status & 0x20)) // OFF -> ON: ignore, ON -> OFF: disable slot if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) - disable = 1; + disable = TRUE; // bit 6 - HPC_SLOT_BUS_SPEED // ignore // bit 7 - HPC_SLOT_LATCH if ((pslot->status & 0x80) != (poldslot->status & 0x80)) { - update = 1; + update = TRUE; // OPEN -> CLOSE if (pslot->status & 0x80) { if (SLOT_PWRGD (pslot->status)) { @@ -979,7 +977,7 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot) msleep(1000); rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status); if (SLOT_PWRGD (status)) - update = 1; + update = TRUE; else // overwrite power in pslot to OFF pslot->status &= ~HPC_SLOT_POWER; } @@ -987,17 +985,17 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot) // CLOSE -> OPEN else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) { - disable = 1; + disable = TRUE; } // else - ignore } // bit 4 - HPC_SLOT_BLINK_ATTN if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08)) - update = 1; + update = TRUE; if (disable) { debug ("process_changeinstatus - disable slot\n"); - pslot->flag = 0; + pslot->flag = FALSE; rc = ibmphp_do_disable_slot (pslot); } @@ -1102,7 +1100,7 @@ void __exit ibmphp_hpc_stop_poll_thread (void) { debug ("%s - Entry\n", __FUNCTION__); - ibmphp_shutdown = 1; + ibmphp_shutdown = TRUE; debug ("before locking operations \n"); ibmphp_lock_operations (); debug ("after locking operations \n"); @@ -1136,7 +1134,7 @@ static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, v u8 * pstatus) { int rc = 0; - u8 done = 0; + u8 done = FALSE; debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout); @@ -1144,14 +1142,14 @@ static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, v *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX); if (*pstatus == HPC_ERROR) { rc = HPC_ERROR; - done = 1; + done = TRUE; } if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO) - done = 1; + done = TRUE; if (!done) { msleep(1000); if (timeout < 1) { - done = 1; + done = TRUE; err ("HPCreadslot - Error ctlr timeout\n"); rc = HPC_ERROR; } else diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c index d87a9e3ea..155133fe5 100644 --- a/drivers/pci/hotplug/ibmphp_pci.c +++ b/drivers/pci/hotplug/ibmphp_pci.c @@ -164,11 +164,12 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) cleanup_count = 6; goto error; } - newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL); + newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL); if (!newfunc) { err ("out of system memory\n"); return -ENOMEM; } + memset (newfunc, 0, sizeof (struct pci_func)); newfunc->busno = cur_func->busno; newfunc->device = device; cur_func->next = newfunc; @@ -199,14 +200,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) } pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number); - flag = 0; + flag = FALSE; for (i = 0; i < 32; i++) { if (func->devices[i]) { - newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL); + newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL); if (!newfunc) { err ("out of system memory\n"); return -ENOMEM; } + memset (newfunc, 0, sizeof (struct pci_func)); newfunc->busno = sec_number; newfunc->device = (u8) i; for (j = 0; j < 4; j++) @@ -226,15 +228,16 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) cleanup_count = 2; goto error; } - flag = 1; + flag = TRUE; } } - newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL); + newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL); if (!newfunc) { err ("out of system memory\n"); return -ENOMEM; } + memset (newfunc, 0, sizeof (struct pci_func)); newfunc->busno = cur_func->busno; newfunc->device = device; for (j = 0; j < 4; j++) @@ -272,15 +275,16 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) cur_func->busno, device, function); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number); debug ("after configuring bridge..., sec_number = %x\n", sec_number); - flag = 0; + flag = FALSE; for (i = 0; i < 32; i++) { if (func->devices[i]) { debug ("inside for loop, device is %x\n", i); - newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL); + newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL); if (!newfunc) { err (" out of system memory\n"); return -ENOMEM; } + memset (newfunc, 0, sizeof (struct pci_func)); newfunc->busno = sec_number; newfunc->device = (u8) i; for (j = 0; j < 4; j++) @@ -301,7 +305,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) cleanup_count = 2; goto error; } - flag = 1; + flag = TRUE; } } @@ -401,12 +405,13 @@ static int configure_device (struct pci_func *func) debug ("len[count] in IO %x, count %d\n", len[count], count); - io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!io[count]) { err ("out of system memory\n"); return -ENOMEM; } + memset (io[count], 0, sizeof (struct resource_node)); io[count]->type = IO; io[count]->busno = func->busno; io[count]->devfunc = PCI_DEVFN(func->device, func->function); @@ -439,27 +444,29 @@ static int configure_device (struct pci_func *func) debug ("len[count] in PFMEM %x, count %d\n", len[count], count); - pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!pfmem[count]) { err ("out of system memory\n"); return -ENOMEM; } + memset (pfmem[count], 0, sizeof (struct resource_node)); pfmem[count]->type = PFMEM; pfmem[count]->busno = func->busno; pfmem[count]->devfunc = PCI_DEVFN(func->device, func->function); pfmem[count]->len = len[count]; - pfmem[count]->fromMem = 0; + pfmem[count]->fromMem = FALSE; if (ibmphp_check_resource (pfmem[count], 0) == 0) { ibmphp_add_resource (pfmem[count]); func->pfmem[count] = pfmem[count]; } else { - mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL); + mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL); if (!mem_tmp) { err ("out of system memory\n"); kfree (pfmem[count]); return -ENOMEM; } + memset (mem_tmp, 0, sizeof (struct resource_node)); mem_tmp->type = MEM; mem_tmp->busno = pfmem[count]->busno; mem_tmp->devfunc = pfmem[count]->devfunc; @@ -467,7 +474,7 @@ static int configure_device (struct pci_func *func) debug ("there's no pfmem... going into mem.\n"); if (ibmphp_check_resource (mem_tmp, 0) == 0) { ibmphp_add_resource (mem_tmp); - pfmem[count]->fromMem = 1; + pfmem[count]->fromMem = TRUE; pfmem[count]->rangeno = mem_tmp->rangeno; pfmem[count]->start = mem_tmp->start; pfmem[count]->end = mem_tmp->end; @@ -505,11 +512,12 @@ static int configure_device (struct pci_func *func) debug ("len[count] in Mem %x, count %d\n", len[count], count); - mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!mem[count]) { err ("out of system memory\n"); return -ENOMEM; } + memset (mem[count], 0, sizeof (struct resource_node)); mem[count]->type = MEM; mem[count]->busno = func->busno; mem[count]->devfunc = PCI_DEVFN(func->device, @@ -571,11 +579,11 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) u16 pfmem_base; u32 bar[2]; u32 len[2]; - u8 flag_io = 0; - u8 flag_mem = 0; - u8 flag_pfmem = 0; - u8 need_io_upper = 0; - u8 need_pfmem_upper = 0; + u8 flag_io = FALSE; + u8 flag_mem = FALSE; + u8 flag_pfmem = FALSE; + u8 need_io_upper = FALSE; + u8 need_pfmem_upper = FALSE; struct res_needed *amount_needed = NULL; struct resource_node *io = NULL; struct resource_node *bus_io[2] = {NULL, NULL}; @@ -669,13 +677,14 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) debug ("len[count] in IO = %x\n", len[count]); - bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + bus_io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!bus_io[count]) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (bus_io[count], 0, sizeof (struct resource_node)); bus_io[count]->type = IO; bus_io[count]->busno = func->busno; bus_io[count]->devfunc = PCI_DEVFN(func->device, @@ -702,35 +711,37 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) debug ("len[count] in PFMEM = %x\n", len[count]); - bus_pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + bus_pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!bus_pfmem[count]) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (bus_pfmem[count], 0, sizeof (struct resource_node)); bus_pfmem[count]->type = PFMEM; bus_pfmem[count]->busno = func->busno; bus_pfmem[count]->devfunc = PCI_DEVFN(func->device, func->function); bus_pfmem[count]->len = len[count]; - bus_pfmem[count]->fromMem = 0; + bus_pfmem[count]->fromMem = FALSE; if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) { ibmphp_add_resource (bus_pfmem[count]); func->pfmem[count] = bus_pfmem[count]; } else { - mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL); + mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL); if (!mem_tmp) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (mem_tmp, 0, sizeof (struct resource_node)); mem_tmp->type = MEM; mem_tmp->busno = bus_pfmem[count]->busno; mem_tmp->devfunc = bus_pfmem[count]->devfunc; mem_tmp->len = bus_pfmem[count]->len; if (ibmphp_check_resource (mem_tmp, 0) == 0) { ibmphp_add_resource (mem_tmp); - bus_pfmem[count]->fromMem = 1; + bus_pfmem[count]->fromMem = TRUE; bus_pfmem[count]->rangeno = mem_tmp->rangeno; ibmphp_add_pfmem_from_mem (bus_pfmem[count]); func->pfmem[count] = bus_pfmem[count]; @@ -759,12 +770,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) debug ("len[count] in Memory is %x\n", len[count]); - bus_mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + bus_mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!bus_mem[count]) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (bus_mem[count], 0, sizeof (struct resource_node)); bus_mem[count]->type = MEM; bus_mem[count]->busno = func->busno; bus_mem[count]->devfunc = PCI_DEVFN(func->device, @@ -826,16 +838,17 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) if (!amount_needed->io) { debug ("it doesn't want IO?\n"); - flag_io = 1; + flag_io = TRUE; } else { debug ("it wants %x IO behind the bridge\n", amount_needed->io); - io = kzalloc(sizeof(*io), GFP_KERNEL); + io = kmalloc(sizeof(*io), GFP_KERNEL); if (!io) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (io, 0, sizeof (struct resource_node)); io->type = IO; io->busno = func->busno; io->devfunc = PCI_DEVFN(func->device, func->function); @@ -843,68 +856,71 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) if (ibmphp_check_resource (io, 1) == 0) { debug ("were we able to add io\n"); ibmphp_add_resource (io); - flag_io = 1; + flag_io = TRUE; } } if (!amount_needed->mem) { debug ("it doesn't want n.e.memory?\n"); - flag_mem = 1; + flag_mem = TRUE; } else { debug ("it wants %x memory behind the bridge\n", amount_needed->mem); - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kmalloc(sizeof(*mem), GFP_KERNEL); if (!mem) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (mem, 0, sizeof (struct resource_node)); mem->type = MEM; mem->busno = func->busno; mem->devfunc = PCI_DEVFN(func->device, func->function); mem->len = amount_needed->mem; if (ibmphp_check_resource (mem, 1) == 0) { ibmphp_add_resource (mem); - flag_mem = 1; + flag_mem = TRUE; debug ("were we able to add mem\n"); } } if (!amount_needed->pfmem) { debug ("it doesn't want n.e.pfmem mem?\n"); - flag_pfmem = 1; + flag_pfmem = TRUE; } else { debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem); - pfmem = kzalloc(sizeof(*pfmem), GFP_KERNEL); + pfmem = kmalloc(sizeof(*pfmem), GFP_KERNEL); if (!pfmem) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (pfmem, 0, sizeof (struct resource_node)); pfmem->type = PFMEM; pfmem->busno = func->busno; pfmem->devfunc = PCI_DEVFN(func->device, func->function); pfmem->len = amount_needed->pfmem; - pfmem->fromMem = 0; + pfmem->fromMem = FALSE; if (ibmphp_check_resource (pfmem, 1) == 0) { ibmphp_add_resource (pfmem); - flag_pfmem = 1; + flag_pfmem = TRUE; } else { - mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL); + mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL); if (!mem_tmp) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (mem_tmp, 0, sizeof (struct resource_node)); mem_tmp->type = MEM; mem_tmp->busno = pfmem->busno; mem_tmp->devfunc = pfmem->devfunc; mem_tmp->len = pfmem->len; if (ibmphp_check_resource (mem_tmp, 1) == 0) { ibmphp_add_resource (mem_tmp); - pfmem->fromMem = 1; + pfmem->fromMem = TRUE; pfmem->rangeno = mem_tmp->rangeno; ibmphp_add_pfmem_from_mem (pfmem); - flag_pfmem = 1; + flag_pfmem = TRUE; } } } @@ -920,12 +936,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) */ bus = ibmphp_find_res_bus (sec_number); if (!bus) { - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kmalloc(sizeof(*bus), GFP_KERNEL); if (!bus) { err ("out of system memory\n"); retval = -ENOMEM; goto error; } + memset (bus, 0, sizeof (struct bus_node)); bus->busno = sec_number; debug ("b4 adding new bus\n"); rc = add_new_bus (bus, io, mem, pfmem, func->busno); @@ -950,11 +967,11 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { debug ("io 32\n"); - need_io_upper = 1; + need_io_upper = TRUE; } if ((pfmem_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { debug ("pfmem 64\n"); - need_pfmem_upper = 1; + need_pfmem_upper = TRUE; } if (bus->noIORanges) { @@ -1094,9 +1111,10 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) }; struct res_needed *amount; - amount = kzalloc(sizeof(*amount), GFP_KERNEL); + amount = kmalloc(sizeof(*amount), GFP_KERNEL); if (amount == NULL) return NULL; + memset (amount, 0, sizeof (struct res_needed)); ibmphp_pci_bus->number = busno; @@ -1119,7 +1137,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) debug ("hdr_type behind the bridge is %x\n", hdr_type); if (hdr_type & PCI_HEADER_TYPE_BRIDGE) { err ("embedded bridges not supported for hot-plugging.\n"); - amount->not_correct = 1; + amount->not_correct = TRUE; return amount; } @@ -1127,12 +1145,12 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) if (class == PCI_CLASS_NOT_DEFINED_VGA) { err ("The device %x is VGA compatible and as is not supported for hot plugging. " "Please choose another device.\n", device); - amount->not_correct = 1; + amount->not_correct = TRUE; return amount; } else if (class == PCI_CLASS_DISPLAY_VGA) { err ("The device %x is not supported for hot plugging. " "Please choose another device.\n", device); - amount->not_correct = 1; + amount->not_correct = TRUE; return amount; } @@ -1192,9 +1210,9 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) } /* end for */ if (!howmany) - amount->not_correct = 1; + amount->not_correct = TRUE; else - amount->not_correct = 0; + amount->not_correct = FALSE; if ((amount->io) && (amount->io < IOBRIDGE)) amount->io = IOBRIDGE; if ((amount->mem) && (amount->mem < MEMBRIDGE)) @@ -1654,11 +1672,12 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r list_add (&bus->bus_list, &cur_bus->bus_list); } if (io) { - io_range = kzalloc(sizeof(*io_range), GFP_KERNEL); + io_range = kmalloc(sizeof(*io_range), GFP_KERNEL); if (!io_range) { err ("out of system memory\n"); return -ENOMEM; } + memset (io_range, 0, sizeof (struct range_node)); io_range->start = io->start; io_range->end = io->end; io_range->rangeno = 1; @@ -1666,11 +1685,12 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r bus->rangeIO = io_range; } if (mem) { - mem_range = kzalloc(sizeof(*mem_range), GFP_KERNEL); + mem_range = kmalloc(sizeof(*mem_range), GFP_KERNEL); if (!mem_range) { err ("out of system memory\n"); return -ENOMEM; } + memset (mem_range, 0, sizeof (struct range_node)); mem_range->start = mem->start; mem_range->end = mem->end; mem_range->rangeno = 1; @@ -1678,11 +1698,12 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r bus->rangeMem = mem_range; } if (pfmem) { - pfmem_range = kzalloc(sizeof(*pfmem_range), GFP_KERNEL); + pfmem_range = kmalloc(sizeof(*pfmem_range), GFP_KERNEL); if (!pfmem_range) { err ("out of system memory\n"); return -ENOMEM; } + memset (pfmem_range, 0, sizeof (struct range_node)); pfmem_range->start = pfmem->start; pfmem_range->end = pfmem->end; pfmem_range->rangeno = 1; diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c index 5636b1ac2..9c224c94d 100644 --- a/drivers/pci/hotplug/ibmphp_res.c +++ b/drivers/pci/hotplug/ibmphp_res.c @@ -55,12 +55,13 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 return NULL; } - newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL); + newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL); if (!newbus) { err ("out of system memory\n"); return NULL; } + memset (newbus, 0, sizeof (struct bus_node)); if (flag) newbus->busno = busno; else @@ -78,11 +79,12 @@ static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * cur return NULL; } - rs = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!rs) { err ("out of system memory\n"); return NULL; } + memset (rs, 0, sizeof (struct resource_node)); rs->busno = curr->bus_num; rs->devfunc = curr->dev_fun; rs->start = curr->start_addr; @@ -98,11 +100,12 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node u8 num_ranges = 0; if (first_bus) { - newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL); + newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL); if (!newbus) { err ("out of system memory.\n"); return -ENOMEM; } + memset (newbus, 0, sizeof (struct bus_node)); newbus->busno = curr->bus_num; } else { newbus = *new_bus; @@ -119,13 +122,14 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node } } - newrange = kzalloc(sizeof(struct range_node), GFP_KERNEL); + newrange = kmalloc (sizeof (struct range_node), GFP_KERNEL); if (!newrange) { if (first_bus) kfree (newbus); err ("out of system memory\n"); return -ENOMEM; } + memset (newrange, 0, sizeof (struct range_node)); newrange->start = curr->start_addr; newrange->end = curr->end_addr; @@ -325,7 +329,7 @@ int __init ibmphp_rsrc_init (void) if (!new_pfmem) return -ENOMEM; new_pfmem->type = PFMEM; - new_pfmem->fromMem = 0; + new_pfmem->fromMem = FALSE; if (ibmphp_add_resource (new_pfmem) < 0) { newbus = alloc_error_bus (curr, 0, 0); if (!newbus) @@ -462,7 +466,7 @@ static int add_range (int type, struct range_node *range, struct bus_node *bus_c static void update_resources (struct bus_node *bus_cur, int type, int rangeno) { struct resource_node *res = NULL; - u8 eol = 0; /* end of list indicator */ + u8 eol = FALSE; /* end of list indicator */ switch (type) { case MEM: @@ -488,7 +492,7 @@ static void update_resources (struct bus_node *bus_cur, int type, int rangeno) else if (res->nextRange) res = res->nextRange; else { - eol = 1; + eol = TRUE; break; } } @@ -979,7 +983,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) int noranges = 0; u32 tmp_start; /* this is to make sure start address is divisible by the length needed */ u32 tmp_divide; - u8 flag = 0; + u8 flag = FALSE; if (!res) return -EINVAL; @@ -1046,17 +1050,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) if ((range->start % tmp_divide) == 0) { /* just perfect, starting address is divisible by length */ - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = range->start; } else { /* Needs adjusting */ tmp_start = range->start; - flag = 0; + flag = FALSE; while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) { if ((tmp_start % tmp_divide) == 0) { - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = tmp_start; break; @@ -1085,17 +1089,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) if (((res_cur->end + 1) % tmp_divide) == 0) { /* just perfect, starting address is divisible by length */ - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = res_cur->end + 1; } else { /* Needs adjusting */ tmp_start = res_cur->end + 1; - flag = 0; + flag = FALSE; while ((len_tmp = range->end - tmp_start) >= res->len) { if ((tmp_start % tmp_divide) == 0) { - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = tmp_start; break; @@ -1123,17 +1127,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) if ((len_tmp < len_cur) || (len_cur == 0)) { if ((range->start % tmp_divide) == 0) { /* just perfect, starting address is divisible by length */ - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = range->start; } else { /* Needs adjusting */ tmp_start = range->start; - flag = 0; + flag = FALSE; while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) { if ((tmp_start % tmp_divide) == 0) { - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = tmp_start; break; @@ -1158,17 +1162,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) if ((len_tmp < len_cur) || (len_cur == 0)) { if (((res_prev->end + 1) % tmp_divide) == 0) { /* just perfect, starting address's divisible by length */ - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = res_prev->end + 1; } else { /* Needs adjusting */ tmp_start = res_prev->end + 1; - flag = 0; + flag = FALSE; while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) { if ((tmp_start % tmp_divide) == 0) { - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = tmp_start; break; @@ -1217,17 +1221,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) if ((len_tmp < len_cur) || (len_cur == 0)) { if ((range->start % tmp_divide) == 0) { /* just perfect, starting address's divisible by length */ - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = range->start; } else { /* Needs adjusting */ tmp_start = range->start; - flag = 0; + flag = FALSE; while ((len_tmp = range->end - tmp_start) >= res->len) { if ((tmp_start % tmp_divide) == 0) { - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = tmp_start; break; @@ -1281,17 +1285,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) if ((len_tmp < len_cur) || (len_cur == 0)) { if ((range->start % tmp_divide) == 0) { /* just perfect, starting address's divisible by length */ - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = range->start; } else { /* Needs adjusting */ tmp_start = range->start; - flag = 0; + flag = FALSE; while ((len_tmp = range->end - tmp_start) >= res->len) { if ((tmp_start % tmp_divide) == 0) { - flag = 1; + flag = TRUE; len_cur = len_tmp; start_cur = tmp_start; break; @@ -1684,7 +1688,7 @@ static int __init once_over (void) bus_cur = list_entry (tmp, struct bus_node, bus_list); if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) { for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) { - pfmem_cur->fromMem = 1; + pfmem_cur->fromMem = TRUE; if (pfmem_prev) pfmem_prev->next = pfmem_cur->next; else @@ -1701,11 +1705,12 @@ static int __init once_over (void) bus_cur->firstPFMemFromMem = pfmem_cur; - mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!mem) { err ("out of system memory\n"); return -ENOMEM; } + memset (mem, 0, sizeof (struct resource_node)); mem->type = MEM; mem->busno = pfmem_cur->busno; mem->devfunc = pfmem_cur->devfunc; @@ -1989,11 +1994,12 @@ static int __init update_bridge_ranges (struct bus_node **bus) end_address |= (upper_io_end << 16); if ((start_address) && (start_address <= end_address)) { - range = kzalloc(sizeof(struct range_node), GFP_KERNEL); + range = kmalloc (sizeof (struct range_node), GFP_KERNEL); if (!range) { err ("out of system memory\n"); return -ENOMEM; } + memset (range, 0, sizeof (struct range_node)); range->start = start_address; range->end = end_address + 0xfff; @@ -2014,12 +2020,13 @@ static int __init update_bridge_ranges (struct bus_node **bus) fix_resources (bus_sec); if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) { - io = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + io = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!io) { kfree (range); err ("out of system memory\n"); return -ENOMEM; } + memset (io, 0, sizeof (struct resource_node)); io->type = IO; io->busno = bus_cur->busno; io->devfunc = ((device << 3) | (function & 0x7)); @@ -2038,11 +2045,12 @@ static int __init update_bridge_ranges (struct bus_node **bus) if ((start_address) && (start_address <= end_address)) { - range = kzalloc(sizeof(struct range_node), GFP_KERNEL); + range = kmalloc (sizeof (struct range_node), GFP_KERNEL); if (!range) { err ("out of system memory\n"); return -ENOMEM; } + memset (range, 0, sizeof (struct range_node)); range->start = start_address; range->end = end_address + 0xfffff; @@ -2064,12 +2072,13 @@ static int __init update_bridge_ranges (struct bus_node **bus) fix_resources (bus_sec); if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) { - mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!mem) { kfree (range); err ("out of system memory\n"); return -ENOMEM; } + memset (mem, 0, sizeof (struct resource_node)); mem->type = MEM; mem->busno = bus_cur->busno; mem->devfunc = ((device << 3) | (function & 0x7)); @@ -2092,11 +2101,12 @@ static int __init update_bridge_ranges (struct bus_node **bus) if ((start_address) && (start_address <= end_address)) { - range = kzalloc(sizeof(struct range_node), GFP_KERNEL); + range = kmalloc (sizeof (struct range_node), GFP_KERNEL); if (!range) { err ("out of system memory\n"); return -ENOMEM; } + memset (range, 0, sizeof (struct range_node)); range->start = start_address; range->end = end_address + 0xfffff; @@ -2117,19 +2127,20 @@ static int __init update_bridge_ranges (struct bus_node **bus) fix_resources (bus_sec); if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) { - pfmem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (!pfmem) { kfree (range); err ("out of system memory\n"); return -ENOMEM; } + memset (pfmem, 0, sizeof (struct resource_node)); pfmem->type = PFMEM; pfmem->busno = bus_cur->busno; pfmem->devfunc = ((device << 3) | (function & 0x7)); pfmem->start = start_address; pfmem->end = end_address + 0xfffff; pfmem->len = pfmem->end - pfmem->start + 1; - pfmem->fromMem = 0; + pfmem->fromMem = FALSE; ibmphp_add_resource (pfmem); } diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h index eb0d01d47..88d44f7fe 100644 --- a/drivers/pci/hotplug/pci_hotplug.h +++ b/drivers/pci/hotplug/pci_hotplug.h @@ -176,21 +176,5 @@ extern int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info); extern struct subsystem pci_hotplug_slots_subsys; -struct hotplug_params { - u8 cache_line_size; - u8 latency_timer; - u8 enable_serr; - u8 enable_perr; -}; - -#ifdef CONFIG_ACPI -#include -#include -#include -extern acpi_status acpi_run_oshp(acpi_handle handle); -extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, - struct hotplug_params *hpp); -int acpi_root_bridge(acpi_handle handle); -#endif #endif diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 92c1f0f1e..0aac6a613 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -34,7 +34,6 @@ #include #include /* signal_pending() */ #include -#include #include "pci_hotplug.h" #define MY_NAME "pciehp" @@ -50,6 +49,12 @@ extern int pciehp_force; #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) +struct hotplug_params { + u8 cache_line_size; + u8 latency_timer; + u8 enable_serr; + u8 enable_perr; +}; struct slot { struct slot *next; @@ -91,7 +96,7 @@ struct php_ctlr_state_s { #define MAX_EVENTS 10 struct controller { struct controller *next; - struct mutex crit_sect; /* critical section mutex */ + struct semaphore crit_sect; /* critical section semaphore */ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ @@ -186,6 +191,9 @@ extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id); /* pci functions */ extern int pciehp_configure_device (struct slot *p_slot); extern int pciehp_unconfigure_device (struct slot *p_slot); +extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev); +extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp); @@ -277,19 +285,4 @@ struct hpc_ops { int (*check_lnk_status) (struct controller *ctrl); }; - -#ifdef CONFIG_ACPI -#define pciehp_get_hp_hw_control_from_firmware(dev) \ - pciehp_acpi_get_hp_hw_control_from_firmware(dev) -static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, - struct hotplug_params *hpp) -{ - if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) - return -ENODEV; - return 0; -} -#else -#define pciehp_get_hp_hw_control_from_firmware(dev) 0 -#define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV) -#endif /* CONFIG_ACPI */ #endif /* _PCIEHP_H */ diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 601cf9045..4fb569018 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -117,23 +117,27 @@ static int init_slots(struct controller *ctrl) slot_number = ctrl->first_slot; while (number_of_slots) { - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kmalloc(sizeof(*slot), GFP_KERNEL); if (!slot) goto error; + memset(slot, 0, sizeof(struct slot)); slot->hotplug_slot = - kzalloc(sizeof(*(slot->hotplug_slot)), + kmalloc(sizeof(*(slot->hotplug_slot)), GFP_KERNEL); if (!slot->hotplug_slot) goto error_slot; hotplug_slot = slot->hotplug_slot; + memset(hotplug_slot, 0, sizeof(struct hotplug_slot)); hotplug_slot->info = - kzalloc(sizeof(*(hotplug_slot->info)), + kmalloc(sizeof(*(hotplug_slot->info)), GFP_KERNEL); if (!hotplug_slot->info) goto error_hpslot; hotplug_slot_info = hotplug_slot->info; + memset(hotplug_slot_info, 0, + sizeof(struct hotplug_slot_info)); hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); if (!hotplug_slot->name) goto error_info; @@ -369,11 +373,12 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ u8 value; struct pci_dev *pdev; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL); if (!ctrl) { err("%s : out of memory\n", __FUNCTION__); goto err_out_none; } + memset(ctrl, 0, sizeof(struct controller)); pdev = dev->port; ctrl->pci_dev = pdev; @@ -434,7 +439,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ } /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ @@ -442,7 +447,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ if (rc) { /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); goto err_out_free_ctrl_slot; } else /* Wait for the command to complete */ @@ -450,7 +455,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return 0; diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 33d198768..83c4b8657 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -229,13 +229,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) static void set_slot_off(struct controller *ctrl, struct slot * pslot) { /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ if (POWER_CTRL(ctrl->ctrlcap)) { if (pslot->hpc_ops->power_off_slot(pslot)) { err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return; } wait_for_ctrl_irq (ctrl); @@ -249,14 +249,14 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) if (ATTN_LED(ctrl->ctrlcap)) { if (pslot->hpc_ops->set_attention_status(pslot, 1)) { err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return; } wait_for_ctrl_irq (ctrl); } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); } /** @@ -279,13 +279,13 @@ static int board_added(struct slot *p_slot) ctrl->slot_device_offset, hp_slot); /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); if (POWER_CTRL(ctrl->ctrlcap)) { /* Power on slot */ rc = p_slot->hpc_ops->power_on_slot(p_slot); if (rc) { - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return -1; } @@ -301,7 +301,7 @@ static int board_added(struct slot *p_slot) } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); /* Wait for ~1 second */ wait_for_ctrl_irq (ctrl); @@ -335,7 +335,7 @@ static int board_added(struct slot *p_slot) pci_fixup_device(pci_fixup_final, ctrl->pci_dev); if (PWR_LED(ctrl->ctrlcap)) { /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); p_slot->hpc_ops->green_led_on(p_slot); @@ -343,7 +343,7 @@ static int board_added(struct slot *p_slot) wait_for_ctrl_irq (ctrl); /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); } return 0; @@ -375,14 +375,14 @@ static int remove_board(struct slot *p_slot) dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); if (POWER_CTRL(ctrl->ctrlcap)) { /* power off slot */ rc = p_slot->hpc_ops->power_off_slot(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return rc; } /* Wait for the command to complete */ @@ -398,7 +398,7 @@ static int remove_board(struct slot *p_slot) } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); return 0; } @@ -445,7 +445,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { /* Wait for exclusive access to hardware */ - mutex_lock(&p_slot->ctrl->crit_sect); + down(&p_slot->ctrl->crit_sect); p_slot->hpc_ops->green_led_off(p_slot); @@ -453,7 +453,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) wait_for_ctrl_irq (p_slot->ctrl); /* Done with exclusive hardware access */ - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); } p_slot->state = STATIC_STATE; } @@ -495,7 +495,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot) if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { /* Wait for exclusive access to hardware */ - mutex_lock(&p_slot->ctrl->crit_sect); + down(&p_slot->ctrl->crit_sect); p_slot->hpc_ops->green_led_off(p_slot); @@ -503,7 +503,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot) wait_for_ctrl_irq (p_slot->ctrl); /* Done with exclusive hardware access */ - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); } p_slot->state = STATIC_STATE; } @@ -616,7 +616,7 @@ static void interrupt_event_handler(struct controller *ctrl) switch (p_slot->state) { case BLINKINGOFF_STATE: /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); if (PWR_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->green_led_on(p_slot); @@ -630,11 +630,11 @@ static void interrupt_event_handler(struct controller *ctrl) wait_for_ctrl_irq (ctrl); } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); break; case BLINKINGON_STATE: /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); if (PWR_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->green_led_off(p_slot); @@ -647,7 +647,7 @@ static void interrupt_event_handler(struct controller *ctrl) wait_for_ctrl_irq (ctrl); } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); break; default: @@ -676,7 +676,7 @@ static void interrupt_event_handler(struct controller *ctrl) } /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); /* blink green LED and turn off amber */ if (PWR_LED(ctrl->ctrlcap)) { @@ -693,7 +693,7 @@ static void interrupt_event_handler(struct controller *ctrl) } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); init_timer(&p_slot->task_event); p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ @@ -708,7 +708,7 @@ static void interrupt_event_handler(struct controller *ctrl) if (POWER_CTRL(ctrl->ctrlcap)) { dbg("power fault\n"); /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); + down(&ctrl->crit_sect); if (ATTN_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->set_attention_status(p_slot, 1); @@ -721,7 +721,7 @@ static void interrupt_event_handler(struct controller *ctrl) } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); + up(&ctrl->crit_sect); } } /***********SURPRISE REMOVAL********************/ @@ -756,19 +756,19 @@ int pciehp_enable_slot(struct slot *p_slot) int rc; /* Check to see if (latch closed, card present, power off) */ - mutex_lock(&p_slot->ctrl->crit_sect); + down(&p_slot->ctrl->crit_sect); rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); return 1; } if (MRL_SENS(p_slot->ctrl->ctrlcap)) { rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); return 1; } } @@ -777,11 +777,11 @@ int pciehp_enable_slot(struct slot *p_slot) rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); return 1; } } - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); @@ -806,13 +806,13 @@ int pciehp_disable_slot(struct slot *p_slot) return 1; /* Check to see if (latch closed, card present, power on) */ - mutex_lock(&p_slot->ctrl->crit_sect); + down(&p_slot->ctrl->crit_sect); if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) { ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); return 1; } } @@ -821,7 +821,7 @@ int pciehp_disable_slot(struct slot *p_slot) ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); return 1; } } @@ -830,12 +830,12 @@ int pciehp_disable_slot(struct slot *p_slot) ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); return 1; } } - mutex_unlock(&p_slot->ctrl->crit_sect); + up(&p_slot->ctrl->crit_sect); ret = remove_board(p_slot); update_slot_info(p_slot); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 6c14d9e46..77e530321 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -38,10 +38,7 @@ #include "../pci.h" #include "pciehp.h" -#include -#include -#include -#include + #ifdef DEBUG #define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */ #define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */ @@ -1239,76 +1236,6 @@ static struct hpc_ops pciehp_hpc_ops = { .check_lnk_status = hpc_check_lnk_status, }; -#ifdef CONFIG_ACPI -int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) -{ - acpi_status status; - acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); - struct pci_dev *pdev = dev; - struct pci_bus *parent; - struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; - - /* - * Per PCI firmware specification, we should run the ACPI _OSC - * method to get control of hotplug hardware before using it. - * If an _OSC is missing, we look for an OSHP to do the same thing. - * To handle different BIOS behavior, we look for _OSC and OSHP - * within the scope of the hotplug controller and its parents, upto - * the host bridge under which this controller exists. - */ - while (!handle) { - /* - * This hotplug controller was not listed in the ACPI name - * space at all. Try to get acpi handle of parent pci bus. - */ - if (!pdev || !pdev->bus->parent) - break; - parent = pdev->bus->parent; - dbg("Could not find %s in acpi namespace, trying parent\n", - pci_name(pdev)); - if (!parent->self) - /* Parent must be a host bridge */ - handle = acpi_get_pci_rootbridge_handle( - pci_domain_nr(parent), - parent->number); - else - handle = DEVICE_ACPI_HANDLE( - &(parent->self->dev)); - pdev = parent->self; - } - - while (handle) { - acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); - dbg("Trying to get hotplug control for %s \n", - (char *)string.pointer); - status = pci_osc_control_set(handle, - OSC_PCI_EXPRESS_NATIVE_HP_CONTROL); - if (status == AE_NOT_FOUND) - status = acpi_run_oshp(handle); - if (ACPI_SUCCESS(status)) { - dbg("Gained control for hotplug HW for pci %s (%s)\n", - pci_name(dev), (char *)string.pointer); - acpi_os_free(string.pointer); - return 0; - } - if (acpi_root_bridge(handle)) - break; - chandle = handle; - status = acpi_get_parent(chandle, &handle); - if (ACPI_FAILURE(status)) - break; - } - - err("Cannot get control of hotplug hardware for pci %s\n", - pci_name(dev)); - - acpi_os_free(string.pointer); - return -1; -} -#endif - - - int pcie_init(struct controller * ctrl, struct pcie_device *dev) { struct php_ctlr_state_s *php_ctlr, *p; @@ -1407,7 +1334,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) if (pci_enable_device(pdev)) goto abort_free_ctlr; - mutex_init(&ctrl->crit_sect); + init_MUTEX(&ctrl->crit_sect); /* setup wait queue */ init_waitqueue_head(&ctrl->queue); diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c new file mode 100644 index 000000000..2bdb30f68 --- /dev/null +++ b/drivers/pci/hotplug/pciehprm_acpi.c @@ -0,0 +1,257 @@ +/* + * PCIEHPRM ACPI: PHP Resource Manager for ACPI platform + * + * Copyright (C) 2003-2004 Intel Corporation + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "pciehp.h" + +#define METHOD_NAME__SUN "_SUN" +#define METHOD_NAME__HPP "_HPP" +#define METHOD_NAME_OSHP "OSHP" + +static u8 * acpi_path_name( acpi_handle handle) +{ + acpi_status status; + static u8 path_name[ACPI_PATHNAME_MAX]; + struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name }; + + memset(path_name, 0, sizeof (path_name)); + status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf); + + if (ACPI_FAILURE(status)) + return NULL; + else + return path_name; +} + +static acpi_status +acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) +{ + acpi_status status; + u8 nui[4]; + struct acpi_buffer ret_buf = { 0, NULL}; + union acpi_object *ext_obj, *package; + u8 *path_name = acpi_path_name(handle); + int i, len = 0; + + /* get _hpp */ + status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); + switch (status) { + case AE_BUFFER_OVERFLOW: + ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); + if (!ret_buf.pointer) { + err ("%s:%s alloc for _HPP fail\n", __FUNCTION__, + path_name); + return AE_NO_MEMORY; + } + status = acpi_evaluate_object(handle, METHOD_NAME__HPP, + NULL, &ret_buf); + if (ACPI_SUCCESS(status)) + break; + default: + if (ACPI_FAILURE(status)) { + dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__, + path_name, status); + return status; + } + } + + ext_obj = (union acpi_object *) ret_buf.pointer; + if (ext_obj->type != ACPI_TYPE_PACKAGE) { + err ("%s:%s _HPP obj not a package\n", __FUNCTION__, + path_name); + status = AE_ERROR; + goto free_and_return; + } + + len = ext_obj->package.count; + package = (union acpi_object *) ret_buf.pointer; + for ( i = 0; (i < len) || (i < 4); i++) { + ext_obj = (union acpi_object *) &package->package.elements[i]; + switch (ext_obj->type) { + case ACPI_TYPE_INTEGER: + nui[i] = (u8)ext_obj->integer.value; + break; + default: + err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__, + path_name); + status = AE_ERROR; + goto free_and_return; + } + } + + hpp->cache_line_size = nui[0]; + hpp->latency_timer = nui[1]; + hpp->enable_serr = nui[2]; + hpp->enable_perr = nui[3]; + + dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); + dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer); + dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); + dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); + +free_and_return: + kfree(ret_buf.pointer); + return status; +} + +static acpi_status acpi_run_oshp(acpi_handle handle) +{ + acpi_status status; + u8 *path_name = acpi_path_name(handle); + + /* run OSHP */ + status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); + if (ACPI_FAILURE(status)) { + dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name, + status); + } else { + dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name); + } + return status; +} + +static int is_root_bridge(acpi_handle handle) +{ + acpi_status status; + struct acpi_device_info *info; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + int i; + + status = acpi_get_object_info(handle, &buffer); + if (ACPI_SUCCESS(status)) { + info = buffer.pointer; + if ((info->valid & ACPI_VALID_HID) && + !strcmp(PCI_ROOT_HID_STRING, + info->hardware_id.value)) { + acpi_os_free(buffer.pointer); + return 1; + } + if (info->valid & ACPI_VALID_CID) { + for (i=0; i < info->compatibility_id.count; i++) { + if (!strcmp(PCI_ROOT_HID_STRING, + info->compatibility_id.id[i].value)) { + acpi_os_free(buffer.pointer); + return 1; + } + } + } + } + return 0; +} + +int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) +{ + acpi_status status; + acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); + struct pci_dev *pdev = dev; + struct pci_bus *parent; + u8 *path_name; + + /* + * Per PCI firmware specification, we should run the ACPI _OSC + * method to get control of hotplug hardware before using it. + * If an _OSC is missing, we look for an OSHP to do the same thing. + * To handle different BIOS behavior, we look for _OSC and OSHP + * within the scope of the hotplug controller and its parents, upto + * the host bridge under which this controller exists. + */ + while (!handle) { + /* + * This hotplug controller was not listed in the ACPI name + * space at all. Try to get acpi handle of parent pci bus. + */ + if (!pdev || !pdev->bus->parent) + break; + parent = pdev->bus->parent; + dbg("Could not find %s in acpi namespace, trying parent\n", + pci_name(pdev)); + if (!parent->self) + /* Parent must be a host bridge */ + handle = acpi_get_pci_rootbridge_handle( + pci_domain_nr(parent), + parent->number); + else + handle = DEVICE_ACPI_HANDLE( + &(parent->self->dev)); + pdev = parent->self; + } + + while (handle) { + path_name = acpi_path_name(handle); + dbg("Trying to get hotplug control for %s \n", path_name); + status = pci_osc_control_set(handle, + OSC_PCI_EXPRESS_NATIVE_HP_CONTROL); + if (status == AE_NOT_FOUND) + status = acpi_run_oshp(handle); + if (ACPI_SUCCESS(status)) { + dbg("Gained control for hotplug HW for pci %s (%s)\n", + pci_name(dev), path_name); + return 0; + } + if (is_root_bridge(handle)) + break; + chandle = handle; + status = acpi_get_parent(chandle, &handle); + if (ACPI_FAILURE(status)) + break; + } + + err("Cannot get control of hotplug hardware for pci %s\n", + pci_name(dev)); + return -1; +} + +void pciehp_get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp) +{ + acpi_status status = AE_NOT_FOUND; + struct pci_dev *pdev = dev; + + /* + * _HPP settings apply to all child buses, until another _HPP is + * encountered. If we don't find an _HPP for the input pci dev, + * look for it in the parent device scope since that would apply to + * this pci dev. If we don't find any _HPP, use hardcoded defaults + */ + while (pdev && (ACPI_FAILURE(status))) { + acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); + if (!handle) + break; + status = acpi_run_hpp(handle, hpp); + if (!(pdev->bus->parent)) + break; + /* Check if a parent object supports _HPP */ + pdev = pdev->bus->parent->self; + } +} + diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c new file mode 100644 index 000000000..29180dfe8 --- /dev/null +++ b/drivers/pci/hotplug/pciehprm_nonacpi.c @@ -0,0 +1,47 @@ +/* + * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform + * + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. + * Copyright (C) 2003-2004 Intel Corporation + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to , + * + */ + +#include +#include +#include +#include +#include +#include +#include "pciehp.h" + +void pciehp_get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp) +{ + return; +} + +int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) +{ + return 0; +} diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c index 0a46f5496..3194d51c6 100644 --- a/drivers/pci/hotplug/pcihp_skeleton.c +++ b/drivers/pci/hotplug/pcihp_skeleton.c @@ -37,12 +37,10 @@ #include #include "pci_hotplug.h" -#define SLOT_NAME_SIZE 10 struct slot { u8 number; struct hotplug_slot *hotplug_slot; struct list_head slot_list; - char name[SLOT_NAME_SIZE]; }; static LIST_HEAD(slot_list); @@ -235,10 +233,12 @@ static void release_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); kfree(slot); } +#define SLOT_NAME_SIZE 10 static void make_slot_name(struct slot *slot) { /* @@ -257,6 +257,7 @@ static int __init init_slots(void) struct slot *slot; struct hotplug_slot *hotplug_slot; struct hotplug_slot_info *info; + char *name; int retval = -ENOMEM; int i; @@ -265,23 +266,31 @@ static int __init init_slots(void) * with the pci_hotplug subsystem. */ for (i = 0; i < num_slots; ++i) { - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kmalloc(sizeof(struct slot), GFP_KERNEL); if (!slot) goto error; + memset(slot, 0, sizeof(struct slot)); - hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); + hotplug_slot = kmalloc(sizeof(struct hotplug_slot), + GFP_KERNEL); if (!hotplug_slot) goto error_slot; + memset(hotplug_slot, 0, sizeof (struct hotplug_slot)); slot->hotplug_slot = hotplug_slot; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); if (!info) goto error_hpslot; + memset(info, 0, sizeof (struct hotplug_slot_info)); hotplug_slot->info = info; + name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); + if (!name) + goto error_info; + hotplug_slot->name = name; + slot->number = i; - hotplug_slot->name = slot->name; hotplug_slot->private = slot; hotplug_slot->release = &release_slot; make_slot_name(slot); @@ -291,16 +300,16 @@ static int __init init_slots(void) * Initialize the slot info structure with some known * good values. */ - get_power_status(hotplug_slot, &info->power_status); - get_attention_status(hotplug_slot, &info->attention_status); - get_latch_status(hotplug_slot, &info->latch_status); - get_adapter_status(hotplug_slot, &info->adapter_status); + info->power_status = get_power_status(slot); + info->attention_status = get_attention_status(slot); + info->latch_status = get_latch_status(slot); + info->adapter_status = get_adapter_status(slot); dbg("registering slot %d\n", i); retval = pci_hp_register(slot->hotplug_slot); if (retval) { err("pci_hp_register failed with error %d\n", retval); - goto error_info; + goto error_name; } /* add slot to our internal list */ @@ -308,6 +317,8 @@ static int __init init_slots(void) } return 0; +error_name: + kfree(name); error_info: kfree(info); error_hpslot: diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 46825fee3..3eefe2cec 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include @@ -27,7 +27,7 @@ #include "rpaphp.h" #include "rpadlpar.h" -static DEFINE_MUTEX(rpadlpar_mutex); +static DECLARE_MUTEX(rpadlpar_sem); #define DLPAR_MODULE_NAME "rpadlpar_io" @@ -300,7 +300,7 @@ int dlpar_add_slot(char *drc_name) int node_type; int rc = -EIO; - if (mutex_lock_interruptible(&rpadlpar_mutex)) + if (down_interruptible(&rpadlpar_sem)) return -ERESTARTSYS; /* Find newly added node */ @@ -324,7 +324,7 @@ int dlpar_add_slot(char *drc_name) printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name); exit: - mutex_unlock(&rpadlpar_mutex); + up(&rpadlpar_sem); return rc; } @@ -417,7 +417,7 @@ int dlpar_remove_slot(char *drc_name) int node_type; int rc = 0; - if (mutex_lock_interruptible(&rpadlpar_mutex)) + if (down_interruptible(&rpadlpar_sem)) return -ERESTARTSYS; dn = find_dlpar_node(drc_name, &node_type); @@ -439,7 +439,7 @@ int dlpar_remove_slot(char *drc_name) } printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name); exit: - mutex_unlock(&rpadlpar_mutex); + up(&rpadlpar_sem); return rc; } diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 638004546..6e79f5675 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -360,6 +360,9 @@ static int __init rpaphp_init(void) while ((dn = of_find_node_by_type(dn, "pci"))) rpaphp_add_slot(dn); + if (!num_slots) + return -ENODEV; + return 0; } diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index b771196a6..78943e064 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -84,16 +84,19 @@ struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_ { struct slot *slot; - slot = kzalloc(sizeof(struct slot), GFP_KERNEL); + slot = kmalloc(sizeof (struct slot), GFP_KERNEL); if (!slot) goto error_nomem; - slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); + memset(slot, 0, sizeof (struct slot)); + slot->hotplug_slot = kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL); if (!slot->hotplug_slot) goto error_slot; - slot->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), + memset(slot->hotplug_slot, 0, sizeof (struct hotplug_slot)); + slot->hotplug_slot->info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL); if (!slot->hotplug_slot->info) goto error_hpslot; + memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info)); slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL); if (!slot->hotplug_slot->name) goto error_info; diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 8cb9abde7..a32ae82e5 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2005-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2005 Silicon Graphics, Inc. All rights reserved. * * This work was based on the 2.4/2.6 kernel development by Dick Reigner. * Work to add BIOS PROM support was completed by Mike Habeck. @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -82,7 +81,7 @@ static struct hotplug_slot_ops sn_hotplug_slot_ops = { .get_power_status = get_power_status, }; -static DEFINE_MUTEX(sn_hotplug_mutex); +static DECLARE_MUTEX(sn_hotplug_sem); static ssize_t path_show (struct hotplug_slot *bss_hotplug_slot, char *buf) @@ -231,13 +230,6 @@ static void sn_bus_free_data(struct pci_dev *dev) list_for_each_entry(child, &subordinate_bus->devices, bus_list) sn_bus_free_data(child); } - /* - * Some drivers may use dma accesses during the - * driver remove function. We release the sysdata - * areas after the driver remove functions have - * been called. - */ - sn_bus_store_sysdata(dev); sn_pci_unfixup_slot(dev); } @@ -347,7 +339,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) int rc; /* Serialize the Linux PCI infrastructure */ - mutex_lock(&sn_hotplug_mutex); + down(&sn_hotplug_sem); /* * Power-on and initialize the slot in the SN @@ -355,7 +347,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) */ rc = sn_slot_enable(bss_hotplug_slot, slot->device_num); if (rc) { - mutex_unlock(&sn_hotplug_mutex); + up(&sn_hotplug_sem); return rc; } @@ -363,7 +355,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) PCI_DEVFN(slot->device_num + 1, 0)); if (!num_funcs) { dev_dbg(slot->pci_bus->self, "no device in slot\n"); - mutex_unlock(&sn_hotplug_mutex); + up(&sn_hotplug_sem); return -ENODEV; } @@ -403,7 +395,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) if (new_ppb) pci_bus_add_devices(new_bus); - mutex_unlock(&sn_hotplug_mutex); + up(&sn_hotplug_sem); if (rc == 0) dev_dbg(slot->pci_bus->self, @@ -423,7 +415,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) int rc; /* Acquire update access to the bus */ - mutex_lock(&sn_hotplug_mutex); + down(&sn_hotplug_sem); /* is it okay to bring this slot down? */ rc = sn_slot_disable(bss_hotplug_slot, slot->device_num, @@ -437,6 +429,13 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) PCI_DEVFN(slot->device_num + 1, PCI_FUNC(func))); if (dev) { + /* + * Some drivers may use dma accesses during the + * driver remove function. We release the sysdata + * areas after the driver remove functions have + * been called. + */ + sn_bus_store_sysdata(dev); sn_bus_free_data(dev); pci_remove_bus_device(dev); pci_dev_put(dev); @@ -451,7 +450,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) PCI_REQ_SLOT_DISABLE); leaving: /* Release the bus lock */ - mutex_unlock(&sn_hotplug_mutex); + up(&sn_hotplug_sem); return rc; } @@ -463,9 +462,9 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot, struct pcibus_info *pcibus_info; pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus); - mutex_lock(&sn_hotplug_mutex); + down(&sn_hotplug_sem); *value = pcibus_info->pbi_enabled_devices & (1 << slot->device_num); - mutex_unlock(&sn_hotplug_mutex); + up(&sn_hotplug_sem); return 0; } diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 5c70f4390..7d6f521d0 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -33,7 +33,6 @@ #include #include #include /* signal_pending(), struct timer_list */ -#include #include "pci_hotplug.h" @@ -46,7 +45,6 @@ extern int shpchp_poll_mode; extern int shpchp_poll_time; extern int shpchp_debug; -extern struct workqueue_struct *shpchp_wq; /*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ #define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) @@ -54,8 +52,10 @@ extern struct workqueue_struct *shpchp_wq; #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) -#define SLOT_NAME_SIZE 10 +#define SLOT_MAGIC 0x67267321 struct slot { + u32 magic; + struct slot *next; u8 bus; u8 device; u16 status; @@ -70,27 +70,26 @@ struct slot { struct hpc_ops *hpc_ops; struct hotplug_slot *hotplug_slot; struct list_head slot_list; - char name[SLOT_NAME_SIZE]; - struct work_struct work; /* work for button event */ - struct mutex lock; }; struct event_info { u32 event_type; - struct slot *p_slot; - struct work_struct work; + u8 hp_slot; }; struct controller { - struct mutex crit_sect; /* critical section mutex */ - struct mutex cmd_lock; /* command lock */ + struct controller *next; + struct semaphore crit_sect; /* critical section semaphore */ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; - struct list_head slot_list; + struct pci_bus *pci_bus; + struct event_info event_queue[10]; + struct slot *slot; struct hpc_ops *hpc_ops; wait_queue_head_t queue; /* sleep & wake process */ + u8 next_event; u8 bus; u8 device; u8 function; @@ -106,6 +105,12 @@ struct controller { volatile int cmd_busy; }; +struct hotplug_params { + u8 cache_line_size; + u8 latency_timer; + u8 enable_serr; + u8 enable_perr; +}; /* Define AMD SHPC ID */ #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 @@ -175,8 +180,11 @@ struct controller { /* sysfs functions for the hotplug controller info */ extern void shpchp_create_ctrl_files (struct controller *ctrl); -extern int shpchp_sysfs_enable_slot(struct slot *slot); -extern int shpchp_sysfs_disable_slot(struct slot *slot); +/* controller functions */ +extern int shpchp_event_start_thread(void); +extern void shpchp_event_stop_thread(void); +extern int shpchp_enable_slot(struct slot *slot); +extern int shpchp_disable_slot(struct slot *slot); extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id); extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id); @@ -187,28 +195,16 @@ extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id); extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); extern int shpchp_configure_device(struct slot *p_slot); extern int shpchp_unconfigure_device(struct slot *p_slot); +extern void get_hp_hw_control_from_firmware(struct pci_dev *dev); +extern void get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp); +extern int shpchprm_get_physical_slot_number(struct controller *ctrl, + u32 *sun, u8 busnum, u8 devnum); extern void shpchp_remove_ctrl_files(struct controller *ctrl); -extern void cleanup_slots(struct controller *ctrl); -extern void queue_pushbutton_work(void *data); -#ifdef CONFIG_ACPI -static inline int get_hp_params_from_firmware(struct pci_dev *dev, - struct hotplug_params *hpp) -{ - if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) - return -ENODEV; - return 0; -} -#define get_hp_hw_control_from_firmware(pdev) \ - do { \ - if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \ - acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \ - } while (0) -#else -#define get_hp_params_from_firmware(dev, hpp) (-ENODEV) -#define get_hp_hw_control_from_firmware(dev) do { } while (0) -#endif +/* Global variables */ +extern struct controller *shpchp_ctrl_list; struct ctrl_reg { volatile u32 base_offset; @@ -290,6 +286,10 @@ static inline int slot_paranoia_check (struct slot *slot, const char *function) dbg("%s - slot == NULL", function); return -1; } + if (slot->magic != SLOT_MAGIC) { + dbg("%s - bad magic number for slot", function); + return -1; + } if (!slot->hotplug_slot) { dbg("%s - slot->hotplug_slot == NULL!", function); return -1; @@ -314,19 +314,44 @@ static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const ch static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device) { - struct slot *slot; + struct slot *p_slot, *tmp_slot = NULL; if (!ctrl) return NULL; - list_for_each_entry(slot, &ctrl->slot_list, slot_list) { - if (slot->device == device) - return slot; + p_slot = ctrl->slot; + + while (p_slot && (p_slot->device != device)) { + tmp_slot = p_slot; + p_slot = p_slot->next; } + if (p_slot == NULL) { + err("ERROR: shpchp_find_slot device=0x%x\n", device); + p_slot = tmp_slot; + } + + return (p_slot); +} + +static inline int wait_for_ctrl_irq (struct controller *ctrl) +{ + DECLARE_WAITQUEUE(wait, current); + int retval = 0; + + add_wait_queue(&ctrl->queue, &wait); - err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); + if (!shpchp_poll_mode) { + /* Sleep for up to 1 second */ + msleep_interruptible(1000); + } else { + /* Sleep for up to 2 seconds */ + msleep_interruptible(2000); + } + remove_wait_queue(&ctrl->queue, &wait); + if (signal_pending(current)) + retval = -EINTR; - return NULL; + return retval; } static inline void amd_pogo_errata_save_misc_reg(struct slot *p_slot) @@ -402,6 +427,13 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot) pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); } +#define SLOT_NAME_SIZE 10 + +static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) +{ + snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number); +} + enum php_ctlr_type { PCI, ISA, diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 3be4d492c..a2b3f0010 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -32,14 +32,13 @@ #include #include #include -#include #include "shpchp.h" /* Global variables */ int shpchp_debug; int shpchp_poll_mode; int shpchp_poll_time; -struct workqueue_struct *shpchp_wq; +struct controller *shpchp_ctrl_list; /* = NULL */ #define DRIVER_VERSION "0.4" #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " @@ -58,6 +57,7 @@ MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds"); #define SHPC_MODULE_NAME "shpchp" +static int shpc_start_thread (void); static int set_attention_status (struct hotplug_slot *slot, u8 value); static int enable_slot (struct hotplug_slot *slot); static int disable_slot (struct hotplug_slot *slot); @@ -94,120 +94,107 @@ static void release_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); kfree(slot); } -static void make_slot_name(struct slot *slot) -{ - snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d", - slot->bus, slot->number); -} - - - - -static int -shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, - u8 busnum, u8 devnum) -{ - int offset = devnum - ctrl->slot_device_offset; - - dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, - ctrl->slot_num_inc, offset); - *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset); - return 0; -} - - - static int init_slots(struct controller *ctrl) { - struct slot *slot; - struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *info; - int retval = -ENOMEM; - int i; - u32 sun; - - for (i = 0; i < ctrl->num_slots; i++) { - slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) + struct slot *new_slot; + u8 number_of_slots; + u8 slot_device; + u32 slot_number, sun; + int result = -ENOMEM; + + number_of_slots = ctrl->num_slots; + slot_device = ctrl->slot_device_offset; + slot_number = ctrl->first_slot; + + while (number_of_slots) { + new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL); + if (!new_slot) goto error; - hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); - if (!hotplug_slot) + memset(new_slot, 0, sizeof(struct slot)); + new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL); + if (!new_slot->hotplug_slot) goto error_slot; - slot->hotplug_slot = hotplug_slot; + memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot)); - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) + new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL); + if (!new_slot->hotplug_slot->info) goto error_hpslot; - hotplug_slot->info = info; - - hotplug_slot->name = slot->name; + memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info)); + new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL); + if (!new_slot->hotplug_slot->name) + goto error_info; - slot->hp_slot = i; - slot->ctrl = ctrl; - slot->bus = ctrl->slot_bus; - slot->device = ctrl->slot_device_offset + i; - slot->hpc_ops = ctrl->hpc_ops; - mutex_init(&slot->lock); + new_slot->magic = SLOT_MAGIC; + new_slot->ctrl = ctrl; + new_slot->bus = ctrl->slot_bus; + new_slot->device = slot_device; + new_slot->hpc_ops = ctrl->hpc_ops; if (shpchprm_get_physical_slot_number(ctrl, &sun, - slot->bus, slot->device)) - goto error_info; + new_slot->bus, new_slot->device)) + goto error_name; - slot->number = sun; - INIT_WORK(&slot->work, queue_pushbutton_work, slot); + new_slot->number = sun; + new_slot->hp_slot = slot_device - ctrl->slot_device_offset; /* register this slot with the hotplug pci core */ - hotplug_slot->private = slot; - hotplug_slot->release = &release_slot; - make_slot_name(slot); - hotplug_slot->ops = &shpchp_hotplug_slot_ops; - - get_power_status(hotplug_slot, &info->power_status); - get_attention_status(hotplug_slot, &info->attention_status); - get_latch_status(hotplug_slot, &info->latch_status); - get_adapter_status(hotplug_slot, &info->adapter_status); - - dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " - "slot_device_offset=%x\n", slot->bus, slot->device, - slot->hp_slot, slot->number, ctrl->slot_device_offset); - retval = pci_hp_register(slot->hotplug_slot); - if (retval) { - err("pci_hp_register failed with error %d\n", retval); - goto error_info; + new_slot->hotplug_slot->private = new_slot; + new_slot->hotplug_slot->release = &release_slot; + make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot); + new_slot->hotplug_slot->ops = &shpchp_hotplug_slot_ops; + + new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status)); + new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status)); + new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status)); + new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status)); + + dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n", new_slot->bus, + new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset); + result = pci_hp_register (new_slot->hotplug_slot); + if (result) { + err ("pci_hp_register failed with error %d\n", result); + goto error_name; } - list_add(&slot->slot_list, &ctrl->slot_list); + new_slot->next = ctrl->slot; + ctrl->slot = new_slot; + + number_of_slots--; + slot_device++; + slot_number += ctrl->slot_num_inc; } return 0; + +error_name: + kfree(new_slot->hotplug_slot->name); error_info: - kfree(info); + kfree(new_slot->hotplug_slot->info); error_hpslot: - kfree(hotplug_slot); + kfree(new_slot->hotplug_slot); error_slot: - kfree(slot); + kfree(new_slot); error: - return retval; + return result; } -void cleanup_slots(struct controller *ctrl) +static void cleanup_slots(struct controller *ctrl) { - struct list_head *tmp; - struct list_head *next; - struct slot *slot; - - list_for_each_safe(tmp, next, &ctrl->slot_list) { - slot = list_entry(tmp, struct slot, slot_list); - list_del(&slot->slot_list); - cancel_delayed_work(&slot->work); - flush_scheduled_work(); - flush_workqueue(shpchp_wq); - pci_hp_deregister(slot->hotplug_slot); + struct slot *old_slot, *next_slot; + + old_slot = ctrl->slot; + ctrl->slot = NULL; + + while (old_slot) { + next_slot = old_slot->next; + pci_hp_deregister(old_slot->hotplug_slot); + old_slot = next_slot; } } @@ -220,12 +207,9 @@ static int get_ctlr_slot_config(struct controller *ctrl) int rc; int flags; - rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, - &first_device_num, &physical_slot_num, - &updown, &flags); + rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &updown, &flags); if (rc) { - err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", - __FUNCTION__, ctrl->bus, ctrl->device); + err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device); return -1; } @@ -234,19 +218,19 @@ static int get_ctlr_slot_config(struct controller *ctrl) ctrl->first_slot = physical_slot_num; ctrl->slot_num_inc = updown; /* either -1 or 1 */ - dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d " - "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num, - physical_slot_num, updown, ctrl->bus, ctrl->device); + dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d (%x:%x)\n", + __FUNCTION__, num_ctlr_slots, first_device_num, physical_slot_num, updown, ctrl->bus, ctrl->device); return 0; } + /* * set_attention_status - Turns the Amber LED for a slot on, off or blink */ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -256,27 +240,29 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) return 0; } + static int enable_slot (struct hotplug_slot *hotplug_slot) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - return shpchp_sysfs_enable_slot(slot); + return shpchp_enable_slot(slot); } + static int disable_slot (struct hotplug_slot *hotplug_slot) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - return shpchp_sysfs_disable_slot(slot); + return shpchp_disable_slot(slot); } static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -290,7 +276,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -304,7 +290,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -318,7 +304,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -332,7 +318,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -344,11 +330,11 @@ static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - + retval = slot->hpc_ops->get_max_bus_speed(slot, value); if (retval < 0) *value = PCI_SPEED_UNKNOWN; @@ -358,11 +344,11 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - + retval = slot->hpc_ops->get_cur_bus_speed(slot, value); if (retval < 0) *value = PCI_SPEED_UNKNOWN; @@ -386,54 +372,61 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int rc; struct controller *ctrl; struct slot *t_slot; - int first_device_num; /* first PCI device number */ - int num_ctlr_slots; /* number of slots implemented */ + int first_device_num; /* first PCI device number supported by this SHPC */ + int num_ctlr_slots; /* number of slots supported by this SHPC */ if (!is_shpc_capable(pdev)) return -ENODEV; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL); if (!ctrl) { err("%s : out of memory\n", __FUNCTION__); goto err_out_none; } - INIT_LIST_HEAD(&ctrl->slot_list); + memset(ctrl, 0, sizeof(struct controller)); rc = shpc_init(ctrl, pdev); if (rc) { - dbg("%s: controller initialization failed\n", - SHPC_MODULE_NAME); + dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME); goto err_out_free_ctrl; } pci_set_drvdata(pdev, ctrl); + ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL); + if (!ctrl->pci_bus) { + err("out of memory\n"); + rc = -ENOMEM; + goto err_out_unmap_mmio_region; + } + + memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); ctrl->bus = pdev->bus->number; ctrl->slot_bus = pdev->subordinate->number; + ctrl->device = PCI_SLOT(pdev->devfn); ctrl->function = PCI_FUNC(pdev->devfn); - - dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", - ctrl->bus, ctrl->device, ctrl->function, pdev->irq); + dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", ctrl->bus, ctrl->device, ctrl->function, pdev->irq); /* - * Save configuration headers for this and subordinate PCI buses + * Save configuration headers for this and subordinate PCI buses */ + rc = get_ctlr_slot_config(ctrl); if (rc) { err(msg_initialization_err, rc); - goto err_out_release_ctlr; + goto err_out_free_ctrl_bus; } first_device_num = ctrl->slot_device_offset; num_ctlr_slots = ctrl->num_slots; ctrl->add_support = 1; - + /* Setup the slot information structures */ rc = init_slots(ctrl); if (rc) { err(msg_initialization_err, 6); - goto err_out_release_ctlr; + goto err_out_free_ctrl_slot; } /* Now hpc_functions (slot->hpc_ops->functions) are ready */ @@ -444,16 +437,30 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot); if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) { - err(SHPC_MODULE_NAME ": Can't get current bus speed. " - "Set to 33MHz PCI.\n"); + err(SHPC_MODULE_NAME ": Can't get current bus speed. Set to 33MHz PCI.\n"); ctrl->speed = PCI_SPEED_33MHz; } + /* Finish setting up the hot plug ctrl device */ + ctrl->next_event = 0; + + if (!shpchp_ctrl_list) { + shpchp_ctrl_list = ctrl; + ctrl->next = NULL; + } else { + ctrl->next = shpchp_ctrl_list; + shpchp_ctrl_list = ctrl; + } + shpchp_create_ctrl_files(ctrl); return 0; -err_out_release_ctlr: +err_out_free_ctrl_slot: + cleanup_slots(ctrl); +err_out_free_ctrl_bus: + kfree(ctrl->pci_bus); +err_out_unmap_mmio_region: ctrl->hpc_ops->release_ctlr(ctrl); err_out_free_ctrl: kfree(ctrl); @@ -461,28 +468,74 @@ err_out_none: return -ENODEV; } -static void shpc_remove(struct pci_dev *dev) + +static int shpc_start_thread(void) { - struct controller *ctrl = pci_get_drvdata(dev); + int retval = 0; + + dbg("Initialize + Start the notification/polling mechanism \n"); + + retval = shpchp_event_start_thread(); + if (retval) { + dbg("shpchp_event_start_thread() failed\n"); + return retval; + } + + return retval; +} + +static void __exit unload_shpchpd(void) +{ + struct controller *ctrl; + struct controller *tctrl; + + ctrl = shpchp_ctrl_list; + + while (ctrl) { + shpchp_remove_ctrl_files(ctrl); + cleanup_slots(ctrl); + + kfree (ctrl->pci_bus); + ctrl->hpc_ops->release_ctlr(ctrl); + + tctrl = ctrl; + ctrl = ctrl->next; + + kfree(tctrl); + } + + /* Stop the notification mechanism */ + shpchp_event_stop_thread(); - shpchp_remove_ctrl_files(ctrl); - ctrl->hpc_ops->release_ctlr(ctrl); - kfree(ctrl); } + static struct pci_device_id shpcd_pci_tbl[] = { - {PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0)}, + { + .class = ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), + .class_mask = ~0, + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { /* end: all zeroes */ } }; + MODULE_DEVICE_TABLE(pci, shpcd_pci_tbl); + + static struct pci_driver shpc_driver = { .name = SHPC_MODULE_NAME, .id_table = shpcd_pci_tbl, .probe = shpc_probe, - .remove = shpc_remove, + /* remove: shpc_remove_one, */ }; + + static int __init shpcd_init(void) { int retval = 0; @@ -491,15 +544,17 @@ static int __init shpcd_init(void) shpchp_poll_mode = 1; #endif - shpchp_wq = create_singlethread_workqueue("shpchpd"); - if (!shpchp_wq) - return -ENOMEM; + retval = shpc_start_thread(); + if (retval) + goto error_hpc_init; retval = pci_register_driver(&shpc_driver); dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + +error_hpc_init: if (retval) { - destroy_workqueue(shpchp_wq); + shpchp_event_stop_thread(); } return retval; } @@ -507,8 +562,10 @@ static int __init shpcd_init(void) static void __exit shpcd_cleanup(void) { dbg("unload_shpchpd()\n"); + unload_shpchpd(); + pci_unregister_driver(&shpc_driver); - destroy_workqueue(shpchp_wq); + info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); } diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 4e6381481..643252d9b 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -32,50 +32,65 @@ #include #include #include -#include #include "../pci.h" #include "shpchp.h" -static void interrupt_event_handler(void *data); -static int shpchp_enable_slot(struct slot *p_slot); -static int shpchp_disable_slot(struct slot *p_slot); +static void interrupt_event_handler(struct controller *ctrl); -static int queue_interrupt_event(struct slot *p_slot, u32 event_type) -{ - struct event_info *info; - - info = kmalloc(sizeof(*info), GFP_ATOMIC); - if (!info) - return -ENOMEM; - - info->event_type = event_type; - info->p_slot = p_slot; - INIT_WORK(&info->work, interrupt_event_handler, info); - - schedule_work(&info->work); - - return 0; -} +static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ +static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ +static int event_finished; +static unsigned long pushbutton_pending; /* = 0 */ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) { struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; - u32 event_type; + u8 rc = 0; + u8 getstatus; + struct event_info *taskInfo; /* Attention Button Change */ dbg("shpchp: Attention button interrupt received.\n"); + /* This is the structure that tells the worker thread what to do */ + taskInfo = &(ctrl->event_queue[ctrl->next_event]); p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); + p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); + p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + + ctrl->next_event = (ctrl->next_event + 1) % 10; + taskInfo->hp_slot = hp_slot; + + rc++; /* * Button pressed - See if need to TAKE ACTION!!! */ info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); - event_type = INT_BUTTON_PRESS; + taskInfo->event_type = INT_BUTTON_PRESS; + + if ((p_slot->state == BLINKINGON_STATE) + || (p_slot->state == BLINKINGOFF_STATE)) { + /* Cancel if we are still blinking; this means that we press the + * attention again before the 5 sec. limit expires to cancel hot-add + * or hot-remove + */ + taskInfo->event_type = INT_BUTTON_CANCEL; + info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot); + } else if ((p_slot->state == POWERON_STATE) + || (p_slot->state == POWEROFF_STATE)) { + /* Ignore if the slot is on power-on or power-off state; this + * means that the previous attention button action to hot-add or + * hot-remove is undergoing + */ + taskInfo->event_type = INT_BUTTON_IGNORE; + info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot); + } - queue_interrupt_event(p_slot, event_type); + if (rc) + up(&event_semaphore); /* signal event thread that new event is posted */ return 0; @@ -85,12 +100,21 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) { struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; + u8 rc = 0; u8 getstatus; - u32 event_type; + struct event_info *taskInfo; /* Switch Change */ dbg("shpchp: Switch interrupt received.\n"); + /* This is the structure that tells the worker thread + * what to do + */ + taskInfo = &(ctrl->event_queue[ctrl->next_event]); + ctrl->next_event = (ctrl->next_event + 1) % 10; + taskInfo->hp_slot = hp_slot; + + rc++; p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); @@ -102,9 +126,9 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) * Switch opened */ info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); - event_type = INT_SWITCH_OPEN; + taskInfo->event_type = INT_SWITCH_OPEN; if (p_slot->pwr_save && p_slot->presence_save) { - event_type = INT_POWER_FAULT; + taskInfo->event_type = INT_POWER_FAULT; err("Surprise Removal of card\n"); } } else { @@ -112,23 +136,34 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) * Switch closed */ info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); - event_type = INT_SWITCH_CLOSE; + taskInfo->event_type = INT_SWITCH_CLOSE; } - queue_interrupt_event(p_slot, event_type); + if (rc) + up(&event_semaphore); /* signal event thread that new event is posted */ - return 1; + return rc; } u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) { struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; - u32 event_type; + u8 rc = 0; + /*u8 temp_byte;*/ + struct event_info *taskInfo; /* Presence Change */ dbg("shpchp: Presence/Notify input change.\n"); + /* This is the structure that tells the worker thread + * what to do + */ + taskInfo = &(ctrl->event_queue[ctrl->next_event]); + ctrl->next_event = (ctrl->next_event + 1) % 10; + taskInfo->hp_slot = hp_slot; + + rc++; p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); /* @@ -140,29 +175,39 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) * Card Present */ info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); - event_type = INT_PRESENCE_ON; + taskInfo->event_type = INT_PRESENCE_ON; } else { /* * Not Present */ info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); - event_type = INT_PRESENCE_OFF; + taskInfo->event_type = INT_PRESENCE_OFF; } - queue_interrupt_event(p_slot, event_type); + if (rc) + up(&event_semaphore); /* signal event thread that new event is posted */ - return 1; + return rc; } u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) { struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; - u32 event_type; + u8 rc = 0; + struct event_info *taskInfo; /* Power fault */ dbg("shpchp: Power fault interrupt received.\n"); + /* This is the structure that tells the worker thread + * what to do + */ + taskInfo = &(ctrl->event_queue[ctrl->next_event]); + ctrl->next_event = (ctrl->next_event + 1) % 10; + taskInfo->hp_slot = hp_slot; + + rc++; p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { @@ -171,21 +216,21 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) */ info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); p_slot->status = 0x00; - event_type = INT_POWER_FAULT_CLEAR; + taskInfo->event_type = INT_POWER_FAULT_CLEAR; } else { /* * Power fault */ info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); - event_type = INT_POWER_FAULT; + taskInfo->event_type = INT_POWER_FAULT; /* set power fault status for this board */ p_slot->status = 0xFF; info("power fault bit %x set\n", hp_slot); } + if (rc) + up(&event_semaphore); /* signal event thread that new event is posted */ - queue_interrupt_event(p_slot, event_type); - - return 1; + return rc; } /* The following routines constitute the bulk of the @@ -197,11 +242,21 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, int rc = 0; dbg("%s: change to speed %d\n", __FUNCTION__, speed); + down(&ctrl->crit_sect); if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) { - err("%s: Issue of set bus speed mode command failed\n", - __FUNCTION__); + err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } + + if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { + err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", + __FUNCTION__); + err("%s: Error code (%d)\n", __FUNCTION__, rc); + up(&ctrl->crit_sect); + return WRONG_BUS_FREQUENCY; + } + up(&ctrl->crit_sect); return rc; } @@ -210,26 +265,33 @@ static int fix_bus_speed(struct controller *ctrl, struct slot *pslot, enum pci_bus_speed msp) { int rc = 0; - - /* - * If other slots on the same bus are occupied, we cannot - * change the bus speed. - */ - if (flag) { - if (asp < bsp) { - err("%s: speed of bus %x and adapter %x mismatch\n", - __FUNCTION__, bsp, asp); - rc = WRONG_BUS_FREQUENCY; + + if (flag != 0) { /* Other slots on the same bus are occupied */ + if ( asp < bsp ) { + err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bsp, asp); + return WRONG_BUS_FREQUENCY; } - return rc; - } - - if (asp < msp) { - if (bsp != asp) - rc = change_bus_speed(ctrl, pslot, asp); } else { - if (bsp != msp) - rc = change_bus_speed(ctrl, pslot, msp); + /* Other slots on the same bus are empty */ + if (msp == bsp) { + /* if adapter_speed >= bus_speed, do nothing */ + if (asp < bsp) { + /* + * Try to lower bus speed to accommodate the adapter if other slots + * on the same controller are empty + */ + if ((rc = change_bus_speed(ctrl, pslot, asp))) + return rc; + } + } else { + if (asp < msp) { + if ((rc = change_bus_speed(ctrl, pslot, asp))) + return rc; + } else { + if ((rc = change_bus_speed(ctrl, pslot, msp))) + return rc; + } + } } return rc; } @@ -246,7 +308,8 @@ static int board_added(struct slot *p_slot) u8 hp_slot; u8 slots_not_empty = 0; int rc = 0; - enum pci_bus_speed asp, bsp, msp; + enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed; + u8 pi, mode; struct controller *ctrl = p_slot->ctrl; hp_slot = p_slot->device - ctrl->slot_device_offset; @@ -255,68 +318,187 @@ static int board_added(struct slot *p_slot) __FUNCTION__, p_slot->device, ctrl->slot_device_offset, hp_slot); + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + /* Power on slot without connecting to bus */ rc = p_slot->hpc_ops->power_on_slot(p_slot); if (rc) { err("%s: Failed to power on slot\n", __FUNCTION__); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); return -1; } + rc = p_slot->hpc_ops->check_cmd_status(ctrl); + if (rc) { + err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + return -1; + } + + if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { if (slots_not_empty) return WRONG_BUS_FREQUENCY; if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } + if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { + err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", + __FUNCTION__); + err("%s: Error code (%d)\n", __FUNCTION__, rc); + up(&ctrl->crit_sect); + return WRONG_BUS_FREQUENCY; + } /* turn on board, blink green LED, turn off Amber LED */ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return rc; } + + if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { + err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); + up(&ctrl->crit_sect); + return rc; + } } - rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp); - if (rc) { - err("%s: Can't get adapter speed or bus mode mismatch\n", - __FUNCTION__); + rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed); + /* 0 = PCI 33Mhz, 1 = PCI 66 Mhz, 2 = PCI-X 66 PA, 4 = PCI-X 66 ECC, */ + /* 5 = PCI-X 133 PA, 7 = PCI-X 133 ECC, 0xa = PCI-X 133 Mhz 266, */ + /* 0xd = PCI-X 133 Mhz 533 */ + /* This encoding is different from the one used in cur_bus_speed & */ + /* max_bus_speed */ + + if (rc || adapter_speed == PCI_SPEED_UNKNOWN) { + err("%s: Can't get adapter speed or bus mode mismatch\n", __FUNCTION__); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } - rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp); - if (rc) { + rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bus_speed); + if (rc || bus_speed == PCI_SPEED_UNKNOWN) { err("%s: Can't get bus operation speed\n", __FUNCTION__); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } - rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &msp); - if (rc) { + rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &max_bus_speed); + if (rc || max_bus_speed == PCI_SPEED_UNKNOWN) { err("%s: Can't get max bus operation speed\n", __FUNCTION__); - msp = bsp; + max_bus_speed = bus_speed; + } + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + + if ((rc = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) { + err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__); + pi = 1; } /* Check if there are other slots or devices on the same bus */ if (!list_empty(&ctrl->pci_dev->subordinate->devices)) slots_not_empty = 1; - dbg("%s: slots_not_empty %d, adapter_speed %d, bus_speed %d, " - "max_bus_speed %d\n", __FUNCTION__, slots_not_empty, asp, - bsp, msp); + dbg("%s: slots_not_empty %d, pi %d\n", __FUNCTION__, + slots_not_empty, pi); + dbg("adapter_speed %d, bus_speed %d, max_bus_speed %d\n", + adapter_speed, bus_speed, max_bus_speed); - rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, asp, bsp, msp); - if (rc) - return rc; + if (pi == 2) { + dbg("%s: In PI = %d\n", __FUNCTION__, pi); + if ((rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode))) { + err("%s: Can't get Mode1_ECC, set mode to 0\n", __FUNCTION__); + mode = 0; + } + + switch (adapter_speed) { + case PCI_SPEED_133MHz_PCIX_533: + case PCI_SPEED_133MHz_PCIX_266: + if ((bus_speed != adapter_speed) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; + break; + case PCI_SPEED_133MHz_PCIX_ECC: + case PCI_SPEED_133MHz_PCIX: + if (mode) { /* Bus - Mode 1 ECC */ + if ((bus_speed != 0x7) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; + } else { + if ((bus_speed != 0x4) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; + } + break; + case PCI_SPEED_66MHz_PCIX_ECC: + case PCI_SPEED_66MHz_PCIX: + if (mode) { /* Bus - Mode 1 ECC */ + if ((bus_speed != 0x5) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; + } else { + if ((bus_speed != 0x2) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; + } + break; + case PCI_SPEED_66MHz: + if ((bus_speed != 0x1) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; + break; + case PCI_SPEED_33MHz: + if (bus_speed > 0x0) { + if (slots_not_empty == 0) { + if ((rc = change_bus_speed(ctrl, p_slot, adapter_speed))) + return rc; + } else { + err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); + return WRONG_BUS_FREQUENCY; + } + } + break; + default: + err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); + return WRONG_BUS_FREQUENCY; + } + } else { + /* If adpater_speed == bus_speed, nothing to do here */ + dbg("%s: In PI = %d\n", __FUNCTION__, pi); + if ((adapter_speed != bus_speed) && + ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) + return rc; + } + down(&ctrl->crit_sect); /* turn on board, blink green LED, turn off Amber LED */ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return rc; } + if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { + err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); + up(&ctrl->crit_sect); + return rc; + } + + up(&ctrl->crit_sect); + /* Wait for ~1 second */ - msleep(1000); + wait_for_ctrl_irq (ctrl); dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status); /* Check for a power fault */ @@ -338,18 +520,40 @@ static int board_added(struct slot *p_slot) p_slot->is_a_board = 0x01; p_slot->pwr_save = 1; + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + p_slot->hpc_ops->green_led_on(p_slot); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + return 0; err_exit: + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + /* turn off slot, turn on Amber LED, turn off Green LED */ rc = p_slot->hpc_ops->slot_disable(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + return rc; + } + + rc = p_slot->hpc_ops->check_cmd_status(ctrl); + if (rc) { + err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); return rc; } + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + return(rc); } @@ -376,19 +580,37 @@ static int remove_board(struct slot *p_slot) if (p_slot->is_a_board) p_slot->status = 0x01; + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + /* turn off slot, turn on Amber LED, turn off Green LED */ rc = p_slot->hpc_ops->slot_disable(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); return rc; } + + rc = p_slot->hpc_ops->check_cmd_status(ctrl); + if (rc) { + err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + return rc; + } rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); if (rc) { err("%s: Issue of Set Attention command failed\n", __FUNCTION__); + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); return rc; } + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + p_slot->pwr_save = 0; p_slot->is_a_board = 0; @@ -396,10 +618,13 @@ static int remove_board(struct slot *p_slot) } -struct pushbutton_work_info { - struct slot *p_slot; - struct work_struct work; -}; +static void pushbutton_helper_thread (unsigned long data) +{ + pushbutton_pending = data; + + up(&event_semaphore); +} + /** * shpchp_pushbutton_thread @@ -408,63 +633,96 @@ struct pushbutton_work_info { * Handles all pending events and exits. * */ -static void shpchp_pushbutton_thread(void *data) +static void shpchp_pushbutton_thread (unsigned long slot) { - struct pushbutton_work_info *info = data; - struct slot *p_slot = info->p_slot; + struct slot *p_slot = (struct slot *) slot; + u8 getstatus; + + pushbutton_pending = 0; + + if (!p_slot) { + dbg("%s: Error! slot NULL\n", __FUNCTION__); + return; + } + + p_slot->hpc_ops->get_power_status(p_slot, &getstatus); + if (getstatus) { + p_slot->state = POWEROFF_STATE; - mutex_lock(&p_slot->lock); - switch (p_slot->state) { - case POWEROFF_STATE: - mutex_unlock(&p_slot->lock); shpchp_disable_slot(p_slot); - mutex_lock(&p_slot->lock); p_slot->state = STATIC_STATE; - break; - case POWERON_STATE: - mutex_unlock(&p_slot->lock); - if (shpchp_enable_slot(p_slot)) + } else { + p_slot->state = POWERON_STATE; + + if (shpchp_enable_slot(p_slot)) { + /* Wait for exclusive access to hardware */ + down(&p_slot->ctrl->crit_sect); + p_slot->hpc_ops->green_led_off(p_slot); - mutex_lock(&p_slot->lock); + + /* Done with exclusive hardware access */ + up(&p_slot->ctrl->crit_sect); + } p_slot->state = STATIC_STATE; - break; - default: - break; } - mutex_unlock(&p_slot->lock); - kfree(info); + return; } -void queue_pushbutton_work(void *data) -{ - struct slot *p_slot = data; - struct pushbutton_work_info *info; - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - err("%s: Cannot allocate memory\n", __FUNCTION__); - return; +/* this is the main worker thread */ +static int event_thread(void* data) +{ + struct controller *ctrl; + lock_kernel(); + daemonize("shpchpd_event"); + unlock_kernel(); + + while (1) { + dbg("!!!!event_thread sleeping\n"); + down_interruptible (&event_semaphore); + dbg("event_thread woken finished = %d\n", event_finished); + if (event_finished || signal_pending(current)) + break; + /* Do stuff here */ + if (pushbutton_pending) + shpchp_pushbutton_thread(pushbutton_pending); + else + for (ctrl = shpchp_ctrl_list; ctrl; ctrl=ctrl->next) + interrupt_event_handler(ctrl); } - info->p_slot = p_slot; - INIT_WORK(&info->work, shpchp_pushbutton_thread, info); + dbg("event_thread signals exit\n"); + up(&event_exit); + return 0; +} - mutex_lock(&p_slot->lock); - switch (p_slot->state) { - case BLINKINGOFF_STATE: - p_slot->state = POWEROFF_STATE; - break; - case BLINKINGON_STATE: - p_slot->state = POWERON_STATE; - break; - default: - goto out; +int shpchp_event_start_thread (void) +{ + int pid; + + /* initialize our semaphores */ + init_MUTEX_LOCKED(&event_exit); + event_finished=0; + + init_MUTEX_LOCKED(&event_semaphore); + pid = kernel_thread(event_thread, NULL, 0); + + if (pid < 0) { + err ("Can't start up our event thread\n"); + return -1; } - queue_work(shpchp_wq, &info->work); - out: - mutex_unlock(&p_slot->lock); + return 0; +} + + +void shpchp_event_stop_thread (void) +{ + event_finished = 1; + up(&event_semaphore); + down(&event_exit); } + static int update_slot_info (struct slot *slot) { struct hotplug_slot_info *info; @@ -484,110 +742,149 @@ static int update_slot_info (struct slot *slot) return result; } -/* - * Note: This function must be called with slot->lock held - */ -static void handle_button_press_event(struct slot *p_slot) +static void interrupt_event_handler(struct controller *ctrl) { + int loop = 0; + int change = 1; + u8 hp_slot; u8 getstatus; + struct slot *p_slot; - switch (p_slot->state) { - case STATIC_STATE: - p_slot->hpc_ops->get_power_status(p_slot, &getstatus); - if (getstatus) { - p_slot->state = BLINKINGOFF_STATE; - info(msg_button_off, p_slot->number); - } else { - p_slot->state = BLINKINGON_STATE; - info(msg_button_on, p_slot->number); - } - /* blink green LED and turn off amber */ - p_slot->hpc_ops->green_led_blink(p_slot); - p_slot->hpc_ops->set_attention_status(p_slot, 0); - - schedule_delayed_work(&p_slot->work, 5*HZ); - break; - case BLINKINGOFF_STATE: - case BLINKINGON_STATE: - /* - * Cancel if we are still blinking; this means that we - * press the attention again before the 5 sec. limit - * expires to cancel hot-add or hot-remove - */ - info("Button cancel on Slot(%s)\n", p_slot->name); - dbg("%s: button cancel\n", __FUNCTION__); - cancel_delayed_work(&p_slot->work); - if (p_slot->state == BLINKINGOFF_STATE) - p_slot->hpc_ops->green_led_on(p_slot); - else - p_slot->hpc_ops->green_led_off(p_slot); - p_slot->hpc_ops->set_attention_status(p_slot, 0); - info(msg_button_cancel, p_slot->number); - p_slot->state = STATIC_STATE; - break; - case POWEROFF_STATE: - case POWERON_STATE: - /* - * Ignore if the slot is on power-on or power-off state; - * this means that the previous attention button action - * to hot-add or hot-remove is undergoing - */ - info("Button ignore on Slot(%s)\n", p_slot->name); - update_slot_info(p_slot); - break; - default: - warn("Not a valid state\n"); - break; - } -} - -static void interrupt_event_handler(void *data) -{ - struct event_info *info = data; - struct slot *p_slot = info->p_slot; - - mutex_lock(&p_slot->lock); - switch (info->event_type) { - case INT_BUTTON_PRESS: - handle_button_press_event(p_slot); - break; - case INT_POWER_FAULT: - dbg("%s: power fault\n", __FUNCTION__); - p_slot->hpc_ops->set_attention_status(p_slot, 1); - p_slot->hpc_ops->green_led_off(p_slot); - break; - default: - update_slot_info(p_slot); - break; + while (change) { + change = 0; + + for (loop = 0; loop < 10; loop++) { + if (ctrl->event_queue[loop].event_type != 0) { + dbg("%s:loop %x event_type %x\n", __FUNCTION__, loop, + ctrl->event_queue[loop].event_type); + hp_slot = ctrl->event_queue[loop].hp_slot; + + p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); + + if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { + dbg("%s: button cancel\n", __FUNCTION__); + del_timer(&p_slot->task_event); + + switch (p_slot->state) { + case BLINKINGOFF_STATE: + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + p_slot->hpc_ops->green_led_on(p_slot); + + p_slot->hpc_ops->set_attention_status(p_slot, 0); + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + break; + case BLINKINGON_STATE: + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + p_slot->hpc_ops->green_led_off(p_slot); + + p_slot->hpc_ops->set_attention_status(p_slot, 0); + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + + break; + default: + warn("Not a valid state\n"); + return; + } + info(msg_button_cancel, p_slot->number); + p_slot->state = STATIC_STATE; + } else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) { + /* Button Pressed (No action on 1st press...) */ + dbg("%s: Button pressed\n", __FUNCTION__); + + p_slot->hpc_ops->get_power_status(p_slot, &getstatus); + if (getstatus) { + /* slot is on */ + dbg("%s: slot is on\n", __FUNCTION__); + p_slot->state = BLINKINGOFF_STATE; + info(msg_button_off, p_slot->number); + } else { + /* slot is off */ + dbg("%s: slot is off\n", __FUNCTION__); + p_slot->state = BLINKINGON_STATE; + info(msg_button_on, p_slot->number); + } + + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + /* blink green LED and turn off amber */ + p_slot->hpc_ops->green_led_blink(p_slot); + + p_slot->hpc_ops->set_attention_status(p_slot, 0); + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + + init_timer(&p_slot->task_event); + p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ + p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; + p_slot->task_event.data = (unsigned long) p_slot; + + dbg("%s: add_timer p_slot = %p\n", __FUNCTION__,(void *) p_slot); + add_timer(&p_slot->task_event); + } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { + /***********POWER FAULT********************/ + dbg("%s: power fault\n", __FUNCTION__); + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + p_slot->hpc_ops->set_attention_status(p_slot, 1); + + p_slot->hpc_ops->green_led_off(p_slot); + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); + } else { + /* refresh notification */ + if (p_slot) + update_slot_info(p_slot); + } + + ctrl->event_queue[loop].event_type = 0; + + change = 1; + } + } /* End of FOR loop */ } - mutex_unlock(&p_slot->lock); - kfree(info); + return; } -static int shpchp_enable_slot (struct slot *p_slot) +int shpchp_enable_slot (struct slot *p_slot) { u8 getstatus = 0; - int rc, retval = -ENODEV; + int rc; /* Check to see if (latch closed, card present, power off) */ - mutex_lock(&p_slot->ctrl->crit_sect); + down(&p_slot->ctrl->crit_sect); rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); - goto out; + up(&p_slot->ctrl->crit_sect); + return -ENODEV; } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); - goto out; + up(&p_slot->ctrl->crit_sect); + return -ENODEV; } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); - goto out; + up(&p_slot->ctrl->crit_sect); + return -ENODEV; } + up(&p_slot->ctrl->crit_sect); p_slot->is_a_board = 1; @@ -602,119 +899,56 @@ static int shpchp_enable_slot (struct slot *p_slot) && p_slot->ctrl->num_slots == 1) { /* handle amd pogo errata; this must be done before enable */ amd_pogo_errata_save_misc_reg(p_slot); - retval = board_added(p_slot); + rc = board_added(p_slot); /* handle amd pogo errata; this must be done after enable */ amd_pogo_errata_restore_misc_reg(p_slot); } else - retval = board_added(p_slot); + rc = board_added(p_slot); - if (retval) { + if (rc) { p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); } update_slot_info(p_slot); - out: - mutex_unlock(&p_slot->ctrl->crit_sect); - return retval; + return rc; } -static int shpchp_disable_slot (struct slot *p_slot) +int shpchp_disable_slot (struct slot *p_slot) { u8 getstatus = 0; - int rc, retval = -ENODEV; + int ret = 0; if (!p_slot->ctrl) return -ENODEV; /* Check to see if (latch closed, card present, power on) */ - mutex_lock(&p_slot->ctrl->crit_sect); + down(&p_slot->ctrl->crit_sect); - rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); - if (rc || !getstatus) { + ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); + if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); - goto out; + up(&p_slot->ctrl->crit_sect); + return -ENODEV; } - rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - if (rc || getstatus) { + ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); - goto out; + up(&p_slot->ctrl->crit_sect); + return -ENODEV; } - rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); - if (rc || !getstatus) { + ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); + if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); - goto out; + up(&p_slot->ctrl->crit_sect); + return -ENODEV; } + up(&p_slot->ctrl->crit_sect); - retval = remove_board(p_slot); + ret = remove_board(p_slot); update_slot_info(p_slot); - out: - mutex_unlock(&p_slot->ctrl->crit_sect); - return retval; + return ret; } -int shpchp_sysfs_enable_slot(struct slot *p_slot) -{ - int retval = -ENODEV; - - mutex_lock(&p_slot->lock); - switch (p_slot->state) { - case BLINKINGON_STATE: - cancel_delayed_work(&p_slot->work); - case STATIC_STATE: - p_slot->state = POWERON_STATE; - mutex_unlock(&p_slot->lock); - retval = shpchp_enable_slot(p_slot); - mutex_lock(&p_slot->lock); - p_slot->state = STATIC_STATE; - break; - case POWERON_STATE: - info("Slot %s is already in powering on state\n", - p_slot->name); - break; - case BLINKINGOFF_STATE: - case POWEROFF_STATE: - info("Already enabled on slot %s\n", p_slot->name); - break; - default: - err("Not a valid state on slot %s\n", p_slot->name); - break; - } - mutex_unlock(&p_slot->lock); - - return retval; -} - -int shpchp_sysfs_disable_slot(struct slot *p_slot) -{ - int retval = -ENODEV; - - mutex_lock(&p_slot->lock); - switch (p_slot->state) { - case BLINKINGOFF_STATE: - cancel_delayed_work(&p_slot->work); - case STATIC_STATE: - p_slot->state = POWEROFF_STATE; - mutex_unlock(&p_slot->lock); - retval = shpchp_disable_slot(p_slot); - mutex_lock(&p_slot->lock); - p_slot->state = STATIC_STATE; - break; - case POWEROFF_STATE: - info("Slot %s is already in powering off state\n", - p_slot->name); - break; - case BLINKINGON_STATE: - case POWERON_STATE: - info("Already disabled on slot %s\n", p_slot->name); - break; - default: - err("Not a valid state on slot %s\n", p_slot->name); - break; - } - mutex_unlock(&p_slot->lock); - - return retval; -} diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 66123cf4d..b4226ff3a 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -82,6 +82,31 @@ #define SLOT_100MHZ_PCIX_533 0x0f000000 #define SLOT_133MHZ_PCIX_533 0xf0000000 + +/* Secondary Bus Configuration Register */ +/* For PI = 1, Bits 0 to 2 have been encoded as follows to show current bus speed/mode */ +#define PCI_33MHZ 0x0 +#define PCI_66MHZ 0x1 +#define PCIX_66MHZ 0x2 +#define PCIX_100MHZ 0x3 +#define PCIX_133MHZ 0x4 + +/* For PI = 2, Bits 0 to 3 have been encoded as follows to show current bus speed/mode */ +#define PCI_33MHZ 0x0 +#define PCI_66MHZ 0x1 +#define PCIX_66MHZ 0x2 +#define PCIX_100MHZ 0x3 +#define PCIX_133MHZ 0x4 +#define PCIX_66MHZ_ECC 0x5 +#define PCIX_100MHZ_ECC 0x6 +#define PCIX_133MHZ_ECC 0x7 +#define PCIX_66MHZ_266 0x9 +#define PCIX_100MHZ_266 0xa +#define PCIX_133MHZ_266 0xb +#define PCIX_66MHZ_533 0x11 +#define PCIX_100MHZ_533 0x12 +#define PCIX_133MHZ_533 0x13 + /* Slot Configuration */ #define SLOT_NUM 0x0000001F #define FIRST_DEV_NUM 0x00001F00 @@ -206,7 +231,6 @@ static spinlock_t list_lock; static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); -static int hpc_check_cmd_status(struct controller *ctrl); /* This is the interrupt polling timeout function. */ static void int_poll_timeout(unsigned long lphp_ctlr) @@ -279,13 +303,10 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) int i; DBG_ENTER_ROUTINE - - mutex_lock(&slot->ctrl->cmd_lock); - + if (!php_ctlr) { err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - retval = -EINVAL; - goto out; + return -1; } for (i = 0; i < 10; i++) { @@ -302,8 +323,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) if (cmd_status & 0x1) { /* After 1 sec and and the controller is still busy */ err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); - retval = -EBUSY; - goto out; + return -1; } ++t_slot; @@ -320,17 +340,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) * Wait for command completion. */ retval = shpc_wait_cmd(slot->ctrl); - if (retval) - goto out; - - cmd_status = hpc_check_cmd_status(slot->ctrl); - if (cmd_status) { - err("%s: Failed to issued command 0x%x (error code = %d)\n", - __FUNCTION__, cmd, cmd_status); - retval = -EIO; - } - out: - mutex_unlock(&slot->ctrl->cmd_lock); DBG_LEAVE_ROUTINE return retval; @@ -523,41 +532,81 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) { - int retval = 0; struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; - u32 slot_reg = readl(php_ctlr->creg + SLOT1 + 4 * slot->hp_slot); - u8 pcix_cap = (slot_reg >> 12) & 7; - u8 m66_cap = (slot_reg >> 9) & 1; + u32 slot_reg; + u16 slot_status, sec_bus_status; + u8 m66_cap, pcix_cap, pi; + int retval = 0; DBG_ENTER_ROUTINE - dbg("%s: slot_reg = %x, pcix_cap = %x, m66_cap = %x\n", - __FUNCTION__, slot_reg, pcix_cap, m66_cap); + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } - switch (pcix_cap) { - case 0x0: - *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; - break; - case 0x1: - *value = PCI_SPEED_66MHz_PCIX; - break; - case 0x3: - *value = PCI_SPEED_133MHz_PCIX; - break; - case 0x4: - *value = PCI_SPEED_133MHz_PCIX_266; - break; - case 0x5: - *value = PCI_SPEED_133MHz_PCIX_533; - break; - case 0x2: - default: - *value = PCI_SPEED_UNKNOWN; - retval = -ENODEV; - break; + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + + pi = readb(php_ctlr->creg + PROG_INTERFACE); + slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); + dbg("%s: pi = %d, slot_reg = %x\n", __FUNCTION__, pi, slot_reg); + slot_status = (u16) slot_reg; + dbg("%s: slot_status = %x\n", __FUNCTION__, slot_status); + sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); + + pcix_cap = (u8) ((slot_status & 0x3000) >> 12); + dbg("%s: pcix_cap = %x\n", __FUNCTION__, pcix_cap); + m66_cap = (u8) ((slot_status & 0x0200) >> 9); + dbg("%s: m66_cap = %x\n", __FUNCTION__, m66_cap); + + + if (pi == 2) { + switch (pcix_cap) { + case 0: + *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; + break; + case 1: + *value = PCI_SPEED_66MHz_PCIX; + break; + case 3: + *value = PCI_SPEED_133MHz_PCIX; + break; + case 4: + *value = PCI_SPEED_133MHz_PCIX_266; + break; + case 5: + *value = PCI_SPEED_133MHz_PCIX_533; + break; + case 2: /* Reserved */ + default: + *value = PCI_SPEED_UNKNOWN; + retval = -ENODEV; + break; + } + } else { + switch (pcix_cap) { + case 0: + *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; + break; + case 1: + *value = PCI_SPEED_66MHz_PCIX; + break; + case 3: + *value = PCI_SPEED_133MHz_PCIX; + break; + case 2: /* Reserved */ + default: + *value = PCI_SPEED_UNKNOWN; + retval = -ENODEV; + break; + } } dbg("Adapter speed = %d\n", *value); + DBG_LEAVE_ROUTINE return retval; } @@ -748,7 +797,6 @@ static void hpc_release_ctlr(struct controller *ctrl) { struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; struct php_ctlr_state_s *p, *p_prev; - int i; DBG_ENTER_ROUTINE @@ -757,14 +805,6 @@ static void hpc_release_ctlr(struct controller *ctrl) return ; } - /* - * Mask all slot event interrupts - */ - for (i = 0; i < ctrl->num_slots; i++) - writel(0xffff3fff, php_ctlr->creg + SLOT1 + (4 * i)); - - cleanup_slots(ctrl); - if (shpchp_poll_mode) { del_timer(&php_ctlr->int_poll_timer); } else { @@ -774,7 +814,6 @@ static void hpc_release_ctlr(struct controller *ctrl) pci_disable_msi(php_ctlr->pci_dev); } } - if (php_ctlr->pci_dev) { iounmap(php_ctlr->creg); release_mem_region(ctrl->mmio_base, ctrl->mmio_size); @@ -900,66 +939,98 @@ static int hpc_slot_disable(struct slot * slot) static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) { - int retval; + u8 slot_cmd; + u8 pi; + int retval = 0; struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; - u8 pi, cmd; DBG_ENTER_ROUTINE + + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } pi = readb(php_ctlr->creg + PROG_INTERFACE); - if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) - return -EINVAL; + + if (pi == 1) { + switch (value) { + case 0: + slot_cmd = SETA_PCI_33MHZ; + break; + case 1: + slot_cmd = SETA_PCI_66MHZ; + break; + case 2: + slot_cmd = SETA_PCIX_66MHZ; + break; + case 3: + slot_cmd = SETA_PCIX_100MHZ; + break; + case 4: + slot_cmd = SETA_PCIX_133MHZ; + break; + default: + slot_cmd = PCI_SPEED_UNKNOWN; + retval = -ENODEV; + return retval; + } + } else { + switch (value) { + case 0: + slot_cmd = SETB_PCI_33MHZ; + break; + case 1: + slot_cmd = SETB_PCI_66MHZ; + break; + case 2: + slot_cmd = SETB_PCIX_66MHZ_PM; + break; + case 3: + slot_cmd = SETB_PCIX_100MHZ_PM; + break; + case 4: + slot_cmd = SETB_PCIX_133MHZ_PM; + break; + case 5: + slot_cmd = SETB_PCIX_66MHZ_EM; + break; + case 6: + slot_cmd = SETB_PCIX_100MHZ_EM; + break; + case 7: + slot_cmd = SETB_PCIX_133MHZ_EM; + break; + case 8: + slot_cmd = SETB_PCIX_66MHZ_266; + break; + case 0x9: + slot_cmd = SETB_PCIX_100MHZ_266; + break; + case 0xa: + slot_cmd = SETB_PCIX_133MHZ_266; + break; + case 0xb: + slot_cmd = SETB_PCIX_66MHZ_533; + break; + case 0xc: + slot_cmd = SETB_PCIX_100MHZ_533; + break; + case 0xd: + slot_cmd = SETB_PCIX_133MHZ_533; + break; + default: + slot_cmd = PCI_SPEED_UNKNOWN; + retval = -ENODEV; + return retval; + } - switch (value) { - case PCI_SPEED_33MHz: - cmd = SETA_PCI_33MHZ; - break; - case PCI_SPEED_66MHz: - cmd = SETA_PCI_66MHZ; - break; - case PCI_SPEED_66MHz_PCIX: - cmd = SETA_PCIX_66MHZ; - break; - case PCI_SPEED_100MHz_PCIX: - cmd = SETA_PCIX_100MHZ; - break; - case PCI_SPEED_133MHz_PCIX: - cmd = SETA_PCIX_133MHZ; - break; - case PCI_SPEED_66MHz_PCIX_ECC: - cmd = SETB_PCIX_66MHZ_EM; - break; - case PCI_SPEED_100MHz_PCIX_ECC: - cmd = SETB_PCIX_100MHZ_EM; - break; - case PCI_SPEED_133MHz_PCIX_ECC: - cmd = SETB_PCIX_133MHZ_EM; - break; - case PCI_SPEED_66MHz_PCIX_266: - cmd = SETB_PCIX_66MHZ_266; - break; - case PCI_SPEED_100MHz_PCIX_266: - cmd = SETB_PCIX_100MHZ_266; - break; - case PCI_SPEED_133MHz_PCIX_266: - cmd = SETB_PCIX_133MHZ_266; - break; - case PCI_SPEED_66MHz_PCIX_533: - cmd = SETB_PCIX_66MHZ_533; - break; - case PCI_SPEED_100MHz_PCIX_533: - cmd = SETB_PCIX_100MHZ_533; - break; - case PCI_SPEED_133MHz_PCIX_533: - cmd = SETB_PCIX_133MHZ_533; - break; - default: - return -EINVAL; } - - retval = shpc_write_cmd(slot, 0, cmd); - if (retval) + retval = shpc_write_cmd(slot, 0, slot_cmd); + if (retval) { err("%s: Write command failed!\n", __FUNCTION__); + return -1; + } DBG_LEAVE_ROUTINE return retval; @@ -1022,8 +1093,14 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) wake_up_interruptible(&ctrl->queue); } - if ((intr_loc = (intr_loc >> 1)) == 0) - goto out; + if ((intr_loc = (intr_loc >> 1)) == 0) { + /* Unmask Global Interrupt Mask */ + temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); + temp_dword &= 0xfffffffe; + writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); + + return IRQ_NONE; + } for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { /* To find out which slot has interrupt pending */ @@ -1053,7 +1130,6 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); } } - out: if (!shpchp_poll_mode) { /* Unmask Global Interrupt Mask */ temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); @@ -1066,43 +1142,64 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) { - int retval = 0; struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; - u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); - u32 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1); - u32 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); + int retval = 0; + u8 pi; + u32 slot_avail1, slot_avail2; DBG_ENTER_ROUTINE + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + + pi = readb(php_ctlr->creg + PROG_INTERFACE); + slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1); + slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); + if (pi == 2) { if (slot_avail2 & SLOT_133MHZ_PCIX_533) - bus_speed = PCI_SPEED_133MHz_PCIX_533; + bus_speed = PCIX_133MHZ_533; else if (slot_avail2 & SLOT_100MHZ_PCIX_533) - bus_speed = PCI_SPEED_100MHz_PCIX_533; + bus_speed = PCIX_100MHZ_533; else if (slot_avail2 & SLOT_66MHZ_PCIX_533) - bus_speed = PCI_SPEED_66MHz_PCIX_533; + bus_speed = PCIX_66MHZ_533; else if (slot_avail2 & SLOT_133MHZ_PCIX_266) - bus_speed = PCI_SPEED_133MHz_PCIX_266; + bus_speed = PCIX_133MHZ_266; else if (slot_avail2 & SLOT_100MHZ_PCIX_266) - bus_speed = PCI_SPEED_100MHz_PCIX_266; + bus_speed = PCIX_100MHZ_266; else if (slot_avail2 & SLOT_66MHZ_PCIX_266) - bus_speed = PCI_SPEED_66MHz_PCIX_266; - } - - if (bus_speed == PCI_SPEED_UNKNOWN) { + bus_speed = PCIX_66MHZ_266; + else if (slot_avail1 & SLOT_133MHZ_PCIX) + bus_speed = PCIX_133MHZ; + else if (slot_avail1 & SLOT_100MHZ_PCIX) + bus_speed = PCIX_100MHZ; + else if (slot_avail1 & SLOT_66MHZ_PCIX) + bus_speed = PCIX_66MHZ; + else if (slot_avail2 & SLOT_66MHZ) + bus_speed = PCI_66MHZ; + else if (slot_avail1 & SLOT_33MHZ) + bus_speed = PCI_33MHZ; + else bus_speed = PCI_SPEED_UNKNOWN; + } else { if (slot_avail1 & SLOT_133MHZ_PCIX) - bus_speed = PCI_SPEED_133MHz_PCIX; + bus_speed = PCIX_133MHZ; else if (slot_avail1 & SLOT_100MHZ_PCIX) - bus_speed = PCI_SPEED_100MHz_PCIX; + bus_speed = PCIX_100MHZ; else if (slot_avail1 & SLOT_66MHZ_PCIX) - bus_speed = PCI_SPEED_66MHz_PCIX; + bus_speed = PCIX_66MHZ; else if (slot_avail2 & SLOT_66MHZ) - bus_speed = PCI_SPEED_66MHz; + bus_speed = PCI_66MHZ; else if (slot_avail1 & SLOT_33MHZ) - bus_speed = PCI_SPEED_33MHz; - else - retval = -ENODEV; + bus_speed = PCI_33MHZ; + else bus_speed = PCI_SPEED_UNKNOWN; } *value = bus_speed; @@ -1113,69 +1210,111 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) { - int retval = 0; struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; - u16 sec_bus_reg = readw(php_ctlr->creg + SEC_BUS_CONFIG); - u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); - u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); + u16 sec_bus_status; + int retval = 0; + u8 pi; DBG_ENTER_ROUTINE - if ((pi == 1) && (speed_mode > 4)) { - *value = PCI_SPEED_UNKNOWN; - return -ENODEV; + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; } - switch (speed_mode) { - case 0x0: - *value = PCI_SPEED_33MHz; - break; - case 0x1: - *value = PCI_SPEED_66MHz; - break; - case 0x2: - *value = PCI_SPEED_66MHz_PCIX; - break; - case 0x3: - *value = PCI_SPEED_100MHz_PCIX; - break; - case 0x4: - *value = PCI_SPEED_133MHz_PCIX; - break; - case 0x5: - *value = PCI_SPEED_66MHz_PCIX_ECC; - break; - case 0x6: - *value = PCI_SPEED_100MHz_PCIX_ECC; - break; - case 0x7: - *value = PCI_SPEED_133MHz_PCIX_ECC; - break; - case 0x8: - *value = PCI_SPEED_66MHz_PCIX_266; - break; - case 0x9: - *value = PCI_SPEED_100MHz_PCIX_266; - break; - case 0xa: - *value = PCI_SPEED_133MHz_PCIX_266; - break; - case 0xb: - *value = PCI_SPEED_66MHz_PCIX_533; - break; - case 0xc: - *value = PCI_SPEED_100MHz_PCIX_533; - break; - case 0xd: - *value = PCI_SPEED_133MHz_PCIX_533; - break; - default: - *value = PCI_SPEED_UNKNOWN; - retval = -ENODEV; - break; + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; } + pi = readb(php_ctlr->creg + PROG_INTERFACE); + sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); + + if (pi == 2) { + switch (sec_bus_status & 0x000f) { + case 0: + bus_speed = PCI_SPEED_33MHz; + break; + case 1: + bus_speed = PCI_SPEED_66MHz; + break; + case 2: + bus_speed = PCI_SPEED_66MHz_PCIX; + break; + case 3: + bus_speed = PCI_SPEED_100MHz_PCIX; + break; + case 4: + bus_speed = PCI_SPEED_133MHz_PCIX; + break; + case 5: + bus_speed = PCI_SPEED_66MHz_PCIX_ECC; + break; + case 6: + bus_speed = PCI_SPEED_100MHz_PCIX_ECC; + break; + case 7: + bus_speed = PCI_SPEED_133MHz_PCIX_ECC; + break; + case 8: + bus_speed = PCI_SPEED_66MHz_PCIX_266; + break; + case 9: + bus_speed = PCI_SPEED_100MHz_PCIX_266; + break; + case 0xa: + bus_speed = PCI_SPEED_133MHz_PCIX_266; + break; + case 0xb: + bus_speed = PCI_SPEED_66MHz_PCIX_533; + break; + case 0xc: + bus_speed = PCI_SPEED_100MHz_PCIX_533; + break; + case 0xd: + bus_speed = PCI_SPEED_133MHz_PCIX_533; + break; + case 0xe: + case 0xf: + default: + bus_speed = PCI_SPEED_UNKNOWN; + break; + } + } else { + /* In the case where pi is undefined, default it to 1 */ + switch (sec_bus_status & 0x0007) { + case 0: + bus_speed = PCI_SPEED_33MHz; + break; + case 1: + bus_speed = PCI_SPEED_66MHz; + break; + case 2: + bus_speed = PCI_SPEED_66MHz_PCIX; + break; + case 3: + bus_speed = PCI_SPEED_100MHz_PCIX; + break; + case 4: + bus_speed = PCI_SPEED_133MHz_PCIX; + break; + case 5: + bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ + break; + case 6: + bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ + break; + case 7: + bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ + break; + default: + bus_speed = PCI_SPEED_UNKNOWN; + break; + } + } + + *value = bus_speed; dbg("Current bus speed = %d\n", bus_speed); DBG_LEAVE_ROUTINE return retval; @@ -1204,6 +1343,7 @@ static struct hpc_ops shpchp_hpc_ops = { .green_led_blink = hpc_set_green_led_blink, .release_ctlr = hpc_release_ctlr, + .check_cmd_status = hpc_check_cmd_status, }; inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, @@ -1235,13 +1375,15 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ spin_lock_init(&list_lock); - php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL); + php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL); if (!php_ctlr) { /* allocate controller state data */ err("%s: HPC controller memory allocation error!\n", __FUNCTION__); goto abort; } + memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s)); + php_ctlr->pci_dev = pdev; /* save pci_dev in context */ if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == @@ -1312,9 +1454,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) } dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); - mutex_init(&ctrl->crit_sect); - mutex_init(&ctrl->cmd_lock); - + init_MUTEX(&ctrl->crit_sect); /* Setup wait queue */ init_waitqueue_head(&ctrl->queue); diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 257adc233..19e1a5e1e 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -38,7 +38,7 @@ static void program_fw_provided_values(struct pci_dev *dev) { u16 pci_cmd, pci_bctl; struct pci_dev *cdev; - struct hotplug_params hpp; + struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */ /* Program hpp values for this device */ if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || @@ -46,13 +46,7 @@ static void program_fw_provided_values(struct pci_dev *dev) (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) return; - /* use default values if we can't get them from firmware */ - if (get_hp_params_from_firmware(dev, &hpp)) { - hpp.cache_line_size = 8; - hpp.latency_timer = 0x40; - hpp.enable_serr = 0; - hpp.enable_perr = 0; - } + get_hp_params_from_firmware(dev, &hpp); pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size); pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer); diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/shpchprm_acpi.c similarity index 55% rename from drivers/pci/hotplug/acpi_pcihp.c rename to drivers/pci/hotplug/shpchprm_acpi.c index 39af9c325..17145e522 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c @@ -1,7 +1,7 @@ /* - * Common ACPI functions for hot plug platforms + * SHPCHPRM ACPI: PHP Resource Manager for ACPI platform * - * Copyright (C) 2006 Intel Corporation + * Copyright (C) 2003-2004 Intel Corporation * * All rights reserved. * @@ -31,12 +31,26 @@ #include #include #include -#include "pci_hotplug.h" +#include "shpchp.h" #define METHOD_NAME__SUN "_SUN" #define METHOD_NAME__HPP "_HPP" #define METHOD_NAME_OSHP "OSHP" +static u8 * acpi_path_name( acpi_handle handle) +{ + acpi_status status; + static u8 path_name[ACPI_PATHNAME_MAX]; + struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name }; + + memset(path_name, 0, sizeof (path_name)); + status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf); + + if (ACPI_FAILURE(status)) + return NULL; + else + return path_name; +} static acpi_status acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) @@ -44,21 +58,18 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) acpi_status status; u8 nui[4]; struct acpi_buffer ret_buf = { 0, NULL}; - struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *ext_obj, *package; + u8 *path_name = acpi_path_name(handle); int i, len = 0; - acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); - /* get _hpp */ status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); switch (status) { case AE_BUFFER_OVERFLOW: ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); if (!ret_buf.pointer) { - printk(KERN_ERR "%s:%s alloc for _HPP fail\n", - __FUNCTION__, (char *)string.pointer); - acpi_os_free(string.pointer); + err ("%s:%s alloc for _HPP fail\n", __FUNCTION__, + path_name); return AE_NO_MEMORY; } status = acpi_evaluate_object(handle, METHOD_NAME__HPP, @@ -67,17 +78,16 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) break; default: if (ACPI_FAILURE(status)) { - pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__, - (char *)string.pointer, status); - acpi_os_free(string.pointer); + dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__, + path_name, status); return status; } } ext_obj = (union acpi_object *) ret_buf.pointer; if (ext_obj->type != ACPI_TYPE_PACKAGE) { - printk(KERN_ERR "%s:%s _HPP obj not a package\n", __FUNCTION__, - (char *)string.pointer); + err ("%s:%s _HPP obj not a package\n", __FUNCTION__, + path_name); status = AE_ERROR; goto free_and_return; } @@ -91,8 +101,8 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) nui[i] = (u8)ext_obj->integer.value; break; default: - printk(KERN_ERR "%s:%s _HPP obj type incorrect\n", - __FUNCTION__, (char *)string.pointer); + err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__, + path_name); status = AE_ERROR; goto free_and_return; } @@ -103,52 +113,54 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) hpp->enable_serr = nui[2]; hpp->enable_perr = nui[3]; - pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); - pr_debug(" _HPP: latency timer =0x%x\n", hpp->latency_timer); - pr_debug(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); - pr_debug(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); + dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); + dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer); + dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); + dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); free_and_return: - acpi_os_free(string.pointer); - acpi_os_free(ret_buf.pointer); + kfree(ret_buf.pointer); return status; } - - -/* acpi_run_oshp - get control of hotplug from the firmware - * - * @handle - the handle of the hotplug controller. - */ -acpi_status acpi_run_oshp(acpi_handle handle) +static void acpi_run_oshp(acpi_handle handle) { acpi_status status; - struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; - - acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); + u8 *path_name = acpi_path_name(handle); /* run OSHP */ status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); - if (ACPI_FAILURE(status)) - printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", __FUNCTION__, - (char *)string.pointer, status); - else - pr_debug("%s:%s OSHP passes\n", __FUNCTION__, - (char *)string.pointer); - - acpi_os_free(string.pointer); - return status; + if (ACPI_FAILURE(status)) { + err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name, + status); + } else { + dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name); + } } -EXPORT_SYMBOL_GPL(acpi_run_oshp); +int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) +{ + int offset = devnum - ctrl->slot_device_offset; + + dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset); + *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset); + return 0; +} +void get_hp_hw_control_from_firmware(struct pci_dev *dev) +{ + /* + * OSHP is an optional ACPI firmware control method. If present, + * we need to run it to inform BIOS that we will control SHPC + * hardware from now on. + */ + acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev)); + if (!handle) + return; + acpi_run_oshp(handle); +} -/* acpi_get_hp_params_from_firmware - * - * @dev - the pci_dev of the newly added device - * @hpp - allocated by the caller - */ -acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, +void get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp) { acpi_status status = AE_NOT_FOUND; @@ -170,42 +182,5 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, /* Check if a parent object supports _HPP */ pdev = pdev->bus->parent->self; } - return status; } -EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware); - -/* acpi_root_bridge - check to see if this acpi object is a root bridge - * - * @handle - the acpi object in question. - */ -int acpi_root_bridge(acpi_handle handle) -{ - acpi_status status; - struct acpi_device_info *info; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - int i; - - status = acpi_get_object_info(handle, &buffer); - if (ACPI_SUCCESS(status)) { - info = buffer.pointer; - if ((info->valid & ACPI_VALID_HID) && - !strcmp(PCI_ROOT_HID_STRING, - info->hardware_id.value)) { - acpi_os_free(buffer.pointer); - return 1; - } - if (info->valid & ACPI_VALID_CID) { - for (i=0; i < info->compatibility_id.count; i++) { - if (!strcmp(PCI_ROOT_HID_STRING, - info->compatibility_id.id[i].value)) { - acpi_os_free(buffer.pointer); - return 1; - } - } - } - acpi_os_free(buffer.pointer); - } - return 0; -} -EXPORT_SYMBOL_GPL(acpi_root_bridge); diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c new file mode 100644 index 000000000..ed6c1254b --- /dev/null +++ b/drivers/pci/hotplug/shpchprm_legacy.c @@ -0,0 +1,54 @@ +/* + * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform + * + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. + * Copyright (C) 2003-2004 Intel Corporation + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to , + * + */ + +#include +#include +#include +#include +#include "shpchp.h" + +int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) +{ + int offset = devnum - ctrl->slot_device_offset; + + *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset); + return 0; +} + +void get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp) +{ + return; +} + +void get_hp_hw_control_from_firmware(struct pci_dev *dev) +{ + return; +} + diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c new file mode 100644 index 000000000..c6b40998e --- /dev/null +++ b/drivers/pci/hotplug/shpchprm_nonacpi.c @@ -0,0 +1,57 @@ +/* + * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform + * + * Copyright (C) 1995,2001 Compaq Computer Corporation + * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001 IBM Corp. + * Copyright (C) 2003-2004 Intel Corporation + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to , + * + */ + +#include +#include +#include +#include +#include +#include + +#include "shpchp.h" + +int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) +{ + int offset = devnum - ctrl->slot_device_offset; + + dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset); + *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset); + return 0; +} + +void get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp) +{ + return; +} + +void get_hp_hw_control_from_firmware(struct pci_dev *dev) +{ + return; +} diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 9855c4c92..48723d6fa 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -103,9 +103,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) switch (entry->msi_attrib.type) { case PCI_CAP_ID_MSI: { - int pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI); + int pos; - if (!pos) + if (!(pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI))) return; pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), @@ -347,9 +347,9 @@ static int assign_msi_vector(void) static int get_new_vector(void) { - int vector = assign_msi_vector(); + int vector; - if (vector > 0) + if ((vector = assign_msi_vector()) > 0) set_intr_gate(vector, interrupt[vector]); return vector; @@ -369,8 +369,7 @@ static int msi_init(void) return status; } - status = msi_cache_init(); - if (status < 0) { + if ((status = msi_cache_init()) < 0) { pci_msi_enable = 0; printk(KERN_WARNING "PCI: MSI cache init failed\n"); return status; @@ -504,201 +503,6 @@ void pci_scan_msi_device(struct pci_dev *dev) nr_reserved_vectors++; } -#ifdef CONFIG_PM -int pci_save_msi_state(struct pci_dev *dev) -{ - int pos, i = 0; - u16 control; - struct pci_cap_saved_state *save_state; - u32 *cap; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos <= 0 || dev->no_msi) - return 0; - - pci_read_config_word(dev, msi_control_reg(pos), &control); - if (!(control & PCI_MSI_FLAGS_ENABLE)) - return 0; - - save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u32) * 5, - GFP_KERNEL); - if (!save_state) { - printk(KERN_ERR "Out of memory in pci_save_msi_state\n"); - return -ENOMEM; - } - cap = &save_state->data[0]; - - pci_read_config_dword(dev, pos, &cap[i++]); - control = cap[0] >> 16; - pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, &cap[i++]); - if (control & PCI_MSI_FLAGS_64BIT) { - pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, &cap[i++]); - pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, &cap[i++]); - } else - pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); - if (control & PCI_MSI_FLAGS_MASKBIT) - pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); - disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); - save_state->cap_nr = PCI_CAP_ID_MSI; - pci_add_saved_cap(dev, save_state); - return 0; -} - -void pci_restore_msi_state(struct pci_dev *dev) -{ - int i = 0, pos; - u16 control; - struct pci_cap_saved_state *save_state; - u32 *cap; - - save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSI); - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (!save_state || pos <= 0) - return; - cap = &save_state->data[0]; - - control = cap[i++] >> 16; - pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, cap[i++]); - if (control & PCI_MSI_FLAGS_64BIT) { - pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, cap[i++]); - pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, cap[i++]); - } else - pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, cap[i++]); - if (control & PCI_MSI_FLAGS_MASKBIT) - pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, cap[i++]); - pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); - enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); - pci_remove_saved_cap(save_state); - kfree(save_state); -} - -int pci_save_msix_state(struct pci_dev *dev) -{ - int pos; - u16 control; - struct pci_cap_saved_state *save_state; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos <= 0 || dev->no_msi) - return 0; - - pci_read_config_word(dev, msi_control_reg(pos), &control); - if (!(control & PCI_MSIX_FLAGS_ENABLE)) - return 0; - save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16), - GFP_KERNEL); - if (!save_state) { - printk(KERN_ERR "Out of memory in pci_save_msix_state\n"); - return -ENOMEM; - } - *((u16 *)&save_state->data[0]) = control; - - disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); - save_state->cap_nr = PCI_CAP_ID_MSIX; - pci_add_saved_cap(dev, save_state); - return 0; -} - -void pci_restore_msix_state(struct pci_dev *dev) -{ - u16 save; - int pos; - int vector, head, tail = 0; - void __iomem *base; - int j; - struct msg_address address; - struct msg_data data; - struct msi_desc *entry; - int temp; - struct pci_cap_saved_state *save_state; - - save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX); - if (!save_state) - return; - save = *((u16 *)&save_state->data[0]); - pci_remove_saved_cap(save_state); - kfree(save_state); - - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos <= 0) - return; - - /* route the table */ - temp = dev->irq; - if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) - return; - vector = head = dev->irq; - while (head != tail) { - entry = msi_desc[vector]; - base = entry->mask_base; - j = entry->msi_attrib.entry_nr; - - msi_address_init(&address); - msi_data_init(&data, vector); - - address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; - address.lo_address.value |= entry->msi_attrib.current_cpu << - MSI_TARGET_CPU_SHIFT; - - writel(address.lo_address.value, - base + j * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(address.hi_address, - base + j * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(*(u32*)&data, - base + j * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_DATA_OFFSET); - - tail = msi_desc[vector]->link.tail; - vector = tail; - } - dev->irq = temp; - - pci_write_config_word(dev, msi_control_reg(pos), save); - enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); -} -#endif - -static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry) -{ - struct msg_address address; - struct msg_data data; - int pos, vector = dev->irq; - u16 control; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - pci_read_config_word(dev, msi_control_reg(pos), &control); - /* Configure MSI capability structure */ - msi_address_init(&address); - msi_data_init(&data, vector); - entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> - MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); - pci_write_config_dword(dev, msi_lower_address_reg(pos), - address.lo_address.value); - if (is_64bit_address(control)) { - pci_write_config_dword(dev, - msi_upper_address_reg(pos), address.hi_address); - pci_write_config_word(dev, - msi_data_reg(pos, 1), *((u32*)&data)); - } else - pci_write_config_word(dev, - msi_data_reg(pos, 0), *((u32*)&data)); - if (entry->msi_attrib.maskbit) { - unsigned int maskbits, temp; - /* All MSIs are unmasked by default, Mask them all */ - pci_read_config_dword(dev, - msi_mask_bits_reg(pos, is_64bit_address(control)), - &maskbits); - temp = (1 << multi_msi_capable(control)); - temp = ((temp - 1) & ~temp); - maskbits |= temp; - pci_write_config_dword(dev, - msi_mask_bits_reg(pos, is_64bit_address(control)), - maskbits); - } -} - /** * msi_capability_init - configure device's MSI capability structure * @dev: pointer to the pci_dev data structure of MSI device function @@ -711,18 +515,18 @@ static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry) static int msi_capability_init(struct pci_dev *dev) { struct msi_desc *entry; + struct msg_address address; + struct msg_data data; int pos, vector; u16 control; pos = pci_find_capability(dev, PCI_CAP_ID_MSI); pci_read_config_word(dev, msi_control_reg(pos), &control); /* MSI Entry Initialization */ - entry = alloc_msi_entry(); - if (!entry) + if (!(entry = alloc_msi_entry())) return -ENOMEM; - vector = get_msi_vector(dev); - if (vector < 0) { + if ((vector = get_msi_vector(dev)) < 0) { kmem_cache_free(msi_cachep, entry); return -EBUSY; } @@ -742,8 +546,33 @@ static int msi_capability_init(struct pci_dev *dev) /* Replace with MSI handler */ irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit); /* Configure MSI capability structure */ - msi_register_init(dev, entry); - + msi_address_init(&address); + msi_data_init(&data, vector); + entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> + MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); + pci_write_config_dword(dev, msi_lower_address_reg(pos), + address.lo_address.value); + if (is_64bit_address(control)) { + pci_write_config_dword(dev, + msi_upper_address_reg(pos), address.hi_address); + pci_write_config_word(dev, + msi_data_reg(pos, 1), *((u32*)&data)); + } else + pci_write_config_word(dev, + msi_data_reg(pos, 0), *((u32*)&data)); + if (entry->msi_attrib.maskbit) { + unsigned int maskbits, temp; + /* All MSIs are unmasked by default, Mask them all */ + pci_read_config_dword(dev, + msi_mask_bits_reg(pos, is_64bit_address(control)), + &maskbits); + temp = (1 << multi_msi_capable(control)); + temp = ((temp - 1) & ~temp); + maskbits |= temp; + pci_write_config_dword(dev, + msi_mask_bits_reg(pos, is_64bit_address(control)), + maskbits); + } attach_msi_entry(entry, vector); /* Set MSI enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); @@ -768,8 +597,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msg_address address; struct msg_data data; int vector, pos, i, j, nr_entries, temp = 0; - unsigned long phys_addr; - u32 table_offset; + u32 phys_addr, table_offset; u16 control; u8 bir; void __iomem *base; @@ -778,11 +606,11 @@ static int msix_capability_init(struct pci_dev *dev, /* Request & Map MSI-X table region */ pci_read_config_word(dev, msi_control_reg(pos), &control); nr_entries = multi_msix_capable(control); - - pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset); + pci_read_config_dword(dev, msix_table_offset_reg(pos), + &table_offset); bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); - table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; - phys_addr = pci_resource_start (dev, bir) + table_offset; + phys_addr = pci_resource_start (dev, bir); + phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK); base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); if (base == NULL) return -ENOMEM; @@ -792,11 +620,8 @@ static int msix_capability_init(struct pci_dev *dev, entry = alloc_msi_entry(); if (!entry) break; - vector = get_msi_vector(dev); - if (vector < 0) { - kmem_cache_free(msi_cachep, entry); + if ((vector = get_msi_vector(dev)) < 0) break; - } j = entries[i].entry; entries[i].vector = vector; @@ -874,17 +699,12 @@ int pci_enable_msi(struct pci_dev* dev) if (dev->no_msi) return status; - if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) - return -EINVAL; - temp = dev->irq; - status = msi_init(); - if (status < 0) + if ((status = msi_init()) < 0) return status; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (!pos) + if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSI))) return -EINVAL; pci_read_config_word(dev, msi_control_reg(pos), &control); @@ -901,7 +721,6 @@ int pci_enable_msi(struct pci_dev* dev) vector_irq[dev->irq] = -1; nr_released_vectors--; spin_unlock_irqrestore(&msi_lock, flags); - msi_register_init(dev, msi_desc[dev->irq]); enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); return 0; } @@ -909,8 +728,8 @@ int pci_enable_msi(struct pci_dev* dev) dev->irq = temp; } /* Check whether driver already requested for MSI-X vectors */ - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 && + !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { printk(KERN_INFO "PCI: %s: Can't enable MSI. " "Device already has MSI-X vectors assigned\n", pci_name(dev)); @@ -936,13 +755,7 @@ void pci_disable_msi(struct pci_dev* dev) u16 control; unsigned long flags; - if (!pci_msi_enable) - return; - if (!dev) - return; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (!pos) + if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSI))) return; pci_read_config_word(dev, msi_control_reg(pos), &control); @@ -1013,10 +826,8 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) * Detect last MSI-X vector to be released. * Release the MSI-X memory-mapped table. */ -#if 0 int pos, nr_entries; - unsigned long phys_addr; - u32 table_offset; + u32 phys_addr, table_offset; u16 control; u8 bir; @@ -1027,12 +838,9 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset); bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); - table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; - phys_addr = pci_resource_start(dev, bir) + table_offset; -/* - * FIXME! and what did you want to do with phys_addr? - */ -#endif + phys_addr = pci_resource_start (dev, bir); + phys_addr += (u32)(table_offset & + ~PCI_MSIX_FLAGS_BIRMASK); iounmap(base); } } @@ -1116,12 +924,10 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) if (!pci_msi_enable || !dev || !entries) return -EINVAL; - status = msi_init(); - if (status < 0) + if ((status = msi_init()) < 0) return status; - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (!pos) + if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX))) return -EINVAL; pci_read_config_word(dev, msi_control_reg(pos), &control); @@ -1200,13 +1006,7 @@ void pci_disable_msix(struct pci_dev* dev) int pos, temp; u16 control; - if (!pci_msi_enable) - return; - if (!dev) - return; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (!pos) + if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX))) return; pci_read_config_word(dev, msi_control_reg(pos), &control); @@ -1266,8 +1066,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) return; temp = dev->irq; /* Save IOAPIC IRQ */ - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) > 0 && + !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { spin_lock_irqsave(&msi_lock, flags); state = msi_desc[dev->irq]->msi_attrib.state; spin_unlock_irqrestore(&msi_lock, flags); @@ -1280,8 +1080,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) msi_free_vector(dev, dev->irq, 0); dev->irq = temp; /* Restore IOAPIC IRQ */ } - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 && + !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { int vector, head, tail = 0, warning = 0; void __iomem *base = NULL; @@ -1301,9 +1101,7 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) msi_free_vector(dev, vector, 0); if (warning) { /* Force to release the MSI-X memory-mapped table */ -#if 0 - unsigned long phys_addr; - u32 table_offset; + u32 phys_addr, table_offset; u16 control; u8 bir; @@ -1312,12 +1110,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset); bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); - table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; - phys_addr = pci_resource_start(dev, bir) + table_offset; -/* - * FIXME! and what did you want to do with phys_addr? - */ -#endif + phys_addr = pci_resource_start (dev, bir); + phys_addr += (u32)(table_offset & + ~PCI_MSIX_FLAGS_BIRMASK); iounmap(base); printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " "called without free_irq() on all MSI-X vectors\n", @@ -1328,11 +1123,6 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) } } -void pci_no_msi(void) -{ - pci_msi_enable = 0; -} - EXPORT_SYMBOL(pci_enable_msi); EXPORT_SYMBOL(pci_disable_msi); EXPORT_SYMBOL(pci_enable_msix); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 10e1a905c..0aa14c92b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -53,10 +53,11 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) if (fields < 0) return -EINVAL; - dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); + dynid = kmalloc(sizeof(*dynid), GFP_KERNEL); if (!dynid) return -ENOMEM; + memset(dynid, 0, sizeof(*dynid)); INIT_LIST_HEAD(&dynid->node); dynid->id.vendor = vendor; dynid->id.device = device; @@ -271,12 +272,10 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) struct pci_driver * drv = pci_dev->driver; int i = 0; - if (drv && drv->suspend) { + if (drv && drv->suspend) i = drv->suspend(pci_dev, state); - suspend_report_result(drv->suspend, i); - } else { + else pci_save_state(pci_dev); - } return i; } @@ -285,9 +284,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) * Default resume method for devices that have no driver provided resume, * or not even a driver at all. */ -static int pci_default_resume(struct pci_dev *pci_dev) +static void pci_default_resume(struct pci_dev *pci_dev) { - int retval = 0; + int retval; /* restore the PCI config space */ pci_restore_state(pci_dev); @@ -297,21 +296,18 @@ static int pci_default_resume(struct pci_dev *pci_dev) /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); - - return retval; } static int pci_device_resume(struct device * dev) { - int error; struct pci_dev * pci_dev = to_pci_dev(dev); struct pci_driver * drv = pci_dev->driver; if (drv && drv->resume) - error = drv->resume(pci_dev); + drv->resume(pci_dev); else - error = pci_default_resume(pci_dev); - return error; + pci_default_resume(pci_dev); + return 0; } static void pci_device_shutdown(struct device *dev) @@ -384,6 +380,14 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner) /* initialize common driver fields */ drv->driver.name = drv->name; drv->driver.bus = &pci_bus_type; + /* FIXME, once all of the existing PCI drivers have been fixed to set + * the pci shutdown function, this test can go away. */ + if (!drv->driver.shutdown) + drv->driver.shutdown = pci_device_shutdown; + else + printk(KERN_WARNING "Warning: PCI driver %s has a struct " + "device_driver shutdown method, please update!\n", + drv->name); drv->driver.owner = owner; drv->driver.kobj.ktype = &pci_driver_kobj_type; @@ -510,7 +514,6 @@ struct bus_type pci_bus_type = { .probe = pci_device_probe, .remove = pci_device_remove, .suspend = pci_device_suspend, - .shutdown = pci_device_shutdown, .resume = pci_device_resume, .dev_attrs = pci_dev_attrs, }; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 56ac2bc00..965a59346 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -501,8 +501,9 @@ int pci_create_sysfs_dev_files (struct pci_dev *pdev) if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) { struct bin_attribute *rom_attr; - rom_attr = kzalloc(sizeof(*rom_attr), GFP_ATOMIC); + rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC); if (rom_attr) { + memset(rom_attr, 0x00, sizeof(*rom_attr)); pdev->rom_attr = rom_attr; rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE); rom_attr->attr.name = "rom"; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 12286275b..d2d187916 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -19,6 +19,7 @@ #include /* isa_dma_bridge_buggy */ #include "pci.h" +#if 0 /** * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children @@ -33,7 +34,7 @@ pci_bus_max_busnr(struct pci_bus* bus) struct list_head *tmp; unsigned char max, n; - max = bus->subordinate; + max = bus->number; list_for_each(tmp, &bus->children) { n = pci_bus_max_busnr(pci_bus_b(tmp)); if(n > max) @@ -41,9 +42,7 @@ pci_bus_max_busnr(struct pci_bus* bus) } return max; } -EXPORT_SYMBOL_GPL(pci_bus_max_busnr); -#if 0 /** * pci_max_busnr - returns maximum PCI bus number * @@ -307,11 +306,9 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) * Can enter D0 from any state, but if we can only go deeper * to sleep if we're already in a low power state */ - if (state != PCI_D0 && dev->current_state > state) { - printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n", - __FUNCTION__, pci_name(dev), state, dev->current_state); + if (state != PCI_D0 && dev->current_state > state) return -EINVAL; - } else if (dev->current_state == state) + else if (dev->current_state == state) return 0; /* we're already there */ /* find PCI PM capability in list */ @@ -446,10 +443,6 @@ pci_save_state(struct pci_dev *dev) /* XXX: 100% dword access ok here? */ for (i = 0; i < 16; i++) pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); - if ((i = pci_save_msi_state(dev)) != 0) - return i; - if ((i = pci_save_msix_state(dev)) != 0) - return i; return 0; } @@ -461,25 +454,9 @@ int pci_restore_state(struct pci_dev *dev) { int i; - int val; - /* - * The Base Address register should be programmed before the command - * register(s) - */ - for (i = 15; i >= 0; i--) { - pci_read_config_dword(dev, i * 4, &val); - if (val != dev->saved_config_space[i]) { - printk(KERN_DEBUG "PM: Writing back config space on " - "device %s at offset %x (was %x, writing %x)\n", - pci_name(dev), i, - val, (int)dev->saved_config_space[i]); - pci_write_config_dword(dev,i * 4, - dev->saved_config_space[i]); - } - } - pci_restore_msi_state(dev); - pci_restore_msix_state(dev); + for (i = 0; i < 16; i++) + pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); return 0; } @@ -518,8 +495,9 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) int pci_enable_device(struct pci_dev *dev) { - int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); - if (err) + int err; + + if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1))) return err; pci_fixup_device(pci_fixup_enable, dev); dev->is_enabled = 1; @@ -661,7 +639,7 @@ void pci_release_region(struct pci_dev *pdev, int bar) * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. */ -int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) +int pci_request_region(struct pci_dev *pdev, int bar, char *res_name) { if (pci_resource_len(pdev, bar) == 0) return 0; @@ -719,7 +697,7 @@ void pci_release_regions(struct pci_dev *pdev) * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. */ -int pci_request_regions(struct pci_dev *pdev, const char *res_name) +int pci_request_regions(struct pci_dev *pdev, char *res_name) { int i; @@ -922,12 +900,8 @@ static int __devinit pci_setup(char *str) if (k) *k++ = 0; if (*str && (str = pcibios_setup(str)) && *str) { - if (!strcmp(str, "nomsi")) { - pci_no_msi(); - } else { - printk(KERN_ERR "PCI: Unknown option `%s'\n", - str); - } + /* PCI layer options should be handled here */ + printk(KERN_ERR "PCI: Unknown option `%s'\n", str); } str = k; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 30630cbe2..a6dfee2f6 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -50,21 +50,8 @@ extern int pci_msi_quirk; #ifdef CONFIG_PCI_MSI void disable_msi_mode(struct pci_dev *dev, int pos, int type); -void pci_no_msi(void); #else static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { } -static inline void pci_no_msi(void) { } -#endif -#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) -int pci_save_msi_state(struct pci_dev *dev); -int pci_save_msix_state(struct pci_dev *dev); -void pci_restore_msi_state(struct pci_dev *dev); -void pci_restore_msix_state(struct pci_dev *dev); -#else -static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } -static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; } -static inline void pci_restore_msi_state(struct pci_dev *dev) {} -static inline void pci_restore_msix_state(struct pci_dev *dev) {} #endif extern int pcie_mch_quirk; diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 537b372dc..a63bd8f72 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -27,6 +27,11 @@ #define get_descriptor_id(type, service) (((type - 4) << 4) | service) +struct pcie_port_device_ext { + int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */ + unsigned int saved_msi_config_space[5]; +}; + extern struct bus_type pcie_port_bus_type; extern int pcie_port_device_probe(struct pci_dev *dev); extern int pcie_port_device_register(struct pci_dev *dev); diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 576285765..e4e5f1e8d 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include "portdrv.h" @@ -61,7 +63,7 @@ static int pcie_port_remove_service(struct device *dev) static void pcie_port_shutdown_service(struct device *dev) {} -static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32 level) +static int pcie_port_suspend_service(struct device *dev, pm_message_t state) { struct pcie_device *pciedev; struct pcie_port_service_driver *driver; @@ -76,7 +78,7 @@ static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32 return 0; } -static int pcie_port_resume_service(struct device *dev, u32 level) +static int pcie_port_resume_service(struct device *dev) { struct pcie_device *pciedev; struct pcie_port_service_driver *driver; @@ -232,19 +234,16 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, /* Initialize generic device interface */ device = &dev->device; memset(device, 0, sizeof(struct device)); - INIT_LIST_HEAD(&device->node); - INIT_LIST_HEAD(&device->children); - INIT_LIST_HEAD(&device->bus_list); device->bus = &pcie_port_bus_type; device->driver = NULL; - device->driver_data = NULL; + device->driver_data = NULL; device->release = release_pcie_device; /* callback to free pcie dev */ - sprintf(&device->bus_id[0], "pcie%02x", - get_descriptor_id(port_type, service_type)); + snprintf(device->bus_id, sizeof(device->bus_id), "%s:pcie%02x", + pci_name(parent), get_descriptor_id(port_type, service_type)); device->parent = &parent->dev; } -static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, +static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, int port_type, int service_type, int irq, int irq_mode) { struct pcie_device *device; @@ -270,27 +269,35 @@ int pcie_port_device_probe(struct pci_dev *dev) pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®); type = (reg >> 4) & PORT_TYPE_MASK; if ( type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT || - type == PCIE_SW_DOWNSTREAM_PORT ) + type == PCIE_SW_DOWNSTREAM_PORT ) return 0; - + return -ENODEV; } int pcie_port_device_register(struct pci_dev *dev) { + struct pcie_port_device_ext *p_ext; int status, type, capabilities, irq_mode, i; int vectors[PCIE_PORT_DEVICE_MAXSERVICES]; u16 reg16; + /* Allocate port device extension */ + if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL))) + return -ENOMEM; + + pci_set_drvdata(dev, p_ext); + /* Get port type */ - pci_read_config_word(dev, - pci_find_capability(dev, PCI_CAP_ID_EXP) + + pci_read_config_word(dev, + pci_find_capability(dev, PCI_CAP_ID_EXP) + PCIE_CAPABILITIES_REG, ®16); type = (reg16 >> 4) & PORT_TYPE_MASK; /* Now get port services */ capabilities = get_port_device_capability(dev); irq_mode = assign_interrupt_mode(dev, vectors, capabilities); + p_ext->interrupt_mode = irq_mode; /* Allocate child services if any */ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { @@ -299,11 +306,11 @@ int pcie_port_device_register(struct pci_dev *dev) if (capabilities & (1 << i)) { child = alloc_pcie_device( dev, /* parent */ - type, /* port type */ + type, /* port type */ i, /* service type */ vectors[i], /* irq */ irq_mode /* interrupt mode */); - if (child) { + if (child) { status = device_register(&child->device); if (status) { kfree(child); @@ -317,84 +324,78 @@ int pcie_port_device_register(struct pci_dev *dev) } #ifdef CONFIG_PM -int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state) +static int suspend_iter(struct device *dev, void *data) { - struct list_head *head, *tmp; - struct device *parent, *child; - struct device_driver *driver; struct pcie_port_service_driver *service_driver; + pm_message_t state = * (pm_message_t *) data; + + if ((dev->bus == &pcie_port_bus_type) && + (dev->driver)) { + service_driver = to_service_driver(dev->driver); + if (service_driver->suspend) + service_driver->suspend(to_pcie_device(dev), state); + } + return 0; +} - parent = &dev->dev; - head = &parent->children; - tmp = head->next; - while (head != tmp) { - child = container_of(tmp, struct device, node); - tmp = tmp->next; - if (child->bus != &pcie_port_bus_type) - continue; - driver = child->driver; - if (!driver) - continue; - service_driver = to_service_driver(driver); - if (service_driver->suspend) - service_driver->suspend(to_pcie_device(child), state); - } - return 0; +int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state) +{ + device_for_each_child(&dev->dev, &state, suspend_iter); + return 0; } -int pcie_port_device_resume(struct pci_dev *dev) -{ - struct list_head *head, *tmp; - struct device *parent, *child; - struct device_driver *driver; +static int resume_iter(struct device *dev, void *data) +{ struct pcie_port_service_driver *service_driver; - parent = &dev->dev; - head = &parent->children; - tmp = head->next; - while (head != tmp) { - child = container_of(tmp, struct device, node); - tmp = tmp->next; - if (child->bus != &pcie_port_bus_type) - continue; - driver = child->driver; - if (!driver) - continue; - service_driver = to_service_driver(driver); - if (service_driver->resume) - service_driver->resume(to_pcie_device(child)); + if ((dev->bus == &pcie_port_bus_type) && + (dev->driver)) { + service_driver = to_service_driver(dev->driver); + if (service_driver->resume) + service_driver->resume(to_pcie_device(dev)); } - return 0; + return 0; +} +int pcie_port_device_resume(struct pci_dev *dev) +{ + device_for_each_child(&dev->dev, NULL, resume_iter); + return 0; } #endif -void pcie_port_device_remove(struct pci_dev *dev) +static int remove_iter(struct device *dev, void *data) { - struct list_head *head, *tmp; - struct device *parent, *child; - struct device_driver *driver; struct pcie_port_service_driver *service_driver; - int interrupt_mode = PCIE_PORT_INTx_MODE; - parent = &dev->dev; - head = &parent->children; - tmp = head->next; - while (head != tmp) { - child = container_of(tmp, struct device, node); - tmp = tmp->next; - if (child->bus != &pcie_port_bus_type) - continue; - driver = child->driver; - if (driver) { - service_driver = to_service_driver(driver); - if (service_driver->remove) - service_driver->remove(to_pcie_device(child)); + if (dev->bus == &pcie_port_bus_type) { + if (dev->driver) { + service_driver = to_service_driver(dev->driver); + if (service_driver->remove) + service_driver->remove(to_pcie_device(dev)); } - interrupt_mode = (to_pcie_device(child))->interrupt_mode; - put_device(child); - device_unregister(child); + *(unsigned long*)data = (unsigned long)dev; + return 1; } + return 0; +} + +void pcie_port_device_remove(struct pci_dev *dev) +{ + struct device *device; + unsigned long device_addr; + int interrupt_mode = PCIE_PORT_INTx_MODE; + int status; + + do { + status = device_for_each_child(&dev->dev, &device_addr, remove_iter); + if (status) { + device = (struct device*)device_addr; + interrupt_mode = (to_pcie_device(device))->interrupt_mode; + put_device(device); + device_unregister(device); + } + } while (status); /* Switch to INTx by default if MSI enabled */ if (interrupt_mode == PCIE_PORT_MSIX_MODE) pci_disable_msix(dev); @@ -423,7 +424,7 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) new->driver.resume = pcie_port_resume_service; return driver_register(&new->driver); -} +} void pcie_port_service_unregister(struct pcie_port_service_driver *new) { diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 50bfc1b2f..02260141d 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -30,16 +30,75 @@ MODULE_LICENSE("GPL"); /* global data */ static const char device_name[] = "pcieport-driver"; -static int pcie_portdrv_save_config(struct pci_dev *dev) +static void pci_save_msi_state(struct pci_dev *dev) { - return pci_save_state(dev); + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + int i = 0, pos; + u16 control; + + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0) + return; + + pci_read_config_dword(dev, pos, &p_ext->saved_msi_config_space[i++]); + control = p_ext->saved_msi_config_space[0] >> 16; + pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, + &p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_64BIT) { + pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, + &p_ext->saved_msi_config_space[i++]); + pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, + &p_ext->saved_msi_config_space[i++]); + } else + pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, + &p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_MASKBIT) + pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, + &p_ext->saved_msi_config_space[i++]); +} + +static void pci_restore_msi_state(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + int i = 0, pos; + u16 control; + + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0) + return; + + control = p_ext->saved_msi_config_space[i++] >> 16; + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, + p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_64BIT) { + pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, + p_ext->saved_msi_config_space[i++]); + pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, + p_ext->saved_msi_config_space[i++]); + } else + pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, + p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_MASKBIT) + pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, + p_ext->saved_msi_config_space[i++]); +} + +static void pcie_portdrv_save_config(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + + pci_save_state(dev); + if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE) + pci_save_msi_state(dev); } static int pcie_portdrv_restore_config(struct pci_dev *dev) { + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); int retval; pci_restore_state(dev); + if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE) + pci_restore_msi_state(dev); retval = pci_enable_device(dev); if (retval) return retval; @@ -90,8 +149,7 @@ static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state) { int ret = pcie_port_device_suspend(dev, state); - if (!ret) - ret = pcie_portdrv_save_config(dev); + pcie_portdrv_save_config(dev); return ret; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a10ed9dab..adfad4fd6 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -33,9 +33,10 @@ LIST_HEAD(pci_devices); */ static void pci_create_legacy_files(struct pci_bus *b) { - b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2, + b->legacy_io = kmalloc(sizeof(struct bin_attribute) * 2, GFP_ATOMIC); if (b->legacy_io) { + memset(b->legacy_io, 0, sizeof(struct bin_attribute) * 2); b->legacy_io->attr.name = "legacy_io"; b->legacy_io->size = 0xffff; b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; @@ -319,8 +320,9 @@ static struct pci_bus * __devinit pci_alloc_bus(void) { struct pci_bus *b; - b = kzalloc(sizeof(*b), GFP_KERNEL); + b = kmalloc(sizeof(*b), GFP_KERNEL); if (b) { + memset(b, 0, sizeof(*b)); INIT_LIST_HEAD(&b->node); INIT_LIST_HEAD(&b->children); INIT_LIST_HEAD(&b->devices); @@ -345,7 +347,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) child->parent = parent; child->ops = parent->ops; child->sysdata = parent->sysdata; - child->bus_flags = parent->bus_flags; child->bridge = get_device(&bridge->dev); child->class_dev.class = &pcibus_class; @@ -455,7 +456,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max * pass and just note the configuration. */ if (pass) - goto out; + return max; busnr = (buses >> 8) & 0xFF; /* @@ -465,12 +466,12 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max if (pci_find_bus(pci_domain_nr(bus), busnr)) { printk(KERN_INFO "PCI: Bus %04x:%02x already known\n", pci_domain_nr(bus), busnr); - goto out; + return max; } child = pci_add_new_bus(bus, dev, busnr); if (!child) - goto out; + return max; child->primary = buses & 0xFF; child->subordinate = (buses >> 16) & 0xFF; child->bridge_ctl = bctl; @@ -495,7 +496,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max bus ranges. */ pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses & ~0xffffff); - goto out; + return max; } /* Clear errors */ @@ -504,7 +505,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max /* Prevent assigning a bus number that already exists. * This can happen when a bridge is hot-plugged */ if (pci_find_bus(pci_domain_nr(bus), max+1)) - goto out; + return max; child = pci_add_new_bus(bus, dev, ++max); buses = (buses & 0xff000000) | ((unsigned int)(child->primary) << 0) @@ -536,11 +537,6 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max pci_fixup_parent_subordinate_busnr(child, max); /* Now we can scan all subordinate buses... */ max = pci_scan_child_bus(child); - /* - * now fix it up again since we have found - * the real value of max. - */ - pci_fixup_parent_subordinate_busnr(child, max); } else { /* * For CardBus bridges, we leave 4 bus numbers @@ -580,6 +576,8 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); } + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); + sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); while (bus->parent) { @@ -587,22 +585,17 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max (child->number > bus->subordinate) || (child->number < bus->number) || (child->subordinate < bus->number)) { - printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is " + printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) may be " "hidden behind%s bridge #%02x (-#%02x)%s\n", child->number, child->subordinate, bus->self->transparent ? " transparent" : " ", bus->number, bus->subordinate, pcibios_assign_all_busses() ? " " : " (try 'pci=assign-busses')"); - printk(KERN_WARNING "Please report the result to " - "linux-kernel to fix this permanently\n"); } bus = bus->parent; } -out: - pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); - return max; } @@ -795,10 +788,11 @@ pci_scan_device(struct pci_bus *bus, int devfn) if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) return NULL; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) return NULL; + memset(dev, 0, sizeof(struct pci_dev)); dev->bus = bus; dev->sysdata = bus->sysdata; dev->dev.parent = bus->bridge; diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 54b2ebc9c..92a885760 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -458,6 +458,131 @@ int pci_proc_detach_bus(struct pci_bus* bus) return 0; } +#ifdef CONFIG_PCI_LEGACY_PROC + +/* + * Backward compatible /proc/pci interface. + */ + +/* + * Convert some of the configuration space registers of the device at + * address (bus,devfn) into a string (possibly several lines each). + * The configuration string is stored starting at buf[len]. If the + * string would exceed the size of the buffer (SIZE), 0 is returned. + */ +static int show_dev_config(struct seq_file *m, void *v) +{ + struct pci_dev *dev = v; + struct pci_dev *first_dev; + struct pci_driver *drv; + u32 class_rev; + unsigned char latency, min_gnt, max_lat; + int reg; + + first_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); + if (dev == first_dev) + seq_puts(m, "PCI devices found:\n"); + pci_dev_put(first_dev); + + drv = pci_dev_driver(dev); + + pci_user_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + pci_user_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); + pci_user_read_config_byte (dev, PCI_MIN_GNT, &min_gnt); + pci_user_read_config_byte (dev, PCI_MAX_LAT, &max_lat); + seq_printf(m, " Bus %2d, device %3d, function %2d:\n", + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + seq_printf(m, " Class %04x", class_rev >> 16); + seq_printf(m, ": PCI device %04x:%04x", dev->vendor, dev->device); + seq_printf(m, " (rev %d).\n", class_rev & 0xff); + + if (dev->irq) + seq_printf(m, " IRQ %d.\n", dev->irq); + + if (latency || min_gnt || max_lat) { + seq_printf(m, " Master Capable. "); + if (latency) + seq_printf(m, "Latency=%d. ", latency); + else + seq_puts(m, "No bursts. "); + if (min_gnt) + seq_printf(m, "Min Gnt=%d.", min_gnt); + if (max_lat) + seq_printf(m, "Max Lat=%d.", max_lat); + seq_putc(m, '\n'); + } + + for (reg = 0; reg < 6; reg++) { + struct resource *res = dev->resource + reg; + unsigned long base, end, flags; + + base = res->start; + end = res->end; + flags = res->flags; + if (!end) + continue; + + if (flags & PCI_BASE_ADDRESS_SPACE_IO) { + seq_printf(m, " I/O at 0x%lx [0x%lx].\n", + base, end); + } else { + const char *pref, *type = "unknown"; + + if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH) + pref = "P"; + else + pref = "Non-p"; + switch (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { + case PCI_BASE_ADDRESS_MEM_TYPE_32: + type = "32 bit"; break; + case PCI_BASE_ADDRESS_MEM_TYPE_1M: + type = "20 bit"; break; + case PCI_BASE_ADDRESS_MEM_TYPE_64: + type = "64 bit"; break; + } + seq_printf(m, " %srefetchable %s memory at " + "0x%lx [0x%lx].\n", pref, type, + base, + end); + } + } + return 0; +} + +static struct seq_operations proc_pci_op = { + .start = pci_seq_start, + .next = pci_seq_next, + .stop = pci_seq_stop, + .show = show_dev_config +}; + +static int proc_pci_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &proc_pci_op); +} +static struct file_operations proc_pci_operations = { + .open = proc_pci_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static void legacy_proc_init(void) +{ + struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL); + if (entry) + entry->proc_fops = &proc_pci_operations; +} + +#else + +static void legacy_proc_init(void) +{ + +} + +#endif /* CONFIG_PCI_LEGACY_PROC */ + static int proc_bus_pci_dev_open(struct inode *inode, struct file *file) { return seq_open(file, &proc_bus_pci_devices_op); @@ -481,6 +606,7 @@ static int __init pci_proc_init(void) while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { pci_proc_attach_device(dev); } + legacy_proc_init(); return 0; } diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6e3786f4d..2a66e3952 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -390,6 +390,7 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev) piix4_io_quirk(dev, "PIIX4 devres J", 0x7c, 1 << 20); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, quirk_piix4_acpi ); /* * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at @@ -429,6 +430,12 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi ); /* * VIA ACPI: One IO region pointed to by longword at @@ -576,11 +583,8 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) { unsigned char revid, tmp; - if (dev->subordinate) { - printk(KERN_WARNING "PCI: MSI quirk detected. " - "PCI_BUS_FLAGS_NO_MSI set for subordinate bus.\n"); - dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; - } + pci_msi_quirk = 1; + printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); if (nr_ioapics == 0) return; @@ -652,13 +656,7 @@ static void quirk_via_irq(struct pci_dev *dev) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); } } -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); /* * VIA VT82C598 has its device ID settable and many BIOSes @@ -874,35 +872,6 @@ static void __init quirk_eisa_bridge(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge ); -/* - * On the MSI-K8T-Neo2Fir Board, the internal Soundcard is disabled - * when a PCI-Soundcard is added. The BIOS only gives Options - * "Disabled" and "AUTO". This Quirk Sets the corresponding - * Register-Value to enable the Soundcard. - */ -static void __init k8t_sound_hostbridge(struct pci_dev *dev) -{ - unsigned char val; - - printk(KERN_INFO "PCI: Quirk-MSI-K8T Soundcard On\n"); - pci_read_config_byte(dev, 0x50, &val); - if (val == 0x88 || val == 0xc8) { - pci_write_config_byte(dev, 0x50, val & (~0x40)); - - /* Verify the Change for Status output */ - pci_read_config_byte(dev, 0x50, &val); - if (val & 0x40) - printk(KERN_INFO "PCI: MSI-K8T soundcard still off\n"); - else - printk(KERN_INFO "PCI: MSI-K8T soundcard on\n"); - } else { - printk(KERN_INFO "PCI: Unexpected Value in PCI-Register: " - "no Change!\n"); - } - -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); - #ifndef CONFIG_ACPI_SLEEP /* * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge @@ -950,6 +919,11 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x8070: /* P4G8X Deluxe */ asus_hides_smbus = 1; } + if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH) + switch (dev->subsystem_device) { + case 0x80c9: /* PU-DLS */ + asus_hides_smbus = 1; + } if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) switch (dev->subsystem_device) { case 0x1751: /* M2N notebook */ @@ -965,7 +939,6 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { switch (dev->subsystem_device) { case 0x1882: /* M6V notebook */ - case 0x1977: /* A6VA notebook */ asus_hides_smbus = 1; } } @@ -982,12 +955,6 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x12bd: /* HP D530 */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { - switch (dev->subsystem_device) { - case 0x099c: /* HP Compaq nx6110 */ - asus_hides_smbus = 1; - } - } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) switch(dev->subsystem_device) { @@ -1018,6 +985,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asu DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7501_MCH, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); @@ -1041,6 +1009,7 @@ static void __init asus_hides_smbus_lpc(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); @@ -1124,37 +1093,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); -/* - * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller - * and MC97 modem controller are disabled when a second PCI soundcard is - * present. This patch, tweaking the VT8237 ISA bridge, enables them. - * -- bjd - */ -static void __init asus_hides_ac97_lpc(struct pci_dev *dev) -{ - u8 val; - int asus_hides_ac97 = 0; - - if (likely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) { - if (dev->device == PCI_DEVICE_ID_VIA_8237) - asus_hides_ac97 = 1; - } - - if (!asus_hides_ac97) - return; - - pci_read_config_byte(dev, 0x50, &val); - if (val & 0xc0) { - pci_write_config_byte(dev, 0x50, val & (~0xc0)); - pci_read_config_byte(dev, 0x50, &val); - if (val & 0xc0) - printk(KERN_INFO "PCI: onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n", val); - else - printk(KERN_INFO "PCI: enabled onboard AC97/MC97 devices\n"); - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); @@ -1329,33 +1267,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1, quirk_pc DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV, quirk_pcie_pxh); -/* - * Fixup the cardbus bridges on the IBM Dock II docking station - */ -static void __devinit quirk_ibm_dock2_cardbus(struct pci_dev *dev) -{ - u32 val; - - /* - * tie the 2 interrupt pins to INTA, and configure the - * multifunction routing register to handle this. - */ - if ((dev->subsystem_vendor == PCI_VENDOR_ID_IBM) && - (dev->subsystem_device == 0x0148)) { - printk(KERN_INFO "PCI: Found IBM Dock II Cardbus Bridge " - "applying quirk\n"); - pci_read_config_dword(dev, 0x8c, &val); - val = ((val & 0xffffff00) | 0x1002); - pci_write_config_dword(dev, 0x8c, val); - pci_read_config_dword(dev, 0x80, &val); - val = ((val & 0x00ffff00) | 0x2864c077); - pci_write_config_dword(dev, 0x80, val); - } -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, - quirk_ibm_dock2_cardbus); - static void __devinit quirk_netmos(struct pci_dev *dev) { unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4; @@ -1390,6 +1301,63 @@ static void __devinit quirk_netmos(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); +static void __devinit quirk_e100_interrupt(struct pci_dev *dev) +{ + u16 command; + u32 bar; + u8 __iomem *csr; + u8 cmd_hi; + + switch (dev->device) { + /* PCI IDs taken from drivers/net/e100.c */ + case 0x1029: + case 0x1030 ... 0x1034: + case 0x1038 ... 0x103E: + case 0x1050 ... 0x1057: + case 0x1059: + case 0x1064 ... 0x106B: + case 0x1091 ... 0x1095: + case 0x1209: + case 0x1229: + case 0x2449: + case 0x2459: + case 0x245D: + case 0x27DC: + break; + default: + return; + } + + /* + * Some firmware hands off the e100 with interrupts enabled, + * which can cause a flood of interrupts if packets are + * received before the driver attaches to the device. So + * disable all e100 interrupts here. The driver will + * re-enable them when it's ready. + */ + pci_read_config_word(dev, PCI_COMMAND, &command); + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar); + + if (!(command & PCI_COMMAND_MEMORY) || !bar) + return; + + csr = ioremap(bar, 8); + if (!csr) { + printk(KERN_WARNING "PCI: Can't map %s e100 registers\n", + pci_name(dev)); + return; + } + + cmd_hi = readb(csr + 3); + if (cmd_hi == 0) { + printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts " + "enabled, disabling\n", pci_name(dev)); + writeb(1, csr + 3); + } + + iounmap(csr); +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); static void __devinit fixup_rev1_53c810(struct pci_dev* dev) { @@ -1485,6 +1453,25 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); +/* Under some circumstances, AER is not linked with extended capabilities. + * Force it to be linked by setting the corresponding control bit in the + * config space. + */ +static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) +{ + uint8_t b; + if (pci_read_config_byte(dev, 0xf41, &b) == 0) { + if (!(b & 0x20)) { + pci_write_config_byte(dev, 0xf41, b | 0x20); + printk(KERN_INFO + "PCI: Linking AER extended capability on %s\n", + pci_name(dev)); + } + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, + quirk_nvidia_ck804_pcie_aer_ext_cap); + EXPORT_SYMBOL(pcie_mch_quirk); #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_fixup_device); diff --git a/drivers/pci/search.c b/drivers/pci/search.c index ce7dd6e7b..05fa91a31 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -246,9 +246,9 @@ pci_get_subsys(unsigned int vendor, unsigned int device, } dev = NULL; exit: + pci_dev_put(from); dev = pci_dev_get(dev); spin_unlock(&pci_bus_lock); - pci_dev_put(from); return dev; } @@ -339,9 +339,9 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) } dev = NULL; exit: + pci_dev_put(from); dev = pci_dev_get(dev); spin_unlock(&pci_bus_lock); - pci_dev_put(from); return dev; } diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 61cb4b29f..1f4ad0e78 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -250,7 +250,7 @@ config M32R_CFC_NUM config PCMCIA_VRC4171 tristate "NEC VRC4171 Card Controllers support" - depends on CPU_VR41XX && ISA && PCMCIA + depends on VRC4171 && PCMCIA config PCMCIA_VRC4173 tristate "NEC VRC4173 CARDU support" @@ -263,13 +263,6 @@ config OMAP_CF Say Y here to support the CompactFlash controller on OMAP. Note that this doesn't support "True IDE" mode. -config AT91_CF - tristate "AT91 CompactFlash Controller" - depends on PCMCIA && ARCH_AT91RM9200 - help - Say Y here to support the CompactFlash controller on AT91 chips. - Or choose M to compile the driver as a module named "at91_cf". - config PCCARD_NONSTATIC tristate diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 427696551..bcecf5133 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -10,7 +10,7 @@ pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o obj-$(CONFIG_PCCARD) += pcmcia_core.o -pcmcia-y += ds.o pcmcia_resource.o +pcmcia-y += ds.o pcmcia_compat.o pcmcia_resource.o pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o obj-$(CONFIG_PCMCIA) += pcmcia.o @@ -36,7 +36,6 @@ obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o obj-$(CONFIG_OMAP_CF) += omap_cf.o -obj-$(CONFIG_AT91_CF) += at91_cf.o sa11xx_core-y += soc_common.o sa11xx_base.o pxa2xx_core-y += soc_common.o pxa2xx_base.o diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c deleted file mode 100644 index a4d50940e..000000000 --- a/drivers/pcmcia/at91_cf.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * at91_cf.c -- AT91 CompactFlash controller driver - * - * Copyright (C) 2005 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 -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - - -/* - * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; - * some other bit in {A24,A22..A11} is nREG to flag memory access - * (vs attributes). So more than 2KB/region would just be waste. - */ -#define CF_ATTR_PHYS (AT91_CF_BASE) -#define CF_IO_PHYS (AT91_CF_BASE + (1 << 23)) -#define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800) - -/*--------------------------------------------------------------------------*/ - -static const char driver_name[] = "at91_cf"; - -struct at91_cf_socket { - struct pcmcia_socket socket; - - unsigned present:1; - - struct platform_device *pdev; - struct at91_cf_data *board; -}; - -#define SZ_2K (2 * SZ_1K) - -static inline int at91_cf_present(struct at91_cf_socket *cf) -{ - return !at91_get_gpio_value(cf->board->det_pin); -} - -/*--------------------------------------------------------------------------*/ - -static int at91_cf_ss_init(struct pcmcia_socket *s) -{ - return 0; -} - -static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r) -{ - struct at91_cf_socket *cf = (struct at91_cf_socket *) _cf; - - if (irq == cf->board->det_pin) { - unsigned present = at91_cf_present(cf); - - /* kick pccard as needed */ - if (present != cf->present) { - cf->present = present; - pr_debug("%s: card %s\n", driver_name, - present ? "present" : "gone"); - pcmcia_parse_events(&cf->socket, SS_DETECT); - } - } - - return IRQ_HANDLED; -} - -static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) -{ - struct at91_cf_socket *cf; - - if (!sp) - return -EINVAL; - - cf = container_of(s, struct at91_cf_socket, socket); - - /* NOTE: CF is always 3VCARD */ - if (at91_cf_present(cf)) { - int rdy = cf->board->irq_pin; /* RDY/nIRQ */ - int vcc = cf->board->vcc_pin; - - *sp = SS_DETECT | SS_3VCARD; - if (!rdy || at91_get_gpio_value(rdy)) - *sp |= SS_READY; - if (!vcc || at91_get_gpio_value(vcc)) - *sp |= SS_POWERON; - } else - *sp = 0; - - return 0; -} - -static int -at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) -{ - struct at91_cf_socket *cf; - - cf = container_of(sock, struct at91_cf_socket, socket); - - /* switch Vcc if needed and possible */ - if (cf->board->vcc_pin) { - switch (s->Vcc) { - case 0: - at91_set_gpio_value(cf->board->vcc_pin, 0); - break; - case 33: - at91_set_gpio_value(cf->board->vcc_pin, 1); - break; - default: - return -EINVAL; - } - } - - /* toggle reset if needed */ - at91_set_gpio_value(cf->board->rst_pin, s->flags & SS_RESET); - - pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", - driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); - - return 0; -} - -static int at91_cf_ss_suspend(struct pcmcia_socket *s) -{ - return at91_cf_set_socket(s, &dead_socket); -} - -/* we already mapped the I/O region */ -static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) -{ - struct at91_cf_socket *cf; - u32 csr; - - cf = container_of(s, struct at91_cf_socket, socket); - io->flags &= (MAP_ACTIVE | MAP_16BIT | MAP_AUTOSZ); - - /* - * Use 16 bit accesses unless/until we need 8-bit i/o space. - * Always set CSR4 ... PCMCIA won't always unmap things. - */ - csr = at91_sys_read(AT91_SMC_CSR(4)) & ~AT91_SMC_DBW; - - /* - * NOTE: this CF controller ignores IOIS16, so we can't really do - * MAP_AUTOSZ. The 16bit mode allows single byte access on either - * D0-D7 (even addr) or D8-D15 (odd), so it's close enough for many - * purposes (and handles ide-cs). - * - * The 8bit mode is needed for odd byte access on D0-D7. It seems - * some cards only like that way to get at the odd byte, despite - * CF 3.0 spec table 35 also giving the D8-D15 option. - */ - if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) { - csr |= AT91_SMC_DBW_8; - pr_debug("%s: 8bit i/o bus\n", driver_name); - } else { - csr |= AT91_SMC_DBW_16; - pr_debug("%s: 16bit i/o bus\n", driver_name); - } - at91_sys_write(AT91_SMC_CSR(4), csr); - - io->start = cf->socket.io_offset; - io->stop = io->start + SZ_2K - 1; - - return 0; -} - -/* pcmcia layer maps/unmaps mem regions */ -static int -at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) -{ - struct at91_cf_socket *cf; - - if (map->card_start) - return -EINVAL; - - cf = container_of(s, struct at91_cf_socket, socket); - - map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT; - if (map->flags & MAP_ATTRIB) - map->static_start = CF_ATTR_PHYS; - else - map->static_start = CF_MEM_PHYS; - - return 0; -} - -static struct pccard_operations at91_cf_ops = { - .init = at91_cf_ss_init, - .suspend = at91_cf_ss_suspend, - .get_status = at91_cf_get_status, - .set_socket = at91_cf_set_socket, - .set_io_map = at91_cf_set_io_map, - .set_mem_map = at91_cf_set_mem_map, -}; - -/*--------------------------------------------------------------------------*/ - -static int __init at91_cf_probe(struct device *dev) -{ - struct at91_cf_socket *cf; - struct at91_cf_data *board = dev->platform_data; - struct platform_device *pdev = to_platform_device(dev); - struct resource *io; - unsigned int csa; - int status; - - if (!board || !board->det_pin || !board->rst_pin) - return -ENODEV; - - io = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!io) - return -ENODEV; - - cf = kcalloc(1, sizeof *cf, GFP_KERNEL); - if (!cf) - return -ENOMEM; - - cf->board = board; - cf->pdev = pdev; - dev_set_drvdata(dev, cf); - - /* CF takes over CS4, CS5, CS6 */ - csa = at91_sys_read(AT91_EBI_CSA); - at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); - - /* force poweron defaults for these pins ... */ - (void) at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ - (void) at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ - (void) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ - (void) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ - - /* nWAIT is _not_ a default setting */ - (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ - - /* - * Static memory controller timing adjustments. - * REVISIT: these timings are in terms of MCK cycles, so - * when MCK changes (cpufreq etc) so must these values... - */ - at91_sys_write(AT91_SMC_CSR(4), - AT91_SMC_ACSS_STD - | AT91_SMC_DBW_16 - | AT91_SMC_BAT - | AT91_SMC_WSEN - | AT91_SMC_NWS_(32) /* wait states */ - | AT91_SMC_RWSETUP_(6) /* setup time */ - | AT91_SMC_RWHOLD_(4) /* hold time */ - ); - - /* must be a GPIO; ergo must trigger on both edges */ - status = request_irq(board->det_pin, at91_cf_irq, - SA_SAMPLE_RANDOM, driver_name, cf); - if (status < 0) - goto fail0; - - /* - * The card driver will request this irq later as needed. - * but it causes lots of "irqNN: nobody cared" messages - * unless we report that we handle everything (sigh). - * (Note: DK board doesn't wire the IRQ pin...) - */ - if (board->irq_pin) { - status = request_irq(board->irq_pin, at91_cf_irq, - SA_SHIRQ, driver_name, cf); - if (status < 0) - goto fail0a; - cf->socket.pci_irq = board->irq_pin; - } else - cf->socket.pci_irq = NR_IRQS + 1; - - /* pcmcia layer only remaps "real" memory not iospace */ - cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K); - if (!cf->socket.io_offset) - goto fail1; - - /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ - if (!request_mem_region(io->start, io->end + 1 - io->start, - driver_name)) - goto fail1; - - pr_info("%s: irqs det #%d, io #%d\n", driver_name, - board->det_pin, board->irq_pin); - - cf->socket.owner = THIS_MODULE; - cf->socket.dev.dev = dev; - cf->socket.ops = &at91_cf_ops; - cf->socket.resource_ops = &pccard_static_ops; - cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP - | SS_CAP_MEM_ALIGN; - cf->socket.map_size = SZ_2K; - cf->socket.io[0].res = io; - - status = pcmcia_register_socket(&cf->socket); - if (status < 0) - goto fail2; - - return 0; - -fail2: - iounmap((void __iomem *) cf->socket.io_offset); - release_mem_region(io->start, io->end + 1 - io->start); -fail1: - if (board->irq_pin) - free_irq(board->irq_pin, cf); -fail0a: - free_irq(board->det_pin, cf); -fail0: - at91_sys_write(AT91_EBI_CSA, csa); - kfree(cf); - return status; -} - -static int __exit at91_cf_remove(struct device *dev) -{ - struct at91_cf_socket *cf = dev_get_drvdata(dev); - struct resource *io = cf->socket.io[0].res; - unsigned int csa; - - pcmcia_unregister_socket(&cf->socket); - free_irq(cf->board->irq_pin, cf); - free_irq(cf->board->det_pin, cf); - iounmap((void __iomem *) cf->socket.io_offset); - release_mem_region(io->start, io->end + 1 - io->start); - - csa = at91_sys_read(AT91_EBI_CSA); - at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A); - - kfree(cf); - return 0; -} - -static struct device_driver at91_cf_driver = { - .name = (char *) driver_name, - .bus = &platform_bus_type, - .probe = at91_cf_probe, - .remove = __exit_p(at91_cf_remove), - .suspend = pcmcia_socket_dev_suspend, - .resume = pcmcia_socket_dev_resume, -}; - -/*--------------------------------------------------------------------------*/ - -static int __init at91_cf_init(void) -{ - return driver_register(&at91_cf_driver); -} -module_init(at91_cf_init); - -static void __exit at91_cf_exit(void) -{ - driver_unregister(&at91_cf_driver); -} -module_exit(at91_cf_exit); - -MODULE_DESCRIPTION("AT91 Compact Flash Driver"); -MODULE_AUTHOR("David Brownell"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 912c03e5e..120fa8da6 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -12,6 +12,7 @@ * (C) 1999 David A. Hinds */ +#include #include #include #include diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 316299857..613f2f1fb 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -110,9 +111,9 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state) list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { if (socket->dev.dev != dev) continue; - mutex_lock(&socket->skt_mutex); + down(&socket->skt_sem); socket_suspend(socket); - mutex_unlock(&socket->skt_mutex); + up(&socket->skt_sem); } up_read(&pcmcia_socket_list_rwsem); @@ -128,9 +129,9 @@ int pcmcia_socket_dev_resume(struct device *dev) list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { if (socket->dev.dev != dev) continue; - mutex_lock(&socket->skt_mutex); + down(&socket->skt_sem); socket_resume(socket); - mutex_unlock(&socket->skt_mutex); + up(&socket->skt_sem); } up_read(&pcmcia_socket_list_rwsem); @@ -236,7 +237,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) init_completion(&socket->socket_released); init_completion(&socket->thread_done); init_waitqueue_head(&socket->thread_wait); - mutex_init(&socket->skt_mutex); + init_MUTEX(&socket->skt_sem); spin_lock_init(&socket->thread_lock); ret = kernel_thread(pccardd, socket, CLONE_KERNEL); @@ -405,6 +406,8 @@ static void socket_shutdown(struct pcmcia_socket *s) cb_free(s); #endif s->functions = 0; + kfree(s->config); + s->config = NULL; s->ops->get_status(s, &status); if (status & SS_POWERON) { @@ -661,7 +664,7 @@ static int pccardd(void *__skt) spin_unlock_irqrestore(&skt->thread_lock, flags); if (events) { - mutex_lock(&skt->skt_mutex); + down(&skt->skt_sem); if (events & SS_DETECT) socket_detect_change(skt); if (events & SS_BATDEAD) @@ -670,7 +673,7 @@ static int pccardd(void *__skt) send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW); if (events & SS_READY) send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW); - mutex_unlock(&skt->skt_mutex); + up(&skt->skt_sem); continue; } @@ -714,8 +717,8 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c) { int ret = 0; - /* s->skt_mutex also protects s->callback */ - mutex_lock(&s->skt_mutex); + /* s->skt_sem also protects s->callback */ + down(&s->skt_sem); if (c) { /* registration */ @@ -731,7 +734,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c) } else s->callback = NULL; err: - mutex_unlock(&s->skt_mutex); + up(&s->skt_sem); return ret; } @@ -749,7 +752,7 @@ int pccard_reset_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "resetting socket\n"); - mutex_lock(&skt->skt_mutex); + down(&skt->skt_sem); do { if (!(skt->state & SOCKET_PRESENT)) { ret = CS_NO_CARD; @@ -778,7 +781,7 @@ int pccard_reset_card(struct pcmcia_socket *skt) ret = CS_SUCCESS; } while (0); - mutex_unlock(&skt->skt_mutex); + up(&skt->skt_sem); return ret; } /* reset_card */ @@ -794,7 +797,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "suspending socket\n"); - mutex_lock(&skt->skt_mutex); + down(&skt->skt_sem); do { if (!(skt->state & SOCKET_PRESENT)) { ret = CS_NO_CARD; @@ -811,7 +814,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) } ret = socket_suspend(skt); } while (0); - mutex_unlock(&skt->skt_mutex); + up(&skt->skt_sem); return ret; } /* suspend_card */ @@ -824,7 +827,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "waking up socket\n"); - mutex_lock(&skt->skt_mutex); + down(&skt->skt_sem); do { if (!(skt->state & SOCKET_PRESENT)) { ret = CS_NO_CARD; @@ -838,7 +841,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) if (!ret && skt->callback) skt->callback->resume(skt); } while (0); - mutex_unlock(&skt->skt_mutex); + up(&skt->skt_sem); return ret; } /* resume_card */ @@ -852,7 +855,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "user eject request\n"); - mutex_lock(&skt->skt_mutex); + down(&skt->skt_sem); do { if (!(skt->state & SOCKET_PRESENT)) { ret = -ENODEV; @@ -868,7 +871,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt) socket_remove(skt); ret = 0; } while (0); - mutex_unlock(&skt->skt_mutex); + up(&skt->skt_sem); return ret; } /* eject_card */ @@ -881,7 +884,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) cs_dbg(skt, 1, "user insert request\n"); - mutex_lock(&skt->skt_mutex); + down(&skt->skt_sem); do { if (skt->state & SOCKET_PRESENT) { ret = -EBUSY; @@ -893,7 +896,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) } ret = 0; } while (0); - mutex_unlock(&skt->skt_mutex); + up(&skt->skt_sem); return ret; } /* insert_card */ diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index d6164cd58..7b37eba35 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -15,7 +15,7 @@ #ifndef _LINUX_CS_INTERNAL_H #define _LINUX_CS_INTERNAL_H -#include +#include /* Flags in client state */ #define CLIENT_CONFIG_LOCKED 0x0001 @@ -23,7 +23,7 @@ #define CLIENT_IO_REQ 0x0004 #define CLIENT_UNBOUND 0x0008 #define CLIENT_STALE 0x0010 -#define CLIENT_WIN_REQ(i) (0x1<<(i)) +#define CLIENT_WIN_REQ(i) (0x20<<(i)) #define CLIENT_CARDBUS 0x8000 #define REGION_MAGIC 0xE3C9 @@ -31,7 +31,7 @@ typedef struct region_t { u_short region_magic; u_short state; dev_info_t dev_info; - struct pcmcia_device *mtd; + client_handle_t mtd; u_int MediaID; region_info_t info; } region_t; @@ -40,12 +40,12 @@ typedef struct region_t { /* Each card function gets one of these guys */ typedef struct config_t { - struct kref ref; u_int state; u_int Attributes; u_int IntType; u_int ConfigBase; u_char Status, Pin, Copy, Option, ExtStatus; + u_int Present; u_int CardValues; io_req_t io; struct { @@ -95,6 +95,12 @@ static inline void cs_socket_put(struct pcmcia_socket *skt) } } +#define CHECK_SOCKET(s) \ + (((s) >= sockets) || (socket_table[s]->ops == NULL)) + +#define SOCKET(h) (h->socket) +#define CONFIG(h) (&SOCKET(h)->config[(h)->func]) + /* In cardbus.c */ int cb_alloc(struct pcmcia_socket *s); void cb_free(struct pcmcia_socket *s); @@ -127,9 +133,10 @@ extern struct class_interface pccard_sysfs_interface; extern struct rw_semaphore pcmcia_socket_list_rwsem; extern struct list_head pcmcia_socket_list; int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req); -int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config); +int pccard_get_configuration_info(struct pcmcia_socket *s, unsigned int function, config_info_t *config); int pccard_reset_card(struct pcmcia_socket *skt); -int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status); +int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status); +int pccard_access_configuration_register(struct pcmcia_socket *s, unsigned int function, conf_reg_t *reg); struct pcmcia_callback{ diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 74b3124e8..a4333a826 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -10,9 +10,10 @@ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * (C) 1999 David A. Hinds - * (C) 2003 - 2006 Dominik Brodowski + * (C) 2003 - 2005 Dominik Brodowski */ +#include #include #include #include @@ -22,7 +23,6 @@ #include #include #include -#include #define IN_CARD_SERVICES #include @@ -236,11 +236,11 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) /** * pcmcia_load_firmware - load CIS from userspace if device-provided is broken * @dev - the pcmcia device which needs a CIS override - * @filename - requested filename in /lib/firmware/ + * @filename - requested filename in /lib/firmware/cis/ * * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if * the one provided by the card is broken. The firmware files reside in - * /lib/firmware/ in userspace. + * /lib/firmware/cis/ in userspace. */ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) { @@ -298,6 +298,9 @@ static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filenam * * Registers a PCMCIA driver with the PCMCIA bus core. */ +static int pcmcia_device_probe(struct device *dev); +static int pcmcia_device_remove(struct device * dev); + int pcmcia_register_driver(struct pcmcia_driver *driver) { if (!driver) @@ -340,19 +343,12 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev) put_device(&p_dev->dev); } -static void pcmcia_release_function(struct kref *ref) -{ - struct config_t *c = container_of(ref, struct config_t, ref); - kfree(c); -} - static void pcmcia_release_dev(struct device *dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); ds_dbg(1, "releasing dev %p\n", p_dev); pcmcia_put_socket(p_dev->socket); kfree(p_dev->devname); - kref_put(&p_dev->function_config->ref, pcmcia_release_function); kfree(p_dev); } @@ -381,12 +377,29 @@ static int pcmcia_device_probe(struct device * dev) p_drv = to_pcmcia_drv(dev->driver); s = p_dev->socket; - if ((!p_drv->probe) || (!p_dev->function_config) || - (!try_module_get(p_drv->owner))) { + if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) { ret = -EINVAL; goto put_dev; } + p_dev->state &= ~CLIENT_UNBOUND; + + /* set up the device configuration, if it hasn't been done before */ + if (!s->functions) { + cistpl_longlink_mfc_t mfc; + if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, + &mfc) == CS_SUCCESS) + s->functions = mfc.nfn; + else + s->functions = 1; + s->config = kzalloc(sizeof(config_t) * s->functions, + GFP_KERNEL); + if (!s->config) { + ret = -ENOMEM; + goto put_module; + } + } + ret = p_drv->probe(p_dev); if (ret) goto put_module; @@ -397,7 +410,7 @@ static int pcmcia_device_probe(struct device * dev) * call which will then check whether there are two * pseudo devices, and if not, add the second one. */ - did = p_dev->dev.driver_data; + did = (struct pcmcia_device_id *) p_dev->dev.driver_data; if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) pcmcia_add_pseudo_device(p_dev->socket); @@ -412,79 +425,33 @@ static int pcmcia_device_probe(struct device * dev) } -/* - * Removes a PCMCIA card from the device tree and socket list. - */ -static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *leftover) -{ - struct pcmcia_device *p_dev; - struct pcmcia_device *tmp; - unsigned long flags; - - ds_dbg(2, "unbind_request(%d)\n", s->sock); - - - if (!leftover) - s->device_count = 0; - else - s->device_count = 1; - - /* unregister all pcmcia_devices registered with this socket, except leftover */ - list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) { - if (p_dev == leftover) - continue; - - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); - list_del(&p_dev->socket_device_list); - p_dev->_removed=1; - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - - device_unregister(&p_dev->dev); - } - - return; -} - static int pcmcia_device_remove(struct device * dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; - struct pcmcia_device_id *did; int i; + /* detach the "instance" */ p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); - - /* If we're removing the primary module driving a - * pseudo multi-function card, we need to unbind - * all devices - */ - did = p_dev->dev.driver_data; - if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && - (p_dev->socket->device_count != 0) && - (p_dev->device_no == 0)) - pcmcia_card_remove(p_dev->socket, p_dev); - - /* detach the "instance" */ if (!p_drv) return 0; if (p_drv->remove) p_drv->remove(p_dev); - p_dev->dev_node = NULL; - /* check for proper unloading */ - if (p_dev->_irq || p_dev->_io || p_dev->_locked) + if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", p_drv->drv.name); for (i = 0; i < MAX_WIN; i++) - if (p_dev->_win & CLIENT_WIN_REQ(i)) + if (p_dev->state & CLIENT_WIN_REQ(i)) printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", p_drv->drv.name); /* references from pcmcia_probe_device */ + p_dev->state = CLIENT_UNBOUND; pcmcia_put_dev(p_dev); module_put(p_drv->owner); @@ -492,6 +459,37 @@ static int pcmcia_device_remove(struct device * dev) } +/* + * Removes a PCMCIA card from the device tree and socket list. + */ +static void pcmcia_card_remove(struct pcmcia_socket *s) +{ + struct pcmcia_device *p_dev; + unsigned long flags; + + ds_dbg(2, "unbind_request(%d)\n", s->sock); + + s->device_count = 0; + + for (;;) { + /* unregister all pcmcia_devices registered with this socket*/ + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + if (list_empty(&s->devices_list)) { + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + return; + } + p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); + list_del(&p_dev->socket_device_list); + p_dev->state |= CLIENT_STALE; + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + + device_unregister(&p_dev->dev); + } + + return; +} /* unbind_request */ + + /* * pcmcia_device_query -- determine information about a pcmcia device */ @@ -573,11 +571,11 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) * won't work, this doesn't matter much at the moment: the driver core doesn't * support it either. */ -static DEFINE_MUTEX(device_add_lock); +static DECLARE_MUTEX(device_add_lock); struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) { - struct pcmcia_device *p_dev, *tmp_dev; + struct pcmcia_device *p_dev; unsigned long flags; int bus_id_len; @@ -585,7 +583,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f if (!s) return NULL; - mutex_lock(&device_add_lock); + down(&device_add_lock); /* max of 2 devices per card */ if (s->device_count == 2) @@ -598,8 +596,6 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f p_dev->socket = s; p_dev->device_no = (s->device_count++); p_dev->func = function; - if (s->functions <= function) - s->functions = function + 1; p_dev->dev.bus = &pcmcia_bus_type; p_dev->dev.parent = s->dev.dev; @@ -612,55 +608,36 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); /* compat */ - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); - - /* - * p_dev->function_config must be the same for all card functions. - * Note that this is serialized by the device_add_lock, so that - * only one such struct will be created. - */ - list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) - if (p_dev->func == tmp_dev->func) { - p_dev->function_config = tmp_dev->function_config; - kref_get(&p_dev->function_config->ref); - } + p_dev->state = CLIENT_UNBOUND; /* Add to the list in pcmcia_bus_socket */ - list_add(&p_dev->socket_device_list, &s->devices_list); - + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + list_add_tail(&p_dev->socket_device_list, &s->devices_list); spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - if (!p_dev->function_config) { - p_dev->function_config = kzalloc(sizeof(struct config_t), - GFP_KERNEL); - if (!p_dev->function_config) - goto err_unreg; - kref_init(&p_dev->function_config->ref); - } - printk(KERN_NOTICE "pcmcia: registering new device %s\n", p_dev->devname); pcmcia_device_query(p_dev); - if (device_register(&p_dev->dev)) - goto err_unreg; + if (device_register(&p_dev->dev)) { + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + list_del(&p_dev->socket_device_list); + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - mutex_unlock(&device_add_lock); + goto err_free; + } - return p_dev; + up(&device_add_lock); - err_unreg: - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); - list_del(&p_dev->socket_device_list); - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + return p_dev; err_free: kfree(p_dev->devname); kfree(p_dev); s->device_count--; err_put: - mutex_unlock(&device_add_lock); + up(&device_add_lock); pcmcia_put_socket(s); return NULL; @@ -719,7 +696,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) int no_devices=0; unsigned long flags; - /* must be called with skt_mutex held */ + /* must be called with skt_sem held */ spin_lock_irqsave(&pcmcia_dev_list_lock, flags); if (list_empty(&skt->devices_list)) no_devices=1; @@ -842,11 +819,9 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { struct pcmcia_driver * p_drv = to_pcmcia_drv(drv); struct pcmcia_device_id *did = p_drv->id_table; -#ifdef CONFIG_PCMCIA_IOCTL /* matching by cardmgr */ if (p_dev->cardmgr == p_drv) return 1; -#endif while (did && did->match_flags) { if (pcmcia_devmatch(p_dev, did)) @@ -952,7 +927,7 @@ static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - if (p_dev->suspended) + if (p_dev->dev.power.power_state.event != PM_EVENT_ON) return sprintf(buf, "off\n"); else return sprintf(buf, "on\n"); @@ -967,9 +942,11 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute if (!count) return -EINVAL; - if ((!p_dev->suspended) && !strncmp(buf, "off", 3)) + if ((p_dev->dev.power.power_state.event == PM_EVENT_ON) && + (!strncmp(buf, "off", 3))) ret = dpm_runtime_suspend(dev, PMSG_SUSPEND); - else if (p_dev->suspended && !strncmp(buf, "on", 2)) + else if ((p_dev->dev.power.power_state.event != PM_EVENT_ON) && + (!strncmp(buf, "on", 2))) dpm_runtime_resume(dev); return ret ? ret : count; @@ -1005,9 +982,9 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, if (!count) return -EINVAL; - mutex_lock(&p_dev->socket->skt_mutex); + down(&p_dev->socket->skt_sem); p_dev->allow_func_id_match = 1; - mutex_unlock(&p_dev->socket->skt_mutex); + up(&p_dev->socket->skt_sem); bus_rescan_devices(&pcmcia_bus_type); @@ -1035,27 +1012,14 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = NULL; - int ret = 0; if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); - if (!p_drv) - goto out; + if (p_drv && p_drv->suspend) + return p_drv->suspend(p_dev); - if (p_drv->suspend) { - ret = p_drv->suspend(p_dev); - if (ret) - goto out; - } - - if (p_dev->device_no == p_dev->func) - pcmcia_release_configuration(p_dev); - - out: - if (!ret) - p_dev->suspended = 1; - return ret; + return 0; } @@ -1063,27 +1027,14 @@ static int pcmcia_dev_resume(struct device * dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = NULL; - int ret = 0; if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); - if (!p_drv) - goto out; - - if (p_dev->device_no == p_dev->func) { - ret = pcmcia_request_configuration(p_dev, &p_dev->conf); - if (ret) - goto out; - } + if (p_drv && p_drv->resume) + return p_drv->resume(p_dev); - if (p_drv->resume) - ret = p_drv->resume(p_dev); - - out: - if (!ret) - p_dev->suspended = 0; - return ret; + return 0; } @@ -1143,19 +1094,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) { struct pcmcia_socket *s = pcmcia_get_socket(skt); - if (!s) { - printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \ - "failed, event 0x%x lost!\n", skt, event); - return -ENODEV; - } - ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", event, priority, skt); switch (event) { case CS_EVENT_CARD_REMOVAL: s->pcmcia_state.present = 0; - pcmcia_card_remove(skt, NULL); + pcmcia_card_remove(skt); handle_event(skt, event); break; @@ -1183,32 +1128,6 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) } /* ds_event */ -struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *_p_dev) -{ - struct pcmcia_device *p_dev; - struct pcmcia_device *ret = NULL; - - p_dev = pcmcia_get_dev(_p_dev); - if (!p_dev) - return NULL; - - if (!p_dev->socket->pcmcia_state.present) - goto out; - - if (p_dev->_removed) - goto out; - - if (p_dev->suspended) - goto out; - - ret = p_dev; - out: - pcmcia_put_dev(p_dev); - return ret; -} -EXPORT_SYMBOL(pcmcia_dev_present); - - static struct pcmcia_callback pcmcia_bus_callback = { .owner = THIS_MODULE, .event = ds_event, diff --git a/drivers/pcmcia/ds_internal.h b/drivers/pcmcia/ds_internal.h index 3a2b25e6e..d359bd25a 100644 --- a/drivers/pcmcia/ds_internal.h +++ b/drivers/pcmcia/ds_internal.h @@ -8,8 +8,6 @@ extern void pcmcia_put_dev(struct pcmcia_device *p_dev); struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function); -extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); - #ifdef CONFIG_PCMCIA_IOCTL extern void __init pcmcia_setup_ioctl(void); extern void __exit pcmcia_cleanup_ioctl(void); @@ -17,7 +15,7 @@ extern void handle_event(struct pcmcia_socket *s, event_t event); extern int handle_request(struct pcmcia_socket *s, event_t event); #else static inline void __init pcmcia_setup_ioctl(void) { return; } -static inline void __exit pcmcia_cleanup_ioctl(void) { return; } +static inline void __init pcmcia_cleanup_ioctl(void) { return; } static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; } static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; } #endif diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index d5f03a338..7979c85df 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index a2f05f485..35a92d1e4 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -509,8 +510,7 @@ static irqreturn_t i365_count_irq(int irq, void *dev, struct pt_regs *regs) static u_int __init test_irq(u_short sock, int irq) { debug(2, " testing ISA irq %d\n", irq); - if (request_irq(irq, i365_count_irq, SA_PROBEIRQ, "scan", - i365_count_irq) != 0) + if (request_irq(irq, i365_count_irq, 0, "scan", i365_count_irq) != 0) return 1; irq_hits = 0; irq_sock = sock; msleep(10); @@ -562,7 +562,7 @@ static u_int __init isa_scan(u_short sock, u_int mask0) } else { /* Fallback: just find interrupts that aren't in use */ for (i = 0; i < 16; i++) - if ((mask0 & (1 << i)) && (_check_irq(i, SA_PROBEIRQ) == 0)) + if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0)) mask1 |= (1 << i); printk("default"); /* If scan failed, default to polled status */ @@ -726,7 +726,7 @@ static void __init add_pcic(int ns, int type) u_int cs_mask = mask & ((cs_irq) ? (1< 0; cs_irq--) if ((cs_mask & (1 << cs_irq)) && - (_check_irq(cs_irq, SA_PROBEIRQ) == 0)) + (_check_irq(cs_irq, 0) == 0)) break; if (cs_irq) { grab_irq = 1; diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 2c23d7584..47b5ade95 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -218,7 +218,7 @@ static int __init omap_cf_probe(struct device *dev) /* either CFLASH.IREQ (INT_1610_CF) or some GPIO */ irq = platform_get_irq(pdev, 0); - if (irq < 0) + if (!irq) return -EINVAL; cf = kcalloc(1, sizeof *cf, GFP_KERNEL); diff --git a/drivers/pcmcia/pcmcia_compat.c b/drivers/pcmcia/pcmcia_compat.c new file mode 100644 index 000000000..ebb161c4f --- /dev/null +++ b/drivers/pcmcia/pcmcia_compat.c @@ -0,0 +1,65 @@ +/* + * PCMCIA 16-bit compatibility functions + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Copyright (C) 2004 Dominik Brodowski + * + * 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 +#include +#include + +#define IN_CARD_SERVICES +#include +#include +#include +#include +#include +#include + +#include "cs_internal.h" + +int pcmcia_get_first_tuple(struct pcmcia_device *p_dev, tuple_t *tuple) +{ + return pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple); +} +EXPORT_SYMBOL(pcmcia_get_first_tuple); + +int pcmcia_get_next_tuple(struct pcmcia_device *p_dev, tuple_t *tuple) +{ + return pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple); +} +EXPORT_SYMBOL(pcmcia_get_next_tuple); + +int pcmcia_get_tuple_data(struct pcmcia_device *p_dev, tuple_t *tuple) +{ + return pccard_get_tuple_data(p_dev->socket, tuple); +} +EXPORT_SYMBOL(pcmcia_get_tuple_data); + +int pcmcia_parse_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, cisparse_t *parse) +{ + return pccard_parse_tuple(tuple, parse); +} +EXPORT_SYMBOL(pcmcia_parse_tuple); + +int pcmcia_validate_cis(struct pcmcia_device *p_dev, cisinfo_t *info) +{ + return pccard_validate_cis(p_dev->socket, p_dev->func, info); +} +EXPORT_SYMBOL(pcmcia_validate_cis); + + +int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req) +{ + return pccard_reset_card(p_dev->socket); +} +EXPORT_SYMBOL(pcmcia_reset_card); diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 738b1ef59..80969f7e7 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -18,6 +18,7 @@ */ +#include #include #include #include @@ -69,26 +70,10 @@ extern int ds_pc_debug; #define ds_dbg(lvl, fmt, arg...) do { } while (0) #endif -static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s, - unsigned int function) -{ - struct pcmcia_device *p_dev = NULL; - unsigned long flags; - - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); - list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { - if (p_dev->func == function) { - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - return pcmcia_get_dev(p_dev); - } - } - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - return NULL; -} /* backwards-compatible accessing of driver --- by name! */ -static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info) +static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info) { struct device_driver *drv; struct pcmcia_driver *p_drv; @@ -229,7 +214,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) * by userspace before, we need to * return the "instance". */ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - bind_info->instance = p_dev; + bind_info->instance = p_dev->instance; ret = -EBUSY; goto err_put_module; } else { @@ -268,9 +253,9 @@ rescan: /* * Prevent this racing with a card insertion. */ - mutex_lock(&s->skt_mutex); + down(&s->skt_sem); bus_rescan_devices(&pcmcia_bus_type); - mutex_unlock(&s->skt_mutex); + up(&s->skt_sem); /* check whether the driver indeed matched. I don't care if this * is racy or not, because it can only happen on cardmgr access @@ -304,7 +289,6 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int { dev_node_t *node; struct pcmcia_device *p_dev; - struct pcmcia_driver *p_drv; unsigned long flags; int ret = 0; @@ -359,16 +343,16 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int found: spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - p_drv = to_pcmcia_drv(p_dev->dev.driver); - if (p_drv && !p_dev->_locked) { + if ((!p_dev->instance) || + (p_dev->instance->state & DEV_CONFIG_PENDING)) { ret = -EAGAIN; goto err_put; } if (first) - node = p_dev->dev_node; + node = p_dev->instance->dev; else - for (node = p_dev->dev_node; node; node = node->next) + for (node = p_dev->instance->dev; node; node = node->next) if (node == bind_info->next) break; if (!node) { @@ -426,7 +410,7 @@ static int ds_open(struct inode *inode, struct file *file) if (!warning_printed) { printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl " - "usage from process: %s.\n", current->comm); + "usage.\n"); printk(KERN_INFO "pcmcia: This interface will soon be removed from " "the kernel; please expect breakage unless you upgrade " "to new tools.\n"); @@ -599,20 +583,14 @@ static int ds_ioctl(struct inode * inode, struct file * file, if (buf->config.Function && (buf->config.Function >= s->functions)) ret = CS_BAD_ARGS; - else { - struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); - if (p_dev == NULL) - ret = CS_BAD_ARGS; - else { - ret = pccard_get_configuration_info(s, p_dev, &buf->config); - pcmcia_put_dev(p_dev); - } - } + else + ret = pccard_get_configuration_info(s, + buf->config.Function, &buf->config); break; case DS_GET_FIRST_TUPLE: - mutex_lock(&s->skt_mutex); + down(&s->skt_sem); pcmcia_validate_mem(s); - mutex_unlock(&s->skt_mutex); + up(&s->skt_sem); ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple); break; case DS_GET_NEXT_TUPLE: @@ -631,23 +609,16 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = pccard_reset_card(s); break; case DS_GET_STATUS: - if (buf->status.Function && - (buf->status.Function >= s->functions)) - ret = CS_BAD_ARGS; - else { - struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); - if (p_dev == NULL) - ret = CS_BAD_ARGS; - else { - ret = pccard_get_status(s, p_dev, &buf->status); - pcmcia_put_dev(p_dev); - } - } - break; + if (buf->status.Function && + (buf->status.Function >= s->functions)) + ret = CS_BAD_ARGS; + else + ret = pccard_get_status(s, buf->status.Function, &buf->status); + break; case DS_VALIDATE_CIS: - mutex_lock(&s->skt_mutex); + down(&s->skt_sem); pcmcia_validate_mem(s); - mutex_unlock(&s->skt_mutex); + up(&s->skt_sem); ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo); break; case DS_SUSPEND_CARD: @@ -667,17 +638,12 @@ static int ds_ioctl(struct inode * inode, struct file * file, err = -EPERM; goto free_out; } - - ret = CS_BAD_ARGS; - - if (!(buf->conf_reg.Function && - (buf->conf_reg.Function >= s->functions))) { - struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function); - if (p_dev) { - ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg); - pcmcia_put_dev(p_dev); - } - } + if (buf->conf_reg.Function && + (buf->conf_reg.Function >= s->functions)) + ret = CS_BAD_ARGS; + else + ret = pccard_access_configuration_register(s, + buf->conf_reg.Function, &buf->conf_reg); break; case DS_GET_FIRST_REGION: case DS_GET_NEXT_REGION: diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 3131bb0a0..89022ad5b 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -14,6 +14,7 @@ * */ +#include #include #include #include @@ -88,6 +89,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, } if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { *base = s->io_offset | (*base & 0x0fff); + s->io[0].Attributes = attr; return 0; } /* Check for an already-allocated window that must conflict with @@ -95,36 +97,38 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, * potential conflicts, just the most obvious ones. */ for (i = 0; i < MAX_IO_WIN; i++) - if ((s->io[i].res) && - ((s->io[i].res->start & (align-1)) == *base)) + if ((s->io[i].NumPorts != 0) && + ((s->io[i].BasePort & (align-1)) == *base)) return 1; for (i = 0; i < MAX_IO_WIN; i++) { - if (!s->io[i].res) { + if (s->io[i].NumPorts == 0) { s->io[i].res = pcmcia_find_io_region(*base, num, align, s); if (s->io[i].res) { - *base = s->io[i].res->start; - s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS); - s->io[i].InUse = num; + s->io[i].Attributes = attr; + s->io[i].BasePort = *base = s->io[i].res->start; + s->io[i].NumPorts = s->io[i].InUse = num; break; } else return 1; - } else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS)) + } else if (s->io[i].Attributes != attr) continue; /* Try to extend top of window */ - try = s->io[i].res->end + 1; + try = s->io[i].BasePort + s->io[i].NumPorts; if ((*base == 0) || (*base == try)) if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, s->io[i].res->end + num, s) == 0) { *base = try; + s->io[i].NumPorts += num; s->io[i].InUse += num; break; } /* Try to extend bottom of window */ - try = s->io[i].res->start - num; + try = s->io[i].BasePort - num; if ((*base == 0) || (*base == try)) if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, s->io[i].res->end, s) == 0) { - *base = try; + s->io[i].BasePort = *base = try; + s->io[i].NumPorts += num; s->io[i].InUse += num; break; } @@ -139,13 +143,12 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base, int i; for (i = 0; i < MAX_IO_WIN; i++) { - if (!s->io[i].res) - continue; - if ((s->io[i].res->start <= base) && - (s->io[i].res->end >= base+num-1)) { + if ((s->io[i].BasePort <= base) && + (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) { s->io[i].InUse -= num; /* Free the window if no one else is using it */ if (s->io[i].InUse == 0) { + s->io[i].NumPorts = 0; release_resource(s->io[i].res); kfree(s->io[i].res); s->io[i].res = NULL; @@ -162,19 +165,21 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base, * this and the tuple reading services. */ -int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, +int pccard_access_configuration_register(struct pcmcia_socket *s, + unsigned int function, conf_reg_t *reg) { - struct pcmcia_socket *s; config_t *c; int addr; u_char val; - if (!p_dev || !p_dev->function_config) + if (!s || !s->config) return CS_NO_CARD; - s = p_dev->socket; - c = p_dev->function_config; + c = &s->config[function]; + + if (c == NULL) + return CS_NO_CARD; if (!(c->state & CONFIG_LOCKED)) return CS_CONFIGURATION_LOCKED; @@ -195,12 +200,20 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, break; } return CS_SUCCESS; -} /* pcmcia_access_configuration_register */ +} /* pccard_access_configuration_register */ + +int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, + conf_reg_t *reg) +{ + return pccard_access_configuration_register(p_dev->socket, + p_dev->func, reg); +} EXPORT_SYMBOL(pcmcia_access_configuration_register); + int pccard_get_configuration_info(struct pcmcia_socket *s, - struct pcmcia_device *p_dev, + unsigned int function, config_info_t *config) { config_t *c; @@ -208,6 +221,7 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; + config->Function = function; #ifdef CONFIG_CARDBUS if (s->state & SOCKET_CARDBUS) { @@ -221,22 +235,14 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, config->AssignedIRQ = s->irq.AssignedIRQ; if (config->AssignedIRQ) config->Attributes |= CONF_ENABLE_IRQ; - if (s->io[0].res) { - config->BasePort1 = s->io[0].res->start; - config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1; - } + config->BasePort1 = s->io[0].BasePort; + config->NumPorts1 = s->io[0].NumPorts; } return CS_SUCCESS; } #endif - if (p_dev) { - c = p_dev->function_config; - config->Function = p_dev->func; - } else { - c = NULL; - config->Function = 0; - } + c = (s->config != NULL) ? &s->config[function] : NULL; if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { config->Attributes = 0; @@ -265,7 +271,7 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config) { - return pccard_get_configuration_info(p_dev->socket, p_dev, + return pccard_get_configuration_info(p_dev->socket, p_dev->func, config); } EXPORT_SYMBOL(pcmcia_get_configuration_info); @@ -311,7 +317,7 @@ EXPORT_SYMBOL(pcmcia_get_window); * SocketState yet: I haven't seen any point for it. */ -int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, +int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status) { config_t *c; @@ -328,12 +334,11 @@ int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; - c = (p_dev) ? p_dev->function_config : NULL; - + c = (s->config != NULL) ? &s->config[function] : NULL; if ((c != NULL) && (c->state & CONFIG_LOCKED) && (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { u_char reg; - if (c->CardValues & PRESENT_PIN_REPLACE) { + if (c->Present & PRESENT_PIN_REPLACE) { pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); status->CardState |= (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; @@ -347,7 +352,7 @@ int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, /* No PRR? Then assume we're always ready */ status->CardState |= CS_EVENT_READY_CHANGE; } - if (c->CardValues & PRESENT_EXT_STATUS) { + if (c->Present & PRESENT_EXT_STATUS) { pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); status->CardState |= (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; @@ -365,9 +370,11 @@ int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, return CS_SUCCESS; } /* pccard_get_status */ -int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status) +int pcmcia_get_status(client_handle_t handle, cs_status_t *status) { - return pccard_get_status(p_dev->socket, p_dev, status); + struct pcmcia_socket *s; + s = SOCKET(handle); + return pccard_get_status(s, handle->func, status); } EXPORT_SYMBOL(pcmcia_get_status); @@ -415,8 +422,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, config_t *c; s = p_dev->socket; - c = p_dev->function_config; - + c = CONFIG(p_dev); if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; if (!(c->state & CONFIG_LOCKED)) @@ -448,28 +454,6 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, (mod->Attributes & CONF_VPP2_CHANGE_VALID)) return CS_BAD_VPP; - if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { - pccard_io_map io_off = { 0, 0, 0, 0, 1 }; - pccard_io_map io_on; - int i; - - io_on.speed = io_speed; - for (i = 0; i < MAX_IO_WIN; i++) { - if (!s->io[i].res) - continue; - io_off.map = i; - io_on.map = i; - - io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8; - io_on.start = s->io[i].res->start; - io_on.stop = s->io[i].res->end; - - s->ops->set_io_map(s, &io_off); - mdelay(40); - s->ops->set_io_map(s, &io_on); - } - } - return CS_SUCCESS; } /* modify_configuration */ EXPORT_SYMBOL(pcmcia_modify_configuration); @@ -479,23 +463,23 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) { pccard_io_map io = { 0, 0, 0, 0, 1 }; struct pcmcia_socket *s = p_dev->socket; - config_t *c = p_dev->function_config; int i; - if (p_dev->_locked) { - p_dev->_locked = 0; + if (!(p_dev->state & CLIENT_CONFIG_LOCKED)) + return CS_BAD_HANDLE; + p_dev->state &= ~CLIENT_CONFIG_LOCKED; + + if (!(p_dev->state & CLIENT_STALE)) { + config_t *c = CONFIG(p_dev); if (--(s->lock_count) == 0) { s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ s->socket.Vpp = 0; s->socket.io_irq = 0; s->ops->set_socket(s, &s->socket); } - } - if (c->state & CONFIG_LOCKED) { - c->state &= ~CONFIG_LOCKED; if (c->state & CONFIG_IO_REQ) for (i = 0; i < MAX_IO_WIN; i++) { - if (!s->io[i].res) + if (s->io[i].NumPorts == 0) continue; s->io[i].Config--; if (s->io[i].Config != 0) @@ -503,10 +487,12 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) io.map = i; s->ops->set_io_map(s, &io); } + c->state &= ~CONFIG_LOCKED; } return CS_SUCCESS; } /* pcmcia_release_configuration */ +EXPORT_SYMBOL(pcmcia_release_configuration); /** pcmcia_release_io @@ -517,23 +503,25 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) * don't bother checking the port ranges against the current socket * values. */ -static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) +int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) { struct pcmcia_socket *s = p_dev->socket; - config_t *c = p_dev->function_config; - if (!p_dev->_io ) + if (!(p_dev->state & CLIENT_IO_REQ)) return CS_BAD_HANDLE; - - p_dev->_io = 0; - - if ((c->io.BasePort1 != req->BasePort1) || - (c->io.NumPorts1 != req->NumPorts1) || - (c->io.BasePort2 != req->BasePort2) || - (c->io.NumPorts2 != req->NumPorts2)) - return CS_BAD_ARGS; - - c->state &= ~CONFIG_IO_REQ; + p_dev->state &= ~CLIENT_IO_REQ; + + if (!(p_dev->state & CLIENT_STALE)) { + config_t *c = CONFIG(p_dev); + if (c->state & CONFIG_LOCKED) + return CS_CONFIGURATION_LOCKED; + if ((c->io.BasePort1 != req->BasePort1) || + (c->io.NumPorts1 != req->NumPorts1) || + (c->io.BasePort2 != req->BasePort2) || + (c->io.NumPorts2 != req->NumPorts2)) + return CS_BAD_ARGS; + c->state &= ~CONFIG_IO_REQ; + } release_io_space(s, req->BasePort1, req->NumPorts1); if (req->NumPorts2) @@ -541,26 +529,28 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) return CS_SUCCESS; } /* pcmcia_release_io */ +EXPORT_SYMBOL(pcmcia_release_io); -static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) +int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) { struct pcmcia_socket *s = p_dev->socket; - config_t *c= p_dev->function_config; - - if (!p_dev->_irq) + if (!(p_dev->state & CLIENT_IRQ_REQ)) return CS_BAD_HANDLE; - p_dev->_irq = 0; - - if (c->state & CONFIG_LOCKED) - return CS_CONFIGURATION_LOCKED; - if (c->irq.Attributes != req->Attributes) - return CS_BAD_ATTRIBUTE; - if (s->irq.AssignedIRQ != req->AssignedIRQ) - return CS_BAD_IRQ; - if (--s->irq.Config == 0) { - c->state &= ~CONFIG_IRQ_REQ; - s->irq.AssignedIRQ = 0; + p_dev->state &= ~CLIENT_IRQ_REQ; + + if (!(p_dev->state & CLIENT_STALE)) { + config_t *c = CONFIG(p_dev); + if (c->state & CONFIG_LOCKED) + return CS_CONFIGURATION_LOCKED; + if (c->irq.Attributes != req->Attributes) + return CS_BAD_ATTRIBUTE; + if (s->irq.AssignedIRQ != req->AssignedIRQ) + return CS_BAD_IRQ; + if (--s->irq.Config == 0) { + c->state &= ~CONFIG_IRQ_REQ; + s->irq.AssignedIRQ = 0; + } } if (req->Attributes & IRQ_HANDLE_PRESENT) { @@ -573,6 +563,7 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) return CS_SUCCESS; } /* pcmcia_release_irq */ +EXPORT_SYMBOL(pcmcia_release_irq); int pcmcia_release_window(window_handle_t win) @@ -582,7 +573,7 @@ int pcmcia_release_window(window_handle_t win) if ((win == NULL) || (win->magic != WINDOW_MAGIC)) return CS_BAD_HANDLE; s = win->sock; - if (!(win->handle->_win & CLIENT_WIN_REQ(win->index))) + if (!(win->handle->state & CLIENT_WIN_REQ(win->index))) return CS_BAD_HANDLE; /* Shut down memory window */ @@ -596,7 +587,7 @@ int pcmcia_release_window(window_handle_t win) kfree(win->ctl.res); win->ctl.res = NULL; } - win->handle->_win &= ~CLIENT_WIN_REQ(win->index); + win->handle->state &= ~CLIENT_WIN_REQ(win->index); win->magic = 0; @@ -619,12 +610,16 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, if (req->IntType & INT_CARDBUS) return CS_UNSUPPORTED_MODE; - c = p_dev->function_config; + c = CONFIG(p_dev); if (c->state & CONFIG_LOCKED) return CS_CONFIGURATION_LOCKED; /* Do power control. We don't allow changes in Vcc. */ - s->socket.Vpp = req->Vpp; + if (s->socket.Vcc != req->Vcc) + return CS_BAD_VCC; + if (req->Vpp1 != req->Vpp2) + return CS_BAD_VPP; + s->socket.Vpp = req->Vpp1; if (s->ops->set_socket(s, &s->socket)) return CS_BAD_VPP; @@ -648,7 +643,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, /* Set up CIS configuration registers */ base = c->ConfigBase = req->ConfigBase; - c->CardValues = req->Present; + c->Present = c->CardValues = req->Present; if (req->Present & PRESENT_COPY) { c->Copy = req->Copy; pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy); @@ -695,10 +690,10 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, if (c->state & CONFIG_IO_REQ) { iomap.speed = io_speed; for (i = 0; i < MAX_IO_WIN; i++) - if (s->io[i].res) { + if (s->io[i].NumPorts != 0) { iomap.map = i; iomap.flags = MAP_ACTIVE; - switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) { + switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) { case IO_DATA_PATH_WIDTH_16: iomap.flags |= MAP_16BIT; break; case IO_DATA_PATH_WIDTH_AUTO: @@ -706,15 +701,15 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, default: break; } - iomap.start = s->io[i].res->start; - iomap.stop = s->io[i].res->end; + iomap.start = s->io[i].BasePort; + iomap.stop = iomap.start + s->io[i].NumPorts - 1; s->ops->set_io_map(s, &iomap); s->io[i].Config++; } } c->state |= CONFIG_LOCKED; - p_dev->_locked = 1; + p_dev->state |= CLIENT_CONFIG_LOCKED; return CS_SUCCESS; } /* pcmcia_request_configuration */ EXPORT_SYMBOL(pcmcia_request_configuration); @@ -735,7 +730,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) if (!req) return CS_UNSUPPORTED_MODE; - c = p_dev->function_config; + c = CONFIG(p_dev); if (c->state & CONFIG_LOCKED) return CS_CONFIGURATION_LOCKED; if (c->state & CONFIG_IO_REQ) @@ -760,7 +755,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) c->io = *req; c->state |= CONFIG_IO_REQ; - p_dev->_io = 1; + p_dev->state |= CLIENT_IO_REQ; return CS_SUCCESS; } /* pcmcia_request_io */ EXPORT_SYMBOL(pcmcia_request_io); @@ -791,7 +786,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; - c = p_dev->function_config; + c = CONFIG(p_dev); if (c->state & CONFIG_LOCKED) return CS_CONFIGURATION_LOCKED; if (c->state & CONFIG_IRQ_REQ) @@ -856,7 +851,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) s->irq.Config++; c->state |= CONFIG_IRQ_REQ; - p_dev->_irq = 1; + p_dev->state |= CLIENT_IRQ_REQ; #ifdef CONFIG_PCMCIA_PROBE pcmcia_used_irq[irq]++; @@ -916,7 +911,7 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h if (!win->ctl.res) return CS_IN_USE; } - (*p_dev)->_win |= CLIENT_WIN_REQ(w); + (*p_dev)->state |= CLIENT_WIN_REQ(w); /* Configure the socket controller */ win->ctl.map = w+1; @@ -946,12 +941,3 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h return CS_SUCCESS; } /* pcmcia_request_window */ EXPORT_SYMBOL(pcmcia_request_window); - -void pcmcia_disable_device(struct pcmcia_device *p_dev) { - pcmcia_release_configuration(p_dev); - pcmcia_release_io(p_dev, &p_dev->io); - pcmcia_release_irq(p_dev, &p_dev->irq); - if (&p_dev->win) - pcmcia_release_window(p_dev->win); -} -EXPORT_SYMBOL(pcmcia_disable_device); diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 247ab837f..f2789afb2 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -589,7 +590,7 @@ static int pd6729_check_irq(int irq, int flags) return 0; } -static u_int __devinit pd6729_isa_scan(void) +static u_int __init pd6729_isa_scan(void) { u_int mask0, mask = 0; int i; diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 42efe2188..fd3647368 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -16,84 +16,79 @@ #include #include #include -#include +#include +#include #include #include - #include -#include -#include #include "soc_common.h" #define NO_KEEP_VS 0x0001 -static unsigned char keep_vs; -static unsigned char keep_rd; +/* PCMCIA to Scoop linkage -static struct pcmcia_irqs irqs[] = { - { 0, CORGI_IRQ_GPIO_CF_CD, "PCMCIA0 CD"}, -}; + There is no easy way to link multiple scoop devices into one + single entity for the pxa2xx_pcmcia device so this structure + is used which is setup by the platform code +*/ +struct scoop_pcmcia_config *platform_scoop_config; +#define SCOOP_DEV platform_scoop_config->devs -static void sharpsl_pcmcia_init_reset(void) +static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) { - reset_scoop(&corgiscoop_device.dev); - keep_vs = NO_KEEP_VS; - keep_rd = 0; + struct scoop_pcmcia_dev *scoopdev = &SCOOP_DEV[skt->nr]; + + reset_scoop(scoopdev->dev); + + /* Shared power controls need to be handled carefully */ + if (platform_scoop_config->power_ctrl) + platform_scoop_config->power_ctrl(scoopdev->dev, 0x0000, skt->nr); + else + write_scoop_reg(scoopdev->dev, SCOOP_CPR, 0x0000); + + scoopdev->keep_vs = NO_KEEP_VS; + scoopdev->keep_rd = 0; } static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - /* - * Setup default state of GPIO outputs - * before we enable them as outputs. - */ - GPSR(GPIO48_nPOE) = - GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | - GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | - GPIO_bit(GPIO52_nPCE_1) | - GPIO_bit(GPIO53_nPCE_2); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO52_nPCE_1_MD); - pxa_gpio_mode(GPIO53_nPCE_2_MD); - pxa_gpio_mode(GPIO54_pSKTSEL_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); + if (platform_scoop_config->pcmcia_init) + platform_scoop_config->pcmcia_init(); /* Register interrupts */ - ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); - - if (ret) { - printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); - return ret; + if (SCOOP_DEV[skt->nr].cd_irq >= 0) { + struct pcmcia_irqs cd_irq; + + cd_irq.sock = skt->nr; + cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; + cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; + ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); + + if (ret) { + printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); + return ret; + } } - /* Enable interrupt */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR, 0x00C0); - write_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR, 0x0101); - keep_vs = NO_KEEP_VS; - - skt->irq = CORGI_IRQ_GPIO_CF_IRQ; + skt->irq = SCOOP_DEV[skt->nr].irq; return 0; } static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + if (SCOOP_DEV[skt->nr].cd_irq >= 0) { + struct pcmcia_irqs cd_irq; - /* CF_BUS_OFF */ - sharpsl_pcmcia_init_reset(); + cd_irq.sock = skt->nr; + cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; + cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; + soc_pcmcia_free_irqs(skt, &cd_irq, 1); + } } @@ -101,31 +96,36 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { unsigned short cpr, csr; + struct device *scoop = SCOOP_DEV[skt->nr].dev; - cpr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR); + cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR); - write_scoop_reg(&corgiscoop_device.dev, SCOOP_IRM, 0x00FF); - write_scoop_reg(&corgiscoop_device.dev, SCOOP_ISR, 0x0000); - write_scoop_reg(&corgiscoop_device.dev, SCOOP_IRM, 0x0000); - csr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CSR); + write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); + write_scoop_reg(scoop, SCOOP_ISR, 0x0000); + write_scoop_reg(scoop, SCOOP_IRM, 0x0000); + csr = read_scoop_reg(scoop, SCOOP_CSR); if (csr & 0x0004) { /* card eject */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000); - keep_vs = NO_KEEP_VS; + write_scoop_reg(scoop, SCOOP_CDR, 0x0000); + SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; } - else if (!(keep_vs & NO_KEEP_VS)) { + else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) { /* keep vs1,vs2 */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000); - csr |= keep_vs; + write_scoop_reg(scoop, SCOOP_CDR, 0x0000); + csr |= SCOOP_DEV[skt->nr].keep_vs; } else if (cpr & 0x0003) { /* power on */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000); - keep_vs = (csr & 0x00C0); + write_scoop_reg(scoop, SCOOP_CDR, 0x0000); + SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0); } else { /* card detect */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0002); + if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) { + write_scoop_reg(scoop, SCOOP_CDR, 0x0000); + } else { + write_scoop_reg(scoop, SCOOP_CDR, 0x0002); + } } state->detect = (csr & 0x0004) ? 0 : 1; @@ -139,7 +139,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); } - } @@ -147,6 +146,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { unsigned long flags; + struct device *scoop = SCOOP_DEV[skt->nr].dev; unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; @@ -166,13 +166,18 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, local_irq_save(flags); - nmcr = (mcr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR)) & ~0x0010; - ncpr = (cpr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR)) & ~0x0083; - nccr = (ccr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CCR)) & ~0x0080; - nimr = (imr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR)) & ~0x003E; - - ncpr |= (state->Vcc == 33) ? 0x0001 : - (state->Vcc == 50) ? 0x0002 : 0; + nmcr = (mcr = read_scoop_reg(scoop, SCOOP_MCR)) & ~0x0010; + ncpr = (cpr = read_scoop_reg(scoop, SCOOP_CPR)) & ~0x0083; + nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; + nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; + + if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) { + ncpr |= (state->Vcc == 33) ? 0x0002 : + (state->Vcc == 50) ? 0x0002 : 0; + } else { + ncpr |= (state->Vcc == 33) ? 0x0001 : + (state->Vcc == 50) ? 0x0002 : 0; + } nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; nccr |= (state->flags&SS_RESET)? 0x0080: 0; @@ -184,22 +189,26 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ((skt->status&SS_WRPROT) ? 0x0008 : 0); if (!(ncpr & 0x0003)) { - keep_rd = 0; - } else if (!keep_rd) { + SCOOP_DEV[skt->nr].keep_rd = 0; + } else if (!SCOOP_DEV[skt->nr].keep_rd) { if (nccr & 0x0080) - keep_rd = 1; + SCOOP_DEV[skt->nr].keep_rd = 1; else nccr |= 0x0080; } if (mcr != nmcr) - write_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR, nmcr); - if (cpr != ncpr) - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR, ncpr); + write_scoop_reg(scoop, SCOOP_MCR, nmcr); + if (cpr != ncpr) { + if (platform_scoop_config->power_ctrl) + platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr); + else + write_scoop_reg(scoop, SCOOP_CPR, ncpr); + } if (ccr != nccr) - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CCR, nccr); + write_scoop_reg(scoop, SCOOP_CCR, nccr); if (imr != nimr) - write_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR, nimr); + write_scoop_reg(scoop, SCOOP_IMR, nimr); local_irq_restore(flags); @@ -208,57 +217,77 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) { + sharpsl_pcmcia_init_reset(skt); + + /* Enable interrupt */ + write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0); + write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101); + SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; } static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { + sharpsl_pcmcia_init_reset(skt); } static struct pcmcia_low_level sharpsl_pcmcia_ops = { - .owner = THIS_MODULE, - .hw_init = sharpsl_pcmcia_hw_init, - .hw_shutdown = sharpsl_pcmcia_hw_shutdown, - .socket_state = sharpsl_pcmcia_socket_state, - .configure_socket = sharpsl_pcmcia_configure_socket, - .socket_init = sharpsl_pcmcia_socket_init, - .socket_suspend = sharpsl_pcmcia_socket_suspend, - .first = 0, - .nr = 1, + .owner = THIS_MODULE, + .hw_init = sharpsl_pcmcia_hw_init, + .hw_shutdown = sharpsl_pcmcia_hw_shutdown, + .socket_state = sharpsl_pcmcia_socket_state, + .configure_socket = sharpsl_pcmcia_configure_socket, + .socket_init = sharpsl_pcmcia_socket_init, + .socket_suspend = sharpsl_pcmcia_socket_suspend, + .first = 0, + .nr = 0, }; +#ifdef CONFIG_SA1100_COLLIE +#include "sa11xx_base.h" + +int __init pcmcia_collie_init(struct device *dev) +{ + int ret = -ENODEV; + + if (machine_is_collie()) + ret = sa11xx_drv_pcmcia_probe(dev, &sharpsl_pcmcia_ops, 0, 1); + + return ret; +} + +#else + static struct platform_device *sharpsl_pcmcia_device; static int __init sharpsl_pcmcia_init(void) { int ret; - sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); + sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs; + sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); + if (!sharpsl_pcmcia_device) return -ENOMEM; - memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); - sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; + sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; + sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; + + ret = platform_device_add(sharpsl_pcmcia_device); - ret = platform_device_register(sharpsl_pcmcia_device); if (ret) - kfree(sharpsl_pcmcia_device); + platform_device_put(sharpsl_pcmcia_device); return ret; } static void __exit sharpsl_pcmcia_exit(void) { - /* - * This call is supposed to free our sharpsl_pcmcia_device. - * Unfortunately platform_device don't have a free method, and - * we can't assume it's free of any reference at this point so we - * can't free it either. - */ platform_device_unregister(sharpsl_pcmcia_device); } -module_init(sharpsl_pcmcia_init); +fs_initcall(sharpsl_pcmcia_init); module_exit(sharpsl_pcmcia_exit); +#endif MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support"); MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 81dfc2cac..514609369 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -12,6 +12,7 @@ * (C) 1999 David A. Hinds */ +#include #include #include @@ -21,8 +22,6 @@ #include "cs_internal.h" -#ifdef CONFIG_PCMCIA_IOCTL - #ifdef CONFIG_PCMCIA_PROBE static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) @@ -99,8 +98,6 @@ int pcmcia_adjust_resource_info(adjust_t *adj) } EXPORT_SYMBOL(pcmcia_adjust_resource_info); -#endif - int pcmcia_validate_mem(struct pcmcia_socket *s) { if (s->resource_ops->validate_mem) diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 0f8b157c9..5301ac603 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -12,6 +12,7 @@ * (C) 1999 David A. Hinds */ +#include #include #include #include @@ -60,7 +61,7 @@ struct socket_data { unsigned int rsrc_mem_probe; }; -static DEFINE_MUTEX(rsrc_mutex); +static DECLARE_MUTEX(rsrc_sem); #define MEM_PROBE_LOW (1 << 0) #define MEM_PROBE_HIGH (1 << 1) @@ -483,7 +484,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) /* - * Locking note: Must be called with skt_mutex held! + * Locking note: Must be called with skt_sem held! */ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) { @@ -494,7 +495,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) if (!probe_mem) return 0; - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); if (s->features & SS_CAP_PAGE_REGS) probe_mask = MEM_PROBE_HIGH; @@ -506,7 +507,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) s_data->rsrc_mem_probe |= probe_mask; } - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); return ret; } @@ -584,7 +585,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star struct socket_data *s_data = s->resource_data; int ret = -ENOMEM; - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) { unsigned long start = m->base; unsigned long end = m->base + m->num - 1; @@ -595,7 +596,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star ret = adjust_resource(res, r_start, r_end - r_start + 1); break; } - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); return ret; } @@ -629,7 +630,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, data.offset = base & data.mask; data.map = &s_data->io_db; - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); #ifdef CONFIG_PCI if (s->cb_dev) { ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, @@ -638,7 +639,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, #endif ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, 1, pcmcia_align, &data); - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); if (ret != 0) { kfree(res); @@ -671,7 +672,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num, min = 0x100000UL + base; } - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); #ifdef CONFIG_PCI if (s->cb_dev) { ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, @@ -681,7 +682,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num, #endif ret = allocate_resource(&iomem_resource, res, num, min, max, 1, pcmcia_align, &data); - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); if (ret == 0 || low) break; low = 1; @@ -704,7 +705,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned if (end < start) return -EINVAL; - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); switch (action) { case ADD_MANAGED_RESOURCE: ret = add_interval(&data->mem_db, start, size); @@ -722,7 +723,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned default: ret = -EINVAL; } - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); return ret; } @@ -740,7 +741,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long if (end > IO_SPACE_LIMIT) return -EINVAL; - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); switch (action) { case ADD_MANAGED_RESOURCE: if (add_interval(&data->io_db, start, size) != 0) { @@ -759,7 +760,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long ret = -EINVAL; break; } - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); return ret; } @@ -866,7 +867,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s) struct socket_data *data = s->resource_data; struct resource_map *p, *q; - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); for (p = data->mem_db.next; p != &data->mem_db; p = q) { q = p->next; kfree(p); @@ -875,7 +876,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s) q = p->next; kfree(p); } - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); } @@ -900,7 +901,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf) struct resource_map *p; ssize_t ret = 0; - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); data = s->resource_data; for (p = data->io_db.next; p != &data->io_db; p = p->next) { @@ -912,7 +913,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf) ((unsigned long) p->base + p->num - 1)); } - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); return (ret); } @@ -952,7 +953,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf) struct resource_map *p; ssize_t ret = 0; - mutex_lock(&rsrc_mutex); + down(&rsrc_sem); data = s->resource_data; for (p = data->mem_db.next; p != &data->mem_db; p = p->next) { @@ -964,7 +965,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf) ((unsigned long) p->base + p->num - 1)); } - mutex_unlock(&rsrc_mutex); + up(&rsrc_sem); return (ret); } diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c index eb89928f2..2b3c2895b 100644 --- a/drivers/pcmcia/sa1100_cerf.c +++ b/drivers/pcmcia/sa1100_cerf.c @@ -5,6 +5,7 @@ * Based off the Assabet. * */ +#include #include #include #include diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 8eed03938..5ab1cdef7 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -29,7 +29,6 @@ #include #define IN_CARD_SERVICES -#include #include #include #include @@ -43,35 +42,28 @@ static ssize_t pccard_show_type(struct class_device *dev, char *buf) { - int val; struct pcmcia_socket *s = to_socket(dev); if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - s->ops->get_status(s, &val); - if (val & SS_CARDBUS) + if (s->state & SOCKET_CARDBUS) return sprintf(buf, "32-bit\n"); - if (val & SS_DETECT) - return sprintf(buf, "16-bit\n"); - return sprintf(buf, "invalid\n"); + return sprintf(buf, "16-bit\n"); } -static CLASS_DEVICE_ATTR(card_type, 0400, pccard_show_type, NULL); +static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL); static ssize_t pccard_show_voltage(struct class_device *dev, char *buf) { - int val; struct pcmcia_socket *s = to_socket(dev); if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - s->ops->get_status(s, &val); - if (val & SS_3VCARD) - return sprintf(buf, "3.3V\n"); - if (val & SS_XVCARD) - return sprintf(buf, "X.XV\n"); - return sprintf(buf, "5.0V\n"); + if (s->socket.Vcc) + return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, + s->socket.Vcc % 10); + return sprintf(buf, "X.XV\n"); } -static CLASS_DEVICE_ATTR(card_voltage, 0400, pccard_show_voltage, NULL); +static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL); static ssize_t pccard_show_vpp(struct class_device *dev, char *buf) { @@ -80,7 +72,7 @@ static ssize_t pccard_show_vpp(struct class_device *dev, char *buf) return -ENODEV; return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10); } -static CLASS_DEVICE_ATTR(card_vpp, 0400, pccard_show_vpp, NULL); +static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL); static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) { @@ -89,7 +81,7 @@ static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) return -ENODEV; return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10); } -static CLASS_DEVICE_ATTR(card_vcc, 0400, pccard_show_vcc, NULL); +static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL); static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count) @@ -106,6 +98,30 @@ static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, si } static CLASS_DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert); + +static ssize_t pccard_show_card_pm_state(struct class_device *dev, char *buf) +{ + struct pcmcia_socket *s = to_socket(dev); + return sprintf(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on"); +} + +static ssize_t pccard_store_card_pm_state(struct class_device *dev, const char *buf, size_t count) +{ + ssize_t ret = -EINVAL; + struct pcmcia_socket *s = to_socket(dev); + + if (!count) + return -EINVAL; + + if (!(s->state & SOCKET_SUSPEND) && !strncmp(buf, "off", 3)) + ret = pcmcia_suspend_card(s); + else if ((s->state & SOCKET_SUSPEND) && !strncmp(buf, "on", 2)) + ret = pcmcia_resume_card(s); + + return ret ? -ENODEV : count; +} +static CLASS_DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state); + static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, size_t count) { ssize_t ret; @@ -163,28 +179,163 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf, return -EINVAL; spin_lock_irqsave(&s->lock, flags); - if (!s->resource_setup_done) { + if (!s->resource_setup_done) s->resource_setup_done = 1; - spin_unlock_irqrestore(&s->lock, flags); + spin_unlock_irqrestore(&s->lock, flags); + + down(&s->skt_sem); + if ((s->callback) && + (s->state & SOCKET_PRESENT) && + !(s->state & SOCKET_CARDBUS)) { + if (try_module_get(s->callback->owner)) { + s->callback->requery(s); + module_put(s->callback->owner); + } + } + up(&s->skt_sem); + + return count; +} +static CLASS_DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource); + + +static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count) +{ + tuple_t tuple; + int status, i; + loff_t pointer = 0; + ssize_t ret = 0; + u_char *tuplebuffer; + u_char *tempbuffer; + + tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL); + if (!tuplebuffer) + return -ENOMEM; + + tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL); + if (!tempbuffer) { + ret = -ENOMEM; + goto free_tuple; + } + + memset(&tuple, 0, sizeof(tuple_t)); + + tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON; + tuple.DesiredTuple = RETURN_FIRST_TUPLE; + tuple.TupleOffset = 0; + + status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple); + while (!status) { + tuple.TupleData = tuplebuffer; + tuple.TupleDataMax = 255; + memset(tuplebuffer, 0, sizeof(u_char) * 255); + + status = pccard_get_tuple_data(s, &tuple); + if (status) + break; + + if (off < (pointer + 2 + tuple.TupleDataLen)) { + tempbuffer[0] = tuple.TupleCode & 0xff; + tempbuffer[1] = tuple.TupleLink & 0xff; + for (i = 0; i < tuple.TupleDataLen; i++) + tempbuffer[i + 2] = tuplebuffer[i] & 0xff; + + for (i = 0; i < (2 + tuple.TupleDataLen); i++) { + if (((i + pointer) >= off) && + (i + pointer) < (off + count)) { + buf[ret] = tempbuffer[i]; + ret++; + } + } + } + + pointer += 2 + tuple.TupleDataLen; + + if (pointer >= (off + count)) + break; + if (tuple.TupleCode == CISTPL_END) + break; + status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple); + } + + kfree(tempbuffer); + free_tuple: + kfree(tuplebuffer); + + return (ret); +} + +static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size_t count) +{ + unsigned int size = 0x200; + + if (off >= size) + count = 0; + else { + struct pcmcia_socket *s; + cisinfo_t cisinfo; + + if (off + count > size) + count = size - off; + + s = to_socket(container_of(kobj, struct class_device, kobj)); + + if (!(s->state & SOCKET_PRESENT)) + return -ENODEV; + if (pccard_validate_cis(s, BIND_FN_ALL, &cisinfo)) + return -EIO; + if (!cisinfo.Chains) + return -ENODATA; + + count = pccard_extract_cis(s, buf, off, count); + } + + return (count); +} + +static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count) +{ + struct pcmcia_socket *s = to_socket(container_of(kobj, struct class_device, kobj)); + cisdump_t *cis; + ssize_t ret = count; + + if (off) + return -EINVAL; + + if (count >= 0x200) + return -EINVAL; + + if (!(s->state & SOCKET_PRESENT)) + return -ENODEV; + + cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); + if (!cis) + return -ENOMEM; + + cis->Length = count + 1; + memcpy(cis->Data, buf, count); + + if (pcmcia_replace_cis(s, cis)) + ret = -EIO; + + kfree(cis); + + if (!ret) { down(&s->skt_sem); - if ((s->callback) && - (s->state & SOCKET_PRESENT) && + if ((s->callback) && (s->state & SOCKET_PRESENT) && !(s->state & SOCKET_CARDBUS)) { if (try_module_get(s->callback->owner)) { - s->callback->resources_done(s); + s->callback->requery(s); module_put(s->callback->owner); } } up(&s->skt_sem); - - return count; } - spin_unlock_irqrestore(&s->lock, flags); - return count; + + return (ret); } -static CLASS_DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource); static struct class_device_attribute *pccard_socket_attributes[] = { @@ -193,13 +344,22 @@ static struct class_device_attribute *pccard_socket_attributes[] = { &class_device_attr_card_vpp, &class_device_attr_card_vcc, &class_device_attr_card_insert, + &class_device_attr_card_pm_state, &class_device_attr_card_eject, &class_device_attr_card_irq_mask, &class_device_attr_available_resources_setup_done, NULL, }; -static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev) +static struct bin_attribute pccard_cis_attr = { + .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR, .owner = THIS_MODULE}, + .size = 0x200, + .read = pccard_show_cis, + .write = pccard_store_cis, +}; + +static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev, + struct class_interface *class_intf) { struct class_device_attribute **attr; int ret = 0; @@ -209,14 +369,18 @@ static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev) if (ret) break; } + if (!ret) + ret = sysfs_create_bin_file(&class_dev->kobj, &pccard_cis_attr); return ret; } -static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev) +static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev, + struct class_interface *class_intf) { struct class_device_attribute **attr; + sysfs_remove_bin_file(&class_dev->kobj, &pccard_cis_attr); for (attr = pccard_socket_attributes; *attr; attr++) class_device_remove_file(class_dev, *attr); } diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 7a3d1b8e1..d5b4ff744 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -30,6 +30,7 @@ #ifndef _LINUX_TI113X_H #define _LINUX_TI113X_H +#include /* Register definitions for TI 113X PCI-to-CardBus bridges */ diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 459e6e194..0574efd78 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -634,7 +634,7 @@ static void vrc4171_remove_sockets(void) static int __devinit vrc4171_card_setup(char *options) { if (options == NULL || *options == '\0') - return 1; + return 0; if (strncmp(options, "irq:", 4) == 0) { int irq; @@ -644,7 +644,7 @@ static int __devinit vrc4171_card_setup(char *options) vrc4171_irq = irq; if (*options != ',') - return 1; + return 0; options++; } @@ -663,10 +663,10 @@ static int __devinit vrc4171_card_setup(char *options) } if (*options != ',') - return 1; + return 0; options++; } else - return 1; + return 0; } @@ -688,7 +688,7 @@ static int __devinit vrc4171_card_setup(char *options) } if (*options != ',') - return 1; + return 0; options++; if (strncmp(options, "memnoprobe", 10) == 0) @@ -700,7 +700,7 @@ static int __devinit vrc4171_card_setup(char *options) } } - return 1; + return 0; } __setup("vrc4171_card=", vrc4171_card_setup); diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index 6004196f7..57f38dba0 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c @@ -516,7 +516,7 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev, static int __devinit vrc4173_cardu_setup(char *options) { if (options == NULL || *options == '\0') - return 1; + return 0; if (strncmp(options, "cardu1:", 7) == 0) { options += 7; @@ -527,9 +527,9 @@ static int __devinit vrc4173_cardu_setup(char *options) } if (*options != ',') - return 1; + return 0; } else - return 1; + return 0; } if (strncmp(options, "cardu2:", 7) == 0) { @@ -538,7 +538,7 @@ static int __devinit vrc4173_cardu_setup(char *options) cardu_sockets[CARDU2].noprobe = 1; } - return 1; + return 0; } __setup("vrc4173_cardu=", vrc4173_cardu_setup); diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index bb19c6407..b68eef251 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -47,7 +47,7 @@ static void card_remove(struct pnp_dev * dev) { dev->card_link = NULL; } - + static void card_remove_first(struct pnp_dev * dev) { struct pnp_card_driver * drv = to_pnp_card_driver(dev->driver); @@ -361,7 +361,7 @@ static int card_resume(struct pnp_dev *dev) int pnp_register_card_driver(struct pnp_card_driver * drv) { - int error; + int count; struct list_head *pos, *temp; drv->link.name = drv->name; @@ -372,19 +372,21 @@ int pnp_register_card_driver(struct pnp_card_driver * drv) drv->link.suspend = drv->suspend ? card_suspend : NULL; drv->link.resume = drv->resume ? card_resume : NULL; - error = pnp_register_driver(&drv->link); - if (error < 0) - return error; + count = pnp_register_driver(&drv->link); + if (count < 0) + return count; spin_lock(&pnp_lock); list_add_tail(&drv->global_list, &pnp_card_drivers); spin_unlock(&pnp_lock); + count = 0; + list_for_each_safe(pos,temp,&pnp_cards){ struct pnp_card *card = list_entry(pos, struct pnp_card, global_list); - card_probe(card,drv); + count += card_probe(card,drv); } - return 0; + return count; } /** diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index e54c15383..7cafacdd1 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -201,14 +201,31 @@ struct bus_type pnp_bus_type = { .resume = pnp_bus_resume, }; + +static int count_devices(struct device * dev, void * c) +{ + int * count = c; + (*count)++; + return 0; +} + int pnp_register_driver(struct pnp_driver *drv) { + int count; + pnp_dbg("the driver '%s' has been registered", drv->name); drv->driver.name = drv->name; drv->driver.bus = &pnp_bus_type; - return driver_register(&drv->driver); + count = driver_register(&drv->driver); + + /* get the number of initial matches */ + if (count >= 0){ + count = 0; + driver_for_each_device(&drv->driver, NULL, &count, count_devices); + } + return count; } void pnp_unregister_driver(struct pnp_driver *drv) diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index ac7c2bb6c..57fd60314 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #if 0 @@ -93,7 +92,7 @@ MODULE_LICENSE("GPL"); #define _LTAG_FIXEDMEM32RANGE 0x86 static unsigned char isapnp_checksum_value; -static DEFINE_MUTEX(isapnp_cfg_mutex); +static DECLARE_MUTEX(isapnp_cfg_mutex); static int isapnp_detected; static int isapnp_csn_count; @@ -647,10 +646,8 @@ static int __init isapnp_create_device(struct pnp_card *card, size = 0; skip = 0; option = pnp_register_independent_option(dev); - if (!option) { - kfree(dev); + if (!option) return 1; - } pnp_add_card_device(card,dev); } else { skip = 1; @@ -904,7 +901,7 @@ int isapnp_cfg_begin(int csn, int logdev) { if (csn < 1 || csn > isapnp_csn_count || logdev > 10) return -EINVAL; - mutex_lock(&isapnp_cfg_mutex); + down(&isapnp_cfg_mutex); isapnp_wait(); isapnp_key(); isapnp_wake(csn); @@ -930,7 +927,7 @@ int isapnp_cfg_begin(int csn, int logdev) int isapnp_cfg_end(void) { isapnp_wait(); - mutex_unlock(&isapnp_cfg_mutex); + up(&isapnp_cfg_mutex); return 0; } diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 6fff109bd..c4256aa32 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -479,7 +479,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev) int pnp_start_dev(struct pnp_dev *dev) { if (!pnp_can_write(dev)) { - pnp_info("Device %s does not support activation.", dev->dev.bus_id); + pnp_info("Device %s does not supported activation.", dev->dev.bus_id); return -EINVAL; } @@ -503,7 +503,7 @@ int pnp_start_dev(struct pnp_dev *dev) int pnp_stop_dev(struct pnp_dev *dev) { if (!pnp_can_disable(dev)) { - pnp_info("Device %s does not support disabling.", dev->dev.bus_id); + pnp_info("Device %s does not supported disabling.", dev->dev.bus_id); return -EINVAL; } if (dev->protocol->disable(dev)<0) { diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index c89c98a2c..5e38cd733 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -448,7 +448,11 @@ pnpbios_parse_resource_option_data(unsigned char * p, unsigned char * end, struc break; case SMALL_TAG_END: - return p + 2; + if (option_independent != option) + printk(KERN_WARNING "PnPBIOS: Missing SMALL_TAG_ENDDEP tag\n"); + p = p + 2; + return (unsigned char *)p; + break; default: /* an unkown tag */ len_err: diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 688421de9..6ded52716 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -396,8 +396,7 @@ int pnp_check_irq(struct pnp_dev * dev, int idx) /* check if the resource is already in use, skip if the * device is active because it itself may be in use */ if(!dev->active) { - if (request_irq(*irq, pnp_test_handler, - SA_INTERRUPT|SA_PROBEIRQ, "pnp", NULL)) + if (request_irq(*irq, pnp_test_handler, SA_INTERRUPT, "pnp", NULL)) return 0; free_irq(*irq, NULL); } diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig deleted file mode 100644 index 65d090dbe..000000000 --- a/drivers/rtc/Kconfig +++ /dev/null @@ -1,175 +0,0 @@ -\# -# RTC class/drivers configuration -# - -menu "Real Time Clock" - -config RTC_LIB - tristate - -config RTC_CLASS - tristate "RTC class" - depends on EXPERIMENTAL - default n - select RTC_LIB - help - Generic RTC class support. If you say yes here, you will - be allowed to plug one or more RTCs to your system. You will - probably want to enable one of more of the interfaces below. - - This driver can also be built as a module. If so, the module - will be called rtc-class. - -config RTC_HCTOSYS - bool "Set system time from RTC on startup" - depends on RTC_CLASS = y - default y - help - If you say yes here, the system time will be set using - the value read from the specified RTC device. This is useful - in order to avoid unnecessary fschk runs. - -config RTC_HCTOSYS_DEVICE - string "The RTC to read the time from" - depends on RTC_HCTOSYS = y - default "rtc0" - help - The RTC device that will be used as the source for - the system time, usually rtc0. - -comment "RTC interfaces" - depends on RTC_CLASS - -config RTC_INTF_SYSFS - tristate "sysfs" - depends on RTC_CLASS && SYSFS - default RTC_CLASS - help - Say yes here if you want to use your RTC using the sysfs - interface, /sys/class/rtc/rtcX . - - This driver can also be built as a module. If so, the module - will be called rtc-sysfs. - -config RTC_INTF_PROC - tristate "proc" - depends on RTC_CLASS && PROC_FS - default RTC_CLASS - help - Say yes here if you want to use your RTC using the proc - interface, /proc/driver/rtc . - - This driver can also be built as a module. If so, the module - will be called rtc-proc. - -config RTC_INTF_DEV - tristate "dev" - depends on RTC_CLASS - default RTC_CLASS - help - Say yes here if you want to use your RTC using the dev - interface, /dev/rtc . - - This driver can also be built as a module. If so, the module - will be called rtc-dev. - -comment "RTC drivers" - depends on RTC_CLASS - -config RTC_DRV_X1205 - tristate "Xicor/Intersil X1205" - depends on RTC_CLASS && I2C - help - If you say yes here you get support for the - Xicor/Intersil X1205 RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-x1205. - -config RTC_DRV_DS1672 - tristate "Dallas/Maxim DS1672" - depends on RTC_CLASS && I2C - help - If you say yes here you get support for the - Dallas/Maxim DS1672 timekeeping chip. - - This driver can also be built as a module. If so, the module - will be called rtc-ds1672. - -config RTC_DRV_PCF8563 - tristate "Philips PCF8563/Epson RTC8564" - depends on RTC_CLASS && I2C - help - If you say yes here you get support for the - Philips PCF8563 RTC chip. The Epson RTC8564 - should work as well. - - This driver can also be built as a module. If so, the module - will be called rtc-pcf8563. - -config RTC_DRV_RS5C372 - tristate "Ricoh RS5C372A/B" - depends on RTC_CLASS && I2C - help - If you say yes here you get support for the - Ricoh RS5C372A and RS5C372B RTC chips. - - This driver can also be built as a module. If so, the module - will be called rtc-rs5c372. - -config RTC_DRV_M48T86 - tristate "ST M48T86/Dallas DS12887" - depends on RTC_CLASS - help - If you say Y here you will get support for the - ST M48T86 and Dallas DS12887 RTC chips. - - This driver can also be built as a module. If so, the module - will be called rtc-m48t86. - -config RTC_DRV_EP93XX - tristate "Cirrus Logic EP93XX" - depends on RTC_CLASS && ARCH_EP93XX - help - If you say yes here you get support for the - RTC embedded in the Cirrus Logic EP93XX processors. - - This driver can also be built as a module. If so, the module - will be called rtc-ep93xx. - -config RTC_DRV_SA1100 - tristate "SA11x0/PXA2xx" - depends on RTC_CLASS && (ARCH_SA1100 || ARCH_PXA) - help - If you say Y here you will get access to the real time clock - built into your SA11x0 or PXA2xx CPU. - - To compile this driver as a module, choose M here: the - module will be called rtc-sa1100. - -config RTC_DRV_VR41XX - tristate "NEC VR41XX" - depends on RTC_CLASS && CPU_VR41XX - help - If you say Y here you will get access to the real time clock - built into your NEC VR41XX CPU. - - To compile this driver as a module, choose M here: the - module will be called rtc-vr41xx. - -config RTC_DRV_TEST - tristate "Test driver/device" - depends on RTC_CLASS - help - If you say yes here you get support for the - RTC test driver. It's a software RTC which can be - used to test the RTC subsystem APIs. It gets - the time from the system clock. - You want this driver only if you are doing development - on the RTC subsystem. Please read the source code - for further details. - - This driver can also be built as a module. If so, the module - will be called rtc-test. - -endmenu diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile deleted file mode 100644 index a9ca0f171..000000000 --- a/drivers/rtc/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# -# Makefile for RTC class/drivers. -# - -obj-$(CONFIG_RTC_LIB) += rtc-lib.o -obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o -obj-$(CONFIG_RTC_CLASS) += rtc-core.o -rtc-core-y := class.o interface.o - -obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o -obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o -obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o - -obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o -obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o -obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o -obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o -obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o -obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o -obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o -obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o -obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c deleted file mode 100644 index 413c7d54e..000000000 --- a/drivers/rtc/class.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * RTC subsystem, base class - * - * Copyright (C) 2005 Tower Technologies - * Author: Alessandro Zummo - * - * class skeleton from drivers/hwmon/hwmon.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include - -static DEFINE_IDR(rtc_idr); -static DEFINE_MUTEX(idr_lock); -struct class *rtc_class; - -static void rtc_device_release(struct class_device *class_dev) -{ - struct rtc_device *rtc = to_rtc_device(class_dev); - mutex_lock(&idr_lock); - idr_remove(&rtc_idr, rtc->id); - mutex_unlock(&idr_lock); - kfree(rtc); -} - -/** - * rtc_device_register - register w/ RTC class - * @dev: the device to register - * - * rtc_device_unregister() must be called when the class device is no - * longer needed. - * - * Returns the pointer to the new struct class device. - */ -struct rtc_device *rtc_device_register(const char *name, struct device *dev, - struct rtc_class_ops *ops, - struct module *owner) -{ - struct rtc_device *rtc; - int id, err; - - if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { - err = -ENOMEM; - goto exit; - } - - - mutex_lock(&idr_lock); - err = idr_get_new(&rtc_idr, NULL, &id); - mutex_unlock(&idr_lock); - - if (err < 0) - goto exit; - - id = id & MAX_ID_MASK; - - rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); - if (rtc == NULL) { - err = -ENOMEM; - goto exit_idr; - } - - rtc->id = id; - rtc->ops = ops; - rtc->owner = owner; - rtc->class_dev.dev = dev; - rtc->class_dev.class = rtc_class; - rtc->class_dev.release = rtc_device_release; - - mutex_init(&rtc->ops_lock); - spin_lock_init(&rtc->irq_lock); - spin_lock_init(&rtc->irq_task_lock); - - strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); - snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id); - - err = class_device_register(&rtc->class_dev); - if (err) - goto exit_kfree; - - dev_info(dev, "rtc core: registered %s as %s\n", - rtc->name, rtc->class_dev.class_id); - - return rtc; - -exit_kfree: - kfree(rtc); - -exit_idr: - idr_remove(&rtc_idr, id); - -exit: - dev_err(dev, "rtc core: unable to register %s, err = %d\n", - name, err); - return ERR_PTR(err); -} -EXPORT_SYMBOL_GPL(rtc_device_register); - - -/** - * rtc_device_unregister - removes the previously registered RTC class device - * - * @rtc: the RTC class device to destroy - */ -void rtc_device_unregister(struct rtc_device *rtc) -{ - mutex_lock(&rtc->ops_lock); - rtc->ops = NULL; - mutex_unlock(&rtc->ops_lock); - class_device_unregister(&rtc->class_dev); -} -EXPORT_SYMBOL_GPL(rtc_device_unregister); - -int rtc_interface_register(struct class_interface *intf) -{ - intf->class = rtc_class; - return class_interface_register(intf); -} -EXPORT_SYMBOL_GPL(rtc_interface_register); - -static int __init rtc_init(void) -{ - rtc_class = class_create(THIS_MODULE, "rtc"); - if (IS_ERR(rtc_class)) { - printk(KERN_ERR "%s: couldn't create class\n", __FILE__); - return PTR_ERR(rtc_class); - } - return 0; -} - -static void __exit rtc_exit(void) -{ - class_destroy(rtc_class); -} - -module_init(rtc_init); -module_exit(rtc_exit); - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("RTC class support"); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c deleted file mode 100644 index d02fe9a00..000000000 --- a/drivers/rtc/hctosys.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * RTC subsystem, initialize system time on startup - * - * Copyright (C) 2005 Tower Technologies - * Author: Alessandro Zummo - * - * 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 - -/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary - * whether it stores the most close value or the value with partial - * seconds truncated. However, it is important that we use it to store - * the truncated value. This is because otherwise it is necessary, - * in an rtc sync function, to read both xtime.tv_sec and - * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read - * of >32bits is not possible. So storing the most close value would - * slow down the sync API. So here we have the truncated value and - * the best guess is to add 0.5s. - */ - -static int __init rtc_hctosys(void) -{ - int err; - struct rtc_time tm; - struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); - - if (class_dev == NULL) { - printk("%s: unable to open rtc device (%s)\n", - __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); - return -ENODEV; - } - - err = rtc_read_time(class_dev, &tm); - if (err == 0) { - err = rtc_valid_tm(&tm); - if (err == 0) { - struct timespec tv; - - tv.tv_nsec = NSEC_PER_SEC >> 1; - - rtc_tm_to_time(&tm, &tv.tv_sec); - - do_settimeofday(&tv); - - dev_info(class_dev->dev, - "setting the system clock to " - "%d-%02d-%02d %02d:%02d:%02d (%u)\n", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, - (unsigned int) tv.tv_sec); - } - else - dev_err(class_dev->dev, - "hctosys: invalid date/time\n"); - } - else - dev_err(class_dev->dev, - "hctosys: unable to read the hardware clock\n"); - - rtc_class_close(class_dev); - - return 0; -} - -late_initcall(rtc_hctosys); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c deleted file mode 100644 index 56e490709..000000000 --- a/drivers/rtc/interface.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * RTC subsystem, interface functions - * - * Copyright (C) 2005 Tower Technologies - * Author: Alessandro Zummo - * - * based on arch/arm/common/rtctime.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include - -int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) -{ - int err; - struct rtc_device *rtc = to_rtc_device(class_dev); - - err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return -EBUSY; - - if (!rtc->ops) - err = -ENODEV; - else if (!rtc->ops->read_time) - err = -EINVAL; - else { - memset(tm, 0, sizeof(struct rtc_time)); - err = rtc->ops->read_time(class_dev->dev, tm); - } - - mutex_unlock(&rtc->ops_lock); - return err; -} -EXPORT_SYMBOL_GPL(rtc_read_time); - -int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm) -{ - int err; - struct rtc_device *rtc = to_rtc_device(class_dev); - - err = rtc_valid_tm(tm); - if (err != 0) - return err; - - err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return -EBUSY; - - if (!rtc->ops) - err = -ENODEV; - else if (!rtc->ops->set_time) - err = -EINVAL; - else - err = rtc->ops->set_time(class_dev->dev, tm); - - mutex_unlock(&rtc->ops_lock); - return err; -} -EXPORT_SYMBOL_GPL(rtc_set_time); - -int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) -{ - int err; - struct rtc_device *rtc = to_rtc_device(class_dev); - - err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return -EBUSY; - - if (!rtc->ops) - err = -ENODEV; - else if (rtc->ops->set_mmss) - err = rtc->ops->set_mmss(class_dev->dev, secs); - else if (rtc->ops->read_time && rtc->ops->set_time) { - struct rtc_time new, old; - - err = rtc->ops->read_time(class_dev->dev, &old); - if (err == 0) { - rtc_time_to_tm(secs, &new); - - /* - * avoid writing when we're going to change the day of - * the month. We will retry in the next minute. This - * basically means that if the RTC must not drift - * by more than 1 minute in 11 minutes. - */ - if (!((old.tm_hour == 23 && old.tm_min == 59) || - (new.tm_hour == 23 && new.tm_min == 59))) - err = rtc->ops->set_time(class_dev->dev, &new); - } - } - else - err = -EINVAL; - - mutex_unlock(&rtc->ops_lock); - - return err; -} -EXPORT_SYMBOL_GPL(rtc_set_mmss); - -int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) -{ - int err; - struct rtc_device *rtc = to_rtc_device(class_dev); - - err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return -EBUSY; - - if (rtc->ops == NULL) - err = -ENODEV; - else if (!rtc->ops->read_alarm) - err = -EINVAL; - else { - memset(alarm, 0, sizeof(struct rtc_wkalrm)); - err = rtc->ops->read_alarm(class_dev->dev, alarm); - } - - mutex_unlock(&rtc->ops_lock); - return err; -} -EXPORT_SYMBOL_GPL(rtc_read_alarm); - -int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) -{ - int err; - struct rtc_device *rtc = to_rtc_device(class_dev); - - err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return -EBUSY; - - if (!rtc->ops) - err = -ENODEV; - else if (!rtc->ops->set_alarm) - err = -EINVAL; - else - err = rtc->ops->set_alarm(class_dev->dev, alarm); - - mutex_unlock(&rtc->ops_lock); - return err; -} -EXPORT_SYMBOL_GPL(rtc_set_alarm); - -void rtc_update_irq(struct class_device *class_dev, - unsigned long num, unsigned long events) -{ - struct rtc_device *rtc = to_rtc_device(class_dev); - - spin_lock(&rtc->irq_lock); - rtc->irq_data = (rtc->irq_data + (num << 8)) | events; - spin_unlock(&rtc->irq_lock); - - spin_lock(&rtc->irq_task_lock); - if (rtc->irq_task) - rtc->irq_task->func(rtc->irq_task->private_data); - spin_unlock(&rtc->irq_task_lock); - - wake_up_interruptible(&rtc->irq_queue); - kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); -} -EXPORT_SYMBOL_GPL(rtc_update_irq); - -struct class_device *rtc_class_open(char *name) -{ - struct class_device *class_dev = NULL, - *class_dev_tmp; - - down(&rtc_class->sem); - list_for_each_entry(class_dev_tmp, &rtc_class->children, node) { - if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) { - class_dev = class_dev_tmp; - break; - } - } - - if (class_dev) { - if (!try_module_get(to_rtc_device(class_dev)->owner)) - class_dev = NULL; - } - up(&rtc_class->sem); - - return class_dev; -} -EXPORT_SYMBOL_GPL(rtc_class_open); - -void rtc_class_close(struct class_device *class_dev) -{ - module_put(to_rtc_device(class_dev)->owner); -} -EXPORT_SYMBOL_GPL(rtc_class_close); - -int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) -{ - int retval = -EBUSY; - struct rtc_device *rtc = to_rtc_device(class_dev); - - if (task == NULL || task->func == NULL) - return -EINVAL; - - spin_lock(&rtc->irq_task_lock); - if (rtc->irq_task == NULL) { - rtc->irq_task = task; - retval = 0; - } - spin_unlock(&rtc->irq_task_lock); - - return retval; -} -EXPORT_SYMBOL_GPL(rtc_irq_register); - -void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) -{ - struct rtc_device *rtc = to_rtc_device(class_dev); - - spin_lock(&rtc->irq_task_lock); - if (rtc->irq_task == task) - rtc->irq_task = NULL; - spin_unlock(&rtc->irq_task_lock); -} -EXPORT_SYMBOL_GPL(rtc_irq_unregister); - -int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled) -{ - int err = 0; - unsigned long flags; - struct rtc_device *rtc = to_rtc_device(class_dev); - - spin_lock_irqsave(&rtc->irq_task_lock, flags); - if (rtc->irq_task != task) - err = -ENXIO; - spin_unlock_irqrestore(&rtc->irq_task_lock, flags); - - if (err == 0) - err = rtc->ops->irq_set_state(class_dev->dev, enabled); - - return err; -} -EXPORT_SYMBOL_GPL(rtc_irq_set_state); - -int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) -{ - int err = 0, tmp = 0; - unsigned long flags; - struct rtc_device *rtc = to_rtc_device(class_dev); - - /* allowed range is 2-8192 */ - if (freq < 2 || freq > 8192) - return -EINVAL; -/* - FIXME: this does not belong here, will move where appropriate - at a later stage. It cannot hurt right now, trust me :) - if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) - return -EACCES; -*/ - /* check if freq is a power of 2 */ - while (freq > (1 << tmp)) - tmp++; - - if (freq != (1 << tmp)) - return -EINVAL; - - spin_lock_irqsave(&rtc->irq_task_lock, flags); - if (rtc->irq_task != task) - err = -ENXIO; - spin_unlock_irqrestore(&rtc->irq_task_lock, flags); - - if (err == 0) { - err = rtc->ops->irq_set_freq(class_dev->dev, freq); - if (err == 0) - rtc->irq_freq = freq; - } - return err; -} diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c deleted file mode 100644 index 201156700..000000000 --- a/drivers/rtc/rtc-dev.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * RTC subsystem, dev interface - * - * Copyright (C) 2005 Tower Technologies - * Author: Alessandro Zummo - * - * based on arch/arm/common/rtctime.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include - -static struct class *rtc_dev_class; -static dev_t rtc_devt; - -#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */ - -static int rtc_dev_open(struct inode *inode, struct file *file) -{ - int err; - struct rtc_device *rtc = container_of(inode->i_cdev, - struct rtc_device, char_dev); - struct rtc_class_ops *ops = rtc->ops; - - /* We keep the lock as long as the device is in use - * and return immediately if busy - */ - if (!(mutex_trylock(&rtc->char_lock))) - return -EBUSY; - - file->private_data = &rtc->class_dev; - - err = ops->open ? ops->open(rtc->class_dev.dev) : 0; - if (err == 0) { - spin_lock_irq(&rtc->irq_lock); - rtc->irq_data = 0; - spin_unlock_irq(&rtc->irq_lock); - - return 0; - } - - /* something has gone wrong, release the lock */ - mutex_unlock(&rtc->char_lock); - return err; -} - - -static ssize_t -rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) -{ - struct rtc_device *rtc = to_rtc_device(file->private_data); - - DECLARE_WAITQUEUE(wait, current); - unsigned long data; - ssize_t ret; - - if (count != sizeof(unsigned int) && count < sizeof(unsigned long)) - return -EINVAL; - - add_wait_queue(&rtc->irq_queue, &wait); - do { - __set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irq(&rtc->irq_lock); - data = rtc->irq_data; - rtc->irq_data = 0; - spin_unlock_irq(&rtc->irq_lock); - - if (data != 0) { - ret = 0; - break; - } - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - schedule(); - } while (1); - set_current_state(TASK_RUNNING); - remove_wait_queue(&rtc->irq_queue, &wait); - - if (ret == 0) { - /* Check for any data updates */ - if (rtc->ops->read_callback) - data = rtc->ops->read_callback(rtc->class_dev.dev, - data); - - if (sizeof(int) != sizeof(long) && - count == sizeof(unsigned int)) - ret = put_user(data, (unsigned int __user *)buf) ?: - sizeof(unsigned int); - else - ret = put_user(data, (unsigned long __user *)buf) ?: - sizeof(unsigned long); - } - return ret; -} - -static unsigned int rtc_dev_poll(struct file *file, poll_table *wait) -{ - struct rtc_device *rtc = to_rtc_device(file->private_data); - unsigned long data; - - poll_wait(file, &rtc->irq_queue, wait); - - data = rtc->irq_data; - - return (data != 0) ? (POLLIN | POLLRDNORM) : 0; -} - -static int rtc_dev_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int err = 0; - struct class_device *class_dev = file->private_data; - struct rtc_device *rtc = to_rtc_device(class_dev); - struct rtc_class_ops *ops = rtc->ops; - struct rtc_time tm; - struct rtc_wkalrm alarm; - void __user *uarg = (void __user *) arg; - - /* avoid conflicting IRQ users */ - if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { - spin_lock(&rtc->irq_task_lock); - if (rtc->irq_task) - err = -EBUSY; - spin_unlock(&rtc->irq_task_lock); - - if (err < 0) - return err; - } - - /* try the driver's ioctl interface */ - if (ops->ioctl) { - err = ops->ioctl(class_dev->dev, cmd, arg); - if (err != -ENOIOCTLCMD) - return err; - } - - /* if the driver does not provide the ioctl interface - * or if that particular ioctl was not implemented - * (-ENOIOCTLCMD), we will try to emulate here. - */ - - switch (cmd) { - case RTC_ALM_READ: - err = rtc_read_alarm(class_dev, &alarm); - if (err < 0) - return err; - - if (copy_to_user(uarg, &alarm.time, sizeof(tm))) - return -EFAULT; - break; - - case RTC_ALM_SET: - if (copy_from_user(&alarm.time, uarg, sizeof(tm))) - return -EFAULT; - - alarm.enabled = 0; - alarm.pending = 0; - alarm.time.tm_mday = -1; - alarm.time.tm_mon = -1; - alarm.time.tm_year = -1; - alarm.time.tm_wday = -1; - alarm.time.tm_yday = -1; - alarm.time.tm_isdst = -1; - err = rtc_set_alarm(class_dev, &alarm); - break; - - case RTC_RD_TIME: - err = rtc_read_time(class_dev, &tm); - if (err < 0) - return err; - - if (copy_to_user(uarg, &tm, sizeof(tm))) - return -EFAULT; - break; - - case RTC_SET_TIME: - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&tm, uarg, sizeof(tm))) - return -EFAULT; - - err = rtc_set_time(class_dev, &tm); - break; -#if 0 - case RTC_EPOCH_SET: -#ifndef rtc_epoch - /* - * There were no RTC clocks before 1900. - */ - if (arg < 1900) { - err = -EINVAL; - break; - } - if (!capable(CAP_SYS_TIME)) { - err = -EACCES; - break; - } - rtc_epoch = arg; - err = 0; -#endif - break; - - case RTC_EPOCH_READ: - err = put_user(rtc_epoch, (unsigned long __user *)uarg); - break; -#endif - case RTC_WKALM_SET: - if (copy_from_user(&alarm, uarg, sizeof(alarm))) - return -EFAULT; - - err = rtc_set_alarm(class_dev, &alarm); - break; - - case RTC_WKALM_RD: - err = rtc_read_alarm(class_dev, &alarm); - if (err < 0) - return err; - - if (copy_to_user(uarg, &alarm, sizeof(alarm))) - return -EFAULT; - break; - - default: - err = -ENOTTY; - break; - } - - return err; -} - -static int rtc_dev_release(struct inode *inode, struct file *file) -{ - struct rtc_device *rtc = to_rtc_device(file->private_data); - - if (rtc->ops->release) - rtc->ops->release(rtc->class_dev.dev); - - mutex_unlock(&rtc->char_lock); - return 0; -} - -static int rtc_dev_fasync(int fd, struct file *file, int on) -{ - struct rtc_device *rtc = to_rtc_device(file->private_data); - return fasync_helper(fd, file, on, &rtc->async_queue); -} - -static struct file_operations rtc_dev_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = rtc_dev_read, - .poll = rtc_dev_poll, - .ioctl = rtc_dev_ioctl, - .open = rtc_dev_open, - .release = rtc_dev_release, - .fasync = rtc_dev_fasync, -}; - -/* insertion/removal hooks */ - -static int rtc_dev_add_device(struct class_device *class_dev, - struct class_interface *class_intf) -{ - int err = 0; - struct rtc_device *rtc = to_rtc_device(class_dev); - - if (rtc->id >= RTC_DEV_MAX) { - dev_err(class_dev->dev, "too many RTCs\n"); - return -EINVAL; - } - - mutex_init(&rtc->char_lock); - spin_lock_init(&rtc->irq_lock); - init_waitqueue_head(&rtc->irq_queue); - - cdev_init(&rtc->char_dev, &rtc_dev_fops); - rtc->char_dev.owner = rtc->owner; - - if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) { - cdev_del(&rtc->char_dev); - dev_err(class_dev->dev, - "failed to add char device %d:%d\n", - MAJOR(rtc_devt), rtc->id); - return -ENODEV; - } - - rtc->rtc_dev = class_device_create(rtc_dev_class, NULL, - MKDEV(MAJOR(rtc_devt), rtc->id), - class_dev->dev, "rtc%d", rtc->id); - if (IS_ERR(rtc->rtc_dev)) { - dev_err(class_dev->dev, "cannot create rtc_dev device\n"); - err = PTR_ERR(rtc->rtc_dev); - goto err_cdev_del; - } - - dev_info(class_dev->dev, "rtc intf: dev (%d:%d)\n", - MAJOR(rtc->rtc_dev->devt), - MINOR(rtc->rtc_dev->devt)); - - return 0; - -err_cdev_del: - - cdev_del(&rtc->char_dev); - return err; -} - -static void rtc_dev_remove_device(struct class_device *class_dev, - struct class_interface *class_intf) -{ - struct rtc_device *rtc = to_rtc_device(class_dev); - - if (rtc->rtc_dev) { - dev_dbg(class_dev->dev, "removing char %d:%d\n", - MAJOR(rtc->rtc_dev->devt), - MINOR(rtc->rtc_dev->devt)); - - class_device_unregister(rtc->rtc_dev); - cdev_del(&rtc->char_dev); - } -} - -/* interface registration */ - -static struct class_interface rtc_dev_interface = { - .add = &rtc_dev_add_device, - .remove = &rtc_dev_remove_device, -}; - -static int __init rtc_dev_init(void) -{ - int err; - - rtc_dev_class = class_create(THIS_MODULE, "rtc-dev"); - if (IS_ERR(rtc_dev_class)) - return PTR_ERR(rtc_dev_class); - - err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); - if (err < 0) { - printk(KERN_ERR "%s: failed to allocate char dev region\n", - __FILE__); - goto err_destroy_class; - } - - err = rtc_interface_register(&rtc_dev_interface); - if (err < 0) { - printk(KERN_ERR "%s: failed to register the interface\n", - __FILE__); - goto err_unregister_chrdev; - } - - return 0; - -err_unregister_chrdev: - unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); - -err_destroy_class: - class_destroy(rtc_dev_class); - - return err; -} - -static void __exit rtc_dev_exit(void) -{ - class_interface_unregister(&rtc_dev_interface); - class_destroy(rtc_dev_class); - unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); -} - -module_init(rtc_dev_init); -module_exit(rtc_dev_exit); - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("RTC class dev interface"); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c deleted file mode 100644 index 9be81fd47..000000000 --- a/drivers/rtc/rtc-ds1672.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * An rtc/i2c driver for the Dallas DS1672 - * Copyright 2005-06 Tower Technologies - * - * Author: Alessandro Zummo - * - * 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 -#include -#include - -#define DRV_VERSION "0.3" - -/* Addresses to scan: none. This chip cannot be detected. */ -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD; - -/* Registers */ - -#define DS1672_REG_CNT_BASE 0 -#define DS1672_REG_CONTROL 4 -#define DS1672_REG_TRICKLE 5 - -#define DS1672_REG_CONTROL_EOSC 0x80 - -/* Prototypes */ -static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind); - -/* - * In the routines that deal directly with the ds1672 hardware, we use - * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch - * Epoch is initialized as 2000. Time is set to UTC. - */ -static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) -{ - unsigned long time; - unsigned char addr = DS1672_REG_CNT_BASE; - unsigned char buf[4]; - - struct i2c_msg msgs[] = { - { client->addr, 0, 1, &addr }, /* setup read ptr */ - { client->addr, I2C_M_RD, 4, buf }, /* read date */ - }; - - /* read date registers */ - if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - dev_dbg(&client->dev, - "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" - __FUNCTION__, buf[0], buf[1], buf[2], buf[3]); - - time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; - - rtc_time_to_tm(time, tm); - - dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - return 0; -} - -static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) -{ - int xfer; - unsigned char buf[6]; - - buf[0] = DS1672_REG_CNT_BASE; - buf[1] = secs & 0x000000FF; - buf[2] = (secs & 0x0000FF00) >> 8; - buf[3] = (secs & 0x00FF0000) >> 16; - buf[4] = (secs & 0xFF000000) >> 24; - buf[5] = 0; /* set control reg to enable counting */ - - xfer = i2c_master_send(client, buf, 6); - if (xfer != 6) { - dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer); - return -EIO; - } - - return 0; -} - -static int ds1672_set_datetime(struct i2c_client *client, struct rtc_time *tm) -{ - unsigned long secs; - - dev_dbg(&client->dev, - "%s: secs=%d, mins=%d, hours=%d, ", - "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - rtc_tm_to_time(tm, &secs); - - return ds1672_set_mmss(client, secs); -} - -static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return ds1672_get_datetime(to_i2c_client(dev), tm); -} - -static int ds1672_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return ds1672_set_datetime(to_i2c_client(dev), tm); -} - -static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) -{ - return ds1672_set_mmss(to_i2c_client(dev), secs); -} - -static int ds1672_get_control(struct i2c_client *client, u8 *status) -{ - unsigned char addr = DS1672_REG_CONTROL; - - struct i2c_msg msgs[] = { - { client->addr, 0, 1, &addr }, /* setup read ptr */ - { client->addr, I2C_M_RD, 1, status }, /* read control */ - }; - - /* read control register */ - if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - return 0; -} - -/* following are the sysfs callback functions */ -static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - u8 control; - int err; - - err = ds1672_get_control(client, &control); - if (err) - return err; - - return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC) - ? "disabled" : "enabled"); -} -static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); - -static struct rtc_class_ops ds1672_rtc_ops = { - .read_time = ds1672_rtc_read_time, - .set_time = ds1672_rtc_set_time, - .set_mmss = ds1672_rtc_set_mmss, -}; - -static int ds1672_attach(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, ds1672_probe); -} - -static int ds1672_detach(struct i2c_client *client) -{ - int err; - struct rtc_device *rtc = i2c_get_clientdata(client); - - if (rtc) - rtc_device_unregister(rtc); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(client); - - return 0; -} - -static struct i2c_driver ds1672_driver = { - .driver = { - .name = "ds1672", - }, - .id = I2C_DRIVERID_DS1672, - .attach_adapter = &ds1672_attach, - .detach_client = &ds1672_detach, -}; - -static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) -{ - int err = 0; - u8 control; - struct i2c_client *client; - struct rtc_device *rtc; - - dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - err = -ENODEV; - goto exit; - } - - if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* I2C client */ - client->addr = address; - client->driver = &ds1672_driver; - client->adapter = adapter; - - strlcpy(client->name, ds1672_driver.driver.name, I2C_NAME_SIZE); - - /* Inform the i2c layer */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; - - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - - rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev, - &ds1672_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - goto exit_detach; - } - - i2c_set_clientdata(client, rtc); - - /* read control register */ - err = ds1672_get_control(client, &control); - if (err) - goto exit_detach; - - if (control & DS1672_REG_CONTROL_EOSC) - dev_warn(&client->dev, "Oscillator not enabled. " - "Set time to enable.\n"); - - /* Register sysfs hooks */ - device_create_file(&client->dev, &dev_attr_control); - - return 0; - -exit_detach: - i2c_detach_client(client); - -exit_kfree: - kfree(client); - -exit: - return err; -} - -static int __init ds1672_init(void) -{ - return i2c_add_driver(&ds1672_driver); -} - -static void __exit ds1672_exit(void) -{ - i2c_del_driver(&ds1672_driver); -} - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -module_init(ds1672_init); -module_exit(ds1672_exit); diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c deleted file mode 100644 index e1a1169e4..000000000 --- a/drivers/rtc/rtc-ep93xx.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * A driver for the RTC embedded in the Cirrus Logic EP93XX processors - * Copyright (c) 2006 Tower Technologies - * - * Author: Alessandro Zummo - * - * 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 -#include -#include -#include - -#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x)) -#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000) -#define EP93XX_RTC_LOAD EP93XX_RTC_REG(0x000C) -#define EP93XX_RTC_SWCOMP EP93XX_RTC_REG(0x0108) - -#define DRV_VERSION "0.2" - -static int ep93xx_get_swcomp(struct device *dev, unsigned short *preload, - unsigned short *delete) -{ - unsigned short comp = __raw_readl(EP93XX_RTC_SWCOMP); - - if (preload) - *preload = comp & 0xffff; - - if (delete) - *delete = (comp >> 16) & 0x1f; - - return 0; -} - -static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - unsigned long time = __raw_readl(EP93XX_RTC_DATA); - - rtc_time_to_tm(time, tm); - return 0; -} - -static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs) -{ - __raw_writel(secs + 1, EP93XX_RTC_LOAD); - return 0; -} - -static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - int err; - unsigned long secs; - - err = rtc_tm_to_time(tm, &secs); - if (err != 0) - return err; - - return ep93xx_rtc_set_mmss(dev, secs); -} - -static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) -{ - unsigned short preload, delete; - - ep93xx_get_swcomp(dev, &preload, &delete); - - seq_printf(seq, "preload\t\t: %d\n", preload); - seq_printf(seq, "delete\t\t: %d\n", delete); - - return 0; -} - -static struct rtc_class_ops ep93xx_rtc_ops = { - .read_time = ep93xx_rtc_read_time, - .set_time = ep93xx_rtc_set_time, - .set_mmss = ep93xx_rtc_set_mmss, - .proc = ep93xx_rtc_proc, -}; - -static ssize_t ep93xx_sysfs_show_comp_preload(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned short preload; - - ep93xx_get_swcomp(dev, &preload, NULL); - - return sprintf(buf, "%d\n", preload); -} -static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_sysfs_show_comp_preload, NULL); - -static ssize_t ep93xx_sysfs_show_comp_delete(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned short delete; - - ep93xx_get_swcomp(dev, NULL, &delete); - - return sprintf(buf, "%d\n", delete); -} -static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_sysfs_show_comp_delete, NULL); - - -static int __devinit ep93xx_rtc_probe(struct platform_device *dev) -{ - struct rtc_device *rtc = rtc_device_register("ep93xx", - &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - return PTR_ERR(rtc); - } - - platform_set_drvdata(dev, rtc); - - device_create_file(&dev->dev, &dev_attr_comp_preload); - device_create_file(&dev->dev, &dev_attr_comp_delete); - - return 0; -} - -static int __devexit ep93xx_rtc_remove(struct platform_device *dev) -{ - struct rtc_device *rtc = platform_get_drvdata(dev); - - if (rtc) - rtc_device_unregister(rtc); - - platform_set_drvdata(dev, NULL); - - return 0; -} - -static struct platform_driver ep93xx_rtc_platform_driver = { - .driver = { - .name = "ep93xx-rtc", - .owner = THIS_MODULE, - }, - .probe = ep93xx_rtc_probe, - .remove = __devexit_p(ep93xx_rtc_remove), -}; - -static int __init ep93xx_rtc_init(void) -{ - return platform_driver_register(&ep93xx_rtc_platform_driver); -} - -static void __exit ep93xx_rtc_exit(void) -{ - platform_driver_unregister(&ep93xx_rtc_platform_driver); -} - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("EP93XX RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -module_init(ep93xx_rtc_init); -module_exit(ep93xx_rtc_exit); diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c deleted file mode 100644 index cfedc1d28..000000000 --- a/drivers/rtc/rtc-lib.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * rtc and date/time utility functions - * - * Copyright (C) 2005-06 Tower Technologies - * Author: Alessandro Zummo - * - * based on arch/arm/common/rtctime.c and other bits - * - * 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 -#include - -static const unsigned char rtc_days_in_month[] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) -#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) - -int rtc_month_days(unsigned int month, unsigned int year) -{ - return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); -} -EXPORT_SYMBOL(rtc_month_days); - -/* - * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. - */ -void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) -{ - register int days, month, year; - - days = time / 86400; - time -= days * 86400; - - /* day of the week, 1970-01-01 was a Thursday */ - tm->tm_wday = (days + 4) % 7; - - year = 1970 + days / 365; - days -= (year - 1970) * 365 - + LEAPS_THRU_END_OF(year - 1) - - LEAPS_THRU_END_OF(1970 - 1); - if (days < 0) { - year -= 1; - days += 365 + LEAP_YEAR(year); - } - tm->tm_year = year - 1900; - tm->tm_yday = days + 1; - - for (month = 0; month < 11; month++) { - int newdays; - - newdays = days - rtc_month_days(month, year); - if (newdays < 0) - break; - days = newdays; - } - tm->tm_mon = month; - tm->tm_mday = days + 1; - - tm->tm_hour = time / 3600; - time -= tm->tm_hour * 3600; - tm->tm_min = time / 60; - tm->tm_sec = time - tm->tm_min * 60; -} -EXPORT_SYMBOL(rtc_time_to_tm); - -/* - * Does the rtc_time represent a valid date/time? - */ -int rtc_valid_tm(struct rtc_time *tm) -{ - if (tm->tm_year < 70 - || tm->tm_mon >= 12 - || tm->tm_mday < 1 - || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900) - || tm->tm_hour >= 24 - || tm->tm_min >= 60 - || tm->tm_sec >= 60) - return -EINVAL; - - return 0; -} -EXPORT_SYMBOL(rtc_valid_tm); - -/* - * Convert Gregorian date to seconds since 01-01-1970 00:00:00. - */ -int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) -{ - *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - return 0; -} -EXPORT_SYMBOL(rtc_tm_to_time); - -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c deleted file mode 100644 index 8c0d1a673..000000000 --- a/drivers/rtc/rtc-m48t86.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * ST M48T86 / Dallas DS12887 RTC driver - * Copyright (c) 2006 Tower Technologies - * - * Author: Alessandro Zummo - * - * 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 drivers only supports the clock running in BCD and 24H mode. - * If it will be ever adapted to binary and 12H mode, care must be taken - * to not introduce bugs. - */ - -#include -#include -#include -#include -#include - -#define M48T86_REG_SEC 0x00 -#define M48T86_REG_SECALRM 0x01 -#define M48T86_REG_MIN 0x02 -#define M48T86_REG_MINALRM 0x03 -#define M48T86_REG_HOUR 0x04 -#define M48T86_REG_HOURALRM 0x05 -#define M48T86_REG_DOW 0x06 /* 1 = sunday */ -#define M48T86_REG_DOM 0x07 -#define M48T86_REG_MONTH 0x08 /* 1 - 12 */ -#define M48T86_REG_YEAR 0x09 /* 0 - 99 */ -#define M48T86_REG_A 0x0A -#define M48T86_REG_B 0x0B -#define M48T86_REG_C 0x0C -#define M48T86_REG_D 0x0D - -#define M48T86_REG_B_H24 (1 << 1) -#define M48T86_REG_B_DM (1 << 2) -#define M48T86_REG_B_SET (1 << 7) -#define M48T86_REG_D_VRT (1 << 7) - -#define DRV_VERSION "0.1" - - -static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - unsigned char reg; - struct platform_device *pdev = to_platform_device(dev); - struct m48t86_ops *ops = pdev->dev.platform_data; - - reg = ops->readbyte(M48T86_REG_B); - - if (reg & M48T86_REG_B_DM) { - /* data (binary) mode */ - tm->tm_sec = ops->readbyte(M48T86_REG_SEC); - tm->tm_min = ops->readbyte(M48T86_REG_MIN); - tm->tm_hour = ops->readbyte(M48T86_REG_HOUR) & 0x3F; - tm->tm_mday = ops->readbyte(M48T86_REG_DOM); - /* tm_mon is 0-11 */ - tm->tm_mon = ops->readbyte(M48T86_REG_MONTH) - 1; - tm->tm_year = ops->readbyte(M48T86_REG_YEAR) + 100; - tm->tm_wday = ops->readbyte(M48T86_REG_DOW); - } else { - /* bcd mode */ - tm->tm_sec = BCD2BIN(ops->readbyte(M48T86_REG_SEC)); - tm->tm_min = BCD2BIN(ops->readbyte(M48T86_REG_MIN)); - tm->tm_hour = BCD2BIN(ops->readbyte(M48T86_REG_HOUR) & 0x3F); - tm->tm_mday = BCD2BIN(ops->readbyte(M48T86_REG_DOM)); - /* tm_mon is 0-11 */ - tm->tm_mon = BCD2BIN(ops->readbyte(M48T86_REG_MONTH)) - 1; - tm->tm_year = BCD2BIN(ops->readbyte(M48T86_REG_YEAR)) + 100; - tm->tm_wday = BCD2BIN(ops->readbyte(M48T86_REG_DOW)); - } - - /* correct the hour if the clock is in 12h mode */ - if (!(reg & M48T86_REG_B_H24)) - if (ops->readbyte(M48T86_REG_HOUR) & 0x80) - tm->tm_hour += 12; - - return 0; -} - -static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - unsigned char reg; - struct platform_device *pdev = to_platform_device(dev); - struct m48t86_ops *ops = pdev->dev.platform_data; - - reg = ops->readbyte(M48T86_REG_B); - - /* update flag and 24h mode */ - reg |= M48T86_REG_B_SET | M48T86_REG_B_H24; - ops->writebyte(reg, M48T86_REG_B); - - if (reg & M48T86_REG_B_DM) { - /* data (binary) mode */ - ops->writebyte(tm->tm_sec, M48T86_REG_SEC); - ops->writebyte(tm->tm_min, M48T86_REG_MIN); - ops->writebyte(tm->tm_hour, M48T86_REG_HOUR); - ops->writebyte(tm->tm_mday, M48T86_REG_DOM); - ops->writebyte(tm->tm_mon + 1, M48T86_REG_MONTH); - ops->writebyte(tm->tm_year % 100, M48T86_REG_YEAR); - ops->writebyte(tm->tm_wday, M48T86_REG_DOW); - } else { - /* bcd mode */ - ops->writebyte(BIN2BCD(tm->tm_sec), M48T86_REG_SEC); - ops->writebyte(BIN2BCD(tm->tm_min), M48T86_REG_MIN); - ops->writebyte(BIN2BCD(tm->tm_hour), M48T86_REG_HOUR); - ops->writebyte(BIN2BCD(tm->tm_mday), M48T86_REG_DOM); - ops->writebyte(BIN2BCD(tm->tm_mon + 1), M48T86_REG_MONTH); - ops->writebyte(BIN2BCD(tm->tm_year % 100), M48T86_REG_YEAR); - ops->writebyte(BIN2BCD(tm->tm_wday), M48T86_REG_DOW); - } - - /* update ended */ - reg &= ~M48T86_REG_B_SET; - ops->writebyte(reg, M48T86_REG_B); - - return 0; -} - -static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq) -{ - unsigned char reg; - struct platform_device *pdev = to_platform_device(dev); - struct m48t86_ops *ops = pdev->dev.platform_data; - - reg = ops->readbyte(M48T86_REG_B); - - seq_printf(seq, "mode\t\t: %s\n", - (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); - - reg = ops->readbyte(M48T86_REG_D); - - seq_printf(seq, "battery\t\t: %s\n", - (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted"); - - return 0; -} - -static struct rtc_class_ops m48t86_rtc_ops = { - .read_time = m48t86_rtc_read_time, - .set_time = m48t86_rtc_set_time, - .proc = m48t86_rtc_proc, -}; - -static int __devinit m48t86_rtc_probe(struct platform_device *dev) -{ - unsigned char reg; - struct m48t86_ops *ops = dev->dev.platform_data; - struct rtc_device *rtc = rtc_device_register("m48t86", - &dev->dev, &m48t86_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - platform_set_drvdata(dev, rtc); - - /* read battery status */ - reg = ops->readbyte(M48T86_REG_D); - dev_info(&dev->dev, "battery %s\n", - (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted"); - - return 0; -} - -static int __devexit m48t86_rtc_remove(struct platform_device *dev) -{ - struct rtc_device *rtc = platform_get_drvdata(dev); - - if (rtc) - rtc_device_unregister(rtc); - - platform_set_drvdata(dev, NULL); - - return 0; -} - -static struct platform_driver m48t86_rtc_platform_driver = { - .driver = { - .name = "rtc-m48t86", - .owner = THIS_MODULE, - }, - .probe = m48t86_rtc_probe, - .remove = __devexit_p(m48t86_rtc_remove), -}; - -static int __init m48t86_rtc_init(void) -{ - return platform_driver_register(&m48t86_rtc_platform_driver); -} - -static void __exit m48t86_rtc_exit(void) -{ - platform_driver_unregister(&m48t86_rtc_platform_driver); -} - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("M48T86 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -module_init(m48t86_rtc_init); -module_exit(m48t86_rtc_exit); diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c deleted file mode 100644 index ba9a583b7..000000000 --- a/drivers/rtc/rtc-pcf8563.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * An I2C driver for the Philips PCF8563 RTC - * Copyright 2005-06 Tower Technologies - * - * Author: Alessandro Zummo - * Maintainers: http://www.nslu2-linux.org/ - * - * based on the other drivers in this same directory. - * - * http://www.semiconductors.philips.com/acrobat/datasheets/PCF8563-04.pdf - * - * 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 -#include -#include - -#define DRV_VERSION "0.4.2" - -/* Addresses to scan: none - * This chip cannot be reliably autodetected. An empty eeprom - * located at 0x51 will pass the validation routine due to - * the way the registers are implemented. - */ -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Module parameters */ -I2C_CLIENT_INSMOD; - -#define PCF8563_REG_ST1 0x00 /* status */ -#define PCF8563_REG_ST2 0x01 - -#define PCF8563_REG_SC 0x02 /* datetime */ -#define PCF8563_REG_MN 0x03 -#define PCF8563_REG_HR 0x04 -#define PCF8563_REG_DM 0x05 -#define PCF8563_REG_DW 0x06 -#define PCF8563_REG_MO 0x07 -#define PCF8563_REG_YR 0x08 - -#define PCF8563_REG_AMN 0x09 /* alarm */ -#define PCF8563_REG_AHR 0x0A -#define PCF8563_REG_ADM 0x0B -#define PCF8563_REG_ADW 0x0C - -#define PCF8563_REG_CLKO 0x0D /* clock out */ -#define PCF8563_REG_TMRC 0x0E /* timer control */ -#define PCF8563_REG_TMR 0x0F /* timer */ - -#define PCF8563_SC_LV 0x80 /* low voltage */ -#define PCF8563_MO_C 0x80 /* century */ - -static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind); -static int pcf8563_detach(struct i2c_client *client); - -/* - * In the routines that deal directly with the pcf8563 hardware, we use - * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. - */ -static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) -{ - unsigned char buf[13] = { PCF8563_REG_ST1 }; - - struct i2c_msg msgs[] = { - { client->addr, 0, 1, buf }, /* setup read ptr */ - { client->addr, I2C_M_RD, 13, buf }, /* read status + date */ - }; - - /* read registers */ - if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) - dev_info(&client->dev, - "low voltage detected, date/time is not reliable.\n"); - - dev_dbg(&client->dev, - "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, " - "mday=%02x, wday=%02x, mon=%02x, year=%02x\n", - __FUNCTION__, - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7], - buf[8]); - - - tm->tm_sec = BCD2BIN(buf[PCF8563_REG_SC] & 0x7F); - tm->tm_min = BCD2BIN(buf[PCF8563_REG_MN] & 0x7F); - tm->tm_hour = BCD2BIN(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */ - tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F); - tm->tm_wday = buf[PCF8563_REG_DW] & 0x07; - tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ - tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]) - + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 100 : 0); - - dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - /* the clock can give out invalid datetime, but we cannot return - * -EINVAL otherwise hwclock will refuse to set the time on bootup. - */ - if (rtc_valid_tm(tm) < 0) - dev_err(&client->dev, "retrieved date/time is not valid.\n"); - - return 0; -} - -static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) -{ - int i, err; - unsigned char buf[9]; - - dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - /* hours, minutes and seconds */ - buf[PCF8563_REG_SC] = BIN2BCD(tm->tm_sec); - buf[PCF8563_REG_MN] = BIN2BCD(tm->tm_min); - buf[PCF8563_REG_HR] = BIN2BCD(tm->tm_hour); - - buf[PCF8563_REG_DM] = BIN2BCD(tm->tm_mday); - - /* month, 1 - 12 */ - buf[PCF8563_REG_MO] = BIN2BCD(tm->tm_mon + 1); - - /* year and century */ - buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100); - if (tm->tm_year / 100) - buf[PCF8563_REG_MO] |= PCF8563_MO_C; - - buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; - - /* write register's data */ - for (i = 0; i < 7; i++) { - unsigned char data[2] = { PCF8563_REG_SC + i, - buf[PCF8563_REG_SC + i] }; - - err = i2c_master_send(client, data, sizeof(data)); - if (err != sizeof(data)) { - dev_err(&client->dev, - "%s: err=%d addr=%02x, data=%02x\n", - __FUNCTION__, err, data[0], data[1]); - return -EIO; - } - }; - - return 0; -} - -struct pcf8563_limit -{ - unsigned char reg; - unsigned char mask; - unsigned char min; - unsigned char max; -}; - -static int pcf8563_validate_client(struct i2c_client *client) -{ - int i; - - static const struct pcf8563_limit pattern[] = { - /* register, mask, min, max */ - { PCF8563_REG_SC, 0x7F, 0, 59 }, - { PCF8563_REG_MN, 0x7F, 0, 59 }, - { PCF8563_REG_HR, 0x3F, 0, 23 }, - { PCF8563_REG_DM, 0x3F, 0, 31 }, - { PCF8563_REG_MO, 0x1F, 0, 12 }, - }; - - /* check limits (only registers with bcd values) */ - for (i = 0; i < ARRAY_SIZE(pattern); i++) { - int xfer; - unsigned char value; - unsigned char buf = pattern[i].reg; - - struct i2c_msg msgs[] = { - { client->addr, 0, 1, &buf }, - { client->addr, I2C_M_RD, 1, &buf }, - }; - - xfer = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - - if (xfer != ARRAY_SIZE(msgs)) { - dev_err(&client->adapter->dev, - "%s: could not read register 0x%02X\n", - __FUNCTION__, pattern[i].reg); - - return -EIO; - } - - value = BCD2BIN(buf & pattern[i].mask); - - if (value > pattern[i].max || - value < pattern[i].min) { - dev_dbg(&client->adapter->dev, - "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, " - "max=%d, value=%d, raw=0x%02X\n", - __FUNCTION__, i, pattern[i].reg, pattern[i].mask, - pattern[i].min, pattern[i].max, - value, buf); - - return -ENODEV; - } - } - - return 0; -} - -static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return pcf8563_get_datetime(to_i2c_client(dev), tm); -} - -static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return pcf8563_set_datetime(to_i2c_client(dev), tm); -} - -static struct rtc_class_ops pcf8563_rtc_ops = { - .read_time = pcf8563_rtc_read_time, - .set_time = pcf8563_rtc_set_time, -}; - -static int pcf8563_attach(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, pcf8563_probe); -} - -static struct i2c_driver pcf8563_driver = { - .driver = { - .name = "pcf8563", - }, - .id = I2C_DRIVERID_PCF8563, - .attach_adapter = &pcf8563_attach, - .detach_client = &pcf8563_detach, -}; - -static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct rtc_device *rtc; - - int err = 0; - - dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - err = -ENODEV; - goto exit; - } - - if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client->addr = address; - client->driver = &pcf8563_driver; - client->adapter = adapter; - - strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE); - - /* Verify the chip is really an PCF8563 */ - if (kind < 0) { - if (pcf8563_validate_client(client) < 0) { - err = -ENODEV; - goto exit_kfree; - } - } - - /* Inform the i2c layer */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; - - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - - rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev, - &pcf8563_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - goto exit_detach; - } - - i2c_set_clientdata(client, rtc); - - return 0; - -exit_detach: - i2c_detach_client(client); - -exit_kfree: - kfree(client); - -exit: - return err; -} - -static int pcf8563_detach(struct i2c_client *client) -{ - int err; - struct rtc_device *rtc = i2c_get_clientdata(client); - - if (rtc) - rtc_device_unregister(rtc); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(client); - - return 0; -} - -static int __init pcf8563_init(void) -{ - return i2c_add_driver(&pcf8563_driver); -} - -static void __exit pcf8563_exit(void) -{ - i2c_del_driver(&pcf8563_driver); -} - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -module_init(pcf8563_init); -module_exit(pcf8563_exit); diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c deleted file mode 100644 index cef5f5a3b..000000000 --- a/drivers/rtc/rtc-proc.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * RTC subsystem, proc interface - * - * Copyright (C) 2005-06 Tower Technologies - * Author: Alessandro Zummo - * - * based on arch/arm/common/rtctime.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include - -static struct class_device *rtc_dev = NULL; -static DEFINE_MUTEX(rtc_lock); - -static int rtc_proc_show(struct seq_file *seq, void *offset) -{ - int err; - struct class_device *class_dev = seq->private; - struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; - struct rtc_wkalrm alrm; - struct rtc_time tm; - - err = rtc_read_time(class_dev, &tm); - if (err == 0) { - seq_printf(seq, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - } - - err = rtc_read_alarm(class_dev, &alrm); - if (err == 0) { - seq_printf(seq, "alrm_time\t: "); - if ((unsigned int)alrm.time.tm_hour <= 24) - seq_printf(seq, "%02d:", alrm.time.tm_hour); - else - seq_printf(seq, "**:"); - if ((unsigned int)alrm.time.tm_min <= 59) - seq_printf(seq, "%02d:", alrm.time.tm_min); - else - seq_printf(seq, "**:"); - if ((unsigned int)alrm.time.tm_sec <= 59) - seq_printf(seq, "%02d\n", alrm.time.tm_sec); - else - seq_printf(seq, "**\n"); - - seq_printf(seq, "alrm_date\t: "); - if ((unsigned int)alrm.time.tm_year <= 200) - seq_printf(seq, "%04d-", alrm.time.tm_year + 1900); - else - seq_printf(seq, "****-"); - if ((unsigned int)alrm.time.tm_mon <= 11) - seq_printf(seq, "%02d-", alrm.time.tm_mon + 1); - else - seq_printf(seq, "**-"); - if ((unsigned int)alrm.time.tm_mday <= 31) - seq_printf(seq, "%02d\n", alrm.time.tm_mday); - else - seq_printf(seq, "**\n"); - seq_printf(seq, "alrm_wakeup\t: %s\n", - alrm.enabled ? "yes" : "no"); - seq_printf(seq, "alrm_pending\t: %s\n", - alrm.pending ? "yes" : "no"); - } - - seq_printf(seq, "24hr\t\t: yes\n"); - - if (ops->proc) - ops->proc(class_dev->dev, seq); - - return 0; -} - -static int rtc_proc_open(struct inode *inode, struct file *file) -{ - struct class_device *class_dev = PDE(inode)->data; - - if (!try_module_get(THIS_MODULE)) - return -ENODEV; - - return single_open(file, rtc_proc_show, class_dev); -} - -static int rtc_proc_release(struct inode *inode, struct file *file) -{ - int res = single_release(inode, file); - module_put(THIS_MODULE); - return res; -} - -static struct file_operations rtc_proc_fops = { - .open = rtc_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = rtc_proc_release, -}; - -static int rtc_proc_add_device(struct class_device *class_dev, - struct class_interface *class_intf) -{ - mutex_lock(&rtc_lock); - if (rtc_dev == NULL) { - struct proc_dir_entry *ent; - - rtc_dev = class_dev; - - ent = create_proc_entry("driver/rtc", 0, NULL); - if (ent) { - struct rtc_device *rtc = to_rtc_device(class_dev); - - ent->proc_fops = &rtc_proc_fops; - ent->owner = rtc->owner; - ent->data = class_dev; - - dev_info(class_dev->dev, "rtc intf: proc\n"); - } - else - rtc_dev = NULL; - } - mutex_unlock(&rtc_lock); - - return 0; -} - -static void rtc_proc_remove_device(struct class_device *class_dev, - struct class_interface *class_intf) -{ - mutex_lock(&rtc_lock); - if (rtc_dev == class_dev) { - remove_proc_entry("driver/rtc", NULL); - rtc_dev = NULL; - } - mutex_unlock(&rtc_lock); -} - -static struct class_interface rtc_proc_interface = { - .add = &rtc_proc_add_device, - .remove = &rtc_proc_remove_device, -}; - -static int __init rtc_proc_init(void) -{ - return rtc_interface_register(&rtc_proc_interface); -} - -static void __exit rtc_proc_exit(void) -{ - class_interface_unregister(&rtc_proc_interface); -} - -module_init(rtc_proc_init); -module_exit(rtc_proc_exit); - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("RTC class proc interface"); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c deleted file mode 100644 index 7553d7976..000000000 --- a/drivers/rtc/rtc-rs5c372.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * An I2C driver for the Ricoh RS5C372 RTC - * - * Copyright (C) 2005 Pavel Mironchik - * Copyright (C) 2006 Tower Technologies - * - * 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 -#include -#include - -#define DRV_VERSION "0.2" - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD; - -#define RS5C372_REG_SECS 0 -#define RS5C372_REG_MINS 1 -#define RS5C372_REG_HOURS 2 -#define RS5C372_REG_WDAY 3 -#define RS5C372_REG_DAY 4 -#define RS5C372_REG_MONTH 5 -#define RS5C372_REG_YEAR 6 -#define RS5C372_REG_TRIM 7 - -#define RS5C372_TRIM_XSL 0x80 -#define RS5C372_TRIM_MASK 0x7F - -#define RS5C372_REG_BASE 0 - -static int rs5c372_attach(struct i2c_adapter *adapter); -static int rs5c372_detach(struct i2c_client *client); -static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind); - -static struct i2c_driver rs5c372_driver = { - .driver = { - .name = "rs5c372", - }, - .attach_adapter = &rs5c372_attach, - .detach_client = &rs5c372_detach, -}; - -static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) -{ - unsigned char buf[7] = { RS5C372_REG_BASE }; - - /* this implements the 1st reading method, according - * to the datasheet. buf[0] is initialized with - * address ptr and transmission format register. - */ - struct i2c_msg msgs[] = { - { client->addr, 0, 1, buf }, - { client->addr, I2C_M_RD, 7, buf }, - }; - - if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - tm->tm_sec = BCD2BIN(buf[RS5C372_REG_SECS] & 0x7f); - tm->tm_min = BCD2BIN(buf[RS5C372_REG_MINS] & 0x7f); - tm->tm_hour = BCD2BIN(buf[RS5C372_REG_HOURS] & 0x3f); - tm->tm_wday = BCD2BIN(buf[RS5C372_REG_WDAY] & 0x07); - tm->tm_mday = BCD2BIN(buf[RS5C372_REG_DAY] & 0x3f); - - /* tm->tm_mon is zero-based */ - tm->tm_mon = BCD2BIN(buf[RS5C372_REG_MONTH] & 0x1f) - 1; - - /* year is 1900 + tm->tm_year */ - tm->tm_year = BCD2BIN(buf[RS5C372_REG_YEAR]) + 100; - - dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - return 0; -} - -static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) -{ - unsigned char buf[8] = { RS5C372_REG_BASE }; - - dev_dbg(&client->dev, - "%s: secs=%d, mins=%d, hours=%d ", - "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - buf[1] = BIN2BCD(tm->tm_sec); - buf[2] = BIN2BCD(tm->tm_min); - buf[3] = BIN2BCD(tm->tm_hour); - buf[4] = BIN2BCD(tm->tm_wday); - buf[5] = BIN2BCD(tm->tm_mday); - buf[6] = BIN2BCD(tm->tm_mon + 1); - buf[7] = BIN2BCD(tm->tm_year - 100); - - if ((i2c_master_send(client, buf, 8)) != 8) { - dev_err(&client->dev, "%s: write error\n", __FUNCTION__); - return -EIO; - } - - return 0; -} - -static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) -{ - unsigned char buf = RS5C372_REG_TRIM; - - struct i2c_msg msgs[] = { - { client->addr, 0, 1, &buf }, - { client->addr, I2C_M_RD, 1, &buf }, - }; - - if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, trim); - - if (osc) - *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768; - - if (trim) - *trim = buf & RS5C372_TRIM_MASK; - - return 0; -} - -static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return rs5c372_get_datetime(to_i2c_client(dev), tm); -} - -static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return rs5c372_set_datetime(to_i2c_client(dev), tm); -} - -static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) -{ - int err, osc, trim; - - err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim); - if (err == 0) { - seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000); - seq_printf(seq, "trim\t: %d\n", trim); - } - - return 0; -} - -static struct rtc_class_ops rs5c372_rtc_ops = { - .proc = rs5c372_rtc_proc, - .read_time = rs5c372_rtc_read_time, - .set_time = rs5c372_rtc_set_time, -}; - -static ssize_t rs5c372_sysfs_show_trim(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int err, trim; - - err = rs5c372_get_trim(to_i2c_client(dev), NULL, &trim); - if (err) - return err; - - return sprintf(buf, "0x%2x\n", trim); -} -static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL); - -static ssize_t rs5c372_sysfs_show_osc(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int err, osc; - - err = rs5c372_get_trim(to_i2c_client(dev), &osc, NULL); - if (err) - return err; - - return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000); -} -static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL); - -static int rs5c372_attach(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, rs5c372_probe); -} - -static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) -{ - int err = 0; - struct i2c_client *client; - struct rtc_device *rtc; - - dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - err = -ENODEV; - goto exit; - } - - if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* I2C client */ - client->addr = address; - client->driver = &rs5c372_driver; - client->adapter = adapter; - - strlcpy(client->name, rs5c372_driver.driver.name, I2C_NAME_SIZE); - - /* Inform the i2c layer */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; - - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - - rtc = rtc_device_register(rs5c372_driver.driver.name, &client->dev, - &rs5c372_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - goto exit_detach; - } - - i2c_set_clientdata(client, rtc); - - device_create_file(&client->dev, &dev_attr_trim); - device_create_file(&client->dev, &dev_attr_osc); - - return 0; - -exit_detach: - i2c_detach_client(client); - -exit_kfree: - kfree(client); - -exit: - return err; -} - -static int rs5c372_detach(struct i2c_client *client) -{ - int err; - struct rtc_device *rtc = i2c_get_clientdata(client); - - if (rtc) - rtc_device_unregister(rtc); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(client); - - return 0; -} - -static __init int rs5c372_init(void) -{ - return i2c_add_driver(&rs5c372_driver); -} - -static __exit void rs5c372_exit(void) -{ - i2c_del_driver(&rs5c372_driver); -} - -module_init(rs5c372_init); -module_exit(rs5c372_exit); - -MODULE_AUTHOR( - "Pavel Mironchik , " - "Alessandro Zummo "); -MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c deleted file mode 100644 index a997529f8..000000000 --- a/drivers/rtc/rtc-sa1100.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Real Time Clock interface for StrongARM SA1x00 and XScale PXA2xx - * - * Copyright (c) 2000 Nils Faerber - * - * Based on rtc.c by Paul Gortmaker - * - * Original Driver by Nils Faerber - * - * Modifications from: - * CIH - * Nicolas Pitre - * Andrew Christian - * - * Converted to the RTC subsystem and Driver Model - * by Richard Purdie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef CONFIG_ARCH_PXA -#include -#endif - -#define TIMER_FREQ CLOCK_TICK_RATE -#define RTC_DEF_DIVIDER 32768 - 1 -#define RTC_DEF_TRIM 0 - -static unsigned long rtc_freq = 1024; -static struct rtc_time rtc_alarm; -static spinlock_t sa1100_rtc_lock = SPIN_LOCK_UNLOCKED; - -static int rtc_update_alarm(struct rtc_time *alrm) -{ - struct rtc_time alarm_tm, now_tm; - unsigned long now, time; - int ret; - - do { - now = RCNR; - rtc_time_to_tm(now, &now_tm); - rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); - ret = rtc_tm_to_time(&alarm_tm, &time); - if (ret != 0) - break; - - RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); - RTAR = time; - } while (now != RCNR); - - return ret; -} - -static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - struct platform_device *pdev = to_platform_device(dev_id); - struct rtc_device *rtc = platform_get_drvdata(pdev); - unsigned int rtsr; - unsigned long events = 0; - - spin_lock(&sa1100_rtc_lock); - - rtsr = RTSR; - /* clear interrupt sources */ - RTSR = 0; - RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); - - /* clear alarm interrupt if it has occurred */ - if (rtsr & RTSR_AL) - rtsr &= ~RTSR_ALE; - RTSR = rtsr & (RTSR_ALE | RTSR_HZE); - - /* update irq data & counter */ - if (rtsr & RTSR_AL) - events |= RTC_AF | RTC_IRQF; - if (rtsr & RTSR_HZ) - events |= RTC_UF | RTC_IRQF; - - rtc_update_irq(&rtc->class_dev, 1, events); - - if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) - rtc_update_alarm(&rtc_alarm); - - spin_unlock(&sa1100_rtc_lock); - - return IRQ_HANDLED; -} - -static int rtc_timer1_count; - -static irqreturn_t timer1_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - struct platform_device *pdev = to_platform_device(dev_id); - struct rtc_device *rtc = platform_get_drvdata(pdev); - - /* - * If we match for the first time, rtc_timer1_count will be 1. - * Otherwise, we wrapped around (very unlikely but - * still possible) so compute the amount of missed periods. - * The match reg is updated only when the data is actually retrieved - * to avoid unnecessary interrupts. - */ - OSSR = OSSR_M1; /* clear match on timer1 */ - - rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF); - - if (rtc_timer1_count == 1) - rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); - - return IRQ_HANDLED; -} - -static int sa1100_rtc_read_callback(struct device *dev, int data) -{ - if (data & RTC_PF) { - /* interpolate missed periods and set match for the next */ - unsigned long period = TIMER_FREQ/rtc_freq; - unsigned long oscr = OSCR; - unsigned long osmr1 = OSMR1; - unsigned long missed = (oscr - osmr1)/period; - data += missed << 8; - OSSR = OSSR_M1; /* clear match on timer 1 */ - OSMR1 = osmr1 + (missed + 1)*period; - /* Ensure we didn't miss another match in the mean time. - * Here we compare (match - OSCR) 8 instead of 0 -- - * see comment in pxa_timer_interrupt() for explanation. - */ - while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) { - data += 0x100; - OSSR = OSSR_M1; /* clear match on timer 1 */ - OSMR1 = osmr1 + period; - } - } - return data; -} - -static int sa1100_rtc_open(struct device *dev) -{ - int ret; - - ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT, - "rtc 1Hz", dev); - if (ret) { - dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); - goto fail_ui; - } - ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT, - "rtc Alrm", dev); - if (ret) { - dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); - goto fail_ai; - } - ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, - "rtc timer", dev); - if (ret) { - dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); - goto fail_pi; - } - return 0; - - fail_pi: - free_irq(IRQ_RTCAlrm, dev); - fail_ai: - free_irq(IRQ_RTC1Hz, dev); - fail_ui: - return ret; -} - -static void sa1100_rtc_release(struct device *dev) -{ - spin_lock_irq(&sa1100_rtc_lock); - RTSR = 0; - OIER &= ~OIER_E1; - OSSR = OSSR_M1; - spin_unlock_irq(&sa1100_rtc_lock); - - free_irq(IRQ_OST1, dev); - free_irq(IRQ_RTCAlrm, dev); - free_irq(IRQ_RTC1Hz, dev); -} - - -static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - switch(cmd) { - case RTC_AIE_OFF: - spin_lock_irq(&sa1100_rtc_lock); - RTSR &= ~RTSR_ALE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - case RTC_AIE_ON: - spin_lock_irq(&sa1100_rtc_lock); - RTSR |= RTSR_ALE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - case RTC_UIE_OFF: - spin_lock_irq(&sa1100_rtc_lock); - RTSR &= ~RTSR_HZE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - case RTC_UIE_ON: - spin_lock_irq(&sa1100_rtc_lock); - RTSR |= RTSR_HZE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - case RTC_PIE_OFF: - spin_lock_irq(&sa1100_rtc_lock); - OIER &= ~OIER_E1; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - case RTC_PIE_ON: - if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE)) - return -EACCES; - spin_lock_irq(&sa1100_rtc_lock); - OSMR1 = TIMER_FREQ/rtc_freq + OSCR; - OIER |= OIER_E1; - rtc_timer1_count = 1; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - case RTC_IRQP_READ: - return put_user(rtc_freq, (unsigned long *)arg); - case RTC_IRQP_SET: - if (arg < 1 || arg > TIMER_FREQ) - return -EINVAL; - if ((arg > 64) && (!capable(CAP_SYS_RESOURCE))) - return -EACCES; - rtc_freq = arg; - return 0; - } - return -ENOIOCTLCMD; -} - -static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - rtc_time_to_tm(RCNR, tm); - return 0; -} - -static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - unsigned long time; - int ret; - - ret = rtc_tm_to_time(tm, &time); - if (ret == 0) - RCNR = time; - return ret; -} - -static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); - alrm->pending = RTSR & RTSR_AL ? 1 : 0; - return 0; -} - -static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - int ret; - - spin_lock_irq(&sa1100_rtc_lock); - ret = rtc_update_alarm(&alrm->time); - if (ret == 0) { - memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time)); - - if (alrm->enabled) - enable_irq_wake(IRQ_RTCAlrm); - else - disable_irq_wake(IRQ_RTCAlrm); - } - spin_unlock_irq(&sa1100_rtc_lock); - - return ret; -} - -static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) -{ - seq_printf(seq, "trim/divider\t: 0x%08lx\n", RTTR); - seq_printf(seq, "alarm_IRQ\t: %s\n", - (RTSR & RTSR_ALE) ? "yes" : "no" ); - seq_printf(seq, "update_IRQ\t: %s\n", - (RTSR & RTSR_HZE) ? "yes" : "no"); - seq_printf(seq, "periodic_IRQ\t: %s\n", - (OIER & OIER_E1) ? "yes" : "no"); - seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq); - - return 0; -} - -static struct rtc_class_ops sa1100_rtc_ops = { - .open = sa1100_rtc_open, - .read_callback = sa1100_rtc_read_callback, - .release = sa1100_rtc_release, - .ioctl = sa1100_rtc_ioctl, - .read_time = sa1100_rtc_read_time, - .set_time = sa1100_rtc_set_time, - .read_alarm = sa1100_rtc_read_alarm, - .set_alarm = sa1100_rtc_set_alarm, - .proc = sa1100_rtc_proc, -}; - -static int sa1100_rtc_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc; - - /* - * According to the manual we should be able to let RTTR be zero - * and then a default diviser for a 32.768KHz clock is used. - * Apparently this doesn't work, at least for my SA1110 rev 5. - * If the clock divider is uninitialized then reset it to the - * default value to get the 1Hz clock. - */ - if (RTTR == 0) { - RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); - dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); - /* The current RTC value probably doesn't make sense either */ - RCNR = 0; - } - - rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, - THIS_MODULE); - - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - platform_set_drvdata(pdev, rtc); - - return 0; -} - -static int sa1100_rtc_remove(struct platform_device *pdev) -{ - struct rtc_device *rtc = platform_get_drvdata(pdev); - - if (rtc) - rtc_device_unregister(rtc); - - return 0; -} - -static struct platform_driver sa1100_rtc_driver = { - .probe = sa1100_rtc_probe, - .remove = sa1100_rtc_remove, - .driver = { - .name = "sa1100-rtc", - }, -}; - -static int __init sa1100_rtc_init(void) -{ - return platform_driver_register(&sa1100_rtc_driver); -} - -static void __exit sa1100_rtc_exit(void) -{ - platform_driver_unregister(&sa1100_rtc_driver); -} - -module_init(sa1100_rtc_init); -module_exit(sa1100_rtc_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c deleted file mode 100644 index 7c1f3d2e5..000000000 --- a/drivers/rtc/rtc-sysfs.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * RTC subsystem, sysfs interface - * - * Copyright (C) 2005 Tower Technologies - * Author: Alessandro Zummo - * - * 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 -#include - -/* device attributes */ - -static ssize_t rtc_sysfs_show_name(struct class_device *dev, char *buf) -{ - return sprintf(buf, "%s\n", to_rtc_device(dev)->name); -} -static CLASS_DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL); - -static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf) -{ - ssize_t retval; - struct rtc_time tm; - - retval = rtc_read_time(dev, &tm); - if (retval == 0) { - retval = sprintf(buf, "%04d-%02d-%02d\n", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - } - - return retval; -} -static CLASS_DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL); - -static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf) -{ - ssize_t retval; - struct rtc_time tm; - - retval = rtc_read_time(dev, &tm); - if (retval == 0) { - retval = sprintf(buf, "%02d:%02d:%02d\n", - tm.tm_hour, tm.tm_min, tm.tm_sec); - } - - return retval; -} -static CLASS_DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL); - -static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf) -{ - ssize_t retval; - struct rtc_time tm; - - retval = rtc_read_time(dev, &tm); - if (retval == 0) { - unsigned long time; - rtc_tm_to_time(&tm, &time); - retval = sprintf(buf, "%lu\n", time); - } - - return retval; -} -static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL); - -static struct attribute *rtc_attrs[] = { - &class_device_attr_name.attr, - &class_device_attr_date.attr, - &class_device_attr_time.attr, - &class_device_attr_since_epoch.attr, - NULL, -}; - -static struct attribute_group rtc_attr_group = { - .attrs = rtc_attrs, -}; - -static int __devinit rtc_sysfs_add_device(struct class_device *class_dev, - struct class_interface *class_intf) -{ - int err; - - dev_info(class_dev->dev, "rtc intf: sysfs\n"); - - err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group); - if (err) - dev_err(class_dev->dev, - "failed to create sysfs attributes\n"); - - return err; -} - -static void rtc_sysfs_remove_device(struct class_device *class_dev, - struct class_interface *class_intf) -{ - sysfs_remove_group(&class_dev->kobj, &rtc_attr_group); -} - -/* interface registration */ - -static struct class_interface rtc_sysfs_interface = { - .add = &rtc_sysfs_add_device, - .remove = &rtc_sysfs_remove_device, -}; - -static int __init rtc_sysfs_init(void) -{ - return rtc_interface_register(&rtc_sysfs_interface); -} - -static void __exit rtc_sysfs_exit(void) -{ - class_interface_unregister(&rtc_sysfs_interface); -} - -module_init(rtc_sysfs_init); -module_exit(rtc_sysfs_exit); - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("RTC class sysfs interface"); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c deleted file mode 100644 index e1fa5fe79..000000000 --- a/drivers/rtc/rtc-test.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * An RTC test device/driver - * Copyright (C) 2005 Tower Technologies - * Author: Alessandro Zummo - * - * 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 -#include -#include -#include - -static struct platform_device *test0 = NULL, *test1 = NULL; - -static int test_rtc_read_alarm(struct device *dev, - struct rtc_wkalrm *alrm) -{ - return 0; -} - -static int test_rtc_set_alarm(struct device *dev, - struct rtc_wkalrm *alrm) -{ - return 0; -} - -static int test_rtc_read_time(struct device *dev, - struct rtc_time *tm) -{ - rtc_time_to_tm(get_seconds(), tm); - return 0; -} - -static int test_rtc_set_time(struct device *dev, - struct rtc_time *tm) -{ - return 0; -} - -static int test_rtc_set_mmss(struct device *dev, unsigned long secs) -{ - return 0; -} - -static int test_rtc_proc(struct device *dev, struct seq_file *seq) -{ - struct platform_device *plat_dev = to_platform_device(dev); - - seq_printf(seq, "test\t\t: yes\n"); - seq_printf(seq, "id\t\t: %d\n", plat_dev->id); - - return 0; -} - -static int test_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - /* We do support interrupts, they're generated - * using the sysfs interface. - */ - switch (cmd) { - case RTC_PIE_ON: - case RTC_PIE_OFF: - case RTC_UIE_ON: - case RTC_UIE_OFF: - case RTC_AIE_ON: - case RTC_AIE_OFF: - return 0; - - default: - return -ENOIOCTLCMD; - } -} - -static struct rtc_class_ops test_rtc_ops = { - .proc = test_rtc_proc, - .read_time = test_rtc_read_time, - .set_time = test_rtc_set_time, - .read_alarm = test_rtc_read_alarm, - .set_alarm = test_rtc_set_alarm, - .set_mmss = test_rtc_set_mmss, - .ioctl = test_rtc_ioctl, -}; - -static ssize_t test_irq_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", 42); -} -static ssize_t test_irq_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int retval; - struct platform_device *plat_dev = to_platform_device(dev); - struct rtc_device *rtc = platform_get_drvdata(plat_dev); - - retval = count; - if (strncmp(buf, "tick", 4) == 0) - rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF); - else if (strncmp(buf, "alarm", 5) == 0) - rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF); - else if (strncmp(buf, "update", 6) == 0) - rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF); - else - retval = -EINVAL; - - return retval; -} -static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store); - -static int test_probe(struct platform_device *plat_dev) -{ - int err; - struct rtc_device *rtc = rtc_device_register("test", &plat_dev->dev, - &test_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - return err; - } - device_create_file(&plat_dev->dev, &dev_attr_irq); - - platform_set_drvdata(plat_dev, rtc); - - return 0; -} - -static int __devexit test_remove(struct platform_device *plat_dev) -{ - struct rtc_device *rtc = platform_get_drvdata(plat_dev); - - rtc_device_unregister(rtc); - device_remove_file(&plat_dev->dev, &dev_attr_irq); - - return 0; -} - -static struct platform_driver test_drv = { - .probe = test_probe, - .remove = __devexit_p(test_remove), - .driver = { - .name = "rtc-test", - .owner = THIS_MODULE, - }, -}; - -static int __init test_init(void) -{ - int err; - - if ((err = platform_driver_register(&test_drv))) - return err; - - if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) { - err = -ENOMEM; - goto exit_driver_unregister; - } - - if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) { - err = -ENOMEM; - goto exit_free_test0; - } - - if ((err = platform_device_add(test0))) - goto exit_free_test1; - - if ((err = platform_device_add(test1))) - goto exit_device_unregister; - - return 0; - -exit_device_unregister: - platform_device_unregister(test0); - -exit_free_test1: - platform_device_put(test1); - -exit_free_test0: - platform_device_put(test0); - -exit_driver_unregister: - platform_driver_unregister(&test_drv); - return err; -} - -static void __exit test_exit(void) -{ - platform_device_unregister(test0); - platform_device_unregister(test1); - platform_driver_unregister(&test_drv); -} - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("RTC test driver/device"); -MODULE_LICENSE("GPL"); - -module_init(test_init); -module_exit(test_exit); diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c deleted file mode 100644 index 788b6d1f8..000000000 --- a/drivers/rtc/rtc-x1205.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * An i2c driver for the Xicor/Intersil X1205 RTC - * Copyright 2004 Karen Spearel - * Copyright 2005 Alessandro Zummo - * - * please send all reports to: - * Karen Spearel - * Alessandro Zummo - * - * based on a lot of other RTC drivers. - * - * 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 -#include -#include -#include - -#define DRV_VERSION "1.0.7" - -/* Addresses to scan: none. This chip is located at - * 0x6f and uses a two bytes register addressing. - * Two bytes need to be written to read a single register, - * while most other chips just require one and take the second - * one as the data to be written. To prevent corrupting - * unknown chips, the user must explicitely set the probe parameter. - */ - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD; - -/* offsets into CCR area */ - -#define CCR_SEC 0 -#define CCR_MIN 1 -#define CCR_HOUR 2 -#define CCR_MDAY 3 -#define CCR_MONTH 4 -#define CCR_YEAR 5 -#define CCR_WDAY 6 -#define CCR_Y2K 7 - -#define X1205_REG_SR 0x3F /* status register */ -#define X1205_REG_Y2K 0x37 -#define X1205_REG_DW 0x36 -#define X1205_REG_YR 0x35 -#define X1205_REG_MO 0x34 -#define X1205_REG_DT 0x33 -#define X1205_REG_HR 0x32 -#define X1205_REG_MN 0x31 -#define X1205_REG_SC 0x30 -#define X1205_REG_DTR 0x13 -#define X1205_REG_ATR 0x12 -#define X1205_REG_INT 0x11 -#define X1205_REG_0 0x10 -#define X1205_REG_Y2K1 0x0F -#define X1205_REG_DWA1 0x0E -#define X1205_REG_YRA1 0x0D -#define X1205_REG_MOA1 0x0C -#define X1205_REG_DTA1 0x0B -#define X1205_REG_HRA1 0x0A -#define X1205_REG_MNA1 0x09 -#define X1205_REG_SCA1 0x08 -#define X1205_REG_Y2K0 0x07 -#define X1205_REG_DWA0 0x06 -#define X1205_REG_YRA0 0x05 -#define X1205_REG_MOA0 0x04 -#define X1205_REG_DTA0 0x03 -#define X1205_REG_HRA0 0x02 -#define X1205_REG_MNA0 0x01 -#define X1205_REG_SCA0 0x00 - -#define X1205_CCR_BASE 0x30 /* Base address of CCR */ -#define X1205_ALM0_BASE 0x00 /* Base address of ALARM0 */ - -#define X1205_SR_RTCF 0x01 /* Clock failure */ -#define X1205_SR_WEL 0x02 /* Write Enable Latch */ -#define X1205_SR_RWEL 0x04 /* Register Write Enable */ - -#define X1205_DTR_DTR0 0x01 -#define X1205_DTR_DTR1 0x02 -#define X1205_DTR_DTR2 0x04 - -#define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */ - -/* Prototypes */ -static int x1205_attach(struct i2c_adapter *adapter); -static int x1205_detach(struct i2c_client *client); -static int x1205_probe(struct i2c_adapter *adapter, int address, int kind); - -static struct i2c_driver x1205_driver = { - .driver = { - .name = "x1205", - }, - .id = I2C_DRIVERID_X1205, - .attach_adapter = &x1205_attach, - .detach_client = &x1205_detach, -}; - -/* - * In the routines that deal directly with the x1205 hardware, we use - * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch - * Epoch is initialized as 2000. Time is set to UTC. - */ -static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, - unsigned char reg_base) -{ - unsigned char dt_addr[2] = { 0, reg_base }; - - unsigned char buf[8]; - - struct i2c_msg msgs[] = { - { client->addr, 0, 2, dt_addr }, /* setup read ptr */ - { client->addr, I2C_M_RD, 8, buf }, /* read date */ - }; - - /* read date registers */ - if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - dev_dbg(&client->dev, - "%s: raw read data - sec=%02x, min=%02x, hr=%02x, " - "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n", - __FUNCTION__, - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7]); - - tm->tm_sec = BCD2BIN(buf[CCR_SEC]); - tm->tm_min = BCD2BIN(buf[CCR_MIN]); - tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */ - tm->tm_mday = BCD2BIN(buf[CCR_MDAY]); - tm->tm_mon = BCD2BIN(buf[CCR_MONTH]) - 1; /* mon is 0-11 */ - tm->tm_year = BCD2BIN(buf[CCR_YEAR]) - + (BCD2BIN(buf[CCR_Y2K]) * 100) - 1900; - tm->tm_wday = buf[CCR_WDAY]; - - dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - return 0; -} - -static int x1205_get_status(struct i2c_client *client, unsigned char *sr) -{ - static unsigned char sr_addr[2] = { 0, X1205_REG_SR }; - - struct i2c_msg msgs[] = { - { client->addr, 0, 2, sr_addr }, /* setup read ptr */ - { client->addr, I2C_M_RD, 1, sr }, /* read status */ - }; - - /* read status register */ - if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - return 0; -} - -static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, - int datetoo, u8 reg_base) -{ - int i, xfer; - unsigned char buf[8]; - - static const unsigned char wel[3] = { 0, X1205_REG_SR, - X1205_SR_WEL }; - - static const unsigned char rwel[3] = { 0, X1205_REG_SR, - X1205_SR_WEL | X1205_SR_RWEL }; - - static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 }; - - dev_dbg(&client->dev, - "%s: secs=%d, mins=%d, hours=%d\n", - __FUNCTION__, - tm->tm_sec, tm->tm_min, tm->tm_hour); - - buf[CCR_SEC] = BIN2BCD(tm->tm_sec); - buf[CCR_MIN] = BIN2BCD(tm->tm_min); - - /* set hour and 24hr bit */ - buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL; - - /* should we also set the date? */ - if (datetoo) { - dev_dbg(&client->dev, - "%s: mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); - - /* month, 1 - 12 */ - buf[CCR_MONTH] = BIN2BCD(tm->tm_mon + 1); - - /* year, since the rtc epoch*/ - buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100); - buf[CCR_WDAY] = tm->tm_wday & 0x07; - buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100); - } - - /* this sequence is required to unlock the chip */ - if ((xfer = i2c_master_send(client, wel, 3)) != 3) { - dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer); - return -EIO; - } - - if ((xfer = i2c_master_send(client, rwel, 3)) != 3) { - dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer); - return -EIO; - } - - /* write register's data */ - for (i = 0; i < (datetoo ? 8 : 3); i++) { - unsigned char rdata[3] = { 0, reg_base + i, buf[i] }; - - xfer = i2c_master_send(client, rdata, 3); - if (xfer != 3) { - dev_err(&client->dev, - "%s: xfer=%d addr=%02x, data=%02x\n", - __FUNCTION__, - xfer, rdata[1], rdata[2]); - return -EIO; - } - }; - - /* disable further writes */ - if ((xfer = i2c_master_send(client, diswe, 3)) != 3) { - dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer); - return -EIO; - } - - return 0; -} - -static int x1205_fix_osc(struct i2c_client *client) -{ - int err; - struct rtc_time tm; - - tm.tm_hour = tm.tm_min = tm.tm_sec = 0; - - if ((err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE)) < 0) - dev_err(&client->dev, - "unable to restart the oscillator\n"); - - return err; -} - -static int x1205_get_dtrim(struct i2c_client *client, int *trim) -{ - unsigned char dtr; - static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR }; - - struct i2c_msg msgs[] = { - { client->addr, 0, 2, dtr_addr }, /* setup read ptr */ - { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */ - }; - - /* read dtr register */ - if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - dev_dbg(&client->dev, "%s: raw dtr=%x\n", __FUNCTION__, dtr); - - *trim = 0; - - if (dtr & X1205_DTR_DTR0) - *trim += 20; - - if (dtr & X1205_DTR_DTR1) - *trim += 10; - - if (dtr & X1205_DTR_DTR2) - *trim = -*trim; - - return 0; -} - -static int x1205_get_atrim(struct i2c_client *client, int *trim) -{ - s8 atr; - static unsigned char atr_addr[2] = { 0, X1205_REG_ATR }; - - struct i2c_msg msgs[] = { - { client->addr, 0, 2, atr_addr }, /* setup read ptr */ - { client->addr, I2C_M_RD, 1, &atr }, /* read atr */ - }; - - /* read atr register */ - if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); - return -EIO; - } - - dev_dbg(&client->dev, "%s: raw atr=%x\n", __FUNCTION__, atr); - - /* atr is a two's complement value on 6 bits, - * perform sign extension. The formula is - * Catr = (atr * 0.25pF) + 11.00pF. - */ - if (atr & 0x20) - atr |= 0xC0; - - dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr); - - *trim = (atr * 250) + 11000; - - dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim); - - return 0; -} - -struct x1205_limit -{ - unsigned char reg, mask, min, max; -}; - -static int x1205_validate_client(struct i2c_client *client) -{ - int i, xfer; - - /* Probe array. We will read the register at the specified - * address and check if the given bits are zero. - */ - static const unsigned char probe_zero_pattern[] = { - /* register, mask */ - X1205_REG_SR, 0x18, - X1205_REG_DTR, 0xF8, - X1205_REG_ATR, 0xC0, - X1205_REG_INT, 0x18, - X1205_REG_0, 0xFF, - }; - - static const struct x1205_limit probe_limits_pattern[] = { - /* register, mask, min, max */ - { X1205_REG_Y2K, 0xFF, 19, 20 }, - { X1205_REG_DW, 0xFF, 0, 6 }, - { X1205_REG_YR, 0xFF, 0, 99 }, - { X1205_REG_MO, 0xFF, 0, 12 }, - { X1205_REG_DT, 0xFF, 0, 31 }, - { X1205_REG_HR, 0x7F, 0, 23 }, - { X1205_REG_MN, 0xFF, 0, 59 }, - { X1205_REG_SC, 0xFF, 0, 59 }, - { X1205_REG_Y2K1, 0xFF, 19, 20 }, - { X1205_REG_Y2K0, 0xFF, 19, 20 }, - }; - - /* check that registers have bits a 0 where expected */ - for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2) { - unsigned char buf; - - unsigned char addr[2] = { 0, probe_zero_pattern[i] }; - - struct i2c_msg msgs[2] = { - { client->addr, 0, 2, addr }, - { client->addr, I2C_M_RD, 1, &buf }, - }; - - if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { - dev_err(&client->adapter->dev, - "%s: could not read register %x\n", - __FUNCTION__, probe_zero_pattern[i]); - - return -EIO; - } - - if ((buf & probe_zero_pattern[i+1]) != 0) { - dev_err(&client->adapter->dev, - "%s: register=%02x, zero pattern=%d, value=%x\n", - __FUNCTION__, probe_zero_pattern[i], i, buf); - - return -ENODEV; - } - } - - /* check limits (only registers with bcd values) */ - for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++) { - unsigned char reg, value; - - unsigned char addr[2] = { 0, probe_limits_pattern[i].reg }; - - struct i2c_msg msgs[2] = { - { client->addr, 0, 2, addr }, - { client->addr, I2C_M_RD, 1, ® }, - }; - - if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { - dev_err(&client->adapter->dev, - "%s: could not read register %x\n", - __FUNCTION__, probe_limits_pattern[i].reg); - - return -EIO; - } - - value = BCD2BIN(reg & probe_limits_pattern[i].mask); - - if (value > probe_limits_pattern[i].max || - value < probe_limits_pattern[i].min) { - dev_dbg(&client->adapter->dev, - "%s: register=%x, lim pattern=%d, value=%d\n", - __FUNCTION__, probe_limits_pattern[i].reg, - i, value); - - return -ENODEV; - } - } - - return 0; -} - -static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - return x1205_get_datetime(to_i2c_client(dev), - &alrm->time, X1205_ALM0_BASE); -} - -static int x1205_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - return x1205_set_datetime(to_i2c_client(dev), - &alrm->time, 1, X1205_ALM0_BASE); -} - -static int x1205_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return x1205_get_datetime(to_i2c_client(dev), - tm, X1205_CCR_BASE); -} - -static int x1205_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return x1205_set_datetime(to_i2c_client(dev), - tm, 1, X1205_CCR_BASE); -} - -static int x1205_rtc_proc(struct device *dev, struct seq_file *seq) -{ - int err, dtrim, atrim; - - if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0) - seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim); - - if ((err = x1205_get_atrim(to_i2c_client(dev), &atrim)) == 0) - seq_printf(seq, "analog_trim\t: %d.%02d pF\n", - atrim / 1000, atrim % 1000); - return 0; -} - -static struct rtc_class_ops x1205_rtc_ops = { - .proc = x1205_rtc_proc, - .read_time = x1205_rtc_read_time, - .set_time = x1205_rtc_set_time, - .read_alarm = x1205_rtc_read_alarm, - .set_alarm = x1205_rtc_set_alarm, -}; - -static ssize_t x1205_sysfs_show_atrim(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int err, atrim; - - err = x1205_get_atrim(to_i2c_client(dev), &atrim); - if (err) - return err; - - return sprintf(buf, "%d.%02d pF\n", atrim / 1000, atrim % 1000); -} -static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL); - -static ssize_t x1205_sysfs_show_dtrim(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int err, dtrim; - - err = x1205_get_dtrim(to_i2c_client(dev), &dtrim); - if (err) - return err; - - return sprintf(buf, "%d ppm\n", dtrim); -} -static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); - -static int x1205_attach(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, x1205_probe); -} - -static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) -{ - int err = 0; - unsigned char sr; - struct i2c_client *client; - struct rtc_device *rtc; - - dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - err = -ENODEV; - goto exit; - } - - if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* I2C client */ - client->addr = address; - client->driver = &x1205_driver; - client->adapter = adapter; - - strlcpy(client->name, x1205_driver.driver.name, I2C_NAME_SIZE); - - /* Verify the chip is really an X1205 */ - if (kind < 0) { - if (x1205_validate_client(client) < 0) { - err = -ENODEV; - goto exit_kfree; - } - } - - /* Inform the i2c layer */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; - - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - - rtc = rtc_device_register(x1205_driver.driver.name, &client->dev, - &x1205_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - goto exit_detach; - } - - i2c_set_clientdata(client, rtc); - - /* Check for power failures and eventualy enable the osc */ - if ((err = x1205_get_status(client, &sr)) == 0) { - if (sr & X1205_SR_RTCF) { - dev_err(&client->dev, - "power failure detected, " - "please set the clock\n"); - udelay(50); - x1205_fix_osc(client); - } - } - else - dev_err(&client->dev, "couldn't read status\n"); - - device_create_file(&client->dev, &dev_attr_atrim); - device_create_file(&client->dev, &dev_attr_dtrim); - - return 0; - -exit_detach: - i2c_detach_client(client); - -exit_kfree: - kfree(client); - -exit: - return err; -} - -static int x1205_detach(struct i2c_client *client) -{ - int err; - struct rtc_device *rtc = i2c_get_clientdata(client); - - if (rtc) - rtc_device_unregister(rtc); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(client); - - return 0; -} - -static int __init x1205_init(void) -{ - return i2c_add_driver(&x1205_driver); -} - -static void __exit x1205_exit(void) -{ - i2c_del_driver(&x1205_driver); -} - -MODULE_AUTHOR( - "Karen Spearel , " - "Alessandro Zummo "); -MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -module_init(x1205_init); -module_exit(x1205_exit); diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig index 4d36208ff..721787cc5 100644 --- a/drivers/s390/Kconfig +++ b/drivers/s390/Kconfig @@ -183,13 +183,7 @@ config S390_TAPE_34XX tape subsystems and 100% compatibles. It is safe to say "Y" here. -config S390_TAPE_3590 - tristate "Support for 3590 tape hardware" - depends on S390_TAPE - help - Select this option if you want to access IBM 3590 magnetic - tape subsystems and 100% compatibles. - It is safe to say "Y" here. + config VMLOGRDR tristate "Support for the z/VM recording system services (VM only)" diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig index 929d6fff6..6f50cc932 100644 --- a/drivers/s390/block/Kconfig +++ b/drivers/s390/block/Kconfig @@ -49,18 +49,20 @@ config DASD_FBA config DASD_DIAG tristate "Support for DIAG access to Disks" - depends on DASD + depends on DASD && ( 64BIT = 'n' || EXPERIMENTAL) help Select this option if you want to use Diagnose250 command to access Disks under VM. If you are not running under VM or unsure what it is, say "N". -config DASD_EER - bool "Extended error reporting (EER)" +config DASD_CMB + tristate "Compatibility interface for DASD channel measurement blocks" depends on DASD help - This driver provides a character device interface to the - DASD extended error reporting. This is only needed if you want to - use applications written for the EER facility. + This driver provides an additional interface to the channel measurement + facility, which is normally accessed though sysfs, with a set of + ioctl functions specific to the dasd driver. + This is only needed if you want to use applications written for + linux-2.4 dasd channel measurement facility interface. endif diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile index be9f22d52..58c678013 100644 --- a/drivers/s390/block/Makefile +++ b/drivers/s390/block/Makefile @@ -7,13 +7,11 @@ dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o dasd_diag_mod-objs := dasd_diag.o dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \ dasd_genhd.o dasd_erp.o -ifdef CONFIG_DASD_EER -dasd_mod-objs += dasd_eer.o -endif obj-$(CONFIG_DASD) += dasd_mod.o obj-$(CONFIG_DASD_DIAG) += dasd_diag_mod.o obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o obj-$(CONFIG_DASD_FBA) += dasd_fba_mod.o +obj-$(CONFIG_DASD_CMB) += dasd_cmb.o obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o obj-$(CONFIG_DCSSBLK) += dcssblk.o diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index cfb1fff37..33157c84d 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -43,6 +43,7 @@ MODULE_AUTHOR("Holger Smolinski "); MODULE_DESCRIPTION("Linux on S/390 DASD device driver," " Copyright 2000 IBM Corporation"); MODULE_SUPPORTED_DEVICE("dasd"); +MODULE_PARM(dasd, "1-" __MODULE_STRING(256) "s"); MODULE_LICENSE("GPL"); /* @@ -70,9 +71,10 @@ dasd_alloc_device(void) { struct dasd_device *device; - device = kzalloc(sizeof (struct dasd_device), GFP_ATOMIC); + device = kmalloc(sizeof (struct dasd_device), GFP_ATOMIC); if (device == NULL) return ERR_PTR(-ENOMEM); + memset(device, 0, sizeof (struct dasd_device)); /* open_count = 0 means device online but not in use */ atomic_set(&device->open_count, -1); @@ -149,8 +151,6 @@ dasd_state_new_to_known(struct dasd_device *device) static inline void dasd_state_known_to_new(struct dasd_device * device) { - /* Disable extended error reporting for this device. */ - dasd_eer_disable(device); /* Forget the discipline information. */ if (device->discipline) module_put(device->discipline->owner); @@ -314,11 +314,6 @@ dasd_increase_state(struct dasd_device *device) device->target >= DASD_STATE_READY) rc = dasd_state_basic_to_ready(device); - if (!rc && - device->state == DASD_STATE_UNFMT && - device->target > DASD_STATE_UNFMT) - rc = -EPERM; - if (!rc && device->state == DASD_STATE_READY && device->target >= DASD_STATE_ONLINE) @@ -546,29 +541,33 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize, struct dasd_ccw_req *cqr; /* Sanity checks */ - BUG_ON( magic == NULL || datasize > PAGE_SIZE || - (cplength*sizeof(struct ccw1)) > PAGE_SIZE); + if ( magic == NULL || datasize > PAGE_SIZE || + (cplength*sizeof(struct ccw1)) > PAGE_SIZE) + BUG(); - cqr = kzalloc(sizeof(struct dasd_ccw_req), GFP_ATOMIC); + cqr = kmalloc(sizeof(struct dasd_ccw_req), GFP_ATOMIC); if (cqr == NULL) return ERR_PTR(-ENOMEM); + memset(cqr, 0, sizeof(struct dasd_ccw_req)); cqr->cpaddr = NULL; if (cplength > 0) { - cqr->cpaddr = kcalloc(cplength, sizeof(struct ccw1), + cqr->cpaddr = kmalloc(cplength*sizeof(struct ccw1), GFP_ATOMIC | GFP_DMA); if (cqr->cpaddr == NULL) { kfree(cqr); return ERR_PTR(-ENOMEM); } + memset(cqr->cpaddr, 0, cplength*sizeof(struct ccw1)); } cqr->data = NULL; if (datasize > 0) { - cqr->data = kzalloc(datasize, GFP_ATOMIC | GFP_DMA); + cqr->data = kmalloc(datasize, GFP_ATOMIC | GFP_DMA); if (cqr->data == NULL) { kfree(cqr->cpaddr); kfree(cqr); return ERR_PTR(-ENOMEM); } + memset(cqr->data, 0, datasize); } strncpy((char *) &cqr->magic, magic, 4); ASCEBC((char *) &cqr->magic, 4); @@ -587,8 +586,9 @@ dasd_smalloc_request(char *magic, int cplength, int datasize, int size; /* Sanity checks */ - BUG_ON( magic == NULL || datasize > PAGE_SIZE || - (cplength*sizeof(struct ccw1)) > PAGE_SIZE); + if ( magic == NULL || datasize > PAGE_SIZE || + (cplength*sizeof(struct ccw1)) > PAGE_SIZE) + BUG(); size = (sizeof(struct dasd_ccw_req) + 7L) & -8L; if (cplength > 0) @@ -892,9 +892,6 @@ dasd_handle_state_change_pending(struct dasd_device *device) struct dasd_ccw_req *cqr; struct list_head *l, *n; - /* First of all start sense subsystem status request. */ - dasd_eer_snss(device); - device->stopped &= ~DASD_STOPPED_PENDING; /* restart all 'running' IO on queue */ @@ -1114,19 +1111,6 @@ restart: } goto restart; } - - /* First of all call extended error reporting. */ - if (dasd_eer_enabled(device) && - cqr->status == DASD_CQR_FAILED) { - dasd_eer_write(device, cqr, DASD_EER_FATALERROR); - - /* restart request */ - cqr->status = DASD_CQR_QUEUED; - cqr->retries = 255; - device->stopped |= DASD_STOPPED_QUIESCE; - goto restart; - } - /* Process finished ERP request. */ if (cqr->refers) { __dasd_process_erp(device, cqr); @@ -1262,28 +1246,24 @@ __dasd_start_head(struct dasd_device * device) if (list_empty(&device->ccw_queue)) return; cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); - if (cqr->status != DASD_CQR_QUEUED) - return; - /* Non-temporary stop condition will trigger fail fast */ + /* check FAILFAST */ if (device->stopped & ~DASD_STOPPED_PENDING && - test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && - (!dasd_eer_enabled(device))) { + test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) { cqr->status = DASD_CQR_FAILED; dasd_schedule_bh(device); - return; } - /* Don't try to start requests if device is stopped */ - if (device->stopped) - return; - - rc = device->discipline->start_IO(cqr); - if (rc == 0) - dasd_set_timer(device, cqr->expires); - else if (rc == -EACCES) { - dasd_schedule_bh(device); - } else - /* Hmpf, try again in 1/2 sec */ - dasd_set_timer(device, 50); + if ((cqr->status == DASD_CQR_QUEUED) && + (!device->stopped)) { + /* try to start the first I/O that can be started */ + rc = device->discipline->start_IO(cqr); + if (rc == 0) + dasd_set_timer(device, cqr->expires); + else if (rc == -EACCES) { + dasd_schedule_bh(device); + } else + /* Hmpf, try again in 1/2 sec */ + dasd_set_timer(device, 50); + } } /* @@ -1827,7 +1807,7 @@ dasd_exit(void) #ifdef CONFIG_PROC_FS dasd_proc_exit(); #endif - dasd_eer_exit(); + dasd_ioctl_exit(); if (dasd_page_cache != NULL) { kmem_cache_destroy(dasd_page_cache); dasd_page_cache = NULL; @@ -1976,7 +1956,7 @@ int dasd_generic_set_offline (struct ccw_device *cdev) { struct dasd_device *device; - int max_count, open_count; + int max_count; device = dasd_device_from_cdev(cdev); if (IS_ERR(device)) @@ -1993,16 +1973,10 @@ dasd_generic_set_offline (struct ccw_device *cdev) * in the other openers. */ max_count = device->bdev ? 0 : -1; - open_count = (int) atomic_read(&device->open_count); - if (open_count > max_count) { - if (open_count > 0) - printk (KERN_WARNING "Can't offline dasd device with " - "open count = %i.\n", - open_count); - else - printk (KERN_WARNING "%s", - "Can't offline dasd device due to internal " - "use\n"); + if (atomic_read(&device->open_count) > max_count) { + printk (KERN_WARNING "Can't offline dasd device with open" + " count = %i.\n", + atomic_read(&device->open_count)); clear_bit(DASD_FLAG_OFFLINE, &device->flags); dasd_put_device(device); return -EBUSY; @@ -2030,9 +2004,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event) switch (event) { case CIO_GONE: case CIO_NO_PATH: - /* First of all call extended error reporting. */ - dasd_eer_write(device, NULL, DASD_EER_NOPATH); - if (device->state < DASD_STATE_BASIC) break; /* Device is active. We want to keep it. */ @@ -2090,7 +2061,6 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) put_driver(drv); } - static int __init dasd_init(void) { @@ -2123,7 +2093,7 @@ dasd_init(void) rc = dasd_parse(); if (rc) goto failed; - rc = dasd_eer_init(); + rc = dasd_ioctl_init(); if (rc) goto failed; #ifdef CONFIG_PROC_FS diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 2ed515623..4ee0f934e 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -1108,9 +1108,6 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense) case 0x0B: DEV_MESSAGE(KERN_WARNING, device, "%s", "FORMAT F - Volume is suspended duplex"); - /* call extended error reporting (EER) */ - dasd_eer_write(device, erp->refers, - DASD_EER_PPRCSUSPEND); break; case 0x0C: DEV_MESSAGE(KERN_WARNING, device, "%s", diff --git a/drivers/s390/block/dasd_cmb.c b/drivers/s390/block/dasd_cmb.c new file mode 100644 index 000000000..e88f73ee7 --- /dev/null +++ b/drivers/s390/block/dasd_cmb.c @@ -0,0 +1,128 @@ +/* + * Linux on zSeries Channel Measurement Facility support + * (dasd device driver interface) + * + * Copyright 2000,2003 IBM Corporation + * + * Author: Arnd Bergmann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include "dasd_int.h" + +static int +dasd_ioctl_cmf_enable(struct block_device *bdev, int no, long args) +{ + struct dasd_device *device; + + device = bdev->bd_disk->private_data; + if (!device) + return -EINVAL; + + return enable_cmf(device->cdev); +} + +static int +dasd_ioctl_cmf_disable(struct block_device *bdev, int no, long args) +{ + struct dasd_device *device; + + device = bdev->bd_disk->private_data; + if (!device) + return -EINVAL; + + return disable_cmf(device->cdev); +} + +static int +dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args) +{ + struct dasd_device *device; + struct cmbdata __user *udata; + struct cmbdata data; + size_t size; + int ret; + + device = bdev->bd_disk->private_data; + if (!device) + return -EINVAL; + udata = (void __user *) args; + size = _IOC_SIZE(no); + + if (!access_ok(VERIFY_WRITE, udata, size)) + return -EFAULT; + ret = cmf_readall(device->cdev, &data); + if (ret) + return ret; + if (copy_to_user(udata, &data, min(size, sizeof(*udata)))) + return -EFAULT; + return 0; +} + +/* module initialization below here. dasd already provides a mechanism + * to dynamically register ioctl functions, so we simply use this. */ +static inline int +ioctl_reg(unsigned int no, dasd_ioctl_fn_t handler) +{ + return dasd_ioctl_no_register(THIS_MODULE, no, handler); +} + +static inline void +ioctl_unreg(unsigned int no, dasd_ioctl_fn_t handler) +{ + dasd_ioctl_no_unregister(THIS_MODULE, no, handler); +} + +static void +dasd_cmf_exit(void) +{ + ioctl_unreg(BIODASDCMFENABLE, dasd_ioctl_cmf_enable); + ioctl_unreg(BIODASDCMFDISABLE, dasd_ioctl_cmf_disable); + ioctl_unreg(BIODASDREADALLCMB, dasd_ioctl_readall_cmb); +} + +static int __init +dasd_cmf_init(void) +{ + int ret; + ret = ioctl_reg (BIODASDCMFENABLE, dasd_ioctl_cmf_enable); + if (ret) + goto err; + ret = ioctl_reg (BIODASDCMFDISABLE, dasd_ioctl_cmf_disable); + if (ret) + goto err; + ret = ioctl_reg (BIODASDREADALLCMB, dasd_ioctl_readall_cmb); + if (ret) + goto err; + + return 0; +err: + dasd_cmf_exit(); + + return ret; +} + +module_init(dasd_cmf_init); +module_exit(dasd_cmf_exit); + +MODULE_AUTHOR("Arnd Bergmann "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("channel measurement facility interface for dasd\n" + "Copyright 2003 IBM Corporation\n"); diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 216bc4fba..1629b27c4 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -45,7 +44,6 @@ struct dasd_devmap { unsigned int devindex; unsigned short features; struct dasd_device *device; - struct dasd_uid uid; }; /* @@ -71,8 +69,6 @@ int dasd_autodetect = 0; /* is true, when autodetection is active */ * strings when running as a module. */ static char *dasd[256]; -module_param_array(dasd, charp, NULL, 0); - /* * Single spinlock to protect devmap structures and lists. */ @@ -438,7 +434,8 @@ dasd_forget_ranges(void) spin_lock(&dasd_devmap_lock); for (i = 0; i < 256; i++) { list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) { - BUG_ON(devmap->device != NULL); + if (devmap->device != NULL) + BUG(); list_del(&devmap->list); kfree(devmap); } @@ -547,7 +544,8 @@ dasd_delete_device(struct dasd_device *device) /* First remove device pointer from devmap. */ devmap = dasd_find_busid(device->cdev->dev.bus_id); - BUG_ON(IS_ERR(devmap)); + if (IS_ERR(devmap)) + BUG(); spin_lock(&dasd_devmap_lock); if (devmap->device != device) { spin_unlock(&dasd_devmap_lock); @@ -717,116 +715,10 @@ dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *bu static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); -static ssize_t -dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct dasd_devmap *devmap; - int alias; - - devmap = dasd_find_busid(dev->bus_id); - spin_lock(&dasd_devmap_lock); - if (!IS_ERR(devmap)) - alias = devmap->uid.alias; - else - alias = 0; - spin_unlock(&dasd_devmap_lock); - - return sprintf(buf, alias ? "1\n" : "0\n"); -} - -static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL); - -static ssize_t -dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct dasd_devmap *devmap; - char *vendor; - - devmap = dasd_find_busid(dev->bus_id); - spin_lock(&dasd_devmap_lock); - if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0) - vendor = devmap->uid.vendor; - else - vendor = ""; - spin_unlock(&dasd_devmap_lock); - - return snprintf(buf, PAGE_SIZE, "%s\n", vendor); -} - -static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL); - -#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\ - /* SSID */ 4 + 1 + /* unit addr */ 2 + 1) - -static ssize_t -dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct dasd_devmap *devmap; - char uid[UID_STRLEN]; - - devmap = dasd_find_busid(dev->bus_id); - spin_lock(&dasd_devmap_lock); - if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0) - snprintf(uid, sizeof(uid), "%s.%s.%04x.%02x", - devmap->uid.vendor, devmap->uid.serial, - devmap->uid.ssid, devmap->uid.unit_addr); - else - uid[0] = 0; - spin_unlock(&dasd_devmap_lock); - - return snprintf(buf, PAGE_SIZE, "%s\n", uid); -} - -static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); - -/* - * extended error-reporting - */ -static ssize_t -dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct dasd_devmap *devmap; - int eer_flag; - - devmap = dasd_find_busid(dev->bus_id); - if (!IS_ERR(devmap) && devmap->device) - eer_flag = dasd_eer_enabled(devmap->device); - else - eer_flag = 0; - return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n"); -} - -static ssize_t -dasd_eer_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct dasd_devmap *devmap; - int rc; - - devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); - if (IS_ERR(devmap)) - return PTR_ERR(devmap); - if (!devmap->device) - return count; - if (buf[0] == '1') { - rc = dasd_eer_enable(devmap->device); - if (rc) - return rc; - } else - dasd_eer_disable(devmap->device); - return count; -} - -static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store); - static struct attribute * dasd_attrs[] = { &dev_attr_readonly.attr, &dev_attr_discipline.attr, - &dev_attr_alias.attr, - &dev_attr_vendor.attr, - &dev_attr_uid.attr, &dev_attr_use_diag.attr, - &dev_attr_eer_enabled.attr, NULL, }; @@ -834,42 +726,6 @@ static struct attribute_group dasd_attr_group = { .attrs = dasd_attrs, }; - -/* - * Return copy of the device unique identifier. - */ -int -dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid) -{ - struct dasd_devmap *devmap; - - devmap = dasd_find_busid(cdev->dev.bus_id); - if (IS_ERR(devmap)) - return PTR_ERR(devmap); - spin_lock(&dasd_devmap_lock); - *uid = devmap->uid; - spin_unlock(&dasd_devmap_lock); - return 0; -} - -/* - * Register the given device unique identifier into devmap struct. - */ -int -dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) -{ - struct dasd_devmap *devmap; - - devmap = dasd_find_busid(cdev->dev.bus_id); - if (IS_ERR(devmap)) - return PTR_ERR(devmap); - spin_lock(&dasd_devmap_lock); - devmap->uid = *uid; - spin_unlock(&dasd_devmap_lock); - return 0; -} -EXPORT_SYMBOL(dasd_set_uid); - /* * Return value of the specified feature. */ diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 7d5a6cee4..822e2a265 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -446,39 +446,6 @@ dasd_eckd_cdl_reclen(int recid) return LABEL_SIZE; } -/* - * Generate device unique id that specifies the physical device. - */ -static int -dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid) -{ - struct dasd_eckd_private *private; - struct dasd_eckd_confdata *confdata; - - private = (struct dasd_eckd_private *) device->private; - if (!private) - return -ENODEV; - confdata = &private->conf_data; - if (!confdata) - return -ENODEV; - - memset(uid, 0, sizeof(struct dasd_uid)); - strncpy(uid->vendor, confdata->ned1.HDA_manufacturer, - sizeof(uid->vendor) - 1); - EBCASC(uid->vendor, sizeof(uid->vendor) - 1); - strncpy(uid->serial, confdata->ned1.HDA_location, - sizeof(uid->serial) - 1); - EBCASC(uid->serial, sizeof(uid->serial) - 1); - uid->ssid = confdata->neq.subsystemID; - if (confdata->ned2.sneq.flags == 0x40) { - uid->alias = 1; - uid->unit_addr = confdata->ned2.sneq.base_unit_addr; - } else - uid->unit_addr = confdata->ned1.unit_addr; - - return 0; -} - static int dasd_eckd_read_conf(struct dasd_device *device) { @@ -540,15 +507,11 @@ dasd_eckd_read_conf(struct dasd_device *device) return 0; } -/* - * Check device characteristics. - * If the device is accessible using ECKD discipline, the device is enabled. - */ + static int dasd_eckd_check_characteristics(struct dasd_device *device) { struct dasd_eckd_private *private; - struct dasd_uid uid; void *rdc_data; int rc; @@ -573,7 +536,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) /* Read Device Characteristics */ rdc_data = (void *) &(private->rdc_data); - memset(rdc_data, 0, sizeof(rdc_data)); rc = read_dev_chars(device->cdev, &rdc_data, 64); if (rc) { DEV_MESSAGE(KERN_WARNING, device, @@ -594,17 +556,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device) /* Read Configuration Data */ rc = dasd_eckd_read_conf (device); - if (rc) - return rc; - - /* Generate device unique id and register in devmap */ - rc = dasd_eckd_generate_uid(device, &uid); - if (rc) - return rc; - - rc = dasd_set_uid(device->cdev, &uid); - return rc; + } static struct dasd_ccw_req * @@ -1274,14 +1227,19 @@ dasd_eckd_fill_info(struct dasd_device * device, * (see dasd_eckd_reserve) device. */ static int -dasd_eckd_release(struct dasd_device *device) +dasd_eckd_release(struct block_device *bdev, int no, long args) { + struct dasd_device *device; struct dasd_ccw_req *cqr; int rc; if (!capable(CAP_SYS_ADMIN)) return -EACCES; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1, 32, device); if (IS_ERR(cqr)) { @@ -1314,14 +1272,19 @@ dasd_eckd_release(struct dasd_device *device) * the interrupt is outstanding for a certain time. */ static int -dasd_eckd_reserve(struct dasd_device *device) +dasd_eckd_reserve(struct block_device *bdev, int no, long args) { + struct dasd_device *device; struct dasd_ccw_req *cqr; int rc; if (!capable(CAP_SYS_ADMIN)) return -EACCES; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1, 32, device); if (IS_ERR(cqr)) { @@ -1353,14 +1316,19 @@ dasd_eckd_reserve(struct dasd_device *device) * (unconditional reserve) */ static int -dasd_eckd_steal_lock(struct dasd_device *device) +dasd_eckd_steal_lock(struct block_device *bdev, int no, long args) { + struct dasd_device *device; struct dasd_ccw_req *cqr; int rc; if (!capable(CAP_SYS_ADMIN)) return -EACCES; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1, 32, device); if (IS_ERR(cqr)) { @@ -1390,14 +1358,19 @@ dasd_eckd_steal_lock(struct dasd_device *device) * Read performance statistics */ static int -dasd_eckd_performance(struct dasd_device *device, void __user *argp) +dasd_eckd_performance(struct block_device *bdev, int no, long args) { + struct dasd_device *device; struct dasd_psf_prssd_data *prssdp; struct dasd_rssd_perf_stats_t *stats; struct dasd_ccw_req *cqr; struct ccw1 *ccw; int rc; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1 /* PSF */ + 1 /* RSSD */ , (sizeof (struct dasd_psf_prssd_data) + @@ -1441,9 +1414,8 @@ dasd_eckd_performance(struct dasd_device *device, void __user *argp) /* Prepare for Read Subsystem Data */ prssdp = (struct dasd_psf_prssd_data *) cqr->data; stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); - if (copy_to_user(argp, stats, - sizeof(struct dasd_rssd_perf_stats_t))) - rc = -EFAULT; + rc = copy_to_user((long __user *) args, (long *) stats, + sizeof(struct dasd_rssd_perf_stats_t)); } dasd_sfree_request(cqr, cqr->device); return rc; @@ -1454,22 +1426,27 @@ dasd_eckd_performance(struct dasd_device *device, void __user *argp) * Returnes the cache attributes used in Define Extend (DE). */ static int -dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp) +dasd_eckd_get_attrib (struct block_device *bdev, int no, long args) { - struct dasd_eckd_private *private = - (struct dasd_eckd_private *)device->private; - struct attrib_data_t attrib = private->attrib; + struct dasd_device *device; + struct dasd_eckd_private *private; + struct attrib_data_t attrib; int rc; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (!argp) + if (!args) return -EINVAL; - rc = 0; - if (copy_to_user(argp, (long *) &attrib, - sizeof (struct attrib_data_t))) - rc = -EFAULT; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + + private = (struct dasd_eckd_private *) device->private; + attrib = private->attrib; + + rc = copy_to_user((long __user *) args, (long *) &attrib, + sizeof (struct attrib_data_t)); return rc; } @@ -1479,19 +1456,26 @@ dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp) * Stores the attributes for cache operation to be used in Define Extend (DE). */ static int -dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp) +dasd_eckd_set_attrib(struct block_device *bdev, int no, long args) { - struct dasd_eckd_private *private = - (struct dasd_eckd_private *)device->private; + struct dasd_device *device; + struct dasd_eckd_private *private; struct attrib_data_t attrib; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (!argp) + if (!args) return -EINVAL; - if (copy_from_user(&attrib, argp, sizeof(struct attrib_data_t))) + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + + if (copy_from_user(&attrib, (void __user *) args, + sizeof (struct attrib_data_t))) { return -EFAULT; + } + private = (struct dasd_eckd_private *) device->private; private->attrib = attrib; DEV_MESSAGE(KERN_INFO, device, @@ -1500,27 +1484,6 @@ dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp) return 0; } -static int -dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp) -{ - switch (cmd) { - case BIODASDGATTR: - return dasd_eckd_get_attrib(device, argp); - case BIODASDSATTR: - return dasd_eckd_set_attrib(device, argp); - case BIODASDPSRD: - return dasd_eckd_performance(device, argp); - case BIODASDRLSE: - return dasd_eckd_release(device); - case BIODASDRSRV: - return dasd_eckd_reserve(device); - case BIODASDSLCK: - return dasd_eckd_steal_lock(device); - default: - return -ENOIOCTLCMD; - } -} - /* * Print sense data and related channel program. * Parts are printed because printk buffer is only 1024 bytes. @@ -1679,7 +1642,6 @@ static struct dasd_discipline dasd_eckd_discipline = { .free_cp = dasd_eckd_free_cp, .dump_sense = dasd_eckd_dump_sense, .fill_info = dasd_eckd_fill_info, - .ioctl = dasd_eckd_ioctl, }; static int __init @@ -1687,18 +1649,59 @@ dasd_eckd_init(void) { int ret; + dasd_ioctl_no_register(THIS_MODULE, BIODASDGATTR, + dasd_eckd_get_attrib); + dasd_ioctl_no_register(THIS_MODULE, BIODASDSATTR, + dasd_eckd_set_attrib); + dasd_ioctl_no_register(THIS_MODULE, BIODASDPSRD, + dasd_eckd_performance); + dasd_ioctl_no_register(THIS_MODULE, BIODASDRLSE, + dasd_eckd_release); + dasd_ioctl_no_register(THIS_MODULE, BIODASDRSRV, + dasd_eckd_reserve); + dasd_ioctl_no_register(THIS_MODULE, BIODASDSLCK, + dasd_eckd_steal_lock); + ASCEBC(dasd_eckd_discipline.ebcname, 4); ret = ccw_driver_register(&dasd_eckd_driver); - if (!ret) - dasd_generic_auto_online(&dasd_eckd_driver); - return ret; + if (ret) { + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR, + dasd_eckd_get_attrib); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR, + dasd_eckd_set_attrib); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD, + dasd_eckd_performance); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE, + dasd_eckd_release); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV, + dasd_eckd_reserve); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK, + dasd_eckd_steal_lock); + return ret; + } + + dasd_generic_auto_online(&dasd_eckd_driver); + return 0; } static void __exit dasd_eckd_cleanup(void) { ccw_driver_unregister(&dasd_eckd_driver); + + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR, + dasd_eckd_get_attrib); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR, + dasd_eckd_set_attrib); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD, + dasd_eckd_performance); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE, + dasd_eckd_release); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV, + dasd_eckd_reserve); + dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK, + dasd_eckd_steal_lock); } module_init(dasd_eckd_init); diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index d5734e976..bc3823d35 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h @@ -29,7 +29,6 @@ #define DASD_ECKD_CCW_PSF 0x27 #define DASD_ECKD_CCW_RSSD 0x3e #define DASD_ECKD_CCW_LOCATE_RECORD 0x47 -#define DASD_ECKD_CCW_SNSS 0x54 #define DASD_ECKD_CCW_DEFINE_EXTENT 0x63 #define DASD_ECKD_CCW_WRITE_MT 0x85 #define DASD_ECKD_CCW_READ_MT 0x86 @@ -228,36 +227,26 @@ struct dasd_eckd_confdata { unsigned char HDA_manufacturer[3]; unsigned char HDA_location[2]; unsigned char HDA_seqno[12]; - __u8 ID; - __u8 unit_addr; + __u16 ID; } __attribute__ ((packed)) ned1; - union { - struct { - struct { - unsigned char identifier:2; - unsigned char token_id:1; - unsigned char sno_valid:1; - unsigned char subst_sno:1; - unsigned char recNED:1; - unsigned char emuNED:1; - unsigned char reserved:1; - } __attribute__ ((packed)) flags; - __u8 descriptor; - __u8 reserved[2]; - unsigned char dev_type[6]; - unsigned char dev_model[3]; - unsigned char DASD_manufacturer[3]; - unsigned char DASD_location[2]; - unsigned char DASD_seqno[12]; - __u16 ID; - } __attribute__ ((packed)) ned; + struct { struct { - unsigned char flags; /* byte 0 */ - unsigned char res2[7]; /* byte 1- 7 */ - unsigned char sua_flags; /* byte 8 */ - __u8 base_unit_addr; /* byte 9 */ - unsigned char res3[22]; /* byte 10-31 */ - } __attribute__ ((packed)) sneq; + unsigned char identifier:2; + unsigned char token_id:1; + unsigned char sno_valid:1; + unsigned char subst_sno:1; + unsigned char recNED:1; + unsigned char emuNED:1; + unsigned char reserved:1; + } __attribute__ ((packed)) flags; + __u8 descriptor; + __u8 reserved[2]; + unsigned char dev_type[6]; + unsigned char dev_model[3]; + unsigned char DASD_manufacturer[3]; + unsigned char DASD_location[2]; + unsigned char DASD_seqno[12]; + __u16 ID; } __attribute__ ((packed)) ned2; struct { struct { diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c deleted file mode 100644 index 2d946b6ca..000000000 --- a/drivers/s390/block/dasd_eer.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Character device driver for extended error reporting. - * - * Copyright (C) 2005 IBM Corporation - * extended error reporting for DASD ECKD devices - * Author(s): Stefan Weinhuber - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "dasd_int.h" -#include "dasd_eckd.h" - -#ifdef PRINTK_HEADER -#undef PRINTK_HEADER -#endif /* PRINTK_HEADER */ -#define PRINTK_HEADER "dasd(eer):" - -/* - * SECTION: the internal buffer - */ - -/* - * The internal buffer is meant to store obaque blobs of data, so it does - * not know of higher level concepts like triggers. - * It consists of a number of pages that are used as a ringbuffer. Each data - * blob is stored in a simple record that consists of an integer, which - * contains the size of the following data, and the data bytes themselfes. - * - * To allow for multiple independent readers we create one internal buffer - * each time the device is opened and destroy the buffer when the file is - * closed again. The number of pages used for this buffer is determined by - * the module parmeter eer_pages. - * - * One record can be written to a buffer by using the functions - * - dasd_eer_start_record (one time per record to write the size to the - * buffer and reserve the space for the data) - * - dasd_eer_write_buffer (one or more times per record to write the data) - * The data can be written in several steps but you will have to compute - * the total size up front for the invocation of dasd_eer_start_record. - * If the ringbuffer is full, dasd_eer_start_record will remove the required - * number of old records. - * - * A record is typically read in two steps, first read the integer that - * specifies the size of the following data, then read the data. - * Both can be done by - * - dasd_eer_read_buffer - * - * For all mentioned functions you need to get the bufferlock first and keep - * it until a complete record is written or read. - * - * All information necessary to keep track of an internal buffer is kept in - * a struct eerbuffer. The buffer specific to a file pointer is strored in - * the private_data field of that file. To be able to write data to all - * existing buffers, each buffer is also added to the bufferlist. - * If the user does not want to read a complete record in one go, we have to - * keep track of the rest of the record. residual stores the number of bytes - * that are still to deliver. If the rest of the record is invalidated between - * two reads then residual will be set to -1 so that the next read will fail. - * All entries in the eerbuffer structure are protected with the bufferlock. - * To avoid races between writing to a buffer on the one side and creating - * and destroying buffers on the other side, the bufferlock must also be used - * to protect the bufferlist. - */ - -static int eer_pages = 5; -module_param(eer_pages, int, S_IRUGO|S_IWUSR); - -struct eerbuffer { - struct list_head list; - char **buffer; - int buffersize; - int buffer_page_count; - int head; - int tail; - int residual; -}; - -static LIST_HEAD(bufferlist); -static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED; -static DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue); - -/* - * How many free bytes are available on the buffer. - * Needs to be called with bufferlock held. - */ -static int dasd_eer_get_free_bytes(struct eerbuffer *eerb) -{ - if (eerb->head < eerb->tail) - return eerb->tail - eerb->head - 1; - return eerb->buffersize - eerb->head + eerb->tail -1; -} - -/* - * How many bytes of buffer space are used. - * Needs to be called with bufferlock held. - */ -static int dasd_eer_get_filled_bytes(struct eerbuffer *eerb) -{ - - if (eerb->head >= eerb->tail) - return eerb->head - eerb->tail; - return eerb->buffersize - eerb->tail + eerb->head; -} - -/* - * The dasd_eer_write_buffer function just copies count bytes of data - * to the buffer. Make sure to call dasd_eer_start_record first, to - * make sure that enough free space is available. - * Needs to be called with bufferlock held. - */ -static void dasd_eer_write_buffer(struct eerbuffer *eerb, - char *data, int count) -{ - - unsigned long headindex,localhead; - unsigned long rest, len; - char *nextdata; - - nextdata = data; - rest = count; - while (rest > 0) { - headindex = eerb->head / PAGE_SIZE; - localhead = eerb->head % PAGE_SIZE; - len = min(rest, PAGE_SIZE - localhead); - memcpy(eerb->buffer[headindex]+localhead, nextdata, len); - nextdata += len; - rest -= len; - eerb->head += len; - if (eerb->head == eerb->buffersize) - eerb->head = 0; /* wrap around */ - BUG_ON(eerb->head > eerb->buffersize); - } -} - -/* - * Needs to be called with bufferlock held. - */ -static int dasd_eer_read_buffer(struct eerbuffer *eerb, char *data, int count) -{ - - unsigned long tailindex,localtail; - unsigned long rest, len, finalcount; - char *nextdata; - - finalcount = min(count, dasd_eer_get_filled_bytes(eerb)); - nextdata = data; - rest = finalcount; - while (rest > 0) { - tailindex = eerb->tail / PAGE_SIZE; - localtail = eerb->tail % PAGE_SIZE; - len = min(rest, PAGE_SIZE - localtail); - memcpy(nextdata, eerb->buffer[tailindex] + localtail, len); - nextdata += len; - rest -= len; - eerb->tail += len; - if (eerb->tail == eerb->buffersize) - eerb->tail = 0; /* wrap around */ - BUG_ON(eerb->tail > eerb->buffersize); - } - return finalcount; -} - -/* - * Whenever you want to write a blob of data to the internal buffer you - * have to start by using this function first. It will write the number - * of bytes that will be written to the buffer. If necessary it will remove - * old records to make room for the new one. - * Needs to be called with bufferlock held. - */ -static int dasd_eer_start_record(struct eerbuffer *eerb, int count) -{ - int tailcount; - - if (count + sizeof(count) > eerb->buffersize) - return -ENOMEM; - while (dasd_eer_get_free_bytes(eerb) < count + sizeof(count)) { - if (eerb->residual > 0) { - eerb->tail += eerb->residual; - if (eerb->tail >= eerb->buffersize) - eerb->tail -= eerb->buffersize; - eerb->residual = -1; - } - dasd_eer_read_buffer(eerb, (char *) &tailcount, - sizeof(tailcount)); - eerb->tail += tailcount; - if (eerb->tail >= eerb->buffersize) - eerb->tail -= eerb->buffersize; - } - dasd_eer_write_buffer(eerb, (char*) &count, sizeof(count)); - - return 0; -}; - -/* - * Release pages that are not used anymore. - */ -static void dasd_eer_free_buffer_pages(char **buf, int no_pages) -{ - int i; - - for (i = 0; i < no_pages; i++) - free_page((unsigned long) buf[i]); -} - -/* - * Allocate a new set of memory pages. - */ -static int dasd_eer_allocate_buffer_pages(char **buf, int no_pages) -{ - int i; - - for (i = 0; i < no_pages; i++) { - buf[i] = (char *) get_zeroed_page(GFP_KERNEL); - if (!buf[i]) { - dasd_eer_free_buffer_pages(buf, i); - return -ENOMEM; - } - } - return 0; -} - -/* - * SECTION: The extended error reporting functionality - */ - -/* - * When a DASD device driver wants to report an error, it calls the - * function dasd_eer_write and gives the respective trigger ID as - * parameter. Currently there are four kinds of triggers: - * - * DASD_EER_FATALERROR: all kinds of unrecoverable I/O problems - * DASD_EER_PPRCSUSPEND: PPRC was suspended - * DASD_EER_NOPATH: There is no path to the device left. - * DASD_EER_STATECHANGE: The state of the device has changed. - * - * For the first three triggers all required information can be supplied by - * the caller. For these triggers a record is written by the function - * dasd_eer_write_standard_trigger. - * - * The DASD_EER_STATECHANGE trigger is special since a sense subsystem - * status ccw need to be executed to gather the necessary sense data first. - * The dasd_eer_snss function will queue the SNSS request and the request - * callback will then call dasd_eer_write with the DASD_EER_STATCHANGE - * trigger. - * - * To avoid memory allocations at runtime, the necessary memory is allocated - * when the extended error reporting is enabled for a device (by - * dasd_eer_probe). There is one sense subsystem status request for each - * eer enabled DASD device. The presence of the cqr in device->eer_cqr - * indicates that eer is enable for the device. The use of the snss request - * is protected by the DASD_FLAG_EER_IN_USE bit. When this flag indicates - * that the cqr is currently in use, dasd_eer_snss cannot start a second - * request but sets the DASD_FLAG_EER_SNSS flag instead. The callback of - * the SNSS request will check the bit and call dasd_eer_snss again. - */ - -#define SNSS_DATA_SIZE 44 - -#define DASD_EER_BUSID_SIZE 10 -struct dasd_eer_header { - __u32 total_size; - __u32 trigger; - __u64 tv_sec; - __u64 tv_usec; - char busid[DASD_EER_BUSID_SIZE]; -}; - -/* - * The following function can be used for those triggers that have - * all necessary data available when the function is called. - * If the parameter cqr is not NULL, the chain of requests will be searched - * for valid sense data, and all valid sense data sets will be added to - * the triggers data. - */ -static void dasd_eer_write_standard_trigger(struct dasd_device *device, - struct dasd_ccw_req *cqr, - int trigger) -{ - struct dasd_ccw_req *temp_cqr; - int data_size; - struct timeval tv; - struct dasd_eer_header header; - unsigned long flags; - struct eerbuffer *eerb; - - /* go through cqr chain and count the valid sense data sets */ - data_size = 0; - for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) - if (temp_cqr->irb.esw.esw0.erw.cons) - data_size += 32; - - header.total_size = sizeof(header) + data_size + 4; /* "EOR" */ - header.trigger = trigger; - do_gettimeofday(&tv); - header.tv_sec = tv.tv_sec; - header.tv_usec = tv.tv_usec; - strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE); - - spin_lock_irqsave(&bufferlock, flags); - list_for_each_entry(eerb, &bufferlist, list) { - dasd_eer_start_record(eerb, header.total_size); - dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header)); - for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) - if (temp_cqr->irb.esw.esw0.erw.cons) - dasd_eer_write_buffer(eerb, cqr->irb.ecw, 32); - dasd_eer_write_buffer(eerb, "EOR", 4); - } - spin_unlock_irqrestore(&bufferlock, flags); - wake_up_interruptible(&dasd_eer_read_wait_queue); -} - -/* - * This function writes a DASD_EER_STATECHANGE trigger. - */ -static void dasd_eer_write_snss_trigger(struct dasd_device *device, - struct dasd_ccw_req *cqr, - int trigger) -{ - int data_size; - int snss_rc; - struct timeval tv; - struct dasd_eer_header header; - unsigned long flags; - struct eerbuffer *eerb; - - snss_rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; - if (snss_rc) - data_size = 0; - else - data_size = SNSS_DATA_SIZE; - - header.total_size = sizeof(header) + data_size + 4; /* "EOR" */ - header.trigger = DASD_EER_STATECHANGE; - do_gettimeofday(&tv); - header.tv_sec = tv.tv_sec; - header.tv_usec = tv.tv_usec; - strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE); - - spin_lock_irqsave(&bufferlock, flags); - list_for_each_entry(eerb, &bufferlist, list) { - dasd_eer_start_record(eerb, header.total_size); - dasd_eer_write_buffer(eerb, (char *) &header , sizeof(header)); - if (!snss_rc) - dasd_eer_write_buffer(eerb, cqr->data, SNSS_DATA_SIZE); - dasd_eer_write_buffer(eerb, "EOR", 4); - } - spin_unlock_irqrestore(&bufferlock, flags); - wake_up_interruptible(&dasd_eer_read_wait_queue); -} - -/* - * This function is called for all triggers. It calls the appropriate - * function that writes the actual trigger records. - */ -void dasd_eer_write(struct dasd_device *device, struct dasd_ccw_req *cqr, - unsigned int id) -{ - if (!device->eer_cqr) - return; - switch (id) { - case DASD_EER_FATALERROR: - case DASD_EER_PPRCSUSPEND: - dasd_eer_write_standard_trigger(device, cqr, id); - break; - case DASD_EER_NOPATH: - dasd_eer_write_standard_trigger(device, NULL, id); - break; - case DASD_EER_STATECHANGE: - dasd_eer_write_snss_trigger(device, cqr, id); - break; - default: /* unknown trigger, so we write it without any sense data */ - dasd_eer_write_standard_trigger(device, NULL, id); - break; - } -} -EXPORT_SYMBOL(dasd_eer_write); - -/* - * Start a sense subsystem status request. - * Needs to be called with the device held. - */ -void dasd_eer_snss(struct dasd_device *device) -{ - struct dasd_ccw_req *cqr; - - cqr = device->eer_cqr; - if (!cqr) /* Device not eer enabled. */ - return; - if (test_and_set_bit(DASD_FLAG_EER_IN_USE, &device->flags)) { - /* Sense subsystem status request in use. */ - set_bit(DASD_FLAG_EER_SNSS, &device->flags); - return; - } - clear_bit(DASD_FLAG_EER_SNSS, &device->flags); - cqr->status = DASD_CQR_QUEUED; - list_add(&cqr->list, &device->ccw_queue); - dasd_schedule_bh(device); -} - -/* - * Callback function for use with sense subsystem status request. - */ -static void dasd_eer_snss_cb(struct dasd_ccw_req *cqr, void *data) -{ - struct dasd_device *device = cqr->device; - unsigned long flags; - - dasd_eer_write(device, cqr, DASD_EER_STATECHANGE); - spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); - if (device->eer_cqr == cqr) { - clear_bit(DASD_FLAG_EER_IN_USE, &device->flags); - if (test_bit(DASD_FLAG_EER_SNSS, &device->flags)) - /* Another SNSS has been requested in the meantime. */ - dasd_eer_snss(device); - cqr = NULL; - } - spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); - if (cqr) - /* - * Extended error recovery has been switched off while - * the SNSS request was running. It could even have - * been switched off and on again in which case there - * is a new ccw in device->eer_cqr. Free the "old" - * snss request now. - */ - dasd_kfree_request(cqr, device); -} - -/* - * Enable error reporting on a given device. - */ -int dasd_eer_enable(struct dasd_device *device) -{ - struct dasd_ccw_req *cqr; - unsigned long flags; - - if (device->eer_cqr) - return 0; - - if (!device->discipline || strcmp(device->discipline->name, "ECKD")) - return -EPERM; /* FIXME: -EMEDIUMTYPE ? */ - - cqr = dasd_kmalloc_request("ECKD", 1 /* SNSS */, - SNSS_DATA_SIZE, device); - if (!cqr) - return -ENOMEM; - - cqr->device = device; - cqr->retries = 255; - cqr->expires = 10 * HZ; - - cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS; - cqr->cpaddr->count = SNSS_DATA_SIZE; - cqr->cpaddr->flags = 0; - cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; - - cqr->buildclk = get_clock(); - cqr->status = DASD_CQR_FILLED; - cqr->callback = dasd_eer_snss_cb; - - spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); - if (!device->eer_cqr) { - device->eer_cqr = cqr; - cqr = NULL; - } - spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); - if (cqr) - dasd_kfree_request(cqr, device); - return 0; -} - -/* - * Disable error reporting on a given device. - */ -void dasd_eer_disable(struct dasd_device *device) -{ - struct dasd_ccw_req *cqr; - unsigned long flags; - int in_use; - - if (!device->eer_cqr) - return; - spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); - cqr = device->eer_cqr; - device->eer_cqr = NULL; - clear_bit(DASD_FLAG_EER_SNSS, &device->flags); - in_use = test_and_clear_bit(DASD_FLAG_EER_IN_USE, &device->flags); - spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); - if (cqr && !in_use) - dasd_kfree_request(cqr, device); -} - -/* - * SECTION: the device operations - */ - -/* - * On the one side we need a lock to access our internal buffer, on the - * other side a copy_to_user can sleep. So we need to copy the data we have - * to transfer in a readbuffer, which is protected by the readbuffer_mutex. - */ -static char readbuffer[PAGE_SIZE]; -static DECLARE_MUTEX(readbuffer_mutex); - -static int dasd_eer_open(struct inode *inp, struct file *filp) -{ - struct eerbuffer *eerb; - unsigned long flags; - - eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); - eerb->buffer_page_count = eer_pages; - if (eerb->buffer_page_count < 1 || - eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { - kfree(eerb); - MESSAGE(KERN_WARNING, "can't open device since module " - "parameter eer_pages is smaller then 1 or" - " bigger then %d", (int)(INT_MAX / PAGE_SIZE)); - return -EINVAL; - } - eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE; - eerb->buffer = kmalloc(eerb->buffer_page_count * sizeof(char *), - GFP_KERNEL); - if (!eerb->buffer) { - kfree(eerb); - return -ENOMEM; - } - if (dasd_eer_allocate_buffer_pages(eerb->buffer, - eerb->buffer_page_count)) { - kfree(eerb->buffer); - kfree(eerb); - return -ENOMEM; - } - filp->private_data = eerb; - spin_lock_irqsave(&bufferlock, flags); - list_add(&eerb->list, &bufferlist); - spin_unlock_irqrestore(&bufferlock, flags); - - return nonseekable_open(inp,filp); -} - -static int dasd_eer_close(struct inode *inp, struct file *filp) -{ - struct eerbuffer *eerb; - unsigned long flags; - - eerb = (struct eerbuffer *) filp->private_data; - spin_lock_irqsave(&bufferlock, flags); - list_del(&eerb->list); - spin_unlock_irqrestore(&bufferlock, flags); - dasd_eer_free_buffer_pages(eerb->buffer, eerb->buffer_page_count); - kfree(eerb->buffer); - kfree(eerb); - - return 0; -} - -static ssize_t dasd_eer_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int tc,rc; - int tailcount,effective_count; - unsigned long flags; - struct eerbuffer *eerb; - - eerb = (struct eerbuffer *) filp->private_data; - if (down_interruptible(&readbuffer_mutex)) - return -ERESTARTSYS; - - spin_lock_irqsave(&bufferlock, flags); - - if (eerb->residual < 0) { /* the remainder of this record */ - /* has been deleted */ - eerb->residual = 0; - spin_unlock_irqrestore(&bufferlock, flags); - up(&readbuffer_mutex); - return -EIO; - } else if (eerb->residual > 0) { - /* OK we still have a second half of a record to deliver */ - effective_count = min(eerb->residual, (int) count); - eerb->residual -= effective_count; - } else { - tc = 0; - while (!tc) { - tc = dasd_eer_read_buffer(eerb, (char *) &tailcount, - sizeof(tailcount)); - if (!tc) { - /* no data available */ - spin_unlock_irqrestore(&bufferlock, flags); - up(&readbuffer_mutex); - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - rc = wait_event_interruptible( - dasd_eer_read_wait_queue, - eerb->head != eerb->tail); - if (rc) - return rc; - if (down_interruptible(&readbuffer_mutex)) - return -ERESTARTSYS; - spin_lock_irqsave(&bufferlock, flags); - } - } - WARN_ON(tc != sizeof(tailcount)); - effective_count = min(tailcount,(int)count); - eerb->residual = tailcount - effective_count; - } - - tc = dasd_eer_read_buffer(eerb, readbuffer, effective_count); - WARN_ON(tc != effective_count); - - spin_unlock_irqrestore(&bufferlock, flags); - - if (copy_to_user(buf, readbuffer, effective_count)) { - up(&readbuffer_mutex); - return -EFAULT; - } - - up(&readbuffer_mutex); - return effective_count; -} - -static unsigned int dasd_eer_poll(struct file *filp, poll_table *ptable) -{ - unsigned int mask; - unsigned long flags; - struct eerbuffer *eerb; - - eerb = (struct eerbuffer *) filp->private_data; - poll_wait(filp, &dasd_eer_read_wait_queue, ptable); - spin_lock_irqsave(&bufferlock, flags); - if (eerb->head != eerb->tail) - mask = POLLIN | POLLRDNORM ; - else - mask = 0; - spin_unlock_irqrestore(&bufferlock, flags); - return mask; -} - -static struct file_operations dasd_eer_fops = { - .open = &dasd_eer_open, - .release = &dasd_eer_close, - .read = &dasd_eer_read, - .poll = &dasd_eer_poll, - .owner = THIS_MODULE, -}; - -static struct miscdevice dasd_eer_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "dasd_eer", - .fops = &dasd_eer_fops, -}; - -int __init dasd_eer_init(void) -{ - int rc; - - rc = misc_register(&dasd_eer_dev); - if (rc) { - MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not " - "register misc device"); - return rc; - } - - return 0; -} - -void __exit dasd_eer_exit(void) -{ - WARN_ON(misc_deregister(&dasd_eer_dev) != 0); -} diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index b842377cb..8fd71ab02 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c @@ -32,8 +32,9 @@ dasd_alloc_erp_request(char *magic, int cplength, int datasize, int size; /* Sanity checks */ - BUG_ON( magic == NULL || datasize > PAGE_SIZE || - (cplength*sizeof(struct ccw1)) > PAGE_SIZE); + if ( magic == NULL || datasize > PAGE_SIZE || + (cplength*sizeof(struct ccw1)) > PAGE_SIZE) + BUG(); size = (sizeof(struct dasd_ccw_req) + 7L) & -8L; if (cplength > 0) @@ -124,7 +125,8 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr) struct dasd_device *device; int success; - BUG_ON(cqr->refers == NULL || cqr->function == NULL); + if (cqr->refers == NULL || cqr->function == NULL) + BUG(); device = cqr->device; success = cqr->status == DASD_CQR_DONE; diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index d4b13e300..7cb0b9e78 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -69,6 +69,15 @@ */ struct dasd_device; +typedef int (*dasd_ioctl_fn_t) (struct block_device *bdev, int no, long args); + +struct dasd_ioctl { + struct list_head list; + struct module *owner; + int no; + dasd_ioctl_fn_t handler; +}; + typedef enum { dasd_era_fatal = -1, /* no chance to recover */ dasd_era_none = 0, /* don't recover, everything alright */ @@ -263,38 +272,10 @@ struct dasd_discipline { /* i/o control functions. */ int (*fill_geometry) (struct dasd_device *, struct hd_geometry *); int (*fill_info) (struct dasd_device *, struct dasd_information2_t *); - int (*ioctl) (struct dasd_device *, unsigned int, void __user *); }; extern struct dasd_discipline *dasd_diag_discipline_pointer; -/* - * Unique identifier for dasd device. - */ -struct dasd_uid { - __u8 alias; - char vendor[4]; - char serial[15]; - __u16 ssid; - __u8 unit_addr; -}; - -/* - * Notification numbers for extended error reporting notifications: - * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's - * eer pointer) is freed. The error reporting module needs to do all necessary - * cleanup steps. - * The DASD_EER_TRIGGER notification sends the actual error reports (triggers). - */ -#define DASD_EER_DISABLE 0 -#define DASD_EER_TRIGGER 1 - -/* Trigger IDs for extended error reporting DASD_EER_TRIGGER notification */ -#define DASD_EER_FATALERROR 1 -#define DASD_EER_NOPATH 2 -#define DASD_EER_STATECHANGE 3 -#define DASD_EER_PPRCSUSPEND 4 - struct dasd_device { /* Block device stuff. */ struct gendisk *gdp; @@ -308,9 +289,6 @@ struct dasd_device { unsigned long flags; /* per device flags */ unsigned short features; /* copy of devmap-features (read-only!) */ - /* extended error reporting stuff (eer) */ - struct dasd_ccw_req *eer_cqr; - /* Device discipline stuff. */ struct dasd_discipline *discipline; struct dasd_discipline *base_discipline; @@ -356,8 +334,6 @@ struct dasd_device { /* per device flags */ #define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */ #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ -#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ -#define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ void dasd_put_device_wake(struct dasd_device *); @@ -526,8 +502,6 @@ void dasd_devmap_exit(void); struct dasd_device *dasd_create_device(struct ccw_device *); void dasd_delete_device(struct dasd_device *); -int dasd_get_uid(struct ccw_device *, struct dasd_uid *); -int dasd_set_uid(struct ccw_device *, struct dasd_uid *); int dasd_get_feature(struct ccw_device *, int); int dasd_set_feature(struct ccw_device *, int, int); @@ -549,6 +523,10 @@ int dasd_scan_partitions(struct dasd_device *); void dasd_destroy_partitions(struct dasd_device *); /* externals in dasd_ioctl.c */ +int dasd_ioctl_init(void); +void dasd_ioctl_exit(void); +int dasd_ioctl_no_register(struct module *, int, dasd_ioctl_fn_t); +int dasd_ioctl_no_unregister(struct module *, int, dasd_ioctl_fn_t); int dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); long dasd_compat_ioctl(struct file *, unsigned int, unsigned long); @@ -579,30 +557,6 @@ dasd_era_t dasd_9336_erp_examine(struct dasd_ccw_req *, struct irb *); dasd_era_t dasd_9343_erp_examine(struct dasd_ccw_req *, struct irb *); struct dasd_ccw_req *dasd_9343_erp_action(struct dasd_ccw_req *); -/* externals in dasd_eer.c */ -#ifdef CONFIG_DASD_EER -int dasd_eer_init(void); -void dasd_eer_exit(void); -int dasd_eer_enable(struct dasd_device *); -void dasd_eer_disable(struct dasd_device *); -void dasd_eer_write(struct dasd_device *, struct dasd_ccw_req *cqr, - unsigned int id); -void dasd_eer_snss(struct dasd_device *); - -static inline int dasd_eer_enabled(struct dasd_device *device) -{ - return device->eer_cqr != NULL; -} -#else -#define dasd_eer_init() (0) -#define dasd_eer_exit() do { } while (0) -#define dasd_eer_enable(d) (0) -#define dasd_eer_disable(d) do { } while (0) -#define dasd_eer_write(d,c,i) do { } while (0) -#define dasd_eer_snss(d) do { } while (0) -#define dasd_eer_enabled(d) (0) -#endif /* CONFIG_DASD_ERR */ - #endif /* __KERNEL__ */ #endif /* DASD_H */ diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index b8c80d28d..fafeeae52 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -16,7 +16,6 @@ #include #include -#include #include /* This is ugly... */ @@ -24,12 +23,116 @@ #include "dasd_int.h" +/* + * SECTION: ioctl functions. + */ +static struct list_head dasd_ioctl_list = LIST_HEAD_INIT(dasd_ioctl_list); + +/* + * Find the ioctl with number no. + */ +static struct dasd_ioctl * +dasd_find_ioctl(int no) +{ + struct dasd_ioctl *ioctl; + + list_for_each_entry (ioctl, &dasd_ioctl_list, list) + if (ioctl->no == no) + return ioctl; + return NULL; +} + +/* + * Register ioctl with number no. + */ +int +dasd_ioctl_no_register(struct module *owner, int no, dasd_ioctl_fn_t handler) +{ + struct dasd_ioctl *new; + if (dasd_find_ioctl(no)) + return -EBUSY; + new = kmalloc(sizeof (struct dasd_ioctl), GFP_KERNEL); + if (new == NULL) + return -ENOMEM; + new->owner = owner; + new->no = no; + new->handler = handler; + list_add(&new->list, &dasd_ioctl_list); + return 0; +} + +/* + * Deregister ioctl with number no. + */ +int +dasd_ioctl_no_unregister(struct module *owner, int no, dasd_ioctl_fn_t handler) +{ + struct dasd_ioctl *old = dasd_find_ioctl(no); + if (old == NULL) + return -ENOENT; + if (old->no != no || old->handler != handler || owner != old->owner) + return -EINVAL; + list_del(&old->list); + kfree(old); + return 0; +} + +int +dasd_ioctl(struct inode *inp, struct file *filp, + unsigned int no, unsigned long data) +{ + struct block_device *bdev = inp->i_bdev; + struct dasd_device *device = bdev->bd_disk->private_data; + struct dasd_ioctl *ioctl; + const char *dir; + int rc; + + if ((_IOC_DIR(no) != _IOC_NONE) && (data == 0)) { + PRINT_DEBUG("empty data ptr"); + return -EINVAL; + } + dir = _IOC_DIR (no) == _IOC_NONE ? "0" : + _IOC_DIR (no) == _IOC_READ ? "r" : + _IOC_DIR (no) == _IOC_WRITE ? "w" : + _IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u"; + DBF_DEV_EVENT(DBF_DEBUG, device, + "ioctl 0x%08x %s'0x%x'%d(%d) with data %8lx", no, + dir, _IOC_TYPE(no), _IOC_NR(no), _IOC_SIZE(no), data); + /* Search for ioctl no in the ioctl list. */ + list_for_each_entry(ioctl, &dasd_ioctl_list, list) { + if (ioctl->no == no) { + /* Found a matching ioctl. Call it. */ + if (!try_module_get(ioctl->owner)) + continue; + rc = ioctl->handler(bdev, no, data); + module_put(ioctl->owner); + return rc; + } + } + /* No ioctl with number no. */ + DBF_DEV_EVENT(DBF_INFO, device, + "unknown ioctl 0x%08x=%s'0x%x'%d(%d) data %8lx", no, + dir, _IOC_TYPE(no), _IOC_NR(no), _IOC_SIZE(no), data); + return -EINVAL; +} + +long +dasd_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rval; + + lock_kernel(); + rval = dasd_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); + unlock_kernel(); + + return (rval == -EINVAL) ? -ENOIOCTLCMD : rval; +} static int -dasd_ioctl_api_version(void __user *argp) +dasd_ioctl_api_version(struct block_device *bdev, int no, long args) { int ver = DASD_API_VERSION; - return put_user(ver, (int __user *)argp); + return put_user(ver, (int __user *) args); } /* @@ -37,18 +140,20 @@ dasd_ioctl_api_version(void __user *argp) * used by dasdfmt after BIODASDDISABLE to retrigger blocksize detection */ static int -dasd_ioctl_enable(struct block_device *bdev) +dasd_ioctl_enable(struct block_device *bdev, int no, long args) { - struct dasd_device *device = bdev->bd_disk->private_data; + struct dasd_device *device; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; dasd_enable_device(device); /* Formatting the dasd device can change the capacity. */ - mutex_lock(&bdev->bd_mutex); + down(&bdev->bd_sem); i_size_write(bdev->bd_inode, (loff_t)get_capacity(device->gdp) << 9); - mutex_unlock(&bdev->bd_mutex); + up(&bdev->bd_sem); return 0; } @@ -57,13 +162,15 @@ dasd_ioctl_enable(struct block_device *bdev) * Used by dasdfmt. Disable I/O operations but allow ioctls. */ static int -dasd_ioctl_disable(struct block_device *bdev) +dasd_ioctl_disable(struct block_device *bdev, int no, long args) { - struct dasd_device *device = bdev->bd_disk->private_data; + struct dasd_device *device; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; /* * Man this is sick. We don't do a real disable but only downgrade * the device to DASD_STATE_BASIC. The reason is that dasdfmt uses @@ -77,9 +184,9 @@ dasd_ioctl_disable(struct block_device *bdev) * Set i_size to zero, since read, write, etc. check against this * value. */ - mutex_lock(&bdev->bd_mutex); + down(&bdev->bd_sem); i_size_write(bdev->bd_inode, 0); - mutex_unlock(&bdev->bd_mutex); + up(&bdev->bd_sem); return 0; } @@ -87,13 +194,18 @@ dasd_ioctl_disable(struct block_device *bdev) * Quiesce device. */ static int -dasd_ioctl_quiesce(struct dasd_device *device) +dasd_ioctl_quiesce(struct block_device *bdev, int no, long args) { + struct dasd_device *device; unsigned long flags; if (!capable (CAP_SYS_ADMIN)) return -EACCES; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + DEV_MESSAGE (KERN_DEBUG, device, "%s", "Quiesce IO on device"); spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); @@ -107,13 +219,18 @@ dasd_ioctl_quiesce(struct dasd_device *device) * Quiesce device. */ static int -dasd_ioctl_resume(struct dasd_device *device) +dasd_ioctl_resume(struct block_device *bdev, int no, long args) { + struct dasd_device *device; unsigned long flags; if (!capable (CAP_SYS_ADMIN)) return -EACCES; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + DEV_MESSAGE (KERN_DEBUG, device, "%s", "resume IO on device"); @@ -185,19 +302,25 @@ dasd_format(struct dasd_device * device, struct format_data_t * fdata) * Format device. */ static int -dasd_ioctl_format(struct block_device *bdev, void __user *argp) +dasd_ioctl_format(struct block_device *bdev, int no, long args) { - struct dasd_device *device = bdev->bd_disk->private_data; + struct dasd_device *device; struct format_data_t fdata; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (!argp) + if (!args) return -EINVAL; + /* fdata == NULL is no longer a valid arg to dasd_format ! */ + device = bdev->bd_disk->private_data; + + if (device == NULL) + return -ENODEV; if (device->features & DASD_FEATURE_READONLY) return -EROFS; - if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) + if (copy_from_user(&fdata, (void __user *) args, + sizeof (struct format_data_t))) return -EFAULT; if (bdev != bdev->bd_contains) { DEV_MESSAGE(KERN_WARNING, device, "%s", @@ -212,8 +335,17 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp) * Reset device profile information */ static int -dasd_ioctl_reset_profile(struct dasd_device *device) +dasd_ioctl_reset_profile(struct block_device *bdev, int no, long args) { + struct dasd_device *device; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + memset(&device->profile, 0, sizeof (struct dasd_profile_info_t)); return 0; } @@ -222,24 +354,31 @@ dasd_ioctl_reset_profile(struct dasd_device *device) * Return device profile information */ static int -dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) +dasd_ioctl_read_profile(struct block_device *bdev, int no, long args) { + struct dasd_device *device; + + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + if (dasd_profile_level == DASD_PROFILE_OFF) return -EIO; - if (copy_to_user(argp, &device->profile, + + if (copy_to_user((long __user *) args, (long *) &device->profile, sizeof (struct dasd_profile_info_t))) return -EFAULT; return 0; } #else static int -dasd_ioctl_reset_profile(struct dasd_device *device) +dasd_ioctl_reset_profile(struct block_device *bdev, int no, long args) { return -ENOSYS; } static int -dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) +dasd_ioctl_read_profile(struct block_device *bdev, int no, long args) { return -ENOSYS; } @@ -249,18 +388,22 @@ dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) * Return dasd information. Used for BIODASDINFO and BIODASDINFO2. */ static int -dasd_ioctl_information(struct dasd_device *device, - unsigned int cmd, void __user *argp) +dasd_ioctl_information(struct block_device *bdev, int no, long args) { + struct dasd_device *device; struct dasd_information2_t *dasd_info; unsigned long flags; int rc; struct ccw_device *cdev; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + if (!device->discipline->fill_info) return -EINVAL; - dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); + dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); if (dasd_info == NULL) return -ENOMEM; @@ -303,7 +446,8 @@ dasd_ioctl_information(struct dasd_device *device, memcpy(dasd_info->type, device->discipline->name, 4); else memcpy(dasd_info->type, "none", 4); - + dasd_info->req_queue_len = 0; + dasd_info->chanq_len = 0; if (device->request_queue->request_fn) { struct list_head *l; #ifdef DASD_EXTENDED_PROFILING @@ -323,8 +467,8 @@ dasd_ioctl_information(struct dasd_device *device, } rc = 0; - if (copy_to_user(argp, dasd_info, - ((cmd == (unsigned int) BIODASDINFO2) ? + if (copy_to_user((long __user *) args, (long *) dasd_info, + ((no == (unsigned int) BIODASDINFO2) ? sizeof (struct dasd_information2_t) : sizeof (struct dasd_information_t)))) rc = -EFAULT; @@ -336,103 +480,69 @@ dasd_ioctl_information(struct dasd_device *device, * Set read only */ static int -dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) +dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) { - struct dasd_device *device = bdev->bd_disk->private_data; - int intval; + struct dasd_device *device; + int intval, rc; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (bdev != bdev->bd_contains) // ro setting is not allowed for partitions return -EINVAL; - if (get_user(intval, (int *)argp)) + if (get_user(intval, (int __user *) args)) return -EFAULT; + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; set_disk_ro(bdev->bd_disk, intval); - return dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval); + rc = dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval); + + return rc; } -static int -dasd_ioctl_readall_cmb(struct dasd_device *device, unsigned int cmd, - unsigned long arg) +/* + * List of static ioctls. + */ +static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = { - struct cmbdata __user *argp = (void __user *) arg; - size_t size = _IOC_SIZE(cmd); - struct cmbdata data; - int ret; - - ret = cmf_readall(device->cdev, &data); - if (!ret && copy_to_user(argp, &data, min(size, sizeof(*argp)))) - return -EFAULT; - return ret; -} + { BIODASDDISABLE, dasd_ioctl_disable }, + { BIODASDENABLE, dasd_ioctl_enable }, + { BIODASDQUIESCE, dasd_ioctl_quiesce }, + { BIODASDRESUME, dasd_ioctl_resume }, + { BIODASDFMT, dasd_ioctl_format }, + { BIODASDINFO, dasd_ioctl_information }, + { BIODASDINFO2, dasd_ioctl_information }, + { BIODASDPRRD, dasd_ioctl_read_profile }, + { BIODASDPRRST, dasd_ioctl_reset_profile }, + { BLKROSET, dasd_ioctl_set_ro }, + { DASDAPIVER, dasd_ioctl_api_version }, + { -1, NULL } +}; int -dasd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +dasd_ioctl_init(void) { - struct block_device *bdev = inode->i_bdev; - struct dasd_device *device = bdev->bd_disk->private_data; - void __user *argp = (void __user *)arg; + int i; - if (!device) - return -ENODEV; - - if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { - PRINT_DEBUG("empty data ptr"); - return -EINVAL; - } - - switch (cmd) { - case BIODASDDISABLE: - return dasd_ioctl_disable(bdev); - case BIODASDENABLE: - return dasd_ioctl_enable(bdev); - case BIODASDQUIESCE: - return dasd_ioctl_quiesce(device); - case BIODASDRESUME: - return dasd_ioctl_resume(device); - case BIODASDFMT: - return dasd_ioctl_format(bdev, argp); - case BIODASDINFO: - return dasd_ioctl_information(device, cmd, argp); - case BIODASDINFO2: - return dasd_ioctl_information(device, cmd, argp); - case BIODASDPRRD: - return dasd_ioctl_read_profile(device, argp); - case BIODASDPRRST: - return dasd_ioctl_reset_profile(device); - case BLKROSET: - return dasd_ioctl_set_ro(bdev, argp); - case DASDAPIVER: - return dasd_ioctl_api_version(argp); - case BIODASDCMFENABLE: - return enable_cmf(device->cdev); - case BIODASDCMFDISABLE: - return disable_cmf(device->cdev); - case BIODASDREADALLCMB: - return dasd_ioctl_readall_cmb(device, cmd, arg); - default: - /* if the discipline has an ioctl method try it. */ - if (device->discipline->ioctl) { - int rval = device->discipline->ioctl(device, cmd, argp); - if (rval != -ENOIOCTLCMD) - return rval; - } + for (i = 0; dasd_ioctls[i].no != -1; i++) + dasd_ioctl_no_register(NULL, dasd_ioctls[i].no, + dasd_ioctls[i].fn); + return 0; - return -EINVAL; - } } -long -dasd_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +void +dasd_ioctl_exit(void) { - int rval; + int i; - lock_kernel(); - rval = dasd_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); - unlock_kernel(); + for (i = 0; dasd_ioctls[i].no != -1; i++) + dasd_ioctl_no_unregister(NULL, dasd_ioctls[i].no, + dasd_ioctls[i].fn); - return (rval == -EINVAL) ? -ENOIOCTLCMD : rval; } + +EXPORT_SYMBOL(dasd_ioctl_no_register); +EXPORT_SYMBOL(dasd_ioctl_no_unregister); diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index ad23aede3..1aa3c2617 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c @@ -294,40 +294,23 @@ out_error: #endif /* CONFIG_DASD_PROFILE */ } -/* - * Create dasd proc-fs entries. - * In case creation failed, cleanup and return -ENOENT. - */ int dasd_proc_init(void) { dasd_proc_root_entry = proc_mkdir("dasd", &proc_root); - if (!dasd_proc_root_entry) - goto out_nodasd; dasd_proc_root_entry->owner = THIS_MODULE; dasd_devices_entry = create_proc_entry("devices", S_IFREG | S_IRUGO | S_IWUSR, dasd_proc_root_entry); - if (!dasd_devices_entry) - goto out_nodevices; dasd_devices_entry->proc_fops = &dasd_devices_file_ops; dasd_devices_entry->owner = THIS_MODULE; dasd_statistics_entry = create_proc_entry("statistics", S_IFREG | S_IRUGO | S_IWUSR, dasd_proc_root_entry); - if (!dasd_statistics_entry) - goto out_nostatistics; dasd_statistics_entry->read_proc = dasd_statistics_read; dasd_statistics_entry->write_proc = dasd_statistics_write; dasd_statistics_entry->owner = THIS_MODULE; return 0; - - out_nostatistics: - remove_proc_entry("devices", dasd_proc_root_entry); - out_nodevices: - remove_proc_entry("dasd", &proc_root); - out_nodasd: - return -ENOENT; } void diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index be9b05347..2e727f49a 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -273,7 +273,7 @@ removeseg: list_del(&dev_info->lh); del_gendisk(dev_info->gd); - blk_cleanup_queue(dev_info->dcssblk_queue); + blk_put_queue(dev_info->dcssblk_queue); dev_info->gd->queue = NULL; put_disk(dev_info->gd); device_unregister(dev); @@ -388,11 +388,12 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char /* * get a struct dcssblk_dev_info */ - dev_info = kzalloc(sizeof(struct dcssblk_dev_info), GFP_KERNEL); + dev_info = kmalloc(sizeof(struct dcssblk_dev_info), GFP_KERNEL); if (dev_info == NULL) { rc = -ENOMEM; goto out; } + memset(dev_info, 0, sizeof(struct dcssblk_dev_info)); strcpy(dev_info->segment_name, local_buf); strlcpy(dev_info->dev.bus_id, local_buf, BUS_ID_SIZE); @@ -490,7 +491,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char unregister_dev: PRINT_ERR("device_create_file() failed!\n"); list_del(&dev_info->lh); - blk_cleanup_queue(dev_info->dcssblk_queue); + blk_put_queue(dev_info->dcssblk_queue); dev_info->gd->queue = NULL; put_disk(dev_info->gd); device_unregister(&dev_info->dev); @@ -504,7 +505,7 @@ list_del: unload_seg: segment_unload(local_buf); dealloc_gendisk: - blk_cleanup_queue(dev_info->dcssblk_queue); + blk_put_queue(dev_info->dcssblk_queue); dev_info->gd->queue = NULL; put_disk(dev_info->gd); free_dev_info: @@ -561,7 +562,7 @@ dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const ch list_del(&dev_info->lh); del_gendisk(dev_info->gd); - blk_cleanup_queue(dev_info->dcssblk_queue); + blk_put_queue(dev_info->dcssblk_queue); dev_info->gd->queue = NULL; put_disk(dev_info->gd); device_unregister(&dev_info->dev); diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 0c0162ff6..6377a9673 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -26,5 +26,4 @@ tape-$(CONFIG_PROC_FS) += tape_proc.o tape-objs := tape_core.o tape_std.o tape_char.o $(tape-y) obj-$(CONFIG_S390_TAPE) += tape.o tape_class.o obj-$(CONFIG_S390_TAPE_34XX) += tape_34xx.o -obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o obj-$(CONFIG_MONREADER) += monreader.o diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index a6415377b..5f6fa4c67 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -368,9 +368,10 @@ fs3270_alloc_view(void) { struct fs3270 *fp; - fp = kzalloc(sizeof(struct fs3270),GFP_KERNEL); + fp = (struct fs3270 *) kmalloc(sizeof(struct fs3270),GFP_KERNEL); if (!fp) return ERR_PTR(-ENOMEM); + memset(fp, 0, sizeof(struct fs3270)); fp->init = raw3270_request_alloc(0); if (IS_ERR(fp->init)) { kfree(fp); diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index d4d2ff0a9..a317a123d 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -50,12 +50,14 @@ kbd_alloc(void) { struct kbd_data *kbd; int i, len; - kbd = kzalloc(sizeof(struct kbd_data), GFP_KERNEL); + kbd = kmalloc(sizeof(struct kbd_data), GFP_KERNEL); if (!kbd) goto out; - kbd->key_maps = kzalloc(sizeof(key_maps), GFP_KERNEL); - if (!kbd->key_maps) + memset(kbd, 0, sizeof(struct kbd_data)); + kbd->key_maps = kmalloc(sizeof(key_maps), GFP_KERNEL); + if (!key_maps) goto out_kbd; + memset(kbd->key_maps, 0, sizeof(key_maps)); for (i = 0; i < ARRAY_SIZE(key_maps); i++) { if (key_maps[i]) { kbd->key_maps[i] = @@ -66,9 +68,10 @@ kbd_alloc(void) { sizeof(u_short)*NR_KEYS); } } - kbd->func_table = kzalloc(sizeof(func_table), GFP_KERNEL); + kbd->func_table = kmalloc(sizeof(func_table), GFP_KERNEL); if (!kbd->func_table) goto out_maps; + memset(kbd->func_table, 0, sizeof(func_table)); for (i = 0; i < ARRAY_SIZE(func_table); i++) { if (func_table[i]) { len = strlen(func_table[i]) + 1; @@ -79,9 +82,10 @@ kbd_alloc(void) { } } kbd->fn_handler = - kzalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL); + kmalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL); if (!kbd->fn_handler) goto out_func; + memset(kbd->fn_handler, 0, sizeof(fn_handler_fn *) * NR_FN_HANDLER); kbd->accent_table = kmalloc(sizeof(struct kbdiacr)*MAX_DIACR, GFP_KERNEL); if (!kbd->accent_table) diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index fb7bc9e5e..5fd3ad867 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -257,13 +257,14 @@ mon_alloc_mem(void) int i,j; struct mon_private *monpriv; - monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); + monpriv = kmalloc(sizeof(struct mon_private), GFP_KERNEL); if (!monpriv) { P_ERROR("no memory for monpriv\n"); return NULL; } + memset(monpriv, 0, sizeof(struct mon_private)); for (i = 0; i < MON_MSGLIM; i++) { - monpriv->msg_array[i] = kzalloc(sizeof(struct mon_msg), + monpriv->msg_array[i] = kmalloc(sizeof(struct mon_msg), GFP_KERNEL); if (!monpriv->msg_array[i]) { P_ERROR("open, no memory for msg_array\n"); @@ -271,6 +272,7 @@ mon_alloc_mem(void) kfree(monpriv->msg_array[j]); return NULL; } + memset(monpriv->msg_array[i], 0, sizeof(struct mon_msg)); } return monpriv; } diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index eecb2afad..1026f2bc3 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -28,7 +28,6 @@ #include #include #include -#include struct class *class3270; @@ -60,7 +59,7 @@ struct raw3270 { #define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */ /* Semaphore to protect global data of raw3270 (devices, views, etc). */ -static DEFINE_MUTEX(raw3270_mutex); +static DECLARE_MUTEX(raw3270_sem); /* List of 3270 devices. */ static struct list_head raw3270_devices = LIST_HEAD_INIT(raw3270_devices); @@ -116,9 +115,10 @@ raw3270_request_alloc(size_t size) struct raw3270_request *rq; /* Allocate request structure */ - rq = kzalloc(sizeof(struct raw3270_request), GFP_KERNEL | GFP_DMA); + rq = kmalloc(sizeof(struct raw3270_request), GFP_KERNEL | GFP_DMA); if (!rq) return ERR_PTR(-ENOMEM); + memset(rq, 0, sizeof(struct raw3270_request)); /* alloc output buffer. */ if (size > 0) { @@ -816,7 +816,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc) * number for it. Note: there is no device with minor 0, * see special case for fs3270.c:fs3270_open(). */ - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); /* Keep the list sorted. */ minor = RAW3270_FIRSTMINOR; rp->minor = -1; @@ -833,7 +833,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc) rp->minor = minor; list_add_tail(&rp->list, &raw3270_devices); } - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); /* No free minor number? Then give up. */ if (rp->minor == -1) return -EUSERS; @@ -1004,7 +1004,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor) if (minor <= 0) return -ENODEV; - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); rc = -ENODEV; list_for_each_entry(rp, &raw3270_devices, list) { if (rp->minor != minor) @@ -1025,7 +1025,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor) spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); break; } - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); return rc; } @@ -1039,7 +1039,7 @@ raw3270_find_view(struct raw3270_fn *fn, int minor) struct raw3270_view *view, *tmp; unsigned long flags; - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); view = ERR_PTR(-ENODEV); list_for_each_entry(rp, &raw3270_devices, list) { if (rp->minor != minor) @@ -1058,7 +1058,7 @@ raw3270_find_view(struct raw3270_fn *fn, int minor) spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); break; } - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); return view; } @@ -1105,7 +1105,7 @@ raw3270_delete_device(struct raw3270 *rp) struct ccw_device *cdev; /* Remove from device chain. */ - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); if (rp->clttydev) class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor)); @@ -1113,7 +1113,7 @@ raw3270_delete_device(struct raw3270 *rp) class_device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, rp->minor)); list_del_init(&rp->list); - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); /* Disconnect from ccw_device. */ cdev = rp->cdev; @@ -1209,13 +1209,13 @@ int raw3270_register_notifier(void (*notifier)(int, int)) if (!np) return -ENOMEM; np->notifier = notifier; - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); list_add_tail(&np->list, &raw3270_notifier); list_for_each_entry(rp, &raw3270_devices, list) { get_device(&rp->cdev->dev); notifier(rp->minor, 1); } - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); return 0; } @@ -1223,14 +1223,14 @@ void raw3270_unregister_notifier(void (*notifier)(int, int)) { struct raw3270_notifier *np; - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); list_for_each_entry(np, &raw3270_notifier, list) if (np->notifier == notifier) { list_del(&np->list); kfree(np); break; } - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); } /* @@ -1257,10 +1257,10 @@ raw3270_set_online (struct ccw_device *cdev) goto failure; raw3270_create_attributes(rp); set_bit(RAW3270_FLAGS_READY, &rp->flags); - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); list_for_each_entry(np, &raw3270_notifier, list) np->notifier(rp->minor, 1); - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); return 0; failure: @@ -1308,10 +1308,10 @@ raw3270_remove (struct ccw_device *cdev) } spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); list_for_each_entry(np, &raw3270_notifier, list) np->notifier(rp->minor, 0); - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); /* Reset 3270 device. */ raw3270_reset_device(rp); @@ -1371,13 +1371,13 @@ raw3270_init(void) rc = ccw_driver_register(&raw3270_ccw_driver); if (rc == 0) { /* Create attributes for early (= console) device. */ - mutex_lock(&raw3270_mutex); + down(&raw3270_sem); class3270 = class_create(THIS_MODULE, "3270"); list_for_each_entry(rp, &raw3270_devices, list) { get_device(&rp->cdev->dev); raw3270_create_attributes(rp); } - mutex_unlock(&raw3270_mutex); + up(&raw3270_sem); } return rc; } diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c index 91e93c78f..ac10dfb20 100644 --- a/drivers/s390/char/sclp_rw.c +++ b/drivers/s390/char/sclp_rw.c @@ -24,7 +24,7 @@ /* * The room for the SCCB (only for writing) is not equal to a pages size - * (as it is specified as the maximum size in the the SCLP documentation) + * (as it is specified as the maximum size in the the SCLP ducumentation) * because of the additional data structure described above. */ #define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer)) diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index cd51ace8b..01d865d93 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -250,7 +250,6 @@ extern void tape_free_request(struct tape_request *); extern int tape_do_io(struct tape_device *, struct tape_request *); extern int tape_do_io_async(struct tape_device *, struct tape_request *); extern int tape_do_io_interruptible(struct tape_device *, struct tape_request *); -extern int tape_cancel_io(struct tape_device *, struct tape_request *); void tape_hotplug_event(struct tape_device *, int major, int action); static inline int diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index d4f2da738..682039cac 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -2,7 +2,8 @@ * drivers/s390/char/tape_34xx.c * tape device discipline for 3480/3490 tapes. * - * Copyright (C) IBM Corp. 2001,2006 + * S390 and zSeries version + * Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Carsten Otte * Tuan Ngo-Anh * Martin Schwidefsky @@ -27,6 +28,11 @@ debug_info_t *TAPE_DBF_AREA = NULL; EXPORT_SYMBOL(TAPE_DBF_AREA); +enum tape_34xx_type { + tape_3480, + tape_3490, +}; + #define TAPE34XX_FMT_3480 0 #define TAPE34XX_FMT_3480_2_XF 1 #define TAPE34XX_FMT_3480_XF 2 diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c deleted file mode 100644 index d71ef1ade..000000000 --- a/drivers/s390/char/tape_3590.c +++ /dev/null @@ -1,1301 +0,0 @@ -/* - * drivers/s390/char/tape_3590.c - * tape device discipline for 3590 tapes. - * - * Copyright (C) IBM Corp. 2001,2006 - * Author(s): Stefan Bader - * Michael Holzheu - * Martin Schwidefsky - */ - -#include -#include -#include -#include - -#define TAPE_DBF_AREA tape_3590_dbf - -#include "tape.h" -#include "tape_std.h" -#include "tape_3590.h" - -/* - * Pointer to debug area. - */ -debug_info_t *TAPE_DBF_AREA = NULL; -EXPORT_SYMBOL(TAPE_DBF_AREA); - -/******************************************************************* - * Error Recovery fuctions: - * - Read Opposite: implemented - * - Read Device (buffered) log: BRA - * - Read Library log: BRA - * - Swap Devices: BRA - * - Long Busy: BRA - * - Special Intercept: BRA - * - Read Alternate: implemented - *******************************************************************/ - -#define PRINTK_HEADER "TAPE_3590: " - -static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = { - [0x00] = "", - [0x10] = "Lost Sense", - [0x11] = "Assigned Elsewhere", - [0x12] = "Allegiance Reset", - [0x13] = "Shared Access Violation", - [0x20] = "Command Reject", - [0x21] = "Configuration Error", - [0x22] = "Protection Exception", - [0x23] = "Write Protect", - [0x24] = "Write Length", - [0x25] = "Read-Only Format", - [0x31] = "Beginning of Partition", - [0x33] = "End of Partition", - [0x34] = "End of Data", - [0x35] = "Block not found", - [0x40] = "Device Intervention", - [0x41] = "Loader Intervention", - [0x42] = "Library Intervention", - [0x50] = "Write Error", - [0x51] = "Erase Error", - [0x52] = "Formatting Error", - [0x53] = "Read Error", - [0x54] = "Unsupported Format", - [0x55] = "No Formatting", - [0x56] = "Positioning lost", - [0x57] = "Read Length", - [0x60] = "Unsupported Medium", - [0x61] = "Medium Length Error", - [0x62] = "Medium removed", - [0x64] = "Load Check", - [0x65] = "Unload Check", - [0x70] = "Equipment Check", - [0x71] = "Bus out Check", - [0x72] = "Protocol Error", - [0x73] = "Interface Error", - [0x74] = "Overrun", - [0x75] = "Halt Signal", - [0x90] = "Device fenced", - [0x91] = "Device Path fenced", - [0xa0] = "Volume misplaced", - [0xa1] = "Volume inaccessible", - [0xa2] = "Volume in input", - [0xa3] = "Volume ejected", - [0xa4] = "All categories reserved", - [0xa5] = "Duplicate Volume", - [0xa6] = "Library Manager Offline", - [0xa7] = "Library Output Station full", - [0xa8] = "Vision System non-operational", - [0xa9] = "Library Manager Equipment Check", - [0xaa] = "Library Equipment Check", - [0xab] = "All Library Cells full", - [0xac] = "No Cleaner Volumes in Library", - [0xad] = "I/O Station door open", - [0xae] = "Subsystem environmental alert", -}; - -/* - * 3590 IOCTL Overload - */ -static int -tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case TAPE390_DISPLAY: { - struct display_struct disp; - - if (copy_from_user(&disp, (char __user *) arg, sizeof(disp))) - return -EFAULT; - - return tape_std_display(device, &disp); - } - default: - return -EINVAL; /* no additional ioctls */ - } -} - -/* - * SENSE Medium: Get Sense data about medium state - */ -static int -tape_3590_sense_medium(struct tape_device *device) -{ - struct tape_request *request; - - request = tape_alloc_request(1, 128); - if (IS_ERR(request)) - return PTR_ERR(request); - request->op = TO_MSEN; - tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata); - return tape_do_io_free(device, request); -} - -/* - * MTTELL: Tell block. Return the number of block relative to current file. - */ -static int -tape_3590_mttell(struct tape_device *device, int mt_count) -{ - __u64 block_id; - int rc; - - rc = tape_std_read_block_id(device, &block_id); - if (rc) - return rc; - return block_id >> 32; -} - -/* - * MTSEEK: seek to the specified block. - */ -static int -tape_3590_mtseek(struct tape_device *device, int count) -{ - struct tape_request *request; - - DBF_EVENT(6, "xsee id: %x\n", count); - request = tape_alloc_request(3, 4); - if (IS_ERR(request)) - return PTR_ERR(request); - request->op = TO_LBL; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - *(__u32 *) request->cpdata = count; - tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); - tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); - return tape_do_io_free(device, request); -} - -/* - * Read Opposite Error Recovery Function: - * Used, when Read Forward does not work - */ -static void -tape_3590_read_opposite(struct tape_device *device, - struct tape_request *request) -{ - struct tape_3590_disc_data *data; - - /* - * We have allocated 4 ccws in tape_std_read, so we can now - * transform the request to a read backward, followed by a - * forward space block. - */ - request->op = TO_RBA; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - data = device->discdata; - tape_ccw_cc_idal(request->cpaddr + 1, data->read_back_op, - device->char_data.idal_buf); - tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL); - tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL); - DBF_EVENT(6, "xrop ccwg\n"); -} - -/* - * Read Attention Msg - * This should be done after an interrupt with attention bit (0x80) - * in device state. - * - * After a "read attention message" request there are two possible - * results: - * - * 1. A unit check is presented, when attention sense is present (e.g. when - * a medium has been unloaded). The attention sense comes then - * together with the unit check. The recovery action is either "retry" - * (in case there is an attention message pending) or "permanent error". - * - * 2. The attention msg is written to the "read subsystem data" buffer. - * In this case we probably should print it to the console. - */ -static int -tape_3590_read_attmsg(struct tape_device *device) -{ - struct tape_request *request; - char *buf; - - request = tape_alloc_request(3, 4096); - if (IS_ERR(request)) - return PTR_ERR(request); - request->op = TO_READ_ATTMSG; - buf = request->cpdata; - buf[0] = PREP_RD_SS_DATA; - buf[6] = RD_ATTMSG; /* read att msg */ - tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf); - tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12); - tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); - return tape_do_io_free(device, request); -} - -/* - * These functions are used to schedule follow-up actions from within an - * interrupt context (like unsolicited interrupts). - */ -struct work_handler_data { - struct tape_device *device; - enum tape_op op; - struct work_struct work; -}; - -static void -tape_3590_work_handler(void *data) -{ - struct work_handler_data *p = data; - - switch (p->op) { - case TO_MSEN: - tape_3590_sense_medium(p->device); - break; - case TO_READ_ATTMSG: - tape_3590_read_attmsg(p->device); - break; - default: - DBF_EVENT(3, "T3590: work handler undefined for " - "operation 0x%02x\n", p->op); - } - tape_put_device(p->device); - kfree(p); -} - -static int -tape_3590_schedule_work(struct tape_device *device, enum tape_op op) -{ - struct work_handler_data *p; - - if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL) - return -ENOMEM; - - INIT_WORK(&p->work, tape_3590_work_handler, p); - - p->device = tape_get_device_reference(device); - p->op = op; - - schedule_work(&p->work); - return 0; -} - -#ifdef CONFIG_S390_TAPE_BLOCK -/* - * Tape Block READ - */ -static struct tape_request * -tape_3590_bread(struct tape_device *device, struct request *req) -{ - struct tape_request *request; - struct ccw1 *ccw; - int count = 0, start_block, i; - unsigned off; - char *dst; - struct bio_vec *bv; - struct bio *bio; - - DBF_EVENT(6, "xBREDid:"); - start_block = req->sector >> TAPEBLOCK_HSEC_S2B; - DBF_EVENT(6, "start_block = %i\n", start_block); - - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); - } - } - request = tape_alloc_request(2 + count + 1, 4); - if (IS_ERR(request)) - return request; - request->op = TO_BLOCK; - *(__u32 *) request->cpdata = start_block; - ccw = request->cpaddr; - ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte); - - /* - * We always setup a nop after the mode set ccw. This slot is - * used in tape_std_check_locate to insert a locate ccw if the - * current tape position doesn't match the start block to be read. - */ - ccw = tape_ccw_cc(ccw, NOP, 0, NULL); - - rq_for_each_bio(bio, req) { - bio_for_each_segment(bv, bio, i) { - dst = page_address(bv->bv_page) + bv->bv_offset; - for (off = 0; off < bv->bv_len; - off += TAPEBLOCK_HSEC_SIZE) { - ccw->flags = CCW_FLAG_CC; - ccw->cmd_code = READ_FORWARD; - ccw->count = TAPEBLOCK_HSEC_SIZE; - set_normalized_cda(ccw, (void *) __pa(dst)); - ccw++; - dst += TAPEBLOCK_HSEC_SIZE; - } - if (off > bv->bv_len) - BUG(); - } - } - ccw = tape_ccw_end(ccw, NOP, 0, NULL); - DBF_EVENT(6, "xBREDccwg\n"); - return request; -} - -static void -tape_3590_free_bread(struct tape_request *request) -{ - struct ccw1 *ccw; - - /* Last ccw is a nop and doesn't need clear_normalized_cda */ - for (ccw = request->cpaddr; ccw->flags & CCW_FLAG_CC; ccw++) - if (ccw->cmd_code == READ_FORWARD) - clear_normalized_cda(ccw); - tape_free_request(request); -} - -/* - * check_locate is called just before the tape request is passed to - * the common io layer for execution. It has to check the current - * tape position and insert a locate ccw if it doesn't match the - * start block for the request. - */ -static void -tape_3590_check_locate(struct tape_device *device, struct tape_request *request) -{ - __u32 *start_block; - - start_block = (__u32 *) request->cpdata; - if (*start_block != device->blk_data.block_position) { - /* Add the start offset of the file to get the real block. */ - *start_block += device->bof; - tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); - } -} -#endif - -/* - * The done handler is called at device/channel end and wakes up the sleeping - * process - */ -static int -tape_3590_done(struct tape_device *device, struct tape_request *request) -{ - struct tape_3590_med_sense *sense; - - DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]); - - switch (request->op) { - case TO_BSB: - case TO_BSF: - case TO_DSE: - case TO_FSB: - case TO_FSF: - case TO_LBL: - case TO_RFO: - case TO_RBA: - case TO_REW: - case TO_WRI: - case TO_WTM: - case TO_BLOCK: - case TO_LOAD: - tape_med_state_set(device, MS_LOADED); - break; - case TO_RUN: - tape_med_state_set(device, MS_UNLOADED); - break; - case TO_MSEN: - sense = (struct tape_3590_med_sense *) request->cpdata; - if (sense->masst == MSENSE_UNASSOCIATED) - tape_med_state_set(device, MS_UNLOADED); - if (sense->masst == MSENSE_ASSOCIATED_MOUNT) - tape_med_state_set(device, MS_LOADED); - break; - case TO_RBI: /* RBI seems to succeed even without medium loaded. */ - case TO_NOP: /* Same to NOP. */ - case TO_READ_CONFIG: - case TO_READ_ATTMSG: - case TO_DIS: - case TO_ASSIGN: - case TO_UNASSIGN: - break; - case TO_SIZE: - break; - } - return TAPE_IO_SUCCESS; -} - -/* - * This fuction is called, when error recovery was successfull - */ -static inline int -tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request) -{ - DBF_EVENT(3, "Error Recovery successfull for %s\n", - tape_op_verbose[request->op]); - return tape_3590_done(device, request); -} - -/* - * This fuction is called, when error recovery was not successfull - */ -static inline int -tape_3590_erp_failed(struct tape_device *device, struct tape_request *request, - struct irb *irb, int rc) -{ - DBF_EVENT(3, "Error Recovery failed for %s\n", - tape_op_verbose[request->op]); - tape_dump_sense_dbf(device, request, irb); - return rc; -} - -/* - * Error Recovery do retry - */ -static inline int -tape_3590_erp_retry(struct tape_device *device, struct tape_request *request, - struct irb *irb) -{ - DBF_EVENT(2, "Retry: %s\n", tape_op_verbose[request->op]); - tape_dump_sense_dbf(device, request, irb); - return TAPE_IO_RETRY; -} - -/* - * Handle unsolicited interrupts - */ -static int -tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb) -{ - if (irb->scsw.dstat == DEV_STAT_CHN_END) - /* Probably result of halt ssch */ - return TAPE_IO_PENDING; - else if (irb->scsw.dstat == 0x85) - /* Device Ready -> check medium state */ - tape_3590_schedule_work(device, TO_MSEN); - else if (irb->scsw.dstat & DEV_STAT_ATTENTION) - tape_3590_schedule_work(device, TO_READ_ATTMSG); - else { - DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id); - PRINT_WARN("Unsolicited IRQ (Device End) caught.\n"); - tape_dump_sense(device, NULL, irb); - } - return TAPE_IO_SUCCESS; -} - -/* - * Basic Recovery routine - */ -static int -tape_3590_erp_basic(struct tape_device *device, struct tape_request *request, - struct irb *irb, int rc) -{ - struct tape_3590_sense *sense; - - sense = (struct tape_3590_sense *) irb->ecw; - - switch (sense->bra) { - case SENSE_BRA_PER: - return tape_3590_erp_failed(device, request, irb, rc); - case SENSE_BRA_CONT: - return tape_3590_erp_succeded(device, request); - case SENSE_BRA_RE: - return tape_3590_erp_retry(device, request, irb); - case SENSE_BRA_DRE: - return tape_3590_erp_failed(device, request, irb, rc); - default: - PRINT_ERR("Unknown BRA %x - This should not happen!\n", - sense->bra); - BUG(); - return TAPE_IO_STOP; - } -} - -/* - * RDL: Read Device (buffered) log - */ -static int -tape_3590_erp_read_buf_log(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - /* - * We just do the basic error recovery at the moment (retry). - * Perhaps in the future, we read the log and dump it somewhere... - */ - return tape_3590_erp_basic(device, request, irb, -EIO); -} - -/* - * SWAP: Swap Devices - */ -static int -tape_3590_erp_swap(struct tape_device *device, struct tape_request *request, - struct irb *irb) -{ - /* - * This error recovery should swap the tapes - * if the original has a problem. The operation - * should proceed with the new tape... this - * should probably be done in user space! - */ - PRINT_WARN("(%s): Swap Tape Device!\n", device->cdev->dev.bus_id); - return tape_3590_erp_basic(device, request, irb, -EIO); -} - -/* - * LBY: Long Busy - */ -static int -tape_3590_erp_long_busy(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - /* FIXME: how about WAITING for a minute ? */ - PRINT_WARN("(%s): Device is busy! Please wait a minute!\n", - device->cdev->dev.bus_id); - return tape_3590_erp_basic(device, request, irb, -EBUSY); -} - -/* - * SPI: Special Intercept - */ -static int -tape_3590_erp_special_interrupt(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - return tape_3590_erp_basic(device, request, irb, -EIO); -} - -/* - * RDA: Read Alternate - */ -static int -tape_3590_erp_read_alternate(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - struct tape_3590_disc_data *data; - - /* - * The issued Read Backward or Read Previous command is not - * supported by the device - * The recovery action should be to issue another command: - * Read Revious: if Read Backward is not supported - * Read Backward: if Read Previous is not supported - */ - data = device->discdata; - if (data->read_back_op == READ_PREVIOUS) { - DBF_EVENT(2, "(%08x): No support for READ_PREVIOUS command\n", - device->cdev_id); - data->read_back_op = READ_BACKWARD; - } else { - DBF_EVENT(2, "(%08x): No support for READ_BACKWARD command\n", - device->cdev_id); - data->read_back_op = READ_PREVIOUS; - } - tape_3590_read_opposite(device, request); - return tape_3590_erp_retry(device, request, irb); -} - -/* - * Error Recovery read opposite - */ -static int -tape_3590_erp_read_opposite(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - switch (request->op) { - case TO_RFO: - /* - * We did read forward, but the data could not be read. - * We will read backward and then skip forward again. - */ - tape_3590_read_opposite(device, request); - return tape_3590_erp_retry(device, request, irb); - case TO_RBA: - /* We tried to read forward and backward, but hat no success */ - return tape_3590_erp_failed(device, request, irb, -EIO); - break; - default: - PRINT_WARN("read_opposite_recovery_called_with_op: %s\n", - tape_op_verbose[request->op]); - return tape_3590_erp_failed(device, request, irb, -EIO); - } -} - -/* - * Print an MIM (Media Information Message) (message code f0) - */ -static void -tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb) -{ - struct tape_3590_sense *sense; - - sense = (struct tape_3590_sense *) irb->ecw; - /* Exception Message */ - switch (sense->fmt.f70.emc) { - case 0x02: - PRINT_WARN("(%s): Data degraded\n", device->cdev->dev.bus_id); - break; - case 0x03: - PRINT_WARN("(%s): Data degraded in partion %i\n", - device->cdev->dev.bus_id, sense->fmt.f70.mp); - break; - case 0x04: - PRINT_WARN("(%s): Medium degraded\n", device->cdev->dev.bus_id); - break; - case 0x05: - PRINT_WARN("(%s): Medium degraded in partition %i\n", - device->cdev->dev.bus_id, sense->fmt.f70.mp); - break; - case 0x06: - PRINT_WARN("(%s): Block 0 Error\n", device->cdev->dev.bus_id); - break; - case 0x07: - PRINT_WARN("(%s): Medium Exception 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f70.md); - break; - default: - PRINT_WARN("(%s): MIM ExMsg: 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f70.emc); - break; - } - /* Service Message */ - switch (sense->fmt.f70.smc) { - case 0x02: - PRINT_WARN("(%s): Reference Media maintenance procedure %i\n", - device->cdev->dev.bus_id, sense->fmt.f70.md); - break; - default: - PRINT_WARN("(%s): MIM ServiceMsg: 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f70.smc); - break; - } -} - -/* - * Print an I/O Subsystem Service Information Message (message code f1) - */ -static void -tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb) -{ - struct tape_3590_sense *sense; - - sense = (struct tape_3590_sense *) irb->ecw; - /* Exception Message */ - switch (sense->fmt.f71.emc) { - case 0x01: - PRINT_WARN("(%s): Effect of failure is unknown\n", - device->cdev->dev.bus_id); - break; - case 0x02: - PRINT_WARN("(%s): CU Exception - no performance impact\n", - device->cdev->dev.bus_id); - break; - case 0x03: - PRINT_WARN("(%s): CU Exception on channel interface 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.md[0]); - break; - case 0x04: - PRINT_WARN("(%s): CU Exception on device path 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.md[0]); - break; - case 0x05: - PRINT_WARN("(%s): CU Exception on library path 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.md[0]); - break; - case 0x06: - PRINT_WARN("(%s): CU Exception on node 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.md[0]); - break; - case 0x07: - PRINT_WARN("(%s): CU Exception on partition 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.md[0]); - break; - default: - PRINT_WARN("(%s): SIM ExMsg: 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.emc); - } - /* Service Message */ - switch (sense->fmt.f71.smc) { - case 0x01: - PRINT_WARN("(%s): Repair impact is unknown\n", - device->cdev->dev.bus_id); - break; - case 0x02: - PRINT_WARN("(%s): Repair will not impact cu performance\n", - device->cdev->dev.bus_id); - break; - case 0x03: - if (sense->fmt.f71.mdf == 0) - PRINT_WARN("(%s): Repair will disable node " - "0x%x on CU\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1]); - else - PRINT_WARN("(%s): Repair will disable nodes " - "(0x%x-0x%x) on CU\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1], sense->fmt.f71.md[2]); - break; - case 0x04: - if (sense->fmt.f71.mdf == 0) - PRINT_WARN("(%s): Repair will disable cannel path " - "0x%x on CU\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1]); - else - PRINT_WARN("(%s): Repair will disable cannel paths " - "(0x%x-0x%x) on CU\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1], sense->fmt.f71.md[2]); - break; - case 0x05: - if (sense->fmt.f71.mdf == 0) - PRINT_WARN("(%s): Repair will disable device path " - "0x%x on CU\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1]); - else - PRINT_WARN("(%s): Repair will disable device paths " - "(0x%x-0x%x) on CU\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1], sense->fmt.f71.md[2]); - break; - case 0x06: - if (sense->fmt.f71.mdf == 0) - PRINT_WARN("(%s): Repair will disable library path " - "0x%x on CU\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1]); - else - PRINT_WARN("(%s): Repair will disable library paths " - "(0x%x-0x%x) on CU\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1], sense->fmt.f71.md[2]); - break; - case 0x07: - PRINT_WARN("(%s): Repair will disable access to CU\n", - device->cdev->dev.bus_id); - break; - default: - PRINT_WARN("(%s): SIM ServiceMsg: 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.smc); - } -} - -/* - * Print an Device Subsystem Service Information Message (message code f2) - */ -static void -tape_3590_print_dev_sim_msg_f2(struct tape_device *device, struct irb *irb) -{ - struct tape_3590_sense *sense; - - sense = (struct tape_3590_sense *) irb->ecw; - /* Exception Message */ - switch (sense->fmt.f71.emc) { - case 0x01: - PRINT_WARN("(%s): Effect of failure is unknown\n", - device->cdev->dev.bus_id); - break; - case 0x02: - PRINT_WARN("(%s): DV Exception - no performance impact\n", - device->cdev->dev.bus_id); - break; - case 0x03: - PRINT_WARN("(%s): DV Exception on channel interface 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.md[0]); - break; - case 0x04: - PRINT_WARN("(%s): DV Exception on loader 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.md[0]); - break; - case 0x05: - PRINT_WARN("(%s): DV Exception on message display 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.md[0]); - break; - case 0x06: - PRINT_WARN("(%s): DV Exception in tape path\n", - device->cdev->dev.bus_id); - break; - case 0x07: - PRINT_WARN("(%s): DV Exception in drive\n", - device->cdev->dev.bus_id); - break; - default: - PRINT_WARN("(%s): DSIM ExMsg: 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.emc); - } - /* Service Message */ - switch (sense->fmt.f71.smc) { - case 0x01: - PRINT_WARN("(%s): Repair impact is unknown\n", - device->cdev->dev.bus_id); - break; - case 0x02: - PRINT_WARN("(%s): Repair will not impact device performance\n", - device->cdev->dev.bus_id); - break; - case 0x03: - if (sense->fmt.f71.mdf == 0) - PRINT_WARN("(%s): Repair will disable channel path " - "0x%x on DV\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1]); - else - PRINT_WARN("(%s): Repair will disable channel path " - "(0x%x-0x%x) on DV\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1], sense->fmt.f71.md[2]); - break; - case 0x04: - if (sense->fmt.f71.mdf == 0) - PRINT_WARN("(%s): Repair will disable interface 0x%x " - "on DV\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1]); - else - PRINT_WARN("(%s): Repair will disable interfaces " - "(0x%x-0x%x) on DV\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1], sense->fmt.f71.md[2]); - break; - case 0x05: - if (sense->fmt.f71.mdf == 0) - PRINT_WARN("(%s): Repair will disable loader 0x%x " - "on DV\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1]); - else - PRINT_WARN("(%s): Repair will disable loader " - "(0x%x-0x%x) on DV\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1], sense->fmt.f71.md[2]); - break; - case 0x07: - PRINT_WARN("(%s): Repair will disable access to DV\n", - device->cdev->dev.bus_id); - break; - case 0x08: - if (sense->fmt.f71.mdf == 0) - PRINT_WARN("(%s): Repair will disable message " - "display 0x%x on DV\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1]); - else - PRINT_WARN("(%s): Repair will disable message " - "displays (0x%x-0x%x) on DV\n", - device->cdev->dev.bus_id, - sense->fmt.f71.md[1], sense->fmt.f71.md[2]); - break; - case 0x09: - PRINT_WARN("(%s): Clean DV\n", device->cdev->dev.bus_id); - break; - default: - PRINT_WARN("(%s): DSIM ServiceMsg: 0x%02x\n", - device->cdev->dev.bus_id, sense->fmt.f71.smc); - } -} - -/* - * Print standard ERA Message - */ -static void -tape_3590_print_era_msg(struct tape_device *device, struct irb *irb) -{ - struct tape_3590_sense *sense; - - sense = (struct tape_3590_sense *) irb->ecw; - if (sense->mc == 0) - return; - if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) { - if (tape_3590_msg[sense->mc] != NULL) - PRINT_WARN("(%s): %s\n", device->cdev->dev.bus_id, - tape_3590_msg[sense->mc]); - else { - PRINT_WARN("(%s): Message Code 0x%x\n", - device->cdev->dev.bus_id, sense->mc); - } - return; - } - if (sense->mc == 0xf0) { - /* Standard Media Information Message */ - PRINT_WARN("(%s): MIM SEV=%i, MC=%02x, ES=%x/%x, " - "RC=%02x-%04x-%02x\n", device->cdev->dev.bus_id, - sense->fmt.f70.sev, sense->mc, - sense->fmt.f70.emc, sense->fmt.f70.smc, - sense->fmt.f70.refcode, sense->fmt.f70.mid, - sense->fmt.f70.fid); - tape_3590_print_mim_msg_f0(device, irb); - return; - } - if (sense->mc == 0xf1) { - /* Standard I/O Subsystem Service Information Message */ - PRINT_WARN("(%s): IOSIM SEV=%i, DEVTYPE=3590/%02x, " - "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n", - device->cdev->dev.bus_id, sense->fmt.f71.sev, - device->cdev->id.dev_model, - sense->mc, sense->fmt.f71.emc, - sense->fmt.f71.smc, sense->fmt.f71.refcode1, - sense->fmt.f71.refcode2, sense->fmt.f71.refcode3); - tape_3590_print_io_sim_msg_f1(device, irb); - return; - } - if (sense->mc == 0xf2) { - /* Standard Device Service Information Message */ - PRINT_WARN("(%s): DEVSIM SEV=%i, DEVTYPE=3590/%02x, " - "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n", - device->cdev->dev.bus_id, sense->fmt.f71.sev, - device->cdev->id.dev_model, - sense->mc, sense->fmt.f71.emc, - sense->fmt.f71.smc, sense->fmt.f71.refcode1, - sense->fmt.f71.refcode2, sense->fmt.f71.refcode3); - tape_3590_print_dev_sim_msg_f2(device, irb); - return; - } - if (sense->mc == 0xf3) { - /* Standard Library Service Information Message */ - return; - } - PRINT_WARN("(%s): Device Message(%x)\n", - device->cdev->dev.bus_id, sense->mc); -} - -/* - * 3590 error Recovery routine: - * If possible, it tries to recover from the error. If this is not possible, - * inform the user about the problem. - */ -static int -tape_3590_unit_check(struct tape_device *device, struct tape_request *request, - struct irb *irb) -{ - struct tape_3590_sense *sense; - int rc; - -#ifdef CONFIG_S390_TAPE_BLOCK - if (request->op == TO_BLOCK) { - /* - * Recovery for block device requests. Set the block_position - * to something invalid and retry. - */ - device->blk_data.block_position = -1; - if (request->retries-- <= 0) - return tape_3590_erp_failed(device, request, irb, -EIO); - else - return tape_3590_erp_retry(device, request, irb); - } -#endif - - sense = (struct tape_3590_sense *) irb->ecw; - - /* - * First check all RC-QRCs where we want to do something special - * - "break": basic error recovery is done - * - "goto out:": just print error message if available - */ - rc = -EIO; - switch (sense->rc_rqc) { - - case 0x1110: - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_buf_log(device, request, irb); - - case 0x2011: - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_alternate(device, request, irb); - - case 0x2230: - case 0x2231: - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_special_interrupt(device, request, irb); - - case 0x3010: - DBF_EVENT(2, "(%08x): Backward at Beginning of Partition\n", - device->cdev_id); - return tape_3590_erp_basic(device, request, irb, -ENOSPC); - case 0x3012: - DBF_EVENT(2, "(%08x): Forward at End of Partition\n", - device->cdev_id); - return tape_3590_erp_basic(device, request, irb, -ENOSPC); - case 0x3020: - DBF_EVENT(2, "(%08x): End of Data Mark\n", device->cdev_id); - return tape_3590_erp_basic(device, request, irb, -ENOSPC); - - case 0x3122: - DBF_EVENT(2, "(%08x): Rewind Unload initiated\n", - device->cdev_id); - return tape_3590_erp_basic(device, request, irb, -EIO); - case 0x3123: - DBF_EVENT(2, "(%08x): Rewind Unload complete\n", - device->cdev_id); - tape_med_state_set(device, MS_UNLOADED); - return tape_3590_erp_basic(device, request, irb, 0); - - case 0x4010: - /* - * print additional msg since default msg - * "device intervention" is not very meaningfull - */ - PRINT_WARN("(%s): Tape operation when medium not loaded\n", - device->cdev->dev.bus_id); - tape_med_state_set(device, MS_UNLOADED); - return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM); - case 0x4012: /* Device Long Busy */ - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_long_busy(device, request, irb); - - case 0x5010: - if (sense->rac == 0xd0) { - /* Swap */ - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_swap(device, request, irb); - } - if (sense->rac == 0x26) { - /* Read Opposite */ - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_opposite(device, request, - irb); - } - return tape_3590_erp_basic(device, request, irb, -EIO); - case 0x5020: - case 0x5021: - case 0x5022: - case 0x5040: - case 0x5041: - case 0x5042: - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_swap(device, request, irb); - - case 0x5110: - case 0x5111: - return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE); - - case 0x5120: - case 0x1120: - tape_med_state_set(device, MS_UNLOADED); - return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM); - - case 0x6020: - PRINT_WARN("(%s): Cartridge of wrong type ?\n", - device->cdev->dev.bus_id); - return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE); - - case 0x8011: - PRINT_WARN("(%s): Another host has reserved the tape device\n", - device->cdev->dev.bus_id); - return tape_3590_erp_basic(device, request, irb, -EPERM); - case 0x8013: - PRINT_WARN("(%s): Another host has priviliged access to the " - "tape device\n", device->cdev->dev.bus_id); - PRINT_WARN("(%s): To solve the problem unload the current " - "cartridge!\n", device->cdev->dev.bus_id); - return tape_3590_erp_basic(device, request, irb, -EPERM); - default: - return tape_3590_erp_basic(device, request, irb, -EIO); - } -} - -/* - * 3590 interrupt handler: - */ -static int -tape_3590_irq(struct tape_device *device, struct tape_request *request, - struct irb *irb) -{ - if (request == NULL) - return tape_3590_unsolicited_irq(device, irb); - - if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) && - (irb->scsw.dstat & DEV_STAT_DEV_END) && (request->op == TO_WRI)) { - /* Write at end of volume */ - DBF_EVENT(2, "End of volume\n"); - return tape_3590_erp_failed(device, request, irb, -ENOSPC); - } - - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) - return tape_3590_unit_check(device, request, irb); - - if (irb->scsw.dstat & DEV_STAT_DEV_END) { - if (irb->scsw.dstat == DEV_STAT_UNIT_EXCEP) { - if (request->op == TO_FSB || request->op == TO_BSB) - request->rescnt++; - else - DBF_EVENT(5, "Unit Exception!\n"); - } - - return tape_3590_done(device, request); - } - - if (irb->scsw.dstat & DEV_STAT_CHN_END) { - DBF_EVENT(2, "cannel end\n"); - return TAPE_IO_PENDING; - } - - if (irb->scsw.dstat & DEV_STAT_ATTENTION) { - DBF_EVENT(2, "Unit Attention when busy..\n"); - return TAPE_IO_PENDING; - } - - DBF_EVENT(6, "xunknownirq\n"); - PRINT_ERR("Unexpected interrupt.\n"); - PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]); - tape_dump_sense(device, request, irb); - return TAPE_IO_STOP; -} - -/* - * Setup device function - */ -static int -tape_3590_setup_device(struct tape_device *device) -{ - int rc; - struct tape_3590_disc_data *data; - - DBF_EVENT(6, "3590 device setup\n"); - data = kmalloc(sizeof(struct tape_3590_disc_data), - GFP_KERNEL | GFP_DMA); - if (data == NULL) - return -ENOMEM; - data->read_back_op = READ_PREVIOUS; - device->discdata = data; - - if ((rc = tape_std_assign(device)) == 0) { - /* Try to find out if medium is loaded */ - if ((rc = tape_3590_sense_medium(device)) != 0) - DBF_LH(3, "3590 medium sense returned %d\n", rc); - } - - return rc; -} - -/* - * Cleanup device function - */ -static void -tape_3590_cleanup_device(struct tape_device *device) -{ - flush_scheduled_work(); - tape_std_unassign(device); - - kfree(device->discdata); - device->discdata = NULL; -} - -/* - * List of 3590 magnetic tape commands. - */ -static tape_mtop_fn tape_3590_mtop[TAPE_NR_MTOPS] = { - [MTRESET] = tape_std_mtreset, - [MTFSF] = tape_std_mtfsf, - [MTBSF] = tape_std_mtbsf, - [MTFSR] = tape_std_mtfsr, - [MTBSR] = tape_std_mtbsr, - [MTWEOF] = tape_std_mtweof, - [MTREW] = tape_std_mtrew, - [MTOFFL] = tape_std_mtoffl, - [MTNOP] = tape_std_mtnop, - [MTRETEN] = tape_std_mtreten, - [MTBSFM] = tape_std_mtbsfm, - [MTFSFM] = tape_std_mtfsfm, - [MTEOM] = tape_std_mteom, - [MTERASE] = tape_std_mterase, - [MTRAS1] = NULL, - [MTRAS2] = NULL, - [MTRAS3] = NULL, - [MTSETBLK] = tape_std_mtsetblk, - [MTSETDENSITY] = NULL, - [MTSEEK] = tape_3590_mtseek, - [MTTELL] = tape_3590_mttell, - [MTSETDRVBUFFER] = NULL, - [MTFSS] = NULL, - [MTBSS] = NULL, - [MTWSM] = NULL, - [MTLOCK] = NULL, - [MTUNLOCK] = NULL, - [MTLOAD] = tape_std_mtload, - [MTUNLOAD] = tape_std_mtunload, - [MTCOMPRESSION] = tape_std_mtcompression, - [MTSETPART] = NULL, - [MTMKPART] = NULL -}; - -/* - * Tape discipline structure for 3590. - */ -static struct tape_discipline tape_discipline_3590 = { - .owner = THIS_MODULE, - .setup_device = tape_3590_setup_device, - .cleanup_device = tape_3590_cleanup_device, - .process_eov = tape_std_process_eov, - .irq = tape_3590_irq, - .read_block = tape_std_read_block, - .write_block = tape_std_write_block, -#ifdef CONFIG_S390_TAPE_BLOCK - .bread = tape_3590_bread, - .free_bread = tape_3590_free_bread, - .check_locate = tape_3590_check_locate, -#endif - .ioctl_fn = tape_3590_ioctl, - .mtop_array = tape_3590_mtop -}; - -static struct ccw_device_id tape_3590_ids[] = { - {CCW_DEVICE_DEVTYPE(0x3590, 0, 0x3590, 0), .driver_info = tape_3590}, - {CCW_DEVICE_DEVTYPE(0x3592, 0, 0x3592, 0), .driver_info = tape_3592}, - { /* end of list */ } -}; - -static int -tape_3590_online(struct ccw_device *cdev) -{ - return tape_generic_online(cdev->dev.driver_data, - &tape_discipline_3590); -} - -static int -tape_3590_offline(struct ccw_device *cdev) -{ - return tape_generic_offline(cdev->dev.driver_data); -} - -static struct ccw_driver tape_3590_driver = { - .name = "tape_3590", - .owner = THIS_MODULE, - .ids = tape_3590_ids, - .probe = tape_generic_probe, - .remove = tape_generic_remove, - .set_offline = tape_3590_offline, - .set_online = tape_3590_online, -}; - -/* - * Setup discipline structure. - */ -static int -tape_3590_init(void) -{ - int rc; - - TAPE_DBF_AREA = debug_register("tape_3590", 2, 2, 4 * sizeof(long)); - debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); -#ifdef DBF_LIKE_HELL - debug_set_level(TAPE_DBF_AREA, 6); -#endif - - DBF_EVENT(3, "3590 init\n"); - /* Register driver for 3590 tapes. */ - rc = ccw_driver_register(&tape_3590_driver); - if (rc) - DBF_EVENT(3, "3590 init failed\n"); - else - DBF_EVENT(3, "3590 registered\n"); - return rc; -} - -static void -tape_3590_exit(void) -{ - ccw_driver_unregister(&tape_3590_driver); - - debug_unregister(TAPE_DBF_AREA); -} - -MODULE_DEVICE_TABLE(ccw, tape_3590_ids); -MODULE_AUTHOR("(C) 2001,2006 IBM Corporation"); -MODULE_DESCRIPTION("Linux on zSeries channel attached 3590 tape device driver"); -MODULE_LICENSE("GPL"); - -module_init(tape_3590_init); -module_exit(tape_3590_exit); diff --git a/drivers/s390/char/tape_3590.h b/drivers/s390/char/tape_3590.h deleted file mode 100644 index cf274b944..000000000 --- a/drivers/s390/char/tape_3590.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * drivers/s390/char/tape_3590.h - * tape device discipline for 3590 tapes. - * - * Copyright (C) IBM Corp. 2001,2006 - * Author(s): Stefan Bader - * Michael Holzheu - * Martin Schwidefsky - */ - -#ifndef _TAPE_3590_H -#define _TAPE_3590_H - -#define MEDIUM_SENSE 0xc2 -#define READ_PREVIOUS 0x0a -#define MODE_SENSE 0xcf -#define PERFORM_SS_FUNC 0x77 -#define READ_SS_DATA 0x3e - -#define PREP_RD_SS_DATA 0x18 -#define RD_ATTMSG 0x3 - -#define SENSE_BRA_PER 0 -#define SENSE_BRA_CONT 1 -#define SENSE_BRA_RE 2 -#define SENSE_BRA_DRE 3 - -#define SENSE_FMT_LIBRARY 0x23 -#define SENSE_FMT_UNSOLICITED 0x40 -#define SENSE_FMT_COMMAND_REJ 0x41 -#define SENSE_FMT_COMMAND_EXEC0 0x50 -#define SENSE_FMT_COMMAND_EXEC1 0x51 -#define SENSE_FMT_EVENT0 0x60 -#define SENSE_FMT_EVENT1 0x61 -#define SENSE_FMT_MIM 0x70 -#define SENSE_FMT_SIM 0x71 - -#define MSENSE_UNASSOCIATED 0x00 -#define MSENSE_ASSOCIATED_MOUNT 0x01 -#define MSENSE_ASSOCIATED_UMOUNT 0x02 - -#define TAPE_3590_MAX_MSG 0xb0 - -/* Datatypes */ - -struct tape_3590_disc_data { - unsigned char modeset_byte; - int read_back_op; -}; - -struct tape_3590_sense { - - unsigned int command_rej:1; - unsigned int interv_req:1; - unsigned int bus_out_check:1; - unsigned int eq_check:1; - unsigned int data_check:1; - unsigned int overrun:1; - unsigned int def_unit_check:1; - unsigned int assgnd_elsew:1; - - unsigned int locate_fail:1; - unsigned int inst_online:1; - unsigned int reserved:1; - unsigned int blk_seq_err:1; - unsigned int begin_part:1; - unsigned int wr_mode:1; - unsigned int wr_prot:1; - unsigned int not_cap:1; - - unsigned int bra:2; - unsigned int lc:3; - unsigned int vlf_active:1; - unsigned int stm:1; - unsigned int med_pos:1; - - unsigned int rac:8; - - unsigned int rc_rqc:16; - - unsigned int mc:8; - - unsigned int sense_fmt:8; - - union { - struct { - unsigned int emc:4; - unsigned int smc:4; - unsigned int sev:2; - unsigned int reserved:6; - unsigned int md:8; - unsigned int refcode:8; - unsigned int mid:16; - unsigned int mp:16; - unsigned char volid[6]; - unsigned int fid:8; - } f70; - struct { - unsigned int emc:4; - unsigned int smc:4; - unsigned int sev:2; - unsigned int reserved1:5; - unsigned int mdf:1; - unsigned char md[3]; - unsigned int simid:8; - unsigned int uid:16; - unsigned int refcode1:16; - unsigned int refcode2:16; - unsigned int refcode3:16; - unsigned int reserved2:8; - } f71; - unsigned char data[14]; - } fmt; - unsigned char pad[10]; - -} __attribute__ ((packed)); - -struct tape_3590_med_sense { - unsigned int macst:4; - unsigned int masst:4; - char pad[127]; -} __attribute__ ((packed)); - -#endif /* _TAPE_3590_H */ diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index b70d92690..5ced2725d 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -198,7 +198,9 @@ tapeblock_request_fn(request_queue_t *queue) device = (struct tape_device *) queue->queuedata; DBF_LH(6, "tapeblock_request_fn(device=%p)\n", device); - BUG_ON(device == NULL); + if (device == NULL) + BUG(); + tapeblock_trigger_requeue(device); } @@ -305,7 +307,8 @@ tapeblock_revalidate_disk(struct gendisk *disk) int rc; device = (struct tape_device *) disk->private_data; - BUG_ON(!device); + if (!device) + BUG(); if (!device->blk_data.medium_changed) return 0; @@ -432,14 +435,16 @@ tapeblock_ioctl( ) { int rc; int minor; - struct gendisk *disk; - struct tape_device *device; + struct gendisk *disk = inode->i_bdev->bd_disk; + struct tape_device *device = disk->private_data; rc = 0; disk = inode->i_bdev->bd_disk; - BUG_ON(!disk); + if (!disk) + BUG(); device = disk->private_data; - BUG_ON(!device); + if (!device) + BUG(); minor = iminor(inode); DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command); diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index a5c68e60f..b3569c82b 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -44,10 +44,11 @@ struct tape_class_device *register_tape_dev( int rc; char * s; - tcd = kzalloc(sizeof(struct tape_class_device), GFP_KERNEL); + tcd = kmalloc(sizeof(struct tape_class_device), GFP_KERNEL); if (!tcd) return ERR_PTR(-ENOMEM); + memset(tcd, 0, sizeof(struct tape_class_device)); strncpy(tcd->device_name, device_name, TAPECLASS_NAME_LEN); for (s = strchr(tcd->device_name, '/'); s; s = strchr(s, '/')) *s = '!'; diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index e6e4086d3..4ea438c74 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -210,14 +210,18 @@ tape_state_set(struct tape_device *device, enum tape_state newstate) return; } DBF_EVENT(4, "ts. dev: %x\n", device->first_minor); - DBF_EVENT(4, "old ts:\t\n"); - if (device->tape_state < TS_SIZE && device->tape_state >=0 ) + if (device->tape_state < TO_SIZE && device->tape_state >= 0) + str = tape_state_verbose[device->tape_state]; + else + str = "UNKNOWN TS"; + DBF_EVENT(4, "old ts: %s\n", str); + if (device->tape_state < TO_SIZE && device->tape_state >=0 ) str = tape_state_verbose[device->tape_state]; else str = "UNKNOWN TS"; DBF_EVENT(4, "%s\n", str); DBF_EVENT(4, "new ts:\t\n"); - if (newstate < TS_SIZE && newstate >= 0) + if (newstate < TO_SIZE && newstate >= 0) str = tape_state_verbose[newstate]; else str = "UNKNOWN TS"; @@ -449,14 +453,16 @@ tape_alloc_device(void) { struct tape_device *device; - device = kzalloc(sizeof(struct tape_device), GFP_KERNEL); + device = (struct tape_device *) + kmalloc(sizeof(struct tape_device), GFP_KERNEL); if (device == NULL) { DBF_EXCEPTION(2, "ti:no mem\n"); PRINT_INFO ("can't allocate memory for " "tape info structure\n"); return ERR_PTR(-ENOMEM); } - device->modeset_byte = kmalloc(1, GFP_KERNEL | GFP_DMA); + memset(device, 0, sizeof(struct tape_device)); + device->modeset_byte = (char *) kmalloc(1, GFP_KERNEL | GFP_DMA); if (device->modeset_byte == NULL) { DBF_EXCEPTION(2, "ti:no mem\n"); PRINT_INFO("can't allocate memory for modeset byte\n"); @@ -653,30 +659,34 @@ tape_alloc_request(int cplength, int datasize) DBF_LH(6, "tape_alloc_request(%d, %d)\n", cplength, datasize); - request = kzalloc(sizeof(struct tape_request), GFP_KERNEL); + request = (struct tape_request *) kmalloc(sizeof(struct tape_request), + GFP_KERNEL); if (request == NULL) { DBF_EXCEPTION(1, "cqra nomem\n"); return ERR_PTR(-ENOMEM); } + memset(request, 0, sizeof(struct tape_request)); /* allocate channel program */ if (cplength > 0) { - request->cpaddr = kcalloc(cplength, sizeof(struct ccw1), + request->cpaddr = kmalloc(cplength*sizeof(struct ccw1), GFP_ATOMIC | GFP_DMA); if (request->cpaddr == NULL) { DBF_EXCEPTION(1, "cqra nomem\n"); kfree(request); return ERR_PTR(-ENOMEM); } + memset(request->cpaddr, 0, cplength*sizeof(struct ccw1)); } /* alloc small kernel buffer */ if (datasize > 0) { - request->cpdata = kzalloc(datasize, GFP_KERNEL | GFP_DMA); + request->cpdata = kmalloc(datasize, GFP_KERNEL | GFP_DMA); if (request->cpdata == NULL) { DBF_EXCEPTION(1, "cqra nomem\n"); kfree(request->cpaddr); kfree(request); return ERR_PTR(-ENOMEM); } + memset(request->cpdata, 0, datasize); } DBF_LH(6, "New request %p(%p/%p)\n", request, request->cpaddr, request->cpdata); @@ -751,13 +761,6 @@ __tape_start_next_request(struct tape_device *device) */ if (request->status == TAPE_REQUEST_IN_IO) return; - /* - * Request has already been stopped. We have to wait until - * the request is removed from the queue in the interrupt - * handling. - */ - if (request->status == TAPE_REQUEST_DONE) - return; /* * We wanted to cancel the request but the common I/O layer @@ -1012,7 +1015,7 @@ tape_do_io_interruptible(struct tape_device *device, wq, (request->callback == NULL) ); - } while (rc == -ERESTARTSYS); + } while (rc != -ERESTARTSYS); DBF_EVENT(3, "IO stopped on %08x\n", device->cdev_id); rc = -ERESTARTSYS; @@ -1020,20 +1023,6 @@ tape_do_io_interruptible(struct tape_device *device, return rc; } -/* - * Stop running ccw. - */ -int -tape_cancel_io(struct tape_device *device, struct tape_request *request) -{ - int rc; - - spin_lock_irq(get_ccwdev_lock(device->cdev)); - rc = __tape_cancel_io(device, request); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - return rc; -} - /* * Tape interrupt routine, called from the ccw_device layer */ @@ -1075,16 +1064,15 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) /* * If the condition code is not zero and the start function bit is * still set, this is an deferred error and the last start I/O did - * not succeed. At this point the condition that caused the deferred - * error might still apply. So we just schedule the request to be - * started later. + * not succeed. Restart the request now. */ - if (irb->scsw.cc != 0 && (irb->scsw.fctl & SCSW_FCTL_START_FUNC) && - (request->status == TAPE_REQUEST_IN_IO)) { - DBF_EVENT(3,"(%08x): deferred cc=%i, fctl=%i. restarting\n", - device->cdev_id, irb->scsw.cc, irb->scsw.fctl); - request->status = TAPE_REQUEST_QUEUED; - schedule_delayed_work(&device->tape_dnr, HZ); + if (irb->scsw.cc != 0 && (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) { + PRINT_WARN("(%s): deferred cc=%i. restaring\n", + cdev->dev.bus_id, + irb->scsw.cc); + rc = __tape_start_io(device, request); + if (rc) + __tape_end_request(device, request, rc); return; } @@ -1298,5 +1286,4 @@ EXPORT_SYMBOL(tape_dump_sense_dbf); EXPORT_SYMBOL(tape_do_io); EXPORT_SYMBOL(tape_do_io_async); EXPORT_SYMBOL(tape_do_io_interruptible); -EXPORT_SYMBOL(tape_cancel_io); EXPORT_SYMBOL(tape_mtop); diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 99cf881f4..2f9fe3098 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -37,19 +37,20 @@ tape_std_assign_timeout(unsigned long data) { struct tape_request * request; struct tape_device * device; - int rc; request = (struct tape_request *) data; if ((device = request->device) == NULL) BUG(); - DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n", + spin_lock_irq(get_ccwdev_lock(device->cdev)); + if (request->callback != NULL) { + DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n", device->cdev_id); - rc = tape_cancel_io(device, request); - if(rc) - PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n", - device->cdev->dev.bus_id, rc); - + PRINT_ERR("%s: Assignment timeout. Device busy.\n", + device->cdev->dev.bus_id); + ccw_device_clear(device->cdev, (long) request); + } + spin_unlock_irq(get_ccwdev_lock(device->cdev)); } int diff --git a/drivers/s390/char/tape_std.h b/drivers/s390/char/tape_std.h index 1fc952359..3ab6aafb7 100644 --- a/drivers/s390/char/tape_std.h +++ b/drivers/s390/char/tape_std.h @@ -1,8 +1,9 @@ /* - * drivers/s390/char/tape_std.h + * drivers/s390/char/tape_34xx.h * standard tape device functions for ibm tapes. * - * Copyright (C) IBM Corp. 2001,2006 + * S390 and zSeries version + * Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Carsten Otte * Tuan Ngo-Anh * Martin Schwidefsky @@ -148,12 +149,4 @@ void tape_std_error_recovery_do_retry(struct tape_device *); void tape_std_error_recovery_read_opposite(struct tape_device *); void tape_std_error_recovery_HWBUG(struct tape_device *, int condno); -/* S390 tape types */ -enum s390_tape_type { - tape_3480, - tape_3490, - tape_3590, - tape_3592, -}; - #endif // _TAPE_STD_H diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 9a1417768..4b9069370 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -691,9 +691,10 @@ tty3270_alloc_view(void) struct tty3270 *tp; int pages; - tp = kzalloc(sizeof(struct tty3270), GFP_KERNEL); + tp = kmalloc(sizeof(struct tty3270),GFP_KERNEL); if (!tp) goto out_err; + memset(tp, 0, sizeof(struct tty3270)); tp->freemem_pages = kmalloc(sizeof(void *) * TTY3270_STRING_PAGES, GFP_KERNEL); if (!tp->freemem_pages) @@ -766,14 +767,16 @@ tty3270_alloc_screen(struct tty3270 *tp) int lines; size = sizeof(struct tty3270_line) * (tp->view.rows - 2); - tp->screen = kzalloc(size, GFP_KERNEL); + tp->screen = kmalloc(size, GFP_KERNEL); if (!tp->screen) goto out_err; + memset(tp->screen, 0, size); for (lines = 0; lines < tp->view.rows - 2; lines++) { size = sizeof(struct tty3270_cell) * tp->view.cols; - tp->screen[lines].cells = kzalloc(size, GFP_KERNEL); + tp->screen[lines].cells = kmalloc(size, GFP_KERNEL); if (!tp->screen[lines].cells) goto out_screen; + memset(tp->screen[lines].cells, 0, size); } return 0; out_screen: diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index c625b69eb..b2d75de14 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -759,8 +759,9 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) { struct device *dev; int ret; - dev = kzalloc(sizeof(struct device), GFP_KERNEL); + dev = kmalloc(sizeof(struct device), GFP_KERNEL); if (dev) { + memset(dev, 0, sizeof(struct device)); snprintf(dev->bus_id, BUS_ID_SIZE, "%s", priv->internal_name); dev->bus = &iucv_bus; diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 0960bef7b..cb8e2e672 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c @@ -414,11 +414,11 @@ cio_ignore_proc_init (void) entry = create_proc_entry ("cio_ignore", S_IFREG | S_IRUGO | S_IWUSR, &proc_root); if (!entry) - return -ENOENT; + return 0; entry->proc_fops = &cio_ignore_proc_fops; - return 0; + return 1; } __initcall (cio_ignore_proc_init); diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index bdfee7fba..8013c8eb7 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -157,10 +157,11 @@ ccwgroup_create(struct device *root, if (argc > 256) /* disallow dumb users */ return -EINVAL; - gdev = kzalloc(sizeof(*gdev) + argc*sizeof(gdev->cdev[0]), GFP_KERNEL); + gdev = kmalloc(sizeof(*gdev) + argc*sizeof(gdev->cdev[0]), GFP_KERNEL); if (!gdev) return -ENOMEM; + memset(gdev, 0, sizeof(*gdev) + argc*sizeof(gdev->cdev[0])); atomic_set(&gdev->onoff, 0); del_drvdata = 0; diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 72187e54d..f4183d660 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -98,8 +98,10 @@ chsc_get_sch_desc_irq(struct subchannel *sch, void *page) ssd_area = page; - ssd_area->request.length = 0x0010; - ssd_area->request.code = 0x0004; + ssd_area->request = (struct chsc_header) { + .length = 0x0010, + .code = 0x0004, + }; ssd_area->ssid = sch->schid.ssid; ssd_area->f_sch = sch->schid.sch_no; @@ -242,10 +244,28 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) if (sch->vpm == mask) goto out_unreg; - if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && - (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && - (sch->schib.pmcw.lpum == mask) && - (sch->vpm == 0)) { + if ((sch->schib.scsw.actl & (SCSW_ACTL_CLEAR_PEND | + SCSW_ACTL_HALT_PEND | + SCSW_ACTL_START_PEND | + SCSW_ACTL_RESUME_PEND)) && + (sch->schib.pmcw.lpum == mask)) { + int cc = cio_cancel(sch); + + if (cc == -ENODEV) + goto out_unreg; + + if (cc == -EINVAL) { + cc = cio_clear(sch); + if (cc == -ENODEV) + goto out_unreg; + /* Call handler. */ + if (sch->driver && sch->driver->termination) + sch->driver->termination(&sch->dev); + goto out_unlock; + } + } else if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && + (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && + (sch->schib.pmcw.lpum == mask)) { int cc; cc = cio_clear(sch); @@ -497,8 +517,10 @@ chsc_process_crw(void) struct device *dev; memset(sei_area, 0, sizeof(*sei_area)); memset(&res_data, 0, sizeof(struct res_acc_data)); - sei_area->request.length = 0x0010; - sei_area->request.code = 0x000e; + sei_area->request = (struct chsc_header) { + .length = 0x0010, + .code = 0x000e, + }; ccode = chsc(sei_area); if (ccode > 0) @@ -635,13 +657,13 @@ __chp_add(struct subchannel_id schid, void *data) if (sch->schib.pmcw.chpid[i] == chp->id) { if (stsch(sch->schid, &sch->schib) != 0) { /* Endgame. */ - spin_unlock_irq(&sch->lock); + spin_unlock(&sch->lock); return -ENXIO; } break; } if (i==8) { - spin_unlock_irq(&sch->lock); + spin_unlock(&sch->lock); return 0; } sch->lpm = ((sch->schib.pmcw.pim & @@ -852,264 +874,6 @@ s390_vary_chpid( __u8 chpid, int on) return 0; } -/* - * Channel measurement related functions - */ -static ssize_t -chp_measurement_chars_read(struct kobject *kobj, char *buf, loff_t off, - size_t count) -{ - struct channel_path *chp; - unsigned int size; - - chp = to_channelpath(container_of(kobj, struct device, kobj)); - if (!chp->cmg_chars) - return 0; - - size = sizeof(struct cmg_chars); - - if (off > size) - return 0; - if (off + count > size) - count = size - off; - memcpy(buf, chp->cmg_chars + off, count); - return count; -} - -static struct bin_attribute chp_measurement_chars_attr = { - .attr = { - .name = "measurement_chars", - .mode = S_IRUSR, - .owner = THIS_MODULE, - }, - .size = sizeof(struct cmg_chars), - .read = chp_measurement_chars_read, -}; - -static void -chp_measurement_copy_block(struct cmg_entry *buf, - struct channel_subsystem *css, int chpid) -{ - void *area; - struct cmg_entry *entry, reference_buf; - int idx; - - if (chpid < 128) { - area = css->cub_addr1; - idx = chpid; - } else { - area = css->cub_addr2; - idx = chpid - 128; - } - entry = area + (idx * sizeof(struct cmg_entry)); - do { - memcpy(buf, entry, sizeof(*entry)); - memcpy(&reference_buf, entry, sizeof(*entry)); - } while (reference_buf.values[0] != buf->values[0]); -} - -static ssize_t -chp_measurement_read(struct kobject *kobj, char *buf, loff_t off, size_t count) -{ - struct channel_path *chp; - struct channel_subsystem *css; - unsigned int size; - - chp = to_channelpath(container_of(kobj, struct device, kobj)); - css = to_css(chp->dev.parent); - - size = sizeof(struct cmg_chars); - - /* Only allow single reads. */ - if (off || count < size) - return 0; - chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id); - return count; -} - -static struct bin_attribute chp_measurement_attr = { - .attr = { - .name = "measurement", - .mode = S_IRUSR, - .owner = THIS_MODULE, - }, - .size = sizeof(struct cmg_entry), - .read = chp_measurement_read, -}; - -static void -chsc_remove_chp_cmg_attr(struct channel_path *chp) -{ - sysfs_remove_bin_file(&chp->dev.kobj, &chp_measurement_chars_attr); - sysfs_remove_bin_file(&chp->dev.kobj, &chp_measurement_attr); -} - -static int -chsc_add_chp_cmg_attr(struct channel_path *chp) -{ - int ret; - - ret = sysfs_create_bin_file(&chp->dev.kobj, - &chp_measurement_chars_attr); - if (ret) - return ret; - ret = sysfs_create_bin_file(&chp->dev.kobj, &chp_measurement_attr); - if (ret) - sysfs_remove_bin_file(&chp->dev.kobj, - &chp_measurement_chars_attr); - return ret; -} - -static void -chsc_remove_cmg_attr(struct channel_subsystem *css) -{ - int i; - - for (i = 0; i <= __MAX_CHPID; i++) { - if (!css->chps[i]) - continue; - chsc_remove_chp_cmg_attr(css->chps[i]); - } -} - -static int -chsc_add_cmg_attr(struct channel_subsystem *css) -{ - int i, ret; - - ret = 0; - for (i = 0; i <= __MAX_CHPID; i++) { - if (!css->chps[i]) - continue; - ret = chsc_add_chp_cmg_attr(css->chps[i]); - if (ret) - goto cleanup; - } - return ret; -cleanup: - for (--i; i >= 0; i--) { - if (!css->chps[i]) - continue; - chsc_remove_chp_cmg_attr(css->chps[i]); - } - return ret; -} - - -static int -__chsc_do_secm(struct channel_subsystem *css, int enable, void *page) -{ - struct { - struct chsc_header request; - u32 operation_code : 2; - u32 : 30; - u32 key : 4; - u32 : 28; - u32 zeroes1; - u32 cub_addr1; - u32 zeroes2; - u32 cub_addr2; - u32 reserved[13]; - struct chsc_header response; - u32 status : 8; - u32 : 4; - u32 fmt : 4; - u32 : 16; - } *secm_area; - int ret, ccode; - - secm_area = page; - secm_area->request.length = 0x0050; - secm_area->request.code = 0x0016; - - secm_area->key = PAGE_DEFAULT_KEY; - secm_area->cub_addr1 = (u64)(unsigned long)css->cub_addr1; - secm_area->cub_addr2 = (u64)(unsigned long)css->cub_addr2; - - secm_area->operation_code = enable ? 0 : 1; - - ccode = chsc(secm_area); - if (ccode > 0) - return (ccode == 3) ? -ENODEV : -EBUSY; - - switch (secm_area->response.code) { - case 0x0001: /* Success. */ - ret = 0; - break; - case 0x0003: /* Invalid block. */ - case 0x0007: /* Invalid format. */ - case 0x0008: /* Other invalid block. */ - CIO_CRW_EVENT(2, "Error in chsc request block!\n"); - ret = -EINVAL; - break; - case 0x0004: /* Command not provided in model. */ - CIO_CRW_EVENT(2, "Model does not provide secm\n"); - ret = -EOPNOTSUPP; - break; - case 0x0102: /* cub adresses incorrect */ - CIO_CRW_EVENT(2, "Invalid addresses in chsc request block\n"); - ret = -EINVAL; - break; - case 0x0103: /* key error */ - CIO_CRW_EVENT(2, "Access key error in secm\n"); - ret = -EINVAL; - break; - case 0x0105: /* error while starting */ - CIO_CRW_EVENT(2, "Error while starting channel measurement\n"); - ret = -EIO; - break; - default: - CIO_CRW_EVENT(2, "Unknown CHSC response %d\n", - secm_area->response.code); - ret = -EIO; - } - return ret; -} - -int -chsc_secm(struct channel_subsystem *css, int enable) -{ - void *secm_area; - int ret; - - secm_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); - if (!secm_area) - return -ENOMEM; - - mutex_lock(&css->mutex); - if (enable && !css->cm_enabled) { - css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); - css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); - if (!css->cub_addr1 || !css->cub_addr2) { - free_page((unsigned long)css->cub_addr1); - free_page((unsigned long)css->cub_addr2); - free_page((unsigned long)secm_area); - mutex_unlock(&css->mutex); - return -ENOMEM; - } - } - ret = __chsc_do_secm(css, enable, secm_area); - if (!ret) { - css->cm_enabled = enable; - if (css->cm_enabled) { - ret = chsc_add_cmg_attr(css); - if (ret) { - memset(secm_area, 0, PAGE_SIZE); - __chsc_do_secm(css, 0, secm_area); - css->cm_enabled = 0; - } - } else - chsc_remove_cmg_attr(css); - } - if (enable && !css->cm_enabled) { - free_page((unsigned long)css->cub_addr1); - free_page((unsigned long)css->cub_addr2); - } - mutex_unlock(&css->mutex); - free_page((unsigned long)secm_area); - return ret; -} - /* * Files for the channel path entries. */ @@ -1161,39 +925,9 @@ chp_type_show(struct device *dev, struct device_attribute *attr, char *buf) static DEVICE_ATTR(type, 0444, chp_type_show, NULL); -static ssize_t -chp_cmg_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct channel_path *chp = to_channelpath(dev); - - if (!chp) - return 0; - if (chp->cmg == -1) /* channel measurements not available */ - return sprintf(buf, "unknown\n"); - return sprintf(buf, "%x\n", chp->cmg); -} - -static DEVICE_ATTR(cmg, 0444, chp_cmg_show, NULL); - -static ssize_t -chp_shared_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct channel_path *chp = to_channelpath(dev); - - if (!chp) - return 0; - if (chp->shared == -1) /* channel measurements not available */ - return sprintf(buf, "unknown\n"); - return sprintf(buf, "%x\n", chp->shared); -} - -static DEVICE_ATTR(shared, 0444, chp_shared_show, NULL); - static struct attribute * chp_attrs[] = { &dev_attr_status.attr, &dev_attr_type.attr, - &dev_attr_cmg.attr, - &dev_attr_shared.attr, NULL, }; @@ -1232,8 +966,10 @@ chsc_determine_channel_path_description(int chpid, if (!scpd_area) return -ENOMEM; - scpd_area->request.length = 0x0010; - scpd_area->request.code = 0x0002; + scpd_area->request = (struct chsc_header) { + .length = 0x0010, + .code = 0x0002, + }; scpd_area->first_chpid = chpid; scpd_area->last_chpid = chpid; @@ -1270,111 +1006,6 @@ out: return ret; } -static void -chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, - struct cmg_chars *chars) -{ - switch (chp->cmg) { - case 2: - case 3: - chp->cmg_chars = kmalloc(sizeof(struct cmg_chars), - GFP_KERNEL); - if (chp->cmg_chars) { - int i, mask; - struct cmg_chars *cmg_chars; - - cmg_chars = chp->cmg_chars; - for (i = 0; i < NR_MEASUREMENT_CHARS; i++) { - mask = 0x80 >> (i + 3); - if (cmcv & mask) - cmg_chars->values[i] = chars->values[i]; - else - cmg_chars->values[i] = 0; - } - } - break; - default: - /* No cmg-dependent data. */ - break; - } -} - -static int -chsc_get_channel_measurement_chars(struct channel_path *chp) -{ - int ccode, ret; - - struct { - struct chsc_header request; - u32 : 24; - u32 first_chpid : 8; - u32 : 24; - u32 last_chpid : 8; - u32 zeroes1; - struct chsc_header response; - u32 zeroes2; - u32 not_valid : 1; - u32 shared : 1; - u32 : 22; - u32 chpid : 8; - u32 cmcv : 5; - u32 : 11; - u32 cmgq : 8; - u32 cmg : 8; - u32 zeroes3; - u32 data[NR_MEASUREMENT_CHARS]; - } *scmc_area; - - scmc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); - if (!scmc_area) - return -ENOMEM; - - scmc_area->request.length = 0x0010; - scmc_area->request.code = 0x0022; - - scmc_area->first_chpid = chp->id; - scmc_area->last_chpid = chp->id; - - ccode = chsc(scmc_area); - if (ccode > 0) { - ret = (ccode == 3) ? -ENODEV : -EBUSY; - goto out; - } - - switch (scmc_area->response.code) { - case 0x0001: /* Success. */ - if (!scmc_area->not_valid) { - chp->cmg = scmc_area->cmg; - chp->shared = scmc_area->shared; - chsc_initialize_cmg_chars(chp, scmc_area->cmcv, - (struct cmg_chars *) - &scmc_area->data); - } else { - chp->cmg = -1; - chp->shared = -1; - } - ret = 0; - break; - case 0x0003: /* Invalid block. */ - case 0x0007: /* Invalid format. */ - case 0x0008: /* Invalid bit combination. */ - CIO_CRW_EVENT(2, "Error in chsc request block!\n"); - ret = -EINVAL; - break; - case 0x0004: /* Command not provided. */ - CIO_CRW_EVENT(2, "Model does not provide scmc\n"); - ret = -EOPNOTSUPP; - break; - default: - CIO_CRW_EVENT(2, "Unknown CHSC response %d\n", - scmc_area->response.code); - ret = -EIO; - } -out: - free_page((unsigned long)scmc_area); - return ret; -} - /* * Entries for chpids on the system bus. * This replaces /proc/chpids. @@ -1385,9 +1016,10 @@ new_channel_path(int chpid) struct channel_path *chp; int ret; - chp = kzalloc(sizeof(struct channel_path), GFP_KERNEL); + chp = kmalloc(sizeof(struct channel_path), GFP_KERNEL); if (!chp) return -ENOMEM; + memset(chp, 0, sizeof(struct channel_path)); /* fill in status, etc. */ chp->id = chpid; @@ -1402,22 +1034,6 @@ new_channel_path(int chpid) ret = chsc_determine_channel_path_description(chpid, &chp->desc); if (ret) goto out_free; - /* Get channel-measurement characteristics. */ - if (css_characteristics_avail && css_chsc_characteristics.scmc - && css_chsc_characteristics.secm) { - ret = chsc_get_channel_measurement_chars(chp); - if (ret) - goto out_free; - } else { - static int msg_done; - - if (!msg_done) { - printk(KERN_WARNING "cio: Channel measurements not " - "available, continuing.\n"); - msg_done = 1; - } - chp->cmg = -1; - } /* make it known to the system */ ret = device_register(&chp->dev); @@ -1430,19 +1046,8 @@ new_channel_path(int chpid) if (ret) { device_unregister(&chp->dev); goto out_free; - } - mutex_lock(&css[0]->mutex); - if (css[0]->cm_enabled) { - ret = chsc_add_chp_cmg_attr(chp); - if (ret) { - sysfs_remove_group(&chp->dev.kobj, &chp_attr_group); - device_unregister(&chp->dev); - mutex_unlock(&css[0]->mutex); - goto out_free; - } - } - css[0]->chps[chpid] = chp; - mutex_unlock(&css[0]->mutex); + } else + css[0]->chps[chpid] = chp; return ret; out_free: kfree(chp); @@ -1498,8 +1103,10 @@ chsc_enable_facility(int operation_code) sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA); if (!sda_area) return -ENOMEM; - sda_area->request.length = 0x0400; - sda_area->request.code = 0x0031; + sda_area->request = (struct chsc_header) { + .length = 0x0400, + .code = 0x0031, + }; sda_area->operation_code = operation_code; ret = chsc(sda_area); @@ -1554,8 +1161,10 @@ chsc_determine_css_characteristics(void) return -ENOMEM; } - scsc_area->request.length = 0x0010; - scsc_area->request.code = 0x0010; + scsc_area->request = (struct chsc_header) { + .length = 0x0010, + .code = 0x0010, + }; result = chsc(scsc_area); if (result) { diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index a25924578..3e75095f3 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h @@ -12,16 +12,6 @@ struct chsc_header { u16 code; }; -#define NR_MEASUREMENT_CHARS 5 -struct cmg_chars { - u32 values[NR_MEASUREMENT_CHARS]; -}; - -#define NR_MEASUREMENT_ENTRIES 8 -struct cmg_entry { - u32 values[NR_MEASUREMENT_ENTRIES]; -}; - struct channel_path_desc { u8 flags; u8 lsn; @@ -37,10 +27,6 @@ struct channel_path { int id; int state; struct channel_path_desc desc; - /* Channel-measurement related stuff: */ - int cmg; - int shared; - void *cmg_chars; struct device dev; }; @@ -66,11 +52,7 @@ struct css_general_char { struct css_chsc_char { u64 res; - u64 : 20; - u32 secm : 1; /* bit 84 */ - u32 : 1; - u32 scmc : 1; /* bit 86 */ - u32 : 20; + u64 : 43; u32 scssc : 1; /* bit 107 */ u32 scsscf : 1; /* bit 108 */ u32 : 19; @@ -85,8 +67,6 @@ extern int css_characteristics_avail; extern void *chsc_get_chp_desc(struct subchannel*, int); extern int chsc_enable_facility(int); -struct channel_subsystem; -extern int chsc_secm(struct channel_subsystem *, int); #define to_channelpath(device) container_of(device, struct channel_path, dev) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 5b20d8c9c..cbb86fa5f 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -67,7 +67,7 @@ cio_debug_init (void) goto out_unregister; debug_register_view (cio_debug_msg_id, &debug_sprintf_view); debug_set_level (cio_debug_msg_id, 2); - cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 16); + cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 8); if (!cio_debug_trace_id) goto out_unregister; debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); diff --git a/drivers/s390/cio/cio_debug.h b/drivers/s390/cio/cio_debug.h index f88844ada..6af8b27d3 100644 --- a/drivers/s390/cio/cio_debug.h +++ b/drivers/s390/cio/cio_debug.h @@ -3,11 +3,6 @@ #include -/* for use of debug feature */ -extern debug_info_t *cio_debug_msg_id; -extern debug_info_t *cio_debug_trace_id; -extern debug_info_t *cio_debug_crw_id; - #define CIO_TRACE_EVENT(imp, txt) do { \ debug_text_event(cio_debug_trace_id, imp, txt); \ } while (0) @@ -20,19 +15,18 @@ extern debug_info_t *cio_debug_crw_id; debug_sprintf_event(cio_debug_crw_id, imp , ##args); \ } while (0) -static inline void -CIO_HEX_EVENT(int level, void *data, int length) -{ - while (length > 0) { - debug_event(cio_debug_trace_id, level, data, length); - length -= cio_debug_trace_id->buf_size; - data += cio_debug_trace_id->buf_size; - } -} +#define CIO_HEX_EVENT(imp, args...) do { \ + debug_event(cio_debug_trace_id, imp, ##args); \ + } while (0) #define CIO_DEBUG(printk_level,event_level,msg...) ({ \ if (cio_show_msg) printk(printk_level msg); \ CIO_MSG_EVENT (event_level, msg); \ }) +/* for use of debug feature */ +extern debug_info_t *cio_debug_msg_id; +extern debug_info_t *cio_debug_trace_id; +extern debug_info_t *cio_debug_crw_id; + #endif diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 74ea8aac4..3c77d6596 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -452,50 +452,15 @@ channel_subsystem_release(struct device *dev) struct channel_subsystem *css; css = to_css(dev); - mutex_destroy(&css->mutex); kfree(css); } -static ssize_t -css_cm_enable_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct channel_subsystem *css = to_css(dev); - - if (!css) - return 0; - return sprintf(buf, "%x\n", css->cm_enabled); -} - -static ssize_t -css_cm_enable_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct channel_subsystem *css = to_css(dev); - int ret; - - switch (buf[0]) { - case '0': - ret = css->cm_enabled ? chsc_secm(css, 0) : 0; - break; - case '1': - ret = css->cm_enabled ? 0 : chsc_secm(css, 1); - break; - default: - ret = -EINVAL; - } - return ret < 0 ? ret : count; -} - -static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store); - static inline void __init setup_css(int nr) { u32 tod_high; memset(css[nr], 0, sizeof(struct channel_subsystem)); - mutex_init(&css[nr]->mutex); css[nr]->valid = 1; css[nr]->cssid = nr; sprintf(css[nr]->device.bus_id, "css%x", nr); @@ -542,9 +507,6 @@ init_channel_subsystem (void) ret = device_register(&css[i]->device); if (ret) goto out_free; - if (css_characteristics_avail && css_chsc_characteristics.secm) - device_create_file(&css[i]->device, - &dev_attr_cm_enable); } css_init_done = 1; @@ -557,9 +519,6 @@ out_free: out_unregister: while (i > 0) { i--; - if (css_characteristics_avail && css_chsc_characteristics.secm) - device_remove_file(&css[i]->device, - &dev_attr_cm_enable); device_unregister(&css[i]->device); } out_bus: @@ -630,9 +589,10 @@ css_enqueue_subchannel_slow(struct subchannel_id schid) struct slow_subchannel *new_slow_sch; unsigned long flags; - new_slow_sch = kzalloc(sizeof(struct slow_subchannel), GFP_ATOMIC); + new_slow_sch = kmalloc(sizeof(struct slow_subchannel), GFP_ATOMIC); if (!new_slow_sch) return -ENOMEM; + memset(new_slow_sch, 0, sizeof(struct slow_subchannel)); new_slow_sch->schid = schid; spin_lock_irqsave(&slow_subchannel_lock, flags); list_add_tail(&new_slow_sch->slow_list, &slow_subchannels_head); diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index e210f89a2..b6375861c 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -1,7 +1,6 @@ #ifndef _CSS_H #define _CSS_H -#include #include #include @@ -45,11 +44,11 @@ struct pgid { union { __u8 fc; /* SPID function code */ struct path_state ps; /* SNID path state */ - } __attribute__ ((packed)) inf; + } inf; union { __u32 cpu_addr : 16; /* CPU address */ struct extended_cssid ext_cssid; - } __attribute__ ((packed)) pgid_high; + } pgid_high; __u32 cpu_id : 24; /* CPU identification */ __u32 cpu_model : 16; /* CPU model */ __u32 tod_high; /* high word TOD clock */ @@ -151,11 +150,6 @@ struct channel_subsystem { struct channel_path *chps[__MAX_CHPID + 1]; struct device device; struct pgid global_pgid; - struct mutex mutex; - /* channel measurement related */ - int cm_enabled; - void *cub_addr1; - void *cub_addr2; }; #define to_css(dev) container_of(dev, struct channel_subsystem, device) diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 8e3053c2a..afc4e8855 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -826,15 +826,17 @@ io_subchannel_probe (struct subchannel *sch) get_device(&cdev->dev); return 0; } - cdev = kzalloc (sizeof(*cdev), GFP_KERNEL); + cdev = kmalloc (sizeof(*cdev), GFP_KERNEL); if (!cdev) return -ENOMEM; - cdev->private = kzalloc(sizeof(struct ccw_device_private), + memset(cdev, 0, sizeof(struct ccw_device)); + cdev->private = kmalloc(sizeof(struct ccw_device_private), GFP_KERNEL | GFP_DMA); if (!cdev->private) { kfree(cdev); return -ENOMEM; } + memset(cdev->private, 0, sizeof(struct ccw_device_private)); atomic_set(&cdev->private->onoff, 0); cdev->dev = (struct device) { .parent = &sch->dev, diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 49ec562d7..b302779e7 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -749,7 +749,7 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event) /* Unit check but no sense data. Need basic sense. */ if (ccw_device_do_sense(cdev, irb) != 0) goto call_handler_unsol; - memcpy(&cdev->private->irb, irb, sizeof(struct irb)); + memcpy(irb, &cdev->private->irb, sizeof(struct irb)); cdev->private->state = DEV_STATE_W4SENSE; cdev->private->intparm = 0; return; @@ -827,17 +827,6 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) } return; } - /* - * Check if a halt or clear has been issued in the meanwhile. If yes, - * only deliver the halt/clear interrupt to the device driver as if it - * had killed the original request. - */ - if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) { - cdev->private->flags.dosense = 0; - memset(&cdev->private->irb, 0, sizeof(struct irb)); - ccw_device_accumulate_irb(cdev, irb); - goto call_handler; - } /* Add basic sense info to irb. */ ccw_device_accumulate_basic_sense(cdev, irb); if (cdev->private->flags.dosense) { @@ -845,7 +834,6 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) ccw_device_do_sense(cdev, irb); return; } -call_handler: cdev->private->state = DEV_STATE_ONLINE; /* Call the handler. */ if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify) diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 795abb5a6..3a50b1903 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -359,9 +359,10 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length) CIO_TRACE_EVENT (4, "rddevch"); CIO_TRACE_EVENT (4, sch->dev.bus_id); - rdc_ccw = kzalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); + rdc_ccw = kmalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); if (!rdc_ccw) return -ENOMEM; + memset(rdc_ccw, 0, sizeof(struct ccw1)); rdc_ccw->cmd_code = CCW_CMD_RDC; rdc_ccw->count = length; rdc_ccw->flags = CCW_FLAG_SLI; @@ -425,14 +426,16 @@ read_conf_data_lpm (struct ccw_device *cdev, void **buffer, int *length, __u8 lp if (!ciw || ciw->cmd == 0) return -EOPNOTSUPP; - rcd_ccw = kzalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); + rcd_ccw = kmalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); if (!rcd_ccw) return -ENOMEM; - rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA); + memset(rcd_ccw, 0, sizeof(struct ccw1)); + rcd_buf = kmalloc(ciw->count, GFP_KERNEL | GFP_DMA); if (!rcd_buf) { kfree(rcd_ccw); return -ENOMEM; } + memset (rcd_buf, 0, ciw->count); rcd_ccw->cmd_code = ciw->cmd; rcd_ccw->cda = (__u32) __pa (rcd_buf); rcd_ccw->count = ciw->count; diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 96f519281..9ed37dc9a 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -81,8 +80,6 @@ static int indicator_used[INDICATORS_PER_CACHELINE]; static __u32 * volatile indicators; static __u32 volatile spare_indicator; static atomic_t spare_indicator_usecount; -#define QDIO_MEMPOOL_SCSSC_ELEMENTS 2 -static mempool_t *qdio_mempool_scssc; static debug_info_t *qdio_dbf_setup; static debug_info_t *qdio_dbf_sbal; @@ -1640,7 +1637,7 @@ next: } kfree(irq_ptr->qdr); - free_page((unsigned long) irq_ptr); + kfree(irq_ptr); } static void @@ -1689,14 +1686,16 @@ qdio_alloc_qs(struct qdio_irq *irq_ptr, int result=-ENOMEM; for (i=0;islib = kmalloc(PAGE_SIZE, GFP_KERNEL); + memset(q,0,sizeof(struct qdio_q)); + + q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL); if (!q->slib) { QDIO_PRINT_ERR("kmalloc of slib failed!\n"); goto out; @@ -1706,12 +1705,14 @@ qdio_alloc_qs(struct qdio_irq *irq_ptr, } for (i=0;islib=kmalloc(PAGE_SIZE,GFP_KERNEL); if (!q->slib) { QDIO_PRINT_ERR("kmalloc of slib failed!\n"); @@ -2307,7 +2308,7 @@ qdio_get_ssqd_information(struct qdio_irq *irq_ptr) QDIO_DBF_TEXT0(0,setup,"getssqd"); qdioac = 0; - ssqd_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC); + ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!ssqd_area) { QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \ "SIGAs for sch x%x.\n", irq_ptr->schid.sch_no); @@ -2367,7 +2368,7 @@ qdio_get_ssqd_information(struct qdio_irq *irq_ptr) out: qdio_check_subchannel_qebsm(irq_ptr, qdioac, ssqd_area->sch_token); - mempool_free(ssqd_area, qdio_mempool_scssc); + free_page ((unsigned long) ssqd_area); irq_ptr->qdioac = qdioac; } @@ -2461,7 +2462,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero) virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind); } - scssc_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC); + scssc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!scssc_area) { QDIO_PRINT_WARN("No memory for setting indicators on " \ "subchannel 0.%x.%x.\n", @@ -2517,7 +2518,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero) QDIO_DBF_HEX2(0,setup,&real_addr_dev_st_chg_ind,sizeof(unsigned long)); result = 0; out: - mempool_free(scssc_area, qdio_mempool_scssc); + free_page ((unsigned long) scssc_area); return result; } @@ -2546,7 +2547,7 @@ tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target) if (!irq_ptr->is_thinint_irq) return -ENODEV; - scsscf_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC); + scsscf_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!scsscf_area) { QDIO_PRINT_WARN("No memory for setting delay target on " \ "subchannel 0.%x.%x.\n", @@ -2584,7 +2585,7 @@ tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target) QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long)); result = 0; /* not critical */ out: - mempool_free(scsscf_area, qdio_mempool_scssc); + free_page ((unsigned long) scsscf_area); return result; } @@ -2983,7 +2984,7 @@ qdio_allocate(struct qdio_initialize *init_data) qdio_allocate_do_dbf(init_data); /* create irq */ - irq_ptr = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + irq_ptr=kmalloc(sizeof(struct qdio_irq), GFP_KERNEL | GFP_DMA); QDIO_DBF_TEXT0(0,setup,"irq_ptr:"); QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*)); @@ -2993,12 +2994,14 @@ qdio_allocate(struct qdio_initialize *init_data) return -ENOMEM; } + memset(irq_ptr,0,sizeof(struct qdio_irq)); + init_MUTEX(&irq_ptr->setting_up_sema); /* QDR must be in DMA area since CCW data address is only 32 bit */ irq_ptr->qdr=kmalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA); if (!(irq_ptr->qdr)) { - free_page((unsigned long) irq_ptr); + kfree(irq_ptr); QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n"); return -ENOMEM; } @@ -3683,10 +3686,10 @@ qdio_get_qdio_memory(void) for (i=1;itype == TYPE82_RSP_CODE) - PRINTKW("Machine check failure\n"); - else - PRINTKW("Module failure\n"); - return REC_HARDWAR_ERR; case REP82_ERROR_OPERAND_INVALID: - return REC_OPERAND_INV; case REP88_ERROR_MESSAGE_MALFORMD: - PRINTKW("Message malformed\n"); return REC_OPERAND_INV; case REP82_ERROR_OPERAND_SIZE: return REC_OPERAND_SIZE; diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c index 982acc730..7d6f19030 100644 --- a/drivers/s390/crypto/z90main.c +++ b/drivers/s390/crypto/z90main.c @@ -1,9 +1,9 @@ /* * linux/drivers/s390/crypto/z90main.c * - * z90crypt 1.3.3 + * z90crypt 1.3.2 * - * Copyright (C) 2001, 2005 IBM Corporation + * Copyright (C) 2001, 2004 IBM Corporation * Author(s): Robert Burroughs (burrough@us.ibm.com) * Eric Rossman (edrossma@us.ibm.com) * @@ -707,12 +707,13 @@ z90crypt_open(struct inode *inode, struct file *filp) if (quiesce_z90crypt) return -EQUIESCE; - private_data_p = kzalloc(sizeof(struct priv_data), GFP_KERNEL); + private_data_p = kmalloc(sizeof(struct priv_data), GFP_KERNEL); if (!private_data_p) { PRINTK("Memory allocate failed\n"); return -ENOMEM; } + memset((void *)private_data_p, 0, sizeof(struct priv_data)); private_data_p->status = STAT_OPEN; private_data_p->opener_pid = PID(); filp->private_data = private_data_p; @@ -990,7 +991,6 @@ remove_device(struct device *device_p) * PCIXCC_MCL2 512-2048 ----- (applying any GA LIC will make an MCL3 card) * PCIXCC_MCL3 ----- 128-2048 * CEX2C 512-2048 128-2048 - * CEX2A ??-2048 same (the lower limit is less than 128 bit...) * * ext_bitlens (extended bitlengths) is a global, since you should not apply an * MCL to just one card in a machine. We assume, at first, that all cards have @@ -2736,11 +2736,13 @@ create_z90crypt(int *cdx_p) z90crypt.max_count = Z90CRYPT_NUM_DEVS; z90crypt.cdx = *cdx_p; - hdware_blk_p = kzalloc(sizeof(struct hdware_block), GFP_ATOMIC); + hdware_blk_p = (struct hdware_block *) + kmalloc(sizeof(struct hdware_block), GFP_ATOMIC); if (!hdware_blk_p) { PDEBUG("kmalloc for hardware block failed\n"); return ENOMEM; } + memset(hdware_blk_p, 0x00, sizeof(struct hdware_block)); z90crypt.hdware_info = hdware_blk_p; return 0; @@ -2975,11 +2977,12 @@ create_crypto_device(int index) total_size = sizeof(struct device) + z90crypt.q_depth_array[index] * sizeof(int); - dev_ptr = kzalloc(total_size, GFP_ATOMIC); + dev_ptr = (struct device *) kmalloc(total_size, GFP_ATOMIC); if (!dev_ptr) { PRINTK("kmalloc device %d failed\n", index); return ENOMEM; } + memset(dev_ptr, 0, total_size); dev_ptr->dev_resp_p = kmalloc(MAX_RESPONSE_SIZE, GFP_ATOMIC); if (!dev_ptr->dev_resp_p) { kfree(dev_ptr); diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 23d53bf9d..a86436a7a 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -310,7 +310,7 @@ claw_probe(struct ccwgroup_device *cgdev) printk(KERN_INFO "claw: variable cgdev =\n"); dumpit((char *)cgdev, sizeof(struct ccwgroup_device)); #endif - privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL); + privptr = kmalloc(sizeof(struct claw_privbk), GFP_KERNEL); if (privptr == NULL) { probe_error(cgdev); put_device(&cgdev->dev); @@ -319,6 +319,7 @@ claw_probe(struct ccwgroup_device *cgdev) CLAW_DBF_TEXT_(2,setup,"probex%d",-ENOMEM); return -ENOMEM; } + memset(privptr,0x00,sizeof(struct claw_privbk)); privptr->p_mtc_envelope= kmalloc( MAX_ENVELOPE_SIZE, GFP_KERNEL); privptr->p_env = kmalloc(sizeof(struct claw_env), GFP_KERNEL); if ((privptr->p_mtc_envelope==NULL) || (privptr->p_env==NULL)) { @@ -1403,7 +1404,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first, if ( privptr-> p_read_active_first ==NULL ) { #ifdef DEBUGMSG - printk(KERN_INFO "%s:%s p_read_active_first == NULL \n", + printk(KERN_INFO "%s:%s p_read_active_frist == NULL \n", dev->name,__FUNCTION__); printk(KERN_INFO "%s:%s Read active first/last changed \n", dev->name,__FUNCTION__); diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index fe986af88..af9f21231 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c @@ -1486,13 +1486,13 @@ ch_action_iofatal(fsm_instance * fi, int event, void *arg) } } -static void +static void ch_action_reinit(fsm_instance *fi, int event, void *arg) { struct channel *ch = (struct channel *)arg; struct net_device *dev = ch->netdev; struct ctc_priv *privptr = dev->priv; - + DBF_TEXT(trace, 4, __FUNCTION__); ch_action_iofatal(fi, event, arg); fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev); @@ -1624,7 +1624,7 @@ less_than(char *id1, char *id2) } dev1 = simple_strtoul(id1, &id1, 16); dev2 = simple_strtoul(id2, &id2, 16); - + return (dev1 < dev2); } @@ -1895,7 +1895,7 @@ ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) irb->scsw.dstat); return; } - + priv = ((struct ccwgroup_device *)cdev->dev.driver_data) ->dev.driver_data; @@ -1909,7 +1909,7 @@ ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) "device %s\n", cdev->dev.bus_id); return; } - + dev = (struct net_device *) (ch->netdev); if (dev == NULL) { ctc_pr_crit("ctc: ctc_irq_handler dev=NULL bus_id=%s, ch=0x%p\n", @@ -2008,12 +2008,12 @@ dev_action_stop(fsm_instance * fi, int event, void *arg) fsm_event(ch->fsm, CH_EVENT_STOP, ch); } } -static void +static void dev_action_restart(fsm_instance *fi, int event, void *arg) { struct net_device *dev = (struct net_device *)arg; struct ctc_priv *privptr = dev->priv; - + DBF_TEXT(trace, 3, __FUNCTION__); ctc_pr_debug("%s: Restarting\n", dev->name); dev_action_stop(fi, event, arg); @@ -2193,7 +2193,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb) DBF_TEXT(trace, 5, __FUNCTION__); /* we need to acquire the lock for testing the state - * otherwise we can have an IRQ changing the state to + * otherwise we can have an IRQ changing the state to * TXIDLE after the test but before acquiring the lock. */ spin_lock_irqsave(&ch->collect_lock, saveflags); @@ -2393,7 +2393,7 @@ ctc_tx(struct sk_buff *skb, struct net_device * dev) /** * If channels are not running, try to restart them - * and throw away packet. + * and throw away packet. */ if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { fsm_event(privptr->fsm, DEV_EVENT_START, dev); @@ -2738,7 +2738,7 @@ ctc_remove_files(struct device *dev) /** * Add ctc specific attributes. * Add ctc private data. - * + * * @param cgdev pointer to ccwgroup_device just added * * @returns 0 on success, !0 on failure. @@ -2869,7 +2869,7 @@ ctc_new_device(struct ccwgroup_device *cgdev) DBF_TEXT(setup, 3, buffer); type = get_channel_type(&cgdev->cdev[0]->id); - + snprintf(read_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id); snprintf(write_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[1]->dev.bus_id); @@ -2907,7 +2907,7 @@ ctc_new_device(struct ccwgroup_device *cgdev) channel_get(type, direction == READ ? read_id : write_id, direction); if (privptr->channel[direction] == NULL) { - if (direction == WRITE) + if (direction == WRITE) channel_free(privptr->channel[READ]); ctc_free_netdevice(dev, 1); @@ -2955,7 +2955,7 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev) { struct ctc_priv *priv; struct net_device *ndev; - + DBF_TEXT(setup, 3, __FUNCTION__); pr_debug("%s() called\n", __FUNCTION__); diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c index af54d1de0..5cdcdbf92 100644 --- a/drivers/s390/net/ctctty.c +++ b/drivers/s390/net/ctctty.c @@ -130,7 +130,7 @@ ctc_tty_readmodem(ctc_tty_info *info) if ((tty = info->tty)) { if (info->mcr & UART_MCR_RTS) { struct sk_buff *skb; - + if ((skb = skb_dequeue(&info->rx_queue))) { int len = skb->len; tty_insert_flip_string(tty, skb->data, len); @@ -328,7 +328,7 @@ ctc_tty_inject(ctc_tty_info *info, char c) { int skb_res; struct sk_buff *skb; - + DBF_TEXT(trace, 4, __FUNCTION__); if (ctc_tty_shuttingdown) return; @@ -497,7 +497,7 @@ ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count) c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE; if (c <= 0) break; - + skb_res = info->netdev->hard_header_len + sizeof(info->mcr) + + sizeof(__u32); skb = dev_alloc_skb(skb_res + c); @@ -828,7 +828,7 @@ ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info if (tty_hung_up_p(filp) || (info->flags & CTC_ASYNC_CLOSING)) { if (info->flags & CTC_ASYNC_CLOSING) - wait_event(info->close_wait, + wait_event(info->close_wait, !(info->flags & CTC_ASYNC_CLOSING)); #ifdef MODEM_DO_RESTART if (info->flags & CTC_ASYNC_HUP_NOTIFY) @@ -1247,7 +1247,7 @@ ctc_tty_unregister_netdev(struct net_device *dev) { void ctc_tty_cleanup(void) { unsigned long saveflags; - + DBF_TEXT(trace, 2, __FUNCTION__); spin_lock_irqsave(&ctc_tty_lock, saveflags); ctc_tty_shuttingdown = 1; diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c index e965f03a7..b12533104 100644 --- a/drivers/s390/net/cu3088.c +++ b/drivers/s390/net/cu3088.c @@ -20,7 +20,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ - + #include #include #include @@ -77,7 +77,7 @@ group_write(struct device_driver *drv, const char *buf, size_t count) int len; if (!(end = strchr(start, delim[i]))) - return -EINVAL; + return count; len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start + 1); strlcpy (bus_ids[i], start, len); argv[i] = bus_ids[i]; @@ -94,7 +94,7 @@ static DRIVER_ATTR(group, 0200, NULL, group_write); /* Register-unregister for ctc&lcs */ int -register_cu3088_discipline(struct ccwgroup_driver *dcp) +register_cu3088_discipline(struct ccwgroup_driver *dcp) { int rc; @@ -109,7 +109,7 @@ register_cu3088_discipline(struct ccwgroup_driver *dcp) rc = driver_create_file(&dcp->driver, &driver_attr_group); if (rc) ccwgroup_driver_unregister(dcp); - + return rc; } @@ -137,7 +137,7 @@ static int __init cu3088_init (void) { int rc; - + cu3088_root_dev = s390_root_dev_register("cu3088"); if (IS_ERR(cu3088_root_dev)) return PTR_ERR(cu3088_root_dev); diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c index 7145e2134..6caf5fa6a 100644 --- a/drivers/s390/net/fsm.c +++ b/drivers/s390/net/fsm.c @@ -21,34 +21,38 @@ init_fsm(char *name, const char **state_names, const char **event_names, int nr_ fsm_function_t *m; fsm *f; - this = kzalloc(sizeof(fsm_instance), order); + this = (fsm_instance *)kmalloc(sizeof(fsm_instance), order); if (this == NULL) { printk(KERN_WARNING "fsm(%s): init_fsm: Couldn't alloc instance\n", name); return NULL; } + memset(this, 0, sizeof(fsm_instance)); strlcpy(this->name, name, sizeof(this->name)); - f = kzalloc(sizeof(fsm), order); + f = (fsm *)kmalloc(sizeof(fsm), order); if (f == NULL) { printk(KERN_WARNING "fsm(%s): init_fsm: Couldn't alloc fsm\n", name); kfree_fsm(this); return NULL; } + memset(f, 0, sizeof(fsm)); f->nr_events = nr_events; f->nr_states = nr_states; f->event_names = event_names; f->state_names = state_names; this->f = f; - m = kcalloc(nr_states*nr_events, sizeof(fsm_function_t), order); + m = (fsm_function_t *)kmalloc( + sizeof(fsm_function_t) * nr_states * nr_events, order); if (m == NULL) { printk(KERN_WARNING "fsm(%s): init_fsm: Couldn't alloc jumptable\n", name); kfree_fsm(this); return NULL; } + memset(m, 0, sizeof(fsm_function_t) * f->nr_states * f->nr_events); f->jumpmatrix = m; for (i = 0; i < tmpl_len; i++) { diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c index e0c7deb98..760e77ec5 100644 --- a/drivers/s390/net/iucv.c +++ b/drivers/s390/net/iucv.c @@ -1,4 +1,4 @@ -/* +/* * IUCV network driver * * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation @@ -28,7 +28,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ - + /* #define DEBUG */ #include @@ -81,7 +81,7 @@ iucv_bus_match (struct device *dev, struct device_driver *drv) struct bus_type iucv_bus = { .name = "iucv", .match = iucv_bus_match, -}; +}; struct device *iucv_root; @@ -297,7 +297,7 @@ MODULE_LICENSE("GPL"); /* * Debugging stuff *******************************************************************************/ - + #ifdef DEBUG static int debuglevel = 0; @@ -344,7 +344,7 @@ do { \ /* * Internal functions *******************************************************************************/ - + /** * print start banner */ @@ -386,7 +386,7 @@ iucv_init(void) } /* Note: GFP_DMA used used to get memory below 2G */ - iucv_external_int_buffer = kzalloc(sizeof(iucv_GeneralInterrupt), + iucv_external_int_buffer = kmalloc(sizeof(iucv_GeneralInterrupt), GFP_KERNEL|GFP_DMA); if (!iucv_external_int_buffer) { printk(KERN_WARNING @@ -396,9 +396,10 @@ iucv_init(void) bus_unregister(&iucv_bus); return -ENOMEM; } + memset(iucv_external_int_buffer, 0, sizeof(iucv_GeneralInterrupt)); /* Initialize parameter pool */ - iucv_param_pool = kzalloc(sizeof(iucv_param) * PARAM_POOL_SIZE, + iucv_param_pool = kmalloc(sizeof(iucv_param) * PARAM_POOL_SIZE, GFP_KERNEL|GFP_DMA); if (!iucv_param_pool) { printk(KERN_WARNING "%s: Could not allocate param pool\n", @@ -409,6 +410,7 @@ iucv_init(void) bus_unregister(&iucv_bus); return -ENOMEM; } + memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE); /* Initialize irq queue */ INIT_LIST_HEAD(&iucv_irq_queue); @@ -791,14 +793,15 @@ iucv_register_program (__u8 pgmname[16], } max_connections = iucv_query_maxconn(); - iucv_pathid_table = kcalloc(max_connections, sizeof(handler *), - GFP_ATOMIC); + iucv_pathid_table = kmalloc(max_connections * sizeof(handler *), + GFP_ATOMIC); if (iucv_pathid_table == NULL) { printk(KERN_WARNING "%s: iucv_pathid_table storage " "allocation failed\n", __FUNCTION__); kfree(new_handler); return NULL; } + memset (iucv_pathid_table, 0, max_connections * sizeof(handler *)); } memset(new_handler, 0, sizeof (handler)); memcpy(new_handler->id.user_data, pgmname, @@ -810,7 +813,7 @@ iucv_register_program (__u8 pgmname[16], sizeof (new_handler->id.userid)); EBC_TOUPPER (new_handler->id.userid, sizeof (new_handler->id.userid)); - + if (pgmmask) { memcpy (new_handler->id.mask, pgmmask, sizeof (new_handler->id.mask)); @@ -1229,7 +1232,7 @@ iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit) /* parm->ipaudit has only 3 bytes */ *audit >>= 8; } - + release_param(parm); iucv_debug(1, "b2f0_result = %ld", b2f0_result); @@ -2330,14 +2333,14 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) temp_buff1[j] &= (h->id.mask)[j]; temp_buff2[j] &= (h->id.mask)[j]; } - + iucv_dumpit("temp_buff1:", temp_buff1, sizeof(temp_buff1)); iucv_dumpit("temp_buff2", temp_buff2, sizeof(temp_buff2)); - + if (!memcmp (temp_buff1, temp_buff2, 24)) { - + iucv_debug(2, "found a matching handler"); break; @@ -2368,7 +2371,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) } else iucv_sever(int_buf->ippathid, no_listener); break; - + case 0x02: /*connection complete */ if (messagesDisabled) { iucv_setmask(~0); @@ -2387,7 +2390,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) } else iucv_sever(int_buf->ippathid, no_listener); break; - + case 0x03: /* connection severed */ if (messagesDisabled) { iucv_setmask(~0); @@ -2398,13 +2401,13 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) interrupt->ConnectionSevered( (iucv_ConnectionSevered *)int_buf, h->pgm_data); - + else iucv_sever (int_buf->ippathid, no_listener); } else iucv_sever(int_buf->ippathid, no_listener); break; - + case 0x04: /* connection quiesced */ if (messagesDisabled) { iucv_setmask(~0); @@ -2420,7 +2423,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) "ConnectionQuiesced not called"); } break; - + case 0x05: /* connection resumed */ if (messagesDisabled) { iucv_setmask(~0); @@ -2436,7 +2439,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) "ConnectionResumed not called"); } break; - + case 0x06: /* priority message complete */ case 0x07: /* nonpriority message complete */ if (h) { @@ -2449,7 +2452,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) "MessageComplete not called"); } break; - + case 0x08: /* priority message pending */ case 0x09: /* nonpriority message pending */ if (h) { @@ -2467,7 +2470,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) __FUNCTION__); break; } /* end switch */ - + iucv_debug(2, "exiting pathid %d, type %02X", int_buf->ippathid, int_buf->iptype); diff --git a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h index 5b6b1b724..0c4644d3d 100644 --- a/drivers/s390/net/iucv.h +++ b/drivers/s390/net/iucv.h @@ -4,7 +4,7 @@ * * S390 version * Copyright (C) 2000 IBM Corporation - * Author(s):Alan Altmark (Alan_Altmark@us.ibm.com) + * Author(s):Alan Altmark (Alan_Altmark@us.ibm.com) * Xenia Tkatschow (xenia@us.ibm.com) * * @@ -16,17 +16,17 @@ * CP Programming Services book, also available on the web * thru www.ibm.com/s390/vm/pubs, manual # SC24-5760 * - * Definition of Return Codes - * -All positive return codes including zero are reflected back - * from CP except for iucv_register_program. The definition of each - * return code can be found in CP Programming Services book. - * Also available on the web thru www.ibm.com/s390/vm/pubs, manual # SC24-5760 - * - Return Code of: - * (-EINVAL) Invalid value - * (-ENOMEM) storage allocation failed + * Definition of Return Codes + * -All positive return codes including zero are reflected back + * from CP except for iucv_register_program. The definition of each + * return code can be found in CP Programming Services book. + * Also available on the web thru www.ibm.com/s390/vm/pubs, manual # SC24-5760 + * - Return Code of: + * (-EINVAL) Invalid value + * (-ENOMEM) storage allocation failed * pgmask defined in iucv_register_program will be set depending on input - * paramters. - * + * paramters. + * */ #include @@ -124,13 +124,13 @@ iucv_hex_dump(unsigned char *buf, size_t len) #define iucv_handle_t void * /* flags1: - * All flags are defined in the field IPFLAGS1 of each function - * and can be found in CP Programming Services. - * IPLOCAL - Indicates the connect can only be satisfied on the - * local system - * IPPRTY - Indicates a priority message - * IPQUSCE - Indicates you do not want to receive messages on a - * path until an iucv_resume is issued + * All flags are defined in the field IPFLAGS1 of each function + * and can be found in CP Programming Services. + * IPLOCAL - Indicates the connect can only be satisfied on the + * local system + * IPPRTY - Indicates a priority message + * IPQUSCE - Indicates you do not want to receive messages on a + * path until an iucv_resume is issued * IPRMDATA - Indicates that the message is in the parameter list */ #define IPLOCAL 0x01 @@ -154,14 +154,14 @@ iucv_hex_dump(unsigned char *buf, size_t len) #define AllInterrupts 0xf8 /* * Mapping of external interrupt buffers should be used with the corresponding - * interrupt types. - * Names: iucv_ConnectionPending -> connection pending + * interrupt types. + * Names: iucv_ConnectionPending -> connection pending * iucv_ConnectionComplete -> connection complete - * iucv_ConnectionSevered -> connection severed - * iucv_ConnectionQuiesced -> connection quiesced - * iucv_ConnectionResumed -> connection resumed - * iucv_MessagePending -> message pending - * iucv_MessageComplete -> message complete + * iucv_ConnectionSevered -> connection severed + * iucv_ConnectionQuiesced -> connection quiesced + * iucv_ConnectionResumed -> connection resumed + * iucv_MessagePending -> message pending + * iucv_MessageComplete -> message complete */ typedef struct { u16 ippathid; @@ -260,16 +260,16 @@ typedef struct { uchar res2[3]; } iucv_MessageComplete; -/* - * iucv_interrupt_ops_t: Is a vector of functions that handle - * IUCV interrupts. - * Parameter list: - * eib - is a pointer to a 40-byte area described - * with one of the structures above. - * pgm_data - this data is strictly for the - * interrupt handler that is passed by - * the application. This may be an address - * or token. +/* + * iucv_interrupt_ops_t: Is a vector of functions that handle + * IUCV interrupts. + * Parameter list: + * eib - is a pointer to a 40-byte area described + * with one of the structures above. + * pgm_data - this data is strictly for the + * interrupt handler that is passed by + * the application. This may be an address + * or token. */ typedef struct { void (*ConnectionPending) (iucv_ConnectionPending * eib, @@ -287,8 +287,8 @@ typedef struct { } iucv_interrupt_ops_t; /* - *iucv_array_t : Defines buffer array. - * Inside the array may be 31- bit addresses and 31-bit lengths. + *iucv_array_t : Defines buffer array. + * Inside the array may be 31- bit addresses and 31-bit lengths. */ typedef struct { u32 address; @@ -299,19 +299,19 @@ extern struct bus_type iucv_bus; extern struct device *iucv_root; /* -prototypes- */ -/* - * Name: iucv_register_program - * Purpose: Registers an application with IUCV - * Input: prmname - user identification +/* + * Name: iucv_register_program + * Purpose: Registers an application with IUCV + * Input: prmname - user identification * userid - machine identification * pgmmask - indicates which bits in the prmname and userid combined will be * used to determine who is given control - * ops - address of vector of interrupt handlers - * pgm_data- application data passed to interrupt handlers - * Output: NA - * Return: address of handler + * ops - address of vector of interrupt handlers + * pgm_data- application data passed to interrupt handlers + * Output: NA + * Return: address of handler * (0) - Error occurred, registration not completed. - * NOTE: Exact cause of failure will be recorded in syslog. + * NOTE: Exact cause of failure will be recorded in syslog. */ iucv_handle_t iucv_register_program (uchar pgmname[16], uchar userid[8], @@ -319,13 +319,13 @@ iucv_handle_t iucv_register_program (uchar pgmname[16], iucv_interrupt_ops_t * ops, void *pgm_data); -/* - * Name: iucv_unregister_program - * Purpose: Unregister application with IUCV - * Input: address of handler - * Output: NA - * Return: (0) - Normal return - * (-EINVAL) - Internal error, wild pointer +/* + * Name: iucv_unregister_program + * Purpose: Unregister application with IUCV + * Input: address of handler + * Output: NA + * Return: (0) - Normal return + * (-EINVAL) - Internal error, wild pointer */ int iucv_unregister_program (iucv_handle_t handle); @@ -333,7 +333,7 @@ int iucv_unregister_program (iucv_handle_t handle); * Name: iucv_accept * Purpose: This function is issued after the user receives a Connection Pending external * interrupt and now wishes to complete the IUCV communication path. - * Input: pathid - u16 , Path identification number + * Input: pathid - u16 , Path identification number * msglim_reqstd - u16, The number of outstanding messages requested. * user_data - uchar[16], Data specified by the iucv_connect function. * flags1 - int, Contains options for this path. @@ -358,34 +358,34 @@ int iucv_accept (u16 pathid, void *pgm_data, int *flags1_out, u16 * msglim); /* - * Name: iucv_connect + * Name: iucv_connect * Purpose: This function establishes an IUCV path. Although the connect may complete - * successfully, you are not able to use the path until you receive an IUCV - * Connection Complete external interrupt. - * Input: pathid - u16 *, Path identification number - * msglim_reqstd - u16, Number of outstanding messages requested - * user_data - uchar[16], 16-byte user data + * successfully, you are not able to use the path until you receive an IUCV + * Connection Complete external interrupt. + * Input: pathid - u16 *, Path identification number + * msglim_reqstd - u16, Number of outstanding messages requested + * user_data - uchar[16], 16-byte user data * userid - uchar[8], User identification - * system_name - uchar[8], 8-byte identifying the system name + * system_name - uchar[8], 8-byte identifying the system name * flags1 - int, Contains options for this path. * -IPPRTY - 0x20, Specifies if you want to send priority message. * -IPRMDATA - 0x80, Specifies whether your program can handle a message * in the parameter list. - * -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being + * -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being * established. - * -IPLOCAL - 0X01, Allows an application to force the partner to be on + * -IPLOCAL - 0X01, Allows an application to force the partner to be on * the local system. If local is specified then target class cannot be - * specified. + * specified. * flags1_out - int * Contains information about the path * - IPPRTY - 0x20, Indicates you may send priority messages. * msglim - * u16, Number of outstanding messages - * handle - iucv_handle_t, Address of handler - * pgm_data - void *, Application data passed to interrupt handlers + * handle - iucv_handle_t, Address of handler + * pgm_data - void *, Application data passed to interrupt handlers * Output: return code from CP IUCV call * rc - return code from iucv_declare_buffer - * -EINVAL - Invalid handle passed by application - * -EINVAL - Pathid address is NULL - * add_pathid_result - Return code from internal function add_pathid + * -EINVAL - Invalid handle passed by application + * -EINVAL - Pathid address is NULL + * add_pathid_result - Return code from internal function add_pathid */ int iucv_connect (u16 * pathid, @@ -397,16 +397,16 @@ int int *flags1_out, u16 * msglim, iucv_handle_t handle, void *pgm_data); -/* - * Name: iucv_purge - * Purpose: This function cancels a message that you have sent. - * Input: pathid - Path identification number. +/* + * Name: iucv_purge + * Purpose: This function cancels a message that you have sent. + * Input: pathid - Path identification number. * msgid - Specifies the message ID of the message to be purged. - * srccls - Specifies the source message class. - * Output: audit - Contains information about asynchronous error - * that may have affected the normal completion - * of this message. - * Return: Return code from CP IUCV call. + * srccls - Specifies the source message class. + * Output: audit - Contains information about asynchronous error + * that may have affected the normal completion + * of this message. + * Return: Return code from CP IUCV call. */ int iucv_purge (u16 pathid, u32 msgid, u32 srccls, __u32 *audit); /* @@ -426,38 +426,38 @@ ulong iucv_query_maxconn (void); */ ulong iucv_query_bufsize (void); -/* - * Name: iucv_quiesce - * Purpose: This function temporarily suspends incoming messages on an - * IUCV path. You can later reactivate the path by invoking - * the iucv_resume function. - * Input: pathid - Path identification number - * user_data - 16-bytes of user data - * Output: NA - * Return: Return code from CP IUCV call. +/* + * Name: iucv_quiesce + * Purpose: This function temporarily suspends incoming messages on an + * IUCV path. You can later reactivate the path by invoking + * the iucv_resume function. + * Input: pathid - Path identification number + * user_data - 16-bytes of user data + * Output: NA + * Return: Return code from CP IUCV call. */ int iucv_quiesce (u16 pathid, uchar user_data[16]); -/* - * Name: iucv_receive - * Purpose: This function receives messages that are being sent to you +/* + * Name: iucv_receive + * Purpose: This function receives messages that are being sent to you * over established paths. Data will be returned in buffer for length of * buflen. - * Input: - * pathid - Path identification number. - * buffer - Address of buffer to receive. - * buflen - Length of buffer to receive. - * msgid - Specifies the message ID. - * trgcls - Specifies target class. - * Output: + * Input: + * pathid - Path identification number. + * buffer - Address of buffer to receive. + * buflen - Length of buffer to receive. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * Output: * flags1_out: int *, Contains information about this path. * IPNORPY - 0x10 Specifies this is a one-way message and no reply is - * expected. - * IPPRTY - 0x20 Specifies if you want to send priority message. + * expected. + * IPPRTY - 0x20 Specifies if you want to send priority message. * IPRMDATA - 0x80 specifies the data is contained in the parameter list * residual_buffer - address of buffer updated by the number * of bytes you have received. - * residual_length - + * residual_length - * Contains one of the following values, if the receive buffer is: * The same length as the message, this field is zero. * Longer than the message, this field contains the number of @@ -466,8 +466,8 @@ int iucv_quiesce (u16 pathid, uchar user_data[16]); * count (that is, the number of bytes remaining in the * message that does not fit into the buffer. In this * case b2f0_result = 5. - * Return: Return code from CP IUCV call. - * (-EINVAL) - buffer address is pointing to NULL + * Return: Return code from CP IUCV call. + * (-EINVAL) - buffer address is pointing to NULL */ int iucv_receive (u16 pathid, u32 msgid, @@ -477,16 +477,16 @@ int iucv_receive (u16 pathid, int *flags1_out, ulong * residual_buffer, ulong * residual_length); - /* - * Name: iucv_receive_array - * Purpose: This function receives messages that are being sent to you + /* + * Name: iucv_receive_array + * Purpose: This function receives messages that are being sent to you * over established paths. Data will be returned in first buffer for * length of first buffer. - * Input: pathid - Path identification number. + * Input: pathid - Path identification number. * msgid - specifies the message ID. * trgcls - Specifies target class. - * buffer - Address of array of buffers. - * buflen - Total length of buffers. + * buffer - Address of array of buffers. + * buflen - Total length of buffers. * Output: * flags1_out: int *, Contains information about this path. * IPNORPY - 0x10 Specifies this is a one-way message and no reply is @@ -504,8 +504,8 @@ int iucv_receive (u16 pathid, * count (that is, the number of bytes remaining in the * message that does not fit into the buffer. In this * case b2f0_result = 5. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Buffer address is NULL. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. */ int iucv_receive_array (u16 pathid, u32 msgid, @@ -515,44 +515,44 @@ int iucv_receive_array (u16 pathid, int *flags1_out, ulong * residual_buffer, ulong * residual_length); -/* - * Name: iucv_reject - * Purpose: The reject function refuses a specified message. Between the - * time you are notified of a message and the time that you - * complete the message, the message may be rejected. - * Input: pathid - Path identification number. - * msgid - Specifies the message ID. - * trgcls - Specifies target class. - * Output: NA - * Return: Return code from CP IUCV call. +/* + * Name: iucv_reject + * Purpose: The reject function refuses a specified message. Between the + * time you are notified of a message and the time that you + * complete the message, the message may be rejected. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * Output: NA + * Return: Return code from CP IUCV call. */ int iucv_reject (u16 pathid, u32 msgid, u32 trgcls); -/* - * Name: iucv_reply - * Purpose: This function responds to the two-way messages that you - * receive. You must identify completely the message to - * which you wish to reply. ie, pathid, msgid, and trgcls. - * Input: pathid - Path identification number. - * msgid - Specifies the message ID. - * trgcls - Specifies target class. +/* + * Name: iucv_reply + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. * flags1 - Option for path. - * IPPRTY- 0x20, Specifies if you want to send priority message. - * buffer - Address of reply buffer. - * buflen - Length of reply buffer. - * Output: residual_buffer - Address of buffer updated by the number - * of bytes you have moved. + * IPPRTY- 0x20, Specifies if you want to send priority message. + * buffer - Address of reply buffer. + * buflen - Length of reply buffer. + * Output: residual_buffer - Address of buffer updated by the number + * of bytes you have moved. * residual_length - Contains one of the following values: * If the answer buffer is the same length as the reply, this field * contains zero. * If the answer buffer is longer than the reply, this field contains - * the number of bytes remaining in the buffer. + * the number of bytes remaining in the buffer. * If the answer buffer is shorter than the reply, this field contains * a residual count (that is, the number of bytes remianing in the * reply that does not fit into the buffer. In this * case b2f0_result = 5. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Buffer address is NULL. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. */ int iucv_reply (u16 pathid, u32 msgid, @@ -561,20 +561,20 @@ int iucv_reply (u16 pathid, void *buffer, ulong buflen, ulong * residual_buffer, ulong * residual_length); -/* - * Name: iucv_reply_array - * Purpose: This function responds to the two-way messages that you - * receive. You must identify completely the message to - * which you wish to reply. ie, pathid, msgid, and trgcls. - * The array identifies a list of addresses and lengths of - * discontiguous buffers that contains the reply data. - * Input: pathid - Path identification number - * msgid - Specifies the message ID. - * trgcls - Specifies target class. +/* + * Name: iucv_reply_array + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * The array identifies a list of addresses and lengths of + * discontiguous buffers that contains the reply data. + * Input: pathid - Path identification number + * msgid - Specifies the message ID. + * trgcls - Specifies target class. * flags1 - Option for path. * IPPRTY- 0x20, Specifies if you want to send priority message. - * buffer - Address of array of reply buffers. - * buflen - Total length of reply buffers. + * buffer - Address of array of reply buffers. + * buflen - Total length of reply buffers. * Output: residual_buffer - Address of buffer which IUCV is currently working on. * residual_length - Contains one of the following values: * If the answer buffer is the same length as the reply, this field @@ -585,8 +585,8 @@ int iucv_reply (u16 pathid, * a residual count (that is, the number of bytes remianing in the * reply that does not fit into the buffer. In this * case b2f0_result = 5. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Buffer address is NULL. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. */ int iucv_reply_array (u16 pathid, u32 msgid, @@ -596,77 +596,77 @@ int iucv_reply_array (u16 pathid, ulong buflen, ulong * residual_address, ulong * residual_length); -/* - * Name: iucv_reply_prmmsg - * Purpose: This function responds to the two-way messages that you - * receive. You must identify completely the message to - * which you wish to reply. ie, pathid, msgid, and trgcls. - * Prmmsg signifies the data is moved into the - * parameter list. - * Input: pathid - Path identification number. - * msgid - Specifies the message ID. - * trgcls - Specifies target class. +/* + * Name: iucv_reply_prmmsg + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Prmmsg signifies the data is moved into the + * parameter list. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. * flags1 - Option for path. * IPPRTY- 0x20 Specifies if you want to send priority message. - * prmmsg - 8-bytes of data to be placed into the parameter. - * list. - * Output: NA - * Return: Return code from CP IUCV call. + * prmmsg - 8-bytes of data to be placed into the parameter. + * list. + * Output: NA + * Return: Return code from CP IUCV call. */ int iucv_reply_prmmsg (u16 pathid, u32 msgid, u32 trgcls, int flags1, uchar prmmsg[8]); -/* - * Name: iucv_resume - * Purpose: This function restores communications over a quiesced path - * Input: pathid - Path identification number. - * user_data - 16-bytes of user data. - * Output: NA - * Return: Return code from CP IUCV call. +/* + * Name: iucv_resume + * Purpose: This function restores communications over a quiesced path + * Input: pathid - Path identification number. + * user_data - 16-bytes of user data. + * Output: NA + * Return: Return code from CP IUCV call. */ int iucv_resume (u16 pathid, uchar user_data[16]); -/* - * Name: iucv_send - * Purpose: This function transmits data to another application. - * Data to be transmitted is in a buffer and this is a - * one-way message and the receiver will not reply to the - * message. - * Input: pathid - Path identification number. - * trgcls - Specifies target class. - * srccls - Specifies the source message class. - * msgtag - Specifies a tag to be associated with the message. +/* + * Name: iucv_send + * Purpose: This function transmits data to another application. + * Data to be transmitted is in a buffer and this is a + * one-way message and the receiver will not reply to the + * message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. * flags1 - Option for path. * IPPRTY- 0x20 Specifies if you want to send priority message. - * buffer - Address of send buffer. - * buflen - Length of send buffer. - * Output: msgid - Specifies the message ID. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Buffer address is NULL. + * buffer - Address of send buffer. + * buflen - Length of send buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. */ int iucv_send (u16 pathid, u32 * msgid, u32 trgcls, u32 srccls, u32 msgtag, int flags1, void *buffer, ulong buflen); -/* - * Name: iucv_send_array - * Purpose: This function transmits data to another application. - * The contents of buffer is the address of the array of - * addresses and lengths of discontiguous buffers that hold - * the message text. This is a one-way message and the - * receiver will not reply to the message. - * Input: pathid - Path identification number. - * trgcls - Specifies target class. - * srccls - Specifies the source message class. +/* + * Name: iucv_send_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. * msgtag - Specifies a tag to be associated witht the message. * flags1 - Option for path. - * IPPRTY- specifies if you want to send priority message. - * buffer - Address of array of send buffers. - * buflen - Total length of send buffers. - * Output: msgid - Specifies the message ID. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Buffer address is NULL. + * IPPRTY- specifies if you want to send priority message. + * buffer - Address of array of send buffers. + * buflen - Total length of send buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. */ int iucv_send_array (u16 pathid, u32 * msgid, @@ -675,48 +675,48 @@ int iucv_send_array (u16 pathid, u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen); -/* - * Name: iucv_send_prmmsg - * Purpose: This function transmits data to another application. - * Prmmsg specifies that the 8-bytes of data are to be moved - * into the parameter list. This is a one-way message and the - * receiver will not reply to the message. - * Input: pathid - Path identification number. - * trgcls - Specifies target class. - * srccls - Specifies the source message class. - * msgtag - Specifies a tag to be associated with the message. +/* + * Name: iucv_send_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. * flags1 - Option for path. * IPPRTY- 0x20 specifies if you want to send priority message. - * prmmsg - 8-bytes of data to be placed into parameter list. - * Output: msgid - Specifies the message ID. - * Return: Return code from CP IUCV call. + * prmmsg - 8-bytes of data to be placed into parameter list. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. */ int iucv_send_prmmsg (u16 pathid, u32 * msgid, u32 trgcls, u32 srccls, u32 msgtag, int flags1, uchar prmmsg[8]); -/* - * Name: iucv_send2way - * Purpose: This function transmits data to another application. - * Data to be transmitted is in a buffer. The receiver - * of the send is expected to reply to the message and - * a buffer is provided into which IUCV moves the reply - * to this message. - * Input: pathid - Path identification number. - * trgcls - Specifies target class. - * srccls - Specifies the source message class. - * msgtag - Specifies a tag associated with the message. +/* + * Name: iucv_send2way + * Purpose: This function transmits data to another application. + * Data to be transmitted is in a buffer. The receiver + * of the send is expected to reply to the message and + * a buffer is provided into which IUCV moves the reply + * to this message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag associated with the message. * flags1 - Option for path. * IPPRTY- 0x20 Specifies if you want to send priority message. - * buffer - Address of send buffer. - * buflen - Length of send buffer. - * ansbuf - Address of buffer into which IUCV moves the reply of - * this message. - * anslen - Address of length of buffer. - * Output: msgid - Specifies the message ID. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Buffer or ansbuf address is NULL. + * buffer - Address of send buffer. + * buflen - Length of send buffer. + * ansbuf - Address of buffer into which IUCV moves the reply of + * this message. + * anslen - Address of length of buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer or ansbuf address is NULL. */ int iucv_send2way (u16 pathid, u32 * msgid, @@ -726,28 +726,28 @@ int iucv_send2way (u16 pathid, int flags1, void *buffer, ulong buflen, void *ansbuf, ulong anslen); -/* - * Name: iucv_send2way_array - * Purpose: This function transmits data to another application. - * The contents of buffer is the address of the array of - * addresses and lengths of discontiguous buffers that hold - * the message text. The receiver of the send is expected to - * reply to the message and a buffer is provided into which - * IUCV moves the reply to this message. - * Input: pathid - Path identification number. - * trgcls - Specifies target class. - * srccls - Specifies the source message class. - * msgtag - Specifies a tag to be associated with the message. +/* + * Name: iucv_send2way_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. The receiver of the send is expected to + * reply to the message and a buffer is provided into which + * IUCV moves the reply to this message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. * flags1 - Option for path. * IPPRTY- 0x20 Specifies if you want to send priority message. - * buffer - Sddress of array of send buffers. - * buflen - Total length of send buffers. - * ansbuf - Address of array of buffer into which IUCV moves the reply - * of this message. - * anslen - Address of length reply buffers. - * Output: msgid - Specifies the message ID. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Buffer address is NULL. + * buffer - Sddress of array of send buffers. + * buflen - Total length of send buffers. + * ansbuf - Address of array of buffer into which IUCV moves the reply + * of this message. + * anslen - Address of length reply buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. */ int iucv_send2way_array (u16 pathid, u32 * msgid, @@ -758,27 +758,27 @@ int iucv_send2way_array (u16 pathid, iucv_array_t * buffer, ulong buflen, iucv_array_t * ansbuf, ulong anslen); -/* - * Name: iucv_send2way_prmmsg - * Purpose: This function transmits data to another application. - * Prmmsg specifies that the 8-bytes of data are to be moved - * into the parameter list. This is a two-way message and the - * receiver of the message is expected to reply. A buffer - * is provided into which IUCV moves the reply to this - * message. - * Input: pathid - Rath identification number. - * trgcls - Specifies target class. - * srccls - Specifies the source message class. - * msgtag - Specifies a tag to be associated with the message. +/* + * Name: iucv_send2way_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. + * Input: pathid - Rath identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. * flags1 - Option for path. * IPPRTY- 0x20 Specifies if you want to send priority message. - * prmmsg - 8-bytes of data to be placed in parameter list. - * ansbuf - Address of buffer into which IUCV moves the reply of + * prmmsg - 8-bytes of data to be placed in parameter list. + * ansbuf - Address of buffer into which IUCV moves the reply of * this message. - * anslen - Address of length of buffer. - * Output: msgid - Specifies the message ID. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Buffer address is NULL. + * anslen - Address of length of buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. */ int iucv_send2way_prmmsg (u16 pathid, u32 * msgid, @@ -788,29 +788,29 @@ int iucv_send2way_prmmsg (u16 pathid, ulong flags1, uchar prmmsg[8], void *ansbuf, ulong anslen); -/* - * Name: iucv_send2way_prmmsg_array - * Purpose: This function transmits data to another application. - * Prmmsg specifies that the 8-bytes of data are to be moved - * into the parameter list. This is a two-way message and the - * receiver of the message is expected to reply. A buffer - * is provided into which IUCV moves the reply to this - * message. The contents of ansbuf is the address of the - * array of addresses and lengths of discontiguous buffers - * that contain the reply. - * Input: pathid - Path identification number. - * trgcls - Specifies target class. - * srccls - Specifies the source message class. - * msgtag - Specifies a tag to be associated with the message. +/* + * Name: iucv_send2way_prmmsg_array + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. The contents of ansbuf is the address of the + * array of addresses and lengths of discontiguous buffers + * that contain the reply. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. * flags1 - Option for path. * IPPRTY- 0x20 specifies if you want to send priority message. - * prmmsg - 8-bytes of data to be placed into the parameter list. + * prmmsg - 8-bytes of data to be placed into the parameter list. * ansbuf - Address of array of buffer into which IUCV moves the reply - * of this message. - * anslen - Address of length of reply buffers. - * Output: msgid - Specifies the message ID. - * Return: Return code from CP IUCV call. - * (-EINVAL) - Ansbuf address is NULL. + * of this message. + * anslen - Address of length of reply buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Ansbuf address is NULL. */ int iucv_send2way_prmmsg_array (u16 pathid, u32 * msgid, @@ -821,29 +821,29 @@ int iucv_send2way_prmmsg_array (u16 pathid, uchar prmmsg[8], iucv_array_t * ansbuf, ulong anslen); -/* - * Name: iucv_setmask - * Purpose: This function enables or disables the following IUCV - * external interruptions: Nonpriority and priority message - * interrupts, nonpriority and priority reply interrupts. +/* + * Name: iucv_setmask + * Purpose: This function enables or disables the following IUCV + * external interruptions: Nonpriority and priority message + * interrupts, nonpriority and priority reply interrupts. * Input: SetMaskFlag - options for interrupts - * 0x80 - Nonpriority_MessagePendingInterruptsFlag - * 0x40 - Priority_MessagePendingInterruptsFlag - * 0x20 - Nonpriority_MessageCompletionInterruptsFlag - * 0x10 - Priority_MessageCompletionInterruptsFlag + * 0x80 - Nonpriority_MessagePendingInterruptsFlag + * 0x40 - Priority_MessagePendingInterruptsFlag + * 0x20 - Nonpriority_MessageCompletionInterruptsFlag + * 0x10 - Priority_MessageCompletionInterruptsFlag * 0x08 - IUCVControlInterruptsFlag - * Output: NA - * Return: Return code from CP IUCV call. + * Output: NA + * Return: Return code from CP IUCV call. */ int iucv_setmask (int SetMaskFlag); -/* - * Name: iucv_sever - * Purpose: This function terminates an IUCV path. - * Input: pathid - Path identification number. - * user_data - 16-bytes of user data. - * Output: NA - * Return: Return code from CP IUCV call. - * (-EINVAL) - Interal error, wild pointer. +/* + * Name: iucv_sever + * Purpose: This function terminates an IUCV path. + * Input: pathid - Path identification number. + * user_data - 16-bytes of user data. + * Output: NA + * Return: Return code from CP IUCV call. + * (-EINVAL) - Interal error, wild pointer. */ int iucv_sever (u16 pathid, uchar user_data[16]); diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index f94419b33..9cf88d720 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -68,7 +68,6 @@ static void lcs_tasklet(unsigned long); static void lcs_start_kernel_thread(struct lcs_card *card); static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *); static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *); -static int lcs_recovery(void *ptr); /** * Debug Facility Stuff @@ -116,10 +115,11 @@ lcs_alloc_channel(struct lcs_channel *channel) LCS_DBF_TEXT(2, setup, "ichalloc"); for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) { /* alloc memory fo iobuffer */ - channel->iob[cnt].data = - kzalloc(LCS_IOBUFFERSIZE, GFP_DMA | GFP_KERNEL); + channel->iob[cnt].data = (void *) + kmalloc(LCS_IOBUFFERSIZE, GFP_DMA | GFP_KERNEL); if (channel->iob[cnt].data == NULL) break; + memset(channel->iob[cnt].data, 0, LCS_IOBUFFERSIZE); channel->iob[cnt].state = BUF_STATE_EMPTY; } if (cnt < LCS_NUM_BUFFS) { @@ -182,9 +182,10 @@ lcs_alloc_card(void) LCS_DBF_TEXT(2, setup, "alloclcs"); - card = kzalloc(sizeof(struct lcs_card), GFP_KERNEL | GFP_DMA); + card = kmalloc(sizeof(struct lcs_card), GFP_KERNEL | GFP_DMA); if (card == NULL) return NULL; + memset(card, 0, sizeof(struct lcs_card)); card->lan_type = LCS_FRAME_TYPE_AUTO; card->pkt_seq = 0; card->lancmd_timeout = LCS_LANCMD_TIMEOUT_DEFAULT; @@ -430,6 +431,12 @@ lcs_setup_card(struct lcs_card *card) card->tx_buffer = NULL; card->tx_emitted = 0; + /* Initialize kernel thread task used for LGW commands. */ + INIT_WORK(&card->kernel_thread_starter, + (void *)lcs_start_kernel_thread,card); + card->thread_start_mask = 0; + card->thread_allowed_mask = 0; + card->thread_running_mask = 0; init_waitqueue_head(&card->wait_q); spin_lock_init(&card->lock); spin_lock_init(&card->ipm_lock); @@ -786,9 +793,10 @@ lcs_alloc_reply(struct lcs_cmd *cmd) LCS_DBF_TEXT(4, trace, "getreply"); - reply = kzalloc(sizeof(struct lcs_reply), GFP_ATOMIC); + reply = kmalloc(sizeof(struct lcs_reply), GFP_ATOMIC); if (!reply) return NULL; + memset(reply,0,sizeof(struct lcs_reply)); atomic_set(&reply->refcnt,1); reply->sequence_no = cmd->sequence_no; reply->received = 0; @@ -1145,6 +1153,8 @@ list_modified: list_add_tail(&ipm->list, &card->ipm_list); } spin_unlock_irqrestore(&card->ipm_lock, flags); + if (card->state == DEV_STATE_UP) + netif_wake_queue(card->dev); } /** @@ -1227,17 +1237,17 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) if (ipm != NULL) continue; /* Address already in list. */ ipm = (struct lcs_ipm_list *) - kzalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC); + kmalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC); if (ipm == NULL) { PRINT_INFO("Not enough memory to add " "new multicast entry!\n"); break; } + memset(ipm, 0, sizeof(struct lcs_ipm_list)); memcpy(&ipm->ipm.mac_addr, buf, LCS_MAC_LENGTH); ipm->ipm.ip_addr = im4->multiaddr; ipm->ipm_state = LCS_IPM_STATE_SET_REQUIRED; spin_lock_irqsave(&card->ipm_lock, flags); - LCS_DBF_HEX(2,trace,&ipm->ipm.ip_addr,4); list_add(&ipm->list, &card->ipm_list); spin_unlock_irqrestore(&card->ipm_lock, flags); } @@ -1265,15 +1275,7 @@ lcs_register_mc_addresses(void *data) read_unlock(&in4_dev->mc_list_lock); in_dev_put(in4_dev); - netif_carrier_off(card->dev); - netif_tx_disable(card->dev); - wait_event(card->write.wait_q, - (card->write.state != CH_STATE_RUNNING)); lcs_fix_multicast_list(card); - if (card->state == DEV_STATE_UP) { - netif_carrier_on(card->dev); - netif_wake_queue(card->dev); - } out: lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD); return 0; @@ -1290,7 +1292,7 @@ lcs_set_multicast_list(struct net_device *dev) LCS_DBF_TEXT(4, trace, "setmulti"); card = (struct lcs_card *) dev->priv; - if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) + if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) schedule_work(&card->kernel_thread_starter); } @@ -1322,53 +1324,6 @@ lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb) return PTR_ERR(irb); } -static int -lcs_get_problem(struct ccw_device *cdev, struct irb *irb) -{ - int dstat, cstat; - char *sense; - - sense = (char *) irb->ecw; - cstat = irb->scsw.cstat; - dstat = irb->scsw.dstat; - - if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK | - SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK | - SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) { - LCS_DBF_TEXT(2, trace, "CGENCHK"); - return 1; - } - if (dstat & DEV_STAT_UNIT_CHECK) { - if (sense[LCS_SENSE_BYTE_1] & - LCS_SENSE_RESETTING_EVENT) { - LCS_DBF_TEXT(2, trace, "REVIND"); - return 1; - } - if (sense[LCS_SENSE_BYTE_0] & - LCS_SENSE_CMD_REJECT) { - LCS_DBF_TEXT(2, trace, "CMDREJ"); - return 0; - } - if ((!sense[LCS_SENSE_BYTE_0]) && - (!sense[LCS_SENSE_BYTE_1]) && - (!sense[LCS_SENSE_BYTE_2]) && - (!sense[LCS_SENSE_BYTE_3])) { - LCS_DBF_TEXT(2, trace, "ZEROSEN"); - return 0; - } - LCS_DBF_TEXT(2, trace, "DGENCHK"); - return 1; - } - return 0; -} - -void -lcs_schedule_recovery(struct lcs_card *card) -{ - LCS_DBF_TEXT(2, trace, "startrec"); - if (!lcs_set_thread_start_bit(card, LCS_RECOVERY_THREAD)) - schedule_work(&card->kernel_thread_starter); -} /** * IRQ Handler for LCS channels @@ -1378,8 +1333,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) { struct lcs_card *card; struct lcs_channel *channel; - int rc, index; - int cstat, dstat; + int index; if (lcs_check_irb_error(cdev, irb)) return; @@ -1390,30 +1344,17 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) else channel = &card->write; - cstat = irb->scsw.cstat; - dstat = irb->scsw.dstat; LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id); LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.cstat, irb->scsw.dstat); LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.fctl, irb->scsw.actl); - /* Check for channel and device errors presented */ - rc = lcs_get_problem(cdev, irb); - if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) { - PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n", - cdev->dev.bus_id, dstat, cstat); - if (rc) { - lcs_schedule_recovery(card); - wake_up(&card->wait_q); - return; - } - } /* How far in the ccw chain have we processed? */ if ((channel->state != CH_STATE_INIT) && (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) { - index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa) + index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa) - channel->ccws; if ((irb->scsw.actl & SCSW_ACTL_SUSPENDED) || - (irb->scsw.cstat & SCHN_STAT_PCI)) + (irb->scsw.cstat | SCHN_STAT_PCI)) /* Bloody io subsystem tells us lies about cpa... */ index = (index - 1) & (LCS_NUM_BUFFS - 1); while (channel->io_idx != index) { @@ -1432,6 +1373,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED) /* CCW execution stopped on a suspend bit. */ channel->state = CH_STATE_SUSPENDED; + if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) { if (irb->scsw.cc != 0) { ccw_device_halt(channel->ccwdev, (addr_t) channel); @@ -1440,6 +1382,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) /* The channel has been stopped by halt_IO. */ channel->state = CH_STATE_HALTED; } + if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { channel->state = CH_STATE_CLEARED; } @@ -1515,7 +1458,7 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) lcs_release_buffer(channel, buffer); card = (struct lcs_card *) ((char *) channel - offsetof(struct lcs_card, write)); - if (netif_queue_stopped(card->dev) && netif_carrier_ok(card->dev)) + if (netif_queue_stopped(card->dev)) netif_wake_queue(card->dev); spin_lock(&card->lock); card->tx_emitted--; @@ -1551,10 +1494,6 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, card->stats.tx_carrier_errors++; return 0; } - if (skb->protocol == htons(ETH_P_IPV6)) { - dev_kfree_skb(skb); - return 0; - } netif_stop_queue(card->dev); spin_lock(&card->lock); if (card->tx_buffer != NULL && @@ -1699,6 +1638,30 @@ lcs_detect(struct lcs_card *card) return rc; } +/** + * reset card + */ +static int +lcs_resetcard(struct lcs_card *card) +{ + int retries; + + LCS_DBF_TEXT(2, trace, "rescard"); + for (retries = 0; retries < 10; retries++) { + if (lcs_detect(card) == 0) { + netif_wake_queue(card->dev); + card->state = DEV_STATE_UP; + PRINT_INFO("LCS device %s successfully restarted!\n", + card->dev->name); + return 0; + } + msleep(3000); + } + PRINT_ERR("Error in Reseting LCS card!\n"); + return -EIO; +} + + /** * LCS Stop card */ @@ -1722,6 +1685,111 @@ lcs_stopcard(struct lcs_card *card) return rc; } +/** + * LGW initiated commands + */ +static int +lcs_lgw_startlan_thread(void *data) +{ + struct lcs_card *card; + + card = (struct lcs_card *) data; + daemonize("lgwstpln"); + + if (!lcs_do_run_thread(card, LCS_STARTLAN_THREAD)) + return 0; + LCS_DBF_TEXT(4, trace, "lgwstpln"); + if (card->dev) + netif_stop_queue(card->dev); + if (lcs_startlan(card) == 0) { + netif_wake_queue(card->dev); + card->state = DEV_STATE_UP; + PRINT_INFO("LCS Startlan for device %s succeeded!\n", + card->dev->name); + + } else + PRINT_ERR("LCS Startlan for device %s failed!\n", + card->dev->name); + lcs_clear_thread_running_bit(card, LCS_STARTLAN_THREAD); + return 0; +} + +/** + * Send startup command initiated by Lan Gateway + */ +static int +lcs_lgw_startup_thread(void *data) +{ + int rc; + + struct lcs_card *card; + + card = (struct lcs_card *) data; + daemonize("lgwstaln"); + + if (!lcs_do_run_thread(card, LCS_STARTUP_THREAD)) + return 0; + LCS_DBF_TEXT(4, trace, "lgwstaln"); + if (card->dev) + netif_stop_queue(card->dev); + rc = lcs_send_startup(card, LCS_INITIATOR_LGW); + if (rc != 0) { + PRINT_ERR("Startup for LCS device %s initiated " \ + "by LGW failed!\nReseting card ...\n", + card->dev->name); + /* do a card reset */ + rc = lcs_resetcard(card); + if (rc == 0) + goto Done; + } + rc = lcs_startlan(card); + if (rc == 0) { + netif_wake_queue(card->dev); + card->state = DEV_STATE_UP; + } +Done: + if (rc == 0) + PRINT_INFO("LCS Startup for device %s succeeded!\n", + card->dev->name); + else + PRINT_ERR("LCS Startup for device %s failed!\n", + card->dev->name); + lcs_clear_thread_running_bit(card, LCS_STARTUP_THREAD); + return 0; +} + + +/** + * send stoplan command initiated by Lan Gateway + */ +static int +lcs_lgw_stoplan_thread(void *data) +{ + struct lcs_card *card; + int rc; + + card = (struct lcs_card *) data; + daemonize("lgwstop"); + + if (!lcs_do_run_thread(card, LCS_STOPLAN_THREAD)) + return 0; + LCS_DBF_TEXT(4, trace, "lgwstop"); + if (card->dev) + netif_stop_queue(card->dev); + if (lcs_send_stoplan(card, LCS_INITIATOR_LGW) == 0) + PRINT_INFO("Stoplan for %s initiated by LGW succeeded!\n", + card->dev->name); + else + PRINT_ERR("Stoplan %s initiated by LGW failed!\n", + card->dev->name); + /*Try to reset the card, stop it on failure */ + rc = lcs_resetcard(card); + if (rc != 0) + rc = lcs_stopcard(card); + lcs_clear_thread_running_bit(card, LCS_STOPLAN_THREAD); + return rc; +} + /** * Kernel Thread helper functions for LGW initiated commands */ @@ -1729,12 +1797,15 @@ static void lcs_start_kernel_thread(struct lcs_card *card) { LCS_DBF_TEXT(5, trace, "krnthrd"); - if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD)) - kernel_thread(lcs_recovery, (void *) card, SIGCHLD); + if (lcs_do_start_thread(card, LCS_STARTUP_THREAD)) + kernel_thread(lcs_lgw_startup_thread, (void *) card, SIGCHLD); + if (lcs_do_start_thread(card, LCS_STARTLAN_THREAD)) + kernel_thread(lcs_lgw_startlan_thread, (void *) card, SIGCHLD); + if (lcs_do_start_thread(card, LCS_STOPLAN_THREAD)) + kernel_thread(lcs_lgw_stoplan_thread, (void *) card, SIGCHLD); #ifdef CONFIG_IP_MULTICAST if (lcs_do_start_thread(card, LCS_SET_MC_THREAD)) - kernel_thread(lcs_register_mc_addresses, - (void *) card, SIGCHLD); + kernel_thread(lcs_register_mc_addresses, (void *) card, SIGCHLD); #endif } @@ -1748,14 +1819,19 @@ lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd) if (cmd->initiator == LCS_INITIATOR_LGW) { switch(cmd->cmd_code) { case LCS_CMD_STARTUP: + if (!lcs_set_thread_start_bit(card, + LCS_STARTUP_THREAD)) + schedule_work(&card->kernel_thread_starter); + break; case LCS_CMD_STARTLAN: - lcs_schedule_recovery(card); + if (!lcs_set_thread_start_bit(card, + LCS_STARTLAN_THREAD)) + schedule_work(&card->kernel_thread_starter); break; case LCS_CMD_STOPLAN: - PRINT_WARN("Stoplan for %s initiated by LGW.\n", - card->dev->name); - if (card->dev) - netif_carrier_off(card->dev); + if (!lcs_set_thread_start_bit(card, + LCS_STOPLAN_THREAD)) + schedule_work(&card->kernel_thread_starter); break; default: PRINT_INFO("UNRECOGNIZED LGW COMMAND\n"); @@ -1871,11 +1947,8 @@ lcs_stop_device(struct net_device *dev) LCS_DBF_TEXT(2, trace, "stopdev"); card = (struct lcs_card *) dev->priv; - netif_carrier_off(dev); - netif_tx_disable(dev); + netif_stop_queue(dev); dev->flags &= ~IFF_UP; - wait_event(card->write.wait_q, - (card->write.state != CH_STATE_RUNNING)); rc = lcs_stopcard(card); if (rc) PRINT_ERR("Try it again!\n "); @@ -1901,7 +1974,6 @@ lcs_open_device(struct net_device *dev) } else { dev->flags |= IFF_UP; - netif_carrier_on(dev); netif_wake_queue(dev); card->state = DEV_STATE_UP; } @@ -1993,31 +2065,10 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store); -static ssize_t -lcs_dev_recover_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct lcs_card *card = dev->driver_data; - char *tmp; - int i; - - if (!card) - return -EINVAL; - if (card->state != DEV_STATE_UP) - return -EPERM; - i = simple_strtoul(buf, &tmp, 16); - if (i == 1) - lcs_schedule_recovery(card); - return count; -} - -static DEVICE_ATTR(recover, 0200, NULL, lcs_dev_recover_store); - static struct attribute * lcs_attrs[] = { &dev_attr_portno.attr, &dev_attr_type.attr, &dev_attr_lancmd_timeout.attr, - &dev_attr_recover.attr, NULL, }; @@ -2054,12 +2105,6 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) ccwgdev->dev.driver_data = card; ccwgdev->cdev[0]->handler = lcs_irq; ccwgdev->cdev[1]->handler = lcs_irq; - card->gdev = ccwgdev; - INIT_WORK(&card->kernel_thread_starter, - (void *) lcs_start_kernel_thread, card); - card->thread_start_mask = 0; - card->thread_allowed_mask = 0; - card->thread_running_mask = 0; return 0; } @@ -2161,7 +2206,6 @@ netdev_out: if (recover_state == DEV_STATE_RECOVER) { lcs_set_multicast_list(card->dev); card->dev->flags |= IFF_UP; - netif_carrier_on(card->dev); netif_wake_queue(card->dev); card->state = DEV_STATE_UP; } else { @@ -2191,7 +2235,7 @@ out: * lcs_shutdown_device, called when setting the group device offline. */ static int -__lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode) +lcs_shutdown_device(struct ccwgroup_device *ccwgdev) { struct lcs_card *card; enum lcs_dev_states recover_state; @@ -2201,11 +2245,9 @@ __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode) card = (struct lcs_card *)ccwgdev->dev.driver_data; if (!card) return -ENODEV; - if (recovery_mode == 0) { - lcs_set_allowed_threads(card, 0); - if (lcs_wait_for_threads(card, LCS_SET_MC_THREAD)) - return -ERESTARTSYS; - } + lcs_set_allowed_threads(card, 0); + if (lcs_wait_for_threads(card, LCS_SET_MC_THREAD)) + return -ERESTARTSYS; LCS_DBF_HEX(3, setup, &card, sizeof(void*)); recover_state = card->state; @@ -2220,43 +2262,6 @@ __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode) return 0; } -static int -lcs_shutdown_device(struct ccwgroup_device *ccwgdev) -{ - return __lcs_shutdown_device(ccwgdev, 0); -} - -/** - * drive lcs recovery after startup and startlan initiated by Lan Gateway - */ -static int -lcs_recovery(void *ptr) -{ - struct lcs_card *card; - struct ccwgroup_device *gdev; - int rc; - - card = (struct lcs_card *) ptr; - daemonize("lcs_recover"); - - LCS_DBF_TEXT(4, trace, "recover1"); - if (!lcs_do_run_thread(card, LCS_RECOVERY_THREAD)) - return 0; - LCS_DBF_TEXT(4, trace, "recover2"); - gdev = card->gdev; - PRINT_WARN("Recovery of device %s started...\n", gdev->dev.bus_id); - rc = __lcs_shutdown_device(gdev, 1); - rc = lcs_new_device(gdev); - if (!rc) - PRINT_INFO("Device %s successfully recovered!\n", - card->dev->name); - else - PRINT_INFO("Device %s could not be recovered!\n", - card->dev->name); - lcs_clear_thread_running_bit(card, LCS_RECOVERY_THREAD); - return 0; -} - /** * lcs_remove_device, free buffers and card */ diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h index 931439329..2fad5e40c 100644 --- a/drivers/s390/net/lcs.h +++ b/drivers/s390/net/lcs.h @@ -73,17 +73,13 @@ do { \ /** * LCS sense byte definitions */ -#define LCS_SENSE_BYTE_0 0 -#define LCS_SENSE_BYTE_1 1 -#define LCS_SENSE_BYTE_2 2 -#define LCS_SENSE_BYTE_3 3 #define LCS_SENSE_INTERFACE_DISCONNECT 0x01 #define LCS_SENSE_EQUIPMENT_CHECK 0x10 #define LCS_SENSE_BUS_OUT_CHECK 0x20 #define LCS_SENSE_INTERVENTION_REQUIRED 0x40 #define LCS_SENSE_CMD_REJECT 0x80 -#define LCS_SENSE_RESETTING_EVENT 0x80 -#define LCS_SENSE_DEVICE_ONLINE 0x20 +#define LCS_SENSE_RESETTING_EVENT 0x0080 +#define LCS_SENSE_DEVICE_ONLINE 0x0020 /** * LCS packet type definitions @@ -156,9 +152,10 @@ enum lcs_dev_states { enum lcs_threads { LCS_SET_MC_THREAD = 1, - LCS_RECOVERY_THREAD = 2, + LCS_STARTLAN_THREAD = 2, + LCS_STOPLAN_THREAD = 4, + LCS_STARTUP_THREAD = 8, }; - /** * LCS struct declarations */ @@ -289,7 +286,6 @@ struct lcs_card { struct net_device_stats stats; unsigned short (*lan_type_trans)(struct sk_buff *skb, struct net_device *dev); - struct ccwgroup_device *gdev; struct lcs_channel read; struct lcs_channel write; struct lcs_buffer *tx_buffer; diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index b452cc1af..71d3853e8 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -30,7 +30,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ - + #undef DEBUG #include @@ -65,7 +65,7 @@ MODULE_AUTHOR ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); - + #define PRINTK_HEADER " iucv: " /* for debugging */ static struct device_driver netiucv_driver = { @@ -202,7 +202,7 @@ netiucv_printname(char *name) *p = '\0'; return tmp; } - + /** * States of the interface statemachine. */ @@ -244,7 +244,7 @@ static const char *dev_event_names[] = { "Connection up", "Connection down", }; - + /** * Events of the connection statemachine */ @@ -364,7 +364,7 @@ static const char *conn_state_names[] = { "Connect error", }; - + /** * Debug Facility Stuff */ @@ -516,7 +516,7 @@ static void fsm_action_nop(fsm_instance *fi, int event, void *arg) { } - + /** * Actions of the connection statemachine *****************************************************************************/ @@ -993,7 +993,7 @@ static const fsm_node conn_fsm[] = { static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); - + /** * Actions for interface - statemachine. *****************************************************************************/ @@ -1182,7 +1182,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) { fsm_newstate(conn->fsm, CONN_STATE_TX); conn->prof.send_stamp = xtime; - + rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */, 0, nskb->data, nskb->len); /* Shut up, gcc! nskb is always below 2G. */ @@ -1220,7 +1220,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) { return rc; } - + /** * Interface API for upper network layers *****************************************************************************/ @@ -1291,7 +1291,7 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) /** * If connection is not running, try to restart it - * and throw away packet. + * and throw away packet. */ if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { fsm_event(privptr->fsm, DEV_EVENT_START, dev); @@ -1538,7 +1538,7 @@ static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; - + IUCV_DBF_TEXT(trace, 4, __FUNCTION__); priv->conn->prof.maxcqueue = 0; return count; @@ -1559,7 +1559,7 @@ static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; - + IUCV_DBF_TEXT(trace, 4, __FUNCTION__); priv->conn->prof.doios_single = 0; return count; @@ -1580,7 +1580,7 @@ static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; - + IUCV_DBF_TEXT(trace, 5, __FUNCTION__); priv->conn->prof.doios_multi = 0; return count; @@ -1601,7 +1601,7 @@ static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; - + IUCV_DBF_TEXT(trace, 4, __FUNCTION__); priv->conn->prof.txlen = 0; return count; @@ -1622,7 +1622,7 @@ static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; - + IUCV_DBF_TEXT(trace, 4, __FUNCTION__); priv->conn->prof.tx_time = 0; return count; @@ -1728,13 +1728,14 @@ static int netiucv_register_device(struct net_device *ndev) { struct netiucv_priv *priv = ndev->priv; - struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); + struct device *dev = kmalloc(sizeof(struct device), GFP_KERNEL); int ret; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); if (dev) { + memset(dev, 0, sizeof(struct device)); snprintf(dev->bus_id, BUS_ID_SIZE, "net%s", ndev->name); dev->bus = &iucv_bus; dev->parent = iucv_root; @@ -1783,9 +1784,11 @@ netiucv_new_connection(struct net_device *dev, char *username) { struct iucv_connection **clist = &iucv_connections; struct iucv_connection *conn = - kzalloc(sizeof(struct iucv_connection), GFP_KERNEL); + (struct iucv_connection *) + kmalloc(sizeof(struct iucv_connection), GFP_KERNEL); if (conn) { + memset(conn, 0, sizeof(struct iucv_connection)); skb_queue_head_init(&conn->collect_queue); skb_queue_head_init(&conn->commit_queue); conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; @@ -2000,7 +2003,7 @@ conn_write(struct device_driver *drv, const char *buf, size_t count) } PRINT_INFO("%s: '%s'\n", dev->name, netiucv_printname(username)); - + return count; out_free_ndev: @@ -2099,7 +2102,7 @@ static int __init netiucv_init(void) { int ret; - + ret = iucv_register_dbf_views(); if (ret) { PRINT_WARN("netiucv_init failed, " @@ -2128,7 +2131,7 @@ netiucv_init(void) } return ret; } - + module_init(netiucv_init); module_exit(netiucv_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 619f4a0c7..4df0fcd7b 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -376,7 +376,7 @@ struct qeth_hdr_osn { __u8 reserved3[18]; __u32 ccid; } __attribute__ ((packed)); - + struct qeth_hdr { union { struct qeth_hdr_layer2 l2; @@ -825,7 +825,7 @@ struct qeth_card { int use_hard_stop; int (*orig_hard_header)(struct sk_buff *,struct net_device *, unsigned short,void *,void *,unsigned); - struct qeth_osn_info osn_info; + struct qeth_osn_info osn_info; }; struct qeth_card_list_struct { @@ -944,7 +944,7 @@ qeth_get_netdev_flags(struct qeth_card *card) return 0; switch (card->info.type) { case QETH_CARD_TYPE_IQD: - case QETH_CARD_TYPE_OSN: + case QETH_CARD_TYPE_OSN: return IFF_NOARP; #ifdef CONFIG_QETH_IPV6 default: @@ -981,7 +981,7 @@ static inline int qeth_get_max_mtu_for_card(int cardtype) { switch (cardtype) { - + case QETH_CARD_TYPE_UNKNOWN: case QETH_CARD_TYPE_OSAE: case QETH_CARD_TYPE_OSN: @@ -1097,9 +1097,9 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr) int count = 0, rc = 0; int in[4]; - rc = sscanf(buf, "%d.%d.%d.%d%n", + rc = sscanf(buf, "%d.%d.%d.%d%n", &in[0], &in[1], &in[2], &in[3], &count); - if (rc != 4 || count<=0) + if (rc != 4 || count) return -EINVAL; for (count = 0; count < 4; count++) { if (in[count] > 255) @@ -1131,7 +1131,7 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr) cnt = out = found = save_cnt = num2 = 0; end = start = (char *) buf; - in = (__u16 *) addr; + in = (__u16 *) addr; memset(in, 0, 16); while (end) { end = strchr(end,':'); @@ -1139,7 +1139,7 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr) end = (char *)buf + (strlen(buf)); out = 1; } - if ((end - start)) { + if ((end - start)) { memset(num, 0, 5); memcpy(num, start, end - start); if (!qeth_isxdigit(num)) @@ -1241,5 +1241,5 @@ qeth_osn_register(unsigned char *read_dev_no, extern void qeth_osn_deregister(struct net_device *); - + #endif /* __QETH_H__ */ diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index 38aad8321..82cb4af2f 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c @@ -81,7 +81,7 @@ void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf) { struct qeth_eddp_context_reference *ref; - + QETH_DBF_TEXT(trace, 6, "eddprctx"); while (!list_empty(&buf->ctx_list)){ ref = list_entry(buf->ctx_list.next, @@ -135,7 +135,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, "buffer!\n"); goto out; } - } + } /* check if the whole next skb fits into current buffer */ if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) - buf->next_element_to_fill) @@ -148,7 +148,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, * and increment ctx's refcnt */ must_refcnt = 1; continue; - } + } if (must_refcnt){ must_refcnt = 0; if (qeth_eddp_buf_ref_context(buf, ctx)){ @@ -266,7 +266,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len, int left_in_frag; int copy_len; u8 *src; - + QETH_DBF_TEXT(trace, 5, "eddpcdtc"); if (skb_shinfo(eddp->skb)->nr_frags == 0) { memcpy(dst, eddp->skb->data + eddp->skb_offset, len); @@ -389,8 +389,9 @@ qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl) struct qeth_eddp_data *eddp; QETH_DBF_TEXT(trace, 5, "eddpcrda"); - eddp = kzalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC); + eddp = kmalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC); if (eddp){ + memset(eddp, 0, sizeof(struct qeth_eddp_data)); eddp->nhl = nhl; eddp->thl = thl; memcpy(&eddp->qh, qh, sizeof(struct qeth_hdr)); @@ -408,7 +409,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, struct tcphdr *tcph; int data_len; u32 hcsum; - + QETH_DBF_TEXT(trace, 5, "eddpftcp"); eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl; if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) { @@ -420,7 +421,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, } tcph = eddp->skb->h.th; while (eddp->skb_offset < eddp->skb->len) { - data_len = min((int)skb_shinfo(eddp->skb)->gso_size, + data_len = min((int)skb_shinfo(eddp->skb)->tso_size, (int)(eddp->skb->len - eddp->skb_offset)); /* prepare qdio hdr */ if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){ @@ -465,13 +466,13 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, eddp->th.tcp.h.seq += data_len; } } - + static inline int qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, struct sk_buff *skb, struct qeth_hdr *qhdr) { struct qeth_eddp_data *eddp = NULL; - + QETH_DBF_TEXT(trace, 5, "eddpficx"); /* create our segmentation headers and copy original headers */ if (skb->protocol == ETH_P_IP) @@ -512,23 +513,23 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb, int hdr_len) { int skbs_per_page; - + QETH_DBF_TEXT(trace, 5, "eddpcanp"); /* can we put multiple skbs in one page? */ - skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len); + skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len); if (skbs_per_page > 1){ - ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) / + ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) / skbs_per_page + 1; ctx->elements_per_skb = 1; } else { /* no -> how many elements per skb? */ - ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len + + ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len + PAGE_SIZE) >> PAGE_SHIFT; ctx->num_pages = ctx->elements_per_skb * - (skb_shinfo(skb)->gso_segs + 1); + (skb_shinfo(skb)->tso_segs + 1); } ctx->num_elements = ctx->elements_per_skb * - (skb_shinfo(skb)->gso_segs + 1); + (skb_shinfo(skb)->tso_segs + 1); } static inline struct qeth_eddp_context * @@ -541,11 +542,12 @@ qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb, QETH_DBF_TEXT(trace, 5, "creddpcg"); /* create the context and allocate pages */ - ctx = kzalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC); + ctx = kmalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC); if (ctx == NULL){ QETH_DBF_TEXT(trace, 2, "ceddpcn1"); return NULL; } + memset(ctx, 0, sizeof(struct qeth_eddp_context)); ctx->type = QETH_LARGE_SEND_EDDP; qeth_eddp_calc_num_pages(ctx, skb, hdr_len); if (ctx->elements_per_skb > QETH_MAX_BUFFER_ELEMENTS(card)){ @@ -553,12 +555,13 @@ qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb, kfree(ctx); return NULL; } - ctx->pages = kcalloc(ctx->num_pages, sizeof(u8 *), GFP_ATOMIC); + ctx->pages = kmalloc(ctx->num_pages * sizeof(u8 *), GFP_ATOMIC); if (ctx->pages == NULL){ QETH_DBF_TEXT(trace, 2, "ceddpcn2"); kfree(ctx); return NULL; } + memset(ctx->pages, 0, ctx->num_pages * sizeof(u8 *)); for (i = 0; i < ctx->num_pages; ++i){ addr = (u8 *)__get_free_page(GFP_ATOMIC); if (addr == NULL){ @@ -570,13 +573,15 @@ qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb, memset(addr, 0, PAGE_SIZE); ctx->pages[i] = addr; } - ctx->elements = kcalloc(ctx->num_elements, + ctx->elements = kmalloc(ctx->num_elements * sizeof(struct qeth_eddp_element), GFP_ATOMIC); if (ctx->elements == NULL){ QETH_DBF_TEXT(trace, 2, "ceddpcn4"); qeth_eddp_free_context(ctx); return NULL; } + memset(ctx->elements, 0, + ctx->num_elements * sizeof(struct qeth_eddp_element)); /* reset num_elements; will be incremented again in fill_buffer to * reflect number of actually used elements */ ctx->num_elements = 0; @@ -588,7 +593,7 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb, struct qeth_hdr *qhdr) { struct qeth_eddp_context *ctx = NULL; - + QETH_DBF_TEXT(trace, 5, "creddpct"); if (skb->protocol == ETH_P_IP) ctx = qeth_eddp_create_context_generic(card, skb, diff --git a/drivers/s390/net/qeth_fs.h b/drivers/s390/net/qeth_fs.h index 61faf0551..e422b41c6 100644 --- a/drivers/s390/net/qeth_fs.h +++ b/drivers/s390/net/qeth_fs.h @@ -42,7 +42,7 @@ qeth_create_device_attributes_osn(struct device *dev); extern void qeth_remove_device_attributes_osn(struct device *dev); - + extern int qeth_create_driver_attributes(void); diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 290866932..dba7f7f02 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -297,10 +297,12 @@ qeth_alloc_card(void) struct qeth_card *card; QETH_DBF_TEXT(setup, 2, "alloccrd"); - card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL); + card = (struct qeth_card *) kmalloc(sizeof(struct qeth_card), + GFP_DMA|GFP_KERNEL); if (!card) return NULL; QETH_DBF_HEX(setup, 2, &card, sizeof(void *)); + memset(card, 0, sizeof(struct qeth_card)); if (qeth_setup_channel(&card->read)) { kfree(card); return NULL; @@ -513,7 +515,7 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) QETH_DBF_TEXT(setup, 3, "setoffl"); QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); - + if (card->dev && netif_carrier_ok(card->dev)) netif_carrier_off(card->dev); recover_flag = card->state; @@ -604,13 +606,13 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo, list_for_each_entry(addr, &card->ip_list, entry) { if (card->options.layer2) { if ((addr->type == todo->type) && - (memcmp(&addr->mac, &todo->mac, + (memcmp(&addr->mac, &todo->mac, OSA_ADDR_LEN) == 0)) { found = 1; break; } continue; - } + } if ((addr->proto == QETH_PROT_IPV4) && (todo->proto == QETH_PROT_IPV4) && (addr->type == todo->type) && @@ -694,13 +696,13 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add) if (card->options.layer2) { if ((tmp->type == addr->type) && (tmp->is_multicast == addr->is_multicast) && - (memcmp(&tmp->mac, &addr->mac, + (memcmp(&tmp->mac, &addr->mac, OSA_ADDR_LEN) == 0)) { found = 1; break; } continue; - } + } if ((tmp->proto == QETH_PROT_IPV4) && (addr->proto == QETH_PROT_IPV4) && (tmp->type == addr->type) && @@ -1173,7 +1175,7 @@ qeth_determine_card_type(struct qeth_card *card) "due to hardware limitations!\n"); card->qdio.no_out_queues = 1; card->qdio.default_out_queue = 0; - } + } return 0; } i++; @@ -1198,7 +1200,7 @@ qeth_probe_device(struct ccwgroup_device *gdev) return -ENODEV; QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id); - + card = qeth_alloc_card(); if (!card) { put_device(dev); @@ -1220,7 +1222,7 @@ qeth_probe_device(struct ccwgroup_device *gdev) put_device(dev); qeth_free_card(card); return rc; - } + } if ((rc = qeth_setup_card(card))){ QETH_DBF_TEXT_(setup, 2, "2err%d", rc); put_device(dev); @@ -1362,7 +1364,7 @@ qeth_wait_for_buffer(struct qeth_channel *channel) static void qeth_clear_cmd_buffers(struct qeth_channel *channel) { - int cnt; + int cnt = 0; for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++) qeth_release_buffer(channel,&channel->iob[cnt]); @@ -1630,8 +1632,9 @@ qeth_alloc_reply(struct qeth_card *card) { struct qeth_reply *reply; - reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC); + reply = kmalloc(sizeof(struct qeth_reply), GFP_ATOMIC); if (reply){ + memset(reply, 0, sizeof(struct qeth_reply)); atomic_set(&reply->refcnt, 1); reply->card = card; }; @@ -1843,7 +1846,7 @@ struct qeth_cmd_buffer *iob) &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH); QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN); } - + static int qeth_send_control_data(struct qeth_card *card, int len, struct qeth_cmd_buffer *iob, @@ -1937,7 +1940,7 @@ qeth_osn_send_control_data(struct qeth_card *card, int len, wake_up(&card->wait_q); } return rc; -} +} static inline void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, @@ -1966,7 +1969,7 @@ qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2); return qeth_osn_send_control_data(card, s1, iob); } - + static int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, int (*reply_cb) @@ -2579,7 +2582,7 @@ qeth_process_inbound_buffer(struct qeth_card *card, skb->dev = card->dev; if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr); - else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) + else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) qeth_rebuild_skb(card, skb, hdr); else { /*in case of OSN*/ skb_push(skb, sizeof(struct qeth_hdr)); @@ -2763,7 +2766,7 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status, index = i % QDIO_MAX_BUFFERS_PER_Q; buffer = &card->qdio.in_q->bufs[index]; if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) && - qeth_check_qdio_errors(buffer->buffer, + qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err,"qinerr"))) qeth_process_inbound_buffer(card, buffer, index); /* clear buffer and give back to hardware */ @@ -2811,11 +2814,11 @@ qeth_handle_send_error(struct qeth_card *card, QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card)); return QETH_SEND_ERROR_LINK_FAILURE; case 3: - default: QETH_DBF_TEXT(trace, 1, "SIGAcc3"); QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card)); return QETH_SEND_ERROR_KICK_IT; } + return QETH_SEND_ERROR_LINK_FAILURE; } void @@ -3187,7 +3190,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) if (card->qdio.state == QETH_QDIO_ALLOCATED) return 0; - card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), + card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), GFP_KERNEL|GFP_DMA); if (!card->qdio.in_q) return - ENOMEM; @@ -3345,11 +3348,13 @@ qeth_qdio_establish(struct qeth_card *card) QETH_DBF_TEXT(setup, 2, "qdioest"); - qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char), + qib_param_field = kmalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char), GFP_KERNEL); if (!qib_param_field) return -ENOMEM; + memset(qib_param_field, 0, QDIO_MAX_BUFFERS_PER_Q * sizeof(char)); + qeth_create_qib_param_field(card, qib_param_field); qeth_create_qib_param_field_blkt(card, qib_param_field); @@ -3476,7 +3481,7 @@ qeth_halt_channels(struct qeth_card *card) rc3 = qeth_halt_channel(&card->data); if (rc1) return rc1; - if (rc2) + if (rc2) return rc2; return rc3; } @@ -3491,7 +3496,7 @@ qeth_clear_channels(struct qeth_card *card) rc3 = qeth_clear_channel(&card->data); if (rc1) return rc1; - if (rc2) + if (rc2) return rc2; return rc3; } @@ -3798,10 +3803,10 @@ qeth_open(struct net_device *dev) QETH_DBF_TEXT(trace,4,"nomacadr"); return -EPERM; } - card->data.state = CH_STATE_UP; - card->state = CARD_STATE_UP; card->dev->flags |= IFF_UP; netif_start_queue(dev); + card->data.state = CH_STATE_UP; + card->state = CARD_STATE_UP; if (!card->lan_online && netif_carrier_ok(dev)) netif_carrier_off(dev); @@ -3817,7 +3822,7 @@ qeth_stop(struct net_device *dev) card = (struct qeth_card *) dev->priv; - netif_tx_disable(dev); + netif_stop_queue(dev); card->dev->flags &= ~IFF_UP; if (card->state == CARD_STATE_UP) card->state = CARD_STATE_SOFTSETUP; @@ -3860,7 +3865,6 @@ qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb) if ((hdr_mac == QETH_TR_MAC_NC) || (hdr_mac == QETH_TR_MAC_C)) return RTN_MULTICAST; - break; /* eth or so multicast? */ default: if ((hdr_mac == QETH_ETH_MAC_V4) || @@ -3958,7 +3962,7 @@ qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, #endif *hdr = (struct qeth_hdr *) qeth_push_skb(card, skb, sizeof(struct qeth_hdr)); - if (*hdr == NULL) + if (hdr == NULL) return -EINVAL; return 0; } @@ -4098,7 +4102,7 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, } } else { /* passthrough */ if((skb->dev->type == ARPHRD_IEEE802_TR) && - !memcmp(skb->data + sizeof(struct qeth_hdr) + + !memcmp(skb->data + sizeof(struct qeth_hdr) + sizeof(__u16), skb->dev->broadcast, 6)) { hdr->hdr.l3.flags = QETH_CAST_BROADCAST | QETH_HDR_PASSTHRU; @@ -4385,7 +4389,7 @@ out: } static inline int -qeth_get_elements_no(struct qeth_card *card, void *hdr, +qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb, int elems) { int elements_needed = 0; @@ -4415,8 +4419,6 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) int elements_needed = 0; enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; struct qeth_eddp_context *ctx = NULL; - int tx_bytes = skb->len; - unsigned short nr_frags = skb_shinfo(skb)->nr_frags; int rc; QETH_DBF_TEXT(trace, 6, "sendpkt"); @@ -4442,7 +4444,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) return 0; } cast_type = qeth_get_cast_type(card, skb); - if ((cast_type == RTN_BROADCAST) && + if ((cast_type == RTN_BROADCAST) && (card->info.broadcast_capable == 0)){ card->stats.tx_dropped++; card->stats.tx_errors++; @@ -4452,7 +4454,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) queue = card->qdio.out_qs [qeth_get_priority_queue(card, skb, ipv, cast_type)]; - if (skb_is_gso(skb)) + if (skb_shinfo(skb)->tso_size) large_send = card->options.large_send; /*are we able to do TSO ? If so ,prepare and send it from here */ @@ -4464,7 +4466,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) card->stats.tx_errors++; dev_kfree_skb_any(skb); return NETDEV_TX_OK; - } + } elements_needed++; } else { if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) { @@ -4497,17 +4499,18 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) elements_needed, ctx); if (!rc){ card->stats.tx_packets++; - card->stats.tx_bytes += tx_bytes; + card->stats.tx_bytes += skb->len; #ifdef CONFIG_QETH_PERF_STATS - if (skb_is_gso(skb) && !(large_send == QETH_LARGE_SEND_NO)) { + if (skb_shinfo(skb)->tso_size && + !(large_send == QETH_LARGE_SEND_NO)) { card->perf_stats.large_send_bytes += skb->len; card->perf_stats.large_send_cnt++; } - if (nr_frags > 0){ + if (skb_shinfo(skb)->nr_frags > 0){ card->perf_stats.sg_skbs_sent++; /* nr_frags + skb->data */ card->perf_stats.sg_frags_sent += - nr_frags + 1; + skb_shinfo(skb)->nr_frags + 1; } #endif /* CONFIG_QETH_PERF_STATS */ } @@ -4582,11 +4585,38 @@ qeth_mdio_read(struct net_device *dev, int phy_id, int regnum) case MII_NCONFIG: /* network interface config */ break; default: + rc = 0; break; } return rc; } +static void +qeth_mdio_write(struct net_device *dev, int phy_id, int regnum, int value) +{ + switch(regnum){ + case MII_BMCR: /* Basic mode control register */ + case MII_BMSR: /* Basic mode status register */ + case MII_PHYSID1: /* PHYS ID 1 */ + case MII_PHYSID2: /* PHYS ID 2 */ + case MII_ADVERTISE: /* Advertisement control reg */ + case MII_LPA: /* Link partner ability reg */ + case MII_EXPANSION: /* Expansion register */ + case MII_DCOUNTER: /* disconnect counter */ + case MII_FCSCOUNTER: /* false carrier counter */ + case MII_NWAYTEST: /* N-way auto-neg test register */ + case MII_RERRCOUNTER: /* rx error counter */ + case MII_SREVISION: /* silicon revision */ + case MII_RESV1: /* reserved 1 */ + case MII_LBRERROR: /* loopback, rx, bypass error */ + case MII_PHYADDR: /* physical address */ + case MII_RESV2: /* reserved 2 */ + case MII_TPISTATUS: /* TPI status for 10mbps */ + case MII_NCONFIG: /* network interface config */ + default: + break; + } +} static inline const char * qeth_arp_get_error_cause(int *rc) @@ -4814,8 +4844,9 @@ qeth_arp_query(struct qeth_card *card, char *udata) /* get size of userspace buffer and mask_bits -> 6 bytes */ if (copy_from_user(&qinfo, udata, 6)) return -EFAULT; - if (!(qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL))) + if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL))) return -ENOMEM; + memset(qinfo.udata, 0, qinfo.udata_len); qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET; iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING, IPA_CMD_ASS_ARP_QUERY_INFO, @@ -4963,10 +4994,11 @@ qeth_snmp_command(struct qeth_card *card, char *udata) return -EFAULT; } qinfo.udata_len = ureq->hdr.data_len; - if (!(qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL))){ + if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL))){ kfree(ureq); return -ENOMEM; } + memset(qinfo.udata, 0, qinfo.udata_len); qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr); iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, @@ -5204,6 +5236,21 @@ qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) mii_data->val_out = qeth_mdio_read(dev,mii_data->phy_id, mii_data->reg_num); break; + case SIOCSMIIREG: + rc = -EOPNOTSUPP; + break; + /* TODO: remove return if qeth_mdio_write does something */ + if (!capable(CAP_NET_ADMIN)){ + rc = -EPERM; + break; + } + mii_data = if_mii(rq); + if (mii_data->phy_id != 0) + rc = -EINVAL; + else + qeth_mdio_write(dev, mii_data->phy_id, mii_data->reg_num, + mii_data->val_in); + break; default: rc = -EOPNOTSUPP; } @@ -5373,7 +5420,7 @@ qeth_layer2_send_setdelvlan_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data; if (cmd->hdr.return_code) { PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. " - "Continuing\n",cmd->data.setdelvlan.vlan_id, + "Continuing\n",cmd->data.setdelvlan.vlan_id, QETH_CARD_IFNAME(card), cmd->hdr.return_code); QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command); QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card)); @@ -5393,7 +5440,7 @@ qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i, iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.setdelvlan.vlan_id = i; - return qeth_send_ipa_cmd(card, iob, + return qeth_send_ipa_cmd(card, iob, qeth_layer2_send_setdelvlan_cb, NULL); } @@ -5457,7 +5504,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) * Examine hardware response to SET_PROMISC_MODE */ static int -qeth_setadp_promisc_mode_cb(struct qeth_card *card, +qeth_setadp_promisc_mode_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { @@ -5468,10 +5515,10 @@ qeth_setadp_promisc_mode_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data; setparms = &(cmd->data.setadapterparms); - + qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd); - if (cmd->hdr.return_code) { - QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code); + if (cmd->hdr.return_code) { + QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code); setparms->data.mode = SET_PROMISC_MODE_OFF; } card->info.promisc_mode = setparms->data.mode; @@ -5517,7 +5564,7 @@ qeth_set_multicast_list(struct net_device *dev) if (card->info.type == QETH_CARD_TYPE_OSN) return ; - + QETH_DBF_TEXT(trace, 3, "setmulti"); qeth_delete_mc_addresses(card); if (card->options.layer2) { @@ -5557,11 +5604,12 @@ qeth_get_addr_buffer(enum qeth_prot_versions prot) { struct qeth_ipaddr *addr; - addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC); + addr = kmalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC); if (addr == NULL) { PRINT_WARN("Not enough memory to add address\n"); return NULL; } + memset(addr,0,sizeof(struct qeth_ipaddr)); addr->type = QETH_IP_TYPE_NORMAL; addr->proto = prot; return addr; @@ -5575,7 +5623,7 @@ qeth_osn_assist(struct net_device *dev, struct qeth_cmd_buffer *iob; struct qeth_card *card; int rc; - + QETH_DBF_TEXT(trace, 2, "osnsdmc"); if (!dev) return -ENODEV; @@ -5654,7 +5702,7 @@ qeth_osn_deregister(struct net_device * dev) card->osn_info.data_cb = NULL; return; } - + static void qeth_delete_mc_addresses(struct qeth_card *card) { @@ -5818,7 +5866,7 @@ qeth_add_multicast_ipv6(struct qeth_card *card) struct inet6_dev *in6_dev; QETH_DBF_TEXT(trace,4,"chkmcv6"); - if (!qeth_is_supported(card, IPA_IPV6)) + if (!qeth_is_supported(card, IPA_IPV6)) return ; in6_dev = in6_dev_get(card->dev); if (in6_dev == NULL) @@ -6359,9 +6407,12 @@ qeth_netdev_init(struct net_device *dev) dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid; dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid; #endif + dev->hard_header = card->orig_hard_header; if (qeth_get_netdev_flags(card) & IFF_NOARP) { dev->rebuild_header = NULL; dev->hard_header = NULL; + if (card->options.fake_ll) + dev->hard_header = qeth_fake_header; dev->header_cache_update = NULL; dev->hard_header_cache = NULL; } @@ -6370,9 +6421,6 @@ qeth_netdev_init(struct net_device *dev) if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD)) card->dev->dev_id = card->info.unique_id & 0xffff; #endif - if (card->options.fake_ll && - (qeth_get_netdev_flags(card) & IFF_NOARP)) - dev->hard_header = qeth_fake_header; dev->hard_header_parse = NULL; dev->set_mac_address = qeth_layer2_set_mac_address; dev->flags |= qeth_get_netdev_flags(card); @@ -6477,9 +6525,6 @@ retry: /*network device will be recovered*/ if (card->dev) { card->dev->hard_header = card->orig_hard_header; - if (card->options.fake_ll && - (qeth_get_netdev_flags(card) & IFF_NOARP)) - card->dev->hard_header = qeth_fake_header; return 0; } /* at first set_online allocate netdev */ @@ -6587,7 +6632,7 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data; if (!card->options.layer2 || card->info.guestlan || - !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) { + !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) { memcpy(card->dev->dev_addr, &cmd->data.setadapterparms.data.change_addr.addr, OSA_ADDR_LEN); @@ -6855,7 +6900,7 @@ qeth_send_setassparms(struct qeth_card *card, struct qeth_cmd_buffer *iob, cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); if (len <= sizeof(__u32)) cmd->data.setassparms.data.flags_32bit = (__u32) data; - else /* (len > sizeof(__u32)) */ + else if (len > sizeof(__u32)) memcpy(&cmd->data.setassparms.data, (void *) data, len); rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param); @@ -7034,12 +7079,14 @@ qeth_softsetup_ipv6(struct qeth_card *card) QETH_DBF_TEXT(trace,3,"softipv6"); + netif_stop_queue(card->dev); rc = qeth_send_startlan(card, QETH_PROT_IPV6); if (rc) { PRINT_ERR("IPv6 startlan failed on %s\n", QETH_CARD_IFNAME(card)); return rc; } + netif_wake_queue(card->dev); rc = qeth_query_ipassists(card,QETH_PROT_IPV6); if (rc) { PRINT_ERR("IPv6 query ipassist failed on %s\n", @@ -7332,6 +7379,11 @@ qeth_setrouting_v6(struct qeth_card *card) qeth_correct_routing_type(card, &card->options.route6.type, QETH_PROT_IPV6); + if ((card->options.route6.type == NO_ROUTER) || + ((card->info.type == QETH_CARD_TYPE_OSAE) && + (card->options.route6.type == MULTICAST_ROUTER) && + !qeth_is_supported6(card,IPA_OSA_MC_ROUTER))) + return 0; rc = qeth_send_setrouting(card, card->options.route6.type, QETH_PROT_IPV6); if (rc) { @@ -7353,8 +7405,7 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type) card->options.large_send = type; return 0; } - if (card->state == CARD_STATE_UP) - netif_tx_disable(card->dev); + netif_stop_queue(card->dev); card->options.large_send = type; switch (card->options.large_send) { case QETH_LARGE_SEND_EDDP: @@ -7376,8 +7427,7 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type) card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); break; } - if (card->state == CARD_STATE_UP) - netif_wake_queue(card->dev); + netif_wake_queue(card->dev); return rc; } @@ -7430,7 +7480,7 @@ qeth_softsetup_card(struct qeth_card *card) if ((rc = qeth_setrouting_v6(card))) QETH_DBF_TEXT_(setup, 2, "5err%d", rc); out: - netif_tx_disable(card->dev); + netif_stop_queue(card->dev); return 0; } @@ -7570,7 +7620,7 @@ qeth_stop_card(struct qeth_card *card, int recovery_mode) if (card->read.state == CH_STATE_UP && card->write.state == CH_STATE_UP && (card->state == CARD_STATE_UP)) { - if (recovery_mode && + if (recovery_mode && card->info.type != QETH_CARD_TYPE_OSN) { qeth_stop(card->dev); } else { @@ -7739,8 +7789,10 @@ static int qeth_register_netdev(struct qeth_card *card) { QETH_DBF_TEXT(setup, 3, "regnetd"); - if (card->dev->reg_state != NETREG_UNINITIALIZED) + if (card->dev->reg_state != NETREG_UNINITIALIZED) { + qeth_netdev_init(card->dev); return 0; + } /* sysfs magic */ SET_NETDEV_DEV(card->dev, &card->gdev->dev); return register_netdev(card->dev); @@ -7751,7 +7803,7 @@ qeth_start_again(struct qeth_card *card, int recovery_mode) { QETH_DBF_TEXT(setup ,2, "startag"); - if (recovery_mode && + if (recovery_mode && card->info.type != QETH_CARD_TYPE_OSN) { qeth_open(card->dev); } else { @@ -8015,6 +8067,7 @@ static int (*qeth_old_arp_constructor) (struct neighbour *); static struct neigh_ops arp_direct_ops_template = { .family = AF_INET, + .destructor = NULL, .solicit = NULL, .error_report = NULL, .output = dev_queue_xmit, diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h index 0477c4747..011c41041 100644 --- a/drivers/s390/net/qeth_mpc.h +++ b/drivers/s390/net/qeth_mpc.h @@ -445,7 +445,7 @@ enum qeth_ipa_arp_return_codes { /* Helper functions */ #define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \ (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY)) - + /*****************************************************************************/ /* END OF IP Assist related definitions */ /*****************************************************************************/ @@ -490,7 +490,7 @@ extern unsigned char ULP_ENABLE[]; /* Layer 2 defintions */ #define QETH_PROT_LAYER2 0x08 #define QETH_PROT_TCPIP 0x03 -#define QETH_PROT_OSN2 0x0a +#define QETH_PROT_OSN2 0x0a #define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50) #define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19) diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c index 66f2da14e..3c6339df8 100644 --- a/drivers/s390/net/qeth_proc.c +++ b/drivers/s390/net/qeth_proc.c @@ -36,7 +36,7 @@ qeth_procfile_seq_start(struct seq_file *s, loff_t *offset) { struct device *dev = NULL; loff_t nr = 0; - + down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); if (*offset == 0) return SEQ_START_TOKEN; @@ -60,8 +60,8 @@ static void * qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) { struct device *prev, *next; - - if (it == SEQ_START_TOKEN) + + if (it == SEQ_START_TOKEN) prev = NULL; else prev = (struct device *) it; @@ -74,7 +74,7 @@ qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) static inline const char * qeth_get_router_str(struct qeth_card *card, int ipv) { - enum qeth_routing_types routing_type = NO_ROUTER; + int routing_type = 0; if (ipv == 4) { routing_type = card->options.route4.type; @@ -86,26 +86,26 @@ qeth_get_router_str(struct qeth_card *card, int ipv) #endif /* CONFIG_QETH_IPV6 */ } - switch (routing_type){ - case PRIMARY_ROUTER: + if (routing_type == PRIMARY_ROUTER) return "pri"; - case SECONDARY_ROUTER: + else if (routing_type == SECONDARY_ROUTER) return "sec"; - case MULTICAST_ROUTER: + else if (routing_type == MULTICAST_ROUTER) { if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO) return "mc+"; return "mc"; - case PRIMARY_CONNECTOR: + } else if (routing_type == PRIMARY_CONNECTOR) { if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO) return "p+c"; return "p.c"; - case SECONDARY_CONNECTOR: + } else if (routing_type == SECONDARY_CONNECTOR) { if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO) return "s+c"; return "s.c"; - default: /* NO_ROUTER */ + } else if (routing_type == NO_ROUTER) return "no"; - } + else + return "unk"; } static int @@ -180,7 +180,7 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) struct device *device; struct qeth_card *card; - + if (it == SEQ_START_TOKEN) return 0; @@ -192,27 +192,27 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) CARD_DDEV_ID(card), QETH_CARD_IFNAME(card) ); - seq_printf(s, " Skb's/buffers received : %lu/%u\n" - " Skb's/buffers sent : %lu/%u\n\n", + seq_printf(s, " Skb's/buffers received : %li/%i\n" + " Skb's/buffers sent : %li/%i\n\n", card->stats.rx_packets, card->perf_stats.bufs_rec, card->stats.tx_packets, card->perf_stats.bufs_sent ); - seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n" - " Skb's/buffers sent with packing : %u/%u\n\n", + seq_printf(s, " Skb's/buffers sent without packing : %li/%i\n" + " Skb's/buffers sent with packing : %i/%i\n\n", card->stats.tx_packets - card->perf_stats.skbs_sent_pack, card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack, card->perf_stats.skbs_sent_pack, card->perf_stats.bufs_sent_pack ); - seq_printf(s, " Skbs sent in SG mode : %u\n" - " Skb fragments sent in SG mode : %u\n\n", + seq_printf(s, " Skbs sent in SG mode : %i\n" + " Skb fragments sent in SG mode : %i\n\n", card->perf_stats.sg_skbs_sent, card->perf_stats.sg_frags_sent); - seq_printf(s, " large_send tx (in Kbytes) : %u\n" - " large_send count : %u\n\n", + seq_printf(s, " large_send tx (in Kbytes) : %i\n" + " large_send count : %i\n\n", card->perf_stats.large_send_bytes >> 10, card->perf_stats.large_send_cnt); - seq_printf(s, " Packing state changes no pkg.->packing : %u/%u\n" + seq_printf(s, " Packing state changes no pkg.->packing : %i/%i\n" " Watermarks L/H : %i/%i\n" " Current buffer usage (outbound q's) : " "%i/%i/%i/%i\n\n", @@ -229,16 +229,16 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) atomic_read(&card->qdio.out_qs[3]->used_buffers) : 0 ); - seq_printf(s, " Inbound handler time (in us) : %u\n" - " Inbound handler count : %u\n" - " Inbound do_QDIO time (in us) : %u\n" - " Inbound do_QDIO count : %u\n\n" - " Outbound handler time (in us) : %u\n" - " Outbound handler count : %u\n\n" - " Outbound time (in us, incl QDIO) : %u\n" - " Outbound count : %u\n" - " Outbound do_QDIO time (in us) : %u\n" - " Outbound do_QDIO count : %u\n\n", + seq_printf(s, " Inbound handler time (in us) : %i\n" + " Inbound handler count : %i\n" + " Inbound do_QDIO time (in us) : %i\n" + " Inbound do_QDIO count : %i\n\n" + " Outbound handler time (in us) : %i\n" + " Outbound handler count : %i\n\n" + " Outbound time (in us, incl QDIO) : %i\n" + " Outbound count : %i\n" + " Outbound do_QDIO time (in us) : %i\n" + " Outbound do_QDIO count : %i\n\n", card->perf_stats.inbound_time, card->perf_stats.inbound_cnt, card->perf_stats.inbound_do_qdio_time, diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c index 185a9cfbc..c1831f572 100644 --- a/drivers/s390/net/qeth_sys.c +++ b/drivers/s390/net/qeth_sys.c @@ -115,7 +115,7 @@ qeth_dev_portno_store(struct device *dev, struct device_attribute *attr, const c return -EPERM; portno = simple_strtoul(buf, &tmp, 16); - if (portno > MAX_PORTNO){ + if ((portno < 0) || (portno > MAX_PORTNO)){ PRINT_WARN("portno 0x%X is out of range\n", portno); return -EINVAL; } @@ -785,7 +785,7 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con } if (card->options.large_send == type) return count; - if ((rc = qeth_set_large_send(card, type))) + if ((rc = qeth_set_large_send(card, type))) return rc; return count; } @@ -1145,10 +1145,11 @@ qeth_dev_ipato_add_store(const char *buf, size_t count, if ((rc = qeth_parse_ipatoe(buf, proto, addr, &mask_bits))) return rc; - if (!(ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL))){ + if (!(ipatoe = kmalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL))){ PRINT_WARN("No memory to allocate ipato entry\n"); return -ENOMEM; } + memset(ipatoe, 0, sizeof(struct qeth_ipato_entry)); ipatoe->proto = proto; memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16); ipatoe->mask_bits = mask_bits; @@ -1682,7 +1683,7 @@ qeth_create_device_attributes(struct device *dev) if (card->info.type == QETH_CARD_TYPE_OSN) return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group); - + if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group))) return ret; if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){ @@ -1713,7 +1714,7 @@ qeth_remove_device_attributes(struct device *dev) if (card->info.type == QETH_CARD_TYPE_OSN) return sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group); - + sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group); sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group); diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h index 593f29814..1286ddea4 100644 --- a/drivers/s390/net/qeth_tso.h +++ b/drivers/s390/net/qeth_tso.h @@ -51,7 +51,7 @@ qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb) hdr->ext.hdr_version = 1; hdr->ext.hdr_len = 28; /*insert non-fix values */ - hdr->ext.mss = skb_shinfo(skb)->gso_size; + hdr->ext.mss = skb_shinfo(skb)->tso_size; hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4); hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len - sizeof(struct qeth_hdr_tso)); @@ -117,11 +117,11 @@ __qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer, int fragno; unsigned long addr; int element, cnt, dlen; - + fragno = skb_shinfo(skb)->nr_frags; element = *next_element_to_fill; dlen = 0; - + if (is_tso) buffer->element[element].flags = SBAL_FLAGS_MIDDLE_FRAG; diff --git a/drivers/s390/s390_rdev.c b/drivers/s390/s390_rdev.c index 3c7145d9f..e3f647169 100644 --- a/drivers/s390/s390_rdev.c +++ b/drivers/s390/s390_rdev.c @@ -27,9 +27,10 @@ s390_root_dev_register(const char *name) if (!strlen(name)) return ERR_PTR(-EINVAL); - dev = kzalloc(sizeof(struct device), GFP_KERNEL); + dev = kmalloc(sizeof(struct device), GFP_KERNEL); if (!dev) return ERR_PTR(-ENOMEM); + memset(dev, 0, sizeof(struct device)); strncpy(dev->bus_id, name, min(strlen(name), (size_t)BUS_ID_SIZE)); dev->release = s390_root_dev_release; ret = device_register(dev); diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index f99e55308..3bf466603 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c @@ -13,7 +13,6 @@ #include #include #include -#include #include @@ -363,19 +362,12 @@ s390_revalidate_registers(struct mci *mci) return kill_task; } -#define MAX_IPD_COUNT 29 -#define MAX_IPD_TIME (5 * 60 * USEC_PER_SEC) /* 5 minutes */ - /* * machine check handler. */ void s390_do_machine_check(struct pt_regs *regs) { - static DEFINE_SPINLOCK(ipd_lock); - static unsigned long long last_ipd; - static int ipd_count; - unsigned long long tmp; struct mci *mci; struct mcck_struct *mcck; int umode; @@ -412,27 +404,11 @@ s390_do_machine_check(struct pt_regs *regs) s390_handle_damage("processing backup machine " "check with damage."); } - - /* - * Nullifying exigent condition, therefore we might - * retry this instruction. - */ - - spin_lock(&ipd_lock); - - tmp = get_clock(); - - if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME) - ipd_count++; - else - ipd_count = 1; - - last_ipd = tmp; - - if (ipd_count == MAX_IPD_COUNT) - s390_handle_damage("too many ipd retries."); - - spin_unlock(&ipd_lock); + if (!umode) + s390_handle_damage("processing backup machine " + "check in kernel mode."); + mcck->kill_task = 1; + mcck->mcck_code = *(unsigned long long *) mci; } else { /* Processing damage -> stopping machine */ diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 395cfc6a3..95b92f317 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -829,6 +829,18 @@ zfcp_unit_dequeue(struct zfcp_unit *unit) device_unregister(&unit->sysfs_device); } +static void * +zfcp_mempool_alloc(gfp_t gfp_mask, void *size) +{ + return kmalloc((size_t) size, gfp_mask); +} + +static void +zfcp_mempool_free(void *element, void *size) +{ + kfree(element); +} + /* * Allocates a combined QTCB/fsf_req buffer for erp actions and fcp/SCSI * commands. @@ -841,39 +853,51 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) { adapter->pool.fsf_req_erp = - mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ERP_NR, - sizeof(struct zfcp_fsf_req_pool_element)); - if (!adapter->pool.fsf_req_erp) + mempool_create(ZFCP_POOL_FSF_REQ_ERP_NR, + zfcp_mempool_alloc, zfcp_mempool_free, (void *) + sizeof(struct zfcp_fsf_req_pool_element)); + + if (NULL == adapter->pool.fsf_req_erp) return -ENOMEM; adapter->pool.fsf_req_scsi = - mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_SCSI_NR, - sizeof(struct zfcp_fsf_req_pool_element)); - if (!adapter->pool.fsf_req_scsi) + mempool_create(ZFCP_POOL_FSF_REQ_SCSI_NR, + zfcp_mempool_alloc, zfcp_mempool_free, (void *) + sizeof(struct zfcp_fsf_req_pool_element)); + + if (NULL == adapter->pool.fsf_req_scsi) return -ENOMEM; adapter->pool.fsf_req_abort = - mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ABORT_NR, - sizeof(struct zfcp_fsf_req_pool_element)); - if (!adapter->pool.fsf_req_abort) + mempool_create(ZFCP_POOL_FSF_REQ_ABORT_NR, + zfcp_mempool_alloc, zfcp_mempool_free, (void *) + sizeof(struct zfcp_fsf_req_pool_element)); + + if (NULL == adapter->pool.fsf_req_abort) return -ENOMEM; adapter->pool.fsf_req_status_read = - mempool_create_kmalloc_pool(ZFCP_POOL_STATUS_READ_NR, - sizeof(struct zfcp_fsf_req)); - if (!adapter->pool.fsf_req_status_read) + mempool_create(ZFCP_POOL_STATUS_READ_NR, + zfcp_mempool_alloc, zfcp_mempool_free, + (void *) sizeof(struct zfcp_fsf_req)); + + if (NULL == adapter->pool.fsf_req_status_read) return -ENOMEM; adapter->pool.data_status_read = - mempool_create_kmalloc_pool(ZFCP_POOL_STATUS_READ_NR, - sizeof(struct fsf_status_read_buffer)); - if (!adapter->pool.data_status_read) + mempool_create(ZFCP_POOL_STATUS_READ_NR, + zfcp_mempool_alloc, zfcp_mempool_free, + (void *) sizeof(struct fsf_status_read_buffer)); + + if (NULL == adapter->pool.data_status_read) return -ENOMEM; adapter->pool.data_gid_pn = - mempool_create_kmalloc_pool(ZFCP_POOL_DATA_GID_PN_NR, - sizeof(struct zfcp_gid_pn_data)); - if (!adapter->pool.data_gid_pn) + mempool_create(ZFCP_POOL_DATA_GID_PN_NR, + zfcp_mempool_alloc, zfcp_mempool_free, (void *) + sizeof(struct zfcp_gid_pn_data)); + + if (NULL == adapter->pool.data_gid_pn) return -ENOMEM; return 0; diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 3e156e005..1c8b612d8 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -440,8 +440,7 @@ static int __init bbc_i2c_init(void) struct linux_ebus_device *edev = NULL; int err, index = 0; - if ((tlb_type != cheetah && tlb_type != cheetah_plus) || - !bbc_present()) + if (tlb_type != cheetah || !bbc_present()) return -ENODEV; for_each_ebus(ebus) { @@ -487,4 +486,3 @@ static void bbc_i2c_cleanup(void) module_init(bbc_i2c_init); module_exit(bbc_i2c_cleanup); -MODULE_LICENSE("GPL"); diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 2beb3dded..6bdd768b7 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -71,8 +71,9 @@ flash_mmap(struct file *file, struct vm_area_struct *vma) if (vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)) > size) size = vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)); + pgprot_val(vma->vm_page_prot) &= ~(_PAGE_CACHE); + pgprot_val(vma->vm_page_prot) |= _PAGE_E; vma->vm_flags |= (VM_SHM | VM_LOCKED); - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) return -EAGAIN; diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index 239e108b8..383a95f34 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -392,16 +392,13 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, return -ENOMEM; } - cnt = prom_getproperty(op.op_nodeid, str, tmp, len); - if (cnt <= 0) { - error = -EINVAL; - } else { - tmp[len] = '\0'; + prom_getproperty(op.op_nodeid, str, tmp, len); - if (__copy_to_user(argp, &op, sizeof(op)) != 0 || - copy_to_user(op.op_buf, tmp, len) != 0) - error = -EFAULT; - } + tmp[len] = '\0'; + + if (__copy_to_user(argp, &op, sizeof(op)) != 0 + || copy_to_user(op.op_buf, tmp, len) != 0) + error = -EFAULT; kfree(tmp); kfree(str); diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index caeb6d246..913254981 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -2,9 +2,8 @@ 3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux. Written By: Adam Radford - Modifications By: Tom Couch - Copyright (C) 2004-2006 Applied Micro Circuits Corporation. + Copyright (C) 2004-2005 Applied Micro Circuits 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 @@ -63,9 +62,6 @@ 2.26.02.003 - Correctly handle single sgl's with use_sg=1. 2.26.02.004 - Add support for 9550SX controllers. 2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher. - 2.26.02.006 - Fix 9550SX pchip reset timeout. - Add big endian support. - 2.26.02.007 - Disable local interrupts during kmap/unmap_atomic(). */ #include @@ -212,7 +208,7 @@ static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id) header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; tw_dev->posted_request_count--; - aen = le16_to_cpu(header->status_block.error); + aen = header->status_block.error; full_command_packet = tw_dev->command_packet_virt[request_id]; command_packet = &full_command_packet->command.oldcommand; @@ -309,7 +305,7 @@ static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset) tw_dev->posted_request_count--; header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; - aen = le16_to_cpu(header->status_block.error); + aen = header->status_block.error; queue = 0; count++; @@ -369,7 +365,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H tw_dev->aen_clobber = 1; } - aen = le16_to_cpu(header->status_block.error); + aen = header->status_block.error; memset(event, 0, sizeof(TW_Event)); event->severity = TW_SEV_OUT(header->status_block.severity__reserved); @@ -386,7 +382,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0'; event->parameter_len = strlen(header->err_specific_desc); - memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + (error_str[0] == '\0' ? 0 : (1 + strlen(error_str)))); + memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len); if (event->severity != TW_AEN_SEVERITY_DEBUG) printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n", host, @@ -466,24 +462,24 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id) command_packet = &full_command_packet->command.oldcommand; command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM); command_packet->request_id = request_id; - command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); - command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); + command_packet->byte8_offset.param.sgl[0].address = tw_dev->generic_buffer_phys[request_id]; + command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE; command_packet->size = TW_COMMAND_SIZE; - command_packet->byte6_offset.parameter_count = cpu_to_le16(1); + command_packet->byte6_offset.parameter_count = 1; /* Setup the param */ param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; memset(param, 0, TW_SECTOR_SIZE); - param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */ - param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */ - param->parameter_size_bytes = cpu_to_le16(4); + param->table_id = TW_TIMEKEEP_TABLE | 0x8000; /* Controller time keep table */ + param->parameter_id = 0x3; /* SchedulerTime */ + param->parameter_size_bytes = 4; /* Convert system time in UTC to local time seconds since last Sunday 12:00AM */ do_gettimeofday(&utc); local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60)); schedulertime = local_time - (3 * 86400); - schedulertime = cpu_to_le32(schedulertime % 604800); + schedulertime = schedulertime % 604800; memcpy(param->data, &schedulertime, sizeof(u32)); @@ -935,19 +931,26 @@ out: /* This function will clear the pchip/response queue on 9550SX */ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev) { - u32 response_que_value = 0; - unsigned long before; - int retval = 1; + u32 status_reg_value, response_que_value; + int count = 0, retval = 1; if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) { - before = jiffies; - while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + + while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) { response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); - if (time_after(jiffies, before + HZ * 30)) + if ((response_que_value & TW_9550SX_DRAIN_COMPLETED) == TW_9550SX_DRAIN_COMPLETED) { + /* P-chip settle time */ + msleep(500); + retval = 0; goto out; + } + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); + count++; } - /* P-chip settle time */ - msleep(500); + if (count == TW_MAX_RESPONSE_DRAIN) + goto out; + retval = 0; } else retval = 0; @@ -969,7 +972,7 @@ static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_ error_str = &(full_command_packet->header.err_specific_desc[strlen(full_command_packet->header.err_specific_desc) + 1]); /* Don't print error for Logical unit not supported during rollcall */ - error = le16_to_cpu(full_command_packet->header.status_block.error); + error = full_command_packet->header.status_block.error; if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) { if (print_host) printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n", @@ -1027,7 +1030,7 @@ static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id) tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH; } /* End twa_free_request_id() */ -/* This function will get parameter table entries from the firmware */ +/* This function will get parameter table entires from the firmware */ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes) { TW_Command_Full *full_command_packet; @@ -1044,18 +1047,18 @@ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM); command_packet->size = TW_COMMAND_SIZE; command_packet->request_id = request_id; - command_packet->byte6_offset.block_count = cpu_to_le16(1); + command_packet->byte6_offset.block_count = 1; /* Now setup the param */ param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; memset(param, 0, TW_SECTOR_SIZE); - param->table_id = cpu_to_le16(table_id | 0x8000); - param->parameter_id = cpu_to_le16(parameter_id); - param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes); + param->table_id = table_id | 0x8000; + param->parameter_id = parameter_id; + param->parameter_size_bytes = parameter_size_bytes; param_value = tw_dev->generic_buffer_phys[request_id]; - command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(param_value); - command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); + command_packet->byte8_offset.param.sgl[0].address = param_value; + command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE; /* Post the command packet to the board */ twa_post_command_packet(tw_dev, request_id, 1); @@ -1104,20 +1107,18 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits, tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand; tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION); tw_initconnect->request_id = request_id; - tw_initconnect->message_credits = cpu_to_le16(message_credits); + tw_initconnect->message_credits = message_credits; tw_initconnect->features = set_features; /* Turn on 64-bit sgl support if we need to */ tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0; - tw_initconnect->features = cpu_to_le32(tw_initconnect->features); - if (set_features & TW_EXTENDED_INIT_CONNECT) { tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED; - tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl); - tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id); - tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch); - tw_initconnect->fw_build = cpu_to_le16(current_fw_build); + tw_initconnect->fw_srl = current_fw_srl; + tw_initconnect->fw_arch_id = current_fw_arch_id; + tw_initconnect->fw_branch = current_fw_branch; + tw_initconnect->fw_build = current_fw_build; } else tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE; @@ -1129,11 +1130,11 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits, TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection"); } else { if (set_features & TW_EXTENDED_INIT_CONNECT) { - *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl); - *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id); - *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch); - *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build); - *init_connect_result = le32_to_cpu(tw_initconnect->result); + *fw_on_ctlr_srl = tw_initconnect->fw_srl; + *fw_on_ctlr_arch_id = tw_initconnect->fw_arch_id; + *fw_on_ctlr_branch = tw_initconnect->fw_branch; + *fw_on_ctlr_build = tw_initconnect->fw_build; + *init_connect_result = tw_initconnect->result; } retval = 0; } @@ -1357,10 +1358,10 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d newcommand = &full_command_packet->command.newcommand; newcommand->request_id__lunl = TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id); - newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); - newcommand->sg_list[0].length = cpu_to_le32(length); + newcommand->sg_list[0].address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1; + newcommand->sg_list[0].length = length; newcommand->sgl_entries__lunh = - cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1)); + TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1); } else { oldcommand = &full_command_packet->command.oldcommand; oldcommand->request_id = request_id; @@ -1368,8 +1369,8 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { /* Load the sg list */ sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); - sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); - sgl->length = cpu_to_le32(length); + sgl->address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1; + sgl->length = length; if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4)) oldcommand->size += 1; @@ -1827,10 +1828,10 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, if (srb) { command_packet->unit = srb->device->id; command_packet->request_id__lunl = - cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id)); + TW_REQ_LUN_IN(srb->device->lun, request_id); } else { command_packet->request_id__lunl = - cpu_to_le16(TW_REQ_LUN_IN(0, request_id)); + TW_REQ_LUN_IN(0, request_id); command_packet->unit = 0; } @@ -1840,8 +1841,8 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, /* Map sglist from scsi layer to cmd packet */ if (tw_dev->srb[request_id]->use_sg == 0) { if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) { - command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); - command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); + command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id]; + command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH; if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL) memcpy(tw_dev->generic_buffer_virt[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen); } else { @@ -1849,12 +1850,12 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, if (buffaddr == 0) goto out; - command_packet->sg_list[0].address = TW_CPU_TO_SGL(buffaddr); - command_packet->sg_list[0].length = cpu_to_le32(tw_dev->srb[request_id]->request_bufflen); + command_packet->sg_list[0].address = buffaddr; + command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen; } - command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), 1)); + command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), 1); - if (command_packet->sg_list[0].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) { + if (command_packet->sg_list[0].address & TW_ALIGNMENT_9000_SGL) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi"); goto out; } @@ -1868,35 +1869,35 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length); kunmap_atomic(buf - sg->offset, KM_IRQ0); } - command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); - command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); + command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id]; + command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH; } else { sg_count = twa_map_scsi_sg_data(tw_dev, request_id); if (sg_count == 0) goto out; for (i = 0; i < sg_count; i++) { - command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(&sglist[i])); - command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(&sglist[i])); - if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) { + command_packet->sg_list[i].address = sg_dma_address(&sglist[i]); + command_packet->sg_list[i].length = sg_dma_len(&sglist[i]); + if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi"); goto out; } } } - command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg)); + command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg); } } else { /* Internal cdb post */ for (i = 0; i < use_sg; i++) { - command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address); - command_packet->sg_list[i].length = cpu_to_le32(sglistarg[i].length); - if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) { + command_packet->sg_list[i].address = sglistarg[i].address; + command_packet->sg_list[i].length = sglistarg[i].length; + if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post"); goto out; } } - command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg)); + command_packet->sgl_entries__lunh = TW_REQ_LUN_IN(0, use_sg); } if (srb) { @@ -2118,8 +2119,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH), (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE, TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH), - le32_to_cpu(*(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE, - TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH))); + *(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE, + TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH)); /* Now setup the interrupt handler */ retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev); diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index 8c8ecbed3..1b16d57f0 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h @@ -267,7 +267,6 @@ static twa_message_type twa_error_table[] = { #define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000 #define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000 #define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000 -#define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR 0x00000008 /* Status register bit definitions */ #define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000 @@ -285,9 +284,8 @@ static twa_message_type twa_error_table[] = { #define TW_STATUS_MICROCONTROLLER_READY 0x00002000 #define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000 #define TW_STATUS_EXPECTED_BITS 0x00002000 -#define TW_STATUS_UNEXPECTED_BITS 0x00F00008 -#define TW_STATUS_SBUF_WRITE_ERROR 0x00000008 -#define TW_STATUS_VALID_INTERRUPT 0x00DF0008 +#define TW_STATUS_UNEXPECTED_BITS 0x00F00000 +#define TW_STATUS_VALID_INTERRUPT 0x00DF0000 /* RESPONSE QUEUE BIT DEFINITIONS */ #define TW_RESPONSE_ID_MASK 0x00000FF0 @@ -324,9 +322,9 @@ static twa_message_type twa_error_table[] = { /* Compatibility defines */ #define TW_9000_ARCH_ID 0x5 -#define TW_CURRENT_DRIVER_SRL 28 -#define TW_CURRENT_DRIVER_BUILD 9 -#define TW_CURRENT_DRIVER_BRANCH 4 +#define TW_CURRENT_DRIVER_SRL 30 +#define TW_CURRENT_DRIVER_BUILD 80 +#define TW_CURRENT_DRIVER_BRANCH 0 /* Phase defines */ #define TW_PHASE_INITIAL 0 @@ -334,6 +332,7 @@ static twa_message_type twa_error_table[] = { #define TW_PHASE_SGLIST 2 /* Misc defines */ +#define TW_9550SX_DRAIN_COMPLETED 0xFFFF #define TW_SECTOR_SIZE 512 #define TW_ALIGNMENT_9000 4 /* 4 bytes */ #define TW_ALIGNMENT_9000_SGL 0x3 @@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = { #ifndef PCI_DEVICE_ID_3WARE_9000 #define PCI_DEVICE_ID_3WARE_9000 0x1002 #endif +#ifndef PCI_DEVICE_ID_3WARE_9550SX +#define PCI_DEVICE_ID_3WARE_9550SX 0x1003 +#endif /* Bitmask macros to eliminate bitfields */ @@ -443,6 +445,7 @@ static twa_message_type twa_error_table[] = { #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4) #define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8)) #define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC) +#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30) #define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x))) #define TW_CLEAR_ATTENTION_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x))) #define TW_CLEAR_HOST_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x))) @@ -669,7 +672,7 @@ typedef struct TAG_TW_Device_Extension { u32 ioctl_msec; int chrdev_request_id; wait_queue_head_t ioctl_wqueue; - struct semaphore ioctl_sem; + struct mutex ioctl_lock; char aen_clobber; unsigned short working_srl; unsigned short working_branch; diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 6a0f9506e..4ce743860 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -238,6 +238,14 @@ static char *NCR_700_SBCL_to_phase[] = { "MSG IN", }; +static __u8 NCR_700_SDTR_msg[] = { + 0x01, /* Extended message */ + 0x03, /* Extended message Length */ + 0x01, /* SDTR Extended message */ + NCR_700_MIN_PERIOD, + NCR_700_MAX_OFFSET +}; + /* This translates the SDTR message offset and period to a value * which can be loaded into the SXFER_REG. * @@ -258,7 +266,7 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata, return 0; if(period < hostdata->min_period) { - printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD*4); + printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4); period = hostdata->min_period; } XFERP = (period*4 * hostdata->sync_clock)/1000 - 4; @@ -1426,9 +1434,11 @@ NCR_700_start_command(struct scsi_cmnd *SCp) if(hostdata->fast && NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) { - count += spi_populate_sync_msg(&hostdata->msgout[count], - spi_period(SCp->device->sdev_target), - spi_offset(SCp->device->sdev_target)); + memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg, + sizeof(NCR_700_SDTR_msg)); + hostdata->msgout[count+3] = spi_period(SCp->device->sdev_target); + hostdata->msgout[count+4] = spi_offset(SCp->device->sdev_target); + count += sizeof(NCR_700_SDTR_msg); NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index bde3d5834..1c4593432 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -41,8 +41,6 @@ #include #include #include -#include -#include #include #include @@ -678,7 +676,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, (u64) 0xffffffff)) continue; Bus = PCI_Device->bus->number; @@ -833,7 +831,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, (u64) 0xffffffff)) continue; Bus = PCI_Device->bus->number; @@ -887,7 +885,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, (u64) 0xffffffff)) continue; Bus = PCI_Device->bus->number; @@ -2898,7 +2896,7 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou */ if (HostAdapter->ActiveCommands[TargetID] == 0) HostAdapter->LastSequencePoint[TargetID] = jiffies; - else if (time_after(jiffies, HostAdapter->LastSequencePoint[TargetID] + 4 * HZ)) { + else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4 * HZ) { HostAdapter->LastSequencePoint[TargetID] = jiffies; QueueTag = BusLogic_OrderedQueueTag; } diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 8e3d949b7..8d64f0bed 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -15,46 +15,116 @@ */ + #include + #ifndef CONFIG_SCSI_OMIT_FLASHPOINT + #define MAX_CARDS 8 #undef BUSTYPE_PCI + +#define OS_InPortByte(port) inb(port) +#define OS_InPortWord(port) inw(port) +#define OS_InPortLong(port) inl(port) +#define OS_OutPortByte(port, value) outb(value, port) +#define OS_OutPortWord(port, value) outw(value, port) +#define OS_OutPortLong(port, value) outl(value, port) + + +/* + Define name replacements for compatibility with the Linux BusLogic Driver. +*/ + +#define SccbMgr_sense_adapter FlashPoint_ProbeHostAdapter +#define SccbMgr_config_adapter FlashPoint_HardwareResetHostAdapter +#define SccbMgr_unload_card FlashPoint_ReleaseHostAdapter +#define SccbMgr_start_sccb FlashPoint_StartCCB +#define SccbMgr_abort_sccb FlashPoint_AbortCCB +#define SccbMgr_my_int FlashPoint_InterruptPending +#define SccbMgr_isr FlashPoint_HandleInterrupt + + +#define MAX_CDBLEN 12 + +#define SCAM_LEV_2 1 + #define CRCMASK 0xA001 +#define BL_VENDOR_ID 0x104B +#define FP_DEVICE_ID 0x8130 +#define MM_DEVICE_ID 0x1040 + + #define FAILURE 0xFFFFFFFFL -#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */ -#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */ - -struct sccb; -typedef void (*CALL_BK_FN) (struct sccb *); - -struct sccb_mgr_info { - unsigned long si_baseaddr; - unsigned char si_present; - unsigned char si_intvect; - unsigned char si_id; - unsigned char si_lun; - unsigned short si_fw_revision; - unsigned short si_per_targ_init_sync; - unsigned short si_per_targ_fast_nego; - unsigned short si_per_targ_ultra_nego; - unsigned short si_per_targ_no_disc; - unsigned short si_per_targ_wide_nego; - unsigned short si_flags; - unsigned char si_card_family; - unsigned char si_bustype; - unsigned char si_card_model[3]; - unsigned char si_relative_cardnum; - unsigned char si_reserved[4]; - unsigned long si_OS_reserved; - unsigned char si_XlatInfo[4]; - unsigned long si_reserved2[5]; - unsigned long si_secondary_range; -}; + +typedef unsigned char UCHAR; +typedef unsigned short USHORT; +typedef unsigned int UINT; +typedef unsigned long ULONG; +typedef unsigned char * PUCHAR; +typedef unsigned short* PUSHORT; +typedef unsigned long * PULONG; +typedef void * PVOID; + + +typedef unsigned char * uchar_ptr; +typedef unsigned short * ushort_ptr; +typedef unsigned long * ulong_ptr; + + +#define s08bits char +#define s16bits short +#define s32bits long + +#define u08bits unsigned s08bits +#define u16bits unsigned s16bits +#define u32bits unsigned s32bits + +typedef u08bits * pu08bits; +typedef u16bits * pu16bits; +typedef u32bits * pu32bits; + + +#define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */ +#define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */ + + + + +typedef struct _SCCB *PSCCB; +typedef void (*CALL_BK_FN)(PSCCB); + + +typedef struct SCCBMgr_info { + ULONG si_baseaddr; + UCHAR si_present; + UCHAR si_intvect; + UCHAR si_id; + UCHAR si_lun; + USHORT si_fw_revision; + USHORT si_per_targ_init_sync; + USHORT si_per_targ_fast_nego; + USHORT si_per_targ_ultra_nego; + USHORT si_per_targ_no_disc; + USHORT si_per_targ_wide_nego; + USHORT si_flags; + UCHAR si_card_family; + UCHAR si_bustype; + UCHAR si_card_model[3]; + UCHAR si_relative_cardnum; + UCHAR si_reserved[4]; + ULONG si_OS_reserved; + UCHAR si_XlatInfo[4]; + ULONG si_reserved2[5]; + ULONG si_secondary_range; +} SCCBMGR_INFO; + +typedef SCCBMGR_INFO * PSCCBMGR_INFO; + #define SCSI_PARITY_ENA 0x0001 #define LOW_BYTE_TERM 0x0010 @@ -68,81 +138,107 @@ struct sccb_mgr_info { #define FLAG_SCAM_ENABLED 0x0080 #define FLAG_SCAM_LEVEL2 0x0100 + + + #define HARPOON_FAMILY 0x02 + +#define ISA_BUS_CARD 0x01 +#define EISA_BUS_CARD 0x02 +#define PCI_BUS_CARD 0x03 +#define VESA_BUS_CARD 0x04 + /* SCCB struct used for both SCCB and UCB manager compiles! * The UCB Manager treats the SCCB as it's 'native hardware structure' */ + #pragma pack(1) -struct sccb { - unsigned char OperationCode; - unsigned char ControlByte; - unsigned char CdbLength; - unsigned char RequestSenseLength; - unsigned long DataLength; - unsigned long DataPointer; - unsigned char CcbRes[2]; - unsigned char HostStatus; - unsigned char TargetStatus; - unsigned char TargID; - unsigned char Lun; - unsigned char Cdb[12]; - unsigned char CcbRes1; - unsigned char Reserved1; - unsigned long Reserved2; - unsigned long SensePointer; - - CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */ - unsigned long SccbIOPort; /* Identifies board base port */ - unsigned char SccbStatus; - unsigned char SCCBRes2; - unsigned short SccbOSFlags; - - unsigned long Sccb_XferCnt; /* actual transfer count */ - unsigned long Sccb_ATC; - unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */ - unsigned long Sccb_res1; - unsigned short Sccb_MGRFlags; - unsigned short Sccb_sgseg; - unsigned char Sccb_scsimsg; /* identify msg for selection */ - unsigned char Sccb_tag; - unsigned char Sccb_scsistat; - unsigned char Sccb_idmsg; /* image of last msg in */ - struct sccb *Sccb_forwardlink; - struct sccb *Sccb_backlink; - unsigned long Sccb_savedATC; - unsigned char Save_Cdb[6]; - unsigned char Save_CdbLen; - unsigned char Sccb_XferState; - unsigned long Sccb_SGoffset; -}; +typedef struct _SCCB { + UCHAR OperationCode; + UCHAR ControlByte; + UCHAR CdbLength; + UCHAR RequestSenseLength; + ULONG DataLength; + ULONG DataPointer; + UCHAR CcbRes[2]; + UCHAR HostStatus; + UCHAR TargetStatus; + UCHAR TargID; + UCHAR Lun; + UCHAR Cdb[12]; + UCHAR CcbRes1; + UCHAR Reserved1; + ULONG Reserved2; + ULONG SensePointer; + + + CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */ + ULONG SccbIOPort; /* Identifies board base port */ + UCHAR SccbStatus; + UCHAR SCCBRes2; + USHORT SccbOSFlags; + + + ULONG Sccb_XferCnt; /* actual transfer count */ + ULONG Sccb_ATC; + ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */ + ULONG Sccb_res1; + USHORT Sccb_MGRFlags; + USHORT Sccb_sgseg; + UCHAR Sccb_scsimsg; /* identify msg for selection */ + UCHAR Sccb_tag; + UCHAR Sccb_scsistat; + UCHAR Sccb_idmsg; /* image of last msg in */ + PSCCB Sccb_forwardlink; + PSCCB Sccb_backlink; + ULONG Sccb_savedATC; + UCHAR Save_Cdb[6]; + UCHAR Save_CdbLen; + UCHAR Sccb_XferState; + ULONG Sccb_SGoffset; + } SCCB; + +#define SCCB_SIZE sizeof(SCCB) #pragma pack() + + +#define SCSI_INITIATOR_COMMAND 0x00 +#define TARGET_MODE_COMMAND 0x01 #define SCATTER_GATHER_COMMAND 0x02 #define RESIDUAL_COMMAND 0x03 #define RESIDUAL_SG_COMMAND 0x04 #define RESET_COMMAND 0x81 -#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */ -#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */ -#define SCCB_DATA_XFER_OUT 0x10 /* Write */ -#define SCCB_DATA_XFER_IN 0x08 /* Read */ -#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */ +#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */ +#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */ +#define TAG_Q_MASK 0xE0 +#define SCCB_DATA_XFER_OUT 0x10 /* Write */ +#define SCCB_DATA_XFER_IN 0x08 /* Read */ -#define BUS_FREE_ST 0 + +#define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */ +#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */ + + +#define BUS_FREE_ST 0 #define SELECT_ST 1 -#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */ -#define SELECT_SN_ST 3 /* Select w\ Sync Nego */ -#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */ -#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */ +#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */ +#define SELECT_SN_ST 3 /* Select w\ Sync Nego */ +#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */ +#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */ #define COMMAND_ST 6 #define DATA_OUT_ST 7 #define DATA_IN_ST 8 #define DISCONNECT_ST 9 +#define STATUS_ST 10 #define ABORT_ST 11 +#define MESSAGE_ST 12 + #define F_HOST_XFER_DIR 0x01 #define F_ALL_XFERRED 0x02 @@ -151,115 +247,163 @@ struct sccb { #define F_ODD_BALL_CNT 0x10 #define F_NO_DATA_YET 0x80 + #define F_STATUSLOADED 0x01 +#define F_MSGLOADED 0x02 #define F_DEV_SELECTED 0x04 -#define SCCB_COMPLETE 0x00 /* SCCB completed without error */ + +#define SCCB_COMPLETE 0x00 /* SCCB completed without error */ #define SCCB_DATA_UNDER_RUN 0x0C -#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */ +#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */ #define SCCB_DATA_OVER_RUN 0x12 -#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */ +#define SCCB_UNEXPECTED_BUS_FREE 0x13 /* Target dropped SCSI BSY */ +#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */ + +#define SCCB_INVALID_OP_CODE 0x16 /* SCCB invalid operation code */ +#define SCCB_INVALID_SCCB 0x1A /* Invalid SCCB - bad parameter */ +#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */ +#define SCCB_BM_ERR 0x30 /* BusMaster error. */ +#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */ + + + +#define SCCB_INVALID_DIRECTION 0x18 /* Invalid target direction */ +#define SCCB_DUPLICATE_SCCB 0x19 /* Duplicate SCCB */ +#define SCCB_SCSI_RST 0x35 /* SCSI RESET detected. */ -#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */ -#define SCCB_BM_ERR 0x30 /* BusMaster error. */ -#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */ #define SCCB_IN_PROCESS 0x00 #define SCCB_SUCCESS 0x01 #define SCCB_ABORT 0x02 +#define SCCB_NOT_FOUND 0x03 #define SCCB_ERROR 0x04 +#define SCCB_INVALID 0x05 + +#define SCCB_SIZE sizeof(SCCB) + #define ORION_FW_REV 3110 -#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */ +#define HARP_REVD 1 -#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */ + +#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */ + +#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */ + +#define WIDE_SCSI 1 #define MAX_SCSI_TAR 16 #define MAX_LUN 32 #define LUN_MASK 0x1f -#define SG_BUF_CNT 16 /*Number of prefetched elements. */ +#if defined(HARP_REVA) +#define SG_BUF_CNT 15 /*Number of prefetched elements. */ +#else +#define SG_BUF_CNT 16 /*Number of prefetched elements. */ +#endif + +#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */ +#define SG_LOCAL_MASK 0x00000000L +#define SG_ELEMENT_MASK 0xFFFFFFFFL -#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */ -#define RD_HARPOON(ioport) inb((u32)ioport) -#define RDW_HARPOON(ioport) inw((u32)ioport) -#define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset))) -#define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport) -#define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport) -#define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset)) +#define RD_HARPOON(ioport) OS_InPortByte((u32bits)ioport) +#define RDW_HARPOON(ioport) OS_InPortWord((u32bits)ioport) +#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset))) +#define WR_HARPOON(ioport,val) OS_OutPortByte((u32bits)ioport,(u08bits) val) +#define WRW_HARPOON(ioport,val) OS_OutPortWord((u32bits)ioport,(u16bits)val) +#define WR_HARP32(ioport,offset,data) OS_OutPortLong((u32bits)(ioport + offset), data) + #define TAR_SYNC_MASK (BIT(7)+BIT(6)) +#define SYNC_UNKNOWN 0x00 #define SYNC_TRYING BIT(6) #define SYNC_SUPPORTED (BIT(7)+BIT(6)) #define TAR_WIDE_MASK (BIT(5)+BIT(4)) +#define WIDE_DISABLED 0x00 #define WIDE_ENABLED BIT(4) #define WIDE_NEGOCIATED BIT(5) #define TAR_TAG_Q_MASK (BIT(3)+BIT(2)) +#define TAG_Q_UNKNOWN 0x00 #define TAG_Q_TRYING BIT(2) #define TAG_Q_REJECT BIT(3) +#define TAG_Q_SUPPORTED (BIT(3)+BIT(2)) #define TAR_ALLOW_DISC BIT(0) + #define EE_SYNC_MASK (BIT(0)+BIT(1)) +#define EE_SYNC_ASYNC 0x00 #define EE_SYNC_5MB BIT(0) #define EE_SYNC_10MB BIT(1) #define EE_SYNC_20MB (BIT(0)+BIT(1)) +#define EE_ALLOW_DISC BIT(6) #define EE_WIDE_SCSI BIT(7) -struct sccb_mgr_tar_info { - - struct sccb *TarSelQ_Head; - struct sccb *TarSelQ_Tail; - unsigned char TarLUN_CA; /*Contingent Allgiance */ - unsigned char TarTagQ_Cnt; - unsigned char TarSelQ_Cnt; - unsigned char TarStatus; - unsigned char TarEEValue; - unsigned char TarSyncCtrl; - unsigned char TarReserved[2]; /* for alignment */ - unsigned char LunDiscQ_Idx[MAX_LUN]; - unsigned char TarLUNBusy[MAX_LUN]; -}; - -struct nvram_info { - unsigned char niModel; /* Model No. of card */ - unsigned char niCardNo; /* Card no. */ - unsigned long niBaseAddr; /* Port Address of card */ - unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */ - unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */ - unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */ - unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */ - unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */ - unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */ -}; + +typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info; + + +typedef struct SCCBMgr_tar_info { + + PSCCB TarSelQ_Head; + PSCCB TarSelQ_Tail; + UCHAR TarLUN_CA; /*Contingent Allgiance */ + UCHAR TarTagQ_Cnt; + UCHAR TarSelQ_Cnt; + UCHAR TarStatus; + UCHAR TarEEValue; + UCHAR TarSyncCtrl; + UCHAR TarReserved[2]; /* for alignment */ + UCHAR LunDiscQ_Idx[MAX_LUN]; + UCHAR TarLUNBusy[MAX_LUN]; +} SCCBMGR_TAR_INFO; + +typedef struct NVRAMInfo { + UCHAR niModel; /* Model No. of card */ + UCHAR niCardNo; /* Card no. */ + ULONG niBaseAddr; /* Port Address of card */ + UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */ + UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */ + UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */ + UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */ + UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */ + UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */ +}NVRAMINFO; + +typedef NVRAMINFO *PNVRamInfo; #define MODEL_LT 1 #define MODEL_DL 2 #define MODEL_LW 3 #define MODEL_DW 4 -struct sccb_card { - struct sccb *currentSCCB; - struct sccb_mgr_info *cardInfo; - unsigned long ioPort; +typedef struct SCCBcard { + PSCCB currentSCCB; + PSCCBMGR_INFO cardInfo; - unsigned short cmdCounter; - unsigned char discQCount; - unsigned char tagQ_Lst; - unsigned char cardIndex; - unsigned char scanIndex; - unsigned char globalFlags; - unsigned char ourId; - struct nvram_info *pNvRamInfo; - struct sccb *discQ_Tbl[QUEUE_DEPTH]; + ULONG ioPort; + + USHORT cmdCounter; + UCHAR discQCount; + UCHAR tagQ_Lst; + UCHAR cardIndex; + UCHAR scanIndex; + UCHAR globalFlags; + UCHAR ourId; + PNVRamInfo pNvRamInfo; + PSCCB discQ_Tbl[QUEUE_DEPTH]; + +}SCCBCARD; + +typedef struct SCCBcard *PSCCBcard; -}; #define F_TAG_STARTED 0x01 #define F_CONLUN_IO 0x02 @@ -270,10 +414,13 @@ struct sccb_card { #define F_NEW_SCCB_CMD 0x40 #define F_UPDATE_EEPROM 0x80 + #define ID_STRING_LENGTH 32 -#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */ +#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */ + +#define TYPE_CODE1 00 /*No ID yet */ -#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */ +#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */ #define ASSIGN_ID 0x00 #define SET_P_FLAG 0x01 @@ -283,42 +430,97 @@ struct sccb_card { #define ID_0_7 0x18 #define ID_8_F 0x11 +#define ID_10_17 0x12 +#define ID_18_1F 0x0B #define MISC_CODE 0x14 #define CLR_P_FLAG 0x18 +#define LOCATE_ON 0x12 +#define LOCATE_OFF 0x0B + +#define LVL_1_MST 0x00 +#define LVL_2_MST 0x40 +#define DOM_LVL_2 0xC0 + #define INIT_SELTD 0x01 #define LEVEL2_TAR 0x02 -enum scam_id_st { ID0, ID1, ID2, ID3, ID4, ID5, ID6, ID7, ID8, ID9, ID10, ID11, - ID12, - ID13, ID14, ID15, ID_UNUSED, ID_UNASSIGNED, ID_ASSIGNED, LEGACY, - CLR_PRIORITY, NO_ID_AVAIL -}; + +enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12, + ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY, + CLR_PRIORITY,NO_ID_AVAIL }; typedef struct SCCBscam_info { - unsigned char id_string[ID_STRING_LENGTH]; - enum scam_id_st state; + UCHAR id_string[ID_STRING_LENGTH]; + enum scam_id_st state; + +} SCCBSCAM_INFO, *PSCCBSCAM_INFO; -} SCCBSCAM_INFO; +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_REZERO_UNIT 0x01 #define SCSI_REQUEST_SENSE 0x03 +#define SCSI_FORMAT_UNIT 0x04 +#define SCSI_REASSIGN 0x07 #define SCSI_READ 0x08 #define SCSI_WRITE 0x0A +#define SCSI_SEEK 0x0B +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT 0x15 +#define SCSI_RESERVE_UNIT 0x16 +#define SCSI_RELEASE_UNIT 0x17 +#define SCSI_MODE_SENSE 0x1A #define SCSI_START_STOP_UNIT 0x1B +#define SCSI_SEND_DIAGNOSTIC 0x1D +#define SCSI_READ_CAPACITY 0x25 #define SCSI_READ_EXTENDED 0x28 #define SCSI_WRITE_EXTENDED 0x2A +#define SCSI_SEEK_EXTENDED 0x2B #define SCSI_WRITE_AND_VERIFY 0x2E +#define SCSI_VERIFY 0x2F +#define SCSI_READ_DEFECT_DATA 0x37 +#define SCSI_WRITE_BUFFER 0x3B +#define SCSI_READ_BUFFER 0x3C +#define SCSI_RECV_DIAGNOSTIC 0x1C +#define SCSI_READ_LONG 0x3E +#define SCSI_WRITE_LONG 0x3F +#define SCSI_LAST_SCSI_CMND SCSI_WRITE_LONG +#define SCSI_INVALID_CMND 0xFF + + #define SSGOOD 0x00 #define SSCHECK 0x02 +#define SSCOND_MET 0x04 +#define SSBUSY 0x08 +#define SSRESERVATION_CONFLICT 0x18 +#define SSCMD_TERM 0x22 #define SSQ_FULL 0x28 + +#define SKNO_SEN 0x00 +#define SKRECOV_ERR 0x01 +#define SKNOT_RDY 0x02 +#define SKMED_ERR 0x03 +#define SKHW_ERR 0x04 +#define SKILL_REQ 0x05 +#define SKUNIT_ATTN 0x06 +#define SKDATA_PROTECT 0x07 +#define SKBLNK_CHK 0x08 +#define SKCPY_ABORT 0x0A +#define SKABORT_CMD 0x0B +#define SKEQUAL 0x0C +#define SKVOL_OVF 0x0D +#define SKMIS_CMP 0x0E + + #define SMCMD_COMP 0x00 #define SMEXT 0x01 #define SMSAVE_DATA_PTR 0x02 #define SMREST_DATA_PTR 0x03 #define SMDISC 0x04 +#define SMINIT_DETEC_ERR 0x05 #define SMABORT 0x06 #define SMREJECT 0x07 #define SMNO_OP 0x08 @@ -331,31 +533,62 @@ typedef struct SCCBscam_info { #define SMIDENT 0x80 #define DISC_PRIV 0x40 + #define SMSYNC 0x01 +#define SM10MBS 0x19 /* 100ns */ +#define SM5MBS 0x32 /* 200ns */ +#define SMOFFSET 0x0F /* Maxoffset value */ #define SMWDTR 0x03 #define SM8BIT 0x00 #define SM16BIT 0x01 -#define SMIGNORWR 0x23 /* Ignore Wide Residue */ +#define SM32BIT 0x02 +#define SMIGNORWR 0x23 /* Ignore Wide Residue */ + + +#define ARBITRATION_DELAY 0x01 /* 2.4us using a 40Mhz clock */ +#define BUS_SETTLE_DELAY 0x01 /* 400ns */ +#define BUS_CLEAR_DELAY 0x01 /* 800ns */ + + + +#define SPHASE_TO 0x0A /* 10 second timeout waiting for */ +#define SCMD_TO 0x0F /* Overall command timeout */ + + #define SIX_BYTE_CMD 0x06 +#define TEN_BYTE_CMD 0x0A #define TWELVE_BYTE_CMD 0x0C #define ASYNC 0x00 -#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */ +#define PERI25NS 0x06 /* 25/4ns to next clock for xbow. */ +#define SYNC10MBS 0x19 +#define SYNC5MBS 0x32 +#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */ + #define EEPROM_WD_CNT 256 #define EEPROM_CHECK_SUM 0 #define FW_SIGNATURE 2 #define MODEL_NUMB_0 4 +#define MODEL_NUMB_1 5 #define MODEL_NUMB_2 6 +#define MODEL_NUMB_3 7 #define MODEL_NUMB_4 8 +#define MODEL_NUMB_5 9 +#define IO_BASE_ADDR 10 +#define IRQ_NUMBER 12 +#define PCI_INT_PIN 13 +#define BUS_DELAY 14 /*On time in byte 14 off delay in 15 */ #define SYSTEM_CONFIG 16 #define SCSI_CONFIG 17 #define BIOS_CONFIG 18 +#define SPIN_UP_DELAY 19 #define SCAM_CONFIG 20 #define ADAPTER_SCSI_ID 24 + #define IGNORE_B_SCAN 32 #define SEND_START_ENA 34 #define DEVICE_ENABLE 36 @@ -370,405 +603,717 @@ typedef struct SCCBscam_info { #define SYNC_RATE_TBLcd 50 #define SYNC_RATE_TBLef 52 -#define EE_SCAMBASE 256 -#define SCAM_ENABLED BIT(2) -#define SCAM_LEVEL2 BIT(3) -#define RENEGO_ENA BITW(10) -#define CONNIO_ENA BITW(11) -#define GREEN_PC_ENA BITW(12) +#define EE_SCAMBASE 256 + + -#define AUTO_RATE_00 00 -#define AUTO_RATE_05 01 -#define AUTO_RATE_10 02 -#define AUTO_RATE_20 03 + #define DOM_MASTER (BIT(0) + BIT(1)) + #define SCAM_ENABLED BIT(2) + #define SCAM_LEVEL2 BIT(3) -#define WIDE_NEGO_BIT BIT(7) -#define DISC_ENABLE_BIT BIT(6) -#define hp_vendor_id_0 0x00 /* LSB */ -#define ORION_VEND_0 0x4B + #define RENEGO_ENA BITW(10) + #define CONNIO_ENA BITW(11) + #define GREEN_PC_ENA BITW(12) -#define hp_vendor_id_1 0x01 /* MSB */ -#define ORION_VEND_1 0x10 -#define hp_device_id_0 0x02 /* LSB */ -#define ORION_DEV_0 0x30 + #define AUTO_RATE_00 00 + #define AUTO_RATE_05 01 + #define AUTO_RATE_10 02 + #define AUTO_RATE_20 03 -#define hp_device_id_1 0x03 /* MSB */ -#define ORION_DEV_1 0x81 + #define WIDE_NEGO_BIT BIT(7) + #define DISC_ENABLE_BIT BIT(6) + + + + #define hp_vendor_id_0 0x00 /* LSB */ + #define ORION_VEND_0 0x4B + + #define hp_vendor_id_1 0x01 /* MSB */ + #define ORION_VEND_1 0x10 + + #define hp_device_id_0 0x02 /* LSB */ + #define ORION_DEV_0 0x30 + + #define hp_device_id_1 0x03 /* MSB */ + #define ORION_DEV_1 0x81 /* Sub Vendor ID and Sub Device ID only available in - Harpoon Version 2 and higher */ + Harpoon Version 2 and higher */ + + #define hp_sub_vendor_id_0 0x04 /* LSB */ + #define hp_sub_vendor_id_1 0x05 /* MSB */ + #define hp_sub_device_id_0 0x06 /* LSB */ + #define hp_sub_device_id_1 0x07 /* MSB */ + + + #define hp_dual_addr_lo 0x08 + #define hp_dual_addr_lmi 0x09 + #define hp_dual_addr_hmi 0x0A + #define hp_dual_addr_hi 0x0B + + #define hp_semaphore 0x0C + #define SCCB_MGR_ACTIVE BIT(0) + #define TICKLE_ME BIT(1) + #define SCCB_MGR_PRESENT BIT(3) + #define BIOS_IN_USE BIT(4) + + #define hp_user_defined_D 0x0D + + #define hp_reserved_E 0x0E + + #define hp_sys_ctrl 0x0F + + #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */ + #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */ + #define HALT_MACH BIT(3) /*Halt State Machine */ + #define HARD_ABORT BIT(4) /*Hard Abort */ + #define DIAG_MODE BIT(5) /*Diagnostic Mode */ + + #define BM_ABORT_TMOUT 0x50 /*Halt State machine time out */ + + #define hp_sys_cfg 0x10 + + #define DONT_RST_FIFO BIT(7) /*Don't reset FIFO */ + + + #define hp_host_ctrl0 0x11 + + #define DUAL_ADDR_MODE BIT(0) /*Enable 64-bit addresses */ + #define IO_MEM_SPACE BIT(1) /*I/O Memory Space */ + #define RESOURCE_LOCK BIT(2) /*Enable Resource Lock */ + #define IGNOR_ACCESS_ERR BIT(3) /*Ignore Access Error */ + #define HOST_INT_EDGE BIT(4) /*Host interrupt level/edge mode sel */ + #define SIX_CLOCKS BIT(5) /*6 Clocks between Strobe */ + #define DMA_EVEN_PARITY BIT(6) /*Enable DMA Enen Parity */ + +/* + #define BURST_MODE BIT(0) +*/ + + #define hp_reserved_12 0x12 + + #define hp_host_blk_cnt 0x13 + + #define XFER_BLK1 0x00 /* 0 0 0 1 byte per block*/ + #define XFER_BLK2 0x01 /* 0 0 1 2 byte per block*/ + #define XFER_BLK4 0x02 /* 0 1 0 4 byte per block*/ + #define XFER_BLK8 0x03 /* 0 1 1 8 byte per block*/ + #define XFER_BLK16 0x04 /* 1 0 0 16 byte per block*/ + #define XFER_BLK32 0x05 /* 1 0 1 32 byte per block*/ + #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/ + + #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/ + + + #define hp_reserved_14 0x14 + #define hp_reserved_15 0x15 + #define hp_reserved_16 0x16 + + #define hp_int_mask 0x17 + + #define INT_CMD_COMPL BIT(0) /* DMA command complete */ + #define INT_EXT_STATUS BIT(1) /* Extended Status Set */ + #define INT_SCSI BIT(2) /* Scsi block interrupt */ + #define INT_FIFO_RDY BIT(4) /* FIFO data ready */ + + + #define hp_xfer_cnt_lo 0x18 + #define hp_xfer_cnt_mi 0x19 + #define hp_xfer_cnt_hi 0x1A + #define hp_xfer_cmd 0x1B + + #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */ + #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */ + #define XFER_HOST_MPU 0x02 /* 0 1 0 Transfer Host -> MPU */ + #define XFER_MPU_HOST 0x03 /* 0 1 1 Transfer MPU -> Host */ + #define XFER_DMA_MPU 0x04 /* 1 0 0 Transfer DMA -> MPU */ + #define XFER_MPU_DMA 0x05 /* 1 0 1 Transfer MPU -> DMA */ + #define SET_SEMAPHORE 0x06 /* 1 1 0 Set Semaphore */ + #define XFER_NOP 0x07 /* 1 1 1 Transfer NOP */ + #define XFER_MB_MPU 0x06 /* 1 1 0 Transfer MB -> MPU */ + #define XFER_MB_DMA 0x07 /* 1 1 1 Transfer MB -> DMA */ + + + #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */ + #define XFER_HOST_8BIT 0x08 /* 0 1 8 BIT Transfer Size */ + #define XFER_HOST_16BIT 0x10 /* 1 0 16 BIT Transfer Size */ + #define XFER_HOST_32BIT 0x18 /* 1 1 32 BIT Transfer Size */ + + #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */ + #define XFER_DMA_16BIT 0x40 /* 1 0 16 BIT Transfer Size */ + + #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */ + + #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT)) + #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT)) + #define WIDE_HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_16BIT)) + #define WIDE_HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_16BIT)) + + #define hp_host_addr_lo 0x1C + #define hp_host_addr_lmi 0x1D + #define hp_host_addr_hmi 0x1E + #define hp_host_addr_hi 0x1F + + #define hp_pio_data 0x20 + #define hp_reserved_21 0x21 + #define hp_ee_ctrl 0x22 + + #define EXT_ARB_ACK BIT(7) + #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */ + #define SEE_MS BIT(5) + #define SEE_CS BIT(3) + #define SEE_CLK BIT(2) + #define SEE_DO BIT(1) + #define SEE_DI BIT(0) -#define hp_sub_device_id_0 0x06 /* LSB */ + #define EE_READ 0x06 + #define EE_WRITE 0x05 + #define EWEN 0x04 + #define EWEN_ADDR 0x03C0 + #define EWDS 0x04 + #define EWDS_ADDR 0x0000 -#define hp_semaphore 0x0C -#define SCCB_MGR_ACTIVE BIT(0) -#define TICKLE_ME BIT(1) -#define SCCB_MGR_PRESENT BIT(3) -#define BIOS_IN_USE BIT(4) + #define hp_brdctl 0x23 -#define hp_sys_ctrl 0x0F + #define DAT_7 BIT(7) + #define DAT_6 BIT(6) + #define DAT_5 BIT(5) + #define BRD_STB BIT(4) + #define BRD_CS BIT(3) + #define BRD_WR BIT(2) -#define STOP_CLK BIT(0) /*Turn off BusMaster Clock */ -#define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */ -#define HALT_MACH BIT(3) /*Halt State Machine */ -#define HARD_ABORT BIT(4) /*Hard Abort */ + #define hp_reserved_24 0x24 + #define hp_reserved_25 0x25 -#define hp_host_blk_cnt 0x13 -#define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */ -#define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */ -#define hp_int_mask 0x17 + #define hp_bm_ctrl 0x26 -#define INT_CMD_COMPL BIT(0) /* DMA command complete */ -#define INT_EXT_STATUS BIT(1) /* Extended Status Set */ + #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */ + #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */ + #define BM_XFER_MIN_8 BIT(2) /*Enable bus master transfer of 9 */ + #define BIOS_ENA BIT(3) /*Enable BIOS/FLASH Enable */ + #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */ + #define FAST_SINGLE BIT(6) /*?? */ -#define hp_xfer_cnt_lo 0x18 -#define hp_xfer_cnt_hi 0x1A -#define hp_xfer_cmd 0x1B + #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L) -#define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */ -#define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */ + #define hp_reserved_27 0x27 -#define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */ + #define hp_sg_addr 0x28 + #define hp_page_ctrl 0x29 -#define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */ + #define SCATTER_EN BIT(0) + #define SGRAM_ARAM BIT(1) + #define BIOS_SHADOW BIT(2) + #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */ + #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */ -#define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */ + #define hp_reserved_2A 0x2A + #define hp_pci_cmd_cfg 0x2B -#define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT)) -#define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT)) + #define IO_SPACE_ENA BIT(0) /*enable I/O space */ + #define MEM_SPACE_ENA BIT(1) /*enable memory space */ + #define BUS_MSTR_ENA BIT(2) /*enable bus master operation */ + #define MEM_WI_ENA BIT(4) /*enable Write and Invalidate */ + #define PAR_ERR_RESP BIT(6) /*enable parity error responce. */ -#define hp_host_addr_lo 0x1C -#define hp_host_addr_hmi 0x1E + #define hp_reserved_2C 0x2C -#define hp_ee_ctrl 0x22 + #define hp_pci_stat_cfg 0x2D -#define EXT_ARB_ACK BIT(7) -#define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */ -#define SEE_MS BIT(5) -#define SEE_CS BIT(3) -#define SEE_CLK BIT(2) -#define SEE_DO BIT(1) -#define SEE_DI BIT(0) + #define DATA_PARITY_ERR BIT(0) + #define REC_TARGET_ABORT BIT(4) /*received Target abort */ + #define REC_MASTER_ABORT BIT(5) /*received Master abort */ + #define SIG_SYSTEM_ERR BIT(6) + #define DETECTED_PAR_ERR BIT(7) -#define EE_READ 0x06 -#define EE_WRITE 0x05 -#define EWEN 0x04 -#define EWEN_ADDR 0x03C0 -#define EWDS 0x04 -#define EWDS_ADDR 0x0000 + #define hp_reserved_2E 0x2E -#define hp_bm_ctrl 0x26 + #define hp_sys_status 0x2F -#define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */ -#define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */ -#define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */ -#define FAST_SINGLE BIT(6) /*?? */ + #define SLV_DATA_RDY BIT(0) /*Slave data ready */ + #define XFER_CNT_ZERO BIT(1) /*Transfer counter = 0 */ + #define BM_FIFO_EMPTY BIT(2) /*FIFO empty */ + #define BM_FIFO_FULL BIT(3) /*FIFO full */ + #define HOST_OP_DONE BIT(4) /*host operation done */ + #define DMA_OP_DONE BIT(5) /*DMA operation done */ + #define SLV_OP_DONE BIT(6) /*Slave operation done */ + #define PWR_ON_FLAG BIT(7) /*Power on flag */ -#define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L) + #define hp_reserved_30 0x30 -#define hp_sg_addr 0x28 -#define hp_page_ctrl 0x29 + #define hp_host_status0 0x31 -#define SCATTER_EN BIT(0) -#define SGRAM_ARAM BIT(1) -#define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */ -#define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */ + #define HOST_TERM BIT(5) /*Host Terminal Count */ + #define HOST_TRSHLD BIT(6) /*Host Threshold */ + #define CONNECTED_2_HOST BIT(7) /*Connected to Host */ -#define hp_pci_stat_cfg 0x2D + #define hp_reserved_32 0x32 -#define REC_MASTER_ABORT BIT(5) /*received Master abort */ + #define hp_rev_num 0x33 -#define hp_rev_num 0x33 + #define REV_A_CONST 0x0E + #define REV_B_CONST 0x0E -#define hp_stack_data 0x34 -#define hp_stack_addr 0x35 + #define hp_stack_data 0x34 + #define hp_stack_addr 0x35 -#define hp_ext_status 0x36 + #define hp_ext_status 0x36 -#define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */ -#define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */ -#define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */ -#define CMD_ABORTED BIT(4) /*Command aborted */ -#define BM_PARITY_ERR BIT(5) /*parity error on data received */ -#define PIO_OVERRUN BIT(6) /*Slave data overrun */ -#define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */ -#define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \ + #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */ + #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */ + #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */ + #define FIFO_TC_NOT_ZERO BIT(2) /*FIFO or transfer counter not zero */ + #define CHIP_RST_OCCUR BIT(3) /*Chip reset occurs */ + #define CMD_ABORTED BIT(4) /*Command aborted */ + #define BM_PARITY_ERR BIT(5) /*parity error on data received */ + #define PIO_OVERRUN BIT(6) /*Slave data overrun */ + #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */ + #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \ BM_PARITY_ERR | PIO_OVERRUN) -#define hp_int_status 0x37 - -#define EXT_STATUS_ON BIT(1) /*Extended status is valid */ -#define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */ -#define INT_ASSERTED BIT(5) /* */ - -#define hp_fifo_cnt 0x38 - -#define hp_intena 0x40 - -#define RESET BITW(7) -#define PROG_HLT BITW(6) -#define PARITY BITW(5) -#define FIFO BITW(4) -#define SEL BITW(3) -#define SCAM_SEL BITW(2) -#define RSEL BITW(1) -#define TIMEOUT BITW(0) -#define BUS_FREE BITW(15) -#define XFER_CNT_0 BITW(14) -#define PHASE BITW(13) -#define IUNKWN BITW(12) -#define ICMD_COMP BITW(11) -#define ITICKLE BITW(10) -#define IDO_STRT BITW(9) -#define ITAR_DISC BITW(8) -#define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8)) -#define CLR_ALL_INT 0xFFFF -#define CLR_ALL_INT_1 0xFF00 - -#define hp_intstat 0x42 - -#define hp_scsisig 0x44 - -#define SCSI_SEL BIT(7) -#define SCSI_BSY BIT(6) -#define SCSI_REQ BIT(5) -#define SCSI_ACK BIT(4) -#define SCSI_ATN BIT(3) -#define SCSI_CD BIT(2) -#define SCSI_MSG BIT(1) -#define SCSI_IOBIT BIT(0) - -#define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0)) -#define S_MSGO_PH (BIT(2)+BIT(1) ) -#define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0)) -#define S_DATAI_PH ( BIT(0)) -#define S_DATAO_PH 0x00 -#define S_ILL_PH ( BIT(1) ) - -#define hp_scsictrl_0 0x45 - -#define SEL_TAR BIT(6) -#define ENA_ATN BIT(4) -#define ENA_RESEL BIT(2) -#define SCSI_RST BIT(1) -#define ENA_SCAM_SEL BIT(0) + #define hp_int_status 0x37 + + #define BM_CMD_CMPL BIT(0) /*Bus Master command complete */ + #define EXT_STATUS_ON BIT(1) /*Extended status is valid */ + #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */ + #define BM_FIFO_RDY BIT(4) + #define INT_ASSERTED BIT(5) /* */ + #define SRAM_BUSY BIT(6) /*Scatter/Gather RAM busy */ + #define CMD_REG_BUSY BIT(7) + + + #define hp_fifo_cnt 0x38 + #define hp_curr_host_cnt 0x39 + #define hp_reserved_3A 0x3A + #define hp_fifo_in_addr 0x3B + + #define hp_fifo_out_addr 0x3C + #define hp_reserved_3D 0x3D + #define hp_reserved_3E 0x3E + #define hp_reserved_3F 0x3F + + + + #define hp_intena 0x40 + + #define RESET BITW(7) + #define PROG_HLT BITW(6) + #define PARITY BITW(5) + #define FIFO BITW(4) + #define SEL BITW(3) + #define SCAM_SEL BITW(2) + #define RSEL BITW(1) + #define TIMEOUT BITW(0) + #define BUS_FREE BITW(15) + #define XFER_CNT_0 BITW(14) + #define PHASE BITW(13) + #define IUNKWN BITW(12) + #define ICMD_COMP BITW(11) + #define ITICKLE BITW(10) + #define IDO_STRT BITW(9) + #define ITAR_DISC BITW(8) + #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8)) + #define CLR_ALL_INT 0xFFFF + #define CLR_ALL_INT_1 0xFF00 + + #define hp_intstat 0x42 + + #define hp_scsisig 0x44 + + #define SCSI_SEL BIT(7) + #define SCSI_BSY BIT(6) + #define SCSI_REQ BIT(5) + #define SCSI_ACK BIT(4) + #define SCSI_ATN BIT(3) + #define SCSI_CD BIT(2) + #define SCSI_MSG BIT(1) + #define SCSI_IOBIT BIT(0) + + #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0)) + #define S_CMD_PH (BIT(2) ) + #define S_MSGO_PH (BIT(2)+BIT(1) ) + #define S_STAT_PH (BIT(2) +BIT(0)) + #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0)) + #define S_DATAI_PH ( BIT(0)) + #define S_DATAO_PH 0x00 + #define S_ILL_PH ( BIT(1) ) + + #define hp_scsictrl_0 0x45 + + #define NO_ARB BIT(7) + #define SEL_TAR BIT(6) + #define ENA_ATN BIT(4) + #define ENA_RESEL BIT(2) + #define SCSI_RST BIT(1) + #define ENA_SCAM_SEL BIT(0) + + + + #define hp_portctrl_0 0x46 + + #define SCSI_PORT BIT(7) + #define SCSI_INBIT BIT(6) + #define DMA_PORT BIT(5) + #define DMA_RD BIT(4) + #define HOST_PORT BIT(3) + #define HOST_WRT BIT(2) + #define SCSI_BUS_EN BIT(1) + #define START_TO BIT(0) + + #define hp_scsireset 0x47 + + #define SCSI_TAR BIT(7) + #define SCSI_INI BIT(6) + #define SCAM_EN BIT(5) + #define ACK_HOLD BIT(4) + #define DMA_RESET BIT(3) + #define HPSCSI_RESET BIT(2) + #define PROG_RESET BIT(1) + #define FIFO_CLR BIT(0) + + #define hp_xfercnt_0 0x48 + #define hp_xfercnt_1 0x49 + #define hp_xfercnt_2 0x4A + #define hp_xfercnt_3 0x4B + + #define hp_fifodata_0 0x4C + #define hp_fifodata_1 0x4D + #define hp_addstat 0x4E + + #define SCAM_TIMER BIT(7) + #define AUTO_RUNNING BIT(6) + #define FAST_SYNC BIT(5) + #define SCSI_MODE8 BIT(3) + #define SCSI_PAR_ERR BIT(0) + + #define hp_prgmcnt_0 0x4F + + #define AUTO_PC_MASK 0x3F + + #define hp_selfid_0 0x50 + #define hp_selfid_1 0x51 + #define hp_arb_id 0x52 + + #define ARB_ID (BIT(3) + BIT(2) + BIT(1) + BIT(0)) + + #define hp_select_id 0x53 + + #define RESEL_ID (BIT(7) + BIT(6) + BIT(5) + BIT(4)) + #define SELECT_ID (BIT(3) + BIT(2) + BIT(1) + BIT(0)) + + #define hp_synctarg_base 0x54 + #define hp_synctarg_12 0x54 + #define hp_synctarg_13 0x55 + #define hp_synctarg_14 0x56 + #define hp_synctarg_15 0x57 + + #define hp_synctarg_8 0x58 + #define hp_synctarg_9 0x59 + #define hp_synctarg_10 0x5A + #define hp_synctarg_11 0x5B + + #define hp_synctarg_4 0x5C + #define hp_synctarg_5 0x5D + #define hp_synctarg_6 0x5E + #define hp_synctarg_7 0x5F + + #define hp_synctarg_0 0x60 + #define hp_synctarg_1 0x61 + #define hp_synctarg_2 0x62 + #define hp_synctarg_3 0x63 + + #define RATE_20MB 0x00 + #define RATE_10MB ( BIT(5)) + #define RATE_6_6MB ( BIT(6) ) + #define RATE_5MB ( BIT(6)+BIT(5)) + #define RATE_4MB (BIT(7) ) + #define RATE_3_33MB (BIT(7) +BIT(5)) + #define RATE_2_85MB (BIT(7)+BIT(6) ) + #define RATE_2_5MB (BIT(7)+BIT(5)+BIT(6)) + #define NEXT_CLK BIT(5) + #define SLOWEST_SYNC (BIT(7)+BIT(6)+BIT(5)) + #define NARROW_SCSI BIT(4) + #define SYNC_OFFSET (BIT(3) + BIT(2) + BIT(1) + BIT(0)) + #define DEFAULT_ASYNC 0x00 + #define DEFAULT_OFFSET 0x0F -#define hp_portctrl_0 0x46 + #define hp_autostart_0 0x64 + #define hp_autostart_1 0x65 + #define hp_autostart_2 0x66 + #define hp_autostart_3 0x67 -#define SCSI_PORT BIT(7) -#define SCSI_INBIT BIT(6) -#define DMA_PORT BIT(5) -#define DMA_RD BIT(4) -#define HOST_PORT BIT(3) -#define HOST_WRT BIT(2) -#define SCSI_BUS_EN BIT(1) -#define START_TO BIT(0) -#define hp_scsireset 0x47 -#define SCSI_INI BIT(6) -#define SCAM_EN BIT(5) -#define DMA_RESET BIT(3) -#define HPSCSI_RESET BIT(2) -#define PROG_RESET BIT(1) -#define FIFO_CLR BIT(0) + #define DISABLE 0x00 + #define AUTO_IMMED BIT(5) + #define SELECT BIT(6) + #define RESELECT (BIT(6)+BIT(5)) + #define BUSFREE BIT(7) + #define XFER_0 (BIT(7)+BIT(5)) + #define END_DATA (BIT(7)+BIT(6)) + #define MSG_PHZ (BIT(7)+BIT(6)+BIT(5)) -#define hp_xfercnt_0 0x48 -#define hp_xfercnt_2 0x4A + #define hp_gp_reg_0 0x68 + #define hp_gp_reg_1 0x69 + #define hp_gp_reg_2 0x6A + #define hp_gp_reg_3 0x6B -#define hp_fifodata_0 0x4C -#define hp_addstat 0x4E + #define hp_seltimeout 0x6C -#define SCAM_TIMER BIT(7) -#define SCSI_MODE8 BIT(3) -#define SCSI_PAR_ERR BIT(0) -#define hp_prgmcnt_0 0x4F + #define TO_2ms 0x54 /* 2.0503ms */ + #define TO_4ms 0x67 /* 3.9959ms */ -#define hp_selfid_0 0x50 -#define hp_selfid_1 0x51 -#define hp_arb_id 0x52 + #define TO_5ms 0x03 /* 4.9152ms */ + #define TO_10ms 0x07 /* 11.xxxms */ + #define TO_250ms 0x99 /* 250.68ms */ + #define TO_290ms 0xB1 /* 289.99ms */ + #define TO_350ms 0xD6 /* 350.62ms */ + #define TO_417ms 0xFF /* 417.79ms */ -#define hp_select_id 0x53 + #define hp_clkctrl_0 0x6D -#define hp_synctarg_base 0x54 -#define hp_synctarg_12 0x54 -#define hp_synctarg_13 0x55 -#define hp_synctarg_14 0x56 -#define hp_synctarg_15 0x57 + #define PWR_DWN BIT(6) + #define ACTdeassert BIT(4) + #define ATNonErr BIT(3) + #define CLK_30MHZ BIT(1) + #define CLK_40MHZ (BIT(1) + BIT(0)) + #define CLK_50MHZ BIT(2) -#define hp_synctarg_8 0x58 -#define hp_synctarg_9 0x59 -#define hp_synctarg_10 0x5A -#define hp_synctarg_11 0x5B + #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ) -#define hp_synctarg_4 0x5C -#define hp_synctarg_5 0x5D -#define hp_synctarg_6 0x5E -#define hp_synctarg_7 0x5F + #define hp_fiforead 0x6E + #define hp_fifowrite 0x6F -#define hp_synctarg_0 0x60 -#define hp_synctarg_1 0x61 -#define hp_synctarg_2 0x62 -#define hp_synctarg_3 0x63 + #define hp_offsetctr 0x70 + #define hp_xferstat 0x71 -#define NARROW_SCSI BIT(4) -#define DEFAULT_OFFSET 0x0F + #define FIFO_FULL BIT(7) + #define FIFO_EMPTY BIT(6) + #define FIFO_MASK 0x3F /* Mask for the FIFO count value. */ + #define FIFO_LEN 0x20 -#define hp_autostart_0 0x64 -#define hp_autostart_1 0x65 -#define hp_autostart_3 0x67 + #define hp_portctrl_1 0x72 -#define AUTO_IMMED BIT(5) -#define SELECT BIT(6) -#define END_DATA (BIT(7)+BIT(6)) + #define EVEN_HOST_P BIT(5) + #define INVT_SCSI BIT(4) + #define CHK_SCSI_P BIT(3) + #define HOST_MODE8 BIT(0) + #define HOST_MODE16 0x00 -#define hp_gp_reg_0 0x68 -#define hp_gp_reg_1 0x69 -#define hp_gp_reg_3 0x6B + #define hp_xfer_pad 0x73 -#define hp_seltimeout 0x6C + #define ID_UNLOCK BIT(3) + #define XFER_PAD BIT(2) -#define TO_4ms 0x67 /* 3.9959ms */ + #define hp_scsidata_0 0x74 + #define hp_scsidata_1 0x75 + #define hp_timer_0 0x76 + #define hp_timer_1 0x77 -#define TO_5ms 0x03 /* 4.9152ms */ -#define TO_10ms 0x07 /* 11.xxxms */ -#define TO_250ms 0x99 /* 250.68ms */ -#define TO_290ms 0xB1 /* 289.99ms */ + #define hp_reserved_78 0x78 + #define hp_reserved_79 0x79 + #define hp_reserved_7A 0x7A + #define hp_reserved_7B 0x7B -#define hp_clkctrl_0 0x6D + #define hp_reserved_7C 0x7C + #define hp_reserved_7D 0x7D + #define hp_reserved_7E 0x7E + #define hp_reserved_7F 0x7F -#define PWR_DWN BIT(6) -#define ACTdeassert BIT(4) -#define CLK_40MHZ (BIT(1) + BIT(0)) + #define hp_aramBase 0x80 + #define BIOS_DATA_OFFSET 0x60 + #define BIOS_RELATIVE_CARD 0x64 -#define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ) -#define hp_fiforead 0x6E -#define hp_fifowrite 0x6F -#define hp_offsetctr 0x70 -#define hp_xferstat 0x71 -#define FIFO_EMPTY BIT(6) + #define AUTO_LEN 0x80 + #define AR0 0x00 + #define AR1 BITW(8) + #define AR2 BITW(9) + #define AR3 (BITW(9) + BITW(8)) + #define SDATA BITW(10) -#define hp_portctrl_1 0x72 + #define NOP_OP 0x00 /* Nop command */ -#define CHK_SCSI_P BIT(3) -#define HOST_MODE8 BIT(0) + #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */ -#define hp_xfer_pad 0x73 + #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */ -#define ID_UNLOCK BIT(3) + #define CBE_OP (BITW(14)+BITW(12)+BITW(11)) /* Cmp SCSI cmd class & Branch EQ */ + + #define CBN_OP (BITW(14)+BITW(13)) /* Cmp SCSI cmd class & Branch NOT EQ */ + + #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */ -#define hp_scsidata_0 0x74 -#define hp_scsidata_1 0x75 + #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */ -#define hp_aramBase 0x80 -#define BIOS_DATA_OFFSET 0x60 -#define BIOS_RELATIVE_CARD 0x64 -#define AR3 (BITW(9) + BITW(8)) -#define SDATA BITW(10) + #define ADATA_OUT 0x00 + #define ADATA_IN BITW(8) + #define ACOMMAND BITW(10) + #define ASTATUS (BITW(10)+BITW(8)) + #define AMSG_OUT (BITW(10)+BITW(9)) + #define AMSG_IN (BITW(10)+BITW(9)+BITW(8)) + #define AILLEGAL (BITW(9)+BITW(8)) -#define CRD_OP BITW(11) /* Cmp Reg. w/ Data */ -#define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */ + #define BRH_OP BITW(13) /* Branch */ -#define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */ + + #define ALWAYS 0x00 + #define EQUAL BITW(8) + #define NOT_EQ BITW(9) -#define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */ + #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */ -#define ADATA_OUT 0x00 -#define ADATA_IN BITW(8) -#define ACOMMAND BITW(10) -#define ASTATUS (BITW(10)+BITW(8)) -#define AMSG_OUT (BITW(10)+BITW(9)) -#define AMSG_IN (BITW(10)+BITW(9)+BITW(8)) + + #define ATN_SET BITW(8) + #define ATN_RESET BITW(9) + #define XFER_CNT (BITW(9)+BITW(8)) + #define FIFO_0 BITW(10) + #define FIFO_NOT0 (BITW(10)+BITW(8)) + #define T_USE_SYNC0 (BITW(10)+BITW(9)) -#define BRH_OP BITW(13) /* Branch */ -#define ALWAYS 0x00 -#define EQUAL BITW(8) -#define NOT_EQ BITW(9) + #define MPM_OP BITW(15) /* Match phase and move data */ -#define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */ + #define MDR_OP (BITW(12)+BITW(11)) /* Move data to Reg. */ -#define FIFO_0 BITW(10) + #define MRR_OP BITW(14) /* Move DReg. to Reg. */ -#define MPM_OP BITW(15) /* Match phase and move data */ -#define MRR_OP BITW(14) /* Move DReg. to Reg. */ + #define S_IDREG (BIT(2)+BIT(1)+BIT(0)) -#define S_IDREG (BIT(2)+BIT(1)+BIT(0)) -#define D_AR0 0x00 -#define D_AR1 BIT(0) -#define D_BUCKET (BIT(2) + BIT(1) + BIT(0)) + #define D_AR0 0x00 + #define D_AR1 BIT(0) + #define D_AR2 BIT(1) + #define D_AR3 (BIT(1) + BIT(0)) + #define D_SDATA BIT(2) + #define D_BUCKET (BIT(2) + BIT(1) + BIT(0)) -#define RAT_OP (BITW(14)+BITW(13)+BITW(11)) -#define SSI_OP (BITW(15)+BITW(11)) + #define ADR_OP (BITW(13)+BITW(12)) /* Logical AND Reg. w. Data */ -#define SSI_ITAR_DISC (ITAR_DISC >> 8) -#define SSI_IDO_STRT (IDO_STRT >> 8) + #define ADS_OP (BITW(14)+BITW(13)+BITW(12)) -#define SSI_ICMD_COMP (ICMD_COMP >> 8) -#define SSI_ITICKLE (ITICKLE >> 8) + #define ODR_OP (BITW(13)+BITW(12)+BITW(11)) -#define SSI_IUNKWN (IUNKWN >> 8) -#define SSI_INO_CC (IUNKWN >> 8) -#define SSI_IRFAIL (IUNKWN >> 8) + #define ODS_OP (BITW(14)+BITW(13)+BITW(12)+BITW(11)) -#define NP 0x10 /*Next Phase */ -#define NTCMD 0x02 /*Non- Tagged Command start */ -#define CMDPZ 0x04 /*Command phase */ -#define DINT 0x12 /*Data Out/In interrupt */ -#define DI 0x13 /*Data Out */ -#define DC 0x19 /*Disconnect Message */ -#define ST 0x1D /*Status Phase */ -#define UNKNWN 0x24 /*Unknown bus action */ -#define CC 0x25 /*Command Completion failure */ -#define TICK 0x26 /*New target reselected us. */ -#define SELCHK 0x28 /*Select & Check SCSI ID latch reg */ + #define STR_OP (BITW(15)+BITW(14)) /* Store to A_Reg. */ -#define ID_MSG_STRT hp_aramBase + 0x00 -#define NON_TAG_ID_MSG hp_aramBase + 0x06 -#define CMD_STRT hp_aramBase + 0x08 -#define SYNC_MSGS hp_aramBase + 0x08 + #define AINT_ENA1 0x00 + #define AINT_STAT1 BITW(8) + #define ASCSI_SIG BITW(9) + #define ASCSI_CNTL (BITW(9)+BITW(8)) + #define APORT_CNTL BITW(10) + #define ARST_CNTL (BITW(10)+BITW(8)) + #define AXFERCNT0 (BITW(10)+BITW(9)) + #define AXFERCNT1 (BITW(10)+BITW(9)+BITW(8)) + #define AXFERCNT2 BITW(11) + #define AFIFO_DATA (BITW(11)+BITW(8)) + #define ASCSISELID (BITW(11)+BITW(9)) + #define ASCSISYNC0 (BITW(11)+BITW(9)+BITW(8)) -#define TAG_STRT 0x00 -#define DISCONNECT_START 0x10/2 -#define END_DATA_START 0x14/2 -#define CMD_ONLY_STRT CMDPZ/2 -#define SELCHK_STRT SELCHK/2 + + #define RAT_OP (BITW(14)+BITW(13)+BITW(11)) + + #define SSI_OP (BITW(15)+BITW(11)) + + + #define SSI_ITAR_DISC (ITAR_DISC >> 8) + #define SSI_IDO_STRT (IDO_STRT >> 8) + #define SSI_IDI_STRT (IDO_STRT >> 8) + + #define SSI_ICMD_COMP (ICMD_COMP >> 8) + #define SSI_ITICKLE (ITICKLE >> 8) + + #define SSI_IUNKWN (IUNKWN >> 8) + #define SSI_INO_CC (IUNKWN >> 8) + #define SSI_IRFAIL (IUNKWN >> 8) + + + #define NP 0x10 /*Next Phase */ + #define NTCMD 0x02 /*Non- Tagged Command start */ + #define CMDPZ 0x04 /*Command phase */ + #define DINT 0x12 /*Data Out/In interrupt */ + #define DI 0x13 /*Data Out */ + #define MI 0x14 /*Message In */ + #define DC 0x19 /*Disconnect Message */ + #define ST 0x1D /*Status Phase */ + #define UNKNWN 0x24 /*Unknown bus action */ + #define CC 0x25 /*Command Completion failure */ + #define TICK 0x26 /*New target reselected us. */ + #define RFAIL 0x27 /*Reselection failed */ + #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */ + + + #define ID_MSG_STRT hp_aramBase + 0x00 + #define NON_TAG_ID_MSG hp_aramBase + 0x06 + #define CMD_STRT hp_aramBase + 0x08 + #define SYNC_MSGS hp_aramBase + 0x08 + + + + + + #define TAG_STRT 0x00 + #define SELECTION_START 0x00 + #define DISCONNECT_START 0x10/2 + #define END_DATA_START 0x14/2 + #define NONTAG_STRT 0x02/2 + #define CMD_ONLY_STRT CMDPZ/2 + #define TICKLE_STRT TICK/2 + #define SELCHK_STRT SELCHK/2 + + + + +#define mEEPROM_CLK_DELAY(port) (RD_HARPOON(port+hp_intstat_1)) + +#define mWAIT_10MS(port) (RD_HARPOON(port+hp_intstat_1)) + + +#define CLR_XFER_CNT(port) (WR_HARPOON(port+hp_xfercnt_0, 0x00)) + +#define SET_XFER_CNT(port, data) (WR_HARP32(port,hp_xfercnt_0,data)) #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;} /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \ xfercnt <<= 16,\ - xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0))) + xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0))) */ -#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\ +#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\ addr >>= 16,\ - WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\ + WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\ WR_HARP32(port,hp_xfercnt_0,count),\ - WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\ + WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\ count >>= 16,\ WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF))) #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\ WR_HARPOON(port+hp_scsisig, S_ILL_PH);} + #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\ WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));} +#define ACCEPT_STAT(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\ + WR_HARPOON(port+hp_scsisig, S_ILL_PH);} + +#define ACCEPT_STAT_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\ + WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));} + #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\ WR_HARPOON(port+hp_scsireset, 0x00)) @@ -784,1220 +1329,1194 @@ typedef struct SCCBscam_info { #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \ (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE))) -static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, - unsigned char syncFlag); -static void FPT_ssel(unsigned long port, unsigned char p_card); -static void FPT_sres(unsigned long port, unsigned char p_card, - struct sccb_card *pCurrCard); -static void FPT_shandem(unsigned long port, unsigned char p_card, - struct sccb *pCurrSCCB); -static void FPT_stsyncn(unsigned long port, unsigned char p_card); -static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse, - unsigned char offset); -static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, - unsigned char p_sync_value, - struct sccb_mgr_tar_info *currTar_Info); -static void FPT_sresb(unsigned long port, unsigned char p_card); -static void FPT_sxfrp(unsigned long p_port, unsigned char p_card); -static void FPT_schkdd(unsigned long port, unsigned char p_card); -static unsigned char FPT_RdStack(unsigned long port, unsigned char index); -static void FPT_WrStack(unsigned long portBase, unsigned char index, - unsigned char data); -static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort); - -static void FPT_SendMsg(unsigned long port, unsigned char message); -static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg, - unsigned char error_code); - -static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card); -static void FPT_RNVRamData(struct nvram_info *pNvRamInfo); - -static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card); -static void FPT_stwidn(unsigned long port, unsigned char p_card); -static void FPT_siwidr(unsigned long port, unsigned char width); - -static void FPT_queueSelectFail(struct sccb_card *pCurrCard, - unsigned char p_card); -static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card); -static void FPT_queueCmdComplete(struct sccb_card *pCurrCard, - struct sccb *p_SCCB, unsigned char p_card); -static void FPT_queueSearchSelect(struct sccb_card *pCurrCard, - unsigned char p_card); -static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code); -static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card); -static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB, - unsigned char p_card); -static void FPT_utilUpdateResidual(struct sccb *p_SCCB); -static unsigned short FPT_CalcCrc16(unsigned char buffer[]); -static unsigned char FPT_CalcLrc(unsigned char buffer[]); - -static void FPT_Wait1Second(unsigned long p_port); -static void FPT_Wait(unsigned long p_port, unsigned char p_delay); -static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode); -static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, - unsigned short ee_addr); -static unsigned short FPT_utilEERead(unsigned long p_port, - unsigned short ee_addr); -static unsigned short FPT_utilEEReadOrg(unsigned long p_port, - unsigned short ee_addr); -static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, - unsigned short ee_addr); - -static void FPT_phaseDataOut(unsigned long port, unsigned char p_card); -static void FPT_phaseDataIn(unsigned long port, unsigned char p_card); -static void FPT_phaseCommand(unsigned long port, unsigned char p_card); -static void FPT_phaseStatus(unsigned long port, unsigned char p_card); -static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card); -static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card); -static void FPT_phaseIllegal(unsigned long port, unsigned char p_card); - -static void FPT_phaseDecode(unsigned long port, unsigned char p_card); -static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card); -static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card); - -static void FPT_XbowInit(unsigned long port, unsigned char scamFlg); -static void FPT_BusMasterInit(unsigned long p_port); -static void FPT_DiagEEPROM(unsigned long p_port); - -static void FPT_dataXferProcessor(unsigned long port, - struct sccb_card *pCurrCard); -static void FPT_busMstrSGDataXferStart(unsigned long port, - struct sccb *pCurrSCCB); -static void FPT_busMstrDataXferStart(unsigned long port, - struct sccb *pCurrSCCB); -static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, - struct sccb *pCurrSCCB); -static void FPT_hostDataXferRestart(struct sccb *currSCCB); - -static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, - unsigned char p_card, - struct sccb_card *pCurrCard, - unsigned short p_int); - -static void FPT_SccbMgrTableInitAll(void); -static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard, - unsigned char p_card); -static void FPT_SccbMgrTableInitTarget(unsigned char p_card, - unsigned char target); - -static void FPT_scini(unsigned char p_card, unsigned char p_our_id, - unsigned char p_power_up); - -static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type); -static void FPT_scbusf(unsigned long p_port); -static void FPT_scsel(unsigned long p_port); -static void FPT_scasid(unsigned char p_card, unsigned long p_port); -static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data); -static unsigned char FPT_scsendi(unsigned long p_port, - unsigned char p_id_string[]); -static unsigned char FPT_sciso(unsigned long p_port, - unsigned char p_id_string[]); -static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit); -static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit); -static unsigned char FPT_scvalq(unsigned char p_quintet); -static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id); -static void FPT_scwtsel(unsigned long p_port); -static void FPT_inisci(unsigned char p_card, unsigned long p_port, - unsigned char p_our_id); -static void FPT_scsavdi(unsigned char p_card, unsigned long p_port); -static unsigned char FPT_scmachid(unsigned char p_card, - unsigned char p_id_string[]); - -static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card); -static void FPT_autoLoadDefaultMap(unsigned long p_port); - -static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = - { {{0}} }; -static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} }; -static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} }; -static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} }; - -static unsigned char FPT_mbCards = 0; -static unsigned char FPT_scamHAString[] = - { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', - ' ', 'B', 'T', '-', '9', '3', '0', - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 -}; - -static unsigned short FPT_default_intena = 0; - -static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char) = { -0}; + + + +void scsiStartAuto(ULONG port); +static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag); +static void FPT_ssel(ULONG port, UCHAR p_card); +static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard); +static void FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB); +static void FPT_stsyncn(ULONG port, UCHAR p_card); +static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset); +static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value, + PSCCBMgr_tar_info currTar_Info); +static void FPT_sresb(ULONG port, UCHAR p_card); +static void FPT_sxfrp(ULONG p_port, UCHAR p_card); +static void FPT_schkdd(ULONG port, UCHAR p_card); +static UCHAR FPT_RdStack(ULONG port, UCHAR index); +static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data); +static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort); + +static void FPT_SendMsg(ULONG port, UCHAR message); +static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, + UCHAR error_code); + +static void FPT_sinits(PSCCB p_sccb, UCHAR p_card); +static void FPT_RNVRamData(PNVRamInfo pNvRamInfo); + +static UCHAR FPT_siwidn(ULONG port, UCHAR p_card); +static void FPT_stwidn(ULONG port, UCHAR p_card); +static void FPT_siwidr(ULONG port, UCHAR width); + + +static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card); +static void FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card); +static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB, + UCHAR p_card); +static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card); +static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code); +static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card); +static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card); +static void FPT_utilUpdateResidual(PSCCB p_SCCB); +static USHORT FPT_CalcCrc16(UCHAR buffer[]); +static UCHAR FPT_CalcLrc(UCHAR buffer[]); + + +static void FPT_Wait1Second(ULONG p_port); +static void FPT_Wait(ULONG p_port, UCHAR p_delay); +static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode); +static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr); +static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr); +static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr); +static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr); + + + +static void FPT_phaseDataOut(ULONG port, UCHAR p_card); +static void FPT_phaseDataIn(ULONG port, UCHAR p_card); +static void FPT_phaseCommand(ULONG port, UCHAR p_card); +static void FPT_phaseStatus(ULONG port, UCHAR p_card); +static void FPT_phaseMsgOut(ULONG port, UCHAR p_card); +static void FPT_phaseMsgIn(ULONG port, UCHAR p_card); +static void FPT_phaseIllegal(ULONG port, UCHAR p_card); + +static void FPT_phaseDecode(ULONG port, UCHAR p_card); +static void FPT_phaseChkFifo(ULONG port, UCHAR p_card); +static void FPT_phaseBusFree(ULONG p_port, UCHAR p_card); + + + + +static void FPT_XbowInit(ULONG port, UCHAR scamFlg); +static void FPT_BusMasterInit(ULONG p_port); +static void FPT_DiagEEPROM(ULONG p_port); + + + + +void busMstrAbort(ULONG port); +static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard); +static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB); +static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB); +static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB); +static void FPT_hostDataXferRestart(PSCCB currSCCB); + + +static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, + PSCCBcard pCurrCard, USHORT p_int); + +static void FPT_SccbMgrTableInitAll(void); +static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card); +static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target); + + + +static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up); + +static int FPT_scarb(ULONG p_port, UCHAR p_sel_type); +static void FPT_scbusf(ULONG p_port); +static void FPT_scsel(ULONG p_port); +static void FPT_scasid(UCHAR p_card, ULONG p_port); +static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data); +static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]); +static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]); +static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit); +static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit); +static UCHAR FPT_scvalq(UCHAR p_quintet); +static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id); +static void FPT_scwtsel(ULONG p_port); +static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id); +static void FPT_scsavdi(UCHAR p_card, ULONG p_port); +static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]); + + +static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card); +static void FPT_autoLoadDefaultMap(ULONG p_port); + + + +void OS_start_timer(unsigned long ioport, unsigned long timeout); +void OS_stop_timer(unsigned long ioport, unsigned long timeout); +void OS_disable_int(unsigned char intvec); +void OS_enable_int(unsigned char intvec); +void OS_delay(unsigned long count); +int OS_VirtToPhys(u32bits CardHandle, u32bits *physaddr, u32bits *virtaddr); + +static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } }; +static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } }; +static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } }; +static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } }; + + +static UCHAR FPT_mbCards = 0; +static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \ + ' ', 'B', 'T', '-', '9', '3', '0', \ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; + +static USHORT FPT_default_intena = 0; + + +static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 }; + /*--------------------------------------------------------------------- * - * Function: FlashPoint_ProbeHostAdapter + * Function: SccbMgr_sense_adapter * * Description: Setup and/or Search for cards and return info to caller. * *---------------------------------------------------------------------*/ -static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) +static int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo) { - static unsigned char first_time = 1; + static UCHAR first_time = 1; + + UCHAR i,j,id,ScamFlg; + USHORT temp,temp2,temp3,temp4,temp5,temp6; + ULONG ioport; + PNVRamInfo pCurrNvRam; - unsigned char i, j, id, ScamFlg; - unsigned short temp, temp2, temp3, temp4, temp5, temp6; - unsigned long ioport; - struct nvram_info *pCurrNvRam; + ioport = pCardInfo->si_baseaddr; - ioport = pCardInfo->si_baseaddr; - if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0) - return (int)FAILURE; + if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0) + return((int)FAILURE); - if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1)) - return (int)FAILURE; + if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1)) + return((int)FAILURE); - if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0)) - return (int)FAILURE; + if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0)) + return((int)FAILURE); - if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1)) - return (int)FAILURE; + if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1)) + return((int)FAILURE); - if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) { + + if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){ /* For new Harpoon then check for sub_device ID LSB the bits(0-3) must be all ZERO for compatible with current version of SCCBMgr, else skip this Harpoon device. */ - if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f) - return (int)FAILURE; + if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f) + return((int)FAILURE); } - if (first_time) { - FPT_SccbMgrTableInitAll(); - first_time = 0; + if (first_time) + { + FPT_SccbMgrTableInitAll(); + first_time = 0; FPT_mbCards = 0; - } + } - if (FPT_RdStack(ioport, 0) != 0x00) { - if (FPT_ChkIfChipInitialized(ioport) == 0) { + if(FPT_RdStack(ioport, 0) != 0x00) { + if(FPT_ChkIfChipInitialized(ioport) == 0) + { pCurrNvRam = NULL; - WR_HARPOON(ioport + hp_semaphore, 0x00); - FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ + WR_HARPOON(ioport+hp_semaphore, 0x00); + FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ FPT_DiagEEPROM(ioport); - } else { - if (FPT_mbCards < MAX_MB_CARDS) { + } + else + { + if(FPT_mbCards < MAX_MB_CARDS) { pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards]; FPT_mbCards++; pCurrNvRam->niBaseAddr = ioport; FPT_RNVRamData(pCurrNvRam); - } else - return (int)FAILURE; + }else + return((int) FAILURE); } - } else + }else pCurrNvRam = NULL; - WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT); - WR_HARPOON(ioport + hp_sys_ctrl, 0x00); + WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT); + WR_HARPOON(ioport+hp_sys_ctrl, 0x00); - if (pCurrNvRam) + if(pCurrNvRam) pCardInfo->si_id = pCurrNvRam->niAdapId; else - pCardInfo->si_id = - (unsigned - char)(FPT_utilEERead(ioport, - (ADAPTER_SCSI_ID / - 2)) & (unsigned char)0x0FF); - - pCardInfo->si_lun = 0x00; - pCardInfo->si_fw_revision = ORION_FW_REV; - temp2 = 0x0000; - temp3 = 0x0000; - temp4 = 0x0000; - temp5 = 0x0000; - temp6 = 0x0000; - - for (id = 0; id < (16 / 2); id++) { - - if (pCurrNvRam) { - temp = (unsigned short)pCurrNvRam->niSyncTbl[id]; - temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + - (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); - } else - temp = - FPT_utilEERead(ioport, - (unsigned short)((SYNC_RATE_TBL / 2) - + id)); - - for (i = 0; i < 2; temp >>= 8, i++) { - - temp2 >>= 1; - temp3 >>= 1; - temp4 >>= 1; - temp5 >>= 1; - temp6 >>= 1; - switch (temp & 0x3) { - case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */ - temp6 |= 0x8000; /* Fall through */ - case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */ - temp5 |= 0x8000; /* Fall through */ - case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */ - temp2 |= 0x8000; /* Fall through */ - case AUTO_RATE_00: /* Asynchronous */ - break; - } + pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) & + (UCHAR)0x0FF); - if (temp & DISC_ENABLE_BIT) - temp3 |= 0x8000; + pCardInfo->si_lun = 0x00; + pCardInfo->si_fw_revision = ORION_FW_REV; + temp2 = 0x0000; + temp3 = 0x0000; + temp4 = 0x0000; + temp5 = 0x0000; + temp6 = 0x0000; - if (temp & WIDE_NEGO_BIT) - temp4 |= 0x8000; + for (id = 0; id < (16/2); id++) { - } - } + if(pCurrNvRam){ + temp = (USHORT) pCurrNvRam->niSyncTbl[id]; + temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + + (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); + }else + temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id)); + + for (i = 0; i < 2; temp >>=8,i++) { + + temp2 >>= 1; + temp3 >>= 1; + temp4 >>= 1; + temp5 >>= 1; + temp6 >>= 1; + switch (temp & 0x3) + { + case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */ + temp6 |= 0x8000; /* Fall through */ + case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */ + temp5 |= 0x8000; /* Fall through */ + case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */ + temp2 |= 0x8000; /* Fall through */ + case AUTO_RATE_00: /* Asynchronous */ + break; + } + + if (temp & DISC_ENABLE_BIT) + temp3 |= 0x8000; + + if (temp & WIDE_NEGO_BIT) + temp4 |= 0x8000; + + } + } - pCardInfo->si_per_targ_init_sync = temp2; - pCardInfo->si_per_targ_no_disc = temp3; - pCardInfo->si_per_targ_wide_nego = temp4; - pCardInfo->si_per_targ_fast_nego = temp5; - pCardInfo->si_per_targ_ultra_nego = temp6; + pCardInfo->si_per_targ_init_sync = temp2; + pCardInfo->si_per_targ_no_disc = temp3; + pCardInfo->si_per_targ_wide_nego = temp4; + pCardInfo->si_per_targ_fast_nego = temp5; + pCardInfo->si_per_targ_ultra_nego = temp6; - if (pCurrNvRam) + if(pCurrNvRam) i = pCurrNvRam->niSysConf; else - i = (unsigned - char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2))); + i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2))); - if (pCurrNvRam) + if(pCurrNvRam) ScamFlg = pCurrNvRam->niScamConf; else - ScamFlg = - (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2); - - pCardInfo->si_flags = 0x0000; + ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2); - if (i & 0x01) - pCardInfo->si_flags |= SCSI_PARITY_ENA; + pCardInfo->si_flags = 0x0000; - if (!(i & 0x02)) - pCardInfo->si_flags |= SOFT_RESET; + if (i & 0x01) + pCardInfo->si_flags |= SCSI_PARITY_ENA; - if (i & 0x10) - pCardInfo->si_flags |= EXTENDED_TRANSLATION; + if (!(i & 0x02)) + pCardInfo->si_flags |= SOFT_RESET; - if (ScamFlg & SCAM_ENABLED) - pCardInfo->si_flags |= FLAG_SCAM_ENABLED; + if (i & 0x10) + pCardInfo->si_flags |= EXTENDED_TRANSLATION; - if (ScamFlg & SCAM_LEVEL2) - pCardInfo->si_flags |= FLAG_SCAM_LEVEL2; + if (ScamFlg & SCAM_ENABLED) + pCardInfo->si_flags |= FLAG_SCAM_ENABLED; - j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L); - if (i & 0x04) { - j |= SCSI_TERM_ENA_L; - } - WR_HARPOON(ioport + hp_bm_ctrl, j); + if (ScamFlg & SCAM_LEVEL2) + pCardInfo->si_flags |= FLAG_SCAM_LEVEL2; - j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H); - if (i & 0x08) { - j |= SCSI_TERM_ENA_H; - } - WR_HARPOON(ioport + hp_ee_ctrl, j); - - if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD)) - - pCardInfo->si_flags |= SUPPORT_16TAR_32LUN; - - pCardInfo->si_card_family = HARPOON_FAMILY; - pCardInfo->si_bustype = BUSTYPE_PCI; - - if (pCurrNvRam) { - pCardInfo->si_card_model[0] = '9'; - switch (pCurrNvRam->niModel & 0x0f) { - case MODEL_LT: - pCardInfo->si_card_model[1] = '3'; - pCardInfo->si_card_model[2] = '0'; - break; - case MODEL_LW: - pCardInfo->si_card_model[1] = '5'; - pCardInfo->si_card_model[2] = '0'; - break; - case MODEL_DL: - pCardInfo->si_card_model[1] = '3'; - pCardInfo->si_card_model[2] = '2'; - break; - case MODEL_DW: - pCardInfo->si_card_model[1] = '5'; - pCardInfo->si_card_model[2] = '2'; - break; - } - } else { - temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2)); - pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8); - temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2)); + j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L); + if (i & 0x04) { + j |= SCSI_TERM_ENA_L; + } + WR_HARPOON(ioport+hp_bm_ctrl, j ); - pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF); - pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8); - } + j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H); + if (i & 0x08) { + j |= SCSI_TERM_ENA_H; + } + WR_HARPOON(ioport+hp_ee_ctrl, j ); - if (pCardInfo->si_card_model[1] == '3') { - if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= LOW_BYTE_TERM; - } else if (pCardInfo->si_card_model[2] == '0') { - temp = RD_HARPOON(ioport + hp_xfer_pad); - WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4))); - if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= LOW_BYTE_TERM; - WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4))); - if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= HIGH_BYTE_TERM; - WR_HARPOON(ioport + hp_xfer_pad, temp); - } else { - temp = RD_HARPOON(ioport + hp_ee_ctrl); - temp2 = RD_HARPOON(ioport + hp_xfer_pad); - WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS)); - WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4))); - temp3 = 0; - for (i = 0; i < 8; i++) { - temp3 <<= 1; - if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))) - temp3 |= 1; - WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4))); - WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4))); - } - WR_HARPOON(ioport + hp_ee_ctrl, temp); - WR_HARPOON(ioport + hp_xfer_pad, temp2); - if (!(temp3 & BIT(7))) - pCardInfo->si_flags |= LOW_BYTE_TERM; - if (!(temp3 & BIT(6))) - pCardInfo->si_flags |= HIGH_BYTE_TERM; - } + if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD)) - ARAM_ACCESS(ioport); + pCardInfo->si_flags |= SUPPORT_16TAR_32LUN; - for (i = 0; i < 4; i++) { + pCardInfo->si_card_family = HARPOON_FAMILY; + pCardInfo->si_bustype = BUSTYPE_PCI; - pCardInfo->si_XlatInfo[i] = - RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i); - } + if(pCurrNvRam){ + pCardInfo->si_card_model[0] = '9'; + switch(pCurrNvRam->niModel & 0x0f){ + case MODEL_LT: + pCardInfo->si_card_model[1] = '3'; + pCardInfo->si_card_model[2] = '0'; + break; + case MODEL_LW: + pCardInfo->si_card_model[1] = '5'; + pCardInfo->si_card_model[2] = '0'; + break; + case MODEL_DL: + pCardInfo->si_card_model[1] = '3'; + pCardInfo->si_card_model[2] = '2'; + break; + case MODEL_DW: + pCardInfo->si_card_model[1] = '5'; + pCardInfo->si_card_model[2] = '2'; + break; + } + }else{ + temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2)); + pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8); + temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2)); + + pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF); + pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8); + } + + if (pCardInfo->si_card_model[1] == '3') + { + if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)) + pCardInfo->si_flags |= LOW_BYTE_TERM; + } + else if (pCardInfo->si_card_model[2] == '0') + { + temp = RD_HARPOON(ioport+hp_xfer_pad); + WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4))); + if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)) + pCardInfo->si_flags |= LOW_BYTE_TERM; + WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4))); + if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)) + pCardInfo->si_flags |= HIGH_BYTE_TERM; + WR_HARPOON(ioport+hp_xfer_pad, temp); + } + else + { + temp = RD_HARPOON(ioport+hp_ee_ctrl); + temp2 = RD_HARPOON(ioport+hp_xfer_pad); + WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS)); + WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4))); + temp3 = 0; + for (i = 0; i < 8; i++) + { + temp3 <<= 1; + if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))) + temp3 |= 1; + WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4))); + WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4))); + } + WR_HARPOON(ioport+hp_ee_ctrl, temp); + WR_HARPOON(ioport+hp_xfer_pad, temp2); + if (!(temp3 & BIT(7))) + pCardInfo->si_flags |= LOW_BYTE_TERM; + if (!(temp3 & BIT(6))) + pCardInfo->si_flags |= HIGH_BYTE_TERM; + } + + + ARAM_ACCESS(ioport); + + for ( i = 0; i < 4; i++ ) { + + pCardInfo->si_XlatInfo[i] = + RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i); + } /* return with -1 if no sort, else return with logical card number sorted by BIOS (zero-based) */ pCardInfo->si_relative_cardnum = - (unsigned - char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1); + (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1); - SGRAM_ACCESS(ioport); + SGRAM_ACCESS(ioport); - FPT_s_PhaseTbl[0] = FPT_phaseDataOut; - FPT_s_PhaseTbl[1] = FPT_phaseDataIn; - FPT_s_PhaseTbl[2] = FPT_phaseIllegal; - FPT_s_PhaseTbl[3] = FPT_phaseIllegal; - FPT_s_PhaseTbl[4] = FPT_phaseCommand; - FPT_s_PhaseTbl[5] = FPT_phaseStatus; - FPT_s_PhaseTbl[6] = FPT_phaseMsgOut; - FPT_s_PhaseTbl[7] = FPT_phaseMsgIn; + FPT_s_PhaseTbl[0] = FPT_phaseDataOut; + FPT_s_PhaseTbl[1] = FPT_phaseDataIn; + FPT_s_PhaseTbl[2] = FPT_phaseIllegal; + FPT_s_PhaseTbl[3] = FPT_phaseIllegal; + FPT_s_PhaseTbl[4] = FPT_phaseCommand; + FPT_s_PhaseTbl[5] = FPT_phaseStatus; + FPT_s_PhaseTbl[6] = FPT_phaseMsgOut; + FPT_s_PhaseTbl[7] = FPT_phaseMsgIn; - pCardInfo->si_present = 0x01; + pCardInfo->si_present = 0x01; - return 0; + return(0); } + /*--------------------------------------------------------------------- * - * Function: FlashPoint_HardwareResetHostAdapter + * Function: SccbMgr_config_adapter * * Description: Setup adapter for normal operation (hard reset). * *---------------------------------------------------------------------*/ -static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info - *pCardInfo) +static ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo) { - struct sccb_card *CurrCard = NULL; - struct nvram_info *pCurrNvRam; - unsigned char i, j, thisCard, ScamFlg; - unsigned short temp, sync_bit_map, id; - unsigned long ioport; + PSCCBcard CurrCard = NULL; + PNVRamInfo pCurrNvRam; + UCHAR i,j,thisCard, ScamFlg; + USHORT temp,sync_bit_map,id; + ULONG ioport; - ioport = pCardInfo->si_baseaddr; + ioport = pCardInfo->si_baseaddr; - for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) { + for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) { - if (thisCard == MAX_CARDS) { + if (thisCard == MAX_CARDS) { - return FAILURE; - } + return(FAILURE); + } - if (FPT_BL_Card[thisCard].ioPort == ioport) { + if (FPT_BL_Card[thisCard].ioPort == ioport) { - CurrCard = &FPT_BL_Card[thisCard]; - FPT_SccbMgrTableInitCard(CurrCard, thisCard); - break; - } + CurrCard = &FPT_BL_Card[thisCard]; + FPT_SccbMgrTableInitCard(CurrCard,thisCard); + break; + } - else if (FPT_BL_Card[thisCard].ioPort == 0x00) { + else if (FPT_BL_Card[thisCard].ioPort == 0x00) { - FPT_BL_Card[thisCard].ioPort = ioport; - CurrCard = &FPT_BL_Card[thisCard]; + FPT_BL_Card[thisCard].ioPort = ioport; + CurrCard = &FPT_BL_Card[thisCard]; - if (FPT_mbCards) - for (i = 0; i < FPT_mbCards; i++) { - if (CurrCard->ioPort == - FPT_nvRamInfo[i].niBaseAddr) - CurrCard->pNvRamInfo = - &FPT_nvRamInfo[i]; + if(FPT_mbCards) + for(i = 0; i < FPT_mbCards; i++){ + if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr) + CurrCard->pNvRamInfo = &FPT_nvRamInfo[i]; } - FPT_SccbMgrTableInitCard(CurrCard, thisCard); - CurrCard->cardIndex = thisCard; - CurrCard->cardInfo = pCardInfo; + FPT_SccbMgrTableInitCard(CurrCard,thisCard); + CurrCard->cardIndex = thisCard; + CurrCard->cardInfo = pCardInfo; - break; - } - } + break; + } + } pCurrNvRam = CurrCard->pNvRamInfo; - if (pCurrNvRam) { + if(pCurrNvRam){ ScamFlg = pCurrNvRam->niScamConf; - } else { - ScamFlg = - (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2); + } + else{ + ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2); } - FPT_BusMasterInit(ioport); - FPT_XbowInit(ioport, ScamFlg); - FPT_autoLoadDefaultMap(ioport); + FPT_BusMasterInit(ioport); + FPT_XbowInit(ioport, ScamFlg); - for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) { - } + FPT_autoLoadDefaultMap(ioport); - WR_HARPOON(ioport + hp_selfid_0, id); - WR_HARPOON(ioport + hp_selfid_1, 0x00); - WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id); - CurrCard->ourId = pCardInfo->si_id; - i = (unsigned char)pCardInfo->si_flags; - if (i & SCSI_PARITY_ENA) - WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P)); + for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){} - j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L); - if (i & LOW_BYTE_TERM) - j |= SCSI_TERM_ENA_L; - WR_HARPOON(ioport + hp_bm_ctrl, j); + WR_HARPOON(ioport+hp_selfid_0, id); + WR_HARPOON(ioport+hp_selfid_1, 0x00); + WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id); + CurrCard->ourId = pCardInfo->si_id; - j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H); - if (i & HIGH_BYTE_TERM) - j |= SCSI_TERM_ENA_H; - WR_HARPOON(ioport + hp_ee_ctrl, j); + i = (UCHAR) pCardInfo->si_flags; + if (i & SCSI_PARITY_ENA) + WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P)); - if (!(pCardInfo->si_flags & SOFT_RESET)) { + j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L); + if (i & LOW_BYTE_TERM) + j |= SCSI_TERM_ENA_L; + WR_HARPOON(ioport+hp_bm_ctrl, j); - FPT_sresb(ioport, thisCard); + j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H); + if (i & HIGH_BYTE_TERM) + j |= SCSI_TERM_ENA_H; + WR_HARPOON(ioport+hp_ee_ctrl, j ); - FPT_scini(thisCard, pCardInfo->si_id, 0); - } - if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS) - CurrCard->globalFlags |= F_NO_FILTER; + if (!(pCardInfo->si_flags & SOFT_RESET)) { - if (pCurrNvRam) { - if (pCurrNvRam->niSysConf & 0x10) - CurrCard->globalFlags |= F_GREEN_PC; - } else { - if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA) + FPT_sresb(ioport,thisCard); + + FPT_scini(thisCard, pCardInfo->si_id, 0); + } + + + + if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS) + CurrCard->globalFlags |= F_NO_FILTER; + + if(pCurrNvRam){ + if(pCurrNvRam->niSysConf & 0x10) CurrCard->globalFlags |= F_GREEN_PC; } + else{ + if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA) + CurrCard->globalFlags |= F_GREEN_PC; + } /* Set global flag to indicate Re-Negotiation to be done on all - ckeck condition */ - if (pCurrNvRam) { - if (pCurrNvRam->niScsiConf & 0x04) - CurrCard->globalFlags |= F_DO_RENEGO; - } else { - if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA) + ckeck condition */ + if(pCurrNvRam){ + if(pCurrNvRam->niScsiConf & 0x04) CurrCard->globalFlags |= F_DO_RENEGO; } + else{ + if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA) + CurrCard->globalFlags |= F_DO_RENEGO; + } - if (pCurrNvRam) { - if (pCurrNvRam->niScsiConf & 0x08) - CurrCard->globalFlags |= F_CONLUN_IO; - } else { - if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA) + if(pCurrNvRam){ + if(pCurrNvRam->niScsiConf & 0x08) CurrCard->globalFlags |= F_CONLUN_IO; } + else{ + if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA) + CurrCard->globalFlags |= F_CONLUN_IO; + } - temp = pCardInfo->si_per_targ_no_disc; - for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) { + temp = pCardInfo->si_per_targ_no_disc; - if (temp & id) - FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC; - } + for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) { - sync_bit_map = 0x0001; + if (temp & id) + FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC; + } + + sync_bit_map = 0x0001; - for (id = 0; id < (MAX_SCSI_TAR / 2); id++) { + for (id = 0; id < (MAX_SCSI_TAR/2); id++) { - if (pCurrNvRam) { - temp = (unsigned short)pCurrNvRam->niSyncTbl[id]; + if(pCurrNvRam){ + temp = (USHORT) pCurrNvRam->niSyncTbl[id]; temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + - (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); - } else - temp = - FPT_utilEERead(ioport, - (unsigned short)((SYNC_RATE_TBL / 2) - + id)); + (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); + }else + temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id)); - for (i = 0; i < 2; temp >>= 8, i++) { + for (i = 0; i < 2; temp >>=8,i++) { - if (pCardInfo->si_per_targ_init_sync & sync_bit_map) { + if (pCardInfo->si_per_targ_init_sync & sync_bit_map) { - FPT_sccbMgrTbl[thisCard][id * 2 + - i].TarEEValue = - (unsigned char)temp; - } + FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp; + } - else { - FPT_sccbMgrTbl[thisCard][id * 2 + - i].TarStatus |= - SYNC_SUPPORTED; - FPT_sccbMgrTbl[thisCard][id * 2 + - i].TarEEValue = - (unsigned char)(temp & ~EE_SYNC_MASK); - } + else { + FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED; + FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = + (UCHAR)(temp & ~EE_SYNC_MASK); + } /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) || (id*2+i >= 8)){ */ - if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) { + if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){ - FPT_sccbMgrTbl[thisCard][id * 2 + - i].TarEEValue |= - EE_WIDE_SCSI; + FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI; - } + } - else { /* NARROW SCSI */ - FPT_sccbMgrTbl[thisCard][id * 2 + - i].TarStatus |= - WIDE_NEGOCIATED; - } + else { /* NARROW SCSI */ + FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED; + } - sync_bit_map <<= 1; - } - } + sync_bit_map <<= 1; + + + + } + } - WR_HARPOON((ioport + hp_semaphore), - (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) | - SCCB_MGR_PRESENT)); + WR_HARPOON((ioport+hp_semaphore), + (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT)); - return (unsigned long)CurrCard; + return((ULONG)CurrCard); } -static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard) +static void SccbMgr_unload_card(ULONG pCurrCard) { - unsigned char i; - unsigned long portBase; - unsigned long regOffset; - unsigned long scamData; - unsigned long *pScamTbl; - struct nvram_info *pCurrNvRam; + UCHAR i; + ULONG portBase; + ULONG regOffset; + ULONG scamData; + ULONG *pScamTbl; + PNVRamInfo pCurrNvRam; - pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo; + pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo; - if (pCurrNvRam) { + if(pCurrNvRam){ FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel); FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf); FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf); FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf); FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId); - for (i = 0; i < MAX_SCSI_TAR / 2; i++) - FPT_WrStack(pCurrNvRam->niBaseAddr, - (unsigned char)(i + 5), - pCurrNvRam->niSyncTbl[i]); + for(i = 0; i < MAX_SCSI_TAR / 2; i++) + FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]); portBase = pCurrNvRam->niBaseAddr; - for (i = 0; i < MAX_SCSI_TAR; i++) { - regOffset = hp_aramBase + 64 + i * 4; - pScamTbl = (unsigned long *)&pCurrNvRam->niScamTbl[i]; + for(i = 0; i < MAX_SCSI_TAR; i++){ + regOffset = hp_aramBase + 64 + i*4; + pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i]; scamData = *pScamTbl; WR_HARP32(portBase, regOffset, scamData); } - } else { - FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0); + }else{ + FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0); } } -static void FPT_RNVRamData(struct nvram_info *pNvRamInfo) + +static void FPT_RNVRamData(PNVRamInfo pNvRamInfo) { - unsigned char i; - unsigned long portBase; - unsigned long regOffset; - unsigned long scamData; - unsigned long *pScamTbl; - - pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0); - pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1); + UCHAR i; + ULONG portBase; + ULONG regOffset; + ULONG scamData; + ULONG *pScamTbl; + + pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0); + pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1); pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2); pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3); - pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4); + pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4); - for (i = 0; i < MAX_SCSI_TAR / 2; i++) - pNvRamInfo->niSyncTbl[i] = - FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5)); + for(i = 0; i < MAX_SCSI_TAR / 2; i++) + pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5)); portBase = pNvRamInfo->niBaseAddr; - for (i = 0; i < MAX_SCSI_TAR; i++) { - regOffset = hp_aramBase + 64 + i * 4; + for(i = 0; i < MAX_SCSI_TAR; i++){ + regOffset = hp_aramBase + 64 + i*4; RD_HARP32(portBase, regOffset, scamData); - pScamTbl = (unsigned long *)&pNvRamInfo->niScamTbl[i]; + pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i]; *pScamTbl = scamData; } } -static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index) +static UCHAR FPT_RdStack(ULONG portBase, UCHAR index) { WR_HARPOON(portBase + hp_stack_addr, index); - return RD_HARPOON(portBase + hp_stack_data); + return(RD_HARPOON(portBase + hp_stack_data)); } -static void FPT_WrStack(unsigned long portBase, unsigned char index, - unsigned char data) +static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data) { WR_HARPOON(portBase + hp_stack_addr, index); WR_HARPOON(portBase + hp_stack_data, data); } -static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort) + +static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort) { - if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4)) - return 0; - if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT) - != CLKCTRL_DEFAULT) - return 0; - if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) || - (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms)) - return 1; - return 0; + if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4)) + return(0); + if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT) + != CLKCTRL_DEFAULT) + return(0); + if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) || + (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms)) + return(1); + return(0); } - /*--------------------------------------------------------------------- * - * Function: FlashPoint_StartCCB + * Function: SccbMgr_start_sccb * * Description: Start a command pointed to by p_Sccb. When the * command is completed it will be returned via the * callback function. * *---------------------------------------------------------------------*/ -static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb) +static void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb) { - unsigned long ioport; - unsigned char thisCard, lun; - struct sccb *pSaveSccb; - CALL_BK_FN callback; + ULONG ioport; + UCHAR thisCard, lun; + PSCCB pSaveSccb; + CALL_BK_FN callback; - thisCard = ((struct sccb_card *)pCurrCard)->cardIndex; - ioport = ((struct sccb_card *)pCurrCard)->ioPort; + thisCard = ((PSCCBcard) pCurrCard)->cardIndex; + ioport = ((PSCCBcard) pCurrCard)->ioPort; - if ((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN)) { + if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN)) + { p_Sccb->HostStatus = SCCB_COMPLETE; p_Sccb->SccbStatus = SCCB_ERROR; - callback = (CALL_BK_FN) p_Sccb->SccbCallback; + callback = (CALL_BK_FN)p_Sccb->SccbCallback; if (callback) callback(p_Sccb); return; } - FPT_sinits(p_Sccb, thisCard); + FPT_sinits(p_Sccb,thisCard); - if (!((struct sccb_card *)pCurrCard)->cmdCounter) { - WR_HARPOON(ioport + hp_semaphore, - (RD_HARPOON(ioport + hp_semaphore) - | SCCB_MGR_ACTIVE)); - if (((struct sccb_card *)pCurrCard)->globalFlags & F_GREEN_PC) { - WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT); - WR_HARPOON(ioport + hp_sys_ctrl, 0x00); - } - } + if (!((PSCCBcard) pCurrCard)->cmdCounter) + { + WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore) + | SCCB_MGR_ACTIVE)); + + if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC) + { + WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT); + WR_HARPOON(ioport+hp_sys_ctrl, 0x00); + } + } - ((struct sccb_card *)pCurrCard)->cmdCounter++; - - if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) { - - WR_HARPOON(ioport + hp_semaphore, - (RD_HARPOON(ioport + hp_semaphore) - | TICKLE_ME)); - if (p_Sccb->OperationCode == RESET_COMMAND) { - pSaveSccb = - ((struct sccb_card *)pCurrCard)->currentSCCB; - ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb; - FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); - ((struct sccb_card *)pCurrCard)->currentSCCB = - pSaveSccb; - } else { - FPT_queueAddSccb(p_Sccb, thisCard); - } - } + ((PSCCBcard)pCurrCard)->cmdCounter++; - else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) { - - if (p_Sccb->OperationCode == RESET_COMMAND) { - pSaveSccb = - ((struct sccb_card *)pCurrCard)->currentSCCB; - ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb; - FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); - ((struct sccb_card *)pCurrCard)->currentSCCB = - pSaveSccb; - } else { - FPT_queueAddSccb(p_Sccb, thisCard); - } - } + if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) { + + WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore) + | TICKLE_ME)); + if(p_Sccb->OperationCode == RESET_COMMAND) + { + pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB; + ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; + FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); + ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb; + } + else + { + FPT_queueAddSccb(p_Sccb,thisCard); + } + } + + else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) { + + if(p_Sccb->OperationCode == RESET_COMMAND) + { + pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB; + ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; + FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); + ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb; + } + else + { + FPT_queueAddSccb(p_Sccb,thisCard); + } + } - else { + else { - MDISABLE_INT(ioport); + MDISABLE_INT(ioport); - if ((((struct sccb_card *)pCurrCard)->globalFlags & F_CONLUN_IO) - && - ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID]. - TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) lun = p_Sccb->Lun; else lun = 0; - if ((((struct sccb_card *)pCurrCard)->currentSCCB == NULL) && - (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) - && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun] - == 0)) { + if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) && + (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) && + (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun] + == 0)) { - ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb; - FPT_ssel(p_Sccb->SccbIOPort, thisCard); - } + ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; + FPT_ssel(p_Sccb->SccbIOPort,thisCard); + } - else { - - if (p_Sccb->OperationCode == RESET_COMMAND) { - pSaveSccb = - ((struct sccb_card *)pCurrCard)-> - currentSCCB; - ((struct sccb_card *)pCurrCard)->currentSCCB = - p_Sccb; - FPT_queueSelectFail(&FPT_BL_Card[thisCard], - thisCard); - ((struct sccb_card *)pCurrCard)->currentSCCB = - pSaveSccb; - } else { - FPT_queueAddSccb(p_Sccb, thisCard); - } - } + else { - MENABLE_INT(ioport); - } + if(p_Sccb->OperationCode == RESET_COMMAND) + { + pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB; + ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; + FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); + ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb; + } + else + { + FPT_queueAddSccb(p_Sccb,thisCard); + } + } + + + MENABLE_INT(ioport); + } } + /*--------------------------------------------------------------------- * - * Function: FlashPoint_AbortCCB + * Function: SccbMgr_abort_sccb * * Description: Abort the command pointed to by p_Sccb. When the * command is completed it will be returned via the * callback function. * *---------------------------------------------------------------------*/ -static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb *p_Sccb) +static int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb) { - unsigned long ioport; + ULONG ioport; - unsigned char thisCard; + UCHAR thisCard; CALL_BK_FN callback; - unsigned char TID; - struct sccb *pSaveSCCB; - struct sccb_mgr_tar_info *currTar_Info; + UCHAR TID; + PSCCB pSaveSCCB; + PSCCBMgr_tar_info currTar_Info; + - ioport = ((struct sccb_card *)pCurrCard)->ioPort; + ioport = ((PSCCBcard) pCurrCard)->ioPort; - thisCard = ((struct sccb_card *)pCurrCard)->cardIndex; + thisCard = ((PSCCBcard)pCurrCard)->cardIndex; - if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) { + if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) + { - if (FPT_queueFindSccb(p_Sccb, thisCard)) { + if (FPT_queueFindSccb(p_Sccb,thisCard)) + { - ((struct sccb_card *)pCurrCard)->cmdCounter--; + ((PSCCBcard)pCurrCard)->cmdCounter--; - if (!((struct sccb_card *)pCurrCard)->cmdCounter) - WR_HARPOON(ioport + hp_semaphore, - (RD_HARPOON(ioport + hp_semaphore) - & (unsigned - char)(~(SCCB_MGR_ACTIVE | - TICKLE_ME)))); + if (!((PSCCBcard)pCurrCard)->cmdCounter) + WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore) + & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) )); p_Sccb->SccbStatus = SCCB_ABORT; callback = p_Sccb->SccbCallback; callback(p_Sccb); - return 0; + return(0); } - else { - if (((struct sccb_card *)pCurrCard)->currentSCCB == - p_Sccb) { + else + { + if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb) + { p_Sccb->SccbStatus = SCCB_ABORT; - return 0; + return(0); } - else { + else + { TID = p_Sccb->TargID; - if (p_Sccb->Sccb_tag) { + + if(p_Sccb->Sccb_tag) + { MDISABLE_INT(ioport); - if (((struct sccb_card *)pCurrCard)-> - discQ_Tbl[p_Sccb->Sccb_tag] == - p_Sccb) { + if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb) + { p_Sccb->SccbStatus = SCCB_ABORT; - p_Sccb->Sccb_scsistat = - ABORT_ST; - p_Sccb->Sccb_scsimsg = - SMABORT_TAG; - - if (((struct sccb_card *) - pCurrCard)->currentSCCB == - NULL) { - ((struct sccb_card *) - pCurrCard)-> - currentSCCB = p_Sccb; - FPT_ssel(ioport, - thisCard); - } else { - pSaveSCCB = - ((struct sccb_card - *)pCurrCard)-> - currentSCCB; - ((struct sccb_card *) - pCurrCard)-> - currentSCCB = p_Sccb; - FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard); - ((struct sccb_card *) - pCurrCard)-> - currentSCCB = pSaveSCCB; + p_Sccb->Sccb_scsistat = ABORT_ST; + p_Sccb->Sccb_scsimsg = SMABORT_TAG; + + if(((PSCCBcard) pCurrCard)->currentSCCB == NULL) + { + ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; + FPT_ssel(ioport, thisCard); + } + else + { + pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB; + ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; + FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard); + ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB; } } MENABLE_INT(ioport); - return 0; - } else { - currTar_Info = - &FPT_sccbMgrTbl[thisCard][p_Sccb-> - TargID]; - - if (FPT_BL_Card[thisCard]. - discQ_Tbl[currTar_Info-> - LunDiscQ_Idx[p_Sccb->Lun]] - == p_Sccb) { + return(0); + } + else + { + currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID]; + + if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]] + == p_Sccb) + { p_Sccb->SccbStatus = SCCB_ABORT; - return 0; + return(0); } } } } } - return -1; + return(-1); } + /*--------------------------------------------------------------------- * - * Function: FlashPoint_InterruptPending + * Function: SccbMgr_my_int * * Description: Do a quick check to determine if there is a pending * interrupt for this card and disable the IRQ Pin if so. * *---------------------------------------------------------------------*/ -static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard) +static UCHAR SccbMgr_my_int(ULONG pCurrCard) { - unsigned long ioport; + ULONG ioport; - ioport = ((struct sccb_card *)pCurrCard)->ioPort; + ioport = ((PSCCBcard)pCurrCard)->ioPort; - if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) { - return 1; - } + if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED) + { + return(1); + } - else + else - return 0; + return(0); } + + /*--------------------------------------------------------------------- * - * Function: FlashPoint_HandleInterrupt + * Function: SccbMgr_isr * * Description: This is our entry point when an interrupt is generated * by the card and the upper level driver passes it on to * us. * *---------------------------------------------------------------------*/ -static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) +static int SccbMgr_isr(ULONG pCurrCard) { - struct sccb *currSCCB; - unsigned char thisCard, result, bm_status, bm_int_st; - unsigned short hp_int; - unsigned char i, target; - unsigned long ioport; + PSCCB currSCCB; + UCHAR thisCard,result,bm_status, bm_int_st; + USHORT hp_int; + UCHAR i, target; + ULONG ioport; - thisCard = ((struct sccb_card *)pCurrCard)->cardIndex; - ioport = ((struct sccb_card *)pCurrCard)->ioPort; + thisCard = ((PSCCBcard)pCurrCard)->cardIndex; + ioport = ((PSCCBcard)pCurrCard)->ioPort; - MDISABLE_INT(ioport); + MDISABLE_INT(ioport); - if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON) - bm_status = - RD_HARPOON(ioport + - hp_ext_status) & (unsigned char)BAD_EXT_STATUS; - else - bm_status = 0; + if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON) + bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS; + else + bm_status = 0; - WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); + WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); - while ((hp_int = - RDW_HARPOON((ioport + - hp_intstat)) & FPT_default_intena) | bm_status) { + while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) | + bm_status) + { - currSCCB = ((struct sccb_card *)pCurrCard)->currentSCCB; + currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB; - if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) { - result = - FPT_SccbMgr_bad_isr(ioport, thisCard, - ((struct sccb_card *)pCurrCard), - hp_int); - WRW_HARPOON((ioport + hp_intstat), - (FIFO | TIMEOUT | RESET | SCAM_SEL)); - bm_status = 0; + if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) { + result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int); + WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL)); + bm_status = 0; - if (result) { + if (result) { - MENABLE_INT(ioport); - return result; - } - } + MENABLE_INT(ioport); + return(result); + } + } - else if (hp_int & ICMD_COMP) { - - if (!(hp_int & BUS_FREE)) { - /* Wait for the BusFree before starting a new command. We - must also check for being reselected since the BusFree - may not show up if another device reselects us in 1.5us or - less. SRR Wednesday, 3/8/1995. - */ - while (! - (RDW_HARPOON((ioport + hp_intstat)) & - (BUS_FREE | RSEL))) ; - } - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_HOST_XFER_ACT) + else if (hp_int & ICMD_COMP) { + + if ( !(hp_int & BUS_FREE) ) { + /* Wait for the BusFree before starting a new command. We + must also check for being reselected since the BusFree + may not show up if another device reselects us in 1.5us or + less. SRR Wednesday, 3/8/1995. + */ + while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ; + } + + if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) - FPT_phaseChkFifo(ioport, thisCard); + FPT_phaseChkFifo(ioport, thisCard); /* WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0)); */ - WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1); + WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1); - FPT_autoCmdCmplt(ioport, thisCard); + FPT_autoCmdCmplt(ioport,thisCard); - } + } - else if (hp_int & ITAR_DISC) { - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_HOST_XFER_ACT) { + else if (hp_int & ITAR_DISC) + { - FPT_phaseChkFifo(ioport, thisCard); + if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) { - } + FPT_phaseChkFifo(ioport, thisCard); - if (RD_HARPOON(ioport + hp_gp_reg_1) == SMSAVE_DATA_PTR) { + } - WR_HARPOON(ioport + hp_gp_reg_1, 0x00); - currSCCB->Sccb_XferState |= F_NO_DATA_YET; + if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) { - currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC; - } + WR_HARPOON(ioport+hp_gp_reg_1, 0x00); + currSCCB->Sccb_XferState |= F_NO_DATA_YET; - currSCCB->Sccb_scsistat = DISCONNECT_ST; - FPT_queueDisconnect(currSCCB, thisCard); - - /* Wait for the BusFree before starting a new command. We - must also check for being reselected since the BusFree - may not show up if another device reselects us in 1.5us or - less. SRR Wednesday, 3/8/1995. - */ - while (! - (RDW_HARPOON((ioport + hp_intstat)) & - (BUS_FREE | RSEL)) - && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE) - && RD_HARPOON((ioport + hp_scsisig)) == - (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | - SCSI_IOBIT))) ; - - /* - The additional loop exit condition above detects a timing problem - with the revision D/E harpoon chips. The caller should reset the - host adapter to recover when 0xFE is returned. - */ - if (! - (RDW_HARPOON((ioport + hp_intstat)) & - (BUS_FREE | RSEL))) { - MENABLE_INT(ioport); - return 0xFE; - } + currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC; + } - WRW_HARPOON((ioport + hp_intstat), - (BUS_FREE | ITAR_DISC)); + currSCCB->Sccb_scsistat = DISCONNECT_ST; + FPT_queueDisconnect(currSCCB,thisCard); - ((struct sccb_card *)pCurrCard)->globalFlags |= - F_NEW_SCCB_CMD; + /* Wait for the BusFree before starting a new command. We + must also check for being reselected since the BusFree + may not show up if another device reselects us in 1.5us or + less. SRR Wednesday, 3/8/1995. + */ + while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) && + !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) && + RD_HARPOON((ioport+hp_scsisig)) == + (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ; - } + /* + The additional loop exit condition above detects a timing problem + with the revision D/E harpoon chips. The caller should reset the + host adapter to recover when 0xFE is returned. + */ + if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) + { + MENABLE_INT(ioport); + return 0xFE; + } - else if (hp_int & RSEL) { + WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC)); - WRW_HARPOON((ioport + hp_intstat), - (PROG_HLT | RSEL | PHASE | BUS_FREE)); - if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) { - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_HOST_XFER_ACT) { - FPT_phaseChkFifo(ioport, thisCard); - } + ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD; - if (RD_HARPOON(ioport + hp_gp_reg_1) == - SMSAVE_DATA_PTR) { - WR_HARPOON(ioport + hp_gp_reg_1, 0x00); - currSCCB->Sccb_XferState |= - F_NO_DATA_YET; - currSCCB->Sccb_savedATC = - currSCCB->Sccb_ATC; - } + } - WRW_HARPOON((ioport + hp_intstat), - (BUS_FREE | ITAR_DISC)); - currSCCB->Sccb_scsistat = DISCONNECT_ST; - FPT_queueDisconnect(currSCCB, thisCard); - } - FPT_sres(ioport, thisCard, - ((struct sccb_card *)pCurrCard)); - FPT_phaseDecode(ioport, thisCard); + else if (hp_int & RSEL) { - } + WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE)); - else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) { + if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC) + { + if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) + { + FPT_phaseChkFifo(ioport, thisCard); + } - WRW_HARPOON((ioport + hp_intstat), - (IDO_STRT | XFER_CNT_0)); - FPT_phaseDecode(ioport, thisCard); + if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) + { + WR_HARPOON(ioport+hp_gp_reg_1, 0x00); + currSCCB->Sccb_XferState |= F_NO_DATA_YET; + currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC; + } - } + WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC)); + currSCCB->Sccb_scsistat = DISCONNECT_ST; + FPT_queueDisconnect(currSCCB,thisCard); + } - else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) { - WRW_HARPOON((ioport + hp_intstat), - (PHASE | IUNKWN | PROG_HLT)); - if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char) - 0x3f) < (unsigned char)SELCHK) { - FPT_phaseDecode(ioport, thisCard); - } else { - /* Harpoon problem some SCSI target device respond to selection - with short BUSY pulse (<400ns) this will make the Harpoon is not able - to latch the correct Target ID into reg. x53. - The work around require to correct this reg. But when write to this - reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we - need to read this reg first then restore it later. After update to 0x53 */ - - i = (unsigned - char)(RD_HARPOON(ioport + hp_fifowrite)); - target = - (unsigned - char)(RD_HARPOON(ioport + hp_gp_reg_3)); - WR_HARPOON(ioport + hp_xfer_pad, - (unsigned char)ID_UNLOCK); - WR_HARPOON(ioport + hp_select_id, - (unsigned char)(target | target << - 4)); - WR_HARPOON(ioport + hp_xfer_pad, - (unsigned char)0x00); - WR_HARPOON(ioport + hp_fifowrite, i); - WR_HARPOON(ioport + hp_autostart_3, - (AUTO_IMMED + TAG_STRT)); - } - } + FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard)); + FPT_phaseDecode(ioport,thisCard); - else if (hp_int & XFER_CNT_0) { + } - WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0); - FPT_schkdd(ioport, thisCard); + else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) + { - } + WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0)); + FPT_phaseDecode(ioport,thisCard); - else if (hp_int & BUS_FREE) { + } - WRW_HARPOON((ioport + hp_intstat), BUS_FREE); - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_HOST_XFER_ACT) { + else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) ) + { + WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT)); + if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK) + { + FPT_phaseDecode(ioport,thisCard); + } + else + { + /* Harpoon problem some SCSI target device respond to selection + with short BUSY pulse (<400ns) this will make the Harpoon is not able + to latch the correct Target ID into reg. x53. + The work around require to correct this reg. But when write to this + reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we + need to read this reg first then restore it later. After update to 0x53 */ - FPT_hostDataXferAbort(ioport, thisCard, - currSCCB); - } + i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite)); + target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3)); + WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK); + WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4)); + WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00); + WR_HARPOON(ioport+hp_fifowrite, i); + WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT)); + } + } - FPT_phaseBusFree(ioport, thisCard); - } + else if (hp_int & XFER_CNT_0) { - else if (hp_int & ITICKLE) { + WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0); - WRW_HARPOON((ioport + hp_intstat), ITICKLE); - ((struct sccb_card *)pCurrCard)->globalFlags |= - F_NEW_SCCB_CMD; - } + FPT_schkdd(ioport,thisCard); - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_NEW_SCCB_CMD) { + } - ((struct sccb_card *)pCurrCard)->globalFlags &= - ~F_NEW_SCCB_CMD; - if (((struct sccb_card *)pCurrCard)->currentSCCB == - NULL) { + else if (hp_int & BUS_FREE) { - FPT_queueSearchSelect(((struct sccb_card *) - pCurrCard), thisCard); - } + WRW_HARPOON((ioport+hp_intstat), BUS_FREE); + + if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) { + + FPT_hostDataXferAbort(ioport,thisCard,currSCCB); + } - if (((struct sccb_card *)pCurrCard)->currentSCCB != - NULL) { - ((struct sccb_card *)pCurrCard)->globalFlags &= - ~F_NEW_SCCB_CMD; - FPT_ssel(ioport, thisCard); + FPT_phaseBusFree(ioport,thisCard); } - break; - } + else if (hp_int & ITICKLE) { + + WRW_HARPOON((ioport+hp_intstat), ITICKLE); + ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD; + } + + + + if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) { + + + ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD; + + + if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) { + + FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard); + } + + if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) { + ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD; + FPT_ssel(ioport,thisCard); + } + + break; - } /*end while */ + } - MENABLE_INT(ioport); + } /*end while */ - return 0; + MENABLE_INT(ioport); + + return(0); } /*--------------------------------------------------------------------- @@ -2010,149 +2529,150 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) * processing time. * *---------------------------------------------------------------------*/ -static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, - unsigned char p_card, - struct sccb_card *pCurrCard, - unsigned short p_int) +static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, + PSCCBcard pCurrCard, USHORT p_int) { - unsigned char temp, ScamFlg; - struct sccb_mgr_tar_info *currTar_Info; - struct nvram_info *pCurrNvRam; + UCHAR temp, ScamFlg; + PSCCBMgr_tar_info currTar_Info; + PNVRamInfo pCurrNvRam; - if (RD_HARPOON(p_port + hp_ext_status) & - (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) { - if (pCurrCard->globalFlags & F_HOST_XFER_ACT) { + if (RD_HARPOON(p_port+hp_ext_status) & + (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) ) + { - FPT_hostDataXferAbort(p_port, p_card, - pCurrCard->currentSCCB); - } + if (pCurrCard->globalFlags & F_HOST_XFER_ACT) + { - if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT) - { - WR_HARPOON(p_port + hp_pci_stat_cfg, - (RD_HARPOON(p_port + hp_pci_stat_cfg) & - ~REC_MASTER_ABORT)); + FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB); + } - WR_HARPOON(p_port + hp_host_blk_cnt, 0x00); + if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT) - } + { + WR_HARPOON(p_port+hp_pci_stat_cfg, + (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT)); - if (pCurrCard->currentSCCB != NULL) { + WR_HARPOON(p_port+hp_host_blk_cnt, 0x00); - if (!pCurrCard->currentSCCB->HostStatus) - pCurrCard->currentSCCB->HostStatus = - SCCB_BM_ERR; + } - FPT_sxfrp(p_port, p_card); + if (pCurrCard->currentSCCB != NULL) + { - temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) & - (EXT_ARB_ACK | SCSI_TERM_ENA_H)); - WR_HARPOON(p_port + hp_ee_ctrl, - ((unsigned char)temp | SEE_MS | SEE_CS)); - WR_HARPOON(p_port + hp_ee_ctrl, temp); + if (!pCurrCard->currentSCCB->HostStatus) + pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR; - if (! - (RDW_HARPOON((p_port + hp_intstat)) & - (BUS_FREE | RESET))) { - FPT_phaseDecode(p_port, p_card); - } - } - } + FPT_sxfrp(p_port,p_card); - else if (p_int & RESET) { + temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & + (EXT_ARB_ACK | SCSI_TERM_ENA_H)); + WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS)); + WR_HARPOON(p_port+hp_ee_ctrl, temp); - WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT); - WR_HARPOON(p_port + hp_sys_ctrl, 0x00); - if (pCurrCard->currentSCCB != NULL) { + if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET))) + { + FPT_phaseDecode(p_port,p_card); + } + } + } - if (pCurrCard->globalFlags & F_HOST_XFER_ACT) - FPT_hostDataXferAbort(p_port, p_card, - pCurrCard->currentSCCB); - } + else if (p_int & RESET) + { - DISABLE_AUTO(p_port); + WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT); + WR_HARPOON(p_port+hp_sys_ctrl, 0x00); + if (pCurrCard->currentSCCB != NULL) { - FPT_sresb(p_port, p_card); + if (pCurrCard->globalFlags & F_HOST_XFER_ACT) - while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) { - } + FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB); + } - pCurrNvRam = pCurrCard->pNvRamInfo; - if (pCurrNvRam) { - ScamFlg = pCurrNvRam->niScamConf; - } else { - ScamFlg = - (unsigned char)FPT_utilEERead(p_port, - SCAM_CONFIG / 2); - } - FPT_XbowInit(p_port, ScamFlg); + DISABLE_AUTO(p_port); - FPT_scini(p_card, pCurrCard->ourId, 0); + FPT_sresb(p_port,p_card); - return 0xFF; - } + while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {} + + pCurrNvRam = pCurrCard->pNvRamInfo; + if(pCurrNvRam){ + ScamFlg = pCurrNvRam->niScamConf; + } + else{ + ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2); + } - else if (p_int & FIFO) { + FPT_XbowInit(p_port, ScamFlg); - WRW_HARPOON((p_port + hp_intstat), FIFO); + FPT_scini(p_card, pCurrCard->ourId, 0); - if (pCurrCard->currentSCCB != NULL) - FPT_sxfrp(p_port, p_card); - } + return(0xFF); + } + + + else if (p_int & FIFO) { + + WRW_HARPOON((p_port+hp_intstat), FIFO); + + if (pCurrCard->currentSCCB != NULL) + FPT_sxfrp(p_port,p_card); + } + + else if (p_int & TIMEOUT) + { - else if (p_int & TIMEOUT) { + DISABLE_AUTO(p_port); - DISABLE_AUTO(p_port); + WRW_HARPOON((p_port+hp_intstat), + (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN)); - WRW_HARPOON((p_port + hp_intstat), - (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE | - IUNKWN)); + pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT; - pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT; - currTar_Info = - &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID]; - if ((pCurrCard->globalFlags & F_CONLUN_IO) - && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != - TAG_Q_TRYING)) - currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = - 0; + currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID]; + if((pCurrCard->globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0; else - currTar_Info->TarLUNBusy[0] = 0; + currTar_Info->TarLUNBusy[0] = 0; - if (currTar_Info->TarEEValue & EE_SYNC_MASK) { - currTar_Info->TarSyncCtrl = 0; - currTar_Info->TarStatus &= ~TAR_SYNC_MASK; - } - if (currTar_Info->TarEEValue & EE_WIDE_SCSI) { - currTar_Info->TarStatus &= ~TAR_WIDE_MASK; - } + if (currTar_Info->TarEEValue & EE_SYNC_MASK) + { + currTar_Info->TarSyncCtrl = 0; + currTar_Info->TarStatus &= ~TAR_SYNC_MASK; + } - FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI, - currTar_Info); + if (currTar_Info->TarEEValue & EE_WIDE_SCSI) + { + currTar_Info->TarStatus &= ~TAR_WIDE_MASK; + } - FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card); + FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info); - } + FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card); + + } - else if (p_int & SCAM_SEL) { + else if (p_int & SCAM_SEL) + { - FPT_scarb(p_port, LEVEL2_TAR); - FPT_scsel(p_port); - FPT_scasid(p_card, p_port); + FPT_scarb(p_port,LEVEL2_TAR); + FPT_scsel(p_port); + FPT_scasid(p_card, p_port); - FPT_scbusf(p_port); + FPT_scbusf(p_port); - WRW_HARPOON((p_port + hp_intstat), SCAM_SEL); - } + WRW_HARPOON((p_port+hp_intstat), SCAM_SEL); + } - return 0x00; + return(0x00); } + /*--------------------------------------------------------------------- * * Function: SccbMgrTableInit @@ -2163,19 +2683,21 @@ static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, static void FPT_SccbMgrTableInitAll() { - unsigned char thisCard; + UCHAR thisCard; - for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) { - FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard); + for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) + { + FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard); - FPT_BL_Card[thisCard].ioPort = 0x00; - FPT_BL_Card[thisCard].cardInfo = NULL; - FPT_BL_Card[thisCard].cardIndex = 0xFF; - FPT_BL_Card[thisCard].ourId = 0x00; - FPT_BL_Card[thisCard].pNvRamInfo = NULL; - } + FPT_BL_Card[thisCard].ioPort = 0x00; + FPT_BL_Card[thisCard].cardInfo = NULL; + FPT_BL_Card[thisCard].cardIndex = 0xFF; + FPT_BL_Card[thisCard].ourId = 0x00; + FPT_BL_Card[thisCard].pNvRamInfo = NULL; + } } + /*--------------------------------------------------------------------- * * Function: SccbMgrTableInit @@ -2184,30 +2706,33 @@ static void FPT_SccbMgrTableInitAll() * *---------------------------------------------------------------------*/ -static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard, - unsigned char p_card) +static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card) { - unsigned char scsiID, qtag; + UCHAR scsiID, qtag; - for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) { + for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) + { FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; } - for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) { - FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0; - FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0; - FPT_SccbMgrTableInitTarget(p_card, scsiID); - } + for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) + { + FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0; + FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0; + FPT_SccbMgrTableInitTarget(p_card, scsiID); + } - pCurrCard->scanIndex = 0x00; - pCurrCard->currentSCCB = NULL; - pCurrCard->globalFlags = 0x00; - pCurrCard->cmdCounter = 0x00; + pCurrCard->scanIndex = 0x00; + pCurrCard->currentSCCB = NULL; + pCurrCard->globalFlags = 0x00; + pCurrCard->cmdCounter = 0x00; pCurrCard->tagQ_Lst = 0x01; - pCurrCard->discQCount = 0; + pCurrCard->discQCount = 0; + } + /*--------------------------------------------------------------------- * * Function: SccbMgrTableInit @@ -2216,12 +2741,11 @@ static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard, * *---------------------------------------------------------------------*/ -static void FPT_SccbMgrTableInitTarget(unsigned char p_card, - unsigned char target) +static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target) { - unsigned char lun, qtag; - struct sccb_mgr_tar_info *currTar_Info; + UCHAR lun, qtag; + PSCCBMgr_tar_info currTar_Info; currTar_Info = &FPT_sccbMgrTbl[p_card][target]; @@ -2233,15 +2757,19 @@ static void FPT_SccbMgrTableInitTarget(unsigned char p_card, currTar_Info->TarTagQ_Cnt = 0; currTar_Info->TarLUN_CA = 0; - for (lun = 0; lun < MAX_LUN; lun++) { + + for (lun = 0; lun < MAX_LUN; lun++) + { currTar_Info->TarLUNBusy[lun] = 0; currTar_Info->LunDiscQ_Idx[lun] = 0; } - for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) { - if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) { - if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == - target) { + for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) + { + if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) + { + if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target) + { FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; FPT_BL_Card[p_card].discQCount--; } @@ -2249,6 +2777,7 @@ static void FPT_SccbMgrTableInitTarget(unsigned char p_card, } } + /*--------------------------------------------------------------------- * * Function: sfetm @@ -2258,66 +2787,71 @@ static void FPT_SccbMgrTableInitTarget(unsigned char p_card, * *---------------------------------------------------------------------*/ -static unsigned char FPT_sfm(unsigned long port, struct sccb *pCurrSCCB) +static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB) { - unsigned char message; - unsigned short TimeOutLoop; + UCHAR message; + USHORT TimeOutLoop; TimeOutLoop = 0; - while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) && - (TimeOutLoop++ < 20000)) { - } + while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) && + (TimeOutLoop++ < 20000) ){} + + + WR_HARPOON(port+hp_portctrl_0, SCSI_PORT); - WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); + message = RD_HARPOON(port+hp_scsidata_0); - message = RD_HARPOON(port + hp_scsidata_0); + WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH); - WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH); if (TimeOutLoop > 20000) - message = 0x00; /* force message byte = 0 if Time Out on Req */ - - if ((RDW_HARPOON((port + hp_intstat)) & PARITY) && - (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) { - WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); - WR_HARPOON(port + hp_xferstat, 0); - WR_HARPOON(port + hp_fiforead, 0); - WR_HARPOON(port + hp_fifowrite, 0); - if (pCurrSCCB != NULL) { + message = 0x00; /* force message byte = 0 if Time Out on Req */ + + if ((RDW_HARPOON((port+hp_intstat)) & PARITY) && + (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR)) + { + WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); + WR_HARPOON(port+hp_xferstat, 0); + WR_HARPOON(port+hp_fiforead, 0); + WR_HARPOON(port+hp_fifowrite, 0); + if (pCurrSCCB != NULL) + { pCurrSCCB->Sccb_scsimsg = SMPARITY; } message = 0x00; - do { + do + { ACCEPT_MSG_ATN(port); TimeOutLoop = 0; - while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) && - (TimeOutLoop++ < 20000)) { - } - if (TimeOutLoop > 20000) { - WRW_HARPOON((port + hp_intstat), PARITY); - return message; + while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) && + (TimeOutLoop++ < 20000) ){} + if (TimeOutLoop > 20000) + { + WRW_HARPOON((port+hp_intstat), PARITY); + return(message); } - if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) != - S_MSGI_PH) { - WRW_HARPOON((port + hp_intstat), PARITY); - return message; + if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH) + { + WRW_HARPOON((port+hp_intstat), PARITY); + return(message); } - WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); + WR_HARPOON(port+hp_portctrl_0, SCSI_PORT); - RD_HARPOON(port + hp_scsidata_0); + RD_HARPOON(port+hp_scsidata_0); - WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); + WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); - } while (1); + }while(1); } - WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); - WR_HARPOON(port + hp_xferstat, 0); - WR_HARPOON(port + hp_fiforead, 0); - WR_HARPOON(port + hp_fifowrite, 0); - return message; + WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); + WR_HARPOON(port+hp_xferstat, 0); + WR_HARPOON(port+hp_fiforead, 0); + WR_HARPOON(port+hp_fifowrite, 0); + return(message); } + /*--------------------------------------------------------------------- * * Function: FPT_ssel @@ -2326,90 +2860,102 @@ static unsigned char FPT_sfm(unsigned long port, struct sccb *pCurrSCCB) * *---------------------------------------------------------------------*/ -static void FPT_ssel(unsigned long port, unsigned char p_card) +static void FPT_ssel(ULONG port, UCHAR p_card) { - unsigned char auto_loaded, i, target, *theCCB; + UCHAR auto_loaded, i, target, *theCCB; - unsigned long cdb_reg; - struct sccb_card *CurrCard; - struct sccb *currSCCB; - struct sccb_mgr_tar_info *currTar_Info; - unsigned char lastTag, lun; + ULONG cdb_reg; + PSCCBcard CurrCard; + PSCCB currSCCB; + PSCCBMgr_tar_info currTar_Info; + UCHAR lastTag, lun; - CurrCard = &FPT_BL_Card[p_card]; - currSCCB = CurrCard->currentSCCB; - target = currSCCB->TargID; - currTar_Info = &FPT_sccbMgrTbl[p_card][target]; - lastTag = CurrCard->tagQ_Lst; + CurrCard = &FPT_BL_Card[p_card]; + currSCCB = CurrCard->currentSCCB; + target = currSCCB->TargID; + currTar_Info = &FPT_sccbMgrTbl[p_card][target]; + lastTag = CurrCard->tagQ_Lst; + + ARAM_ACCESS(port); - ARAM_ACCESS(port); if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT) currSCCB->ControlByte &= ~F_USE_CMD_Q; - if (((CurrCard->globalFlags & F_CONLUN_IO) && - ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + if(((CurrCard->globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) - lun = currSCCB->Lun; + lun = currSCCB->Lun; else lun = 0; - if (CurrCard->globalFlags & F_TAG_STARTED) { - if (!(currSCCB->ControlByte & F_USE_CMD_Q)) { - if ((currTar_Info->TarLUN_CA == 0) - && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) - == TAG_Q_TRYING)) { - - if (currTar_Info->TarTagQ_Cnt != 0) { - currTar_Info->TarLUNBusy[lun] = 1; - FPT_queueSelectFail(CurrCard, p_card); - SGRAM_ACCESS(port); - return; - } - else { - currTar_Info->TarLUNBusy[lun] = 1; - } + if (CurrCard->globalFlags & F_TAG_STARTED) + { + if (!(currSCCB->ControlByte & F_USE_CMD_Q)) + { + if ((currTar_Info->TarLUN_CA == 0) + && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) + == TAG_Q_TRYING)) + { - } - /*End non-tagged */ - else { - currTar_Info->TarLUNBusy[lun] = 1; - } + if (currTar_Info->TarTagQ_Cnt !=0) + { + currTar_Info->TarLUNBusy[lun] = 1; + FPT_queueSelectFail(CurrCard,p_card); + SGRAM_ACCESS(port); + return; + } - } - /*!Use cmd Q Tagged */ - else { - if (currTar_Info->TarLUN_CA == 1) { - FPT_queueSelectFail(CurrCard, p_card); - SGRAM_ACCESS(port); - return; - } + else { + currTar_Info->TarLUNBusy[lun] = 1; + } - currTar_Info->TarLUNBusy[lun] = 1; + } /*End non-tagged */ - } /*else use cmd Q tagged */ + else { + currTar_Info->TarLUNBusy[lun] = 1; + } - } - /*if glob tagged started */ - else { - currTar_Info->TarLUNBusy[lun] = 1; - } + } /*!Use cmd Q Tagged */ - if ((((CurrCard->globalFlags & F_CONLUN_IO) && - ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) - || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) { - if (CurrCard->discQCount >= QUEUE_DEPTH) { + else { + if (currTar_Info->TarLUN_CA == 1) + { + FPT_queueSelectFail(CurrCard,p_card); + SGRAM_ACCESS(port); + return; + } + + currTar_Info->TarLUNBusy[lun] = 1; + + } /*else use cmd Q tagged */ + + } /*if glob tagged started */ + + else { + currTar_Info->TarLUNBusy[lun] = 1; + } + + + + if((((CurrCard->globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) + { + if(CurrCard->discQCount >= QUEUE_DEPTH) + { currTar_Info->TarLUNBusy[lun] = 1; - FPT_queueSelectFail(CurrCard, p_card); + FPT_queueSelectFail(CurrCard,p_card); SGRAM_ACCESS(port); return; } - for (i = 1; i < QUEUE_DEPTH; i++) { - if (++lastTag >= QUEUE_DEPTH) - lastTag = 1; - if (CurrCard->discQ_Tbl[lastTag] == NULL) { + for (i = 1; i < QUEUE_DEPTH; i++) + { + if (++lastTag >= QUEUE_DEPTH) lastTag = 1; + if (CurrCard->discQ_Tbl[lastTag] == NULL) + { CurrCard->tagQ_Lst = lastTag; currTar_Info->LunDiscQ_Idx[lun] = lastTag; CurrCard->discQ_Tbl[lastTag] = currSCCB; @@ -2417,206 +2963,206 @@ static void FPT_ssel(unsigned long port, unsigned char p_card) break; } } - if (i == QUEUE_DEPTH) { + if(i == QUEUE_DEPTH) + { currTar_Info->TarLUNBusy[lun] = 1; - FPT_queueSelectFail(CurrCard, p_card); + FPT_queueSelectFail(CurrCard,p_card); SGRAM_ACCESS(port); return; } } - auto_loaded = 0; - WR_HARPOON(port + hp_select_id, target); - WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */ - if (currSCCB->OperationCode == RESET_COMMAND) { - WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT + - (currSCCB-> - Sccb_idmsg & ~DISC_PRIV))); + auto_loaded = 0; - WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP); + WR_HARPOON(port+hp_select_id, target); + WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */ - currSCCB->Sccb_scsimsg = SMDEV_RESET; + if (currSCCB->OperationCode == RESET_COMMAND) { + WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+ + (currSCCB->Sccb_idmsg & ~DISC_PRIV))); - WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT)); - auto_loaded = 1; - currSCCB->Sccb_scsistat = SELECT_BDR_ST; + WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP); - if (currTar_Info->TarEEValue & EE_SYNC_MASK) { - currTar_Info->TarSyncCtrl = 0; - currTar_Info->TarStatus &= ~TAR_SYNC_MASK; - } + currSCCB->Sccb_scsimsg = SMDEV_RESET; - if (currTar_Info->TarEEValue & EE_WIDE_SCSI) { - currTar_Info->TarStatus &= ~TAR_WIDE_MASK; - } + WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); + auto_loaded = 1; + currSCCB->Sccb_scsistat = SELECT_BDR_ST; - FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info); - FPT_SccbMgrTableInitTarget(p_card, target); + if (currTar_Info->TarEEValue & EE_SYNC_MASK) + { + currTar_Info->TarSyncCtrl = 0; + currTar_Info->TarStatus &= ~TAR_SYNC_MASK; + } - } + if (currTar_Info->TarEEValue & EE_WIDE_SCSI) + { + currTar_Info->TarStatus &= ~TAR_WIDE_MASK; + } - else if (currSCCB->Sccb_scsistat == ABORT_ST) { - WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT + - (currSCCB-> - Sccb_idmsg & ~DISC_PRIV))); + FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info); + FPT_SccbMgrTableInitTarget(p_card, target); - WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ); + } - WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + - (((unsigned - char)(currSCCB-> - ControlByte & - TAG_TYPE_MASK) - >> 6) | (unsigned char) - 0x20))); - WRW_HARPOON((port + SYNC_MSGS + 2), - (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag)); - WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP)); + else if(currSCCB->Sccb_scsistat == ABORT_ST) + { + WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+ + (currSCCB->Sccb_idmsg & ~DISC_PRIV))); - WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT)); - auto_loaded = 1; + WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ); - } + WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+ + (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK) + >> 6) | (UCHAR)0x20))); + WRW_HARPOON((port+SYNC_MSGS+2), + (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag)); + WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP )); - else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) { - auto_loaded = FPT_siwidn(port, p_card); - currSCCB->Sccb_scsistat = SELECT_WN_ST; - } + WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); + auto_loaded = 1; + + } - else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) - == SYNC_SUPPORTED)) { - auto_loaded = FPT_sisyncn(port, p_card, 0); - currSCCB->Sccb_scsistat = SELECT_SN_ST; - } + else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) { + auto_loaded = FPT_siwidn(port,p_card); + currSCCB->Sccb_scsistat = SELECT_WN_ST; + } - if (!auto_loaded) { + else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) + == SYNC_SUPPORTED)) { + auto_loaded = FPT_sisyncn(port,p_card, 0); + currSCCB->Sccb_scsistat = SELECT_SN_ST; + } - if (currSCCB->ControlByte & F_USE_CMD_Q) { - CurrCard->globalFlags |= F_TAG_STARTED; + if (!auto_loaded) + { - if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) - == TAG_Q_REJECT) { - currSCCB->ControlByte &= ~F_USE_CMD_Q; + if (currSCCB->ControlByte & F_USE_CMD_Q) + { - /* Fix up the start instruction with a jump to - Non-Tag-CMD handling */ - WRW_HARPOON((port + ID_MSG_STRT), - BRH_OP + ALWAYS + NTCMD); + CurrCard->globalFlags |= F_TAG_STARTED; - WRW_HARPOON((port + NON_TAG_ID_MSG), - (MPM_OP + AMSG_OUT + - currSCCB->Sccb_idmsg)); + if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) + == TAG_Q_REJECT) + { + currSCCB->ControlByte &= ~F_USE_CMD_Q; - WR_HARPOON(port + hp_autostart_3, - (SELECT + SELCHK_STRT)); + /* Fix up the start instruction with a jump to + Non-Tag-CMD handling */ + WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD); - /* Setup our STATE so we know what happend when - the wheels fall off. */ - currSCCB->Sccb_scsistat = SELECT_ST; + WRW_HARPOON((port+NON_TAG_ID_MSG), + (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg)); - currTar_Info->TarLUNBusy[lun] = 1; - } + WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); + + /* Setup our STATE so we know what happend when + the wheels fall off. */ + currSCCB->Sccb_scsistat = SELECT_ST; + + currTar_Info->TarLUNBusy[lun] = 1; + } + + else + { + WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg)); + + WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+ + (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK) + >> 6) | (UCHAR)0x20))); - else { - WRW_HARPOON((port + ID_MSG_STRT), - (MPM_OP + AMSG_OUT + - currSCCB->Sccb_idmsg)); - - WRW_HARPOON((port + ID_MSG_STRT + 2), - (MPM_OP + AMSG_OUT + - (((unsigned char)(currSCCB-> - ControlByte & - TAG_TYPE_MASK) - >> 6) | (unsigned char)0x20))); - - for (i = 1; i < QUEUE_DEPTH; i++) { - if (++lastTag >= QUEUE_DEPTH) - lastTag = 1; - if (CurrCard->discQ_Tbl[lastTag] == - NULL) { - WRW_HARPOON((port + - ID_MSG_STRT + 6), - (MPM_OP + AMSG_OUT + - lastTag)); + for (i = 1; i < QUEUE_DEPTH; i++) + { + if (++lastTag >= QUEUE_DEPTH) lastTag = 1; + if (CurrCard->discQ_Tbl[lastTag] == NULL) + { + WRW_HARPOON((port+ID_MSG_STRT+6), + (MPM_OP+AMSG_OUT+lastTag)); CurrCard->tagQ_Lst = lastTag; currSCCB->Sccb_tag = lastTag; - CurrCard->discQ_Tbl[lastTag] = - currSCCB; + CurrCard->discQ_Tbl[lastTag] = currSCCB; CurrCard->discQCount++; break; } } - if (i == QUEUE_DEPTH) { - currTar_Info->TarLUNBusy[lun] = 1; - FPT_queueSelectFail(CurrCard, p_card); - SGRAM_ACCESS(port); - return; - } - currSCCB->Sccb_scsistat = SELECT_Q_ST; + if ( i == QUEUE_DEPTH ) + { + currTar_Info->TarLUNBusy[lun] = 1; + FPT_queueSelectFail(CurrCard,p_card); + SGRAM_ACCESS(port); + return; + } - WR_HARPOON(port + hp_autostart_3, - (SELECT + SELCHK_STRT)); - } - } + currSCCB->Sccb_scsistat = SELECT_Q_ST; - else { + WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); + } + } - WRW_HARPOON((port + ID_MSG_STRT), - BRH_OP + ALWAYS + NTCMD); + else + { - WRW_HARPOON((port + NON_TAG_ID_MSG), - (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg)); + WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD); - currSCCB->Sccb_scsistat = SELECT_ST; + WRW_HARPOON((port+NON_TAG_ID_MSG), + (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg)); - WR_HARPOON(port + hp_autostart_3, - (SELECT + SELCHK_STRT)); - } + currSCCB->Sccb_scsistat = SELECT_ST; - theCCB = (unsigned char *)&currSCCB->Cdb[0]; + WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); + } - cdb_reg = port + CMD_STRT; - for (i = 0; i < currSCCB->CdbLength; i++) { - WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB)); - cdb_reg += 2; - theCCB++; - } + theCCB = (UCHAR *)&currSCCB->Cdb[0]; - if (currSCCB->CdbLength != TWELVE_BYTE_CMD) - WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP)); + cdb_reg = port + CMD_STRT; - } - /* auto_loaded */ - WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00); - WR_HARPOON(port + hp_xferstat, 0x00); + for (i=0; i < currSCCB->CdbLength; i++) + { + WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB)); + cdb_reg +=2; + theCCB++; + } + + if (currSCCB->CdbLength != TWELVE_BYTE_CMD) + WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP)); - WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE)); + } /* auto_loaded */ - WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT)); + WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00); + WR_HARPOON(port+hp_xferstat, 0x00); - if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) { - WR_HARPOON(port + hp_scsictrl_0, - (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL)); - } else { + WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE)); -/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F); + WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT)); + + + if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) + { + WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL)); + } + else + { + +/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F); auto_loaded |= AUTO_IMMED; */ - auto_loaded = AUTO_IMMED; + auto_loaded = AUTO_IMMED; - DISABLE_AUTO(port); + DISABLE_AUTO(port); - WR_HARPOON(port + hp_autostart_3, auto_loaded); - } + WR_HARPOON(port+hp_autostart_3, auto_loaded); + } - SGRAM_ACCESS(port); + SGRAM_ACCESS(port); } + /*--------------------------------------------------------------------- * * Function: FPT_sres @@ -2625,276 +3171,303 @@ static void FPT_ssel(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_sres(unsigned long port, unsigned char p_card, - struct sccb_card *pCurrCard) +static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard) { - unsigned char our_target, message, lun = 0, tag, msgRetryCount; + UCHAR our_target, message, lun = 0, tag, msgRetryCount; + - struct sccb_mgr_tar_info *currTar_Info; - struct sccb *currSCCB; + PSCCBMgr_tar_info currTar_Info; + PSCCB currSCCB; - if (pCurrCard->currentSCCB != NULL) { - currTar_Info = - &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID]; + + + + if(pCurrCard->currentSCCB != NULL) + { + currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID]; DISABLE_AUTO(port); - WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL)); + + WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL)); + currSCCB = pCurrCard->currentSCCB; - if (currSCCB->Sccb_scsistat == SELECT_WN_ST) { + if(currSCCB->Sccb_scsistat == SELECT_WN_ST) + { currTar_Info->TarStatus &= ~TAR_WIDE_MASK; currSCCB->Sccb_scsistat = BUS_FREE_ST; } - if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { + if(currSCCB->Sccb_scsistat == SELECT_SN_ST) + { currTar_Info->TarStatus &= ~TAR_SYNC_MASK; currSCCB->Sccb_scsistat = BUS_FREE_ST; } - if (((pCurrCard->globalFlags & F_CONLUN_IO) && - ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != - TAG_Q_TRYING))) { - currTar_Info->TarLUNBusy[currSCCB->Lun] = 0; - if (currSCCB->Sccb_scsistat != ABORT_ST) { + if(((pCurrCard->globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + { + currTar_Info->TarLUNBusy[currSCCB->Lun] = 0; + if(currSCCB->Sccb_scsistat != ABORT_ST) + { pCurrCard->discQCount--; - pCurrCard->discQ_Tbl[currTar_Info-> - LunDiscQ_Idx[currSCCB-> - Lun]] - = NULL; + pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]] + = NULL; } - } else { - currTar_Info->TarLUNBusy[0] = 0; - if (currSCCB->Sccb_tag) { - if (currSCCB->Sccb_scsistat != ABORT_ST) { - pCurrCard->discQCount--; - pCurrCard->discQ_Tbl[currSCCB-> - Sccb_tag] = NULL; - } - } else { - if (currSCCB->Sccb_scsistat != ABORT_ST) { + } + else + { + currTar_Info->TarLUNBusy[0] = 0; + if(currSCCB->Sccb_tag) + { + if(currSCCB->Sccb_scsistat != ABORT_ST) + { + pCurrCard->discQCount--; + pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL; + } + }else + { + if(currSCCB->Sccb_scsistat != ABORT_ST) + { pCurrCard->discQCount--; - pCurrCard->discQ_Tbl[currTar_Info-> - LunDiscQ_Idx[0]] = - NULL; + pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL; } } } - FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card); + FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card); } - WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00); + WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00); + - our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4); + our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4); currTar_Info = &FPT_sccbMgrTbl[p_card][our_target]; + msgRetryCount = 0; - do { + do + { currTar_Info = &FPT_sccbMgrTbl[p_card][our_target]; tag = 0; - while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) { - if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) { - WRW_HARPOON((port + hp_intstat), PHASE); + while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) + { + if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) + { + + WRW_HARPOON((port+hp_intstat), PHASE); return; } } - WRW_HARPOON((port + hp_intstat), PHASE); - if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) { - - message = FPT_sfm(port, pCurrCard->currentSCCB); - if (message) { - - if (message <= (0x80 | LUN_MASK)) { - lun = message & (unsigned char)LUN_MASK; - - if ((currTar_Info-> - TarStatus & TAR_TAG_Q_MASK) == - TAG_Q_TRYING) { - if (currTar_Info->TarTagQ_Cnt != - 0) { - - if (! - (currTar_Info-> - TarLUN_CA)) { - ACCEPT_MSG(port); /*Release the ACK for ID msg. */ - - message = - FPT_sfm - (port, - pCurrCard-> - currentSCCB); - if (message) { - ACCEPT_MSG - (port); + WRW_HARPOON((port+hp_intstat), PHASE); + if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) + { + + message = FPT_sfm(port,pCurrCard->currentSCCB); + if (message) + { + + if (message <= (0x80 | LUN_MASK)) + { + lun = message & (UCHAR)LUN_MASK; + + if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING) + { + if (currTar_Info->TarTagQ_Cnt != 0) + { + + if (!(currTar_Info->TarLUN_CA)) + { + ACCEPT_MSG(port); /*Release the ACK for ID msg. */ + + + message = FPT_sfm(port,pCurrCard->currentSCCB); + if (message) + { + ACCEPT_MSG(port); } else - message - = 0; - - if (message != - 0) { - tag = - FPT_sfm - (port, - pCurrCard-> - currentSCCB); - - if (! - (tag)) - message - = - 0; + message = 0; + + if(message != 0) + { + tag = FPT_sfm(port,pCurrCard->currentSCCB); + + if (!(tag)) + message = 0; } - } - /*C.A. exists! */ - } - /*End Q cnt != 0 */ - } - /*End Tag cmds supported! */ - } - /*End valid ID message. */ - else { + } /*C.A. exists! */ + + } /*End Q cnt != 0 */ + + } /*End Tag cmds supported! */ + + } /*End valid ID message. */ + + else + { ACCEPT_MSG_ATN(port); } - } - /* End good id message. */ - else { + } /* End good id message. */ + + else + { message = 0; } - } else { + } + else + { ACCEPT_MSG_ATN(port); - while (! - (RDW_HARPOON((port + hp_intstat)) & - (PHASE | RESET)) - && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) - && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ; + while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) && + !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) && + (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ; return; } - if (message == 0) { + if(message == 0) + { msgRetryCount++; - if (msgRetryCount == 1) { + if(msgRetryCount == 1) + { FPT_SendMsg(port, SMPARITY); - } else { + } + else + { FPT_SendMsg(port, SMDEV_RESET); - FPT_sssyncv(port, our_target, NARROW_SCSI, - currTar_Info); - - if (FPT_sccbMgrTbl[p_card][our_target]. - TarEEValue & EE_SYNC_MASK) { + FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info); - FPT_sccbMgrTbl[p_card][our_target]. - TarStatus &= ~TAR_SYNC_MASK; + if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK) + { + + FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK; } - if (FPT_sccbMgrTbl[p_card][our_target]. - TarEEValue & EE_WIDE_SCSI) { + if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI) + { - FPT_sccbMgrTbl[p_card][our_target]. - TarStatus &= ~TAR_WIDE_MASK; + FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK; } - FPT_queueFlushTargSccb(p_card, our_target, - SCCB_COMPLETE); - FPT_SccbMgrTableInitTarget(p_card, our_target); + + FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE); + FPT_SccbMgrTableInitTarget(p_card,our_target); return; } } - } while (message == 0); + }while(message == 0); + - if (((pCurrCard->globalFlags & F_CONLUN_IO) && - ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { + + if(((pCurrCard->globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + { currTar_Info->TarLUNBusy[lun] = 1; - pCurrCard->currentSCCB = - pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]]; - if (pCurrCard->currentSCCB != NULL) { + pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]]; + if(pCurrCard->currentSCCB != NULL) + { ACCEPT_MSG(port); - } else { + } + else + { ACCEPT_MSG_ATN(port); } - } else { + } + else + { currTar_Info->TarLUNBusy[0] = 1; - if (tag) { - if (pCurrCard->discQ_Tbl[tag] != NULL) { - pCurrCard->currentSCCB = - pCurrCard->discQ_Tbl[tag]; - currTar_Info->TarTagQ_Cnt--; + + if (tag) + { + if (pCurrCard->discQ_Tbl[tag] != NULL) + { + pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag]; + currTar_Info->TarTagQ_Cnt--; ACCEPT_MSG(port); - } else { - ACCEPT_MSG_ATN(port); } - } else { - pCurrCard->currentSCCB = - pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]]; - if (pCurrCard->currentSCCB != NULL) { + else + { + ACCEPT_MSG_ATN(port); + } + }else + { + pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]]; + if(pCurrCard->currentSCCB != NULL) + { ACCEPT_MSG(port); - } else { + } + else + { ACCEPT_MSG_ATN(port); } } } - if (pCurrCard->currentSCCB != NULL) { - if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) { - /* During Abort Tag command, the target could have got re-selected - and completed the command. Check the select Q and remove the CCB - if it is in the Select Q */ + if(pCurrCard->currentSCCB != NULL) + { + if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) + { + /* During Abort Tag command, the target could have got re-selected + and completed the command. Check the select Q and remove the CCB + if it is in the Select Q */ FPT_queueFindSccb(pCurrCard->currentSCCB, p_card); } } - while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) && - !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) && - (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ; + + while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) && + !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) && + (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ; } -static void FPT_SendMsg(unsigned long port, unsigned char message) +static void FPT_SendMsg(ULONG port, UCHAR message) { - while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) { - if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) { + while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) + { + if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) + { - WRW_HARPOON((port + hp_intstat), PHASE); + WRW_HARPOON((port+hp_intstat), PHASE); return; } } - WRW_HARPOON((port + hp_intstat), PHASE); - if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) { - WRW_HARPOON((port + hp_intstat), - (BUS_FREE | PHASE | XFER_CNT_0)); + WRW_HARPOON((port+hp_intstat), PHASE); + if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) + { + WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0)); + - WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN); + WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN); - WR_HARPOON(port + hp_scsidata_0, message); + WR_HARPOON(port+hp_scsidata_0,message); - WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); + WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); ACCEPT_MSG(port); - WR_HARPOON(port + hp_portctrl_0, 0x00); + WR_HARPOON(port+hp_portctrl_0, 0x00); if ((message == SMABORT) || (message == SMDEV_RESET) || - (message == SMABORT_TAG)) { - while (! - (RDW_HARPOON((port + hp_intstat)) & - (BUS_FREE | PHASE))) { - } + (message == SMABORT_TAG) ) + { + while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {} - if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) { - WRW_HARPOON((port + hp_intstat), BUS_FREE); + if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) + { + WRW_HARPOON((port+hp_intstat), BUS_FREE); } } } @@ -2908,180 +3481,178 @@ static void FPT_SendMsg(unsigned long port, unsigned char message) * target device. * *---------------------------------------------------------------------*/ -static void FPT_sdecm(unsigned char message, unsigned long port, - unsigned char p_card) +static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card) { - struct sccb *currSCCB; - struct sccb_card *CurrCard; - struct sccb_mgr_tar_info *currTar_Info; + PSCCB currSCCB; + PSCCBcard CurrCard; + PSCCBMgr_tar_info currTar_Info; CurrCard = &FPT_BL_Card[p_card]; currSCCB = CurrCard->currentSCCB; currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; - if (message == SMREST_DATA_PTR) { - if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) { + if (message == SMREST_DATA_PTR) + { + if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) + { currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC; FPT_hostDataXferRestart(currSCCB); } ACCEPT_MSG(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } - else if (message == SMCMD_COMP) { + else if (message == SMCMD_COMP) + { + - if (currSCCB->Sccb_scsistat == SELECT_Q_ST) { - currTar_Info->TarStatus &= - ~(unsigned char)TAR_TAG_Q_MASK; - currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT; + if (currSCCB->Sccb_scsistat == SELECT_Q_ST) + { + currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK; + currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT; } ACCEPT_MSG(port); } - else if ((message == SMNO_OP) || (message >= SMIDENT) - || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) { + else if ((message == SMNO_OP) || (message >= SMIDENT) + || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) + { ACCEPT_MSG(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } - else if (message == SMREJECT) { + else if (message == SMREJECT) + { if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) || - (currSCCB->Sccb_scsistat == SELECT_WN_ST) || - ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING) - || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == - TAG_Q_TRYING)) + (currSCCB->Sccb_scsistat == SELECT_WN_ST) || + ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) || + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) ) + { - WRW_HARPOON((port + hp_intstat), BUS_FREE); + WRW_HARPOON((port+hp_intstat), BUS_FREE); ACCEPT_MSG(port); - while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) && - (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE))) - { - } - if (currSCCB->Lun == 0x00) { - if ((currSCCB->Sccb_scsistat == SELECT_SN_ST)) { + while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) && + (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {} + + if(currSCCB->Lun == 0x00) + { + if ((currSCCB->Sccb_scsistat == SELECT_SN_ST)) + { - currTar_Info->TarStatus |= - (unsigned char)SYNC_SUPPORTED; + currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED; - currTar_Info->TarEEValue &= - ~EE_SYNC_MASK; + currTar_Info->TarEEValue &= ~EE_SYNC_MASK; } - else if ((currSCCB->Sccb_scsistat == - SELECT_WN_ST)) { + else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST)) + { + - currTar_Info->TarStatus = - (currTar_Info-> - TarStatus & ~WIDE_ENABLED) | - WIDE_NEGOCIATED; + currTar_Info->TarStatus = (currTar_Info->TarStatus & + ~WIDE_ENABLED) | WIDE_NEGOCIATED; - currTar_Info->TarEEValue &= - ~EE_WIDE_SCSI; + currTar_Info->TarEEValue &= ~EE_WIDE_SCSI; } - else if ((currTar_Info-> - TarStatus & TAR_TAG_Q_MASK) == - TAG_Q_TRYING) { - currTar_Info->TarStatus = - (currTar_Info-> - TarStatus & ~(unsigned char) - TAR_TAG_Q_MASK) | TAG_Q_REJECT; + else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) + { + currTar_Info->TarStatus = (currTar_Info->TarStatus & + ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT; + currSCCB->ControlByte &= ~F_USE_CMD_Q; CurrCard->discQCount--; - CurrCard->discQ_Tbl[currSCCB-> - Sccb_tag] = NULL; + CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL; currSCCB->Sccb_tag = 0x00; } } - if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) { + if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) + { + - if (currSCCB->Lun == 0x00) { - WRW_HARPOON((port + hp_intstat), - BUS_FREE); + if(currSCCB->Lun == 0x00) + { + WRW_HARPOON((port+hp_intstat), BUS_FREE); CurrCard->globalFlags |= F_NEW_SCCB_CMD; } } - else { + else + { - if ((CurrCard->globalFlags & F_CONLUN_IO) && - ((currTar_Info-> - TarStatus & TAR_TAG_Q_MASK) != - TAG_Q_TRYING)) - currTar_Info->TarLUNBusy[currSCCB-> - Lun] = 1; + if((CurrCard->globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + currTar_Info->TarLUNBusy[currSCCB->Lun] = 1; else currTar_Info->TarLUNBusy[0] = 1; - currSCCB->ControlByte &= - ~(unsigned char)F_USE_CMD_Q; - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q; + + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } } - else { + else + { ACCEPT_MSG(port); - while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) && - (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE))) + while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) && + (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {} + + if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE)) { - } - - if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) { - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } } } - else if (message == SMEXT) { + else if (message == SMEXT) + { ACCEPT_MSG(port); - FPT_shandem(port, p_card, currSCCB); + FPT_shandem(port,p_card,currSCCB); } - else if (message == SMIGNORWR) { + else if (message == SMIGNORWR) + { - ACCEPT_MSG(port); /* ACK the RESIDUE MSG */ + ACCEPT_MSG(port); /* ACK the RESIDUE MSG */ - message = FPT_sfm(port, currSCCB); + message = FPT_sfm(port,currSCCB); - if (currSCCB->Sccb_scsimsg != SMPARITY) + if(currSCCB->Sccb_scsimsg != SMPARITY) ACCEPT_MSG(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } - else { + + else + { currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; currSCCB->Sccb_scsimsg = SMREJECT; ACCEPT_MSG_ATN(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } } + /*--------------------------------------------------------------------- * * Function: FPT_shandem @@ -3089,65 +3660,76 @@ static void FPT_sdecm(unsigned char message, unsigned long port, * Description: Decide what to do with the extended message. * *---------------------------------------------------------------------*/ -static void FPT_shandem(unsigned long port, unsigned char p_card, - struct sccb *pCurrSCCB) +static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB) { - unsigned char length, message; + UCHAR length,message; - length = FPT_sfm(port, pCurrSCCB); - if (length) { + length = FPT_sfm(port,pCurrSCCB); + if (length) + { ACCEPT_MSG(port); - message = FPT_sfm(port, pCurrSCCB); - if (message) { + message = FPT_sfm(port,pCurrSCCB); + if (message) + { - if (message == SMSYNC) { + if (message == SMSYNC) + { - if (length == 0x03) { + if (length == 0x03) + { ACCEPT_MSG(port); - FPT_stsyncn(port, p_card); - } else { + FPT_stsyncn(port,p_card); + } + else + { pCurrSCCB->Sccb_scsimsg = SMREJECT; ACCEPT_MSG_ATN(port); } - } else if (message == SMWDTR) { + } + else if (message == SMWDTR) + { - if (length == 0x02) { + if (length == 0x02) + { ACCEPT_MSG(port); - FPT_stwidn(port, p_card); - } else { + FPT_stwidn(port,p_card); + } + else + { pCurrSCCB->Sccb_scsimsg = SMREJECT; ACCEPT_MSG_ATN(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + - DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } - } else { + } + else + { pCurrSCCB->Sccb_scsimsg = SMREJECT; ACCEPT_MSG_ATN(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } - } else { - if (pCurrSCCB->Sccb_scsimsg != SMPARITY) + } + else + { + if(pCurrSCCB->Sccb_scsimsg != SMPARITY) ACCEPT_MSG(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } - } else { - if (pCurrSCCB->Sccb_scsimsg == SMPARITY) - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + }else + { + if(pCurrSCCB->Sccb_scsimsg == SMPARITY) + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } } + /*--------------------------------------------------------------------- * * Function: FPT_sisyncn @@ -3157,79 +3739,73 @@ static void FPT_shandem(unsigned long port, unsigned char p_card, * *---------------------------------------------------------------------*/ -static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, - unsigned char syncFlag) +static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag) { - struct sccb *currSCCB; - struct sccb_mgr_tar_info *currTar_Info; + PSCCB currSCCB; + PSCCBMgr_tar_info currTar_Info; - currSCCB = FPT_BL_Card[p_card].currentSCCB; - currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; + currSCCB = FPT_BL_Card[p_card].currentSCCB; + currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; - if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) { + if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) { - WRW_HARPOON((port + ID_MSG_STRT), - (MPM_OP + AMSG_OUT + - (currSCCB-> - Sccb_idmsg & ~(unsigned char)DISC_PRIV))); - WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ); + WRW_HARPOON((port+ID_MSG_STRT), + (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV))); - WRW_HARPOON((port + SYNC_MSGS + 0), - (MPM_OP + AMSG_OUT + SMEXT)); - WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03)); - WRW_HARPOON((port + SYNC_MSGS + 4), - (MPM_OP + AMSG_OUT + SMSYNC)); + WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ); - if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB) + WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT )); + WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 )); + WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC)); - WRW_HARPOON((port + SYNC_MSGS + 6), - (MPM_OP + AMSG_OUT + 12)); - else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == - EE_SYNC_10MB) + if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB) - WRW_HARPOON((port + SYNC_MSGS + 6), - (MPM_OP + AMSG_OUT + 25)); + WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12)); - else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == - EE_SYNC_5MB) + else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB) - WRW_HARPOON((port + SYNC_MSGS + 6), - (MPM_OP + AMSG_OUT + 50)); + WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25)); + else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB) + + WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50)); + + else + WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00)); + + + WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP )); + WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET)); + WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP )); + + + if(syncFlag == 0) + { + WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); + currTar_Info->TarStatus = ((currTar_Info->TarStatus & + ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING); + } else - WRW_HARPOON((port + SYNC_MSGS + 6), - (MPM_OP + AMSG_OUT + 00)); - - WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP)); - WRW_HARPOON((port + SYNC_MSGS + 10), - (MPM_OP + AMSG_OUT + DEFAULT_OFFSET)); - WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP)); - - if (syncFlag == 0) { - WR_HARPOON(port + hp_autostart_3, - (SELECT + SELCHK_STRT)); - currTar_Info->TarStatus = - ((currTar_Info-> - TarStatus & ~(unsigned char)TAR_SYNC_MASK) | - (unsigned char)SYNC_TRYING); - } else { - WR_HARPOON(port + hp_autostart_3, - (AUTO_IMMED + CMD_ONLY_STRT)); + { + WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT)); } - return 1; - } - else { + return(1); + } - currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED; - currTar_Info->TarEEValue &= ~EE_SYNC_MASK; - return 0; - } + else { + + currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED; + currTar_Info->TarEEValue &= ~EE_SYNC_MASK; + return(0); + } } + + /*--------------------------------------------------------------------- * * Function: FPT_stsyncn @@ -3238,128 +3814,131 @@ static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, * necessary. * *---------------------------------------------------------------------*/ -static void FPT_stsyncn(unsigned long port, unsigned char p_card) +static void FPT_stsyncn(ULONG port, UCHAR p_card) { - unsigned char sync_msg, offset, sync_reg, our_sync_msg; - struct sccb *currSCCB; - struct sccb_mgr_tar_info *currTar_Info; + UCHAR sync_msg,offset,sync_reg,our_sync_msg; + PSCCB currSCCB; + PSCCBMgr_tar_info currTar_Info; - currSCCB = FPT_BL_Card[p_card].currentSCCB; - currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; + currSCCB = FPT_BL_Card[p_card].currentSCCB; + currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; - sync_msg = FPT_sfm(port, currSCCB); + sync_msg = FPT_sfm(port,currSCCB); - if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) + { + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); return; } - ACCEPT_MSG(port); + ACCEPT_MSG(port); - offset = FPT_sfm(port, currSCCB); - if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + offset = FPT_sfm(port,currSCCB); + + if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) + { + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); return; } - if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB) + if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB) - our_sync_msg = 12; /* Setup our Message to 20mb/s */ + our_sync_msg = 12; /* Setup our Message to 20mb/s */ - else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB) + else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB) - our_sync_msg = 25; /* Setup our Message to 10mb/s */ + our_sync_msg = 25; /* Setup our Message to 10mb/s */ - else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB) + else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB) - our_sync_msg = 50; /* Setup our Message to 5mb/s */ - else + our_sync_msg = 50; /* Setup our Message to 5mb/s */ + else - our_sync_msg = 0; /* Message = Async */ + our_sync_msg = 0; /* Message = Async */ - if (sync_msg < our_sync_msg) { - sync_msg = our_sync_msg; /*if faster, then set to max. */ - } + if (sync_msg < our_sync_msg) { + sync_msg = our_sync_msg; /*if faster, then set to max. */ + } - if (offset == ASYNC) - sync_msg = ASYNC; + if (offset == ASYNC) + sync_msg = ASYNC; - if (offset > MAX_OFFSET) - offset = MAX_OFFSET; + if (offset > MAX_OFFSET) + offset = MAX_OFFSET; - sync_reg = 0x00; + sync_reg = 0x00; - if (sync_msg > 12) + if (sync_msg > 12) - sync_reg = 0x20; /* Use 10MB/s */ + sync_reg = 0x20; /* Use 10MB/s */ - if (sync_msg > 25) + if (sync_msg > 25) - sync_reg = 0x40; /* Use 6.6MB/s */ + sync_reg = 0x40; /* Use 6.6MB/s */ - if (sync_msg > 38) + if (sync_msg > 38) - sync_reg = 0x60; /* Use 5MB/s */ + sync_reg = 0x60; /* Use 5MB/s */ - if (sync_msg > 50) + if (sync_msg > 50) - sync_reg = 0x80; /* Use 4MB/s */ + sync_reg = 0x80; /* Use 4MB/s */ - if (sync_msg > 62) + if (sync_msg > 62) - sync_reg = 0xA0; /* Use 3.33MB/s */ + sync_reg = 0xA0; /* Use 3.33MB/s */ - if (sync_msg > 75) + if (sync_msg > 75) - sync_reg = 0xC0; /* Use 2.85MB/s */ + sync_reg = 0xC0; /* Use 2.85MB/s */ - if (sync_msg > 87) + if (sync_msg > 87) - sync_reg = 0xE0; /* Use 2.5MB/s */ + sync_reg = 0xE0; /* Use 2.5MB/s */ - if (sync_msg > 100) { + if (sync_msg > 100) { - sync_reg = 0x00; /* Use ASYNC */ - offset = 0x00; - } + sync_reg = 0x00; /* Use ASYNC */ + offset = 0x00; + } - if (currTar_Info->TarStatus & WIDE_ENABLED) - sync_reg |= offset; + if (currTar_Info->TarStatus & WIDE_ENABLED) - else + sync_reg |= offset; - sync_reg |= (offset | NARROW_SCSI); + else - FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info); + sync_reg |= (offset | NARROW_SCSI); - if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { + FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info); - ACCEPT_MSG(port); - currTar_Info->TarStatus = ((currTar_Info->TarStatus & - ~(unsigned char)TAR_SYNC_MASK) | - (unsigned char)SYNC_SUPPORTED); + if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); - } - else { + ACCEPT_MSG(port); - ACCEPT_MSG_ATN(port); + currTar_Info->TarStatus = ((currTar_Info->TarStatus & + ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED); + + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); + } - FPT_sisyncr(port, sync_msg, offset); + else { - currTar_Info->TarStatus = ((currTar_Info->TarStatus & - ~(unsigned char)TAR_SYNC_MASK) | - (unsigned char)SYNC_SUPPORTED); - } + + ACCEPT_MSG_ATN(port); + + FPT_sisyncr(port,sync_msg,offset); + + currTar_Info->TarStatus = ((currTar_Info->TarStatus & + ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED); + } } + /*--------------------------------------------------------------------- * * Function: FPT_sisyncr @@ -3367,28 +3946,28 @@ static void FPT_stsyncn(unsigned long port, unsigned char p_card) * Description: Answer the targets sync message. * *---------------------------------------------------------------------*/ -static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse, - unsigned char offset) +static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset) { - ARAM_ACCESS(port); - WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT)); - WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03)); - WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC)); - WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse)); - WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP)); - WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset)); - WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP)); - SGRAM_ACCESS(port); - - WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); - WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1); - - WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT)); - - while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) { - } + ARAM_ACCESS(port); + WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT )); + WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 )); + WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC)); + WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse)); + WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP )); + WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset)); + WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP )); + SGRAM_ACCESS(port); + + WR_HARPOON(port+hp_portctrl_0, SCSI_PORT); + WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1); + + WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT)); + + while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {} } + + /*--------------------------------------------------------------------- * * Function: FPT_siwidn @@ -3398,53 +3977,50 @@ static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse, * *---------------------------------------------------------------------*/ -static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card) +static UCHAR FPT_siwidn(ULONG port, UCHAR p_card) { - struct sccb *currSCCB; - struct sccb_mgr_tar_info *currTar_Info; + PSCCB currSCCB; + PSCCBMgr_tar_info currTar_Info; - currSCCB = FPT_BL_Card[p_card].currentSCCB; - currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; + currSCCB = FPT_BL_Card[p_card].currentSCCB; + currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; - if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) { + if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) { - WRW_HARPOON((port + ID_MSG_STRT), - (MPM_OP + AMSG_OUT + - (currSCCB-> - Sccb_idmsg & ~(unsigned char)DISC_PRIV))); - WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ); + WRW_HARPOON((port+ID_MSG_STRT), + (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV))); - WRW_HARPOON((port + SYNC_MSGS + 0), - (MPM_OP + AMSG_OUT + SMEXT)); - WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02)); - WRW_HARPOON((port + SYNC_MSGS + 4), - (MPM_OP + AMSG_OUT + SMWDTR)); - WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP)); - WRW_HARPOON((port + SYNC_MSGS + 8), - (MPM_OP + AMSG_OUT + SM16BIT)); - WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP)); + WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ); - WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT)); + WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT )); + WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 )); + WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR)); + WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP )); + WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT)); + WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP )); - currTar_Info->TarStatus = ((currTar_Info->TarStatus & - ~(unsigned char)TAR_WIDE_MASK) | - (unsigned char)WIDE_ENABLED); + WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); - return 1; - } - else { + currTar_Info->TarStatus = ((currTar_Info->TarStatus & + ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED); + + return(1); + } - currTar_Info->TarStatus = ((currTar_Info->TarStatus & - ~(unsigned char)TAR_WIDE_MASK) | - WIDE_NEGOCIATED); + else { - currTar_Info->TarEEValue &= ~EE_WIDE_SCSI; - return 0; - } + currTar_Info->TarStatus = ((currTar_Info->TarStatus & + ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED); + + currTar_Info->TarEEValue &= ~EE_WIDE_SCSI; + return(0); + } } + + /*--------------------------------------------------------------------- * * Function: FPT_stwidn @@ -3453,70 +4029,79 @@ static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card) * necessary. * *---------------------------------------------------------------------*/ -static void FPT_stwidn(unsigned long port, unsigned char p_card) +static void FPT_stwidn(ULONG port, UCHAR p_card) { - unsigned char width; - struct sccb *currSCCB; - struct sccb_mgr_tar_info *currTar_Info; + UCHAR width; + PSCCB currSCCB; + PSCCBMgr_tar_info currTar_Info; - currSCCB = FPT_BL_Card[p_card].currentSCCB; - currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; + currSCCB = FPT_BL_Card[p_card].currentSCCB; + currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; - width = FPT_sfm(port, currSCCB); + width = FPT_sfm(port,currSCCB); - if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) + { + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); return; } - if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI)) - width = 0; - if (width) { - currTar_Info->TarStatus |= WIDE_ENABLED; - width = 0; - } else { - width = NARROW_SCSI; - currTar_Info->TarStatus &= ~WIDE_ENABLED; - } + if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI)) + width = 0; - FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info); + if (width) { + currTar_Info->TarStatus |= WIDE_ENABLED; + width = 0; + } + else { + width = NARROW_SCSI; + currTar_Info->TarStatus &= ~WIDE_ENABLED; + } - if (currSCCB->Sccb_scsistat == SELECT_WN_ST) { - currTar_Info->TarStatus |= WIDE_NEGOCIATED; + FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info); - if (! - ((currTar_Info->TarStatus & TAR_SYNC_MASK) == - SYNC_SUPPORTED)) { - ACCEPT_MSG_ATN(port); - ARAM_ACCESS(port); - FPT_sisyncn(port, p_card, 1); - currSCCB->Sccb_scsistat = SELECT_SN_ST; - SGRAM_ACCESS(port); - } else { - ACCEPT_MSG(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); - } - } - else { + if (currSCCB->Sccb_scsistat == SELECT_WN_ST) + { + - ACCEPT_MSG_ATN(port); - if (currTar_Info->TarEEValue & EE_WIDE_SCSI) - width = SM16BIT; + currTar_Info->TarStatus |= WIDE_NEGOCIATED; + + if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED)) + { + ACCEPT_MSG_ATN(port); + ARAM_ACCESS(port); + FPT_sisyncn(port,p_card, 1); + currSCCB->Sccb_scsistat = SELECT_SN_ST; + SGRAM_ACCESS(port); + } else - width = SM8BIT; + { + ACCEPT_MSG(port); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); + } + } - FPT_siwidr(port, width); + else { - currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED); - } + + ACCEPT_MSG_ATN(port); + + if (currTar_Info->TarEEValue & EE_WIDE_SCSI) + width = SM16BIT; + else + width = SM8BIT; + + FPT_siwidr(port,width); + + currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED); + } } + /*--------------------------------------------------------------------- * * Function: FPT_siwidr @@ -3524,26 +4109,27 @@ static void FPT_stwidn(unsigned long port, unsigned char p_card) * Description: Answer the targets Wide nego message. * *---------------------------------------------------------------------*/ -static void FPT_siwidr(unsigned long port, unsigned char width) +static void FPT_siwidr(ULONG port, UCHAR width) { - ARAM_ACCESS(port); - WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT)); - WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02)); - WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR)); - WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP)); - WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width)); - WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP)); - SGRAM_ACCESS(port); + ARAM_ACCESS(port); + WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT )); + WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 )); + WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR)); + WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP )); + WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width)); + WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP )); + SGRAM_ACCESS(port); - WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); - WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1); + WR_HARPOON(port+hp_portctrl_0, SCSI_PORT); + WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1); - WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT)); + WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT)); - while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) { - } + while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {} } + + /*--------------------------------------------------------------------- * * Function: FPT_sssyncv @@ -3552,71 +4138,71 @@ static void FPT_siwidr(unsigned long port, unsigned char width) * ID specified. * *---------------------------------------------------------------------*/ -static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, - unsigned char p_sync_value, - struct sccb_mgr_tar_info *currTar_Info) +static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value, + PSCCBMgr_tar_info currTar_Info) { - unsigned char index; - - index = p_id; - - switch (index) { - - case 0: - index = 12; /* hp_synctarg_0 */ - break; - case 1: - index = 13; /* hp_synctarg_1 */ - break; - case 2: - index = 14; /* hp_synctarg_2 */ - break; - case 3: - index = 15; /* hp_synctarg_3 */ - break; - case 4: - index = 8; /* hp_synctarg_4 */ - break; - case 5: - index = 9; /* hp_synctarg_5 */ - break; - case 6: - index = 10; /* hp_synctarg_6 */ - break; - case 7: - index = 11; /* hp_synctarg_7 */ - break; - case 8: - index = 4; /* hp_synctarg_8 */ - break; - case 9: - index = 5; /* hp_synctarg_9 */ - break; - case 10: - index = 6; /* hp_synctarg_10 */ - break; - case 11: - index = 7; /* hp_synctarg_11 */ - break; - case 12: - index = 0; /* hp_synctarg_12 */ - break; - case 13: - index = 1; /* hp_synctarg_13 */ - break; - case 14: - index = 2; /* hp_synctarg_14 */ - break; - case 15: - index = 3; /* hp_synctarg_15 */ + UCHAR index; + + index = p_id; + + switch (index) { + + case 0: + index = 12; /* hp_synctarg_0 */ + break; + case 1: + index = 13; /* hp_synctarg_1 */ + break; + case 2: + index = 14; /* hp_synctarg_2 */ + break; + case 3: + index = 15; /* hp_synctarg_3 */ + break; + case 4: + index = 8; /* hp_synctarg_4 */ + break; + case 5: + index = 9; /* hp_synctarg_5 */ + break; + case 6: + index = 10; /* hp_synctarg_6 */ + break; + case 7: + index = 11; /* hp_synctarg_7 */ + break; + case 8: + index = 4; /* hp_synctarg_8 */ + break; + case 9: + index = 5; /* hp_synctarg_9 */ + break; + case 10: + index = 6; /* hp_synctarg_10 */ + break; + case 11: + index = 7; /* hp_synctarg_11 */ + break; + case 12: + index = 0; /* hp_synctarg_12 */ + break; + case 13: + index = 1; /* hp_synctarg_13 */ + break; + case 14: + index = 2; /* hp_synctarg_14 */ + break; + case 15: + index = 3; /* hp_synctarg_15 */ - } + } - WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value); + WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value); currTar_Info->TarSyncCtrl = p_sync_value; } + /*--------------------------------------------------------------------- * * Function: FPT_sresb @@ -3624,67 +4210,69 @@ static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, * Description: Reset the desired card's SCSI bus. * *---------------------------------------------------------------------*/ -static void FPT_sresb(unsigned long port, unsigned char p_card) +static void FPT_sresb(ULONG port, UCHAR p_card) { - unsigned char scsiID, i; + UCHAR scsiID, i; - struct sccb_mgr_tar_info *currTar_Info; + PSCCBMgr_tar_info currTar_Info; - WR_HARPOON(port + hp_page_ctrl, - (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE)); - WRW_HARPOON((port + hp_intstat), CLR_ALL_INT); + WR_HARPOON(port+hp_page_ctrl, + (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE)); + WRW_HARPOON((port+hp_intstat), CLR_ALL_INT); - WR_HARPOON(port + hp_scsictrl_0, SCSI_RST); + WR_HARPOON(port+hp_scsictrl_0, SCSI_RST); - scsiID = RD_HARPOON(port + hp_seltimeout); - WR_HARPOON(port + hp_seltimeout, TO_5ms); - WRW_HARPOON((port + hp_intstat), TIMEOUT); + scsiID = RD_HARPOON(port+hp_seltimeout); + WR_HARPOON(port+hp_seltimeout,TO_5ms); + WRW_HARPOON((port+hp_intstat), TIMEOUT); - WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO)); + WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO)); - while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) { - } + while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {} - WR_HARPOON(port + hp_seltimeout, scsiID); + WR_HARPOON(port+hp_seltimeout,scsiID); - WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL); + WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL); - FPT_Wait(port, TO_5ms); + FPT_Wait(port, TO_5ms); - WRW_HARPOON((port + hp_intstat), CLR_ALL_INT); + WRW_HARPOON((port+hp_intstat), CLR_ALL_INT); - WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00)); + WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00)); - for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) { - currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID]; + for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) + { + currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID]; - if (currTar_Info->TarEEValue & EE_SYNC_MASK) { - currTar_Info->TarSyncCtrl = 0; - currTar_Info->TarStatus &= ~TAR_SYNC_MASK; - } + if (currTar_Info->TarEEValue & EE_SYNC_MASK) + { + currTar_Info->TarSyncCtrl = 0; + currTar_Info->TarStatus &= ~TAR_SYNC_MASK; + } - if (currTar_Info->TarEEValue & EE_WIDE_SCSI) { - currTar_Info->TarStatus &= ~TAR_WIDE_MASK; - } + if (currTar_Info->TarEEValue & EE_WIDE_SCSI) + { + currTar_Info->TarStatus &= ~TAR_WIDE_MASK; + } - FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info); + FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info); - FPT_SccbMgrTableInitTarget(p_card, scsiID); - } + FPT_SccbMgrTableInitTarget(p_card, scsiID); + } - FPT_BL_Card[p_card].scanIndex = 0x00; - FPT_BL_Card[p_card].currentSCCB = NULL; - FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT - | F_NEW_SCCB_CMD); - FPT_BL_Card[p_card].cmdCounter = 0x00; + FPT_BL_Card[p_card].scanIndex = 0x00; + FPT_BL_Card[p_card].currentSCCB = NULL; + FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT + | F_NEW_SCCB_CMD); + FPT_BL_Card[p_card].cmdCounter = 0x00; FPT_BL_Card[p_card].discQCount = 0x00; - FPT_BL_Card[p_card].tagQ_Lst = 0x01; + FPT_BL_Card[p_card].tagQ_Lst = 0x01; - for (i = 0; i < QUEUE_DEPTH; i++) + for(i = 0; i < QUEUE_DEPTH; i++) FPT_BL_Card[p_card].discQ_Tbl[i] = NULL; - WR_HARPOON(port + hp_page_ctrl, - (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE)); + WR_HARPOON(port+hp_page_ctrl, + (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE)); } @@ -3695,43 +4283,46 @@ static void FPT_sresb(unsigned long port, unsigned char p_card) * Description: Setup for the Auto Sense command. * *---------------------------------------------------------------------*/ -static void FPT_ssenss(struct sccb_card *pCurrCard) +static void FPT_ssenss(PSCCBcard pCurrCard) { - unsigned char i; - struct sccb *currSCCB; + UCHAR i; + PSCCB currSCCB; - currSCCB = pCurrCard->currentSCCB; + currSCCB = pCurrCard->currentSCCB; - currSCCB->Save_CdbLen = currSCCB->CdbLength; - for (i = 0; i < 6; i++) { + currSCCB->Save_CdbLen = currSCCB->CdbLength; - currSCCB->Save_Cdb[i] = currSCCB->Cdb[i]; - } + for (i = 0; i < 6; i++) { + + currSCCB->Save_Cdb[i] = currSCCB->Cdb[i]; + } - currSCCB->CdbLength = SIX_BYTE_CMD; - currSCCB->Cdb[0] = SCSI_REQUEST_SENSE; - currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */ - currSCCB->Cdb[2] = 0x00; - currSCCB->Cdb[3] = 0x00; - currSCCB->Cdb[4] = currSCCB->RequestSenseLength; - currSCCB->Cdb[5] = 0x00; + currSCCB->CdbLength = SIX_BYTE_CMD; + currSCCB->Cdb[0] = SCSI_REQUEST_SENSE; + currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */ + currSCCB->Cdb[2] = 0x00; + currSCCB->Cdb[3] = 0x00; + currSCCB->Cdb[4] = currSCCB->RequestSenseLength; + currSCCB->Cdb[5] = 0x00; - currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength; + currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength; - currSCCB->Sccb_ATC = 0x00; + currSCCB->Sccb_ATC = 0x00; - currSCCB->Sccb_XferState |= F_AUTO_SENSE; + currSCCB->Sccb_XferState |= F_AUTO_SENSE; - currSCCB->Sccb_XferState &= ~F_SG_XFER; + currSCCB->Sccb_XferState &= ~F_SG_XFER; - currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV; + currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV; - currSCCB->ControlByte = 0x00; + currSCCB->ControlByte = 0x00; - currSCCB->Sccb_MGRFlags &= F_STATUSLOADED; + currSCCB->Sccb_MGRFlags &= F_STATUSLOADED; } + + /*--------------------------------------------------------------------- * * Function: FPT_sxfrp @@ -3741,79 +4332,79 @@ static void FPT_ssenss(struct sccb_card *pCurrCard) * *---------------------------------------------------------------------*/ -static void FPT_sxfrp(unsigned long p_port, unsigned char p_card) +static void FPT_sxfrp(ULONG p_port, UCHAR p_card) { - unsigned char curr_phz; - - DISABLE_AUTO(p_port); - - if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) { - - FPT_hostDataXferAbort(p_port, p_card, - FPT_BL_Card[p_card].currentSCCB); + UCHAR curr_phz; - } - /* If the Automation handled the end of the transfer then do not - match the phase or we will get out of sync with the ISR. */ + DISABLE_AUTO(p_port); - if (RDW_HARPOON((p_port + hp_intstat)) & - (BUS_FREE | XFER_CNT_0 | AUTO_INT)) - return; + if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) { - WR_HARPOON(p_port + hp_xfercnt_0, 0x00); + FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB); - curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ; + } - WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0); + /* If the Automation handled the end of the transfer then do not + match the phase or we will get out of sync with the ISR. */ - WR_HARPOON(p_port + hp_scsisig, curr_phz); + if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT)) + return; - while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) && - (curr_phz == - (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ))) - { - if (curr_phz & (unsigned char)SCSI_IOBIT) { - WR_HARPOON(p_port + hp_portctrl_0, - (SCSI_PORT | HOST_PORT | SCSI_INBIT)); + WR_HARPOON(p_port+hp_xfercnt_0, 0x00); - if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) { - RD_HARPOON(p_port + hp_fifodata_0); - } - } else { - WR_HARPOON(p_port + hp_portctrl_0, - (SCSI_PORT | HOST_PORT | HOST_WRT)); - if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) { - WR_HARPOON(p_port + hp_fifodata_0, 0xFA); - } - } - } /* End of While loop for padding data I/O phase */ + curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ; - while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) { - if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) - break; - } + WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0); - WR_HARPOON(p_port + hp_portctrl_0, - (SCSI_PORT | HOST_PORT | SCSI_INBIT)); - while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) { - RD_HARPOON(p_port + hp_fifodata_0); - } - if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) { - WR_HARPOON(p_port + hp_autostart_0, - (AUTO_IMMED + DISCONNECT_START)); - while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) { - } + WR_HARPOON(p_port+hp_scsisig, curr_phz); - if (RDW_HARPOON((p_port + hp_intstat)) & - (ICMD_COMP | ITAR_DISC)) - while (! - (RDW_HARPOON((p_port + hp_intstat)) & - (BUS_FREE | RSEL))) ; - } + while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) && + (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) ) + { + if (curr_phz & (UCHAR)SCSI_IOBIT) + { + WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT)); + + if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)) + { + RD_HARPOON(p_port+hp_fifodata_0); + } + } + else + { + WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT)); + if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY) + { + WR_HARPOON(p_port+hp_fifodata_0,0xFA); + } + } + } /* End of While loop for padding data I/O phase */ + + while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET))) + { + if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ) + break; + } + + WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT)); + while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)) + { + RD_HARPOON(p_port+hp_fifodata_0); + } + + if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET))) + { + WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START)); + while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {} + + if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC)) + while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ; + } } + /*--------------------------------------------------------------------- * * Function: FPT_schkdd @@ -3823,99 +4414,111 @@ static void FPT_sxfrp(unsigned long p_port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_schkdd(unsigned long port, unsigned char p_card) +static void FPT_schkdd(ULONG port, UCHAR p_card) { - unsigned short TimeOutLoop; - unsigned char sPhase; + USHORT TimeOutLoop; + UCHAR sPhase; - struct sccb *currSCCB; + PSCCB currSCCB; - currSCCB = FPT_BL_Card[p_card].currentSCCB; + currSCCB = FPT_BL_Card[p_card].currentSCCB; - if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) && - (currSCCB->Sccb_scsistat != DATA_IN_ST)) { - return; - } - if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) { + if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) && + (currSCCB->Sccb_scsistat != DATA_IN_ST)) { + return; + } - currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1); - currSCCB->Sccb_XferCnt = 1; - currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT; - WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00); - WR_HARPOON(port + hp_xferstat, 0x00); - } + if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) + { - else { + currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1); - currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt; + currSCCB->Sccb_XferCnt = 1; - currSCCB->Sccb_XferCnt = 0; - } + currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT; + WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00); + WR_HARPOON(port+hp_xferstat, 0x00); + } - if ((RDW_HARPOON((port + hp_intstat)) & PARITY) && - (currSCCB->HostStatus == SCCB_COMPLETE)) { + else + { - currSCCB->HostStatus = SCCB_PARITY_ERR; - WRW_HARPOON((port + hp_intstat), PARITY); - } + currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt; - FPT_hostDataXferAbort(port, p_card, currSCCB); + currSCCB->Sccb_XferCnt = 0; + } - while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) { - } + if ((RDW_HARPOON((port+hp_intstat)) & PARITY) && + (currSCCB->HostStatus == SCCB_COMPLETE)) { - TimeOutLoop = 0; + currSCCB->HostStatus = SCCB_PARITY_ERR; + WRW_HARPOON((port+hp_intstat), PARITY); + } - while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) { - if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) { - return; - } - if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) { - break; - } - if (RDW_HARPOON((port + hp_intstat)) & RESET) { - return; - } - if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ) - || (TimeOutLoop++ > 0x3000)) - break; - } - sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ); - if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) || - (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) || - (sPhase == (SCSI_BSY | S_DATAO_PH)) || - (sPhase == (SCSI_BSY | S_DATAI_PH))) { + FPT_hostDataXferAbort(port,p_card,currSCCB); - WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); - if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) { - if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) { - FPT_phaseDataIn(port, p_card); - } + while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {} - else { - FPT_phaseDataOut(port, p_card); - } - } else { - FPT_sxfrp(port, p_card); - if (!(RDW_HARPOON((port + hp_intstat)) & - (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) { - WRW_HARPOON((port + hp_intstat), AUTO_INT); - FPT_phaseDecode(port, p_card); - } - } + TimeOutLoop = 0; - } + while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY) + { + if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) { + return; + } + if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) { + break; + } + if (RDW_HARPOON((port+hp_intstat)) & RESET) { + return; + } + if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) ) + break; + } - else { - WR_HARPOON(port + hp_portctrl_0, 0x00); - } + sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ); + if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) || + (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) || + (sPhase == (SCSI_BSY | S_DATAO_PH)) || + (sPhase == (SCSI_BSY | S_DATAI_PH))) + { + + WR_HARPOON(port+hp_portctrl_0, SCSI_PORT); + + if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) + { + if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) { + FPT_phaseDataIn(port,p_card); + } + + else { + FPT_phaseDataOut(port,p_card); + } + } + else + { + FPT_sxfrp(port,p_card); + if (!(RDW_HARPOON((port+hp_intstat)) & + (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) + { + WRW_HARPOON((port+hp_intstat), AUTO_INT); + FPT_phaseDecode(port,p_card); + } + } + + } + + else { + WR_HARPOON(port+hp_portctrl_0, 0x00); + } } + /*--------------------------------------------------------------------- * * Function: FPT_sinits @@ -3924,37 +4527,39 @@ static void FPT_schkdd(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card) +static void FPT_sinits(PSCCB p_sccb, UCHAR p_card) { - struct sccb_mgr_tar_info *currTar_Info; + PSCCBMgr_tar_info currTar_Info; - if ((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN)) { + if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN)) + { return; } - currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; + currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; - p_sccb->Sccb_XferState = 0x00; - p_sccb->Sccb_XferCnt = p_sccb->DataLength; + p_sccb->Sccb_XferState = 0x00; + p_sccb->Sccb_XferCnt = p_sccb->DataLength; - if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) || - (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) { + if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) || + (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) { - p_sccb->Sccb_SGoffset = 0; - p_sccb->Sccb_XferState = F_SG_XFER; - p_sccb->Sccb_XferCnt = 0x00; - } + p_sccb->Sccb_SGoffset = 0; + p_sccb->Sccb_XferState = F_SG_XFER; + p_sccb->Sccb_XferCnt = 0x00; + } - if (p_sccb->DataLength == 0x00) + if (p_sccb->DataLength == 0x00) - p_sccb->Sccb_XferState |= F_ALL_XFERRED; + p_sccb->Sccb_XferState |= F_ALL_XFERRED; - if (p_sccb->ControlByte & F_USE_CMD_Q) { - if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT) - p_sccb->ControlByte &= ~F_USE_CMD_Q; + if (p_sccb->ControlByte & F_USE_CMD_Q) + { + if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT) + p_sccb->ControlByte &= ~F_USE_CMD_Q; - else - currTar_Info->TarStatus |= TAG_Q_TRYING; - } + else + currTar_Info->TarStatus |= TAG_Q_TRYING; + } /* For !single SCSI device in system & device allow Disconnect or command is tag_q type then send Cmd with Disconnect Enable @@ -3965,35 +4570,35 @@ static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card) (currTar_Info->TarStatus & TAR_ALLOW_DISC)) || (currTar_Info->TarStatus & TAG_Q_TRYING)) { */ - if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) || - (currTar_Info->TarStatus & TAG_Q_TRYING)) { - p_sccb->Sccb_idmsg = - (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun; - } + if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) || + (currTar_Info->TarStatus & TAG_Q_TRYING)) { + p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun; + } - else { + else { - p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun; - } + p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun; + } - p_sccb->HostStatus = 0x00; - p_sccb->TargetStatus = 0x00; - p_sccb->Sccb_tag = 0x00; - p_sccb->Sccb_MGRFlags = 0x00; - p_sccb->Sccb_sgseg = 0x00; - p_sccb->Sccb_ATC = 0x00; - p_sccb->Sccb_savedATC = 0x00; + p_sccb->HostStatus = 0x00; + p_sccb->TargetStatus = 0x00; + p_sccb->Sccb_tag = 0x00; + p_sccb->Sccb_MGRFlags = 0x00; + p_sccb->Sccb_sgseg = 0x00; + p_sccb->Sccb_ATC = 0x00; + p_sccb->Sccb_savedATC = 0x00; /* p_sccb->SccbVirtDataPtr = 0x00; p_sccb->Sccb_forwardlink = NULL; p_sccb->Sccb_backlink = NULL; */ - p_sccb->Sccb_scsistat = BUS_FREE_ST; - p_sccb->SccbStatus = SCCB_IN_PROCESS; - p_sccb->Sccb_scsimsg = SMNO_OP; + p_sccb->Sccb_scsistat = BUS_FREE_ST; + p_sccb->SccbStatus = SCCB_IN_PROCESS; + p_sccb->Sccb_scsimsg = SMNO_OP; } + /*--------------------------------------------------------------------- * * Function: Phase Decode @@ -4002,21 +4607,23 @@ static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card) +static void FPT_phaseDecode(ULONG p_port, UCHAR p_card) { - unsigned char phase_ref; - void (*phase) (unsigned long, unsigned char); + unsigned char phase_ref; + void (*phase) (ULONG, UCHAR); + - DISABLE_AUTO(p_port); + DISABLE_AUTO(p_port); - phase_ref = - (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ); + phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ); - phase = FPT_s_PhaseTbl[phase_ref]; + phase = FPT_s_PhaseTbl[phase_ref]; - (*phase) (p_port, p_card); /* Call the correct phase func */ + (*phase)(p_port, p_card); /* Call the correct phase func */ } + + /*--------------------------------------------------------------------- * * Function: Data Out Phase @@ -4025,39 +4632,42 @@ static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseDataOut(unsigned long port, unsigned char p_card) +static void FPT_phaseDataOut(ULONG port, UCHAR p_card) { - struct sccb *currSCCB; + PSCCB currSCCB; - currSCCB = FPT_BL_Card[p_card].currentSCCB; - if (currSCCB == NULL) { - return; /* Exit if No SCCB record */ - } + currSCCB = FPT_BL_Card[p_card].currentSCCB; + if (currSCCB == NULL) + { + return; /* Exit if No SCCB record */ + } - currSCCB->Sccb_scsistat = DATA_OUT_ST; - currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET); + currSCCB->Sccb_scsistat = DATA_OUT_ST; + currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET); - WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); + WR_HARPOON(port+hp_portctrl_0, SCSI_PORT); - WRW_HARPOON((port + hp_intstat), XFER_CNT_0); + WRW_HARPOON((port+hp_intstat), XFER_CNT_0); - WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START)); + WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START)); - FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); + FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); - if (currSCCB->Sccb_XferCnt == 0) { + if (currSCCB->Sccb_XferCnt == 0) { - if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) && - (currSCCB->HostStatus == SCCB_COMPLETE)) - currSCCB->HostStatus = SCCB_DATA_OVER_RUN; - FPT_sxfrp(port, p_card); - if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET))) - FPT_phaseDecode(port, p_card); - } + if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) && + (currSCCB->HostStatus == SCCB_COMPLETE)) + currSCCB->HostStatus = SCCB_DATA_OVER_RUN; + + FPT_sxfrp(port,p_card); + if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET))) + FPT_phaseDecode(port,p_card); + } } + /*--------------------------------------------------------------------- * * Function: Data In Phase @@ -4066,40 +4676,43 @@ static void FPT_phaseDataOut(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseDataIn(unsigned long port, unsigned char p_card) +static void FPT_phaseDataIn(ULONG port, UCHAR p_card) { - struct sccb *currSCCB; + PSCCB currSCCB; - currSCCB = FPT_BL_Card[p_card].currentSCCB; + currSCCB = FPT_BL_Card[p_card].currentSCCB; - if (currSCCB == NULL) { - return; /* Exit if No SCCB record */ - } + if (currSCCB == NULL) + { + return; /* Exit if No SCCB record */ + } - currSCCB->Sccb_scsistat = DATA_IN_ST; - currSCCB->Sccb_XferState |= F_HOST_XFER_DIR; - currSCCB->Sccb_XferState &= ~F_NO_DATA_YET; - WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); + currSCCB->Sccb_scsistat = DATA_IN_ST; + currSCCB->Sccb_XferState |= F_HOST_XFER_DIR; + currSCCB->Sccb_XferState &= ~F_NO_DATA_YET; - WRW_HARPOON((port + hp_intstat), XFER_CNT_0); + WR_HARPOON(port+hp_portctrl_0, SCSI_PORT); - WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START)); + WRW_HARPOON((port+hp_intstat), XFER_CNT_0); - FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); + WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START)); - if (currSCCB->Sccb_XferCnt == 0) { + FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); - if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) && - (currSCCB->HostStatus == SCCB_COMPLETE)) - currSCCB->HostStatus = SCCB_DATA_OVER_RUN; + if (currSCCB->Sccb_XferCnt == 0) { - FPT_sxfrp(port, p_card); - if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET))) - FPT_phaseDecode(port, p_card); - } + if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) && + (currSCCB->HostStatus == SCCB_COMPLETE)) + currSCCB->HostStatus = SCCB_DATA_OVER_RUN; + + FPT_sxfrp(port,p_card); + if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET))) + FPT_phaseDecode(port,p_card); + + } } /*--------------------------------------------------------------------- @@ -4110,49 +4723,50 @@ static void FPT_phaseDataIn(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card) +static void FPT_phaseCommand(ULONG p_port, UCHAR p_card) { - struct sccb *currSCCB; - unsigned long cdb_reg; - unsigned char i; + PSCCB currSCCB; + ULONG cdb_reg; + UCHAR i; - currSCCB = FPT_BL_Card[p_card].currentSCCB; + currSCCB = FPT_BL_Card[p_card].currentSCCB; - if (currSCCB->OperationCode == RESET_COMMAND) { + if (currSCCB->OperationCode == RESET_COMMAND) { - currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; - currSCCB->CdbLength = SIX_BYTE_CMD; - } + currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; + currSCCB->CdbLength = SIX_BYTE_CMD; + } - WR_HARPOON(p_port + hp_scsisig, 0x00); + WR_HARPOON(p_port+hp_scsisig, 0x00); - ARAM_ACCESS(p_port); + ARAM_ACCESS(p_port); - cdb_reg = p_port + CMD_STRT; - for (i = 0; i < currSCCB->CdbLength; i++) { + cdb_reg = p_port + CMD_STRT; - if (currSCCB->OperationCode == RESET_COMMAND) + for (i=0; i < currSCCB->CdbLength; i++) { - WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00)); + if (currSCCB->OperationCode == RESET_COMMAND) - else - WRW_HARPOON(cdb_reg, - (MPM_OP + ACOMMAND + currSCCB->Cdb[i])); - cdb_reg += 2; - } + WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00)); - if (currSCCB->CdbLength != TWELVE_BYTE_CMD) - WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP)); + else + WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i])); + cdb_reg +=2; + } + + if (currSCCB->CdbLength != TWELVE_BYTE_CMD) + WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP)); - WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT)); + WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT)); - currSCCB->Sccb_scsistat = COMMAND_ST; + currSCCB->Sccb_scsistat = COMMAND_ST; - WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT)); - SGRAM_ACCESS(p_port); + WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT)); + SGRAM_ACCESS(p_port); } + /*--------------------------------------------------------------------- * * Function: Status phase @@ -4161,18 +4775,19 @@ static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseStatus(unsigned long port, unsigned char p_card) +static void FPT_phaseStatus(ULONG port, UCHAR p_card) { - /* Start-up the automation to finish off this command and let the - isr handle the interrupt for command complete when it comes in. - We could wait here for the interrupt to be generated? - */ + /* Start-up the automation to finish off this command and let the + isr handle the interrupt for command complete when it comes in. + We could wait here for the interrupt to be generated? + */ - WR_HARPOON(port + hp_scsisig, 0x00); + WR_HARPOON(port+hp_scsisig, 0x00); - WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START)); + WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START)); } + /*--------------------------------------------------------------------- * * Function: Phase Message Out @@ -4182,11 +4797,11 @@ static void FPT_phaseStatus(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card) +static void FPT_phaseMsgOut(ULONG port, UCHAR p_card) { - unsigned char message, scsiID; - struct sccb *currSCCB; - struct sccb_mgr_tar_info *currTar_Info; + UCHAR message,scsiID; + PSCCB currSCCB; + PSCCBMgr_tar_info currTar_Info; currSCCB = FPT_BL_Card[p_card].currentSCCB; @@ -4195,124 +4810,133 @@ static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card) message = currSCCB->Sccb_scsimsg; scsiID = currSCCB->TargID; - if (message == SMDEV_RESET) { + if (message == SMDEV_RESET) + { + currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID]; currTar_Info->TarSyncCtrl = 0; - FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info); + FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info); - if (FPT_sccbMgrTbl[p_card][scsiID]. - TarEEValue & EE_SYNC_MASK) { + if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK) + { - FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= - ~TAR_SYNC_MASK; + FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK; } - if (FPT_sccbMgrTbl[p_card][scsiID]. - TarEEValue & EE_WIDE_SCSI) { + if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI) + { - FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= - ~TAR_WIDE_MASK; + FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK; } - FPT_queueFlushSccb(p_card, SCCB_COMPLETE); - FPT_SccbMgrTableInitTarget(p_card, scsiID); - } else if (currSCCB->Sccb_scsistat == ABORT_ST) { + + FPT_queueFlushSccb(p_card,SCCB_COMPLETE); + FPT_SccbMgrTableInitTarget(p_card,scsiID); + } + else if (currSCCB->Sccb_scsistat == ABORT_ST) + { currSCCB->HostStatus = SCCB_COMPLETE; - if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != - NULL) { - FPT_BL_Card[p_card].discQ_Tbl[currSCCB-> - Sccb_tag] = NULL; + if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL) + { + FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--; } - + } - else if (currSCCB->Sccb_scsistat < COMMAND_ST) { + else if (currSCCB->Sccb_scsistat < COMMAND_ST) + { - if (message == SMNO_OP) { - currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED; - FPT_ssel(port, p_card); + if(message == SMNO_OP) + { + currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED; + + FPT_ssel(port,p_card); return; } - } else { + } + else + { + if (message == SMABORT) - FPT_queueFlushSccb(p_card, SCCB_COMPLETE); + FPT_queueFlushSccb(p_card,SCCB_COMPLETE); } - } else { + } + else + { message = SMABORT; } - WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0)); + WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0)); + - WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN); + WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN); - WR_HARPOON(port + hp_scsidata_0, message); + WR_HARPOON(port+hp_scsidata_0,message); - WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); + WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); ACCEPT_MSG(port); - WR_HARPOON(port + hp_portctrl_0, 0x00); + WR_HARPOON(port+hp_portctrl_0, 0x00); - if ((message == SMABORT) || (message == SMDEV_RESET) || - (message == SMABORT_TAG)) { + if ((message == SMABORT) || (message == SMDEV_RESET) || + (message == SMABORT_TAG) ) + { - while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) { - } + while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {} - if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) { - WRW_HARPOON((port + hp_intstat), BUS_FREE); + if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) + { + WRW_HARPOON((port+hp_intstat), BUS_FREE); - if (currSCCB != NULL) { + if (currSCCB != NULL) + { - if ((FPT_BL_Card[p_card]. - globalFlags & F_CONLUN_IO) - && - ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & TAR_TAG_Q_MASK) != - TAG_Q_TRYING)) - FPT_sccbMgrTbl[p_card][currSCCB-> - TargID]. - TarLUNBusy[currSCCB->Lun] = 0; + if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0; else - FPT_sccbMgrTbl[p_card][currSCCB-> - TargID]. - TarLUNBusy[0] = 0; + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0; - FPT_queueCmdComplete(&FPT_BL_Card[p_card], - currSCCB, p_card); + FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card); } - else { - FPT_BL_Card[p_card].globalFlags |= - F_NEW_SCCB_CMD; + else + { + FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; } } - else { + else + { - FPT_sxfrp(port, p_card); + FPT_sxfrp(port,p_card); } } - else { + else + { - if (message == SMPARITY) { + if(message == SMPARITY) + { currSCCB->Sccb_scsimsg = SMNO_OP; - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); - } else { - FPT_sxfrp(port, p_card); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); + } + else + { + FPT_sxfrp(port,p_card); } } } + /*--------------------------------------------------------------------- * * Function: Message In phase @@ -4321,43 +4945,49 @@ static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card) +static void FPT_phaseMsgIn(ULONG port, UCHAR p_card) { - unsigned char message; - struct sccb *currSCCB; + UCHAR message; + PSCCB currSCCB; currSCCB = FPT_BL_Card[p_card].currentSCCB; - if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) { + if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) + { FPT_phaseChkFifo(port, p_card); } - message = RD_HARPOON(port + hp_scsidata_0); - if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) { + message = RD_HARPOON(port+hp_scsidata_0); + if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) + { - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + END_DATA_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START)); } - else { + else + { - message = FPT_sfm(port, currSCCB); - if (message) { + message = FPT_sfm(port,currSCCB); + if (message) + { - FPT_sdecm(message, port, p_card); - } else { - if (currSCCB->Sccb_scsimsg != SMPARITY) + FPT_sdecm(message,port,p_card); + + } + else + { + if(currSCCB->Sccb_scsimsg != SMPARITY) ACCEPT_MSG(port); - WR_HARPOON(port + hp_autostart_1, - (AUTO_IMMED + DISCONNECT_START)); + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } } } + /*--------------------------------------------------------------------- * * Function: Illegal phase @@ -4368,23 +4998,25 @@ static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseIllegal(unsigned long port, unsigned char p_card) +static void FPT_phaseIllegal(ULONG port, UCHAR p_card) { - struct sccb *currSCCB; + PSCCB currSCCB; - currSCCB = FPT_BL_Card[p_card].currentSCCB; + currSCCB = FPT_BL_Card[p_card].currentSCCB; - WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig)); - if (currSCCB != NULL) { + WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig)); + if (currSCCB != NULL) { - currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; - currSCCB->Sccb_scsistat = ABORT_ST; - currSCCB->Sccb_scsimsg = SMABORT; - } + currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; + currSCCB->Sccb_scsistat = ABORT_ST; + currSCCB->Sccb_scsimsg = SMABORT; + } - ACCEPT_MSG_ATN(port); + ACCEPT_MSG_ATN(port); } + + /*--------------------------------------------------------------------- * * Function: Phase Check FIFO @@ -4394,69 +5026,76 @@ static void FPT_phaseIllegal(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card) +static void FPT_phaseChkFifo(ULONG port, UCHAR p_card) { - unsigned long xfercnt; - struct sccb *currSCCB; + ULONG xfercnt; + PSCCB currSCCB; - currSCCB = FPT_BL_Card[p_card].currentSCCB; + currSCCB = FPT_BL_Card[p_card].currentSCCB; - if (currSCCB->Sccb_scsistat == DATA_IN_ST) { + if (currSCCB->Sccb_scsistat == DATA_IN_ST) + { - while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) && - (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) { - } + while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) && + (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {} - if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) { - currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt; - currSCCB->Sccb_XferCnt = 0; + if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) + { + currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt; - if ((RDW_HARPOON((port + hp_intstat)) & PARITY) && - (currSCCB->HostStatus == SCCB_COMPLETE)) { - currSCCB->HostStatus = SCCB_PARITY_ERR; - WRW_HARPOON((port + hp_intstat), PARITY); - } + currSCCB->Sccb_XferCnt = 0; - FPT_hostDataXferAbort(port, p_card, currSCCB); + if ((RDW_HARPOON((port+hp_intstat)) & PARITY) && + (currSCCB->HostStatus == SCCB_COMPLETE)) + { + currSCCB->HostStatus = SCCB_PARITY_ERR; + WRW_HARPOON((port+hp_intstat), PARITY); + } - FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); + FPT_hostDataXferAbort(port,p_card,currSCCB); - while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) - && (RD_HARPOON(port + hp_ext_status) & - BM_CMD_BUSY)) { - } + FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); - } - } + while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) && + (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {} - /*End Data In specific code. */ - GET_XFER_CNT(port, xfercnt); + } + } /*End Data In specific code. */ - WR_HARPOON(port + hp_xfercnt_0, 0x00); - WR_HARPOON(port + hp_portctrl_0, 0x00); - currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt); + GET_XFER_CNT(port,xfercnt); - currSCCB->Sccb_XferCnt = xfercnt; - if ((RDW_HARPOON((port + hp_intstat)) & PARITY) && - (currSCCB->HostStatus == SCCB_COMPLETE)) { + WR_HARPOON(port+hp_xfercnt_0, 0x00); - currSCCB->HostStatus = SCCB_PARITY_ERR; - WRW_HARPOON((port + hp_intstat), PARITY); - } - FPT_hostDataXferAbort(port, p_card, currSCCB); + WR_HARPOON(port+hp_portctrl_0, 0x00); + + currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt); + + currSCCB->Sccb_XferCnt = xfercnt; + + if ((RDW_HARPOON((port+hp_intstat)) & PARITY) && + (currSCCB->HostStatus == SCCB_COMPLETE)) { + + currSCCB->HostStatus = SCCB_PARITY_ERR; + WRW_HARPOON((port+hp_intstat), PARITY); + } + - WR_HARPOON(port + hp_fifowrite, 0x00); - WR_HARPOON(port + hp_fiforead, 0x00); - WR_HARPOON(port + hp_xferstat, 0x00); + FPT_hostDataXferAbort(port,p_card,currSCCB); - WRW_HARPOON((port + hp_intstat), XFER_CNT_0); + + WR_HARPOON(port+hp_fifowrite, 0x00); + WR_HARPOON(port+hp_fiforead, 0x00); + WR_HARPOON(port+hp_xferstat, 0x00); + + WRW_HARPOON((port+hp_intstat), XFER_CNT_0); } + /*--------------------------------------------------------------------- * * Function: Phase Bus Free @@ -4465,94 +5104,96 @@ static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card) * because of command complete or from a disconnect. * *---------------------------------------------------------------------*/ -static void FPT_phaseBusFree(unsigned long port, unsigned char p_card) +static void FPT_phaseBusFree(ULONG port, UCHAR p_card) { - struct sccb *currSCCB; - - currSCCB = FPT_BL_Card[p_card].currentSCCB; - - if (currSCCB != NULL) { - - DISABLE_AUTO(port); - - if (currSCCB->OperationCode == RESET_COMMAND) { - - if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && - ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[currSCCB->Lun] = 0; - else - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[0] = 0; - - FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, - p_card); + PSCCB currSCCB; - FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card); + currSCCB = FPT_BL_Card[p_card].currentSCCB; - } - - else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= - (unsigned char)SYNC_SUPPORTED; - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= - ~EE_SYNC_MASK; - } + if (currSCCB != NULL) + { - else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) { - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus = - (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED; + DISABLE_AUTO(port); - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= - ~EE_WIDE_SCSI; - } - else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) { - /* Make sure this is not a phony BUS_FREE. If we were - reselected or if BUSY is NOT on then this is a - valid BUS FREE. SRR Wednesday, 5/10/1995. */ - - if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) || - (RDW_HARPOON((port + hp_intstat)) & RSEL)) { - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus &= ~TAR_TAG_Q_MASK; - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus |= TAG_Q_REJECT; - } + if (currSCCB->OperationCode == RESET_COMMAND) + { - else { - return; - } - } + if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0; + else + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0; + + FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card); + + FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card); + + } + + else if(currSCCB->Sccb_scsistat == SELECT_SN_ST) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= + (UCHAR)SYNC_SUPPORTED; + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK; + } + + else if(currSCCB->Sccb_scsistat == SELECT_WN_ST) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus = + (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. + TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED; + + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI; + } + + else if(currSCCB->Sccb_scsistat == SELECT_Q_ST) + { + /* Make sure this is not a phony BUS_FREE. If we were + reselected or if BUSY is NOT on then this is a + valid BUS FREE. SRR Wednesday, 5/10/1995. */ + + if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) || + (RDW_HARPOON((port+hp_intstat)) & RSEL)) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK; + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT; + } + + else + { + return; + } + } + + else + { + + currSCCB->Sccb_scsistat = BUS_FREE_ST; + + if (!currSCCB->HostStatus) + { + currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; + } + + if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0; + else + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0; - else { + FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card); + return; + } - currSCCB->Sccb_scsistat = BUS_FREE_ST; - if (!currSCCB->HostStatus) { - currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; - } + FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; - if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && - ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[currSCCB->Lun] = 0; - else - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[0] = 0; + } /*end if !=null */ +} - FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, - p_card); - return; - } - FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; - } /*end if !=null */ -} /*--------------------------------------------------------------------- * @@ -4561,101 +5202,103 @@ static void FPT_phaseBusFree(unsigned long port, unsigned char p_card) * Description: Load the Automation RAM with the defualt map values. * *---------------------------------------------------------------------*/ -static void FPT_autoLoadDefaultMap(unsigned long p_port) +static void FPT_autoLoadDefaultMap(ULONG p_port) { - unsigned long map_addr; - - ARAM_ACCESS(p_port); - map_addr = p_port + hp_aramBase; - - WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */ - map_addr += 2; - WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */ - map_addr += 2; - WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */ - map_addr += 2; - WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */ - map_addr += 2; - WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */ - map_addr += 2; /*This means AYNC DATA IN */ - WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */ - map_addr += 2; - WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */ - map_addr += 2; - WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */ - map_addr += 2; - WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */ - map_addr += 2; - WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */ - map_addr += 2; - WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */ - map_addr += 2; - WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */ - map_addr += 2; - WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */ - map_addr += 2; - WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */ - map_addr += 2; - WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */ - map_addr += 2; - WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */ - map_addr += 2; - WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */ - map_addr += 2; - WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */ - map_addr += 2; - WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */ - map_addr += 2; - WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */ - map_addr += 2; - WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */ - map_addr += 2; - WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */ - map_addr += 2; - WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */ - map_addr += 2; - - WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */ - map_addr += 2; - WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */ - map_addr += 2; - WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */ - map_addr += 2; - WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */ - map_addr += 2; /* DIDN'T GET ONE */ - WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */ - map_addr += 2; - WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */ - map_addr += 2; - WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */ - - SGRAM_ACCESS(p_port); + ULONG map_addr; + + ARAM_ACCESS(p_port); + map_addr = p_port + hp_aramBase; + + WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */ + map_addr +=2; + WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */ + map_addr +=2; + WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */ + map_addr +=2; + WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */ + map_addr +=2; + WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */ + map_addr +=2; /*This means AYNC DATA IN */ + WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */ + map_addr +=2; + WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */ + map_addr +=2; + WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */ + map_addr +=2; + WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */ + map_addr +=2; + WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */ + map_addr +=2; + WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */ + map_addr +=2; + WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */ + map_addr +=2; + WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */ + map_addr +=2; + WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */ + map_addr +=2; + WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */ + map_addr +=2; + WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */ + map_addr +=2; + WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */ + map_addr +=2; + WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */ + map_addr +=2; + WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */ + map_addr +=2; + WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */ + map_addr +=2; + WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */ + map_addr +=2; + WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */ + map_addr +=2; + WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */ + map_addr +=2; + + WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */ + map_addr +=2; + WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */ + map_addr +=2; + WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */ + map_addr +=2; + WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */ + map_addr +=2; /* DIDN'T GET ONE */ + WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/ + map_addr +=2; + WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */ + map_addr +=2; + WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */ + + + + SGRAM_ACCESS(p_port); } /*--------------------------------------------------------------------- @@ -4667,261 +5310,203 @@ static void FPT_autoLoadDefaultMap(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card) +static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card) { - struct sccb *currSCCB; - unsigned char status_byte; + PSCCB currSCCB; + UCHAR status_byte; - currSCCB = FPT_BL_Card[p_card].currentSCCB; + currSCCB = FPT_BL_Card[p_card].currentSCCB; - status_byte = RD_HARPOON(p_port + hp_gp_reg_0); + status_byte = RD_HARPOON(p_port+hp_gp_reg_0); - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0; + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0; - if (status_byte != SSGOOD) { + if (status_byte != SSGOOD) { - if (status_byte == SSQ_FULL) { + if (status_byte == SSQ_FULL) { - if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && - ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[currSCCB->Lun] = 1; - if (FPT_BL_Card[p_card].discQCount != 0) + + if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1; + if(FPT_BL_Card[p_card].discQCount != 0) FPT_BL_Card[p_card].discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl[FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - LunDiscQ_Idx[currSCCB->Lun]] = - NULL; - } else { - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[0] = 1; - if (currSCCB->Sccb_tag) { - if (FPT_BL_Card[p_card].discQCount != 0) - FPT_BL_Card[p_card]. - discQCount--; - FPT_BL_Card[p_card].discQ_Tbl[currSCCB-> - Sccb_tag] - = NULL; - } else { - if (FPT_BL_Card[p_card].discQCount != 0) - FPT_BL_Card[p_card]. - discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl[FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - LunDiscQ_Idx[0]] = NULL; + FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; + } + else + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1; + if(currSCCB->Sccb_tag) + { + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; + }else + { + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; } } - currSCCB->Sccb_MGRFlags |= F_STATUSLOADED; + currSCCB->Sccb_MGRFlags |= F_STATUSLOADED; - FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card); + FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card); - return; - } + return; + } - if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= - (unsigned char)SYNC_SUPPORTED; + if(currSCCB->Sccb_scsistat == SELECT_SN_ST) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= + (UCHAR)SYNC_SUPPORTED; - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= - ~EE_SYNC_MASK; - FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK; + FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; - if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && - ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[currSCCB->Lun] = 1; - if (FPT_BL_Card[p_card].discQCount != 0) + if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1; + if(FPT_BL_Card[p_card].discQCount != 0) FPT_BL_Card[p_card].discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl[FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - LunDiscQ_Idx[currSCCB->Lun]] = - NULL; - } else { - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[0] = 1; - if (currSCCB->Sccb_tag) { - if (FPT_BL_Card[p_card].discQCount != 0) - FPT_BL_Card[p_card]. - discQCount--; - FPT_BL_Card[p_card].discQ_Tbl[currSCCB-> - Sccb_tag] - = NULL; - } else { - if (FPT_BL_Card[p_card].discQCount != 0) - FPT_BL_Card[p_card]. - discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl[FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - LunDiscQ_Idx[0]] = NULL; + FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; + } + else + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1; + if(currSCCB->Sccb_tag) + { + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; + }else + { + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; } } - return; + return; - } + } - if (currSCCB->Sccb_scsistat == SELECT_WN_ST) { + if(currSCCB->Sccb_scsistat == SELECT_WN_ST) + { - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus = - (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED; + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus = + (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. + TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED; - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= - ~EE_WIDE_SCSI; - FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI; + FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; - if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && - ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[currSCCB->Lun] = 1; - if (FPT_BL_Card[p_card].discQCount != 0) + if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1; + if(FPT_BL_Card[p_card].discQCount != 0) FPT_BL_Card[p_card].discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl[FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - LunDiscQ_Idx[currSCCB->Lun]] = - NULL; - } else { - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUNBusy[0] = 1; - if (currSCCB->Sccb_tag) { - if (FPT_BL_Card[p_card].discQCount != 0) - FPT_BL_Card[p_card]. - discQCount--; - FPT_BL_Card[p_card].discQ_Tbl[currSCCB-> - Sccb_tag] - = NULL; - } else { - if (FPT_BL_Card[p_card].discQCount != 0) - FPT_BL_Card[p_card]. - discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl[FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - LunDiscQ_Idx[0]] = NULL; + FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; + } + else + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1; + if(currSCCB->Sccb_tag) + { + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; + }else + { + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; } } - return; - - } - - if (status_byte == SSCHECK) { - if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) { - if (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarEEValue & EE_SYNC_MASK) { - FPT_sccbMgrTbl[p_card][currSCCB-> - TargID]. - TarStatus &= ~TAR_SYNC_MASK; + return; + + } + + if (status_byte == SSCHECK) + { + if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) + { + if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK; } - if (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarEEValue & EE_WIDE_SCSI) { - FPT_sccbMgrTbl[p_card][currSCCB-> - TargID]. - TarStatus &= ~TAR_WIDE_MASK; + if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK; } } } - if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) { - - currSCCB->SccbStatus = SCCB_ERROR; - currSCCB->TargetStatus = status_byte; - - if (status_byte == SSCHECK) { - - FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarLUN_CA = 1; - - if (currSCCB->RequestSenseLength != - NO_AUTO_REQUEST_SENSE) { - - if (currSCCB->RequestSenseLength == 0) - currSCCB->RequestSenseLength = - 14; - - FPT_ssenss(&FPT_BL_Card[p_card]); - FPT_BL_Card[p_card].globalFlags |= - F_NEW_SCCB_CMD; - - if (((FPT_BL_Card[p_card]. - globalFlags & F_CONLUN_IO) - && - ((FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - TarStatus & TAR_TAG_Q_MASK) != - TAG_Q_TRYING))) { - FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - TarLUNBusy[currSCCB->Lun] = - 1; - if (FPT_BL_Card[p_card]. - discQCount != 0) - FPT_BL_Card[p_card]. - discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl[FPT_sccbMgrTbl - [p_card] - [currSCCB-> - TargID]. - LunDiscQ_Idx - [currSCCB->Lun]] = - NULL; - } else { - FPT_sccbMgrTbl[p_card] - [currSCCB->TargID]. - TarLUNBusy[0] = 1; - if (currSCCB->Sccb_tag) { - if (FPT_BL_Card[p_card]. - discQCount != 0) - FPT_BL_Card - [p_card]. - discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl[currSCCB-> - Sccb_tag] - = NULL; - } else { - if (FPT_BL_Card[p_card]. - discQCount != 0) - FPT_BL_Card - [p_card]. - discQCount--; - FPT_BL_Card[p_card]. - discQ_Tbl - [FPT_sccbMgrTbl - [p_card][currSCCB-> - TargID]. - LunDiscQ_Idx[0]] = - NULL; + if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) { + + currSCCB->SccbStatus = SCCB_ERROR; + currSCCB->TargetStatus = status_byte; + + if (status_byte == SSCHECK) { + + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA + = 1; + + + if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) { + + if (currSCCB->RequestSenseLength == 0) + currSCCB->RequestSenseLength = 14; + + FPT_ssenss(&FPT_BL_Card[p_card]); + FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; + + if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1; + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; + } + else + { + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1; + if(currSCCB->Sccb_tag) + { + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; + }else + { + if(FPT_BL_Card[p_card].discQCount != 0) + FPT_BL_Card[p_card].discQCount--; + FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; } } - return; - } - } - } - } + return; + } + } + } + } + - if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && - ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. - TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB-> - Lun] = 0; + if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0; else - FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0; + FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0; + - FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card); + FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card); } #define SHORT_WAIT 0x0000000F #define LONG_WAIT 0x0000FFFFL + /*--------------------------------------------------------------------- * * Function: Data Transfer Processor @@ -4940,33 +5525,37 @@ static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_dataXferProcessor(unsigned long port, - struct sccb_card *pCurrCard) +static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard) { - struct sccb *currSCCB; - - currSCCB = pCurrCard->currentSCCB; + PSCCB currSCCB; - if (currSCCB->Sccb_XferState & F_SG_XFER) { - if (pCurrCard->globalFlags & F_HOST_XFER_ACT) - { - currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT; - currSCCB->Sccb_SGoffset = 0x00; - } - pCurrCard->globalFlags |= F_HOST_XFER_ACT; + currSCCB = pCurrCard->currentSCCB; - FPT_busMstrSGDataXferStart(port, currSCCB); - } + if (currSCCB->Sccb_XferState & F_SG_XFER) + { + if (pCurrCard->globalFlags & F_HOST_XFER_ACT) - else { - if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) { + { + currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT; + currSCCB->Sccb_SGoffset = 0x00; + } pCurrCard->globalFlags |= F_HOST_XFER_ACT; + + FPT_busMstrSGDataXferStart(port, currSCCB); + } - FPT_busMstrDataXferStart(port, currSCCB); - } - } + else + { + if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) + { + pCurrCard->globalFlags |= F_HOST_XFER_ACT; + + FPT_busMstrDataXferStart(port, currSCCB); + } + } } + /*--------------------------------------------------------------------- * * Function: BusMaster Scatter Gather Data Transfer Start @@ -4974,101 +5563,104 @@ static void FPT_dataXferProcessor(unsigned long port, * Description: * *---------------------------------------------------------------------*/ -static void FPT_busMstrSGDataXferStart(unsigned long p_port, - struct sccb *pcurrSCCB) +static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB) { - unsigned long count, addr, tmpSGCnt; - unsigned int sg_index; - unsigned char sg_count, i; - unsigned long reg_offset; + ULONG count,addr,tmpSGCnt; + UINT sg_index; + UCHAR sg_count, i; + ULONG reg_offset; - if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { - count = ((unsigned long)HOST_RD_CMD) << 24; - } + if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { - else { - count = ((unsigned long)HOST_WRT_CMD) << 24; - } + count = ((ULONG) HOST_RD_CMD)<<24; + } - sg_count = 0; - tmpSGCnt = 0; - sg_index = pcurrSCCB->Sccb_sgseg; - reg_offset = hp_aramBase; + else { + count = ((ULONG) HOST_WRT_CMD)<<24; + } - i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) & - ~(SGRAM_ARAM | SCATTER_EN)); + sg_count = 0; + tmpSGCnt = 0; + sg_index = pcurrSCCB->Sccb_sgseg; + reg_offset = hp_aramBase; - WR_HARPOON(p_port + hp_page_ctrl, i); - while ((sg_count < (unsigned char)SG_BUF_CNT) && - ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < - pcurrSCCB->DataLength)) { + i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN)); - tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer) + - (sg_index * 2)); - count |= *(((unsigned long *)pcurrSCCB->DataPointer) + - (sg_index * 2)); + WR_HARPOON(p_port+hp_page_ctrl, i); - addr = *(((unsigned long *)pcurrSCCB->DataPointer) + - ((sg_index * 2) + 1)); + while ((sg_count < (UCHAR)SG_BUF_CNT) && + ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) { - if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) { + tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+ + (sg_index * 2)); - addr += - ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset); - count = - (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset; + count |= *(((ULONG *)pcurrSCCB->DataPointer)+ + (sg_index * 2)); - tmpSGCnt = count & 0x00FFFFFFL; - } + addr = *(((ULONG *)pcurrSCCB->DataPointer)+ + ((sg_index * 2) + 1)); - WR_HARP32(p_port, reg_offset, addr); - reg_offset += 4; - WR_HARP32(p_port, reg_offset, count); - reg_offset += 4; + if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) { - count &= 0xFF000000L; - sg_index++; - sg_count++; + addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset); + count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset; - } /*End While */ + tmpSGCnt = count & 0x00FFFFFFL; + } - pcurrSCCB->Sccb_XferCnt = tmpSGCnt; + WR_HARP32(p_port,reg_offset,addr); + reg_offset +=4; - WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4)); + WR_HARP32(p_port,reg_offset,count); + reg_offset +=4; - if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { + count &= 0xFF000000L; + sg_index++; + sg_count++; - WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt); + } /*End While */ - WR_HARPOON(p_port + hp_portctrl_0, - (DMA_PORT | SCSI_PORT | SCSI_INBIT)); - WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH); - } + pcurrSCCB->Sccb_XferCnt = tmpSGCnt; - else { + WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4)); - if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) && - (tmpSGCnt & 0x000000001)) { + if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { - pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT; - tmpSGCnt--; - } + WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt); - WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt); - WR_HARPOON(p_port + hp_portctrl_0, - (SCSI_PORT | DMA_PORT | DMA_RD)); - WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH); - } + WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT)); + WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH); + } + + else { + + + if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) && + (tmpSGCnt & 0x000000001)) + { + + pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT; + tmpSGCnt--; + } + - WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN)); + WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt); + + WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD)); + WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH); + } + + + WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN)); } + /*--------------------------------------------------------------------- * * Function: BusMaster Data Transfer Start @@ -5076,49 +5668,47 @@ static void FPT_busMstrSGDataXferStart(unsigned long p_port, * Description: * *---------------------------------------------------------------------*/ -static void FPT_busMstrDataXferStart(unsigned long p_port, - struct sccb *pcurrSCCB) +static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB) { - unsigned long addr, count; + ULONG addr,count; - if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) { + if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) { - count = pcurrSCCB->Sccb_XferCnt; + count = pcurrSCCB->Sccb_XferCnt; - addr = - (unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC; - } + addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC; + } - else { - addr = pcurrSCCB->SensePointer; - count = pcurrSCCB->RequestSenseLength; + else { + addr = pcurrSCCB->SensePointer; + count = pcurrSCCB->RequestSenseLength; - } + } - HP_SETUP_ADDR_CNT(p_port, addr, count); + HP_SETUP_ADDR_CNT(p_port,addr,count); - if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { - WR_HARPOON(p_port + hp_portctrl_0, - (DMA_PORT | SCSI_PORT | SCSI_INBIT)); - WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH); + if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { - WR_HARPOON(p_port + hp_xfer_cmd, - (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT)); - } + WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT)); + WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH); - else { + WR_HARPOON(p_port+hp_xfer_cmd, + (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT)); + } - WR_HARPOON(p_port + hp_portctrl_0, - (SCSI_PORT | DMA_PORT | DMA_RD)); - WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH); + else { - WR_HARPOON(p_port + hp_xfer_cmd, - (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT)); + WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD)); + WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH); - } + WR_HARPOON(p_port+hp_xfer_cmd, + (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT)); + + } } + /*--------------------------------------------------------------------- * * Function: BusMaster Timeout Handler @@ -5131,38 +5721,37 @@ static void FPT_busMstrDataXferStart(unsigned long p_port, * command busy is also time out, it'll just give up. * *---------------------------------------------------------------------*/ -static unsigned char FPT_busMstrTimeOut(unsigned long p_port) +static UCHAR FPT_busMstrTimeOut(ULONG p_port) { - unsigned long timeout; + ULONG timeout; - timeout = LONG_WAIT; + timeout = LONG_WAIT; - WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH); + WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH); - while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED)) - && timeout--) { - } + while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {} - if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) { - WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT); + + + if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) { + WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT); - timeout = LONG_WAIT; - while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) - && timeout--) { - } - } + timeout = LONG_WAIT; + while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {} + } - RD_HARPOON(p_port + hp_int_status); /*Clear command complete */ + RD_HARPOON(p_port+hp_int_status); /*Clear command complete */ - if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) { - return 1; - } + if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) { + return(1); + } - else { - return 0; - } + else { + return(0); + } } + /*--------------------------------------------------------------------- * * Function: Host Data Transfer Abort @@ -5170,282 +5759,256 @@ static unsigned char FPT_busMstrTimeOut(unsigned long p_port) * Description: Abort any in progress transfer. * *---------------------------------------------------------------------*/ -static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, - struct sccb *pCurrSCCB) +static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB) { - unsigned long timeout; - unsigned long remain_cnt; - unsigned int sg_ptr; + ULONG timeout; + ULONG remain_cnt; + UINT sg_ptr; - FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT; + FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT; - if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) { + if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) { - if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) { - WR_HARPOON(port + hp_bm_ctrl, - (RD_HARPOON(port + hp_bm_ctrl) | - FLUSH_XFER_CNTR)); - timeout = LONG_WAIT; + if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) { - while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) - && timeout--) { - } + WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR)); + timeout = LONG_WAIT; - WR_HARPOON(port + hp_bm_ctrl, - (RD_HARPOON(port + hp_bm_ctrl) & - ~FLUSH_XFER_CNTR)); + while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {} - if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { + WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR)); - if (FPT_busMstrTimeOut(port)) { + if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) { - if (pCurrSCCB->HostStatus == 0x00) + if (FPT_busMstrTimeOut(port)) { - pCurrSCCB->HostStatus = - SCCB_BM_ERR; + if (pCurrSCCB->HostStatus == 0x00) - } + pCurrSCCB->HostStatus = SCCB_BM_ERR; - if (RD_HARPOON(port + hp_int_status) & - INT_EXT_STATUS) + } - if (RD_HARPOON(port + hp_ext_status) & - BAD_EXT_STATUS) + if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) - if (pCurrSCCB->HostStatus == - 0x00) - { - pCurrSCCB->HostStatus = - SCCB_BM_ERR; - } - } - } - } + if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) - else if (pCurrSCCB->Sccb_XferCnt) { + if (pCurrSCCB->HostStatus == 0x00) - if (pCurrSCCB->Sccb_XferState & F_SG_XFER) { + { + pCurrSCCB->HostStatus = SCCB_BM_ERR; + } + } + } + } - WR_HARPOON(port + hp_page_ctrl, - (RD_HARPOON(port + hp_page_ctrl) & - ~SCATTER_EN)); + else if (pCurrSCCB->Sccb_XferCnt) { - WR_HARPOON(port + hp_sg_addr, 0x00); + if (pCurrSCCB->Sccb_XferState & F_SG_XFER) { - sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT; - if (sg_ptr > - (unsigned int)(pCurrSCCB->DataLength / - SG_ELEMENT_SIZE)) { + WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) & + ~SCATTER_EN)); - sg_ptr = - (unsigned int)(pCurrSCCB->DataLength / - SG_ELEMENT_SIZE); - } + WR_HARPOON(port+hp_sg_addr,0x00); - remain_cnt = pCurrSCCB->Sccb_XferCnt; + sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT; - while (remain_cnt < 0x01000000L) { + if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) { - sg_ptr--; + sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE); + } - if (remain_cnt > - (unsigned - long)(*(((unsigned long *)pCurrSCCB-> - DataPointer) + (sg_ptr * 2)))) { + remain_cnt = pCurrSCCB->Sccb_XferCnt; - remain_cnt -= - (unsigned - long)(*(((unsigned long *) - pCurrSCCB->DataPointer) + - (sg_ptr * 2))); - } + while (remain_cnt < 0x01000000L) { - else { + sg_ptr--; - break; - } - } + if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB-> + DataPointer) + (sg_ptr * 2)))) { - if (remain_cnt < 0x01000000L) { + remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB-> + DataPointer) + (sg_ptr * 2))); + } - pCurrSCCB->Sccb_SGoffset = remain_cnt; + else { - pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr; + break; + } + } - if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == - pCurrSCCB->DataLength && (remain_cnt == 0)) - pCurrSCCB->Sccb_XferState |= - F_ALL_XFERRED; - } - else { + if (remain_cnt < 0x01000000L) { - if (pCurrSCCB->HostStatus == 0x00) { - pCurrSCCB->HostStatus = - SCCB_GROSS_FW_ERR; - } - } - } + pCurrSCCB->Sccb_SGoffset = remain_cnt; - if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) { + pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr; - if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { - FPT_busMstrTimeOut(port); - } + if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength + && (remain_cnt == 0)) - else { + pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; + } - if (RD_HARPOON(port + hp_int_status) & - INT_EXT_STATUS) { + else { - if (RD_HARPOON(port + hp_ext_status) & - BAD_EXT_STATUS) { - if (pCurrSCCB->HostStatus == - 0x00) { + if (pCurrSCCB->HostStatus == 0x00) { - pCurrSCCB->HostStatus = - SCCB_BM_ERR; - } - } - } + pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR; + } + } + } - } - } - else { + if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) { - if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) { - timeout = SHORT_WAIT; + if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) { - while ((RD_HARPOON(port + hp_ext_status) & - BM_CMD_BUSY) - && ((RD_HARPOON(port + hp_fifo_cnt)) >= - BM_THRESHOLD) && timeout--) { - } - } + FPT_busMstrTimeOut(port); + } - if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { + else { - WR_HARPOON(port + hp_bm_ctrl, - (RD_HARPOON(port + hp_bm_ctrl) | - FLUSH_XFER_CNTR)); + if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) { - timeout = LONG_WAIT; + if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) { - while ((RD_HARPOON(port + hp_ext_status) & - BM_CMD_BUSY) && timeout--) { - } + if (pCurrSCCB->HostStatus == 0x00) { - WR_HARPOON(port + hp_bm_ctrl, - (RD_HARPOON(port + hp_bm_ctrl) & - ~FLUSH_XFER_CNTR)); + pCurrSCCB->HostStatus = SCCB_BM_ERR; + } + } + } - if (RD_HARPOON(port + hp_ext_status) & - BM_CMD_BUSY) { + } + } - if (pCurrSCCB->HostStatus == 0x00) { + else { - pCurrSCCB->HostStatus = - SCCB_BM_ERR; - } - FPT_busMstrTimeOut(port); - } - } + if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) { - if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) { + timeout = SHORT_WAIT; - if (RD_HARPOON(port + hp_ext_status) & - BAD_EXT_STATUS) { + while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && + ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) && + timeout--) {} + } - if (pCurrSCCB->HostStatus == 0x00) { + if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) { - pCurrSCCB->HostStatus = - SCCB_BM_ERR; - } - } - } - } + WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | + FLUSH_XFER_CNTR)); - } + timeout = LONG_WAIT; - else { + while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && + timeout--) {} - if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { + WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & + ~FLUSH_XFER_CNTR)); - timeout = LONG_WAIT; - while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) - && timeout--) { - } + if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) { - if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { + if (pCurrSCCB->HostStatus == 0x00) { - if (pCurrSCCB->HostStatus == 0x00) { + pCurrSCCB->HostStatus = SCCB_BM_ERR; + } - pCurrSCCB->HostStatus = SCCB_BM_ERR; - } + FPT_busMstrTimeOut(port); + } + } - FPT_busMstrTimeOut(port); - } - } + if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) { - if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) { + if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) { - if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) { + if (pCurrSCCB->HostStatus == 0x00) { - if (pCurrSCCB->HostStatus == 0x00) { + pCurrSCCB->HostStatus = SCCB_BM_ERR; + } + } + } + } - pCurrSCCB->HostStatus = SCCB_BM_ERR; - } - } + } - } + else { - if (pCurrSCCB->Sccb_XferState & F_SG_XFER) { - WR_HARPOON(port + hp_page_ctrl, - (RD_HARPOON(port + hp_page_ctrl) & - ~SCATTER_EN)); + if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) { - WR_HARPOON(port + hp_sg_addr, 0x00); + timeout = LONG_WAIT; - pCurrSCCB->Sccb_sgseg += SG_BUF_CNT; + while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {} - pCurrSCCB->Sccb_SGoffset = 0x00; + if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) { - if ((unsigned long)(pCurrSCCB->Sccb_sgseg * - SG_ELEMENT_SIZE) >= - pCurrSCCB->DataLength) { + if (pCurrSCCB->HostStatus == 0x00) { - pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; + pCurrSCCB->HostStatus = SCCB_BM_ERR; + } - pCurrSCCB->Sccb_sgseg = - (unsigned short)(pCurrSCCB->DataLength / - SG_ELEMENT_SIZE); + FPT_busMstrTimeOut(port); + } + } - } - } - else { + if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) { - if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE)) + if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) { - pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; - } - } + if (pCurrSCCB->HostStatus == 0x00) { + + pCurrSCCB->HostStatus = SCCB_BM_ERR; + } + } + + } + + if (pCurrSCCB->Sccb_XferState & F_SG_XFER) { + + WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) & + ~SCATTER_EN)); + + WR_HARPOON(port+hp_sg_addr,0x00); + + pCurrSCCB->Sccb_sgseg += SG_BUF_CNT; + + pCurrSCCB->Sccb_SGoffset = 0x00; - WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); + + if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >= + pCurrSCCB->DataLength) { + + pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; + + pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE); + + } + } + + else { + + if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE)) + + pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; + } + } + + WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT)); } + + /*--------------------------------------------------------------------- * * Function: Host Data Transfer Restart @@ -5454,47 +6017,47 @@ static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, * pointers message. * *---------------------------------------------------------------------*/ -static void FPT_hostDataXferRestart(struct sccb *currSCCB) +static void FPT_hostDataXferRestart(PSCCB currSCCB) { - unsigned long data_count; - unsigned int sg_index; - unsigned long *sg_ptr; + ULONG data_count; + UINT sg_index; + ULONG *sg_ptr; - if (currSCCB->Sccb_XferState & F_SG_XFER) { + if (currSCCB->Sccb_XferState & F_SG_XFER) { - currSCCB->Sccb_XferCnt = 0; + currSCCB->Sccb_XferCnt = 0; - sg_index = 0xffff; /*Index by long words into sg list. */ - data_count = 0; /*Running count of SG xfer counts. */ + sg_index = 0xffff; /*Index by long words into sg list. */ + data_count = 0; /*Running count of SG xfer counts. */ - sg_ptr = (unsigned long *)currSCCB->DataPointer; + sg_ptr = (ULONG *)currSCCB->DataPointer; - while (data_count < currSCCB->Sccb_ATC) { + while (data_count < currSCCB->Sccb_ATC) { - sg_index++; - data_count += *(sg_ptr + (sg_index * 2)); - } + sg_index++; + data_count += *(sg_ptr+(sg_index * 2)); + } - if (data_count == currSCCB->Sccb_ATC) { + if (data_count == currSCCB->Sccb_ATC) { - currSCCB->Sccb_SGoffset = 0; - sg_index++; - } + currSCCB->Sccb_SGoffset = 0; + sg_index++; + } - else { - currSCCB->Sccb_SGoffset = - data_count - currSCCB->Sccb_ATC; - } + else { + currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC; + } - currSCCB->Sccb_sgseg = (unsigned short)sg_index; - } + currSCCB->Sccb_sgseg = (USHORT)sg_index; + } - else { - currSCCB->Sccb_XferCnt = - currSCCB->DataLength - currSCCB->Sccb_ATC; - } + else { + currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC; + } } + + /*--------------------------------------------------------------------- * * Function: FPT_scini @@ -5503,192 +6066,177 @@ static void FPT_hostDataXferRestart(struct sccb *currSCCB) * *---------------------------------------------------------------------*/ -static void FPT_scini(unsigned char p_card, unsigned char p_our_id, - unsigned char p_power_up) +static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up) { - unsigned char loser, assigned_id; - unsigned long p_port; + UCHAR loser,assigned_id; + ULONG p_port; - unsigned char i, k, ScamFlg; - struct sccb_card *currCard; - struct nvram_info *pCurrNvRam; + UCHAR i,k,ScamFlg ; + PSCCBcard currCard; + PNVRamInfo pCurrNvRam; - currCard = &FPT_BL_Card[p_card]; - p_port = currCard->ioPort; + currCard = &FPT_BL_Card[p_card]; + p_port = currCard->ioPort; pCurrNvRam = currCard->pNvRamInfo; - if (pCurrNvRam) { + + if(pCurrNvRam){ ScamFlg = pCurrNvRam->niScamConf; i = pCurrNvRam->niSysConf; - } else { - ScamFlg = - (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2); - i = (unsigned - char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2))); } - if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */ + else{ + ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2); + i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2))); + } + if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */ return; - FPT_inisci(p_card, p_port, p_our_id); + FPT_inisci(p_card,p_port, p_our_id); - /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW - too slow to return to SCAM selection */ + /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW + too slow to return to SCAM selection */ - /* if (p_power_up) - FPT_Wait1Second(p_port); - else - FPT_Wait(p_port, TO_250ms); */ + /* if (p_power_up) + FPT_Wait1Second(p_port); + else + FPT_Wait(p_port, TO_250ms); */ - FPT_Wait1Second(p_port); + FPT_Wait1Second(p_port); - if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) { - while (!(FPT_scarb(p_port, INIT_SELTD))) { - } + if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) + { + while (!(FPT_scarb(p_port,INIT_SELTD))) {} - FPT_scsel(p_port); + FPT_scsel(p_port); - do { - FPT_scxferc(p_port, SYNC_PTRN); - FPT_scxferc(p_port, DOM_MSTR); - loser = - FPT_scsendi(p_port, - &FPT_scamInfo[p_our_id].id_string[0]); - } while (loser == 0xFF); + do { + FPT_scxferc(p_port,SYNC_PTRN); + FPT_scxferc(p_port,DOM_MSTR); + loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]); + } while ( loser == 0xFF ); - FPT_scbusf(p_port); + FPT_scbusf(p_port); - if ((p_power_up) && (!loser)) { - FPT_sresb(p_port, p_card); - FPT_Wait(p_port, TO_250ms); + if ((p_power_up) && (!loser)) + { + FPT_sresb(p_port,p_card); + FPT_Wait(p_port, TO_250ms); - while (!(FPT_scarb(p_port, INIT_SELTD))) { - } + while (!(FPT_scarb(p_port,INIT_SELTD))) {} - FPT_scsel(p_port); + FPT_scsel(p_port); - do { - FPT_scxferc(p_port, SYNC_PTRN); - FPT_scxferc(p_port, DOM_MSTR); - loser = - FPT_scsendi(p_port, - &FPT_scamInfo[p_our_id]. - id_string[0]); - } while (loser == 0xFF); + do { + FPT_scxferc(p_port, SYNC_PTRN); + FPT_scxferc(p_port, DOM_MSTR); + loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id]. + id_string[0]); + } while ( loser == 0xFF ); - FPT_scbusf(p_port); - } - } + FPT_scbusf(p_port); + } + } - else { - loser = 0; - } + else + { + loser = 0; + } - if (!loser) { - - FPT_scamInfo[p_our_id].state = ID_ASSIGNED; - - if (ScamFlg & SCAM_ENABLED) { - - for (i = 0; i < MAX_SCSI_TAR; i++) { - if ((FPT_scamInfo[i].state == ID_UNASSIGNED) || - (FPT_scamInfo[i].state == ID_UNUSED)) { - if (FPT_scsell(p_port, i)) { - FPT_scamInfo[i].state = LEGACY; - if ((FPT_scamInfo[i]. - id_string[0] != 0xFF) - || (FPT_scamInfo[i]. - id_string[1] != 0xFA)) { - - FPT_scamInfo[i]. - id_string[0] = 0xFF; - FPT_scamInfo[i]. - id_string[1] = 0xFA; - if (pCurrNvRam == NULL) - currCard-> - globalFlags - |= - F_UPDATE_EEPROM; - } - } - } - } - FPT_sresb(p_port, p_card); - FPT_Wait1Second(p_port); - while (!(FPT_scarb(p_port, INIT_SELTD))) { - } - FPT_scsel(p_port); - FPT_scasid(p_card, p_port); - } + if (!loser) + { - } + FPT_scamInfo[p_our_id].state = ID_ASSIGNED; - else if ((loser) && (ScamFlg & SCAM_ENABLED)) { - FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0; - assigned_id = 0; - FPT_scwtsel(p_port); - do { - while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) { - } + if (ScamFlg & SCAM_ENABLED) + { - i = FPT_scxferc(p_port, 0x00); - if (i == ASSIGN_ID) { - if (! - (FPT_scsendi - (p_port, - &FPT_scamInfo[p_our_id].id_string[0]))) { - i = FPT_scxferc(p_port, 0x00); - if (FPT_scvalq(i)) { - k = FPT_scxferc(p_port, 0x00); - - if (FPT_scvalq(k)) { - currCard->ourId = - ((unsigned char)(i - << - 3) - + - (k & - (unsigned char)7)) - & (unsigned char) - 0x3F; - FPT_inisci(p_card, - p_port, - p_our_id); - FPT_scamInfo[currCard-> - ourId]. - state = ID_ASSIGNED; - FPT_scamInfo[currCard-> - ourId]. - id_string[0] - = SLV_TYPE_CODE0; - assigned_id = 1; - } - } - } - } + for (i=0; i < MAX_SCSI_TAR; i++) + { + if ((FPT_scamInfo[i].state == ID_UNASSIGNED) || + (FPT_scamInfo[i].state == ID_UNUSED)) + { + if (FPT_scsell(p_port,i)) + { + FPT_scamInfo[i].state = LEGACY; + if ((FPT_scamInfo[i].id_string[0] != 0xFF) || + (FPT_scamInfo[i].id_string[1] != 0xFA)) + { + + FPT_scamInfo[i].id_string[0] = 0xFF; + FPT_scamInfo[i].id_string[1] = 0xFA; + if(pCurrNvRam == NULL) + currCard->globalFlags |= F_UPDATE_EEPROM; + } + } + } + } + + FPT_sresb(p_port,p_card); + FPT_Wait1Second(p_port); + while (!(FPT_scarb(p_port,INIT_SELTD))) {} + FPT_scsel(p_port); + FPT_scasid(p_card, p_port); + } - else if (i == SET_P_FLAG) { - if (!(FPT_scsendi(p_port, - &FPT_scamInfo[p_our_id]. - id_string[0]))) - FPT_scamInfo[p_our_id].id_string[0] |= - 0x80; - } - } while (!assigned_id); + } - while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) { - } - } + else if ((loser) && (ScamFlg & SCAM_ENABLED)) + { + FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0; + assigned_id = 0; + FPT_scwtsel(p_port); + + do { + while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {} + + i = FPT_scxferc(p_port,0x00); + if (i == ASSIGN_ID) + { + if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]))) + { + i = FPT_scxferc(p_port,0x00); + if (FPT_scvalq(i)) + { + k = FPT_scxferc(p_port,0x00); + + if (FPT_scvalq(k)) + { + currCard->ourId = + ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F; + FPT_inisci(p_card, p_port, p_our_id); + FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED; + FPT_scamInfo[currCard->ourId].id_string[0] + = SLV_TYPE_CODE0; + assigned_id = 1; + } + } + } + } + + else if (i == SET_P_FLAG) + { + if (!(FPT_scsendi(p_port, + &FPT_scamInfo[p_our_id].id_string[0]))) + FPT_scamInfo[p_our_id].id_string[0] |= 0x80; + } + }while (!assigned_id); + + while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {} + } + + if (ScamFlg & SCAM_ENABLED) + { + FPT_scbusf(p_port); + if (currCard->globalFlags & F_UPDATE_EEPROM) + { + FPT_scsavdi(p_card, p_port); + currCard->globalFlags &= ~F_UPDATE_EEPROM; + } + } - if (ScamFlg & SCAM_ENABLED) { - FPT_scbusf(p_port); - if (currCard->globalFlags & F_UPDATE_EEPROM) { - FPT_scsavdi(p_card, p_port); - currCard->globalFlags &= ~F_UPDATE_EEPROM; - } - } /* for (i=0,k=0; i < MAX_SCSI_TAR; i++) @@ -5705,6 +6253,7 @@ static void FPT_scini(unsigned char p_card, unsigned char p_our_id, */ } + /*--------------------------------------------------------------------- * * Function: FPT_scarb @@ -5713,60 +6262,59 @@ static void FPT_scini(unsigned char p_card, unsigned char p_our_id, * *---------------------------------------------------------------------*/ -static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type) +static int FPT_scarb(ULONG p_port, UCHAR p_sel_type) { - if (p_sel_type == INIT_SELTD) { + if (p_sel_type == INIT_SELTD) + { - while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) { - } + while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {} - if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) - return 0; - if (RD_HARPOON(p_port + hp_scsidata_0) != 00) - return 0; + if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) + return(0); - WR_HARPOON(p_port + hp_scsisig, - (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY)); + if (RD_HARPOON(p_port+hp_scsidata_0) != 00) + return(0); - if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) { + WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY)); - WR_HARPOON(p_port + hp_scsisig, - (RD_HARPOON(p_port + hp_scsisig) & - ~SCSI_BSY)); - return 0; - } + if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) { - WR_HARPOON(p_port + hp_scsisig, - (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL)); + WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) & + ~SCSI_BSY)); + return(0); + } - if (RD_HARPOON(p_port + hp_scsidata_0) != 00) { - WR_HARPOON(p_port + hp_scsisig, - (RD_HARPOON(p_port + hp_scsisig) & - ~(SCSI_BSY | SCSI_SEL))); - return 0; - } - } + WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL)); + + if (RD_HARPOON(p_port+hp_scsidata_0) != 00) { + + WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) & + ~(SCSI_BSY | SCSI_SEL))); + return(0); + } + } - WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0) - & ~ACTdeassert)); - WR_HARPOON(p_port + hp_scsireset, SCAM_EN); - WR_HARPOON(p_port + hp_scsidata_0, 0x00); - WR_HARPOON(p_port + hp_scsidata_1, 0x00); - WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN); - WR_HARPOON(p_port + hp_scsisig, - (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG)); + WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0) + & ~ACTdeassert)); + WR_HARPOON(p_port+hp_scsireset, SCAM_EN); + WR_HARPOON(p_port+hp_scsidata_0, 0x00); + WR_HARPOON(p_port+hp_scsidata_1, 0x00); + WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN); - WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig) - & ~SCSI_BSY)); + WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG)); - FPT_Wait(p_port, TO_250ms); + WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) + & ~SCSI_BSY)); - return 1; + FPT_Wait(p_port,TO_250ms); + + return(1); } + /*--------------------------------------------------------------------- * * Function: FPT_scbusf @@ -5775,30 +6323,34 @@ static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type) * *---------------------------------------------------------------------*/ -static void FPT_scbusf(unsigned long p_port) +static void FPT_scbusf(ULONG p_port) { - WR_HARPOON(p_port + hp_page_ctrl, - (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE)); + WR_HARPOON(p_port+hp_page_ctrl, + (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)); + - WR_HARPOON(p_port + hp_scsidata_0, 0x00); + WR_HARPOON(p_port+hp_scsidata_0, 0x00); - WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0) - & ~SCSI_BUS_EN)); + WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0) + & ~SCSI_BUS_EN)); - WR_HARPOON(p_port + hp_scsisig, 0x00); + WR_HARPOON(p_port+hp_scsisig, 0x00); - WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset) - & ~SCAM_EN)); - WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0) - | ACTdeassert)); + WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset) + & ~SCAM_EN)); - WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL)); + WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0) + | ACTdeassert)); - WR_HARPOON(p_port + hp_page_ctrl, - (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE)); + WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL)); + + WR_HARPOON(p_port+hp_page_ctrl, + (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)); } + + /*--------------------------------------------------------------------- * * Function: FPT_scasid @@ -5807,75 +6359,86 @@ static void FPT_scbusf(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_scasid(unsigned char p_card, unsigned long p_port) +static void FPT_scasid(UCHAR p_card, ULONG p_port) { - unsigned char temp_id_string[ID_STRING_LENGTH]; + UCHAR temp_id_string[ID_STRING_LENGTH]; - unsigned char i, k, scam_id; - unsigned char crcBytes[3]; - struct nvram_info *pCurrNvRam; - unsigned short *pCrcBytes; + UCHAR i,k,scam_id; + UCHAR crcBytes[3]; + PNVRamInfo pCurrNvRam; + ushort_ptr pCrcBytes; pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo; - i = 0; + i=0; - while (!i) { + while (!i) + { - for (k = 0; k < ID_STRING_LENGTH; k++) { - temp_id_string[k] = (unsigned char)0x00; - } + for (k=0; k < ID_STRING_LENGTH; k++) + { + temp_id_string[k] = (UCHAR) 0x00; + } - FPT_scxferc(p_port, SYNC_PTRN); - FPT_scxferc(p_port, ASSIGN_ID); + FPT_scxferc(p_port,SYNC_PTRN); + FPT_scxferc(p_port,ASSIGN_ID); - if (!(FPT_sciso(p_port, &temp_id_string[0]))) { - if (pCurrNvRam) { - pCrcBytes = (unsigned short *)&crcBytes[0]; + if (!(FPT_sciso(p_port,&temp_id_string[0]))) + { + if(pCurrNvRam){ + pCrcBytes = (ushort_ptr)&crcBytes[0]; *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]); crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]); temp_id_string[1] = crcBytes[2]; temp_id_string[2] = crcBytes[0]; temp_id_string[3] = crcBytes[1]; - for (k = 4; k < ID_STRING_LENGTH; k++) - temp_id_string[k] = (unsigned char)0x00; + for(k = 4; k < ID_STRING_LENGTH; k++) + temp_id_string[k] = (UCHAR) 0x00; } - i = FPT_scmachid(p_card, temp_id_string); + i = FPT_scmachid(p_card,temp_id_string); - if (i == CLR_PRIORITY) { - FPT_scxferc(p_port, MISC_CODE); - FPT_scxferc(p_port, CLR_P_FLAG); - i = 0; /*Not the last ID yet. */ - } + if (i == CLR_PRIORITY) + { + FPT_scxferc(p_port,MISC_CODE); + FPT_scxferc(p_port,CLR_P_FLAG); + i = 0; /*Not the last ID yet. */ + } - else if (i != NO_ID_AVAIL) { - if (i < 8) - FPT_scxferc(p_port, ID_0_7); - else - FPT_scxferc(p_port, ID_8_F); + else if (i != NO_ID_AVAIL) + { + if (i < 8 ) + FPT_scxferc(p_port,ID_0_7); + else + FPT_scxferc(p_port,ID_8_F); - scam_id = (i & (unsigned char)0x07); + scam_id = (i & (UCHAR) 0x07); - for (k = 1; k < 0x08; k <<= 1) - if (!(k & i)) - scam_id += 0x08; /*Count number of zeros in DB0-3. */ - FPT_scxferc(p_port, scam_id); + for (k=1; k < 0x08; k <<= 1) + if (!( k & i )) + scam_id += 0x08; /*Count number of zeros in DB0-3. */ - i = 0; /*Not the last ID yet. */ - } - } + FPT_scxferc(p_port,scam_id); - else { - i = 1; - } + i = 0; /*Not the last ID yet. */ + } + } + + else + { + i = 1; + } - } /*End while */ + } /*End while */ - FPT_scxferc(p_port, SYNC_PTRN); - FPT_scxferc(p_port, CFG_CMPLT); + FPT_scxferc(p_port,SYNC_PTRN); + FPT_scxferc(p_port,CFG_CMPLT); } + + + + /*--------------------------------------------------------------------- * * Function: FPT_scsel @@ -5884,32 +6447,32 @@ static void FPT_scasid(unsigned char p_card, unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_scsel(unsigned long p_port) +static void FPT_scsel(ULONG p_port) { - WR_HARPOON(p_port + hp_scsisig, SCSI_SEL); - FPT_scwiros(p_port, SCSI_MSG); + WR_HARPOON(p_port+hp_scsisig, SCSI_SEL); + FPT_scwiros(p_port, SCSI_MSG); + + WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY)); + - WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY)); + WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD)); + WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) | + (UCHAR)(BIT(7)+BIT(6)))); - WR_HARPOON(p_port + hp_scsisig, - (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD)); - WR_HARPOON(p_port + hp_scsidata_0, - (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) | - (unsigned char)(BIT(7) + BIT(6)))); - WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD)); - FPT_scwiros(p_port, SCSI_SEL); + WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD)); + FPT_scwiros(p_port, SCSI_SEL); - WR_HARPOON(p_port + hp_scsidata_0, - (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) & - ~(unsigned char)BIT(6))); - FPT_scwirod(p_port, BIT(6)); + WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) & + ~(UCHAR)BIT(6))); + FPT_scwirod(p_port, BIT(6)); - WR_HARPOON(p_port + hp_scsisig, - (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD)); + WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD)); } + + /*--------------------------------------------------------------------- * * Function: FPT_scxferc @@ -5918,47 +6481,48 @@ static void FPT_scsel(unsigned long p_port) * *---------------------------------------------------------------------*/ -static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data) +static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data) { - unsigned char curr_data, ret_data; + UCHAR curr_data, ret_data; - curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */ + curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */ - WR_HARPOON(p_port + hp_scsidata_0, curr_data); + WR_HARPOON(p_port+hp_scsidata_0, curr_data); - curr_data &= ~BIT(7); + curr_data &= ~BIT(7); - WR_HARPOON(p_port + hp_scsidata_0, curr_data); + WR_HARPOON(p_port+hp_scsidata_0, curr_data); - FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */ - while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ; + FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */ + while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5))); - ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F); + ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F); - curr_data |= BIT(6); + curr_data |= BIT(6); - WR_HARPOON(p_port + hp_scsidata_0, curr_data); + WR_HARPOON(p_port+hp_scsidata_0, curr_data); - curr_data &= ~BIT(5); + curr_data &= ~BIT(5); - WR_HARPOON(p_port + hp_scsidata_0, curr_data); + WR_HARPOON(p_port+hp_scsidata_0, curr_data); - FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */ + FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */ - curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */ - curr_data |= BIT(7); + curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */ + curr_data |= BIT(7); - WR_HARPOON(p_port + hp_scsidata_0, curr_data); + WR_HARPOON(p_port+hp_scsidata_0, curr_data); - curr_data &= ~BIT(6); + curr_data &= ~BIT(6); - WR_HARPOON(p_port + hp_scsidata_0, curr_data); + WR_HARPOON(p_port+hp_scsidata_0, curr_data); - FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */ + FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */ - return ret_data; + return(ret_data); } + /*--------------------------------------------------------------------- * * Function: FPT_scsendi @@ -5968,50 +6532,51 @@ static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data) * *---------------------------------------------------------------------*/ -static unsigned char FPT_scsendi(unsigned long p_port, - unsigned char p_id_string[]) +static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]) { - unsigned char ret_data, byte_cnt, bit_cnt, defer; + UCHAR ret_data,byte_cnt,bit_cnt,defer; - defer = 0; + defer = 0; - for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) { + for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) { - for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) { + for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) { - if (defer) - ret_data = FPT_scxferc(p_port, 00); + if (defer) + ret_data = FPT_scxferc(p_port,00); - else if (p_id_string[byte_cnt] & bit_cnt) + else if (p_id_string[byte_cnt] & bit_cnt) - ret_data = FPT_scxferc(p_port, 02); + ret_data = FPT_scxferc(p_port,02); - else { + else { - ret_data = FPT_scxferc(p_port, 01); - if (ret_data & 02) - defer = 1; - } + ret_data = FPT_scxferc(p_port,01); + if (ret_data & 02) + defer = 1; + } - if ((ret_data & 0x1C) == 0x10) - return 0x00; /*End of isolation stage, we won! */ + if ((ret_data & 0x1C) == 0x10) + return(0x00); /*End of isolation stage, we won! */ - if (ret_data & 0x1C) - return 0xFF; + if (ret_data & 0x1C) + return(0xFF); - if ((defer) && (!(ret_data & 0x1F))) - return 0x01; /*End of isolation stage, we lost. */ + if ((defer) && (!(ret_data & 0x1F))) + return(0x01); /*End of isolation stage, we lost. */ - } /*bit loop */ + } /*bit loop */ - } /*byte loop */ + } /*byte loop */ - if (defer) - return 0x01; /*We lost */ - else - return 0; /*We WON! Yeeessss! */ + if (defer) + return(0x01); /*We lost */ + else + return(0); /*We WON! Yeeessss! */ } + + /*--------------------------------------------------------------------- * * Function: FPT_sciso @@ -6020,31 +6585,31 @@ static unsigned char FPT_scsendi(unsigned long p_port, * *---------------------------------------------------------------------*/ -static unsigned char FPT_sciso(unsigned long p_port, - unsigned char p_id_string[]) +static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]) { - unsigned char ret_data, the_data, byte_cnt, bit_cnt; + UCHAR ret_data,the_data,byte_cnt,bit_cnt; - the_data = 0; + the_data = 0; - for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) { + for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) { - for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) { + for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) { - ret_data = FPT_scxferc(p_port, 0); + ret_data = FPT_scxferc(p_port,0); - if (ret_data & 0xFC) - return 0xFF; + if (ret_data & 0xFC) + return(0xFF); - else { + else { - the_data <<= 1; - if (ret_data & BIT(1)) { - the_data |= 1; - } - } + the_data <<= 1; + if (ret_data & BIT(1)) { + the_data |= 1; + } + } - if ((ret_data & 0x1F) == 0) { + if ((ret_data & 0x1F) == 0) + { /* if(bit_cnt != 0 || bit_cnt != 8) { @@ -6055,21 +6620,23 @@ static unsigned char FPT_sciso(unsigned long p_port, continue; } */ - if (byte_cnt) - return 0x00; - else - return 0xFF; - } + if (byte_cnt) + return(0x00); + else + return(0xFF); + } - } /*bit loop */ + } /*bit loop */ - p_id_string[byte_cnt] = the_data; + p_id_string[byte_cnt] = the_data; - } /*byte loop */ + } /*byte loop */ - return 0; + return(0); } + + /*--------------------------------------------------------------------- * * Function: FPT_scwirod @@ -6079,24 +6646,26 @@ static unsigned char FPT_sciso(unsigned long p_port, * *---------------------------------------------------------------------*/ -static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit) +static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit) { - unsigned char i; + UCHAR i; - i = 0; - while (i < MAX_SCSI_TAR) { + i = 0; + while ( i < MAX_SCSI_TAR ) { - if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit) + if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit) - i = 0; + i = 0; - else + else - i++; + i++; - } + } } + + /*--------------------------------------------------------------------- * * Function: FPT_scwiros @@ -6106,24 +6675,25 @@ static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit) * *---------------------------------------------------------------------*/ -static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit) +static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit) { - unsigned char i; + UCHAR i; - i = 0; - while (i < MAX_SCSI_TAR) { + i = 0; + while ( i < MAX_SCSI_TAR ) { - if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit) + if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit) - i = 0; + i = 0; - else + else - i++; + i++; - } + } } + /*--------------------------------------------------------------------- * * Function: FPT_scvalq @@ -6132,22 +6702,23 @@ static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit) * *---------------------------------------------------------------------*/ -static unsigned char FPT_scvalq(unsigned char p_quintet) +static UCHAR FPT_scvalq(UCHAR p_quintet) { - unsigned char count; + UCHAR count; - for (count = 1; count < 0x08; count <<= 1) { - if (!(p_quintet & count)) - p_quintet -= 0x80; - } + for (count=1; count < 0x08; count<<=1) { + if (!(p_quintet & count)) + p_quintet -= 0x80; + } - if (p_quintet & 0x18) - return 0; + if (p_quintet & 0x18) + return(0); - else - return 1; + else + return(1); } + /*--------------------------------------------------------------------- * * Function: FPT_scsell @@ -6158,78 +6729,75 @@ static unsigned char FPT_scvalq(unsigned char p_quintet) * *---------------------------------------------------------------------*/ -static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id) +static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id) { - unsigned long i; + ULONG i; - WR_HARPOON(p_port + hp_page_ctrl, - (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE)); + WR_HARPOON(p_port+hp_page_ctrl, + (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)); - ARAM_ACCESS(p_port); + ARAM_ACCESS(p_port); - WR_HARPOON(p_port + hp_addstat, - (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER)); - WR_HARPOON(p_port + hp_seltimeout, TO_4ms); + WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER)); + WR_HARPOON(p_port+hp_seltimeout,TO_4ms); - for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) { - WRW_HARPOON(i, (MPM_OP + ACOMMAND)); - } - WRW_HARPOON(i, (BRH_OP + ALWAYS + NP)); - WRW_HARPOON((p_port + hp_intstat), - (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT)); + for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) { + WRW_HARPOON(i, (MPM_OP+ACOMMAND)); + } + WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP)); + + WRW_HARPOON((p_port+hp_intstat), + (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT)); - WR_HARPOON(p_port + hp_select_id, targ_id); + WR_HARPOON(p_port+hp_select_id, targ_id); - WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT); - WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT)); - WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL)); + WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT); + WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT)); + WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL)); - while (!(RDW_HARPOON((p_port + hp_intstat)) & - (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) { - } - if (RDW_HARPOON((p_port + hp_intstat)) & RESET) - FPT_Wait(p_port, TO_250ms); + while (!(RDW_HARPOON((p_port+hp_intstat)) & + (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {} - DISABLE_AUTO(p_port); + if (RDW_HARPOON((p_port+hp_intstat)) & RESET) + FPT_Wait(p_port, TO_250ms); - WR_HARPOON(p_port + hp_addstat, - (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER)); - WR_HARPOON(p_port + hp_seltimeout, TO_290ms); + DISABLE_AUTO(p_port); - SGRAM_ACCESS(p_port); + WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER)); + WR_HARPOON(p_port+hp_seltimeout,TO_290ms); - if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) { + SGRAM_ACCESS(p_port); - WRW_HARPOON((p_port + hp_intstat), - (RESET | TIMEOUT | SEL | BUS_FREE | PHASE)); + if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) { - WR_HARPOON(p_port + hp_page_ctrl, - (RD_HARPOON(p_port + hp_page_ctrl) & - ~G_INT_DISABLE)); + WRW_HARPOON((p_port+hp_intstat), + (RESET | TIMEOUT | SEL | BUS_FREE | PHASE)); - return 0; /*No legacy device */ - } + WR_HARPOON(p_port+hp_page_ctrl, + (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)); + + return(0); /*No legacy device */ + } - else { + else { - while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) { - if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) { - WR_HARPOON(p_port + hp_scsisig, - (SCSI_ACK + S_ILL_PH)); - ACCEPT_MSG(p_port); - } + while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) { + if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ) + { + WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); + ACCEPT_MSG(p_port); + } } - WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1); + WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1); - WR_HARPOON(p_port + hp_page_ctrl, - (RD_HARPOON(p_port + hp_page_ctrl) & - ~G_INT_DISABLE)); + WR_HARPOON(p_port+hp_page_ctrl, + (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)); - return 1; /*Found one of them oldies! */ - } + return(1); /*Found one of them oldies! */ + } } /*--------------------------------------------------------------------- @@ -6240,12 +6808,12 @@ static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id) * *---------------------------------------------------------------------*/ -static void FPT_scwtsel(unsigned long p_port) +static void FPT_scwtsel(ULONG p_port) { - while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) { - } + while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {} } + /*--------------------------------------------------------------------- * * Function: FPT_inisci @@ -6254,64 +6822,57 @@ static void FPT_scwtsel(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_inisci(unsigned char p_card, unsigned long p_port, - unsigned char p_our_id) +static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id) { - unsigned char i, k, max_id; - unsigned short ee_data; - struct nvram_info *pCurrNvRam; + UCHAR i,k,max_id; + USHORT ee_data; + PNVRamInfo pCurrNvRam; pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo; - if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD) - max_id = 0x08; + if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD) + max_id = 0x08; - else - max_id = 0x10; + else + max_id = 0x10; - if (pCurrNvRam) { - for (i = 0; i < max_id; i++) { + if(pCurrNvRam){ + for(i = 0; i < max_id; i++){ - for (k = 0; k < 4; k++) - FPT_scamInfo[i].id_string[k] = - pCurrNvRam->niScamTbl[i][k]; - for (k = 4; k < ID_STRING_LENGTH; k++) - FPT_scamInfo[i].id_string[k] = - (unsigned char)0x00; + for(k = 0; k < 4; k++) + FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k]; + for(k = 4; k < ID_STRING_LENGTH; k++) + FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00; - if (FPT_scamInfo[i].id_string[0] == 0x00) - FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */ - else - FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */ + if(FPT_scamInfo[i].id_string[0] == 0x00) + FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */ + else + FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */ } - } else { - for (i = 0; i < max_id; i++) { - for (k = 0; k < ID_STRING_LENGTH; k += 2) { - ee_data = - FPT_utilEERead(p_port, - (unsigned - short)((EE_SCAMBASE / 2) + - (unsigned short)(i * - ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2))); - FPT_scamInfo[i].id_string[k] = - (unsigned char)ee_data; - ee_data >>= 8; - FPT_scamInfo[i].id_string[k + 1] = - (unsigned char)ee_data; - } + }else { + for (i=0; i < max_id; i++) + { + for (k=0; k < ID_STRING_LENGTH; k+=2) + { + ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) + + (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2))); + FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data; + ee_data >>= 8; + FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data; + } - if ((FPT_scamInfo[i].id_string[0] == 0x00) || - (FPT_scamInfo[i].id_string[0] == 0xFF)) + if ((FPT_scamInfo[i].id_string[0] == 0x00) || + (FPT_scamInfo[i].id_string[0] == 0xFF)) - FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */ + FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */ - else - FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */ + else + FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */ - } + } } - for (k = 0; k < ID_STRING_LENGTH; k++) + for(k = 0; k < ID_STRING_LENGTH; k++) FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k]; } @@ -6325,114 +6886,127 @@ static void FPT_inisci(unsigned char p_card, unsigned long p_port, * *---------------------------------------------------------------------*/ -static unsigned char FPT_scmachid(unsigned char p_card, - unsigned char p_id_string[]) +static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]) { - unsigned char i, k, match; + UCHAR i,k,match; - for (i = 0; i < MAX_SCSI_TAR; i++) { - match = 1; + for (i=0; i < MAX_SCSI_TAR; i++) { - for (k = 0; k < ID_STRING_LENGTH; k++) { - if (p_id_string[k] != FPT_scamInfo[i].id_string[k]) - match = 0; - } + match = 1; - if (match) { - FPT_scamInfo[i].state = ID_ASSIGNED; - return i; - } + for (k=0; k < ID_STRING_LENGTH; k++) + { + if (p_id_string[k] != FPT_scamInfo[i].id_string[k]) + match = 0; + } - } + if (match) + { + FPT_scamInfo[i].state = ID_ASSIGNED; + return(i); + } - if (p_id_string[0] & BIT(5)) - i = 8; - else - i = MAX_SCSI_TAR; + } - if (((p_id_string[0] & 0x06) == 0x02) - || ((p_id_string[0] & 0x06) == 0x04)) - match = p_id_string[1] & (unsigned char)0x1F; - else - match = 7; - while (i > 0) { - i--; - if (FPT_scamInfo[match].state == ID_UNUSED) { - for (k = 0; k < ID_STRING_LENGTH; k++) { - FPT_scamInfo[match].id_string[k] = - p_id_string[k]; - } + if (p_id_string[0] & BIT(5)) + i = 8; + else + i = MAX_SCSI_TAR; - FPT_scamInfo[match].state = ID_ASSIGNED; + if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04)) + match = p_id_string[1] & (UCHAR) 0x1F; + else + match = 7; - if (FPT_BL_Card[p_card].pNvRamInfo == NULL) - FPT_BL_Card[p_card].globalFlags |= - F_UPDATE_EEPROM; - return match; + while (i > 0) + { + i--; - } + if (FPT_scamInfo[match].state == ID_UNUSED) + { + for (k=0; k < ID_STRING_LENGTH; k++) + { + FPT_scamInfo[match].id_string[k] = p_id_string[k]; + } - match--; + FPT_scamInfo[match].state = ID_ASSIGNED; - if (match == 0xFF) { - if (p_id_string[0] & BIT(5)) - match = 7; - else - match = MAX_SCSI_TAR - 1; - } - } + if(FPT_BL_Card[p_card].pNvRamInfo == NULL) + FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM; + return(match); + + } - if (p_id_string[0] & BIT(7)) { - return CLR_PRIORITY; + + match--; + + if (match == 0xFF) + { + if (p_id_string[0] & BIT(5)) + match = 7; + else + match = MAX_SCSI_TAR-1; } + } - if (p_id_string[0] & BIT(5)) - i = 8; - else - i = MAX_SCSI_TAR; - if (((p_id_string[0] & 0x06) == 0x02) - || ((p_id_string[0] & 0x06) == 0x04)) - match = p_id_string[1] & (unsigned char)0x1F; - else - match = 7; - while (i > 0) { + if (p_id_string[0] & BIT(7)) + { + return(CLR_PRIORITY); + } + - i--; + if (p_id_string[0] & BIT(5)) + i = 8; + else + i = MAX_SCSI_TAR; - if (FPT_scamInfo[match].state == ID_UNASSIGNED) { - for (k = 0; k < ID_STRING_LENGTH; k++) { - FPT_scamInfo[match].id_string[k] = - p_id_string[k]; - } + if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04)) + match = p_id_string[1] & (UCHAR) 0x1F; + else + match = 7; - FPT_scamInfo[match].id_string[0] |= BIT(7); - FPT_scamInfo[match].state = ID_ASSIGNED; - if (FPT_BL_Card[p_card].pNvRamInfo == NULL) - FPT_BL_Card[p_card].globalFlags |= - F_UPDATE_EEPROM; - return match; + while (i > 0) + { - } + i--; - match--; + if (FPT_scamInfo[match].state == ID_UNASSIGNED) + { + for (k=0; k < ID_STRING_LENGTH; k++) + { + FPT_scamInfo[match].id_string[k] = p_id_string[k]; + } - if (match == 0xFF) { - if (p_id_string[0] & BIT(5)) - match = 7; - else - match = MAX_SCSI_TAR - 1; - } + FPT_scamInfo[match].id_string[0] |= BIT(7); + FPT_scamInfo[match].state = ID_ASSIGNED; + if(FPT_BL_Card[p_card].pNvRamInfo == NULL) + FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM; + return(match); + + } + + + match--; + + if (match == 0xFF) + { + if (p_id_string[0] & BIT(5)) + match = 7; + else + match = MAX_SCSI_TAR-1; } + } - return NO_ID_AVAIL; + return(NO_ID_AVAIL); } + /*--------------------------------------------------------------------- * * Function: FPT_scsavdi @@ -6441,41 +7015,45 @@ static unsigned char FPT_scmachid(unsigned char p_card, * *---------------------------------------------------------------------*/ -static void FPT_scsavdi(unsigned char p_card, unsigned long p_port) +static void FPT_scsavdi(UCHAR p_card, ULONG p_port) { - unsigned char i, k, max_id; - unsigned short ee_data, sum_data; + UCHAR i,k,max_id; + USHORT ee_data,sum_data; - sum_data = 0x0000; - for (i = 1; i < EE_SCAMBASE / 2; i++) { - sum_data += FPT_utilEERead(p_port, i); - } + sum_data = 0x0000; - FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */ + for (i = 1; i < EE_SCAMBASE/2; i++) + { + sum_data += FPT_utilEERead(p_port, i); + } - if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD) - max_id = 0x08; - else - max_id = 0x10; - - for (i = 0; i < max_id; i++) { - - for (k = 0; k < ID_STRING_LENGTH; k += 2) { - ee_data = FPT_scamInfo[i].id_string[k + 1]; - ee_data <<= 8; - ee_data |= FPT_scamInfo[i].id_string[k]; - sum_data += ee_data; - FPT_utilEEWrite(p_port, ee_data, - (unsigned short)((EE_SCAMBASE / 2) + - (unsigned short)(i * - ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2))); - } - } + FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */ + + if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD) + max_id = 0x08; + + else + max_id = 0x10; - FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2); - FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */ + for (i=0; i < max_id; i++) + { + + for (k=0; k < ID_STRING_LENGTH; k+=2) + { + ee_data = FPT_scamInfo[i].id_string[k+1]; + ee_data <<= 8; + ee_data |= FPT_scamInfo[i].id_string[k]; + sum_data += ee_data; + FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) + + (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2))); + } + } + + + FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2); + FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */ } /*--------------------------------------------------------------------- @@ -6486,47 +7064,48 @@ static void FPT_scsavdi(unsigned char p_card, unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg) +static void FPT_XbowInit(ULONG port, UCHAR ScamFlg) { - unsigned char i; +UCHAR i; - i = RD_HARPOON(port + hp_page_ctrl); - WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE)); + i = RD_HARPOON(port+hp_page_ctrl); + WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE)); - WR_HARPOON(port + hp_scsireset, 0x00); - WR_HARPOON(port + hp_portctrl_1, HOST_MODE8); + WR_HARPOON(port+hp_scsireset,0x00); + WR_HARPOON(port+hp_portctrl_1,HOST_MODE8); - WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET | - FIFO_CLR)); + WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \ + FIFO_CLR)); - WR_HARPOON(port + hp_scsireset, SCSI_INI); + WR_HARPOON(port+hp_scsireset,SCSI_INI); - WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT); + WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT); - WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */ - WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL); + WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */ + WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL); - WRW_HARPOON((port + hp_intstat), CLR_ALL_INT); + WRW_HARPOON((port+hp_intstat), CLR_ALL_INT); - FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT | - BUS_FREE | XFER_CNT_0 | AUTO_INT; + FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT | + BUS_FREE | XFER_CNT_0 | AUTO_INT; - if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) + if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) FPT_default_intena |= SCAM_SEL; - WRW_HARPOON((port + hp_intena), FPT_default_intena); + WRW_HARPOON((port+hp_intena), FPT_default_intena); - WR_HARPOON(port + hp_seltimeout, TO_290ms); + WR_HARPOON(port+hp_seltimeout,TO_290ms); - /* Turn on SCSI_MODE8 for narrow cards to fix the - strapping issue with the DUAL CHANNEL card */ - if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD) - WR_HARPOON(port + hp_addstat, SCSI_MODE8); + /* Turn on SCSI_MODE8 for narrow cards to fix the + strapping issue with the DUAL CHANNEL card */ + if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD) + WR_HARPOON(port+hp_addstat,SCSI_MODE8); - WR_HARPOON(port + hp_page_ctrl, i); + WR_HARPOON(port+hp_page_ctrl, i); } + /*--------------------------------------------------------------------- * * Function: FPT_BusMasterInit @@ -6535,24 +7114,28 @@ static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg) * *---------------------------------------------------------------------*/ -static void FPT_BusMasterInit(unsigned long p_port) +static void FPT_BusMasterInit(ULONG p_port) { - WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST); - WR_HARPOON(p_port + hp_sys_ctrl, 0x00); - WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64); + WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST); + WR_HARPOON(p_port+hp_sys_ctrl, 0x00); + + WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64); + - WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT)); + WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT)); - WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H)); + WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H)); - RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */ - WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); - WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) & - ~SCATTER_EN)); + + RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */ + WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); + WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) & + ~SCATTER_EN)); } + /*--------------------------------------------------------------------- * * Function: FPT_DiagEEPROM @@ -6562,153 +7145,158 @@ static void FPT_BusMasterInit(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_DiagEEPROM(unsigned long p_port) +static void FPT_DiagEEPROM(ULONG p_port) { - unsigned short index, temp, max_wd_cnt; + USHORT index,temp,max_wd_cnt; - if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD) - max_wd_cnt = EEPROM_WD_CNT; - else - max_wd_cnt = EEPROM_WD_CNT * 2; + if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD) + max_wd_cnt = EEPROM_WD_CNT; + else + max_wd_cnt = EEPROM_WD_CNT * 2; - temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2); + temp = FPT_utilEERead(p_port, FW_SIGNATURE/2); - if (temp == 0x4641) { + if (temp == 0x4641) { - for (index = 2; index < max_wd_cnt; index++) { + for (index = 2; index < max_wd_cnt; index++) { - temp += FPT_utilEERead(p_port, index); + temp += FPT_utilEERead(p_port, index); - } + } - if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) { + if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) { - return; /*EEPROM is Okay so return now! */ - } - } + return; /*EEPROM is Okay so return now! */ + } + } - FPT_utilEEWriteOnOff(p_port, (unsigned char)1); - for (index = 0; index < max_wd_cnt; index++) { + FPT_utilEEWriteOnOff(p_port,(UCHAR)1); - FPT_utilEEWrite(p_port, 0x0000, index); - } + for (index = 0; index < max_wd_cnt; index++) { + + FPT_utilEEWrite(p_port, 0x0000, index); + } - temp = 0; - - FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2); - temp += 0x4641; - FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2); - temp += 0x3920; - FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2); - temp += 0x3033; - FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2); - temp += 0x2020; - FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2); - temp += 0x70D3; - FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2); - temp += 0x0010; - FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2); - temp += 0x0003; - FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2); - temp += 0x0007; - - FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2); - temp += 0x0000; - FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2); - temp += 0x0000; - FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2); - temp += 0x0000; - - FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2); - temp += 0x4242; - FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2); - temp += 0x4242; - FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2); - temp += 0x4242; - FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2); - temp += 0x4242; - FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2); - temp += 0x4242; - FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2); - temp += 0x4242; - FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2); - temp += 0x4242; - FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2); - temp += 0x4242; - - FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */ - temp += 0x6C46; - FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */ - temp += 0x7361; - FPT_utilEEWrite(p_port, 0x5068, 68 / 2); - temp += 0x5068; - FPT_utilEEWrite(p_port, 0x696F, 70 / 2); - temp += 0x696F; - FPT_utilEEWrite(p_port, 0x746E, 72 / 2); - temp += 0x746E; - FPT_utilEEWrite(p_port, 0x4C20, 74 / 2); - temp += 0x4C20; - FPT_utilEEWrite(p_port, 0x2054, 76 / 2); - temp += 0x2054; - FPT_utilEEWrite(p_port, 0x2020, 78 / 2); - temp += 0x2020; - - index = ((EE_SCAMBASE / 2) + (7 * 16)); - FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index); - temp += (0x0700 + TYPE_CODE0); - index++; - FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */ - temp += 0x5542; /* BUSLOGIC */ - index++; - FPT_utilEEWrite(p_port, 0x4C53, index); - temp += 0x4C53; - index++; - FPT_utilEEWrite(p_port, 0x474F, index); - temp += 0x474F; - index++; - FPT_utilEEWrite(p_port, 0x4349, index); - temp += 0x4349; - index++; - FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */ - temp += 0x5442; /* BT- 930 */ - index++; - FPT_utilEEWrite(p_port, 0x202D, index); - temp += 0x202D; - index++; - FPT_utilEEWrite(p_port, 0x3339, index); - temp += 0x3339; - index++; /*Serial # */ - FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */ - temp += 0x2030; - index++; - FPT_utilEEWrite(p_port, 0x5453, index); - temp += 0x5453; - index++; - FPT_utilEEWrite(p_port, 0x5645, index); - temp += 0x5645; - index++; - FPT_utilEEWrite(p_port, 0x2045, index); - temp += 0x2045; - index++; - FPT_utilEEWrite(p_port, 0x202F, index); - temp += 0x202F; - index++; - FPT_utilEEWrite(p_port, 0x4F4A, index); - temp += 0x4F4A; - index++; - FPT_utilEEWrite(p_port, 0x204E, index); - temp += 0x204E; - index++; - FPT_utilEEWrite(p_port, 0x3539, index); - temp += 0x3539; - - FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2); - - FPT_utilEEWriteOnOff(p_port, (unsigned char)0); + temp = 0; + + FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2); + temp += 0x4641; + FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2); + temp += 0x3920; + FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2); + temp += 0x3033; + FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2); + temp += 0x2020; + FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2); + temp += 0x70D3; + FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2); + temp += 0x0010; + FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2); + temp += 0x0003; + FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2); + temp += 0x0007; + + FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2); + temp += 0x0000; + FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2); + temp += 0x0000; + FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2); + temp += 0x0000; + + FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2); + temp += 0x4242; + FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2); + temp += 0x4242; + FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2); + temp += 0x4242; + FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2); + temp += 0x4242; + FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2); + temp += 0x4242; + FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2); + temp += 0x4242; + FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2); + temp += 0x4242; + FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2); + temp += 0x4242; + + + FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */ + temp += 0x6C46; + FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */ + temp += 0x7361; + FPT_utilEEWrite(p_port, 0x5068, 68/2); + temp += 0x5068; + FPT_utilEEWrite(p_port, 0x696F, 70/2); + temp += 0x696F; + FPT_utilEEWrite(p_port, 0x746E, 72/2); + temp += 0x746E; + FPT_utilEEWrite(p_port, 0x4C20, 74/2); + temp += 0x4C20; + FPT_utilEEWrite(p_port, 0x2054, 76/2); + temp += 0x2054; + FPT_utilEEWrite(p_port, 0x2020, 78/2); + temp += 0x2020; + + index = ((EE_SCAMBASE/2)+(7*16)); + FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index); + temp += (0x0700+TYPE_CODE0); + index++; + FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */ + temp += 0x5542; /* BUSLOGIC */ + index++; + FPT_utilEEWrite(p_port, 0x4C53, index); + temp += 0x4C53; + index++; + FPT_utilEEWrite(p_port, 0x474F, index); + temp += 0x474F; + index++; + FPT_utilEEWrite(p_port, 0x4349, index); + temp += 0x4349; + index++; + FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */ + temp += 0x5442; /* BT- 930 */ + index++; + FPT_utilEEWrite(p_port, 0x202D, index); + temp += 0x202D; + index++; + FPT_utilEEWrite(p_port, 0x3339, index); + temp += 0x3339; + index++; /*Serial # */ + FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */ + temp += 0x2030; + index++; + FPT_utilEEWrite(p_port, 0x5453, index); + temp += 0x5453; + index++; + FPT_utilEEWrite(p_port, 0x5645, index); + temp += 0x5645; + index++; + FPT_utilEEWrite(p_port, 0x2045, index); + temp += 0x2045; + index++; + FPT_utilEEWrite(p_port, 0x202F, index); + temp += 0x202F; + index++; + FPT_utilEEWrite(p_port, 0x4F4A, index); + temp += 0x4F4A; + index++; + FPT_utilEEWrite(p_port, 0x204E, index); + temp += 0x204E; + index++; + FPT_utilEEWrite(p_port, 0x3539, index); + temp += 0x3539; + + + + FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2); + + FPT_utilEEWriteOnOff(p_port,(UCHAR)0); } + /*--------------------------------------------------------------------- * * Function: Queue Search Select @@ -6717,127 +7305,103 @@ static void FPT_DiagEEPROM(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_queueSearchSelect(struct sccb_card *pCurrCard, - unsigned char p_card) +static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card) { - unsigned char scan_ptr, lun; - struct sccb_mgr_tar_info *currTar_Info; - struct sccb *pOldSccb; + UCHAR scan_ptr, lun; + PSCCBMgr_tar_info currTar_Info; + PSCCB pOldSccb; - scan_ptr = pCurrCard->scanIndex; - do { + scan_ptr = pCurrCard->scanIndex; + do + { currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr]; - if ((pCurrCard->globalFlags & F_CONLUN_IO) && - ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != - TAG_Q_TRYING)) { - if (currTar_Info->TarSelQ_Cnt != 0) { + if((pCurrCard->globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) + { + if (currTar_Info->TarSelQ_Cnt != 0) + { scan_ptr++; if (scan_ptr == MAX_SCSI_TAR) scan_ptr = 0; + + for(lun=0; lun < MAX_LUN; lun++) + { + if(currTar_Info->TarLUNBusy[lun] == 0) + { - for (lun = 0; lun < MAX_LUN; lun++) { - if (currTar_Info->TarLUNBusy[lun] == 0) { - - pCurrCard->currentSCCB = - currTar_Info->TarSelQ_Head; + pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head; pOldSccb = NULL; - while ((pCurrCard-> - currentSCCB != NULL) - && (lun != - pCurrCard-> - currentSCCB->Lun)) { - pOldSccb = - pCurrCard-> - currentSCCB; - pCurrCard->currentSCCB = - (struct sccb - *)(pCurrCard-> - currentSCCB)-> - Sccb_forwardlink; + while((pCurrCard->currentSCCB != NULL) && + (lun != pCurrCard->currentSCCB->Lun)) + { + pOldSccb = pCurrCard->currentSCCB; + pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)-> + Sccb_forwardlink; } - if (pCurrCard->currentSCCB == - NULL) + if(pCurrCard->currentSCCB == NULL) continue; - if (pOldSccb != NULL) { - pOldSccb-> - Sccb_forwardlink = - (struct sccb - *)(pCurrCard-> - currentSCCB)-> - Sccb_forwardlink; - pOldSccb-> - Sccb_backlink = - (struct sccb - *)(pCurrCard-> - currentSCCB)-> - Sccb_backlink; - currTar_Info-> - TarSelQ_Cnt--; - } else { - currTar_Info-> - TarSelQ_Head = - (struct sccb - *)(pCurrCard-> - currentSCCB)-> - Sccb_forwardlink; - - if (currTar_Info-> - TarSelQ_Head == - NULL) { - currTar_Info-> - TarSelQ_Tail - = NULL; - currTar_Info-> - TarSelQ_Cnt - = 0; - } else { - currTar_Info-> - TarSelQ_Cnt--; - currTar_Info-> - TarSelQ_Head-> - Sccb_backlink - = - (struct sccb - *)NULL; + if(pOldSccb != NULL) + { + pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)-> + Sccb_forwardlink; + pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)-> + Sccb_backlink; + currTar_Info->TarSelQ_Cnt--; + } + else + { + currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink; + + if (currTar_Info->TarSelQ_Head == NULL) + { + currTar_Info->TarSelQ_Tail = NULL; + currTar_Info->TarSelQ_Cnt = 0; + } + else + { + currTar_Info->TarSelQ_Cnt--; + currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL; } } - pCurrCard->scanIndex = scan_ptr; + pCurrCard->scanIndex = scan_ptr; - pCurrCard->globalFlags |= - F_NEW_SCCB_CMD; + pCurrCard->globalFlags |= F_NEW_SCCB_CMD; - break; + break; } } } - else { + else + { scan_ptr++; if (scan_ptr == MAX_SCSI_TAR) { scan_ptr = 0; } } - } else { + } + else + { if ((currTar_Info->TarSelQ_Cnt != 0) && - (currTar_Info->TarLUNBusy[0] == 0)) { + (currTar_Info->TarLUNBusy[0] == 0)) + { - pCurrCard->currentSCCB = - currTar_Info->TarSelQ_Head; + pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head; - currTar_Info->TarSelQ_Head = - (struct sccb *)(pCurrCard->currentSCCB)-> - Sccb_forwardlink; + currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink; - if (currTar_Info->TarSelQ_Head == NULL) { + if (currTar_Info->TarSelQ_Head == NULL) + { currTar_Info->TarSelQ_Tail = NULL; currTar_Info->TarSelQ_Cnt = 0; - } else { + } + else + { currTar_Info->TarSelQ_Cnt--; - currTar_Info->TarSelQ_Head-> - Sccb_backlink = (struct sccb *)NULL; + currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL; } scan_ptr++; @@ -6851,9 +7415,11 @@ static void FPT_queueSearchSelect(struct sccb_card *pCurrCard, break; } - else { + else + { scan_ptr++; - if (scan_ptr == MAX_SCSI_TAR) { + if (scan_ptr == MAX_SCSI_TAR) + { scan_ptr = 0; } } @@ -6861,6 +7427,7 @@ static void FPT_queueSearchSelect(struct sccb_card *pCurrCard, } while (scan_ptr != pCurrCard->scanIndex); } + /*--------------------------------------------------------------------- * * Function: Queue Select Fail @@ -6869,39 +7436,37 @@ static void FPT_queueSearchSelect(struct sccb_card *pCurrCard, * *---------------------------------------------------------------------*/ -static void FPT_queueSelectFail(struct sccb_card *pCurrCard, - unsigned char p_card) +static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card) { - unsigned char thisTarg; - struct sccb_mgr_tar_info *currTar_Info; + UCHAR thisTarg; + PSCCBMgr_tar_info currTar_Info; - if (pCurrCard->currentSCCB != NULL) { - thisTarg = - (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))-> - TargID); - currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; + if (pCurrCard->currentSCCB != NULL) + { + thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID); + currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; - pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL; + pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL; - pCurrCard->currentSCCB->Sccb_forwardlink = - currTar_Info->TarSelQ_Head; + pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head; - if (currTar_Info->TarSelQ_Cnt == 0) { - currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB; - } + if (currTar_Info->TarSelQ_Cnt == 0) + { + currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB; + } - else { - currTar_Info->TarSelQ_Head->Sccb_backlink = - pCurrCard->currentSCCB; - } + else + { + currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB; + } - currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB; - pCurrCard->currentSCCB = NULL; - currTar_Info->TarSelQ_Cnt++; - } -} + currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB; + pCurrCard->currentSCCB = NULL; + currTar_Info->TarSelQ_Cnt++; + } +} /*--------------------------------------------------------------------- * * Function: Queue Command Complete @@ -6910,97 +7475,101 @@ static void FPT_queueSelectFail(struct sccb_card *pCurrCard, * *---------------------------------------------------------------------*/ -static void FPT_queueCmdComplete(struct sccb_card *pCurrCard, - struct sccb *p_sccb, unsigned char p_card) +static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb, + UCHAR p_card) { - unsigned char i, SCSIcmd; - CALL_BK_FN callback; - struct sccb_mgr_tar_info *currTar_Info; - - SCSIcmd = p_sccb->Cdb[0]; - - if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) { - - if ((p_sccb-> - ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) - && (p_sccb->HostStatus == SCCB_COMPLETE) - && (p_sccb->TargetStatus != SSCHECK)) - - if ((SCSIcmd == SCSI_READ) || - (SCSIcmd == SCSI_WRITE) || - (SCSIcmd == SCSI_READ_EXTENDED) || - (SCSIcmd == SCSI_WRITE_EXTENDED) || - (SCSIcmd == SCSI_WRITE_AND_VERIFY) || - (SCSIcmd == SCSI_START_STOP_UNIT) || - (pCurrCard->globalFlags & F_NO_FILTER) - ) - p_sccb->HostStatus = SCCB_DATA_UNDER_RUN; - } + UCHAR i, SCSIcmd; + CALL_BK_FN callback; + PSCCBMgr_tar_info currTar_Info; - if (p_sccb->SccbStatus == SCCB_IN_PROCESS) { - if (p_sccb->HostStatus || p_sccb->TargetStatus) - p_sccb->SccbStatus = SCCB_ERROR; - else - p_sccb->SccbStatus = SCCB_SUCCESS; - } + SCSIcmd = p_sccb->Cdb[0]; - if (p_sccb->Sccb_XferState & F_AUTO_SENSE) { - p_sccb->CdbLength = p_sccb->Save_CdbLen; - for (i = 0; i < 6; i++) { - p_sccb->Cdb[i] = p_sccb->Save_Cdb[i]; - } - } + if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) { - if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) || - (p_sccb->OperationCode == RESIDUAL_COMMAND)) { + if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) && + (p_sccb->HostStatus == SCCB_COMPLETE) && + (p_sccb->TargetStatus != SSCHECK)) - FPT_utilUpdateResidual(p_sccb); + if ((SCSIcmd == SCSI_READ) || + (SCSIcmd == SCSI_WRITE) || + (SCSIcmd == SCSI_READ_EXTENDED) || + (SCSIcmd == SCSI_WRITE_EXTENDED) || + (SCSIcmd == SCSI_WRITE_AND_VERIFY) || + (SCSIcmd == SCSI_START_STOP_UNIT) || + (pCurrCard->globalFlags & F_NO_FILTER) + ) + p_sccb->HostStatus = SCCB_DATA_UNDER_RUN; + } + + + if(p_sccb->SccbStatus == SCCB_IN_PROCESS) + { + if (p_sccb->HostStatus || p_sccb->TargetStatus) + p_sccb->SccbStatus = SCCB_ERROR; + else + p_sccb->SccbStatus = SCCB_SUCCESS; } - pCurrCard->cmdCounter--; - if (!pCurrCard->cmdCounter) { + if (p_sccb->Sccb_XferState & F_AUTO_SENSE) { - if (pCurrCard->globalFlags & F_GREEN_PC) { - WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0, - (PWR_DWN | CLKCTRL_DEFAULT)); - WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK); - } + p_sccb->CdbLength = p_sccb->Save_CdbLen; + for (i=0; i < 6; i++) { + p_sccb->Cdb[i] = p_sccb->Save_Cdb[i]; + } + } - WR_HARPOON(pCurrCard->ioPort + hp_semaphore, - (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) & - ~SCCB_MGR_ACTIVE)); + if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) || + (p_sccb->OperationCode == RESIDUAL_COMMAND)) { - } + FPT_utilUpdateResidual(p_sccb); + } + + pCurrCard->cmdCounter--; + if (!pCurrCard->cmdCounter) { + + if (pCurrCard->globalFlags & F_GREEN_PC) { + WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT)); + WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK); + } - if (pCurrCard->discQCount != 0) { - currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; - if (((pCurrCard->globalFlags & F_CONLUN_IO) && - ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != - TAG_Q_TRYING))) { + WR_HARPOON(pCurrCard->ioPort+hp_semaphore, + (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE)); + + } + + if(pCurrCard->discQCount != 0) + { + currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; + if(((pCurrCard->globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + { pCurrCard->discQCount--; - pCurrCard->discQ_Tbl[currTar_Info-> - LunDiscQ_Idx[p_sccb->Lun]] = NULL; - } else { - if (p_sccb->Sccb_tag) { + pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL; + } + else + { + if(p_sccb->Sccb_tag) + { pCurrCard->discQCount--; pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL; - } else { + }else + { pCurrCard->discQCount--; - pCurrCard->discQ_Tbl[currTar_Info-> - LunDiscQ_Idx[0]] = NULL; + pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL; } } } - callback = (CALL_BK_FN) p_sccb->SccbCallback; - callback(p_sccb); - pCurrCard->globalFlags |= F_NEW_SCCB_CMD; - pCurrCard->currentSCCB = NULL; + callback = (CALL_BK_FN)p_sccb->SccbCallback; + callback(p_sccb); + pCurrCard->globalFlags |= F_NEW_SCCB_CMD; + pCurrCard->currentSCCB = NULL; } + /*--------------------------------------------------------------------- * * Function: Queue Disconnect @@ -7008,32 +7577,33 @@ static void FPT_queueCmdComplete(struct sccb_card *pCurrCard, * Description: Add SCCB to our disconnect array. * *---------------------------------------------------------------------*/ -static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card) +static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card) { - struct sccb_mgr_tar_info *currTar_Info; + PSCCBMgr_tar_info currTar_Info; currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; - if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && - ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { - FPT_BL_Card[p_card].discQ_Tbl[currTar_Info-> - LunDiscQ_Idx[p_sccb->Lun]] = - p_sccb; - } else { - if (p_sccb->Sccb_tag) { - FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = - p_sccb; - FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = - 0; + if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && + ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) + { + FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb; + } + else + { + if (p_sccb->Sccb_tag) + { + FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb; + FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0; FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++; - } else { - FPT_BL_Card[p_card].discQ_Tbl[currTar_Info-> - LunDiscQ_Idx[0]] = p_sccb; + }else + { + FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb; } } FPT_BL_Card[p_card].currentSCCB = NULL; } + /*--------------------------------------------------------------------- * * Function: Queue Flush SCCB @@ -7042,35 +7612,33 @@ static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code) +static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code) { - unsigned char qtag, thisTarg; - struct sccb *currSCCB; - struct sccb_mgr_tar_info *currTar_Info; - - currSCCB = FPT_BL_Card[p_card].currentSCCB; - if (currSCCB != NULL) { - thisTarg = (unsigned char)currSCCB->TargID; - currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; + UCHAR qtag,thisTarg; + PSCCB currSCCB; + PSCCBMgr_tar_info currTar_Info; - for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) { + currSCCB = FPT_BL_Card[p_card].currentSCCB; + if(currSCCB != NULL) + { + thisTarg = (UCHAR)currSCCB->TargID; + currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; - if (FPT_BL_Card[p_card].discQ_Tbl[qtag] && - (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == - thisTarg)) { + for (qtag=0; qtag - HostStatus = (unsigned char)error_code; + if (FPT_BL_Card[p_card].discQ_Tbl[qtag] && + (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) + { - FPT_queueCmdComplete(&FPT_BL_Card[p_card], - FPT_BL_Card[p_card]. - discQ_Tbl[qtag], p_card); + FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code; + + FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card); - FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; - currTar_Info->TarTagQ_Cnt--; + FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; + currTar_Info->TarTagQ_Cnt--; - } - } + } + } } } @@ -7083,57 +7651,61 @@ static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code) * *---------------------------------------------------------------------*/ -static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg, - unsigned char error_code) +static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, + UCHAR error_code) { - unsigned char qtag; - struct sccb_mgr_tar_info *currTar_Info; + UCHAR qtag; + PSCCBMgr_tar_info currTar_Info; - currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; + currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; - for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) { + for (qtag=0; qtagTargID == thisTarg)) { + if (FPT_BL_Card[p_card].discQ_Tbl[qtag] && + (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) + { - FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = - (unsigned char)error_code; + FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code; - FPT_queueCmdComplete(&FPT_BL_Card[p_card], - FPT_BL_Card[p_card]. - discQ_Tbl[qtag], p_card); + FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card); - FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; - currTar_Info->TarTagQ_Cnt--; + FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; + currTar_Info->TarTagQ_Cnt--; - } - } + } + } } -static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card) + + + + +static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card) { - struct sccb_mgr_tar_info *currTar_Info; - currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID]; + PSCCBMgr_tar_info currTar_Info; + currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID]; - p_SCCB->Sccb_forwardlink = NULL; + p_SCCB->Sccb_forwardlink = NULL; - p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail; + p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail; - if (currTar_Info->TarSelQ_Cnt == 0) { + if (currTar_Info->TarSelQ_Cnt == 0) { - currTar_Info->TarSelQ_Head = p_SCCB; - } + currTar_Info->TarSelQ_Head = p_SCCB; + } - else { + else { - currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB; - } + currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB; + } - currTar_Info->TarSelQ_Tail = p_SCCB; - currTar_Info->TarSelQ_Cnt++; + + currTar_Info->TarSelQ_Tail = p_SCCB; + currTar_Info->TarSelQ_Cnt++; } + /*--------------------------------------------------------------------- * * Function: Queue Find SCCB @@ -7143,56 +7715,54 @@ static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card) * *---------------------------------------------------------------------*/ -static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB, - unsigned char p_card) +static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card) { - struct sccb *q_ptr; - struct sccb_mgr_tar_info *currTar_Info; + PSCCB q_ptr; + PSCCBMgr_tar_info currTar_Info; - currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID]; + currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID]; - q_ptr = currTar_Info->TarSelQ_Head; + q_ptr = currTar_Info->TarSelQ_Head; - while (q_ptr != NULL) { + while(q_ptr != NULL) { - if (q_ptr == p_SCCB) { + if (q_ptr == p_SCCB) { - if (currTar_Info->TarSelQ_Head == q_ptr) { - currTar_Info->TarSelQ_Head = - q_ptr->Sccb_forwardlink; + if (currTar_Info->TarSelQ_Head == q_ptr) { + + currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink; } - if (currTar_Info->TarSelQ_Tail == q_ptr) { + if (currTar_Info->TarSelQ_Tail == q_ptr) { - currTar_Info->TarSelQ_Tail = - q_ptr->Sccb_backlink; + currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink; } - if (q_ptr->Sccb_forwardlink != NULL) { - q_ptr->Sccb_forwardlink->Sccb_backlink = - q_ptr->Sccb_backlink; + if (q_ptr->Sccb_forwardlink != NULL) { + q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink; } - if (q_ptr->Sccb_backlink != NULL) { - q_ptr->Sccb_backlink->Sccb_forwardlink = - q_ptr->Sccb_forwardlink; + if (q_ptr->Sccb_backlink != NULL) { + q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink; } - currTar_Info->TarSelQ_Cnt--; + currTar_Info->TarSelQ_Cnt--; - return 1; - } + return(1); + } - else { - q_ptr = q_ptr->Sccb_forwardlink; - } - } + else { + q_ptr = q_ptr->Sccb_forwardlink; + } + } - return 0; + + return(0); } + /*--------------------------------------------------------------------- * * Function: Utility Update Residual Count @@ -7206,47 +7776,48 @@ static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB, * *---------------------------------------------------------------------*/ -static void FPT_utilUpdateResidual(struct sccb *p_SCCB) +static void FPT_utilUpdateResidual(PSCCB p_SCCB) { - unsigned long partial_cnt; - unsigned int sg_index; - unsigned long *sg_ptr; + ULONG partial_cnt; + UINT sg_index; + ULONG *sg_ptr; - if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) { + if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) { - p_SCCB->DataLength = 0x0000; - } + p_SCCB->DataLength = 0x0000; + } - else if (p_SCCB->Sccb_XferState & F_SG_XFER) { + else if (p_SCCB->Sccb_XferState & F_SG_XFER) { - partial_cnt = 0x0000; + partial_cnt = 0x0000; - sg_index = p_SCCB->Sccb_sgseg; + sg_index = p_SCCB->Sccb_sgseg; - sg_ptr = (unsigned long *)p_SCCB->DataPointer; + sg_ptr = (ULONG *)p_SCCB->DataPointer; - if (p_SCCB->Sccb_SGoffset) { + if (p_SCCB->Sccb_SGoffset) { partial_cnt = p_SCCB->Sccb_SGoffset; sg_index++; - } + } - while (((unsigned long)sg_index * - (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) { + while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) < + p_SCCB->DataLength ) { - partial_cnt += *(sg_ptr + (sg_index * 2)); + partial_cnt += *(sg_ptr+(sg_index * 2)); sg_index++; - } + } - p_SCCB->DataLength = partial_cnt; - } + p_SCCB->DataLength = partial_cnt; + } - else { + else { - p_SCCB->DataLength -= p_SCCB->Sccb_ATC; - } + p_SCCB->DataLength -= p_SCCB->Sccb_ATC; + } } + /*--------------------------------------------------------------------- * * Function: Wait 1 Second @@ -7255,22 +7826,23 @@ static void FPT_utilUpdateResidual(struct sccb *p_SCCB) * *---------------------------------------------------------------------*/ -static void FPT_Wait1Second(unsigned long p_port) +static void FPT_Wait1Second(ULONG p_port) { - unsigned char i; + UCHAR i; - for (i = 0; i < 4; i++) { + for(i=0; i < 4; i++) { - FPT_Wait(p_port, TO_250ms); + FPT_Wait(p_port, TO_250ms); - if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST)) - break; + if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST)) + break; - if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) - break; - } + if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) + break; + } } + /*--------------------------------------------------------------------- * * Function: FPT_Wait @@ -7279,43 +7851,45 @@ static void FPT_Wait1Second(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_Wait(unsigned long p_port, unsigned char p_delay) +static void FPT_Wait(ULONG p_port, UCHAR p_delay) { - unsigned char old_timer; - unsigned char green_flag; + UCHAR old_timer; + UCHAR green_flag; - old_timer = RD_HARPOON(p_port + hp_seltimeout); + old_timer = RD_HARPOON(p_port+hp_seltimeout); - green_flag = RD_HARPOON(p_port + hp_clkctrl_0); - WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT); + green_flag=RD_HARPOON(p_port+hp_clkctrl_0); + WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT); - WR_HARPOON(p_port + hp_seltimeout, p_delay); - WRW_HARPOON((p_port + hp_intstat), TIMEOUT); - WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT)); + WR_HARPOON(p_port+hp_seltimeout,p_delay); + WRW_HARPOON((p_port+hp_intstat), TIMEOUT); + WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT)); - WR_HARPOON(p_port + hp_portctrl_0, - (RD_HARPOON(p_port + hp_portctrl_0) | START_TO)); - while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) { + WR_HARPOON(p_port+hp_portctrl_0, + (RD_HARPOON(p_port+hp_portctrl_0) | START_TO)); - if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST)) - break; + while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) { - if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) - break; - } + if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST)) + break; + + if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) + break; + } - WR_HARPOON(p_port + hp_portctrl_0, - (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO)); + WR_HARPOON(p_port+hp_portctrl_0, + (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO)); - WRW_HARPOON((p_port + hp_intstat), TIMEOUT); - WRW_HARPOON((p_port + hp_intena), FPT_default_intena); + WRW_HARPOON((p_port+hp_intstat), TIMEOUT); + WRW_HARPOON((p_port+hp_intena), FPT_default_intena); - WR_HARPOON(p_port + hp_clkctrl_0, green_flag); + WR_HARPOON(p_port+hp_clkctrl_0,green_flag); - WR_HARPOON(p_port + hp_seltimeout, old_timer); + WR_HARPOON(p_port+hp_seltimeout,old_timer); } + /*--------------------------------------------------------------------- * * Function: Enable/Disable Write to EEPROM @@ -7325,26 +7899,26 @@ static void FPT_Wait(unsigned long p_port, unsigned char p_delay) * *---------------------------------------------------------------------*/ -static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode) +static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode) { - unsigned char ee_value; + UCHAR ee_value; - ee_value = - (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) & - (EXT_ARB_ACK | SCSI_TERM_ENA_H)); + ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H)); - if (p_mode) + if (p_mode) - FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR); + FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR); + + else - else - FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR); + FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR); - WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */ - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */ + WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */ + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */ } + /*--------------------------------------------------------------------- * * Function: Write EEPROM @@ -7354,46 +7928,46 @@ static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode) * *---------------------------------------------------------------------*/ -static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, - unsigned short ee_addr) +static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr) { - unsigned char ee_value; - unsigned short i; + UCHAR ee_value; + USHORT i; - ee_value = - (unsigned - char)((RD_HARPOON(p_port + hp_ee_ctrl) & - (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS)); + ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))| + (SEE_MS | SEE_CS)); - FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr); - ee_value |= (SEE_MS + SEE_CS); - for (i = 0x8000; i != 0; i >>= 1) { + FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr); - if (i & ee_data) - ee_value |= SEE_DO; - else - ee_value &= ~SEE_DO; - - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - ee_value |= SEE_CLK; /* Clock data! */ - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - ee_value &= ~SEE_CLK; - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - } - ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H); - WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); - FPT_Wait(p_port, TO_10ms); + ee_value |= (SEE_MS + SEE_CS); + + for(i = 0x8000; i != 0; i>>=1) { - WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */ - WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */ - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */ + if (i & ee_data) + ee_value |= SEE_DO; + else + ee_value &= ~SEE_DO; + + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + ee_value |= SEE_CLK; /* Clock data! */ + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + ee_value &= ~SEE_CLK; + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + } + ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H); + WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); + + FPT_Wait(p_port, TO_10ms); + + WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */ + WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */ + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */ } /*--------------------------------------------------------------------- @@ -7405,25 +7979,25 @@ static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, * *---------------------------------------------------------------------*/ -static unsigned short FPT_utilEERead(unsigned long p_port, - unsigned short ee_addr) +static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr) { - unsigned short i, ee_data1, ee_data2; + USHORT i, ee_data1, ee_data2; i = 0; ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr); - do { + do + { ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr); - if (ee_data1 == ee_data2) - return ee_data1; + if(ee_data1 == ee_data2) + return(ee_data1); ee_data1 = ee_data2; i++; - } while (i < 4); + }while(i < 4); - return ee_data1; + return(ee_data1); } /*--------------------------------------------------------------------- @@ -7435,45 +8009,45 @@ static unsigned short FPT_utilEERead(unsigned long p_port, * *---------------------------------------------------------------------*/ -static unsigned short FPT_utilEEReadOrg(unsigned long p_port, - unsigned short ee_addr) +static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr) { - unsigned char ee_value; - unsigned short i, ee_data; + UCHAR ee_value; + USHORT i, ee_data; - ee_value = - (unsigned - char)((RD_HARPOON(p_port + hp_ee_ctrl) & - (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS)); + ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))| + (SEE_MS | SEE_CS)); - FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr); - ee_value |= (SEE_MS + SEE_CS); - ee_data = 0; + FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr); - for (i = 1; i <= 16; i++) { - ee_value |= SEE_CLK; /* Clock data! */ - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - ee_value &= ~SEE_CLK; - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); + ee_value |= (SEE_MS + SEE_CS); + ee_data = 0; - ee_data <<= 1; + for(i = 1; i <= 16; i++) { - if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI) - ee_data |= 1; - } + ee_value |= SEE_CLK; /* Clock data! */ + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + ee_value &= ~SEE_CLK; + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + + ee_data <<= 1; - ee_value &= ~(SEE_MS + SEE_CS); - WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */ - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */ + if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI) + ee_data |= 1; + } - return ee_data; + ee_value &= ~(SEE_MS + SEE_CS); + WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */ + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */ + + return(ee_data); } + /*--------------------------------------------------------------------- * * Function: Send EE command and Address to the EEPROM @@ -7483,95 +8057,101 @@ static unsigned short FPT_utilEEReadOrg(unsigned long p_port, * *---------------------------------------------------------------------*/ -static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, - unsigned short ee_addr) +static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr) { - unsigned char ee_value; - unsigned char narrow_flg; + UCHAR ee_value; + UCHAR narrow_flg; - unsigned short i; + USHORT i; - narrow_flg = - (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) & - NARROW_SCSI_CARD); - ee_value = SEE_MS; - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); + narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD); - ee_value |= SEE_CS; /* Set CS to EEPROM */ - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - for (i = 0x04; i != 0; i >>= 1) { + ee_value = SEE_MS; + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); - if (i & ee_cmd) - ee_value |= SEE_DO; - else - ee_value &= ~SEE_DO; - - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - ee_value |= SEE_CLK; /* Clock data! */ - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - ee_value &= ~SEE_CLK; - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - } + ee_value |= SEE_CS; /* Set CS to EEPROM */ + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); - if (narrow_flg) - i = 0x0080; - else - i = 0x0200; + for(i = 0x04; i != 0; i>>=1) { - while (i != 0) { + if (i & ee_cmd) + ee_value |= SEE_DO; + else + ee_value &= ~SEE_DO; - if (i & ee_addr) - ee_value |= SEE_DO; - else - ee_value &= ~SEE_DO; - - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - ee_value |= SEE_CLK; /* Clock data! */ - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - ee_value &= ~SEE_CLK; - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - WR_HARPOON(p_port + hp_ee_ctrl, ee_value); - - i >>= 1; - } + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + ee_value |= SEE_CLK; /* Clock data! */ + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + ee_value &= ~SEE_CLK; + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + } + + + if (narrow_flg) + i = 0x0080; + + else + i = 0x0200; + + + while (i != 0) { + + if (i & ee_addr) + ee_value |= SEE_DO; + else + ee_value &= ~SEE_DO; + + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + ee_value |= SEE_CLK; /* Clock data! */ + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + ee_value &= ~SEE_CLK; + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + + i >>= 1; + } } -static unsigned short FPT_CalcCrc16(unsigned char buffer[]) +static USHORT FPT_CalcCrc16(UCHAR buffer[]) { - unsigned short crc = 0; - int i, j; - unsigned short ch; - for (i = 0; i < ID_STRING_LENGTH; i++) { - ch = (unsigned short)buffer[i]; - for (j = 0; j < 8; j++) { - if ((crc ^ ch) & 1) - crc = (crc >> 1) ^ CRCMASK; - else - crc >>= 1; - ch >>= 1; - } - } - return crc; + USHORT crc=0; + int i,j; + USHORT ch; + for (i=0; i < ID_STRING_LENGTH; i++) + { + ch = (USHORT) buffer[i]; + for(j=0; j < 8; j++) + { + if ((crc ^ ch) & 1) + crc = (crc >> 1) ^ CRCMASK; + else + crc >>= 1; + ch >>= 1; + } + } + return(crc); } -static unsigned char FPT_CalcLrc(unsigned char buffer[]) +static UCHAR FPT_CalcLrc(UCHAR buffer[]) { int i; - unsigned char lrc; + UCHAR lrc; lrc = 0; - for (i = 0; i < ID_STRING_LENGTH; i++) + for(i = 0; i < ID_STRING_LENGTH; i++) lrc ^= buffer[i]; - return lrc; + return(lrc); } + + /* The following inline definitions avoid type conflicts. */ @@ -7579,49 +8159,51 @@ static unsigned char FPT_CalcLrc(unsigned char buffer[]) static inline unsigned char FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo) { - return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) - FlashPointInfo); + return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo); } + static inline FlashPoint_CardHandle_T FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo) { - return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) - FlashPointInfo); + return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo); } static inline void FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle) { - FlashPoint_ReleaseHostAdapter(CardHandle); + FlashPoint_ReleaseHostAdapter(CardHandle); } + static inline void -FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, - struct BusLogic_CCB *CCB) +FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB) { - FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB); + FlashPoint_StartCCB(CardHandle, (PSCCB) CCB); } + static inline void -FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, - struct BusLogic_CCB *CCB) +FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB) { - FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB); + FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB); } + static inline boolean FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle) { - return FlashPoint_InterruptPending(CardHandle); + return FlashPoint_InterruptPending(CardHandle); } + static inline int FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle) { - return FlashPoint_HandleInterrupt(CardHandle); + return FlashPoint_HandleInterrupt(CardHandle); } + #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter @@ -7630,7 +8212,9 @@ FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle) #define FlashPoint_InterruptPending FlashPoint__InterruptPending #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt -#else /* CONFIG_SCSI_OMIT_FLASHPOINT */ + +#else /* CONFIG_SCSI_OMIT_FLASHPOINT */ + /* Define prototypes for the FlashPoint SCCB Manager Functions. @@ -7638,11 +8222,12 @@ FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle) extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *); extern FlashPoint_CardHandle_T -FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *); + FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *); extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *); extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *); extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T); extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); -#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */ + +#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */ diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a480a3742..da70464f1 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -379,14 +379,6 @@ config SCSI_AHA1740 config SCSI_AACRAID tristate "Adaptec AACRAID support" depends on SCSI && PCI - help - This driver supports a variety of Dell, HP, Adaptec, IBM and - ICP storage products. For a list of supported products, refer - to . - - To compile this driver as a module, choose M here: the module - will be called aacraid. - source "drivers/scsi/aic7xxx/Kconfig.aic7xxx" @@ -532,6 +524,16 @@ config SCSI_PDC_ADMA If unsure, say N. +config SCSI_HPTIOP + tristate "HighPoint RocketRAID 3xxx Controller support" + depends on SCSI && PCI + help + This option enables support for HighPoint RocketRAID 3xxx + controllers. + + To compile this driver as a module, choose M here; the module + will be called hptiop. If unsure, say N. + config SCSI_SATA_QSTOR tristate "Pacific Digital SATA QStor support" depends on SCSI_SATA && PCI @@ -597,10 +599,10 @@ config SCSI_SATA_VIA If unsure, say N. config SCSI_SATA_VITESSE - tristate "VITESSE VSC-7174 / INTEL 31244 SATA support" + tristate "VITESSE VSC-7174 SATA support" depends on SCSI_SATA && PCI help - This option enables support for Vitesse VSC7174 and Intel 31244 Serial ATA. + This option enables support for Vitesse VSC7174 Serial ATA. If unsure, say N. @@ -1081,7 +1083,7 @@ config SCSI_SYM53C8XX_DMA_ADDRESSING_MODE memory using PCI DAC cycles. config SCSI_SYM53C8XX_DEFAULT_TAGS - int "Default tagged command queue depth" + int "default tagged command queue depth" depends on SCSI_SYM53C8XX_2 default "16" help @@ -1092,7 +1094,7 @@ config SCSI_SYM53C8XX_DEFAULT_TAGS exceed CONFIG_SCSI_SYM53C8XX_MAX_TAGS. config SCSI_SYM53C8XX_MAX_TAGS - int "Maximum number of queued commands" + int "maximum number of queued commands" depends on SCSI_SYM53C8XX_2 default "64" help @@ -1101,14 +1103,13 @@ config SCSI_SYM53C8XX_MAX_TAGS possible. The driver supports up to 256 queued commands per device. This value is used as a compiled-in hard limit. -config SCSI_SYM53C8XX_MMIO - bool "Use memory mapped IO" +config SCSI_SYM53C8XX_IOMAPPED + bool "use port IO" depends on SCSI_SYM53C8XX_2 - default y help - Memory mapped IO is faster than Port IO. Most people should - answer Y here, but some machines may have problems. If you have - to answer N here, please report the problem to the maintainer. + If you say Y here, the driver will use port IO to access + the card. This is significantly slower then using memory + mapped IO. Most people should answer N. config SCSI_IPR tristate "IBM Power Linux RAID adapter support" @@ -1312,6 +1313,15 @@ config SCSI_QLOGIC_FAS To compile this driver as a module, choose M here: the module will be called qlogicfas. +config SCSI_QLOGIC_FC + tristate "Qlogic ISP FC SCSI support" + depends on PCI && SCSI + help + This is a driver for the QLogic ISP2100 SCSI-FCP host adapter. + + To compile this driver as a module, choose M here: the + module will be called qlogicfc. + config SCSI_QLOGIC_FC_FIRMWARE bool "Include loadable firmware in driver" depends on SCSI_QLOGIC_FC diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 81803a16f..ddc0b3d50 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o +obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ obj-$(CONFIG_SCSI_LPFC) += lpfc/ @@ -116,6 +117,7 @@ obj-$(CONFIG_SCSI_PPA) += ppa.o obj-$(CONFIG_SCSI_IMM) += imm.o obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o +obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o obj-$(CONFIG_SCSI_FCAL) += fcal.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o @@ -136,6 +138,7 @@ obj-$(CONFIG_SCSI_SATA_NV) += libata.o sata_nv.o obj-$(CONFIG_SCSI_SATA_ULI) += libata.o sata_uli.o obj-$(CONFIG_SCSI_SATA_MV) += libata.o sata_mv.o obj-$(CONFIG_SCSI_PDC_ADMA) += libata.o pdc_adma.o +obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o obj-$(CONFIG_ARM) += arm/ @@ -146,9 +149,6 @@ obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o obj-$(CONFIG_CHR_DEV_SG) += sg.o obj-$(CONFIG_CHR_DEV_SCH) += ch.o -# This goes last, so that "real" scsi devices probe earlier -obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o - scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ scsicam.o scsi_error.o scsi_lib.o \ scsi_scan.o scsi_sysfs.o \ @@ -164,7 +164,7 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m) zalon7xx-objs := zalon.o ncr53c8xx.o NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o -libata-objs := libata-core.o libata-scsi.o libata-bmdma.o +libata-objs := libata-core.o libata-scsi.o oktagon_esp_mod-objs := oktagon_esp.o oktagon_io.o # Files generated that shall be removed upon make clean diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index 577e63499..e993a7ba2 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -218,7 +218,7 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, return 0; detect_failed: - release_region(region, 64); + release_region(host->base, 64); region_failed: kfree(hostdata); diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 3dce21c78..9f45ae174 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -89,7 +89,6 @@ #include #include #include -#include #include #include @@ -1053,7 +1052,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, 0xffffffffULL)) { printk(KERN_WARNING "Unable to set 32bit DMA " "on inia100 adapter, ignoring.\n"); goto out_disable_device; diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 642a3b4e5..a16f8ded8 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -149,20 +148,20 @@ static int dacmode = -1; static int commit = -1; -module_param(nondasd, int, S_IRUGO|S_IWUSR); +module_param(nondasd, int, 0); MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); -module_param(dacmode, int, S_IRUGO|S_IWUSR); +module_param(dacmode, int, 0); MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on"); -module_param(commit, int, S_IRUGO|S_IWUSR); +module_param(commit, int, 0); MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on"); int numacb = -1; module_param(numacb, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid values are 512 and down. Default is to use suggestion from Firmware."); +MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid\nvalues are 512 and down. Default is to use suggestion from Firmware."); int acbsize = -1; module_param(acbsize, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware."); +MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512,\n2048, 4096 and 8192. Default is to use suggestion from Firmware."); /** * aac_get_config_status - check the adapter configuration * @common: adapter to query @@ -387,7 +386,6 @@ static void get_container_name_callback(void *context, struct fib * fibptr) struct scsi_cmnd * scsicmd; scsicmd = (struct scsi_cmnd *) context; - scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); if (fibptr == NULL) @@ -454,10 +452,8 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) /* * Check that the command queued to the controller */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + if (status == -EINPROGRESS) return 0; - } printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status); aac_fib_complete(cmd_fibcontext); @@ -910,10 +906,9 @@ static void io_callback(void *context, struct fib * fibptr) u32 cid; scsicmd = (struct scsi_cmnd *) context; - scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dev = (struct aac_dev *)scsicmd->device->host->hostdata; - cid = scmd_id(scsicmd); + cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); if (nblank(dprintk(x))) { u64 lba; @@ -1155,10 +1150,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) /* * Check that the command queued to the controller */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + if (status == -EINPROGRESS) return 0; - } printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status); /* @@ -1324,8 +1317,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) /* * Check that the command queued to the controller */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + if (status == -EINPROGRESS) + { return 0; } @@ -1347,7 +1340,6 @@ static void synchronize_callback(void *context, struct fib *fibptr) struct scsi_cmnd *cmd; cmd = context; - cmd->SCp.phase = AAC_OWNER_MIDLEVEL; dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); @@ -1361,7 +1353,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) else { struct scsi_device *sdev = cmd->device; struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; - u32 cid = sdev_id(sdev); + u32 cid = ID_LUN_TO_CONTAINER(sdev->id, sdev->lun); printk(KERN_WARNING "synchronize_callback: synchronize failed, status = %d\n", le32_to_cpu(synchronizereply->status)); @@ -1393,12 +1385,12 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) unsigned long flags; /* - * Wait for all outstanding queued commands to complete to this - * specific target (block). + * Wait for all commands to complete to this specific + * target (block). */ spin_lock_irqsave(&sdev->list_lock, flags); list_for_each_entry(cmd, &sdev->cmd_list, list) - if (cmd != scsicmd && cmd->SCp.phase == AAC_OWNER_FIRMWARE) { + if (cmd != scsicmd && cmd->serial_number != 0) { ++active; break; } @@ -1441,10 +1433,8 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) /* * Check that the command queued to the controller */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + if (status == -EINPROGRESS) return 0; - } printk(KERN_WARNING "aac_synchronize: aac_fib_send failed with status: %d.\n", status); @@ -1467,6 +1457,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) struct Scsi_Host *host = scsicmd->device->host; struct aac_dev *dev = (struct aac_dev *)host->hostdata; struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev; + int ret; /* * If the bus, id or lun is out of range, return fail @@ -1474,14 +1465,13 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * itself. */ if (scmd_id(scsicmd) != host->this_id) { - if ((scmd_channel(scsicmd) == CONTAINER_CHANNEL)) { - if((scmd_id(scsicmd) >= dev->maximum_num_containers) || - (scsicmd->device->lun != 0)) { + if ((scsicmd->device->channel == CONTAINER_CHANNEL)) { + if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ scsicmd->result = DID_NO_CONNECT << 16; scsicmd->scsi_done(scsicmd); return 0; } - cid = scmd_id(scsicmd); + cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); /* * If the target container doesn't exist, it may have @@ -1557,7 +1547,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) { struct inquiry_data inq_data; - dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id)); memset(&inq_data, 0, sizeof (struct inquiry_data)); inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ @@ -1607,14 +1597,13 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) cp[11] = 0; cp[12] = 0; aac_internal_transfer(scsicmd, cp, 0, - min_t(size_t, scsicmd->cmnd[13], sizeof(cp))); + min((unsigned int)scsicmd->cmnd[13], sizeof(cp))); if (sizeof(cp) < scsicmd->cmnd[13]) { unsigned int len, offset = sizeof(cp); memset(cp, 0, offset); do { - len = min_t(size_t, scsicmd->cmnd[13] - offset, - sizeof(cp)); + len = min(scsicmd->cmnd[13]-offset, sizeof(cp)); aac_internal_transfer(scsicmd, cp, offset, len); } while ((offset += len) < scsicmd->cmnd[13]); } @@ -1738,19 +1727,24 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * containers to /dev/sd device names */ + spin_unlock_irq(host->host_lock); if (scsicmd->request->rq_disk) strlcpy(fsa_dev_ptr[cid].devname, scsicmd->request->rq_disk->disk_name, min(sizeof(fsa_dev_ptr[cid].devname), sizeof(scsicmd->request->rq_disk->disk_name) + 1)); - - return aac_read(scsicmd, cid); + ret = aac_read(scsicmd, cid); + spin_lock_irq(host->host_lock); + return ret; case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: - return aac_write(scsicmd, cid); + spin_unlock_irq(host->host_lock); + ret = aac_write(scsicmd, cid); + spin_lock_irq(host->host_lock); + return ret; case SYNCHRONIZE_CACHE: /* Issue FIB to tell Firmware to flush it's cache */ @@ -1783,7 +1777,7 @@ static int query_disk(struct aac_dev *dev, void __user *arg) if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk))) return -EFAULT; if (qd.cnum == -1) - qd.cnum = qd.id; + qd.cnum = ID_LUN_TO_CONTAINER(qd.id, qd.lun); else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1)) { if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers) @@ -1895,7 +1889,6 @@ static void aac_srb_callback(void *context, struct fib * fibptr) struct scsi_cmnd *scsicmd; scsicmd = (struct scsi_cmnd *) context; - scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dev = (struct aac_dev *)scsicmd->device->host->hostdata; if (fibptr == NULL) @@ -2074,13 +2067,14 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) u32 timeout; dev = (struct aac_dev *)scsicmd->device->host->hostdata; - if (scmd_id(scsicmd) >= dev->maximum_num_physicals || + if (scsicmd->device->id >= dev->maximum_num_physicals || scsicmd->device->lun > 7) { scsicmd->result = DID_NO_CONNECT << 16; scsicmd->scsi_done(scsicmd); return 0; } + dev = (struct aac_dev *)scsicmd->device->host->hostdata; switch(scsicmd->sc_data_direction){ case DMA_TO_DEVICE: flag = SRB_DataOut; @@ -2108,8 +2102,8 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext); srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); - srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(scsicmd))); - srbcmd->id = cpu_to_le32(scmd_id(scsicmd)); + srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scsicmd->device->channel)); + srbcmd->id = cpu_to_le32(scsicmd->device->id); srbcmd->lun = cpu_to_le32(scsicmd->device->lun); srbcmd->flags = cpu_to_le32(flag); timeout = scsicmd->timeout_per_command/HZ; @@ -2166,8 +2160,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) /* * Check that the command queued to the controller */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + if (status == -EINPROGRESS){ return 0; } @@ -2198,6 +2191,8 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg) scsicmd->sc_data_direction); psg->count = cpu_to_le32(sg_count); + byte_count = 0; + for (i = 0; i < sg_count; i++) { psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg)); psg->sg[i].count = cpu_to_le32(sg_dma_len(sg)); @@ -2253,17 +2248,18 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg, scsicmd->sc_data_direction); + psg->count = cpu_to_le32(sg_count); + + byte_count = 0; for (i = 0; i < sg_count; i++) { - int count = sg_dma_len(sg); addr = sg_dma_address(sg); psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); psg->sg[i].addr[1] = cpu_to_le32(addr>>32); - psg->sg[i].count = cpu_to_le32(count); - byte_count += count; + psg->sg[i].count = cpu_to_le32(sg_dma_len(sg)); + byte_count += sg_dma_len(sg); sg++; } - psg->count = cpu_to_le32(sg_count); /* hba wants the size to be exact */ if(byte_count > scsicmd->request_bufflen){ u32 temp = le32_to_cpu(psg->sg[i-1].count) - @@ -2278,15 +2274,16 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p } } else if(scsicmd->request_bufflen) { - scsicmd->SCp.dma_handle = pci_map_single(dev->pdev, + u64 addr; + addr = pci_map_single(dev->pdev, scsicmd->request_buffer, scsicmd->request_bufflen, scsicmd->sc_data_direction); - addr = scsicmd->SCp.dma_handle; psg->count = cpu_to_le32(1); psg->sg[0].addr[0] = cpu_to_le32(addr & 0xffffffff); psg->sg[0].addr[1] = cpu_to_le32(addr >> 32); psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen); + scsicmd->SCp.dma_handle = addr; byte_count = scsicmd->request_bufflen; } return byte_count; diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index f773b0dcf..2d430b7e8 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -10,10 +10,6 @@ * D E F I N E S *----------------------------------------------------------------------------*/ -#ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 2409 -# define AAC_DRIVER_BRANCH "-mh1" -#endif #define MAXIMUM_NUM_CONTAINERS 32 #define AAC_NUM_MGT_FIB 8 @@ -29,6 +25,7 @@ * These macros convert from physical channels to virtual channels */ #define CONTAINER_CHANNEL (0) +#define ID_LUN_TO_CONTAINER(id, lun) (id) #define CONTAINER_TO_CHANNEL(cont) (CONTAINER_CHANNEL) #define CONTAINER_TO_ID(cont) (cont) #define CONTAINER_TO_LUN(cont) (0) @@ -792,7 +789,6 @@ struct fsa_dev_info { u64 size; u32 type; u32 config_waiting_on; - unsigned long config_waiting_stamp; u16 queue_depth; u8 config_needed; u8 valid; @@ -1001,7 +997,7 @@ struct aac_dev int maximum_num_physicals; int maximum_num_channels; struct fsa_dev_info *fsa_dev; - struct task_struct *thread; + pid_t thread_pid; int cardtype; /* @@ -1021,6 +1017,7 @@ struct aac_dev * AIF thread states */ u32 aif_thread; + struct completion aif_completion; struct aac_adapter_info adapter_info; struct aac_supplement_adapter_info supplement_adapter_info; /* These are in adapter info but they are in the io flow so @@ -1775,11 +1772,6 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor) } struct scsi_cmnd; -/* SCp.phase values */ -#define AAC_OWNER_MIDLEVEL 0x101 -#define AAC_OWNER_LOWLEVEL 0x102 -#define AAC_OWNER_ERROR_HANDLER 0x103 -#define AAC_OWNER_FIRMWARE 0x106 const char *aac_driverinfo(struct Scsi_Host *); struct fib *aac_fib_alloc(struct aac_dev *dev); @@ -1805,7 +1797,7 @@ int aac_sa_init(struct aac_dev *dev); unsigned int aac_response_normal(struct aac_queue * q); unsigned int aac_command_normal(struct aac_queue * q); unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); -int aac_command_thread(void *data); +int aac_command_thread(struct aac_dev * dev); int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size); struct aac_driver_ident* aac_get_driver_ident(int devtype); diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 9f75144e5..47fefca72 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include @@ -295,16 +293,6 @@ return_fib: status = 0; } else { spin_unlock_irqrestore(&dev->fib_lock, flags); - /* If someone killed the AIF aacraid thread, restart it */ - status = !dev->aif_thread; - if (status && dev->queues && dev->fsa_dev) { - /* Be paranoid, be very paranoid! */ - kthread_stop(dev->thread); - ssleep(1); - dev->aif_thread = 0; - dev->thread = kthread_run(aac_command_thread, dev, dev->name); - ssleep(1); - } if (f.wait) { if(down_interruptible(&fibctx->wait_sem) < 0) { status = -EINTR; diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 19397453b..1628d0949 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -433,6 +433,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) } INIT_LIST_HEAD(&dev->fib_list); + init_completion(&dev->aif_completion); return dev; } diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 9f9f4aae2..609fd19b1 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -767,9 +766,9 @@ void aac_printf(struct aac_dev *dev, u32 val) if (cp[length] != 0) cp[length] = 0; if (level == LOG_AAC_HIGH_ERROR) - printk(KERN_WARNING "%s:%s", dev->name, cp); + printk(KERN_WARNING "aacraid:%s", cp); else - printk(KERN_INFO "%s:%s", dev->name, cp); + printk(KERN_INFO "aacraid:%s", cp); } memset(cp, 0, 256); } @@ -784,7 +783,6 @@ void aac_printf(struct aac_dev *dev, u32 val) * dispatches it to the appropriate routine for handling. */ -#define AIF_SNIFF_TIMEOUT (30*HZ) static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) { struct hw_fib * hw_fib = fibptr->hw_fib; @@ -838,7 +836,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) if (device) { dev->fsa_dev[container].config_needed = CHANGE; dev->fsa_dev[container].config_waiting_on = AifEnConfigChange; - dev->fsa_dev[container].config_waiting_stamp = jiffies; scsi_device_put(device); } } @@ -851,15 +848,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) if (container != (u32)-1) { if (container >= dev->maximum_num_containers) break; - if ((dev->fsa_dev[container].config_waiting_on == - le32_to_cpu(*(u32 *)aifcmd->data)) && - time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) + if (dev->fsa_dev[container].config_waiting_on == + le32_to_cpu(*(u32 *)aifcmd->data)) dev->fsa_dev[container].config_waiting_on = 0; } else for (container = 0; container < dev->maximum_num_containers; ++container) { - if ((dev->fsa_dev[container].config_waiting_on == - le32_to_cpu(*(u32 *)aifcmd->data)) && - time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) + if (dev->fsa_dev[container].config_waiting_on == + le32_to_cpu(*(u32 *)aifcmd->data)) dev->fsa_dev[container].config_waiting_on = 0; } break; @@ -876,7 +871,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) dev->fsa_dev[container].config_needed = ADD; dev->fsa_dev[container].config_waiting_on = AifEnConfigChange; - dev->fsa_dev[container].config_waiting_stamp = jiffies; break; /* @@ -889,7 +883,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) dev->fsa_dev[container].config_needed = DELETE; dev->fsa_dev[container].config_waiting_on = AifEnConfigChange; - dev->fsa_dev[container].config_waiting_stamp = jiffies; break; /* @@ -900,13 +893,11 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) container = le32_to_cpu(((u32 *)aifcmd->data)[1]); if (container >= dev->maximum_num_containers) break; - if (dev->fsa_dev[container].config_waiting_on && - time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) + if (dev->fsa_dev[container].config_waiting_on) break; dev->fsa_dev[container].config_needed = CHANGE; dev->fsa_dev[container].config_waiting_on = AifEnConfigChange; - dev->fsa_dev[container].config_waiting_stamp = jiffies; break; case AifEnConfigChange: @@ -921,15 +912,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) if (container != (u32)-1) { if (container >= dev->maximum_num_containers) break; - if ((dev->fsa_dev[container].config_waiting_on == - le32_to_cpu(*(u32 *)aifcmd->data)) && - time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) + if (dev->fsa_dev[container].config_waiting_on == + le32_to_cpu(*(u32 *)aifcmd->data)) dev->fsa_dev[container].config_waiting_on = 0; } else for (container = 0; container < dev->maximum_num_containers; ++container) { - if ((dev->fsa_dev[container].config_waiting_on == - le32_to_cpu(*(u32 *)aifcmd->data)) && - time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) + if (dev->fsa_dev[container].config_waiting_on == + le32_to_cpu(*(u32 *)aifcmd->data)) dev->fsa_dev[container].config_waiting_on = 0; } break; @@ -956,8 +945,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) dev->fsa_dev[container].config_waiting_on = AifEnContainerChange; dev->fsa_dev[container].config_needed = ADD; - dev->fsa_dev[container].config_waiting_stamp = - jiffies; } } if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero)) @@ -973,8 +960,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) dev->fsa_dev[container].config_waiting_on = AifEnContainerChange; dev->fsa_dev[container].config_needed = DELETE; - dev->fsa_dev[container].config_waiting_stamp = - jiffies; } } break; @@ -983,9 +968,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) device_config_needed = NOTHING; for (container = 0; container < dev->maximum_num_containers; ++container) { - if ((dev->fsa_dev[container].config_waiting_on == 0) && - (dev->fsa_dev[container].config_needed != NOTHING) && - time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) { + if ((dev->fsa_dev[container].config_waiting_on == 0) + && (dev->fsa_dev[container].config_needed != NOTHING)) { device_config_needed = dev->fsa_dev[container].config_needed; dev->fsa_dev[container].config_needed = NOTHING; @@ -1061,9 +1045,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) * more FIBs. */ -int aac_command_thread(void *data) +int aac_command_thread(struct aac_dev * dev) { - struct aac_dev *dev = data; struct hw_fib *hw_fib, *hw_newfib; struct fib *fib, *newfib; struct aac_fib_context *fibctx; @@ -1075,7 +1058,12 @@ int aac_command_thread(void *data) */ if (dev->aif_thread) return -EINVAL; - + /* + * Set up the name that will appear in 'ps' + * stored in task_struct.comm[16]. + */ + daemonize("aacraid"); + allow_signal(SIGKILL); /* * Let the DPC know it has a place to send the AIF's to. */ @@ -1278,12 +1266,13 @@ int aac_command_thread(void *data) spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags); schedule(); - if (kthread_should_stop()) + if(signal_pending(current)) break; set_current_state(TASK_INTERRUPTIBLE); } if (dev->queues) remove_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait); dev->aif_thread = 0; + complete_and_exit(&dev->aif_completion, 0); return 0; } diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 6ef89c99d..271617890 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -27,6 +27,12 @@ * Abstract: Linux Driver entry module for Adaptec RAID Array Controller */ +#define AAC_DRIVER_VERSION "1.1-4" +#ifndef AAC_DRIVER_BRANCH +#define AAC_DRIVER_BRANCH "" +#endif +#define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__ +#define AAC_DRIVERNAME "aacraid" #include #include @@ -39,11 +45,9 @@ #include #include #include -#include #include #include #include -#include #include #include @@ -56,13 +60,6 @@ #include "aacraid.h" -#define AAC_DRIVER_VERSION "1.1-5" -#ifndef AAC_DRIVER_BRANCH -#define AAC_DRIVER_BRANCH "" -#endif -#define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__ -#define AAC_DRIVERNAME "aacraid" - #ifdef AAC_DRIVER_BUILD #define _str(x) #x #define str(x) _str(x) @@ -74,7 +71,7 @@ MODULE_AUTHOR("Red Hat Inc and Adaptec"); MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, " "Adaptec Advanced Raid Products, " - "HP NetRAID-4M, IBM ServeRAID & ICP SCSI driver"); + "and HP NetRAID-4M SCSI driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(AAC_DRIVER_FULL_VERSION); @@ -244,7 +241,6 @@ static struct aac_driver_ident aac_drivers[] = { static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { cmd->scsi_done = done; - cmd->SCp.phase = AAC_OWNER_LOWLEVEL; return (aac_scsi_cmd(cmd) ? FAILED : 0); } @@ -473,8 +469,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) __shost_for_each_device(dev, host) { spin_lock_irqsave(&dev->list_lock, flags); list_for_each_entry(command, &dev->cmd_list, list) { - if ((command != cmd) && - (command->SCp.phase == AAC_OWNER_FIRMWARE)) { + if (command->serial_number) { active++; break; } @@ -572,12 +567,12 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long f = compat_alloc_user_space(sizeof(*f)); ret = 0; - if (clear_user(f, sizeof(*f)) != sizeof(*f)) + if (clear_user(f, sizeof(*f) != sizeof(*f))) ret = -EFAULT; if (copy_in_user(f, (void __user *)arg, sizeof(struct fib_ioctl) - sizeof(u32))) ret = -EFAULT; if (!ret) - ret = aac_do_ioctl(dev, cmd, f); + ret = aac_do_ioctl(dev, cmd, (void __user *)arg); break; } @@ -690,18 +685,6 @@ static ssize_t aac_show_serial_number(struct class_device *class_dev, return len; } -static ssize_t aac_show_max_channel(struct class_device *class_dev, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", - class_to_shost(class_dev)->max_channel); -} - -static ssize_t aac_show_max_id(struct class_device *class_dev, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", - class_to_shost(class_dev)->max_id); -} - static struct class_device_attribute aac_model = { .attr = { @@ -745,20 +728,6 @@ static struct class_device_attribute aac_serial_number = { }, .show = aac_show_serial_number, }; -static struct class_device_attribute aac_max_channel = { - .attr = { - .name = "max_channel", - .mode = S_IRUGO, - }, - .show = aac_show_max_channel, -}; -static struct class_device_attribute aac_max_id = { - .attr = { - .name = "max_id", - .mode = S_IRUGO, - }, - .show = aac_show_max_id, -}; static struct class_device_attribute *aac_attrs[] = { &aac_model, @@ -767,8 +736,6 @@ static struct class_device_attribute *aac_attrs[] = { &aac_monitor_version, &aac_bios_version, &aac_serial_number, - &aac_max_channel, - &aac_max_id, NULL }; @@ -806,7 +773,6 @@ static struct scsi_host_template aac_driver_template = { .cmd_per_lun = AAC_NUM_IO_FIB, #endif .use_clustering = ENABLE_CLUSTERING, - .emulated = 1, }; @@ -830,19 +796,18 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, error = pci_enable_device(pdev); if (error) goto out; - error = -ENODEV; if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) - goto out_disable_pdev; + goto out; /* * 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)) - goto out_disable_pdev; + if (pci_set_dma_mask(pdev, 0x7FFFFFFFULL) || + pci_set_consistent_dma_mask(pdev, 0x7FFFFFFFULL)) + goto out; pci_set_master(pdev); @@ -885,10 +850,10 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, /* * Start any kernel threads needed */ - aac->thread = kthread_run(aac_command_thread, aac, AAC_DRIVERNAME); - if (IS_ERR(aac->thread)) { + aac->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, + aac, 0); + if (aac->thread_pid < 0) { printk(KERN_ERR "aacraid: Unable to create command thread.\n"); - error = PTR_ERR(aac->thread); goto out_deinit; } @@ -937,9 +902,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, * physical channels are address by their actual physical number+1 */ if (aac->nondasd_support == 1) - shost->max_channel = aac->maximum_num_channels; + shost->max_channel = aac->maximum_num_channels + 1; else - shost->max_channel = 0; + shost->max_channel = 1; aac_get_config_status(aac); aac_get_containers(aac); @@ -969,7 +934,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, return 0; out_deinit: - kthread_stop(aac->thread); + kill_proc(aac->thread_pid, SIGKILL, 0); + wait_for_completion(&aac->aif_completion); + aac_send_shutdown(aac); aac_adapter_disable_int(aac); free_irq(pdev->irq, aac); @@ -1003,7 +970,8 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) scsi_remove_host(shost); - kthread_stop(aac->thread); + kill_proc(aac->thread_pid, SIGKILL, 0); + wait_for_completion(&aac->aif_completion); aac_send_shutdown(aac); aac_adapter_disable_int(aac); @@ -1053,8 +1021,7 @@ static int __init aac_init(void) static void __exit aac_exit(void) { - if (aac_cfg_major > -1) - unregister_chrdev(aac_cfg_major, "aac"); + unregister_chrdev(aac_cfg_major, "aac"); pci_unregister_driver(&aac_pci_driver); } diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c index 7a23e027e..e9b775d6b 100644 --- a/drivers/scsi/aacraid/rkt.c +++ b/drivers/scsi/aacraid/rkt.c @@ -183,7 +183,7 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, /* * Yield the processor in case we are slow */ - msleep(1); + schedule_timeout_uninterruptible(1); } if (ok != 1) { /* @@ -343,7 +343,7 @@ static int aac_rkt_check_health(struct aac_dev *dev) NULL, NULL, NULL, NULL, NULL); pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), post, paddr); - if ((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X'))) { + if ((buffer[0] == '0') && (buffer[1] == 'x')) { ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); ret <<= 4; ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index 729b9eb26..6998bc877 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c @@ -183,7 +183,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, /* * Yield the processor in case we are slow */ - msleep(1); + schedule_timeout_uninterruptible(1); } if (ok != 1) { /* @@ -342,7 +342,7 @@ static int aac_rx_check_health(struct aac_dev *dev) NULL, NULL, NULL, NULL, NULL); pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), post, paddr); - if ((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X'))) { + if ((buffer[0] == '0') && (buffer[1] == 'x')) { ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); ret <<= 4; ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index a53454908..466f05cfb 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c @@ -189,7 +189,7 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, ok = 1; break; } - msleep(1); + schedule_timeout_uninterruptible(1); } if (ok != 1) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 331c8c55d..da2b04262 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -896,6 +896,14 @@ typedef unsigned char uchar; #define ASC_DVCLIB_CALL_FAILED (0) #define ASC_DVCLIB_CALL_ERROR (-1) +#define PCI_VENDOR_ID_ASP 0x10cd +#define PCI_DEVICE_ID_ASP_1200A 0x1100 +#define PCI_DEVICE_ID_ASP_ABP940 0x1200 +#define PCI_DEVICE_ID_ASP_ABP940U 0x1300 +#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300 +#define PCI_DEVICE_ID_38C0800_REV1 0x2500 +#define PCI_DEVICE_ID_38C1600_REV1 0x2700 + /* * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists. * The SRB structure will have to be changed and the ASC_SRB2SCSIQ() @@ -17297,7 +17305,7 @@ AdvWaitEEPCmd(AdvPortAddr iop_base) /* * Write the EEPROM from 'cfg_buf'. */ -void +void __init AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) { ushort *wbuf; @@ -17364,7 +17372,7 @@ AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) /* * Write the EEPROM from 'cfg_buf'. */ -void +void __init AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) { @@ -17432,7 +17440,7 @@ AdvSet38C0800EEPConfig(AdvPortAddr iop_base, /* * Write the EEPROM from 'cfg_buf'. */ -void +void __init AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) { diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index de80cdfb5..531a1f9ce 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -1716,7 +1716,12 @@ static void seldo_run(struct Scsi_Host *shpnt) ADDMSGO(BUS_DEVICE_RESET); } else if (SYNCNEG==0 && SYNCHRONOUS) { CURRENT_SC->SCp.phase |= syncneg; - MSGOLEN += spi_populate_sync_msg(&MSGO(MSGOLEN), 50, 8); + ADDMSGO(EXTENDED_MESSAGE); + ADDMSGO(3); + ADDMSGO(EXTENDED_SDTR); + ADDMSGO(50); /* 200ns */ + ADDMSGO(8); /* 8 byte req/ack offset */ + SYNCNEG=1; /* negotiation in progress */ } diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 7f54d5da6..559ff7aae 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -67,9 +66,6 @@ enum { AHCI_IRQ_ON_SG = (1 << 31), AHCI_CMD_ATAPI = (1 << 5), AHCI_CMD_WRITE = (1 << 6), - AHCI_CMD_PREFETCH = (1 << 7), - AHCI_CMD_RESET = (1 << 8), - AHCI_CMD_CLR_BUSY = (1 << 10), RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ @@ -89,9 +85,6 @@ enum { /* HOST_CAP bits */ HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ - HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ - HOST_CAP_CLO = (1 << 24), /* Command List Override support */ - HOST_CAP_SSC = (1 << 14), /* Slumber capable */ /* registers for each SATA port */ PORT_LST_ADDR = 0x00, /* command list DMA addr */ @@ -142,16 +135,13 @@ enum { /* PORT_CMD bits */ PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ - PORT_CMD_CPD = (1 << 20), /* Cold presence detection */ PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ - PORT_CMD_CLO = (1 << 3), /* Command list override */ PORT_CMD_POWER_ON = (1 << 2), /* Power up device */ PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ - PORT_CMD_ICC_MASK = (0xf << 28), /* i/f ICC state mask */ PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ @@ -179,7 +169,6 @@ struct ahci_host_priv { unsigned long flags; u32 cap; /* cache of HOST_CAP register */ u32 port_map; /* cache of HOST_PORTS_IMPL reg */ - u32 dev_map; /* connected devices */ }; struct ahci_port_priv { @@ -195,32 +184,17 @@ struct ahci_port_priv { static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); +static int ahci_qc_issue(struct ata_queued_cmd *qc); static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); -static int ahci_start_engine(void __iomem *port_mmio); -static int ahci_stop_engine(void __iomem *port_mmio); -static int ahci_stop_fis_rx(void __iomem *port_mmio); -static void ahci_start_fis_rx(void __iomem *port_mmio, - struct ahci_port_priv *pp, - struct ahci_host_priv *hpriv); -static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes); +static void ahci_phy_reset(struct ata_port *ap); static void ahci_irq_clear(struct ata_port *ap); static void ahci_eng_timeout(struct ata_port *ap); static int ahci_port_start(struct ata_port *ap); static void ahci_port_stop(struct ata_port *ap); -static int ahci_port_suspend(struct ata_port *ap, pm_message_t state); -static int ahci_port_resume(struct ata_port *ap); -static int ahci_port_standby(void __iomem *port_mmio, u32 cap); -static int ahci_port_spinup(void __iomem *port_mmio, u32 cap); -static void ahci_port_disable(struct ata_port *ap); static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); static void ahci_qc_prep(struct ata_queued_cmd *qc); static u8 ahci_check_status(struct ata_port *ap); static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); -static int ahci_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state); -static int ahci_scsi_device_resume(struct scsi_device *sdev); -static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t state); -static int ahci_pci_device_resume(struct pci_dev *pdev); static void ahci_remove_one (struct pci_dev *pdev); static struct scsi_host_template ahci_sht = { @@ -228,9 +202,11 @@ static struct scsi_host_template ahci_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = AHCI_MAX_SG, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = AHCI_USE_CLUSTERING, @@ -238,12 +214,10 @@ static struct scsi_host_template ahci_sht = { .dma_boundary = AHCI_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, .bios_param = ata_std_bios_param, - .resume = ahci_scsi_device_resume, - .suspend = ahci_scsi_device_suspend, }; static const struct ata_port_operations ahci_ops = { - .port_disable = ahci_port_disable, + .port_disable = ata_port_disable, .check_status = ahci_check_status, .check_altstatus = ahci_check_status, @@ -251,7 +225,7 @@ static const struct ata_port_operations ahci_ops = { .tf_read = ahci_tf_read, - .probe_reset = ahci_probe_reset, + .phy_reset = ahci_phy_reset, .qc_prep = ahci_qc_prep, .qc_issue = ahci_qc_issue, @@ -273,7 +247,8 @@ static const struct ata_port_info ahci_port_info[] = { { .sht = &ahci_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, + ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | + ATA_FLAG_PIO_DMA, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops, @@ -315,10 +290,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { board_ahci }, /* JMicron JMB360 */ { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* JMicron JMB363 */ - { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* ATI SB600 non-raid */ - { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* ATI SB600 raid */ { } /* terminate list */ }; @@ -328,8 +299,6 @@ static struct pci_driver ahci_pci_driver = { .id_table = ahci_pci_tbl, .probe = ahci_init_one, .remove = ahci_remove_one, - .suspend = ahci_pci_device_suspend, - .resume = ahci_pci_device_resume, }; @@ -403,23 +372,21 @@ static int ahci_port_start(struct ata_port *ap) ap->private_data = pp; - /* - * Driver is setup; initialize the HBA - */ - ahci_start_fis_rx(port_mmio, pp, hpriv); - rc = ahci_port_spinup(port_mmio, hpriv->cap); - if (rc) - printk(KERN_WARNING "ata%d: could not spinup device (%d)\n", - ap->id, rc); - - /* - * Do not enable DMA here; according to the spec - * (section 10.1.1) we should first enable FIS reception, - * then check if the port is enabled before we try to - * switch on DMA. - * And as the port check is done during probe - * we really shouldn't be doing it here. - */ + if (hpriv->cap & HOST_CAP_64) + writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); + writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); + readl(port_mmio + PORT_LST_ADDR); /* flush */ + + if (hpriv->cap & HOST_CAP_64) + writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); + writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); + readl(port_mmio + PORT_FIS_ADDR); /* flush */ + + writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | + PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | + PORT_CMD_START, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ + return 0; } @@ -428,114 +395,25 @@ static void ahci_port_stop(struct ata_port *ap) { struct device *dev = ap->host_set->dev; struct ahci_port_priv *pp = ap->private_data; - - ahci_port_suspend(ap, PMSG_SUSPEND); - - ap->private_data = NULL; - dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, - pp->cmd_slot, pp->cmd_slot_dma); - ata_pad_free(ap, dev); - kfree(pp); -} - -static int ahci_port_suspend(struct ata_port *ap, pm_message_t state) -{ void __iomem *mmio = ap->host_set->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - struct ahci_host_priv *hpriv = ap->host_set->private_data; - int rc; - - /* - * Disable DMA - */ - rc = ahci_stop_engine(port_mmio); - if (rc) { - printk(KERN_WARNING "ata%u: DMA engine busy\n", ap->id); - return rc; - } - - /* - * Disable FIS reception - */ - rc = ahci_stop_fis_rx(port_mmio); - if (rc) - printk(KERN_WARNING "ata%d: FIS RX still running (rc %d)\n", - ap->id, rc); - - /* - * Put device into slumber mode - */ - if (!rc && state.event != PM_EVENT_FREEZE) - ahci_port_standby(port_mmio, hpriv->cap); - - return rc; -} - -static int ahci_port_resume(struct ata_port *ap) -{ - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - struct ahci_host_priv *hpriv = ap->host_set->private_data; - struct ahci_port_priv *pp = ap->private_data; - int rc; u32 tmp; - /* - * Enable FIS reception - */ - ahci_start_fis_rx(port_mmio, pp, hpriv); - - rc = ahci_port_spinup(port_mmio, hpriv->cap); - if (rc) - printk(KERN_WARNING "ata%d: could not spinup device (%d)\n", - ap->id, rc); - - /* - * Clear error status - */ - tmp = readl(port_mmio + PORT_SCR_ERR); - writel(tmp, port_mmio + PORT_SCR_ERR); - /* - * Clear interrupt status - */ - tmp = readl(mmio + HOST_CTL); - if (!(tmp & HOST_IRQ_EN)) { - u32 irq_stat; - - /* ack any pending irq events for this port */ - irq_stat = readl(port_mmio + PORT_IRQ_STAT); - if (irq_stat) - writel(irq_stat, port_mmio + PORT_IRQ_STAT); - - /* set irq mask (enables interrupts) */ - writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); - - if ((hpriv->dev_map >> (ap->port_no + 1)) == 0) { - /* - * Enable interrupts if this was the last port - */ - printk(KERN_WARNING "ata%d: enabling interrupts\n", - ap->id); - - irq_stat = readl(mmio + HOST_IRQ_STAT); - if (irq_stat) - writel(irq_stat, mmio + HOST_IRQ_STAT); - - tmp |= HOST_IRQ_EN; - writel(tmp, mmio + HOST_CTL); - (void) readl(mmio + HOST_CTL); - } - } + tmp = readl(port_mmio + PORT_CMD); + tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); + writel(tmp, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ - /* - * Enable DMA + /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so + * this is slightly incorrect. */ - rc = ahci_start_engine(port_mmio); - if (rc) - printk(KERN_WARNING "ata%d: cannot start DMA engine (rc %d)\n", - ap->id, rc); + msleep(500); - return rc; + ap->private_data = NULL; + dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, + pp->cmd_slot, pp->cmd_slot_dma); + ata_pad_free(ap, dev); + kfree(pp); } static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) @@ -572,268 +450,17 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int ahci_stop_engine(void __iomem *port_mmio) -{ - int work; - u32 tmp; - - tmp = readl(port_mmio + PORT_CMD); - /* Check if the HBA is idle */ - if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) - return 0; - - /* Setting HBA to idle */ - tmp &= ~PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); - - /* - * wait for engine to become idle - */ - work = 1000; - while (work-- > 0) { - tmp = readl(port_mmio + PORT_CMD); - if ((tmp & PORT_CMD_LIST_ON) == 0) - return 0; - udelay(10); - } - - return -EIO; -} - -static int ahci_start_engine(void __iomem *port_mmio) -{ - u32 tmp; - int work = 1000; - - /* - * Get current status - */ - tmp = readl(port_mmio + PORT_CMD); - - /* - * AHCI rev 1.1 section 10.3.1: - * Software shall not set PxCMD.ST to '1' until it verifies - * that PxCMD.CR is '0' and has set PxCMD.FRE to '1' - */ - if ((tmp & PORT_CMD_FIS_RX) == 0) - return -EPERM; - - /* - * wait for engine to become idle. - */ - while (work-- > 0) { - tmp = readl(port_mmio + PORT_CMD); - if ((tmp & PORT_CMD_LIST_ON) == 0) - break; - udelay(10); - } - - if (!work) { - /* - * We need to do a port reset / HBA reset here - */ - return -EBUSY; - } - - /* - * Start DMA - */ - tmp |= PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* flush */ - - return 0; -} - -static int ahci_stop_fis_rx(void __iomem *port_mmio) -{ - u32 tmp; - int work = 1000; - - /* - * Get current status - */ - tmp = readl(port_mmio + PORT_CMD); - - /* Check if FIS RX is already disabled */ - if ((tmp & PORT_CMD_FIS_RX) == 0) - return 0; - - /* - * AHCI Rev 1.1 section 10.3.2 - * Software shall not clear PxCMD.FRE while - * PxCMD.ST or PxCMD.CR is set to '1' - */ - if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_START)) { - return -EPERM; - } - - /* - * Disable FIS reception - * - * AHCI Rev 1.1 Section 10.1.2: - * If PxCMD.FRE is set to '1', software should clear it - * to '0' and wait at least 500 milliseconds for PxCMD.FR - * to return '0' when read. If PxCMD.FR does not clear - * '0' correctly, then software may attempt a port reset - * of a full HBA reset to recover. - */ - tmp &= ~(PORT_CMD_FIS_RX); - writel(tmp, port_mmio + PORT_CMD); - - mdelay(500); - work = 1000; - while (work-- > 0) { - tmp = readl(port_mmio + PORT_CMD); - if ((tmp & PORT_CMD_FIS_ON) == 0) - return 0; - udelay(10); - } - - return -EBUSY; -} - -static void ahci_start_fis_rx(void __iomem *port_mmio, - struct ahci_port_priv *pp, - struct ahci_host_priv *hpriv) -{ - u32 tmp; - - /* - * Set FIS registers - */ - if (hpriv->cap & HOST_CAP_64) - writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); - writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); - readl(port_mmio + PORT_LST_ADDR); /* flush */ - - if (hpriv->cap & HOST_CAP_64) - writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); - writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); - readl(port_mmio + PORT_FIS_ADDR); /* flush */ - - /* - * Enable FIS reception - */ - tmp = readl(port_mmio + PORT_CMD); - tmp |= PORT_CMD_FIS_RX; - writel(tmp, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* flush */ -} - -static int ahci_port_standby(void __iomem *port_mmio, u32 cap) -{ - u32 tmp, scontrol, sstatus; - - tmp = readl(port_mmio + PORT_CMD); - /* - * AHCI Rev1.1 Section 5.3.2.3: - * Software is only allowed to program the PxCMD.FRE, - * PxCMD.POD, PxSCTL.DET, and PxCMD.SUD register bits - * when PxCMD.ST is set to '0' - */ - if (tmp & PORT_CMD_START) - return -EBUSY; - - if (cap & HOST_CAP_SSC) { - /* - * Enable transitions to slumber mode - */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - if ((scontrol & 0x0f00) > 0x100) { - scontrol &= ~0xf00; - writel(scontrol, port_mmio + PORT_SCR_CTL); - } - /* - * Put device into slumber mode - */ - tmp |= PORT_CMD_ICC_SLUMBER; - writel(tmp, port_mmio + PORT_CMD); - tmp = readl(port_mmio + PORT_CMD); - - /* - * Actually, we should wait for the device to - * enter slumber mode by checking - * sstatus & 0xf00 == 6 - */ - sstatus = readl(port_mmio + PORT_SCR_STAT); - } - - /* - * Put device into listen mode - */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - scontrol &= ~0xf; - writel(scontrol, port_mmio + PORT_SCR_CTL); - - tmp = readl(port_mmio + PORT_CMD); - if (cap & HOST_CAP_SSS) { - /* - * Spin down the device for staggered spin-up support - */ - tmp &= ~PORT_CMD_SPIN_UP; - writel(tmp, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* flush */ - } - - return 0; -} - -static int ahci_port_spinup(void __iomem *port_mmio, u32 cap) -{ - u32 tmp; - - tmp = readl(port_mmio + PORT_CMD); - /* - * AHCI Rev1.1 Section 5.3.2.3: - * Software is only allowed to program the PxCMD.FRE, - * PxCMD.POD, PxSCTL.DET, and PxCMD.SUD register bits - * when PxCMD.ST is set to '0' - */ - if (tmp & PORT_CMD_START) - return -EBUSY; - - /* - * Power on device if supported - */ - if (tmp & PORT_CMD_CPD) { - tmp |= PORT_CMD_POWER_ON; - writel(tmp, port_mmio + PORT_CMD); - tmp = readl(port_mmio + PORT_CMD); - } - - /* - * Spin up device - */ - if (cap & HOST_CAP_SSS) { - tmp |= PORT_CMD_SPIN_UP; - writel(tmp, port_mmio + PORT_CMD); - tmp = readl(port_mmio + PORT_CMD); - } - - if ((tmp & PORT_CMD_ICC_MASK) != PORT_CMD_ICC_ACTIVE) { - tmp |= PORT_CMD_ICC_ACTIVE; - writel(tmp, port_mmio + PORT_CMD); - tmp = readl(port_mmio + PORT_CMD); - } - - return 0; -} - -static void ahci_port_disable(struct ata_port *ap) -{ - struct ahci_host_priv *hpriv = ap->host_set->private_data; - - ata_port_disable(ap); - - hpriv->dev_map &= ~(1 << ap->port_no); -} - -static unsigned int ahci_dev_classify(struct ata_port *ap) +static void ahci_phy_reset(struct ata_port *ap) { void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; struct ata_taskfile tf; - u32 tmp; + struct ata_device *dev = &ap->device[0]; + u32 new_tmp, tmp; + + __sata_phy_reset(ap); + + if (ap->flags & ATA_FLAG_PORT_DISABLED) + return; tmp = readl(port_mmio + PORT_SIG); tf.lbah = (tmp >> 24) & 0xff; @@ -841,182 +468,15 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) tf.lbal = (tmp >> 8) & 0xff; tf.nsect = (tmp) & 0xff; - return ata_dev_classify(&tf); -} - -static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) -{ - pp->cmd_slot[0].opts = cpu_to_le32(opts); - pp->cmd_slot[0].status = 0; - pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); - pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); -} - -static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val, - unsigned long interval_msec, - unsigned long timeout_msec) -{ - unsigned long timeout; - u32 tmp; - - timeout = jiffies + (timeout_msec * HZ) / 1000; - do { - tmp = readl(reg); - if ((tmp & mask) == val) - return 0; - msleep(interval_msec); - } while (time_before(jiffies, timeout)); - - return -1; -} - -static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) -{ - struct ahci_host_priv *hpriv = ap->host_set->private_data; - struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - const u32 cmd_fis_len = 5; /* five dwords */ - const char *reason = NULL; - struct ata_taskfile tf; - u8 *fis; - int rc; - - DPRINTK("ENTER\n"); - - /* prepare for SRST (AHCI-1.1 10.4.1) */ - rc = ahci_stop_engine(port_mmio); - if (rc) { - reason = "failed to stop engine"; - goto fail_restart; - } - - /* check BUSY/DRQ, perform Command List Override if necessary */ - ahci_tf_read(ap, &tf); - if (tf.command & (ATA_BUSY | ATA_DRQ)) { - u32 tmp; - - if (!(hpriv->cap & HOST_CAP_CLO)) { - rc = -EIO; - reason = "port busy but no CLO"; - goto fail_restart; - } - - tmp = readl(port_mmio + PORT_CMD); - tmp |= PORT_CMD_CLO; - writel(tmp, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* flush */ - - if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0, - 1, 500)) { - rc = -EIO; - reason = "CLO failed"; - goto fail_restart; - } - } - - /* restart engine */ - ahci_start_engine(port_mmio); - - ata_tf_init(ap, &tf, 0); - fis = pp->cmd_tbl; - - /* issue the first D2H Register FIS */ - ahci_fill_cmd_slot(pp, cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); - - tf.ctl |= ATA_SRST; - ata_tf_to_fis(&tf, fis, 0); - fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ - - writel(1, port_mmio + PORT_CMD_ISSUE); - readl(port_mmio + PORT_CMD_ISSUE); /* flush */ - - if (ahci_poll_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x0, 1, 500)) { - rc = -EIO; - reason = "1st FIS failed"; - goto fail; - } - - /* spec says at least 5us, but be generous and sleep for 1ms */ - msleep(1); - - /* issue the second D2H Register FIS */ - ahci_fill_cmd_slot(pp, cmd_fis_len); - - tf.ctl &= ~ATA_SRST; - ata_tf_to_fis(&tf, fis, 0); - fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ - - writel(1, port_mmio + PORT_CMD_ISSUE); - readl(port_mmio + PORT_CMD_ISSUE); /* flush */ - - /* spec mandates ">= 2ms" before checking status. - * We wait 150ms, because that was the magic delay used for - * ATAPI devices in Hale Landis's ATADRVR, for the period of time - * between when the ATA command register is written, and then - * status is checked. Because waiting for "a while" before - * checking status is fine, post SRST, we perform this magic - * delay here as well. - */ - msleep(150); - - *class = ATA_DEV_NONE; - if (sata_dev_present(ap)) { - if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { - rc = -EIO; - reason = "device not ready"; - goto fail; - } - *class = ahci_dev_classify(ap); + dev->class = ata_dev_classify(&tf); + if (!ata_dev_present(dev)) { + ata_port_disable(ap); + return; } - DPRINTK("EXIT, class=%u\n", *class); - return 0; - - fail_restart: - ahci_start_engine(port_mmio); - fail: - if (verbose) - printk(KERN_ERR "ata%u: softreset failed (%s)\n", - ap->id, reason); - else - DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason); - return rc; -} - -static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class) -{ - int rc; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - - - DPRINTK("ENTER\n"); - - ahci_stop_engine(port_mmio); - rc = sata_std_hardreset(ap, verbose, class); - ahci_start_engine(port_mmio); - - if (rc == 0) - *class = ahci_dev_classify(ap); - if (*class == ATA_DEV_UNKNOWN) - *class = ATA_DEV_NONE; - - DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); - return rc; -} - -static void ahci_postreset(struct ata_port *ap, unsigned int *class) -{ - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; - struct ahci_host_priv *hpriv = ap->host_set->private_data; - u32 new_tmp, tmp; - - ata_std_postreset(ap, class); - /* Make sure port's ATAPI bit is set appropriately */ new_tmp = tmp = readl(port_mmio + PORT_CMD); - if (*class == ATA_DEV_ATAPI) + if (dev->class == ATA_DEV_ATAPI) new_tmp |= PORT_CMD_ATAPI; else new_tmp &= ~PORT_CMD_ATAPI; @@ -1024,16 +484,6 @@ static void ahci_postreset(struct ata_port *ap, unsigned int *class) writel(new_tmp, port_mmio + PORT_CMD); readl(port_mmio + PORT_CMD); /* flush */ } - - if (*class != ATA_DEV_NONE) - hpriv->dev_map |= (1 << ap->port_no); -} - -static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes) -{ - return ata_drive_probe_reset(ap, ata_std_probeinit, - ahci_softreset, ahci_hardreset, - ahci_postreset, classes); } static u8 ahci_check_status(struct ata_port *ap) @@ -1083,36 +533,42 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ahci_port_priv *pp = ap->private_data; - int is_atapi = is_atapi_taskfile(&qc->tf); u32 opts; const u32 cmd_fis_len = 5; /* five dwords */ unsigned int n_elem; + /* + * Fill in command slot information (currently only one slot, + * slot 0, is currently since we don't do queueing) + */ + + opts = cmd_fis_len; + if (qc->tf.flags & ATA_TFLAG_WRITE) + opts |= AHCI_CMD_WRITE; + if (is_atapi_taskfile(&qc->tf)) + opts |= AHCI_CMD_ATAPI; + + pp->cmd_slot[0].opts = cpu_to_le32(opts); + pp->cmd_slot[0].status = 0; + pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); + pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); + /* * Fill in command table information. First, the header, * a SATA Register - Host to Device command FIS. */ ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); - if (is_atapi) { + if (opts & AHCI_CMD_ATAPI) { memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); - memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, - qc->dev->cdb_len); + memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len); } - n_elem = 0; - if (qc->flags & ATA_QCFLAG_DMAMAP) - n_elem = ahci_fill_sg(qc); + if (!(qc->flags & ATA_QCFLAG_DMAMAP)) + return; - /* - * Fill in command slot information. - */ - opts = cmd_fis_len | n_elem << 16; - if (qc->tf.flags & ATA_TFLAG_WRITE) - opts |= AHCI_CMD_WRITE; - if (is_atapi) - opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; + n_elem = ahci_fill_sg(qc); - ahci_fill_cmd_slot(pp, opts); + pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16); } static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) @@ -1120,6 +576,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) void __iomem *mmio = ap->host_set->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); u32 tmp; + int work; if ((ap->device[0].class != ATA_DEV_ATAPI) || ((irq_stat & PORT_IRQ_TF_ERR) == 0)) @@ -1135,7 +592,20 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) readl(port_mmio + PORT_SCR_ERR)); /* stop DMA */ - ahci_stop_engine(port_mmio); + tmp = readl(port_mmio + PORT_CMD); + tmp &= ~PORT_CMD_START; + writel(tmp, port_mmio + PORT_CMD); + + /* wait for engine to stop. TODO: this could be + * as long as 500 msec + */ + work = 1000; + while (work-- > 0) { + tmp = readl(port_mmio + PORT_CMD); + if ((tmp & PORT_CMD_LIST_ON) == 0) + break; + udelay(10); + } /* clear SATA phy error, if any */ tmp = readl(port_mmio + PORT_SCR_ERR); @@ -1154,7 +624,10 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) } /* re-start DMA */ - ahci_start_engine(port_mmio); + tmp = readl(port_mmio + PORT_CMD); + tmp |= PORT_CMD_START; + writel(tmp, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ } static void ahci_eng_timeout(struct ata_port *ap) @@ -1169,78 +642,25 @@ static void ahci_eng_timeout(struct ata_port *ap) spin_lock_irqsave(&host_set->lock, flags); - ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); qc = ata_qc_from_tag(ap, ap->active_tag); - qc->err_mask |= AC_ERR_TIMEOUT; - - spin_unlock_irqrestore(&host_set->lock, flags); - - ata_eh_qc_complete(qc); -} - -int ahci_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) -{ - struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; - struct ata_device *dev = &ap->device[sdev->id]; - int rc; - - rc = ata_device_suspend(ap, dev, state); - - if (!rc) - rc = ahci_port_suspend(ap, state); - - return rc; -} - -int ahci_scsi_device_resume(struct scsi_device *sdev) -{ - struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; - struct ata_device *dev = &ap->device[sdev->id]; - - ahci_port_resume(ap); - - return ata_device_resume(ap, dev); -} - -int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct device *dev = pci_dev_to_dev(pdev); - struct ata_host_set *host_set = dev_get_drvdata(dev); - void __iomem *mmio = host_set->mmio_base; - u32 tmp; - - /* - * AHCI spec rev1.1 section 8.3.3: - * Software must disable interrupts prior to - * requesting a transition of the HBA to - * D3 state. - */ - tmp = readl(mmio + HOST_CTL); - tmp &= ~HOST_IRQ_EN; - writel(tmp, mmio + HOST_CTL); - tmp = readl(mmio + HOST_CTL); /* flush */ - - return ata_pci_device_suspend(pdev, state); -} - -int ahci_pci_device_resume(struct pci_dev *pdev) -{ - struct device *dev = pci_dev_to_dev(pdev); - struct ata_host_set *host_set = dev_get_drvdata(dev); - void __iomem *mmio = host_set->mmio_base; - u32 tmp; - - /* - * Enabling AHCI mode - */ - tmp = readl(mmio + HOST_CTL); - if (!(tmp & HOST_AHCI_EN)) { - tmp |= HOST_AHCI_EN; - writel(tmp, mmio + HOST_CTL); - tmp = readl(mmio + HOST_CTL); + if (!qc) { + printk(KERN_ERR "ata%u: BUG: timeout without command\n", + ap->id); + } else { + ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); + + /* hack alert! We cannot use the supplied completion + * function from inside the ->eh_strategy_handler() thread. + * libata is the only user of ->eh_strategy_handler() in + * any kernel, so the default scsi_done() assumes it is + * not being called from the SCSI EH. + */ + qc->scsidone = scsi_finish_command; + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); } - return ata_pci_device_resume(pdev); + spin_unlock_irqrestore(&host_set->lock, flags); } static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) @@ -1258,7 +678,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) ci = readl(port_mmio + PORT_CMD_ISSUE); if (likely((ci & 0x1) == 0)) { if (qc) { - WARN_ON(qc->err_mask); + assert(qc->err_mask == 0); ata_qc_complete(qc); qc = NULL; } @@ -1277,7 +697,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) ahci_restart_port(ap, status); if (qc) { - qc->err_mask |= err_mask; + qc->err_mask |= AC_ERR_OTHER; ata_qc_complete(qc); } } @@ -1350,7 +770,7 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * return IRQ_RETVAL(handled); } -static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) +static int ahci_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; @@ -1423,7 +843,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) hpriv->cap = readl(mmio + HOST_CAP); hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); - hpriv->dev_map = 0; probe_ent->n_ports = (hpriv->cap & 0x1f) + 1; VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n", @@ -1469,29 +888,23 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) (unsigned long) mmio, i); /* make sure port is not active */ - rc = ahci_stop_engine(port_mmio); - if (rc) - printk(KERN_WARNING "ata%u: DMA engine busy (rc %d)\n", - i, rc); - - rc = ahci_stop_fis_rx(port_mmio); - if (rc) - printk(KERN_WARNING "ata%u: FIS RX not stopped (rc %d)\n", - i, rc); - - /* - * Actually, this is wrong again. - * AHCI spec says that we first should - * enable FIS reception before sending - * SPIN_UP to the device ... - */ + tmp = readl(port_mmio + PORT_CMD); + VPRINTK("PORT_CMD 0x%x\n", tmp); + if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | + PORT_CMD_FIS_RX | PORT_CMD_START)) { + tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | + PORT_CMD_FIS_RX | PORT_CMD_START); + writel(tmp, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ + + /* spec says 500 msecs for each bit, so + * this is slightly incorrect. + */ + msleep(500); + } writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD); - /* - * Wait for the communications link to establish - */ - j = 0; while (j < 100) { msleep(10); diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx index 5517da585..6c2c39555 100644 --- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx +++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx @@ -86,7 +86,7 @@ config AIC7XXX_DEBUG_MASK default "0" help Bit mask of debug options that is only valid if the - CONFIG_AIC7XXX_DEBUG_ENABLE option is enabled. The bits in this mask + CONFIG_AIC7XXX_DEBUG_ENBLE option is enabled. The bits in this mask are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the variable ahc_debug in that file to find them. diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index bb5166da4..1d11f7e77 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h @@ -372,7 +372,7 @@ typedef enum { AHD_CURRENT_SENSING = 0x40000, AHD_SCB_CONFIG_USED = 0x80000,/* No SEEPROM but SCB had info. */ AHD_HP_BOARD = 0x100000, - AHD_BUS_RESET_ACTIVE = 0x200000, + AHD_RESET_POLL_ACTIVE = 0x200000, AHD_UPDATE_PEND_CMDS = 0x400000, AHD_RUNNING_QOUTFIFO = 0x800000, AHD_HAD_FIRST_SEL = 0x1000000 @@ -589,7 +589,7 @@ typedef enum { SCB_PACKETIZED = 0x00800, SCB_EXPECT_PPR_BUSFREE = 0x01000, SCB_PKT_SENSE = 0x02000, - SCB_EXTERNAL_RESET = 0x04000,/* Device was reset externally */ + SCB_CMDPHASE_ABORT = 0x04000, SCB_ON_COL_LIST = 0x08000, SCB_SILENT = 0x10000 /* * Be quiet about transmission type diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 08771f6f6..342f77966 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -207,6 +207,7 @@ static void ahd_add_scb_to_free_list(struct ahd_softc *ahd, static u_int ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, u_int prev, u_int next, u_int tid); static void ahd_reset_current_bus(struct ahd_softc *ahd); +static ahd_callback_t ahd_reset_poll; static ahd_callback_t ahd_stat_timer; #ifdef AHD_DUMP_SEQ static void ahd_dumpseq(struct ahd_softc *ahd); @@ -977,13 +978,9 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) break; } case INVALID_SEQINT: - printf("%s: Invalid Sequencer interrupt occurred, " - "resetting channel.\n", + printf("%s: Invalid Sequencer interrupt occurred.\n", ahd_name(ahd)); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) - ahd_dump_card_state(ahd); -#endif + ahd_dump_card_state(ahd); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); break; case STATUS_OVERRUN: @@ -1053,10 +1050,12 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) * If a target takes us into the command phase * assume that it has been externally reset and * has thus lost our previous packetized negotiation - * agreement. - * Revert to async/narrow transfers until we - * can renegotiate with the device and notify - * the OSM about the reset. + * agreement. Since we have not sent an identify + * message and may not have fully qualified the + * connection, we change our command to TUR, assert + * ATN and ABORT the task when we go to message in + * phase. The OSM will see the REQUEUE_REQUEST + * status and retry the command. */ scbid = ahd_get_scbptr(ahd); scb = ahd_lookup_scb(ahd, scbid); @@ -1083,15 +1082,31 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, /*ppr_options*/0, AHD_TRANS_ACTIVE, /*paused*/TRUE); - scb->flags |= SCB_EXTERNAL_RESET; + ahd_outb(ahd, SCB_CDB_STORE, 0); + ahd_outb(ahd, SCB_CDB_STORE+1, 0); + ahd_outb(ahd, SCB_CDB_STORE+2, 0); + ahd_outb(ahd, SCB_CDB_STORE+3, 0); + ahd_outb(ahd, SCB_CDB_STORE+4, 0); + ahd_outb(ahd, SCB_CDB_STORE+5, 0); + ahd_outb(ahd, SCB_CDB_LEN, 6); + scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE); + scb->hscb->control |= MK_MESSAGE; + ahd_outb(ahd, SCB_CONTROL, scb->hscb->control); + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); + /* + * The lun is 0, regardless of the SCB's lun + * as we have not sent an identify message. + */ + ahd_outb(ahd, SAVED_LUN, 0); + ahd_outb(ahd, SEQ_FLAGS, 0); + ahd_assert_atn(ahd); + scb->flags &= ~SCB_PACKETIZED; + scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT; ahd_freeze_devq(ahd, scb); ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); ahd_freeze_scb(scb); - /* Notify XPT */ - ahd_send_async(ahd, devinfo.channel, devinfo.target, - CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); - /* * Allow the sequencer to continue with * non-pack processing. @@ -1515,18 +1530,6 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) lqistat1 = ahd_inb(ahd, LQISTAT1); lqostat0 = ahd_inb(ahd, LQOSTAT0); busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME; - - /* - * Ignore external resets after a bus reset. - */ - if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) - return; - - /* - * Clear bus reset flag - */ - ahd->flags &= ~AHD_BUS_RESET_ACTIVE; - if ((status0 & (SELDI|SELDO)) != 0) { u_int simode0; @@ -2200,6 +2203,22 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) if (sent_msg == MSG_ABORT_TAG) tag = SCB_GET_TAG(scb); + if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) { + /* + * This abort is in response to an + * unexpected switch to command phase + * for a packetized connection. Since + * the identify message was never sent, + * "saved lun" is 0. We really want to + * abort only the SCB that encountered + * this error, which could have a different + * lun. The SCB will be retried so the OS + * will see the UA after renegotiating to + * packetized. + */ + tag = SCB_GET_TAG(scb); + saved_lun = scb->hscb->lun; + } found = ahd_abort_scbs(ahd, target, 'A', saved_lun, tag, ROLE_INITIATOR, CAM_REQ_ABORTED); @@ -3743,8 +3762,11 @@ ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, { if (offset == 0) period = AHD_ASYNC_XFER_PERIOD; - ahd->msgout_index += spi_populate_sync_msg( - ahd->msgout_buf + ahd->msgout_index, period, offset); + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR; + ahd->msgout_buf[ahd->msgout_index++] = period; + ahd->msgout_buf[ahd->msgout_index++] = offset; ahd->msgout_len += 5; if (bootverbose) { printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n", @@ -3761,8 +3783,10 @@ static void ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, u_int bus_width) { - ahd->msgout_index += spi_populate_width_msg( - ahd->msgout_buf + ahd->msgout_index, bus_width); + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR; + ahd->msgout_buf[ahd->msgout_index++] = bus_width; ahd->msgout_len += 4; if (bootverbose) { printf("(%s:%c:%d:%d): Sending WDTR %x\n", @@ -3789,9 +3813,14 @@ ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, ppr_options |= MSG_EXT_PPR_PCOMP_EN; if (offset == 0) period = AHD_ASYNC_XFER_PERIOD; - ahd->msgout_index += spi_populate_ppr_msg( - ahd->msgout_buf + ahd->msgout_index, period, offset, - bus_width, ppr_options); + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN; + ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR; + ahd->msgout_buf[ahd->msgout_index++] = period; + ahd->msgout_buf[ahd->msgout_index++] = 0; + ahd->msgout_buf[ahd->msgout_index++] = offset; + ahd->msgout_buf[ahd->msgout_index++] = bus_width; + ahd->msgout_buf[ahd->msgout_index++] = ppr_options; ahd->msgout_len += 8; if (bootverbose) { printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, " @@ -7065,6 +7094,7 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) ahd_flush_qoutfifo(ahd); + ahd_platform_flushwork(ahd); ahd->flags &= ~AHD_ALL_INTERRUPTS; } @@ -7824,17 +7854,6 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) int found; u_int fifo; u_int next_fifo; - uint8_t scsiseq; - - /* - * Check if the last bus reset is cleared - */ - if (ahd->flags & AHD_BUS_RESET_ACTIVE) { - printf("%s: bus reset still active\n", - ahd_name(ahd)); - return 0; - } - ahd->flags |= AHD_BUS_RESET_ACTIVE; ahd->pending_device = NULL; @@ -7848,12 +7867,6 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) /* Make sure the sequencer is in a safe location. */ ahd_clear_critical_section(ahd); - /* - * Run our command complete fifos to ensure that we perform - * completion processing on any commands that 'completed' - * before the reset occurred. - */ - ahd_run_qoutfifo(ahd); #ifdef AHD_TARGET_MODE if ((ahd->flags & AHD_TARGETROLE) != 0) { ahd_run_tqinfifo(ahd, /*paused*/TRUE); @@ -7918,14 +7931,30 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) ahd_clear_fifo(ahd, 1); /* - * Reenable selections + * Revert to async/narrow transfers until we renegotiate. */ - ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST); - scsiseq = ahd_inb(ahd, SCSISEQ_TEMPLATE); - ahd_outb(ahd, SCSISEQ1, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP)); - max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; + for (target = 0; target <= max_scsiid; target++) { + + if (ahd->enabled_targets[target] == NULL) + continue; + for (initiator = 0; initiator <= max_scsiid; initiator++) { + struct ahd_devinfo devinfo; + + ahd_compile_devinfo(&devinfo, target, initiator, + CAM_LUN_WILDCARD, + 'A', ROLE_UNKNOWN); + ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR, /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, /*period*/0, + /*offset*/0, /*ppr_options*/0, + AHD_TRANS_CUR, /*paused*/TRUE); + } + } + #ifdef AHD_TARGET_MODE + max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7; + /* * Send an immediate notify ccb to all target more peripheral * drivers affected by this action. @@ -7953,31 +7982,51 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) /* Notify the XPT that a bus reset occurred */ ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); - + ahd_restart(ahd); /* - * Revert to async/narrow transfers until we renegotiate. + * Freeze the SIMQ until our poller can determine that + * the bus reset has really gone away. We set the initial + * timer to 0 to have the check performed as soon as possible + * from the timer context. */ - for (target = 0; target <= max_scsiid; target++) { + if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) { + ahd->flags |= AHD_RESET_POLL_ACTIVE; + ahd_freeze_simq(ahd); + ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd); + } + return (found); +} - if (ahd->enabled_targets[target] == NULL) - continue; - for (initiator = 0; initiator <= max_scsiid; initiator++) { - struct ahd_devinfo devinfo; - ahd_compile_devinfo(&devinfo, target, initiator, - CAM_LUN_WILDCARD, - 'A', ROLE_UNKNOWN); - ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_CUR, /*paused*/TRUE); - ahd_set_syncrate(ahd, &devinfo, /*period*/0, - /*offset*/0, /*ppr_options*/0, - AHD_TRANS_CUR, /*paused*/TRUE); - } +#define AHD_RESET_POLL_US 1000 +static void +ahd_reset_poll(void *arg) +{ + struct ahd_softc *ahd = arg; + u_int scsiseq1; + u_long s; + + ahd_lock(ahd, &s); + ahd_pause(ahd); + ahd_update_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); + if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) { + ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US, + ahd_reset_poll, ahd); + ahd_unpause(ahd); + ahd_unlock(ahd, &s); + return; } - ahd_restart(ahd); - - return (found); + /* Reset is now low. Complete chip reinitialization. */ + ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST); + scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE); + ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP)); + ahd_unpause(ahd); + ahd->flags &= ~AHD_RESET_POLL_ACTIVE; + ahd_unlock(ahd, &s); + ahd_release_simq(ahd); } /**************************** Statistics Processing ***************************/ diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 66e4a47bb..2eb114438 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -373,7 +373,8 @@ static void ahd_linux_handle_scsi_status(struct ahd_softc *, struct scb *); static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd); -static int ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd); +static void ahd_linux_sem_timeout(u_long arg); +static int ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo); @@ -452,13 +453,18 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) struct ahd_softc *ahd; struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device); int rtn = SCSI_MLQUEUE_HOST_BUSY; + unsigned long flags; ahd = *(struct ahd_softc **)cmd->device->host->hostdata; - cmd->scsi_done = scsi_done; - cmd->result = CAM_REQ_INPROG << 16; - rtn = ahd_linux_run_command(ahd, dev, cmd); + ahd_lock(ahd, &flags); + if (ahd->platform_data->qfrozen == 0) { + cmd->scsi_done = scsi_done; + cmd->result = CAM_REQ_INPROG << 16; + rtn = ahd_linux_run_command(ahd, dev, cmd); + } + ahd_unlock(ahd, &flags); return rtn; } @@ -669,9 +675,10 @@ static int ahd_linux_abort(struct scsi_cmnd *cmd) { int error; - - error = ahd_linux_queue_abort_cmd(cmd); + error = ahd_linux_queue_recovery_cmd(cmd, SCB_ABORT); + if (error != 0) + printf("aic79xx_abort returns 0x%x\n", error); return error; } @@ -681,97 +688,12 @@ ahd_linux_abort(struct scsi_cmnd *cmd) static int ahd_linux_dev_reset(struct scsi_cmnd *cmd) { - struct ahd_softc *ahd; - struct ahd_linux_device *dev; - struct scb *reset_scb; - u_int cdb_byte; - int retval = SUCCESS; - int paused; - int wait; - struct ahd_initiator_tinfo *tinfo; - struct ahd_tmode_tstate *tstate; - unsigned long flags; - DECLARE_COMPLETION(done); - - reset_scb = NULL; - paused = FALSE; - wait = FALSE; - ahd = *(struct ahd_softc **)cmd->device->host->hostdata; - - scmd_printk(KERN_INFO, cmd, - "Attempting to queue a TARGET RESET message:"); - - printf("CDB:"); - for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++) - printf(" 0x%x", cmd->cmnd[cdb_byte]); - printf("\n"); - - /* - * Determine if we currently own this command. - */ - dev = scsi_transport_device_data(cmd->device); - - if (dev == NULL) { - /* - * No target device for this command exists, - * so we must not still own the command. - */ - scmd_printk(KERN_INFO, cmd, "Is not an active device\n"); - return SUCCESS; - } - - /* - * Generate us a new SCB - */ - reset_scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX); - if (!reset_scb) { - scmd_printk(KERN_INFO, cmd, "No SCB available\n"); - return FAILED; - } - - tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, - cmd->device->id, &tstate); - reset_scb->io_ctx = cmd; - reset_scb->platform_data->dev = dev; - reset_scb->sg_count = 0; - ahd_set_residual(reset_scb, 0); - ahd_set_sense_residual(reset_scb, 0); - reset_scb->platform_data->xfer_len = 0; - reset_scb->hscb->control = 0; - reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd); - reset_scb->hscb->lun = cmd->device->lun; - reset_scb->hscb->cdb_len = 0; - reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET; - reset_scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE; - if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { - reset_scb->flags |= SCB_PACKETIZED; - } else { - reset_scb->hscb->control |= MK_MESSAGE; - } - dev->openings--; - dev->active++; - dev->commands_issued++; - - ahd_lock(ahd, &flags); - - LIST_INSERT_HEAD(&ahd->pending_scbs, reset_scb, pending_links); - ahd_queue_scb(ahd, reset_scb); - - ahd->platform_data->eh_done = &done; - ahd_unlock(ahd, &flags); - - printf("%s: Device reset code sleeping\n", ahd_name(ahd)); - if (!wait_for_completion_timeout(&done, 5 * HZ)) { - ahd_lock(ahd, &flags); - ahd->platform_data->eh_done = NULL; - ahd_unlock(ahd, &flags); - printf("%s: Device reset timer expired (active %d)\n", - ahd_name(ahd), dev->active); - retval = FAILED; - } - printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval); + int error; - return (retval); + error = ahd_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); + if (error != 0) + printf("aic79xx_dev_reset returns 0x%x\n", error); + return error; } /* @@ -781,8 +703,8 @@ static int ahd_linux_bus_reset(struct scsi_cmnd *cmd) { struct ahd_softc *ahd; + u_long s; int found; - unsigned long flags; ahd = *(struct ahd_softc **)cmd->device->host->hostdata; #ifdef AHD_DEBUG @@ -790,11 +712,10 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd) printf("%s: Bus reset called for cmd %p\n", ahd_name(ahd), cmd); #endif - ahd_lock(ahd, &flags); - + ahd_lock(ahd, &s); found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A', /*initiate reset*/TRUE); - ahd_unlock(ahd, &flags); + ahd_unlock(ahd, &s); if (bootverbose) printf("%s: SCSI bus reset delivered. " @@ -911,6 +832,59 @@ ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map) } /********************* Platform Dependent Functions ***************************/ +/* + * Compare "left hand" softc with "right hand" softc, returning: + * < 0 - lahd has a lower priority than rahd + * 0 - Softcs are equal + * > 0 - lahd has a higher priority than rahd + */ +int +ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd) +{ + int value; + + /* + * Under Linux, cards are ordered as follows: + * 1) PCI devices that are marked as the boot controller. + * 2) PCI devices with BIOS enabled sorted by bus/slot/func. + * 3) All remaining PCI devices sorted by bus/slot/func. + */ +#if 0 + value = (lahd->flags & AHD_BOOT_CHANNEL) + - (rahd->flags & AHD_BOOT_CHANNEL); + if (value != 0) + /* Controllers set for boot have a *higher* priority */ + return (value); +#endif + + value = (lahd->flags & AHD_BIOS_ENABLED) + - (rahd->flags & AHD_BIOS_ENABLED); + if (value != 0) + /* Controllers with BIOS enabled have a *higher* priority */ + return (value); + + /* Still equal. Sort by bus/slot/func. */ + if (aic79xx_reverse_scan != 0) + value = ahd_get_pci_bus(lahd->dev_softc) + - ahd_get_pci_bus(rahd->dev_softc); + else + value = ahd_get_pci_bus(rahd->dev_softc) + - ahd_get_pci_bus(lahd->dev_softc); + if (value != 0) + return (value); + if (aic79xx_reverse_scan != 0) + value = ahd_get_pci_slot(lahd->dev_softc) + - ahd_get_pci_slot(rahd->dev_softc); + else + value = ahd_get_pci_slot(rahd->dev_softc) + - ahd_get_pci_slot(lahd->dev_softc); + if (value != 0) + return (value); + + value = rahd->channel - lahd->channel; + return (value); +} + static void ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value) { @@ -1241,6 +1215,7 @@ ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data)); ahd->platform_data->irq = AHD_LINUX_NOIRQ; ahd_lockinit(ahd); + init_MUTEX_LOCKED(&ahd->platform_data->eh_sem); ahd->seltime = (aic79xx_seltime & 0x3) << 4; return (0); } @@ -1392,12 +1367,14 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) { case AHD_DEV_Q_BASIC: - scsi_set_tag_type(sdev, MSG_SIMPLE_TASK); - scsi_activate_tcq(sdev, dev->openings + dev->active); + scsi_adjust_queue_depth(sdev, + MSG_SIMPLE_TASK, + dev->openings + dev->active); break; case AHD_DEV_Q_TAGGED: - scsi_set_tag_type(sdev, MSG_ORDERED_TASK); - scsi_activate_tcq(sdev, dev->openings + dev->active); + scsi_adjust_queue_depth(sdev, + MSG_ORDERED_TASK, + dev->openings + dev->active); break; default: /* @@ -1406,7 +1383,9 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, * serially on the controller/device. This should * remove some latency. */ - scsi_deactivate_tcq(sdev, 1); + scsi_adjust_queue_depth(sdev, + /*NON-TAGGED*/0, + /*queue depth*/2); break; } } @@ -1485,9 +1464,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, struct ahd_tmode_tstate *tstate; u_int col_idx; uint16_t mask; - unsigned long flags; - - ahd_lock(ahd, &flags); /* * Get an scb to use. @@ -1503,7 +1479,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, } if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { ahd->flags |= AHD_RESOURCE_SHORTAGE; - ahd_unlock(ahd, &flags); return SCSI_MLQUEUE_HOST_BUSY; } @@ -1530,6 +1505,30 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, if ((tstate->auto_negotiate & mask) != 0) { scb->flags |= SCB_AUTO_NEGOTIATE; scb->hscb->control |= MK_MESSAGE; + } else if (cmd->cmnd[0] == INQUIRY + && (tinfo->curr.offset != 0 + || tinfo->curr.width != MSG_EXT_WDTR_BUS_8_BIT + || tinfo->curr.ppr_options != 0) + && (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ)==0) { + /* + * The SCSI spec requires inquiry + * commands to complete without + * reporting unit attention conditions. + * Because of this, an inquiry command + * that occurs just after a device is + * reset will result in a data phase + * with mismatched negotiated rates. + * The core already forces a renegotiation + * for reset events that are visible to + * our controller or that we initiate, + * but a third party device reset or a + * hot-plug insertion can still cause this + * issue. Therefore, we force a re-negotiation + * for every inquiry command unless we + * are async. + */ + scb->flags |= SCB_NEGOTIATE; + scb->hscb->control |= MK_MESSAGE; } if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) { @@ -1605,8 +1604,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, scb->flags |= SCB_ACTIVE; ahd_queue_scb(ahd, scb); - ahd_unlock(ahd, &flags); - return 0; } @@ -1627,6 +1624,12 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) return IRQ_RETVAL(ours); } +void +ahd_platform_flushwork(struct ahd_softc *ahd) +{ + +} + void ahd_send_async(struct ahd_softc *ahd, char channel, u_int target, u_int lun, ac_code code, void *arg) @@ -1636,6 +1639,7 @@ ahd_send_async(struct ahd_softc *ahd, char channel, { char buf[80]; struct scsi_target *starget; + struct ahd_linux_target *targ; struct info_str info; struct ahd_initiator_tinfo *tinfo; struct ahd_tmode_tstate *tstate; @@ -1668,6 +1672,7 @@ ahd_send_async(struct ahd_softc *ahd, char channel, starget = ahd->platform_data->starget[target]; if (starget == NULL) break; + targ = scsi_transport_target_data(starget); target_ppr_options = (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0) @@ -1819,9 +1824,10 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb) if (ahd_get_transaction_status(scb) == CAM_BDR_SENT || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED) ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); - - if (ahd->platform_data->eh_done) - complete(ahd->platform_data->eh_done); + if ((ahd->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) { + ahd->platform_data->flags &= ~AHD_SCB_UP_EH_SEM; + up(&ahd->platform_data->eh_sem); + } } ahd_free_scb(ahd, scb); @@ -1976,125 +1982,133 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd) { - int status; - int new_status = DID_OK; - int do_fallback = 0; - int scsi_status; - /* * Map CAM error codes into Linux Error codes. We * avoid the conversion so that the DV code has the * full error information available when making * state change decisions. */ - - status = ahd_cmd_get_transaction_status(cmd); - switch (status) { - case CAM_REQ_INPROG: - case CAM_REQ_CMP: - new_status = DID_OK; - break; - case CAM_AUTOSENSE_FAIL: - new_status = DID_ERROR; - /* Fallthrough */ - case CAM_SCSI_STATUS_ERROR: - scsi_status = ahd_cmd_get_scsi_status(cmd); - - switch(scsi_status) { - case SCSI_STATUS_CMD_TERMINATED: - case SCSI_STATUS_CHECK_COND: - if ((cmd->result >> 24) != DRIVER_SENSE) { - do_fallback = 1; - } else { - struct scsi_sense_data *sense; - - sense = (struct scsi_sense_data *) - &cmd->sense_buffer; - if (sense->extra_len >= 5 && - (sense->add_sense_code == 0x47 - || sense->add_sense_code == 0x48)) - do_fallback = 1; - } + { + uint32_t status; + u_int new_status; + + status = ahd_cmd_get_transaction_status(cmd); + switch (status) { + case CAM_REQ_INPROG: + case CAM_REQ_CMP: + case CAM_SCSI_STATUS_ERROR: + new_status = DID_OK; + break; + case CAM_REQ_ABORTED: + new_status = DID_ABORT; + break; + case CAM_BUSY: + new_status = DID_BUS_BUSY; + break; + case CAM_REQ_INVALID: + case CAM_PATH_INVALID: + new_status = DID_BAD_TARGET; + break; + case CAM_SEL_TIMEOUT: + new_status = DID_NO_CONNECT; + break; + case CAM_SCSI_BUS_RESET: + case CAM_BDR_SENT: + new_status = DID_RESET; + break; + case CAM_UNCOR_PARITY: + new_status = DID_PARITY; + break; + case CAM_CMD_TIMEOUT: + new_status = DID_TIME_OUT; + break; + case CAM_UA_ABORT: + case CAM_REQ_CMP_ERR: + case CAM_AUTOSENSE_FAIL: + case CAM_NO_HBA: + case CAM_DATA_RUN_ERR: + case CAM_UNEXP_BUSFREE: + case CAM_SEQUENCE_FAIL: + case CAM_CCB_LEN_ERR: + case CAM_PROVIDE_FAIL: + case CAM_REQ_TERMIO: + case CAM_UNREC_HBA_ERROR: + case CAM_REQ_TOO_BIG: + new_status = DID_ERROR; + break; + case CAM_REQUEUE_REQ: + new_status = DID_REQUEUE; break; default: + /* We should never get here */ + new_status = DID_ERROR; break; } - break; - case CAM_REQ_ABORTED: - new_status = DID_ABORT; - break; - case CAM_BUSY: - new_status = DID_BUS_BUSY; - break; - case CAM_REQ_INVALID: - case CAM_PATH_INVALID: - new_status = DID_BAD_TARGET; - break; - case CAM_SEL_TIMEOUT: - new_status = DID_NO_CONNECT; - break; - case CAM_SCSI_BUS_RESET: - case CAM_BDR_SENT: - new_status = DID_RESET; - break; - case CAM_UNCOR_PARITY: - new_status = DID_PARITY; - do_fallback = 1; - break; - case CAM_CMD_TIMEOUT: - new_status = DID_TIME_OUT; - do_fallback = 1; - break; - case CAM_REQ_CMP_ERR: - case CAM_UNEXP_BUSFREE: - case CAM_DATA_RUN_ERR: - new_status = DID_ERROR; - do_fallback = 1; - break; - case CAM_UA_ABORT: - case CAM_NO_HBA: - case CAM_SEQUENCE_FAIL: - case CAM_CCB_LEN_ERR: - case CAM_PROVIDE_FAIL: - case CAM_REQ_TERMIO: - case CAM_UNREC_HBA_ERROR: - case CAM_REQ_TOO_BIG: - new_status = DID_ERROR; - break; - case CAM_REQUEUE_REQ: - new_status = DID_REQUEUE; - break; - default: - /* We should never get here */ - new_status = DID_ERROR; - break; - } - if (do_fallback) { - printf("%s: device overrun (status %x) on %d:%d:%d\n", - ahd_name(ahd), status, cmd->device->channel, - cmd->device->id, cmd->device->lun); + ahd_cmd_set_transaction_status(cmd, new_status); } - ahd_cmd_set_transaction_status(cmd, new_status); - cmd->scsi_done(cmd); } +static void +ahd_linux_sem_timeout(u_long arg) +{ + struct ahd_softc *ahd; + u_long s; + + ahd = (struct ahd_softc *)arg; + + ahd_lock(ahd, &s); + if ((ahd->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) { + ahd->platform_data->flags &= ~AHD_SCB_UP_EH_SEM; + up(&ahd->platform_data->eh_sem); + } + ahd_unlock(ahd, &s); +} + void ahd_freeze_simq(struct ahd_softc *ahd) { - scsi_block_requests(ahd->platform_data->host); + unsigned long s; + + ahd_lock(ahd, &s); + ahd->platform_data->qfrozen++; + if (ahd->platform_data->qfrozen == 1) { + scsi_block_requests(ahd->platform_data->host); + ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS, + CAM_LUN_WILDCARD, SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ); + } + ahd_unlock(ahd, &s); } void ahd_release_simq(struct ahd_softc *ahd) { - scsi_unblock_requests(ahd->platform_data->host); + u_long s; + int unblock_reqs; + + unblock_reqs = 0; + ahd_lock(ahd, &s); + if (ahd->platform_data->qfrozen > 0) + ahd->platform_data->qfrozen--; + if (ahd->platform_data->qfrozen == 0) { + unblock_reqs = 1; + } + ahd_unlock(ahd, &s); + /* + * There is still a race here. The mid-layer + * should keep its own freeze count and use + * a bottom half handler to run the queues + * so we can unblock with our own lock held. + */ + if (unblock_reqs) + scsi_unblock_requests(ahd->platform_data->host); } static int -ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd) +ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) { struct ahd_softc *ahd; struct ahd_linux_device *dev; @@ -2109,6 +2123,7 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd) int paused; int wait; int disconnected; + int found; ahd_mode_state saved_modes; unsigned long flags; @@ -2118,7 +2133,8 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd) ahd = *(struct ahd_softc **)cmd->device->host->hostdata; scmd_printk(KERN_INFO, cmd, - "Attempting to queue an ABORT message:"); + "Attempting to queue a%s message:", + flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); printf("CDB:"); for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++) @@ -2154,6 +2170,19 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd) break; } + if (pending_scb == NULL && flag == SCB_DEVICE_RESET) { + + /* Any SCB for this device will do for a target reset */ + LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + if (ahd_match_scb(ahd, pending_scb, + scmd_id(cmd), + scmd_channel(cmd) + 'A', + CAM_LUN_WILDCARD, + SCB_LIST_NULL, ROLE_INITIATOR)) + break; + } + } + if (pending_scb == NULL) { scmd_printk(KERN_INFO, cmd, "Command not found\n"); goto no_cmd; @@ -2187,17 +2216,25 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd) ahd_dump_card_state(ahd); disconnected = TRUE; - if (ahd_search_qinfifo(ahd, cmd->device->id, - cmd->device->channel + 'A', - cmd->device->lun, - pending_scb->hscb->tag, - ROLE_INITIATOR, CAM_REQ_ABORTED, - SEARCH_COMPLETE) > 0) { - printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", - ahd_name(ahd), cmd->device->channel, - cmd->device->id, cmd->device->lun); - retval = SUCCESS; - goto done; + if (flag == SCB_ABORT) { + if (ahd_search_qinfifo(ahd, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, + pending_scb->hscb->tag, + ROLE_INITIATOR, CAM_REQ_ABORTED, + SEARCH_COMPLETE) > 0) { + printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", + ahd_name(ahd), cmd->device->channel, + cmd->device->id, cmd->device->lun); + retval = SUCCESS; + goto done; + } + } else if (ahd_search_qinfifo(ahd, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, + ROLE_INITIATOR, /*status*/0, + SEARCH_COUNT) > 0) { + disconnected = FALSE; } saved_modes = ahd_save_modes(ahd); @@ -2205,12 +2242,17 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd) last_phase = ahd_inb(ahd, LASTPHASE); saved_scbptr = ahd_get_scbptr(ahd); active_scbptr = saved_scbptr; - if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) { + if (disconnected && ((last_phase != P_BUSFREE) || + (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0)) { struct scb *bus_scb; bus_scb = ahd_lookup_scb(ahd, active_scbptr); if (bus_scb == pending_scb) disconnected = FALSE; + else if (flag != SCB_ABORT + && ahd_inb(ahd, SAVED_SCSIID) == pending_scb->hscb->scsiid + && ahd_inb(ahd, SAVED_LUN) == SCB_GET_LUN(pending_scb)) + disconnected = FALSE; } /* @@ -2219,26 +2261,41 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd) * bus or is in the disconnected state. */ saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); - if (last_phase != P_BUSFREE - && SCB_GET_TAG(pending_scb) == active_scbptr) { + if (SCB_GET_TAG(pending_scb) == active_scbptr + || (flag == SCB_DEVICE_RESET + && SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd))) { /* * We're active on the bus, so assert ATN * and hope that the target responds. */ pending_scb = ahd_lookup_scb(ahd, active_scbptr); - pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; + pending_scb->flags |= SCB_RECOVERY_SCB|SCB_DEVICE_RESET; ahd_outb(ahd, MSG_OUT, HOST_MSG); ahd_outb(ahd, SCSISIGO, last_phase|ATNO); - scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n"); + scmd_printk(KERN_INFO, cmd, "BDR message in message buffer\n"); wait = TRUE; + } else if (last_phase != P_BUSFREE + && ahd_inb(ahd, SCSIPHASE) == 0) { + /* + * SCB is not identified, there + * is no pending REQ, and the sequencer + * has not seen a busfree. Looks like + * a stuck connection waiting to + * go busfree. Reset the bus. + */ + found = ahd_reset_channel(ahd, cmd->device->channel + 'A', + /*Initiate Reset*/TRUE); + printf("%s: Issued Channel %c Bus Reset. " + "%d SCBs aborted\n", ahd_name(ahd), + cmd->device->channel + 'A', found); } else if (disconnected) { /* * Actually re-queue this SCB in an attempt * to select the device before it reconnects. */ - pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; + pending_scb->flags |= SCB_RECOVERY_SCB|flag; ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb)); pending_scb->hscb->cdb_len = 0; pending_scb->hscb->task_attribute = 0; @@ -2308,29 +2365,30 @@ done: if (paused) ahd_unpause(ahd); if (wait) { - DECLARE_COMPLETION(done); + struct timer_list timer; + int ret; - ahd->platform_data->eh_done = &done; + ahd->platform_data->flags |= AHD_SCB_UP_EH_SEM; ahd_unlock(ahd, &flags); + init_timer(&timer); + timer.data = (u_long)ahd; + timer.expires = jiffies + (5 * HZ); + timer.function = ahd_linux_sem_timeout; + add_timer(&timer); printf("%s: Recovery code sleeping\n", ahd_name(ahd)); - if (!wait_for_completion_timeout(&done, 5 * HZ)) { - ahd_lock(ahd, &flags); - ahd->platform_data->eh_done = NULL; - ahd_unlock(ahd, &flags); + down(&ahd->platform_data->eh_sem); + printf("%s: Recovery code awake\n", ahd_name(ahd)); + ret = del_timer_sync(&timer); + if (ret == 0) { printf("%s: Timer Expired (active %d)\n", ahd_name(ahd), dev->active); retval = FAILED; } - printf("Recovery code awake\n"); } else ahd_unlock(ahd, &flags); - if (retval != SUCCESS) - printf("%s: Command abort returning 0x%x\n", - ahd_name(ahd), retval); - - return retval; + return (retval); } static void ahd_linux_set_width(struct scsi_target *starget, int width) diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 2b8331649..9cb101345 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -381,12 +381,15 @@ struct ahd_platform_data { struct scsi_target *starget[AHD_NUM_TARGETS]; spinlock_t spin_lock; - struct completion *eh_done; + u_int qfrozen; + struct semaphore eh_sem; struct Scsi_Host *host; /* pointer to scsi host */ #define AHD_LINUX_NOIRQ ((uint32_t)~0) uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ +#define AHD_SCB_UP_EH_SEM 0x1 + uint32_t flags; }; /************************** OS Utility Wrappers *******************************/ @@ -872,6 +875,8 @@ int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, role_t role, uint32_t status); irqreturn_t ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); +void ahd_platform_flushwork(struct ahd_softc *ahd); +int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *); void ahd_done(struct ahd_softc*, struct scb*); void ahd_send_async(struct ahd_softc *, char channel, u_int target, u_int lun, ac_code, void *); diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index d37566978..58ac46103 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -2461,8 +2461,11 @@ ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, { if (offset == 0) period = AHC_ASYNC_XFER_PERIOD; - ahc->msgout_index += spi_populate_sync_msg( - ahc->msgout_buf + ahc->msgout_index, period, offset); + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN; + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR; + ahc->msgout_buf[ahc->msgout_index++] = period; + ahc->msgout_buf[ahc->msgout_index++] = offset; ahc->msgout_len += 5; if (bootverbose) { printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n", @@ -2479,8 +2482,10 @@ static void ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, u_int bus_width) { - ahc->msgout_index += spi_populate_width_msg( - ahc->msgout_buf + ahc->msgout_index, bus_width); + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN; + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR; + ahc->msgout_buf[ahc->msgout_index++] = bus_width; ahc->msgout_len += 4; if (bootverbose) { printf("(%s:%c:%d:%d): Sending WDTR %x\n", @@ -2500,9 +2505,14 @@ ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, { if (offset == 0) period = AHC_ASYNC_XFER_PERIOD; - ahc->msgout_index += spi_populate_ppr_msg( - ahc->msgout_buf + ahc->msgout_index, period, offset, - bus_width, ppr_options); + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED; + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN; + ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR; + ahc->msgout_buf[ahc->msgout_index++] = period; + ahc->msgout_buf[ahc->msgout_index++] = 0; + ahc->msgout_buf[ahc->msgout_index++] = offset; + ahc->msgout_buf[ahc->msgout_index++] = bus_width; + ahc->msgout_buf[ahc->msgout_index++] = ppr_options; ahc->msgout_len += 8; if (bootverbose) { printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, " diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 2c801672d..051970efb 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -373,6 +373,7 @@ static void ahc_linux_handle_scsi_status(struct ahc_softc *, struct scb *); static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd); +static void ahc_linux_sem_timeout(u_long arg); static void ahc_linux_freeze_simq(struct ahc_softc *ahc); static void ahc_linux_release_simq(struct ahc_softc *ahc); static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); @@ -1192,6 +1193,7 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); ahc->platform_data->irq = AHC_LINUX_NOIRQ; ahc_lockinit(ahc); + init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); ahc->seltime = (aic7xxx_seltime & 0x3) << 4; ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; if (aic7xxx_pci_parity == 0) @@ -1828,9 +1830,10 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) if (ahc_get_transaction_status(scb) == CAM_BDR_SENT || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED) ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); - - if (ahc->platform_data->eh_done) - complete(ahc->platform_data->eh_done); + if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { + ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; + up(&ahc->platform_data->eh_sem); + } } ahc_free_scb(ahc, scb); @@ -2036,6 +2039,22 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) cmd->scsi_done(cmd); } +static void +ahc_linux_sem_timeout(u_long arg) +{ + struct ahc_softc *ahc; + u_long s; + + ahc = (struct ahc_softc *)arg; + + ahc_lock(ahc, &s); + if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { + ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; + up(&ahc->platform_data->eh_sem); + } + ahc_unlock(ahc, &s); +} + static void ahc_linux_freeze_simq(struct ahc_softc *ahc) { @@ -2336,21 +2355,25 @@ done: if (paused) ahc_unpause(ahc); if (wait) { - DECLARE_COMPLETION(done); + struct timer_list timer; + int ret; - ahc->platform_data->eh_done = &done; + ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE; ahc_unlock(ahc, &flags); + init_timer(&timer); + timer.data = (u_long)ahc; + timer.expires = jiffies + (5 * HZ); + timer.function = ahc_linux_sem_timeout; + add_timer(&timer); printf("Recovery code sleeping\n"); - if (!wait_for_completion_timeout(&done, 5 * HZ)) { - ahc_lock(ahc, &flags); - ahc->platform_data->eh_done = NULL; - ahc_unlock(ahc, &flags); - + down(&ahc->platform_data->eh_sem); + printf("Recovery code awake\n"); + ret = del_timer_sync(&timer); + if (ret == 0) { printf("Timer Expired\n"); retval = FAILED; } - printf("Recovery code awake\n"); } else ahc_unlock(ahc, &flags); return (retval); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index a20b08c9f..e0edacae8 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -369,12 +369,15 @@ struct ahc_platform_data { spinlock_t spin_lock; u_int qfrozen; - struct completion *eh_done; + struct semaphore eh_sem; struct Scsi_Host *host; /* pointer to scsi host */ #define AHC_LINUX_NOIRQ ((uint32_t)~0) uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ + +#define AHC_UP_EH_SEMAPHORE 0x1 + uint32_t flags; }; /************************** OS Utility Wrappers *******************************/ diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 0c9c2f400..cb30d9c11 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -219,7 +219,6 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ahc->flags |= AHC_39BIT_ADDRESSING; } else { if (dma_set_mask(dev, DMA_32BIT_MASK)) { - 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 3adecef21..5f586140e 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c @@ -2036,12 +2036,12 @@ ahc_pci_resume(struct ahc_softc *ahc) * that the OS doesn't know about and rely on our chip * reset handler to handle the rest. */ - ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, - ahc->bus_softc.pci_softc.devconfig, /*bytes*/4); - ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, - ahc->bus_softc.pci_softc.command, /*bytes*/1); - ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, - ahc->bus_softc.pci_softc.csize_lattime, /*bytes*/1); + ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4, + ahc->bus_softc.pci_softc.devconfig); + ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1, + ahc->bus_softc.pci_softc.command); + ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1, + ahc->bus_softc.pci_softc.csize_lattime); if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) { struct seeprom_descriptor sd; u_int sxfrctl1; diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index fad210926..583d2d8c8 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -550,6 +550,6 @@ module_exit(cumanascsi2_exit); MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("Cumana SCSI-2 driver for Acorn machines"); -module_param_array(term, int, NULL, 0); +MODULE_PARM(term, "1-8i"); MODULE_PARM_DESC(term, "SCSI bus termination"); MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index dcbb4b2b3..3ffec7efc 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -674,6 +674,6 @@ module_exit(eesox_exit); MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("EESOX 'Fast' SCSI driver for Acorn machines"); -module_param_array(term, int, NULL, 0); +MODULE_PARM(term, "1-8i"); MODULE_PARM_DESC(term, "SCSI bus termination"); MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index 3d69f6c45..3113bdced 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -466,6 +466,6 @@ module_exit(powertecscsi_exit); MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("Powertec SCSI driver"); -module_param_array(term, int, NULL, 0); +MODULE_PARM(term, "1-8i"); MODULE_PARM_DESC(term, "SCSI bus termination"); MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 6dc88149f..fc3ca051c 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -101,54 +101,36 @@ enum { ICH5_PCS = 0x92, /* port control and status */ PIIX_SCC = 0x0A, /* sub-class code register */ - PIIX_FLAG_IGNORE_PCS = (1 << 25), /* ignore PCS present bits */ - PIIX_FLAG_SCR = (1 << 26), /* SCR available */ - PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ - PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ - PIIX_FLAG_COMBINED = (1 << 29), /* combined mode possible */ - /* ICH6/7 use different scheme for map value */ - PIIX_FLAG_COMBINED_ICH6 = PIIX_FLAG_COMBINED | (1 << 30), + PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */ + PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */ + PIIX_FLAG_COMBINED = (1 << 30), /* combined mode possible */ /* combined mode. if set, PATA is channel 0. * if clear, PATA is channel 1. */ + PIIX_COMB_PATA_P0 = (1 << 1), + PIIX_COMB = (1 << 2), /* combined mode enabled? */ + PIIX_PORT_ENABLED = (1 << 0), PIIX_PORT_PRESENT = (1 << 4), PIIX_80C_PRI = (1 << 5) | (1 << 4), PIIX_80C_SEC = (1 << 7) | (1 << 6), - /* controller IDs */ - piix4_pata = 0, - ich5_pata = 1, - ich5_sata = 2, - esb_sata = 3, - ich6_sata = 4, - ich6_sata_ahci = 5, - ich6m_sata_ahci = 6, - - /* constants for mapping table */ - P0 = 0, /* port 0 */ - P1 = 1, /* port 1 */ - P2 = 2, /* port 2 */ - P3 = 3, /* port 3 */ - IDE = -1, /* IDE */ - NA = -2, /* not avaliable */ - RV = -3, /* reserved */ + ich5_pata = 0, + ich5_sata = 1, + piix4_pata = 2, + ich6_sata = 3, + ich6_sata_ahci = 4, PIIX_AHCI_DEVICE = 6, }; -struct piix_map_db { - const u32 mask; - const int map[][4]; -}; - static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes); -static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes); +static void piix_pata_phy_reset(struct ata_port *ap); +static void piix_sata_phy_reset(struct ata_port *ap); static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); @@ -165,32 +147,19 @@ static const struct pci_device_id piix_pci_tbl[] = { * list in drivers/pci/quirks.c. */ - /* 82801EB (ICH5) */ { 0x8086, 0x24d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, - /* 82801EB (ICH5) */ { 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, - /* 6300ESB (ICH5 variant with broken PCS present bits) */ - { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata }, - /* 6300ESB pretending RAID */ - { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata }, - /* 82801FB/FW (ICH6/ICH6W) */ + { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, + { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata }, - /* 82801FR/FRW (ICH6R/ICH6RW) */ { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, - /* 82801FBM ICH6M (ICH6R with only port 0 and 2 implemented) */ - { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci }, - /* 82801GB/GR/GH (ICH7, identical to ICH6) */ + { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, - /* 2801GBM/GHM (ICH7M, identical to ICH6M) */ - { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci }, - /* Enterprise Southbridge 2 (where's the datasheet?) */ + { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, - /* SATA Controller 1 IDE (ICH8, no datasheet yet) */ { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, - /* SATA Controller 2 IDE (ICH8, ditto) */ { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, - /* Mobile SATA Controller IDE (ICH8M, ditto) */ - { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci }, + { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, { } /* terminate list */ }; @@ -209,9 +178,11 @@ static struct scsi_host_template piix_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -234,7 +205,7 @@ static const struct ata_port_operations piix_pata_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, - .probe_reset = piix_pata_probe_reset, + .phy_reset = piix_pata_phy_reset, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -262,7 +233,7 @@ static const struct ata_port_operations piix_sata_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, - .probe_reset = piix_sata_probe_reset, + .phy_reset = piix_sata_phy_reset, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -281,62 +252,12 @@ static const struct ata_port_operations piix_sata_ops = { .host_stop = ata_host_stop, }; -static struct piix_map_db ich5_map_db = { - .mask = 0x7, - .map = { - /* PM PS SM SS MAP */ - { P0, NA, P1, NA }, /* 000b */ - { P1, NA, P0, NA }, /* 001b */ - { RV, RV, RV, RV }, - { RV, RV, RV, RV }, - { P0, P1, IDE, IDE }, /* 100b */ - { P1, P0, IDE, IDE }, /* 101b */ - { IDE, IDE, P0, P1 }, /* 110b */ - { IDE, IDE, P1, P0 }, /* 111b */ - }, -}; - -static struct piix_map_db ich6_map_db = { - .mask = 0x3, - .map = { - /* PM PS SM SS MAP */ - { P0, P2, P1, P3 }, /* 00b */ - { IDE, IDE, P1, P3 }, /* 01b */ - { P0, P2, IDE, IDE }, /* 10b */ - { RV, RV, RV, RV }, - }, -}; - -static struct piix_map_db ich6m_map_db = { - .mask = 0x3, - .map = { - /* PM PS SM SS MAP */ - { P0, P2, RV, RV }, /* 00b */ - { RV, RV, RV, RV }, - { P0, P2, IDE, IDE }, /* 10b */ - { RV, RV, RV, RV }, - }, -}; - static struct ata_port_info piix_port_info[] = { - /* piix4_pata */ - { - .sht = &piix_sht, - .host_flags = ATA_FLAG_SLAVE_POSS, - .pio_mask = 0x1f, /* pio0-4 */ -#if 0 - .mwdma_mask = 0x06, /* mwdma1-2 */ -#else - .mwdma_mask = 0x00, /* mwdma broken */ -#endif - .udma_mask = ATA_UDMA_MASK_40C, - .port_ops = &piix_pata_ops, - }, - /* ich5_pata */ { .sht = &piix_sht, - .host_flags = ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR, + .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | + PIIX_FLAG_CHECKINTR, .pio_mask = 0x1f, /* pio0-4 */ #if 0 .mwdma_mask = 0x06, /* mwdma1-2 */ @@ -350,63 +271,50 @@ static struct ata_port_info piix_port_info[] = { /* ich5_sata */ { .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED | - PIIX_FLAG_CHECKINTR, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | + PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &piix_sata_ops, - .private_data = &ich5_map_db, }, - /* i6300esb_sata */ + /* piix4_pata */ { .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED | - PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS, + .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &piix_sata_ops, - .private_data = &ich5_map_db, +#if 0 + .mwdma_mask = 0x06, /* mwdma1-2 */ +#else + .mwdma_mask = 0x00, /* mwdma broken */ +#endif + .udma_mask = ATA_UDMA_MASK_40C, + .port_ops = &piix_pata_ops, }, /* ich6_sata */ { .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | - PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | + PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR | + ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &piix_sata_ops, - .private_data = &ich6_map_db, }, /* ich6_sata_ahci */ { .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | - PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &piix_sata_ops, - .private_data = &ich6_map_db, - }, - - /* ich6m_sata_ahci */ - { - .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | - PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | + PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR | + ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &piix_sata_ops, - .private_data = &ich6m_map_db, }, }; @@ -455,123 +363,102 @@ cbl40: } /** - * piix_pata_probeinit - probeinit for PATA host controller - * @ap: Target port + * piix_pata_phy_reset - Probe specified port on PATA host controller + * @ap: Port to probe * - * Probeinit including cable detection. + * Probe PATA phy. * * LOCKING: * None (inherited from caller). */ -static void piix_pata_probeinit(struct ata_port *ap) -{ - piix_pata_cbl_detect(ap); - ata_std_probeinit(ap); -} -/** - * piix_pata_probe_reset - Perform reset on PATA port and classify - * @ap: Port to reset - * @classes: Resulting classes of attached devices - * - * Reset PATA phy and classify attached devices. - * - * LOCKING: - * None (inherited from caller). - */ -static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes) +static void piix_pata_phy_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) { + ata_port_disable(ap); printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; + return; } - return ata_drive_probe_reset(ap, piix_pata_probeinit, - ata_std_softreset, NULL, - ata_std_postreset, classes); + piix_pata_cbl_detect(ap); + + ata_port_probe(ap); + + ata_bus_reset(ap); } /** * piix_sata_probe - Probe PCI device for present SATA devices * @ap: Port associated with the PCI device we wish to probe * - * Reads and configures SATA PCI device's PCI config register - * Port Configuration and Status (PCS) to determine port and - * device availability. + * Reads SATA PCI device's PCI config register Port Configuration + * and Status (PCS) to determine port and device availability. * * LOCKING: * None (inherited from caller). * * RETURNS: - * Mask of avaliable devices on the port. + * Non-zero if port is enabled, it may or may not have a device + * attached in that case (PRESENT bit would only be set if BIOS probe + * was done). Zero is returned if port is disabled. */ -static unsigned int piix_sata_probe (struct ata_port *ap) +static int piix_sata_probe (struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); - const unsigned int *map = ap->host_set->private_data; - int base = 2 * ap->hard_port_no; - unsigned int present_mask = 0; - int port, i; + int combined = (ap->flags & ATA_FLAG_SLAVE_POSS); + int orig_mask, mask, i; u8 pcs; - pci_read_config_byte(pdev, ICH5_PCS, &pcs); - DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base); - - /* enable all ports on this ap and wait for them to settle */ - for (i = 0; i < 2; i++) { - port = map[base + i]; - if (port >= 0) - pcs |= 1 << port; - } - - pci_write_config_byte(pdev, ICH5_PCS, pcs); - msleep(100); + mask = (PIIX_PORT_PRESENT << ap->hard_port_no) | + (PIIX_PORT_ENABLED << ap->hard_port_no); - /* let's see which devices are present */ pci_read_config_byte(pdev, ICH5_PCS, &pcs); + orig_mask = (int) pcs & 0xff; + + /* TODO: this is vaguely wrong for ICH6 combined mode, + * where only two of the four SATA ports are mapped + * onto a single ATA channel. It is also vaguely inaccurate + * for ICH5, which has only two ports. However, this is ok, + * as further device presence detection code will handle + * any false positives produced here. + */ - for (i = 0; i < 2; i++) { - port = map[base + i]; - if (port < 0) - continue; - if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port)) - present_mask |= 1 << i; - else - pcs &= ~(1 << port); - } - - /* disable offline ports on non-AHCI controllers */ - if (!(ap->flags & PIIX_FLAG_AHCI)) - pci_write_config_byte(pdev, ICH5_PCS, pcs); + for (i = 0; i < 4; i++) { + mask = (PIIX_PORT_ENABLED << i); - DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", - ap->id, pcs, present_mask); + if ((orig_mask & mask) == mask) + if (combined || (i == ap->hard_port_no)) + return 1; + } - return present_mask; + return 0; } /** - * piix_sata_probe_reset - Perform reset on SATA port and classify - * @ap: Port to reset - * @classes: Resulting classes of attached devices + * piix_sata_phy_reset - Probe specified port on SATA host controller + * @ap: Port to probe * - * Reset SATA phy and classify attached devices. + * Probe SATA phy. * * LOCKING: * None (inherited from caller). */ -static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes) + +static void piix_sata_phy_reset(struct ata_port *ap) { if (!piix_sata_probe(ap)) { + ata_port_disable(ap); printk(KERN_INFO "ata%u: SATA port has no device.\n", ap->id); - return 0; + return; } - return ata_drive_probe_reset(ap, ata_std_probeinit, - ata_std_softreset, NULL, - ata_std_postreset, classes); + ap->cbl = ATA_CBL_SATA; + + ata_port_probe(ap); + + ata_bus_reset(ap); } /** @@ -740,8 +627,7 @@ static int piix_disable_ahci(struct pci_dev *pdev) /** * piix_check_450nx_errata - Check for problem 450NX setup - * @ata_dev: the PCI device to check - * + * * Check for the present of 450NX errata #19 and errata #25. If * they are found return an error code so we can turn off DMA */ @@ -752,7 +638,7 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev) u16 cfg; u8 rev; int no_piix_dma = 0; - + while((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL) { /* Look for 450NX PXB. Check for problem configurations @@ -771,55 +657,7 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev) if(no_piix_dma == 2) dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n"); return no_piix_dma; -} - -static void __devinit piix_init_sata_map(struct pci_dev *pdev, - struct ata_port_info *pinfo) -{ - struct piix_map_db *map_db = pinfo[0].private_data; - const unsigned int *map; - int i, invalid_map = 0; - u8 map_value; - - pci_read_config_byte(pdev, ICH5_PMR, &map_value); - - map = map_db->map[map_value & map_db->mask]; - - dev_printk(KERN_INFO, &pdev->dev, "MAP ["); - for (i = 0; i < 4; i++) { - switch (map[i]) { - case RV: - invalid_map = 1; - printk(" XX"); - break; - - case NA: - printk(" --"); - break; - - case IDE: - WARN_ON((i & 1) || map[i + 1] != IDE); - pinfo[i / 2] = piix_port_info[ich5_pata]; - i++; - printk(" IDE IDE"); - break; - - default: - printk(" P%d", map[i]); - if (i & 1) - pinfo[i / 2].host_flags |= ATA_FLAG_SLAVE_POSS; - break; - } - } - printk(" ]\n"); - - if (invalid_map) - dev_printk(KERN_ERR, &pdev->dev, - "invalid MAP value %u\n", map_value); - - pinfo[0].private_data = (void *)map; - pinfo[1].private_data = (void *)map; -} +} /** * piix_init_one - Register PIIX ATA PCI device with kernel services @@ -839,9 +677,9 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_port_info port_info[2]; - struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] }; - unsigned long host_flags; + struct ata_port_info *port_info[2]; + unsigned int combined = 0; + unsigned int pata_chan = 0, sata_chan = 0; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, @@ -851,12 +689,10 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (!in_module_init) return -ENODEV; - port_info[0] = piix_port_info[ent->driver_data]; - port_info[1] = piix_port_info[ent->driver_data]; - - host_flags = port_info[0].host_flags; + port_info[0] = &piix_port_info[ent->driver_data]; + port_info[1] = &piix_port_info[ent->driver_data]; - if (host_flags & PIIX_FLAG_AHCI) { + if (port_info[0]->host_flags & PIIX_FLAG_AHCI) { u8 tmp; pci_read_config_byte(pdev, PIIX_SCC, &tmp); if (tmp == PIIX_AHCI_DEVICE) { @@ -866,9 +702,18 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) } } - /* Initialize SATA map */ - if (host_flags & ATA_FLAG_SATA) - piix_init_sata_map(pdev, port_info); + if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) { + u8 tmp; + pci_read_config_byte(pdev, ICH5_PMR, &tmp); + + if (tmp & PIIX_COMB) { + combined = 1; + if (tmp & PIIX_COMB_PATA_P0) + sata_chan = 1; + else + pata_chan = 1; + } + } /* On ICH5, some BIOSen disable the interrupt using the * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3. @@ -876,19 +721,28 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) * MSI is disabled (and it is disabled, as we don't use * message-signalled interrupts currently). */ - if (host_flags & PIIX_FLAG_CHECKINTR) + if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR) pci_intx(pdev, 1); + if (combined) { + port_info[sata_chan] = &piix_port_info[ent->driver_data]; + port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS; + port_info[pata_chan] = &piix_port_info[ich5_pata]; + + dev_printk(KERN_WARNING, &pdev->dev, + "combined mode detected (p=%u, s=%u)\n", + pata_chan, sata_chan); + } if (piix_check_450nx_errata(pdev)) { /* This writes into the master table but it does not really matter for this errata as we will apply it to all the PIIX devices on the board */ - port_info[0].mwdma_mask = 0; - port_info[0].udma_mask = 0; - port_info[1].mwdma_mask = 0; - port_info[1].udma_mask = 0; + port_info[0]->mwdma_mask = 0; + port_info[0]->udma_mask = 0; + port_info[1]->mwdma_mask = 0; + port_info[1]->udma_mask = 0; } - return ata_pci_init_one(pdev, ppinfo, 2); + return ata_pci_init_one(pdev, port_info, 2); } static int __init piix_init(void) diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index f677c5a32..f4c1ca7c1 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -239,17 +239,17 @@ static int atari_read_overruns = 0; #endif static int setup_can_queue = -1; -module_param(setup_can_queue, int, 0); +MODULE_PARM(setup_can_queue, "i"); static int setup_cmd_per_lun = -1; -module_param(setup_cmd_per_lun, int, 0); +MODULE_PARM(setup_cmd_per_lun, "i"); static int setup_sg_tablesize = -1; -module_param(setup_sg_tablesize, int, 0); +MODULE_PARM(setup_sg_tablesize, "i"); #ifdef SUPPORT_TAGS static int setup_use_tagged_queuing = -1; -module_param(setup_use_tagged_queuing, int, 0); +MODULE_PARM(setup_use_tagged_queuing, "i"); #endif static int setup_hostid = -1; -module_param(setup_hostid, int, 0); +MODULE_PARM(setup_hostid, "i"); #if defined(CONFIG_TT_DMA_EMUL) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index a198d8666..5227a779c 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -2632,7 +2631,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_enable_device(pdev)) return -EIO; - if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { + if (!pci_set_dma_mask(pdev, 0xFFFFFFFFUL)) { 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/ch.c b/drivers/scsi/ch.c index d9abd1645..c3f27285d 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -39,7 +39,6 @@ MODULE_DESCRIPTION("device driver for scsi media changer devices"); MODULE_AUTHOR("Gerd Knorr "); MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(SCSI_CHANGER_MAJOR); static int init = 1; module_param(init, int, 0444); diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index 38e4010ef..7905b904e 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -116,7 +116,7 @@ static int __devinit dmx3191d_probe_one(struct pci_dev *pdev, out_free_irq: free_irq(shost->irq, shost); out_release_region: - release_region(io, DMX3191D_REGION_LEN); + release_region(shost->io_port, DMX3191D_REGION_LEN); out_disable_device: pci_disable_device(pdev); out: diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index b1b704a42..6e6b293dc 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -57,7 +57,6 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver"); #include #include #include -#include #include #include @@ -907,8 +906,8 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev } pci_set_master(pDev); - if (pci_set_dma_mask(pDev, DMA_64BIT_MASK) && - pci_set_dma_mask(pDev, DMA_32BIT_MASK)) + if (pci_set_dma_mask(pDev, 0xffffffffffffffffULL) && + pci_set_dma_mask(pDev, 0xffffffffULL)) return -EINVAL; base_addr0_phys = pci_resource_start(pDev,0); diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index 059eeee4b..b3f9de8f7 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -490,7 +490,6 @@ #include #include #include -#include #include #include #include @@ -1427,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, 0xffffffff)) printk("%s: warning, pci_set_dma_mask failed.\n", ha->board_name); } diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index e6bcfe949..45756fa90 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -127,7 +127,7 @@ static int ncr_53c400a = NCR_NOT_SET; static int dtc_3181e = NCR_NOT_SET; static struct override { - NCR5380_map_type NCR5380_map_name; + NCR5380_implementation_fields; int irq; int dma; int board; /* Use NCR53c400, Ricoh, etc. extensions ? */ @@ -299,10 +299,6 @@ int __init generic_NCR5380_detect(struct scsi_host_template * tpnt) }; int flags = 0; struct Scsi_Host *instance; -#ifdef CONFIG_SCSI_G_NCR5380_MEM - unsigned long base; - void __iomem *iomem; -#endif if (ncr_irq != NCR_NOT_SET) overrides[0].irq = ncr_irq; @@ -428,22 +424,15 @@ int __init generic_NCR5380_detect(struct scsi_host_template * tpnt) region_size = NCR5380_region_size; } #else - base = overrides[current_override].NCR5380_map_name; - if (!request_mem_region(base, NCR5380_region_size, "ncr5380")) - continue; - iomem = ioremap(base, NCR5380_region_size); - if (!iomem) { - release_mem_region(base, NCR5380_region_size); + if(!request_mem_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380")) continue; - } #endif instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); if (instance == NULL) { #ifndef CONFIG_SCSI_G_NCR5380_MEM release_region(overrides[current_override].NCR5380_map_name, region_size); #else - iounmap(iomem); - release_mem_region(base, NCR5380_region_size); + release_mem_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size); #endif continue; } @@ -451,8 +440,6 @@ int __init generic_NCR5380_detect(struct scsi_host_template * tpnt) instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name; #ifndef CONFIG_SCSI_G_NCR5380_MEM instance->n_io_port = region_size; -#else - ((struct NCR5380_hostdata *)instance->hostdata).iomem = iomem; #endif NCR5380_init(instance, flags); @@ -522,7 +509,6 @@ int generic_NCR5380_release_resources(struct Scsi_Host *instance) #ifndef CONFIG_SCSI_G_NCR5380_MEM release_region(instance->NCR5380_instance_name, instance->n_io_port); #else - iounmap(((struct NCR5380_hostdata *)instance->hostdata).iomem); release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size); #endif @@ -600,7 +586,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, } #else /* implies CONFIG_SCSI_G_NCR5380_MEM */ - memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128); + isa_memcpy_fromio(dst + start, NCR53C400_host_buffer + NCR5380_map_name, 128); #endif start += 128; blocks--; @@ -620,7 +606,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, } #else /* implies CONFIG_SCSI_G_NCR5380_MEM */ - memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128); + isa_memcpy_fromio(dst + start, NCR53C400_host_buffer + NCR5380_map_name, 128); #endif start += 128; blocks--; @@ -685,7 +671,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, } #else /* implies CONFIG_SCSI_G_NCR5380_MEM */ - memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128); + isa_memcpy_toio(NCR53C400_host_buffer + NCR5380_map_name, src + start, 128); #endif start += 128; blocks--; @@ -701,7 +687,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, } #else /* implies CONFIG_SCSI_G_NCR5380_MEM */ - memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128); + isa_memcpy_toio(NCR53C400_host_buffer + NCR5380_map_name, src + start, 128); #endif start += 128; blocks--; diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h index d60a89cb8..656fbe2f9 100644 --- a/drivers/scsi/g_NCR5380.h +++ b/drivers/scsi/g_NCR5380.h @@ -82,15 +82,6 @@ static const char* generic_NCR5380_info(struct Scsi_Host *); #define NCR5380_read(reg) (inb(NCR5380_map_name + (reg))) #define NCR5380_write(reg, value) (outb((value), (NCR5380_map_name + (reg)))) -#define NCR5380_implementation_fields \ - NCR5380_map_type NCR5380_map_name - -#define NCR5380_local_declare() \ - register NCR5380_implementation_fields - -#define NCR5380_setup(instance) \ - NCR5380_map_name = (NCR5380_map_type)((instance)->NCR5380_instance_name) - #else /* therefore CONFIG_SCSI_G_NCR5380_MEM */ @@ -104,20 +95,18 @@ static const char* generic_NCR5380_info(struct Scsi_Host *); #define NCR53C400_host_buffer 0x3900 #define NCR5380_region_size 0x3a00 -#define NCR5380_read(reg) readb(iomem + NCR53C400_mem_base + (reg)) -#define NCR5380_write(reg, value) writeb(value, iomem + NCR53C400_mem_base + (reg)) +#define NCR5380_read(reg) isa_readb(NCR5380_map_name + NCR53C400_mem_base + (reg)) +#define NCR5380_write(reg, value) isa_writeb(value, NCR5380_map_name + NCR53C400_mem_base + (reg)) +#endif #define NCR5380_implementation_fields \ - NCR5380_map_type NCR5380_map_name; \ - void __iomem *iomem; + NCR5380_map_type NCR5380_map_name #define NCR5380_local_declare() \ - register void __iomem *iomem + register NCR5380_implementation_fields #define NCR5380_setup(instance) \ - iomem = (((struct NCR5380_hostdata *)(instance)->hostdata).iomem) - -#endif + NCR5380_map_name = (NCR5380_map_type)((instance)->NCR5380_instance_name) #define NCR5380_intr generic_NCR5380_intr #define NCR5380_queue_command generic_NCR5380_queue_command diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index bd801c1b4..f6d44b6f1 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -388,7 +388,6 @@ #include #include #include -#include #ifdef GDTH_RTC #include #endif @@ -657,7 +656,6 @@ module_param(probe_eisa_isa, int, 0); module_param(force_dma32, int, 0); MODULE_AUTHOR("Achim Leubner"); MODULE_LICENSE("GPL"); -MODULE_VERSION(GDTH_VERSION_STR); /* ioctl interface */ static struct file_operations gdth_fops = { @@ -673,7 +671,7 @@ static struct file_operations gdth_fops = { static struct notifier_block gdth_notifier = { gdth_halt, NULL, 0 }; -static int notifier_disabled = 0; + static void gdth_delay(int milliseconds) { @@ -3406,7 +3404,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) IStatus &= ~0x80; #ifdef INT_COAL if (coalesced) - ha->status = pcs->ext_status && 0xffff; + ha->status = pcs->ext_status & 0xffff; else #endif ha->status = gdth_readw(&dp6m_ptr->i960r.status); @@ -3418,7 +3416,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) if (coalesced) { ha->info = pcs->info0; ha->info2 = pcs->info1; - ha->service = (pcs->ext_status >> 16) && 0xffff; + ha->service = (pcs->ext_status >> 16) & 0xffff; } else #endif { @@ -4529,15 +4527,15 @@ static int __init gdth_detect(struct scsi_host_template *shtp) if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat &GDT_64BIT)|| /* 64-bit DMA only supported from FW >= x.43 */ (!ha->dma64_support)) { - if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { + if (pci_set_dma_mask(pcistr[ctr].pdev, 0xffffffff)) { printk(KERN_WARNING "GDT-PCI %d: Unable to set 32-bit DMA\n", hanum); err = TRUE; } } else { shp->max_cmd_len = 16; - if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { + if (!pci_set_dma_mask(pcistr[ctr].pdev, 0xffffffffffffffffULL)) { printk("GDT-PCI %d: 64-bit DMA enabled\n", hanum); - } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { + } else if (pci_set_dma_mask(pcistr[ctr].pdev, 0xffffffff)) { printk(KERN_WARNING "GDT-PCI %d: Unable to set 64/32-bit DMA\n", hanum); err = TRUE; } @@ -4597,13 +4595,13 @@ static int __init gdth_detect(struct scsi_host_template *shtp) add_timer(&gdth_timer); #endif major = register_chrdev(0,"gdth",&gdth_fops); - notifier_disabled = 0; register_reboot_notifier(&gdth_notifier); } gdth_polling = FALSE; return gdth_ctr_vcount; } + static int gdth_release(struct Scsi_Host *shp) { int hanum; @@ -5634,14 +5632,10 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) char cmnd[MAX_COMMAND_SIZE]; #endif - if (notifier_disabled) - return NOTIFY_OK; - TRACE2(("gdth_halt() event %d\n",(int)event)); if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) return NOTIFY_DONE; - notifier_disabled = 1; printk("GDT-HA: Flushing all host drives .. "); for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { gdth_flush(hanum); @@ -5685,6 +5679,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) #ifdef GDTH_STATISTICS del_timer(&gdth_timer); #endif + unregister_reboot_notifier(&gdth_notifier); return NOTIFY_OK; } diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index dfcb96f3e..588107923 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -294,9 +294,22 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) if (sht->unchecked_isa_dma && privsize) gfp_mask |= __GFP_DMA; - shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask); + /* Check to see if this host has any error handling facilities */ + if (!sht->eh_strategy_handler && !sht->eh_abort_handler && + !sht->eh_device_reset_handler && !sht->eh_bus_reset_handler && + !sht->eh_host_reset_handler) { + printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\n" + "ERROR: This is not a safe way to run your " + "SCSI host\n" + "ERROR: The error handling must be added to " + "this driver\n", sht->proc_name); + dump_stack(); + } + + shost = kmalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask); if (!shost) return NULL; + memset(shost, 0, sizeof(struct Scsi_Host) + privsize); spin_lock_init(&shost->default_lock); scsi_assign_lock(shost, &shost->default_lock); diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c new file mode 100644 index 000000000..9a3dae1dc --- /dev/null +++ b/drivers/scsi/hptiop.c @@ -0,0 +1,943 @@ +/* + * HighPoint RR3xxx controller driver for Linux + * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Please report bugs/comments/suggestions to linux@highpoint-tech.com + * + * For more information, visit http://www.highpoint-tech.com + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hptiop.h" + +MODULE_AUTHOR("HighPoint Technologies, Inc."); +MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx SATA Controller Driver"); + +static char driver_name[] = "hptiop"; +static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; +static const char driver_ver[] = "v1.0 (060426)"; + +static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); +static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); +static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg); + +static inline void hptiop_pci_posting_flush(struct hpt_iopmu __iomem *iop) +{ + readl(&iop->outbound_intstatus); +} + +static int iop_wait_ready(struct hpt_iopmu __iomem *iop, u32 millisec) +{ + u32 req = 0; + int i; + + for (i = 0; i < millisec; i++) { + req = readl(&iop->inbound_queue); + if (req != IOPMU_QUEUE_EMPTY) + break; + msleep(1); + } + + if (req != IOPMU_QUEUE_EMPTY) { + writel(req, &iop->outbound_queue); + hptiop_pci_posting_flush(iop); + return 0; + } + + return -1; +} + +static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag) +{ + if ((tag & IOPMU_QUEUE_MASK_HOST_BITS) == IOPMU_QUEUE_ADDR_HOST_BIT) + return hptiop_host_request_callback(hba, + tag & ~IOPMU_QUEUE_ADDR_HOST_BIT); + else + return hptiop_iop_request_callback(hba, tag); +} + +static inline void hptiop_drain_outbound_queue(struct hptiop_hba *hba) +{ + u32 req; + + while ((req = readl(&hba->iop->outbound_queue)) != IOPMU_QUEUE_EMPTY) { + + if (req & IOPMU_QUEUE_MASK_HOST_BITS) + hptiop_request_callback(hba, req); + else { + struct hpt_iop_request_header __iomem * p; + + p = (struct hpt_iop_request_header __iomem *) + ((char __iomem *)hba->iop + req); + + if (readl(&p->flags) & IOP_REQUEST_FLAG_SYNC_REQUEST) { + if (readl(&p->context)) + hptiop_request_callback(hba, req); + else + writel(1, &p->context); + } + else + hptiop_request_callback(hba, req); + } + } +} + +static int __iop_intr(struct hptiop_hba *hba) +{ + struct hpt_iopmu __iomem *iop = hba->iop; + u32 status; + int ret = 0; + + status = readl(&iop->outbound_intstatus); + + if (status & IOPMU_OUTBOUND_INT_MSG0) { + u32 msg = readl(&iop->outbound_msgaddr0); + dprintk("received outbound msg %x\n", msg); + writel(IOPMU_OUTBOUND_INT_MSG0, &iop->outbound_intstatus); + hptiop_message_callback(hba, msg); + ret = 1; + } + + if (status & IOPMU_OUTBOUND_INT_POSTQUEUE) { + hptiop_drain_outbound_queue(hba); + ret = 1; + } + + return ret; +} + +static int iop_send_sync_request(struct hptiop_hba *hba, + void __iomem *_req, u32 millisec) +{ + struct hpt_iop_request_header __iomem *req = _req; + u32 i; + + writel(readl(&req->flags) | IOP_REQUEST_FLAG_SYNC_REQUEST, + &req->flags); + + writel(0, &req->context); + + writel((unsigned long)req - (unsigned long)hba->iop, + &hba->iop->inbound_queue); + + hptiop_pci_posting_flush(hba->iop); + + for (i = 0; i < millisec; i++) { + __iop_intr(hba); + if (readl(&req->context)) + return 0; + msleep(1); + } + + return -1; +} + +static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec) +{ + u32 i; + + hba->msg_done = 0; + + writel(msg, &hba->iop->inbound_msgaddr0); + + hptiop_pci_posting_flush(hba->iop); + + for (i = 0; i < millisec; i++) { + spin_lock_irq(hba->host->host_lock); + __iop_intr(hba); + spin_unlock_irq(hba->host->host_lock); + if (hba->msg_done) + break; + msleep(1); + } + + return hba->msg_done? 0 : -1; +} + +static int iop_get_config(struct hptiop_hba *hba, + struct hpt_iop_request_get_config *config) +{ + u32 req32; + struct hpt_iop_request_get_config __iomem *req; + + req32 = readl(&hba->iop->inbound_queue); + if (req32 == IOPMU_QUEUE_EMPTY) + return -1; + + req = (struct hpt_iop_request_get_config __iomem *) + ((unsigned long)hba->iop + req32); + + writel(0, &req->header.flags); + writel(IOP_REQUEST_TYPE_GET_CONFIG, &req->header.type); + writel(sizeof(struct hpt_iop_request_get_config), &req->header.size); + writel(IOP_RESULT_PENDING, &req->header.result); + + if (iop_send_sync_request(hba, req, 20000)) { + dprintk("Get config send cmd failed\n"); + return -1; + } + + memcpy_fromio(config, req, sizeof(*config)); + writel(req32, &hba->iop->outbound_queue); + return 0; +} + +static int iop_set_config(struct hptiop_hba *hba, + struct hpt_iop_request_set_config *config) +{ + u32 req32; + struct hpt_iop_request_set_config __iomem *req; + + req32 = readl(&hba->iop->inbound_queue); + if (req32 == IOPMU_QUEUE_EMPTY) + return -1; + + req = (struct hpt_iop_request_set_config __iomem *) + ((unsigned long)hba->iop + req32); + + memcpy_toio((u8 __iomem *)req + sizeof(struct hpt_iop_request_header), + (u8 *)config + sizeof(struct hpt_iop_request_header), + sizeof(struct hpt_iop_request_set_config) - + sizeof(struct hpt_iop_request_header)); + + writel(0, &req->header.flags); + writel(IOP_REQUEST_TYPE_SET_CONFIG, &req->header.type); + writel(sizeof(struct hpt_iop_request_set_config), &req->header.size); + writel(IOP_RESULT_PENDING, &req->header.result); + + if (iop_send_sync_request(hba, req, 20000)) { + dprintk("Set config send cmd failed\n"); + return -1; + } + + writel(req32, &hba->iop->outbound_queue); + return 0; +} + +static int hptiop_initialize_iop(struct hptiop_hba *hba) +{ + struct hpt_iopmu __iomem *iop = hba->iop; + + /* enable interrupts */ + writel(~(IOPMU_OUTBOUND_INT_POSTQUEUE | IOPMU_OUTBOUND_INT_MSG0), + &iop->outbound_intmask); + + hba->initialized = 1; + + /* start background tasks */ + if (iop_send_sync_msg(hba, + IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 5000)) { + printk(KERN_ERR "scsi%d: fail to start background task\n", + hba->host->host_no); + return -1; + } + return 0; +} + +static int hptiop_map_pci_bar(struct hptiop_hba *hba) +{ + u32 mem_base_phy, length; + void __iomem *mem_base_virt; + struct pci_dev *pcidev = hba->pcidev; + + if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) { + printk(KERN_ERR "scsi%d: pci resource invalid\n", + hba->host->host_no); + return -1; + } + + mem_base_phy = pci_resource_start(pcidev, 0); + length = pci_resource_len(pcidev, 0); + mem_base_virt = ioremap(mem_base_phy, length); + + if (!mem_base_virt) { + printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n", + hba->host->host_no); + return -1; + } + + hba->iop = mem_base_virt; + dprintk("hptiop_map_pci_bar: iop=%p\n", hba->iop); + return 0; +} + +static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg) +{ + dprintk("iop message 0x%x\n", msg); + + if (!hba->initialized) + return; + + if (msg == IOPMU_INBOUND_MSG0_RESET) { + atomic_set(&hba->resetting, 0); + wake_up(&hba->reset_wq); + } + else if (msg <= IOPMU_INBOUND_MSG0_MAX) + hba->msg_done = 1; +} + +static inline struct hptiop_request *get_req(struct hptiop_hba *hba) +{ + struct hptiop_request *ret; + + dprintk("get_req : req=%p\n", hba->req_list); + + ret = hba->req_list; + if (ret) + hba->req_list = ret->next; + + return ret; +} + +static inline void free_req(struct hptiop_hba *hba, struct hptiop_request *req) +{ + dprintk("free_req(%d, %p)\n", req->index, req); + req->next = hba->req_list; + hba->req_list = req; +} + +static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag) +{ + struct hpt_iop_request_scsi_command *req; + struct scsi_cmnd *scp; + + req = (struct hpt_iop_request_scsi_command *)hba->reqs[tag].req_virt; + dprintk("hptiop_host_request_callback: req=%p, type=%d, " + "result=%d, context=0x%x tag=%d\n", + req, req->header.type, req->header.result, + req->header.context, tag); + + BUG_ON(!req->header.result); + BUG_ON(req->header.type != cpu_to_le32(IOP_REQUEST_TYPE_SCSI_COMMAND)); + + scp = hba->reqs[tag].scp; + + if (HPT_SCP(scp)->mapped) { + if (scp->use_sg) + pci_unmap_sg(hba->pcidev, + (struct scatterlist *)scp->request_buffer, + scp->use_sg, + scp->sc_data_direction + ); + else + pci_unmap_single(hba->pcidev, + HPT_SCP(scp)->dma_handle, + scp->request_bufflen, + scp->sc_data_direction + ); + } + + switch (le32_to_cpu(req->header.result)) { + case IOP_RESULT_SUCCESS: + scp->result = (DID_OK<<16); + break; + case IOP_RESULT_BAD_TARGET: + scp->result = (DID_BAD_TARGET<<16); + break; + case IOP_RESULT_BUSY: + scp->result = (DID_BUS_BUSY<<16); + break; + case IOP_RESULT_RESET: + scp->result = (DID_RESET<<16); + break; + case IOP_RESULT_FAIL: + scp->result = (DID_ERROR<<16); + break; + case IOP_RESULT_INVALID_REQUEST: + scp->result = (DID_ABORT<<16); + break; + case IOP_RESULT_MODE_SENSE_CHECK_CONDITION: + scp->result = SAM_STAT_CHECK_CONDITION; + memset(&scp->sense_buffer, + 0, sizeof(scp->sense_buffer)); + memcpy(&scp->sense_buffer, + &req->sg_list, le32_to_cpu(req->dataxfer_length)); + break; + + default: + scp->result = ((DRIVER_INVALID|SUGGEST_ABORT)<<24) | + (DID_ABORT<<16); + break; + } + + dprintk("scsi_done(%p)\n", scp); + scp->scsi_done(scp); + free_req(hba, &hba->reqs[tag]); +} + +void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag) +{ + struct hpt_iop_request_header __iomem *req; + struct hpt_iop_request_ioctl_command __iomem *p; + struct hpt_ioctl_k *arg; + + req = (struct hpt_iop_request_header __iomem *) + ((unsigned long)hba->iop + tag); + dprintk("hptiop_iop_request_callback: req=%p, type=%d, " + "result=%d, context=0x%x tag=%d\n", + req, readl(&req->type), readl(&req->result), + readl(&req->context), tag); + + BUG_ON(!readl(&req->result)); + BUG_ON(readl(&req->type) != IOP_REQUEST_TYPE_IOCTL_COMMAND); + + p = (struct hpt_iop_request_ioctl_command __iomem *)req; + arg = (struct hpt_ioctl_k *)(unsigned long) + (readl(&req->context) | + ((u64)readl(&req->context_hi32)<<32)); + + if (readl(&req->result) == IOP_RESULT_SUCCESS) { + arg->result = HPT_IOCTL_RESULT_OK; + + if (arg->outbuf_size) + memcpy_fromio(arg->outbuf, + &p->buf[(readl(&p->inbuf_size) + 3)& ~3], + arg->outbuf_size); + + if (arg->bytes_returned) + *arg->bytes_returned = arg->outbuf_size; + } + else + arg->result = HPT_IOCTL_RESULT_FAILED; + + arg->done(arg); + writel(tag, &hba->iop->outbound_queue); +} + +static irqreturn_t hptiop_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct hptiop_hba *hba = dev_id; + int handled; + unsigned long flags; + + spin_lock_irqsave(hba->host->host_lock, flags); + handled = __iop_intr(hba); + spin_unlock_irqrestore(hba->host->host_lock, flags); + + return handled; +} + +static int hptiop_buildsgl(struct scsi_cmnd *scp, struct hpt_iopsg *psg) +{ + struct Scsi_Host *host = scp->device->host; + struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; + struct scatterlist *sglist = (struct scatterlist *)scp->request_buffer; + + /* + * though we'll not get non-use_sg fields anymore, + * keep use_sg checking anyway + */ + if (scp->use_sg) { + int idx; + + HPT_SCP(scp)->sgcnt = pci_map_sg(hba->pcidev, + sglist, scp->use_sg, + scp->sc_data_direction); + HPT_SCP(scp)->mapped = 1; + BUG_ON(HPT_SCP(scp)->sgcnt > hba->max_sg_descriptors); + + for (idx = 0; idx < HPT_SCP(scp)->sgcnt; idx++) { + psg[idx].pci_address = + cpu_to_le64(sg_dma_address(&sglist[idx])); + psg[idx].size = cpu_to_le32(sg_dma_len(&sglist[idx])); + psg[idx].eot = (idx == HPT_SCP(scp)->sgcnt - 1) ? + cpu_to_le32(1) : 0; + } + + return HPT_SCP(scp)->sgcnt; + } else { + HPT_SCP(scp)->dma_handle = pci_map_single( + hba->pcidev, + scp->request_buffer, + scp->request_bufflen, + scp->sc_data_direction + ); + HPT_SCP(scp)->mapped = 1; + psg->pci_address = cpu_to_le64(HPT_SCP(scp)->dma_handle); + psg->size = cpu_to_le32(scp->request_bufflen); + psg->eot = cpu_to_le32(1); + return 1; + } +} + +static int hptiop_queuecommand(struct scsi_cmnd *scp, + void (*done)(struct scsi_cmnd *)) +{ + struct Scsi_Host *host = scp->device->host; + struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; + struct hpt_iop_request_scsi_command *req; + int sg_count = 0; + struct hptiop_request *_req; + + BUG_ON(!done); + scp->scsi_done = done; + + _req = get_req(hba); + if (_req == NULL) { + dprintk("hptiop_queuecmd : no free req\n"); + return SCSI_MLQUEUE_HOST_BUSY; + } + + _req->scp = scp; + + dprintk("hptiop_queuecmd(scp=%p) %d/%d/%d/%d cdb=(%x-%x-%x) " + "req_index=%d, req=%p\n", + scp, + host->host_no, scp->device->channel, + scp->device->id, scp->device->lun, + *((u32 *)&scp->cmnd), + *((u32 *)&scp->cmnd + 1), + *((u32 *)&scp->cmnd + 2), + _req->index, _req->req_virt); + + scp->result = 0; + + if (scp->device->channel || scp->device->lun || + scp->device->id > hba->max_devices) { + scp->result = DID_BAD_TARGET << 16; + free_req(hba, _req); + goto cmd_done; + } + + req = (struct hpt_iop_request_scsi_command *)_req->req_virt; + + /* build S/G table */ + if (scp->request_bufflen) + sg_count = hptiop_buildsgl(scp, req->sg_list); + else + HPT_SCP(scp)->mapped = 0; + + req->header.flags = cpu_to_le32(IOP_REQUEST_FLAG_OUTPUT_CONTEXT); + req->header.type = cpu_to_le32(IOP_REQUEST_TYPE_SCSI_COMMAND); + req->header.result = cpu_to_le32(IOP_RESULT_PENDING); + req->header.context = cpu_to_le32(IOPMU_QUEUE_ADDR_HOST_BIT | + (u32)_req->index); + req->header.context_hi32 = 0; + req->dataxfer_length = cpu_to_le32(scp->request_bufflen); + req->channel = scp->device->channel; + req->target = scp->device->id; + req->lun = scp->device->lun; + req->header.size = cpu_to_le32( + sizeof(struct hpt_iop_request_scsi_command) + - sizeof(struct hpt_iopsg) + + sg_count * sizeof(struct hpt_iopsg)); + + memcpy(req->cdb, scp->cmnd, sizeof(req->cdb)); + + writel(IOPMU_QUEUE_ADDR_HOST_BIT | _req->req_shifted_phy, + &hba->iop->inbound_queue); + + return 0; + +cmd_done: + dprintk("scsi_done(scp=%p)\n", scp); + scp->scsi_done(scp); + return 0; +} + +static const char *hptiop_info(struct Scsi_Host *host) +{ + return driver_name_long; +} + +static int hptiop_reset_hba(struct hptiop_hba *hba) +{ + if (atomic_xchg(&hba->resetting, 1) == 0) { + atomic_inc(&hba->reset_count); + writel(IOPMU_INBOUND_MSG0_RESET, + &hba->iop->inbound_msgaddr0); + hptiop_pci_posting_flush(hba->iop); + } + + wait_event_timeout(hba->reset_wq, + atomic_read(&hba->resetting) == 0, 60 * HZ); + + if (atomic_read(&hba->resetting)) { + /* IOP is in unkown state, abort reset */ + printk(KERN_ERR "scsi%d: reset failed\n", hba->host->host_no); + return -1; + } + + if (iop_send_sync_msg(hba, + IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 5000)) { + dprintk("scsi%d: fail to start background task\n", + hba->host->host_no); + } + + return 0; +} + +static int hptiop_reset(struct scsi_cmnd *scp) +{ + struct Scsi_Host * host = scp->device->host; + struct hptiop_hba * hba = (struct hptiop_hba *)host->hostdata; + + printk(KERN_WARNING "hptiop_reset(%d/%d/%d) scp=%p\n", + scp->device->host->host_no, scp->device->channel, + scp->device->id, scp); + + return hptiop_reset_hba(hba)? FAILED : SUCCESS; +} + +static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev, + int queue_depth) +{ + if(queue_depth > 256) + queue_depth = 256; + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); + return queue_depth; +} + +static ssize_t hptiop_show_version(struct class_device *class_dev, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", driver_ver); +} + +static ssize_t hptiop_show_fw_version(struct class_device *class_dev, char *buf) +{ + struct Scsi_Host *host = class_to_shost(class_dev); + struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; + + return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", + hba->firmware_version >> 24, + (hba->firmware_version >> 16) & 0xff, + (hba->firmware_version >> 8) & 0xff, + hba->firmware_version & 0xff); +} + +static struct class_device_attribute hptiop_attr_version = { + .attr = { + .name = "driver-version", + .mode = S_IRUGO, + }, + .show = hptiop_show_version, +}; + +static struct class_device_attribute hptiop_attr_fw_version = { + .attr = { + .name = "firmware-version", + .mode = S_IRUGO, + }, + .show = hptiop_show_fw_version, +}; + +static struct class_device_attribute *hptiop_attrs[] = { + &hptiop_attr_version, + &hptiop_attr_fw_version, + NULL +}; + +static struct scsi_host_template driver_template = { + .module = THIS_MODULE, + .name = driver_name, + .queuecommand = hptiop_queuecommand, + .eh_device_reset_handler = hptiop_reset, + .eh_bus_reset_handler = hptiop_reset, + .info = hptiop_info, + .unchecked_isa_dma = 0, + .emulated = 0, + .use_clustering = ENABLE_CLUSTERING, + .proc_name = driver_name, + .shost_attrs = hptiop_attrs, + .this_id = -1, + .change_queue_depth = hptiop_adjust_disk_queue_depth, +}; + +static int __devinit hptiop_probe(struct pci_dev *pcidev, + const struct pci_device_id *id) +{ + struct Scsi_Host *host = NULL; + struct hptiop_hba *hba; + struct hpt_iop_request_get_config iop_config; + struct hpt_iop_request_set_config set_config; + dma_addr_t start_phy; + void *start_virt; + u32 offset, i, req_size; + + dprintk("hptiop_probe(%p)\n", pcidev); + + if (pci_enable_device(pcidev)) { + printk(KERN_ERR "hptiop: fail to enable pci device\n"); + return -ENODEV; + } + + printk(KERN_INFO "adapter at PCI %d:%d:%d, IRQ %d\n", + pcidev->bus->number, pcidev->devfn >> 3, pcidev->devfn & 7, + pcidev->irq); + + 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)) { + printk(KERN_ERR "hptiop: fail to set dma_mask\n"); + goto disable_pci_device; + } + } + + if (pci_request_regions(pcidev, driver_name)) { + printk(KERN_ERR "hptiop: pci_request_regions failed\n"); + goto disable_pci_device; + } + + host = scsi_host_alloc(&driver_template, sizeof(struct hptiop_hba)); + if (!host) { + printk(KERN_ERR "hptiop: fail to alloc scsi host\n"); + goto free_pci_regions; + } + + hba = (struct hptiop_hba *)host->hostdata; + + hba->pcidev = pcidev; + hba->host = host; + hba->initialized = 0; + + atomic_set(&hba->resetting, 0); + atomic_set(&hba->reset_count, 0); + + init_waitqueue_head(&hba->reset_wq); + init_waitqueue_head(&hba->ioctl_wq); + + host->max_lun = 1; + host->max_channel = 0; + host->io_port = 0; + host->n_io_port = 0; + host->irq = pcidev->irq; + + if (hptiop_map_pci_bar(hba)) + goto free_scsi_host; + + if (iop_wait_ready(hba->iop, 20000)) { + printk(KERN_ERR "scsi%d: firmware not ready\n", + hba->host->host_no); + goto unmap_pci_bar; + } + + if (iop_get_config(hba, &iop_config)) { + printk(KERN_ERR "scsi%d: get config failed\n", + hba->host->host_no); + goto unmap_pci_bar; + } + + hba->max_requests = min(le32_to_cpu(iop_config.max_requests), + HPTIOP_MAX_REQUESTS); + hba->max_devices = le32_to_cpu(iop_config.max_devices); + hba->max_request_size = le32_to_cpu(iop_config.request_size); + hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count); + hba->firmware_version = le32_to_cpu(iop_config.firmware_version); + hba->sdram_size = le32_to_cpu(iop_config.sdram_size); + + host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9; + host->max_id = le32_to_cpu(iop_config.max_devices); + host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count); + host->can_queue = le32_to_cpu(iop_config.max_requests); + host->cmd_per_lun = le32_to_cpu(iop_config.max_requests); + host->max_cmd_len = 16; + + set_config.vbus_id = cpu_to_le32(host->host_no); + set_config.iop_id = cpu_to_le32(host->host_no); + + if (iop_set_config(hba, &set_config)) { + printk(KERN_ERR "scsi%d: set config failed\n", + hba->host->host_no); + goto unmap_pci_bar; + } + + pci_set_drvdata(pcidev, host); + + if (request_irq(pcidev->irq, hptiop_intr, SA_SHIRQ, + driver_name, hba)) { + printk(KERN_ERR "scsi%d: request irq %d failed\n", + hba->host->host_no, pcidev->irq); + goto unmap_pci_bar; + } + + /* Allocate request mem */ + req_size = sizeof(struct hpt_iop_request_scsi_command) + + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1); + if ((req_size& 0x1f) != 0) + req_size = (req_size + 0x1f) & ~0x1f; + + dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests); + + hba->req_size = req_size; + start_virt = dma_alloc_coherent(&pcidev->dev, + hba->req_size*hba->max_requests + 0x20, + &start_phy, GFP_KERNEL); + + if (!start_virt) { + printk(KERN_ERR "scsi%d: fail to alloc request mem\n", + hba->host->host_no); + goto free_request_irq; + } + + hba->dma_coherent = start_virt; + hba->dma_coherent_handle = start_phy; + + if ((start_phy & 0x1f) != 0) + { + offset = ((start_phy + 0x1f) & ~0x1f) - start_phy; + start_phy += offset; + start_virt += offset; + } + + hba->req_list = start_virt; + for (i = 0; i < hba->max_requests; i++) { + hba->reqs[i].next = NULL; + hba->reqs[i].req_virt = start_virt; + hba->reqs[i].req_shifted_phy = start_phy >> 5; + hba->reqs[i].index = i; + free_req(hba, &hba->reqs[i]); + start_virt = (char *)start_virt + hba->req_size; + start_phy = start_phy + hba->req_size; + } + + /* Enable Interrupt and start background task */ + if (hptiop_initialize_iop(hba)) + goto free_request_mem; + + if (scsi_add_host(host, &pcidev->dev)) { + printk(KERN_ERR "scsi%d: scsi_add_host failed\n", + hba->host->host_no); + goto free_request_mem; + } + + + scsi_scan_host(host); + + dprintk("scsi%d: hptiop_probe successfully\n", hba->host->host_no); + return 0; + +free_request_mem: + dma_free_coherent(&hba->pcidev->dev, + hba->req_size*hba->max_requests + 0x20, + hba->dma_coherent, hba->dma_coherent_handle); + +free_request_irq: + free_irq(hba->pcidev->irq, hba); + +unmap_pci_bar: + iounmap(hba->iop); + +free_pci_regions: + pci_release_regions(pcidev) ; + +free_scsi_host: + scsi_host_put(host); + +disable_pci_device: + pci_disable_device(pcidev); + + dprintk("scsi%d: hptiop_probe fail\n", host->host_no); + return -ENODEV; +} + +static void hptiop_shutdown(struct pci_dev *pcidev) +{ + struct Scsi_Host *host = pci_get_drvdata(pcidev); + struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; + struct hpt_iopmu __iomem *iop = hba->iop; + u32 int_mask; + + dprintk("hptiop_shutdown(%p)\n", hba); + + /* stop the iop */ + if (iop_send_sync_msg(hba, IOPMU_INBOUND_MSG0_SHUTDOWN, 60000)) + printk(KERN_ERR "scsi%d: shutdown the iop timeout\n", + hba->host->host_no); + + /* disable all outbound interrupts */ + int_mask = readl(&iop->outbound_intmask); + writel(int_mask | + IOPMU_OUTBOUND_INT_MSG0 | IOPMU_OUTBOUND_INT_POSTQUEUE, + &iop->outbound_intmask); + hptiop_pci_posting_flush(iop); +} + +static void hptiop_remove(struct pci_dev *pcidev) +{ + struct Scsi_Host *host = pci_get_drvdata(pcidev); + struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; + + dprintk("scsi%d: hptiop_remove\n", hba->host->host_no); + + scsi_remove_host(host); + + hptiop_shutdown(pcidev); + + free_irq(hba->pcidev->irq, hba); + + dma_free_coherent(&hba->pcidev->dev, + hba->req_size * hba->max_requests + 0x20, + hba->dma_coherent, + hba->dma_coherent_handle); + + iounmap(hba->iop); + + pci_release_regions(hba->pcidev); + pci_set_drvdata(hba->pcidev, NULL); + pci_disable_device(hba->pcidev); + + scsi_host_put(host); +} + +static struct pci_device_id hptiop_id_table[] = { + { PCI_DEVICE(0x1103, 0x3220) }, + { PCI_DEVICE(0x1103, 0x3320) }, + {}, +}; + +MODULE_DEVICE_TABLE(pci, hptiop_id_table); + +static struct pci_driver hptiop_pci_driver = { + .name = driver_name, + .id_table = hptiop_id_table, + .probe = hptiop_probe, + .remove = hptiop_remove, + .shutdown = hptiop_shutdown, +}; + +static int __init hptiop_module_init(void) +{ + printk(KERN_INFO "%s %s\n", driver_name_long, driver_ver); + return pci_register_driver(&hptiop_pci_driver); +} + +static void __exit hptiop_module_exit(void) +{ + pci_unregister_driver(&hptiop_pci_driver); +} + + +module_init(hptiop_module_init); +module_exit(hptiop_module_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/hptiop.h b/drivers/scsi/hptiop.h new file mode 100644 index 000000000..f04f7e81d --- /dev/null +++ b/drivers/scsi/hptiop.h @@ -0,0 +1,465 @@ +/* + * HighPoint RR3xxx controller driver for Linux + * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Please report bugs/comments/suggestions to linux@highpoint-tech.com + * + * For more information, visit http://www.highpoint-tech.com + */ +#ifndef _HPTIOP_H_ +#define _HPTIOP_H_ + +/* + * logical device type. + * Identify array (logical device) and physical device. + */ +#define LDT_ARRAY 1 +#define LDT_DEVICE 2 + +/* + * Array types + */ +#define AT_UNKNOWN 0 +#define AT_RAID0 1 +#define AT_RAID1 2 +#define AT_RAID5 3 +#define AT_RAID6 4 +#define AT_JBOD 7 + +#define MAX_NAME_LENGTH 36 +#define MAX_ARRAYNAME_LEN 16 + +#define MAX_ARRAY_MEMBERS_V1 8 +#define MAX_ARRAY_MEMBERS_V2 16 + +/* keep definition for source code compatiblity */ +#define MAX_ARRAY_MEMBERS MAX_ARRAY_MEMBERS_V1 + +/* + * array flags + */ +#define ARRAY_FLAG_DISABLED 0x00000001 /* The array is disabled */ +#define ARRAY_FLAG_NEEDBUILDING 0x00000002 /* need to be rebuilt */ +#define ARRAY_FLAG_REBUILDING 0x00000004 /* in rebuilding process */ +#define ARRAY_FLAG_BROKEN 0x00000008 /* broken but still working */ +#define ARRAY_FLAG_BOOTDISK 0x00000010 /* has a active partition */ +#define ARRAY_FLAG_BOOTMARK 0x00000040 /* array has boot mark set */ +#define ARRAY_FLAG_NEED_AUTOREBUILD 0x00000080 /* auto-rebuild should start */ +#define ARRAY_FLAG_VERIFYING 0x00000100 /* is being verified */ +#define ARRAY_FLAG_INITIALIZING 0x00000200 /* is being initialized */ +#define ARRAY_FLAG_TRANSFORMING 0x00000400 /* tranform in progress */ +#define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need tranform */ +#define ARRAY_FLAG_NEEDINITIALIZING 0x00001000 /* initialization not done */ +#define ARRAY_FLAG_BROKEN_REDUNDANT 0x00002000 /* broken but redundant */ + +/* + * device flags + */ +#define DEVICE_FLAG_DISABLED 0x00000001 /* device is disabled */ +#define DEVICE_FLAG_UNINITIALIZED 0x00010000 /* device is not initialized */ +#define DEVICE_FLAG_LEGACY 0x00020000 /* lagacy drive */ +#define DEVICE_FLAG_IS_SPARE 0x80000000 /* is a spare disk */ + +/* + * ioctl codes + */ +#define HPT_CTL_CODE(x) (x+0xFF00) +#define HPT_CTL_CODE_LINUX_TO_IOP(x) ((x)-0xff00) + +#define HPT_IOCTL_GET_CONTROLLER_INFO HPT_CTL_CODE(2) +#define HPT_IOCTL_GET_CHANNEL_INFO HPT_CTL_CODE(3) +#define HPT_IOCTL_GET_LOGICAL_DEVICES HPT_CTL_CODE(4) +#define HPT_IOCTL_GET_DRIVER_CAPABILITIES HPT_CTL_CODE(19) +#define HPT_IOCTL_GET_DEVICE_INFO_V3 HPT_CTL_CODE(46) +#define HPT_IOCTL_GET_CONTROLLER_INFO_V2 HPT_CTL_CODE(47) + +/* + * Controller information. + */ +struct hpt_controller_info { + u8 chip_type; /* chip type */ + u8 interrupt_level; /* IRQ level */ + u8 num_buses; /* bus count */ + u8 chip_flags; + + u8 product_id[MAX_NAME_LENGTH];/* product name */ + u8 vendor_id[MAX_NAME_LENGTH]; /* vendor name */ +} +__attribute__((packed)); + +/* + * Channel information. + */ +struct hpt_channel_info { + __le32 io_port; /* IDE Base Port Address */ + __le32 control_port; /* IDE Control Port Address */ + __le32 devices[2]; /* device connected to this channel */ +} +__attribute__((packed)); + +/* + * Array information. + */ +struct hpt_array_info_v3 { + u8 name[MAX_ARRAYNAME_LEN]; /* array name */ + u8 description[64]; /* array description */ + u8 create_manager[16]; /* who created it */ + __le32 create_time; /* when created it */ + + u8 array_type; /* array type */ + u8 block_size_shift; /* stripe size */ + u8 ndisk; /* Number of ID in Members[] */ + u8 reserved; + + __le32 flags; /* working flags, see ARRAY_FLAG_XXX */ + __le32 members[MAX_ARRAY_MEMBERS_V2]; /* member array/disks */ + + __le32 rebuilding_progress; + __le64 rebuilt_sectors; /* rebuilding point (LBA) for single member */ + + __le32 transform_source; + __le32 transform_target; /* destination device ID */ + __le32 transforming_progress; + __le32 signature; /* persistent identification*/ + __le16 critical_members; /* bit mask of critical members */ + __le16 reserve2; + __le32 reserve; +} +__attribute__((packed)); + +/* + * physical device information. + */ +#define MAX_PARENTS_PER_DISK 8 + +struct hpt_device_info_v2 { + u8 ctlr_id; /* controller id */ + u8 path_id; /* bus */ + u8 target_id; /* id */ + u8 device_mode_setting; /* Current Data Transfer mode: 0-4 PIO0-4 */ + /* 5-7 MW DMA0-2, 8-13 UDMA0-5 */ + u8 device_type; /* device type */ + u8 usable_mode; /* highest usable mode */ + +#ifdef __BIG_ENDIAN_BITFIELD + u8 NCQ_enabled: 1; + u8 NCQ_supported: 1; + u8 TCQ_enabled: 1; + u8 TCQ_supported: 1; + u8 write_cache_enabled: 1; + u8 write_cache_supported: 1; + u8 read_ahead_enabled: 1; + u8 read_ahead_supported: 1; + u8 reserved6: 6; + u8 spin_up_mode: 2; +#else + u8 read_ahead_supported: 1; + u8 read_ahead_enabled: 1; + u8 write_cache_supported: 1; + u8 write_cache_enabled: 1; + u8 TCQ_supported: 1; + u8 TCQ_enabled: 1; + u8 NCQ_supported: 1; + u8 NCQ_enabled: 1; + u8 spin_up_mode: 2; + u8 reserved6: 6; +#endif + + __le32 flags; /* working flags, see DEVICE_FLAG_XXX */ + u8 ident[150]; /* (partitial) Identify Data of this device */ + + __le64 total_free; + __le64 max_free; + __le64 bad_sectors; + __le32 parent_arrays[MAX_PARENTS_PER_DISK]; +} +__attribute__((packed)); + +/* + * Logical device information. + */ +#define INVALID_TARGET_ID 0xFF +#define INVALID_BUS_ID 0xFF + +struct hpt_logical_device_info_v3 { + u8 type; /* LDT_ARRAY or LDT_DEVICE */ + u8 cache_policy; /* refer to CACHE_POLICY_xxx */ + u8 vbus_id; /* vbus sequence in vbus_list */ + u8 target_id; /* OS target id. 0xFF is invalid */ + /* OS name: DISK $VBusId_$TargetId */ + __le64 capacity; /* array capacity */ + __le32 parent_array; /* don't use this field for physical + device. use ParentArrays field in + hpt_device_info_v2 */ + /* reserved statistic fields */ + __le32 stat1; + __le32 stat2; + __le32 stat3; + __le32 stat4; + + union { + struct hpt_array_info_v3 array; + struct hpt_device_info_v2 device; + } __attribute__((packed)) u; + +} +__attribute__((packed)); + +/* + * ioctl structure + */ +#define HPT_IOCTL_MAGIC 0xA1B2C3D4 + +struct hpt_ioctl_u { + u32 magic; /* used to check if it's a valid ioctl packet */ + u32 ioctl_code; /* operation control code */ + void __user *inbuf; /* input data buffer */ + u32 inbuf_size; /* size of input data buffer */ + void __user *outbuf; /* output data buffer */ + u32 outbuf_size; /* size of output data buffer */ + void __user *bytes_returned; /* count of bytes returned */ +} +__attribute__((packed)); + + +struct hpt_iopmu +{ + __le32 resrved0[4]; + __le32 inbound_msgaddr0; + __le32 inbound_msgaddr1; + __le32 outbound_msgaddr0; + __le32 outbound_msgaddr1; + __le32 inbound_doorbell; + __le32 inbound_intstatus; + __le32 inbound_intmask; + __le32 outbound_doorbell; + __le32 outbound_intstatus; + __le32 outbound_intmask; + __le32 reserved1[2]; + __le32 inbound_queue; + __le32 outbound_queue; +}; + +#define IOPMU_QUEUE_EMPTY 0xffffffff +#define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 +#define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 + +#define IOPMU_OUTBOUND_INT_MSG0 1 +#define IOPMU_OUTBOUND_INT_MSG1 2 +#define IOPMU_OUTBOUND_INT_DOORBELL 4 +#define IOPMU_OUTBOUND_INT_POSTQUEUE 8 +#define IOPMU_OUTBOUND_INT_PCI 0x10 + +#define IOPMU_INBOUND_INT_MSG0 1 +#define IOPMU_INBOUND_INT_MSG1 2 +#define IOPMU_INBOUND_INT_DOORBELL 4 +#define IOPMU_INBOUND_INT_ERROR 8 +#define IOPMU_INBOUND_INT_POSTQUEUE 0x10 + +enum hpt_iopmu_message { + /* host-to-iop messages */ + IOPMU_INBOUND_MSG0_NOP = 0, + IOPMU_INBOUND_MSG0_RESET, + IOPMU_INBOUND_MSG0_FLUSH, + IOPMU_INBOUND_MSG0_SHUTDOWN, + IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK, + IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, + IOPMU_INBOUND_MSG0_MAX = 0xff, + /* iop-to-host messages */ + IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100, + IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff, + IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200, + IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff, + IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300, + IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff, +}; + +struct hpt_iop_request_header +{ + __le32 size; + __le32 type; + __le32 flags; + __le32 result; + __le32 context; /* host context */ + __le32 context_hi32; +}; + +#define IOP_REQUEST_FLAG_SYNC_REQUEST 1 +#define IOP_REQUEST_FLAG_BIST_REQUEST 2 +#define IOP_REQUEST_FLAG_REMAPPED 4 +#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8 + +enum hpt_iop_request_type { + IOP_REQUEST_TYPE_GET_CONFIG = 0, + IOP_REQUEST_TYPE_SET_CONFIG, + IOP_REQUEST_TYPE_BLOCK_COMMAND, + IOP_REQUEST_TYPE_SCSI_COMMAND, + IOP_REQUEST_TYPE_IOCTL_COMMAND, + IOP_REQUEST_TYPE_MAX +}; + +enum hpt_iop_result_type { + IOP_RESULT_PENDING = 0, + IOP_RESULT_SUCCESS, + IOP_RESULT_FAIL, + IOP_RESULT_BUSY, + IOP_RESULT_RESET, + IOP_RESULT_INVALID_REQUEST, + IOP_RESULT_BAD_TARGET, + IOP_RESULT_MODE_SENSE_CHECK_CONDITION, +}; + +struct hpt_iop_request_get_config +{ + struct hpt_iop_request_header header; + __le32 interface_version; + __le32 firmware_version; + __le32 max_requests; + __le32 request_size; + __le32 max_sg_count; + __le32 data_transfer_length; + __le32 alignment_mask; + __le32 max_devices; + __le32 sdram_size; +}; + +struct hpt_iop_request_set_config +{ + struct hpt_iop_request_header header; + __le32 iop_id; + __le32 vbus_id; + __le32 reserve[6]; +}; + +struct hpt_iopsg +{ + __le32 size; + __le32 eot; /* non-zero: end of table */ + __le64 pci_address; +}; + +struct hpt_iop_request_block_command +{ + struct hpt_iop_request_header header; + u8 channel; + u8 target; + u8 lun; + u8 pad1; + __le16 command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */ + __le16 sectors; + __le64 lba; + struct hpt_iopsg sg_list[1]; +}; + +#define IOP_BLOCK_COMMAND_READ 1 +#define IOP_BLOCK_COMMAND_WRITE 2 +#define IOP_BLOCK_COMMAND_VERIFY 3 +#define IOP_BLOCK_COMMAND_FLUSH 4 +#define IOP_BLOCK_COMMAND_SHUTDOWN 5 + +struct hpt_iop_request_scsi_command +{ + struct hpt_iop_request_header header; + u8 channel; + u8 target; + u8 lun; + u8 pad1; + u8 cdb[16]; + __le32 dataxfer_length; + struct hpt_iopsg sg_list[1]; +}; + +struct hpt_iop_request_ioctl_command +{ + struct hpt_iop_request_header header; + __le32 ioctl_code; + __le32 inbuf_size; + __le32 outbuf_size; + __le32 bytes_returned; + u8 buf[1]; + /* out data should be put at buf[(inbuf_size+3)&~3] */ +}; + +#define HPTIOP_MAX_REQUESTS 256u + +struct hptiop_request { + struct hptiop_request * next; + void * req_virt; + u32 req_shifted_phy; + struct scsi_cmnd * scp; + int index; +}; + +struct hpt_scsi_pointer { + int mapped; + int sgcnt; + dma_addr_t dma_handle; +}; + +#define HPT_SCP(scp) ((struct hpt_scsi_pointer *)&(scp)->SCp) + +struct hptiop_hba { + struct hpt_iopmu __iomem * iop; + struct Scsi_Host * host; + struct pci_dev * pcidev; + + struct list_head link; + + /* IOP config info */ + u32 firmware_version; + u32 sdram_size; + u32 max_devices; + u32 max_requests; + u32 max_request_size; + u32 max_sg_descriptors; + + u32 req_size; /* host-allocated request buffer size */ + int initialized; + int msg_done; + + struct hptiop_request * req_list; + struct hptiop_request reqs[HPTIOP_MAX_REQUESTS]; + + /* used to free allocated dma area */ + void * dma_coherent; + dma_addr_t dma_coherent_handle; + + atomic_t reset_count; + atomic_t resetting; + + wait_queue_head_t reset_wq; + wait_queue_head_t ioctl_wq; +}; + +struct hpt_ioctl_k +{ + struct hptiop_hba * hba; + u32 ioctl_code; + u32 inbuf_size; + u32 outbuf_size; + void * inbuf; + void * outbuf; + u32 * bytes_returned; + void (*done)(struct hpt_ioctl_k *); + int result; /* HPT_IOCTL_RESULT_ */ +}; + +#define HPT_IOCTL_RESULT_OK 0 +#define HPT_IOCTL_RESULT_FAILED (-1) + +#if 0 +#define dprintk(fmt, args...) do { printk(fmt, ##args); } while(0) +#else +#define dprintk(fmt, args...) +#endif + +#endif diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 24eb59e14..b60c1b927 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c @@ -2412,7 +2412,8 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, spin_lock_irqsave(hosts[i]->host_lock, flags); /* Check it */ host_index = i; if (!shpnt) { - len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter"); + len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter for host number %d\n", + shpnt->host_no); return len; } max_pun = subsystem_maxid(host_index); @@ -2488,7 +2489,7 @@ static int option_setup(char *str) } ints[0] = i - 1; internal_ibmmca_scsi_setup(cur, ints); - return 1; + return 0; } __setup("ibmmcascsi=", option_setup); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 2e9be83a6..eaefeddb2 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -168,7 +168,7 @@ static void release_event_pool(struct event_pool *pool, ++in_use; if (pool->events[i].ext_list) { dma_free_coherent(hostdata->dev, - SG_ALL * sizeof(struct srp_direct_buf), + SG_ALL * sizeof(struct memory_descriptor), pool->events[i].ext_list, pool->events[i].ext_list_token); } @@ -284,37 +284,40 @@ static void set_srp_direction(struct scsi_cmnd *cmd, struct srp_cmd *srp_cmd, int numbuf) { - u8 fmt; - if (numbuf == 0) return; - if (numbuf == 1) - fmt = SRP_DATA_DESC_DIRECT; - else { - fmt = SRP_DATA_DESC_INDIRECT; - numbuf = min(numbuf, MAX_INDIRECT_BUFS); - + if (numbuf == 1) { if (cmd->sc_data_direction == DMA_TO_DEVICE) - srp_cmd->data_out_desc_cnt = numbuf; - else - srp_cmd->data_in_desc_cnt = numbuf; + srp_cmd->data_out_format = SRP_DIRECT_BUFFER; + else + srp_cmd->data_in_format = SRP_DIRECT_BUFFER; + } else { + if (cmd->sc_data_direction == DMA_TO_DEVICE) { + srp_cmd->data_out_format = SRP_INDIRECT_BUFFER; + srp_cmd->data_out_count = + numbuf < MAX_INDIRECT_BUFS ? + numbuf: MAX_INDIRECT_BUFS; + } else { + srp_cmd->data_in_format = SRP_INDIRECT_BUFFER; + srp_cmd->data_in_count = + numbuf < MAX_INDIRECT_BUFS ? + numbuf: MAX_INDIRECT_BUFS; + } } - - if (cmd->sc_data_direction == DMA_TO_DEVICE) - srp_cmd->buf_fmt = fmt << 4; - else - srp_cmd->buf_fmt = fmt; } -static void unmap_sg_list(int num_entries, +static void unmap_sg_list(int num_entries, struct device *dev, - struct srp_direct_buf *md) -{ + struct memory_descriptor *md) +{ int i; - for (i = 0; i < num_entries; ++i) - dma_unmap_single(dev, md[i].va, md[i].len, DMA_BIDIRECTIONAL); + for (i = 0; i < num_entries; ++i) { + dma_unmap_single(dev, + md[i].virtual_address, + md[i].length, DMA_BIDIRECTIONAL); + } } /** @@ -327,26 +330,23 @@ static void unmap_cmd_data(struct srp_cmd *cmd, struct srp_event_struct *evt_struct, struct device *dev) { - u8 out_fmt, in_fmt; - - out_fmt = cmd->buf_fmt >> 4; - in_fmt = cmd->buf_fmt & ((1U << 4) - 1); - - if (out_fmt == SRP_NO_DATA_DESC && in_fmt == SRP_NO_DATA_DESC) + if ((cmd->data_out_format == SRP_NO_BUFFER) && + (cmd->data_in_format == SRP_NO_BUFFER)) return; - else if (out_fmt == SRP_DATA_DESC_DIRECT || - in_fmt == SRP_DATA_DESC_DIRECT) { - struct srp_direct_buf *data = - (struct srp_direct_buf *) cmd->add_data; - dma_unmap_single(dev, data->va, data->len, DMA_BIDIRECTIONAL); + else if ((cmd->data_out_format == SRP_DIRECT_BUFFER) || + (cmd->data_in_format == SRP_DIRECT_BUFFER)) { + struct memory_descriptor *data = + (struct memory_descriptor *)cmd->additional_data; + dma_unmap_single(dev, data->virtual_address, data->length, + DMA_BIDIRECTIONAL); } else { - struct srp_indirect_buf *indirect = - (struct srp_indirect_buf *) cmd->add_data; - int num_mapped = indirect->table_desc.len / - sizeof(struct srp_direct_buf); + struct indirect_descriptor *indirect = + (struct indirect_descriptor *)cmd->additional_data; + int num_mapped = indirect->head.length / + sizeof(indirect->list[0]); if (num_mapped <= MAX_INDIRECT_BUFS) { - unmap_sg_list(num_mapped, dev, &indirect->desc_list[0]); + unmap_sg_list(num_mapped, dev, &indirect->list[0]); return; } @@ -356,17 +356,17 @@ static void unmap_cmd_data(struct srp_cmd *cmd, static int map_sg_list(int num_entries, struct scatterlist *sg, - struct srp_direct_buf *md) + struct memory_descriptor *md) { int i; u64 total_length = 0; for (i = 0; i < num_entries; ++i) { - struct srp_direct_buf *descr = md + i; + struct memory_descriptor *descr = md + i; struct scatterlist *sg_entry = &sg[i]; - descr->va = sg_dma_address(sg_entry); - descr->len = sg_dma_len(sg_entry); - descr->key = 0; + descr->virtual_address = sg_dma_address(sg_entry); + descr->length = sg_dma_len(sg_entry); + descr->memory_handle = 0; total_length += sg_dma_len(sg_entry); } return total_length; @@ -389,10 +389,10 @@ static int map_sg_data(struct scsi_cmnd *cmd, int sg_mapped; u64 total_length = 0; struct scatterlist *sg = cmd->request_buffer; - struct srp_direct_buf *data = - (struct srp_direct_buf *) srp_cmd->add_data; - struct srp_indirect_buf *indirect = - (struct srp_indirect_buf *) data; + struct memory_descriptor *data = + (struct memory_descriptor *)srp_cmd->additional_data; + struct indirect_descriptor *indirect = + (struct indirect_descriptor *)data; sg_mapped = dma_map_sg(dev, sg, cmd->use_sg, DMA_BIDIRECTIONAL); @@ -403,9 +403,9 @@ static int map_sg_data(struct scsi_cmnd *cmd, /* special case; we can use a single direct descriptor */ if (sg_mapped == 1) { - data->va = sg_dma_address(&sg[0]); - data->len = sg_dma_len(&sg[0]); - data->key = 0; + data->virtual_address = sg_dma_address(&sg[0]); + data->length = sg_dma_len(&sg[0]); + data->memory_handle = 0; return 1; } @@ -416,26 +416,25 @@ static int map_sg_data(struct scsi_cmnd *cmd, return 0; } - indirect->table_desc.va = 0; - indirect->table_desc.len = sg_mapped * sizeof(struct srp_direct_buf); - indirect->table_desc.key = 0; + indirect->head.virtual_address = 0; + indirect->head.length = sg_mapped * sizeof(indirect->list[0]); + indirect->head.memory_handle = 0; if (sg_mapped <= MAX_INDIRECT_BUFS) { - total_length = map_sg_list(sg_mapped, sg, - &indirect->desc_list[0]); - indirect->len = total_length; + total_length = map_sg_list(sg_mapped, sg, &indirect->list[0]); + indirect->total_length = total_length; return 1; } /* get indirect table */ if (!evt_struct->ext_list) { - evt_struct->ext_list = (struct srp_direct_buf *) + evt_struct->ext_list =(struct memory_descriptor*) dma_alloc_coherent(dev, - SG_ALL * sizeof(struct srp_direct_buf), - &evt_struct->ext_list_token, 0); + SG_ALL * sizeof(struct memory_descriptor), + &evt_struct->ext_list_token, 0); if (!evt_struct->ext_list) { - printk(KERN_ERR - "ibmvscsi: Can't allocate memory for indirect table\n"); + printk(KERN_ERR + "ibmvscsi: Can't allocate memory for indirect table\n"); return 0; } @@ -443,11 +442,11 @@ static int map_sg_data(struct scsi_cmnd *cmd, total_length = map_sg_list(sg_mapped, sg, evt_struct->ext_list); - indirect->len = total_length; - indirect->table_desc.va = evt_struct->ext_list_token; - indirect->table_desc.len = sg_mapped * sizeof(indirect->desc_list[0]); - memcpy(indirect->desc_list, evt_struct->ext_list, - MAX_INDIRECT_BUFS * sizeof(struct srp_direct_buf)); + indirect->total_length = total_length; + indirect->head.virtual_address = evt_struct->ext_list_token; + indirect->head.length = sg_mapped * sizeof(indirect->list[0]); + memcpy(indirect->list, evt_struct->ext_list, + MAX_INDIRECT_BUFS * sizeof(struct memory_descriptor)); return 1; } @@ -464,20 +463,20 @@ static int map_sg_data(struct scsi_cmnd *cmd, static int map_single_data(struct scsi_cmnd *cmd, struct srp_cmd *srp_cmd, struct device *dev) { - struct srp_direct_buf *data = - (struct srp_direct_buf *) srp_cmd->add_data; + struct memory_descriptor *data = + (struct memory_descriptor *)srp_cmd->additional_data; - data->va = + data->virtual_address = dma_map_single(dev, cmd->request_buffer, cmd->request_bufflen, DMA_BIDIRECTIONAL); - if (dma_mapping_error(data->va)) { + if (dma_mapping_error(data->virtual_address)) { printk(KERN_ERR "ibmvscsi: Unable to map request_buffer for command!\n"); return 0; } - data->len = cmd->request_bufflen; - data->key = 0; + data->length = cmd->request_bufflen; + data->memory_handle = 0; set_srp_direction(cmd, srp_cmd, 1); @@ -549,7 +548,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, /* Copy the IU into the transfer area */ *evt_struct->xfer_iu = evt_struct->iu; - evt_struct->xfer_iu->srp.rsp.tag = (u64)evt_struct; + evt_struct->xfer_iu->srp.generic.tag = (u64)evt_struct; /* Add this to the sent list. We need to do this * before we actually send @@ -587,27 +586,27 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct) struct srp_rsp *rsp = &evt_struct->xfer_iu->srp.rsp; struct scsi_cmnd *cmnd = evt_struct->cmnd; - if (unlikely(rsp->opcode != SRP_RSP)) { + if (unlikely(rsp->type != SRP_RSP_TYPE)) { if (printk_ratelimit()) printk(KERN_WARNING "ibmvscsi: bad SRP RSP type %d\n", - rsp->opcode); + rsp->type); } if (cmnd) { cmnd->result = rsp->status; if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION) memcpy(cmnd->sense_buffer, - rsp->data, - rsp->sense_data_len); + rsp->sense_and_response_data, + rsp->sense_data_list_length); unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, evt_struct->hostdata->dev); - if (rsp->flags & SRP_RSP_FLAG_DOOVER) - cmnd->resid = rsp->data_out_res_cnt; - else if (rsp->flags & SRP_RSP_FLAG_DIOVER) - cmnd->resid = rsp->data_in_res_cnt; + if (rsp->doover) + cmnd->resid = rsp->data_out_residual_count; + else if (rsp->diover) + cmnd->resid = rsp->data_in_residual_count; } if (evt_struct->cmnd_done) @@ -634,11 +633,10 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, { struct srp_cmd *srp_cmd; struct srp_event_struct *evt_struct; - struct srp_indirect_buf *indirect; + struct indirect_descriptor *indirect; struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)&cmnd->device->host->hostdata; u16 lun = lun_from_dev(cmnd->device); - u8 out_fmt, in_fmt; evt_struct = get_event_struct(&hostdata->pool); if (!evt_struct) @@ -646,8 +644,8 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, /* Set up the actual SRP IU */ srp_cmd = &evt_struct->iu.srp.cmd; - memset(srp_cmd, 0x00, SRP_MAX_IU_LEN); - srp_cmd->opcode = SRP_CMD; + memset(srp_cmd, 0x00, sizeof(*srp_cmd)); + srp_cmd->type = SRP_CMD_TYPE; memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd)); srp_cmd->lun = ((u64) lun) << 48; @@ -666,15 +664,13 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, evt_struct->cmnd_done = done; /* Fix up dma address of the buffer itself */ - indirect = (struct srp_indirect_buf *) srp_cmd->add_data; - out_fmt = srp_cmd->buf_fmt >> 4; - in_fmt = srp_cmd->buf_fmt & ((1U << 4) - 1); - if ((in_fmt == SRP_DATA_DESC_INDIRECT || - out_fmt == SRP_DATA_DESC_INDIRECT) && - indirect->table_desc.va == 0) { - indirect->table_desc.va = evt_struct->crq.IU_data_ptr + - offsetof(struct srp_cmd, add_data) + - offsetof(struct srp_indirect_buf, desc_list); + indirect = (struct indirect_descriptor *)srp_cmd->additional_data; + if (((srp_cmd->data_out_format == SRP_INDIRECT_BUFFER) || + (srp_cmd->data_in_format == SRP_INDIRECT_BUFFER)) && + (indirect->head.virtual_address == 0)) { + indirect->head.virtual_address = evt_struct->crq.IU_data_ptr + + offsetof(struct srp_cmd, additional_data) + + offsetof(struct indirect_descriptor, list); } return ibmvscsi_send_srp_event(evt_struct, hostdata); @@ -739,8 +735,7 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) { struct viosrp_adapter_info *req; struct srp_event_struct *evt_struct; - dma_addr_t addr; - + evt_struct = get_event_struct(&hostdata->pool); if (!evt_struct) { printk(KERN_ERR "ibmvscsi: couldn't allocate an event " @@ -758,10 +753,10 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) req->common.type = VIOSRP_ADAPTER_INFO_TYPE; req->common.length = sizeof(hostdata->madapter_info); - req->buffer = addr = dma_map_single(hostdata->dev, - &hostdata->madapter_info, - sizeof(hostdata->madapter_info), - DMA_BIDIRECTIONAL); + req->buffer = dma_map_single(hostdata->dev, + &hostdata->madapter_info, + sizeof(hostdata->madapter_info), + DMA_BIDIRECTIONAL); if (dma_mapping_error(req->buffer)) { printk(KERN_ERR @@ -771,13 +766,8 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) return; } - if (ibmvscsi_send_srp_event(evt_struct, hostdata)) { + if (ibmvscsi_send_srp_event(evt_struct, hostdata)) printk(KERN_ERR "ibmvscsi: couldn't send ADAPTER_INFO_REQ!\n"); - dma_unmap_single(hostdata->dev, - addr, - sizeof(hostdata->madapter_info), - DMA_BIDIRECTIONAL); - } }; /** @@ -790,10 +780,10 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) static void login_rsp(struct srp_event_struct *evt_struct) { struct ibmvscsi_host_data *hostdata = evt_struct->hostdata; - switch (evt_struct->xfer_iu->srp.login_rsp.opcode) { - case SRP_LOGIN_RSP: /* it worked! */ + switch (evt_struct->xfer_iu->srp.generic.type) { + case SRP_LOGIN_RSP_TYPE: /* it worked! */ break; - case SRP_LOGIN_REJ: /* refused! */ + case SRP_LOGIN_REJ_TYPE: /* refused! */ printk(KERN_INFO "ibmvscsi: SRP_LOGIN_REJ reason %u\n", evt_struct->xfer_iu->srp.login_rej.reason); /* Login failed. */ @@ -802,7 +792,7 @@ static void login_rsp(struct srp_event_struct *evt_struct) default: printk(KERN_ERR "ibmvscsi: Invalid login response typecode 0x%02x!\n", - evt_struct->xfer_iu->srp.login_rsp.opcode); + evt_struct->xfer_iu->srp.generic.type); /* Login failed. */ atomic_set(&hostdata->request_limit, -1); return; @@ -810,17 +800,17 @@ static void login_rsp(struct srp_event_struct *evt_struct) printk(KERN_INFO "ibmvscsi: SRP_LOGIN succeeded\n"); - if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta > + if (evt_struct->xfer_iu->srp.login_rsp.request_limit_delta > (max_requests - 2)) - evt_struct->xfer_iu->srp.login_rsp.req_lim_delta = + evt_struct->xfer_iu->srp.login_rsp.request_limit_delta = max_requests - 2; /* Now we know what the real request-limit is */ atomic_set(&hostdata->request_limit, - evt_struct->xfer_iu->srp.login_rsp.req_lim_delta); + evt_struct->xfer_iu->srp.login_rsp.request_limit_delta); hostdata->host->can_queue = - evt_struct->xfer_iu->srp.login_rsp.req_lim_delta - 2; + evt_struct->xfer_iu->srp.login_rsp.request_limit_delta - 2; if (hostdata->host->can_queue < 1) { printk(KERN_ERR "ibmvscsi: Invalid request_limit_delta\n"); @@ -859,19 +849,18 @@ static int send_srp_login(struct ibmvscsi_host_data *hostdata) login = &evt_struct->iu.srp.login_req; memset(login, 0x00, sizeof(struct srp_login_req)); - login->opcode = SRP_LOGIN_REQ; - login->req_it_iu_len = sizeof(union srp_iu); - login->req_buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT; + login->type = SRP_LOGIN_REQ_TYPE; + login->max_requested_initiator_to_target_iulen = sizeof(union srp_iu); + login->required_buffer_formats = 0x0006; - spin_lock_irqsave(hostdata->host->host_lock, flags); /* Start out with a request limit of 1, since this is negotiated in * the login request we are just sending */ atomic_set(&hostdata->request_limit, 1); + spin_lock_irqsave(hostdata->host->host_lock, flags); rc = ibmvscsi_send_srp_event(evt_struct, hostdata); spin_unlock_irqrestore(hostdata->host->host_lock, flags); - printk("ibmvscsic: sent SRP login\n"); return rc; }; @@ -939,13 +928,13 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) /* Set up an abort SRP command */ memset(tsk_mgmt, 0x00, sizeof(*tsk_mgmt)); - tsk_mgmt->opcode = SRP_TSK_MGMT; + tsk_mgmt->type = SRP_TSK_MGMT_TYPE; tsk_mgmt->lun = ((u64) lun) << 48; - tsk_mgmt->tsk_mgmt_func = SRP_TSK_ABORT_TASK; - tsk_mgmt->task_tag = (u64) found_evt; + tsk_mgmt->task_mgmt_flags = 0x01; /* ABORT TASK */ + tsk_mgmt->managed_task_tag = (u64) found_evt; printk(KERN_INFO "ibmvscsi: aborting command. lun 0x%lx, tag 0x%lx\n", - tsk_mgmt->lun, tsk_mgmt->task_tag); + tsk_mgmt->lun, tsk_mgmt->managed_task_tag); evt->sync_srp = &srp_rsp; init_completion(&evt->comp); @@ -959,25 +948,25 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) wait_for_completion(&evt->comp); /* make sure we got a good response */ - if (unlikely(srp_rsp.srp.rsp.opcode != SRP_RSP)) { + if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) { if (printk_ratelimit()) printk(KERN_WARNING "ibmvscsi: abort bad SRP RSP type %d\n", - srp_rsp.srp.rsp.opcode); + srp_rsp.srp.generic.type); return FAILED; } - if (srp_rsp.srp.rsp.flags & SRP_RSP_FLAG_RSPVALID) - rsp_rc = *((int *)srp_rsp.srp.rsp.data); + if (srp_rsp.srp.rsp.rspvalid) + rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data); else rsp_rc = srp_rsp.srp.rsp.status; if (rsp_rc) { if (printk_ratelimit()) printk(KERN_WARNING - "ibmvscsi: abort code %d for task tag 0x%lx\n", + "ibmvscsi: abort code %d for task tag 0x%lx\n", rsp_rc, - tsk_mgmt->task_tag); + tsk_mgmt->managed_task_tag); return FAILED; } @@ -998,13 +987,13 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) spin_unlock_irqrestore(hostdata->host->host_lock, flags); printk(KERN_INFO "ibmvscsi: aborted task tag 0x%lx completed\n", - tsk_mgmt->task_tag); + tsk_mgmt->managed_task_tag); return SUCCESS; } printk(KERN_INFO "ibmvscsi: successfully aborted task tag 0x%lx\n", - tsk_mgmt->task_tag); + tsk_mgmt->managed_task_tag); cmd->result = (DID_ABORT << 16); list_del(&found_evt->list); @@ -1051,9 +1040,9 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) /* Set up a lun reset SRP command */ memset(tsk_mgmt, 0x00, sizeof(*tsk_mgmt)); - tsk_mgmt->opcode = SRP_TSK_MGMT; + tsk_mgmt->type = SRP_TSK_MGMT_TYPE; tsk_mgmt->lun = ((u64) lun) << 48; - tsk_mgmt->tsk_mgmt_func = SRP_TSK_LUN_RESET; + tsk_mgmt->task_mgmt_flags = 0x08; /* LUN RESET */ printk(KERN_INFO "ibmvscsi: resetting device. lun 0x%lx\n", tsk_mgmt->lun); @@ -1070,16 +1059,16 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) wait_for_completion(&evt->comp); /* make sure we got a good response */ - if (unlikely(srp_rsp.srp.rsp.opcode != SRP_RSP)) { + if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) { if (printk_ratelimit()) printk(KERN_WARNING "ibmvscsi: reset bad SRP RSP type %d\n", - srp_rsp.srp.rsp.opcode); + srp_rsp.srp.generic.type); return FAILED; } - if (srp_rsp.srp.rsp.flags & SRP_RSP_FLAG_RSPVALID) - rsp_rc = *((int *)srp_rsp.srp.rsp.data); + if (srp_rsp.srp.rsp.rspvalid) + rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data); else rsp_rc = srp_rsp.srp.rsp.status; @@ -1087,7 +1076,8 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) if (printk_ratelimit()) printk(KERN_WARNING "ibmvscsi: reset code %d for task tag 0x%lx\n", - rsp_rc, tsk_mgmt->task_tag); + rsp_rc, + tsk_mgmt->managed_task_tag); return FAILED; } @@ -1189,7 +1179,6 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, /* We need to re-setup the interpartition connection */ printk(KERN_INFO "ibmvscsi: Re-enabling adapter!\n"); - atomic_set(&hostdata->request_limit, -1); purge_requests(hostdata, DID_REQUEUE); if (ibmvscsi_reenable_crq_queue(&hostdata->queue, hostdata) == 0) @@ -1237,7 +1226,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, } if (crq->format == VIOSRP_SRP_FORMAT) - atomic_add(evt_struct->xfer_iu->srp.rsp.req_lim_delta, + atomic_add(evt_struct->xfer_iu->srp.rsp.request_limit_delta, &hostdata->request_limit); if (evt_struct->done) @@ -1265,7 +1254,6 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, { struct viosrp_host_config *host_config; struct srp_event_struct *evt_struct; - dma_addr_t addr; int rc; evt_struct = get_event_struct(&hostdata->pool); @@ -1286,9 +1274,8 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, memset(host_config, 0x00, sizeof(*host_config)); host_config->common.type = VIOSRP_HOST_CONFIG_TYPE; host_config->common.length = length; - host_config->buffer = addr = dma_map_single(hostdata->dev, buffer, - length, - DMA_BIDIRECTIONAL); + host_config->buffer = dma_map_single(hostdata->dev, buffer, length, + DMA_BIDIRECTIONAL); if (dma_mapping_error(host_config->buffer)) { printk(KERN_ERR @@ -1299,9 +1286,11 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, init_completion(&evt_struct->comp); rc = ibmvscsi_send_srp_event(evt_struct, hostdata); - if (rc == 0) + if (rc == 0) { wait_for_completion(&evt_struct->comp); - dma_unmap_single(hostdata->dev, addr, length, DMA_BIDIRECTIONAL); + dma_unmap_single(hostdata->dev, host_config->buffer, + length, DMA_BIDIRECTIONAL); + } return rc; } diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 5c6d93582..4550d71e4 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -68,7 +68,7 @@ struct srp_event_struct { void (*cmnd_done) (struct scsi_cmnd *); struct completion comp; union viosrp_iu *sync_srp; - struct srp_direct_buf *ext_list; + struct memory_descriptor *ext_list; dma_addr_t ext_list_token; }; diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 1a9992bdf..f47dd87c0 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -34,6 +34,7 @@ #include #include #include "ibmvscsi.h" +#include "srp.h" static char partition_name[97] = "UNKNOWN"; static unsigned int partition_number = -1; @@ -79,7 +80,7 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, tasklet_kill(&hostdata->srp_task); do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); - } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); + } while ((rc == H_Busy) || (H_isLongBusy(rc))); dma_unmap_single(hostdata->dev, queue->msg_token, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); @@ -229,7 +230,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, queue->msg_token, PAGE_SIZE); - if (rc == H_RESOURCE) + if (rc == H_Resource) /* maybe kexecing and resource is busy. try a reset */ rc = ibmvscsi_reset_crq_queue(queue, hostdata); @@ -268,7 +269,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, req_irq_failed: do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); - } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); + } while ((rc == H_Busy) || (H_isLongBusy(rc))); reg_crq_failed: dma_unmap_single(hostdata->dev, queue->msg_token, @@ -294,7 +295,7 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, /* Re-enable the CRQ */ do { rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address); - } while ((rc == H_IN_PROGRESS) || (rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); + } while ((rc == H_InProgress) || (rc == H_Busy) || (H_isLongBusy(rc))); if (rc) printk(KERN_ERR "ibmvscsi: Error %d enabling adapter\n", rc); @@ -316,7 +317,7 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, /* Close the CRQ */ do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); - } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); + } while ((rc == H_Busy) || (H_isLongBusy(rc))); /* Clean out the queue */ memset(queue->msgs, 0x00, PAGE_SIZE); diff --git a/drivers/scsi/ibmvscsi/srp.h b/drivers/scsi/ibmvscsi/srp.h new file mode 100644 index 000000000..7d8e4c4ac --- /dev/null +++ b/drivers/scsi/ibmvscsi/srp.h @@ -0,0 +1,227 @@ +/*****************************************************************************/ +/* srp.h -- SCSI RDMA Protocol definitions */ +/* */ +/* Written By: Colin Devilbis, IBM Corporation */ +/* */ +/* Copyright (C) 2003 IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* */ +/* */ +/* This file contains structures and definitions for the SCSI RDMA Protocol */ +/* (SRP) as defined in the T10 standard available at www.t10.org. This */ +/* file was based on the 16a version of the standard */ +/* */ +/*****************************************************************************/ +#ifndef SRP_H +#define SRP_H + +#define SRP_VERSION "16.a" + +#define PACKED __attribute__((packed)) + +enum srp_types { + SRP_LOGIN_REQ_TYPE = 0x00, + SRP_LOGIN_RSP_TYPE = 0xC0, + SRP_LOGIN_REJ_TYPE = 0xC2, + SRP_I_LOGOUT_TYPE = 0x03, + SRP_T_LOGOUT_TYPE = 0x80, + SRP_TSK_MGMT_TYPE = 0x01, + SRP_CMD_TYPE = 0x02, + SRP_RSP_TYPE = 0xC1, + SRP_CRED_REQ_TYPE = 0x81, + SRP_CRED_RSP_TYPE = 0x41, + SRP_AER_REQ_TYPE = 0x82, + SRP_AER_RSP_TYPE = 0x42 +}; + +enum srp_descriptor_formats { + SRP_NO_BUFFER = 0x00, + SRP_DIRECT_BUFFER = 0x01, + SRP_INDIRECT_BUFFER = 0x02 +}; + +struct memory_descriptor { + u64 virtual_address; + u32 memory_handle; + u32 length; +}; + +struct indirect_descriptor { + struct memory_descriptor head; + u32 total_length; + struct memory_descriptor list[1] PACKED; +}; + +struct srp_generic { + u8 type; + u8 reserved1[7]; + u64 tag; +}; + +struct srp_login_req { + u8 type; + u8 reserved1[7]; + u64 tag; + u32 max_requested_initiator_to_target_iulen; + u32 reserved2; + u16 required_buffer_formats; + u8 reserved3:6; + u8 multi_channel_action:2; + u8 reserved4; + u32 reserved5; + u8 initiator_port_identifier[16]; + u8 target_port_identifier[16]; +}; + +struct srp_login_rsp { + u8 type; + u8 reserved1[3]; + u32 request_limit_delta; + u64 tag; + u32 max_initiator_to_target_iulen; + u32 max_target_to_initiator_iulen; + u16 supported_buffer_formats; + u8 reserved2:6; + u8 multi_channel_result:2; + u8 reserved3; + u8 reserved4[24]; +}; + +struct srp_login_rej { + u8 type; + u8 reserved1[3]; + u32 reason; + u64 tag; + u64 reserved2; + u16 supported_buffer_formats; + u8 reserved3[6]; +}; + +struct srp_i_logout { + u8 type; + u8 reserved1[7]; + u64 tag; +}; + +struct srp_t_logout { + u8 type; + u8 reserved1[3]; + u32 reason; + u64 tag; +}; + +struct srp_tsk_mgmt { + u8 type; + u8 reserved1[7]; + u64 tag; + u32 reserved2; + u64 lun PACKED; + u8 reserved3; + u8 reserved4; + u8 task_mgmt_flags; + u8 reserved5; + u64 managed_task_tag; + u64 reserved6; +}; + +struct srp_cmd { + u8 type; + u32 reserved1 PACKED; + u8 data_out_format:4; + u8 data_in_format:4; + u8 data_out_count; + u8 data_in_count; + u64 tag; + u32 reserved2; + u64 lun PACKED; + u8 reserved3; + u8 reserved4:5; + u8 task_attribute:3; + u8 reserved5; + u8 additional_cdb_len; + u8 cdb[16]; + u8 additional_data[0x100 - 0x30]; +}; + +struct srp_rsp { + u8 type; + u8 reserved1[3]; + u32 request_limit_delta; + u64 tag; + u16 reserved2; + u8 reserved3:2; + u8 diunder:1; + u8 diover:1; + u8 dounder:1; + u8 doover:1; + u8 snsvalid:1; + u8 rspvalid:1; + u8 status; + u32 data_in_residual_count; + u32 data_out_residual_count; + u32 sense_data_list_length; + u32 response_data_list_length; + u8 sense_and_response_data[18]; +}; + +struct srp_cred_req { + u8 type; + u8 reserved1[3]; + u32 request_limit_delta; + u64 tag; +}; + +struct srp_cred_rsp { + u8 type; + u8 reserved1[7]; + u64 tag; +}; + +struct srp_aer_req { + u8 type; + u8 reserved1[3]; + u32 request_limit_delta; + u64 tag; + u32 reserved2; + u64 lun; + u32 sense_data_list_length; + u32 reserved3; + u8 sense_data[20]; +}; + +struct srp_aer_rsp { + u8 type; + u8 reserved1[7]; + u64 tag; +}; + +union srp_iu { + struct srp_generic generic; + struct srp_login_req login_req; + struct srp_login_rsp login_rsp; + struct srp_login_rej login_rej; + struct srp_i_logout i_logout; + struct srp_t_logout t_logout; + struct srp_tsk_mgmt tsk_mgmt; + struct srp_cmd cmd; + struct srp_rsp rsp; + struct srp_cred_req cred_req; + struct srp_cred_rsp cred_rsp; + struct srp_aer_req aer_req; + struct srp_aer_rsp aer_rsp; +}; + +#endif diff --git a/drivers/scsi/ibmvscsi/viosrp.h b/drivers/scsi/ibmvscsi/viosrp.h index 90f1a6128..6a6bba8a2 100644 --- a/drivers/scsi/ibmvscsi/viosrp.h +++ b/drivers/scsi/ibmvscsi/viosrp.h @@ -33,22 +33,7 @@ /*****************************************************************************/ #ifndef VIOSRP_H #define VIOSRP_H -#include - -#define SRP_VERSION "16.a" -#define SRP_MAX_IU_LEN 256 - -union srp_iu { - struct srp_login_req login_req; - struct srp_login_rsp login_rsp; - struct srp_login_rej login_rej; - struct srp_i_logout i_logout; - struct srp_t_logout t_logout; - struct srp_tsk_mgmt tsk_mgmt; - struct srp_cmd cmd; - struct srp_rsp rsp; - u8 reserved[SRP_MAX_IU_LEN]; -}; +#include "srp.h" enum viosrp_crq_formats { VIOSRP_SRP_FORMAT = 0x01, diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 39b760a24..0cf0e4c7a 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include @@ -110,7 +109,7 @@ typedef struct ide_scsi_obj { unsigned long log; /* log flags */ } idescsi_scsi_t; -static DEFINE_MUTEX(idescsi_ref_mutex); +static DECLARE_MUTEX(idescsi_ref_sem); #define ide_scsi_g(disk) \ container_of((disk)->private_data, struct ide_scsi_obj, driver) @@ -119,19 +118,19 @@ static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk) { struct ide_scsi_obj *scsi = NULL; - mutex_lock(&idescsi_ref_mutex); + down(&idescsi_ref_sem); scsi = ide_scsi_g(disk); if (scsi) scsi_host_get(scsi->host); - mutex_unlock(&idescsi_ref_mutex); + up(&idescsi_ref_sem); return scsi; } static void ide_scsi_put(struct ide_scsi_obj *scsi) { - mutex_lock(&idescsi_ref_mutex); + down(&idescsi_ref_sem); scsi_host_put(scsi->host); - mutex_unlock(&idescsi_ref_mutex); + up(&idescsi_ref_sem); } static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host) diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index 9c519876f..34daa3e06 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -1898,21 +1898,6 @@ static int int_tab[] in2000__INITDATA = { 10 }; -static int probe_bios(u32 addr, u32 *s1, uchar *switches) -{ - void __iomem *p = ioremap(addr, 0x34); - if (!p) - return 0; - *s1 = readl(p + 0x10); - if (*s1 == 0x41564f4e || readl(p + 0x30) == 0x61776c41) { - /* Read the switch image that's mapped into EPROM space */ - *switches = ~readb(p + 0x20); - iounmap(p); - return 1; - } - iounmap(p); - return 0; -} static int __init in2000_detect(struct scsi_host_template * tpnt) { @@ -1945,7 +1930,6 @@ static int __init in2000_detect(struct scsi_host_template * tpnt) detect_count = 0; for (bios = 0; bios_tab[bios]; bios++) { - u32 s1 = 0; if (check_setup_args("ioport", &val, buf)) { base = val; switches = ~inb(base + IO_SWITCHES) & 0xff; @@ -1957,9 +1941,13 @@ static int __init in2000_detect(struct scsi_host_template * tpnt) * for the obvious ID strings. We look for the 2 most common ones and * hope that they cover all the cases... */ - else if (probe_bios(bios_tab[bios], &s1, &switches)) { + else if (isa_readl(bios_tab[bios] + 0x10) == 0x41564f4e || isa_readl(bios_tab[bios] + 0x30) == 0x61776c41) { printk("Found IN2000 BIOS at 0x%x ", (unsigned int) bios_tab[bios]); +/* Read the switch image that's mapped into EPROM space */ + + switches = ~((isa_readb(bios_tab[bios] + 0x20) & 0xff)); + /* Find out where the IO space is */ x = switches & (SW_ADDR0 | SW_ADDR1); @@ -2049,7 +2037,7 @@ static int __init in2000_detect(struct scsi_host_template * tpnt) /* Older BIOS's had a 'sync on/off' switch - use its setting */ - if (s1 == 0x41564f4e && (switches & SW_SYNC_DOS5)) + if (isa_readl(bios_tab[bios] + 0x10) == 0x41564f4e && (switches & SW_SYNC_DOS5)) hostdata->sync_off = 0x00; /* sync defaults to on */ else hostdata->sync_off = 0xff; /* sync defaults to off */ diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 0cc7f65b5..ea6f3c0e0 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -127,7 +127,6 @@ #include #include #include -#include #include #include @@ -2781,7 +2780,7 @@ static int tul_NewReturnNumberOfAdapters(void) if (((dRegValue & 0xFF00) >> 8) == 0xFF) dRegValue = 0; wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8)); - if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) { + if (pci_set_dma_mask(pDev, 0xffffffff)) { printk(KERN_WARNING "i91u: Could not set 32 bit DMA mask\n"); continue; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 8b80e59c8..2bba5e55d 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -164,6 +164,29 @@ MODULE_PARM_DESC(auto_create, "Auto-create single device RAID 0 arrays when init MODULE_LICENSE("GPL"); MODULE_VERSION(IPR_DRIVER_VERSION); +static const char *ipr_gpdd_dev_end_states[] = { + "Command complete", + "Terminated by host", + "Terminated by device reset", + "Terminated by bus reset", + "Unknown", + "Command not started" +}; + +static const char *ipr_gpdd_dev_bus_phases[] = { + "Bus free", + "Arbitration", + "Selection", + "Message out", + "Command", + "Message in", + "Data out", + "Data in", + "Status", + "Reselection", + "Unknown" +}; + /* A constant array of IOASCs/URCs/Error Messages */ static const struct ipr_error_table_t ipr_error_table[] = { @@ -846,8 +869,8 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) { if (res->sdev) { + res->sdev->hostdata = NULL; res->del_from_ml = 1; - res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; if (ioa_cfg->allow_ml_add_del) schedule_work(&ioa_cfg->work_q); } else @@ -1333,8 +1356,8 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, return; if (ipr_is_device(&hostrcb->hcam.u.error.failing_dev_res_addr)) { - ipr_ra_err(ioa_cfg, hostrcb->hcam.u.error.failing_dev_res_addr, - "%s\n", ipr_error_table[error_index].error); + ipr_res_err(ioa_cfg, hostrcb->hcam.u.error.failing_dev_res_addr, + "%s\n", ipr_error_table[error_index].error); } else { dev_err(&ioa_cfg->pdev->dev, "%s\n", ipr_error_table[error_index].error); @@ -2084,6 +2107,7 @@ restart: did_work = 1; sdev = res->sdev; if (!scsi_device_get(sdev)) { + res->sdev = NULL; list_move_tail(&res->queue, &ioa_cfg->free_res_q); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); scsi_remove_device(sdev); @@ -2100,7 +2124,6 @@ restart: bus = res->cfgte.res_addr.bus; target = res->cfgte.res_addr.target; lun = res->cfgte.res_addr.lun; - res->add_to_ml = 0; spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); scsi_add_device(ioa_cfg->host, bus, target, lun); spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); @@ -3191,7 +3214,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) sdev->timeout = IPR_VSET_RW_TIMEOUT; blk_queue_max_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS); } - if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res)) + if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data)) sdev->allow_restart = 1; scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); } @@ -3280,44 +3303,6 @@ static int ipr_eh_host_reset(struct scsi_cmnd * cmd) return rc; } -/** - * ipr_device_reset - Reset the device - * @ioa_cfg: ioa config struct - * @res: resource entry struct - * - * This function issues a device reset to the affected device. - * If the device is a SCSI device, a LUN reset will be sent - * to the device first. If that does not work, a target reset - * will be sent. - * - * Return value: - * 0 on success / non-zero on failure - **/ -static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, - struct ipr_resource_entry *res) -{ - struct ipr_cmnd *ipr_cmd; - struct ipr_ioarcb *ioarcb; - struct ipr_cmd_pkt *cmd_pkt; - u32 ioasc; - - ENTER; - ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); - ioarcb = &ipr_cmd->ioarcb; - cmd_pkt = &ioarcb->cmd_pkt; - - ioarcb->res_handle = res->cfgte.res_handle; - cmd_pkt->request_type = IPR_RQTYPE_IOACMD; - cmd_pkt->cdb[0] = IPR_RESET_DEVICE; - - ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); - ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); - list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - - LEAVE; - return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0); -} - /** * ipr_eh_dev_reset - Reset the device * @scsi_cmd: scsi command struct @@ -3334,7 +3319,8 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) struct ipr_cmnd *ipr_cmd; struct ipr_ioa_cfg *ioa_cfg; struct ipr_resource_entry *res; - int rc; + struct ipr_cmd_pkt *cmd_pkt; + u32 ioasc; ENTER; ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; @@ -3361,12 +3347,25 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) } res->resetting_device = 1; - scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n"); - rc = ipr_device_reset(ioa_cfg, res); + + ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); + + ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; + cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; + cmd_pkt->request_type = IPR_RQTYPE_IOACMD; + cmd_pkt->cdb[0] = IPR_RESET_DEVICE; + + ipr_sdev_err(scsi_cmd->device, "Resetting device\n"); + ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); + + ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + res->resetting_device = 0; + list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); + LEAVE; - return (rc ? FAILED : SUCCESS); + return (IPR_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS); } static int ipr_eh_dev_reset(struct scsi_cmnd * cmd) @@ -3441,7 +3440,7 @@ static void ipr_abort_timeout(struct ipr_cmnd *ipr_cmd) return; } - sdev_printk(KERN_ERR, ipr_cmd->u.sdev, "Abort timed out. Resetting bus.\n"); + ipr_sdev_err(ipr_cmd->u.sdev, "Abort timed out. Resetting bus\n"); reset_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ipr_cmd->sibling = reset_cmd; reset_cmd->sibling = ipr_cmd; @@ -3505,8 +3504,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS; ipr_cmd->u.sdev = scsi_cmd->device; - scmd_printk(KERN_ERR, scsi_cmd, "Aborting command: %02X\n", - scsi_cmd->cmnd[0]); + ipr_sdev_err(scsi_cmd->device, "Aborting command: %02X\n", scsi_cmd->cmnd[0]); ipr_send_blocking_cmd(ipr_cmd, ipr_abort_timeout, IPR_CANCEL_ALL_TIMEOUT); ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); @@ -3817,8 +3815,8 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { scsi_cmd->result |= (DID_ERROR << 16); - scmd_printk(KERN_ERR, scsi_cmd, - "Request Sense failed with IOASC: 0x%08X\n", ioasc); + ipr_sdev_err(scsi_cmd->device, + "Request Sense failed with IOASC: 0x%08X\n", ioasc); } else { memcpy(scsi_cmd->sense_buffer, ipr_cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); @@ -3940,7 +3938,6 @@ static void ipr_erp_cancel_all(struct ipr_cmnd *ipr_cmd) * ipr_dump_ioasa - Dump contents of IOASA * @ioa_cfg: ioa config struct * @ipr_cmd: ipr command struct - * @res: resource entry struct * * This function is invoked by the interrupt handler when ops * fail. It will log the IOASA if appropriate. Only called @@ -3950,7 +3947,7 @@ static void ipr_erp_cancel_all(struct ipr_cmnd *ipr_cmd) * none **/ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, - struct ipr_cmnd *ipr_cmd, struct ipr_resource_entry *res) + struct ipr_cmnd *ipr_cmd) { int i; u16 data_len; @@ -3978,7 +3975,16 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, return; } - ipr_res_err(ioa_cfg, res, "%s\n", ipr_error_table[error_index].error); + ipr_sdev_err(ipr_cmd->scsi_cmd->device, "%s\n", + ipr_error_table[error_index].error); + + if ((ioasa->u.gpdd.end_state <= ARRAY_SIZE(ipr_gpdd_dev_end_states)) && + (ioasa->u.gpdd.bus_phase <= ARRAY_SIZE(ipr_gpdd_dev_bus_phases))) { + ipr_sdev_err(ipr_cmd->scsi_cmd->device, + "Device End state: %s Phase: %s\n", + ipr_gpdd_dev_end_states[ioasa->u.gpdd.end_state], + ipr_gpdd_dev_bus_phases[ioasa->u.gpdd.bus_phase]); + } if (sizeof(struct ipr_ioasa) < be16_to_cpu(ioasa->ret_stat_len)) data_len = sizeof(struct ipr_ioasa); @@ -4135,7 +4141,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, } if (ipr_is_gscsi(res)) - ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); + ipr_dump_ioasa(ioa_cfg, ipr_cmd); else ipr_gen_sense(ipr_cmd); @@ -4534,7 +4540,7 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) ipr_cmd->job_step = ipr_ioa_reset_done; list_for_each_entry_continue(res, &ioa_cfg->used_res_q, queue) { - if (!ipr_is_scsi_disk(res)) + if (!IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data)) continue; ipr_cmd->u.res = res; @@ -4974,7 +4980,7 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) list_for_each_entry_safe(res, temp, &old_res, queue) { if (res->sdev) { res->del_from_ml = 1; - res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; + res->sdev->hostdata = NULL; list_move_tail(&res->queue, &ioa_cfg->used_res_q); } else { list_move_tail(&res->queue, &ioa_cfg->free_res_q); @@ -5824,109 +5830,6 @@ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg, shutdown_type); } -/** - * ipr_reset_freeze - Hold off all I/O activity - * @ipr_cmd: ipr command struct - * - * Description: If the PCI slot is frozen, hold off all I/O - * activity; then, as soon as the slot is available again, - * initiate an adapter reset. - */ -static int ipr_reset_freeze(struct ipr_cmnd *ipr_cmd) -{ - /* Disallow new interrupts, avoid loop */ - ipr_cmd->ioa_cfg->allow_interrupts = 0; - list_add_tail(&ipr_cmd->queue, &ipr_cmd->ioa_cfg->pending_q); - ipr_cmd->done = ipr_reset_ioa_job; - return IPR_RC_JOB_RETURN; -} - -/** - * ipr_pci_frozen - Called when slot has experienced a PCI bus error. - * @pdev: PCI device struct - * - * Description: This routine is called to tell us that the PCI bus - * is down. Can't do anything here, except put the device driver - * into a holding pattern, waiting for the PCI bus to come back. - */ -static void ipr_pci_frozen(struct pci_dev *pdev) -{ - unsigned long flags = 0; - struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); - - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_freeze, IPR_SHUTDOWN_NONE); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); -} - -/** - * ipr_pci_slot_reset - Called when PCI slot has been reset. - * @pdev: PCI device struct - * - * Description: This routine is called by the pci error recovery - * code after the PCI slot has been reset, just before we - * should resume normal operations. - */ -static pci_ers_result_t ipr_pci_slot_reset(struct pci_dev *pdev) -{ - unsigned long flags = 0; - struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); - - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_restore_cfg_space, - IPR_SHUTDOWN_NONE); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); - return PCI_ERS_RESULT_RECOVERED; -} - -/** - * ipr_pci_perm_failure - Called when PCI slot is dead for good. - * @pdev: PCI device struct - * - * Description: This routine is called when the PCI bus has - * permanently failed. - */ -static void ipr_pci_perm_failure(struct pci_dev *pdev) -{ - unsigned long flags = 0; - struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); - - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - if (ioa_cfg->sdt_state == WAIT_FOR_DUMP) - ioa_cfg->sdt_state = ABORT_DUMP; - ioa_cfg->reset_retries = IPR_NUM_RESET_RELOAD_RETRIES; - ioa_cfg->in_ioa_bringdown = 1; - ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); -} - -/** - * ipr_pci_error_detected - Called when a PCI error is detected. - * @pdev: PCI device struct - * @state: PCI channel state - * - * Description: Called when a PCI error is detected. - * - * Return value: - * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT - */ -static pci_ers_result_t ipr_pci_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) -{ - switch (state) { - case pci_channel_io_frozen: - ipr_pci_frozen(pdev); - return PCI_ERS_RESULT_NEED_RESET; - case pci_channel_io_perm_failure: - ipr_pci_perm_failure(pdev); - return PCI_ERS_RESULT_DISCONNECT; - break; - default: - break; - } - return PCI_ERS_RESULT_NEED_RESET; -} - /** * ipr_probe_ioa_part2 - Initializes IOAs found in ipr_probe_ioa(..) * @ioa_cfg: ioa cfg struct @@ -6698,18 +6601,12 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, ipr_pci_table); -static struct pci_error_handlers ipr_err_handler = { - .error_detected = ipr_pci_error_detected, - .slot_reset = ipr_pci_slot_reset, -}; - static struct pci_driver ipr_driver = { .name = IPR_NAME, .id_table = ipr_pci_table, .probe = ipr_probe, .remove = ipr_remove, .shutdown = ipr_shutdown, - .err_handler = &ipr_err_handler, }; /** diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 446f42592..fd360bfe5 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -36,23 +36,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.0.13" -#define IPR_DRIVER_DATE "(February 21, 2005)" - -/* - * IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing - * resulting in a bunch of extra debugging printks to the console - * - * IPR_DEBUG: Setting this to 1 will turn on some error path tracing. - * Enables the ipr_trace macro. - */ -#ifdef IPR_DEBUG_ALL -#define IPR_DEBUG 1 -#define IPR_DBG_TRACE 1 -#else -#define IPR_DEBUG 0 -#define IPR_DBG_TRACE 0 -#endif +#define IPR_DRIVER_VERSION "2.1.2" +#define IPR_DRIVER_DATE "(February 8, 2006)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -76,6 +61,10 @@ #define IPR_SUBS_DEV_ID_571A 0x02C0 #define IPR_SUBS_DEV_ID_571B 0x02BE #define IPR_SUBS_DEV_ID_571E 0x02BF +#define IPR_SUBS_DEV_ID_571F 0x02D5 +#define IPR_SUBS_DEV_ID_572A 0x02C1 +#define IPR_SUBS_DEV_ID_572B 0x02C2 +#define IPR_SUBS_DEV_ID_575B 0x030D #define IPR_NAME "ipr" @@ -95,7 +84,10 @@ #define IPR_IOASC_HW_DEV_BUS_STATUS 0x04448500 #define IPR_IOASC_IOASC_MASK 0xFFFFFF00 #define IPR_IOASC_SCSI_STATUS_MASK 0x000000FF +#define IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT 0x05240000 #define IPR_IOASC_IR_RESOURCE_HANDLE 0x05250000 +#define IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA 0x05258100 +#define IPR_IOASA_IR_DUAL_IOA_DISABLED 0x052C8000 #define IPR_IOASC_BUS_WAS_RESET 0x06290000 #define IPR_IOASC_BUS_WAS_RESET_BY_OTHER 0x06298000 #define IPR_IOASC_ABORTED_CMD_TERM_BY_HOST 0x0B5A0000 @@ -107,14 +99,14 @@ #define IPR_NUM_LOG_HCAMS 2 #define IPR_NUM_CFG_CHG_HCAMS 2 #define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) -#define IPR_MAX_NUM_TARGETS_PER_BUS 0x10 +#define IPR_MAX_NUM_TARGETS_PER_BUS 256 #define IPR_MAX_NUM_LUNS_PER_TARGET 256 #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 #define IPR_VSET_BUS 0xff #define IPR_IOA_BUS 0xff #define IPR_IOA_TARGET 0xff #define IPR_IOA_LUN 0xff -#define IPR_MAX_NUM_BUSES 4 +#define IPR_MAX_NUM_BUSES 8 #define IPR_MAX_BUS_TO_SCAN IPR_MAX_NUM_BUSES #define IPR_NUM_RESET_RELOAD_RETRIES 3 @@ -205,6 +197,7 @@ #define IPR_SDT_FMT2_EXP_ROM_SEL 0x8 #define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2 #define IPR_DOORBELL 0x82800000 +#define IPR_RUNTIME_RESET 0x40000000 #define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0) #define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3) @@ -261,6 +254,16 @@ struct ipr_std_inq_vpids { u8 product_id[IPR_PROD_ID_LEN]; }__attribute__((packed)); +struct ipr_vpd { + struct ipr_std_inq_vpids vpids; + u8 sn[IPR_SERIAL_NUM_LEN]; +}__attribute__((packed)); + +struct ipr_ext_vpd { + struct ipr_vpd vpd; + __be32 wwid[2]; +}__attribute__((packed)); + struct ipr_std_inq_data { u8 peri_qual_dev_type; #define IPR_STD_INQ_PERI_QUAL(peri) ((peri) >> 5) @@ -304,6 +307,10 @@ struct ipr_config_table_entry { #define IPR_SUBTYPE_GENERIC_SCSI 1 #define IPR_SUBTYPE_VOLUME_SET 2 +#define IPR_QUEUEING_MODEL(res) ((((res)->cfgte.flags) & 0x70) >> 4) +#define IPR_QUEUE_FROZEN_MODEL 0 +#define IPR_QUEUE_NACA_MODEL 1 + struct ipr_res_addr res_addr; __be32 res_handle; __be32 reserved4[2]; @@ -410,23 +417,26 @@ struct ipr_ioadl_desc { struct ipr_ioasa_vset { __be32 failing_lba_hi; __be32 failing_lba_lo; - __be32 ioa_data[22]; + __be32 reserved; }__attribute__((packed, aligned (4))); struct ipr_ioasa_af_dasd { __be32 failing_lba; + __be32 reserved[2]; }__attribute__((packed, aligned (4))); struct ipr_ioasa_gpdd { u8 end_state; u8 bus_phase; __be16 reserved; - __be32 ioa_data[23]; + __be32 ioa_data[2]; }__attribute__((packed, aligned (4))); -struct ipr_ioasa_raw { - __be32 ioa_data[24]; -}__attribute__((packed, aligned (4))); +struct ipr_auto_sense { + __be16 auto_sense_len; + __be16 ioa_data_len; + __be32 data[SCSI_SENSE_BUFFERSIZE/sizeof(__be32)]; +}; struct ipr_ioasa { __be32 ioasc; @@ -453,6 +463,8 @@ struct ipr_ioasa { __be32 fd_res_handle; __be32 ioasc_specific; /* status code specific field */ +#define IPR_ADDITIONAL_STATUS_FMT 0x80000000 +#define IPR_AUTOSENSE_VALID 0x40000000 #define IPR_IOASC_SPECIFIC_MASK 0x00ffffff #define IPR_FIELD_POINTER_VALID (0x80000000 >> 8) #define IPR_FIELD_POINTER_MASK 0x0000ffff @@ -461,8 +473,9 @@ struct ipr_ioasa { struct ipr_ioasa_vset vset; struct ipr_ioasa_af_dasd dasd; struct ipr_ioasa_gpdd gpdd; - struct ipr_ioasa_raw raw; } u; + + struct ipr_auto_sense auto_sense; }__attribute__((packed, aligned (4))); struct ipr_mode_parm_hdr { @@ -536,28 +549,49 @@ struct ipr_inquiry_page3 { u8 patch_number[4]; }__attribute__((packed)); +#define IPR_INQUIRY_PAGE0_ENTRIES 20 +struct ipr_inquiry_page0 { + u8 peri_qual_dev_type; + u8 page_code; + u8 reserved1; + u8 len; + u8 page[IPR_INQUIRY_PAGE0_ENTRIES]; +}__attribute__((packed)); + struct ipr_hostrcb_device_data_entry { - struct ipr_std_inq_vpids dev_vpids; - u8 dev_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd vpd; struct ipr_res_addr dev_res_addr; - struct ipr_std_inq_vpids new_dev_vpids; - u8 new_dev_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids ioa_last_with_dev_vpids; - u8 ioa_last_with_dev_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_last_with_dev_vpids; - u8 cfc_last_with_dev_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd new_vpd; + struct ipr_vpd ioa_last_with_dev_vpd; + struct ipr_vpd cfc_last_with_dev_vpd; __be32 ioa_data[5]; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb_device_data_entry_enhanced { + struct ipr_ext_vpd vpd; + u8 ccin[4]; + struct ipr_res_addr dev_res_addr; + struct ipr_ext_vpd new_vpd; + u8 new_ccin[4]; + struct ipr_ext_vpd ioa_last_with_dev_vpd; + struct ipr_ext_vpd cfc_last_with_dev_vpd; +}__attribute__((packed, aligned (4))); + struct ipr_hostrcb_array_data_entry { - struct ipr_std_inq_vpids vpids; - u8 serial_num[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd vpd; + struct ipr_res_addr expected_dev_res_addr; + struct ipr_res_addr dev_res_addr; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_array_data_entry_enhanced { + struct ipr_ext_vpd vpd; + u8 ccin[4]; struct ipr_res_addr expected_dev_res_addr; struct ipr_res_addr dev_res_addr; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_ff_error { - __be32 ioa_data[246]; + __be32 ioa_data[502]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_01_error { @@ -568,47 +602,75 @@ struct ipr_hostrcb_type_01_error { }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_02_error { - struct ipr_std_inq_vpids ioa_vpids; - u8 ioa_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_vpids; - u8 cfc_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids ioa_last_attached_to_cfc_vpids; - u8 ioa_last_attached_to_cfc_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_last_attached_to_ioa_vpids; - u8 cfc_last_attached_to_ioa_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd ioa_vpd; + struct ipr_vpd cfc_vpd; + struct ipr_vpd ioa_last_attached_to_cfc_vpd; + struct ipr_vpd cfc_last_attached_to_ioa_vpd; + __be32 ioa_data[3]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_12_error { + struct ipr_ext_vpd ioa_vpd; + struct ipr_ext_vpd cfc_vpd; + struct ipr_ext_vpd ioa_last_attached_to_cfc_vpd; + struct ipr_ext_vpd cfc_last_attached_to_ioa_vpd; __be32 ioa_data[3]; - u8 reserved[844]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_03_error { - struct ipr_std_inq_vpids ioa_vpids; - u8 ioa_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_vpids; - u8 cfc_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd ioa_vpd; + struct ipr_vpd cfc_vpd; __be32 errors_detected; __be32 errors_logged; u8 ioa_data[12]; - struct ipr_hostrcb_device_data_entry dev_entry[3]; - u8 reserved[444]; + struct ipr_hostrcb_device_data_entry dev[3]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_13_error { + struct ipr_ext_vpd ioa_vpd; + struct ipr_ext_vpd cfc_vpd; + __be32 errors_detected; + __be32 errors_logged; + struct ipr_hostrcb_device_data_entry_enhanced dev[3]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_04_error { - struct ipr_std_inq_vpids ioa_vpids; - u8 ioa_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_vpids; - u8 cfc_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd ioa_vpd; + struct ipr_vpd cfc_vpd; u8 ioa_data[12]; struct ipr_hostrcb_array_data_entry array_member[10]; __be32 exposed_mode_adn; __be32 array_id; - struct ipr_std_inq_vpids incomp_dev_vpids; - u8 incomp_dev_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd incomp_dev_vpd; __be32 ioa_data2; struct ipr_hostrcb_array_data_entry array_member2[8]; struct ipr_res_addr last_func_vset_res_addr; u8 vset_serial_num[IPR_SERIAL_NUM_LEN]; u8 protection_level[8]; - u8 reserved[124]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_14_error { + struct ipr_ext_vpd ioa_vpd; + struct ipr_ext_vpd cfc_vpd; + __be32 exposed_mode_adn; + __be32 array_id; + struct ipr_res_addr last_func_vset_res_addr; + u8 vset_serial_num[IPR_SERIAL_NUM_LEN]; + u8 protection_level[8]; + __be32 num_entries; + struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_07_error { + u8 failure_reason[64]; + struct ipr_vpd vpd; + u32 data[222]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_17_error { + u8 failure_reason[64]; + struct ipr_ext_vpd vpd; + u32 data[476]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_error { @@ -622,6 +684,11 @@ struct ipr_hostrcb_error { struct ipr_hostrcb_type_02_error type_02_error; struct ipr_hostrcb_type_03_error type_03_error; struct ipr_hostrcb_type_04_error type_04_error; + struct ipr_hostrcb_type_07_error type_07_error; + struct ipr_hostrcb_type_12_error type_12_error; + struct ipr_hostrcb_type_13_error type_13_error; + struct ipr_hostrcb_type_14_error type_14_error; + struct ipr_hostrcb_type_17_error type_17_error; } u; }__attribute__((packed, aligned (4))); @@ -655,6 +722,12 @@ struct ipr_hcam { #define IPR_HOST_RCB_OVERLAY_ID_3 0x03 #define IPR_HOST_RCB_OVERLAY_ID_4 0x04 #define IPR_HOST_RCB_OVERLAY_ID_6 0x06 +#define IPR_HOST_RCB_OVERLAY_ID_7 0x07 +#define IPR_HOST_RCB_OVERLAY_ID_12 0x12 +#define IPR_HOST_RCB_OVERLAY_ID_13 0x13 +#define IPR_HOST_RCB_OVERLAY_ID_14 0x14 +#define IPR_HOST_RCB_OVERLAY_ID_16 0x16 +#define IPR_HOST_RCB_OVERLAY_ID_17 0x17 #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF u8 reserved1[3]; @@ -743,6 +816,7 @@ struct ipr_resource_table { struct ipr_misc_cbs { struct ipr_ioa_vpd ioa_vpd; + struct ipr_inquiry_page0 page0_data; struct ipr_inquiry_page3 page3_data; struct ipr_mode_pages mode_pages; struct ipr_supported_device supp_dev; @@ -813,6 +887,7 @@ struct ipr_trace_entry { struct ipr_sglist { u32 order; u32 num_sg; + u32 num_dma_sg; u32 buffer_len; struct scatterlist scatterlist[1]; }; @@ -825,6 +900,13 @@ enum ipr_sdt_state { DUMP_OBTAINED }; +enum ipr_cache_state { + CACHE_NONE, + CACHE_DISABLED, + CACHE_ENABLED, + CACHE_INVALID +}; + /* Per-controller data */ struct ipr_ioa_cfg { char eye_catcher[8]; @@ -840,7 +922,9 @@ struct ipr_ioa_cfg { u8 dump_taken:1; u8 allow_cmds:1; u8 allow_ml_add_del:1; + u8 needs_hard_reset:1; + enum ipr_cache_state cache_state; u16 type; /* CCIN of the card */ u8 log_level; @@ -911,11 +995,11 @@ struct ipr_ioa_cfg { u16 reset_retries; u32 errors_logged; + u32 doorbell; struct Scsi_Host *host; struct pci_dev *pdev; struct ipr_sglist *ucode_sglist; - struct ipr_mode_pages *saved_mode_pages; u8 saved_mode_page_len; struct work_struct work_q; @@ -948,6 +1032,7 @@ struct ipr_cmnd { struct timer_list timer; void (*done) (struct ipr_cmnd *); int (*job_step) (struct ipr_cmnd *); + int (*job_step_failed) (struct ipr_cmnd *); u16 cmd_index; u8 sense_buffer[SCSI_SENSE_BUFFERSIZE]; dma_addr_t sense_buffer_dma; @@ -1083,11 +1168,7 @@ struct ipr_ucode_image_header { /* * Macros */ -#if IPR_DEBUG -#define IPR_DBG_CMD(CMD) do { CMD; } while (0) -#else -#define IPR_DBG_CMD(CMD) -#endif +#define IPR_DBG_CMD(CMD) if (ipr_debug) { CMD; } #ifdef CONFIG_SCSI_IPR_TRACE #define ipr_create_trace_file(kobj, attr) sysfs_create_bin_file(kobj, attr) @@ -1114,9 +1195,8 @@ struct ipr_ucode_image_header { #define ipr_warn(...) printk(KERN_WARNING IPR_NAME": "__VA_ARGS__) #define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)) -#define ipr_sdev_printk(level, sdev, fmt, ...) \ - printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, sdev->host->host_no, \ - sdev->channel, sdev->id, sdev->lun, ##__VA_ARGS__) +#define ipr_sdev_printk(level, sdev, fmt, args...) \ + sdev_printk(level, sdev, fmt, ## args) #define ipr_sdev_err(sdev, fmt, ...) \ ipr_sdev_printk(KERN_ERR, sdev, fmt, ##__VA_ARGS__) @@ -1136,16 +1216,22 @@ struct ipr_ucode_image_header { #define ipr_res_dbg(ioa_cfg, res, fmt, ...) \ IPR_DBG_CMD(ipr_res_printk(KERN_INFO, ioa_cfg, res, fmt, ##__VA_ARGS__)) +#define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \ +{ \ + if ((res).bus >= IPR_MAX_NUM_BUSES) { \ + ipr_err(fmt": unknown\n", ##__VA_ARGS__); \ + } else { \ + ipr_err(fmt": %d:%d:%d:%d\n", \ + ##__VA_ARGS__, (ioa_cfg)->host->host_no, \ + (res).bus, (res).target, (res).lun); \ + } \ +} + #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ __FILE__, __FUNCTION__, __LINE__) -#if IPR_DBG_TRACE -#define ENTER printk(KERN_INFO IPR_NAME": Entering %s\n", __FUNCTION__) -#define LEAVE printk(KERN_INFO IPR_NAME": Leaving %s\n", __FUNCTION__) -#else -#define ENTER -#define LEAVE -#endif +#define ENTER IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Entering %s\n", __FUNCTION__)) +#define LEAVE IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Leaving %s\n", __FUNCTION__)) #define ipr_err_separator \ ipr_err("----------------------------------------------------------\n") @@ -1217,6 +1303,20 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res) return 0; } +/** + * ipr_is_naca_model - Determine if a resource is using NACA queueing model + * @res: resource entry struct + * + * Return value: + * 1 if NACA queueing model / 0 if not NACA queueing model + **/ +static inline int ipr_is_naca_model(struct ipr_resource_entry *res) +{ + if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL) + return 1; + return 0; +} + /** * ipr_is_device - Determine if resource address is that of a device * @res_addr: resource address struct @@ -1227,7 +1327,7 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res) static inline int ipr_is_device(struct ipr_res_addr *res_addr) { if ((res_addr->bus < IPR_MAX_NUM_BUSES) && - (res_addr->target < IPR_MAX_NUM_TARGETS_PER_BUS)) + (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) return 1; return 0; diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index a4c0b04cf..86c546164 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -179,7 +179,6 @@ #include #include -#include #include @@ -1147,7 +1146,7 @@ ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *)) return (0); } ha->ioctl_reset = 1; /* This reset request is from an IOCTL */ - __ips_eh_reset(SC); + ips_eh_reset(SC); SC->result = DID_OK << 16; SC->scsi_done(SC); return (0); @@ -7285,10 +7284,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, 0xffffffffffffffffULL)) { (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, 0xffffffffULL) != 0) { printk(KERN_WARNING "Unable to set DMA Mask\n"); return ips_abort_init(ha, index); } diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 2068b6682..ff79e68b3 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -3200,8 +3200,8 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) * Data-Out PDU's within R2T-sequence can be quite big; * using mempool */ - ctask->datapool = mempool_create_slab_pool(ISCSI_DTASK_DEFAULT_MAX, - taskcache); + ctask->datapool = mempool_create(ISCSI_DTASK_DEFAULT_MAX, + mempool_alloc_slab, mempool_free_slab, taskcache); if (ctask->datapool == NULL) { kfifo_free(ctask->r2tqueue); iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts); @@ -3639,7 +3639,7 @@ iscsi_tcp_init(void) taskcache = kmem_cache_create("iscsi_taskcache", sizeof(struct iscsi_data_task), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); + SLAB_HWCACHE_ALIGN | SLAB_NO_REAP, NULL, NULL); if (!taskcache) return -ENOMEM; diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index fc031c76d..fcd304e11 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -52,6 +52,7 @@ static volatile unsigned char cmd_buffer[16]; * via PIO. */ +int jazz_esp_detect(struct scsi_host_template *tpnt); static int jazz_esp_release(struct Scsi_Host *shost) { if (shost->irq) @@ -74,7 +75,7 @@ static int jazz_esp_detect(struct scsi_host_template *tpnt) * first assumption it is there:-) */ if (1) { - esp_dev = NULL; + esp_dev = 0; esp = esp_allocate(tpnt, (void *) esp_dev); /* Do command transfer with programmed I/O */ @@ -93,13 +94,13 @@ static int jazz_esp_detect(struct scsi_host_template *tpnt) esp->dma_setup = &dma_setup; /* Optional functions */ - esp->dma_barrier = NULL; - esp->dma_drain = NULL; - esp->dma_invalidate = NULL; - esp->dma_irq_entry = NULL; - esp->dma_irq_exit = NULL; - esp->dma_poll = NULL; - esp->dma_reset = NULL; + esp->dma_barrier = 0; + esp->dma_drain = 0; + esp->dma_invalidate = 0; + esp->dma_irq_entry = 0; + esp->dma_irq_exit = 0; + esp->dma_poll = 0; + esp->dma_reset = 0; esp->dma_led_off = &dma_led_off; esp->dma_led_on = &dma_led_on; @@ -119,7 +120,7 @@ static int jazz_esp_detect(struct scsi_host_template *tpnt) * of DMA channel, so we can use the jazz DMA functions * */ - esp->dregs = (void *) JAZZ_SCSI_DMA; + esp->dregs = JAZZ_SCSI_DMA; /* ESP register base */ esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE); diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index eb7bd310c..459a4daeb 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -112,7 +112,7 @@ lasi700_probe(struct parisc_device *dev) hostdata->dev = &dev->dev; dma_set_mask(&dev->dev, DMA_32BIT_MASK); - hostdata->base = ioremap_nocache(base, 0x100); + hostdata->base = ioremap(base, 0x100); hostdata->differential = 0; if (dev->id.sversion == LASI_700_SVERSION) { diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c deleted file mode 100644 index 835dff0ba..000000000 --- a/drivers/scsi/libata-bmdma.c +++ /dev/null @@ -1,994 +0,0 @@ -/* - * libata-bmdma.c - helper library for PCI IDE BMDMA - * - * Maintained by: Jeff Garzik - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * - * Copyright 2003-2006 Red Hat, Inc. All rights reserved. - * Copyright 2003-2006 Jeff Garzik - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - * libata documentation is available via 'make {ps|pdf}docs', - * as Documentation/DocBook/libata.* - * - * Hardware documentation available from http://www.t13.org/ and - * http://www.sata-io.org/ - * - */ - -#include -#include -#include -#include - -#include "libata.h" - -/** - * ata_tf_load_pio - send taskfile registers to host controller - * @ap: Port to which output is sent - * @tf: ATA taskfile register set - * - * Outputs ATA taskfile to standard ATA host controller. - * - * LOCKING: - * Inherited from caller. - */ - -static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; - - if (tf->ctl != ap->last_ctl) { - outb(tf->ctl, ioaddr->ctl_addr); - ap->last_ctl = tf->ctl; - ata_wait_idle(ap); - } - - if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { - outb(tf->hob_feature, ioaddr->feature_addr); - outb(tf->hob_nsect, ioaddr->nsect_addr); - outb(tf->hob_lbal, ioaddr->lbal_addr); - outb(tf->hob_lbam, ioaddr->lbam_addr); - outb(tf->hob_lbah, ioaddr->lbah_addr); - VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", - tf->hob_feature, - tf->hob_nsect, - tf->hob_lbal, - tf->hob_lbam, - tf->hob_lbah); - } - - if (is_addr) { - outb(tf->feature, ioaddr->feature_addr); - outb(tf->nsect, ioaddr->nsect_addr); - outb(tf->lbal, ioaddr->lbal_addr); - outb(tf->lbam, ioaddr->lbam_addr); - outb(tf->lbah, ioaddr->lbah_addr); - VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", - tf->feature, - tf->nsect, - tf->lbal, - tf->lbam, - tf->lbah); - } - - if (tf->flags & ATA_TFLAG_DEVICE) { - outb(tf->device, ioaddr->device_addr); - VPRINTK("device 0x%X\n", tf->device); - } - - ata_wait_idle(ap); -} - -/** - * ata_tf_load_mmio - send taskfile registers to host controller - * @ap: Port to which output is sent - * @tf: ATA taskfile register set - * - * Outputs ATA taskfile to standard ATA host controller using MMIO. - * - * LOCKING: - * Inherited from caller. - */ - -static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; - - if (tf->ctl != ap->last_ctl) { - writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr); - ap->last_ctl = tf->ctl; - ata_wait_idle(ap); - } - - if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { - writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr); - writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr); - writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr); - writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr); - writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr); - VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", - tf->hob_feature, - tf->hob_nsect, - tf->hob_lbal, - tf->hob_lbam, - tf->hob_lbah); - } - - if (is_addr) { - writeb(tf->feature, (void __iomem *) ioaddr->feature_addr); - writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr); - writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr); - writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr); - writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr); - VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", - tf->feature, - tf->nsect, - tf->lbal, - tf->lbam, - tf->lbah); - } - - if (tf->flags & ATA_TFLAG_DEVICE) { - writeb(tf->device, (void __iomem *) ioaddr->device_addr); - VPRINTK("device 0x%X\n", tf->device); - } - - ata_wait_idle(ap); -} - - -/** - * ata_tf_load - send taskfile registers to host controller - * @ap: Port to which output is sent - * @tf: ATA taskfile register set - * - * Outputs ATA taskfile to standard ATA host controller using MMIO - * or PIO as indicated by the ATA_FLAG_MMIO flag. - * Writes the control, feature, nsect, lbal, lbam, and lbah registers. - * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, - * hob_lbal, hob_lbam, and hob_lbah. - * - * This function waits for idle (!BUSY and !DRQ) after writing - * registers. If the control register has a new value, this - * function also waits for idle after writing control and before - * writing the remaining registers. - * - * May be used as the tf_load() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ -void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) -{ - if (ap->flags & ATA_FLAG_MMIO) - ata_tf_load_mmio(ap, tf); - else - ata_tf_load_pio(ap, tf); -} - -/** - * ata_exec_command_pio - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set - * - * Issues PIO write to ATA command register, with proper - * synchronization with interrupt handler / other threads. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf) -{ - DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); - - outb(tf->command, ap->ioaddr.command_addr); - ata_pause(ap); -} - - -/** - * ata_exec_command_mmio - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set - * - * Issues MMIO write to ATA command register, with proper - * synchronization with interrupt handler / other threads. - * - * FIXME: missing write posting for 400nS delay enforcement - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) -{ - DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); - - writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr); - ata_pause(ap); -} - - -/** - * ata_exec_command - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set - * - * Issues PIO/MMIO write to ATA command register, with proper - * synchronization with interrupt handler / other threads. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) -{ - if (ap->flags & ATA_FLAG_MMIO) - ata_exec_command_mmio(ap, tf); - else - ata_exec_command_pio(ap, tf); -} - -/** - * ata_tf_read_pio - input device's ATA taskfile shadow registers - * @ap: Port from which input is read - * @tf: ATA taskfile register set for storing input - * - * Reads ATA taskfile registers for currently-selected device - * into @tf. - * - * LOCKING: - * Inherited from caller. - */ - -static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - - tf->command = ata_check_status(ap); - tf->feature = inb(ioaddr->error_addr); - tf->nsect = inb(ioaddr->nsect_addr); - tf->lbal = inb(ioaddr->lbal_addr); - tf->lbam = inb(ioaddr->lbam_addr); - tf->lbah = inb(ioaddr->lbah_addr); - tf->device = inb(ioaddr->device_addr); - - if (tf->flags & ATA_TFLAG_LBA48) { - outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr); - tf->hob_feature = inb(ioaddr->error_addr); - tf->hob_nsect = inb(ioaddr->nsect_addr); - tf->hob_lbal = inb(ioaddr->lbal_addr); - tf->hob_lbam = inb(ioaddr->lbam_addr); - tf->hob_lbah = inb(ioaddr->lbah_addr); - } -} - -/** - * ata_tf_read_mmio - input device's ATA taskfile shadow registers - * @ap: Port from which input is read - * @tf: ATA taskfile register set for storing input - * - * Reads ATA taskfile registers for currently-selected device - * into @tf via MMIO. - * - * LOCKING: - * Inherited from caller. - */ - -static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - - tf->command = ata_check_status(ap); - tf->feature = readb((void __iomem *)ioaddr->error_addr); - tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); - tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); - tf->lbam = readb((void __iomem *)ioaddr->lbam_addr); - tf->lbah = readb((void __iomem *)ioaddr->lbah_addr); - tf->device = readb((void __iomem *)ioaddr->device_addr); - - if (tf->flags & ATA_TFLAG_LBA48) { - writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr); - tf->hob_feature = readb((void __iomem *)ioaddr->error_addr); - tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr); - tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr); - tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr); - tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr); - } -} - - -/** - * ata_tf_read - input device's ATA taskfile shadow registers - * @ap: Port from which input is read - * @tf: ATA taskfile register set for storing input - * - * Reads ATA taskfile registers for currently-selected device - * into @tf. - * - * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 - * is set, also reads the hob registers. - * - * May be used as the tf_read() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ -void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) -{ - if (ap->flags & ATA_FLAG_MMIO) - ata_tf_read_mmio(ap, tf); - else - ata_tf_read_pio(ap, tf); -} - -/** - * ata_check_status_pio - Read device status reg & clear interrupt - * @ap: port where the device is - * - * Reads ATA taskfile status register for currently-selected device - * and return its value. This also clears pending interrupts - * from this device - * - * LOCKING: - * Inherited from caller. - */ -static u8 ata_check_status_pio(struct ata_port *ap) -{ - return inb(ap->ioaddr.status_addr); -} - -/** - * ata_check_status_mmio - Read device status reg & clear interrupt - * @ap: port where the device is - * - * Reads ATA taskfile status register for currently-selected device - * via MMIO and return its value. This also clears pending interrupts - * from this device - * - * LOCKING: - * Inherited from caller. - */ -static u8 ata_check_status_mmio(struct ata_port *ap) -{ - return readb((void __iomem *) ap->ioaddr.status_addr); -} - - -/** - * ata_check_status - Read device status reg & clear interrupt - * @ap: port where the device is - * - * Reads ATA taskfile status register for currently-selected device - * and return its value. This also clears pending interrupts - * from this device - * - * May be used as the check_status() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ -u8 ata_check_status(struct ata_port *ap) -{ - if (ap->flags & ATA_FLAG_MMIO) - return ata_check_status_mmio(ap); - return ata_check_status_pio(ap); -} - - -/** - * ata_altstatus - Read device alternate status reg - * @ap: port where the device is - * - * Reads ATA taskfile alternate status register for - * currently-selected device and return its value. - * - * Note: may NOT be used as the check_altstatus() entry in - * ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ -u8 ata_altstatus(struct ata_port *ap) -{ - if (ap->ops->check_altstatus) - return ap->ops->check_altstatus(ap); - - if (ap->flags & ATA_FLAG_MMIO) - return readb((void __iomem *)ap->ioaddr.altstatus_addr); - return inb(ap->ioaddr.altstatus_addr); -} - -/** - * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); - u8 dmactl; - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - - /* load PRD table addr. */ - mb(); /* make sure PRD table writes are visible to controller */ - writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS); - - /* specify data direction, triple-check start bit is clear */ - dmactl = readb(mmio + ATA_DMA_CMD); - dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); - if (!rw) - dmactl |= ATA_DMA_WR; - writeb(dmactl, mmio + ATA_DMA_CMD); - - /* issue r/w command */ - ap->ops->exec_command(ap, &qc->tf); -} - -/** - * ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - u8 dmactl; - - /* start host DMA transaction */ - dmactl = readb(mmio + ATA_DMA_CMD); - writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD); - - /* Strictly, one may wish to issue a readb() here, to - * flush the mmio write. However, control also passes - * to the hardware at this point, and it will interrupt - * us when we are to resume control. So, in effect, - * we don't care when the mmio write flushes. - * Further, a read of the DMA status register _immediately_ - * following the write may not be what certain flaky hardware - * is expected, so I think it is best to not add a readb() - * without first all the MMIO ATA cards/mobos. - * Or maybe I'm just being paranoid. - */ -} - -/** - * ata_bmdma_setup_pio - Set up PCI IDE BMDMA transaction (PIO) - * @qc: Info associated with this ATA transaction. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_bmdma_setup_pio (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); - u8 dmactl; - - /* load PRD table addr. */ - outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS); - - /* specify data direction, triple-check start bit is clear */ - dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); - if (!rw) - dmactl |= ATA_DMA_WR; - outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - - /* issue r/w command */ - ap->ops->exec_command(ap, &qc->tf); -} - -/** - * ata_bmdma_start_pio - Start a PCI IDE BMDMA transaction (PIO) - * @qc: Info associated with this ATA transaction. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_bmdma_start_pio (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - u8 dmactl; - - /* start host DMA transaction */ - dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - outb(dmactl | ATA_DMA_START, - ap->ioaddr.bmdma_addr + ATA_DMA_CMD); -} - - -/** - * ata_bmdma_start - Start a PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * Writes the ATA_DMA_START flag to the DMA command register. - * - * May be used as the bmdma_start() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -void ata_bmdma_start(struct ata_queued_cmd *qc) -{ - if (qc->ap->flags & ATA_FLAG_MMIO) - ata_bmdma_start_mmio(qc); - else - ata_bmdma_start_pio(qc); -} - - -/** - * ata_bmdma_setup - Set up PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * Writes address of PRD table to device's PRD Table Address - * register, sets the DMA control register, and calls - * ops->exec_command() to start the transfer. - * - * May be used as the bmdma_setup() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -void ata_bmdma_setup(struct ata_queued_cmd *qc) -{ - if (qc->ap->flags & ATA_FLAG_MMIO) - ata_bmdma_setup_mmio(qc); - else - ata_bmdma_setup_pio(qc); -} - - -/** - * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. - * @ap: Port associated with this ATA transaction. - * - * Clear interrupt and error flags in DMA status register. - * - * May be used as the irq_clear() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -void ata_bmdma_irq_clear(struct ata_port *ap) -{ - if (!ap->ioaddr.bmdma_addr) - return; - - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = - ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; - writeb(readb(mmio), mmio); - } else { - unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; - outb(inb(addr), addr); - } -} - - -/** - * ata_bmdma_status - Read PCI IDE BMDMA status - * @ap: Port associated with this ATA transaction. - * - * Read and return BMDMA status register. - * - * May be used as the bmdma_status() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -u8 ata_bmdma_status(struct ata_port *ap) -{ - u8 host_stat; - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - host_stat = readb(mmio + ATA_DMA_STATUS); - } else - host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); - return host_stat; -} - - -/** - * ata_bmdma_stop - Stop PCI IDE BMDMA transfer - * @qc: Command we are ending DMA for - * - * Clears the ATA_DMA_START flag in the dma control register - * - * May be used as the bmdma_stop() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -void ata_bmdma_stop(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - - /* clear start/stop bit */ - writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START, - mmio + ATA_DMA_CMD); - } else { - /* clear start/stop bit */ - outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START, - ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - } - - /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_altstatus(ap); /* dummy read */ -} - -#ifdef CONFIG_PCI -static struct ata_probe_ent * -ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) -{ - struct ata_probe_ent *probe_ent; - - probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); - if (!probe_ent) { - printk(KERN_ERR DRV_NAME "(%s): out of memory\n", - kobject_name(&(dev->kobj))); - return NULL; - } - - INIT_LIST_HEAD(&probe_ent->node); - probe_ent->dev = dev; - - probe_ent->sht = port->sht; - probe_ent->host_flags = port->host_flags; - probe_ent->pio_mask = port->pio_mask; - probe_ent->mwdma_mask = port->mwdma_mask; - probe_ent->udma_mask = port->udma_mask; - probe_ent->port_ops = port->port_ops; - - return probe_ent; -} - - -/** - * ata_pci_init_native_mode - Initialize native-mode driver - * @pdev: pci device to be initialized - * @port: array[2] of pointers to port info structures. - * @ports: bitmap of ports present - * - * Utility function which allocates and initializes an - * ata_probe_ent structure for a standard dual-port - * PIO-based IDE controller. The returned ata_probe_ent - * structure can be passed to ata_device_add(). The returned - * ata_probe_ent structure should then be freed with kfree(). - * - * The caller need only pass the address of the primary port, the - * secondary will be deduced automatically. If the device has non - * standard secondary port mappings this function can be called twice, - * once for each interface. - */ - -struct ata_probe_ent * -ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports) -{ - struct ata_probe_ent *probe_ent = - ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); - int p = 0; - unsigned long bmdma; - - if (!probe_ent) - return NULL; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = SA_SHIRQ; - probe_ent->private_data = port[0]->private_data; - - if (ports & ATA_PORT_PRIMARY) { - probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); - probe_ent->port[p].altstatus_addr = - probe_ent->port[p].ctl_addr = - pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; - bmdma = pci_resource_start(pdev, 4); - if (bmdma) { - if (inb(bmdma + 2) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; - probe_ent->port[p].bmdma_addr = bmdma; - } - ata_std_ports(&probe_ent->port[p]); - p++; - } - - if (ports & ATA_PORT_SECONDARY) { - probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2); - probe_ent->port[p].altstatus_addr = - probe_ent->port[p].ctl_addr = - pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; - bmdma = pci_resource_start(pdev, 4); - if (bmdma) { - bmdma += 8; - if(inb(bmdma + 2) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; - probe_ent->port[p].bmdma_addr = bmdma; - } - ata_std_ports(&probe_ent->port[p]); - p++; - } - - probe_ent->n_ports = p; - return probe_ent; -} - - -static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, - struct ata_port_info *port, int port_num) -{ - struct ata_probe_ent *probe_ent; - unsigned long bmdma; - - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); - if (!probe_ent) - return NULL; - - probe_ent->legacy_mode = 1; - probe_ent->n_ports = 1; - probe_ent->hard_port_no = port_num; - probe_ent->private_data = port->private_data; - - switch(port_num) - { - case 0: - probe_ent->irq = 14; - probe_ent->port[0].cmd_addr = 0x1f0; - probe_ent->port[0].altstatus_addr = - probe_ent->port[0].ctl_addr = 0x3f6; - break; - case 1: - probe_ent->irq = 15; - probe_ent->port[0].cmd_addr = 0x170; - probe_ent->port[0].altstatus_addr = - probe_ent->port[0].ctl_addr = 0x376; - break; - } - - bmdma = pci_resource_start(pdev, 4); - if (bmdma != 0) { - bmdma += 8 * port_num; - probe_ent->port[0].bmdma_addr = bmdma; - if (inb(bmdma + 2) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; - } - ata_std_ports(&probe_ent->port[0]); - - return probe_ent; -} - - -/** - * ata_pci_init_one - Initialize/register PCI IDE host controller - * @pdev: Controller to be initialized - * @port_info: Information from low-level host driver - * @n_ports: Number of ports attached to host controller - * - * This is a helper function which can be called from a driver's - * xxx_init_one() probe function if the hardware uses traditional - * IDE taskfile registers. - * - * This function calls pci_enable_device(), reserves its register - * regions, sets the dma mask, enables bus master mode, and calls - * ata_device_add() - * - * LOCKING: - * Inherited from PCI layer (may sleep). - * - * RETURNS: - * Zero on success, negative on errno-based value on error. - */ - -int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, - unsigned int n_ports) -{ - struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL; - struct ata_port_info *port[2]; - u8 tmp8, mask; - unsigned int legacy_mode = 0; - int disable_dev_on_err = 1; - int rc; - - DPRINTK("ENTER\n"); - - port[0] = port_info[0]; - if (n_ports > 1) - port[1] = port_info[1]; - else - port[1] = port[0]; - - if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0 - && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - /* TODO: What if one channel is in native mode ... */ - pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); - mask = (1 << 2) | (1 << 0); - if ((tmp8 & mask) != mask) - legacy_mode = (1 << 3); - } - - /* FIXME... */ - if ((!legacy_mode) && (n_ports > 2)) { - printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n"); - n_ports = 2; - /* For now */ - } - - /* FIXME: Really for ATA it isn't safe because the device may be - multi-purpose and we want to leave it alone if it was already - enabled. Secondly for shared use as Arjan says we want refcounting - - Checking dev->is_enabled is insufficient as this is not set at - boot for the primary video which is BIOS enabled - */ - - rc = pci_enable_device(pdev); - if (rc) - return rc; - - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) { - disable_dev_on_err = 0; - goto err_out; - } - - /* FIXME: Should use platform specific mappers for legacy port ranges */ - if (legacy_mode) { - if (!request_region(0x1f0, 8, "libata")) { - struct resource *conflict, res; - res.start = 0x1f0; - res.end = 0x1f0 + 8 - 1; - conflict = ____request_resource(&ioport_resource, &res); - if (!strcmp(conflict->name, "libata")) - legacy_mode |= (1 << 0); - else { - disable_dev_on_err = 0; - printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); - } - } else - legacy_mode |= (1 << 0); - - if (!request_region(0x170, 8, "libata")) { - struct resource *conflict, res; - res.start = 0x170; - res.end = 0x170 + 8 - 1; - conflict = ____request_resource(&ioport_resource, &res); - if (!strcmp(conflict->name, "libata")) - legacy_mode |= (1 << 1); - else { - disable_dev_on_err = 0; - printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); - } - } else - legacy_mode |= (1 << 1); - } - - /* we have legacy mode, but all ports are unavailable */ - if (legacy_mode == (1 << 3)) { - rc = -EBUSY; - goto err_out_regions; - } - - /* FIXME: If we get no DMA mask we should fall back to PIO */ - rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - goto err_out_regions; - rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - goto err_out_regions; - - if (legacy_mode) { - if (legacy_mode & (1 << 0)) - probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0); - if (legacy_mode & (1 << 1)) - probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1); - } else { - if (n_ports == 2) - probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); - else - probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); - } - if (!probe_ent && !probe_ent2) { - rc = -ENOMEM; - goto err_out_regions; - } - - pci_set_master(pdev); - - /* FIXME: check ata_device_add return */ - if (legacy_mode) { - if (legacy_mode & (1 << 0)) - ata_device_add(probe_ent); - if (legacy_mode & (1 << 1)) - ata_device_add(probe_ent2); - } else - ata_device_add(probe_ent); - - kfree(probe_ent); - kfree(probe_ent2); - - return 0; - -err_out_regions: - if (legacy_mode & (1 << 0)) - release_region(0x1f0, 8); - if (legacy_mode & (1 << 1)) - release_region(0x170, 8); - pci_release_regions(pdev); -err_out: - if (disable_dev_on_err) - pci_disable_device(pdev); - return rc; -} - -/** - * ata_pci_clear_simplex - attempt to kick device out of simplex - * @pdev: PCI device - * - * Some PCI ATA devices report simplex mode but in fact can be told to - * enter non simplex mode. This implements the neccessary logic to - * perform the task on such devices. Calling it on other devices will - * have -undefined- behaviour. - */ - -int ata_pci_clear_simplex(struct pci_dev *pdev) -{ - unsigned long bmdma = pci_resource_start(pdev, 4); - u8 simplex; - - if (bmdma == 0) - return -ENOENT; - - simplex = inb(bmdma + 0x02); - outb(simplex & 0x60, bmdma + 0x02); - simplex = inb(bmdma + 0x02); - if (simplex & 0x80) - return -EOPNOTSUPP; - return 0; -} - -unsigned long ata_pci_default_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long xfer_mask) -{ - /* Filter out DMA modes if the device has been configured by - the BIOS as PIO only */ - - if (ap->ioaddr.bmdma_addr == 0) - xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); - return xfer_mask; -} - -#endif /* CONFIG_PCI */ - diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index d680ccd94..400e9d74a 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -61,19 +61,24 @@ #include "libata.h" -static unsigned int ata_dev_init_params(struct ata_port *ap, - struct ata_device *dev, - u16 heads, - u16 sectors); +static unsigned int ata_busy_sleep (struct ata_port *ap, + unsigned long tmout_pat, + unsigned long tmout); +static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev); +static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); static void ata_set_mode(struct ata_port *ap); -static unsigned int ata_dev_set_xfermode(struct ata_port *ap, - struct ata_device *dev); -static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev); +static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); +static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift); +static int fgb(u32 bitmap); +static int ata_choose_xfer_mode(const struct ata_port *ap, + u8 *xfer_mode_out, + unsigned int *xfer_shift_out); +static void __ata_qc_complete(struct ata_queued_cmd *qc); static unsigned int ata_unique_id = 1; static struct workqueue_struct *ata_wq; -int atapi_enabled = 1; +int atapi_enabled = 0; module_param(atapi_enabled, int, 0444); MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); @@ -86,6 +91,403 @@ MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +/** + * ata_tf_load_pio - send taskfile registers to host controller + * @ap: Port to which output is sent + * @tf: ATA taskfile register set + * + * Outputs ATA taskfile to standard ATA host controller. + * + * LOCKING: + * Inherited from caller. + */ + +static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; + + if (tf->ctl != ap->last_ctl) { + outb(tf->ctl, ioaddr->ctl_addr); + ap->last_ctl = tf->ctl; + ata_wait_idle(ap); + } + + if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { + outb(tf->hob_feature, ioaddr->feature_addr); + outb(tf->hob_nsect, ioaddr->nsect_addr); + outb(tf->hob_lbal, ioaddr->lbal_addr); + outb(tf->hob_lbam, ioaddr->lbam_addr); + outb(tf->hob_lbah, ioaddr->lbah_addr); + VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->hob_feature, + tf->hob_nsect, + tf->hob_lbal, + tf->hob_lbam, + tf->hob_lbah); + } + + if (is_addr) { + outb(tf->feature, ioaddr->feature_addr); + outb(tf->nsect, ioaddr->nsect_addr); + outb(tf->lbal, ioaddr->lbal_addr); + outb(tf->lbam, ioaddr->lbam_addr); + outb(tf->lbah, ioaddr->lbah_addr); + VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", + tf->feature, + tf->nsect, + tf->lbal, + tf->lbam, + tf->lbah); + } + + if (tf->flags & ATA_TFLAG_DEVICE) { + outb(tf->device, ioaddr->device_addr); + VPRINTK("device 0x%X\n", tf->device); + } + + ata_wait_idle(ap); +} + +/** + * ata_tf_load_mmio - send taskfile registers to host controller + * @ap: Port to which output is sent + * @tf: ATA taskfile register set + * + * Outputs ATA taskfile to standard ATA host controller using MMIO. + * + * LOCKING: + * Inherited from caller. + */ + +static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; + + if (tf->ctl != ap->last_ctl) { + writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr); + ap->last_ctl = tf->ctl; + ata_wait_idle(ap); + } + + if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { + writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr); + writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr); + writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr); + writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr); + writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr); + VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->hob_feature, + tf->hob_nsect, + tf->hob_lbal, + tf->hob_lbam, + tf->hob_lbah); + } + + if (is_addr) { + writeb(tf->feature, (void __iomem *) ioaddr->feature_addr); + writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr); + writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr); + writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr); + writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr); + VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", + tf->feature, + tf->nsect, + tf->lbal, + tf->lbam, + tf->lbah); + } + + if (tf->flags & ATA_TFLAG_DEVICE) { + writeb(tf->device, (void __iomem *) ioaddr->device_addr); + VPRINTK("device 0x%X\n", tf->device); + } + + ata_wait_idle(ap); +} + + +/** + * ata_tf_load - send taskfile registers to host controller + * @ap: Port to which output is sent + * @tf: ATA taskfile register set + * + * Outputs ATA taskfile to standard ATA host controller using MMIO + * or PIO as indicated by the ATA_FLAG_MMIO flag. + * Writes the control, feature, nsect, lbal, lbam, and lbah registers. + * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, + * hob_lbal, hob_lbam, and hob_lbah. + * + * This function waits for idle (!BUSY and !DRQ) after writing + * registers. If the control register has a new value, this + * function also waits for idle after writing control and before + * writing the remaining registers. + * + * May be used as the tf_load() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) +{ + if (ap->flags & ATA_FLAG_MMIO) + ata_tf_load_mmio(ap, tf); + else + ata_tf_load_pio(ap, tf); +} + +/** + * ata_exec_command_pio - issue ATA command to host controller + * @ap: port to which command is being issued + * @tf: ATA taskfile register set + * + * Issues PIO write to ATA command register, with proper + * synchronization with interrupt handler / other threads. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf) +{ + DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); + + outb(tf->command, ap->ioaddr.command_addr); + ata_pause(ap); +} + + +/** + * ata_exec_command_mmio - issue ATA command to host controller + * @ap: port to which command is being issued + * @tf: ATA taskfile register set + * + * Issues MMIO write to ATA command register, with proper + * synchronization with interrupt handler / other threads. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) +{ + DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); + + writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr); + ata_pause(ap); +} + + +/** + * ata_exec_command - issue ATA command to host controller + * @ap: port to which command is being issued + * @tf: ATA taskfile register set + * + * Issues PIO/MMIO write to ATA command register, with proper + * synchronization with interrupt handler / other threads. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ +void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) +{ + if (ap->flags & ATA_FLAG_MMIO) + ata_exec_command_mmio(ap, tf); + else + ata_exec_command_pio(ap, tf); +} + +/** + * ata_tf_to_host - issue ATA taskfile to host controller + * @ap: port to which command is being issued + * @tf: ATA taskfile register set + * + * Issues ATA taskfile register set to ATA host controller, + * with proper synchronization with interrupt handler and + * other threads. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +static inline void ata_tf_to_host(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + ap->ops->tf_load(ap, tf); + ap->ops->exec_command(ap, tf); +} + +/** + * ata_tf_read_pio - input device's ATA taskfile shadow registers + * @ap: Port from which input is read + * @tf: ATA taskfile register set for storing input + * + * Reads ATA taskfile registers for currently-selected device + * into @tf. + * + * LOCKING: + * Inherited from caller. + */ + +static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + + tf->command = ata_check_status(ap); + tf->feature = inb(ioaddr->error_addr); + tf->nsect = inb(ioaddr->nsect_addr); + tf->lbal = inb(ioaddr->lbal_addr); + tf->lbam = inb(ioaddr->lbam_addr); + tf->lbah = inb(ioaddr->lbah_addr); + tf->device = inb(ioaddr->device_addr); + + if (tf->flags & ATA_TFLAG_LBA48) { + outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr); + tf->hob_feature = inb(ioaddr->error_addr); + tf->hob_nsect = inb(ioaddr->nsect_addr); + tf->hob_lbal = inb(ioaddr->lbal_addr); + tf->hob_lbam = inb(ioaddr->lbam_addr); + tf->hob_lbah = inb(ioaddr->lbah_addr); + } +} + +/** + * ata_tf_read_mmio - input device's ATA taskfile shadow registers + * @ap: Port from which input is read + * @tf: ATA taskfile register set for storing input + * + * Reads ATA taskfile registers for currently-selected device + * into @tf via MMIO. + * + * LOCKING: + * Inherited from caller. + */ + +static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + + tf->command = ata_check_status(ap); + tf->feature = readb((void __iomem *)ioaddr->error_addr); + tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); + tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); + tf->lbam = readb((void __iomem *)ioaddr->lbam_addr); + tf->lbah = readb((void __iomem *)ioaddr->lbah_addr); + tf->device = readb((void __iomem *)ioaddr->device_addr); + + if (tf->flags & ATA_TFLAG_LBA48) { + writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr); + tf->hob_feature = readb((void __iomem *)ioaddr->error_addr); + tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr); + tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr); + tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr); + tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr); + } +} + + +/** + * ata_tf_read - input device's ATA taskfile shadow registers + * @ap: Port from which input is read + * @tf: ATA taskfile register set for storing input + * + * Reads ATA taskfile registers for currently-selected device + * into @tf. + * + * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 + * is set, also reads the hob registers. + * + * May be used as the tf_read() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) +{ + if (ap->flags & ATA_FLAG_MMIO) + ata_tf_read_mmio(ap, tf); + else + ata_tf_read_pio(ap, tf); +} + +/** + * ata_check_status_pio - Read device status reg & clear interrupt + * @ap: port where the device is + * + * Reads ATA taskfile status register for currently-selected device + * and return its value. This also clears pending interrupts + * from this device + * + * LOCKING: + * Inherited from caller. + */ +static u8 ata_check_status_pio(struct ata_port *ap) +{ + return inb(ap->ioaddr.status_addr); +} + +/** + * ata_check_status_mmio - Read device status reg & clear interrupt + * @ap: port where the device is + * + * Reads ATA taskfile status register for currently-selected device + * via MMIO and return its value. This also clears pending interrupts + * from this device + * + * LOCKING: + * Inherited from caller. + */ +static u8 ata_check_status_mmio(struct ata_port *ap) +{ + return readb((void __iomem *) ap->ioaddr.status_addr); +} + + +/** + * ata_check_status - Read device status reg & clear interrupt + * @ap: port where the device is + * + * Reads ATA taskfile status register for currently-selected device + * and return its value. This also clears pending interrupts + * from this device + * + * May be used as the check_status() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +u8 ata_check_status(struct ata_port *ap) +{ + if (ap->flags & ATA_FLAG_MMIO) + return ata_check_status_mmio(ap); + return ata_check_status_pio(ap); +} + + +/** + * ata_altstatus - Read device alternate status reg + * @ap: port where the device is + * + * Reads ATA taskfile alternate status register for + * currently-selected device and return its value. + * + * Note: may NOT be used as the check_altstatus() entry in + * ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +u8 ata_altstatus(struct ata_port *ap) +{ + if (ap->ops->check_altstatus) + return ap->ops->check_altstatus(ap); + + if (ap->flags & ATA_FLAG_MMIO) + return readb((void __iomem *)ap->ioaddr.altstatus_addr); + return inb(ap->ioaddr.altstatus_addr); +} + /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure @@ -192,7 +594,7 @@ static const u8 ata_rw_cmds[] = { * ata_rwcmd_protocol - set taskfile r/w commands and protocol * @qc: command to examine and configure * - * Examine the device configuration and tf->flags to calculate + * Examine the device configuration and tf->flags to calculate * the proper read/write commands and protocol to use. * * LOCKING: @@ -205,7 +607,7 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc) u8 cmd; int index, fua, lba48, write; - + fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0; lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0; write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0; @@ -230,207 +632,85 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc) return -1; } +static const char * const xfer_mode_str[] = { + "UDMA/16", + "UDMA/25", + "UDMA/33", + "UDMA/44", + "UDMA/66", + "UDMA/100", + "UDMA/133", + "UDMA7", + "MWDMA0", + "MWDMA1", + "MWDMA2", + "PIO0", + "PIO1", + "PIO2", + "PIO3", + "PIO4", +}; + /** - * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask - * @pio_mask: pio_mask - * @mwdma_mask: mwdma_mask - * @udma_mask: udma_mask + * ata_udma_string - convert UDMA bit offset to string + * @mask: mask of bits supported; only highest bit counts. * - * Pack @pio_mask, @mwdma_mask and @udma_mask into a single - * unsigned int xfer_mask. + * Determine string which represents the highest speed + * (highest bit in @udma_mask). * * LOCKING: * None. * * RETURNS: - * Packed xfer_mask. + * Constant C string representing highest speed listed in + * @udma_mask, or the constant C string "". */ -static unsigned int ata_pack_xfermask(unsigned int pio_mask, - unsigned int mwdma_mask, - unsigned int udma_mask) -{ - return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) | - ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) | - ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA); -} -/** - * ata_unpack_xfermask - Unpack xfer_mask into pio, mwdma and udma masks - * @xfer_mask: xfer_mask to unpack - * @pio_mask: resulting pio_mask - * @mwdma_mask: resulting mwdma_mask - * @udma_mask: resulting udma_mask - * - * Unpack @xfer_mask into @pio_mask, @mwdma_mask and @udma_mask. - * Any NULL distination masks will be ignored. - */ -static void ata_unpack_xfermask(unsigned int xfer_mask, - unsigned int *pio_mask, - unsigned int *mwdma_mask, - unsigned int *udma_mask) +static const char *ata_mode_string(unsigned int mask) { - if (pio_mask) - *pio_mask = (xfer_mask & ATA_MASK_PIO) >> ATA_SHIFT_PIO; - if (mwdma_mask) - *mwdma_mask = (xfer_mask & ATA_MASK_MWDMA) >> ATA_SHIFT_MWDMA; - if (udma_mask) - *udma_mask = (xfer_mask & ATA_MASK_UDMA) >> ATA_SHIFT_UDMA; -} + int i; -static const struct ata_xfer_ent { - int shift, bits; - u8 base; -} ata_xfer_tbl[] = { - { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, - { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 }, - { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 }, - { -1, }, -}; + for (i = 7; i >= 0; i--) + if (mask & (1 << i)) + goto out; + for (i = ATA_SHIFT_MWDMA + 2; i >= ATA_SHIFT_MWDMA; i--) + if (mask & (1 << i)) + goto out; + for (i = ATA_SHIFT_PIO + 4; i >= ATA_SHIFT_PIO; i--) + if (mask & (1 << i)) + goto out; -/** - * ata_xfer_mask2mode - Find matching XFER_* for the given xfer_mask - * @xfer_mask: xfer_mask of interest - * - * Return matching XFER_* value for @xfer_mask. Only the highest - * bit of @xfer_mask is considered. - * - * LOCKING: - * None. - * - * RETURNS: - * Matching XFER_* value, 0 if no match found. - */ -static u8 ata_xfer_mask2mode(unsigned int xfer_mask) -{ - int highbit = fls(xfer_mask) - 1; - const struct ata_xfer_ent *ent; + return ""; - for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) - if (highbit >= ent->shift && highbit < ent->shift + ent->bits) - return ent->base + highbit - ent->shift; - return 0; +out: + return xfer_mode_str[i]; } /** - * ata_xfer_mode2mask - Find matching xfer_mask for XFER_* - * @xfer_mode: XFER_* of interest + * ata_pio_devchk - PATA device presence detection + * @ap: ATA channel to examine + * @device: Device to examine (starting at zero) * - * Return matching xfer_mask for @xfer_mode. + * This technique was originally described in + * Hale Landis's ATADRVR (www.ata-atapi.com), and + * later found its way into the ATA/ATAPI spec. * - * LOCKING: - * None. + * Write a pattern to the ATA shadow registers, + * and if a device is present, it will respond by + * correctly storing and echoing back the + * ATA shadow register contents. * - * RETURNS: - * Matching xfer_mask, 0 if no match found. + * LOCKING: + * caller. */ -static unsigned int ata_xfer_mode2mask(u8 xfer_mode) + +static unsigned int ata_pio_devchk(struct ata_port *ap, + unsigned int device) { - const struct ata_xfer_ent *ent; + struct ata_ioports *ioaddr = &ap->ioaddr; + u8 nsect, lbal; - for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) - if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits) - return 1 << (ent->shift + xfer_mode - ent->base); - return 0; -} - -/** - * ata_xfer_mode2shift - Find matching xfer_shift for XFER_* - * @xfer_mode: XFER_* of interest - * - * Return matching xfer_shift for @xfer_mode. - * - * LOCKING: - * None. - * - * RETURNS: - * Matching xfer_shift, -1 if no match found. - */ -static int ata_xfer_mode2shift(unsigned int xfer_mode) -{ - const struct ata_xfer_ent *ent; - - for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) - if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits) - return ent->shift; - return -1; -} - -/** - * ata_mode_string - convert xfer_mask to string - * @xfer_mask: mask of bits supported; only highest bit counts. - * - * Determine string which represents the highest speed - * (highest bit in @modemask). - * - * LOCKING: - * None. - * - * RETURNS: - * Constant C string representing highest speed listed in - * @mode_mask, or the constant C string "". - */ -static const char *ata_mode_string(unsigned int xfer_mask) -{ - static const char * const xfer_mode_str[] = { - "PIO0", - "PIO1", - "PIO2", - "PIO3", - "PIO4", - "MWDMA0", - "MWDMA1", - "MWDMA2", - "UDMA/16", - "UDMA/25", - "UDMA/33", - "UDMA/44", - "UDMA/66", - "UDMA/100", - "UDMA/133", - "UDMA7", - }; - int highbit; - - highbit = fls(xfer_mask) - 1; - if (highbit >= 0 && highbit < ARRAY_SIZE(xfer_mode_str)) - return xfer_mode_str[highbit]; - return ""; -} - -static void ata_dev_disable(struct ata_port *ap, struct ata_device *dev) -{ - if (ata_dev_present(dev)) { - printk(KERN_WARNING "ata%u: dev %u disabled\n", - ap->id, dev->devno); - dev->class++; - } -} - -/** - * ata_pio_devchk - PATA device presence detection - * @ap: ATA channel to examine - * @device: Device to examine (starting at zero) - * - * This technique was originally described in - * Hale Landis's ATADRVR (www.ata-atapi.com), and - * later found its way into the ATA/ATAPI spec. - * - * Write a pattern to the ATA shadow registers, - * and if a device is present, it will respond by - * correctly storing and echoing back the - * ATA shadow register contents. - * - * LOCKING: - * caller. - */ - -static unsigned int ata_pio_devchk(struct ata_port *ap, - unsigned int device) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - u8 nsect, lbal; - - ap->ops->dev_select(ap, device); + ap->ops->dev_select(ap, device); outb(0x55, ioaddr->nsect_addr); outb(0xaa, ioaddr->lbal_addr); @@ -558,7 +838,6 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) * ata_dev_try_classify - Parse returned ATA device signature * @ap: ATA channel to examine * @device: Device to examine (starting at zero) - * @r_err: Value of error register on completion * * After an event -- SRST, E.D.D., or SATA COMRESET -- occurs, * an ATA/ATAPI-defined set of values is placed in the ATA @@ -571,14 +850,11 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) * * LOCKING: * caller. - * - * RETURNS: - * Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE. */ -static unsigned int -ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err) +static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device) { + struct ata_device *dev = &ap->device[device]; struct ata_taskfile tf; unsigned int class; u8 err; @@ -589,8 +865,8 @@ ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err) ap->ops->tf_read(ap, &tf); err = tf.feature; - if (r_err) - *r_err = err; + + dev->class = ATA_DEV_NONE; /* see if device passed diags */ if (err == 1) @@ -598,20 +874,22 @@ ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err) else if ((device == 0) && (err == 0x81)) /* do nothing */ ; else - return ATA_DEV_NONE; + return err; - /* determine if device is ATA or ATAPI */ + /* determine if device if ATA or ATAPI */ class = ata_dev_classify(&tf); - if (class == ATA_DEV_UNKNOWN) - return ATA_DEV_NONE; + return err; if ((class == ATA_DEV_ATA) && (ata_chk_status(ap) == 0)) - return ATA_DEV_NONE; - return class; + return err; + + dev->class = class; + + return err; } /** - * ata_id_string - Convert IDENTIFY DEVICE page into string + * ata_dev_id_string - Convert IDENTIFY DEVICE page into string * @id: IDENTIFY DEVICE results we will examine * @s: string into which data is output * @ofs: offset into identify device page @@ -625,8 +903,8 @@ ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err) * caller. */ -void ata_id_string(const u16 *id, unsigned char *s, - unsigned int ofs, unsigned int len) +void ata_dev_id_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len) { unsigned int c; @@ -644,49 +922,6 @@ void ata_id_string(const u16 *id, unsigned char *s, } } -/** - * ata_id_c_string - Convert IDENTIFY DEVICE page into C string - * @id: IDENTIFY DEVICE results we will examine - * @s: string into which data is output - * @ofs: offset into identify device page - * @len: length of string to return. must be an odd number. - * - * This function is identical to ata_id_string except that it - * trims trailing spaces and terminates the resulting string with - * null. @len must be actual maximum length (even number) + 1. - * - * LOCKING: - * caller. - */ -void ata_id_c_string(const u16 *id, unsigned char *s, - unsigned int ofs, unsigned int len) -{ - unsigned char *p; - - WARN_ON(!(len & 1)); - - ata_id_string(id, s, ofs, len - 1); - - p = s + strnlen(s, len - 1); - while (p > s && p[-1] == ' ') - p--; - *p = '\0'; -} - -static u64 ata_id_n_sectors(const u16 *id) -{ - if (ata_id_has_lba(id)) { - if (ata_id_has_lba48(id)) - return ata_id_u64(id, 100); - else - return ata_id_u32(id, 60); - } else { - if (ata_id_current_chs_valid(id)) - return ata_id_u32(id, 57); - else - return id[1] * id[3] * id[6]; - } -} /** * ata_noop_dev_select - Select device 0/1 on ATA bus @@ -776,175 +1011,90 @@ void ata_dev_select(struct ata_port *ap, unsigned int device, /** * ata_dump_id - IDENTIFY DEVICE info debugging output - * @id: IDENTIFY DEVICE page to dump + * @dev: Device whose IDENTIFY DEVICE page we will dump * - * Dump selected 16-bit words from the given IDENTIFY DEVICE - * page. + * Dump selected 16-bit words from a detected device's + * IDENTIFY PAGE page. * * LOCKING: * caller. */ -static inline void ata_dump_id(const u16 *id) +static inline void ata_dump_id(const struct ata_device *dev) { DPRINTK("49==0x%04x " "53==0x%04x " "63==0x%04x " "64==0x%04x " "75==0x%04x \n", - id[49], - id[53], - id[63], - id[64], - id[75]); + dev->id[49], + dev->id[53], + dev->id[63], + dev->id[64], + dev->id[75]); DPRINTK("80==0x%04x " "81==0x%04x " "82==0x%04x " "83==0x%04x " "84==0x%04x \n", - id[80], - id[81], - id[82], - id[83], - id[84]); + dev->id[80], + dev->id[81], + dev->id[82], + dev->id[83], + dev->id[84]); DPRINTK("88==0x%04x " "93==0x%04x\n", - id[88], - id[93]); + dev->id[88], + dev->id[93]); } -/** - * ata_id_xfermask - Compute xfermask from the given IDENTIFY data - * @id: IDENTIFY data to compute xfer mask from - * - * Compute the xfermask for this device. This is not as trivial - * as it seems if we must consider early devices correctly. - * - * FIXME: pre IDE drive timing (do we care ?). - * - * LOCKING: - * None. +/* + * Compute the PIO modes available for this device. This is not as + * trivial as it seems if we must consider early devices correctly. * - * RETURNS: - * Computed xfermask + * FIXME: pre IDE drive timing (do we care ?). */ -static unsigned int ata_id_xfermask(const u16 *id) + +static unsigned int ata_pio_modes(const struct ata_device *adev) { - unsigned int pio_mask, mwdma_mask, udma_mask; + u16 modes; /* Usual case. Word 53 indicates word 64 is valid */ - if (id[ATA_ID_FIELD_VALID] & (1 << 1)) { - pio_mask = id[ATA_ID_PIO_MODES] & 0x03; - pio_mask <<= 3; - pio_mask |= 0x7; - } else { - /* If word 64 isn't valid then Word 51 high byte holds - * the PIO timing number for the maximum. Turn it into - * a mask. - */ - pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ; - - /* But wait.. there's more. Design your standards by - * committee and you too can get a free iordy field to - * process. However its the speeds not the modes that - * are supported... Note drivers using the timing API - * will get this right anyway - */ + if (adev->id[ATA_ID_FIELD_VALID] & (1 << 1)) { + modes = adev->id[ATA_ID_PIO_MODES] & 0x03; + modes <<= 3; + modes |= 0x7; + return modes; } - mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07; - - udma_mask = 0; - if (id[ATA_ID_FIELD_VALID] & (1 << 2)) - udma_mask = id[ATA_ID_UDMA_MODES] & 0xff; - - return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); -} - -/** - * ata_port_queue_task - Queue port_task - * @ap: The ata_port to queue port_task for - * @fn: workqueue function to be scheduled - * @data: data value to pass to workqueue function - * @delay: delay time for workqueue function - * - * Schedule @fn(@data) for execution after @delay jiffies using - * port_task. There is one port_task per port and it's the - * user(low level driver)'s responsibility to make sure that only - * one task is active at any given time. - * - * libata core layer takes care of synchronization between - * port_task and EH. ata_port_queue_task() may be ignored for EH - * synchronization. - * - * LOCKING: - * Inherited from caller. - */ -void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data, - unsigned long delay) -{ - int rc; - - if (ap->flags & ATA_FLAG_FLUSH_PORT_TASK) - return; - - PREPARE_WORK(&ap->port_task, fn, data); - - if (!delay) - rc = queue_work(ata_wq, &ap->port_task); - else - rc = queue_delayed_work(ata_wq, &ap->port_task, delay); - - /* rc == 0 means that another user is using port task */ - WARN_ON(rc == 0); + /* If word 64 isn't valid then Word 51 high byte holds the PIO timing + number for the maximum. Turn it into a mask and return it */ + modes = (2 << ((adev->id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF)) - 1 ; + return modes; + /* But wait.. there's more. Design your standards by committee and + you too can get a free iordy field to process. However its the + speeds not the modes that are supported... Note drivers using the + timing API will get this right anyway */ } -/** - * ata_port_flush_task - Flush port_task - * @ap: The ata_port to flush port_task for - * - * After this function completes, port_task is guranteed not to - * be running or scheduled. - * - * LOCKING: - * Kernel thread context (may sleep) - */ -void ata_port_flush_task(struct ata_port *ap) -{ - unsigned long flags; - - DPRINTK("ENTER\n"); - - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->flags |= ATA_FLAG_FLUSH_PORT_TASK; - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - DPRINTK("flush #1\n"); - flush_workqueue(ata_wq); - - /* - * At this point, if a task is running, it's guaranteed to see - * the FLUSH flag; thus, it will never queue pio tasks again. - * Cancel and flush. - */ - if (!cancel_delayed_work(&ap->port_task)) { - DPRINTK("flush #2\n"); - flush_workqueue(ata_wq); - } - - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->flags &= ~ATA_FLAG_FLUSH_PORT_TASK; - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - DPRINTK("EXIT\n"); -} +struct ata_exec_internal_arg { + unsigned int err_mask; + struct ata_taskfile *tf; + struct completion *waiting; +}; -void ata_qc_complete_internal(struct ata_queued_cmd *qc) +int ata_qc_complete_internal(struct ata_queued_cmd *qc) { - struct completion *waiting = qc->private_data; + struct ata_exec_internal_arg *arg = qc->private_data; + struct completion *waiting = arg->waiting; - qc->ap->ops->tf_read(qc->ap, &qc->tf); + if (!(qc->err_mask & ~AC_ERR_DEV)) + qc->ap->ops->tf_read(qc->ap, arg->tf); + arg->err_mask = qc->err_mask; + arg->waiting = NULL; complete(waiting); + + return 0; } /** @@ -975,7 +1125,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, struct ata_queued_cmd *qc; DECLARE_COMPLETION(wait); unsigned long flags; - unsigned int err_mask; + struct ata_exec_internal_arg arg; spin_lock_irqsave(&ap->host_set->lock, flags); @@ -989,16 +1139,17 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, qc->nsect = buflen / ATA_SECT_SIZE; } - qc->private_data = &wait; + arg.waiting = &wait; + arg.tf = tf; + qc->private_data = &arg; qc->complete_fn = ata_qc_complete_internal; - ata_qc_issue(qc); + if (ata_qc_issue(qc)) + goto issue_fail; spin_unlock_irqrestore(&ap->host_set->lock, flags); if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) { - ata_port_flush_task(ap); - spin_lock_irqsave(&ap->host_set->lock, flags); /* We're racing with irq here. If we lose, the @@ -1007,8 +1158,8 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, * before the caller cleans up, it will result in a * spurious interrupt. We can live with that. */ - if (qc->flags & ATA_QCFLAG_ACTIVE) { - qc->err_mask = AC_ERR_TIMEOUT; + if (arg.waiting) { + qc->err_mask = AC_ERR_OTHER; ata_qc_complete(qc); printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n", ap->id, command); @@ -1017,28 +1168,12 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, spin_unlock_irqrestore(&ap->host_set->lock, flags); } - *tf = qc->tf; - err_mask = qc->err_mask; + return arg.err_mask; + issue_fail: ata_qc_free(qc); - - /* XXX - Some LLDDs (sata_mv) disable port on command failure. - * Until those drivers are fixed, we detect the condition - * here, fail the command with AC_ERR_SYSTEM and reenable the - * port. - * - * Note that this doesn't change any behavior as internal - * command failure results in disabling the device in the - * higher layer for LLDDs without new reset/EH callbacks. - * - * Kill the following code as soon as those drivers are fixed. - */ - if (ap->flags & ATA_FLAG_PORT_DISABLED) { - err_mask |= AC_ERR_SYSTEM; - ata_port_probe(ap); - } - - return err_mask; + spin_unlock_irqrestore(&ap->host_set->lock, flags); + return AC_ERR_OTHER; } /** @@ -1058,7 +1193,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) return 0; if (speed > 2) return 1; - + /* If we have no drive specific rule, then PIO 2 is non IORDY */ if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE */ @@ -1075,280 +1210,272 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) } /** - * ata_dev_read_id - Read ID data from the specified device - * @ap: port on which target device resides - * @dev: target device - * @p_class: pointer to class of the target device (may be changed) - * @post_reset: is this read ID post-reset? - * @p_id: read IDENTIFY page (newly allocated) - * - * Read ID data from the specified device. ATA_CMD_ID_ATA is - * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI - * devices. This function also issues ATA_CMD_INIT_DEV_PARAMS - * for pre-ATA4 drives. + * ata_dev_identify - obtain IDENTIFY x DEVICE page + * @ap: port on which device we wish to probe resides + * @device: device bus address, starting at zero + * + * Following bus reset, we issue the IDENTIFY [PACKET] DEVICE + * command, and read back the 512-byte device information page. + * The device information page is fed to us via the standard + * PIO-IN protocol, but we hand-code it here. (TODO: investigate + * using standard PIO-IN paths) + * + * After reading the device information page, we use several + * bits of information from it to initialize data structures + * that will be used during the lifetime of the ata_device. + * Other data from the info page is used to disqualify certain + * older ATA devices we do not wish to support. * * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. + * Inherited from caller. Some functions called by this function + * obtain the host_set lock. */ -static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, - unsigned int *p_class, int post_reset, u16 **p_id) + +static void ata_dev_identify(struct ata_port *ap, unsigned int device) { - unsigned int class = *p_class; + struct ata_device *dev = &ap->device[device]; + unsigned int major_version; + u16 tmp; + unsigned long xfer_modes; + unsigned int using_edd; struct ata_taskfile tf; - unsigned int err_mask = 0; - u16 *id; - const char *reason; + unsigned int err_mask; int rc; - DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); + if (!ata_dev_present(dev)) { + DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n", + ap->id, device); + return; + } - ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ + if (ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET)) + using_edd = 0; + else + using_edd = 1; - id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL); - if (id == NULL) { - rc = -ENOMEM; - reason = "out of memory"; - goto err_out; - } + DPRINTK("ENTER, host %u, dev %u\n", ap->id, device); - retry: - ata_tf_init(ap, &tf, dev->devno); + assert (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ATAPI || + dev->class == ATA_DEV_NONE); + + ata_dev_select(ap, device, 1, 1); /* select device 0/1 */ - switch (class) { - case ATA_DEV_ATA: +retry: + ata_tf_init(ap, &tf, device); + + if (dev->class == ATA_DEV_ATA) { tf.command = ATA_CMD_ID_ATA; - break; - case ATA_DEV_ATAPI: + DPRINTK("do ATA identify\n"); + } else { tf.command = ATA_CMD_ID_ATAPI; - break; - default: - rc = -ENODEV; - reason = "unsupported class"; - goto err_out; + DPRINTK("do ATAPI identify\n"); } tf.protocol = ATA_PROT_PIO; err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, - id, sizeof(id[0]) * ATA_ID_WORDS); - if (err_mask) { - rc = -EIO; - reason = "I/O error"; - goto err_out; - } + dev->id, sizeof(dev->id)); - swap_buf_le16(id, ATA_ID_WORDS); - - /* sanity check */ - if ((class == ATA_DEV_ATA) != (ata_id_is_ata(id) | ata_id_is_cfa(id))) { - rc = -EINVAL; - reason = "device reports illegal type"; - goto err_out; - } + if (err_mask) { + if (err_mask & ~AC_ERR_DEV) + goto err_out; - if (post_reset && class == ATA_DEV_ATA) { /* - * The exact sequence expected by certain pre-ATA4 drives is: - * SRST RESET - * IDENTIFY - * INITIALIZE DEVICE PARAMETERS - * anything else.. - * Some drives were very specific about that exact sequence. + * arg! EDD works for all test cases, but seems to return + * the ATA signature for some ATAPI devices. Until the + * reason for this is found and fixed, we fix up the mess + * here. If IDENTIFY DEVICE returns command aborted + * (as ATAPI devices do), then we issue an + * IDENTIFY PACKET DEVICE. + * + * ATA software reset (SRST, the default) does not appear + * to have this problem. */ - if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { - err_mask = ata_dev_init_params(ap, dev, id[3], id[6]); - if (err_mask) { - rc = -EIO; - reason = "INIT_DEV_PARAMS failed"; - goto err_out; + if ((using_edd) && (dev->class == ATA_DEV_ATA)) { + u8 err = tf.feature; + if (err & ATA_ABORTED) { + dev->class = ATA_DEV_ATAPI; + goto retry; } - - /* current CHS translation info (id[53-58]) might be - * changed. reread the identify device info. - */ - post_reset = 0; - goto retry; } + goto err_out; } - *p_class = class; - *p_id = id; - return 0; - - err_out: - printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n", - ap->id, dev->devno, reason); - kfree(id); - return rc; -} - -static inline u8 ata_dev_knobble(const struct ata_port *ap, - struct ata_device *dev) -{ - return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); -} - -/** - * ata_dev_configure - Configure the specified ATA/ATAPI device - * @ap: Port on which target device resides - * @dev: Target device to configure - * @print_info: Enable device info printout - * - * Configure @dev according to @dev->id. Generic and low-level - * driver specific fixups are also applied. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise - */ -static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, - int print_info) -{ - const u16 *id = dev->id; - unsigned int xfer_mask; - int i, rc; - - if (!ata_dev_present(dev)) { - DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n", - ap->id, dev->devno); - return 0; - } - - DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); + swap_buf_le16(dev->id, ATA_ID_WORDS); /* print device capabilities */ - if (print_info) - printk(KERN_DEBUG "ata%u: dev %u cfg 49:%04x 82:%04x 83:%04x " - "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", - ap->id, dev->devno, id[49], id[82], id[83], - id[84], id[85], id[86], id[87], id[88]); - - /* initialize to-be-configured parameters */ - dev->flags &= ~ATA_DFLAG_CFG_MASK; - dev->max_sectors = 0; - dev->cdb_len = 0; - dev->n_sectors = 0; - dev->cylinders = 0; - dev->heads = 0; - dev->sectors = 0; + printk(KERN_DEBUG "ata%u: dev %u cfg " + "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", + ap->id, device, dev->id[49], + dev->id[82], dev->id[83], dev->id[84], + dev->id[85], dev->id[86], dev->id[87], + dev->id[88]); /* * common ATA, ATAPI feature tests */ - /* find max transfer mode; for printk only */ - xfer_mask = ata_id_xfermask(id); + /* we require DMA support (bits 8 of word 49) */ + if (!ata_id_has_dma(dev->id)) { + printk(KERN_DEBUG "ata%u: no dma\n", ap->id); + goto err_out_nosup; + } + + /* quick-n-dirty find max transfer mode; for printk only */ + xfer_modes = dev->id[ATA_ID_UDMA_MODES]; + if (!xfer_modes) + xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA; + if (!xfer_modes) + xfer_modes = ata_pio_modes(dev); - ata_dump_id(id); + ata_dump_id(dev); /* ATA-specific feature tests */ if (dev->class == ATA_DEV_ATA) { - dev->n_sectors = ata_id_n_sectors(id); + if (!ata_id_is_ata(dev->id)) /* sanity check */ + goto err_out_nosup; + + /* get major version */ + tmp = dev->id[ATA_ID_MAJOR_VER]; + for (major_version = 14; major_version >= 1; major_version--) + if (tmp & (1 << major_version)) + break; + + /* + * The exact sequence expected by certain pre-ATA4 drives is: + * SRST RESET + * IDENTIFY + * INITIALIZE DEVICE PARAMETERS + * anything else.. + * Some drives were very specific about that exact sequence. + */ + if (major_version < 4 || (!ata_id_has_lba(dev->id))) { + ata_dev_init_params(ap, dev); - if (ata_id_has_lba(id)) { - const char *lba_desc; + /* current CHS translation info (id[53-58]) might be + * changed. reread the identify device info. + */ + ata_dev_reread_id(ap, dev); + } - lba_desc = "LBA"; + if (ata_id_has_lba(dev->id)) { dev->flags |= ATA_DFLAG_LBA; - if (ata_id_has_lba48(id)) { + + if (ata_id_has_lba48(dev->id)) { dev->flags |= ATA_DFLAG_LBA48; - lba_desc = "LBA48"; + dev->n_sectors = ata_id_u64(dev->id, 100); + } else { + dev->n_sectors = ata_id_u32(dev->id, 60); } /* print device info to dmesg */ - if (print_info) - printk(KERN_INFO "ata%u: dev %u ATA-%d, " - "max %s, %Lu sectors: %s\n", - ap->id, dev->devno, - ata_id_major_version(id), - ata_mode_string(xfer_mask), - (unsigned long long)dev->n_sectors, - lba_desc); - } else { + printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n", + ap->id, device, + major_version, + ata_mode_string(xfer_modes), + (unsigned long long)dev->n_sectors, + dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA"); + } else { /* CHS */ /* Default translation */ - dev->cylinders = id[1]; - dev->heads = id[3]; - dev->sectors = id[6]; + dev->cylinders = dev->id[1]; + dev->heads = dev->id[3]; + dev->sectors = dev->id[6]; + dev->n_sectors = dev->cylinders * dev->heads * dev->sectors; - if (ata_id_current_chs_valid(id)) { + if (ata_id_current_chs_valid(dev->id)) { /* Current CHS translation is valid. */ - dev->cylinders = id[54]; - dev->heads = id[55]; - dev->sectors = id[56]; + dev->cylinders = dev->id[54]; + dev->heads = dev->id[55]; + dev->sectors = dev->id[56]; + + dev->n_sectors = ata_id_u32(dev->id, 57); } /* print device info to dmesg */ - if (print_info) - printk(KERN_INFO "ata%u: dev %u ATA-%d, " - "max %s, %Lu sectors: CHS %u/%u/%u\n", - ap->id, dev->devno, - ata_id_major_version(id), - ata_mode_string(xfer_mask), - (unsigned long long)dev->n_sectors, - dev->cylinders, dev->heads, dev->sectors); + printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n", + ap->id, device, + major_version, + ata_mode_string(xfer_modes), + (unsigned long long)dev->n_sectors, + (int)dev->cylinders, (int)dev->heads, (int)dev->sectors); + } - dev->cdb_len = 16; + ap->host->max_cmd_len = 16; } /* ATAPI-specific feature tests */ else if (dev->class == ATA_DEV_ATAPI) { - rc = atapi_cdb_len(id); + if (ata_id_is_ata(dev->id)) /* sanity check */ + goto err_out_nosup; + + rc = atapi_cdb_len(dev->id); if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id); - rc = -EINVAL; goto err_out_nosup; } - dev->cdb_len = (unsigned int) rc; + ap->cdb_len = (unsigned int) rc; + ap->host->max_cmd_len = (unsigned char) ap->cdb_len; /* print device info to dmesg */ - if (print_info) - printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n", - ap->id, dev->devno, ata_mode_string(xfer_mask)); - } - - ap->host->max_cmd_len = 0; - for (i = 0; i < ATA_MAX_DEVICES; i++) - ap->host->max_cmd_len = max_t(unsigned int, - ap->host->max_cmd_len, - ap->device[i].cdb_len); - - /* limit bridge transfers to udma5, 200 sectors */ - if (ata_dev_knobble(ap, dev)) { - if (print_info) - printk(KERN_INFO "ata%u(%u): applying bridge limits\n", - ap->id, dev->devno); - dev->udma_mask &= ATA_UDMA5; - dev->max_sectors = ATA_MAX_SECTORS; + printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n", + ap->id, device, + ata_mode_string(xfer_modes)); } - if (ap->ops->dev_config) - ap->ops->dev_config(ap, dev); - DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap)); - return 0; + return; err_out_nosup: + printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n", + ap->id, device); +err_out: + dev->class++; /* converts ATA_DEV_xxx into ATA_DEV_xxx_UNSUP */ DPRINTK("EXIT, err\n"); - return rc; +} + + +static inline u8 ata_dev_knobble(const struct ata_port *ap) +{ + return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id))); } /** - * ata_bus_probe - Reset and probe ATA bus - * @ap: Bus to probe - * - * Master ATA bus probing function. Initiates a hardware-dependent - * bus reset, then attempts to identify any devices found on - * the bus. + * ata_dev_config - Run device specific handlers and check for + * SATA->PATA bridges + * @ap: Bus + * @i: Device * - * LOCKING: + * LOCKING: + */ + +void ata_dev_config(struct ata_port *ap, unsigned int i) +{ + /* limit bridge transfers to udma5, 200 sectors */ + if (ata_dev_knobble(ap)) { + printk(KERN_INFO "ata%u(%u): applying bridge limits\n", + ap->id, ap->device->devno); + ap->udma_mask &= ATA_UDMA5; + ap->host->max_sectors = ATA_MAX_SECTORS; + ap->host->hostt->max_sectors = ATA_MAX_SECTORS; + ap->device[i].flags |= ATA_DFLAG_LOCK_SECTORS; + } + + if (ap->ops->dev_config) + ap->ops->dev_config(ap, &ap->device[i]); +} + +/** + * ata_bus_probe - Reset and probe ATA bus + * @ap: Bus to probe + * + * Master ATA bus probing function. Initiates a hardware-dependent + * bus reset, then attempts to identify any devices found on + * the bus. + * + * LOCKING: * PCI/etc. bus probe sem. * * RETURNS: @@ -1357,66 +1484,24 @@ err_out_nosup: static int ata_bus_probe(struct ata_port *ap) { - unsigned int classes[ATA_MAX_DEVICES]; - unsigned int i, rc, found = 0; - - ata_port_probe(ap); - - /* reset and determine device classes */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - classes[i] = ATA_DEV_UNKNOWN; - - if (ap->ops->probe_reset) { - rc = ap->ops->probe_reset(ap, classes); - if (rc) { - printk("ata%u: reset failed (errno=%d)\n", ap->id, rc); - return rc; - } - } else { - ap->ops->phy_reset(ap); - - if (!(ap->flags & ATA_FLAG_PORT_DISABLED)) - for (i = 0; i < ATA_MAX_DEVICES; i++) - classes[i] = ap->device[i].class; - - ata_port_probe(ap); - } + unsigned int i, found = 0; - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (classes[i] == ATA_DEV_UNKNOWN) - classes[i] = ATA_DEV_NONE; + ap->ops->phy_reset(ap); + if (ap->flags & ATA_FLAG_PORT_DISABLED) + goto err_out; - /* read IDENTIFY page and configure devices */ for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - - dev->class = classes[i]; - - if (!ata_dev_present(dev)) - continue; - - WARN_ON(dev->id != NULL); - if (ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id)) { - dev->class = ATA_DEV_NONE; - continue; + ata_dev_identify(ap, i); + if (ata_dev_present(&ap->device[i])) { + found = 1; + ata_dev_config(ap,i); } - - if (ata_dev_configure(ap, dev, 1)) { - ata_dev_disable(ap, dev); - continue; - } - - found = 1; } - if (!found) + if ((!found) || (ap->flags & ATA_FLAG_PORT_DISABLED)) goto err_out_disable; - if (ap->ops->set_mode) - ap->ops->set_mode(ap); - else - ata_set_mode(ap); - + ata_set_mode(ap); if (ap->flags & ATA_FLAG_PORT_DISABLED) goto err_out_disable; @@ -1424,6 +1509,7 @@ static int ata_bus_probe(struct ata_port *ap) err_out_disable: ap->ops->port_disable(ap); +err_out: return -1; } @@ -1443,41 +1529,6 @@ void ata_port_probe(struct ata_port *ap) ap->flags &= ~ATA_FLAG_PORT_DISABLED; } -/** - * sata_print_link_status - Print SATA link status - * @ap: SATA port to printk link status about - * - * This function prints link speed and status of a SATA link. - * - * LOCKING: - * None. - */ -static void sata_print_link_status(struct ata_port *ap) -{ - u32 sstatus, tmp; - const char *speed; - - if (!ap->ops->scr_read) - return; - - sstatus = scr_read(ap, SCR_STATUS); - - if (sata_dev_present(ap)) { - tmp = (sstatus >> 4) & 0xf; - if (tmp & (1 << 0)) - speed = "1.5"; - else if (tmp & (1 << 1)) - speed = "3.0"; - else - speed = ""; - printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n", - ap->id, speed, sstatus); - } else { - printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n", - ap->id, sstatus); - } -} - /** * __sata_phy_reset - Wake/reset a low-level SATA PHY * @ap: SATA port associated with target SATA PHY. @@ -1512,14 +1563,27 @@ void __sata_phy_reset(struct ata_port *ap) break; } while (time_before(jiffies, timeout)); - /* print link status */ - sata_print_link_status(ap); - /* TODO: phy layer with polling, timeouts, etc. */ - if (sata_dev_present(ap)) + sstatus = scr_read(ap, SCR_STATUS); + if (sata_dev_present(ap)) { + const char *speed; + u32 tmp; + + tmp = (sstatus >> 4) & 0xf; + if (tmp & (1 << 0)) + speed = "1.5"; + else if (tmp & (1 << 1)) + speed = "3.0"; + else + speed = ""; + printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n", + ap->id, speed, sstatus); ata_port_probe(ap); - else + } else { + printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n", + ap->id, sstatus); ata_port_disable(ap); + } if (ap->flags & ATA_FLAG_PORT_DISABLED) return; @@ -1551,23 +1615,6 @@ void sata_phy_reset(struct ata_port *ap) ata_bus_reset(ap); } -/** - * ata_dev_pair - return other device on cable - * @ap: port - * @adev: device - * - * Obtain the other device on the same cable, or if none is - * present NULL is returned - */ - -struct ata_device *ata_dev_pair(struct ata_port *ap, struct ata_device *adev) -{ - struct ata_device *pair = &ap->device[1 - adev->devno]; - if (!ata_dev_present(pair)) - return NULL; - return pair; -} - /** * ata_port_disable - Disable port. * @ap: Port to be disabled. @@ -1596,7 +1643,7 @@ void ata_port_disable(struct ata_port *ap) * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). * These were taken from ATA/ATAPI-6 standard, rev 0a, except * for PIO 5, which is a nonstandard extension and UDMA6, which - * is currently supported only by Maxtor drives. + * is currently supported only by Maxtor drives. */ static const struct ata_timing ata_timing[] = { @@ -1611,11 +1658,11 @@ static const struct ata_timing ata_timing[] = { { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, /* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 }, */ - + { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, - + { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, @@ -1668,7 +1715,7 @@ static const struct ata_timing* ata_timing_find_mode(unsigned short speed) for (t = ata_timing; t->mode != speed; t++) if (t->mode == 0xFF) return NULL; - return t; + return t; } int ata_timing_compute(struct ata_device *adev, unsigned short speed, @@ -1678,7 +1725,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, struct ata_timing p; /* - * Find the mode. + * Find the mode. */ if (!(s = ata_timing_find_mode(speed))) @@ -1709,9 +1756,9 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, ata_timing_quantize(t, t, T, UT); /* - * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, - * S.M.A.R.T * and some other commands. We have to ensure that the - * DMA cycle timing is slower/equal than the fastest PIO timing. + * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T + * and some other commands. We have to ensure that the DMA cycle timing is + * slower/equal than the fastest PIO timing. */ if (speed > XFER_PIO_4) { @@ -1720,7 +1767,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, } /* - * Lengthen active & recovery time so that cycle time is correct. + * Lenghten active & recovery time so that cycle time is correct. */ if (t->act8b + t->rec8b < t->cyc8b) { @@ -1736,77 +1783,98 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, return 0; } -static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) +static const struct { + unsigned int shift; + u8 base; +} xfer_mode_classes[] = { + { ATA_SHIFT_UDMA, XFER_UDMA_0 }, + { ATA_SHIFT_MWDMA, XFER_MW_DMA_0 }, + { ATA_SHIFT_PIO, XFER_PIO_0 }, +}; + +static u8 base_from_shift(unsigned int shift) { - unsigned int err_mask; - int rc; + int i; + + for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) + if (xfer_mode_classes[i].shift == shift) + return xfer_mode_classes[i].base; + + return 0xff; +} + +static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) +{ + int ofs, idx; + u8 base; + + if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED)) + return; if (dev->xfer_shift == ATA_SHIFT_PIO) dev->flags |= ATA_DFLAG_PIO; - err_mask = ata_dev_set_xfermode(ap, dev); - if (err_mask) { - printk(KERN_ERR - "ata%u: failed to set xfermode (err_mask=0x%x)\n", - ap->id, err_mask); - return -EIO; - } + ata_dev_set_xfermode(ap, dev); - rc = ata_dev_revalidate(ap, dev, 0); - if (rc) { - printk(KERN_ERR - "ata%u: failed to revalidate after set xfermode\n", - ap->id); - return rc; - } + base = base_from_shift(dev->xfer_shift); + ofs = dev->xfer_mode - base; + idx = ofs + dev->xfer_shift; + WARN_ON(idx >= ARRAY_SIZE(xfer_mode_str)); - DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n", - dev->xfer_shift, (int)dev->xfer_mode); + DPRINTK("idx=%d xfer_shift=%u, xfer_mode=0x%x, base=0x%x, offset=%d\n", + idx, dev->xfer_shift, (int)dev->xfer_mode, (int)base, ofs); printk(KERN_INFO "ata%u: dev %u configured for %s\n", - ap->id, dev->devno, - ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode))); - return 0; + ap->id, dev->devno, xfer_mode_str[idx]); } static int ata_host_set_pio(struct ata_port *ap) { - int i; + unsigned int mask; + int x, i; + u8 base, xfer_mode; + + mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO); + x = fgb(mask); + if (x < 0) { + printk(KERN_WARNING "ata%u: no PIO support\n", ap->id); + return -1; + } - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; + base = base_from_shift(ATA_SHIFT_PIO); + xfer_mode = base + x; - if (!ata_dev_present(dev)) - continue; + DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n", + (int)base, (int)xfer_mode, mask, x); - if (!dev->pio_mode) { - printk(KERN_WARNING "ata%u: no PIO support for device %d.\n", ap->id, i); - return -1; + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + if (ata_dev_present(dev)) { + dev->pio_mode = xfer_mode; + dev->xfer_mode = xfer_mode; + dev->xfer_shift = ATA_SHIFT_PIO; + if (ap->ops->set_piomode) + ap->ops->set_piomode(ap, dev); } - - dev->xfer_mode = dev->pio_mode; - dev->xfer_shift = ATA_SHIFT_PIO; - if (ap->ops->set_piomode) - ap->ops->set_piomode(ap, dev); } return 0; } -static void ata_host_set_dma(struct ata_port *ap) +static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, + unsigned int xfer_shift) { int i; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - - if (!ata_dev_present(dev) || !dev->dma_mode) - continue; - - dev->xfer_mode = dev->dma_mode; - dev->xfer_shift = ata_xfer_mode2shift(dev->dma_mode); - if (ap->ops->set_dmamode) - ap->ops->set_dmamode(ap, dev); + if (ata_dev_present(dev)) { + dev->dma_mode = xfer_mode; + dev->xfer_mode = xfer_mode; + dev->xfer_shift = xfer_shift; + if (ap->ops->set_dmamode) + ap->ops->set_dmamode(ap, dev); + } } } @@ -1818,62 +1886,36 @@ static void ata_host_set_dma(struct ata_port *ap) * * LOCKING: * PCI/etc. bus probe sem. + * */ static void ata_set_mode(struct ata_port *ap) { - int i, rc, used_dma = 0; - - /* step 1: calculate xfer_mask */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - unsigned int pio_mask, dma_mask; - - if (!ata_dev_present(dev)) - continue; - - ata_dev_xfermask(ap, dev); - - /* TODO: let LLDD filter dev->*_mask here */ - - pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0); - dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); - dev->pio_mode = ata_xfer_mask2mode(pio_mask); - dev->dma_mode = ata_xfer_mask2mode(dma_mask); - - if (dev->dma_mode) - used_dma = 1; - } + unsigned int xfer_shift; + u8 xfer_mode; + int rc; - /* step 2: always set host PIO timings */ + /* step 1: always set host PIO timings */ rc = ata_host_set_pio(ap); if (rc) goto err_out; - /* step 3: set host DMA timings */ - ata_host_set_dma(ap); - - /* step 4: update devices' xfer mode */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - - if (!ata_dev_present(dev)) - continue; + /* step 2: choose the best data xfer mode */ + xfer_mode = xfer_shift = 0; + rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift); + if (rc) + goto err_out; - if (ata_dev_set_mode(ap, dev)) - goto err_out; - } + /* step 3: if that xfer mode isn't PIO, set host DMA timings */ + if (xfer_shift != ATA_SHIFT_PIO) + ata_host_set_dma(ap, xfer_mode, xfer_shift); - /* - * Record simplex status. If we selected DMA then the other - * host channels are not permitted to do so. - */ + /* step 4: update devices' xfer mode */ + ata_dev_set_mode(ap, &ap->device[0]); + ata_dev_set_mode(ap, &ap->device[1]); - if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX)) - ap->host_set->simplex_claimed = 1; + if (ap->flags & ATA_FLAG_PORT_DISABLED) + return; - /* - * Chip specific finalisation - */ if (ap->ops->post_set_mode) ap->ops->post_set_mode(ap); @@ -1883,26 +1925,6 @@ err_out: ata_port_disable(ap); } -/** - * ata_tf_to_host - issue ATA taskfile to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set - * - * Issues ATA taskfile register set to ATA host controller, - * with proper synchronization with interrupt handler and - * other threads. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static inline void ata_tf_to_host(struct ata_port *ap, - const struct ata_taskfile *tf) -{ - ap->ops->tf_load(ap, tf); - ap->ops->exec_command(ap, tf); -} - /** * ata_busy_sleep - sleep until BSY clears, or timeout * @ap: port containing status register to be polled @@ -1913,10 +1935,12 @@ static inline void ata_tf_to_host(struct ata_port *ap, * or a timeout occurs. * * LOCKING: None. + * */ -unsigned int ata_busy_sleep (struct ata_port *ap, - unsigned long tmout_pat, unsigned long tmout) +static unsigned int ata_busy_sleep (struct ata_port *ap, + unsigned long tmout_pat, + unsigned long tmout) { unsigned long timer_start, timeout; u8 status; @@ -1995,6 +2019,45 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) ap->ops->dev_select(ap, 0); } +/** + * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command. + * @ap: Port to reset and probe + * + * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and + * probe the bus. Not often used these days. + * + * LOCKING: + * PCI/etc. bus probe sem. + * Obtains host_set lock. + * + */ + +static unsigned int ata_bus_edd(struct ata_port *ap) +{ + struct ata_taskfile tf; + unsigned long flags; + + /* set up execute-device-diag (bus reset) taskfile */ + /* also, take interrupts to a known state (disabled) */ + DPRINTK("execute-device-diag\n"); + ata_tf_init(ap, &tf, 0); + tf.ctl |= ATA_NIEN; + tf.command = ATA_CMD_EDD; + tf.protocol = ATA_PROT_NODATA; + + /* do bus reset */ + spin_lock_irqsave(&ap->host_set->lock, flags); + ata_tf_to_host(ap, &tf); + spin_unlock_irqrestore(&ap->host_set->lock, flags); + + /* spec says at least 2ms. but who knows with those + * crazy ATAPI devices... + */ + msleep(150); + + return ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); +} + static unsigned int ata_bus_softreset(struct ata_port *ap, unsigned int devmask) { @@ -2024,18 +2087,9 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, * status is checked. Because waiting for "a while" before * checking status is fine, post SRST, we perform this magic * delay here as well. - * - * Old drivers/ide uses the 2mS rule and then waits for ready */ msleep(150); - /* Before we perform post reset processing we want to see if - * the bus shows 0xFF because the odd clown forgets the D7 - * pulldown resistor. - */ - if (ata_check_status(ap) == 0xFF) - return AC_ERR_OTHER; - ata_bus_post_reset(ap, devmask); return 0; @@ -2058,647 +2112,276 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, * Obtains host_set lock. * * SIDE EFFECTS: - * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. - */ - -void ata_bus_reset(struct ata_port *ap) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; - u8 err; - unsigned int dev0, dev1 = 0, devmask = 0; - - DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); - - /* determine if device 0/1 are present */ - if (ap->flags & ATA_FLAG_SATA_RESET) - dev0 = 1; - else { - dev0 = ata_devchk(ap, 0); - if (slave_possible) - dev1 = ata_devchk(ap, 1); - } - - if (dev0) - devmask |= (1 << 0); - if (dev1) - devmask |= (1 << 1); - - /* select device 0 again */ - ap->ops->dev_select(ap, 0); - - /* issue bus reset */ - if (ap->flags & ATA_FLAG_SRST) - if (ata_bus_softreset(ap, devmask)) - goto err_out; - - /* - * determine by signature whether we have ATA or ATAPI devices - */ - ap->device[0].class = ata_dev_try_classify(ap, 0, &err); - if ((slave_possible) && (err != 0x81)) - ap->device[1].class = ata_dev_try_classify(ap, 1, &err); - - /* re-enable interrupts */ - if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ - ata_irq_on(ap); - - /* is double-select really necessary? */ - if (ap->device[1].class != ATA_DEV_NONE) - ap->ops->dev_select(ap, 1); - if (ap->device[0].class != ATA_DEV_NONE) - ap->ops->dev_select(ap, 0); - - /* if no devices were detected, disable this port */ - if ((ap->device[0].class == ATA_DEV_NONE) && - (ap->device[1].class == ATA_DEV_NONE)) - goto err_out; - - if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) { - /* set up device control for ATA_FLAG_SATA_RESET */ - if (ap->flags & ATA_FLAG_MMIO) - writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); - else - outb(ap->ctl, ioaddr->ctl_addr); - } - - DPRINTK("EXIT\n"); - return; - -err_out: - printk(KERN_ERR "ata%u: disabling port\n", ap->id); - ap->ops->port_disable(ap); - - DPRINTK("EXIT\n"); -} - -static int sata_phy_resume(struct ata_port *ap) -{ - unsigned long timeout = jiffies + (HZ * 5); - u32 sstatus; - - scr_write_flush(ap, SCR_CONTROL, 0x300); - - /* Wait for phy to become ready, if necessary. */ - do { - msleep(200); - sstatus = scr_read(ap, SCR_STATUS); - if ((sstatus & 0xf) != 1) - return 0; - } while (time_before(jiffies, timeout)); - - return -1; -} - -/** - * ata_std_probeinit - initialize probing - * @ap: port to be probed - * - * @ap is about to be probed. Initialize it. This function is - * to be used as standard callback for ata_drive_probe_reset(). - * - * NOTE!!! Do not use this function as probeinit if a low level - * driver implements only hardreset. Just pass NULL as probeinit - * in that case. Using this function is probably okay but doing - * so makes reset sequence different from the original - * ->phy_reset implementation and Jeff nervous. :-P - */ -void ata_std_probeinit(struct ata_port *ap) -{ - if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) { - sata_phy_resume(ap); - if (sata_dev_present(ap)) - ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); - } -} - -/** - * ata_std_softreset - reset host port via ATA SRST - * @ap: port to reset - * @verbose: fail verbosely - * @classes: resulting classes of attached devices - * - * Reset host port using ATA SRST. This function is to be used - * as standard callback for ata_drive_*_reset() functions. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes) -{ - unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; - unsigned int devmask = 0, err_mask; - u8 err; - - DPRINTK("ENTER\n"); - - if (ap->ops->scr_read && !sata_dev_present(ap)) { - classes[0] = ATA_DEV_NONE; - goto out; - } - - /* determine if device 0/1 are present */ - if (ata_devchk(ap, 0)) - devmask |= (1 << 0); - if (slave_possible && ata_devchk(ap, 1)) - devmask |= (1 << 1); - - /* select device 0 again */ - ap->ops->dev_select(ap, 0); - - /* issue bus reset */ - DPRINTK("about to softreset, devmask=%x\n", devmask); - err_mask = ata_bus_softreset(ap, devmask); - if (err_mask) { - if (verbose) - printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n", - ap->id, err_mask); - else - DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n", - err_mask); - return -EIO; - } - - /* determine by signature whether we have ATA or ATAPI devices */ - classes[0] = ata_dev_try_classify(ap, 0, &err); - if (slave_possible && err != 0x81) - classes[1] = ata_dev_try_classify(ap, 1, &err); - - out: - DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); - return 0; -} - -/** - * sata_std_hardreset - reset host port via SATA phy reset - * @ap: port to reset - * @verbose: fail verbosely - * @class: resulting class of attached device - * - * SATA phy-reset host port using DET bits of SControl register. - * This function is to be used as standard callback for - * ata_drive_*_reset(). - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class) -{ - DPRINTK("ENTER\n"); - - /* Issue phy wake/reset */ - scr_write_flush(ap, SCR_CONTROL, 0x301); - - /* - * Couldn't find anything in SATA I/II specs, but AHCI-1.1 - * 10.4.2 says at least 1 ms. - */ - msleep(1); - - /* Bring phy back */ - sata_phy_resume(ap); - - /* TODO: phy layer with polling, timeouts, etc. */ - if (!sata_dev_present(ap)) { - *class = ATA_DEV_NONE; - DPRINTK("EXIT, link offline\n"); - return 0; - } - - if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { - if (verbose) - printk(KERN_ERR "ata%u: COMRESET failed " - "(device not ready)\n", ap->id); - else - DPRINTK("EXIT, device not ready\n"); - return -EIO; - } - - ap->ops->dev_select(ap, 0); /* probably unnecessary */ - - *class = ata_dev_try_classify(ap, 0, NULL); - - DPRINTK("EXIT, class=%u\n", *class); - return 0; -} - -/** - * ata_std_postreset - standard postreset callback - * @ap: the target ata_port - * @classes: classes of attached devices - * - * This function is invoked after a successful reset. Note that - * the device might have been reset more than once using - * different reset methods before postreset is invoked. - * - * This function is to be used as standard callback for - * ata_drive_*_reset(). - * - * LOCKING: - * Kernel thread context (may sleep) - */ -void ata_std_postreset(struct ata_port *ap, unsigned int *classes) -{ - DPRINTK("ENTER\n"); - - /* set cable type if it isn't already set */ - if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA) - ap->cbl = ATA_CBL_SATA; - - /* print link status */ - if (ap->cbl == ATA_CBL_SATA) - sata_print_link_status(ap); - - /* re-enable interrupts */ - if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ - ata_irq_on(ap); - - /* is double-select really necessary? */ - if (classes[0] != ATA_DEV_NONE) - ap->ops->dev_select(ap, 1); - if (classes[1] != ATA_DEV_NONE) - ap->ops->dev_select(ap, 0); - - /* bail out if no device is present */ - if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { - DPRINTK("EXIT, no device\n"); - return; - } - - /* set up device control */ - if (ap->ioaddr.ctl_addr) { - if (ap->flags & ATA_FLAG_MMIO) - writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr); - else - outb(ap->ctl, ap->ioaddr.ctl_addr); - } - - DPRINTK("EXIT\n"); -} - -/** - * ata_std_probe_reset - standard probe reset method - * @ap: prot to perform probe-reset - * @classes: resulting classes of attached devices - * - * The stock off-the-shelf ->probe_reset method. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes) -{ - ata_reset_fn_t hardreset; - - hardreset = NULL; - if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) - hardreset = sata_std_hardreset; - - return ata_drive_probe_reset(ap, ata_std_probeinit, - ata_std_softreset, hardreset, - ata_std_postreset, classes); -} - -static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset, - ata_postreset_fn_t postreset, - unsigned int *classes) -{ - int i, rc; - - for (i = 0; i < ATA_MAX_DEVICES; i++) - classes[i] = ATA_DEV_UNKNOWN; - - rc = reset(ap, 0, classes); - if (rc) - return rc; - - /* If any class isn't ATA_DEV_UNKNOWN, consider classification - * is complete and convert all ATA_DEV_UNKNOWN to - * ATA_DEV_NONE. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (classes[i] != ATA_DEV_UNKNOWN) - break; - - if (i < ATA_MAX_DEVICES) - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (classes[i] == ATA_DEV_UNKNOWN) - classes[i] = ATA_DEV_NONE; - - if (postreset) - postreset(ap, classes); - - return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV; -} - -/** - * ata_drive_probe_reset - Perform probe reset with given methods - * @ap: port to reset - * @probeinit: probeinit method (can be NULL) - * @softreset: softreset method (can be NULL) - * @hardreset: hardreset method (can be NULL) - * @postreset: postreset method (can be NULL) - * @classes: resulting classes of attached devices - * - * Reset the specified port and classify attached devices using - * given methods. This function prefers softreset but tries all - * possible reset sequences to reset and classify devices. This - * function is intended to be used for constructing ->probe_reset - * callback by low level drivers. - * - * Reset methods should follow the following rules. - * - * - Return 0 on sucess, -errno on failure. - * - If classification is supported, fill classes[] with - * recognized class codes. - * - If classification is not supported, leave classes[] alone. - * - If verbose is non-zero, print error message on failure; - * otherwise, shut up. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -EINVAL if no reset method is avaliable, -ENODEV - * if classification fails, and any error code from reset - * methods. - */ -int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, - ata_reset_fn_t softreset, ata_reset_fn_t hardreset, - ata_postreset_fn_t postreset, unsigned int *classes) -{ - int rc = -EINVAL; - - if (probeinit) - probeinit(ap); - - if (softreset) { - rc = do_probe_reset(ap, softreset, postreset, classes); - if (rc == 0) - return 0; - } - - if (!hardreset) - return rc; - - rc = do_probe_reset(ap, hardreset, postreset, classes); - if (rc == 0 || rc != -ENODEV) - return rc; - - if (softreset) - rc = do_probe_reset(ap, softreset, postreset, classes); - - return rc; -} - -/** - * ata_dev_same_device - Determine whether new ID matches configured device - * @ap: port on which the device to compare against resides - * @dev: device to compare against - * @new_class: class of the new device - * @new_id: IDENTIFY page of the new device - * - * Compare @new_class and @new_id against @dev and determine - * whether @dev is the device indicated by @new_class and - * @new_id. - * - * LOCKING: - * None. - * - * RETURNS: - * 1 if @dev matches @new_class and @new_id, 0 otherwise. + * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. */ -static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev, - unsigned int new_class, const u16 *new_id) -{ - const u16 *old_id = dev->id; - unsigned char model[2][41], serial[2][21]; - u64 new_n_sectors; - if (dev->class != new_class) { - printk(KERN_INFO - "ata%u: dev %u class mismatch %d != %d\n", - ap->id, dev->devno, dev->class, new_class); - return 0; - } +void ata_bus_reset(struct ata_port *ap) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; + u8 err; + unsigned int dev0, dev1 = 0, rc = 0, devmask = 0; - ata_id_c_string(old_id, model[0], ATA_ID_PROD_OFS, sizeof(model[0])); - ata_id_c_string(new_id, model[1], ATA_ID_PROD_OFS, sizeof(model[1])); - ata_id_c_string(old_id, serial[0], ATA_ID_SERNO_OFS, sizeof(serial[0])); - ata_id_c_string(new_id, serial[1], ATA_ID_SERNO_OFS, sizeof(serial[1])); - new_n_sectors = ata_id_n_sectors(new_id); + DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); - if (strcmp(model[0], model[1])) { - printk(KERN_INFO - "ata%u: dev %u model number mismatch '%s' != '%s'\n", - ap->id, dev->devno, model[0], model[1]); - return 0; + /* determine if device 0/1 are present */ + if (ap->flags & ATA_FLAG_SATA_RESET) + dev0 = 1; + else { + dev0 = ata_devchk(ap, 0); + if (slave_possible) + dev1 = ata_devchk(ap, 1); } - if (strcmp(serial[0], serial[1])) { - printk(KERN_INFO - "ata%u: dev %u serial number mismatch '%s' != '%s'\n", - ap->id, dev->devno, serial[0], serial[1]); - return 0; - } + if (dev0) + devmask |= (1 << 0); + if (dev1) + devmask |= (1 << 1); - if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) { - printk(KERN_INFO - "ata%u: dev %u n_sectors mismatch %llu != %llu\n", - ap->id, dev->devno, (unsigned long long)dev->n_sectors, - (unsigned long long)new_n_sectors); - return 0; + /* select device 0 again */ + ap->ops->dev_select(ap, 0); + + /* issue bus reset */ + if (ap->flags & ATA_FLAG_SRST) + rc = ata_bus_softreset(ap, devmask); + else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) { + /* set up device control */ + if (ap->flags & ATA_FLAG_MMIO) + writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); + else + outb(ap->ctl, ioaddr->ctl_addr); + rc = ata_bus_edd(ap); } - return 1; -} + if (rc) + goto err_out; -/** - * ata_dev_revalidate - Revalidate ATA device - * @ap: port on which the device to revalidate resides - * @dev: device to revalidate - * @post_reset: is this revalidation after reset? - * - * Re-read IDENTIFY page and make sure @dev is still attached to - * the port. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, negative errno otherwise - */ -int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev, - int post_reset) -{ - unsigned int class; - u16 *id; - int rc; + /* + * determine by signature whether we have ATA or ATAPI devices + */ + err = ata_dev_try_classify(ap, 0); + if ((slave_possible) && (err != 0x81)) + ata_dev_try_classify(ap, 1); - if (!ata_dev_present(dev)) - return -ENODEV; + /* re-enable interrupts */ + if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ + ata_irq_on(ap); - class = dev->class; - id = NULL; + /* is double-select really necessary? */ + if (ap->device[1].class != ATA_DEV_NONE) + ap->ops->dev_select(ap, 1); + if (ap->device[0].class != ATA_DEV_NONE) + ap->ops->dev_select(ap, 0); - /* allocate & read ID data */ - rc = ata_dev_read_id(ap, dev, &class, post_reset, &id); - if (rc) - goto fail; + /* if no devices were detected, disable this port */ + if ((ap->device[0].class == ATA_DEV_NONE) && + (ap->device[1].class == ATA_DEV_NONE)) + goto err_out; - /* is the device still there? */ - if (!ata_dev_same_device(ap, dev, class, id)) { - rc = -ENODEV; - goto fail; + if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) { + /* set up device control for ATA_FLAG_SATA_RESET */ + if (ap->flags & ATA_FLAG_MMIO) + writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); + else + outb(ap->ctl, ioaddr->ctl_addr); } - kfree(dev->id); - dev->id = id; + DPRINTK("EXIT\n"); + return; - /* configure device according to the new ID */ - return ata_dev_configure(ap, dev, 0); +err_out: + printk(KERN_ERR "ata%u: disabling port\n", ap->id); + ap->ops->port_disable(ap); - fail: - printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n", - ap->id, dev->devno, rc); - kfree(id); - return rc; + DPRINTK("EXIT\n"); +} + +static void ata_pr_blacklisted(const struct ata_port *ap, + const struct ata_device *dev) +{ + printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n", + ap->id, dev->devno); } static const char * const ata_dma_blacklist [] = { - "WDC AC11000H", NULL, - "WDC AC22100H", NULL, - "WDC AC32500H", NULL, - "WDC AC33100H", NULL, - "WDC AC31600H", NULL, - "WDC AC32100H", "24.09P07", - "WDC AC23200L", "21.10N21", - "Compaq CRD-8241B", NULL, - "CRD-8400B", NULL, - "CRD-8480B", NULL, - "CRD-8482B", NULL, - "CRD-84", NULL, - "SanDisk SDP3B", NULL, - "SanDisk SDP3B-64", NULL, - "SANYO CD-ROM CRD", NULL, - "HITACHI CDR-8", NULL, - "HITACHI CDR-8335", NULL, - "HITACHI CDR-8435", NULL, - "Toshiba CD-ROM XM-6202B", NULL, - "TOSHIBA CD-ROM XM-1702BC", NULL, - "CD-532E-A", NULL, - "E-IDE CD-ROM CR-840", NULL, - "CD-ROM Drive/F5A", NULL, - "WPI CDD-820", NULL, - "SAMSUNG CD-ROM SC-148C", NULL, - "SAMSUNG CD-ROM SC", NULL, - "SanDisk SDP3B-64", NULL, - "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL, - "_NEC DV5800A", NULL, - "SAMSUNG CD-ROM SN-124", "N001" + "WDC AC11000H", + "WDC AC22100H", + "WDC AC32500H", + "WDC AC33100H", + "WDC AC31600H", + "WDC AC32100H", + "WDC AC23200L", + "Compaq CRD-8241B", + "CRD-8400B", + "CRD-8480B", + "CRD-8482B", + "CRD-84", + "SanDisk SDP3B", + "SanDisk SDP3B-64", + "SANYO CD-ROM CRD", + "HITACHI CDR-8", + "HITACHI CDR-8335", + "HITACHI CDR-8435", + "Toshiba CD-ROM XM-6202B", + "TOSHIBA CD-ROM XM-1702BC", + "CD-532E-A", + "E-IDE CD-ROM CR-840", + "CD-ROM Drive/F5A", + "WPI CDD-820", + "SAMSUNG CD-ROM SC-148C", + "SAMSUNG CD-ROM SC", + "SanDisk SDP3B-64", + "ATAPI CD-ROM DRIVE 40X MAXIMUM", + "_NEC DV5800A", }; -static int ata_strim(char *s, size_t len) +static int ata_dma_blacklisted(const struct ata_device *dev) { - len = strnlen(s, len); + unsigned char model_num[40]; + char *s; + unsigned int len; + int i; + + ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, + sizeof(model_num)); + s = &model_num[0]; + len = strnlen(s, sizeof(model_num)); /* ATAPI specifies that empty space is blank-filled; remove blanks */ while ((len > 0) && (s[len - 1] == ' ')) { len--; s[len] = 0; } - return len; + + for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++) + if (!strncmp(ata_dma_blacklist[i], s, len)) + return 1; + + return 0; } -static int ata_dma_blacklisted(const struct ata_device *dev) +static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift) { - unsigned char model_num[40]; - unsigned char model_rev[16]; - unsigned int nlen, rlen; - int i; + const struct ata_device *master, *slave; + unsigned int mask; - ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, - sizeof(model_num)); - ata_id_string(dev->id, model_rev, ATA_ID_FW_REV_OFS, - sizeof(model_rev)); - nlen = ata_strim(model_num, sizeof(model_num)); - rlen = ata_strim(model_rev, sizeof(model_rev)); - - for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) { - if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) { - if (ata_dma_blacklist[i+1] == NULL) - return 1; - if (!strncmp(ata_dma_blacklist[i], model_rev, rlen)) - return 1; + master = &ap->device[0]; + slave = &ap->device[1]; + + assert (ata_dev_present(master) || ata_dev_present(slave)); + + if (shift == ATA_SHIFT_UDMA) { + mask = ap->udma_mask; + if (ata_dev_present(master)) { + mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); + if (ata_dma_blacklisted(master)) { + mask = 0; + ata_pr_blacklisted(ap, master); + } + } + if (ata_dev_present(slave)) { + mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff); + if (ata_dma_blacklisted(slave)) { + mask = 0; + ata_pr_blacklisted(ap, slave); + } } } - return 0; + else if (shift == ATA_SHIFT_MWDMA) { + mask = ap->mwdma_mask; + if (ata_dev_present(master)) { + mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07); + if (ata_dma_blacklisted(master)) { + mask = 0; + ata_pr_blacklisted(ap, master); + } + } + if (ata_dev_present(slave)) { + mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07); + if (ata_dma_blacklisted(slave)) { + mask = 0; + ata_pr_blacklisted(ap, slave); + } + } + } + else if (shift == ATA_SHIFT_PIO) { + mask = ap->pio_mask; + if (ata_dev_present(master)) { + /* spec doesn't return explicit support for + * PIO0-2, so we fake it + */ + u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03; + tmp_mode <<= 3; + tmp_mode |= 0x7; + mask &= tmp_mode; + } + if (ata_dev_present(slave)) { + /* spec doesn't return explicit support for + * PIO0-2, so we fake it + */ + u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03; + tmp_mode <<= 3; + tmp_mode |= 0x7; + mask &= tmp_mode; + } + } + else { + mask = 0xffffffff; /* shut up compiler warning */ + BUG(); + } + + return mask; +} + +/* find greatest bit */ +static int fgb(u32 bitmap) +{ + unsigned int i; + int x = -1; + + for (i = 0; i < 32; i++) + if (bitmap & (1 << i)) + x = i; + + return x; } /** - * ata_dev_xfermask - Compute supported xfermask of the given device - * @ap: Port on which the device to compute xfermask for resides - * @dev: Device to compute xfermask for + * ata_choose_xfer_mode - attempt to find best transfer mode + * @ap: Port for which an xfer mode will be selected + * @xfer_mode_out: (output) SET FEATURES - XFER MODE code + * @xfer_shift_out: (output) bit shift that selects this mode * - * Compute supported xfermask of @dev and store it in - * dev->*_mask. This function is responsible for applying all - * known limits including host controller limits, device - * blacklist, etc... - * - * FIXME: The current implementation limits all transfer modes to - * the fastest of the lowested device on the port. This is not - * required on most controllers. + * Based on host and device capabilities, determine the + * maximum transfer mode that is amenable to all. * * LOCKING: - * None. + * PCI/etc. bus probe sem. + * + * RETURNS: + * Zero on success, negative on error. */ -static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) -{ - struct ata_host_set *hs = ap->host_set; - unsigned long xfer_mask; - int i; - xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, - ap->udma_mask); - - /* FIXME: Use port-wide xfermask for now */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *d = &ap->device[i]; - if (!ata_dev_present(d)) - continue; - xfer_mask &= ata_pack_xfermask(d->pio_mask, d->mwdma_mask, - d->udma_mask); - xfer_mask &= ata_id_xfermask(d->id); - if (ata_dma_blacklisted(d)) - xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); - /* Apply cable rule here. Don't apply it early because when - we handle hot plug the cable type can itself change */ - if (ap->cbl == ATA_CBL_PATA40) - xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); - } +static int ata_choose_xfer_mode(const struct ata_port *ap, + u8 *xfer_mode_out, + unsigned int *xfer_shift_out) +{ + unsigned int mask, shift; + int x, i; - if (ata_dma_blacklisted(dev)) - printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " - "disabling DMA\n", ap->id, dev->devno); + for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) { + shift = xfer_mode_classes[i].shift; + mask = ata_get_mode_mask(ap, shift); - if (hs->flags & ATA_HOST_SIMPLEX) { - if (hs->simplex_claimed) - xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); + x = fgb(mask); + if (x >= 0) { + *xfer_mode_out = xfer_mode_classes[i].base + x; + *xfer_shift_out = shift; + return 0; + } } - if (ap->ops->mode_filter) - xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask); - ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, - &dev->udma_mask); + return -1; } /** @@ -2711,16 +2394,11 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) * * LOCKING: * PCI/etc. bus probe sem. - * - * RETURNS: - * 0 on success, AC_ERR_* mask otherwise. */ -static unsigned int ata_dev_set_xfermode(struct ata_port *ap, - struct ata_device *dev) +static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) { struct ata_taskfile tf; - unsigned int err_mask; /* set up set-features taskfile */ DPRINTK("set features - xfer mode\n"); @@ -2732,37 +2410,73 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap, tf.protocol = ATA_PROT_NODATA; tf.nsect = dev->xfer_mode; - err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); + if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) { + printk(KERN_ERR "ata%u: failed to set xfermode, disabled\n", + ap->id); + ata_port_disable(ap); + } + + DPRINTK("EXIT\n"); +} + +/** + * ata_dev_reread_id - Reread the device identify device info + * @ap: port where the device is + * @dev: device to reread the identify device info + * + * LOCKING: + */ + +static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev) +{ + struct ata_taskfile tf; + + ata_tf_init(ap, &tf, dev->devno); + + if (dev->class == ATA_DEV_ATA) { + tf.command = ATA_CMD_ID_ATA; + DPRINTK("do ATA identify\n"); + } else { + tf.command = ATA_CMD_ID_ATAPI; + DPRINTK("do ATAPI identify\n"); + } + + tf.flags |= ATA_TFLAG_DEVICE; + tf.protocol = ATA_PROT_PIO; + + if (ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, + dev->id, sizeof(dev->id))) + goto err_out; + + swap_buf_le16(dev->id, ATA_ID_WORDS); + + ata_dump_id(dev); + + DPRINTK("EXIT\n"); - DPRINTK("EXIT, err_mask=%x\n", err_mask); - return err_mask; + return; +err_out: + printk(KERN_ERR "ata%u: failed to reread ID, disabled\n", ap->id); + ata_port_disable(ap); } /** * ata_dev_init_params - Issue INIT DEV PARAMS command * @ap: Port associated with device @dev * @dev: Device to which command will be sent - * @heads: Number of heads (taskfile parameter) - * @sectors: Number of sectors (taskfile parameter) * * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, AC_ERR_* mask otherwise. */ -static unsigned int ata_dev_init_params(struct ata_port *ap, - struct ata_device *dev, - u16 heads, - u16 sectors) +static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) { struct ata_taskfile tf; - unsigned int err_mask; + u16 sectors = dev->id[6]; + u16 heads = dev->id[3]; /* Number of sectors per track 1-255. Number of heads 1-16 */ if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) - return AC_ERR_INVALID; + return; /* set up init dev params taskfile */ DPRINTK("init dev params \n"); @@ -2774,10 +2488,13 @@ static unsigned int ata_dev_init_params(struct ata_port *ap, tf.nsect = sectors; tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ - err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); + if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) { + printk(KERN_ERR "ata%u: failed to init parameters, disabled\n", + ap->id); + ata_port_disable(ap); + } - DPRINTK("EXIT, err_mask=%x\n", err_mask); - return err_mask; + DPRINTK("EXIT\n"); } /** @@ -2797,11 +2514,11 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) int dir = qc->dma_dir; void *pad_buf = NULL; - WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); - WARN_ON(sg == NULL); + assert(qc->flags & ATA_QCFLAG_DMAMAP); + assert(sg != NULL); if (qc->flags & ATA_QCFLAG_SINGLE) - WARN_ON(qc->n_elem > 1); + assert(qc->n_elem <= 1); VPRINTK("unmapping %u sg elements\n", qc->n_elem); @@ -2814,7 +2531,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) if (qc->flags & ATA_QCFLAG_SG) { if (qc->n_elem) - dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); + dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir); /* restore last sg */ sg[qc->orig_n_elem - 1].length += qc->pad_len; if (pad_buf) { @@ -2825,7 +2542,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) } } else { if (qc->n_elem) - dma_unmap_single(ap->dev, + dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), dir); /* restore sg */ @@ -2856,8 +2573,8 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) struct scatterlist *sg; unsigned int idx; - WARN_ON(qc->__sg == NULL); - WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); + assert(qc->__sg != NULL); + assert(qc->n_elem > 0 || qc->pad_len > 0); idx = 0; ata_for_each_sg(sg, qc) { @@ -2931,8 +2648,6 @@ void ata_qc_prep(struct ata_queued_cmd *qc) ata_fill_sg(qc); } -void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } - /** * ata_sg_init_one - Associate command with memory buffer * @qc: Command to be associated @@ -3012,7 +2727,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); struct scatterlist *psg = &qc->pad_sgent; - WARN_ON(qc->dev->class != ATA_DEV_ATAPI); + assert(qc->dev->class == ATA_DEV_ATAPI); memset(pad_buf, 0, ATA_DMA_PAD_SZ); @@ -3036,7 +2751,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) goto skip_map; } - dma_address = dma_map_single(ap->dev, qc->buf_virt, + dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt, sg->length, dir); if (dma_mapping_error(dma_address)) { /* restore sg */ @@ -3076,7 +2791,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) int n_elem, pre_n_elem, dir, trim_sg = 0; VPRINTK("ENTER, ata%u\n", ap->id); - WARN_ON(!(qc->flags & ATA_QCFLAG_SG)); + assert(qc->flags & ATA_QCFLAG_SG); /* we must lengthen transfers to end on a 32-bit boundary */ qc->pad_len = lsg->length & 3; @@ -3085,7 +2800,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) struct scatterlist *psg = &qc->pad_sgent; unsigned int offset; - WARN_ON(qc->dev->class != ATA_DEV_ATAPI); + assert(qc->dev->class == ATA_DEV_ATAPI); memset(pad_buf, 0, ATA_DMA_PAD_SZ); @@ -3124,7 +2839,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) } dir = qc->dma_dir; - n_elem = dma_map_sg(ap->dev, sg, pre_n_elem, dir); + n_elem = dma_map_sg(ap->host_set->dev, sg, pre_n_elem, dir); if (n_elem < 1) { /* restore last sg */ lsg->length += qc->pad_len; @@ -3161,7 +2876,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc) } /** - * ata_pio_poll - poll using PIO, depending on current state + * ata_pio_poll - * @ap: the target ata_port * * LOCKING: @@ -3179,7 +2894,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap) unsigned int reg_state = HSM_ST_UNKNOWN; qc = ata_qc_from_tag(ap, ap->active_tag); - WARN_ON(qc == NULL); + assert(qc != NULL); switch (ap->hsm_task_state) { case HSM_ST: @@ -3200,7 +2915,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap) status = ata_chk_status(ap); if (status & ATA_BUSY) { if (time_after(jiffies, ap->pio_task_timeout)) { - qc->err_mask |= AC_ERR_TIMEOUT; + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_TMOUT; return 0; } @@ -3247,7 +2962,7 @@ static int ata_pio_complete (struct ata_port *ap) } qc = ata_qc_from_tag(ap, ap->active_tag); - WARN_ON(qc == NULL); + assert(qc != NULL); drv_stat = ata_wait_idle(ap); if (!ata_ok(drv_stat)) { @@ -3258,7 +2973,7 @@ static int ata_pio_complete (struct ata_port *ap) ap->hsm_task_state = HSM_ST_IDLE; - WARN_ON(qc->err_mask); + assert(qc->err_mask == 0); ata_poll_qc_complete(qc); /* another command may start at this point */ @@ -3268,7 +2983,7 @@ static int ata_pio_complete (struct ata_port *ap) /** - * swap_buf_le16 - swap halves of 16-bit words in place + * swap_buf_le16 - swap halves of 16-words in place * @buf: Buffer to swap * @buf_words: Number of 16-bit words in buffer. * @@ -3578,7 +3293,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) err_out: printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n", ap->id, dev->devno); - qc->err_mask |= AC_ERR_HSM; + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_ERR; } @@ -3615,7 +3330,7 @@ static void ata_pio_block(struct ata_port *ap) } qc = ata_qc_from_tag(ap, ap->active_tag); - WARN_ON(qc == NULL); + assert(qc != NULL); /* check error */ if (status & (ATA_ERR | ATA_DF)) { @@ -3636,15 +3351,13 @@ static void ata_pio_block(struct ata_port *ap) } else { /* handle BSY=0, DRQ=0 as error */ if ((status & ATA_DRQ) == 0) { - qc->err_mask |= AC_ERR_HSM; + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_ERR; return; } ata_pio_sector(qc); } - - ata_altstatus(ap); /* flush */ } static void ata_pio_error(struct ata_port *ap) @@ -3652,15 +3365,15 @@ static void ata_pio_error(struct ata_port *ap) struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); - WARN_ON(qc == NULL); + assert(qc != NULL); if (qc->tf.command != ATA_CMD_PACKET) printk(KERN_WARNING "ata%u: PIO error\n", ap->id); - /* make sure qc->err_mask is available to + /* make sure qc->err_mask is available to * know what's wrong and recover */ - WARN_ON(qc->err_mask == 0); + assert(qc->err_mask); ap->hsm_task_state = HSM_ST_IDLE; @@ -3669,116 +3382,41 @@ static void ata_pio_error(struct ata_port *ap) static void ata_pio_task(void *_data) { - struct ata_port *ap = _data; - unsigned long timeout; - int qc_completed; - -fsm_start: - timeout = 0; - qc_completed = 0; - - switch (ap->hsm_task_state) { - case HSM_ST_IDLE: - return; - - case HSM_ST: - ata_pio_block(ap); - break; - - case HSM_ST_LAST: - qc_completed = ata_pio_complete(ap); - break; - - case HSM_ST_POLL: - case HSM_ST_LAST_POLL: - timeout = ata_pio_poll(ap); - break; - - case HSM_ST_TMOUT: - case HSM_ST_ERR: - ata_pio_error(ap); - return; - } - - if (timeout) - ata_port_queue_task(ap, ata_pio_task, ap, timeout); - else if (!qc_completed) - goto fsm_start; -} - -/** - * atapi_packet_task - Write CDB bytes to hardware - * @_data: Port to which ATAPI device is attached. - * - * When device has indicated its readiness to accept - * a CDB, this function is called. Send the CDB. - * If DMA is to be performed, exit immediately. - * Otherwise, we are in polling mode, so poll - * status under operation succeeds or fails. - * - * LOCKING: - * Kernel thread context (may sleep) - */ - -static void atapi_packet_task(void *_data) -{ - struct ata_port *ap = _data; - struct ata_queued_cmd *qc; - u8 status; - - qc = ata_qc_from_tag(ap, ap->active_tag); - WARN_ON(qc == NULL); - WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); - - /* sleep-wait for BSY to clear */ - DPRINTK("busy wait\n"); - if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) { - qc->err_mask |= AC_ERR_TIMEOUT; - goto err_out; - } - - /* make sure DRQ is set */ - status = ata_chk_status(ap); - if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) { - qc->err_mask |= AC_ERR_HSM; - goto err_out; - } + struct ata_port *ap = _data; + unsigned long timeout; + int qc_completed; - /* send SCSI cdb */ - DPRINTK("send cdb\n"); - WARN_ON(qc->dev->cdb_len < 12); +fsm_start: + timeout = 0; + qc_completed = 0; - if (qc->tf.protocol == ATA_PROT_ATAPI_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { - unsigned long flags; + switch (ap->hsm_task_state) { + case HSM_ST_IDLE: + return; - /* Once we're done issuing command and kicking bmdma, - * irq handler takes over. To not lose irq, we need - * to clear NOINTR flag before sending cdb, but - * interrupt handler shouldn't be invoked before we're - * finished. Hence, the following locking. - */ - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->flags &= ~ATA_FLAG_NOINTR; - ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1); - ata_altstatus(ap); /* flush */ + case HSM_ST: + ata_pio_block(ap); + break; - if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) - ap->ops->bmdma_start(qc); /* initiate bmdma */ - spin_unlock_irqrestore(&ap->host_set->lock, flags); - } else { - ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1); - ata_altstatus(ap); /* flush */ + case HSM_ST_LAST: + qc_completed = ata_pio_complete(ap); + break; - /* PIO commands are handled by polling */ - ap->hsm_task_state = HSM_ST; - ata_port_queue_task(ap, ata_pio_task, ap, 0); - } + case HSM_ST_POLL: + case HSM_ST_LAST_POLL: + timeout = ata_pio_poll(ap); + break; - return; + case HSM_ST_TMOUT: + case HSM_ST_ERR: + ata_pio_error(ap); + return; + } -err_out: - ata_poll_qc_complete(qc); + if (timeout) + queue_delayed_work(ata_wq, &ap->pio_task, timeout); + else if (!qc_completed) + goto fsm_start; } /** @@ -3809,10 +3447,16 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) DPRINTK("ENTER\n"); - ap->hsm_task_state = HSM_ST_IDLE; - spin_lock_irqsave(&host_set->lock, flags); + /* hack alert! We cannot use the supplied completion + * function from inside the ->eh_strategy_handler() thread. + * libata is the only user of ->eh_strategy_handler() in + * any kernel, so the default scsi_done() assumes it is + * not being called from the SCSI EH. + */ + qc->scsidone = scsi_finish_command; + switch (qc->tf.protocol) { case ATA_PROT_DMA: @@ -3836,13 +3480,12 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) /* complete taskfile transaction */ qc->err_mask |= ac_err_mask(drv_stat); + ata_qc_complete(qc); break; } spin_unlock_irqrestore(&host_set->lock, flags); - ata_eh_qc_complete(qc); - DPRINTK("EXIT\n"); } @@ -3867,10 +3510,20 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) void ata_eng_timeout(struct ata_port *ap) { + struct ata_queued_cmd *qc; + DPRINTK("ENTER\n"); - ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag)); + qc = ata_qc_from_tag(ap, ap->active_tag); + if (qc) + ata_qc_timeout(qc); + else { + printk(KERN_ERR "ata%u: BUG: timeout without command\n", + ap->id); + goto out; + } +out: DPRINTK("EXIT\n"); } @@ -3926,6 +3579,21 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, return qc; } +static void __ata_qc_complete(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + unsigned int tag; + + qc->flags = 0; + tag = qc->tag; + if (likely(ata_tag_valid(tag))) { + if (tag == ap->active_tag) + ap->active_tag = ATA_TAG_POISON; + qc->tag = ATA_TAG_POISON; + clear_bit(tag, &ap->qactive); + } +} + /** * ata_qc_free - free unused ata_queued_cmd * @qc: Command to complete @@ -3938,25 +3606,29 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, */ void ata_qc_free(struct ata_queued_cmd *qc) { - struct ata_port *ap = qc->ap; - unsigned int tag; + assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ - WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ - - qc->flags = 0; - tag = qc->tag; - if (likely(ata_tag_valid(tag))) { - if (tag == ap->active_tag) - ap->active_tag = ATA_TAG_POISON; - qc->tag = ATA_TAG_POISON; - clear_bit(tag, &ap->qactive); - } + __ata_qc_complete(qc); } -void __ata_qc_complete(struct ata_queued_cmd *qc) +/** + * ata_qc_complete - Complete an active ATA command + * @qc: Command to complete + * @err_mask: ATA Status register contents + * + * Indicate to the mid and upper layers that an ATA + * command has completed, with either an ok or not-ok status. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +void ata_qc_complete(struct ata_queued_cmd *qc) { - WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ - WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); + int rc; + + assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ + assert(qc->flags & ATA_QCFLAG_ACTIVE); if (likely(qc->flags & ATA_QCFLAG_DMAMAP)) ata_sg_clean(qc); @@ -3968,7 +3640,17 @@ void __ata_qc_complete(struct ata_queued_cmd *qc) qc->flags &= ~ATA_QCFLAG_ACTIVE; /* call completion callback */ - qc->complete_fn(qc); + rc = qc->complete_fn(qc); + + /* if callback indicates not to complete command (non-zero), + * return immediately + */ + if (rc != 0) + return; + + __ata_qc_complete(qc); + + VPRINTK("EXIT\n"); } static inline int ata_should_dma_map(struct ata_queued_cmd *qc) @@ -3982,6 +3664,7 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc) case ATA_PROT_ATAPI: case ATA_PROT_PIO: + case ATA_PROT_PIO_MULT: if (ap->flags & ATA_FLAG_PIO_DMA) return 1; @@ -4005,21 +3688,22 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc) * * LOCKING: * spin_lock_irqsave(host_set lock) + * + * RETURNS: + * Zero on success, negative on error. */ -void ata_qc_issue(struct ata_queued_cmd *qc) + +int ata_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - qc->ap->active_tag = qc->tag; - qc->flags |= ATA_QCFLAG_ACTIVE; - if (ata_should_dma_map(qc)) { if (qc->flags & ATA_QCFLAG_SG) { if (ata_sg_setup(qc)) - goto sg_err; + goto err_out; } else if (qc->flags & ATA_QCFLAG_SINGLE) { if (ata_sg_setup_one(qc)) - goto sg_err; + goto err_out; } } else { qc->flags &= ~ATA_QCFLAG_DMAMAP; @@ -4027,85 +3711,314 @@ void ata_qc_issue(struct ata_queued_cmd *qc) ap->ops->qc_prep(qc); - qc->err_mask |= ap->ops->qc_issue(qc); - if (unlikely(qc->err_mask)) - goto err; - return; + qc->ap->active_tag = qc->tag; + qc->flags |= ATA_QCFLAG_ACTIVE; -sg_err: - qc->flags &= ~ATA_QCFLAG_DMAMAP; - qc->err_mask |= AC_ERR_SYSTEM; -err: - ata_qc_complete(qc); + return ap->ops->qc_issue(qc); + +err_out: + return -1; +} + + +/** + * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner + * @qc: command to issue to device + * + * Using various libata functions and hooks, this function + * starts an ATA command. ATA commands are grouped into + * classes called "protocols", and issuing each type of protocol + * is slightly different. + * + * May be used as the qc_issue() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + * + * RETURNS: + * Zero on success, negative on error. + */ + +int ata_qc_issue_prot(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + + ata_dev_select(ap, qc->dev->devno, 1, 0); + + switch (qc->tf.protocol) { + case ATA_PROT_NODATA: + ata_tf_to_host(ap, &qc->tf); + break; + + case ATA_PROT_DMA: + ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ + ap->ops->bmdma_setup(qc); /* set up bmdma */ + ap->ops->bmdma_start(qc); /* initiate bmdma */ + break; + + case ATA_PROT_PIO: /* load tf registers, initiate polling pio */ + ata_qc_set_polling(qc); + ata_tf_to_host(ap, &qc->tf); + ap->hsm_task_state = HSM_ST; + queue_work(ata_wq, &ap->pio_task); + break; + + case ATA_PROT_ATAPI: + ata_qc_set_polling(qc); + ata_tf_to_host(ap, &qc->tf); + queue_work(ata_wq, &ap->packet_task); + break; + + case ATA_PROT_ATAPI_NODATA: + ap->flags |= ATA_FLAG_NOINTR; + ata_tf_to_host(ap, &qc->tf); + queue_work(ata_wq, &ap->packet_task); + break; + + case ATA_PROT_ATAPI_DMA: + ap->flags |= ATA_FLAG_NOINTR; + ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ + ap->ops->bmdma_setup(qc); /* set up bmdma */ + queue_work(ata_wq, &ap->packet_task); + break; + + default: + WARN_ON(1); + return -1; + } + + return 0; +} + +/** + * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction + * @qc: Info associated with this ATA transaction. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +static void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); + u8 dmactl; + void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + + /* load PRD table addr. */ + mb(); /* make sure PRD table writes are visible to controller */ + writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS); + + /* specify data direction, triple-check start bit is clear */ + dmactl = readb(mmio + ATA_DMA_CMD); + dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); + if (!rw) + dmactl |= ATA_DMA_WR; + writeb(dmactl, mmio + ATA_DMA_CMD); + + /* issue r/w command */ + ap->ops->exec_command(ap, &qc->tf); +} + +/** + * ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction + * @qc: Info associated with this ATA transaction. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + u8 dmactl; + + /* start host DMA transaction */ + dmactl = readb(mmio + ATA_DMA_CMD); + writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD); + + /* Strictly, one may wish to issue a readb() here, to + * flush the mmio write. However, control also passes + * to the hardware at this point, and it will interrupt + * us when we are to resume control. So, in effect, + * we don't care when the mmio write flushes. + * Further, a read of the DMA status register _immediately_ + * following the write may not be what certain flaky hardware + * is expected, so I think it is best to not add a readb() + * without first all the MMIO ATA cards/mobos. + * Or maybe I'm just being paranoid. + */ +} + +/** + * ata_bmdma_setup_pio - Set up PCI IDE BMDMA transaction (PIO) + * @qc: Info associated with this ATA transaction. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +static void ata_bmdma_setup_pio (struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); + u8 dmactl; + + /* load PRD table addr. */ + outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS); + + /* specify data direction, triple-check start bit is clear */ + dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); + dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); + if (!rw) + dmactl |= ATA_DMA_WR; + outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); + + /* issue r/w command */ + ap->ops->exec_command(ap, &qc->tf); +} + +/** + * ata_bmdma_start_pio - Start a PCI IDE BMDMA transaction (PIO) + * @qc: Info associated with this ATA transaction. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +static void ata_bmdma_start_pio (struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + u8 dmactl; + + /* start host DMA transaction */ + dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); + outb(dmactl | ATA_DMA_START, + ap->ioaddr.bmdma_addr + ATA_DMA_CMD); +} + + +/** + * ata_bmdma_start - Start a PCI IDE BMDMA transaction + * @qc: Info associated with this ATA transaction. + * + * Writes the ATA_DMA_START flag to the DMA command register. + * + * May be used as the bmdma_start() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ +void ata_bmdma_start(struct ata_queued_cmd *qc) +{ + if (qc->ap->flags & ATA_FLAG_MMIO) + ata_bmdma_start_mmio(qc); + else + ata_bmdma_start_pio(qc); +} + + +/** + * ata_bmdma_setup - Set up PCI IDE BMDMA transaction + * @qc: Info associated with this ATA transaction. + * + * Writes address of PRD table to device's PRD Table Address + * register, sets the DMA control register, and calls + * ops->exec_command() to start the transfer. + * + * May be used as the bmdma_setup() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ +void ata_bmdma_setup(struct ata_queued_cmd *qc) +{ + if (qc->ap->flags & ATA_FLAG_MMIO) + ata_bmdma_setup_mmio(qc); + else + ata_bmdma_setup_pio(qc); } + /** - * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner - * @qc: command to issue to device + * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. + * @ap: Port associated with this ATA transaction. * - * Using various libata functions and hooks, this function - * starts an ATA command. ATA commands are grouped into - * classes called "protocols", and issuing each type of protocol - * is slightly different. + * Clear interrupt and error flags in DMA status register. * - * May be used as the qc_issue() entry in ata_port_operations. + * May be used as the irq_clear() entry in ata_port_operations. * * LOCKING: * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * Zero on success, AC_ERR_* mask on failure */ -unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) +void ata_bmdma_irq_clear(struct ata_port *ap) { - struct ata_port *ap = qc->ap; + if (ap->flags & ATA_FLAG_MMIO) { + void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; + writeb(readb(mmio), mmio); + } else { + unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; + outb(inb(addr), addr); + } - ata_dev_select(ap, qc->dev->devno, 1, 0); +} - switch (qc->tf.protocol) { - case ATA_PROT_NODATA: - ata_tf_to_host(ap, &qc->tf); - break; - case ATA_PROT_DMA: - ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ - ap->ops->bmdma_setup(qc); /* set up bmdma */ - ap->ops->bmdma_start(qc); /* initiate bmdma */ - break; +/** + * ata_bmdma_status - Read PCI IDE BMDMA status + * @ap: Port associated with this ATA transaction. + * + * Read and return BMDMA status register. + * + * May be used as the bmdma_status() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ - case ATA_PROT_PIO: /* load tf registers, initiate polling pio */ - ata_qc_set_polling(qc); - ata_tf_to_host(ap, &qc->tf); - ap->hsm_task_state = HSM_ST; - ata_port_queue_task(ap, ata_pio_task, ap, 0); - break; +u8 ata_bmdma_status(struct ata_port *ap) +{ + u8 host_stat; + if (ap->flags & ATA_FLAG_MMIO) { + void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + host_stat = readb(mmio + ATA_DMA_STATUS); + } else + host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); + return host_stat; +} - case ATA_PROT_ATAPI: - ata_qc_set_polling(qc); - ata_tf_to_host(ap, &qc->tf); - ata_port_queue_task(ap, atapi_packet_task, ap, 0); - break; - case ATA_PROT_ATAPI_NODATA: - ap->flags |= ATA_FLAG_NOINTR; - ata_tf_to_host(ap, &qc->tf); - ata_port_queue_task(ap, atapi_packet_task, ap, 0); - break; +/** + * ata_bmdma_stop - Stop PCI IDE BMDMA transfer + * @qc: Command we are ending DMA for + * + * Clears the ATA_DMA_START flag in the dma control register + * + * May be used as the bmdma_stop() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ - case ATA_PROT_ATAPI_DMA: - ap->flags |= ATA_FLAG_NOINTR; - ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ - ap->ops->bmdma_setup(qc); /* set up bmdma */ - ata_port_queue_task(ap, atapi_packet_task, ap, 0); - break; +void ata_bmdma_stop(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + if (ap->flags & ATA_FLAG_MMIO) { + void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - default: - WARN_ON(1); - return AC_ERR_SYSTEM; + /* clear start/stop bit */ + writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START, + mmio + ATA_DMA_CMD); + } else { + /* clear start/stop bit */ + outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START, + ap->ioaddr.bmdma_addr + ATA_DMA_CMD); } - return 0; + /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ + ata_altstatus(ap); /* dummy read */ } /** @@ -4180,9 +4093,9 @@ idle_irq: #ifdef ATA_IRQ_TRAP if ((ap->stats.idle_irq % 1000) == 0) { + handled = 1; ata_irq_ack(ap, 0); /* debug trap */ printk(KERN_WARNING "ata%d: irq trap\n", ap->id); - return 1; } #endif return 0; /* irq not handled */ @@ -4234,6 +4147,91 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) return IRQ_RETVAL(handled); } +/** + * atapi_packet_task - Write CDB bytes to hardware + * @_data: Port to which ATAPI device is attached. + * + * When device has indicated its readiness to accept + * a CDB, this function is called. Send the CDB. + * If DMA is to be performed, exit immediately. + * Otherwise, we are in polling mode, so poll + * status under operation succeeds or fails. + * + * LOCKING: + * Kernel thread context (may sleep) + */ + +static void atapi_packet_task(void *_data) +{ + struct ata_port *ap = _data; + struct ata_queued_cmd *qc; + u8 status; + + qc = ata_qc_from_tag(ap, ap->active_tag); + assert(qc != NULL); + assert(qc->flags & ATA_QCFLAG_ACTIVE); + + /* sleep-wait for BSY to clear */ + DPRINTK("busy wait\n"); + if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) { + qc->err_mask |= AC_ERR_ATA_BUS; + goto err_out; + } + + /* make sure DRQ is set */ + status = ata_chk_status(ap); + if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) { + qc->err_mask |= AC_ERR_ATA_BUS; + goto err_out; + } + + /* send SCSI cdb */ + DPRINTK("send cdb\n"); + assert(ap->cdb_len >= 12); + + if (qc->tf.protocol == ATA_PROT_ATAPI_DMA || + qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { + unsigned long flags; + + /* Once we're done issuing command and kicking bmdma, + * irq handler takes over. To not lose irq, we need + * to clear NOINTR flag before sending cdb, but + * interrupt handler shouldn't be invoked before we're + * finished. Hence, the following locking. + */ + spin_lock_irqsave(&ap->host_set->lock, flags); + ap->flags &= ~ATA_FLAG_NOINTR; + ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); + if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) + ap->ops->bmdma_start(qc); /* initiate bmdma */ + spin_unlock_irqrestore(&ap->host_set->lock, flags); + } else { + ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); + + /* PIO commands are handled by polling */ + ap->hsm_task_state = HSM_ST; + queue_work(ata_wq, &ap->pio_task); + } + + return; + +err_out: + ata_poll_qc_complete(qc); +} + + +/** + * ata_port_start - Set port up for dma. + * @ap: Port to initialize + * + * Called just after data structures for each port are + * initialized. Allocates space for PRD table. + * + * May be used as the port_start() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ /* * Execute a 'simple' command, that only consists of the opcode 'cmd' itself, @@ -4286,8 +4284,6 @@ static int ata_start_drive(struct ata_port *ap, struct ata_device *dev) /** * ata_device_resume - wakeup a previously suspended devices - * @ap: port the device is connected to - * @dev: the device to resume * * Kick the drive back into action, by sending it an idle immediate * command and making sure its transfer mode matches between drive @@ -4311,42 +4307,26 @@ int ata_device_resume(struct ata_port *ap, struct ata_device *dev) /** * ata_device_suspend - prepare a device for suspend - * @ap: port the device is connected to - * @dev: the device to suspend - * @state: target power management state * * Flush the cache on the drive, if appropriate, then issue a * standbynow command. + * */ -int ata_device_suspend(struct ata_port *ap, struct ata_device *dev, pm_message_t state) +int ata_device_suspend(struct ata_port *ap, struct ata_device *dev) { if (!ata_dev_present(dev)) return 0; if (dev->class == ATA_DEV_ATA) ata_flush_cache(ap, dev); - if (state.event != PM_EVENT_FREEZE) - ata_standby_drive(ap, dev); + ata_standby_drive(ap, dev); ap->flags |= ATA_FLAG_SUSPENDED; return 0; } -/** - * ata_port_start - Set port up for dma. - * @ap: Port to initialize - * - * Called just after data structures for each port are - * initialized. Allocates space for PRD table. - * - * May be used as the port_start() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ - int ata_port_start (struct ata_port *ap) { - struct device *dev = ap->dev; + struct device *dev = ap->host_set->dev; int rc; ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL); @@ -4379,7 +4359,7 @@ int ata_port_start (struct ata_port *ap) void ata_port_stop (struct ata_port *ap) { - struct device *dev = ap->dev; + struct device *dev = ap->host_set->dev; dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); ata_pad_free(ap, dev); @@ -4445,7 +4425,6 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, ap->host = host; ap->ctl = ATA_DEVCTL_OBS; ap->host_set = host_set; - ap->dev = ent->dev; ap->port_no = port_no; ap->hard_port_no = ent->legacy_mode ? ent->hard_port_no : port_no; @@ -4453,22 +4432,16 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, ap->mwdma_mask = ent->mwdma_mask; ap->udma_mask = ent->udma_mask; ap->flags |= ent->host_flags; - ap->flags |= ent->port_flags[port_no]; /* pata fix */ ap->ops = ent->port_ops; ap->cbl = ATA_CBL_NONE; ap->active_tag = ATA_TAG_POISON; ap->last_ctl = 0xFF; - INIT_WORK(&ap->port_task, NULL, NULL); - INIT_LIST_HEAD(&ap->eh_done_q); + INIT_WORK(&ap->packet_task, atapi_packet_task, ap); + INIT_WORK(&ap->pio_task, ata_pio_task, ap); - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - dev->devno = i; - dev->pio_mask = UINT_MAX; - dev->mwdma_mask = UINT_MAX; - dev->udma_mask = UINT_MAX; - } + for (i = 0; i < ATA_MAX_DEVICES; i++) + ap->device[i].devno = i; #ifdef ATA_IRQ_TRAP ap->stats.unhandled_irq = 1; @@ -4502,20 +4475,10 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, int rc; DPRINTK("ENTER\n"); - - if (!ent->port_ops->probe_reset && - !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { - printk(KERN_ERR "ata%u: no reset mechanism available\n", - port_no); - return NULL; - } - host = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); if (!host) return NULL; - host->transportt = &ata_scsi_transport_template; - ap = (struct ata_port *) &host->hostdata[0]; ata_host_init(ap, host, host_set, ent, port_no); @@ -4570,7 +4533,6 @@ int ata_device_add(const struct ata_probe_ent *ent) host_set->mmio_base = ent->mmio_base; host_set->private_data = ent->private_data; host_set->ops = ent->port_ops; - host_set->flags = ent->host_set_flags; /* register each port bound to this device */ for (i = 0; i < ent->n_ports; i++) { @@ -4618,9 +4580,9 @@ int ata_device_add(const struct ata_probe_ent *ent) ap = host_set->ports[i]; - DPRINTK("ata%u: bus probe begin\n", ap->id); + DPRINTK("ata%u: probe begin\n", ap->id); rc = ata_bus_probe(ap); - DPRINTK("ata%u: bus probe end\n", ap->id); + DPRINTK("ata%u: probe end\n", ap->id); if (rc) { /* FIXME: do something useful here? @@ -4644,7 +4606,7 @@ int ata_device_add(const struct ata_probe_ent *ent) } /* probes are done, now scan each port's disk(s) */ - DPRINTK("host probe begin\n"); + DPRINTK("probe begin\n"); for (i = 0; i < count; i++) { struct ata_port *ap = host_set->ports[i]; @@ -4671,7 +4633,7 @@ err_free_ret: * ata_host_set_remove - PCI layer callback for device removal * @host_set: ATA host set that was removed * - * Unregister all objects associated with this host set. Free those + * Unregister all objects associated with this host set. Free those * objects. * * LOCKING: @@ -4730,14 +4692,11 @@ void ata_host_set_remove(struct ata_host_set *host_set) int ata_scsi_release(struct Scsi_Host *host) { struct ata_port *ap = (struct ata_port *) &host->hostdata[0]; - int i; DPRINTK("ENTER\n"); ap->ops->port_disable(ap); ata_host_remove(ap, 0); - for (i = 0; i < ATA_MAX_DEVICES; i++) - kfree(ap->device[i].id); DPRINTK("EXIT\n"); return 1; @@ -4769,6 +4728,32 @@ void ata_std_ports(struct ata_ioports *ioaddr) ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD; } +static struct ata_probe_ent * +ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) +{ + struct ata_probe_ent *probe_ent; + + probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); + if (!probe_ent) { + printk(KERN_ERR DRV_NAME "(%s): out of memory\n", + kobject_name(&(dev->kobj))); + return NULL; + } + + INIT_LIST_HEAD(&probe_ent->node); + probe_ent->dev = dev; + + probe_ent->sht = port->sht; + probe_ent->host_flags = port->host_flags; + probe_ent->pio_mask = port->pio_mask; + probe_ent->mwdma_mask = port->mwdma_mask; + probe_ent->udma_mask = port->udma_mask; + probe_ent->port_ops = port->port_ops; + + return probe_ent; +} + + #ifdef CONFIG_PCI @@ -4779,6 +4764,256 @@ void ata_pci_host_stop (struct ata_host_set *host_set) pci_iounmap(pdev, host_set->mmio_base); } +/** + * ata_pci_init_native_mode - Initialize native-mode driver + * @pdev: pci device to be initialized + * @port: array[2] of pointers to port info structures. + * @ports: bitmap of ports present + * + * Utility function which allocates and initializes an + * ata_probe_ent structure for a standard dual-port + * PIO-based IDE controller. The returned ata_probe_ent + * structure can be passed to ata_device_add(). The returned + * ata_probe_ent structure should then be freed with kfree(). + * + * The caller need only pass the address of the primary port, the + * secondary will be deduced automatically. If the device has non + * standard secondary port mappings this function can be called twice, + * once for each interface. + */ + +struct ata_probe_ent * +ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports) +{ + struct ata_probe_ent *probe_ent = + ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); + int p = 0; + + if (!probe_ent) + return NULL; + + probe_ent->irq = pdev->irq; + probe_ent->irq_flags = SA_SHIRQ; + probe_ent->private_data = port[0]->private_data; + + if (ports & ATA_PORT_PRIMARY) { + probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); + probe_ent->port[p].altstatus_addr = + probe_ent->port[p].ctl_addr = + pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; + probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); + ata_std_ports(&probe_ent->port[p]); + p++; + } + + if (ports & ATA_PORT_SECONDARY) { + probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2); + probe_ent->port[p].altstatus_addr = + probe_ent->port[p].ctl_addr = + pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; + probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; + ata_std_ports(&probe_ent->port[p]); + p++; + } + + probe_ent->n_ports = p; + return probe_ent; +} + +static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num) +{ + struct ata_probe_ent *probe_ent; + + probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); + if (!probe_ent) + return NULL; + + probe_ent->legacy_mode = 1; + probe_ent->n_ports = 1; + probe_ent->hard_port_no = port_num; + probe_ent->private_data = port->private_data; + + switch(port_num) + { + case 0: + probe_ent->irq = 14; + probe_ent->port[0].cmd_addr = 0x1f0; + probe_ent->port[0].altstatus_addr = + probe_ent->port[0].ctl_addr = 0x3f6; + break; + case 1: + probe_ent->irq = 15; + probe_ent->port[0].cmd_addr = 0x170; + probe_ent->port[0].altstatus_addr = + probe_ent->port[0].ctl_addr = 0x376; + break; + } + probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num; + ata_std_ports(&probe_ent->port[0]); + return probe_ent; +} + +/** + * ata_pci_init_one - Initialize/register PCI IDE host controller + * @pdev: Controller to be initialized + * @port_info: Information from low-level host driver + * @n_ports: Number of ports attached to host controller + * + * This is a helper function which can be called from a driver's + * xxx_init_one() probe function if the hardware uses traditional + * IDE taskfile registers. + * + * This function calls pci_enable_device(), reserves its register + * regions, sets the dma mask, enables bus master mode, and calls + * ata_device_add() + * + * LOCKING: + * Inherited from PCI layer (may sleep). + * + * RETURNS: + * Zero on success, negative on errno-based value on error. + */ + +int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, + unsigned int n_ports) +{ + struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL; + struct ata_port_info *port[2]; + u8 tmp8, mask; + unsigned int legacy_mode = 0; + int disable_dev_on_err = 1; + int rc; + + DPRINTK("ENTER\n"); + + port[0] = port_info[0]; + if (n_ports > 1) + port[1] = port_info[1]; + else + port[1] = port[0]; + + if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0 + && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { + /* TODO: What if one channel is in native mode ... */ + pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); + mask = (1 << 2) | (1 << 0); + if ((tmp8 & mask) != mask) + legacy_mode = (1 << 3); + } + + /* FIXME... */ + if ((!legacy_mode) && (n_ports > 2)) { + printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n"); + n_ports = 2; + /* For now */ + } + + /* FIXME: Really for ATA it isn't safe because the device may be + multi-purpose and we want to leave it alone if it was already + enabled. Secondly for shared use as Arjan says we want refcounting + + Checking dev->is_enabled is insufficient as this is not set at + boot for the primary video which is BIOS enabled + */ + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) { + disable_dev_on_err = 0; + goto err_out; + } + + /* FIXME: Should use platform specific mappers for legacy port ranges */ + if (legacy_mode) { + if (!request_region(0x1f0, 8, "libata")) { + struct resource *conflict, res; + res.start = 0x1f0; + res.end = 0x1f0 + 8 - 1; + conflict = ____request_resource(&ioport_resource, &res); + if (!strcmp(conflict->name, "libata")) + legacy_mode |= (1 << 0); + else { + disable_dev_on_err = 0; + printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); + } + } else + legacy_mode |= (1 << 0); + + if (!request_region(0x170, 8, "libata")) { + struct resource *conflict, res; + res.start = 0x170; + res.end = 0x170 + 8 - 1; + conflict = ____request_resource(&ioport_resource, &res); + if (!strcmp(conflict->name, "libata")) + legacy_mode |= (1 << 1); + else { + disable_dev_on_err = 0; + printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); + } + } else + legacy_mode |= (1 << 1); + } + + /* we have legacy mode, but all ports are unavailable */ + if (legacy_mode == (1 << 3)) { + rc = -EBUSY; + goto err_out_regions; + } + + rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + goto err_out_regions; + rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + goto err_out_regions; + + if (legacy_mode) { + if (legacy_mode & (1 << 0)) + probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0); + if (legacy_mode & (1 << 1)) + probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1); + } else { + if (n_ports == 2) + probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); + else + probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); + } + if (!probe_ent && !probe_ent2) { + rc = -ENOMEM; + goto err_out_regions; + } + + pci_set_master(pdev); + + /* FIXME: check ata_device_add return */ + if (legacy_mode) { + if (legacy_mode & (1 << 0)) + ata_device_add(probe_ent); + if (legacy_mode & (1 << 1)) + ata_device_add(probe_ent2); + } else + ata_device_add(probe_ent); + + kfree(probe_ent); + kfree(probe_ent2); + + return 0; + +err_out_regions: + if (legacy_mode & (1 << 0)) + release_region(0x1f0, 8); + if (legacy_mode & (1 << 1)) + release_region(0x170, 8); + pci_release_regions(pdev); +err_out: + if (disable_dev_on_err) + pci_disable_device(pdev); + return rc; +} + /** * ata_pci_remove_one - PCI layer callback for device removal * @pdev: PCI device that was removed @@ -4909,7 +5144,7 @@ EXPORT_SYMBOL_GPL(ata_device_add); EXPORT_SYMBOL_GPL(ata_host_set_remove); EXPORT_SYMBOL_GPL(ata_sg_init); EXPORT_SYMBOL_GPL(ata_sg_init_one); -EXPORT_SYMBOL_GPL(__ata_qc_complete); +EXPORT_SYMBOL_GPL(ata_qc_complete); EXPORT_SYMBOL_GPL(ata_qc_issue_prot); EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_tf_load); @@ -4926,7 +5161,6 @@ EXPORT_SYMBOL_GPL(ata_port_stop); EXPORT_SYMBOL_GPL(ata_host_stop); EXPORT_SYMBOL_GPL(ata_interrupt); EXPORT_SYMBOL_GPL(ata_qc_prep); -EXPORT_SYMBOL_GPL(ata_noop_qc_prep); EXPORT_SYMBOL_GPL(ata_bmdma_setup); EXPORT_SYMBOL_GPL(ata_bmdma_start); EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); @@ -4936,29 +5170,18 @@ EXPORT_SYMBOL_GPL(ata_port_probe); EXPORT_SYMBOL_GPL(sata_phy_reset); EXPORT_SYMBOL_GPL(__sata_phy_reset); EXPORT_SYMBOL_GPL(ata_bus_reset); -EXPORT_SYMBOL_GPL(ata_std_probeinit); -EXPORT_SYMBOL_GPL(ata_std_softreset); -EXPORT_SYMBOL_GPL(sata_std_hardreset); -EXPORT_SYMBOL_GPL(ata_std_postreset); -EXPORT_SYMBOL_GPL(ata_std_probe_reset); -EXPORT_SYMBOL_GPL(ata_drive_probe_reset); -EXPORT_SYMBOL_GPL(ata_dev_revalidate); -EXPORT_SYMBOL_GPL(ata_dev_classify); -EXPORT_SYMBOL_GPL(ata_dev_pair); EXPORT_SYMBOL_GPL(ata_port_disable); EXPORT_SYMBOL_GPL(ata_ratelimit); -EXPORT_SYMBOL_GPL(ata_busy_sleep); -EXPORT_SYMBOL_GPL(ata_port_queue_task); EXPORT_SYMBOL_GPL(ata_scsi_ioctl); EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); +EXPORT_SYMBOL_GPL(ata_scsi_error); EXPORT_SYMBOL_GPL(ata_scsi_slave_config); EXPORT_SYMBOL_GPL(ata_scsi_release); EXPORT_SYMBOL_GPL(ata_host_intr); -EXPORT_SYMBOL_GPL(ata_id_string); -EXPORT_SYMBOL_GPL(ata_id_c_string); +EXPORT_SYMBOL_GPL(ata_dev_classify); +EXPORT_SYMBOL_GPL(ata_dev_id_string); +EXPORT_SYMBOL_GPL(ata_dev_config); EXPORT_SYMBOL_GPL(ata_scsi_simulate); -EXPORT_SYMBOL_GPL(ata_eh_qc_complete); -EXPORT_SYMBOL_GPL(ata_eh_qc_retry); EXPORT_SYMBOL_GPL(ata_pio_need_iordy); EXPORT_SYMBOL_GPL(ata_timing_compute); @@ -4972,8 +5195,6 @@ EXPORT_SYMBOL_GPL(ata_pci_init_one); EXPORT_SYMBOL_GPL(ata_pci_remove_one); EXPORT_SYMBOL_GPL(ata_pci_device_suspend); EXPORT_SYMBOL_GPL(ata_pci_device_resume); -EXPORT_SYMBOL_GPL(ata_pci_default_filter); -EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); #endif /* CONFIG_PCI */ EXPORT_SYMBOL_GPL(ata_device_suspend); diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index b405acf11..59503c9cc 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -53,8 +52,6 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd); static struct ata_device * ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); -static void ata_scsi_error(struct Scsi_Host *host); -enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); #define RW_RECOVERY_MPAGE 0x1 #define RW_RECOVERY_MPAGE_LEN 12 @@ -95,15 +92,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { 0, 30 /* extended self test time, see 05-359r1 */ }; -/* - * libata transport template. libata doesn't do real transport stuff. - * It just needs the eh_timed_out hook. - */ -struct scsi_transport_template ata_scsi_transport_template = { - .eh_strategy_handler = ata_scsi_error, - .eh_timed_out = ata_scsi_timed_out, -}; - static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) @@ -163,7 +151,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) struct scsi_sense_hdr sshdr; enum dma_data_direction data_dir; - if (arg == NULL) + if (NULL == (void *)arg) return -EINVAL; if (copy_from_user(args, arg, sizeof(args))) @@ -213,7 +201,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) /* Need code to retrieve data from check condition? */ if ((argbuf) - && copy_to_user(arg + sizeof(args), argbuf, argsize)) + && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize)) rc = -EFAULT; error: if (argbuf) @@ -240,7 +228,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) u8 args[7]; struct scsi_sense_hdr sshdr; - if (arg == NULL) + if (NULL == (void *)arg) return -EINVAL; if (copy_from_user(args, arg, sizeof(args))) @@ -258,7 +246,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) scsi_cmd[14] = args[0]; /* Good values for timeout and retries? Values below - from scsi_ioctl_send_command() for default case... */ + from scsi_ioctl_send_command() for default case... */ if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, (10*HZ), 5)) rc = -EIO; @@ -269,8 +257,20 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) { + struct ata_port *ap; + struct ata_device *dev; int val = -EINVAL, rc = -EINVAL; + ap = (struct ata_port *) &scsidev->host->hostdata[0]; + if (!ap) + goto out; + + dev = ata_scsi_find_dev(ap, scsidev); + if (!dev) { + rc = -ENODEV; + goto out; + } + switch (cmd) { case ATA_IOC_GET_IO32: val = 0; @@ -299,6 +299,7 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) break; } +out: return rc; } @@ -403,12 +404,12 @@ int ata_scsi_device_resume(struct scsi_device *sdev) return ata_device_resume(ap, dev); } -int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) +int ata_scsi_device_suspend(struct scsi_device *sdev) { struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; struct ata_device *dev = &ap->device[sdev->id]; - return ata_device_suspend(ap, dev, state); + return ata_device_suspend(ap, dev); } /** @@ -427,7 +428,7 @@ int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) * LOCKING: * spin_lock_irqsave(host_set lock) */ -void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, +void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, u8 *ascq) { int i; @@ -484,7 +485,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, /* Look for drv_err */ for (i = 0; sense_table[i][0] != 0xFF; i++) { /* Look for best matches first */ - if ((sense_table[i][0] & drv_err) == + if ((sense_table[i][0] & drv_err) == sense_table[i][0]) { *sk = sense_table[i][1]; *asc = sense_table[i][2]; @@ -507,16 +508,21 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, } } /* No error? Undecoded? */ - printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", + printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", id, drv_stat); - /* We need a sensible error return here, which is tricky, and one - that won't cause people to do things like return a disk wrongly */ - *sk = ABORTED_COMMAND; - *asc = 0x00; - *ascq = 0x00; + /* For our last chance pick, use medium read error because + * it's much more common than an ATA drive telling you a write + * has failed. + */ + *sk = MEDIUM_ERROR; + *asc = 0x11; /* "unrecovered read error" */ + *ascq = 0x04; /* "auto-reallocation failed" */ translate_done: + printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to " + "SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", id, drv_stat, drv_err, + *sk, *asc, *ascq); return; } @@ -547,7 +553,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) /* * Read the controller registers. */ - WARN_ON(qc->ap->ops->tf_read == NULL); + assert(NULL != qc->ap->ops->tf_read); qc->ap->ops->tf_read(qc->ap, tf); /* @@ -622,7 +628,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) /* * Read the controller registers. */ - WARN_ON(qc->ap->ops->tf_read == NULL); + assert(NULL != qc->ap->ops->tf_read); qc->ap->ops->tf_read(qc->ap, tf); /* @@ -656,41 +662,6 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) } } -static void ata_scsi_sdev_config(struct scsi_device *sdev) -{ - sdev->use_10_for_rw = 1; - sdev->use_10_for_ms = 1; -} - -static void ata_scsi_dev_config(struct scsi_device *sdev, - struct ata_device *dev) -{ - unsigned int max_sectors; - - /* TODO: 2048 is an arbitrary number, not the - * hardware maximum. This should be increased to - * 65534 when Jens Axboe's patch for dynamically - * determining max_sectors is merged. - */ - max_sectors = ATA_MAX_SECTORS; - if (dev->flags & ATA_DFLAG_LBA48) - max_sectors = 2048; - if (dev->max_sectors) - max_sectors = dev->max_sectors; - - blk_queue_max_sectors(sdev->request_queue, max_sectors); - - /* - * SATA DMA transfers must be multiples of 4 byte, so - * we need to pad ATAPI transfers using an extra sg. - * Decrement max hw segments accordingly. - */ - if (dev->class == ATA_DEV_ATAPI) { - request_queue_t *q = sdev->request_queue; - blk_queue_max_hw_segments(q, q->max_hw_segments - 1); - } -} - /** * ata_scsi_slave_config - Set SCSI device attributes * @sdev: SCSI device to examine @@ -705,7 +676,8 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, int ata_scsi_slave_config(struct scsi_device *sdev) { - ata_scsi_sdev_config(sdev); + sdev->use_10_for_rw = 1; + sdev->use_10_for_ms = 1; blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD); @@ -716,51 +688,32 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ap = (struct ata_port *) &sdev->host->hostdata[0]; dev = &ap->device[sdev->id]; - ata_scsi_dev_config(sdev, dev); - } - - return 0; /* scsi layer doesn't check return value, sigh */ -} - -/** - * ata_scsi_timed_out - SCSI layer time out callback - * @cmd: timed out SCSI command - * - * Handles SCSI layer timeout. We race with normal completion of - * the qc for @cmd. If the qc is already gone, we lose and let - * the scsi command finish (EH_HANDLED). Otherwise, the qc has - * timed out and EH should be invoked. Prevent ata_qc_complete() - * from finishing it by setting EH_SCHEDULED and return - * EH_NOT_HANDLED. - * - * LOCKING: - * Called from timer context - * - * RETURNS: - * EH_HANDLED or EH_NOT_HANDLED - */ -enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) -{ - struct Scsi_Host *host = cmd->device->host; - struct ata_port *ap = (struct ata_port *) &host->hostdata[0]; - unsigned long flags; - struct ata_queued_cmd *qc; - enum scsi_eh_timer_return ret = EH_HANDLED; - - DPRINTK("ENTER\n"); + /* TODO: 1024 is an arbitrary number, not the + * hardware maximum. This should be increased to + * 65534 when Jens Axboe's patch for dynamically + * determining max_sectors is merged. + */ + if ((dev->flags & ATA_DFLAG_LBA48) && + ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { + /* + * do not overwrite sdev->host->max_sectors, since + * other drives on this host may not support LBA48 + */ + blk_queue_max_sectors(sdev->request_queue, 2048); + } - spin_lock_irqsave(&ap->host_set->lock, flags); - qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc) { - WARN_ON(qc->scsicmd != cmd); - qc->flags |= ATA_QCFLAG_EH_SCHEDULED; - qc->err_mask |= AC_ERR_TIMEOUT; - ret = EH_NOT_HANDLED; + /* + * SATA DMA transfers must be multiples of 4 byte, so + * we need to pad ATAPI transfers using an extra sg. + * Decrement max hw segments accordingly. + */ + if (dev->class == ATA_DEV_ATAPI) { + request_queue_t *q = sdev->request_queue; + blk_queue_max_hw_segments(q, q->max_hw_segments - 1); + } } - spin_unlock_irqrestore(&ap->host_set->lock, flags); - DPRINTK("EXIT, ret=%d\n", ret); - return ret; + return 0; /* scsi layer doesn't check return value, sigh */ } /** @@ -771,86 +724,29 @@ enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) * * LOCKING: * Inherited from SCSI layer (none, can sleep) + * + * RETURNS: + * Zero. */ -static void ata_scsi_error(struct Scsi_Host *host) +int ata_scsi_error(struct Scsi_Host *host) { struct ata_port *ap; - unsigned long flags; DPRINTK("ENTER\n"); ap = (struct ata_port *) &host->hostdata[0]; - - spin_lock_irqsave(&ap->host_set->lock, flags); - WARN_ON(ap->flags & ATA_FLAG_IN_EH); - ap->flags |= ATA_FLAG_IN_EH; - WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL); - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - ata_port_flush_task(ap); - ap->ops->eng_timeout(ap); - WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q)); - - scsi_eh_flush_done_q(&ap->eh_done_q); - - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->flags &= ~ATA_FLAG_IN_EH; - spin_unlock_irqrestore(&ap->host_set->lock, flags); + /* TODO: this is per-command; when queueing is supported + * this code will either change or move to a more + * appropriate place + */ + host->host_failed--; + INIT_LIST_HEAD(&host->eh_cmd_q); DPRINTK("EXIT\n"); -} - -static void ata_eh_scsidone(struct scsi_cmnd *scmd) -{ - /* nada */ -} - -static void __ata_eh_qc_complete(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct scsi_cmnd *scmd = qc->scsicmd; - unsigned long flags; - - spin_lock_irqsave(&ap->host_set->lock, flags); - qc->scsidone = ata_eh_scsidone; - __ata_qc_complete(qc); - WARN_ON(ata_tag_valid(qc->tag)); - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - scsi_eh_finish_cmd(scmd, &ap->eh_done_q); -} - -/** - * ata_eh_qc_complete - Complete an active ATA command from EH - * @qc: Command to complete - * - * Indicate to the mid and upper layers that an ATA command has - * completed. To be used from EH. - */ -void ata_eh_qc_complete(struct ata_queued_cmd *qc) -{ - struct scsi_cmnd *scmd = qc->scsicmd; - scmd->retries = scmd->allowed; - __ata_eh_qc_complete(qc); -} - -/** - * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH - * @qc: Command to retry - * - * Indicate to the mid and upper layers that an ATA command - * should be retried. To be used from EH. - * - * SCSI midlayer limits the number of retries to scmd->allowed. - * This function might need to adjust scmd->retries for commands - * which get retried due to unrelated NCQ failures. - */ -void ata_eh_qc_retry(struct ata_queued_cmd *qc) -{ - __ata_eh_qc_complete(qc); + return 0; } /** @@ -1089,13 +985,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc if (dev->flags & ATA_DFLAG_LBA) { tf->flags |= ATA_TFLAG_LBA; - if (lba_28_ok(block, n_block)) { - /* use LBA28 */ - tf->command = ATA_CMD_VERIFY; - tf->device |= (block >> 24) & 0xf; - } else if (lba_48_ok(block, n_block)) { - if (!(dev->flags & ATA_DFLAG_LBA48)) - goto out_of_range; + if (dev->flags & ATA_DFLAG_LBA48) { + if (n_block > (64 * 1024)) + goto invalid_fld; /* use LBA48 */ tf->flags |= ATA_TFLAG_LBA48; @@ -1106,9 +998,15 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc tf->hob_lbah = (block >> 40) & 0xff; tf->hob_lbam = (block >> 32) & 0xff; tf->hob_lbal = (block >> 24) & 0xff; - } else - /* request too large even for LBA48 */ - goto out_of_range; + } else { + if (n_block > 256) + goto invalid_fld; + + /* use LBA28 */ + tf->command = ATA_CMD_VERIFY; + + tf->device |= (block >> 24) & 0xf; + } tf->nsect = n_block & 0xff; @@ -1121,8 +1019,8 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc /* CHS */ u32 sect, head, cyl, track; - if (!lba_28_ok(block, n_block)) - goto out_of_range; + if (n_block > 256) + goto invalid_fld; /* Convert LBA to CHS */ track = (u32)block / dev->sectors; @@ -1132,14 +1030,14 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc DPRINTK("block %u track %u cyl %u head %u sect %u\n", (u32)block, track, cyl, head, sect); - - /* Check whether the converted CHS can fit. - Cylinder: 0-65535 + + /* Check whether the converted CHS can fit. + Cylinder: 0-65535 Head: 0-15 Sector: 1-255*/ - if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) + if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) goto out_of_range; - + tf->command = ATA_CMD_VERIFY; tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ tf->lbal = sect; @@ -1241,11 +1139,9 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm if (dev->flags & ATA_DFLAG_LBA) { tf->flags |= ATA_TFLAG_LBA; - if (lba_28_ok(block, n_block)) { - /* use LBA28 */ - tf->device |= (block >> 24) & 0xf; - } else if (lba_48_ok(block, n_block)) { - if (!(dev->flags & ATA_DFLAG_LBA48)) + if (dev->flags & ATA_DFLAG_LBA48) { + /* The request -may- be too large for LBA48. */ + if ((block >> 48) || (n_block > 65536)) goto out_of_range; /* use LBA48 */ @@ -1256,9 +1152,15 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm tf->hob_lbah = (block >> 40) & 0xff; tf->hob_lbam = (block >> 32) & 0xff; tf->hob_lbal = (block >> 24) & 0xff; - } else - /* request too large even for LBA48 */ - goto out_of_range; + } else { + /* use LBA28 */ + + /* The request -may- be too large for LBA28. */ + if ((block >> 28) || (n_block > 256)) + goto out_of_range; + + tf->device |= (block >> 24) & 0xf; + } if (unlikely(ata_rwcmd_protocol(qc) < 0)) goto invalid_fld; @@ -1271,12 +1173,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm tf->lbal = block & 0xff; tf->device |= ATA_LBA; - } else { + } else { /* CHS */ u32 sect, head, cyl, track; /* The request -may- be too large for CHS addressing. */ - if (!lba_28_ok(block, n_block)) + if ((block >> 28) || (n_block > 256)) goto out_of_range; if (unlikely(ata_rwcmd_protocol(qc) < 0)) @@ -1291,8 +1193,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm DPRINTK("block %u track %u cyl %u head %u sect %u\n", (u32)block, track, cyl, head, sect); - /* Check whether the converted CHS can fit. - Cylinder: 0-65535 + /* Check whether the converted CHS can fit. + Cylinder: 0-65535 Head: 0-15 Sector: 1-255*/ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) @@ -1323,7 +1225,7 @@ nothing_to_do: return 1; } -static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) +static int ata_scsi_qc_complete(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; u8 *cdb = cmd->cmnd; @@ -1360,7 +1262,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) qc->scsidone(cmd); - ata_qc_free(qc); + return 0; } /** @@ -1426,7 +1328,8 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, goto early_finish; /* select device, send command to hardware */ - ata_qc_issue(qc); + if (ata_qc_issue(qc)) + goto err_did; VPRINTK("EXIT\n"); return; @@ -1542,7 +1445,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, * @buflen: Response buffer length. * * Returns standard device identification data associated - * with non-VPD INQUIRY command output. + * with non-EVPD INQUIRY command output. * * LOCKING: * spin_lock_irqsave(host_set lock) @@ -1569,8 +1472,8 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, if (buflen > 35) { memcpy(&rbuf[8], "ATA ", 8); - ata_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16); - ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4); + ata_dev_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16); + ata_dev_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4); if (rbuf[32] == 0 || rbuf[32] == ' ') memcpy(&rbuf[32], "n/a ", 4); } @@ -1593,12 +1496,12 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, } /** - * ata_scsiop_inq_00 - Simulate INQUIRY VPD page 0, list of pages + * ata_scsiop_inq_00 - Simulate INQUIRY EVPD page 0, list of pages * @args: device IDENTIFY data / SCSI command of interest. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. * - * Returns list of inquiry VPD pages available. + * Returns list of inquiry EVPD pages available. * * LOCKING: * spin_lock_irqsave(host_set lock) @@ -1612,7 +1515,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf, 0x80, /* page 0x80, unit serial no page */ 0x83 /* page 0x83, device ident page */ }; - rbuf[3] = sizeof(pages); /* number of supported VPD pages */ + rbuf[3] = sizeof(pages); /* number of supported EVPD pages */ if (buflen > 6) memcpy(rbuf + 4, pages, sizeof(pages)); @@ -1621,7 +1524,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf, } /** - * ata_scsiop_inq_80 - Simulate INQUIRY VPD page 80, device serial number + * ata_scsiop_inq_80 - Simulate INQUIRY EVPD page 80, device serial number * @args: device IDENTIFY data / SCSI command of interest. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. @@ -1644,22 +1547,22 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf, memcpy(rbuf, hdr, sizeof(hdr)); if (buflen > (ATA_SERNO_LEN + 4 - 1)) - ata_id_string(args->id, (unsigned char *) &rbuf[4], - ATA_ID_SERNO_OFS, ATA_SERNO_LEN); + ata_dev_id_string(args->id, (unsigned char *) &rbuf[4], + ATA_ID_SERNO_OFS, ATA_SERNO_LEN); return 0; } +static const char * const inq_83_str = "Linux ATA-SCSI simulator"; + /** - * ata_scsiop_inq_83 - Simulate INQUIRY VPD page 83, device identity + * ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity * @args: device IDENTIFY data / SCSI command of interest. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. * - * Yields two logical unit device identification designators: - * - vendor specific ASCII containing the ATA serial number - * - SAT defined "t10 vendor id based" containing ASCII vendor - * name ("ATA "), model and serial numbers. + * Returns device identification. Currently hardcoded to + * return "Linux ATA-SCSI simulator". * * LOCKING: * spin_lock_irqsave(host_set lock) @@ -1668,39 +1571,16 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf, unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen) { - int num; - const int sat_model_serial_desc_len = 68; - const int ata_model_byte_len = 40; - rbuf[1] = 0x83; /* this page code */ - num = 4; - - if (buflen > (ATA_SERNO_LEN + num + 3)) { - /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */ - rbuf[num + 0] = 2; - rbuf[num + 3] = ATA_SERNO_LEN; - num += 4; - ata_id_string(args->id, (unsigned char *) rbuf + num, - ATA_ID_SERNO_OFS, ATA_SERNO_LEN); - num += ATA_SERNO_LEN; - } - if (buflen > (sat_model_serial_desc_len + num + 3)) { - /* SAT defined lu model and serial numbers descriptor */ - /* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */ - rbuf[num + 0] = 2; - rbuf[num + 1] = 1; - rbuf[num + 3] = sat_model_serial_desc_len; - num += 4; - memcpy(rbuf + num, "ATA ", 8); - num += 8; - ata_id_string(args->id, (unsigned char *) rbuf + num, - ATA_ID_PROD_OFS, ata_model_byte_len); - num += ata_model_byte_len; - ata_id_string(args->id, (unsigned char *) rbuf + num, - ATA_ID_SERNO_OFS, ATA_SERNO_LEN); - num += ATA_SERNO_LEN; + rbuf[3] = 4 + strlen(inq_83_str); /* page len */ + + /* our one and only identification descriptor (vendor-specific) */ + if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) { + rbuf[4 + 0] = 2; /* code set: ASCII */ + rbuf[4 + 3] = strlen(inq_83_str); + memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str)); } - rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */ + return 0; } @@ -1833,12 +1713,15 @@ static int ata_dev_supports_fua(u16 *id) if (!ata_id_has_fua(id)) return 0; - ata_id_c_string(id, model, ATA_ID_PROD_OFS, sizeof(model)); - ata_id_c_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw)); + model[40] = '\0'; + fw[8] = '\0'; - if (strcmp(model, "Maxtor")) + ata_dev_id_string(id, model, ATA_ID_PROD_OFS, sizeof(model) - 1); + ata_dev_id_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw) - 1); + + if (strncmp(model, "Maxtor", 6)) return 1; - if (strcmp(fw, "BANC1G10")) + if (strncmp(fw, "BANC1G10", 8)) return 1; return 0; /* blacklisted */ @@ -2132,7 +2015,7 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 done(cmd); } -static void atapi_sense_complete(struct ata_queued_cmd *qc) +static int atapi_sense_complete(struct ata_queued_cmd *qc) { if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) /* FIXME: not quite right; we don't want the @@ -2143,7 +2026,7 @@ static void atapi_sense_complete(struct ata_queued_cmd *qc) ata_gen_ata_desc_sense(qc); qc->scsidone(qc->scsicmd); - ata_qc_free(qc); + return 0; } /* is it pointless to prefer PIO for "safety reasons"? */ @@ -2173,7 +2056,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); qc->dma_dir = DMA_FROM_DEVICE; - memset(&qc->cdb, 0, qc->dev->cdb_len); + memset(&qc->cdb, 0, ap->cdb_len); qc->cdb[0] = REQUEST_SENSE; qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; @@ -2192,12 +2075,15 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) qc->complete_fn = atapi_sense_complete; - ata_qc_issue(qc); + if (ata_qc_issue(qc)) { + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); + } DPRINTK("EXIT\n"); } -static void atapi_qc_complete(struct ata_queued_cmd *qc) +static int atapi_qc_complete(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; unsigned int err_mask = qc->err_mask; @@ -2207,7 +2093,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) if (unlikely(err_mask & AC_ERR_DEV)) { cmd->result = SAM_STAT_CHECK_CONDITION; atapi_request_sense(qc); - return; + return 1; } else if (unlikely(err_mask)) @@ -2247,7 +2133,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) } qc->scsidone(cmd); - ata_qc_free(qc); + return 0; } /** * atapi_xlat - Initialize PACKET taskfile @@ -2273,7 +2159,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) if (ata_check_atapi_dma(qc)) using_pio = 1; - memcpy(&qc->cdb, scsicmd, dev->cdb_len); + memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len); qc->complete_fn = atapi_qc_complete; @@ -2377,6 +2263,9 @@ ata_scsi_map_proto(u8 byte1) case 4: /* PIO Data-in */ case 5: /* PIO Data-out */ + if (byte1 & 0xe0) { + return ATA_PROT_PIO_MULT; + } return ATA_PROT_PIO; case 10: /* Device Reset */ @@ -2415,10 +2304,6 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN) goto invalid_fld; - if (scsicmd[1] & 0xe0) - /* PIO multi not supported yet */ - goto invalid_fld; - /* * 12 and 16 byte CDBs use different offsets to * provide the various register values. @@ -2575,21 +2460,6 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, #endif } -static inline void __ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), - struct ata_port *ap, struct ata_device *dev) -{ - if (dev->class == ATA_DEV_ATA) { - ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, - cmd->cmnd[0]); - - if (xlat_func) - ata_scsi_translate(ap, dev, cmd, done, xlat_func); - else - ata_scsi_simulate(ap, dev, cmd, done); - } else - ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); -} - /** * ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device * @cmd: SCSI command to be sent @@ -2624,13 +2494,24 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) ata_scsi_dump_cdb(ap, cmd); dev = ata_scsi_find_dev(ap, scsidev); - if (likely(dev)) - __ata_scsi_queuecmd(cmd, done, ap, dev); - else { + if (unlikely(!dev)) { cmd->result = (DID_BAD_TARGET << 16); done(cmd); + goto out_unlock; } + if (dev->class == ATA_DEV_ATA) { + ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, + cmd->cmnd[0]); + + if (xlat_func) + ata_scsi_translate(ap, dev, cmd, done, xlat_func); + else + ata_scsi_simulate(ap, dev, cmd, done); + } else + ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); + +out_unlock: spin_unlock(&ap->host_set->lock); spin_lock(shost->host_lock); return 0; @@ -2638,8 +2519,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) /** * ata_scsi_simulate - simulate SCSI command on ATA device - * @ap: port the device is connected to - * @dev: the target device + * @id: current IDENTIFY data for target device. * @cmd: SCSI command being sent to device. * @done: SCSI command completion function. * diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index bac8cbae0..fddaf479a 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -45,9 +45,8 @@ extern int libata_fua; extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, struct ata_device *dev); extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); -extern void ata_port_flush_task(struct ata_port *ap); extern void ata_qc_free(struct ata_queued_cmd *qc); -extern void ata_qc_issue(struct ata_queued_cmd *qc); +extern int ata_qc_issue(struct ata_queued_cmd *qc); extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); extern void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep); @@ -57,9 +56,8 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); /* libata-scsi.c */ -extern struct scsi_transport_template ata_scsi_transport_template; - extern void ata_scsi_scan_host(struct ata_port *ap); +extern int ata_scsi_error(struct Scsi_Host *host); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen); diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 087c44539..38ffa8d6e 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -121,9 +121,7 @@ struct lpfc_stats { uint32_t elsRcvLOGO; uint32_t elsRcvPRLO; uint32_t elsRcvPRLI; - uint32_t elsRcvLIRR; - uint32_t elsRcvRPS; - uint32_t elsRcvRPL; + uint32_t elsRcvRRQ; uint32_t elsXmitFLOGI; uint32_t elsXmitPLOGI; uint32_t elsXmitPRLI; @@ -169,35 +167,33 @@ struct lpfc_sysfs_mbox { }; struct lpfc_hba { + struct list_head hba_list; /* List of hbas/ports */ struct lpfc_sli sli; struct lpfc_sli2_slim *slim2p; dma_addr_t slim2p_mapping; uint16_t pci_cfg_value; struct semaphore hba_can_block; - int32_t hba_state; - -#define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ -#define LPFC_WARM_START 1 /* HBA state after selective reset */ -#define LPFC_INIT_START 2 /* Initial state after board reset */ -#define LPFC_INIT_MBX_CMDS 3 /* Initialize HBA with mbox commands */ -#define LPFC_LINK_DOWN 4 /* HBA initialized, link is down */ -#define LPFC_LINK_UP 5 /* Link is up - issue READ_LA */ -#define LPFC_LOCAL_CFG_LINK 6 /* local NPORT Id configured */ -#define LPFC_FLOGI 7 /* FLOGI sent to Fabric */ -#define LPFC_FABRIC_CFG_LINK 8 /* Fabric assigned NPORT Id + uint32_t hba_state; + +#define LPFC_INIT_START 1 /* Initial state after board reset */ +#define LPFC_INIT_MBX_CMDS 2 /* Initialize HBA with mbox commands */ +#define LPFC_LINK_DOWN 3 /* HBA initialized, link is down */ +#define LPFC_LINK_UP 4 /* Link is up - issue READ_LA */ +#define LPFC_LOCAL_CFG_LINK 5 /* local NPORT Id configured */ +#define LPFC_FLOGI 6 /* FLOGI sent to Fabric */ +#define LPFC_FABRIC_CFG_LINK 7 /* Fabric assigned NPORT Id configured */ -#define LPFC_NS_REG 9 /* Register with NameServer */ -#define LPFC_NS_QRY 10 /* Query NameServer for NPort ID list */ -#define LPFC_BUILD_DISC_LIST 11 /* Build ADISC and PLOGI lists for +#define LPFC_NS_REG 8 /* Register with NameServer */ +#define LPFC_NS_QRY 9 /* Query NameServer for NPort ID list */ +#define LPFC_BUILD_DISC_LIST 10 /* Build ADISC and PLOGI lists for * device authentication / discovery */ -#define LPFC_DISC_AUTH 12 /* Processing ADISC list */ -#define LPFC_CLEAR_LA 13 /* authentication cmplt - issue +#define LPFC_DISC_AUTH 11 /* Processing ADISC list */ +#define LPFC_CLEAR_LA 12 /* authentication cmplt - issue CLEAR_LA */ #define LPFC_HBA_READY 32 -#define LPFC_HBA_ERROR -1 +#define LPFC_HBA_ERROR 0xff - int32_t stopped; /* HBA has not been restarted since last ERATT */ uint8_t fc_linkspeed; /* Link speed after last READ_LA */ uint32_t fc_eventTag; /* event tag for link attention */ @@ -249,7 +245,6 @@ struct lpfc_hba { #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ -#define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ uint32_t fc_topology; /* link topology, from LINK INIT */ @@ -294,8 +289,8 @@ struct lpfc_hba { uint32_t cfg_link_speed; uint32_t cfg_cr_delay; uint32_t cfg_cr_count; - uint32_t cfg_multi_ring_support; uint32_t cfg_fdmi_on; + uint32_t cfg_fcp_bind_method; uint32_t cfg_discovery_threads; uint32_t cfg_max_luns; uint32_t cfg_poll; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b62a72dfa..5625a8c2a 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -79,7 +79,7 @@ static ssize_t lpfc_serialnum_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber); } @@ -87,7 +87,7 @@ static ssize_t lpfc_modeldesc_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc); } @@ -95,7 +95,7 @@ static ssize_t lpfc_modelname_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName); } @@ -103,7 +103,7 @@ static ssize_t lpfc_programtype_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType); } @@ -111,7 +111,7 @@ static ssize_t lpfc_portnum_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port); } @@ -119,7 +119,7 @@ static ssize_t lpfc_fwrev_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; char fwrev[32]; lpfc_decode_firmware_rev(phba, fwrev, 1); return snprintf(buf, PAGE_SIZE, "%s\n",fwrev); @@ -130,7 +130,7 @@ lpfc_hdw_show(struct class_device *cdev, char *buf) { char hdw[9]; struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; lpfc_vpd_t *vp = &phba->vpd; lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); return snprintf(buf, PAGE_SIZE, "%s\n", hdw); @@ -139,18 +139,16 @@ static ssize_t lpfc_option_rom_version_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); } static ssize_t lpfc_state_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; int len = 0; switch (phba->hba_state) { - case LPFC_STATE_UNKNOWN: - case LPFC_WARM_START: case LPFC_INIT_START: case LPFC_INIT_MBX_CMDS: case LPFC_LINK_DOWN: @@ -196,7 +194,7 @@ static ssize_t lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt + phba->fc_unmap_cnt); } @@ -205,7 +203,7 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) static int lpfc_issue_lip(struct Scsi_Host *host) { - struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0]; LPFC_MBOXQ_t *pmboxq; int mbxstatus = MBXERR_ERROR; @@ -237,7 +235,7 @@ static ssize_t lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); } @@ -245,7 +243,7 @@ static ssize_t lpfc_board_online_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; if (phba->fc_flag & FC_OFFLINE_MODE) return snprintf(buf, PAGE_SIZE, "0\n"); @@ -258,7 +256,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf, size_t count) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; struct completion online_compl; int val=0, status=0; @@ -280,63 +278,11 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf, return -EIO; } -static ssize_t -lpfc_board_mode_show(struct class_device *cdev, char *buf) -{ - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - char * state; - - if (phba->hba_state == LPFC_HBA_ERROR) - state = "error"; - else if (phba->hba_state == LPFC_WARM_START) - state = "warm start"; - else if (phba->hba_state == LPFC_INIT_START) - state = "offline"; - else - state = "online"; - - return snprintf(buf, PAGE_SIZE, "%s\n", state); -} - -static ssize_t -lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) -{ - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - struct completion online_compl; - int status=0; - - init_completion(&online_compl); - - if(strncmp(buf, "online", sizeof("online") - 1) == 0) - lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_ONLINE); - else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) - lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_OFFLINE); - else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0) - lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_WARM_START); - else if (strncmp(buf, "error", sizeof("error") - 1) == 0) - lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_KILL); - else - return -EINVAL; - - wait_for_completion(&online_compl); - - if (!status) - return strlen(buf); - else - return -EIO; -} - static ssize_t lpfc_poll_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll); } @@ -346,7 +292,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, size_t count) { struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; uint32_t creg_val; uint32_t old_val; int val=0; @@ -403,7 +349,7 @@ static ssize_t \ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ { \ struct Scsi_Host *host = class_to_shost(cdev);\ - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ int val = 0;\ val = phba->cfg_##attr;\ return snprintf(buf, PAGE_SIZE, "%d\n",\ @@ -415,7 +361,7 @@ static ssize_t \ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ { \ struct Scsi_Host *host = class_to_shost(cdev);\ - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ int val = 0;\ val = phba->cfg_##attr;\ return snprintf(buf, PAGE_SIZE, "%#x\n",\ @@ -458,7 +404,7 @@ static ssize_t \ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ { \ struct Scsi_Host *host = class_to_shost(cdev);\ - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ int val=0;\ if (!isdigit(buf[0]))\ return -EINVAL;\ @@ -534,8 +480,6 @@ static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, NULL); static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, lpfc_board_online_show, lpfc_board_online_store); -static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, - lpfc_board_mode_show, lpfc_board_mode_store); static int lpfc_poll = 0; module_param(lpfc_poll, int, 0); @@ -575,16 +519,6 @@ LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask"); LPFC_ATTR_R(lun_queue_depth, 30, 1, 128, "Max number of FCP commands we can queue to a specific LUN"); -/* -# hba_queue_depth: This parameter is used to limit the number of outstanding -# commands per lpfc HBA. Value range is [32,8192]. If this parameter -# value is greater than the maximum number of exchanges supported by the HBA, -# then maximum number of exchanges supported by the HBA is used to determine -# the hba_queue_depth. -*/ -LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192, - "Max number of FCP commands we can queue to a lpfc HBA"); - /* # Some disk devices have a "select ID" or "select Target" capability. # From a protocol standpoint "select ID" usually means select the @@ -616,7 +550,6 @@ LPFC_ATTR_RW(nodev_tmo, 30, 0, 255, /* # lpfc_topology: link topology for init link # 0x0 = attempt loop mode then point-to-point -# 0x01 = internal loopback mode # 0x02 = attempt point-to-point mode only # 0x04 = attempt loop mode only # 0x06 = attempt point-to-point mode then loop @@ -624,7 +557,7 @@ LPFC_ATTR_RW(nodev_tmo, 30, 0, 255, # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. # Default value is 0. */ -LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology"); +LPFC_ATTR_R(topology, 0, 0, 6, "Select Fibre Channel topology"); /* # lpfc_link_speed: Link speed selection for initializing the Fibre Channel @@ -664,20 +597,12 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support"); # is 0. Default value of cr_count is 1. The cr_count feature is disabled if # cr_delay is set to 0. */ -LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an " +LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an" "interrupt response is generated"); -LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an " +LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an" "interrupt response is generated"); -/* -# lpfc_multi_ring_support: Determines how many rings to spread available -# cmd/rsp IOCB entries across. -# Value range is [1,2]. Default value is 1. -*/ -LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary " - "SLI rings to spread IOCB entries across"); - /* # lpfc_fdmi_on: controls FDMI support. # 0 = no FDMI support @@ -691,7 +616,7 @@ LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support"); # Specifies the maximum number of ELS cmds we can have outstanding (for # discovery). Value range is [1,64]. Default value = 32. */ -LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " +LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands" "during discovery"); /* @@ -724,7 +649,6 @@ struct class_device_attribute *lpfc_host_attrs[] = { &class_device_attr_lpfc_drvr_version, &class_device_attr_lpfc_log_verbose, &class_device_attr_lpfc_lun_queue_depth, - &class_device_attr_lpfc_hba_queue_depth, &class_device_attr_lpfc_nodev_tmo, &class_device_attr_lpfc_fcp_class, &class_device_attr_lpfc_use_adisc, @@ -734,13 +658,11 @@ struct class_device_attribute *lpfc_host_attrs[] = { &class_device_attr_lpfc_link_speed, &class_device_attr_lpfc_cr_delay, &class_device_attr_lpfc_cr_count, - &class_device_attr_lpfc_multi_ring_support, &class_device_attr_lpfc_fdmi_on, &class_device_attr_lpfc_max_luns, &class_device_attr_nport_evt_cnt, &class_device_attr_management_version, &class_device_attr_board_online, - &class_device_attr_board_mode, &class_device_attr_lpfc_poll, &class_device_attr_lpfc_poll_tmo, NULL, @@ -752,7 +674,7 @@ sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) size_t buf_off; struct Scsi_Host *host = class_to_shost(container_of(kobj, struct class_device, kobj)); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; if ((off + count) > FF_REG_AREA_SIZE) return -ERANGE; @@ -785,7 +707,7 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) uint32_t * tmp_ptr; struct Scsi_Host *host = class_to_shost(container_of(kobj, struct class_device, kobj)); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; if (off > FF_REG_AREA_SIZE) return -ERANGE; @@ -840,7 +762,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) { struct Scsi_Host * host = class_to_shost(container_of(kobj, struct class_device, kobj)); - struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata[0]; struct lpfcMboxq * mbox = NULL; if ((count + off) > MAILBOX_CMD_SIZE) @@ -856,7 +778,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) return -ENOMEM; - memset(mbox, 0, sizeof (LPFC_MBOXQ_t)); + } spin_lock_irq(host->host_lock); @@ -893,7 +815,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) struct Scsi_Host *host = class_to_shost(container_of(kobj, struct class_device, kobj)); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; int rc; if (off > sizeof(MAILBOX_t)) @@ -950,11 +872,8 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) case MBX_DUMP_MEMORY: case MBX_DOWN_LOAD: case MBX_UPDATE_CFG: - case MBX_KILL_BOARD: case MBX_LOAD_AREA: case MBX_LOAD_EXP_ROM: - case MBX_BEACON: - case MBX_DEL_LD_ENTRY: break; case MBX_READ_SPARM64: case MBX_READ_LA: @@ -1071,7 +990,7 @@ lpfc_free_sysfs_attr(struct lpfc_hba *phba) static void lpfc_get_host_port_id(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; /* note: fc_myDID already in cpu endianness */ fc_host_port_id(shost) = phba->fc_myDID; } @@ -1079,7 +998,7 @@ lpfc_get_host_port_id(struct Scsi_Host *shost) static void lpfc_get_host_port_type(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; spin_lock_irq(shost->host_lock); @@ -1104,7 +1023,7 @@ lpfc_get_host_port_type(struct Scsi_Host *shost) static void lpfc_get_host_port_state(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; spin_lock_irq(shost->host_lock); @@ -1112,8 +1031,6 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; else { switch (phba->hba_state) { - case LPFC_STATE_UNKNOWN: - case LPFC_WARM_START: case LPFC_INIT_START: case LPFC_INIT_MBX_CMDS: case LPFC_LINK_DOWN: @@ -1147,7 +1064,7 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) static void lpfc_get_host_speed(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; spin_lock_irq(shost->host_lock); @@ -1174,7 +1091,7 @@ lpfc_get_host_speed(struct Scsi_Host *shost) static void lpfc_get_host_fabric_name (struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; u64 node_name; spin_lock_irq(shost->host_lock); @@ -1196,7 +1113,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost) static struct fc_host_statistics * lpfc_get_stats(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; struct lpfc_sli *psli = &phba->sli; struct fc_host_statistics *hs = &phba->link_stats; LPFC_MBOXQ_t *pmboxq; @@ -1286,7 +1203,7 @@ static void lpfc_get_starget_port_id(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; uint32_t did = -1; struct lpfc_nodelist *ndlp = NULL; @@ -1307,7 +1224,7 @@ static void lpfc_get_starget_node_name(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; u64 node_name = 0; struct lpfc_nodelist *ndlp = NULL; @@ -1328,7 +1245,7 @@ static void lpfc_get_starget_port_name(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; u64 port_name = 0; struct lpfc_nodelist *ndlp = NULL; @@ -1449,7 +1366,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_log_verbose_init(phba, lpfc_log_verbose); lpfc_cr_delay_init(phba, lpfc_cr_delay); lpfc_cr_count_init(phba, lpfc_cr_count); - lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); lpfc_fcp_class_init(phba, lpfc_fcp_class); lpfc_use_adisc_init(phba, lpfc_use_adisc); @@ -1495,9 +1411,5 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) default: phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH; } - - if (phba->cfg_hba_queue_depth > lpfc_hba_queue_depth) - lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); - return; } diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index ee22173fc..f1e708946 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -26,7 +26,7 @@ void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); -void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *); +void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *, uint32_t); void lpfc_unreg_login(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *); @@ -42,6 +42,9 @@ void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); +int lpfc_nlp_plogi(struct lpfc_hba *, struct lpfc_nodelist *); +int lpfc_nlp_adisc(struct lpfc_hba *, struct lpfc_nodelist *); +int lpfc_nlp_unmapped(struct lpfc_hba *, struct lpfc_nodelist *); int lpfc_nlp_list(struct lpfc_hba *, struct lpfc_nodelist *, int); void lpfc_set_disctmo(struct lpfc_hba *); int lpfc_can_disctmo(struct lpfc_hba *); @@ -51,10 +54,12 @@ int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *); void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t); struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t); +struct lpfc_nodelist *lpfc_setup_rscn_node(struct lpfc_hba *, uint32_t); void lpfc_disc_list_loopmap(struct lpfc_hba *); void lpfc_disc_start(struct lpfc_hba *); void lpfc_disc_flush_list(struct lpfc_hba *); void lpfc_disc_timeout(unsigned long); +void lpfc_scan_timeout(unsigned long); struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); @@ -63,13 +68,19 @@ int lpfc_do_work(void *); int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *, uint32_t); +uint32_t lpfc_cmpl_prli_reglogin_issue(struct lpfc_hba *, + struct lpfc_nodelist *, void *, + uint32_t); +uint32_t lpfc_cmpl_plogi_prli_issue(struct lpfc_hba *, struct lpfc_nodelist *, + void *, uint32_t); + int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *, struct serv_parm *, uint32_t); int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp, int); int lpfc_els_abort_flogi(struct lpfc_hba *); int lpfc_initial_flogi(struct lpfc_hba *); -int lpfc_issue_els_plogi(struct lpfc_hba *, uint32_t, uint8_t); +int lpfc_issue_els_plogi(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); @@ -83,7 +94,6 @@ int lpfc_els_rsp_adisc_acc(struct lpfc_hba *, struct lpfc_iocbq *, struct lpfc_nodelist *); int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *, struct lpfc_nodelist *); -void lpfc_cancel_retry_delay_tmo(struct lpfc_hba *, struct lpfc_nodelist *); void lpfc_els_retry_delay(unsigned long); void lpfc_els_retry_delay_handler(struct lpfc_nodelist *); void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, @@ -107,15 +117,18 @@ void lpfc_fdmi_tmo_handler(struct lpfc_hba *); int lpfc_config_port_prep(struct lpfc_hba *); int lpfc_config_port_post(struct lpfc_hba *); int lpfc_hba_down_prep(struct lpfc_hba *); -int lpfc_hba_down_post(struct lpfc_hba *); void lpfc_hba_init(struct lpfc_hba *, uint32_t *); int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); +uint8_t *lpfc_get_lpfchba_info(struct lpfc_hba *, uint8_t *); +int lpfc_fcp_abort(struct lpfc_hba *, int, int, int); int lpfc_online(struct lpfc_hba *); int lpfc_offline(struct lpfc_hba *); + int lpfc_sli_setup(struct lpfc_hba *); int lpfc_sli_queue_setup(struct lpfc_hba *); +void lpfc_slim_access(struct lpfc_hba *); void lpfc_handle_eratt(struct lpfc_hba *); void lpfc_handle_latt(struct lpfc_hba *); @@ -124,7 +137,6 @@ irqreturn_t lpfc_intr_handler(int, void *, struct pt_regs *); void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *); void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *); -void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *); LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); @@ -137,12 +149,6 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba); struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); - -void lpfc_reset_barrier(struct lpfc_hba * phba); -int lpfc_sli_brdready(struct lpfc_hba *, uint32_t); -int lpfc_sli_brdkill(struct lpfc_hba *); -int lpfc_sli_brdreset(struct lpfc_hba *); -int lpfc_sli_brdrestart(struct lpfc_hba *); int lpfc_sli_hba_setup(struct lpfc_hba *); int lpfc_sli_hba_down(struct lpfc_hba *); int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); @@ -168,10 +174,12 @@ int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, void lpfc_mbox_timeout(unsigned long); void lpfc_mbox_timeout_handler(struct lpfc_hba *); +void lpfc_map_fcp_cmnd_to_bpl(struct lpfc_hba *, struct lpfc_scsi_buf *); +void lpfc_free_scsi_cmd(struct lpfc_scsi_buf *); +uint32_t lpfc_os_timeout_transform(struct lpfc_hba *, uint32_t); -struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t, uint32_t); -struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, uint32_t, - struct lpfc_name *); +struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, + uint32_t did); int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, uint32_t timeout); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index b65ee57af..7f427f9c4 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -260,10 +260,8 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; - if (!tmo) { - /* FC spec states we need 3 * ratov for CT requests */ - tmo = (3 * phba->fc_ratov); - } + if (!tmo) + tmo = (2 * phba->fc_ratov) + 1; icmd->ulpTimeout = tmo; icmd->ulpBdeCount = 1; icmd->ulpLe = 1; @@ -323,7 +321,6 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) struct lpfc_sli_ct_request *Response = (struct lpfc_sli_ct_request *) mp->virt; struct lpfc_nodelist *ndlp = NULL; - struct lpfc_nodelist *next_ndlp; struct lpfc_dmabuf *mlast, *next_mp; uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; uint32_t Did; @@ -392,36 +389,8 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) nsout1: list_del(&head); - /* - * The driver has cycled through all Nports in the RSCN payload. - * Complete the handling by cleaning up and marking the - * current driver state. - */ + /* Here we are finished in the case RSCN */ if (phba->hba_state == LPFC_HBA_READY) { - - /* - * Switch ports that connect a loop of multiple targets need - * special consideration. The driver wants to unregister the - * rpi only on the target that was pulled from the loop. On - * RSCN, the driver wants to rediscover an NPort only if the - * driver flagged it as NLP_NPR_2B_DISC. Provided adisc is - * not enabled and the NPort is not capable of retransmissions - * (FC Tape) prevent timing races with the scsi error handler by - * unregistering the Nport's RPI. This action causes all - * outstanding IO to flush back to the midlayer. - */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, - nlp_listp) { - if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC) && - (lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) { - if ((phba->cfg_use_adisc == 0) && - !(ndlp->nlp_fcp_info & - NLP_FCP_2_DEVICE)) { - lpfc_unreg_rpi(phba, ndlp); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - } - } - } lpfc_els_flush_rscn(phba); spin_lock_irq(phba->host->host_lock); phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ @@ -480,11 +449,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, CTrsp = (struct lpfc_sli_ct_request *) outp->virt; if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { - lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d:0239 NameServer Rsp " - "Data: x%x\n", - phba->brd_no, - phba->fc_flag); lpfc_ns_rsp(phba, outp, (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); } else if (CTrsp->CommandResponse.bits.CmdRsp == @@ -1014,19 +978,19 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED); ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); - - ae->un.SupportSpeed = 0; - if (phba->lmt & LMT_10Gb) + if (FC_JEDEC_ID(vp->rev.biuRev) == VIPER_JEDEC_ID) ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT; - if (phba->lmt & LMT_8Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT; - if (phba->lmt & LMT_4Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT; - if (phba->lmt & LMT_2Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT; - if (phba->lmt & LMT_1Gb) - ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT; - + else if (FC_JEDEC_ID(vp->rev.biuRev) == HELIOS_JEDEC_ID) + ae->un.SupportSpeed = HBA_PORTSPEED_4GBIT; + else if ((FC_JEDEC_ID(vp->rev.biuRev) == + CENTAUR_2G_JEDEC_ID) + || (FC_JEDEC_ID(vp->rev.biuRev) == + PEGASUS_JEDEC_ID) + || (FC_JEDEC_ID(vp->rev.biuRev) == + THOR_JEDEC_ID)) + ae->un.SupportSpeed = HBA_PORTSPEED_2GBIT; + else + ae->un.SupportSpeed = HBA_PORTSPEED_1GBIT; pab->ab.EntryCnt++; size += FOURBYTES + 4; @@ -1166,6 +1130,11 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) { struct lpfc_nodelist *ndlp; + spin_lock_irq(phba->host->host_lock); + if (!(phba->work_hba_events & WORKER_FDMI_TMO)) { + spin_unlock_irq(phba->host->host_lock); + return; + } ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); if (ndlp) { if (system_utsname.nodename[0] != '\0') { @@ -1174,6 +1143,7 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); } } + spin_unlock_irq(phba->host->host_lock); return; } diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 41cf5d3ea..ed6c81660 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -28,24 +28,18 @@ * This is used by Fibre Channel protocol to support FCP. */ -/* worker thread events */ -enum lpfc_work_type { - LPFC_EVT_NODEV_TMO, - LPFC_EVT_ONLINE, - LPFC_EVT_OFFLINE, - LPFC_EVT_WARM_START, - LPFC_EVT_KILL, - LPFC_EVT_ELS_RETRY, -}; - /* structure used to queue event to the discovery tasklet */ struct lpfc_work_evt { struct list_head evt_listp; void * evt_arg1; void * evt_arg2; - enum lpfc_work_type evt; + uint32_t evt; }; +#define LPFC_EVT_NODEV_TMO 0x1 +#define LPFC_EVT_ONLINE 0x2 +#define LPFC_EVT_OFFLINE 0x3 +#define LPFC_EVT_ELS_RETRY 0x4 struct lpfc_nodelist { struct list_head nlp_listp; @@ -62,7 +56,6 @@ struct lpfc_nodelist { uint16_t nlp_rpi; uint16_t nlp_state; /* state transition indicator */ - uint16_t nlp_prev_state; /* state transition indicator */ uint16_t nlp_xri; /* output exchange id for RPI */ uint16_t nlp_sid; /* scsi id */ #define NLP_NO_SID 0xffff @@ -113,7 +106,6 @@ struct lpfc_nodelist { #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from NPR list */ #define NLP_DELAY_REMOVE 0x4000000 /* Defer removal till end of DSM */ -#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ /* Defines for list searchs */ #define NLP_SEARCH_MAPPED 0x1 /* search mapped */ diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 283b7d824..20f1a0713 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -92,14 +92,15 @@ lpfc_els_chk_latt(struct lpfc_hba * phba) } } - return 1; + return (1); } static struct lpfc_iocbq * -lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, - uint16_t cmdSize, uint8_t retry, struct lpfc_nodelist * ndlp, - uint32_t did, uint32_t elscmd) +lpfc_prep_els_iocb(struct lpfc_hba * phba, + uint8_t expectRsp, + uint16_t cmdSize, + uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd) { struct lpfc_sli_ring *pring; struct lpfc_iocbq *elsiocb; @@ -180,7 +181,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; if (expectRsp) { icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); - icmd->un.elsreq64.remoteID = did; /* DID */ + icmd->un.elsreq64.remoteID = ndlp->nlp_DID; /* DID */ icmd->ulpCommand = CMD_ELS_REQUEST64_CR; } else { icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64); @@ -224,7 +225,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, "%d:0116 Xmit ELS command x%x to remote " "NPORT x%x Data: x%x x%x\n", phba->brd_no, elscmd, - did, icmd->ulpIoTag, phba->hba_state); + ndlp->nlp_DID, icmd->ulpIoTag, phba->hba_state); } else { /* Xmit ELS response to remote NPORT */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, @@ -234,7 +235,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, ndlp->nlp_DID, icmd->ulpIoTag, cmdSize); } - return elsiocb; + return (elsiocb); } @@ -302,6 +303,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, if (lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0)) goto fail_free_mbox; + /* + * set_slim mailbox command needs to execute first, + * queue this command to be processed later. + */ mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; mbox->context2 = ndlp; @@ -441,10 +446,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0100 FLOGI failure Data: x%x x%x x%x\n", + "%d:0100 FLOGI failure Data: x%x x%x\n", phba->brd_no, - irsp->ulpStatus, irsp->un.ulpWord[4], - irsp->ulpTimeout); + irsp->ulpStatus, irsp->un.ulpWord[4]); goto flogifail; } @@ -511,10 +515,10 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, pring = &phba->sli.ring[LPFC_ELS_RING]; cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); - elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, - ndlp->nlp_DID, ELS_CMD_FLOGI); - if (!elsiocb) - return 1; + if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, + ndlp, ELS_CMD_FLOGI)) == 0) { + return (1); + } icmd = &elsiocb->iocb; pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); @@ -548,9 +552,9 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, spin_unlock_irq(phba->host->host_lock); if (rc == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } - return 0; + return (0); } int @@ -607,21 +611,29 @@ lpfc_initial_flogi(struct lpfc_hba * phba) { struct lpfc_nodelist *ndlp; - /* First look for the Fabric ndlp */ - ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, Fabric_DID); - if (!ndlp) { + /* First look for Fabric ndlp on the unmapped list */ + + if ((ndlp = + lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, + Fabric_DID)) == 0) { /* Cannot find existing Fabric ndlp, so allocate a new one */ - ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); - if (!ndlp) - return 0; + if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) + == 0) { + return (0); + } lpfc_nlp_init(phba, ndlp, Fabric_DID); - } else { - lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ); + } + else { + phba->fc_unmap_cnt--; + list_del(&ndlp->nlp_listp); + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_LIST_MASK; + spin_unlock_irq(phba->host->host_lock); } if (lpfc_issue_els_flogi(phba, ndlp, 0)) { mempool_free( ndlp, phba->nlp_mem_pool); } - return 1; + return (1); } static void @@ -647,90 +659,38 @@ lpfc_more_plogi(struct lpfc_hba * phba) return; } -static struct lpfc_nodelist * -lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, - struct lpfc_nodelist *ndlp) -{ - struct lpfc_nodelist *new_ndlp; - struct lpfc_dmabuf *pcmd, *prsp; - uint32_t *lp; - struct serv_parm *sp; - uint8_t name[sizeof (struct lpfc_name)]; - uint32_t rc; - - pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; - prsp = (struct lpfc_dmabuf *) pcmd->list.next; - lp = (uint32_t *) prsp->virt; - sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); - - /* Now we to find out if the NPort we are logging into, matches the WWPN - * we have for that ndlp. If not, we have some work to do. - */ - new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); - - memset(name, 0, sizeof (struct lpfc_name)); - rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); - if (!rc || (new_ndlp == ndlp)) { - return ndlp; - } - - if (!new_ndlp) { - new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); - if (!new_ndlp) - return ndlp; - - lpfc_nlp_init(phba, new_ndlp, ndlp->nlp_DID); - } - - lpfc_unreg_rpi(phba, new_ndlp); - new_ndlp->nlp_prev_state = ndlp->nlp_state; - new_ndlp->nlp_DID = ndlp->nlp_DID; - new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST); - - /* Move this back to NPR list */ - lpfc_unreg_rpi(phba, ndlp); - ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ - ndlp->nlp_state = NLP_STE_NPR_NODE; - lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - - return new_ndlp; -} - static void lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) { IOCB_t *irsp; + struct lpfc_sli *psli; struct lpfc_nodelist *ndlp; int disc, rc, did, type; + psli = &phba->sli; /* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; irsp = &rspiocb->iocb; - ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, - irsp->un.elsreq64.remoteID); - if (!ndlp) - goto out; + ndlp = (struct lpfc_nodelist *) cmdiocb->context1; + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_PLOGI_SND; + spin_unlock_irq(phba->host->host_lock); /* Since ndlp can be freed in the disc state machine, note if this node * is being used during discovery. */ disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; - spin_unlock_irq(phba->host->host_lock); rc = 0; /* PLOGI completes to NPort */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0102 PLOGI completes to NPort x%x " - "Data: x%x x%x x%x x%x x%x\n", + "Data: x%x x%x x%x x%x\n", phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, - irsp->un.ulpWord[4], irsp->ulpTimeout, disc, - phba->num_disc_nodes); + irsp->un.ulpWord[4], disc, phba->num_disc_nodes); /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(phba)) { @@ -762,41 +722,55 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { - rc = NLP_STE_FREED_NODE; - } else { + disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); + } + else { rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_PLOGI); } } else { /* Good status, call state machine */ - ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp); rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_PLOGI); } + if (type & NLP_FABRIC) { + /* If we cannot login to Nameserver, kick off discovery now */ + if ((did == NameServer_DID) && (rc == NLP_STE_FREED_NODE)) { + lpfc_disc_start(phba); + } + goto out; + } + if (disc && phba->num_disc_nodes) { /* Check to see if there are more PLOGIs to be sent */ lpfc_more_plogi(phba); + } - if (phba->num_disc_nodes == 0) { + if (rc != NLP_STE_FREED_NODE) { + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; + spin_unlock_irq(phba->host->host_lock); + } + + if (phba->num_disc_nodes == 0) { + if(disc) { spin_lock_irq(phba->host->host_lock); phba->fc_flag &= ~FC_NDISC_ACTIVE; spin_unlock_irq(phba->host->host_lock); - - lpfc_can_disctmo(phba); - if (phba->fc_flag & FC_RSCN_MODE) { - /* - * Check to see if more RSCNs came in while - * we were processing this one. - */ - if ((phba->fc_rscn_id_cnt == 0) && - (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { - spin_lock_irq(phba->host->host_lock); - phba->fc_flag &= ~FC_RSCN_MODE; - spin_unlock_irq(phba->host->host_lock); - } else { - lpfc_els_handle_rscn(phba); - } + } + lpfc_can_disctmo(phba); + if (phba->fc_flag & FC_RSCN_MODE) { + /* Check to see if more RSCNs came in while we were + * processing this one. + */ + if ((phba->fc_rscn_id_cnt == 0) && + (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { + spin_lock_irq(phba->host->host_lock); + phba->fc_flag &= ~FC_RSCN_MODE; + spin_unlock_irq(phba->host->host_lock); + } else { + lpfc_els_handle_rscn(phba); } } } @@ -807,7 +781,8 @@ out: } int -lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) +lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, + uint8_t retry) { struct serv_parm *sp; IOCB_t *icmd; @@ -821,10 +796,10 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); - elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, 0, did, - ELS_CMD_PLOGI); - if (!elsiocb) - return 1; + if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, + ndlp, ELS_CMD_PLOGI)) == 0) { + return (1); + } icmd = &elsiocb->iocb; pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); @@ -844,13 +819,15 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) phba->fc_stat.elsXmitPLOGI++; elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag |= NLP_PLOGI_SND; if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { + ndlp->nlp_flag &= ~NLP_PLOGI_SND; spin_unlock_irq(phba->host->host_lock); lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } spin_unlock_irq(phba->host->host_lock); - return 0; + return (0); } static void @@ -874,10 +851,9 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, /* PRLI completes to NPort */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0103 PRLI completes to NPort x%x " - "Data: x%x x%x x%x x%x\n", + "Data: x%x x%x x%x\n", phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, - irsp->un.ulpWord[4], irsp->ulpTimeout, - phba->num_disc_nodes); + irsp->un.ulpWord[4], phba->num_disc_nodes); phba->fc_prli_sent--; /* Check to see if link went down during discovery */ @@ -897,7 +873,8 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { goto out; - } else { + } + else { lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_PRLI); } @@ -927,10 +904,10 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ cmdsize = (sizeof (uint32_t) + sizeof (PRLI)); - elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, - ndlp->nlp_DID, ELS_CMD_PRLI); - if (!elsiocb) - return 1; + if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, + ndlp, ELS_CMD_PRLI)) == 0) { + return (1); + } icmd = &elsiocb->iocb; pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); @@ -966,11 +943,11 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ndlp->nlp_flag &= ~NLP_PRLI_SND; spin_unlock_irq(phba->host->host_lock); lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } spin_unlock_irq(phba->host->host_lock); phba->fc_prli_sent++; - return 0; + return (0); } static void @@ -1039,22 +1016,21 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, irsp = &(rspiocb->iocb); ndlp = (struct lpfc_nodelist *) cmdiocb->context1; + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_ADISC_SND; + spin_unlock_irq(phba->host->host_lock); /* Since ndlp can be freed in the disc state machine, note if this node * is being used during discovery. */ disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC); - spin_unlock_irq(phba->host->host_lock); /* ADISC completes to NPort */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0104 ADISC completes to NPort x%x " - "Data: x%x x%x x%x x%x x%x\n", + "Data: x%x x%x x%x x%x\n", phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, - irsp->un.ulpWord[4], irsp->ulpTimeout, disc, - phba->num_disc_nodes); + irsp->un.ulpWord[4], disc, phba->num_disc_nodes); /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(phba)) { @@ -1078,10 +1054,13 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } /* ADISC failed */ /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ - if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || - ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) && - (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) && - (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) { + if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && + ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || + (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || + (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { + disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); + } + else { lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_ADISC); } @@ -1133,6 +1112,9 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } } } + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; + spin_unlock_irq(phba->host->host_lock); out: lpfc_els_free_iocb(phba, cmdiocb); return; @@ -1154,10 +1136,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ cmdsize = (sizeof (uint32_t) + sizeof (ADISC)); - elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, - ndlp->nlp_DID, ELS_CMD_ADISC); - if (!elsiocb) - return 1; + if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, + ndlp, ELS_CMD_ADISC)) == 0) { + return (1); + } icmd = &elsiocb->iocb; pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); @@ -1181,10 +1163,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ndlp->nlp_flag &= ~NLP_ADISC_SND; spin_unlock_irq(phba->host->host_lock); lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } spin_unlock_irq(phba->host->host_lock); - return 0; + return (0); } static void @@ -1208,10 +1190,9 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, /* LOGO completes to NPort */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0105 LOGO completes to NPort x%x " - "Data: x%x x%x x%x x%x\n", + "Data: x%x x%x x%x\n", phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, - irsp->un.ulpWord[4], irsp->ulpTimeout, - phba->num_disc_nodes); + irsp->un.ulpWord[4], phba->num_disc_nodes); /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(phba)) @@ -1230,15 +1211,18 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { goto out; - } else { + } + else { lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); } } else { - /* Good status, call state machine. - * This will unregister the rpi if needed. - */ + /* Good status, call state machine */ lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); + + if (ndlp->nlp_flag & NLP_DELAY_TMO) { + lpfc_unreg_rpi(phba, ndlp); + } } out: @@ -1260,11 +1244,11 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, psli = &phba->sli; pring = &psli->ring[LPFC_ELS_RING]; - cmdsize = (2 * sizeof (uint32_t)) + sizeof (struct lpfc_name); - elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, - ndlp->nlp_DID, ELS_CMD_LOGO); - if (!elsiocb) - return 1; + cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name)); + if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, + ndlp, ELS_CMD_LOGO)) == 0) { + return (1); + } icmd = &elsiocb->iocb; pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); @@ -1284,10 +1268,10 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ndlp->nlp_flag &= ~NLP_LOGO_SND; spin_unlock_irq(phba->host->host_lock); lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } spin_unlock_irq(phba->host->host_lock); - return 0; + return (0); } static void @@ -1302,10 +1286,9 @@ lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n", + "%d:0106 ELS cmd tag x%x completes Data: x%x x%x\n", phba->brd_no, - irsp->ulpIoTag, irsp->ulpStatus, - irsp->un.ulpWord[4], irsp->ulpTimeout); + irsp->ulpIoTag, irsp->ulpStatus, irsp->un.ulpWord[4]); /* Check to see if link went down during discovery */ lpfc_els_chk_latt(phba); @@ -1327,17 +1310,16 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) psli = &phba->sli; pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ cmdsize = (sizeof (uint32_t) + sizeof (SCR)); - ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); - if (!ndlp) - return 1; + if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) == 0) { + return (1); + } lpfc_nlp_init(phba, ndlp, nportid); - elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, - ndlp->nlp_DID, ELS_CMD_SCR); - if (!elsiocb) { + if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, + ndlp, ELS_CMD_SCR)) == 0) { mempool_free( ndlp, phba->nlp_mem_pool); - return 1; + return (1); } icmd = &elsiocb->iocb; @@ -1357,11 +1339,11 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); - return 0; + return (0); } static int @@ -1381,16 +1363,15 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) psli = &phba->sli; pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ cmdsize = (sizeof (uint32_t) + sizeof (FARP)); - ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); - if (!ndlp) - return 1; + if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) == 0) { + return (1); + } lpfc_nlp_init(phba, ndlp, nportid); - elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, - ndlp->nlp_DID, ELS_CMD_RNID); - if (!elsiocb) { + if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, + ndlp, ELS_CMD_RNID)) == 0) { mempool_free( ndlp, phba->nlp_mem_pool); - return 1; + return (1); } icmd = &elsiocb->iocb; @@ -1424,52 +1405,11 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); - return 0; -} - -void -lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp) -{ - nlp->nlp_flag &= ~NLP_DELAY_TMO; - del_timer_sync(&nlp->nlp_delayfunc); - nlp->nlp_last_elscmd = 0; - - if (!list_empty(&nlp->els_retry_evt.evt_listp)) - list_del_init(&nlp->els_retry_evt.evt_listp); - - if (nlp->nlp_flag & NLP_NPR_2B_DISC) { - nlp->nlp_flag &= ~NLP_NPR_2B_DISC; - if (phba->num_disc_nodes) { - /* Check to see if there are more - * PLOGIs to be sent - */ - lpfc_more_plogi(phba); - - if (phba->num_disc_nodes == 0) { - phba->fc_flag &= ~FC_NDISC_ACTIVE; - lpfc_can_disctmo(phba); - if (phba->fc_flag & FC_RSCN_MODE) { - /* - * Check to see if more RSCNs - * came in while we were - * processing this one. - */ - if((phba->fc_rscn_id_cnt==0) && - !(phba->fc_flag & FC_RSCN_DISCOVERY)) { - phba->fc_flag &= ~FC_RSCN_MODE; - } - else { - lpfc_els_handle_rscn(phba); - } - } - } - } - } - return; + return (0); } void @@ -1510,9 +1450,8 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) phba = ndlp->nlp_phba; spin_lock_irq(phba->host->host_lock); - did = ndlp->nlp_DID; - cmd = ndlp->nlp_last_elscmd; - ndlp->nlp_last_elscmd = 0; + did = (uint32_t) (ndlp->nlp_DID); + cmd = (uint32_t) (ndlp->nlp_last_elscmd); if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { spin_unlock_irq(phba->host->host_lock); @@ -1521,12 +1460,6 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) ndlp->nlp_flag &= ~NLP_DELAY_TMO; spin_unlock_irq(phba->host->host_lock); - /* - * If a discovery event readded nlp_delayfunc after timer - * firing and before processing the timer, cancel the - * nlp_delayfunc. - */ - del_timer_sync(&ndlp->nlp_delayfunc); retry = ndlp->nlp_retry; switch (cmd) { @@ -1534,32 +1467,24 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) lpfc_issue_els_flogi(phba, ndlp, retry); break; case ELS_CMD_PLOGI: - if(!lpfc_issue_els_plogi(phba, ndlp->nlp_DID, retry)) { - ndlp->nlp_prev_state = ndlp->nlp_state; - ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - } + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); + lpfc_issue_els_plogi(phba, ndlp, retry); break; case ELS_CMD_ADISC: - if (!lpfc_issue_els_adisc(phba, ndlp, retry)) { - ndlp->nlp_prev_state = ndlp->nlp_state; - ndlp->nlp_state = NLP_STE_ADISC_ISSUE; - lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); - } + ndlp->nlp_state = NLP_STE_ADISC_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); + lpfc_issue_els_adisc(phba, ndlp, retry); break; case ELS_CMD_PRLI: - if (!lpfc_issue_els_prli(phba, ndlp, retry)) { - ndlp->nlp_prev_state = ndlp->nlp_state; - ndlp->nlp_state = NLP_STE_PRLI_ISSUE; - lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); - } + ndlp->nlp_state = NLP_STE_PRLI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); + lpfc_issue_els_prli(phba, ndlp, retry); break; case ELS_CMD_LOGO: - if (!lpfc_issue_els_logo(phba, ndlp, retry)) { - ndlp->nlp_prev_state = ndlp->nlp_state; - ndlp->nlp_state = NLP_STE_NPR_NODE; - lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - } + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); + lpfc_issue_els_logo(phba, ndlp, retry); break; } return; @@ -1577,7 +1502,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, int retry, maxretry; int delay; uint32_t cmd; - uint32_t did; retry = 0; delay = 0; @@ -1586,7 +1510,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ndlp = (struct lpfc_nodelist *) cmdiocb->context1; pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; cmd = 0; - /* Note: context2 may be 0 for internal driver abort * of delays ELS command. */ @@ -1596,16 +1519,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, cmd = *elscmd++; } - if(ndlp) - did = ndlp->nlp_DID; - else { - /* We should only hit this case for retrying PLOGI */ - did = irsp->un.elsreq64.remoteID; - ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); - if (!ndlp && (cmd != ELS_CMD_PLOGI)) - return 1; - } - switch (irsp->ulpStatus) { case IOSTAT_FCP_RSP_ERROR: case IOSTAT_REMOTE_STOP: @@ -1624,6 +1537,11 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, case IOERR_SEQUENCE_TIMEOUT: retry = 1; + if ((cmd == ELS_CMD_FLOGI) + && (phba->fc_topology != TOPOLOGY_LOOP)) { + delay = 1; + maxretry = 48; + } break; case IOERR_NO_RESOURCES: @@ -1694,8 +1612,9 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, break; } - if (did == FDMI_DID) + if (ndlp->nlp_DID == FDMI_DID) { retry = 1; + } if ((++cmdiocb->retry) >= maxretry) { phba->fc_stat.elsRetryExceeded++; @@ -1709,7 +1628,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, "%d:0107 Retry ELS command x%x to remote " "NPORT x%x Data: x%x x%x\n", phba->brd_no, - cmd, did, cmdiocb->retry, delay); + cmd, ndlp->nlp_DID, cmdiocb->retry, delay); if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) { /* If discovery / RSCN timer is running, reset it */ @@ -1720,61 +1639,54 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } phba->fc_stat.elsXmitRetry++; - if (ndlp && delay) { + if (delay) { phba->fc_stat.elsDelayRetry++; ndlp->nlp_retry = cmdiocb->retry; mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); ndlp->nlp_flag |= NLP_DELAY_TMO; - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); ndlp->nlp_last_elscmd = cmd; - return 1; + return (1); } switch (cmd) { case ELS_CMD_FLOGI: lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); - return 1; + return (1); case ELS_CMD_PLOGI: - if (ndlp) { - ndlp->nlp_prev_state = ndlp->nlp_state; - ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - } - lpfc_issue_els_plogi(phba, did, cmdiocb->retry); - return 1; + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); + lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry); + return (1); case ELS_CMD_ADISC: - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_ADISC_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry); - return 1; + return (1); case ELS_CMD_PRLI: - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_PRLI_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry); - return 1; + return (1); case ELS_CMD_LOGO: - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry); - return 1; + return (1); } } /* No retry ELS command to remote NPORT */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0108 No retry ELS command x%x to remote NPORT x%x " - "Data: x%x\n", + "Data: x%x x%x\n", phba->brd_no, - cmd, did, cmdiocb->retry); + cmd, ndlp->nlp_DID, cmdiocb->retry, ndlp->nlp_flag); - return 0; + return (0); } int @@ -1823,6 +1735,10 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_LOGO_ACC; + spin_unlock_irq(phba->host->host_lock); + switch (ndlp->nlp_state) { case NLP_STE_UNUSED_NODE: /* node is just allocated */ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); @@ -1860,20 +1776,21 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, /* ELS response tag completes */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0110 ELS response tag x%x completes " - "Data: x%x x%x x%x x%x x%x x%x x%x\n", + "Data: x%x x%x x%x x%x x%x x%x\n", phba->brd_no, cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, - rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout, - ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, - ndlp->nlp_rpi); + rspiocb->iocb.un.ulpWord[4], ndlp->nlp_DID, + ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); if (mbox) { if ((rspiocb->iocb.ulpStatus == 0) && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { + /* set_slim mailbox command needs to execute first, + * queue this command to be processed later. + */ lpfc_unreg_rpi(phba, ndlp); mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->context2 = ndlp; - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST); if (lpfc_sli_issue_mbox(phba, mbox, @@ -1888,7 +1805,6 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, mempool_free( mbox, phba->mbox_mem_pool); if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - ndlp = NULL; } } } @@ -1915,7 +1831,6 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, uint8_t *pcmd; uint16_t cmdsize; int rc; - ELS_PKT *els_pkt_ptr; psli = &phba->sli; pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ @@ -1924,11 +1839,10 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, switch (flag) { case ELS_CMD_ACC: cmdsize = sizeof (uint32_t); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, - ndlp, ndlp->nlp_DID, ELS_CMD_ACC); - if (!elsiocb) { - ndlp->nlp_flag &= ~NLP_LOGO_ACC; - return 1; + if ((elsiocb = + lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, + ndlp, ELS_CMD_ACC)) == 0) { + return (1); } icmd = &elsiocb->iocb; icmd->ulpContext = oldcmd->ulpContext; /* Xri */ @@ -1938,11 +1852,11 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, break; case ELS_CMD_PLOGI: cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t)); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, - ndlp, ndlp->nlp_DID, ELS_CMD_ACC); - if (!elsiocb) - return 1; - + if ((elsiocb = + lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, + ndlp, ELS_CMD_ACC)) == 0) { + return (1); + } icmd = &elsiocb->iocb; icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); @@ -1954,25 +1868,8 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, pcmd += sizeof (uint32_t); memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); break; - case ELS_CMD_PRLO: - cmdsize = sizeof (uint32_t) + sizeof (PRLO); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, - ndlp, ndlp->nlp_DID, ELS_CMD_PRLO); - if (!elsiocb) - return 1; - - icmd = &elsiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri */ - pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); - - memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt, - sizeof (uint32_t) + sizeof (PRLO)); - *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC; - els_pkt_ptr = (ELS_PKT *) pcmd; - els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED; - break; default: - return 1; + return (1); } if (newnode) @@ -1988,9 +1885,6 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); if (ndlp->nlp_flag & NLP_LOGO_ACC) { - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~NLP_LOGO_ACC; - spin_unlock_irq(phba->host->host_lock); elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc; } else { elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; @@ -2002,9 +1896,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, spin_unlock_irq(phba->host->host_lock); if (rc == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } - return 0; + return (0); } int @@ -2024,10 +1918,10 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ cmdsize = 2 * sizeof (uint32_t); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, - ndlp, ndlp->nlp_DID, ELS_CMD_LS_RJT); - if (!elsiocb) - return 1; + if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, + ndlp, ELS_CMD_LS_RJT)) == 0) { + return (1); + } icmd = &elsiocb->iocb; oldcmd = &oldiocb->iocb; @@ -2054,9 +1948,9 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, spin_unlock_irq(phba->host->host_lock); if (rc == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } - return 0; + return (0); } int @@ -2077,10 +1971,10 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ cmdsize = sizeof (uint32_t) + sizeof (ADISC); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, - ndlp, ndlp->nlp_DID, ELS_CMD_ACC); - if (!elsiocb) - return 1; + if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, + ndlp, ELS_CMD_ACC)) == 0) { + return (1); + } /* Xmit ADISC ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, @@ -2112,9 +2006,9 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, spin_unlock_irq(phba->host->host_lock); if (rc == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } - return 0; + return (0); } int @@ -2136,10 +2030,13 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba, pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ cmdsize = sizeof (uint32_t) + sizeof (PRLI); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, ndlp, - ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK))); - if (!elsiocb) - return 1; + if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, + ndlp, + (ELS_CMD_ACC | + (ELS_CMD_PRLI & ~ELS_RSP_MASK)))) == + 0) { + return (1); + } /* Xmit PRLI ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, @@ -2189,9 +2086,9 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba, spin_unlock_irq(phba->host->host_lock); if (rc == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } - return 0; + return (0); } static int @@ -2217,10 +2114,10 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, if (format) cmdsize += sizeof (RNID_TOP_DISC); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, - ndlp, ndlp->nlp_DID, ELS_CMD_ACC); - if (!elsiocb) - return 1; + if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, + ndlp, ELS_CMD_ACC)) == 0) { + return (1); + } /* Xmit RNID ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, @@ -2272,9 +2169,9 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, spin_unlock_irq(phba->host->host_lock); if (rc == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); - return 1; + return (1); } - return 0; + return (0); } int @@ -2290,7 +2187,6 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba) if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { if (ndlp->nlp_flag & NLP_NPR_ADISC) { ndlp->nlp_flag &= ~NLP_NPR_ADISC; - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_ADISC_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); @@ -2312,7 +2208,7 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba) phba->fc_flag &= ~FC_NLP_MORE; spin_unlock_irq(phba->host->host_lock); } - return sentadisc; + return(sentadisc); } int @@ -2328,10 +2224,9 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && (!(ndlp->nlp_flag & NLP_DELAY_TMO))) { if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); + lpfc_issue_els_plogi(phba, ndlp, 0); sentplogi++; phba->num_disc_nodes++; if (phba->num_disc_nodes >= @@ -2349,7 +2244,7 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) phba->fc_flag &= ~FC_NLP_MORE; spin_unlock_irq(phba->host->host_lock); } - return sentplogi; + return(sentplogi); } int @@ -2369,7 +2264,7 @@ lpfc_els_flush_rscn(struct lpfc_hba * phba) phba->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); spin_unlock_irq(phba->host->host_lock); lpfc_can_disctmo(phba); - return 0; + return (0); } int @@ -2390,7 +2285,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) /* If we are doing a FULL RSCN rediscovery, match everything */ if (phba->fc_flag & FC_RSCN_DISCOVERY) { - return did; + return (did); } for (i = 0; i < phba->fc_rscn_id_cnt; i++) { @@ -2438,7 +2333,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) } } } - return match; + return (match); } static int @@ -2470,15 +2365,17 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba) lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RECOVERY); - - /* Make sure NLP_DELAY_TMO is NOT running - * after a device recovery event. - */ - if (ndlp->nlp_flag & NLP_DELAY_TMO) - lpfc_cancel_retry_delay_tmo(phba, ndlp); + if (ndlp->nlp_flag & NLP_DELAY_TMO) { + ndlp->nlp_flag &= ~NLP_DELAY_TMO; + del_timer_sync(&ndlp->nlp_delayfunc); + if (!list_empty(&ndlp-> + els_retry_evt.evt_listp)) + list_del_init(&ndlp-> + els_retry_evt.evt_listp); + } } } - return 0; + return (0); } static int @@ -2511,10 +2408,10 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, /* If we are about to begin discovery, just ACC the RSCN. * Discovery processing will satisfy it. */ - if (phba->hba_state <= LPFC_NS_QRY) { + if (phba->hba_state < LPFC_NS_QRY) { lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode); - return 0; + return (0); } /* If we are already processing an RSCN, save the received @@ -2556,7 +2453,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, /* send RECOVERY event for ALL nodes that match RSCN payload */ lpfc_rscn_recovery_check(phba); - return 0; + return (0); } phba->fc_flag |= FC_RSCN_MODE; @@ -2575,7 +2472,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, /* send RECOVERY event for ALL nodes that match RSCN payload */ lpfc_rscn_recovery_check(phba); - return lpfc_els_handle_rscn(phba); + return (lpfc_els_handle_rscn(phba)); } int @@ -2597,41 +2494,40 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) /* To process RSCN, first compare RSCN data with NameServer */ phba->fc_ns_retry = 0; - ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, NameServer_DID); - if (ndlp) { + if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, + NameServer_DID))) { /* Good ndlp, issue CT Request to NameServer */ if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { /* Wait for NameServer query cmpl before we can continue */ - return 1; + return (1); } } else { /* If login to NameServer does not exist, issue one */ /* Good status, issue PLOGI to NameServer */ - ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); - if (ndlp) { + if ((ndlp = + lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID))) { /* Wait for NameServer login cmpl before we can continue */ - return 1; + return (1); } - ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); - if (!ndlp) { + if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) + == 0) { lpfc_els_flush_rscn(phba); - return 0; + return (0); } else { lpfc_nlp_init(phba, ndlp, NameServer_DID); ndlp->nlp_type |= NLP_FABRIC; - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_issue_els_plogi(phba, NameServer_DID, 0); + lpfc_issue_els_plogi(phba, ndlp, 0); /* Wait for NameServer login cmpl before we can continue */ - return 1; + return (1); } } lpfc_els_flush_rscn(phba); - return 0; + return (0); } static int @@ -2665,7 +2561,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, "%d:0113 An FLOGI ELS command x%x was received " "from DID x%x in Loop Mode\n", phba->brd_no, cmd, did); - return 1; + return (1); } did = Fabric_DID; @@ -2681,7 +2577,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, if (!rc) { if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) == 0) { - return 1; + return (1); } lpfc_linkdown(phba); lpfc_init_link(phba, mbox, @@ -2694,8 +2590,9 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, if (rc == MBX_NOT_FINISHED) { mempool_free( mbox, phba->mbox_mem_pool); } - return 1; - } else if (rc > 0) { /* greater than */ + return (1); + } + else if (rc > 0) { /* greater than */ spin_lock_irq(phba->host->host_lock); phba->fc_flag |= FC_PT2PT_PLOGI; spin_unlock_irq(phba->host->host_lock); @@ -2709,13 +2606,13 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; stat.un.b.vendorUnique = 0; lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); - return 1; + return (1); } /* Send back ACC */ lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode); - return 0; + return (0); } static int @@ -2753,246 +2650,45 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba, stat.un.b.vendorUnique = 0; lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); } - return 0; -} - -static int -lpfc_els_rcv_lirr(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, - struct lpfc_nodelist * ndlp) -{ - struct ls_rjt stat; - - /* For now, unconditionally reject this command */ - stat.un.b.lsRjtRsvd0 = 0; - stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; - stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; - stat.un.b.vendorUnique = 0; - lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); - return 0; -} - -static void -lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) -{ - struct lpfc_sli *psli; - struct lpfc_sli_ring *pring; - MAILBOX_t *mb; - IOCB_t *icmd; - RPS_RSP *rps_rsp; - uint8_t *pcmd; - struct lpfc_iocbq *elsiocb; - struct lpfc_nodelist *ndlp; - uint16_t xri, status; - uint32_t cmdsize; - - psli = &phba->sli; - pring = &psli->ring[LPFC_ELS_RING]; - mb = &pmb->mb; - - ndlp = (struct lpfc_nodelist *) pmb->context2; - xri = (uint16_t) ((unsigned long)(pmb->context1)); - pmb->context1 = 0; - pmb->context2 = 0; - - if (mb->mbxStatus) { - mempool_free( pmb, phba->mbox_mem_pool); - return; - } - - cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); - mempool_free( pmb, phba->mbox_mem_pool); - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, - ndlp->nlp_DID, ELS_CMD_ACC); - if (!elsiocb) - return; - - icmd = &elsiocb->iocb; - icmd->ulpContext = xri; - - pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); - *((uint32_t *) (pcmd)) = ELS_CMD_ACC; - pcmd += sizeof (uint32_t); /* Skip past command */ - rps_rsp = (RPS_RSP *)pcmd; - - if (phba->fc_topology != TOPOLOGY_LOOP) - status = 0x10; - else - status = 0x8; - if (phba->fc_flag & FC_FABRIC) - status |= 0x4; - - rps_rsp->rsvd1 = 0; - rps_rsp->portStatus = be16_to_cpu(status); - rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt); - rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt); - rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt); - rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt); - rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord); - rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt); - - /* Xmit ELS RPS ACC response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0128 Xmit ELS RPS ACC response tag x%x " - "Data: x%x x%x x%x x%x x%x\n", - phba->brd_no, - elsiocb->iocb.ulpIoTag, - elsiocb->iocb.ulpContext, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - - elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; - phba->fc_stat.elsXmitACC++; - if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { - lpfc_els_free_iocb(phba, elsiocb); - } - return; + return (0); } static int -lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, +lpfc_els_rcv_rrq(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist * ndlp) { - uint32_t *lp; - uint8_t flag; - LPFC_MBOXQ_t *mbox; struct lpfc_dmabuf *pcmd; - RPS *rps; - struct ls_rjt stat; - - if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && - (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { - stat.un.b.lsRjtRsvd0 = 0; - stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; - stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; - stat.un.b.vendorUnique = 0; - lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); - } - - pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; - lp = (uint32_t *) pcmd->virt; - flag = (be32_to_cpu(*lp++) & 0xf); - rps = (RPS *) lp; - - if ((flag == 0) || - ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) || - ((flag == 2) && (memcmp(&rps->un.portName, &phba->fc_portname, - sizeof (struct lpfc_name)) == 0))) { - if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC))) { - lpfc_read_lnk_stat(phba, mbox); - mbox->context1 = - (void *)((unsigned long)cmdiocb->iocb.ulpContext); - mbox->context2 = ndlp; - mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; - if (lpfc_sli_issue_mbox (phba, mbox, - (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { - /* Mbox completion will send ELS Response */ - return 0; - } - mempool_free(mbox, phba->mbox_mem_pool); - } - } - stat.un.b.lsRjtRsvd0 = 0; - stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; - stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; - stat.un.b.vendorUnique = 0; - lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); - return 0; -} - -static int -lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, - struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp) -{ + uint32_t *lp; IOCB_t *icmd; - IOCB_t *oldcmd; - RPL_RSP rpl_rsp; - struct lpfc_iocbq *elsiocb; struct lpfc_sli_ring *pring; struct lpfc_sli *psli; - uint8_t *pcmd; + RRQ *rrq; + uint32_t cmd, did; psli = &phba->sli; - pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ - - elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, - ndlp, ndlp->nlp_DID, ELS_CMD_ACC); - if (!elsiocb) - return 1; - - icmd = &elsiocb->iocb; - oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri */ - - pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); - *((uint32_t *) (pcmd)) = ELS_CMD_ACC; - pcmd += sizeof (uint16_t); - *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize); - pcmd += sizeof(uint16_t); - - /* Setup the RPL ACC payload */ - rpl_rsp.listLen = be32_to_cpu(1); - rpl_rsp.index = 0; - rpl_rsp.port_num_blk.portNum = 0; - rpl_rsp.port_num_blk.portID = be32_to_cpu(phba->fc_myDID); - memcpy(&rpl_rsp.port_num_blk.portName, &phba->fc_portname, - sizeof(struct lpfc_name)); - - memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t)); - - - /* Xmit ELS RPL ACC response tag */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0128 Xmit ELS RPL ACC response tag x%x " - "Data: x%x x%x x%x x%x x%x\n", - phba->brd_no, - elsiocb->iocb.ulpIoTag, - elsiocb->iocb.ulpContext, ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - - elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; - - phba->fc_stat.elsXmitACC++; - if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { - lpfc_els_free_iocb(phba, elsiocb); - return 1; - } - return 0; -} - -static int -lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, - struct lpfc_nodelist * ndlp) -{ - struct lpfc_dmabuf *pcmd; - uint32_t *lp; - uint32_t maxsize; - uint16_t cmdsize; - RPL *rpl; - struct ls_rjt stat; - - if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && - (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { - stat.un.b.lsRjtRsvd0 = 0; - stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; - stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; - stat.un.b.vendorUnique = 0; - lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); - } - + pring = &psli->ring[LPFC_FCP_RING]; + icmd = &cmdiocb->iocb; + did = icmd->un.elsreq64.remoteID; pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; lp = (uint32_t *) pcmd->virt; - rpl = (RPL *) (lp + 1); - maxsize = be32_to_cpu(rpl->maxsize); + cmd = *lp++; + rrq = (RRQ *) lp; - /* We support only one port */ - if ((rpl->index == 0) && - ((maxsize == 0) || - ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) { - cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP); + /* RRQ received */ + /* Get oxid / rxid from payload and abort it */ + spin_lock_irq(phba->host->host_lock); + if ((rrq->SID == be32_to_cpu(phba->fc_myDID))) { + lpfc_sli_abort_iocb(phba, pring, 0, 0, rrq->Oxid, + LPFC_CTX_CTX); } else { - cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t); + lpfc_sli_abort_iocb(phba, pring, 0, 0, rrq->Rxid, + LPFC_CTX_CTX); } - lpfc_els_rsp_rpl_acc(phba, cmdsize, cmdiocb, ndlp); + + spin_unlock_irq(phba->host->host_lock); + /* ACCEPT the rrq request */ + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); return 0; } @@ -3024,7 +2720,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, /* We will only support match on WWPN or WWNN */ if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) { - return 0; + return (0); } cnt = 0; @@ -3047,10 +2743,9 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) { /* Log back into the node before sending the FARP. */ if (fp->Rflags & FARP_REQUEST_PLOGI) { - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); + lpfc_issue_els_plogi(phba, ndlp, 0); } /* Send a FARP response to that node */ @@ -3059,7 +2754,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, } } } - return 0; + return (0); } static int @@ -3092,89 +2787,47 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba, static int lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, - struct lpfc_nodelist * fan_ndlp) + struct lpfc_nodelist * ndlp) { struct lpfc_dmabuf *pcmd; uint32_t *lp; IOCB_t *icmd; - uint32_t cmd, did; FAN *fp; - struct lpfc_nodelist *ndlp, *next_ndlp; - - /* FAN received */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:265 FAN received\n", - phba->brd_no); + uint32_t cmd, did; icmd = &cmdiocb->iocb; did = icmd->un.elsreq64.remoteID; - pcmd = (struct lpfc_dmabuf *)cmdiocb->context2; - lp = (uint32_t *)pcmd->virt; + pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; + lp = (uint32_t *) pcmd->virt; cmd = *lp++; - fp = (FAN *)lp; + fp = (FAN *) lp; - /* FAN received; Fan does not have a reply sequence */ - - if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { - if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName, - sizeof(struct lpfc_name)) != 0) || - (memcmp(&phba->fc_fabparam.portName, &fp->FportName, - sizeof(struct lpfc_name)) != 0)) { - /* - * This node has switched fabrics. FLOGI is required - * Clean up the old rpi's - */ + /* FAN received */ - list_for_each_entry_safe(ndlp, next_ndlp, - &phba->fc_npr_list, nlp_listp) { - - if (ndlp->nlp_type & NLP_FABRIC) { - /* - * Clean up old Fabric, Nameserver and - * other NLP_FABRIC logins - */ - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { - /* Fail outstanding I/O now since this - * device is marked for PLOGI - */ - lpfc_unreg_rpi(phba, ndlp); - } - } + /* ACCEPT the FAN request */ + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); - phba->hba_state = LPFC_FLOGI; - lpfc_set_disctmo(phba); - lpfc_initial_flogi(phba); - return 0; - } - /* Discovery not needed, - * move the nodes to their original state. + if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { + /* The discovery state machine needs to take a different + * action if this node has switched fabrics */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, - nlp_listp) { - - switch (ndlp->nlp_prev_state) { - case NLP_STE_UNMAPPED_NODE: - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; - lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); - break; - - case NLP_STE_MAPPED_NODE: - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - ndlp->nlp_state = NLP_STE_MAPPED_NODE; - lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); - break; - - default: - break; - } + if ((memcmp(&fp->FportName, &phba->fc_fabparam.portName, + sizeof (struct lpfc_name)) != 0) + || + (memcmp(&fp->FnodeName, &phba->fc_fabparam.nodeName, + sizeof (struct lpfc_name)) != 0)) { + /* This node has switched fabrics. An FLOGI is required + * after the timeout + */ + return (0); } - /* Start discovery - this should just do CLEAR_LA */ + /* Start discovery */ lpfc_disc_start(phba); } - return 0; + + return (0); } void @@ -3251,9 +2904,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { struct lpfc_nodelist *ndlp; - spin_unlock_irq(phba->host->host_lock); + ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); - spin_lock_irq(phba->host->host_lock); remote_ID = ndlp->nlp_DID; if (cmd->un.elsreq64.bdl.ulpIoTag32) { lpfc_sli_issue_abort_iotag32(phba, @@ -3298,6 +2950,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) struct lpfc_dmabuf *pcmd; uint32_t *elscmd; uint32_t els_command; + uint32_t remote_ID; pring = &phba->sli.ring[LPFC_ELS_RING]; spin_lock_irq(phba->host->host_lock); @@ -3320,6 +2973,18 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) elscmd = (uint32_t *) (pcmd->virt); els_command = *elscmd; + if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { + struct lpfc_nodelist *ndlp; + + ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); + remote_ID = ndlp->nlp_DID; + if (phba->hba_state == LPFC_HBA_READY) { + continue; + } + } else { + remote_ID = cmd->un.elsreq64.remoteID; + } + list_del(&piocb->list); pring->txcmplq_cnt--; @@ -3330,7 +2995,8 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) spin_unlock_irq(phba->host->host_lock); (piocb->iocb_cmpl) (phba, piocb, piocb); spin_lock_irq(phba->host->host_lock); - } else + } + else lpfc_sli_release_iocbq(phba, piocb); } @@ -3344,6 +3010,18 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) elscmd = (uint32_t *) (pcmd->virt); els_command = *elscmd; + if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { + struct lpfc_nodelist *ndlp; + + ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); + remote_ID = ndlp->nlp_DID; + if (phba->hba_state == LPFC_HBA_READY) { + continue; + } + } else { + remote_ID = cmd->un.elsreq64.remoteID; + } + list_del(&piocb->list); pring->txcmplq_cnt--; @@ -3354,7 +3032,8 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) spin_unlock_irq(phba->host->host_lock); (piocb->iocb_cmpl) (phba, piocb, piocb); spin_lock_irq(phba->host->host_lock); - } else + } + else lpfc_sli_release_iocbq(phba, piocb); } spin_unlock_irq(phba->host->host_lock); @@ -3426,11 +3105,10 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, } did = icmd->un.rcvels.remoteID; - ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); - if (!ndlp) { + if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did)) == 0) { /* Cannot find existing Fabric ndlp, so allocate a new one */ - ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); - if (!ndlp) { + if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) + == 0) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); drop_cmd = 1; @@ -3523,6 +3201,10 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, phba->fc_stat.elsRcvFAN++; lpfc_els_rcv_fan(phba, elsiocb, ndlp); break; + case ELS_CMD_RRQ: + phba->fc_stat.elsRcvRRQ++; + lpfc_els_rcv_rrq(phba, elsiocb, ndlp); + break; case ELS_CMD_PRLI: phba->fc_stat.elsRcvPRLI++; if (phba->hba_state < LPFC_DISC_AUTH) { @@ -3531,33 +3213,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, } lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI); break; - case ELS_CMD_LIRR: - phba->fc_stat.elsRcvLIRR++; - lpfc_els_rcv_lirr(phba, elsiocb, ndlp); - if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); - } - break; - case ELS_CMD_RPS: - phba->fc_stat.elsRcvRPS++; - lpfc_els_rcv_rps(phba, elsiocb, ndlp); - if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); - } - break; - case ELS_CMD_RPL: - phba->fc_stat.elsRcvRPL++; - lpfc_els_rcv_rpl(phba, elsiocb, ndlp); - if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); - } - break; case ELS_CMD_RNID: phba->fc_stat.elsRcvRNID++; lpfc_els_rcv_rnid(phba, elsiocb, ndlp); - if (newnode) { - mempool_free( ndlp, phba->nlp_mem_pool); - } break; default: /* Unsupported ELS command, reject */ @@ -3591,9 +3249,8 @@ dropit: if (drop_cmd == 1) { lpfc_printf_log(phba, KERN_ERR, LOG_ELS, "%d:0111 Dropping received ELS cmd " - "Data: x%x x%x x%x\n", phba->brd_no, - icmd->ulpStatus, icmd->un.ulpWord[4], - icmd->ulpTimeout); + "Data: x%x x%x\n", phba->brd_no, + icmd->ulpStatus, icmd->un.ulpWord[4]); phba->fc_stat.elsRcvDrop++; } return; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index adb086009..a1f751e79 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -59,7 +59,6 @@ static void lpfc_disc_timeout_handler(struct lpfc_hba *); static void lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { - uint8_t *name = (uint8_t *)&ndlp->nlp_portname; int warn_on = 0; spin_lock_irq(phba->host->host_lock); @@ -68,15 +67,6 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) return; } - /* - * If a discovery event readded nodev_timer after timer - * firing and before processing the timer, cancel the - * nlp_tmofunc. - */ - spin_unlock_irq(phba->host->host_lock); - del_timer_sync(&ndlp->nlp_tmofunc); - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~NLP_NODEV_TMO; if (ndlp->nlp_sid != NLP_NO_SID) { @@ -89,23 +79,15 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) if (warn_on) { lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d:0203 Nodev timeout on " - "WWPN %x:%x:%x:%x:%x:%x:%x:%x " - "NPort x%x Data: x%x x%x x%x\n", - phba->brd_no, - *name, *(name+1), *(name+2), *(name+3), - *(name+4), *(name+5), *(name+6), *(name+7), - ndlp->nlp_DID, ndlp->nlp_flag, + "%d:0203 Nodev timeout on NPort x%x " + "Data: x%x x%x x%x\n", + phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); } else { lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d:0204 Nodev timeout on " - "WWPN %x:%x:%x:%x:%x:%x:%x:%x " - "NPort x%x Data: x%x x%x x%x\n", - phba->brd_no, - *name, *(name+1), *(name+2), *(name+3), - *(name+4), *(name+5), *(name+6), *(name+7), - ndlp->nlp_DID, ndlp->nlp_flag, + "%d:0204 Nodev timeout on NPort x%x " + "Data: x%x x%x x%x\n", + phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); } @@ -126,7 +108,7 @@ lpfc_work_list_done(struct lpfc_hba * phba) evt_listp); spin_unlock_irq(phba->host->host_lock); free_evt = 1; - switch (evtp->evt) { + switch(evtp->evt) { case LPFC_EVT_NODEV_TMO: ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); lpfc_process_nodev_timeout(phba, ndlp); @@ -138,35 +120,11 @@ lpfc_work_list_done(struct lpfc_hba * phba) free_evt = 0; break; case LPFC_EVT_ONLINE: - if (phba->hba_state < LPFC_LINK_DOWN) - *(int *)(evtp->evt_arg1) = lpfc_online(phba); - else - *(int *)(evtp->evt_arg1) = 0; + *(int *)(evtp->evt_arg1) = lpfc_online(phba); complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_OFFLINE: - if (phba->hba_state >= LPFC_LINK_DOWN) - lpfc_offline(phba); - lpfc_sli_brdrestart(phba); - *(int *)(evtp->evt_arg1) = - lpfc_sli_brdready(phba,HS_FFRDY | HS_MBRDY); - complete((struct completion *)(evtp->evt_arg2)); - break; - case LPFC_EVT_WARM_START: - if (phba->hba_state >= LPFC_LINK_DOWN) - lpfc_offline(phba); - lpfc_reset_barrier(phba); - lpfc_sli_brdreset(phba); - lpfc_hba_down_post(phba); - *(int *)(evtp->evt_arg1) = - lpfc_sli_brdready(phba, HS_MBRDY); - complete((struct completion *)(evtp->evt_arg2)); - break; - case LPFC_EVT_KILL: - if (phba->hba_state >= LPFC_LINK_DOWN) - lpfc_offline(phba); - *(int *)(evtp->evt_arg1) - = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba); + *(int *)(evtp->evt_arg1) = lpfc_offline(phba); complete((struct completion *)(evtp->evt_arg2)); break; } @@ -193,13 +151,13 @@ lpfc_work_done(struct lpfc_hba * phba) work_hba_events=phba->work_hba_events; spin_unlock_irq(phba->host->host_lock); - if (ha_copy & HA_ERATT) + if(ha_copy & HA_ERATT) lpfc_handle_eratt(phba); - if (ha_copy & HA_MBATT) + if(ha_copy & HA_MBATT) lpfc_sli_handle_mb_event(phba); - if (ha_copy & HA_LATT) + if(ha_copy & HA_LATT) lpfc_handle_latt(phba); if (work_hba_events & WORKER_DISC_TMO) @@ -311,8 +269,8 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, evtp->evt_arg2 = arg2; evtp->evt = evt; - spin_lock_irq(phba->host->host_lock); list_add_tail(&evtp->evt_listp, &phba->work_list); + spin_lock_irq(phba->host->host_lock); if (phba->work_wait) wake_up(phba->work_wait); spin_unlock_irq(phba->host->host_lock); @@ -325,20 +283,16 @@ lpfc_linkdown(struct lpfc_hba * phba) { struct lpfc_sli *psli; struct lpfc_nodelist *ndlp, *next_ndlp; - struct list_head *listp, *node_list[7]; + struct list_head *listp; + struct list_head *node_list[7]; LPFC_MBOXQ_t *mb; int rc, i; psli = &phba->sli; - /* sysfs or selective reset may call this routine to clean up */ - if (phba->hba_state >= LPFC_LINK_DOWN) { - if (phba->hba_state == LPFC_LINK_DOWN) - return 0; - spin_lock_irq(phba->host->host_lock); - phba->hba_state = LPFC_LINK_DOWN; - spin_unlock_irq(phba->host->host_lock); - } + spin_lock_irq(phba->host->host_lock); + phba->hba_state = LPFC_LINK_DOWN; + spin_unlock_irq(phba->host->host_lock); /* Clean up any firmware default rpi's */ if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { @@ -370,19 +324,32 @@ lpfc_linkdown(struct lpfc_hba * phba) continue; list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { - - rc = lpfc_disc_state_machine(phba, ndlp, NULL, - NLP_EVT_DEVICE_RECOVERY); - - /* Check config parameter use-adisc or FCP-2 */ - if ((rc != NLP_STE_FREED_NODE) && - (phba->cfg_use_adisc == 0) && - !(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) { - /* We know we will have to relogin, so - * unreglogin the rpi right now to fail - * any outstanding I/Os quickly. - */ - lpfc_unreg_rpi(phba, ndlp); + /* Fabric nodes are not handled thru state machine for + link down */ + if (ndlp->nlp_type & NLP_FABRIC) { + /* Remove ALL Fabric nodes except Fabric_DID */ + if (ndlp->nlp_DID != Fabric_DID) { + /* Take it off current list and free */ + lpfc_nlp_list(phba, ndlp, + NLP_NO_LIST); + } + } + else { + + rc = lpfc_disc_state_machine(phba, ndlp, NULL, + NLP_EVT_DEVICE_RECOVERY); + + /* Check config parameter use-adisc or FCP-2 */ + if ((rc != NLP_STE_FREED_NODE) && + (phba->cfg_use_adisc == 0) && + !(ndlp->nlp_fcp_info & + NLP_FCP_2_DEVICE)) { + /* We know we will have to relogin, so + * unreglogin the rpi right now to fail + * any outstanding I/Os quickly. + */ + lpfc_unreg_rpi(phba, ndlp); + } } } } @@ -417,15 +384,13 @@ lpfc_linkdown(struct lpfc_hba * phba) lpfc_can_disctmo(phba); /* Must process IOCBs on all rings to handle ABORTed I/Os */ - return 0; + return (0); } static int lpfc_linkup(struct lpfc_hba * phba) { struct lpfc_nodelist *ndlp, *next_ndlp; - struct list_head *listp, *node_list[7]; - int i; spin_lock_irq(phba->host->host_lock); phba->hba_state = LPFC_LINK_UP; @@ -436,33 +401,14 @@ lpfc_linkup(struct lpfc_hba * phba) spin_unlock_irq(phba->host->host_lock); - node_list[0] = &phba->fc_plogi_list; - node_list[1] = &phba->fc_adisc_list; - node_list[2] = &phba->fc_reglogin_list; - node_list[3] = &phba->fc_prli_list; - node_list[4] = &phba->fc_nlpunmap_list; - node_list[5] = &phba->fc_nlpmap_list; - node_list[6] = &phba->fc_npr_list; - for (i = 0; i < 7; i++) { - listp = node_list[i]; - if (list_empty(listp)) - continue; - - list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { - if (phba->fc_flag & FC_LBIT) { - if (ndlp->nlp_type & NLP_FABRIC) { - /* On Linkup its safe to clean up the - * ndlp from Fabric connections. - */ - lpfc_nlp_list(phba, ndlp, - NLP_UNUSED_LIST); - } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { - /* Fail outstanding IO now since device - * is marked for PLOGI. - */ - lpfc_unreg_rpi(phba, ndlp); - } - } + /* + * Clean up old Fabric NLP_FABRIC logins. + */ + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, + nlp_listp) { + if (ndlp->nlp_DID == Fabric_DID) { + /* Take it off current list and free */ + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } } @@ -516,7 +462,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_els_disc_plogi(phba); } - if (!phba->num_disc_nodes) { + if(!phba->num_disc_nodes) { spin_lock_irq(phba->host->host_lock); phba->fc_flag &= ~FC_NDISC_ACTIVE; spin_unlock_irq(phba->host->host_lock); @@ -558,59 +504,80 @@ out: } static void -lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) +lpfc_mbx_cmpl_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { - struct lpfc_sli *psli = &phba->sli; - int rc; + struct lpfc_sli *psli; + MAILBOX_t *mb; - if (pmb->mb.mbxStatus) - goto out; + psli = &phba->sli; + mb = &pmb->mb; + /* Check for error */ + if (mb->mbxStatus) { + /* CONFIG_LINK mbox error state */ + lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, + "%d:0306 CONFIG_LINK mbxStatus error x%x " + "HBA state x%x\n", + phba->brd_no, mb->mbxStatus, phba->hba_state); - mempool_free(pmb, phba->mbox_mem_pool); + lpfc_linkdown(phba); + phba->hba_state = LPFC_HBA_ERROR; + goto out; + } - if (phba->fc_topology == TOPOLOGY_LOOP && - phba->fc_flag & FC_PUBLIC_LOOP && - !(phba->fc_flag & FC_LBIT)) { - /* Need to wait for FAN - use discovery timer - * for timeout. hba_state is identically - * LPFC_LOCAL_CFG_LINK while waiting for FAN - */ - lpfc_set_disctmo(phba); - return; + if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { + if (phba->fc_topology == TOPOLOGY_LOOP) { + /* If we are public loop and L bit was set */ + if ((phba->fc_flag & FC_PUBLIC_LOOP) && + !(phba->fc_flag & FC_LBIT)) { + /* Need to wait for FAN - use discovery timer + * for timeout. hba_state is identically + * LPFC_LOCAL_CFG_LINK while waiting for FAN + */ + lpfc_set_disctmo(phba); + mempool_free( pmb, phba->mbox_mem_pool); + return; + } } - /* Start discovery by sending a FLOGI. hba_state is identically - * LPFC_FLOGI while waiting for FLOGI cmpl - */ - phba->hba_state = LPFC_FLOGI; - lpfc_set_disctmo(phba); - lpfc_initial_flogi(phba); - return; + /* Start discovery by sending a FLOGI hba_state is identically + * LPFC_FLOGI while waiting for FLOGI cmpl + */ + phba->hba_state = LPFC_FLOGI; + lpfc_set_disctmo(phba); + lpfc_initial_flogi(phba); + mempool_free( pmb, phba->mbox_mem_pool); + return; + } + if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { + mempool_free( pmb, phba->mbox_mem_pool); + return; + } out: - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "%d:0306 CONFIG_LINK mbxStatus error x%x " - "HBA state x%x\n", - phba->brd_no, pmb->mb.mbxStatus, phba->hba_state); - - lpfc_linkdown(phba); - - phba->hba_state = LPFC_HBA_ERROR; - - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, + /* CONFIG_LINK bad hba state */ + lpfc_printf_log(phba, + KERN_ERR, + LOG_DISCOVERY, "%d:0200 CONFIG_LINK bad hba state x%x\n", phba->brd_no, phba->hba_state); - lpfc_clear_la(phba, pmb); - pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; - rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); - if (rc == MBX_NOT_FINISHED) { - mempool_free(pmb, phba->mbox_mem_pool); - lpfc_disc_flush_list(phba); - psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; - psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; - psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; - phba->hba_state = LPFC_HBA_READY; + if (phba->hba_state != LPFC_CLEAR_LA) { + lpfc_clear_la(phba, pmb); + pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; + if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)) + == MBX_NOT_FINISHED) { + mempool_free( pmb, phba->mbox_mem_pool); + lpfc_disc_flush_list(phba); + psli->ring[(psli->ip_ring)].flag &= + ~LPFC_STOP_IOCB_EVENT; + psli->ring[(psli->fcp_ring)].flag &= + ~LPFC_STOP_IOCB_EVENT; + psli->ring[(psli->next_ring)].flag &= + ~LPFC_STOP_IOCB_EVENT; + phba->hba_state = LPFC_HBA_READY; + } + } else { + mempool_free( pmb, phba->mbox_mem_pool); } return; } @@ -683,7 +650,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); spin_lock_irq(phba->host->host_lock); - switch (la->UlnkSpeed) { + switch(la->UlnkSpeed) { case LA_1GHZ_LINK: phba->fc_linkspeed = LA_1GHZ_LINK; break; @@ -764,7 +731,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) if (cfglink_mbox) { phba->hba_state = LPFC_LOCAL_CFG_LINK; lpfc_config_link(phba, cfglink_mbox); - cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; + cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_config_link; lpfc_sli_issue_mbox(phba, cfglink_mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); } @@ -817,13 +784,6 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) memcpy(&phba->alpa_map[0], mp->virt, 128); - spin_lock_irq(phba->host->host_lock); - if (la->pb) - phba->fc_flag |= FC_BYPASSED_MODE; - else - phba->fc_flag &= ~FC_BYPASSED_MODE; - spin_unlock_irq(phba->host->host_lock); - if (((phba->fc_eventTag + 1) < la->eventTag) || (phba->fc_eventTag == la->eventTag)) { phba->fc_stat.LinkMultiEvent++; @@ -944,36 +904,32 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) */ lpfc_issue_els_scr(phba, SCR_DID, 0); - ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); - if (!ndlp) { - /* Allocate a new node instance. If the pool is empty, - * start the discovery process and skip the Nameserver - * login process. This is attempted again later on. - * Otherwise, issue a Port Login (PLOGI) to NameServer. - */ - ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); - if (!ndlp) { - lpfc_disc_start(phba); - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); - mempool_free( pmb, phba->mbox_mem_pool); - return; - } else { - lpfc_nlp_init(phba, ndlp, NameServer_DID); - ndlp->nlp_type |= NLP_FABRIC; - } - } - ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - lpfc_issue_els_plogi(phba, NameServer_DID, 0); - if (phba->cfg_fdmi_on) { - ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, - GFP_KERNEL); - if (ndlp_fdmi) { - lpfc_nlp_init(phba, ndlp_fdmi, FDMI_DID); - ndlp_fdmi->nlp_type |= NLP_FABRIC; - ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_issue_els_plogi(phba, FDMI_DID, 0); + /* Allocate a new node instance. If the pool is empty, just + * start the discovery process and skip the Nameserver login + * process. This is attempted again later on. Otherwise, issue + * a Port Login (PLOGI) to the NameServer + */ + if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) + == 0) { + lpfc_disc_start(phba); + } else { + lpfc_nlp_init(phba, ndlp, NameServer_DID); + ndlp->nlp_type |= NLP_FABRIC; + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); + lpfc_issue_els_plogi(phba, ndlp, 0); + if (phba->cfg_fdmi_on) { + if ((ndlp_fdmi = mempool_alloc( + phba->nlp_mem_pool, + GFP_KERNEL))) { + lpfc_nlp_init(phba, ndlp_fdmi, + FDMI_DID); + ndlp_fdmi->nlp_type |= NLP_FABRIC; + ndlp_fdmi->nlp_state = + NLP_STE_PLOGI_ISSUE; + lpfc_issue_els_plogi(phba, ndlp_fdmi, + 0); + } } } } @@ -981,6 +937,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free( pmb, phba->mbox_mem_pool); + return; } @@ -1071,6 +1028,10 @@ lpfc_register_remote_port(struct lpfc_hba * phba, /* initialize static port data */ rport->maxframe_size = ndlp->nlp_maxframe; rport->supported_classes = ndlp->nlp_class_sup; + if ((rport->scsi_target_id != -1) && + (rport->scsi_target_id < MAX_FCP_TARGET)) { + ndlp->nlp_sid = rport->scsi_target_id; + } rdata = rport->dd_data; rdata->pnode = ndlp; @@ -1083,10 +1044,6 @@ lpfc_register_remote_port(struct lpfc_hba * phba, if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) fc_remote_port_rolechg(rport, rport_ids.roles); - if ((rport->scsi_target_id != -1) && - (rport->scsi_target_id < MAX_FCP_TARGET)) { - ndlp->nlp_sid = rport->scsi_target_id; - } return; } @@ -1113,12 +1070,12 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) psli = &phba->sli; /* Sanity check to ensure we are not moving to / from the same list */ - if ((nlp->nlp_flag & NLP_LIST_MASK) == list) + if ((nlp->nlp_flag & NLP_LIST_MASK) == list) { if (list != NLP_NO_LIST) - return 0; + return(0); + } - spin_lock_irq(phba->host->host_lock); - switch (nlp->nlp_flag & NLP_LIST_MASK) { + switch(nlp->nlp_flag & NLP_LIST_MASK) { case NLP_NO_LIST: /* Not on any list */ break; case NLP_UNUSED_LIST: @@ -1144,8 +1101,10 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) case NLP_UNMAPPED_LIST: phba->fc_unmap_cnt--; list_del(&nlp->nlp_listp); + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; nlp->nlp_type &= ~NLP_FC_NODE; + spin_unlock_irq(phba->host->host_lock); phba->nport_event_cnt++; if (nlp->rport) rport_del = unmapped; @@ -1163,14 +1122,19 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) /* Stop delay tmo if taking node off NPR list */ if ((nlp->nlp_flag & NLP_DELAY_TMO) && (list != NLP_NPR_LIST)) { - spin_unlock_irq(phba->host->host_lock); - lpfc_cancel_retry_delay_tmo(phba, nlp); spin_lock_irq(phba->host->host_lock); + nlp->nlp_flag &= ~NLP_DELAY_TMO; + spin_unlock_irq(phba->host->host_lock); + del_timer_sync(&nlp->nlp_delayfunc); + if (!list_empty(&nlp->els_retry_evt.evt_listp)) + list_del_init(&nlp->els_retry_evt.evt_listp); } break; } + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag &= ~NLP_LIST_MASK; + spin_unlock_irq(phba->host->host_lock); /* Add NPort to list */ lpfc_printf_log(phba, @@ -1180,40 +1144,48 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) phba->brd_no, nlp->nlp_DID, list, nlp->nlp_flag); - switch (list) { + switch(list) { case NLP_NO_LIST: /* No list, just remove it */ - spin_unlock_irq(phba->host->host_lock); lpfc_nlp_remove(phba, nlp); - spin_lock_irq(phba->host->host_lock); /* as node removed - stop further transport calls */ rport_del = none; break; case NLP_UNUSED_LIST: + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= list; + spin_unlock_irq(phba->host->host_lock); /* Put it at the end of the unused list */ list_add_tail(&nlp->nlp_listp, &phba->fc_unused_list); phba->fc_unused_cnt++; break; case NLP_PLOGI_LIST: + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= list; + spin_unlock_irq(phba->host->host_lock); /* Put it at the end of the plogi list */ list_add_tail(&nlp->nlp_listp, &phba->fc_plogi_list); phba->fc_plogi_cnt++; break; case NLP_ADISC_LIST: + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= list; + spin_unlock_irq(phba->host->host_lock); /* Put it at the end of the adisc list */ list_add_tail(&nlp->nlp_listp, &phba->fc_adisc_list); phba->fc_adisc_cnt++; break; case NLP_REGLOGIN_LIST: + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= list; + spin_unlock_irq(phba->host->host_lock); /* Put it at the end of the reglogin list */ list_add_tail(&nlp->nlp_listp, &phba->fc_reglogin_list); phba->fc_reglogin_cnt++; break; case NLP_PRLI_LIST: + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= list; + spin_unlock_irq(phba->host->host_lock); /* Put it at the end of the prli list */ list_add_tail(&nlp->nlp_listp, &phba->fc_prli_list); phba->fc_prli_cnt++; @@ -1222,28 +1194,31 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) rport_add = unmapped; /* ensure all vestiges of "mapped" significance are gone */ nlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= list; + spin_unlock_irq(phba->host->host_lock); /* Put it at the end of the unmap list */ list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list); phba->fc_unmap_cnt++; phba->nport_event_cnt++; /* stop nodev tmo if running */ if (nlp->nlp_flag & NLP_NODEV_TMO) { + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag &= ~NLP_NODEV_TMO; spin_unlock_irq(phba->host->host_lock); del_timer_sync(&nlp->nlp_tmofunc); - spin_lock_irq(phba->host->host_lock); if (!list_empty(&nlp->nodev_timeout_evt.evt_listp)) list_del_init(&nlp->nodev_timeout_evt. evt_listp); } - nlp->nlp_flag &= ~NLP_NODEV_REMOVE; nlp->nlp_type |= NLP_FC_NODE; break; case NLP_MAPPED_LIST: rport_add = mapped; + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= list; + spin_unlock_irq(phba->host->host_lock); /* Put it at the end of the map list */ list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list); phba->fc_map_cnt++; @@ -1251,35 +1226,41 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) /* stop nodev tmo if running */ if (nlp->nlp_flag & NLP_NODEV_TMO) { nlp->nlp_flag &= ~NLP_NODEV_TMO; - spin_unlock_irq(phba->host->host_lock); del_timer_sync(&nlp->nlp_tmofunc); - spin_lock_irq(phba->host->host_lock); if (!list_empty(&nlp->nodev_timeout_evt.evt_listp)) list_del_init(&nlp->nodev_timeout_evt. evt_listp); } - nlp->nlp_flag &= ~NLP_NODEV_REMOVE; break; case NLP_NPR_LIST: + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= list; + spin_unlock_irq(phba->host->host_lock); /* Put it at the end of the npr list */ list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list); phba->fc_npr_cnt++; - if (!(nlp->nlp_flag & NLP_NODEV_TMO)) + /* + * Sanity check for Fabric entity. + * Set nodev_tmo for NPR state, for Fabric use 1 sec. + */ + if (nlp->nlp_type & NLP_FABRIC) { + mod_timer(&nlp->nlp_tmofunc, jiffies + HZ); + } + else { mod_timer(&nlp->nlp_tmofunc, - jiffies + HZ * phba->cfg_nodev_tmo); - + jiffies + HZ * phba->cfg_nodev_tmo); + } + spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= NLP_NODEV_TMO; nlp->nlp_flag &= ~NLP_RCV_PLOGI; + spin_unlock_irq(phba->host->host_lock); break; case NLP_JUST_DQ: break; } - spin_unlock_irq(phba->host->host_lock); - /* * We make all the calls into the transport after we have * moved the node between lists. This so that we don't @@ -1322,7 +1303,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) } } } - return 0; + return (0); } /* @@ -1333,15 +1314,7 @@ lpfc_set_disctmo(struct lpfc_hba * phba) { uint32_t tmo; - if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { - /* For FAN, timeout should be greater then edtov */ - tmo = (((phba->fc_edtov + 999) / 1000) + 1); - } else { - /* Normal discovery timeout should be > then ELS/CT timeout - * FC spec states we need 3 * ratov for CT requests - */ - tmo = ((phba->fc_ratov * 3) + 3); - } + tmo = ((phba->fc_ratov * 2) + 1); mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo); spin_lock_irq(phba->host->host_lock); @@ -1381,7 +1354,7 @@ lpfc_can_disctmo(struct lpfc_hba * phba) phba->brd_no, phba->hba_state, phba->fc_flag, phba->fc_plogi_cnt, phba->fc_adisc_cnt); - return 0; + return (0); } /* @@ -1402,13 +1375,11 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, switch (icmd->ulpCommand) { case CMD_GEN_REQUEST64_CR: if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) - return 1; + return (1); case CMD_ELS_REQUEST64_CR: - if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID) - return 1; case CMD_XMIT_ELS_RSP64_CX: if (iocb->context1 == (uint8_t *) ndlp) - return 1; + return (1); } } else if (pring->ringno == psli->ip_ring) { @@ -1416,15 +1387,15 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, /* Skip match check if waiting to relogin to FCP target */ if ((ndlp->nlp_type & NLP_FCP_TARGET) && (ndlp->nlp_flag & NLP_DELAY_TMO)) { - return 0; + return (0); } if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) { - return 1; + return (1); } } else if (pring->ringno == psli->next_ring) { } - return 0; + return (0); } /* @@ -1485,7 +1456,7 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) } } - return 0; + return (0); } /* @@ -1576,7 +1547,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) spin_unlock_irq(phba->host->host_lock); del_timer_sync(&ndlp->nlp_tmofunc); - ndlp->nlp_last_elscmd = 0; del_timer_sync(&ndlp->nlp_delayfunc); if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp)) @@ -1586,7 +1556,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_unreg_rpi(phba, ndlp); - return 0; + return (0); } /* @@ -1609,18 +1579,24 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) if (ndlp->nlp_flag & NLP_DELAY_TMO) { - lpfc_cancel_retry_delay_tmo(phba, ndlp); + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_DELAY_TMO; + spin_unlock_irq(phba->host->host_lock); + del_timer_sync(&ndlp->nlp_delayfunc); + if (!list_empty(&ndlp->els_retry_evt.evt_listp)) + list_del_init(&ndlp->els_retry_evt.evt_listp); } if (ndlp->nlp_disc_refcnt) { spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag |= NLP_DELAY_REMOVE; spin_unlock_irq(phba->host->host_lock); - } else { + } + else { lpfc_freenode(phba, ndlp); mempool_free( ndlp, phba->nlp_mem_pool); } - return 0; + return(0); } static int @@ -1631,20 +1607,20 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) D_ID matchdid; if (did == Bcast_DID) - return 0; + return (0); if (ndlp->nlp_DID == 0) { - return 0; + return (0); } /* First check for Direct match */ if (ndlp->nlp_DID == did) - return 1; + return (1); /* Next check for area/domain identically equals 0 match */ mydid.un.word = phba->fc_myDID; if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { - return 0; + return (0); } matchdid.un.word = did; @@ -1655,9 +1631,9 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) if ((ndlpdid.un.b.domain == 0) && (ndlpdid.un.b.area == 0)) { if (ndlpdid.un.b.id) - return 1; + return (1); } - return 0; + return (0); } matchdid.un.word = ndlp->nlp_DID; @@ -1666,11 +1642,11 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) if ((matchdid.un.b.domain == 0) && (matchdid.un.b.area == 0)) { if (matchdid.un.b.id) - return 1; + return (1); } } } - return 0; + return (0); } /* Search for a nodelist entry on a specific list */ @@ -1680,7 +1656,6 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) struct lpfc_nodelist *ndlp, *next_ndlp; uint32_t data1; - spin_lock_irq(phba->host->host_lock); if (order & NLP_SEARCH_UNMAPPED) { list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, nlp_listp) { @@ -1696,8 +1671,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) phba->brd_no, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + return (ndlp); } } } @@ -1718,8 +1692,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) phba->brd_no, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + return (ndlp); } } } @@ -1741,8 +1714,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) phba->brd_no, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + return (ndlp); } } } @@ -1764,8 +1736,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) phba->brd_no, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + return (ndlp); } } } @@ -1787,8 +1758,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) phba->brd_no, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + return (ndlp); } } } @@ -1810,8 +1780,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) phba->brd_no, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + return (ndlp); } } } @@ -1833,8 +1802,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) phba->brd_no, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + return (ndlp); } } } @@ -1856,14 +1824,11 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) phba->brd_no, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + return (ndlp); } } } - spin_unlock_irq(phba->host->host_lock); - /* FIND node did NOT FOUND */ lpfc_printf_log(phba, KERN_INFO, @@ -1881,9 +1846,8 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) struct lpfc_nodelist *ndlp; uint32_t flg; - ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); - if (!ndlp) { - if ((phba->fc_flag & FC_RSCN_MODE) && + if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did)) == 0) { + if ((phba->hba_state == LPFC_HBA_READY) && ((lpfc_rscn_payload_check(phba, did) == 0))) return NULL; ndlp = (struct lpfc_nodelist *) @@ -1896,21 +1860,22 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) ndlp->nlp_flag |= NLP_NPR_2B_DISC; return ndlp; } - if (phba->fc_flag & FC_RSCN_MODE) { + if ((phba->hba_state == LPFC_HBA_READY) && + (phba->fc_flag & FC_RSCN_MODE)) { if (lpfc_rscn_payload_check(phba, did)) { ndlp->nlp_flag |= NLP_NPR_2B_DISC; - - /* Since this node is marked for discovery, - * delay timeout is not needed. - */ - if (ndlp->nlp_flag & NLP_DELAY_TMO) - lpfc_cancel_retry_delay_tmo(phba, ndlp); - } else + } + else { + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp = NULL; - } else { + } + } + else { flg = ndlp->nlp_flag & NLP_LIST_MASK; - if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST)) + if ((flg == NLP_ADISC_LIST) || + (flg == NLP_PLOGI_LIST)) { return NULL; + } ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); ndlp->nlp_flag |= NLP_NPR_2B_DISC; @@ -2058,7 +2023,8 @@ lpfc_disc_start(struct lpfc_hba * phba) spin_lock_irq(phba->host->host_lock); phba->fc_flag &= ~FC_RSCN_MODE; spin_unlock_irq(phba->host->host_lock); - } else + } + else lpfc_els_handle_rscn(phba); } } @@ -2208,7 +2174,7 @@ static void lpfc_disc_timeout_handler(struct lpfc_hba *phba) { struct lpfc_sli *psli; - struct lpfc_nodelist *ndlp, *next_ndlp; + struct lpfc_nodelist *ndlp; LPFC_MBOXQ_t *clearlambox, *initlinkmbox; int rc, clrlaerr = 0; @@ -2235,19 +2201,10 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) "%d:0221 FAN timeout\n", phba->brd_no); - /* Start discovery by sending FLOGI, clean up old rpis */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, - nlp_listp) { - if (ndlp->nlp_type & NLP_FABRIC) { - /* Clean up the ndlp on Fabric connections */ - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { - /* Fail outstanding IO now since device - * is marked for PLOGI. - */ - lpfc_unreg_rpi(phba, ndlp); - } - } + /* Forget about FAN, Start discovery by sending a FLOGI + * hba_state is identically LPFC_FLOGI while waiting for FLOGI + * cmpl + */ phba->hba_state = LPFC_FLOGI; lpfc_set_disctmo(phba); lpfc_initial_flogi(phba); @@ -2513,57 +2470,11 @@ lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) &phba->fc_reglogin_list}; int i; - spin_lock_irq(phba->host->host_lock); for (i = 0; i < ARRAY_SIZE(lists); i++ ) list_for_each_entry(ndlp, lists[i], nlp_listp) - if (ndlp->nlp_rpi == rpi) { - spin_unlock_irq(phba->host->host_lock); - return ndlp; - } - spin_unlock_irq(phba->host->host_lock); - return NULL; -} + if (ndlp->nlp_rpi == rpi) + return (ndlp); -/* - * This routine looks up the ndlp lists - * for the given WWPN. If WWPN found - * it return the node list pointer - * else return NULL. - */ -struct lpfc_nodelist * -lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order, - struct lpfc_name * wwpn) -{ - struct lpfc_nodelist *ndlp; - struct list_head * lists[]={&phba->fc_nlpunmap_list, - &phba->fc_nlpmap_list, - &phba->fc_npr_list, - &phba->fc_plogi_list, - &phba->fc_adisc_list, - &phba->fc_reglogin_list, - &phba->fc_prli_list}; - uint32_t search[]={NLP_SEARCH_UNMAPPED, - NLP_SEARCH_MAPPED, - NLP_SEARCH_NPR, - NLP_SEARCH_PLOGI, - NLP_SEARCH_ADISC, - NLP_SEARCH_REGLOGIN, - NLP_SEARCH_PRLI}; - int i; - - spin_lock_irq(phba->host->host_lock); - for (i = 0; i < ARRAY_SIZE(lists); i++ ) { - if (!(order & search[i])) - continue; - list_for_each_entry(ndlp, lists[i], nlp_listp) { - if (memcmp(&ndlp->nlp_portname, wwpn, - sizeof(struct lpfc_name)) == 0) { - spin_unlock_irq(phba->host->host_lock); - return ndlp; - } - } - } - spin_unlock_irq(phba->host->host_lock); return NULL; } diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index eedf98801..1ea565e05 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -449,19 +449,15 @@ struct serv_parm { /* Structure is in Big Endian format */ #define ELS_CMD_RRQ 0x12000000 #define ELS_CMD_PRLI 0x20100014 #define ELS_CMD_PRLO 0x21100014 -#define ELS_CMD_PRLO_ACC 0x02100014 #define ELS_CMD_PDISC 0x50000000 #define ELS_CMD_FDISC 0x51000000 #define ELS_CMD_ADISC 0x52000000 #define ELS_CMD_FARP 0x54000000 #define ELS_CMD_FARPR 0x55000000 -#define ELS_CMD_RPS 0x56000000 -#define ELS_CMD_RPL 0x57000000 #define ELS_CMD_FAN 0x60000000 #define ELS_CMD_RSCN 0x61040000 #define ELS_CMD_SCR 0x62000000 #define ELS_CMD_RNID 0x78000000 -#define ELS_CMD_LIRR 0x7A000000 #else /* __LITTLE_ENDIAN_BITFIELD */ #define ELS_CMD_MASK 0xffff #define ELS_RSP_MASK 0xff @@ -485,19 +481,15 @@ struct serv_parm { /* Structure is in Big Endian format */ #define ELS_CMD_RRQ 0x12 #define ELS_CMD_PRLI 0x14001020 #define ELS_CMD_PRLO 0x14001021 -#define ELS_CMD_PRLO_ACC 0x14001002 #define ELS_CMD_PDISC 0x50 #define ELS_CMD_FDISC 0x51 #define ELS_CMD_ADISC 0x52 #define ELS_CMD_FARP 0x54 #define ELS_CMD_FARPR 0x55 -#define ELS_CMD_RPS 0x56 -#define ELS_CMD_RPL 0x57 #define ELS_CMD_FAN 0x60 #define ELS_CMD_RSCN 0x0461 #define ELS_CMD_SCR 0x62 #define ELS_CMD_RNID 0x78 -#define ELS_CMD_LIRR 0x7A #endif /* @@ -766,40 +758,12 @@ typedef struct _RNID { /* Structure is in Big Endian format */ } un; } RNID; -typedef struct _RPS { /* Structure is in Big Endian format */ - union { - uint32_t portNum; - struct lpfc_name portName; - } un; -} RPS; - -typedef struct _RPS_RSP { /* Structure is in Big Endian format */ - uint16_t rsvd1; - uint16_t portStatus; - uint32_t linkFailureCnt; - uint32_t lossSyncCnt; - uint32_t lossSignalCnt; - uint32_t primSeqErrCnt; - uint32_t invalidXmitWord; - uint32_t crcCnt; -} RPS_RSP; - -typedef struct _RPL { /* Structure is in Big Endian format */ - uint32_t maxsize; - uint32_t index; -} RPL; - -typedef struct _PORT_NUM_BLK { - uint32_t portNum; - uint32_t portID; - struct lpfc_name portName; -} PORT_NUM_BLK; - -typedef struct _RPL_RSP { /* Structure is in Big Endian format */ - uint32_t listLen; - uint32_t index; - PORT_NUM_BLK port_num_blk; -} RPL_RSP; +typedef struct _RRQ { /* Structure is in Big Endian format */ + uint32_t SID; + uint16_t Oxid; + uint16_t Rxid; + uint8_t resv[32]; /* optional association hdr */ +} RRQ; /* This is used for RSCN command */ typedef struct _D_ID { /* Structure is in Big Endian format */ @@ -840,6 +804,7 @@ typedef struct _ELS_PKT { /* Structure is in Big Endian format */ FARP farp; /* Payload for FARP/ACC */ FAN fan; /* Payload for FAN */ SCR scr; /* Payload for SCR/ACC */ + RRQ rrq; /* Payload for RRQ */ RNID rnid; /* Payload for RNID */ uint8_t pad[128 - 4]; /* Pad out to payload of 128 bytes */ } un; @@ -1235,9 +1200,7 @@ typedef struct { /* FireFly BIU registers */ #define MBX_SET_MASK 0x20 #define MBX_SET_SLIM 0x21 #define MBX_UNREG_D_ID 0x23 -#define MBX_KILL_BOARD 0x24 #define MBX_CONFIG_FARP 0x25 -#define MBX_BEACON 0x2A #define MBX_LOAD_AREA 0x81 #define MBX_RUN_BIU_DIAG64 0x84 @@ -1541,7 +1504,6 @@ typedef struct { #define FLAGS_TOPOLOGY_FAILOVER 0x0400 /* Bit 10 */ #define FLAGS_LINK_SPEED 0x0800 /* Bit 11 */ -#define FLAGS_IMED_ABORT 0x04000 /* Bit 14 */ uint32_t link_speed; #define LINK_SPEED_AUTO 0 /* Auto selection */ @@ -1714,13 +1676,13 @@ typedef struct { uint32_t rttov; uint32_t altov; uint32_t lmt; -#define LMT_RESERVED 0x000 /* Not used */ -#define LMT_1Gb 0x004 -#define LMT_2Gb 0x008 -#define LMT_4Gb 0x040 -#define LMT_8Gb 0x080 -#define LMT_10Gb 0x100 - +#define LMT_RESERVED 0x0 /* Not used */ +#define LMT_266_10bit 0x1 /* 265.625 Mbaud 10 bit iface */ +#define LMT_532_10bit 0x2 /* 531.25 Mbaud 10 bit iface */ +#define LMT_1063_20bit 0x3 /* 1062.5 Mbaud 20 bit iface */ +#define LMT_1063_10bit 0x4 /* 1062.5 Mbaud 10 bit iface */ +#define LMT_2125_10bit 0x8 /* 2125 Mbaud 10 bit iface */ +#define LMT_4250_10bit 0x40 /* 4250 Mbaud 10 bit iface */ uint32_t rsvd2; uint32_t rsvd3; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 908d0f277..b7a603a45 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -42,7 +42,7 @@ #include "lpfc_crtn.h" #include "lpfc_version.h" -static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); +static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *); static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); static int lpfc_post_rcv_buf(struct lpfc_hba *); @@ -161,6 +161,9 @@ lpfc_config_port_prep(struct lpfc_hba * phba) memcpy(phba->RandomData, (char *)&mb->un.varWords[24], sizeof (phba->RandomData)); + /* Get the default values for Model Name and Description */ + lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc); + /* Get adapter VPD information */ pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL); if (!pmb->context2) @@ -179,15 +182,16 @@ lpfc_config_port_prep(struct lpfc_hba * phba) "mbxCmd x%x DUMP VPD, mbxStatus x%x\n", phba->brd_no, mb->mbxCommand, mb->mbxStatus); - mb->un.varDmp.word_cnt = 0; + kfree(lpfc_vpd_data); + lpfc_vpd_data = NULL; + break; } - if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) - mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; + lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset, mb->un.varDmp.word_cnt); offset += mb->un.varDmp.word_cnt; - } while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE); - lpfc_parse_vpd(phba, lpfc_vpd_data, offset); + } while (mb->un.varDmp.word_cnt); + lpfc_parse_vpd(phba, lpfc_vpd_data); kfree(lpfc_vpd_data); out_free_context2: @@ -294,6 +298,15 @@ lpfc_config_port_post(struct lpfc_hba * phba) } } + /* This should turn on DELAYED ABTS for ELS timeouts */ + lpfc_set_slim(phba, pmb, 0x052198, 0x1); + if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { + phba->hba_state = LPFC_HBA_ERROR; + mempool_free( pmb, phba->mbox_mem_pool); + return -EIO; + } + + lpfc_read_config(phba, pmb); if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { lpfc_printf_log(phba, @@ -314,22 +327,13 @@ lpfc_config_port_post(struct lpfc_hba * phba) mb->un.varRdConfig.max_xri + 1; phba->lmt = mb->un.varRdConfig.lmt; - - /* Get the default values for Model Name and Description */ - lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc); - - if ((phba->cfg_link_speed > LINK_SPEED_10G) - || ((phba->cfg_link_speed == LINK_SPEED_1G) - && !(phba->lmt & LMT_1Gb)) - || ((phba->cfg_link_speed == LINK_SPEED_2G) - && !(phba->lmt & LMT_2Gb)) - || ((phba->cfg_link_speed == LINK_SPEED_4G) - && !(phba->lmt & LMT_4Gb)) - || ((phba->cfg_link_speed == LINK_SPEED_8G) - && !(phba->lmt & LMT_8Gb)) - || ((phba->cfg_link_speed == LINK_SPEED_10G) - && !(phba->lmt & LMT_10Gb))) { - /* Reset link speed to auto */ + /* HBA is not 4GB capable, or HBA is not 2GB capable, + don't let link speed ask for it */ + if ((((phba->lmt & LMT_4250_10bit) != LMT_4250_10bit) && + (phba->cfg_link_speed > LINK_SPEED_2G)) || + (((phba->lmt & LMT_2125_10bit) != LMT_2125_10bit) && + (phba->cfg_link_speed > LINK_SPEED_1G))) { + /* Reset link speed to auto. 1G/2GB HBA cfg'd for 4G */ lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT, @@ -458,40 +462,6 @@ lpfc_hba_down_prep(struct lpfc_hba * phba) return (0); } -/************************************************************************/ -/* */ -/* lpfc_hba_down_post */ -/* This routine will do uninitialization after the HBA is reset */ -/* when bringing down the SLI Layer. */ -/* This routine returns 0 on success. Any other return value */ -/* indicates an error. */ -/* */ -/************************************************************************/ -int -lpfc_hba_down_post(struct lpfc_hba * phba) -{ - struct lpfc_sli *psli = &phba->sli; - struct lpfc_sli_ring *pring; - struct lpfc_dmabuf *mp, *next_mp; - int i; - - /* Cleanup preposted buffers on the ELS ring */ - pring = &psli->ring[LPFC_ELS_RING]; - list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { - list_del(&mp->list); - pring->postbufq_cnt--; - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); - } - - for (i = 0; i < psli->num_rings; i++) { - pring = &psli->ring[i]; - lpfc_sli_abort_iocb_ring(phba, pring); - } - - return 0; -} - /************************************************************************/ /* */ /* lpfc_handle_eratt */ @@ -506,6 +476,20 @@ lpfc_handle_eratt(struct lpfc_hba * phba) struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; + /* + * If a reset is sent to the HBA restore PCI configuration registers. + */ + if ( phba->hba_state == LPFC_INIT_START ) { + mdelay(1); + readl(phba->HCregaddr); /* flush */ + writel(0, phba->HCregaddr); + readl(phba->HCregaddr); /* flush */ + + /* Restore PCI cmd register */ + pci_write_config_word(phba->pcidev, + PCI_COMMAND, phba->pci_cfg_value); + } + if (phba->work_hs & HS_FFER6) { /* Re-establishing Link */ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, @@ -515,7 +499,6 @@ lpfc_handle_eratt(struct lpfc_hba * phba) phba->work_status[0], phba->work_status[1]); spin_lock_irq(phba->host->host_lock); phba->fc_flag |= FC_ESTABLISH_LINK; - psli->sli_flag &= ~LPFC_SLI2_ACTIVE; spin_unlock_irq(phba->host->host_lock); /* @@ -533,7 +516,6 @@ lpfc_handle_eratt(struct lpfc_hba * phba) * attempt to restart it. */ lpfc_offline(phba); - lpfc_sli_brdrestart(phba); if (lpfc_online(phba) == 0) { /* Initialize the HBA */ mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); return; @@ -549,10 +531,8 @@ lpfc_handle_eratt(struct lpfc_hba * phba) phba->brd_no, phba->work_hs, phba->work_status[0], phba->work_status[1]); - psli->sli_flag &= ~LPFC_SLI2_ACTIVE; lpfc_offline(phba); - phba->hba_state = LPFC_HBA_ERROR; - lpfc_hba_down_post(phba); + } } @@ -643,7 +623,7 @@ lpfc_handle_latt_err_exit: /* */ /************************************************************************/ static int -lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) +lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd) { uint8_t lenlo, lenhi; uint32_t Length; @@ -662,10 +642,9 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) phba->brd_no, (uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2], (uint32_t) vpd[3]); - while (!finished && (index < (len - 4))) { + do { switch (vpd[index]) { case 0x82: - case 0x91: index += 1; lenlo = vpd[index]; index += 1; @@ -681,8 +660,7 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) lenhi = vpd[index]; index += 1; Length = ((((unsigned short)lenhi) << 8) + lenlo); - if (Length > len - index) - Length = len - index; + while (Length > 0) { /* Look for Serial Number */ if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) { @@ -776,7 +754,7 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) index ++; break; } - } + } while (!finished && (index < 108)); return(1); } @@ -787,173 +765,137 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) lpfc_vpd_t *vp; uint16_t dev_id = phba->pcidev->device; uint16_t dev_subid = phba->pcidev->subsystem_device; - uint8_t hdrtype; - int max_speed; - char * ports; - struct { - char * name; - int max_speed; - char * ports; - char * bus; - } m = {"", 0, "", ""}; - - pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); - ports = (hdrtype == 0x80) ? "2-port " : ""; - if (mdp && mdp[0] != '\0' - && descp && descp[0] != '\0') - return; - - if (phba->lmt & LMT_10Gb) - max_speed = 10; - else if (phba->lmt & LMT_8Gb) - max_speed = 8; - else if (phba->lmt & LMT_4Gb) - max_speed = 4; - else if (phba->lmt & LMT_2Gb) - max_speed = 2; - else - max_speed = 1; + uint8_t hdrtype = phba->pcidev->hdr_type; + char *model_str = ""; vp = &phba->vpd; switch (dev_id) { case PCI_DEVICE_ID_FIREFLY: - m = (typeof(m)){"LP6000", max_speed, "", "PCI"}; + model_str = "LP6000 1Gb PCI"; break; case PCI_DEVICE_ID_SUPERFLY: if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3) - m = (typeof(m)){"LP7000", max_speed, "", "PCI"}; + model_str = "LP7000 1Gb PCI"; else - m = (typeof(m)){"LP7000E", max_speed, "", "PCI"}; + model_str = "LP7000E 1Gb PCI"; break; case PCI_DEVICE_ID_DRAGONFLY: - m = (typeof(m)){"LP8000", max_speed, "", "PCI"}; + model_str = "LP8000 1Gb PCI"; break; case PCI_DEVICE_ID_CENTAUR: if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) - m = (typeof(m)){"LP9002", max_speed, "", "PCI"}; + model_str = "LP9002 2Gb PCI"; else - m = (typeof(m)){"LP9000", max_speed, "", "PCI"}; + model_str = "LP9000 1Gb PCI"; break; case PCI_DEVICE_ID_RFLY: - m = (typeof(m)){"LP952", max_speed, "", "PCI"}; + model_str = "LP952 2Gb PCI"; break; case PCI_DEVICE_ID_PEGASUS: - m = (typeof(m)){"LP9802", max_speed, "", "PCI-X"}; + model_str = "LP9802 2Gb PCI-X"; break; case PCI_DEVICE_ID_THOR: if (hdrtype == 0x80) - m = (typeof(m)){"LP10000DC", - max_speed, ports, "PCI-X"}; + model_str = "LP10000DC 2Gb 2-port PCI-X"; else - m = (typeof(m)){"LP10000", - max_speed, ports, "PCI-X"}; + model_str = "LP10000 2Gb PCI-X"; break; case PCI_DEVICE_ID_VIPER: - m = (typeof(m)){"LPX1000", max_speed, "", "PCI-X"}; + model_str = "LPX1000 10Gb PCI-X"; break; case PCI_DEVICE_ID_PFLY: - m = (typeof(m)){"LP982", max_speed, "", "PCI-X"}; + model_str = "LP982 2Gb PCI-X"; break; case PCI_DEVICE_ID_TFLY: if (hdrtype == 0x80) - m = (typeof(m)){"LP1050DC", max_speed, ports, "PCI-X"}; + model_str = "LP1050DC 2Gb 2-port PCI-X"; else - m = (typeof(m)){"LP1050", max_speed, ports, "PCI-X"}; + model_str = "LP1050 2Gb PCI-X"; break; case PCI_DEVICE_ID_HELIOS: if (hdrtype == 0x80) - m = (typeof(m)){"LP11002", max_speed, ports, "PCI-X2"}; + model_str = "LP11002 4Gb 2-port PCI-X2"; else - m = (typeof(m)){"LP11000", max_speed, ports, "PCI-X2"}; + model_str = "LP11000 4Gb PCI-X2"; break; case PCI_DEVICE_ID_HELIOS_SCSP: - m = (typeof(m)){"LP11000-SP", max_speed, ports, "PCI-X2"}; + model_str = "LP11000-SP 4Gb PCI-X2"; break; case PCI_DEVICE_ID_HELIOS_DCSP: - m = (typeof(m)){"LP11002-SP", max_speed, ports, "PCI-X2"}; + model_str = "LP11002-SP 4Gb 2-port PCI-X2"; break; case PCI_DEVICE_ID_NEPTUNE: if (hdrtype == 0x80) - m = (typeof(m)){"LPe1002", max_speed, ports, "PCIe"}; + model_str = "LPe1002 4Gb 2-port"; else - m = (typeof(m)){"LPe1000", max_speed, ports, "PCIe"}; + model_str = "LPe1000 4Gb PCIe"; break; case PCI_DEVICE_ID_NEPTUNE_SCSP: - m = (typeof(m)){"LPe1000-SP", max_speed, ports, "PCIe"}; + model_str = "LPe1000-SP 4Gb PCIe"; break; case PCI_DEVICE_ID_NEPTUNE_DCSP: - m = (typeof(m)){"LPe1002-SP", max_speed, ports, "PCIe"}; + model_str = "LPe1002-SP 4Gb 2-port PCIe"; break; case PCI_DEVICE_ID_BMID: - m = (typeof(m)){"LP1150", max_speed, ports, "PCI-X2"}; + model_str = "LP1150 4Gb PCI-X2"; break; case PCI_DEVICE_ID_BSMB: - m = (typeof(m)){"LP111", max_speed, ports, "PCI-X2"}; + model_str = "LP111 4Gb PCI-X2"; break; case PCI_DEVICE_ID_ZEPHYR: if (hdrtype == 0x80) - m = (typeof(m)){"LPe11002", max_speed, ports, "PCIe"}; + model_str = "LPe11002 4Gb 2-port PCIe"; else - m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; + model_str = "LPe11000 4Gb PCIe"; break; case PCI_DEVICE_ID_ZEPHYR_SCSP: - m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; + model_str = "LPe11000-SP 4Gb PCIe"; break; case PCI_DEVICE_ID_ZEPHYR_DCSP: - m = (typeof(m)){"LPe11002-SP", max_speed, ports, "PCIe"}; + model_str = "LPe11002-SP 4Gb 2-port PCIe"; break; case PCI_DEVICE_ID_ZMID: - m = (typeof(m)){"LPe1150", max_speed, ports, "PCIe"}; + model_str = "LPe1150 4Gb PCIe"; break; case PCI_DEVICE_ID_ZSMB: - m = (typeof(m)){"LPe111", max_speed, ports, "PCIe"}; + model_str = "LPe111 4Gb PCIe"; break; case PCI_DEVICE_ID_LP101: - m = (typeof(m)){"LP101", max_speed, ports, "PCI-X"}; + model_str = "LP101 2Gb PCI-X"; break; case PCI_DEVICE_ID_LP10000S: - m = (typeof(m)){"LP10000-S", max_speed, ports, "PCI"}; + model_str = "LP10000-S 2Gb PCI"; break; case PCI_DEVICE_ID_LP11000S: case PCI_DEVICE_ID_LPE11000S: switch (dev_subid) { case PCI_SUBSYSTEM_ID_LP11000S: - m = (typeof(m)){"LP11000-S", max_speed, - ports, "PCI-X2"}; + model_str = "LP11002-S 4Gb PCI-X2"; break; case PCI_SUBSYSTEM_ID_LP11002S: - m = (typeof(m)){"LP11002-S", max_speed, - ports, "PCI-X2"}; + model_str = "LP11000-S 4Gb 2-port PCI-X2"; break; case PCI_SUBSYSTEM_ID_LPE11000S: - m = (typeof(m)){"LPe11000-S", max_speed, - ports, "PCIe"}; + model_str = "LPe11002-S 4Gb PCIe"; break; case PCI_SUBSYSTEM_ID_LPE11002S: - m = (typeof(m)){"LPe11002-S", max_speed, - ports, "PCIe"}; + model_str = "LPe11002-S 4Gb 2-port PCIe"; break; case PCI_SUBSYSTEM_ID_LPE11010S: - m = (typeof(m)){"LPe11010-S", max_speed, - "10-port ", "PCIe"}; + model_str = "LPe11010-S 4Gb 10-port PCIe"; break; default: - m = (typeof(m)){ 0 }; break; } break; default: - m = (typeof(m)){ 0 }; break; } - - if (mdp && mdp[0] == '\0') - snprintf(mdp, 79,"%s", m.name); - if (descp && descp[0] == '\0') - snprintf(descp, 255, - "Emulex %s %dGb %s%s Fibre Channel Adapter", - m.name, m.max_speed, m.ports, m.bus); + if (mdp) + sscanf(model_str, "%s", mdp); + if (descp) + sprintf(descp, "Emulex %s Fibre Channel Adapter", model_str); } /**************************************************/ @@ -1520,23 +1462,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) phba->pci_bar2_map = pci_resource_start(phba->pcidev, 2); bar2map_len = pci_resource_len(phba->pcidev, 2); - /* Map HBA SLIM to a kernel virtual address. */ + /* Map HBA SLIM and Control Registers to a kernel virtual address. */ phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len); - if (!phba->slim_memmap_p) { - error = -ENODEV; - dev_printk(KERN_ERR, &pdev->dev, - "ioremap failed for SLIM memory.\n"); - goto out_idr_remove; - } - - /* Map HBA Control Registers to a kernel virtual address. */ phba->ctrl_regs_memmap_p = ioremap(phba->pci_bar2_map, bar2map_len); - if (!phba->ctrl_regs_memmap_p) { - error = -ENODEV; - dev_printk(KERN_ERR, &pdev->dev, - "ioremap failed for HBA control registers.\n"); - goto out_iounmap_slim; - } /* Allocate memory for SLI-2 structures */ phba->slim2p = dma_alloc_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE, @@ -1611,6 +1539,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); host->transportt = lpfc_transport_template; + host->hostdata[0] = (unsigned long)phba; pci_set_drvdata(pdev, host); error = scsi_add_host(host, &pdev->dev); if (error) @@ -1618,7 +1547,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) error = lpfc_alloc_sysfs_attr(phba); if (error) - goto out_remove_host; + goto out_kthread_stop; error = request_irq(phba->pcidev->irq, lpfc_intr_handler, SA_SHIRQ, LPFC_DRIVER_NAME, phba); @@ -1635,10 +1564,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; error = lpfc_sli_hba_setup(phba); - if (error) { - error = -ENODEV; + if (error) goto out_free_irq; - } if (phba->cfg_poll & DISABLE_FCP_RING_INT) { spin_lock_irq(phba->host->host_lock); @@ -1663,14 +1590,21 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(host)); fc_host_supported_speeds(host) = 0; - if (phba->lmt & LMT_10Gb) + switch (FC_JEDEC_ID(phba->vpd.rev.biuRev)) { + case VIPER_JEDEC_ID: fc_host_supported_speeds(host) |= FC_PORTSPEED_10GBIT; - if (phba->lmt & LMT_4Gb) + break; + case HELIOS_JEDEC_ID: fc_host_supported_speeds(host) |= FC_PORTSPEED_4GBIT; - if (phba->lmt & LMT_2Gb) + /* Fall through */ + case CENTAUR_2G_JEDEC_ID: + case PEGASUS_JEDEC_ID: + case THOR_JEDEC_ID: fc_host_supported_speeds(host) |= FC_PORTSPEED_2GBIT; - if (phba->lmt & LMT_1Gb) - fc_host_supported_speeds(host) |= FC_PORTSPEED_1GBIT; + /* Fall through */ + default: + fc_host_supported_speeds(host) = FC_PORTSPEED_1GBIT; + } fc_host_maxframe_size(host) = ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | @@ -1693,9 +1627,6 @@ out_free_irq: free_irq(phba->pcidev->irq, phba); out_free_sysfs_attr: lpfc_free_sysfs_attr(phba); -out_remove_host: - fc_remove_host(phba->host); - scsi_remove_host(phba->host); out_kthread_stop: kthread_stop(phba->worker_thread); out_free_iocbq: @@ -1712,19 +1643,16 @@ out_free_slim: phba->slim2p_mapping); out_iounmap: iounmap(phba->ctrl_regs_memmap_p); -out_iounmap_slim: iounmap(phba->slim_memmap_p); out_idr_remove: idr_remove(&lpfc_hba_index, phba->brd_no); out_put_host: - phba->host = NULL; scsi_host_put(host); out_release_regions: pci_release_regions(pdev); out_disable_device: pci_disable_device(pdev); out: - pci_set_drvdata(pdev, NULL); return error; } @@ -1732,7 +1660,7 @@ static void __devexit lpfc_pci_remove_one(struct pci_dev *pdev) { struct Scsi_Host *host = pci_get_drvdata(pdev); - struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata[0]; unsigned long iflag; lpfc_free_sysfs_attr(phba); @@ -1753,7 +1681,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) * the HBA. */ lpfc_sli_hba_down(phba); - lpfc_sli_brdrestart(phba); /* Release the irq reservation */ free_irq(phba->pcidev->irq, phba); diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index e42f22aaf..e3bc8d3f7 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -195,14 +195,8 @@ lpfc_init_link(struct lpfc_hba * phba, mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; break; - case FLAGS_LOCAL_LB: - mb->un.varInitLnk.link_flags = FLAGS_LOCAL_LB; - break; } - /* Enable asynchronous ABTS responses from firmware */ - mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT; - /* NEW_FEATURE * Setting up the link speed */ @@ -295,36 +289,49 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb) return; } -/**********************************************/ -/* lpfc_read_nv Issue a READ CONFIG */ -/* mailbox command */ -/**********************************************/ +/***********************************************/ + +/* command to write slim */ +/***********************************************/ void -lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) +lpfc_set_slim(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint32_t addr, + uint32_t value) { MAILBOX_t *mb; mb = &pmb->mb; memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); - mb->mbxCommand = MBX_READ_CONFIG; + /* addr = 0x090597 is AUTO ABTS disable for ELS commands */ + /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */ + + /* + * Always turn on DELAYED ABTS for ELS timeouts + */ + if ((addr == 0x052198) && (value == 0)) + value = 1; + + mb->un.varWords[0] = addr; + mb->un.varWords[1] = value; + + mb->mbxCommand = MBX_SET_SLIM; mb->mbxOwner = OWN_HOST; return; } -/*************************************************/ -/* lpfc_read_lnk_stat Issue a READ LINK STATUS */ -/* mailbox command */ -/*************************************************/ +/**********************************************/ +/* lpfc_read_nv Issue a READ CONFIG */ +/* mailbox command */ +/**********************************************/ void -lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) +lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { MAILBOX_t *mb; mb = &pmb->mb; memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); - mb->mbxCommand = MBX_READ_LNK_STAT; + mb->mbxCommand = MBX_READ_CONFIG; mb->mbxOwner = OWN_HOST; return; } @@ -612,17 +619,6 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) phba->brd_no); } -void -lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) -{ - MAILBOX_t *mb = &pmb->mb; - - memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); - mb->mbxCommand = MBX_KILL_BOARD; - mb->mbxOwner = OWN_HOST; - return; -} - void lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) { diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 07017658a..352df47bc 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -38,6 +38,18 @@ #define LPFC_MBUF_POOL_SIZE 64 /* max elements in MBUF safety pool */ #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */ +static void * +lpfc_pool_kmalloc(gfp_t gfp_flags, void *data) +{ + return kmalloc((unsigned long)data, gfp_flags); +} + +static void +lpfc_pool_kfree(void *obj, void *data) +{ + kfree(obj); +} + int lpfc_mem_alloc(struct lpfc_hba * phba) { @@ -67,13 +79,15 @@ lpfc_mem_alloc(struct lpfc_hba * phba) pool->current_count++; } - phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE, - sizeof(LPFC_MBOXQ_t)); + phba->mbox_mem_pool = mempool_create(LPFC_MEM_POOL_SIZE, + lpfc_pool_kmalloc, lpfc_pool_kfree, + (void *)(unsigned long)sizeof(LPFC_MBOXQ_t)); if (!phba->mbox_mem_pool) goto fail_free_mbuf_pool; - phba->nlp_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE, - sizeof(struct lpfc_nodelist)); + phba->nlp_mem_pool = mempool_create(LPFC_MEM_POOL_SIZE, + lpfc_pool_kmalloc, lpfc_pool_kfree, + (void *)(unsigned long)sizeof(struct lpfc_nodelist)); if (!phba->nlp_mem_pool) goto fail_free_mbox_pool; diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 27d60ad89..fbead7860 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -46,13 +46,13 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, * table entry for that node. */ if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0) - return 0; + return (0); if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0) - return 0; + return (0); /* we match, return success */ - return 1; + return (1); } int @@ -150,7 +150,8 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, lp = (uint32_t *) prsp->virt; ptr = (void *)((uint8_t *)lp + sizeof(uint32_t)); } - } else { + } + else { /* Force ulpStatus error since we are returning NULL ptr */ if (!(irsp->ulpStatus)) { irsp->ulpStatus = IOSTAT_LOCAL_REJECT; @@ -158,7 +159,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, } ptr = NULL; } - return ptr; + return (ptr); } @@ -259,9 +260,13 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, } while(found); /* If we are delaying issuing an ELS command, cancel it */ - if (ndlp->nlp_flag & NLP_DELAY_TMO) - lpfc_cancel_retry_delay_tmo(phba, ndlp); - return 0; + if (ndlp->nlp_flag & NLP_DELAY_TMO) { + ndlp->nlp_flag &= ~NLP_DELAY_TMO; + del_timer_sync(&ndlp->nlp_delayfunc); + if (!list_empty(&ndlp->els_retry_evt.evt_listp)) + list_del_init(&ndlp->els_retry_evt.evt_listp); + } + return (0); } static int @@ -295,10 +300,12 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, /* Start discovery - this should just do CLEAR_LA */ lpfc_disc_start(phba); - } else { + } + else { lpfc_initial_flogi(phba); } - } else { + } + else { stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, @@ -314,7 +321,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); - return 0; + return (0); } icmd = &cmdiocb->iocb; @@ -346,7 +353,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; /* no need to reg_login if we are already in one of these states */ - switch (ndlp->nlp_state) { + switch(ndlp->nlp_state) { case NLP_STE_NPR_NODE: if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) break; @@ -355,7 +362,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, case NLP_STE_UNMAPPED_NODE: case NLP_STE_MAPPED_NODE: lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); - return 1; + return (1); } if ((phba->fc_flag & FC_PT2PT) @@ -391,16 +398,24 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, */ mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->context2 = ndlp; - ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); + ndlp->nlp_flag |= NLP_ACC_REGLOGIN; + /* If there is an outstanding PLOGI issued, abort it before + * sending ACC rsp to PLOGI recieved. + */ + if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) { + /* software abort outstanding PLOGI */ + lpfc_els_abort(phba, ndlp, 1); + } + ndlp->nlp_flag |= NLP_RCV_PLOGI; lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); - return 1; + return (1); out: stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); - return 0; + return (0); } static int @@ -436,11 +451,12 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, (lpfc_check_adisc(phba, ndlp, pnn, ppn))) { if (cmd == ELS_CMD_ADISC) { lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp); - } else { + } + else { lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); } - return 1; + return (1); } /* Reject this request because invalid parameters */ stat.un.b.lsRjtRsvd0 = 0; @@ -449,62 +465,49 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, stat.un.b.vendorUnique = 0; lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); + ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; /* 1 sec timeout */ mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(phba->host->host_lock); - ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; - ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - return 0; + return (0); } static int lpfc_rcv_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, - struct lpfc_iocbq *cmdiocb, - uint32_t els_cmd) + struct lpfc_iocbq *cmdiocb) { /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */ /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary * PLOGIs during LOGO storms from a device. */ ndlp->nlp_flag |= NLP_LOGO_ACC; - if (els_cmd == ELS_CMD_PRLO) - lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); - else - lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); - if (!(ndlp->nlp_type & NLP_FABRIC) || - (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { + if (!(ndlp->nlp_type & NLP_FABRIC)) { /* Only try to re-login if this is NOT a Fabric Node */ + ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(phba->host->host_lock); - - ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; - ndlp->nlp_prev_state = ndlp->nlp_state; - ndlp->nlp_state = NLP_STE_NPR_NODE; - lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - } else { - ndlp->nlp_prev_state = ndlp->nlp_state; - ndlp->nlp_state = NLP_STE_UNUSED_NODE; - lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); } - spin_lock_irq(phba->host->host_lock); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); + ndlp->nlp_flag &= ~NLP_NPR_ADISC; - spin_unlock_irq(phba->host->host_lock); /* The driver has to wait until the ACC completes before it continues * processing the LOGO. The action will resume in * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an * unreg_login, the driver waits so the ACC does not get aborted. */ - return 0; + return (0); } static void @@ -552,12 +555,20 @@ lpfc_disc_set_adisc(struct lpfc_hba * phba, if ((phba->cfg_use_adisc == 0) && !(phba->fc_flag & FC_RSCN_MODE)) { if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) - return 0; + return (0); } spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag |= NLP_NPR_ADISC; spin_unlock_irq(phba->host->host_lock); - return 1; + return (1); +} + +static uint32_t +lpfc_disc_noop(struct lpfc_hba * phba, + struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) +{ + /* This routine does nothing, just return the current state */ + return (ndlp->nlp_state); } static uint32_t @@ -572,7 +583,7 @@ lpfc_disc_illegal(struct lpfc_hba * phba, phba->brd_no, ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, ndlp->nlp_flag); - return ndlp->nlp_state; + return (ndlp->nlp_state); } /* Start of Discovery State Machine routines */ @@ -586,13 +597,12 @@ lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { - ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; ndlp->nlp_state = NLP_STE_UNUSED_NODE; lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); - return ndlp->nlp_state; + return (ndlp->nlp_state); } lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; + return (NLP_STE_FREED_NODE); } static uint32_t @@ -601,7 +611,7 @@ lpfc_rcv_els_unused_node(struct lpfc_hba * phba, { lpfc_issue_els_logo(phba, ndlp, 0); lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -618,7 +628,7 @@ lpfc_rcv_logo_unused_node(struct lpfc_hba * phba, lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -626,7 +636,7 @@ lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; + return (NLP_STE_FREED_NODE); } static uint32_t @@ -634,7 +644,7 @@ lpfc_device_rm_unused_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; + return (NLP_STE_FREED_NODE); } static uint32_t @@ -667,26 +677,12 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); - } else { + } + else { lpfc_rcv_plogi(phba, ndlp, cmdiocb); } /* if our portname was less */ - return ndlp->nlp_state; -} - -static uint32_t -lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, - struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) -{ - struct lpfc_iocbq *cmdiocb; - - cmdiocb = (struct lpfc_iocbq *) arg; - - /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp, 1); - - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -699,24 +695,24 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, /* software abort outstanding PLOGI */ lpfc_els_abort(phba, ndlp, 1); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag |= NLP_DELAY_TMO; + spin_unlock_irq(phba->host->host_lock); if (evt == NLP_EVT_RCV_LOGO) { lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); - } else { + } + else { lpfc_issue_els_logo(phba, ndlp, 0); } /* Put ndlp in npr list set plogi timer for 1 sec */ - mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag |= NLP_DELAY_TMO; - spin_unlock_irq(phba->host->host_lock); - ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; - ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; + ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -735,8 +731,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, rspiocb = cmdiocb->context_un.rsp_iocb; if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { - /* Recovery from PLOGI collision logic */ - return ndlp->nlp_state; + return (ndlp->nlp_state); } irsp = &rspiocb->iocb; @@ -792,7 +787,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, if (lpfc_reg_login (phba, irsp->un.elsreq64.remoteID, (uint8_t *) sp, mbox, 0) == 0) { - switch (ndlp->nlp_DID) { + /* set_slim mailbox command needs to + * execute first, queue this command to + * be processed later. + */ + switch(ndlp->nlp_DID) { case NameServer_DID: mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login; @@ -813,7 +812,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, NLP_STE_REG_LOGIN_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST); - return ndlp->nlp_state; + return (ndlp->nlp_state); } mempool_free(mbox, phba->mbox_mem_pool); } else { @@ -825,24 +824,18 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, /* Free this node since the driver cannot login or has the wrong sparm */ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; + return (NLP_STE_FREED_NODE); } static uint32_t lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } - else { - /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp, 1); + /* software abort outstanding PLOGI */ + lpfc_els_abort(phba, ndlp, 1); - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + return (NLP_STE_FREED_NODE); } static uint32_t @@ -853,14 +846,13 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, /* software abort outstanding PLOGI */ lpfc_els_abort(phba, ndlp, 1); - ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -876,14 +868,13 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { - return ndlp->nlp_state; + return (ndlp->nlp_state); } - ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); + lpfc_issue_els_plogi(phba, ndlp, 0); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -896,7 +887,7 @@ lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -911,8 +902,8 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, /* software abort outstanding ADISC */ lpfc_els_abort(phba, ndlp, 0); - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); - return ndlp->nlp_state; + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t @@ -925,7 +916,7 @@ lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_padisc(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -938,8 +929,8 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; /* Treat like rcv logo */ - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); - return ndlp->nlp_state; + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t @@ -959,33 +950,29 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, if ((irsp->ulpStatus) || (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { + ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; /* 1 sec timeout */ mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(phba->host->host_lock); - ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); - ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_unreg_rpi(phba, ndlp); - return ndlp->nlp_state; + return (ndlp->nlp_state); } - if (ndlp->nlp_type & NLP_FCP_TARGET) { - ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; ndlp->nlp_state = NLP_STE_MAPPED_NODE; lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); } else { - ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); } - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -993,17 +980,11 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } - else { - /* software abort outstanding ADISC */ - lpfc_els_abort(phba, ndlp, 1); + /* software abort outstanding ADISC */ + lpfc_els_abort(phba, ndlp, 1); - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + return (NLP_STE_FREED_NODE); } static uint32_t @@ -1014,15 +995,14 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, /* software abort outstanding ADISC */ lpfc_els_abort(phba, ndlp, 1); - ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); - ndlp->nlp_flag |= NLP_NPR_ADISC; + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); - return ndlp->nlp_state; + lpfc_disc_set_adisc(phba, ndlp); + return (ndlp->nlp_state); } static uint32_t @@ -1035,7 +1015,7 @@ lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_plogi(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1048,7 +1028,7 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1060,8 +1040,8 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); - return ndlp->nlp_state; + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t @@ -1074,7 +1054,7 @@ lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_padisc(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1085,8 +1065,8 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, struct lpfc_iocbq *cmdiocb; cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); - return ndlp->nlp_state; + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + return (ndlp->nlp_state); } static uint32_t @@ -1110,34 +1090,31 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, phba->brd_no, did, mb->mbxStatus, phba->hba_state); - /* Put ndlp in npr list set plogi timer for 1 sec */ mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(phba->host->host_lock); - ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; lpfc_issue_els_logo(phba, ndlp, 0); - ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; + /* Put ndlp in npr list set plogi timer for 1 sec */ + ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - return ndlp->nlp_state; + return (ndlp->nlp_state); } ndlp->nlp_rpi = mb->un.varWords[0]; /* Only if we are not a fabric nport do we issue PRLI */ if (!(ndlp->nlp_type & NLP_FABRIC)) { - ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; ndlp->nlp_state = NLP_STE_PRLI_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); lpfc_issue_els_prli(phba, ndlp, 0); } else { - ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); } - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1145,14 +1122,8 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } - else { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + return (NLP_STE_FREED_NODE); } static uint32_t @@ -1160,13 +1131,12 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1178,7 +1148,7 @@ lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_plogi(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1190,7 +1160,7 @@ lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1204,8 +1174,8 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, /* Software abort outstanding PRLI before sending acc */ lpfc_els_abort(phba, ndlp, 1); - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); - return ndlp->nlp_state; + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t @@ -1217,7 +1187,7 @@ lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_padisc(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } /* This routine is envoked when we rcv a PRLO request from a nport @@ -1232,8 +1202,8 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, struct lpfc_iocbq *cmdiocb; cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); - return ndlp->nlp_state; + lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); + return (ndlp->nlp_state); } static uint32_t @@ -1250,10 +1220,9 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, irsp = &rspiocb->iocb; if (irsp->ulpStatus) { - ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); - return ndlp->nlp_state; + return (ndlp->nlp_state); } /* Check out PRLI rsp */ @@ -1269,10 +1238,9 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; } - ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; ndlp->nlp_state = NLP_STE_MAPPED_NODE; lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); - return ndlp->nlp_state; + return (ndlp->nlp_state); } /*! lpfc_device_rm_prli_issue @@ -1296,17 +1264,11 @@ static uint32_t lpfc_device_rm_prli_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } - else { - /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp, 1); + /* software abort outstanding PRLI */ + lpfc_els_abort(phba, ndlp, 1); - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + return (NLP_STE_FREED_NODE); } @@ -1333,13 +1295,12 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, /* software abort outstanding PRLI */ lpfc_els_abort(phba, ndlp, 1); - ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1351,7 +1312,7 @@ lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_plogi(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1364,7 +1325,7 @@ lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba, lpfc_rcv_prli(phba, ndlp, cmdiocb); lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1375,8 +1336,8 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); - return ndlp->nlp_state; + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t @@ -1388,7 +1349,7 @@ lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_padisc(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1399,21 +1360,21 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); - return ndlp->nlp_state; + /* Treat like rcv logo */ + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t lpfc_device_recov_unmap_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; lpfc_disc_set_adisc(phba, ndlp); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1425,7 +1386,7 @@ lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_plogi(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1437,7 +1398,7 @@ lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1448,8 +1409,8 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); - return ndlp->nlp_state; + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t @@ -1462,7 +1423,7 @@ lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_padisc(phba, ndlp, cmdiocb); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1480,8 +1441,8 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, spin_unlock_irq(phba->host->host_lock); /* Treat like rcv logo */ - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); - return ndlp->nlp_state; + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t @@ -1489,14 +1450,13 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); lpfc_disc_set_adisc(phba, ndlp); - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1510,25 +1470,23 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, /* Ignore PLOGI if we have an outstanding LOGO */ if (ndlp->nlp_flag & NLP_LOGO_SND) { - return ndlp->nlp_state; + return (ndlp->nlp_state); } if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; + ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC); spin_unlock_irq(phba->host->host_lock); - return ndlp->nlp_state; + return (ndlp->nlp_state); } /* send PLOGI immediately, move to PLOGI issue state */ if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); + lpfc_issue_els_plogi(phba, ndlp, 0); } - - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1548,22 +1506,16 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { if (ndlp->nlp_flag & NLP_NPR_ADISC) { - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - spin_unlock_irq(phba->host->host_lock); - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_ADISC_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); lpfc_issue_els_adisc(phba, ndlp, 0); } else { - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); + lpfc_issue_els_plogi(phba, ndlp, 0); } - } - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1575,8 +1527,8 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); - return ndlp->nlp_state; + lpfc_rcv_logo(phba, ndlp, cmdiocb); + return (ndlp->nlp_state); } static uint32_t @@ -1592,18 +1544,16 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { if (ndlp->nlp_flag & NLP_NPR_ADISC) { - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_ADISC_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); lpfc_issue_els_adisc(phba, ndlp, 0); } else { - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); - lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); + lpfc_issue_els_plogi(phba, ndlp, 0); } } - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1615,61 +1565,25 @@ lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag |= NLP_LOGO_ACC; - spin_unlock_irq(phba->host->host_lock); - lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); - if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { - mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag |= NLP_DELAY_TMO; - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - spin_unlock_irq(phba->host->host_lock); - ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; - } else { - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - spin_unlock_irq(phba->host->host_lock); - } - return ndlp->nlp_state; -} - -static uint32_t -lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, - struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) -{ - struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; - - cmdiocb = (struct lpfc_iocbq *) arg; - rspiocb = cmdiocb->context_un.rsp_iocb; - - irsp = &rspiocb->iocb; - if (irsp->ulpStatus) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; + if (ndlp->nlp_flag & NLP_DELAY_TMO) { + if (ndlp->nlp_last_elscmd == (unsigned long)ELS_CMD_PLOGI) { + return (ndlp->nlp_state); + } else { + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_DELAY_TMO; + spin_unlock_irq(phba->host->host_lock); + del_timer_sync(&ndlp->nlp_delayfunc); + if (!list_empty(&ndlp->els_retry_evt.evt_listp)) + list_del_init(&ndlp->els_retry_evt.evt_listp); + } } - return ndlp->nlp_state; -} - -static uint32_t -lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, - struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) -{ - struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; - cmdiocb = (struct lpfc_iocbq *) arg; - rspiocb = cmdiocb->context_un.rsp_iocb; - - irsp = &rspiocb->iocb; - if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } - return ndlp->nlp_state; + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); + lpfc_issue_els_plogi(phba, ndlp, 0); + return (ndlp->nlp_state); } static uint32_t @@ -1678,26 +1592,7 @@ lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba, { lpfc_unreg_rpi(phba, ndlp); /* This routine does nothing, just return the current state */ - return ndlp->nlp_state; -} - -static uint32_t -lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, - struct lpfc_nodelist * ndlp, void *arg, - uint32_t evt) -{ - struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; - - cmdiocb = (struct lpfc_iocbq *) arg; - rspiocb = cmdiocb->context_un.rsp_iocb; - - irsp = &rspiocb->iocb; - if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } - return ndlp->nlp_state; + return (ndlp->nlp_state); } static uint32_t @@ -1711,15 +1606,9 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, pmb = (LPFC_MBOXQ_t *) arg; mb = &pmb->mb; - if (!mb->mbxStatus) - ndlp->nlp_rpi = mb->un.varWords[0]; - else { - if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; - } - } - return ndlp->nlp_state; + ndlp->nlp_rpi = mb->un.varWords[0]; + + return (ndlp->nlp_state); } static uint32_t @@ -1727,12 +1616,8 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { - ndlp->nlp_flag |= NLP_NODEV_REMOVE; - return ndlp->nlp_state; - } lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - return NLP_STE_FREED_NODE; + return (NLP_STE_FREED_NODE); } static uint32_t @@ -1741,12 +1626,9 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, uint32_t evt) { spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(phba->host->host_lock); - if (ndlp->nlp_flag & NLP_DELAY_TMO) { - lpfc_cancel_retry_delay_tmo(phba, ndlp); - } - return ndlp->nlp_state; + return (ndlp->nlp_state); } @@ -1825,7 +1707,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */ lpfc_rcv_els_plogi_issue, /* RCV_PRLI */ - lpfc_rcv_logo_plogi_issue, /* RCV_LOGO */ + lpfc_rcv_els_plogi_issue, /* RCV_LOGO */ lpfc_rcv_els_plogi_issue, /* RCV_ADISC */ lpfc_rcv_els_plogi_issue, /* RCV_PDISC */ lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ @@ -1913,10 +1795,10 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) lpfc_rcv_padisc_npr_node, /* RCV_ADISC */ lpfc_rcv_padisc_npr_node, /* RCV_PDISC */ lpfc_rcv_prlo_npr_node, /* RCV_PRLO */ - lpfc_cmpl_plogi_npr_node, /* CMPL_PLOGI */ - lpfc_cmpl_prli_npr_node, /* CMPL_PRLI */ + lpfc_disc_noop, /* CMPL_PLOGI */ + lpfc_disc_noop, /* CMPL_PRLI */ lpfc_cmpl_logo_npr_node, /* CMPL_LOGO */ - lpfc_cmpl_adisc_npr_node, /* CMPL_ADISC */ + lpfc_disc_noop, /* CMPL_ADISC */ lpfc_cmpl_reglogin_npr_node, /* CMPL_REG_LOGIN */ lpfc_device_rm_npr_node, /* DEVICE_RM */ lpfc_device_recov_npr_node, /* DEVICE_RECOVERY */ @@ -1962,9 +1844,10 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, ndlp->nlp_flag &= ~NLP_DELAY_REMOVE; spin_unlock_irq(phba->host->host_lock); lpfc_nlp_remove(phba, ndlp); - return NLP_STE_FREED_NODE; + return (NLP_STE_FREED_NODE); } if (rc == NLP_STE_FREED_NODE) - return NLP_STE_FREED_NODE; - return rc; + return (NLP_STE_FREED_NODE); + ndlp->nlp_state = rc; + return (rc); } diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 7dc4c2e6b..dafabeefc 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -467,12 +467,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, sdev = cmd->device; cmd->scsi_done(cmd); - if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { - lpfc_release_scsi_buf(phba, lpfc_cmd); - return; - } - - if (!result && pnode != NULL && + if (!result && ((jiffies - pnode->last_ramp_up_time) > LPFC_Q_RAMP_UP_INTERVAL * HZ) && ((jiffies - pnode->last_q_full_time) > @@ -500,7 +495,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, * Check for queue full. If the lun is reporting queue full, then * back off the lun queue depth to prevent target overloads. */ - if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) { + if (result == SAM_STAT_TASK_SET_FULL) { pnode->last_q_full_time = jiffies; shost_for_each_device(tmp_sdev, sdev->host) { @@ -629,7 +624,8 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq; IOCB_t *piocb; struct fcp_cmnd *fcp_cmnd; - struct lpfc_rport_data *rdata = lpfc_cmd->rdata; + struct scsi_device *scsi_dev = lpfc_cmd->pCmd->device; + struct lpfc_rport_data *rdata = scsi_dev->hostdata; struct lpfc_nodelist *ndlp = rdata->pnode; if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { @@ -664,18 +660,56 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, piocb->ulpTimeout = lpfc_cmd->timeout; } + lpfc_cmd->rdata = rdata; + + switch (task_mgmt_cmd) { + case FCP_LUN_RESET: + /* Issue LUN Reset to TGT LUN */ + lpfc_printf_log(phba, + KERN_INFO, + LOG_FCP, + "%d:0703 Issue LUN Reset to TGT %d LUN %d " + "Data: x%x x%x\n", + phba->brd_no, + scsi_dev->id, scsi_dev->lun, + ndlp->nlp_rpi, ndlp->nlp_flag); + + break; + case FCP_ABORT_TASK_SET: + /* Issue Abort Task Set to TGT LUN */ + lpfc_printf_log(phba, + KERN_INFO, + LOG_FCP, + "%d:0701 Issue Abort Task Set to TGT %d LUN %d " + "Data: x%x x%x\n", + phba->brd_no, + scsi_dev->id, scsi_dev->lun, + ndlp->nlp_rpi, ndlp->nlp_flag); + + break; + case FCP_TARGET_RESET: + /* Issue Target Reset to TGT */ + lpfc_printf_log(phba, + KERN_INFO, + LOG_FCP, + "%d:0702 Issue Target Reset to TGT %d " + "Data: x%x x%x\n", + phba->brd_no, + scsi_dev->id, ndlp->nlp_rpi, + ndlp->nlp_flag); + break; + } + return (1); } static int -lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, - unsigned tgt_id, struct lpfc_rport_data *rdata) +lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) { struct lpfc_iocbq *iocbq; struct lpfc_iocbq *iocbqrsp; int ret; - lpfc_cmd->rdata = rdata; ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); if (!ret) return FAILED; @@ -687,13 +721,6 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, if (!iocbqrsp) return FAILED; - /* Issue Target Reset to TGT */ - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d:0702 Issue Target Reset to TGT %d " - "Data: x%x x%x\n", - phba->brd_no, tgt_id, rdata->pnode->nlp_rpi, - rdata->pnode->nlp_flag); - ret = lpfc_sli_issue_iocb_wait(phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); @@ -716,7 +743,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, const char * lpfc_info(struct Scsi_Host *host) { - struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0]; int len; static char lpfcinfobuf[384]; @@ -776,7 +803,7 @@ static int lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) { struct lpfc_hba *phba = - (struct lpfc_hba *) cmnd->device->host->hostdata; + (struct lpfc_hba *) cmnd->device->host->hostdata[0]; struct lpfc_sli *psli = &phba->sli; struct lpfc_rport_data *rdata = cmnd->device->hostdata; struct lpfc_nodelist *ndlp = rdata->pnode; @@ -850,7 +877,7 @@ static int lpfc_abort_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; - struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring]; struct lpfc_iocbq *iocb; struct lpfc_iocbq *abtsiocb; @@ -954,7 +981,7 @@ static int lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; - struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; struct lpfc_scsi_buf *lpfc_cmd; struct lpfc_iocbq *iocbq, *iocbqrsp; struct lpfc_rport_data *rdata = cmnd->device->hostdata; @@ -989,7 +1016,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) lpfc_cmd->pCmd = cmnd; lpfc_cmd->timeout = 60; lpfc_cmd->scsi_hba = phba; - lpfc_cmd->rdata = rdata; ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); if (!ret) @@ -1002,11 +1028,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) if (iocbqrsp == NULL) goto out_free_scsi_buf; - lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d:0703 Issue LUN Reset to TGT %d LUN %d " - "Data: x%x x%x\n", phba->brd_no, cmnd->device->id, - cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); - ret = lpfc_sli_issue_iocb_wait(phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); @@ -1073,11 +1094,12 @@ static int lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; - struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; struct lpfc_nodelist *ndlp = NULL; int match; int ret = FAILED, i, err_count = 0; int cnt, loopcnt; + unsigned int midlayer_id = 0; struct lpfc_scsi_buf * lpfc_cmd; lpfc_block_requests(phba); @@ -1097,6 +1119,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) * targets known to the driver. Should any target reset * fail, this routine returns failure to the midlayer. */ + midlayer_id = cmnd->device->id; for (i = 0; i < MAX_FCP_TARGET; i++) { /* Search the mapped list for this target ID */ match = 0; @@ -1109,8 +1132,9 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) if (!match) continue; - ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, - i, ndlp->rport->dd_data); + lpfc_cmd->pCmd->device->id = i; + lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data; + ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba); if (ret != SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d:0713 Bus Reset on target %d failed\n", @@ -1129,6 +1153,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) * the targets. Unfortunately, some targets do not abide by * this forcing the driver to double check. */ + cmnd->device->id = midlayer_id; cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], 0, 0, LPFC_CTX_HOST); if (cnt) @@ -1170,7 +1195,7 @@ out: static int lpfc_slave_alloc(struct scsi_device *sdev) { - struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0]; struct lpfc_scsi_buf *scsi_buf = NULL; struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); uint32_t total = 0, i; @@ -1226,7 +1251,7 @@ lpfc_slave_alloc(struct scsi_device *sdev) static int lpfc_slave_configure(struct scsi_device *sdev) { - struct lpfc_hba *phba = (struct lpfc_hba *) sdev->host->hostdata; + struct lpfc_hba *phba = (struct lpfc_hba *) sdev->host->hostdata[0]; struct fc_rport *rport = starget_to_rport(sdev->sdev_target); if (sdev->tagged_supported) diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index cdcd25358..acd64c49e 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h @@ -23,13 +23,10 @@ struct lpfc_hba; #define list_remove_head(list, entry, type, member) \ - do { \ - entry = NULL; \ if (!list_empty(list)) { \ entry = list_entry((list)->next, type, member); \ list_del_init(&entry->member); \ - } \ - } while(0) + } #define list_get_first(list, type, member) \ (list_empty(list)) ? NULL : \ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index bb69a7a1e..7b785ade8 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -513,9 +513,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) case MBX_SET_MASK: case MBX_SET_SLIM: case MBX_UNREG_D_ID: - case MBX_KILL_BOARD: case MBX_CONFIG_FARP: - case MBX_BEACON: case MBX_LOAD_AREA: case MBX_RUN_BIU_DIAG64: case MBX_CONFIG_PORT: @@ -766,9 +764,7 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } /* unSolicited Responses */ if (pring->prt[0].profile) { - if (pring->prt[0].lpfc_sli_rcv_unsol_event) - (pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring, - saveq); + (pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring, saveq); match = 1; } else { /* We must search, based on rctl / type @@ -779,9 +775,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, Rctl) && (pring->prt[i]. type == Type)) { - if (pring->prt[i].lpfc_sli_rcv_unsol_event) - (pring->prt[i].lpfc_sli_rcv_unsol_event) - (phba, pring, saveq); + (pring->prt[i].lpfc_sli_rcv_unsol_event) + (phba, pring, saveq); match = 1; break; } @@ -1154,17 +1149,12 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, &rspiocbq); if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { - if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { - (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, - &rspiocbq); - } else { - spin_unlock_irqrestore( - phba->host->host_lock, iflag); - (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, - &rspiocbq); - spin_lock_irqsave(phba->host->host_lock, - iflag); - } + spin_unlock_irqrestore( + phba->host->host_lock, iflag); + (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, + &rspiocbq); + spin_lock_irqsave(phba->host->host_lock, + iflag); } break; default: @@ -1522,240 +1512,98 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) return errcnt; } -int -lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) -{ - uint32_t status; - int i = 0; - int retval = 0; - - /* Read the HBA Host Status Register */ - status = readl(phba->HSregaddr); - - /* - * Check status register every 100ms for 5 retries, then every - * 500ms for 5, then every 2.5 sec for 5, then reset board and - * every 2.5 sec for 4. - * Break our of the loop if errors occurred during init. - */ - while (((status & mask) != mask) && - !(status & HS_FFERM) && - i++ < 20) { - - if (i <= 5) - msleep(10); - else if (i <= 10) - msleep(500); - else - msleep(2500); - - if (i == 15) { - phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */ - lpfc_sli_brdrestart(phba); - } - /* Read the HBA Host Status Register */ - status = readl(phba->HSregaddr); - } - - /* Check to see if any errors occurred during init */ - if ((status & HS_FFERM) || (i >= 20)) { - phba->hba_state = LPFC_HBA_ERROR; - retval = 1; - } - - return retval; -} - -#define BARRIER_TEST_PATTERN (0xdeadbeef) - -void lpfc_reset_barrier(struct lpfc_hba * phba) -{ - uint32_t * resp_buf; - uint32_t * mbox_buf; - volatile uint32_t mbox; - uint32_t hc_copy; - int i; - uint8_t hdrtype; - - pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); - if (hdrtype != 0x80 || - (FC_JEDEC_ID(phba->vpd.rev.biuRev) != HELIOS_JEDEC_ID && - FC_JEDEC_ID(phba->vpd.rev.biuRev) != THOR_JEDEC_ID)) - return; - - /* - * Tell the other part of the chip to suspend temporarily all - * its DMA activity. - */ - resp_buf = (uint32_t *)phba->MBslimaddr; - - /* Disable the error attention */ - hc_copy = readl(phba->HCregaddr); - writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); - readl(phba->HCregaddr); /* flush */ - - if (readl(phba->HAregaddr) & HA_ERATT) { - /* Clear Chip error bit */ - writel(HA_ERATT, phba->HAregaddr); - phba->stopped = 1; - } - - mbox = 0; - ((MAILBOX_t *)&mbox)->mbxCommand = MBX_KILL_BOARD; - ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP; - - writel(BARRIER_TEST_PATTERN, (resp_buf + 1)); - mbox_buf = (uint32_t *)phba->MBslimaddr; - writel(mbox, mbox_buf); - - for (i = 0; - readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN) && i < 50; i++) - mdelay(1); - - if (readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN)) { - if (phba->sli.sli_flag & LPFC_SLI2_ACTIVE || - phba->stopped) - goto restore_hc; - else - goto clear_errat; - } - - ((MAILBOX_t *)&mbox)->mbxOwner = OWN_HOST; - for (i = 0; readl(resp_buf) != mbox && i < 500; i++) - mdelay(1); - -clear_errat: - - while (!(readl(phba->HAregaddr) & HA_ERATT) && ++i < 500) - mdelay(1); - - if (readl(phba->HAregaddr) & HA_ERATT) { - writel(HA_ERATT, phba->HAregaddr); - phba->stopped = 1; - } - -restore_hc: - writel(hc_copy, phba->HCregaddr); - readl(phba->HCregaddr); /* flush */ -} - -int -lpfc_sli_brdkill(struct lpfc_hba * phba) +/****************************************************************************** +* lpfc_sli_send_reset +* +* Note: After returning from this function, the HBA cannot be accessed for +* 1 ms. Since we do not wish to delay in interrupt context, it is the +* responsibility of the caller to perform the mdelay(1) and flush via readl(). +******************************************************************************/ +static int +lpfc_sli_send_reset(struct lpfc_hba * phba, uint16_t skip_post) { - struct lpfc_sli *psli; - LPFC_MBOXQ_t *pmb; - uint32_t status; - uint32_t ha_copy; - int retval; - int i = 0; - - psli = &phba->sli; + MAILBOX_t *swpmb; + volatile uint32_t word0; + void __iomem *to_slim; + unsigned long flags = 0; - /* Kill HBA */ - lpfc_printf_log(phba, - KERN_INFO, - LOG_SLI, - "%d:0329 Kill HBA Data: x%x x%x\n", - phba->brd_no, - phba->hba_state, - psli->sli_flag); + spin_lock_irqsave(phba->host->host_lock, flags); - if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, - GFP_KERNEL)) == 0) - return 1; + /* A board reset must use REAL SLIM. */ + phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE; - /* Disable the error attention */ - spin_lock_irq(phba->host->host_lock); - status = readl(phba->HCregaddr); - status &= ~HC_ERINT_ENA; - writel(status, phba->HCregaddr); - readl(phba->HCregaddr); /* flush */ - spin_unlock_irq(phba->host->host_lock); + word0 = 0; + swpmb = (MAILBOX_t *) & word0; + swpmb->mbxCommand = MBX_RESTART; + swpmb->mbxHc = 1; - lpfc_kill_board(phba, pmb); - pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - retval = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); + to_slim = phba->MBslimaddr; + writel(*(uint32_t *) swpmb, to_slim); + readl(to_slim); /* flush */ - if (retval != MBX_SUCCESS) { - if (retval != MBX_BUSY) - mempool_free(pmb, phba->mbox_mem_pool); - return 1; + /* Only skip post after fc_ffinit is completed */ + if (skip_post) { + word0 = 1; /* This is really setting up word1 */ + } else { + word0 = 0; /* This is really setting up word1 */ } + to_slim = phba->MBslimaddr + sizeof (uint32_t); + writel(*(uint32_t *) swpmb, to_slim); + readl(to_slim); /* flush */ - psli->sli_flag &= ~LPFC_SLI2_ACTIVE; - - mempool_free(pmb, phba->mbox_mem_pool); - - /* There is no completion for a KILL_BOARD mbox cmd. Check for an error - * attention every 100ms for 3 seconds. If we don't get ERATT after - * 3 seconds we still set HBA_ERROR state because the status of the - * board is now undefined. - */ - ha_copy = readl(phba->HAregaddr); - - while ((i++ < 30) && !(ha_copy & HA_ERATT)) { - mdelay(100); - ha_copy = readl(phba->HAregaddr); - } + /* Turn off parity checking and serr during the physical reset */ + pci_read_config_word(phba->pcidev, PCI_COMMAND, &phba->pci_cfg_value); + pci_write_config_word(phba->pcidev, PCI_COMMAND, + (phba->pci_cfg_value & + ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); - del_timer_sync(&psli->mbox_tmo); - if (ha_copy & HA_ERATT) { - writel(HA_ERATT, phba->HAregaddr); - phba->stopped = 1; - } - spin_lock_irq(phba->host->host_lock); - psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; - spin_unlock_irq(phba->host->host_lock); + writel(HC_INITFF, phba->HCregaddr); - psli->mbox_active = NULL; - lpfc_hba_down_post(phba); - phba->hba_state = LPFC_HBA_ERROR; + phba->hba_state = LPFC_INIT_START; + spin_unlock_irqrestore(phba->host->host_lock, flags); - return (ha_copy & HA_ERATT ? 0 : 1); + return 0; } -int -lpfc_sli_brdreset(struct lpfc_hba * phba) +static int +lpfc_sli_brdreset(struct lpfc_hba * phba, uint16_t skip_post) { - struct lpfc_sli *psli; struct lpfc_sli_ring *pring; - uint16_t cfg_value; int i; + struct lpfc_dmabuf *mp, *next_mp; + unsigned long flags = 0; - psli = &phba->sli; - - /* Reset HBA */ - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no, - phba->hba_state, psli->sli_flag); - - /* perform board reset */ - phba->fc_eventTag = 0; - phba->fc_myDID = 0; - phba->fc_prevDID = 0; - - psli->sli_flag = 0; - - /* Turn off parity checking and serr during the physical reset */ - pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value); - pci_write_config_word(phba->pcidev, PCI_COMMAND, - (cfg_value & - ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); - - psli->sli_flag &= ~LPFC_SLI2_ACTIVE; - /* Now toggle INITFF bit in the Host Control Register */ - writel(HC_INITFF, phba->HCregaddr); + lpfc_sli_send_reset(phba, skip_post); mdelay(1); + + spin_lock_irqsave(phba->host->host_lock, flags); + /* Risk the write on flush case ie no delay after the readl */ readl(phba->HCregaddr); /* flush */ + /* Now toggle INITFF bit set by lpfc_sli_send_reset */ writel(0, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ /* Restore PCI cmd register */ - pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value); + pci_write_config_word(phba->pcidev, PCI_COMMAND, phba->pci_cfg_value); + + /* perform board reset */ + phba->fc_eventTag = 0; + phba->fc_myDID = 0; + phba->fc_prevDID = Mask_DID; + + /* Reset HBA */ + lpfc_printf_log(phba, + KERN_INFO, + LOG_SLI, + "%d:0325 Reset HBA Data: x%x x%x x%x\n", + phba->brd_no, + phba->hba_state, + phba->sli.sli_flag, + skip_post); /* Initialize relevant SLI info */ - for (i = 0; i < psli->num_rings; i++) { - pring = &psli->ring[i]; + for (i = 0; i < phba->sli.num_rings; i++) { + pring = &phba->sli.ring[i]; pring->flag = 0; pring->rspidx = 0; pring->next_cmdidx = 0; @@ -1763,64 +1611,27 @@ lpfc_sli_brdreset(struct lpfc_hba * phba) pring->cmdidx = 0; pring->missbufcnt = 0; } + spin_unlock_irqrestore(phba->host->host_lock, flags); - phba->hba_state = LPFC_WARM_START; - return 0; -} - -int -lpfc_sli_brdrestart(struct lpfc_hba * phba) -{ - MAILBOX_t *mb; - struct lpfc_sli *psli; - uint16_t skip_post; - volatile uint32_t word0; - void __iomem *to_slim; - - spin_lock_irq(phba->host->host_lock); - - psli = &phba->sli; - - /* Restart HBA */ - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0328 Restart HBA Data: x%x x%x\n", phba->brd_no, - phba->hba_state, psli->sli_flag); - - word0 = 0; - mb = (MAILBOX_t *) &word0; - mb->mbxCommand = MBX_RESTART; - mb->mbxHc = 1; - - lpfc_reset_barrier(phba); - - to_slim = phba->MBslimaddr; - writel(*(uint32_t *) mb, to_slim); - readl(to_slim); /* flush */ - - /* Only skip post after fc_ffinit is completed */ - if (phba->hba_state) { - skip_post = 1; - word0 = 1; /* This is really setting up word1 */ + if (skip_post) { + mdelay(100); } else { - skip_post = 0; - word0 = 0; /* This is really setting up word1 */ + mdelay(2000); } - to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t); - writel(*(uint32_t *) mb, to_slim); - readl(to_slim); /* flush */ - - lpfc_sli_brdreset(phba); - phba->stopped = 0; - phba->hba_state = LPFC_INIT_START; - spin_unlock_irq(phba->host->host_lock); - - if (skip_post) - mdelay(100); - else - mdelay(2000); + spin_lock_irqsave(phba->host->host_lock, flags); + /* Cleanup preposted buffers on the ELS ring */ + pring = &phba->sli.ring[LPFC_ELS_RING]; + list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { + list_del(&mp->list); + pring->postbufq_cnt--; + lpfc_mbuf_free(phba, mp->virt, mp->phys); + kfree(mp); + } + spin_unlock_irqrestore(phba->host->host_lock, flags); - lpfc_hba_down_post(phba); + for (i = 0; i < phba->sli.num_rings; i++) + lpfc_sli_abort_iocb_ring(phba, &phba->sli.ring[i]); return 0; } @@ -1880,8 +1691,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) } if (i == 15) { - phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */ - lpfc_sli_brdrestart(phba); + lpfc_sli_brdreset(phba, 0); } /* Read the HBA Host Status Register */ status = readl(phba->HSregaddr); @@ -1925,8 +1735,8 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) } while (resetcount < 2 && !done) { - phba->hba_state = LPFC_STATE_UNKNOWN; - lpfc_sli_brdrestart(phba); + phba->hba_state = 0; + lpfc_sli_brdreset(phba, 0); msleep(2500); rc = lpfc_sli_chipset_init(phba); if (rc) @@ -2110,21 +1920,6 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) mb = &pmbox->mb; status = MBX_SUCCESS; - if (phba->hba_state == LPFC_HBA_ERROR) { - spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); - - /* Mbox command cannot issue */ - LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) - return (MBX_NOT_FINISHED); - } - - if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && - !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { - spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); - LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) - return (MBX_NOT_FINISHED); - } - if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { /* Polling for a mbox command when another one is already active * is not allowed in SLI. Also, the driver must have established @@ -2207,8 +2002,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) /* If we are not polling, we MUST be in SLI2 mode */ if (flag != MBX_POLL) { - if (!(psli->sli_flag & LPFC_SLI2_ACTIVE) && - (mb->mbxCommand != MBX_KILL_BOARD)) { + if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); @@ -2292,9 +2086,8 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) ha_copy = readl(phba->HAregaddr); /* Wait for command to complete */ - while (((word0 & OWN_CHIP) == OWN_CHIP) || - (!(ha_copy & HA_MBATT) && - (phba->hba_state > LPFC_WARM_START))) { + while (((word0 & OWN_CHIP) == OWN_CHIP) + || !(ha_copy & HA_MBATT)) { if (i++ >= 100) { psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; spin_unlock_irqrestore(phba->host->host_lock, @@ -2444,6 +2237,16 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, !(phba->sli.sli_flag & LPFC_PROCESS_LA))) goto iocb_busy; + /* + * Check to see if this is a high priority command. + * If so bypass tx queue processing. + */ + if (unlikely((flag & SLI_IOCB_HIGH_PRIORITY) && + (iocb = lpfc_sli_next_iocb_slot(phba, pring)))) { + lpfc_sli_submit_iocb(phba, pring, iocb, piocb); + piocb = NULL; + } + while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && (nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb))) lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb); @@ -2471,37 +2274,6 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return IOCB_BUSY; } -static int -lpfc_extra_ring_setup( struct lpfc_hba *phba) -{ - struct lpfc_sli *psli; - struct lpfc_sli_ring *pring; - - psli = &phba->sli; - - /* Adjust cmd/rsp ring iocb entries more evenly */ - pring = &psli->ring[psli->fcp_ring]; - pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES; - pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES; - pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES; - pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES; - - pring = &psli->ring[1]; - pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES; - pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES; - pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES; - pring->numRiocb += SLI2_IOCB_RSP_R3XTRA_ENTRIES; - - /* Setup default profile for this ring */ - pring->iotag_max = 4096; - pring->num_mask = 1; - pring->prt[0].profile = 0; /* Mask 0 */ - pring->prt[0].rctl = FC_UNSOL_DATA; - pring->prt[0].type = 5; - pring->prt[0].lpfc_sli_rcv_unsol_event = NULL; - return 0; -} - int lpfc_sli_setup(struct lpfc_hba *phba) { @@ -2585,8 +2357,6 @@ lpfc_sli_setup(struct lpfc_hba *phba) "SLI2 SLIM Data: x%x x%x\n", phba->brd_no, totiocb, MAX_SLI2_IOCB); } - if (phba->cfg_multi_ring_support == 2) - lpfc_extra_ring_setup(phba); return 0; } @@ -2695,6 +2465,15 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) spin_unlock_irqrestore(phba->host->host_lock, flags); + /* + * Provided the hba is not in an error state, reset it. It is not + * capable of IO anymore. + */ + if (phba->hba_state != LPFC_HBA_ERROR) { + phba->hba_state = LPFC_INIT_START; + lpfc_sli_brdreset(phba, 1); + } + return 1; } @@ -3098,10 +2877,11 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, pmboxq->context1 = NULL; /* if schedule_timeout returns 0, we timed out and were not woken up */ - if ((timeleft == 0) || signal_pending(current)) + if (timeleft == 0) { retval = MBX_TIMEOUT; - else + } else { retval = MBX_SUCCESS; + } } @@ -3207,7 +2987,13 @@ lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs) /* Clear Chip error bit */ writel(HA_ERATT, phba->HAregaddr); readl(phba->HAregaddr); /* flush */ - phba->stopped = 1; + + /* + * Reseting the HBA is the only reliable way + * to shutdown interrupt when there is a + * ERROR. + */ + lpfc_sli_send_reset(phba, phba->hba_state); } spin_lock(phba->host->host_lock); diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index a52d6c6cf..b7a9f970f 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -61,6 +61,7 @@ struct lpfc_iocbq { }; #define SLI_IOCB_RET_IOCB 1 /* Return IOCB if cmd ring full */ +#define SLI_IOCB_HIGH_PRIORITY 2 /* High priority command */ #define IOCB_SUCCESS 0 #define IOCB_BUSY 1 @@ -199,6 +200,8 @@ struct lpfc_sli { struct timer_list mbox_tmo; /* Hold clk to timeout active mbox cmd */ + uint32_t *MBhostaddr; /* virtual address for mbox cmds */ + #define LPFC_IOCBQ_LOOKUP_INCREMENT 1024 struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */ size_t iocbq_lookup_len; /* current lengs of the array */ diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 6b737568b..fa681a934 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2006 Emulex. All rights reserved. * + * Copyright (C) 2004-2005 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -18,12 +18,12 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.1.6" +#define LPFC_DRIVER_VERSION "8.1.1" #define LPFC_DRIVER_NAME "lpfc" #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ LPFC_DRIVER_VERSION -#define LPFC_COPYRIGHT "Copyright(c) 2004-2006 Emulex. All rights reserved." +#define LPFC_COPYRIGHT "Copyright(c) 2004-2005 Emulex. All rights reserved." #define DFC_API_VERSION "0.0.0" diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index de35ffe2f..7144674bc 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include "scsi.h" @@ -2095,7 +2094,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, 0xffffffff) != 0 ) { kfree(*pdev); return -1; } @@ -4471,6 +4470,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) { Scsi_Cmnd *scmd; struct scsi_device *sdev; + unsigned long flags = 0; scb_t *scb; int rval; @@ -4859,10 +4859,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, 0xffffffffffffffffULL); adapter->has_64bit_addr = 1; } else { - pci_set_dma_mask(pdev, DMA_32BIT_MASK); + pci_set_dma_mask(pdev, 0xffffffff); adapter->has_64bit_addr = 0; } diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index bec1424ed..bf9f7f7ba 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_mbox.c - * Version : v2.20.4.8 (Apr 11 2006) + * Version : v2.20.4.7 (Nov 14 2005) * * Authors: * Atul Mukker @@ -2278,7 +2278,6 @@ megaraid_mbox_dpc(unsigned long devp) unsigned long flags; uint8_t c; int status; - uioc_t *kioc; if (!adapter) return; @@ -2321,9 +2320,6 @@ megaraid_mbox_dpc(unsigned long devp) // remove from local clist list_del_init(&scb->list); - kioc = (uioc_t *)scb->gp; - kioc->status = 0; - megaraid_mbox_mm_done(adapter, scb); continue; @@ -2640,7 +2636,6 @@ megaraid_reset_handler(struct scsi_cmnd *scp) int recovery_window; int recovering; int i; - uioc_t *kioc; adapter = SCP2ADAPTER(scp); raid_dev = ADAP2RAIDDEV(adapter); @@ -2660,51 +2655,32 @@ megaraid_reset_handler(struct scsi_cmnd *scp) // Also, reset all the commands currently owned by the driver spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) { - list_del_init(&scb->list); // from pending list - - if (scb->sno >= MBOX_MAX_SCSI_CMDS) { - con_log(CL_ANN, (KERN_WARNING - "megaraid: IOCTL packet with %d[%d:%d] being reset\n", - scb->sno, scb->dev_channel, scb->dev_target)); - scb->status = -1; - - kioc = (uioc_t *)scb->gp; - kioc->status = -EFAULT; + list_del_init(&scb->list); // from pending list - megaraid_mbox_mm_done(adapter, scb); - } else { - if (scb->scp == scp) { // Found command - con_log(CL_ANN, (KERN_WARNING - "megaraid: %ld:%d[%d:%d], reset from pending list\n", - scp->serial_number, scb->sno, - scb->dev_channel, scb->dev_target)); - } else { - con_log(CL_ANN, (KERN_WARNING - "megaraid: IO packet with %d[%d:%d] being reset\n", - scb->sno, scb->dev_channel, scb->dev_target)); - } + con_log(CL_ANN, (KERN_WARNING + "megaraid: %ld:%d[%d:%d], reset from pending list\n", + scp->serial_number, scb->sno, + scb->dev_channel, scb->dev_target)); - scb->scp->result = (DID_RESET << 16); - scb->scp->scsi_done(scb->scp); + scp->result = (DID_RESET << 16); + scp->scsi_done(scp); - megaraid_dealloc_scb(adapter, scb); - } + megaraid_dealloc_scb(adapter, scb); } spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); if (adapter->outstanding_cmds) { con_log(CL_ANN, (KERN_NOTICE "megaraid: %d outstanding commands. Max wait %d sec\n", - adapter->outstanding_cmds, - (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT))); + adapter->outstanding_cmds, MBOX_RESET_WAIT)); } recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; recovering = adapter->outstanding_cmds; - for (i = 0; i < recovery_window; i++) { + for (i = 0; i < recovery_window && adapter->outstanding_cmds; i++) { megaraid_ack_sequence(adapter); @@ -2713,11 +2689,12 @@ megaraid_reset_handler(struct scsi_cmnd *scp) con_log(CL_ANN, ( "megaraid mbox: Wait for %d commands to complete:%d\n", adapter->outstanding_cmds, - (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT) - i)); + MBOX_RESET_WAIT - i)); } // bailout if no recovery happended in reset time - if (adapter->outstanding_cmds == 0) { + if ((i == MBOX_RESET_WAIT) && + (recovering == adapter->outstanding_cmds)) { break; } @@ -2820,7 +2797,7 @@ mbox_post_sync_cmd(adapter_t *adapter, uint8_t raw_mbox[]) // available within 1 second, assume FW is initializing and wait // for an extended amount of time if (mbox->numstatus == 0xFF) { // status not yet available - udelay(25); + udelay(25);; for (i = 0; mbox->numstatus == 0xFF && i < 1000; i++) { rmb(); @@ -2941,13 +2918,12 @@ mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[]) wmb(); WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1); - for (i = 0; i < MBOX_SYNC_WAIT_CNT; i++) { + for (i = 0; i < 0xFFFFF; i++) { if (mbox->numstatus != 0xFF) break; rmb(); - udelay(MBOX_SYNC_DELAY_200); } - if (i == MBOX_SYNC_WAIT_CNT) { + if (i == 0xFFFFF) { // We may need to re-calibrate the counter con_log(CL_ANN, (KERN_CRIT "megaraid: fast sync command timed out\n")); @@ -3499,7 +3475,7 @@ megaraid_cmm_register(adapter_t *adapter) adp.drvr_data = (unsigned long)adapter; adp.pdev = adapter->pdev; adp.issue_uioc = megaraid_mbox_mm_handler; - adp.timeout = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; + adp.timeout = 300; adp.max_kioc = MBOX_MAX_USER_CMDS; if ((rval = mraid_mm_register_adp(&adp)) != 0) { @@ -3726,6 +3702,7 @@ megaraid_mbox_mm_done(adapter_t *adapter, scb_t *scb) unsigned long flags; kioc = (uioc_t *)scb->gp; + kioc->status = 0; mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf; mbox64->mbox32.status = scb->status; raw_mbox = (uint8_t *)&mbox64->mbox32; diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h index 868fb0ec9..882fb1a0b 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.h +++ b/drivers/scsi/megaraid/megaraid_mbox.h @@ -21,8 +21,8 @@ #include "megaraid_ioctl.h" -#define MEGARAID_VERSION "2.20.4.8" -#define MEGARAID_EXT_VERSION "(Release Date: Mon Apr 11 12:27:22 EST 2006)" +#define MEGARAID_VERSION "2.20.4.7" +#define MEGARAID_EXT_VERSION "(Release Date: Mon Nov 14 12:27:22 EST 2005)" /* @@ -100,9 +100,6 @@ #define MBOX_BUSY_WAIT 10 // max usec to wait for busy mailbox #define MBOX_RESET_WAIT 180 // wait these many seconds in reset #define MBOX_RESET_EXT_WAIT 120 // extended wait reset -#define MBOX_SYNC_WAIT_CNT 0xFFFF // wait loop index for synchronous mode - -#define MBOX_SYNC_DELAY_200 200 // 200 micro-seconds /* * maximum transfer that can happen through the firmware commands issued diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index e8f534fb3..8f3ce0432 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -898,8 +898,10 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) adapter = kmalloc(sizeof(mraid_mmadp_t), GFP_KERNEL); - if (!adapter) - return -ENOMEM; + if (!adapter) { + rval = -ENOMEM; + goto memalloc_error; + } memset(adapter, 0, sizeof(mraid_mmadp_t)); diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 39729460b..4f39dd019 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -772,6 +772,8 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) goto out_return_cmd; cmd->scmd = scmd; + scmd->SCp.ptr = (char *)cmd; + scmd->SCp.sent_command = jiffies; /* * Issue the command to the FW @@ -802,12 +804,6 @@ static int megasas_slave_configure(struct scsi_device *sdev) */ if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK) return -ENXIO; - - /* - * The RAID firmware may require extended timeouts. - */ - if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) - sdev->timeout = 90 * HZ; return 0; } @@ -879,6 +875,23 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) return ret_val; } +static enum scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) +{ + unsigned long seconds; + + if (scmd->SCp.ptr) { + seconds = (jiffies - scmd->SCp.sent_command) / HZ; + + if (seconds < 90) { + return EH_RESET_TIMER; + } else { + return EH_NOT_HANDLED; + } + } + + return EH_HANDLED; +} + /** * megasas_reset_device - Device reset handler entry point */ @@ -902,7 +915,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) int ret; /* - * First wait for all commands to complete + * Frist wait for all commands to complete */ ret = megasas_generic_reset(scmd); @@ -949,6 +962,7 @@ static struct scsi_host_template megasas_template = { .eh_device_reset_handler = megasas_reset_device, .eh_bus_reset_handler = megasas_reset_bus_host, .eh_host_reset_handler = megasas_reset_bus_host, + .eh_timed_out = megasas_reset_timer, .use_clustering = ENABLE_CLUSTERING, }; diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index f85242100..d6d2125f9 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -1748,7 +1748,7 @@ static int mesh_host_reset(struct scsi_cmnd *cmd) static void set_mesh_power(struct mesh_state *ms, int state) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; if (state) { pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 1); diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 22f913127..32350707b 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -69,10 +69,6 @@ ** Low PCI traffic for command handling when on-chip RAM is present. ** Aggressive SCSI SCRIPTS optimizations. ** -** 2005 by Matthew Wilcox and James Bottomley -** PCI-ectomy. This driver now supports only the 720 chip (see the -** NCR_Q720 and zalon drivers for the bus probe logic). -** ******************************************************************************* */ @@ -94,6 +90,13 @@ #define SCSI_NCR_DEBUG_FLAGS (0) +/*========================================================== +** +** Include files +** +**========================================================== +*/ + #include #include #include @@ -118,7 +121,6 @@ #include #include -#include #include #include #include @@ -126,8 +128,10 @@ #include "ncr53c8xx.h" +#define NAME53C "ncr53c" #define NAME53C8XX "ncr53c8xx" + /*========================================================== ** ** Debugging tags @@ -2107,7 +2111,7 @@ static struct script script0 __initdata = { */ /* - ** The MESSAGE_REJECT problem seems to be due to a selection + ** The M_REJECT problem seems to be due to a selection ** timing problem. ** Wait immediately for the selection to complete. ** (2.5x behaves so) @@ -2158,7 +2162,7 @@ static struct script script0 __initdata = { /* ** Selection complete. ** Send the IDENTIFY and SIMPLE_TAG messages - ** (and the EXTENDED_SDTR message) + ** (and the M_X_SYNC_REQ message) */ SCR_MOVE_TBL ^ SCR_MSG_OUT, offsetof (struct dsb, smsg), @@ -2187,7 +2191,7 @@ static struct script script0 __initdata = { /* ** Initialize the msgout buffer with a NOOP message. */ - SCR_LOAD_REG (scratcha, NOP), + SCR_LOAD_REG (scratcha, M_NOOP), 0, SCR_COPY (1), RADDR (scratcha), @@ -2339,21 +2343,21 @@ static struct script script0 __initdata = { /* ** Handle this message. */ - SCR_JUMP ^ IFTRUE (DATA (COMMAND_COMPLETE)), + SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)), PADDR (complete), - SCR_JUMP ^ IFTRUE (DATA (DISCONNECT)), + SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)), PADDR (disconnect), - SCR_JUMP ^ IFTRUE (DATA (SAVE_POINTERS)), + SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)), PADDR (save_dp), - SCR_JUMP ^ IFTRUE (DATA (RESTORE_POINTERS)), + SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)), PADDR (restore_dp), - SCR_JUMP ^ IFTRUE (DATA (EXTENDED_MESSAGE)), + SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), PADDRH (msg_extended), - SCR_JUMP ^ IFTRUE (DATA (NOP)), + SCR_JUMP ^ IFTRUE (DATA (M_NOOP)), PADDR (clrack), - SCR_JUMP ^ IFTRUE (DATA (MESSAGE_REJECT)), + SCR_JUMP ^ IFTRUE (DATA (M_REJECT)), PADDRH (msg_reject), - SCR_JUMP ^ IFTRUE (DATA (IGNORE_WIDE_RESIDUE)), + SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)), PADDRH (msg_ign_residue), /* ** Rest of the messages left as @@ -2368,7 +2372,7 @@ static struct script script0 __initdata = { */ SCR_INT, SIR_REJECT_SENT, - SCR_LOAD_REG (scratcha, MESSAGE_REJECT), + SCR_LOAD_REG (scratcha, M_REJECT), 0, }/*-------------------------< SETMSG >----------------------*/,{ SCR_COPY (1), @@ -2560,7 +2564,7 @@ static struct script script0 __initdata = { /* ** If it was no ABORT message ... */ - SCR_JUMP ^ IFTRUE (DATA (ABORT_TASK_SET)), + SCR_JUMP ^ IFTRUE (DATA (M_ABORT)), PADDRH (msg_out_abort), /* ** ... wait for the next phase @@ -2572,7 +2576,7 @@ static struct script script0 __initdata = { /* ** ... else clear the message ... */ - SCR_LOAD_REG (scratcha, NOP), + SCR_LOAD_REG (scratcha, M_NOOP), 0, SCR_COPY (4), RADDR (scratcha), @@ -3031,7 +3035,7 @@ static struct scripth scripth0 __initdata = { */ SCR_MOVE_ABS (1) ^ SCR_MSG_IN, NADDR (msgin[2]), - SCR_JUMP ^ IFTRUE (DATA (EXTENDED_WDTR)), + SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)), PADDRH (msg_wdtr), /* ** unknown extended message @@ -3065,7 +3069,7 @@ static struct scripth scripth0 __initdata = { }/*-------------------------< SEND_WDTR >----------------*/,{ /* - ** Send the EXTENDED_WDTR + ** Send the M_X_WIDE_REQ */ SCR_MOVE_ABS (4) ^ SCR_MSG_OUT, NADDR (msgout), @@ -3085,7 +3089,7 @@ static struct scripth scripth0 __initdata = { */ SCR_MOVE_ABS (1) ^ SCR_MSG_IN, NADDR (msgin[2]), - SCR_JUMP ^ IFTRUE (DATA (EXTENDED_SDTR)), + SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)), PADDRH (msg_sdtr), /* ** unknown extended message @@ -3120,7 +3124,7 @@ static struct scripth scripth0 __initdata = { }/*-------------------------< SEND_SDTR >-------------*/,{ /* - ** Send the EXTENDED_SDTR + ** Send the M_X_SYNC_REQ */ SCR_MOVE_ABS (5) ^ SCR_MSG_OUT, NADDR (msgout), @@ -3198,10 +3202,10 @@ static struct scripth scripth0 __initdata = { }/*-------------------------< RESET >----------------------*/,{ /* - ** Send a TARGET_RESET message if bad IDENTIFY + ** Send a M_RESET message if bad IDENTIFY ** received on reselection. */ - SCR_LOAD_REG (scratcha, ABORT_TASK), + SCR_LOAD_REG (scratcha, M_ABORT_TAG), 0, SCR_JUMP, PADDRH (abort_resel), @@ -3209,7 +3213,7 @@ static struct scripth scripth0 __initdata = { /* ** Abort a wrong tag received on reselection. */ - SCR_LOAD_REG (scratcha, ABORT_TASK), + SCR_LOAD_REG (scratcha, M_ABORT_TAG), 0, SCR_JUMP, PADDRH (abort_resel), @@ -3217,7 +3221,7 @@ static struct scripth scripth0 __initdata = { /* ** Abort a reselection when no active CCB. */ - SCR_LOAD_REG (scratcha, ABORT_TASK_SET), + SCR_LOAD_REG (scratcha, M_ABORT), 0, }/*-------------------------< ABORT_RESEL >----------------*/,{ SCR_COPY (1), @@ -3329,7 +3333,7 @@ static struct scripth scripth0 __initdata = { ** Read the message, since we got it directly ** from the SCSI BUS data lines. ** Signal problem to C code for logging the event. - ** Send an ABORT_TASK_SET to clear all pending tasks. + ** Send a M_ABORT to clear all pending tasks. */ SCR_INT, SIR_RESEL_BAD_LUN, @@ -3341,7 +3345,7 @@ static struct scripth scripth0 __initdata = { /* ** We donnot have a task for that I_T_L. ** Signal problem to C code for logging the event. - ** Send an ABORT_TASK_SET message. + ** Send a M_ABORT message. */ SCR_INT, SIR_RESEL_BAD_I_T_L, @@ -3351,7 +3355,7 @@ static struct scripth scripth0 __initdata = { /* ** We donnot have a task that matches the tag. ** Signal problem to C code for logging the event. - ** Send an ABORT_TASK message. + ** Send a M_ABORTTAG message. */ SCR_INT, SIR_RESEL_BAD_I_T_L_Q, @@ -3362,7 +3366,7 @@ static struct scripth scripth0 __initdata = { ** We donnot know the target that reselected us. ** Grab the first message if any (IDENTIFY). ** Signal problem to C code for logging the event. - ** TARGET_RESET message. + ** M_RESET message. */ SCR_INT, SIR_RESEL_BAD_TARGET, @@ -4105,11 +4109,17 @@ static int ncr_prepare_nego(struct ncb *np, struct ccb *cp, u_char *msgptr) switch (nego) { case NS_SYNC: - msglen += spi_populate_sync_msg(msgptr + msglen, - tp->maxoffs ? tp->minsync : 0, tp->maxoffs); + msgptr[msglen++] = M_EXTENDED; + msgptr[msglen++] = 3; + msgptr[msglen++] = M_X_SYNC_REQ; + msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0; + msgptr[msglen++] = tp->maxoffs; break; case NS_WIDE: - msglen += spi_populate_width_msg(msgptr + msglen, tp->usrwide); + msgptr[msglen++] = M_EXTENDED; + msgptr[msglen++] = 2; + msgptr[msglen++] = M_X_WIDE_REQ; + msgptr[msglen++] = tp->usrwide; break; } @@ -4210,7 +4220,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd) **---------------------------------------------------- */ - idmsg = IDENTIFY(0, sdev->lun); + idmsg = M_IDENTIFY | sdev->lun; if (cp ->tag != NO_TAG || (cp != np->ccb && np->disc && !(tp->usrflag & UF_NODISC))) @@ -4229,7 +4239,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd) */ if (lp && time_after(jiffies, lp->tags_stime)) { if (lp->tags_smap) { - order = ORDERED_QUEUE_TAG; + order = M_ORDERED_TAG; if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){ PRINT_ADDR(cmd, "ordered tag forced.\n"); @@ -4247,10 +4257,10 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd) case 0x08: /* READ_SMALL (6) */ case 0x28: /* READ_BIG (10) */ case 0xa8: /* READ_HUGE (12) */ - order = SIMPLE_QUEUE_TAG; + order = M_SIMPLE_TAG; break; default: - order = ORDERED_QUEUE_TAG; + order = M_ORDERED_TAG; } } msgptr[msglen++] = order; @@ -6219,9 +6229,9 @@ static int ncr_int_par (struct ncb *np) if (!(dbc & 0xc0000000)) phase = (dbc >> 24) & 7; if (phase == 7) - msg = MSG_PARITY_ERROR; + msg = M_PARITY; else - msg = INITIATOR_ERROR; + msg = M_ID_ERROR; /* @@ -6785,8 +6795,6 @@ void ncr_int_sir (struct ncb *np) /*----------------------------------------------------------------------------- ** ** Was Sie schon immer ueber transfermode negotiation wissen wollten ... -** ("Everything you've always wanted to know about transfer mode -** negotiation") ** ** We try to negotiate sync and wide transfer only after ** a successful inquire command. We look at byte 7 of the @@ -6888,8 +6896,8 @@ void ncr_int_sir (struct ncb *np) break; } - np->msgin [0] = NOP; - np->msgout[0] = NOP; + np->msgin [0] = M_NOOP; + np->msgout[0] = M_NOOP; cp->nego_status = 0; break; @@ -6983,7 +6991,12 @@ void ncr_int_sir (struct ncb *np) spi_offset(starget) = ofs; ncr_setsync(np, cp, scntl3, (fak<<5)|ofs); - spi_populate_sync_msg(np->msgout, per, ofs); + np->msgout[0] = M_EXTENDED; + np->msgout[1] = 3; + np->msgout[2] = M_X_SYNC_REQ; + np->msgout[3] = per; + np->msgout[4] = ofs; + cp->nego_status = NS_SYNC; if (DEBUG_FLAGS & DEBUG_NEGO) { @@ -6994,7 +7007,7 @@ void ncr_int_sir (struct ncb *np) OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad)); return; } - np->msgin [0] = NOP; + np->msgin [0] = M_NOOP; break; @@ -7069,9 +7082,13 @@ void ncr_int_sir (struct ncb *np) spi_width(starget) = wide; ncr_setwide(np, cp, wide, 1); - spi_populate_width_msg(np->msgout, wide); - np->msgin [0] = NOP; + np->msgout[0] = M_EXTENDED; + np->msgout[1] = 2; + np->msgout[2] = M_X_WIDE_REQ; + np->msgout[3] = wide; + + np->msgin [0] = M_NOOP; cp->nego_status = NS_WIDE; @@ -7090,12 +7107,12 @@ void ncr_int_sir (struct ncb *np) case SIR_REJECT_RECEIVED: /*----------------------------------------------- ** - ** We received a MESSAGE_REJECT. + ** We received a M_REJECT message. ** **----------------------------------------------- */ - PRINT_ADDR(cp->cmd, "MESSAGE_REJECT received (%x:%x).\n", + PRINT_ADDR(cp->cmd, "M_REJECT received (%x:%x).\n", (unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]); break; @@ -7107,7 +7124,7 @@ void ncr_int_sir (struct ncb *np) **----------------------------------------------- */ - ncr_print_msg(cp, "MESSAGE_REJECT sent for", np->msgin); + ncr_print_msg(cp, "M_REJECT sent for", np->msgin); break; /*-------------------------------------------------------------------- @@ -7126,7 +7143,7 @@ void ncr_int_sir (struct ncb *np) **----------------------------------------------- */ - PRINT_ADDR(cp->cmd, "IGNORE_WIDE_RESIDUE received, but not yet " + PRINT_ADDR(cp->cmd, "M_IGN_RESIDUE received, but not yet " "implemented.\n"); break; #if 0 @@ -7139,7 +7156,7 @@ void ncr_int_sir (struct ncb *np) **----------------------------------------------- */ - PRINT_ADDR(cp->cmd, "DISCONNECT received, but datapointer " + PRINT_ADDR(cp->cmd, "M_DISCONNECT received, but datapointer " "not saved: data=%x save=%x goal=%x.\n", (unsigned) INL (nc_temp), (unsigned) scr_to_cpu(np->header.savep), @@ -7845,7 +7862,7 @@ static int __init ncr_snooptest (struct ncb* np) **========================================================== ** ** Note: we have to return the correct value. -** THERE IS NO SAFE DEFAULT VALUE. +** THERE IS NO SAVE DEFAULT VALUE. ** ** Most NCR/SYMBIOS boards are delivered with a 40 Mhz clock. ** 53C860 and 53C875 rev. 1 support fast20 transfers but @@ -8545,7 +8562,7 @@ struct Scsi_Host * __init ncr_attach(struct scsi_host_template *tpnt, /* use SIMPLE TAG messages by default */ #ifdef SCSI_NCR_ALWAYS_SIMPLE_TAG - np->order = SIMPLE_QUEUE_TAG; + np->order = M_SIMPLE_TAG; #endif spin_unlock_irqrestore(&np->smp_lock, flags); diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h index 0e4e46a01..6a7bef2e6 100644 --- a/drivers/scsi/ncr53c8xx.h +++ b/drivers/scsi/ncr53c8xx.h @@ -56,10 +56,8 @@ #include #include -#include - /* -** If you want a driver as small as possible, donnot define the +** If you want a driver as small as possible, do not define the ** following options. */ #define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT @@ -1256,6 +1254,39 @@ struct scr_tblsel { **----------------------------------------------------------- */ +/* +** Messages +*/ + +#define M_COMPLETE COMMAND_COMPLETE +#define M_EXTENDED EXTENDED_MESSAGE +#define M_SAVE_DP SAVE_POINTERS +#define M_RESTORE_DP RESTORE_POINTERS +#define M_DISCONNECT DISCONNECT +#define M_ID_ERROR INITIATOR_ERROR +#define M_ABORT ABORT_TASK_SET +#define M_REJECT MESSAGE_REJECT +#define M_NOOP NOP +#define M_PARITY MSG_PARITY_ERROR +#define M_LCOMPLETE LINKED_CMD_COMPLETE +#define M_FCOMPLETE LINKED_FLG_CMD_COMPLETE +#define M_RESET TARGET_RESET +#define M_ABORT_TAG ABORT_TASK +#define M_CLEAR_QUEUE CLEAR_TASK_SET +#define M_INIT_REC INITIATE_RECOVERY +#define M_REL_REC RELEASE_RECOVERY +#define M_TERMINATE (0x11) +#define M_SIMPLE_TAG SIMPLE_QUEUE_TAG +#define M_HEAD_TAG HEAD_OF_QUEUE_TAG +#define M_ORDERED_TAG ORDERED_QUEUE_TAG +#define M_IGN_RESIDUE IGNORE_WIDE_RESIDUE +#define M_IDENTIFY (0x80) + +#define M_X_MODIFY_DP EXTENDED_MODIFY_DATA_POINTER +#define M_X_SYNC_REQ EXTENDED_SDTR +#define M_X_WIDE_REQ EXTENDED_WDTR +#define M_X_PPR_REQ EXTENDED_PPR + /* ** Status */ diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 30ee0ef4b..a279ebb61 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -2777,7 +2776,7 @@ static int nsp32_detect(struct scsi_host_template *sht) /* * setup DMA */ - if (pci_set_dma_mask(PCIDEV, DMA_32BIT_MASK) != 0) { + if (pci_set_dma_mask(PCIDEV, 0xffffffffUL) != 0) { nsp32_msg (KERN_ERR, "failed to set PCI DMA mask"); goto scsi_unregister; } diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index e3bd4bc33..d9946bd95 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -13,7 +13,7 @@ order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede + Copyright 1992 - 2002 Kai Makisara / 2000 - 2004 Willem Riede email osst@riede.org $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $ @@ -24,7 +24,7 @@ */ static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $"; -static const char * osst_version = "0.99.4"; +static const char * osst_version = "0.99.3"; /* The "failure to reconnect" firmware bug */ #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/ @@ -48,8 +48,8 @@ static const char * osst_version = "0.99.4"; #include #include #include +#include #include -#include #include #include #include @@ -70,6 +70,7 @@ static const char * osst_version = "0.99.4"; #include #include #include +#include #define ST_KILOBYTE 1024 @@ -86,7 +87,6 @@ static int max_sg_segs = 0; MODULE_AUTHOR("Willem Riede"); MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR); module_param(max_dev, int, 0444); MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); @@ -107,6 +107,8 @@ static struct osst_dev_parm { }; #endif +static char *osst_formats[ST_NBR_MODES] ={"", "l", "m", "a"}; + /* Some default definitions have been moved to osst_options.h */ #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE) #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE) @@ -177,16 +179,16 @@ static struct scsi_driver osst_template = { } }; -static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt, +static int osst_int_ioctl(struct osst_tape *STp, struct scsi_request ** aSRpnt, unsigned int cmd_in, unsigned long arg); -static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip); +static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int frame, int skip); -static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt); +static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt); -static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt); +static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt); -static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending); +static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending); static inline char *tape_name(struct osst_tape *tape) { @@ -195,84 +197,52 @@ static inline char *tape_name(struct osst_tape *tape) /* Routines that handle the interaction with mid-layer SCSI routines */ - -/* Normalize Sense */ -static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s) -{ - const u8 *ucp; - const u8 *sense = SRpnt->sense; - - s->have_sense = scsi_normalize_sense(SRpnt->sense, - SCSI_SENSE_BUFFERSIZE, &s->sense_hdr); - s->flags = 0; - - if (s->have_sense) { - s->deferred = 0; - s->remainder_valid = - scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64); - switch (sense[0] & 0x7f) { - case 0x71: - s->deferred = 1; - case 0x70: - s->fixed_format = 1; - s->flags = sense[2] & 0xe0; - break; - case 0x73: - s->deferred = 1; - case 0x72: - s->fixed_format = 0; - ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4); - s->flags = ucp ? (ucp[3] & 0xe0) : 0; - break; - } - } -} - /* Convert the result to success code */ -static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt) +static int osst_chk_result(struct osst_tape * STp, struct scsi_request * SRpnt) { char *name = tape_name(STp); - int result = SRpnt->result; - u8 * sense = SRpnt->sense, scode; + int result = SRpnt->sr_result; + unsigned char * sense = SRpnt->sr_sense_buffer, scode; #if DEBUG const char *stp; #endif - struct st_cmdstatus *cmdstatp; - if (!result) + if (!result) { + sense[0] = 0; /* We don't have sense data if this byte is zero */ return 0; - - cmdstatp = &STp->buffer->cmdstat; - osst_analyze_sense(SRpnt, cmdstatp); - - if (cmdstatp->have_sense) - scode = STp->buffer->cmdstat.sense_hdr.sense_key; - else + } + if ((driver_byte(result) & DRIVER_MASK) == DRIVER_SENSE) + scode = sense[2] & 0x0f; + else { + sense[0] = 0; /* We don't have sense data if this byte is zero */ scode = 0; + } #if DEBUG if (debugging) { - printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n", + printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", name, result, - SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], - SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); + SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2], + SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5], + SRpnt->sr_bufflen); if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n", name, scode, sense[12], sense[13]); - if (cmdstatp->have_sense) - __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); + if (driver_byte(result) & DRIVER_SENSE) + scsi_print_req_sense("osst ", SRpnt); } else #endif - if (cmdstatp->have_sense && ( + if (!(driver_byte(result) & DRIVER_SENSE) || + ((sense[0] & 0x70) == 0x70 && scode != NO_SENSE && scode != RECOVERED_ERROR && /* scode != UNIT_ATTENTION && */ scode != BLANK_CHECK && scode != VOLUME_OVERFLOW && - SRpnt->cmd[0] != MODE_SENSE && - SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ - if (cmdstatp->have_sense) { + SRpnt->sr_cmnd[0] != MODE_SENSE && + SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ + if (driver_byte(result) & DRIVER_SENSE) { printk(KERN_WARNING "%s:W: Command with sense data:\n", name); - __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); + scsi_print_req_sense("osst:", SRpnt); } else { static int notyetprinted = 1; @@ -292,14 +262,15 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt) } STp->pos_unknown |= STp->device->was_reset; - if (cmdstatp->have_sense && scode == RECOVERED_ERROR) { + if ((sense[0] & 0x70) == 0x70 && + scode == RECOVERED_ERROR) { STp->recover_count++; STp->recover_erreg++; #if DEBUG if (debugging) { - if (SRpnt->cmd[0] == READ_6) + if (SRpnt->sr_cmnd[0] == READ_6) stp = "read"; - else if (SRpnt->cmd[0] == WRITE_6) + else if (SRpnt->sr_cmnd[0] == WRITE_6) stp = "write"; else stp = "ioctl"; @@ -315,99 +286,74 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt) /* Wakeup from interrupt */ -static void osst_sleep_done(void *data, char *sense, int result, int resid) +static void osst_sleep_done (struct scsi_cmnd * SCpnt) { - struct osst_request *SRpnt = data; - struct osst_tape *STp = SRpnt->stp; + struct osst_tape * STp = container_of(SCpnt->request->rq_disk->private_data, struct osst_tape, driver); + + if ((STp->buffer)->writing && + (SCpnt->sense_buffer[0] & 0x70) == 0x70 && + (SCpnt->sense_buffer[2] & 0x40)) { + /* EOM at write-behind, has all been written? */ + if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW) + STp->buffer->midlevel_result = SCpnt->result; /* Error */ + else + STp->buffer->midlevel_result = INT_MAX; /* OK */ + } + else + STp->buffer->midlevel_result = SCpnt->result; + SCpnt->request->rq_status = RQ_SCSI_DONE; + STp->buffer->last_SRpnt = SCpnt->sc_request; - memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); - STp->buffer->cmdstat.midlevel_result = SRpnt->result = result; #if DEBUG STp->write_pending = 0; #endif - if (SRpnt->waiting) - complete(SRpnt->waiting); + complete(SCpnt->request->waiting); } -/* osst_request memory management */ -static struct osst_request *osst_allocate_request(void) -{ - return kzalloc(sizeof(struct osst_request), GFP_KERNEL); -} - -static void osst_release_request(struct osst_request *streq) -{ - kfree(streq); -} /* Do the scsi command. Waits until command performed if do_wait is true. Otherwise osst_write_behind_check() is used to check that the command has finished. */ -static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp, +static struct scsi_request * osst_do_scsi(struct scsi_request *SRpnt, struct osst_tape *STp, unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait) { unsigned char *bp; - unsigned short use_sg; #ifdef OSST_INJECT_ERRORS static int inject = 0; static int repeat = 0; #endif - struct completion *waiting; - - /* if async, make sure there's no command outstanding */ - if (!do_wait && ((STp->buffer)->last_SRpnt)) { - printk(KERN_ERR "%s: Async command already active.\n", - tape_name(STp)); - if (signal_pending(current)) - (STp->buffer)->syscall_result = (-EINTR); - else - (STp->buffer)->syscall_result = (-EBUSY); - return NULL; - } - if (SRpnt == NULL) { - SRpnt = osst_allocate_request(); - if (SRpnt == NULL) { - printk(KERN_ERR "%s: Can't allocate SCSI request.\n", - tape_name(STp)); + if ((SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC)) == NULL) { + printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp)); if (signal_pending(current)) (STp->buffer)->syscall_result = (-EINTR); else (STp->buffer)->syscall_result = (-EBUSY); return NULL; } - SRpnt->stp = STp; } - /* If async IO, set last_SRpnt. This ptr tells write_behind_check - which IO is outstanding. It's nulled out when the IO completes. */ - if (!do_wait) - (STp->buffer)->last_SRpnt = SRpnt; - - waiting = &STp->wait; - init_completion(waiting); - SRpnt->waiting = waiting; - - use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0; - if (use_sg) { + init_completion(&STp->wait); + SRpnt->sr_use_sg = (bytes > (STp->buffer)->sg[0].length) ? + (STp->buffer)->use_sg : 0; + if (SRpnt->sr_use_sg) { bp = (char *)&(STp->buffer->sg[0]); - if (STp->buffer->sg_segs < use_sg) - use_sg = STp->buffer->sg_segs; + if (STp->buffer->sg_segs < SRpnt->sr_use_sg) + SRpnt->sr_use_sg = STp->buffer->sg_segs; } else bp = (STp->buffer)->b_data; + SRpnt->sr_data_direction = direction; + SRpnt->sr_cmd_len = 0; + SRpnt->sr_request->waiting = &(STp->wait); + SRpnt->sr_request->rq_status = RQ_SCSI_BUSY; + SRpnt->sr_request->rq_disk = STp->drive; - memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); - STp->buffer->cmdstat.have_sense = 0; - STp->buffer->syscall_result = 0; + scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries); - if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes, - use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL)) - /* could not allocate the buffer or request was too large */ - (STp->buffer)->syscall_result = (-EBUSY); - else if (do_wait) { - wait_for_completion(waiting); - SRpnt->waiting = NULL; + if (do_wait) { + wait_for_completion(SRpnt->sr_request->waiting); + SRpnt->sr_request->waiting = NULL; STp->buffer->syscall_result = osst_chk_result(STp, SRpnt); #ifdef OSST_INJECT_ERRORS if (STp->buffer->syscall_result == 0 && @@ -440,22 +386,21 @@ static void osst_write_behind_check(struct osst_tape *STp) STp->nbr_finished++; #endif wait_for_completion(&(STp->wait)); - STp->buffer->last_SRpnt->waiting = NULL; + (STp->buffer)->last_SRpnt->sr_request->waiting = NULL; STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt); - if (STp->buffer->syscall_result) - STp->buffer->syscall_result = - osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1); + if ((STp->buffer)->syscall_result) + (STp->buffer)->syscall_result = + osst_write_error_recovery(STp, &((STp->buffer)->last_SRpnt), 1); else STp->first_frame_position++; - osst_release_request(STp->buffer->last_SRpnt); + scsi_release_request((STp->buffer)->last_SRpnt); if (STbuffer->writing < STbuffer->buffer_bytes) printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n"); - STbuffer->last_SRpnt = NULL; STbuffer->buffer_bytes -= STbuffer->writing; STbuffer->writing = 0; @@ -664,11 +609,11 @@ err_out: /* * Wait for the unit to become Ready */ -static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt, +static int osst_wait_ready(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout, int initial_delay) { unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt; + struct scsi_request * SRpnt; unsigned long startwait = jiffies; #if DEBUG int dbg = debugging; @@ -688,10 +633,10 @@ static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt if (!SRpnt) return (-EBUSY); while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && - (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && - (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) || - ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 && - SRpnt->sense[13] == 0 ) )) { + (( SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 && + (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8) ) || + ( SRpnt->sr_sense_buffer[2] == 6 && SRpnt->sr_sense_buffer[12] == 0x28 && + SRpnt->sr_sense_buffer[13] == 0 ) )) { #if DEBUG if (debugging) { printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name); @@ -715,8 +660,8 @@ static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt #if DEBUG printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name); printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name, - STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], - SRpnt->sense[12], SRpnt->sense[13]); + STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2], + SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]); #endif return (-EIO); } @@ -729,10 +674,10 @@ static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt /* * Wait for a tape to be inserted in the unit */ -static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout) +static int osst_wait_for_medium(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout) { unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt; + struct scsi_request * SRpnt; unsigned long startwait = jiffies; #if DEBUG int dbg = debugging; @@ -749,7 +694,8 @@ static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** a if (!SRpnt) return (-EBUSY); while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && - SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) { + SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 0x3a && + SRpnt->sr_sense_buffer[13] == 0 ) { #if DEBUG if (debugging) { printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name); @@ -768,13 +714,13 @@ static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** a #if DEBUG debugging = dbg; #endif - if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 && - SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) { + if ( STp->buffer->syscall_result && SRpnt->sr_sense_buffer[2] != 2 && + SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) { #if DEBUG printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name); printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name, - STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], - SRpnt->sense[12], SRpnt->sense[13]); + STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2], + SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]); #endif return 0; } @@ -784,7 +730,7 @@ static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** a return 1; } -static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame) +static int osst_position_tape_and_confirm(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame) { int retval; @@ -798,10 +744,10 @@ static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_re /* * Wait for write(s) to complete */ -static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt) +static int osst_flush_drive_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt) { unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt; + struct scsi_request * SRpnt; int result = 0; int delay = OSST_WAIT_WRITE_COMPLETE; #if DEBUG @@ -818,8 +764,8 @@ static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request * *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); if (STp->buffer->syscall_result) { - if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) { - if (SRpnt->sense[13] == 8) { + if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) { + if (SRpnt->sr_sense_buffer[13] == 8) { delay = OSST_WAIT_LONG_WRITE_COMPLETE; } } else @@ -832,7 +778,7 @@ static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request * } #define OSST_POLL_PER_SEC 10 -static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to) +static int osst_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int curr, int minlast, int to) { unsigned long startwait = jiffies; char * name = tape_name(STp); @@ -857,7 +803,7 @@ static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt ) && result >= 0) { #if DEBUG - if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC)) + if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC) printk (OSST_DEB_MSG "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n", name, curr, curr+minlast, STp->first_frame_position, @@ -868,7 +814,7 @@ static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt return 0; } #if DEBUG - if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted) + if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted) { printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n", name, curr, curr+minlast, STp->first_frame_position, @@ -887,9 +833,9 @@ static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt return -EBUSY; } -static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing) +static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int writing) { - struct osst_request * SRpnt; + struct scsi_request * SRpnt; unsigned char cmd[MAX_COMMAND_SIZE]; unsigned long startwait = jiffies; int retval = 1; @@ -910,7 +856,7 @@ static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request * while (retval && time_before (jiffies, startwait + 5*60*HZ)) { - if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) { + if (STp->buffer->syscall_result && (SRpnt->sr_sense_buffer[2] & 0x0f) != 2) { /* some failure - not just not-ready */ retval = osst_write_error_recovery(STp, aSRpnt, 0); @@ -935,9 +881,9 @@ static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request * if (STp->buffer->syscall_result) printk(KERN_WARNING "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name, - (*aSRpnt)->sense[ 2] & 0x0f, - (*aSRpnt)->sense[12], - (*aSRpnt)->sense[13]); + (*aSRpnt)->sr_sense_buffer[ 2] & 0x0f, + (*aSRpnt)->sr_sense_buffer[12], + (*aSRpnt)->sr_sense_buffer[13]); return retval; } @@ -945,10 +891,10 @@ static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request * /* * Read the next OnStream tape frame at the current location */ -static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout) +static int osst_read_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int timeout) { unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt; + struct scsi_request * SRpnt; int retval = 0; #if DEBUG os_aux_t * aux = STp->buffer->aux; @@ -986,10 +932,10 @@ static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt if (debugging) printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", name, - SRpnt->sense[0], SRpnt->sense[1], - SRpnt->sense[2], SRpnt->sense[3], - SRpnt->sense[4], SRpnt->sense[5], - SRpnt->sense[6], SRpnt->sense[7]); + SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1], + SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3], + SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5], + SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]); #endif } else @@ -1016,10 +962,10 @@ static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt return (retval); } -static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt) +static int osst_initiate_read(struct osst_tape * STp, struct scsi_request ** aSRpnt) { struct st_partstat * STps = &(STp->ps[STp->partition]); - struct osst_request * SRpnt ; + struct scsi_request * SRpnt ; unsigned char cmd[MAX_COMMAND_SIZE]; int retval = 0; char * name = tape_name(STp); @@ -1053,7 +999,7 @@ static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSR return retval; } -static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, +static int osst_get_logical_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame_seq_number, int quiet) { struct st_partstat * STps = &(STp->ps[STp->partition]); @@ -1182,7 +1128,7 @@ static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** return (STps->eof); } -static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num) +static int osst_seek_logical_blk(struct osst_tape * STp, struct scsi_request ** aSRpnt, int logical_blk_num) { struct st_partstat * STps = &(STp->ps[STp->partition]); char * name = tape_name(STp); @@ -1291,7 +1237,7 @@ error: #define OSST_SECTOR_SHIFT 9 #define OSST_SECTOR_MASK 0x03F -static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt) +static int osst_get_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int sector; #if DEBUG @@ -1321,7 +1267,7 @@ static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt return sector; } -static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector) +static int osst_seek_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt, int sector) { struct st_partstat * STps = &(STp->ps[STp->partition]); int frame = sector >> OSST_FRAME_SHIFT, @@ -1384,10 +1330,10 @@ static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpn * Precondition for this function to work: all frames in the * drive's buffer must be of one type (DATA, MARK or EOD)! */ -static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt, +static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned int frame, unsigned int skip, int pending) { - struct osst_request * SRpnt = * aSRpnt; + struct scsi_request * SRpnt = * aSRpnt; unsigned char * buffer, * p; unsigned char cmd[MAX_COMMAND_SIZE]; int flag, new_frame, i; @@ -1531,8 +1477,8 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); - if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && - (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) { + if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 && + (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) { /* in the process of becoming ready */ msleep(100); continue; @@ -1549,17 +1495,17 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst } *aSRpnt = SRpnt; if (flag) { - if ((SRpnt->sense[ 2] & 0x0f) == 13 && - SRpnt->sense[12] == 0 && - SRpnt->sense[13] == 2) { + if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 && + SRpnt->sr_sense_buffer[12] == 0 && + SRpnt->sr_sense_buffer[13] == 2) { printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name); vfree(buffer); return (-EIO); /* hit end of tape = fail */ } - i = ((SRpnt->sense[3] << 24) | - (SRpnt->sense[4] << 16) | - (SRpnt->sense[5] << 8) | - SRpnt->sense[6] ) - new_frame; + i = ((SRpnt->sr_sense_buffer[3] << 24) | + (SRpnt->sr_sense_buffer[4] << 16) | + (SRpnt->sr_sense_buffer[5] << 8) | + SRpnt->sr_sense_buffer[6] ) - new_frame; p = &buffer[i * OS_DATA_SIZE]; #if DEBUG printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i); @@ -1582,11 +1528,11 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst return 0; } -static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt, +static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned int frame, unsigned int skip, int pending) { unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt; + struct scsi_request * SRpnt; char * name = tape_name(STp); int expected = 0; int attempts = 1000 / skip; @@ -1638,9 +1584,9 @@ static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request *aSRpnt = SRpnt; if (STp->buffer->syscall_result) { /* additional write error */ - if ((SRpnt->sense[ 2] & 0x0f) == 13 && - SRpnt->sense[12] == 0 && - SRpnt->sense[13] == 2) { + if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 && + SRpnt->sr_sense_buffer[12] == 0 && + SRpnt->sr_sense_buffer[13] == 2) { printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name); @@ -1685,9 +1631,9 @@ static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request * Error recovery algorithm for the OnStream tape. */ -static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending) +static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending) { - struct osst_request * SRpnt = * aSRpnt; + struct scsi_request * SRpnt = * aSRpnt; struct st_partstat * STps = & STp->ps[STp->partition]; char * name = tape_name(STp); int retval = 0; @@ -1696,20 +1642,20 @@ static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request rw_state = STps->rw; - if ((SRpnt->sense[ 2] & 0x0f) != 3 - || SRpnt->sense[12] != 12 - || SRpnt->sense[13] != 0) { + if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) != 3 + || SRpnt->sr_sense_buffer[12] != 12 + || SRpnt->sr_sense_buffer[13] != 0) { #if DEBUG printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name, - SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]); + SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]); #endif return (-EIO); } - frame = (SRpnt->sense[3] << 24) | - (SRpnt->sense[4] << 16) | - (SRpnt->sense[5] << 8) | - SRpnt->sense[6]; - skip = SRpnt->sense[9]; + frame = (SRpnt->sr_sense_buffer[3] << 24) | + (SRpnt->sr_sense_buffer[4] << 16) | + (SRpnt->sr_sense_buffer[5] << 8) | + SRpnt->sr_sense_buffer[6]; + skip = SRpnt->sr_sense_buffer[9]; #if DEBUG printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip); @@ -1764,7 +1710,7 @@ static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request return retval; } -static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt, +static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { char * name = tape_name(STp); @@ -1863,7 +1809,7 @@ found: * * Just scans for the filemark sequentially. */ -static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt, +static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { int cnt = 0; @@ -1917,7 +1863,7 @@ static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct /* * Fast linux specific version of OnStream FSF */ -static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt, +static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { char * name = tape_name(STp); @@ -2068,10 +2014,10 @@ static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct * to test the error recovery mechanism. */ #if DEBUG -static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries) +static void osst_set_retries(struct osst_tape * STp, struct scsi_request ** aSRpnt, int retries) { unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt = * aSRpnt; + struct scsi_request * SRpnt = * aSRpnt; char * name = tape_name(STp); memset(cmd, 0, MAX_COMMAND_SIZE); @@ -2100,7 +2046,7 @@ static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRp #endif -static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt) +static int osst_write_filemark(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int result; int this_mark_ppos = STp->first_frame_position; @@ -2128,7 +2074,7 @@ static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aS return result; } -static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt) +static int osst_write_eod(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int result; #if DEBUG @@ -2151,7 +2097,7 @@ static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt) return result; } -static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count) +static int osst_write_filler(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count) { char * name = tape_name(STp); @@ -2176,7 +2122,7 @@ static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRp return osst_flush_drive_buffer(STp, aSRpnt); } -static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count) +static int __osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count) { char * name = tape_name(STp); int result; @@ -2203,7 +2149,7 @@ static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aS return result; } -static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod) +static int osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int locate_eod) { os_header_t * header; int result; @@ -2277,7 +2223,7 @@ static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRp return result; } -static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt) +static int osst_reset_header(struct osst_tape * STp, struct scsi_request ** aSRpnt) { if (STp->header_cache != NULL) memset(STp->header_cache, 0, sizeof(os_header_t)); @@ -2290,7 +2236,7 @@ static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRp return osst_write_header(STp, aSRpnt, 1); } -static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos) +static int __osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt, int ppos) { char * name = tape_name(STp); os_header_t * header; @@ -2467,7 +2413,7 @@ static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** return 1; } -static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt) +static int osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int position, ppos; int first, last; @@ -2522,7 +2468,7 @@ static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** a return 1; } -static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt) +static int osst_verify_position(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int frame_position = STp->first_frame_position; int frame_seq_numbr = STp->frame_seq_number; @@ -2598,11 +2544,11 @@ static unsigned int osst_parse_firmware_rev (const char * str) /* * Configure the OnStream SCII tape drive for default operation */ -static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt) +static int osst_configure_onstream(struct osst_tape *STp, struct scsi_request ** aSRpnt) { unsigned char cmd[MAX_COMMAND_SIZE]; char * name = tape_name(STp); - struct osst_request * SRpnt = * aSRpnt; + struct scsi_request * SRpnt = * aSRpnt; osst_mode_parameter_header_t * header; osst_block_size_page_t * bs; osst_capabilities_page_t * cp; @@ -2769,7 +2715,7 @@ static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** /* Step over EOF if it has been inadvertently crossed (ioctl not used because it messes up the block number). */ -static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward) +static int cross_eof(struct osst_tape *STp, struct scsi_request ** aSRpnt, int forward) { int result; char * name = tape_name(STp); @@ -2798,10 +2744,10 @@ static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int f /* Get the tape position. */ -static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt) +static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt) { unsigned char scmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt; + struct scsi_request * SRpnt; int result = 0; char * name = tape_name(STp); @@ -2826,14 +2772,14 @@ static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** *aSRpnt = SRpnt; if (STp->buffer->syscall_result) - result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */ + result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */ if (result == -EINVAL) printk(KERN_ERR "%s:E: Can't read tape position.\n", name); else { if (result == -EIO) { /* re-read position - this needs to preserve media errors */ unsigned char mysense[16]; - memcpy (mysense, SRpnt->sense, 16); + memcpy (mysense, SRpnt->sr_sense_buffer, 16); memset (scmd, 0, MAX_COMMAND_SIZE); scmd[0] = READ_POSITION; STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; @@ -2842,10 +2788,10 @@ static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** #if DEBUG printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n", name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:", - SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]); + SRpnt->sr_sense_buffer[2],SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]); #endif if (!STp->buffer->syscall_result) - memcpy (SRpnt->sense, mysense, 16); + memcpy (SRpnt->sr_sense_buffer, mysense, 16); else printk(KERN_WARNING "%s:W: Double error in get position\n", name); } @@ -2882,10 +2828,10 @@ static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** /* Set the tape block */ -static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip) +static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int ppos, int skip) { unsigned char scmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt; + struct scsi_request * SRpnt; struct st_partstat * STps; int result = 0; int pp = (ppos == 3000 && !skip)? 0 : ppos; @@ -2940,7 +2886,7 @@ static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** return result; } -static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT) +static int osst_write_trailer(struct osst_tape *STp, struct scsi_request ** aSRpnt, int leave_at_EOT) { struct st_partstat * STps = &(STp->ps[STp->partition]); int result = 0; @@ -2967,12 +2913,12 @@ out: /* osst versions of st functions - augmented and stripped to suit OnStream only */ /* Flush the write buffer (never need to write if variable blocksize). */ -static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt) +static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt) { int offset, transfer, blks = 0; int result = 0; unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt = *aSRpnt; + struct scsi_request * SRpnt = *aSRpnt; struct st_partstat * STps; char * name = tape_name(STp); @@ -2980,13 +2926,13 @@ static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** if (SRpnt == (STp->buffer)->last_SRpnt) #if DEBUG { printk(OSST_DEB_MSG - "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name); + "%s:D: aSRpnt points to scsi_request that write_behind_check will release -- cleared\n", name); #endif *aSRpnt = SRpnt = NULL; #if DEBUG } else if (SRpnt) printk(OSST_DEB_MSG - "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name); + "%s:D: aSRpnt does not point to scsi_request that write_behind_check will release -- strange\n", name); #endif osst_write_behind_check(STp); if ((STp->buffer)->syscall_result) { @@ -3064,12 +3010,12 @@ static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** #if DEBUG printk(OSST_DEB_MSG "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n", - name, SRpnt->sense[0], SRpnt->sense[2], - SRpnt->sense[12], SRpnt->sense[13]); + name, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2], + SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]); #endif - if ((SRpnt->sense[0] & 0x70) == 0x70 && - (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */ - (SRpnt->sense[2] & 0x0f) == NO_SENSE) { + if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && + (SRpnt->sr_sense_buffer[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */ + (SRpnt->sr_sense_buffer[2] & 0x0f) == NO_SENSE) { STp->dirty = 0; (STp->buffer)->buffer_bytes = 0; result = (-ENOSPC); @@ -3097,7 +3043,7 @@ static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** /* Flush the tape buffer. The tape will be positioned correctly unless seek_next is true. */ -static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next) +static int osst_flush_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt, int seek_next) { struct st_partstat * STps; int backspace = 0, result = 0; @@ -3159,10 +3105,10 @@ static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRp return result; } -static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous) +static int osst_write_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int synchronous) { unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt; + struct scsi_request * SRpnt; int blks; #if DEBUG char * name = tape_name(STp); @@ -3223,9 +3169,9 @@ static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpn if (debugging) printk(OSST_DEB_MSG "%s:D: Error on write:\n", name); #endif - if ((SRpnt->sense[0] & 0x70) == 0x70 && - (SRpnt->sense[2] & 0x40)) { - if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW) + if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && + (SRpnt->sr_sense_buffer[2] & 0x40)) { + if ((SRpnt->sr_sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW) return (-ENOSPC); } else { @@ -3242,7 +3188,7 @@ static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpn return 0; } -/* Lock or unlock the drive door. Don't use when struct osst_request allocated. */ +/* Lock or unlock the drive door. Don't use when struct scsi_request allocated. */ static int do_door_lock(struct osst_tape * STp, int do_lock) { int retval, cmd; @@ -3290,7 +3236,7 @@ static ssize_t osst_write(struct file * filp, const char __user * buf, size_t co int write_threshold; int doing_write = 0; const char __user * b_point; - struct osst_request * SRpnt = NULL; + struct scsi_request * SRpnt = NULL; struct st_modedef * STm; struct st_partstat * STps; struct osst_tape * STp = filp->private_data; @@ -3481,7 +3427,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name #if DEBUG if (debugging) printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n", - name, (int) count, STps->drv_file, STps->drv_block, + name, count, STps->drv_file, STps->drv_block, STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position); #endif b_point = buf; @@ -3517,7 +3463,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name #if DEBUG if (debugging) printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n", - name, (int) transfer); + name, transfer); #endif } else { @@ -3535,7 +3481,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name if (retval < 0) { if (SRpnt != NULL) { - osst_release_request(SRpnt); + scsi_release_request(SRpnt); SRpnt = NULL; } STp->buffer->buffer_bytes = 0; @@ -3597,7 +3543,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name retval = total; out: - if (SRpnt != NULL) osst_release_request(SRpnt); + if (SRpnt != NULL) scsi_release_request(SRpnt); up(&STp->lock); @@ -3613,7 +3559,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo int special; struct st_modedef * STm; struct st_partstat * STps; - struct osst_request * SRpnt = NULL; + struct scsi_request * SRpnt = NULL; struct osst_tape * STp = filp->private_data; char * name = tape_name(STp); @@ -3721,7 +3667,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo #if DEBUG if (debugging && STps->eof != ST_NOEOF) printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name, - STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total)); + STps->eof, (STp->buffer)->buffer_bytes, count - total); #endif /* force multiple of block size, note block_size may have been adjusted */ transfer = (((STp->buffer)->buffer_bytes < count - total ? @@ -3782,7 +3728,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo retval = total; out: - if (SRpnt != NULL) osst_release_request(SRpnt); + if (SRpnt != NULL) scsi_release_request(SRpnt); up(&STp->lock); @@ -3970,7 +3916,7 @@ static int osst_set_options(struct osst_tape *STp, long options) /* Internal ioctl function */ -static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt, +static int osst_int_ioctl(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned int cmd_in, unsigned long arg) { int timeout; @@ -3978,7 +3924,7 @@ static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt, int i, ioctl_result; int chg_eof = 1; unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt = * aSRpnt; + struct scsi_request * SRpnt = * aSRpnt; struct st_partstat * STps; int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num; int datalen = 0, direction = DMA_NONE; @@ -4336,14 +4282,14 @@ os_bypass: } else if (cmd_in == MTERASE) { STp->header_ok = 0; } else if (SRpnt) { /* SCSI command was not completely successful. */ - if (SRpnt->sense[2] & 0x40) { + if (SRpnt->sr_sense_buffer[2] & 0x40) { STps->eof = ST_EOM_OK; STps->drv_block = 0; } if (chg_eof) STps->eof = ST_NOEOF; - if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK) + if ((SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK) STps->eof = ST_EOD; if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60)) @@ -4361,7 +4307,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) unsigned short flags; int i, b_size, new_session = 0, retval = 0; unsigned char cmd[MAX_COMMAND_SIZE]; - struct osst_request * SRpnt = NULL; + struct scsi_request * SRpnt = NULL; struct osst_tape * STp; struct st_modedef * STm; struct st_partstat * STps; @@ -4469,17 +4415,17 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) retval = (STp->buffer)->syscall_result; /* FIXME - valid? */ goto err_out; } - if ((SRpnt->sense[0] & 0x70) == 0x70 && - (SRpnt->sense[2] & 0x0f) == NOT_READY && - SRpnt->sense[12] == 4 ) { + if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && + (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY && + SRpnt->sr_sense_buffer[12] == 4 ) { #if DEBUG - printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]); + printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sr_sense_buffer[13]); #endif if (filp->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto err_out; } - if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */ + if (SRpnt->sr_sense_buffer[13] == 2) { /* initialize command required (LOAD) */ memset (cmd, 0, MAX_COMMAND_SIZE); cmd[0] = START_STOP; cmd[1] = 1; @@ -4487,10 +4433,10 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); } - osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0); + osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0); } - if ((SRpnt->sense[0] & 0x70) == 0x70 && - (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */ + if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && + (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */ #if DEBUG printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name); #endif @@ -4503,8 +4449,8 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); - if ((SRpnt->sense[0] & 0x70) != 0x70 || - (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION) + if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 || + (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION) break; } @@ -4530,7 +4476,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) * open without reconfiguring and re-reading the headers */ if (!STp->buffer->syscall_result && STp->header_ok && - !SRpnt->result && SRpnt->sense[0] == 0) { + !SRpnt->sr_result && SRpnt->sr_sense_buffer[0] == 0) { memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SENSE; @@ -4569,7 +4515,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) } STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size; STp->fast_open = 1; - osst_release_request(SRpnt); + scsi_release_request(SRpnt); return 0; } #if DEBUG @@ -4582,7 +4528,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) STp->fast_open = 0; if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */ - (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) { + (SRpnt->sr_sense_buffer[2] != 2 || SRpnt->sr_sense_buffer[12] != 0x3A) ) { memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SELECT; @@ -4612,11 +4558,11 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); - if ((SRpnt->sense[0] & 0x70) != 0x70 || - (SRpnt->sense[2] & 0x0f) == NOT_READY) + if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 || + (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY) break; - if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { + if ((SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { STp->pos_unknown = 0; STp->partition = STp->new_partition = 0; if (STp->can_partitions) @@ -4640,13 +4586,13 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) if ((STp->buffer)->syscall_result != 0) { if ((STp->device)->scsi_level >= SCSI_2 && - (SRpnt->sense[0] & 0x70) == 0x70 && - (SRpnt->sense[2] & 0x0f) == NOT_READY && - SRpnt->sense[12] == 0x3a) { /* Check ASC */ + (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && + (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY && + SRpnt->sr_sense_buffer[12] == 0x3a) { /* Check ASC */ STp->ready = ST_NO_TAPE; } else STp->ready = ST_NOT_READY; - osst_release_request(SRpnt); + scsi_release_request(SRpnt); SRpnt = NULL; STp->density = 0; /* Clear the erroneous "residue" */ STp->write_prot = 0; @@ -4706,14 +4652,14 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) osst_analyze_headers(STp, &SRpnt); - osst_release_request(SRpnt); + scsi_release_request(SRpnt); SRpnt = NULL; return 0; err_out: if (SRpnt != NULL) - osst_release_request(SRpnt); + scsi_release_request(SRpnt); normalize_buffer(STp->buffer); STp->header_ok = 0; STp->in_use = 0; @@ -4730,7 +4676,7 @@ static int os_scsi_tape_flush(struct file * filp) struct osst_tape * STp = filp->private_data; struct st_modedef * STm = &(STp->modes[STp->current_mode]); struct st_partstat * STps = &(STp->ps[STp->partition]); - struct osst_request * SRpnt = NULL; + struct scsi_request * SRpnt = NULL; char * name = tape_name(STp); if (file_count(filp) > 1) @@ -4793,7 +4739,7 @@ out: if (result == 0 && result2 < 0) result = result2; } - if (SRpnt) osst_release_request(SRpnt); + if (SRpnt) scsi_release_request(SRpnt); if (STp->abort_count || STp->recover_count) { printk(KERN_INFO "%s:I:", name); @@ -4847,7 +4793,7 @@ static int osst_ioctl(struct inode * inode,struct file * file, unsigned int blk; struct st_modedef * STm; struct st_partstat * STps; - struct osst_request * SRpnt = NULL; + struct scsi_request * SRpnt = NULL; struct osst_tape * STp = file->private_data; char * name = tape_name(STp); void __user * p = (void __user *)arg; @@ -5161,14 +5107,14 @@ static int osst_ioctl(struct inode * inode,struct file * file, retval = -EFAULT; goto out; } - if (SRpnt) osst_release_request(SRpnt); + if (SRpnt) scsi_release_request(SRpnt); up(&STp->lock); return scsi_ioctl(STp->device, cmd_in, p); out: - if (SRpnt) osst_release_request(SRpnt); + if (SRpnt) scsi_release_request(SRpnt); up(&STp->lock); @@ -5721,7 +5667,7 @@ static int osst_probe(struct device *dev) struct st_partstat * STps; struct osst_buffer * buffer; struct gendisk * drive; - int i, dev_num; + int i, mode, dev_num; if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) return -ENODEV; @@ -5857,6 +5803,18 @@ static int osst_probe(struct device *dev) snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); } + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + /* Rewind entry */ + devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)), + S_IFCHR | S_IRUGO | S_IWUGO, + "%s/ot%s", SDp->devfs_name, osst_formats[mode]); + + /* No-rewind entry */ + devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128), + S_IFCHR | S_IRUGO | S_IWUGO, + "%s/ot%sn", SDp->devfs_name, osst_formats[mode]); + } + drive->number = devfs_register_tape(SDp->devfs_name); sdev_printk(KERN_INFO, SDp, "osst :I: Attached OnStream %.5s tape as %s\n", @@ -5873,7 +5831,7 @@ static int osst_remove(struct device *dev) { struct scsi_device * SDp = to_scsi_device(dev); struct osst_tape * tpnt; - int i; + int i, mode; if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) return 0; @@ -5884,6 +5842,11 @@ static int osst_remove(struct device *dev) osst_sysfs_destroy(MKDEV(OSST_MAJOR, i)); osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128)); tpnt->device = NULL; + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]); + devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]); + } + devfs_unregister_tape(tpnt->drive->number); put_disk(tpnt->drive); os_scsi_tapes[i] = NULL; osst_nr_dev--; diff --git a/drivers/scsi/osst.h b/drivers/scsi/osst.h index 011d4d6ca..b72e1c76f 100644 --- a/drivers/scsi/osst.h +++ b/drivers/scsi/osst.h @@ -518,8 +518,7 @@ struct osst_buffer { int writing; int midlevel_result; int syscall_result; - struct osst_request *last_SRpnt; - struct st_cmdstatus cmdstat; + struct scsi_request *last_SRpnt; unsigned char *b_data; os_aux_t *aux; /* onstream AUX structure at end of each block */ unsigned short use_sg; /* zero or number of s/g segments for this adapter */ @@ -627,15 +626,6 @@ struct osst_tape { struct gendisk *drive; } ; -/* scsi tape command */ -struct osst_request { - unsigned char cmd[MAX_COMMAND_SIZE]; - unsigned char sense[SCSI_SENSE_BUFFERSIZE]; - int result; - struct osst_tape *stp; - struct completion *waiting; -}; - /* Values of write_type */ #define OS_WRITE_DATA 0 #define OS_WRITE_EOD 1 diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index ee449b29f..5609847e2 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -89,29 +89,29 @@ MODULE_LICENSE("Dual MPL/GPL"); /*====================================================================*/ typedef struct scsi_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct Scsi_Host *host; } scsi_info_t; -static void aha152x_release_cs(struct pcmcia_device *link); +static void aha152x_release_cs(dev_link_t *link); static void aha152x_detach(struct pcmcia_device *p_dev); -static int aha152x_config_cs(struct pcmcia_device *link); +static void aha152x_config_cs(dev_link_t *link); -static struct pcmcia_device *dev_list; +static dev_link_t *dev_list; -static int aha152x_probe(struct pcmcia_device *link) +static int aha152x_attach(struct pcmcia_device *p_dev) { scsi_info_t *info; - + dev_link_t *link; + DEBUG(0, "aha152x_attach()\n"); /* Create new SCSI device */ info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; memset(info, 0, sizeof(*info)); - info->p_dev = link; - link->priv = info; + link = &info->link; link->priv = info; link->io.NumPorts1 = 0x20; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -119,22 +119,41 @@ static int aha152x_probe(struct pcmcia_device *link) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - return aha152x_config_cs(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + aha152x_config_cs(link); + + return 0; } /* aha152x_attach */ /*====================================================================*/ -static void aha152x_detach(struct pcmcia_device *link) +static void aha152x_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + dev_link_t **linkp; + DEBUG(0, "aha152x_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; + if (*linkp == NULL) + return; - aha152x_release_cs(link); + if (link->state & DEV_CONFIG) + aha152x_release_cs(link); /* Unlink device structure, free bits */ + *linkp = link->next; kfree(link->priv); + } /* aha152x_detach */ /*====================================================================*/ @@ -142,8 +161,9 @@ static void aha152x_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int aha152x_config_cs(struct pcmcia_device *link) +static void aha152x_config_cs(dev_link_t *link) { + client_handle_t handle = link->handle; scsi_info_t *info = link->priv; struct aha152x_setup s; tuple_t tuple; @@ -158,16 +178,19 @@ static int aha152x_config_cs(struct pcmcia_device *link) tuple.TupleData = tuple_data; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; + /* Configure card */ + link->state |= DEV_CONFIG; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; /* For New Media T&J, look for a SCSI window */ if (parse.cftable_entry.io.win[0].len >= 0x20) @@ -178,15 +201,15 @@ static int aha152x_config_cs(struct pcmcia_device *link) if ((parse.cftable_entry.io.nwin > 0) && (link->io.BasePort1 < 0xffff)) { link->conf.ConfigIndex = parse.cftable_entry.index; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(handle, &link->io); if (i == CS_SUCCESS) break; } next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); /* Set configuration options for the aha152x driver */ memset(&s, 0, sizeof(s)); @@ -208,30 +231,53 @@ static int aha152x_config_cs(struct pcmcia_device *link) } sprintf(info->node.dev_name, "scsi%d", host->host_no); - link->dev_node = &info->node; + link->dev = &info->node; info->host = host; - return 0; - + link->state &= ~DEV_CONFIG_PENDING; + return; + cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); aha152x_release_cs(link); - return -ENODEV; + return; } -static void aha152x_release_cs(struct pcmcia_device *link) +static void aha152x_release_cs(dev_link_t *link) { scsi_info_t *info = link->priv; aha152x_release(info->host); - pcmcia_disable_device(link); + link->dev = NULL; + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; } -static int aha152x_resume(struct pcmcia_device *link) +static int aha152x_suspend(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int aha152x_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); scsi_info_t *info = link->priv; - aha152x_host_reset_host(info->host); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + aha152x_host_reset_host(info->host); + } return 0; } @@ -251,9 +297,10 @@ static struct pcmcia_driver aha152x_cs_driver = { .drv = { .name = "aha152x_cs", }, - .probe = aha152x_probe, + .probe = aha152x_attach, .remove = aha152x_detach, .id_table = aha152x_ids, + .suspend = aha152x_suspend, .resume = aha152x_resume, }; @@ -270,3 +317,4 @@ static void __exit exit_aha152x_cs(void) module_init(init_aha152x_cs); module_exit(exit_aha152x_cs); + diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 85f7ffac1..788c58d80 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -73,48 +73,57 @@ static char *version = /*====================================================================*/ typedef struct scsi_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct Scsi_Host *host; } scsi_info_t; -static void fdomain_release(struct pcmcia_device *link); +static void fdomain_release(dev_link_t *link); static void fdomain_detach(struct pcmcia_device *p_dev); -static int fdomain_config(struct pcmcia_device *link); +static void fdomain_config(dev_link_t *link); -static int fdomain_probe(struct pcmcia_device *link) +static int fdomain_attach(struct pcmcia_device *p_dev) { - scsi_info_t *info; - - DEBUG(0, "fdomain_attach()\n"); - - /* Create new SCSI device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->p_dev = link; - link->priv = info; - link->io.NumPorts1 = 0x10; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 10; - 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; - link->conf.Present = PRESENT_OPTION; - - return fdomain_config(link); + scsi_info_t *info; + dev_link_t *link; + + DEBUG(0, "fdomain_attach()\n"); + + /* Create new SCSI device */ + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) return -ENOMEM; + memset(info, 0, sizeof(*info)); + link = &info->link; link->priv = info; + link->io.NumPorts1 = 0x10; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->io.IOAddrLines = 10; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.Present = PRESENT_OPTION; + + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + fdomain_config(link); + + return 0; } /* fdomain_attach */ /*====================================================================*/ -static void fdomain_detach(struct pcmcia_device *link) +static void fdomain_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + DEBUG(0, "fdomain_detach(0x%p)\n", link); - fdomain_release(link); + if (link->state & DEV_CONFIG) + fdomain_release(link); kfree(link->priv); } /* fdomain_detach */ @@ -124,8 +133,9 @@ static void fdomain_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int fdomain_config(struct pcmcia_device *link) +static void fdomain_config(dev_link_t *link) { + client_handle_t handle = link->handle; scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; @@ -140,75 +150,103 @@ static int fdomain_config(struct pcmcia_device *link) tuple.TupleData = tuple_data; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; + /* Configure card */ + link->state |= DEV_CONFIG; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; link->conf.ConfigIndex = parse.cftable_entry.index; link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(handle, &link->io); if (i == CS_SUCCESS) break; next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); - + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); + /* A bad hack... */ release_region(link->io.BasePort1, link->io.NumPorts1); /* Set configuration options for the fdomain driver */ sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ); fdomain_setup(str); - + host = __fdomain_16x0_detect(&fdomain_driver_template); if (!host) { printk(KERN_INFO "fdomain_cs: no SCSI devices found\n"); goto cs_failed; } - - if (scsi_add_host(host, NULL)) - goto cs_failed; + + scsi_add_host(host, NULL); /* XXX handle failure */ scsi_scan_host(host); sprintf(info->node.dev_name, "scsi%d", host->host_no); - link->dev_node = &info->node; + link->dev = &info->node; info->host = host; - - return 0; - + + link->state &= ~DEV_CONFIG_PENDING; + return; + cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); fdomain_release(link); - return -ENODEV; + return; + } /* fdomain_config */ /*====================================================================*/ -static void fdomain_release(struct pcmcia_device *link) +static void fdomain_release(dev_link_t *link) { - scsi_info_t *info = link->priv; + scsi_info_t *info = link->priv; - DEBUG(0, "fdomain_release(0x%p)\n", link); + DEBUG(0, "fdomain_release(0x%p)\n", link); - scsi_remove_host(info->host); - pcmcia_disable_device(link); - scsi_unregister(info->host); + scsi_remove_host(info->host); + link->dev = NULL; + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + scsi_unregister(info->host); + + link->state &= ~DEV_CONFIG; } /*====================================================================*/ -static int fdomain_resume(struct pcmcia_device *link) +static int fdomain_suspend(struct pcmcia_device *dev) { - fdomain_16x0_bus_reset(NULL); + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int fdomain_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + fdomain_16x0_bus_reset(NULL); + } return 0; } @@ -226,9 +264,10 @@ static struct pcmcia_driver fdomain_cs_driver = { .drv = { .name = "fdomain_cs", }, - .probe = fdomain_probe, + .probe = fdomain_attach, .remove = fdomain_detach, .id_table = fdomain_ids, + .suspend = fdomain_suspend, .resume = fdomain_resume, }; diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 231f9c311..9e3ab3fd5 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1593,11 +1593,11 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt) configure the card at this point -- we wait until we receive a card insertion event. ======================================================================*/ -static int nsp_cs_probe(struct pcmcia_device *link) +static int nsp_cs_attach(struct pcmcia_device *p_dev) { scsi_info_t *info; + dev_link_t *link; nsp_hw_data *data = &nsp_data_base; - int ret; nsp_dbg(NSP_DEBUG_INIT, "in"); @@ -1605,7 +1605,7 @@ static int nsp_cs_probe(struct pcmcia_device *link) info = kmalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) { return -ENOMEM; } memset(info, 0, sizeof(*info)); - info->p_dev = link; + link = &info->link; link->priv = info; data->ScsiInfo = info; @@ -1627,13 +1627,18 @@ static int nsp_cs_probe(struct pcmcia_device *link) /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - ret = nsp_cs_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + nsp_cs_config(link); nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); - return ret; + return 0; } /* nsp_cs_attach */ @@ -1643,12 +1648,16 @@ static int nsp_cs_probe(struct pcmcia_device *link) structures are freed. Otherwise, the structures will be freed when the device is released. ======================================================================*/ -static void nsp_cs_detach(struct pcmcia_device *link) +static void nsp_cs_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); - ((scsi_info_t *)link->priv)->stop = 1; - nsp_cs_release(link); + if (link->state & DEV_CONFIG) { + ((scsi_info_t *)link->priv)->stop = 1; + nsp_cs_release(link); + } kfree(link->priv); link->priv = NULL; @@ -1663,9 +1672,9 @@ static void nsp_cs_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) /*====================================================================*/ -static int nsp_cs_config(struct pcmcia_device *link) +static void nsp_cs_config(dev_link_t *link) { - int ret; + client_handle_t handle = link->handle; scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; @@ -1689,22 +1698,26 @@ static int nsp_cs_config(struct pcmcia_device *link) tuple.TupleData = tuple_data; tuple.TupleDataMax = sizeof(tuple_data); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } @@ -1730,10 +1743,10 @@ static int nsp_cs_config(struct pcmcia_device *link) } if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; } @@ -1760,7 +1773,7 @@ static int nsp_cs_config(struct pcmcia_device *link) 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) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; } @@ -1775,7 +1788,7 @@ static int nsp_cs_config(struct pcmcia_device *link) req.Size = 0x1000; } req.AccessSpeed = 0; - if (pcmcia_request_window(&link, &req, &link->win) != 0) + if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(link->win, &map) != 0) @@ -1789,14 +1802,17 @@ static int nsp_cs_config(struct pcmcia_device *link) next_entry: nsp_dbg(NSP_DEBUG_INIT, "next"); - pcmcia_disable_device(link); - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + + if (link->io.NumPorts1) { + pcmcia_release_io(link->handle, &link->io); + } + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } if (link->conf.Attributes & CONF_ENABLE_IRQ) { - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); } - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); if (free_ports) { if (link->io.BasePort1) { @@ -1838,19 +1854,16 @@ static int nsp_cs_config(struct pcmcia_device *link) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) - ret = scsi_add_host (host, NULL); - if (ret) - goto cs_failed; - + scsi_add_host (host, NULL); scsi_scan_host(host); snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no); - link->dev_node = &info->node; + link->dev = &info->node; info->host = host; #else nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO"); - tail = &link->dev_node; + tail = &link->dev; info->ndev = 0; nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); @@ -1895,10 +1908,11 @@ static int nsp_cs_config(struct pcmcia_device *link) #endif /* Finally, report what we've done */ - printk(KERN_INFO "nsp_cs: index 0x%02x: ", - link->conf.ConfigIndex); - if (link->conf.Vpp) { - printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); + printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d", + link->conf.ConfigIndex, + link->conf.Vcc/10, link->conf.Vcc%10); + if (link->conf.Vpp1) { + printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); } if (link->conf.Attributes & CONF_ENABLE_IRQ) { printk(", irq %d", link->irq.AssignedIRQ); @@ -1915,14 +1929,15 @@ static int nsp_cs_config(struct pcmcia_device *link) req.Base+req.Size-1); printk("\n"); - return 0; + link->state &= ~DEV_CONFIG_PENDING; + return; cs_failed: nsp_dbg(NSP_DEBUG_INIT, "config fail"); - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); nsp_cs_release(link); - return -ENODEV; + return; } /* nsp_cs_config */ #undef CS_CHECK @@ -1932,7 +1947,7 @@ static int nsp_cs_config(struct pcmcia_device *link) device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. ======================================================================*/ -static void nsp_cs_release(struct pcmcia_device *link) +static void nsp_cs_release(dev_link_t *link) { scsi_info_t *info = link->priv; nsp_hw_data *data = NULL; @@ -1953,15 +1968,22 @@ static void nsp_cs_release(struct pcmcia_device *link) #else scsi_unregister_host(&nsp_driver_template); #endif - link->dev_node = NULL; + link->dev = NULL; if (link->win) { if (data != NULL) { iounmap((void *)(data->MmioAddress)); } + pcmcia_release_window(link->win); } - pcmcia_disable_device(link); - + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) { + pcmcia_release_io(link->handle, &link->io); + } + if (link->irq.AssignedIRQ) { + pcmcia_release_irq(link->handle, &link->irq); + } + link->state &= ~DEV_CONFIG; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) if (info->host != NULL) { scsi_host_put(info->host); @@ -1969,11 +1991,14 @@ static void nsp_cs_release(struct pcmcia_device *link) #endif } /* nsp_cs_release */ -static int nsp_cs_suspend(struct pcmcia_device *link) +static int nsp_cs_suspend(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); scsi_info_t *info = link->priv; nsp_hw_data *data; + link->state |= DEV_SUSPEND; + nsp_dbg(NSP_DEBUG_INIT, "event: suspend"); if (info->host != NULL) { @@ -1986,16 +2011,25 @@ static int nsp_cs_suspend(struct pcmcia_device *link) info->stop = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + return 0; } -static int nsp_cs_resume(struct pcmcia_device *link) +static int nsp_cs_resume(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); scsi_info_t *info = link->priv; nsp_hw_data *data; nsp_dbg(NSP_DEBUG_INIT, "event: resume"); + link->state &= ~DEV_SUSPEND; + + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + info->stop = 0; if (info->host != NULL) { @@ -2031,7 +2065,7 @@ static struct pcmcia_driver nsp_driver = { .drv = { .name = "nsp_cs", }, - .probe = nsp_cs_probe, + .probe = nsp_cs_attach, .remove = nsp_cs_detach, .id_table = nsp_cs_ids, .suspend = nsp_cs_suspend, @@ -2064,7 +2098,19 @@ static int __init nsp_cs_init(void) static void __exit nsp_cs_exit(void) { nsp_msg(KERN_INFO, "unloading..."); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) pcmcia_unregister_driver(&nsp_driver); +#else + unregister_pcmcia_driver(&dev_info); + /* XXX: this really needs to move into generic code.. */ + while (dev_list != NULL) { + if (dev_list->state & DEV_CONFIG) { + nsp_cs_release(dev_list); + } + nsp_cs_detach(dev_list); + } +#endif } diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 8908b8e5b..b66b140a7 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -225,7 +225,7 @@ /*====================================================================*/ typedef struct scsi_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; struct Scsi_Host *host; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) dev_node_t node; @@ -297,8 +297,8 @@ typedef struct _nsp_hw_data { /* Card service functions */ static void nsp_cs_detach (struct pcmcia_device *p_dev); -static void nsp_cs_release(struct pcmcia_device *link); -static int nsp_cs_config (struct pcmcia_device *link); +static void nsp_cs_release(dev_link_t *link); +static void nsp_cs_config (dev_link_t *link); /* Linux SCSI subsystem specific functions */ static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); @@ -450,7 +450,7 @@ static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno) return host; } -static void cs_error(struct pcmcia_device *handle, int func, int ret) +static void cs_error(client_handle_t handle, int func, int ret) { error_info_t err = { func, ret }; pcmcia_report_error(handle, &err); diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 86c2ac6ae..dce7e687f 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -91,18 +91,18 @@ static struct scsi_host_template qlogicfas_driver_template = { /*====================================================================*/ typedef struct scsi_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct Scsi_Host *host; unsigned short manf_id; } scsi_info_t; -static void qlogic_release(struct pcmcia_device *link); +static void qlogic_release(dev_link_t *link); static void qlogic_detach(struct pcmcia_device *p_dev); -static int qlogic_config(struct pcmcia_device * link); +static void qlogic_config(dev_link_t * link); static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, - struct pcmcia_device *link, int qbase, int qlirq) + dev_link_t *link, int qbase, int qlirq) { int qltyp; /* type of chip */ int qinitid; @@ -156,9 +156,10 @@ free_scsi_host: err: return NULL; } -static int qlogic_probe(struct pcmcia_device *link) +static int qlogic_attach(struct pcmcia_device *p_dev) { scsi_info_t *info; + dev_link_t *link; DEBUG(0, "qlogic_attach()\n"); @@ -167,7 +168,7 @@ static int qlogic_probe(struct pcmcia_device *link) if (!info) return -ENOMEM; memset(info, 0, sizeof(*info)); - info->p_dev = link; + link = &info->link; link->priv = info; link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -175,19 +176,30 @@ static int qlogic_probe(struct pcmcia_device *link) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - return qlogic_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + qlogic_config(link); + + return 0; } /* qlogic_attach */ /*====================================================================*/ -static void qlogic_detach(struct pcmcia_device *link) +static void qlogic_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + DEBUG(0, "qlogic_detach(0x%p)\n", link); - qlogic_release(link); + if (link->state & DEV_CONFIG) + qlogic_release(link); + kfree(link->priv); } /* qlogic_detach */ @@ -197,8 +209,9 @@ static void qlogic_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int qlogic_config(struct pcmcia_device * link) +static void qlogic_config(dev_link_t * link) { + client_handle_t handle = link->handle; scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; @@ -212,35 +225,38 @@ static int qlogic_config(struct pcmcia_device * link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; tuple.DesiredTuple = CISTPL_MANFID; - if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) + if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) info->manf_id = le16_to_cpu(tuple.TupleData[0]); + /* Configure card */ + link->state |= DEV_CONFIG; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; link->conf.ConfigIndex = parse.cftable_entry.index; link->io.BasePort1 = parse.cftable_entry.io.win[0].base; link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; if (link->io.BasePort1 != 0) { - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(handle, &link->io); if (i == CS_SUCCESS) break; } next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { /* set ATAcmd */ @@ -259,54 +275,82 @@ static int qlogic_config(struct pcmcia_device * link) if (!host) { printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); - goto cs_failed; + goto out; } sprintf(info->node.dev_name, "scsi%d", host->host_no); - link->dev_node = &info->node; + link->dev = &info->node; info->host = host; - return 0; +out: + link->state &= ~DEV_CONFIG_PENDING; + return; cs_failed: - cs_error(link, last_fn, last_ret); - pcmcia_disable_device(link); - return -ENODEV; + cs_error(link->handle, last_fn, last_ret); + link->dev = NULL; + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; + return; } /* qlogic_config */ /*====================================================================*/ -static void qlogic_release(struct pcmcia_device *link) +static void qlogic_release(dev_link_t *link) { scsi_info_t *info = link->priv; DEBUG(0, "qlogic_release(0x%p)\n", link); scsi_remove_host(info->host); + link->dev = NULL; free_irq(link->irq.AssignedIRQ, info->host); - pcmcia_disable_device(link); + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); scsi_host_put(info->host); + + link->state &= ~DEV_CONFIG; } /*====================================================================*/ -static int qlogic_resume(struct pcmcia_device *link) +static int qlogic_suspend(struct pcmcia_device *dev) { - scsi_info_t *info = link->priv; + dev_link_t *link = dev_to_instance(dev); - pcmcia_request_configuration(link, &link->conf); - if ((info->manf_id == MANFID_MACNICA) || - (info->manf_id == MANFID_PIONEER) || - (info->manf_id == 0x0098)) { - outb(0x80, link->io.BasePort1 + 0xd); - outb(0x24, link->io.BasePort1 + 0x9); - outb(0x04, link->io.BasePort1 + 0xd); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int qlogic_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + scsi_info_t *info = link->priv; + + pcmcia_request_configuration(link->handle, &link->conf); + if ((info->manf_id == MANFID_MACNICA) || + (info->manf_id == MANFID_PIONEER) || + (info->manf_id == 0x0098)) { + outb(0x80, link->io.BasePort1 + 0xd); + outb(0x24, link->io.BasePort1 + 0x9); + outb(0x04, link->io.BasePort1 + 0xd); + } + /* Ugggglllyyyy!!! */ + qlogicfas408_bus_reset(NULL); } - /* Ugggglllyyyy!!! */ - qlogicfas408_bus_reset(NULL); return 0; } @@ -338,9 +382,10 @@ static struct pcmcia_driver qlogic_cs_driver = { .drv = { .name = "qlogic_cs", }, - .probe = qlogic_probe, + .probe = qlogic_attach, .remove = qlogic_detach, .id_table = qlogic_ids, + .suspend = qlogic_suspend, .resume = qlogic_resume, }; diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 9f5982770..3a4dd6f5b 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -202,7 +202,7 @@ static char *version = /* ================================================================== */ struct scsi_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; struct Scsi_Host *host; unsigned short manf_id; @@ -527,7 +527,7 @@ idle_out: } static void -SYM53C500_release(struct pcmcia_device *link) +SYM53C500_release(dev_link_t *link) { struct scsi_info_t *info = link->priv; struct Scsi_Host *shost = info->host; @@ -550,7 +550,13 @@ SYM53C500_release(struct pcmcia_device *link) if (shost->io_port && shost->n_io_port) release_region(shost->io_port, shost->n_io_port); - pcmcia_disable_device(link); + link->dev = NULL; + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; scsi_host_put(shost); } /* SYM53C500_release */ @@ -707,9 +713,10 @@ static struct scsi_host_template sym53c500_driver_template = { #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int -SYM53C500_config(struct pcmcia_device *link) +static void +SYM53C500_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct scsi_info_t *info = link->priv; tuple_t tuple; cisparse_t parse; @@ -726,37 +733,40 @@ SYM53C500_config(struct pcmcia_device *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; tuple.DesiredTuple = CISTPL_MANFID; - if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && - (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) + if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) info->manf_id = le16_to_cpu(tuple.TupleData[0]); + /* Configure card */ + link->state |= DEV_CONFIG; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; link->conf.ConfigIndex = parse.cftable_entry.index; link->io.BasePort1 = parse.cftable_entry.io.win[0].base; link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; if (link->io.BasePort1 != 0) { - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(handle, &link->io); if (i == CS_SUCCESS) break; } next_entry: - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); /* * That's the trouble with copying liberally from another driver. @@ -825,7 +835,7 @@ next_entry: data->fast_pio = USE_FAST_PIO; sprintf(info->node.dev_name, "scsi%d", host->host_no); - link->dev_node = &info->node; + link->dev = &info->node; info->host = host; if (scsi_add_host(host, NULL)) @@ -833,7 +843,7 @@ next_entry: scsi_scan_host(host); - return 0; + goto out; /* SUCCESS */ err_free_irq: free_irq(irq_level, host); @@ -842,50 +852,74 @@ err_free_scsi: err_release: release_region(port_base, 0x10); printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n"); - return -ENODEV; + +out: + link->state &= ~DEV_CONFIG_PENDING; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); SYM53C500_release(link); - return -ENODEV; + return; } /* SYM53C500_config */ -static int sym53c500_resume(struct pcmcia_device *link) +static int sym53c500_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int sym53c500_resume(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); struct scsi_info_t *info = link->priv; - /* See earlier comment about manufacturer IDs. */ - if ((info->manf_id == MANFID_MACNICA) || - (info->manf_id == MANFID_PIONEER) || - (info->manf_id == 0x0098)) { - outb(0x80, link->io.BasePort1 + 0xd); - outb(0x24, link->io.BasePort1 + 0x9); - outb(0x04, link->io.BasePort1 + 0xd); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + + /* See earlier comment about manufacturer IDs. */ + if ((info->manf_id == MANFID_MACNICA) || + (info->manf_id == MANFID_PIONEER) || + (info->manf_id == 0x0098)) { + outb(0x80, link->io.BasePort1 + 0xd); + outb(0x24, link->io.BasePort1 + 0x9); + outb(0x04, link->io.BasePort1 + 0xd); + } + /* + * If things don't work after a "resume", + * this is a good place to start looking. + */ + SYM53C500_int_host_reset(link->io.BasePort1); } - /* - * If things don't work after a "resume", - * this is a good place to start looking. - */ - SYM53C500_int_host_reset(link->io.BasePort1); return 0; } static void -SYM53C500_detach(struct pcmcia_device *link) +SYM53C500_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + DEBUG(0, "SYM53C500_detach(0x%p)\n", link); - SYM53C500_release(link); + if (link->state & DEV_CONFIG) + SYM53C500_release(link); kfree(link->priv); link->priv = NULL; } /* SYM53C500_detach */ static int -SYM53C500_probe(struct pcmcia_device *link) +SYM53C500_attach(struct pcmcia_device *p_dev) { struct scsi_info_t *info; + dev_link_t *link; DEBUG(0, "SYM53C500_attach()\n"); @@ -894,7 +928,7 @@ SYM53C500_probe(struct pcmcia_device *link) if (!info) return -ENOMEM; memset(info, 0, sizeof(*info)); - info->p_dev = link; + link = &info->link; link->priv = info; link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -902,10 +936,17 @@ SYM53C500_probe(struct pcmcia_device *link) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - return SYM53C500_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + SYM53C500_config(link); + + return 0; } /* SYM53C500_attach */ MODULE_AUTHOR("Bob Tracy "); @@ -925,9 +966,10 @@ static struct pcmcia_driver sym53c500_cs_driver = { .drv = { .name = "sym53c500_cs", }, - .probe = SYM53C500_probe, + .probe = SYM53C500_attach, .remove = SYM53C500_detach, .id_table = sym53c500_ids, + .suspend = sym53c500_suspend, .resume = sym53c500_resume, }; diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index 5cda16cfa..e8df0c9ec 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c @@ -131,7 +131,7 @@ static void adma_host_stop(struct ata_host_set *host_set); static void adma_port_stop(struct ata_port *ap); static void adma_phy_reset(struct ata_port *ap); static void adma_qc_prep(struct ata_queued_cmd *qc); -static unsigned int adma_qc_issue(struct ata_queued_cmd *qc); +static int adma_qc_issue(struct ata_queued_cmd *qc); static int adma_check_atapi_dma(struct ata_queued_cmd *qc); static void adma_bmdma_stop(struct ata_queued_cmd *qc); static u8 adma_bmdma_status(struct ata_port *ap); @@ -143,9 +143,11 @@ static struct scsi_host_template adma_ata_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ENABLE_CLUSTERING, @@ -320,7 +322,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) = (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4); i += 4; - VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4, + VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", nelem, (unsigned long)addr, len); } return i; @@ -417,7 +419,7 @@ static inline void adma_packet_start(struct ata_queued_cmd *qc) writew(aPIOMD4 | aGO, chan + ADMA_CONTROL); } -static unsigned int adma_qc_issue(struct ata_queued_cmd *qc) +static int adma_qc_issue(struct ata_queued_cmd *qc) { struct adma_port_priv *pp = qc->ap->private_data; diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 108910f51..05347eed9 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -727,7 +726,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd) retv--; if (retv) { - if (time_after(jiffies, dev->jstart + (1 * HZ))) { + if ((jiffies - dev->jstart) > (1 * HZ)) { printk ("ppa: Parallel port cable is unplugged!!\n"); ppa_fail(dev, DID_BUS_BUSY); @@ -982,12 +981,6 @@ static int device_check(ppa_struct *dev) return -ENODEV; } -static int ppa_adjust_queue(struct scsi_device *device) -{ - blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); - return 0; -} - static struct scsi_host_template ppa_template = { .module = THIS_MODULE, .proc_name = "ppa", @@ -1003,7 +996,6 @@ static struct scsi_host_template ppa_template = { .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, .can_queue = 1, - .slave_alloc = ppa_adjust_queue, }; /*************************************************************************** diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index 5c2cdf523..76972b44f 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c @@ -329,7 +329,7 @@ static void Irq_Handler (int irq, void *dev_id, struct pt_regs *regs) pinquiryData->AdditionalLength = 35 - 4; // Fill in vendor identification fields. - for ( z = 0; z < 20; z += 2 ) + for ( z = 0; z < 8; z += 2 ) { pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1]; pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z]; diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 5a48e55f9..e0230249f 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -350,7 +350,6 @@ #include #include #include -#include #include #include @@ -4322,7 +4321,7 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) #ifdef QLA_64BIT_PTR if (pci_set_dma_mask(ha->pdev, (dma_addr_t) ~ 0ULL)) { - if (pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK)) { + if (pci_set_dma_mask(ha->pdev, 0xffffffff)) { printk(KERN_WARNING "scsi(%li): Unable to set a " "suitable DMA mask - aborting\n", ha->host_no); error = -ENODEV; @@ -4332,7 +4331,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, 0xffffffff)) { printk(KERN_WARNING "scsi(%li): Unable to set a " "suitable DMA mask - aborting\n", ha->host_no); error = -ENODEV; diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index ff40906c6..5758b2566 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig @@ -10,13 +10,14 @@ config SCSI_QLA_FC By default, firmware for the ISP parts will be loaded via the Firmware Loader interface. - ISP Firmware Filename - ---------- ----------------- - 21xx ql2100_fw.bin - 22xx ql2200_fw.bin - 2300, 2312, 6312 ql2300_fw.bin - 2322, 6322 ql2322_fw.bin - 24xx ql2400_fw.bin + ISP Firmware Filename + ---------- ----------------- + 21xx ql2100_fw.bin + 22xx ql2200_fw.bin + 2300, 2312 ql2300_fw.bin + 2322 ql2322_fw.bin + 6312, 6322 ql6312_fw.bin + 24xx ql2400_fw.bin Upon request, the driver caches the firmware image until the driver is unloaded. @@ -50,17 +51,23 @@ config SCSI_QLA22XX This driver supports the QLogic 22xx (ISP2200) host adapter family. config SCSI_QLA2300 - tristate " Build QLogic ISP2300/ISP6312 firmware-module" + tristate " Build QLogic ISP2300 firmware-module" depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE ---help--- - This driver supports the QLogic 2300 (ISP2300, ISP2312 and - ISP6312) host adapter family. + This driver supports the QLogic 2300 (ISP2300 and ISP2312) host + adapter family. config SCSI_QLA2322 - tristate " Build QLogic ISP2322/ISP6322 firmware-module" + tristate " Build QLogic ISP2322 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 2322 (ISP2322) host adapter family. + +config SCSI_QLA6312 + tristate " Build QLogic ISP63xx firmware-module" depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE ---help--- - This driver supports the QLogic 2322 (ISP2322 and ISP6322) host + This driver supports the QLogic 63xx (ISP6312 and ISP6322) host adapter family. config SCSI_QLA24XX diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile index c8f670ee6..d028bc50c 100644 --- a/drivers/scsi/qla2xxx/Makefile +++ b/drivers/scsi/qla2xxx/Makefile @@ -9,10 +9,12 @@ qla2100-y := ql2100.o ql2100_fw.o qla2200-y := ql2200.o ql2200_fw.o qla2300-y := ql2300.o ql2300_fw.o qla2322-y := ql2322.o ql2322_fw.o +qla6312-y := ql6312.o ql6312_fw.o qla2400-y := ql2400.o ql2400_fw.o obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o +obj-$(CONFIG_SCSI_QLA6312) += qla2xxx.o qla6312.o obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o diff --git a/drivers/scsi/qla2xxx/ql2300.c b/drivers/scsi/qla2xxx/ql2300.c index e7a93ddda..fd2f4b795 100644 --- a/drivers/scsi/qla2xxx/ql2300.c +++ b/drivers/scsi/qla2xxx/ql2300.c @@ -40,11 +40,6 @@ static struct qla_board_info qla_board_tbl[] = { .isp_name = "ISP2312", .fw_info = qla_fw_tbl, }, - { - .drv_name = qla_driver_name, - .isp_name = "ISP6312", - .fw_info = qla_fw_tbl, - }, }; static struct pci_device_id qla2300_pci_tbl[] = { @@ -62,13 +57,6 @@ static struct pci_device_id qla2300_pci_tbl[] = { .subdevice = PCI_ANY_ID, .driver_data = (unsigned long)&qla_board_tbl[1], }, - { - .vendor = PCI_VENDOR_ID_QLOGIC, - .device = PCI_DEVICE_ID_QLOGIC_ISP6312, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long)&qla_board_tbl[2], - }, {0, 0}, }; MODULE_DEVICE_TABLE(pci, qla2300_pci_tbl); diff --git a/drivers/scsi/qla2xxx/ql2300_fw.c b/drivers/scsi/qla2xxx/ql2300_fw.c index b8ce7fe5d..dfc9cd58d 100644 --- a/drivers/scsi/qla2xxx/ql2300_fw.c +++ b/drivers/scsi/qla2xxx/ql2300_fw.c @@ -6,7 +6,7 @@ */ /* - * Firmware Version 3.03.20 (15:39 Feb 01, 2006) + * Firmware Version 3.03.18 (12:09 Sep 20, 2005) */ #ifdef UNIQUE_FW_NAME @@ -16,15 +16,15 @@ unsigned short risc_code_version = 3*1024+3; #endif #ifdef UNIQUE_FW_NAME -unsigned char fw2300ipx_version_str[] = {3, 3,20}; +unsigned char fw2300ipx_version_str[] = {3, 3,18}; #else -unsigned char firmware_version[] = {3, 3,20}; +unsigned char firmware_version[] = {3, 3,18}; #endif #ifdef UNIQUE_FW_NAME -#define fw2300ipx_VERSION_STRING "3.03.20" +#define fw2300ipx_VERSION_STRING "3.03.18" #else -#define FW_VERSION_STRING "3.03.20" +#define FW_VERSION_STRING "3.03.18" #endif #ifdef UNIQUE_FW_NAME @@ -38,12 +38,12 @@ unsigned short fw2300ipx_code01[] = { #else unsigned short risc_code01[] = { #endif - 0x0470, 0x0000, 0x0000, 0xf091, 0x0000, 0x0003, 0x0003, 0x0014, + 0x0470, 0x0000, 0x0000, 0xee08, 0x0000, 0x0003, 0x0003, 0x0012, 0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, - 0x332e, 0x3033, 0x2e32, 0x3020, 0x2020, 0x2020, 0x2400, 0x20a9, + 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000, @@ -52,173 +52,173 @@ unsigned short risc_code01[] = { 0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001, 0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78, - 0x7883, 0x0004, 0x2089, 0x2d93, 0x2051, 0x1800, 0x2a70, 0x20e1, + 0x7883, 0x0004, 0x2089, 0x2dac, 0x2051, 0x1800, 0x2a70, 0x20e1, 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e52, 0x2029, 0x4d00, 0x2031, 0xffff, 0x2039, 0x4cd0, 0x2021, 0x0200, 0x20e9, 0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9, 0x0001, 0x20a1, 0x1000, 0x900e, 0x2001, 0x0cc0, 0x9084, 0x0fff, 0x20a8, 0x4104, 0x2001, 0x0000, 0x9086, 0x0000, 0x0120, 0x21a8, 0x4104, 0x8001, 0x1de0, 0x756e, 0x7672, 0x776a, 0x7476, 0x747a, - 0x00e6, 0x2071, 0x1ad1, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x7170, + 0x00e6, 0x2071, 0x1ad2, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x7170, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x000f, 0x2001, 0x0001, 0x9112, 0x900e, 0x21a8, 0x4104, 0x8211, 0x1de0, 0x7170, 0x3400, 0x8001, 0x9102, 0x0120, 0x0218, 0x20a8, 0x900e, 0x4104, 0x2009, 0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e, 0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f26, 0x080c, - 0x613c, 0x080c, 0xb269, 0x080c, 0x10dd, 0x080c, 0x12fc, 0x080c, - 0x1bd7, 0x080c, 0x0d57, 0x080c, 0x1062, 0x080c, 0x34b6, 0x080c, - 0x7946, 0x080c, 0x6b7c, 0x080c, 0x8a69, 0x080c, 0x874a, 0x080c, - 0x24b7, 0x080c, 0x93a5, 0x080c, 0x8066, 0x080c, 0x22e8, 0x080c, - 0x241c, 0x080c, 0x24ac, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, + 0x6135, 0x080c, 0xb097, 0x080c, 0x10dd, 0x080c, 0x12fc, 0x080c, + 0x1c00, 0x080c, 0x0d57, 0x080c, 0x1062, 0x080c, 0x34ac, 0x080c, + 0x7862, 0x080c, 0x6ab6, 0x080c, 0x8935, 0x080c, 0x8616, 0x080c, + 0x24d8, 0x080c, 0x91e1, 0x080c, 0x7f32, 0x080c, 0x2311, 0x080c, + 0x2445, 0x080c, 0x24cd, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091f, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04, 0x0913, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1800, 0x7003, 0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, - 0x1178, 0x080c, 0x4d09, 0x080c, 0x34dd, 0x080c, 0x79b7, 0x080c, - 0x7122, 0x080c, 0x8b50, 0x080c, 0x8776, 0x080c, 0x2cdd, 0x0c58, + 0x1178, 0x080c, 0x4cae, 0x080c, 0x34d3, 0x080c, 0x78d3, 0x080c, + 0x7054, 0x080c, 0x8a1c, 0x080c, 0x8642, 0x080c, 0x2cf6, 0x0c58, 0x000b, 0x0c78, 0x0944, 0x0945, 0x0ae0, 0x0942, 0x0ba0, 0x0d56, 0x0d56, 0x0d56, 0x080c, 0x0dc5, 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0ab3, 0x080c, 0x0e94, - 0x080c, 0x7637, 0x0150, 0x080c, 0x765a, 0x15a0, 0x2079, 0x0100, - 0x7828, 0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x7563, 0x7000, + 0x080c, 0x7569, 0x0150, 0x080c, 0x758c, 0x15a0, 0x2079, 0x0100, + 0x7828, 0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x7495, 0x7000, 0x9086, 0x0001, 0x1904, 0x0ab3, 0x7098, 0x9086, 0x0029, 0x1904, - 0x0ab3, 0x080c, 0x8733, 0x080c, 0x8725, 0x2001, 0x0161, 0x2003, + 0x0ab3, 0x080c, 0x85ff, 0x080c, 0x85f1, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0x9295, 0x5e2f, - 0x7a2a, 0x2011, 0x74b2, 0x080c, 0x883d, 0x2011, 0x74a5, 0x080c, - 0x8917, 0x2011, 0x5f97, 0x080c, 0x883d, 0x2011, 0x8030, 0x901e, - 0x7396, 0x04d0, 0x080c, 0x583f, 0x2079, 0x0100, 0x7844, 0x9005, - 0x1904, 0x0ab3, 0x2011, 0x5f97, 0x080c, 0x883d, 0x2011, 0x74b2, - 0x080c, 0x883d, 0x2011, 0x74a5, 0x080c, 0x8917, 0x2001, 0x0265, + 0x7a2a, 0x2011, 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, + 0x87e3, 0x2011, 0x5f90, 0x080c, 0x8709, 0x2011, 0x8030, 0x901e, + 0x7396, 0x04d0, 0x080c, 0x583d, 0x2079, 0x0100, 0x7844, 0x9005, + 0x1904, 0x0ab3, 0x2011, 0x5f90, 0x080c, 0x8709, 0x2011, 0x73e4, + 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842, - 0x2001, 0x19a7, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100, - 0x080c, 0x60e4, 0x00ce, 0x0804, 0x0ab3, 0x780f, 0x006b, 0x7a28, - 0x080c, 0x763f, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, - 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a8, 0x2003, 0x0001, - 0x080c, 0x2b82, 0x080c, 0x4c44, 0x7248, 0xc284, 0x724a, 0x2001, - 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa9b0, 0x2011, - 0x0004, 0x080c, 0xd0e8, 0x080c, 0x6947, 0x080c, 0x7637, 0x1120, - 0x080c, 0x2bc6, 0x02e0, 0x0400, 0x080c, 0x60eb, 0x0140, 0x7097, - 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a11, 0x0804, 0x0ab3, 0x080c, - 0x57d5, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, - 0x080c, 0x57d9, 0xd0d4, 0x1118, 0x080c, 0x2bc6, 0x1270, 0x2011, - 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x57d9, 0xd0d4, 0x1db8, + 0x2001, 0x19a8, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100, + 0x080c, 0x60dd, 0x00ce, 0x0804, 0x0ab3, 0x780f, 0x006b, 0x7a28, + 0x080c, 0x7571, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, + 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a9, 0x2003, 0x0001, + 0x080c, 0x2b9b, 0x080c, 0x4be9, 0x7248, 0xc284, 0x724a, 0x2001, + 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa7de, 0x2011, + 0x0004, 0x080c, 0xce66, 0x080c, 0x6940, 0x080c, 0x7569, 0x1120, + 0x080c, 0x2bdf, 0x02e0, 0x0400, 0x080c, 0x60e4, 0x0140, 0x7097, + 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a0a, 0x0804, 0x0ab3, 0x080c, + 0x57d3, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, + 0x080c, 0x57d7, 0xd0d4, 0x1118, 0x080c, 0x2bdf, 0x1270, 0x2011, + 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x57d7, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, - 0xc0bd, 0x2012, 0x080c, 0x6a9b, 0x1128, 0xd0a4, 0x0118, 0x2204, - 0xc0fd, 0x2012, 0x080c, 0x6a61, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, - 0x00a8, 0x707f, 0x0000, 0x080c, 0x7637, 0x1130, 0x70b0, 0x9005, - 0x1168, 0x080c, 0xd52b, 0x0050, 0x080c, 0xd52b, 0x70dc, 0xd09c, - 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, 0x60c1, 0x70e7, 0x0000, - 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, 0x2bce, 0x0228, 0x2011, - 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x7637, 0x1178, - 0x9016, 0x0016, 0x080c, 0x298b, 0x2019, 0x196d, 0x211a, 0x001e, + 0xc0bd, 0x2012, 0x080c, 0x6a8a, 0x1128, 0xd0a4, 0x0118, 0x2204, + 0xc0fd, 0x2012, 0x080c, 0x6a50, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, + 0x00a8, 0x707f, 0x0000, 0x080c, 0x7569, 0x1130, 0x70b0, 0x9005, + 0x1168, 0x080c, 0xd2a9, 0x0050, 0x080c, 0xd2a9, 0x70dc, 0xd09c, + 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, 0x60ba, 0x70e7, 0x0000, + 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, 0x2be7, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x7569, 0x1178, + 0x9016, 0x0016, 0x080c, 0x29ac, 0x2019, 0x196e, 0x211a, 0x001e, 0x705f, 0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, - 0x196d, 0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, - 0xc295, 0x72de, 0x080c, 0x7637, 0x0118, 0x9296, 0x0004, 0x0548, - 0x2011, 0x0001, 0x080c, 0xd0e8, 0x70ab, 0x0000, 0x70af, 0xffff, + 0x196e, 0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, + 0xc295, 0x72de, 0x080c, 0x7569, 0x0118, 0x9296, 0x0004, 0x0548, + 0x2011, 0x0001, 0x080c, 0xce66, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, - 0x0003, 0x782a, 0x00fe, 0x080c, 0x3000, 0x2011, 0x0005, 0x080c, - 0xaabf, 0x080c, 0x9ab1, 0x080c, 0x7637, 0x0148, 0x00c6, 0x2061, - 0x0100, 0x0016, 0x080c, 0x298b, 0x61e2, 0x001e, 0x00ce, 0x012e, + 0x0003, 0x782a, 0x00fe, 0x080c, 0x3019, 0x2011, 0x0005, 0x080c, + 0xa8ed, 0x080c, 0x98ed, 0x080c, 0x7569, 0x0148, 0x00c6, 0x2061, + 0x0100, 0x0016, 0x080c, 0x29ac, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x0420, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x00f6, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a, - 0x00fe, 0x2011, 0x0005, 0x080c, 0xaabf, 0x080c, 0x9ab1, 0x080c, - 0x7637, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x298b, + 0x00fe, 0x2011, 0x0005, 0x080c, 0xa8ed, 0x080c, 0x98ed, 0x080c, + 0x7569, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x29ac, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, - 0x080c, 0x7637, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, - 0x080c, 0x7637, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, + 0x080c, 0x7569, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, + 0x080c, 0x7569, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, - 0x090c, 0x334c, 0x8108, 0x1f04, 0x0ac7, 0x707f, 0x0000, 0x7080, + 0x090c, 0x3342, 0x8108, 0x1f04, 0x0ac7, 0x707f, 0x0000, 0x7080, 0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, - 0x0b9d, 0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x3000, 0x080c, - 0x9ab1, 0x0804, 0x0b9d, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558, + 0x0b9d, 0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x3019, 0x080c, + 0x98ed, 0x0804, 0x0b9d, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558, 0xd084, 0x0548, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, - 0xd08c, 0x0508, 0x080c, 0x33af, 0x11d0, 0x70e0, 0x9086, 0xffff, - 0x01b0, 0x080c, 0x31bc, 0x080c, 0x9ab1, 0x70dc, 0xd094, 0x1904, - 0x0b9d, 0x2011, 0x0001, 0x080c, 0xd7e3, 0x0110, 0x2011, 0x0003, - 0x901e, 0x080c, 0x31f6, 0x080c, 0x9ab1, 0x0804, 0x0b9d, 0x70e4, + 0xd08c, 0x0508, 0x080c, 0x33a5, 0x11d0, 0x70e0, 0x9086, 0xffff, + 0x01b0, 0x080c, 0x31b2, 0x080c, 0x98ed, 0x70dc, 0xd094, 0x1904, + 0x0b9d, 0x2011, 0x0001, 0x080c, 0xd561, 0x0110, 0x2011, 0x0003, + 0x901e, 0x080c, 0x31ec, 0x080c, 0x98ed, 0x0804, 0x0b9d, 0x70e4, 0x9005, 0x1904, 0x0b9d, 0x70a8, 0x9005, 0x1904, 0x0b9d, 0x70dc, - 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0b9d, 0x080c, 0x6a61, 0x1904, - 0x0b9d, 0x080c, 0x6ab4, 0x1904, 0x0b9d, 0x080c, 0x6a9b, 0x01c0, - 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6724, + 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0b9d, 0x080c, 0x6a50, 0x1904, + 0x0b9d, 0x080c, 0x6aa3, 0x1904, 0x0b9d, 0x080c, 0x6a8a, 0x01c0, + 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b3d, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0b9d, - 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b4, - 0x080c, 0x0f96, 0x2011, 0x19ce, 0x080c, 0x0f96, 0x7030, 0xc08c, + 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b5, + 0x080c, 0x0f96, 0x2011, 0x19cf, 0x080c, 0x0f96, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff, 0x080c, 0x0e76, 0x9006, - 0x080c, 0x281c, 0x080c, 0x33af, 0x0118, 0x080c, 0x4de1, 0x0050, - 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4dfb, - 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x765a, 0x0150, - 0x080c, 0x7637, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, - 0xffdf, 0x782a, 0x00fe, 0x2001, 0x19e9, 0x2004, 0x9086, 0x0005, - 0x1120, 0x2011, 0x0000, 0x080c, 0xaabf, 0x2011, 0x0000, 0x080c, - 0xaac9, 0x080c, 0x9ab1, 0x080c, 0x9bd3, 0x012e, 0x00be, 0x0005, + 0x080c, 0x283d, 0x080c, 0x33a5, 0x0118, 0x080c, 0x4d86, 0x0050, + 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4da0, + 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x758c, 0x0150, + 0x080c, 0x7569, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, + 0xffdf, 0x782a, 0x00fe, 0x2001, 0x19ea, 0x2004, 0x9086, 0x0005, + 0x1120, 0x2011, 0x0000, 0x080c, 0xa8ed, 0x2011, 0x0000, 0x080c, + 0xa8f7, 0x080c, 0x98ed, 0x080c, 0x9a0f, 0x012e, 0x00be, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, - 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x60aa, + 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x60a3, 0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, - 0x7954, 0xd1ac, 0x1904, 0x0c2d, 0x2001, 0x19a8, 0x2004, 0x9005, - 0x1518, 0x080c, 0x2c49, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bb1, - 0x2001, 0x0001, 0x080c, 0x2b94, 0x00b8, 0x080c, 0x2c51, 0x1138, - 0x9006, 0x080c, 0x2bb1, 0x9006, 0x080c, 0x2b94, 0x0068, 0x080c, - 0x2c59, 0x1d50, 0x2001, 0x1998, 0x2004, 0xd0fc, 0x0108, 0x0020, - 0x080c, 0x29bf, 0x0804, 0x0d0d, 0x080c, 0x7648, 0x0148, 0x080c, - 0x765a, 0x1118, 0x080c, 0x7941, 0x0050, 0x080c, 0x763f, 0x0dd0, - 0x080c, 0x793c, 0x080c, 0x7932, 0x080c, 0x7563, 0x0058, 0x080c, - 0x7637, 0x0140, 0x2009, 0x00f8, 0x080c, 0x60aa, 0x7843, 0x0090, + 0x7954, 0xd1ac, 0x1904, 0x0c2d, 0x2001, 0x19a9, 0x2004, 0x9005, + 0x1518, 0x080c, 0x2c62, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bca, + 0x2001, 0x0001, 0x080c, 0x2bad, 0x00b8, 0x080c, 0x2c6a, 0x1138, + 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0068, 0x080c, + 0x2c72, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, + 0x080c, 0x29d8, 0x0804, 0x0d0d, 0x080c, 0x757a, 0x0148, 0x080c, + 0x758c, 0x1118, 0x080c, 0x785d, 0x0050, 0x080c, 0x7571, 0x0dd0, + 0x080c, 0x7858, 0x080c, 0x784e, 0x080c, 0x7495, 0x0058, 0x080c, + 0x7569, 0x0140, 0x2009, 0x00f8, 0x080c, 0x60a3, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, - 0x7637, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d12, 0x1f04, 0x0c0c, - 0x0070, 0x7824, 0x080c, 0x7651, 0x0118, 0xd0ac, 0x1904, 0x0d12, + 0x7569, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d12, 0x1f04, 0x0c0c, + 0x0070, 0x7824, 0x080c, 0x7583, 0x0118, 0xd0ac, 0x1904, 0x0d12, 0x9084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d12, 0x2001, - 0x0001, 0x080c, 0x281c, 0x0804, 0x0d25, 0x2001, 0x19a8, 0x2004, - 0x9005, 0x1518, 0x080c, 0x2c49, 0x1148, 0x2001, 0x0001, 0x080c, - 0x2bb1, 0x2001, 0x0001, 0x080c, 0x2b94, 0x00b8, 0x080c, 0x2c51, - 0x1138, 0x9006, 0x080c, 0x2bb1, 0x9006, 0x080c, 0x2b94, 0x0068, - 0x080c, 0x2c59, 0x1d50, 0x2001, 0x1998, 0x2004, 0xd0fc, 0x0108, - 0x0020, 0x080c, 0x29bf, 0x0804, 0x0d0d, 0x7850, 0x9085, 0x0040, - 0x7852, 0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c61, + 0x0001, 0x080c, 0x283d, 0x0804, 0x0d25, 0x2001, 0x19a9, 0x2004, + 0x9005, 0x1518, 0x080c, 0x2c62, 0x1148, 0x2001, 0x0001, 0x080c, + 0x2bca, 0x2001, 0x0001, 0x080c, 0x2bad, 0x00b8, 0x080c, 0x2c6a, + 0x1138, 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0068, + 0x080c, 0x2c72, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, + 0x0020, 0x080c, 0x29d8, 0x0804, 0x0d0d, 0x7850, 0x9085, 0x0040, + 0x7852, 0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c7a, 0x9085, 0x2000, 0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c66, - 0x080c, 0x88f7, 0x1f04, 0x0c66, 0x7850, 0x9085, 0x0400, 0x9084, - 0xdfbf, 0x7852, 0x793a, 0x080c, 0x7648, 0x0148, 0x080c, 0x765a, - 0x1118, 0x080c, 0x7941, 0x0050, 0x080c, 0x763f, 0x0dd0, 0x080c, - 0x793c, 0x080c, 0x7932, 0x080c, 0x7563, 0x0020, 0x2009, 0x00f8, - 0x080c, 0x60aa, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c8c, 0x7850, - 0x9085, 0x1400, 0x7852, 0x080c, 0x7637, 0x0120, 0x7843, 0x0090, - 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x88f7, - 0x7820, 0xd09c, 0x1588, 0x080c, 0x7637, 0x0904, 0x0cf2, 0x7824, - 0xd0ac, 0x1904, 0x0d12, 0x080c, 0x765a, 0x1530, 0x0046, 0x2021, - 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c61, + 0x080c, 0x87c3, 0x1f04, 0x0c66, 0x7850, 0x9085, 0x0400, 0x9084, + 0xdfbf, 0x7852, 0x793a, 0x080c, 0x757a, 0x0148, 0x080c, 0x758c, + 0x1118, 0x080c, 0x785d, 0x0050, 0x080c, 0x7571, 0x0dd0, 0x080c, + 0x7858, 0x080c, 0x784e, 0x080c, 0x7495, 0x0020, 0x2009, 0x00f8, + 0x080c, 0x60a3, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c8c, 0x7850, + 0x9085, 0x1400, 0x7852, 0x080c, 0x7569, 0x0120, 0x7843, 0x0090, + 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x87c3, + 0x7820, 0xd09c, 0x1588, 0x080c, 0x7569, 0x0904, 0x0cf2, 0x7824, + 0xd0ac, 0x1904, 0x0d12, 0x080c, 0x758c, 0x1530, 0x0046, 0x2021, + 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c7a, 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d33, 0x8421, - 0x1158, 0x1d04, 0x0ccd, 0x080c, 0x88f7, 0x080c, 0x793c, 0x080c, - 0x7932, 0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cda, - 0x080c, 0x88f7, 0x2009, 0x199b, 0x2104, 0x9005, 0x0118, 0x8001, + 0x1158, 0x1d04, 0x0ccd, 0x080c, 0x87c3, 0x080c, 0x7858, 0x080c, + 0x784e, 0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cda, + 0x080c, 0x87c3, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, 0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, - 0x080c, 0x2c42, 0x7924, 0x080c, 0x2c61, 0xd19c, 0x0110, 0x080c, - 0x2b82, 0x00d8, 0x080c, 0x7648, 0x1140, 0x94a2, 0x03e8, 0x1128, - 0x080c, 0x760f, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, - 0x2c61, 0x7824, 0x080c, 0x7651, 0x0110, 0xd0ac, 0x1158, 0x9084, + 0x080c, 0x2c5b, 0x7924, 0x080c, 0x2c7a, 0xd19c, 0x0110, 0x080c, + 0x2b9b, 0x00d8, 0x080c, 0x757a, 0x1140, 0x94a2, 0x03e8, 0x1128, + 0x080c, 0x7541, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, + 0x2c7a, 0x7824, 0x080c, 0x7583, 0x0110, 0xd0ac, 0x1158, 0x9084, 0x1800, 0x0950, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, - 0x281c, 0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, + 0x283d, 0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028, - 0x782a, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x19a8, 0x2003, + 0x782a, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x19a9, 0x2003, 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6, - 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x88f7, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x87c3, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086, - 0x0001, 0x1110, 0x080c, 0x34dd, 0x00ee, 0x0005, 0x0005, 0x2a70, - 0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0014, - 0x600f, 0x0137, 0x2001, 0x197c, 0x900e, 0x2102, 0x7196, 0x2001, + 0x0001, 0x1110, 0x080c, 0x34d3, 0x00ee, 0x0005, 0x0005, 0x2a70, + 0x2061, 0x19ad, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0012, + 0x600f, 0x0137, 0x2001, 0x197d, 0x900e, 0x2102, 0x7196, 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008, - 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd52b, 0x70eb, - 0x00c0, 0x2061, 0x196c, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, + 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd2a9, 0x70eb, + 0x00c0, 0x2061, 0x196d, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f, - 0x07d0, 0x2061, 0x1974, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, + 0x07d0, 0x2061, 0x1975, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, - 0x1989, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, - 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6724, + 0x198a, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, + 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x671d, 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210, 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, @@ -226,20 +226,20 @@ unsigned short risc_code01[] = { 0x0dc7, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000, 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, 0x000e, 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae, - 0x681c, 0x78b2, 0x2001, 0x1a09, 0x2004, 0x78b6, 0x2001, 0x1a86, + 0x681c, 0x78b2, 0x2001, 0x1a0a, 0x2004, 0x78b6, 0x2001, 0x1a87, 0x2004, 0x78ba, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, - 0x1aa9, 0x7a08, 0x226a, 0x2069, 0x1aaa, 0x7a18, 0x226a, 0x8d68, - 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1ab7, 0x201a, 0x2019, 0x1aba, + 0x1aaa, 0x7a08, 0x226a, 0x2069, 0x1aab, 0x7a18, 0x226a, 0x8d68, + 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1ab8, 0x201a, 0x2019, 0x1abb, 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, - 0x9386, 0x1acf, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, - 0xdead, 0x2019, 0x1ab8, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, - 0x0000, 0x2069, 0x1a89, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, + 0x9386, 0x1ad0, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, + 0xdead, 0x2019, 0x1ab9, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, + 0x0000, 0x2069, 0x1a8a, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0e26, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1c, 0x2004, 0x9005, + 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1d, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, - 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x57e4, 0x1108, 0x0099, + 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x57e2, 0x1108, 0x0099, 0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600, 0x1118, 0x918d, 0x2800, 0x0010, 0x918d, 0x2000, 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, @@ -251,8 +251,8 @@ unsigned short risc_code01[] = { 0x080c, 0x0f00, 0x002e, 0x0005, 0x0026, 0x080c, 0x0efb, 0x0128, 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, 0x0f00, 0x002e, 0x0005, 0x0026, 0x70ef, 0x0000, 0x080c, 0x0efb, - 0x1148, 0x080c, 0x2c59, 0x1118, 0x2011, 0x8484, 0x0058, 0x2011, - 0x8282, 0x0040, 0x080c, 0x2c59, 0x1118, 0x2011, 0xcdc5, 0x0010, + 0x1148, 0x080c, 0x2c72, 0x1118, 0x2011, 0x8484, 0x0058, 0x2011, + 0x8282, 0x0040, 0x080c, 0x2c72, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f00, 0x002e, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70e8, 0x1110, 0xc0e4, 0x0048, 0x0006, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x70ef, 0x0000, 0xc0e5, @@ -305,7 +305,7 @@ unsigned short risc_code01[] = { 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, 0xa802, - 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x012e, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, 0x0040, @@ -321,21 +321,21 @@ unsigned short risc_code01[] = { 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278, 0x9982, 0x0534, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188d, 0x7010, 0x9902, 0x1228, 0x9085, 0x0001, - 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x1a1b, + 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x1a1c, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x10f1, 0x702b, 0x0020, 0x00ee, 0x0005, - 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a1b, - 0x701c, 0x9088, 0x1a25, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, + 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a1c, + 0x701c, 0x9088, 0x1a26, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0dc5, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, - 0x2091, 0x8000, 0x00e6, 0x2071, 0x1a1b, 0x7004, 0x9005, 0x1128, + 0x2091, 0x8000, 0x00e6, 0x2071, 0x1a1c, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, 0x113a, 0x12bd, 0x1138, 0x1138, 0x12b1, 0x12b1, 0x12b1, 0x12b1, 0x080c, 0x0dc5, 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, - 0x9180, 0x1a25, 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, + 0x9180, 0x1a26, 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, @@ -347,8 +347,8 @@ unsigned short risc_code01[] = { 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, - 0x001e, 0x0005, 0x2009, 0x1a1b, 0x2104, 0xc095, 0x200a, 0x080c, - 0x1117, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1a1b, 0x00f6, 0x2079, + 0x001e, 0x0005, 0x2009, 0x1a1c, 0x2104, 0xc095, 0x200a, 0x080c, + 0x1117, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1a1c, 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c, 0x0dbe, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1128, 0x11d0, 0x1204, 0x12dc, 0x0dc5, 0x12f7, 0x0dc5, @@ -370,45 +370,45 @@ unsigned short risc_code01[] = { 0x1117, 0x0005, 0x00de, 0x009e, 0x080c, 0x1117, 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, - 0x4002, 0x080c, 0x6e92, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, + 0x4002, 0x080c, 0x6dc4, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x1040, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, - 0x10f8, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6e92, + 0x10f8, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6dc4, 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, - 0x080c, 0xb2d3, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, + 0x080c, 0xb101, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, 0x1040, 0x7007, 0x0000, 0x080c, 0x1117, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, - 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x192f, + 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x1930, 0x204c, 0xa87c, 0x7812, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0x782b, 0x0020, 0x0126, 0x2091, 0x8000, 0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900, 0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088, - 0x782b, 0x0040, 0x0096, 0x2001, 0x192f, 0x204c, 0xaa7c, 0x009e, - 0x080c, 0x8d91, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, - 0x080c, 0x8bf3, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7007, + 0x782b, 0x0040, 0x0096, 0x2001, 0x1930, 0x204c, 0xaa7c, 0x009e, + 0x080c, 0x8c5a, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, + 0x080c, 0x8abf, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, - 0x0300, 0x2071, 0x1a65, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x781b, - 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9, 0x03ea, - 0x2061, 0xf0ae, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, + 0x0300, 0x2071, 0x1a66, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x781b, + 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9, 0x03e8, + 0x2061, 0xee29, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, 0x1f04, 0x1312, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0120, - 0x7820, 0x080c, 0x1376, 0x0cc8, 0x2001, 0x1a66, 0x2003, 0x0000, + 0x7820, 0x080c, 0x1376, 0x0cc8, 0x2001, 0x1a67, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, - 0x1a89, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200, 0x2004, - 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a89, 0x602f, 0x1cd0, - 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, 0x20c7, - 0x2001, 0x33b6, 0xd0fc, 0x190c, 0x0dc5, 0x2001, 0x1810, 0x2004, + 0x1a8a, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200, 0x2004, + 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a8a, 0x602f, 0x1cd0, + 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, 0x20f0, + 0x2001, 0x33ac, 0xd0fc, 0x190c, 0x0dc5, 0x2001, 0x1810, 0x2004, 0xd0c4, 0x1128, 0x2001, 0x0003, 0x2004, 0xd0d4, 0x1118, 0x783f, - 0x33b6, 0x0020, 0x9084, 0xc000, 0x783f, 0xb3b6, 0x604f, 0x193d, - 0x2001, 0x1928, 0x2004, 0x6042, 0x00ce, 0x0005, 0x9086, 0x000d, + 0x33ac, 0x0020, 0x9084, 0xc000, 0x783f, 0xb3ac, 0x604f, 0x193e, + 0x2001, 0x1929, 0x2004, 0x6042, 0x00ce, 0x0005, 0x9086, 0x000d, 0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c, - 0xd0c6, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, + 0xce44, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, 0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c, - 0xb352, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, + 0xb180, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c, 0x0dbe, 0xd19c, 0x0158, 0x7820, 0x908c, 0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0dc5, 0x0023, 0x012e, 0x0005, 0x012e, 0x0005, 0x13cf, 0x13cf, 0x13e6, 0x13eb, 0x13ef, @@ -416,18 +416,18 @@ unsigned short risc_code01[] = { 0x1575, 0x157c, 0x13cf, 0x157d, 0x157e, 0x1589, 0x1590, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13f6, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13d3, 0x13d1, 0x080c, - 0x0dc5, 0x080c, 0x0dbe, 0x080c, 0x159b, 0x2009, 0x1a7e, 0x2104, - 0x8000, 0x200a, 0x080c, 0x813a, 0x080c, 0x1ad9, 0x0005, 0x2009, - 0x0048, 0x2060, 0x080c, 0xb352, 0x012e, 0x0005, 0x7004, 0xc085, + 0x0dc5, 0x080c, 0x0dbe, 0x080c, 0x159b, 0x2009, 0x1a7f, 0x2104, + 0x8000, 0x200a, 0x080c, 0x8006, 0x080c, 0x1b02, 0x0005, 0x2009, + 0x0048, 0x2060, 0x080c, 0xb180, 0x012e, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x159b, 0x080c, 0x16fb, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x159b, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, - 0x0048, 0x080c, 0xb352, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, + 0x0048, 0x080c, 0xb180, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x15a0, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x159b, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, - 0x009e, 0x2009, 0x0048, 0x080c, 0xb352, 0x0005, 0x080c, 0x159b, + 0x009e, 0x2009, 0x0048, 0x080c, 0xb180, 0x0005, 0x080c, 0x159b, 0x080c, 0x0dc5, 0x080c, 0x159b, 0x080c, 0x14ea, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0904, 0x149b, 0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, @@ -437,20 +437,20 @@ unsigned short risc_code01[] = { 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1503, 0x0005, 0x7827, 0x0018, 0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106, 0x0110, 0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4, - 0x0140, 0x00ee, 0x080c, 0x1ad9, 0x080c, 0x1322, 0x7803, 0x0001, + 0x0140, 0x00ee, 0x080c, 0x1b02, 0x080c, 0x1322, 0x7803, 0x0001, 0x0005, 0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006, 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1503, 0x2001, 0x020d, 0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, 0x0dc5, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, - 0x080c, 0x813a, 0x080c, 0x1ad9, 0x080c, 0xd0d8, 0x0158, 0xa9ac, + 0x080c, 0x8006, 0x080c, 0x1b02, 0x080c, 0xce56, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, - 0xc0bd, 0xa882, 0x080c, 0xccf3, 0x0005, 0x6020, 0x9086, 0x0009, - 0x1128, 0x2009, 0x004c, 0x080c, 0xb352, 0x0048, 0x6010, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd4c4, 0x2029, + 0xc0bd, 0xa882, 0x080c, 0xca71, 0x0005, 0x6020, 0x9086, 0x0009, + 0x1128, 0x2009, 0x004c, 0x080c, 0xb180, 0x0048, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd242, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, - 0x7dbc, 0x080c, 0xf057, 0xd5a4, 0x1118, 0x080c, 0x15a0, 0x0005, - 0x080c, 0x813a, 0x080c, 0x1ad9, 0x0005, 0x781f, 0x0300, 0x7803, + 0x7dbc, 0x080c, 0xedd2, 0xd5a4, 0x1118, 0x080c, 0x15a0, 0x0005, + 0x080c, 0x8006, 0x080c, 0x1b02, 0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x1611, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, @@ -463,15 +463,15 @@ unsigned short risc_code01[] = { 0x05b0, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550, 0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, - 0x00b0, 0x00f6, 0x2c78, 0x080c, 0x18fd, 0x00fe, 0x2009, 0x01f4, + 0x00b0, 0x00f6, 0x2c78, 0x080c, 0x18f1, 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x15a0, 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c, 0x1322, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x16de, 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009, - 0x0053, 0x080c, 0xb352, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, - 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x90de, - 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8ce2, 0x0cd0, 0x0005, + 0x0053, 0x080c, 0xb180, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, + 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x8fab, + 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8bae, 0x0cd0, 0x0005, 0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214, 0x080c, 0x1611, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c, 0x14ea, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, @@ -481,7 +481,7 @@ unsigned short risc_code01[] = { 0x810c, 0x080c, 0x1603, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, - 0x080c, 0x813a, 0x080c, 0x1ad9, 0x0090, 0x7827, 0x0015, 0x782b, + 0x080c, 0x8006, 0x080c, 0x1b02, 0x0090, 0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, @@ -497,17 +497,17 @@ unsigned short risc_code01[] = { 0x0904, 0x168a, 0x9284, 0x0048, 0x9086, 0x0008, 0x1904, 0x168a, 0x2001, 0x0109, 0x2004, 0xd08c, 0x01f0, 0x0006, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x0126, 0x2091, 0x2800, 0x00f6, 0x0026, - 0x0016, 0x2009, 0x1a81, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, - 0x94b1, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e, 0x014e, 0x013e, + 0x0016, 0x2009, 0x1a82, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, + 0x92ed, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x000e, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x01d0, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x00f6, - 0x0016, 0x2009, 0x1a82, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, - 0x1eeb, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, + 0x0016, 0x2009, 0x1a83, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, + 0x1f14, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x7818, 0xd0bc, 0x1904, 0x163a, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0f4, 0x1528, 0x7a18, 0x9284, 0x0030, 0x0508, - 0x9284, 0x0048, 0x9086, 0x0008, 0x11e0, 0x2001, 0x19f7, 0x2004, - 0x9005, 0x01b8, 0x2001, 0x1a69, 0x2004, 0x9086, 0x0000, 0x0188, - 0x2009, 0x1a80, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa767, + 0x9284, 0x0048, 0x9086, 0x0008, 0x11e0, 0x2001, 0x19f8, 0x2004, + 0x9005, 0x01b8, 0x2001, 0x1a6a, 0x2004, 0x9086, 0x0000, 0x0188, + 0x2009, 0x1a81, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa595, 0x2009, 0x180c, 0x2104, 0xc0f5, 0x200a, 0x2009, 0xff00, 0x0804, 0x163a, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x080c, 0x1633, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, @@ -515,7232 +515,7150 @@ unsigned short risc_code01[] = { 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, - 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a7f, 0x2404, 0x8000, - 0x0208, 0x2022, 0x080c, 0x813a, 0x080c, 0x1ad9, 0x9006, 0x00ee, + 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a80, 0x2404, 0x8000, + 0x0208, 0x2022, 0x080c, 0x8006, 0x080c, 0x1b02, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x175d, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x175d, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x175d, 0x9c06, 0x15f0, 0x0126, - 0x2091, 0x2600, 0x080c, 0x8081, 0x012e, 0x7358, 0x745c, 0x6014, + 0x2091, 0x2600, 0x080c, 0x7f4d, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x190c, 0xd49f, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, + 0xd0bc, 0x190c, 0xd21d, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, - 0x080c, 0x20e7, 0x1190, 0x080c, 0x195a, 0x2a00, 0xa816, 0x0130, + 0x080c, 0x2110, 0x1190, 0x080c, 0x194e, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x15a0, 0x0005, 0x080c, 0x0dc5, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x190c, 0x6b5e, 0x2ff0, 0x0126, - 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, - 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, - 0x20c7, 0x2165, 0x0002, 0x179a, 0x1808, 0x179a, 0x179a, 0x179e, - 0x17e9, 0x179a, 0x17be, 0x1793, 0x17ff, 0x179a, 0x179a, 0x17a3, - 0x18f5, 0x17d2, 0x17c8, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, - 0x0904, 0x17ff, 0x9085, 0x0001, 0x0804, 0x18eb, 0xa87c, 0xd0ac, - 0x0dc8, 0x0804, 0x180f, 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x187a, - 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42, - 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x933d, 0x2005, 0x9005, - 0x090c, 0x0dc5, 0x2004, 0xa8ae, 0x0804, 0x18d3, 0xa87c, 0xd0bc, - 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x180f, - 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, - 0x0804, 0x187a, 0xa87c, 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, - 0xa83e, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa164, 0xa91a, 0x91ec, - 0x000f, 0x9d80, 0x20c7, 0x2065, 0xa888, 0xd19c, 0x1904, 0x187a, - 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x179a, 0xa804, 0x9045, 0x090c, - 0x0dc5, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20c7, 0x2065, - 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x187a, 0x0080, 0xa87c, - 0xd0ac, 0x0904, 0x179a, 0x9006, 0xa842, 0xa83e, 0x0804, 0x187a, - 0xa87c, 0xd0ac, 0x0904, 0x179a, 0x9006, 0xa842, 0xa83e, 0x2c05, - 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1832, - 0x1832, 0x1834, 0x1832, 0x1832, 0x1832, 0x183e, 0x1832, 0x1832, - 0x1832, 0x1848, 0x1832, 0x1832, 0x1832, 0x1852, 0x1832, 0x1832, - 0x1832, 0x185c, 0x1832, 0x1832, 0x1832, 0x1866, 0x1832, 0x1832, - 0x1832, 0x1870, 0x080c, 0x0dc5, 0xa574, 0xa478, 0x9d86, 0x0024, - 0x0904, 0x17a8, 0xa37c, 0xa280, 0x0804, 0x18d3, 0xa584, 0xa488, - 0x9d86, 0x0024, 0x0904, 0x17a8, 0xa38c, 0xa290, 0x0804, 0x18d3, - 0xa594, 0xa498, 0x9d86, 0x0024, 0x0904, 0x17a8, 0xa39c, 0xa2a0, - 0x0804, 0x18d3, 0xa5a4, 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x17a8, - 0xa3ac, 0xa2b0, 0x0804, 0x18d3, 0xa5b4, 0xa4b8, 0x9d86, 0x0024, - 0x0904, 0x17a8, 0xa3bc, 0xa2c0, 0x0804, 0x18d3, 0xa5c4, 0xa4c8, - 0x9d86, 0x0024, 0x0904, 0x17a8, 0xa3cc, 0xa2d0, 0x0804, 0x18d3, - 0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904, 0x17a8, 0xa3dc, 0xa2e0, - 0x0804, 0x18d3, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, - 0x001b, 0x0002, 0x189d, 0x189b, 0x189b, 0x189b, 0x189b, 0x189b, - 0x18a8, 0x189b, 0x189b, 0x189b, 0x189b, 0x189b, 0x18b3, 0x189b, - 0x189b, 0x189b, 0x189b, 0x189b, 0x18be, 0x189b, 0x189b, 0x189b, - 0x189b, 0x189b, 0x18c9, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, - 0xa678, 0x9d86, 0x002c, 0x0904, 0x17a8, 0xa37c, 0xa280, 0x0458, - 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c, 0x0904, 0x17a8, - 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, - 0x002c, 0x0904, 0x17a8, 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, - 0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904, 0x17a8, 0xa3c4, 0xa2c8, - 0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904, - 0x17a8, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, - 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, - 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, - 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, - 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x179a, 0x2001, - 0x180d, 0x2004, 0xd08c, 0x190c, 0x6b5e, 0x2ff0, 0x0126, 0x2091, - 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, - 0x2061, 0x20c2, 0xa813, 0x20c2, 0x2c05, 0xa80a, 0xa964, 0xa91a, - 0xa87c, 0xd0ac, 0x090c, 0x0dc5, 0x9006, 0xa842, 0xa83e, 0x2c05, - 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0xadcc, 0xacd0, 0xafd4, 0xaed8, - 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, - 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, - 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, - 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, - 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, - 0x9045, 0x090c, 0x0dc5, 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, - 0x9080, 0x20c7, 0x2015, 0x82ff, 0x090c, 0x0dc5, 0xaa12, 0x2205, - 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, - 0x0002, 0x1a4f, 0x19b1, 0x19b1, 0x1a4f, 0x1a4f, 0x1a49, 0x1a4f, - 0x19b1, 0x1a00, 0x1a00, 0x1a00, 0x1a4f, 0x1a4f, 0x1a4f, 0x1a46, - 0x1a00, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, - 0x0904, 0x1a51, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, - 0x001b, 0x0002, 0x199d, 0x199b, 0x199b, 0x199b, 0x199b, 0x199b, - 0x19a1, 0x199b, 0x199b, 0x199b, 0x199b, 0x199b, 0x19a5, 0x199b, - 0x199b, 0x199b, 0x199b, 0x199b, 0x19a9, 0x199b, 0x199b, 0x199b, - 0x199b, 0x199b, 0x19ad, 0x080c, 0x0dc5, 0xa774, 0xa678, 0x0804, - 0x1a51, 0xa78c, 0xa690, 0x0804, 0x1a51, 0xa7a4, 0xa6a8, 0x0804, - 0x1a51, 0xa7bc, 0xa6c0, 0x0804, 0x1a51, 0xa7d4, 0xa6d8, 0x0804, - 0x1a51, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, - 0x0002, 0x19d4, 0x19d4, 0x19d6, 0x19d4, 0x19d4, 0x19d4, 0x19dc, - 0x19d4, 0x19d4, 0x19d4, 0x19e2, 0x19d4, 0x19d4, 0x19d4, 0x19e8, - 0x19d4, 0x19d4, 0x19d4, 0x19ee, 0x19d4, 0x19d4, 0x19d4, 0x19f4, - 0x19d4, 0x19d4, 0x19d4, 0x19fa, 0x080c, 0x0dc5, 0xa574, 0xa478, - 0xa37c, 0xa280, 0x0804, 0x1a51, 0xa584, 0xa488, 0xa38c, 0xa290, - 0x0804, 0x1a51, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1a51, - 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1a51, 0xa5b4, 0xa4b8, - 0xa3bc, 0xa2c0, 0x0804, 0x1a51, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, - 0x0804, 0x1a51, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1a51, - 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, - 0x1a23, 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x1a2a, 0x1a21, - 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x1a31, 0x1a21, 0x1a21, 0x1a21, - 0x1a21, 0x1a21, 0x1a38, 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x1a21, - 0x1a3f, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, - 0xa280, 0x0438, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, - 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x00c8, - 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0090, 0xa5cc, - 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, - 0x1130, 0x080c, 0x207f, 0x1904, 0x195a, 0x900e, 0x0050, 0x080c, - 0x0dc5, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, - 0x207f, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, - 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, - 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, - 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, - 0xb352, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, - 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, - 0x601e, 0x2009, 0x0048, 0x0804, 0xb352, 0x0005, 0x0126, 0x00c6, - 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, - 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, - 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, - 0x080c, 0x1394, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, - 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1394, 0x00ce, 0x2001, - 0x0038, 0x080c, 0x1b69, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, - 0x0042, 0x190c, 0x0dc5, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, - 0x1d40, 0x080c, 0x1b78, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, - 0x1b65, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, - 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, - 0x2001, 0xf000, 0x8001, 0x090c, 0x0dc5, 0x7aac, 0xd2ac, 0x1dd0, - 0x00fe, 0x080c, 0x7637, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, - 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, - 0x8211, 0x1de0, 0x0059, 0x0804, 0x76e4, 0x0479, 0x0039, 0x2001, - 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, - 0x0200, 0x080c, 0x2c6d, 0x2009, 0x003c, 0x080c, 0x2409, 0x2001, - 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, - 0x8725, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, - 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1322, - 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, - 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, - 0x7637, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, - 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, - 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, - 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, - 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, - 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, - 0x0005, 0x2c08, 0x621c, 0x080c, 0x1611, 0x7930, 0x0005, 0x2c08, - 0x621c, 0x080c, 0x16bc, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, - 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, - 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bd6, 0x2001, 0x001e, 0x0c69, - 0x8631, 0x1d80, 0x080c, 0x0dc5, 0x781f, 0x0202, 0x2001, 0x015d, - 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, - 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, - 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, - 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, - 0x080c, 0x1b6f, 0x9186, 0x0040, 0x190c, 0x0dc5, 0x00d6, 0x2069, - 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, - 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, - 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, - 0x090c, 0x0dc5, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, - 0x2091, 0x2400, 0x2071, 0x1a69, 0x2079, 0x0090, 0x012e, 0x0005, - 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904, 0x1c78, - 0xa964, 0x9184, 0x0007, 0x0002, 0x1bf4, 0x1c63, 0x1c0b, 0x1c0d, - 0x1c0b, 0x1c4b, 0x1c2b, 0x1c1a, 0x918c, 0x00ff, 0x9186, 0x0008, - 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0x9006, 0xa842, 0xa83e, - 0xa988, 0x2900, 0xa85a, 0xa813, 0x20c2, 0x0804, 0x1c74, 0x9186, - 0x0048, 0x0904, 0x1c63, 0x080c, 0x0dc5, 0x9184, 0x00ff, 0x9086, - 0x0013, 0x0904, 0x1c63, 0x9184, 0x00ff, 0x9086, 0x001b, 0x0904, - 0x1c63, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0xa890, 0xa842, + 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, + 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, + 0x000f, 0x9088, 0x20f0, 0x2165, 0x0002, 0x1794, 0x1802, 0x1794, + 0x1794, 0x1798, 0x17e3, 0x1794, 0x17b8, 0x178d, 0x17f9, 0x1794, + 0x1794, 0x179d, 0x18ef, 0x17cc, 0x17c2, 0xa964, 0x918c, 0x00ff, + 0x918e, 0x0048, 0x0904, 0x17f9, 0x9085, 0x0001, 0x0804, 0x18e5, + 0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1809, 0xa87c, 0xd0ac, 0x0da0, + 0x0804, 0x1874, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2, + 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x9179, + 0x2005, 0x9005, 0x090c, 0x0dc5, 0x2004, 0xa8ae, 0x0804, 0x18cd, + 0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, + 0x0804, 0x1809, 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c, + 0xa83e, 0xa888, 0x0804, 0x1874, 0xa87c, 0xd0bc, 0x0928, 0xa890, + 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa164, + 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20f0, 0x2065, 0xa888, 0xd19c, + 0x1904, 0x1874, 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0xa804, + 0x9045, 0x090c, 0x0dc5, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, + 0x20f0, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1874, + 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0x9006, 0xa842, 0xa83e, + 0x0804, 0x1874, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0x9006, 0xa842, + 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, + 0x0002, 0x182c, 0x182c, 0x182e, 0x182c, 0x182c, 0x182c, 0x1838, + 0x182c, 0x182c, 0x182c, 0x1842, 0x182c, 0x182c, 0x182c, 0x184c, + 0x182c, 0x182c, 0x182c, 0x1856, 0x182c, 0x182c, 0x182c, 0x1860, + 0x182c, 0x182c, 0x182c, 0x186a, 0x080c, 0x0dc5, 0xa574, 0xa478, + 0x9d86, 0x0024, 0x0904, 0x17a2, 0xa37c, 0xa280, 0x0804, 0x18cd, + 0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, 0x17a2, 0xa38c, 0xa290, + 0x0804, 0x18cd, 0xa594, 0xa498, 0x9d86, 0x0024, 0x0904, 0x17a2, + 0xa39c, 0xa2a0, 0x0804, 0x18cd, 0xa5a4, 0xa4a8, 0x9d86, 0x0024, + 0x0904, 0x17a2, 0xa3ac, 0xa2b0, 0x0804, 0x18cd, 0xa5b4, 0xa4b8, + 0x9d86, 0x0024, 0x0904, 0x17a2, 0xa3bc, 0xa2c0, 0x0804, 0x18cd, + 0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, 0x17a2, 0xa3cc, 0xa2d0, + 0x0804, 0x18cd, 0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904, 0x17a2, + 0xa3dc, 0xa2e0, 0x0804, 0x18cd, 0x2c05, 0x908a, 0x0034, 0x1a0c, + 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1897, 0x1895, 0x1895, 0x1895, + 0x1895, 0x1895, 0x18a2, 0x1895, 0x1895, 0x1895, 0x1895, 0x1895, + 0x18ad, 0x1895, 0x1895, 0x1895, 0x1895, 0x1895, 0x18b8, 0x1895, + 0x1895, 0x1895, 0x1895, 0x1895, 0x18c3, 0x080c, 0x0dc5, 0xa56c, + 0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, 0x0904, 0x17a2, 0xa37c, + 0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c, + 0x0904, 0x17a2, 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, + 0xa6a8, 0x9d86, 0x002c, 0x0904, 0x17a2, 0xa3ac, 0xa2b0, 0x00a8, + 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904, 0x17a2, + 0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, + 0x002c, 0x0904, 0x17a2, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, + 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, + 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, + 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, + 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, + 0x1794, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, + 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x20eb, 0xa813, 0x20eb, + 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0dc5, + 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, + 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, + 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, + 0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109, + 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, + 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, + 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa80e, + 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x20f0, 0x2015, 0x82ff, + 0x090c, 0x0dc5, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730, + 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1a78, 0x19a5, 0x19a5, + 0x1a78, 0x19a5, 0x1a72, 0x1a78, 0x19a5, 0x1a15, 0x1a15, 0x1a15, + 0x1a78, 0x1a15, 0x1a78, 0x1a6f, 0x1a15, 0xc0fc, 0xa882, 0xab2c, + 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1a7a, 0x2c05, 0x908a, + 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1991, 0x198f, + 0x198f, 0x198f, 0x198f, 0x198f, 0x1995, 0x198f, 0x198f, 0x198f, + 0x198f, 0x198f, 0x1999, 0x198f, 0x198f, 0x198f, 0x198f, 0x198f, + 0x199d, 0x198f, 0x198f, 0x198f, 0x198f, 0x198f, 0x19a1, 0x080c, + 0x0dc5, 0xa774, 0xa678, 0x0804, 0x1a7a, 0xa78c, 0xa690, 0x0804, + 0x1a7a, 0xa7a4, 0xa6a8, 0x0804, 0x1a7a, 0xa7bc, 0xa6c0, 0x0804, + 0x1a7a, 0xa7d4, 0xa6d8, 0x0804, 0x1a7a, 0xa898, 0x901d, 0x1108, + 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x19cd, 0x19cd, 0x19cf, 0x19cd, 0x19cd, 0x19cd, + 0x19d9, 0x19cd, 0x19cd, 0x19cd, 0x19e3, 0x19cd, 0x19cd, 0x19cd, + 0x19ed, 0x19cd, 0x19cd, 0x19cd, 0x19f7, 0x19cd, 0x19cd, 0x19cd, + 0x1a01, 0x19cd, 0x19cd, 0x19cd, 0x1a0b, 0x080c, 0x0dc5, 0xa574, + 0xa478, 0x9d86, 0x0004, 0x0904, 0x1a7a, 0xa37c, 0xa280, 0x0804, + 0x1a7a, 0xa584, 0xa488, 0x9d86, 0x0004, 0x0904, 0x1a7a, 0xa38c, + 0xa290, 0x0804, 0x1a7a, 0xa594, 0xa498, 0x9d86, 0x0004, 0x0904, + 0x1a7a, 0xa39c, 0xa2a0, 0x0804, 0x1a7a, 0xa5a4, 0xa4a8, 0x9d86, + 0x0004, 0x0904, 0x1a7a, 0xa3ac, 0xa2b0, 0x0804, 0x1a7a, 0xa5b4, + 0xa4b8, 0x9d86, 0x0004, 0x0904, 0x1a7a, 0xa3bc, 0xa2c0, 0x0804, + 0x1a7a, 0xa5c4, 0xa4c8, 0x9d86, 0x0004, 0x0904, 0x1a7a, 0xa3cc, + 0xa2d0, 0x0804, 0x1a7a, 0xa5d4, 0xa4d8, 0x9d86, 0x0004, 0x0904, + 0x1a7a, 0xa3dc, 0xa2e0, 0x0804, 0x1a7a, 0xa898, 0x901d, 0x1108, + 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x1a3d, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, + 0x1a47, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a51, 0x1a3b, + 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a5b, 0x1a3b, 0x1a3b, 0x1a3b, + 0x1a3b, 0x1a3b, 0x1a65, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, + 0xa678, 0x9d86, 0x000c, 0x05b0, 0xa37c, 0xa280, 0x0498, 0xa584, + 0xa488, 0xa78c, 0xa690, 0x9d86, 0x000c, 0x0560, 0xa394, 0xa298, + 0x0448, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x000c, 0x0510, + 0xa3ac, 0xa2b0, 0x00f8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, + 0x000c, 0x01c0, 0xa3c4, 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, 0xa7d4, + 0xa6d8, 0x9d86, 0x000c, 0x0170, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, + 0x000e, 0x1130, 0x080c, 0x20a8, 0x1904, 0x194e, 0x900e, 0x0050, + 0x080c, 0x0dc5, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, + 0x080c, 0x20a8, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, + 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, + 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, + 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, + 0x080c, 0xb180, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, + 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, + 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xb180, 0x0005, 0x0126, + 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, + 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, + 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, + 0x0120, 0x080c, 0x1394, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, + 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1394, 0x00ce, + 0x2001, 0x0038, 0x080c, 0x1b92, 0x7930, 0x9186, 0x0040, 0x0160, + 0x9186, 0x0042, 0x190c, 0x0dc5, 0x2001, 0x001e, 0x8001, 0x1df0, + 0x8631, 0x1d40, 0x080c, 0x1ba1, 0x000e, 0x6022, 0x012e, 0x0005, + 0x080c, 0x1b8e, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, + 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, + 0x0004, 0x2001, 0xf000, 0x8001, 0x090c, 0x0dc5, 0x7aac, 0xd2ac, + 0x1dd0, 0x00fe, 0x080c, 0x7569, 0x1188, 0x2001, 0x0138, 0x2003, + 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, + 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7616, 0x0479, 0x0039, + 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, + 0x2071, 0x0200, 0x080c, 0x2c86, 0x2009, 0x003c, 0x080c, 0x2432, + 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, + 0x080c, 0x85f1, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, + 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, + 0x1322, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, + 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, + 0x080c, 0x7569, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, + 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, + 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, + 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, + 0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, + 0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, + 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x1611, 0x7930, 0x0005, + 0x2c08, 0x621c, 0x080c, 0x16bc, 0x7930, 0x0005, 0x8001, 0x1df0, + 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, + 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bff, 0x2001, 0x001e, + 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0dc5, 0x781f, 0x0202, 0x2001, + 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, + 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, + 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, + 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, + 0x0030, 0x080c, 0x1b98, 0x9186, 0x0040, 0x190c, 0x0dc5, 0x00d6, + 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, + 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, + 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, + 0x0007, 0x090c, 0x0dc5, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, + 0x0126, 0x2091, 0x2400, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x012e, + 0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904, + 0x1ca1, 0xa964, 0x9184, 0x0007, 0x0002, 0x1c1d, 0x1c8c, 0x1c34, + 0x1c36, 0x1c34, 0x1c74, 0x1c54, 0x1c43, 0x918c, 0x00ff, 0x9186, + 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0x9006, 0xa842, + 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x20eb, 0x0804, 0x1c9d, + 0x9186, 0x0048, 0x0904, 0x1c8c, 0x080c, 0x0dc5, 0x9184, 0x00ff, + 0x9086, 0x0013, 0x0904, 0x1c8c, 0x9184, 0x00ff, 0x9086, 0x001b, + 0x0904, 0x1c8c, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa890, + 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, + 0xa84a, 0xa988, 0x0804, 0x1c94, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x001e, 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, - 0xa988, 0x0804, 0x1c6b, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, - 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0xa890, 0xa842, 0xa83a, - 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa804, - 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20c7, 0x2005, - 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015, 0x1540, - 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0xa804, 0xa85a, 0x2040, 0xa064, - 0x9084, 0x000f, 0x9080, 0x20c7, 0x2005, 0xa812, 0xa988, 0x9006, - 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0xa988, - 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084, 0x000f, - 0x9080, 0x20c7, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd, 0xa87e, - 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c, 0x1eeb, - 0x00e6, 0x2071, 0x1a69, 0x7000, 0x9005, 0x1904, 0x1cdf, 0x7206, - 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b, 0x0004, - 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6, 0x2058, - 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200, 0x7803, - 0x0040, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x781a, - 0x78d7, 0x0000, 0x00fe, 0xa814, 0x2050, 0xa858, 0x2040, 0xa810, - 0x2060, 0xa064, 0x90ec, 0x000f, 0xa944, 0x791a, 0x7116, 0xa848, - 0x781e, 0x701a, 0x9006, 0x700e, 0x7012, 0x7004, 0xa940, 0xa838, - 0x9106, 0x1500, 0xa93c, 0xa834, 0x9106, 0x11e0, 0x0006, 0x0016, - 0xa938, 0xa834, 0x9105, 0x0118, 0x001e, 0x000e, 0x0098, 0x001e, - 0x000e, 0x8aff, 0x01c8, 0x0126, 0x2091, 0x8000, 0x2009, 0x0306, - 0x200b, 0x0808, 0x00d9, 0x0108, 0x00c9, 0x012e, 0x9006, 0x00ee, - 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34, 0x080c, 0x20e7, - 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80, 0x2009, - 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, 0x0005, 0x0076, 0x0066, - 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1e9e, 0x700c, - 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1e9d, 0x9705, - 0x0904, 0x1e9d, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, - 0x0002, 0x1e22, 0x1d61, 0x1d61, 0x1e22, 0x1e22, 0x1dff, 0x1e22, - 0x1d61, 0x1e06, 0x1db0, 0x1db0, 0x1e22, 0x1e22, 0x1e22, 0x1df9, - 0x1db0, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, - 0x0904, 0x1e2f, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, - 0x001b, 0x0002, 0x1d4d, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, - 0x1d51, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d55, 0x1d4b, - 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d59, 0x1d4b, 0x1d4b, 0x1d4b, - 0x1d4b, 0x1d4b, 0x1d5d, 0x080c, 0x0dc5, 0xa774, 0xa678, 0x0804, - 0x1e2f, 0xa78c, 0xa690, 0x0804, 0x1e2f, 0xa7a4, 0xa6a8, 0x0804, - 0x1e2f, 0xa7bc, 0xa6c0, 0x0804, 0x1e2f, 0xa7d4, 0xa6d8, 0x0804, - 0x1e2f, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, - 0x0002, 0x1d84, 0x1d84, 0x1d86, 0x1d84, 0x1d84, 0x1d84, 0x1d8c, - 0x1d84, 0x1d84, 0x1d84, 0x1d92, 0x1d84, 0x1d84, 0x1d84, 0x1d98, - 0x1d84, 0x1d84, 0x1d84, 0x1d9e, 0x1d84, 0x1d84, 0x1d84, 0x1da4, - 0x1d84, 0x1d84, 0x1d84, 0x1daa, 0x080c, 0x0dc5, 0xa574, 0xa478, - 0xa37c, 0xa280, 0x0804, 0x1e2f, 0xa584, 0xa488, 0xa38c, 0xa290, - 0x0804, 0x1e2f, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1e2f, - 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e2f, 0xa5b4, 0xa4b8, - 0xa3bc, 0xa2c0, 0x0804, 0x1e2f, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, - 0x0804, 0x1e2f, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1e2f, - 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, - 0x1dd3, 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, 0x1ddb, 0x1dd1, - 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, 0x1de3, 0x1dd1, 0x1dd1, 0x1dd1, - 0x1dd1, 0x1dd1, 0x1deb, 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, - 0x1df2, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, - 0xa280, 0x0804, 0x1e2f, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, - 0xa298, 0x0804, 0x1e2f, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, - 0xa2b0, 0x0804, 0x1e2f, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, - 0xa2c8, 0x04e8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, - 0x04b0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1518, 0x080c, - 0x207f, 0x1904, 0x1cfc, 0x900e, 0x0804, 0x1e9e, 0xab64, 0x939c, - 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060, 0x6004, - 0x9086, 0x0043, 0x00ce, 0x0904, 0x1db0, 0xab9c, 0x9016, 0xad8c, - 0xac90, 0xaf94, 0xae98, 0x0098, 0x9386, 0x0008, 0x0904, 0x1db0, - 0x080c, 0x0dc5, 0xa964, 0x918c, 0x00ff, 0x9186, 0x0013, 0x0904, - 0x1d61, 0x9186, 0x001b, 0x0904, 0x1db0, 0x080c, 0x0dc5, 0x2009, - 0x030f, 0x2104, 0xd0fc, 0x0538, 0x0066, 0x2009, 0x0306, 0x2134, - 0x200b, 0x4000, 0x2104, 0x9084, 0x0030, 0x15b8, 0x2031, 0x1000, - 0x2600, 0x9302, 0x928b, 0x0000, 0xa82e, 0xa932, 0x0278, 0x9105, - 0x0168, 0x2011, 0x0000, 0x2618, 0x2600, 0x9500, 0xa81e, 0x9481, - 0x0000, 0xa822, 0xa880, 0xc0fd, 0xa882, 0x0020, 0xa82f, 0x0000, - 0xa833, 0x0000, 0x006e, 0x7b12, 0x7a16, 0x7d02, 0x7c06, 0x7f0a, - 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002, 0xa83c, 0x9300, - 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300, 0x700e, 0x7010, - 0x9201, 0x7012, 0x080c, 0x207f, 0x0448, 0xd6b4, 0x0110, 0x200b, - 0x4040, 0x2031, 0x0080, 0x9584, 0x007f, 0x0108, 0x9632, 0x7124, - 0x7000, 0x9086, 0x0000, 0x1198, 0xc185, 0x7126, 0x2009, 0x0306, - 0x2104, 0xd0b4, 0x1904, 0x1e40, 0x200b, 0x4040, 0x2009, 0x1a83, - 0x2104, 0x8000, 0x0a04, 0x1e40, 0x200a, 0x0804, 0x1e40, 0xc18d, - 0x7126, 0xd184, 0x1d58, 0x0804, 0x1e40, 0x9006, 0x002e, 0x003e, - 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0dc5, 0x0026, - 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, 0x0000, - 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x0118, 0xa880, - 0xc0bd, 0xa882, 0x782c, 0xd0ac, 0x1de8, 0x080c, 0x1cef, 0x6020, - 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, - 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, - 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xccf3, 0x00ce, 0x2001, - 0x19f7, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c, 0x2409, - 0x080c, 0xac2b, 0x2011, 0x0000, 0x080c, 0xaac9, 0x080c, 0x9bd3, - 0x002e, 0x0804, 0x202f, 0x0126, 0x2091, 0x2400, 0xa858, 0x2040, - 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1ea7, 0x7000, - 0x0002, 0x202f, 0x1efd, 0x1f7d, 0x202d, 0x8001, 0x7002, 0x7027, - 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f4a, 0x080c, 0x1cf6, - 0x0904, 0x202f, 0x080c, 0x1cf6, 0x0804, 0x202f, 0x782b, 0x0004, - 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x1518, 0xa87c, - 0xc0f5, 0xa87e, 0x00f8, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x0016, - 0x7910, 0xa82c, 0x9100, 0xa82e, 0x7914, 0xa830, 0x9101, 0xa832, - 0x001e, 0x7810, 0x931a, 0x7814, 0x9213, 0x7800, 0xa81e, 0x7804, - 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x209a, 0xa880, - 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, 0xa812, - 0x7003, 0x0000, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, - 0x0804, 0x202f, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, - 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, - 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0dc5, 0x7820, 0xd0bc, - 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016, - 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984, - 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008, 0x7003, - 0x0000, 0x080c, 0x1cef, 0x0804, 0x202f, 0x8001, 0x7002, 0x7024, - 0x8004, 0x7026, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, 0x1ef0, - 0xd19c, 0x1904, 0x202b, 0x8aff, 0x0904, 0x202f, 0x080c, 0x1cf6, - 0x0804, 0x202f, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, 0x209a, - 0xdd9c, 0x1904, 0x1fea, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, - 0x9082, 0x001b, 0x0002, 0x1fbe, 0x1fbe, 0x1fc0, 0x1fbe, 0x1fbe, - 0x1fbe, 0x1fc6, 0x1fbe, 0x1fbe, 0x1fbe, 0x1fcc, 0x1fbe, 0x1fbe, - 0x1fbe, 0x1fd2, 0x1fbe, 0x1fbe, 0x1fbe, 0x1fd8, 0x1fbe, 0x1fbe, - 0x1fbe, 0x1fde, 0x1fbe, 0x1fbe, 0x1fbe, 0x1fe4, 0x080c, 0x0dc5, - 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1f1f, 0xa08c, 0x931a, - 0xa090, 0x9213, 0x0804, 0x1f1f, 0xa09c, 0x931a, 0xa0a0, 0x9213, - 0x0804, 0x1f1f, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f1f, - 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f1f, 0xa0cc, 0x931a, - 0xa0d0, 0x9213, 0x0804, 0x1f1f, 0xa0dc, 0x931a, 0xa0e0, 0x9213, - 0x0804, 0x1f1f, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, - 0x001b, 0x0002, 0x200d, 0x200b, 0x200b, 0x200b, 0x200b, 0x200b, - 0x2013, 0x200b, 0x200b, 0x200b, 0x200b, 0x200b, 0x2019, 0x200b, - 0x200b, 0x200b, 0x200b, 0x200b, 0x201f, 0x200b, 0x200b, 0x200b, - 0x200b, 0x200b, 0x2025, 0x080c, 0x0dc5, 0xa07c, 0x931a, 0xa080, - 0x9213, 0x0804, 0x1f1f, 0xa094, 0x931a, 0xa098, 0x9213, 0x0804, - 0x1f1f, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f1f, 0xa0c4, - 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1f1f, 0xa0dc, 0x931a, 0xa0e0, - 0x9213, 0x0804, 0x1f1f, 0x0804, 0x1f1b, 0x080c, 0x0dc5, 0x012e, - 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a69, 0x7000, 0x9086, 0x0000, - 0x0904, 0x207a, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, - 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, - 0xf0a0, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5, 0x0016, - 0x2009, 0x0040, 0x080c, 0x2409, 0x001e, 0x2001, 0x020c, 0x2102, - 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, - 0x2009, 0x0040, 0x080c, 0x2409, 0x782c, 0xd0fc, 0x09a8, 0x080c, - 0x1eeb, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, 0x782c, - 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2409, 0x782b, 0x0002, - 0x7003, 0x0000, 0x080c, 0x1cef, 0x00ee, 0x00fe, 0x0005, 0xa880, - 0xd0fc, 0x11a8, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, - 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, - 0x9080, 0x20c7, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x8a51, 0x0005, - 0x2050, 0x0005, 0xa880, 0xd0fc, 0x11b8, 0x8a50, 0x8c61, 0x2c05, - 0x9005, 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005, 0x1108, - 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080, 0x20d7, - 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x0005, 0x0000, 0x001d, 0x0021, - 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, - 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, - 0x20ba, 0x20b6, 0x20ba, 0x20ba, 0x20c4, 0x0000, 0x20ba, 0x20c1, - 0x20c1, 0x20be, 0x20c1, 0x20c1, 0x0000, 0x20c4, 0x20c1, 0x0000, - 0x20bc, 0x20bc, 0x0000, 0x20bc, 0x20c4, 0x0000, 0x20bc, 0x20c2, - 0x20c2, 0x20c2, 0x0000, 0x20c2, 0x0000, 0x20c4, 0x20c2, 0x00c6, - 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x22c6, - 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, - 0x1118, 0x2061, 0x20c2, 0x00d0, 0x9de0, 0x20c7, 0x9d86, 0x0007, - 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, - 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, - 0x22c6, 0xa004, 0x9045, 0x0904, 0x22c6, 0x08d8, 0x2c05, 0x9005, - 0x0904, 0x21ae, 0xdd9c, 0x1904, 0x216a, 0x908a, 0x0036, 0x1a0c, - 0x0dc5, 0x9082, 0x001b, 0x0002, 0x213f, 0x213f, 0x2141, 0x213f, - 0x213f, 0x213f, 0x2147, 0x213f, 0x213f, 0x213f, 0x214d, 0x213f, - 0x213f, 0x213f, 0x2153, 0x213f, 0x213f, 0x213f, 0x2159, 0x213f, - 0x213f, 0x213f, 0x215f, 0x213f, 0x213f, 0x213f, 0x2165, 0x080c, - 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21a4, 0xa08c, - 0x9422, 0xa090, 0x931b, 0x0804, 0x21a4, 0xa09c, 0x9422, 0xa0a0, - 0x931b, 0x0804, 0x21a4, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, - 0x21a4, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21a4, 0xa0cc, - 0x9422, 0xa0d0, 0x931b, 0x0804, 0x21a4, 0xa0dc, 0x9422, 0xa0e0, - 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, - 0x0002, 0x218c, 0x218a, 0x218a, 0x218a, 0x218a, 0x218a, 0x2191, - 0x218a, 0x218a, 0x218a, 0x218a, 0x218a, 0x2196, 0x218a, 0x218a, - 0x218a, 0x218a, 0x218a, 0x219b, 0x218a, 0x218a, 0x218a, 0x218a, - 0x218a, 0x21a0, 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, - 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, - 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, - 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, - 0x8a51, 0x0904, 0x22c6, 0x8c60, 0x0804, 0x2116, 0xa004, 0x9045, - 0x0904, 0x22c6, 0x0804, 0x20f1, 0x8a51, 0x0904, 0x22c6, 0x8c60, - 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22c6, 0xa064, - 0x90ec, 0x000f, 0x9de0, 0x20c7, 0x2c05, 0x2060, 0xa880, 0xc0fc, - 0xa882, 0x0804, 0x22bb, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, - 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2258, 0x9082, 0x001b, - 0x0002, 0x21f4, 0x21f4, 0x21f6, 0x21f4, 0x21f4, 0x21f4, 0x2204, - 0x21f4, 0x21f4, 0x21f4, 0x2212, 0x21f4, 0x21f4, 0x21f4, 0x2220, - 0x21f4, 0x21f4, 0x21f4, 0x222e, 0x21f4, 0x21f4, 0x21f4, 0x223c, - 0x21f4, 0x21f4, 0x21f4, 0x224a, 0x080c, 0x0dc5, 0xa17c, 0x2400, - 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa074, 0x9420, - 0xa078, 0x9319, 0x0804, 0x22b6, 0xa18c, 0x2400, 0x9122, 0xa190, + 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20f0, + 0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015, + 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa804, 0xa85a, 0x2040, + 0xa064, 0x9084, 0x000f, 0x9080, 0x20f0, 0x2005, 0xa812, 0xa988, + 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1ece, + 0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084, + 0x000f, 0x9080, 0x20f0, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd, + 0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c, + 0x1f14, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9005, 0x1904, 0x1d08, + 0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b, + 0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6, + 0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200, + 0x7803, 0x0040, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, + 0x781a, 0x78d7, 0x0000, 0x00fe, 0xa814, 0x2050, 0xa858, 0x2040, + 0xa810, 0x2060, 0xa064, 0x90ec, 0x000f, 0xa944, 0x791a, 0x7116, + 0xa848, 0x781e, 0x701a, 0x9006, 0x700e, 0x7012, 0x7004, 0xa940, + 0xa838, 0x9106, 0x1500, 0xa93c, 0xa834, 0x9106, 0x11e0, 0x0006, + 0x0016, 0xa938, 0xa834, 0x9105, 0x0118, 0x001e, 0x000e, 0x0098, + 0x001e, 0x000e, 0x8aff, 0x01c8, 0x0126, 0x2091, 0x8000, 0x2009, + 0x0306, 0x200b, 0x0808, 0x00d9, 0x0108, 0x00c9, 0x012e, 0x9006, + 0x00ee, 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34, 0x080c, + 0x2110, 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80, + 0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, 0x0005, 0x0076, + 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1ec7, + 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1ec6, + 0x9705, 0x0904, 0x1ec6, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, + 0x2d00, 0x0002, 0x1e4b, 0x1d8a, 0x1d8a, 0x1e4b, 0x1e4b, 0x1e28, + 0x1e4b, 0x1d8a, 0x1e2f, 0x1dd9, 0x1dd9, 0x1e4b, 0x1e4b, 0x1e4b, + 0x1e22, 0x1dd9, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, + 0xdd9c, 0x0904, 0x1e58, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, + 0x9082, 0x001b, 0x0002, 0x1d76, 0x1d74, 0x1d74, 0x1d74, 0x1d74, + 0x1d74, 0x1d7a, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d7e, + 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d82, 0x1d74, 0x1d74, + 0x1d74, 0x1d74, 0x1d74, 0x1d86, 0x080c, 0x0dc5, 0xa774, 0xa678, + 0x0804, 0x1e58, 0xa78c, 0xa690, 0x0804, 0x1e58, 0xa7a4, 0xa6a8, + 0x0804, 0x1e58, 0xa7bc, 0xa6c0, 0x0804, 0x1e58, 0xa7d4, 0xa6d8, + 0x0804, 0x1e58, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x1dad, 0x1dad, 0x1daf, 0x1dad, 0x1dad, 0x1dad, + 0x1db5, 0x1dad, 0x1dad, 0x1dad, 0x1dbb, 0x1dad, 0x1dad, 0x1dad, + 0x1dc1, 0x1dad, 0x1dad, 0x1dad, 0x1dc7, 0x1dad, 0x1dad, 0x1dad, + 0x1dcd, 0x1dad, 0x1dad, 0x1dad, 0x1dd3, 0x080c, 0x0dc5, 0xa574, + 0xa478, 0xa37c, 0xa280, 0x0804, 0x1e58, 0xa584, 0xa488, 0xa38c, + 0xa290, 0x0804, 0x1e58, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, + 0x1e58, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e58, 0xa5b4, + 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1e58, 0xa5c4, 0xa4c8, 0xa3cc, + 0xa2d0, 0x0804, 0x1e58, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, + 0x1e58, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, + 0x0002, 0x1dfc, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1e04, + 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1e0c, 0x1dfa, 0x1dfa, + 0x1dfa, 0x1dfa, 0x1dfa, 0x1e14, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, + 0x1dfa, 0x1e1b, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678, + 0xa37c, 0xa280, 0x0804, 0x1e58, 0xa584, 0xa488, 0xa78c, 0xa690, + 0xa394, 0xa298, 0x0804, 0x1e58, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, + 0xa3ac, 0xa2b0, 0x0804, 0x1e58, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, + 0xa3c4, 0xa2c8, 0x04e8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, + 0xa2e0, 0x04b0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1518, + 0x080c, 0x20a8, 0x1904, 0x1d25, 0x900e, 0x0804, 0x1ec7, 0xab64, + 0x939c, 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060, + 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1dd9, 0xab9c, 0x9016, + 0xad8c, 0xac90, 0xaf94, 0xae98, 0x0098, 0x9386, 0x0008, 0x0904, + 0x1dd9, 0x080c, 0x0dc5, 0xa964, 0x918c, 0x00ff, 0x9186, 0x0013, + 0x0904, 0x1d8a, 0x9186, 0x001b, 0x0904, 0x1dd9, 0x080c, 0x0dc5, + 0x2009, 0x030f, 0x2104, 0xd0fc, 0x0538, 0x0066, 0x2009, 0x0306, + 0x2134, 0x200b, 0x4000, 0x2104, 0x9084, 0x0030, 0x15b8, 0x2031, + 0x1000, 0x2600, 0x9302, 0x928b, 0x0000, 0xa82e, 0xa932, 0x0278, + 0x9105, 0x0168, 0x2011, 0x0000, 0x2618, 0x2600, 0x9500, 0xa81e, + 0x9481, 0x0000, 0xa822, 0xa880, 0xc0fd, 0xa882, 0x0020, 0xa82f, + 0x0000, 0xa833, 0x0000, 0x006e, 0x7b12, 0x7a16, 0x7d02, 0x7c06, + 0x7f0a, 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002, 0xa83c, + 0x9300, 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300, 0x700e, + 0x7010, 0x9201, 0x7012, 0x080c, 0x20a8, 0x0448, 0xd6b4, 0x0110, + 0x200b, 0x4040, 0x2031, 0x0080, 0x9584, 0x007f, 0x0108, 0x9632, + 0x7124, 0x7000, 0x9086, 0x0000, 0x1198, 0xc185, 0x7126, 0x2009, + 0x0306, 0x2104, 0xd0b4, 0x1904, 0x1e69, 0x200b, 0x4040, 0x2009, + 0x1a84, 0x2104, 0x8000, 0x0a04, 0x1e69, 0x200a, 0x0804, 0x1e69, + 0xc18d, 0x7126, 0xd184, 0x1d58, 0x0804, 0x1e69, 0x9006, 0x002e, + 0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0dc5, + 0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, + 0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xce56, 0x0118, + 0xa880, 0xc0bd, 0xa882, 0x782c, 0xd0ac, 0x1de8, 0x080c, 0x1d18, + 0x6020, 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001, + 0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, + 0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xca71, 0x00ce, + 0x2001, 0x19f8, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c, + 0x2432, 0x080c, 0xaa59, 0x2011, 0x0000, 0x080c, 0xa8f7, 0x080c, + 0x9a0f, 0x002e, 0x0804, 0x2058, 0x0126, 0x2091, 0x2400, 0xa858, + 0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1ed0, + 0x7000, 0x0002, 0x2058, 0x1f26, 0x1fa6, 0x2056, 0x8001, 0x7002, + 0x7027, 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f73, 0x080c, + 0x1d1f, 0x0904, 0x2058, 0x080c, 0x1d1f, 0x0804, 0x2058, 0x782b, + 0x0004, 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x1518, + 0xa87c, 0xc0f5, 0xa87e, 0x00f8, 0x0026, 0x0036, 0xab3c, 0xaa40, + 0x0016, 0x7910, 0xa82c, 0x9100, 0xa82e, 0x7914, 0xa830, 0x9101, + 0xa832, 0x001e, 0x7810, 0x931a, 0x7814, 0x9213, 0x7800, 0xa81e, + 0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x20c3, + 0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, + 0xa812, 0x7003, 0x0000, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027, + 0x0000, 0x0804, 0x2058, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, + 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, + 0x7816, 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0dc5, 0x7820, + 0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, + 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, + 0x1984, 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008, + 0x7003, 0x0000, 0x080c, 0x1d18, 0x0804, 0x2058, 0x8001, 0x7002, + 0x7024, 0x8004, 0x7026, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, + 0x1f19, 0xd19c, 0x1904, 0x2054, 0x8aff, 0x0904, 0x2058, 0x080c, + 0x1d1f, 0x0804, 0x2058, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, + 0x20c3, 0xdd9c, 0x1904, 0x2013, 0x2c05, 0x908a, 0x0036, 0x1a0c, + 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1fe7, 0x1fe7, 0x1fe9, 0x1fe7, + 0x1fe7, 0x1fe7, 0x1fef, 0x1fe7, 0x1fe7, 0x1fe7, 0x1ff5, 0x1fe7, + 0x1fe7, 0x1fe7, 0x1ffb, 0x1fe7, 0x1fe7, 0x1fe7, 0x2001, 0x1fe7, + 0x1fe7, 0x1fe7, 0x2007, 0x1fe7, 0x1fe7, 0x1fe7, 0x200d, 0x080c, + 0x0dc5, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1f48, 0xa08c, + 0x931a, 0xa090, 0x9213, 0x0804, 0x1f48, 0xa09c, 0x931a, 0xa0a0, + 0x9213, 0x0804, 0x1f48, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, + 0x1f48, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f48, 0xa0cc, + 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1f48, 0xa0dc, 0x931a, 0xa0e0, + 0x9213, 0x0804, 0x1f48, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, + 0x9082, 0x001b, 0x0002, 0x2036, 0x2034, 0x2034, 0x2034, 0x2034, + 0x2034, 0x203c, 0x2034, 0x2034, 0x2034, 0x2034, 0x2034, 0x2042, + 0x2034, 0x2034, 0x2034, 0x2034, 0x2034, 0x2048, 0x2034, 0x2034, + 0x2034, 0x2034, 0x2034, 0x204e, 0x080c, 0x0dc5, 0xa07c, 0x931a, + 0xa080, 0x9213, 0x0804, 0x1f48, 0xa094, 0x931a, 0xa098, 0x9213, + 0x0804, 0x1f48, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f48, + 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1f48, 0xa0dc, 0x931a, + 0xa0e0, 0x9213, 0x0804, 0x1f48, 0x0804, 0x1f44, 0x080c, 0x0dc5, + 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9086, + 0x0000, 0x0904, 0x20a3, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, + 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, + 0x080c, 0xee1b, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5, + 0x0016, 0x2009, 0x0040, 0x080c, 0x2432, 0x001e, 0x2001, 0x020c, + 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, + 0x1120, 0x2009, 0x0040, 0x080c, 0x2432, 0x782c, 0xd0fc, 0x09a8, + 0x080c, 0x1f14, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, + 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2432, 0x782b, + 0x0002, 0x7003, 0x0000, 0x080c, 0x1d18, 0x00ee, 0x00fe, 0x0005, + 0xa880, 0xd0fc, 0x11a8, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, + 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, + 0x000f, 0x9080, 0x20f0, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x8a51, + 0x0005, 0x2050, 0x0005, 0xa880, 0xd0fc, 0x11b8, 0x8a50, 0x8c61, + 0x2c05, 0x9005, 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005, + 0x1108, 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080, + 0x2100, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x0005, 0x0000, 0x001d, + 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, + 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, + 0x0000, 0x20e3, 0x20df, 0x20e3, 0x20e3, 0x20ed, 0x0000, 0x20e3, + 0x20ea, 0x20ea, 0x20e7, 0x20ea, 0x20ea, 0x0000, 0x20ed, 0x20ea, + 0x0000, 0x20e5, 0x20e5, 0x0000, 0x20e5, 0x20ed, 0x0000, 0x20e5, + 0x20eb, 0x20eb, 0x20eb, 0x0000, 0x20eb, 0x0000, 0x20ed, 0x20eb, + 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, + 0x22ef, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, + 0x0008, 0x1118, 0x2061, 0x20eb, 0x00d0, 0x9de0, 0x20f0, 0x9d86, + 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, + 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, + 0x0804, 0x22ef, 0xa004, 0x9045, 0x0904, 0x22ef, 0x08d8, 0x2c05, + 0x9005, 0x0904, 0x21d7, 0xdd9c, 0x1904, 0x2193, 0x908a, 0x0036, + 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x2168, 0x2168, 0x216a, + 0x2168, 0x2168, 0x2168, 0x2170, 0x2168, 0x2168, 0x2168, 0x2176, + 0x2168, 0x2168, 0x2168, 0x217c, 0x2168, 0x2168, 0x2168, 0x2182, + 0x2168, 0x2168, 0x2168, 0x2188, 0x2168, 0x2168, 0x2168, 0x218e, + 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21cd, + 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x21cd, 0xa09c, 0x9422, + 0xa0a0, 0x931b, 0x0804, 0x21cd, 0xa0ac, 0x9422, 0xa0b0, 0x931b, + 0x0804, 0x21cd, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21cd, + 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x21cd, 0xa0dc, 0x9422, + 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x21b5, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21b3, + 0x21ba, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21bf, 0x21b3, + 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21c4, 0x21b3, 0x21b3, 0x21b3, + 0x21b3, 0x21b3, 0x21c9, 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, + 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, + 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, + 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, + 0x0160, 0x8a51, 0x0904, 0x22ef, 0x8c60, 0x0804, 0x213f, 0xa004, + 0x9045, 0x0904, 0x22ef, 0x0804, 0x211a, 0x8a51, 0x0904, 0x22ef, + 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22ef, + 0xa064, 0x90ec, 0x000f, 0x9de0, 0x20f0, 0x2c05, 0x2060, 0xa880, + 0xc0fc, 0xa882, 0x0804, 0x22e4, 0x2c05, 0x8422, 0x8420, 0x831a, + 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2281, 0x9082, + 0x001b, 0x0002, 0x221d, 0x221d, 0x221f, 0x221d, 0x221d, 0x221d, + 0x222d, 0x221d, 0x221d, 0x221d, 0x223b, 0x221d, 0x221d, 0x221d, + 0x2249, 0x221d, 0x221d, 0x221d, 0x2257, 0x221d, 0x221d, 0x221d, + 0x2265, 0x221d, 0x221d, 0x221d, 0x2273, 0x080c, 0x0dc5, 0xa17c, + 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa074, + 0x9420, 0xa078, 0x9319, 0x0804, 0x22df, 0xa18c, 0x2400, 0x9122, + 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, + 0x9319, 0x0804, 0x22df, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, + 0x911b, 0x0a0c, 0x0dc5, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, + 0x22df, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, + 0x0dc5, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x22df, 0xa1bc, + 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4, + 0x9420, 0xa0b8, 0x9319, 0x0804, 0x22df, 0xa1cc, 0x2400, 0x9122, + 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0c4, 0x9420, 0xa0c8, + 0x9319, 0x0804, 0x22df, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, + 0x911b, 0x0a0c, 0x0dc5, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, + 0x22df, 0x9082, 0x001b, 0x0002, 0x229f, 0x229d, 0x229d, 0x229d, + 0x229d, 0x229d, 0x22ac, 0x229d, 0x229d, 0x229d, 0x229d, 0x229d, + 0x22b9, 0x229d, 0x229d, 0x229d, 0x229d, 0x229d, 0x22c6, 0x229d, + 0x229d, 0x229d, 0x229d, 0x229d, 0x22d3, 0x080c, 0x0dc5, 0xa17c, + 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa06c, + 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, 0x9319, - 0x0804, 0x22b6, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, - 0x0a0c, 0x0dc5, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x22b6, - 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, - 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x22b6, 0xa1bc, 0x2400, - 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4, 0x9420, - 0xa0b8, 0x9319, 0x0804, 0x22b6, 0xa1cc, 0x2400, 0x9122, 0xa1d0, - 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0c4, 0x9420, 0xa0c8, 0x9319, - 0x0804, 0x22b6, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, - 0x0a0c, 0x0dc5, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x22b6, - 0x9082, 0x001b, 0x0002, 0x2276, 0x2274, 0x2274, 0x2274, 0x2274, - 0x2274, 0x2283, 0x2274, 0x2274, 0x2274, 0x2274, 0x2274, 0x2290, - 0x2274, 0x2274, 0x2274, 0x2274, 0x2274, 0x229d, 0x2274, 0x2274, - 0x2274, 0x2274, 0x2274, 0x22aa, 0x080c, 0x0dc5, 0xa17c, 0x2400, - 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa06c, 0x9420, - 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, - 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, - 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, - 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, - 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4, 0x9420, 0xa0b8, - 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, - 0x0a0c, 0x0dc5, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, - 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, - 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, - 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, - 0x190c, 0x0dbe, 0x9084, 0x0007, 0x0002, 0x22e7, 0x1eeb, 0x22e7, - 0x22dd, 0x22e0, 0x22e3, 0x22e0, 0x22e3, 0x080c, 0x1eeb, 0x0005, - 0x080c, 0x11b2, 0x0005, 0x080c, 0x1eeb, 0x080c, 0x11b2, 0x0005, - 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, - 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, - 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, - 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, - 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2406, 0x7900, 0xd1dc, 0x1118, - 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x232e, 0x2326, - 0x8081, 0x2326, 0x2328, 0x2328, 0x2328, 0x2328, 0x8067, 0x2326, - 0x232a, 0x2326, 0x2328, 0x2326, 0x2328, 0x2326, 0x080c, 0x0dc5, - 0x0031, 0x0020, 0x080c, 0x8067, 0x080c, 0x8081, 0x0005, 0x0006, - 0x0016, 0x0026, 0x080c, 0xf0a0, 0x7930, 0x9184, 0x0003, 0x01c0, - 0x2001, 0x19f7, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133, 0x2004, - 0x9005, 0x090c, 0x0dc5, 0x00c6, 0x2001, 0x19f7, 0x2064, 0x080c, - 0xccf3, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2409, 0x00d0, - 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, - 0x7637, 0x1138, 0x080c, 0x7932, 0x080c, 0x612e, 0x080c, 0x7563, - 0x0010, 0x080c, 0x5fed, 0x080c, 0x8130, 0x0041, 0x0018, 0x9184, - 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, - 0x0046, 0x0056, 0x2071, 0x1a65, 0x080c, 0x1ad9, 0x005e, 0x004e, - 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, - 0x7128, 0x2001, 0x196f, 0x2102, 0x2001, 0x1977, 0x2102, 0x2001, - 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, - 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, - 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, - 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, - 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, - 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, - 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, - 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, - 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, - 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, - 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, - 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, - 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, - 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, - 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, - 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, - 0x0dbe, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, - 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, - 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, - 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c67, 0x080c, - 0x2b82, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, - 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084, 0xb17f, - 0x9085, 0x2000, 0x6052, 0x2009, 0x199d, 0x2011, 0x199e, 0x6358, - 0x939c, 0x38f0, 0x2320, 0x080c, 0x2bc6, 0x1238, 0x939d, 0x4003, - 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, - 0x8603, 0x230a, 0x2412, 0x9006, 0x080c, 0x2bb1, 0x9006, 0x080c, - 0x2b94, 0x20a9, 0x0012, 0x1d04, 0x245b, 0x2091, 0x6000, 0x1f04, - 0x245b, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, - 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28ac, 0x2009, - 0x00ef, 0x6132, 0x6136, 0x080c, 0x28bc, 0x60e7, 0x0000, 0x61ea, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1110, 0x2001, - 0x0008, 0x60e2, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, - 0x602f, 0x0000, 0x6007, 0x349f, 0x60bb, 0x0000, 0x20a9, 0x0018, - 0x60bf, 0x0000, 0x1f04, 0x2490, 0x60bb, 0x0000, 0x60bf, 0x0108, - 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, - 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, - 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, - 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, - 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001, 0x0005, - 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x0066, - 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, 0x1138, 0x6020, - 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, 0x9184, 0x5e2c, - 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284, 0x0007, - 0x0082, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0d70, - 0x0c98, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e, 0x0d30, - 0x0c58, 0x2513, 0x24f9, 0x24fc, 0x24ff, 0x2504, 0x2506, 0x250a, - 0x250e, 0x080c, 0x93e2, 0x00b8, 0x080c, 0x94b1, 0x00a0, 0x080c, - 0x94b1, 0x080c, 0x93e2, 0x0078, 0x0099, 0x0068, 0x080c, 0x93e2, - 0x0079, 0x0048, 0x080c, 0x94b1, 0x0059, 0x0028, 0x080c, 0x94b1, - 0x080c, 0x93e2, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, - 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x2784, - 0xd1f4, 0x190c, 0x0dbe, 0x080c, 0x7637, 0x0904, 0x256e, 0x080c, - 0xd7e3, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024, 0x9084, - 0x1800, 0x0550, 0x080c, 0x765a, 0x0118, 0x080c, 0x7648, 0x1520, - 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xd7e3, 0x0168, 0x080c, - 0x765a, 0x1150, 0x2001, 0x19a8, 0x2003, 0x0001, 0x6027, 0x1800, - 0x080c, 0x74b2, 0x0804, 0x2787, 0x70a4, 0x9005, 0x1150, 0x70a7, - 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x768b, 0x00de, 0x1904, - 0x2787, 0x080c, 0x793c, 0x0428, 0x080c, 0x765a, 0x1590, 0x6024, - 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x793c, 0x080c, 0x7932, - 0x080c, 0x612e, 0x080c, 0x7563, 0x0804, 0x2784, 0xd1ac, 0x1508, - 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, - 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, 0x7818, 0x0804, - 0x2784, 0x080c, 0x7937, 0x0048, 0x2001, 0x197d, 0x2003, 0x0002, - 0x0020, 0x080c, 0x7774, 0x0804, 0x2784, 0x080c, 0x78ba, 0x0804, - 0x2784, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x27e1, 0xd2b4, - 0x1904, 0x27f4, 0x0000, 0xd1ac, 0x0904, 0x2699, 0x0036, 0x6328, - 0xc3bc, 0x632a, 0x003e, 0x080c, 0x7637, 0x11c0, 0x6027, 0x0020, - 0x0006, 0x0026, 0x0036, 0x080c, 0x7651, 0x1158, 0x080c, 0x7932, - 0x080c, 0x612e, 0x080c, 0x7563, 0x003e, 0x002e, 0x000e, 0x00ae, - 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x760f, 0x0016, 0x0046, - 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, - 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, 0x7038, - 0xd084, 0x0190, 0x080c, 0xd7e3, 0x1118, 0x9186, 0xf800, 0x1160, - 0x7048, 0xd084, 0x1148, 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, - 0x8016, 0x080c, 0x4c44, 0x003e, 0x080c, 0xd7dc, 0x1904, 0x2676, - 0x9196, 0xff00, 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, - 0x0110, 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x33aa, - 0x0128, 0xc18d, 0x7132, 0x080c, 0x6a9b, 0x1510, 0x6240, 0x9294, - 0x0010, 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, - 0x7030, 0xd08c, 0x0904, 0x2676, 0x7038, 0xd08c, 0x1140, 0x2001, - 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2676, 0xc1ad, 0x2102, 0x0036, - 0x73d8, 0x2011, 0x8013, 0x080c, 0x4c44, 0x003e, 0x0804, 0x2676, - 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, - 0x2676, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, - 0x4c44, 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, - 0xd1a4, 0x01f0, 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, - 0x8a50, 0x2019, 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xeba1, - 0x00ce, 0x9484, 0x00ff, 0x9080, 0x33b6, 0x200d, 0x918c, 0xff00, - 0x810f, 0x2120, 0x9006, 0x2009, 0x000e, 0x080c, 0xec31, 0x001e, - 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x321b, 0x001e, - 0x00a8, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6724, - 0x1140, 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, - 0x6148, 0x8108, 0x1f04, 0x2666, 0x00be, 0x015e, 0x00ce, 0x004e, - 0x080c, 0xb244, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, - 0x9296, 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, - 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, - 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, 0x2003, 0x0000, 0x6027, - 0x0020, 0xd194, 0x0904, 0x2784, 0x0016, 0x6220, 0xd2b4, 0x0904, - 0x2721, 0x080c, 0x88c3, 0x080c, 0xa6e9, 0x6027, 0x0004, 0x00f6, - 0x2019, 0x19f1, 0x2304, 0x907d, 0x0904, 0x26f0, 0x7804, 0x9086, - 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, - 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, - 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, - 0x080c, 0x2d49, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, - 0x080c, 0x2c42, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, - 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x080c, 0x99a5, 0x080c, - 0x9ab1, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xb2d3, - 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, - 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, - 0x080c, 0x2d49, 0x00de, 0x00c6, 0x2061, 0x19e8, 0x6028, 0x080c, - 0xd7e3, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, - 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0xa6c5, 0x0804, 0x2783, - 0x2061, 0x0100, 0x62c0, 0x080c, 0xb0ca, 0x2019, 0x19f1, 0x2304, - 0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xb352, 0x00ce, 0x0804, - 0x2783, 0xd2bc, 0x0904, 0x276a, 0x080c, 0x88d0, 0x6014, 0x9084, - 0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, - 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d49, 0x00de, - 0x00c6, 0x2061, 0x19e8, 0x6044, 0x080c, 0xd7e3, 0x0120, 0x909a, - 0x0003, 0x1658, 0x0018, 0x909a, 0x00c8, 0x1638, 0x8000, 0x6046, - 0x603c, 0x00ce, 0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, 0x88c8, - 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, - 0x1984, 0x918d, 0x0012, 0x6116, 0x0430, 0x9080, 0x0008, 0x2004, - 0x9086, 0x0009, 0x0d98, 0x6114, 0x918c, 0x1984, 0x918d, 0x0016, - 0x6116, 0x00c8, 0x6027, 0x0004, 0x00b0, 0x0036, 0x2019, 0x0001, - 0x080c, 0xaa49, 0x003e, 0x2019, 0x19f7, 0x2304, 0x9065, 0x0150, - 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f, - 0x080c, 0xb352, 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27dc, 0x7038, - 0xd0ac, 0x1538, 0x0016, 0x0156, 0x6027, 0x0008, 0x080c, 0x2d73, - 0x20a9, 0x0028, 0xa001, 0x1f04, 0x2792, 0x6150, 0x9185, 0x1400, - 0x6052, 0x20a9, 0x0366, 0x1d04, 0x279b, 0x080c, 0x88f7, 0x6020, - 0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x04a0, - 0x080c, 0x2c29, 0x1f04, 0x279b, 0x015e, 0x6152, 0x001e, 0x6027, - 0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xb244, 0x60e3, - 0x0000, 0x080c, 0xf07f, 0x080c, 0xf09a, 0x080c, 0x57d9, 0xd0fc, - 0x1138, 0x080c, 0xd7dc, 0x1120, 0x9085, 0x0001, 0x080c, 0x767b, - 0x9006, 0x080c, 0x2d39, 0x2009, 0x0002, 0x080c, 0x2c67, 0x00e6, - 0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0ea3, 0x00ee, 0x6027, - 0x0008, 0x080c, 0x0ba0, 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, - 0x0005, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0904, - 0x259b, 0x0016, 0x2009, 0x27ed, 0x00d0, 0x2001, 0x188b, 0x200c, - 0xc184, 0x2102, 0x001e, 0x0c40, 0x0016, 0x2001, 0x188b, 0x200c, - 0xd194, 0x001e, 0x0904, 0x259b, 0x0016, 0x2009, 0x2800, 0x0038, - 0x2001, 0x188b, 0x200c, 0xc194, 0x2102, 0x001e, 0x08a8, 0x6028, - 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003, - 0xffff, 0x6043, 0x0001, 0x080c, 0x2c61, 0x6027, 0x0080, 0x6017, - 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016, 0x0026, 0x0036, - 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x71d0, - 0x70d2, 0x9116, 0x0904, 0x286b, 0x81ff, 0x01a0, 0x2009, 0x0000, - 0x080c, 0x2c67, 0x2011, 0x8011, 0x2019, 0x010e, 0x231c, 0x939e, - 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, 0x0000, 0x080c, - 0x4c44, 0x0448, 0x2001, 0x19a9, 0x200c, 0x81ff, 0x1140, 0x2001, - 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008, 0x2118, - 0x2011, 0x8012, 0x080c, 0x4c44, 0x080c, 0x0ea3, 0x080c, 0x57d9, - 0xd0fc, 0x1188, 0x080c, 0xd7dc, 0x1170, 0x00c6, 0x080c, 0x2907, - 0x080c, 0xa9b0, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, - 0x080c, 0x321b, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, - 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, - 0xff00, 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, - 0x01e8, 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, - 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, - 0x1820, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, - 0x2500, 0x080c, 0x83a5, 0x0048, 0x9584, 0x00ff, 0x9080, 0x33b6, - 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x33b6, - 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, - 0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, - 0x1f04, 0x28b7, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, - 0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, - 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, - 0x000f, 0x9080, 0xf880, 0x2005, 0x6856, 0x8211, 0x1f04, 0x28cc, - 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, - 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, - 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, - 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, - 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x28fc, 0x680f, - 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, - 0x57d5, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, - 0x2009, 0x002e, 0x080c, 0xec31, 0x004e, 0x0005, 0x00f6, 0x0016, - 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2973, 0x080c, - 0x2bc6, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, - 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, - 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, - 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, - 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, - 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, - 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, - 0x0020, 0x2018, 0x080c, 0x9375, 0x928c, 0xff00, 0x0110, 0x2011, - 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, - 0x220a, 0x080c, 0x7637, 0x1118, 0x2009, 0x196d, 0x220a, 0x002e, - 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, - 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, - 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0dbe, 0x002e, 0x001e, - 0x000e, 0x012e, 0x0005, 0x2001, 0x180d, 0x2004, 0xd08c, 0x0118, - 0x2009, 0x0002, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, - 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, - 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, - 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, - 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, - 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, - 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x1990, 0x2004, 0x908a, - 0x0007, 0x1a0c, 0x0dc5, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, - 0x015e, 0x0005, 0x29d9, 0x29f7, 0x2a1b, 0x2a1d, 0x2a46, 0x2a48, - 0x2a4a, 0x2001, 0x0001, 0x080c, 0x281c, 0x080c, 0x2c24, 0x2001, - 0x1992, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, - 0x20a9, 0x0009, 0x080c, 0x2be2, 0x2001, 0x1990, 0x2003, 0x0006, - 0x2009, 0x001e, 0x2011, 0x2a4b, 0x080c, 0x88d5, 0x0005, 0x2009, - 0x1995, 0x200b, 0x0000, 0x2001, 0x199a, 0x2003, 0x0036, 0x2001, - 0x1999, 0x2003, 0x002a, 0x2001, 0x1992, 0x2003, 0x0001, 0x9006, - 0x080c, 0x2b94, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2be2, - 0x2001, 0x1990, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2a4b, - 0x080c, 0x88d5, 0x0005, 0x080c, 0x0dc5, 0x2001, 0x199a, 0x2003, - 0x0036, 0x2001, 0x1992, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, + 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, + 0x0dc5, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, + 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4, 0x9420, + 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, + 0x911b, 0x0a0c, 0x0dc5, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, + 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, + 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, + 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, + 0xd0bc, 0x190c, 0x0dbe, 0x9084, 0x0007, 0x0002, 0x2310, 0x1f14, + 0x2310, 0x2306, 0x2309, 0x230c, 0x2309, 0x230c, 0x080c, 0x1f14, + 0x0005, 0x080c, 0x11b2, 0x0005, 0x080c, 0x1f14, 0x080c, 0x11b2, + 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, + 0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, + 0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, + 0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, + 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x242f, 0x7900, 0xd1dc, + 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x2357, + 0x234f, 0x7f4d, 0x234f, 0x2351, 0x2351, 0x2351, 0x2351, 0x7f33, + 0x234f, 0x2353, 0x234f, 0x2351, 0x234f, 0x2351, 0x234f, 0x080c, + 0x0dc5, 0x0031, 0x0020, 0x080c, 0x7f33, 0x080c, 0x7f4d, 0x0005, + 0x0006, 0x0016, 0x0026, 0x080c, 0xee1b, 0x7930, 0x9184, 0x0003, + 0x01c0, 0x2001, 0x19f8, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133, + 0x2004, 0x9005, 0x090c, 0x0dc5, 0x00c6, 0x2001, 0x19f8, 0x2064, + 0x080c, 0xca71, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2432, + 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, + 0x080c, 0x7569, 0x1138, 0x080c, 0x784e, 0x080c, 0x6127, 0x080c, + 0x7495, 0x0010, 0x080c, 0x5fe6, 0x080c, 0x7ffc, 0x0041, 0x0018, + 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, + 0x0036, 0x0046, 0x0056, 0x2071, 0x1a66, 0x080c, 0x1b02, 0x005e, + 0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, + 0x1800, 0x7128, 0x2001, 0x1970, 0x2102, 0x2001, 0x1978, 0x2102, + 0x2001, 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, + 0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, + 0x0005, 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, + 0x8423, 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, + 0x8403, 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, + 0x1238, 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, + 0x9182, 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, + 0x0098, 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, + 0x0058, 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, + 0x0018, 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, + 0x8301, 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, + 0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, + 0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, + 0x2069, 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, + 0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, + 0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, + 0x080c, 0x0dbe, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, + 0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, + 0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, + 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c80, + 0x080c, 0x2b9b, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084, + 0x000c, 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084, + 0xb17f, 0x9085, 0x2000, 0x6052, 0x2009, 0x199e, 0x2011, 0x199f, + 0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x2bdf, 0x1238, 0x939d, + 0x4003, 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203, + 0x94a5, 0x8603, 0x230a, 0x2412, 0x9006, 0x080c, 0x2bca, 0x9006, + 0x080c, 0x2bad, 0x20a9, 0x0012, 0x1d04, 0x2484, 0x2091, 0x6000, + 0x1f04, 0x2484, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, + 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28cd, + 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x28dd, 0x60e7, 0x0000, + 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, + 0x0080, 0x602f, 0x0000, 0x6007, 0x349f, 0x60bb, 0x0000, 0x20a9, + 0x0018, 0x60bf, 0x0000, 0x1f04, 0x24b1, 0x60bb, 0x0000, 0x60bf, + 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf, + 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, + 0x006b, 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, + 0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, + 0x2001, 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001, + 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, + 0x0066, 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, 0x1138, + 0x6020, 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, 0x9184, + 0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284, + 0x0007, 0x0082, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, + 0x0d70, 0x0c98, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e, + 0x0d30, 0x0c58, 0x2534, 0x251a, 0x251d, 0x2520, 0x2525, 0x2527, + 0x252b, 0x252f, 0x080c, 0x921e, 0x00b8, 0x080c, 0x92ed, 0x00a0, + 0x080c, 0x92ed, 0x080c, 0x921e, 0x0078, 0x0099, 0x0068, 0x080c, + 0x921e, 0x0079, 0x0048, 0x080c, 0x92ed, 0x0059, 0x0028, 0x080c, + 0x92ed, 0x080c, 0x921e, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, + 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, + 0x27a5, 0xd1f4, 0x190c, 0x0dbe, 0x080c, 0x7569, 0x0904, 0x258f, + 0x080c, 0xd561, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024, + 0x9084, 0x1800, 0x0550, 0x080c, 0x758c, 0x0118, 0x080c, 0x757a, + 0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xd561, 0x0168, + 0x080c, 0x758c, 0x1150, 0x2001, 0x19a9, 0x2003, 0x0001, 0x6027, + 0x1800, 0x080c, 0x73e4, 0x0804, 0x27a8, 0x70a4, 0x9005, 0x1150, + 0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x75bd, 0x00de, + 0x1904, 0x27a8, 0x080c, 0x7858, 0x0428, 0x080c, 0x758c, 0x1590, + 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7858, 0x080c, + 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x0804, 0x27a5, 0xd1ac, + 0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, + 0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, 0x773b, + 0x0804, 0x27a5, 0x080c, 0x7853, 0x0048, 0x2001, 0x197e, 0x2003, + 0x0002, 0x0020, 0x080c, 0x769e, 0x0804, 0x27a5, 0x080c, 0x77d6, + 0x0804, 0x27a5, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x2802, + 0xd2b4, 0x1904, 0x2815, 0x0000, 0xd1ac, 0x0904, 0x26ba, 0x0036, + 0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x7569, 0x11c0, 0x6027, + 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x7583, 0x1158, 0x080c, + 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x003e, 0x002e, 0x000e, + 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7541, 0x0016, + 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, + 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, + 0x7038, 0xd084, 0x0190, 0x080c, 0xd561, 0x1118, 0x9186, 0xf800, + 0x1160, 0x7048, 0xd084, 0x1148, 0xc085, 0x704a, 0x0036, 0x2418, + 0x2011, 0x8016, 0x080c, 0x4be9, 0x003e, 0x080c, 0xd55a, 0x1904, + 0x2697, 0x9196, 0xff00, 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, + 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, + 0x33a0, 0x0128, 0xc18d, 0x7132, 0x080c, 0x6a8a, 0x1510, 0x6240, + 0x9294, 0x0010, 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, + 0x01c0, 0x7030, 0xd08c, 0x0904, 0x2697, 0x7038, 0xd08c, 0x1140, + 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2697, 0xc1ad, 0x2102, + 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4be9, 0x003e, 0x0804, + 0x2697, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, + 0x1904, 0x2697, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, + 0x080c, 0x4be9, 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x1848, + 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, + 0x080c, 0x891c, 0x2019, 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, + 0xe915, 0x00ce, 0x9484, 0x00ff, 0x9080, 0x33ac, 0x200d, 0x918c, + 0xff00, 0x810f, 0x2120, 0x9006, 0x2009, 0x000e, 0x080c, 0xe9a5, + 0x001e, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3211, + 0x001e, 0x00a8, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, + 0x671d, 0x1140, 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, + 0x080c, 0x6141, 0x8108, 0x1f04, 0x2687, 0x00be, 0x015e, 0x00ce, + 0x004e, 0x080c, 0xb072, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, + 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, + 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, + 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, 0x2003, 0x0000, + 0x6027, 0x0020, 0xd194, 0x0904, 0x27a5, 0x0016, 0x6220, 0xd2b4, + 0x0904, 0x2742, 0x080c, 0x878f, 0x080c, 0xa517, 0x6027, 0x0004, + 0x00f6, 0x2019, 0x19f2, 0x2304, 0x907d, 0x0904, 0x2711, 0x7804, + 0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, + 0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, + 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, + 0x1df0, 0x080c, 0x2d62, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, + 0x0009, 0x080c, 0x2c5b, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, + 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x080c, 0x97e1, + 0x080c, 0x98ed, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, + 0xb101, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, + 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, + 0x0110, 0x080c, 0x2d62, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6028, + 0x080c, 0xd561, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, + 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0xa4f3, 0x0804, + 0x27a4, 0x2061, 0x0100, 0x62c0, 0x080c, 0xaef8, 0x2019, 0x19f2, + 0x2304, 0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xb180, 0x00ce, + 0x0804, 0x27a4, 0xd2bc, 0x0904, 0x278b, 0x080c, 0x879c, 0x6014, + 0x9084, 0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, + 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d62, + 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6044, 0x080c, 0xd561, 0x0120, + 0x909a, 0x0003, 0x1658, 0x0018, 0x909a, 0x00c8, 0x1638, 0x8000, + 0x6046, 0x603c, 0x00ce, 0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, + 0x8794, 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, + 0x918c, 0x1984, 0x918d, 0x0012, 0x6116, 0x0430, 0x9080, 0x0008, + 0x2004, 0x9086, 0x0009, 0x0d98, 0x6114, 0x918c, 0x1984, 0x918d, + 0x0016, 0x6116, 0x00c8, 0x6027, 0x0004, 0x00b0, 0x0036, 0x2019, + 0x0001, 0x080c, 0xa877, 0x003e, 0x2019, 0x19f8, 0x2304, 0x9065, + 0x0150, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, + 0x004f, 0x080c, 0xb180, 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27fd, + 0x7038, 0xd0ac, 0x1538, 0x0016, 0x0156, 0x6027, 0x0008, 0x080c, + 0x2d8c, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x27b3, 0x6150, 0x9185, + 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04, 0x27bc, 0x080c, 0x87c3, + 0x6020, 0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, + 0x04a0, 0x080c, 0x2c42, 0x1f04, 0x27bc, 0x015e, 0x6152, 0x001e, + 0x6027, 0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xb072, + 0x60e3, 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15, 0x080c, 0x57d7, + 0xd0fc, 0x1138, 0x080c, 0xd55a, 0x1120, 0x9085, 0x0001, 0x080c, + 0x75ad, 0x9006, 0x080c, 0x2d52, 0x2009, 0x0002, 0x080c, 0x2c80, + 0x00e6, 0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0ea3, 0x00ee, + 0x6027, 0x0008, 0x080c, 0x0ba0, 0x001e, 0x918c, 0xffd0, 0x6126, + 0x00ae, 0x0005, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, + 0x0904, 0x25bc, 0x0016, 0x2009, 0x280e, 0x00d0, 0x2001, 0x188b, + 0x200c, 0xc184, 0x2102, 0x001e, 0x0c40, 0x0016, 0x2001, 0x188b, + 0x200c, 0xd194, 0x001e, 0x0904, 0x25bc, 0x0016, 0x2009, 0x2821, + 0x0038, 0x2001, 0x188b, 0x200c, 0xc194, 0x2102, 0x001e, 0x08a8, + 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, + 0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2c7a, 0x6027, 0x0080, + 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016, 0x0026, + 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, + 0x71d0, 0x70d2, 0x9116, 0x0904, 0x288c, 0x81ff, 0x01a0, 0x2009, + 0x0000, 0x080c, 0x2c80, 0x2011, 0x8011, 0x2019, 0x010e, 0x231c, + 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, 0x0000, + 0x080c, 0x4be9, 0x0448, 0x2001, 0x19aa, 0x200c, 0x81ff, 0x1140, + 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008, + 0x2118, 0x2011, 0x8012, 0x080c, 0x4be9, 0x080c, 0x0ea3, 0x080c, + 0x57d7, 0xd0fc, 0x1188, 0x080c, 0xd55a, 0x1170, 0x00c6, 0x080c, + 0x2928, 0x080c, 0xa7de, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, + 0x0002, 0x080c, 0x3211, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, + 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, + 0x9094, 0xff00, 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, + 0x81ff, 0x01e8, 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, + 0x1820, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, + 0x2011, 0x1820, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, + 0x1120, 0x2500, 0x080c, 0x8271, 0x0048, 0x9584, 0x00ff, 0x9080, + 0x33ac, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, + 0x33ac, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, + 0x2001, 0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, + 0x6856, 0x1f04, 0x28d8, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, + 0x2069, 0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, + 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, + 0x9184, 0x000f, 0x9080, 0xf5f7, 0x2005, 0x6856, 0x8211, 0x1f04, + 0x28ed, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, + 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, + 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, + 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, + 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x291d, + 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, + 0x080c, 0x57d3, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, + 0x2020, 0x2009, 0x002e, 0x080c, 0xe9a5, 0x004e, 0x0005, 0x00f6, + 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2994, + 0x080c, 0x2bdf, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, + 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, + 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, + 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, + 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, + 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, + 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, + 0x9080, 0x0020, 0x2018, 0x080c, 0x91b1, 0x928c, 0xff00, 0x0110, + 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, + 0x0138, 0x220a, 0x080c, 0x7569, 0x1118, 0x2009, 0x196e, 0x220a, + 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, + 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, + 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0dbe, 0x002e, + 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, + 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, + 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, + 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, + 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, + 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, + 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, + 0x908a, 0x0007, 0x1a0c, 0x0dc5, 0x0033, 0x00ee, 0x002e, 0x001e, + 0x000e, 0x015e, 0x0005, 0x29f2, 0x2a10, 0x2a34, 0x2a36, 0x2a5f, + 0x2a61, 0x2a63, 0x2001, 0x0001, 0x080c, 0x283d, 0x080c, 0x2c3d, + 0x2001, 0x1993, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, + 0x9006, 0x20a9, 0x0009, 0x080c, 0x2bfb, 0x2001, 0x1991, 0x2003, + 0x0006, 0x2009, 0x001e, 0x2011, 0x2a64, 0x080c, 0x87a1, 0x0005, + 0x2009, 0x1996, 0x200b, 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, + 0x2001, 0x199a, 0x2003, 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, + 0x9006, 0x080c, 0x2bad, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, + 0x2bfb, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, + 0x2a64, 0x080c, 0x87a1, 0x0005, 0x080c, 0x0dc5, 0x2001, 0x199b, + 0x2003, 0x0036, 0x2001, 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, + 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, + 0x080c, 0x2bad, 0x2001, 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, + 0x20a9, 0x0009, 0x080c, 0x2bfb, 0x2001, 0x1991, 0x2003, 0x0006, + 0x2009, 0x001e, 0x2011, 0x2a64, 0x080c, 0x87a1, 0x0005, 0x080c, + 0x0dc5, 0x080c, 0x0dc5, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, + 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, + 0x1993, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dc5, 0x0043, 0x012e, + 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2a86, + 0x2aa2, 0x2ade, 0x2b0a, 0x2b2a, 0x2b36, 0x2b38, 0x080c, 0x2bef, + 0x1190, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, + 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1991, + 0x2003, 0x0001, 0x0030, 0x080c, 0x2b5c, 0x2001, 0xffff, 0x080c, + 0x2a01, 0x0005, 0x080c, 0x2b3a, 0x05c0, 0x2009, 0x199a, 0x2104, + 0x8001, 0x200a, 0x080c, 0x2bef, 0x1158, 0x7a38, 0x9294, 0x0005, + 0x9296, 0x0005, 0x0518, 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, + 0x2009, 0x1996, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, + 0x080c, 0x2b42, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, - 0x2b94, 0x2001, 0x1996, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, - 0x0009, 0x080c, 0x2be2, 0x2001, 0x1990, 0x2003, 0x0006, 0x2009, - 0x001e, 0x2011, 0x2a4b, 0x080c, 0x88d5, 0x0005, 0x080c, 0x0dc5, - 0x080c, 0x0dc5, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, - 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1992, - 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dc5, 0x0043, 0x012e, 0x015e, - 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2a6d, 0x2a89, - 0x2ac5, 0x2af1, 0x2b11, 0x2b1d, 0x2b1f, 0x080c, 0x2bd6, 0x1190, - 0x2009, 0x1998, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, - 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1990, 0x2003, - 0x0001, 0x0030, 0x080c, 0x2b43, 0x2001, 0xffff, 0x080c, 0x29e8, - 0x0005, 0x080c, 0x2b21, 0x05c0, 0x2009, 0x1999, 0x2104, 0x8001, - 0x200a, 0x080c, 0x2bd6, 0x1158, 0x7a38, 0x9294, 0x0005, 0x9296, - 0x0005, 0x0518, 0x2009, 0x1998, 0x2104, 0xc085, 0x200a, 0x2009, - 0x1995, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, - 0x2b29, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, - 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb1, - 0x2001, 0x1992, 0x2003, 0x0002, 0x0028, 0x2001, 0x1990, 0x2003, - 0x0003, 0x0010, 0x080c, 0x2a0a, 0x0005, 0x080c, 0x2b21, 0x0540, - 0x2009, 0x1999, 0x2104, 0x8001, 0x200a, 0x080c, 0x2bd6, 0x1148, - 0x2001, 0x1990, 0x2003, 0x0003, 0x2001, 0x1991, 0x2003, 0x0000, - 0x00b8, 0x2009, 0x1999, 0x2104, 0x9005, 0x1118, 0x080c, 0x2b66, - 0x0010, 0x080c, 0x2b36, 0x080c, 0x2b29, 0x2009, 0x1995, 0x200b, - 0x0000, 0x2001, 0x1992, 0x2003, 0x0001, 0x080c, 0x2a0a, 0x0000, - 0x0005, 0x0479, 0x01e8, 0x080c, 0x2bd6, 0x1198, 0x2009, 0x1996, - 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, - 0x199b, 0x2003, 0x000a, 0x2009, 0x1998, 0x2104, 0xc0fd, 0x200a, - 0x0038, 0x00f9, 0x2001, 0x1992, 0x2003, 0x0004, 0x080c, 0x2a35, - 0x0005, 0x0079, 0x0148, 0x080c, 0x2bd6, 0x1118, 0x080c, 0x2a21, - 0x0018, 0x0079, 0x080c, 0x2a35, 0x0005, 0x080c, 0x0dc5, 0x080c, - 0x0dc5, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x090c, 0x2b82, - 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, - 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb1, 0x0005, 0x7a38, 0x9294, - 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, - 0x080c, 0x2b94, 0x0005, 0x2009, 0x1995, 0x2104, 0x8000, 0x200a, - 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, - 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, - 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, - 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb1, 0x0005, 0x0086, 0x2001, - 0x1998, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0dc5, 0x2009, 0x1997, - 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, - 0x1120, 0x080c, 0x0dc5, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, - 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1990, 0x20a9, 0x0009, - 0x2003, 0x0000, 0x8000, 0x1f04, 0x2b88, 0x2001, 0x1997, 0x2003, - 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, - 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, - 0x2009, 0x199d, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, - 0x9085, 0x0006, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x00fe, - 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0138, 0x7838, - 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x0030, 0x7838, 0x9084, - 0xfffb, 0x9085, 0x0005, 0x783a, 0x00fe, 0x0005, 0x0006, 0x2001, - 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001, - 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9, - 0x0064, 0x7820, 0x080c, 0x2c61, 0xd09c, 0x1110, 0x1f04, 0x2bd9, - 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x7850, - 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, - 0x2c61, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008, 0x9186, 0x0000, - 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, - 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, - 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, - 0x2c0f, 0x080c, 0x88f7, 0x1f04, 0x2c0f, 0x7850, 0x9085, 0x0400, - 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2c61, 0x9085, 0x1000, 0x7852, - 0x000e, 0x001e, 0x012e, 0x0005, 0x7850, 0x9084, 0xffcf, 0x7852, - 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, - 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2c33, - 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2c39, 0x00fe, 0x015e, - 0x000e, 0x0005, 0x1d04, 0x2c42, 0x080c, 0x88f7, 0x1f04, 0x2c42, - 0x0005, 0x0006, 0x2001, 0x199c, 0x2004, 0x9086, 0x0000, 0x000e, - 0x0005, 0x0006, 0x2001, 0x199c, 0x2004, 0x9086, 0x0001, 0x000e, - 0x0005, 0x0006, 0x2001, 0x199c, 0x2004, 0x9086, 0x0002, 0x000e, - 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, - 0x2001, 0x19a9, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, - 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, - 0xa001, 0x200a, 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, - 0x918c, 0xff00, 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, 0x0170, - 0x9186, 0x0100, 0x1904, 0x2cda, 0x0048, 0x0016, 0x2009, 0x1a87, - 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, - 0x080c, 0x0e52, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, - 0x0169, 0x2104, 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, - 0x1db0, 0x9086, 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, 0x2031, - 0x0002, 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a88, - 0x263c, 0x8738, 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, 0x9402, - 0x02a0, 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, - 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, 0x180c, - 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x1981, 0x200c, - 0x080c, 0x0e52, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, - 0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001, - 0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126, - 0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e, - 0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, 0x0161, - 0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, 0x0008, - 0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, 0x6017, - 0x0040, 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, 0x0016, - 0x2019, 0x0141, 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, 0x9084, - 0x2800, 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, - 0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012, - 0x6016, 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, - 0x0005, 0x0016, 0x0026, 0x080c, 0x7651, 0x0108, 0xc0bc, 0x2009, - 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, - 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, - 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, - 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, - 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, - 0x1128, 0x080c, 0x7651, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, - 0x001e, 0x000e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, 0x0040, - 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2c61, 0x9085, - 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2d84, 0x080c, 0x88f7, - 0x1f04, 0x2d84, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, - 0x015e, 0x000e, 0x0005, 0x2fff, 0x2fff, 0x2e23, 0x2e23, 0x2e2f, - 0x2e2f, 0x2e3b, 0x2e3b, 0x2e49, 0x2e49, 0x2e55, 0x2e55, 0x2e63, - 0x2e63, 0x2e71, 0x2e71, 0x2e83, 0x2e83, 0x2e8f, 0x2e8f, 0x2e9d, - 0x2e9d, 0x2ebb, 0x2ebb, 0x2edb, 0x2edb, 0x2eab, 0x2eab, 0x2ecb, - 0x2ecb, 0x2ee9, 0x2ee9, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2efb, 0x2efb, 0x2f07, 0x2f07, 0x2f15, - 0x2f15, 0x2f23, 0x2f23, 0x2f33, 0x2f33, 0x2f41, 0x2f41, 0x2f51, - 0x2f51, 0x2f61, 0x2f61, 0x2f73, 0x2f73, 0x2f81, 0x2f81, 0x2f91, - 0x2f91, 0x2fb3, 0x2fb3, 0x2fd5, 0x2fd5, 0x2fa1, 0x2fa1, 0x2fc4, - 0x2fc4, 0x2fe4, 0x2fe4, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, - 0x2e81, 0x2e81, 0x2e81, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x24c0, 0x0804, 0x2ff7, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x22cc, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24c0, 0x080c, - 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, 0x2307, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x080c, 0x2307, 0x0804, - 0x2ff7, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x0804, 0x2ff7, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x24c0, 0x080c, 0x1394, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, - 0x1394, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x24c0, 0x080c, 0x1394, 0x080c, - 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x080c, - 0x1394, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, 0x1394, 0x080c, - 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x080c, 0x2307, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x080c, 0x1394, 0x080c, - 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x0804, 0x2ff7, 0x0106, - 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, - 0x2976, 0x080c, 0x24c0, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, - 0x22cc, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, - 0x24c0, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x2307, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2976, 0x080c, 0x24c0, 0x080c, 0x2307, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, 0x2307, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x080c, - 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x1394, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2976, 0x080c, 0x24c0, 0x080c, 0x1394, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, 0x1394, 0x0804, - 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x2976, 0x080c, 0x24c0, 0x080c, 0x1394, 0x080c, - 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, - 0x24c0, 0x080c, 0x1394, 0x0498, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, - 0x080c, 0x1394, 0x080c, 0x2307, 0x0410, 0x0106, 0x0006, 0x0126, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, - 0x1394, 0x080c, 0x2307, 0x0098, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, - 0x080c, 0x24c0, 0x080c, 0x1394, 0x080c, 0x2307, 0x0000, 0x015e, - 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d, - 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6a61, 0x1904, - 0x3137, 0x72dc, 0x2001, 0x197c, 0x2004, 0x9005, 0x1110, 0xd29c, - 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x3137, 0x080c, 0x313c, - 0x0804, 0x3137, 0xd2cc, 0x1904, 0x3137, 0x080c, 0x7637, 0x1120, - 0x70af, 0xffff, 0x0804, 0x3137, 0xd294, 0x0120, 0x70af, 0xffff, - 0x0804, 0x3137, 0x080c, 0x33a5, 0x0160, 0x080c, 0xd7e3, 0x0128, - 0x2001, 0x1818, 0x203c, 0x0804, 0x30b0, 0x70af, 0xffff, 0x0804, - 0x3137, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, 0x30b0, - 0xd28c, 0x1904, 0x30b0, 0x0036, 0x73ac, 0x938e, 0xffff, 0x1110, - 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, 0x938c, 0x0001, - 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x970e, - 0x0904, 0x30a6, 0x908e, 0x0000, 0x0904, 0x30a6, 0x908e, 0x00ff, - 0x1160, 0x7230, 0xd284, 0x1904, 0x30ab, 0x7294, 0xc28d, 0x7296, - 0x70af, 0xffff, 0x003e, 0x0804, 0x30b0, 0x2009, 0x180d, 0x210c, - 0xd18c, 0x0150, 0x0026, 0x2011, 0x0010, 0x080c, 0x6ac7, 0x002e, - 0x0118, 0x70af, 0xffff, 0x0488, 0x900e, 0x080c, 0x2873, 0x080c, - 0x66b9, 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, - 0x00c6, 0x2060, 0x080c, 0x8cf7, 0x00ce, 0x090c, 0x9096, 0xb8af, - 0x0000, 0x080c, 0x6aa3, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, - 0xd0bc, 0x0138, 0x080c, 0x6944, 0x0120, 0x080c, 0x3155, 0x0148, - 0x0028, 0x080c, 0x3295, 0x080c, 0x3181, 0x0118, 0x8318, 0x0804, - 0x304a, 0x73ae, 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x3137, - 0x9780, 0x33b6, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, - 0x70ac, 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, - 0x0220, 0x2008, 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, - 0x3137, 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x312c, 0x2001, - 0x180d, 0x2004, 0xd08c, 0x0158, 0x0026, 0x2011, 0x0010, 0x080c, - 0x6ac7, 0x002e, 0x0120, 0x2009, 0xffff, 0x0804, 0x3134, 0xc484, - 0x080c, 0x6724, 0x0168, 0x080c, 0xd7e3, 0x1904, 0x312c, 0x080c, - 0x33a5, 0x1904, 0x312c, 0x080c, 0x66b9, 0x1904, 0x3134, 0x0008, - 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, - 0x080c, 0x8cf7, 0x00ce, 0x090c, 0x9096, 0xb8af, 0x0000, 0x080c, - 0x6aa3, 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, - 0x7294, 0xd28c, 0x0180, 0x080c, 0x6aa3, 0x9082, 0x0006, 0x02e0, - 0xd484, 0x1118, 0x080c, 0x66de, 0x0028, 0x080c, 0x3321, 0x01a0, - 0x080c, 0x334c, 0x0088, 0x080c, 0x3295, 0x080c, 0xd7e3, 0x1160, - 0x080c, 0x3181, 0x0188, 0x0040, 0x080c, 0xd7e3, 0x1118, 0x080c, - 0x3321, 0x0110, 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, - 0x30c9, 0x70af, 0xffff, 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, - 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, - 0x2009, 0x007e, 0x080c, 0x66b9, 0x1168, 0xb813, 0x00ff, 0xb817, - 0xfffe, 0x080c, 0x3295, 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, - 0x080c, 0xd52b, 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, - 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, - 0xb325, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd554, 0x6023, 0x0001, - 0x9006, 0x080c, 0x6656, 0x2001, 0x0000, 0x080c, 0x666a, 0x0126, - 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, - 0x080c, 0xb352, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, - 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, - 0x9084, 0x00ff, 0xb842, 0x080c, 0xb325, 0x0548, 0x2b00, 0x6012, - 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, - 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c, 0x3250, 0x080c, - 0xd554, 0x6023, 0x0001, 0x9006, 0x080c, 0x6656, 0x2001, 0x0002, - 0x080c, 0x666a, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, - 0x012e, 0x2009, 0x0002, 0x080c, 0xb352, 0x9085, 0x0001, 0x00ce, - 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, - 0x0080, 0x080c, 0x66b9, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, - 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, - 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, 0xb27d, 0x01d0, 0x2b00, - 0x6012, 0x080c, 0xd554, 0x6023, 0x0001, 0x9006, 0x080c, 0x6656, - 0x2001, 0x0002, 0x080c, 0x666a, 0x0126, 0x2091, 0x8000, 0x70e4, - 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c, 0xb352, 0x9085, - 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, - 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, 0x080c, 0x66b9, 0x11b8, - 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8cf, 0x0004, 0x080c, 0xb27d, - 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, - 0xd554, 0x2009, 0x0022, 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, - 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, - 0x00b6, 0x21f0, 0x080c, 0x96af, 0x080c, 0x962f, 0x080c, 0xb111, - 0x080c, 0xc2d3, 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, - 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6724, - 0x1140, 0x9686, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, - 0x6148, 0x001e, 0x8108, 0x1f04, 0x3235, 0x9686, 0x0001, 0x190c, - 0x3379, 0x00be, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, - 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, - 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x96a4, 0x0076, - 0x2039, 0x0000, 0x080c, 0x9577, 0x2c08, 0x080c, 0xe91c, 0x007e, - 0x001e, 0xba10, 0xbb14, 0xbcc0, 0x080c, 0x6148, 0xba12, 0xbb16, - 0xbcc2, 0x00be, 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, - 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, - 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, - 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, - 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, - 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, - 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078, - 0x080c, 0x57d5, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020, - 0x2009, 0x002d, 0x080c, 0xec31, 0x20a9, 0x0800, 0x9016, 0x0026, - 0x928e, 0x007e, 0x0904, 0x3300, 0x928e, 0x007f, 0x0904, 0x3300, - 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c0, - 0x8fff, 0x1148, 0x2001, 0x198e, 0x0006, 0x2003, 0x0001, 0x04f1, - 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, - 0x080c, 0x6a6d, 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x96a4, - 0x0076, 0x2039, 0x0000, 0x080c, 0x9577, 0x00b6, 0x00c6, 0x0026, - 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, - 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, - 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xe91c, 0x001e, 0x007e, - 0x002e, 0x8210, 0x1f04, 0x32b7, 0x015e, 0x001e, 0x002e, 0x003e, - 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, - 0x0016, 0x080c, 0x57d5, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, - 0x2220, 0x2009, 0x0029, 0x080c, 0xec31, 0x001e, 0x002e, 0x004e, - 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, - 0x080c, 0x6a9b, 0x11d0, 0x2100, 0x080c, 0x28a6, 0x81ff, 0x01b8, - 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, 0xd384, 0x0120, - 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, - 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, - 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x0036, 0x2019, 0x0029, 0x00a9, 0x003e, 0x9180, 0x1000, - 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061, 0x1ab7, 0x001e, - 0x6112, 0x080c, 0x3250, 0x001e, 0x080c, 0x66de, 0x012e, 0x00ce, - 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c, 0xac6c, 0x080c, - 0xef94, 0x002e, 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, - 0x0005, 0x00c6, 0x00b6, 0x080c, 0x7637, 0x1118, 0x20a9, 0x0800, - 0x0010, 0x20a9, 0x0782, 0x080c, 0x7637, 0x1110, 0x900e, 0x0010, - 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, - 0x0110, 0xb800, 0xd0bc, 0x090c, 0x66de, 0x8108, 0x1f04, 0x338a, - 0x2061, 0x1800, 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, - 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, - 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, - 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, - 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, - 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, - 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, - 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, - 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, - 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, - 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, - 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, - 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, - 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, - 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, - 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, - 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, - 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, - 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, - 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, - 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, - 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, - 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, - 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, - 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, - 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, - 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, - 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, - 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, - 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, + 0x2bca, 0x2001, 0x1993, 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, + 0x2003, 0x0003, 0x0010, 0x080c, 0x2a23, 0x0005, 0x080c, 0x2b3a, + 0x0540, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2bef, + 0x1148, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001, 0x1992, 0x2003, + 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005, 0x1118, 0x080c, + 0x2b7f, 0x0010, 0x080c, 0x2b4f, 0x080c, 0x2b42, 0x2009, 0x1996, + 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001, 0x080c, 0x2a23, + 0x0000, 0x0005, 0x0479, 0x01e8, 0x080c, 0x2bef, 0x1198, 0x2009, + 0x1997, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, + 0x2001, 0x199c, 0x2003, 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, + 0x200a, 0x0038, 0x00f9, 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, + 0x2a4e, 0x0005, 0x0079, 0x0148, 0x080c, 0x2bef, 0x1118, 0x080c, + 0x2a3a, 0x0018, 0x0079, 0x080c, 0x2a4e, 0x0005, 0x080c, 0x0dc5, + 0x080c, 0x0dc5, 0x2009, 0x199b, 0x2104, 0x8001, 0x200a, 0x090c, + 0x2b9b, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, + 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bca, 0x0005, 0x7a38, + 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x2bad, 0x0005, 0x2009, 0x1996, 0x2104, 0x8000, + 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, + 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, + 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bca, 0x0005, 0x0086, + 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0dc5, 0x2009, + 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, + 0xd084, 0x1120, 0x080c, 0x0dc5, 0x9006, 0x0010, 0x2001, 0x0001, + 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1991, 0x20a9, + 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x2ba1, 0x2001, 0x1998, + 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, + 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, + 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, + 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f, 0x210c, 0x795a, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0138, + 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x0030, 0x7838, + 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x00fe, 0x0005, 0x0006, + 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, + 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, + 0x20a9, 0x0064, 0x7820, 0x080c, 0x2c7a, 0xd09c, 0x1110, 0x1f04, + 0x2bf2, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, + 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, + 0x080c, 0x2c7a, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008, 0x9186, + 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, + 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, + 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, + 0x1d04, 0x2c28, 0x080c, 0x87c3, 0x1f04, 0x2c28, 0x7850, 0x9085, + 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2c7a, 0x9085, 0x1000, + 0x7852, 0x000e, 0x001e, 0x012e, 0x0005, 0x7850, 0x9084, 0xffcf, + 0x7852, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, + 0x000a, 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, + 0x2c4c, 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2c52, 0x00fe, + 0x015e, 0x000e, 0x0005, 0x1d04, 0x2c5b, 0x080c, 0x87c3, 0x1f04, + 0x2c5b, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000, + 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001, + 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002, + 0x000e, 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, + 0x0006, 0x2001, 0x19aa, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, + 0x2104, 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, + 0xa001, 0xa001, 0x200a, 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, + 0x200c, 0x918c, 0xff00, 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, + 0x0170, 0x9186, 0x0100, 0x1904, 0x2cf3, 0x0048, 0x0016, 0x2009, + 0x1a88, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, + 0x00a2, 0x080c, 0x0e52, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, + 0x2009, 0x0169, 0x2104, 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, + 0x910e, 0x1db0, 0x9086, 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, + 0x2031, 0x0002, 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, + 0x1a89, 0x263c, 0x8738, 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, + 0x9402, 0x02a0, 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, + 0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, + 0x180c, 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x1982, + 0x200c, 0x080c, 0x0e52, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, + 0x2004, 0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, + 0x2001, 0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, + 0x0126, 0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, + 0x012e, 0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, + 0x0161, 0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, + 0x0008, 0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, + 0x6017, 0x0040, 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, + 0x0016, 0x2019, 0x0141, 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, + 0x9084, 0x2800, 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, + 0x0118, 0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, + 0x0012, 0x6016, 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, + 0x00ce, 0x0005, 0x0016, 0x0026, 0x080c, 0x7583, 0x0108, 0xc0bc, + 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, + 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, + 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, + 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, + 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, + 0x2104, 0x1128, 0x080c, 0x7583, 0x0110, 0xc0bc, 0x0008, 0xc0bd, + 0x200a, 0x001e, 0x000e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, + 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2c7a, + 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2d9d, 0x080c, + 0x87c3, 0x1f04, 0x2d9d, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, + 0x6052, 0x015e, 0x000e, 0x0005, 0x3018, 0x3018, 0x2e3c, 0x2e3c, + 0x2e48, 0x2e48, 0x2e54, 0x2e54, 0x2e62, 0x2e62, 0x2e6e, 0x2e6e, + 0x2e7c, 0x2e7c, 0x2e8a, 0x2e8a, 0x2e9c, 0x2e9c, 0x2ea8, 0x2ea8, + 0x2eb6, 0x2eb6, 0x2ed4, 0x2ed4, 0x2ef4, 0x2ef4, 0x2ec4, 0x2ec4, + 0x2ee4, 0x2ee4, 0x2f02, 0x2f02, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2f14, 0x2f14, 0x2f20, 0x2f20, + 0x2f2e, 0x2f2e, 0x2f3c, 0x2f3c, 0x2f4c, 0x2f4c, 0x2f5a, 0x2f5a, + 0x2f6a, 0x2f6a, 0x2f7a, 0x2f7a, 0x2f8c, 0x2f8c, 0x2f9a, 0x2f9a, + 0x2faa, 0x2faa, 0x2fcc, 0x2fcc, 0x2fee, 0x2fee, 0x2fba, 0x2fba, + 0x2fdd, 0x2fdd, 0x2ffd, 0x2ffd, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, + 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1, 0x0804, 0x3010, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x22f5, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, 0x080c, 0x2330, + 0x0804, 0x3010, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x0804, 0x3010, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x24e1, 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, + 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1, 0x080c, 0x1394, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, + 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x1394, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, 0x080c, 0x1394, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x0804, 0x3010, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x2997, 0x080c, 0x24e1, 0x0804, 0x3010, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, + 0x080c, 0x22f5, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, + 0x080c, 0x24e1, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x2330, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x24e1, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x1394, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x1394, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x1394, + 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x1394, + 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, + 0x080c, 0x24e1, 0x080c, 0x1394, 0x0498, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, + 0x22f5, 0x080c, 0x1394, 0x080c, 0x2330, 0x0410, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, + 0x080c, 0x1394, 0x080c, 0x2330, 0x0098, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, + 0x22f5, 0x080c, 0x24e1, 0x080c, 0x1394, 0x080c, 0x2330, 0x0000, + 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, + 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6a50, + 0x1904, 0x312d, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110, + 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x312d, 0x080c, + 0x3132, 0x0804, 0x312d, 0xd2cc, 0x1904, 0x312d, 0x080c, 0x7569, + 0x1120, 0x70af, 0xffff, 0x0804, 0x312d, 0xd294, 0x0120, 0x70af, + 0xffff, 0x0804, 0x312d, 0x080c, 0x339b, 0x0160, 0x080c, 0xd561, + 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x30b6, 0x70af, 0xffff, + 0x0804, 0x312d, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, + 0x30b6, 0xd28c, 0x1904, 0x30b6, 0x0036, 0x73ac, 0x938e, 0xffff, + 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, 0x938c, + 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, + 0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150, + 0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff, + 0x003e, 0x04a0, 0x900e, 0x080c, 0x2894, 0x080c, 0x66b2, 0x1538, + 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, + 0x080c, 0x8bc3, 0x00ce, 0x090c, 0x8f64, 0xb8af, 0x0000, 0x080c, + 0x6a92, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, + 0x080c, 0x693d, 0x0120, 0x080c, 0x314b, 0x0148, 0x0028, 0x080c, + 0x328b, 0x080c, 0x3177, 0x0118, 0x8318, 0x0804, 0x3063, 0x73ae, + 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x312d, 0x9780, 0x33ac, + 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096, + 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, + 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x312d, 0x2700, + 0x0156, 0x0016, 0x9106, 0x0904, 0x3122, 0xc484, 0x080c, 0x671d, + 0x0168, 0x080c, 0xd561, 0x1904, 0x3122, 0x080c, 0x339b, 0x1904, + 0x3122, 0x080c, 0x66b2, 0x1904, 0x312a, 0x0008, 0xc485, 0xb8bb, + 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8bc3, + 0x00ce, 0x090c, 0x8f64, 0xb8af, 0x0000, 0x080c, 0x6a92, 0x1130, + 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, + 0x0180, 0x080c, 0x6a92, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, + 0x080c, 0x66d7, 0x0028, 0x080c, 0x3317, 0x01a0, 0x080c, 0x3342, + 0x0088, 0x080c, 0x328b, 0x080c, 0xd561, 0x1160, 0x080c, 0x3177, + 0x0188, 0x0040, 0x080c, 0xd561, 0x1118, 0x080c, 0x3317, 0x0110, + 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x30cf, 0x70af, + 0xffff, 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, + 0x00be, 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, 0x007e, + 0x080c, 0x66b2, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, + 0x328b, 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd2a9, + 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, + 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xb153, 0x01d0, + 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x9006, 0x080c, + 0x664f, 0x2001, 0x0000, 0x080c, 0x6663, 0x0126, 0x2091, 0x8000, + 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, 0xb180, + 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, + 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, + 0xb842, 0x080c, 0xb153, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, + 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x1110, 0x080c, 0x3246, 0x080c, 0xd2d2, 0x6023, + 0x0001, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c, 0x6663, + 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, + 0x0002, 0x080c, 0xb180, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, + 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, + 0x66b2, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, + 0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, + 0x00d6, 0x00c6, 0x080c, 0xb0ab, 0x01d0, 0x2b00, 0x6012, 0x080c, + 0xd2d2, 0x6023, 0x0001, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, + 0x080c, 0x6663, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, + 0x012e, 0x2009, 0x0002, 0x080c, 0xb180, 0x9085, 0x0001, 0x00ce, + 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2009, 0x007f, 0x080c, 0x66b2, 0x11b8, 0xb813, 0x00ff, + 0xb817, 0xfffd, 0xb8cf, 0x0004, 0x080c, 0xb0ab, 0x0170, 0x2b00, + 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd2d2, 0x2009, + 0x0022, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, + 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, + 0x080c, 0x94eb, 0x080c, 0x946b, 0x080c, 0xaf3f, 0x080c, 0xc051, + 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, + 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d, 0x1140, 0x9686, + 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6141, 0x001e, + 0x8108, 0x1f04, 0x322b, 0x9686, 0x0001, 0x190c, 0x336f, 0x00be, + 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, + 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, + 0x0026, 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039, 0x0000, + 0x080c, 0x93b3, 0x2c08, 0x080c, 0xe690, 0x007e, 0x001e, 0xba10, + 0xbb14, 0xbcc0, 0x080c, 0x6141, 0xba12, 0xbb16, 0xbcc2, 0x00be, + 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, + 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, + 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa, + 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0, + 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, + 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, + 0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x57d3, + 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, + 0x080c, 0xe9a5, 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, + 0x0904, 0x32f6, 0x928e, 0x007f, 0x0904, 0x32f6, 0x928e, 0x0080, + 0x05e8, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148, + 0x2001, 0x198f, 0x0006, 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003, + 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6a5c, + 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039, + 0x0000, 0x080c, 0x93b3, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, + 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, + 0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, + 0x0016, 0x2c08, 0x080c, 0xe690, 0x001e, 0x007e, 0x002e, 0x8210, + 0x1f04, 0x32ad, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, + 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, + 0x57d3, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, + 0x0029, 0x080c, 0xe9a5, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6a8a, + 0x11d0, 0x2100, 0x080c, 0x28c7, 0x81ff, 0x01b8, 0x2019, 0x0001, + 0x8314, 0x92e0, 0x1c80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, + 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, + 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036, + 0x2019, 0x0029, 0x00a9, 0x003e, 0x9180, 0x1000, 0x2004, 0x9065, + 0x0158, 0x0016, 0x00c6, 0x2061, 0x1ab8, 0x001e, 0x6112, 0x080c, + 0x3246, 0x001e, 0x080c, 0x66d7, 0x012e, 0x00ce, 0x001e, 0x0005, + 0x0016, 0x0026, 0x2110, 0x080c, 0xaa9a, 0x080c, 0xed0f, 0x002e, + 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, + 0x00b6, 0x080c, 0x7569, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, + 0x0782, 0x080c, 0x7569, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, + 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, + 0xd0bc, 0x090c, 0x66d7, 0x8108, 0x1f04, 0x3380, 0x2061, 0x1800, + 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, + 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, + 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, + 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, + 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, + 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, + 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, + 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, + 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, + 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, + 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, + 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, + 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, + 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, + 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, + 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, + 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, + 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, + 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, + 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, + 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, + 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, + 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, + 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, + 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, + 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, + 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, + 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, + 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, + 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, + 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, - 0x7003, 0x0002, 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, - 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, - 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x706a, 0xa867, 0x0002, - 0xa8ab, 0xdcb0, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x706e, - 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, - 0x0002, 0x34e5, 0x34e6, 0x34f9, 0x350d, 0x0005, 0x1004, 0x34f6, - 0x0e04, 0x34f6, 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, - 0x9005, 0x1128, 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, - 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, - 0x0100, 0x0128, 0x9086, 0x0200, 0x0904, 0x35e1, 0x0005, 0x7018, - 0x2048, 0x2061, 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, - 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, - 0x0005, 0x9086, 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, - 0x1800, 0x701c, 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, - 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x35de, - 0x61d0, 0x0804, 0x3573, 0x35b5, 0x35ed, 0x35de, 0x35f9, 0x3603, - 0x3609, 0x360d, 0x361d, 0x3621, 0x3637, 0x363d, 0x3643, 0x364e, - 0x3659, 0x3668, 0x3677, 0x3685, 0x369c, 0x36b7, 0x35de, 0x3762, - 0x37a0, 0x3846, 0x3857, 0x387a, 0x35de, 0x35de, 0x35de, 0x38b2, - 0x38ce, 0x38d7, 0x3906, 0x390c, 0x35de, 0x3952, 0x35de, 0x35de, - 0x35de, 0x35de, 0x35de, 0x395d, 0x3966, 0x396e, 0x3970, 0x35de, - 0x35de, 0x35de, 0x35de, 0x35de, 0x35de, 0x399c, 0x35de, 0x35de, - 0x35de, 0x35de, 0x35de, 0x39b9, 0x3a40, 0x35de, 0x35de, 0x35de, - 0x35de, 0x35de, 0x35de, 0x0002, 0x3a6a, 0x3a6d, 0x3acc, 0x3ae5, - 0x3b15, 0x3db7, 0x35de, 0x5398, 0x35de, 0x35de, 0x35de, 0x35de, - 0x35de, 0x35de, 0x35de, 0x35de, 0x3637, 0x363d, 0x42ec, 0x57f9, - 0x430a, 0x5427, 0x5479, 0x5584, 0x35de, 0x55e6, 0x5622, 0x5653, - 0x575b, 0x5680, 0x56db, 0x35de, 0x430e, 0x44e1, 0x44f7, 0x451c, - 0x4581, 0x45f5, 0x4615, 0x468c, 0x46e8, 0x4744, 0x4747, 0x476c, - 0x4823, 0x4889, 0x4891, 0x49c6, 0x4b6e, 0x4ba2, 0x4e06, 0x35de, - 0x4e24, 0x4eeb, 0x4fd4, 0x502e, 0x35de, 0x50c1, 0x35de, 0x50d7, - 0x50f2, 0x4891, 0x5338, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, - 0x4c20, 0x0126, 0x2091, 0x8000, 0x0e04, 0x35bf, 0x0010, 0x012e, - 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, - 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, - 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, - 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, - 0x4005, 0x0868, 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, - 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, - 0x4c2d, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, - 0x7990, 0x0804, 0x4c30, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, - 0x35b5, 0x7984, 0x2114, 0x0804, 0x35b5, 0x20e1, 0x0000, 0x2099, - 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, - 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x35b5, 0x7884, 0x2060, 0x0804, - 0x366a, 0x2009, 0x0003, 0x2011, 0x0003, 0x2019, 0x0014, 0x789b, - 0x0137, 0x7893, 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, - 0x7896, 0x0804, 0x35b5, 0x7897, 0x0001, 0x0804, 0x35b5, 0x2039, - 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35f1, 0x2039, 0x0001, 0x7d98, - 0x7c9c, 0x0804, 0x35fd, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, - 0x35ea, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x35f1, 0x79a0, 0x9182, - 0x0040, 0x0210, 0x0804, 0x35ea, 0x2138, 0x7d98, 0x7c9c, 0x0804, - 0x35fd, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35ea, 0x21e8, - 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x35b5, - 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, - 0x1dd8, 0x2010, 0x9005, 0x0904, 0x35b5, 0x0804, 0x35e4, 0x79a0, - 0x9182, 0x0040, 0x0210, 0x0804, 0x35ea, 0x21e0, 0x20a9, 0x0001, - 0x7984, 0x2198, 0x4012, 0x0804, 0x35b5, 0x2069, 0x1847, 0x7884, - 0x7990, 0x911a, 0x1a04, 0x35ea, 0x8019, 0x0904, 0x35ea, 0x684a, - 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, - 0x080c, 0x7963, 0x0804, 0x35b5, 0x2069, 0x1847, 0x7884, 0x7994, - 0x911a, 0x1a04, 0x35ea, 0x8019, 0x0904, 0x35ea, 0x684e, 0x6946, - 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, - 0x2091, 0x8000, 0x080c, 0x6bf8, 0x012e, 0x0804, 0x35b5, 0x902e, - 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35e7, 0x7984, - 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, - 0x4101, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, - 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c2d, - 0x701f, 0x36db, 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, - 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, - 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, 0x1904, 0x35e7, 0x810f, - 0x918c, 0x00ff, 0x0904, 0x35e7, 0x7112, 0x7010, 0x8001, 0x0560, - 0x7012, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, - 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, - 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, - 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c2d, 0x701f, 0x3719, - 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, - 0x000a, 0x1904, 0x35e7, 0x0888, 0x0126, 0x2091, 0x8000, 0x7014, - 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, - 0x0029, 0x1148, 0xc2fd, 0xaa7a, 0x080c, 0x629f, 0x0138, 0xa87a, - 0xa982, 0x012e, 0x0060, 0x080c, 0x65cf, 0x1130, 0x7007, 0x0003, - 0x701f, 0x3747, 0x012e, 0x0005, 0x080c, 0x710b, 0x012e, 0x0126, - 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, 0x18a6, - 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, - 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, 0xaf60, - 0x0804, 0x4c30, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, 0x0010, - 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, 0x2020, - 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, 0x0100, - 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, 0x2009, - 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1c, 0x2004, 0x9005, - 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, - 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, 0x0427, - 0x81ff, 0x1904, 0x35e7, 0x7984, 0x080c, 0x6724, 0x1904, 0x35ea, - 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x35ea, 0x7c88, - 0x7d8c, 0x080c, 0x6887, 0x080c, 0x6856, 0x0000, 0x1518, 0x2061, - 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, - 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, - 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, - 0x1a04, 0x35e7, 0x0c30, 0x080c, 0xccf3, 0x012e, 0x0904, 0x35e7, - 0x0804, 0x35b5, 0x900e, 0x2001, 0x0005, 0x080c, 0x710b, 0x0126, - 0x2091, 0x8000, 0x080c, 0xd3d4, 0x080c, 0x6e9f, 0x012e, 0x0804, - 0x35b5, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6724, 0x1904, 0x3833, - 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0, - 0x080c, 0x6887, 0x080c, 0x6856, 0x1520, 0x2061, 0x1cd0, 0x0126, - 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, - 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e, - 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, 0x000d, - 0x12b0, 0x0c28, 0x080c, 0xccf3, 0x012e, 0x2009, 0x0003, 0x0178, - 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x710b, 0x0126, 0x2091, - 0x8000, 0x080c, 0xd3d4, 0x080c, 0x6e92, 0x012e, 0x0070, 0xb097, - 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006, - 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904, - 0x35e7, 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x67eb, 0x0904, - 0x35e7, 0x080c, 0x688d, 0x0904, 0x35e7, 0x0804, 0x460c, 0x81ff, - 0x1904, 0x35e7, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x080c, 0x691b, - 0x0904, 0x35e7, 0x2019, 0x0005, 0x79a8, 0x080c, 0x68a8, 0x0904, - 0x35e7, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35ea, 0x8003, 0x800b, - 0x810b, 0x9108, 0x080c, 0x884b, 0x79a8, 0xd184, 0x1904, 0x35b5, - 0x0804, 0x460c, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, - 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8, - 0x2508, 0x080c, 0x6724, 0x11d8, 0x080c, 0x691b, 0x1128, 0x2009, - 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c, - 0x68a8, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000, - 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x884b, 0x8529, - 0x1ae0, 0x012e, 0x0804, 0x35b5, 0x012e, 0x0804, 0x35e7, 0x012e, - 0x0804, 0x35ea, 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x67eb, - 0x0904, 0x35e7, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, - 0x96a4, 0x0076, 0x903e, 0x080c, 0x9577, 0x900e, 0x080c, 0xe91c, - 0x007e, 0x00ce, 0x080c, 0x6887, 0x0804, 0x35b5, 0x080c, 0x4bfb, - 0x0904, 0x35ea, 0x080c, 0x6887, 0x2208, 0x0804, 0x35b5, 0x0156, - 0x00d6, 0x00e6, 0x2069, 0x1910, 0x6810, 0x6914, 0x910a, 0x1208, - 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069, 0x1000, - 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68, 0x1f04, - 0x38e8, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x35b5, - 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, - 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0x1910, - 0x6910, 0x62bc, 0x0804, 0x35b5, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x35e7, 0x0126, 0x2091, 0x8000, 0x080c, 0x57e9, 0x0128, - 0x2009, 0x0007, 0x012e, 0x0804, 0x35e7, 0x012e, 0x615c, 0x9190, - 0x33b6, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108, 0x6280, - 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, 0x0001, - 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, 0x0003, - 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, 0x0002, - 0x0068, 0x080c, 0x7637, 0x1118, 0x2031, 0x0004, 0x0038, 0xd79c, - 0x0120, 0x2009, 0x0005, 0x0804, 0x35e7, 0x9036, 0x7e9a, 0x7f9e, - 0x0804, 0x35b5, 0x614c, 0x6250, 0x2019, 0x1986, 0x231c, 0x2001, - 0x1987, 0x2004, 0x789a, 0x0804, 0x35b5, 0x0126, 0x2091, 0x8000, - 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x35b5, 0x080c, 0x4c17, - 0x0904, 0x35ea, 0xba44, 0xbb38, 0x0804, 0x35b5, 0x080c, 0x0dc5, - 0x080c, 0x4c17, 0x2110, 0x0904, 0x35ea, 0xb804, 0x908c, 0x00ff, - 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, 0x2009, - 0x0009, 0x1904, 0x35e7, 0x0126, 0x2091, 0x8000, 0x2019, 0x0005, - 0x00c6, 0x9066, 0x080c, 0xac6c, 0x080c, 0x96a4, 0x0076, 0x903e, - 0x080c, 0x9577, 0x900e, 0x080c, 0xe91c, 0x007e, 0x00ce, 0xb807, - 0x0407, 0x012e, 0x0804, 0x35b5, 0x614c, 0x6250, 0x7884, 0x604e, - 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305, 0x6816, 0x788c, - 0x2069, 0x1986, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014, 0x1210, - 0x2031, 0x07d0, 0x2069, 0x1987, 0x2d04, 0x266a, 0x789a, 0x0804, - 0x35b5, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a, 0x910e, - 0xd1b4, 0x190c, 0x0ebe, 0xd094, 0x0148, 0x00e6, 0x2071, 0x19fb, - 0x79b4, 0x9192, 0x07d0, 0x1208, 0x713e, 0x00ee, 0xd0c4, 0x01a8, - 0x00d6, 0x78a8, 0x2009, 0x199d, 0x200a, 0x78ac, 0x2011, 0x199e, - 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, - 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x7888, 0xd0ec, 0x0178, - 0x6034, 0xc08d, 0x6036, 0x2001, 0x0050, 0x6076, 0x607a, 0x6056, - 0x606b, 0x2450, 0x00c6, 0x2061, 0x1ad1, 0x2062, 0x00ce, 0x2011, - 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0080, 0x0010, - 0x918c, 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, - 0x788c, 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, - 0x190c, 0x0ed4, 0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, - 0x0001, 0x090c, 0x42ec, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, - 0x0114, 0x2012, 0x012e, 0x0804, 0x35b5, 0x00f6, 0x2079, 0x1800, - 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, - 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, - 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, - 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x35ea, 0x788c, - 0x902d, 0x0904, 0x35ea, 0x900e, 0x080c, 0x6724, 0x1120, 0xba44, - 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, - 0x080c, 0x4c17, 0x0904, 0x35ea, 0x7888, 0x900d, 0x0904, 0x35ea, - 0x788c, 0x9005, 0x0904, 0x35ea, 0xba44, 0xb946, 0xbb38, 0xb83a, - 0x0804, 0x35b5, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, - 0x57e9, 0x1904, 0x35e7, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, - 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, - 0x9182, 0x007f, 0x16e0, 0x9188, 0x33b6, 0x210d, 0x918c, 0x00ff, - 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, - 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0xb27d, 0x000e, - 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x66bf, 0x2b08, - 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4be4, 0x01d0, - 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, - 0x701f, 0x3ac5, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xb352, - 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x35e7, 0x00ce, - 0x0804, 0x35ea, 0x080c, 0xb2d3, 0x0cb0, 0xa830, 0x9086, 0x0100, - 0x0904, 0x35e7, 0x0804, 0x35b5, 0x2061, 0x1a74, 0x0126, 0x2091, - 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, - 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, - 0x0804, 0x35b5, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x35e7, - 0x080c, 0x7637, 0x0904, 0x35e7, 0x0126, 0x2091, 0x8000, 0x6254, - 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x28dc, 0x080c, - 0x5a11, 0x012e, 0x0804, 0x35b5, 0x012e, 0x0804, 0x35ea, 0x0006, - 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070, 0x2061, 0x1847, - 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x9375, 0x7206, - 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, - 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x35b7, 0x7884, - 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, - 0x00e1, 0x0298, 0x012e, 0x0804, 0x35ea, 0x2001, 0x002a, 0x2004, - 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, - 0x0804, 0x35ea, 0x012e, 0x0804, 0x35e7, 0x080c, 0xb23d, 0x0dd0, - 0x7884, 0xd0fc, 0x0904, 0x3b94, 0x00c6, 0x080c, 0x4be4, 0x00ce, - 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, - 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, - 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, - 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, - 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, - 0x8004, 0xa816, 0x080c, 0x3d1a, 0x0928, 0x7014, 0x2048, 0xad2c, - 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, - 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, - 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c2d, 0x701f, 0x3c57, - 0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, - 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3aff, 0x2001, - 0x19a0, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, - 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, - 0x3d89, 0x080c, 0x3d48, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, - 0x1a69, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, - 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, - 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x4130, 0x008e, 0x00ee, - 0x00fe, 0x080c, 0x4052, 0x080c, 0x3f57, 0x05b8, 0x2001, 0x020b, - 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x41a4, 0x00f6, 0x2079, - 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, - 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, - 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, - 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, - 0x2001, 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, - 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3f61, 0x080c, - 0x3d43, 0x0058, 0x080c, 0x3d43, 0x080c, 0x40c8, 0x080c, 0x4048, - 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, - 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, - 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, - 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, - 0x12fc, 0x2009, 0x0028, 0x080c, 0x2409, 0x2001, 0x0227, 0x200c, - 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, - 0x008e, 0x004e, 0x2001, 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, - 0x0804, 0x35b5, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b7, 0x0016, - 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, - 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, - 0x9005, 0x0904, 0x3cb3, 0x2048, 0x1f04, 0x3c67, 0x7068, 0x2040, - 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, - 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, - 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c2d, 0x701f, - 0x3c57, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, - 0x0006, 0x080c, 0x0f8b, 0x000e, 0x080c, 0x4c30, 0x701f, 0x3c57, + 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, 0x7003, 0x0002, + 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, + 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, 0x080c, 0x1027, + 0x090c, 0x0dc5, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, + 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x706e, 0xa867, 0x0002, + 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, 0x0002, 0x34db, + 0x34dc, 0x34ef, 0x3503, 0x0005, 0x1004, 0x34ec, 0x0e04, 0x34ec, + 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, + 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, + 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, + 0x9086, 0x0200, 0x0904, 0x35d7, 0x0005, 0x7018, 0x2048, 0x2061, + 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, + 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, + 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, + 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, + 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x35d4, 0x61d0, 0x0804, + 0x3569, 0x35ab, 0x35e3, 0x35d4, 0x35ef, 0x35f9, 0x35ff, 0x3603, + 0x3613, 0x3617, 0x362d, 0x3633, 0x3639, 0x3644, 0x364f, 0x365e, + 0x366d, 0x367b, 0x3692, 0x36ad, 0x35d4, 0x3756, 0x3794, 0x383a, + 0x384b, 0x386e, 0x35d4, 0x35d4, 0x35d4, 0x38a6, 0x38c2, 0x38cb, + 0x38fa, 0x3900, 0x35d4, 0x3946, 0x35d4, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x3951, 0x395a, 0x3962, 0x3964, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x35d4, 0x35d4, 0x3990, 0x35d4, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x39ad, 0x3a22, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x0002, 0x3a4c, 0x3a4f, 0x3aae, 0x3ac7, 0x3af7, 0x3d99, + 0x35d4, 0x5396, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4, + 0x35d4, 0x35d4, 0x362d, 0x3633, 0x42ce, 0x57f7, 0x42ec, 0x5425, + 0x5477, 0x5582, 0x35d4, 0x55e4, 0x5620, 0x5651, 0x5759, 0x567e, + 0x56d9, 0x35d4, 0x42f0, 0x44b6, 0x44cc, 0x44f1, 0x4556, 0x45ca, + 0x45ea, 0x4661, 0x46bd, 0x4719, 0x471c, 0x4741, 0x47f8, 0x485e, + 0x4866, 0x499b, 0x4b13, 0x4b47, 0x4dab, 0x35d4, 0x4dc9, 0x4e6f, + 0x4f58, 0x4fb2, 0x35d4, 0x5069, 0x35d4, 0x50d5, 0x50f0, 0x4866, + 0x5336, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x4bc5, 0x0126, + 0x2091, 0x8000, 0x0e04, 0x35b5, 0x0010, 0x012e, 0x0cc0, 0x7c36, + 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, + 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, + 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, + 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, + 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, + 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4bd2, 0x2039, + 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, + 0x4bd5, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x35ab, 0x7984, + 0x2114, 0x0804, 0x35ab, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, + 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, + 0x7b8c, 0x0804, 0x35ab, 0x7884, 0x2060, 0x0804, 0x3660, 0x2009, + 0x0003, 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0137, 0x7893, + 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, + 0x35ab, 0x7897, 0x0001, 0x0804, 0x35ab, 0x2039, 0x0001, 0x7d98, + 0x7c9c, 0x0804, 0x35e7, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, + 0x35f3, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e0, 0x2138, + 0x7d98, 0x7c9c, 0x0804, 0x35e7, 0x79a0, 0x9182, 0x0040, 0x0210, + 0x0804, 0x35e0, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x35f3, 0x79a0, + 0x9182, 0x0040, 0x0210, 0x0804, 0x35e0, 0x21e8, 0x7984, 0x7888, + 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x35ab, 0x2061, 0x0800, + 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, + 0x9005, 0x0904, 0x35ab, 0x0804, 0x35da, 0x79a0, 0x9182, 0x0040, + 0x0210, 0x0804, 0x35e0, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, + 0x4012, 0x0804, 0x35ab, 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, + 0x1a04, 0x35e0, 0x8019, 0x0904, 0x35e0, 0x684a, 0x6942, 0x788c, + 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x787f, + 0x0804, 0x35ab, 0x2069, 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, + 0x35e0, 0x8019, 0x0904, 0x35e0, 0x684e, 0x6946, 0x788c, 0x6862, + 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6b2a, 0x012e, 0x0804, 0x35ab, 0x902e, 0x2520, 0x81ff, + 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x7984, 0x7b88, 0x7a8c, + 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, + 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2009, 0x0020, + 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4bd2, 0x701f, 0x36d1, + 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, + 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, + 0x0120, 0x9096, 0x0029, 0x1904, 0x35dd, 0x810f, 0x918c, 0x00ff, + 0x0904, 0x35dd, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, + 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2009, 0x0020, + 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, + 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, + 0x0019, 0xaf60, 0x080c, 0x4bd2, 0x701f, 0x370f, 0x0005, 0xa864, + 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, + 0x35dd, 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, + 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, + 0x6298, 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, + 0x0050, 0x080c, 0x65c8, 0x1128, 0x7007, 0x0003, 0x701f, 0x373b, + 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, + 0x20e1, 0x0001, 0x2099, 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, + 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, + 0x2009, 0x0020, 0x012e, 0xaf60, 0x0804, 0x4bd5, 0x2091, 0x8000, + 0x7837, 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, + 0x788b, 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, + 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, + 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, + 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, + 0x2001, 0x1a1d, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, + 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, + 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x35dd, 0x7984, + 0x080c, 0x671d, 0x1904, 0x35e0, 0x7e98, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x1a04, 0x35e0, 0x7c88, 0x7d8c, 0x080c, 0x6880, 0x080c, + 0x684f, 0x0000, 0x1518, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, + 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, + 0x9406, 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a04, 0x35dd, 0x0c30, 0x080c, + 0xca71, 0x012e, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x900e, 0x2001, + 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd152, + 0x080c, 0x6dd1, 0x012e, 0x0804, 0x35ab, 0x00a6, 0x2950, 0xb198, + 0x080c, 0x671d, 0x1904, 0x3827, 0xb6a4, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x6880, 0x080c, 0x684f, + 0x1520, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, + 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, + 0xa870, 0x9506, 0x0158, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, + 0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xca71, + 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, + 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd152, 0x080c, + 0x6dc4, 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, + 0x0005, 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, + 0x00ae, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4ba0, 0x0904, + 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x080c, 0x6886, 0x0904, + 0x35dd, 0x0804, 0x45e1, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4bbc, + 0x0904, 0x35e0, 0x080c, 0x6914, 0x0904, 0x35dd, 0x2019, 0x0005, + 0x79a8, 0x080c, 0x68a1, 0x0904, 0x35dd, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x35e0, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8717, + 0x79a8, 0xd184, 0x1904, 0x35ab, 0x0804, 0x45e1, 0x0126, 0x2091, + 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, + 0x645c, 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x671d, 0x11d8, + 0x080c, 0x6914, 0x1128, 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, + 0x2019, 0x0004, 0x900e, 0x080c, 0x68a1, 0x1118, 0x2009, 0x0006, + 0x0078, 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, + 0x9108, 0x080c, 0x8717, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x35ab, + 0x012e, 0x0804, 0x35dd, 0x012e, 0x0804, 0x35e0, 0x080c, 0x4ba0, + 0x0904, 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0xbaa0, 0x2019, + 0x0005, 0x00c6, 0x9066, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, + 0x93b3, 0x900e, 0x080c, 0xe690, 0x007e, 0x00ce, 0x080c, 0x6880, + 0x0804, 0x35ab, 0x080c, 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6880, + 0x2208, 0x0804, 0x35ab, 0x0156, 0x00d6, 0x00e6, 0x2069, 0x1910, + 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, + 0x20a9, 0x007e, 0x2069, 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, + 0x0059, 0x9210, 0x8d68, 0x1f04, 0x38dc, 0x2300, 0x9218, 0x00ee, + 0x00de, 0x015e, 0x0804, 0x35ab, 0x00f6, 0x0016, 0x907d, 0x0138, + 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, + 0x00fe, 0x0005, 0x2069, 0x1910, 0x6910, 0x62bc, 0x0804, 0x35ab, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x0126, 0x2091, + 0x8000, 0x080c, 0x57e7, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, + 0x35dd, 0x012e, 0x615c, 0x9190, 0x33ac, 0x2215, 0x9294, 0x00ff, + 0x637c, 0x83ff, 0x0108, 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, + 0x000a, 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, + 0x0022, 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, + 0x0012, 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x7569, 0x1118, + 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, + 0x35dd, 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x35ab, 0x614c, 0x6250, + 0x2019, 0x1987, 0x231c, 0x2001, 0x1988, 0x2004, 0x789a, 0x0804, + 0x35ab, 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, + 0x0804, 0x35ab, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0xba44, 0xbb38, + 0x0804, 0x35ab, 0x080c, 0x0dc5, 0x080c, 0x4bbc, 0x2110, 0x0904, + 0x35e0, 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, + 0xff00, 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x35dd, 0x0126, + 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0xaa9a, + 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x900e, 0x080c, + 0xe690, 0x007e, 0x00ce, 0xb807, 0x0407, 0x012e, 0x0804, 0x35ab, + 0x614c, 0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, + 0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x1987, 0x2d1c, 0x206a, + 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1988, + 0x2d04, 0x266a, 0x789a, 0x0804, 0x35ab, 0x0126, 0x2091, 0x8000, + 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0ebe, 0xd094, + 0x0148, 0x00e6, 0x2071, 0x19fc, 0x79b4, 0x9192, 0x07d0, 0x1208, + 0x713e, 0x00ee, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e, + 0x200a, 0x78ac, 0x2011, 0x199f, 0x2012, 0x2069, 0x0100, 0x6838, + 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, + 0x00de, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, + 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, + 0x6140, 0x910d, 0x788c, 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, + 0x910e, 0xd1e4, 0x190c, 0x0ed4, 0x9084, 0x0020, 0x0130, 0x78b4, + 0x6046, 0x9084, 0x0001, 0x090c, 0x42ce, 0x6040, 0xd0cc, 0x0120, + 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x35ab, 0x00f6, + 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, + 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, + 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, + 0x35e0, 0x788c, 0x902d, 0x0904, 0x35e0, 0x900e, 0x080c, 0x671d, + 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, + 0x8108, 0x0ca0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x7888, 0x900d, + 0x0904, 0x35e0, 0x788c, 0x9005, 0x0904, 0x35e0, 0xba44, 0xb946, + 0xbb38, 0xb83a, 0x0804, 0x35ab, 0x2011, 0xbc09, 0x0010, 0x2011, + 0xbc05, 0x080c, 0x57e7, 0x1904, 0x35dd, 0x00c6, 0x2061, 0x0100, + 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, + 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x33ac, 0x210d, + 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, + 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, + 0xb0ab, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, + 0x66b8, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, + 0x4b89, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, + 0xc0fd, 0xa86a, 0x701f, 0x3aa7, 0x2900, 0x6016, 0x2009, 0x0032, + 0x080c, 0xb180, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, + 0x35dd, 0x00ce, 0x0804, 0x35e0, 0x080c, 0xb101, 0x0cb0, 0xa830, + 0x9086, 0x0100, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x2061, 0x1a75, + 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, + 0x2061, 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, + 0x78aa, 0x012e, 0x0804, 0x35ab, 0x900e, 0x2110, 0x0c88, 0x81ff, + 0x1904, 0x35dd, 0x080c, 0x7569, 0x0904, 0x35dd, 0x0126, 0x2091, + 0x8000, 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, + 0x28fd, 0x080c, 0x5a0a, 0x012e, 0x0804, 0x35ab, 0x012e, 0x0804, + 0x35e0, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19ab, 0x2070, + 0x2061, 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, + 0x91b1, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, + 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, + 0x35ad, 0x7884, 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, + 0x0180, 0x9082, 0x00e1, 0x0298, 0x012e, 0x0804, 0x35e0, 0x2001, + 0x002a, 0x2004, 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, + 0x1230, 0x012e, 0x0804, 0x35e0, 0x012e, 0x0804, 0x35dd, 0x080c, + 0xb06b, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3b76, 0x00c6, 0x080c, + 0x4b89, 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, + 0xa80e, 0x789c, 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, + 0x002f, 0x2004, 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, + 0x0031, 0x2004, 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, + 0x0035, 0x2004, 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, + 0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, 0x3cfc, 0x0928, 0x7014, + 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, + 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4bd2, + 0x701f, 0x3c39, 0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, + 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, + 0x3ae1, 0x2001, 0x19a1, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, + 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, + 0x0012, 0x080c, 0x3d6b, 0x080c, 0x3d2a, 0x00f6, 0x00e6, 0x0086, + 0x2940, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, + 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, + 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x4112, + 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4034, 0x080c, 0x3f39, 0x05b8, + 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x4186, + 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, + 0x2071, 0x0200, 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, + 0x3200, 0x1510, 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, + 0xe100, 0x11d0, 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, + 0x9106, 0x1190, 0x2001, 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, + 0x2061, 0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, + 0x3f43, 0x080c, 0x3d25, 0x0058, 0x080c, 0x3d25, 0x080c, 0x40aa, + 0x080c, 0x402a, 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, + 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, + 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, + 0x0108, 0x60bf, 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, + 0x2102, 0x080c, 0x12fc, 0x2009, 0x0028, 0x080c, 0x2432, 0x2001, + 0x0227, 0x200c, 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, + 0x00ae, 0x009e, 0x008e, 0x004e, 0x2001, 0x19a1, 0x2004, 0x9005, + 0x1118, 0x012e, 0x0804, 0x35ab, 0x012e, 0x2021, 0x400c, 0x0804, + 0x35ad, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, + 0x0096, 0x00d6, 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, + 0x7022, 0xa804, 0x9005, 0x0904, 0x3c95, 0x2048, 0x1f04, 0x3c49, + 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, + 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, + 0x2048, 0xa864, 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, + 0x4bd2, 0x701f, 0x3c39, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, + 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f8b, 0x000e, 0x080c, 0x4bd5, + 0x701f, 0x3c39, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, + 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, + 0x9086, 0x0103, 0x1118, 0x701f, 0x3cfa, 0x0450, 0x7014, 0x2048, + 0xa868, 0xc0fd, 0xa86a, 0x2009, 0x007f, 0x080c, 0x66b2, 0x0110, + 0x9006, 0x0030, 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd325, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, - 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, - 0x1118, 0x701f, 0x3d18, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, - 0xa86a, 0x2009, 0x007f, 0x080c, 0x66b9, 0x0110, 0x9006, 0x0030, - 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd5a7, 0x015e, 0x00de, - 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, - 0x0904, 0x35e7, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, - 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3cea, 0x7007, 0x0003, - 0x0804, 0x3ca8, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, - 0x35b7, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, - 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, - 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, - 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f8b, 0x000e, - 0x080c, 0x4c30, 0x007e, 0x701f, 0x3c57, 0x7023, 0x0001, 0x0005, - 0x0804, 0x35b5, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, - 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, - 0x080c, 0x4be4, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, - 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, - 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, - 0x00fe, 0x000e, 0x0005, 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, - 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, - 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, - 0xc1ac, 0x6106, 0x080c, 0x4be4, 0xa813, 0x0019, 0xa817, 0x0001, - 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, - 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, - 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2409, 0x2001, 0x002a, - 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, - 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, - 0x0005, 0x00e6, 0x080c, 0x4be4, 0x2940, 0xa013, 0x0019, 0xa017, - 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, - 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, - 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, - 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, - 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, - 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2c59, 0x1130, 0x9006, - 0x080c, 0x2bb1, 0x9006, 0x080c, 0x2b94, 0x2001, 0x199f, 0x2003, - 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3dd8, 0x3de1, 0x3dea, - 0x3dd5, 0x3dd5, 0x3dd5, 0x3dd5, 0x3dd5, 0x012e, 0x0804, 0x35ea, - 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3fab, - 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085, 0x4000, 0x200a, 0x080c, - 0x3fab, 0x0078, 0x080c, 0x7637, 0x1128, 0x012e, 0x2009, 0x0016, - 0x0804, 0x35e7, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, - 0x35b7, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0db0, 0x0086, 0x0096, - 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3aff, - 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, - 0x2060, 0x2058, 0x080c, 0x427f, 0x080c, 0x41cf, 0x903e, 0x2720, - 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a69, 0x2079, 0x0090, - 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, - 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x4130, 0x080c, - 0x2c61, 0x080c, 0x2c61, 0x080c, 0x2c61, 0x080c, 0x2c61, 0x080c, - 0x4130, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4052, 0x2009, 0x9c40, - 0x8109, 0x11b0, 0x080c, 0x3f61, 0x2001, 0x0004, 0x200c, 0x918c, - 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, - 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35e7, 0x0cf8, - 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, - 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, - 0x81ff, 0x0150, 0x080c, 0x4030, 0x2d00, 0x9c05, 0x9b05, 0x0120, - 0x080c, 0x3f61, 0x0804, 0x3f0e, 0x080c, 0x41a4, 0x080c, 0x40c8, - 0x080c, 0x4013, 0x080c, 0x4048, 0x00f6, 0x2079, 0x0100, 0x7824, - 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3f61, 0x00fe, 0x0804, 0x3f0e, - 0x00fe, 0x080c, 0x3f57, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, - 0x2001, 0x0033, 0x2502, 0x080c, 0x3f61, 0x0080, 0x87ff, 0x0138, - 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, - 0x1a65, 0x2004, 0x9086, 0x0000, 0x1904, 0x3e5e, 0x2001, 0x032f, - 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, - 0x3f0e, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, - 0x3f0e, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, - 0xd0ac, 0x1148, 0x2001, 0x1a65, 0x2003, 0x0003, 0x2001, 0x032a, - 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, - 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2409, 0x2900, - 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, - 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, - 0x0203, 0x2004, 0x1f04, 0x3ee5, 0x00ce, 0x0030, 0xa817, 0x0001, - 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, - 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, - 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, - 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3e18, 0x001e, 0x00c6, - 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, - 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, - 0x918c, 0xfffd, 0x2102, 0x080c, 0x12fc, 0x7884, 0x9084, 0x0003, - 0x9086, 0x0002, 0x01a0, 0x2009, 0x0028, 0x080c, 0x2409, 0x2001, - 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ef, 0x6052, 0x602f, - 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce, - 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, - 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, - 0x0804, 0x35b5, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b7, 0x9085, - 0x0001, 0x1d04, 0x3f60, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, - 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, - 0x0004, 0x2001, 0x1a65, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, - 0x080c, 0x2409, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, - 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a69, - 0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, - 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, - 0x080c, 0x2409, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x41a4, 0x7000, - 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, - 0x2009, 0x0040, 0x080c, 0x2409, 0x782b, 0x0002, 0x7003, 0x0000, - 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, - 0x200c, 0x7932, 0x7936, 0x080c, 0x28bc, 0x7850, 0x9084, 0xfbff, - 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, - 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3fc6, - 0x2091, 0x6000, 0x1f04, 0x3fc6, 0x7850, 0x9085, 0x0400, 0x9084, - 0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, - 0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, - 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, - 0x3fe6, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, - 0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, - 0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, - 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2d39, - 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2d39, 0x7827, - 0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, - 0x2071, 0x1a65, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, - 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, - 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, - 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, - 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, - 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, - 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, - 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19ab, 0x2004, - 0x70e2, 0x080c, 0x3d39, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, - 0x181f, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, - 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, - 0x702e, 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, - 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, - 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, - 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, - 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, - 0x41a4, 0x00f6, 0x2071, 0x1a65, 0x2079, 0x0320, 0x00d6, 0x2069, - 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, - 0x00de, 0x080c, 0x3d39, 0x0140, 0x2001, 0x199f, 0x200c, 0x2003, - 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, 0x8109, 0x1df0, - 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, 0x080c, - 0x4130, 0x2011, 0x0001, 0x080c, 0x4130, 0x00fe, 0x00ee, 0x0005, - 0x00f6, 0x00e6, 0x2071, 0x1a65, 0x2079, 0x0320, 0x792c, 0xd1fc, - 0x0904, 0x412d, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, 0x4129, - 0x7000, 0x0002, 0x412d, 0x40de, 0x410e, 0x4129, 0xd1bc, 0x1170, - 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, 0x4130, - 0x0904, 0x412d, 0x080c, 0x4130, 0x0804, 0x412d, 0x00f6, 0x2079, - 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, 0x0004, - 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, - 0x4030, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe, - 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, 0x7002, - 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x40d2, 0x2011, - 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, 0x0015, - 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, 0x1960, - 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, - 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, 0xa058, - 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, 0x938a, - 0x0007, 0x1a0c, 0x0dc5, 0x9398, 0x415e, 0x231d, 0x083f, 0x9080, - 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, 0x908a, - 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, 0x2001, - 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x419b, 0x4192, - 0x4189, 0x4180, 0x4177, 0x416e, 0x4165, 0xa964, 0x7902, 0xa968, - 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, 0x7902, - 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, 0xa984, - 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, 0x0005, - 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, 0x7916, - 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, 0xa9b0, - 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, 0x7912, - 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, 0xa9cc, - 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, 0x2071, - 0x1a69, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, 0x0002, - 0x2940, 0x9026, 0x7000, 0x0002, 0x41cb, 0x41b7, 0x41c2, 0x8001, - 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x4130, 0x190c, - 0x4130, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, 0x1d38, 0x2011, - 0x0001, 0x080c, 0x4130, 0x008e, 0x00ee, 0x00fe, 0x0005, 0x00f6, - 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, - 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, - 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, 0x2038, - 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, 0x4be4, - 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, - 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, - 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x4247, 0x1d68, - 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4be4, 0xa813, 0x0019, 0xa817, - 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, - 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, - 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, 0x2079, - 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, - 0x2409, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, - 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x9006, - 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, - 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, 0x2099, - 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, 0x700e, - 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, 0x702c, - 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, 0x7400, - 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, 0x080c, - 0x4be4, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, 0xa05a, - 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, - 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, 0x0030, - 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4be4, 0x2940, 0xa813, - 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, - 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, - 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x4247, 0x1d68, 0x2900, - 0xa85a, 0x00d8, 0x080c, 0x4be4, 0x2940, 0xa013, 0x0019, 0xa017, - 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, 0x2001, - 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, - 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, 0x2003, - 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, 0x918d, - 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a65, 0x2003, 0x0003, - 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000, - 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, - 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x20a9, - 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, 0x20a9, - 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004, 0x2009, - 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, 0x0005, - 0x0804, 0x35b5, 0x7d98, 0x7c9c, 0x0804, 0x36b9, 0x080c, 0x7637, - 0x190c, 0x60f3, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069, 0x1847, - 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, - 0x0001, 0x080c, 0x4c2d, 0x701f, 0x4326, 0x0005, 0x080c, 0x57e4, - 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, - 0x1847, 0x6800, 0x9005, 0x0904, 0x35ea, 0x2001, 0x180d, 0x2004, - 0xd08c, 0x6804, 0x0118, 0xc0a4, 0xc0ac, 0x6806, 0xd0ac, 0x0118, - 0xd0a4, 0x0904, 0x35ea, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, - 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010, - 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, - 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106, - 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x35ea, - 0x9288, 0x33b6, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc, 0x0130, - 0x6828, 0x908a, 0x007f, 0x1a04, 0x35ea, 0x605e, 0x6888, 0x9084, - 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x19b2, - 0x9080, 0x29b7, 0x2005, 0x200a, 0x000e, 0x2009, 0x19b3, 0x9080, - 0x29bb, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x35ea, - 0x908a, 0x0841, 0x1a04, 0x35ea, 0x9084, 0x0007, 0x1904, 0x35ea, - 0x680c, 0x9005, 0x0904, 0x35ea, 0x6810, 0x9005, 0x0904, 0x35ea, - 0x6848, 0x6940, 0x910a, 0x1a04, 0x35ea, 0x8001, 0x0904, 0x35ea, - 0x684c, 0x6944, 0x910a, 0x1a04, 0x35ea, 0x8001, 0x0904, 0x35ea, - 0x2009, 0x1981, 0x200b, 0x0000, 0x2001, 0x1869, 0x2004, 0xd0c4, - 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, 0x0e52, 0x3b00, 0xc085, - 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084, 0x00ff, - 0x6052, 0x080c, 0x7963, 0x080c, 0x6b8e, 0x080c, 0x6bf8, 0x6808, - 0x602a, 0x080c, 0x237b, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, - 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2916, 0x003e, - 0x6000, 0x9086, 0x0000, 0x1904, 0x44cf, 0x6818, 0x691c, 0x6a20, - 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, - 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, - 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006, - 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9, - 0x0004, 0x20a1, 0x19b4, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004, - 0x20a1, 0x19ce, 0x20e9, 0x0001, 0x4001, 0x080c, 0x8962, 0x00c6, - 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0510, 0x0068, 0x2009, - 0x0100, 0x210c, 0x918e, 0x0008, 0x1110, 0x839d, 0x0010, 0x83f5, - 0x3e18, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7f6f, 0x6878, 0x6016, - 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, - 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, - 0x1f04, 0x441f, 0x00ce, 0x00c6, 0x2061, 0x199c, 0x2001, 0x180d, - 0x2004, 0xd08c, 0x11a8, 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, - 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c, 0x2bb1, - 0x2001, 0x0001, 0x080c, 0x2b94, 0x0088, 0x9286, 0x4000, 0x1148, - 0x2063, 0x0001, 0x9006, 0x080c, 0x2bb1, 0x9006, 0x080c, 0x2b94, - 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce, 0x00e6, - 0x2c70, 0x080c, 0x0ea3, 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, - 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x6a80, 0x9284, 0x0030, - 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, - 0x2001, 0x197c, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, - 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, - 0x080c, 0x298b, 0x2001, 0x196d, 0x2102, 0x0008, 0x2102, 0x00c6, - 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, - 0x7637, 0x0128, 0x080c, 0x50cb, 0x0110, 0x080c, 0x28dc, 0x60d4, - 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x44b7, 0x00e0, 0x080c, - 0x7637, 0x1168, 0x2011, 0x74b2, 0x080c, 0x883d, 0x2011, 0x74a5, - 0x080c, 0x8917, 0x080c, 0x7937, 0x080c, 0x7563, 0x0040, 0x080c, - 0x5fed, 0x0028, 0x6003, 0x0004, 0x2009, 0x44cf, 0x0020, 0x080c, - 0x6a05, 0x0804, 0x35b5, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, - 0x9086, 0x004c, 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, - 0x0817, 0x6000, 0x9086, 0x0000, 0x0904, 0x35e7, 0x2069, 0x1847, - 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, - 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x4c30, 0x9006, - 0x080c, 0x28dc, 0x81ff, 0x1904, 0x35e7, 0x080c, 0x7637, 0x11b0, - 0x080c, 0x7932, 0x080c, 0x612e, 0x080c, 0x33aa, 0x0118, 0x6130, - 0xc18d, 0x6132, 0x080c, 0xd7e3, 0x0130, 0x080c, 0x765a, 0x1118, - 0x080c, 0x760f, 0x0038, 0x080c, 0x7563, 0x0020, 0x080c, 0x60f3, - 0x080c, 0x5fed, 0x0804, 0x35b5, 0x81ff, 0x1904, 0x35e7, 0x080c, - 0x7637, 0x1110, 0x0804, 0x35e7, 0x0126, 0x2091, 0x8000, 0x6194, - 0x81ff, 0x0190, 0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, - 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c30, - 0x701f, 0x35b3, 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, - 0x1c80, 0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, - 0xffff, 0x4304, 0x655c, 0x9588, 0x33b6, 0x210d, 0x918c, 0x00ff, - 0x216a, 0x900e, 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, - 0x6724, 0x1190, 0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, - 0xff00, 0x8007, 0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, - 0xff00, 0x9405, 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, - 0x0c18, 0x8201, 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, - 0x0040, 0x20a1, 0x1c80, 0x2099, 0x1c80, 0x080c, 0x607e, 0x0804, - 0x452c, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x080c, 0x4be4, 0x1120, - 0x2009, 0x0002, 0x0804, 0x35e7, 0x080c, 0x57d5, 0xd0b4, 0x0558, - 0x7884, 0x908e, 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, - 0x0080, 0x0508, 0x080c, 0x33a5, 0x1148, 0xb800, 0xd08c, 0x11d8, - 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, - 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd2a3, 0x1120, 0x2009, 0x0003, - 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x45b7, 0x0005, 0x080c, - 0x4c17, 0x0904, 0x35ea, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, - 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, - 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, - 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x0070, 0x20a9, 0x0004, - 0xa85c, 0x9080, 0x000a, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, - 0x000a, 0x2098, 0x080c, 0x0f8b, 0x8906, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, - 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4c30, 0x81ff, 0x1904, 0x35e7, - 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x6896, 0x0904, 0x35e7, - 0x0058, 0xa878, 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x35e7, - 0xa974, 0xaa94, 0x0804, 0x35b5, 0x080c, 0x57dd, 0x0904, 0x35b5, - 0x701f, 0x4601, 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x35e7, - 0x7888, 0x908a, 0x1000, 0x1a04, 0x35ea, 0x080c, 0x4c17, 0x0904, - 0x35ea, 0x080c, 0x6aa3, 0x0120, 0x080c, 0x6aab, 0x1904, 0x35ea, - 0x080c, 0x691b, 0x0904, 0x35e7, 0x2019, 0x0004, 0x900e, 0x080c, - 0x68a8, 0x0904, 0x35e7, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, - 0x908a, 0x1000, 0x12f8, 0x080c, 0x4c15, 0x01e0, 0x080c, 0x6aa3, - 0x0118, 0x080c, 0x6aab, 0x11b0, 0x080c, 0x691b, 0x2009, 0x0002, - 0x0168, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x68a8, 0x2009, - 0x0003, 0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, - 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, - 0x0030, 0x0005, 0xa897, 0x4000, 0x080c, 0x57dd, 0x0110, 0x9006, - 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, - 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, - 0x645c, 0x2400, 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, - 0x0005, 0x080c, 0x6724, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, - 0x9108, 0x080c, 0x884b, 0x0005, 0x81ff, 0x1904, 0x35e7, 0x798c, - 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4bfb, 0x0904, - 0x35ea, 0x080c, 0x6aa3, 0x0120, 0x080c, 0x6aab, 0x1904, 0x35ea, - 0x080c, 0x67eb, 0x0904, 0x35e7, 0x080c, 0x689f, 0x0904, 0x35e7, - 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, 0x35b5, 0x0804, 0x460c, - 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, - 0x4c08, 0x01a0, 0x080c, 0x6aa3, 0x0118, 0x080c, 0x6aab, 0x1170, - 0x080c, 0x67eb, 0x2009, 0x0002, 0x0128, 0x080c, 0x689f, 0x1170, - 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, - 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57dd, 0x0110, - 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, - 0x81ff, 0x1904, 0x35e7, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, - 0x2102, 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x6aa3, 0x0120, - 0x080c, 0x6aab, 0x1904, 0x35ea, 0x080c, 0x67eb, 0x0904, 0x35e7, - 0x080c, 0x688d, 0x0904, 0x35e7, 0x2001, 0x197f, 0x2004, 0xd0fc, - 0x1904, 0x35b5, 0x0804, 0x460c, 0xa9a0, 0x2001, 0x197f, 0x918c, - 0x8000, 0xc18d, 0x2102, 0x080c, 0x4c08, 0x01a0, 0x080c, 0x6aa3, - 0x0118, 0x080c, 0x6aab, 0x1170, 0x080c, 0x67eb, 0x2009, 0x0002, - 0x0128, 0x080c, 0x688d, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, - 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, - 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, - 0x1128, 0x080c, 0x57dd, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0000, 0x0005, 0x6100, 0x0804, 0x35b5, 0x080c, - 0x4c17, 0x0904, 0x35ea, 0x080c, 0x57e9, 0x1904, 0x35e7, 0x79a8, - 0xd184, 0x1158, 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, - 0xbb2c, 0x831f, 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, - 0xb820, 0x8007, 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, - 0x918c, 0x0202, 0x0804, 0x35b5, 0x78a8, 0x909c, 0x0003, 0xd0ac, - 0x1158, 0xd0b4, 0x1148, 0x939a, 0x0003, 0x1a04, 0x35e7, 0x625c, - 0x7884, 0x9206, 0x1904, 0x47c7, 0x080c, 0x894c, 0x2001, 0xffec, - 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, - 0x0006, 0x78a8, 0x9084, 0x0080, 0x1528, 0x0006, 0x0036, 0x2001, - 0x1a83, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a84, 0x201c, - 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a85, 0x201c, 0x7bae, 0x2003, - 0x0000, 0x2001, 0x1a7f, 0x201c, 0x7baa, 0x2003, 0x0000, 0x2001, - 0x1a86, 0x201c, 0x7bb2, 0x2003, 0x0000, 0x003e, 0x000e, 0x000e, - 0x0804, 0x4c30, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, - 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, - 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x47e7, 0x0005, 0x81ff, - 0x1904, 0x35e7, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x080c, 0x6aa3, - 0x1904, 0x35e7, 0x00c6, 0x080c, 0x4be4, 0x00ce, 0x0904, 0x35e7, - 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xd249, - 0x0904, 0x35e7, 0x7007, 0x0003, 0x701f, 0x480d, 0x0005, 0x080c, - 0x42ec, 0x0006, 0x0036, 0x2001, 0x1a83, 0x201c, 0x7b9a, 0x2003, - 0x0000, 0x2001, 0x1a84, 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, - 0x1a85, 0x201c, 0x7bae, 0x2003, 0x0000, 0x2001, 0x1a7f, 0x201c, - 0x7baa, 0x2003, 0x0000, 0x2001, 0x1a86, 0x201c, 0x7bb2, 0x2003, - 0x0000, 0x003e, 0x000e, 0x0804, 0x35b5, 0xa830, 0x9086, 0x0100, - 0x0904, 0x35e7, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0x0804, 0x4c30, 0x9006, 0x080c, 0x28dc, 0x78a8, 0x9084, - 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x35e7, 0x080c, - 0x7637, 0x0110, 0x080c, 0x60f3, 0x7888, 0x908a, 0x1000, 0x1a04, - 0x35ea, 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, - 0x35ea, 0x2100, 0x080c, 0x28a6, 0x0026, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x2061, 0x19fb, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, - 0x0000, 0x607f, 0x0000, 0x080c, 0x7637, 0x1158, 0x080c, 0x7932, - 0x080c, 0x612e, 0x9085, 0x0001, 0x080c, 0x767b, 0x080c, 0x7563, - 0x00d0, 0x080c, 0xb244, 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, - 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, - 0x0010, 0x2009, 0x1999, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, - 0x6019, 0x080c, 0x88d5, 0x7984, 0x080c, 0x7637, 0x1110, 0x2009, - 0x00ff, 0x7a88, 0x080c, 0x466f, 0x012e, 0x00ce, 0x002e, 0x0804, - 0x35b5, 0x7984, 0x080c, 0x66b9, 0x2b08, 0x1904, 0x35ea, 0x0804, - 0x35b5, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35e7, 0x60dc, - 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35e7, - 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, 0x7984, - 0x81ff, 0x0904, 0x35ea, 0x9192, 0x0021, 0x1a04, 0x35ea, 0x7a8c, - 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, - 0x7736, 0x080c, 0x4c2d, 0x701f, 0x48c4, 0x7880, 0x9086, 0x006e, - 0x0110, 0x701f, 0x527d, 0x0005, 0x2009, 0x0080, 0x080c, 0x6724, - 0x1118, 0x080c, 0x6aa3, 0x0120, 0x2021, 0x400a, 0x0804, 0x35b7, - 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, - 0xa884, 0x90be, 0x0100, 0x0904, 0x495d, 0x90be, 0x0112, 0x0904, - 0x495d, 0x90be, 0x0113, 0x0904, 0x495d, 0x90be, 0x0114, 0x0904, - 0x495d, 0x90be, 0x0117, 0x0904, 0x495d, 0x90be, 0x011a, 0x0904, - 0x495d, 0x90be, 0x011c, 0x0904, 0x495d, 0x90be, 0x0121, 0x0904, - 0x4944, 0x90be, 0x0131, 0x0904, 0x4944, 0x90be, 0x0171, 0x0904, - 0x495d, 0x90be, 0x0173, 0x0904, 0x495d, 0x90be, 0x01a1, 0x1128, - 0xa894, 0x8007, 0xa896, 0x0804, 0x4968, 0x90be, 0x0212, 0x0904, - 0x4951, 0x90be, 0x0213, 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, - 0x0217, 0x0188, 0x90be, 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, - 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, - 0x00de, 0x0804, 0x35ea, 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, - 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c, 0x49a6, 0x7028, - 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, - 0x0001, 0x080c, 0x49a6, 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, - 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49b3, - 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, - 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49b3, 0x7028, 0x9080, 0x000c, - 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, - 0x00c6, 0x080c, 0x4be4, 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, - 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, - 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, - 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, - 0xa804, 0x2048, 0x080c, 0xd264, 0x1120, 0x2009, 0x0003, 0x0804, - 0x35e7, 0x7007, 0x0003, 0x701f, 0x499d, 0x0005, 0x00ce, 0x009e, - 0x00de, 0x2009, 0x0002, 0x0804, 0x35e7, 0xa820, 0x9086, 0x8001, - 0x1904, 0x35b5, 0x2009, 0x0004, 0x0804, 0x35e7, 0x0016, 0x0026, - 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, - 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, - 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, - 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, - 0x2009, 0x0001, 0x0804, 0x35e7, 0x60dc, 0xd0ac, 0x1188, 0x2009, - 0x180d, 0x210c, 0xd18c, 0x0130, 0xd09c, 0x0120, 0x2009, 0x0016, - 0x0804, 0x35e7, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35e7, - 0x7984, 0x78a8, 0x2040, 0x080c, 0xb23d, 0x1120, 0x9182, 0x007f, - 0x0a04, 0x35ea, 0x9186, 0x00ff, 0x0904, 0x35ea, 0x9182, 0x0800, - 0x1a04, 0x35ea, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080, - 0x924e, 0x0904, 0x35ea, 0x080c, 0xb23d, 0x1120, 0x99cc, 0xff00, - 0x0904, 0x35ea, 0x0126, 0x2091, 0x8000, 0x2001, 0x180d, 0x2004, - 0xd08c, 0x0198, 0x9386, 0x00ff, 0x0180, 0x0026, 0x2011, 0x8008, - 0x080c, 0x6ac7, 0x002e, 0x0148, 0x918d, 0x8000, 0x080c, 0x6b11, - 0x1120, 0x2001, 0x4009, 0x0804, 0x4a64, 0x080c, 0x4af7, 0x0904, - 0x4a6a, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6, 0x0006, - 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24, 0x9305, - 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34, 0x9305, - 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6aa3, 0x0110, 0xc89d, - 0x0438, 0x900e, 0x080c, 0x6944, 0x1108, 0xc185, 0xb800, 0xd0bc, - 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, - 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, - 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, - 0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804, 0x35b7, - 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, - 0x2c70, 0x080c, 0xb325, 0x0904, 0x4abf, 0x2b00, 0x6012, 0x080c, - 0xd554, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4be4, 0x00ce, - 0x2b70, 0x1158, 0x080c, 0xb2d3, 0x00ee, 0x00ce, 0x00be, 0x001e, - 0x012e, 0x2009, 0x0002, 0x0804, 0x35e7, 0x900e, 0xa966, 0xa96a, - 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, - 0xa86a, 0xd89c, 0x1110, 0x080c, 0x3250, 0x6023, 0x0001, 0x9006, - 0x080c, 0x6656, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, 0x666a, - 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x666a, 0x2009, - 0x0002, 0x080c, 0xb352, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, - 0x00e6, 0x2058, 0xb8cc, 0xc08d, 0xb8ce, 0x9085, 0x0001, 0x00ee, - 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, - 0x35e7, 0x7007, 0x0003, 0x701f, 0x4ace, 0x0005, 0xa830, 0x2009, - 0x180d, 0x210c, 0xd18c, 0x0140, 0x2008, 0x918e, 0xdead, 0x1120, - 0x2021, 0x4009, 0x0804, 0x35b7, 0x9086, 0x0100, 0x7024, 0x2058, - 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, 0x0804, 0x5729, - 0x900e, 0xa868, 0xd0f4, 0x1904, 0x35b5, 0x080c, 0x6944, 0x1108, - 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35b5, 0x00e6, - 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4b46, 0x902e, 0x080c, 0xb23d, - 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, - 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, - 0x2100, 0x9406, 0x1904, 0x4b57, 0x2428, 0x94ce, 0x007f, 0x1120, - 0x92ce, 0xfffd, 0x1558, 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, - 0xfffc, 0x1520, 0x93ce, 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, - 0xbf10, 0x2700, 0x9306, 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, - 0x2400, 0x9106, 0x1180, 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, - 0x6a43, 0x1570, 0x2001, 0x4000, 0x0460, 0x080c, 0x6aa3, 0x1540, - 0x2001, 0x4000, 0x0430, 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, - 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, - 0x0918, 0x080c, 0xb23d, 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, - 0x8e70, 0x1f04, 0x4b0d, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, - 0x2001, 0x0001, 0x0030, 0x080c, 0x66b9, 0x1dd0, 0xbb12, 0xba16, - 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, - 0x2009, 0x0001, 0x0804, 0x35e7, 0x080c, 0x4be4, 0x1120, 0x2009, - 0x0002, 0x0804, 0x35e7, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, - 0x7884, 0x9005, 0x0904, 0x35ea, 0x9096, 0x00ff, 0x0120, 0x9092, - 0x0004, 0x1a04, 0x35ea, 0x2010, 0x2918, 0x080c, 0x31f6, 0x1120, - 0x2009, 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x4b99, - 0x0005, 0xa830, 0x9086, 0x0100, 0x1904, 0x35b5, 0x2009, 0x0004, - 0x0804, 0x35e7, 0x7984, 0x080c, 0xb23d, 0x1120, 0x9182, 0x007f, - 0x0a04, 0x35ea, 0x9186, 0x00ff, 0x0904, 0x35ea, 0x9182, 0x0800, - 0x1a04, 0x35ea, 0x2001, 0x9400, 0x080c, 0x5784, 0x1904, 0x35e7, - 0x0804, 0x35b5, 0xa998, 0x080c, 0xb23d, 0x1118, 0x9182, 0x007f, - 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, - 0x9400, 0x080c, 0x5784, 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, - 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x0005, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, - 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c, 0x100e, 0x0198, 0x9006, - 0xa802, 0x7014, 0x9005, 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, - 0x7018, 0xa802, 0x0086, 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, - 0x9085, 0x0001, 0x0005, 0x7984, 0x080c, 0x6724, 0x1130, 0x7e88, - 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, - 0xa998, 0x080c, 0x6724, 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, - 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, - 0x2608, 0x080c, 0x6724, 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, - 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148, 0xa904, 0x080c, 0x1040, - 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, + 0x002e, 0x001e, 0x0904, 0x35dd, 0x0016, 0x0026, 0x0036, 0x0046, + 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3ccc, + 0x7007, 0x0003, 0x0804, 0x3c8a, 0xa830, 0x9086, 0x0100, 0x2021, + 0x400c, 0x0904, 0x35ad, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, + 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, + 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, + 0x0f8b, 0x000e, 0x080c, 0x4bd5, 0x007e, 0x701f, 0x3c39, 0x7023, + 0x0001, 0x0005, 0x0804, 0x35ab, 0x0156, 0x00c6, 0xa814, 0x908a, + 0x001e, 0x0218, 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, + 0x0168, 0x0016, 0x080c, 0x4b89, 0x001e, 0x0130, 0xa800, 0x2040, + 0xa008, 0xa80a, 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, + 0x00ce, 0x015e, 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, + 0x9086, 0x0044, 0x00fe, 0x000e, 0x0005, 0x2001, 0x19a1, 0x2003, + 0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, + 0x19ac, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, + 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x080c, 0x4b89, 0xa813, 0x0019, + 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, + 0x2001, 0x002f, 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, + 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2432, + 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, + 0x0000, 0x601f, 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, + 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x080c, 0x4b89, 0x2940, 0xa013, + 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, + 0xa866, 0x2001, 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, + 0x9084, 0xfff8, 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, + 0x0004, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, + 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, + 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2c72, + 0x1130, 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x2001, + 0x19a0, 0x2003, 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3dba, + 0x3dc3, 0x3dcc, 0x3db7, 0x3db7, 0x3db7, 0x3db7, 0x3db7, 0x012e, + 0x0804, 0x35e0, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a, + 0x080c, 0x3f8d, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085, 0x4000, + 0x200a, 0x080c, 0x3f8d, 0x0078, 0x080c, 0x7569, 0x1128, 0x012e, + 0x2009, 0x0016, 0x0804, 0x35dd, 0x81ff, 0x0128, 0x012e, 0x2021, + 0x400b, 0x0804, 0x35ad, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0db0, + 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x080c, 0x3ae1, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, + 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x4261, 0x080c, 0x41b1, + 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a, + 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, + 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, + 0x4112, 0x080c, 0x2c7a, 0x080c, 0x2c7a, 0x080c, 0x2c7a, 0x080c, + 0x2c7a, 0x080c, 0x4112, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4034, + 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3f43, 0x2001, 0x0004, + 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, + 0x35dd, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, + 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, + 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x4012, 0x2d00, 0x9c05, + 0x9b05, 0x0120, 0x080c, 0x3f43, 0x0804, 0x3ef0, 0x080c, 0x4186, + 0x080c, 0x40aa, 0x080c, 0x3ff5, 0x080c, 0x402a, 0x00f6, 0x2079, + 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3f43, 0x00fe, + 0x0804, 0x3ef0, 0x00fe, 0x080c, 0x3f39, 0x1150, 0x8d68, 0x2001, + 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3f43, 0x0080, + 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, + 0x0038, 0x2001, 0x1a66, 0x2004, 0x9086, 0x0000, 0x1904, 0x3e40, + 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, + 0x9605, 0x0904, 0x3ef0, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, + 0x9b05, 0x1904, 0x3ef0, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, + 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a66, 0x2003, 0x0003, + 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, + 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, + 0x2432, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, + 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, + 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3ec7, 0x00ce, 0x0030, + 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, + 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, + 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, + 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3dfa, + 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, + 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, + 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x12fc, 0x7884, + 0x9084, 0x0003, 0x9086, 0x0002, 0x01a0, 0x2009, 0x0028, 0x080c, + 0x2432, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ef, + 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, + 0x0010, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, + 0x1118, 0x012e, 0x0804, 0x35ab, 0x012e, 0x2021, 0x400c, 0x0804, + 0x35ad, 0x9085, 0x0001, 0x1d04, 0x3f42, 0x2091, 0x6000, 0x8420, + 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, + 0x032a, 0x2003, 0x0004, 0x2001, 0x1a66, 0x2003, 0x0000, 0x0071, + 0x2009, 0x0048, 0x080c, 0x2432, 0x2001, 0x0227, 0x2024, 0x2402, + 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, + 0x2071, 0x1a6a, 0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, + 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, + 0x2009, 0x0040, 0x080c, 0x2432, 0x782c, 0xd0fc, 0x0d88, 0x080c, + 0x4186, 0x7000, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, + 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2432, 0x782b, 0x0002, + 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, + 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c, 0x28dd, 0x7850, + 0x9084, 0xfbff, 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, + 0x1df0, 0x9084, 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, + 0x1d04, 0x3fa8, 0x2091, 0x6000, 0x1f04, 0x3fa8, 0x7850, 0x9085, + 0x0400, 0x9084, 0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, + 0x0003, 0x9086, 0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, + 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, + 0xa001, 0x1f04, 0x3fc8, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, + 0x61a8, 0x7854, 0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, + 0x7827, 0x0048, 0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, + 0x2019, 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, + 0x080c, 0x2d52, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, + 0x2d52, 0x7827, 0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, + 0x00f6, 0x00e6, 0x2071, 0x1a66, 0x2079, 0x0320, 0x2001, 0x0201, + 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, + 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, + 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, + 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, + 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, + 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, + 0x19ac, 0x2004, 0x70e2, 0x080c, 0x3d1b, 0x1188, 0x2001, 0x1820, + 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, + 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, + 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, + 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, + 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, + 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, + 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, + 0x7016, 0x080c, 0x4186, 0x00f6, 0x2071, 0x1a66, 0x2079, 0x0320, + 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, + 0x6898, 0x780a, 0x00de, 0x080c, 0x3d1b, 0x0140, 0x2001, 0x19a0, + 0x200c, 0x2003, 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, + 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, + 0x0011, 0x080c, 0x4112, 0x2011, 0x0001, 0x080c, 0x4112, 0x00fe, + 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a66, 0x2079, 0x0320, + 0x792c, 0xd1fc, 0x0904, 0x410f, 0x782b, 0x0002, 0x9026, 0xd19c, + 0x1904, 0x410b, 0x7000, 0x0002, 0x410f, 0x40c0, 0x40f0, 0x410b, + 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, + 0x080c, 0x4112, 0x0904, 0x410f, 0x080c, 0x4112, 0x0804, 0x410f, + 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, + 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, + 0x0de8, 0x080c, 0x4012, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, + 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, + 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, + 0x40b4, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, + 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, + 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, + 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, + 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, + 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0dc5, 0x9398, 0x4140, 0x231d, + 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, + 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, + 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, + 0x417d, 0x4174, 0x416b, 0x4162, 0x4159, 0x4150, 0x4147, 0xa964, + 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, + 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, + 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, + 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, + 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, + 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, + 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, + 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, + 0x0086, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, + 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, 0x41ad, 0x4199, + 0x41a4, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, + 0x4112, 0x190c, 0x4112, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, + 0x1d38, 0x2011, 0x0001, 0x080c, 0x4112, 0x008e, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, + 0x19ac, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, + 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, + 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, + 0x080c, 0x4b89, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, + 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, + 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, + 0x4229, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4b89, 0xa813, + 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, + 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, + 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, + 0x0090, 0x2079, 0x0100, 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009, + 0x0040, 0x080c, 0x2432, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, + 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, + 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, + 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, + 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, + 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, + 0x0086, 0x080c, 0x4b89, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, + 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, + 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, + 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4b89, + 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, + 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, + 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x4229, + 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4b89, 0x2940, 0xa013, + 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, + 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, + 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, + 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, + 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a66, + 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, + 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, + 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, + 0x8000, 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, + 0x4004, 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, + 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, + 0x0108, 0x0005, 0x0804, 0x35ab, 0x7d98, 0x7c9c, 0x0804, 0x36af, + 0x080c, 0x7569, 0x190c, 0x60ec, 0x6040, 0x9084, 0x0020, 0x09b1, + 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bd2, 0x701f, 0x4308, 0x0005, + 0x080c, 0x57e2, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, + 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x35e0, 0x6804, + 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x35e0, 0xd094, 0x00c6, 0x2061, + 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, + 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, + 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, + 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, + 0x1a04, 0x35e0, 0x9288, 0x33ac, 0x210d, 0x918c, 0x00ff, 0x6166, + 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x35e0, 0x605e, + 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, + 0x2009, 0x19b3, 0x9080, 0x29d0, 0x2005, 0x200a, 0x000e, 0x2009, + 0x19b4, 0x9080, 0x29d4, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, + 0x0a04, 0x35e0, 0x908a, 0x0841, 0x1a04, 0x35e0, 0x9084, 0x0007, + 0x1904, 0x35e0, 0x680c, 0x9005, 0x0904, 0x35e0, 0x6810, 0x9005, + 0x0904, 0x35e0, 0x6848, 0x6940, 0x910a, 0x1a04, 0x35e0, 0x8001, + 0x0904, 0x35e0, 0x684c, 0x6944, 0x910a, 0x1a04, 0x35e0, 0x8001, + 0x0904, 0x35e0, 0x2009, 0x1982, 0x200b, 0x0000, 0x2001, 0x1869, + 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, 0x0e52, + 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, + 0x9084, 0x00ff, 0x6052, 0x080c, 0x787f, 0x080c, 0x6ac8, 0x080c, + 0x6b2a, 0x6808, 0x602a, 0x080c, 0x23a4, 0x2009, 0x0170, 0x200b, + 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, + 0x2937, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x44a4, 0x6818, + 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, + 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, + 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, + 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, + 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001, + 0x20a9, 0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c, + 0x882e, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0510, + 0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008, 0x1110, 0x839d, + 0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7e3b, + 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, + 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, + 0x6003, 0x0001, 0x1f04, 0x43f9, 0x00ce, 0x00c6, 0x2061, 0x199d, + 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063, + 0x0000, 0x2001, 0x0001, 0x080c, 0x2bca, 0x2001, 0x0001, 0x080c, + 0x2bad, 0x0088, 0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006, + 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0028, 0x9286, 0x8000, + 0x1d30, 0x2063, 0x0002, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ea3, + 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085, + 0x0100, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128, + 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80, + 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118, + 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x29ac, 0x2001, + 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, + 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x7569, 0x0128, 0x080c, + 0x50c9, 0x0110, 0x080c, 0x28fd, 0x60d4, 0x9005, 0x01c0, 0x6003, + 0x0001, 0x2009, 0x448c, 0x00e0, 0x080c, 0x7569, 0x1168, 0x2011, + 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x080c, + 0x7853, 0x080c, 0x7495, 0x0040, 0x080c, 0x5fe6, 0x0028, 0x6003, + 0x0004, 0x2009, 0x44a4, 0x0020, 0x080c, 0x69f4, 0x0804, 0x35ab, + 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, + 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000, 0x9086, + 0x0000, 0x0904, 0x35dd, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894, + 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x2039, 0x0001, 0x0804, 0x4bd5, 0x9006, 0x080c, 0x28fd, 0x81ff, + 0x1904, 0x35dd, 0x080c, 0x7569, 0x11b0, 0x080c, 0x784e, 0x080c, + 0x6127, 0x080c, 0x33a0, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, + 0xd561, 0x0130, 0x080c, 0x758c, 0x1118, 0x080c, 0x7541, 0x0038, + 0x080c, 0x7495, 0x0020, 0x080c, 0x60ec, 0x080c, 0x5fe6, 0x0804, + 0x35ab, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x7569, 0x1110, 0x0804, + 0x35dd, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f, + 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bd5, 0x701f, 0x35a9, 0x012e, + 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9, 0x0040, + 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304, 0x655c, + 0x9588, 0x33ac, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, + 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x671d, 0x1190, 0xb814, + 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007, 0x201a, + 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, + 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, + 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1c80, + 0x2099, 0x1c80, 0x080c, 0x6077, 0x0804, 0x4501, 0x080c, 0x4bbc, + 0x0904, 0x35e0, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, + 0x35dd, 0x080c, 0x57d3, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, + 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, + 0x339b, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0x080c, 0xd021, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007, + 0x0003, 0x701f, 0x458c, 0x0005, 0x080c, 0x4bbc, 0x0904, 0x35e0, + 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, + 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, + 0x080c, 0x0f8b, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, + 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, + 0x0f8b, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x0804, 0x4bd5, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4ba0, 0x0904, + 0x35e0, 0x080c, 0x688f, 0x0904, 0x35dd, 0x0058, 0xa878, 0x9005, + 0x0120, 0x2009, 0x0004, 0x0804, 0x35dd, 0xa974, 0xaa94, 0x0804, + 0x35ab, 0x080c, 0x57db, 0x0904, 0x35ab, 0x701f, 0x45d6, 0x7007, + 0x0003, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x35e0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92, + 0x0120, 0x080c, 0x6a9a, 0x1904, 0x35e0, 0x080c, 0x6914, 0x0904, + 0x35dd, 0x2019, 0x0004, 0x900e, 0x080c, 0x68a1, 0x0904, 0x35dd, + 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, + 0x080c, 0x4bba, 0x01e0, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, + 0x11b0, 0x080c, 0x6914, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, + 0x2019, 0x0004, 0x080c, 0x68a1, 0x2009, 0x0003, 0x0120, 0xa998, + 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, + 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506, + 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x671d, + 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8717, + 0x0005, 0x81ff, 0x1904, 0x35dd, 0x798c, 0x2001, 0x1981, 0x918c, + 0x8000, 0x2102, 0x080c, 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6a92, + 0x0120, 0x080c, 0x6a9a, 0x1904, 0x35e0, 0x080c, 0x67e4, 0x0904, + 0x35dd, 0x080c, 0x6898, 0x0904, 0x35dd, 0x2001, 0x1981, 0x2004, + 0xd0fc, 0x1904, 0x35ab, 0x0804, 0x45e1, 0xa9a0, 0x2001, 0x1981, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bad, 0x01a0, 0x080c, + 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1170, 0x080c, 0x67e4, 0x2009, + 0x0002, 0x0128, 0x080c, 0x6898, 0x1170, 0x2009, 0x0003, 0xa897, + 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x35dd, + 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4ba0, + 0x0904, 0x35e0, 0x080c, 0x6a92, 0x0120, 0x080c, 0x6a9a, 0x1904, + 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x080c, 0x6886, 0x0904, + 0x35dd, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, 0x35ab, 0x0804, + 0x45e1, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, + 0x080c, 0x4bad, 0x01a0, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, + 0x1170, 0x080c, 0x67e4, 0x2009, 0x0002, 0x0128, 0x080c, 0x6886, + 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57db, + 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x0005, 0x6100, 0x0804, 0x35ab, 0x080c, 0x4bbc, 0x0904, 0x35e0, + 0x080c, 0x57e7, 0x1904, 0x35dd, 0x79a8, 0xd184, 0x1158, 0xb834, + 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, + 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, + 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, + 0x35ab, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1158, 0xd0b4, 0x1148, + 0x939a, 0x0003, 0x1a04, 0x35dd, 0x625c, 0x7884, 0x9206, 0x1904, + 0x479c, 0x080c, 0x8818, 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, + 0x0080, 0x1528, 0x0006, 0x0036, 0x2001, 0x1a84, 0x201c, 0x7b9a, + 0x2003, 0x0000, 0x2001, 0x1a85, 0x201c, 0x7b9e, 0x2003, 0x0000, + 0x2001, 0x1a86, 0x201c, 0x7bae, 0x2003, 0x0000, 0x2001, 0x1a80, + 0x201c, 0x7baa, 0x2003, 0x0000, 0x2001, 0x1a87, 0x201c, 0x7bb2, + 0x2003, 0x0000, 0x003e, 0x000e, 0x000e, 0x0804, 0x4bd5, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, - 0x0002, 0x701f, 0x35b5, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, - 0x2079, 0x0000, 0x2001, 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, - 0x4c61, 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, - 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, - 0x4cc7, 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, - 0x7044, 0x9005, 0x1540, 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, - 0x2060, 0x080c, 0x100e, 0x0904, 0x4cbf, 0xa84b, 0x0000, 0x2900, - 0x7046, 0x2001, 0x0002, 0x9080, 0x20c7, 0x2005, 0xa846, 0x0098, - 0x7038, 0x90e0, 0x0004, 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, - 0x2061, 0x18ba, 0x2c00, 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, - 0x8108, 0x714a, 0x0460, 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, - 0xa144, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, - 0x001e, 0x8108, 0x2105, 0x9005, 0xa146, 0x1520, 0x080c, 0x100e, - 0x1130, 0x8109, 0xa946, 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, - 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, - 0x2001, 0x0002, 0x9080, 0x20c7, 0x2005, 0xa846, 0x0058, 0x2262, - 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, - 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4ce9, 0x4ce9, - 0x4ceb, 0x4ce9, 0x4ce9, 0x4ce9, 0x4cef, 0x4ce9, 0x4ce9, 0x4ce9, - 0x4cf3, 0x4ce9, 0x4ce9, 0x4ce9, 0x4cf7, 0x4ce9, 0x4ce9, 0x4ce9, - 0x4cfb, 0x4ce9, 0x4ce9, 0x4ce9, 0x4cff, 0x4ce9, 0x4ce9, 0x4ce9, - 0x4d04, 0x080c, 0x0dc5, 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, - 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, - 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, - 0xa3ca, 0xa4ce, 0x0804, 0x4cc2, 0xa2d6, 0xa3da, 0xa4de, 0x0804, - 0x4cc2, 0x00e6, 0x2071, 0x189e, 0x7048, 0x9005, 0x0904, 0x4d9b, - 0x0126, 0x2091, 0x8000, 0x0e04, 0x4d9a, 0x00f6, 0x2079, 0x0000, - 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, - 0x9005, 0x0500, 0xa948, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, - 0x0dc5, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, - 0x4d9d, 0xa804, 0x9005, 0x090c, 0x0dc5, 0x7042, 0x2938, 0x2040, - 0xa003, 0x0000, 0x2001, 0x0002, 0x9080, 0x20c7, 0x2005, 0xa04a, - 0x0804, 0x4d9d, 0x703c, 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, - 0x2200, 0x7836, 0x7833, 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, - 0x788a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x11aa, 0x87ff, 0x0118, 0x2748, 0x080c, 0x1040, 0x7048, 0x8001, - 0x704a, 0x9005, 0x1170, 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, - 0x1040, 0x9006, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, - 0x0420, 0x7040, 0x9005, 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, - 0x9c80, 0x0004, 0x90fa, 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, - 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044, 0x9005, 0x090c, 0x0dc5, - 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, - 0x9080, 0x20c7, 0x2005, 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, - 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, - 0x0002, 0x4dbc, 0x4dbc, 0x4dbe, 0x4dbc, 0x4dbc, 0x4dbc, 0x4dc3, - 0x4dbc, 0x4dbc, 0x4dbc, 0x4dc8, 0x4dbc, 0x4dbc, 0x4dbc, 0x4dcd, - 0x4dbc, 0x4dbc, 0x4dbc, 0x4dd2, 0x4dbc, 0x4dbc, 0x4dbc, 0x4dd7, - 0x4dbc, 0x4dbc, 0x4dbc, 0x4ddc, 0x080c, 0x0dc5, 0xaa74, 0xab78, - 0xac7c, 0x0804, 0x4d48, 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4d48, - 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4d48, 0xaaa4, 0xaba8, 0xacac, - 0x0804, 0x4d48, 0xaab4, 0xabb8, 0xacbc, 0x0804, 0x4d48, 0xaac4, - 0xabc8, 0xaccc, 0x0804, 0x4d48, 0xaad4, 0xabd8, 0xacdc, 0x0804, - 0x4d48, 0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, - 0x080c, 0x6724, 0x2019, 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, - 0x0000, 0x2011, 0x801b, 0x080c, 0x4c44, 0x00ce, 0x00be, 0x003e, - 0x002e, 0x001e, 0x0005, 0x0026, 0x080c, 0x57d5, 0xd0c4, 0x0120, - 0x2011, 0x8014, 0x080c, 0x4c44, 0x002e, 0x0005, 0x81ff, 0x1904, - 0x35e7, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, - 0x6032, 0x080c, 0x7637, 0x1158, 0x080c, 0x7932, 0x080c, 0x612e, - 0x9085, 0x0001, 0x080c, 0x767b, 0x080c, 0x7563, 0x0010, 0x080c, - 0x5fed, 0x012e, 0x0804, 0x35b5, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x35e7, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, 0x0804, - 0x35e7, 0x080c, 0x6a9b, 0x0120, 0x2009, 0x0008, 0x0804, 0x35e7, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x0178, 0x0026, 0x2011, 0x0010, - 0x080c, 0x6ac7, 0x002e, 0x0140, 0x7984, 0x080c, 0x6b11, 0x1120, - 0x2009, 0x4009, 0x0804, 0x35e7, 0x7984, 0x080c, 0x66b9, 0x1904, - 0x35ea, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x2b00, 0x7026, 0x080c, - 0x6aa3, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, - 0x6944, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, - 0x35b5, 0x080c, 0x4be4, 0x0904, 0x35e7, 0x9006, 0xa866, 0xa832, - 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd302, 0x0904, 0x35e7, 0x7888, - 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x7007, 0x0003, 0x701f, - 0x4ecb, 0x0005, 0x2061, 0x1800, 0x080c, 0x57e9, 0x2009, 0x0007, - 0x1560, 0x080c, 0x6a9b, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, - 0x080c, 0x66b9, 0x1530, 0x080c, 0x4c15, 0x0518, 0x080c, 0x6aa3, - 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6944, - 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, - 0xc0fc, 0xa86a, 0x080c, 0xd302, 0x11e0, 0xa89c, 0xd094, 0x0118, - 0xb8cc, 0xc08d, 0xb8ce, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, - 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, - 0x0005, 0x9006, 0x0005, 0xa830, 0x2009, 0x180d, 0x210c, 0xd18c, - 0x0140, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, - 0x35b7, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x5729, - 0x900e, 0x080c, 0x6944, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, - 0xc18d, 0x0804, 0x35b5, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, - 0x0804, 0x35e7, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, - 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, 0x900e, 0x2130, - 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, - 0x702a, 0x20a0, 0x080c, 0x6724, 0x1904, 0x4f81, 0x080c, 0x6aa3, - 0x0138, 0x080c, 0x6aab, 0x0120, 0x080c, 0x6a43, 0x1904, 0x4f81, - 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, - 0x0006, 0x2098, 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, - 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x49b3, - 0x0080, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x3400, - 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, - 0x49b3, 0x9186, 0x007e, 0x0170, 0x9186, 0x0080, 0x0158, 0x080c, - 0x6aa3, 0x90c2, 0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c, 0x6944, - 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4, 0x20e0, - 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, - 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, - 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0, 0x3d00, - 0x20e0, 0x080c, 0x49a6, 0x9c80, 0x0026, 0x2098, 0xb8c4, 0x20e0, - 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, - 0x0005, 0x8108, 0x080c, 0xb23d, 0x0118, 0x9186, 0x0800, 0x0040, - 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, - 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, - 0x0150, 0x0804, 0x4f0a, 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, - 0x35b5, 0x7033, 0x0001, 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, - 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, - 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, - 0x7007, 0x0002, 0x701f, 0x4fbd, 0x0005, 0x7030, 0x9005, 0x1180, - 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, - 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, 0x4f0a, - 0x7124, 0x810b, 0x0804, 0x35b5, 0x2029, 0x007e, 0x7984, 0x7a88, - 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, - 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x9184, 0x00ff, 0x90e2, 0x0020, - 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x9284, 0xff00, 0x8007, - 0x90e2, 0x0020, 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x9284, - 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, - 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35ea, 0x9502, - 0x0a04, 0x35ea, 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35ea, - 0x9502, 0x0a04, 0x35ea, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, - 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x9484, 0x00ff, 0x90e2, - 0x0020, 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x2061, 0x1989, - 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x35b5, 0x080c, 0x4be4, - 0x0904, 0x35e7, 0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, - 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c2d, 0x701f, 0x5041, - 0x0005, 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, - 0x9080, 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, - 0x20e9, 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x50a8, - 0x6804, 0x2008, 0x918c, 0xfff8, 0x1904, 0x50a8, 0x680c, 0x9005, - 0x0904, 0x50a8, 0x9082, 0xff01, 0x1a04, 0x50a8, 0x6810, 0x9082, - 0x005c, 0x06f0, 0x6824, 0x2008, 0x9082, 0x0008, 0x06c8, 0x9182, - 0x0400, 0x16b0, 0x0056, 0x2029, 0x0000, 0x080c, 0x8e80, 0x005e, - 0x6944, 0x6820, 0x9102, 0x0660, 0x6820, 0x9082, 0x0019, 0x1640, - 0x6828, 0x6944, 0x810c, 0x9102, 0x0618, 0x6840, 0x9082, 0x000f, - 0x12f8, 0x080c, 0x1027, 0x2900, 0x0590, 0x684e, 0x00e6, 0x2071, - 0x1931, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8d3c, 0x00be, 0x00ee, - 0x01e8, 0x080c, 0x8a84, 0x080c, 0x8ad3, 0x1160, 0x6857, 0x0000, - 0x00c6, 0x6b10, 0x2061, 0x1a65, 0x630a, 0x00ce, 0x0804, 0x35b5, - 0x0804, 0x35ea, 0x080c, 0x8acc, 0x00e6, 0x2071, 0x1931, 0x080c, - 0x8f00, 0x080c, 0x8f0f, 0x080c, 0x8d21, 0x00ee, 0x2001, 0x188a, - 0x204c, 0x080c, 0x1040, 0x2001, 0x188a, 0x2003, 0x0000, 0x0804, - 0x35e7, 0x0126, 0x2091, 0x8000, 0x080c, 0x92bf, 0x080c, 0x8acc, - 0x012e, 0x0804, 0x35b5, 0x0006, 0x080c, 0x57d5, 0xd0cc, 0x000e, - 0x0005, 0x0006, 0x080c, 0x57d9, 0xd0bc, 0x000e, 0x0005, 0x6174, - 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x35b5, 0x83ff, - 0x1904, 0x35ea, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35ea, 0x2019, - 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04, 0x35ea, 0x7986, 0x6276, - 0x0804, 0x35b5, 0x080c, 0x57e9, 0x1904, 0x35e7, 0x7c88, 0x7d84, - 0x7e98, 0x7f8c, 0x080c, 0x4be4, 0x0904, 0x35e7, 0x900e, 0x901e, - 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, - 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, - 0x6aa3, 0x0118, 0x080c, 0x6aab, 0x1148, 0x20a9, 0x0001, 0xb814, - 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, - 0x0800, 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, - 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x9375, 0x2208, 0x0804, - 0x35b5, 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, - 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, - 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, 0x7007, - 0x0002, 0x701f, 0x514c, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, - 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, - 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804, 0x510a, 0x7224, 0x900e, - 0x2001, 0x0003, 0x080c, 0x9375, 0x2208, 0x0804, 0x35b5, 0x00f6, - 0x00e6, 0x080c, 0x57e9, 0x2009, 0x0007, 0x1904, 0x51df, 0x2071, - 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x51df, 0xac9c, - 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c, 0x1027, 0x2009, 0x0002, - 0x0904, 0x51df, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, - 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, - 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6aa3, 0x0118, 0x080c, - 0x6aab, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, - 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, - 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, - 0x0003, 0x080c, 0x9375, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, - 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x9006, - 0x705e, 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, - 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, - 0xa076, 0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, - 0x51eb, 0x000e, 0xa0a2, 0x080c, 0x10f8, 0x9006, 0x0048, 0x009e, - 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dc5, - 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, - 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, - 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, - 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, - 0xa897, 0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x9375, - 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, - 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6e9f, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, - 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6aa3, - 0x0118, 0x080c, 0x6aab, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, - 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, - 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, - 0x810c, 0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dc5, - 0x2148, 0x080c, 0x1040, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, - 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, - 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, - 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, - 0x080c, 0x10f8, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, - 0x7000, 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, - 0x009e, 0x0804, 0x35ea, 0xa884, 0xa988, 0x080c, 0x2873, 0x1518, - 0x080c, 0x66b9, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, - 0x4be4, 0x01c8, 0x080c, 0x4be4, 0x01b0, 0x009e, 0xa867, 0x0000, - 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, - 0xd284, 0x1120, 0x2009, 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, - 0x701f, 0x52b8, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35e7, - 0x7124, 0x080c, 0x334c, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, - 0x0004, 0x0804, 0x35e7, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, - 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, - 0x9080, 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, - 0x20a9, 0x002a, 0x080c, 0x0f8b, 0xaa6c, 0xab70, 0xac74, 0xad78, - 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, - 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, - 0x2009, 0x0004, 0x000e, 0x007e, 0x0804, 0x4c30, 0x97c6, 0x7200, - 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, - 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, - 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x5314, 0x0005, - 0x000e, 0x007e, 0x0804, 0x35ea, 0x7020, 0x2048, 0xa804, 0x2048, - 0xa804, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, - 0x002a, 0x080c, 0x0f8b, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, - 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4c30, - 0x81ff, 0x1904, 0x35e7, 0x798c, 0x2001, 0x197e, 0x918c, 0x8000, - 0x2102, 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x6aa3, 0x0120, - 0x080c, 0x6aab, 0x1904, 0x35ea, 0x080c, 0x67eb, 0x0904, 0x35e7, - 0x0126, 0x2091, 0x8000, 0x080c, 0x68b1, 0x012e, 0x0904, 0x35e7, - 0x2001, 0x197e, 0x2004, 0xd0fc, 0x1904, 0x35b5, 0x0804, 0x460c, - 0xa9a0, 0x2001, 0x197e, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, - 0x4c08, 0x01a0, 0x080c, 0x6aa3, 0x0118, 0x080c, 0x6aab, 0x1170, - 0x080c, 0x67eb, 0x2009, 0x0002, 0x0128, 0x080c, 0x68b1, 0x1170, - 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, + 0x0002, 0x701f, 0x47bc, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x080c, + 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x1904, 0x35dd, 0x00c6, + 0x080c, 0x4b89, 0x00ce, 0x0904, 0x35dd, 0xa867, 0x0000, 0xa868, + 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcfc7, 0x0904, 0x35dd, 0x7007, + 0x0003, 0x701f, 0x47e2, 0x0005, 0x080c, 0x42ce, 0x0006, 0x0036, + 0x2001, 0x1a84, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a85, + 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a86, 0x201c, 0x7bae, + 0x2003, 0x0000, 0x2001, 0x1a80, 0x201c, 0x7baa, 0x2003, 0x0000, + 0x2001, 0x1a87, 0x201c, 0x7bb2, 0x2003, 0x0000, 0x003e, 0x000e, + 0x0804, 0x35ab, 0xa830, 0x9086, 0x0100, 0x0904, 0x35dd, 0x8906, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, + 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4bd5, + 0x9006, 0x080c, 0x28fd, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, + 0x0118, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x7569, 0x0110, 0x080c, + 0x60ec, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e0, 0x7984, 0x9186, + 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x35e0, 0x2100, 0x080c, + 0x28c7, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19fc, + 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, + 0x080c, 0x7569, 0x1158, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085, + 0x0001, 0x080c, 0x75ad, 0x080c, 0x7495, 0x00d0, 0x080c, 0xb072, + 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, + 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, + 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x6012, 0x080c, 0x87a1, + 0x7984, 0x080c, 0x7569, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, + 0x4644, 0x012e, 0x00ce, 0x002e, 0x0804, 0x35ab, 0x7984, 0x080c, + 0x66b2, 0x2b08, 0x1904, 0x35e0, 0x0804, 0x35ab, 0x81ff, 0x0120, + 0x2009, 0x0001, 0x0804, 0x35dd, 0x60dc, 0xd0ac, 0x1130, 0xd09c, + 0x1120, 0x2009, 0x0005, 0x0804, 0x35dd, 0x080c, 0x4b89, 0x1120, + 0x2009, 0x0002, 0x0804, 0x35dd, 0x7984, 0x81ff, 0x0904, 0x35e0, + 0x9192, 0x0021, 0x1a04, 0x35e0, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4bd2, + 0x701f, 0x4899, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x527b, + 0x0005, 0x2009, 0x0080, 0x080c, 0x671d, 0x1118, 0x080c, 0x6a92, + 0x0120, 0x2021, 0x400a, 0x0804, 0x35ad, 0x00d6, 0x0096, 0xa964, + 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, + 0x0904, 0x4932, 0x90be, 0x0112, 0x0904, 0x4932, 0x90be, 0x0113, + 0x0904, 0x4932, 0x90be, 0x0114, 0x0904, 0x4932, 0x90be, 0x0117, + 0x0904, 0x4932, 0x90be, 0x011a, 0x0904, 0x4932, 0x90be, 0x011c, + 0x0904, 0x4932, 0x90be, 0x0121, 0x0904, 0x4919, 0x90be, 0x0131, + 0x0904, 0x4919, 0x90be, 0x0171, 0x0904, 0x4932, 0x90be, 0x0173, + 0x0904, 0x4932, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, + 0x0804, 0x493d, 0x90be, 0x0212, 0x0904, 0x4926, 0x90be, 0x0213, + 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, + 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, + 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x35e0, + 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, + 0x20a9, 0x0007, 0x080c, 0x497b, 0x7028, 0x9080, 0x000e, 0x2098, + 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x497b, + 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, + 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4988, 0x00b8, 0x7028, 0x9080, + 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, + 0x080c, 0x4988, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, + 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4b89, + 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, + 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, + 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, + 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, + 0xcfe2, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, + 0x701f, 0x4972, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, + 0x0804, 0x35dd, 0xa820, 0x9086, 0x8001, 0x1904, 0x35ab, 0x2009, + 0x0004, 0x0804, 0x35dd, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, + 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, + 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, + 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x35dd, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, + 0x0804, 0x35dd, 0x7984, 0x78a8, 0x2040, 0x080c, 0xb06b, 0x1120, + 0x9182, 0x007f, 0x0a04, 0x35e0, 0x9186, 0x00ff, 0x0904, 0x35e0, + 0x9182, 0x0800, 0x1a04, 0x35e0, 0x7a8c, 0x7b88, 0x607c, 0x9306, + 0x1158, 0x6080, 0x924e, 0x0904, 0x35e0, 0x080c, 0xb06b, 0x1120, + 0x99cc, 0xff00, 0x0904, 0x35e0, 0x0126, 0x2091, 0x8000, 0x080c, + 0x4a9c, 0x0904, 0x4a1c, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, + 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, + 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, + 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6a92, + 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, 0x693d, 0x1108, 0xc185, + 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, + 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, + 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, + 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, + 0x0804, 0x35ad, 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, + 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xb153, 0x0904, 0x4a71, 0x2b00, + 0x6012, 0x080c, 0xd2d2, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, + 0x4b89, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xb101, 0x00ee, 0x00ce, + 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x900e, + 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, + 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, 0x3246, 0x6023, + 0x0001, 0x9006, 0x080c, 0x664f, 0xd89c, 0x0138, 0x2001, 0x0004, + 0x080c, 0x6663, 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, + 0x6663, 0x2009, 0x0002, 0x080c, 0xb180, 0x78a8, 0xd094, 0x0138, + 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8cc, 0xc08d, 0xb8ce, 0x9085, + 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, + 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x4a80, 0x0005, + 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, + 0xba04, 0x9294, 0x00ff, 0x0804, 0x5727, 0x900e, 0xa868, 0xd0f4, + 0x1904, 0x35ab, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0x0804, 0x35ab, 0x00e6, 0x00d6, 0x0096, 0x83ff, + 0x0904, 0x4aeb, 0x902e, 0x080c, 0xb06b, 0x0130, 0x9026, 0x20a9, + 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, + 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, + 0x4afc, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, + 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, + 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, + 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, + 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6a32, 0x1570, 0x2001, + 0x4000, 0x0460, 0x080c, 0x6a92, 0x1540, 0x2001, 0x4000, 0x0430, + 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, + 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xb06b, + 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4ab2, + 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, + 0x080c, 0x66b2, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, + 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x35dd, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, + 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, + 0x35e0, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x35e0, + 0x2010, 0x2918, 0x080c, 0x31ec, 0x1120, 0x2009, 0x0003, 0x0804, + 0x35dd, 0x7007, 0x0003, 0x701f, 0x4b3e, 0x0005, 0xa830, 0x9086, + 0x0100, 0x1904, 0x35ab, 0x2009, 0x0004, 0x0804, 0x35dd, 0x7984, + 0x080c, 0xb06b, 0x1120, 0x9182, 0x007f, 0x0a04, 0x35e0, 0x9186, + 0x00ff, 0x0904, 0x35e0, 0x9182, 0x0800, 0x1a04, 0x35e0, 0x2001, + 0x9400, 0x080c, 0x5782, 0x1904, 0x35dd, 0x0804, 0x35ab, 0xa998, + 0x080c, 0xb06b, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, + 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x5782, + 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, - 0x2001, 0x197e, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57dd, 0x0110, - 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, - 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904, 0x4581, 0x080c, 0x4c17, - 0x0904, 0x35ea, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, - 0x35e7, 0x080c, 0x6aa3, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, - 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, - 0x0028, 0x080c, 0x57d5, 0xd0b4, 0x0904, 0x45bb, 0x7884, 0x908e, - 0x007e, 0x0904, 0x45bb, 0x908e, 0x007f, 0x0904, 0x45bb, 0x908e, - 0x0080, 0x0904, 0x45bb, 0xb800, 0xd08c, 0x1904, 0x45bb, 0xa867, - 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd2a3, 0x1120, 0x2009, - 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x53e0, 0x0005, - 0x080c, 0x4c17, 0x0904, 0x35ea, 0x0804, 0x45bb, 0x080c, 0x33a5, - 0x0108, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, - 0x0001, 0x0804, 0x35e7, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, - 0x0804, 0x35e7, 0x080c, 0x6a9b, 0x0120, 0x2009, 0x0008, 0x0804, - 0x35e7, 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x45bb, 0x9006, - 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd302, 0x1120, - 0x2009, 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x5419, - 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, - 0x5729, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x0804, 0x53b2, 0x81ff, - 0x2009, 0x0001, 0x1904, 0x35e7, 0x080c, 0x57e9, 0x2009, 0x0007, - 0x1904, 0x35e7, 0x080c, 0x6a9b, 0x0120, 0x2009, 0x0008, 0x0804, - 0x35e7, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x080c, 0x6aa3, 0x2009, - 0x0009, 0x1904, 0x35e7, 0x080c, 0x4be4, 0x2009, 0x0002, 0x0904, - 0x35e7, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, - 0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, - 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, - 0x35ea, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xd555, 0x2009, - 0x0003, 0x0904, 0x35e7, 0x7007, 0x0003, 0x701f, 0x5470, 0x0005, - 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x35e7, 0x0804, - 0x35b5, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, - 0x57e9, 0x1188, 0x2009, 0x0014, 0x0804, 0x35e7, 0xd2dc, 0x1578, - 0x81ff, 0x2009, 0x0001, 0x1904, 0x35e7, 0x080c, 0x57e9, 0x2009, - 0x0007, 0x1904, 0x35e7, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, - 0x080c, 0x57af, 0x0804, 0x35b5, 0xd2fc, 0x0160, 0x080c, 0x4c17, - 0x0904, 0x35ea, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5784, - 0x0804, 0x35b5, 0x080c, 0x4c17, 0x0904, 0x35ea, 0xb804, 0x9084, - 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x555f, 0x080c, - 0x4be4, 0x2009, 0x0002, 0x0904, 0x555f, 0xa85c, 0x9080, 0x001b, - 0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, - 0x4c2d, 0x701f, 0x54cc, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, - 0xa870, 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, - 0x35ea, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4c17, - 0x1110, 0x0804, 0x35ea, 0x2009, 0x0043, 0x080c, 0xd5c1, 0x2009, - 0x0003, 0x0904, 0x555f, 0x7007, 0x0003, 0x701f, 0x54f0, 0x0005, - 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x555f, 0x7984, - 0x7aa8, 0x9284, 0x1000, 0xc0d5, 0x080c, 0x5784, 0x0804, 0x35b5, - 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, - 0x57e9, 0x1158, 0x2009, 0x0014, 0x0804, 0x554e, 0x2061, 0x1800, - 0x080c, 0x57e9, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, - 0x5000, 0xc0d5, 0x080c, 0x57af, 0x0058, 0xd2fc, 0x0180, 0x080c, - 0x4c15, 0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5784, - 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, - 0x4c15, 0x0510, 0x080c, 0x6aa3, 0x2009, 0x0009, 0x11b8, 0xa8c4, - 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, - 0xff00, 0x1190, 0x080c, 0x4c15, 0x1108, 0x0070, 0x2009, 0x004b, - 0x080c, 0xd5c1, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, + 0x0c48, 0x080c, 0x100e, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, + 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, + 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, + 0x7984, 0x080c, 0x671d, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x671d, + 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, + 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x671d, + 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, + 0x0128, 0x2148, 0xa904, 0x080c, 0x1040, 0x0cc8, 0x7116, 0x711a, + 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, + 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, + 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x35ab, + 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, + 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c06, 0x7a36, 0x7833, + 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x4c6c, 0x0016, 0x0086, + 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, + 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x100e, + 0x0904, 0x4c64, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, + 0x9080, 0x20f0, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, + 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, + 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, + 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, + 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, 0x001e, 0x8108, 0x2105, + 0x9005, 0xa146, 0x1520, 0x080c, 0x100e, 0x1130, 0x8109, 0xa946, + 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, + 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, + 0x20f0, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, + 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, + 0x9082, 0x001b, 0x0002, 0x4c8e, 0x4c8e, 0x4c90, 0x4c8e, 0x4c8e, + 0x4c8e, 0x4c94, 0x4c8e, 0x4c8e, 0x4c8e, 0x4c98, 0x4c8e, 0x4c8e, + 0x4c8e, 0x4c9c, 0x4c8e, 0x4c8e, 0x4c8e, 0x4ca0, 0x4c8e, 0x4c8e, + 0x4c8e, 0x4ca4, 0x4c8e, 0x4c8e, 0x4c8e, 0x4ca9, 0x080c, 0x0dc5, + 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, + 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, + 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, + 0x4c67, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4c67, 0x00e6, 0x2071, + 0x189e, 0x7048, 0x9005, 0x0904, 0x4d40, 0x0126, 0x2091, 0x8000, + 0x0e04, 0x4d3f, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, + 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, + 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, 0x001e, + 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d42, 0xa804, 0x9005, + 0x090c, 0x0dc5, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, + 0x0002, 0x9080, 0x20f0, 0x2005, 0xa04a, 0x0804, 0x4d42, 0x703c, + 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, + 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x87ff, 0x0118, + 0x2748, 0x080c, 0x1040, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, + 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x1040, 0x9006, 0x7042, + 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, + 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, + 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, + 0x703a, 0x7044, 0x9005, 0x090c, 0x0dc5, 0x2048, 0xa800, 0x9005, + 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x20f0, 0x2005, + 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, + 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4d61, 0x4d61, + 0x4d63, 0x4d61, 0x4d61, 0x4d61, 0x4d68, 0x4d61, 0x4d61, 0x4d61, + 0x4d6d, 0x4d61, 0x4d61, 0x4d61, 0x4d72, 0x4d61, 0x4d61, 0x4d61, + 0x4d77, 0x4d61, 0x4d61, 0x4d61, 0x4d7c, 0x4d61, 0x4d61, 0x4d61, + 0x4d81, 0x080c, 0x0dc5, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4ced, + 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4ced, 0xaa94, 0xab98, 0xac9c, + 0x0804, 0x4ced, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4ced, 0xaab4, + 0xabb8, 0xacbc, 0x0804, 0x4ced, 0xaac4, 0xabc8, 0xaccc, 0x0804, + 0x4ced, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4ced, 0x0016, 0x0026, + 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x671d, 0x2019, + 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, + 0x080c, 0x4be9, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, + 0x0026, 0x080c, 0x57d3, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, + 0x4be9, 0x002e, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x0126, 0x2091, + 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x7569, + 0x1158, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085, 0x0001, 0x080c, + 0x75ad, 0x080c, 0x7495, 0x0010, 0x080c, 0x5fe6, 0x012e, 0x0804, + 0x35ab, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x080c, + 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x080c, 0x6a8a, + 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0x7984, 0x080c, 0x66b2, + 0x1904, 0x35e0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x2b00, 0x7026, + 0x080c, 0x6a92, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, + 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, + 0x0804, 0x35ab, 0x080c, 0x4b89, 0x0904, 0x35dd, 0x9006, 0xa866, + 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd080, 0x0904, 0x35dd, + 0x7888, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x7007, 0x0003, + 0x701f, 0x4e5c, 0x0005, 0x2061, 0x1800, 0x080c, 0x57e7, 0x2009, + 0x0007, 0x1560, 0x080c, 0x6a8a, 0x0118, 0x2009, 0x0008, 0x0430, + 0xa998, 0x080c, 0x66b2, 0x1530, 0x080c, 0x4bba, 0x0518, 0x080c, + 0x6a92, 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, + 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, + 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xd080, 0x11e0, 0xa89c, 0xd094, + 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x2009, 0x0003, 0xa897, 0x4005, + 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, + 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, + 0x2058, 0x1110, 0x0804, 0x5727, 0x900e, 0x080c, 0x693d, 0x1108, + 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35ab, 0x080c, + 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7f84, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, + 0x0804, 0x35dd, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, + 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x671d, + 0x1904, 0x4f05, 0x080c, 0x6a92, 0x0138, 0x080c, 0x6a9a, 0x0120, + 0x080c, 0x6a32, 0x1904, 0x4f05, 0xd794, 0x1110, 0xd784, 0x01a8, + 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, + 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, + 0x20a9, 0x0002, 0x080c, 0x4988, 0x0080, 0xb8c4, 0x20e0, 0xb8c8, + 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, 0x2098, + 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4988, 0x9186, 0x007e, 0x0170, + 0x9186, 0x0080, 0x0158, 0x080c, 0x6a92, 0x90c2, 0x0006, 0x1210, + 0xc1fd, 0x0020, 0x080c, 0x693d, 0x1108, 0xc1fd, 0x4104, 0xc1fc, + 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, + 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, + 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, + 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x497b, 0x9c80, + 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, + 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xb06b, + 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, + 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, + 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4e8e, 0x86ff, + 0x1120, 0x7124, 0x810b, 0x0804, 0x35ab, 0x7033, 0x0001, 0x7122, + 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, + 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, + 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x4f41, + 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, + 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, + 0xa494, 0xa598, 0x0804, 0x4e8e, 0x7124, 0x810b, 0x0804, 0x35ab, + 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, + 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0, + 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, + 0x35e0, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0, + 0x9502, 0x0a04, 0x35e0, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, + 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9384, 0xff00, 0x8007, 0x90e2, + 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9384, 0x00ff, + 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9484, + 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, + 0x35e0, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, + 0x0a04, 0x35e0, 0x2061, 0x198a, 0x6102, 0x6206, 0x630a, 0x640e, + 0x0804, 0x35ab, 0x080c, 0x4b89, 0x0904, 0x35dd, 0x2009, 0x0016, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, + 0x080c, 0x4bd2, 0x701f, 0x4fc5, 0x0005, 0x2001, 0x0138, 0x2003, + 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, + 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, + 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, + 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x5046, 0x6804, + 0x2008, 0x918c, 0xfff8, 0x1904, 0x5046, 0x680c, 0x9005, 0x0904, + 0x5046, 0x9082, 0xff01, 0x1a04, 0x5046, 0x6810, 0x9082, 0x005c, + 0x0a04, 0x5046, 0x6824, 0x2008, 0x9082, 0x0008, 0x0a04, 0x5046, + 0x9182, 0x0400, 0x1a04, 0x5046, 0x0056, 0x2029, 0x0000, 0x080c, + 0x8d49, 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, + 0x0019, 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, 0x0678, 0x6840, + 0x9082, 0x000f, 0x1658, 0x080c, 0x1027, 0x2900, 0x0904, 0x5062, + 0x684e, 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059, 0x0000, 0x080c, + 0x8c05, 0x00be, 0x00ee, 0x0568, 0x080c, 0x8950, 0x080c, 0x899f, + 0x11e0, 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, + 0x2000, 0x6106, 0x6b10, 0x2061, 0x1a66, 0x630a, 0x00ce, 0x080c, + 0x29ac, 0x2001, 0x0138, 0x2102, 0x0804, 0x35ab, 0x080c, 0x29ac, + 0x2001, 0x0138, 0x2102, 0x0804, 0x35e0, 0x080c, 0x8998, 0x00e6, + 0x2071, 0x1932, 0x080c, 0x8dc9, 0x080c, 0x8dd8, 0x080c, 0x8be8, + 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x1040, 0x2001, 0x188a, + 0x2003, 0x0000, 0x080c, 0x29ac, 0x2001, 0x0138, 0x2102, 0x0804, + 0x35dd, 0x2001, 0x1926, 0x200c, 0x918e, 0x0000, 0x0904, 0x50c7, + 0x080c, 0x8be3, 0x0904, 0x50c7, 0x2001, 0x0101, 0x200c, 0x918c, + 0xdfff, 0x2102, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, + 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c, 0x8be8, 0x0126, + 0x2091, 0x8000, 0x2001, 0x0035, 0x080c, 0x1611, 0x012e, 0x00c6, + 0x2061, 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, + 0x29ac, 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925, + 0x080c, 0x8b22, 0x0120, 0x2f00, 0x080c, 0x8bae, 0x0cc8, 0x00fe, + 0x00ee, 0x0126, 0x2091, 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, + 0x0138, 0x2148, 0x080c, 0x1040, 0x2001, 0x188a, 0x2003, 0x0000, + 0x2001, 0x183d, 0x2003, 0x0020, 0x080c, 0x8998, 0x00e6, 0x2071, + 0x1932, 0x080c, 0x8dc9, 0x080c, 0x8dd8, 0x00ee, 0x012e, 0x0804, + 0x35ab, 0x0006, 0x080c, 0x57d3, 0xd0cc, 0x000e, 0x0005, 0x0006, + 0x080c, 0x57d7, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, + 0x82ff, 0x1118, 0x7986, 0x0804, 0x35ab, 0x83ff, 0x1904, 0x35e0, + 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35e0, 0x2019, 0xffff, 0x6078, + 0x9302, 0x9200, 0x0a04, 0x35e0, 0x7986, 0x6276, 0x0804, 0x35ab, + 0x080c, 0x57e7, 0x1904, 0x35dd, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, + 0x080c, 0x4b89, 0x0904, 0x35dd, 0x900e, 0x901e, 0x7326, 0x7332, + 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, + 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118, + 0x080c, 0x6a9a, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, + 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, + 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, + 0x2001, 0x0003, 0x080c, 0x91b1, 0x2208, 0x0804, 0x35ab, 0x7033, + 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, + 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, + 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, + 0x514a, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, + 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, + 0xa694, 0xa798, 0x0804, 0x5108, 0x7224, 0x900e, 0x2001, 0x0003, + 0x080c, 0x91b1, 0x2208, 0x0804, 0x35ab, 0x00f6, 0x00e6, 0x080c, + 0x57e7, 0x2009, 0x0007, 0x1904, 0x51dd, 0x2071, 0x189e, 0x745c, + 0x84ff, 0x2009, 0x000e, 0x1904, 0x51dd, 0xac9c, 0xad98, 0xaea4, + 0xafa0, 0x0096, 0x080c, 0x1027, 0x2009, 0x0002, 0x0904, 0x51dd, + 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, + 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, + 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1148, + 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, + 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, + 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, + 0x91b1, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, + 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x9006, 0x705e, 0x918d, + 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, + 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, + 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x51e9, 0x000e, + 0xa0a2, 0x080c, 0x10f8, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, + 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0x00e6, 0x2071, + 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, + 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, + 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x91b1, 0xaa9a, 0x715c, + 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x705f, 0x0000, + 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, + 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, + 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118, 0x080c, + 0x6a9a, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, + 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, + 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, + 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, + 0x1040, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0xa09f, 0x0000, + 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, + 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, + 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, + 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, + 0x35e0, 0xa884, 0xa988, 0x080c, 0x2894, 0x1518, 0x080c, 0x66b2, + 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4b89, 0x01c8, + 0x080c, 0x4b89, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, + 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xd002, 0x1120, + 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x52b6, + 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x7124, 0x080c, + 0x3342, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, + 0x35dd, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, + 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, + 0x080c, 0x0f8b, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, + 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, + 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, + 0x000e, 0x007e, 0x0804, 0x4bd5, 0x97c6, 0x7200, 0x11b8, 0x96c2, + 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, + 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, + 0x10f8, 0x7007, 0x0002, 0x701f, 0x5312, 0x0005, 0x000e, 0x007e, + 0x0804, 0x35e0, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, + 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, + 0x0f8b, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, + 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4bd5, 0x81ff, 0x1904, + 0x35dd, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, + 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x0120, 0x080c, 0x6a9a, + 0x1904, 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x0126, 0x2091, + 0x8000, 0x080c, 0x68aa, 0x012e, 0x0904, 0x35dd, 0x2001, 0x197f, + 0x2004, 0xd0fc, 0x1904, 0x35ab, 0x0804, 0x45e1, 0xa9a0, 0x2001, + 0x197f, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bad, 0x01a0, + 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1170, 0x080c, 0x67e4, + 0x2009, 0x0002, 0x0128, 0x080c, 0x68aa, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, - 0xd2dc, 0x0904, 0x35e7, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, - 0x080c, 0x5784, 0x001e, 0x1904, 0x35e7, 0x0804, 0x35b5, 0x00f6, - 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, - 0x0150, 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x5784, - 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x35e7, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, 0x0804, - 0x35e7, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6724, 0x1904, - 0x35ea, 0x9186, 0x007f, 0x0138, 0x080c, 0x6aa3, 0x0120, 0x2009, - 0x0009, 0x0804, 0x35e7, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, - 0x0804, 0x35e7, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, - 0x0100, 0x8007, 0xa80a, 0x080c, 0xd2bd, 0x1120, 0x2009, 0x0003, - 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x55bf, 0x0005, 0xa808, - 0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35e7, - 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, - 0x8007, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, - 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, - 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4c30, 0x080c, 0x4be4, - 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, 0x7984, 0x9194, 0xff00, - 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b4, 0x0040, - 0x92c6, 0x0001, 0x1118, 0x7023, 0x19ce, 0x0010, 0x0804, 0x35ea, - 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, - 0x0019, 0xaf60, 0x080c, 0x4c2d, 0x701f, 0x560f, 0x0005, 0x2001, - 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, - 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, - 0x0804, 0x35b5, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, - 0x35e7, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, - 0x1118, 0x2099, 0x19b4, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, - 0x19ce, 0x0010, 0x0804, 0x35ea, 0xa85c, 0x9080, 0x0019, 0x20a0, - 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, - 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, - 0xaf60, 0x0804, 0x4c30, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35ea, - 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, - 0x2061, 0x19fb, 0x614a, 0x00ce, 0x012e, 0x0804, 0x35b5, 0x00c6, - 0x080c, 0x7637, 0x1160, 0x080c, 0x7932, 0x080c, 0x612e, 0x9085, - 0x0001, 0x080c, 0x767b, 0x080c, 0x7563, 0x080c, 0x0dc5, 0x2061, - 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5fed, 0x00ce, 0x0005, - 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35e7, - 0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x199c, 0x2c0c, 0x2062, - 0x080c, 0x2c49, 0x01a0, 0x080c, 0x2c51, 0x0188, 0x080c, 0x2c59, - 0x0170, 0x2162, 0x0804, 0x35ea, 0x2061, 0x0100, 0x6038, 0x9086, - 0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, - 0x9086, 0x0002, 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, - 0x0026, 0x2011, 0x0003, 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, - 0xaac9, 0x002e, 0x080c, 0xa9d3, 0x0036, 0x901e, 0x080c, 0xaa49, - 0x003e, 0x60e3, 0x0000, 0x080c, 0xf07f, 0x080c, 0xf09a, 0x9085, - 0x0001, 0x080c, 0x767b, 0x9006, 0x080c, 0x2d39, 0x2001, 0x1800, - 0x2003, 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x6027, 0x0008, - 0x00ce, 0x0804, 0x35b5, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, - 0x35e7, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e7, - 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6724, 0x1904, 0x35ea, - 0x9186, 0x007f, 0x0138, 0x080c, 0x6aa3, 0x0120, 0x2009, 0x0009, - 0x0804, 0x35e7, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, - 0x35e7, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd2c0, - 0x1120, 0x2009, 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, - 0x5712, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, - 0x0804, 0x35e7, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, - 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, - 0x4c30, 0xa898, 0x9086, 0x000d, 0x1904, 0x35e7, 0x2021, 0x4005, - 0x0126, 0x2091, 0x8000, 0x0e04, 0x5736, 0x0010, 0x012e, 0x0cc0, - 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, - 0x0010, 0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, - 0x799e, 0x080c, 0x4c20, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, - 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, - 0x19fb, 0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, - 0x7898, 0x6072, 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, - 0x2001, 0x1a0b, 0x2044, 0x2001, 0x1a12, 0xa076, 0xa060, 0xa072, - 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, - 0x00ce, 0x012e, 0x0804, 0x35b5, 0x0126, 0x2091, 0x8000, 0x00b6, - 0x00c6, 0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, - 0x2019, 0x0029, 0x080c, 0x336a, 0x003e, 0x080c, 0xd125, 0x000e, - 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, - 0x080c, 0x6148, 0x080c, 0xb23d, 0x0110, 0xb817, 0x0000, 0x9006, - 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, - 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, - 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, - 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, - 0x0128, 0x0026, 0x2200, 0x080c, 0x5784, 0x002e, 0x001e, 0x8108, - 0x1f04, 0x57b7, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004, - 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, - 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, - 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, - 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, - 0x0005, 0x79a4, 0x81ff, 0x0904, 0x35ea, 0x9182, 0x0081, 0x1a04, - 0x35ea, 0x810c, 0x0016, 0x080c, 0x4be4, 0x0170, 0x080c, 0x0f16, - 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, - 0x4c2d, 0x701f, 0x5819, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, - 0x35e7, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, - 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e, - 0x080c, 0x4c30, 0x701f, 0x582d, 0x0005, 0x2061, 0x18b8, 0x2c44, - 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f1e, 0x002e, 0x001e, - 0x080c, 0x0fcb, 0x9006, 0xa802, 0xa806, 0x0804, 0x35b5, 0x0126, - 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, - 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, - 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x59ed, 0x0068, 0xd08c, - 0x0118, 0x080c, 0x58f6, 0x0040, 0xd094, 0x0118, 0x080c, 0x58c6, - 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, - 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, - 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x7030, - 0xd09c, 0x1120, 0x6004, 0x9085, 0x0002, 0x6006, 0x7098, 0x9005, - 0x0120, 0x709b, 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, 0xf0f0, - 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, - 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, 0x0178, - 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, 0x9294, - 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x60aa, 0x00f0, 0x6040, - 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, 0x7087, - 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, 0x2009, - 0x1c80, 0x200b, 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, 0x2009, - 0x000f, 0x2011, 0x5f90, 0x080c, 0x88d5, 0x0005, 0x2001, 0x1869, - 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, 0x1528, - 0x2011, 0x5f90, 0x080c, 0x883d, 0x6040, 0x9094, 0x0010, 0x9285, - 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, - 0x58dc, 0x6242, 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285, - 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, 0x708f, - 0x0000, 0x9006, 0x080c, 0x6133, 0x0000, 0x0005, 0x708c, 0x908a, - 0x0003, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5900, 0x5951, 0x59ec, - 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, 0x2001, - 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, - 0x9084, 0x00fc, 0x0120, 0x1f04, 0x590f, 0x080c, 0x0dc5, 0x68a0, - 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600, - 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x610f, 0x2079, 0x1c00, - 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, - 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, 0x080c, - 0xaf8e, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, - 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, - 0x080c, 0x5fc1, 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, 0x6042, - 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, 0x59c9, - 0x6020, 0xd0b4, 0x1904, 0x59c7, 0x71a0, 0x81ff, 0x0904, 0x59b5, - 0x9486, 0x000c, 0x1904, 0x59c2, 0x9480, 0x0018, 0x8004, 0x20a8, - 0x080c, 0x6108, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, 0x2304, - 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x596e, 0x6043, 0x0004, - 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, - 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, 0x07d0, - 0x2011, 0x5f97, 0x080c, 0x88d5, 0x080c, 0x610f, 0x04c0, 0x080c, - 0x6108, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, 0x7834, - 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, - 0x0190, 0x080c, 0x6108, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, - 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, - 0x1f04, 0x59a9, 0x0078, 0x70a3, 0x0000, 0x080c, 0x6108, 0x20e1, - 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x20a9, - 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00fe, - 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, - 0x080c, 0xaf8e, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, - 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, - 0x19f2, 0x2013, 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, 0x60a7, - 0x9575, 0x080c, 0xa6e0, 0x08d8, 0x0005, 0x7098, 0x908a, 0x001d, - 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5a1e, 0x5a31, 0x5a5a, 0x5a7a, - 0x5aa0, 0x5acf, 0x5af5, 0x5b2d, 0x5b53, 0x5b81, 0x5bbc, 0x5bf4, - 0x5c12, 0x5c3d, 0x5c5f, 0x5c7a, 0x5c84, 0x5cb8, 0x5cde, 0x5d0d, - 0x5d33, 0x5d6b, 0x5daf, 0x5dec, 0x5e0d, 0x5e66, 0x5e88, 0x5eb6, - 0x5eb6, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, 0x0100, - 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, 0x0140, - 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0002, - 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5f97, 0x080c, 0x88d5, - 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020, - 0xd0b4, 0x11f0, 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, - 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x2011, 0x5f97, 0x080c, - 0x883d, 0x709b, 0x0010, 0x080c, 0x5c84, 0x0010, 0x7093, 0x0000, - 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, 0x2011, - 0x5f97, 0x080c, 0x883d, 0x080c, 0x608c, 0x2079, 0x0240, 0x7833, - 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, - 0x0000, 0x8108, 0x1f04, 0x5a6f, 0x60c3, 0x0014, 0x080c, 0x5fc1, - 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f97, - 0x080c, 0x883d, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6108, 0x2079, - 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, 0x1160, - 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, - 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, 0x60e4, 0x00fe, 0x0005, - 0x00f6, 0x709b, 0x0005, 0x080c, 0x608c, 0x2079, 0x0240, 0x7833, - 0x1103, 0x7837, 0x0000, 0x080c, 0x6108, 0x080c, 0x60eb, 0x1170, - 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, - 0x0008, 0x080c, 0x5f44, 0x0168, 0x080c, 0x60c1, 0x20a9, 0x0008, + 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, + 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, + 0x1118, 0xd084, 0x0904, 0x4556, 0x080c, 0x4bbc, 0x0904, 0x35e0, + 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x080c, + 0x6a92, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, + 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, + 0x57d3, 0xd0b4, 0x0904, 0x4590, 0x7884, 0x908e, 0x007e, 0x0904, + 0x4590, 0x908e, 0x007f, 0x0904, 0x4590, 0x908e, 0x0080, 0x0904, + 0x4590, 0xb800, 0xd08c, 0x1904, 0x4590, 0xa867, 0x0000, 0xa868, + 0xc0fd, 0xa86a, 0x080c, 0xd021, 0x1120, 0x2009, 0x0003, 0x0804, + 0x35dd, 0x7007, 0x0003, 0x701f, 0x53de, 0x0005, 0x080c, 0x4bbc, + 0x0904, 0x35e0, 0x0804, 0x4590, 0x080c, 0x339b, 0x0108, 0x0005, + 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x35dd, 0x080c, 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, + 0x080c, 0x6a8a, 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0xb89c, + 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4590, 0x9006, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd080, 0x1120, 0x2009, 0x0003, + 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x5417, 0x0005, 0xa830, + 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x5727, 0x080c, + 0x4bbc, 0x0904, 0x35e0, 0x0804, 0x53b0, 0x81ff, 0x2009, 0x0001, + 0x1904, 0x35dd, 0x080c, 0x57e7, 0x2009, 0x0007, 0x1904, 0x35dd, + 0x080c, 0x6a8a, 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0x080c, + 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x2009, 0x0009, 0x1904, + 0x35dd, 0x080c, 0x4b89, 0x2009, 0x0002, 0x0904, 0x35dd, 0x9006, + 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, + 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, + 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x35e0, 0xc0e5, + 0xa952, 0xa956, 0xa83e, 0x080c, 0xd2d3, 0x2009, 0x0003, 0x0904, + 0x35dd, 0x7007, 0x0003, 0x701f, 0x546e, 0x0005, 0xa830, 0x9086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x7aa8, + 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x57e7, 0x1188, + 0x2009, 0x0014, 0x0804, 0x35dd, 0xd2dc, 0x1578, 0x81ff, 0x2009, + 0x0001, 0x1904, 0x35dd, 0x080c, 0x57e7, 0x2009, 0x0007, 0x1904, + 0x35dd, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x57ad, + 0x0804, 0x35ab, 0xd2fc, 0x0160, 0x080c, 0x4bbc, 0x0904, 0x35e0, + 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5782, 0x0804, 0x35ab, + 0x080c, 0x4bbc, 0x0904, 0x35e0, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x2009, 0x0009, 0x1904, 0x555d, 0x080c, 0x4b89, 0x2009, + 0x0002, 0x0904, 0x555d, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, + 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4bd2, 0x701f, + 0x54ca, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, + 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x35e0, 0xa866, + 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bbc, 0x1110, 0x0804, + 0x35e0, 0x2009, 0x0043, 0x080c, 0xd33f, 0x2009, 0x0003, 0x0904, + 0x555d, 0x7007, 0x0003, 0x701f, 0x54ee, 0x0005, 0xa830, 0x9086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x555d, 0x7984, 0x7aa8, 0x9284, + 0x1000, 0xc0d5, 0x080c, 0x5782, 0x0804, 0x35ab, 0x00c6, 0xaab0, + 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x57e7, 0x1158, + 0x2009, 0x0014, 0x0804, 0x554c, 0x2061, 0x1800, 0x080c, 0x57e7, + 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, + 0x080c, 0x57ad, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4bba, 0x0590, + 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5782, 0xa87b, 0x0000, + 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4bba, 0x0510, + 0x080c, 0x6a92, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, + 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, + 0x080c, 0x4bba, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd33f, + 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, + 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, + 0x35dd, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x5782, + 0x001e, 0x1904, 0x35dd, 0x0804, 0x35ab, 0x00f6, 0x2d78, 0xaab0, + 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, + 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x5782, 0x001e, 0x9085, + 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, + 0x080c, 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7984, + 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x671d, 0x1904, 0x35e0, 0x9186, + 0x007f, 0x0138, 0x080c, 0x6a92, 0x0120, 0x2009, 0x0009, 0x0804, + 0x35dd, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, + 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, + 0xa80a, 0x080c, 0xd03b, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd, + 0x7007, 0x0003, 0x701f, 0x55bd, 0x0005, 0xa808, 0x8007, 0x9086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35dd, 0xa8e0, 0xa866, + 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, + 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x0804, 0x4bd5, 0x080c, 0x4b89, 0x1120, 0x2009, + 0x0002, 0x0804, 0x35dd, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, + 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001, + 0x1118, 0x7023, 0x19cf, 0x0010, 0x0804, 0x35e0, 0x2009, 0x001a, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, + 0x080c, 0x4bd2, 0x701f, 0x560d, 0x0005, 0x2001, 0x182e, 0x2003, + 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, + 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x35ab, + 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x7984, + 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, + 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19cf, 0x0010, + 0x0804, 0x35e0, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, + 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, + 0x4bd5, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35e0, 0x0126, 0x2091, + 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x19fc, + 0x614a, 0x00ce, 0x012e, 0x0804, 0x35ab, 0x00c6, 0x080c, 0x7569, + 0x1160, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085, 0x0001, 0x080c, + 0x75ad, 0x080c, 0x7495, 0x080c, 0x0dc5, 0x2061, 0x1800, 0x6030, + 0xc09d, 0x6032, 0x080c, 0x5fe6, 0x00ce, 0x0005, 0x00c6, 0x2001, + 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35dd, 0x7884, 0x9005, + 0x0188, 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062, 0x080c, 0x2c62, + 0x01a0, 0x080c, 0x2c6a, 0x0188, 0x080c, 0x2c72, 0x0170, 0x2162, + 0x0804, 0x35e0, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, + 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, + 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, 0x2011, + 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c, 0xa8f7, 0x002e, + 0x080c, 0xa801, 0x0036, 0x901e, 0x080c, 0xa877, 0x003e, 0x60e3, + 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15, 0x9085, 0x0001, 0x080c, + 0x75ad, 0x9006, 0x080c, 0x2d52, 0x2001, 0x1800, 0x2003, 0x0004, + 0x2001, 0x19a9, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce, 0x0804, + 0x35ab, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x080c, + 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7984, 0x7ea8, + 0x96b4, 0x00ff, 0x080c, 0x671d, 0x1904, 0x35e0, 0x9186, 0x007f, + 0x0138, 0x080c, 0x6a92, 0x0120, 0x2009, 0x0009, 0x0804, 0x35dd, + 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd03e, 0x1120, 0x2009, + 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x5710, 0x0005, + 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35dd, + 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4bd5, 0xa898, + 0x9086, 0x000d, 0x1904, 0x35dd, 0x2021, 0x4005, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x5734, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, + 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, + 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, + 0x4bc5, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19fc, 0x7984, + 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, + 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x1a0c, + 0x2044, 0x2001, 0x1a13, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, + 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, + 0x0804, 0x35ab, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, + 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019, 0x0029, + 0x080c, 0x3360, 0x003e, 0x080c, 0xcea3, 0x000e, 0x1198, 0xd0e4, + 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x6141, + 0x080c, 0xb06b, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, + 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, + 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, + 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, 0x007f, + 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, + 0x2200, 0x080c, 0x5782, 0x002e, 0x001e, 0x8108, 0x1f04, 0x57b5, + 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004, 0x0005, 0x2001, + 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4, + 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071, + 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, + 0x81ff, 0x0904, 0x35e0, 0x9182, 0x0081, 0x1a04, 0x35e0, 0x810c, + 0x0016, 0x080c, 0x4b89, 0x0170, 0x080c, 0x0f16, 0x2100, 0x2238, + 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4bd2, 0x701f, + 0x5817, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2079, + 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, + 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e, 0x080c, 0x4bd5, + 0x701f, 0x582b, 0x0005, 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026, + 0xa270, 0xa174, 0x080c, 0x0f1e, 0x002e, 0x001e, 0x080c, 0x0fcb, + 0x9006, 0xa802, 0xa806, 0x0804, 0x35ab, 0x0126, 0x0156, 0x0136, + 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, + 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, + 0xd084, 0x0118, 0x080c, 0x59e6, 0x0068, 0xd08c, 0x0118, 0x080c, + 0x58ef, 0x0040, 0xd094, 0x0118, 0x080c, 0x58bf, 0x0018, 0xd09c, + 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, + 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, + 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7098, 0x9005, + 0x000e, 0x0120, 0x709b, 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, + 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, + 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, + 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, + 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x60a3, 0x00f0, + 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, + 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, + 0x2009, 0x1c80, 0x200b, 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, + 0x2009, 0x000f, 0x2011, 0x5f89, 0x080c, 0x87a1, 0x0005, 0x2001, + 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, + 0x1528, 0x2011, 0x5f89, 0x080c, 0x8709, 0x6040, 0x9094, 0x0010, + 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, + 0x1f04, 0x58d5, 0x6242, 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, + 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, + 0x708f, 0x0000, 0x9006, 0x080c, 0x612c, 0x0000, 0x0005, 0x708c, + 0x908a, 0x0003, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x58f9, 0x594a, + 0x59e5, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, + 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, + 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5908, 0x080c, 0x0dc5, + 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, + 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x6108, 0x2079, + 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, + 0x080c, 0xadbc, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, + 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, + 0x0000, 0x080c, 0x5fba, 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, + 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, + 0x59c2, 0x6020, 0xd0b4, 0x1904, 0x59c0, 0x71a0, 0x81ff, 0x0904, + 0x59ae, 0x9486, 0x000c, 0x1904, 0x59bb, 0x9480, 0x0018, 0x8004, + 0x20a8, 0x080c, 0x6101, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, + 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x5967, 0x6043, + 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, + 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, + 0x07d0, 0x2011, 0x5f90, 0x080c, 0x87a1, 0x080c, 0x6108, 0x04c0, + 0x080c, 0x6101, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, + 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, + 0x9005, 0x0190, 0x080c, 0x6101, 0x2011, 0x026e, 0x2019, 0x1805, + 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, + 0x8318, 0x1f04, 0x59a2, 0x0078, 0x70a3, 0x0000, 0x080c, 0x6101, + 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00, + 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, + 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, + 0x1db8, 0x080c, 0xadbc, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, + 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, + 0x2011, 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x080c, 0xa50e, 0x08d8, 0x0005, 0x7098, 0x908a, + 0x001d, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5a17, 0x5a2a, 0x5a53, + 0x5a73, 0x5a99, 0x5ac8, 0x5aee, 0x5b26, 0x5b4c, 0x5b7a, 0x5bb5, + 0x5bed, 0x5c0b, 0x5c36, 0x5c58, 0x5c73, 0x5c7d, 0x5cb1, 0x5cd7, + 0x5d06, 0x5d2c, 0x5d64, 0x5da8, 0x5de5, 0x5e06, 0x5e5f, 0x5e81, + 0x5eaf, 0x5eaf, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, + 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, + 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, + 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5f90, 0x080c, + 0x87a1, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, + 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x2011, 0x5f90, + 0x080c, 0x8709, 0x709b, 0x0010, 0x080c, 0x5c7d, 0x0010, 0x7093, + 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, + 0x2011, 0x5f90, 0x080c, 0x8709, 0x080c, 0x6085, 0x2079, 0x0240, + 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, + 0x200b, 0x0000, 0x8108, 0x1f04, 0x5a68, 0x60c3, 0x0014, 0x080c, + 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, + 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe, + 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x6085, 0x2079, 0x0240, + 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4, + 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, + 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0168, 0x080c, 0x60ba, 0x20a9, + 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, + 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005, + 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, + 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0007, 0x080c, 0x6085, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, + 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4, 0x11b8, 0x7084, 0x9005, + 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33ac, 0x200d, + 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0180, + 0x080c, 0x50cf, 0x0110, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, + 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, + 0x6085, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, + 0x60e4, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5eb0, 0x1188, + 0x9085, 0x0001, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, - 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, - 0x7090, 0x9005, 0x0500, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, - 0x0014, 0x11b8, 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, - 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, 0x0029, - 0x0010, 0x080c, 0x60e4, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0007, - 0x080c, 0x608c, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, - 0x080c, 0x6108, 0x080c, 0x60eb, 0x11b8, 0x7084, 0x9005, 0x11a0, - 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33b6, 0x200d, 0x918c, - 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f44, 0x0180, 0x080c, - 0x50d1, 0x0110, 0x080c, 0x28dc, 0x20a9, 0x0008, 0x20e1, 0x0000, - 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, - 0x0014, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, - 0x0500, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0014, 0x11b8, - 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, - 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, - 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, 0x080c, - 0x60e4, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, 0x608c, - 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x60eb, - 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5eb7, 0x1188, 0x9085, - 0x0001, 0x080c, 0x28dc, 0x20a9, 0x0008, 0x080c, 0x6108, 0x20e1, + 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fba, 0x0010, 0x080c, 0x5a0a, + 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011, 0x5f90, + 0x080c, 0x8709, 0x9086, 0x0014, 0x1560, 0x080c, 0x6101, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, + 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, + 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, + 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, 0x000e, 0x080c, 0x5c58, + 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, + 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, + 0xffff, 0x4304, 0x080c, 0x6085, 0x2079, 0x0240, 0x7833, 0x1106, + 0x7837, 0x0000, 0x080c, 0x60e4, 0x0118, 0x2013, 0x0000, 0x0020, + 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, + 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, + 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5bda, 0x60c3, + 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x01c0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084, 0x1178, + 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, + 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, + 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, 0x080c, 0x6085, + 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x6101, + 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, + 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, + 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c1e, + 0x60c3, 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x01e0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084, + 0x1198, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, + 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x6057, + 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005, + 0x918d, 0x0001, 0x080c, 0x612c, 0x709b, 0x000f, 0x7093, 0x0000, + 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, + 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5f90, + 0x080c, 0x86fd, 0x0005, 0x7090, 0x9005, 0x0130, 0x2011, 0x5f90, + 0x080c, 0x8709, 0x709b, 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, + 0xadbc, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, + 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, + 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x60e4, 0x11a0, + 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, + 0x080c, 0x2894, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, + 0x2011, 0x0008, 0x080c, 0x5f3d, 0x60c3, 0x0014, 0x080c, 0x5fba, + 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, + 0x8709, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, + 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, + 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, + 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, + 0x709b, 0x0013, 0x080c, 0x6093, 0x2079, 0x0240, 0x7833, 0x1103, + 0x7837, 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4, 0x1170, 0x7084, + 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, + 0x080c, 0x5f3d, 0x0168, 0x080c, 0x60ba, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, - 0x60c3, 0x0014, 0x080c, 0x5fc1, 0x0010, 0x080c, 0x5a11, 0x00fe, - 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011, 0x5f97, 0x080c, - 0x883d, 0x9086, 0x0014, 0x1560, 0x080c, 0x6108, 0x2079, 0x0260, - 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, 0x2011, - 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, - 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, 0x9005, - 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, - 0x0001, 0x7097, 0x0000, 0x709b, 0x000e, 0x080c, 0x5c5f, 0x0010, - 0x080c, 0x60e4, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, 0x2011, - 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, - 0x4304, 0x080c, 0x608c, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, - 0x0000, 0x080c, 0x60eb, 0x0118, 0x2013, 0x0000, 0x0020, 0x7060, - 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, - 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, - 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5be1, 0x60c3, 0x0084, - 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01c0, - 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0084, 0x1178, 0x080c, - 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, - 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, 0x60e4, - 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, 0x080c, 0x608c, 0x2079, - 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x6108, 0x20a9, - 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108, - 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, - 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c25, 0x60c3, - 0x0084, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, - 0x01e0, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0084, 0x1198, - 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, - 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x605e, 0x709b, - 0x000e, 0x0029, 0x0010, 0x080c, 0x60e4, 0x00fe, 0x0005, 0x918d, - 0x0001, 0x080c, 0x6133, 0x709b, 0x000f, 0x7093, 0x0000, 0x2061, - 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, - 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5f97, 0x080c, - 0x8831, 0x0005, 0x7090, 0x9005, 0x0130, 0x2011, 0x5f97, 0x080c, - 0x883d, 0x709b, 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, 0xaf8e, - 0x080c, 0x6108, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, - 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, - 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x60eb, 0x11a0, 0x717c, - 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, 0x080c, - 0x2873, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, 0x2011, - 0x0008, 0x080c, 0x5f44, 0x60c3, 0x0014, 0x080c, 0x5fc1, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f97, 0x080c, 0x883d, - 0x9086, 0x0014, 0x11b8, 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, - 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0012, - 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, - 0x0013, 0x080c, 0x609a, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, - 0x0000, 0x080c, 0x6108, 0x080c, 0x60eb, 0x1170, 0x7084, 0x9005, - 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, - 0x5f44, 0x0168, 0x080c, 0x60c1, 0x20a9, 0x0008, 0x20e1, 0x0000, - 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, - 0x0014, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, - 0x0500, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0014, 0x11b8, - 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, - 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, - 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, 0x7093, - 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, 0x609a, - 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6108, - 0x080c, 0x60eb, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, - 0xffff, 0x0180, 0x9180, 0x33b6, 0x200d, 0x918c, 0xff00, 0x810f, - 0x2011, 0x0008, 0x080c, 0x5f44, 0x0180, 0x080c, 0x50d1, 0x0110, - 0x080c, 0x28dc, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, + 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, + 0x6093, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, + 0x6101, 0x080c, 0x60e4, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, + 0x9186, 0xffff, 0x0180, 0x9180, 0x33ac, 0x200d, 0x918c, 0xff00, + 0x810f, 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0180, 0x080c, 0x50cf, + 0x0110, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, + 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, + 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, + 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, 0x15a8, 0x080c, + 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, + 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, + 0x080c, 0x612c, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, + 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, + 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, + 0x612c, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, + 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, + 0x080c, 0xadbc, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x0260, + 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, + 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, + 0x026e, 0x709b, 0x0017, 0x080c, 0x60e4, 0x1150, 0x7084, 0x9005, + 0x1138, 0x080c, 0x5eb0, 0x1188, 0x9085, 0x0001, 0x080c, 0x28fd, + 0x20a9, 0x0008, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, - 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, 0x2011, - 0x5f97, 0x080c, 0x883d, 0x9086, 0x0014, 0x15a8, 0x080c, 0x6108, - 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, 0x9084, - 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, 0x080c, - 0x6133, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, - 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c4, - 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, 0x6133, - 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, 0x709b, - 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x080c, - 0xaf8e, 0x080c, 0x6108, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, - 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, - 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, 0x026e, - 0x709b, 0x0017, 0x080c, 0x60eb, 0x1150, 0x7084, 0x9005, 0x1138, - 0x080c, 0x5eb7, 0x1188, 0x9085, 0x0001, 0x080c, 0x28dc, 0x20a9, - 0x0008, 0x080c, 0x6108, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, - 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fc1, - 0x0010, 0x080c, 0x5a11, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01d8, - 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0084, 0x1190, 0x080c, - 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, - 0x9005, 0x1138, 0x9006, 0x080c, 0x6133, 0x709b, 0x0018, 0x0029, - 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0019, - 0x080c, 0x609a, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, - 0x080c, 0x6108, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, 0x0040, - 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, 0x8000, - 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e20, 0x2039, 0x1c0e, 0x080c, - 0x60eb, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, 0x8000, - 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, 0x2310, - 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118, 0x9294, - 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, 0x20a9, - 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, 0x0260, - 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5e53, - 0x60c3, 0x0084, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, - 0x9005, 0x01e0, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0084, - 0x1198, 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, - 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x605e, - 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, - 0x9085, 0x0001, 0x080c, 0x6133, 0x709b, 0x001b, 0x080c, 0xaf8e, - 0x080c, 0x6108, 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, 0x9480, - 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e, - 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, - 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, - 0x5e9f, 0x60c3, 0x0084, 0x080c, 0x5fc1, 0x0005, 0x0005, 0x0086, - 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, 0x1c0e, - 0x20e9, 0x0001, 0x28a0, 0x080c, 0x6108, 0x20e1, 0x0000, 0x2099, - 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, - 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, - 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5ed1, 0x0804, 0x5f40, - 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, - 0x91a6, 0x3fff, 0x0904, 0x5f40, 0x918d, 0xc000, 0x20a9, 0x0010, - 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, - 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, - 0x0008, 0x8318, 0x1f04, 0x5ef7, 0x04d8, 0x23a8, 0x2021, 0x0001, - 0x8426, 0x8425, 0x1f04, 0x5f09, 0x2328, 0x8529, 0x92be, 0x0007, - 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, - 0x95a8, 0x0010, 0x1f04, 0x5f18, 0x755e, 0x95c8, 0x33b6, 0x292d, - 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, - 0x28bc, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0x9405, - 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1, - 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, 0x0008, - 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, - 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, 0x01ce, - 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, 0x0218, - 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, 0x0010, - 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, - 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, 0x11b8, - 0x9405, 0x203a, 0x715e, 0x91a0, 0x33b6, 0x242d, 0x95ac, 0x00ff, - 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x28bc, 0x001e, - 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, 0x0005, - 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, 0x00e6, - 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x604d, 0x080c, - 0xa6e9, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d49, 0x0126, - 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, 0x0026, - 0x0016, 0x2009, 0x00f7, 0x080c, 0x60aa, 0x001e, 0x9094, 0x0010, - 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, - 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x2bce, 0x0228, 0x2011, - 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f2, 0x2013, 0x0000, - 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, - 0xa6e0, 0x6144, 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, 0x0018, - 0x718c, 0x918d, 0x1000, 0x2011, 0x1999, 0x2112, 0x2009, 0x07d0, - 0x2011, 0x5f97, 0x080c, 0x88d5, 0x0005, 0x0016, 0x0026, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x080c, 0xb244, 0x2009, 0x00f7, 0x080c, - 0x60aa, 0x2061, 0x19fb, 0x900e, 0x611a, 0x611e, 0x617a, 0x617e, - 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, - 0x6043, 0x0010, 0x2009, 0x1999, 0x200b, 0x0000, 0x2009, 0x002d, - 0x2011, 0x6019, 0x080c, 0x8831, 0x012e, 0x00ce, 0x002e, 0x001e, - 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, - 0x0100, 0x080c, 0xa6e9, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, - 0x0110, 0x080c, 0x2d49, 0x080c, 0x763f, 0x0188, 0x080c, 0x765a, - 0x1170, 0x080c, 0x793c, 0x0016, 0x080c, 0x298b, 0x2001, 0x196d, - 0x2102, 0x001e, 0x080c, 0x7937, 0x080c, 0x7563, 0x0050, 0x2009, - 0x0001, 0x080c, 0x2c67, 0x2001, 0x0001, 0x080c, 0x281c, 0x080c, - 0x5fed, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, - 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x1999, - 0x201c, 0x080c, 0x4c44, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, - 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x6108, 0x20e9, 0x0000, - 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6102, 0x2099, - 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6105, - 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016, 0x0026, - 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, - 0x6082, 0x002e, 0x001e, 0x0005, 0x080c, 0xaf8e, 0x20e1, 0x0001, - 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, - 0x4003, 0x0005, 0x080c, 0xaf8e, 0x080c, 0x6108, 0x20e1, 0x0000, - 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, - 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, - 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, 0x9084, - 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce, - 0x0005, 0x0016, 0x0046, 0x080c, 0x6a9f, 0x0158, 0x9006, 0x2020, - 0x2009, 0x002a, 0x080c, 0xec31, 0x2001, 0x180c, 0x200c, 0xc195, - 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x321b, 0x080c, 0xd7e3, - 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4dfb, - 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5fed, 0x709b, 0x0000, - 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, 0xd09c, - 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, - 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e, - 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008, - 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6, - 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001, - 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200, 0x7807, - 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827, - 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, 0x1800, - 0x2003, 0x0001, 0x0005, 0x2001, 0x19a7, 0x0118, 0x2003, 0x0001, - 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, 0x2009, - 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x6142, 0x015e, 0x0005, - 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006, - 0xb802, 0xb8ce, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, - 0x33b6, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb8c2, - 0x080c, 0xb23d, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbc2, 0x20a9, - 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, 0x23a0, - 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, 0x002e, - 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a, 0xb85e, - 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, - 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, - 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040, 0xb8a7, - 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, - 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, - 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, - 0x0dc5, 0x080c, 0x8cf7, 0x00ce, 0x090c, 0x9096, 0xb8af, 0x0000, - 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, - 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, - 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6230, 0x9182, 0x0800, 0x1a04, - 0x6234, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x623a, - 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084, 0x00ff, - 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x624c, 0xb850, - 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, 0x951c, - 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002, 0xa803, - 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e, 0x04b8, - 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, - 0xb23d, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, - 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, - 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, - 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, - 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, - 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, - 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, - 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x6aa3, 0x1990, 0xb800, - 0xd0bc, 0x0978, 0x0804, 0x61e3, 0x080c, 0x68c0, 0x0904, 0x61fc, - 0x0804, 0x61e7, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa874, - 0x908e, 0x00ff, 0x1120, 0x2001, 0x196b, 0x205c, 0x0060, 0xa974, - 0x9182, 0x0800, 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, 0x01d0, - 0x080c, 0x6a43, 0x11d0, 0x080c, 0xb27d, 0x0570, 0x2b00, 0x6012, - 0x2900, 0x6016, 0x6023, 0x0009, 0x600b, 0x0000, 0xa874, 0x908e, - 0x00ff, 0x1110, 0x600b, 0x8000, 0x2009, 0x0043, 0x080c, 0xb352, - 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, - 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, - 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, - 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00b6, - 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, - 0x631d, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x62f5, 0xb8a0, - 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x6aab, - 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, - 0x0005, 0x0118, 0x080c, 0x6aa3, 0x1598, 0xa87c, 0xd0fc, 0x01e0, - 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xd0c6, - 0x002e, 0x1120, 0x2001, 0x0008, 0x0804, 0x631f, 0x6020, 0x9086, - 0x000a, 0x0120, 0x2001, 0x0008, 0x0804, 0x631f, 0x601a, 0x6003, - 0x0008, 0x2900, 0x6016, 0x0058, 0x080c, 0xb27d, 0x05e8, 0x2b00, - 0x6012, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, - 0x0003, 0x080c, 0xb352, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, - 0x9082, 0x0006, 0x1290, 0x080c, 0xb23d, 0x1160, 0xb8a0, 0x9084, - 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, - 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, - 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, - 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, - 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, - 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, - 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, - 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, - 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, - 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, - 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, - 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, - 0x9006, 0x0008, 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, 0x63b4, - 0x636f, 0x6386, 0x63b4, 0x63b4, 0x63b4, 0x63b4, 0x63b4, 0x2100, - 0x9082, 0x007e, 0x1278, 0x080c, 0x66b9, 0x0148, 0x9046, 0xb810, - 0x9306, 0x1904, 0x63bc, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, - 0xba16, 0x0010, 0x080c, 0x4af7, 0x0150, 0x04b0, 0x080c, 0x6724, - 0x1598, 0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, - 0xb27d, 0x0530, 0x2b00, 0x6012, 0x080c, 0xd554, 0x2900, 0x6016, - 0x600b, 0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, - 0x080c, 0x3250, 0x9006, 0x080c, 0x6656, 0x2001, 0x0002, 0x080c, - 0x666a, 0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, - 0x080c, 0xb352, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, - 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, - 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, - 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, 0x65a7, - 0x90c6, 0x0056, 0x0904, 0x65ab, 0x90c6, 0x0066, 0x0904, 0x65af, - 0x90c6, 0x0067, 0x0904, 0x65b3, 0x90c6, 0x0068, 0x0904, 0x65b7, - 0x90c6, 0x0071, 0x0904, 0x65bb, 0x90c6, 0x0074, 0x0904, 0x65bf, - 0x90c6, 0x007c, 0x0904, 0x65c3, 0x90c6, 0x007e, 0x0904, 0x65c7, - 0x90c6, 0x0037, 0x0904, 0x65cb, 0x9016, 0x2079, 0x1800, 0xa974, - 0x9186, 0x00ff, 0x0904, 0x65a2, 0x9182, 0x0800, 0x1a04, 0x65a2, - 0x080c, 0x6724, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, - 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xb23d, 0x1904, - 0x658b, 0xb8a0, 0x9084, 0xff80, 0x1904, 0x658b, 0xa894, 0x90c6, - 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, 0x64eb, 0x90c6, 0x0064, - 0x0904, 0x6514, 0x2008, 0x0804, 0x64ad, 0xa998, 0xa8b0, 0x2040, - 0x080c, 0xb23d, 0x1120, 0x9182, 0x007f, 0x0a04, 0x64ad, 0x9186, - 0x00ff, 0x0904, 0x64ad, 0x9182, 0x0800, 0x1a04, 0x64ad, 0xaaa0, - 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, 0x1128, - 0x2208, 0x2310, 0x009e, 0x0804, 0x64ad, 0x080c, 0xb23d, 0x1140, - 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x64ad, - 0x009e, 0x080c, 0x4af7, 0x0904, 0x64b7, 0x900e, 0x9016, 0x90c6, - 0x4000, 0x15e0, 0x0006, 0x080c, 0x6944, 0x1108, 0xc185, 0xb800, - 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, - 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, - 0x2098, 0x080c, 0x0f8b, 0xa8c4, 0xabc8, 0x9305, 0xabcc, 0x9305, - 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, 0x9305, - 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, 0x4007, - 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, - 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, 0x0138, - 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, 0xa896, - 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, 0x080c, - 0xb27d, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c78, - 0x2b00, 0x6012, 0x080c, 0xd554, 0x2900, 0x6016, 0x6023, 0x0001, - 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, - 0x080c, 0x3250, 0x012e, 0x9006, 0x080c, 0x6656, 0x2001, 0x0002, - 0x080c, 0x666a, 0x2009, 0x0002, 0x080c, 0xb352, 0xa8b0, 0xd094, - 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x9006, 0x9005, 0x012e, 0x00ee, - 0x00fe, 0x00be, 0x0005, 0x080c, 0x57e9, 0x0118, 0x2009, 0x0007, - 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x6724, 0x1904, 0x64a8, 0x9186, - 0x007f, 0x0130, 0x080c, 0x6aa3, 0x0118, 0x2009, 0x0009, 0x0080, - 0x0096, 0x080c, 0x100e, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040, - 0x2900, 0x009e, 0xa806, 0x080c, 0xd2c0, 0x19b0, 0x2009, 0x0003, - 0x2001, 0x4005, 0x0804, 0x64af, 0xa998, 0xaeb0, 0x080c, 0x6724, - 0x1904, 0x64a8, 0x0096, 0x080c, 0x100e, 0x1128, 0x009e, 0x2009, - 0x0002, 0x0804, 0x6568, 0x2900, 0x009e, 0xa806, 0x0096, 0x2048, - 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, - 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, - 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, 0x0f8b, - 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xd684, - 0x1168, 0x080c, 0x57d5, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, - 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x6aa3, - 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x57e9, 0x0118, 0xa89b, - 0x0007, 0x0050, 0x080c, 0xd2a3, 0x1904, 0x64e4, 0x2009, 0x0003, - 0x2001, 0x4005, 0x0804, 0x64af, 0xa87b, 0x0030, 0xa897, 0x4005, - 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, - 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, 0xb7f1, 0x1904, 0x64e4, - 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x64e5, - 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, - 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, - 0x0804, 0x64e5, 0x2001, 0x0029, 0x900e, 0x0804, 0x64e5, 0x080c, - 0x37e9, 0x0804, 0x64e6, 0x080c, 0x5500, 0x0804, 0x64e6, 0x080c, - 0x4637, 0x0804, 0x64e6, 0x080c, 0x46b0, 0x0804, 0x64e6, 0x080c, - 0x470c, 0x0804, 0x64e6, 0x080c, 0x4bba, 0x0804, 0x64e6, 0x080c, - 0x4e82, 0x0804, 0x64e6, 0x080c, 0x5167, 0x0804, 0x64e6, 0x080c, - 0x5360, 0x0804, 0x64e6, 0x080c, 0x3a25, 0x0804, 0x64e6, 0x00b6, - 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1618, 0x9182, - 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, 0x905d, 0x0140, 0x080c, - 0x6aa3, 0x1148, 0x00e9, 0x080c, 0x684f, 0x9006, 0x00b0, 0x2001, - 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, 0xb900, 0xd1fc, - 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, 0x2001, 0x0029, - 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x00be, 0x0005, - 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, 0x0150, 0x2900, 0x0096, - 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, 0xb852, 0x012e, 0x0005, - 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, 0x0126, 0x2091, - 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071, 0x19e8, 0x7004, - 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802, 0x2900, 0xb84e, - 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, - 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050, 0xb000, 0xa802, - 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, - 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, - 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, 0x904d, 0x0130, 0xa800, - 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x0005, 0x00b6, 0x0126, - 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, - 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, - 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, - 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, - 0x0158, 0x080c, 0x6a9f, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, - 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, - 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, - 0x0dc5, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, - 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, - 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6a9b, 0x1138, - 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, - 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, - 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, - 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, - 0x100e, 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, - 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x6148, 0x9006, - 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, - 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, - 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, - 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040, 0x00d6, - 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, - 0x2048, 0x080c, 0xd0d8, 0x0110, 0x080c, 0x0fc0, 0x080c, 0xb2d3, - 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, - 0x621c, 0xd2c4, 0x0110, 0x080c, 0x9096, 0x00ce, 0x2b48, 0xb8c8, - 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x1050, 0x00de, 0x9006, 0x002e, - 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, - 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, - 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, - 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x7637, 0x1510, - 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xb23d, 0x11d8, 0x0078, - 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1982, 0x7048, 0x2062, - 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, - 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, - 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, - 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, - 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, - 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, - 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, - 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, - 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, - 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, - 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, - 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, - 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, - 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, - 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, - 0x7054, 0xb89e, 0x0036, 0xbbcc, 0xc384, 0xba00, 0x2009, 0x1867, - 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, - 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, - 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbce, 0x003e, 0x00ee, - 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, - 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, - 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, - 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, - 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, - 0x8109, 0x1dd0, 0x080c, 0x0dc5, 0x3c00, 0x20e8, 0x3300, 0x8001, - 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, - 0x0060, 0x080c, 0x100e, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, - 0x080c, 0x68e0, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, - 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, - 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x68ef, - 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, - 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0126, - 0x2091, 0x8000, 0x080c, 0x951c, 0x012e, 0x0005, 0x901e, 0x0010, - 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, 0x2048, - 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878, - 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, - 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0xaaf1, 0xaa00, - 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202, - 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, 0x9016, - 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x6944, 0x0128, - 0x080c, 0xd195, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6944, - 0x0128, 0x080c, 0xd13a, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, - 0x6944, 0x0128, 0x080c, 0xd192, 0x0010, 0x9085, 0x0001, 0x0005, - 0x080c, 0x6944, 0x0128, 0x080c, 0xd159, 0x0010, 0x9085, 0x0001, - 0x0005, 0x080c, 0x6944, 0x0128, 0x080c, 0xd1d8, 0x0010, 0x9085, - 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005, + 0x5fba, 0x0010, 0x080c, 0x5a0a, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x01d8, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084, 0x1190, + 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, + 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x612c, 0x709b, 0x0018, + 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0019, 0x080c, 0x6093, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, + 0x0000, 0x080c, 0x6101, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, + 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, + 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e19, 0x2039, 0x1c0e, + 0x080c, 0x60e4, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, + 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, + 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118, + 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, + 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, + 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, + 0x5e4c, 0x60c3, 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, + 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, + 0x0084, 0x1198, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, + 0x6057, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, + 0x0005, 0x9085, 0x0001, 0x080c, 0x612c, 0x709b, 0x001b, 0x080c, + 0xadbc, 0x080c, 0x6101, 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, + 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, + 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, + 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, + 0x1f04, 0x5e98, 0x60c3, 0x0084, 0x080c, 0x5fba, 0x0005, 0x0005, + 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, + 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x6101, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, + 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, + 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5eca, 0x0804, + 0x5f39, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, + 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f39, 0x918d, 0xc000, 0x20a9, + 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, + 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, + 0x8319, 0x0008, 0x8318, 0x1f04, 0x5ef0, 0x04d8, 0x23a8, 0x2021, + 0x0001, 0x8426, 0x8425, 0x1f04, 0x5f02, 0x2328, 0x8529, 0x92be, + 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, + 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f11, 0x755e, 0x95c8, 0x33ac, + 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, + 0x080c, 0x28dd, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, + 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, + 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, + 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, + 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, + 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, + 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, + 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, + 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, 0x33ac, 0x242d, 0x95ac, + 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x28dd, + 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, + 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x6046, + 0x080c, 0xa517, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d62, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, + 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x60a3, 0x001e, 0x9094, + 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x2be7, 0x0228, + 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f3, 0x2013, + 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, + 0x080c, 0xa50e, 0x6144, 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, + 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x199a, 0x2112, 0x2009, + 0x07d0, 0x2011, 0x5f90, 0x080c, 0x87a1, 0x0005, 0x0016, 0x0026, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb072, 0x2009, 0x00f7, + 0x080c, 0x60a3, 0x2061, 0x19fc, 0x900e, 0x611a, 0x611e, 0x617a, + 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, + 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009, + 0x002d, 0x2011, 0x6012, 0x080c, 0x86fd, 0x012e, 0x00ce, 0x002e, + 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, + 0x2071, 0x0100, 0x080c, 0xa517, 0x2071, 0x0140, 0x7004, 0x9084, + 0x4000, 0x0110, 0x080c, 0x2d62, 0x080c, 0x7571, 0x0188, 0x080c, + 0x758c, 0x1170, 0x080c, 0x7858, 0x0016, 0x080c, 0x29ac, 0x2001, + 0x196e, 0x2102, 0x001e, 0x080c, 0x7853, 0x080c, 0x7495, 0x0050, + 0x2009, 0x0001, 0x080c, 0x2c80, 0x2001, 0x0001, 0x080c, 0x283d, + 0x080c, 0x5fe6, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, + 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, + 0x199a, 0x201c, 0x080c, 0x4be9, 0x003e, 0x002e, 0x0005, 0x20a9, + 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x6101, 0x20e9, + 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x60fb, + 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, + 0x60fe, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016, + 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, + 0x1f04, 0x607b, 0x002e, 0x001e, 0x0005, 0x080c, 0xadbc, 0x20e1, + 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x000c, 0x4003, 0x0005, 0x080c, 0xadbc, 0x080c, 0x6101, 0x20e1, + 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, + 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, + 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, + 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6a8e, 0x0158, 0x9006, + 0x2020, 0x2009, 0x002a, 0x080c, 0xe9a5, 0x2001, 0x180c, 0x200c, + 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3211, 0x080c, + 0xd561, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, + 0x4da0, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5fe6, 0x709b, + 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, + 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, + 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, + 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, + 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, + 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, + 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200, + 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, + 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, + 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a8, 0x0118, 0x2003, + 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, + 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x613b, 0x015e, + 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, + 0x9006, 0xb802, 0xb8ce, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, + 0x9198, 0x33ac, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, + 0xb8c2, 0x080c, 0xb06b, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbc2, + 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, + 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, + 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a, + 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, + 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, + 0xb8be, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040, + 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, + 0xb846, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, + 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, 0x9c02, + 0x1a0c, 0x0dc5, 0x080c, 0x8bc3, 0x00ce, 0x090c, 0x8f64, 0xb8af, + 0x0000, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, + 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6229, 0x9182, 0x0800, + 0x1a04, 0x622d, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, + 0x6233, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084, + 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x6245, + 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, + 0x9358, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002, + 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e, + 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, + 0x080c, 0xb06b, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, + 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, + 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, + 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, + 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, + 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, + 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, + 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x6a92, 0x1990, + 0xb800, 0xd0bc, 0x0978, 0x0804, 0x61dc, 0x080c, 0x68b9, 0x0904, + 0x61f5, 0x0804, 0x61e0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, + 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, 0x196c, 0x205c, 0x0060, + 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, + 0x01d0, 0x080c, 0x6a32, 0x11d0, 0x080c, 0xb0ab, 0x0570, 0x2b00, + 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x600b, 0x0000, 0xa874, + 0x908e, 0x00ff, 0x1110, 0x600b, 0x8000, 0x2009, 0x0043, 0x080c, + 0xb180, 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, + 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, + 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, + 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, + 0x1a04, 0x6316, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x62ee, + 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, + 0x6a9a, 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, + 0x908e, 0x0005, 0x0118, 0x080c, 0x6a92, 0x1598, 0xa87c, 0xd0fc, + 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, + 0xce44, 0x002e, 0x1120, 0x2001, 0x0008, 0x0804, 0x6318, 0x6020, + 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, 0x0804, 0x6318, 0x601a, + 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, 0x080c, 0xb0ab, 0x05e8, + 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, + 0x2009, 0x0003, 0x080c, 0xb180, 0x9006, 0x0458, 0x2001, 0x0028, + 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, 0xb06b, 0x1160, 0xb8a0, + 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, + 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, + 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, + 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, + 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, + 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, + 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, + 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, + 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, + 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, + 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, + 0x63ad, 0x6368, 0x637f, 0x63ad, 0x63ad, 0x63ad, 0x63ad, 0x63ad, + 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, 0x66b2, 0x0148, 0x9046, + 0xb810, 0x9306, 0x1904, 0x63b5, 0xb814, 0x9206, 0x15f0, 0x0028, + 0xbb12, 0xba16, 0x0010, 0x080c, 0x4a9c, 0x0150, 0x04b0, 0x080c, + 0x671d, 0x1598, 0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, + 0x080c, 0xb0ab, 0x0530, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x2900, + 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, + 0x1170, 0x080c, 0x3246, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, + 0x080c, 0x6663, 0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, + 0x0003, 0x080c, 0xb180, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, + 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, + 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, + 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, + 0x65a0, 0x90c6, 0x0056, 0x0904, 0x65a4, 0x90c6, 0x0066, 0x0904, + 0x65a8, 0x90c6, 0x0067, 0x0904, 0x65ac, 0x90c6, 0x0068, 0x0904, + 0x65b0, 0x90c6, 0x0071, 0x0904, 0x65b4, 0x90c6, 0x0074, 0x0904, + 0x65b8, 0x90c6, 0x007c, 0x0904, 0x65bc, 0x90c6, 0x007e, 0x0904, + 0x65c0, 0x90c6, 0x0037, 0x0904, 0x65c4, 0x9016, 0x2079, 0x1800, + 0xa974, 0x9186, 0x00ff, 0x0904, 0x659b, 0x9182, 0x0800, 0x1a04, + 0x659b, 0x080c, 0x671d, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, + 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xb06b, + 0x1904, 0x6584, 0xb8a0, 0x9084, 0xff80, 0x1904, 0x6584, 0xa894, + 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, 0x64e4, 0x90c6, + 0x0064, 0x0904, 0x650d, 0x2008, 0x0804, 0x64a6, 0xa998, 0xa8b0, + 0x2040, 0x080c, 0xb06b, 0x1120, 0x9182, 0x007f, 0x0a04, 0x64a6, + 0x9186, 0x00ff, 0x0904, 0x64a6, 0x9182, 0x0800, 0x1a04, 0x64a6, + 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, + 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, 0x64a6, 0x080c, 0xb06b, + 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, + 0x64a6, 0x009e, 0x080c, 0x4a9c, 0x0904, 0x64b0, 0x900e, 0x9016, + 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, 0x693d, 0x1108, 0xc185, + 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x000a, 0x2098, 0x080c, 0x0f8b, 0xa8c4, 0xabc8, 0x9305, 0xabcc, + 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, + 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, + 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, + 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, + 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, + 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, + 0x080c, 0xb0ab, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, + 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x2900, 0x6016, 0x6023, + 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x3246, 0x012e, 0x9006, 0x080c, 0x664f, 0x2001, + 0x0002, 0x080c, 0x6663, 0x2009, 0x0002, 0x080c, 0xb180, 0xa8b0, + 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x9006, 0x9005, 0x012e, + 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x57e7, 0x0118, 0x2009, + 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x671d, 0x1904, 0x64a1, + 0x9186, 0x007f, 0x0130, 0x080c, 0x6a92, 0x0118, 0x2009, 0x0009, + 0x0080, 0x0096, 0x080c, 0x100e, 0x1120, 0x009e, 0x2009, 0x0002, + 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xd03e, 0x19b0, 0x2009, + 0x0003, 0x2001, 0x4005, 0x0804, 0x64a8, 0xa998, 0xaeb0, 0x080c, + 0x671d, 0x1904, 0x64a1, 0x0096, 0x080c, 0x100e, 0x1128, 0x009e, + 0x2009, 0x0002, 0x0804, 0x6561, 0x2900, 0x009e, 0xa806, 0x0096, + 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, + 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, + 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, + 0x0f8b, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0xd684, 0x1168, 0x080c, 0x57d3, 0xd0b4, 0x1118, 0xa89b, 0x000b, + 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, + 0x6a92, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x57e7, 0x0118, + 0xa89b, 0x0007, 0x0050, 0x080c, 0xd021, 0x1904, 0x64dd, 0x2009, + 0x0003, 0x2001, 0x4005, 0x0804, 0x64a8, 0xa87b, 0x0030, 0xa897, + 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, + 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, 0xb61f, 0x1904, + 0x64dd, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, + 0x64de, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, + 0x900e, 0x0804, 0x64de, 0x2001, 0x0029, 0x900e, 0x0804, 0x64de, + 0x080c, 0x37dd, 0x0804, 0x64df, 0x080c, 0x54fe, 0x0804, 0x64df, + 0x080c, 0x460c, 0x0804, 0x64df, 0x080c, 0x4685, 0x0804, 0x64df, + 0x080c, 0x46e1, 0x0804, 0x64df, 0x080c, 0x4b5f, 0x0804, 0x64df, + 0x080c, 0x4e13, 0x0804, 0x64df, 0x080c, 0x5165, 0x0804, 0x64df, + 0x080c, 0x535e, 0x0804, 0x64df, 0x080c, 0x3a07, 0x0804, 0x64df, + 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1618, + 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, 0x905d, 0x0140, + 0x080c, 0x6a92, 0x1148, 0x00e9, 0x080c, 0x6848, 0x9006, 0x00b0, + 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, 0xb900, + 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, 0x2001, + 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x00be, + 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, 0x0150, 0x2900, + 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, 0xb852, 0x012e, + 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, 0x0126, + 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071, 0x19e9, + 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802, 0x2900, + 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, + 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050, 0xb000, + 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005, 0x0126, + 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, + 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, 0x904d, 0x0130, + 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x0005, 0x00b6, + 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, + 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, + 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, + 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, + 0xd0ac, 0x0158, 0x080c, 0x6a8e, 0x0140, 0x9284, 0xff00, 0x8007, + 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, + 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, + 0x090c, 0x0dc5, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, + 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, + 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6a8a, + 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, + 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, + 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, + 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, + 0x080c, 0x100e, 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, + 0xb8ca, 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x6141, + 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, + 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, + 0x9085, 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, + 0x0568, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040, + 0x00d6, 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, + 0x6014, 0x2048, 0x080c, 0xce56, 0x0110, 0x080c, 0x0fc0, 0x080c, + 0xb101, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, + 0x0128, 0x621c, 0xd2c4, 0x0110, 0x080c, 0x8f64, 0x00ce, 0x2b48, + 0xb8c8, 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x1050, 0x00de, 0x9006, + 0x002e, 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, + 0x0218, 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, + 0x0dc0, 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, + 0x9006, 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x7569, + 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xb06b, 0x11d8, + 0x0078, 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1983, 0x7048, + 0x2062, 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, + 0x703c, 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, + 0x2069, 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, + 0xb866, 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, + 0x9088, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, + 0x9088, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, + 0x6817, 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, + 0x7050, 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, + 0x007e, 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, + 0x0008, 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, + 0x9182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, + 0x1218, 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, + 0x0004, 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, + 0x2009, 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, + 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, + 0xb89a, 0x7054, 0xb89e, 0x0036, 0xbbcc, 0xc384, 0xba00, 0x2009, + 0x1867, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, + 0xc2ac, 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, + 0xd38c, 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbce, 0x003e, + 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, + 0xb8a4, 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, + 0x0010, 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, + 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, + 0x2098, 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, + 0x0120, 0x8109, 0x1dd0, 0x080c, 0x0dc5, 0x3c00, 0x20e8, 0x3300, + 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, + 0x013e, 0x0060, 0x080c, 0x100e, 0x0170, 0x2900, 0xb8a6, 0xa803, + 0x0000, 0x080c, 0x68d9, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, + 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, + 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, + 0x68e8, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, + 0x0020, 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0x080c, 0x9358, 0x012e, 0x0005, 0x901e, + 0x0010, 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, + 0x2048, 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, + 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, + 0x9506, 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0xa91f, + 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, + 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, + 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x693d, + 0x0128, 0x080c, 0xcf13, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, + 0x693d, 0x0128, 0x080c, 0xceb8, 0x0010, 0x9085, 0x0001, 0x0005, + 0x080c, 0x693d, 0x0128, 0x080c, 0xcf10, 0x0010, 0x9085, 0x0001, + 0x0005, 0x080c, 0x693d, 0x0128, 0x080c, 0xced7, 0x0010, 0x9085, + 0x0001, 0x0005, 0x080c, 0x693d, 0x0128, 0x080c, 0xcf56, 0x0010, + 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, + 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, + 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, + 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, + 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, + 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, + 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, - 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005, - 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0, - 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136, - 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, - 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, - 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, - 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, - 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006, - 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, - 0x904d, 0x1128, 0x080c, 0x100e, 0x0168, 0x2900, 0xb8a6, 0x080c, - 0x68e0, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, - 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, - 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1040, 0x9085, - 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, - 0x00f6, 0x080c, 0x7637, 0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc, - 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d, - 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, - 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0, 0x0156, - 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6724, 0x1168, 0xb804, - 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, - 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x696b, - 0x015e, 0x080c, 0x6a61, 0x0120, 0x2001, 0x1985, 0x200c, 0x0098, - 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0190, 0x2009, 0x07d0, 0x2001, - 0x182c, 0x2004, 0x9005, 0x0138, 0x2001, 0x1867, 0x2004, 0xd0e4, - 0x0110, 0x2009, 0x5dc0, 0x2011, 0x69a2, 0x080c, 0x88d5, 0x00fe, - 0x00be, 0x0005, 0x00b6, 0x2011, 0x69a2, 0x080c, 0x883d, 0x080c, - 0x6a61, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, - 0xb902, 0x080c, 0x6a9f, 0x0130, 0x2009, 0x07d0, 0x2011, 0x69a2, - 0x080c, 0x88d5, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, - 0x7082, 0x080c, 0x3000, 0x00ee, 0x04b0, 0x0156, 0x00c6, 0x20a9, - 0x007f, 0x900e, 0x0016, 0x080c, 0x6724, 0x1538, 0xb800, 0xd0ec, - 0x0520, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, - 0xec31, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a9b, 0x2001, - 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, - 0x2019, 0x0029, 0x080c, 0x96a4, 0x0076, 0x903e, 0x080c, 0x9577, - 0x900e, 0x080c, 0xe91c, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, - 0x69ca, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, - 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x0096, - 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2958, 0x009e, 0x2001, 0x196b, - 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, 0x908c, - 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, 0x6148, - 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, 0x0200, - 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, 0xb8af, - 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, - 0x00be, 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, 0xb804, 0x908c, - 0x00ff, 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, 0x0170, 0x9196, - 0x0005, 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, 0x0006, 0x0128, - 0x9196, 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, 0x001e, 0x000e, - 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, - 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, - 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, - 0x0dc5, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, - 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, 0x2204, 0xd0cc, - 0x0138, 0x2001, 0x1983, 0x200c, 0x2011, 0x6a91, 0x080c, 0x88d5, - 0x0005, 0x2011, 0x6a91, 0x080c, 0x883d, 0x2011, 0x1837, 0x2204, - 0xc0cc, 0x2012, 0x0005, 0x080c, 0x57d5, 0xd0ac, 0x0005, 0x080c, - 0x57d5, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, - 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, - 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xd7e3, - 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, - 0x905d, 0x0110, 0xb8cc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, - 0x0016, 0x0036, 0x0046, 0x0076, 0x00b6, 0x2001, 0x1818, 0x203c, - 0x9780, 0x33b6, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, - 0x2008, 0x9284, 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, - 0x2100, 0x9706, 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, - 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, - 0xb89c, 0xd0a4, 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, - 0x9182, 0x0800, 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, - 0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, - 0x0005, 0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, - 0x0005, 0x0046, 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, - 0x9080, 0x1000, 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, - 0x9086, 0x0006, 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1818, - 0x203c, 0x9780, 0x33b6, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, - 0x2020, 0x2400, 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, - 0x0178, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, - 0xd0a4, 0x0130, 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, - 0x8420, 0x9482, 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, - 0x007e, 0x005e, 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, - 0x00be, 0x007e, 0x005e, 0x004e, 0x9006, 0x0005, 0x0006, 0x2001, - 0x00a0, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x000e, 0x0005, - 0x0006, 0x2001, 0x00f8, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, - 0x000e, 0x0005, 0x0006, 0x2001, 0x00e8, 0x8001, 0xa001, 0xa001, - 0xa001, 0x1dd8, 0x000e, 0x0005, 0x2071, 0x1910, 0x7003, 0x0001, - 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, 0x700a, - 0x7046, 0x2001, 0x1922, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, - 0x2071, 0x1948, 0x900e, 0x710a, 0x080c, 0x57d5, 0xd0fc, 0x1140, - 0x080c, 0x57d5, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0470, - 0x2001, 0x1867, 0x200c, 0x9184, 0x0007, 0x0006, 0x2001, 0x180d, - 0x2004, 0xd08c, 0x000e, 0x0108, 0x9006, 0x0002, 0x6b98, 0x6b98, - 0x6b98, 0x6b98, 0x6b98, 0x6bb6, 0x6bcb, 0x6bd9, 0x7003, 0x0003, - 0x2009, 0x1868, 0x210c, 0x9184, 0xff00, 0x908e, 0xff00, 0x0140, - 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, 0x7006, 0x0030, - 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, 0x2071, 0x1910, - 0x704f, 0x0000, 0x2071, 0x1800, 0x70f3, 0x0001, 0x00ee, 0x001e, - 0x0005, 0x7003, 0x0000, 0x2071, 0x1910, 0x2009, 0x1868, 0x210c, - 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160, 0x714e, 0x8004, - 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c, 0x0007, 0x0128, - 0x70f2, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70f3, 0x0005, 0x08f0, - 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6, 0x2071, - 0x1910, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001, 0x0488, - 0x6844, 0x9005, 0x0158, 0x080c, 0x79a4, 0x6a60, 0x9200, 0x7002, - 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6860, 0x7002, - 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, 0x6844, 0x9005, - 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, 0x9085, 0x0040, - 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071, 0x1910, - 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, - 0x9006, 0x00ee, 0x0005, 0x00e6, 0x0026, 0x2071, 0x1948, 0x7000, - 0x9015, 0x0904, 0x6ea5, 0x9286, 0x0003, 0x0904, 0x6d3e, 0x9286, - 0x0005, 0x0904, 0x6d3e, 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, - 0x6c99, 0x7140, 0xa868, 0x9102, 0x0a04, 0x6ea5, 0xa878, 0xd084, - 0x15d8, 0xa853, 0x0019, 0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, - 0x701c, 0x9005, 0x1904, 0x7073, 0x0e04, 0x70e1, 0x2071, 0x0000, - 0xa850, 0x7032, 0xa84c, 0x7082, 0xa870, 0x7086, 0xa86c, 0x708a, - 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, - 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, - 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, - 0x01de, 0x014e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11aa, 0x0804, 0x6d21, 0xa853, 0x001b, 0x2001, 0x8027, - 0x0820, 0x7004, 0xd08c, 0x1904, 0x6ea5, 0xa853, 0x001a, 0x2001, - 0x8024, 0x0804, 0x6c5d, 0x00e6, 0x0026, 0x2071, 0x1948, 0x7000, - 0x9015, 0x0904, 0x6ea5, 0x9286, 0x0003, 0x0904, 0x6d3e, 0x9286, - 0x0005, 0x0904, 0x6d3e, 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, - 0x6d06, 0xa868, 0xd0fc, 0x1508, 0x00e6, 0x0026, 0x2001, 0x1948, - 0x2004, 0x9015, 0x0904, 0x6ea5, 0xa978, 0xa874, 0x9105, 0x1904, - 0x6ea5, 0x9286, 0x0003, 0x0904, 0x6d3e, 0x9286, 0x0005, 0x0904, - 0x6d3e, 0xa87c, 0xd0bc, 0x1904, 0x6ea5, 0x2200, 0x0002, 0x6ea5, - 0x6d02, 0x6d3e, 0x6d3e, 0x6ea5, 0x6d3e, 0x0005, 0xa868, 0xd0fc, - 0x1500, 0x00e6, 0x0026, 0x2009, 0x1948, 0x210c, 0x81ff, 0x0904, - 0x6ea5, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x6ea5, - 0x9186, 0x0003, 0x0904, 0x6d3e, 0x9186, 0x0005, 0x0904, 0x6d3e, - 0xa87c, 0xd0cc, 0x0904, 0x6ea5, 0xa84f, 0x8021, 0xa853, 0x0017, - 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, 0x0016, 0x2071, 0x1910, - 0x701c, 0x9005, 0x1904, 0x7073, 0x0e04, 0x70e1, 0x2071, 0x0000, - 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, - 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x11aa, 0x2071, 0x1800, 0x2011, 0x0001, 0xa804, 0x900d, 0x702c, - 0x1158, 0xa802, 0x2900, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, - 0x8725, 0x002e, 0x00ee, 0x0005, 0x0096, 0x2148, 0xa904, 0xa802, - 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, - 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, - 0x9005, 0x1904, 0x6e29, 0x782c, 0x908c, 0x0780, 0x190c, 0x722f, - 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6d5c, 0x6e29, - 0x6d80, 0x6dc6, 0x080c, 0x0dc5, 0x2071, 0x1800, 0x2900, 0x7822, - 0xa804, 0x900d, 0x1168, 0x2071, 0x19fb, 0x7044, 0x9005, 0x1320, - 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, + 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, + 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, + 0xb8a4, 0x904d, 0x1128, 0x080c, 0x100e, 0x0168, 0x2900, 0xb8a6, + 0x080c, 0x68d9, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, + 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, + 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1040, + 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, + 0x00b6, 0x00f6, 0x080c, 0x7569, 0x01b0, 0x71c4, 0x81ff, 0x1198, + 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, + 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, + 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0, + 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d, 0x1168, + 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, + 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, + 0x6964, 0x015e, 0x080c, 0x6a50, 0x0120, 0x2001, 0x1986, 0x200c, + 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0, + 0x2011, 0x698f, 0x080c, 0x87a1, 0x00fe, 0x00be, 0x0005, 0x00b6, + 0x2011, 0x698f, 0x080c, 0x8709, 0x080c, 0x6a50, 0x01d8, 0x2001, + 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6a8e, + 0x0130, 0x2009, 0x07d0, 0x2011, 0x698f, 0x080c, 0x87a1, 0x00e6, + 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x3019, + 0x00ee, 0x04c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, + 0x080c, 0x671d, 0x1548, 0xb800, 0xd0ec, 0x0530, 0xd0bc, 0x1520, + 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe9a5, + 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a8a, 0x2001, 0x0707, + 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x2019, + 0x0029, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x900e, + 0x080c, 0xe690, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x69b7, + 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, + 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x0096, 0x080c, + 0x1027, 0x090c, 0x0dc5, 0x2958, 0x009e, 0x2001, 0x196c, 0x2b02, + 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, 0x908c, 0xffc0, + 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, 0x6141, 0xb807, + 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, 0x0200, 0xb86c, + 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, 0xb8af, 0x0000, + 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, + 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, 0xb804, 0x908c, 0x00ff, + 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, 0x0170, 0x9196, 0x0005, + 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, 0x0006, 0x0128, 0x9196, + 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, 0x001e, 0x000e, 0x0005, + 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, + 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, + 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0dc5, + 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, + 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, 0x2204, 0xd0cc, 0x0138, + 0x2001, 0x1984, 0x200c, 0x2011, 0x6a80, 0x080c, 0x87a1, 0x0005, + 0x2011, 0x6a80, 0x080c, 0x8709, 0x2011, 0x1837, 0x2204, 0xc0cc, + 0x2012, 0x0005, 0x080c, 0x57d3, 0xd0ac, 0x0005, 0x080c, 0x57d3, + 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, + 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, + 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xd561, 0x0158, + 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, + 0x0110, 0xb8cc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x2071, 0x1910, + 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, + 0x701e, 0x700a, 0x7046, 0x2001, 0x1922, 0x2003, 0x0000, 0x0005, + 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e, 0x710a, 0x080c, 0x57d3, + 0xd0fc, 0x1140, 0x080c, 0x57d3, 0x900e, 0xd09c, 0x0108, 0x8108, + 0x7102, 0x0430, 0x2001, 0x1867, 0x200c, 0x9184, 0x0007, 0x0002, + 0x6ad2, 0x6ad2, 0x6ad2, 0x6ad2, 0x6ad2, 0x6ae8, 0x6afd, 0x6b0b, + 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, 0x9184, 0xff00, 0x908e, + 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, + 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, + 0x2071, 0x1910, 0x704f, 0x0000, 0x2071, 0x1800, 0x70f3, 0x0001, + 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x1910, 0x2009, + 0x1868, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160, + 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c, + 0x0007, 0x0128, 0x70f2, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70f3, + 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, + 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, + 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x78c0, 0x6a60, + 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, + 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, + 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, + 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, + 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, + 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0x00e6, 0x0026, 0x2071, + 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd7, 0x9286, 0x0003, 0x0904, + 0x6c70, 0x9286, 0x0005, 0x0904, 0x6c70, 0x2071, 0x1877, 0xa87c, + 0x9005, 0x0904, 0x6bcb, 0x7140, 0xa868, 0x9102, 0x0a04, 0x6dd7, + 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001, 0x8023, 0xa84e, + 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6fa5, 0x0e04, 0x7013, + 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082, 0xa870, 0x7086, + 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, + 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, + 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x6c53, 0xa853, 0x001b, + 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904, 0x6dd7, 0xa853, + 0x001a, 0x2001, 0x8024, 0x0804, 0x6b8f, 0x00e6, 0x0026, 0x2071, + 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd7, 0x9286, 0x0003, 0x0904, + 0x6c70, 0x9286, 0x0005, 0x0904, 0x6c70, 0xa84f, 0x8022, 0xa853, + 0x0018, 0x0804, 0x6c38, 0xa868, 0xd0fc, 0x1508, 0x00e6, 0x0026, + 0x2001, 0x1949, 0x2004, 0x9015, 0x0904, 0x6dd7, 0xa978, 0xa874, + 0x9105, 0x1904, 0x6dd7, 0x9286, 0x0003, 0x0904, 0x6c70, 0x9286, + 0x0005, 0x0904, 0x6c70, 0xa87c, 0xd0bc, 0x1904, 0x6dd7, 0x2200, + 0x0002, 0x6dd7, 0x6c34, 0x6c70, 0x6c70, 0x6dd7, 0x6c70, 0x0005, + 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, 0x1949, 0x210c, + 0x81ff, 0x0904, 0x6dd7, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, + 0x1904, 0x6dd7, 0x9186, 0x0003, 0x0904, 0x6c70, 0x9186, 0x0005, + 0x0904, 0x6c70, 0xa87c, 0xd0cc, 0x0904, 0x6dd7, 0xa84f, 0x8021, + 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, 0x0016, + 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6fa5, 0x0e04, 0x7013, + 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, 0x7086, + 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11aa, 0x2071, 0x1800, 0x2011, 0x0001, 0xa804, + 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e, 0x70c0, 0x9200, + 0x70c2, 0x080c, 0x85f1, 0x002e, 0x00ee, 0x0005, 0x0096, 0x2148, + 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e, 0x0c58, + 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, + 0x0000, 0x7010, 0x9005, 0x1904, 0x6d5b, 0x782c, 0x908c, 0x0780, + 0x190c, 0x7161, 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, + 0x6c8e, 0x6d5b, 0x6cb2, 0x6cf8, 0x080c, 0x0dc5, 0x2071, 0x1800, + 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, 0x19fc, 0x7044, + 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, + 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, + 0x85f1, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, + 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, + 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, + 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, + 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7161, 0xd0a4, 0x19f0, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, + 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, - 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x0c18, - 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1578, 0x7824, - 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, - 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, - 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, - 0x080c, 0x8725, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, - 0x19f0, 0x2071, 0x19fb, 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, - 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, - 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, - 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x0808, 0x0096, 0x00e6, - 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, - 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, 0x9094, 0x0780, - 0x190c, 0x722f, 0xd0a4, 0x1d60, 0x00ee, 0x782c, 0x9094, 0x0780, - 0x190c, 0x722f, 0xd09c, 0x1198, 0x009e, 0x2900, 0x7822, 0xa804, - 0x900d, 0x1550, 0x2071, 0x19fb, 0x7044, 0x9005, 0x1320, 0x2001, - 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x009e, - 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, - 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1168, 0x2071, - 0x19fb, 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, 0x2004, 0x7046, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x0808, + 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d60, 0x00ee, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x1198, 0x009e, 0x2900, + 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19fc, 0x7044, 0x9005, + 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1168, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, + 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, + 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x00fe, + 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, + 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, + 0x900d, 0x1904, 0x6daf, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, + 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, + 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7161, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, + 0x190c, 0x7161, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, + 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, + 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, + 0x1d60, 0x00ee, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, + 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, + 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, + 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, + 0x85f1, 0x00ee, 0x0804, 0x6d6b, 0xa868, 0xd0fc, 0x1904, 0x6e25, + 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fc0, 0x009e, + 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6e25, 0x00e6, 0x0026, 0xa84f, + 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, 0x70ec, 0x8001, + 0x0558, 0x1a04, 0x6e22, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864, + 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904, + 0x6f21, 0x782c, 0x908c, 0x0780, 0x190c, 0x7161, 0x8004, 0x8004, + 0x8004, 0x9084, 0x0003, 0x0002, 0x6e26, 0x6f21, 0x6e41, 0x6eb2, + 0x080c, 0x0dc5, 0x2009, 0x1949, 0x2104, 0x0002, 0x6ded, 0x6ded, + 0x6ded, 0x6c79, 0x6ded, 0x6c79, 0x70ef, 0x0fa0, 0x71e8, 0x8107, + 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x70ea, 0x3b08, + 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, + 0x20d0, 0x0808, 0x70ee, 0x0804, 0x6de3, 0x0005, 0x2071, 0x1800, + 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, + 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, + 0x6ea1, 0x7830, 0x8007, 0x908c, 0x001f, 0x70f0, 0x9102, 0x1220, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040, + 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, + 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x19f0, 0x0e04, 0x6e98, + 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, + 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, + 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, + 0x0804, 0x6e54, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, + 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, + 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d60, + 0x00ee, 0x0e04, 0x6ef4, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, + 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, + 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, + 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, + 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, - 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x00fe, 0x002e, 0x00ee, + 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, - 0x6e7d, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd09c, 0x1198, - 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, - 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, - 0x722f, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, - 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, - 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, - 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, 0x1d60, 0x00ee, - 0x2071, 0x19fb, 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, 0x2004, - 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, - 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, - 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x00ee, - 0x0804, 0x6e39, 0xa868, 0xd0fc, 0x1904, 0x6ef3, 0x0096, 0xa804, - 0xa807, 0x0000, 0x904d, 0x190c, 0x0fc0, 0x009e, 0x0020, 0xa868, - 0xd0fc, 0x1904, 0x6ef3, 0x00e6, 0x0026, 0xa84f, 0x0000, 0x00f6, - 0x2079, 0x0050, 0x2071, 0x1800, 0x70ec, 0x8001, 0x0558, 0x1a04, - 0x6ef0, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864, 0x9084, 0x00ff, - 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904, 0x6fef, 0x782c, - 0x908c, 0x0780, 0x190c, 0x722f, 0x8004, 0x8004, 0x8004, 0x9084, - 0x0003, 0x0002, 0x6ef4, 0x6fef, 0x6f0f, 0x6f80, 0x080c, 0x0dc5, - 0x2009, 0x1948, 0x2104, 0x0002, 0x6ebb, 0x6ebb, 0x6ebb, 0x6d47, - 0x6ebb, 0x6d47, 0x70ef, 0x0fa0, 0x71e8, 0x8107, 0x9106, 0x9094, - 0x00c0, 0x9184, 0xff3f, 0x9205, 0x70ea, 0x3b08, 0x3a00, 0x9104, - 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, 0x20d0, 0x0808, - 0x70ee, 0x0804, 0x6eb1, 0x0005, 0x2071, 0x1800, 0x2900, 0x7822, - 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, - 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, - 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x0c60, 0x2071, - 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6f6f, 0x7830, - 0x8007, 0x908c, 0x001f, 0x70f0, 0x9102, 0x1220, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, - 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, - 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, - 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, 0x9094, 0x0780, - 0x190c, 0x722f, 0xd0a4, 0x19f0, 0x0e04, 0x6f66, 0x7838, 0x7938, - 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, - 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2001, 0x1922, - 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2001, 0x1921, - 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, + 0x6f90, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x11b0, + 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, + 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x0d50, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7161, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048, + 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, + 0x70c2, 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, + 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6f89, 0x7838, 0x7938, 0x910e, + 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, + 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, + 0x080c, 0x85f1, 0x00ee, 0x0804, 0x6f31, 0x2071, 0x1910, 0xa803, + 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128, + 0x1e04, 0x6fd0, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, - 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x0804, 0x6f22, - 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, - 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, - 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, - 0x6fc2, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, - 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, - 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x704b, - 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd09c, 0x1170, - 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, 0x009e, 0x2908, - 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, - 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, - 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, - 0x70c2, 0x080c, 0x8725, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, - 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, - 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x705e, 0x782c, - 0x9094, 0x0780, 0x190c, 0x722f, 0xd09c, 0x11b0, 0x701c, 0x904d, - 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012, 0x1108, - 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, - 0x190c, 0x722f, 0xd09c, 0x0d50, 0x782c, 0x9094, 0x0780, 0x190c, - 0x722f, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, - 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, - 0x8725, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, 0x1d60, - 0x00ee, 0x0e04, 0x7057, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, - 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, - 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x11aa, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, - 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, - 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, - 0x00ee, 0x0804, 0x6fff, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x0e04, 0x6fba, + 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, + 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, + 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1910, 0x080c, + 0x714d, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, + 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, + 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, + 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, - 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128, 0x1e04, 0x709e, - 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, - 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, - 0x9200, 0x70c2, 0x080c, 0x8725, 0x0e04, 0x7088, 0x2071, 0x1910, - 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, - 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, - 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x11aa, 0x2071, 0x1910, 0x080c, 0x721b, 0x002e, - 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, - 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, - 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, - 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, - 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, - 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071, - 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, - 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, 0x0103, - 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, 0x20a0, - 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, 0xa87a, - 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002, 0x712e, 0x712f, - 0x721a, 0x712f, 0x712c, 0x721a, 0x080c, 0x0dc5, 0x0005, 0x2001, - 0x1948, 0x2004, 0x0002, 0x7139, 0x7139, 0x71b3, 0x71b4, 0x7139, - 0x71b4, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x723a, 0x701c, 0x904d, - 0x0508, 0xa84c, 0x9005, 0x0904, 0x7184, 0x0e04, 0x7162, 0xa94c, - 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, - 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1910, - 0x080c, 0x721b, 0x012e, 0x0804, 0x71b2, 0xa850, 0x9082, 0x001c, - 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, - 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, - 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b, 0x2004, 0x9094, - 0x0780, 0x190c, 0x722f, 0xd09c, 0x2071, 0x1910, 0x1510, 0x2071, - 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, - 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, - 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071, 0x1910, 0x701c, - 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, - 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, 0x2069, 0x19fb, - 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003, 0x0540, 0x2001, - 0x1815, 0x2004, 0x2009, 0x1ad1, 0x210c, 0x9102, 0x1500, 0x0126, - 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838, 0x9106, 0x0190, - 0x0e04, 0x71e6, 0x2069, 0x0000, 0x6837, 0x8040, 0x6833, 0x0012, - 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x11aa, 0x2069, 0x19fb, 0x6847, 0xffff, 0x012e, 0x00de, - 0x0126, 0x2091, 0x8000, 0x1e0c, 0x72a5, 0x701c, 0x904d, 0x0540, - 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, 0xd09c, 0x1500, - 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, - 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, - 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x701c, 0x2048, - 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, - 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000, 0x701c, 0x904d, - 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, - 0x701a, 0x012e, 0x080c, 0x1040, 0x0005, 0x012e, 0x0005, 0x2091, - 0x8000, 0x0e04, 0x7231, 0x0006, 0x0016, 0x2001, 0x8004, 0x0006, - 0x0804, 0x0dce, 0x0096, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, - 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, - 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, - 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780, 0x1981, 0xd0a4, - 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102, 0x0e88, 0x00e6, - 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, - 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, - 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, - 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, 0x9094, 0x0780, - 0x190c, 0x722f, 0xd0a4, 0x19f0, 0x7838, 0x7938, 0x910e, 0x1de0, - 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, - 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x00ee, - 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, - 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, + 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, + 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, + 0x080c, 0x85f1, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, + 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, + 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002, + 0x7060, 0x7061, 0x714c, 0x7061, 0x705e, 0x714c, 0x080c, 0x0dc5, + 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x706b, 0x706b, 0x70e5, + 0x70e6, 0x706b, 0x70e6, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x716c, + 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x70b6, 0x0e04, + 0x7094, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, + 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, + 0x2071, 0x1910, 0x080c, 0x714d, 0x012e, 0x0804, 0x70e4, 0xa850, + 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, + 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, + 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, + 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b, + 0x2004, 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x2071, 0x1910, + 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, + 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, + 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071, + 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, + 0x2069, 0x19fc, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003, + 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1ad2, 0x210c, 0x9102, + 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838, + 0x9106, 0x0190, 0x0e04, 0x7118, 0x2069, 0x0000, 0x6837, 0x8040, + 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11aa, 0x2069, 0x19fc, 0x6847, 0xffff, + 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x71d7, 0x701c, + 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, + 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, + 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, + 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, + 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, + 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000, + 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1040, 0x0005, 0x012e, + 0x0005, 0x2091, 0x8000, 0x0e04, 0x7163, 0x0006, 0x0016, 0x2001, + 0x8004, 0x0006, 0x0804, 0x0dce, 0x0096, 0x00f6, 0x2079, 0x0050, + 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, - 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, - 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, - 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, - 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, 0x1d70, 0x00d6, 0x2069, - 0x0050, 0x693c, 0x2069, 0x1948, 0x6808, 0x690a, 0x2069, 0x19fb, - 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, 0x2001, 0x1949, 0x200c, - 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x002a, - 0x1a0c, 0x0dc5, 0x9082, 0x001d, 0x001b, 0x6027, 0x1e00, 0x0005, - 0x73e6, 0x7353, 0x736f, 0x7399, 0x73d5, 0x7415, 0x7427, 0x736f, - 0x73fd, 0x730e, 0x733c, 0x73bf, 0x730d, 0x0005, 0x00d6, 0x2069, - 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005, 0x1518, 0x709b, - 0x0029, 0x2069, 0x198f, 0x2d04, 0x7002, 0x080c, 0x7774, 0x6028, - 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, 0x0029, 0x2069, 0x198f, - 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a, 0x00e6, 0x0036, - 0x0046, 0x0056, 0x2071, 0x1a65, 0x080c, 0x1ad9, 0x005e, 0x004e, - 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, - 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, 0x709b, 0x0029, 0x2069, - 0x198f, 0x2d04, 0x7002, 0x080c, 0x7818, 0x6028, 0x9085, 0x0600, - 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d39, - 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x7494, 0xd1d4, 0x1160, - 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, 0x0020, 0x080c, 0x7494, + 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780, + 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102, + 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, + 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, + 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x19f0, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, + 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, + 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, + 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11aa, 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7161, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, + 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, + 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d70, + 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1949, 0x6808, 0x690a, + 0x2069, 0x19fc, 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, 0x2001, + 0x194a, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, + 0x908a, 0x002a, 0x1a0c, 0x0dc5, 0x9082, 0x001d, 0x001b, 0x6027, + 0x1e00, 0x0005, 0x7318, 0x7285, 0x72a1, 0x72cb, 0x7307, 0x7347, + 0x7359, 0x72a1, 0x732f, 0x7240, 0x726e, 0x72f1, 0x723f, 0x0005, + 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005, + 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, + 0x769e, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, 0x0029, + 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a, + 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a66, 0x080c, 0x1b02, + 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, + 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, 0x709b, + 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x773b, 0x6028, + 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, 0x0090, + 0x080c, 0x2d52, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x73c6, + 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, 0x0020, + 0x080c, 0x73c6, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, + 0x0005, 0x2001, 0x0088, 0x080c, 0x2d52, 0x6124, 0xd1cc, 0x11e8, + 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, 0x080c, + 0x1b2f, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x7595, + 0x2001, 0x0080, 0x080c, 0x2d52, 0x709b, 0x0029, 0x0058, 0x709b, + 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010, + 0x709b, 0x001f, 0x0005, 0x080c, 0x1b2f, 0x60e3, 0x0001, 0x600c, + 0xc0b4, 0x600e, 0x080c, 0x7595, 0x2001, 0x0080, 0x080c, 0x2d52, + 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, 0x9184, + 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, 0x0028, 0x0040, + 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, + 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, + 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x2001, - 0x0088, 0x080c, 0x2d39, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, - 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, 0x080c, 0x1b06, 0x60e3, - 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x7663, 0x2001, 0x0080, - 0x080c, 0x2d39, 0x709b, 0x0029, 0x0058, 0x709b, 0x001e, 0x0040, - 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, - 0x0005, 0x080c, 0x1b06, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, - 0x080c, 0x7663, 0x2001, 0x0080, 0x080c, 0x2d39, 0x6124, 0xd1d4, - 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, 0x9184, 0x1e00, 0x1118, - 0x709b, 0x0029, 0x0058, 0x709b, 0x0028, 0x0040, 0x709b, 0x001e, - 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x6124, - 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0x9184, 0x1e00, - 0x1158, 0x709b, 0x0029, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, - 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x2001, 0x00a0, 0x080c, - 0x2d39, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, 0x080c, 0x1b06, - 0x709b, 0x001e, 0x0010, 0x709b, 0x001d, 0x0005, 0x080c, 0x7517, - 0x6124, 0xd1dc, 0x1188, 0x080c, 0x7494, 0x0016, 0x080c, 0x1b06, - 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x709b, 0x001e, 0x0020, - 0x709b, 0x001f, 0x080c, 0x7494, 0x0005, 0x0006, 0x2001, 0x00a0, - 0x080c, 0x2d39, 0x000e, 0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150, - 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, - 0x001d, 0x0010, 0x709b, 0x0021, 0x0005, 0x080c, 0x7517, 0x6124, - 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, - 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x0006, - 0x2001, 0x0090, 0x080c, 0x2d39, 0x000e, 0x6124, 0xd1d4, 0x1178, - 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158, 0x709b, 0x001e, - 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010, 0x709b, - 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, - 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2091, 0x8000, 0x080c, - 0x7637, 0x11d8, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x01b0, 0xc1b4, - 0x2102, 0x6027, 0x0200, 0x080c, 0x2c61, 0x6024, 0xd0cc, 0x0148, - 0x2001, 0x00a0, 0x080c, 0x2d39, 0x080c, 0x7932, 0x080c, 0x612e, - 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x7651, 0x0150, - 0x080c, 0x7648, 0x1138, 0x2001, 0x0001, 0x080c, 0x281c, 0x080c, - 0x760f, 0x00a0, 0x080c, 0x7514, 0x0178, 0x2001, 0x0001, 0x080c, - 0x281c, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, - 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, - 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x74a5, 0x080c, - 0x8917, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x74a5, - 0x080c, 0x890e, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, - 0x080c, 0xa6e9, 0x2071, 0x1800, 0x080c, 0x7442, 0x001e, 0x00fe, - 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, - 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, 0xa6e9, 0x2061, 0x0100, - 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x2011, - 0x0003, 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, 0xaac9, 0x080c, - 0xa9d3, 0x080c, 0x88c3, 0x0036, 0x901e, 0x080c, 0xaa49, 0x003e, - 0x60e3, 0x0000, 0x080c, 0xf07f, 0x080c, 0xf09a, 0x2009, 0x0004, - 0x080c, 0x2c67, 0x080c, 0x2b82, 0x2001, 0x1800, 0x2003, 0x0004, - 0x6027, 0x0008, 0x2011, 0x74a5, 0x080c, 0x8917, 0x080c, 0x7651, - 0x0118, 0x9006, 0x080c, 0x2d39, 0x080c, 0x0ba0, 0x2001, 0x0001, - 0x080c, 0x281c, 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, - 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6, 0x2011, 0x74b2, 0x2071, - 0x19fb, 0x701c, 0x9206, 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, - 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, - 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, - 0x2d39, 0x0156, 0x20a9, 0x002d, 0x1d04, 0x7524, 0x2091, 0x6000, - 0x1f04, 0x7524, 0x015e, 0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, - 0x0220, 0x0118, 0x689e, 0x00de, 0x0005, 0x689f, 0x0014, 0x68e8, - 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001, 0x1da8, 0x080c, 0x8923, - 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, - 0x2071, 0x1800, 0x080c, 0x7941, 0x2001, 0x196d, 0x2003, 0x0000, - 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x28e7, 0x9006, 0x080c, - 0x2d39, 0x080c, 0x5fed, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, - 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, - 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197d, 0x200c, 0x9186, - 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002, 0x0158, - 0x9186, 0x0003, 0x0158, 0x0804, 0x75ff, 0x709b, 0x0022, 0x0040, - 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, 0x709b, 0x0024, - 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28e7, - 0x0026, 0x080c, 0xb244, 0x002e, 0x7000, 0x908e, 0x0004, 0x0118, - 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, - 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, - 0x080c, 0xd7e3, 0x0118, 0x9006, 0x080c, 0x2d63, 0x0804, 0x760b, - 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2c61, 0x6904, - 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2d39, 0x1f04, 0x75a3, - 0x080c, 0x768b, 0x012e, 0x015e, 0x080c, 0x7648, 0x01d8, 0x6044, - 0x9005, 0x0198, 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, - 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, 0x768b, 0x9006, - 0x8001, 0x1df0, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, - 0x080c, 0x768b, 0x080c, 0xd7e3, 0x0118, 0x9006, 0x080c, 0x2d63, - 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8, - 0x2011, 0x74b2, 0x080c, 0x88d5, 0x002e, 0x001e, 0x080c, 0x871c, - 0x7034, 0xc085, 0x7036, 0x2001, 0x197d, 0x2003, 0x0004, 0x080c, - 0x72f5, 0x080c, 0x7648, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc, - 0x1100, 0x080c, 0x7937, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, - 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, - 0x080c, 0x8733, 0x080c, 0x8725, 0x080c, 0x7941, 0x2001, 0x196d, - 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x28e7, - 0x9006, 0x080c, 0x2d39, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027, - 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, - 0x2001, 0x197c, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, - 0x080c, 0x57d9, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, - 0x0006, 0x080c, 0x57d9, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, - 0x0005, 0x0006, 0x080c, 0x57d9, 0x9084, 0x0030, 0x9086, 0x0010, - 0x000e, 0x0005, 0x0006, 0x080c, 0x57d9, 0x9084, 0x0030, 0x9086, - 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, - 0x908c, 0x0013, 0x0168, 0x0020, 0x080c, 0x2907, 0x900e, 0x0010, - 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x321b, 0x9006, 0x0019, - 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, - 0x080c, 0xd7dc, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, - 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, - 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x0016, 0x6138, 0x6050, - 0x9084, 0xfbff, 0x9085, 0x2000, 0x6052, 0x613a, 0x20a9, 0x0012, - 0x1d04, 0x76a0, 0x2091, 0x6000, 0x1f04, 0x76a0, 0x602f, 0x0100, - 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, - 0x613a, 0x001e, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, - 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x60e3, 0x0000, - 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28e7, 0x2001, 0x00a0, - 0x0006, 0x080c, 0xd7e3, 0x000e, 0x0130, 0x080c, 0x2d57, 0x9006, - 0x080c, 0x2d63, 0x0010, 0x080c, 0x2d39, 0x000e, 0x6052, 0x6050, - 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100, 0x080c, 0x2bd6, - 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, - 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, - 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001, 0x180c, 0x200c, - 0xc1c5, 0x2102, 0x0804, 0x7766, 0x2001, 0x180c, 0x200c, 0xc1c4, - 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027, 0x0200, 0x2001, - 0x0090, 0x080c, 0x2d39, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1518, - 0x1d04, 0x770d, 0x2091, 0x6000, 0x1f04, 0x770d, 0x2011, 0x0003, - 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, 0xaac9, 0x080c, 0xa9d3, - 0x901e, 0x080c, 0xaa49, 0x2001, 0x00a0, 0x080c, 0x2d39, 0x080c, - 0x7932, 0x080c, 0x612e, 0x080c, 0xd7e3, 0x0110, 0x080c, 0x0d33, - 0x9085, 0x0001, 0x04c8, 0x080c, 0x1b06, 0x60e3, 0x0000, 0x2001, - 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1118, 0x2001, 0x196d, - 0x2004, 0x080c, 0x28e7, 0x60e2, 0x2001, 0x0080, 0x080c, 0x2d39, - 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c61, - 0x6024, 0x910c, 0x0140, 0x1d04, 0x774a, 0x2091, 0x6000, 0x1f04, - 0x774a, 0x0804, 0x7716, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, - 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd7e3, - 0x0110, 0x080c, 0x0d33, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, - 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, - 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x7000, - 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, 0x5540, - 0x9086, 0x5540, 0x1128, 0x2069, 0x1a7c, 0x2d04, 0x8000, 0x206a, - 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, - 0x1904, 0x77d9, 0x2001, 0x0088, 0x080c, 0x2d39, 0x9006, 0x60e2, - 0x6886, 0x080c, 0x28e7, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, - 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x6027, - 0x0400, 0x2069, 0x198f, 0x7000, 0x206a, 0x709b, 0x0026, 0x7003, - 0x0001, 0x20a9, 0x0002, 0x1d04, 0x77bb, 0x2091, 0x6000, 0x1f04, - 0x77bb, 0x0804, 0x7810, 0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, - 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c61, 0x6024, 0x910c, 0x0508, - 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x77c7, 0x2091, 0x6000, 0x1f04, - 0x77c7, 0x2011, 0x0003, 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, - 0xaac9, 0x080c, 0xa9d3, 0x901e, 0x080c, 0xaa49, 0x2001, 0x00a0, - 0x080c, 0x2d39, 0x080c, 0x7932, 0x080c, 0x612e, 0x9085, 0x0001, - 0x00f8, 0x080c, 0x1b06, 0x2001, 0x0080, 0x080c, 0x2d39, 0x2069, - 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, - 0x0008, 0x6886, 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, - 0x1118, 0x2001, 0x196d, 0x2004, 0x080c, 0x28e7, 0x60e2, 0x9006, - 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, - 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, - 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01c8, 0x2011, - 0x0003, 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, 0xaac9, 0x080c, - 0xa9d3, 0x901e, 0x080c, 0xaa49, 0x2069, 0x0140, 0x2001, 0x00a0, - 0x080c, 0x2d39, 0x080c, 0x7932, 0x080c, 0x612e, 0x0804, 0x78b2, - 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c, - 0x749a, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c, 0x2d39, 0x60e3, - 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, - 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, - 0x198f, 0x7000, 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, - 0x78b2, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c61, 0x6024, - 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x7869, 0x0006, - 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8776, 0x00ee, 0x00de, - 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19fb, 0x7078, 0x00ee, - 0x9005, 0x19f8, 0x0438, 0x0026, 0x2011, 0x74b2, 0x080c, 0x883d, - 0x2011, 0x74a5, 0x080c, 0x8917, 0x002e, 0x2069, 0x0140, 0x60e3, - 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1118, 0x2001, - 0x196d, 0x2004, 0x080c, 0x28e7, 0x60e2, 0x2001, 0x180c, 0x200c, - 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, - 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, - 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd7dc, 0x1904, - 0x7920, 0x7130, 0xd184, 0x1170, 0x080c, 0x33aa, 0x0138, 0xc18d, - 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, - 0x0904, 0x7920, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, 0x0016, - 0x2019, 0x000e, 0x080c, 0xeba1, 0x0156, 0x00b6, 0x20a9, 0x007f, - 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, - 0x6724, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, - 0xec31, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8a50, 0x001e, - 0x8108, 0x1f04, 0x78e9, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, - 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x321b, 0x001e, - 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6724, - 0x1110, 0x080c, 0x6148, 0x8108, 0x1f04, 0x7916, 0x00be, 0x015e, - 0x080c, 0x1b06, 0x080c, 0xb244, 0x60e3, 0x0000, 0x080c, 0x612e, - 0x080c, 0x7563, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, - 0x015e, 0x0005, 0x2001, 0x197d, 0x2003, 0x0001, 0x0005, 0x2001, - 0x197d, 0x2003, 0x0000, 0x0005, 0x2001, 0x197c, 0x2003, 0xaaaa, - 0x0005, 0x2001, 0x197c, 0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, - 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x1027, 0x090c, 0x0dc5, - 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x1027, 0x090c, 0x0dc5, - 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, - 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, - 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, - 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, - 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, - 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, - 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, - 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, - 0x2102, 0x00d6, 0x2069, 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, - 0x7f74, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, - 0x8003, 0x2011, 0x0100, 0x2214, 0x9296, 0x0008, 0x1110, 0x818d, - 0x0010, 0x81f5, 0x3e08, 0x1f04, 0x79a8, 0x015e, 0x0005, 0x2079, - 0x0040, 0x2071, 0x18fa, 0x7004, 0x0002, 0x79c7, 0x79c8, 0x7a00, - 0x7a5b, 0x7bbb, 0x79c5, 0x79c5, 0x7be5, 0x080c, 0x0dc5, 0x0005, - 0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x8056, 0xd0a4, - 0x01f8, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, - 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, - 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x79f0, 0x79ca, 0x79f0, - 0x79ee, 0x79f0, 0x79f0, 0x79f0, 0x79f0, 0x79f0, 0x080c, 0x7a5b, - 0x782c, 0xd09c, 0x090c, 0x7f74, 0x0005, 0x9082, 0x005a, 0x1218, - 0x2100, 0x003b, 0x0c10, 0x080c, 0x7a91, 0x0c90, 0x00e3, 0x08e8, - 0x0005, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, - 0x7a91, 0x7ab3, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, - 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, - 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a9d, 0x7a91, 0x7cdb, - 0x7a91, 0x7a91, 0x7a91, 0x7ab3, 0x7a91, 0x7a9d, 0x7d1c, 0x7d5d, - 0x7da4, 0x7db8, 0x7a91, 0x7a91, 0x7ab3, 0x7a9d, 0x7ac7, 0x7a91, - 0x7b8f, 0x7e63, 0x7e7e, 0x7a91, 0x7ab3, 0x7a91, 0x7ac7, 0x7a91, - 0x7a91, 0x7b85, 0x7e7e, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, - 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7adb, 0x7a91, 0x7a91, 0x7a91, - 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7ffa, 0x7a91, - 0x7fa4, 0x7a91, 0x7fa4, 0x7a91, 0x7af0, 0x7a91, 0x7a91, 0x7a91, - 0x7a91, 0x7a91, 0x7a91, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, - 0x1198, 0x782c, 0x080c, 0x7f9d, 0xd0a4, 0x0170, 0x7824, 0x2048, - 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, - 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7f74, 0x0005, 0x7a91, - 0x7a9d, 0x7cc7, 0x7a91, 0x7a9d, 0x7a91, 0x7a9d, 0x7a9d, 0x7a91, - 0x7a9d, 0x7cc7, 0x7a9d, 0x7a9d, 0x7a9d, 0x7a9d, 0x7a9d, 0x7a91, - 0x7a9d, 0x7cc7, 0x7a91, 0x7a91, 0x7a9d, 0x7a91, 0x7a91, 0x7a91, - 0x7a9d, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, - 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, - 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, - 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6e9f, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, - 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c64, 0x7007, 0x0003, - 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c64, 0x0005, 0xa864, - 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, - 0x0804, 0x7c7f, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, - 0x704b, 0x7c7f, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, - 0x7a99, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c9b, 0x7007, - 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c9b, 0x0005, - 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7a99, - 0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1904, 0x7b5c, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x0904, 0x7b47, 0xa99c, 0x9186, - 0x00ff, 0x05e8, 0xa994, 0x9186, 0x006f, 0x0188, 0x9186, 0x0074, - 0x15b0, 0x0026, 0x2011, 0x0010, 0x080c, 0x6ac7, 0x002e, 0x0578, - 0x0016, 0xa998, 0x080c, 0x6b11, 0x001e, 0x1548, 0x0400, 0x080c, - 0x7637, 0x0140, 0xa897, 0x4005, 0xa89b, 0x0016, 0x2001, 0x0030, - 0x900e, 0x0438, 0x0026, 0x2011, 0x8008, 0x080c, 0x6ac7, 0x002e, - 0x01b0, 0x0016, 0x0026, 0x0036, 0xa998, 0xaaa0, 0xab9c, 0x918d, - 0x8000, 0x080c, 0x6b11, 0x003e, 0x002e, 0x001e, 0x1140, 0xa897, - 0x4005, 0xa89b, 0x4009, 0x2001, 0x0030, 0x900e, 0x0050, 0xa868, - 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x63c5, 0x1108, - 0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, - 0x080c, 0x6e9f, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0904, - 0x7b00, 0x9186, 0x0064, 0x0904, 0x7b00, 0x9186, 0x007c, 0x0904, - 0x7b00, 0x9186, 0x0028, 0x0904, 0x7b00, 0x9186, 0x0038, 0x0904, - 0x7b00, 0x9186, 0x0078, 0x0904, 0x7b00, 0x9186, 0x005f, 0x0904, - 0x7b00, 0x9186, 0x0056, 0x0904, 0x7b00, 0xa897, 0x4005, 0xa89b, - 0x0001, 0x2001, 0x0030, 0x900e, 0x0860, 0xa87c, 0x9084, 0x00c0, - 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7e95, 0x2900, - 0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, - 0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, - 0x7aa1, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7aa1, 0x82ff, 0x1138, - 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7c22, 0x0018, 0x9280, - 0x7c18, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7c03, 0x080c, - 0x1027, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, - 0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, - 0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, - 0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, - 0xa17a, 0x810b, 0xa17e, 0x080c, 0x10f8, 0xa06c, 0x908e, 0x0100, - 0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, - 0x2048, 0x080c, 0x1040, 0x7014, 0x2048, 0x0804, 0x7aa1, 0x7020, - 0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, - 0x711a, 0x0804, 0x7bbb, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, - 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, - 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7e95, 0x0804, 0x7c64, - 0x7c1a, 0x7c1e, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, - 0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, - 0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, - 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, - 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, - 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, - 0xb6aa, 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, - 0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, - 0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, - 0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, - 0x1178, 0x080c, 0x61c2, 0x1108, 0x0005, 0x080c, 0x710b, 0x0126, - 0x2091, 0x8000, 0x080c, 0xd3ce, 0x080c, 0x6e9f, 0x012e, 0x0ca0, - 0x080c, 0xd7dc, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, - 0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, - 0x0000, 0x080c, 0x6252, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, - 0x8000, 0x080c, 0x6e9f, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, - 0x2001, 0x0000, 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, - 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x6327, 0x1138, - 0x0005, 0x9006, 0xa87a, 0x080c, 0x629f, 0x1108, 0x0005, 0x0126, - 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6e9f, 0x012e, 0x0cb0, - 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, - 0x2061, 0x1800, 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, - 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, - 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, - 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, - 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, - 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, - 0x9005, 0x11d8, 0xa974, 0x080c, 0x6724, 0x11b8, 0x0066, 0xae80, - 0x080c, 0x6834, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, - 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6724, 0x1110, 0x080c, - 0x6934, 0x8108, 0x1f04, 0x7d04, 0x00ce, 0xa87c, 0xd084, 0x1120, - 0x080c, 0x1040, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, - 0x6e9f, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, - 0x0001, 0x080c, 0x6a9f, 0x0580, 0x2061, 0x1a74, 0x6100, 0xd184, - 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, - 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, - 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, - 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, - 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, - 0x6202, 0x012e, 0x0804, 0x7f5e, 0x012e, 0x0804, 0x7f58, 0x012e, - 0x0804, 0x7f52, 0x012e, 0x0804, 0x7f55, 0x0126, 0x2091, 0x8000, - 0x7007, 0x0001, 0x080c, 0x6a9f, 0x05e0, 0x2061, 0x1a74, 0x6000, - 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, - 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, - 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, - 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, - 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, - 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, - 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7f5e, 0x012e, 0x0804, - 0x7f5b, 0x012e, 0x0804, 0x7f58, 0x0126, 0x2091, 0x8000, 0x7007, - 0x0001, 0x2061, 0x1a74, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, - 0x0220, 0x630a, 0x012e, 0x0804, 0x7f6c, 0x012e, 0x0804, 0x7f5b, - 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, - 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x9084, 0xfcff, - 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, - 0x0598, 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xb306, - 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110, - 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xb352, 0xa988, 0x918c, - 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, - 0x080c, 0x8a50, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a74, - 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, - 0x012e, 0x00be, 0x0804, 0x7f5e, 0x00ce, 0x012e, 0x00be, 0x0804, - 0x7f58, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, - 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, - 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, - 0x0029, 0x1d10, 0xa974, 0x080c, 0x6724, 0x1968, 0xb800, 0xc0e4, - 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, - 0x1986, 0x2004, 0x601a, 0x0804, 0x7df3, 0xa88c, 0x9065, 0x0960, - 0x00e6, 0xa890, 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, - 0x080c, 0xb306, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xb306, 0x00ee, - 0x0804, 0x7df3, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, - 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, - 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, - 0x00ee, 0x0804, 0x7df3, 0x2061, 0x1a74, 0x6000, 0xd084, 0x0190, - 0xd08c, 0x1904, 0x7f6c, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, - 0x0220, 0x6206, 0x012e, 0x0804, 0x7f6c, 0x012e, 0xa883, 0x0016, - 0x0804, 0x7f65, 0xa883, 0x0007, 0x0804, 0x7f65, 0xa864, 0x8007, - 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, - 0x0005, 0x080c, 0x7a99, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, - 0x7016, 0x701a, 0x704b, 0x7e95, 0x0005, 0x00b6, 0x00e6, 0x0126, - 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, - 0x7f17, 0x6130, 0xd194, 0x1904, 0x7f41, 0xa878, 0x2070, 0x9e82, - 0x1cd0, 0x0a04, 0x7f0b, 0x6068, 0x9e02, 0x1a04, 0x7f0b, 0x7120, - 0x9186, 0x0006, 0x1904, 0x7efd, 0x7010, 0x905d, 0x0904, 0x7f17, - 0xb800, 0xd0e4, 0x1904, 0x7f3b, 0x2061, 0x1a74, 0x6100, 0x9184, - 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7f44, - 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, - 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7f47, 0x080c, 0x57d5, 0xd09c, - 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8970, 0x012e, - 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, - 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7f47, 0x012e, 0x00ee, 0x00be, - 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7f65, - 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6724, - 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, - 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, - 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, - 0x57d9, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0, - 0x6068, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, - 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, - 0x9086, 0x0007, 0x1904, 0x7ea1, 0x7003, 0x0002, 0x0804, 0x7ea1, - 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, - 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, - 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe754, 0x012e, 0x00ee, - 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, - 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, - 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6e9f, 0x012e, 0x0005, 0x080c, 0x1040, 0x0005, 0x00d6, - 0x080c, 0x8967, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, - 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, - 0x190c, 0x8056, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, - 0x0020, 0x0278, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, - 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, - 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, - 0x190c, 0x8056, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, - 0x080c, 0xb27d, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, - 0x9086, 0x0035, 0x1138, 0x6008, 0xc0fd, 0x600a, 0x2001, 0x196b, - 0x2004, 0x0098, 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, - 0x9105, 0xa99c, 0x918c, 0x00ff, 0x080c, 0x2873, 0x1540, 0x00b6, - 0x080c, 0x6724, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, - 0x2009, 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, - 0x2009, 0x0041, 0x080c, 0xb352, 0x0005, 0xa87b, 0x0101, 0x0126, - 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, 0x0005, 0xa87b, 0x002c, - 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, 0x0005, 0xa87b, - 0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, 0x080c, - 0xb2d3, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, - 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x8047, 0xa97c, - 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, - 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, - 0x080c, 0xb27d, 0x1118, 0x080c, 0xb325, 0x05a8, 0x6212, 0xa874, - 0x0002, 0x8025, 0x802a, 0x802d, 0x8033, 0x2019, 0x0002, 0x080c, - 0xeba1, 0x0060, 0x080c, 0xeb38, 0x0048, 0x2019, 0x0002, 0xa980, - 0x080c, 0xeb53, 0x0018, 0xa980, 0x080c, 0xeb38, 0x080c, 0xb2d3, - 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, - 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, - 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, - 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, - 0x0e04, 0x8058, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, - 0x0dce, 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, - 0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, - 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x15a0, 0x00fe, - 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, - 0x0005, 0x781c, 0xd08c, 0x0904, 0x80d8, 0x68c0, 0x90aa, 0x0005, - 0x0a04, 0x871c, 0x7d44, 0x7c40, 0x9584, 0x00f6, 0x1510, 0x9484, - 0x7000, 0x0140, 0x908a, 0x2000, 0x1260, 0x9584, 0x0700, 0x8007, - 0x0804, 0x80df, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x0da8, - 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, 0x9086, - 0x8100, 0x11c0, 0x080c, 0xf057, 0x080c, 0x8601, 0x7817, 0x0140, - 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x865f, 0x19c0, 0xd5a4, - 0x0148, 0x0046, 0x0056, 0x080c, 0x813a, 0x080c, 0x236e, 0x005e, - 0x004e, 0x0020, 0x080c, 0xf057, 0x7817, 0x0140, 0x080c, 0x7637, - 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, - 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000, 0x080c, 0x811b, - 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, 0x9ab1, 0x0005, 0x0002, - 0x80f1, 0x8409, 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80e8, - 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, 0x9ab1, - 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000, 0x810f, 0x9484, - 0x0fff, 0x6892, 0x9286, 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, - 0x1118, 0x080c, 0x583f, 0x0070, 0x080c, 0x815a, 0x0058, 0x9286, - 0x3000, 0x1118, 0x080c, 0x8341, 0x0028, 0x9286, 0x8000, 0x1110, - 0x080c, 0x8528, 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, - 0x090c, 0x9ab1, 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, - 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, - 0x2011, 0x8048, 0x2518, 0x080c, 0x4c44, 0x003e, 0x002e, 0x0005, - 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, - 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, - 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, - 0x0160, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, - 0x2011, 0x8048, 0x080c, 0x4c44, 0x002e, 0x00fe, 0x005e, 0x004e, - 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, - 0x9096, 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x8312, 0x9186, - 0x0023, 0x15c0, 0x080c, 0x85c6, 0x0904, 0x8312, 0x6120, 0x9186, - 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, - 0x9186, 0x000a, 0x1904, 0x8312, 0x7124, 0x610a, 0x7030, 0x908e, - 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, 0xb352, 0x0804, 0x8312, - 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, - 0x080c, 0xb352, 0x0804, 0x8312, 0x908e, 0x0100, 0x1904, 0x8312, - 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, 0x0016, 0x080c, 0xb352, - 0x0804, 0x8312, 0x9186, 0x0022, 0x1904, 0x8312, 0x7030, 0x908e, - 0x0300, 0x1580, 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, - 0x918c, 0x00ff, 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, - 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, - 0x28bc, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2873, - 0x695e, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, - 0x70b6, 0x00ee, 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, 0x0017, - 0x0804, 0x82c2, 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, - 0x8312, 0x080c, 0x7637, 0x0120, 0x2009, 0x001d, 0x0804, 0x82c2, - 0x68dc, 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804, 0x82c2, 0x908e, - 0x0500, 0x1140, 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, 0x0018, - 0x0804, 0x82c2, 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, - 0x82c2, 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x82c2, - 0x908e, 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, - 0x001b, 0x0804, 0x82c2, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, - 0x1904, 0x8312, 0x2009, 0x001c, 0x0804, 0x82c2, 0x908e, 0x1300, - 0x1120, 0x2009, 0x0034, 0x0804, 0x82c2, 0x908e, 0x1200, 0x1140, - 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, 0x0024, 0x0804, 0x82c2, - 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, - 0x1810, 0x2004, 0xd09c, 0x0904, 0x82c2, 0x080c, 0xdf1a, 0x1904, - 0x8312, 0x0804, 0x82c0, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, - 0x2009, 0x002a, 0x0804, 0x82c2, 0x908e, 0x0f00, 0x1120, 0x2009, - 0x0020, 0x0804, 0x82c2, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, - 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, - 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, - 0x4c44, 0x004e, 0x8108, 0x0f04, 0x8276, 0x9186, 0x0280, 0x1d88, - 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, - 0x2009, 0x0023, 0x0804, 0x82c2, 0x908e, 0x6000, 0x1120, 0x2009, - 0x003f, 0x0804, 0x82c2, 0x908e, 0x5400, 0x1138, 0x080c, 0x86cc, - 0x1904, 0x8312, 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, - 0x080c, 0x86f4, 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, - 0x0448, 0x908e, 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, - 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, - 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, - 0x2009, 0x004f, 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, - 0x2009, 0x0050, 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, - 0x2009, 0x004c, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, - 0x080c, 0x2873, 0x1904, 0x8315, 0x080c, 0x66b9, 0x1904, 0x8315, - 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c, 0x7637, 0x01c0, 0x68dc, - 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, - 0xff00, 0x1168, 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, - 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff, 0xb8c2, 0x0080, 0xb8c0, - 0x9005, 0x1168, 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, - 0x6880, 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, - 0xb27d, 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, - 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, - 0x080c, 0xb352, 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, - 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c44, - 0x080c, 0xb325, 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, - 0x610a, 0x001e, 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, - 0x1128, 0x6007, 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, - 0x6017, 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x9547, - 0x08a0, 0x080c, 0x873b, 0x1158, 0x080c, 0x3374, 0x1140, 0x7010, - 0x9084, 0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, - 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, - 0x0033, 0x11e8, 0x080c, 0x85c6, 0x0904, 0x83a1, 0x7124, 0x610a, - 0x7030, 0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15d0, 0x2009, - 0x0015, 0x080c, 0xb352, 0x04a8, 0x908e, 0x0100, 0x1590, 0x7034, - 0x9005, 0x1578, 0x2009, 0x0016, 0x080c, 0xb352, 0x0450, 0x9186, - 0x0032, 0x1538, 0x7030, 0x908e, 0x1400, 0x1518, 0x2009, 0x0038, - 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2873, - 0x11b8, 0x080c, 0x66b9, 0x11a0, 0xbe12, 0xbd16, 0x080c, 0xb27d, - 0x0178, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0004, 0x7120, - 0x610a, 0x001e, 0x080c, 0xb352, 0x080c, 0x9ab1, 0x0010, 0x00ce, - 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, - 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, - 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x8403, - 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, 0x8403, 0x9596, - 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, - 0x1837, 0x231c, 0xd3ac, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, - 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, - 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff, 0x11d0, 0x9496, 0x00ff, - 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, - 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, - 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, - 0x8420, 0x8e70, 0x1f04, 0x83d8, 0x82ff, 0x1118, 0x9085, 0x0001, - 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, - 0x0005, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, - 0x0138, 0x7000, 0x908c, 0xff00, 0x810f, 0x9184, 0x000f, 0x004a, - 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, 0x9ab1, - 0x0005, 0x8431, 0x8431, 0x8431, 0x85d8, 0x8431, 0x843a, 0x8465, - 0x84f3, 0x8431, 0x8431, 0x8431, 0x8431, 0x8431, 0x8431, 0x8431, - 0x8431, 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, - 0x9ab1, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, - 0x9c8c, 0x0007, 0x11c0, 0x9c8a, 0x1cd0, 0x02a8, 0x6868, 0x9c02, - 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, - 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, - 0x0046, 0x080c, 0xb352, 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, - 0x9005, 0x090c, 0x9ab1, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484, - 0x0fff, 0x0904, 0x84c9, 0x7110, 0xd1bc, 0x1904, 0x84c9, 0x7108, - 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15b0, - 0x81ff, 0x15a0, 0x9080, 0x33b6, 0x200d, 0x918c, 0xff00, 0x810f, - 0x2001, 0x0080, 0x9106, 0x0904, 0x84c9, 0x080c, 0x66b9, 0x1904, - 0x84c9, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15d8, 0xba04, 0x9294, - 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c, 0xb27d, 0x05e8, 0x2b08, - 0x7028, 0x6046, 0x702c, 0x604a, 0x6112, 0x6023, 0x0006, 0x7120, - 0x610a, 0x7130, 0x6156, 0x2009, 0x0044, 0x080c, 0xe192, 0x0408, - 0x080c, 0x6aa3, 0x1138, 0xb807, 0x0606, 0x0c30, 0x190c, 0x83a5, - 0x11c0, 0x0898, 0x080c, 0xb27d, 0x2b08, 0x0198, 0x6112, 0x6023, - 0x0004, 0x7120, 0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, - 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, - 0x9ab1, 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, - 0x9ab1, 0x00ce, 0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, - 0x0120, 0x2011, 0x8049, 0x080c, 0x4c44, 0x080c, 0xb325, 0x0d48, - 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, - 0x6017, 0xf300, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x94ff, - 0x080c, 0x9ab1, 0x08b0, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7020, - 0x2060, 0x9c84, 0x0007, 0x11c0, 0x9c82, 0x1cd0, 0x02a8, 0x6868, - 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, - 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, - 0x2009, 0x0045, 0x080c, 0xb352, 0x7817, 0x0140, 0x2001, 0x19f1, - 0x2004, 0x9005, 0x090c, 0x9ab1, 0x00be, 0x0005, 0x6120, 0x9186, - 0x0002, 0x0128, 0x9186, 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, - 0x080c, 0x873b, 0x1180, 0x080c, 0x3374, 0x1168, 0x7010, 0x9084, - 0xff00, 0x8007, 0x9086, 0x0000, 0x1130, 0x9184, 0x000f, 0x908a, - 0x0006, 0x1208, 0x000b, 0x0005, 0x8542, 0x8543, 0x8542, 0x8542, - 0x85a8, 0x85b7, 0x0005, 0x00b6, 0x700c, 0x7108, 0x080c, 0x2873, - 0x1904, 0x85a6, 0x080c, 0x66b9, 0x1904, 0x85a6, 0xbe12, 0xbd16, - 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, - 0x1904, 0x85a6, 0x080c, 0x6aa3, 0x0148, 0x9086, 0x0004, 0x0130, - 0x080c, 0x6aab, 0x0118, 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, - 0x85c6, 0x00ce, 0x05d8, 0x080c, 0xb27d, 0x2b08, 0x05b8, 0x6112, - 0x080c, 0xd554, 0x6023, 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, - 0x080c, 0xb352, 0x0458, 0x080c, 0x6aa3, 0x0148, 0x9086, 0x0004, - 0x0130, 0x080c, 0x6aab, 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, - 0xb27d, 0x2b08, 0x01d8, 0x6112, 0x080c, 0xd554, 0x6023, 0x0005, - 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb352, 0x0078, 0x080c, - 0xb27d, 0x2b08, 0x0158, 0x6112, 0x080c, 0xd554, 0x6023, 0x0004, - 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0xb352, 0x00be, 0x0005, - 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c, 0x851e, 0x1130, - 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0xb352, 0x0005, 0x7110, - 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, 0x851e, 0x1130, 0x7124, - 0x610a, 0x2009, 0x008a, 0x080c, 0xb352, 0x0005, 0x7020, 0x2060, - 0x9c84, 0x0007, 0x1158, 0x9c82, 0x1cd0, 0x0240, 0x2001, 0x181a, - 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, - 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, 0x2060, 0x9c84, 0x0007, - 0x11b0, 0x9c82, 0x1cd0, 0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, - 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1140, 0x700c, - 0xb914, 0x9106, 0x1120, 0x2009, 0x0051, 0x080c, 0xb352, 0x7817, - 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, 0x9ab1, 0x00be, - 0x0005, 0x2031, 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, - 0x0005, 0x2031, 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, - 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, - 0xc000, 0x05d0, 0x080c, 0xb27d, 0x05b8, 0x0066, 0x00c6, 0x0046, - 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2873, 0x15a0, - 0x080c, 0x66b9, 0x1588, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, - 0x6012, 0x080c, 0xd554, 0x080c, 0x100e, 0x0510, 0x2900, 0x605a, - 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, - 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, - 0x006e, 0x6616, 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, - 0x080c, 0x9547, 0x080c, 0x9ab1, 0x00fe, 0x009e, 0x00ce, 0x0005, - 0x080c, 0xb2d3, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, - 0x7000, 0x908c, 0xff00, 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, - 0x1904, 0x86b6, 0x9186, 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, - 0x9005, 0x1904, 0x86b8, 0x7030, 0x908e, 0x0400, 0x0904, 0x86b8, - 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, - 0x11d8, 0x2009, 0x1837, 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, - 0x080c, 0x6a61, 0x0588, 0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, - 0x00ff, 0x9106, 0x1518, 0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, - 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, - 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, - 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023, 0x1140, 0x080c, 0x85c6, - 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, 0x0000, 0x9006, 0x0010, - 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030, 0x908e, 0x0300, 0x0118, - 0x908e, 0x5200, 0x1d98, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, - 0x9086, 0x0008, 0x0d68, 0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, - 0x7038, 0x2020, 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, - 0x0004, 0x2019, 0x1805, 0x2011, 0x027a, 0x080c, 0xc365, 0x1178, - 0xd48c, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, - 0x080c, 0xc365, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, - 0x001e, 0x004e, 0x015e, 0x0005, 0x0156, 0x0046, 0x0016, 0x0036, - 0x7038, 0x2020, 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, - 0x0004, 0x2019, 0x1805, 0x2011, 0x0272, 0x080c, 0xc365, 0x1178, - 0xd48c, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, - 0x080c, 0xc365, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, - 0x001e, 0x004e, 0x015e, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, - 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, - 0x7834, 0xd084, 0x1130, 0x2079, 0x0200, 0x7800, 0x9085, 0x1200, - 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7034, 0xc084, - 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001, 0x1837, 0x200c, 0x9184, - 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006, 0x001e, 0x0005, 0x9085, - 0x0001, 0x0cd8, 0x2071, 0x19fb, 0x7003, 0x0003, 0x700f, 0x0361, - 0x9006, 0x701a, 0x707a, 0x7012, 0x7017, 0x1cd0, 0x7007, 0x0000, - 0x7026, 0x702b, 0xa6ff, 0x7032, 0x703a, 0x703f, 0x0064, 0x7037, - 0xa767, 0x7047, 0xffff, 0x704a, 0x704f, 0x5667, 0x7052, 0x7063, - 0x88de, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x7042, 0xa867, - 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19fb, - 0x1d04, 0x882c, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1540, - 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x894c, 0x2001, 0x1869, - 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, 0x0000, - 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0dc5, 0x700f, 0x0361, - 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c, 0x8923, 0x7048, - 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c, 0x080f, 0x0018, - 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, 0x8001, - 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, 0x03e8, - 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030, - 0x900d, 0x05a8, 0x702c, 0x8001, 0x702e, 0x1588, 0x0016, 0x2009, - 0x0306, 0x210c, 0x9184, 0x0030, 0x01e8, 0x9184, 0x0048, 0x9086, - 0x0008, 0x11c0, 0x7038, 0x9005, 0x01a8, 0x8001, 0x703a, 0x1190, - 0x080c, 0x7637, 0x0178, 0x00e6, 0x2071, 0x19e8, 0x080c, 0xa7f5, - 0x00ee, 0x1140, 0x2009, 0x1a86, 0x2104, 0x8000, 0x0208, 0x200a, - 0x001e, 0x0068, 0x001e, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, - 0x9184, 0x007f, 0x090c, 0xa8ab, 0x0010, 0x7034, 0x080f, 0x7044, - 0x9005, 0x0118, 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, - 0x7050, 0x8001, 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, - 0x1120, 0x7158, 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, - 0x0016, 0x7078, 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, - 0x7077, 0x0009, 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, - 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, - 0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x8854, 0x8855, - 0x8871, 0x00e6, 0x2071, 0x19fb, 0x7018, 0x9005, 0x1120, 0x711a, - 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, - 0x19fb, 0x701c, 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, - 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x19fb, 0xb888, 0x9102, - 0x0208, 0xb98a, 0x00ee, 0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, - 0x6724, 0x1168, 0xb888, 0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, - 0x2091, 0x8000, 0x0016, 0x080c, 0x9ab1, 0x001e, 0x012e, 0x8108, - 0x9182, 0x0800, 0x0218, 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, - 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000, 0x6040, 0x9005, - 0x0128, 0x8001, 0x6042, 0x1110, 0x080c, 0xd3e5, 0x6018, 0x9005, - 0x0558, 0x8001, 0x601a, 0x1540, 0x6120, 0x9186, 0x0003, 0x0148, - 0x9186, 0x0006, 0x0130, 0x9186, 0x0009, 0x11e0, 0x611c, 0xd1c4, - 0x1100, 0x080c, 0xd0d8, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, - 0x199a, 0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, - 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, - 0xd0e4, 0x0110, 0x080c, 0xcdbc, 0x012e, 0x9c88, 0x0018, 0x7116, - 0x2001, 0x181a, 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, - 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fb, 0x7027, 0x07d0, 0x7023, - 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a04, 0x2003, 0x0000, 0x0005, - 0x00e6, 0x2071, 0x19fb, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, - 0x2011, 0x1a07, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fb, - 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, - 0x705c, 0x8000, 0x705e, 0x2001, 0x1a0b, 0x2044, 0xa06c, 0x9086, - 0x0000, 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, - 0x7064, 0xa08e, 0x080c, 0x10f8, 0x002e, 0x008e, 0x0005, 0x0006, - 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x0156, 0x080c, 0x8776, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, - 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, - 0x19fb, 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, - 0x0006, 0x2071, 0x19fb, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, - 0x000e, 0x00ee, 0x0005, 0x2069, 0x1800, 0x69e8, 0xd1e4, 0x1518, - 0x0026, 0xd1ec, 0x0140, 0x6a54, 0x6874, 0x9202, 0x0288, 0x8117, - 0x9294, 0x00c0, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, - 0x0007, 0x0110, 0x69ea, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, - 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68ea, - 0x080c, 0x0eee, 0x002e, 0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, - 0x210d, 0x2061, 0x0100, 0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, - 0xfff4, 0x200f, 0x1220, 0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, - 0x001e, 0x0005, 0x00c6, 0x2061, 0x1a74, 0x00ce, 0x0005, 0x9184, - 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a74, 0x2060, 0x0005, - 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, - 0x1a74, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, - 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, - 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x89fa, 0xd0b4, - 0x1168, 0xd0bc, 0x1904, 0x89d3, 0x2009, 0x0006, 0x080c, 0x8a27, - 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160, - 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8a21, 0x908c, - 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, - 0x1869, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, - 0x0804, 0xb352, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, - 0xb352, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, - 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, - 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, - 0x918e, 0x0003, 0x1904, 0x8a21, 0x908c, 0x2020, 0x918e, 0x2020, - 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, 0x007e, - 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xb352, 0x0005, 0x6110, - 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, - 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, - 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, - 0x2009, 0x0041, 0x080c, 0xb352, 0x0005, 0x00b9, 0x0ce8, 0x87ff, - 0x1dd8, 0x2009, 0x0043, 0x080c, 0xb352, 0x0cb0, 0x6110, 0x00b6, - 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, - 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, - 0x080c, 0xd0d8, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, - 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, - 0x1158, 0x00c6, 0x2061, 0x1a74, 0x6200, 0xd28c, 0x1120, 0x6204, - 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6cde, 0x6014, 0x904d, - 0x0076, 0x2039, 0x0000, 0x190c, 0x8970, 0x007e, 0x009e, 0x0005, - 0x0156, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x81ff, 0x0110, 0x9205, - 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, - 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, - 0x0005, 0x2071, 0x1924, 0x7003, 0x0006, 0x7007, 0x0000, 0x700f, - 0x0000, 0x7013, 0x0001, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa867, - 0x0006, 0xa86b, 0x0001, 0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, - 0x702e, 0x7033, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x0096, - 0x00e6, 0x2071, 0x1924, 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, - 0x7322, 0x6834, 0x7026, 0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, - 0x7016, 0x683c, 0x701a, 0x2009, 0x0028, 0x200a, 0x9005, 0x0148, - 0x900e, 0x9188, 0x000c, 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, - 0x8318, 0xaa8e, 0xab92, 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, - 0x0001, 0x700f, 0x0000, 0x0006, 0x2009, 0x1ad1, 0x2104, 0x9082, - 0x0007, 0x200a, 0x000e, 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, - 0x080c, 0x1611, 0x9006, 0x2071, 0x193d, 0x7002, 0x7006, 0x702a, - 0x00ee, 0x009e, 0x012e, 0x0005, 0x2009, 0x1ad1, 0x2104, 0x9080, - 0x0007, 0x200a, 0x0005, 0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, - 0x2071, 0x1800, 0x7154, 0x2001, 0x0008, 0x910a, 0x0638, 0x2001, - 0x187d, 0x20ac, 0x9006, 0x9080, 0x0008, 0x1f04, 0x8ae3, 0x71c0, - 0x9102, 0x02e0, 0x2071, 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, - 0xb27d, 0x6023, 0x0009, 0x6003, 0x0004, 0x601f, 0x0101, 0x0089, - 0x0126, 0x2091, 0x8000, 0x080c, 0x8c61, 0x012e, 0x1f04, 0x8aef, - 0x9006, 0x00ce, 0x015e, 0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, - 0x0cc8, 0x00e6, 0x00b6, 0x0096, 0x0086, 0x0056, 0x0046, 0x0026, - 0x7118, 0x720c, 0x7620, 0x7004, 0xd084, 0x1128, 0x2021, 0x0024, - 0x2029, 0x0002, 0x0020, 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, - 0x100e, 0x090c, 0x0dc5, 0x2900, 0x6016, 0x2058, 0xac66, 0x9006, - 0xa802, 0xa806, 0xa86a, 0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, - 0x0020, 0x7008, 0xa89a, 0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, - 0xa8b3, 0x0000, 0x8109, 0x0160, 0x080c, 0x100e, 0x090c, 0x0dc5, - 0xad66, 0x2b00, 0xa802, 0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, - 0x002e, 0x004e, 0x005e, 0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, - 0x2079, 0x0000, 0x2071, 0x1924, 0x7004, 0x004b, 0x700c, 0x0002, - 0x8b5b, 0x8b54, 0x8b54, 0x0005, 0x8b65, 0x8bbb, 0x8bbb, 0x8bbb, - 0x8bbc, 0x8bcd, 0x8bcd, 0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, - 0x78a0, 0x79a0, 0x9106, 0x1904, 0x8bad, 0x7814, 0xd0bc, 0x1904, - 0x8bb6, 0x012e, 0x7018, 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, - 0x8bff, 0x0005, 0x1210, 0x7114, 0x910a, 0x9192, 0x000a, 0x0210, - 0x2009, 0x000a, 0x2001, 0x1888, 0x2014, 0x2001, 0x1936, 0x2004, - 0x9100, 0x9202, 0x0e50, 0x080c, 0x8d5c, 0x2200, 0x9102, 0x0208, - 0x2208, 0x0096, 0x702c, 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, - 0x8e65, 0x2100, 0xa87e, 0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, - 0x8000, 0x2009, 0x1a1b, 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, - 0x012e, 0x080c, 0x1117, 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, - 0x0904, 0x8b6d, 0x080c, 0x8d34, 0x012e, 0x0005, 0x7810, 0xc0c5, - 0x7812, 0x0804, 0x8b6d, 0x0005, 0x700c, 0x0002, 0x8bc1, 0x8bc4, - 0x8bc3, 0x080c, 0x8b63, 0x0005, 0x8001, 0x700e, 0x0096, 0x702c, - 0x2048, 0xa974, 0x009e, 0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, - 0x2048, 0x7018, 0x9100, 0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, - 0x7020, 0xa892, 0x9006, 0x0068, 0x0006, 0x080c, 0x8e65, 0x2100, - 0xaa8c, 0x9210, 0xaa8e, 0x1220, 0xa890, 0x9081, 0x0000, 0xa892, - 0x000e, 0x009e, 0x0126, 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, - 0x8d34, 0x012e, 0x0005, 0x00e6, 0x2071, 0x1924, 0x700c, 0x0002, - 0x8bfd, 0x8bfd, 0x8bfb, 0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, - 0x2091, 0x8000, 0x7030, 0x9005, 0x0508, 0x2078, 0x7814, 0x2048, - 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8c6a, 0x00be, 0x01b0, - 0x00e6, 0x2071, 0x193d, 0x080c, 0x8cb1, 0x00ee, 0x0178, 0x0096, - 0x080c, 0x1027, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x04b9, 0x0041, - 0x2001, 0x1947, 0x2003, 0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, - 0x00d6, 0x00c6, 0x0086, 0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, - 0x0180, 0xa864, 0x9084, 0x000f, 0x2068, 0x9d88, 0x20c7, 0x2165, - 0x0056, 0x2029, 0x0000, 0x080c, 0x8dea, 0x080c, 0x207f, 0x1dd8, - 0x005e, 0x00ae, 0x2001, 0x187f, 0x2004, 0xa88a, 0x080c, 0x1768, - 0x781f, 0x0101, 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, - 0x8cc0, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, - 0x0138, 0x2078, 0x780c, 0x7032, 0x2001, 0x1947, 0x2003, 0x0001, - 0x0005, 0x00e6, 0x2071, 0x1924, 0x7030, 0x600e, 0x2c00, 0x7032, - 0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8f33, 0x2005, - 0x906d, 0x090c, 0x0dc5, 0x9b80, 0x8f2b, 0x2005, 0x9065, 0x090c, - 0x0dc5, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, - 0x9085, 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, - 0x0148, 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, - 0x080c, 0x4c44, 0x684c, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa804, - 0x8000, 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, - 0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4c44, 0x684c, - 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa800, 0x8000, 0xa802, 0x009e, - 0x0888, 0x7000, 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, - 0x2300, 0x9005, 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, - 0x00d6, 0x7814, 0x9005, 0x090c, 0x0dc5, 0x781c, 0x9084, 0x0101, - 0x9086, 0x0101, 0x190c, 0x0dc5, 0x7827, 0x0000, 0x2069, 0x193d, - 0x6804, 0x9080, 0x193f, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, - 0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x193f, 0x2003, 0x0000, - 0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, - 0x0096, 0x2048, 0x9005, 0x190c, 0x1040, 0x009e, 0xa8ab, 0x0000, - 0x080c, 0x0fc0, 0x080c, 0xb2d3, 0x00ce, 0x009e, 0x0005, 0x6020, - 0x9086, 0x0009, 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, - 0x9085, 0x0001, 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, - 0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x9067, 0x00be, 0x6013, - 0x0000, 0x601b, 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, - 0x1928, 0x210c, 0xd194, 0x0005, 0x2009, 0x1928, 0x210c, 0xd1c4, - 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1924, 0x7110, - 0xc194, 0xc185, 0x7007, 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, - 0x1611, 0x00ee, 0x012e, 0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, - 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, - 0x700e, 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, - 0x0000, 0x080c, 0x8eb3, 0x0170, 0x080c, 0x8ee8, 0x0158, 0x2900, - 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a, 0x00de, - 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, - 0x00c6, 0x2071, 0x1931, 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, - 0x8ee8, 0x090c, 0x0dc5, 0x7018, 0x9005, 0x1160, 0x2900, 0x7002, - 0x700a, 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802, 0x7012, - 0x701e, 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a, 0xa803, - 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a, 0x701e, - 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, - 0x0005, 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, - 0x8000, 0x2071, 0x1931, 0x7300, 0x831f, 0x831e, 0x831e, 0x9384, - 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, - 0x8e65, 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021, 0x0078, - 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, - 0xa001, 0xa001, 0x4005, 0x2508, 0x080c, 0x8e6e, 0x2130, 0x7014, - 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004, 0x9600, - 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800, 0x9005, - 0x1148, 0x2009, 0x0001, 0x0026, 0x080c, 0x8d5c, 0x002e, 0x7000, - 0x2048, 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, - 0x9212, 0x1904, 0x8d9b, 0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, - 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, - 0x9580, 0x8f2b, 0x2005, 0x9075, 0x090c, 0x0dc5, 0x080c, 0x8e40, - 0x012e, 0x9580, 0x8f27, 0x2005, 0x9075, 0x090c, 0x0dc5, 0x0156, - 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, - 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, - 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, - 0x2d00, 0x0002, 0x8e2a, 0x8e2a, 0x8e2c, 0x8e2a, 0x8e2c, 0x8e2a, - 0x8e2a, 0x8e2a, 0x8e2a, 0x8e2a, 0x8e32, 0x8e2a, 0x8e32, 0x8e2a, - 0x8e2a, 0x8e2a, 0x080c, 0x0dc5, 0x4104, 0x20a9, 0x0002, 0x4002, - 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003, 0x01de, - 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, - 0x0096, 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, - 0x9188, 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198, 0x7008, - 0x2048, 0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x8ef7, 0x009e, - 0xa807, 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012, 0x700f, - 0x0000, 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b, 0x810b, - 0x2100, 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006, 0x0026, - 0x2100, 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e, 0x8108, - 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, - 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8eb1, 0x901e, 0x6808, 0x9005, - 0x0108, 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318, 0x6810, - 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, - 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003, 0x0967, - 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, - 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, - 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, - 0x2b00, 0x9080, 0x8f2f, 0x2005, 0x9005, 0x090c, 0x0dc5, 0x2004, - 0x90a0, 0x000a, 0x080c, 0x1027, 0x01d0, 0x2900, 0x7026, 0xa803, - 0x0000, 0xa807, 0x0000, 0x080c, 0x1027, 0x0188, 0x7024, 0xa802, - 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, - 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005, 0x7024, - 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c, 0x1040, 0x2400, 0x0cc0, - 0x0126, 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130, 0xa800, - 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005, 0x0126, - 0x2091, 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e, 0x0005, - 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, - 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, - 0x7008, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x1040, - 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e, 0x701a, - 0x701e, 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005, 0x1a67, - 0x0000, 0x0000, 0x0000, 0x1931, 0x0000, 0x0000, 0x0000, 0x1888, - 0x0000, 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, - 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, - 0x9053, 0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x9028, 0xb814, - 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, - 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118, 0xa078, - 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, - 0x1a0c, 0x0dc5, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, - 0x908c, 0x000f, 0x91e0, 0x20c7, 0x2c65, 0x9786, 0x0024, 0x2c05, - 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, - 0x8f93, 0x8f93, 0x8f95, 0x8f93, 0x8f93, 0x8f93, 0x8f97, 0x8f93, - 0x8f93, 0x8f93, 0x8f99, 0x8f93, 0x8f93, 0x8f93, 0x8f9b, 0x8f93, - 0x8f93, 0x8f93, 0x8f9d, 0x8f93, 0x8f93, 0x8f93, 0x8f9f, 0x8f93, - 0x8f93, 0x8f93, 0x8fa1, 0x080c, 0x0dc5, 0xa180, 0x04b8, 0xa190, - 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, - 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, - 0x001b, 0x0002, 0x8fc5, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, - 0x8fc7, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc9, 0x8fc3, - 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fcb, 0x8fc3, 0x8fc3, 0x8fc3, - 0x8fc3, 0x8fc3, 0x8fcd, 0x080c, 0x0dc5, 0xa180, 0x0038, 0xa198, - 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, - 0x8fe9, 0x8feb, 0x8fed, 0x8fef, 0x8ff1, 0x8ff3, 0x8ff5, 0x8ff7, - 0x8ff9, 0x8ffb, 0x8ffd, 0x8fff, 0x9001, 0x9003, 0x9005, 0x9007, - 0x9009, 0x900b, 0x900d, 0x900f, 0x9011, 0x9013, 0x9015, 0x9017, - 0x9019, 0x080c, 0x0dc5, 0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, - 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, - 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, - 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, - 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, - 0x0048, 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, - 0x0008, 0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x207f, 0x090c, - 0x0dc5, 0x0804, 0x8f6d, 0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, - 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, - 0x8f4f, 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, - 0x01b0, 0x2001, 0x1925, 0x2004, 0x9005, 0x0188, 0x2001, 0x1800, - 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, - 0x0004, 0x2011, 0x8014, 0x080c, 0x4c44, 0x004e, 0x003e, 0x00be, - 0x001e, 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a, 0xa936, - 0x7008, 0x9005, 0x0120, 0x8210, 0x910a, 0x0230, 0x0128, 0x7010, - 0x8210, 0x910a, 0x0208, 0x1de0, 0xaa8a, 0xa26a, 0x0005, 0x00f6, - 0x00d6, 0x0036, 0x2079, 0x0300, 0x781b, 0x0200, 0x7818, 0xd094, - 0x1dd8, 0x781b, 0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0, - 0xb8ac, 0x906d, 0x0198, 0x2079, 0x0000, 0x9c1e, 0x1118, 0x680c, - 0xb8ae, 0x0050, 0x9c06, 0x0130, 0x2d78, 0x680c, 0x906d, 0x1dd0, - 0x080c, 0x0dc5, 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, - 0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, - 0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, - 0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, - 0x1f04, 0x90a3, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, - 0x1d90, 0xb8ac, 0x9065, 0x01f0, 0x600c, 0xb8ae, 0x6024, 0xc08d, - 0x6026, 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, - 0x0101, 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa88b, 0x0000, 0xa8a8, - 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0dc5, 0x080c, 0x1040, 0x080c, - 0x8c61, 0x08f8, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, - 0x003e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, - 0x0016, 0x0006, 0x0156, 0x080c, 0x2873, 0x015e, 0x11b0, 0x080c, - 0x66b9, 0x190c, 0x0dc5, 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, - 0xb27d, 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, - 0x080c, 0xb352, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, - 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, - 0x0005, 0x9119, 0x9119, 0x9119, 0x911b, 0x916c, 0x9119, 0x9119, - 0x9119, 0x91e6, 0x9119, 0x9223, 0x9119, 0x9119, 0x9119, 0x9119, - 0x9119, 0x080c, 0x0dc5, 0x9182, 0x0040, 0x0002, 0x912e, 0x912e, - 0x912e, 0x912e, 0x912e, 0x912e, 0x912e, 0x912e, 0x912e, 0x9130, - 0x9145, 0x912e, 0x912e, 0x912e, 0x912e, 0x9158, 0x080c, 0x0dc5, - 0x0096, 0x080c, 0x9a61, 0x080c, 0x9bd3, 0x6114, 0x2148, 0xa87b, - 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, - 0x6ca3, 0x080c, 0xb2d3, 0x009e, 0x0005, 0x080c, 0x9a61, 0x00d6, - 0x6114, 0x080c, 0xd0d8, 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, - 0x6e9f, 0x009e, 0x00de, 0x080c, 0xb2d3, 0x080c, 0x9bd3, 0x0005, - 0x080c, 0x9a61, 0x080c, 0x3250, 0x6114, 0x0096, 0x2148, 0x080c, - 0xd0d8, 0x0120, 0xa87b, 0x0029, 0x080c, 0x6e9f, 0x009e, 0x080c, - 0xb2d3, 0x080c, 0x9bd3, 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, - 0x0096, 0x0002, 0x9187, 0x9187, 0x9187, 0x9187, 0x9187, 0x9187, - 0x9187, 0x9187, 0x9189, 0x9187, 0x9187, 0x9187, 0x91e2, 0x9187, - 0x9187, 0x9187, 0x9187, 0x9187, 0x9187, 0x9190, 0x9187, 0x080c, - 0x0dc5, 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, 0x91e2, - 0x6024, 0xd08c, 0x15d8, 0x080c, 0x8d17, 0x05e0, 0x00e6, 0x6114, - 0x2148, 0x080c, 0x8f37, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6c3b, - 0x009e, 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, - 0x080c, 0x9067, 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, - 0x8c6a, 0x00be, 0x01e0, 0x2071, 0x193d, 0x080c, 0x8cb1, 0x01b8, - 0x9086, 0x0001, 0x1128, 0x2001, 0x1947, 0x2004, 0x9005, 0x1178, - 0x0096, 0x080c, 0x100e, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, - 0x2c78, 0x080c, 0x8c28, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, - 0x8c61, 0x0cd0, 0x080c, 0x8d1c, 0x1160, 0x6010, 0x9005, 0x0130, - 0x2058, 0xb8ac, 0x9005, 0x190c, 0x0dc5, 0x6012, 0x2c00, 0x080c, - 0x8ce2, 0x0005, 0x080c, 0x9290, 0x009e, 0x0005, 0x9182, 0x0040, - 0x0096, 0x0002, 0x91fa, 0x91fa, 0x91fa, 0x91fc, 0x91fa, 0x91fa, - 0x91fa, 0x9221, 0x91fa, 0x91fa, 0x91fa, 0x91fa, 0x91fa, 0x91fa, - 0x91fa, 0x91fa, 0x080c, 0x0dc5, 0x6003, 0x0003, 0x6106, 0x6014, - 0x2048, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa837, 0x0000, 0xa83b, - 0x0000, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, - 0x8013, 0x8213, 0x9210, 0x621a, 0x2c10, 0x080c, 0x1be0, 0x080c, - 0x9564, 0x0126, 0x2091, 0x8000, 0x080c, 0x9bd3, 0x012e, 0x009e, - 0x0005, 0x080c, 0x0dc5, 0x080c, 0x9a61, 0x080c, 0x9bd3, 0x6114, - 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, - 0x00be, 0x080c, 0x6e9f, 0x080c, 0xb2d3, 0x009e, 0x0005, 0x6000, + 0x00a0, 0x080c, 0x2d52, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, + 0x080c, 0x1b2f, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d, 0x0005, + 0x080c, 0x7449, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x73c6, 0x0016, + 0x080c, 0x1b2f, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x709b, + 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x73c6, 0x0005, 0x0006, + 0x2001, 0x00a0, 0x080c, 0x2d52, 0x000e, 0x6124, 0xd1d4, 0x1160, + 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, + 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, 0x0005, 0x080c, + 0x7449, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, + 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, + 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d52, 0x000e, 0x6124, + 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158, + 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, + 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6, + 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2091, + 0x8000, 0x080c, 0x7569, 0x11d8, 0x2001, 0x180c, 0x200c, 0xd1b4, + 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, 0x2c7a, 0x6024, + 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e, + 0x080c, 0x6127, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, + 0x7583, 0x0150, 0x080c, 0x757a, 0x1138, 0x2001, 0x0001, 0x080c, + 0x283d, 0x080c, 0x7541, 0x00a0, 0x080c, 0x7446, 0x0178, 0x2001, + 0x0001, 0x080c, 0x283d, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, + 0x9086, 0x0022, 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, + 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, + 0x73d7, 0x080c, 0x87e3, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, + 0x2011, 0x73d7, 0x080c, 0x87da, 0x002e, 0x001e, 0x0005, 0x00e6, + 0x00f6, 0x0016, 0x080c, 0xa517, 0x2071, 0x1800, 0x080c, 0x7374, + 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, 0xa517, + 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, + 0x602a, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c, + 0xa8f7, 0x080c, 0xa801, 0x080c, 0x878f, 0x0036, 0x901e, 0x080c, + 0xa877, 0x003e, 0x60e3, 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15, + 0x2009, 0x0004, 0x080c, 0x2c80, 0x080c, 0x2b9b, 0x2001, 0x1800, + 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x73d7, 0x080c, 0x87e3, + 0x080c, 0x7583, 0x0118, 0x9006, 0x080c, 0x2d52, 0x080c, 0x0ba0, + 0x2001, 0x0001, 0x080c, 0x283d, 0x012e, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6, 0x2011, + 0x73e4, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1118, 0x7018, 0x9005, + 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, + 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8, 0x2001, + 0x00c0, 0x080c, 0x2d52, 0x0156, 0x20a9, 0x002d, 0x1d04, 0x7456, + 0x2091, 0x6000, 0x1f04, 0x7456, 0x015e, 0x00d6, 0x2069, 0x1800, + 0x689c, 0x8001, 0x0220, 0x0118, 0x689e, 0x00de, 0x0005, 0x689f, + 0x0014, 0x68e8, 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001, 0x1da8, + 0x080c, 0x87ef, 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, + 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x785d, 0x2001, 0x196e, + 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x2908, + 0x9006, 0x080c, 0x2d52, 0x080c, 0x5fe6, 0x6027, 0xffff, 0x602b, + 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, + 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197e, + 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, + 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7531, 0x709b, + 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, + 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, + 0x080c, 0x2908, 0x0026, 0x080c, 0xb072, 0x002e, 0x7000, 0x908e, + 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, + 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, + 0x012e, 0x015e, 0x080c, 0xd561, 0x0118, 0x9006, 0x080c, 0x2d7c, + 0x0804, 0x753d, 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, + 0x2c7a, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2d52, + 0x1f04, 0x74d5, 0x080c, 0x75bd, 0x012e, 0x015e, 0x080c, 0x757a, + 0x01d8, 0x6044, 0x9005, 0x0198, 0x2011, 0x0114, 0x2204, 0x9085, + 0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, + 0x75bd, 0x9006, 0x8001, 0x1df0, 0x000e, 0x6052, 0x0028, 0x6804, + 0xd0d4, 0x1110, 0x080c, 0x75bd, 0x080c, 0xd561, 0x0118, 0x9006, + 0x080c, 0x2d7c, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, + 0x2009, 0x00c8, 0x2011, 0x73e4, 0x080c, 0x87a1, 0x002e, 0x001e, + 0x080c, 0x85e8, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003, + 0x0004, 0x080c, 0x7227, 0x080c, 0x757a, 0x0138, 0x6804, 0xd0d4, + 0x1120, 0xd0dc, 0x1100, 0x080c, 0x7853, 0x00ee, 0x00de, 0x00ce, + 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, + 0x2071, 0x1800, 0x080c, 0x85ff, 0x080c, 0x85f1, 0x080c, 0x785d, + 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, + 0x080c, 0x2908, 0x9006, 0x080c, 0x2d52, 0x6043, 0x0090, 0x6043, + 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, + 0x0005, 0x0006, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x000e, + 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030, 0x9086, 0x0000, + 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030, 0x9086, + 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030, + 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, + 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, + 0x180c, 0x2004, 0x908c, 0x0013, 0x0168, 0x0020, 0x080c, 0x2928, + 0x900e, 0x0010, 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x3211, + 0x9006, 0x0019, 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, + 0x2e04, 0x0130, 0x080c, 0xd55a, 0x1128, 0x9085, 0x0010, 0x0010, + 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, + 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x0016, + 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000, 0x6052, 0x613a, + 0x20a9, 0x0012, 0x1d04, 0x75d2, 0x2091, 0x6000, 0x1f04, 0x75d2, + 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, + 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, 0x0040, 0x602f, 0x0000, + 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, + 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2908, + 0x2001, 0x00a0, 0x0006, 0x080c, 0xd561, 0x000e, 0x0130, 0x080c, + 0x2d70, 0x9006, 0x080c, 0x2d7c, 0x0010, 0x080c, 0x2d52, 0x000e, + 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x2bef, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, + 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001, + 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x7690, 0x2001, 0x180c, + 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027, + 0x0200, 0x2001, 0x0090, 0x080c, 0x2d52, 0x20a9, 0x0366, 0x6024, + 0xd0cc, 0x1518, 0x1d04, 0x763f, 0x2091, 0x6000, 0x1f04, 0x763f, + 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c, 0xa8f7, + 0x080c, 0xa801, 0x901e, 0x080c, 0xa877, 0x2001, 0x00a0, 0x080c, + 0x2d52, 0x080c, 0x784e, 0x080c, 0x6127, 0x080c, 0xd561, 0x0110, + 0x080c, 0x0d33, 0x9085, 0x0001, 0x0488, 0x080c, 0x1b2f, 0x60e3, + 0x0000, 0x2001, 0x196e, 0x2004, 0x080c, 0x2908, 0x60e2, 0x2001, + 0x0080, 0x080c, 0x2d52, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, + 0x1e00, 0x080c, 0x2c7a, 0x6024, 0x910c, 0x0138, 0x1d04, 0x7675, + 0x2091, 0x6000, 0x1f04, 0x7675, 0x0818, 0x6028, 0x9085, 0x1e00, + 0x602a, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, + 0x080c, 0xd561, 0x0110, 0x080c, 0x0d33, 0x9006, 0x00ee, 0x00de, + 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, + 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, + 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a7d, 0x2d04, + 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, + 0x6884, 0x9005, 0x1904, 0x7703, 0x2001, 0x0088, 0x080c, 0x2d52, + 0x9006, 0x60e2, 0x6886, 0x080c, 0x2908, 0x2069, 0x0200, 0x6804, + 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, + 0x602a, 0x6027, 0x0400, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, + 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x76e5, 0x2091, + 0x6000, 0x1f04, 0x76e5, 0x0804, 0x7733, 0x2069, 0x0140, 0x20a9, + 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c7a, 0x6024, + 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x76f1, 0x2091, + 0x6000, 0x1f04, 0x76f1, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, + 0x0002, 0x080c, 0xa8f7, 0x080c, 0xa801, 0x901e, 0x080c, 0xa877, + 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e, 0x080c, 0x6127, + 0x9085, 0x0001, 0x00c0, 0x080c, 0x1b2f, 0x2001, 0x0080, 0x080c, + 0x2d52, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, + 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, + 0x2908, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, + 0x00c0, 0x01c8, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, + 0x080c, 0xa8f7, 0x080c, 0xa801, 0x901e, 0x080c, 0xa877, 0x2069, + 0x0140, 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e, 0x080c, + 0x6127, 0x0804, 0x77ce, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, + 0xc1b5, 0x2102, 0x080c, 0x73cc, 0x2069, 0x0140, 0x2001, 0x0080, + 0x080c, 0x2d52, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, + 0x1118, 0x6808, 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, + 0x6027, 0x0200, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0027, + 0x7003, 0x0001, 0x0804, 0x77ce, 0x6027, 0x1e00, 0x2009, 0x1e00, + 0x080c, 0x2c7a, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, + 0x1d04, 0x778c, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, + 0x8642, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, + 0x19fc, 0x7078, 0x00ee, 0x9005, 0x19f8, 0x0400, 0x0026, 0x2011, + 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x002e, + 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, + 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2908, + 0x60e2, 0x2001, 0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, + 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, + 0x0026, 0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, + 0x1800, 0x080c, 0xd55a, 0x1904, 0x783c, 0x7130, 0xd184, 0x1170, + 0x080c, 0x33a0, 0x0138, 0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, + 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x783c, 0x2011, 0x1848, + 0x220c, 0xd1a4, 0x0538, 0x0016, 0x2019, 0x000e, 0x080c, 0xe915, + 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, + 0x9186, 0x0080, 0x0188, 0x080c, 0x671d, 0x1170, 0x2120, 0x9006, + 0x0016, 0x2009, 0x000e, 0x080c, 0xe9a5, 0x2009, 0x0001, 0x2011, + 0x0100, 0x080c, 0x891c, 0x001e, 0x8108, 0x1f04, 0x7805, 0x00be, + 0x015e, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, + 0x0004, 0x080c, 0x3211, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, + 0x007f, 0x900e, 0x080c, 0x671d, 0x1110, 0x080c, 0x6141, 0x8108, + 0x1f04, 0x7832, 0x00be, 0x015e, 0x080c, 0x1b2f, 0x080c, 0xb072, + 0x60e3, 0x0000, 0x080c, 0x6127, 0x080c, 0x7495, 0x00ee, 0x00ce, + 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x197e, + 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003, 0x0000, 0x0005, + 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197d, 0x2003, + 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007, 0x0000, + 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0, 0x2900, 0x704e, + 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0, 0x2900, 0x7052, + 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, + 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, + 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, + 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, 0x7002, 0x6854, + 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, 0x9005, 0x1110, + 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, + 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, + 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, 0x18fa, + 0x6807, 0x0001, 0x00de, 0x080c, 0x7e40, 0x9006, 0x00ee, 0x0005, + 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x2011, 0x0100, 0x2214, + 0x9296, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x1f04, + 0x78c4, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004, + 0x0002, 0x78e3, 0x78e4, 0x791c, 0x7977, 0x7a87, 0x78e1, 0x78e1, + 0x7ab1, 0x080c, 0x0dc5, 0x0005, 0x2079, 0x0040, 0x782c, 0x908c, + 0x0780, 0x190c, 0x7f22, 0xd0a4, 0x01f8, 0x7824, 0x2048, 0x9006, + 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x0040, 0x0610, + 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, 0x0003, 0x1168, 0x7004, + 0x0002, 0x790c, 0x78e6, 0x790c, 0x790a, 0x790c, 0x790c, 0x790c, + 0x790c, 0x790c, 0x080c, 0x7977, 0x782c, 0xd09c, 0x090c, 0x7e40, + 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, 0x003b, 0x0c10, 0x080c, + 0x79ad, 0x0c90, 0x00e3, 0x08e8, 0x0005, 0x79ad, 0x79ad, 0x79ad, + 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79cf, 0x79ad, 0x79ad, + 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, + 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, + 0x79ad, 0x79b9, 0x79ad, 0x7ba7, 0x79ad, 0x79ad, 0x79ad, 0x79cf, + 0x79ad, 0x79b9, 0x7be8, 0x7c29, 0x7c70, 0x7c84, 0x79ad, 0x79ad, + 0x79cf, 0x79b9, 0x79e3, 0x79ad, 0x7a5b, 0x7d2f, 0x7d4a, 0x79ad, + 0x79cf, 0x79ad, 0x79e3, 0x79ad, 0x79ad, 0x7a51, 0x7d4a, 0x79ad, + 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, + 0x79f7, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, + 0x79ad, 0x79ad, 0x7ec6, 0x79ad, 0x7e70, 0x79ad, 0x7e70, 0x79ad, + 0x7a0c, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x2079, + 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, 0x782c, 0x080c, 0x7e69, + 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, + 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, 0x002b, 0x0c50, 0x00e9, + 0x080c, 0x7e40, 0x0005, 0x79ad, 0x79b9, 0x7b93, 0x79ad, 0x79b9, + 0x79ad, 0x79b9, 0x79b9, 0x79ad, 0x79b9, 0x7b93, 0x79b9, 0x79b9, + 0x79b9, 0x79b9, 0x79b9, 0x79ad, 0x79b9, 0x7b93, 0x79ad, 0x79ad, + 0x79b9, 0x79ad, 0x79ad, 0x79ad, 0x79b9, 0x00e6, 0x2071, 0x18fa, + 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, 0x2009, 0x1000, 0x0049, + 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, 0x2009, 0x0800, 0x0009, + 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, 0x00ff, 0x9105, 0xa86a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x0005, 0xa864, + 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, 0x1120, 0x7007, 0x0001, + 0x0804, 0x7b30, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, + 0x704b, 0x7b30, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0968, + 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b4b, 0x7007, 0x0003, + 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b4b, 0x0005, 0xa864, + 0x8007, 0x9084, 0x00ff, 0x0904, 0x79b5, 0x8001, 0x1120, 0x7007, + 0x0001, 0x0804, 0x7b67, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, + 0x701a, 0x704b, 0x7b67, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, + 0x9086, 0x0001, 0x1904, 0x79b5, 0x7007, 0x0001, 0x2009, 0x1834, + 0x210c, 0x81ff, 0x11a8, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, + 0x0000, 0x080c, 0x63be, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, + 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6dd1, 0x012e, 0x0ca0, + 0xa994, 0x9186, 0x0071, 0x0d38, 0x9186, 0x0064, 0x0d20, 0x9186, + 0x007c, 0x0d08, 0x9186, 0x0028, 0x09f0, 0x9186, 0x0038, 0x09d8, + 0x9186, 0x0078, 0x09c0, 0x9186, 0x005f, 0x09a8, 0x9186, 0x0056, + 0x0990, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, + 0x08a0, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, + 0x0001, 0x0804, 0x7d61, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040, + 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888, + 0x7012, 0x9082, 0x0401, 0x1a04, 0x79bd, 0xaab4, 0x928a, 0x0002, + 0x1a04, 0x79bd, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, + 0x2001, 0x7aee, 0x0018, 0x9280, 0x7ae4, 0x2005, 0x7056, 0x7010, + 0x9015, 0x0904, 0x7acf, 0x080c, 0x1027, 0x1118, 0x7007, 0x0004, + 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050, + 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008, + 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, + 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c, + 0x10f8, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, + 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1040, 0x7014, + 0x2048, 0x0804, 0x79bd, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, + 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x7a87, 0x7014, + 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, + 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, + 0x0904, 0x7d61, 0x0804, 0x7b30, 0x7ae6, 0x7aea, 0x0002, 0x001d, + 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d, + 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050, + 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, + 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, + 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, + 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a, + 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e, + 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e, + 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005, + 0x2009, 0x1834, 0x210c, 0x81ff, 0x1178, 0x080c, 0x61bb, 0x1108, + 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd14c, + 0x080c, 0x6dd1, 0x012e, 0x0ca0, 0x080c, 0xd55a, 0x1d70, 0x2001, + 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1188, + 0xa888, 0x9005, 0x0188, 0xa883, 0x0000, 0x080c, 0x624b, 0x1108, + 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, + 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, 0x0000, 0x0c90, 0x0419, + 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, + 0x0120, 0x080c, 0x6320, 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, + 0x6298, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, + 0x080c, 0x6dd1, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98, + 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, 0x1800, 0x60d0, 0x9005, + 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, 0x2908, 0x2048, 0xa906, + 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0003, 0x0030, + 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x00b6, + 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff, 0x9096, 0x0004, + 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190, 0x900e, 0x20a9, + 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, 0x11d8, 0xa974, 0x080c, + 0x671d, 0x11b8, 0x0066, 0xae80, 0x080c, 0x682d, 0x006e, 0x0088, + 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, + 0x080c, 0x671d, 0x1110, 0x080c, 0x692d, 0x8108, 0x1f04, 0x7bd0, + 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, 0x1040, 0x00be, 0x0005, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x00be, 0x0005, + 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a8e, 0x0580, + 0x2061, 0x1a75, 0x6100, 0xd184, 0x0178, 0xa888, 0x9084, 0x00ff, + 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005, 0x1538, 0x6003, + 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0xa890, 0x9005, + 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888, 0x9084, 0x00ff, + 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff, 0x0148, 0x600a, + 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x7e2a, + 0x012e, 0x0804, 0x7e24, 0x012e, 0x0804, 0x7e1e, 0x012e, 0x0804, + 0x7e21, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a8e, + 0x05e0, 0x2061, 0x1a75, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, + 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170, 0xa988, 0x918c, + 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620, 0x0028, 0x8001, + 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c, 0x0188, 0xa988, + 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120, 0x2100, 0x9318, + 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100, 0x931a, 0x0250, + 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, + 0x0804, 0x7e2a, 0x012e, 0x0804, 0x7e27, 0x012e, 0x0804, 0x7e24, + 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0x1a75, 0x6300, + 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, + 0x7e38, 0x012e, 0x0804, 0x7e27, 0x00b6, 0x0126, 0x00c6, 0x2091, + 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, + 0x1a75, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888, + 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, 0x2001, 0x1834, 0x2004, + 0x9005, 0x0118, 0x080c, 0xb134, 0x0068, 0x6017, 0xf400, 0x605b, + 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, 0x615a, 0x2009, 0x0041, + 0x080c, 0xb180, 0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, + 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, 0x891c, 0x002e, 0xa87c, + 0xd0c4, 0x0148, 0x2061, 0x1a75, 0x6000, 0xd08c, 0x1120, 0x6008, + 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e2a, + 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e24, 0xa984, 0x9186, 0x002e, + 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045, 0x0510, 0x9186, + 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194, 0x2102, 0x08b8, + 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, 0x1d10, 0xa974, 0x080c, + 0x671d, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, + 0x09b8, 0x6007, 0x0024, 0x2001, 0x1987, 0x2004, 0x601a, 0x0804, + 0x7cbf, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, + 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, 0xb134, 0x8eff, 0x0118, + 0x2e60, 0x080c, 0xb134, 0x00ee, 0x0804, 0x7cbf, 0x6024, 0xc0dc, + 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, + 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, + 0x080c, 0x933b, 0x080c, 0x98ed, 0x00ee, 0x0804, 0x7cbf, 0x2061, + 0x1a75, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x7e38, 0x0126, + 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, + 0x7e38, 0x012e, 0xa883, 0x0016, 0x0804, 0x7e31, 0xa883, 0x0007, + 0x0804, 0x7e31, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, + 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, 0x080c, 0x79b5, 0x0040, + 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7d61, + 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, + 0x1800, 0x61d0, 0x81ff, 0x1904, 0x7de3, 0x6130, 0xd194, 0x1904, + 0x7e0d, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x0a04, 0x7dd7, 0x6068, + 0x9e02, 0x1a04, 0x7dd7, 0x7120, 0x9186, 0x0006, 0x1904, 0x7dc9, + 0x7010, 0x905d, 0x0904, 0x7de3, 0xb800, 0xd0e4, 0x1904, 0x7e07, + 0x2061, 0x1a75, 0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, + 0x7024, 0xd0dc, 0x1904, 0x7e10, 0xa883, 0x0000, 0xa803, 0x0000, + 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, + 0x7e13, 0x080c, 0x57d3, 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, + 0x2e60, 0x080c, 0x883c, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, + 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, + 0x7e13, 0x012e, 0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, + 0x0006, 0x00be, 0x0804, 0x7e31, 0xd184, 0x0db8, 0xd1c4, 0x1190, + 0x00a0, 0xa974, 0x080c, 0x671d, 0x15d0, 0xb800, 0xd0e4, 0x15b8, + 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, + 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, + 0xa883, 0x0035, 0x0430, 0x080c, 0x57d7, 0xd0fc, 0x01e8, 0xa878, + 0x2070, 0x9e82, 0x1cd0, 0x02c0, 0x6068, 0x9e02, 0x12a8, 0x7120, + 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc, + 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007, 0x1904, 0x7d6d, + 0x7003, 0x0002, 0x0804, 0x7d6d, 0xa883, 0x0028, 0x0010, 0xa883, + 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, + 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, + 0x080c, 0xe4c8, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2009, 0x003e, + 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, + 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084, 0xff00, 0x9105, + 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x0005, + 0x080c, 0x1040, 0x0005, 0x00d6, 0x080c, 0x8833, 0x00de, 0x0005, + 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, + 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, 0x7f22, 0xd09c, 0x11a8, + 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278, 0x8001, 0x70c2, + 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802, 0xa806, 0x2071, + 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e, 0x00ee, 0x00de, + 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x7f22, 0x000e, 0x0005, + 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, 0xb0ab, 0x05d8, 0x2900, + 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x1138, 0x6008, + 0xc0fd, 0x600a, 0x2001, 0x196c, 0x2004, 0x0098, 0xa8a0, 0x9084, + 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, 0xa99c, 0x918c, 0x00ff, + 0x080c, 0x2894, 0x1540, 0x00b6, 0x080c, 0x671d, 0x2b00, 0x00be, + 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040, 0xa864, 0x9084, + 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, 0x0041, 0x080c, 0xb180, + 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, + 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6dd1, 0x012e, 0x0005, 0xa87b, 0x0028, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6dd1, 0x012e, 0x080c, 0xb101, 0x0005, 0x00d6, 0x00c6, + 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, + 0x0004, 0x1a04, 0x7f13, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, + 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, + 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0xb0ab, 0x1118, 0x080c, + 0xb153, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7ef1, 0x7ef6, 0x7ef9, + 0x7eff, 0x2019, 0x0002, 0x080c, 0xe915, 0x0060, 0x080c, 0xe8ac, + 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xe8c7, 0x0018, 0xa980, + 0x080c, 0xe8ac, 0x080c, 0xb101, 0xa887, 0x0000, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6dd1, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, + 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, + 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, + 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7f24, 0x0006, 0x0016, + 0x2001, 0x8003, 0x0006, 0x0804, 0x0dce, 0x2001, 0x1834, 0x2004, + 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, + 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, + 0x1120, 0x080c, 0x15a0, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, + 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, + 0x7fa4, 0x68c0, 0x90aa, 0x0005, 0x0a04, 0x85e8, 0x7d44, 0x7c40, + 0x9584, 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, + 0x1260, 0x9584, 0x0700, 0x8007, 0x0804, 0x7fab, 0x7000, 0x9084, + 0xff00, 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, + 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xedd2, + 0x080c, 0x84cd, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, + 0x080c, 0x852b, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, + 0x8006, 0x080c, 0x2397, 0x005e, 0x004e, 0x0020, 0x080c, 0xedd2, + 0x7817, 0x0140, 0x080c, 0x7569, 0x0168, 0x2001, 0x0111, 0x2004, + 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, + 0x2003, 0x0000, 0x080c, 0x7fe7, 0x2001, 0x19f2, 0x2004, 0x9005, + 0x090c, 0x98ed, 0x0005, 0x0002, 0x7fbd, 0x82d5, 0x7fb4, 0x7fb4, + 0x7fb4, 0x7fb4, 0x7fb4, 0x7fb4, 0x7817, 0x0140, 0x2001, 0x19f2, + 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x7000, 0x908c, 0xff00, + 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286, 0x2000, + 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x583d, 0x0070, + 0x080c, 0x8026, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x820d, + 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x83f4, 0x7817, 0x0140, + 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x2001, + 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, + 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, + 0x4be9, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, + 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, + 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, + 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, + 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4be9, + 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, + 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, + 0x0023, 0x1904, 0x81de, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8492, + 0x0904, 0x81de, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, + 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x81de, + 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, + 0x080c, 0xb180, 0x0804, 0x81de, 0x908e, 0x0214, 0x0118, 0x908e, + 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xb180, 0x0804, 0x81de, + 0x908e, 0x0100, 0x1904, 0x81de, 0x7034, 0x9005, 0x1904, 0x81de, + 0x2009, 0x0016, 0x080c, 0xb180, 0x0804, 0x81de, 0x9186, 0x0022, + 0x1904, 0x81de, 0x7030, 0x908e, 0x0300, 0x1580, 0x68dc, 0xd0a4, + 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, 0x697e, 0x7004, + 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, + 0x00ff, 0x0016, 0x2008, 0x080c, 0x28dd, 0x7932, 0x7936, 0x001e, + 0x000e, 0x00fe, 0x080c, 0x2894, 0x695e, 0x703c, 0x00e6, 0x2071, + 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee, 0x7034, 0x9005, + 0x1904, 0x81de, 0x2009, 0x0017, 0x0804, 0x818e, 0x908e, 0x0400, + 0x1190, 0x7034, 0x9005, 0x1904, 0x81de, 0x080c, 0x7569, 0x0120, + 0x2009, 0x001d, 0x0804, 0x818e, 0x68dc, 0xc0a5, 0x68de, 0x2009, + 0x0030, 0x0804, 0x818e, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, + 0x1904, 0x81de, 0x2009, 0x0018, 0x0804, 0x818e, 0x908e, 0x2010, + 0x1120, 0x2009, 0x0019, 0x0804, 0x818e, 0x908e, 0x2110, 0x1120, + 0x2009, 0x001a, 0x0804, 0x818e, 0x908e, 0x5200, 0x1140, 0x7034, + 0x9005, 0x1904, 0x81de, 0x2009, 0x001b, 0x0804, 0x818e, 0x908e, + 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x81de, 0x2009, 0x001c, + 0x0804, 0x818e, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, + 0x818e, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x81de, + 0x2009, 0x0024, 0x0804, 0x818e, 0x908c, 0xff00, 0x918e, 0x2400, + 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, + 0x818e, 0x080c, 0xdc98, 0x1904, 0x81de, 0x0804, 0x818c, 0x908c, + 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x818e, + 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x818e, 0x908e, + 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, + 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, + 0x8108, 0x0046, 0x2124, 0x080c, 0x4be9, 0x004e, 0x8108, 0x0f04, + 0x8142, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, + 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0804, 0x818e, + 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804, 0x818e, 0x908e, + 0x5400, 0x1138, 0x080c, 0x8598, 0x1904, 0x81de, 0x2009, 0x0046, + 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x85c0, 0x1118, 0x2009, + 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e, 0x7800, 0x1118, + 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, + 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, + 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, + 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, + 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, + 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x1904, 0x81e1, + 0x080c, 0x66b2, 0x1904, 0x81e1, 0xbe12, 0xbd16, 0x001e, 0x0016, + 0x080c, 0x7569, 0x01c0, 0x68dc, 0xd08c, 0x1148, 0x7000, 0x9084, + 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x687c, + 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, + 0x00ff, 0xb8c2, 0x0080, 0xb8c0, 0x9005, 0x1168, 0x9186, 0x0046, + 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506, 0x9084, 0xff00, + 0x1110, 0x001e, 0x0098, 0x080c, 0xb0ab, 0x01a8, 0x2b08, 0x6112, + 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, + 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xb180, 0x00ce, 0x00be, + 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, + 0x2011, 0x8049, 0x080c, 0x4be9, 0x080c, 0xb153, 0x0d90, 0x2b08, + 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, + 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, + 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, + 0x6003, 0x0001, 0x080c, 0x9383, 0x08a0, 0x080c, 0x8607, 0x1158, + 0x080c, 0x336a, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, + 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, + 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8492, + 0x0904, 0x826d, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, + 0x7034, 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, 0xb180, 0x04a8, + 0x908e, 0x0100, 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, + 0x080c, 0xb180, 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, + 0x1400, 0x1518, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, + 0x8211, 0x220c, 0x080c, 0x2894, 0x11b8, 0x080c, 0x66b2, 0x11a0, + 0xbe12, 0xbd16, 0x080c, 0xb0ab, 0x0178, 0x2b08, 0x6112, 0x080c, + 0xd2d2, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xb180, + 0x080c, 0x98ed, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, + 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, + 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, + 0x2009, 0x007f, 0x0804, 0x82cf, 0x9596, 0xfffe, 0x1120, 0x2009, + 0x007e, 0x0804, 0x82cf, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, + 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac, 0x0130, + 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, + 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, + 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, + 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, + 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, + 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x82a4, + 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, + 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837, 0x200c, + 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, + 0x810f, 0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19f2, + 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x82fd, 0x82fd, 0x82fd, + 0x84a4, 0x82fd, 0x8306, 0x8331, 0x83bf, 0x82fd, 0x82fd, 0x82fd, + 0x82fd, 0x82fd, 0x82fd, 0x82fd, 0x82fd, 0x7817, 0x0140, 0x2001, + 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x00b6, 0x7110, + 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a, + 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, + 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, + 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xb180, 0x7817, + 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x00be, + 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x8395, 0x7110, + 0xd1bc, 0x1904, 0x8395, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, + 0x2130, 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x33ac, + 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, + 0x8395, 0x080c, 0x66b2, 0x1904, 0x8395, 0xbe12, 0xbd16, 0xb800, + 0xd0ec, 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, + 0x080c, 0xb0ab, 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, + 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, + 0x0044, 0x080c, 0xdf10, 0x0408, 0x080c, 0x6a92, 0x1138, 0xb807, + 0x0606, 0x0c30, 0x190c, 0x8271, 0x11c0, 0x0898, 0x080c, 0xb0ab, + 0x2b08, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, + 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, + 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x7817, 0x0140, 0x2001, + 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x00ce, 0x00be, 0x0005, + 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, + 0x4be9, 0x080c, 0xb153, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, + 0x7120, 0x610a, 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, + 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, 0x08b0, 0x00b6, + 0x7110, 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0, + 0x9c82, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084, + 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, + 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xb180, + 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, + 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, + 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8607, 0x1180, 0x080c, + 0x336a, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, + 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, + 0x840e, 0x840f, 0x840e, 0x840e, 0x8474, 0x8483, 0x0005, 0x00b6, + 0x700c, 0x7108, 0x080c, 0x2894, 0x1904, 0x8472, 0x080c, 0x66b2, + 0x1904, 0x8472, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, + 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x8472, 0x080c, 0x6a92, + 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a9a, 0x0118, 0x9086, + 0x0004, 0x1588, 0x00c6, 0x080c, 0x8492, 0x00ce, 0x05d8, 0x080c, + 0xb0ab, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0002, + 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb180, 0x0458, 0x080c, + 0x6a92, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a9a, 0x0118, + 0x9086, 0x0004, 0x1180, 0x080c, 0xb0ab, 0x2b08, 0x01d8, 0x6112, + 0x080c, 0xd2d2, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, + 0x080c, 0xb180, 0x0078, 0x080c, 0xb0ab, 0x2b08, 0x0158, 0x6112, + 0x080c, 0xd2d2, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, + 0x080c, 0xb180, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, + 0x0148, 0x080c, 0x83ea, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, + 0x080c, 0xb180, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, + 0x080c, 0x83ea, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, + 0xb180, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, + 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218, 0x9085, + 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, + 0x7024, 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298, + 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, + 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, + 0x0051, 0x080c, 0xb180, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, + 0x9005, 0x090c, 0x98ed, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, + 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, + 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, + 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0xb0ab, + 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, + 0x220c, 0x080c, 0x2894, 0x15a0, 0x080c, 0x66b2, 0x1588, 0xbe12, + 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xd2d2, 0x080c, + 0x100e, 0x0510, 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a, + 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, + 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, + 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xb101, 0x006e, 0x0cc0, + 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, + 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x8582, 0x9186, 0x0022, + 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x8584, 0x7030, + 0x908e, 0x0400, 0x0904, 0x8584, 0x908e, 0x6000, 0x05e8, 0x908e, + 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837, 0x210c, + 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6a50, 0x0588, 0x68b0, + 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x6880, + 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, + 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, + 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, + 0x0023, 0x1140, 0x080c, 0x8492, 0x0128, 0x6004, 0x9086, 0x0002, + 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, + 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, + 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, + 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, + 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, + 0x027a, 0x080c, 0xc0e3, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, + 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xc0e3, 0x1120, 0xd494, + 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, + 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, + 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, + 0x0272, 0x080c, 0xc0e3, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, + 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xc0e3, 0x1120, 0xd494, + 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, + 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, + 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, + 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, + 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, + 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, + 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19fc, + 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, + 0x7017, 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, 0xa52d, 0x7032, + 0x703a, 0x703f, 0x0064, 0x7037, 0xa595, 0x7047, 0xffff, 0x704a, + 0x704f, 0x5665, 0x7052, 0x7063, 0x87aa, 0x080c, 0x1027, 0x090c, + 0x0dc5, 0x2900, 0x7042, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, + 0xdcb0, 0x0005, 0x2071, 0x19fc, 0x1d04, 0x86f8, 0x2091, 0x6000, + 0x700c, 0x8001, 0x700e, 0x1540, 0x2001, 0x013c, 0x2004, 0x9005, + 0x190c, 0x8818, 0x2001, 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, + 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, + 0x080c, 0x0dc5, 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, + 0x8000, 0x080c, 0x87ef, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, + 0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, + 0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, + 0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, + 0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x05a8, 0x702c, 0x8001, + 0x702e, 0x1588, 0x0016, 0x2009, 0x0306, 0x210c, 0x9184, 0x0030, + 0x01e8, 0x9184, 0x0048, 0x9086, 0x0008, 0x11c0, 0x7038, 0x9005, + 0x01a8, 0x8001, 0x703a, 0x1190, 0x080c, 0x7569, 0x0178, 0x00e6, + 0x2071, 0x19e9, 0x080c, 0xa623, 0x00ee, 0x1140, 0x2009, 0x1a87, + 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x0068, 0x001e, 0x702f, + 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, 0xa6d9, + 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310, 0x8001, + 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052, 0x1148, + 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156, 0x7060, + 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d, 0x0158, + 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109, 0x717a, + 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138, + 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e, + 0x7004, 0x0002, 0x8720, 0x8721, 0x873d, 0x00e6, 0x2071, 0x19fc, + 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, + 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1120, + 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x00e6, + 0x2071, 0x19fc, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005, + 0x0005, 0x00b6, 0x7110, 0x080c, 0x671d, 0x1168, 0xb888, 0x8001, + 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, + 0x98ed, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e, + 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126, + 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110, + 0x080c, 0xd163, 0x6018, 0x9005, 0x0558, 0x8001, 0x601a, 0x1540, + 0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, + 0x0009, 0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c, 0xce56, 0x01b0, + 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, + 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, + 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, 0x080c, 0xcb3e, + 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, + 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005, 0x00e6, 0x2071, + 0x19fc, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, + 0x1a05, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x7132, + 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x1a08, 0x2013, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x19fc, 0x711a, 0x721e, 0x700b, 0x0009, + 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000, 0x705e, 0x2001, + 0x1a0c, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, 0x7070, 0xa09a, + 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e, 0x080c, 0x10f8, + 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, 0x8642, 0x015e, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e, + 0x000e, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x717a, 0x727e, 0x7077, + 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x707c, + 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x2069, + 0x1800, 0x69e8, 0xd1e4, 0x1518, 0x0026, 0xd1ec, 0x0140, 0x6a54, + 0x6874, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0, 0x0088, 0x9184, + 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, 0x69ea, 0x0070, + 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106, 0x9094, 0x00c0, + 0x9184, 0xff3f, 0x9205, 0x68ea, 0x080c, 0x0eee, 0x002e, 0x0005, + 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100, 0x60f0, + 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220, 0x8108, + 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x2061, + 0x1a75, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003, 0x8003, 0x8003, + 0x9080, 0x1a75, 0x2060, 0x0005, 0xa884, 0x908a, 0x199a, 0x1638, + 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a75, 0x6014, 0x00ce, 0x9005, + 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, + 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, + 0x00c0, 0x0904, 0x88c6, 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x889f, + 0x2009, 0x0006, 0x080c, 0x88f3, 0x0005, 0x900e, 0x0c60, 0x2001, + 0x1999, 0x08b0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, + 0x0003, 0x1904, 0x88ed, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, + 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, 0x1138, + 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xb180, 0x0005, 0x87ff, + 0x1de8, 0x2009, 0x0042, 0x0804, 0xb180, 0x6110, 0x00b6, 0x2158, + 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, + 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, + 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x88ed, + 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, + 0x080c, 0x1768, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, + 0x080c, 0xb180, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, + 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, + 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, + 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, 0xb180, + 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, + 0xb180, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, + 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, + 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xce56, 0x0518, 0x6014, + 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, + 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a75, + 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, + 0x080c, 0x6c10, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, + 0x883c, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a75, + 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, + 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, + 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1925, 0x7003, + 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, 0x080c, + 0x1027, 0x090c, 0x0dc5, 0xa867, 0x0006, 0xa86b, 0x0001, 0xa8ab, + 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000, 0x0005, + 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1925, 0x702c, + 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, 0xa896, + 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c, 0x701a, 0x2009, + 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188, 0x000c, 0x8001, + 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92, 0x7010, + 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000, 0x0006, + 0x2009, 0x1ad2, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e, 0xc095, + 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x1611, 0x9006, 0x2071, + 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e, 0x0005, + 0x2009, 0x1ad2, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005, 0x00e6, + 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154, 0x2001, + 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006, 0x9080, + 0x0008, 0x1f04, 0x89af, 0x71c0, 0x9102, 0x02e0, 0x2071, 0x1877, + 0x20a9, 0x0007, 0x00c6, 0x080c, 0xb0ab, 0x6023, 0x0009, 0x6003, + 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8b2d, 0x012e, 0x1f04, 0x89bb, 0x9006, 0x00ce, 0x015e, 0x012e, + 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6, 0x0096, + 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620, 0x7004, + 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, 0x2021, + 0x002c, 0x2029, 0x000a, 0x080c, 0x100e, 0x090c, 0x0dc5, 0x2900, + 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a, 0xa87a, + 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a, 0x7010, + 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109, 0x0160, + 0x080c, 0x100e, 0x090c, 0x0dc5, 0xad66, 0x2b00, 0xa802, 0x2900, + 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e, 0x008e, + 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071, 0x1925, + 0x7004, 0x004b, 0x700c, 0x0002, 0x8a27, 0x8a20, 0x8a20, 0x0005, + 0x8a31, 0x8a87, 0x8a87, 0x8a87, 0x8a88, 0x8a99, 0x8a99, 0x700c, + 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106, 0x1904, + 0x8a79, 0x7814, 0xd0bc, 0x1904, 0x8a82, 0x012e, 0x7018, 0x910a, + 0x1128, 0x7030, 0x9005, 0x1904, 0x8acb, 0x0005, 0x1210, 0x7114, + 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001, 0x1888, + 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202, 0x0e50, 0x080c, + 0x8c25, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c, 0x2048, + 0xa873, 0x0001, 0xa976, 0x080c, 0x8d2e, 0x2100, 0xa87e, 0xa86f, + 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a1c, 0x2104, + 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x1117, 0x1de8, + 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8a39, 0x080c, 0x8bfd, + 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8a39, 0x0005, + 0x700c, 0x0002, 0x8a8d, 0x8a90, 0x8a8f, 0x080c, 0x8a2f, 0x0005, + 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e, 0x0011, + 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100, 0x7214, + 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006, 0x0068, + 0x0006, 0x080c, 0x8d2e, 0x2100, 0xaa8c, 0x9210, 0xaa8e, 0x1220, + 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126, 0x2091, + 0x8000, 0x78a2, 0x701a, 0x080c, 0x8bfd, 0x012e, 0x0005, 0x00e6, + 0x2071, 0x1925, 0x700c, 0x0002, 0x8ac9, 0x8ac9, 0x8ac7, 0x700f, + 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030, 0x9005, + 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059, 0x0000, + 0x080c, 0x8b36, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e, 0x080c, + 0x8b7d, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1027, 0x2900, 0x009e, + 0x0148, 0xa8aa, 0x04b9, 0x0041, 0x2001, 0x1948, 0x2003, 0x0000, + 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086, 0x00a6, + 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084, 0x000f, + 0x2068, 0x9d88, 0x20f0, 0x2165, 0x0056, 0x2029, 0x0000, 0x080c, + 0x8cb3, 0x080c, 0x20a8, 0x1dd8, 0x005e, 0x00ae, 0x2001, 0x187f, + 0x2004, 0xa88a, 0x080c, 0x1768, 0x781f, 0x0101, 0x7813, 0x0000, + 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8c, 0x012e, 0x008e, 0x00ce, + 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, 0x2078, 0x780c, 0x7032, + 0x2001, 0x1948, 0x2003, 0x0001, 0x0005, 0x00e6, 0x2071, 0x1925, + 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, 0x0005, 0x00d6, 0x00c6, + 0x0026, 0x9b80, 0x8dfc, 0x2005, 0x906d, 0x090c, 0x0dc5, 0x9b80, + 0x8df4, 0x2005, 0x9065, 0x090c, 0x0dc5, 0x6114, 0x2600, 0x9102, + 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, 0x0001, 0x002e, 0x00ce, + 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, 0x6854, 0xd084, 0x1178, + 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, 0x4be9, 0x684c, 0x0096, + 0x904d, 0x090c, 0x0dc5, 0xa804, 0x8000, 0xa806, 0x009e, 0x9006, + 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, 0xc08d, 0x6856, 0x2011, + 0x8025, 0x080c, 0x4be9, 0x684c, 0x0096, 0x904d, 0x090c, 0x0dc5, + 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, 0x7000, 0x2019, 0x0008, + 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, 0x9005, 0x0020, 0x0210, + 0x9302, 0x0008, 0x8002, 0x0005, 0x00d6, 0x7814, 0x9005, 0x090c, + 0x0dc5, 0x781c, 0x9084, 0x0101, 0x9086, 0x0101, 0x190c, 0x0dc5, + 0x7827, 0x0000, 0x2069, 0x193e, 0x6804, 0x9080, 0x1940, 0x2f08, + 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, 0x0208, 0x900e, 0x6906, + 0x9180, 0x1940, 0x2003, 0x0000, 0x00de, 0x0005, 0x0096, 0x00c6, + 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, 0x2048, 0x9005, 0x190c, + 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x0fc0, 0x080c, 0xb101, + 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, 0x0009, 0x1128, 0x601c, + 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x6000, + 0x9086, 0x0000, 0x0178, 0x6010, 0x9005, 0x0150, 0x00b6, 0x2058, + 0x080c, 0x8f31, 0x00be, 0x6013, 0x0000, 0x601b, 0x0000, 0x0010, + 0x2c00, 0x0861, 0x0005, 0x2009, 0x1929, 0x210c, 0xd194, 0x0005, + 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1925, 0x7110, 0xc194, + 0xd19c, 0x1118, 0xc185, 0x7007, 0x0000, 0x7112, 0x2001, 0x003b, + 0x080c, 0x1611, 0x00ee, 0x012e, 0x0005, 0x7814, 0xd0bc, 0x1108, + 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006, + 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026, + 0x702f, 0x0000, 0x080c, 0x8d7c, 0x0170, 0x080c, 0x8db1, 0x0158, + 0x2900, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a, + 0x00de, 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086, + 0x00d6, 0x00c6, 0x2071, 0x1932, 0x721c, 0x2100, 0x9202, 0x1618, + 0x080c, 0x8db1, 0x090c, 0x0dc5, 0x7018, 0x9005, 0x1160, 0x2900, + 0x7002, 0x700a, 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802, + 0x7012, 0x701e, 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a, + 0xa803, 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a, + 0x701e, 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e, + 0x00ee, 0x0005, 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126, + 0x2091, 0x8000, 0x2071, 0x1932, 0x7300, 0x831f, 0x831e, 0x831e, + 0x9384, 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104, + 0x080c, 0x8d2e, 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021, + 0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8, + 0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c, 0x8d37, 0x2130, + 0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004, + 0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800, + 0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c, 0x8c25, 0x002e, + 0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, + 0x2500, 0x9212, 0x1904, 0x8c64, 0x012e, 0x00ee, 0x014e, 0x013e, + 0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x9580, 0x8df4, 0x2005, 0x9075, 0x090c, 0x0dc5, 0x080c, + 0x8d09, 0x012e, 0x9580, 0x8df0, 0x2005, 0x9075, 0x090c, 0x0dc5, + 0x0156, 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e, + 0x9384, 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860, + 0x20e8, 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003, + 0x2e0c, 0x2d00, 0x0002, 0x8cf3, 0x8cf3, 0x8cf5, 0x8cf3, 0x8cf5, + 0x8cf3, 0x8cf3, 0x8cf3, 0x8cf3, 0x8cf3, 0x8cfb, 0x8cf3, 0x8cfb, + 0x8cf3, 0x8cf3, 0x8cf3, 0x080c, 0x0dc5, 0x4104, 0x20a9, 0x0002, + 0x4002, 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003, + 0x01de, 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e, + 0x0005, 0x0096, 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1, + 0x810c, 0x9188, 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198, + 0x7008, 0x2048, 0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x8dc0, + 0x009e, 0xa807, 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012, + 0x700f, 0x0000, 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b, + 0x810b, 0x2100, 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006, + 0x0026, 0x2100, 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e, + 0x8108, 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e, + 0x0cd8, 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8d7a, 0x901e, 0x6808, + 0x9005, 0x0108, 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318, + 0x6810, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a, + 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003, + 0x0967, 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0, + 0x9082, 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967, + 0x0a67, 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091, + 0x8000, 0x2b00, 0x9080, 0x8df8, 0x2005, 0x9005, 0x090c, 0x0dc5, + 0x2004, 0x90a0, 0x000a, 0x080c, 0x1027, 0x01d0, 0x2900, 0x7026, + 0xa803, 0x0000, 0xa807, 0x0000, 0x080c, 0x1027, 0x0188, 0x7024, + 0xa802, 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110, + 0x0208, 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005, + 0x7024, 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c, 0x1040, 0x2400, + 0x0cc0, 0x0126, 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130, + 0xa800, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e, + 0x0005, 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048, + 0xa800, 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, 0x009e, 0x0005, + 0x0096, 0x7008, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, + 0x1040, 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e, + 0x701a, 0x701e, 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005, + 0x1a68, 0x0000, 0x0000, 0x0000, 0x1932, 0x0000, 0x0000, 0x0000, + 0x1888, 0x0000, 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000, + 0x00e6, 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877, + 0x080c, 0x8f1c, 0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x8ef1, + 0xb814, 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003, + 0xa07e, 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118, + 0xa078, 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a, + 0x0019, 0x1a0c, 0x0dc5, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc, + 0x00ff, 0x908c, 0x000f, 0x91e0, 0x20f0, 0x2c65, 0x9786, 0x0024, + 0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, + 0x0002, 0x8e5c, 0x8e5c, 0x8e5e, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e60, + 0x8e5c, 0x8e5c, 0x8e5c, 0x8e62, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e64, + 0x8e5c, 0x8e5c, 0x8e5c, 0x8e66, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e68, + 0x8e5c, 0x8e5c, 0x8e5c, 0x8e6a, 0x080c, 0x0dc5, 0xa180, 0x04b8, + 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478, + 0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0dc5, + 0x9082, 0x001b, 0x0002, 0x8e8e, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, + 0x8e8c, 0x8e90, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e92, + 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e94, 0x8e8c, 0x8e8c, + 0x8e8c, 0x8e8c, 0x8e8c, 0x8e96, 0x080c, 0x0dc5, 0xa180, 0x0038, + 0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600, + 0x0002, 0x8eb2, 0x8eb4, 0x8eb6, 0x8eb8, 0x8eba, 0x8ebc, 0x8ebe, + 0x8ec0, 0x8ec2, 0x8ec4, 0x8ec6, 0x8ec8, 0x8eca, 0x8ecc, 0x8ece, + 0x8ed0, 0x8ed2, 0x8ed4, 0x8ed6, 0x8ed8, 0x8eda, 0x8edc, 0x8ede, + 0x8ee0, 0x8ee2, 0x080c, 0x0dc5, 0xb9e2, 0x0468, 0xb9de, 0x0458, + 0xb9da, 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418, + 0xb9ca, 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8, + 0xb9ba, 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098, + 0xb9aa, 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058, + 0xb99a, 0x0048, 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018, + 0xb98a, 0x0008, 0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x20a8, + 0x090c, 0x0dc5, 0x0804, 0x8e36, 0x00ae, 0x00be, 0x00ce, 0x00ee, + 0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006, + 0x0804, 0x8e18, 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810, + 0x9005, 0x01b0, 0x2001, 0x1926, 0x2004, 0x9005, 0x0188, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0, + 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4be9, 0x004e, 0x003e, + 0x00be, 0x001e, 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a, + 0xa936, 0x7008, 0x9005, 0x0120, 0x8210, 0x910a, 0x0238, 0x0130, + 0x7010, 0x8210, 0x910a, 0x0210, 0x0108, 0x0cd8, 0xaa8a, 0xa26a, + 0x0005, 0x00f6, 0x00d6, 0x0036, 0x2079, 0x0300, 0x781b, 0x0200, + 0x7818, 0xd094, 0x1dd8, 0x781b, 0x0202, 0xa001, 0xa001, 0x7818, + 0xd094, 0x1da0, 0xb8ac, 0x9005, 0x01b8, 0x2068, 0x2079, 0x0000, + 0x2c08, 0x911e, 0x1118, 0x680c, 0xb8ae, 0x0060, 0x9106, 0x0140, + 0x2d00, 0x2078, 0x680c, 0x9005, 0x090c, 0x0dc5, 0x2068, 0x0cb0, + 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, 0x781b, 0x0200, + 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x00c6, + 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, 0x01ff, 0x2071, + 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, 0x1f04, 0x8f71, + 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, 0x1d90, 0xb8ac, + 0x9005, 0x01e8, 0x2060, 0x600c, 0xb8ae, 0x6024, 0xc08d, 0x6026, + 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, 0x0101, + 0x6014, 0x2048, 0xa88b, 0x0000, 0xa8a8, 0xa8ab, 0x0000, 0x904d, + 0x090c, 0x0dc5, 0x080c, 0x1040, 0x080c, 0x8b2d, 0x0c00, 0x2071, + 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e, 0x00ce, 0x009e, + 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016, 0x0006, 0x0156, + 0x080c, 0x2894, 0x015e, 0x11b0, 0x080c, 0x66b2, 0x190c, 0x0dc5, + 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xb0ab, 0x0140, 0x2b00, + 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c, 0xb180, 0x00be, + 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066, 0x6000, 0x90b2, + 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0x8fe6, 0x8fe6, + 0x8fe6, 0x8fe8, 0x9039, 0x8fe6, 0x8fe6, 0x8fe6, 0x90a0, 0x8fe6, + 0x90dd, 0x8fe6, 0x8fe6, 0x8fe6, 0x8fe6, 0x8fe6, 0x080c, 0x0dc5, + 0x9182, 0x0040, 0x0002, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb, + 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffd, 0x9012, 0x8ffb, 0x8ffb, + 0x8ffb, 0x8ffb, 0x9025, 0x080c, 0x0dc5, 0x0096, 0x080c, 0x989d, + 0x080c, 0x9a0f, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, + 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6bd5, 0x080c, 0xb101, + 0x009e, 0x0005, 0x080c, 0x989d, 0x00d6, 0x6114, 0x080c, 0xce56, + 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6dd1, 0x009e, 0x00de, + 0x080c, 0xb101, 0x080c, 0x9a0f, 0x0005, 0x080c, 0x989d, 0x080c, + 0x3246, 0x6114, 0x0096, 0x2148, 0x080c, 0xce56, 0x0120, 0xa87b, + 0x0029, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c, 0x9a0f, + 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096, 0x0002, 0x9054, + 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9056, + 0x9054, 0x9054, 0x9054, 0x909c, 0x9054, 0x9054, 0x9054, 0x9054, + 0x9054, 0x9054, 0x905d, 0x9054, 0x080c, 0x0dc5, 0x6114, 0x2148, + 0xa938, 0x918e, 0xffff, 0x0904, 0x909c, 0x6024, 0xd08c, 0x15c0, + 0x00e6, 0x6114, 0x2148, 0x080c, 0x8e00, 0x0096, 0xa8a8, 0x2048, + 0x080c, 0x6b6d, 0x009e, 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128, + 0x00b6, 0x2058, 0x080c, 0x8f31, 0x00be, 0xae88, 0x00b6, 0x2059, + 0x0000, 0x080c, 0x8b36, 0x00be, 0x01e0, 0x2071, 0x193e, 0x080c, + 0x8b7d, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001, 0x1948, 0x2004, + 0x9005, 0x1178, 0x0096, 0x080c, 0x100e, 0x2900, 0x009e, 0x0148, + 0xa8aa, 0x00f6, 0x2c78, 0x080c, 0x8af4, 0x00fe, 0x00ee, 0x009e, + 0x0005, 0x080c, 0x8b2d, 0x0cd0, 0x080c, 0x914a, 0x009e, 0x0005, + 0x9182, 0x0040, 0x0096, 0x0002, 0x90b4, 0x90b4, 0x90b4, 0x90b6, + 0x90b4, 0x90b4, 0x90b4, 0x90db, 0x90b4, 0x90b4, 0x90b4, 0x90b4, + 0x90b4, 0x90b4, 0x90b4, 0x90b4, 0x080c, 0x0dc5, 0x6003, 0x0003, + 0x6106, 0x6014, 0x2048, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa837, + 0x0000, 0xa83b, 0x0000, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, + 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x2c10, 0x080c, + 0x1c09, 0x080c, 0x93a0, 0x0126, 0x2091, 0x8000, 0x080c, 0x9a0f, + 0x012e, 0x009e, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x989d, 0x080c, + 0x9a0f, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, + 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6dd1, 0x080c, 0xb101, 0x009e, + 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x0013, + 0x009e, 0x0005, 0x910a, 0x910a, 0x910a, 0x910c, 0x911d, 0x910a, + 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, + 0x910a, 0x910a, 0x080c, 0x0dc5, 0x080c, 0xaa59, 0x6114, 0x2148, + 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, + 0x080c, 0x6dd1, 0x080c, 0xb101, 0x0005, 0x0461, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x0013, 0x009e, 0x0005, - 0x9250, 0x9250, 0x9250, 0x9252, 0x9263, 0x9250, 0x9250, 0x9250, - 0x9250, 0x9250, 0x9250, 0x9250, 0x9250, 0x9250, 0x9250, 0x9250, - 0x080c, 0x0dc5, 0x080c, 0xac2b, 0x6114, 0x2148, 0xa87b, 0x0006, - 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6e9f, - 0x080c, 0xb2d3, 0x0005, 0x0461, 0x0005, 0x6000, 0x908a, 0x0010, - 0x1a0c, 0x0dc5, 0x0096, 0x0013, 0x009e, 0x0005, 0x927e, 0x927e, - 0x927e, 0x9280, 0x9290, 0x927e, 0x927e, 0x927e, 0x927e, 0x927e, - 0x927e, 0x927e, 0x927e, 0x927e, 0x927e, 0x927e, 0x080c, 0x0dc5, - 0x0036, 0x00e6, 0x2071, 0x19e8, 0x703c, 0x9c06, 0x1120, 0x2019, - 0x0000, 0x080c, 0xaa49, 0x080c, 0xac2b, 0x00ee, 0x003e, 0x0005, - 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, 0x6014, - 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x9067, - 0x00be, 0x2071, 0x193d, 0x080c, 0x8cb1, 0x0160, 0x2001, 0x187f, - 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8c28, 0x00ee, - 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, 0x080c, - 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8c61, 0x0c80, 0x2001, - 0x1925, 0x200c, 0x918e, 0x0000, 0x190c, 0x8d17, 0x05c8, 0x00e6, - 0x2071, 0x1924, 0x7110, 0xc1c5, 0x7112, 0x080c, 0x8d21, 0x00f6, - 0x00c6, 0x2071, 0x1000, 0x00b6, 0x2e04, 0x905d, 0x0138, 0xb8ac, - 0x9065, 0x0120, 0x080c, 0x8cf7, 0x090c, 0x9096, 0x8e70, 0x9e86, - 0x1800, 0x1d90, 0x00be, 0x00d6, 0x0096, 0x0046, 0x2061, 0x1cd0, - 0x2001, 0x181a, 0x2024, 0x6020, 0x9086, 0x0000, 0x1191, 0x9ce0, - 0x0018, 0x2400, 0x9c06, 0x1db8, 0x004e, 0x009e, 0x00de, 0x00d1, - 0x00ce, 0x00fe, 0x2071, 0x1924, 0x7110, 0xc1c4, 0x7112, 0x00ee, - 0x0005, 0x6020, 0x9086, 0x0009, 0x1160, 0x6100, 0x9186, 0x0004, - 0x1138, 0x6110, 0x81ff, 0x190c, 0x0dc5, 0x2c00, 0x080c, 0x8ce2, - 0x9006, 0x0005, 0x2071, 0x193f, 0x2073, 0x0000, 0x8e70, 0x9e86, - 0x1947, 0x1dd0, 0x2071, 0x193d, 0x7006, 0x7002, 0x2001, 0x1930, - 0x2064, 0x8cff, 0x0130, 0x6120, 0x918e, 0x0000, 0x190c, 0x0dc5, - 0x2102, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0148, 0x0096, 0x2148, - 0x080c, 0x1040, 0x009e, 0x2001, 0x188a, 0x2003, 0x0000, 0x2071, - 0x1931, 0x080c, 0x8f00, 0x0804, 0x8f0f, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x187a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126, 0x2091, 0x8000, - 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004, 0x2019, 0x0100, - 0x231c, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e, 0x0020, 0x80f6, - 0x3e00, 0x81f6, 0x3e08, 0x1208, 0x9200, 0x1f04, 0x9356, 0x93a6, - 0x0008, 0x1118, 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, - 0x3e08, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, - 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x0510, 0x911a, 0x1600, - 0x8213, 0x2039, 0x0100, 0x273c, 0x97be, 0x0008, 0x1110, 0x818d, - 0x0010, 0x81f5, 0x3e08, 0x0228, 0x911a, 0x1220, 0x1f04, 0x9380, - 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x9380, 0x0006, 0x3200, - 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, - 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, - 0x2079, 0x19e8, 0x012e, 0x00d6, 0x2069, 0x19e8, 0x6803, 0x0005, - 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, - 0xaf8e, 0x0401, 0x080c, 0xaf79, 0x00e9, 0x080c, 0xaf7c, 0x00d1, - 0x080c, 0xaf7f, 0x00b9, 0x080c, 0xaf82, 0x00a1, 0x080c, 0xaf85, - 0x0089, 0x080c, 0xaf88, 0x0071, 0x080c, 0xaf8b, 0x0059, 0x01de, - 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, 0x206a, - 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, - 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, 0x0007, - 0x0002, 0x93f3, 0x9417, 0x9458, 0x93f9, 0x9417, 0x93f3, 0x93f1, - 0x93f1, 0x080c, 0x0dc5, 0x080c, 0x88c3, 0x080c, 0x9ab1, 0x00ce, - 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x5f97, - 0x080c, 0x883d, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, 0x782a, - 0x080c, 0x5fd7, 0x0c88, 0x62c0, 0x080c, 0xb0ca, 0x080c, 0x5f97, - 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, 0x080c, - 0x88c3, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, 0x0000, - 0x7824, 0x9065, 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb352, - 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0dc5, 0x7828, - 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x2bce, - 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0dc5, - 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x9ab1, 0x0c00, - 0x080c, 0xa6c5, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0xb0ca, - 0x080c, 0xf094, 0x2009, 0x0014, 0x080c, 0xb352, 0x00ce, 0x0880, - 0x2001, 0x1a04, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, - 0x0000, 0x7824, 0x9065, 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, - 0xb3a4, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005, - 0x090c, 0x0dc5, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a, - 0x00de, 0x00ce, 0x00be, 0x080c, 0x2bce, 0x02f0, 0x00b6, 0x00c6, - 0x00d6, 0x781c, 0x905d, 0x090c, 0x0dc5, 0xb800, 0xc0dc, 0xb802, - 0x7924, 0x2160, 0x080c, 0xb2d3, 0xb93c, 0x81ff, 0x090c, 0x0dc5, - 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, - 0x00be, 0x080c, 0x9ab1, 0x0868, 0x080c, 0xa6c5, 0x0850, 0x2011, - 0x0130, 0x2214, 0x080c, 0xb0ca, 0x080c, 0xf094, 0x7824, 0x9065, - 0x2009, 0x0014, 0x080c, 0xb352, 0x00de, 0x00ce, 0x00be, 0x0804, - 0x9469, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1eeb, - 0x6024, 0x6027, 0x0002, 0xd0f4, 0x15b8, 0x62c8, 0x60c4, 0x9205, - 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0xb352, - 0x00ce, 0x0005, 0x2011, 0x1a07, 0x2013, 0x0000, 0x0cc8, 0x793c, - 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x1628, 0x8108, 0x7946, - 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, - 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10, 0x793c, 0x9188, - 0x0008, 0x210c, 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, - 0x9085, 0x0016, 0x6016, 0x08a0, 0x793c, 0x2160, 0x2009, 0x004a, - 0x080c, 0xb352, 0x0868, 0x7848, 0xc085, 0x784a, 0x0848, 0x0006, - 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, - 0x2061, 0x19e8, 0x6020, 0x8000, 0x6022, 0x6010, 0x9005, 0x0148, - 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, - 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x19e8, 0xb800, - 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086, 0x0001, 0x1110, - 0x2b00, 0x681e, 0x00de, 0x0804, 0x9ab1, 0x00de, 0x0005, 0xc0d5, - 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b, 0x0000, 0x0086, - 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e, 0x2069, 0x19e8, - 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e, 0x08d8, 0x0006, - 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, - 0x2061, 0x19e8, 0x6020, 0x8000, 0x6022, 0x6008, 0x9005, 0x0148, - 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, - 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, - 0x2061, 0x19e8, 0x6034, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, - 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce, 0x0005, 0x00f6, - 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, - 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e8, - 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x95f3, - 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x95ee, 0x87ff, 0x0120, - 0x6054, 0x9106, 0x1904, 0x95ee, 0x703c, 0x9c06, 0x1178, 0x0036, - 0x2019, 0x0001, 0x080c, 0xaa49, 0x7033, 0x0000, 0x9006, 0x703e, - 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001, 0x7038, 0x9c36, - 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, - 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, - 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, - 0x080c, 0xd0d8, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, - 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0xac1b, 0xa867, 0x0103, - 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xd3ce, - 0x080c, 0xef85, 0x080c, 0x6e9f, 0x007e, 0x003e, 0x001e, 0x080c, - 0xd2c3, 0x080c, 0xb306, 0x00ce, 0x0804, 0x958d, 0x2c78, 0x600c, - 0x2060, 0x0804, 0x958d, 0x85ff, 0x0120, 0x0036, 0x080c, 0x9bd3, - 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e, - 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, - 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, - 0xef85, 0x080c, 0xebd4, 0x007e, 0x003e, 0x001e, 0x0890, 0x6020, - 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, 0x0076, - 0x080c, 0x6e9f, 0x080c, 0xb2d3, 0x007e, 0x003e, 0x001e, 0x0818, - 0x6020, 0x9086, 0x000a, 0x0904, 0x95d8, 0x0804, 0x95d1, 0x0006, - 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, - 0x8000, 0x2079, 0x19e8, 0x7838, 0x9065, 0x0904, 0x9684, 0x600c, - 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019, - 0x0001, 0x080c, 0xaa49, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42, - 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xd0d8, 0x0548, 0x6014, 0x2048, - 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, 0x1188, - 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1988, 0x2004, 0x6042, - 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0xac1b, 0xa867, 0x0103, - 0xab7a, 0xa877, 0x0000, 0x080c, 0x6e92, 0x080c, 0xd2c3, 0x080c, - 0xb306, 0x000e, 0x0804, 0x963c, 0x7e3a, 0x7e36, 0x012e, 0x00fe, - 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, - 0x0006, 0x1118, 0x080c, 0xebd4, 0x0c50, 0x6020, 0x9086, 0x0009, - 0x1130, 0xab7a, 0x080c, 0x6e9f, 0x080c, 0xb2d3, 0x0c10, 0x6020, - 0x9086, 0x000a, 0x09a8, 0x0868, 0x0016, 0x0026, 0x0086, 0x9046, - 0x0099, 0x080c, 0x978f, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, - 0x0126, 0x2079, 0x19e8, 0x2091, 0x8000, 0x080c, 0x9826, 0x080c, - 0x98b6, 0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, - 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, - 0x2071, 0x19e8, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9754, - 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x974f, 0x88ff, 0x0120, - 0x6054, 0x9106, 0x1904, 0x974f, 0x7024, 0x9c06, 0x1568, 0x2069, - 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88c3, - 0x080c, 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7027, 0x0000, - 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, - 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, - 0x0009, 0x630a, 0x0804, 0x974f, 0x7014, 0x9c36, 0x1110, 0x660c, - 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, - 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, - 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, - 0x080c, 0xd0d8, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, - 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0098, 0xa867, 0x0103, 0xab7a, - 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xd3ce, 0x080c, - 0xef85, 0x080c, 0x6e9f, 0x008e, 0x003e, 0x001e, 0x080c, 0xd2c3, - 0x080c, 0xb306, 0x080c, 0xaaf1, 0x00ce, 0x0804, 0x96cd, 0x2c78, - 0x600c, 0x2060, 0x0804, 0x96cd, 0x012e, 0x000e, 0x001e, 0x006e, - 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, - 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xef85, - 0x080c, 0xebd4, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xbcb6, - 0x6020, 0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, - 0x000e, 0x0904, 0x9735, 0x9086, 0x008b, 0x0904, 0x9735, 0x0840, - 0x6020, 0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, - 0x000e, 0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x9748, 0x00b6, - 0x00a6, 0x0096, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, - 0x1000, 0x2004, 0x905d, 0x0904, 0x981f, 0x00f6, 0x00e6, 0x00d6, - 0x0066, 0x2071, 0x19e8, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, - 0x701c, 0x9b06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, - 0x761e, 0xb858, 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, - 0x2900, 0xb05a, 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, - 0xc0dc, 0xb802, 0x080c, 0x664c, 0x0904, 0x981b, 0x7624, 0x86ff, - 0x0904, 0x980a, 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, - 0x2069, 0x0100, 0x68c0, 0x9005, 0x0560, 0x080c, 0x88c3, 0x080c, - 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7027, 0x0000, 0x0036, - 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, - 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, 0x6824, - 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, - 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xb306, 0x00ce, + 0x9138, 0x9138, 0x9138, 0x913a, 0x914a, 0x9138, 0x9138, 0x9138, + 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, + 0x080c, 0x0dc5, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06, + 0x1120, 0x2019, 0x0000, 0x080c, 0xa877, 0x080c, 0xaa59, 0x00ee, + 0x003e, 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, + 0x0000, 0x6014, 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, + 0x080c, 0x8f31, 0x00be, 0x2071, 0x193e, 0x080c, 0x8b7d, 0x0160, + 0x2001, 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, + 0x8af4, 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, + 0x2048, 0x080c, 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8b2d, + 0x0c80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x187a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, + 0x9006, 0x8004, 0x2019, 0x0100, 0x231c, 0x93a6, 0x0008, 0x1118, + 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x1208, + 0x9200, 0x1f04, 0x9192, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e, + 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x004e, 0x003e, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, + 0x9005, 0x0510, 0x911a, 0x1600, 0x8213, 0x2039, 0x0100, 0x273c, + 0x97be, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x0228, + 0x911a, 0x1220, 0x1f04, 0x91bc, 0x0028, 0x911a, 0x2308, 0x8210, + 0x1f04, 0x91bc, 0x0006, 0x3200, 0x9084, 0xefff, 0x2080, 0x000e, + 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200, 0x9085, 0x1000, + 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9, 0x012e, 0x00d6, + 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, + 0x0000, 0x2069, 0x0200, 0x080c, 0xadbc, 0x0401, 0x080c, 0xada7, + 0x00e9, 0x080c, 0xadaa, 0x00d1, 0x080c, 0xadad, 0x00b9, 0x080c, + 0xadb0, 0x00a1, 0x080c, 0xadb3, 0x0089, 0x080c, 0xadb6, 0x0071, + 0x080c, 0xadb9, 0x0059, 0x01de, 0x014e, 0x015e, 0x2069, 0x0004, + 0x2d04, 0x9085, 0x8001, 0x206a, 0x00de, 0x0005, 0x20a9, 0x0020, + 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005, 0x00c6, 0x6027, + 0x0001, 0x7804, 0x9084, 0x0007, 0x0002, 0x922f, 0x9253, 0x9294, + 0x9235, 0x9253, 0x922f, 0x922d, 0x922d, 0x080c, 0x0dc5, 0x080c, + 0x878f, 0x080c, 0x98ed, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, + 0x00ce, 0x0005, 0x2011, 0x5f90, 0x080c, 0x8709, 0x7828, 0x9092, + 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, 0x5fd0, 0x0c88, 0x62c0, + 0x080c, 0xaef8, 0x080c, 0x5f90, 0x7807, 0x0003, 0x7827, 0x0000, + 0x782b, 0x0000, 0x0c28, 0x080c, 0x878f, 0x6220, 0xd2a4, 0x0170, + 0xd2cc, 0x0160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0dc5, + 0x2009, 0x0013, 0x080c, 0xb180, 0x00ce, 0x0005, 0x00c6, 0x7824, + 0x9065, 0x090c, 0x0dc5, 0x7828, 0x9092, 0xc350, 0x12c0, 0x8000, + 0x782a, 0x00ce, 0x080c, 0x2be7, 0x0278, 0x00c6, 0x7924, 0x2160, + 0x6010, 0x906d, 0x090c, 0x0dc5, 0x7807, 0x0000, 0x7827, 0x0000, + 0x00ce, 0x080c, 0x98ed, 0x0c00, 0x080c, 0xa4f3, 0x08e8, 0x2011, + 0x0130, 0x2214, 0x080c, 0xaef8, 0x080c, 0xee0f, 0x2009, 0x0014, + 0x080c, 0xb180, 0x00ce, 0x0880, 0x2001, 0x1a05, 0x2003, 0x0000, + 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, + 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb1d2, 0x00ce, 0x0005, 0x00b6, + 0x00c6, 0x00d6, 0x7824, 0x9005, 0x090c, 0x0dc5, 0x7828, 0x9092, + 0xc350, 0x1648, 0x8000, 0x782a, 0x00de, 0x00ce, 0x00be, 0x080c, + 0x2be7, 0x02f0, 0x00b6, 0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c, + 0x0dc5, 0xb800, 0xc0dc, 0xb802, 0x7924, 0x2160, 0x080c, 0xb101, + 0xb93c, 0x81ff, 0x090c, 0x0dc5, 0x8109, 0xb93e, 0x7807, 0x0000, + 0x7827, 0x0000, 0x00de, 0x00ce, 0x00be, 0x080c, 0x98ed, 0x0868, + 0x080c, 0xa4f3, 0x0850, 0x2011, 0x0130, 0x2214, 0x080c, 0xaef8, + 0x080c, 0xee0f, 0x7824, 0x9065, 0x2009, 0x0014, 0x080c, 0xb180, + 0x00de, 0x00ce, 0x00be, 0x0804, 0x92a5, 0x00c6, 0x2001, 0x009b, + 0x2004, 0xd0fc, 0x190c, 0x1f14, 0x6024, 0x6027, 0x0002, 0xd0f4, + 0x15b8, 0x62c8, 0x60c4, 0x9205, 0x1170, 0x783c, 0x9065, 0x0130, + 0x2009, 0x0049, 0x080c, 0xb180, 0x00ce, 0x0005, 0x2011, 0x1a08, + 0x2013, 0x0000, 0x0cc8, 0x793c, 0x81ff, 0x0dc0, 0x7944, 0x9192, + 0x7530, 0x1628, 0x8108, 0x7946, 0x793c, 0x9188, 0x0008, 0x210c, + 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984, 0x9085, 0x0012, + 0x6016, 0x0c10, 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0009, + 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, 0x6016, 0x08a0, + 0x793c, 0x2160, 0x2009, 0x004a, 0x080c, 0xb180, 0x0868, 0x7848, + 0xc085, 0x784a, 0x0848, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6020, 0x8000, + 0x6022, 0x6010, 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, + 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, + 0x00d6, 0x2069, 0x19e9, 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, + 0x6822, 0x9086, 0x0001, 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, + 0x98ed, 0x00de, 0x0005, 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, + 0xb856, 0xb85b, 0x0000, 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, + 0xa05a, 0x008e, 0x2069, 0x19e9, 0x0c08, 0xb856, 0xb85a, 0x2b00, + 0x681a, 0x681e, 0x08d8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6020, 0x8000, + 0x6022, 0x6008, 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, + 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, + 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6034, 0x9005, + 0x0130, 0x9080, 0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, + 0x6136, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, + 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, + 0x0126, 0x902e, 0x2071, 0x19e9, 0x7638, 0x2660, 0x2678, 0x2091, + 0x8000, 0x8cff, 0x0904, 0x942f, 0x6010, 0x2058, 0xb8a0, 0x9206, + 0x1904, 0x942a, 0x87ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x942a, + 0x703c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0xa877, + 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, + 0x2029, 0x0001, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, + 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, + 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce56, 0x01f0, 0x6014, + 0x2048, 0x6020, 0x9086, 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, + 0x090c, 0xaa49, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, + 0x0036, 0x0076, 0x080c, 0xd14c, 0x080c, 0xed00, 0x080c, 0x6dd1, + 0x007e, 0x003e, 0x001e, 0x080c, 0xd041, 0x080c, 0xb134, 0x00ce, + 0x0804, 0x93c9, 0x2c78, 0x600c, 0x2060, 0x0804, 0x93c9, 0x85ff, + 0x0120, 0x0036, 0x080c, 0x9a0f, 0x003e, 0x012e, 0x000e, 0x001e, + 0x002e, 0x003e, 0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, + 0x0016, 0x0036, 0x0076, 0x080c, 0xed00, 0x080c, 0xe948, 0x007e, + 0x003e, 0x001e, 0x0890, 0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, + 0x0006, 0x0016, 0x0036, 0x0076, 0x080c, 0x6dd1, 0x080c, 0xb101, + 0x007e, 0x003e, 0x001e, 0x0818, 0x6020, 0x9086, 0x000a, 0x0904, + 0x9414, 0x0804, 0x940d, 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, + 0x00f6, 0x9036, 0x0126, 0x2091, 0x8000, 0x2079, 0x19e9, 0x7838, + 0x9065, 0x0904, 0x94c0, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c, + 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, 0xa877, 0x7833, + 0x0000, 0x901e, 0x7b3e, 0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, + 0xce56, 0x0548, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1590, + 0x3e08, 0x918e, 0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6040, 0x9005, 0x11a8, + 0x2001, 0x1989, 0x2004, 0x6042, 0x0080, 0x6004, 0x9086, 0x0040, + 0x090c, 0xaa49, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, + 0x6dc4, 0x080c, 0xd041, 0x080c, 0xb134, 0x000e, 0x0804, 0x9478, + 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, + 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xe948, + 0x0c50, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, 0x6dd1, + 0x080c, 0xb101, 0x0c10, 0x6020, 0x9086, 0x000a, 0x09a8, 0x0868, + 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c, 0x95cb, 0x008e, + 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e9, 0x2091, + 0x8000, 0x080c, 0x9662, 0x080c, 0x96f2, 0x012e, 0x00fe, 0x0005, + 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7614, 0x2660, + 0x2678, 0x8cff, 0x0904, 0x9590, 0x6010, 0x2058, 0xb8a0, 0x9206, + 0x1904, 0x958b, 0x88ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x958b, + 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, + 0xd0cc, 0x1508, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, + 0x080c, 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, + 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x0804, 0x958b, + 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, + 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, + 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, + 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce56, 0x01e8, 0x6020, + 0x9086, 0x0003, 0x1580, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, + 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, + 0x0086, 0x080c, 0xd14c, 0x080c, 0xed00, 0x080c, 0x6dd1, 0x008e, + 0x003e, 0x001e, 0x080c, 0xd041, 0x080c, 0xb134, 0x080c, 0xa91f, + 0x00ce, 0x0804, 0x9509, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9509, + 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, + 0x0036, 0x0086, 0x080c, 0xed00, 0x080c, 0xe948, 0x008e, 0x003e, + 0x001e, 0x08d0, 0x080c, 0xbae2, 0x6020, 0x9086, 0x0002, 0x1160, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x9571, 0x9086, + 0x008b, 0x0904, 0x9571, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, 0x008b, + 0x09b0, 0x0804, 0x9584, 0x00b6, 0x00a6, 0x0096, 0x00c6, 0x0006, + 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, 0x905d, 0x0904, + 0x965b, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, 0x19e9, 0xbe54, + 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06, 0x1130, 0x86ff, + 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858, 0x904d, 0x0108, + 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a, 0xb857, 0x0000, + 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x6645, + 0x0904, 0x9657, 0x7624, 0x86ff, 0x0904, 0x9646, 0x9680, 0x0005, + 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005, + 0x0560, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, 0x080c, + 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, + 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, + 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, + 0x2660, 0x080c, 0xb134, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, + 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x95fe, 0x89ff, 0x0158, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd14c, 0x080c, + 0xed00, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x0804, 0x95fe, 0x006e, + 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x009e, 0x00ae, + 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036, + 0x7814, 0x9065, 0x0904, 0x96c5, 0x600c, 0x0006, 0x600f, 0x0000, + 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, + 0xd0cc, 0x1508, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, + 0x080c, 0xaa49, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, + 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x0040, 0x080c, 0x6a2a, 0x1520, 0x6003, 0x0009, + 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xce54, 0x01b0, + 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xd05e, 0x1118, 0x080c, + 0xbae2, 0x0060, 0x080c, 0x6a2a, 0x1168, 0xa867, 0x0103, 0xab7a, + 0xa877, 0x0000, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x080c, 0xb134, + 0x080c, 0xa91f, 0x000e, 0x0804, 0x9669, 0x7e16, 0x7e12, 0x00de, + 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, + 0x1118, 0x080c, 0xe948, 0x0c50, 0x080c, 0xbae2, 0x6020, 0x9086, + 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0990, + 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005, 0x19b0, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086, 0x008b, + 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6, 0x00c6, 0x00d6, + 0x7818, 0x905d, 0x0904, 0x9772, 0xb854, 0x0006, 0x9006, 0xb856, + 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x6645, 0x0904, + 0x976f, 0x7e24, 0x86ff, 0x0904, 0x9762, 0x9680, 0x0005, 0x2004, + 0x9906, 0x1904, 0x9762, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005, + 0x0904, 0x9759, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, + 0x080c, 0xaa49, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, + 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e, 0x0002, 0x1168, + 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c, 0x81ff, 0x1518, + 0x2009, 0x1989, 0x210c, 0x2102, 0x00f0, 0xb83c, 0x9005, 0x0110, + 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c, 0xb134, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, - 0x0804, 0x97c2, 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, - 0x0000, 0x080c, 0xd3ce, 0x080c, 0xef85, 0x080c, 0x6e9f, 0x080c, - 0xaaf1, 0x0804, 0x97c2, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, - 0x000e, 0x00ce, 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, - 0x0066, 0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x9889, - 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, - 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88c3, - 0x080c, 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7827, 0x0000, - 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, - 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, - 0x6a3b, 0x1520, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, - 0x2048, 0x080c, 0xd0d6, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, - 0x080c, 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0060, 0x080c, 0x6a3b, - 0x1168, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6e9f, - 0x080c, 0xd2c3, 0x080c, 0xb306, 0x080c, 0xaaf1, 0x000e, 0x0804, - 0x982d, 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, - 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xebd4, 0x0c50, - 0x080c, 0xbcb6, 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, - 0x9086, 0x0085, 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, - 0x6020, 0x9086, 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, - 0x000e, 0x0d18, 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, - 0x0096, 0x00b6, 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x9936, - 0xb854, 0x0006, 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, - 0xb802, 0x080c, 0x664c, 0x0904, 0x9933, 0x7e24, 0x86ff, 0x0904, - 0x9926, 0x9680, 0x0005, 0x2004, 0x9906, 0x1904, 0x9926, 0x00d6, - 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x991d, 0x080c, 0x88c3, - 0x080c, 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7827, 0x0000, - 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, - 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, - 0x3e08, 0x918e, 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, - 0x0010, 0x200c, 0x81ff, 0x1518, 0x2009, 0x1988, 0x210c, 0x2102, - 0x00f0, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, - 0x0000, 0x080c, 0xb306, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, - 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x98c9, 0x89ff, 0x0138, - 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6e9f, 0x080c, - 0xaaf1, 0x0804, 0x98c9, 0x000e, 0x0804, 0x98bd, 0x781e, 0x781a, - 0x00de, 0x00ce, 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, - 0x00d6, 0x0096, 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, - 0x0188, 0xa878, 0x9606, 0x1170, 0x2071, 0x19e8, 0x7024, 0x9035, - 0x0148, 0x9080, 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, - 0xb802, 0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, - 0x2079, 0x0100, 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, - 0x0009, 0x630a, 0x00ce, 0x04b8, 0x080c, 0xa6e9, 0x78c3, 0x0000, - 0x080c, 0xac1b, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, - 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d39, 0x9006, - 0x080c, 0x2d39, 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, - 0x0001, 0x080c, 0xac1b, 0x003e, 0x080c, 0x664c, 0x00c6, 0xb83c, - 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xb2d3, 0x00ce, - 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd3ce, 0x080c, - 0x6e9f, 0x080c, 0xaaf1, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, - 0x2011, 0x0101, 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, - 0xc2e4, 0x2202, 0x2071, 0x19e8, 0x7004, 0x9084, 0x0007, 0x0002, - 0x99c2, 0x99c6, 0x99e4, 0x9a0d, 0x9a4b, 0x99c2, 0x99dd, 0x99c0, - 0x080c, 0x0dc5, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, - 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, - 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, - 0x00be, 0x0005, 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, - 0x0000, 0x7020, 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x664c, - 0xb800, 0xc0dc, 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, - 0x8001, 0x7022, 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, - 0x00ce, 0x00ee, 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, - 0x080c, 0x9ab1, 0x0ca8, 0x7218, 0x721e, 0x080c, 0x9ab1, 0x0c80, - 0xc2ec, 0x2202, 0x080c, 0x9bd3, 0x0c58, 0x7024, 0x9065, 0x05b8, - 0x700c, 0x9c06, 0x1160, 0x080c, 0xaaf1, 0x600c, 0x9015, 0x0120, - 0x720e, 0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, - 0x9c06, 0x1160, 0x080c, 0xaaf1, 0x600c, 0x9015, 0x0120, 0x7216, - 0x600f, 0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, - 0x0003, 0x1198, 0x6010, 0x2058, 0x080c, 0x664c, 0xb800, 0xc0dc, - 0xb802, 0x080c, 0xaaf1, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, - 0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, - 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0xaaf1, - 0x600c, 0x9015, 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0xac1b, - 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, - 0x0ca8, 0x00d6, 0x2069, 0x19e8, 0x6830, 0x9084, 0x0003, 0x0002, - 0x9a6e, 0x9a70, 0x9a94, 0x9a6c, 0x080c, 0x0dc5, 0x00de, 0x0005, - 0x00c6, 0x6840, 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, - 0x600c, 0x9015, 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, - 0x683f, 0x0000, 0x2011, 0x1a07, 0x2013, 0x0000, 0x00ce, 0x00de, - 0x0005, 0x683a, 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, - 0x0d68, 0x6003, 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, - 0x684a, 0x683c, 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, - 0x600f, 0x0000, 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, - 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, - 0x0005, 0x2001, 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, - 0x080c, 0x9bd3, 0x2001, 0x19f4, 0x2004, 0x9086, 0x0001, 0x0d58, - 0x00d6, 0x2069, 0x19e8, 0x6804, 0x9084, 0x0007, 0x0006, 0x9005, - 0x11c8, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1198, 0x2001, - 0x197c, 0x2004, 0x9086, 0xaaaa, 0x0168, 0x2001, 0x188b, 0x2004, - 0xd08c, 0x1118, 0xd084, 0x1118, 0x0028, 0x080c, 0x9bd3, 0x000e, - 0x00de, 0x0005, 0x000e, 0x0002, 0x9aee, 0x9ba7, 0x9ba7, 0x9ba7, - 0x9ba7, 0x9ba9, 0x9ba7, 0x9aec, 0x080c, 0x0dc5, 0x6820, 0x9005, - 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, 0x01f0, 0x6104, - 0x918e, 0x0040, 0x1180, 0x2009, 0x1837, 0x210c, 0x918c, 0x0028, - 0x1150, 0x080c, 0x7637, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, - 0xc095, 0x200a, 0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, - 0x080c, 0x9c7c, 0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, - 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x9c7c, 0x00ce, - 0x00de, 0x0005, 0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, - 0x9b91, 0xb84c, 0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, - 0x905d, 0x0120, 0x920e, 0x0904, 0x9b91, 0x0028, 0x6818, 0x920e, - 0x0904, 0x9b91, 0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, - 0x1d70, 0x2b00, 0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, - 0xb2aa, 0x0904, 0x9b91, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, - 0x0096, 0x2148, 0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, - 0xa884, 0x009e, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, - 0x801b, 0x831b, 0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, - 0x009e, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, - 0x2061, 0x0100, 0xbac0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, - 0x080c, 0xa219, 0x2069, 0x19e8, 0xbb00, 0xc3dd, 0xbb02, 0x6807, - 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, - 0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, - 0x0005, 0x00ee, 0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, - 0x6b26, 0x6820, 0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x664c, - 0x080c, 0xb0ea, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, - 0x0005, 0x00c6, 0x680c, 0x9065, 0x01d8, 0x6104, 0x918e, 0x0040, - 0x1180, 0x2009, 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, - 0x7637, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a, - 0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9c7c, - 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed, 0x2202, - 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x19e8, 0x6830, - 0x9086, 0x0000, 0x1570, 0x2001, 0x180c, 0x2014, 0xd2e4, 0x0130, - 0xc2e4, 0x2202, 0x080c, 0x9ac0, 0x2069, 0x19e8, 0x2001, 0x180c, - 0x200c, 0xd1c4, 0x1508, 0x6838, 0x907d, 0x01d8, 0x6a04, 0x9296, - 0x0000, 0x1904, 0x9c70, 0x7920, 0x918e, 0x0009, 0x0568, 0x6833, - 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, - 0x2091, 0x2400, 0x002e, 0x080c, 0x1c79, 0x1158, 0x012e, 0x080c, - 0xa546, 0x00de, 0x00fe, 0x0005, 0xc1c4, 0x2102, 0x080c, 0x76e4, - 0x08d0, 0x012e, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0x9015, - 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, - 0x0c40, 0x683a, 0x6836, 0x0cc0, 0x7908, 0xd1fc, 0x1198, 0x6833, - 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, - 0x2091, 0x2400, 0x002e, 0x080c, 0x1c79, 0x19d8, 0x012e, 0x080c, - 0xa4c7, 0x0878, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1188, - 0x2001, 0x197c, 0x2004, 0x9086, 0xaaaa, 0x0158, 0x2001, 0x19e9, - 0x2004, 0x9005, 0x11f0, 0x2001, 0x188b, 0x200c, 0xc185, 0xc18c, - 0x2102, 0x2f00, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, - 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c79, - 0x1904, 0x9c11, 0x012e, 0x6a3c, 0x2278, 0x080c, 0xa451, 0x0804, - 0x9c09, 0x2011, 0x188b, 0x2204, 0xc08d, 0x2012, 0x0804, 0x9c09, - 0x6a04, 0x9296, 0x0006, 0x1904, 0x9bcb, 0x6a30, 0x9296, 0x0000, - 0x0904, 0x9bf3, 0x0804, 0x9bcb, 0x6020, 0x9084, 0x000f, 0x000b, - 0x0005, 0x9c90, 0x9c95, 0xa149, 0xa1e2, 0x9c95, 0xa149, 0xa1e2, - 0x9c90, 0x9c95, 0x9c90, 0x9c90, 0x9c90, 0x9c90, 0x9c90, 0x9c90, - 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0005, 0x00b6, 0x0156, 0x0136, - 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, - 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dc5, - 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, - 0x0040, 0x1a04, 0x9d01, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, - 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9eaa, - 0x9ee5, 0x9f0e, 0x9fd8, 0x9ffa, 0xa000, 0xa00d, 0xa015, 0xa021, - 0xa027, 0xa038, 0xa027, 0xa090, 0xa015, 0xa09c, 0xa0a2, 0xa021, - 0xa0a2, 0xa0ae, 0x9cff, 0x9cff, 0x9cff, 0x9cff, 0x9cff, 0x9cff, - 0x9cff, 0x9cff, 0x9cff, 0x9cff, 0x9cff, 0xa900, 0xa923, 0xa934, - 0xa954, 0xa986, 0xa00d, 0x9cff, 0xa00d, 0xa027, 0x9cff, 0x9f0e, - 0x9fd8, 0x9cff, 0xad12, 0xa027, 0x9cff, 0xad2e, 0xa027, 0x9cff, - 0xa021, 0x9ea4, 0x9d22, 0x9cff, 0xad4a, 0xadb7, 0xae92, 0x9cff, - 0xae9f, 0xa00a, 0xaeca, 0x9cff, 0xa990, 0xaef7, 0x9cff, 0x080c, - 0x0dc5, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, - 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xaf92, 0xb044, - 0x9d20, 0x9d5a, 0x9e06, 0x9e11, 0x9d20, 0xa00d, 0x9d20, 0x9e6b, - 0x9e77, 0x9d75, 0x9d20, 0x9d90, 0x9dc4, 0xb1b1, 0xb1f6, 0xa027, - 0x080c, 0x0dc5, 0x00d6, 0x0096, 0x080c, 0xa0c1, 0x0026, 0x0036, - 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, - 0x0018, 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, - 0x2019, 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, - 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0xa6bd, 0x003e, - 0x002e, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, - 0x00be, 0x080c, 0xb23d, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, - 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0xa0c1, 0x7003, 0x0500, - 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, - 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, - 0x080c, 0xa6bd, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, - 0xa0c1, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, - 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, - 0x701e, 0x60c3, 0x0010, 0x080c, 0xa6bd, 0x009e, 0x00de, 0x0005, - 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0xa0c1, 0x20e9, - 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, - 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016, 0x200c, 0x2001, 0x0001, - 0x080c, 0x23ee, 0x080c, 0xde7c, 0x9006, 0x080c, 0x23ee, 0x001e, - 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa6bd, - 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, - 0x8000, 0x080c, 0xa10c, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, - 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, - 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016, 0x200c, 0x080c, 0xde7c, - 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, - 0x2048, 0x080c, 0x0fc0, 0x080c, 0xa6bd, 0x012e, 0x009e, 0x00de, - 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, - 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0xa0c1, - 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, - 0xa6bd, 0x00d6, 0x00e6, 0x080c, 0xa10c, 0x7814, 0x9084, 0xff00, - 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, - 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, - 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, - 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9e31, 0x2069, 0x1801, - 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9e3a, 0x9096, - 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, - 0x2069, 0x19b4, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19ce, 0x20a9, - 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, - 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, - 0x8d68, 0x8e70, 0x1f04, 0x9e51, 0x60c3, 0x004c, 0x080c, 0xa6bd, - 0x00ee, 0x00de, 0x0005, 0x080c, 0xa0c1, 0x7003, 0x6300, 0x7007, - 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x00d6, - 0x0026, 0x0016, 0x080c, 0xa10c, 0x7003, 0x0200, 0x7814, 0x700e, - 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, - 0x1924, 0x6810, 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, - 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, - 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa6bd, - 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, - 0x0804, 0xa6bd, 0x080c, 0xa0c1, 0x7003, 0x5200, 0x2069, 0x1847, - 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x28a6, 0x710e, - 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, - 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, - 0x20a1, 0x0254, 0x4003, 0x080c, 0xb23d, 0x1120, 0xb8a0, 0x9082, - 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, - 0x2004, 0x7036, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, - 0x7036, 0x60c3, 0x001c, 0x0804, 0xa6bd, 0x080c, 0xa0c1, 0x7003, - 0x0500, 0x080c, 0xb23d, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, - 0x2001, 0x181f, 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, - 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, - 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, - 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0xa6bd, 0x080c, 0xa0c1, - 0x9006, 0x080c, 0x6a6d, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2011, - 0x0240, 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, 0x7003, - 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, - 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, - 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9f98, 0x00d6, 0x2069, 0x196c, - 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, - 0x9084, 0x2000, 0x7012, 0x080c, 0xb254, 0x680c, 0x7016, 0x701f, - 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x0428, 0x6800, 0x700a, - 0x6804, 0x700e, 0x2009, 0x180d, 0x210c, 0xd18c, 0x0110, 0x2001, - 0x0002, 0x00f6, 0x2079, 0x0100, 0x080c, 0x7637, 0x1128, 0x78e3, - 0x0000, 0x080c, 0x28e7, 0x78e2, 0x00fe, 0x6808, 0x080c, 0x7637, - 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, - 0xb254, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, - 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, - 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, - 0xaf79, 0x2069, 0x1974, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, - 0x080c, 0x57d9, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04e0, - 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01a8, 0x0016, 0x2001, 0x180d, - 0x2004, 0xd08c, 0x2009, 0x0002, 0x1118, 0x2001, 0x196d, 0x200c, - 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x28e7, - 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196c, 0x20e9, 0x0000, - 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, - 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, - 0x20a1, 0x025a, 0x4003, 0x080c, 0xaf79, 0x20a1, 0x024e, 0x20a9, - 0x0008, 0x2099, 0x1974, 0x4003, 0x60c3, 0x0074, 0x0804, 0xa6bd, - 0x080c, 0xa0c1, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, - 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, + 0x0804, 0x9705, 0x89ff, 0x0138, 0xa867, 0x0103, 0xab7a, 0xa877, + 0x0000, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x0804, 0x9705, 0x000e, + 0x0804, 0x96f9, 0x781e, 0x781a, 0x00de, 0x00ce, 0x00be, 0x009e, + 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066, 0xb800, + 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878, 0x9606, 0x1170, + 0x2071, 0x19e9, 0x7024, 0x9035, 0x0148, 0x9080, 0x0005, 0x2004, + 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029, 0x006e, 0x009e, + 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, 0x78c0, 0x9005, + 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x04b8, + 0x080c, 0xa517, 0x78c3, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000, + 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x2079, 0x0100, + 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0xaa49, 0x003e, + 0x080c, 0x6645, 0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, + 0x2660, 0x080c, 0xb101, 0x00ce, 0xa867, 0x0103, 0xab7a, 0xa877, + 0x0000, 0x080c, 0xd14c, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x00fe, + 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101, 0x2204, 0xc0c4, + 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202, 0x2071, 0x19e9, + 0x7004, 0x9084, 0x0007, 0x0002, 0x97fe, 0x9802, 0x9820, 0x9849, + 0x9887, 0x97fe, 0x9819, 0x97fc, 0x080c, 0x0dc5, 0x00ce, 0x00ee, + 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020, 0x8001, 0x7022, + 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, + 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7216, 0x7212, + 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x9005, 0x0070, + 0x6010, 0x2058, 0x080c, 0x6645, 0xb800, 0xc0dc, 0xb802, 0x7007, + 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022, 0x1148, 0x2001, + 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee, 0x00be, 0x0005, + 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x98ed, 0x0ca8, 0x7218, + 0x721e, 0x080c, 0x98ed, 0x0c80, 0xc2ec, 0x2202, 0x080c, 0x9a0f, + 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06, 0x1160, 0x080c, + 0xa91f, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0448, + 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160, 0x080c, 0xa91f, + 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000, 0x00d0, 0x7216, + 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198, 0x6010, 0x2058, + 0x080c, 0x6645, 0xb800, 0xc0dc, 0xb802, 0x080c, 0xa91f, 0x701c, + 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e, 0x0010, 0x7218, + 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, + 0x9065, 0x0140, 0x080c, 0xa91f, 0x600c, 0x9015, 0x0158, 0x720e, + 0x600f, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000, 0x00ce, 0x00ee, + 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6, 0x2069, 0x19e9, + 0x6830, 0x9084, 0x0003, 0x0002, 0x98aa, 0x98ac, 0x98d0, 0x98a8, + 0x080c, 0x0dc5, 0x00de, 0x0005, 0x00c6, 0x6840, 0x9086, 0x0001, + 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015, 0x0170, 0x6a3a, + 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0x1a08, + 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90, + 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003, 0x0003, 0x0c50, + 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c, 0x9065, 0x0160, + 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, + 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, 0x2001, + 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001, 0x180c, 0x200c, + 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x9a0f, 0x2001, 0x19f5, + 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069, 0x19e9, 0x6804, + 0x9084, 0x0007, 0x0006, 0x9005, 0x11c8, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x1198, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, + 0x0168, 0x2001, 0x188b, 0x2004, 0xd08c, 0x1118, 0xd084, 0x1118, + 0x0028, 0x080c, 0x9a0f, 0x000e, 0x00de, 0x0005, 0x000e, 0x0002, + 0x992a, 0x99e3, 0x99e3, 0x99e3, 0x99e3, 0x99e5, 0x99e3, 0x9928, + 0x080c, 0x0dc5, 0x6820, 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, + 0x680c, 0x9065, 0x01f0, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009, + 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, 0x7569, 0x0138, + 0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807, + 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de, + 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b, + 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de, 0x0005, 0x00b6, 0x00e6, + 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x99cd, 0xb84c, 0x900d, 0x0118, + 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, 0x920e, 0x0904, + 0x99cd, 0x0028, 0x6818, 0x920e, 0x0904, 0x99cd, 0x2058, 0xb84c, + 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, 0x681e, 0xbb3c, + 0xb838, 0x9302, 0x1e40, 0x080c, 0xb0d8, 0x0904, 0x99cd, 0x8318, + 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148, 0xa880, 0x9084, + 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e, 0x908a, 0x199a, + 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, + 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, 0x00ff, 0x918e, + 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100, 0xbac0, 0x629a, + 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0xa047, 0x2069, 0x19e9, + 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, + 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, 0x00fe, + 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee, 0x00be, 0x00ce, + 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820, 0x8001, 0x6822, + 0x682b, 0x0000, 0x080c, 0x6645, 0x080c, 0xaf18, 0x00ee, 0x00be, + 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, + 0x01d8, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009, 0x1837, 0x210c, + 0x918c, 0x0028, 0x1150, 0x080c, 0x7569, 0x0138, 0x0006, 0x2009, + 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807, 0x0004, 0x6826, + 0x682b, 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de, 0x0005, 0x2001, + 0x180c, 0x2014, 0xc2ed, 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, + 0x00d6, 0x2069, 0x19e9, 0x6830, 0x9086, 0x0000, 0x1570, 0x2001, + 0x180c, 0x2014, 0xd2e4, 0x0130, 0xc2e4, 0x2202, 0x080c, 0x98fc, + 0x2069, 0x19e9, 0x2001, 0x180c, 0x200c, 0xd1c4, 0x1508, 0x6838, + 0x907d, 0x01d8, 0x6a04, 0x9296, 0x0000, 0x1904, 0x9aac, 0x7920, + 0x918e, 0x0009, 0x0568, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, + 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, + 0x1ca2, 0x1158, 0x012e, 0x080c, 0xa374, 0x00de, 0x00fe, 0x0005, + 0xc1c4, 0x2102, 0x080c, 0x7616, 0x08d0, 0x012e, 0x6843, 0x0000, + 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f, 0x0000, + 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836, 0x0cc0, + 0x7908, 0xd1fc, 0x1198, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, + 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, + 0x1ca2, 0x19d8, 0x012e, 0x080c, 0xa2f5, 0x0878, 0x2001, 0x1837, + 0x2004, 0x9084, 0x0028, 0x1188, 0x2001, 0x197d, 0x2004, 0x9086, + 0xaaaa, 0x0158, 0x2001, 0x19ea, 0x2004, 0x9005, 0x11f0, 0x2001, + 0x188b, 0x200c, 0xc185, 0xc18c, 0x2102, 0x2f00, 0x6833, 0x0001, + 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, + 0x2400, 0x002e, 0x080c, 0x1ca2, 0x1904, 0x9a4d, 0x012e, 0x6a3c, + 0x2278, 0x080c, 0xa27f, 0x0804, 0x9a45, 0x2011, 0x188b, 0x2204, + 0xc08d, 0x2012, 0x0804, 0x9a45, 0x6a04, 0x9296, 0x0006, 0x1904, + 0x9a07, 0x6a30, 0x9296, 0x0000, 0x0904, 0x9a2f, 0x0804, 0x9a07, + 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x9acc, 0x9ad1, 0x9f77, + 0xa010, 0x9ad1, 0x9f77, 0xa010, 0x9acc, 0x9ad1, 0x9acc, 0x9acc, + 0x9acc, 0x9acc, 0x9acc, 0x9acc, 0x080c, 0x97e1, 0x080c, 0x98ed, + 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, + 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, + 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x6110, 0x2158, 0xb9c0, 0x2c78, + 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x9b3d, 0x005b, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, + 0x015e, 0x00be, 0x0005, 0x9ce6, 0x9d21, 0x9d4a, 0x9e06, 0x9e28, + 0x9e2e, 0x9e3b, 0x9e43, 0x9e4f, 0x9e55, 0x9e66, 0x9e55, 0x9ebe, + 0x9e43, 0x9eca, 0x9ed0, 0x9e4f, 0x9ed0, 0x9edc, 0x9b3b, 0x9b3b, + 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, + 0x9b3b, 0xa72e, 0xa751, 0xa762, 0xa782, 0xa7b4, 0x9e3b, 0x9b3b, + 0x9e3b, 0x9e55, 0x9b3b, 0x9d4a, 0x9e06, 0x9b3b, 0xab40, 0x9e55, + 0x9b3b, 0xab5c, 0x9e55, 0x9b3b, 0x9e4f, 0x9ce0, 0x9b5e, 0x9b3b, + 0xab78, 0xabe5, 0xacc0, 0x9b3b, 0xaccd, 0x9e38, 0xacf8, 0x9b3b, + 0xa7be, 0xad25, 0x9b3b, 0x080c, 0x0dc5, 0x2100, 0x005b, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, + 0x00be, 0x0005, 0xadc0, 0xae72, 0x9b5c, 0x9b96, 0x9c42, 0x9c4d, + 0x9b5c, 0x9e3b, 0x9b5c, 0x9ca7, 0x9cb3, 0x9bb1, 0x9b5c, 0x9bcc, + 0x9c00, 0xafdf, 0xb024, 0x9e55, 0x080c, 0x0dc5, 0x00d6, 0x0096, + 0x080c, 0x9eef, 0x0026, 0x0036, 0x7814, 0x2048, 0xa958, 0xd1cc, + 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, 0x2019, 0x0018, 0x0030, + 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, 0x0014, 0x7102, 0x7206, + 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026, + 0x63c2, 0x080c, 0xa4eb, 0x003e, 0x002e, 0x009e, 0x00de, 0x0005, + 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, 0xb06b, 0x1118, + 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096, + 0x080c, 0x9eef, 0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a, + 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016, 0xa884, 0x701a, + 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa4eb, 0x009e, 0x00de, + 0x0005, 0x00d6, 0x0096, 0x080c, 0x9eef, 0x7003, 0x0500, 0x7814, + 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8, + 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, + 0xa4eb, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, + 0x8000, 0x080c, 0x9eef, 0x20e9, 0x0000, 0x2001, 0x19a5, 0x2003, + 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a5, + 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, 0x2417, 0x080c, 0xdbfa, + 0x9006, 0x080c, 0x2417, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, + 0x0c28, 0x04d9, 0x080c, 0xa4eb, 0x012e, 0x009e, 0x00de, 0x0005, + 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f3a, 0x20e9, + 0x0000, 0x2001, 0x19a5, 0x2003, 0x0000, 0x7814, 0x2048, 0xa86f, + 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a5, + 0x0016, 0x200c, 0x080c, 0xdbfa, 0x001e, 0xa804, 0x9005, 0x0110, + 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, 0x0fc0, 0x080c, + 0xa4eb, 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084, + 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000, + 0x1de0, 0x0005, 0x080c, 0x9eef, 0x7003, 0x7800, 0x7808, 0x8007, + 0x700a, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x00e6, 0x080c, + 0x9f3a, 0x7814, 0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70, + 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, 0x0120, 0x2073, 0x0010, + 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, 0x8e70, 0x2073, 0x0034, + 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, + 0x1f04, 0x9c6d, 0x2069, 0x1801, 0x20a9, 0x0004, 0x2d76, 0x8d68, + 0x8e70, 0x1f04, 0x9c76, 0x9096, 0xdf00, 0x0130, 0x9096, 0xe000, + 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5, 0x9086, 0xdf00, + 0x0110, 0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86, 0x0260, 0x1148, + 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, 0x6012, 0x00ce, 0x2071, + 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70, 0x1f04, 0x9c8d, + 0x60c3, 0x004c, 0x080c, 0xa4eb, 0x00ee, 0x00de, 0x0005, 0x080c, + 0x9eef, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e, 0x60c3, + 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x0026, 0x0016, 0x080c, 0x9f3a, + 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0, 0x0004, 0x2009, + 0x0001, 0x2011, 0x000c, 0x2069, 0x1925, 0x6810, 0xd084, 0x1148, + 0x2073, 0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70, 0x8108, 0x9290, + 0x0004, 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, + 0x710a, 0x62c2, 0x080c, 0xa4eb, 0x001e, 0x002e, 0x00de, 0x0005, + 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, 0xa4eb, 0x080c, 0x9eef, + 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, 0xd084, 0x0130, 0x6828, + 0x0016, 0x080c, 0x28c7, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, + 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, + 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, + 0xb06b, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, + 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, 0x7036, 0x0030, 0x2001, + 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, + 0xa4eb, 0x080c, 0x9eef, 0x7003, 0x0500, 0x080c, 0xb06b, 0x1120, + 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x700a, + 0x2001, 0x1820, 0x2004, 0x700e, 0x0030, 0x2001, 0x1818, 0x2004, + 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, + 0x0804, 0xa4eb, 0x080c, 0x9eef, 0x9006, 0x080c, 0x6a5c, 0xb8a0, + 0x9086, 0x007e, 0x1170, 0x2011, 0x0240, 0x2013, 0x22ff, 0x2011, + 0x0241, 0x2013, 0xfffe, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, + 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, + 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, + 0x9dcd, 0x00d6, 0x2069, 0x196d, 0x2001, 0x1837, 0x2004, 0xd0a4, + 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x080c, + 0xb082, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022, 0x681c, + 0x7026, 0x00f0, 0x6800, 0x700a, 0x6804, 0x700e, 0x00f6, 0x2079, + 0x0100, 0x080c, 0x7569, 0x1128, 0x78e3, 0x0000, 0x080c, 0x2908, + 0x78e2, 0x00fe, 0x6808, 0x080c, 0x7569, 0x1118, 0x9084, 0x37ff, + 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, 0xb082, 0x680c, 0x7016, + 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, + 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, + 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, 0xada7, 0x2069, 0x1975, + 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, 0x080c, 0x57d7, 0xd0e4, + 0x0110, 0x680c, 0x700e, 0x00de, 0x04a8, 0x2001, 0x1837, 0x2004, + 0xd0a4, 0x0170, 0x0016, 0x2001, 0x196e, 0x200c, 0x60e0, 0x9106, + 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x2908, 0x61e2, 0x001e, + 0x20e1, 0x0001, 0x2099, 0x196d, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1, + 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, + 0x4003, 0x080c, 0xada7, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, + 0x1975, 0x4003, 0x60c3, 0x0074, 0x0804, 0xa4eb, 0x080c, 0x9eef, + 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, 0x2000, + 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, + 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, 0x0002, + 0x00d6, 0x0804, 0x9e9f, 0x7026, 0x60c3, 0x0014, 0x0804, 0xa4eb, + 0x080c, 0x9eef, 0x7003, 0x5000, 0x0804, 0x9d6c, 0x080c, 0x9eef, + 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, 0xa4eb, + 0x080c, 0x9f31, 0x0010, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x60c3, + 0x0004, 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0100, 0x700b, + 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c, + 0x9f3a, 0x7003, 0x0200, 0x0804, 0x9d6c, 0x080c, 0x9f3a, 0x7003, + 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, 0x0003, + 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x080c, + 0x9f3a, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, 0xb894, + 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, 0xb998, + 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058, + 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700, + 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, - 0x9085, 0x0002, 0x00d6, 0x0804, 0xa071, 0x7026, 0x60c3, 0x0014, - 0x0804, 0xa6bd, 0x080c, 0xa0c1, 0x7003, 0x5000, 0x0804, 0x9f30, - 0x080c, 0xa0c1, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, - 0x0804, 0xa6bd, 0x080c, 0xa103, 0x0010, 0x080c, 0xa10c, 0x7003, - 0x0200, 0x60c3, 0x0004, 0x0804, 0xa6bd, 0x080c, 0xa10c, 0x7003, - 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, - 0xa6bd, 0x080c, 0xa10c, 0x7003, 0x0200, 0x0804, 0x9f30, 0x080c, - 0xa10c, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, - 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, - 0x00d6, 0x080c, 0xa10c, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, - 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, - 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, - 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, - 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847, - 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, - 0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085, - 0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5, - 0xbacc, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, - 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, - 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0xa6bd, - 0x080c, 0xa10c, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, - 0x60c3, 0x0014, 0x0804, 0xa6bd, 0x080c, 0xa10c, 0x7003, 0x0200, - 0x0804, 0x9eae, 0x080c, 0xa10c, 0x7003, 0x0100, 0x700b, 0x0003, - 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x080c, 0xa10c, - 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0xa6bd, - 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, - 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, - 0x0100, 0x080c, 0xaf8e, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, - 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029, - 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa6ab, 0x721a, 0x9f95, - 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, - 0x0026, 0x080c, 0xaf8e, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, - 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013, - 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, - 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, - 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, - 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xaf8e, 0xb810, 0x9305, - 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, - 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, - 0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, - 0x004e, 0x003e, 0x00de, 0x080c, 0xa6ab, 0x721a, 0x7a08, 0x7222, - 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0xa6ab, - 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, - 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, - 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, - 0x0092, 0x1a0c, 0x0dc5, 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061, - 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x00be, 0x0005, 0xa17a, 0xa189, 0xa194, 0xa178, 0xa178, - 0xa178, 0xa17a, 0xa178, 0xa178, 0xa178, 0xa178, 0xa178, 0xa178, - 0x080c, 0x0dc5, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x2bce, - 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, - 0xa6bd, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, - 0x60c3, 0x000c, 0x0804, 0xa6bd, 0x04a1, 0x7003, 0x0003, 0x7007, - 0x0300, 0x60c3, 0x0004, 0x0804, 0xa6bd, 0x0026, 0x080c, 0xaf8e, - 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, - 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0xa0dc, - 0x0026, 0x080c, 0xaf8e, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, - 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, - 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, - 0xa13e, 0x0026, 0x080c, 0xaf8e, 0xb810, 0x9085, 0x8500, 0x7002, - 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, - 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, - 0x0804, 0xa13e, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, - 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, - 0x0dc5, 0x908a, 0x0054, 0x1a0c, 0x0dc5, 0x7910, 0x2158, 0xb9c0, - 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, - 0x00de, 0x00ce, 0x00be, 0x0005, 0xa219, 0xa2e0, 0xa2b3, 0xa402, - 0xa217, 0xa217, 0xa217, 0xa217, 0xa217, 0xa217, 0xa217, 0xaad8, - 0xaadd, 0xaae2, 0xaae7, 0xa217, 0xaed6, 0xa217, 0xaad3, 0x080c, - 0x0dc5, 0x0096, 0x780b, 0xffff, 0x080c, 0xa284, 0x7914, 0x2148, - 0xa978, 0x7956, 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, - 0xa8b4, 0x7032, 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, - 0x0008, 0x7132, 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005, - 0x0040, 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006, - 0x8004, 0x2010, 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, - 0xd1ac, 0x0158, 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c, - 0x18f7, 0x0010, 0x080c, 0x1768, 0x0050, 0xd1b4, 0x0118, 0x7047, - 0x0001, 0x0028, 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, - 0xaeac, 0x726a, 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, - 0x0200, 0x6813, 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, - 0x6017, 0x0009, 0x2001, 0x1a04, 0x2003, 0x07d0, 0x2001, 0x1a03, - 0x2003, 0x0009, 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, - 0xb8cc, 0xd084, 0x0180, 0x2001, 0x1ad0, 0x200c, 0x8108, 0x2102, - 0x2001, 0x1acf, 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x794a, - 0x712e, 0x7b46, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, - 0xba10, 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, - 0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, - 0x7027, 0xffff, 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, - 0xa890, 0x7002, 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, - 0x60c3, 0x000c, 0x009e, 0x00de, 0x0804, 0xa6bd, 0x6813, 0x0008, - 0xb810, 0x9085, 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, - 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0889, 0x080c, 0xa6ab, - 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, - 0x00d6, 0x0096, 0x080c, 0xa3e0, 0x7814, 0x2048, 0x080c, 0xd0d6, - 0x1130, 0x7814, 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, - 0x001b, 0x009e, 0x00de, 0x0005, 0xa2fe, 0xa367, 0xa377, 0xa39d, - 0xa3a9, 0xa3ba, 0xa3c2, 0xa2fc, 0x080c, 0x0dc5, 0x0016, 0x0036, - 0xa97c, 0x918c, 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, - 0x7824, 0xd0cc, 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, - 0x003e, 0x001e, 0x2001, 0x19b2, 0x2004, 0x60c2, 0x0804, 0xa6bd, - 0xc3e5, 0x0c88, 0x9186, 0x0001, 0x190c, 0x0dc5, 0xaba8, 0x7824, - 0xd0cc, 0x1904, 0xa364, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, - 0xa8a4, 0x7026, 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, - 0x0570, 0xd3c4, 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, - 0x9108, 0x6810, 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, - 0x0000, 0x22a0, 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, - 0x9080, 0x002c, 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, 0x2011, - 0x0240, 0x22a0, 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, 0x6812, - 0x015e, 0x9184, 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, - 0x003e, 0x001e, 0x0804, 0xa6bd, 0xc3e5, 0x0804, 0xa323, 0x2011, - 0x0008, 0x2001, 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, - 0x7824, 0xd0cc, 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, - 0x0302, 0x0016, 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, 0x0108, - 0xc2dd, 0x001e, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, - 0x0012, 0x702f, 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, 0x704f, - 0x000a, 0x2069, 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, 0x700b, - 0x2500, 0x60c3, 0x0032, 0x0804, 0xa6bd, 0x2011, 0x0028, 0x7824, - 0xd0cc, 0x1128, 0x7216, 0x60c3, 0x0018, 0x0804, 0xa6bd, 0x0cd0, - 0xc2e5, 0x2011, 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, - 0x702f, 0x0008, 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, - 0x0804, 0xa6bd, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, - 0x7216, 0x0c08, 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, - 0x00ff, 0x8001, 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, - 0x003e, 0x0888, 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, - 0x000e, 0x0108, 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, 0x0818, - 0x00d6, 0x6813, 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, 0xb814, - 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7824, - 0xd0cc, 0x1168, 0x7013, 0x0898, 0x080c, 0xa6ab, 0x721a, 0x7a08, - 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, - 0x0889, 0x0c90, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, - 0x001e, 0x0005, 0xa412, 0xa412, 0xa414, 0xa412, 0xa412, 0xa412, - 0xa42e, 0xa412, 0x080c, 0x0dc5, 0x7914, 0x918c, 0x08ff, 0x918d, - 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, - 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, - 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0xa6bd, 0x2009, 0x0003, - 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xaf8e, 0x001e, - 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, - 0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, - 0x7116, 0x080c, 0xa6ab, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, - 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, - 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, - 0x76dc, 0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, - 0x96b4, 0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, - 0x636a, 0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, - 0x6067, 0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, - 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, - 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, - 0xffff, 0x7814, 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, - 0xa848, 0x60c6, 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, - 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, - 0x9084, 0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0048, - 0x6028, 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x6027, 0xffff, 0x2001, - 0x00b2, 0x6016, 0x2009, 0x07d0, 0x080c, 0x88c8, 0x003e, 0x004e, - 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, + 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, + 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbacc, 0xd28c, + 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec, + 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e, + 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0xa4eb, 0x080c, 0x9f3a, + 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, + 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x0804, 0x9cea, + 0x080c, 0x9f3a, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, + 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0100, + 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0026, 0x00d6, + 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, + 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, + 0xadbc, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e, + 0x003e, 0x00de, 0x080c, 0xa4d9, 0x721a, 0x9f95, 0x0000, 0x7222, + 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c, + 0xadbc, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800, + 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10, + 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000, + 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, + 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300, + 0x2021, 0x0100, 0x080c, 0xadbc, 0xb810, 0x9305, 0x7002, 0xb814, + 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, 0x700a, + 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e, + 0x00de, 0x080c, 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, + 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0xa4d9, 0x721a, 0x7a08, + 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, + 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, + 0x0dc5, 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, + 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, + 0x0005, 0x9fa8, 0x9fb7, 0x9fc2, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa8, + 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x080c, 0x0dc5, + 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x2be7, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0xa4eb, 0x0431, + 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, + 0x0804, 0xa4eb, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, + 0x0004, 0x0804, 0xa4eb, 0x0026, 0x080c, 0xadbc, 0xb810, 0x9085, + 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, + 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0x9f0a, 0x0026, 0x080c, + 0xadbc, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, + 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f6c, 0x0026, + 0x080c, 0xadbc, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, + 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f6c, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, + 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0dc5, 0x908a, + 0x0054, 0x1a0c, 0x0dc5, 0x7910, 0x2158, 0xb9c0, 0x2061, 0x0100, + 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x0005, 0xa047, 0xa10e, 0xa0e1, 0xa230, 0xa045, 0xa045, + 0xa045, 0xa045, 0xa045, 0xa045, 0xa045, 0xa906, 0xa90b, 0xa910, + 0xa915, 0xa045, 0xad04, 0xa045, 0xa901, 0x080c, 0x0dc5, 0x0096, + 0x780b, 0xffff, 0x080c, 0xa0b2, 0x7914, 0x2148, 0xa978, 0x7956, + 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032, + 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132, + 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, + 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010, + 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158, + 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c, 0x18f1, 0x0010, + 0x080c, 0x1768, 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028, + 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a, + 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813, + 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009, + 0x2001, 0x1a05, 0x2003, 0x07d0, 0x2001, 0x1a04, 0x2003, 0x0009, + 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8cc, 0xd084, + 0x0180, 0x2001, 0x1ad1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1ad0, + 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46, + 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, + 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, + 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, + 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002, + 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c, + 0x009e, 0x00de, 0x0804, 0xa4eb, 0x6813, 0x0008, 0xb810, 0x9085, + 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, + 0x6880, 0x700e, 0x7013, 0x0889, 0x080c, 0xa4d9, 0x721a, 0x7a08, + 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, + 0x080c, 0xa20e, 0x7814, 0x2048, 0x080c, 0xce54, 0x1130, 0x7814, + 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e, + 0x00de, 0x0005, 0xa12c, 0xa195, 0xa1a5, 0xa1cb, 0xa1d7, 0xa1e8, + 0xa1f0, 0xa12a, 0x080c, 0x0dc5, 0x0016, 0x0036, 0xa97c, 0x918c, + 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc, + 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e, + 0x2001, 0x19b3, 0x2004, 0x60c2, 0x0804, 0xa4eb, 0xc3e5, 0x0c88, + 0x9186, 0x0001, 0x190c, 0x0dc5, 0xaba8, 0x7824, 0xd0cc, 0x1904, + 0xa192, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026, + 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4, + 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810, + 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0, + 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c, + 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0, + 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184, + 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e, + 0x0804, 0xa4eb, 0xc3e5, 0x0804, 0xa151, 0x2011, 0x0008, 0x2001, + 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc, + 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016, + 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e, + 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f, + 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069, + 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3, + 0x0032, 0x0804, 0xa4eb, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, + 0x7216, 0x60c3, 0x0018, 0x0804, 0xa4eb, 0x0cd0, 0xc2e5, 0x2011, + 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, + 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0xa4eb, + 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08, + 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, + 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888, + 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, + 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813, + 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7824, 0xd0cc, 0x1168, + 0x7013, 0x0898, 0x080c, 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10, + 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, + 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, + 0xa240, 0xa240, 0xa242, 0xa240, 0xa240, 0xa240, 0xa25c, 0xa240, + 0x080c, 0x0dc5, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, + 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130, + 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, + 0x60c3, 0x0001, 0x0804, 0xa4eb, 0x2009, 0x0003, 0x0019, 0x7033, + 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xadbc, 0x001e, 0xb810, 0x9085, + 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, + 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, + 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, - 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, - 0x76dc, 0xd6ac, 0x1168, 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, - 0xff80, 0x1130, 0x9080, 0x33b6, 0x2015, 0x9294, 0x00ff, 0x0020, - 0xb910, 0xba14, 0x737c, 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, - 0x007e, 0x1218, 0x9584, 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, - 0x6266, 0x636a, 0x646e, 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, - 0x0000, 0x616e, 0xb8b8, 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, - 0x0110, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, - 0x8007, 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, - 0x6087, 0xffff, 0x7814, 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, - 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, - 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, - 0x00f6, 0x2079, 0x0140, 0x7803, 0x0000, 0x00fe, 0x2009, 0x0092, - 0x6116, 0x2009, 0x07d0, 0x080c, 0x88c8, 0x003e, 0x004e, 0x005e, - 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, - 0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, - 0x2071, 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, - 0x737c, 0x7480, 0x7820, 0x90be, 0x0006, 0x0904, 0xa61a, 0x90be, - 0x000a, 0x1904, 0xa5d6, 0xb8c0, 0x609e, 0x7814, 0x2048, 0xa87c, - 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f, - 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, - 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, - 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, - 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb8c0, 0x609e, 0x0050, - 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, - 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, - 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077, - 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, - 0x607f, 0x0000, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, - 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, - 0x080c, 0xaf73, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, - 0x0110, 0x2009, 0x1b58, 0x080c, 0x88c8, 0x003e, 0x004e, 0x005e, - 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, 0x9086, - 0x0040, 0x0904, 0xa656, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, - 0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x60af, 0x95d5, 0x60d7, - 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, - 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7814, 0x2048, - 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, - 0xb86c, 0x60ce, 0xbac0, 0x629e, 0x080c, 0xaf73, 0x2009, 0x07d0, - 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, - 0x88c8, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, - 0x00be, 0x0005, 0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, - 0x0002, 0x0904, 0xa672, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, - 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, - 0x00ff, 0xb88e, 0x8007, 0x607a, 0x7838, 0x607e, 0x2f00, 0x6086, - 0x7808, 0x6082, 0xa890, 0x608a, 0xa88c, 0x608e, 0xa8b0, 0x60c6, - 0xa8ac, 0x60ca, 0xa8ac, 0x7930, 0x9108, 0x7932, 0xa8b0, 0x792c, - 0x9109, 0x792e, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, - 0xbac0, 0x629e, 0x080c, 0xaf50, 0x0804, 0xa606, 0xb8cc, 0xd084, - 0x0148, 0xb88c, 0x7814, 0x2048, 0xb88c, 0x784a, 0xa836, 0x2900, - 0xa83a, 0xb046, 0x9185, 0x0600, 0x6062, 0x6266, 0x636a, 0x646e, - 0x6073, 0x0829, 0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, - 0x0804, 0xa5e9, 0x9185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, - 0x7824, 0xd0cc, 0x7826, 0x0118, 0x6073, 0x0889, 0x0010, 0x6073, - 0x0898, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, - 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, + 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4, + 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028, + 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, + 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff, + 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008, + 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, + 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, + 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, + 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, + 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, + 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0048, 0x6028, 0xc0bd, + 0x602a, 0x609f, 0x00ff, 0x6027, 0xffff, 0x2001, 0x00b2, 0x6016, + 0x2009, 0x07d0, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x006e, + 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, + 0x1800, 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, + 0x1168, 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, + 0x9080, 0x33ac, 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, + 0x737c, 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, + 0x9584, 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, + 0x646e, 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, + 0xb8b8, 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, + 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, + 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, + 0x7814, 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, + 0x60c6, 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, + 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x00f6, 0x2079, + 0x0140, 0x7803, 0x0000, 0x00fe, 0x2009, 0x0092, 0x6116, 0x2009, + 0x07d0, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, + 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, + 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, + 0x7820, 0x90be, 0x0006, 0x0904, 0xa448, 0x90be, 0x000a, 0x1904, + 0xa404, 0xb8c0, 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, + 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, + 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, + 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, + 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, + 0x0129, 0x6077, 0x0000, 0xb8c0, 0x609e, 0x0050, 0x2039, 0x0029, + 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, + 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, + 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, + 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, + 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xada1, + 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, + 0x1b58, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, + 0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, + 0xa484, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, + 0x0809, 0x6077, 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, + 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, + 0x2f00, 0x6082, 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, + 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, + 0xbac0, 0x629e, 0x080c, 0xada1, 0x2009, 0x07d0, 0x60c4, 0x9084, + 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x8794, 0x003e, + 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, + 0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, + 0xa4a0, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, + 0x0880, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, + 0x8007, 0x607a, 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, + 0xa890, 0x608a, 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, + 0xa8ac, 0x7930, 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, - 0x7824, 0xd0cc, 0x0120, 0x080c, 0xaf73, 0x0804, 0xa606, 0x080c, - 0xaf50, 0x0804, 0xa606, 0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, - 0x9294, 0x00ff, 0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, - 0x19e8, 0x6843, 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, - 0x9575, 0x00f1, 0x080c, 0x88ba, 0x0005, 0x0016, 0x2001, 0x180c, - 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, - 0x88ba, 0x001e, 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, - 0x19e9, 0x2003, 0x0000, 0x2001, 0x19f1, 0x2003, 0x0000, 0x0c88, - 0x0006, 0x6014, 0x9084, 0x1804, 0x9085, 0x0009, 0x6016, 0x000e, - 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4, 0x60a7, - 0x95f5, 0x6014, 0x9084, 0x1804, 0x9085, 0x0008, 0x6016, 0x000e, - 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6, - 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, - 0x7637, 0x11c0, 0x2001, 0x1a04, 0x2004, 0x9005, 0x15d0, 0x080c, - 0x76e4, 0x1160, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, - 0xd084, 0x090c, 0x0dc5, 0x080c, 0x88ba, 0x0458, 0x00c6, 0x2061, - 0x19e8, 0x00c8, 0x6904, 0x9194, 0x4000, 0x0540, 0x0811, 0x080c, - 0x2d49, 0x00c6, 0x2061, 0x19e8, 0x6128, 0x9192, 0x0008, 0x1258, - 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x88ba, - 0x080c, 0xa6e0, 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, - 0xf094, 0x080c, 0x88c3, 0x2009, 0x0014, 0x080c, 0xb352, 0x00ce, - 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a04, - 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e8, 0x6128, 0x9192, - 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x88ba, 0x080c, - 0x5fed, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, - 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x88d0, 0x2071, - 0x19e8, 0x713c, 0x81ff, 0x0904, 0xa7e9, 0x2061, 0x0100, 0x2069, - 0x0140, 0x080c, 0x7637, 0x11e0, 0x0036, 0x2019, 0x0002, 0x080c, - 0xaa49, 0x003e, 0x713c, 0x2160, 0x080c, 0xf094, 0x2009, 0x004a, - 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, - 0x2009, 0x004a, 0x080c, 0xb352, 0x080c, 0x76e4, 0x0804, 0xa7e9, - 0x080c, 0xa7f5, 0x0904, 0xa7e9, 0x6904, 0xd1f4, 0x0904, 0xa7f0, - 0x080c, 0x2d49, 0x00c6, 0x703c, 0x9065, 0x090c, 0x0dc5, 0x6020, - 0x00ce, 0x9086, 0x0006, 0x1528, 0x61c8, 0x60c4, 0x9105, 0x1508, - 0x2009, 0x180c, 0x2104, 0xd0d4, 0x01e0, 0x6214, 0x9294, 0x1800, - 0x1128, 0x6224, 0x9294, 0x0002, 0x1560, 0x0030, 0xc0d4, 0x200a, - 0xd0cc, 0x0110, 0x080c, 0x2c7b, 0x6014, 0x9084, 0xe7fd, 0x9085, - 0x0010, 0x6016, 0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xb352, - 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, 0xaa49, 0x003e, 0x713c, - 0x2160, 0x080c, 0xf094, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, - 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, - 0xb352, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, - 0xd1ec, 0x1904, 0xa7a0, 0x0804, 0xa7a2, 0x00d6, 0x00c6, 0x0096, - 0x703c, 0x9065, 0x090c, 0x0dc5, 0x2001, 0x0306, 0x200c, 0x9184, - 0x0030, 0x0904, 0xa8a8, 0x9184, 0x0048, 0x9086, 0x0008, 0x1904, - 0xa8a8, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, - 0x1904, 0xa8a8, 0x2009, 0x022a, 0x2104, 0x2009, 0x022f, 0x210c, - 0x9116, 0x9084, 0x03ff, 0x918c, 0x03ff, 0x9294, 0x0400, 0x0110, - 0x9102, 0x0030, 0x2010, 0x2100, 0x9202, 0x2009, 0x0228, 0x9102, - 0x9082, 0x0005, 0x0250, 0x2008, 0x2001, 0x013b, 0x2004, 0x8004, - 0x8004, 0x8004, 0x9102, 0x1a04, 0xa8a8, 0x2009, 0x1a84, 0x2104, - 0x8000, 0x0208, 0x200a, 0x2069, 0x0100, 0x6914, 0x918c, 0x1984, - 0x918d, 0x0010, 0x6916, 0x69c8, 0x2011, 0x0020, 0x68c8, 0x9106, - 0x15c0, 0x8211, 0x1dd8, 0x2001, 0x0306, 0x2003, 0x4800, 0x2001, - 0x009a, 0x2003, 0x0004, 0x2001, 0x1a69, 0x2003, 0x0000, 0x2001, - 0x1a72, 0x2003, 0x0000, 0x6a88, 0x698c, 0x2200, 0x9105, 0x1170, - 0x0096, 0x6014, 0x2048, 0xa87c, 0xc0dc, 0xa87e, 0xa880, 0xc0fc, - 0xa882, 0x009e, 0x2c10, 0x080c, 0x1be0, 0x0040, 0x6014, 0x2048, - 0xaa3a, 0xa936, 0x6ac4, 0x69c8, 0xa946, 0xaa4a, 0x0126, 0x00c6, - 0x2091, 0x2400, 0x002e, 0x080c, 0x1c79, 0x190c, 0x0dc5, 0x012e, - 0x0090, 0x2009, 0x1a85, 0x2104, 0x8000, 0x0208, 0x200a, 0x69c8, - 0x2011, 0x0020, 0x8211, 0x1df0, 0x68c8, 0x9106, 0x1dc0, 0x69c4, - 0x68c8, 0x9105, 0x0160, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002, - 0x7048, 0xc085, 0x704a, 0x0079, 0x7048, 0xc084, 0x704a, 0x2009, - 0x07d0, 0x080c, 0x88c8, 0x9006, 0x009e, 0x00ce, 0x00de, 0x0005, - 0x9085, 0x0001, 0x0cc8, 0x0026, 0x00e6, 0x2071, 0x19e8, 0x7048, - 0xd084, 0x01d8, 0x713c, 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, - 0x0008, 0x2114, 0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, - 0x9085, 0x0012, 0x7016, 0x0048, 0x928e, 0x0009, 0x0db0, 0x7014, - 0x9084, 0x1984, 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005, - 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, - 0x0126, 0x2091, 0x8000, 0x6010, 0x2058, 0xbca0, 0x2071, 0x19e8, - 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0, 0x9406, 0x0118, 0xb854, - 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048, 0xac6c, 0xad70, 0xae78, - 0x009e, 0x080c, 0x6856, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, - 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, - 0x080c, 0xa0c1, 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, 0x7016, - 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, 0x0130, - 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, 0x1800, - 0x607c, 0x6180, 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, 0x60c3, - 0x002c, 0x0804, 0xa6bd, 0x080c, 0xa0c1, 0x7003, 0x0f00, 0x7808, - 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, - 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x0156, 0x080c, 0xa10c, 0x7003, - 0x0200, 0x080c, 0x894c, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, - 0xffed, 0x9ef0, 0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, - 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xa943, 0x60c3, - 0x001c, 0x015e, 0x0804, 0xa6bd, 0x0016, 0x0026, 0x080c, 0xa0e8, - 0x080c, 0xa0fa, 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, 0x7814, - 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x9192, - 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, 0x080c, - 0xa6bd, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, - 0xaf79, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0xa0c1, - 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, - 0x0016, 0x0026, 0x080c, 0xa0c1, 0x20e9, 0x0000, 0x20a1, 0x024c, - 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, - 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, - 0x4003, 0x8003, 0x60c2, 0x080c, 0xa6bd, 0x002e, 0x001e, 0x0005, - 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, - 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c, 0xd2e0, 0x1110, 0x080c, - 0xbcb6, 0x600c, 0x0006, 0x080c, 0xd54c, 0x080c, 0xb2d3, 0x080c, - 0xaaf1, 0x00ce, 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e, - 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, - 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, - 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, - 0x0140, 0x2071, 0x19e8, 0x7024, 0x2060, 0x8cff, 0x01f8, 0x080c, - 0xa6e9, 0x6ac0, 0x68c3, 0x0000, 0x080c, 0x88c3, 0x00c6, 0x2061, - 0x0100, 0x080c, 0xb0ca, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009, - 0x0013, 0x080c, 0xb352, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, - 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, - 0x88c3, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, - 0x0008, 0x68c3, 0x0000, 0x2011, 0x5f97, 0x080c, 0x883d, 0x20a9, - 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, - 0x7804, 0x9084, 0x4000, 0x190c, 0x2d49, 0x0090, 0xd084, 0x0118, - 0x6827, 0x4001, 0x0010, 0x1f04, 0xaa2b, 0x7804, 0x9084, 0x1000, - 0x0138, 0x2001, 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, + 0x080c, 0xad7e, 0x0804, 0xa434, 0xb8cc, 0xd084, 0x0148, 0xb88c, + 0x7814, 0x2048, 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, + 0x9185, 0x0600, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, + 0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0xa417, + 0x9185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, + 0x7826, 0x0118, 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, + 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, + 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, + 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, + 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x7824, 0xd0cc, + 0x0120, 0x080c, 0xada1, 0x0804, 0xa434, 0x080c, 0xad7e, 0x0804, + 0xa434, 0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, + 0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x6843, + 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, + 0x080c, 0x8786, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, + 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x8786, 0x001e, + 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, + 0x0000, 0x2001, 0x19f2, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, + 0x9084, 0x1804, 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, + 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, + 0x9084, 0x1804, 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, + 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, + 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x7569, 0x11c0, + 0x2001, 0x1a05, 0x2004, 0x9005, 0x15d0, 0x080c, 0x7616, 0x1160, + 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, + 0x0dc5, 0x080c, 0x8786, 0x0458, 0x00c6, 0x2061, 0x19e9, 0x00c8, + 0x6904, 0x9194, 0x4000, 0x0540, 0x0811, 0x080c, 0x2d62, 0x00c6, + 0x2061, 0x19e9, 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, + 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x8786, 0x080c, 0xa50e, + 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, 0xee0f, 0x080c, + 0x878f, 0x2009, 0x0014, 0x080c, 0xb180, 0x00ce, 0x0000, 0x002e, + 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a05, 0x2004, 0x9005, + 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6128, 0x9192, 0x0003, 0x1e08, + 0x8108, 0x612a, 0x00ce, 0x080c, 0x8786, 0x080c, 0x5fe6, 0x2009, + 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, + 0x00e6, 0x0016, 0x0026, 0x080c, 0x879c, 0x2071, 0x19e9, 0x713c, + 0x81ff, 0x0904, 0xa617, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, + 0x7569, 0x11e0, 0x0036, 0x2019, 0x0002, 0x080c, 0xa877, 0x003e, + 0x713c, 0x2160, 0x080c, 0xee0f, 0x2009, 0x004a, 0x6220, 0x9296, + 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, + 0x080c, 0xb180, 0x080c, 0x7616, 0x0804, 0xa617, 0x080c, 0xa623, + 0x0904, 0xa617, 0x6904, 0xd1f4, 0x0904, 0xa61e, 0x080c, 0x2d62, + 0x00c6, 0x703c, 0x9065, 0x090c, 0x0dc5, 0x6020, 0x00ce, 0x9086, + 0x0006, 0x1528, 0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009, 0x180c, + 0x2104, 0xd0d4, 0x01e0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, + 0x9294, 0x0002, 0x1560, 0x0030, 0xc0d4, 0x200a, 0xd0cc, 0x0110, + 0x080c, 0x2c94, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, + 0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xb180, 0x00c0, 0x0036, + 0x2019, 0x0001, 0x080c, 0xa877, 0x003e, 0x713c, 0x2160, 0x080c, + 0xee0f, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, + 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, 0xb180, 0x002e, + 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, + 0xa5ce, 0x0804, 0xa5d0, 0x00d6, 0x00c6, 0x0096, 0x703c, 0x9065, + 0x090c, 0x0dc5, 0x2001, 0x0306, 0x200c, 0x9184, 0x0030, 0x0904, + 0xa6d6, 0x9184, 0x0048, 0x9086, 0x0008, 0x1904, 0xa6d6, 0x2009, + 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1904, 0xa6d6, + 0x2009, 0x022a, 0x2104, 0x2009, 0x022f, 0x210c, 0x9116, 0x9084, + 0x03ff, 0x918c, 0x03ff, 0x9294, 0x0400, 0x0110, 0x9102, 0x0030, + 0x2010, 0x2100, 0x9202, 0x2009, 0x0228, 0x9102, 0x9082, 0x0005, + 0x0250, 0x2008, 0x2001, 0x013b, 0x2004, 0x8004, 0x8004, 0x8004, + 0x9102, 0x1a04, 0xa6d6, 0x2009, 0x1a85, 0x2104, 0x8000, 0x0208, + 0x200a, 0x2069, 0x0100, 0x6914, 0x918c, 0x1984, 0x918d, 0x0010, + 0x6916, 0x69c8, 0x2011, 0x0020, 0x68c8, 0x9106, 0x15c0, 0x8211, + 0x1dd8, 0x2001, 0x0306, 0x2003, 0x4800, 0x2001, 0x009a, 0x2003, + 0x0004, 0x2001, 0x1a6a, 0x2003, 0x0000, 0x2001, 0x1a73, 0x2003, + 0x0000, 0x6a88, 0x698c, 0x2200, 0x9105, 0x1170, 0x0096, 0x6014, + 0x2048, 0xa87c, 0xc0dc, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x009e, + 0x2c10, 0x080c, 0x1c09, 0x0040, 0x6014, 0x2048, 0xaa3a, 0xa936, + 0x6ac4, 0x69c8, 0xa946, 0xaa4a, 0x0126, 0x00c6, 0x2091, 0x2400, + 0x002e, 0x080c, 0x1ca2, 0x190c, 0x0dc5, 0x012e, 0x0090, 0x2009, + 0x1a86, 0x2104, 0x8000, 0x0208, 0x200a, 0x69c8, 0x2011, 0x0020, + 0x8211, 0x1df0, 0x68c8, 0x9106, 0x1dc0, 0x69c4, 0x68c8, 0x9105, + 0x0160, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002, 0x7048, 0xc085, + 0x704a, 0x0079, 0x7048, 0xc084, 0x704a, 0x2009, 0x07d0, 0x080c, + 0x8794, 0x9006, 0x009e, 0x00ce, 0x00de, 0x0005, 0x9085, 0x0001, + 0x0cc8, 0x0026, 0x00e6, 0x2071, 0x19e9, 0x7048, 0xd084, 0x01d8, + 0x713c, 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, + 0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, + 0x7016, 0x0048, 0x928e, 0x0009, 0x0db0, 0x7014, 0x9084, 0x1984, + 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, + 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, + 0x8000, 0x6010, 0x2058, 0xbca0, 0x2071, 0x19e9, 0x7018, 0x2058, + 0x8bff, 0x0190, 0xb8a0, 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, + 0x6014, 0x0096, 0x2048, 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, + 0x684f, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x080c, 0x9eef, + 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, + 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, + 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, + 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, + 0xa4eb, 0x080c, 0x9eef, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, + 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, + 0x0804, 0xa4eb, 0x0156, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x080c, + 0x8818, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, + 0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, + 0x0002, 0x9290, 0x0002, 0x1f04, 0xa771, 0x60c3, 0x001c, 0x015e, + 0x0804, 0xa4eb, 0x0016, 0x0026, 0x080c, 0x9f16, 0x080c, 0x9f28, + 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, + 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, + 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, + 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, 0x080c, 0xa4eb, 0x002e, + 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, 0xada7, 0x20a1, + 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x9eef, 0x7003, 0x6200, + 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0016, 0x0026, + 0x080c, 0x9eef, 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, + 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, + 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, + 0x60c2, 0x080c, 0xa4eb, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x700c, 0x2060, + 0x8cff, 0x0178, 0x080c, 0xd05e, 0x1110, 0x080c, 0xbae2, 0x600c, + 0x0006, 0x080c, 0xd2ca, 0x080c, 0xb101, 0x080c, 0xa91f, 0x00ce, + 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, - 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, - 0x19e8, 0x703c, 0x2060, 0x8cff, 0x0904, 0xaab4, 0x9386, 0x0002, - 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xaab4, 0x68af, 0x95f5, - 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, - 0x0008, 0x080c, 0x88d0, 0x080c, 0x2031, 0x2001, 0x0032, 0x6920, - 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, - 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, - 0x9084, 0x4000, 0x190c, 0x2d49, 0x0090, 0xd08c, 0x0118, 0x6827, - 0x0002, 0x0010, 0x1f04, 0xaa8a, 0x7804, 0x9084, 0x1000, 0x0138, - 0x2001, 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x6827, - 0x4000, 0x6824, 0x83ff, 0x1140, 0x2009, 0x0049, 0x6020, 0x9086, - 0x0009, 0x0110, 0x080c, 0xb352, 0x000e, 0x001e, 0x002e, 0x006e, - 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, - 0x0126, 0x2091, 0x8000, 0x2069, 0x19e8, 0x6a06, 0x012e, 0x00de, - 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e8, 0x6a32, - 0x012e, 0x00de, 0x0005, 0x080c, 0xa284, 0x7047, 0x1000, 0x0098, - 0x080c, 0xa284, 0x7047, 0x4000, 0x0070, 0x080c, 0xa284, 0x7047, - 0x2000, 0x0048, 0x080c, 0xa284, 0x7047, 0x0400, 0x0020, 0x080c, - 0xa284, 0x7047, 0x0200, 0x7854, 0x7032, 0x60c3, 0x0020, 0x0804, - 0xa6bd, 0x00e6, 0x2071, 0x19e8, 0x7020, 0x9005, 0x0110, 0x8001, - 0x7022, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, - 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x7614, - 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xab96, 0x8cff, - 0x0904, 0xab96, 0x6020, 0x9086, 0x0006, 0x1904, 0xab91, 0x88ff, - 0x0138, 0x2800, 0x9c06, 0x1904, 0xab91, 0x2039, 0x0000, 0x0050, - 0x6010, 0x9b06, 0x1904, 0xab91, 0x85ff, 0x0120, 0x6054, 0x9106, - 0x1904, 0xab91, 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, - 0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, - 0x88c3, 0x080c, 0xac1b, 0x7027, 0x0000, 0x0428, 0x080c, 0x88c3, - 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, - 0x0000, 0x080c, 0xac1b, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, - 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d39, - 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, - 0x6827, 0x0001, 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, - 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, - 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, - 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, - 0x0096, 0x2048, 0x080c, 0xd0d6, 0x0110, 0x080c, 0xebd4, 0x009e, - 0x080c, 0xb306, 0x080c, 0xaaf1, 0x88ff, 0x1190, 0x00ce, 0x0804, - 0xab0c, 0x2c78, 0x600c, 0x2060, 0x0804, 0xab0c, 0x9006, 0x012e, - 0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, - 0x601b, 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, - 0x00d6, 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x19e8, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, - 0xac0a, 0x6020, 0x9086, 0x0006, 0x1904, 0xac05, 0x87ff, 0x0128, - 0x2700, 0x9c06, 0x1904, 0xac05, 0x0040, 0x6010, 0x9b06, 0x15e8, - 0x85ff, 0x0118, 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, - 0x0036, 0x2019, 0x0001, 0x080c, 0xaa49, 0x7033, 0x0000, 0x9006, - 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, - 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, - 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, - 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, - 0x2048, 0x080c, 0xd0d6, 0x0110, 0x080c, 0xebd4, 0x080c, 0xb306, - 0x87ff, 0x1198, 0x00ce, 0x0804, 0xabb6, 0x2c78, 0x600c, 0x2060, - 0x0804, 0xabb6, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, - 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, - 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e8, 0x2001, 0x1800, - 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, - 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, - 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x2c10, 0x7638, - 0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, - 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, - 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, - 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, - 0x6004, 0x9086, 0x0040, 0x090c, 0x99a5, 0x9085, 0x0001, 0x0020, - 0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, - 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, + 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x19e9, 0x7024, 0x2060, 0x8cff, 0x01f8, 0x080c, 0xa517, 0x6ac0, + 0x68c3, 0x0000, 0x080c, 0x878f, 0x00c6, 0x2061, 0x0100, 0x080c, + 0xaef8, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, + 0xb180, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, + 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x878f, 0x6814, + 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, + 0x0000, 0x2011, 0x5f90, 0x080c, 0x8709, 0x20a9, 0x01f4, 0x0009, + 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, + 0x4000, 0x190c, 0x2d62, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, + 0x0010, 0x1f04, 0xa859, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x0005, 0x0126, + 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, + 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, + 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x703c, + 0x2060, 0x8cff, 0x0904, 0xa8e2, 0x9386, 0x0002, 0x1128, 0x6814, + 0x9084, 0x0002, 0x0904, 0xa8e2, 0x68af, 0x95f5, 0x6817, 0x0010, + 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, + 0x879c, 0x080c, 0x205a, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, + 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, + 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, + 0x190c, 0x2d62, 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, + 0x1f04, 0xa8b8, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, + 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x6827, 0x4000, 0x6824, + 0x83ff, 0x1140, 0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0110, + 0x080c, 0xb180, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, + 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, + 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a32, 0x012e, 0x00de, + 0x0005, 0x080c, 0xa0b2, 0x7047, 0x1000, 0x0098, 0x080c, 0xa0b2, + 0x7047, 0x4000, 0x0070, 0x080c, 0xa0b2, 0x7047, 0x2000, 0x0048, + 0x080c, 0xa0b2, 0x7047, 0x0400, 0x0020, 0x080c, 0xa0b2, 0x7047, + 0x0200, 0x7854, 0x7032, 0x60c3, 0x0020, 0x0804, 0xa4eb, 0x00e6, + 0x2071, 0x19e9, 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, + 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7614, 0x2660, 0x2678, + 0x2039, 0x0001, 0x87ff, 0x0904, 0xa9c4, 0x8cff, 0x0904, 0xa9c4, + 0x6020, 0x9086, 0x0006, 0x1904, 0xa9bf, 0x88ff, 0x0138, 0x2800, + 0x9c06, 0x1904, 0xa9bf, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, + 0x1904, 0xa9bf, 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0xa9bf, + 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, + 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x878f, 0x080c, + 0xaa49, 0x7027, 0x0000, 0x0428, 0x080c, 0x878f, 0x6820, 0xd0b4, + 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, + 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, + 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, + 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, + 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, + 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, + 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, + 0x080c, 0xce54, 0x0110, 0x080c, 0xe948, 0x009e, 0x080c, 0xb134, + 0x080c, 0xa91f, 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa93a, 0x2c78, + 0x600c, 0x2060, 0x0804, 0xa93a, 0x9006, 0x012e, 0x000e, 0x006e, + 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, + 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, - 0x19e8, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0xad01, 0x6010, - 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0xacfc, 0x7024, - 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xacd3, - 0x080c, 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7027, 0x0000, - 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, - 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, - 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, - 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, - 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, - 0x080c, 0xd2cf, 0x1180, 0x080c, 0x3279, 0x080c, 0xd2e0, 0x1518, - 0x080c, 0xbcb6, 0x0400, 0x080c, 0xac1b, 0x6824, 0xd084, 0x09b0, - 0x6827, 0x0001, 0x0898, 0x080c, 0xd2e0, 0x1118, 0x080c, 0xbcb6, - 0x0090, 0x6014, 0x2048, 0x080c, 0xd0d6, 0x0168, 0x6020, 0x9086, - 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, - 0x6e92, 0x080c, 0xd2c3, 0x080c, 0xd54c, 0x080c, 0xb306, 0x080c, - 0xaaf1, 0x00ce, 0x0804, 0xac7c, 0x2c78, 0x600c, 0x2060, 0x0804, - 0xac7c, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, - 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, - 0xebd4, 0x0c08, 0x00d6, 0x080c, 0xa10c, 0x7003, 0x0200, 0x7007, - 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1989, 0x20e9, - 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, - 0x7027, 0x7878, 0x080c, 0xa6bd, 0x00de, 0x0005, 0x080c, 0xa10c, - 0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, - 0x00ff, 0x7022, 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, - 0x0200, 0x7002, 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, - 0x0804, 0xa6bd, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, - 0x0035, 0x080c, 0xd759, 0x00de, 0x1904, 0xadaf, 0x080c, 0xa0c1, - 0x7003, 0x1300, 0x782c, 0x080c, 0xaeb5, 0x2068, 0x6820, 0x9086, - 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0xb23d, 0x11d8, - 0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, - 0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, - 0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, - 0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, - 0xb814, 0x700e, 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0xb23d, - 0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, - 0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, - 0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, - 0x000c, 0x001e, 0x00de, 0x080c, 0xa6bd, 0x00be, 0x0005, 0x781b, - 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, - 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, - 0x0904, 0xae2a, 0x9186, 0x0005, 0x0904, 0xae12, 0x9186, 0x0004, - 0x05d8, 0x9186, 0x0008, 0x0904, 0xae1b, 0x7807, 0x0037, 0x782f, - 0x0003, 0x7817, 0x1700, 0x080c, 0xae92, 0x0005, 0x080c, 0xae53, - 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002, - 0xadf3, 0xadfe, 0xadf5, 0xadfe, 0xadfa, 0xadf3, 0xadf3, 0xadfe, - 0xadfe, 0xadfe, 0xadfe, 0xadf3, 0xadf3, 0xadf3, 0xadf3, 0xadf3, - 0xadfe, 0xadf3, 0xadfe, 0x080c, 0x0dc5, 0x6824, 0xd0e4, 0x0110, - 0xd0cc, 0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, - 0x6830, 0x7026, 0x0804, 0xae4c, 0x080c, 0xae53, 0x00d6, 0x0026, - 0x792c, 0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, - 0x900e, 0x04d0, 0x080c, 0xae53, 0x00d6, 0x0026, 0x792c, 0x2168, - 0x2009, 0x4000, 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, - 0x2009, 0x4000, 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, - 0x900e, 0x0410, 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, - 0x6924, 0xc185, 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, - 0xa9b0, 0xa838, 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, - 0x0000, 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, - 0x2009, 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, - 0x00de, 0x0804, 0xa6bd, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, - 0x080c, 0xa10c, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, - 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0xb23d, 0x1118, 0x9092, - 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68, 0x2d34, - 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, - 0x6498, 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, - 0x9086, 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, - 0x7312, 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, - 0x00be, 0x0005, 0x080c, 0xa10c, 0x7003, 0x0100, 0x782c, 0x700a, - 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x080c, - 0xa0b8, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, - 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, - 0x701a, 0x60c3, 0x0010, 0x0804, 0xa6bd, 0x00e6, 0x2071, 0x0240, - 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8cc, 0xd084, - 0x0120, 0x7844, 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, - 0x00ee, 0x0005, 0x080c, 0xa103, 0x7003, 0x0100, 0x782c, 0x700a, - 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x0021, 0x60c3, - 0x0000, 0x0804, 0xa6bd, 0x00d6, 0x080c, 0xaf8e, 0xb810, 0x9085, - 0x0300, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, - 0x6880, 0x700e, 0x7013, 0x0819, 0x080c, 0xa6ab, 0x721a, 0x2f10, - 0x7222, 0x7a08, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, - 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, - 0x2bce, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, - 0x080c, 0xa6e0, 0x080c, 0x88ba, 0x0005, 0x0036, 0x0096, 0x00d6, - 0x00e6, 0x7858, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, - 0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, - 0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, - 0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, - 0x0200, 0x080c, 0xaf8e, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, - 0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, - 0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, - 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, - 0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, - 0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, - 0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, - 0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b3, 0x210c, 0x009e, - 0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, - 0x0005, 0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, - 0x000b, 0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, - 0x2009, 0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, - 0x6912, 0x0005, 0x080c, 0xa0c1, 0x0016, 0x0026, 0x0096, 0x00d6, - 0x7814, 0x2048, 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, - 0x0028, 0x1138, 0x2001, 0x197c, 0x2004, 0x9086, 0xaaaa, 0x1904, - 0xb033, 0x7003, 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, - 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, - 0x700e, 0xa998, 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, - 0x1805, 0x2e10, 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, - 0x1f04, 0xafc4, 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, - 0x8108, 0x8210, 0x1f04, 0xafce, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x0029, 0x2098, 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, - 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, - 0xaf79, 0x00de, 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, - 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, - 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, - 0x8109, 0x1dc0, 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, + 0x19e9, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0xaa38, 0x6020, + 0x9086, 0x0006, 0x1904, 0xaa33, 0x87ff, 0x0128, 0x2700, 0x9c06, + 0x1904, 0xaa33, 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, + 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, + 0x0001, 0x080c, 0xa877, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, + 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, + 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, + 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, + 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, + 0xce54, 0x0110, 0x080c, 0xe948, 0x080c, 0xb134, 0x87ff, 0x1198, + 0x00ce, 0x0804, 0xa9e4, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa9e4, + 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, + 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, + 0x0c80, 0x00e6, 0x2071, 0x19e9, 0x2001, 0x1800, 0x2004, 0x9086, + 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, + 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2071, 0x19e9, 0x2c10, 0x7638, 0x2660, 0x2678, + 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, + 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, + 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, + 0x0040, 0x090c, 0x97e1, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, + 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x760c, + 0x2660, 0x2678, 0x8cff, 0x0904, 0xab2f, 0x6010, 0x00b6, 0x2058, + 0xb8a0, 0x00be, 0x9206, 0x1904, 0xab2a, 0x7024, 0x9c06, 0x1520, + 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xab01, 0x080c, 0xa517, + 0x68c3, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2d52, 0x9006, 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, + 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, + 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd04d, + 0x1180, 0x080c, 0x326f, 0x080c, 0xd05e, 0x1518, 0x080c, 0xbae2, + 0x0400, 0x080c, 0xaa49, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, + 0x0898, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x0090, 0x6014, + 0x2048, 0x080c, 0xce54, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dc4, 0x080c, + 0xd041, 0x080c, 0xd2ca, 0x080c, 0xb134, 0x080c, 0xa91f, 0x00ce, + 0x0804, 0xaaaa, 0x2c78, 0x600c, 0x2060, 0x0804, 0xaaaa, 0x012e, + 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xe948, 0x0c08, + 0x00d6, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, + 0x0014, 0x20e1, 0x0001, 0x2099, 0x198a, 0x20e9, 0x0000, 0x20a1, + 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, + 0x080c, 0xa4eb, 0x00de, 0x0005, 0x080c, 0x9f3a, 0x700b, 0x0800, + 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, + 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, + 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0xa4eb, + 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, + 0xd4d7, 0x00de, 0x1904, 0xabdd, 0x080c, 0x9eef, 0x7003, 0x1300, + 0x782c, 0x080c, 0xace3, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, + 0x7810, 0x2058, 0xbaa0, 0x080c, 0xb06b, 0x11d8, 0x9286, 0x007e, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, + 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, + 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, + 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0xb06b, 0x1130, 0x7810, + 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181f, + 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, + 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, + 0x00de, 0x080c, 0xa4eb, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, + 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, + 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xac58, + 0x9186, 0x0005, 0x0904, 0xac40, 0x9186, 0x0004, 0x05d8, 0x9186, + 0x0008, 0x0904, 0xac49, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, + 0x1700, 0x080c, 0xacc0, 0x0005, 0x080c, 0xac81, 0x00d6, 0x0026, + 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002, 0xac21, 0xac2c, + 0xac23, 0xac2c, 0xac28, 0xac21, 0xac21, 0xac2c, 0xac2c, 0xac2c, + 0xac2c, 0xac21, 0xac21, 0xac21, 0xac21, 0xac21, 0xac2c, 0xac21, + 0xac2c, 0x080c, 0x0dc5, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, + 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, + 0x0804, 0xac7a, 0x080c, 0xac81, 0x00d6, 0x0026, 0x792c, 0x2168, + 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, + 0x080c, 0xac81, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, + 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, + 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, + 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, + 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, + 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, + 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, + 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, + 0xa4eb, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9f3a, + 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, + 0x2058, 0xb8a0, 0x080c, 0xb06b, 0x1118, 0x9092, 0x007e, 0x0268, + 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, + 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, + 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, + 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, + 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, + 0x080c, 0x9f3a, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, + 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c, 0x9ee6, 0x7003, + 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, + 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, + 0x0010, 0x0804, 0xa4eb, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, + 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8cc, 0xd084, 0x0120, 0x7844, + 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, + 0x080c, 0x9f31, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, + 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0021, 0x60c3, 0x0000, 0x0804, + 0xa4eb, 0x00d6, 0x080c, 0xadbc, 0xb810, 0x9085, 0x0300, 0x7002, + 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, + 0x7013, 0x0819, 0x080c, 0xa4d9, 0x721a, 0x2f10, 0x7222, 0x7a08, + 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, + 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x2be7, 0x0228, + 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa50e, + 0x080c, 0x8786, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, + 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, + 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, + 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, + 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, + 0xadbc, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, + 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, + 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, + 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, + 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, + 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, + 0xc1d5, 0x2102, 0x2009, 0x19b4, 0x210c, 0x009e, 0x918d, 0x0092, + 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, + 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, + 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, + 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, + 0x080c, 0x9eef, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, + 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, + 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xae61, 0x7003, + 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, + 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, + 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, + 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xadf2, + 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, + 0x1f04, 0xadfc, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, + 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, + 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xada7, 0x00de, + 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, - 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, - 0x1837, 0x2004, 0x9084, 0x0028, 0x1168, 0x080c, 0x7637, 0x0150, - 0x6028, 0xc0bd, 0x602a, 0x6014, 0x9084, 0x1804, 0x9085, 0x0029, - 0x6016, 0x0010, 0x080c, 0xa6bd, 0x080c, 0x88ba, 0x00de, 0x009e, - 0x002e, 0x001e, 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, - 0x9085, 0x00ff, 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, - 0x00ff, 0x00ee, 0x0804, 0xafa9, 0x080c, 0xa0c1, 0x0016, 0x0026, - 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, - 0x00c6, 0xa89c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, - 0x9105, 0x700a, 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, - 0x9105, 0x700e, 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, - 0x9084, 0x00ff, 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, - 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, - 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, - 0x1dc0, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, - 0x8210, 0x1f04, 0xb085, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, - 0x2012, 0x8108, 0x8210, 0x1f04, 0xb08f, 0x00d6, 0x0016, 0x2069, - 0x0200, 0x080c, 0xaf79, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, - 0x0002, 0x2009, 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, - 0x8210, 0x1f04, 0xb0a5, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, - 0x8210, 0x8109, 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, - 0x1f04, 0xb0b6, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, - 0x9575, 0x080c, 0xa6bd, 0x080c, 0x88ba, 0x00de, 0x009e, 0x002e, - 0x001e, 0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, - 0x2069, 0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, - 0x20a9, 0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, - 0x9006, 0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, - 0x00de, 0x0005, 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056, - 0x9006, 0xa836, 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, - 0x6007, 0x0040, 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001, - 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa813, 0x20c5, 0x080c, 0x9564, - 0x0126, 0x2091, 0x8000, 0x080c, 0x9bd3, 0x012e, 0x009e, 0x00de, - 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, - 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x760c, 0x2660, 0x2678, - 0x8cff, 0x0904, 0xb19d, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, - 0x68c0, 0x9005, 0x0904, 0xb16f, 0x080c, 0xa6e9, 0x68c3, 0x0000, - 0x080c, 0xac1b, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, - 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d39, 0x9006, - 0x080c, 0x2d39, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, - 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, - 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, - 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, - 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd2cf, 0x1180, 0x080c, - 0x3279, 0x080c, 0xd2e0, 0x1518, 0x080c, 0xbcb6, 0x0400, 0x080c, - 0xac1b, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, - 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0090, 0x6014, 0x2048, 0x080c, - 0xd0d6, 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, - 0xab7a, 0xa877, 0x0000, 0x080c, 0x6e9f, 0x080c, 0xd2c3, 0x080c, - 0xd54c, 0x080c, 0xb306, 0x080c, 0xaaf1, 0x00ce, 0x0804, 0xb120, - 0x2c78, 0x600c, 0x2060, 0x0804, 0xb120, 0x700f, 0x0000, 0x700b, - 0x0000, 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, - 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xebd4, - 0x08f0, 0x00d6, 0x0156, 0x080c, 0xa10c, 0x7a14, 0x82ff, 0x0138, - 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, - 0x0200, 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, - 0x0004, 0x1110, 0xc38d, 0x0060, 0x080c, 0x7637, 0x1110, 0xc3ad, - 0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, - 0x730e, 0x080c, 0x894c, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, - 0xffed, 0x2071, 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, - 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xb1e3, 0x60c3, - 0x0020, 0x080c, 0xa6bd, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, - 0xa10c, 0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, - 0x000e, 0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, - 0x0488, 0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, - 0x19be, 0x2204, 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, - 0x0421, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, - 0x2004, 0x7022, 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001, - 0x1818, 0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, - 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, - 0x60c3, 0x001c, 0x015e, 0x0804, 0xa6bd, 0x0006, 0x2001, 0x1837, - 0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0xaabf, - 0x2011, 0x0002, 0x080c, 0xaac9, 0x080c, 0xa9d3, 0x0036, 0x901e, - 0x080c, 0xaa49, 0x003e, 0x0005, 0x080c, 0x33af, 0x0188, 0x0016, - 0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020, 0x7012, 0x2009, 0x007e, - 0x080c, 0x6724, 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, - 0x0005, 0x2071, 0x188d, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976, - 0x2071, 0x1800, 0x7076, 0x707a, 0x706b, 0xffe0, 0x2071, 0x1800, - 0x7074, 0x7056, 0x705b, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071, - 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0010, 0x0608, 0x7058, - 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, - 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, - 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, - 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, - 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7554, 0x9582, 0x0010, - 0x0600, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, - 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, - 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, - 0x1228, 0x755a, 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, 0x1cd0, - 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, - 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0dc5, 0x9006, 0x6006, 0x600a, - 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, - 0x601e, 0x6056, 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, - 0x603a, 0x603e, 0x6042, 0x602a, 0x2061, 0x1800, 0x6054, 0x8000, - 0x6056, 0x9086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, - 0x0016, 0x080c, 0x9ab1, 0x001e, 0x012e, 0x0cb0, 0x0006, 0x6000, - 0x9086, 0x0000, 0x01c0, 0x601c, 0xd084, 0x190c, 0x1a8e, 0x6017, - 0x0000, 0x6023, 0x0007, 0x2001, 0x1986, 0x2004, 0x0006, 0x9082, - 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xee87, 0x6043, - 0x0000, 0x6013, 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071, - 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058, + 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, + 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x1168, 0x080c, 0x7569, 0x0150, 0x6028, 0xc0bd, + 0x602a, 0x6014, 0x9084, 0x1804, 0x9085, 0x0029, 0x6016, 0x0010, + 0x080c, 0xa4eb, 0x080c, 0x8786, 0x00de, 0x009e, 0x002e, 0x001e, + 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, + 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, + 0x0804, 0xadd7, 0x080c, 0x9eef, 0x0016, 0x0026, 0x0096, 0x00d6, + 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, + 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, + 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, + 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, + 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, + 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, + 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, + 0xaeb3, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, + 0x8210, 0x1f04, 0xaebd, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, + 0xada7, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, + 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, + 0xaed3, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, + 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaee4, + 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, + 0xa4eb, 0x080c, 0x8786, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, + 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, + 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, + 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, + 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, + 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, + 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, + 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, + 0x2900, 0xa85a, 0xa813, 0x20ee, 0x080c, 0x93a0, 0x0126, 0x2091, + 0x8000, 0x080c, 0x9a0f, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, + 0x8000, 0x2071, 0x19e9, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, + 0xafcb, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, + 0x0904, 0xaf9d, 0x080c, 0xa517, 0x68c3, 0x0000, 0x080c, 0xaa49, + 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, + 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, + 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, + 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, + 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, + 0x600f, 0x0000, 0x080c, 0xd04d, 0x1180, 0x080c, 0x326f, 0x080c, + 0xd05e, 0x1518, 0x080c, 0xbae2, 0x0400, 0x080c, 0xaa49, 0x6824, + 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xd05e, 0x1118, + 0x080c, 0xbae2, 0x0090, 0x6014, 0x2048, 0x080c, 0xce54, 0x0168, + 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, + 0x0000, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x080c, 0xd2ca, 0x080c, + 0xb134, 0x080c, 0xa91f, 0x00ce, 0x0804, 0xaf4e, 0x2c78, 0x600c, + 0x2060, 0x0804, 0xaf4e, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, + 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe948, 0x08f0, 0x00d6, + 0x0156, 0x080c, 0x9f3a, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, + 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, + 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, + 0xc38d, 0x0060, 0x080c, 0x7569, 0x1110, 0xc3ad, 0x0008, 0xc3a5, + 0x6adc, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, + 0x8818, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, + 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, + 0x0002, 0x9290, 0x0002, 0x1f04, 0xb011, 0x60c3, 0x0020, 0x080c, + 0xa4eb, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x9f3a, 0x7a14, + 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, + 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, + 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, + 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, + 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7022, + 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, 0x2004, + 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, + 0x015e, 0x0804, 0xa4eb, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, + 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, + 0x080c, 0xa8f7, 0x080c, 0xa801, 0x0036, 0x901e, 0x080c, 0xa877, + 0x003e, 0x0005, 0x080c, 0x33a5, 0x0188, 0x0016, 0x00b6, 0x00c6, + 0x7010, 0x9085, 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x671d, + 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x2071, + 0x188d, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976, 0x2071, 0x1800, + 0x7076, 0x707a, 0x706b, 0xffe0, 0x2071, 0x1800, 0x7074, 0x7056, + 0x705b, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, + 0x8000, 0x7554, 0x9582, 0x0010, 0x0608, 0x7058, 0x2060, 0x6000, + 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, + 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, + 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, + 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, + 0x00e6, 0x2071, 0x1800, 0x7554, 0x9582, 0x0010, 0x0600, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, - 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, - 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, - 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0xb365, 0xb36e, - 0xb389, 0xb3a4, 0xd82b, 0xd848, 0xd863, 0xb365, 0xb36e, 0x9100, - 0xb3bd, 0xb365, 0xb365, 0xb365, 0xb365, 0x9186, 0x0013, 0x1128, - 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0005, 0x0005, 0x0066, 0x6000, - 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb387, - 0xbb05, 0xbcfd, 0xb387, 0xbd93, 0xb6a0, 0xb387, 0xb387, 0xba87, - 0xc3b1, 0xb387, 0xb387, 0xb387, 0xb387, 0xb387, 0xb387, 0x080c, - 0x0dc5, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, - 0x006e, 0x0005, 0xb3a2, 0xca7e, 0xb3a2, 0xb3a2, 0xb3a2, 0xb3a2, - 0xb3a2, 0xb3a2, 0xca15, 0xcc00, 0xb3a2, 0xcabf, 0xcb3e, 0xcabf, - 0xcb3e, 0xb3a2, 0x080c, 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, - 0x0dc5, 0x6000, 0x0002, 0xb3bb, 0xc3f8, 0xc4c0, 0xc5f3, 0xc7a2, - 0xb3bb, 0xb3bb, 0xb3bb, 0xc3cc, 0xc9a1, 0xc9a4, 0xb3bb, 0xb3bb, - 0xb3bb, 0xb3bb, 0xc9d3, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, - 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb3d6, 0xb3d6, - 0xb419, 0xb4b8, 0xb54d, 0xb3d6, 0xb3d6, 0xb3d6, 0xb3d8, 0xb3d6, - 0xb3d6, 0xb3d6, 0xb3d6, 0xb3d6, 0xb3d6, 0xb3d6, 0x080c, 0x0dc5, - 0x9186, 0x004c, 0x0588, 0x9186, 0x0003, 0x190c, 0x0dc5, 0x0096, - 0x601c, 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, - 0xa87c, 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, - 0xa84a, 0x9006, 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, - 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, - 0x2c10, 0x080c, 0x1be0, 0x080c, 0x9564, 0x0126, 0x2091, 0x8000, - 0x080c, 0x9bd3, 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, - 0x00be, 0x2c00, 0x080c, 0xb56f, 0x080c, 0xd7fb, 0x6003, 0x0007, - 0x0005, 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, - 0x2048, 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, - 0x0046, 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, - 0xa87b, 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, - 0x0000, 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, - 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, - 0x2100, 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, - 0x9086, 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, - 0x8423, 0x9405, 0x0002, 0xb480, 0xb480, 0xb47b, 0xb47e, 0xb480, - 0xb478, 0xb46b, 0xb46b, 0xb46b, 0xb46b, 0xb46b, 0xb46b, 0xb46b, - 0xb46b, 0xb46b, 0xb46b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, - 0x001e, 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dc5, - 0x080c, 0xbfab, 0x0028, 0x080c, 0xc0e9, 0x0010, 0x080c, 0xc1df, - 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, - 0x000e, 0x080c, 0xb62d, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, - 0xb100, 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, - 0x0000, 0x2041, 0x126c, 0x080c, 0xb7f1, 0x0160, 0x000e, 0x9005, - 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, - 0x0804, 0xb2d3, 0x2001, 0x002c, 0x900e, 0x080c, 0xb693, 0x0c70, - 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, - 0x0a0c, 0x0dc5, 0x91b2, 0x0050, 0x1a0c, 0x0dc5, 0x9182, 0x0047, - 0x00ca, 0x2001, 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, - 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x94b1, 0x002e, 0x001e, - 0x000e, 0x012e, 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, - 0xb419, 0x0005, 0xb4eb, 0xb4eb, 0xb4ed, 0xb523, 0xb4eb, 0xb4eb, - 0xb4eb, 0xb4eb, 0xb536, 0x080c, 0x0dc5, 0x00d6, 0x0016, 0x0096, - 0x080c, 0x9a61, 0x080c, 0x9bd3, 0x6003, 0x0004, 0x6114, 0x2148, - 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, - 0x9005, 0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb693, 0x080c, - 0xb2d3, 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, - 0xa8ae, 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, - 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, - 0x001e, 0x00de, 0x0005, 0x080c, 0x9a61, 0x00d6, 0x0096, 0x6114, - 0x2148, 0x080c, 0xd0d8, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6e9f, - 0x009e, 0x00de, 0x080c, 0xb2d3, 0x0804, 0x9bd3, 0x080c, 0x9a61, - 0x080c, 0x3250, 0x080c, 0xd7f8, 0x00d6, 0x0096, 0x6114, 0x2148, - 0x080c, 0xd0d8, 0x0120, 0xa87b, 0x0029, 0x080c, 0x6e9f, 0x009e, - 0x00de, 0x080c, 0xb2d3, 0x0804, 0x9bd3, 0x9182, 0x0047, 0x0002, - 0xb55d, 0xb55f, 0xb55d, 0xb55d, 0xb55d, 0xb55d, 0xb55d, 0xb55d, - 0xb55d, 0xb55d, 0xb55d, 0xb55d, 0xb55f, 0x080c, 0x0dc5, 0x00d6, - 0x0096, 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, - 0x0000, 0x080c, 0x6e9f, 0x009e, 0x00de, 0x0804, 0xb2d3, 0x0026, - 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, + 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1228, 0x755a, + 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc8, 0x9006, + 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, + 0x9c02, 0x1a0c, 0x0dc5, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016, + 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x6056, + 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, + 0x6042, 0x602a, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x9086, + 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, + 0x98ed, 0x001e, 0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000, + 0x01c0, 0x601c, 0xd084, 0x190c, 0x1ab7, 0x6017, 0x0000, 0x6023, + 0x0007, 0x2001, 0x1987, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e, + 0x0208, 0x8004, 0x601a, 0x080c, 0xec02, 0x6043, 0x0000, 0x6013, + 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, + 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058, 0x2060, 0x6000, + 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, + 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, + 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, + 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, + 0x6020, 0x9084, 0x000f, 0x0002, 0xb193, 0xb19c, 0xb1b7, 0xb1d2, + 0xd5a9, 0xd5c6, 0xd5e1, 0xb193, 0xb19c, 0x8fcd, 0xb1eb, 0xb193, + 0xb193, 0xb193, 0xb193, 0x9186, 0x0013, 0x1128, 0x080c, 0x97e1, + 0x080c, 0x98ed, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010, + 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1b5, 0xb931, 0xbb29, + 0xb1b5, 0xbbbf, 0xb4ce, 0xb1b5, 0xb1b5, 0xb8b3, 0xc12f, 0xb1b5, + 0xb1b5, 0xb1b5, 0xb1b5, 0xb1b5, 0xb1b5, 0x080c, 0x0dc5, 0x0066, + 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, + 0xb1d0, 0xc7fc, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0, + 0xc793, 0xc97e, 0xb1d0, 0xc83d, 0xc8bc, 0xc83d, 0xc8bc, 0xb1d0, + 0x080c, 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0dc5, 0x6000, + 0x0002, 0xb1e9, 0xc176, 0xc23e, 0xc371, 0xc520, 0xb1e9, 0xb1e9, + 0xb1e9, 0xc14a, 0xc71f, 0xc722, 0xb1e9, 0xb1e9, 0xb1e9, 0xb1e9, + 0xc751, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, + 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb204, 0xb204, 0xb247, 0xb2e6, + 0xb37b, 0xb204, 0xb204, 0xb204, 0xb206, 0xb204, 0xb204, 0xb204, + 0xb204, 0xb204, 0xb204, 0xb204, 0x080c, 0x0dc5, 0x9186, 0x004c, + 0x0588, 0x9186, 0x0003, 0x190c, 0x0dc5, 0x0096, 0x601c, 0xc0ed, + 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, + 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006, + 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, + 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c, + 0x1c09, 0x080c, 0x93a0, 0x0126, 0x2091, 0x8000, 0x080c, 0x9a0f, + 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, + 0x080c, 0xb39d, 0x080c, 0xd579, 0x6003, 0x0007, 0x0005, 0x00d6, + 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048, 0xa87c, + 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, + 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, + 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, + 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, + 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, + 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, + 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, + 0x0002, 0xb2ae, 0xb2ae, 0xb2a9, 0xb2ac, 0xb2ae, 0xb2a6, 0xb299, + 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, + 0xb299, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, + 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dc5, 0x080c, 0xbd80, + 0x0028, 0x080c, 0xbe67, 0x0010, 0x080c, 0xbf5d, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, + 0xb45b, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, + 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, + 0x126c, 0x080c, 0xb61f, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, + 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0xb101, + 0x2001, 0x002c, 0x900e, 0x080c, 0xb4c1, 0x0c70, 0x91b6, 0x0015, + 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0dc5, + 0x91b2, 0x0050, 0x1a0c, 0x0dc5, 0x9182, 0x0047, 0x00ca, 0x2001, + 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x080c, 0x92ed, 0x002e, 0x001e, 0x000e, 0x012e, + 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb247, 0x0005, + 0xb319, 0xb319, 0xb31b, 0xb351, 0xb319, 0xb319, 0xb319, 0xb319, + 0xb364, 0x080c, 0x0dc5, 0x00d6, 0x0016, 0x0096, 0x080c, 0x989d, + 0x080c, 0x9a0f, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, + 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, + 0x2001, 0x0000, 0x900e, 0x080c, 0xb4c1, 0x080c, 0xb101, 0x00a8, + 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, + 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, + 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, + 0x0005, 0x080c, 0x989d, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, + 0xce56, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6dd1, 0x009e, 0x00de, + 0x080c, 0xb101, 0x0804, 0x9a0f, 0x080c, 0x989d, 0x080c, 0x3246, + 0x080c, 0xd576, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56, + 0x0120, 0xa87b, 0x0029, 0x080c, 0x6dd1, 0x009e, 0x00de, 0x080c, + 0xb101, 0x0804, 0x9a0f, 0x9182, 0x0047, 0x0002, 0xb38b, 0xb38d, + 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, + 0xb38b, 0xb38b, 0xb38d, 0x080c, 0x0dc5, 0x00d6, 0x0096, 0x601f, + 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, + 0x6dd1, 0x009e, 0x00de, 0x0804, 0xb101, 0x0026, 0x0036, 0x0056, + 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x100e, 0x000e, + 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, + 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x7990, + 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, + 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, + 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xca03, 0x04c0, 0x2130, + 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xca03, 0x96b2, 0x0034, + 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e, 0x01d0, + 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, + 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xca03, 0x00b8, + 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, + 0xca03, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, + 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, + 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, + 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6dd1, 0x000e, + 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, + 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, - 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, - 0x1800, 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, - 0x2950, 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, - 0x0001, 0x9182, 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xcc85, - 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xcc85, - 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, - 0x100e, 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, - 0xb406, 0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, - 0xcc85, 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, - 0x001b, 0x080c, 0xcc85, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, - 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, - 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, - 0x0050, 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, - 0x6e9f, 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, - 0x006e, 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, - 0x0006, 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, - 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, - 0xaa66, 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, - 0x9182, 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, - 0xac76, 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, - 0x200c, 0x918d, 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, - 0x6e9f, 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, - 0x0096, 0x0016, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, - 0x001e, 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, - 0x000c, 0x2098, 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, - 0x2011, 0x0020, 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, - 0x100e, 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, - 0xa85c, 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, - 0x2009, 0x0280, 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, - 0x2200, 0x9402, 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, - 0x2020, 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, - 0x83ff, 0x0180, 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, - 0x9085, 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb642, - 0x0804, 0xb644, 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, - 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, - 0xa87a, 0xa982, 0x080c, 0x6e92, 0x009e, 0x003e, 0x00de, 0x0005, - 0x91b6, 0x0015, 0x1118, 0x080c, 0xb2d3, 0x0030, 0x91b6, 0x0016, - 0x190c, 0x0dc5, 0x080c, 0xb2d3, 0x0005, 0x20a9, 0x000e, 0x20e1, - 0x0000, 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, - 0x20a0, 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, - 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, - 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, - 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, - 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, 0xd0d8, 0x0130, - 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, - 0xb2d3, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, - 0x6010, 0x00b6, 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005, - 0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, - 0xb2d3, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, - 0x0006, 0x0016, 0x080c, 0xd7e3, 0x0188, 0x6014, 0x9005, 0x1170, - 0x600b, 0x0003, 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, - 0x080c, 0xbadd, 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, - 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, - 0x0000, 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, - 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, - 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, - 0x0205, 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, - 0x2003, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, - 0x080c, 0xb2d3, 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, - 0x7030, 0x9086, 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, - 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, - 0x2011, 0x0002, 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xcc85, - 0x080c, 0xd0d8, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, - 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb2d3, 0x001e, 0x009e, 0x0005, - 0x0016, 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, - 0x0001, 0x0096, 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa97a, 0x080c, - 0x6e9f, 0x009e, 0x080c, 0xb2d3, 0x001e, 0x0005, 0x0016, 0x0096, - 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, - 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, - 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xcc85, 0x009e, - 0x080c, 0xd0d8, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, - 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb2d3, 0x009e, 0x001e, - 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, - 0x080c, 0xbcb6, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, - 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, - 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, - 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x0019, 0x0d08, 0x008e, - 0x0898, 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x01b0, 0xa8ab, - 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, - 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, - 0x080c, 0x10f8, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, - 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, - 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, - 0xba14, 0x00be, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, - 0x2009, 0x0035, 0x080c, 0xd759, 0x001e, 0x1158, 0x622c, 0x2268, - 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, - 0x0128, 0x080c, 0xb2d3, 0x0020, 0x0039, 0x0010, 0x080c, 0xb910, - 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, - 0x0015, 0x0904, 0xb8f8, 0x918e, 0x0016, 0x1904, 0xb90e, 0x700c, - 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, - 0xb8d2, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb8b5, - 0x0804, 0xb90c, 0x6808, 0x9086, 0xffff, 0x1904, 0xb8fa, 0xa87c, - 0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, - 0x1904, 0xb8fa, 0x6824, 0xd084, 0x1904, 0xb8fa, 0xd0b4, 0x0158, - 0x0016, 0x2001, 0x1986, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, - 0x001e, 0x1a04, 0xb8fa, 0x080c, 0xd2c3, 0x685c, 0xa882, 0xa87c, - 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, - 0x000a, 0x080c, 0x9375, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, - 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xcde3, 0x00ce, - 0x0804, 0xb90c, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x61c2, - 0x0010, 0x080c, 0x65cf, 0x00ce, 0x1904, 0xb8fa, 0x00c6, 0x2d60, - 0x080c, 0xb2d3, 0x00ce, 0x0804, 0xb90c, 0x00c6, 0x080c, 0xb325, - 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xd554, 0x6023, - 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0xb2d3, 0x00ce, 0x080c, - 0xb352, 0x00ce, 0x0804, 0xb90c, 0x2001, 0x1988, 0x2004, 0x6842, - 0x00ce, 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, - 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, - 0x0003, 0x080c, 0xd79d, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, - 0x0002, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x00ce, 0x00e8, 0x700c, - 0x9086, 0x2a00, 0x1138, 0x2001, 0x1988, 0x2004, 0x6842, 0x00a0, - 0x0479, 0x00a0, 0x89ff, 0x090c, 0x0dc5, 0x00c6, 0x00d6, 0x2d60, - 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x6cb9, 0x080c, 0xd2c3, - 0x080c, 0xb306, 0x00de, 0x00ce, 0x080c, 0xb2d3, 0x009e, 0x0005, - 0x9186, 0x0015, 0x1128, 0x2001, 0x1988, 0x2004, 0x6842, 0x0068, - 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xee87, - 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x00ce, 0x080c, 0xb2d3, 0x0005, - 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, - 0x2001, 0x1988, 0x2004, 0x6842, 0x0804, 0xb98a, 0x00c6, 0x2d60, - 0x080c, 0xcce6, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, - 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x94ff, - 0x080c, 0x9ab1, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, - 0x89ff, 0x090c, 0x0dc5, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, - 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, - 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, - 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, - 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, - 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, - 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xd44b, 0x080c, - 0x9ab1, 0x0010, 0x080c, 0xb2d3, 0x004e, 0x003e, 0x002e, 0x0005, - 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, - 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xb9f5, 0x700c, 0x6210, - 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb9f5, 0x6038, - 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, - 0xb9f5, 0x9286, 0x0002, 0x0904, 0xb9f5, 0x9286, 0x0000, 0x05e8, - 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, - 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, - 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, - 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, - 0x0096, 0x2048, 0x080c, 0xd0d8, 0x090c, 0x0dc5, 0xa87b, 0x0003, - 0x009e, 0x080c, 0xd79d, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, - 0x0002, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x00ce, 0x0030, 0x6038, - 0x2070, 0x2001, 0x1988, 0x2004, 0x7042, 0x080c, 0xb2d3, 0x002e, - 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, - 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, - 0xc48c, 0xbc02, 0x0470, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, - 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc379, - 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xba66, 0x0096, 0x0156, - 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, - 0x0004, 0x080c, 0xc379, 0x002e, 0x003e, 0x015e, 0x009e, 0x15b0, - 0x7238, 0xba0a, 0x733c, 0xbb0e, 0x83ff, 0x0118, 0xbc00, 0xc48d, - 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, - 0xb6dc, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, - 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, - 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, - 0x2041, 0x1252, 0x080c, 0xb7f1, 0x0130, 0x00fe, 0x009e, 0x080c, - 0xb2d3, 0x00be, 0x0005, 0x080c, 0xbcb6, 0x0cb8, 0x2b78, 0x00f6, - 0x080c, 0x3250, 0x080c, 0xd7f8, 0x00fe, 0x00c6, 0x080c, 0xb27d, - 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, - 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x666a, 0x080c, 0x6696, - 0x080c, 0x9547, 0x080c, 0x9ab1, 0x00ce, 0x0804, 0xba39, 0x2100, - 0x91b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b2, 0x0040, 0x1a04, 0xbaef, - 0x0002, 0xbadd, 0xbadd, 0xbad3, 0xbadd, 0xbadd, 0xbadd, 0xbad1, - 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, - 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, - 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, - 0xbadd, 0xbad1, 0xbadd, 0xbadd, 0xbad1, 0xbad1, 0xbad1, 0xbad1, - 0xbad1, 0xbad3, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, - 0xbad1, 0xbad1, 0xbad1, 0xbadd, 0xbadd, 0xbad1, 0xbad1, 0xbad1, - 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbadd, 0xbad1, - 0xbad1, 0x080c, 0x0dc5, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8cc, - 0xc08c, 0xb8ce, 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, - 0x9186, 0x0032, 0x0118, 0x080c, 0x9547, 0x0010, 0x080c, 0x94ff, - 0x0126, 0x2091, 0x8000, 0x080c, 0x9ab1, 0x012e, 0x0005, 0x2600, - 0x0002, 0xbadd, 0xbadd, 0xbb03, 0xbadd, 0xbadd, 0xbb03, 0xbb03, - 0xbb03, 0xbb03, 0xbadd, 0xbb03, 0xbadd, 0xbb03, 0xbadd, 0xbb03, - 0xbb03, 0xbb03, 0xbb03, 0x080c, 0x0dc5, 0x6004, 0x90b2, 0x0053, - 0x1a0c, 0x0dc5, 0x91b6, 0x0013, 0x0904, 0xbbd8, 0x91b6, 0x0027, - 0x1904, 0xbb82, 0x080c, 0x99a5, 0x6004, 0x080c, 0xd2cf, 0x01b0, - 0x080c, 0xd2e0, 0x01a8, 0x908e, 0x0021, 0x0904, 0xbb7f, 0x908e, - 0x0022, 0x1130, 0x080c, 0xb708, 0x0904, 0xbb7b, 0x0804, 0xbb7c, - 0x908e, 0x003d, 0x0904, 0xbb7f, 0x0804, 0xbb75, 0x080c, 0x3279, - 0x2001, 0x0007, 0x080c, 0x666a, 0x6010, 0x00b6, 0x2058, 0xb9a0, - 0x00be, 0x080c, 0xbcb6, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, - 0x2014, 0xc285, 0x080c, 0x7637, 0x1108, 0xc2ad, 0x2202, 0x0036, - 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xef94, 0x002e, 0x003e, - 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x96a4, - 0x0076, 0x903e, 0x080c, 0x9577, 0x6010, 0x00b6, 0x905d, 0x0100, - 0x00be, 0x2c08, 0x080c, 0xe91c, 0x007e, 0x003e, 0x002e, 0x001e, - 0x080c, 0xd7f8, 0x0016, 0x080c, 0xd54c, 0x080c, 0xb2d3, 0x001e, - 0x080c, 0x334c, 0x080c, 0x9ab1, 0x0030, 0x080c, 0xd54c, 0x080c, - 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x080c, 0xbcb6, 0x0cb0, 0x080c, - 0xbcf2, 0x0c98, 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, - 0x080c, 0xd809, 0x0d80, 0x6000, 0x9086, 0x0002, 0x0904, 0xbcfd, - 0x0c50, 0x9186, 0x0014, 0x1d38, 0x080c, 0x99a5, 0x6004, 0x908e, - 0x0022, 0x1118, 0x080c, 0xb708, 0x09f0, 0x080c, 0x3250, 0x080c, - 0xd7f8, 0x080c, 0xd2cf, 0x1198, 0x080c, 0x3279, 0x6010, 0x00b6, - 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbcb6, 0x9186, 0x007e, 0x1128, - 0x2001, 0x1837, 0x200c, 0xc185, 0x2102, 0x0804, 0xbb75, 0x080c, - 0xd2e0, 0x1120, 0x080c, 0xbcb6, 0x0804, 0xbb75, 0x6004, 0x908e, - 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, - 0x080c, 0x35e7, 0x00fe, 0x00ee, 0x0804, 0xbb75, 0x6004, 0x908e, - 0x0021, 0x0d40, 0x908e, 0x0022, 0x090c, 0xbcb6, 0x0804, 0xbb75, - 0x90b2, 0x0040, 0x1a04, 0xbc92, 0x2008, 0x0002, 0xbc20, 0xbc21, - 0xbc24, 0xbc27, 0xbc2a, 0xbc37, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, - 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, - 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, - 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc3a, 0xbc47, 0xbc1e, 0xbc49, - 0xbc47, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc47, 0xbc47, - 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, - 0xbc79, 0xbc47, 0xbc1e, 0xbc43, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc44, - 0xbc1e, 0xbc1e, 0xbc1e, 0xbc47, 0xbc70, 0xbc1e, 0x080c, 0x0dc5, - 0x0430, 0x2001, 0x000b, 0x0470, 0x2001, 0x0003, 0x0458, 0x2001, - 0x0005, 0x0440, 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, - 0x00ff, 0x9086, 0x0000, 0x1500, 0x2001, 0x0001, 0x00d8, 0x2001, - 0x0009, 0x00c0, 0x080c, 0x99a5, 0x6003, 0x0005, 0x080c, 0xd7fb, - 0x080c, 0x9ab1, 0x0070, 0x0018, 0x0010, 0x080c, 0x666a, 0x0804, - 0xbc8a, 0x080c, 0x99a5, 0x080c, 0xd7fb, 0x6003, 0x0004, 0x080c, - 0x9ab1, 0x0005, 0x080c, 0x666a, 0x080c, 0x99a5, 0x6003, 0x0002, - 0x0036, 0x2019, 0x1852, 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, - 0x1986, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, - 0x801b, 0x831b, 0x9318, 0x631a, 0x003e, 0x080c, 0x9ab1, 0x0c08, - 0x080c, 0x99a5, 0x080c, 0xd54c, 0x080c, 0xb2d3, 0x080c, 0x9ab1, - 0x08c0, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, - 0x35e7, 0x00fe, 0x00ee, 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x080c, - 0x9ab1, 0x0838, 0x080c, 0x99a5, 0x6003, 0x0002, 0x080c, 0xd7fb, - 0x0804, 0x9ab1, 0x2600, 0x2008, 0x0002, 0xbca9, 0xbc8a, 0xbca7, - 0xbc8a, 0xbc8a, 0xbca7, 0xbca7, 0xbca7, 0xbca7, 0xbc8a, 0xbca7, - 0xbc8a, 0xbca7, 0xbc8a, 0xbca7, 0xbca7, 0xbca7, 0xbca7, 0x080c, - 0x0dc5, 0x080c, 0x99a5, 0x0096, 0x6014, 0x2048, 0x080c, 0x6e9f, - 0x009e, 0x080c, 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x00e6, 0x0096, - 0x0026, 0x0016, 0x080c, 0xd0d8, 0x0568, 0x6014, 0x2048, 0xa864, - 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, - 0x556f, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, - 0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xd6bd, 0x0090, - 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, - 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, - 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, - 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, - 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, - 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x6604, - 0x96b6, 0x004d, 0x1120, 0x080c, 0xd5dc, 0x0804, 0xbd82, 0x6604, - 0x96b6, 0x0043, 0x1120, 0x080c, 0xd625, 0x0804, 0xbd82, 0x6604, - 0x96b6, 0x004b, 0x1120, 0x080c, 0xd651, 0x0804, 0xbd82, 0x6604, - 0x96b6, 0x0033, 0x1120, 0x080c, 0xd56e, 0x0804, 0xbd82, 0x6604, - 0x96b6, 0x0028, 0x1120, 0x080c, 0xd31e, 0x0804, 0xbd82, 0x6604, - 0x96b6, 0x0029, 0x1120, 0x080c, 0xd35f, 0x0804, 0xbd82, 0x6604, - 0x96b6, 0x001f, 0x1120, 0x080c, 0xb6ad, 0x0804, 0xbd82, 0x6604, - 0x96b6, 0x0000, 0x1118, 0x080c, 0xb9fb, 0x04e0, 0x6604, 0x96b6, - 0x0022, 0x1118, 0x080c, 0xb6e9, 0x04a8, 0x6604, 0x96b6, 0x0035, - 0x1118, 0x080c, 0xb80f, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, - 0x080c, 0xb990, 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, - 0xb721, 0x0400, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb75d, - 0x00c8, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xb79e, 0x0090, - 0x6604, 0x96b6, 0x0041, 0x1118, 0x080c, 0xb788, 0x0058, 0x91b6, - 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, - 0x0804, 0xc08e, 0x00be, 0x0005, 0x080c, 0xb36d, 0x0cd8, 0xbd9f, - 0xbdad, 0xbd9f, 0xbdf4, 0xbd9f, 0xbfab, 0xc09b, 0xbd9f, 0xbd9f, - 0xc064, 0xbd9f, 0xc07a, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, - 0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0xb2d3, 0xa001, - 0xa001, 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, - 0x080c, 0x6656, 0x0804, 0xb2d3, 0x0005, 0x00e6, 0x2071, 0x1800, - 0x7090, 0x9086, 0x0074, 0x1540, 0x080c, 0xe8ed, 0x11b0, 0x6010, - 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, - 0xc0c5, 0xb802, 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, 0x666a, - 0x080c, 0x3279, 0x080c, 0xb2d3, 0x0098, 0x2001, 0x000a, 0x080c, - 0x666a, 0x080c, 0x3279, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, - 0x9547, 0x080c, 0x9ab1, 0x0020, 0x2001, 0x0001, 0x080c, 0xbf7b, - 0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, - 0x6656, 0x2069, 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, - 0x080c, 0x6696, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, - 0x1824, 0x2204, 0x9086, 0x0074, 0x1904, 0xbf50, 0x6010, 0x2058, - 0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xc1ea, 0x0804, 0xbebd, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x0904, 0xbe5f, 0x00d6, 0x080c, - 0x7637, 0x01a0, 0x0026, 0x2011, 0x0010, 0x080c, 0x6ac7, 0x002e, - 0x0904, 0xbe5e, 0x080c, 0x57e9, 0x1598, 0x6014, 0x2048, 0xa807, - 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, - 0x2058, 0xb910, 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, - 0x8008, 0x080c, 0x6ac7, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, - 0x0dc5, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, - 0x2001, 0x0030, 0x900e, 0x2011, 0x4009, 0x080c, 0xd6bd, 0x0040, - 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, - 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c, 0x3279, 0x080c, 0xb2d3, - 0x001e, 0x080c, 0x334c, 0x00de, 0x0804, 0xbf55, 0x00de, 0x080c, - 0xc1df, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, - 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, - 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd6bd, - 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, - 0x0006, 0x080c, 0x666a, 0x080c, 0x3279, 0x080c, 0xb2d3, 0x0804, - 0xbf55, 0x080c, 0xbf63, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, - 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, - 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd6bd, 0x08f8, - 0x080c, 0xbf59, 0x0160, 0x9006, 0x080c, 0x6656, 0x2001, 0x0004, - 0x080c, 0x6696, 0x2001, 0x0007, 0x080c, 0x666a, 0x08a0, 0x2001, - 0x0004, 0x080c, 0x666a, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, - 0x9547, 0x080c, 0x9ab1, 0x0804, 0xbf55, 0xb85c, 0xd0e4, 0x0178, - 0x080c, 0xd4ee, 0x080c, 0x7637, 0x0118, 0xd0dc, 0x1904, 0xbe7f, - 0x2011, 0x1837, 0x2204, 0xc0ad, 0x2012, 0x0804, 0xbe7f, 0x080c, - 0xd52b, 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, - 0xeab9, 0x000e, 0x1904, 0xbe7f, 0xc0b5, 0x2012, 0x2001, 0x0006, - 0x080c, 0x666a, 0x9006, 0x080c, 0x6656, 0x00c6, 0x2001, 0x180f, - 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, - 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, - 0x7082, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, - 0x080c, 0x28bc, 0x00f6, 0x2100, 0x900e, 0x080c, 0x2873, 0x795e, - 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, - 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, - 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x28bc, 0x00f6, - 0x2079, 0x1800, 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x2873, - 0x795e, 0x00fe, 0x8108, 0x080c, 0x66b9, 0x2b00, 0x00ce, 0x1904, - 0xbe7f, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, - 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, - 0xb916, 0x2001, 0x0002, 0x080c, 0x666a, 0x6023, 0x0001, 0x6003, - 0x0001, 0x6007, 0x0002, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0028, - 0x080c, 0xbcb6, 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, - 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, - 0x2004, 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xefed, 0x0190, 0x2071, - 0x0260, 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, - 0x0140, 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, - 0xba16, 0x00ee, 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, - 0x080c, 0x666a, 0x080c, 0x57e9, 0x1120, 0x2001, 0x0007, 0x080c, - 0x6696, 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, - 0x009e, 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, - 0xbba0, 0x00be, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4c44, - 0x004e, 0x003e, 0x080c, 0x3279, 0x6020, 0x9086, 0x000a, 0x1108, - 0x0005, 0x0804, 0xb2d3, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, - 0x1800, 0x7090, 0x9086, 0x0014, 0x1904, 0xc05a, 0x2001, 0x180d, - 0x2004, 0xd08c, 0x0904, 0xc00d, 0x00d6, 0x080c, 0x7637, 0x01a0, - 0x0026, 0x2011, 0x0010, 0x080c, 0x6ac7, 0x002e, 0x0904, 0xc00c, - 0x080c, 0x57e9, 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, - 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, - 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, - 0x6ac7, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, 0x0dc5, 0x2048, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, - 0x900e, 0x2011, 0x4009, 0x080c, 0xd6bd, 0x0040, 0x6014, 0x2048, - 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, - 0xb9a0, 0x0016, 0x080c, 0x3279, 0x080c, 0xb2d3, 0x001e, 0x080c, - 0x334c, 0x00de, 0x0804, 0xc05f, 0x00de, 0x080c, 0x57e9, 0x1170, - 0x6014, 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, - 0x2021, 0x0006, 0x080c, 0x4dfb, 0x004e, 0x003e, 0x00d6, 0x6010, - 0x2058, 0x080c, 0x67bf, 0x080c, 0xbde2, 0x00de, 0x080c, 0xc2b5, - 0x1588, 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, - 0x080c, 0x666a, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, - 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, - 0x4000, 0x080c, 0xd6bd, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, - 0x0029, 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, - 0x009e, 0x080c, 0x3279, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, - 0xb2d3, 0x0028, 0x080c, 0xbcb6, 0x9006, 0x080c, 0xbf7b, 0x001e, - 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, - 0x0014, 0x1160, 0x2001, 0x0002, 0x080c, 0x666a, 0x6003, 0x0001, - 0x6007, 0x0001, 0x080c, 0x9547, 0x0804, 0x9ab1, 0x2001, 0x0001, - 0x0804, 0xbf7b, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, - 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x666a, - 0x0804, 0xb2d3, 0x2001, 0x0001, 0x0804, 0xbf7b, 0x0002, 0xbd9f, - 0xc0a6, 0xbd9f, 0xc0e9, 0xbd9f, 0xc196, 0xc09b, 0xbda2, 0xbd9f, - 0xc1aa, 0xbd9f, 0xc1bc, 0x6604, 0x9686, 0x0003, 0x0904, 0xbfab, - 0x96b6, 0x001e, 0x1110, 0x080c, 0xb2d3, 0x0005, 0x00b6, 0x00d6, - 0x00c6, 0x080c, 0xc1ce, 0x11a0, 0x9006, 0x080c, 0x6656, 0x080c, - 0x3250, 0x080c, 0xd7f8, 0x2001, 0x0002, 0x080c, 0x666a, 0x6003, - 0x0001, 0x6007, 0x0002, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0428, - 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, - 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, - 0x000a, 0x0098, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, - 0x1900, 0x0158, 0x908e, 0x1e00, 0x0990, 0x080c, 0x3250, 0x080c, - 0xd7f8, 0x2001, 0x0001, 0x080c, 0xbf7b, 0x00ce, 0x00de, 0x00be, - 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xc1dc, 0x00d6, - 0x2069, 0x197c, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, - 0x9086, 0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, - 0x00de, 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x6656, 0x2001, - 0x0002, 0x080c, 0x666a, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, - 0x9547, 0x080c, 0x9ab1, 0x0804, 0xc166, 0x080c, 0xd0d8, 0x01b0, - 0x6014, 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, - 0x0016, 0x2001, 0x0002, 0x080c, 0xd71a, 0x00b0, 0x6014, 0x2048, - 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, - 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, - 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c, 0xbcb6, 0x2009, 0x026e, - 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, - 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, - 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, - 0x2001, 0x0004, 0x080c, 0x666a, 0x2001, 0x0028, 0x601a, 0x6007, - 0x0052, 0x0020, 0x2001, 0x0001, 0x080c, 0xbf7b, 0x002e, 0x00be, - 0x009e, 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, - 0xd0d8, 0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, - 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, - 0x0138, 0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, - 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, - 0x60c1, 0x00ee, 0x0010, 0x080c, 0x3250, 0x0860, 0x2001, 0x0004, - 0x080c, 0x666a, 0x080c, 0xc1dc, 0x1140, 0x6003, 0x0001, 0x6007, - 0x0003, 0x080c, 0x9547, 0x0804, 0x9ab1, 0x080c, 0xbcb6, 0x9006, - 0x0804, 0xbf7b, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x666a, - 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x9547, 0x0804, 0x9ab1, - 0x2001, 0x0001, 0x0804, 0xbf7b, 0x00f9, 0x1160, 0x2001, 0x000a, - 0x080c, 0x666a, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9547, - 0x0804, 0x9ab1, 0x2001, 0x0001, 0x0804, 0xbf7b, 0x2009, 0x026e, - 0x2104, 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, - 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, - 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c, 0x6733, 0x001e, 0x00ce, - 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, - 0x6010, 0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, - 0x080c, 0xc287, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, - 0x080c, 0x6a9f, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, - 0xec31, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, - 0x2009, 0x0001, 0x080c, 0x321b, 0x00e6, 0x2071, 0x1800, 0x080c, - 0x3000, 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, - 0x080c, 0x334c, 0x8108, 0x1f04, 0xc220, 0x015e, 0x00ce, 0x080c, - 0xc1df, 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, - 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, - 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, - 0x2102, 0x9184, 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, - 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, - 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, - 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, - 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x28bc, 0x080c, 0x7637, - 0x0170, 0x2071, 0x0260, 0x2069, 0x1982, 0x7048, 0x206a, 0x704c, - 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xd4ee, 0x0040, - 0x2001, 0x0006, 0x080c, 0x666a, 0x080c, 0x3279, 0x080c, 0xb2d3, - 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, - 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, - 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, - 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, - 0x2b48, 0x2019, 0x000a, 0x080c, 0xc379, 0x1148, 0x2011, 0x027a, - 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xc379, 0x1100, 0x015e, - 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, - 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, - 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, - 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, - 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, - 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f1, - 0x252c, 0x2021, 0x19f7, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, - 0x7254, 0x7074, 0x9202, 0x1a04, 0xc345, 0x080c, 0x8cf7, 0x0904, - 0xc33e, 0x080c, 0xec62, 0x0904, 0xc33e, 0x6720, 0x9786, 0x0007, - 0x0904, 0xc33e, 0x2500, 0x9c06, 0x0904, 0xc33e, 0x2400, 0x9c06, - 0x05e8, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, - 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, - 0x9086, 0x0004, 0x1110, 0x080c, 0x1a8e, 0x9786, 0x000a, 0x0148, - 0x080c, 0xd2e0, 0x1130, 0x00ce, 0x080c, 0xbcb6, 0x080c, 0xb306, - 0x00e8, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x01a8, 0x9786, 0x0003, - 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, - 0x2048, 0x080c, 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, - 0x6e92, 0x080c, 0xd2c3, 0x080c, 0xb306, 0x00ce, 0x9ce0, 0x0018, - 0x7068, 0x9c02, 0x1210, 0x0804, 0xc2e8, 0x012e, 0x000e, 0x002e, - 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, - 0x0006, 0x1118, 0x080c, 0xebd4, 0x0c30, 0x9786, 0x0009, 0x1148, - 0x6000, 0x9086, 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xb352, - 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, 0x220c, 0x2304, 0x9106, - 0x1130, 0x8210, 0x8318, 0x1f04, 0xc365, 0x9006, 0x0005, 0x2304, - 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, - 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, - 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, - 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, - 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, - 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, - 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, 0x2304, 0x9106, 0x1130, - 0x8210, 0x8318, 0x1f04, 0xc3a3, 0x9006, 0x0005, 0x918d, 0x0001, - 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0xd2cf, - 0x0120, 0x080c, 0xd2e0, 0x0168, 0x0028, 0x080c, 0x3279, 0x080c, - 0xd2e0, 0x0138, 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x080c, 0x9ab1, - 0x0005, 0x080c, 0xbcb6, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, - 0x0040, 0x0208, 0x000a, 0x0005, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, - 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3ea, - 0xc3ea, 0xc3ea, 0xc3ea, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3ea, 0xc3e8, - 0x080c, 0x0dc5, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, - 0x94ff, 0x0126, 0x2091, 0x8000, 0x080c, 0x9ab1, 0x012e, 0x0005, - 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc482, - 0x9186, 0x0027, 0x1520, 0x080c, 0x99a5, 0x080c, 0x3250, 0x080c, - 0xd7f8, 0x0096, 0x6114, 0x2148, 0x080c, 0xd0d8, 0x0198, 0x080c, - 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0068, 0xa867, 0x0103, 0xa87b, - 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6e9f, - 0x080c, 0xd2c3, 0x009e, 0x080c, 0xb2d3, 0x0804, 0x9ab1, 0x9186, - 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046, - 0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186, - 0x0048, 0x190c, 0x0dc5, 0x080c, 0xd809, 0x0130, 0x6000, 0x9086, - 0x0002, 0x1110, 0x0804, 0xc4c0, 0x0005, 0x0002, 0xc45c, 0xc45a, - 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, - 0xc45a, 0xc477, 0xc477, 0xc477, 0xc477, 0xc45a, 0xc477, 0xc45a, - 0xc477, 0xc45a, 0x080c, 0x0dc5, 0x080c, 0x99a5, 0x0096, 0x6114, - 0x2148, 0x080c, 0xd0d8, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, - 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6e9f, 0x080c, - 0xd2c3, 0x009e, 0x080c, 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x080c, - 0x99a5, 0x080c, 0xd2e0, 0x090c, 0xbcb6, 0x080c, 0xb2d3, 0x080c, - 0x9ab1, 0x0005, 0x0002, 0xc499, 0xc497, 0xc497, 0xc497, 0xc497, - 0xc497, 0xc497, 0xc497, 0xc497, 0xc497, 0xc497, 0xc4b0, 0xc4b0, - 0xc4b0, 0xc4b0, 0xc497, 0xc4ba, 0xc497, 0xc4b0, 0xc497, 0x080c, - 0x0dc5, 0x0096, 0x080c, 0x99a5, 0x6014, 0x2048, 0x2001, 0x1988, - 0x2004, 0x6042, 0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, - 0x9085, 0x0400, 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, - 0x080c, 0x99a5, 0x080c, 0xd7fb, 0x080c, 0xd800, 0x6003, 0x000f, - 0x0804, 0x9ab1, 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x0804, 0x9ab1, - 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, - 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4de, 0xc5be, 0xc4dc, - 0xc5f2, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, - 0xc4dc, 0xc4dc, 0xc4dc, 0xc5f2, 0x080c, 0x0dc5, 0x00b6, 0x0096, - 0x6114, 0x2148, 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, - 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc5ad, 0xa87b, 0x0000, 0xa867, - 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, - 0x190c, 0xc78b, 0x080c, 0x6cb9, 0x6210, 0x2258, 0xba3c, 0x82ff, - 0x0110, 0x8211, 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc58e, 0x080c, - 0xb2d3, 0x009e, 0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, - 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc592, 0x7348, 0xab92, 0x734c, - 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, - 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, - 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, - 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, - 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, - 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, - 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc4e5, - 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, - 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, - 0xcc85, 0x003e, 0xd6cc, 0x0904, 0xc4fa, 0x7154, 0xa98a, 0x81ff, - 0x0904, 0xc4fa, 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, - 0x2011, 0x0029, 0x080c, 0xcc85, 0x2011, 0x0205, 0x2013, 0x0000, - 0x080c, 0xd786, 0x0804, 0xc4fa, 0xa868, 0xd0fc, 0x0120, 0x2009, - 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c, 0xcc24, 0x00ae, - 0x080c, 0xd786, 0x080c, 0xcc75, 0x0804, 0xc4fc, 0x080c, 0xd3d8, - 0x0804, 0xc509, 0xa87c, 0xd0ac, 0x0904, 0xc515, 0xa880, 0xd0bc, - 0x1904, 0xc515, 0x9684, 0x0400, 0x0130, 0xa838, 0xab34, 0x9305, - 0x0904, 0xc515, 0x00b8, 0x7348, 0xa838, 0x9306, 0x1198, 0x734c, - 0xa834, 0x931e, 0x0904, 0xc515, 0x0068, 0xa87c, 0xd0ac, 0x0904, - 0xc4ed, 0xa838, 0xa934, 0x9105, 0x0904, 0xc4ed, 0xa880, 0xd0bc, - 0x1904, 0xc4ed, 0x080c, 0xd412, 0x0804, 0xc509, 0x0096, 0x00f6, - 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, 0x7b00, - 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, 0x6003, - 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, - 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, - 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, 0x6043, - 0x0000, 0x2c10, 0x080c, 0x1be0, 0x080c, 0x9564, 0x080c, 0x9bd3, - 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, - 0x0208, 0x000a, 0x0005, 0xc60f, 0xc60f, 0xc60f, 0xc60f, 0xc60f, - 0xc611, 0xc6a7, 0xc60f, 0xc60f, 0xc6be, 0xc74e, 0xc60f, 0xc60f, - 0xc60f, 0xc60f, 0xc763, 0xc60f, 0xc60f, 0xc60f, 0xc60f, 0x080c, - 0x0dc5, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, - 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, - 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, - 0x00be, 0x86ff, 0x0904, 0xc6a2, 0x9694, 0xff00, 0x9284, 0x0c00, - 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, - 0xc6a2, 0x080c, 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, - 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, - 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, - 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, - 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, - 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, - 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, - 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, - 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, - 0x080c, 0xcc85, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, - 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, - 0x0029, 0x080c, 0xcc85, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, - 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, - 0x080c, 0xcc24, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x00f6, - 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, - 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, 0x00ae, - 0x00fe, 0x2c10, 0x080c, 0x1be0, 0x0804, 0xa6b6, 0x6003, 0x0002, - 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, - 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, - 0x080c, 0x1768, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, - 0x009e, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0096, 0x2001, 0x1988, - 0x2004, 0x6042, 0x080c, 0x9a61, 0x080c, 0x9bd3, 0x6114, 0x2148, - 0xa97c, 0xd1e4, 0x0904, 0xc749, 0xd1cc, 0x05c8, 0xa978, 0xa868, - 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, 0x810f, - 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, 0x2098, - 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, 0x000e, - 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, - 0x001e, 0x0458, 0x0016, 0x080c, 0x0fc0, 0x009e, 0xa87c, 0xc0cc, - 0xa87e, 0xa974, 0x0016, 0x080c, 0xcc75, 0x001e, 0x00f0, 0xa867, - 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086, - 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0xa87b, - 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, - 0x0000, 0x0016, 0x080c, 0x6cb9, 0x001e, 0xd1e4, 0x1120, 0x080c, - 0xb2d3, 0x009e, 0x0005, 0x080c, 0xd3d8, 0x0cd8, 0x6004, 0x9086, - 0x0040, 0x1120, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x2019, 0x0001, - 0x080c, 0xaa49, 0x6003, 0x0002, 0x080c, 0xd800, 0x080c, 0x9a61, - 0x080c, 0x9bd3, 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, - 0x99a5, 0x080c, 0x9ab1, 0x2019, 0x0001, 0x080c, 0xaa49, 0x080c, - 0x9a61, 0x080c, 0x3250, 0x080c, 0xd7f8, 0x0096, 0x6114, 0x2148, - 0x080c, 0xd0d8, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, - 0x0000, 0x080c, 0x6e9f, 0x080c, 0xd2c3, 0x009e, 0x080c, 0xb2d3, - 0x080c, 0x9bd3, 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, - 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, - 0x2009, 0x1a7d, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, - 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, - 0x000a, 0x0005, 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc7c0, - 0xc7be, 0xc7be, 0xc866, 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc7be, - 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc998, 0x080c, 0x0dc5, - 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, - 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, - 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, - 0x86ff, 0x0904, 0xc85f, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, - 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc85f, - 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, - 0x0c38, 0x080c, 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, - 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, - 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, - 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, - 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, - 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, - 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, - 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, + 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, + 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, + 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, + 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, + 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6dd1, 0x009e, + 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, + 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, + 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, + 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, + 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x100e, 0x2900, + 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, + 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, + 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, + 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, + 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, + 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb470, 0x0804, 0xb472, + 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, + 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, + 0x080c, 0x6dc4, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, + 0x1118, 0x080c, 0xb101, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0dc5, + 0x080c, 0xb101, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, + 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, + 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, + 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, + 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, + 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, + 0x8211, 0x1db8, 0x0096, 0x080c, 0xce56, 0x0130, 0x6014, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xb101, 0x0096, + 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, + 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xb101, 0x003e, + 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, + 0x080c, 0xd561, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, + 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xb909, + 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, + 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, + 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, + 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, + 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, + 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, + 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0xb101, + 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, + 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, + 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, + 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xca03, 0x080c, 0xce56, + 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, + 0x0103, 0x080c, 0xb101, 0x001e, 0x009e, 0x0005, 0x0016, 0x2009, + 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001, 0x0096, + 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa97a, 0x080c, 0x6dd1, 0x009e, + 0x080c, 0xb101, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086, + 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b, + 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096, + 0x9005, 0x0108, 0x2048, 0x080c, 0xca03, 0x009e, 0x080c, 0xce56, + 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, + 0xa867, 0x0103, 0x080c, 0xb101, 0x009e, 0x001e, 0x0005, 0x0086, + 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xbae2, + 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, + 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, + 0x0000, 0x2041, 0x1252, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, + 0x0006, 0x080c, 0x100e, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, + 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, + 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x10f8, + 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, + 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, + 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, + 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, + 0x080c, 0xd4d7, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c, + 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c, + 0xb101, 0x0020, 0x0039, 0x0010, 0x080c, 0xb73e, 0x002e, 0x00de, + 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904, + 0xb726, 0x918e, 0x0016, 0x1904, 0xb73c, 0x700c, 0x908c, 0xff00, + 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb700, 0x89ff, + 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb6e3, 0x0804, 0xb73a, + 0x6808, 0x9086, 0xffff, 0x1904, 0xb728, 0xa87c, 0x9084, 0x0060, + 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, 0xb728, + 0x6824, 0xd084, 0x1904, 0xb728, 0xd0b4, 0x0158, 0x0016, 0x2001, + 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04, + 0xb728, 0x080c, 0xd041, 0x685c, 0xa882, 0xa87c, 0xc0dc, 0xc0f4, + 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c, + 0x91b1, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e, + 0x1138, 0x00c6, 0x2d60, 0x080c, 0xcb65, 0x00ce, 0x0804, 0xb73a, + 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x61bb, 0x0010, 0x080c, + 0x65c8, 0x00ce, 0x1904, 0xb728, 0x00c6, 0x2d60, 0x080c, 0xb101, + 0x00ce, 0x0804, 0xb73a, 0x00c6, 0x080c, 0xb153, 0x0198, 0x6017, + 0x0000, 0x6810, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0003, 0x6904, + 0x00c6, 0x2d60, 0x080c, 0xb101, 0x00ce, 0x080c, 0xb180, 0x00ce, + 0x0804, 0xb73a, 0x2001, 0x1989, 0x2004, 0x6842, 0x00ce, 0x04d0, + 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, + 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, + 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, + 0x933b, 0x080c, 0x98ed, 0x00ce, 0x00e8, 0x700c, 0x9086, 0x2a00, + 0x1138, 0x2001, 0x1989, 0x2004, 0x6842, 0x00a0, 0x0479, 0x00a0, + 0x89ff, 0x090c, 0x0dc5, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, + 0xa87b, 0x0003, 0x080c, 0x6beb, 0x080c, 0xd041, 0x080c, 0xb134, + 0x00de, 0x00ce, 0x080c, 0xb101, 0x009e, 0x0005, 0x9186, 0x0015, + 0x1128, 0x2001, 0x1989, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016, + 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xec02, 0x080c, 0x88f1, + 0x080c, 0xb101, 0x00ce, 0x080c, 0xb101, 0x0005, 0x0026, 0x0036, + 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1989, + 0x2004, 0x6842, 0x0804, 0xb7b8, 0x00c6, 0x2d60, 0x080c, 0xca64, + 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, + 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, + 0x0dc5, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178, + 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001, + 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c, + 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838, + 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306, + 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a, + 0x2001, 0x0005, 0x6832, 0x080c, 0xd1c9, 0x080c, 0x98ed, 0x0010, + 0x080c, 0xb101, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, + 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, + 0x00be, 0x9206, 0x1904, 0xb823, 0x700c, 0x6210, 0x00b6, 0x2258, + 0xba14, 0x00be, 0x9206, 0x1904, 0xb823, 0x6038, 0x2068, 0x6824, + 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb823, 0x9286, + 0x0002, 0x0904, 0xb823, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c, + 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e, + 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b, + 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186, + 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048, + 0x080c, 0xce56, 0x090c, 0x0dc5, 0xa87b, 0x0003, 0x009e, 0x080c, + 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, + 0x933b, 0x080c, 0x98ed, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, + 0x1989, 0x2004, 0x7042, 0x080c, 0xb101, 0x002e, 0x00de, 0x00ee, + 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058, + 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02, + 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010, + 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc0f7, 0x002e, 0x003e, + 0x015e, 0x009e, 0x1904, 0xb892, 0x0096, 0x0156, 0x0036, 0x0026, + 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, + 0xc0f7, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, + 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, + 0x00fe, 0x009e, 0x00be, 0x0804, 0xb50a, 0x0096, 0x2048, 0xaa12, + 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, + 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, 0xb61f, + 0x0130, 0x00fe, 0x009e, 0x080c, 0xb101, 0x00be, 0x0005, 0x080c, + 0xbae2, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x3246, 0x080c, 0xd576, + 0x00fe, 0x00c6, 0x080c, 0xb0ab, 0x2f00, 0x6012, 0x6017, 0x0000, + 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, + 0x080c, 0x6663, 0x080c, 0x668f, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x00ce, 0x0804, 0xb865, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0dc5, + 0x91b2, 0x0040, 0x1a04, 0xb91b, 0x0002, 0xb909, 0xb909, 0xb8ff, + 0xb909, 0xb909, 0xb909, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb909, 0xb8fd, 0xb909, 0xb909, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8ff, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb909, + 0xb909, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, + 0xb8fd, 0xb8fd, 0xb909, 0xb8fd, 0xb8fd, 0x080c, 0x0dc5, 0x0066, + 0x00b6, 0x6610, 0x2658, 0xb8cc, 0xc08c, 0xb8ce, 0x00be, 0x006e, + 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, + 0x9383, 0x0010, 0x080c, 0x933b, 0x0126, 0x2091, 0x8000, 0x080c, + 0x98ed, 0x012e, 0x0005, 0x2600, 0x0002, 0xb909, 0xb909, 0xb92f, + 0xb909, 0xb909, 0xb92f, 0xb92f, 0xb92f, 0xb92f, 0xb909, 0xb92f, + 0xb909, 0xb92f, 0xb909, 0xb92f, 0xb92f, 0xb92f, 0xb92f, 0x080c, + 0x0dc5, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6, 0x0013, + 0x0904, 0xba04, 0x91b6, 0x0027, 0x1904, 0xb9ae, 0x080c, 0x97e1, + 0x6004, 0x080c, 0xd04d, 0x01b0, 0x080c, 0xd05e, 0x01a8, 0x908e, + 0x0021, 0x0904, 0xb9ab, 0x908e, 0x0022, 0x1130, 0x080c, 0xb536, + 0x0904, 0xb9a7, 0x0804, 0xb9a8, 0x908e, 0x003d, 0x0904, 0xb9ab, + 0x0804, 0xb9a1, 0x080c, 0x326f, 0x2001, 0x0007, 0x080c, 0x6663, + 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbae2, 0x9186, + 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, 0xc285, 0x080c, 0x7569, + 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, + 0x080c, 0xed0f, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, + 0x2019, 0x0028, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, + 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xe690, + 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xd576, 0x0016, 0x080c, + 0xd2ca, 0x080c, 0xb101, 0x001e, 0x080c, 0x3342, 0x080c, 0x98ed, + 0x0030, 0x080c, 0xd2ca, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, + 0x080c, 0xbae2, 0x0cb0, 0x080c, 0xbb1e, 0x0c98, 0x9186, 0x0015, + 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xd587, 0x0d80, 0x6000, + 0x9086, 0x0002, 0x0904, 0xbb29, 0x0c50, 0x9186, 0x0014, 0x1d38, + 0x080c, 0x97e1, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb536, + 0x09f0, 0x080c, 0x3246, 0x080c, 0xd576, 0x080c, 0xd04d, 0x1198, + 0x080c, 0x326f, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, + 0xbae2, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185, + 0x2102, 0x0804, 0xb9a1, 0x080c, 0xd05e, 0x1120, 0x080c, 0xbae2, + 0x0804, 0xb9a1, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, + 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35dd, 0x00fe, 0x00ee, + 0x0804, 0xb9a1, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, + 0x090c, 0xbae2, 0x0804, 0xb9a1, 0x90b2, 0x0040, 0x1a04, 0xbabe, + 0x2008, 0x0002, 0xba4c, 0xba4d, 0xba50, 0xba53, 0xba56, 0xba63, + 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, + 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, + 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, + 0xba66, 0xba73, 0xba4a, 0xba75, 0xba73, 0xba4a, 0xba4a, 0xba4a, + 0xba4a, 0xba4a, 0xba73, 0xba73, 0xba4a, 0xba4a, 0xba4a, 0xba4a, + 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xbaa5, 0xba73, 0xba4a, 0xba6f, + 0xba4a, 0xba4a, 0xba4a, 0xba70, 0xba4a, 0xba4a, 0xba4a, 0xba73, + 0xba9c, 0xba4a, 0x080c, 0x0dc5, 0x0430, 0x2001, 0x000b, 0x0470, + 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010, 0x00b6, + 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x1500, + 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, 0x97e1, + 0x6003, 0x0005, 0x080c, 0xd579, 0x080c, 0x98ed, 0x0070, 0x0018, + 0x0010, 0x080c, 0x6663, 0x0804, 0xbab6, 0x080c, 0x97e1, 0x080c, + 0xd579, 0x6003, 0x0004, 0x080c, 0x98ed, 0x0005, 0x080c, 0x6663, + 0x080c, 0x97e1, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304, + 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040, 0x8007, + 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, + 0x003e, 0x080c, 0x98ed, 0x0c08, 0x080c, 0x97e1, 0x080c, 0xd2ca, + 0x080c, 0xb101, 0x080c, 0x98ed, 0x08c0, 0x00e6, 0x00f6, 0x2071, + 0x189e, 0x2079, 0x0000, 0x080c, 0x35dd, 0x00fe, 0x00ee, 0x080c, + 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0838, 0x080c, 0x97e1, + 0x6003, 0x0002, 0x080c, 0xd579, 0x0804, 0x98ed, 0x2600, 0x2008, + 0x0002, 0xbad5, 0xbab6, 0xbad3, 0xbab6, 0xbab6, 0xbad3, 0xbad3, + 0xbad3, 0xbad3, 0xbab6, 0xbad3, 0xbab6, 0xbad3, 0xbab6, 0xbad3, + 0xbad3, 0xbad3, 0xbad3, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x0096, + 0x6014, 0x2048, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c, + 0x98ed, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c, 0xce56, + 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, + 0x9086, 0x0056, 0x1148, 0x080c, 0x556d, 0x0130, 0x2001, 0x0000, + 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, + 0x4005, 0x080c, 0xd43b, 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, + 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, + 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, + 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, + 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, + 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, + 0x000c, 0x1a0c, 0x0dc5, 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, + 0xd35a, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, + 0xd3a3, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, + 0xd3cf, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, + 0xd2ec, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, + 0xd09c, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, + 0xd0dd, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x001f, 0x1120, 0x080c, + 0xb4db, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0000, 0x1118, 0x080c, + 0xb829, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c, 0xb517, + 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xb63d, 0x0470, + 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb7be, 0x0438, 0x6604, + 0x96b6, 0x003d, 0x1118, 0x080c, 0xb54f, 0x0400, 0x6604, 0x96b6, + 0x0044, 0x1118, 0x080c, 0xb58b, 0x00c8, 0x6604, 0x96b6, 0x0049, + 0x1118, 0x080c, 0xb5cc, 0x0090, 0x6604, 0x96b6, 0x0041, 0x1118, + 0x080c, 0xb5b6, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, + 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbe0c, 0x00be, 0x0005, + 0x080c, 0xb19b, 0x0cd8, 0xbbcb, 0xbbd9, 0xbbcb, 0xbc20, 0xbbcb, + 0xbd80, 0xbe19, 0xbbcb, 0xbbcb, 0xbde2, 0xbbcb, 0xbdf8, 0x0096, + 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, + 0x009e, 0x0804, 0xb101, 0xa001, 0xa001, 0x0005, 0x6604, 0x96b6, + 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x664f, 0x0804, 0xb101, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, 0x0074, 0x1540, + 0x080c, 0xe661, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, + 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9, 0x00be, + 0x2001, 0x0006, 0x080c, 0x6663, 0x080c, 0x326f, 0x080c, 0xb101, + 0x0098, 0x2001, 0x000a, 0x080c, 0x6663, 0x080c, 0x326f, 0x6003, + 0x0001, 0x6007, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0020, + 0x2001, 0x0001, 0x080c, 0xbd50, 0x00ee, 0x0005, 0x00d6, 0xb800, + 0xd084, 0x0160, 0x9006, 0x080c, 0x664f, 0x2069, 0x1847, 0x6804, + 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x668f, 0x00de, 0x0005, + 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, + 0x1904, 0xbd25, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120, + 0x080c, 0xbf68, 0x0804, 0xbc92, 0x080c, 0xbf5d, 0x6010, 0x2058, + 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, 0x2048, + 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, + 0x900e, 0x2011, 0x4000, 0x080c, 0xd43b, 0x0030, 0xa807, 0x0000, + 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c, 0x6663, + 0x080c, 0x326f, 0x080c, 0xb101, 0x0804, 0xbd2a, 0x080c, 0xbd38, + 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, 0x900e, + 0x2011, 0x4000, 0x080c, 0xd43b, 0x08f8, 0x080c, 0xbd2e, 0x0160, + 0x9006, 0x080c, 0x664f, 0x2001, 0x0004, 0x080c, 0x668f, 0x2001, + 0x0007, 0x080c, 0x6663, 0x08a0, 0x2001, 0x0004, 0x080c, 0x6663, + 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x0804, 0xbd2a, 0xb85c, 0xd0e4, 0x0178, 0x080c, 0xd26c, 0x080c, + 0x7569, 0x0118, 0xd0dc, 0x1904, 0xbc54, 0x2011, 0x1837, 0x2204, + 0xc0ad, 0x2012, 0x0804, 0xbc54, 0x080c, 0xd2a9, 0x2011, 0x1837, + 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe82d, 0x000e, 0x1904, + 0xbc54, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x6663, 0x9006, + 0x080c, 0x664f, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c, 0x0520, + 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c, 0x9084, + 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, 0x908c, 0x00ff, + 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x28dd, 0x00f6, + 0x2100, 0x900e, 0x080c, 0x2894, 0x795e, 0x00fe, 0x9186, 0x0081, + 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, 0x00f6, 0x2079, + 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, 0x780c, 0xc0b5, + 0x780e, 0x00fe, 0x080c, 0x28dd, 0x00f6, 0x2079, 0x1800, 0x7982, + 0x2100, 0x900e, 0x797e, 0x080c, 0x2894, 0x795e, 0x00fe, 0x8108, + 0x080c, 0x66b2, 0x2b00, 0x00ce, 0x1904, 0xbc54, 0x6012, 0x2009, + 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c, 0x918c, + 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001, 0x0002, + 0x080c, 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, + 0x080c, 0x9383, 0x080c, 0x98ed, 0x0028, 0x080c, 0xbae2, 0x2001, + 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, 0x1810, + 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac, 0x0005, + 0x00e6, 0x080c, 0xed68, 0x0190, 0x2071, 0x0260, 0x7108, 0x720c, + 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, 0x2058, + 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, 0x0005, + 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x6663, 0x080c, + 0x57e7, 0x1120, 0x2001, 0x0007, 0x080c, 0x668f, 0x2600, 0x9005, + 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x1178, + 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, + 0x0004, 0x2011, 0x8014, 0x080c, 0x4be9, 0x004e, 0x003e, 0x080c, + 0x326f, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0xb101, + 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090, 0x9086, + 0x0014, 0x1904, 0xbdd8, 0x080c, 0x57e7, 0x1170, 0x6014, 0x9005, + 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, + 0x080c, 0x4da0, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, + 0x67b8, 0x080c, 0xbc0e, 0x00de, 0x080c, 0xc033, 0x1588, 0x6010, + 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x6663, + 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, + 0xd43b, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, + 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, + 0x326f, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xb101, 0x0028, + 0x080c, 0xbae2, 0x9006, 0x080c, 0xbd50, 0x001e, 0x002e, 0x00ee, + 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x1160, + 0x2001, 0x0002, 0x080c, 0x6663, 0x6003, 0x0001, 0x6007, 0x0001, + 0x080c, 0x9383, 0x0804, 0x98ed, 0x2001, 0x0001, 0x0804, 0xbd50, + 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, + 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x6663, 0x0804, 0xb101, + 0x2001, 0x0001, 0x0804, 0xbd50, 0x0002, 0xbbcb, 0xbe24, 0xbbcb, + 0xbe67, 0xbbcb, 0xbf14, 0xbe19, 0xbbce, 0xbbcb, 0xbf28, 0xbbcb, + 0xbf3a, 0x6604, 0x9686, 0x0003, 0x0904, 0xbd80, 0x96b6, 0x001e, + 0x1110, 0x080c, 0xb101, 0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, + 0xbf4c, 0x11a0, 0x9006, 0x080c, 0x664f, 0x080c, 0x3246, 0x080c, + 0xd576, 0x2001, 0x0002, 0x080c, 0x6663, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0428, 0x2009, 0x026e, + 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840, 0x9084, + 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, 0x000a, 0x0098, + 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, 0x1900, 0x0158, + 0x908e, 0x1e00, 0x0990, 0x080c, 0x3246, 0x080c, 0xd576, 0x2001, + 0x0001, 0x080c, 0xbd50, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, + 0x00b6, 0x0026, 0x9016, 0x080c, 0xbf5a, 0x00d6, 0x2069, 0x197d, + 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, + 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, + 0x00de, 0x0088, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c, + 0x6663, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c, + 0x98ed, 0x0804, 0xbee4, 0x080c, 0xce56, 0x01b0, 0x6014, 0x2048, + 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, + 0x0002, 0x080c, 0xd498, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, + 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, + 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, + 0x9006, 0x0c38, 0x080c, 0xbae2, 0x2009, 0x026e, 0x2134, 0x96b4, + 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, + 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, + 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001, 0x0004, + 0x080c, 0x6663, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0020, + 0x2001, 0x0001, 0x080c, 0xbd50, 0x002e, 0x00be, 0x009e, 0x0005, + 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xce56, 0x0140, + 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, + 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, + 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, + 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60ba, 0x00ee, + 0x0010, 0x080c, 0x3246, 0x0860, 0x2001, 0x0004, 0x080c, 0x6663, + 0x080c, 0xbf5a, 0x1140, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, + 0x9383, 0x0804, 0x98ed, 0x080c, 0xbae2, 0x9006, 0x0804, 0xbd50, + 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x6663, 0x6003, 0x0001, + 0x6007, 0x0005, 0x080c, 0x9383, 0x0804, 0x98ed, 0x2001, 0x0001, + 0x0804, 0xbd50, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c, 0x6663, + 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9383, 0x0804, 0x98ed, + 0x2001, 0x0001, 0x0804, 0xbd50, 0x2009, 0x026e, 0x2104, 0x9086, + 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, + 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, + 0x6110, 0x2158, 0x080c, 0x672c, 0x001e, 0x00ce, 0x00be, 0x0005, + 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, + 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xc005, + 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6a8e, + 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe9a5, 0x2001, + 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, + 0x080c, 0x3211, 0x00e6, 0x2071, 0x1800, 0x080c, 0x3019, 0x00ee, + 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x3342, + 0x8108, 0x1f04, 0xbf9e, 0x015e, 0x00ce, 0x080c, 0xbf5d, 0x2071, + 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837, 0x200c, + 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, + 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102, 0x9184, + 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, 0x2e04, 0x9084, + 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, + 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084, + 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, 0x2200, 0x9084, + 0x00ff, 0x2008, 0x080c, 0x28dd, 0x080c, 0x7569, 0x0170, 0x2071, + 0x0260, 0x2069, 0x1983, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050, + 0x680a, 0x7054, 0x680e, 0x080c, 0xd26c, 0x0040, 0x2001, 0x0006, + 0x080c, 0x6663, 0x080c, 0x326f, 0x080c, 0xb101, 0x001e, 0x003e, + 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036, + 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, 0x01f0, 0x2071, + 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205, + 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019, + 0x000a, 0x080c, 0xc0f7, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x2019, 0x0006, 0x080c, 0xc0f7, 0x1100, 0x015e, 0x00ee, 0x003e, + 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086, + 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec, + 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4, + 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee, + 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, 0x252c, 0x2021, + 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7254, 0x7074, + 0x9202, 0x1a04, 0xc0c3, 0x080c, 0x8bc3, 0x0904, 0xc0bc, 0x080c, + 0xe9d6, 0x0904, 0xc0bc, 0x6720, 0x9786, 0x0007, 0x0904, 0xc0bc, + 0x2500, 0x9c06, 0x0904, 0xc0bc, 0x2400, 0x9c06, 0x05e8, 0x3e08, + 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058, + 0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086, 0x0004, + 0x1110, 0x080c, 0x1ab7, 0x9786, 0x000a, 0x0148, 0x080c, 0xd05e, + 0x1130, 0x00ce, 0x080c, 0xbae2, 0x080c, 0xb134, 0x00e8, 0x6014, + 0x2048, 0x080c, 0xce56, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, + 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, + 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dc4, 0x080c, + 0xd041, 0x080c, 0xb134, 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02, + 0x1210, 0x0804, 0xc066, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, + 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, + 0x080c, 0xe948, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, + 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xb180, 0x08e0, 0x9786, + 0x000a, 0x0980, 0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, + 0x8318, 0x1f04, 0xc0e3, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, + 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, + 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, + 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, + 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, + 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, + 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, + 0x0005, 0x220c, 0x810f, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, + 0x1f04, 0xc121, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, + 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0xd04d, 0x0120, 0x080c, + 0xd05e, 0x0168, 0x0028, 0x080c, 0x326f, 0x080c, 0xd05e, 0x0138, + 0x080c, 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, + 0xbae2, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xc166, 0xc166, 0xc166, 0xc166, 0xc166, 0xc166, + 0xc166, 0xc166, 0xc166, 0xc166, 0xc166, 0xc168, 0xc168, 0xc168, + 0xc168, 0xc166, 0xc166, 0xc166, 0xc168, 0xc166, 0x080c, 0x0dc5, + 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x0126, + 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005, 0x9186, 0x0013, + 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc200, 0x9186, 0x0027, + 0x1520, 0x080c, 0x97e1, 0x080c, 0x3246, 0x080c, 0xd576, 0x0096, + 0x6114, 0x2148, 0x080c, 0xce56, 0x0198, 0x080c, 0xd05e, 0x1118, + 0x080c, 0xbae2, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6dd1, 0x080c, 0xd041, + 0x009e, 0x080c, 0xb101, 0x0804, 0x98ed, 0x9186, 0x0014, 0x1120, + 0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046, 0x0150, 0x9186, + 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186, 0x0048, 0x190c, + 0x0dc5, 0x080c, 0xd587, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110, + 0x0804, 0xc23e, 0x0005, 0x0002, 0xc1da, 0xc1d8, 0xc1d8, 0xc1d8, + 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1f5, + 0xc1f5, 0xc1f5, 0xc1f5, 0xc1d8, 0xc1f5, 0xc1d8, 0xc1f5, 0xc1d8, + 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x0096, 0x6114, 0x2148, 0x080c, + 0xce56, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, + 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x009e, + 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, 0x97e1, 0x080c, + 0xd05e, 0x090c, 0xbae2, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, + 0x0002, 0xc217, 0xc215, 0xc215, 0xc215, 0xc215, 0xc215, 0xc215, + 0xc215, 0xc215, 0xc215, 0xc215, 0xc22e, 0xc22e, 0xc22e, 0xc22e, + 0xc215, 0xc238, 0xc215, 0xc22e, 0xc215, 0x080c, 0x0dc5, 0x0096, + 0x080c, 0x97e1, 0x6014, 0x2048, 0x2001, 0x1989, 0x2004, 0x6042, + 0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400, + 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x97e1, + 0x080c, 0xd579, 0x080c, 0xd57e, 0x6003, 0x000f, 0x0804, 0x98ed, + 0x080c, 0x97e1, 0x080c, 0xb101, 0x0804, 0x98ed, 0x9182, 0x0054, + 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc25a, 0xc25a, + 0xc25a, 0xc25a, 0xc25a, 0xc25c, 0xc33c, 0xc25a, 0xc370, 0xc25a, + 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, + 0xc25a, 0xc370, 0x080c, 0x0dc5, 0x00b6, 0x0096, 0x6114, 0x2148, + 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800, + 0xd0bc, 0x1904, 0xc32b, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, + 0x080c, 0x6beb, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, + 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc30c, 0x080c, 0xb101, 0x009e, + 0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, + 0xd0bc, 0x1904, 0xc310, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, + 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, + 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, + 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, + 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, + 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, + 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, + 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc263, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, - 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xcc85, 0x003e, - 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, - 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xcc85, - 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, - 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xcc24, 0x080c, - 0x1a5a, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1988, - 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, - 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, 0xd1e4, - 0x0904, 0xc993, 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc962, 0xa978, 0xa868, - 0xd0fc, 0x0904, 0xc923, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, - 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, - 0xc8f0, 0x9086, 0x0028, 0x1904, 0xc8dc, 0xa87b, 0x001c, 0xb07b, - 0x001c, 0x0804, 0xc8f8, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, - 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, - 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, - 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, - 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x9006, - 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, - 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, - 0x080c, 0xd412, 0x0804, 0xc993, 0xd1dc, 0x0158, 0xa87b, 0x0015, - 0xb07b, 0x0015, 0x080c, 0xd6a6, 0x0118, 0xb174, 0xc1dc, 0xb176, - 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, - 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc78b, - 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, - 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, - 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, - 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, - 0x080c, 0xd786, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, - 0x001e, 0x0804, 0xc98f, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, - 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, - 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, - 0xb07b, 0x0015, 0x080c, 0xd6a6, 0x0118, 0xb174, 0xc1dc, 0xb176, - 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, - 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc78b, - 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, - 0x0fc0, 0x009e, 0x080c, 0xd786, 0xa974, 0x0016, 0x080c, 0xcc75, - 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, - 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, - 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xd6a6, 0x0118, 0xa974, - 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, - 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, - 0x190c, 0xc78b, 0xa974, 0x0016, 0x080c, 0x6cb9, 0x001e, 0xd1e4, - 0x1120, 0x080c, 0xb2d3, 0x009e, 0x0005, 0x080c, 0xd3d8, 0x0cd8, - 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1a7a, 0x009e, - 0x0005, 0x080c, 0x99a5, 0x0010, 0x080c, 0x9a61, 0x080c, 0xd0d8, - 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xd2e0, 0x1118, 0x080c, - 0xbcb6, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, - 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, - 0x080c, 0xef85, 0xa877, 0x0000, 0x080c, 0x6e9f, 0x009e, 0x080c, - 0xb2d3, 0x080c, 0x9ab1, 0x0804, 0x9bd3, 0xa87b, 0x0004, 0x0c90, - 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, - 0x0208, 0x000a, 0x0005, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, - 0xc9f1, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, - 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0x080c, - 0x0dc5, 0x080c, 0x57dd, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, - 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, - 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, - 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, - 0x080c, 0x6e9f, 0x009e, 0x0804, 0xb2d3, 0x9182, 0x0085, 0x0002, - 0xca27, 0xca25, 0xca25, 0xca33, 0xca25, 0xca25, 0xca25, 0xca25, - 0xca25, 0xca25, 0xca25, 0xca25, 0xca25, 0x080c, 0x0dc5, 0x6003, - 0x0001, 0x6106, 0x080c, 0x94ff, 0x0126, 0x2091, 0x8000, 0x080c, - 0x9ab1, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, - 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xd0c6, 0x01f8, 0x2268, - 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, - 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xcce6, 0x00de, 0x00ce, 0x0158, - 0x702c, 0xd084, 0x1118, 0x080c, 0xccb0, 0x0010, 0x6803, 0x0002, - 0x6007, 0x0086, 0x0028, 0x080c, 0xccd2, 0x0d90, 0x6007, 0x0087, - 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x7220, 0x080c, - 0xd0c6, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xd412, - 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, - 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, - 0x1a0c, 0x0dc5, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, - 0x9186, 0x0014, 0x190c, 0x0dc5, 0x080c, 0x99a5, 0x0096, 0x6014, - 0x2048, 0x080c, 0xd0d8, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, - 0xa87b, 0x0029, 0x080c, 0x6e9f, 0x009e, 0x080c, 0xb306, 0x0804, - 0x9ab1, 0xcab6, 0xcab8, 0xcab8, 0xcab6, 0xcab6, 0xcab6, 0xcab6, - 0xcab6, 0xcab6, 0xcab6, 0xcab6, 0xcab6, 0xcab6, 0x080c, 0x0dc5, - 0x080c, 0x99a5, 0x080c, 0xb306, 0x080c, 0x9ab1, 0x0005, 0x9186, - 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, - 0x0027, 0x11f8, 0x080c, 0x99a5, 0x080c, 0x3250, 0x080c, 0xd7f8, - 0x0096, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x0150, 0xa867, 0x0103, - 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6e9f, 0x080c, 0xd2c3, - 0x009e, 0x080c, 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x080c, 0xb36d, - 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x99a5, 0x0096, 0x6014, - 0x2048, 0x080c, 0xd0d8, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, - 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xcb0e, - 0xcb0c, 0xcb0c, 0xcb0c, 0xcb0c, 0xcb0c, 0xcb26, 0xcb0c, 0xcb0c, - 0xcb0c, 0xcb0c, 0xcb0c, 0xcb0c, 0x080c, 0x0dc5, 0x080c, 0x99a5, - 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, - 0x0035, 0x1118, 0x2001, 0x1986, 0x0010, 0x2001, 0x1987, 0x2004, - 0x601a, 0x6003, 0x000c, 0x080c, 0x9ab1, 0x0005, 0x080c, 0x99a5, - 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, - 0x0035, 0x1118, 0x2001, 0x1986, 0x0010, 0x2001, 0x1987, 0x2004, - 0x601a, 0x6003, 0x000e, 0x080c, 0x9ab1, 0x0005, 0x9182, 0x0092, - 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xb36d, 0xcb54, - 0xcb54, 0xcb54, 0xcb54, 0xcb56, 0xcba3, 0xcb54, 0xcb54, 0xcb54, - 0xcb54, 0xcb54, 0xcb54, 0xcb54, 0x080c, 0x0dc5, 0x0096, 0x6010, - 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, + 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xca03, 0x003e, + 0xd6cc, 0x0904, 0xc278, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc278, + 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, + 0x080c, 0xca03, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd504, + 0x0804, 0xc278, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, + 0x0c50, 0x00a6, 0x2950, 0x080c, 0xc9a2, 0x00ae, 0x080c, 0xd504, + 0x080c, 0xc9f3, 0x0804, 0xc27a, 0x080c, 0xd156, 0x0804, 0xc287, + 0xa87c, 0xd0ac, 0x0904, 0xc293, 0xa880, 0xd0bc, 0x1904, 0xc293, + 0x9684, 0x0400, 0x0130, 0xa838, 0xab34, 0x9305, 0x0904, 0xc293, + 0x00b8, 0x7348, 0xa838, 0x9306, 0x1198, 0x734c, 0xa834, 0x931e, + 0x0904, 0xc293, 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xc26b, 0xa838, + 0xa934, 0x9105, 0x0904, 0xc26b, 0xa880, 0xd0bc, 0x1904, 0xc26b, + 0x080c, 0xd190, 0x0804, 0xc287, 0x0096, 0x00f6, 0x6003, 0x0003, + 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, + 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, 0x6003, 0x0002, 0x00fe, + 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, + 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, + 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, 0x6043, 0x0000, 0x2c10, + 0x080c, 0x1c09, 0x080c, 0x93a0, 0x080c, 0x9a0f, 0x009e, 0x0005, + 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, + 0x0005, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38f, 0xc425, + 0xc38d, 0xc38d, 0xc43c, 0xc4cc, 0xc38d, 0xc38d, 0xc38d, 0xc38d, + 0xc4e1, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0x080c, 0x0dc5, 0x0076, + 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x7644, + 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, + 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, + 0x0904, 0xc420, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, + 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc420, 0x080c, + 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, 0xc7cd, 0xb77e, + 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, + 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, + 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, + 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, + 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, + 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, + 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, + 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xca03, + 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, + 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, + 0xca03, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, + 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc9a2, + 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x00f6, 0x00a6, 0x6003, + 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, + 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, 0x00ae, 0x00fe, 0x2c10, + 0x080c, 0x1c09, 0x0804, 0xa4e4, 0x6003, 0x0002, 0x6004, 0x9086, + 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0160, + 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, 0x080c, 0x1768, + 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, 0x009e, 0x080c, + 0x97e1, 0x080c, 0x98ed, 0x0096, 0x2001, 0x1989, 0x2004, 0x6042, + 0x080c, 0x989d, 0x080c, 0x9a0f, 0x6114, 0x2148, 0xa97c, 0xd1e4, + 0x0904, 0xc4c7, 0xd1cc, 0x05c8, 0xa978, 0xa868, 0xd0fc, 0x0540, + 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0xa860, 0x20e8, 0xa85c, + 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, 0x810f, 0x9184, 0x003f, + 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, 0x2098, 0x0156, 0x20a9, + 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, + 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0458, + 0x0016, 0x080c, 0x0fc0, 0x009e, 0xa87c, 0xc0cc, 0xa87e, 0xa974, + 0x0016, 0x080c, 0xc9f3, 0x001e, 0x00f0, 0xa867, 0x0103, 0xa974, + 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086, 0x0028, 0x1118, + 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0xa87b, 0x0015, 0x0038, + 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0x0016, + 0x080c, 0x6beb, 0x001e, 0xd1e4, 0x1120, 0x080c, 0xb101, 0x009e, + 0x0005, 0x080c, 0xd156, 0x0cd8, 0x6004, 0x9086, 0x0040, 0x1120, + 0x080c, 0x97e1, 0x080c, 0x98ed, 0x2019, 0x0001, 0x080c, 0xa877, + 0x6003, 0x0002, 0x080c, 0xd57e, 0x080c, 0x989d, 0x080c, 0x9a0f, + 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x97e1, 0x080c, + 0x98ed, 0x2019, 0x0001, 0x080c, 0xa877, 0x080c, 0x989d, 0x080c, + 0x3246, 0x080c, 0xd576, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56, + 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, + 0x6dd1, 0x080c, 0xd041, 0x009e, 0x080c, 0xb101, 0x080c, 0x9a0f, + 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, + 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009, 0x1a7e, + 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, + 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, + 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53e, 0xc53c, 0xc53c, + 0xc5e4, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, + 0xc53c, 0xc53c, 0xc53c, 0xc716, 0x080c, 0x0dc5, 0x0076, 0x00a6, + 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, + 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, + 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, + 0xc5dd, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, + 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc5dd, 0x9686, 0x0100, + 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c, + 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, 0x97bd, 0x0200, + 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, + 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, 0x968c, 0x0c00, + 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, + 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, + 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, + 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, + 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, + 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, + 0x0018, 0x2011, 0x0025, 0x080c, 0xca03, 0x003e, 0xd6cc, 0x01e8, + 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, + 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xca03, 0x2011, 0x0205, + 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, + 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc9a2, 0x080c, 0x1a83, 0x009e, + 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1989, 0x2004, 0x6042, + 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x1118, 0xa87c, + 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, 0xd1e4, 0x0904, 0xc711, + 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x1500, 0xd1cc, 0x0904, 0xc6e0, 0xa978, 0xa868, 0xd0fc, 0x0904, + 0xc6a1, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, + 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, 0xc66e, 0x9086, + 0x0028, 0x1904, 0xc65a, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, + 0xc676, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, 0x9205, 0x09c8, + 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, 0x9206, 0x0988, + 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, 0x603a, 0xa9b0, + 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x6010, 0x00b6, + 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x9006, 0xa876, 0xa892, + 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, + 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd190, + 0x0804, 0xc711, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, + 0x080c, 0xd424, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, + 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, + 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, 0xa87c, 0xb07e, + 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, + 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, + 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd504, + 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0804, + 0xc70d, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, + 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, + 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, + 0x080c, 0xd424, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, + 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, + 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, 0xa890, 0xb092, + 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x0fc0, 0x009e, + 0x080c, 0xd504, 0xa974, 0x0016, 0x080c, 0xc9f3, 0x001e, 0x0468, + 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, + 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, + 0xa87b, 0x0015, 0x080c, 0xd424, 0x0118, 0xa974, 0xc1dc, 0xa976, + 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, + 0xa974, 0x0016, 0x080c, 0x6beb, 0x001e, 0xd1e4, 0x1120, 0x080c, + 0xb101, 0x009e, 0x0005, 0x080c, 0xd156, 0x0cd8, 0x6114, 0x0096, + 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1aa3, 0x009e, 0x0005, 0x080c, + 0x97e1, 0x0010, 0x080c, 0x989d, 0x080c, 0xce56, 0x01f0, 0x0096, + 0x6114, 0x2148, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x00a0, + 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, 0x11b8, 0xd184, + 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, 0x080c, 0xed00, + 0xa877, 0x0000, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c, + 0x98ed, 0x0804, 0x9a0f, 0xa87b, 0x0004, 0x0c90, 0xa87b, 0x0004, + 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, + 0x0005, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76f, 0xc76d, + 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, + 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0x080c, 0x0dc5, 0x080c, + 0x57db, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, 0x9016, 0xd1c4, + 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, 0x0188, 0xa87b, + 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, 0x0103, 0xa976, + 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, 0x080c, 0x6dd1, + 0x009e, 0x0804, 0xb101, 0x9182, 0x0085, 0x0002, 0xc7a5, 0xc7a3, + 0xc7a3, 0xc7b1, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3, + 0xc7a3, 0xc7a3, 0xc7a3, 0x080c, 0x0dc5, 0x6003, 0x0001, 0x6106, + 0x080c, 0x933b, 0x0126, 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, + 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224, + 0x6216, 0x7220, 0x080c, 0xce44, 0x01f8, 0x2268, 0x6800, 0x9086, + 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, 0x00c6, 0x2d60, + 0x00d6, 0x080c, 0xca64, 0x00de, 0x00ce, 0x0158, 0x702c, 0xd084, + 0x1118, 0x080c, 0xca2e, 0x0010, 0x6803, 0x0002, 0x6007, 0x0086, + 0x0028, 0x080c, 0xca50, 0x0d90, 0x6007, 0x0087, 0x6003, 0x0001, + 0x080c, 0x933b, 0x080c, 0x98ed, 0x7220, 0x080c, 0xce44, 0x0178, + 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824, + 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xd190, 0x00ce, 0x00ee, + 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, + 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, + 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, 0x9186, 0x0014, + 0x190c, 0x0dc5, 0x080c, 0x97e1, 0x0096, 0x6014, 0x2048, 0x080c, + 0xce56, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, + 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb134, 0x0804, 0x98ed, 0xc834, + 0xc836, 0xc836, 0xc834, 0xc834, 0xc834, 0xc834, 0xc834, 0xc834, + 0xc834, 0xc834, 0xc834, 0xc834, 0x080c, 0x0dc5, 0x080c, 0x97e1, + 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005, 0x9186, 0x0013, 0x1128, + 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, 0x0027, 0x11f8, + 0x080c, 0x97e1, 0x080c, 0x3246, 0x080c, 0xd576, 0x0096, 0x6014, + 0x2048, 0x080c, 0xce56, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0029, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x009e, 0x080c, + 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, 0xb19b, 0x0ce0, 0x9186, + 0x0014, 0x1dd0, 0x080c, 0x97e1, 0x0096, 0x6014, 0x2048, 0x080c, + 0xce56, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0006, + 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xc88c, 0xc88a, 0xc88a, + 0xc88a, 0xc88a, 0xc88a, 0xc8a4, 0xc88a, 0xc88a, 0xc88a, 0xc88a, + 0xc88a, 0xc88a, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, - 0x009e, 0x0804, 0xcbb7, 0x080c, 0xd0d8, 0x1118, 0x080c, 0xd2c3, - 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xd2c3, - 0xa867, 0x0103, 0x080c, 0xd7c3, 0x080c, 0x6e9f, 0x00d6, 0x2c68, - 0x080c, 0xb27d, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, - 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, - 0x613e, 0x6910, 0x6112, 0x080c, 0xd554, 0x6954, 0x6156, 0x6023, - 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x2d60, 0x00de, 0x080c, - 0xb2d3, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, - 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, - 0x2c68, 0x080c, 0xd759, 0x11f0, 0x080c, 0xb27d, 0x01d8, 0x6106, - 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, - 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, - 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xd554, 0x080c, 0x94ff, - 0x080c, 0x9ab1, 0x2d60, 0x00de, 0x0804, 0xb2d3, 0x0096, 0x6014, - 0x2048, 0x080c, 0xd0d8, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, - 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, - 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xd3d4, 0xa877, - 0x0000, 0x080c, 0x6e9f, 0x080c, 0xd2c3, 0x009e, 0x0804, 0xb2d3, - 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x0140, 0xa867, - 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6e9f, 0x009e, - 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, - 0x0027, 0x0118, 0x080c, 0xb36d, 0x0030, 0x080c, 0x99a5, 0x080c, - 0xb306, 0x080c, 0x9ab1, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, - 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, - 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, - 0x080c, 0xcc85, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, - 0x0fc0, 0x080c, 0x100e, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, - 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, - 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, - 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, - 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, - 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, - 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, - 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6e9f, 0x2a48, - 0x0cb8, 0x080c, 0x6e9f, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, - 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, - 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, - 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, - 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, - 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, - 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, - 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xd0d8, - 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x710b, 0x080c, - 0x6e92, 0x080c, 0xd2c3, 0x009e, 0x080c, 0xb306, 0x00ee, 0x00de, - 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, - 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, - 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, - 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, - 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, - 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, - 0xcd1d, 0xcd1d, 0xcd18, 0xcd3f, 0xcd0f, 0xcd18, 0xcd3f, 0xcd18, - 0xcd18, 0x9265, 0xcd18, 0xcd18, 0xcd18, 0xcd0f, 0xcd0f, 0x080c, - 0x0dc5, 0x0036, 0x2019, 0x0010, 0x080c, 0xe746, 0x003e, 0x0005, - 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, - 0x6014, 0x2048, 0x080c, 0xd0d8, 0x01c0, 0xa864, 0x9086, 0x0139, - 0x1128, 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, - 0x0005, 0x080c, 0x710b, 0x080c, 0xd3d4, 0x080c, 0x6e92, 0x080c, - 0xb306, 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, - 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0002, 0xcd55, 0xcd85, 0xcd57, - 0xcda6, 0xcd80, 0xcd55, 0xcd18, 0xcd1d, 0xcd1d, 0xcd18, 0xcd18, - 0xcd18, 0xcd18, 0xcd18, 0xcd18, 0xcd18, 0x080c, 0x0dc5, 0x86ff, - 0x1520, 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, - 0x080c, 0xd0d8, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, - 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd3d4, - 0x009e, 0x080c, 0xd79d, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, - 0x0002, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x9085, 0x0001, 0x0005, - 0x0066, 0x080c, 0x1a8e, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e8, - 0x7024, 0x9c06, 0x1120, 0x080c, 0xa9d3, 0x00ee, 0x0840, 0x6020, - 0x9084, 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, - 0x0001, 0x2c40, 0x080c, 0xaafb, 0x009e, 0x008e, 0x0010, 0x080c, - 0xa8d0, 0x00ee, 0x1904, 0xcd57, 0x0804, 0xcd18, 0x0036, 0x00e6, - 0x2071, 0x19e8, 0x703c, 0x9c06, 0x1138, 0x901e, 0x080c, 0xaa49, - 0x00ee, 0x003e, 0x0804, 0xcd57, 0x080c, 0xac2b, 0x00ee, 0x003e, - 0x1904, 0xcd57, 0x0804, 0xcd18, 0x00c6, 0x6020, 0x9084, 0x000f, - 0x0013, 0x00ce, 0x0005, 0xcdd9, 0xcea3, 0xd011, 0xcde3, 0xb306, - 0xcdd9, 0xe73c, 0xd805, 0xcea3, 0x9237, 0xd09d, 0xcdd2, 0xcdd2, - 0xcdd2, 0xcdd2, 0x080c, 0x0dc5, 0x080c, 0xd2e0, 0x1110, 0x080c, - 0xbcb6, 0x0005, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0804, 0xb2d3, - 0x601b, 0x0001, 0x0005, 0x080c, 0xd0d8, 0x0130, 0x6014, 0x0096, - 0x2048, 0x2c00, 0xa896, 0x009e, 0x6000, 0x908a, 0x0010, 0x1a0c, - 0x0dc5, 0x0002, 0xce02, 0xce04, 0xce28, 0xce3c, 0xce62, 0xce02, - 0xcdd9, 0xcdd9, 0xcdd9, 0xce3c, 0xce3c, 0xce02, 0xce02, 0xce02, - 0xce02, 0xce46, 0x080c, 0x0dc5, 0x00e6, 0x6014, 0x0096, 0x2048, - 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e8, 0x7024, 0x9c06, - 0x01a0, 0x080c, 0xa8d0, 0x080c, 0xd79d, 0x6007, 0x0085, 0x6003, - 0x000b, 0x6023, 0x0002, 0x2001, 0x1987, 0x2004, 0x601a, 0x080c, - 0x94ff, 0x080c, 0x9ab1, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, - 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, - 0xd79d, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, - 0x94ff, 0x080c, 0x9ab1, 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, - 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x57dd, - 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, - 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, - 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6e9f, 0x009e, - 0x0804, 0xb2d3, 0x6014, 0x0096, 0x904d, 0x05c0, 0xa97c, 0xd1e4, - 0x05a8, 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, - 0xa884, 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, - 0x0030, 0x2c08, 0x080c, 0x1611, 0x2001, 0x030c, 0x2004, 0x9086, - 0x0041, 0x1198, 0x6014, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa880, - 0xd0f4, 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0068, - 0x009e, 0x00c6, 0x080c, 0x236e, 0x00ce, 0x6000, 0x9086, 0x0004, - 0x1120, 0x2009, 0x0048, 0x080c, 0xb352, 0x0005, 0x009e, 0x080c, - 0x1a8e, 0x0804, 0xce28, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, - 0x000b, 0x0005, 0xceba, 0xcde0, 0xcebc, 0xceba, 0xcebc, 0xcebc, - 0xcdda, 0xceba, 0xcdd4, 0xcdd4, 0xceba, 0xceba, 0xceba, 0xceba, - 0xceba, 0xceba, 0x080c, 0x0dc5, 0x6010, 0x00b6, 0x2058, 0xb804, - 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0dc5, 0x00b6, - 0x0013, 0x00be, 0x0005, 0xced7, 0xcfa8, 0xced9, 0xcf19, 0xced9, - 0xcf19, 0xced9, 0xcee7, 0xced7, 0xcf19, 0xced7, 0xcf08, 0x080c, - 0x0dc5, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, - 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xcfa4, 0x6004, - 0x080c, 0xd2e0, 0x0904, 0xcfc1, 0x908e, 0x0004, 0x1110, 0x080c, - 0x3279, 0x908e, 0x0021, 0x0904, 0xcfc5, 0x908e, 0x0022, 0x0904, - 0xd00c, 0x908e, 0x003d, 0x0904, 0xcfc5, 0x908e, 0x0039, 0x0904, - 0xcfc9, 0x908e, 0x0035, 0x0904, 0xcfc9, 0x908e, 0x001e, 0x0178, - 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff, - 0x9086, 0x0006, 0x0110, 0x080c, 0x3250, 0x080c, 0xbcb6, 0x0804, - 0xb306, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xcf95, - 0x9186, 0x0002, 0x1904, 0xcf6a, 0x2001, 0x1837, 0x2004, 0xd08c, - 0x11c8, 0x080c, 0x7637, 0x11b0, 0x080c, 0xd7e3, 0x0138, 0x080c, - 0x765a, 0x1120, 0x080c, 0x7541, 0x0804, 0xcff5, 0x2001, 0x197d, - 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x7563, - 0x0804, 0xcff5, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x0080, 0x0130, - 0x2001, 0x1837, 0x2004, 0xd0ac, 0x1904, 0xcff5, 0xb8a0, 0x9082, - 0x0081, 0x1a04, 0xcff5, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, - 0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, - 0x6043, 0x0000, 0x080c, 0xb27d, 0x0128, 0x2b00, 0x6012, 0x6023, - 0x0001, 0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, - 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, - 0x2104, 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60c1, - 0x00ee, 0x080c, 0xbcb6, 0x0030, 0x080c, 0xbcb6, 0x080c, 0x3250, - 0x080c, 0xd7f8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x3279, - 0x012e, 0x00ee, 0x080c, 0xb306, 0x0005, 0x2001, 0x0002, 0x080c, - 0x666a, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9547, 0x080c, - 0x9ab1, 0x00de, 0x00ce, 0x0c80, 0x080c, 0x3279, 0x0804, 0xcf15, - 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, - 0xb840, 0x9084, 0x00ff, 0x9005, 0x0904, 0xcf6a, 0x8001, 0xb842, - 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x00de, 0x00ce, - 0x0898, 0x080c, 0xbcb6, 0x0804, 0xcf17, 0x080c, 0xbcf2, 0x0804, - 0xcf17, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd759, 0x00de, 0x0118, - 0x080c, 0xb2d3, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, - 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x603c, 0x600a, 0x2001, 0x1987, 0x2004, 0x601a, 0x602c, 0x2c08, - 0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, - 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0005, 0x00de, 0x00ce, 0x080c, - 0xbcb6, 0x080c, 0x3250, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, - 0x3279, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, - 0x0000, 0x012e, 0x00ee, 0x0005, 0x080c, 0xb708, 0x1904, 0xcfc1, - 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x00d6, - 0x001b, 0x00de, 0x009e, 0x0005, 0xd02c, 0xd02c, 0xd02c, 0xd02c, - 0xd02c, 0xd02c, 0xd02c, 0xd02c, 0xd02c, 0xcdd9, 0xd02c, 0xcde0, - 0xd02e, 0xcde0, 0xd048, 0xd02c, 0x080c, 0x0dc5, 0x6004, 0x9086, - 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, - 0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, - 0x008b, 0x6003, 0x000d, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0005, - 0x080c, 0xd7d7, 0x0118, 0x080c, 0xd7ea, 0x0010, 0x080c, 0xd7f8, - 0x080c, 0xd2c3, 0x080c, 0xd0d8, 0x0570, 0x080c, 0x3250, 0x080c, - 0xd0d8, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, - 0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6e9f, 0x2c68, - 0x080c, 0xb27d, 0x0150, 0x6810, 0x6012, 0x080c, 0xd554, 0x00c6, - 0x2d60, 0x080c, 0xb306, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, - 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9547, - 0x080c, 0x9ab1, 0x00c8, 0x080c, 0xd7d7, 0x0138, 0x6034, 0x9086, - 0x4000, 0x1118, 0x080c, 0x3250, 0x08d0, 0x6034, 0x908c, 0xff00, - 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, - 0x3250, 0x0868, 0x080c, 0xb306, 0x0005, 0x6000, 0x908a, 0x0010, - 0x1a0c, 0x0dc5, 0x0002, 0xd0b3, 0xd0b3, 0xd0b7, 0xd0b5, 0xd0c1, - 0xd0b3, 0xd0b3, 0xb306, 0xd0b3, 0xd0b3, 0xd0b3, 0xd0b3, 0xd0b3, - 0xd0b3, 0xd0b3, 0xd0b3, 0x080c, 0x0dc5, 0x080c, 0xac2b, 0x6114, - 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, 0x6e9f, 0x009e, 0x0804, - 0xb2d3, 0x601c, 0xd084, 0x190c, 0x1a8e, 0x0c88, 0x9284, 0x0007, - 0x1158, 0x9282, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, - 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, - 0x0096, 0x0006, 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, - 0x9086, 0xf000, 0x0110, 0x080c, 0x10b9, 0x000e, 0x009e, 0x0005, - 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, - 0x1cd0, 0x2071, 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, - 0x9206, 0x11f8, 0x080c, 0xd7e3, 0x0180, 0x9286, 0x0001, 0x1168, - 0x6004, 0x9086, 0x0004, 0x1148, 0x080c, 0x3250, 0x080c, 0xd7f8, - 0x00c6, 0x080c, 0xb306, 0x00ce, 0x0060, 0x080c, 0xd4ce, 0x0148, - 0x080c, 0xd2e0, 0x1110, 0x080c, 0xbcb6, 0x00c6, 0x080c, 0xb2d3, - 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, - 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, - 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab7, 0x6112, - 0x080c, 0x3250, 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, - 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb27d, - 0x01b0, 0x6656, 0x2b00, 0x6012, 0x080c, 0x57dd, 0x0118, 0x080c, - 0xd207, 0x0168, 0x080c, 0xd554, 0x6023, 0x0003, 0x2009, 0x004b, - 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, - 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xb325, - 0x0560, 0x6057, 0x0000, 0x2b00, 0x6012, 0x080c, 0xd554, 0x6023, - 0x0003, 0x0016, 0x080c, 0x96a4, 0x0076, 0x903e, 0x080c, 0x9577, - 0x2c08, 0x080c, 0xe91c, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, - 0xb2d3, 0x9085, 0x0001, 0x0070, 0x080c, 0x57dd, 0x0128, 0xd18c, - 0x1170, 0x080c, 0xd207, 0x0148, 0x2009, 0x004c, 0x080c, 0xb352, - 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, - 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, - 0x00c6, 0x0046, 0x0016, 0x080c, 0xb27d, 0x2c78, 0x05a0, 0x7e56, - 0x2b00, 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, - 0xd219, 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, - 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb2d3, - 0x00d0, 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, - 0xb2d3, 0x0088, 0x2f60, 0x080c, 0x57dd, 0x0138, 0xd18c, 0x1118, - 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, - 0xb352, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, - 0x00f6, 0x00c6, 0x0046, 0x080c, 0xb27d, 0x2c78, 0x0508, 0x7e56, - 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, - 0x009e, 0x2001, 0x197e, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, - 0xb2d3, 0x0060, 0x2f60, 0x080c, 0x57dd, 0x0120, 0xd18c, 0x1160, - 0x0071, 0x0130, 0x2009, 0x0052, 0x080c, 0xb352, 0x9085, 0x0001, - 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, - 0x080c, 0x4be4, 0x00ce, 0x1120, 0x080c, 0xb2d3, 0x9006, 0x0005, - 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, - 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x6858, - 0x0158, 0x2001, 0xd21e, 0x0006, 0x900e, 0x2400, 0x080c, 0x710b, - 0x080c, 0x6e9f, 0x000e, 0x0807, 0x2418, 0x080c, 0x993f, 0xbaa0, - 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x96bc, - 0x008e, 0x080c, 0x9577, 0x2f08, 0x2648, 0x080c, 0xe91c, 0xb93c, - 0x81ff, 0x090c, 0x978f, 0x080c, 0x9ab1, 0x012e, 0x007e, 0x009e, - 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb27d, 0x0190, - 0x660a, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, - 0x6016, 0x2009, 0x001f, 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, - 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x080c, 0xb325, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd554, - 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1768, - 0x00fe, 0x2009, 0x0021, 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, - 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, - 0x0016, 0x2091, 0x8000, 0x080c, 0xb27d, 0x0198, 0x660a, 0x2b08, - 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, - 0x0016, 0x080c, 0xb352, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, - 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, - 0xb325, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, - 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xb352, 0x9085, 0x0001, - 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, - 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, - 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, - 0x0016, 0x6004, 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, - 0x908e, 0x0004, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, - 0x0006, 0x0086, 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, - 0x904d, 0x080c, 0xd0d8, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, - 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, - 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, - 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb325, - 0x0198, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, - 0x6016, 0x080c, 0x3250, 0x2009, 0x0028, 0x080c, 0xb352, 0x9085, - 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, - 0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, - 0x080c, 0xbf63, 0x00be, 0x080c, 0xc1df, 0x6003, 0x0001, 0x6007, - 0x0029, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0078, 0x6014, 0x0096, - 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, - 0xd71a, 0x080c, 0xbcb6, 0x080c, 0xb2d3, 0x0005, 0x0096, 0x6014, - 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, - 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6e9f, 0x012e, 0x009e, 0x080c, 0xb2d3, 0x0c30, 0x0096, - 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x666a, 0x00e8, - 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, - 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x67bf, 0x00be, 0x080c, - 0xc2b5, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, - 0x0160, 0x2001, 0x0006, 0x080c, 0x666a, 0x6014, 0x2048, 0xa868, - 0xd0fc, 0x0170, 0x080c, 0xb6dc, 0x0048, 0x6014, 0x2048, 0xa868, - 0xd0fc, 0x0528, 0x080c, 0xbcb6, 0x080c, 0xb2d3, 0x009e, 0x0005, - 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0000, - 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x6944, 0x1108, - 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, - 0x8000, 0x080c, 0x6e9f, 0x012e, 0x080c, 0xb2d3, 0x08f8, 0x6014, - 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, - 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6e9f, 0x012e, 0x080c, 0xb2d3, 0x0840, 0xa878, 0x9086, - 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, - 0x6043, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, - 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0005, 0x00c6, 0x6010, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, - 0x0013, 0x00ce, 0x0005, 0xcdd9, 0xd404, 0xd404, 0xd407, 0xec80, - 0xec9b, 0xec9e, 0xcdd9, 0xcdd9, 0xcdd9, 0xcdd9, 0xcdd9, 0xcdd9, - 0xcdd9, 0xcdd9, 0x080c, 0x0dc5, 0xa001, 0xa001, 0x0005, 0x0096, - 0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, - 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x0550, 0x2001, 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, - 0x080c, 0xb27d, 0x0508, 0x7810, 0x6012, 0x080c, 0xd554, 0x7820, - 0x9086, 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, - 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, - 0x0035, 0x6003, 0x0001, 0x7954, 0x6156, 0x080c, 0x94ff, 0x080c, - 0x9ab1, 0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1988, - 0x2004, 0x6042, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, - 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, - 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, - 0x080c, 0x0fc0, 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, - 0x0002, 0x9086, 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, - 0x681c, 0xc085, 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, - 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, - 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, - 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, - 0x6954, 0x6156, 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, - 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x009e, 0x001e, 0x0005, 0x6024, - 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, - 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, - 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, - 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, - 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, - 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, - 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, - 0x0036, 0x0188, 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, - 0x908e, 0x0039, 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, - 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, - 0x0026, 0x0036, 0x00e6, 0x2001, 0x1982, 0x200c, 0x8000, 0x2014, - 0x2001, 0x0032, 0x080c, 0x9375, 0x2001, 0x1986, 0x82ff, 0x1110, - 0x2011, 0x0014, 0x2202, 0x2001, 0x1984, 0x200c, 0x8000, 0x2014, - 0x2071, 0x196c, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x9375, - 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, - 0x1988, 0x9288, 0x000a, 0x2102, 0x2001, 0x1a98, 0x2102, 0x2001, - 0x0032, 0x080c, 0x1611, 0x080c, 0x6a84, 0x00ee, 0x003e, 0x002e, - 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1986, - 0x2003, 0x0028, 0x2001, 0x1987, 0x2003, 0x0014, 0x2071, 0x196c, - 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0x1988, 0x2009, 0x001e, - 0x2102, 0x2001, 0x1a98, 0x2102, 0x2001, 0x0032, 0x080c, 0x1611, - 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, - 0x080c, 0x1040, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x080c, 0xb27d, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, - 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0xb352, 0x9085, - 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, - 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, - 0x0018, 0x0120, 0x7090, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, - 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x9d4c, 0x01d8, 0x707c, - 0xaa50, 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, - 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, 0x3299, 0x080c, - 0xb6dc, 0x0020, 0x080c, 0xbcb6, 0x080c, 0xb2d3, 0x00fe, 0x00ee, - 0x009e, 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x080c, 0xb27d, 0x0188, 0x2b08, 0x6112, - 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, - 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, - 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xb27d, - 0x0180, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, - 0x6016, 0x001e, 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, 0x00ce, - 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, - 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, - 0x0015, 0x1568, 0x7190, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, - 0x1530, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000, 0x6014, - 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, - 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, - 0x0016, 0x200c, 0x080c, 0xde2e, 0x001e, 0xa804, 0x9005, 0x0110, - 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, - 0xbcb6, 0x080c, 0xb2d3, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, - 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, - 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, - 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, 0x9d4c, 0x01a8, 0x707c, - 0xaa74, 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, - 0x3250, 0x080c, 0xb6dc, 0x0020, 0x080c, 0xbcb6, 0x080c, 0xb2d3, - 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, - 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, - 0x1550, 0x7090, 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, - 0x080c, 0x9d4c, 0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, - 0xaad0, 0x9206, 0x1160, 0x080c, 0x3250, 0x0016, 0xa998, 0xaab0, - 0x9284, 0x1000, 0xc0fd, 0x080c, 0x5784, 0x001e, 0x0010, 0x080c, - 0x556f, 0x080c, 0xd0d8, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, - 0xa897, 0x4000, 0x0080, 0x080c, 0xd0d8, 0x01b8, 0x6014, 0x2048, - 0x080c, 0x556f, 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, - 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, - 0x080c, 0x6e9f, 0x012e, 0x080c, 0xb2d3, 0x00fe, 0x00ee, 0x009e, - 0x0005, 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, - 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, - 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, - 0x9085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, - 0x080c, 0xd0d8, 0x0904, 0xd716, 0x0096, 0x6314, 0x2348, 0xa87a, - 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, - 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6944, 0x1108, 0xc185, - 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, - 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, - 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, - 0x080c, 0x0f8b, 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, - 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, - 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, - 0xa86a, 0x080c, 0x6e92, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, - 0x00be, 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, - 0x6214, 0x2248, 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, - 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, 0x2873, 0x2118, - 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, - 0x2011, 0x8018, 0x080c, 0x4c44, 0x00a8, 0x9096, 0x0001, 0x1148, - 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, - 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, - 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, - 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, - 0x0008, 0x6a2c, 0x080c, 0xd0c6, 0x01f0, 0x2260, 0x6120, 0x9186, - 0x0003, 0x0118, 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, - 0x683c, 0x9206, 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, - 0x6008, 0x693c, 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, - 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, - 0x0198, 0x918c, 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, - 0x000f, 0x918e, 0x0001, 0x1140, 0xa87c, 0xd0ac, 0x0128, 0xa834, - 0xa938, 0x9115, 0x190c, 0xc78b, 0x0005, 0x0036, 0x2019, 0x0001, - 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xd0d8, 0x01c8, - 0x080c, 0xd2c3, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, - 0x2048, 0xa87c, 0x080c, 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0040, - 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6e9f, - 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, - 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, - 0xa87b, 0x0005, 0x080c, 0xd3d4, 0xa877, 0x0000, 0x0005, 0x2001, - 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, - 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, - 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, - 0x00be, 0x2021, 0x0007, 0x080c, 0x4dfb, 0x004e, 0x003e, 0x0005, - 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1986, 0x2004, 0x601a, 0x0005, - 0x2001, 0x1988, 0x2004, 0x6042, 0x0005, 0x080c, 0xb2d3, 0x0804, - 0x9ab1, 0x2001, 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, - 0x2800, 0x0006, 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, - 0x2079, 0x19e8, 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x93e2, - 0x00ce, 0x00ee, 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, - 0x9085, 0x0001, 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, - 0x1a0c, 0x0dc5, 0x001b, 0x006e, 0x00be, 0x0005, 0xd846, 0xdf8d, - 0xe102, 0xd846, 0xd846, 0xd846, 0xd846, 0xd846, 0xd87d, 0xe186, - 0xd846, 0xd846, 0xd846, 0xd846, 0xd846, 0xd846, 0x080c, 0x0dc5, - 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, - 0x0005, 0xd861, 0xe6d5, 0xd861, 0xd861, 0xd861, 0xd861, 0xd861, - 0xd861, 0xe682, 0xe729, 0xd861, 0xedb4, 0xedea, 0xedb4, 0xedea, - 0xd861, 0x080c, 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0dc5, - 0x6000, 0x000a, 0x0005, 0xd87b, 0xe364, 0xe433, 0xe456, 0xe516, - 0xd87b, 0xe5f5, 0xe59e, 0xe192, 0xe658, 0xe66d, 0xd87b, 0xd87b, - 0xd87b, 0xd87b, 0xd87b, 0x080c, 0x0dc5, 0x91b2, 0x0053, 0x1a0c, - 0x0dc5, 0x2100, 0x91b2, 0x0040, 0x1a04, 0xdcfd, 0x0002, 0xd8c7, - 0xdacb, 0xd8c7, 0xd8c7, 0xd8c7, 0xdad4, 0xd8c7, 0xd8c7, 0xd8c7, - 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, - 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c9, 0xd92c, - 0xd93b, 0xd99f, 0xd9ca, 0xda43, 0xdab6, 0xd8c7, 0xd8c7, 0xdad7, - 0xd8c7, 0xd8c7, 0xdaec, 0xdaf9, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, - 0xd8c7, 0xdb9f, 0xd8c7, 0xd8c7, 0xdbb3, 0xd8c7, 0xd8c7, 0xdb6e, - 0xd8c7, 0xd8c7, 0xd8c7, 0xdbcb, 0xd8c7, 0xd8c7, 0xd8c7, 0xdc48, - 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xdcc5, 0x080c, - 0x0dc5, 0x080c, 0x6a61, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, - 0x1128, 0x9084, 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, - 0x602f, 0x0009, 0x6017, 0x0000, 0x0804, 0xdac4, 0x080c, 0x69fd, - 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, - 0x0026, 0x2019, 0x0029, 0x080c, 0x96a4, 0x0076, 0x903e, 0x080c, - 0x9577, 0x2c08, 0x080c, 0xe91c, 0x007e, 0x001e, 0x001e, 0x002e, - 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x6733, 0xbe04, - 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, - 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xf015, 0x002e, - 0x001e, 0x1178, 0x080c, 0xe84e, 0x1904, 0xd997, 0x080c, 0xe7ea, - 0x1120, 0x6007, 0x0008, 0x0804, 0xdac4, 0x6007, 0x0009, 0x0804, - 0xdac4, 0x080c, 0xeab9, 0x0128, 0x080c, 0xe84e, 0x0d78, 0x0804, - 0xd997, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3374, 0x1904, 0xdcfa, - 0x6106, 0x080c, 0xe78e, 0x6007, 0x0006, 0x0804, 0xdac4, 0x6007, - 0x0007, 0x0804, 0xdac4, 0x080c, 0xee26, 0x1904, 0xdcfa, 0x080c, - 0x3374, 0x1904, 0xdcfa, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, - 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x6656, - 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, - 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, - 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, - 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, - 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, - 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe8b2, 0x1190, - 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, - 0x080c, 0x3299, 0x002e, 0x080c, 0x67bf, 0x6007, 0x000a, 0x00de, - 0x0804, 0xdac4, 0x6007, 0x000b, 0x00de, 0x0804, 0xdac4, 0x080c, - 0x3250, 0x080c, 0xd7f8, 0x6007, 0x0001, 0x0804, 0xdac4, 0x080c, - 0xee26, 0x1904, 0xdcfa, 0x080c, 0x3374, 0x1904, 0xdcfa, 0x2071, - 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, - 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, - 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, - 0x3299, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xeff4, - 0x0804, 0xdac4, 0x080c, 0x6a61, 0x1140, 0x2001, 0x1837, 0x2004, - 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd8d6, 0x080c, - 0x69fd, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, - 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x6696, 0x002e, - 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, - 0x0006, 0x1904, 0xd997, 0x080c, 0xe8bf, 0x1120, 0x6007, 0x000e, - 0x0804, 0xdac4, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, - 0x3250, 0x080c, 0xd7f8, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, - 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xec31, 0x6010, + 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, + 0x000c, 0x080c, 0x98ed, 0x0005, 0x080c, 0x97e1, 0x6034, 0x908c, + 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, + 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, + 0x000e, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, + 0x0085, 0x0208, 0x0012, 0x0804, 0xb19b, 0xc8d2, 0xc8d2, 0xc8d2, + 0xc8d2, 0xc8d4, 0xc921, 0xc8d2, 0xc8d2, 0xc8d2, 0xc8d2, 0xc8d2, + 0xc8d2, 0xc8d2, 0x080c, 0x0dc5, 0x0096, 0x6010, 0x00b6, 0x2058, + 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x009e, 0x0804, + 0xc935, 0x080c, 0xce56, 0x1118, 0x080c, 0xd041, 0x0068, 0x6014, + 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xd041, 0xa867, 0x0103, + 0x080c, 0xd541, 0x080c, 0x6dd1, 0x00d6, 0x2c68, 0x080c, 0xb0ab, + 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, + 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x6910, + 0x6112, 0x080c, 0xd2d2, 0x6954, 0x6156, 0x6023, 0x0001, 0x080c, + 0x933b, 0x080c, 0x98ed, 0x2d60, 0x00de, 0x080c, 0xb101, 0x009e, + 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x05a0, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x0130, 0x9186, + 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, 0x2c68, 0x080c, + 0xd4d7, 0x11f0, 0x080c, 0xb0ab, 0x01d8, 0x6106, 0x6003, 0x0001, + 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, 0x6930, 0x6132, + 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, 0x693c, 0x613e, + 0x6954, 0x6156, 0x080c, 0xd2d2, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x2d60, 0x00de, 0x0804, 0xb101, 0x0096, 0x6014, 0x2048, 0x080c, + 0xce56, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec, + 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, + 0x0020, 0xa87b, 0x0005, 0x080c, 0xd152, 0xa877, 0x0000, 0x080c, + 0x6dd1, 0x080c, 0xd041, 0x009e, 0x0804, 0xb101, 0x0016, 0x0096, + 0x6014, 0x2048, 0x080c, 0xce56, 0x0140, 0xa867, 0x0103, 0xa87b, + 0x0028, 0xa877, 0x0000, 0x080c, 0x6dd1, 0x009e, 0x001e, 0x9186, + 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, + 0x080c, 0xb19b, 0x0030, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, + 0x98ed, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, + 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x8304, + 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c, 0xca03, + 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, + 0x100e, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, + 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, 0x001b, 0x0499, + 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, + 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, + 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, + 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, + 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, + 0x0130, 0xa807, 0x0000, 0x080c, 0x6dd1, 0x2a48, 0x0cb8, 0x080c, + 0x6dd1, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, + 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, + 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, + 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, 0x1148, 0x2018, + 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, + 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, + 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, + 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xce56, 0x0150, 0x2001, + 0x0006, 0xa980, 0xc1d5, 0x080c, 0x703d, 0x080c, 0x6dc4, 0x080c, + 0xd041, 0x009e, 0x080c, 0xb134, 0x00ee, 0x00de, 0x00ce, 0x0005, + 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, 0x6020, 0x9086, + 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, 0x9186, 0x008b, + 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, 0x2091, 0x8000, + 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, 0x012e, 0x006e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000, 0x6020, + 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0xca9f, 0xca9f, + 0xca9a, 0xcac1, 0xca8d, 0xca9a, 0xcac1, 0xca9a, 0xca9a, 0x911f, + 0xca9a, 0xca9a, 0xca9a, 0xca8d, 0xca8d, 0x080c, 0x0dc5, 0x0036, + 0x2019, 0x0010, 0x080c, 0xe4c8, 0x6023, 0x0006, 0x6003, 0x0007, + 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x0096, + 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c, 0xce56, 0x01c0, 0xa864, + 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, + 0x900e, 0x2001, 0x0005, 0x080c, 0x703d, 0x080c, 0xd152, 0x080c, + 0x6dc4, 0x080c, 0xb134, 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, + 0x0ce0, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0002, 0xcad7, + 0xcb07, 0xcad9, 0xcb28, 0xcb02, 0xcad7, 0xca9a, 0xca9f, 0xca9f, + 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0x080c, + 0x0dc5, 0x86ff, 0x1520, 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, + 0x6014, 0x2048, 0x080c, 0xce56, 0x0168, 0xa87c, 0xd0cc, 0x0140, + 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, + 0x080c, 0xd152, 0x009e, 0x080c, 0xd51b, 0x6007, 0x0085, 0x6003, + 0x000b, 0x6023, 0x0002, 0x080c, 0x933b, 0x080c, 0x98ed, 0x9085, + 0x0001, 0x0005, 0x0066, 0x080c, 0x1ab7, 0x006e, 0x0890, 0x00e6, + 0x2071, 0x19e9, 0x7024, 0x9c06, 0x1120, 0x080c, 0xa801, 0x00ee, + 0x0840, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, + 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0xa929, 0x009e, 0x008e, + 0x0010, 0x080c, 0xa6fe, 0x00ee, 0x1904, 0xcad9, 0x0804, 0xca9a, + 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06, 0x1138, 0x901e, + 0x080c, 0xa877, 0x00ee, 0x003e, 0x0804, 0xcad9, 0x080c, 0xaa59, + 0x00ee, 0x003e, 0x1904, 0xcad9, 0x0804, 0xca9a, 0x00c6, 0x6020, + 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xcb5b, 0xcc25, 0xcd8f, + 0xcb65, 0xb134, 0xcb5b, 0xe4ba, 0xd583, 0xcc25, 0x90f1, 0xce1b, + 0xcb54, 0xcb54, 0xcb54, 0xcb54, 0x080c, 0x0dc5, 0x080c, 0xd05e, + 0x1110, 0x080c, 0xbae2, 0x0005, 0x080c, 0x97e1, 0x080c, 0x98ed, + 0x0804, 0xb101, 0x601b, 0x0001, 0x0005, 0x080c, 0xce56, 0x0130, + 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, 0x6000, 0x908a, + 0x0010, 0x1a0c, 0x0dc5, 0x0002, 0xcb84, 0xcb86, 0xcbaa, 0xcbbe, + 0xcbe4, 0xcb84, 0xcb5b, 0xcb5b, 0xcb5b, 0xcbbe, 0xcbbe, 0xcb84, + 0xcb84, 0xcb84, 0xcb84, 0xcbc8, 0x080c, 0x0dc5, 0x00e6, 0x6014, + 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9, + 0x7024, 0x9c06, 0x01a0, 0x080c, 0xa6fe, 0x080c, 0xd51b, 0x6007, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, + 0x601a, 0x080c, 0x933b, 0x080c, 0x98ed, 0x00ee, 0x0005, 0x601b, + 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, + 0x009e, 0x080c, 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0005, 0x0096, 0x601b, + 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, + 0x080c, 0x57db, 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, + 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, + 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, + 0x6dd1, 0x009e, 0x0804, 0xb101, 0x6014, 0x0096, 0x904d, 0x05c0, + 0xa97c, 0xd1e4, 0x05a8, 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, + 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, + 0x611a, 0x2001, 0x0030, 0x2c08, 0x080c, 0x1611, 0x2001, 0x030c, + 0x2004, 0x9086, 0x0041, 0x1198, 0x6014, 0x0096, 0x904d, 0x090c, + 0x0dc5, 0xa880, 0xd0f4, 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, + 0x0002, 0x0068, 0x009e, 0x00c6, 0x080c, 0x2397, 0x00ce, 0x6000, + 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xb180, 0x0005, + 0x009e, 0x080c, 0x1ab7, 0x0804, 0xcbaa, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0xcc3c, 0xcb62, 0xcc3e, 0xcc3c, + 0xcc3e, 0xcc3e, 0xcb5c, 0xcc3c, 0xcb56, 0xcb56, 0xcc3c, 0xcc3c, + 0xcc3c, 0xcc3c, 0xcc3c, 0xcc3c, 0x080c, 0x0dc5, 0x6010, 0x00b6, + 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, + 0x0dc5, 0x00b6, 0x0013, 0x00be, 0x0005, 0xcc59, 0xcd26, 0xcc5b, + 0xcc9b, 0xcc5b, 0xcc9b, 0xcc5b, 0xcc69, 0xcc59, 0xcc9b, 0xcc59, + 0xcc8a, 0x080c, 0x0dc5, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, + 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, + 0xcd22, 0x6004, 0x080c, 0xd05e, 0x0904, 0xcd3f, 0x908e, 0x0004, + 0x1110, 0x080c, 0x326f, 0x908e, 0x0021, 0x0904, 0xcd43, 0x908e, + 0x0022, 0x0904, 0xcd8a, 0x908e, 0x003d, 0x0904, 0xcd43, 0x908e, + 0x0039, 0x0904, 0xcd47, 0x908e, 0x0035, 0x0904, 0xcd47, 0x908e, + 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, + 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3246, 0x080c, + 0xbae2, 0x0804, 0xb134, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, + 0x0904, 0xcd13, 0x9186, 0x0002, 0x1904, 0xcce8, 0x2001, 0x1837, + 0x2004, 0xd08c, 0x11c8, 0x080c, 0x7569, 0x11b0, 0x080c, 0xd561, + 0x0138, 0x080c, 0x758c, 0x1120, 0x080c, 0x7473, 0x0804, 0xcd73, + 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, + 0x080c, 0x7495, 0x0804, 0xcd73, 0x6010, 0x2058, 0x2001, 0x1837, + 0x2004, 0xd0ac, 0x1904, 0xcd73, 0xb8a0, 0x9084, 0xff80, 0x1904, + 0xcd73, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, + 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, + 0x080c, 0xb0ab, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, + 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, + 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, 0x2104, 0xc085, + 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60ba, 0x00ee, 0x080c, + 0xbae2, 0x0030, 0x080c, 0xbae2, 0x080c, 0x3246, 0x080c, 0xd576, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x326f, 0x012e, 0x00ee, + 0x080c, 0xb134, 0x0005, 0x2001, 0x0002, 0x080c, 0x6663, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x00de, + 0x00ce, 0x0c80, 0x080c, 0x326f, 0x0804, 0xcc97, 0x00c6, 0x00d6, + 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, + 0x00ff, 0x9005, 0x0904, 0xcce8, 0x8001, 0xb842, 0x6003, 0x0001, + 0x080c, 0x9383, 0x080c, 0x98ed, 0x00de, 0x00ce, 0x0898, 0x080c, + 0xbae2, 0x0804, 0xcc99, 0x080c, 0xbb1e, 0x0804, 0xcc99, 0x00d6, + 0x2c68, 0x6104, 0x080c, 0xd4d7, 0x00de, 0x0118, 0x080c, 0xb101, + 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, + 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, + 0x2001, 0x1988, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, + 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x0005, 0x00de, 0x00ce, 0x080c, 0xbae2, 0x080c, + 0x3246, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x326f, 0x6017, + 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e, + 0x00ee, 0x0005, 0x080c, 0xb536, 0x1904, 0xcd3f, 0x0005, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x00d6, 0x001b, 0x00de, + 0x009e, 0x0005, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, + 0xcdaa, 0xcdaa, 0xcdaa, 0xcb5b, 0xcdaa, 0xcb62, 0xcdac, 0xcb62, + 0xcdc6, 0xcdaa, 0x080c, 0x0dc5, 0x6004, 0x9086, 0x008b, 0x01b0, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, + 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003, + 0x000d, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0005, 0x080c, 0xd555, + 0x0118, 0x080c, 0xd568, 0x0010, 0x080c, 0xd576, 0x080c, 0xd041, + 0x080c, 0xce56, 0x0570, 0x080c, 0x3246, 0x080c, 0xce56, 0x0168, + 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, + 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6dd1, 0x2c68, 0x080c, 0xb0ab, + 0x0150, 0x6810, 0x6012, 0x080c, 0xd2d2, 0x00c6, 0x2d60, 0x080c, + 0xb134, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, + 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x00c8, 0x080c, 0xd555, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118, + 0x080c, 0x3246, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, + 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3246, 0x0868, + 0x080c, 0xb134, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, + 0x0002, 0xce31, 0xce31, 0xce35, 0xce33, 0xce3f, 0xce31, 0xce31, + 0xb134, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31, + 0xce31, 0x080c, 0x0dc5, 0x080c, 0xaa59, 0x6114, 0x0096, 0x2148, + 0xa87b, 0x0006, 0x080c, 0x6dd1, 0x009e, 0x0804, 0xb101, 0x601c, + 0xd084, 0x190c, 0x1ab7, 0x0c88, 0x9284, 0x0007, 0x1158, 0x9282, + 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, 0x9085, + 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, + 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, + 0x0110, 0x080c, 0x10b9, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, + 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071, + 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, + 0x080c, 0xd561, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, + 0x0004, 0x1148, 0x080c, 0x3246, 0x080c, 0xd576, 0x00c6, 0x080c, + 0xb134, 0x00ce, 0x0060, 0x080c, 0xd24c, 0x0148, 0x080c, 0xd05e, + 0x1110, 0x080c, 0xbae2, 0x00c6, 0x080c, 0xb101, 0x00ce, 0x9ce0, + 0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, + 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, + 0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab8, 0x6112, 0x080c, 0x3246, + 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb0ab, 0x01b0, 0x6656, + 0x2b00, 0x6012, 0x080c, 0x57db, 0x0118, 0x080c, 0xcf85, 0x0168, + 0x080c, 0xd2d2, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xb180, + 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xb153, 0x0560, 0x6057, + 0x0000, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0003, 0x0016, + 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x2c08, 0x080c, + 0xe690, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0xb101, 0x9085, + 0x0001, 0x0070, 0x080c, 0x57db, 0x0128, 0xd18c, 0x1170, 0x080c, + 0xcf85, 0x0148, 0x2009, 0x004c, 0x080c, 0xb180, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, + 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, + 0x0016, 0x080c, 0xb0ab, 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812, + 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcf97, 0x001e, + 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, 0x1981, + 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb101, 0x00d0, 0x2001, + 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb101, 0x0088, + 0x2f60, 0x080c, 0x57db, 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148, + 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xb180, 0x9085, + 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, + 0x0046, 0x080c, 0xb0ab, 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812, + 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, 0x2001, + 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb101, 0x0060, + 0x2f60, 0x080c, 0x57db, 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130, + 0x2009, 0x0052, 0x080c, 0xb180, 0x9085, 0x0001, 0x004e, 0x00ce, + 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, 0x4b89, + 0x00ce, 0x1120, 0x080c, 0xb101, 0x9006, 0x0005, 0xa867, 0x0000, + 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, 0x0096, + 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x6851, 0x0158, 0x2001, + 0xcf9c, 0x0006, 0x900e, 0x2400, 0x080c, 0x703d, 0x080c, 0x6dd1, + 0x000e, 0x0807, 0x2418, 0x080c, 0x977b, 0xbaa0, 0x0086, 0x2041, + 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x94f8, 0x008e, 0x080c, + 0x93b3, 0x2f08, 0x2648, 0x080c, 0xe690, 0xb93c, 0x81ff, 0x090c, + 0x95cb, 0x080c, 0x98ed, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0xb0ab, 0x0190, 0x660a, 0x2b08, + 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, + 0x001f, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153, + 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0008, + 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, 0x2009, + 0x0021, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, + 0x8000, 0x080c, 0xb0ab, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, + 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, + 0xb180, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, + 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153, 0x0188, + 0x2b08, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, + 0x2009, 0x0000, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, + 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, + 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, + 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, + 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, + 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, + 0xce56, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, + 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, + 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153, 0x0198, 0x2b08, + 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, + 0x3246, 0x2009, 0x0028, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, + 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xbd38, + 0x00be, 0x080c, 0xbf5d, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, + 0x9383, 0x080c, 0x98ed, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, + 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd498, 0x080c, + 0xbae2, 0x080c, 0xb101, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, + 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, + 0x012e, 0x009e, 0x080c, 0xb101, 0x0c30, 0x0096, 0x9186, 0x0016, + 0x1128, 0x2001, 0x0004, 0x080c, 0x6663, 0x00e8, 0x9186, 0x0015, + 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, + 0x00b6, 0x2058, 0x080c, 0x67b8, 0x00be, 0x080c, 0xc033, 0x1198, + 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, + 0x0006, 0x080c, 0x6663, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, + 0x080c, 0xb50a, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, + 0x080c, 0xbae2, 0x080c, 0xb101, 0x009e, 0x0005, 0x6014, 0x6310, + 0x2358, 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0000, 0xa883, 0x0000, + 0xa897, 0x4000, 0x900e, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6dd1, 0x012e, 0x080c, 0xb101, 0x08f8, 0x6014, 0x904d, 0x090c, + 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, + 0x012e, 0x080c, 0xb101, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, + 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000, + 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, + 0x0005, 0xcb5b, 0xd182, 0xd182, 0xd185, 0xe9f4, 0xea0f, 0xea12, + 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, + 0x080c, 0x0dc5, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, + 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, + 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xb0ab, + 0x0508, 0x7810, 0x6012, 0x080c, 0xd2d2, 0x7820, 0x9086, 0x0003, + 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, + 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, + 0x0001, 0x7954, 0x6156, 0x080c, 0x933b, 0x080c, 0x98ed, 0x2f60, + 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004, 0x6042, + 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180, + 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, + 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fc0, + 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, + 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, + 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, + 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, + 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, + 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954, 0x6156, + 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, + 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, + 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, + 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, + 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, + 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, + 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, + 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, + 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, + 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, + 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, + 0x00e6, 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, + 0x080c, 0x91b1, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, + 0x2202, 0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071, 0x196d, + 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x91b1, 0x2001, 0x1988, + 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989, 0x9288, + 0x000a, 0x2102, 0x2001, 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c, + 0x1611, 0x080c, 0x6a73, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003, 0x0028, + 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b, 0x0000, + 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102, 0x2001, + 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c, 0x1611, 0x00ee, 0x001e, + 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c, 0x1040, + 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, + 0xb0ab, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, + 0x6016, 0x2009, 0x0033, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, + 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018, 0x0120, + 0x7090, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, + 0x1160, 0x2c78, 0x080c, 0x9b88, 0x01d8, 0x707c, 0xaa50, 0x9206, + 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, + 0xbaa0, 0x00be, 0x900e, 0x080c, 0x328f, 0x080c, 0xb50a, 0x0020, + 0x080c, 0xbae2, 0x080c, 0xb101, 0x00fe, 0x00ee, 0x009e, 0x0005, + 0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xb0ab, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd2d2, + 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xb180, + 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xb0ab, 0x0180, 0x2b08, + 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, + 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, + 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, + 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, + 0x7190, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, + 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, + 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, + 0x080c, 0xdbac, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, + 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xbae2, 0x080c, + 0xb101, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, + 0x9186, 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198, 0x6014, + 0x2048, 0x2c78, 0x080c, 0x9b88, 0x01a8, 0x707c, 0xaa74, 0x9206, + 0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3246, 0x080c, + 0xb50a, 0x0020, 0x080c, 0xbae2, 0x080c, 0xb101, 0x00fe, 0x00ee, + 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, + 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x7090, + 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x9b88, + 0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, 0x9206, + 0x1160, 0x080c, 0x3246, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, + 0xc0fd, 0x080c, 0x5782, 0x001e, 0x0010, 0x080c, 0x556d, 0x080c, + 0xce56, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0x0080, 0x080c, 0xce56, 0x01b8, 0x6014, 0x2048, 0x080c, 0x556d, + 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6dd1, + 0x012e, 0x080c, 0xb101, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, + 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, + 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, + 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, + 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xce56, + 0x0904, 0xd494, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, + 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, + 0xd0f4, 0x1140, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa85c, 0x9080, + 0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0f8b, + 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, + 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, + 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, + 0x6dc4, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, + 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, + 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, + 0x9084, 0x00ff, 0x900e, 0x080c, 0x2894, 0x2118, 0x831f, 0x939c, + 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, + 0x080c, 0x4be9, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, + 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, + 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, + 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, + 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, + 0x080c, 0xce44, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, + 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, + 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, + 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, + 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0198, 0x918c, + 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, 0x000f, 0x918e, + 0x0001, 0x1140, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xc509, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, + 0x901e, 0x0499, 0x01e0, 0x080c, 0xce56, 0x01c8, 0x080c, 0xd041, + 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, + 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x0040, 0xa867, 0x0103, + 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6dd1, 0x009e, 0x003e, + 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, + 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, + 0x080c, 0xd152, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, + 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, + 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, + 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, + 0x0007, 0x080c, 0x4da0, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, + 0x0005, 0x2001, 0x1987, 0x2004, 0x601a, 0x0005, 0x2001, 0x1989, + 0x2004, 0x6042, 0x0005, 0x080c, 0xb101, 0x0804, 0x98ed, 0x2001, + 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19e9, + 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x921e, 0x00ce, 0x00ee, + 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001, + 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, + 0x001b, 0x006e, 0x00be, 0x0005, 0xd5c4, 0xdd0b, 0xde80, 0xd5c4, + 0xd5c4, 0xd5c4, 0xd5c4, 0xd5c4, 0xd5fb, 0xdf04, 0xd5c4, 0xd5c4, + 0xd5c4, 0xd5c4, 0xd5c4, 0xd5c4, 0x080c, 0x0dc5, 0x0066, 0x6000, + 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xd5df, + 0xe453, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xe400, + 0xe4a7, 0xd5df, 0xeb2f, 0xeb65, 0xeb2f, 0xeb65, 0xd5df, 0x080c, + 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0dc5, 0x6000, 0x000a, + 0x0005, 0xd5f9, 0xe0e2, 0xe1b1, 0xe1d4, 0xe294, 0xd5f9, 0xe373, + 0xe31c, 0xdf10, 0xe3d6, 0xe3eb, 0xd5f9, 0xd5f9, 0xd5f9, 0xd5f9, + 0xd5f9, 0x080c, 0x0dc5, 0x91b2, 0x0053, 0x1a0c, 0x0dc5, 0x2100, + 0x91b2, 0x0040, 0x1a04, 0xda7b, 0x0002, 0xd645, 0xd849, 0xd645, + 0xd645, 0xd645, 0xd852, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, + 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, + 0xd645, 0xd645, 0xd645, 0xd645, 0xd647, 0xd6aa, 0xd6b9, 0xd71d, + 0xd748, 0xd7c1, 0xd834, 0xd645, 0xd645, 0xd855, 0xd645, 0xd645, + 0xd86a, 0xd877, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd91d, + 0xd645, 0xd645, 0xd931, 0xd645, 0xd645, 0xd8ec, 0xd645, 0xd645, + 0xd645, 0xd949, 0xd645, 0xd645, 0xd645, 0xd9c6, 0xd645, 0xd645, + 0xd645, 0xd645, 0xd645, 0xd645, 0xda43, 0x080c, 0x0dc5, 0x080c, + 0x6a50, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, + 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, + 0x6017, 0x0000, 0x0804, 0xd842, 0x080c, 0x69ec, 0x00e6, 0x00c6, + 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, + 0x0029, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x2c08, + 0x080c, 0xe690, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, + 0x00ee, 0x6610, 0x2658, 0x080c, 0x672c, 0xbe04, 0x9684, 0x00ff, + 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, + 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xed90, 0x002e, 0x001e, 0x1178, + 0x080c, 0xe5c2, 0x1904, 0xd715, 0x080c, 0xe55e, 0x1120, 0x6007, + 0x0008, 0x0804, 0xd842, 0x6007, 0x0009, 0x0804, 0xd842, 0x080c, + 0xe82d, 0x0128, 0x080c, 0xe5c2, 0x0d78, 0x0804, 0xd715, 0x6017, + 0x1900, 0x0c88, 0x080c, 0x336a, 0x1904, 0xda78, 0x6106, 0x080c, + 0xe502, 0x6007, 0x0006, 0x0804, 0xd842, 0x6007, 0x0007, 0x0804, + 0xd842, 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904, + 0xda78, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, + 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x664f, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, + 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, + 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, + 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, + 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe626, 0x1190, 0x9686, 0x0006, + 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x328f, + 0x002e, 0x080c, 0x67b8, 0x6007, 0x000a, 0x00de, 0x0804, 0xd842, + 0x6007, 0x000b, 0x00de, 0x0804, 0xd842, 0x080c, 0x3246, 0x080c, + 0xd576, 0x6007, 0x0001, 0x0804, 0xd842, 0x080c, 0xeba1, 0x1904, + 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x2071, 0x0260, 0x7034, + 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, + 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, + 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x328f, 0x002e, + 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xed6f, 0x0804, 0xd842, + 0x080c, 0x6a50, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, + 0x9086, 0x0008, 0x1110, 0x0804, 0xd654, 0x080c, 0x69ec, 0x6610, + 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, + 0x0026, 0x2001, 0x0006, 0x080c, 0x668f, 0x002e, 0x0050, 0x96b4, + 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, + 0xd715, 0x080c, 0xe633, 0x1120, 0x6007, 0x000e, 0x0804, 0xd842, + 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3246, 0x080c, + 0xd576, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, + 0x0148, 0x2009, 0x0029, 0x080c, 0xe9a5, 0x6010, 0x2058, 0xb800, + 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xd842, + 0x2001, 0x0001, 0x080c, 0x664f, 0x0156, 0x0016, 0x0026, 0x0036, + 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xc0e3, + 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, + 0x8637, 0x9682, 0x0004, 0x0a04, 0xd715, 0x9682, 0x0007, 0x0a04, + 0xd771, 0x0804, 0xd715, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, + 0xd842, 0x080c, 0x6a50, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, + 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd654, 0x080c, 0x69ec, + 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, + 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, + 0x001e, 0x000e, 0x9082, 0x0006, 0x06a0, 0x0150, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd715, + 0x080c, 0xe661, 0x1138, 0x080c, 0xe55e, 0x1120, 0x6007, 0x0010, + 0x0804, 0xd842, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, + 0x3246, 0x080c, 0xd576, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, + 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe9a5, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, - 0x0804, 0xdac4, 0x2001, 0x0001, 0x080c, 0x6656, 0x0156, 0x0016, - 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, - 0x080c, 0xc365, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, - 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xd997, 0x9682, - 0x0007, 0x0a04, 0xd9f3, 0x0804, 0xd997, 0x6017, 0x1900, 0x6007, - 0x0009, 0x0804, 0xdac4, 0x080c, 0x6a61, 0x1140, 0x2001, 0x1837, - 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd8d6, - 0x080c, 0x69fd, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, - 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, - 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, 0x06a0, 0x0150, - 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, - 0x1904, 0xd997, 0x080c, 0xe8ed, 0x1138, 0x080c, 0xe7ea, 0x1120, - 0x6007, 0x0010, 0x0804, 0xdac4, 0x0046, 0x6410, 0x2458, 0xbca0, - 0x0046, 0x080c, 0x3250, 0x080c, 0xd7f8, 0x004e, 0x0016, 0x9006, - 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, - 0xec31, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, - 0x6007, 0x0001, 0x0448, 0x080c, 0xeab9, 0x0198, 0x0016, 0x968c, - 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, - 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0920, 0x0804, 0xd997, - 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x3374, - 0x1904, 0xdcfa, 0x080c, 0xee26, 0x1904, 0xdcfa, 0x080c, 0xdecb, - 0x1904, 0xd997, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x9547, - 0x080c, 0x9ab1, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, - 0x9547, 0x080c, 0x9ab1, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, - 0xee26, 0x1904, 0xdcfa, 0x080c, 0x3374, 0x1904, 0xdcfa, 0x080c, - 0xdecb, 0x1904, 0xd997, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, - 0x9547, 0x080c, 0x9ab1, 0x0005, 0x080c, 0x3374, 0x1904, 0xdcfa, - 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, - 0x0005, 0x080c, 0xee26, 0x1904, 0xdcfa, 0x080c, 0x3374, 0x1904, - 0xdcfa, 0x080c, 0xdecb, 0x1904, 0xd997, 0x0016, 0x0026, 0x00e6, - 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c, 0x9206, - 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, - 0x11a0, 0x7240, 0x080c, 0xd0c6, 0x0570, 0x2260, 0x6008, 0x9086, - 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, - 0x0007, 0x1508, 0x080c, 0xb2d3, 0x04a0, 0x7244, 0x9286, 0xffff, - 0x0180, 0x2c08, 0x080c, 0xd0c6, 0x01b0, 0x2260, 0x7240, 0x6008, - 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, - 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xebfb, 0x1180, 0x7244, - 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, - 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, - 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, - 0xb2d3, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x9547, - 0x080c, 0x9ab1, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, - 0x080c, 0x6656, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, - 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xc365, 0x003e, 0x002e, - 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xdac4, 0x080c, - 0xbf7b, 0x080c, 0x7637, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, - 0x7651, 0x1138, 0x080c, 0x7932, 0x080c, 0x612e, 0x080c, 0x7563, - 0x0010, 0x080c, 0x760f, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, - 0x3374, 0x1904, 0xdcfa, 0x080c, 0xdecb, 0x1904, 0xd997, 0x6106, - 0x080c, 0xdee7, 0x1120, 0x6007, 0x002b, 0x0804, 0xdac4, 0x6007, - 0x002c, 0x0804, 0xdac4, 0x080c, 0xee26, 0x1904, 0xdcfa, 0x080c, - 0x3374, 0x1904, 0xdcfa, 0x080c, 0xdecb, 0x1904, 0xd997, 0x6106, - 0x080c, 0xdeec, 0x1120, 0x6007, 0x002e, 0x0804, 0xdac4, 0x6007, - 0x002f, 0x0804, 0xdac4, 0x080c, 0x3374, 0x1904, 0xdcfa, 0x00e6, - 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, - 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, - 0x00ce, 0x00de, 0x00ee, 0x0804, 0xdacb, 0x080c, 0x57d9, 0xd0e4, - 0x0904, 0xdc45, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, - 0x7108, 0x720c, 0x080c, 0x6a9f, 0x0140, 0x6010, 0x2058, 0xb810, - 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x6a9b, 0x15b8, - 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, - 0x7210, 0x080c, 0xd0c6, 0x0590, 0x080c, 0xddb8, 0x0578, 0x080c, - 0xecad, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, - 0x94ff, 0x080c, 0x9ab1, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, - 0x9286, 0xffff, 0x0150, 0x080c, 0xd0c6, 0x01c0, 0x9280, 0x0002, - 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, - 0x0001, 0x080c, 0xebfb, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, - 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, - 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, - 0x080c, 0x3374, 0x1904, 0xdcfa, 0x6010, 0x2058, 0xb804, 0x9084, - 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xdacb, 0x00e6, 0x00d6, - 0x00c6, 0x080c, 0x57d9, 0xd0e4, 0x0904, 0xdcbd, 0x2069, 0x1800, - 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, - 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xebfb, - 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xd0c6, 0x05d0, 0x7108, 0x9280, - 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, - 0xcce6, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, - 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, - 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xddb8, 0x0904, - 0xdc3e, 0x0056, 0x7510, 0x7614, 0x080c, 0xecc6, 0x005e, 0x00ce, - 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, - 0x2a00, 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0c78, - 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, - 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0c10, 0x6007, 0x003b, 0x602f, - 0x000b, 0x6017, 0x0000, 0x0804, 0xdc15, 0x00e6, 0x0026, 0x080c, - 0x6a61, 0x0550, 0x080c, 0x69fd, 0x080c, 0xee97, 0x1518, 0x2071, - 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, - 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, - 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a9f, - 0x0120, 0x2011, 0x1a01, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, - 0x3000, 0x0010, 0x080c, 0xeecb, 0x002e, 0x00ee, 0x080c, 0xb2d3, - 0x0804, 0xdaca, 0x080c, 0xb2d3, 0x0005, 0x2600, 0x0002, 0xdd11, - 0xdd3f, 0xdd50, 0xdd11, 0xdd11, 0xdd13, 0xdd61, 0xdd11, 0xdd11, - 0xdd11, 0xdd2d, 0xdd11, 0xdd11, 0xdd11, 0xdd6c, 0xdd82, 0xddb3, - 0xdd11, 0x080c, 0x0dc5, 0x080c, 0xee26, 0x1d20, 0x080c, 0x3374, - 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, - 0x9547, 0x0005, 0x080c, 0x3250, 0x080c, 0xd7f8, 0x6007, 0x0001, - 0x6003, 0x0001, 0x080c, 0x9547, 0x0005, 0x080c, 0xee26, 0x1950, - 0x080c, 0x3374, 0x1938, 0x080c, 0xdecb, 0x1d60, 0x703c, 0x6016, - 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x9547, 0x0005, 0x080c, - 0x3374, 0x1904, 0xdcfa, 0x2009, 0x0041, 0x080c, 0xeed4, 0x6007, - 0x0047, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0005, - 0x080c, 0x3374, 0x1904, 0xdcfa, 0x2009, 0x0042, 0x080c, 0xeed4, - 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, - 0x0005, 0x080c, 0x3374, 0x1904, 0xdcfa, 0x2009, 0x0046, 0x080c, - 0xeed4, 0x080c, 0xb2d3, 0x0005, 0x2001, 0x1824, 0x2004, 0x9082, - 0x00e1, 0x1268, 0x080c, 0xddd5, 0x0904, 0xdcfa, 0x6007, 0x004e, - 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0005, 0x6007, - 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, - 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, - 0x19be, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x19bf, 0x2004, - 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, - 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc379, - 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x9547, - 0x080c, 0x9ab1, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, - 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, - 0x2058, 0xb8cc, 0xd084, 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, - 0x712c, 0x6048, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, - 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, - 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, - 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000, 0x080c, 0x1027, - 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816, 0x908a, 0x001e, - 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, 0x200c, 0x0471, - 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1027, 0x01b0, 0x2900, - 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, 0x200c, 0x00b1, - 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x7093, - 0x0000, 0x6014, 0x2048, 0x080c, 0x0fc0, 0x9006, 0x012e, 0x01de, - 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, - 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, 0x23e2, - 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, - 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, - 0x23e2, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x23e2, 0x2061, 0x19a1, - 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, - 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x23e2, - 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a1, 0x2019, 0x0280, 0x3300, - 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, - 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, - 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, - 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x23fa, 0x20a1, 0x024c, 0x2001, - 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, - 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x23fa, 0x20a1, - 0x0240, 0x0c98, 0x080c, 0x23fa, 0x2061, 0x19a4, 0x6004, 0x20a0, - 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, - 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x23fa, 0x20a1, - 0x0240, 0x0c98, 0x2061, 0x19a4, 0x2019, 0x0260, 0x3400, 0x931e, - 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, - 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, - 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, - 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, - 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, - 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, - 0x080c, 0xdf63, 0x00de, 0x0005, 0x00d6, 0x080c, 0xdf70, 0x1520, - 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, - 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xeff4, 0x2009, - 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, - 0x080c, 0x2873, 0x1148, 0x2001, 0x0001, 0x080c, 0xeff4, 0x2110, - 0x900e, 0x080c, 0x3299, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, - 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xb325, 0x05a8, 0x0016, - 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, - 0x2873, 0x1578, 0x080c, 0x66b9, 0x1560, 0xbe12, 0xbd16, 0x00ce, - 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xee26, 0x11d8, 0x080c, - 0x3374, 0x11c0, 0x080c, 0xdecb, 0x0510, 0x2001, 0x0007, 0x080c, - 0x666a, 0x2001, 0x0007, 0x080c, 0x6696, 0x6017, 0x0000, 0x6023, - 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, - 0x9ab1, 0x0010, 0x080c, 0xb2d3, 0x9085, 0x0001, 0x00ce, 0x00be, - 0x0005, 0x080c, 0xb2d3, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, - 0xb2d3, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, - 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, - 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, - 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, - 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, - 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, - 0x1a0c, 0x0dc5, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, - 0x1a04, 0xe0d2, 0x040a, 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, - 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xd809, 0x0128, 0x6000, - 0x9086, 0x0002, 0x0904, 0xbcfd, 0x0005, 0x91b6, 0x0014, 0x190c, - 0x0dc5, 0x2001, 0x0007, 0x080c, 0x6696, 0x080c, 0x99a5, 0x080c, - 0xb306, 0x080c, 0x9ab1, 0x0005, 0xdffc, 0xdffe, 0xdffc, 0xdffc, - 0xdffc, 0xdffe, 0xe00d, 0xe0cb, 0xe051, 0xe0cb, 0xe079, 0xe0cb, - 0xe00d, 0xe0cb, 0xe0c3, 0xe0cb, 0xe0c3, 0xe0cb, 0xe0cb, 0xdffc, - 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xdffc, - 0xdffc, 0xdffc, 0xdffe, 0xdffc, 0xe0cb, 0xdffc, 0xdffc, 0xe0cb, - 0xdffc, 0xe0c8, 0xe0cb, 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xe0cb, - 0xe0cb, 0xdffc, 0xe0cb, 0xe0cb, 0xdffc, 0xe008, 0xdffc, 0xdffc, - 0xdffc, 0xdffc, 0xe0c7, 0xe0cb, 0xdffc, 0xdffc, 0xe0cb, 0xe0cb, - 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0x080c, 0x0dc5, 0x080c, 0x99a5, - 0x080c, 0xd7fb, 0x6003, 0x0002, 0x080c, 0x9ab1, 0x0804, 0xe0d1, - 0x9006, 0x080c, 0x6656, 0x0804, 0xe0cb, 0x080c, 0x6a9b, 0x1904, - 0xe0cb, 0x9006, 0x080c, 0x6656, 0x6010, 0x2058, 0xb810, 0x9086, - 0x00ff, 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, - 0x00fe, 0x00b8, 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0904, 0xe0cb, - 0x080c, 0x33a5, 0x1904, 0xe0cb, 0x2001, 0x1800, 0x2004, 0x9086, - 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, - 0x00fe, 0x2001, 0x0002, 0x080c, 0x666a, 0x080c, 0x99a5, 0x6023, - 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9547, 0x080c, - 0x9ab1, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x884b, 0x0804, - 0xe0d1, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, - 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, 0x080c, 0x9031, 0x2001, - 0x0004, 0x080c, 0x6696, 0x080c, 0xf043, 0x0904, 0xe0cb, 0x080c, - 0x99a5, 0x2001, 0x0004, 0x080c, 0x666a, 0x6023, 0x0001, 0x6003, - 0x0001, 0x6007, 0x0003, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0804, - 0xe0d1, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, - 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4dfb, - 0x004e, 0x003e, 0x2001, 0x0006, 0x080c, 0xe0ef, 0x6610, 0x2658, - 0xbe04, 0x0066, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, - 0x0180, 0x2001, 0x0006, 0x080c, 0x6696, 0x9284, 0x00ff, 0x908e, - 0x0007, 0x0118, 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, - 0x666a, 0x080c, 0x6a9b, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, - 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, - 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xe039, - 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, - 0x0010, 0x080c, 0x6696, 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x080c, - 0x9ab1, 0x0005, 0x2600, 0x0002, 0xe0e6, 0xe0e6, 0xe0e6, 0xe0e6, - 0xe0e6, 0xe0e8, 0xe0e6, 0xe0e8, 0xe0e6, 0xe0e6, 0xe0e8, 0xe0e6, - 0xe0e6, 0xe0e6, 0xe0e8, 0xe0e8, 0xe0e8, 0xe0e8, 0x080c, 0x0dc5, - 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x0016, - 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, - 0x666a, 0x9006, 0x080c, 0x6656, 0x080c, 0x3279, 0x00de, 0x00be, - 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, - 0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x91b6, 0x0015, 0x1110, 0x003b, - 0x0028, 0x91b6, 0x0016, 0x190c, 0x0dc5, 0x006b, 0x0005, 0xbd9f, - 0xbd9f, 0xbd9f, 0xbd9f, 0xe184, 0xbd9f, 0xe16e, 0xe12f, 0xbd9f, - 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0xe184, - 0xbd9f, 0xe16e, 0xe175, 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0x00f6, - 0x080c, 0x6a9b, 0x11d8, 0x080c, 0xd7e3, 0x11c0, 0x6010, 0x905d, - 0x01a8, 0xb8c0, 0x9005, 0x0190, 0x9006, 0x080c, 0x6656, 0x2001, - 0x0002, 0x080c, 0x666a, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x00f0, 0x2011, 0x0263, - 0x2204, 0x8211, 0x220c, 0x080c, 0x2873, 0x11b0, 0x080c, 0x6724, - 0x0118, 0x080c, 0xb2d3, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, - 0xb8c0, 0x0006, 0x080c, 0x6148, 0x000e, 0xb8c2, 0x000e, 0xb816, - 0x000e, 0xb812, 0x080c, 0xb2d3, 0x00fe, 0x0005, 0x6604, 0x96b6, - 0x001e, 0x1110, 0x080c, 0xb2d3, 0x0005, 0x080c, 0xc1dc, 0x1148, - 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, - 0x0010, 0x080c, 0xb2d3, 0x0005, 0x0804, 0xb2d3, 0x6004, 0x908a, - 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0x99a5, 0x080c, 0xb306, 0x080c, - 0x9ab1, 0x0005, 0x9182, 0x0040, 0x0002, 0xe1a9, 0xe1a9, 0xe1a9, - 0xe1a9, 0xe1ab, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, - 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, - 0xe1a9, 0x080c, 0x0dc5, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, - 0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11a8, 0x6106, - 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xe211, 0x080c, - 0xefe8, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, - 0x0200, 0x080c, 0x8a50, 0x0020, 0x9026, 0x080c, 0xee6b, 0x0c38, - 0x080c, 0x100e, 0x090c, 0x0dc5, 0x6003, 0x0007, 0xa867, 0x010d, - 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, - 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, - 0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6e9f, 0x001e, - 0x080c, 0xefe8, 0x1904, 0xe271, 0x9486, 0x2000, 0x1130, 0x2019, - 0x0017, 0x080c, 0xeba1, 0x0804, 0xe271, 0x9486, 0x0200, 0x1120, - 0x080c, 0xeb38, 0x0804, 0xe271, 0x9486, 0x0400, 0x0120, 0x9486, - 0x1000, 0x1904, 0xe271, 0x2019, 0x0002, 0x080c, 0xeb53, 0x0804, - 0xe271, 0x2069, 0x1a74, 0x6a00, 0xd284, 0x0904, 0xe2db, 0x9284, - 0x0300, 0x1904, 0xe2d4, 0x6804, 0x9005, 0x0904, 0xe2bc, 0x2d78, - 0x6003, 0x0007, 0x080c, 0x1027, 0x0904, 0xe27d, 0x7800, 0xd08c, - 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, - 0x2004, 0xd084, 0x1904, 0xe2df, 0x9006, 0xa802, 0xa867, 0x0116, - 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, - 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, - 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, - 0x9080, 0xe279, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, - 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, - 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, - 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, - 0x6e9f, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, - 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, - 0xd084, 0x0120, 0x080c, 0x100e, 0x1904, 0xe226, 0x6017, 0xf100, - 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x94ff, 0x080c, 0x9ab1, - 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, - 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, - 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, - 0x94ff, 0x080c, 0x9ab1, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, - 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x94ff, - 0x080c, 0x9ab1, 0x0804, 0xe271, 0x2001, 0x180e, 0x2004, 0xd0ec, - 0x0120, 0x2011, 0x8049, 0x080c, 0x4c44, 0x6017, 0xf300, 0x0010, - 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x94ff, - 0x080c, 0x9ab1, 0x0804, 0xe271, 0x6017, 0xf500, 0x0c98, 0x6017, - 0xf600, 0x0804, 0xe291, 0x6017, 0xf200, 0x0804, 0xe291, 0xa867, - 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, - 0x9084, 0x0003, 0x9080, 0xe279, 0x2005, 0xa87e, 0x2928, 0x6010, - 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, - 0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, - 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, - 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0dc5, 0x8210, - 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, - 0x0029, 0x20a0, 0x2011, 0xe35b, 0x2041, 0x0001, 0x223d, 0x9784, - 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, - 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, - 0x0c68, 0x2950, 0x080c, 0x1027, 0x0170, 0x2900, 0xb002, 0xa867, - 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, - 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, - 0x1040, 0x0cc8, 0x080c, 0x1040, 0x0804, 0xe27d, 0x2548, 0x8847, - 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, - 0xebd4, 0x0804, 0xe271, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, - 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, - 0x908a, 0x0054, 0x1a0c, 0x0dc5, 0x9082, 0x0040, 0x0a0c, 0x0dc5, - 0x2008, 0x0804, 0xe3ea, 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, - 0xd809, 0x0500, 0x6000, 0x9086, 0x0002, 0x11e0, 0x0804, 0xe433, - 0x9186, 0x0027, 0x0190, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, - 0x0160, 0x190c, 0x0dc5, 0x080c, 0xd809, 0x0160, 0x6000, 0x9086, - 0x0004, 0x190c, 0x0dc5, 0x0804, 0xe516, 0x6004, 0x9082, 0x0040, - 0x2008, 0x001a, 0x080c, 0xb36d, 0x0005, 0xe3b1, 0xe3b3, 0xe3b3, - 0xe3da, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, - 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, - 0xe3b1, 0x080c, 0x0dc5, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0036, - 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, 0xd0d8, 0x01c0, 0x6003, - 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, - 0x2019, 0x0004, 0x080c, 0xebd4, 0x6017, 0x0000, 0x6018, 0x9005, - 0x1120, 0x2001, 0x1987, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, - 0x003e, 0x0005, 0x0096, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x080c, - 0xd0d8, 0x0120, 0x6014, 0x2048, 0x080c, 0x1040, 0x080c, 0xb306, - 0x009e, 0x0005, 0x0002, 0xe3ff, 0xe416, 0xe401, 0xe42d, 0xe3ff, - 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, - 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0x080c, - 0x0dc5, 0x0096, 0x080c, 0x99a5, 0x6014, 0x2048, 0xa87c, 0xd0b4, - 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xb352, 0x0010, - 0x6003, 0x0004, 0x080c, 0x9ab1, 0x009e, 0x0005, 0x080c, 0x99a5, - 0x080c, 0xd0d8, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, - 0xd1ec, 0x1138, 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x080c, 0x9ab1, - 0x0005, 0x080c, 0xee2f, 0x0db0, 0x0cc8, 0x080c, 0x99a5, 0x2009, - 0x0041, 0x0804, 0xe59e, 0x9182, 0x0040, 0x0002, 0xe44a, 0xe44c, - 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, - 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44d, - 0xe44a, 0xe44a, 0x080c, 0x0dc5, 0x0005, 0x00d6, 0x080c, 0x8a25, - 0x00de, 0x080c, 0xee87, 0x080c, 0xb2d3, 0x0005, 0x9182, 0x0040, - 0x0002, 0xe46d, 0xe46d, 0xe46d, 0xe46d, 0xe46d, 0xe46d, 0xe46d, - 0xe46d, 0xe46d, 0xe46f, 0xe4de, 0xe46d, 0xe46d, 0xe46d, 0xe46d, - 0xe4de, 0xe46d, 0xe46d, 0xe46d, 0xe46d, 0x080c, 0x0dc5, 0x2001, - 0x0105, 0x2004, 0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, - 0x2001, 0x0131, 0x2004, 0x9105, 0x1904, 0xe4de, 0x2009, 0x180c, - 0x2104, 0xd0d4, 0x0904, 0xe4de, 0xc0d4, 0x200a, 0x2009, 0x0105, - 0x2104, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867, - 0x2004, 0xd0e4, 0x1528, 0x603b, 0x0000, 0x080c, 0x9a61, 0x6014, - 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, - 0x0002, 0x0508, 0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, - 0x9bd3, 0x2009, 0x0041, 0x009e, 0x0804, 0xe59e, 0x080c, 0x9bd3, - 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8a25, 0x009e, 0x0005, - 0x2001, 0x0100, 0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, - 0x2004, 0x603a, 0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, - 0xd1cc, 0x0110, 0x080c, 0x2c7b, 0x080c, 0x9bd3, 0x6014, 0x2048, - 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x009e, - 0x0005, 0x080c, 0xee2f, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, - 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9a61, 0x080c, 0x9bd3, - 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, - 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, - 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xebd4, 0x6018, - 0x9005, 0x1128, 0x2001, 0x1987, 0x2004, 0x8003, 0x601a, 0x6017, - 0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, - 0x0002, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, - 0xe52d, 0xe52f, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, - 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe57a, 0x080c, 0x0dc5, 0x6014, - 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, - 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, - 0x2009, 0x0041, 0x009e, 0x0804, 0xe59e, 0x6003, 0x0007, 0x601b, - 0x0000, 0x080c, 0x8a25, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, - 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, - 0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, - 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, - 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, - 0x0006, 0x00e9, 0x080c, 0x8a27, 0x009e, 0x0005, 0x6003, 0x0002, - 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1608, 0x1904, - 0xe52f, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, - 0x9105, 0x1120, 0x080c, 0x1608, 0x1904, 0xe52f, 0x0005, 0xd2fc, - 0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, - 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, - 0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, - 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0xe5c2, 0xe5ce, - 0xe5da, 0xe5e6, 0xe5c2, 0xe5c2, 0xe5c2, 0xe5c2, 0xe5c9, 0xe5c4, - 0xe5c4, 0xe5c2, 0xe5c2, 0xe5c2, 0xe5c2, 0xe5c4, 0xe5c2, 0xe5c4, - 0xe5c2, 0xe5c9, 0x080c, 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, - 0x0005, 0x6014, 0x9005, 0x190c, 0x0dc5, 0x0005, 0x6003, 0x0001, - 0x6106, 0x080c, 0x94ff, 0x0126, 0x2091, 0x8000, 0x080c, 0x9ab1, - 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x94ff, 0x0126, - 0x2091, 0x8000, 0x080c, 0x9ab1, 0x012e, 0x0005, 0x6003, 0x0003, - 0x6106, 0x2c10, 0x080c, 0x1be0, 0x0126, 0x2091, 0x8000, 0x080c, - 0x9564, 0x080c, 0x9bd3, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, - 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, - 0x0005, 0xe615, 0xe617, 0xe629, 0xe643, 0xe615, 0xe615, 0xe615, - 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, - 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, 0x080c, 0x0dc5, 0x6014, - 0x2048, 0xa87c, 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, - 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x94ff, 0x080c, 0x9ab1, - 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, - 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x94ff, - 0x080c, 0x9ab1, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, - 0x080c, 0xebd4, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, - 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, - 0x2c10, 0x080c, 0x1be0, 0x080c, 0x9564, 0x080c, 0x9bd3, 0x0005, - 0x080c, 0x99a5, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, - 0xef85, 0x0036, 0x2019, 0x0029, 0x080c, 0xebd4, 0x003e, 0x009e, - 0x080c, 0xb306, 0x080c, 0x9ab1, 0x0005, 0x080c, 0x9a61, 0x6114, - 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xef85, 0x0036, 0x2019, - 0x0029, 0x080c, 0xebd4, 0x003e, 0x009e, 0x080c, 0xb306, 0x080c, - 0x9bd3, 0x0005, 0x9182, 0x0085, 0x0002, 0xe694, 0xe692, 0xe692, - 0xe6a0, 0xe692, 0xe692, 0xe692, 0xe692, 0xe692, 0xe692, 0xe692, - 0xe692, 0xe692, 0x080c, 0x0dc5, 0x6003, 0x000b, 0x6106, 0x080c, - 0x94ff, 0x0126, 0x2091, 0x8000, 0x080c, 0x9ab1, 0x012e, 0x0005, - 0x0026, 0x00e6, 0x080c, 0xee26, 0x0118, 0x080c, 0xb2d3, 0x0450, - 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, - 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, - 0x014e, 0x080c, 0xb5f5, 0x7220, 0x080c, 0xea29, 0x0118, 0x6007, - 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, - 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, - 0x080c, 0x9bd3, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, - 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, - 0x0dc5, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, - 0x0014, 0x0118, 0x080c, 0xb36d, 0x0050, 0x2001, 0x0007, 0x080c, - 0x6696, 0x080c, 0x99a5, 0x080c, 0xb306, 0x080c, 0x9ab1, 0x0005, - 0xe705, 0xe707, 0xe707, 0xe705, 0xe705, 0xe705, 0xe705, 0xe705, - 0xe705, 0xe705, 0xe705, 0xe705, 0xe705, 0x080c, 0x0dc5, 0x080c, - 0x99a5, 0x080c, 0xb306, 0x080c, 0x9ab1, 0x0005, 0x9182, 0x0085, - 0x0a0c, 0x0dc5, 0x9182, 0x0092, 0x1a0c, 0x0dc5, 0x9182, 0x0085, - 0x0002, 0xe726, 0xe726, 0xe726, 0xe728, 0xe726, 0xe726, 0xe726, - 0xe726, 0xe726, 0xe726, 0xe726, 0xe726, 0xe726, 0x080c, 0x0dc5, - 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, - 0x0027, 0x0118, 0x080c, 0xb36d, 0x0030, 0x080c, 0x99a5, 0x080c, - 0xb306, 0x080c, 0x9ab1, 0x0005, 0x0036, 0x080c, 0xee87, 0x6043, - 0x0000, 0x2019, 0x000b, 0x0011, 0x003e, 0x0005, 0x6010, 0x0006, - 0x0059, 0x000e, 0x6012, 0x6023, 0x0006, 0x6003, 0x0007, 0x601b, - 0x0000, 0x6043, 0x0000, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, - 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0xaafb, 0x009e, 0x008e, - 0x1550, 0x0076, 0x2c38, 0x080c, 0xaba6, 0x007e, 0x1520, 0x6000, - 0x9086, 0x0000, 0x0500, 0x6020, 0x9086, 0x0007, 0x01e0, 0x0096, - 0x601c, 0xd084, 0x0140, 0x080c, 0xee87, 0x080c, 0xd7fb, 0x080c, - 0x1a8e, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x0110, - 0x080c, 0xebd4, 0x009e, 0x6017, 0x0000, 0x080c, 0xee87, 0x6023, - 0x0007, 0x080c, 0xd7fb, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, - 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, 0x080c, - 0x2873, 0x1904, 0xe7e4, 0x0016, 0x00c6, 0x080c, 0x6724, 0x1904, - 0xe7e2, 0x001e, 0x00c6, 0x080c, 0xd7e3, 0x1130, 0xb8c0, 0x9005, - 0x0118, 0x080c, 0x33a5, 0x0148, 0x2b10, 0x2160, 0x6010, 0x0006, - 0x6212, 0x080c, 0xd7ea, 0x000e, 0x6012, 0x00ce, 0x002e, 0x0026, - 0x0016, 0x2019, 0x0029, 0x080c, 0xac6c, 0x080c, 0x96a4, 0x0076, - 0x903e, 0x080c, 0x9577, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, - 0xe91c, 0x007e, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, - 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x330e, - 0x002e, 0xbcc0, 0x001e, 0x080c, 0x6148, 0xbe12, 0xbd16, 0xbcc2, - 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, - 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, - 0x2104, 0x9086, 0x0074, 0x1904, 0xe843, 0x2069, 0x0260, 0x6944, - 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xe840, - 0x2001, 0x197c, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb8c0, - 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, - 0x0648, 0x080c, 0xefed, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, - 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, - 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, - 0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, - 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, - 0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, - 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, - 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, - 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, - 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, - 0x8217, 0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, - 0x6733, 0x0804, 0xe8ab, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, - 0x2b48, 0x2019, 0x000a, 0x080c, 0xc379, 0x009e, 0x15a8, 0x2011, - 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, - 0xc379, 0x009e, 0x1548, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, - 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, - 0xec31, 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029, 0x080c, 0x96a4, - 0x0076, 0x2039, 0x0000, 0x080c, 0x9577, 0x2c08, 0x080c, 0xe91c, - 0x007e, 0x2001, 0x0007, 0x080c, 0x6696, 0x2001, 0x0007, 0x080c, - 0x666a, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, 0x00be, - 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086, 0x0800, - 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, - 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c, 0x7930, - 0x7834, 0x080c, 0x2873, 0x11d0, 0x080c, 0x6724, 0x11b8, 0x2011, - 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, - 0xc379, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, - 0x2b48, 0x2019, 0x0006, 0x080c, 0xc379, 0x009e, 0x015e, 0x003e, - 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, - 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, - 0x080c, 0x2873, 0x11d0, 0x080c, 0x6724, 0x11b8, 0x2011, 0x0276, - 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xc379, - 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, - 0x2019, 0x0006, 0x080c, 0xc379, 0x009e, 0x015e, 0x003e, 0x002e, - 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, - 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, - 0x2029, 0x19f1, 0x252c, 0x2021, 0x19f7, 0x2424, 0x2061, 0x1cd0, - 0x2071, 0x1800, 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, - 0x1ab7, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xe9ba, 0x0018, - 0x9606, 0x0904, 0xe9ba, 0x080c, 0x8cf7, 0x0904, 0xe9b1, 0x2100, - 0x9c06, 0x0904, 0xe9b1, 0x6720, 0x9786, 0x0007, 0x0904, 0xe9b1, - 0x080c, 0xec72, 0x1904, 0xe9b1, 0x080c, 0xf00b, 0x0904, 0xe9b1, - 0x080c, 0xec62, 0x0904, 0xe9b1, 0x6720, 0x9786, 0x0001, 0x1148, - 0x080c, 0x33a5, 0x0904, 0xe9f9, 0x6004, 0x9086, 0x0000, 0x1904, - 0xe9f9, 0x9786, 0x0004, 0x0904, 0xe9f9, 0x2500, 0x9c06, 0x0904, - 0xe9b1, 0x2400, 0x9c06, 0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, - 0x15c0, 0x0096, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, - 0x1a8e, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xd2e0, 0x1130, - 0x080c, 0xbcb6, 0x009e, 0x080c, 0xb306, 0x0418, 0x6014, 0x2048, - 0x080c, 0xd0d8, 0x01d8, 0x9786, 0x0003, 0x1570, 0xa867, 0x0103, - 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, - 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xef85, 0x0016, 0x080c, - 0xd3ce, 0x080c, 0x6e92, 0x001e, 0x080c, 0xd2c3, 0x009e, 0x080c, - 0xb306, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, - 0x0804, 0xe930, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, - 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, - 0x0005, 0x0128, 0x080c, 0xef85, 0x080c, 0xebd4, 0x08f8, 0x009e, - 0x0c00, 0x9786, 0x0009, 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, - 0x6000, 0x9086, 0x0003, 0x11a0, 0x080c, 0x9a61, 0x0096, 0x6114, - 0x2148, 0x080c, 0xd0d8, 0x0118, 0x6010, 0x080c, 0x6e9f, 0x009e, - 0x00c6, 0x080c, 0xb2d3, 0x00ce, 0x0036, 0x080c, 0x9bd3, 0x003e, - 0x009e, 0x0804, 0xe9b1, 0x9786, 0x000a, 0x0904, 0xe9a1, 0x0804, - 0xe996, 0x81ff, 0x0904, 0xe9b1, 0x9180, 0x0001, 0x2004, 0x9086, - 0x0018, 0x0138, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1904, - 0xe9b1, 0x6000, 0x9086, 0x0002, 0x1904, 0xe9b1, 0x080c, 0xd2cf, - 0x0138, 0x080c, 0xd2e0, 0x1904, 0xe9b1, 0x080c, 0xbcb6, 0x0038, - 0x080c, 0x3279, 0x080c, 0xd2e0, 0x1110, 0x080c, 0xbcb6, 0x080c, - 0xb306, 0x0804, 0xe9b1, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, - 0x0005, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, - 0xebfb, 0x001e, 0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, - 0x00ce, 0x0005, 0xea48, 0xea48, 0xea48, 0xea48, 0xea48, 0xea48, - 0xea4a, 0xea48, 0xea48, 0xea48, 0xea73, 0xb306, 0xb306, 0xea48, - 0x9006, 0x0005, 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, - 0xbca0, 0x00be, 0x2c00, 0x2009, 0x0020, 0x080c, 0xec31, 0x001e, - 0x004e, 0x2019, 0x0002, 0x080c, 0xe754, 0x003e, 0x9085, 0x0001, - 0x0005, 0x0096, 0x080c, 0xd0d8, 0x0140, 0x6014, 0x904d, 0x080c, - 0xccf3, 0x687b, 0x0005, 0x080c, 0x6e9f, 0x009e, 0x080c, 0xb306, - 0x9085, 0x0001, 0x0005, 0x0019, 0x9085, 0x0001, 0x0005, 0x6000, - 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0xea8e, 0xea8e, - 0xeaa5, 0xea95, 0xeab4, 0xea8e, 0xea8e, 0xea90, 0xea8e, 0xea8e, - 0xea8e, 0xea8e, 0xea8e, 0xea8e, 0xea8e, 0xea8e, 0x080c, 0x0dc5, - 0x080c, 0xb306, 0x9085, 0x0001, 0x0005, 0x0036, 0x00e6, 0x2071, - 0x19e8, 0x703c, 0x9c06, 0x1128, 0x2019, 0x0001, 0x080c, 0xaa49, - 0x0010, 0x080c, 0xac2b, 0x00ee, 0x003e, 0x0096, 0x00d6, 0x6014, - 0x2048, 0xa87b, 0x0005, 0x080c, 0x6e9f, 0x080c, 0xb306, 0x00de, - 0x009e, 0x9085, 0x0001, 0x0005, 0x601c, 0xd084, 0x190c, 0x1a8e, - 0x0c60, 0x2001, 0x0001, 0x080c, 0x6656, 0x0156, 0x0016, 0x0026, - 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, - 0xc365, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, - 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, - 0x8000, 0x2740, 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, - 0xeb2b, 0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602, 0x1a04, - 0xeb2b, 0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, - 0xec62, 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, - 0x1548, 0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, - 0x6010, 0x9b06, 0x11f8, 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, - 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xee87, 0x080c, 0xd7fb, - 0x080c, 0x1a8e, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xd0d8, - 0x0120, 0x0046, 0x080c, 0xebd4, 0x004e, 0x009e, 0x080c, 0xb306, - 0x88ff, 0x1198, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, - 0x1210, 0x0804, 0xeade, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, - 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, - 0x00b6, 0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, - 0x2019, 0x0002, 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xaafb, - 0x009e, 0x008e, 0x903e, 0x080c, 0xaba6, 0x080c, 0xeacf, 0x005e, - 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, - 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, - 0x080c, 0x6724, 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, - 0x0001, 0x0096, 0x904e, 0x080c, 0xaafb, 0x009e, 0x008e, 0x903e, - 0x080c, 0xaba6, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xeb5e, - 0x0036, 0x2508, 0x2029, 0x0003, 0x080c, 0xeacf, 0x003e, 0x015e, - 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, - 0x0056, 0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, - 0x0048, 0x0096, 0x904e, 0x080c, 0xaafb, 0x009e, 0x008e, 0x903e, - 0x080c, 0xaba6, 0x2c20, 0x080c, 0xeacf, 0x005e, 0x007e, 0x00be, - 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, - 0x20a9, 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6724, 0x1190, - 0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xee6b, - 0x004e, 0x0096, 0x904e, 0x080c, 0xaafb, 0x009e, 0x008e, 0x903e, - 0x080c, 0xaba6, 0x003e, 0x001e, 0x8108, 0x1f04, 0xebab, 0x0036, - 0x2029, 0x0002, 0x080c, 0xeacf, 0x003e, 0x015e, 0x00ce, 0x007e, - 0x005e, 0x004e, 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xd0d6, - 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, - 0x907d, 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6e9f, 0x2f48, - 0x0cb0, 0xab82, 0x080c, 0x6e9f, 0x00fe, 0x001e, 0x0005, 0xa800, - 0x907d, 0x0130, 0xa803, 0x0000, 0x080c, 0x6e9f, 0x2f48, 0x0cb8, - 0x080c, 0x6e9f, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, - 0x9005, 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, - 0x12f8, 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000, 0x0168, - 0x6008, 0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0, 0x6010, - 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018, 0x2001, - 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001, 0x0008, - 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4, 0x1d68, - 0x0c30, 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, - 0xaae2, 0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, 0xd0c6, - 0x2001, 0x0000, 0x0120, 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, - 0xa87a, 0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, - 0xa87f, 0x0000, 0x2001, 0x198e, 0x2004, 0xa882, 0x9006, 0xa802, - 0xa86a, 0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, - 0x009e, 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, - 0x0140, 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, - 0x0001, 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, - 0xb8a0, 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, - 0x0016, 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, - 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, - 0x0005, 0x2001, 0x1987, 0x2004, 0x601a, 0x080c, 0x94ff, 0x080c, - 0x9ab1, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, - 0x0158, 0xd0cc, 0x0118, 0x080c, 0xd412, 0x0030, 0x080c, 0xee87, - 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x0005, 0x9280, 0x0008, 0x2004, - 0x9084, 0x000f, 0x0002, 0xecc1, 0xecc1, 0xecc1, 0xecc3, 0xecc1, - 0xecc3, 0xecc3, 0xecc1, 0xecc3, 0xecc1, 0xecc1, 0xecc1, 0xecc1, - 0xecc1, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, - 0x2004, 0x9084, 0x000f, 0x0002, 0xecda, 0xecda, 0xecda, 0xecda, - 0xecda, 0xecda, 0xece7, 0xecda, 0xecda, 0xecda, 0xecda, 0xecda, - 0xecda, 0xecda, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, - 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0005, 0x0096, - 0x00c6, 0x2260, 0x080c, 0xee87, 0x6043, 0x0000, 0x6024, 0xc0f4, - 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, - 0x0007, 0x1904, 0xed40, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, - 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, - 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x00c6, 0x2d60, 0x6100, - 0x9186, 0x0002, 0x1904, 0xedb0, 0x6014, 0x9005, 0x1138, 0x6000, - 0x9086, 0x0007, 0x190c, 0x0dc5, 0x0804, 0xedb0, 0x2048, 0x080c, - 0xd0d8, 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, - 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, - 0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, - 0x080c, 0xe59e, 0x0804, 0xedb0, 0x2009, 0x0041, 0x0804, 0xedaa, - 0x9186, 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, - 0x00de, 0x009e, 0x0804, 0xecda, 0xd0b4, 0x0128, 0xd0fc, 0x090c, - 0x0dc5, 0x0804, 0xecfb, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, - 0x94ff, 0x080c, 0x9ab1, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, - 0x0120, 0x9186, 0x0004, 0x1904, 0xedb0, 0x6814, 0x2048, 0xa97c, - 0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, - 0x2c78, 0x080c, 0x1768, 0x00fe, 0x2009, 0x0042, 0x0498, 0x0036, - 0x080c, 0x100e, 0x090c, 0x0dc5, 0xa867, 0x010d, 0x9006, 0xa802, - 0xa86a, 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, - 0x6038, 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, - 0x2058, 0xb8a0, 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, - 0xa87e, 0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, 0x6e9f, - 0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xe746, 0x2d00, 0x600a, - 0x003e, 0x0038, 0x6043, 0x0000, 0x6003, 0x0007, 0x080c, 0xe59e, - 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, - 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, - 0x99a5, 0x0036, 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, - 0xebd4, 0x009e, 0x003e, 0x080c, 0x9ab1, 0x0005, 0x9186, 0x0014, - 0x0d70, 0x080c, 0xb36d, 0x0005, 0xede3, 0xede1, 0xede1, 0xede1, - 0xede1, 0xede1, 0xede3, 0xede1, 0xede1, 0xede1, 0xede1, 0xede1, - 0xede1, 0x080c, 0x0dc5, 0x080c, 0x99a5, 0x6003, 0x000c, 0x080c, - 0x9ab1, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, - 0x001a, 0x080c, 0xb36d, 0x0005, 0xee01, 0xee01, 0xee01, 0xee01, - 0xee03, 0xee23, 0xee01, 0xee01, 0xee01, 0xee01, 0xee01, 0xee01, - 0xee01, 0x080c, 0x0dc5, 0x00d6, 0x2c68, 0x080c, 0xb27d, 0x01b0, - 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, - 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, - 0x6023, 0x0004, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x2d60, 0x080c, - 0xb2d3, 0x00de, 0x0005, 0x080c, 0xb2d3, 0x0005, 0x00e6, 0x6010, - 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, - 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, - 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1988, 0x2004, 0x6042, 0x2009, - 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c, - 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, - 0x1988, 0x200c, 0x2001, 0x1986, 0x2004, 0x9100, 0x9080, 0x000a, - 0x6042, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104, - 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, - 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8bc, - 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138, - 0x600c, 0x2072, 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x0010, 0x9cf0, - 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, - 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, 0x0110, - 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, - 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, 0x2019, - 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, - 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, - 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc379, - 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, - 0x2048, 0x2019, 0x0006, 0x080c, 0xc379, 0x009e, 0x1100, 0x015e, - 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60c1, - 0x080c, 0x3000, 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x100e, - 0x090c, 0x0dc5, 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, - 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, - 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, - 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, - 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, - 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, - 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, - 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, - 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, - 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, - 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, - 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, - 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, - 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, - 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, - 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, - 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, - 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, - 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, - 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, - 0x002e, 0x080c, 0x6e9f, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, - 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, - 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, - 0x2029, 0x19f1, 0x252c, 0x2021, 0x19f7, 0x2424, 0x2061, 0x1cd0, - 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, - 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, - 0x2400, 0x9c06, 0x01d0, 0x080c, 0xec62, 0x01b8, 0x080c, 0xec72, - 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1a8e, - 0x001e, 0x080c, 0xd2cf, 0x1110, 0x080c, 0x3279, 0x080c, 0xd2e0, - 0x1110, 0x080c, 0xbcb6, 0x080c, 0xb306, 0x9ce0, 0x0018, 0x2001, - 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, - 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, - 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, - 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, - 0xd7e3, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, - 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4dfb, 0x004e, - 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, - 0xac6c, 0x080c, 0xb306, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, - 0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, - 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, - 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, - 0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, - 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, - 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0160, - 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, 0x2004, - 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0126, - 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, 0x1840, 0xd5a4, - 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, 0x8000, - 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, - 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, - 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, - 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xffee, 0x0021, 0x00ee, - 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, 0x8e70, - 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, 0x0c99, - 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, 0x0005, - 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, 0x7014, - 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0003, 0x000b, - 0x07d2, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008, 0x0010, 0x0000, - 0x8066, 0x0000, 0x0101, 0x0008, 0x4407, 0x0003, 0x8060, 0x0000, - 0x0400, 0x0000, 0x580d, 0x000b, 0x79c0, 0x0003, 0x5106, 0x0003, - 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000, 0x0c0a, 0x000b, - 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0, 0x0009, 0x7000, 0x0000, - 0xffa0, 0x0001, 0x2000, 0x0000, 0x1680, 0x000b, 0x808c, 0x0008, - 0x0001, 0x0000, 0x0000, 0x0007, 0x4028, 0x0000, 0x4047, 0x000a, - 0x808c, 0x0008, 0x0002, 0x0000, 0x0822, 0x0003, 0x4022, 0x0000, - 0x0028, 0x000b, 0x4122, 0x0008, 0x94c0, 0x0009, 0xff00, 0x0008, - 0xffe0, 0x0009, 0x0500, 0x0008, 0x0aab, 0x0003, 0x4447, 0x0002, - 0x0ea8, 0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x1286, 0x0003, - 0x0ca0, 0x0001, 0x1286, 0x0003, 0x9180, 0x0001, 0x0004, 0x0000, - 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x0009, 0x0008, 0x4436, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, - 0x0060, 0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, - 0x0411, 0x0000, 0x443e, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, - 0x0e83, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, - 0x0e83, 0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, - 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, - 0x444d, 0x000b, 0x0240, 0x0002, 0x0a80, 0x0003, 0x00fe, 0x0000, - 0x3283, 0x000b, 0x0248, 0x000a, 0x085c, 0x0003, 0x9180, 0x0001, - 0x0006, 0x0008, 0x7f62, 0x0008, 0x8002, 0x0008, 0x0003, 0x0008, - 0x8066, 0x0000, 0x020a, 0x0000, 0x445b, 0x0003, 0x112a, 0x0000, - 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002, 0x0c0a, 0x000b, - 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008, 0x8062, 0x0008, - 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008, 0x4468, 0x0003, - 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0e74, 0x0003, 0x00fe, 0x0000, - 0x43e0, 0x0001, 0x0e74, 0x0003, 0x1734, 0x0000, 0x1530, 0x0000, - 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010, 0x0000, - 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x1e0a, 0x0008, 0x447a, 0x0003, 0x808a, 0x0008, 0x0003, 0x0008, - 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x5880, 0x000b, - 0x8066, 0x0000, 0x3679, 0x0000, 0x4483, 0x0003, 0x5884, 0x0003, - 0x3efe, 0x0008, 0x7f4f, 0x0002, 0x088a, 0x000b, 0x0d00, 0x0000, - 0x0092, 0x000c, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, - 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x00e0, 0x000c, - 0x000a, 0x000b, 0x00fe, 0x0000, 0x349a, 0x0003, 0x1a60, 0x0000, - 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, - 0x4499, 0x000b, 0x03fe, 0x0000, 0x04d0, 0x0001, 0x0cd4, 0x000b, - 0x82c0, 0x0001, 0x1f00, 0x0000, 0xffa0, 0x0001, 0x0400, 0x0000, - 0x08b2, 0x0003, 0x14dc, 0x0003, 0x01fe, 0x0008, 0x0580, 0x0009, - 0x7f06, 0x0000, 0x8690, 0x0009, 0x0000, 0x0008, 0x7f0c, 0x0000, - 0x02fe, 0x0008, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x0680, 0x0009, - 0x10b2, 0x0003, 0x7f08, 0x0008, 0x84c0, 0x0001, 0xff00, 0x0008, - 0x08d4, 0x0003, 0xb9c0, 0x0009, 0x0030, 0x0008, 0x0cc3, 0x000b, - 0x8060, 0x0000, 0x0400, 0x0000, 0x80fe, 0x0008, 0x1a0a, 0x0009, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0409, 0x0000, 0x44bc, 0x0003, - 0x80fe, 0x0008, 0x1a09, 0x0009, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x040a, 0x0000, 0x44c2, 0x0003, 0x00fe, 0x0000, 0x34ca, 0x0003, - 0x8072, 0x0000, 0x1010, 0x0008, 0x3944, 0x0002, 0x08c5, 0x0003, - 0x00ce, 0x0003, 0x8072, 0x0000, 0x2020, 0x0008, 0x3945, 0x000a, - 0x08ca, 0x0003, 0x3946, 0x000a, 0x0cdb, 0x000b, 0x0000, 0x0007, - 0x3943, 0x000a, 0x08db, 0x0003, 0x00ce, 0x0003, 0x00fe, 0x0000, - 0x34d9, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000, 0x00db, 0x000b, - 0x8072, 0x0000, 0x2000, 0x0000, 0x4000, 0x000f, 0x86c0, 0x0009, - 0xfc00, 0x0008, 0x08d4, 0x0003, 0x00b2, 0x000b, 0x1c60, 0x0000, - 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, 0x44e4, 0x000b, - 0x58e5, 0x000b, 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, - 0x0cf3, 0x000b, 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, - 0x044a, 0x0008, 0x030a, 0x0008, 0x040c, 0x0000, 0x0d06, 0x0000, - 0x0d08, 0x0008, 0x00f7, 0x0003, 0x0344, 0x0008, 0x0446, 0x0008, - 0x0548, 0x0008, 0x064a, 0x0000, 0x1948, 0x000a, 0x08fa, 0x0003, - 0x0d4a, 0x0008, 0x58fa, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002, - 0x0901, 0x0003, 0x8000, 0x0000, 0x0001, 0x0000, 0x0092, 0x000c, - 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, 0x2020, 0x0008, - 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, 0x0003, 0x2b24, 0x0008, - 0x2b24, 0x0008, 0x590a, 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, - 0x1242, 0x0002, 0x0958, 0x0003, 0x3a45, 0x000a, 0x0947, 0x000b, - 0x8072, 0x0000, 0x1000, 0x0000, 0x3945, 0x000a, 0x0917, 0x000b, - 0x8072, 0x0000, 0x3010, 0x0000, 0x1e10, 0x000a, 0x7f3c, 0x0000, - 0x0942, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x4520, 0x000b, - 0x00fe, 0x0000, 0x353f, 0x000b, 0x1c60, 0x0000, 0x8062, 0x0008, - 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x4528, 0x0003, - 0x00fe, 0x0000, 0x325b, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, - 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, - 0x4531, 0x000b, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, - 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, - 0x8066, 0x0000, 0x0009, 0x0008, 0x453b, 0x000b, 0x003a, 0x0008, - 0x1dfe, 0x0000, 0x011c, 0x000b, 0x0036, 0x0008, 0x00e0, 0x000c, - 0x0158, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x8072, 0x0000, - 0x2000, 0x0000, 0x0158, 0x000b, 0x3a44, 0x0002, 0x0a89, 0x0003, - 0x8074, 0x0000, 0x1000, 0x0000, 0x8072, 0x0000, 0x1000, 0x0000, - 0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3658, 0x0003, 0x26fe, 0x0008, - 0x26fe, 0x0008, 0x2700, 0x0008, 0x2700, 0x0008, 0x00d0, 0x0009, - 0x0d6a, 0x0003, 0x8074, 0x0000, 0x4040, 0x0008, 0x5958, 0x0003, - 0x5106, 0x0003, 0x3a46, 0x000a, 0x0d6a, 0x0003, 0x3a47, 0x0002, - 0x0965, 0x000b, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, - 0x8000, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x01b4, 0x0003, - 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, - 0x0e52, 0x000b, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, - 0x8066, 0x0000, 0x362a, 0x0000, 0x456f, 0x0003, 0x2000, 0x0000, - 0x2000, 0x0000, 0x2102, 0x0000, 0x2102, 0x0000, 0x2204, 0x0000, - 0x2204, 0x0000, 0x2306, 0x0000, 0x2306, 0x0000, 0x2408, 0x0000, - 0x2408, 0x0000, 0x250a, 0x0000, 0x250a, 0x0000, 0x260c, 0x0000, - 0x260c, 0x0000, 0x270e, 0x0000, 0x270e, 0x0000, 0x2810, 0x0000, - 0x2810, 0x0000, 0x2912, 0x0000, 0x2912, 0x0000, 0x1a60, 0x0000, - 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000, 0x0052, 0x0000, - 0x4589, 0x000b, 0x92c0, 0x0009, 0x0780, 0x0008, 0x0e6e, 0x000b, - 0x124b, 0x0002, 0x0992, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, - 0x0a58, 0x0003, 0x3a46, 0x000a, 0x0da2, 0x000b, 0x5994, 0x0003, - 0x8054, 0x0008, 0x0004, 0x0000, 0x1243, 0x000a, 0x09b0, 0x0003, - 0x8010, 0x0008, 0x000d, 0x0000, 0x0233, 0x000c, 0x1948, 0x000a, - 0x099f, 0x000b, 0x0228, 0x000c, 0x1810, 0x0000, 0x0233, 0x000c, - 0x01b0, 0x000b, 0x1948, 0x000a, 0x09a6, 0x000b, 0x1243, 0x000a, - 0x0a5b, 0x0003, 0x194d, 0x000a, 0x09aa, 0x000b, 0x1243, 0x000a, - 0x0a62, 0x0003, 0x59aa, 0x000b, 0x8054, 0x0008, 0x0004, 0x0000, - 0x0228, 0x000c, 0x1810, 0x0000, 0x0233, 0x000c, 0x8074, 0x0000, - 0xf000, 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, - 0x3a42, 0x0002, 0x0dba, 0x000b, 0x15fe, 0x0008, 0x3461, 0x000b, - 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010, 0x0008, - 0x000c, 0x0008, 0x0233, 0x000c, 0x000a, 0x000b, 0xbbe0, 0x0009, - 0x0030, 0x0008, 0x0dd0, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, - 0x09cd, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x09cd, 0x0003, - 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x0220, 0x000b, - 0x8076, 0x0008, 0x0041, 0x0008, 0x0220, 0x000b, 0xbbe0, 0x0009, - 0x0032, 0x0000, 0x0dd5, 0x000b, 0x3c1e, 0x0008, 0x0220, 0x000b, - 0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dda, 0x000b, 0x3c20, 0x0000, - 0x0220, 0x000b, 0xbbe0, 0x0009, 0x0035, 0x0008, 0x0de0, 0x000b, - 0x8072, 0x0000, 0x8000, 0x0000, 0x039e, 0x0003, 0xbbe0, 0x0009, - 0x0036, 0x0008, 0x0abd, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, - 0x0e01, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0dcd, 0x000b, - 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, - 0x000d, 0x0000, 0x2604, 0x0008, 0x2604, 0x0008, 0x2706, 0x0008, - 0x2706, 0x0008, 0x2808, 0x0000, 0x2808, 0x0000, 0x290a, 0x0000, - 0x290a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x45f8, 0x000b, - 0x0228, 0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, - 0xf000, 0x0008, 0x8072, 0x0000, 0xb000, 0x0000, 0x01b4, 0x0003, - 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0e13, 0x000b, 0x18fe, 0x0000, - 0x3ce0, 0x0009, 0x0a10, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, - 0x0dc9, 0x0003, 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, - 0x8072, 0x0000, 0x8000, 0x0000, 0x0280, 0x000b, 0x8076, 0x0008, - 0x0042, 0x0008, 0x0220, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, - 0x0e20, 0x000b, 0x8074, 0x0000, 0x0808, 0x0008, 0x3a44, 0x0002, - 0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800, 0x0000, 0x8072, 0x0000, - 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, - 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, - 0xbc80, 0x0001, 0x0007, 0x0000, 0x022c, 0x000b, 0x1930, 0x000a, - 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, - 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, - 0x4631, 0x000b, 0x4000, 0x000f, 0x2236, 0x000b, 0x0870, 0x0008, - 0x4000, 0x000f, 0x7e33, 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, - 0x0e33, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0a44, 0x000b, - 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a44, 0x000b, 0x0223, 0x0004, - 0x8076, 0x0008, 0x0040, 0x0000, 0x0246, 0x000b, 0x8076, 0x0008, - 0x0041, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0233, 0x0003, - 0xbac0, 0x0009, 0x0090, 0x0008, 0x0a4f, 0x0003, 0x8074, 0x0000, - 0x0706, 0x0000, 0x0251, 0x000b, 0x8074, 0x0000, 0x0703, 0x0000, - 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x028e, 0x0003, - 0x8010, 0x0008, 0x0008, 0x0000, 0x028e, 0x0003, 0x8010, 0x0008, - 0x0022, 0x0008, 0x028e, 0x0003, 0x0228, 0x000c, 0x8010, 0x0008, - 0x0007, 0x0000, 0x0233, 0x000c, 0x1810, 0x0000, 0x0233, 0x000c, - 0x029a, 0x0003, 0x0228, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, - 0x0233, 0x000c, 0x1810, 0x0000, 0x0233, 0x000c, 0x8074, 0x0000, - 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, - 0x000a, 0x000b, 0x8010, 0x0008, 0x0009, 0x0008, 0x028e, 0x0003, - 0x8010, 0x0008, 0x0005, 0x0008, 0x028e, 0x0003, 0x1648, 0x000a, - 0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008, - 0x0004, 0x0000, 0x4143, 0x000a, 0x086f, 0x0003, 0x3a44, 0x0002, - 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x028e, 0x0003, 0x8010, 0x0008, - 0x0003, 0x0008, 0x0292, 0x000b, 0x8010, 0x0008, 0x000b, 0x0000, - 0x0292, 0x000b, 0x8010, 0x0008, 0x0002, 0x0000, 0x0292, 0x000b, - 0x3a47, 0x0002, 0x0d58, 0x000b, 0x8010, 0x0008, 0x0006, 0x0008, - 0x0292, 0x000b, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, - 0x3000, 0x0008, 0x0233, 0x000c, 0x0249, 0x0004, 0x3a40, 0x000a, - 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, 0x0008, 0x0233, 0x000c, - 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, - 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002, - 0x0aa5, 0x000b, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, - 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002, - 0x0c0a, 0x000b, 0x0283, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, - 0x4447, 0x0002, 0x0ad1, 0x000b, 0xc0c0, 0x0001, 0x00ff, 0x0008, - 0xffe0, 0x0009, 0x00ff, 0x0008, 0x0ea8, 0x000b, 0xc1e0, 0x0001, - 0xffff, 0x0008, 0x0ea8, 0x000b, 0x8010, 0x0008, 0x0013, 0x0000, - 0x0233, 0x000c, 0x8074, 0x0000, 0x0202, 0x0008, 0x000a, 0x000b, - 0x3a40, 0x000a, 0x0ece, 0x000b, 0x8074, 0x0000, 0x0200, 0x0000, - 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, - 0x43e0, 0x0001, 0x0ecc, 0x0003, 0x42fe, 0x0000, 0xffc0, 0x0001, - 0x00ff, 0x0008, 0x00e0, 0x0009, 0x0aa8, 0x0003, 0x0d08, 0x0008, - 0x0321, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b, - 0x03a7, 0x000c, 0x808c, 0x0008, 0x0001, 0x0000, 0x04fe, 0x0008, - 0x338a, 0x0003, 0x0460, 0x0000, 0x8062, 0x0008, 0x0001, 0x0000, - 0x8066, 0x0000, 0x0009, 0x0008, 0x46db, 0x0003, 0x0004, 0x0000, - 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000, 0x80e0, 0x0001, - 0x0004, 0x0000, 0x0af5, 0x000b, 0x80e0, 0x0001, 0x0005, 0x0008, - 0x0af5, 0x000b, 0x80e0, 0x0001, 0x0006, 0x0008, 0x0af5, 0x000b, - 0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x82e0, 0x0009, - 0x0600, 0x0008, 0x0af5, 0x000b, 0x82e0, 0x0009, 0x0500, 0x0008, - 0x0af5, 0x000b, 0x82e0, 0x0009, 0x0400, 0x0000, 0x0f8a, 0x0003, - 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0, 0x0009, 0x1000, 0x0000, - 0x0b21, 0x0003, 0x0398, 0x000c, 0x3941, 0x0002, 0x0b00, 0x0003, - 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x0460, 0x0000, - 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x2209, 0x0008, 0x4706, 0x000b, 0x11fe, 0x0000, 0x331c, 0x0003, - 0x9180, 0x0001, 0x0002, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x4710, 0x0003, - 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x03e0, 0x0009, - 0x0f19, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x0046, 0x0003, - 0x9180, 0x0001, 0x0003, 0x0008, 0x0303, 0x000b, 0x8072, 0x0000, - 0x0400, 0x0000, 0x8010, 0x0008, 0x0010, 0x0000, 0x037b, 0x000b, - 0x0398, 0x000c, 0x3941, 0x0002, 0x0b27, 0x0003, 0x8072, 0x0000, - 0x0400, 0x0000, 0x000a, 0x000b, 0x1042, 0x000a, 0x0b2c, 0x000b, - 0x0360, 0x0004, 0x11fe, 0x0000, 0x3731, 0x000b, 0x8072, 0x0000, - 0x0400, 0x0000, 0x8010, 0x0008, 0x000e, 0x0000, 0x037b, 0x000b, - 0x8060, 0x0000, 0x0400, 0x0000, 0x04fe, 0x0008, 0x3746, 0x000b, - 0x808c, 0x0008, 0x0000, 0x0008, 0x9180, 0x0001, 0x0005, 0x0008, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x473c, 0x000b, - 0x0060, 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, - 0x4206, 0x0008, 0x8066, 0x0000, 0x0412, 0x0000, 0x4744, 0x000b, - 0x035d, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000, 0x0460, 0x0000, - 0x8062, 0x0008, 0x002b, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, - 0x474d, 0x000b, 0x8066, 0x0000, 0x220a, 0x0008, 0x4750, 0x000b, - 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, - 0x8060, 0x0000, 0x0400, 0x0000, 0x9180, 0x0001, 0x0002, 0x0000, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x041a, 0x0008, 0x475c, 0x000b, - 0x8072, 0x0000, 0x0400, 0x0000, 0x0046, 0x0003, 0x8060, 0x0000, - 0x0400, 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x0411, 0x0000, - 0x4765, 0x000b, 0x02fe, 0x0008, 0x03e0, 0x0009, 0x0f6b, 0x0003, - 0x0d22, 0x0000, 0x4000, 0x000f, 0x8280, 0x0009, 0x0002, 0x0000, - 0x1380, 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, - 0x4771, 0x000b, 0x0200, 0x000a, 0xffc0, 0x0001, 0x0007, 0x0000, - 0x7f06, 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x060a, 0x0008, - 0x4779, 0x0003, 0x4000, 0x000f, 0x3a44, 0x0002, 0x0c0a, 0x000b, - 0x2f44, 0x000a, 0x2f44, 0x000a, 0x0e83, 0x000b, 0x808a, 0x0008, - 0x0003, 0x0008, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, - 0x3000, 0x0008, 0x5b86, 0x000b, 0x8054, 0x0008, 0x0019, 0x0000, - 0x000a, 0x000b, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, - 0x0000, 0x0008, 0x8010, 0x0008, 0x0011, 0x0008, 0x0233, 0x000c, - 0x42fe, 0x0000, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x7f10, 0x0008, - 0x0233, 0x000c, 0x4310, 0x0008, 0x0292, 0x000b, 0x3941, 0x0002, - 0x0b9b, 0x000b, 0x4000, 0x000f, 0x8072, 0x0000, 0x0404, 0x0008, - 0x4000, 0x000f, 0x8010, 0x0008, 0x0012, 0x0008, 0x0233, 0x000c, - 0x0360, 0x0004, 0x1110, 0x0000, 0x0233, 0x000c, 0x11fe, 0x0000, - 0x37a1, 0x000b, 0x000a, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, - 0x7f00, 0x0000, 0xc3c0, 0x0001, 0xff00, 0x0008, 0x00d0, 0x0009, - 0x0bcc, 0x0003, 0x0d0a, 0x0000, 0x8580, 0x0001, 0x1000, 0x0000, - 0x7f62, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, - 0x0809, 0x0000, 0x47b6, 0x0003, 0x04fe, 0x0008, 0x33c5, 0x000b, - 0x0460, 0x0000, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, - 0x0211, 0x0000, 0x47be, 0x000b, 0x01fe, 0x0008, 0x00e0, 0x0009, - 0x0fc5, 0x000b, 0x02fe, 0x0008, 0x43e0, 0x0001, 0x0bcb, 0x000b, - 0x0500, 0x0002, 0x7f0a, 0x0000, 0xffe0, 0x0009, 0x0800, 0x0000, - 0x0faf, 0x000b, 0x0d08, 0x0008, 0x4000, 0x000f, 0x43fe, 0x0008, - 0x3e80, 0x0001, 0xffc0, 0x0001, 0x7fff, 0x0000, 0x0d60, 0x0000, - 0x7f62, 0x0008, 0x8066, 0x0000, 0x0809, 0x0000, 0x47d4, 0x000b, - 0x8060, 0x0000, 0x0400, 0x0000, 0x84c0, 0x0001, 0xff00, 0x0008, - 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, - 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, - 0xff80, 0x0009, 0x1000, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, - 0x0809, 0x0000, 0x47e6, 0x0003, 0x4000, 0x000f, 0x8d5b, 0xeac4, - 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, - 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, - 0x12b0 + 0x0448, 0x080c, 0xe82d, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, + 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0920, 0x0804, 0xd715, 0x001e, 0x6017, + 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x336a, 0x1904, 0xda78, + 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715, + 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, + 0x98ed, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xeba1, 0x1904, + 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x080c, 0xdc49, 0x1904, + 0xd715, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, + 0x98ed, 0x0005, 0x080c, 0x336a, 0x1904, 0xda78, 0x6007, 0x0023, + 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c, + 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x080c, + 0xdc49, 0x1904, 0xd715, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, + 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, + 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, + 0x080c, 0xce44, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, + 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, + 0x080c, 0xb101, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, + 0x080c, 0xce44, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, + 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, + 0x2c08, 0x9006, 0x080c, 0xe96f, 0x1180, 0x7244, 0x9286, 0xffff, + 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, + 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, + 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0xb101, 0x2160, + 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x664f, + 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, + 0x2011, 0x0276, 0x080c, 0xc0e3, 0x003e, 0x002e, 0x001e, 0x015e, + 0x0120, 0x6007, 0x0031, 0x0804, 0xd842, 0x080c, 0xbd50, 0x080c, + 0x7569, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x7583, 0x1138, + 0x080c, 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x0010, 0x080c, + 0x7541, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x336a, 0x1904, + 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715, 0x6106, 0x080c, 0xdc65, + 0x1120, 0x6007, 0x002b, 0x0804, 0xd842, 0x6007, 0x002c, 0x0804, + 0xd842, 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904, + 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715, 0x6106, 0x080c, 0xdc6a, + 0x1120, 0x6007, 0x002e, 0x0804, 0xd842, 0x6007, 0x002f, 0x0804, + 0xd842, 0x080c, 0x336a, 0x1904, 0xda78, 0x00e6, 0x00d6, 0x00c6, + 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, + 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, + 0x00ee, 0x0804, 0xd849, 0x080c, 0x57d7, 0xd0e4, 0x0904, 0xd9c3, + 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, + 0x080c, 0x6a8e, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, + 0xb814, 0x9206, 0x0510, 0x080c, 0x6a8a, 0x15b8, 0x2069, 0x1800, + 0x6880, 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, 0x7210, 0x080c, + 0xce44, 0x0590, 0x080c, 0xdb36, 0x0578, 0x080c, 0xea21, 0x0560, + 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, + 0x98ed, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, + 0x0150, 0x080c, 0xce44, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, + 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, + 0xe96f, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, + 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, + 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x336a, + 0x1904, 0xda78, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, + 0x9086, 0x0006, 0x1904, 0xd849, 0x00e6, 0x00d6, 0x00c6, 0x080c, + 0x57d7, 0xd0e4, 0x0904, 0xda3b, 0x2069, 0x1800, 0x2071, 0x026c, + 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, + 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe96f, 0x2c10, 0x00ce, + 0x05e8, 0x080c, 0xce44, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, + 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xca64, 0x002e, + 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, + 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, + 0x2004, 0x9005, 0x0170, 0x080c, 0xdb36, 0x0904, 0xd9bc, 0x0056, + 0x7510, 0x7614, 0x080c, 0xea3a, 0x005e, 0x00ce, 0x00de, 0x00ee, + 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, + 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0c78, 0x6007, 0x003b, + 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, + 0x0000, 0x0804, 0xd993, 0x00e6, 0x0026, 0x080c, 0x6a50, 0x0550, + 0x080c, 0x69ec, 0x080c, 0xec12, 0x1518, 0x2071, 0x1800, 0x70dc, + 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284, + 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, 0x9205, 0x7082, + 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a8e, 0x0120, 0x2011, + 0x1a02, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x3019, 0x0010, + 0x080c, 0xec46, 0x002e, 0x00ee, 0x080c, 0xb101, 0x0804, 0xd848, + 0x080c, 0xb101, 0x0005, 0x2600, 0x0002, 0xda8f, 0xdabd, 0xdace, + 0xda8f, 0xda8f, 0xda91, 0xdadf, 0xda8f, 0xda8f, 0xda8f, 0xdaab, + 0xda8f, 0xda8f, 0xda8f, 0xdaea, 0xdb00, 0xdb31, 0xda8f, 0x080c, + 0x0dc5, 0x080c, 0xeba1, 0x1d20, 0x080c, 0x336a, 0x1d08, 0x7038, + 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x9383, 0x0005, + 0x080c, 0x3246, 0x080c, 0xd576, 0x6007, 0x0001, 0x6003, 0x0001, + 0x080c, 0x9383, 0x0005, 0x080c, 0xeba1, 0x1950, 0x080c, 0x336a, + 0x1938, 0x080c, 0xdc49, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, + 0x6003, 0x0001, 0x080c, 0x9383, 0x0005, 0x080c, 0x336a, 0x1904, + 0xda78, 0x2009, 0x0041, 0x080c, 0xec4f, 0x6007, 0x0047, 0x6003, + 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c, 0x336a, + 0x1904, 0xda78, 0x2009, 0x0042, 0x080c, 0xec4f, 0x6007, 0x0047, + 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c, + 0x336a, 0x1904, 0xda78, 0x2009, 0x0046, 0x080c, 0xec4f, 0x080c, + 0xb101, 0x0005, 0x2001, 0x1824, 0x2004, 0x9082, 0x00e1, 0x1268, + 0x080c, 0xdb53, 0x0904, 0xda78, 0x6007, 0x004e, 0x6003, 0x0001, + 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x6007, 0x0012, 0x0cb0, + 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, + 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x19bf, 0x2004, + 0x9106, 0x11b0, 0x7144, 0x2001, 0x19c0, 0x2004, 0x9106, 0x0190, + 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, + 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x0110, + 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, + 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, + 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8cc, + 0xd084, 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c, 0x6048, + 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, + 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, + 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1, 0x0000, + 0x2001, 0x19a2, 0x2003, 0x0000, 0x080c, 0x1027, 0x05a0, 0x2900, + 0x6016, 0x7090, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0, 0xa833, + 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, + 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, 0x0471, 0x001e, 0x81ff, + 0x01b8, 0x2940, 0x080c, 0x1027, 0x01b0, 0x2900, 0xa006, 0x2100, + 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, + 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000, + 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x7093, 0x0000, 0x6014, + 0x2048, 0x080c, 0x0fc0, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, + 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, 0x240b, 0x2099, 0x026c, + 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, + 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x240b, 0x2099, + 0x0260, 0x0ca8, 0x080c, 0x240b, 0x2061, 0x19a2, 0x6004, 0x2098, + 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0048, + 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x240b, 0x2099, 0x0260, + 0x0ca8, 0x2061, 0x19a2, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, + 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, + 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, + 0x11b8, 0x080c, 0x2423, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, + 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, + 0x01f8, 0x22a8, 0x8108, 0x080c, 0x2423, 0x20a1, 0x0240, 0x0c98, + 0x080c, 0x2423, 0x2061, 0x19a5, 0x6004, 0x20a0, 0x6008, 0x3518, + 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, + 0x0138, 0x22a8, 0x8108, 0x080c, 0x2423, 0x20a1, 0x0240, 0x0c98, + 0x2061, 0x19a5, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, + 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, + 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, + 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, 0xdce1, + 0x00de, 0x0005, 0x00d6, 0x080c, 0xdcee, 0x1520, 0x680c, 0x908c, + 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, + 0xd1e4, 0x0130, 0x9006, 0x080c, 0xed6f, 0x2009, 0x0001, 0x0078, + 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x2894, + 0x1148, 0x2001, 0x0001, 0x080c, 0xed6f, 0x2110, 0x900e, 0x080c, + 0x328f, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, + 0x00b6, 0x00c6, 0x080c, 0xb153, 0x05a8, 0x0016, 0x0026, 0x00c6, + 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x1578, + 0x080c, 0x66b2, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, + 0x2b00, 0x6012, 0x080c, 0xeba1, 0x11d8, 0x080c, 0x336a, 0x11c0, + 0x080c, 0xdc49, 0x0510, 0x2001, 0x0007, 0x080c, 0x6663, 0x2001, + 0x0007, 0x080c, 0x668f, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0010, + 0x080c, 0xb101, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, + 0xb101, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xb101, 0x9006, + 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, 0x6017, + 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, 0x0000, + 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, 0x1190, + 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, 0x810f, + 0x6800, 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, 0x0110, + 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, + 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xde50, + 0x040a, 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118, 0x9186, + 0x0016, 0x1148, 0x080c, 0xd587, 0x0128, 0x6000, 0x9086, 0x0002, + 0x0904, 0xbb29, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0dc5, 0x2001, + 0x0007, 0x080c, 0x668f, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, + 0x98ed, 0x0005, 0xdd7a, 0xdd7c, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7c, + 0xdd8b, 0xde49, 0xddcf, 0xde49, 0xddf7, 0xde49, 0xdd8b, 0xde49, + 0xde41, 0xde49, 0xde41, 0xde49, 0xde49, 0xdd7a, 0xdd7a, 0xdd7a, + 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, + 0xdd7c, 0xdd7a, 0xde49, 0xdd7a, 0xdd7a, 0xde49, 0xdd7a, 0xde46, + 0xde49, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xde49, 0xde49, 0xdd7a, + 0xde49, 0xde49, 0xdd7a, 0xdd86, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, + 0xde45, 0xde49, 0xdd7a, 0xdd7a, 0xde49, 0xde49, 0xdd7a, 0xdd7a, + 0xdd7a, 0xdd7a, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x080c, 0xd579, + 0x6003, 0x0002, 0x080c, 0x98ed, 0x0804, 0xde4f, 0x9006, 0x080c, + 0x664f, 0x0804, 0xde49, 0x080c, 0x6a8a, 0x1904, 0xde49, 0x9006, + 0x080c, 0x664f, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, + 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x00b8, + 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0904, 0xde49, 0x080c, 0x339b, + 0x1904, 0xde49, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, + 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, + 0x0002, 0x080c, 0x6663, 0x080c, 0x97e1, 0x6023, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x6110, + 0x2158, 0x2009, 0x0001, 0x080c, 0x8717, 0x0804, 0xde4f, 0x6610, + 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0148, + 0x9686, 0x0004, 0x0130, 0x080c, 0x8efa, 0x2001, 0x0004, 0x080c, + 0x668f, 0x080c, 0xedbe, 0x0904, 0xde49, 0x080c, 0x97e1, 0x2001, + 0x0004, 0x080c, 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0003, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0804, 0xde4f, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, + 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4da0, 0x004e, 0x003e, + 0x2001, 0x0006, 0x080c, 0xde6d, 0x6610, 0x2658, 0xbe04, 0x0066, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001, + 0x0006, 0x080c, 0x668f, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118, + 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x6663, 0x080c, + 0x6a8a, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01d0, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, + 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xddb7, 0x2001, 0x0004, + 0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, 0x0010, 0x080c, + 0x668f, 0x080c, 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, + 0x2600, 0x0002, 0xde64, 0xde64, 0xde64, 0xde64, 0xde64, 0xde66, + 0xde64, 0xde66, 0xde64, 0xde64, 0xde66, 0xde64, 0xde64, 0xde64, + 0xde66, 0xde66, 0xde66, 0xde66, 0x080c, 0x0dc5, 0x080c, 0x97e1, + 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x0016, 0x00b6, 0x00d6, + 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x6663, 0x9006, + 0x080c, 0x664f, 0x080c, 0x326f, 0x00de, 0x00be, 0x001e, 0x0005, + 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, + 0x1a0c, 0x0dc5, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, + 0x0016, 0x190c, 0x0dc5, 0x006b, 0x0005, 0xbbcb, 0xbbcb, 0xbbcb, + 0xbbcb, 0xdf02, 0xbbcb, 0xdeec, 0xdead, 0xbbcb, 0xbbcb, 0xbbcb, + 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0xdf02, 0xbbcb, 0xdeec, + 0xdef3, 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0x00f6, 0x080c, 0x6a8a, + 0x11d8, 0x080c, 0xd561, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8c0, + 0x9005, 0x0190, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c, + 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9383, 0x080c, 0x98ed, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, + 0x220c, 0x080c, 0x2894, 0x11b0, 0x080c, 0x671d, 0x0118, 0x080c, + 0xb101, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb8c0, 0x0006, + 0x080c, 0x6141, 0x000e, 0xb8c2, 0x000e, 0xb816, 0x000e, 0xb812, + 0x080c, 0xb101, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, + 0x080c, 0xb101, 0x0005, 0x080c, 0xbf5a, 0x1148, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0010, 0x080c, + 0xb101, 0x0005, 0x0804, 0xb101, 0x6004, 0x908a, 0x0053, 0x1a0c, + 0x0dc5, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005, + 0x9182, 0x0040, 0x0002, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf29, + 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, + 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0x080c, + 0x0dc5, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, + 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, + 0x7444, 0x94a4, 0xff00, 0x0904, 0xdf8f, 0x080c, 0xed63, 0x1170, + 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, + 0x891c, 0x0020, 0x9026, 0x080c, 0xebe6, 0x0c38, 0x080c, 0x100e, + 0x090c, 0x0dc5, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, + 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, + 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, + 0x0000, 0xa887, 0x0036, 0x080c, 0x6dd1, 0x001e, 0x080c, 0xed63, + 0x1904, 0xdfef, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, + 0xe915, 0x0804, 0xdfef, 0x9486, 0x0200, 0x1120, 0x080c, 0xe8ac, + 0x0804, 0xdfef, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, + 0xdfef, 0x2019, 0x0002, 0x080c, 0xe8c7, 0x0804, 0xdfef, 0x2069, + 0x1a75, 0x6a00, 0xd284, 0x0904, 0xe059, 0x9284, 0x0300, 0x1904, + 0xe052, 0x6804, 0x9005, 0x0904, 0xe03a, 0x2d78, 0x6003, 0x0007, + 0x080c, 0x1027, 0x0904, 0xdffb, 0x7800, 0xd08c, 0x1118, 0x7804, + 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, + 0x1904, 0xe05d, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, + 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, + 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, + 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xdff7, + 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, + 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, + 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, + 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6dd1, 0x002e, + 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, + 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, + 0x080c, 0x100e, 0x1904, 0xdfa4, 0x6017, 0xf100, 0x6003, 0x0001, + 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0c00, 0x2069, + 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, + 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, + 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x933b, 0x080c, + 0x98ed, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, + 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x0804, 0xdfef, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, + 0x8049, 0x080c, 0x4be9, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, + 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x0804, 0xdfef, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, + 0xe00f, 0x6017, 0xf200, 0x0804, 0xe00f, 0xa867, 0x0146, 0xa86b, + 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, + 0x9080, 0xdff7, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, + 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, + 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, + 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, + 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0dc5, 0x8210, 0x821c, 0x2001, + 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, + 0x2011, 0xe0d9, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, + 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, + 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, + 0x080c, 0x1027, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, + 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, + 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x1040, 0x0cc8, + 0x080c, 0x1040, 0x0804, 0xdffb, 0x2548, 0x8847, 0x9885, 0x0046, + 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xe948, 0x0804, + 0xdfef, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, + 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0054, + 0x1a0c, 0x0dc5, 0x9082, 0x0040, 0x0a0c, 0x0dc5, 0x2008, 0x0804, + 0xe168, 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, 0xd587, 0x0500, + 0x6000, 0x9086, 0x0002, 0x11e0, 0x0804, 0xe1b1, 0x9186, 0x0027, + 0x0190, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0160, 0x190c, + 0x0dc5, 0x080c, 0xd587, 0x0160, 0x6000, 0x9086, 0x0004, 0x190c, + 0x0dc5, 0x0804, 0xe294, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, + 0x080c, 0xb19b, 0x0005, 0xe12f, 0xe131, 0xe131, 0xe158, 0xe12f, + 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, + 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0x080c, + 0x0dc5, 0x080c, 0x97e1, 0x080c, 0x98ed, 0x0036, 0x0096, 0x6014, + 0x904d, 0x01d8, 0x080c, 0xce56, 0x01c0, 0x6003, 0x0002, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, + 0x080c, 0xe948, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, + 0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, + 0x0096, 0x080c, 0x97e1, 0x080c, 0x98ed, 0x080c, 0xce56, 0x0120, + 0x6014, 0x2048, 0x080c, 0x1040, 0x080c, 0xb134, 0x009e, 0x0005, + 0x0002, 0xe17d, 0xe194, 0xe17f, 0xe1ab, 0xe17d, 0xe17d, 0xe17d, + 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, + 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0x080c, 0x0dc5, 0x0096, + 0x080c, 0x97e1, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, + 0x0007, 0x2009, 0x0043, 0x080c, 0xb180, 0x0010, 0x6003, 0x0004, + 0x080c, 0x98ed, 0x009e, 0x0005, 0x080c, 0x97e1, 0x080c, 0xce56, + 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, + 0x080c, 0x88f1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, + 0xebaa, 0x0db0, 0x0cc8, 0x080c, 0x97e1, 0x2009, 0x0041, 0x0804, + 0xe31c, 0x9182, 0x0040, 0x0002, 0xe1c8, 0xe1ca, 0xe1c8, 0xe1c8, + 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, + 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1cb, 0xe1c8, 0xe1c8, + 0x080c, 0x0dc5, 0x0005, 0x00d6, 0x080c, 0x88f1, 0x00de, 0x080c, + 0xec02, 0x080c, 0xb101, 0x0005, 0x9182, 0x0040, 0x0002, 0xe1eb, + 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, + 0xe1ed, 0xe25c, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe25c, 0xe1eb, + 0xe1eb, 0xe1eb, 0xe1eb, 0x080c, 0x0dc5, 0x2001, 0x0105, 0x2004, + 0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, + 0x2004, 0x9105, 0x1904, 0xe25c, 0x2009, 0x180c, 0x2104, 0xd0d4, + 0x0904, 0xe25c, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, + 0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867, 0x2004, 0xd0e4, + 0x1528, 0x603b, 0x0000, 0x080c, 0x989d, 0x6014, 0x0096, 0x2048, + 0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, + 0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x9a0f, 0x2009, + 0x0041, 0x009e, 0x0804, 0xe31c, 0x080c, 0x9a0f, 0x6003, 0x0007, + 0x601b, 0x0000, 0x080c, 0x88f1, 0x009e, 0x0005, 0x2001, 0x0100, + 0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, + 0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, + 0x080c, 0x2c94, 0x080c, 0x9a0f, 0x6014, 0x2048, 0xa97c, 0xd1ec, + 0x1130, 0x080c, 0x88f1, 0x080c, 0xb101, 0x009e, 0x0005, 0x080c, + 0xebaa, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, + 0x2102, 0x0036, 0x080c, 0x989d, 0x080c, 0x9a0f, 0x6014, 0x0096, + 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, + 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, + 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, + 0x0080, 0x2019, 0x0004, 0x080c, 0xe948, 0x6018, 0x9005, 0x1128, + 0x2001, 0x1988, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, + 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xe2ab, + 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ad, + 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, + 0xe2ab, 0xe2ab, 0xe2f8, 0x080c, 0x0dc5, 0x6014, 0x0096, 0x2048, + 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, + 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, + 0x009e, 0x0804, 0xe31c, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, + 0x88f1, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, + 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, + 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, + 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, + 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, + 0x080c, 0x88f3, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, + 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1608, 0x1904, 0xe2ad, 0x0005, + 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, + 0x080c, 0x1608, 0x1904, 0xe2ad, 0x0005, 0xd2fc, 0x0140, 0x8002, + 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, + 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, + 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dc5, 0x6024, + 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0xe340, 0xe34c, 0xe358, 0xe364, + 0xe340, 0xe340, 0xe340, 0xe340, 0xe347, 0xe342, 0xe342, 0xe340, + 0xe340, 0xe340, 0xe340, 0xe342, 0xe340, 0xe342, 0xe340, 0xe347, + 0x080c, 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0x6014, + 0x9005, 0x190c, 0x0dc5, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, + 0x933b, 0x0126, 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005, + 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x0126, 0x2091, 0x8000, + 0x080c, 0x98ed, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, + 0x080c, 0x1c09, 0x0126, 0x2091, 0x8000, 0x080c, 0x93a0, 0x080c, + 0x9a0f, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, + 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe393, + 0xe395, 0xe3a7, 0xe3c1, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, + 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, + 0xe393, 0xe393, 0xe393, 0x080c, 0x0dc5, 0x6014, 0x2048, 0xa87c, + 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, + 0x0001, 0x6106, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0470, 0x6014, + 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, + 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x080c, 0x98ed, + 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe948, + 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, + 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, + 0x1c09, 0x080c, 0x93a0, 0x080c, 0x9a0f, 0x0005, 0x080c, 0x97e1, + 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xed00, 0x0036, + 0x2019, 0x0029, 0x080c, 0xe948, 0x003e, 0x009e, 0x080c, 0xb134, + 0x080c, 0x98ed, 0x0005, 0x080c, 0x989d, 0x6114, 0x81ff, 0x0158, + 0x0096, 0x2148, 0x080c, 0xed00, 0x0036, 0x2019, 0x0029, 0x080c, + 0xe948, 0x003e, 0x009e, 0x080c, 0xb134, 0x080c, 0x9a0f, 0x0005, + 0x9182, 0x0085, 0x0002, 0xe412, 0xe410, 0xe410, 0xe41e, 0xe410, + 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, + 0x080c, 0x0dc5, 0x6003, 0x000b, 0x6106, 0x080c, 0x933b, 0x0126, + 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005, 0x0026, 0x00e6, + 0x080c, 0xeba1, 0x0118, 0x080c, 0xb101, 0x0450, 0x2071, 0x0260, + 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, + 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, + 0xb423, 0x7220, 0x080c, 0xe79d, 0x0118, 0x6007, 0x0086, 0x0040, + 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, + 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x080c, 0x9a0f, + 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, + 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x9082, + 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, + 0x080c, 0xb19b, 0x0050, 0x2001, 0x0007, 0x080c, 0x668f, 0x080c, + 0x97e1, 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005, 0xe483, 0xe485, + 0xe485, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483, + 0xe483, 0xe483, 0xe483, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x080c, + 0xb134, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0dc5, + 0x9182, 0x0092, 0x1a0c, 0x0dc5, 0x9182, 0x0085, 0x0002, 0xe4a4, + 0xe4a4, 0xe4a4, 0xe4a6, 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4, + 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4, 0x080c, 0x0dc5, 0x0005, 0x9186, + 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, + 0x080c, 0xb19b, 0x0030, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, + 0x98ed, 0x0005, 0x0036, 0x080c, 0xec02, 0x6043, 0x0000, 0x2019, + 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, + 0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, + 0x080c, 0xa929, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, + 0xa9d4, 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, + 0x9086, 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, + 0xec02, 0x080c, 0xd579, 0x080c, 0x1ab7, 0x6023, 0x0007, 0x6014, + 0x2048, 0x080c, 0xce56, 0x0110, 0x080c, 0xe948, 0x009e, 0x6017, + 0x0000, 0x080c, 0xec02, 0x6023, 0x0007, 0x080c, 0xd579, 0x003e, + 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, + 0x0260, 0x7938, 0x783c, 0x080c, 0x2894, 0x1904, 0xe558, 0x0016, + 0x00c6, 0x080c, 0x671d, 0x1904, 0xe556, 0x001e, 0x00c6, 0x080c, + 0xd561, 0x1130, 0xb8c0, 0x9005, 0x0118, 0x080c, 0x339b, 0x0148, + 0x2b10, 0x2160, 0x6010, 0x0006, 0x6212, 0x080c, 0xd568, 0x000e, + 0x6012, 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, + 0xaa9a, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x007e, + 0x001e, 0x0076, 0x903e, 0x080c, 0xe690, 0x007e, 0x0026, 0xba04, + 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, + 0x1118, 0xbaa0, 0x080c, 0x3304, 0x002e, 0xbcc0, 0x001e, 0x080c, + 0x6141, 0xbe12, 0xbd16, 0xbcc2, 0x9006, 0x0010, 0x00ce, 0x001e, + 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, + 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074, 0x1904, + 0xe5b7, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, + 0x9184, 0x8000, 0x0904, 0xe5b4, 0x2001, 0x197d, 0x2004, 0x9005, + 0x1140, 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0118, 0x9184, 0x0800, + 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xed68, 0x0118, + 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c, + 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff, + 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, 0x0001, + 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, 0x0088, + 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, 0x0900, + 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, 0x6017, + 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210, + 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286, + 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, 0x0138, + 0x9286, 0x0004, 0x0120, 0x080c, 0x672c, 0x0804, 0xe61f, 0x2011, + 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, + 0xc0f7, 0x009e, 0x15a8, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0f7, 0x009e, 0x1548, 0x0046, + 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, + 0x0138, 0x2009, 0x0029, 0x080c, 0xe9a5, 0xb800, 0xc0e5, 0xb802, + 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039, 0x0000, 0x080c, + 0x93b3, 0x2c08, 0x080c, 0xe690, 0x007e, 0x2001, 0x0007, 0x080c, + 0x668f, 0x2001, 0x0007, 0x080c, 0x6663, 0x001e, 0x004e, 0x9006, + 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, + 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, + 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, + 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x2894, 0x11d0, + 0x080c, 0x671d, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1158, 0x2011, + 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, + 0xc0f7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, + 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, + 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x11d0, 0x080c, + 0x671d, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, + 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1158, 0x2011, 0x027a, + 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0f7, + 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, + 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, + 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0x19f2, 0x252c, 0x2021, + 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654, 0x7074, + 0x81ff, 0x0150, 0x0006, 0x9186, 0x1ab8, 0x000e, 0x0128, 0x8001, + 0x9602, 0x1a04, 0xe72e, 0x0018, 0x9606, 0x0904, 0xe72e, 0x080c, + 0x8bc3, 0x0904, 0xe725, 0x2100, 0x9c06, 0x0904, 0xe725, 0x6720, + 0x9786, 0x0007, 0x0904, 0xe725, 0x080c, 0xe9e6, 0x1904, 0xe725, + 0x080c, 0xed86, 0x0904, 0xe725, 0x080c, 0xe9d6, 0x0904, 0xe725, + 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x339b, 0x0904, 0xe76d, + 0x6004, 0x9086, 0x0000, 0x1904, 0xe76d, 0x9786, 0x0004, 0x0904, + 0xe76d, 0x2500, 0x9c06, 0x0904, 0xe725, 0x2400, 0x9c06, 0x05e8, + 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, 0x9086, + 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x9786, 0x000a, + 0x0148, 0x080c, 0xd05e, 0x1130, 0x080c, 0xbae2, 0x009e, 0x080c, + 0xb134, 0x0418, 0x6014, 0x2048, 0x080c, 0xce56, 0x01d8, 0x9786, + 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, + 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, + 0x080c, 0xed00, 0x0016, 0x080c, 0xd14c, 0x080c, 0x6dc4, 0x001e, + 0x080c, 0xd041, 0x009e, 0x080c, 0xb134, 0x9ce0, 0x0018, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe6a4, 0x012e, 0x002e, + 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, + 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xed00, + 0x080c, 0xe948, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x0009, 0x11f8, + 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0, + 0x080c, 0x989d, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56, 0x0118, + 0x6010, 0x080c, 0x6dd1, 0x009e, 0x00c6, 0x080c, 0xb101, 0x00ce, + 0x0036, 0x080c, 0x9a0f, 0x003e, 0x009e, 0x0804, 0xe725, 0x9786, + 0x000a, 0x0904, 0xe715, 0x0804, 0xe70a, 0x81ff, 0x0904, 0xe725, + 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180, 0x0001, + 0x2004, 0x9086, 0x002d, 0x1904, 0xe725, 0x6000, 0x9086, 0x0002, + 0x1904, 0xe725, 0x080c, 0xd04d, 0x0138, 0x080c, 0xd05e, 0x1904, + 0xe725, 0x080c, 0xbae2, 0x0038, 0x080c, 0x326f, 0x080c, 0xd05e, + 0x1110, 0x080c, 0xbae2, 0x080c, 0xb134, 0x0804, 0xe725, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, + 0x2c08, 0x2170, 0x9006, 0x080c, 0xe96f, 0x001e, 0x0120, 0x6020, + 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe7bc, 0xe7bc, + 0xe7bc, 0xe7bc, 0xe7bc, 0xe7bc, 0xe7be, 0xe7bc, 0xe7bc, 0xe7bc, + 0xe7e7, 0xb134, 0xb134, 0xe7bc, 0x9006, 0x0005, 0x0036, 0x0046, + 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, + 0x0020, 0x080c, 0xe9a5, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, + 0xe4c8, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xce56, + 0x0140, 0x6014, 0x904d, 0x080c, 0xca71, 0x687b, 0x0005, 0x080c, + 0x6dd1, 0x009e, 0x080c, 0xb134, 0x9085, 0x0001, 0x0005, 0x0019, + 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, + 0x000b, 0x0005, 0xe802, 0xe802, 0xe819, 0xe809, 0xe828, 0xe802, + 0xe802, 0xe804, 0xe802, 0xe802, 0xe802, 0xe802, 0xe802, 0xe802, + 0xe802, 0xe802, 0x080c, 0x0dc5, 0x080c, 0xb134, 0x9085, 0x0001, + 0x0005, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06, 0x1128, + 0x2019, 0x0001, 0x080c, 0xa877, 0x0010, 0x080c, 0xaa59, 0x00ee, + 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, 0x0005, 0x080c, + 0x6dd1, 0x080c, 0xb134, 0x00de, 0x009e, 0x9085, 0x0001, 0x0005, + 0x601c, 0xd084, 0x190c, 0x1ab7, 0x0c60, 0x2001, 0x0001, 0x080c, + 0x664f, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, + 0x1805, 0x2011, 0x0276, 0x080c, 0xc0e3, 0x003e, 0x002e, 0x001e, + 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, + 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1cd0, + 0x2079, 0x0001, 0x8fff, 0x0904, 0xe89f, 0x2071, 0x1800, 0x7654, + 0x7074, 0x8001, 0x9602, 0x1a04, 0xe89f, 0x88ff, 0x0120, 0x2800, + 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe9d6, 0x0580, 0x2400, 0x9c06, + 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007, 0x0530, + 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584, + 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, + 0x080c, 0xec02, 0x080c, 0xd579, 0x080c, 0x1ab7, 0x6023, 0x0007, + 0x6014, 0x2048, 0x080c, 0xce56, 0x0120, 0x0046, 0x080c, 0xe948, + 0x004e, 0x009e, 0x080c, 0xb134, 0x88ff, 0x1198, 0x9ce0, 0x0018, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe852, 0x9006, + 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076, 0x0056, 0x0086, + 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210, 0x2258, + 0x0096, 0x904e, 0x080c, 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, + 0xa9d4, 0x080c, 0xe843, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, + 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, + 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x671d, 0x1180, 0x0056, + 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, + 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x005e, 0x003e, + 0x001e, 0x8108, 0x1f04, 0xe8d2, 0x0036, 0x2508, 0x2029, 0x0003, + 0x080c, 0xe843, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, + 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086, + 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c, + 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x2c20, 0x080c, + 0xe843, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056, + 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, 0x0016, + 0x0036, 0x080c, 0x671d, 0x1190, 0x0086, 0x9046, 0x2828, 0x0046, + 0x2021, 0x0001, 0x080c, 0xebe6, 0x004e, 0x0096, 0x904e, 0x080c, + 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x003e, 0x001e, + 0x8108, 0x1f04, 0xe91f, 0x0036, 0x2029, 0x0002, 0x080c, 0xe843, + 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x0005, + 0x0016, 0x00f6, 0x080c, 0xce54, 0x0198, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, + 0xab82, 0x080c, 0x6dd1, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6dd1, + 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, + 0x080c, 0x6dd1, 0x2f48, 0x0cb8, 0x080c, 0x6dd1, 0x0c88, 0x00e6, + 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, 0x2071, 0x1800, + 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, + 0x6000, 0x9086, 0x0000, 0x0168, 0x6008, 0x9206, 0x1150, 0x6320, + 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, + 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, + 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, + 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, + 0x100e, 0x000e, 0x090c, 0x0dc5, 0xaae2, 0xa867, 0x010d, 0xa88e, + 0x0026, 0x2010, 0x080c, 0xce44, 0x2001, 0x0000, 0x0120, 0x2200, + 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, + 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198f, + 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6dd1, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786, + 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128, + 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, + 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, + 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, + 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1988, 0x2004, + 0x601a, 0x080c, 0x933b, 0x080c, 0x98ed, 0x001e, 0x0005, 0xa001, + 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, + 0xd190, 0x0030, 0x080c, 0xec02, 0x080c, 0x88f1, 0x080c, 0xb101, + 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xea35, + 0xea35, 0xea35, 0xea37, 0xea35, 0xea37, 0xea37, 0xea35, 0xea37, + 0xea35, 0xea35, 0xea35, 0xea35, 0xea35, 0x9006, 0x0005, 0x9085, + 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, + 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea5b, 0xea4e, + 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0x6007, 0x003b, + 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c, 0x933b, + 0x080c, 0x98ed, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xec02, + 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, + 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xeab4, 0x6814, + 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, + 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, + 0x98ed, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xeb2b, + 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0dc5, + 0x0804, 0xeb2b, 0x2048, 0x080c, 0xce56, 0x1130, 0x0028, 0x2048, + 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, + 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, + 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xe31c, 0x0804, 0xeb2b, + 0x2009, 0x0041, 0x0804, 0xeb25, 0x9186, 0x0005, 0x15a0, 0x6814, + 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xea4e, + 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0dc5, 0x0804, 0xea6f, 0x6007, + 0x003a, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x00c6, + 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, + 0xeb2b, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, + 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, + 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x100e, 0x090c, 0x0dc5, + 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, + 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, + 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, + 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, + 0xa89f, 0x0001, 0x080c, 0x6dd1, 0x2019, 0x0045, 0x6008, 0x2068, + 0x080c, 0xe4c8, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, + 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, 0x0000, 0x6003, + 0x0007, 0x080c, 0xe31c, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, + 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, + 0x0027, 0x1178, 0x080c, 0x97e1, 0x0036, 0x0096, 0x6014, 0x2048, + 0x2019, 0x0004, 0x080c, 0xe948, 0x009e, 0x003e, 0x080c, 0x98ed, + 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xb19b, 0x0005, 0xeb5e, + 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5e, 0xeb5c, 0xeb5c, + 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0x080c, 0x0dc5, 0x080c, 0x97e1, + 0x6003, 0x000c, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0092, 0x1220, + 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xb19b, 0x0005, 0xeb7c, + 0xeb7c, 0xeb7c, 0xeb7c, 0xeb7e, 0xeb9e, 0xeb7c, 0xeb7c, 0xeb7c, + 0xeb7c, 0xeb7c, 0xeb7c, 0xeb7c, 0x080c, 0x0dc5, 0x00d6, 0x2c68, + 0x080c, 0xb0ab, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, + 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, + 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, 0x933b, 0x080c, + 0x98ed, 0x2d60, 0x080c, 0xb101, 0x00de, 0x0005, 0x080c, 0xb101, + 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, + 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, + 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1989, + 0x2004, 0x6042, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, + 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, + 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c, 0x2001, 0x1987, 0x2004, + 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, 0x2058, 0xb8bc, + 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, + 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, + 0x00e6, 0x6154, 0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, + 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x88f1, 0x080c, + 0xb101, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, + 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, + 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, + 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, + 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, + 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, + 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, + 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, + 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xc0f7, + 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x080c, 0x60ba, 0x080c, 0x3019, 0x00ee, 0x0005, 0x0096, + 0x0026, 0x080c, 0x100e, 0x090c, 0x0dc5, 0xa85c, 0x9080, 0x001a, + 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, + 0x0046, 0x1118, 0xa867, 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, + 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, + 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, + 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, + 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, + 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, + 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, + 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, + 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, + 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, + 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, + 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, + 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, + 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, + 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, + 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, + 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, + 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, + 0x0205, 0x2013, 0x0000, 0x002e, 0x080c, 0x6dd1, 0x009e, 0x0005, + 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, + 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, + 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, + 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, 0x252c, 0x2021, 0x19f8, + 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, + 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, + 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xe9d6, + 0x01b8, 0x080c, 0xe9e6, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, + 0x0016, 0x080c, 0x1ab7, 0x001e, 0x080c, 0xd04d, 0x1110, 0x080c, + 0x326f, 0x080c, 0xd05e, 0x1110, 0x080c, 0xbae2, 0x080c, 0xb134, + 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, + 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, + 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, + 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, + 0x0036, 0x0046, 0x080c, 0xd561, 0x0168, 0x2019, 0xffff, 0x9005, + 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, + 0x080c, 0x4da0, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, + 0x0001, 0x1128, 0x080c, 0xaa9a, 0x080c, 0xb134, 0x9006, 0x0005, + 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800, + 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, + 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, + 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, + 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, + 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, + 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, + 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, + 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, + 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, + 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, + 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, + 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, + 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, + 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, + 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, + 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, + 0x2071, 0x1840, 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, + 0x0005, 0x0003, 0x000b, 0x07ce, 0x0000, 0xc000, 0x0001, 0x8064, + 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0x4407, + 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x79c0, + 0x0003, 0x5106, 0x0003, 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a, + 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0, + 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x1680, + 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4028, + 0x0000, 0x4047, 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0822, + 0x0003, 0x4022, 0x0000, 0x0028, 0x000b, 0x4122, 0x0008, 0x94c0, + 0x0009, 0xff00, 0x0008, 0xffe0, 0x0009, 0x0500, 0x0008, 0x0aab, + 0x0003, 0x4447, 0x0002, 0x0ea8, 0x000b, 0x0bfe, 0x0008, 0x11a0, + 0x0001, 0x1286, 0x0003, 0x0ca0, 0x0001, 0x1286, 0x0003, 0x9180, + 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x4436, 0x000b, 0x808c, + 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x0004, + 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, 0x443e, 0x0003, 0x03fe, + 0x0000, 0x43e0, 0x0001, 0x0e83, 0x000b, 0xc2c0, 0x0009, 0x00ff, + 0x0008, 0x02e0, 0x0001, 0x0e83, 0x000b, 0x9180, 0x0001, 0x0005, + 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, + 0x0000, 0x0019, 0x0000, 0x444d, 0x000b, 0x0240, 0x0002, 0x0a80, + 0x0003, 0x00fe, 0x0000, 0x3283, 0x000b, 0x0248, 0x000a, 0x085c, + 0x0003, 0x9180, 0x0001, 0x0006, 0x0008, 0x7f62, 0x0008, 0x8002, + 0x0008, 0x0003, 0x0008, 0x8066, 0x0000, 0x020a, 0x0000, 0x445b, + 0x0003, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, + 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, + 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, + 0x0008, 0x4468, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0e74, + 0x0003, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0e74, 0x0003, 0x1734, + 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, + 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x447a, 0x0003, 0x808a, + 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, + 0x0000, 0x5880, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0x4483, + 0x0003, 0x5884, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002, 0x088a, + 0x000b, 0x0d00, 0x0000, 0x0092, 0x000c, 0x8054, 0x0008, 0x0011, + 0x0008, 0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, + 0x000b, 0x00e0, 0x000c, 0x000a, 0x000b, 0x00fe, 0x0000, 0x349a, + 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, + 0x0000, 0x0231, 0x0008, 0x4499, 0x000b, 0x03fe, 0x0000, 0x04d0, + 0x0001, 0x0cd4, 0x000b, 0x82c0, 0x0001, 0x1f00, 0x0000, 0xffa0, + 0x0001, 0x0400, 0x0000, 0x08b2, 0x0003, 0x14dc, 0x0003, 0x01fe, + 0x0008, 0x0580, 0x0009, 0x7f06, 0x0000, 0x8690, 0x0009, 0x0000, + 0x0008, 0x7f0c, 0x0000, 0x02fe, 0x0008, 0xffc0, 0x0001, 0x00ff, + 0x0008, 0x0680, 0x0009, 0x10b2, 0x0003, 0x7f08, 0x0008, 0x84c0, + 0x0001, 0xff00, 0x0008, 0x08d4, 0x0003, 0xb9c0, 0x0009, 0x0030, + 0x0008, 0x0cc3, 0x000b, 0x8060, 0x0000, 0x0400, 0x0000, 0x80fe, + 0x0008, 0x1a0b, 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0409, + 0x0000, 0x44bc, 0x0003, 0x80fe, 0x0008, 0x1a0a, 0x0009, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x040a, 0x0000, 0x44c2, 0x0003, 0x00fe, + 0x0000, 0x34ca, 0x0003, 0x8072, 0x0000, 0x1010, 0x0008, 0x3944, + 0x0002, 0x08c5, 0x0003, 0x00ce, 0x0003, 0x8072, 0x0000, 0x2020, + 0x0008, 0x3945, 0x000a, 0x08ca, 0x0003, 0x3946, 0x000a, 0x0cdb, + 0x000b, 0x0000, 0x0007, 0x3943, 0x000a, 0x08db, 0x0003, 0x00ce, + 0x0003, 0x00fe, 0x0000, 0x34d9, 0x000b, 0x8072, 0x0000, 0x1000, + 0x0000, 0x00db, 0x000b, 0x8072, 0x0000, 0x2000, 0x0000, 0x4000, + 0x000f, 0x86c0, 0x0009, 0xfc00, 0x0008, 0x08d4, 0x0003, 0x00b2, + 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, + 0x0008, 0x44e4, 0x000b, 0x58e5, 0x000b, 0x0140, 0x0008, 0x0242, + 0x0000, 0x1f43, 0x0002, 0x0cf3, 0x000b, 0x0d44, 0x0000, 0x0d46, + 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x030a, 0x0008, 0x040c, + 0x0000, 0x0d06, 0x0000, 0x0d08, 0x0008, 0x00f7, 0x0003, 0x0344, + 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, 0x1948, + 0x000a, 0x08fa, 0x0003, 0x0d4a, 0x0008, 0x58fa, 0x0003, 0x3efe, + 0x0008, 0x7f4f, 0x0002, 0x0901, 0x0003, 0x8000, 0x0000, 0x0001, + 0x0000, 0x0092, 0x000c, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, + 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, + 0x0003, 0x2b24, 0x0008, 0x2b24, 0x0008, 0x590a, 0x000b, 0x8054, + 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x0958, 0x0003, 0x3a45, + 0x000a, 0x0947, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000, 0x3945, + 0x000a, 0x0917, 0x000b, 0x8072, 0x0000, 0x3010, 0x0000, 0x1e10, + 0x000a, 0x7f3c, 0x0000, 0x0942, 0x000b, 0x1d00, 0x0002, 0x7f3a, + 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, + 0x0008, 0x4520, 0x000b, 0x00fe, 0x0000, 0x353f, 0x000b, 0x1c60, + 0x0000, 0x8062, 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, + 0x0008, 0x4528, 0x0003, 0x00fe, 0x0000, 0x325b, 0x000b, 0x0038, + 0x0000, 0x0060, 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, + 0x0000, 0x0009, 0x0008, 0x4531, 0x000b, 0x80c0, 0x0009, 0x00ff, + 0x0008, 0x7f3e, 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, + 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x453b, + 0x000b, 0x003a, 0x0008, 0x1dfe, 0x0000, 0x011c, 0x000b, 0x0036, + 0x0008, 0x00e0, 0x000c, 0x0158, 0x000b, 0x8074, 0x0000, 0x2000, + 0x0000, 0x8072, 0x0000, 0x2000, 0x0000, 0x0158, 0x000b, 0x3a44, + 0x0002, 0x0a89, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000, 0x8072, + 0x0000, 0x1000, 0x0000, 0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3658, + 0x0003, 0x26fe, 0x0008, 0x26fe, 0x0008, 0x2700, 0x0008, 0x2700, + 0x0008, 0x00d0, 0x0009, 0x0d6a, 0x0003, 0x8074, 0x0000, 0x4040, + 0x0008, 0x5958, 0x0003, 0x5106, 0x0003, 0x3a46, 0x000a, 0x0d6a, + 0x0003, 0x3a47, 0x0002, 0x0965, 0x000b, 0x8054, 0x0008, 0x0004, + 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x8072, 0x0000, 0x3000, + 0x0008, 0x01b4, 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, + 0x0003, 0x1246, 0x000a, 0x0e52, 0x000b, 0x1a60, 0x0000, 0x8062, + 0x0008, 0x0002, 0x0000, 0x8066, 0x0000, 0x362a, 0x0000, 0x456f, + 0x0003, 0x2000, 0x0000, 0x2000, 0x0000, 0x2102, 0x0000, 0x2102, + 0x0000, 0x2204, 0x0000, 0x2204, 0x0000, 0x2306, 0x0000, 0x2306, + 0x0000, 0x2408, 0x0000, 0x2408, 0x0000, 0x250a, 0x0000, 0x250a, + 0x0000, 0x260c, 0x0000, 0x260c, 0x0000, 0x270e, 0x0000, 0x270e, + 0x0000, 0x2810, 0x0000, 0x2810, 0x0000, 0x2912, 0x0000, 0x2912, + 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, + 0x0000, 0x0052, 0x0000, 0x4589, 0x000b, 0x92c0, 0x0009, 0x0780, + 0x0008, 0x0e6e, 0x000b, 0x124b, 0x0002, 0x0992, 0x0003, 0x2e4d, + 0x0002, 0x2e4d, 0x0002, 0x0a58, 0x0003, 0x3a46, 0x000a, 0x0da2, + 0x000b, 0x5994, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x1243, + 0x000a, 0x09b0, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, 0x0233, + 0x000c, 0x1948, 0x000a, 0x099f, 0x000b, 0x0228, 0x000c, 0x1810, + 0x0000, 0x0233, 0x000c, 0x01b0, 0x000b, 0x1948, 0x000a, 0x09a6, + 0x000b, 0x1243, 0x000a, 0x0a5b, 0x0003, 0x194d, 0x000a, 0x09aa, + 0x000b, 0x1243, 0x000a, 0x0a62, 0x0003, 0x59aa, 0x000b, 0x8054, + 0x0008, 0x0004, 0x0000, 0x0228, 0x000c, 0x1810, 0x0000, 0x0233, + 0x000c, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, 0x3000, + 0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0dba, 0x000b, 0x15fe, + 0x0008, 0x3461, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, + 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0233, 0x000c, 0x000a, + 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0dd0, 0x000b, 0x18fe, + 0x0000, 0x3ce0, 0x0009, 0x09cd, 0x0003, 0x15fe, 0x0008, 0x3ce0, + 0x0009, 0x09cd, 0x0003, 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, + 0x0000, 0x0220, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0220, + 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0dd5, 0x000b, 0x3c1e, + 0x0008, 0x0220, 0x000b, 0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dda, + 0x000b, 0x3c20, 0x0000, 0x0220, 0x000b, 0xbbe0, 0x0009, 0x0035, + 0x0008, 0x0de0, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x039c, + 0x000b, 0xbbe0, 0x0009, 0x0036, 0x0008, 0x0abd, 0x000b, 0xbbe0, + 0x0009, 0x0037, 0x0000, 0x0e01, 0x000b, 0x18fe, 0x0000, 0x3ce0, + 0x0009, 0x0dcd, 0x000b, 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, + 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, 0x2604, 0x0008, 0x2604, + 0x0008, 0x2706, 0x0008, 0x2706, 0x0008, 0x2808, 0x0000, 0x2808, + 0x0000, 0x290a, 0x0000, 0x290a, 0x0000, 0x8066, 0x0000, 0x0422, + 0x0000, 0x45f8, 0x000b, 0x0228, 0x000c, 0x8054, 0x0008, 0x0004, + 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, 0xb000, + 0x0000, 0x01b4, 0x0003, 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0e13, + 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0a10, 0x0003, 0x15fe, + 0x0008, 0x3ce0, 0x0009, 0x0dc9, 0x0003, 0x0223, 0x0004, 0x8076, + 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, 0x0280, + 0x000b, 0x8076, 0x0008, 0x0042, 0x0008, 0x0220, 0x000b, 0xbbe0, + 0x0009, 0x0016, 0x0000, 0x0e20, 0x000b, 0x8074, 0x0000, 0x0808, + 0x0008, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800, + 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, + 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, + 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007, 0x0000, 0x022c, + 0x000b, 0x1930, 0x000a, 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, + 0x0000, 0x000a, 0x0008, 0x4631, 0x000b, 0x4000, 0x000f, 0x2236, + 0x000b, 0x0870, 0x0008, 0x4000, 0x000f, 0x7e33, 0x000b, 0xbbe0, + 0x0009, 0x0030, 0x0008, 0x0e33, 0x0003, 0x18fe, 0x0000, 0x3ce0, + 0x0009, 0x0a44, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a44, + 0x000b, 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x0246, + 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x8072, 0x0000, 0x8000, + 0x0000, 0x0233, 0x0003, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0a4f, + 0x0003, 0x8074, 0x0000, 0x0706, 0x0000, 0x0251, 0x000b, 0x8074, + 0x0000, 0x0703, 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, + 0x0000, 0x028e, 0x0003, 0x8010, 0x0008, 0x0008, 0x0000, 0x028e, + 0x0003, 0x8010, 0x0008, 0x0022, 0x0008, 0x028e, 0x0003, 0x0228, + 0x000c, 0x8010, 0x0008, 0x0007, 0x0000, 0x0233, 0x000c, 0x1810, + 0x0000, 0x0233, 0x000c, 0x029a, 0x0003, 0x0228, 0x000c, 0x8010, + 0x0008, 0x001b, 0x0008, 0x0233, 0x000c, 0x1810, 0x0000, 0x0233, + 0x000c, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, + 0x0008, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, 0x0009, + 0x0008, 0x028e, 0x0003, 0x8010, 0x0008, 0x0005, 0x0008, 0x028e, + 0x0003, 0x1648, 0x000a, 0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001, + 0x0000, 0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x086f, + 0x0003, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x028e, + 0x0003, 0x8010, 0x0008, 0x0003, 0x0008, 0x0292, 0x000b, 0x8010, + 0x0008, 0x000b, 0x0000, 0x0292, 0x000b, 0x8010, 0x0008, 0x0002, + 0x0000, 0x0292, 0x000b, 0x3a47, 0x0002, 0x0d58, 0x000b, 0x8010, + 0x0008, 0x0006, 0x0008, 0x0292, 0x000b, 0x8074, 0x0000, 0xf000, + 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0233, 0x000c, 0x0249, + 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, + 0x0008, 0x0233, 0x000c, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, + 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, + 0x0002, 0x2e4d, 0x0002, 0x0aa5, 0x000b, 0x8054, 0x0008, 0x0019, + 0x0000, 0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, + 0x000b, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0283, 0x000b, 0x808c, + 0x0008, 0x0000, 0x0008, 0x4447, 0x0002, 0x0ad1, 0x000b, 0xc0c0, + 0x0001, 0x00ff, 0x0008, 0xffe0, 0x0009, 0x00ff, 0x0008, 0x0ea8, + 0x000b, 0xc1e0, 0x0001, 0xffff, 0x0008, 0x0ea8, 0x000b, 0x8010, + 0x0008, 0x0013, 0x0000, 0x0233, 0x000c, 0x8074, 0x0000, 0x0202, + 0x0008, 0x000a, 0x000b, 0x3a40, 0x000a, 0x0ece, 0x000b, 0x8074, + 0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, + 0x0000, 0x8000, 0x0000, 0x43e0, 0x0001, 0x0ecc, 0x0003, 0x42fe, + 0x0000, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x00e0, 0x0009, 0x0aa8, + 0x0003, 0x0d08, 0x0008, 0x0321, 0x000b, 0x8072, 0x0000, 0x8000, + 0x0000, 0x000a, 0x000b, 0x03a5, 0x0004, 0x808c, 0x0008, 0x0001, + 0x0000, 0x04fe, 0x0008, 0x3388, 0x000b, 0x0460, 0x0000, 0x8062, + 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x46db, + 0x0003, 0x0004, 0x0000, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00, + 0x0000, 0x80e0, 0x0001, 0x0004, 0x0000, 0x0af5, 0x000b, 0x80e0, + 0x0001, 0x0005, 0x0008, 0x0af5, 0x000b, 0x80e0, 0x0001, 0x0006, + 0x0008, 0x0af5, 0x000b, 0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04, + 0x0008, 0x82e0, 0x0009, 0x0600, 0x0008, 0x0af5, 0x000b, 0x82e0, + 0x0009, 0x0500, 0x0008, 0x0af5, 0x000b, 0x82e0, 0x0009, 0x0400, + 0x0000, 0x0f88, 0x000b, 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0, + 0x0009, 0x1000, 0x0000, 0x0b21, 0x0003, 0x0396, 0x0004, 0x3941, + 0x0002, 0x0b00, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, + 0x000b, 0x0460, 0x0000, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, 0x4706, 0x000b, 0x11fe, + 0x0000, 0x331c, 0x0003, 0x9180, 0x0001, 0x0002, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0609, + 0x0008, 0x4710, 0x0003, 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, + 0x0008, 0x03e0, 0x0009, 0x0f19, 0x0003, 0x8072, 0x0000, 0x0400, + 0x0000, 0x0046, 0x0003, 0x9180, 0x0001, 0x0003, 0x0008, 0x0303, + 0x000b, 0x8072, 0x0000, 0x0400, 0x0000, 0x8010, 0x0008, 0x0010, + 0x0000, 0x0379, 0x0003, 0x0396, 0x0004, 0x3941, 0x0002, 0x0b27, + 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x035e, + 0x000c, 0x11fe, 0x0000, 0x372f, 0x000b, 0x8072, 0x0000, 0x0400, + 0x0000, 0x8010, 0x0008, 0x000e, 0x0000, 0x0379, 0x0003, 0x8060, + 0x0000, 0x0400, 0x0000, 0x04fe, 0x0008, 0x3744, 0x0003, 0x808c, + 0x0008, 0x0000, 0x0008, 0x9180, 0x0001, 0x0005, 0x0008, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x473a, 0x000b, 0x0060, + 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, + 0x0008, 0x8066, 0x0000, 0x0412, 0x0000, 0x4742, 0x000b, 0x035b, + 0x0003, 0x808c, 0x0008, 0x0001, 0x0000, 0x0460, 0x0000, 0x8062, + 0x0008, 0x002b, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x474b, + 0x000b, 0x8066, 0x0000, 0x220a, 0x0008, 0x474e, 0x000b, 0x42fe, + 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x8060, + 0x0000, 0x0400, 0x0000, 0x9180, 0x0001, 0x0002, 0x0000, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x041a, 0x0008, 0x475a, 0x000b, 0x8072, + 0x0000, 0x0400, 0x0000, 0x0046, 0x0003, 0x8060, 0x0000, 0x0400, + 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x0411, 0x0000, 0x4763, + 0x000b, 0x02fe, 0x0008, 0x03e0, 0x0009, 0x0f69, 0x000b, 0x0d22, + 0x0000, 0x4000, 0x000f, 0x8280, 0x0009, 0x0002, 0x0000, 0x1380, + 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, 0x476f, + 0x000b, 0x0200, 0x000a, 0xffc0, 0x0001, 0x0007, 0x0000, 0x7f06, + 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x060a, 0x0008, 0x4777, + 0x000b, 0x4000, 0x000f, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x2f44, + 0x000a, 0x2f44, 0x000a, 0x0e83, 0x000b, 0x808a, 0x0008, 0x0003, + 0x0008, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, + 0x0008, 0x5b84, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, + 0x000b, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0000, + 0x0008, 0x8010, 0x0008, 0x0011, 0x0008, 0x0233, 0x000c, 0x42fe, + 0x0000, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x7f10, 0x0008, 0x0233, + 0x000c, 0x4310, 0x0008, 0x0292, 0x000b, 0x3941, 0x0002, 0x0b99, + 0x0003, 0x4000, 0x000f, 0x8072, 0x0000, 0x0404, 0x0008, 0x4000, + 0x000f, 0x8010, 0x0008, 0x0012, 0x0008, 0x0233, 0x000c, 0x035e, + 0x000c, 0x1110, 0x0000, 0x0233, 0x000c, 0x11fe, 0x0000, 0x379f, + 0x0003, 0x000a, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x7f00, + 0x0000, 0xc3c0, 0x0001, 0xff00, 0x0008, 0x00d0, 0x0009, 0x0bca, + 0x0003, 0x0d0a, 0x0000, 0x8580, 0x0001, 0x1000, 0x0000, 0x7f62, + 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, 0x0809, + 0x0000, 0x47b4, 0x000b, 0x04fe, 0x0008, 0x33c3, 0x000b, 0x0460, + 0x0000, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0211, + 0x0000, 0x47bc, 0x0003, 0x01fe, 0x0008, 0x00e0, 0x0009, 0x0fc3, + 0x000b, 0x02fe, 0x0008, 0x43e0, 0x0001, 0x0bc9, 0x0003, 0x0500, + 0x0002, 0x7f0a, 0x0000, 0xffe0, 0x0009, 0x0800, 0x0000, 0x0fad, + 0x0003, 0x0d08, 0x0008, 0x4000, 0x000f, 0x43fe, 0x0008, 0x3e80, + 0x0001, 0xffc0, 0x0001, 0x7fff, 0x0000, 0x0d60, 0x0000, 0x7f62, + 0x0008, 0x8066, 0x0000, 0x0809, 0x0000, 0x47d2, 0x000b, 0x8060, + 0x0000, 0x0400, 0x0000, 0x84c0, 0x0001, 0xff00, 0x0008, 0x7f60, + 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, + 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0xff80, + 0x0009, 0x1000, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0809, + 0x0000, 0x47e4, 0x000b, 0x4000, 0x000f, 0xa90f, 0xeaf9, 0x0001, + 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x95d0 }; #ifdef UNIQUE_FW_NAME -unsigned short fw2300ipx_length01 = 0xf091; +unsigned short fw2300ipx_length01 = 0xee08; #else -unsigned short risc_code_length01 = 0xf091; +unsigned short risc_code_length01 = 0xee08; #endif diff --git a/drivers/scsi/qla2xxx/ql2322.c b/drivers/scsi/qla2xxx/ql2322.c index 3c8cafc12..c88a22c0d 100644 --- a/drivers/scsi/qla2xxx/ql2322.c +++ b/drivers/scsi/qla2xxx/ql2322.c @@ -52,11 +52,6 @@ static struct qla_board_info qla_board_tbl[] = { .isp_name = "ISP2322", .fw_info = qla_fw_tbl, }, - { - .drv_name = qla_driver_name, - .isp_name = "ISP6322", - .fw_info = qla_fw_tbl, - }, }; static struct pci_device_id qla2322_pci_tbl[] = { @@ -67,13 +62,6 @@ static struct pci_device_id qla2322_pci_tbl[] = { .subdevice = PCI_ANY_ID, .driver_data = (unsigned long)&qla_board_tbl[0], }, - { - .vendor = PCI_VENDOR_ID_QLOGIC, - .device = PCI_DEVICE_ID_QLOGIC_ISP6322, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long)&qla_board_tbl[1], - }, {0, 0}, }; MODULE_DEVICE_TABLE(pci, qla2322_pci_tbl); diff --git a/drivers/scsi/qla2xxx/ql2322_fw.c b/drivers/scsi/qla2xxx/ql2322_fw.c index 53599a8e2..cb968e7a0 100644 --- a/drivers/scsi/qla2xxx/ql2322_fw.c +++ b/drivers/scsi/qla2xxx/ql2322_fw.c @@ -6,7 +6,7 @@ */ /* - * Firmware Version 3.03.20 (15:42 Feb 01, 2006) + * Firmware Version 3.03.18 (12:14 Sep 20, 2005) */ #ifdef UNIQUE_FW_NAME @@ -16,15 +16,15 @@ unsigned short risc_code_version = 3*1024+3; #endif #ifdef UNIQUE_FW_NAME -unsigned char fw2322ipx_version_str[] = {3, 3,20}; +unsigned char fw2322ipx_version_str[] = {3, 3,18}; #else -unsigned char firmware_version[] = {3, 3,20}; +unsigned char firmware_version[] = {3, 3,18}; #endif #ifdef UNIQUE_FW_NAME -#define fw2322ipx_VERSION_STRING "3.03.20" +#define fw2322ipx_VERSION_STRING "3.03.18" #else -#define FW_VERSION_STRING "3.03.20" +#define FW_VERSION_STRING "3.03.18" #endif #ifdef UNIQUE_FW_NAME @@ -38,12 +38,12 @@ unsigned short fw2322ipx_code01[] = { #else unsigned short risc_code01[] = { #endif - 0x0470, 0x0000, 0x0000, 0xe719, 0x0000, 0x0003, 0x0003, 0x0014, + 0x0470, 0x0000, 0x0000, 0xe428, 0x0000, 0x0003, 0x0003, 0x0012, 0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, - 0x332e, 0x3033, 0x2e32, 0x3020, 0x2020, 0x2020, 0x2400, 0x20a9, + 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000, @@ -52,6424 +52,6331 @@ unsigned short risc_code01[] = { 0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001, 0x0000, 0x20c1, 0x0004, 0x20c9, 0x1cff, 0x2059, 0x0000, 0x2b78, - 0x7883, 0x0004, 0x2089, 0x2bc2, 0x2051, 0x1800, 0x2a70, 0x20e1, - 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e74, 0x00f6, - 0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20c6, 0x1170, - 0x2079, 0x0300, 0x080c, 0x20dc, 0x2061, 0xe000, 0x080c, 0x20c6, - 0x1128, 0x2079, 0x0380, 0x080c, 0x20dc, 0x0060, 0x00fe, 0x7883, + 0x7883, 0x0004, 0x2089, 0x2bcb, 0x2051, 0x1800, 0x2a70, 0x20e1, + 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e68, 0x00f6, + 0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20e3, 0x1170, + 0x2079, 0x0300, 0x080c, 0x20f9, 0x2061, 0xe000, 0x080c, 0x20e3, + 0x1128, 0x2079, 0x0380, 0x080c, 0x20f9, 0x0060, 0x00fe, 0x7883, 0x4010, 0x7837, 0x4010, 0x7833, 0x0011, 0x2091, 0x5000, 0x2091, 0x4080, 0x0cf8, 0x00fe, 0x2029, 0x5600, 0x2031, 0xffff, 0x2039, 0x55dc, 0x2021, 0x0200, 0x20e9, 0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9, 0x0001, 0x20a1, 0x1000, 0x900e, 0x2001, 0x0dc1, 0x9084, 0x0fff, 0x20a8, 0x4104, 0x2001, 0x0000, 0x9086, 0x0000, 0x0120, 0x21a8, 0x4104, 0x8001, 0x1de0, 0x756e, - 0x7672, 0x776a, 0x7476, 0x747a, 0x00e6, 0x2071, 0x1b73, 0x2472, + 0x7672, 0x776a, 0x7476, 0x747a, 0x00e6, 0x2071, 0x1b74, 0x2472, 0x00ee, 0x20a1, 0x1ddc, 0x7170, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x000f, 0x2001, 0x0001, 0x9112, 0x900e, 0x21a8, 0x4104, 0x8211, 0x1de0, 0x7170, 0x3400, 0x8001, 0x9102, 0x0120, 0x0218, 0x20a8, 0x900e, 0x4104, 0x2009, 0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e, 0x20a9, 0x0800, 0x4104, 0x8211, - 0x1dd8, 0x080c, 0x0f71, 0x080c, 0x61ab, 0x080c, 0xb102, 0x080c, - 0x1128, 0x080c, 0x1352, 0x080c, 0x1c1c, 0x080c, 0x9582, 0x080c, - 0x0d17, 0x080c, 0x10ad, 0x080c, 0x358e, 0x080c, 0x7aca, 0x080c, - 0x6cea, 0x080c, 0x8c5d, 0x080c, 0x88be, 0x080c, 0x22bf, 0x080c, - 0x81f5, 0x080c, 0x20f5, 0x080c, 0x2233, 0x080c, 0x22b4, 0x2091, + 0x1dd8, 0x080c, 0x0f65, 0x080c, 0x6186, 0x080c, 0xaee4, 0x080c, + 0x111c, 0x080c, 0x1346, 0x080c, 0x1c39, 0x080c, 0x938b, 0x080c, + 0x0d0b, 0x080c, 0x10a1, 0x080c, 0x3574, 0x080c, 0x79b3, 0x080c, + 0x6bf1, 0x080c, 0x8af6, 0x080c, 0x8757, 0x080c, 0x22d4, 0x080c, + 0x808e, 0x080c, 0x2112, 0x080c, 0x2250, 0x080c, 0x22c9, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x0943, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04, 0x0937, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x190c, 0x1200, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c, - 0x9084, 0x0030, 0x9086, 0x0020, 0x1168, 0x7034, 0xc08d, 0x7036, - 0x2001, 0x0050, 0x7076, 0x707a, 0x7056, 0x606b, 0x269c, 0x2071, - 0x1b73, 0x2072, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, 0x1168, - 0x080c, 0x4d66, 0x080c, 0x35b5, 0x080c, 0x7b32, 0x080c, 0x7275, - 0x080c, 0x8d44, 0x080c, 0x88e7, 0x0c68, 0x000b, 0x0c88, 0x0979, - 0x097a, 0x0b15, 0x0977, 0x0bcf, 0x0d16, 0x0d16, 0x0d16, 0x080c, - 0x0d85, 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, - 0x0001, 0x1904, 0x0ae8, 0x080c, 0x0ec4, 0x080c, 0x779e, 0x0150, - 0x080c, 0x77c1, 0x15b0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, - 0x782a, 0x0478, 0x080c, 0x76cd, 0x7000, 0x9086, 0x0001, 0x1904, - 0x0ae8, 0x7098, 0x9086, 0x0029, 0x1904, 0x0ae8, 0x080c, 0x88a7, - 0x080c, 0x8899, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, - 0x2011, 0xffff, 0x080c, 0x2ad3, 0x7a28, 0x9295, 0x5e2c, 0x7a2a, - 0x2011, 0x7612, 0x080c, 0x8993, 0x2011, 0x7605, 0x080c, 0x8a9f, - 0x2011, 0x6002, 0x080c, 0x8993, 0x2011, 0x8030, 0x901e, 0x7396, - 0x04d0, 0x080c, 0x58aa, 0x2079, 0x0100, 0x7844, 0x9005, 0x1904, - 0x0ae8, 0x2011, 0x6002, 0x080c, 0x8993, 0x2011, 0x7612, 0x080c, - 0x8993, 0x2011, 0x7605, 0x080c, 0x8a9f, 0x2001, 0x0265, 0x2001, - 0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, - 0x19a7, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, - 0x6153, 0x00ce, 0x0804, 0x0ae8, 0x780f, 0x006b, 0x7a28, 0x080c, - 0x77a6, 0x0118, 0x9295, 0x5e2c, 0x0010, 0x9295, 0x402c, 0x7a2a, - 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a8, 0x2003, 0x0001, 0x080c, - 0x299b, 0x080c, 0x4ca1, 0x7248, 0xc284, 0x724a, 0x2001, 0x180c, - 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x2001, 0x0390, 0x2003, 0x0400, - 0x080c, 0xacfc, 0x080c, 0xa4f1, 0x2011, 0x0004, 0x080c, 0xcf2b, - 0x080c, 0xad18, 0x080c, 0x6ab1, 0x080c, 0x779e, 0x1120, 0x080c, - 0x29fc, 0x0600, 0x0420, 0x080c, 0x615a, 0x0140, 0x7097, 0x0001, - 0x70d3, 0x0000, 0x080c, 0x5a7c, 0x0804, 0x0ae8, 0x2001, 0x0390, - 0x2003, 0x0404, 0x080c, 0x5840, 0xd094, 0x0188, 0x2011, 0x180c, - 0x2204, 0xc0cd, 0x2012, 0x080c, 0x5844, 0xd0d4, 0x1118, 0x080c, - 0x29fc, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, - 0x5844, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x0060, - 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x6c09, 0x1128, - 0xd0a4, 0x0118, 0x2204, 0xc0fd, 0x2012, 0x080c, 0x6bcf, 0x0120, - 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8, 0x707f, 0x0000, 0x080c, 0x779e, - 0x1130, 0x70b0, 0x9005, 0x1168, 0x080c, 0xd389, 0x0050, 0x080c, - 0xd389, 0x70dc, 0xd09c, 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, - 0x6130, 0x70e7, 0x0000, 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, - 0x2a04, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, - 0x080c, 0x779e, 0x1178, 0x9016, 0x0016, 0x080c, 0x27a4, 0x2019, - 0x196d, 0x211a, 0x001e, 0x705f, 0xffff, 0x7063, 0x00ef, 0x7083, - 0x0000, 0x0020, 0x2019, 0x196d, 0x201b, 0x0000, 0x2079, 0x1847, - 0x7804, 0xd0ac, 0x0108, 0xc295, 0x72de, 0x080c, 0x779e, 0x0118, - 0x9296, 0x0004, 0x0518, 0x2011, 0x0001, 0x080c, 0xcf2b, 0x70ab, - 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x00fe, 0x080c, 0x30bf, - 0x080c, 0xacfc, 0x2011, 0x0005, 0x080c, 0xa62b, 0x080c, 0xad18, - 0x080c, 0x779e, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, - 0x27a4, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x00e0, 0x70ab, 0x0000, - 0x70af, 0xffff, 0x7003, 0x0002, 0x080c, 0xacfc, 0x2011, 0x0005, - 0x080c, 0xa62b, 0x080c, 0xad18, 0x080c, 0x779e, 0x0148, 0x00c6, - 0x2061, 0x0100, 0x0016, 0x080c, 0x27a4, 0x61e2, 0x001e, 0x00ce, - 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x779e, 0x1118, - 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x779e, 0x1110, - 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138, 0x9180, 0x1000, - 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x341e, 0x8108, - 0x1f04, 0x0afc, 0x707f, 0x0000, 0x7080, 0x9084, 0x00ff, 0x7082, - 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x00b6, 0x0126, 0x2091, - 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, 0x0bcc, 0x70ac, 0x9086, - 0xffff, 0x0120, 0x080c, 0x30bf, 0x0804, 0x0bcc, 0x70dc, 0xd0ac, - 0x1110, 0xd09c, 0x0538, 0xd084, 0x0528, 0x0006, 0x2001, 0x0103, - 0x2003, 0x002b, 0x000e, 0xd08c, 0x01e8, 0x080c, 0x3487, 0x11b0, - 0x70e0, 0x9086, 0xffff, 0x0190, 0x080c, 0x327b, 0x70dc, 0xd094, - 0x1904, 0x0bcc, 0x2011, 0x0001, 0x080c, 0xd645, 0x0110, 0x2011, - 0x0003, 0x901e, 0x080c, 0x32b5, 0x0804, 0x0bcc, 0x70e4, 0x9005, - 0x1904, 0x0bcc, 0x70a8, 0x9005, 0x1904, 0x0bcc, 0x70dc, 0xd0a4, - 0x0118, 0xd0b4, 0x0904, 0x0bcc, 0x080c, 0x6bcf, 0x1904, 0x0bcc, - 0x080c, 0x6c22, 0x1904, 0x0bcc, 0x080c, 0x6c09, 0x01c0, 0x0156, - 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x67b4, 0x1118, - 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b6c, 0x00ce, - 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0bcc, 0x0006, - 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b4, 0x080c, - 0x0fe1, 0x2011, 0x19ce, 0x080c, 0x0fe1, 0x7030, 0xc08c, 0x7032, - 0x7003, 0x0003, 0x70af, 0xffff, 0x080c, 0x0e98, 0x9006, 0x080c, - 0x2631, 0x080c, 0x3487, 0x0118, 0x080c, 0x4e3e, 0x0050, 0x0036, - 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4e58, 0x004e, - 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x77c1, 0x0150, 0x080c, - 0x779e, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf, - 0x782a, 0x00fe, 0x080c, 0xacfc, 0x2001, 0x19e9, 0x2004, 0x9086, - 0x0005, 0x1120, 0x2011, 0x0000, 0x080c, 0xa62b, 0x2011, 0x0000, - 0x080c, 0xa635, 0x080c, 0xad18, 0x012e, 0x00be, 0x0005, 0x0016, - 0x0026, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, - 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x6119, - 0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0120, 0x2011, - 0x0040, 0x080c, 0x2ad3, 0xd19c, 0x0120, 0x2011, 0x0008, 0x080c, - 0x2ad3, 0x0006, 0x0036, 0x0156, 0x0000, 0x2001, 0x19a8, 0x2004, - 0x9005, 0x1518, 0x080c, 0x2a67, 0x1148, 0x2001, 0x0001, 0x080c, - 0x29ca, 0x2001, 0x0001, 0x080c, 0x29ad, 0x00b8, 0x080c, 0x2a6f, - 0x1138, 0x9006, 0x080c, 0x29ca, 0x9006, 0x080c, 0x29ad, 0x0068, - 0x080c, 0x2a77, 0x1d50, 0x2001, 0x1998, 0x2004, 0xd0fc, 0x0108, - 0x0020, 0x080c, 0x27d8, 0x0804, 0x0cc9, 0x20a9, 0x003a, 0x1d04, - 0x0c1f, 0x080c, 0x8a7f, 0x1f04, 0x0c1f, 0x080c, 0x77af, 0x0148, - 0x080c, 0x77c1, 0x1118, 0x080c, 0x7ac5, 0x0050, 0x080c, 0x77a6, - 0x0dd0, 0x080c, 0x7ac0, 0x080c, 0x7ab6, 0x080c, 0x76cd, 0x0020, - 0x2009, 0x00f8, 0x080c, 0x6119, 0x7850, 0xc0e5, 0x7852, 0x080c, - 0x779e, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, - 0x2019, 0xea60, 0x0d0c, 0x8a7f, 0x7820, 0xd09c, 0x15a0, 0x080c, - 0x779e, 0x0904, 0x0cab, 0x7824, 0xd0ac, 0x1904, 0x0cce, 0x080c, - 0x77c1, 0x1548, 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e, - 0x2011, 0x1800, 0x080c, 0x2ad3, 0x080c, 0x2a7f, 0x7824, 0x9084, - 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004, - 0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x8421, 0x1160, 0x1d04, - 0x0c7b, 0x080c, 0x8a7f, 0x080c, 0x7ac0, 0x080c, 0x7ab6, 0x7003, - 0x0001, 0x0804, 0x0cce, 0x8319, 0x1928, 0x2001, 0x1810, 0x2004, - 0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x1d04, 0x0c91, 0x080c, - 0x8a7f, 0x2009, 0x199b, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, - 0x1188, 0x200b, 0x000a, 0x2011, 0x0048, 0x080c, 0x2ad3, 0x20a9, - 0x0002, 0x080c, 0x2a60, 0x7924, 0x080c, 0x2a7f, 0xd19c, 0x0110, - 0x080c, 0x299b, 0x00f0, 0x080c, 0x77af, 0x1140, 0x94a2, 0x03e8, - 0x1128, 0x080c, 0x7772, 0x7003, 0x0001, 0x00c0, 0x2011, 0x1800, - 0x080c, 0x2ad3, 0x080c, 0x2a7f, 0x7824, 0x080c, 0x77b8, 0x0110, - 0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0c83, 0x7003, 0x0001, - 0x0028, 0x2001, 0x0001, 0x080c, 0x2631, 0x00a0, 0x7850, 0xc0e4, - 0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d, - 0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x2ad3, 0x7828, 0x9085, - 0x0028, 0x782a, 0x2001, 0x19a8, 0x2003, 0x0000, 0x9006, 0x78f2, - 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x002e, 0x001e, - 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x0046, 0x00b6, 0x00c6, - 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0071, 0x0d0c, 0x8a7f, 0x015e, - 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x002e, - 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086, - 0x0001, 0x1110, 0x080c, 0x35b5, 0x00ee, 0x0005, 0x0005, 0x2a70, - 0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0014, - 0x600f, 0x0137, 0x2001, 0x197c, 0x900e, 0x2102, 0x7196, 0x2001, - 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008, - 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd389, 0x70ef, - 0x00c0, 0x2061, 0x196c, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, - 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f, - 0x07d0, 0x2061, 0x1974, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, - 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, - 0x1989, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, - 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x67b4, - 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, - 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210, - 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, - 0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04, - 0x0d87, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000, - 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, 0x000e, - 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae, - 0x681c, 0x78b2, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, 0x2091, - 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, - 0x1b2b, 0x7a08, 0x226a, 0x2069, 0x1b2c, 0x7a18, 0x226a, 0x8d68, - 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1b39, 0x201a, 0x2019, 0x1b3c, - 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, - 0x9386, 0x1b55, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, - 0xdead, 0x2019, 0x1b3a, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, - 0x0000, 0x2069, 0x1a81, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, - 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0dde, 0x2069, 0x1aa1, 0x2019, - 0x0050, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, - 0x1f04, 0x0deb, 0x0491, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, - 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, - 0xd084, 0x0180, 0x2001, 0x1a25, 0x2004, 0x9005, 0x0128, 0x2001, - 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, - 0x2003, 0x1001, 0x080c, 0x584f, 0x1170, 0x080c, 0x0f32, 0x0110, - 0x080c, 0x0e85, 0x080c, 0x584f, 0x1130, 0x2071, 0x1800, 0x2011, - 0x8000, 0x080c, 0x0f46, 0x0c70, 0x0005, 0x2001, 0x0382, 0x2004, - 0x9084, 0x0007, 0x9086, 0x0001, 0x1120, 0x2001, 0x0015, 0x080c, - 0xaced, 0x2079, 0x0380, 0x2069, 0x1b0b, 0x7818, 0x6802, 0x781c, - 0x6806, 0x7840, 0x680a, 0x7844, 0x680e, 0x782c, 0x6812, 0x2019, - 0x1b16, 0x9016, 0x7808, 0xd09c, 0x0150, 0x7820, 0x201a, 0x8210, - 0x8318, 0x8210, 0x9282, 0x0011, 0x0ea8, 0x2011, 0xdead, 0x6a2a, - 0x7830, 0x681a, 0x7834, 0x681e, 0x7838, 0x6822, 0x783c, 0x6826, - 0x7803, 0x0000, 0x2069, 0x1acb, 0x901e, 0x20a9, 0x0020, 0x7b26, - 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04, 0x0e5f, 0x2069, 0x1aeb, - 0x2019, 0x00b0, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68, - 0x8318, 0x1f04, 0x0e6c, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, - 0x2004, 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d, - 0x6400, 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, - 0x0080, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x2011, - 0x0040, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x0c78, - 0x0026, 0x080c, 0x0f32, 0x1188, 0x2011, 0x010e, 0x2214, 0x9294, - 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0x0947, 0x0010, 0x2011, - 0x1b47, 0x080c, 0x0f46, 0x002e, 0x0005, 0x2011, 0x010e, 0x2214, - 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010, - 0x2011, 0x6840, 0xd0e4, 0x70f3, 0x0000, 0x1120, 0x70f3, 0x0fa0, - 0x080c, 0x0f37, 0x002e, 0x0005, 0x0026, 0x080c, 0x0f32, 0x0148, - 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, - 0x0f37, 0x002e, 0x0005, 0x0026, 0x70f3, 0x0000, 0x080c, 0x0f32, - 0x1130, 0x2011, 0x8040, 0x080c, 0x0f46, 0x002e, 0x0005, 0x080c, - 0x2a77, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, - 0x0f37, 0x002e, 0x0005, 0x00e6, 0x0016, 0x0006, 0x2071, 0x1800, - 0xd0b4, 0x70ec, 0x71e8, 0x1118, 0xc0e4, 0xc1f4, 0x0050, 0x0006, - 0x3b00, 0x9084, 0xff3e, 0x20d8, 0x000e, 0x70f3, 0x0000, 0xc0e5, - 0xc1f5, 0x0099, 0x000e, 0x001e, 0x00ee, 0x0005, 0x00e6, 0x2071, - 0x1800, 0xd0e4, 0x70ec, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0016, - 0x71e8, 0x0019, 0x001e, 0x00ee, 0x0005, 0x70ee, 0x71ea, 0x7000, - 0x9084, 0x0007, 0x000b, 0x0005, 0x0eea, 0x0ec4, 0x0ec4, 0x0e98, - 0x0ed3, 0x0ec4, 0x0ec4, 0x0ed3, 0xc284, 0x0016, 0x3b08, 0x3a00, - 0x9104, 0x918d, 0x00c1, 0x21d8, 0x9084, 0xff3e, 0x9205, 0x20d0, - 0x001e, 0x0005, 0x2001, 0x183b, 0x2004, 0xd0dc, 0x0005, 0x9e86, - 0x1800, 0x190c, 0x0d85, 0x70ec, 0xd0e4, 0x0108, 0xc2e5, 0x72ee, - 0xd0e4, 0x1118, 0x9294, 0x00c1, 0x08f9, 0x0005, 0x9e86, 0x1800, - 0x190c, 0x0d85, 0x70e8, 0xd0f4, 0x0108, 0xc2f5, 0x72ea, 0xd0f4, - 0x1140, 0x9284, 0x8000, 0x8005, 0xc284, 0x9215, 0x9294, 0x00c1, - 0x0861, 0x0005, 0x1d04, 0x0f5a, 0x2091, 0x6000, 0x1f04, 0x0f5a, - 0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, - 0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, - 0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061, 0x188d, 0x600b, - 0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, - 0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, - 0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, - 0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, - 0x000e, 0x200f, 0x2001, 0x189d, 0x928a, 0x000e, 0x1638, 0x928a, - 0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, - 0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, - 0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, - 0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, - 0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, - 0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c, 0x0f61, 0x2100, - 0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, - 0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, - 0x0005, 0x20e9, 0x0001, 0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009, - 0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, - 0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x707c, - 0x8007, 0x7180, 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, - 0x23a0, 0x900e, 0x080c, 0x0d65, 0x2001, 0x0000, 0x810f, 0x20a9, - 0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, - 0x0006, 0x080c, 0x108b, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, - 0x1800, 0x080c, 0x1104, 0x090c, 0x0d85, 0x00ee, 0x0005, 0x0086, - 0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, - 0x2071, 0x1800, 0x73c0, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, - 0x9906, 0x090c, 0x0d85, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0d85, - 0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, - 0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, - 0x1910, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, - 0x090c, 0x0d85, 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, - 0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70c0, - 0x8001, 0x0270, 0x70c2, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, - 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, - 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, - 0x70c0, 0x90ca, 0x0020, 0x0268, 0x8001, 0x70c2, 0x702c, 0x2048, - 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, - 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, - 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, - 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, - 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, - 0x080c, 0x8899, 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, - 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, - 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, - 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7000, 0x9005, - 0x11a0, 0x2001, 0x0558, 0xa802, 0x2048, 0x2009, 0x5600, 0x8940, - 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, - 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7104, - 0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, - 0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, - 0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, - 0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, - 0x1800, 0x74be, 0x74c2, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, - 0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, - 0x0440, 0x0278, 0x9982, 0x0558, 0x0288, 0x9982, 0x0800, 0x1270, - 0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188d, 0x7010, 0x9902, - 0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, - 0x00e6, 0x2071, 0x1a24, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, - 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, - 0x0080, 0x9006, 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04, - 0x113e, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022, - 0x1f04, 0x1147, 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, - 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a24, 0x701c, 0x9088, - 0x1a2e, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, - 0x090c, 0x0d85, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, - 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, - 0x00e6, 0x2071, 0x1a24, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, - 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, - 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, 0x1190, 0x1313, - 0x118e, 0x118e, 0x1307, 0x1307, 0x1307, 0x1307, 0x080c, 0x0d85, - 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, - 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x1a2e, - 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b, - 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, - 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868, - 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, - 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, - 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203, - 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005, - 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018, - 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c, - 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, - 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a, - 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, - 0x2009, 0x1a24, 0x2104, 0xc095, 0x200a, 0x080c, 0x116d, 0x0005, - 0x0016, 0x00e6, 0x2071, 0x1a24, 0x00f6, 0x2079, 0x0080, 0x792c, - 0xd1bc, 0x190c, 0x0d7e, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, - 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x117e, - 0x1226, 0x125a, 0x1332, 0x0d85, 0x134d, 0x0d85, 0x918c, 0x0700, - 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0, - 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8, - 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005, - 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11c3, 0x0005, - 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, - 0x080c, 0x117e, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, - 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, - 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11d8, 0x0005, 0x7008, - 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080, - 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808, - 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, - 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b9, 0x2004, 0x9906, - 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e, - 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086, - 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c, 0x116d, 0x0005, - 0x00de, 0x009e, 0x080c, 0x116d, 0x0005, 0xa8a8, 0xd08c, 0x0005, - 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c, 0x908e, 0x0100, - 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, - 0x7006, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x108b, - 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c, - 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, - 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, - 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, - 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, 0x114e, 0x00e8, - 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x7006, 0x000e, 0x001e, - 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0xb16c, - 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, - 0x108b, 0x7007, 0x0000, 0x080c, 0x116d, 0x00ae, 0x0005, 0x0126, - 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, - 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x192f, 0x204c, 0xa87c, - 0x7812, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, - 0x780e, 0x782b, 0x0020, 0x0126, 0x2091, 0x8000, 0x782b, 0x0041, - 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900, 0x700a, 0x012e, - 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, - 0x0096, 0x2001, 0x192f, 0x204c, 0xaa7c, 0x009e, 0x080c, 0x8f88, - 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, 0x080c, 0x8de7, - 0x7007, 0x0000, 0x080c, 0x117e, 0x0005, 0x7007, 0x0000, 0x080c, - 0x117e, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071, - 0x1a6e, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x0041, 0x7807, 0x0007, - 0x7803, 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, - 0x0000, 0x2001, 0x0165, 0x2003, 0x4198, 0x7808, 0xd09c, 0x0120, - 0x7820, 0x080c, 0x13b6, 0x0cc8, 0x2001, 0x1a6f, 0x2003, 0x0000, - 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, - 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, - 0x1a81, 0x78e3, 0xff00, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001, - 0x1a70, 0x2003, 0x0000, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, - 0x781f, 0x0303, 0x2061, 0x1a81, 0x602f, 0x1ddc, 0x2001, 0x181a, - 0x2004, 0x9082, 0x1ddc, 0x6032, 0x603b, 0x1ec1, 0x602b, 0x1ac1, - 0x6007, 0x1aa1, 0x2061, 0x1aa1, 0x606f, 0x193d, 0x2001, 0x1928, - 0x2004, 0x607a, 0x783f, 0x348e, 0x00ce, 0x0005, 0x9086, 0x000d, - 0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c, - 0xcf09, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, - 0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c, - 0xb20a, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, - 0x9184, 0x0070, 0x190c, 0x0d7e, 0xd19c, 0x05a0, 0x7820, 0x908c, - 0xf000, 0x0540, 0x2060, 0x6020, 0x9086, 0x0003, 0x1550, 0x6000, - 0x9086, 0x0004, 0x1530, 0x6114, 0x2148, 0xa876, 0xa87a, 0xa867, - 0x0103, 0x080c, 0x6e27, 0x00b6, 0x6010, 0x2058, 0xba3c, 0x8211, - 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x190c, 0x68df, 0x00be, 0x6044, - 0xd0fc, 0x190c, 0xad25, 0x080c, 0xb195, 0x7808, 0xd09c, 0x19b0, - 0x012e, 0x0005, 0x908a, 0x0024, 0x1a0c, 0x0d85, 0x002b, 0x012e, - 0x0005, 0x04b0, 0x012e, 0x0005, 0x1438, 0x145e, 0x148e, 0x1493, - 0x1497, 0x149c, 0x14c4, 0x14c8, 0x14d6, 0x14da, 0x1438, 0x15a7, - 0x15ab, 0x161d, 0x1624, 0x1438, 0x1625, 0x1626, 0x1631, 0x1638, - 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x149e, - 0x1438, 0x1466, 0x148b, 0x1452, 0x1438, 0x1472, 0x143c, 0x143a, - 0x080c, 0x0d85, 0x080c, 0x0d7e, 0x080c, 0x1643, 0x2009, 0x1a7d, - 0x2104, 0x8000, 0x200a, 0x080c, 0x82b8, 0x080c, 0x1b1e, 0x0005, - 0x6044, 0xd0fc, 0x190c, 0xad25, 0x2009, 0x0055, 0x080c, 0xb20a, - 0x012e, 0x0005, 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c, - 0xad25, 0x2009, 0x0055, 0x080c, 0xb20a, 0x0005, 0x2009, 0x0048, - 0x080c, 0x1643, 0x2060, 0x080c, 0xb20a, 0x0005, 0x2009, 0x0054, - 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xad25, 0x080c, - 0xb20a, 0x0005, 0x080c, 0x1643, 0x2060, 0x0056, 0x0066, 0x080c, - 0x1643, 0x2028, 0x080c, 0x1643, 0x2030, 0x0036, 0x0046, 0x2021, - 0x0000, 0x2418, 0x2009, 0x0056, 0x080c, 0xb20a, 0x004e, 0x003e, - 0x006e, 0x005e, 0x0005, 0x080c, 0x1643, 0x0005, 0x7004, 0xc085, - 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, - 0x1643, 0x080c, 0x1740, 0x0005, 0x080c, 0x0d85, 0x080c, 0x1643, - 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, - 0x0048, 0x080c, 0xb20a, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, - 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, - 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x1648, 0x2001, - 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, - 0x080c, 0x1643, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, - 0x009e, 0x2009, 0x0048, 0x080c, 0xb20a, 0x0005, 0x080c, 0x1643, - 0x080c, 0x0d85, 0x080c, 0x1643, 0x080c, 0x1592, 0x7827, 0x0018, - 0x79ac, 0xd1dc, 0x0904, 0x1543, 0x7827, 0x0015, 0x7828, 0x782b, - 0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, - 0x0020, 0x0804, 0x1549, 0x7004, 0x9005, 0x01c8, 0x1188, 0x78ab, - 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0d85, - 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x1577, - 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x0005, 0x7827, - 0x0018, 0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106, - 0x0110, 0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4, - 0x0140, 0x00ee, 0x080c, 0x1b1e, 0x080c, 0x1366, 0x7803, 0x0001, - 0x0005, 0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00, - 0x9186, 0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006, - 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x2001, 0x020d, - 0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, - 0x0d85, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, - 0x080c, 0x82b8, 0x080c, 0x1b1e, 0x080c, 0xcf1b, 0x0158, 0xa9ac, - 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, - 0xc0bd, 0xa882, 0x080c, 0xcae9, 0x0005, 0x6020, 0x9086, 0x0009, - 0x1128, 0x2009, 0x004c, 0x080c, 0xb20a, 0x0048, 0x6010, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd31e, 0x2029, - 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, - 0x7dbc, 0x080c, 0xeeb1, 0xd5a4, 0x1118, 0x080c, 0x1648, 0x0005, - 0x080c, 0x82b8, 0x080c, 0x1b1e, 0x0005, 0x781f, 0x0300, 0x7803, - 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, - 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, - 0x080c, 0x16b9, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, - 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0d85, - 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c, - 0x1723, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, - 0x0020, 0x080c, 0x1648, 0x0005, 0x81ff, 0x190c, 0x0d85, 0x0005, - 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904, - 0x1612, 0x2071, 0x0200, 0x080c, 0x1710, 0x05e0, 0x080c, 0x1723, - 0x05b0, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e, - 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550, - 0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, - 0x00b0, 0x00f6, 0x2c78, 0x080c, 0x1942, 0x00fe, 0x2009, 0x01f4, - 0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, - 0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x1648, 0x0040, 0x2001, - 0x020d, 0x2003, 0x0020, 0x080c, 0x1366, 0x7803, 0x0001, 0x00ee, - 0x001e, 0x0005, 0x080c, 0x1723, 0x0dd0, 0x2001, 0x020d, 0x2003, - 0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009, - 0x0053, 0x080c, 0xb20a, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, - 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x92d5, - 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8ed9, 0x0cd0, 0x0005, - 0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214, - 0x080c, 0x16b9, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, - 0x080c, 0x1592, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, - 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000, - 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182, - 0x0841, 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c, - 0x810c, 0x080c, 0x16ab, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, - 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, - 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, - 0x080c, 0x82b8, 0x080c, 0x1b1e, 0x0090, 0x7827, 0x0015, 0x782b, - 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, - 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, - 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, - 0x0015, 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800, - 0x6802, 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005, - 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041, - 0x0005, 0x00f6, 0x00e6, 0x2079, 0x0300, 0x0006, 0x2071, 0x1a6e, - 0x7008, 0x9005, 0x1110, 0x78e3, 0x0c0c, 0x8000, 0x700a, 0x0026, - 0x2011, 0x0006, 0x7808, 0xd09c, 0x0150, 0x0016, 0x0026, 0x00c6, - 0x080c, 0x13d4, 0x00ce, 0x002e, 0x001e, 0x8211, 0x1d98, 0x002e, - 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x00b9, - 0x1178, 0x2071, 0x1a6e, 0x7008, 0x9005, 0x0130, 0x8001, 0x0a0c, - 0x0d85, 0x700a, 0x78e3, 0x0c00, 0x000e, 0x00ee, 0x00fe, 0x0005, - 0x000e, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85, 0x2009, - 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc, 0x1dd8, 0x0005, 0x9085, - 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0c79, - 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85, - 0x7037, 0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc, - 0x1110, 0x7054, 0x2060, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, - 0x9085, 0x0001, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200, - 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc, - 0x1158, 0x2021, 0x1a7e, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c, - 0x82b8, 0x080c, 0x1b1e, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005, - 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0841, - 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x17a2, 0x7017, - 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x17a2, 0x2001, - 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, - 0x1904, 0x17a2, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c, - 0x8210, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, - 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xd2f9, - 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c, - 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x1ee1, 0x1190, - 0x080c, 0x199f, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, - 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, - 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, - 0x080c, 0x1648, 0x0005, 0x080c, 0x0d85, 0x2001, 0x180d, 0x2004, - 0xd08c, 0x190c, 0x6ccc, 0x2cf0, 0x0126, 0x2091, 0x2200, 0x0016, - 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, - 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1ec1, 0x2165, 0x0002, - 0x17df, 0x184d, 0x17df, 0x17df, 0x17e3, 0x182e, 0x17df, 0x1803, - 0x17d8, 0x1844, 0x17df, 0x17df, 0x17e8, 0x193a, 0x1817, 0x180d, - 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x1844, 0x9085, - 0x0001, 0x0804, 0x1930, 0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1854, - 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x18bf, 0xa898, 0x901d, 0x1108, - 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, - 0x2004, 0x9080, 0x9536, 0x2005, 0x9005, 0x090c, 0x0d85, 0x2004, - 0xa8ae, 0x0804, 0x1918, 0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, - 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1854, 0xa87c, 0xd0bc, 0x0978, - 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x18bf, 0xa87c, - 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, - 0x090c, 0x0d85, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ec1, - 0x2065, 0xa888, 0xd19c, 0x1904, 0x18bf, 0x0430, 0xa87c, 0xd0ac, - 0x0904, 0x17df, 0xa804, 0x9045, 0x090c, 0x0d85, 0xa164, 0xa91a, - 0x91ec, 0x000f, 0x9d80, 0x1ec1, 0x2065, 0x9006, 0xa842, 0xa83e, - 0xd19c, 0x1904, 0x18bf, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x17df, - 0x9006, 0xa842, 0xa83e, 0x0804, 0x18bf, 0xa87c, 0xd0ac, 0x0904, - 0x17df, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, - 0x0d85, 0x9082, 0x001b, 0x0002, 0x1877, 0x1877, 0x1879, 0x1877, - 0x1877, 0x1877, 0x1883, 0x1877, 0x1877, 0x1877, 0x188d, 0x1877, - 0x1877, 0x1877, 0x1897, 0x1877, 0x1877, 0x1877, 0x18a1, 0x1877, - 0x1877, 0x1877, 0x18ab, 0x1877, 0x1877, 0x1877, 0x18b5, 0x080c, - 0x0d85, 0xa574, 0xa478, 0x9d86, 0x0024, 0x0904, 0x17ed, 0xa37c, - 0xa280, 0x0804, 0x1918, 0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, - 0x17ed, 0xa38c, 0xa290, 0x0804, 0x1918, 0xa594, 0xa498, 0x9d86, - 0x0024, 0x0904, 0x17ed, 0xa39c, 0xa2a0, 0x0804, 0x1918, 0xa5a4, - 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x17ed, 0xa3ac, 0xa2b0, 0x0804, - 0x1918, 0xa5b4, 0xa4b8, 0x9d86, 0x0024, 0x0904, 0x17ed, 0xa3bc, - 0xa2c0, 0x0804, 0x1918, 0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, - 0x17ed, 0xa3cc, 0xa2d0, 0x0804, 0x1918, 0xa5d4, 0xa4d8, 0x9d86, - 0x0024, 0x0904, 0x17ed, 0xa3dc, 0xa2e0, 0x0804, 0x1918, 0x2c05, - 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x18e2, - 0x18e0, 0x18e0, 0x18e0, 0x18e0, 0x18e0, 0x18ed, 0x18e0, 0x18e0, - 0x18e0, 0x18e0, 0x18e0, 0x18f8, 0x18e0, 0x18e0, 0x18e0, 0x18e0, - 0x18e0, 0x1903, 0x18e0, 0x18e0, 0x18e0, 0x18e0, 0x18e0, 0x190e, - 0x080c, 0x0d85, 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, - 0x0904, 0x17ed, 0xa37c, 0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, - 0xa690, 0x9d86, 0x002c, 0x0904, 0x17ed, 0xa394, 0xa298, 0x0400, - 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x002c, 0x0904, 0x17ed, - 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, - 0x002c, 0x0904, 0x17ed, 0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, - 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904, 0x17ed, 0xa3dc, 0xa2e0, - 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, - 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, - 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, - 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, - 0xa812, 0x0c70, 0x0804, 0x17df, 0x2001, 0x180d, 0x2004, 0xd08c, - 0x190c, 0x6ccc, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, - 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1ebc, 0xa813, - 0x1ebc, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, - 0x0d85, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, - 0x0d85, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, + 0xd084, 0x190c, 0x11f4, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c, + 0x9084, 0x0030, 0x9086, 0x0000, 0x190c, 0x0d79, 0x2071, 0x1800, + 0x7000, 0x908e, 0x0003, 0x1168, 0x080c, 0x4ced, 0x080c, 0x359b, + 0x080c, 0x7a1b, 0x080c, 0x7174, 0x080c, 0x8bdd, 0x080c, 0x8780, + 0x0c68, 0x000b, 0x0c88, 0x096d, 0x096e, 0x0b09, 0x096b, 0x0bc3, + 0x0d0a, 0x0d0a, 0x0d0a, 0x080c, 0x0d79, 0x0005, 0x0126, 0x00f6, + 0x2091, 0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x080c, + 0x0eb8, 0x080c, 0x769d, 0x0150, 0x080c, 0x76c0, 0x15b0, 0x2079, + 0x0100, 0x7828, 0x9085, 0x1800, 0x782a, 0x0478, 0x080c, 0x75cc, + 0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x7098, 0x9086, 0x0029, + 0x1904, 0x0adc, 0x080c, 0x8740, 0x080c, 0x8732, 0x2001, 0x0161, + 0x2003, 0x0001, 0x2079, 0x0100, 0x2011, 0xffff, 0x080c, 0x2adc, + 0x7a28, 0x9295, 0x5e2c, 0x7a2a, 0x2011, 0x7511, 0x080c, 0x882c, + 0x2011, 0x7504, 0x080c, 0x8938, 0x2011, 0x5fdd, 0x080c, 0x882c, + 0x2011, 0x8030, 0x901e, 0x7396, 0x04d0, 0x080c, 0x588a, 0x2079, + 0x0100, 0x7844, 0x9005, 0x1904, 0x0adc, 0x2011, 0x5fdd, 0x080c, + 0x882c, 0x2011, 0x7511, 0x080c, 0x882c, 0x2011, 0x7504, 0x080c, + 0x8938, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840, + 0x9084, 0xfffb, 0x7842, 0x2001, 0x19a8, 0x2004, 0x9005, 0x1140, + 0x00c6, 0x2061, 0x0100, 0x080c, 0x612e, 0x00ce, 0x0804, 0x0adc, + 0x780f, 0x006b, 0x7a28, 0x080c, 0x76a5, 0x0118, 0x9295, 0x5e2c, + 0x0010, 0x9295, 0x402c, 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, + 0x19a9, 0x2003, 0x0001, 0x080c, 0x29a8, 0x080c, 0x4c28, 0x7248, + 0xc284, 0x724a, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, + 0x2001, 0x0390, 0x2003, 0x0400, 0x080c, 0xaaf7, 0x080c, 0xa2ec, + 0x2011, 0x0004, 0x080c, 0xcc43, 0x080c, 0xab13, 0x080c, 0x6a77, + 0x080c, 0x769d, 0x1120, 0x080c, 0x2a09, 0x0600, 0x0420, 0x080c, + 0x6135, 0x0140, 0x7097, 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a57, + 0x0804, 0x0adc, 0x2001, 0x0390, 0x2003, 0x0404, 0x080c, 0x5820, + 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, + 0x5824, 0xd0d4, 0x1118, 0x080c, 0x2a09, 0x1270, 0x2011, 0x180c, + 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x5824, 0xd0d4, 0x1db8, 0x2011, + 0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, 0xc0bd, + 0x2012, 0x080c, 0x6bc5, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd, + 0x2012, 0x080c, 0x6b8b, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8, + 0x707f, 0x0000, 0x080c, 0x769d, 0x1130, 0x70b0, 0x9005, 0x1168, + 0x080c, 0xd0a1, 0x0050, 0x080c, 0xd0a1, 0x70dc, 0xd09c, 0x1128, + 0x70b0, 0x9005, 0x0110, 0x080c, 0x610b, 0x70e7, 0x0000, 0x70e3, + 0x0000, 0x70a7, 0x0000, 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, + 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x769d, 0x1178, 0x9016, + 0x0016, 0x080c, 0x27b9, 0x2019, 0x196e, 0x211a, 0x001e, 0x705f, + 0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, 0x196e, + 0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, 0xc295, + 0x72de, 0x080c, 0x769d, 0x0118, 0x9296, 0x0004, 0x0518, 0x2011, + 0x0001, 0x080c, 0xcc43, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, + 0x0002, 0x00fe, 0x080c, 0x30c8, 0x080c, 0xaaf7, 0x2011, 0x0005, + 0x080c, 0xa426, 0x080c, 0xab13, 0x080c, 0x769d, 0x0148, 0x00c6, + 0x2061, 0x0100, 0x0016, 0x080c, 0x27b9, 0x61e2, 0x001e, 0x00ce, + 0x012e, 0x00e0, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, + 0x080c, 0xaaf7, 0x2011, 0x0005, 0x080c, 0xa426, 0x080c, 0xab13, + 0x080c, 0x769d, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, + 0x27b9, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, + 0x00b6, 0x080c, 0x769d, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, + 0x0782, 0x080c, 0x769d, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, + 0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, + 0xd0bc, 0x090c, 0x3404, 0x8108, 0x1f04, 0x0af0, 0x707f, 0x0000, + 0x7080, 0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce, + 0x0005, 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, + 0x1904, 0x0bc0, 0x70ac, 0x9086, 0xffff, 0x0120, 0x080c, 0x30c8, + 0x0804, 0x0bc0, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0538, 0xd084, + 0x0528, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0xd08c, + 0x01e8, 0x080c, 0x346d, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190, + 0x080c, 0x3261, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001, + 0x080c, 0xd35d, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x329b, + 0x0804, 0x0bc0, 0x70e4, 0x9005, 0x1904, 0x0bc0, 0x70a8, 0x9005, + 0x1904, 0x0bc0, 0x70dc, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0bc0, + 0x080c, 0x6b8b, 0x1904, 0x0bc0, 0x080c, 0x6bde, 0x1904, 0x0bc0, + 0x080c, 0x6bc5, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, + 0x0016, 0x080c, 0x6783, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, + 0x8108, 0x1f04, 0x0b60, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, + 0x015e, 0x0804, 0x0bc0, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, + 0x000e, 0x2011, 0x19b5, 0x080c, 0x0fd5, 0x2011, 0x19cf, 0x080c, + 0x0fd5, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff, + 0x080c, 0x0e8c, 0x9006, 0x080c, 0x2646, 0x080c, 0x346d, 0x0118, + 0x080c, 0x4dc5, 0x0050, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, + 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x76c0, 0x0150, 0x080c, 0x769d, 0x7828, 0x0118, 0x9084, + 0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0xaaf7, + 0x2001, 0x19ea, 0x2004, 0x9086, 0x0005, 0x1120, 0x2011, 0x0000, + 0x080c, 0xa426, 0x2011, 0x0000, 0x080c, 0xa430, 0x080c, 0xab13, + 0x012e, 0x00be, 0x0005, 0x0016, 0x0026, 0x0046, 0x00f6, 0x0126, + 0x2091, 0x8000, 0x2079, 0x0100, 0x7904, 0x918c, 0xfffd, 0x7906, + 0x2009, 0x00f7, 0x080c, 0x60f4, 0x7940, 0x918c, 0x0010, 0x7942, + 0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x2adc, 0xd19c, + 0x0120, 0x2011, 0x0008, 0x080c, 0x2adc, 0x0006, 0x0036, 0x0156, + 0x0000, 0x2001, 0x19a9, 0x2004, 0x9005, 0x1518, 0x080c, 0x2a70, + 0x1148, 0x2001, 0x0001, 0x080c, 0x29d7, 0x2001, 0x0001, 0x080c, + 0x29ba, 0x00b8, 0x080c, 0x2a78, 0x1138, 0x9006, 0x080c, 0x29d7, + 0x9006, 0x080c, 0x29ba, 0x0068, 0x080c, 0x2a80, 0x1d50, 0x2001, + 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27e5, 0x0804, + 0x0cbd, 0x20a9, 0x003a, 0x1d04, 0x0c13, 0x080c, 0x8918, 0x1f04, + 0x0c13, 0x080c, 0x76ae, 0x0148, 0x080c, 0x76c0, 0x1118, 0x080c, + 0x79ae, 0x0050, 0x080c, 0x76a5, 0x0dd0, 0x080c, 0x79a9, 0x080c, + 0x799f, 0x080c, 0x75cc, 0x0020, 0x2009, 0x00f8, 0x080c, 0x60f4, + 0x7850, 0xc0e5, 0x7852, 0x080c, 0x769d, 0x0120, 0x7843, 0x0090, + 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x8918, + 0x7820, 0xd09c, 0x15a0, 0x080c, 0x769d, 0x0904, 0x0c9f, 0x7824, + 0xd0ac, 0x1904, 0x0cc2, 0x080c, 0x76c0, 0x1548, 0x0046, 0x2021, + 0x0320, 0x8421, 0x1df0, 0x004e, 0x2011, 0x1800, 0x080c, 0x2adc, + 0x080c, 0x2a88, 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, + 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, + 0x0ce5, 0x8421, 0x1160, 0x1d04, 0x0c6f, 0x080c, 0x8918, 0x080c, + 0x79a9, 0x080c, 0x799f, 0x7003, 0x0001, 0x0804, 0x0cc2, 0x8319, + 0x1928, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, + 0x0ce5, 0x1d04, 0x0c85, 0x080c, 0x8918, 0x2009, 0x199c, 0x2104, + 0x9005, 0x0118, 0x8001, 0x200a, 0x1188, 0x200b, 0x000a, 0x2011, + 0x0048, 0x080c, 0x2adc, 0x20a9, 0x0002, 0x080c, 0x2a69, 0x7924, + 0x080c, 0x2a88, 0xd19c, 0x0110, 0x080c, 0x29a8, 0x00f0, 0x080c, + 0x76ae, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x7671, 0x7003, + 0x0001, 0x00c0, 0x2011, 0x1800, 0x080c, 0x2adc, 0x080c, 0x2a88, + 0x7824, 0x080c, 0x76b7, 0x0110, 0xd0ac, 0x1160, 0x9084, 0x1800, + 0x0904, 0x0c77, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, + 0x2646, 0x00a0, 0x7850, 0xc0e4, 0x7852, 0x2009, 0x180c, 0x210c, + 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906, 0x2011, 0x0048, + 0x080c, 0x2adc, 0x7828, 0x9085, 0x0028, 0x782a, 0x2001, 0x19a9, + 0x2003, 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, + 0x00fe, 0x004e, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, + 0x0036, 0x0046, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, + 0x0071, 0x0d0c, 0x8918, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x004e, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, + 0x2071, 0x189e, 0x7004, 0x9086, 0x0001, 0x1110, 0x080c, 0x359b, + 0x00ee, 0x0005, 0x0005, 0x2a70, 0x2061, 0x19ad, 0x2063, 0x0003, + 0x6007, 0x0003, 0x600b, 0x0012, 0x600f, 0x0137, 0x2001, 0x197d, + 0x900e, 0x2102, 0x7196, 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, + 0x0218, 0x705f, 0xffff, 0x0008, 0x715e, 0x7067, 0xffff, 0x717e, + 0x7182, 0x080c, 0xd0a1, 0x70ef, 0x00c0, 0x2061, 0x196d, 0x6003, + 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, + 0x6017, 0x001f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x1975, 0x6003, + 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6116, + 0x601b, 0x0001, 0x611e, 0x2061, 0x198a, 0x6003, 0x514c, 0x6007, + 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0x182c, 0x2102, + 0x0005, 0x9016, 0x080c, 0x6783, 0x1178, 0xb804, 0x90c4, 0x00ff, + 0x98c6, 0x0006, 0x0128, 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1120, + 0x9186, 0x0080, 0x0108, 0x8210, 0x8108, 0x9186, 0x0800, 0x1d50, + 0x2208, 0x0005, 0x2091, 0x8000, 0x2079, 0x0000, 0x000e, 0x00f6, + 0x0010, 0x2091, 0x8000, 0x0e04, 0x0d7b, 0x0006, 0x0016, 0x2001, + 0x8002, 0x0006, 0x2079, 0x0000, 0x000e, 0x7882, 0x7836, 0x001e, + 0x798e, 0x000e, 0x788a, 0x000e, 0x7886, 0x3900, 0x789a, 0x00d6, + 0x2069, 0x0300, 0x6818, 0x78ae, 0x681c, 0x78b2, 0x6808, 0x78be, + 0x00de, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6, 0x0036, + 0x0026, 0x2079, 0x0300, 0x2069, 0x1b2c, 0x7a08, 0x226a, 0x2069, + 0x1b2d, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a, 0x782c, 0x2019, + 0x1b3a, 0x201a, 0x2019, 0x1b3d, 0x9016, 0x7808, 0xd09c, 0x0168, + 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1b56, 0x0108, 0x0ca8, + 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019, 0x1b3b, 0x782c, + 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069, 0x1a82, 0x901e, + 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, + 0x0dd2, 0x2069, 0x1aa2, 0x2019, 0x0050, 0x20a9, 0x0020, 0x7b26, + 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0ddf, 0x0491, 0x002e, + 0x003e, 0x00de, 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a26, + 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, + 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x582f, + 0x1170, 0x080c, 0x0f26, 0x0110, 0x080c, 0x0e79, 0x080c, 0x582f, + 0x1130, 0x2071, 0x1800, 0x2011, 0x8000, 0x080c, 0x0f3a, 0x0c70, + 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, + 0x1120, 0x2001, 0x0015, 0x080c, 0xaae8, 0x2079, 0x0380, 0x2069, + 0x1b0c, 0x7818, 0x6802, 0x781c, 0x6806, 0x7840, 0x680a, 0x7844, + 0x680e, 0x782c, 0x6812, 0x2019, 0x1b17, 0x9016, 0x7808, 0xd09c, + 0x0150, 0x7820, 0x201a, 0x8210, 0x8318, 0x8210, 0x9282, 0x0011, + 0x0ea8, 0x2011, 0xdead, 0x6a2a, 0x7830, 0x681a, 0x7834, 0x681e, + 0x7838, 0x6822, 0x783c, 0x6826, 0x7803, 0x0000, 0x2069, 0x1acc, + 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68, 0x8318, + 0x1f04, 0x0e53, 0x2069, 0x1aec, 0x2019, 0x00b0, 0x20a9, 0x0020, + 0x7b26, 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04, 0x0e60, 0x0005, + 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600, 0x1118, + 0x918d, 0x6c00, 0x0010, 0x918d, 0x6400, 0x2001, 0x017f, 0x2102, + 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, 0x0f18, 0x20a9, + 0x0900, 0x080c, 0x0f4e, 0x2011, 0x0040, 0x080c, 0x0f18, 0x20a9, + 0x0900, 0x080c, 0x0f4e, 0x0c78, 0x0026, 0x080c, 0x0f26, 0x1188, + 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, + 0x2011, 0x0947, 0x0010, 0x2011, 0x1b47, 0x080c, 0x0f3a, 0x002e, + 0x0005, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, + 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840, 0xd0e4, 0x70f3, + 0x0000, 0x1120, 0x70f3, 0x0fa0, 0x080c, 0x0f2b, 0x002e, 0x0005, + 0x0026, 0x080c, 0x0f26, 0x0148, 0xd0a4, 0x1138, 0x2011, 0xcdd5, + 0x0010, 0x2011, 0x0080, 0x080c, 0x0f2b, 0x002e, 0x0005, 0x0026, + 0x70f3, 0x0000, 0x080c, 0x0f26, 0x1130, 0x2011, 0x8040, 0x080c, + 0x0f3a, 0x002e, 0x0005, 0x080c, 0x2a80, 0x1118, 0x2011, 0xcdc5, + 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f2b, 0x002e, 0x0005, 0x00e6, + 0x0016, 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70ec, 0x71e8, 0x1118, + 0xc0e4, 0xc1f4, 0x0050, 0x0006, 0x3b00, 0x9084, 0xff3e, 0x20d8, + 0x000e, 0x70f3, 0x0000, 0xc0e5, 0xc1f5, 0x0099, 0x000e, 0x001e, + 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4, 0x70ec, 0x1110, + 0xc0dc, 0x0008, 0xc0dd, 0x0016, 0x71e8, 0x0019, 0x001e, 0x00ee, + 0x0005, 0x70ee, 0x71ea, 0x7000, 0x9084, 0x0007, 0x000b, 0x0005, + 0x0ede, 0x0eb8, 0x0eb8, 0x0e8c, 0x0ec7, 0x0eb8, 0x0eb8, 0x0ec7, + 0xc284, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c1, 0x21d8, + 0x9084, 0xff3e, 0x9205, 0x20d0, 0x001e, 0x0005, 0x2001, 0x183b, + 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0d79, 0x70ec, + 0xd0e4, 0x0108, 0xc2e5, 0x72ee, 0xd0e4, 0x1118, 0x9294, 0x00c1, + 0x08f9, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0d79, 0x70e8, 0xd0f4, + 0x0108, 0xc2f5, 0x72ea, 0xd0f4, 0x1140, 0x9284, 0x8000, 0x8005, + 0xc284, 0x9215, 0x9294, 0x00c1, 0x0861, 0x0005, 0x1d04, 0x0f4e, + 0x2091, 0x6000, 0x1f04, 0x0f4e, 0x0005, 0x890e, 0x810e, 0x810f, + 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006, 0x2200, 0x914d, + 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6, 0x0146, 0x0036, + 0x0096, 0x2061, 0x188d, 0x600b, 0x0000, 0x600f, 0x0000, 0x6003, + 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105, 0x0006, 0x2001, + 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049, 0x0bff, 0xab02, + 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105, 0x9306, 0x0120, + 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f, 0x2001, 0x189d, + 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011, 0x0006, 0x1210, + 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff, 0x01b0, 0x8200, + 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007, 0x0000, 0x0026, + 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0, 0x21a8, 0x4104, + 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e, 0x003e, 0x014e, + 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016, 0x0026, 0x0096, + 0x3348, 0x080c, 0x0f55, 0x2100, 0x9300, 0x2098, 0x22e0, 0x009e, + 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001, 0x4002, 0x8007, + 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9, 0x0001, 0x71b8, + 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x9298, + 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9, 0x0002, 0x9298, + 0x0008, 0x23a0, 0x4001, 0x707c, 0x8007, 0x7180, 0x810f, 0x20a9, + 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e, 0x080c, 0x0d59, + 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001, 0x0005, 0x89ff, + 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x107f, 0x009e, + 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x10f8, 0x090c, + 0x0d79, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006, 0x0026, 0x0036, + 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800, 0x73c0, 0x702c, + 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c, 0x0d79, 0x2300, + 0x9202, 0x0120, 0x1a0c, 0x0d79, 0xa000, 0x0c98, 0x012e, 0x003e, + 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086, 0x00e6, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1910, 0x7010, 0x9005, 0x0140, + 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0d79, 0xa000, 0x0cc8, + 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6, 0x2071, 0x1800, + 0x0126, 0x2091, 0x8000, 0x70c0, 0x8001, 0x0270, 0x70c2, 0x702c, + 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, + 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, + 0x2091, 0x8000, 0x2071, 0x1800, 0x70c0, 0x90ca, 0x0020, 0x0268, + 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0xa803, 0x0000, + 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, + 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, 0x810f, 0x9184, + 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, 0x00e6, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, + 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x012e, 0x00ee, + 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, 0x2049, 0x0400, + 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, + 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, + 0x2071, 0x188d, 0x7000, 0x9005, 0x11a0, 0x2001, 0x0558, 0xa802, + 0x2048, 0x2009, 0x5600, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, + 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848, 0x9188, 0x0040, + 0x0c90, 0x2071, 0x188d, 0x7104, 0x7200, 0x82ff, 0x01d0, 0x7308, + 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319, 0x2001, 0x0800, + 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e, 0xaa62, 0x8420, + 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040, 0x9291, 0x0000, + 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74be, 0x74c2, 0x0005, + 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c, 0xf800, 0x1168, + 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278, 0x9982, 0x0558, + 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982, 0x0800, 0x0250, + 0x2071, 0x188d, 0x7010, 0x9902, 0x1228, 0x9085, 0x0001, 0x001e, + 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x1a25, 0x7007, + 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071, 0x0000, 0x7010, + 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006, 0x702b, 0x0060, + 0x20a9, 0x0040, 0x7022, 0x1f04, 0x1132, 0x702b, 0x0060, 0x702b, + 0x0020, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x113b, 0x702b, 0x0020, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, + 0x2071, 0x1a25, 0x701c, 0x9088, 0x1a2f, 0x280a, 0x8000, 0x9084, + 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0d79, 0x7004, 0x9005, + 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1a25, 0x7004, + 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, + 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, + 0x7000, 0x0002, 0x1184, 0x1307, 0x1182, 0x1182, 0x12fb, 0x12fb, + 0x12fb, 0x12fb, 0x080c, 0x0d79, 0x701c, 0x7120, 0x9106, 0x1148, + 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, + 0x0005, 0x0096, 0x9180, 0x1a2f, 0x2004, 0x700a, 0x2048, 0x8108, + 0x918c, 0x003f, 0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, + 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, + 0x7016, 0xa874, 0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, + 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, + 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, + 0x9006, 0x700e, 0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b, + 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, + 0x0156, 0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1, + 0x0088, 0x782b, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, + 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, + 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, + 0x013e, 0x002e, 0x001e, 0x0005, 0x2009, 0x1a25, 0x2104, 0xc095, + 0x200a, 0x080c, 0x1161, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1a25, + 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c, 0x0d72, 0x782b, + 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, + 0x00ee, 0x001e, 0x0005, 0x1172, 0x121a, 0x124e, 0x1326, 0x0d79, + 0x1341, 0x0d79, 0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156, + 0x7014, 0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, + 0x782b, 0x0040, 0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e, + 0x014e, 0x013e, 0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804, + 0x7806, 0x080c, 0x11b7, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, + 0x0100, 0x009e, 0x7007, 0x0000, 0x080c, 0x1172, 0x0005, 0x7008, + 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700, + 0x1150, 0x700c, 0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806, + 0x080c, 0x11cc, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, + 0x009e, 0x7007, 0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800, + 0xa88e, 0x7804, 0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f, + 0x0100, 0x009e, 0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048, + 0x2001, 0x18b9, 0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de, + 0x009e, 0x00a0, 0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048, + 0x0081, 0x0150, 0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de, + 0x009e, 0x080c, 0x1161, 0x0005, 0x00de, 0x009e, 0x080c, 0x1161, + 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, + 0x0d79, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4002, 0x080c, 0x6f05, 0xa09f, 0x0000, 0xa0a3, + 0x0000, 0x2848, 0x080c, 0x107f, 0x009e, 0x0005, 0x00a6, 0xa0a0, + 0x904d, 0x090c, 0x0d79, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, + 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, + 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, + 0x2810, 0x080c, 0x1142, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, + 0x080c, 0x6f05, 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, + 0x00c6, 0x2060, 0x080c, 0xaf4e, 0x00ce, 0x7008, 0x2048, 0xa89f, + 0x0000, 0xa8a3, 0x0000, 0x080c, 0x107f, 0x7007, 0x0000, 0x080c, + 0x1161, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, + 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, + 0x2001, 0x1930, 0x204c, 0xa87c, 0x7812, 0xa88c, 0x7802, 0xa890, + 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0x782b, 0x0020, 0x0126, + 0x2091, 0x8000, 0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, + 0x7002, 0x2900, 0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000, + 0x2099, 0x0088, 0x782b, 0x0040, 0x0096, 0x2001, 0x1930, 0x204c, + 0xaa7c, 0x009e, 0x080c, 0x8e1e, 0x2009, 0x188c, 0x2104, 0x9084, + 0xfffc, 0x200a, 0x080c, 0x8c80, 0x7007, 0x0000, 0x080c, 0x1172, + 0x0005, 0x7007, 0x0000, 0x080c, 0x1172, 0x0005, 0x0126, 0x2091, + 0x2200, 0x2079, 0x0300, 0x2071, 0x1a6f, 0x7003, 0x0000, 0x78bf, + 0x00f6, 0x0041, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, + 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x2001, 0x0165, 0x2003, + 0x4198, 0x7808, 0xd09c, 0x0120, 0x7820, 0x080c, 0x13aa, 0x0cc8, + 0x2001, 0x1a70, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, + 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0007, 0x7827, 0x0030, 0x782b, + 0x0400, 0x7827, 0x0031, 0x782b, 0x1a82, 0x78e3, 0xff00, 0x781f, + 0xff00, 0x781b, 0xff00, 0x2001, 0x1a71, 0x2003, 0x0000, 0x2001, + 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a82, + 0x602f, 0x1ddc, 0x2001, 0x181a, 0x2004, 0x9082, 0x1ddc, 0x6032, + 0x603b, 0x1ede, 0x602b, 0x1ac2, 0x6007, 0x1aa2, 0x2061, 0x1aa2, + 0x606f, 0x193e, 0x2001, 0x1929, 0x2004, 0x607a, 0x783f, 0x3474, + 0x00ce, 0x0005, 0x9086, 0x000d, 0x11d0, 0x7808, 0xd09c, 0x01b8, + 0x7820, 0x0026, 0x2010, 0x080c, 0xcc21, 0x0180, 0x2260, 0x6000, + 0x9086, 0x0004, 0x1158, 0x0016, 0x6120, 0x9186, 0x0009, 0x0108, + 0x0020, 0x2009, 0x004c, 0x080c, 0xafec, 0x001e, 0x002e, 0x0005, + 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c, 0x0d72, + 0xd19c, 0x05a0, 0x7820, 0x908c, 0xf000, 0x0540, 0x2060, 0x6020, + 0x9086, 0x0003, 0x1550, 0x6000, 0x9086, 0x0004, 0x1530, 0x6114, + 0x2148, 0xa876, 0xa87a, 0xa867, 0x0103, 0x080c, 0x6d26, 0x00b6, + 0x6010, 0x2058, 0xba3c, 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, + 0x190c, 0x68ae, 0x00be, 0x6044, 0xd0fc, 0x190c, 0xab20, 0x080c, + 0xaf77, 0x7808, 0xd09c, 0x19b0, 0x012e, 0x0005, 0x908a, 0x0024, + 0x1a0c, 0x0d79, 0x002b, 0x012e, 0x0005, 0x04b0, 0x012e, 0x0005, + 0x142c, 0x1452, 0x1482, 0x1487, 0x148b, 0x1490, 0x14b8, 0x14bc, + 0x14ca, 0x14ce, 0x142c, 0x159b, 0x159f, 0x1611, 0x1618, 0x142c, + 0x1619, 0x161a, 0x1625, 0x162c, 0x142c, 0x142c, 0x142c, 0x142c, + 0x142c, 0x142c, 0x142c, 0x1492, 0x142c, 0x145a, 0x147f, 0x1446, + 0x142c, 0x1466, 0x1430, 0x142e, 0x080c, 0x0d79, 0x080c, 0x0d72, + 0x080c, 0x1637, 0x2009, 0x1a7e, 0x2104, 0x8000, 0x200a, 0x080c, + 0x8151, 0x080c, 0x1b3b, 0x0005, 0x6044, 0xd0fc, 0x190c, 0xab20, + 0x2009, 0x0055, 0x080c, 0xafec, 0x012e, 0x0005, 0x080c, 0x1637, + 0x2060, 0x6044, 0xd0fc, 0x190c, 0xab20, 0x2009, 0x0055, 0x080c, + 0xafec, 0x0005, 0x2009, 0x0048, 0x080c, 0x1637, 0x2060, 0x080c, + 0xafec, 0x0005, 0x2009, 0x0054, 0x080c, 0x1637, 0x2060, 0x6044, + 0xd0fc, 0x190c, 0xab20, 0x080c, 0xafec, 0x0005, 0x080c, 0x1637, + 0x2060, 0x0056, 0x0066, 0x080c, 0x1637, 0x2028, 0x080c, 0x1637, + 0x2030, 0x0036, 0x0046, 0x2021, 0x0000, 0x2418, 0x2009, 0x0056, + 0x080c, 0xafec, 0x004e, 0x003e, 0x006e, 0x005e, 0x0005, 0x080c, + 0x1637, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004, + 0xc085, 0x7006, 0x0005, 0x080c, 0x1637, 0x080c, 0x1734, 0x0005, + 0x080c, 0x0d79, 0x080c, 0x1637, 0x2060, 0x6014, 0x0096, 0x2048, + 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xafec, 0x2001, + 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001, + 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, + 0x1110, 0x080c, 0x163c, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005, + 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1637, 0x2060, 0x6014, + 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, + 0xafec, 0x0005, 0x080c, 0x1637, 0x080c, 0x0d79, 0x080c, 0x1637, + 0x080c, 0x1586, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0904, 0x1537, + 0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0140, 0x2001, + 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x153d, 0x7004, + 0x9005, 0x01c8, 0x1188, 0x78ab, 0x0004, 0x7827, 0x0018, 0x782b, + 0x0000, 0xd1bc, 0x090c, 0x0d79, 0x2001, 0x020d, 0x2003, 0x0050, + 0x2003, 0x0020, 0x0804, 0x156b, 0x78ab, 0x0004, 0x7803, 0x0001, + 0x080c, 0x159f, 0x0005, 0x7827, 0x0018, 0xa001, 0x7828, 0x7827, + 0x0011, 0xa001, 0x7928, 0x9106, 0x0110, 0x79ac, 0x08e0, 0x00e6, + 0x2071, 0x0200, 0x702c, 0xd0c4, 0x0140, 0x00ee, 0x080c, 0x1b3b, + 0x080c, 0x135a, 0x7803, 0x0001, 0x0005, 0x7037, 0x0001, 0xa001, + 0x7150, 0x00ee, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, 0x79ac, + 0x0810, 0x7004, 0xc09d, 0x7006, 0x78ab, 0x0004, 0x7803, 0x0001, + 0x080c, 0x159f, 0x2001, 0x020d, 0x2003, 0x0020, 0x0005, 0x7828, + 0x782b, 0x0000, 0x9065, 0x090c, 0x0d79, 0x6014, 0x2048, 0x78ab, + 0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x8151, 0x080c, 0x1b3b, + 0x080c, 0xcc33, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f, + 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c, 0xc81b, + 0x0005, 0x6020, 0x9086, 0x0009, 0x1128, 0x2009, 0x004c, 0x080c, + 0xafec, 0x0048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x6024, 0x190c, 0xd036, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001, + 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xebc0, 0xd5a4, + 0x1118, 0x080c, 0x163c, 0x0005, 0x080c, 0x8151, 0x080c, 0x1b3b, + 0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066, + 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186, + 0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x16ad, 0x00fe, 0x007e, + 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104, + 0x9184, 0x0004, 0x190c, 0x0d79, 0xd184, 0x11b1, 0xd19c, 0x0180, + 0xc19c, 0x7106, 0x0016, 0x080c, 0x1717, 0x001e, 0x0148, 0x2001, + 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x080c, 0x163c, 0x0005, + 0x81ff, 0x190c, 0x0d79, 0x0005, 0x2100, 0xc184, 0xc1b4, 0x7106, + 0xd0b4, 0x0016, 0x00e6, 0x1904, 0x1606, 0x2071, 0x0200, 0x080c, + 0x1704, 0x05e0, 0x080c, 0x1717, 0x05b0, 0x6014, 0x9005, 0x05b0, + 0x0096, 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, + 0x0160, 0x908e, 0x0048, 0x1550, 0x601c, 0xd084, 0x11e0, 0x00f6, + 0x2c78, 0x080c, 0x17a1, 0x00fe, 0x00b0, 0x00f6, 0x2c78, 0x080c, + 0x192a, 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0168, 0x2001, 0x0201, + 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1118, + 0x080c, 0x163c, 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c, + 0x135a, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x1717, + 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0461, + 0x0c90, 0x0429, 0x2060, 0x2009, 0x0053, 0x080c, 0xafec, 0x0005, + 0x0005, 0x0005, 0x00e1, 0x2008, 0x00d1, 0x0006, 0x7004, 0xc09d, + 0x7006, 0x000e, 0x080c, 0x916f, 0x0005, 0x0089, 0x9005, 0x0118, + 0x080c, 0x8d72, 0x0cd0, 0x0005, 0x2001, 0x0036, 0x2009, 0x1820, + 0x210c, 0x2011, 0x181f, 0x2214, 0x080c, 0x16ad, 0x0005, 0x7808, + 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c, 0x1586, 0x00d6, 0x2069, + 0x0200, 0x2009, 0x01f4, 0x8109, 0x0510, 0x6804, 0x9005, 0x0dd8, + 0x2001, 0x015d, 0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1528, 0x79b8, + 0x918c, 0x0fff, 0x0180, 0x9182, 0x0841, 0x1268, 0x9188, 0x0007, + 0x918c, 0x0ff8, 0x810c, 0x810c, 0x810c, 0x080c, 0x169f, 0x6827, + 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, + 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, + 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c, 0x8151, 0x080c, 0x1b3b, + 0x0090, 0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b, + 0x0000, 0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, + 0x0300, 0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, + 0x9086, 0x5400, 0x0d30, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803, + 0x0001, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824, + 0x9084, 0x0003, 0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c, + 0x0021, 0x7830, 0x9086, 0x0041, 0x0005, 0x00f6, 0x00e6, 0x2079, + 0x0300, 0x0006, 0x2071, 0x1a6f, 0x7008, 0x9005, 0x1110, 0x78e3, + 0x0c0c, 0x8000, 0x700a, 0x0026, 0x2011, 0x0006, 0x7808, 0xd09c, + 0x0150, 0x0016, 0x0026, 0x00c6, 0x080c, 0x13c8, 0x00ce, 0x002e, + 0x001e, 0x8211, 0x1d98, 0x002e, 0x000e, 0x0006, 0x7832, 0x7936, + 0x7a3a, 0x781b, 0x8080, 0x00b9, 0x1178, 0x2071, 0x1a6f, 0x7008, + 0x9005, 0x0130, 0x8001, 0x0a0c, 0x0d79, 0x700a, 0x78e3, 0x0c00, + 0x000e, 0x00ee, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000, + 0x2004, 0x080c, 0x0d79, 0x2009, 0xff00, 0x8109, 0x0120, 0x7818, + 0xd0bc, 0x1dd8, 0x0005, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, + 0x7a3a, 0x781b, 0x8080, 0x0c79, 0x1108, 0x0005, 0x792c, 0x3900, + 0x8000, 0x2004, 0x080c, 0x0d79, 0x7037, 0x0001, 0x7150, 0x7037, + 0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x918c, + 0xff00, 0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006, + 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, + 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a7f, 0x2404, + 0x8000, 0x0208, 0x2022, 0x080c, 0x8151, 0x080c, 0x1b3b, 0x9006, + 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, + 0x0016, 0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c, + 0xd08c, 0x0904, 0x1796, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, + 0xd0bc, 0x0904, 0x1796, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, + 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x1796, 0x9c06, 0x15f0, + 0x0126, 0x2091, 0x2600, 0x080c, 0x80a9, 0x012e, 0x7358, 0x745c, + 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x190c, 0xd011, 0xab42, 0xac3e, 0x2001, 0x1869, + 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, + 0xffff, 0x080c, 0x1efe, 0x1190, 0x080c, 0x1987, 0x2a00, 0xa816, + 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, + 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, + 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x163c, 0x0005, 0x080c, + 0x0d79, 0x2cf0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, + 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, + 0x9d84, 0x000f, 0x9088, 0x1ede, 0x2165, 0x0002, 0x17cd, 0x183b, + 0x17cd, 0x17cd, 0x17d1, 0x181c, 0x17cd, 0x17f1, 0x17c6, 0x1832, + 0x17cd, 0x17cd, 0x17d6, 0x1928, 0x1805, 0x17fb, 0xa964, 0x918c, + 0x00ff, 0x918e, 0x0048, 0x0904, 0x1832, 0x9085, 0x0001, 0x0804, + 0x191e, 0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1842, 0xa87c, 0xd0ac, + 0x0da0, 0x0804, 0x18ad, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, + 0xaab2, 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, + 0x933f, 0x2005, 0x9005, 0x090c, 0x0d79, 0x2004, 0xa8ae, 0x0804, + 0x1906, 0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, + 0xa888, 0x0804, 0x1842, 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, + 0xa88c, 0xa83e, 0xa888, 0x0804, 0x18ad, 0xa87c, 0xd0bc, 0x0928, + 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0d79, + 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ede, 0x2065, 0xa888, + 0xd19c, 0x1904, 0x18ad, 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x17cd, + 0xa804, 0x9045, 0x090c, 0x0d79, 0xa164, 0xa91a, 0x91ec, 0x000f, + 0x9d80, 0x1ede, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, + 0x18ad, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x17cd, 0x9006, 0xa842, + 0xa83e, 0x0804, 0x18ad, 0xa87c, 0xd0ac, 0x0904, 0x17cd, 0x9006, + 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d79, 0x9082, + 0x001b, 0x0002, 0x1865, 0x1865, 0x1867, 0x1865, 0x1865, 0x1865, + 0x1871, 0x1865, 0x1865, 0x1865, 0x187b, 0x1865, 0x1865, 0x1865, + 0x1885, 0x1865, 0x1865, 0x1865, 0x188f, 0x1865, 0x1865, 0x1865, + 0x1899, 0x1865, 0x1865, 0x1865, 0x18a3, 0x080c, 0x0d79, 0xa574, + 0xa478, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa37c, 0xa280, 0x0804, + 0x1906, 0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa38c, + 0xa290, 0x0804, 0x1906, 0xa594, 0xa498, 0x9d86, 0x0024, 0x0904, + 0x17db, 0xa39c, 0xa2a0, 0x0804, 0x1906, 0xa5a4, 0xa4a8, 0x9d86, + 0x0024, 0x0904, 0x17db, 0xa3ac, 0xa2b0, 0x0804, 0x1906, 0xa5b4, + 0xa4b8, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa3bc, 0xa2c0, 0x0804, + 0x1906, 0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa3cc, + 0xa2d0, 0x0804, 0x1906, 0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904, + 0x17db, 0xa3dc, 0xa2e0, 0x0804, 0x1906, 0x2c05, 0x908a, 0x0034, + 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x18d0, 0x18ce, 0x18ce, + 0x18ce, 0x18ce, 0x18ce, 0x18db, 0x18ce, 0x18ce, 0x18ce, 0x18ce, + 0x18ce, 0x18e6, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18f1, + 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18fc, 0x080c, 0x0d79, + 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, 0x0904, 0x17db, + 0xa37c, 0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, + 0x002c, 0x0904, 0x17db, 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, + 0xa7a4, 0xa6a8, 0x9d86, 0x002c, 0x0904, 0x17db, 0xa3ac, 0xa2b0, + 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904, + 0x17db, 0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, + 0x9d86, 0x002c, 0x0904, 0x17db, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, + 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, + 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, + 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, + 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, + 0x0804, 0x17cd, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, + 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1ed9, 0xa813, + 0x1ed9, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, + 0x0d79, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, + 0x0d79, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, - 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0d85, - 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1ec1, 0x2015, - 0x82ff, 0x090c, 0x0d85, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, - 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1a94, 0x19f6, - 0x19f6, 0x1a94, 0x1a94, 0x1a8e, 0x1a94, 0x19f6, 0x1a45, 0x1a45, - 0x1a45, 0x1a94, 0x1a94, 0x1a94, 0x1a8b, 0x1a45, 0xc0fc, 0xa882, - 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1a96, 0x2c05, - 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x19e2, - 0x19e0, 0x19e0, 0x19e0, 0x19e0, 0x19e0, 0x19e6, 0x19e0, 0x19e0, - 0x19e0, 0x19e0, 0x19e0, 0x19ea, 0x19e0, 0x19e0, 0x19e0, 0x19e0, - 0x19e0, 0x19ee, 0x19e0, 0x19e0, 0x19e0, 0x19e0, 0x19e0, 0x19f2, - 0x080c, 0x0d85, 0xa774, 0xa678, 0x0804, 0x1a96, 0xa78c, 0xa690, - 0x0804, 0x1a96, 0xa7a4, 0xa6a8, 0x0804, 0x1a96, 0xa7bc, 0xa6c0, - 0x0804, 0x1a96, 0xa7d4, 0xa6d8, 0x0804, 0x1a96, 0x2c05, 0x908a, - 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a19, 0x1a19, - 0x1a1b, 0x1a19, 0x1a19, 0x1a19, 0x1a21, 0x1a19, 0x1a19, 0x1a19, - 0x1a27, 0x1a19, 0x1a19, 0x1a19, 0x1a2d, 0x1a19, 0x1a19, 0x1a19, - 0x1a33, 0x1a19, 0x1a19, 0x1a19, 0x1a39, 0x1a19, 0x1a19, 0x1a19, - 0x1a3f, 0x080c, 0x0d85, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, - 0x1a96, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x1a96, 0xa594, - 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1a96, 0xa5a4, 0xa4a8, 0xa3ac, - 0xa2b0, 0x0804, 0x1a96, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, - 0x1a96, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x1a96, 0xa5d4, - 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1a96, 0x2c05, 0x908a, 0x0034, - 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a68, 0x1a66, 0x1a66, - 0x1a66, 0x1a66, 0x1a66, 0x1a6f, 0x1a66, 0x1a66, 0x1a66, 0x1a66, - 0x1a66, 0x1a76, 0x1a66, 0x1a66, 0x1a66, 0x1a66, 0x1a66, 0x1a7d, - 0x1a66, 0x1a66, 0x1a66, 0x1a66, 0x1a66, 0x1a84, 0x080c, 0x0d85, - 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x0438, 0xa584, - 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, - 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x00c8, 0xa5b4, 0xa4b8, 0xa7bc, - 0xa6c0, 0xa3c4, 0xa2c8, 0x0090, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, - 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c, 0x1e97, - 0x1904, 0x199f, 0x900e, 0x0050, 0x080c, 0x0d85, 0xab2e, 0xaa32, - 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x1e97, 0x0005, 0x6014, - 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, - 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, - 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, - 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xb20a, 0x0005, 0xa974, - 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, - 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009, 0x0048, - 0x0804, 0xb20a, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, - 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, - 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, - 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x13d4, 0x8631, - 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, - 0xd09c, 0x190c, 0x13d4, 0x00ce, 0x2001, 0x0038, 0x080c, 0x1bae, - 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c, 0x0d85, - 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c, 0x1bbd, - 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1baa, 0x7827, 0x0015, - 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, - 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x2001, 0xf000, 0x8001, - 0x090c, 0x0d85, 0x7aac, 0xd2ac, 0x1dd0, 0x00fe, 0x080c, 0x779e, - 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, - 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, - 0x0804, 0x7840, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, - 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c, 0x2a8b, - 0x2009, 0x003c, 0x080c, 0x2220, 0x2001, 0x015d, 0x2003, 0x0000, - 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x8899, 0x70a0, 0x70a2, - 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, - 0x00f6, 0x2079, 0x0300, 0x080c, 0x1366, 0x7803, 0x0001, 0x00fe, - 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, - 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x779e, 0x1108, 0x0005, - 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, - 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, - 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, - 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001, 0xa001, - 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, - 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, - 0x080c, 0x16b9, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c, 0x1702, - 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, - 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, - 0x0904, 0x1c1b, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, - 0x0d85, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, - 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, - 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, - 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, - 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1bb4, 0x9186, - 0x0040, 0x190c, 0x0d85, 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, - 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, - 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, - 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0d85, 0xa001, - 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400, 0x2079, - 0x0380, 0x2001, 0x19e8, 0x2070, 0x012e, 0x0005, 0x2cf0, 0x0126, - 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa964, 0xa91a, 0x918c, - 0x00ff, 0x9184, 0x000f, 0x0002, 0x1c50, 0x1c50, 0x1c50, 0x1c52, - 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c44, 0x1c5a, 0x1c50, 0x1c56, - 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x9086, 0x0008, 0x1148, 0xa87c, - 0xd0b4, 0x0904, 0x1dca, 0x2011, 0x1ebc, 0x2205, 0xab88, 0x00a8, - 0x080c, 0x0d85, 0x9186, 0x0013, 0x0128, 0x0cd0, 0x9186, 0x001b, - 0x0108, 0x0cb0, 0xa87c, 0xd0b4, 0x0904, 0x1dca, 0x9184, 0x000f, - 0x9080, 0x1ec1, 0x2015, 0x2205, 0xab88, 0x2908, 0xa80a, 0xa90e, - 0xaa12, 0xab16, 0x9006, 0xa842, 0xa83e, 0x012e, 0x0005, 0x2cf0, - 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa88c, 0xa990, - 0xaaac, 0xabb0, 0xaa36, 0xab3a, 0xa83e, 0xa942, 0xa846, 0xa94a, - 0xa964, 0x918c, 0x00ff, 0x9186, 0x001e, 0x0198, 0x2940, 0xa064, - 0xa81a, 0x90ec, 0x000f, 0x9d80, 0x1ec1, 0x2065, 0x2c05, 0x2808, - 0x2c10, 0xab88, 0xa80a, 0xa90e, 0xaa12, 0xab16, 0x012e, 0x3e60, - 0x0005, 0xa804, 0x2040, 0x0c58, 0x2cf0, 0x0126, 0x2091, 0x2400, - 0x3e60, 0x6014, 0x2048, 0xa97c, 0x2950, 0xd1dc, 0x1904, 0x1d94, - 0xc1dd, 0xa97e, 0x9006, 0xa842, 0xa83e, 0xa988, 0x8109, 0xa916, - 0xa964, 0xa91a, 0x9184, 0x000f, 0x9088, 0x1ec1, 0x2145, 0x0002, - 0x1cc8, 0x1cd6, 0x1cc8, 0x1cc8, 0x1cc8, 0x1cca, 0x1cc8, 0x1cc8, - 0x1d2b, 0x1d2b, 0x1cc8, 0x1cc8, 0x1cc8, 0x1d29, 0x1cc8, 0x1cc8, - 0x080c, 0x0d85, 0xa804, 0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, - 0x9080, 0x1ec1, 0x2045, 0xd19c, 0x1904, 0x1d2b, 0x9036, 0x2638, - 0x2805, 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, - 0x1cfb, 0x1cfb, 0x1cfd, 0x1cfb, 0x1cfb, 0x1cfb, 0x1d03, 0x1cfb, - 0x1cfb, 0x1cfb, 0x1d09, 0x1cfb, 0x1cfb, 0x1cfb, 0x1d0f, 0x1cfb, - 0x1cfb, 0x1cfb, 0x1d15, 0x1cfb, 0x1cfb, 0x1cfb, 0x1d1b, 0x1cfb, - 0x1cfb, 0x1cfb, 0x1d21, 0x080c, 0x0d85, 0xb574, 0xb478, 0xb37c, - 0xb280, 0x0804, 0x1d70, 0xb584, 0xb488, 0xb38c, 0xb290, 0x0804, - 0x1d70, 0xb594, 0xb498, 0xb39c, 0xb2a0, 0x0804, 0x1d70, 0xb5a4, - 0xb4a8, 0xb3ac, 0xb2b0, 0x0804, 0x1d70, 0xb5b4, 0xb4b8, 0xb3bc, - 0xb2c0, 0x0804, 0x1d70, 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0, 0x0804, - 0x1d70, 0xb5d4, 0xb4d8, 0xb3dc, 0xb2e0, 0x0804, 0x1d70, 0x0804, - 0x1d70, 0x080c, 0x0d85, 0x2805, 0x908a, 0x0034, 0x1a0c, 0x0d85, - 0x9082, 0x001b, 0x0002, 0x1d4e, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, - 0x1d4c, 0x1d55, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d5c, - 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d63, 0x1d4c, 0x1d4c, - 0x1d4c, 0x1d4c, 0x1d4c, 0x1d6a, 0x080c, 0x0d85, 0xb56c, 0xb470, - 0xb774, 0xb678, 0xb37c, 0xb280, 0x00d8, 0xb584, 0xb488, 0xb78c, - 0xb690, 0xb394, 0xb298, 0x00a0, 0xb59c, 0xb4a0, 0xb7a4, 0xb6a8, - 0xb3ac, 0xb2b0, 0x0068, 0xb5b4, 0xb4b8, 0xb7bc, 0xb6c0, 0xb3c4, - 0xb2c8, 0x0030, 0xb5cc, 0xb4d0, 0xb7d4, 0xb6d8, 0xb3dc, 0xb2e0, - 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8109, - 0xa916, 0x1118, 0x9006, 0x012e, 0x0005, 0x8840, 0x2805, 0x9005, - 0x1168, 0xb004, 0x9005, 0x090c, 0x0d85, 0x2050, 0xb164, 0xa91a, - 0x9184, 0x000f, 0x9080, 0x1ec1, 0x2045, 0x2805, 0x2810, 0x2a08, - 0xa80a, 0xa90e, 0xaa12, 0x0c30, 0x3e60, 0x6344, 0xd3fc, 0x190c, - 0x0d85, 0xa93c, 0xaa40, 0xa844, 0x9106, 0x1118, 0xa848, 0x9206, - 0x0508, 0x2958, 0xab48, 0xac44, 0x2940, 0x080c, 0x1ee1, 0x1998, - 0x2850, 0x2c40, 0xab14, 0xa880, 0xd0fc, 0x1140, 0xa810, 0x2005, - 0xa80a, 0x2a00, 0xa80e, 0x2009, 0x8015, 0x0070, 0x00c6, 0x3e60, - 0x6044, 0xc0a4, 0x9085, 0x8005, 0x6046, 0x00ce, 0x8319, 0xab16, - 0x1904, 0x1d7d, 0x2009, 0x8005, 0x3e60, 0x6044, 0x9105, 0x6046, - 0x0804, 0x1d7a, 0x080c, 0x0d85, 0x00f6, 0x00e6, 0x0096, 0x00c6, - 0x0026, 0x704c, 0x9c06, 0x190c, 0x0d85, 0x2079, 0x0090, 0x2001, - 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7057, 0x0000, 0x6014, - 0x2048, 0x080c, 0xcf1b, 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, - 0x9086, 0x0006, 0x1170, 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, - 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, - 0xa896, 0x704c, 0x2060, 0x00c6, 0x080c, 0xcae9, 0x080c, 0xacfc, - 0x00ce, 0x704c, 0x9c06, 0x1150, 0x2009, 0x0040, 0x080c, 0x2220, - 0x080c, 0xa7a1, 0x2011, 0x0000, 0x080c, 0xa635, 0x002e, 0x00ce, - 0x009e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0090, 0x781c, - 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, - 0x9085, 0x0012, 0x7816, 0x2019, 0x1000, 0x8319, 0x090c, 0x0d85, - 0x7820, 0xd0bc, 0x1dd0, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, - 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, - 0x1984, 0x9085, 0x0012, 0x7816, 0x2079, 0x0090, 0x782b, 0x0008, - 0x7057, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x19e8, - 0x7054, 0x9086, 0x0000, 0x0904, 0x1e92, 0x2079, 0x0090, 0x2009, - 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, - 0x0003, 0x0188, 0x080c, 0xeefa, 0x2001, 0x0133, 0x2004, 0x9005, - 0x090c, 0x0d85, 0x0016, 0x2009, 0x0040, 0x080c, 0x2220, 0x001e, - 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, - 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2220, 0x782c, - 0xd0fc, 0x09a8, 0x080c, 0xad18, 0x782c, 0xd0fc, 0x1de8, 0x080c, - 0xacfc, 0x7054, 0x9086, 0x0000, 0x1950, 0x782b, 0x0004, 0x782c, - 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2220, 0x782b, 0x0002, - 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x080c, 0x0d85, 0x8c60, - 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, - 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ec1, 0x2065, - 0x8cff, 0x090c, 0x0d85, 0x8a51, 0x0005, 0x2050, 0x0005, 0x0000, - 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, - 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, - 0x0000, 0x0000, 0x1eb4, 0x1eb0, 0x1eb4, 0x1eb4, 0x1ebe, 0x0000, - 0x1eb4, 0x1ebb, 0x1ebb, 0x1eb8, 0x1ebb, 0x1ebb, 0x0000, 0x1ebe, - 0x1ebb, 0x0000, 0x1eb6, 0x1eb6, 0x0000, 0x1eb6, 0x1ebe, 0x0000, - 0x1eb6, 0x1ebc, 0x1ebc, 0x1ebc, 0x0000, 0x1ebc, 0x0000, 0x1ebe, - 0x1ebc, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, - 0x0904, 0x20c0, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, - 0x9086, 0x0008, 0x1118, 0x2061, 0x1ebc, 0x00d0, 0x9de0, 0x1ec1, - 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, - 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, - 0x0310, 0x0804, 0x20c0, 0xa004, 0x9045, 0x0904, 0x20c0, 0x08d8, - 0x2c05, 0x9005, 0x0904, 0x1fa8, 0xdd9c, 0x1904, 0x1f64, 0x908a, - 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1f39, 0x1f39, - 0x1f3b, 0x1f39, 0x1f39, 0x1f39, 0x1f41, 0x1f39, 0x1f39, 0x1f39, - 0x1f47, 0x1f39, 0x1f39, 0x1f39, 0x1f4d, 0x1f39, 0x1f39, 0x1f39, - 0x1f53, 0x1f39, 0x1f39, 0x1f39, 0x1f59, 0x1f39, 0x1f39, 0x1f39, - 0x1f5f, 0x080c, 0x0d85, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, - 0x1f9e, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1f9e, 0xa09c, - 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1f9e, 0xa0ac, 0x9422, 0xa0b0, - 0x931b, 0x0804, 0x1f9e, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, - 0x1f9e, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1f9e, 0xa0dc, - 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0d85, - 0x9082, 0x001b, 0x0002, 0x1f86, 0x1f84, 0x1f84, 0x1f84, 0x1f84, - 0x1f84, 0x1f8b, 0x1f84, 0x1f84, 0x1f84, 0x1f84, 0x1f84, 0x1f90, - 0x1f84, 0x1f84, 0x1f84, 0x1f84, 0x1f84, 0x1f95, 0x1f84, 0x1f84, - 0x1f84, 0x1f84, 0x1f84, 0x1f9a, 0x080c, 0x0d85, 0xa07c, 0x9422, - 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, - 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, - 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, - 0x9405, 0x0160, 0x8a51, 0x0904, 0x20c0, 0x8c60, 0x0804, 0x1f10, - 0xa004, 0x9045, 0x0904, 0x20c0, 0x0804, 0x1eeb, 0x8a51, 0x0904, - 0x20c0, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, - 0x20c0, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1ec1, 0x2c05, 0x2060, - 0xa880, 0xc0fc, 0xa882, 0x0804, 0x20b5, 0x2c05, 0x8422, 0x8420, - 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2052, - 0x9082, 0x001b, 0x0002, 0x1fee, 0x1fee, 0x1ff0, 0x1fee, 0x1fee, - 0x1fee, 0x1ffe, 0x1fee, 0x1fee, 0x1fee, 0x200c, 0x1fee, 0x1fee, - 0x1fee, 0x201a, 0x1fee, 0x1fee, 0x1fee, 0x2028, 0x1fee, 0x1fee, - 0x1fee, 0x2036, 0x1fee, 0x1fee, 0x1fee, 0x2044, 0x080c, 0x0d85, - 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d85, - 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x20b0, 0xa18c, 0x2400, - 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084, 0x9420, - 0xa088, 0x9319, 0x0804, 0x20b0, 0xa19c, 0x2400, 0x9122, 0xa1a0, - 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa094, 0x9420, 0xa098, 0x9319, - 0x0804, 0x20b0, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, - 0x0a0c, 0x0d85, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x20b0, - 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0d85, - 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x20b0, 0xa1cc, 0x2400, - 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0c4, 0x9420, - 0xa0c8, 0x9319, 0x0804, 0x20b0, 0xa1dc, 0x2400, 0x9122, 0xa1e0, - 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0d4, 0x9420, 0xa0d8, 0x9319, - 0x0804, 0x20b0, 0x9082, 0x001b, 0x0002, 0x2070, 0x206e, 0x206e, - 0x206e, 0x206e, 0x206e, 0x207d, 0x206e, 0x206e, 0x206e, 0x206e, - 0x206e, 0x208a, 0x206e, 0x206e, 0x206e, 0x206e, 0x206e, 0x2097, - 0x206e, 0x206e, 0x206e, 0x206e, 0x206e, 0x20a4, 0x080c, 0x0d85, - 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d85, - 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, - 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084, 0x9420, 0xa088, - 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, - 0x0a0c, 0x0d85, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, - 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0b4, - 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, - 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0cc, 0x9420, 0xa0d0, 0x9319, - 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, - 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, - 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x00c6, 0x610c, - 0x0016, 0x9026, 0x2410, 0x6004, 0x9420, 0x9291, 0x0000, 0x2c04, - 0x9210, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1da8, 0x9284, 0x000f, - 0x9405, 0x001e, 0x00ce, 0x0005, 0x7803, 0x0003, 0x780f, 0x0000, - 0x6004, 0x7812, 0x2c04, 0x7816, 0x9ce0, 0x0002, 0x918a, 0x0002, - 0x1db8, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c, 0x0d7e, - 0xd094, 0x0110, 0x080c, 0x1208, 0x0005, 0x0126, 0x2091, 0x2600, - 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, - 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, - 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, - 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600, 0x781c, 0xd0a4, - 0x190c, 0x221d, 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, - 0x9084, 0x000e, 0x0002, 0x213b, 0x2133, 0x8210, 0x2133, 0x2135, - 0x2135, 0x2135, 0x2135, 0x81f6, 0x2133, 0x2137, 0x2133, 0x2135, - 0x2133, 0x2135, 0x2133, 0x080c, 0x0d85, 0x0031, 0x0020, 0x080c, - 0x81f6, 0x080c, 0x8210, 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, - 0xeefa, 0x7930, 0x9184, 0x0003, 0x0510, 0x080c, 0xacfc, 0x2001, - 0x19fb, 0x2004, 0x9005, 0x01a0, 0x2001, 0x0133, 0x2004, 0x9005, - 0x090c, 0x0d85, 0x00c6, 0x2001, 0x19fb, 0x2064, 0x080c, 0xad18, - 0x080c, 0xcae9, 0x2009, 0x0040, 0x080c, 0x2220, 0x00ce, 0x0408, - 0x2009, 0x0040, 0x080c, 0x2220, 0x080c, 0xad18, 0x00d0, 0x9184, - 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, 0x779e, - 0x1138, 0x080c, 0x7ab6, 0x080c, 0x619d, 0x080c, 0x76cd, 0x0010, - 0x080c, 0x6058, 0x080c, 0x82ae, 0x0041, 0x0018, 0x9184, 0x9540, - 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, - 0x0056, 0x2071, 0x1a6e, 0x080c, 0x1b1e, 0x005e, 0x004e, 0x003e, - 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128, - 0x2001, 0x196f, 0x2102, 0x2001, 0x1977, 0x2102, 0x2001, 0x013b, - 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200, - 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, 0x2320, - 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, 0x8423, - 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, 0x8003, - 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011, - 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c, - 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, 0x9182, - 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, 0x9182, - 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, 0x2011, - 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, 0x9402, - 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, 0x012e, - 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0, - 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200, - 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de, - 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8, - 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, 0x0d7e, - 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, - 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, - 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, - 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2a85, 0x080c, 0x299b, - 0x2001, 0x199d, 0x2003, 0x0700, 0x2001, 0x199e, 0x2003, 0x0700, - 0x080c, 0x2af6, 0x9006, 0x080c, 0x29ca, 0x9006, 0x080c, 0x29ad, - 0x20a9, 0x0012, 0x1d04, 0x2252, 0x2091, 0x6000, 0x1f04, 0x2252, - 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, - 0xdfff, 0x6052, 0x6224, 0x080c, 0x2ad3, 0x080c, 0x26c5, 0x2009, - 0x00ef, 0x6132, 0x6136, 0x080c, 0x26d5, 0x60e7, 0x0000, 0x61ea, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1110, 0x2001, - 0x0008, 0x60e2, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, - 0x602f, 0x0000, 0x6007, 0x349f, 0x00c6, 0x2061, 0x0140, 0x608b, - 0x000b, 0x608f, 0x10b8, 0x6093, 0x0000, 0x6097, 0x0198, 0x00ce, - 0x6004, 0x9085, 0x8000, 0x6006, 0x60bb, 0x0000, 0x20a9, 0x0018, - 0x60bf, 0x0000, 0x1f04, 0x2298, 0x60bb, 0x0000, 0x60bf, 0x0108, - 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, - 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, - 0x602b, 0x402c, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, - 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, - 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001, 0x0005, - 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x6028, - 0x910c, 0x0066, 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, - 0x1138, 0x6020, 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, - 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, - 0x9284, 0x0007, 0x0082, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4, - 0x001e, 0x0d70, 0x0c98, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1b4, - 0x001e, 0x0d30, 0x0c58, 0x2306, 0x2303, 0x2303, 0x2303, 0x2305, - 0x2303, 0x2303, 0x2303, 0x080c, 0x0d85, 0x0029, 0x002e, 0x001e, - 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, - 0xd19c, 0x1904, 0x258b, 0xd1f4, 0x190c, 0x0d7e, 0x080c, 0x779e, - 0x0904, 0x2363, 0x080c, 0xd645, 0x1120, 0x7000, 0x9086, 0x0003, - 0x0580, 0x6024, 0x9084, 0x1800, 0x0560, 0x080c, 0x77c1, 0x0118, - 0x080c, 0x77af, 0x1530, 0x2011, 0x0020, 0x080c, 0x2ad3, 0x6043, - 0x0000, 0x080c, 0xd645, 0x0168, 0x080c, 0x77c1, 0x1150, 0x2001, - 0x19a8, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x7612, 0x0804, - 0x258e, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001, 0x00d6, 0x2069, - 0x0140, 0x080c, 0x77f2, 0x00de, 0x1904, 0x258e, 0x080c, 0x7ac0, - 0x0428, 0x080c, 0x77c1, 0x1590, 0x6024, 0x9084, 0x1800, 0x1108, - 0x0468, 0x080c, 0x7ac0, 0x080c, 0x7ab6, 0x080c, 0x619d, 0x080c, - 0x76cd, 0x0804, 0x258b, 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170, - 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7098, 0x9086, - 0x0029, 0x1110, 0x080c, 0x7990, 0x0804, 0x258b, 0x080c, 0x7abb, - 0x0048, 0x2001, 0x197d, 0x2003, 0x0002, 0x0020, 0x080c, 0x78e4, - 0x0804, 0x258b, 0x080c, 0x7a3a, 0x0804, 0x258b, 0x6220, 0xd1bc, - 0x0138, 0xd2bc, 0x1904, 0x25f6, 0xd2b4, 0x1904, 0x2608, 0x0000, - 0xd1ac, 0x0904, 0x2498, 0x0036, 0x6328, 0xc3bc, 0x632a, 0x003e, - 0x080c, 0x779e, 0x11d0, 0x2011, 0x0020, 0x080c, 0x2ad3, 0x0006, - 0x0026, 0x0036, 0x080c, 0x77b8, 0x1158, 0x080c, 0x7ab6, 0x080c, - 0x619d, 0x080c, 0x76cd, 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, - 0x003e, 0x002e, 0x000e, 0x080c, 0x7772, 0x0016, 0x0046, 0x00c6, - 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, - 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, 0x7038, 0xd084, - 0x0190, 0x080c, 0xd645, 0x1118, 0x9186, 0xf800, 0x1160, 0x7048, - 0xd084, 0x1148, 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, - 0x080c, 0x4ca1, 0x003e, 0x080c, 0xd63e, 0x1904, 0x246d, 0x9196, - 0xff00, 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, - 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x3482, 0x0128, - 0xc18d, 0x7132, 0x080c, 0x6c09, 0x1510, 0x6240, 0x9294, 0x0010, - 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, - 0xd08c, 0x0904, 0x246d, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, - 0x200c, 0xd1ac, 0x1904, 0x246d, 0xc1ad, 0x2102, 0x0036, 0x73d8, - 0x2011, 0x8013, 0x080c, 0x4ca1, 0x003e, 0x0804, 0x246d, 0x7038, - 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x246d, - 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4ca1, - 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, - 0x01f0, 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8c44, - 0x2019, 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xe9f9, 0x00ce, - 0x9484, 0x00ff, 0x9080, 0x348e, 0x200d, 0x918c, 0xff00, 0x810f, - 0x2120, 0x9006, 0x2009, 0x000e, 0x080c, 0xea8d, 0x001e, 0x0016, - 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32da, 0x001e, 0x00a8, - 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x67b4, 0x1140, - 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x61b7, - 0x8108, 0x1f04, 0x245d, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, - 0xacfc, 0x080c, 0xafd2, 0x080c, 0xb09b, 0x080c, 0xad18, 0x60e3, - 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, - 0xd19c, 0x11b0, 0x2011, 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, - 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, - 0x2001, 0x1826, 0x2003, 0x0000, 0x2011, 0x0020, 0x080c, 0x2ad3, - 0xd194, 0x0904, 0x258b, 0x0016, 0x080c, 0xacfc, 0x6220, 0xd2b4, - 0x0904, 0x2526, 0x080c, 0x8a4b, 0x080c, 0xa2a0, 0x2011, 0x0004, - 0x080c, 0x2ad3, 0x00f6, 0x2019, 0x19f4, 0x2304, 0x907d, 0x0904, - 0x24f3, 0x7804, 0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, - 0x0096, 0x2069, 0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, - 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, - 0x003c, 0x8001, 0x1df0, 0x080c, 0x2aa9, 0x2001, 0x001e, 0x8001, - 0x0240, 0x20a9, 0x0009, 0x080c, 0x2a60, 0x6904, 0xd1dc, 0x1140, - 0x0cb0, 0x2001, 0x0100, 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, - 0x080c, 0x99ed, 0x080c, 0xad18, 0x7814, 0x2048, 0xa867, 0x0103, - 0x2f60, 0x080c, 0xb16c, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, - 0x001e, 0x00ae, 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, - 0x9084, 0x4000, 0x0110, 0x080c, 0x2aa9, 0x00de, 0x00c6, 0x2061, - 0x19e8, 0x6034, 0x080c, 0xd645, 0x0120, 0x909a, 0x0003, 0x1258, - 0x0018, 0x909a, 0x00c8, 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, - 0xa278, 0x0804, 0x2588, 0x2061, 0x0100, 0x62c0, 0x080c, 0xac2d, - 0x2019, 0x19f4, 0x2304, 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, - 0x0027, 0x080c, 0xb20a, 0x00ce, 0x0804, 0x2588, 0xd2bc, 0x0904, - 0x256b, 0x080c, 0x8a58, 0x2011, 0x0004, 0x080c, 0x2ad3, 0x00d6, - 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2aa9, - 0x00de, 0x00c6, 0x2061, 0x19e8, 0x6050, 0x080c, 0xd645, 0x0120, - 0x909a, 0x0003, 0x1668, 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, - 0x6052, 0x604c, 0x00ce, 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, - 0x8a50, 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, - 0x1984, 0x2011, 0x0012, 0x080c, 0x2ae2, 0x0450, 0x9080, 0x0008, - 0x2004, 0x9086, 0x0009, 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, - 0x080c, 0x2ae2, 0x00e8, 0x2011, 0x0004, 0x080c, 0x2ad3, 0x00c0, - 0x0036, 0x2019, 0x0001, 0x080c, 0xa596, 0x003e, 0x2019, 0x19fb, - 0x2304, 0x9065, 0x0160, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, - 0x1110, 0x2009, 0x004f, 0x6003, 0x0003, 0x080c, 0xb20a, 0x00ce, - 0x080c, 0xad18, 0x001e, 0xd19c, 0x0904, 0x25ef, 0x7038, 0xd0ac, - 0x1558, 0x0016, 0x0156, 0x2011, 0x0008, 0x080c, 0x2ad3, 0x080c, - 0x2af6, 0x080c, 0x2b29, 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, - 0x0f04, 0x25ba, 0x1d04, 0x25a2, 0x080c, 0x8a7f, 0x6020, 0xd09c, - 0x1db8, 0x00f6, 0x2079, 0x0100, 0x080c, 0x2a0c, 0x00fe, 0x1d80, - 0x6050, 0xc0e4, 0x6052, 0x2011, 0x0008, 0x080c, 0x2ad3, 0x015e, - 0x001e, 0x04a8, 0x015e, 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, - 0x080c, 0xacfc, 0x080c, 0xafd2, 0x080c, 0xb09b, 0x080c, 0xad18, - 0x60e3, 0x0000, 0x080c, 0xeed9, 0x080c, 0xeef4, 0x080c, 0x5844, - 0xd0fc, 0x1138, 0x080c, 0xd63e, 0x1120, 0x9085, 0x0001, 0x080c, - 0x77e2, 0x9006, 0x080c, 0x2a99, 0x2009, 0x0002, 0x080c, 0x2a85, - 0x00e6, 0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0ed3, 0x00ee, - 0x2011, 0x0008, 0x080c, 0x2ad3, 0x080c, 0x0bcf, 0x001e, 0x918c, - 0xffd0, 0x2110, 0x080c, 0x2ad3, 0x00ae, 0x0005, 0x0016, 0x2001, - 0x0387, 0x200c, 0xd1a4, 0x001e, 0x0904, 0x2390, 0x0016, 0x2009, - 0x2602, 0x00c0, 0x2001, 0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, - 0x0016, 0x2001, 0x0387, 0x200c, 0xd1b4, 0x001e, 0x0904, 0x2390, - 0x0016, 0x2009, 0x2614, 0x0030, 0x2001, 0x0387, 0x2003, 0x4000, - 0x001e, 0x08a8, 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, - 0xbc91, 0x8000, 0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2a7f, - 0x2011, 0x0080, 0x080c, 0x2ad3, 0x6017, 0x0000, 0x6043, 0x0000, - 0x0817, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, - 0x2091, 0x8000, 0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, - 0x2684, 0x81ff, 0x01a0, 0x2009, 0x0000, 0x080c, 0x2a85, 0x2011, - 0x8011, 0x2019, 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, - 0x0001, 0x0010, 0x2019, 0x0000, 0x080c, 0x4ca1, 0x0468, 0x2001, - 0x19a9, 0x200c, 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, - 0x0118, 0x2019, 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, - 0x4ca1, 0x080c, 0x0ed3, 0x080c, 0x5844, 0xd0fc, 0x11a8, 0x080c, - 0xd63e, 0x1190, 0x00c6, 0x080c, 0x2720, 0x080c, 0xacfc, 0x080c, - 0xa4f1, 0x080c, 0xad18, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, - 0x0002, 0x080c, 0x32da, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, - 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, - 0x9094, 0xff00, 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, - 0x81ff, 0x01e8, 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, - 0x1820, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, - 0x2011, 0x1820, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, - 0x1120, 0x2500, 0x080c, 0x8521, 0x0048, 0x9584, 0x00ff, 0x9080, - 0x348e, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, - 0x348e, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, - 0x2001, 0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, - 0x6856, 0x1f04, 0x26d0, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, - 0x2069, 0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, - 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, - 0x9184, 0x000f, 0x9080, 0xef08, 0x2005, 0x6856, 0x8211, 0x1f04, - 0x26e5, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, - 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, - 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, - 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, - 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x2715, - 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, - 0x080c, 0x5840, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, - 0x2020, 0x2009, 0x002e, 0x080c, 0xea8d, 0x004e, 0x0005, 0x00f6, - 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x278c, - 0x080c, 0x29fc, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, - 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, - 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, - 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, - 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, - 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, - 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, - 0x9080, 0x0020, 0x2018, 0x080c, 0x955b, 0x928c, 0xff00, 0x0110, - 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, - 0x0138, 0x220a, 0x080c, 0x779e, 0x1118, 0x2009, 0x196d, 0x220a, - 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, - 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, - 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0d7e, 0x002e, - 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x180d, 0x2004, 0xd08c, - 0x0118, 0x2009, 0x0002, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, - 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, - 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, - 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, - 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, - 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, - 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x1990, 0x2004, - 0x908a, 0x0007, 0x1a0c, 0x0d85, 0x0033, 0x00ee, 0x002e, 0x001e, - 0x000e, 0x015e, 0x0005, 0x27f2, 0x2810, 0x2834, 0x2836, 0x285f, - 0x2861, 0x2863, 0x2001, 0x0001, 0x080c, 0x2631, 0x080c, 0x2a4a, - 0x2001, 0x1992, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, - 0x9006, 0x20a9, 0x0009, 0x080c, 0x2a18, 0x2001, 0x1990, 0x2003, - 0x0006, 0x2009, 0x001e, 0x2011, 0x2864, 0x080c, 0x8a5d, 0x0005, - 0x2009, 0x1995, 0x200b, 0x0000, 0x2001, 0x199a, 0x2003, 0x0036, - 0x2001, 0x1999, 0x2003, 0x002a, 0x2001, 0x1992, 0x2003, 0x0001, - 0x9006, 0x080c, 0x29ad, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, - 0x2a18, 0x2001, 0x1990, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, - 0x2864, 0x080c, 0x8a5d, 0x0005, 0x080c, 0x0d85, 0x2001, 0x199a, - 0x2003, 0x0036, 0x2001, 0x1992, 0x2003, 0x0003, 0x7a38, 0x9294, - 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, - 0x080c, 0x29ad, 0x2001, 0x1996, 0x2003, 0x0000, 0x2001, 0xffff, - 0x20a9, 0x0009, 0x080c, 0x2a18, 0x2001, 0x1990, 0x2003, 0x0006, - 0x2009, 0x001e, 0x2011, 0x2864, 0x080c, 0x8a5d, 0x0005, 0x080c, - 0x0d85, 0x080c, 0x0d85, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, - 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, - 0x1992, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0d85, 0x0043, 0x012e, - 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2886, - 0x28a2, 0x28de, 0x290a, 0x292a, 0x2936, 0x2938, 0x080c, 0x2a0c, - 0x1190, 0x2009, 0x1998, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, - 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1990, - 0x2003, 0x0001, 0x0030, 0x080c, 0x295c, 0x2001, 0xffff, 0x080c, - 0x2801, 0x0005, 0x080c, 0x293a, 0x05c0, 0x2009, 0x1999, 0x2104, - 0x8001, 0x200a, 0x080c, 0x2a0c, 0x1158, 0x7a38, 0x9294, 0x0005, - 0x9296, 0x0005, 0x0518, 0x2009, 0x1998, 0x2104, 0xc085, 0x200a, - 0x2009, 0x1995, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, - 0x080c, 0x2942, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, - 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, - 0x29ca, 0x2001, 0x1992, 0x2003, 0x0002, 0x0028, 0x2001, 0x1990, - 0x2003, 0x0003, 0x0010, 0x080c, 0x2823, 0x0005, 0x080c, 0x293a, - 0x0540, 0x2009, 0x1999, 0x2104, 0x8001, 0x200a, 0x080c, 0x2a0c, - 0x1148, 0x2001, 0x1990, 0x2003, 0x0003, 0x2001, 0x1991, 0x2003, - 0x0000, 0x00b8, 0x2009, 0x1999, 0x2104, 0x9005, 0x1118, 0x080c, - 0x297f, 0x0010, 0x080c, 0x294f, 0x080c, 0x2942, 0x2009, 0x1995, - 0x200b, 0x0000, 0x2001, 0x1992, 0x2003, 0x0001, 0x080c, 0x2823, - 0x0000, 0x0005, 0x0479, 0x01e8, 0x080c, 0x2a0c, 0x1198, 0x2009, - 0x1996, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, - 0x2001, 0x199b, 0x2003, 0x000a, 0x2009, 0x1998, 0x2104, 0xc0fd, - 0x200a, 0x0038, 0x00f9, 0x2001, 0x1992, 0x2003, 0x0004, 0x080c, - 0x284e, 0x0005, 0x0079, 0x0148, 0x080c, 0x2a0c, 0x1118, 0x080c, - 0x283a, 0x0018, 0x0079, 0x080c, 0x284e, 0x0005, 0x080c, 0x0d85, - 0x080c, 0x0d85, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x090c, - 0x299b, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, - 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ca, 0x0005, 0x7a38, - 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, - 0x0001, 0x080c, 0x29ad, 0x0005, 0x2009, 0x1995, 0x2104, 0x8000, - 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, - 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, - 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, - 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ca, 0x0005, 0x0086, - 0x2001, 0x1998, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0d85, 0x2009, - 0x1997, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, - 0xd084, 0x1120, 0x080c, 0x0d85, 0x9006, 0x0010, 0x2001, 0x0001, - 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1990, 0x20a9, - 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x29a1, 0x2001, 0x1997, - 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, - 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, - 0x783a, 0x2009, 0x199d, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, - 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, - 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, - 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x7850, 0x9084, - 0xfff0, 0x7852, 0x00f8, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, - 0x783a, 0x7850, 0x9084, 0xfff0, 0x0016, 0x2009, 0x017f, 0x210c, - 0x918e, 0x0005, 0x0140, 0x2009, 0x0003, 0x210c, 0x918c, 0x0600, - 0x918e, 0x0400, 0x0118, 0x9085, 0x000a, 0x0010, 0x9085, 0x0000, - 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, - 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, - 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, - 0x080c, 0x2a7f, 0xd09c, 0x1110, 0x1f04, 0x2a0f, 0x015e, 0x0005, - 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x000e, 0x2008, 0x9186, - 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, - 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, - 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, - 0x1d04, 0x2a38, 0x080c, 0x8a7f, 0x1f04, 0x2a38, 0x080c, 0x2af6, - 0x080c, 0x2b29, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e, - 0x012e, 0x0005, 0x080c, 0x2b29, 0x0005, 0x0006, 0x0156, 0x00f6, - 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1100, 0x7854, - 0xd08c, 0x1110, 0x1f04, 0x2a57, 0x00fe, 0x015e, 0x000e, 0x0005, - 0x1d04, 0x2a60, 0x080c, 0x8a7f, 0x1f04, 0x2a60, 0x0005, 0x0006, - 0x2001, 0x199c, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, - 0x2001, 0x199c, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, 0x0006, - 0x2001, 0x199c, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, 0xa001, - 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, 0x19a9, - 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140, - 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, 0x200a, - 0x0005, 0x0016, 0x0026, 0x080c, 0x77b8, 0x0108, 0xc0bc, 0x2009, - 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, - 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, - 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, - 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, - 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, - 0x1128, 0x080c, 0x77b8, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, - 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, 0x0101, - 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202, 0x7843, 0x0100, - 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, 0x0202, 0x7844, - 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104, 0x9205, 0x7a16, - 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005, 0x0016, 0x0026, - 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084, 0xfbff, 0x9085, - 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a60, 0x6050, 0x9085, - 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, 0x080c, 0x2a60, - 0x6054, 0xd0bc, 0x090c, 0x0d85, 0x20a9, 0x0005, 0x080c, 0x2a60, - 0x6054, 0xd0ac, 0x090c, 0x0d85, 0x2009, 0x19b0, 0x9084, 0x7e00, - 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e, 0x002e, 0x001e, - 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050, 0xc0cd, 0x6052, - 0x00ce, 0x000e, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x0006, 0x2061, - 0x0100, 0x2069, 0x0140, 0x6030, 0x0006, 0x6048, 0x0006, 0x60e4, - 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, - 0x0006, 0x6004, 0x0006, 0xc0fc, 0x6006, 0x2009, 0x0800, 0x2001, - 0x0338, 0x2003, 0x0301, 0x8109, 0x090c, 0x0d85, 0x2001, 0x0338, - 0x2004, 0xd084, 0x1dc0, 0x6028, 0x0006, 0x60e0, 0x0006, 0x6888, - 0x0006, 0x688c, 0x0006, 0x6890, 0x0006, 0x080c, 0x779e, 0x1110, - 0x6884, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xa001, 0xa001, - 0xa001, 0xa001, 0x602f, 0x0040, 0x602f, 0x0000, 0x080c, 0x779e, - 0x1120, 0x6803, 0x0080, 0x000e, 0x6886, 0x6897, 0x4198, 0x000e, - 0x6892, 0x000e, 0x688e, 0x000e, 0x688a, 0x000e, 0x60e2, 0x000e, - 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, - 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, 0x604a, 0x000e, - 0x6032, 0x6036, 0x2008, 0x080c, 0x26d5, 0x000e, 0x00de, 0x00ce, - 0x001e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, 0x0040, 0x6052, - 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2a7f, 0x9085, 0x2000, - 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2bb3, 0x080c, 0x8a7f, 0x1f04, - 0x2bb3, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, 0x015e, - 0x000e, 0x0005, 0x30be, 0x30be, 0x2cc2, 0x2cc2, 0x2cce, 0x2cce, - 0x2cda, 0x2cda, 0x2ce8, 0x2ce8, 0x2cf4, 0x2cf4, 0x2d02, 0x2d02, - 0x2d10, 0x2d10, 0x2d22, 0x2d22, 0x2d2e, 0x2d2e, 0x2d3c, 0x2d3c, - 0x2d5a, 0x2d5a, 0x2d7a, 0x2d7a, 0x2d4a, 0x2d4a, 0x2d6a, 0x2d6a, - 0x2d88, 0x2d88, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d9a, 0x2d9a, 0x2da6, 0x2da6, 0x2db4, 0x2db4, - 0x2dc2, 0x2dc2, 0x2dd2, 0x2dd2, 0x2de0, 0x2de0, 0x2df0, 0x2df0, - 0x2e00, 0x2e00, 0x2e12, 0x2e12, 0x2e20, 0x2e20, 0x2e30, 0x2e30, - 0x2e52, 0x2e52, 0x2e76, 0x2e76, 0x2e40, 0x2e40, 0x2e64, 0x2e64, - 0x2e86, 0x2e86, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2e9a, 0x2e9a, 0x2ea6, 0x2ea6, 0x2eb4, 0x2eb4, - 0x2ec2, 0x2ec2, 0x2ed2, 0x2ed2, 0x2ee0, 0x2ee0, 0x2ef0, 0x2ef0, - 0x2f00, 0x2f00, 0x2f12, 0x2f12, 0x2f20, 0x2f20, 0x2f30, 0x2f30, - 0x2f40, 0x2f40, 0x2f52, 0x2f52, 0x2f62, 0x2f62, 0x2f74, 0x2f74, - 0x2f86, 0x2f86, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2f9a, 0x2f9a, 0x2fa8, 0x2fa8, 0x2fb8, 0x2fb8, - 0x2fc8, 0x2fc8, 0x2fda, 0x2fda, 0x2fea, 0x2fea, 0x2ffc, 0x2ffc, - 0x300e, 0x300e, 0x3022, 0x3022, 0x3032, 0x3032, 0x3044, 0x3044, - 0x3056, 0x3056, 0x306a, 0x306a, 0x307b, 0x307b, 0x308e, 0x308e, - 0x30a1, 0x30a1, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, - 0x2d20, 0x2d20, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x22c8, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x22c8, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22c8, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x2114, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x2114, 0x0804, 0x30b6, - 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22c8, - 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x13d4, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x13d4, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x13d4, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x13d4, 0x080c, 0x2114, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, - 0x080c, 0x22c8, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x22c8, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x2114, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0x22c8, 0x080c, 0x2114, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x2114, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x13d4, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x13d4, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x22c8, - 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, - 0x080c, 0x13d4, 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, - 0x080c, 0x13d4, 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, - 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0xad62, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xad62, - 0x080c, 0x22c8, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0xad62, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0xad62, 0x080c, 0x2114, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x2114, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x2114, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0xad62, 0x080c, 0x13d4, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x13d4, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0xad62, 0x080c, 0x13d4, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, - 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0xad62, - 0x080c, 0x13d4, 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, - 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x22c8, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0xad62, 0x0804, 0x30b6, - 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, - 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x22c8, - 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, - 0x080c, 0xad62, 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, - 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x2114, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x13d4, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x22c8, - 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, - 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, - 0x080c, 0xad62, 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, - 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, - 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, - 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x13d4, - 0x080c, 0x2114, 0x04d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, - 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, - 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, 0x0440, 0x0106, 0x0006, - 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, - 0x080c, 0x20ea, 0x080c, 0x13d4, 0x080c, 0xad62, 0x080c, 0x2114, - 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, - 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, - 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, 0x0000, 0x015e, 0x014e, - 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d, 0x00b6, - 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6bcf, 0x1904, 0x31f6, - 0x72dc, 0x2001, 0x197c, 0x2004, 0x9005, 0x1110, 0xd29c, 0x0148, - 0xd284, 0x1138, 0xd2bc, 0x1904, 0x31f6, 0x080c, 0x31fb, 0x0804, - 0x31f6, 0xd2cc, 0x1904, 0x31f6, 0x080c, 0x779e, 0x1120, 0x70af, - 0xffff, 0x0804, 0x31f6, 0xd294, 0x0120, 0x70af, 0xffff, 0x0804, - 0x31f6, 0x080c, 0x347d, 0x0160, 0x080c, 0xd645, 0x0128, 0x2001, - 0x1818, 0x203c, 0x0804, 0x316f, 0x70af, 0xffff, 0x0804, 0x31f6, - 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, 0x316f, 0xd28c, - 0x1904, 0x316f, 0x0036, 0x73ac, 0x938e, 0xffff, 0x1110, 0x2019, - 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0x938c, 0x0001, 0x0120, - 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x970e, 0x0904, - 0x3165, 0x908e, 0x0000, 0x0904, 0x3165, 0x908e, 0x00ff, 0x1160, - 0x7230, 0xd284, 0x1904, 0x316a, 0x7294, 0xc28d, 0x7296, 0x70af, - 0xffff, 0x003e, 0x0804, 0x316f, 0x2009, 0x180d, 0x210c, 0xd18c, - 0x0150, 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, 0x002e, 0x0118, - 0x70af, 0xffff, 0x0488, 0x900e, 0x080c, 0x268c, 0x080c, 0x6749, - 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, - 0x2060, 0x080c, 0x8eee, 0x00ce, 0x090c, 0x928d, 0xb8af, 0x0000, - 0x080c, 0x6c11, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, - 0x0138, 0x080c, 0x6aae, 0x0120, 0x080c, 0x3214, 0x0148, 0x0028, - 0x080c, 0x3360, 0x080c, 0x3240, 0x0118, 0x8318, 0x0804, 0x3109, - 0x73ae, 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x31f6, 0x9780, - 0x348e, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, - 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, - 0x2008, 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x31f6, - 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x31eb, 0x2001, 0x180d, - 0x2004, 0xd08c, 0x0158, 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, - 0x002e, 0x0120, 0x2009, 0xffff, 0x0804, 0x31f3, 0xc484, 0x080c, - 0x67b4, 0x0168, 0x080c, 0xd645, 0x1904, 0x31eb, 0x080c, 0x347d, - 0x1904, 0x31eb, 0x080c, 0x6749, 0x1904, 0x31f3, 0x0008, 0xc485, + 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0d79, + 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1ede, 0x2015, + 0x82ff, 0x090c, 0x0d79, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, + 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1ab1, 0x19de, + 0x19de, 0x1ab1, 0x19de, 0x1aab, 0x1ab1, 0x19de, 0x1a4e, 0x1a4e, + 0x1a4e, 0x1ab1, 0x1a4e, 0x1ab1, 0x1aa8, 0x1a4e, 0xc0fc, 0xa882, + 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1ab3, 0x2c05, + 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x19ca, + 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19ce, 0x19c8, 0x19c8, + 0x19c8, 0x19c8, 0x19c8, 0x19d2, 0x19c8, 0x19c8, 0x19c8, 0x19c8, + 0x19c8, 0x19d6, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19da, + 0x080c, 0x0d79, 0xa774, 0xa678, 0x0804, 0x1ab3, 0xa78c, 0xa690, + 0x0804, 0x1ab3, 0xa7a4, 0xa6a8, 0x0804, 0x1ab3, 0xa7bc, 0xa6c0, + 0x0804, 0x1ab3, 0xa7d4, 0xa6d8, 0x0804, 0x1ab3, 0xa898, 0x901d, + 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d79, + 0x9082, 0x001b, 0x0002, 0x1a06, 0x1a06, 0x1a08, 0x1a06, 0x1a06, + 0x1a06, 0x1a12, 0x1a06, 0x1a06, 0x1a06, 0x1a1c, 0x1a06, 0x1a06, + 0x1a06, 0x1a26, 0x1a06, 0x1a06, 0x1a06, 0x1a30, 0x1a06, 0x1a06, + 0x1a06, 0x1a3a, 0x1a06, 0x1a06, 0x1a06, 0x1a44, 0x080c, 0x0d79, + 0xa574, 0xa478, 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa37c, 0xa280, + 0x0804, 0x1ab3, 0xa584, 0xa488, 0x9d86, 0x0004, 0x0904, 0x1ab3, + 0xa38c, 0xa290, 0x0804, 0x1ab3, 0xa594, 0xa498, 0x9d86, 0x0004, + 0x0904, 0x1ab3, 0xa39c, 0xa2a0, 0x0804, 0x1ab3, 0xa5a4, 0xa4a8, + 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa3ac, 0xa2b0, 0x0804, 0x1ab3, + 0xa5b4, 0xa4b8, 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa3bc, 0xa2c0, + 0x0804, 0x1ab3, 0xa5c4, 0xa4c8, 0x9d86, 0x0004, 0x0904, 0x1ab3, + 0xa3cc, 0xa2d0, 0x0804, 0x1ab3, 0xa5d4, 0xa4d8, 0x9d86, 0x0004, + 0x0904, 0x1ab3, 0xa3dc, 0xa2e0, 0x0804, 0x1ab3, 0xa898, 0x901d, + 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d79, + 0x9082, 0x001b, 0x0002, 0x1a76, 0x1a74, 0x1a74, 0x1a74, 0x1a74, + 0x1a74, 0x1a80, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a8a, + 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a94, 0x1a74, 0x1a74, + 0x1a74, 0x1a74, 0x1a74, 0x1a9e, 0x080c, 0x0d79, 0xa56c, 0xa470, + 0xa774, 0xa678, 0x9d86, 0x000c, 0x05b0, 0xa37c, 0xa280, 0x0498, + 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x000c, 0x0560, 0xa394, + 0xa298, 0x0448, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x000c, + 0x0510, 0xa3ac, 0xa2b0, 0x00f8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, + 0x9d86, 0x000c, 0x01c0, 0xa3c4, 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, + 0xa7d4, 0xa6d8, 0x9d86, 0x000c, 0x0170, 0xa3dc, 0xa2e0, 0x0058, + 0x9d86, 0x000e, 0x1130, 0x080c, 0x1eb4, 0x1904, 0x1987, 0x900e, + 0x0050, 0x080c, 0x0d79, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, + 0xae2a, 0x080c, 0x1eb4, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, + 0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, + 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, + 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, + 0x0048, 0x080c, 0xafec, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, + 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, + 0x601c, 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xafec, 0x0005, + 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, + 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, + 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, + 0xd09c, 0x0120, 0x080c, 0x13c8, 0x8631, 0x1db8, 0x00ce, 0x781f, + 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x13c8, + 0x00ce, 0x2001, 0x0038, 0x080c, 0x1bcb, 0x7930, 0x9186, 0x0040, + 0x0160, 0x9186, 0x0042, 0x190c, 0x0d79, 0x2001, 0x001e, 0x8001, + 0x1df0, 0x8631, 0x1d40, 0x080c, 0x1bda, 0x000e, 0x6022, 0x012e, + 0x0005, 0x080c, 0x1bc7, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, + 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, + 0x78ab, 0x0004, 0x2001, 0xf000, 0x8001, 0x090c, 0x0d79, 0x7aac, + 0xd2ac, 0x1dd0, 0x00fe, 0x080c, 0x769d, 0x1188, 0x2001, 0x0138, + 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, + 0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x773f, 0x0479, + 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, + 0x00e6, 0x2071, 0x0200, 0x080c, 0x2a94, 0x2009, 0x003c, 0x080c, + 0x223d, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, + 0x1de0, 0x080c, 0x8732, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, + 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, + 0x080c, 0x135a, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, + 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, + 0x0000, 0x080c, 0x769d, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, + 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, + 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, + 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, + 0x0019, 0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048, + 0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c, + 0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x16ad, 0x7930, + 0x0005, 0x2c08, 0x621c, 0x080c, 0x16f6, 0x7930, 0x0005, 0x8001, + 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, + 0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1c38, 0x2001, + 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0d79, 0x781f, 0x0202, + 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, + 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, + 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, + 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, + 0x2001, 0x0030, 0x080c, 0x1bd1, 0x9186, 0x0040, 0x190c, 0x0d79, + 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, + 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, + 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, + 0x9184, 0x0007, 0x090c, 0x0d79, 0xa001, 0xa001, 0x781f, 0x0200, + 0x0005, 0x0126, 0x2091, 0x2400, 0x2079, 0x0380, 0x2001, 0x19e9, + 0x2070, 0x012e, 0x0005, 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, + 0x6014, 0x2048, 0xa964, 0xa91a, 0x918c, 0x00ff, 0x9184, 0x000f, + 0x0002, 0x1c6d, 0x1c6d, 0x1c6d, 0x1c6f, 0x1c6d, 0x1c6d, 0x1c6d, + 0x1c6d, 0x1c61, 0x1c77, 0x1c6d, 0x1c73, 0x1c6d, 0x1c6d, 0x1c6d, + 0x1c6d, 0x9086, 0x0008, 0x1148, 0xa87c, 0xd0b4, 0x0904, 0x1de7, + 0x2011, 0x1ed9, 0x2205, 0xab88, 0x00a8, 0x080c, 0x0d79, 0x9186, + 0x0013, 0x0128, 0x0cd0, 0x9186, 0x001b, 0x0108, 0x0cb0, 0xa87c, + 0xd0b4, 0x0904, 0x1de7, 0x9184, 0x000f, 0x9080, 0x1ede, 0x2015, + 0x2205, 0xab88, 0x2908, 0xa80a, 0xa90e, 0xaa12, 0xab16, 0x9006, + 0xa842, 0xa83e, 0x012e, 0x0005, 0x2cf0, 0x0126, 0x2091, 0x2400, + 0x3e60, 0x6014, 0x2048, 0xa88c, 0xa990, 0xaaac, 0xabb0, 0xaa36, + 0xab3a, 0xa83e, 0xa942, 0xa846, 0xa94a, 0xa964, 0x918c, 0x00ff, + 0x9186, 0x001e, 0x0198, 0x2940, 0xa064, 0xa81a, 0x90ec, 0x000f, + 0x9d80, 0x1ede, 0x2065, 0x2c05, 0x2808, 0x2c10, 0xab88, 0xa80a, + 0xa90e, 0xaa12, 0xab16, 0x012e, 0x3e60, 0x0005, 0xa804, 0x2040, + 0x0c58, 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, + 0xa97c, 0x2950, 0xd1dc, 0x1904, 0x1db1, 0xc1dd, 0xa97e, 0x9006, + 0xa842, 0xa83e, 0xa988, 0x8109, 0xa916, 0xa964, 0xa91a, 0x9184, + 0x000f, 0x9088, 0x1ede, 0x2145, 0x0002, 0x1ce5, 0x1cf3, 0x1ce5, + 0x1ce5, 0x1ce5, 0x1ce7, 0x1ce5, 0x1ce5, 0x1d48, 0x1d48, 0x1ce5, + 0x1ce5, 0x1ce5, 0x1d46, 0x1ce5, 0x1ce5, 0x080c, 0x0d79, 0xa804, + 0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, 0x9080, 0x1ede, 0x2045, + 0xd19c, 0x1904, 0x1d48, 0x9036, 0x2638, 0x2805, 0x908a, 0x0036, + 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x1d18, 0x1d18, 0x1d1a, + 0x1d18, 0x1d18, 0x1d18, 0x1d20, 0x1d18, 0x1d18, 0x1d18, 0x1d26, + 0x1d18, 0x1d18, 0x1d18, 0x1d2c, 0x1d18, 0x1d18, 0x1d18, 0x1d32, + 0x1d18, 0x1d18, 0x1d18, 0x1d38, 0x1d18, 0x1d18, 0x1d18, 0x1d3e, + 0x080c, 0x0d79, 0xb574, 0xb478, 0xb37c, 0xb280, 0x0804, 0x1d8d, + 0xb584, 0xb488, 0xb38c, 0xb290, 0x0804, 0x1d8d, 0xb594, 0xb498, + 0xb39c, 0xb2a0, 0x0804, 0x1d8d, 0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0, + 0x0804, 0x1d8d, 0xb5b4, 0xb4b8, 0xb3bc, 0xb2c0, 0x0804, 0x1d8d, + 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0, 0x0804, 0x1d8d, 0xb5d4, 0xb4d8, + 0xb3dc, 0xb2e0, 0x0804, 0x1d8d, 0x0804, 0x1d8d, 0x080c, 0x0d79, + 0x2805, 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, + 0x1d6b, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d72, 0x1d69, + 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d79, 0x1d69, 0x1d69, 0x1d69, + 0x1d69, 0x1d69, 0x1d80, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d69, + 0x1d87, 0x080c, 0x0d79, 0xb56c, 0xb470, 0xb774, 0xb678, 0xb37c, + 0xb280, 0x00d8, 0xb584, 0xb488, 0xb78c, 0xb690, 0xb394, 0xb298, + 0x00a0, 0xb59c, 0xb4a0, 0xb7a4, 0xb6a8, 0xb3ac, 0xb2b0, 0x0068, + 0xb5b4, 0xb4b8, 0xb7bc, 0xb6c0, 0xb3c4, 0xb2c8, 0x0030, 0xb5cc, + 0xb4d0, 0xb7d4, 0xb6d8, 0xb3dc, 0xb2e0, 0xab2e, 0xaa32, 0xad1e, + 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8109, 0xa916, 0x1118, 0x9006, + 0x012e, 0x0005, 0x8840, 0x2805, 0x9005, 0x1168, 0xb004, 0x9005, + 0x090c, 0x0d79, 0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, 0x9080, + 0x1ede, 0x2045, 0x2805, 0x2810, 0x2a08, 0xa80a, 0xa90e, 0xaa12, + 0x0c30, 0x3e60, 0x6344, 0xd3fc, 0x190c, 0x0d79, 0xa93c, 0xaa40, + 0xa844, 0x9106, 0x1118, 0xa848, 0x9206, 0x0508, 0x2958, 0xab48, + 0xac44, 0x2940, 0x080c, 0x1efe, 0x1998, 0x2850, 0x2c40, 0xab14, + 0xa880, 0xd0fc, 0x1140, 0xa810, 0x2005, 0xa80a, 0x2a00, 0xa80e, + 0x2009, 0x8015, 0x0070, 0x00c6, 0x3e60, 0x6044, 0xc0a4, 0x9085, + 0x8005, 0x6046, 0x00ce, 0x8319, 0xab16, 0x1904, 0x1d9a, 0x2009, + 0x8005, 0x3e60, 0x6044, 0x9105, 0x6046, 0x0804, 0x1d97, 0x080c, + 0x0d79, 0x00f6, 0x00e6, 0x0096, 0x00c6, 0x0026, 0x704c, 0x9c06, + 0x190c, 0x0d79, 0x2079, 0x0090, 0x2001, 0x0105, 0x2003, 0x0010, + 0x782b, 0x0004, 0x7057, 0x0000, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, 0x9086, 0x0006, 0x1170, + 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, + 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, 0xa896, 0x704c, 0x2060, + 0x00c6, 0x080c, 0xc81b, 0x080c, 0xaaf7, 0x00ce, 0x704c, 0x9c06, + 0x1150, 0x2009, 0x0040, 0x080c, 0x223d, 0x080c, 0xa59c, 0x2011, + 0x0000, 0x080c, 0xa430, 0x002e, 0x00ce, 0x009e, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0x2079, 0x0090, 0x781c, 0x0006, 0x7818, 0x0006, + 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, + 0x2019, 0x1000, 0x8319, 0x090c, 0x0d79, 0x7820, 0xd0bc, 0x1dd0, + 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, + 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984, 0x9085, 0x0012, + 0x7816, 0x2079, 0x0090, 0x782b, 0x0008, 0x7057, 0x0000, 0x00fe, + 0x0005, 0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054, 0x9086, 0x0000, + 0x0904, 0x1eaf, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, + 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, + 0xec09, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0d79, 0x0016, + 0x2009, 0x0040, 0x080c, 0x223d, 0x001e, 0x2001, 0x020c, 0x2102, + 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, + 0x2009, 0x0040, 0x080c, 0x223d, 0x782c, 0xd0fc, 0x09a8, 0x080c, + 0xab13, 0x782c, 0xd0fc, 0x1de8, 0x080c, 0xaaf7, 0x7054, 0x9086, + 0x0000, 0x1950, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, + 0x0040, 0x080c, 0x223d, 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, + 0x00fe, 0x0005, 0x080c, 0x0d79, 0x8c60, 0x2c05, 0x9005, 0x0110, + 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, + 0x9084, 0x000f, 0x9080, 0x1ede, 0x2065, 0x8cff, 0x090c, 0x0d79, + 0x8a51, 0x0005, 0x2050, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025, + 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027, + 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x1ed1, + 0x1ecd, 0x1ed1, 0x1ed1, 0x1edb, 0x0000, 0x1ed1, 0x1ed8, 0x1ed8, + 0x1ed5, 0x1ed8, 0x1ed8, 0x0000, 0x1edb, 0x1ed8, 0x0000, 0x1ed3, + 0x1ed3, 0x0000, 0x1ed3, 0x1edb, 0x0000, 0x1ed3, 0x1ed9, 0x1ed9, + 0x1ed9, 0x0000, 0x1ed9, 0x0000, 0x1edb, 0x1ed9, 0x00c6, 0x00d6, + 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x20dd, 0x2940, + 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118, + 0x2061, 0x1ed9, 0x00d0, 0x9de0, 0x1ede, 0x9d86, 0x0007, 0x0130, + 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, + 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x20dd, + 0xa004, 0x9045, 0x0904, 0x20dd, 0x08d8, 0x2c05, 0x9005, 0x0904, + 0x1fc5, 0xdd9c, 0x1904, 0x1f81, 0x908a, 0x0036, 0x1a0c, 0x0d79, + 0x9082, 0x001b, 0x0002, 0x1f56, 0x1f56, 0x1f58, 0x1f56, 0x1f56, + 0x1f56, 0x1f5e, 0x1f56, 0x1f56, 0x1f56, 0x1f64, 0x1f56, 0x1f56, + 0x1f56, 0x1f6a, 0x1f56, 0x1f56, 0x1f56, 0x1f70, 0x1f56, 0x1f56, + 0x1f56, 0x1f76, 0x1f56, 0x1f56, 0x1f56, 0x1f7c, 0x080c, 0x0d79, + 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x1fbb, 0xa08c, 0x9422, + 0xa090, 0x931b, 0x0804, 0x1fbb, 0xa09c, 0x9422, 0xa0a0, 0x931b, + 0x0804, 0x1fbb, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x1fbb, + 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x1fbb, 0xa0cc, 0x9422, + 0xa0d0, 0x931b, 0x0804, 0x1fbb, 0xa0dc, 0x9422, 0xa0e0, 0x931b, + 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, + 0x1fa3, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa8, 0x1fa1, + 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fad, 0x1fa1, 0x1fa1, 0x1fa1, + 0x1fa1, 0x1fa1, 0x1fb2, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, + 0x1fb7, 0x080c, 0x0d79, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0098, + 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0, + 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc, + 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, 0x8a51, + 0x0904, 0x20dd, 0x8c60, 0x0804, 0x1f2d, 0xa004, 0x9045, 0x0904, + 0x20dd, 0x0804, 0x1f08, 0x8a51, 0x0904, 0x20dd, 0x8c60, 0x2c05, + 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x20dd, 0xa064, 0x90ec, + 0x000f, 0x9de0, 0x1ede, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882, + 0x0804, 0x20d2, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000, + 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x206f, 0x9082, 0x001b, 0x0002, + 0x200b, 0x200b, 0x200d, 0x200b, 0x200b, 0x200b, 0x201b, 0x200b, + 0x200b, 0x200b, 0x2029, 0x200b, 0x200b, 0x200b, 0x2037, 0x200b, + 0x200b, 0x200b, 0x2045, 0x200b, 0x200b, 0x200b, 0x2053, 0x200b, + 0x200b, 0x200b, 0x2061, 0x080c, 0x0d79, 0xa17c, 0x2400, 0x9122, + 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa074, 0x9420, 0xa078, + 0x9319, 0x0804, 0x20cd, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, + 0x911b, 0x0a0c, 0x0d79, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804, + 0x20cd, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, + 0x0d79, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x20cd, 0xa1ac, + 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0a4, + 0x9420, 0xa0a8, 0x9319, 0x0804, 0x20cd, 0xa1bc, 0x2400, 0x9122, + 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0b4, 0x9420, 0xa0b8, + 0x9319, 0x0804, 0x20cd, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, + 0x911b, 0x0a0c, 0x0d79, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804, + 0x20cd, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, + 0x0d79, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x20cd, 0x9082, + 0x001b, 0x0002, 0x208d, 0x208b, 0x208b, 0x208b, 0x208b, 0x208b, + 0x209a, 0x208b, 0x208b, 0x208b, 0x208b, 0x208b, 0x20a7, 0x208b, + 0x208b, 0x208b, 0x208b, 0x208b, 0x20b4, 0x208b, 0x208b, 0x208b, + 0x208b, 0x208b, 0x20c1, 0x080c, 0x0d79, 0xa17c, 0x2400, 0x9122, + 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa06c, 0x9420, 0xa070, + 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b, + 0x0a0c, 0x0d79, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac, + 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa09c, + 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8, + 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0b4, 0x9420, 0xa0b8, 0x9319, + 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, + 0x0d79, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, 0xa880, + 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816, + 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, 0x00ce, + 0x9085, 0x0001, 0x0005, 0x00c6, 0x610c, 0x0016, 0x9026, 0x2410, + 0x6004, 0x9420, 0x9291, 0x0000, 0x2c04, 0x9210, 0x9ce0, 0x0002, + 0x918a, 0x0002, 0x1da8, 0x9284, 0x000f, 0x9405, 0x001e, 0x00ce, + 0x0005, 0x7803, 0x0003, 0x780f, 0x0000, 0x6004, 0x7812, 0x2c04, + 0x7816, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1db8, 0x0005, 0x2001, + 0x0005, 0x2004, 0xd0bc, 0x190c, 0x0d72, 0xd094, 0x0110, 0x080c, + 0x11fc, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, + 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, + 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, + 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, + 0x0005, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x223a, 0x7900, + 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, + 0x2158, 0x2150, 0x80a9, 0x2150, 0x2152, 0x2152, 0x2152, 0x2152, + 0x808f, 0x2150, 0x2154, 0x2150, 0x2152, 0x2150, 0x2152, 0x2150, + 0x080c, 0x0d79, 0x0031, 0x0020, 0x080c, 0x808f, 0x080c, 0x80a9, + 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, 0xec09, 0x7930, 0x9184, + 0x0003, 0x0510, 0x080c, 0xaaf7, 0x2001, 0x19fc, 0x2004, 0x9005, + 0x01a0, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0d79, 0x00c6, + 0x2001, 0x19fc, 0x2064, 0x080c, 0xab13, 0x080c, 0xc81b, 0x2009, + 0x0040, 0x080c, 0x223d, 0x00ce, 0x0408, 0x2009, 0x0040, 0x080c, + 0x223d, 0x080c, 0xab13, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, + 0x9286, 0x0003, 0x0160, 0x080c, 0x769d, 0x1138, 0x080c, 0x799f, + 0x080c, 0x6178, 0x080c, 0x75cc, 0x0010, 0x080c, 0x6033, 0x080c, + 0x8147, 0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, + 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6f, + 0x080c, 0x1b3b, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128, 0x2001, 0x1970, 0x2102, + 0x2001, 0x1978, 0x2102, 0x2001, 0x013b, 0x2102, 0x2079, 0x0200, + 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, + 0x831c, 0x831c, 0x9398, 0x0005, 0x2320, 0x9182, 0x0204, 0x1230, + 0x2011, 0x0008, 0x8423, 0x8423, 0x8423, 0x0488, 0x9182, 0x024c, + 0x1240, 0x2011, 0x0007, 0x8403, 0x8003, 0x9400, 0x9400, 0x9420, + 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011, 0x0006, 0x8403, 0x8003, + 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c, 0x1230, 0x2011, 0x0005, + 0x8403, 0x8003, 0x9420, 0x0098, 0x9182, 0x042c, 0x1228, 0x2011, + 0x0004, 0x8423, 0x8423, 0x0058, 0x9182, 0x059c, 0x1228, 0x2011, + 0x0003, 0x8403, 0x9420, 0x0018, 0x2011, 0x0002, 0x8423, 0x9482, + 0x0228, 0x8002, 0x8020, 0x8301, 0x9402, 0x0110, 0x0208, 0x8321, + 0x8217, 0x8203, 0x9405, 0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, + 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, + 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200, 0x9005, 0x6810, 0x0110, + 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, + 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, + 0x000e, 0x0005, 0x7938, 0x080c, 0x0d72, 0x00f6, 0x2079, 0x0200, + 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x7902, + 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, + 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, + 0x0000, 0x080c, 0x2a8e, 0x080c, 0x29a8, 0x2001, 0x199e, 0x2003, + 0x0700, 0x2001, 0x199f, 0x2003, 0x0700, 0x080c, 0x2aff, 0x9006, + 0x080c, 0x29d7, 0x9006, 0x080c, 0x29ba, 0x20a9, 0x0012, 0x1d04, + 0x226f, 0x2091, 0x6000, 0x1f04, 0x226f, 0x602f, 0x0100, 0x602f, + 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6224, + 0x080c, 0x2adc, 0x080c, 0x26da, 0x2009, 0x00ef, 0x6132, 0x6136, + 0x080c, 0x26ea, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, + 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, + 0x349f, 0x00c6, 0x2061, 0x0140, 0x608b, 0x000b, 0x608f, 0x10b8, + 0x6093, 0x0000, 0x6097, 0x0198, 0x00ce, 0x6004, 0x9085, 0x8000, + 0x6006, 0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, + 0x22ad, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf, + 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b, + 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, 0x602b, 0x402c, 0x012e, + 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, 0x0080, 0x78c3, 0x0083, + 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, 0x1835, 0x2003, 0x0000, + 0x2001, 0x1834, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, + 0x0006, 0x0016, 0x0026, 0x6124, 0x6028, 0x910c, 0x0066, 0x2031, + 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, 0x1138, 0x6020, 0xd1bc, + 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, 0x9184, 0x5e2c, 0x1118, + 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284, 0x0007, 0x0082, + 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4, 0x001e, 0x0d70, 0x0c98, + 0x0016, 0x2001, 0x0387, 0x200c, 0xd1b4, 0x001e, 0x0d30, 0x0c58, + 0x231b, 0x2318, 0x2318, 0x2318, 0x231a, 0x2318, 0x2318, 0x2318, + 0x080c, 0x0d79, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, + 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x25a0, + 0xd1f4, 0x190c, 0x0d72, 0x080c, 0x769d, 0x0904, 0x2378, 0x080c, + 0xd35d, 0x1120, 0x7000, 0x9086, 0x0003, 0x0580, 0x6024, 0x9084, + 0x1800, 0x0560, 0x080c, 0x76c0, 0x0118, 0x080c, 0x76ae, 0x1530, + 0x2011, 0x0020, 0x080c, 0x2adc, 0x6043, 0x0000, 0x080c, 0xd35d, + 0x0168, 0x080c, 0x76c0, 0x1150, 0x2001, 0x19a9, 0x2003, 0x0001, + 0x6027, 0x1800, 0x080c, 0x7511, 0x0804, 0x25a3, 0x70a4, 0x9005, + 0x1150, 0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x76f1, + 0x00de, 0x1904, 0x25a3, 0x080c, 0x79a9, 0x0428, 0x080c, 0x76c0, + 0x1590, 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x79a9, + 0x080c, 0x799f, 0x080c, 0x6178, 0x080c, 0x75cc, 0x0804, 0x25a0, + 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, + 0x1190, 0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, + 0x7880, 0x0804, 0x25a0, 0x080c, 0x79a4, 0x0048, 0x2001, 0x197e, + 0x2003, 0x0002, 0x0020, 0x080c, 0x77db, 0x0804, 0x25a0, 0x080c, + 0x7923, 0x0804, 0x25a0, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, + 0x260b, 0xd2b4, 0x1904, 0x261d, 0x0000, 0xd1ac, 0x0904, 0x24ad, + 0x0036, 0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x769d, 0x11d0, + 0x2011, 0x0020, 0x080c, 0x2adc, 0x0006, 0x0026, 0x0036, 0x080c, + 0x76b7, 0x1158, 0x080c, 0x799f, 0x080c, 0x6178, 0x080c, 0x75cc, + 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, + 0x080c, 0x7671, 0x0016, 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, + 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, + 0x74da, 0x948c, 0xff00, 0x7038, 0xd084, 0x0190, 0x080c, 0xd35d, + 0x1118, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084, 0x1148, 0xc085, + 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x4c28, 0x003e, + 0x080c, 0xd356, 0x1904, 0x2482, 0x9196, 0xff00, 0x05a8, 0x7060, + 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130, + 0xd184, 0x1550, 0x080c, 0x3468, 0x0128, 0xc18d, 0x7132, 0x080c, + 0x6bc5, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248, 0x9294, + 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x2482, + 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, + 0x2482, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, + 0x4c28, 0x003e, 0x0804, 0x2482, 0x7038, 0xd08c, 0x1140, 0x2001, + 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2482, 0xc1ad, 0x2102, 0x0036, + 0x73d8, 0x2011, 0x8013, 0x080c, 0x4c28, 0x003e, 0x7130, 0xc185, + 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009, + 0x0001, 0x2011, 0x0100, 0x080c, 0x8add, 0x2019, 0x000e, 0x00c6, + 0x2061, 0x0000, 0x080c, 0xe701, 0x00ce, 0x9484, 0x00ff, 0x9080, + 0x3474, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, 0x2009, + 0x000e, 0x080c, 0xe795, 0x001e, 0x0016, 0x2009, 0x0002, 0x2019, + 0x0004, 0x080c, 0x32c0, 0x001e, 0x00a8, 0x0156, 0x00b6, 0x20a9, + 0x007f, 0x900e, 0x080c, 0x6783, 0x1140, 0x7030, 0xd084, 0x1118, + 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6192, 0x8108, 0x1f04, 0x2472, + 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xaaf7, 0x080c, 0xadbe, + 0x080c, 0xae87, 0x080c, 0xab13, 0x60e3, 0x0000, 0x001e, 0x2001, + 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11b0, 0x2011, + 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, + 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, 0x2003, + 0x0000, 0x2011, 0x0020, 0x080c, 0x2adc, 0xd194, 0x0904, 0x25a0, + 0x0016, 0x080c, 0xaaf7, 0x6220, 0xd2b4, 0x0904, 0x253b, 0x080c, + 0x88e4, 0x080c, 0xa09b, 0x2011, 0x0004, 0x080c, 0x2adc, 0x00f6, + 0x2019, 0x19f5, 0x2304, 0x907d, 0x0904, 0x2508, 0x7804, 0x9086, + 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, + 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, + 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, + 0x080c, 0x2ab2, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, + 0x080c, 0x2a69, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, + 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x080c, 0x97f6, 0x080c, + 0xab13, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xaf4e, + 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, + 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, + 0x080c, 0x2ab2, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6034, 0x080c, + 0xd35d, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, + 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0xa073, 0x0804, 0x259d, + 0x2061, 0x0100, 0x62c0, 0x080c, 0xaa28, 0x2019, 0x19f5, 0x2304, + 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027, 0x080c, 0xafec, + 0x00ce, 0x0804, 0x259d, 0xd2bc, 0x0904, 0x2580, 0x080c, 0x88f1, + 0x2011, 0x0004, 0x080c, 0x2adc, 0x00d6, 0x2069, 0x0140, 0x6804, + 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x00de, 0x00c6, 0x2061, + 0x19e9, 0x6050, 0x080c, 0xd35d, 0x0120, 0x909a, 0x0003, 0x1668, + 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, 0x6052, 0x604c, 0x00ce, + 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, 0x88e9, 0x9080, 0x0008, + 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011, 0x0012, + 0x080c, 0x2aeb, 0x0450, 0x9080, 0x0008, 0x2004, 0x9086, 0x0009, + 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2aeb, 0x00e8, + 0x2011, 0x0004, 0x080c, 0x2adc, 0x00c0, 0x0036, 0x2019, 0x0001, + 0x080c, 0xa391, 0x003e, 0x2019, 0x19fc, 0x2304, 0x9065, 0x0160, + 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f, + 0x6003, 0x0003, 0x080c, 0xafec, 0x00ce, 0x080c, 0xab13, 0x001e, + 0xd19c, 0x0904, 0x2604, 0x7038, 0xd0ac, 0x1558, 0x0016, 0x0156, + 0x2011, 0x0008, 0x080c, 0x2adc, 0x080c, 0x2aff, 0x080c, 0x2b32, + 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x0f04, 0x25cf, 0x1d04, + 0x25b7, 0x080c, 0x8918, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079, + 0x0100, 0x080c, 0x2a19, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052, + 0x2011, 0x0008, 0x080c, 0x2adc, 0x015e, 0x001e, 0x04a8, 0x015e, + 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7, 0x080c, + 0xadbe, 0x080c, 0xae87, 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c, + 0xebe8, 0x080c, 0xec03, 0x080c, 0x5824, 0xd0fc, 0x1138, 0x080c, + 0xd356, 0x1120, 0x9085, 0x0001, 0x080c, 0x76e1, 0x9006, 0x080c, + 0x2aa2, 0x2009, 0x0002, 0x080c, 0x2a8e, 0x00e6, 0x2071, 0x1800, + 0x7003, 0x0004, 0x080c, 0x0ec7, 0x00ee, 0x2011, 0x0008, 0x080c, + 0x2adc, 0x080c, 0x0bc3, 0x001e, 0x918c, 0xffd0, 0x2110, 0x080c, + 0x2adc, 0x00ae, 0x0005, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4, + 0x001e, 0x0904, 0x23a5, 0x0016, 0x2009, 0x2617, 0x00c0, 0x2001, + 0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, 0x0016, 0x2001, 0x0387, + 0x200c, 0xd1b4, 0x001e, 0x0904, 0x23a5, 0x0016, 0x2009, 0x2629, + 0x0030, 0x2001, 0x0387, 0x2003, 0x4000, 0x001e, 0x08a8, 0x6028, + 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003, + 0xffff, 0x6043, 0x0001, 0x080c, 0x2a88, 0x2011, 0x0080, 0x080c, + 0x2adc, 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016, + 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, + 0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, 0x2699, 0x81ff, 0x01a0, + 0x2009, 0x0000, 0x080c, 0x2a8e, 0x2011, 0x8011, 0x2019, 0x010e, + 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, + 0x0000, 0x080c, 0x4c28, 0x0468, 0x2001, 0x19aa, 0x200c, 0x81ff, + 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, + 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4c28, 0x080c, 0x0ec7, + 0x080c, 0x5824, 0xd0fc, 0x11a8, 0x080c, 0xd356, 0x1190, 0x00c6, + 0x080c, 0x2735, 0x080c, 0xaaf7, 0x080c, 0xa2ec, 0x080c, 0xab13, + 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x32c0, + 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0, + 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011, + 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214, 0x9294, + 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820, 0x2214, + 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c, + 0x83ba, 0x0048, 0x9584, 0x00ff, 0x9080, 0x3474, 0x200d, 0x918c, + 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x3474, 0x200d, 0x918c, + 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, 0x2003, + 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x26e5, + 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, + 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, + 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, + 0xec17, 0x2005, 0x6856, 0x8211, 0x1f04, 0x26fa, 0x002e, 0x00de, + 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d, + 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, + 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180, 0x9112, + 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, + 0x2001, 0x0404, 0x680e, 0x1f04, 0x272a, 0x680f, 0x0000, 0x000e, + 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x5820, 0xd0c4, + 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e, + 0x080c, 0xe795, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, + 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x27a1, 0x080c, 0x2a09, 0x0660, + 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000, 0x900e, + 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e, 0x0420, + 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e, + 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200, + 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100, 0x1548, + 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e, 0x0300, + 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020, 0x2018, + 0x080c, 0x9364, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, + 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, + 0x769d, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e, 0x00fe, + 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184, + 0x0003, 0x0110, 0x080c, 0x0d72, 0x002e, 0x001e, 0x000e, 0x012e, + 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170, + 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c, 0x918c, + 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004, 0x8007, + 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004, 0x8007, + 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c, 0x0018, + 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006, 0x0016, + 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007, 0x1a0c, + 0x0d79, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005, + 0x27ff, 0x281d, 0x2841, 0x2843, 0x286c, 0x286e, 0x2870, 0x2001, + 0x0001, 0x080c, 0x2646, 0x080c, 0x2a53, 0x2001, 0x1993, 0x2003, + 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, + 0x080c, 0x2a25, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, + 0x2011, 0x2871, 0x080c, 0x88f6, 0x0005, 0x2009, 0x1996, 0x200b, + 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a, 0x2003, + 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c, 0x29ba, + 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a25, 0x2001, 0x1991, + 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2871, 0x080c, 0x88f6, + 0x0005, 0x080c, 0x0d79, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, + 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, + 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ba, 0x2001, + 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, + 0x2a25, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, + 0x2871, 0x080c, 0x88f6, 0x0005, 0x080c, 0x0d79, 0x080c, 0x0d79, + 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126, + 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004, 0x908a, + 0x0007, 0x1a0c, 0x0d79, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee, + 0x002e, 0x001e, 0x000e, 0x0005, 0x2893, 0x28af, 0x28eb, 0x2917, + 0x2937, 0x2943, 0x2945, 0x080c, 0x2a19, 0x1190, 0x2009, 0x1999, + 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0xc08d, + 0x0008, 0xc085, 0x200a, 0x2001, 0x1991, 0x2003, 0x0001, 0x0030, + 0x080c, 0x2969, 0x2001, 0xffff, 0x080c, 0x280e, 0x0005, 0x080c, + 0x2947, 0x05c0, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, + 0x2a19, 0x1158, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0518, + 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996, 0x2104, + 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x294f, 0x00c0, + 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110, + 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29d7, 0x2001, 0x1993, + 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003, 0x0010, + 0x080c, 0x2830, 0x0005, 0x080c, 0x2947, 0x0540, 0x2009, 0x199a, + 0x2104, 0x8001, 0x200a, 0x080c, 0x2a19, 0x1148, 0x2001, 0x1991, + 0x2003, 0x0003, 0x2001, 0x1992, 0x2003, 0x0000, 0x00b8, 0x2009, + 0x199a, 0x2104, 0x9005, 0x1118, 0x080c, 0x298c, 0x0010, 0x080c, + 0x295c, 0x080c, 0x294f, 0x2009, 0x1996, 0x200b, 0x0000, 0x2001, + 0x1993, 0x2003, 0x0001, 0x080c, 0x2830, 0x0000, 0x0005, 0x0479, + 0x01e8, 0x080c, 0x2a19, 0x1198, 0x2009, 0x1997, 0x2104, 0x8000, + 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c, 0x2003, + 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038, 0x00f9, + 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x285b, 0x0005, 0x0079, + 0x0148, 0x080c, 0x2a19, 0x1118, 0x080c, 0x2847, 0x0018, 0x0079, + 0x080c, 0x285b, 0x0005, 0x080c, 0x0d79, 0x080c, 0x0d79, 0x2009, + 0x199b, 0x2104, 0x8001, 0x200a, 0x090c, 0x29a8, 0x0005, 0x7a38, + 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x29d7, 0x0005, 0x7a38, 0x9294, 0x0006, 0x9296, + 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ba, + 0x0005, 0x2009, 0x1996, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, + 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, + 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x04d9, 0x7a38, + 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x29d7, 0x0005, 0x0086, 0x2001, 0x1999, 0x2004, + 0x9084, 0x7fff, 0x090c, 0x0d79, 0x2009, 0x1998, 0x2144, 0x8846, + 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, 0x1120, 0x080c, + 0x0d79, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e, 0x0005, + 0x0006, 0x0156, 0x2001, 0x1991, 0x20a9, 0x0009, 0x2003, 0x0000, + 0x8000, 0x1f04, 0x29ae, 0x2001, 0x1998, 0x2003, 0x8000, 0x015e, + 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, + 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, 0x2009, 0x199e, + 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0006, + 0x783a, 0x2009, 0x199f, 0x210c, 0x795a, 0x00fe, 0x0005, 0x00f6, + 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfffa, + 0x9085, 0x0004, 0x783a, 0x7850, 0x9084, 0xfff0, 0x7852, 0x00f8, + 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x7850, 0x9084, + 0xfff0, 0x0016, 0x2009, 0x017f, 0x210c, 0x918e, 0x0005, 0x0140, + 0x2009, 0x0003, 0x210c, 0x918c, 0x0600, 0x918e, 0x0400, 0x0118, + 0x9085, 0x000a, 0x0010, 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, + 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, + 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, + 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2a88, 0xd09c, + 0x1110, 0x1f04, 0x2a1c, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, + 0x2091, 0x8000, 0x000e, 0x2008, 0x9186, 0x0000, 0x1118, 0x783b, + 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, 0x0006, 0x0060, + 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, 0x9186, 0x0003, + 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, 0x2a45, 0x080c, + 0x8918, 0x1f04, 0x2a45, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, + 0x001e, 0x012e, 0x0005, 0x080c, 0x2b32, 0x0005, 0x0006, 0x0156, + 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1100, + 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a60, 0x00fe, 0x015e, 0x000e, + 0x0005, 0x1d04, 0x2a69, 0x080c, 0x8918, 0x1f04, 0x2a69, 0x0005, + 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, + 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, + 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, + 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, + 0x19aa, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, + 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, + 0x200a, 0x0005, 0x0016, 0x0026, 0x080c, 0x76b7, 0x0108, 0xc0bc, + 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, + 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, + 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, + 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, + 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, + 0x2104, 0x1128, 0x080c, 0x76b7, 0x0110, 0xc0bc, 0x0008, 0xc0bd, + 0x200a, 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, + 0x0101, 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202, 0x7843, + 0x0100, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, 0x0202, + 0x7844, 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104, 0x9205, + 0x7a16, 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084, 0xfbff, + 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a69, 0x6050, + 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, 0x080c, + 0x2a69, 0x6054, 0xd0bc, 0x090c, 0x0d79, 0x20a9, 0x0005, 0x080c, + 0x2a69, 0x6054, 0xd0ac, 0x090c, 0x0d79, 0x2009, 0x19b1, 0x9084, + 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050, 0xc0cd, + 0x6052, 0x00ce, 0x000e, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x0006, + 0x2061, 0x0100, 0x2069, 0x0140, 0x6030, 0x0006, 0x6048, 0x0006, + 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60ec, 0x0006, + 0x600c, 0x0006, 0x6004, 0x0006, 0xc0fc, 0x6006, 0x2009, 0x0800, + 0x2001, 0x0338, 0x2003, 0x0301, 0x8109, 0x090c, 0x0d79, 0x2001, + 0x0338, 0x2004, 0xd084, 0x1dc0, 0x6028, 0x0006, 0x60e0, 0x0006, + 0x6888, 0x0006, 0x688c, 0x0006, 0x6890, 0x0006, 0x080c, 0x769d, + 0x1110, 0x6884, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xa001, + 0xa001, 0xa001, 0xa001, 0x602f, 0x0040, 0x602f, 0x0000, 0x080c, + 0x769d, 0x1120, 0x6803, 0x0080, 0x000e, 0x6886, 0x6897, 0x4198, + 0x000e, 0x6892, 0x000e, 0x688e, 0x000e, 0x688a, 0x000e, 0x60e2, + 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, + 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, 0x604a, + 0x000e, 0x6032, 0x6036, 0x2008, 0x080c, 0x26ea, 0x000e, 0x00de, + 0x00ce, 0x001e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, 0x0040, + 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2a88, 0x9085, + 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2bbc, 0x080c, 0x8918, + 0x1f04, 0x2bbc, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, + 0x015e, 0x000e, 0x0005, 0x30c7, 0x30c7, 0x2ccb, 0x2ccb, 0x2cd7, + 0x2cd7, 0x2ce3, 0x2ce3, 0x2cf1, 0x2cf1, 0x2cfd, 0x2cfd, 0x2d0b, + 0x2d0b, 0x2d19, 0x2d19, 0x2d2b, 0x2d2b, 0x2d37, 0x2d37, 0x2d45, + 0x2d45, 0x2d63, 0x2d63, 0x2d83, 0x2d83, 0x2d53, 0x2d53, 0x2d73, + 0x2d73, 0x2d91, 0x2d91, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2da3, 0x2da3, 0x2daf, 0x2daf, 0x2dbd, + 0x2dbd, 0x2dcb, 0x2dcb, 0x2ddb, 0x2ddb, 0x2de9, 0x2de9, 0x2df9, + 0x2df9, 0x2e09, 0x2e09, 0x2e1b, 0x2e1b, 0x2e29, 0x2e29, 0x2e39, + 0x2e39, 0x2e5b, 0x2e5b, 0x2e7f, 0x2e7f, 0x2e49, 0x2e49, 0x2e6d, + 0x2e6d, 0x2e8f, 0x2e8f, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2ea3, 0x2ea3, 0x2eaf, 0x2eaf, 0x2ebd, + 0x2ebd, 0x2ecb, 0x2ecb, 0x2edb, 0x2edb, 0x2ee9, 0x2ee9, 0x2ef9, + 0x2ef9, 0x2f09, 0x2f09, 0x2f1b, 0x2f1b, 0x2f29, 0x2f29, 0x2f39, + 0x2f39, 0x2f49, 0x2f49, 0x2f5b, 0x2f5b, 0x2f6b, 0x2f6b, 0x2f7d, + 0x2f7d, 0x2f8f, 0x2f8f, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2fa3, 0x2fa3, 0x2fb1, 0x2fb1, 0x2fc1, + 0x2fc1, 0x2fd1, 0x2fd1, 0x2fe3, 0x2fe3, 0x2ff3, 0x2ff3, 0x3005, + 0x3005, 0x3017, 0x3017, 0x302b, 0x302b, 0x303b, 0x303b, 0x304d, + 0x304d, 0x305f, 0x305f, 0x3073, 0x3073, 0x3084, 0x3084, 0x3097, + 0x3097, 0x30aa, 0x30aa, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, + 0x2d29, 0x2d29, 0x2d29, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2107, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804, + 0x30bf, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, + 0x2107, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, + 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, + 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, + 0x2107, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0xab5d, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, + 0xab5d, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, + 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, + 0xab5d, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x0804, + 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, + 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x22dd, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, + 0x2107, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, + 0x2107, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, + 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, + 0x13c8, 0x080c, 0x2131, 0x04d8, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, + 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0440, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x27a4, 0x080c, 0x2107, 0x080c, 0x13c8, 0x080c, 0xab5d, 0x080c, + 0x2131, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, + 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0000, 0x015e, + 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d, + 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6b8b, 0x1904, + 0x31dc, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110, 0xd29c, + 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x31dc, 0x080c, 0x31e1, + 0x0804, 0x31dc, 0xd2cc, 0x1904, 0x31dc, 0x080c, 0x769d, 0x1120, + 0x70af, 0xffff, 0x0804, 0x31dc, 0xd294, 0x0120, 0x70af, 0xffff, + 0x0804, 0x31dc, 0x080c, 0x3463, 0x0160, 0x080c, 0xd35d, 0x0128, + 0x2001, 0x1818, 0x203c, 0x0804, 0x3165, 0x70af, 0xffff, 0x0804, + 0x31dc, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, 0x3165, + 0xd28c, 0x1904, 0x3165, 0x0036, 0x73ac, 0x938e, 0xffff, 0x1110, + 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0x938c, 0x0001, + 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x970e, + 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150, 0x7230, + 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff, 0x003e, + 0x04a0, 0x900e, 0x080c, 0x26a1, 0x080c, 0x6718, 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, - 0x8eee, 0x00ce, 0x090c, 0x928d, 0xb8af, 0x0000, 0x080c, 0x6c11, - 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, - 0xd28c, 0x0180, 0x080c, 0x6c11, 0x9082, 0x0006, 0x02e0, 0xd484, - 0x1118, 0x080c, 0x676e, 0x0028, 0x080c, 0x33f3, 0x01a0, 0x080c, - 0x341e, 0x0088, 0x080c, 0x3360, 0x080c, 0xd645, 0x1160, 0x080c, - 0x3240, 0x0188, 0x0040, 0x080c, 0xd645, 0x1118, 0x080c, 0x33f3, - 0x0110, 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x3188, - 0x70af, 0xffff, 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, - 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, - 0x007e, 0x080c, 0x6749, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, - 0x080c, 0x3360, 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, - 0xd389, 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, - 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xb1dd, - 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd3b6, 0x6023, 0x0001, 0x9006, - 0x080c, 0x66e6, 0x2001, 0x0000, 0x080c, 0x66fa, 0x0126, 0x2091, - 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, - 0xb20a, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, - 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, - 0x00ff, 0xb842, 0x080c, 0xb1dd, 0x0548, 0x2b00, 0x6012, 0xb800, - 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, - 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c, 0x3315, 0x080c, 0xd3b6, - 0x6023, 0x0001, 0x9006, 0x080c, 0x66e6, 0x2001, 0x0002, 0x080c, - 0x66fa, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, - 0x2009, 0x0002, 0x080c, 0xb20a, 0x9085, 0x0001, 0x00ce, 0x00de, - 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, - 0x080c, 0x6749, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, - 0x0110, 0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, - 0x0076, 0x00d6, 0x00c6, 0x080c, 0xb116, 0x01d0, 0x2b00, 0x6012, - 0x080c, 0xd3b6, 0x6023, 0x0001, 0x9006, 0x080c, 0x66e6, 0x2001, - 0x0002, 0x080c, 0x66fa, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, - 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c, 0xb20a, 0x9085, 0x0001, - 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, - 0x2091, 0x8000, 0x2009, 0x007f, 0x080c, 0x6749, 0x11b8, 0xb813, - 0x00ff, 0xb817, 0xfffd, 0xb8d7, 0x0004, 0x080c, 0xb116, 0x0170, - 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd3b6, - 0x2009, 0x0022, 0x080c, 0xb20a, 0x9085, 0x0001, 0x012e, 0x00de, - 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, - 0x21f0, 0x080c, 0xacfc, 0x0106, 0x080c, 0x97bb, 0x080c, 0x9727, - 0x080c, 0xac4d, 0x080c, 0xc179, 0x010e, 0x090c, 0xad18, 0x3e08, - 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, - 0x007f, 0x900e, 0x0016, 0x080c, 0x67b4, 0x1140, 0x9686, 0x0002, - 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x61b7, 0x001e, 0x8108, - 0x1f04, 0x32fa, 0x9686, 0x0001, 0x190c, 0x3451, 0x00be, 0x002e, - 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, - 0x0036, 0x0026, 0x0016, 0x00b6, 0x080c, 0xacfc, 0x0106, 0x6210, - 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x97b0, 0x0076, - 0x2039, 0x0000, 0x080c, 0x966d, 0x2c08, 0x080c, 0xe75d, 0x007e, - 0x001e, 0x010e, 0x090c, 0xad18, 0xba10, 0xbb14, 0xbc84, 0x080c, - 0x61b7, 0xba12, 0xbb16, 0xbc86, 0x00be, 0x001e, 0x002e, 0x003e, - 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, - 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, - 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005, - 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8, - 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, - 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x080c, 0xacfc, - 0x0106, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x5840, - 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, - 0x080c, 0xea8d, 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, - 0x0904, 0x33cf, 0x928e, 0x007f, 0x0904, 0x33cf, 0x928e, 0x0080, - 0x05f0, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c8, 0x8fff, 0x1150, - 0x2001, 0x198e, 0x0006, 0x2003, 0x0001, 0x080c, 0x33e0, 0x000e, - 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, - 0x6bdb, 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x97b0, 0x0076, - 0x2039, 0x0000, 0x080c, 0x966d, 0x00b6, 0x00c6, 0x0026, 0x2158, - 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, - 0x0028, 0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, - 0x00be, 0x0016, 0x2c08, 0x080c, 0xe75d, 0x001e, 0x007e, 0x002e, - 0x8210, 0x1f04, 0x3385, 0x010e, 0x090c, 0xad18, 0x015e, 0x001e, - 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005, - 0x0046, 0x0026, 0x0016, 0x080c, 0x5840, 0xd0c4, 0x0140, 0xd0a4, - 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xea8d, 0x001e, - 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7294, - 0x82ff, 0x01e8, 0x080c, 0x6c09, 0x11d0, 0x2100, 0x080c, 0x26bf, - 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, - 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, - 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, - 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x080c, 0xacfc, 0x0106, 0x0036, 0x2019, - 0x0029, 0x00c1, 0x003e, 0x010e, 0x090c, 0xad18, 0x9180, 0x1000, - 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061, 0x1b39, 0x001e, - 0x6112, 0x080c, 0x3315, 0x001e, 0x080c, 0x676e, 0x012e, 0x00ce, - 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c, 0xa7e2, 0x080c, - 0xedee, 0x002e, 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, - 0x0005, 0x00c6, 0x00b6, 0x080c, 0x779e, 0x1118, 0x20a9, 0x0800, - 0x0010, 0x20a9, 0x0782, 0x080c, 0x779e, 0x1110, 0x900e, 0x0010, - 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, - 0x0110, 0xb800, 0xd0bc, 0x090c, 0x676e, 0x8108, 0x1f04, 0x3462, - 0x2061, 0x1800, 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, - 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, - 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, - 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, - 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, - 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, - 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, - 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, - 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, - 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, - 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, - 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, - 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, - 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, - 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, - 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, - 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, - 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, - 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, - 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, - 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, - 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, - 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, - 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, - 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, - 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, - 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, - 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, - 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, - 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, + 0x8d87, 0x00ce, 0x090c, 0x9128, 0xb8af, 0x0000, 0x080c, 0x6bcd, + 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, + 0x6a74, 0x0120, 0x080c, 0x31fa, 0x0148, 0x0028, 0x080c, 0x3346, + 0x080c, 0x3226, 0x0118, 0x8318, 0x0804, 0x3112, 0x73ae, 0x0010, + 0x70af, 0xffff, 0x003e, 0x0804, 0x31dc, 0x9780, 0x3474, 0x203d, + 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096, 0xffff, + 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802, + 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x31dc, 0x2700, 0x0156, + 0x0016, 0x9106, 0x0904, 0x31d1, 0xc484, 0x080c, 0x6783, 0x0168, + 0x080c, 0xd35d, 0x1904, 0x31d1, 0x080c, 0x3463, 0x1904, 0x31d1, + 0x080c, 0x6718, 0x1904, 0x31d9, 0x0008, 0xc485, 0xb8bb, 0x0520, + 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8d87, 0x00ce, + 0x090c, 0x9128, 0xb8af, 0x0000, 0x080c, 0x6bcd, 0x1130, 0x7030, + 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, + 0x080c, 0x6bcd, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, + 0x673d, 0x0028, 0x080c, 0x33d9, 0x01a0, 0x080c, 0x3404, 0x0088, + 0x080c, 0x3346, 0x080c, 0xd35d, 0x1160, 0x080c, 0x3226, 0x0188, + 0x0040, 0x080c, 0xd35d, 0x1118, 0x080c, 0x33d9, 0x0110, 0x0451, + 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x317e, 0x70af, 0xffff, + 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, + 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, 0x007e, 0x080c, + 0x6718, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x3346, + 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd0a1, 0x001e, + 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, + 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xafbf, 0x01d0, 0x2b00, + 0x6012, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x9006, 0x080c, 0x66b5, + 0x2001, 0x0000, 0x080c, 0x66c9, 0x0126, 0x2091, 0x8000, 0x70a8, + 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, 0xafec, 0x9085, + 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, + 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, + 0x080c, 0xafbf, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, + 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x1110, 0x080c, 0x32fb, 0x080c, 0xd0ce, 0x6023, 0x0001, + 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9, 0x0126, + 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, + 0x080c, 0xafec, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, + 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6718, + 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, + 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, + 0x00c6, 0x080c, 0xaef8, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0ce, + 0x6023, 0x0001, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, + 0x66c9, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, + 0x2009, 0x0002, 0x080c, 0xafec, 0x9085, 0x0001, 0x00ce, 0x00de, + 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, + 0x2009, 0x007f, 0x080c, 0x6718, 0x11b8, 0xb813, 0x00ff, 0xb817, + 0xfffd, 0xb8d7, 0x0004, 0x080c, 0xaef8, 0x0170, 0x2b00, 0x6012, + 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd0ce, 0x2009, 0x0022, + 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, + 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, + 0xaaf7, 0x0106, 0x080c, 0x95c4, 0x080c, 0x9530, 0x080c, 0xaa48, + 0x080c, 0xbeab, 0x010e, 0x090c, 0xab13, 0x3e08, 0x2130, 0x81ff, + 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, + 0x0016, 0x080c, 0x6783, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800, + 0xd0bc, 0x1110, 0x080c, 0x6192, 0x001e, 0x8108, 0x1f04, 0x32e0, + 0x9686, 0x0001, 0x190c, 0x3437, 0x00be, 0x002e, 0x003e, 0x006e, + 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, + 0x0016, 0x00b6, 0x080c, 0xaaf7, 0x0106, 0x6210, 0x2258, 0xbaa0, + 0x0026, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x2039, 0x0000, + 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465, 0x007e, 0x001e, 0x010e, + 0x090c, 0xab13, 0xba10, 0xbb14, 0xbc84, 0x080c, 0x6192, 0xba12, + 0xbb16, 0xbc86, 0x00be, 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, + 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, + 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, + 0x0110, 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, + 0x70e4, 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, + 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, + 0x0026, 0x0016, 0x0156, 0x2178, 0x080c, 0xaaf7, 0x0106, 0x81ff, + 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x5820, 0xd0c4, 0x0140, + 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xe795, + 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x33b5, + 0x928e, 0x007f, 0x0904, 0x33b5, 0x928e, 0x0080, 0x05f0, 0x9288, + 0x1000, 0x210c, 0x81ff, 0x05c8, 0x8fff, 0x1150, 0x2001, 0x198f, + 0x0006, 0x2003, 0x0001, 0x080c, 0x33c6, 0x000e, 0x2003, 0x0000, + 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6b97, 0x00ce, + 0x00be, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x2039, 0x0000, + 0x080c, 0x9476, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, + 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, + 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, + 0x2c08, 0x080c, 0xe465, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, + 0x336b, 0x010e, 0x090c, 0xab13, 0x015e, 0x001e, 0x002e, 0x003e, + 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, + 0x0016, 0x080c, 0x5820, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, + 0x2220, 0x2009, 0x0029, 0x080c, 0xe795, 0x001e, 0x002e, 0x004e, + 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, + 0x080c, 0x6bc5, 0x11d0, 0x2100, 0x080c, 0x26d4, 0x81ff, 0x01b8, + 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0xd384, 0x0120, + 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, + 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xaaf7, 0x0106, 0x0036, 0x2019, 0x0029, 0x00c1, + 0x003e, 0x010e, 0x090c, 0xab13, 0x9180, 0x1000, 0x2004, 0x9065, + 0x0158, 0x0016, 0x00c6, 0x2061, 0x1b3a, 0x001e, 0x6112, 0x080c, + 0x32fb, 0x001e, 0x080c, 0x673d, 0x012e, 0x00ce, 0x001e, 0x0005, + 0x0016, 0x0026, 0x2110, 0x080c, 0xa5dd, 0x080c, 0xeafd, 0x002e, + 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, + 0x00b6, 0x080c, 0x769d, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, + 0x0782, 0x080c, 0x769d, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, + 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, + 0xd0bc, 0x090c, 0x673d, 0x8108, 0x1f04, 0x3448, 0x2061, 0x1800, + 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, + 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, + 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, + 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, + 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, + 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, + 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, + 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, + 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, + 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, + 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, + 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, + 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, + 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, + 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, + 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, + 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, + 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, + 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, + 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, + 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, + 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, + 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, + 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, + 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, + 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, + 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, + 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, + 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, + 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, + 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, - 0x7003, 0x0002, 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, - 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, - 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900, 0x706a, 0xa867, 0x0002, - 0xa8ab, 0xdcb0, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900, 0x706e, - 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, - 0x0002, 0x35bd, 0x35be, 0x35d1, 0x35e5, 0x0005, 0x1004, 0x35ce, - 0x0e04, 0x35ce, 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, - 0x9005, 0x1128, 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, - 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, - 0x0100, 0x0128, 0x9086, 0x0200, 0x0904, 0x36b9, 0x0005, 0x7018, - 0x2048, 0x2061, 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, - 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, - 0x0005, 0x9086, 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, - 0x1800, 0x701c, 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, - 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x36b6, - 0x61d0, 0x0804, 0x364b, 0x368d, 0x36c5, 0x36b6, 0x36d1, 0x36db, - 0x36e1, 0x36e5, 0x36f5, 0x36f9, 0x370f, 0x3715, 0x371b, 0x3726, - 0x3731, 0x3740, 0x374f, 0x375d, 0x3774, 0x378f, 0x36b6, 0x383a, - 0x3878, 0x391d, 0x392e, 0x3951, 0x36b6, 0x36b6, 0x36b6, 0x3989, - 0x39a9, 0x39b2, 0x39de, 0x39e4, 0x36b6, 0x3a2a, 0x36b6, 0x36b6, - 0x36b6, 0x36b6, 0x36b6, 0x3a35, 0x3a3e, 0x3a46, 0x3a48, 0x36b6, - 0x36b6, 0x36b6, 0x36b6, 0x36b6, 0x36b6, 0x3a78, 0x36b6, 0x36b6, - 0x36b6, 0x36b6, 0x36b6, 0x3a95, 0x3b19, 0x36b6, 0x36b6, 0x36b6, - 0x36b6, 0x36b6, 0x36b6, 0x0002, 0x3b43, 0x3b46, 0x3ba5, 0x3bbe, - 0x3bee, 0x3e94, 0x36b6, 0x53f5, 0x36b6, 0x36b6, 0x36b6, 0x36b6, - 0x36b6, 0x36b6, 0x36b6, 0x36b6, 0x370f, 0x3715, 0x4397, 0x5864, - 0x43b5, 0x5484, 0x54d6, 0x55e1, 0x36b6, 0x5643, 0x567f, 0x56b0, - 0x57c0, 0x56dd, 0x5740, 0x36b6, 0x43b9, 0x457f, 0x4595, 0x45ba, - 0x461f, 0x4693, 0x46b3, 0x472a, 0x4786, 0x47e2, 0x47e5, 0x480a, - 0x487c, 0x48e6, 0x48ee, 0x4a23, 0x4bcb, 0x4bff, 0x4e63, 0x36b6, - 0x4e81, 0x4f48, 0x5031, 0x508b, 0x36b6, 0x511e, 0x36b6, 0x5134, - 0x514f, 0x48ee, 0x5395, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, - 0x4c7d, 0x0126, 0x2091, 0x8000, 0x0e04, 0x3697, 0x0010, 0x012e, - 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, - 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x7007, 0x0001, - 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, - 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, - 0x4005, 0x0868, 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, - 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, - 0x4c8a, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, - 0x7990, 0x0804, 0x4c8d, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, - 0x368d, 0x7984, 0x2114, 0x0804, 0x368d, 0x20e1, 0x0000, 0x2099, - 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, - 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x368d, 0x7884, 0x2060, 0x0804, - 0x3742, 0x2009, 0x0003, 0x2011, 0x0003, 0x2019, 0x0014, 0x789b, - 0x0137, 0x7893, 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, - 0x7896, 0x0804, 0x368d, 0x7897, 0x0001, 0x0804, 0x368d, 0x2039, - 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x36c9, 0x2039, 0x0001, 0x7d98, - 0x7c9c, 0x0804, 0x36d5, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, - 0x36c2, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x36c9, 0x79a0, 0x9182, - 0x0040, 0x0210, 0x0804, 0x36c2, 0x2138, 0x7d98, 0x7c9c, 0x0804, - 0x36d5, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36c2, 0x21e8, - 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x368d, - 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, - 0x1dd8, 0x2010, 0x9005, 0x0904, 0x368d, 0x0804, 0x36bc, 0x79a0, - 0x9182, 0x0040, 0x0210, 0x0804, 0x36c2, 0x21e0, 0x20a9, 0x0001, - 0x7984, 0x2198, 0x4012, 0x0804, 0x368d, 0x2069, 0x1847, 0x7884, - 0x7990, 0x911a, 0x1a04, 0x36c2, 0x8019, 0x0904, 0x36c2, 0x684a, - 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, - 0x080c, 0x7ae7, 0x0804, 0x368d, 0x2069, 0x1847, 0x7884, 0x7994, - 0x911a, 0x1a04, 0x36c2, 0x8019, 0x0904, 0x36c2, 0x684e, 0x6946, - 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, - 0x2091, 0x8000, 0x080c, 0x6d66, 0x012e, 0x0804, 0x368d, 0x902e, - 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, 0x7984, - 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, - 0x4101, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, - 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c8a, - 0x701f, 0x37b3, 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, - 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, - 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, 0x1904, 0x36bf, 0x810f, - 0x918c, 0x00ff, 0x0904, 0x36bf, 0x7112, 0x7010, 0x8001, 0x0560, - 0x7012, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, - 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, - 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, - 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c8a, 0x701f, 0x37f1, - 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, - 0x000a, 0x1904, 0x36bf, 0x0888, 0x0126, 0x2091, 0x8000, 0x7014, - 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, - 0x0029, 0x1148, 0xc2fd, 0xaa7a, 0x080c, 0x630a, 0x0138, 0xa87a, - 0xa982, 0x012e, 0x0060, 0x080c, 0x663a, 0x1130, 0x7007, 0x0003, - 0x701f, 0x381f, 0x012e, 0x0005, 0x080c, 0x725e, 0x012e, 0x0126, - 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, 0x18a6, - 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, - 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, 0xaf60, - 0x0804, 0x4c8d, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, 0x0010, - 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, 0x2020, - 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, 0x0100, - 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, 0x2009, - 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a25, 0x2004, 0x9005, - 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, - 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, 0x0427, - 0x81ff, 0x1904, 0x36bf, 0x7984, 0x080c, 0x67b4, 0x1904, 0x36c2, - 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x36c2, 0x7c88, - 0x7d8c, 0x080c, 0x69f1, 0x080c, 0x697e, 0x1518, 0x2061, 0x1ddc, - 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, - 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0150, - 0x012e, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a04, - 0x36bf, 0x0c30, 0x080c, 0xcae9, 0x012e, 0x0904, 0x36bf, 0x0804, - 0x368d, 0x900e, 0x2001, 0x0005, 0x080c, 0x725e, 0x0126, 0x2091, - 0x8000, 0x080c, 0xd226, 0x080c, 0x7012, 0x012e, 0x0804, 0x368d, - 0x00a6, 0x2950, 0xb198, 0x080c, 0x67b4, 0x1904, 0x390a, 0xb6a4, - 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c, - 0x69f1, 0x080c, 0x697e, 0x1520, 0x2061, 0x1ddc, 0x0126, 0x2091, - 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, - 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e, 0x9ce0, - 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0, - 0x0c28, 0x080c, 0xcae9, 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0, - 0x900e, 0x2001, 0x0005, 0x080c, 0x725e, 0x0126, 0x2091, 0x8000, - 0x080c, 0xd226, 0x080c, 0x7006, 0x012e, 0x0070, 0xb097, 0x4005, - 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, - 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006, 0x918d, - 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904, 0x36bf, - 0x080c, 0x4c58, 0x0904, 0x36c2, 0x080c, 0x687b, 0x0904, 0x36bf, - 0x080c, 0x69f7, 0x0904, 0x36bf, 0x0804, 0x46aa, 0x81ff, 0x1904, - 0x36bf, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x080c, 0x6a85, 0x0904, - 0x36bf, 0x2019, 0x0005, 0x79a8, 0x080c, 0x6a12, 0x0904, 0x36bf, - 0x7888, 0x908a, 0x1000, 0x1a04, 0x36c2, 0x8003, 0x800b, 0x810b, - 0x9108, 0x080c, 0x89a1, 0x79a8, 0xd184, 0x1904, 0x368d, 0x0804, - 0x46aa, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, - 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8, 0x2508, - 0x080c, 0x67b4, 0x11d8, 0x080c, 0x6a85, 0x1128, 0x2009, 0x0002, - 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c, 0x6a12, - 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000, 0x1270, - 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x89a1, 0x8529, 0x1ae0, - 0x012e, 0x0804, 0x368d, 0x012e, 0x0804, 0x36bf, 0x012e, 0x0804, - 0x36c2, 0x080c, 0x4c58, 0x0904, 0x36c2, 0x080c, 0x687b, 0x0904, - 0x36bf, 0x080c, 0xacfc, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, - 0x080c, 0x97b0, 0x0076, 0x903e, 0x080c, 0x966d, 0x900e, 0x080c, - 0xe75d, 0x007e, 0x00ce, 0x080c, 0xad18, 0x080c, 0x69f1, 0x0804, - 0x368d, 0x080c, 0x4c58, 0x0904, 0x36c2, 0x080c, 0x69f1, 0x2208, - 0x0804, 0x368d, 0x0156, 0x00d6, 0x00e6, 0x00c6, 0x2069, 0x1910, - 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, - 0x2071, 0x19e8, 0x7028, 0x9065, 0x0118, 0x8210, 0x600c, 0x0cd8, - 0x2300, 0x9218, 0x00ce, 0x00ee, 0x00de, 0x015e, 0x0804, 0x368d, - 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, - 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0x1910, - 0x6910, 0x62bc, 0x0804, 0x368d, 0x81ff, 0x0120, 0x2009, 0x0001, - 0x0804, 0x36bf, 0x0126, 0x2091, 0x8000, 0x080c, 0x5854, 0x0128, - 0x2009, 0x0007, 0x012e, 0x0804, 0x36bf, 0x012e, 0x615c, 0x9190, - 0x348e, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108, 0x6280, - 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, 0x0001, - 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, 0x0003, - 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, 0x0002, - 0x0068, 0x080c, 0x779e, 0x1118, 0x2031, 0x0004, 0x0038, 0xd79c, - 0x0120, 0x2009, 0x0005, 0x0804, 0x36bf, 0x9036, 0x7e9a, 0x7f9e, - 0x0804, 0x368d, 0x614c, 0x6250, 0x2019, 0x1986, 0x231c, 0x2001, - 0x1987, 0x2004, 0x789a, 0x0804, 0x368d, 0x0126, 0x2091, 0x8000, - 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x368d, 0x080c, 0x4c74, - 0x0904, 0x36c2, 0xba44, 0xbb38, 0x0804, 0x368d, 0x080c, 0x0d85, - 0x080c, 0x4c74, 0x2110, 0x0904, 0x36c2, 0xb804, 0x908c, 0x00ff, - 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, 0x2009, - 0x0009, 0x1904, 0x36bf, 0x0126, 0x2091, 0x8000, 0x2019, 0x0005, - 0x00c6, 0x9066, 0x080c, 0xacfc, 0x080c, 0xa7e2, 0x080c, 0x97b0, - 0x0076, 0x903e, 0x080c, 0x966d, 0x900e, 0x080c, 0xe75d, 0x007e, - 0x00ce, 0x080c, 0xad18, 0xb807, 0x0407, 0x012e, 0x0804, 0x368d, - 0x614c, 0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, - 0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x1986, 0x2d1c, 0x206a, - 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1987, - 0x2d04, 0x266a, 0x789a, 0x0804, 0x368d, 0x0126, 0x2091, 0x8000, - 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0eeb, 0xd0c4, - 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199d, 0x200a, 0x78ac, 0x2011, - 0x199e, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, - 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x7888, 0xd0ec, - 0x0178, 0x6034, 0xc08d, 0x6036, 0x2001, 0x0050, 0x6076, 0x607a, - 0x6056, 0x606b, 0x269c, 0x00c6, 0x2061, 0x1b73, 0x2062, 0x00ce, - 0x2011, 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, - 0x0010, 0x918c, 0xff7f, 0x2112, 0x6134, 0xd18c, 0x2001, 0x0000, - 0x0108, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c, 0x6042, - 0x6234, 0xd28c, 0x0120, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, - 0xd1e4, 0x190c, 0x0f06, 0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, - 0x9084, 0x0001, 0x090c, 0x4397, 0x6040, 0xd0cc, 0x0120, 0x78b0, - 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x368d, 0x00f6, 0x2079, - 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, - 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, - 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, - 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x36c2, - 0x788c, 0x902d, 0x0904, 0x36c2, 0x900e, 0x080c, 0x67b4, 0x1120, - 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, - 0x0ca0, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x7888, 0x900d, 0x0904, - 0x36c2, 0x788c, 0x9005, 0x0904, 0x36c2, 0xba44, 0xb946, 0xbb38, - 0xb83a, 0x0804, 0x368d, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, - 0x080c, 0x5854, 0x1904, 0x36bf, 0x00c6, 0x2061, 0x0100, 0x7984, - 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, 0xff00, - 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x348e, 0x210d, 0x918c, - 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, - 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0xb116, - 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x674f, - 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4c41, - 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, - 0xa86a, 0x701f, 0x3b9e, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, - 0xb20a, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x36bf, - 0x00ce, 0x0804, 0x36c2, 0x080c, 0xb16c, 0x0cb0, 0xa830, 0x9086, - 0x0100, 0x0904, 0x36bf, 0x0804, 0x368d, 0x2061, 0x1a73, 0x0126, - 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, - 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, - 0x012e, 0x0804, 0x368d, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, - 0x36bf, 0x080c, 0x779e, 0x0904, 0x36bf, 0x0126, 0x2091, 0x8000, - 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x26f5, - 0x080c, 0x5a7c, 0x012e, 0x0804, 0x368d, 0x012e, 0x0804, 0x36c2, - 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070, 0x2061, - 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x955b, - 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, - 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x368f, - 0x7884, 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, - 0x9082, 0x00e1, 0x0298, 0x012e, 0x0804, 0x36c2, 0x2001, 0x002a, - 0x2004, 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, 0x1230, - 0x012e, 0x0804, 0x36c2, 0x012e, 0x0804, 0x36bf, 0x080c, 0xb094, - 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3c6d, 0x00c6, 0x080c, 0x4c41, - 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, - 0x789c, 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, - 0x2004, 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, - 0x2004, 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, - 0x2004, 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, - 0x00fc, 0x8004, 0xa816, 0x080c, 0x3df7, 0x0928, 0x7014, 0x2048, - 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, - 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c8a, 0x701f, - 0x3d34, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c, 0xacfc, 0x0046, - 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x080c, 0x3bd8, 0x2001, 0x19a0, 0x2003, 0x0000, 0x2021, 0x000a, - 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, - 0x60bf, 0x0012, 0x080c, 0x3e66, 0x080c, 0x3e25, 0x00f6, 0x00e6, - 0x0086, 0x2940, 0x2071, 0x19e8, 0x2079, 0x0090, 0x00d6, 0x2069, - 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, - 0x2001, 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, - 0x41db, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40fd, 0x080c, 0x402a, - 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, - 0x424f, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, - 0x1560, 0x2071, 0x0200, 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, - 0x9086, 0x3200, 0x1510, 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, - 0x9086, 0xe100, 0x11d0, 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, - 0x715c, 0x9106, 0x1190, 0x2001, 0x1820, 0x2004, 0x9106, 0x1168, - 0x00c6, 0x2061, 0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, - 0x080c, 0x4034, 0x080c, 0x3e20, 0x0058, 0x080c, 0x3e20, 0x080c, - 0x4173, 0x080c, 0x40f3, 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, - 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, - 0x001e, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, - 0x60bf, 0x0108, 0x60bf, 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, - 0xfffd, 0x2102, 0x080c, 0x1352, 0x2009, 0x0028, 0x080c, 0x2220, - 0x2001, 0x0227, 0x200c, 0x2102, 0x080c, 0xad18, 0x00fe, 0x00ee, - 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e, 0x2001, - 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x368d, 0x012e, - 0x2021, 0x400c, 0x0804, 0x368f, 0x0016, 0x0026, 0x0036, 0x0046, - 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014, 0x2048, - 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904, 0x3d90, - 0x2048, 0x1f04, 0x3d44, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, - 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, - 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, 0x9086, 0x0103, - 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, - 0x9080, 0x001b, 0x080c, 0x4c8a, 0x701f, 0x3d34, 0x00b0, 0x8906, - 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, - 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fd6, - 0x000e, 0x080c, 0x4c8d, 0x701f, 0x3d34, 0x015e, 0x00de, 0x009e, - 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, - 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f, 0x3df5, - 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009, 0x007f, - 0x080c, 0x6749, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff, 0xb817, - 0xfffd, 0x080c, 0xd409, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, - 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x36bf, 0x0016, - 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, - 0x0156, 0x701f, 0x3dc7, 0x7007, 0x0003, 0x0804, 0x3d85, 0xa830, - 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x368f, 0x0076, 0xad10, - 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, - 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, 0x7003, 0x0002, + 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, + 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, 0x080c, 0x1066, + 0x090c, 0x0d79, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, + 0x080c, 0x1066, 0x090c, 0x0d79, 0x2900, 0x706e, 0xa867, 0x0002, + 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, 0x0002, 0x35a3, + 0x35a4, 0x35b7, 0x35cb, 0x0005, 0x1004, 0x35b4, 0x0e04, 0x35b4, + 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, + 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, + 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, + 0x9086, 0x0200, 0x0904, 0x369f, 0x0005, 0x7018, 0x2048, 0x2061, + 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, + 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, + 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, + 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, + 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x369c, 0x61d0, 0x0804, + 0x3631, 0x3673, 0x36ab, 0x369c, 0x36b7, 0x36c1, 0x36c7, 0x36cb, + 0x36db, 0x36df, 0x36f5, 0x36fb, 0x3701, 0x370c, 0x3717, 0x3726, + 0x3735, 0x3743, 0x375a, 0x3775, 0x369c, 0x381e, 0x385c, 0x3901, + 0x3912, 0x3935, 0x369c, 0x369c, 0x369c, 0x396d, 0x398d, 0x3996, + 0x39c2, 0x39c8, 0x369c, 0x3a0e, 0x369c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x3a19, 0x3a22, 0x3a2a, 0x3a2c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x369c, 0x369c, 0x3a5c, 0x369c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x3a79, 0x3add, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x0002, 0x3b07, 0x3b0a, 0x3b69, 0x3b82, 0x3bb2, 0x3e58, + 0x369c, 0x53d5, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c, + 0x369c, 0x369c, 0x36f5, 0x36fb, 0x435b, 0x5844, 0x4379, 0x5464, + 0x54b6, 0x55c1, 0x369c, 0x5623, 0x565f, 0x5690, 0x57a0, 0x56bd, + 0x5720, 0x369c, 0x437d, 0x4536, 0x454c, 0x4571, 0x45d6, 0x464a, + 0x466a, 0x46e1, 0x473d, 0x4799, 0x479c, 0x47c1, 0x4833, 0x489d, + 0x48a5, 0x49da, 0x4b52, 0x4b86, 0x4dea, 0x369c, 0x4e08, 0x4eae, + 0x4f97, 0x4ff1, 0x369c, 0x50a8, 0x369c, 0x5114, 0x512f, 0x48a5, + 0x5375, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x4c04, 0x0126, + 0x2091, 0x8000, 0x0e04, 0x367d, 0x0010, 0x012e, 0x0cc0, 0x7c36, + 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, + 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11f4, 0x7007, 0x0001, 0x2091, 0x5000, + 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, + 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, + 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, + 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4c11, 0x2039, + 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, + 0x4c14, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x3673, 0x7984, + 0x2114, 0x0804, 0x3673, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, + 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, + 0x7b8c, 0x0804, 0x3673, 0x7884, 0x2060, 0x0804, 0x3728, 0x2009, + 0x0003, 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0137, 0x7893, + 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, + 0x3673, 0x7897, 0x0001, 0x0804, 0x3673, 0x2039, 0x0001, 0x7d98, + 0x7c9c, 0x0804, 0x36af, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, + 0x36bb, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36a8, 0x2138, + 0x7d98, 0x7c9c, 0x0804, 0x36af, 0x79a0, 0x9182, 0x0040, 0x0210, + 0x0804, 0x36a8, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x36bb, 0x79a0, + 0x9182, 0x0040, 0x0210, 0x0804, 0x36a8, 0x21e8, 0x7984, 0x7888, + 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x3673, 0x2061, 0x0800, + 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, + 0x9005, 0x0904, 0x3673, 0x0804, 0x36a2, 0x79a0, 0x9182, 0x0040, + 0x0210, 0x0804, 0x36a8, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, + 0x4012, 0x0804, 0x3673, 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, + 0x1a04, 0x36a8, 0x8019, 0x0904, 0x36a8, 0x684a, 0x6942, 0x788c, + 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x79d0, + 0x0804, 0x3673, 0x2069, 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, + 0x36a8, 0x8019, 0x0904, 0x36a8, 0x684e, 0x6946, 0x788c, 0x6862, + 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6c65, 0x012e, 0x0804, 0x3673, 0x902e, 0x2520, 0x81ff, + 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x7984, 0x7b88, 0x7a8c, + 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x2009, 0x0020, + 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c11, 0x701f, 0x3799, + 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, + 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, + 0x0120, 0x9096, 0x0029, 0x1904, 0x36a5, 0x810f, 0x918c, 0x00ff, + 0x0904, 0x36a5, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x2009, 0x0020, + 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, + 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, + 0x0019, 0xaf60, 0x080c, 0x4c11, 0x701f, 0x37d7, 0x0005, 0xa864, + 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, + 0x36a5, 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, + 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, + 0x62e5, 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, + 0x0050, 0x080c, 0x6615, 0x1128, 0x7007, 0x0003, 0x701f, 0x3803, + 0x0005, 0x080c, 0x715d, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, + 0x20e1, 0x0001, 0x2099, 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, + 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, + 0x2009, 0x0020, 0x012e, 0xaf60, 0x0804, 0x4c14, 0x2091, 0x8000, + 0x7837, 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, + 0x788b, 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, + 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, + 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, + 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, + 0x2001, 0x1a26, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, + 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, + 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x36a5, 0x7984, + 0x080c, 0x6783, 0x1904, 0x36a8, 0x7e98, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x1a04, 0x36a8, 0x7c88, 0x7d8c, 0x080c, 0x69b7, 0x080c, + 0x6944, 0x1518, 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, + 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, + 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x001c, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1a04, 0x36a5, 0x0c30, 0x080c, 0xc81b, + 0x012e, 0x0904, 0x36a5, 0x0804, 0x3673, 0x900e, 0x2001, 0x0005, + 0x080c, 0x715d, 0x0126, 0x2091, 0x8000, 0x080c, 0xcf3e, 0x080c, + 0x6f11, 0x012e, 0x0804, 0x3673, 0x00a6, 0x2950, 0xb198, 0x080c, + 0x6783, 0x1904, 0x38ee, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x69b7, 0x080c, 0x6944, 0x1520, + 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, + 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, + 0x9506, 0x0158, 0x012e, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, + 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xc81b, 0x012e, + 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, + 0x715d, 0x0126, 0x2091, 0x8000, 0x080c, 0xcf3e, 0x080c, 0x6f05, + 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, + 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, + 0x0005, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bdf, 0x0904, 0x36a8, + 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0x69bd, 0x0904, 0x36a5, + 0x0804, 0x4661, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bfb, 0x0904, + 0x36a8, 0x080c, 0x6a4b, 0x0904, 0x36a5, 0x2019, 0x0005, 0x79a8, + 0x080c, 0x69d8, 0x0904, 0x36a5, 0x7888, 0x908a, 0x1000, 0x1a04, + 0x36a8, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x883a, 0x79a8, + 0xd184, 0x1904, 0x3673, 0x0804, 0x4661, 0x0126, 0x2091, 0x8000, + 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, + 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x6783, 0x11d8, 0x080c, + 0x6a4b, 0x1128, 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, + 0x0004, 0x900e, 0x080c, 0x69d8, 0x1118, 0x2009, 0x0006, 0x0078, + 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, + 0x080c, 0x883a, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x3673, 0x012e, + 0x0804, 0x36a5, 0x012e, 0x0804, 0x36a8, 0x080c, 0x4bdf, 0x0904, + 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0xaaf7, 0xbaa0, + 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x95b9, 0x0076, 0x903e, + 0x080c, 0x9476, 0x900e, 0x080c, 0xe465, 0x007e, 0x00ce, 0x080c, + 0xab13, 0x080c, 0x69b7, 0x0804, 0x3673, 0x080c, 0x4bdf, 0x0904, + 0x36a8, 0x080c, 0x69b7, 0x2208, 0x0804, 0x3673, 0x0156, 0x00d6, + 0x00e6, 0x00c6, 0x2069, 0x1910, 0x6810, 0x6914, 0x910a, 0x1208, + 0x900e, 0x6816, 0x9016, 0x901e, 0x2071, 0x19e9, 0x7028, 0x9065, + 0x0118, 0x8210, 0x600c, 0x0cd8, 0x2300, 0x9218, 0x00ce, 0x00ee, + 0x00de, 0x015e, 0x0804, 0x3673, 0x00f6, 0x0016, 0x907d, 0x0138, + 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, + 0x00fe, 0x0005, 0x2069, 0x1910, 0x6910, 0x62bc, 0x0804, 0x3673, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x0126, 0x2091, + 0x8000, 0x080c, 0x5834, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, + 0x36a5, 0x012e, 0x615c, 0x9190, 0x3474, 0x2215, 0x9294, 0x00ff, + 0x637c, 0x83ff, 0x0108, 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, + 0x000a, 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, + 0x0022, 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, + 0x0012, 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x769d, 0x1118, + 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, + 0x36a5, 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x3673, 0x614c, 0x6250, + 0x2019, 0x1987, 0x231c, 0x2001, 0x1988, 0x2004, 0x789a, 0x0804, + 0x3673, 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, + 0x0804, 0x3673, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0xba44, 0xbb38, + 0x0804, 0x3673, 0x080c, 0x0d79, 0x080c, 0x4bfb, 0x2110, 0x0904, + 0x36a8, 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, + 0xff00, 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x36a5, 0x0126, + 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0xaaf7, + 0x080c, 0xa5dd, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, + 0x900e, 0x080c, 0xe465, 0x007e, 0x00ce, 0x080c, 0xab13, 0xb807, + 0x0407, 0x012e, 0x0804, 0x3673, 0x614c, 0x6250, 0x7884, 0x604e, + 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305, 0x6816, 0x788c, + 0x2069, 0x1987, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014, 0x1210, + 0x2031, 0x07d0, 0x2069, 0x1988, 0x2d04, 0x266a, 0x789a, 0x0804, + 0x3673, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a, 0x910e, + 0xd1b4, 0x190c, 0x0edf, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, + 0x199e, 0x200a, 0x78ac, 0x2011, 0x199f, 0x2012, 0x2069, 0x0100, + 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, + 0x695a, 0x00de, 0x2011, 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, + 0x918d, 0x0040, 0x0010, 0x918c, 0xff7f, 0x2112, 0x7988, 0x613e, + 0x6140, 0x788c, 0x6042, 0x910e, 0xd1e4, 0x190c, 0x0efa, 0x9084, + 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, 0x0001, 0x090c, 0x435b, + 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, + 0x0804, 0x3673, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, + 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, + 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, + 0x7888, 0x9025, 0x0904, 0x36a8, 0x788c, 0x902d, 0x0904, 0x36a8, + 0x900e, 0x080c, 0x6783, 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, + 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x4bfb, 0x0904, + 0x36a8, 0x7888, 0x900d, 0x0904, 0x36a8, 0x788c, 0x9005, 0x0904, + 0x36a8, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x3673, 0x2011, + 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x5834, 0x1904, 0x36a5, + 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, + 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, + 0x9188, 0x3474, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, + 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, + 0x8000, 0x0006, 0x080c, 0xaef8, 0x000e, 0x0510, 0x602e, 0x620a, + 0x7984, 0x00b6, 0x080c, 0x671e, 0x2b08, 0x00be, 0x1500, 0x6112, + 0x6023, 0x0001, 0x080c, 0x4bc8, 0x01d0, 0x9006, 0xa866, 0x7007, + 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3b62, 0x2900, + 0x6016, 0x2009, 0x0032, 0x080c, 0xafec, 0x012e, 0x00ce, 0x0005, + 0x012e, 0x00ce, 0x0804, 0x36a5, 0x00ce, 0x0804, 0x36a8, 0x080c, + 0xaf4e, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x36a5, 0x0804, + 0x3673, 0x2061, 0x1a74, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, + 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6354, 0x6074, 0x789a, + 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804, 0x3673, 0x900e, + 0x2110, 0x0c88, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x769d, 0x0904, + 0x36a5, 0x0126, 0x2091, 0x8000, 0x6254, 0x6074, 0x9202, 0x0248, + 0x9085, 0x0001, 0x080c, 0x270a, 0x080c, 0x5a57, 0x012e, 0x0804, + 0x3673, 0x012e, 0x0804, 0x36a8, 0x0006, 0x0016, 0x00c6, 0x00e6, + 0x2001, 0x19ab, 0x2070, 0x2061, 0x1847, 0x6008, 0x2072, 0x900e, + 0x2011, 0x1400, 0x080c, 0x9364, 0x7206, 0x00ee, 0x00ce, 0x001e, + 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, + 0x2021, 0x400b, 0x0804, 0x3675, 0x7884, 0xd0fc, 0x0158, 0x2001, + 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1, 0x0298, 0x012e, + 0x0804, 0x36a8, 0x2001, 0x002a, 0x2004, 0x9005, 0x0128, 0x2069, + 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804, 0x36a8, 0x012e, + 0x0804, 0x36a5, 0x080c, 0xae80, 0x0dd0, 0x7884, 0xd0fc, 0x0904, + 0x3c31, 0x00c6, 0x080c, 0x4bc8, 0x00ce, 0x0d88, 0xa867, 0x0000, + 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812, 0x2001, 0x002e, + 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e, 0x2001, 0x0030, + 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826, 0x2001, 0x0034, + 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e, 0x2001, 0x002a, + 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, + 0x3dbb, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, + 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, + 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x001b, 0x080c, 0x4c11, 0x701f, 0x3cf8, 0x7023, 0x0001, 0x012e, + 0x0005, 0x080c, 0xaaf7, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3b9c, 0x2001, 0x19a1, + 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, + 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3e2a, + 0x080c, 0x3de9, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9, + 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, + 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, + 0x00de, 0x2011, 0x0001, 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe, + 0x080c, 0x40c1, 0x080c, 0x3fee, 0x05b8, 0x2001, 0x020b, 0x2004, + 0x9084, 0x0140, 0x1db8, 0x080c, 0x4213, 0x00f6, 0x2079, 0x0300, + 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037, + 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037, + 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, + 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001, + 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, + 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3ff8, 0x080c, 0x3de4, + 0x0058, 0x080c, 0x3de4, 0x080c, 0x4137, 0x080c, 0x40b7, 0x2001, + 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, + 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d, + 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, + 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x1346, + 0x2009, 0x0028, 0x080c, 0x223d, 0x2001, 0x0227, 0x200c, 0x2102, + 0x080c, 0xab13, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, + 0x009e, 0x008e, 0x004e, 0x2001, 0x19a1, 0x2004, 0x9005, 0x1118, + 0x012e, 0x0804, 0x3673, 0x012e, 0x2021, 0x400c, 0x0804, 0x3675, + 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, + 0x00d6, 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, + 0xa804, 0x9005, 0x0904, 0x3d54, 0x2048, 0x1f04, 0x3d08, 0x7068, + 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, + 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, + 0xa864, 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c11, + 0x701f, 0x3cf8, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, - 0x20a0, 0x0006, 0x080c, 0x0fd6, 0x000e, 0x080c, 0x4c8d, 0x007e, - 0x701f, 0x3d34, 0x7023, 0x0001, 0x0005, 0x0804, 0x368d, 0x0156, - 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e, 0x0010, - 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x4c41, 0x001e, - 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, 0x0c58, 0x9006, - 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, 0x0006, 0x00f6, - 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, 0x000e, 0x0005, - 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6, - 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061, 0x0100, - 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x080c, - 0x4c41, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, - 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2061, - 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, 0x2009, - 0x0040, 0x080c, 0x2220, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, - 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca, 0x9006, - 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x080c, - 0x4c41, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, - 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, 0x2004, 0xa86a, - 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0xa873, 0x0000, - 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, 0x2003, 0x0000, - 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, - 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, - 0x0148, 0x080c, 0x2a77, 0x1130, 0x9006, 0x080c, 0x29ca, 0x9006, - 0x080c, 0x29ad, 0x2001, 0x199f, 0x2003, 0x0000, 0x7884, 0x9084, - 0x0007, 0x0002, 0x3eb5, 0x3eb6, 0x3eb7, 0x3eb2, 0x3eb2, 0x3eb2, - 0x3eb2, 0x3eb2, 0x012e, 0x0804, 0x36c2, 0x0ce0, 0x0cd8, 0x080c, - 0x779e, 0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x36bf, 0x81ff, - 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x368f, 0x2001, 0x0141, - 0x2004, 0xd0dc, 0x0db0, 0x080c, 0xacfc, 0x0086, 0x0096, 0x00a6, - 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3bd8, 0x2009, - 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060, - 0x2058, 0x080c, 0x432a, 0x080c, 0x427a, 0x903e, 0x2720, 0x00f6, - 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e8, 0x2079, 0x0090, 0x00d6, - 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0, - 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x41db, 0x080c, 0x2a7f, - 0x080c, 0x2a7f, 0x080c, 0x2a7f, 0x080c, 0x2a7f, 0x080c, 0x41db, - 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40fd, 0x2009, 0x9c40, 0x8109, - 0x11b0, 0x080c, 0x4034, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, - 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, - 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x36bf, 0x0cf8, 0x2001, - 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000, - 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff, - 0x0150, 0x080c, 0x40db, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c, - 0x4034, 0x0804, 0x3fdd, 0x080c, 0x424f, 0x080c, 0x4173, 0x080c, - 0x40be, 0x080c, 0x40f3, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac, - 0x0130, 0x8b58, 0x080c, 0x4034, 0x00fe, 0x0804, 0x3fdd, 0x00fe, - 0x080c, 0x402a, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001, - 0x0033, 0x2502, 0x080c, 0x4034, 0x0080, 0x87ff, 0x0138, 0x2001, - 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a6e, - 0x2004, 0x9086, 0x0000, 0x1904, 0x3f2d, 0x2001, 0x032f, 0x2003, - 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3fdd, - 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3fdd, - 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, - 0x1148, 0x2001, 0x1a6e, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, - 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016, - 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2220, 0x2900, 0xa85a, - 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6, - 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, 0x0203, - 0x2004, 0x1f04, 0x3fb4, 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0, - 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, - 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, - 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, - 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3ee7, 0x001e, 0x00c6, 0x2001, - 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x6106, - 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, 0x918c, - 0xfffd, 0x2102, 0x080c, 0x1352, 0x7884, 0x9084, 0x0003, 0x9086, - 0x0002, 0x01b0, 0x2009, 0x0028, 0x080c, 0x2220, 0x2001, 0x0227, - 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ff, 0x080c, 0x2b29, 0x6052, - 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, - 0x080c, 0xad18, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, - 0x9d05, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, - 0x008e, 0x1118, 0x012e, 0x0804, 0x368d, 0x012e, 0x2021, 0x400c, - 0x0804, 0x368f, 0x9085, 0x0001, 0x1d04, 0x4033, 0x2091, 0x6000, - 0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, - 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x1a6e, 0x2003, 0x0000, - 0x0071, 0x2009, 0x0048, 0x080c, 0x2220, 0x2001, 0x0227, 0x2024, - 0x2402, 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, - 0x00e6, 0x2071, 0x19e8, 0x7054, 0x9086, 0x0000, 0x0520, 0x2079, - 0x0090, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, - 0x1120, 0x2009, 0x0040, 0x080c, 0x2220, 0x782c, 0xd0fc, 0x0d88, - 0x080c, 0x424f, 0x7054, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, - 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2220, 0x782b, - 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, - 0x0100, 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c, 0x26d5, - 0x080c, 0x2af6, 0x080c, 0x2b29, 0x784b, 0xf7f7, 0x7843, 0x0090, - 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, 0x61a8, 0x7820, - 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, 0x7852, 0x2011, - 0x0048, 0x080c, 0x2ad3, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001, - 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2a99, 0x2011, - 0x0020, 0x080c, 0x2ad3, 0x7843, 0x0000, 0x9006, 0x080c, 0x2a99, - 0x2011, 0x0048, 0x080c, 0x2ad3, 0x00fe, 0x0005, 0x7884, 0xd0ac, - 0x11c8, 0x00f6, 0x00e6, 0x2071, 0x1a6e, 0x2079, 0x0320, 0x2001, - 0x0201, 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, - 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, - 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, - 0x908c, 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, - 0x250a, 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, - 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, - 0x0110, 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, - 0x2001, 0x19ab, 0x2004, 0x70e2, 0x080c, 0x3e16, 0x1188, 0x2001, - 0x1820, 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff, 0x706e, - 0x716a, 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, - 0x702c, 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c, 0x716e, - 0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, - 0x7077, 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, - 0x7082, 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, - 0x70ab, 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, - 0x0092, 0x7016, 0x080c, 0x424f, 0x00f6, 0x2071, 0x1a6e, 0x2079, - 0x0320, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, - 0x780e, 0x6898, 0x780a, 0x00de, 0x080c, 0x3e16, 0x0140, 0x2001, - 0x199f, 0x200c, 0x2003, 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, - 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, - 0x2011, 0x0011, 0x080c, 0x41db, 0x2011, 0x0001, 0x080c, 0x41db, - 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6e, 0x2079, - 0x0320, 0x792c, 0xd1fc, 0x0904, 0x41d8, 0x782b, 0x0002, 0x9026, - 0xd19c, 0x1904, 0x41d4, 0x7000, 0x0002, 0x41d8, 0x4189, 0x41b9, - 0x41d4, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, - 0x0001, 0x080c, 0x41db, 0x0904, 0x41d8, 0x080c, 0x41db, 0x0804, - 0x41d8, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, - 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, - 0x81ff, 0x0de8, 0x080c, 0x40db, 0x2009, 0x0001, 0x00f6, 0x2079, - 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, - 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, - 0x1904, 0x417d, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, - 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, - 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, - 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, - 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, - 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0d85, 0x9398, 0x4209, - 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, - 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, - 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, - 0x0005, 0x4246, 0x423d, 0x4234, 0x422b, 0x4222, 0x4219, 0x4210, - 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, - 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, - 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, - 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, - 0x7912, 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, - 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, - 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, - 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, - 0x00e6, 0x0086, 0x2071, 0x19e8, 0x2079, 0x0090, 0x792c, 0xd1fc, - 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7054, 0x0002, 0x4276, - 0x4262, 0x426d, 0x8001, 0x7056, 0xd19c, 0x1180, 0x2011, 0x0001, - 0x080c, 0x41db, 0x190c, 0x41db, 0x0048, 0x8001, 0x7056, 0x782c, - 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x41db, 0x008e, 0x00ee, - 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, - 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, - 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, - 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, - 0x201c, 0x080c, 0x4c41, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, - 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, - 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, - 0x080c, 0x42f2, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4c41, - 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, - 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, - 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, - 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, - 0x2009, 0x0040, 0x080c, 0x2220, 0x2001, 0x002a, 0x2004, 0x9084, - 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, - 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, - 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, - 0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, - 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, - 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, - 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, - 0x2940, 0x0086, 0x080c, 0x4c41, 0x008e, 0xa058, 0x00a6, 0x2050, - 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, - 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, - 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, - 0x4c41, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, - 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, - 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, - 0x42f2, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4c41, 0x2940, - 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, - 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, - 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, - 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, - 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, - 0x1a6e, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, - 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, - 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, - 0x2091, 0x8000, 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, - 0x9006, 0x4004, 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, - 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, - 0x0052, 0x0108, 0x0005, 0x0804, 0x368d, 0x7d98, 0x7c9c, 0x0804, - 0x3791, 0x080c, 0x779e, 0x190c, 0x6162, 0x6040, 0x9084, 0x0020, - 0x09b1, 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c8a, 0x701f, 0x43d1, - 0x0005, 0x080c, 0x584f, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, - 0x20d8, 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x36c2, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x6804, 0x0118, 0xc0a4, 0xc0ac, - 0x6806, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x36c2, 0xd094, 0x00c6, - 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, - 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, - 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, - 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, - 0x007f, 0x1a04, 0x36c2, 0x9288, 0x348e, 0x210d, 0x918c, 0x00ff, - 0x6166, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x36c2, - 0x605e, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, - 0x0006, 0x2009, 0x19b2, 0x9080, 0x27d0, 0x2005, 0x200a, 0x2008, - 0x2001, 0x0018, 0x080c, 0xaced, 0x2009, 0x0390, 0x200b, 0x0400, - 0x000e, 0x2009, 0x19b3, 0x9080, 0x27d4, 0x2005, 0x200a, 0x6808, - 0x908a, 0x0100, 0x0a04, 0x36c2, 0x908a, 0x0841, 0x1a04, 0x36c2, - 0x9084, 0x0007, 0x1904, 0x36c2, 0x680c, 0x9005, 0x0904, 0x36c2, - 0x6810, 0x9005, 0x0904, 0x36c2, 0x6848, 0x6940, 0x910a, 0x1a04, - 0x36c2, 0x8001, 0x0904, 0x36c2, 0x684c, 0x6944, 0x910a, 0x1a04, - 0x36c2, 0x8001, 0x0904, 0x36c2, 0x6814, 0x908c, 0x00ff, 0x614e, - 0x8007, 0x9084, 0x00ff, 0x6052, 0x080c, 0x7ae7, 0x080c, 0x6cfc, - 0x080c, 0x6d66, 0x6808, 0x602a, 0x080c, 0x2192, 0x2009, 0x0170, - 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, - 0x080c, 0x272f, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x456d, - 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, - 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, - 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, - 0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, - 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b4, 0x20e9, 0x0001, - 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19ce, 0x20e9, 0x0001, 0x4001, - 0x080c, 0x8b26, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, - 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x80fe, - 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, - 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, - 0x6003, 0x0001, 0x1f04, 0x44c2, 0x00ce, 0x00c6, 0x2061, 0x199c, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x11a8, 0x6a88, 0x9284, 0xc000, - 0x2010, 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, - 0x080c, 0x29ca, 0x2001, 0x0001, 0x080c, 0x29ad, 0x0088, 0x9286, - 0x4000, 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29ca, 0x9006, - 0x080c, 0x29ad, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, - 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ed3, 0x00ee, 0x080c, 0x2af6, - 0x080c, 0x2b29, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, - 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, - 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, 0x197c, - 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, - 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x27a4, - 0x2001, 0x196d, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, - 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x779e, 0x0128, - 0x080c, 0x5128, 0x0110, 0x080c, 0x26f5, 0x60d4, 0x9005, 0x01c0, - 0x6003, 0x0001, 0x2009, 0x4555, 0x00e0, 0x080c, 0x779e, 0x1168, - 0x2011, 0x7612, 0x080c, 0x8993, 0x2011, 0x7605, 0x080c, 0x8a9f, - 0x080c, 0x7abb, 0x080c, 0x76cd, 0x0040, 0x080c, 0x6058, 0x0028, - 0x6003, 0x0004, 0x2009, 0x456d, 0x0020, 0x080c, 0x6b73, 0x0804, - 0x368d, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, - 0x1118, 0x2091, 0x31bd, 0x0817, 0x2091, 0x313d, 0x0817, 0x6000, - 0x9086, 0x0000, 0x0904, 0x36bf, 0x2069, 0x1847, 0x7890, 0x6842, - 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0x2039, 0x0001, 0x0804, 0x4c8d, 0x9006, 0x080c, 0x26f5, - 0x81ff, 0x1904, 0x36bf, 0x080c, 0x779e, 0x11b0, 0x080c, 0x7ab6, - 0x080c, 0x619d, 0x080c, 0x3482, 0x0118, 0x6130, 0xc18d, 0x6132, - 0x080c, 0xd645, 0x0130, 0x080c, 0x77c1, 0x1118, 0x080c, 0x7772, - 0x0038, 0x080c, 0x76cd, 0x0020, 0x080c, 0x6162, 0x080c, 0x6058, - 0x0804, 0x368d, 0x81ff, 0x1904, 0x36bf, 0x080c, 0x779e, 0x1110, - 0x0804, 0x36bf, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, - 0x704f, 0x0000, 0x2001, 0x1d80, 0x2009, 0x0040, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c8d, 0x701f, 0x368b, - 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, - 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, - 0x655c, 0x9588, 0x348e, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, - 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x67b4, 0x1190, - 0xb814, 0x821c, 0x0238, 0x9398, 0x1d80, 0x9085, 0xff00, 0x8007, - 0x201a, 0x0038, 0x9398, 0x1d80, 0x2324, 0x94a4, 0xff00, 0x9405, - 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, - 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, - 0x1d80, 0x2099, 0x1d80, 0x080c, 0x60ed, 0x0804, 0x45ca, 0x080c, - 0x4c74, 0x0904, 0x36c2, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, - 0x0804, 0x36bf, 0x080c, 0x5840, 0xd0b4, 0x0558, 0x7884, 0x908e, - 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, - 0x080c, 0x347d, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, - 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, - 0xa86a, 0x080c, 0xd0ec, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, - 0x7007, 0x0003, 0x701f, 0x4655, 0x0005, 0x080c, 0x4c74, 0x0904, - 0x36c2, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, - 0x9080, 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, - 0x2098, 0x080c, 0x0fd6, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, - 0x000a, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, - 0x080c, 0x0fd6, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, - 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0x0804, 0x4c8d, 0x81ff, 0x1904, 0x36bf, 0x080c, 0x4c58, - 0x0904, 0x36c2, 0x080c, 0x6a00, 0x0904, 0x36bf, 0x0058, 0xa878, - 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x36bf, 0xa974, 0xaa94, - 0x0804, 0x368d, 0x080c, 0x5848, 0x0904, 0x368d, 0x701f, 0x469f, - 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x36bf, 0x7888, 0x908a, - 0x1000, 0x1a04, 0x36c2, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x080c, - 0x6c11, 0x0120, 0x080c, 0x6c19, 0x1904, 0x36c2, 0x080c, 0x6a85, - 0x0904, 0x36bf, 0x2019, 0x0004, 0x900e, 0x080c, 0x6a12, 0x0904, - 0x36bf, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, - 0x12f8, 0x080c, 0x4c72, 0x01e0, 0x080c, 0x6c11, 0x0118, 0x080c, - 0x6c19, 0x11b0, 0x080c, 0x6a85, 0x2009, 0x0002, 0x0168, 0x2009, - 0x0002, 0x2019, 0x0004, 0x080c, 0x6a12, 0x2009, 0x0003, 0x0120, - 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, - 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, - 0xa897, 0x4000, 0x080c, 0x5848, 0x0110, 0x9006, 0x0018, 0x900e, - 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, - 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, - 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, - 0x67b4, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, - 0x89a1, 0x0005, 0x81ff, 0x1904, 0x36bf, 0x798c, 0x2001, 0x1980, - 0x918c, 0x8000, 0x2102, 0x080c, 0x4c58, 0x0904, 0x36c2, 0x080c, - 0x6c11, 0x0120, 0x080c, 0x6c19, 0x1904, 0x36c2, 0x080c, 0x687b, - 0x0904, 0x36bf, 0x080c, 0x6a09, 0x0904, 0x36bf, 0x2001, 0x1980, - 0x2004, 0xd0fc, 0x1904, 0x368d, 0x0804, 0x46aa, 0xa9a0, 0x2001, - 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4c65, 0x01a0, - 0x080c, 0x6c11, 0x0118, 0x080c, 0x6c19, 0x1170, 0x080c, 0x687b, - 0x2009, 0x0002, 0x0128, 0x080c, 0x6a09, 0x1170, 0x2009, 0x0003, - 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, - 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1980, - 0x2004, 0xd0fc, 0x1128, 0x080c, 0x5848, 0x0110, 0x9006, 0x0018, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, - 0x36bf, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, - 0x4c58, 0x0904, 0x36c2, 0x080c, 0x6c11, 0x0120, 0x080c, 0x6c19, - 0x1904, 0x36c2, 0x080c, 0x687b, 0x0904, 0x36bf, 0x080c, 0x69f7, - 0x0904, 0x36bf, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, 0x368d, - 0x0804, 0x46aa, 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, 0xc18d, - 0x2102, 0x080c, 0x4c65, 0x01a0, 0x080c, 0x6c11, 0x0118, 0x080c, - 0x6c19, 0x1170, 0x080c, 0x687b, 0x2009, 0x0002, 0x0128, 0x080c, - 0x69f7, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, - 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, - 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, 0x080c, - 0x5848, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, - 0x0000, 0x0005, 0x6100, 0x0804, 0x368d, 0x080c, 0x4c74, 0x0904, - 0x36c2, 0x080c, 0x5854, 0x1904, 0x36bf, 0x79a8, 0xd184, 0x1158, - 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, - 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, - 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, - 0x0804, 0x368d, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, - 0x1140, 0x939a, 0x0003, 0x1a04, 0x36bf, 0x625c, 0x7884, 0x9206, - 0x1548, 0x080c, 0x8b10, 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, - 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, - 0x0080, 0x1118, 0x000e, 0x0804, 0x4c8d, 0x000e, 0x2031, 0x0000, - 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, - 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, - 0x4862, 0x0005, 0x81ff, 0x1904, 0x36bf, 0x080c, 0x4c74, 0x0904, - 0x36c2, 0x080c, 0x6c11, 0x1904, 0x36bf, 0x00c6, 0x080c, 0x4c41, - 0x00ce, 0x0904, 0x36bf, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, - 0x7ea8, 0x080c, 0xd092, 0x0904, 0x36bf, 0x7007, 0x0003, 0x701f, - 0x4866, 0x0005, 0x080c, 0x4397, 0x0804, 0x368d, 0xa830, 0x9086, - 0x0100, 0x0904, 0x36bf, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, - 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0x0804, 0x4c8d, 0x9006, 0x080c, 0x26f5, 0x78a8, - 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x36bf, - 0x080c, 0x779e, 0x0110, 0x080c, 0x6162, 0x7888, 0x908a, 0x1000, - 0x1a04, 0x36c2, 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, - 0x1a04, 0x36c2, 0x2100, 0x080c, 0x26bf, 0x0026, 0x00c6, 0x0126, - 0x2091, 0x8000, 0x2061, 0x1a04, 0x601b, 0x0000, 0x601f, 0x0000, - 0x607b, 0x0000, 0x607f, 0x0000, 0x080c, 0x779e, 0x1158, 0x080c, - 0x7ab6, 0x080c, 0x619d, 0x9085, 0x0001, 0x080c, 0x77e2, 0x080c, - 0x76cd, 0x00f0, 0x080c, 0xacfc, 0x080c, 0xb09b, 0x080c, 0xad18, - 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, - 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1999, - 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x6088, 0x080c, 0x8a5d, - 0x7984, 0x080c, 0x779e, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, - 0x470d, 0x012e, 0x00ce, 0x002e, 0x0804, 0x368d, 0x7984, 0x080c, - 0x6749, 0x2b08, 0x1904, 0x36c2, 0x0804, 0x368d, 0x81ff, 0x0120, - 0x2009, 0x0001, 0x0804, 0x36bf, 0x60dc, 0xd0ac, 0x1130, 0xd09c, - 0x1120, 0x2009, 0x0005, 0x0804, 0x36bf, 0x080c, 0x4c41, 0x1120, - 0x2009, 0x0002, 0x0804, 0x36bf, 0x7984, 0x81ff, 0x0904, 0x36c2, - 0x9192, 0x0021, 0x1a04, 0x36c2, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, - 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4c8a, - 0x701f, 0x4921, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x52da, - 0x0005, 0x2009, 0x0080, 0x080c, 0x67b4, 0x1118, 0x080c, 0x6c11, - 0x0120, 0x2021, 0x400a, 0x0804, 0x368f, 0x00d6, 0x0096, 0xa964, - 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, - 0x0904, 0x49ba, 0x90be, 0x0112, 0x0904, 0x49ba, 0x90be, 0x0113, - 0x0904, 0x49ba, 0x90be, 0x0114, 0x0904, 0x49ba, 0x90be, 0x0117, - 0x0904, 0x49ba, 0x90be, 0x011a, 0x0904, 0x49ba, 0x90be, 0x011c, - 0x0904, 0x49ba, 0x90be, 0x0121, 0x0904, 0x49a1, 0x90be, 0x0131, - 0x0904, 0x49a1, 0x90be, 0x0171, 0x0904, 0x49ba, 0x90be, 0x0173, - 0x0904, 0x49ba, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, - 0x0804, 0x49c5, 0x90be, 0x0212, 0x0904, 0x49ae, 0x90be, 0x0213, - 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, - 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, - 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x36c2, - 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, - 0x20a9, 0x0007, 0x080c, 0x4a03, 0x7028, 0x9080, 0x000e, 0x2098, - 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4a03, - 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, - 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4a10, 0x00b8, 0x7028, 0x9080, - 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, - 0x080c, 0x4a10, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, - 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4c41, - 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, - 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, - 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, - 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, - 0xd0ad, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, 0x7007, 0x0003, - 0x701f, 0x49fa, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, - 0x0804, 0x36bf, 0xa820, 0x9086, 0x8001, 0x1904, 0x368d, 0x2009, - 0x0004, 0x0804, 0x36bf, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, - 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, - 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, - 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, - 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, - 0x36bf, 0x60dc, 0xd0ac, 0x1188, 0x2009, 0x180d, 0x210c, 0xd18c, - 0x0130, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, 0x36bf, 0xd09c, - 0x1120, 0x2009, 0x0005, 0x0804, 0x36bf, 0x7984, 0x78a8, 0x2040, - 0x080c, 0xb094, 0x1120, 0x9182, 0x007f, 0x0a04, 0x36c2, 0x9186, - 0x00ff, 0x0904, 0x36c2, 0x9182, 0x0800, 0x1a04, 0x36c2, 0x7a8c, - 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080, 0x924e, 0x0904, 0x36c2, - 0x080c, 0xb094, 0x1120, 0x99cc, 0xff00, 0x0904, 0x36c2, 0x0126, - 0x2091, 0x8000, 0x2001, 0x180d, 0x2004, 0xd08c, 0x0198, 0x9386, - 0x00ff, 0x0180, 0x0026, 0x2011, 0x8008, 0x080c, 0x6c35, 0x002e, - 0x0148, 0x918d, 0x8000, 0x080c, 0x6c7f, 0x1120, 0x2001, 0x4009, - 0x0804, 0x4ac1, 0x080c, 0x4b54, 0x0904, 0x4ac7, 0x0086, 0x90c6, - 0x4000, 0x008e, 0x1538, 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, - 0x9305, 0xbb20, 0x9305, 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, - 0x9305, 0xbb30, 0x9305, 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, - 0x1128, 0x080c, 0x6c11, 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, - 0x6aae, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, - 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, - 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, - 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, - 0x000a, 0x2020, 0x012e, 0x0804, 0x368f, 0x000e, 0x00ce, 0x2b00, - 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xb1dd, - 0x0904, 0x4b1c, 0x2b00, 0x6012, 0x080c, 0xd3b6, 0x2e58, 0x00ee, - 0x00e6, 0x00c6, 0x080c, 0x4c41, 0x00ce, 0x2b70, 0x1158, 0x080c, - 0xb16c, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, - 0x0804, 0x36bf, 0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, - 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, - 0x080c, 0x3315, 0x6023, 0x0001, 0x9006, 0x080c, 0x66e6, 0xd89c, - 0x0138, 0x2001, 0x0004, 0x080c, 0x66fa, 0x2009, 0x0003, 0x0030, - 0x2001, 0x0002, 0x080c, 0x66fa, 0x2009, 0x0002, 0x080c, 0xb20a, - 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8d4, - 0xc08d, 0xb8d6, 0x9085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, - 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, 0x7007, 0x0003, - 0x701f, 0x4b2b, 0x0005, 0xa830, 0x2009, 0x180d, 0x210c, 0xd18c, - 0x0140, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, - 0x368f, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, - 0xba04, 0x9294, 0x00ff, 0x0804, 0x578e, 0x900e, 0xa868, 0xd0f4, - 0x1904, 0x368d, 0x080c, 0x6aae, 0x1108, 0xc185, 0xb800, 0xd0bc, - 0x0108, 0xc18d, 0x0804, 0x368d, 0x00e6, 0x00d6, 0x0096, 0x83ff, - 0x0904, 0x4ba3, 0x902e, 0x080c, 0xb094, 0x0130, 0x9026, 0x20a9, - 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, - 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, - 0x4bb4, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, - 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, - 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, - 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, - 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6bb1, 0x1570, 0x2001, - 0x4000, 0x0460, 0x080c, 0x6c11, 0x1540, 0x2001, 0x4000, 0x0430, - 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, - 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xb094, - 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4b6a, - 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, - 0x080c, 0x6749, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, - 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, - 0x36bf, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, - 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, - 0x36c2, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x36c2, - 0x2010, 0x2918, 0x080c, 0x32b5, 0x1120, 0x2009, 0x0003, 0x0804, - 0x36bf, 0x7007, 0x0003, 0x701f, 0x4bf6, 0x0005, 0xa830, 0x9086, - 0x0100, 0x1904, 0x368d, 0x2009, 0x0004, 0x0804, 0x36bf, 0x7984, - 0x080c, 0xb094, 0x1120, 0x9182, 0x007f, 0x0a04, 0x36c2, 0x9186, - 0x00ff, 0x0904, 0x36c2, 0x9182, 0x0800, 0x1a04, 0x36c2, 0x2001, - 0x9400, 0x080c, 0x57e9, 0x1904, 0x36bf, 0x0804, 0x368d, 0xa998, - 0x080c, 0xb094, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, - 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x57e9, - 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, - 0x0c48, 0x080c, 0x1059, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, - 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, - 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, - 0x7984, 0x080c, 0x67b4, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, - 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x67b4, - 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, - 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x67b4, - 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, - 0x0128, 0x2148, 0xa904, 0x080c, 0x108b, 0x0cc8, 0x7116, 0x711a, - 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, + 0x20a0, 0x0006, 0x080c, 0x0fca, 0x000e, 0x080c, 0x4c14, 0x701f, + 0x3cf8, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, + 0x003e, 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, + 0x0103, 0x1118, 0x701f, 0x3db9, 0x0450, 0x7014, 0x2048, 0xa868, + 0xc0fd, 0xa86a, 0x2009, 0x007f, 0x080c, 0x6718, 0x0110, 0x9006, + 0x0030, 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd121, 0x015e, + 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, + 0x001e, 0x0904, 0x36a5, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, + 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3d8b, 0x7007, + 0x0003, 0x0804, 0x3d49, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, + 0x0904, 0x3675, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, + 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, + 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fca, + 0x000e, 0x080c, 0x4c14, 0x007e, 0x701f, 0x3cf8, 0x7023, 0x0001, + 0x0005, 0x0804, 0x3673, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, + 0x0218, 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, + 0x0016, 0x080c, 0x4bc8, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, + 0xa80a, 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, + 0x015e, 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, + 0x0044, 0x00fe, 0x000e, 0x0005, 0x2001, 0x19a1, 0x2003, 0x0001, + 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ac, + 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, 0x60ce, + 0x6104, 0xc1ac, 0x6106, 0x080c, 0x4bc8, 0xa813, 0x0019, 0xa817, + 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, + 0x002f, 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, + 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x223d, 0x2001, + 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, + 0x601f, 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x00e6, 0x080c, 0x4bc8, 0x2940, 0xa013, 0x0019, + 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, + 0x2001, 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, + 0xfff8, 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, + 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, + 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, + 0x0126, 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2a80, 0x1130, + 0x9006, 0x080c, 0x29d7, 0x9006, 0x080c, 0x29ba, 0x2001, 0x19a0, + 0x2003, 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3e79, 0x3e7a, + 0x3e7b, 0x3e76, 0x3e76, 0x3e76, 0x3e76, 0x3e76, 0x012e, 0x0804, + 0x36a8, 0x0ce0, 0x0cd8, 0x080c, 0x769d, 0x1128, 0x012e, 0x2009, + 0x0016, 0x0804, 0x36a5, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, + 0x0804, 0x3675, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0db0, 0x080c, + 0xaaf7, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x080c, 0x3b9c, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, + 0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x42ee, 0x080c, + 0x423e, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, + 0x19e9, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, + 0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, + 0x080c, 0x419f, 0x080c, 0x2a88, 0x080c, 0x2a88, 0x080c, 0x2a88, + 0x080c, 0x2a88, 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe, 0x080c, + 0x40c1, 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3ff8, 0x2001, + 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, + 0x080c, 0x36a5, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, + 0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, + 0x2001, 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x409f, 0x2d00, + 0x9c05, 0x9b05, 0x0120, 0x080c, 0x3ff8, 0x0804, 0x3fa1, 0x080c, + 0x4213, 0x080c, 0x4137, 0x080c, 0x4082, 0x080c, 0x40b7, 0x00f6, + 0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3ff8, + 0x00fe, 0x0804, 0x3fa1, 0x00fe, 0x080c, 0x3fee, 0x1150, 0x8d68, + 0x2001, 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3ff8, + 0x0080, 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, + 0x8739, 0x0038, 0x2001, 0x1a6f, 0x2004, 0x9086, 0x0000, 0x1904, + 0x3ef1, 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, + 0x2500, 0x9605, 0x0904, 0x3fa1, 0x7884, 0xd0bc, 0x0128, 0x2d00, + 0x9c05, 0x9b05, 0x1904, 0x3fa1, 0xa013, 0x0019, 0x2001, 0x032a, + 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a6f, 0x2003, + 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, + 0x78b4, 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, + 0x080c, 0x223d, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, + 0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, + 0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3f78, 0x00ce, + 0x0030, 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, + 0x00c6, 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, + 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, + 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, + 0x3eab, 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, + 0x0100, 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, + 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x1346, + 0x7884, 0x9084, 0x0003, 0x9086, 0x0002, 0x01b0, 0x2009, 0x0028, + 0x080c, 0x223d, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, + 0xb7ff, 0x080c, 0x2b32, 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, + 0x6043, 0x0090, 0x6043, 0x0010, 0x080c, 0xab13, 0x00ce, 0x2d08, + 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, + 0x3673, 0x012e, 0x2021, 0x400c, 0x0804, 0x3675, 0x9085, 0x0001, + 0x1d04, 0x3ff7, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005, + 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004, + 0x2001, 0x1a6f, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c, + 0x223d, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003, + 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054, + 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104, + 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, + 0x223d, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4213, 0x7054, 0x9086, + 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, + 0x0040, 0x080c, 0x223d, 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, 0x200c, + 0x7932, 0x7936, 0x080c, 0x26ea, 0x080c, 0x2aff, 0x080c, 0x2b32, + 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, + 0x7852, 0x2019, 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, + 0x7850, 0xc0e4, 0x7852, 0x2011, 0x0048, 0x080c, 0x2adc, 0x7843, + 0x0040, 0x2019, 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, + 0x0100, 0x080c, 0x2aa2, 0x2011, 0x0020, 0x080c, 0x2adc, 0x7843, + 0x0000, 0x9006, 0x080c, 0x2aa2, 0x2011, 0x0048, 0x080c, 0x2adc, + 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, + 0x1a6f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160, + 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, + 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6, + 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009, + 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60, + 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, + 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe, + 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19ac, 0x2004, 0x70e2, + 0x080c, 0x3dda, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, 0x181f, + 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200, + 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e, + 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, + 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080, + 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006, + 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, + 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4213, + 0x00f6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000, + 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de, + 0x080c, 0x3dda, 0x0140, 0x2001, 0x19a0, 0x200c, 0x2003, 0x0001, + 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, + 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, 0x080c, 0x419f, + 0x2011, 0x0001, 0x080c, 0x419f, 0x00fe, 0x00ee, 0x0005, 0x00f6, + 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, + 0x419c, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, 0x4198, 0x7000, + 0x0002, 0x419c, 0x414d, 0x417d, 0x4198, 0xd1bc, 0x1170, 0xd1dc, + 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, 0x419f, 0x0904, + 0x419c, 0x080c, 0x419f, 0x0804, 0x419c, 0x00f6, 0x2079, 0x0300, + 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, 0x0004, 0x7812, + 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x409f, + 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, + 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, + 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x4141, 0x2011, 0x0001, + 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, 0x0015, 0x1120, + 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, + 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, + 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, 0xa058, 0x2048, + 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, 0x938a, 0x0007, + 0x1a0c, 0x0d79, 0x9398, 0x41cd, 0x231d, 0x083f, 0x9080, 0x0004, + 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, 0x908a, 0x0035, + 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, + 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x420a, 0x4201, 0x41f8, + 0x41ef, 0x41e6, 0x41dd, 0x41d4, 0xa964, 0x7902, 0xa968, 0x7906, + 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, 0x7902, 0xa978, + 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, 0xa984, 0x7902, + 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, 0x0005, 0xa994, + 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005, + 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, + 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, + 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, + 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, 0x2071, 0x19e9, + 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, + 0x9026, 0x7054, 0x0002, 0x423a, 0x4226, 0x4231, 0x8001, 0x7056, + 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x419f, 0x190c, 0x419f, + 0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, + 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, + 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19ac, 0x2004, 0x601a, + 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, 0x60ce, 0x6104, 0xc1ac, + 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, 0x2038, 0x2001, + 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, 0x4bc8, 0xa813, + 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, + 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, + 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42b6, 0x1d68, 0x2900, + 0xa85a, 0x00d0, 0x080c, 0x4bc8, 0xa813, 0x0019, 0xa817, 0x0001, + 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, + 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, + 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, 0x2079, 0x0100, + 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x223d, + 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, + 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, + 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, + 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, + 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, 0x700e, 0x810b, + 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, + 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, 0x7400, 0x7304, + 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, 0x080c, 0x4bc8, + 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, + 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, + 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, 0x0030, 0x2024, + 0x2001, 0x0031, 0x201c, 0x080c, 0x4bc8, 0x2940, 0xa813, 0x0019, + 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, + 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, + 0x9080, 0x0019, 0x009e, 0x080c, 0x42b6, 0x1d68, 0x2900, 0xa85a, + 0x00d8, 0x080c, 0x4bc8, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, + 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, 0x2001, 0x0031, + 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, + 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, 0x2003, 0x0004, + 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, 0x918d, 0x0200, + 0x2102, 0xa017, 0x0000, 0x2001, 0x1a6f, 0x2003, 0x0003, 0x2001, + 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, + 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, + 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0007, + 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, 0x20a9, 0x0014, + 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004, 0x2009, 0x013c, + 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, 0x0005, 0x0804, + 0x3673, 0x7d98, 0x7c9c, 0x0804, 0x3777, 0x080c, 0x769d, 0x190c, + 0x613d, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069, 0x1847, 0x2d00, + 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, + 0x080c, 0x4c11, 0x701f, 0x4395, 0x0005, 0x080c, 0x582f, 0x1130, + 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, 0x1847, + 0x6800, 0x9005, 0x0904, 0x36a8, 0x6804, 0xd0ac, 0x0118, 0xd0a4, + 0x0904, 0x36a8, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0138, + 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010, 0x918d, + 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, + 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106, 0x00ce, + 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x36a8, 0x9288, + 0x3474, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc, 0x0130, 0x6828, + 0x908a, 0x007f, 0x1a04, 0x36a8, 0x605e, 0x6888, 0x9084, 0x0030, + 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x19b3, 0x9080, + 0x27dd, 0x2005, 0x200a, 0x2008, 0x2001, 0x0018, 0x080c, 0xaae8, + 0x2009, 0x0390, 0x200b, 0x0400, 0x000e, 0x2009, 0x19b4, 0x9080, + 0x27e1, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x36a8, + 0x908a, 0x0841, 0x1a04, 0x36a8, 0x9084, 0x0007, 0x1904, 0x36a8, + 0x680c, 0x9005, 0x0904, 0x36a8, 0x6810, 0x9005, 0x0904, 0x36a8, + 0x6848, 0x6940, 0x910a, 0x1a04, 0x36a8, 0x8001, 0x0904, 0x36a8, + 0x684c, 0x6944, 0x910a, 0x1a04, 0x36a8, 0x8001, 0x0904, 0x36a8, + 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084, 0x00ff, 0x6052, + 0x080c, 0x79d0, 0x080c, 0x6c03, 0x080c, 0x6c65, 0x6808, 0x602a, + 0x080c, 0x21af, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, 0xa001, + 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2744, 0x003e, 0x6000, + 0x9086, 0x0000, 0x1904, 0x4524, 0x6818, 0x691c, 0x6a20, 0x6b24, + 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, + 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, + 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006, 0x610a, + 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, + 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004, 0x20a1, + 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c, 0x89bf, 0x00c6, 0x900e, + 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, + 0x3508, 0x8109, 0x080c, 0x7f97, 0x6878, 0x6016, 0x6874, 0x2008, + 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, 0x8108, + 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x447e, + 0x00ce, 0x00c6, 0x2061, 0x199d, 0x6a88, 0x9284, 0xc000, 0x2010, + 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c, + 0x29d7, 0x2001, 0x0001, 0x080c, 0x29ba, 0x0088, 0x9286, 0x4000, + 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29d7, 0x9006, 0x080c, + 0x29ba, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce, + 0x00e6, 0x2c70, 0x080c, 0x0ec7, 0x00ee, 0x080c, 0x2aff, 0x080c, + 0x2b32, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085, + 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128, + 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80, + 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118, + 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x27b9, 0x2001, + 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, + 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x769d, 0x0128, 0x080c, + 0x5108, 0x0110, 0x080c, 0x270a, 0x60d4, 0x9005, 0x01c0, 0x6003, + 0x0001, 0x2009, 0x450c, 0x00e0, 0x080c, 0x769d, 0x1168, 0x2011, + 0x7511, 0x080c, 0x882c, 0x2011, 0x7504, 0x080c, 0x8938, 0x080c, + 0x79a4, 0x080c, 0x75cc, 0x0040, 0x080c, 0x6033, 0x0028, 0x6003, + 0x0004, 0x2009, 0x4524, 0x0020, 0x080c, 0x6b2f, 0x0804, 0x3673, + 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, + 0x2091, 0x31bd, 0x0817, 0x2091, 0x313d, 0x0817, 0x6000, 0x9086, + 0x0000, 0x0904, 0x36a5, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894, + 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x2039, 0x0001, 0x0804, 0x4c14, 0x9006, 0x080c, 0x270a, 0x81ff, + 0x1904, 0x36a5, 0x080c, 0x769d, 0x11b0, 0x080c, 0x799f, 0x080c, + 0x6178, 0x080c, 0x3468, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, + 0xd35d, 0x0130, 0x080c, 0x76c0, 0x1118, 0x080c, 0x7671, 0x0038, + 0x080c, 0x75cc, 0x0020, 0x080c, 0x613d, 0x080c, 0x6033, 0x0804, + 0x3673, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x769d, 0x1110, 0x0804, + 0x36a5, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f, + 0x0000, 0x2001, 0x1d80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c14, 0x701f, 0x3671, 0x012e, + 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040, + 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, 0x655c, + 0x9588, 0x3474, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, + 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x6783, 0x1190, 0xb814, + 0x821c, 0x0238, 0x9398, 0x1d80, 0x9085, 0xff00, 0x8007, 0x201a, + 0x0038, 0x9398, 0x1d80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, + 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, + 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1d80, + 0x2099, 0x1d80, 0x080c, 0x60c8, 0x0804, 0x4581, 0x080c, 0x4bfb, + 0x0904, 0x36a8, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, + 0x36a5, 0x080c, 0x5820, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, + 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, + 0x3463, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007, + 0x0003, 0x701f, 0x460c, 0x0005, 0x080c, 0x4bfb, 0x0904, 0x36a8, + 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, + 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, + 0x080c, 0x0fca, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, + 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, + 0x0fca, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x0804, 0x4c14, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bdf, 0x0904, + 0x36a8, 0x080c, 0x69c6, 0x0904, 0x36a5, 0x0058, 0xa878, 0x9005, + 0x0120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa974, 0xaa94, 0x0804, + 0x3673, 0x080c, 0x5828, 0x0904, 0x3673, 0x701f, 0x4656, 0x7007, + 0x0003, 0x0005, 0x81ff, 0x1904, 0x36a5, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x36a8, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x080c, 0x6bcd, + 0x0120, 0x080c, 0x6bd5, 0x1904, 0x36a8, 0x080c, 0x6a4b, 0x0904, + 0x36a5, 0x2019, 0x0004, 0x900e, 0x080c, 0x69d8, 0x0904, 0x36a5, + 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, + 0x080c, 0x4bf9, 0x01e0, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, + 0x11b0, 0x080c, 0x6a4b, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, + 0x2019, 0x0004, 0x080c, 0x69d8, 0x2009, 0x0003, 0x0120, 0xa998, + 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, + 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506, + 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x6783, + 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x883a, + 0x0005, 0x81ff, 0x1904, 0x36a5, 0x798c, 0x2001, 0x1981, 0x918c, + 0x8000, 0x2102, 0x080c, 0x4bdf, 0x0904, 0x36a8, 0x080c, 0x6bcd, + 0x0120, 0x080c, 0x6bd5, 0x1904, 0x36a8, 0x080c, 0x684a, 0x0904, + 0x36a5, 0x080c, 0x69cf, 0x0904, 0x36a5, 0x2001, 0x1981, 0x2004, + 0xd0fc, 0x1904, 0x3673, 0x0804, 0x4661, 0xa9a0, 0x2001, 0x1981, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bec, 0x01a0, 0x080c, + 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1170, 0x080c, 0x684a, 0x2009, + 0x0002, 0x0128, 0x080c, 0x69cf, 0x1170, 0x2009, 0x0003, 0xa897, + 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x36a5, + 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4bdf, + 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x0120, 0x080c, 0x6bd5, 0x1904, + 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0x69bd, 0x0904, + 0x36a5, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, 0x3673, 0x0804, + 0x4661, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, + 0x080c, 0x4bec, 0x01a0, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, + 0x1170, 0x080c, 0x684a, 0x2009, 0x0002, 0x0128, 0x080c, 0x69bd, + 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x5828, + 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x0005, 0x6100, 0x0804, 0x3673, 0x080c, 0x4bfb, 0x0904, 0x36a8, + 0x080c, 0x5834, 0x1904, 0x36a5, 0x79a8, 0xd184, 0x1158, 0xb834, + 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, + 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, + 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, + 0x3673, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, + 0x939a, 0x0003, 0x1a04, 0x36a5, 0x625c, 0x7884, 0x9206, 0x1548, + 0x080c, 0x89a9, 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, 0x0080, + 0x1118, 0x000e, 0x0804, 0x4c14, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, - 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x368d, - 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, - 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4cbe, 0x7a36, 0x7833, - 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, - 0x2004, 0xd084, 0x190c, 0x1200, 0x0804, 0x4d24, 0x0016, 0x0086, - 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, - 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1059, - 0x0904, 0x4d1c, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, - 0x9080, 0x1ec1, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, - 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, - 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, - 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, - 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x2060, 0x001e, 0x8108, 0x2105, - 0x9005, 0xa146, 0x1520, 0x080c, 0x1059, 0x1130, 0x8109, 0xa946, - 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, - 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, - 0x1ec1, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, - 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, - 0x9082, 0x001b, 0x0002, 0x4d46, 0x4d46, 0x4d48, 0x4d46, 0x4d46, - 0x4d46, 0x4d4c, 0x4d46, 0x4d46, 0x4d46, 0x4d50, 0x4d46, 0x4d46, - 0x4d46, 0x4d54, 0x4d46, 0x4d46, 0x4d46, 0x4d58, 0x4d46, 0x4d46, - 0x4d46, 0x4d5c, 0x4d46, 0x4d46, 0x4d46, 0x4d61, 0x080c, 0x0d85, - 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, - 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, - 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, - 0x4d1f, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4d1f, 0x00e6, 0x2071, - 0x189e, 0x7048, 0x9005, 0x0904, 0x4df8, 0x0126, 0x2091, 0x8000, - 0x0e04, 0x4df7, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, - 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, - 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x2060, 0x001e, - 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4dfa, 0xa804, 0x9005, - 0x090c, 0x0d85, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, - 0x0002, 0x9080, 0x1ec1, 0x2005, 0xa04a, 0x0804, 0x4dfa, 0x703c, - 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, - 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x87ff, 0x0118, - 0x2748, 0x080c, 0x108b, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, - 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x108b, 0x9006, 0x7042, - 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, - 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, - 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, - 0x703a, 0x7044, 0x9005, 0x090c, 0x0d85, 0x2048, 0xa800, 0x9005, - 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1ec1, 0x2005, - 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, - 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4e19, 0x4e19, - 0x4e1b, 0x4e19, 0x4e19, 0x4e19, 0x4e20, 0x4e19, 0x4e19, 0x4e19, - 0x4e25, 0x4e19, 0x4e19, 0x4e19, 0x4e2a, 0x4e19, 0x4e19, 0x4e19, - 0x4e2f, 0x4e19, 0x4e19, 0x4e19, 0x4e34, 0x4e19, 0x4e19, 0x4e19, - 0x4e39, 0x080c, 0x0d85, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4da5, - 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4da5, 0xaa94, 0xab98, 0xac9c, - 0x0804, 0x4da5, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4da5, 0xaab4, - 0xabb8, 0xacbc, 0x0804, 0x4da5, 0xaac4, 0xabc8, 0xaccc, 0x0804, - 0x4da5, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4da5, 0x0016, 0x0026, - 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x67b4, 0x2019, - 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, - 0x080c, 0x4ca1, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, - 0x0026, 0x080c, 0x5840, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, - 0x4ca1, 0x002e, 0x0005, 0x81ff, 0x1904, 0x36bf, 0x0126, 0x2091, - 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x779e, - 0x1158, 0x080c, 0x7ab6, 0x080c, 0x619d, 0x9085, 0x0001, 0x080c, - 0x77e2, 0x080c, 0x76cd, 0x0010, 0x080c, 0x6058, 0x012e, 0x0804, - 0x368d, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, 0x080c, - 0x5854, 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x080c, 0x6c09, - 0x0120, 0x2009, 0x0008, 0x0804, 0x36bf, 0x2001, 0x180d, 0x2004, - 0xd08c, 0x0178, 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, 0x002e, - 0x0140, 0x7984, 0x080c, 0x6c7f, 0x1120, 0x2009, 0x4009, 0x0804, - 0x36bf, 0x7984, 0x080c, 0x6749, 0x1904, 0x36c2, 0x080c, 0x4c74, - 0x0904, 0x36c2, 0x2b00, 0x7026, 0x080c, 0x6c11, 0x7888, 0x1170, - 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x6aae, 0x1108, 0xc185, - 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x368d, 0x080c, 0x4c41, - 0x0904, 0x36bf, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, - 0x080c, 0xd154, 0x0904, 0x36bf, 0x7888, 0xd094, 0x0118, 0xb8d4, - 0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f, 0x4f28, 0x0005, 0x2061, - 0x1800, 0x080c, 0x5854, 0x2009, 0x0007, 0x1560, 0x080c, 0x6c09, - 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x6749, 0x1530, - 0x080c, 0x4c72, 0x0518, 0x080c, 0x6c11, 0xa89c, 0x1168, 0x9084, - 0x0005, 0x1150, 0x900e, 0x080c, 0x6aae, 0x1108, 0xc185, 0xb800, - 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, - 0xd154, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, - 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, - 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, - 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, - 0xa830, 0x2009, 0x180d, 0x210c, 0xd18c, 0x0140, 0x2008, 0x918e, - 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x368f, 0x9086, 0x0100, - 0x7024, 0x2058, 0x1110, 0x0804, 0x578e, 0x900e, 0x080c, 0x6aae, - 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x368d, - 0x080c, 0x5854, 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x7f84, - 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4c41, 0x1120, 0x2009, - 0x0002, 0x0804, 0x36bf, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, - 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, - 0x67b4, 0x1904, 0x4fde, 0x080c, 0x6c11, 0x0138, 0x080c, 0x6c19, - 0x0120, 0x080c, 0x6bb1, 0x1904, 0x4fde, 0xd794, 0x1110, 0xd784, - 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, - 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, - 0x20e0, 0x20a9, 0x0002, 0x080c, 0x4a10, 0x0080, 0xb8c4, 0x20e0, - 0xb8c8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, - 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4a10, 0x9186, 0x007e, - 0x0170, 0x9186, 0x0080, 0x0158, 0x080c, 0x6c11, 0x90c2, 0x0006, - 0x1210, 0xc1fd, 0x0020, 0x080c, 0x6aae, 0x1108, 0xc1fd, 0x4104, - 0xc1fc, 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, - 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, - 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, - 0x0002, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4a03, - 0x9c80, 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, - 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, - 0xb094, 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, - 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, - 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4f67, - 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, 0x368d, 0x7033, 0x0001, - 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, - 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, - 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, - 0x501a, 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, - 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, - 0xa390, 0xa494, 0xa598, 0x0804, 0x4f67, 0x7124, 0x810b, 0x0804, - 0x368d, 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, - 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, 0x0a04, - 0x36c2, 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, - 0x0a04, 0x36c2, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, - 0x36c2, 0x9502, 0x0a04, 0x36c2, 0x9284, 0x00ff, 0x90e2, 0x0020, - 0x0a04, 0x36c2, 0x9502, 0x0a04, 0x36c2, 0x9384, 0xff00, 0x8007, - 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, 0x0a04, 0x36c2, 0x9384, - 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, 0x0a04, 0x36c2, - 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, - 0x0a04, 0x36c2, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36c2, - 0x9502, 0x0a04, 0x36c2, 0x2061, 0x1989, 0x6102, 0x6206, 0x630a, - 0x640e, 0x0804, 0x368d, 0x080c, 0x4c41, 0x0904, 0x36bf, 0x2009, - 0x0016, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, - 0xaf60, 0x080c, 0x4c8a, 0x701f, 0x509e, 0x0005, 0x20a9, 0x0016, - 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019, 0x2098, - 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001, 0x2da0, - 0x4003, 0x6800, 0x9005, 0x0904, 0x5105, 0x6804, 0x2008, 0x918c, - 0xfff8, 0x1904, 0x5105, 0x680c, 0x9005, 0x0904, 0x5105, 0x9082, - 0xff01, 0x1a04, 0x5105, 0x6810, 0x9082, 0x005c, 0x06f0, 0x6824, - 0x2008, 0x9082, 0x0008, 0x06c8, 0x9182, 0x0400, 0x16b0, 0x0056, - 0x2029, 0x0000, 0x080c, 0x9077, 0x005e, 0x6944, 0x6820, 0x9102, - 0x0660, 0x6820, 0x9082, 0x0019, 0x1640, 0x6828, 0x6944, 0x810c, - 0x9102, 0x0618, 0x6840, 0x9082, 0x000f, 0x12f8, 0x080c, 0x1072, - 0x2900, 0x0590, 0x684e, 0x00e6, 0x2071, 0x1931, 0x00b6, 0x2059, - 0x0000, 0x080c, 0x8f33, 0x00be, 0x00ee, 0x01e8, 0x080c, 0x8c78, - 0x080c, 0x8cc7, 0x1160, 0x6857, 0x0000, 0x00c6, 0x6b10, 0x2061, - 0x1a6e, 0x630e, 0x00ce, 0x0804, 0x368d, 0x0804, 0x36c2, 0x080c, - 0x8cc0, 0x00e6, 0x2071, 0x1931, 0x080c, 0x90f7, 0x080c, 0x9106, - 0x080c, 0x8f18, 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x108b, - 0x2001, 0x188a, 0x2003, 0x0000, 0x0804, 0x36bf, 0x0126, 0x2091, - 0x8000, 0x080c, 0x94b8, 0x080c, 0x8cc0, 0x012e, 0x0804, 0x368d, - 0x0006, 0x080c, 0x5840, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, - 0x5844, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, - 0x1118, 0x7986, 0x0804, 0x368d, 0x83ff, 0x1904, 0x36c2, 0x2001, - 0xfff0, 0x9200, 0x1a04, 0x36c2, 0x2019, 0xffff, 0x6078, 0x9302, - 0x9200, 0x0a04, 0x36c2, 0x7986, 0x6276, 0x0804, 0x368d, 0x080c, - 0x5854, 0x1904, 0x36bf, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, - 0x4c41, 0x0904, 0x36bf, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, + 0xa496, 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x4819, + 0x0005, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bfb, 0x0904, 0x36a8, + 0x080c, 0x6bcd, 0x1904, 0x36a5, 0x00c6, 0x080c, 0x4bc8, 0x00ce, + 0x0904, 0x36a5, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, + 0x080c, 0xcdaa, 0x0904, 0x36a5, 0x7007, 0x0003, 0x701f, 0x481d, + 0x0005, 0x080c, 0x435b, 0x0804, 0x3673, 0xa830, 0x9086, 0x0100, + 0x0904, 0x36a5, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x0804, 0x4c14, 0x9006, 0x080c, 0x270a, 0x78a8, 0x9084, + 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x36a5, 0x080c, + 0x769d, 0x0110, 0x080c, 0x613d, 0x7888, 0x908a, 0x1000, 0x1a04, + 0x36a8, 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, + 0x36a8, 0x2100, 0x080c, 0x26d4, 0x0026, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x2061, 0x1a05, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, + 0x0000, 0x607f, 0x0000, 0x080c, 0x769d, 0x1158, 0x080c, 0x799f, + 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1, 0x080c, 0x75cc, + 0x00f0, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c, 0xab13, 0x2061, + 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, + 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, + 0x0000, 0x2009, 0x002d, 0x2011, 0x6063, 0x080c, 0x88f6, 0x7984, + 0x080c, 0x769d, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x46c4, + 0x012e, 0x00ce, 0x002e, 0x0804, 0x3673, 0x7984, 0x080c, 0x6718, + 0x2b08, 0x1904, 0x36a8, 0x0804, 0x3673, 0x81ff, 0x0120, 0x2009, + 0x0001, 0x0804, 0x36a5, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, + 0x2009, 0x0005, 0x0804, 0x36a5, 0x080c, 0x4bc8, 0x1120, 0x2009, + 0x0002, 0x0804, 0x36a5, 0x7984, 0x81ff, 0x0904, 0x36a8, 0x9192, + 0x0021, 0x1a04, 0x36a8, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, + 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4c11, 0x701f, + 0x48d8, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x52ba, 0x0005, + 0x2009, 0x0080, 0x080c, 0x6783, 0x1118, 0x080c, 0x6bcd, 0x0120, + 0x2021, 0x400a, 0x0804, 0x3675, 0x00d6, 0x0096, 0xa964, 0xaa6c, + 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, + 0x4971, 0x90be, 0x0112, 0x0904, 0x4971, 0x90be, 0x0113, 0x0904, + 0x4971, 0x90be, 0x0114, 0x0904, 0x4971, 0x90be, 0x0117, 0x0904, + 0x4971, 0x90be, 0x011a, 0x0904, 0x4971, 0x90be, 0x011c, 0x0904, + 0x4971, 0x90be, 0x0121, 0x0904, 0x4958, 0x90be, 0x0131, 0x0904, + 0x4958, 0x90be, 0x0171, 0x0904, 0x4971, 0x90be, 0x0173, 0x0904, + 0x4971, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, + 0x497c, 0x90be, 0x0212, 0x0904, 0x4965, 0x90be, 0x0213, 0x05e8, + 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, + 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, + 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x36a8, 0x7028, + 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, + 0x0007, 0x080c, 0x49ba, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, + 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49ba, 0x00c8, + 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, + 0x20a9, 0x0001, 0x080c, 0x49c7, 0x00b8, 0x7028, 0x9080, 0x000e, + 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, + 0x49c7, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, + 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4bc8, 0x0550, + 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, + 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, + 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, + 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xcdc5, + 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, + 0x49b1, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, + 0x36a5, 0xa820, 0x9086, 0x8001, 0x1904, 0x3673, 0x2009, 0x0004, + 0x0804, 0x36a5, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, + 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, + 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, + 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, + 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, + 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, + 0x36a5, 0x7984, 0x78a8, 0x2040, 0x080c, 0xae80, 0x1120, 0x9182, + 0x007f, 0x0a04, 0x36a8, 0x9186, 0x00ff, 0x0904, 0x36a8, 0x9182, + 0x0800, 0x1a04, 0x36a8, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, + 0x6080, 0x924e, 0x0904, 0x36a8, 0x080c, 0xae80, 0x1120, 0x99cc, + 0xff00, 0x0904, 0x36a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x4adb, + 0x0904, 0x4a5b, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6, + 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24, + 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34, + 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6bcd, 0x0110, + 0xc89d, 0x0438, 0x900e, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007, + 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, + 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108, + 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804, + 0x3675, 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, + 0x00e6, 0x2c70, 0x080c, 0xafbf, 0x0904, 0x4ab0, 0x2b00, 0x6012, + 0x080c, 0xd0ce, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4bc8, + 0x00ce, 0x2b70, 0x1158, 0x080c, 0xaf4e, 0x00ee, 0x00ce, 0x00be, + 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x36a5, 0x900e, 0xa966, + 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, + 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, 0x32fb, 0x6023, 0x0001, + 0x9006, 0x080c, 0x66b5, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, + 0x66c9, 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x66c9, + 0x2009, 0x0002, 0x080c, 0xafec, 0x78a8, 0xd094, 0x0138, 0x00ee, + 0x7024, 0x00e6, 0x2058, 0xb8d4, 0xc08d, 0xb8d6, 0x9085, 0x0001, + 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, + 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x4abf, 0x0005, 0xa830, + 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, + 0x9294, 0x00ff, 0x0804, 0x576e, 0x900e, 0xa868, 0xd0f4, 0x1904, + 0x3673, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, + 0xc18d, 0x0804, 0x3673, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, + 0x4b2a, 0x902e, 0x080c, 0xae80, 0x0130, 0x9026, 0x20a9, 0x0800, + 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, + 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, 0x4b3b, + 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, 0x0030, + 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, 0x00ff, + 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11e8, + 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, 0xd884, + 0x0598, 0xd894, 0x1588, 0x080c, 0x6b6d, 0x1570, 0x2001, 0x4000, + 0x0460, 0x080c, 0x6bcd, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, + 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, + 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xae80, 0x1900, + 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4af1, 0x85ff, + 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, + 0x6718, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, + 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, + 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x36a8, + 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x36a8, 0x2010, + 0x2918, 0x080c, 0x329b, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, + 0x7007, 0x0003, 0x701f, 0x4b7d, 0x0005, 0xa830, 0x9086, 0x0100, + 0x1904, 0x3673, 0x2009, 0x0004, 0x0804, 0x36a5, 0x7984, 0x080c, + 0xae80, 0x1120, 0x9182, 0x007f, 0x0a04, 0x36a8, 0x9186, 0x00ff, + 0x0904, 0x36a8, 0x9182, 0x0800, 0x1a04, 0x36a8, 0x2001, 0x9400, + 0x080c, 0x57c9, 0x1904, 0x36a5, 0x0804, 0x3673, 0xa998, 0x080c, + 0xae80, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, + 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x57c9, 0x11a8, + 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, + 0x080c, 0x104d, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, + 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, + 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, + 0x080c, 0x6783, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x6783, 0x1130, + 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, + 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x6783, 0x1108, + 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, + 0x2148, 0xa904, 0x080c, 0x107f, 0x0cc8, 0x7116, 0x711a, 0x001e, + 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b8, + 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, + 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x3673, 0x0005, + 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18b0, + 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c45, 0x7a36, 0x7833, 0x0012, + 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11f4, 0x0804, 0x4cab, 0x0016, 0x0086, 0x0096, + 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, 0x7148, + 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x104d, 0x0904, + 0x4ca3, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, + 0x1ede, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, + 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, 0x703a, + 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, + 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, + 0x0036, 0x1a0c, 0x0d79, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, + 0xa146, 0x1520, 0x080c, 0x104d, 0x1130, 0x8109, 0xa946, 0x7148, + 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, + 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ede, + 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, + 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, + 0x001b, 0x0002, 0x4ccd, 0x4ccd, 0x4ccf, 0x4ccd, 0x4ccd, 0x4ccd, + 0x4cd3, 0x4ccd, 0x4ccd, 0x4ccd, 0x4cd7, 0x4ccd, 0x4ccd, 0x4ccd, + 0x4cdb, 0x4ccd, 0x4ccd, 0x4ccd, 0x4cdf, 0x4ccd, 0x4ccd, 0x4ccd, + 0x4ce3, 0x4ccd, 0x4ccd, 0x4ccd, 0x4ce8, 0x080c, 0x0d79, 0xa276, + 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, + 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, + 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4ca6, + 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4ca6, 0x00e6, 0x2071, 0x189e, + 0x7048, 0x9005, 0x0904, 0x4d7f, 0x0126, 0x2091, 0x8000, 0x0e04, + 0x4d7e, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, + 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, + 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0d79, 0x2060, 0x001e, 0x8108, + 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d81, 0xa804, 0x9005, 0x090c, + 0x0d79, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, + 0x9080, 0x1ede, 0x2005, 0xa04a, 0x0804, 0x4d81, 0x703c, 0x2060, + 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, + 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x87ff, 0x0118, 0x2748, + 0x080c, 0x107f, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, + 0x2048, 0x9005, 0x0128, 0x080c, 0x107f, 0x9006, 0x7042, 0x7046, + 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, 0x1508, + 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18fa, + 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, + 0x7044, 0x9005, 0x090c, 0x0d79, 0x2048, 0xa800, 0x9005, 0x1de0, + 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1ede, 0x2005, 0xa84a, + 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, + 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4da0, 0x4da0, 0x4da2, + 0x4da0, 0x4da0, 0x4da0, 0x4da7, 0x4da0, 0x4da0, 0x4da0, 0x4dac, + 0x4da0, 0x4da0, 0x4da0, 0x4db1, 0x4da0, 0x4da0, 0x4da0, 0x4db6, + 0x4da0, 0x4da0, 0x4da0, 0x4dbb, 0x4da0, 0x4da0, 0x4da0, 0x4dc0, + 0x080c, 0x0d79, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4d2c, 0xaa84, + 0xab88, 0xac8c, 0x0804, 0x4d2c, 0xaa94, 0xab98, 0xac9c, 0x0804, + 0x4d2c, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4d2c, 0xaab4, 0xabb8, + 0xacbc, 0x0804, 0x4d2c, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4d2c, + 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4d2c, 0x0016, 0x0026, 0x0036, + 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x6783, 0x2019, 0x0001, + 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, 0x080c, + 0x4c28, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, + 0x080c, 0x5820, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4c28, + 0x002e, 0x0005, 0x81ff, 0x1904, 0x36a5, 0x0126, 0x2091, 0x8000, + 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x769d, 0x1158, + 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1, + 0x080c, 0x75cc, 0x0010, 0x080c, 0x6033, 0x012e, 0x0804, 0x3673, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c, 0x5834, + 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x080c, 0x6bc5, 0x0120, + 0x2009, 0x0008, 0x0804, 0x36a5, 0x7984, 0x080c, 0x6718, 0x1904, + 0x36a8, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x2b00, 0x7026, 0x080c, + 0x6bcd, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, + 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, + 0x3673, 0x080c, 0x4bc8, 0x0904, 0x36a5, 0x9006, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce6c, 0x0904, 0x36a5, 0x7888, + 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f, + 0x4e9b, 0x0005, 0x2061, 0x1800, 0x080c, 0x5834, 0x2009, 0x0007, + 0x1560, 0x080c, 0x6bc5, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, + 0x080c, 0x6718, 0x1530, 0x080c, 0x4bf9, 0x0518, 0x080c, 0x6bcd, + 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6a74, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, + 0xc0fc, 0xa86a, 0x080c, 0xce6c, 0x11e0, 0xa89c, 0xd094, 0x0118, + 0xb8d4, 0xc08d, 0xb8d6, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, + 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, + 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, + 0x0005, 0x9006, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, + 0x1110, 0x0804, 0x576e, 0x900e, 0x080c, 0x6a74, 0x1108, 0xc185, + 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3673, 0x080c, 0x5834, + 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7f84, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, + 0x36a5, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, + 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x6783, 0x1904, + 0x4f44, 0x080c, 0x6bcd, 0x0138, 0x080c, 0x6bd5, 0x0120, 0x080c, + 0x6b6d, 0x1904, 0x4f44, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, + 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0198, + 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, + 0x0002, 0x080c, 0x49c7, 0x0080, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, + 0x3d00, 0x20e0, 0x080c, 0x49c7, 0x9186, 0x007e, 0x0170, 0x9186, + 0x0080, 0x0158, 0x080c, 0x6bcd, 0x90c2, 0x0006, 0x1210, 0xc1fd, + 0x0020, 0x080c, 0x6a74, 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794, + 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098, + 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, + 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, + 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x49ba, 0x9c80, 0x0026, + 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, + 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xae80, 0x0118, + 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, + 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, + 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4ecd, 0x86ff, 0x1120, + 0x7124, 0x810b, 0x0804, 0x3673, 0x7033, 0x0001, 0x7122, 0x7024, + 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, + 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, + 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x4f80, 0x0005, + 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, + 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, + 0xa598, 0x0804, 0x4ecd, 0x7124, 0x810b, 0x0804, 0x3673, 0x2029, + 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, + 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9184, + 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, + 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, + 0x0a04, 0x36a8, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8, + 0x9502, 0x0a04, 0x36a8, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, + 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9384, 0x00ff, 0x90e2, + 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9484, 0xff00, + 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, + 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, + 0x36a8, 0x2061, 0x198a, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, + 0x3673, 0x080c, 0x4bc8, 0x0904, 0x36a5, 0x2009, 0x0016, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, + 0x4c11, 0x701f, 0x5004, 0x0005, 0x2001, 0x0138, 0x2003, 0x0000, + 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x20a9, + 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019, + 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001, + 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x5085, 0x6804, 0x2008, + 0x918c, 0xfff8, 0x1904, 0x5085, 0x680c, 0x9005, 0x0904, 0x5085, + 0x9082, 0xff01, 0x1a04, 0x5085, 0x6810, 0x9082, 0x005c, 0x0a04, + 0x5085, 0x6824, 0x2008, 0x9082, 0x0008, 0x0a04, 0x5085, 0x9182, + 0x0400, 0x1a04, 0x5085, 0x0056, 0x2029, 0x0000, 0x080c, 0x8f0d, + 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, 0x0019, + 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, 0x0678, 0x6840, 0x9082, + 0x000f, 0x1658, 0x080c, 0x1066, 0x2900, 0x0904, 0x50a1, 0x684e, + 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8dc9, + 0x00be, 0x00ee, 0x0568, 0x080c, 0x8b11, 0x080c, 0x8b60, 0x11e0, + 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, 0x2000, + 0x6106, 0x6b10, 0x2061, 0x1a6f, 0x630e, 0x00ce, 0x080c, 0x27b9, + 0x2001, 0x0138, 0x2102, 0x0804, 0x3673, 0x080c, 0x27b9, 0x2001, + 0x0138, 0x2102, 0x0804, 0x36a8, 0x080c, 0x8b59, 0x00e6, 0x2071, + 0x1932, 0x080c, 0x8f8d, 0x080c, 0x8f9c, 0x080c, 0x8dac, 0x00ee, + 0x2001, 0x188a, 0x204c, 0x080c, 0x107f, 0x2001, 0x188a, 0x2003, + 0x0000, 0x080c, 0x27b9, 0x2001, 0x0138, 0x2102, 0x0804, 0x36a5, + 0x2001, 0x1926, 0x200c, 0x918e, 0x0000, 0x0904, 0x5106, 0x080c, + 0x8da7, 0x0904, 0x5106, 0x2001, 0x0101, 0x200c, 0x918c, 0xdfff, + 0x2102, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, + 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c, 0x8dac, 0x0126, 0x2091, + 0x8000, 0x2001, 0x0035, 0x080c, 0x16ad, 0x012e, 0x00c6, 0x2061, + 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, 0x27b9, + 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925, 0x080c, + 0x8ce6, 0x0120, 0x2f00, 0x080c, 0x8d72, 0x0cc8, 0x00fe, 0x00ee, + 0x0126, 0x2091, 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0138, + 0x2148, 0x080c, 0x107f, 0x2001, 0x188a, 0x2003, 0x0000, 0x2001, + 0x183e, 0x2003, 0x0020, 0x080c, 0x8b59, 0x00e6, 0x2071, 0x1932, + 0x080c, 0x8f8d, 0x080c, 0x8f9c, 0x00ee, 0x012e, 0x0804, 0x3673, + 0x0006, 0x080c, 0x5820, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, + 0x5824, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, + 0x1118, 0x7986, 0x0804, 0x3673, 0x83ff, 0x1904, 0x36a8, 0x2001, + 0xfff0, 0x9200, 0x1a04, 0x36a8, 0x2019, 0xffff, 0x6078, 0x9302, + 0x9200, 0x0a04, 0x36a8, 0x7986, 0x6276, 0x0804, 0x3673, 0x080c, + 0x5834, 0x1904, 0x36a5, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, + 0x4bc8, 0x0904, 0x36a5, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, - 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6c11, 0x0118, 0x080c, - 0x6c19, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004, + 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c, + 0x6bd5, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, 0x2001, - 0x0003, 0x080c, 0x955b, 0x2208, 0x0804, 0x368d, 0x7033, 0x0001, + 0x0003, 0x080c, 0x9364, 0x2208, 0x0804, 0x3673, 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592, - 0xa696, 0xa79a, 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x51a9, + 0xa696, 0xa79a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x5189, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694, - 0xa798, 0x0804, 0x5167, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, - 0x955b, 0x2208, 0x0804, 0x368d, 0x00f6, 0x00e6, 0x080c, 0x5854, - 0x2009, 0x0007, 0x1904, 0x523c, 0x2071, 0x189e, 0x745c, 0x84ff, - 0x2009, 0x000e, 0x1904, 0x523c, 0xac9c, 0xad98, 0xaea4, 0xafa0, - 0x0096, 0x080c, 0x1072, 0x2009, 0x0002, 0x0904, 0x523c, 0x2900, + 0xa798, 0x0804, 0x5147, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, + 0x9364, 0x2208, 0x0804, 0x3673, 0x00f6, 0x00e6, 0x080c, 0x5834, + 0x2009, 0x0007, 0x1904, 0x521c, 0x2071, 0x189e, 0x745c, 0x84ff, + 0x2009, 0x000e, 0x1904, 0x521c, 0xac9c, 0xad98, 0xaea4, 0xafa0, + 0x0096, 0x080c, 0x1066, 0x2009, 0x0002, 0x0904, 0x521c, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, - 0x0178, 0x080c, 0x6c11, 0x0118, 0x080c, 0x6c19, 0x1148, 0xb814, + 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20, - 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x955b, + 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x9364, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c, - 0x0d85, 0x2148, 0x080c, 0x108b, 0x9006, 0x705e, 0x918d, 0x0001, + 0x0d79, 0x2148, 0x080c, 0x107f, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, 0xa072, - 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x5248, 0x000e, 0xa0a2, - 0x080c, 0x114e, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, + 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x5228, 0x000e, 0xa0a2, + 0x080c, 0x1142, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005, - 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0x00e6, 0x2071, 0x189e, + 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0d79, 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x7254, - 0x900e, 0x2001, 0x0003, 0x080c, 0x955b, 0xaa9a, 0x715c, 0x81ff, - 0x090c, 0x0d85, 0x2148, 0x080c, 0x108b, 0x705f, 0x0000, 0xa0a0, - 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0xa09f, + 0x900e, 0x2001, 0x0003, 0x080c, 0x9364, 0xaa9a, 0x715c, 0x81ff, + 0x090c, 0x0d79, 0x2148, 0x080c, 0x107f, 0x705f, 0x0000, 0xa0a0, + 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, - 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6c11, 0x0118, 0x080c, 0x6c19, + 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, 0xa897, - 0x4000, 0x715c, 0x81ff, 0x090c, 0x0d85, 0x2148, 0x080c, 0x108b, + 0x4000, 0x715c, 0x81ff, 0x090c, 0x0d79, 0x2148, 0x080c, 0x107f, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, - 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0xa09f, 0x0000, 0xa0a3, + 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, - 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x114e, 0x9006, + 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1142, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be, - 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x36c2, - 0xa884, 0xa988, 0x080c, 0x268c, 0x1518, 0x080c, 0x6749, 0x1500, - 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4c41, 0x01c8, 0x080c, - 0x4c41, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, - 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xd0cd, 0x1120, 0x2009, - 0x0003, 0x0804, 0x36bf, 0x7007, 0x0003, 0x701f, 0x5315, 0x0005, - 0x009e, 0x2009, 0x0002, 0x0804, 0x36bf, 0x7124, 0x080c, 0x341e, - 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x36bf, + 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x36a8, + 0xa884, 0xa988, 0x080c, 0x26a1, 0x1518, 0x080c, 0x6718, 0x1500, + 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4bc8, 0x01c8, 0x080c, + 0x4bc8, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xcde5, 0x1120, 0x2009, + 0x0003, 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x52f5, 0x0005, + 0x009e, 0x2009, 0x0002, 0x0804, 0x36a5, 0x7124, 0x080c, 0x3404, + 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, - 0x0fd6, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44, + 0x0fca, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, 0x000e, - 0x007e, 0x0804, 0x4c8d, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, + 0x007e, 0x0804, 0x4c14, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772, - 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, - 0x7007, 0x0002, 0x701f, 0x5371, 0x0005, 0x000e, 0x007e, 0x0804, - 0x36c2, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, + 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1142, + 0x7007, 0x0002, 0x701f, 0x5351, 0x0005, 0x000e, 0x007e, 0x0804, + 0x36a8, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, - 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fd6, + 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fca, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, - 0xa598, 0x2009, 0x002a, 0x0804, 0x4c8d, 0x81ff, 0x1904, 0x36bf, - 0x798c, 0x2001, 0x197e, 0x918c, 0x8000, 0x2102, 0x080c, 0x4c58, - 0x0904, 0x36c2, 0x080c, 0x6c11, 0x0120, 0x080c, 0x6c19, 0x1904, - 0x36c2, 0x080c, 0x687b, 0x0904, 0x36bf, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6a1b, 0x012e, 0x0904, 0x36bf, 0x2001, 0x197e, 0x2004, - 0xd0fc, 0x1904, 0x368d, 0x0804, 0x46aa, 0xa9a0, 0x2001, 0x197e, - 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4c65, 0x01a0, 0x080c, - 0x6c11, 0x0118, 0x080c, 0x6c19, 0x1170, 0x080c, 0x687b, 0x2009, - 0x0002, 0x0128, 0x080c, 0x6a1b, 0x1170, 0x2009, 0x0003, 0xa897, + 0xa598, 0x2009, 0x002a, 0x0804, 0x4c14, 0x81ff, 0x1904, 0x36a5, + 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, 0x4bdf, + 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x0120, 0x080c, 0x6bd5, 0x1904, + 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x0126, 0x2091, 0x8000, + 0x080c, 0x69e1, 0x012e, 0x0904, 0x36a5, 0x2001, 0x197f, 0x2004, + 0xd0fc, 0x1904, 0x3673, 0x0804, 0x4661, 0xa9a0, 0x2001, 0x197f, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bec, 0x01a0, 0x080c, + 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1170, 0x080c, 0x684a, 0x2009, + 0x0002, 0x0128, 0x080c, 0x69e1, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, - 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197e, 0x2004, - 0xd0fc, 0x1128, 0x080c, 0x5848, 0x0110, 0x9006, 0x0018, 0x900e, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, - 0xd084, 0x0904, 0x461f, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x080c, - 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, 0x080c, 0x6c11, + 0xd084, 0x0904, 0x45d6, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x080c, 0x6bcd, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, - 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x5840, - 0xd0b4, 0x0904, 0x4659, 0x7884, 0x908e, 0x007e, 0x0904, 0x4659, - 0x908e, 0x007f, 0x0904, 0x4659, 0x908e, 0x0080, 0x0904, 0x4659, - 0xb800, 0xd08c, 0x1904, 0x4659, 0xa867, 0x0000, 0xa868, 0xc0fd, - 0xa86a, 0x080c, 0xd0ec, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, - 0x7007, 0x0003, 0x701f, 0x543d, 0x0005, 0x080c, 0x4c74, 0x0904, - 0x36c2, 0x0804, 0x4659, 0x080c, 0x347d, 0x0108, 0x0005, 0x2009, - 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, - 0x080c, 0x5854, 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x080c, - 0x6c09, 0x0120, 0x2009, 0x0008, 0x0804, 0x36bf, 0xb89c, 0xd0a4, - 0x1118, 0xd0ac, 0x1904, 0x4659, 0x9006, 0xa866, 0xa832, 0xa868, - 0xc0fd, 0xa86a, 0x080c, 0xd154, 0x1120, 0x2009, 0x0003, 0x0804, - 0x36bf, 0x7007, 0x0003, 0x701f, 0x5476, 0x0005, 0xa830, 0x9086, - 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x578e, 0x080c, 0x4c74, - 0x0904, 0x36c2, 0x0804, 0x540f, 0x81ff, 0x2009, 0x0001, 0x1904, - 0x36bf, 0x080c, 0x5854, 0x2009, 0x0007, 0x1904, 0x36bf, 0x080c, - 0x6c09, 0x0120, 0x2009, 0x0008, 0x0804, 0x36bf, 0x080c, 0x4c74, - 0x0904, 0x36c2, 0x080c, 0x6c11, 0x2009, 0x0009, 0x1904, 0x36bf, - 0x080c, 0x4c41, 0x2009, 0x0002, 0x0904, 0x36bf, 0x9006, 0xa866, + 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x5820, + 0xd0b4, 0x0904, 0x4610, 0x7884, 0x908e, 0x007e, 0x0904, 0x4610, + 0x908e, 0x007f, 0x0904, 0x4610, 0x908e, 0x0080, 0x0904, 0x4610, + 0xb800, 0xd08c, 0x1904, 0x4610, 0xa867, 0x0000, 0xa868, 0xc0fd, + 0xa86a, 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, + 0x7007, 0x0003, 0x701f, 0x541d, 0x0005, 0x080c, 0x4bfb, 0x0904, + 0x36a8, 0x0804, 0x4610, 0x080c, 0x3463, 0x0108, 0x0005, 0x2009, + 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, + 0x080c, 0x5834, 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x080c, + 0x6bc5, 0x0120, 0x2009, 0x0008, 0x0804, 0x36a5, 0xb89c, 0xd0a4, + 0x1118, 0xd0ac, 0x1904, 0x4610, 0x9006, 0xa866, 0xa832, 0xa868, + 0xc0fd, 0xa86a, 0x080c, 0xce6c, 0x1120, 0x2009, 0x0003, 0x0804, + 0x36a5, 0x7007, 0x0003, 0x701f, 0x5456, 0x0005, 0xa830, 0x9086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x576e, 0x080c, 0x4bfb, + 0x0904, 0x36a8, 0x0804, 0x53ef, 0x81ff, 0x2009, 0x0001, 0x1904, + 0x36a5, 0x080c, 0x5834, 0x2009, 0x0007, 0x1904, 0x36a5, 0x080c, + 0x6bc5, 0x0120, 0x2009, 0x0008, 0x0804, 0x36a5, 0x080c, 0x4bfb, + 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x2009, 0x0009, 0x1904, 0x36a5, + 0x080c, 0x4bc8, 0x2009, 0x0002, 0x0904, 0x36a5, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c, - 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x36c2, 0xc0e5, 0xa952, - 0xa956, 0xa83e, 0x080c, 0xd3b7, 0x2009, 0x0003, 0x0904, 0x36bf, - 0x7007, 0x0003, 0x701f, 0x54cd, 0x0005, 0xa830, 0x9086, 0x0100, - 0x2009, 0x0004, 0x0904, 0x36bf, 0x0804, 0x368d, 0x7aa8, 0x9284, - 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x5854, 0x1188, 0x2009, - 0x0014, 0x0804, 0x36bf, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001, - 0x1904, 0x36bf, 0x080c, 0x5854, 0x2009, 0x0007, 0x1904, 0x36bf, - 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x581a, 0x0804, - 0x368d, 0xd2fc, 0x0160, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x7984, - 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57e9, 0x0804, 0x368d, 0x080c, - 0x4c74, 0x0904, 0x36c2, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, - 0x2009, 0x0009, 0x1904, 0x55bc, 0x080c, 0x4c41, 0x2009, 0x0002, - 0x0904, 0x55bc, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008, - 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4c8a, 0x701f, 0x5529, + 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x36a8, 0xc0e5, 0xa952, + 0xa956, 0xa83e, 0x080c, 0xd0cf, 0x2009, 0x0003, 0x0904, 0x36a5, + 0x7007, 0x0003, 0x701f, 0x54ad, 0x0005, 0xa830, 0x9086, 0x0100, + 0x2009, 0x0004, 0x0904, 0x36a5, 0x0804, 0x3673, 0x7aa8, 0x9284, + 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x5834, 0x1188, 0x2009, + 0x0014, 0x0804, 0x36a5, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001, + 0x1904, 0x36a5, 0x080c, 0x5834, 0x2009, 0x0007, 0x1904, 0x36a5, + 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x57fa, 0x0804, + 0x3673, 0xd2fc, 0x0160, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x7984, + 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57c9, 0x0804, 0x3673, 0x080c, + 0x4bfb, 0x0904, 0x36a8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, + 0x2009, 0x0009, 0x1904, 0x559c, 0x080c, 0x4bc8, 0x2009, 0x0002, + 0x0904, 0x559c, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4c11, 0x701f, 0x5509, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, 0x1120, - 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x36c2, 0xa866, 0xa832, - 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4c74, 0x1110, 0x0804, 0x36c2, - 0x2009, 0x0043, 0x080c, 0xd423, 0x2009, 0x0003, 0x0904, 0x55bc, - 0x7007, 0x0003, 0x701f, 0x554d, 0x0005, 0xa830, 0x9086, 0x0100, - 0x2009, 0x0004, 0x0904, 0x55bc, 0x7984, 0x7aa8, 0x9284, 0x1000, - 0xc0d5, 0x080c, 0x57e9, 0x0804, 0x368d, 0x00c6, 0xaab0, 0x9284, - 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x5854, 0x1158, 0x2009, - 0x0014, 0x0804, 0x55ab, 0x2061, 0x1800, 0x080c, 0x5854, 0x2009, + 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x36a8, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bfb, 0x1110, 0x0804, 0x36a8, + 0x2009, 0x0043, 0x080c, 0xd13b, 0x2009, 0x0003, 0x0904, 0x559c, + 0x7007, 0x0003, 0x701f, 0x552d, 0x0005, 0xa830, 0x9086, 0x0100, + 0x2009, 0x0004, 0x0904, 0x559c, 0x7984, 0x7aa8, 0x9284, 0x1000, + 0xc0d5, 0x080c, 0x57c9, 0x0804, 0x3673, 0x00c6, 0xaab0, 0x9284, + 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x5834, 0x1158, 0x2009, + 0x0014, 0x0804, 0x558b, 0x2061, 0x1800, 0x080c, 0x5834, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, 0x080c, - 0x581a, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4c72, 0x0590, 0xa998, - 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57e9, 0xa87b, 0x0000, 0xa883, - 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4c72, 0x0510, 0x080c, - 0x6c11, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, + 0x57fa, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4bf9, 0x0590, 0xa998, + 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57c9, 0xa87b, 0x0000, 0xa883, + 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4bf9, 0x0510, 0x080c, + 0x6bcd, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, - 0x4c72, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd423, 0x2009, + 0x4bf9, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd13b, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, - 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x36bf, - 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57e9, 0x001e, - 0x1904, 0x36bf, 0x0804, 0x368d, 0x00f6, 0x2d78, 0xaab0, 0x0021, + 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x36a5, + 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57c9, 0x001e, + 0x1904, 0x36a5, 0x0804, 0x3673, 0x00f6, 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, 0xa998, - 0x9284, 0x1400, 0xc0fd, 0x080c, 0x57e9, 0x001e, 0x9085, 0x0001, - 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, 0x080c, - 0x5854, 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x7984, 0x7ea8, - 0x96b4, 0x00ff, 0x080c, 0x67b4, 0x1904, 0x36c2, 0x9186, 0x007f, - 0x0138, 0x080c, 0x6c11, 0x0120, 0x2009, 0x0009, 0x0804, 0x36bf, - 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, 0xa867, + 0x9284, 0x1400, 0xc0fd, 0x080c, 0x57c9, 0x001e, 0x9085, 0x0001, + 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c, + 0x5834, 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7984, 0x7ea8, + 0x96b4, 0x00ff, 0x080c, 0x6783, 0x1904, 0x36a8, 0x9186, 0x007f, + 0x0138, 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0009, 0x0804, 0x36a5, + 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, - 0x080c, 0xd106, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, 0x7007, - 0x0003, 0x701f, 0x561c, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100, - 0x1120, 0x2009, 0x0004, 0x0804, 0x36bf, 0xa8e0, 0xa866, 0xa810, + 0x080c, 0xce1e, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007, + 0x0003, 0x701f, 0x55fc, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100, + 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, 0x7c9c, - 0x7d98, 0x0804, 0x4c8d, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, - 0x0804, 0x36bf, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, - 0x82ff, 0x1118, 0x7023, 0x19b4, 0x0040, 0x92c6, 0x0001, 0x1118, - 0x7023, 0x19ce, 0x0010, 0x0804, 0x36c2, 0x2009, 0x001a, 0x7a8c, + 0x7d98, 0x0804, 0x4c14, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, + 0x0804, 0x36a5, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, + 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, + 0x7023, 0x19cf, 0x0010, 0x0804, 0x36a8, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, - 0x4c8a, 0x701f, 0x566c, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001, + 0x4c11, 0x701f, 0x564c, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a, - 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x368d, 0x080c, - 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, 0x7984, 0x9194, - 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b4, - 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19ce, 0x0010, 0x0804, - 0x36c2, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, + 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x3673, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x7984, 0x9194, + 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b5, + 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19cf, 0x0010, 0x0804, + 0x36a8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, - 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4c8d, - 0x7884, 0x908a, 0x1000, 0x1a04, 0x36c2, 0x0126, 0x2091, 0x8000, - 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x1a04, 0x614a, - 0x00ce, 0x012e, 0x0804, 0x368d, 0x00c6, 0x080c, 0x779e, 0x1160, - 0x080c, 0x7ab6, 0x080c, 0x619d, 0x9085, 0x0001, 0x080c, 0x77e2, - 0x080c, 0x76cd, 0x080c, 0x0d85, 0x2061, 0x1800, 0x6030, 0xc09d, - 0x6032, 0x080c, 0x6058, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, - 0x2004, 0x908e, 0x0000, 0x0904, 0x36bf, 0x7884, 0x9005, 0x0188, - 0x7888, 0x2061, 0x199c, 0x2c0c, 0x2062, 0x080c, 0x2a67, 0x01a0, - 0x080c, 0x2a6f, 0x0188, 0x080c, 0x2a77, 0x0170, 0x2162, 0x0804, - 0x36c2, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009, + 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4c14, + 0x7884, 0x908a, 0x1000, 0x1a04, 0x36a8, 0x0126, 0x2091, 0x8000, + 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x1a05, 0x614a, + 0x00ce, 0x012e, 0x0804, 0x3673, 0x00c6, 0x080c, 0x769d, 0x1160, + 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1, + 0x080c, 0x75cc, 0x080c, 0x0d79, 0x2061, 0x1800, 0x6030, 0xc09d, + 0x6032, 0x080c, 0x6033, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, + 0x2004, 0x908e, 0x0000, 0x0904, 0x36a5, 0x7884, 0x9005, 0x0188, + 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062, 0x080c, 0x2a70, 0x01a0, + 0x080c, 0x2a78, 0x0188, 0x080c, 0x2a80, 0x0170, 0x2162, 0x0804, + 0x36a8, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, 0x15a8, - 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x080c, 0xacfc, 0x0026, - 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, 0xa635, - 0x002e, 0x080c, 0xa516, 0x0036, 0x901e, 0x080c, 0xa596, 0x003e, - 0x080c, 0xad18, 0x60e3, 0x0000, 0x080c, 0xeed9, 0x080c, 0xeef4, - 0x9085, 0x0001, 0x080c, 0x77e2, 0x9006, 0x080c, 0x2a99, 0x2001, - 0x1800, 0x2003, 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x0026, - 0x2011, 0x0008, 0x080c, 0x2ad3, 0x002e, 0x00ce, 0x0804, 0x368d, - 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, 0x080c, 0x5854, - 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x7984, 0x7ea8, 0x96b4, - 0x00ff, 0x080c, 0x67b4, 0x1904, 0x36c2, 0x9186, 0x007f, 0x0138, - 0x080c, 0x6c11, 0x0120, 0x2009, 0x0009, 0x0804, 0x36bf, 0x080c, - 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, 0xa867, 0x0000, - 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd109, 0x1120, 0x2009, 0x0003, - 0x0804, 0x36bf, 0x7007, 0x0003, 0x701f, 0x5777, 0x0005, 0xa830, - 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x36bf, 0xa8e0, + 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7, 0x0026, + 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, + 0x002e, 0x080c, 0xa311, 0x0036, 0x901e, 0x080c, 0xa391, 0x003e, + 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c, 0xebe8, 0x080c, 0xec03, + 0x9085, 0x0001, 0x080c, 0x76e1, 0x9006, 0x080c, 0x2aa2, 0x2001, + 0x1800, 0x2003, 0x0004, 0x2001, 0x19a9, 0x2003, 0x0000, 0x0026, + 0x2011, 0x0008, 0x080c, 0x2adc, 0x002e, 0x00ce, 0x0804, 0x3673, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c, 0x5834, + 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7984, 0x7ea8, 0x96b4, + 0x00ff, 0x080c, 0x6783, 0x1904, 0x36a8, 0x9186, 0x007f, 0x0138, + 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0009, 0x0804, 0x36a5, 0x080c, + 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867, 0x0000, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce21, 0x1120, 0x2009, 0x0003, + 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x5757, 0x0005, 0xa830, + 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c, - 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4c8d, 0xa898, 0x9086, - 0x000d, 0x1904, 0x36bf, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, - 0x0e04, 0x579b, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, + 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4c14, 0xa898, 0x9086, + 0x000d, 0x1904, 0x36a5, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, + 0x0e04, 0x577b, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, 0x4005, - 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4c7d, - 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, + 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4c04, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, - 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x1a04, 0x7984, 0x615a, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x1a05, 0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, 0x789c, - 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x1a14, 0x2044, - 0x2001, 0x1a1b, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, + 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x1a15, 0x2044, + 0x2001, 0x1a1c, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, - 0x368d, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000, + 0x3673, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000, 0x0198, 0x0006, 0xd0d4, 0x0160, 0x0036, 0x2019, 0x0029, 0x080c, - 0xacfc, 0x0106, 0x080c, 0x3442, 0x010e, 0x090c, 0xad18, 0x003e, - 0x080c, 0xcf68, 0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, - 0x2004, 0x905d, 0x0160, 0x080c, 0x61b7, 0x080c, 0xb094, 0x0110, + 0xaaf7, 0x0106, 0x080c, 0x3428, 0x010e, 0x090c, 0xab13, 0x003e, + 0x080c, 0xcc80, 0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, + 0x2004, 0x905d, 0x0160, 0x080c, 0x6192, 0x080c, 0xae80, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, - 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x57e9, - 0x002e, 0x001e, 0x8108, 0x1f04, 0x5822, 0x015e, 0x012e, 0x0005, + 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x57c9, + 0x002e, 0x001e, 0x8108, 0x1f04, 0x5802, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004, 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, - 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, 0x81ff, 0x0904, 0x36c2, - 0x9182, 0x0081, 0x1a04, 0x36c2, 0x810c, 0x0016, 0x080c, 0x4c41, - 0x0170, 0x080c, 0x0f61, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, - 0x7a90, 0x001e, 0x080c, 0x4c8a, 0x701f, 0x5884, 0x0005, 0x001e, - 0x2009, 0x0002, 0x0804, 0x36bf, 0x2079, 0x0000, 0x7d94, 0x7c98, + 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, 0x81ff, 0x0904, 0x36a8, + 0x9182, 0x0081, 0x1a04, 0x36a8, 0x810c, 0x0016, 0x080c, 0x4bc8, + 0x0170, 0x080c, 0x0f55, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, + 0x7a90, 0x001e, 0x080c, 0x4c11, 0x701f, 0x5864, 0x0005, 0x001e, + 0x2009, 0x0002, 0x0804, 0x36a5, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, - 0xa074, 0x2071, 0x189e, 0x080c, 0x4c8d, 0x701f, 0x5898, 0x0005, + 0xa074, 0x2071, 0x189e, 0x080c, 0x4c14, 0x701f, 0x5878, 0x0005, 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, - 0x0f69, 0x002e, 0x001e, 0x080c, 0x1016, 0x9006, 0xa802, 0xa806, - 0x0804, 0x368d, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, + 0x0f5d, 0x002e, 0x001e, 0x080c, 0x100a, 0x9006, 0xa802, 0xa806, + 0x0804, 0x3673, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, - 0x5a58, 0x0068, 0xd08c, 0x0118, 0x080c, 0x5961, 0x0040, 0xd094, - 0x0118, 0x080c, 0x5931, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, + 0x5a33, 0x0068, 0xd08c, 0x0118, 0x080c, 0x593c, 0x0040, 0xd094, + 0x0118, 0x080c, 0x590c, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, - 0x001e, 0x0c68, 0x7030, 0xd09c, 0x1120, 0x6004, 0x9085, 0x0002, - 0x6006, 0x7098, 0x9005, 0x0120, 0x709b, 0x0000, 0x7093, 0x0000, - 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, - 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, - 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, - 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, - 0x6119, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, - 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, - 0x70df, 0x0000, 0x2009, 0x1d80, 0x200b, 0x0000, 0x7097, 0x0000, - 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, 0x5ffb, 0x080c, 0x8a5d, - 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, - 0x7088, 0x9005, 0x1528, 0x2011, 0x5ffb, 0x080c, 0x8993, 0x6040, - 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, - 0xd08c, 0x1168, 0x1f04, 0x5947, 0x6242, 0x709b, 0x0000, 0x6040, - 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, - 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x61a2, 0x0000, - 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, 0x0d85, 0x000b, 0x0005, - 0x596b, 0x59bc, 0x5a57, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, - 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, - 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x597a, - 0x080c, 0x0d85, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, - 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, - 0x617e, 0x2079, 0x1d00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, - 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1d0e, 0x20a9, - 0x0004, 0x4003, 0x080c, 0xaaf1, 0x20e1, 0x0001, 0x2099, 0x1d00, - 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, - 0x000c, 0x600f, 0x0000, 0x080c, 0x602c, 0x00fe, 0x9006, 0x7092, - 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, - 0x9025, 0x0904, 0x5a34, 0x6020, 0xd0b4, 0x1904, 0x5a32, 0x71a0, - 0x81ff, 0x0904, 0x5a20, 0x9486, 0x000c, 0x1904, 0x5a2d, 0x9480, - 0x0018, 0x8004, 0x20a8, 0x080c, 0x6177, 0x2011, 0x0260, 0x2019, - 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, - 0x59d9, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, - 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, - 0x0002, 0x2009, 0x07d0, 0x2011, 0x6002, 0x080c, 0x8a5d, 0x080c, - 0x617e, 0x04c0, 0x080c, 0x6177, 0x2079, 0x0260, 0x7930, 0x918e, - 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, - 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x6177, 0x2011, 0x026e, - 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, - 0x11a0, 0x8210, 0x8318, 0x1f04, 0x5a14, 0x0078, 0x70a3, 0x0000, - 0x080c, 0x6177, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, - 0x20a1, 0x1d00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, - 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, - 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xaaf1, 0x20e1, 0x0001, 0x2099, - 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, - 0x60c3, 0x000c, 0x2011, 0x19f5, 0x2013, 0x0000, 0x7093, 0x0000, - 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa293, 0x08d8, 0x0005, - 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0d85, 0x000b, 0x0005, 0x5a89, - 0x5a9c, 0x5ac5, 0x5ae5, 0x5b0b, 0x5b3a, 0x5b60, 0x5b98, 0x5bbe, - 0x5bec, 0x5c27, 0x5c5f, 0x5c7d, 0x5ca8, 0x5cca, 0x5ce5, 0x5cef, - 0x5d23, 0x5d49, 0x5d78, 0x5d9e, 0x5dd6, 0x5e1a, 0x5e57, 0x5e78, - 0x5ed1, 0x5ef3, 0x5f21, 0x5f21, 0x00c6, 0x2061, 0x1800, 0x6003, - 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, - 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, - 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, - 0x6002, 0x080c, 0x8a5d, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, - 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x6177, 0x2079, - 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, - 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, - 0x2011, 0x6002, 0x080c, 0x8993, 0x709b, 0x0010, 0x080c, 0x5cef, - 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, - 0x6043, 0x0004, 0x2011, 0x6002, 0x080c, 0x8993, 0x080c, 0x60fb, - 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, - 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5ada, 0x60c3, - 0x0014, 0x080c, 0x602c, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, - 0x0500, 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, 0x0014, 0x11b8, - 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, + 0x001e, 0x0c68, 0x0006, 0x7098, 0x9005, 0x000e, 0x0120, 0x709b, + 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, + 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, + 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, + 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, + 0x2009, 0x00f7, 0x080c, 0x60f4, 0x00f0, 0x6040, 0x9084, 0x0010, + 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, + 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, 0x2009, 0x1d80, 0x200b, + 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, + 0x5fd6, 0x080c, 0x88f6, 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, + 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, 0x1528, 0x2011, 0x5fd6, + 0x080c, 0x882c, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, + 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x5922, 0x6242, + 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, + 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, + 0x080c, 0x617d, 0x0000, 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, + 0x0d79, 0x000b, 0x0005, 0x5946, 0x5997, 0x5a32, 0x00f6, 0x0016, + 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, + 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, + 0x0120, 0x1f04, 0x5955, 0x080c, 0x0d79, 0x68a0, 0x68a2, 0x689c, + 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, + 0x6837, 0x0020, 0x080c, 0x6159, 0x2079, 0x1d00, 0x7833, 0x1101, + 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, + 0x20a1, 0x1d0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0xa8ec, 0x20e1, + 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, 0x6007, + 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, + 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, 0x5a0f, 0x6020, 0xd0b4, + 0x1904, 0x5a0d, 0x71a0, 0x81ff, 0x0904, 0x59fb, 0x9486, 0x000c, + 0x1904, 0x5a08, 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c, 0x6152, + 0x2011, 0x0260, 0x2019, 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8, + 0x8210, 0x8318, 0x1f04, 0x59b4, 0x6043, 0x0004, 0x2061, 0x0140, + 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, + 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x5fdd, + 0x080c, 0x88f6, 0x080c, 0x6159, 0x04c0, 0x080c, 0x6152, 0x2079, + 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, + 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, + 0x6152, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, + 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04, 0x59ef, + 0x0078, 0x70a3, 0x0000, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099, + 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1d00, 0x20a9, 0x0014, 0x4003, + 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, + 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xa8ec, + 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, 0x19f6, 0x2013, + 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, + 0xa08e, 0x08d8, 0x0005, 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0d79, + 0x000b, 0x0005, 0x5a64, 0x5a77, 0x5aa0, 0x5ac0, 0x5ae6, 0x5b15, + 0x5b3b, 0x5b73, 0x5b99, 0x5bc7, 0x5c02, 0x5c3a, 0x5c58, 0x5c83, + 0x5ca5, 0x5cc0, 0x5cca, 0x5cfe, 0x5d24, 0x5d53, 0x5d79, 0x5db1, + 0x5df5, 0x5e32, 0x5e53, 0x5eac, 0x5ece, 0x5efc, 0x5efc, 0x00c6, + 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, + 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, + 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, + 0x2009, 0x07d0, 0x2011, 0x5fdd, 0x080c, 0x88f6, 0x0005, 0x00f6, + 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, + 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, + 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, + 0x1110, 0x70c7, 0x0001, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x709b, + 0x0010, 0x080c, 0x5cca, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, + 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, 0x2011, 0x5fdd, 0x080c, + 0x882c, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, + 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, + 0x1f04, 0x5ab5, 0x60c3, 0x0014, 0x080c, 0x6007, 0x00fe, 0x0005, + 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, + 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0005, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, + 0x0000, 0x080c, 0x6152, 0x080c, 0x6135, 0x1170, 0x7084, 0x9005, + 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, + 0x5f8a, 0x0168, 0x080c, 0x610b, 0x20a9, 0x0008, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, + 0x0014, 0x080c, 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8, + 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, - 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, - 0x6153, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x60fb, - 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6177, - 0x080c, 0x615a, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, - 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5faf, 0x0168, 0x080c, - 0x6130, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, - 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x602c, - 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x6002, - 0x080c, 0x8993, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6177, 0x2079, - 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, - 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, - 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, 0x6153, 0x00fe, 0x0005, - 0x00f6, 0x709b, 0x0007, 0x080c, 0x60fb, 0x2079, 0x0240, 0x7833, - 0x1104, 0x7837, 0x0000, 0x080c, 0x6177, 0x080c, 0x615a, 0x11b8, - 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, - 0x348e, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, - 0x5faf, 0x0180, 0x080c, 0x512e, 0x0110, 0x080c, 0x26f5, 0x20a9, - 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, - 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x602c, 0x00fe, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x6002, 0x080c, 0x8993, - 0x9086, 0x0014, 0x11b8, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, - 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, - 0x0029, 0x0010, 0x080c, 0x6153, 0x00fe, 0x0005, 0x00f6, 0x709b, - 0x0009, 0x080c, 0x60fb, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, - 0x0100, 0x080c, 0x615a, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, - 0x5f22, 0x1188, 0x9085, 0x0001, 0x080c, 0x26f5, 0x20a9, 0x0008, - 0x080c, 0x6177, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, - 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x602c, 0x0010, - 0x080c, 0x5a7c, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, - 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, 0x0014, 0x1560, 0x080c, - 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, - 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, - 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, - 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, - 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, 0x000e, - 0x080c, 0x5cca, 0x0010, 0x080c, 0x6153, 0x00fe, 0x0005, 0x00f6, - 0x709b, 0x000b, 0x2011, 0x1d0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, - 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x60fb, 0x2079, 0x0240, - 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x615a, 0x0118, 0x2013, - 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, - 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e, 0x8210, 0x8108, 0x9186, - 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, - 0x5c4c, 0x60c3, 0x0084, 0x080c, 0x602c, 0x00fe, 0x0005, 0x00f6, - 0x7090, 0x9005, 0x01c0, 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, - 0x0084, 0x1178, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, - 0x0010, 0x080c, 0x6153, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, - 0x080c, 0x60fb, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, - 0x080c, 0x6177, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, - 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, - 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, - 0x1f04, 0x5c90, 0x60c3, 0x0084, 0x080c, 0x602c, 0x00fe, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x6002, 0x080c, 0x8993, - 0x9086, 0x0084, 0x1198, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, - 0x080c, 0x60cd, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x6153, - 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x61a2, 0x709b, 0x000f, - 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, - 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, - 0x2011, 0x6002, 0x080c, 0x8987, 0x0005, 0x7090, 0x9005, 0x0130, - 0x2011, 0x6002, 0x080c, 0x8993, 0x709b, 0x0000, 0x0005, 0x709b, - 0x0011, 0x080c, 0xaaf1, 0x080c, 0x6177, 0x20e1, 0x0000, 0x2099, - 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, - 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, - 0x615a, 0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, - 0x00ff, 0x0160, 0x080c, 0x268c, 0x9186, 0x007e, 0x0138, 0x9186, - 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5faf, 0x60c3, 0x0014, - 0x080c, 0x602c, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, - 0x6002, 0x080c, 0x8993, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6177, - 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, + 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, + 0x612e, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0007, 0x080c, 0x60d6, + 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6152, + 0x080c, 0x6135, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, + 0xffff, 0x0180, 0x9180, 0x3474, 0x200d, 0x918c, 0xff00, 0x810f, + 0x2011, 0x0008, 0x080c, 0x5f8a, 0x0180, 0x080c, 0x510e, 0x0110, + 0x080c, 0x270a, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, + 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, + 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, - 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, - 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, 0x6109, 0x2079, 0x0240, - 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6177, 0x080c, 0x615a, - 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, - 0x2011, 0x0008, 0x080c, 0x5faf, 0x0168, 0x080c, 0x6130, 0x20a9, - 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, - 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x602c, 0x00fe, 0x0005, - 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x6002, 0x080c, 0x8993, - 0x9086, 0x0014, 0x11b8, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, - 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, - 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, - 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, - 0x0015, 0x080c, 0x6109, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, - 0x0000, 0x080c, 0x6177, 0x080c, 0x615a, 0x11b8, 0x7084, 0x9005, - 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x348e, 0x200d, - 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5faf, 0x0180, - 0x080c, 0x512e, 0x0110, 0x080c, 0x26f5, 0x20a9, 0x0008, 0x20e1, - 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, - 0x60c3, 0x0014, 0x080c, 0x602c, 0x00fe, 0x0005, 0x00f6, 0x7090, - 0x9005, 0x05f0, 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, 0x0014, - 0x15a8, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, - 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, - 0x9085, 0x0001, 0x080c, 0x61a2, 0x7a38, 0xd2fc, 0x0128, 0x70c4, - 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, - 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, - 0x0001, 0x080c, 0x61a2, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, - 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, - 0x00fe, 0x0005, 0x080c, 0xaaf1, 0x080c, 0x6177, 0x20e1, 0x0000, - 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, - 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, - 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x615a, 0x1150, - 0x7084, 0x9005, 0x1138, 0x080c, 0x5f22, 0x1188, 0x9085, 0x0001, - 0x080c, 0x26f5, 0x20a9, 0x0008, 0x080c, 0x6177, 0x20e1, 0x0000, - 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, - 0x0014, 0x080c, 0x602c, 0x0010, 0x080c, 0x5a7c, 0x0005, 0x00f6, - 0x7090, 0x9005, 0x01d8, 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, - 0x0084, 0x1190, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, - 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x61a2, - 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, - 0x00f6, 0x709b, 0x0019, 0x080c, 0x6109, 0x2079, 0x0240, 0x7833, - 0x1106, 0x7837, 0x0000, 0x080c, 0x6177, 0x2009, 0x026e, 0x2039, - 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, - 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e8b, - 0x2039, 0x1d0e, 0x080c, 0x615a, 0x11e8, 0x2728, 0x2514, 0x8207, - 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, - 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, 0x1d0e, 0x2414, 0x938c, - 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, - 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, - 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, - 0x0240, 0x1f04, 0x5ebe, 0x60c3, 0x0084, 0x080c, 0x602c, 0x00fe, - 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x6002, 0x080c, - 0x8993, 0x9086, 0x0084, 0x1198, 0x080c, 0x6177, 0x2079, 0x0260, - 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, - 0x0001, 0x080c, 0x60cd, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, - 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x61a2, 0x709b, - 0x001b, 0x080c, 0xaaf1, 0x080c, 0x6177, 0x2011, 0x0260, 0x2009, - 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, - 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, - 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, - 0x2011, 0x0260, 0x1f04, 0x5f0a, 0x60c3, 0x0084, 0x080c, 0x602c, - 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, - 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x6177, - 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, - 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, - 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, - 0x5f3c, 0x0804, 0x5fab, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, - 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5fab, 0x918d, - 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, - 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, - 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5f62, 0x04d8, - 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5f74, 0x2328, - 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, - 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f83, 0x755e, - 0x95c8, 0x348e, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, - 0x0016, 0x2508, 0x080c, 0x26d5, 0x001e, 0x60e7, 0x0000, 0x65ea, - 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, - 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, - 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, - 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, - 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, - 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, - 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, - 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, - 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, - 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, 0x348e, - 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, - 0x080c, 0x26d5, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, - 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, - 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, - 0x080c, 0x60bc, 0x080c, 0xa2a0, 0x7004, 0x9084, 0x4000, 0x0110, - 0x080c, 0x2aa9, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, - 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x6119, - 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, - 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, - 0x2a04, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, - 0x19f5, 0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, - 0x60a7, 0x9575, 0x080c, 0xa293, 0x6144, 0xd184, 0x0120, 0x7198, - 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x1999, - 0x2112, 0x2009, 0x07d0, 0x2011, 0x6002, 0x080c, 0x8a5d, 0x0005, - 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xacfc, - 0x080c, 0xb09b, 0x080c, 0xad18, 0x2009, 0x00f7, 0x080c, 0x6119, - 0x2061, 0x1a04, 0x900e, 0x611a, 0x611e, 0x617a, 0x617e, 0x2061, - 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, - 0x0010, 0x2009, 0x1999, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, - 0x6088, 0x080c, 0x8987, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005, - 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, 0x0100, - 0x080c, 0xa2a0, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, 0x0110, - 0x080c, 0x2aa9, 0x080c, 0x77a6, 0x0188, 0x080c, 0x77c1, 0x1170, - 0x080c, 0x7ac0, 0x0016, 0x080c, 0x27a4, 0x2001, 0x196d, 0x2102, - 0x001e, 0x080c, 0x7abb, 0x080c, 0x76cd, 0x0050, 0x2009, 0x0001, - 0x080c, 0x2a85, 0x2001, 0x0001, 0x080c, 0x2631, 0x080c, 0x6058, - 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0bc, - 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x1999, 0x201c, - 0x080c, 0x4ca1, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, 0x20e9, - 0x0001, 0x20a1, 0x1d80, 0x080c, 0x6177, 0x20e9, 0x0000, 0x2099, - 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6171, 0x2099, 0x0260, - 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6174, 0x2099, - 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005, 0x0016, 0x0026, 0x3410, - 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, 0x60f1, - 0x002e, 0x001e, 0x0005, 0x080c, 0xaaf1, 0x20e1, 0x0001, 0x2099, - 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, - 0x0005, 0x080c, 0xaaf1, 0x080c, 0x6177, 0x20e1, 0x0000, 0x2099, - 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, - 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, 0x1834, - 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, - 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, - 0x0016, 0x0046, 0x080c, 0x6c0d, 0x0158, 0x9006, 0x2020, 0x2009, - 0x002a, 0x080c, 0xea8d, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, - 0x2019, 0x002a, 0x900e, 0x080c, 0x32da, 0x080c, 0xd645, 0x0140, - 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4e58, 0x003e, - 0x004e, 0x001e, 0x0005, 0x080c, 0x6058, 0x709b, 0x0000, 0x7093, - 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, 0xd09c, 0x0100, - 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, - 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, - 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008, 0x900e, - 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6, 0x0156, - 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001, 0x20a1, - 0x1d00, 0x4004, 0x2079, 0x1d00, 0x7803, 0x2200, 0x7807, 0x00ef, - 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827, 0xffff, - 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, 0x1800, 0x2003, - 0x0001, 0x0005, 0x2001, 0x19a7, 0x0118, 0x2003, 0x0001, 0x0010, - 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, 0x2009, 0x1000, - 0x9006, 0x200a, 0x8108, 0x1f04, 0x61b1, 0x015e, 0x0005, 0x00d6, - 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006, 0xb802, - 0xb8d6, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, 0x348e, - 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb886, 0x080c, - 0xb094, 0x1120, 0x9192, 0x007e, 0x1208, 0xbb86, 0x20a9, 0x0004, - 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, 0x23a0, 0x4004, - 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, 0x002e, 0x001e, - 0xb83e, 0xb842, 0xb8ce, 0xb8d2, 0xb85e, 0xb862, 0xb866, 0xb86a, - 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, - 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, 0xb9a2, 0x0096, 0xb8a4, - 0x904d, 0x0110, 0x080c, 0x108b, 0xb8a7, 0x0000, 0x009e, 0x9006, - 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, 0xb8bb, 0x0520, 0xb8ac, - 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, 0x1ddc, 0x0a0c, 0x0d85, - 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85, 0x080c, 0x8eee, - 0x00ce, 0x090c, 0x928d, 0xb8af, 0x0000, 0x6814, 0x9084, 0x00ff, - 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, - 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, - 0x1a04, 0x628d, 0x9182, 0x0800, 0x1a04, 0x6291, 0x2001, 0x180c, - 0x2004, 0x9084, 0x0003, 0x1904, 0x6297, 0x9188, 0x1000, 0x2104, - 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006, 0x1188, - 0xb8a4, 0x900d, 0x1904, 0x62a9, 0x080c, 0x6669, 0x9006, 0x012e, - 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, - 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0xb094, 0x1160, 0xb8a0, - 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0d10, 0x2001, 0x0029, - 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, - 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, - 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, - 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, - 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x012e, 0x0005, 0x2001, - 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, 0x1000, 0x2104, 0x9065, - 0x09a8, 0x080c, 0x6c11, 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, - 0x6250, 0x080c, 0x6a2a, 0x0904, 0x6259, 0x0804, 0x6254, 0x00e6, - 0x2071, 0x19e8, 0x7004, 0x9086, 0x0002, 0x1128, 0x7030, 0x9080, - 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005, 0x00b6, 0x00e6, 0x0126, - 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, 0x196b, - 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, 0x1000, - 0x2104, 0x905d, 0x01d0, 0x080c, 0x6bb1, 0x11d0, 0x080c, 0xb116, - 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x602b, - 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, 0x602b, 0x8000, 0x2009, - 0x0043, 0x080c, 0xb20a, 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, - 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, - 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, - 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, - 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, - 0x9182, 0x0800, 0x1a04, 0x6388, 0x9188, 0x1000, 0x2104, 0x905d, - 0x0904, 0x6360, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, - 0x1178, 0x080c, 0x6c19, 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, - 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6c11, 0x1598, - 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, - 0x2010, 0x080c, 0xcf09, 0x002e, 0x1120, 0x2001, 0x0008, 0x0804, - 0x638a, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, 0x0804, - 0x638a, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, 0x080c, - 0xb116, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, 0xffff, - 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xb20a, 0x9006, 0x0458, - 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, 0xb094, - 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, - 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, - 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, - 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, - 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, - 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, - 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, - 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, - 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, - 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, - 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, - 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, - 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, 0x00be, - 0x00fe, 0x0005, 0x641f, 0x63da, 0x63f1, 0x641f, 0x641f, 0x641f, - 0x641f, 0x641f, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, 0x6749, - 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6427, 0xb814, 0x9206, - 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x4b54, 0x0150, - 0x04b0, 0x080c, 0x67b4, 0x1598, 0xb810, 0x9306, 0x1580, 0xb814, - 0x9206, 0x1568, 0x080c, 0xb116, 0x0530, 0x2b00, 0x6012, 0x080c, - 0xd3b6, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0xa878, - 0x9086, 0x0001, 0x1170, 0x080c, 0x3315, 0x9006, 0x080c, 0x66e6, - 0x2001, 0x0002, 0x080c, 0x66fa, 0x2001, 0x0200, 0xb86e, 0xb893, - 0x0002, 0x2009, 0x0003, 0x080c, 0xb20a, 0x9006, 0x0068, 0x2001, - 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, - 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, - 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, - 0x0015, 0x0904, 0x6612, 0x90c6, 0x0056, 0x0904, 0x6616, 0x90c6, - 0x0066, 0x0904, 0x661a, 0x90c6, 0x0067, 0x0904, 0x661e, 0x90c6, - 0x0068, 0x0904, 0x6622, 0x90c6, 0x0071, 0x0904, 0x6626, 0x90c6, - 0x0074, 0x0904, 0x662a, 0x90c6, 0x007c, 0x0904, 0x662e, 0x90c6, - 0x007e, 0x0904, 0x6632, 0x90c6, 0x0037, 0x0904, 0x6636, 0x9016, - 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x660d, 0x9182, - 0x0800, 0x1a04, 0x660d, 0x080c, 0x67b4, 0x1198, 0xb804, 0x9084, - 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, - 0x080c, 0xb094, 0x1904, 0x65f6, 0xb8a0, 0x9084, 0xff80, 0x1904, - 0x65f6, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, - 0x6556, 0x90c6, 0x0064, 0x0904, 0x657f, 0x2008, 0x0804, 0x6518, - 0xa998, 0xa8b0, 0x2040, 0x080c, 0xb094, 0x1120, 0x9182, 0x007f, - 0x0a04, 0x6518, 0x9186, 0x00ff, 0x0904, 0x6518, 0x9182, 0x0800, - 0x1a04, 0x6518, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, - 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, 0x6518, - 0x080c, 0xb094, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, - 0x2310, 0x0804, 0x6518, 0x009e, 0x080c, 0x4b54, 0x0904, 0x6522, - 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, 0x6aae, - 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, - 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6, 0x20a9, 0x0004, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, - 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0xa8c4, 0xabc8, - 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, - 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, - 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, - 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, - 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, - 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, - 0x0478, 0x000e, 0x080c, 0xb116, 0x1130, 0x2001, 0x4005, 0x2009, - 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd3b6, 0x2900, - 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, - 0x0126, 0x2091, 0x8000, 0x080c, 0x3315, 0x012e, 0x9006, 0x080c, - 0x66e6, 0x2001, 0x0002, 0x080c, 0x66fa, 0x2009, 0x0002, 0x080c, - 0xb20a, 0xa8b0, 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, 0x9006, - 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x5854, - 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x67b4, - 0x1904, 0x6513, 0x9186, 0x007f, 0x0130, 0x080c, 0x6c11, 0x0118, - 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x1059, 0x1120, 0x009e, - 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xd109, - 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x651a, 0xa998, - 0xaeb0, 0x080c, 0x67b4, 0x1904, 0x6513, 0x0096, 0x080c, 0x1059, - 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x65d3, 0x2900, 0x009e, - 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, - 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, - 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, - 0x2398, 0x080c, 0x0fd6, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, - 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x5840, 0xd0b4, 0x1118, - 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, - 0x00b0, 0x080c, 0x6c11, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, - 0x5854, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xd0ec, 0x1904, - 0x654f, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x651a, 0xa87b, - 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, - 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, - 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x12a8, 0x080c, - 0xb691, 0x1904, 0x654f, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, - 0x900e, 0x0804, 0x6550, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, + 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe, + 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, 0x60d6, 0x2079, 0x0240, + 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x6135, 0x1150, 0x7084, + 0x9005, 0x1138, 0x080c, 0x5efd, 0x1188, 0x9085, 0x0001, 0x080c, + 0x270a, 0x20a9, 0x0008, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099, + 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, + 0x080c, 0x6007, 0x0010, 0x080c, 0x5a57, 0x00fe, 0x0005, 0x00f6, + 0x7090, 0x9005, 0x05a8, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, + 0x0014, 0x1560, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, + 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, + 0x0000, 0x709b, 0x000e, 0x080c, 0x5ca5, 0x0010, 0x080c, 0x612e, + 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, 0x2011, 0x1d0e, 0x20e9, + 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, + 0x60d6, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, + 0x6135, 0x0118, 0x2013, 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, + 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e, + 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, + 0x2009, 0x0240, 0x1f04, 0x5c27, 0x60c3, 0x0084, 0x080c, 0x6007, + 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01c0, 0x2011, 0x5fdd, + 0x080c, 0x882c, 0x9086, 0x0084, 0x1178, 0x080c, 0x6152, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, + 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005, + 0x00f6, 0x709b, 0x000d, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833, + 0x1107, 0x7837, 0x0000, 0x080c, 0x6152, 0x20a9, 0x0040, 0x2011, + 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, + 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, + 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c6b, 0x60c3, 0x0084, 0x080c, + 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, + 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0084, 0x1198, 0x080c, 0x6152, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, + 0x1140, 0x7097, 0x0001, 0x080c, 0x60a8, 0x709b, 0x000e, 0x0029, + 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, + 0x617d, 0x709b, 0x000f, 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, + 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, + 0x0004, 0x2009, 0x07d0, 0x2011, 0x5fdd, 0x080c, 0x8820, 0x0005, + 0x7090, 0x9005, 0x0130, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x709b, + 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, 0xa8ec, 0x080c, 0x6152, + 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, + 0x20a8, 0x4003, 0x080c, 0x6135, 0x11a0, 0x717c, 0x81ff, 0x0188, + 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, 0x080c, 0x26a1, 0x9186, + 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, + 0x5f8a, 0x60c3, 0x0014, 0x080c, 0x6007, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, + 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, + 0x60e4, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, + 0x6152, 0x080c, 0x6135, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, + 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f8a, 0x0168, + 0x080c, 0x610b, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, + 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, + 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, + 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, 0x60e4, 0x2079, 0x0240, + 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6152, 0x080c, 0x6135, + 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, + 0x9180, 0x3474, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, + 0x080c, 0x5f8a, 0x0180, 0x080c, 0x510e, 0x0110, 0x080c, 0x270a, + 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, + 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x6007, 0x00fe, + 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, 0x2011, 0x5fdd, 0x080c, + 0x882c, 0x9086, 0x0014, 0x15a8, 0x080c, 0x6152, 0x2079, 0x0260, + 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, + 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, 0x080c, 0x617d, 0x7a38, + 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, + 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, + 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, 0x617d, 0x7097, 0x0000, + 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, + 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x080c, 0xa8ec, 0x080c, + 0x6152, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, + 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, + 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, + 0x080c, 0x6135, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5efd, + 0x1188, 0x9085, 0x0001, 0x080c, 0x270a, 0x20a9, 0x0008, 0x080c, + 0x6152, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, + 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x6007, 0x0010, 0x080c, + 0x5a57, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01d8, 0x2011, 0x5fdd, + 0x080c, 0x882c, 0x9086, 0x0084, 0x1190, 0x080c, 0x6152, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, + 0x9006, 0x080c, 0x617d, 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, + 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0019, 0x080c, 0x60e4, + 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x6152, + 0x2009, 0x026e, 0x2039, 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738, + 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, + 0x0260, 0x1f04, 0x5e66, 0x2039, 0x1d0e, 0x080c, 0x6135, 0x11e8, + 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, + 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, + 0x1d0e, 0x2414, 0x938c, 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, + 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, + 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, + 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5e99, 0x60c3, 0x0084, + 0x080c, 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, + 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0084, 0x1198, 0x080c, + 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, + 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x60a8, 0x709b, 0x001a, + 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, + 0x080c, 0x617d, 0x709b, 0x001b, 0x080c, 0xa8ec, 0x080c, 0x6152, + 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, + 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, + 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, + 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5ee5, 0x60c3, + 0x0084, 0x080c, 0x6007, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, + 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001, + 0x28a0, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, + 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, + 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, + 0x0008, 0x8211, 0x1f04, 0x5f17, 0x0804, 0x5f86, 0x82ff, 0x1160, + 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, + 0x0904, 0x5f86, 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, + 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, + 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, + 0x1f04, 0x5f3d, 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, + 0x1f04, 0x5f4f, 0x2328, 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, + 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, + 0x1f04, 0x5f5e, 0x755e, 0x95c8, 0x3474, 0x292d, 0x95ac, 0x00ff, + 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26ea, 0x001e, + 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, + 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, + 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, + 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, + 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, + 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, + 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, + 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, + 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, + 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, + 0x715e, 0x91a0, 0x3474, 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, + 0x6536, 0x0016, 0x2508, 0x080c, 0x26ea, 0x001e, 0x60e7, 0x0000, + 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, + 0x0100, 0x2071, 0x0140, 0x080c, 0x6097, 0x080c, 0xa09b, 0x7004, + 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x0126, 0x2091, 0x8000, + 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, + 0x00f7, 0x080c, 0x60f4, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, + 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x8000, 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204, + 0xc0c5, 0x2012, 0x2011, 0x19f6, 0x2013, 0x0000, 0x7093, 0x0000, + 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa08e, 0x6144, + 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, + 0x1000, 0x2011, 0x199a, 0x2112, 0x2009, 0x07d0, 0x2011, 0x5fdd, + 0x080c, 0x88f6, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c, 0xab13, 0x2009, + 0x00f7, 0x080c, 0x60f4, 0x2061, 0x1a05, 0x900e, 0x611a, 0x611e, + 0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, + 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, + 0x2009, 0x002d, 0x2011, 0x6063, 0x080c, 0x8820, 0x012e, 0x00ce, + 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, + 0x0471, 0x2071, 0x0100, 0x080c, 0xa09b, 0x2071, 0x0140, 0x7004, + 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x080c, 0x76a5, 0x0188, + 0x080c, 0x76c0, 0x1170, 0x080c, 0x79a9, 0x0016, 0x080c, 0x27b9, + 0x2001, 0x196e, 0x2102, 0x001e, 0x080c, 0x79a4, 0x080c, 0x75cc, + 0x0050, 0x2009, 0x0001, 0x080c, 0x2a8e, 0x2001, 0x0001, 0x080c, + 0x2646, 0x080c, 0x6033, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, + 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, + 0x2001, 0x199a, 0x201c, 0x080c, 0x4c28, 0x003e, 0x002e, 0x0005, + 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x080c, 0x6152, + 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, + 0x614c, 0x2099, 0x0260, 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e, + 0x080c, 0x614f, 0x2099, 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005, + 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, + 0x8210, 0x1f04, 0x60cc, 0x002e, 0x001e, 0x0005, 0x080c, 0xa8ec, + 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0xa8ec, 0x080c, 0x6152, + 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, + 0x810f, 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, + 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, + 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6bc9, 0x0158, + 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe795, 0x2001, 0x180c, + 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x32c0, + 0x080c, 0xd35d, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, + 0x080c, 0x4ddf, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x6033, + 0x709b, 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, + 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, + 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, + 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, + 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, + 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, + 0x20e9, 0x0001, 0x20a1, 0x1d00, 0x4004, 0x2079, 0x1d00, 0x7803, + 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, + 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, + 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a8, 0x0118, + 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, + 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x618c, + 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, + 0x1847, 0x9006, 0xb802, 0xb8d6, 0xb807, 0x0707, 0xb80a, 0xb80e, + 0xb812, 0x9198, 0x3474, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, + 0x0026, 0xb886, 0x080c, 0xae80, 0x1120, 0x9192, 0x007e, 0x1208, + 0xbb86, 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, + 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, + 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb8ce, 0xb8d2, 0xb85e, + 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, + 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, + 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x107f, 0xb8a7, + 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, + 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, + 0x1ddc, 0x0a0c, 0x0d79, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, + 0x0d79, 0x080c, 0x8d87, 0x00ce, 0x090c, 0x9128, 0xb8af, 0x0000, + 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, + 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, + 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6268, 0x9182, 0x0800, 0x1a04, + 0x626c, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x6272, + 0x9188, 0x1000, 0x2104, 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff, + 0x908e, 0x0006, 0x1188, 0xb8a4, 0x900d, 0x1904, 0x6284, 0x080c, + 0x6644, 0x9006, 0x012e, 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8, + 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, + 0xae80, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, + 0x0d10, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, + 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, + 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, + 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, + 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, + 0x1000, 0x2104, 0x9065, 0x09a8, 0x080c, 0x6bcd, 0x1990, 0xb800, + 0xd0bc, 0x0978, 0x0804, 0x622b, 0x080c, 0x69f0, 0x0904, 0x6234, + 0x0804, 0x622f, 0x00e6, 0x2071, 0x19e9, 0x7004, 0x9086, 0x0002, + 0x1128, 0x7030, 0x9080, 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005, + 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, + 0x1120, 0x2001, 0x196c, 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, + 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, 0x01d0, 0x080c, 0x6b6d, + 0x11d0, 0x080c, 0xaef8, 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, + 0x6023, 0x0009, 0x602b, 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, + 0x602b, 0x8000, 0x2009, 0x0043, 0x080c, 0xafec, 0x9006, 0x00b0, + 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, - 0x2001, 0x0029, 0x900e, 0x0804, 0x6550, 0x2001, 0x0029, 0x900e, - 0x0804, 0x6550, 0x080c, 0x38c0, 0x0804, 0x6551, 0x080c, 0x555d, - 0x0804, 0x6551, 0x080c, 0x46d5, 0x0804, 0x6551, 0x080c, 0x474e, - 0x0804, 0x6551, 0x080c, 0x47aa, 0x0804, 0x6551, 0x080c, 0x4c17, - 0x0804, 0x6551, 0x080c, 0x4edf, 0x0804, 0x6551, 0x080c, 0x51c4, - 0x0804, 0x6551, 0x080c, 0x53bd, 0x0804, 0x6551, 0x080c, 0x3afe, - 0x0804, 0x6551, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, - 0x4000, 0x1608, 0x9182, 0x0800, 0x1258, 0x9188, 0x1000, 0x2104, - 0x905d, 0x0130, 0x080c, 0x6c11, 0x1138, 0x00d9, 0x9006, 0x00b0, - 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, 0xb900, - 0xd1fc, 0x0d98, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, 0x2001, - 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x00be, - 0x0005, 0xa877, 0x0000, 0xb8d0, 0x9005, 0x1904, 0x66da, 0xb888, - 0x9005, 0x1904, 0x66da, 0xb838, 0xb93c, 0x9102, 0x1a04, 0x66da, - 0x2b10, 0x080c, 0xb143, 0x0904, 0x66d6, 0x8108, 0xb93e, 0x6212, - 0x2900, 0x6016, 0x6023, 0x0003, 0x600b, 0xffff, 0x6007, 0x0040, - 0xa878, 0x605e, 0xa880, 0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, - 0x05b8, 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1560, 0x2011, 0x180d, - 0x2214, 0xd28c, 0x190c, 0x6cd6, 0xa816, 0xa864, 0x9094, 0x00f7, - 0x9296, 0x0011, 0x11f8, 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, - 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x000f, 0x8001, 0x1df0, 0x2001, - 0x8004, 0x6003, 0x0004, 0x6046, 0x00f6, 0x2079, 0x0380, 0x7818, - 0xd0bc, 0x1de8, 0x7833, 0x0010, 0x2c00, 0x7836, 0x781b, 0x8080, - 0x00fe, 0x0005, 0x080c, 0x17ad, 0x601c, 0xc0bd, 0x601e, 0x0c38, - 0x2009, 0x180d, 0x210c, 0xd18c, 0x190c, 0x6ce0, 0xd0b4, 0x190c, - 0x1c9c, 0x2001, 0x8004, 0x6003, 0x0002, 0x08e8, 0x81ff, 0x1110, - 0xb88b, 0x0001, 0x2908, 0xb8cc, 0xb9ce, 0x9005, 0x1110, 0xb9d2, - 0x0020, 0x0096, 0x2048, 0xa902, 0x009e, 0x0005, 0x00b6, 0x0126, - 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, - 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, - 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, - 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, - 0x0158, 0x080c, 0x6c0d, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, - 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, - 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, - 0x0d85, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, - 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, - 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6c09, 0x1138, - 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, - 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, - 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, - 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, - 0x1059, 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, - 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x61b7, 0x9006, - 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, - 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, - 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, - 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x108b, 0x00d6, - 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, - 0x2048, 0x080c, 0xcf1b, 0x0110, 0x080c, 0x100b, 0x080c, 0xb16c, - 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, - 0x621c, 0xd2c4, 0x0110, 0x080c, 0x928d, 0x00ce, 0x2b48, 0xb8c8, - 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x109b, 0x00de, 0x9006, 0x002e, - 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, - 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, - 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, - 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x779e, 0x1510, - 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xb094, 0x11d8, 0x0078, - 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1982, 0x7048, 0x2062, - 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, - 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, - 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, - 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, - 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, - 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, - 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, - 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, - 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, - 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, - 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, - 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, - 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, - 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, - 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, - 0x7054, 0xb89e, 0x0036, 0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, - 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, - 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, - 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, - 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, - 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, - 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, - 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, - 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, - 0x8109, 0x1dd0, 0x080c, 0x0d85, 0x3c00, 0x20e8, 0x3300, 0x8001, - 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, - 0x0060, 0x080c, 0x1059, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, - 0x080c, 0x6a4a, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, - 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, - 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x6a59, - 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, - 0x080c, 0x108b, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0096, - 0x00c6, 0xb888, 0x9005, 0x1904, 0x693f, 0xb8d0, 0x904d, 0x0904, - 0x693f, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, - 0x1904, 0x693d, 0x080c, 0xb143, 0x0904, 0x693d, 0x8210, 0xba3e, - 0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x2b00, 0x6012, 0x2900, - 0x6016, 0x6023, 0x0003, 0x600b, 0xffff, 0x6007, 0x0040, 0xa878, - 0x605e, 0xa880, 0x9084, 0x00ff, 0x6066, 0xa883, 0x0000, 0xa87c, - 0xd0ac, 0x01c8, 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1558, 0xa816, - 0xa864, 0x9094, 0x00f7, 0x9296, 0x0011, 0x1520, 0x9084, 0x00ff, - 0xc0bd, 0x601e, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x8004, - 0x6003, 0x0004, 0x0030, 0x080c, 0x1c9c, 0x2001, 0x8004, 0x6003, - 0x0002, 0x6046, 0x2001, 0x0010, 0x2c08, 0x080c, 0xaced, 0xb838, - 0xba3c, 0x9202, 0x0a04, 0x68e5, 0x0010, 0xb88b, 0x0001, 0x00ce, - 0x009e, 0x0005, 0x080c, 0x17ad, 0x601c, 0xc0bd, 0x601e, 0x08f0, - 0x00b6, 0x0096, 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c, - 0x67b4, 0x1158, 0xb8d0, 0x904d, 0x0140, 0x3e00, 0x9086, 0x0002, - 0x1118, 0xb800, 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04, - 0x694e, 0x001e, 0x00be, 0x009e, 0x0005, 0x0096, 0x0016, 0xb8d0, - 0x904d, 0x0188, 0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x9006, - 0xa802, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd220, - 0x080c, 0x7012, 0x0c60, 0x001e, 0x009e, 0x0005, 0x0086, 0x9046, - 0xb8d0, 0x904d, 0x01b0, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, - 0x0128, 0x2940, 0xa800, 0x904d, 0x0160, 0x0ca8, 0xa800, 0x88ff, - 0x1128, 0xb8d2, 0x9005, 0x1118, 0xb8ce, 0x0008, 0xa002, 0xa803, - 0x0000, 0x008e, 0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x0126, - 0x2091, 0x8000, 0x00e6, 0x0096, 0x00c6, 0x0086, 0x0026, 0x2071, - 0x19e8, 0x9046, 0x7028, 0x9065, 0x01e8, 0x6014, 0x2068, 0x83ff, - 0x0120, 0x605c, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, - 0xa870, 0x9506, 0x0120, 0x2c40, 0x600c, 0x2060, 0x0c60, 0x600c, - 0x0006, 0x0066, 0x2830, 0x080c, 0xa420, 0x006e, 0x000e, 0x83ff, - 0x0508, 0x0c08, 0x9046, 0xb8d0, 0x904d, 0x01e0, 0x83ff, 0x0120, - 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, - 0x9506, 0x0120, 0x2940, 0xa800, 0x2048, 0x0c70, 0xb8d0, 0xaa00, - 0x0026, 0x9906, 0x1110, 0xbad2, 0x0008, 0xa202, 0x000e, 0x83ff, - 0x0108, 0x0c10, 0x002e, 0x008e, 0x00ce, 0x009e, 0x00ee, 0x012e, - 0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, - 0x6aae, 0x0128, 0x080c, 0xcfdc, 0x0010, 0x9085, 0x0001, 0x0005, - 0x080c, 0x6aae, 0x0128, 0x080c, 0xcf7d, 0x0010, 0x9085, 0x0001, - 0x0005, 0x080c, 0x6aae, 0x0128, 0x080c, 0xcfd9, 0x0010, 0x9085, - 0x0001, 0x0005, 0x080c, 0x6aae, 0x0128, 0x080c, 0xcf9c, 0x0010, - 0x9085, 0x0001, 0x0005, 0x080c, 0x6aae, 0x0128, 0x080c, 0xd01f, - 0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, - 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, - 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, - 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, - 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, - 0x013e, 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, - 0x0004, 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, - 0x014e, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, - 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, - 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, - 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, - 0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, - 0x014e, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, - 0x8000, 0xb8a4, 0x904d, 0x1128, 0x080c, 0x1059, 0x0168, 0x2900, - 0xb8a6, 0x080c, 0x6a4a, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, - 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, - 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, - 0x108b, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, - 0x0005, 0x00b6, 0x00f6, 0x080c, 0x779e, 0x01b0, 0x71c4, 0x81ff, - 0x1198, 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, - 0x2004, 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, - 0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, - 0x01d0, 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x67b4, - 0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, - 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, - 0x1f04, 0x6ad5, 0x015e, 0x080c, 0x6bcf, 0x0120, 0x2001, 0x1985, - 0x200c, 0x0098, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0190, 0x2009, - 0x07d0, 0x2001, 0x182c, 0x2004, 0x9005, 0x0138, 0x2001, 0x1867, - 0x2004, 0xd0e4, 0x0110, 0x2009, 0x5dc0, 0x2011, 0x6b0c, 0x080c, - 0x8a5d, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x6b0c, 0x080c, - 0x8993, 0x080c, 0x6bcf, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, - 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6c0d, 0x0130, 0x2009, 0x07d0, - 0x2011, 0x6b0c, 0x080c, 0x8a5d, 0x00e6, 0x2071, 0x1800, 0x9006, - 0x707e, 0x7060, 0x7082, 0x080c, 0x30bf, 0x00ee, 0x04d0, 0x0156, - 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x67b4, 0x1558, - 0xb800, 0xd0ec, 0x0540, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, - 0x0029, 0x080c, 0xea8d, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, - 0x6c09, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, - 0x0700, 0xb806, 0x080c, 0xacfc, 0x2019, 0x0029, 0x080c, 0x97b0, - 0x0076, 0x903e, 0x080c, 0x966d, 0x900e, 0x080c, 0xe75d, 0x007e, - 0x004e, 0x080c, 0xad18, 0x001e, 0x8108, 0x1f04, 0x6b34, 0x00ce, - 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, - 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x0096, 0x080c, 0x1072, - 0x090c, 0x0d85, 0x2958, 0x009e, 0x2001, 0x196b, 0x2b02, 0x8b07, - 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, 0x908c, 0xffc0, 0xb9ca, - 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, 0x61b7, 0xb807, 0x0006, - 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, 0x0200, 0xb86c, 0xb893, - 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, 0xb8af, 0x0000, 0x00ce, - 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, - 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc, - 0x0005, 0x0006, 0x0016, 0x0026, 0xb804, 0x908c, 0x00ff, 0x9196, - 0x0006, 0x0188, 0x9196, 0x0004, 0x0170, 0x9196, 0x0005, 0x0158, - 0x908c, 0xff00, 0x810f, 0x9196, 0x0006, 0x0128, 0x9196, 0x0004, - 0x0110, 0x9196, 0x0005, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, - 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0ec, - 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, 0x0006, - 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0d85, 0x000e, - 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, 0x002e, - 0x012e, 0x0005, 0x2011, 0x1837, 0x2204, 0xd0cc, 0x0138, 0x2001, - 0x1983, 0x200c, 0x2011, 0x6bff, 0x080c, 0x8a5d, 0x0005, 0x2011, - 0x6bff, 0x080c, 0x8993, 0x2011, 0x1837, 0x2204, 0xc0cc, 0x2012, - 0x0005, 0x080c, 0x5840, 0xd0ac, 0x0005, 0x080c, 0x5840, 0xd0a4, - 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, 0x001e, - 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, 0x0006, - 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xd645, 0x0158, 0x70dc, - 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, 0x0110, - 0xb8d4, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016, 0x0036, - 0x0046, 0x0076, 0x00b6, 0x2001, 0x1818, 0x203c, 0x9780, 0x348e, - 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, 0x2008, 0x9284, - 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, 0x2100, 0x9706, - 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, 0xb804, 0x9084, - 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, 0xb89c, 0xd0a4, - 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, 0x9182, 0x0800, - 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, 0x00be, 0x007e, - 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, 0x0005, 0x00be, - 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, 0x0005, 0x0046, - 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, 0x9080, 0x1000, - 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, - 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1818, 0x203c, 0x9780, - 0x348e, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2020, 0x2400, - 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, 0x0178, 0xb804, - 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, 0xd0a4, 0x0130, - 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, 0x8420, 0x9482, - 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, 0x007e, 0x005e, - 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, 0x00be, 0x007e, - 0x005e, 0x004e, 0x9006, 0x0005, 0x0006, 0x2001, 0x00a0, 0x8001, - 0xa001, 0xa001, 0xa001, 0x1dd8, 0x000e, 0x0005, 0x0006, 0x2001, - 0x00f8, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x000e, 0x0005, - 0x0006, 0x2001, 0x00e8, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, - 0x000e, 0x0005, 0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, - 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, - 0x1922, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1948, - 0x900e, 0x710a, 0x080c, 0x5840, 0xd0fc, 0x1140, 0x080c, 0x5840, - 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0470, 0x2001, 0x1867, - 0x200c, 0x9184, 0x0007, 0x0006, 0x2001, 0x180d, 0x2004, 0xd08c, - 0x000e, 0x0108, 0x9006, 0x0002, 0x6d06, 0x6d06, 0x6d06, 0x6d06, - 0x6d06, 0x6d24, 0x6d39, 0x6d47, 0x7003, 0x0003, 0x2009, 0x1868, - 0x210c, 0x9184, 0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, - 0x1110, 0x2001, 0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, - 0x0018, 0x7003, 0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, - 0x2071, 0x1800, 0x70f7, 0x0001, 0x00ee, 0x001e, 0x0005, 0x7003, - 0x0000, 0x2071, 0x1910, 0x2009, 0x1868, 0x210c, 0x9184, 0x7f00, - 0x8007, 0x908c, 0x000f, 0x0160, 0x714e, 0x8004, 0x8004, 0x8004, - 0x8004, 0x2071, 0x1800, 0x908c, 0x0007, 0x0128, 0x70f6, 0x0c20, - 0x704f, 0x000f, 0x0c90, 0x70f7, 0x0005, 0x08f0, 0x00e6, 0x2071, - 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, - 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, - 0x0158, 0x080c, 0x7b28, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, - 0x7006, 0x9006, 0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, - 0x6868, 0x700a, 0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, - 0x7016, 0x684c, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, - 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, - 0x702a, 0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, - 0x0005, 0x00e6, 0x0026, 0x2071, 0x1948, 0x7000, 0x9015, 0x0904, - 0x7017, 0x9286, 0x0003, 0x0904, 0x6eac, 0x9286, 0x0005, 0x0904, - 0x6eac, 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6e07, 0x7140, - 0xa868, 0x9102, 0x0a04, 0x7017, 0xa878, 0xd084, 0x15d8, 0xa853, - 0x0019, 0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, - 0x1904, 0x71c6, 0x0e04, 0x7234, 0x2071, 0x0000, 0xa850, 0x7032, - 0xa84c, 0x7082, 0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, - 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, - 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, - 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, - 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, - 0x0804, 0x6e8f, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, - 0xd08c, 0x1904, 0x7017, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, - 0x6dcb, 0x00e6, 0x0026, 0x2071, 0x1948, 0x7000, 0x9015, 0x0904, - 0x7017, 0x9286, 0x0003, 0x0904, 0x6eac, 0x9286, 0x0005, 0x0904, - 0x6eac, 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6e74, 0xa868, - 0xd0fc, 0x1508, 0x00e6, 0x0026, 0x2001, 0x1948, 0x2004, 0x9015, - 0x0904, 0x7017, 0xa978, 0xa874, 0x9105, 0x1904, 0x7017, 0x9286, - 0x0003, 0x0904, 0x6eac, 0x9286, 0x0005, 0x0904, 0x6eac, 0xa87c, - 0xd0bc, 0x1904, 0x7017, 0x2200, 0x0002, 0x7017, 0x6e70, 0x6eac, - 0x6eac, 0x7017, 0x6eac, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, - 0x0026, 0x2009, 0x1948, 0x210c, 0x81ff, 0x0904, 0x7017, 0xa880, - 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7017, 0x9186, 0x0003, - 0x0904, 0x6eac, 0x9186, 0x0005, 0x0904, 0x6eac, 0xa87c, 0xd0cc, - 0x0904, 0x7017, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, - 0xa84f, 0x8020, 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, - 0x1904, 0x71c6, 0x0e04, 0x7234, 0x2071, 0x0000, 0xa84c, 0x7082, - 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, - 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, - 0x1800, 0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, - 0x2900, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, 0x002e, - 0x00ee, 0x0005, 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, - 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, - 0x6f9d, 0x782c, 0x908c, 0x0780, 0x190c, 0x7382, 0x8004, 0x8004, - 0x8004, 0x9084, 0x0003, 0x0002, 0x6eca, 0x6f9d, 0x6eee, 0x6f3a, - 0x080c, 0x0d85, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, - 0x1168, 0x2071, 0x1a04, 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, - 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, - 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, - 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, 0x0c18, 0x2071, 0x1800, - 0x2900, 0x7822, 0xa804, 0x900d, 0x15a0, 0x7824, 0x00e6, 0x2071, - 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, - 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, - 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, - 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, - 0x190c, 0x7382, 0xd0a4, 0x19c8, 0x2071, 0x1a04, 0x7044, 0x9005, - 0x1320, 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, - 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, - 0x0804, 0x6ef5, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, - 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, - 0x8899, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x1d60, - 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, 0x1198, - 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x1a04, - 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, - 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, + 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, + 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, 0x6363, 0x9188, + 0x1000, 0x2104, 0x905d, 0x0904, 0x633b, 0xb8a0, 0x9086, 0x007f, + 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x6bd5, 0x0160, 0xa994, + 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, + 0x080c, 0x6bcd, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, + 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xcc21, 0x002e, 0x1120, + 0x2001, 0x0008, 0x0804, 0x6365, 0x6020, 0x9086, 0x000a, 0x0120, + 0x2001, 0x0008, 0x0804, 0x6365, 0x601a, 0x6003, 0x0008, 0x2900, + 0x6016, 0x0058, 0x080c, 0xaef8, 0x05e8, 0x2b00, 0x6012, 0x2900, + 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, + 0xafec, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, + 0x1290, 0x080c, 0xae80, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, + 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, + 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, + 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, + 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, + 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, + 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, + 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, + 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, + 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, + 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, + 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, 0x63fa, 0x63b5, 0x63cc, + 0x63fa, 0x63fa, 0x63fa, 0x63fa, 0x63fa, 0x2100, 0x9082, 0x007e, + 0x1278, 0x080c, 0x6718, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, + 0x6402, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, + 0x080c, 0x4adb, 0x0150, 0x04b0, 0x080c, 0x6783, 0x1598, 0xb810, + 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0xaef8, 0x0530, + 0x2b00, 0x6012, 0x080c, 0xd0ce, 0x2900, 0x6016, 0x600b, 0xffff, + 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x32fb, + 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9, 0x2001, + 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xafec, + 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, + 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, + 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, + 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, 0x65ed, 0x90c6, 0x0056, + 0x0904, 0x65f1, 0x90c6, 0x0066, 0x0904, 0x65f5, 0x90c6, 0x0067, + 0x0904, 0x65f9, 0x90c6, 0x0068, 0x0904, 0x65fd, 0x90c6, 0x0071, + 0x0904, 0x6601, 0x90c6, 0x0074, 0x0904, 0x6605, 0x90c6, 0x007c, + 0x0904, 0x6609, 0x90c6, 0x007e, 0x0904, 0x660d, 0x90c6, 0x0037, + 0x0904, 0x6611, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, + 0x0904, 0x65e8, 0x9182, 0x0800, 0x1a04, 0x65e8, 0x080c, 0x6783, + 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, + 0x90c6, 0x006f, 0x0148, 0x080c, 0xae80, 0x1904, 0x65d1, 0xb8a0, + 0x9084, 0xff80, 0x1904, 0x65d1, 0xa894, 0x90c6, 0x006f, 0x0158, + 0x90c6, 0x005e, 0x0904, 0x6531, 0x90c6, 0x0064, 0x0904, 0x655a, + 0x2008, 0x0804, 0x64f3, 0xa998, 0xa8b0, 0x2040, 0x080c, 0xae80, + 0x1120, 0x9182, 0x007f, 0x0a04, 0x64f3, 0x9186, 0x00ff, 0x0904, + 0x64f3, 0x9182, 0x0800, 0x1a04, 0x64f3, 0xaaa0, 0xab9c, 0x787c, + 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, + 0x009e, 0x0804, 0x64f3, 0x080c, 0xae80, 0x1140, 0x99cc, 0xff00, + 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x64f3, 0x009e, 0x080c, + 0x4adb, 0x0904, 0x64fd, 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, + 0x0006, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, + 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, + 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, + 0x0fca, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, + 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, + 0x0fca, 0xa8c4, 0xabc8, 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, + 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, + 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, + 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, + 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, + 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, + 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, 0x080c, 0xaef8, 0x1130, + 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, + 0x080c, 0xd0ce, 0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, + 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x32fb, + 0x012e, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9, + 0x2009, 0x0002, 0x080c, 0xafec, 0xa8b0, 0xd094, 0x0118, 0xb8d4, + 0xc08d, 0xb8d6, 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, + 0x0005, 0x080c, 0x5834, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, + 0xaeb0, 0x080c, 0x6783, 0x1904, 0x64ee, 0x9186, 0x007f, 0x0130, + 0x080c, 0x6bcd, 0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, + 0x104d, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, + 0xa806, 0x080c, 0xce21, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, + 0x0804, 0x64f5, 0xa998, 0xaeb0, 0x080c, 0x6783, 0x1904, 0x64ee, + 0x0096, 0x080c, 0x104d, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, + 0x65ae, 0x2900, 0x009e, 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, + 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, + 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, 0x0fca, 0x009e, 0xa87b, + 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, + 0x5820, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, + 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x6bcd, 0x0118, 0xa89b, + 0x0009, 0x0080, 0x080c, 0x5834, 0x0118, 0xa89b, 0x0007, 0x0050, + 0x080c, 0xce04, 0x1904, 0x652a, 0x2009, 0x0003, 0x2001, 0x4005, + 0x0804, 0x64f5, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, + 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, + 0x2041, 0x129c, 0x080c, 0xb473, 0x1904, 0x652a, 0x2009, 0x0002, + 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x652b, 0x2009, 0x180c, + 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x652b, + 0x2001, 0x0029, 0x900e, 0x0804, 0x652b, 0x080c, 0x38a4, 0x0804, + 0x652c, 0x080c, 0x553d, 0x0804, 0x652c, 0x080c, 0x468c, 0x0804, + 0x652c, 0x080c, 0x4705, 0x0804, 0x652c, 0x080c, 0x4761, 0x0804, + 0x652c, 0x080c, 0x4b9e, 0x0804, 0x652c, 0x080c, 0x4e52, 0x0804, + 0x652c, 0x080c, 0x51a4, 0x0804, 0x652c, 0x080c, 0x539d, 0x0804, + 0x652c, 0x080c, 0x3ac2, 0x0804, 0x652c, 0x00b6, 0xa974, 0xae78, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x1608, 0x9182, 0x0800, 0x1258, + 0x9188, 0x1000, 0x2104, 0x905d, 0x0130, 0x080c, 0x6bcd, 0x1138, + 0x00d9, 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, + 0x0006, 0x1240, 0xb900, 0xd1fc, 0x0d98, 0x2001, 0x0029, 0x2009, + 0x1000, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, + 0x900e, 0x9005, 0x00be, 0x0005, 0xa877, 0x0000, 0xb8d0, 0x9005, + 0x1904, 0x66a9, 0xb888, 0x9005, 0x1904, 0x66a9, 0xb838, 0xb93c, + 0x9102, 0x1a04, 0x66a9, 0x2b10, 0x080c, 0xaf25, 0x0904, 0x66a5, + 0x8108, 0xb93e, 0x6212, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b, + 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, 0x6066, 0xa883, + 0x0000, 0xa87c, 0xd0ac, 0x0588, 0xc0dd, 0xa87e, 0xa888, 0x8001, + 0x1530, 0xa816, 0xa864, 0x9094, 0x00f7, 0x9296, 0x0011, 0x11f8, + 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, + 0x2001, 0x000f, 0x8001, 0x1df0, 0x2001, 0x8004, 0x6003, 0x0004, + 0x6046, 0x00f6, 0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, + 0x0010, 0x2c00, 0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x080c, + 0x17a1, 0x601c, 0xc0bd, 0x601e, 0x0c38, 0xd0b4, 0x190c, 0x1cb9, + 0x2001, 0x8004, 0x6003, 0x0002, 0x0c18, 0x81ff, 0x1110, 0xb88b, + 0x0001, 0x2908, 0xb8cc, 0xb9ce, 0x9005, 0x1110, 0xb9d2, 0x0020, + 0x0096, 0x2048, 0xa902, 0x009e, 0x0005, 0x00b6, 0x0126, 0x00c6, + 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, 0x0110, + 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, 0x00be, + 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, + 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, 0x0158, + 0x080c, 0x6bc9, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, + 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06, + 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0d79, + 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, + 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, + 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6bc5, 0x1138, 0x9284, + 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0x9294, + 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, 0x0005, + 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0026, + 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, 0x104d, + 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, 0xb860, + 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x6192, 0x9006, 0x0010, + 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, 0x0126, + 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, + 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, 0x2013, + 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x107f, 0x00d6, 0x00c6, + 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048, + 0x080c, 0xcc33, 0x0110, 0x080c, 0x0fff, 0x080c, 0xaf4e, 0x00ce, + 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, 0x621c, + 0xd2c4, 0x0110, 0x080c, 0x9128, 0x00ce, 0x2b48, 0xb8c8, 0xb85e, + 0xb8c4, 0xb862, 0x080c, 0x108f, 0x00de, 0x9006, 0x002e, 0x012e, + 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085, + 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006, + 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a, + 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x769d, 0x1510, 0xb8a0, + 0x9086, 0x007e, 0x0120, 0x080c, 0xae80, 0x11d8, 0x0078, 0x7040, + 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1983, 0x7048, 0x2062, 0x704c, + 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, + 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800, + 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1, + 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, 0x000a, + 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006, + 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001, + 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876, + 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110, + 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, + 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1, + 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009, + 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, + 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, + 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, + 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054, + 0xb89e, 0x0036, 0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, 0x210c, + 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, + 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108, + 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, 0x002e, + 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, + 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8, + 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c, + 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009, + 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109, + 0x1dd0, 0x080c, 0x0d79, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0, + 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060, + 0x080c, 0x104d, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c, + 0x6a10, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e, + 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4, + 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x6a1f, 0x1158, + 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c, + 0x107f, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0096, 0x00c6, + 0xb888, 0x9005, 0x1904, 0x6905, 0xb8d0, 0x904d, 0x0904, 0x6905, + 0x080c, 0xaf25, 0x0904, 0x6903, 0x8210, 0xba3e, 0xa800, 0xb8d2, + 0x9005, 0x1108, 0xb8ce, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, + 0x0003, 0x600b, 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, + 0x9084, 0x00ff, 0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, 0x01c8, + 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1558, 0xa816, 0xa864, 0x9094, + 0x00f7, 0x9296, 0x0011, 0x1520, 0x9084, 0x00ff, 0xc0bd, 0x601e, + 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x8004, 0x6003, 0x0004, + 0x0030, 0x080c, 0x1cb9, 0x2001, 0x8004, 0x6003, 0x0002, 0x6046, + 0x2001, 0x0010, 0x2c08, 0x080c, 0xaae8, 0xb838, 0xba3c, 0x9202, + 0x0a04, 0x68b4, 0x0010, 0xb88b, 0x0001, 0x00ce, 0x009e, 0x0005, + 0x080c, 0x17a1, 0x601c, 0xc0bd, 0x601e, 0x08f0, 0x00b6, 0x0096, + 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c, 0x6783, 0x1158, + 0xb8d0, 0x904d, 0x0140, 0x3e00, 0x9086, 0x0002, 0x1118, 0xb800, + 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04, 0x6914, 0x001e, + 0x00be, 0x009e, 0x0005, 0x0096, 0x0016, 0xb8d0, 0x904d, 0x0188, + 0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x9006, 0xa802, 0xa867, + 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf38, 0x080c, 0x6f11, + 0x0c60, 0x001e, 0x009e, 0x0005, 0x0086, 0x9046, 0xb8d0, 0x904d, + 0x01b0, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0128, 0x2940, + 0xa800, 0x904d, 0x0160, 0x0ca8, 0xa800, 0x88ff, 0x1128, 0xb8d2, + 0x9005, 0x1118, 0xb8ce, 0x0008, 0xa002, 0xa803, 0x0000, 0x008e, + 0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x0126, 0x2091, 0x8000, + 0x00e6, 0x0096, 0x00c6, 0x0086, 0x0026, 0x2071, 0x19e9, 0x9046, + 0x7028, 0x9065, 0x01e8, 0x6014, 0x2068, 0x83ff, 0x0120, 0x605c, + 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, + 0x0120, 0x2c40, 0x600c, 0x2060, 0x0c60, 0x600c, 0x0006, 0x0066, + 0x2830, 0x080c, 0xa21b, 0x006e, 0x000e, 0x83ff, 0x0508, 0x0c08, + 0x9046, 0xb8d0, 0x904d, 0x01e0, 0x83ff, 0x0120, 0xa878, 0x9606, + 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120, + 0x2940, 0xa800, 0x2048, 0x0c70, 0xb8d0, 0xaa00, 0x0026, 0x9906, + 0x1110, 0xbad2, 0x0008, 0xa202, 0x000e, 0x83ff, 0x0108, 0x0c10, + 0x002e, 0x008e, 0x00ce, 0x009e, 0x00ee, 0x012e, 0x0005, 0x9016, + 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x6a74, 0x0128, + 0x080c, 0xccf4, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6a74, + 0x0128, 0x080c, 0xcc95, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, + 0x6a74, 0x0128, 0x080c, 0xccf1, 0x0010, 0x9085, 0x0001, 0x0005, + 0x080c, 0x6a74, 0x0128, 0x080c, 0xccb4, 0x0010, 0x9085, 0x0001, + 0x0005, 0x080c, 0x6a74, 0x0128, 0x080c, 0xcd37, 0x0010, 0x9085, + 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005, + 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, + 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, + 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, + 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005, + 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0, + 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136, + 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, + 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, + 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, + 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, + 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006, + 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, + 0x904d, 0x1128, 0x080c, 0x104d, 0x0168, 0x2900, 0xb8a6, 0x080c, + 0x6a10, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, + 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, + 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x107f, 0x9085, + 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, + 0x00f6, 0x080c, 0x769d, 0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc, + 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d, + 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, + 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0, 0x0156, + 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6783, 0x1168, 0xb804, + 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, + 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x6a9b, + 0x015e, 0x080c, 0x6b8b, 0x0120, 0x2001, 0x1986, 0x200c, 0x0038, + 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011, + 0x6ac6, 0x080c, 0x88f6, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, + 0x6ac6, 0x080c, 0x882c, 0x080c, 0x6b8b, 0x01d8, 0x2001, 0x107e, + 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6bc9, 0x0130, + 0x2009, 0x07d0, 0x2011, 0x6ac6, 0x080c, 0x88f6, 0x00e6, 0x2071, + 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x30c8, 0x00ee, + 0x04e0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, + 0x6783, 0x1568, 0xb800, 0xd0ec, 0x0550, 0xd0bc, 0x1540, 0x0046, + 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe795, 0xb800, + 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6bc5, 0x2001, 0x0707, 0x1128, + 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x080c, 0xaaf7, + 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, + 0x900e, 0x080c, 0xe465, 0x007e, 0x004e, 0x080c, 0xab13, 0x001e, + 0x8108, 0x1f04, 0x6aee, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, + 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, + 0x00c6, 0x0096, 0x080c, 0x1066, 0x090c, 0x0d79, 0x2958, 0x009e, + 0x2001, 0x196c, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, + 0xb9c6, 0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, + 0x080c, 0x6192, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, + 0xb86f, 0x0200, 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, + 0x00ff, 0xb8af, 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, + 0x0108, 0xb800, 0x00be, 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, + 0xb804, 0x908c, 0x00ff, 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, + 0x0170, 0x9196, 0x0005, 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, + 0x0006, 0x0128, 0x9196, 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, + 0x001e, 0x000e, 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, + 0x905d, 0x0110, 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, + 0x0026, 0x2091, 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, + 0x9b06, 0x190c, 0x0d79, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, + 0x0008, 0xc2fc, 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, + 0x2204, 0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6bbb, + 0x080c, 0x88f6, 0x0005, 0x2011, 0x6bbb, 0x080c, 0x882c, 0x2011, + 0x1837, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x5820, 0xd0ac, + 0x0005, 0x080c, 0x5820, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, + 0x00ff, 0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, + 0xff00, 0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, + 0x080c, 0xd35d, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, + 0x107f, 0x2004, 0x905d, 0x0110, 0xb8d4, 0xd094, 0x00fe, 0x00be, + 0x0005, 0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, + 0x7012, 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, 0x1922, + 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e, + 0x710a, 0x080c, 0x5820, 0xd0fc, 0x1140, 0x080c, 0x5820, 0x900e, + 0xd09c, 0x0108, 0x8108, 0x7102, 0x0430, 0x2001, 0x1867, 0x200c, + 0x9184, 0x0007, 0x0002, 0x6c0d, 0x6c0d, 0x6c0d, 0x6c0d, 0x6c0d, + 0x6c23, 0x6c38, 0x6c46, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, + 0x9184, 0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, + 0x2001, 0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, + 0x7003, 0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, 0x2071, + 0x1800, 0x70f7, 0x0001, 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, + 0x2071, 0x1910, 0x2009, 0x1868, 0x210c, 0x9184, 0x7f00, 0x8007, + 0x908c, 0x000f, 0x0160, 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, + 0x2071, 0x1800, 0x908c, 0x0007, 0x0128, 0x70f6, 0x0c20, 0x704f, + 0x000f, 0x0c90, 0x70f7, 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, + 0x684c, 0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, + 0x702a, 0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, + 0x080c, 0x7a11, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, + 0x9006, 0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, + 0x700a, 0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, + 0x684c, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, + 0x702b, 0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, + 0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, + 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f16, + 0x9286, 0x0003, 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab, + 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6d06, 0x7140, 0xa868, + 0x9102, 0x0a04, 0x6f16, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, + 0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, + 0x70c5, 0x0e04, 0x7133, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, + 0x7082, 0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, + 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, + 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, + 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x0804, + 0x6d8e, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, + 0x1904, 0x6f16, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6cca, + 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f16, + 0x9286, 0x0003, 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab, + 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6d73, 0xa868, 0xd0fc, + 0x1508, 0x00e6, 0x0026, 0x2001, 0x1949, 0x2004, 0x9015, 0x0904, + 0x6f16, 0xa978, 0xa874, 0x9105, 0x1904, 0x6f16, 0x9286, 0x0003, + 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab, 0xa87c, 0xd0bc, + 0x1904, 0x6f16, 0x2200, 0x0002, 0x6f16, 0x6d6f, 0x6dab, 0x6dab, + 0x6f16, 0x6dab, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, + 0x2009, 0x1949, 0x210c, 0x81ff, 0x0904, 0x6f16, 0xa880, 0x9084, + 0x00ff, 0x9086, 0x0001, 0x1904, 0x6f16, 0x9186, 0x0003, 0x0904, + 0x6dab, 0x9186, 0x0005, 0x0904, 0x6dab, 0xa87c, 0xd0cc, 0x0904, + 0x6f16, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, + 0x8020, 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, + 0x70c5, 0x0e04, 0x7133, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, + 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x2071, 0x1800, + 0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x002e, 0x00ee, + 0x0005, 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, + 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6e9c, + 0x782c, 0x908c, 0x0780, 0x190c, 0x7281, 0x8004, 0x8004, 0x8004, + 0x9084, 0x0003, 0x0002, 0x6dc9, 0x6e9c, 0x6ded, 0x6e39, 0x080c, + 0x0d79, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, + 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, + 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, + 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, + 0x9200, 0x70c2, 0x080c, 0x8732, 0x0c18, 0x2071, 0x1800, 0x2900, + 0x7822, 0xa804, 0x900d, 0x15a0, 0x7824, 0x00e6, 0x2071, 0x0040, + 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, + 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee, + 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, + 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7281, 0xd0a4, 0x19c8, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, + 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0804, + 0x6df4, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, + 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d60, 0x00ee, + 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x1198, 0x009e, + 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x1a05, 0x7044, + 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, + 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, + 0x900d, 0x1168, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, + 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, + 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, - 0xa804, 0x900d, 0x1168, 0x2071, 0x1a04, 0x7044, 0x9005, 0x1320, - 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, - 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, - 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, - 0x8899, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, - 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, - 0x2148, 0xa804, 0x900d, 0x1904, 0x6ff1, 0x782c, 0x9094, 0x0780, - 0x190c, 0x7382, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, - 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, - 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, 0x0d68, 0x782c, - 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x01b0, 0x00e6, 0x7824, - 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, - 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, 0x190c, - 0x7382, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x1a04, 0x7044, 0x9005, - 0x1320, 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, - 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, - 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, - 0x70c2, 0x080c, 0x8899, 0x00ee, 0x0804, 0x6fad, 0xa868, 0xd0fc, - 0x15e0, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x100b, - 0x009e, 0x0018, 0xa868, 0xd0fc, 0x1580, 0x00e6, 0x0026, 0xa84f, - 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, - 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, - 0x1904, 0x7142, 0x782c, 0x908c, 0x0780, 0x190c, 0x7382, 0x8004, - 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x7046, 0x7142, 0x7061, - 0x70d3, 0x080c, 0x0d85, 0x2009, 0x1948, 0x2104, 0x0002, 0x7026, - 0x7026, 0x7026, 0x6eb5, 0x7026, 0x6eb5, 0x0005, 0x2071, 0x1800, - 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, + 0xa804, 0x900d, 0x1904, 0x6ef0, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7281, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, + 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x0d68, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7281, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, + 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, + 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, + 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, + 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, + 0x080c, 0x8732, 0x00ee, 0x0804, 0x6eac, 0xa868, 0xd0fc, 0x15e0, + 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fff, 0x009e, + 0x0018, 0xa868, 0xd0fc, 0x1580, 0x00e6, 0x0026, 0xa84f, 0x0000, + 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864, + 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904, + 0x7041, 0x782c, 0x908c, 0x0780, 0x190c, 0x7281, 0x8004, 0x8004, + 0x8004, 0x9084, 0x0003, 0x0002, 0x6f45, 0x7041, 0x6f60, 0x6fd2, + 0x080c, 0x0d79, 0x2009, 0x1949, 0x2104, 0x0002, 0x6f25, 0x6f25, + 0x6f25, 0x6db4, 0x6f25, 0x6db4, 0x0005, 0x2071, 0x1800, 0x2900, + 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0c60, + 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6fc1, + 0x7830, 0xd0dc, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, + 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, + 0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, + 0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x19c8, 0x0e04, 0x6fb8, + 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, + 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, + 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, - 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, - 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, - 0x70c2, 0x7830, 0xd0dc, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, - 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, - 0x1830, 0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, - 0x200c, 0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, - 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8899, - 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x19c8, 0x0e04, - 0x70b9, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, - 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, - 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x1200, 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, - 0x0005, 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, - 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, - 0x8899, 0x0804, 0x7070, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, - 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, - 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, - 0x1d60, 0x00ee, 0x0e04, 0x7115, 0x7838, 0x7938, 0x910e, 0x1de0, - 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, - 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, - 0x190c, 0x1200, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, - 0x7382, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, - 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, - 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, - 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, - 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, + 0x0804, 0x6f6f, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, + 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, + 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d60, + 0x00ee, 0x0e04, 0x7014, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, + 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, + 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11f4, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, + 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, + 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, + 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, + 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, + 0x70b0, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x11b0, + 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, + 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x0d50, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7281, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048, + 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, + 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, + 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x70a9, 0x7838, 0x7938, 0x910e, + 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, + 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11f4, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, + 0x080c, 0x8732, 0x00ee, 0x0804, 0x7051, 0x2071, 0x1910, 0xa803, + 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128, + 0x1e04, 0x70f0, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, - 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, - 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, - 0x1904, 0x71b1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, - 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, - 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, - 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, 0x0d50, 0x782c, - 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x05b8, 0x00e6, 0x7824, - 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, - 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, 0x190c, - 0x7382, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x71aa, 0x7838, 0x7938, - 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, - 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, - 0x2004, 0xd084, 0x190c, 0x1200, 0x704b, 0x0000, 0x00fe, 0x002e, - 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, - 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, - 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, - 0x70c2, 0x080c, 0x8899, 0x00ee, 0x0804, 0x7152, 0x2071, 0x1910, - 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, - 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, - 0x1128, 0x1e04, 0x71f1, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, - 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, - 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, 0x0e04, - 0x71db, 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, - 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, - 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, - 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, 0x1910, - 0x080c, 0x736e, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, - 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, - 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, - 0x013e, 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, - 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, - 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, - 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, - 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, - 0x70c2, 0x080c, 0x8899, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, - 0x0006, 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, - 0x9080, 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, - 0xa87e, 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, - 0x0002, 0x7281, 0x7282, 0x736d, 0x7282, 0x727f, 0x736d, 0x080c, - 0x0d85, 0x0005, 0x2001, 0x1948, 0x2004, 0x0002, 0x728c, 0x728c, - 0x7306, 0x7307, 0x728c, 0x7307, 0x0126, 0x2091, 0x8000, 0x1e0c, - 0x738d, 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x72d7, - 0x0e04, 0x72b5, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, - 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, - 0x1278, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x1200, 0x2071, 0x1910, 0x080c, 0x736e, 0x012e, 0x0804, 0x7305, - 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, - 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, - 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, - 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, - 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, 0x2071, - 0x1910, 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0e04, 0x70da, + 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, + 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, + 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x2071, 0x1910, 0x080c, + 0x726d, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, + 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, + 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, + 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, + 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, + 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, + 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, + 0x080c, 0x8732, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, + 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, + 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002, + 0x7180, 0x7181, 0x726c, 0x7181, 0x717e, 0x726c, 0x080c, 0x0d79, + 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x718b, 0x718b, 0x7205, + 0x7206, 0x718b, 0x7206, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x728c, + 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x71d6, 0x0e04, + 0x71b4, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, + 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, + 0x2071, 0x1910, 0x080c, 0x726d, 0x012e, 0x0804, 0x7204, 0xa850, + 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, + 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, + 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, + 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b, + 0x2004, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x2071, 0x1910, + 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, + 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, + 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071, + 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, + 0x2069, 0x1a05, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003, + 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1b74, 0x210c, 0x9102, + 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838, + 0x9106, 0x0190, 0x0e04, 0x7238, 0x2069, 0x0000, 0x6837, 0x8040, + 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11f4, 0x2069, 0x1a05, 0x6847, 0xffff, + 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x72fc, 0x701c, + 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, + 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, - 0x2071, 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, - 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, - 0x2008, 0x2069, 0x1a04, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, - 0x0003, 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1b73, 0x210c, - 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, - 0x6838, 0x9106, 0x0190, 0x0e04, 0x7339, 0x2069, 0x0000, 0x6837, - 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, - 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2069, 0x1a04, 0x6847, - 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x73fd, - 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, - 0x15c9, 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, - 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, - 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, - 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, - 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, - 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, - 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x108b, 0x0005, - 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x7384, 0x0006, 0x0016, - 0x2001, 0x8004, 0x0006, 0x0804, 0x0d8e, 0x0096, 0x00f6, 0x2079, - 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, - 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, - 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, - 0x1200, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, - 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, - 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, - 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, - 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, - 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, - 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, - 0x190c, 0x7382, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e, 0x1de0, - 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, - 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x00ee, - 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, - 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, + 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, + 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000, + 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x107f, 0x0005, 0x012e, + 0x0005, 0x2091, 0x8000, 0x0e04, 0x7283, 0x0006, 0x0016, 0x2001, + 0x8004, 0x0006, 0x0804, 0x0d82, 0x0096, 0x00f6, 0x2079, 0x0050, + 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, - 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, - 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, - 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, - 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, - 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x1d70, 0x00d6, 0x2069, - 0x0050, 0x693c, 0x2069, 0x1948, 0x6808, 0x690a, 0x2069, 0x1a04, - 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, 0x2001, 0x1949, 0x200c, - 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x002a, - 0x1a0c, 0x0d85, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00, - 0x080c, 0x2ad3, 0x002e, 0x0005, 0x7542, 0x74af, 0x74cb, 0x74f5, - 0x7531, 0x7571, 0x7583, 0x74cb, 0x7559, 0x746a, 0x7498, 0x751b, - 0x7469, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, - 0x6808, 0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x198f, 0x2d04, - 0x7002, 0x080c, 0x78e4, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, - 0x709b, 0x0029, 0x2069, 0x198f, 0x2d04, 0x7002, 0x6028, 0x9085, - 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6e, - 0x080c, 0x1b1e, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, - 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, - 0x1160, 0x709b, 0x0029, 0x2069, 0x198f, 0x2d04, 0x7002, 0x080c, - 0x7990, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, - 0x2001, 0x0090, 0x080c, 0x2a99, 0x000e, 0x6124, 0xd1e4, 0x1190, - 0x080c, 0x75f4, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, - 0x709b, 0x0020, 0x080c, 0x75f4, 0x0028, 0x709b, 0x001d, 0x0010, - 0x709b, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2a99, 0x6124, - 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, - 0x11d8, 0x080c, 0x1b4b, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, - 0x080c, 0x77ca, 0x2001, 0x0080, 0x080c, 0x2a99, 0x709b, 0x0029, - 0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, - 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b4b, 0x60e3, - 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x77ca, 0x2001, 0x0080, - 0x080c, 0x2a99, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, - 0x1148, 0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, - 0x0028, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, - 0x709b, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, - 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, - 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, - 0x0005, 0x2001, 0x00a0, 0x080c, 0x2a99, 0x6124, 0xd1dc, 0x1138, - 0xd1e4, 0x0138, 0x080c, 0x1b4b, 0x709b, 0x001e, 0x0010, 0x709b, - 0x001d, 0x0005, 0x080c, 0x767d, 0x6124, 0xd1dc, 0x1188, 0x080c, - 0x75f4, 0x0016, 0x080c, 0x1b4b, 0x001e, 0xd1d4, 0x1128, 0xd1e4, - 0x0138, 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x75f4, - 0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2a99, 0x000e, 0x6124, - 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, - 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, - 0x0005, 0x080c, 0x767d, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, - 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, - 0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2a99, - 0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, - 0xd1e4, 0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, - 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, - 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, - 0x1800, 0x2091, 0x8000, 0x080c, 0x779e, 0x11f8, 0x2001, 0x180c, - 0x200c, 0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011, 0x0200, - 0x080c, 0x2ad3, 0x002e, 0x080c, 0x2a7f, 0x6024, 0xd0cc, 0x0148, - 0x2001, 0x00a0, 0x080c, 0x2a99, 0x080c, 0x7ab6, 0x080c, 0x619d, - 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x77b8, 0x0150, - 0x080c, 0x77af, 0x1138, 0x2001, 0x0001, 0x080c, 0x2631, 0x080c, - 0x7772, 0x00a0, 0x080c, 0x767a, 0x0178, 0x2001, 0x0001, 0x080c, - 0x2631, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, - 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, - 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x7605, 0x080c, - 0x8a9f, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x7605, - 0x080c, 0x8a96, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, - 0x080c, 0xa2a0, 0x2071, 0x1800, 0x080c, 0x759e, 0x001e, 0x00fe, - 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, - 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, 0xa2a0, 0x2061, 0x0100, - 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, - 0xacfc, 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, - 0xa635, 0x080c, 0xa516, 0x080c, 0x8a4b, 0x0036, 0x901e, 0x080c, - 0xa596, 0x003e, 0x080c, 0xad18, 0x60e3, 0x0000, 0x080c, 0xeed9, - 0x080c, 0xeef4, 0x2009, 0x0004, 0x080c, 0x2a85, 0x080c, 0x299b, - 0x2001, 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2ad3, - 0x2011, 0x7605, 0x080c, 0x8a9f, 0x080c, 0x77b8, 0x0118, 0x9006, - 0x080c, 0x2a99, 0x080c, 0x0bcf, 0x2001, 0x0001, 0x080c, 0x2631, - 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, - 0x0005, 0x0026, 0x00e6, 0x2011, 0x7612, 0x2071, 0x1a04, 0x701c, - 0x9206, 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, - 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, - 0x9086, 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2a99, 0x0156, - 0x20a9, 0x002d, 0x1d04, 0x768a, 0x2091, 0x6000, 0x1f04, 0x768a, - 0x015e, 0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, - 0x689e, 0x00de, 0x0005, 0x689f, 0x0014, 0x68ec, 0xd0dc, 0x0dc8, - 0x6800, 0x9086, 0x0001, 0x1da8, 0x080c, 0x8aab, 0x0c90, 0x00c6, - 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, - 0x080c, 0x7ac5, 0x2001, 0x196d, 0x2003, 0x0000, 0x9006, 0x709a, - 0x60e2, 0x6886, 0x080c, 0x2700, 0x9006, 0x080c, 0x2a99, 0x080c, - 0x6058, 0x0026, 0x2011, 0xffff, 0x080c, 0x2ad3, 0x002e, 0x602b, - 0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, - 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197d, - 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, - 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7762, 0x709b, - 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, - 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, - 0x080c, 0x2700, 0x080c, 0xacfc, 0x0026, 0x080c, 0xafd2, 0x080c, - 0xb09b, 0x002e, 0x080c, 0xad18, 0x7000, 0x908e, 0x0004, 0x0118, - 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, - 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, - 0x080c, 0xd645, 0x0118, 0x9006, 0x080c, 0x2ac3, 0x0804, 0x776e, - 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2a7f, 0x6904, - 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2a99, 0x1f04, 0x7713, - 0x080c, 0x77f2, 0x012e, 0x015e, 0x080c, 0x77af, 0x0170, 0x6044, - 0x9005, 0x0130, 0x080c, 0x77f2, 0x9006, 0x8001, 0x1df0, 0x0028, - 0x6804, 0xd0d4, 0x1110, 0x080c, 0x77f2, 0x080c, 0xd645, 0x0118, - 0x9006, 0x080c, 0x2ac3, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, - 0x0130, 0x2009, 0x00c8, 0x2011, 0x7612, 0x080c, 0x8a5d, 0x002e, - 0x001e, 0x080c, 0x8890, 0x7034, 0xc085, 0x7036, 0x2001, 0x197d, - 0x2003, 0x0004, 0x080c, 0x744d, 0x080c, 0x77af, 0x0138, 0x6804, - 0xd0d4, 0x1120, 0xd0dc, 0x1100, 0x080c, 0x7abb, 0x00ee, 0x00de, - 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, - 0x0140, 0x2071, 0x1800, 0x080c, 0x88a7, 0x080c, 0x8899, 0x080c, - 0x7ac5, 0x2001, 0x196d, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, - 0x6886, 0x080c, 0x2700, 0x9006, 0x080c, 0x2a99, 0x6043, 0x0090, - 0x6043, 0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2ad3, 0x002e, - 0x602b, 0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, - 0x197c, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, - 0x5844, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, - 0x080c, 0x5844, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, - 0x0006, 0x080c, 0x5844, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, - 0x0005, 0x0006, 0x080c, 0x5844, 0x9084, 0x0030, 0x9086, 0x0020, - 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, - 0x0013, 0x0168, 0x0020, 0x080c, 0x2720, 0x900e, 0x0010, 0x2009, - 0x0002, 0x2019, 0x0028, 0x080c, 0x32da, 0x9006, 0x0019, 0x001e, - 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, - 0xd63e, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, - 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, - 0x6004, 0x0006, 0x6028, 0x0006, 0x080c, 0x2af6, 0x080c, 0x2b29, - 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, - 0x20a9, 0x0002, 0x080c, 0x2a60, 0x0026, 0x2011, 0x0040, 0x080c, - 0x2ad3, 0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, - 0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, - 0x080c, 0x2700, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd645, 0x000e, - 0x0130, 0x080c, 0x2ab7, 0x9006, 0x080c, 0x2ac3, 0x0010, 0x080c, - 0x2a99, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, - 0x2079, 0x0100, 0x080c, 0x2a0c, 0x00fe, 0x000e, 0x6052, 0x0005, - 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, - 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xad5a, 0x0158, - 0x2001, 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, - 0xaced, 0x0804, 0x78d6, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, - 0x6028, 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2ad3, - 0x2001, 0x0090, 0x080c, 0x2a99, 0x20a9, 0x0366, 0x6024, 0xd0cc, - 0x1560, 0x1d04, 0x786e, 0x2091, 0x6000, 0x1f04, 0x786e, 0x080c, - 0xacfc, 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, - 0xa635, 0x080c, 0xa516, 0x901e, 0x080c, 0xa596, 0x2001, 0x0386, - 0x2003, 0x7000, 0x080c, 0xad18, 0x2001, 0x00a0, 0x080c, 0x2a99, - 0x080c, 0x7ab6, 0x080c, 0x619d, 0x080c, 0xd645, 0x0110, 0x080c, - 0x0cf1, 0x9085, 0x0001, 0x0804, 0x78dc, 0x080c, 0x1b4b, 0x60e3, - 0x0000, 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1118, - 0x2001, 0x196d, 0x2004, 0x080c, 0x2700, 0x60e2, 0x2001, 0x0080, - 0x080c, 0x2a99, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x2ad3, - 0x2009, 0x1e00, 0x080c, 0x2a7f, 0x6024, 0x910c, 0x0140, 0x1d04, - 0x78b4, 0x2091, 0x6000, 0x1f04, 0x78b4, 0x0804, 0x7877, 0x2001, - 0x0386, 0x2003, 0x7000, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, - 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd645, - 0x0110, 0x080c, 0x0cf1, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, - 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, - 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x7000, - 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, 0x5540, - 0x9086, 0x5540, 0x1128, 0x2069, 0x1a7b, 0x2d04, 0x8000, 0x206a, - 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, - 0x1904, 0x794d, 0x2001, 0x0088, 0x080c, 0x2a99, 0x9006, 0x60e2, - 0x6886, 0x080c, 0x2700, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, - 0x6808, 0x9005, 0x01d0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x2011, - 0x0400, 0x080c, 0x2ad3, 0x2069, 0x198f, 0x7000, 0x206a, 0x709b, - 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x792d, 0x2091, - 0x6000, 0x1f04, 0x792d, 0x0804, 0x7988, 0x2069, 0x0140, 0x20a9, - 0x0384, 0x2011, 0x1e00, 0x080c, 0x2ad3, 0x2009, 0x1e00, 0x080c, - 0x2a7f, 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, - 0x7939, 0x2091, 0x6000, 0x1f04, 0x7939, 0x080c, 0xacfc, 0x2011, - 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, 0xa635, 0x080c, - 0xa516, 0x901e, 0x080c, 0xa596, 0x080c, 0xad18, 0x2001, 0x00a0, - 0x080c, 0x2a99, 0x080c, 0x7ab6, 0x080c, 0x619d, 0x9085, 0x0001, - 0x00f8, 0x080c, 0x1b4b, 0x2001, 0x0080, 0x080c, 0x2a99, 0x2069, - 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, - 0x0008, 0x6886, 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, - 0x1118, 0x2001, 0x196d, 0x2004, 0x080c, 0x2700, 0x60e2, 0x9006, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, + 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780, + 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102, + 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, + 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, + 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee, + 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, + 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7281, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, + 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x00ee, 0x704b, + 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, + 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, + 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x00fe, + 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x0db8, + 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, + 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, + 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, + 0x693c, 0x2069, 0x1949, 0x6808, 0x690a, 0x2069, 0x1a05, 0x9102, + 0x1118, 0x6844, 0x9005, 0x1320, 0x2001, 0x194a, 0x200c, 0x6946, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x002a, 0x1a0c, + 0x0d79, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00, 0x080c, + 0x2adc, 0x002e, 0x0005, 0x7441, 0x73ae, 0x73ca, 0x73f4, 0x7430, + 0x7470, 0x7482, 0x73ca, 0x7458, 0x7369, 0x7397, 0x741a, 0x7368, + 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, + 0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, + 0x080c, 0x77db, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, + 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, + 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6f, 0x080c, + 0x1b3b, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, + 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, + 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x7880, + 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, + 0x0090, 0x080c, 0x2aa2, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, + 0x74f3, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, + 0x0020, 0x080c, 0x74f3, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, + 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2aa2, 0x6124, 0xd1cc, + 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, + 0x080c, 0x1b68, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, + 0x76c9, 0x2001, 0x0080, 0x080c, 0x2aa2, 0x709b, 0x0029, 0x0058, + 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, + 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b68, 0x60e3, 0x0001, + 0x600c, 0xc0b4, 0x600e, 0x080c, 0x76c9, 0x2001, 0x0080, 0x080c, + 0x2aa2, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, + 0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, 0x0028, + 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, + 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, + 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, 0x709b, + 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, + 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x6124, 0xd1dc, 0x1138, 0xd1e4, + 0x0138, 0x080c, 0x1b68, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d, + 0x0005, 0x080c, 0x757c, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x74f3, + 0x0016, 0x080c, 0x1b68, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, + 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x74f3, 0x0005, + 0x0006, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x000e, 0x6124, 0xd1d4, + 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, + 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, 0x0005, + 0x080c, 0x757c, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, + 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, + 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2aa2, 0x000e, + 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, + 0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, + 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, + 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, + 0x2091, 0x8000, 0x080c, 0x769d, 0x11f8, 0x2001, 0x180c, 0x200c, + 0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011, 0x0200, 0x080c, + 0x2adc, 0x002e, 0x080c, 0x2a88, 0x6024, 0xd0cc, 0x0148, 0x2001, + 0x00a0, 0x080c, 0x2aa2, 0x080c, 0x799f, 0x080c, 0x6178, 0x0428, + 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x76b7, 0x0150, 0x080c, + 0x76ae, 0x1138, 0x2001, 0x0001, 0x080c, 0x2646, 0x080c, 0x7671, + 0x00a0, 0x080c, 0x7579, 0x0178, 0x2001, 0x0001, 0x080c, 0x2646, + 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, 0x1118, + 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, 0x00de, + 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x7504, 0x080c, 0x8938, + 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x7504, 0x080c, + 0x892f, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, + 0xa09b, 0x2071, 0x1800, 0x080c, 0x749d, 0x001e, 0x00fe, 0x00ee, + 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x0126, 0x2071, 0x1800, 0x080c, 0xa09b, 0x2061, 0x0100, 0x2069, + 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7, + 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, + 0x080c, 0xa311, 0x080c, 0x88e4, 0x0036, 0x901e, 0x080c, 0xa391, + 0x003e, 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c, 0xebe8, 0x080c, + 0xec03, 0x2009, 0x0004, 0x080c, 0x2a8e, 0x080c, 0x29a8, 0x2001, + 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2adc, 0x2011, + 0x7504, 0x080c, 0x8938, 0x080c, 0x76b7, 0x0118, 0x9006, 0x080c, + 0x2aa2, 0x080c, 0x0bc3, 0x2001, 0x0001, 0x080c, 0x2646, 0x012e, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, + 0x0026, 0x00e6, 0x2011, 0x7511, 0x2071, 0x1a05, 0x701c, 0x9206, + 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, + 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, + 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2aa2, 0x0156, 0x20a9, + 0x002d, 0x1d04, 0x7589, 0x2091, 0x6000, 0x1f04, 0x7589, 0x015e, + 0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, 0x689e, + 0x00de, 0x0005, 0x689f, 0x0014, 0x68ec, 0xd0dc, 0x0dc8, 0x6800, + 0x9086, 0x0001, 0x1da8, 0x080c, 0x8944, 0x0c90, 0x00c6, 0x00d6, + 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, + 0x79ae, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, + 0x6886, 0x080c, 0x2715, 0x9006, 0x080c, 0x2aa2, 0x080c, 0x6033, + 0x0026, 0x2011, 0xffff, 0x080c, 0x2adc, 0x002e, 0x602b, 0x182c, + 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, + 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197e, 0x200c, + 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002, + 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7661, 0x709b, 0x0022, + 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, 0x709b, + 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, + 0x2715, 0x080c, 0xaaf7, 0x0026, 0x080c, 0xadbe, 0x080c, 0xae87, + 0x002e, 0x080c, 0xab13, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b, + 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, + 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, + 0xd35d, 0x0118, 0x9006, 0x080c, 0x2acc, 0x0804, 0x766d, 0x6800, + 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2a88, 0x6904, 0xd1d4, + 0x1140, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x1f04, 0x7612, 0x080c, + 0x76f1, 0x012e, 0x015e, 0x080c, 0x76ae, 0x0170, 0x6044, 0x9005, + 0x0130, 0x080c, 0x76f1, 0x9006, 0x8001, 0x1df0, 0x0028, 0x6804, + 0xd0d4, 0x1110, 0x080c, 0x76f1, 0x080c, 0xd35d, 0x0118, 0x9006, + 0x080c, 0x2acc, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, + 0x2009, 0x00c8, 0x2011, 0x7511, 0x080c, 0x88f6, 0x002e, 0x001e, + 0x080c, 0x8729, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003, + 0x0004, 0x080c, 0x734c, 0x080c, 0x76ae, 0x0138, 0x6804, 0xd0d4, + 0x1120, 0xd0dc, 0x1100, 0x080c, 0x79a4, 0x00ee, 0x00de, 0x00ce, + 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, + 0x2071, 0x1800, 0x080c, 0x8740, 0x080c, 0x8732, 0x080c, 0x79ae, + 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, + 0x080c, 0x2715, 0x9006, 0x080c, 0x2aa2, 0x6043, 0x0090, 0x6043, + 0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2adc, 0x002e, 0x602b, + 0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197d, + 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x5824, + 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c, + 0x5824, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006, + 0x080c, 0x5824, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005, + 0x0006, 0x080c, 0x5824, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e, + 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013, + 0x0168, 0x0020, 0x080c, 0x2735, 0x900e, 0x0010, 0x2009, 0x0002, + 0x2019, 0x0028, 0x080c, 0x32c0, 0x9006, 0x0019, 0x001e, 0x003e, + 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd356, + 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, 0x00ee, + 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, + 0x0006, 0x6028, 0x0006, 0x080c, 0x2aff, 0x080c, 0x2b32, 0x602f, + 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, 0x20a9, + 0x0002, 0x080c, 0x2a69, 0x0026, 0x2011, 0x0040, 0x080c, 0x2adc, + 0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, + 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, + 0x2715, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd35d, 0x000e, 0x0130, + 0x080c, 0x2ac0, 0x9006, 0x080c, 0x2acc, 0x0010, 0x080c, 0x2aa2, + 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, + 0x0100, 0x080c, 0x2a19, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, + 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, + 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xab55, 0x0158, 0x2001, + 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, 0xaae8, + 0x0804, 0x77cd, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, + 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2adc, 0x2001, + 0x0090, 0x080c, 0x2aa2, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1558, + 0x1d04, 0x776d, 0x2091, 0x6000, 0x1f04, 0x776d, 0x080c, 0xaaf7, + 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, + 0x080c, 0xa311, 0x901e, 0x080c, 0xa391, 0x2001, 0x0386, 0x2003, + 0x7000, 0x080c, 0xab13, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x080c, + 0x799f, 0x080c, 0x6178, 0x080c, 0xd35d, 0x0110, 0x080c, 0x0ce5, + 0x9085, 0x0001, 0x04c0, 0x080c, 0x1b68, 0x60e3, 0x0000, 0x2001, + 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x2001, 0x0080, 0x080c, + 0x2aa2, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x2adc, 0x2009, + 0x1e00, 0x080c, 0x2a88, 0x6024, 0x910c, 0x0140, 0x1d04, 0x77ab, + 0x2091, 0x6000, 0x1f04, 0x77ab, 0x0804, 0x7776, 0x2001, 0x0386, + 0x2003, 0x7000, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, 0x9005, + 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd35d, 0x0110, + 0x080c, 0x0ce5, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x7000, 0x9086, + 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, 0x5540, 0x9086, + 0x5540, 0x1128, 0x2069, 0x1a7c, 0x2d04, 0x8000, 0x206a, 0x2069, + 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904, + 0x7844, 0x2001, 0x0088, 0x080c, 0x2aa2, 0x9006, 0x60e2, 0x6886, + 0x080c, 0x2715, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, + 0x9005, 0x01d0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x2011, 0x0400, + 0x080c, 0x2adc, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0026, + 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7824, 0x2091, 0x6000, + 0x1f04, 0x7824, 0x0804, 0x7878, 0x2069, 0x0140, 0x20a9, 0x0384, + 0x2011, 0x1e00, 0x080c, 0x2adc, 0x2009, 0x1e00, 0x080c, 0x2a88, + 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, 0x7830, + 0x2091, 0x6000, 0x1f04, 0x7830, 0x080c, 0xaaf7, 0x2011, 0x0003, + 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, 0x080c, 0xa311, + 0x901e, 0x080c, 0xa391, 0x080c, 0xab13, 0x2001, 0x00a0, 0x080c, + 0x2aa2, 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x00c0, + 0x080c, 0x1b68, 0x2001, 0x0080, 0x080c, 0x2aa2, 0x2069, 0x0140, + 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, + 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01e8, 0x080c, - 0xacfc, 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, - 0xa635, 0x080c, 0xa516, 0x901e, 0x080c, 0xa596, 0x080c, 0xad18, - 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2a99, 0x080c, 0x7ab6, - 0x080c, 0x619d, 0x0804, 0x7a32, 0x2001, 0x180c, 0x200c, 0xd1b4, - 0x1160, 0xc1b5, 0x2102, 0x080c, 0x75fa, 0x2069, 0x0140, 0x2001, - 0x0080, 0x080c, 0x2a99, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, + 0xaaf7, 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, + 0xa430, 0x080c, 0xa311, 0x901e, 0x080c, 0xa391, 0x080c, 0xab13, + 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x080c, 0x799f, + 0x080c, 0x6178, 0x0804, 0x791b, 0x2001, 0x180c, 0x200c, 0xd1b4, + 0x1160, 0xc1b5, 0x2102, 0x080c, 0x74f9, 0x2069, 0x0140, 0x2001, + 0x0080, 0x080c, 0x2aa2, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x0190, 0x6028, 0x9084, 0xfdff, - 0x602a, 0x2011, 0x0200, 0x080c, 0x2ad3, 0x2069, 0x198f, 0x7000, - 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x7a32, 0x2011, - 0x1e00, 0x080c, 0x2ad3, 0x2009, 0x1e00, 0x080c, 0x2a7f, 0x6024, - 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x79e7, 0x0006, - 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x88e7, 0x00ee, 0x00de, - 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x1a04, 0x7078, 0x00ee, - 0x9005, 0x19e8, 0x0438, 0x0026, 0x2011, 0x7612, 0x080c, 0x8993, - 0x2011, 0x7605, 0x080c, 0x8a9f, 0x002e, 0x2069, 0x0140, 0x60e3, + 0x602a, 0x2011, 0x0200, 0x080c, 0x2adc, 0x2069, 0x1990, 0x7000, + 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x791b, 0x2011, + 0x1e00, 0x080c, 0x2adc, 0x2009, 0x1e00, 0x080c, 0x2a88, 0x6024, + 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x78d7, 0x0006, + 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8780, 0x00ee, 0x00de, + 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x1a05, 0x7078, 0x00ee, + 0x9005, 0x19e8, 0x0400, 0x0026, 0x2011, 0x7511, 0x080c, 0x882c, + 0x2011, 0x7504, 0x080c, 0x8938, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, - 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1118, 0x2001, - 0x196d, 0x2004, 0x080c, 0x2700, 0x60e2, 0x2001, 0x180c, 0x200c, - 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, - 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, - 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd63e, 0x1904, - 0x7aa0, 0x7130, 0xd184, 0x1170, 0x080c, 0x3482, 0x0138, 0xc18d, - 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, - 0x0904, 0x7aa0, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, 0x0016, - 0x2019, 0x000e, 0x080c, 0xe9f9, 0x0156, 0x00b6, 0x20a9, 0x007f, - 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, - 0x67b4, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, - 0xea8d, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8c44, 0x001e, - 0x8108, 0x1f04, 0x7a69, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, - 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32da, 0x001e, - 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x67b4, - 0x1110, 0x080c, 0x61b7, 0x8108, 0x1f04, 0x7a96, 0x00be, 0x015e, - 0x080c, 0x1b4b, 0x080c, 0xacfc, 0x080c, 0xb09b, 0x080c, 0xad18, - 0x60e3, 0x0000, 0x080c, 0x619d, 0x080c, 0x76cd, 0x00ee, 0x00ce, - 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x197d, - 0x2003, 0x0001, 0x0005, 0x2001, 0x197d, 0x2003, 0x0000, 0x0005, - 0x2001, 0x197c, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197c, 0x2003, - 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007, 0x0000, - 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900, 0x704e, - 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900, 0x7052, - 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, - 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, - 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, - 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, 0x7002, 0x6854, - 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, 0x9005, 0x1110, - 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, - 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, - 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, 0x18fa, - 0x6807, 0x0001, 0x00de, 0x080c, 0x8103, 0x9006, 0x00ee, 0x0005, - 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x818d, 0x1f04, 0x7b2c, - 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004, 0x0002, - 0x7b42, 0x7b43, 0x7b8f, 0x7bea, 0x7d4a, 0x7b40, 0x7b40, 0x7d74, - 0x080c, 0x0d85, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0, 0x2003, - 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x81e5, 0xd0a4, 0x0578, - 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080, 0x1648, 0x1d04, 0x7b60, - 0x2001, 0x1a07, 0x200c, 0x8109, 0x0510, 0x2091, 0x6000, 0x2102, - 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, - 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, - 0x0003, 0x1168, 0x7004, 0x0002, 0x7b7f, 0x7b49, 0x7b7f, 0x7b7d, - 0x7b7f, 0x7b7f, 0x7b7f, 0x7b7f, 0x7b7f, 0x080c, 0x7bea, 0x782c, - 0xd09c, 0x090c, 0x8103, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, - 0x003b, 0x0c10, 0x080c, 0x7c20, 0x0c90, 0x00e3, 0x08e8, 0x0005, - 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, - 0x7c42, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, - 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, - 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c2c, 0x7c20, 0x7e6a, 0x7c20, - 0x7c20, 0x7c20, 0x7c42, 0x7c20, 0x7c2c, 0x7eab, 0x7eec, 0x7f33, - 0x7f47, 0x7c20, 0x7c20, 0x7c42, 0x7c2c, 0x7c56, 0x7c20, 0x7d1e, - 0x7ff2, 0x800d, 0x7c20, 0x7c42, 0x7c20, 0x7c56, 0x7c20, 0x7c20, - 0x7d14, 0x800d, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, - 0x7c20, 0x7c20, 0x7c20, 0x7c6a, 0x7c20, 0x7c20, 0x7c20, 0x7c20, - 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x8189, 0x7c20, 0x8133, - 0x7c20, 0x8133, 0x7c20, 0x7c7f, 0x7c20, 0x7c20, 0x7c20, 0x7c20, - 0x7c20, 0x7c20, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, - 0x782c, 0x080c, 0x812c, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, - 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, - 0x002b, 0x0c50, 0x00e9, 0x080c, 0x8103, 0x0005, 0x7c20, 0x7c2c, - 0x7e56, 0x7c20, 0x7c2c, 0x7c20, 0x7c2c, 0x7c2c, 0x7c20, 0x7c2c, - 0x7e56, 0x7c2c, 0x7c2c, 0x7c2c, 0x7c2c, 0x7c2c, 0x7c20, 0x7c2c, - 0x7e56, 0x7c20, 0x7c20, 0x7c2c, 0x7c20, 0x7c20, 0x7c20, 0x7c2c, - 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, - 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, - 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, - 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, - 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, - 0x1120, 0x7007, 0x0001, 0x0804, 0x7df3, 0x7007, 0x0003, 0x7012, - 0x2900, 0x7016, 0x701a, 0x704b, 0x7df3, 0x0005, 0xa864, 0x8007, - 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, - 0x7e0e, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, - 0x7e0e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, 0x7c28, - 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7e2a, 0x7007, 0x0003, - 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7e2a, 0x0005, 0xa864, - 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7c28, 0x7007, - 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1904, 0x7ceb, 0x2001, - 0x180d, 0x2004, 0xd08c, 0x0904, 0x7cd6, 0xa99c, 0x9186, 0x00ff, - 0x05e8, 0xa994, 0x9186, 0x006f, 0x0188, 0x9186, 0x0074, 0x15b0, - 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, 0x002e, 0x0578, 0x0016, - 0xa998, 0x080c, 0x6c7f, 0x001e, 0x1548, 0x0400, 0x080c, 0x779e, - 0x0140, 0xa897, 0x4005, 0xa89b, 0x0016, 0x2001, 0x0030, 0x900e, - 0x0438, 0x0026, 0x2011, 0x8008, 0x080c, 0x6c35, 0x002e, 0x01b0, - 0x0016, 0x0026, 0x0036, 0xa998, 0xaaa0, 0xab9c, 0x918d, 0x8000, - 0x080c, 0x6c7f, 0x003e, 0x002e, 0x001e, 0x1140, 0xa897, 0x4005, - 0xa89b, 0x4009, 0x2001, 0x0030, 0x900e, 0x0050, 0xa868, 0x9084, - 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x6430, 0x1108, 0x0005, - 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, - 0x7012, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0904, 0x7c8f, - 0x9186, 0x0064, 0x0904, 0x7c8f, 0x9186, 0x007c, 0x0904, 0x7c8f, - 0x9186, 0x0028, 0x0904, 0x7c8f, 0x9186, 0x0038, 0x0904, 0x7c8f, - 0x9186, 0x0078, 0x0904, 0x7c8f, 0x9186, 0x005f, 0x0904, 0x7c8f, - 0x9186, 0x0056, 0x0904, 0x7c8f, 0xa897, 0x4005, 0xa89b, 0x0001, - 0x2001, 0x0030, 0x900e, 0x0860, 0xa87c, 0x9084, 0x00c0, 0x9086, - 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x8024, 0x2900, 0x7016, - 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, - 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, - 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x7c30, - 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7c30, 0x82ff, 0x1138, 0xa8b8, - 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7db1, 0x0018, 0x9280, 0x7da7, - 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7d92, 0x080c, 0x1072, - 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, - 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, - 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, - 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, - 0x810b, 0xa17e, 0x080c, 0x114e, 0xa06c, 0x908e, 0x0100, 0x0170, - 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, - 0x080c, 0x108b, 0x7014, 0x2048, 0x0804, 0x7c30, 0x7020, 0x2048, - 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, - 0x0804, 0x7d4a, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, - 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, - 0x00ff, 0x9086, 0x001e, 0x0904, 0x8024, 0x0804, 0x7df3, 0x7da9, - 0x7dad, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, - 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, - 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, - 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, - 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, - 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, - 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, - 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, - 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, - 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1178, - 0x080c, 0x622f, 0x1108, 0x0005, 0x080c, 0x725e, 0x0126, 0x2091, - 0x8000, 0x080c, 0xd220, 0x080c, 0x7012, 0x012e, 0x0ca0, 0x080c, - 0xd63e, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, - 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, 0x0000, - 0x080c, 0x62bd, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000, - 0x080c, 0x7012, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, - 0x0000, 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, - 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x6392, 0x1138, 0x0005, - 0x9006, 0xa87a, 0x080c, 0x630a, 0x1108, 0x0005, 0x0126, 0x2091, - 0x8000, 0xa87a, 0xa982, 0x080c, 0x7012, 0x012e, 0x0cb0, 0x2001, - 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, - 0x1800, 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, - 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, - 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, - 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, - 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, - 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, - 0x11d8, 0xa974, 0x080c, 0x67b4, 0x11b8, 0x0066, 0xae80, 0x080c, - 0x68c4, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, - 0x2412, 0x004e, 0x00c6, 0x080c, 0x67b4, 0x1110, 0x080c, 0x6a9e, - 0x8108, 0x1f04, 0x7e93, 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, - 0x108b, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, - 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, - 0x080c, 0x6c0d, 0x0580, 0x2061, 0x1a73, 0x6100, 0xd184, 0x0178, - 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, - 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, - 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, - 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, - 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, - 0x012e, 0x0804, 0x80ed, 0x012e, 0x0804, 0x80e7, 0x012e, 0x0804, - 0x80e1, 0x012e, 0x0804, 0x80e4, 0x0126, 0x2091, 0x8000, 0x7007, - 0x0001, 0x080c, 0x6c0d, 0x05e0, 0x2061, 0x1a73, 0x6000, 0xd084, - 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, - 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, - 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, - 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, - 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, - 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, - 0x6206, 0x630a, 0x012e, 0x0804, 0x80ed, 0x012e, 0x0804, 0x80ea, - 0x012e, 0x0804, 0x80e7, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, - 0x2061, 0x1a73, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, - 0x630a, 0x012e, 0x0804, 0x80fb, 0x012e, 0x0804, 0x80ea, 0x00b6, - 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, - 0x0148, 0x00c6, 0x2061, 0x1a73, 0x6000, 0x9084, 0xfcff, 0x6002, - 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, - 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xb1a7, 0x0068, - 0x6017, 0xf400, 0x6063, 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, - 0x6162, 0x2009, 0x0041, 0x080c, 0xb20a, 0xa988, 0x918c, 0xff00, - 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, - 0x8c44, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a73, 0x6000, - 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, - 0x00be, 0x0804, 0x80ed, 0x00ce, 0x012e, 0x00be, 0x0804, 0x80e7, - 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, - 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, - 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, - 0x1d10, 0xa974, 0x080c, 0x67b4, 0x1968, 0xb800, 0xc0e4, 0xb802, - 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, 0x1986, - 0x2004, 0x601a, 0x0804, 0x7f82, 0xa88c, 0x9065, 0x0960, 0x00e6, - 0xa890, 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, - 0xb1a7, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xb1a7, 0x00ee, 0x0804, - 0x7f82, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, - 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, - 0x6016, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x00ee, - 0x0804, 0x7f82, 0x2061, 0x1a73, 0x6000, 0xd084, 0x0190, 0xd08c, - 0x1904, 0x80fb, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, - 0x6206, 0x012e, 0x0804, 0x80fb, 0x012e, 0xa883, 0x0016, 0x0804, - 0x80f4, 0xa883, 0x0007, 0x0804, 0x80f4, 0xa864, 0x8007, 0x9084, - 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, - 0x080c, 0x7c28, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, - 0x701a, 0x704b, 0x8024, 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, - 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, 0x80a6, - 0x6130, 0xd194, 0x1904, 0x80d0, 0xa878, 0x2070, 0x9e82, 0x1ddc, - 0x0a04, 0x809a, 0x6068, 0x9e02, 0x1a04, 0x809a, 0x7120, 0x9186, - 0x0006, 0x1904, 0x808c, 0x7010, 0x905d, 0x0904, 0x80a6, 0xb800, - 0xd0e4, 0x1904, 0x80ca, 0x2061, 0x1a73, 0x6100, 0x9184, 0x0301, - 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x80d3, 0xa883, - 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, - 0xa87c, 0xd0f4, 0x1904, 0x80d6, 0x080c, 0x5840, 0xd09c, 0x1118, - 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8b34, 0x012e, 0x00ee, - 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, - 0xa87c, 0xd0f4, 0x1904, 0x80d6, 0x012e, 0x00ee, 0x00be, 0x0005, - 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x80f4, 0xd184, - 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x67b4, 0x15d0, - 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, - 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, - 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, 0x5844, - 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x02c0, 0x6068, - 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, - 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, - 0x0007, 0x1904, 0x8030, 0x7003, 0x0002, 0x0804, 0x8030, 0xa883, - 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, - 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, - 0x0002, 0x601b, 0x0014, 0x080c, 0xe586, 0x012e, 0x00ee, 0x00be, - 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, - 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, - 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, - 0x7012, 0x012e, 0x0005, 0x080c, 0x108b, 0x0005, 0x00d6, 0x080c, - 0x8b2b, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, - 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, - 0x81e5, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, - 0x0278, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, - 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, - 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, - 0x81e5, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, - 0xb116, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, - 0x0035, 0x1138, 0x6028, 0xc0fd, 0x602a, 0x2001, 0x196b, 0x2004, - 0x0098, 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, - 0xa99c, 0x918c, 0x00ff, 0x080c, 0x268c, 0x1540, 0x00b6, 0x080c, - 0x67b4, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, - 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, - 0x0041, 0x080c, 0xb20a, 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, - 0x8000, 0x080c, 0x7012, 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, - 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x0005, 0xa87b, 0x0028, - 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x080c, 0xb16c, - 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, - 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x81d6, 0xa97c, 0x9188, - 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, - 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, - 0xb116, 0x1118, 0x080c, 0xb1dd, 0x05a8, 0x6212, 0xa874, 0x0002, - 0x81b4, 0x81b9, 0x81bc, 0x81c2, 0x2019, 0x0002, 0x080c, 0xe9f9, - 0x0060, 0x080c, 0xe984, 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, - 0xe9a3, 0x0018, 0xa980, 0x080c, 0xe984, 0x080c, 0xb16c, 0xa887, - 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x00be, - 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, - 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, - 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, - 0x81e7, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, 0x0d8e, - 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, - 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, - 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x1648, 0x00fe, 0x0005, - 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, - 0x781c, 0xd08c, 0x0904, 0x8268, 0x68c0, 0x90aa, 0x0005, 0x0a04, - 0x8890, 0x7d44, 0x7c40, 0xd59c, 0x190c, 0x0d85, 0x9584, 0x00f6, - 0x1508, 0x9484, 0x7000, 0x0138, 0x908a, 0x2000, 0x1258, 0x9584, - 0x0700, 0x8007, 0x04f0, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, - 0x0db0, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, - 0x9086, 0x8100, 0x11c0, 0x080c, 0xeeb1, 0x080c, 0x8777, 0x7817, - 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x87d3, 0x19c8, - 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x82b8, 0x080c, 0x2185, - 0x005e, 0x004e, 0x0020, 0x080c, 0xeeb1, 0x7817, 0x0140, 0x080c, - 0x779e, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, - 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000, 0x0489, - 0x0005, 0x0002, 0x8275, 0x8585, 0x8272, 0x8272, 0x8272, 0x8272, - 0x8272, 0x8272, 0x7817, 0x0140, 0x0005, 0x7000, 0x908c, 0xff00, - 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286, 0x2000, - 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x58aa, 0x0070, - 0x080c, 0x82d8, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x84bf, - 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x86a4, 0x7817, 0x0140, - 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, - 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, - 0x2518, 0x080c, 0x4ca1, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, - 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, - 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, - 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, - 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, - 0x080c, 0x4ca1, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, - 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, - 0x0120, 0x9096, 0x0023, 0x1904, 0x8490, 0x9186, 0x0023, 0x15c0, - 0x080c, 0x8742, 0x0904, 0x8490, 0x6120, 0x9186, 0x0001, 0x0150, - 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, - 0x1904, 0x8490, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, - 0x2009, 0x0015, 0x080c, 0xb20a, 0x0804, 0x8490, 0x908e, 0x0214, - 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xb20a, - 0x0804, 0x8490, 0x908e, 0x0100, 0x1904, 0x8490, 0x7034, 0x9005, - 0x1904, 0x8490, 0x2009, 0x0016, 0x080c, 0xb20a, 0x0804, 0x8490, - 0x9186, 0x0022, 0x1904, 0x8490, 0x7030, 0x908e, 0x0300, 0x1580, - 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, - 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, - 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26d5, 0x7932, - 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x268c, 0x695e, 0x703c, - 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee, - 0x7034, 0x9005, 0x1904, 0x8490, 0x2009, 0x0017, 0x0804, 0x8440, - 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x8490, 0x080c, - 0x779e, 0x0120, 0x2009, 0x001d, 0x0804, 0x8440, 0x68dc, 0xc0a5, - 0x68de, 0x2009, 0x0030, 0x0804, 0x8440, 0x908e, 0x0500, 0x1140, - 0x7034, 0x9005, 0x1904, 0x8490, 0x2009, 0x0018, 0x0804, 0x8440, - 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x8440, 0x908e, - 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x8440, 0x908e, 0x5200, - 0x1140, 0x7034, 0x9005, 0x1904, 0x8490, 0x2009, 0x001b, 0x0804, - 0x8440, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x8490, - 0x2009, 0x001c, 0x0804, 0x8440, 0x908e, 0x1300, 0x1120, 0x2009, - 0x0034, 0x0804, 0x8440, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, - 0x1904, 0x8490, 0x2009, 0x0024, 0x0804, 0x8440, 0x908c, 0xff00, - 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, - 0xd09c, 0x0904, 0x8440, 0x080c, 0xdd8d, 0x1904, 0x8490, 0x0804, - 0x843e, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, - 0x0804, 0x8440, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, - 0x8440, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d, - 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, - 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4ca1, 0x004e, - 0x8108, 0x0f04, 0x83f4, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, - 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, - 0x0804, 0x8440, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804, - 0x8440, 0x908e, 0x5400, 0x1138, 0x080c, 0x8840, 0x1904, 0x8490, - 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x8868, - 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e, - 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, - 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, - 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, - 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, - 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, - 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x268c, - 0x1904, 0x8493, 0x080c, 0x6749, 0x1904, 0x8493, 0xbe12, 0xbd16, - 0x001e, 0x0016, 0x080c, 0x779e, 0x01c0, 0x68dc, 0xd08c, 0x1148, - 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, - 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00, - 0x1120, 0x9584, 0x00ff, 0xb886, 0x0080, 0xb884, 0x9005, 0x1168, - 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506, - 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xb116, 0x01a8, - 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, - 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xb20a, - 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, - 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4ca1, 0x080c, 0xb1dd, - 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, - 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, - 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, - 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x961e, 0x08a0, 0x080c, - 0x88af, 0x1158, 0x080c, 0x344c, 0x1140, 0x7010, 0x9084, 0xff00, - 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, - 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, - 0x080c, 0x8742, 0x0904, 0x851d, 0x7124, 0x610a, 0x7030, 0x908e, - 0x0200, 0x1140, 0x7034, 0x9005, 0x15c0, 0x2009, 0x0015, 0x080c, - 0xb20a, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005, 0x1568, - 0x2009, 0x0016, 0x080c, 0xb20a, 0x0440, 0x9186, 0x0032, 0x1528, - 0x7030, 0x908e, 0x1400, 0x1508, 0x2009, 0x0038, 0x0016, 0x2011, - 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x268c, 0x11a8, 0x080c, - 0x6749, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xb116, 0x0168, 0x2b08, - 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, - 0x080c, 0xb20a, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, - 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, - 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, - 0x2009, 0x007f, 0x0804, 0x857f, 0x9596, 0xfffe, 0x1120, 0x2009, - 0x007e, 0x0804, 0x857f, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, - 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac, 0x0130, - 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, - 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, - 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, - 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, - 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, - 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x8554, - 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, - 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837, 0x200c, - 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, - 0x810f, 0x9184, 0x000f, 0x001a, 0x7817, 0x0140, 0x0005, 0x85a7, - 0x85a7, 0x85a7, 0x8754, 0x85a7, 0x85aa, 0x85cf, 0x8658, 0x85a7, - 0x85a7, 0x85a7, 0x85a7, 0x85a7, 0x85a7, 0x85a7, 0x85a7, 0x7817, - 0x0140, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, - 0x9c8c, 0x0003, 0x11c0, 0x9c8a, 0x1ddc, 0x02a8, 0x6868, 0x9c02, - 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, - 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, - 0x0046, 0x080c, 0xb20a, 0x7817, 0x0140, 0x00be, 0x0005, 0x00b6, - 0x00c6, 0x9484, 0x0fff, 0x0904, 0x8634, 0x7110, 0xd1bc, 0x1904, - 0x8634, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, - 0xff00, 0x15c8, 0x81ff, 0x15b8, 0x9080, 0x348e, 0x200d, 0x918c, - 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x8634, 0x9182, - 0x0801, 0x1a04, 0x8634, 0x9190, 0x1000, 0x2204, 0x905d, 0x05e0, - 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15b8, 0xba04, 0x9294, 0xff00, - 0x9286, 0x0600, 0x1190, 0x080c, 0xb116, 0x0598, 0x2b08, 0x7028, - 0x604e, 0x702c, 0x6052, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, - 0x7130, 0x615e, 0x080c, 0xe009, 0x00f8, 0x080c, 0x6c11, 0x1138, - 0xb807, 0x0606, 0x0c40, 0x190c, 0x8521, 0x11b0, 0x0880, 0x080c, - 0xb116, 0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, - 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, - 0x6003, 0x0001, 0x080c, 0x961e, 0x7817, 0x0140, 0x00ce, 0x00be, - 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, - 0x080c, 0x4ca1, 0x080c, 0xb1dd, 0x0d78, 0x2b08, 0x6112, 0x6023, - 0x0006, 0x7120, 0x610a, 0x7130, 0x615e, 0x6017, 0xf300, 0x6003, - 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9617, 0x08e0, - 0x00b6, 0x7110, 0xd1bc, 0x05d0, 0x7020, 0x2060, 0x9c84, 0x0003, - 0x15a8, 0x9c82, 0x1ddc, 0x0690, 0x6868, 0x9c02, 0x1678, 0x9484, - 0x0fff, 0x9082, 0x000c, 0x0650, 0x7008, 0x9084, 0x00ff, 0x6110, - 0x2158, 0xb910, 0x9106, 0x1510, 0x700c, 0xb914, 0x9106, 0x11f0, - 0x7124, 0x610a, 0x601c, 0xd0fc, 0x11c8, 0x2001, 0x0271, 0x2004, - 0x9005, 0x1180, 0x9484, 0x0fff, 0x9082, 0x000c, 0x0158, 0x0066, - 0x2031, 0x0100, 0xa001, 0xa001, 0x8631, 0x1de0, 0x006e, 0x601c, - 0xd0fc, 0x1120, 0x2009, 0x0045, 0x080c, 0xb20a, 0x7817, 0x0140, - 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, - 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x88af, 0x1180, 0x080c, - 0x344c, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, - 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, - 0x86be, 0x86bf, 0x86be, 0x86be, 0x8724, 0x8733, 0x0005, 0x00b6, - 0x700c, 0x7108, 0x080c, 0x268c, 0x1904, 0x8722, 0x080c, 0x6749, - 0x1904, 0x8722, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, - 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x8722, 0x080c, 0x6c11, - 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6c19, 0x0118, 0x9086, - 0x0004, 0x1588, 0x00c6, 0x080c, 0x8742, 0x00ce, 0x05d8, 0x080c, - 0xb116, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0002, - 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb20a, 0x0458, 0x080c, - 0x6c11, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6c19, 0x0118, - 0x9086, 0x0004, 0x1180, 0x080c, 0xb116, 0x2b08, 0x01d8, 0x6112, - 0x080c, 0xd3b6, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, - 0x080c, 0xb20a, 0x0078, 0x080c, 0xb116, 0x2b08, 0x0158, 0x6112, - 0x080c, 0xd3b6, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, - 0x080c, 0xb20a, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, - 0x0148, 0x080c, 0x869a, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, - 0x080c, 0xb20a, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, - 0x080c, 0x869a, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, - 0xb20a, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0003, 0x1158, 0x9c82, - 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218, 0x9085, - 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, - 0x7024, 0x2060, 0x9c84, 0x0003, 0x11b0, 0x9c82, 0x1ddc, 0x0298, - 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, - 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, - 0x0051, 0x080c, 0xb20a, 0x7817, 0x0140, 0x00be, 0x0005, 0x2031, - 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, - 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, - 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05c0, - 0x080c, 0xb116, 0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, - 0x2204, 0x8211, 0x220c, 0x080c, 0x268c, 0x1590, 0x080c, 0x6749, - 0x1578, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, - 0xd3b6, 0x080c, 0x1059, 0x0500, 0x2900, 0x6062, 0x9006, 0xa802, - 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, - 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, - 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x961e, - 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xb16c, 0x006e, 0x0cc0, - 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, - 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x882a, 0x9186, 0x0022, - 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x882c, 0x7030, - 0x908e, 0x0400, 0x0904, 0x882c, 0x908e, 0x6000, 0x05e8, 0x908e, - 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837, 0x210c, - 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6bcf, 0x0588, 0x68b0, - 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x6880, - 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, - 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, - 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, - 0x0023, 0x1140, 0x080c, 0x8742, 0x0128, 0x6004, 0x9086, 0x0002, - 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, - 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, - 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, - 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, - 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, - 0x027a, 0x080c, 0xc20e, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, - 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xc20e, 0x1120, 0xd494, - 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, - 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, - 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, - 0x0272, 0x080c, 0xc20e, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, - 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xc20e, 0x1120, 0xd494, - 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, - 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, - 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, - 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, - 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, - 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, - 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x1a04, - 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, - 0x7017, 0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0xa2c0, 0x7032, - 0x7037, 0xa33d, 0x7047, 0xffff, 0x704a, 0x704f, 0x56c4, 0x7052, - 0x7063, 0x8a66, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900, 0x7042, - 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, - 0x1a04, 0x1d04, 0x8982, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, - 0x1590, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x8b10, 0x2001, - 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, - 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d85, 0x700f, - 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x2069, 0x1800, - 0x69ec, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x8ad4, 0x0010, - 0x080c, 0x8aab, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, - 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, - 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, - 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, - 0x7028, 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, - 0x1160, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, - 0x090c, 0xa3eb, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, - 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, - 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, - 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, - 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, - 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, - 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, - 0x080f, 0x012e, 0x7004, 0x0002, 0x89aa, 0x89ab, 0x89d5, 0x00e6, - 0x2071, 0x1a04, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, - 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1a04, 0x701c, - 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, - 0x0005, 0x00e6, 0x2071, 0x1a04, 0xb888, 0x9102, 0x0208, 0xb98a, - 0x00ee, 0x0005, 0x0005, 0x00b6, 0x2031, 0x0010, 0x7110, 0x080c, - 0x67b4, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180, 0x0126, - 0x2091, 0x8000, 0x0066, 0xb8d0, 0x9005, 0x0138, 0x0026, 0xba3c, - 0x0016, 0x080c, 0x68df, 0x001e, 0x002e, 0x006e, 0x012e, 0x8108, - 0x9182, 0x0800, 0x1220, 0x8631, 0x0128, 0x7112, 0x0c00, 0x900e, - 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x2031, 0x0010, 0x7014, - 0x2060, 0x0126, 0x2091, 0x8000, 0x6048, 0x9005, 0x0128, 0x8001, - 0x604a, 0x1110, 0x080c, 0xd237, 0x6018, 0x9005, 0x0904, 0x8a2d, - 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x8a40, 0x781b, - 0x2020, 0xa001, 0x7918, 0xd1b4, 0x0120, 0x781b, 0x2000, 0x0804, - 0x8a40, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001, 0x7918, - 0xd1ac, 0x1dd0, 0x010e, 0x00fe, 0x1540, 0x6120, 0x9186, 0x0003, - 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, 0x0009, 0x11e0, 0x611c, - 0xd1c4, 0x1100, 0x080c, 0xcf1b, 0x01b0, 0x6014, 0x2048, 0xa884, - 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, - 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, - 0x080c, 0xd671, 0x0110, 0x080c, 0xcbd9, 0x012e, 0x9c88, 0x001c, - 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, 0x1228, 0x8631, 0x0138, - 0x2160, 0x0804, 0x89d9, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x0005, - 0x00fe, 0x0c58, 0x00e6, 0x2071, 0x1a04, 0x7027, 0x07d0, 0x7023, - 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a0d, 0x2003, 0x0000, 0x0005, - 0x00e6, 0x2071, 0x1a04, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, - 0x2011, 0x1a10, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1a04, - 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, - 0x705c, 0x8000, 0x705e, 0x2001, 0x1a14, 0x2044, 0xa06c, 0x9086, - 0x0000, 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, - 0x7064, 0xa08e, 0x080c, 0x114e, 0x002e, 0x008e, 0x0005, 0x0006, - 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, - 0x0156, 0x080c, 0x88e7, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, - 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, - 0x1a04, 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, - 0x0006, 0x2071, 0x1a04, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, - 0x000e, 0x00ee, 0x0005, 0x2069, 0x1800, 0x69ec, 0xd1e4, 0x1518, - 0x0026, 0xd1ec, 0x0140, 0x6a54, 0x6874, 0x9202, 0x0288, 0x8117, - 0x9294, 0x00c1, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, - 0x0007, 0x0110, 0x69ee, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, - 0x8107, 0x9106, 0x9094, 0x00c1, 0x9184, 0xff3e, 0x9205, 0x68ee, - 0x080c, 0x0f24, 0x002e, 0x0005, 0x69e8, 0x9184, 0x003f, 0x05b8, - 0x8109, 0x9184, 0x003f, 0x01a8, 0x6a54, 0x6874, 0x9202, 0x0220, - 0xd1bc, 0x0168, 0xc1bc, 0x0018, 0xd1bc, 0x1148, 0xc1bd, 0x2110, - 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x0400, 0x69ea, - 0x00f0, 0x0026, 0x8107, 0x9094, 0x0007, 0x0128, 0x8001, 0x8007, - 0x9085, 0x0007, 0x0050, 0x2010, 0x8004, 0x8004, 0x8004, 0x9084, - 0x0007, 0x9205, 0x8007, 0x9085, 0x0028, 0x9086, 0x0040, 0x2010, - 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x002e, 0x0005, - 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100, 0x60f0, - 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220, 0x8108, - 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x2061, - 0x1a73, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003, 0x8003, 0x8003, - 0x9080, 0x1a73, 0x2060, 0x0005, 0xa884, 0x908a, 0x199a, 0x1638, - 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a73, 0x6014, 0x00ce, 0x9005, - 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, - 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, - 0x00c0, 0x0904, 0x8bee, 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x8bc7, - 0x2009, 0x0006, 0x080c, 0x8c1b, 0x0005, 0x900e, 0x0c60, 0x2001, - 0x1999, 0x08b0, 0xd0fc, 0x05e0, 0x908c, 0x2023, 0x1568, 0x87ff, - 0x1558, 0xa9a8, 0x81ff, 0x1540, 0x6124, 0x918c, 0x0500, 0x1520, - 0x6100, 0x918e, 0x0007, 0x1500, 0x2009, 0x1869, 0x210c, 0xd184, - 0x11d8, 0x6003, 0x0003, 0x6007, 0x0043, 0x6047, 0xb035, 0x080c, - 0x1c6f, 0xa87c, 0xc0dd, 0xa87e, 0x600f, 0x0000, 0x00f6, 0x2079, - 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0013, 0x2c00, 0x7836, - 0x781b, 0x8080, 0x00fe, 0x0005, 0x908c, 0x0003, 0x0120, 0x918e, - 0x0003, 0x1904, 0x8c15, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, - 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, 0x1138, - 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xb20a, 0x0005, 0x87ff, - 0x1de8, 0x2009, 0x0042, 0x0804, 0xb20a, 0x6110, 0x00b6, 0x2158, - 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, - 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, - 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8c15, - 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, - 0x080c, 0x17ad, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, - 0x080c, 0xb20a, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, - 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, - 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, - 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, 0xb20a, - 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, - 0xb20a, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, - 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, - 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xcf1b, 0x0518, 0x6014, - 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, - 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a73, - 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, - 0x080c, 0x6e4c, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, - 0x8b34, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a73, - 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, - 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, - 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1924, 0x7003, - 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, 0x080c, - 0x1072, 0x090c, 0x0d85, 0xa867, 0x0006, 0xa86b, 0x0001, 0xa8ab, - 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000, 0x0005, - 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1924, 0x702c, - 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, 0xa896, - 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c, 0x701a, 0x2009, - 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188, 0x000c, 0x8001, - 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92, 0x7010, - 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000, 0x0006, - 0x2009, 0x1b73, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e, 0xc095, - 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16b9, 0x9006, 0x2071, - 0x193d, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e, 0x0005, - 0x2009, 0x1b73, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005, 0x00e6, - 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154, 0x2001, - 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006, 0x9080, - 0x0008, 0x1f04, 0x8cd7, 0x71c0, 0x9102, 0x02e0, 0x2071, 0x1877, - 0x20a9, 0x0007, 0x00c6, 0x080c, 0xb116, 0x6023, 0x0009, 0x6003, - 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000, 0x080c, - 0x8e58, 0x012e, 0x1f04, 0x8ce3, 0x9006, 0x00ce, 0x015e, 0x012e, - 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6, 0x0096, - 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620, 0x7004, - 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, 0x2021, - 0x002c, 0x2029, 0x000a, 0x080c, 0x1059, 0x090c, 0x0d85, 0x2900, - 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a, 0xa87a, - 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a, 0x7010, - 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109, 0x0160, - 0x080c, 0x1059, 0x090c, 0x0d85, 0xad66, 0x2b00, 0xa802, 0x2900, - 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e, 0x008e, - 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071, 0x1924, - 0x7004, 0x004b, 0x700c, 0x0002, 0x8d4f, 0x8d48, 0x8d48, 0x0005, - 0x8d59, 0x8daf, 0x8daf, 0x8daf, 0x8db0, 0x8dc1, 0x8dc1, 0x700c, - 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106, 0x1904, - 0x8da1, 0x7814, 0xd0bc, 0x1904, 0x8daa, 0x012e, 0x7018, 0x910a, - 0x1128, 0x7030, 0x9005, 0x1904, 0x8df3, 0x0005, 0x1210, 0x7114, - 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001, 0x1888, - 0x2014, 0x2001, 0x1936, 0x2004, 0x9100, 0x9202, 0x0e50, 0x080c, - 0x8f53, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c, 0x2048, - 0xa873, 0x0001, 0xa976, 0x080c, 0x905c, 0x2100, 0xa87e, 0xa86f, - 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a24, 0x2104, - 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x116d, 0x1de8, - 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8d61, 0x080c, 0x8f2b, - 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8d61, 0x0005, - 0x700c, 0x0002, 0x8db5, 0x8db8, 0x8db7, 0x080c, 0x8d57, 0x0005, - 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e, 0x0011, - 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100, 0x7214, - 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006, 0x0068, - 0x0006, 0x080c, 0x905c, 0x2100, 0xaa8c, 0x9210, 0xaa8e, 0x1220, - 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126, 0x2091, - 0x8000, 0x78a2, 0x701a, 0x080c, 0x8f2b, 0x012e, 0x0005, 0x00e6, - 0x2071, 0x1924, 0x700c, 0x0002, 0x8df1, 0x8df1, 0x8def, 0x700f, - 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030, 0x9005, - 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059, 0x0000, - 0x080c, 0x8e61, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193d, 0x080c, - 0x8ea8, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1072, 0x2900, 0x009e, - 0x0148, 0xa8aa, 0x04d1, 0x0041, 0x2001, 0x1947, 0x2003, 0x0000, - 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086, 0x00a6, - 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084, 0x000f, - 0x2068, 0x9d88, 0x1ec1, 0x2165, 0x0056, 0x2029, 0x0000, 0x080c, - 0x8fe1, 0x080c, 0x1e97, 0x1dd8, 0x005e, 0x00ae, 0x2001, 0x187f, - 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x17ad, 0x00ce, 0x781f, - 0x0101, 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x8eb7, - 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, - 0x2078, 0x780c, 0x7032, 0x2001, 0x1947, 0x2003, 0x0001, 0x0005, - 0x00e6, 0x2071, 0x1924, 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, - 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x912a, 0x2005, 0x906d, - 0x090c, 0x0d85, 0x9b80, 0x9122, 0x2005, 0x9065, 0x090c, 0x0d85, - 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, - 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, - 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, - 0x4ca1, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d85, 0xa804, 0x8000, - 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, - 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4ca1, 0x684c, 0x0096, - 0x904d, 0x090c, 0x0d85, 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, - 0x7000, 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, - 0x9005, 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, 0x00d6, - 0x7814, 0x9005, 0x090c, 0x0d85, 0x781c, 0x9084, 0x0101, 0x9086, - 0x0101, 0x190c, 0x0d85, 0x7827, 0x0000, 0x2069, 0x193d, 0x6804, - 0x9080, 0x193f, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, - 0x0208, 0x900e, 0x6906, 0x9180, 0x193f, 0x2003, 0x0000, 0x00de, - 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, - 0x2048, 0x9005, 0x190c, 0x108b, 0x009e, 0xa8ab, 0x0000, 0x080c, - 0x100b, 0x080c, 0xb16c, 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, - 0x0009, 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, - 0x0001, 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, 0x9005, - 0x0150, 0x00b6, 0x2058, 0x080c, 0x925e, 0x00be, 0x6013, 0x0000, - 0x601b, 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, 0x1928, - 0x210c, 0xd194, 0x0005, 0x2009, 0x1928, 0x210c, 0xd1c4, 0x0005, - 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1924, 0x7110, 0xc194, - 0xc185, 0x7007, 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, 0x16b9, - 0x00ee, 0x012e, 0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, 0x7810, - 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, 0x700e, - 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000, - 0x080c, 0x90aa, 0x0170, 0x080c, 0x90df, 0x0158, 0x2900, 0x7002, - 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a, 0x00de, 0x009e, - 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, 0x00c6, - 0x2071, 0x1931, 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x90df, - 0x090c, 0x0d85, 0x7018, 0x9005, 0x1160, 0x2900, 0x7002, 0x700a, - 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802, 0x7012, 0x701e, - 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a, 0xa803, 0x0000, - 0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a, 0x701e, 0x721c, - 0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, 0x0005, - 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000, - 0x2071, 0x1931, 0x7300, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, - 0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x905c, - 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021, 0x0078, 0x9402, - 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xa001, - 0xa001, 0x4005, 0x2508, 0x080c, 0x9065, 0x2130, 0x7014, 0x9600, - 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004, 0x9600, 0x2008, - 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800, 0x9005, 0x1148, - 0x2009, 0x0001, 0x0026, 0x080c, 0x8f53, 0x002e, 0x7000, 0x2048, - 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212, - 0x1904, 0x8f92, 0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, 0x009e, - 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580, - 0x9122, 0x2005, 0x9075, 0x090c, 0x0d85, 0x080c, 0x9037, 0x012e, - 0x9580, 0x911e, 0x2005, 0x9075, 0x090c, 0x0d85, 0x0156, 0x0136, - 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, - 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, 0xa95c, - 0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00, - 0x0002, 0x9021, 0x9021, 0x9023, 0x9021, 0x9023, 0x9021, 0x9021, - 0x9021, 0x9021, 0x9021, 0x9029, 0x9021, 0x9029, 0x9021, 0x9021, - 0x9021, 0x080c, 0x0d85, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003, - 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003, 0x01de, 0x014e, - 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, - 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, 0x9188, - 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198, 0x7008, 0x2048, - 0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x90ee, 0x009e, 0xa807, - 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000, - 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b, 0x810b, 0x2100, - 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006, 0x0026, 0x2100, - 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e, 0x8108, 0x9082, - 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, 0x2d00, - 0x90b8, 0x0008, 0x2031, 0x90a8, 0x901e, 0x6808, 0x9005, 0x0108, - 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318, 0x6810, 0x9112, - 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, 0xd084, - 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003, 0x0967, 0x0a67, - 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, 0x0002, - 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, 0x0cd0, - 0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, - 0x9080, 0x9126, 0x2005, 0x9005, 0x090c, 0x0d85, 0x2004, 0x90a0, - 0x000a, 0x080c, 0x1072, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000, - 0xa807, 0x0000, 0x080c, 0x1072, 0x0188, 0x7024, 0xa802, 0xa807, - 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, 0x0c90, - 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005, 0x7024, 0x9005, - 0x0dc8, 0x2048, 0xac00, 0x080c, 0x108b, 0x2400, 0x0cc0, 0x0126, - 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130, 0xa800, 0x7026, - 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, - 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e, 0x0005, 0x0096, - 0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, - 0x080c, 0x108b, 0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, 0x7008, - 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x108b, 0x000e, - 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e, 0x701a, 0x701e, - 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005, 0x1a71, 0x0000, - 0x0000, 0x0000, 0x1931, 0x0000, 0x0000, 0x0000, 0x1888, 0x0000, - 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, 0x00c6, - 0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x924a, - 0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x921f, 0xb814, 0xa06e, - 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, 0xa834, - 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118, 0xa078, 0xc085, - 0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c, - 0x0d85, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, 0x908c, - 0x000f, 0x91e0, 0x1ec1, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, - 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x918a, - 0x918a, 0x918c, 0x918a, 0x918a, 0x918a, 0x918e, 0x918a, 0x918a, - 0x918a, 0x9190, 0x918a, 0x918a, 0x918a, 0x9192, 0x918a, 0x918a, - 0x918a, 0x9194, 0x918a, 0x918a, 0x918a, 0x9196, 0x918a, 0x918a, - 0x918a, 0x9198, 0x080c, 0x0d85, 0xa180, 0x04b8, 0xa190, 0x04a8, - 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, 0x0468, - 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, - 0x0002, 0x91bc, 0x91ba, 0x91ba, 0x91ba, 0x91ba, 0x91ba, 0x91be, - 0x91ba, 0x91ba, 0x91ba, 0x91ba, 0x91ba, 0x91c0, 0x91ba, 0x91ba, - 0x91ba, 0x91ba, 0x91ba, 0x91c2, 0x91ba, 0x91ba, 0x91ba, 0x91ba, - 0x91ba, 0x91c4, 0x080c, 0x0d85, 0xa180, 0x0038, 0xa198, 0x0028, - 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x91e0, - 0x91e2, 0x91e4, 0x91e6, 0x91e8, 0x91ea, 0x91ec, 0x91ee, 0x91f0, - 0x91f2, 0x91f4, 0x91f6, 0x91f8, 0x91fa, 0x91fc, 0x91fe, 0x9200, - 0x9202, 0x9204, 0x9206, 0x9208, 0x920a, 0x920c, 0x920e, 0x9210, - 0x080c, 0x0d85, 0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, 0x0448, - 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, 0x0408, - 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, 0x00c8, - 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, 0x0088, - 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, 0x0048, - 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, 0x0008, - 0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x1e97, 0x090c, 0x0d85, - 0x0804, 0x9164, 0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, 0xa86c, - 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x9146, - 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, 0x01b0, - 0x2001, 0x1925, 0x2004, 0x9005, 0x0188, 0x2001, 0x1800, 0x2004, - 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0004, - 0x2011, 0x8014, 0x080c, 0x4ca1, 0x004e, 0x003e, 0x00be, 0x001e, - 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a, 0xa936, 0x7008, - 0x9005, 0x0120, 0x8210, 0x910a, 0x0230, 0x0128, 0x7010, 0x8210, - 0x910a, 0x0208, 0x1de0, 0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, - 0x0036, 0x2079, 0x0300, 0x781b, 0x0200, 0x7818, 0xd094, 0x1dd8, - 0x781b, 0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, - 0x906d, 0x0198, 0x2079, 0x0000, 0x9c1e, 0x1118, 0x680c, 0xb8ae, - 0x0050, 0x9c06, 0x0130, 0x2d78, 0x680c, 0x906d, 0x1dd0, 0x080c, - 0x0d85, 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, 0x781b, - 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, 0x0096, - 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, 0x01ff, - 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, 0x1f04, - 0x929a, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, 0x1d90, - 0xb8ac, 0x9065, 0x01f0, 0x600c, 0xb8ae, 0x6024, 0xc08d, 0x6026, - 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, 0x0101, - 0x6014, 0x904d, 0x090c, 0x0d85, 0xa88b, 0x0000, 0xa8a8, 0xa8ab, - 0x0000, 0x904d, 0x090c, 0x0d85, 0x080c, 0x108b, 0x080c, 0x8e58, - 0x08f8, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e, - 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016, - 0x0006, 0x0156, 0x080c, 0x268c, 0x015e, 0x11b0, 0x080c, 0x6749, - 0x190c, 0x0d85, 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xb116, - 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c, - 0xb20a, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066, - 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, - 0x9310, 0x9310, 0x9310, 0x9312, 0x935b, 0x9310, 0x9310, 0x9310, - 0x93d5, 0x9310, 0x940d, 0x9310, 0x9310, 0x9310, 0x9310, 0x9310, - 0x080c, 0x0d85, 0x9182, 0x0040, 0x0002, 0x9325, 0x9325, 0x9325, - 0x9325, 0x9325, 0x9325, 0x9325, 0x9325, 0x9325, 0x9327, 0x9338, - 0x9325, 0x9325, 0x9325, 0x9325, 0x9349, 0x080c, 0x0d85, 0x0096, - 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, - 0x0500, 0x00be, 0x080c, 0x6e11, 0x080c, 0xb16c, 0x009e, 0x0005, - 0x080c, 0x9a48, 0x00d6, 0x6114, 0x080c, 0xcf1b, 0x0130, 0x0096, - 0x6114, 0x2148, 0x080c, 0x7012, 0x009e, 0x00de, 0x080c, 0xb16c, - 0x0005, 0x080c, 0x9a48, 0x080c, 0x3315, 0x6114, 0x0096, 0x2148, - 0x080c, 0xcf1b, 0x0120, 0xa87b, 0x0029, 0x080c, 0x7012, 0x009e, - 0x080c, 0xb16c, 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096, - 0x0002, 0x9376, 0x9376, 0x9376, 0x9376, 0x9376, 0x9376, 0x9376, - 0x9376, 0x9378, 0x9376, 0x9376, 0x9376, 0x93d1, 0x9376, 0x9376, - 0x9376, 0x9376, 0x9376, 0x9376, 0x937f, 0x9376, 0x080c, 0x0d85, - 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, 0x93d1, 0x6024, - 0xd08c, 0x15d8, 0x080c, 0x8f0e, 0x05e0, 0x00e6, 0x6114, 0x2148, - 0x080c, 0x912e, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6da9, 0x009e, - 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, - 0x925e, 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8e61, - 0x00be, 0x01e0, 0x2071, 0x193d, 0x080c, 0x8ea8, 0x01b8, 0x9086, - 0x0001, 0x1128, 0x2001, 0x1947, 0x2004, 0x9005, 0x1178, 0x0096, - 0x080c, 0x1059, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, - 0x080c, 0x8e1c, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8e58, - 0x0cd0, 0x080c, 0x8f13, 0x1160, 0x6010, 0x9005, 0x0130, 0x2058, - 0xb8ac, 0x9005, 0x190c, 0x0d85, 0x6012, 0x2c00, 0x080c, 0x8ed9, - 0x0005, 0x080c, 0x9489, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, - 0x0002, 0x93e9, 0x93e9, 0x93e9, 0x93eb, 0x93e9, 0x93e9, 0x93e9, - 0x940b, 0x93e9, 0x93e9, 0x93e9, 0x93e9, 0x93e9, 0x93e9, 0x93e9, - 0x93e9, 0x080c, 0x0d85, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, - 0xa8ac, 0xa836, 0xa8b0, 0xa83a, 0xa847, 0x0000, 0xa84b, 0x0000, - 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, - 0x8213, 0x9210, 0x621a, 0x080c, 0x1c26, 0x2009, 0x8030, 0x080c, - 0x965e, 0x009e, 0x0005, 0x080c, 0x0d85, 0x080c, 0x9a48, 0x6114, - 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, - 0x00be, 0x080c, 0x7012, 0x080c, 0xb16c, 0x009e, 0x0005, 0x080c, - 0xacfc, 0x6144, 0xd1fc, 0x0120, 0xd1ac, 0x1110, 0x6003, 0x0003, - 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d85, 0x0096, 0x0023, 0x009e, - 0x080c, 0xad18, 0x0005, 0x9443, 0x9443, 0x9443, 0x9445, 0x9456, - 0x9443, 0x9443, 0x9443, 0x9443, 0x9443, 0x9443, 0x9443, 0x9443, - 0x9443, 0x9443, 0x9443, 0x080c, 0x0d85, 0x080c, 0xaee3, 0x6114, - 0x2148, 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, - 0x00be, 0x080c, 0x7012, 0x080c, 0xb16c, 0x0005, 0x0491, 0x0005, - 0x080c, 0xacfc, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, - 0x6003, 0x0003, 0x2009, 0x0003, 0x908a, 0x0010, 0x1a0c, 0x0d85, - 0x0096, 0x0033, 0x009e, 0x0106, 0x080c, 0xad18, 0x010e, 0x0005, - 0x9480, 0x9480, 0x9480, 0x9482, 0x9489, 0x9480, 0x9480, 0x9480, - 0x9480, 0x9480, 0x9480, 0x9480, 0x9480, 0x9480, 0x9480, 0x9480, - 0x080c, 0x0d85, 0x0036, 0x00e6, 0x080c, 0xaee3, 0x00ee, 0x003e, - 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, - 0x6014, 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, - 0x925e, 0x00be, 0x2071, 0x193d, 0x080c, 0x8ea8, 0x0160, 0x2001, - 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8e1c, - 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, - 0x080c, 0x108b, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8e58, 0x0c80, - 0x2001, 0x1925, 0x200c, 0x918e, 0x0000, 0x190c, 0x8f0e, 0x05c8, - 0x00e6, 0x2071, 0x1924, 0x7110, 0xc1c5, 0x7112, 0x080c, 0x8f18, - 0x00f6, 0x00c6, 0x2071, 0x1000, 0x00b6, 0x2e04, 0x905d, 0x0138, - 0xb8ac, 0x9065, 0x0120, 0x080c, 0x8eee, 0x090c, 0x928d, 0x8e70, - 0x9e86, 0x1800, 0x1d90, 0x00be, 0x00d6, 0x0096, 0x0046, 0x2061, - 0x1ddc, 0x2001, 0x181a, 0x2024, 0x6020, 0x9086, 0x0000, 0x1191, - 0x9ce0, 0x001c, 0x2400, 0x9c06, 0x1db8, 0x004e, 0x009e, 0x00de, - 0x00d1, 0x00ce, 0x00fe, 0x2071, 0x1924, 0x7110, 0xc1c4, 0x7112, - 0x00ee, 0x0005, 0x6020, 0x9086, 0x0009, 0x1160, 0x6100, 0x9186, - 0x0004, 0x1138, 0x6110, 0x81ff, 0x190c, 0x0d85, 0x2c00, 0x080c, - 0x8ed9, 0x9006, 0x0005, 0x2071, 0x193f, 0x2073, 0x0000, 0x8e70, - 0x9e86, 0x1947, 0x1dd0, 0x2071, 0x193d, 0x7006, 0x7002, 0x2001, - 0x1930, 0x2064, 0x8cff, 0x0130, 0x6120, 0x918e, 0x0000, 0x190c, - 0x0d85, 0x2102, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0148, 0x0096, - 0x2148, 0x080c, 0x108b, 0x009e, 0x2001, 0x188a, 0x2003, 0x0000, - 0x2071, 0x1931, 0x080c, 0x90f7, 0x0804, 0x9106, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x187a, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126, 0x2091, - 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004, 0x8086, - 0x818e, 0x1208, 0x9200, 0x1f04, 0x954f, 0x8086, 0x818e, 0x004e, - 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156, - 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a, 0x12b8, 0x8213, 0x818d, - 0x0228, 0x911a, 0x1220, 0x1f04, 0x9566, 0x0028, 0x911a, 0x2308, - 0x8210, 0x1f04, 0x9566, 0x0006, 0x3200, 0x9084, 0xefff, 0x2080, - 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200, 0x9085, - 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e8, 0x012e, - 0x00d6, 0x2069, 0x19e8, 0x6803, 0x0005, 0x0156, 0x0146, 0x01d6, - 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xaaf1, 0x04c9, 0x080c, - 0xaadc, 0x04b1, 0x080c, 0xaadf, 0x0499, 0x080c, 0xaae2, 0x0481, - 0x080c, 0xaae5, 0x0469, 0x080c, 0xaae8, 0x0451, 0x080c, 0xaaeb, - 0x0439, 0x080c, 0xaaee, 0x0421, 0x01de, 0x014e, 0x015e, 0x6857, - 0x0000, 0x00f6, 0x2079, 0x0380, 0x0419, 0x7807, 0x0003, 0x7803, - 0x0000, 0x7803, 0x0001, 0x2069, 0x0004, 0x2d04, 0x9084, 0xfffe, - 0x9085, 0x8000, 0x206a, 0x2069, 0x0100, 0x6828, 0x9084, 0xfffc, - 0x682a, 0x00fe, 0x2001, 0x1b5d, 0x2003, 0x0000, 0x00de, 0x0005, - 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005, - 0x00c6, 0x7803, 0x0000, 0x9006, 0x7827, 0x0030, 0x782b, 0x0400, - 0x7827, 0x0031, 0x782b, 0x1af6, 0x781f, 0xff00, 0x781b, 0xff00, - 0x2061, 0x1aeb, 0x602f, 0x19e8, 0x6033, 0x1800, 0x6037, 0x1a04, - 0x603b, 0x1ec1, 0x603f, 0x1ed1, 0x6042, 0x6047, 0x1ac1, 0x00ce, - 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, - 0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e8, - 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080, 0x0003, - 0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e, 0x0cd8, 0x6146, - 0x2c08, 0x2001, 0x0012, 0x080c, 0xaced, 0x0005, 0x0016, 0x2009, - 0x8020, 0x6146, 0x2c08, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, - 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xaced, 0x0088, - 0x00c6, 0x2061, 0x19e8, 0x602c, 0x8000, 0x602e, 0x600c, 0x9005, - 0x0128, 0x9080, 0x0003, 0x2102, 0x610e, 0x0010, 0x6112, 0x610e, - 0x00ce, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, - 0x9086, 0x0001, 0x0198, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, - 0x2061, 0x19e8, 0x6044, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, - 0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8, 0x6146, 0x600f, - 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xaced, 0x0005, 0x6044, - 0xd0dc, 0x0110, 0x080c, 0xa78a, 0x0005, 0x00f6, 0x00e6, 0x00d6, - 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, - 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e8, 0x7648, 0x2660, - 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x96f1, 0x9c86, 0x1b55, - 0x0904, 0x96ec, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x96ec, - 0x87ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x96ec, 0x704c, 0x9c06, - 0x1188, 0x0036, 0x2019, 0x0001, 0x080c, 0xa596, 0x703f, 0x0000, - 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xaff4, 0x003e, - 0x2029, 0x0001, 0x080c, 0x9667, 0x7048, 0x9c36, 0x1110, 0x660c, - 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, - 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, - 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xcf1b, - 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588, 0x6004, - 0x9086, 0x0040, 0x090c, 0xa78a, 0xa867, 0x0103, 0xab7a, 0xa877, - 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xd220, 0x080c, 0xeddf, - 0x080c, 0x7012, 0x007e, 0x003e, 0x001e, 0x080c, 0xd10c, 0x080c, - 0xb1a7, 0x00ce, 0x0804, 0x9683, 0x2c78, 0x600c, 0x2060, 0x0804, - 0x9683, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e, - 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, - 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, - 0xeddf, 0x080c, 0xea30, 0x007e, 0x003e, 0x001e, 0x08c0, 0x6020, - 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, 0x0076, - 0x080c, 0x7012, 0x080c, 0xb16c, 0x007e, 0x003e, 0x001e, 0x0848, - 0x6020, 0x9086, 0x000a, 0x0904, 0x96d6, 0x0804, 0x96cf, 0x0006, - 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, - 0x8000, 0x2079, 0x19e8, 0x7848, 0x9065, 0x0904, 0x9790, 0x600c, - 0x0006, 0x600f, 0x0000, 0x784c, 0x9c06, 0x11b0, 0x0036, 0x2019, - 0x0001, 0x080c, 0xa596, 0x783f, 0x0000, 0x901e, 0x7b4e, 0x7b6a, - 0x7b52, 0x7b6e, 0x080c, 0xaff4, 0x003e, 0x000e, 0x9005, 0x1118, - 0x600c, 0x600f, 0x0000, 0x0006, 0x9c86, 0x1b55, 0x05b0, 0x00e6, - 0x2f70, 0x080c, 0x9667, 0x00ee, 0x080c, 0xcf1b, 0x0548, 0x6014, - 0x2048, 0x6020, 0x9086, 0x0003, 0x15a8, 0x3e08, 0x918e, 0x0002, - 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x0140, 0x6048, 0x9005, 0x11c0, 0x2001, 0x1988, 0x2004, - 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c, 0xa78a, 0xa867, - 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x7006, 0x080c, 0xd10c, - 0x6044, 0xc0fc, 0x6046, 0x080c, 0xb1a7, 0x000e, 0x0804, 0x9734, - 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, - 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xea30, - 0x0c38, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, 0x7012, - 0x080c, 0xb16c, 0x0c10, 0x6020, 0x9086, 0x000a, 0x0990, 0x0850, - 0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x98a3, 0x008e, - 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e8, 0x2091, - 0x8000, 0x080c, 0x98ec, 0x080c, 0x9982, 0x080c, 0x6948, 0x012e, - 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, - 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, - 0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9868, 0x6010, 0x2058, - 0xb8a0, 0x9206, 0x1904, 0x9863, 0x88ff, 0x0120, 0x605c, 0x9106, - 0x1904, 0x9863, 0x7030, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, - 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8a4b, 0x080c, 0xa2a0, - 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7033, 0x0000, 0x0036, 0x2069, - 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, - 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, 0x0100, 0x6824, 0xd084, - 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x7008, 0xc0ad, 0x700a, - 0x6003, 0x0009, 0x630a, 0x0804, 0x9863, 0x7020, 0x9c36, 0x1110, - 0x660c, 0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, - 0x2f00, 0x701e, 0x0010, 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, - 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6044, - 0xc0fc, 0x6046, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x01e8, 0x6020, - 0x9086, 0x0003, 0x1580, 0x080c, 0xd132, 0x1118, 0x080c, 0xbb5c, - 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, - 0x0086, 0x080c, 0xd220, 0x080c, 0xeddf, 0x080c, 0x7012, 0x008e, - 0x003e, 0x001e, 0x080c, 0xd10c, 0x080c, 0xb1a7, 0x080c, 0xa65d, - 0x00ce, 0x0804, 0x97db, 0x2c78, 0x600c, 0x2060, 0x0804, 0x97db, - 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, - 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, - 0x0036, 0x0086, 0x080c, 0xeddf, 0x080c, 0xea30, 0x008e, 0x003e, - 0x001e, 0x08d0, 0x080c, 0xbb5c, 0x6020, 0x9086, 0x0002, 0x1160, - 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x9849, 0x9086, - 0x008b, 0x0904, 0x9849, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920, - 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, 0x008b, - 0x09b0, 0x0804, 0x985c, 0x0006, 0x00f6, 0x00e6, 0x0096, 0x00b6, - 0x00c6, 0x0066, 0x0016, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, - 0x2004, 0x905d, 0x2079, 0x19e8, 0x9036, 0x7828, 0x2060, 0x8cff, - 0x0538, 0x6010, 0x9b06, 0x1500, 0x6043, 0xffff, 0x080c, 0xaf2e, - 0x01d8, 0x610c, 0x0016, 0x080c, 0xa420, 0x6014, 0x2048, 0xa867, - 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, - 0xd220, 0x080c, 0xeddf, 0x080c, 0x7012, 0x008e, 0x003e, 0x001e, - 0x080c, 0xb1a7, 0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060, 0x08b8, - 0x080c, 0x6965, 0x012e, 0x001e, 0x006e, 0x00ce, 0x00be, 0x009e, - 0x00ee, 0x00fe, 0x000e, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, - 0x00d6, 0x9036, 0x7820, 0x9065, 0x0904, 0x9955, 0x600c, 0x0006, - 0x6044, 0xc0fc, 0x6046, 0x600f, 0x0000, 0x7830, 0x9c06, 0x1598, - 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, - 0x8a4b, 0x080c, 0xa2a0, 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7833, - 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, - 0x2001, 0x0100, 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, - 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0058, - 0x080c, 0x6ba9, 0x1538, 0x6003, 0x0009, 0x630a, 0x7808, 0xc0ad, - 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcf19, 0x01b0, - 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xd132, 0x1118, 0x080c, - 0xbb5c, 0x0060, 0x080c, 0x6ba9, 0x1168, 0xa867, 0x0103, 0xab7a, - 0xa877, 0x0000, 0x080c, 0x7012, 0x080c, 0xd10c, 0x080c, 0xb1a7, - 0x080c, 0xa65d, 0x000e, 0x0804, 0x98f3, 0x7e22, 0x7e1e, 0x00de, - 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, - 0x1118, 0x080c, 0xea30, 0x0c50, 0x080c, 0xbb5c, 0x6020, 0x9086, - 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0990, - 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005, 0x19b0, - 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086, 0x008b, - 0x0d00, 0x0860, 0x0006, 0x0096, 0x00b6, 0x00c6, 0x0066, 0x9036, - 0x7828, 0x9065, 0x0510, 0x6010, 0x2058, 0x600c, 0x0006, 0x3e08, - 0x918e, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x11a8, 0x6043, 0xffff, - 0x080c, 0xaf2e, 0x0180, 0x610c, 0x080c, 0xa420, 0x6014, 0x2048, - 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x7012, 0x080c, - 0xb1a7, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e, 0x00ce, 0x00be, - 0x009e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066, 0x080c, - 0x62af, 0x11b0, 0x2071, 0x19e8, 0x7030, 0x9080, 0x0005, 0x2004, - 0x904d, 0x0170, 0xa878, 0x9606, 0x1158, 0x2071, 0x19e8, 0x7030, - 0x9035, 0x0130, 0x9080, 0x0005, 0x2004, 0x9906, 0x1108, 0x0029, - 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x2660, 0x6043, - 0xffff, 0x080c, 0xaf2e, 0x0178, 0x080c, 0xa420, 0x6014, 0x2048, - 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd220, 0x080c, - 0x7012, 0x080c, 0xb1a7, 0x00ce, 0x0005, 0x00b6, 0x00e6, 0x00c6, - 0x080c, 0xacfc, 0x0106, 0x2071, 0x0101, 0x2e04, 0xc0c4, 0x2072, - 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xad18, 0x00ce, 0x00ee, - 0x00be, 0x0005, 0x2071, 0x19e8, 0x7030, 0x9005, 0x0da0, 0x9c06, - 0x190c, 0x0d85, 0x7036, 0x080c, 0x8a4b, 0x7004, 0x9084, 0x0007, - 0x0002, 0x9a1b, 0x9a1d, 0x9a24, 0x9a2e, 0x9a3c, 0x9a1b, 0x9a29, - 0x9a19, 0x080c, 0x0d85, 0x0428, 0x0005, 0x080c, 0xaf19, 0x7007, - 0x0000, 0x7033, 0x0000, 0x00e8, 0x0066, 0x9036, 0x080c, 0xa420, - 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098, 0x080c, 0xaf04, - 0x0140, 0x080c, 0xaf19, 0x0128, 0x0066, 0x9036, 0x080c, 0xa420, - 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xaf04, 0x080c, 0xa78a, - 0x0000, 0x010e, 0x090c, 0xad18, 0x00ce, 0x00ee, 0x00be, 0x0005, - 0x00d6, 0x00c6, 0x080c, 0xacfc, 0x0106, 0x6044, 0xd0fc, 0x1130, - 0x010e, 0x090c, 0xad18, 0x00ce, 0x00de, 0x0005, 0x2069, 0x19e8, - 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d85, 0x6852, 0x00e6, - 0x2d70, 0x080c, 0x9667, 0x00ee, 0x080c, 0x8a58, 0x0016, 0x2009, - 0x0040, 0x080c, 0x2220, 0x001e, 0x683c, 0x9084, 0x0003, 0x0002, - 0x9a76, 0x9a77, 0x9a96, 0x9a74, 0x080c, 0x0d85, 0x0490, 0x6868, - 0x9086, 0x0001, 0x0198, 0x600c, 0x9015, 0x0168, 0x6a4a, 0x600f, - 0x0000, 0x6044, 0x9084, 0x7f7f, 0x6046, 0x9006, 0x6842, 0x684e, - 0x683f, 0x0000, 0x00f0, 0x684a, 0x6846, 0x0c98, 0x686b, 0x0000, - 0x6848, 0x9065, 0x0d70, 0x6003, 0x0002, 0x0c58, 0x6044, 0x9084, - 0x7f7f, 0x6046, 0x9006, 0x6842, 0x684e, 0x686a, 0x6852, 0x686e, - 0x600c, 0x9015, 0x0120, 0x6a4a, 0x600f, 0x0000, 0x0010, 0x684a, - 0x6846, 0x080c, 0xaff4, 0x684f, 0x0000, 0x010e, 0x090c, 0xad18, - 0x00ce, 0x00de, 0x0005, 0x0005, 0x6020, 0x9084, 0x000f, 0x000b, - 0x0005, 0x9ac9, 0x9acc, 0x9f80, 0xa019, 0x9acc, 0x9f80, 0xa019, - 0x9ac9, 0x9acc, 0x9ac9, 0x9ac9, 0x9ac9, 0x9ac9, 0x9ac9, 0x9ac9, - 0x9ac9, 0x080c, 0x99ed, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, - 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, - 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d85, 0x6110, - 0x2158, 0xb984, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, - 0x1a04, 0x9b38, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, - 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9ce1, 0x9d1c, - 0x9d45, 0x9e0f, 0x9e31, 0x9e37, 0x9e44, 0x9e4c, 0x9e58, 0x9e5e, - 0x9e6f, 0x9e5e, 0x9ec7, 0x9e4c, 0x9ed3, 0x9ed9, 0x9e58, 0x9ed9, - 0x9ee5, 0x9b36, 0x9b36, 0x9b36, 0x9b36, 0x9b36, 0x9b36, 0x9b36, - 0x9b36, 0x9b36, 0x9b36, 0x9b36, 0xa441, 0xa464, 0xa475, 0xa495, - 0xa4c7, 0x9e44, 0x9b36, 0x9e44, 0x9e5e, 0x9b36, 0x9d45, 0x9e0f, - 0x9b36, 0xa888, 0x9e5e, 0x9b36, 0xa8a4, 0x9e5e, 0x9b36, 0x9e58, - 0x9cdb, 0x9b59, 0x9b36, 0xa8c0, 0xa92d, 0xaa11, 0x9b36, 0xaa1e, - 0x9e41, 0xaa49, 0x9b36, 0xa4d1, 0xaa55, 0x9b36, 0x080c, 0x0d85, - 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, - 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xaaf5, 0xaba7, 0x9b57, - 0x9b91, 0x9c3d, 0x9c48, 0x9b57, 0x9e44, 0x9b57, 0x9ca2, 0x9cae, - 0x9bac, 0x9b57, 0x9bc7, 0x9bfb, 0xb008, 0xb04d, 0x9e5e, 0x080c, - 0x0d85, 0x00d6, 0x0096, 0x080c, 0x9ef8, 0x0026, 0x0036, 0x7814, - 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, - 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, - 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, - 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0xa270, 0x003e, 0x002e, - 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, - 0x080c, 0xb094, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, - 0x0005, 0x00d6, 0x0096, 0x080c, 0x9ef8, 0x7003, 0x0500, 0x7814, - 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, - 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, - 0xa270, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9ef8, - 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, - 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, - 0x60c3, 0x0010, 0x080c, 0xa270, 0x009e, 0x00de, 0x0005, 0x00d6, - 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9ef8, 0x20e9, 0x0000, - 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, - 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, - 0x2098, 0x2001, 0x19a4, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, - 0x2205, 0x080c, 0xdcef, 0x9006, 0x080c, 0x2205, 0x001e, 0xa804, - 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa270, 0x012e, - 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, - 0x080c, 0x9f43, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000, - 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, - 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, - 0x2098, 0x2001, 0x19a4, 0x0016, 0x200c, 0x080c, 0xdcef, 0x001e, - 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, - 0x080c, 0x100b, 0x080c, 0xa270, 0x012e, 0x009e, 0x00de, 0x0005, - 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, - 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9ef8, 0x7003, - 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0xa270, - 0x00d6, 0x00e6, 0x080c, 0x9f43, 0x7814, 0x9084, 0xff00, 0x2073, - 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, - 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, - 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, - 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9c68, 0x2069, 0x1801, 0x20a9, - 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9c71, 0x9096, 0xdf00, - 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, - 0x19b4, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19ce, 0x20a9, 0x001a, - 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, - 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, - 0x8e70, 0x1f04, 0x9c88, 0x60c3, 0x004c, 0x080c, 0xa270, 0x00ee, - 0x00de, 0x0005, 0x080c, 0x9ef8, 0x7003, 0x6300, 0x7007, 0x0028, - 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x00d6, 0x0026, - 0x0016, 0x080c, 0x9f43, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, - 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, 0x1924, - 0x6810, 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, 0x0000, - 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, 0x2073, - 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa270, 0x001e, - 0x002e, 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, - 0xa270, 0x080c, 0x9ef8, 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, - 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26bf, 0x710e, 0x001e, - 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, - 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, - 0x0254, 0x4003, 0x080c, 0xb094, 0x1120, 0xb8a0, 0x9082, 0x007f, - 0x0248, 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, - 0x7036, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, - 0x60c3, 0x001c, 0x0804, 0xa270, 0x080c, 0x9ef8, 0x7003, 0x0500, - 0x080c, 0xb094, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, - 0x181f, 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, 0x0030, - 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, - 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, - 0x4003, 0x60c3, 0x0010, 0x0804, 0xa270, 0x080c, 0x9ef8, 0x9006, - 0x080c, 0x6bdb, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2011, 0x0240, - 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, 0x7003, 0x0400, - 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, - 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, - 0x9086, 0x007e, 0x1904, 0x9dcf, 0x00d6, 0x2069, 0x196c, 0x2001, - 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, - 0x2000, 0x7012, 0x080c, 0xb0ab, 0x680c, 0x7016, 0x701f, 0x2710, - 0x6818, 0x7022, 0x681c, 0x7026, 0x0428, 0x6800, 0x700a, 0x6804, - 0x700e, 0x2009, 0x180d, 0x210c, 0xd18c, 0x0110, 0x2001, 0x0002, - 0x00f6, 0x2079, 0x0100, 0x080c, 0x779e, 0x1128, 0x78e3, 0x0000, - 0x080c, 0x2700, 0x78e2, 0x00fe, 0x6808, 0x080c, 0x779e, 0x1118, - 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, 0xb0ab, - 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, - 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, - 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, 0xaadc, - 0x2069, 0x1974, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, 0x080c, - 0x5844, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04e0, 0x2001, - 0x1837, 0x2004, 0xd0a4, 0x01a8, 0x0016, 0x2001, 0x180d, 0x2004, - 0xd08c, 0x2009, 0x0002, 0x1118, 0x2001, 0x196d, 0x200c, 0x60e0, - 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x2700, 0x61e2, - 0x001e, 0x20e1, 0x0001, 0x2099, 0x196c, 0x20e9, 0x0000, 0x20a1, - 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, - 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, - 0x025a, 0x4003, 0x080c, 0xaadc, 0x20a1, 0x024e, 0x20a9, 0x0008, - 0x2099, 0x1974, 0x4003, 0x60c3, 0x0074, 0x0804, 0xa270, 0x080c, - 0x9ef8, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, - 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, - 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, - 0x0002, 0x00d6, 0x0804, 0x9ea8, 0x7026, 0x60c3, 0x0014, 0x0804, - 0xa270, 0x080c, 0x9ef8, 0x7003, 0x5000, 0x0804, 0x9d67, 0x080c, - 0x9ef8, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, - 0xa270, 0x080c, 0x9f3a, 0x0010, 0x080c, 0x9f43, 0x7003, 0x0200, - 0x60c3, 0x0004, 0x0804, 0xa270, 0x080c, 0x9f43, 0x7003, 0x0100, - 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa270, - 0x080c, 0x9f43, 0x7003, 0x0200, 0x0804, 0x9d67, 0x080c, 0x9f43, - 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, - 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x00d6, - 0x080c, 0x9f43, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, - 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, - 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, - 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, - 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, - 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, - 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, - 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbad4, - 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, - 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, - 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0xa270, 0x080c, - 0x9f43, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, - 0x0014, 0x0804, 0xa270, 0x080c, 0x9f43, 0x7003, 0x0200, 0x0804, - 0x9ce5, 0x080c, 0x9f43, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, - 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa270, 0x080c, 0x9f43, 0x7003, - 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0xa270, 0x0026, - 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, - 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, - 0x080c, 0xaaf1, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, - 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029, 0x7012, - 0x004e, 0x003e, 0x00de, 0x080c, 0xa264, 0x721a, 0x9f95, 0x0000, - 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, - 0x080c, 0xaaf1, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, - 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013, 0x2029, - 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, - 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, + 0x2001, 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x2001, 0x180c, + 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, + 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd356, + 0x1904, 0x7989, 0x7130, 0xd184, 0x1170, 0x080c, 0x3468, 0x0138, + 0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, + 0xd08c, 0x0904, 0x7989, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, + 0x0016, 0x2019, 0x000e, 0x080c, 0xe701, 0x0156, 0x00b6, 0x20a9, + 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, + 0x080c, 0x6783, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, + 0x080c, 0xe795, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8add, + 0x001e, 0x8108, 0x1f04, 0x7952, 0x00be, 0x015e, 0x001e, 0xd1ac, + 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32c0, + 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, + 0x6783, 0x1110, 0x080c, 0x6192, 0x8108, 0x1f04, 0x797f, 0x00be, + 0x015e, 0x080c, 0x1b68, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c, + 0xab13, 0x60e3, 0x0000, 0x080c, 0x6178, 0x080c, 0x75cc, 0x00ee, + 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, + 0x197e, 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003, 0x0000, + 0x0005, 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197d, + 0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007, + 0x0000, 0x080c, 0x1066, 0x090c, 0x0d79, 0xa8ab, 0xdcb0, 0x2900, + 0x704e, 0x080c, 0x1066, 0x090c, 0x0d79, 0xa8ab, 0xdcb0, 0x2900, + 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, + 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001, + 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, + 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, 0x7002, + 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, 0x9005, + 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040, + 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004, + 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, + 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7f9c, 0x9006, 0x00ee, + 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x818d, 0x1f04, + 0x7a15, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004, + 0x0002, 0x7a2b, 0x7a2c, 0x7a78, 0x7ad3, 0x7be3, 0x7a29, 0x7a29, + 0x7c0d, 0x080c, 0x0d79, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0, + 0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x807e, 0xd0a4, + 0x0578, 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080, 0x1648, 0x1d04, + 0x7a49, 0x2001, 0x1a08, 0x200c, 0x8109, 0x0510, 0x2091, 0x6000, + 0x2102, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, + 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, + 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7a68, 0x7a32, 0x7a68, + 0x7a66, 0x7a68, 0x7a68, 0x7a68, 0x7a68, 0x7a68, 0x080c, 0x7ad3, + 0x782c, 0xd09c, 0x090c, 0x7f9c, 0x0005, 0x9082, 0x005a, 0x1218, + 0x2100, 0x003b, 0x0c10, 0x080c, 0x7b09, 0x0c90, 0x00e3, 0x08e8, + 0x0005, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b2b, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b15, 0x7b09, 0x7d03, + 0x7b09, 0x7b09, 0x7b09, 0x7b2b, 0x7b09, 0x7b15, 0x7d44, 0x7d85, + 0x7dcc, 0x7de0, 0x7b09, 0x7b09, 0x7b2b, 0x7b15, 0x7b3f, 0x7b09, + 0x7bb7, 0x7e8b, 0x7ea6, 0x7b09, 0x7b2b, 0x7b09, 0x7b3f, 0x7b09, + 0x7b09, 0x7bad, 0x7ea6, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b53, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x8022, 0x7b09, + 0x7fcc, 0x7b09, 0x7fcc, 0x7b09, 0x7b68, 0x7b09, 0x7b09, 0x7b09, + 0x7b09, 0x7b09, 0x7b09, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, + 0x1198, 0x782c, 0x080c, 0x7fc5, 0xd0a4, 0x0170, 0x7824, 0x2048, + 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, + 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7f9c, 0x0005, 0x7b09, + 0x7b15, 0x7cef, 0x7b09, 0x7b15, 0x7b09, 0x7b15, 0x7b15, 0x7b09, + 0x7b15, 0x7cef, 0x7b15, 0x7b15, 0x7b15, 0x7b15, 0x7b15, 0x7b09, + 0x7b15, 0x7cef, 0x7b09, 0x7b09, 0x7b15, 0x7b09, 0x7b09, 0x7b09, + 0x7b15, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, + 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, + 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, + 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6f11, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, + 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c8c, 0x7007, 0x0003, + 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c8c, 0x0005, 0xa864, + 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, + 0x0804, 0x7ca7, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, + 0x704b, 0x7ca7, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, + 0x7b11, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7cc3, 0x7007, + 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7cc3, 0x0005, + 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7b11, + 0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868, + 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x640b, 0x1108, + 0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, + 0x080c, 0x6f11, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38, + 0x9186, 0x0064, 0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186, 0x0028, + 0x09f0, 0x9186, 0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0, 0x9186, + 0x005f, 0x09a8, 0x9186, 0x0056, 0x0990, 0xa897, 0x4005, 0xa89b, + 0x0001, 0x2001, 0x0030, 0x900e, 0x08a0, 0xa87c, 0x9084, 0x00c0, + 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ebd, 0x2900, + 0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, + 0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, + 0x7b19, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7b19, 0x82ff, 0x1138, + 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7c4a, 0x0018, 0x9280, + 0x7c40, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7c2b, 0x080c, + 0x1066, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, + 0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, + 0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, + 0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, + 0xa17a, 0x810b, 0xa17e, 0x080c, 0x1142, 0xa06c, 0x908e, 0x0100, + 0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, + 0x2048, 0x080c, 0x107f, 0x7014, 0x2048, 0x0804, 0x7b19, 0x7020, + 0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, + 0x711a, 0x0804, 0x7be3, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, + 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7ebd, 0x0804, 0x7c8c, + 0x7c42, 0x7c46, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, + 0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, + 0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, + 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, + 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, + 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, + 0xb6aa, 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, + 0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, + 0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, + 0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, + 0x1178, 0x080c, 0x620a, 0x1108, 0x0005, 0x080c, 0x715d, 0x0126, + 0x2091, 0x8000, 0x080c, 0xcf38, 0x080c, 0x6f11, 0x012e, 0x0ca0, + 0x080c, 0xd356, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, + 0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, + 0x0000, 0x080c, 0x6298, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6f11, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, + 0x2001, 0x0000, 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, + 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x636d, 0x1138, + 0x0005, 0x9006, 0xa87a, 0x080c, 0x62e5, 0x1108, 0x0005, 0x0126, + 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6f11, 0x012e, 0x0cb0, + 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, + 0x2061, 0x1800, 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, + 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, + 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, + 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, + 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, + 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, + 0x9005, 0x11d8, 0xa974, 0x080c, 0x6783, 0x11b8, 0x0066, 0xae80, + 0x080c, 0x6893, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, + 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6783, 0x1110, 0x080c, + 0x6a64, 0x8108, 0x1f04, 0x7d2c, 0x00ce, 0xa87c, 0xd084, 0x1120, + 0x080c, 0x107f, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6f11, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x080c, 0x6bc9, 0x0580, 0x2061, 0x1a74, 0x6100, 0xd184, + 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, + 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, + 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, + 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, + 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, + 0x6202, 0x012e, 0x0804, 0x7f86, 0x012e, 0x0804, 0x7f80, 0x012e, + 0x0804, 0x7f7a, 0x012e, 0x0804, 0x7f7d, 0x0126, 0x2091, 0x8000, + 0x7007, 0x0001, 0x080c, 0x6bc9, 0x05e0, 0x2061, 0x1a74, 0x6000, + 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, + 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, + 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, + 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, + 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, + 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, + 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7f86, 0x012e, 0x0804, + 0x7f83, 0x012e, 0x0804, 0x7f80, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x2061, 0x1a74, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, + 0x0220, 0x630a, 0x012e, 0x0804, 0x7f94, 0x012e, 0x0804, 0x7f83, + 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, + 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x9084, 0xfcff, + 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, + 0x0598, 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xaf89, + 0x0068, 0x6017, 0xf400, 0x6063, 0x0000, 0xa97c, 0xd1a4, 0x0110, + 0xa980, 0x6162, 0x2009, 0x0041, 0x080c, 0xafec, 0xa988, 0x918c, + 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, + 0x080c, 0x8add, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a74, + 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, + 0x012e, 0x00be, 0x0804, 0x7f86, 0x00ce, 0x012e, 0x00be, 0x0804, + 0x7f80, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, + 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, + 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, + 0x0029, 0x1d10, 0xa974, 0x080c, 0x6783, 0x1968, 0xb800, 0xc0e4, + 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, + 0x1987, 0x2004, 0x601a, 0x0804, 0x7e1b, 0xa88c, 0x9065, 0x0960, + 0x00e6, 0xa890, 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, + 0x080c, 0xaf89, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xaf89, 0x00ee, + 0x0804, 0x7e1b, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, + 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, + 0xa8a8, 0x6016, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, + 0x00ee, 0x0804, 0x7e1b, 0x2061, 0x1a74, 0x6000, 0xd084, 0x0190, + 0xd08c, 0x1904, 0x7f94, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, + 0x0220, 0x6206, 0x012e, 0x0804, 0x7f94, 0x012e, 0xa883, 0x0016, + 0x0804, 0x7f8d, 0xa883, 0x0007, 0x0804, 0x7f8d, 0xa864, 0x8007, + 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, + 0x0005, 0x080c, 0x7b11, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, + 0x7016, 0x701a, 0x704b, 0x7ebd, 0x0005, 0x00b6, 0x00e6, 0x0126, + 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, + 0x7f3f, 0x6130, 0xd194, 0x1904, 0x7f69, 0xa878, 0x2070, 0x9e82, + 0x1ddc, 0x0a04, 0x7f33, 0x6068, 0x9e02, 0x1a04, 0x7f33, 0x7120, + 0x9186, 0x0006, 0x1904, 0x7f25, 0x7010, 0x905d, 0x0904, 0x7f3f, + 0xb800, 0xd0e4, 0x1904, 0x7f63, 0x2061, 0x1a74, 0x6100, 0x9184, + 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7f6c, + 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, + 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7f6f, 0x080c, 0x5820, 0xd09c, + 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x89cd, 0x012e, + 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, + 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7f6f, 0x012e, 0x00ee, 0x00be, + 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7f8d, + 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6783, + 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, + 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, + 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, + 0x5824, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x02c0, + 0x6068, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, + 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, + 0x9086, 0x0007, 0x1904, 0x7ec9, 0x7003, 0x0002, 0x0804, 0x7ec9, + 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, + 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, + 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe28e, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, + 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, + 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6f11, 0x012e, 0x0005, 0x080c, 0x107f, 0x0005, 0x00d6, + 0x080c, 0x89c4, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, + 0x190c, 0x807e, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, + 0x0020, 0x0278, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, + 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, + 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, + 0x190c, 0x807e, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, + 0x080c, 0xaef8, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0035, 0x1138, 0x6028, 0xc0fd, 0x602a, 0x2001, 0x196c, + 0x2004, 0x0098, 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, + 0x9105, 0xa99c, 0x918c, 0x00ff, 0x080c, 0x26a1, 0x1540, 0x00b6, + 0x080c, 0x6783, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, + 0x2009, 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, + 0x2009, 0x0041, 0x080c, 0xafec, 0x0005, 0xa87b, 0x0101, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x0005, 0xa87b, 0x002c, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x0005, 0xa87b, + 0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c, + 0xaf4e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, + 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x806f, 0xa97c, + 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, + 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, + 0x080c, 0xaef8, 0x1118, 0x080c, 0xafbf, 0x05a8, 0x6212, 0xa874, + 0x0002, 0x804d, 0x8052, 0x8055, 0x805b, 0x2019, 0x0002, 0x080c, + 0xe701, 0x0060, 0x080c, 0xe68c, 0x0048, 0x2019, 0x0002, 0xa980, + 0x080c, 0xe6ab, 0x0018, 0xa980, 0x080c, 0xe68c, 0x080c, 0xaf4e, + 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, + 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, + 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, + 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, + 0x0e04, 0x8080, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, + 0x0d82, 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, + 0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, + 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x163c, 0x00fe, + 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, + 0x0005, 0x781c, 0xd08c, 0x0904, 0x8101, 0x68c0, 0x90aa, 0x0005, + 0x0a04, 0x8729, 0x7d44, 0x7c40, 0xd59c, 0x190c, 0x0d79, 0x9584, + 0x00f6, 0x1508, 0x9484, 0x7000, 0x0138, 0x908a, 0x2000, 0x1258, + 0x9584, 0x0700, 0x8007, 0x04f0, 0x7000, 0x9084, 0xff00, 0x9086, + 0x8100, 0x0db0, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084, + 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xebc0, 0x080c, 0x8610, + 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x866c, + 0x19c8, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x8151, 0x080c, + 0x21a2, 0x005e, 0x004e, 0x0020, 0x080c, 0xebc0, 0x7817, 0x0140, + 0x080c, 0x769d, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, + 0x6893, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000, + 0x0489, 0x0005, 0x0002, 0x810e, 0x841e, 0x810b, 0x810b, 0x810b, + 0x810b, 0x810b, 0x810b, 0x7817, 0x0140, 0x0005, 0x7000, 0x908c, + 0xff00, 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286, + 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x588a, + 0x0070, 0x080c, 0x8171, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, + 0x8358, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x853d, 0x7817, + 0x0140, 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, + 0x8048, 0x2518, 0x080c, 0x4c28, 0x003e, 0x002e, 0x0005, 0x0036, + 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, + 0x0050, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, + 0x7c40, 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, + 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, + 0x8048, 0x080c, 0x4c28, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, + 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, + 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x8329, 0x9186, 0x0023, + 0x15c0, 0x080c, 0x85db, 0x0904, 0x8329, 0x6120, 0x9186, 0x0001, + 0x0150, 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, + 0x000a, 0x1904, 0x8329, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, + 0x1130, 0x2009, 0x0015, 0x080c, 0xafec, 0x0804, 0x8329, 0x908e, + 0x0214, 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, + 0xafec, 0x0804, 0x8329, 0x908e, 0x0100, 0x1904, 0x8329, 0x7034, + 0x9005, 0x1904, 0x8329, 0x2009, 0x0016, 0x080c, 0xafec, 0x0804, + 0x8329, 0x9186, 0x0022, 0x1904, 0x8329, 0x7030, 0x908e, 0x0300, + 0x1580, 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, + 0x00ff, 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, + 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26ea, + 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x26a1, 0x695e, + 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, + 0x00ee, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x0017, 0x0804, + 0x82d9, 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x8329, + 0x080c, 0x769d, 0x0120, 0x2009, 0x001d, 0x0804, 0x82d9, 0x68dc, + 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804, 0x82d9, 0x908e, 0x0500, + 0x1140, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x0018, 0x0804, + 0x82d9, 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x82d9, + 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x82d9, 0x908e, + 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x001b, + 0x0804, 0x82d9, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, + 0x8329, 0x2009, 0x001c, 0x0804, 0x82d9, 0x908e, 0x1300, 0x1120, + 0x2009, 0x0034, 0x0804, 0x82d9, 0x908e, 0x1200, 0x1140, 0x7034, + 0x9005, 0x1904, 0x8329, 0x2009, 0x0024, 0x0804, 0x82d9, 0x908c, + 0xff00, 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, + 0x2004, 0xd09c, 0x0904, 0x82d9, 0x080c, 0xdaa3, 0x1904, 0x8329, + 0x0804, 0x82d7, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, + 0x002a, 0x0804, 0x82d9, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, + 0x0804, 0x82d9, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, + 0x026d, 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, + 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4c28, + 0x004e, 0x8108, 0x0f04, 0x828d, 0x9186, 0x0280, 0x1d88, 0x2504, + 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, + 0x0023, 0x0804, 0x82d9, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, + 0x0804, 0x82d9, 0x908e, 0x5400, 0x1138, 0x080c, 0x86d9, 0x1904, + 0x8329, 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, + 0x8701, 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, + 0x908e, 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, + 0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, + 0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, + 0x004f, 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, + 0x0050, 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, + 0x004c, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, + 0x26a1, 0x1904, 0x832c, 0x080c, 0x6718, 0x1904, 0x832c, 0xbe12, + 0xbd16, 0x001e, 0x0016, 0x080c, 0x769d, 0x01c0, 0x68dc, 0xd08c, + 0x1148, 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, + 0x1168, 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, + 0xff00, 0x1120, 0x9584, 0x00ff, 0xb886, 0x0080, 0xb884, 0x9005, + 0x1168, 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, + 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xaef8, + 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, + 0x9186, 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, + 0xafec, 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, + 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c28, 0x080c, + 0xafbf, 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, + 0x001e, 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, + 0x6007, 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, + 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x9427, 0x08a0, + 0x080c, 0x8748, 0x1158, 0x080c, 0x3432, 0x1140, 0x7010, 0x9084, + 0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, + 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, + 0x11e8, 0x080c, 0x85db, 0x0904, 0x83b6, 0x7124, 0x610a, 0x7030, + 0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15c0, 0x2009, 0x0015, + 0x080c, 0xafec, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005, + 0x1568, 0x2009, 0x0016, 0x080c, 0xafec, 0x0440, 0x9186, 0x0032, + 0x1528, 0x7030, 0x908e, 0x1400, 0x1508, 0x2009, 0x0038, 0x0016, + 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a1, 0x11a8, + 0x080c, 0x6718, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xaef8, 0x0168, + 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0004, 0x7120, 0x610a, + 0x001e, 0x080c, 0xafec, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, + 0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, + 0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, + 0x1120, 0x2009, 0x007f, 0x0804, 0x8418, 0x9596, 0xfffe, 0x1120, + 0x2009, 0x007e, 0x0804, 0x8418, 0x9596, 0xfffc, 0x1118, 0x2009, + 0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac, + 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, + 0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, + 0x1140, 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, + 0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, + 0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, + 0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, + 0x83ed, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, + 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837, + 0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, + 0xff00, 0x810f, 0x9184, 0x000f, 0x001a, 0x7817, 0x0140, 0x0005, + 0x8440, 0x8440, 0x8440, 0x85ed, 0x8440, 0x8443, 0x8468, 0x84f1, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x7817, 0x0140, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, + 0x2160, 0x9c8c, 0x0003, 0x11c0, 0x9c8a, 0x1ddc, 0x02a8, 0x6868, + 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, + 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, + 0x2009, 0x0046, 0x080c, 0xafec, 0x7817, 0x0140, 0x00be, 0x0005, + 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x84cd, 0x7110, 0xd1bc, + 0x1904, 0x84cd, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, + 0x9094, 0xff00, 0x15c8, 0x81ff, 0x15b8, 0x9080, 0x3474, 0x200d, + 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x84cd, + 0x9182, 0x0801, 0x1a04, 0x84cd, 0x9190, 0x1000, 0x2204, 0x905d, + 0x05e0, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15b8, 0xba04, 0x9294, + 0xff00, 0x9286, 0x0600, 0x1190, 0x080c, 0xaef8, 0x0598, 0x2b08, + 0x7028, 0x604e, 0x702c, 0x6052, 0x6112, 0x6023, 0x0006, 0x7120, + 0x610a, 0x7130, 0x615e, 0x080c, 0xdd1f, 0x00f8, 0x080c, 0x6bcd, + 0x1138, 0xb807, 0x0606, 0x0c40, 0x190c, 0x83ba, 0x11b0, 0x0880, + 0x080c, 0xaef8, 0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120, + 0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x7817, 0x0140, 0x00ce, + 0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, + 0x8049, 0x080c, 0x4c28, 0x080c, 0xafbf, 0x0d78, 0x2b08, 0x6112, + 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x615e, 0x6017, 0xf300, + 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, + 0x08e0, 0x00b6, 0x7110, 0xd1bc, 0x05d0, 0x7020, 0x2060, 0x9c84, + 0x0003, 0x15a8, 0x9c82, 0x1ddc, 0x0690, 0x6868, 0x9c02, 0x1678, + 0x9484, 0x0fff, 0x9082, 0x000c, 0x0650, 0x7008, 0x9084, 0x00ff, + 0x6110, 0x2158, 0xb910, 0x9106, 0x1510, 0x700c, 0xb914, 0x9106, + 0x11f0, 0x7124, 0x610a, 0x601c, 0xd0fc, 0x11c8, 0x2001, 0x0271, + 0x2004, 0x9005, 0x1180, 0x9484, 0x0fff, 0x9082, 0x000c, 0x0158, + 0x0066, 0x2031, 0x0100, 0xa001, 0xa001, 0x8631, 0x1de0, 0x006e, + 0x601c, 0xd0fc, 0x1120, 0x2009, 0x0045, 0x080c, 0xafec, 0x7817, + 0x0140, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, + 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8748, 0x1180, + 0x080c, 0x3432, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, + 0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, + 0x0005, 0x8557, 0x8558, 0x8557, 0x8557, 0x85bd, 0x85cc, 0x0005, + 0x00b6, 0x700c, 0x7108, 0x080c, 0x26a1, 0x1904, 0x85bb, 0x080c, + 0x6718, 0x1904, 0x85bb, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, + 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x85bb, 0x080c, + 0x6bcd, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bd5, 0x0118, + 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x85db, 0x00ce, 0x05d8, + 0x080c, 0xaef8, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd0ce, 0x6023, + 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xafec, 0x0458, + 0x080c, 0x6bcd, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bd5, + 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xaef8, 0x2b08, 0x01d8, + 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, + 0x0088, 0x080c, 0xafec, 0x0078, 0x080c, 0xaef8, 0x2b08, 0x0158, + 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, + 0x0001, 0x080c, 0xafec, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, + 0x00d1, 0x0148, 0x080c, 0x8533, 0x1130, 0x7124, 0x610a, 0x2009, + 0x0089, 0x080c, 0xafec, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, + 0x0148, 0x080c, 0x8533, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, + 0x080c, 0xafec, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0003, 0x1158, + 0x9c82, 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218, + 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, + 0x11d8, 0x7024, 0x2060, 0x9c84, 0x0003, 0x11b0, 0x9c82, 0x1ddc, + 0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, + 0x2158, 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, + 0x2009, 0x0051, 0x080c, 0xafec, 0x7817, 0x0140, 0x00be, 0x0005, + 0x2031, 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, + 0x2031, 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, + 0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, + 0x05c0, 0x080c, 0xaef8, 0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011, + 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a1, 0x1590, 0x080c, + 0x6718, 0x1578, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, + 0x080c, 0xd0ce, 0x080c, 0x104d, 0x0500, 0x2900, 0x6062, 0x9006, + 0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, + 0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, + 0x6616, 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, + 0x9427, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xaf4e, 0x006e, + 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, + 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x86c3, 0x9186, + 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x86c5, + 0x7030, 0x908e, 0x0400, 0x0904, 0x86c5, 0x908e, 0x6000, 0x05e8, + 0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837, + 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6b8b, 0x0588, + 0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, + 0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, + 0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, + 0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, + 0x9186, 0x0023, 0x1140, 0x080c, 0x85db, 0x0128, 0x6004, 0x9086, + 0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, + 0x0005, 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, + 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, + 0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, + 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, + 0x2011, 0x027a, 0x080c, 0xbf40, 0x1178, 0xd48c, 0x0148, 0x20a9, + 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xbf40, 0x1120, + 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, + 0x0005, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, + 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, + 0x2011, 0x0272, 0x080c, 0xbf40, 0x1178, 0xd48c, 0x0148, 0x20a9, + 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xbf40, 0x1120, + 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, + 0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, + 0x2079, 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, + 0x0016, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, + 0x0118, 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, + 0x1a05, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, + 0x7012, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0xa0bb, + 0x7032, 0x7037, 0xa138, 0x7047, 0xffff, 0x704a, 0x704f, 0x56a4, + 0x7052, 0x7063, 0x88ff, 0x080c, 0x1066, 0x090c, 0x0d79, 0x2900, + 0x7042, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, + 0x2071, 0x1a05, 0x1d04, 0x881b, 0x2091, 0x6000, 0x700c, 0x8001, + 0x700e, 0x1590, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x89a9, + 0x2001, 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, + 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d79, + 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x2069, + 0x1800, 0x69ec, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x896d, + 0x0010, 0x080c, 0x8944, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, + 0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, + 0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, + 0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, + 0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, + 0x702e, 0x1160, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, + 0x007f, 0x090c, 0xa1e6, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, + 0x0118, 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, + 0x8001, 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, + 0x7158, 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, + 0x7078, 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, + 0x0009, 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, + 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, + 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x8843, 0x8844, 0x886e, + 0x00e6, 0x2071, 0x1a05, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, + 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1a05, + 0x701c, 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, + 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1a05, 0xb888, 0x9102, 0x0208, + 0xb98a, 0x00ee, 0x0005, 0x0005, 0x00b6, 0x2031, 0x0010, 0x7110, + 0x080c, 0x6783, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180, + 0x0126, 0x2091, 0x8000, 0x0066, 0xb8d0, 0x9005, 0x0138, 0x0026, + 0xba3c, 0x0016, 0x080c, 0x68ae, 0x001e, 0x002e, 0x006e, 0x012e, + 0x8108, 0x9182, 0x0800, 0x1220, 0x8631, 0x0128, 0x7112, 0x0c00, + 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x2031, 0x0010, + 0x7014, 0x2060, 0x0126, 0x2091, 0x8000, 0x6048, 0x9005, 0x0128, + 0x8001, 0x604a, 0x1110, 0x080c, 0xcf4f, 0x6018, 0x9005, 0x0904, + 0x88c6, 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x88d9, + 0x781b, 0x2020, 0xa001, 0x7918, 0xd1b4, 0x0120, 0x781b, 0x2000, + 0x0804, 0x88d9, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001, + 0x7918, 0xd1ac, 0x1dd0, 0x010e, 0x00fe, 0x1540, 0x6120, 0x9186, + 0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, 0x0009, 0x11e0, + 0x611c, 0xd1c4, 0x1100, 0x080c, 0xcc33, 0x01b0, 0x6014, 0x2048, + 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, 0xa886, 0x908a, + 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0x9108, + 0x611a, 0x080c, 0xd389, 0x0110, 0x080c, 0xc910, 0x012e, 0x9c88, + 0x001c, 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, 0x1228, 0x8631, + 0x0138, 0x2160, 0x0804, 0x8872, 0x7017, 0x1ddc, 0x7007, 0x0000, + 0x0005, 0x00fe, 0x0c58, 0x00e6, 0x2071, 0x1a05, 0x7027, 0x07d0, + 0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a0e, 0x2003, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x1a05, 0x7132, 0x702f, 0x0009, 0x00ee, + 0x0005, 0x2011, 0x1a11, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, + 0x1a05, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, + 0x0026, 0x705c, 0x8000, 0x705e, 0x2001, 0x1a15, 0x2044, 0xa06c, + 0x9086, 0x0000, 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, + 0xa092, 0x7064, 0xa08e, 0x080c, 0x1142, 0x002e, 0x008e, 0x0005, + 0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x0156, 0x080c, 0x8780, 0x015e, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, + 0x2071, 0x1a05, 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, + 0x00e6, 0x0006, 0x2071, 0x1a05, 0x707c, 0x9206, 0x1110, 0x707a, + 0x707e, 0x000e, 0x00ee, 0x0005, 0x2069, 0x1800, 0x69ec, 0xd1e4, + 0x1518, 0x0026, 0xd1ec, 0x0140, 0x6a54, 0x6874, 0x9202, 0x0288, + 0x8117, 0x9294, 0x00c1, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, + 0x9184, 0x0007, 0x0110, 0x69ee, 0x0070, 0x8107, 0x9084, 0x0007, + 0x910d, 0x8107, 0x9106, 0x9094, 0x00c1, 0x9184, 0xff3e, 0x9205, + 0x68ee, 0x080c, 0x0f18, 0x002e, 0x0005, 0x69e8, 0x9184, 0x003f, + 0x05b8, 0x8109, 0x9184, 0x003f, 0x01a8, 0x6a54, 0x6874, 0x9202, + 0x0220, 0xd1bc, 0x0168, 0xc1bc, 0x0018, 0xd1bc, 0x1148, 0xc1bd, + 0x2110, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f3a, 0x00ee, 0x0400, + 0x69ea, 0x00f0, 0x0026, 0x8107, 0x9094, 0x0007, 0x0128, 0x8001, + 0x8007, 0x9085, 0x0007, 0x0050, 0x2010, 0x8004, 0x8004, 0x8004, + 0x9084, 0x0007, 0x9205, 0x8007, 0x9085, 0x0028, 0x9086, 0x0040, + 0x2010, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f3a, 0x00ee, 0x002e, + 0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100, + 0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220, + 0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6, + 0x2061, 0x1a74, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003, 0x8003, + 0x8003, 0x9080, 0x1a74, 0x2060, 0x0005, 0xa884, 0x908a, 0x199a, + 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a74, 0x6014, 0x00ce, + 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0, + 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0, + 0x918e, 0x00c0, 0x0904, 0x8a87, 0xd0b4, 0x1168, 0xd0bc, 0x1904, + 0x8a60, 0x2009, 0x0006, 0x080c, 0x8ab4, 0x0005, 0x900e, 0x0c60, + 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x05e0, 0x908c, 0x2023, 0x1568, + 0x87ff, 0x1558, 0xa9a8, 0x81ff, 0x1540, 0x6124, 0x918c, 0x0500, + 0x1520, 0x6100, 0x918e, 0x0007, 0x1500, 0x2009, 0x1869, 0x210c, + 0xd184, 0x11d8, 0x6003, 0x0003, 0x6007, 0x0043, 0x6047, 0xb035, + 0x080c, 0x1c8c, 0xa87c, 0xc0dd, 0xa87e, 0x600f, 0x0000, 0x00f6, + 0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0013, 0x2c00, + 0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x908c, 0x0003, 0x0120, + 0x918e, 0x0003, 0x1904, 0x8aae, 0x908c, 0x2020, 0x918e, 0x2020, + 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, + 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xafec, 0x0005, + 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xafec, 0x6110, 0x00b6, + 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026, + 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0, + 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, + 0x8aae, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, + 0x2c78, 0x080c, 0x17a1, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, + 0x0042, 0x080c, 0xafec, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, + 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc, + 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, + 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, + 0xafec, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, + 0x080c, 0xafec, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, + 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, + 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xcc33, 0x0518, + 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188, + 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061, + 0x1a74, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, + 0x00ce, 0x080c, 0x6d4b, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, + 0x190c, 0x89cd, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, + 0x1a74, 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002, + 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005, + 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1925, + 0x7003, 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, + 0x080c, 0x1066, 0x090c, 0x0d79, 0xa867, 0x0006, 0xa86b, 0x0001, + 0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1925, + 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, + 0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c, 0x701a, + 0x2009, 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188, 0x000c, + 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92, + 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000, + 0x0006, 0x2009, 0x1b74, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e, + 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16ad, 0x9006, + 0x2071, 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e, + 0x0005, 0x2009, 0x1b74, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005, + 0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154, + 0x2001, 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006, + 0x9080, 0x0008, 0x1f04, 0x8b70, 0x71c0, 0x9102, 0x02e0, 0x2071, + 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xaef8, 0x6023, 0x0009, + 0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000, + 0x080c, 0x8cf1, 0x012e, 0x1f04, 0x8b7c, 0x9006, 0x00ce, 0x015e, + 0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6, + 0x0096, 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620, + 0x7004, 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, + 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x104d, 0x090c, 0x0d79, + 0x2900, 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a, + 0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a, + 0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109, + 0x0160, 0x080c, 0x104d, 0x090c, 0x0d79, 0xad66, 0x2b00, 0xa802, + 0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e, + 0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071, + 0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8be8, 0x8be1, 0x8be1, + 0x0005, 0x8bf2, 0x8c48, 0x8c48, 0x8c48, 0x8c49, 0x8c5a, 0x8c5a, + 0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106, + 0x1904, 0x8c3a, 0x7814, 0xd0bc, 0x1904, 0x8c43, 0x012e, 0x7018, + 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8c8c, 0x0005, 0x1210, + 0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001, + 0x1888, 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202, 0x0e50, + 0x080c, 0x8de9, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c, + 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8ef2, 0x2100, 0xa87e, + 0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a25, + 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x1161, + 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8bfa, 0x080c, + 0x8dc1, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8bfa, + 0x0005, 0x700c, 0x0002, 0x8c4e, 0x8c51, 0x8c50, 0x080c, 0x8bf0, + 0x0005, 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e, + 0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100, + 0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006, + 0x0068, 0x0006, 0x080c, 0x8ef2, 0x2100, 0xaa8c, 0x9210, 0xaa8e, + 0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126, + 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8dc1, 0x012e, 0x0005, + 0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8c8a, 0x8c8a, 0x8c88, + 0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030, + 0x9005, 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059, + 0x0000, 0x080c, 0x8cfa, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e, + 0x080c, 0x8d41, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1066, 0x2900, + 0x009e, 0x0148, 0xa8aa, 0x04d1, 0x0041, 0x2001, 0x1948, 0x2003, + 0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086, + 0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084, + 0x000f, 0x2068, 0x9d88, 0x1ede, 0x2165, 0x0056, 0x2029, 0x0000, + 0x080c, 0x8e77, 0x080c, 0x1eb4, 0x1dd8, 0x005e, 0x00ae, 0x2001, + 0x187f, 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x17a1, 0x00ce, + 0x781f, 0x0101, 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8d50, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, + 0x0138, 0x2078, 0x780c, 0x7032, 0x2001, 0x1948, 0x2003, 0x0001, + 0x0005, 0x00e6, 0x2071, 0x1925, 0x7030, 0x600e, 0x2c00, 0x7032, + 0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8fc0, 0x2005, + 0x906d, 0x090c, 0x0d79, 0x9b80, 0x8fb8, 0x2005, 0x9065, 0x090c, + 0x0d79, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, + 0x9085, 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, + 0x0148, 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, + 0x080c, 0x4c28, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d79, 0xa804, + 0x8000, 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, + 0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4c28, 0x684c, + 0x0096, 0x904d, 0x090c, 0x0d79, 0xa800, 0x8000, 0xa802, 0x009e, + 0x0888, 0x7000, 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, + 0x2300, 0x9005, 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, + 0x00d6, 0x7814, 0x9005, 0x090c, 0x0d79, 0x781c, 0x9084, 0x0101, + 0x9086, 0x0101, 0x190c, 0x0d79, 0x7827, 0x0000, 0x2069, 0x193e, + 0x6804, 0x9080, 0x1940, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, + 0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x1940, 0x2003, 0x0000, + 0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, + 0x0096, 0x2048, 0x9005, 0x190c, 0x107f, 0x009e, 0xa8ab, 0x0000, + 0x080c, 0x0fff, 0x080c, 0xaf4e, 0x00ce, 0x009e, 0x0005, 0x6020, + 0x9086, 0x0009, 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, + 0x9085, 0x0001, 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, + 0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x90f5, 0x00be, 0x6013, + 0x0000, 0x601b, 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, + 0x1929, 0x210c, 0xd194, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, + 0x2071, 0x1925, 0x7110, 0xc194, 0xd19c, 0x1118, 0xc185, 0x7007, + 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, 0x16ad, 0x00ee, 0x012e, + 0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, 0x7810, 0xc0c5, 0x7812, + 0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, 0x700e, 0x701a, 0x701e, + 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8f40, + 0x0170, 0x080c, 0x8f75, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a, + 0x7013, 0x0001, 0x701f, 0x000a, 0x00de, 0x009e, 0x0005, 0x900e, + 0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, 0x00c6, 0x2071, 0x1932, + 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x8f75, 0x090c, 0x0d79, + 0x7018, 0x9005, 0x1160, 0x2900, 0x7002, 0x700a, 0x701a, 0x9006, + 0x7006, 0x700e, 0xa806, 0xa802, 0x7012, 0x701e, 0x0038, 0x2040, + 0xa806, 0x2900, 0xa002, 0x701a, 0xa803, 0x0000, 0x7010, 0x8000, + 0x7012, 0x701c, 0x9080, 0x000a, 0x701e, 0x721c, 0x08d0, 0x721c, + 0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, 0x0005, 0x0096, 0x0156, + 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1932, + 0x7300, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, 0x20e8, 0x939c, + 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x8ef2, 0x810c, 0x2100, + 0x9318, 0x8003, 0x2228, 0x2021, 0x0078, 0x9402, 0x9532, 0x0208, + 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xa001, 0xa001, 0x4005, + 0x2508, 0x080c, 0x8efb, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600, + 0x711c, 0x9102, 0x701e, 0x7004, 0x9600, 0x2008, 0x9082, 0x000a, + 0x1190, 0x7000, 0x2048, 0xa800, 0x9005, 0x1148, 0x2009, 0x0001, + 0x0026, 0x080c, 0x8de9, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002, + 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8e28, + 0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, 0x009e, 0x0005, 0x0016, + 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580, 0x8fb8, 0x2005, + 0x9075, 0x090c, 0x0d79, 0x080c, 0x8ecd, 0x012e, 0x9580, 0x8fb4, + 0x2005, 0x9075, 0x090c, 0x0d79, 0x0156, 0x0136, 0x01c6, 0x0146, + 0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, 0x20e0, 0x9384, + 0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, 0xa95c, 0x2c05, 0x9100, + 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8eb7, + 0x8eb7, 0x8eb9, 0x8eb7, 0x8eb9, 0x8eb7, 0x8eb7, 0x8eb7, 0x8eb7, + 0x8eb7, 0x8ebf, 0x8eb7, 0x8ebf, 0x8eb7, 0x8eb7, 0x8eb7, 0x080c, + 0x0d79, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9, + 0x0002, 0x4003, 0x4104, 0x4003, 0x01de, 0x014e, 0x01ce, 0x013e, + 0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x7014, 0x8001, + 0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, 0x9188, 0x0003, 0x7308, + 0x8210, 0x9282, 0x000a, 0x1198, 0x7008, 0x2048, 0xa800, 0x9005, + 0x0158, 0x0006, 0x080c, 0x8f84, 0x009e, 0xa807, 0x0000, 0x2900, + 0x700a, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000, 0x0008, 0x720e, + 0x009e, 0x0005, 0x0006, 0x810b, 0x810b, 0x2100, 0x810b, 0x9100, + 0x2008, 0x000e, 0x0005, 0x0006, 0x0026, 0x2100, 0x9005, 0x0158, + 0x9092, 0x000c, 0x0240, 0x900e, 0x8108, 0x9082, 0x000c, 0x1de0, + 0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, 0x2d00, 0x90b8, 0x0008, + 0x2031, 0x8f3e, 0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c, + 0x910a, 0x0248, 0x0140, 0x8318, 0x6810, 0x9112, 0x0220, 0x0118, + 0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, 0xd084, 0x2300, 0x2021, + 0x0001, 0x1150, 0x9082, 0x0003, 0x0967, 0x0a67, 0x8420, 0x9082, + 0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, 0x0002, 0x0967, 0x0a67, + 0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, 0x0cd0, 0x6c1a, 0x0005, + 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8fbc, + 0x2005, 0x9005, 0x090c, 0x0d79, 0x2004, 0x90a0, 0x000a, 0x080c, + 0x1066, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, + 0x080c, 0x1066, 0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900, + 0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, 0x0c90, 0x9085, 0x0001, + 0x012e, 0x004e, 0x009e, 0x0005, 0x7024, 0x9005, 0x0dc8, 0x2048, + 0xac00, 0x080c, 0x107f, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000, + 0x7024, 0x2048, 0x9005, 0x0130, 0xa800, 0x7026, 0xa803, 0x0000, + 0xa807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024, + 0xa802, 0x2900, 0x7026, 0x012e, 0x0005, 0x0096, 0x9e80, 0x0009, + 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x107f, + 0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, 0x7008, 0x9005, 0x0138, + 0x2048, 0xa800, 0x0006, 0x080c, 0x107f, 0x000e, 0x0cb8, 0x9006, + 0x7002, 0x700a, 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x702a, + 0x7026, 0x702e, 0x009e, 0x0005, 0x1a72, 0x0000, 0x0000, 0x0000, + 0x1932, 0x0000, 0x0000, 0x0000, 0x1888, 0x0000, 0x0000, 0x0000, + 0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, 0x00c6, 0x00b6, 0x00a6, + 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x90e0, 0xa067, 0x0023, + 0x6010, 0x905d, 0x0904, 0x90b5, 0xb814, 0xa06e, 0xb910, 0xa172, + 0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, 0xa834, 0xa082, 0xa07b, + 0x0000, 0xa898, 0x9005, 0x0118, 0xa078, 0xc085, 0xa07a, 0x2858, + 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c, 0x0d79, 0x2020, + 0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, 0x908c, 0x000f, 0x91e0, + 0x1ede, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036, + 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x9020, 0x9020, 0x9022, + 0x9020, 0x9020, 0x9020, 0x9024, 0x9020, 0x9020, 0x9020, 0x9026, + 0x9020, 0x9020, 0x9020, 0x9028, 0x9020, 0x9020, 0x9020, 0x902a, + 0x9020, 0x9020, 0x9020, 0x902c, 0x9020, 0x9020, 0x9020, 0x902e, + 0x080c, 0x0d79, 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498, + 0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458, + 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x9052, + 0x9050, 0x9050, 0x9050, 0x9050, 0x9050, 0x9054, 0x9050, 0x9050, + 0x9050, 0x9050, 0x9050, 0x9056, 0x9050, 0x9050, 0x9050, 0x9050, + 0x9050, 0x9058, 0x9050, 0x9050, 0x9050, 0x9050, 0x9050, 0x905a, + 0x080c, 0x0d79, 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018, + 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x9076, 0x9078, 0x907a, + 0x907c, 0x907e, 0x9080, 0x9082, 0x9084, 0x9086, 0x9088, 0x908a, + 0x908c, 0x908e, 0x9090, 0x9092, 0x9094, 0x9096, 0x9098, 0x909a, + 0x909c, 0x909e, 0x90a0, 0x90a2, 0x90a4, 0x90a6, 0x080c, 0x0d79, + 0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, 0x0448, 0xb9d6, 0x0438, + 0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, 0x0408, 0xb9c6, 0x00f8, + 0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, 0x00c8, 0xb9b6, 0x00b8, + 0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, 0x0088, 0xb9a6, 0x0078, + 0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, 0x0048, 0xb996, 0x0038, + 0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, 0x0008, 0xb986, 0x8631, + 0x8421, 0x0130, 0x080c, 0x1eb4, 0x090c, 0x0d79, 0x0804, 0x8ffa, + 0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870, + 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x8fdc, 0x0006, 0x0016, + 0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, 0x01b0, 0x2001, 0x1926, + 0x2004, 0x9005, 0x0188, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, + 0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0004, 0x2011, 0x8014, + 0x080c, 0x4c28, 0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005, + 0x9016, 0x710c, 0xa834, 0x910a, 0xa936, 0x7008, 0x9005, 0x0120, + 0x8210, 0x910a, 0x0238, 0x0130, 0x7010, 0x8210, 0x910a, 0x0210, + 0x0108, 0x0cd8, 0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, 0x0036, + 0x2079, 0x0300, 0x781b, 0x0200, 0x7818, 0xd094, 0x1dd8, 0x781b, + 0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, 0x9005, + 0x01b8, 0x2068, 0x2079, 0x0000, 0x2c08, 0x911e, 0x1118, 0x680c, + 0xb8ae, 0x0060, 0x9106, 0x0140, 0x2d00, 0x2078, 0x680c, 0x9005, + 0x090c, 0x0d79, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000, + 0x2079, 0x0300, 0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, + 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, + 0x0156, 0x20a9, 0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, + 0xd094, 0x0110, 0x1f04, 0x9135, 0x701b, 0x0202, 0xa001, 0xa001, + 0x7018, 0xd094, 0x1d90, 0xb8ac, 0x9005, 0x01e8, 0x2060, 0x600c, + 0xb8ae, 0x6024, 0xc08d, 0x6026, 0x6003, 0x0004, 0x601b, 0x0000, + 0x6013, 0x0000, 0x601f, 0x0101, 0x6014, 0x2048, 0xa88b, 0x0000, + 0xa8a8, 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0d79, 0x080c, 0x107f, + 0x080c, 0x8cf1, 0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, + 0x012e, 0x003e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, + 0x00b6, 0x0016, 0x0006, 0x0156, 0x080c, 0x26a1, 0x015e, 0x11b0, + 0x080c, 0x6718, 0x190c, 0x0d79, 0x000e, 0x001e, 0xb912, 0xb816, + 0x080c, 0xaef8, 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, + 0x0001, 0x080c, 0xafec, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, + 0x0cd0, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x0013, + 0x006e, 0x0005, 0x91aa, 0x91aa, 0x91aa, 0x91ac, 0x91f5, 0x91aa, + 0x91aa, 0x91aa, 0x925c, 0x91aa, 0x9294, 0x91aa, 0x91aa, 0x91aa, + 0x91aa, 0x91aa, 0x080c, 0x0d79, 0x9182, 0x0040, 0x0002, 0x91bf, + 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, + 0x91c1, 0x91d2, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91e3, 0x080c, + 0x0d79, 0x0096, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, + 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6d10, 0x080c, 0xaf4e, + 0x009e, 0x0005, 0x080c, 0x9851, 0x00d6, 0x6114, 0x080c, 0xcc33, + 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6f11, 0x009e, 0x00de, + 0x080c, 0xaf4e, 0x0005, 0x080c, 0x9851, 0x080c, 0x32fb, 0x6114, + 0x0096, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0029, 0x080c, + 0x6f11, 0x009e, 0x080c, 0xaf4e, 0x0005, 0x601b, 0x0000, 0x9182, + 0x0040, 0x0096, 0x0002, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, + 0x9210, 0x9210, 0x9210, 0x9212, 0x9210, 0x9210, 0x9210, 0x9258, + 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9219, 0x9210, + 0x080c, 0x0d79, 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, + 0x9258, 0x6024, 0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c, + 0x8fc4, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6ca8, 0x009e, 0xa8ab, + 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90f5, + 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8cfa, 0x00be, + 0x01e0, 0x2071, 0x193e, 0x080c, 0x8d41, 0x01b8, 0x9086, 0x0001, + 0x1128, 0x2001, 0x1948, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c, + 0x104d, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c, + 0x8cb5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8cf1, 0x0cd0, + 0x080c, 0x9310, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002, + 0x9270, 0x9270, 0x9270, 0x9272, 0x9270, 0x9270, 0x9270, 0x9292, + 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, + 0x080c, 0x0d79, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac, + 0xa836, 0xa8b0, 0xa83a, 0xa847, 0x0000, 0xa84b, 0x0000, 0xa884, + 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, + 0x9210, 0x621a, 0x080c, 0x1c43, 0x2009, 0x8030, 0x080c, 0x9467, + 0x009e, 0x0005, 0x080c, 0x0d79, 0x080c, 0x9851, 0x6114, 0x2148, + 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, + 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xaaf7, + 0x6144, 0xd1fc, 0x0120, 0xd1ac, 0x1110, 0x6003, 0x0003, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096, 0x0023, 0x009e, 0x080c, + 0xab13, 0x0005, 0x92ca, 0x92ca, 0x92ca, 0x92cc, 0x92dd, 0x92ca, + 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, + 0x92ca, 0x92ca, 0x080c, 0x0d79, 0x080c, 0xaccf, 0x6114, 0x2148, + 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, + 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x0005, 0x0491, 0x0005, 0x080c, + 0xaaf7, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, 0x6003, + 0x0003, 0x2009, 0x0003, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096, + 0x0033, 0x009e, 0x0106, 0x080c, 0xab13, 0x010e, 0x0005, 0x9307, + 0x9307, 0x9307, 0x9309, 0x9310, 0x9307, 0x9307, 0x9307, 0x9307, + 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x080c, + 0x0d79, 0x0036, 0x00e6, 0x080c, 0xaccf, 0x00ee, 0x003e, 0x0005, + 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, 0x6014, + 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90f5, + 0x00be, 0x2071, 0x193e, 0x080c, 0x8d41, 0x0160, 0x2001, 0x187f, + 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8cb5, 0x00ee, + 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, 0x080c, + 0x107f, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8cf1, 0x0c80, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x187a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126, + 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004, + 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x9358, 0x8086, 0x818e, + 0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, + 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a, 0x12b8, 0x8213, + 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x936f, 0x0028, 0x911a, + 0x2308, 0x8210, 0x1f04, 0x936f, 0x0006, 0x3200, 0x9084, 0xefff, + 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200, + 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9, + 0x012e, 0x00d6, 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146, + 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xa8ec, 0x04c9, + 0x080c, 0xa8d7, 0x04b1, 0x080c, 0xa8da, 0x0499, 0x080c, 0xa8dd, + 0x0481, 0x080c, 0xa8e0, 0x0469, 0x080c, 0xa8e3, 0x0451, 0x080c, + 0xa8e6, 0x0439, 0x080c, 0xa8e9, 0x0421, 0x01de, 0x014e, 0x015e, + 0x6857, 0x0000, 0x00f6, 0x2079, 0x0380, 0x0419, 0x7807, 0x0003, + 0x7803, 0x0000, 0x7803, 0x0001, 0x2069, 0x0004, 0x2d04, 0x9084, + 0xfffe, 0x9085, 0x8000, 0x206a, 0x2069, 0x0100, 0x6828, 0x9084, + 0xfffc, 0x682a, 0x00fe, 0x2001, 0x1b5e, 0x2003, 0x0000, 0x00de, + 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, + 0x0005, 0x00c6, 0x7803, 0x0000, 0x9006, 0x7827, 0x0030, 0x782b, + 0x0400, 0x7827, 0x0031, 0x782b, 0x1af7, 0x781f, 0xff00, 0x781b, + 0xff00, 0x2061, 0x1aec, 0x602f, 0x19e9, 0x6033, 0x1800, 0x6037, + 0x1a05, 0x603b, 0x1ede, 0x603f, 0x1eee, 0x6042, 0x6047, 0x1ac2, + 0x00ce, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, + 0x0001, 0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061, + 0x19e9, 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080, + 0x0003, 0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e, 0x0cd8, + 0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xaae8, 0x0005, 0x0016, + 0x2009, 0x8020, 0x6146, 0x2c08, 0x2001, 0x0382, 0x2004, 0x9084, + 0x0007, 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xaae8, + 0x0088, 0x00c6, 0x2061, 0x19e9, 0x602c, 0x8000, 0x602e, 0x600c, + 0x9005, 0x0128, 0x9080, 0x0003, 0x2102, 0x610e, 0x0010, 0x6112, + 0x610e, 0x00ce, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, + 0x0007, 0x9086, 0x0001, 0x0198, 0x00c6, 0x6146, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x19e9, 0x6044, 0x9005, 0x0130, 0x9080, 0x0003, + 0x2102, 0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8, 0x6146, + 0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xaae8, 0x0005, + 0x6044, 0xd0dc, 0x0110, 0x080c, 0xa585, 0x0005, 0x00f6, 0x00e6, + 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, + 0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e9, 0x7648, + 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x94fa, 0x9c86, + 0x1b56, 0x0904, 0x94f5, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, + 0x94f5, 0x87ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x94f5, 0x704c, + 0x9c06, 0x1188, 0x0036, 0x2019, 0x0001, 0x080c, 0xa391, 0x703f, + 0x0000, 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xade0, + 0x003e, 0x2029, 0x0001, 0x080c, 0x9470, 0x7048, 0x9c36, 0x1110, + 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, + 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066, 0x2c00, + 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, + 0xcc33, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588, + 0x6004, 0x9086, 0x0040, 0x090c, 0xa585, 0xa867, 0x0103, 0xab7a, + 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xcf38, 0x080c, + 0xeaee, 0x080c, 0x6f11, 0x007e, 0x003e, 0x001e, 0x080c, 0xce24, + 0x080c, 0xaf89, 0x00ce, 0x0804, 0x948c, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x948c, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, + 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, + 0x080c, 0xeaee, 0x080c, 0xe738, 0x007e, 0x003e, 0x001e, 0x08c0, + 0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, + 0x0076, 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x007e, 0x003e, 0x001e, + 0x0848, 0x6020, 0x9086, 0x000a, 0x0904, 0x94df, 0x0804, 0x94d8, + 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, + 0x2091, 0x8000, 0x2079, 0x19e9, 0x7848, 0x9065, 0x0904, 0x9599, + 0x600c, 0x0006, 0x600f, 0x0000, 0x784c, 0x9c06, 0x11b0, 0x0036, + 0x2019, 0x0001, 0x080c, 0xa391, 0x783f, 0x0000, 0x901e, 0x7b4e, + 0x7b6a, 0x7b52, 0x7b6e, 0x080c, 0xade0, 0x003e, 0x000e, 0x9005, + 0x1118, 0x600c, 0x600f, 0x0000, 0x0006, 0x9c86, 0x1b56, 0x05b0, + 0x00e6, 0x2f70, 0x080c, 0x9470, 0x00ee, 0x080c, 0xcc33, 0x0548, + 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x15a8, 0x3e08, 0x918e, + 0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x0140, 0x6048, 0x9005, 0x11c0, 0x2001, 0x1989, + 0x2004, 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c, 0xa585, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f05, 0x080c, + 0xce24, 0x6044, 0xc0fc, 0x6046, 0x080c, 0xaf89, 0x000e, 0x0804, + 0x953d, 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, + 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, + 0xe738, 0x0c38, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, + 0x6f11, 0x080c, 0xaf4e, 0x0c10, 0x6020, 0x9086, 0x000a, 0x0990, + 0x0850, 0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x96ac, + 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e9, + 0x2091, 0x8000, 0x080c, 0x96f5, 0x080c, 0x978b, 0x080c, 0x690e, + 0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, + 0x19e9, 0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9671, 0x6010, + 0x2058, 0xb8a0, 0x9206, 0x1904, 0x966c, 0x88ff, 0x0120, 0x605c, + 0x9106, 0x1904, 0x966c, 0x7030, 0x9c06, 0x1580, 0x2069, 0x0100, + 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88e4, 0x080c, + 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585, 0x7033, 0x0000, 0x0036, + 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, + 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x7008, 0xc0ad, + 0x700a, 0x6003, 0x0009, 0x630a, 0x0804, 0x966c, 0x7020, 0x9c36, + 0x1110, 0x660c, 0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36, + 0x0118, 0x2f00, 0x701e, 0x0010, 0x701f, 0x0000, 0x660c, 0x0066, + 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0x6044, 0xc0fc, 0x6046, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01e8, + 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xce4a, 0x1118, 0x080c, + 0xb93c, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, + 0x0036, 0x0086, 0x080c, 0xcf38, 0x080c, 0xeaee, 0x080c, 0x6f11, + 0x008e, 0x003e, 0x001e, 0x080c, 0xce24, 0x080c, 0xaf89, 0x080c, + 0xa458, 0x00ce, 0x0804, 0x95e4, 0x2c78, 0x600c, 0x2060, 0x0804, + 0x95e4, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, + 0x0016, 0x0036, 0x0086, 0x080c, 0xeaee, 0x080c, 0xe738, 0x008e, + 0x003e, 0x001e, 0x08d0, 0x080c, 0xb93c, 0x6020, 0x9086, 0x0002, + 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x9652, + 0x9086, 0x008b, 0x0904, 0x9652, 0x0840, 0x6020, 0x9086, 0x0005, + 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, + 0x008b, 0x09b0, 0x0804, 0x9665, 0x0006, 0x00f6, 0x00e6, 0x0096, + 0x00b6, 0x00c6, 0x0066, 0x0016, 0x0126, 0x2091, 0x8000, 0x9280, + 0x1000, 0x2004, 0x905d, 0x2079, 0x19e9, 0x9036, 0x7828, 0x2060, + 0x8cff, 0x0538, 0x6010, 0x9b06, 0x1500, 0x6043, 0xffff, 0x080c, + 0xad1a, 0x01d8, 0x610c, 0x0016, 0x080c, 0xa21b, 0x6014, 0x2048, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, + 0x080c, 0xcf38, 0x080c, 0xeaee, 0x080c, 0x6f11, 0x008e, 0x003e, + 0x001e, 0x080c, 0xaf89, 0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060, + 0x08b8, 0x080c, 0x692b, 0x012e, 0x001e, 0x006e, 0x00ce, 0x00be, + 0x009e, 0x00ee, 0x00fe, 0x000e, 0x0005, 0x0096, 0x0006, 0x0066, + 0x00c6, 0x00d6, 0x9036, 0x7820, 0x9065, 0x0904, 0x975e, 0x600c, + 0x0006, 0x6044, 0xc0fc, 0x6046, 0x600f, 0x0000, 0x7830, 0x9c06, + 0x1598, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, + 0x080c, 0x88e4, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585, + 0x7833, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, + 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, + 0x0058, 0x080c, 0x6b65, 0x1538, 0x6003, 0x0009, 0x630a, 0x7808, + 0xc0ad, 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcc31, + 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xce4a, 0x1118, + 0x080c, 0xb93c, 0x0060, 0x080c, 0x6b65, 0x1168, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x080c, + 0xaf89, 0x080c, 0xa458, 0x000e, 0x0804, 0x96fc, 0x7e22, 0x7e1e, + 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086, + 0x0006, 0x1118, 0x080c, 0xe738, 0x0c50, 0x080c, 0xb93c, 0x6020, + 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, + 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005, + 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086, + 0x008b, 0x0d00, 0x0860, 0x0006, 0x0096, 0x00b6, 0x00c6, 0x0066, + 0x9036, 0x7828, 0x9065, 0x0510, 0x6010, 0x2058, 0x600c, 0x0006, + 0x3e08, 0x918e, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x11a8, 0x6043, + 0xffff, 0x080c, 0xad1a, 0x0180, 0x610c, 0x080c, 0xa21b, 0x6014, + 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f11, + 0x080c, 0xaf89, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e, 0x00ce, + 0x00be, 0x009e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066, + 0x080c, 0x628a, 0x11b0, 0x2071, 0x19e9, 0x7030, 0x9080, 0x0005, + 0x2004, 0x904d, 0x0170, 0xa878, 0x9606, 0x1158, 0x2071, 0x19e9, + 0x7030, 0x9035, 0x0130, 0x9080, 0x0005, 0x2004, 0x9906, 0x1108, + 0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x2660, + 0x6043, 0xffff, 0x080c, 0xad1a, 0x0178, 0x080c, 0xa21b, 0x6014, + 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf38, + 0x080c, 0x6f11, 0x080c, 0xaf89, 0x00ce, 0x0005, 0x00b6, 0x00e6, + 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x0101, 0x2e04, 0xc0c4, + 0x2072, 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xab13, 0x00ce, + 0x00ee, 0x00be, 0x0005, 0x2071, 0x19e9, 0x7030, 0x9005, 0x0da0, + 0x9c06, 0x190c, 0x0d79, 0x7036, 0x080c, 0x88e4, 0x7004, 0x9084, + 0x0007, 0x0002, 0x9824, 0x9826, 0x982d, 0x9837, 0x9845, 0x9824, + 0x9832, 0x9822, 0x080c, 0x0d79, 0x0428, 0x0005, 0x080c, 0xad05, + 0x7007, 0x0000, 0x7033, 0x0000, 0x00e8, 0x0066, 0x9036, 0x080c, + 0xa21b, 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098, 0x080c, + 0xacf0, 0x0140, 0x080c, 0xad05, 0x0128, 0x0066, 0x9036, 0x080c, + 0xa21b, 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xacf0, 0x080c, + 0xa585, 0x0000, 0x010e, 0x090c, 0xab13, 0x00ce, 0x00ee, 0x00be, + 0x0005, 0x00d6, 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x6044, 0xd0fc, + 0x1130, 0x010e, 0x090c, 0xab13, 0x00ce, 0x00de, 0x0005, 0x2069, + 0x19e9, 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d79, 0x6852, + 0x00e6, 0x2d70, 0x080c, 0x9470, 0x00ee, 0x080c, 0x88f1, 0x0016, + 0x2009, 0x0040, 0x080c, 0x223d, 0x001e, 0x683c, 0x9084, 0x0003, + 0x0002, 0x987f, 0x9880, 0x989f, 0x987d, 0x080c, 0x0d79, 0x0490, + 0x6868, 0x9086, 0x0001, 0x0198, 0x600c, 0x9015, 0x0168, 0x6a4a, + 0x600f, 0x0000, 0x6044, 0x9084, 0x7f7f, 0x6046, 0x9006, 0x6842, + 0x684e, 0x683f, 0x0000, 0x00f0, 0x684a, 0x6846, 0x0c98, 0x686b, + 0x0000, 0x6848, 0x9065, 0x0d70, 0x6003, 0x0002, 0x0c58, 0x6044, + 0x9084, 0x7f7f, 0x6046, 0x9006, 0x6842, 0x684e, 0x686a, 0x6852, + 0x686e, 0x600c, 0x9015, 0x0120, 0x6a4a, 0x600f, 0x0000, 0x0010, + 0x684a, 0x6846, 0x080c, 0xade0, 0x684f, 0x0000, 0x010e, 0x090c, + 0xab13, 0x00ce, 0x00de, 0x0005, 0x0005, 0x6020, 0x9084, 0x000f, + 0x000b, 0x0005, 0x98d2, 0x98d5, 0x9d7b, 0x9e14, 0x98d5, 0x9d7b, + 0x9e14, 0x98d2, 0x98d5, 0x98d2, 0x98d2, 0x98d2, 0x98d2, 0x98d2, + 0x98d2, 0x98d2, 0x080c, 0x97f6, 0x0005, 0x00b6, 0x0156, 0x0136, + 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, + 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d79, + 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, + 0x0040, 0x1a04, 0x9941, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9aea, + 0x9b25, 0x9b4e, 0x9c0a, 0x9c2c, 0x9c32, 0x9c3f, 0x9c47, 0x9c53, + 0x9c59, 0x9c6a, 0x9c59, 0x9cc2, 0x9c47, 0x9cce, 0x9cd4, 0x9c53, + 0x9cd4, 0x9ce0, 0x993f, 0x993f, 0x993f, 0x993f, 0x993f, 0x993f, + 0x993f, 0x993f, 0x993f, 0x993f, 0x993f, 0xa23c, 0xa25f, 0xa270, + 0xa290, 0xa2c2, 0x9c3f, 0x993f, 0x9c3f, 0x9c59, 0x993f, 0x9b4e, + 0x9c0a, 0x993f, 0xa683, 0x9c59, 0x993f, 0xa69f, 0x9c59, 0x993f, + 0x9c53, 0x9ae4, 0x9962, 0x993f, 0xa6bb, 0xa728, 0xa80c, 0x993f, + 0xa819, 0x9c3c, 0xa844, 0x993f, 0xa2cc, 0xa850, 0x993f, 0x080c, + 0x0d79, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, + 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xa8f0, 0xa9a2, + 0x9960, 0x999a, 0x9a46, 0x9a51, 0x9960, 0x9c3f, 0x9960, 0x9aab, + 0x9ab7, 0x99b5, 0x9960, 0x99d0, 0x9a04, 0xadf4, 0xae39, 0x9c59, + 0x080c, 0x0d79, 0x00d6, 0x0096, 0x080c, 0x9cf3, 0x0026, 0x0036, + 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, + 0x0018, 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, + 0x2019, 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, + 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0xa06b, 0x003e, + 0x002e, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, + 0x00be, 0x080c, 0xae80, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, + 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9cf3, 0x7003, 0x0500, + 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, + 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, + 0x080c, 0xa06b, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, + 0x9cf3, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, + 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, + 0x701e, 0x60c3, 0x0010, 0x080c, 0xa06b, 0x009e, 0x00de, 0x0005, + 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9cf3, 0x20e9, + 0x0000, 0x2001, 0x19a5, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, + 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x001b, 0x2098, 0x2001, 0x19a5, 0x0016, 0x200c, 0x2001, 0x0001, + 0x080c, 0x2222, 0x080c, 0xda05, 0x9006, 0x080c, 0x2222, 0x001e, + 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa06b, + 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, + 0x8000, 0x080c, 0x9d3e, 0x20e9, 0x0000, 0x2001, 0x19a5, 0x2003, + 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, + 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x001b, 0x2098, 0x2001, 0x19a5, 0x0016, 0x200c, 0x080c, 0xda05, + 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, + 0x2048, 0x080c, 0x0fff, 0x080c, 0xa06b, 0x012e, 0x009e, 0x00de, + 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, + 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9cf3, + 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, + 0xa06b, 0x00d6, 0x00e6, 0x080c, 0x9d3e, 0x7814, 0x9084, 0xff00, + 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, + 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, + 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, + 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9a71, 0x2069, 0x1801, + 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9a7a, 0x9096, + 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, + 0x2069, 0x19b5, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19cf, 0x20a9, + 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, + 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, + 0x8d68, 0x8e70, 0x1f04, 0x9a91, 0x60c3, 0x004c, 0x080c, 0xa06b, + 0x00ee, 0x00de, 0x0005, 0x080c, 0x9cf3, 0x7003, 0x6300, 0x7007, + 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b, 0x00d6, + 0x0026, 0x0016, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x7814, 0x700e, + 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, + 0x1925, 0x6810, 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, + 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, + 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa06b, + 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, + 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x5200, 0x2069, 0x1847, + 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26d4, 0x710e, + 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, + 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, + 0x20a1, 0x0254, 0x4003, 0x080c, 0xae80, 0x1120, 0xb8a0, 0x9082, + 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, + 0x2004, 0x7036, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, + 0x7036, 0x60c3, 0x001c, 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, + 0x0500, 0x080c, 0xae80, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, + 0x2001, 0x181f, 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, + 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, + 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, + 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0xa06b, 0x080c, 0x9cf3, + 0x9006, 0x080c, 0x6b97, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2011, + 0x0240, 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, 0x7003, + 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, + 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, + 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9bd1, 0x00d6, 0x2069, 0x196d, + 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, + 0x9084, 0x2000, 0x7012, 0x080c, 0xae97, 0x680c, 0x7016, 0x701f, + 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x00f0, 0x6800, 0x700a, + 0x6804, 0x700e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x769d, 0x1128, + 0x78e3, 0x0000, 0x080c, 0x2715, 0x78e2, 0x00fe, 0x6808, 0x080c, + 0x769d, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, + 0x080c, 0xae97, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, + 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, + 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, + 0x080c, 0xa8d7, 0x2069, 0x1975, 0x2071, 0x024e, 0x6800, 0xc0dd, + 0x7002, 0x080c, 0x5824, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, + 0x04a8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016, 0x2001, + 0x196e, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, + 0x080c, 0x2715, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196d, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, + 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, + 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0xa8d7, 0x20a1, + 0x024e, 0x20a9, 0x0008, 0x2099, 0x1975, 0x4003, 0x60c3, 0x0074, + 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x2010, 0x7007, 0x0014, + 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, + 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, + 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9ca3, 0x7026, + 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x5000, + 0x0804, 0x9b70, 0x080c, 0x9cf3, 0x7003, 0x2110, 0x7007, 0x0014, + 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9d35, 0x0010, 0x080c, + 0x9d3e, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0xa06b, 0x080c, + 0x9d3e, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, + 0x0008, 0x0804, 0xa06b, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x0804, + 0x9b70, 0x080c, 0x9d3e, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, + 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, + 0x0804, 0xa06b, 0x00d6, 0x080c, 0x9d3e, 0x7003, 0x0210, 0x7007, + 0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, + 0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, + 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, + 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, + 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, + 0xd1a4, 0x0110, 0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, + 0x1110, 0x9085, 0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, + 0x0150, 0xc0c5, 0xbad4, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, + 0x9296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, + 0x0010, 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, + 0x0804, 0xa06b, 0x080c, 0x9d3e, 0x7003, 0x0210, 0x7007, 0x0014, + 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9d3e, + 0x7003, 0x0200, 0x0804, 0x9aee, 0x080c, 0x9d3e, 0x7003, 0x0100, + 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa06b, + 0x080c, 0x9d3e, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, + 0x0804, 0xa06b, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, - 0x2300, 0x2021, 0x0100, 0x080c, 0xaaf1, 0xb810, 0x9305, 0x7002, - 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, - 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, - 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, - 0x003e, 0x00de, 0x080c, 0xa264, 0x721a, 0x7a08, 0x7222, 0x2f10, - 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0xa264, 0x721a, - 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, - 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, - 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092, - 0x1a0c, 0x0d85, 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061, 0x0100, - 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, - 0x00be, 0x0005, 0x9fb1, 0x9fc0, 0x9fcb, 0x9faf, 0x9faf, 0x9faf, - 0x9fb1, 0x9faf, 0x9faf, 0x9faf, 0x9faf, 0x9faf, 0x9faf, 0x080c, - 0x0d85, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x2a04, 0x0228, - 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0xa270, - 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, - 0x000c, 0x0804, 0xa270, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, - 0x60c3, 0x0004, 0x0804, 0xa270, 0x0026, 0x080c, 0xaaf1, 0xb810, - 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, - 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0x9f13, 0x0026, - 0x080c, 0xaaf1, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, - 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, - 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f75, - 0x0026, 0x080c, 0xaaf1, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, - 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, - 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, - 0x9f75, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, - 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0d85, - 0x908a, 0x0057, 0x1a0c, 0x0d85, 0x7910, 0x2158, 0xb984, 0x2061, - 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x00be, 0x0005, 0xa04e, 0xa04e, 0xa04e, 0xa07f, 0xa04e, - 0xa04e, 0xa04e, 0xa04e, 0xa04e, 0xa04e, 0xa04e, 0xa644, 0xa649, - 0xa64e, 0xa653, 0xa04e, 0xa04e, 0xa04e, 0xa63f, 0x080c, 0x0d85, - 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4, 0xd084, 0x0180, 0x2001, - 0x1b72, 0x200c, 0x8108, 0x2102, 0x2001, 0x1b71, 0x201c, 0x1218, - 0x8318, 0x2302, 0x0ea0, 0x7952, 0x712e, 0x7b4e, 0x732a, 0x9294, - 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, 0x0600, 0x7202, - 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e, - 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, 0x0005, 0x0016, - 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, 0xa08f, - 0xa08f, 0xa091, 0xa08f, 0xa08f, 0xa08f, 0xa0ab, 0xa08f, 0x080c, - 0x0d85, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, 0x2009, - 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130, 0x682c, - 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, 0x60c3, - 0x0001, 0x0804, 0xa270, 0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, - 0x0cb0, 0x0016, 0x080c, 0xaaf1, 0x001e, 0xb810, 0x9085, 0x0100, - 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, - 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0xa264, - 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6, - 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, - 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4, 0x0028, - 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028, 0x0140, - 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, 0x0050, - 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff, 0x606b, - 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008, 0xb88c, - 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, - 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, - 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834, - 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, - 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x0128, - 0x609f, 0x0000, 0x2001, 0x0092, 0x0058, 0x6028, 0xc0bd, 0x602a, - 0x609f, 0x00ff, 0x2011, 0xffff, 0x080c, 0x2ad3, 0x2001, 0x00b2, - 0x2010, 0x900e, 0x080c, 0x2ae2, 0x2009, 0x07d0, 0x080c, 0x8a50, - 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, + 0x2200, 0x2021, 0x0100, 0x080c, 0xa8ec, 0xb810, 0x9305, 0x7002, + 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, + 0x9485, 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa05f, + 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, + 0x002e, 0x0005, 0x0026, 0x080c, 0xa8ec, 0x7003, 0x02ff, 0x7007, + 0xfffc, 0x00d6, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, + 0x00de, 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, + 0x700b, 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, + 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, + 0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xa8ec, + 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, + 0x9005, 0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, + 0xfffe, 0x0020, 0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, + 0x0098, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa05f, 0x721a, + 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, + 0x080c, 0xa05f, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, + 0x024c, 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, + 0x0d79, 0x908a, 0x0092, 0x1a0c, 0x0d79, 0x6110, 0x2158, 0xb984, + 0x2c78, 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9dac, 0x9dbb, 0x9dc6, + 0x9daa, 0x9daa, 0x9daa, 0x9dac, 0x9daa, 0x9daa, 0x9daa, 0x9daa, + 0x9daa, 0x9daa, 0x080c, 0x0d79, 0x0411, 0x60c3, 0x0000, 0x0026, + 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, + 0x002e, 0x0804, 0xa06b, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, + 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804, 0xa06b, 0x04a1, 0x7003, + 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0xa06b, 0x0026, + 0x080c, 0xa8ec, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, + 0x0804, 0x9d0e, 0x0026, 0x080c, 0xa8ec, 0xb810, 0x9085, 0x8400, + 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, + 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, + 0x7012, 0x0804, 0x9d70, 0x0026, 0x080c, 0xa8ec, 0xb810, 0x9085, + 0x8500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, + 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, + 0xc0bc, 0x7012, 0x0804, 0x9d70, 0x00b6, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, + 0x0040, 0x0a0c, 0x0d79, 0x908a, 0x0057, 0x1a0c, 0x0d79, 0x7910, + 0x2158, 0xb984, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9e49, 0x9e49, + 0x9e49, 0x9e7a, 0x9e49, 0x9e49, 0x9e49, 0x9e49, 0x9e49, 0x9e49, + 0x9e49, 0xa43f, 0xa444, 0xa449, 0xa44e, 0x9e49, 0x9e49, 0x9e49, + 0xa43a, 0x080c, 0x0d79, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4, + 0xd084, 0x0180, 0x2001, 0x1b73, 0x200c, 0x8108, 0x2102, 0x2001, + 0x1b72, 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x7952, 0x712e, + 0x7b4e, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, + 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, + 0x720a, 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, + 0xffff, 0x0005, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, + 0x001e, 0x0005, 0x9e8a, 0x9e8a, 0x9e8c, 0x9e8a, 0x9e8a, 0x9e8a, + 0x9ea6, 0x9e8a, 0x080c, 0x0d79, 0x7914, 0x918c, 0x08ff, 0x918d, + 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, + 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, + 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0xa06b, 0x2009, 0x0003, + 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xa8ec, 0x001e, + 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, + 0x7116, 0x080c, 0xa05f, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, - 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, 0x9582, 0x007e, 0x1250, - 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, 0x348e, 0x2015, 0x9294, - 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, 0x7480, 0x70dc, 0xd0ac, - 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, 0xff80, 0x0138, 0x9185, - 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030, 0x6063, 0x0400, - 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6072, 0x6077, 0x0000, - 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, - 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, - 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, 0x2048, 0xa848, - 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834, 0x60ca, 0x009e, - 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, - 0xba84, 0x629e, 0x00f6, 0x2079, 0x0140, 0x7803, 0x0000, 0x00fe, - 0x900e, 0x2011, 0x0092, 0x080c, 0x2ae2, 0x2009, 0x07d0, 0x080c, - 0x8a50, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, - 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056, - 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810, 0x2058, - 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, 0x7820, 0x0002, - 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, - 0xa1ef, 0xa1ef, 0xa1f1, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0x080c, - 0x0d85, 0xb884, 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, - 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, - 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, - 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, - 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, - 0x0129, 0x6077, 0x0000, 0xb884, 0x609e, 0x0050, 0x2039, 0x0029, - 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, - 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, - 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, - 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, - 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834, 0x60ca, - 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xaad1, - 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, - 0x1b58, 0x080c, 0x8a50, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, - 0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40, 0x9294, 0x00ff, 0x8217, - 0x0005, 0x00d6, 0x2069, 0x19e8, 0x686b, 0x0001, 0x00de, 0x0005, - 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x8a42, 0x0005, - 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, - 0x0128, 0x0089, 0x080c, 0x8a42, 0x001e, 0x0005, 0xc1e5, 0x2001, - 0x180c, 0x2102, 0x2001, 0x19e9, 0x2003, 0x0000, 0x2001, 0x19f4, - 0x2003, 0x0000, 0x0c88, 0x0006, 0x0016, 0x0026, 0x2009, 0x1804, - 0x2011, 0x0009, 0x080c, 0x2ae2, 0x002e, 0x001e, 0x000e, 0x0005, - 0x0016, 0x00c6, 0x0006, 0x080c, 0xacfc, 0x0106, 0x2061, 0x0100, - 0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026, 0x2009, 0x1804, 0x2011, - 0x0008, 0x080c, 0x2ae2, 0x002e, 0x001e, 0x010e, 0x090c, 0xad18, - 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, - 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, - 0x080c, 0x779e, 0x1510, 0x2001, 0x1a0d, 0x2004, 0x9005, 0x1904, - 0xa31f, 0x080c, 0x7840, 0x11a8, 0x2069, 0x0380, 0x6843, 0x0101, - 0x6844, 0xd084, 0x1de8, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, - 0x6024, 0xd084, 0x090c, 0x0d85, 0x6843, 0x0100, 0x080c, 0x8a42, - 0x04b0, 0x00c6, 0x2061, 0x19e8, 0x00f0, 0x6904, 0x9194, 0x4000, - 0x0598, 0x080c, 0xa2a0, 0x080c, 0x2aa9, 0x00c6, 0x2061, 0x19e8, - 0x6134, 0x9192, 0x0008, 0x1278, 0x8108, 0x6136, 0x080c, 0xacfc, - 0x6130, 0x080c, 0xad18, 0x00ce, 0x81ff, 0x01c8, 0x080c, 0x8a42, - 0x080c, 0xa293, 0x00a0, 0x080c, 0xacfc, 0x6130, 0x91e5, 0x0000, - 0x0150, 0x080c, 0xeeee, 0x080c, 0x8a4b, 0x6003, 0x0001, 0x2009, - 0x0014, 0x080c, 0xb20a, 0x080c, 0xad18, 0x00ce, 0x0000, 0x002e, - 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a0d, 0x2004, 0x9005, - 0x1db0, 0x00c6, 0x2061, 0x19e8, 0x6134, 0x9192, 0x0003, 0x1ad8, - 0x8108, 0x6136, 0x00ce, 0x080c, 0x8a42, 0x080c, 0x6058, 0x2009, - 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, - 0x00e6, 0x0016, 0x0026, 0x080c, 0x8a58, 0x080c, 0xacfc, 0x2001, - 0x0387, 0x2003, 0x0202, 0x2071, 0x19e8, 0x714c, 0x81ff, 0x0904, - 0xa3d9, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x779e, 0x1518, - 0x0036, 0x2019, 0x0002, 0x080c, 0xa596, 0x003e, 0x080c, 0xeeee, - 0x704c, 0x9065, 0x0180, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, - 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x6003, - 0x0003, 0x080c, 0xb20a, 0x2001, 0x0386, 0x2003, 0x5040, 0x080c, - 0x7840, 0x0804, 0xa3d9, 0x6904, 0xd1f4, 0x0904, 0xa3e6, 0x080c, - 0x2aa9, 0x00c6, 0x704c, 0x9065, 0x090c, 0x0d85, 0x6020, 0x00ce, - 0x9086, 0x0006, 0x1520, 0x61c8, 0x60c4, 0x9105, 0x1500, 0x714c, - 0x9188, 0x0011, 0x2104, 0xd0e4, 0x01d0, 0x6214, 0x9294, 0x1800, - 0x1128, 0x6224, 0x9294, 0x0002, 0x15e0, 0x0010, 0xc0e4, 0x200a, - 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x704c, 0x2060, - 0x080c, 0x9a48, 0x2009, 0x0049, 0x080c, 0xb20a, 0x0450, 0x080c, - 0xeeee, 0x704c, 0x9065, 0x9086, 0x1b55, 0x1158, 0x080c, 0xafd2, - 0x1500, 0x2061, 0x1b55, 0x6064, 0x8000, 0x6066, 0x080c, 0x6058, - 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa596, 0x003e, 0x714c, - 0x2160, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, - 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x6003, 0x0003, 0x080c, - 0xb20a, 0x2001, 0x0387, 0x2003, 0x0200, 0x080c, 0xad18, 0x002e, - 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, - 0xa37f, 0x0804, 0xa381, 0x0026, 0x00e6, 0x2071, 0x19e8, 0x706c, - 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c, 0x81ff, 0x01c0, 0x2071, - 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, 0x1138, 0x2009, - 0x1984, 0x2011, 0x0012, 0x080c, 0x2ae2, 0x0048, 0x928e, 0x0009, - 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2ae2, 0x00ee, - 0x002e, 0x0005, 0x9036, 0x2001, 0x19f2, 0x2004, 0x9005, 0x0128, - 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8, 0x9085, 0x0001, 0x0005, - 0x00f6, 0x2079, 0x19e8, 0x610c, 0x9006, 0x600e, 0x6044, 0xc0fc, - 0x6046, 0x86ff, 0x1140, 0x7824, 0x9c06, 0x1118, 0x7826, 0x782a, - 0x0050, 0x792a, 0x0040, 0x00c6, 0x2660, 0x610e, 0x00ce, 0x7824, - 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa65d, 0x080c, 0xd10c, 0x00fe, - 0x0005, 0x080c, 0x9ef8, 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, - 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, - 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, - 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, - 0x60c3, 0x002c, 0x0804, 0xa270, 0x080c, 0x9ef8, 0x7003, 0x0f00, - 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, - 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x0156, 0x080c, 0x9f43, - 0x7003, 0x0200, 0x080c, 0x8b10, 0x20a9, 0x0006, 0x2011, 0xffec, - 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, - 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xa484, - 0x60c3, 0x001c, 0x015e, 0x0804, 0xa270, 0x0016, 0x0026, 0x080c, - 0x9f1f, 0x080c, 0x9f31, 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, - 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, - 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, - 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, - 0x080c, 0xa270, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, - 0x080c, 0xaadc, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, - 0x9ef8, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, - 0xa270, 0x0016, 0x0026, 0x080c, 0x9ef8, 0x20e9, 0x0000, 0x20a1, - 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, - 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, - 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0xa270, 0x002e, 0x001e, - 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, - 0x19e8, 0x7010, 0x2060, 0x8cff, 0x0188, 0x080c, 0xd132, 0x1110, - 0x080c, 0xbb5c, 0x600c, 0x0006, 0x080c, 0xd3ae, 0x600f, 0x0000, - 0x080c, 0xb16c, 0x080c, 0xa65d, 0x00ce, 0x0c68, 0x2c00, 0x7012, - 0x700e, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, - 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, - 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102, - 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e8, 0x7030, 0x2060, - 0x8cff, 0x0548, 0x080c, 0xa2a0, 0x6ac0, 0x68c3, 0x0000, 0x080c, - 0x8a4b, 0x00c6, 0x2061, 0x0100, 0x080c, 0xac2d, 0x00ce, 0x20a9, - 0x01f4, 0x04b1, 0x080c, 0x99ed, 0x6044, 0xd0ac, 0x1128, 0x2001, - 0x1988, 0x2004, 0x604a, 0x0020, 0x2009, 0x0013, 0x080c, 0xb20a, - 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, - 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, - 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x8a4b, 0x6814, 0x9084, - 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, - 0x2011, 0x6002, 0x080c, 0x8993, 0x20a9, 0x01f4, 0x0009, 0x08c0, - 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, - 0x190c, 0x2aa9, 0x0090, 0xd084, 0x0118, 0x6827, 0x4001, 0x0010, - 0x1f04, 0xa578, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, - 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x0005, 0x0126, 0x0156, - 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, - 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, - 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x0380, 0x701c, 0x0006, - 0x701f, 0x0202, 0x2071, 0x19e8, 0x704c, 0x2060, 0x8cff, 0x0904, - 0xa619, 0x080c, 0xaf84, 0x0904, 0xa619, 0x9386, 0x0002, 0x1128, - 0x6814, 0x9084, 0x0002, 0x0904, 0xa619, 0x68af, 0x95f5, 0x6817, - 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, - 0x080c, 0x8a58, 0x080c, 0x1e44, 0x2001, 0x0032, 0x6920, 0xd1bc, - 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x0016, - 0x2009, 0x0040, 0x080c, 0x2220, 0x001e, 0x20a9, 0x03e8, 0x6824, - 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, - 0x2aa9, 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, - 0xa5e7, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, - 0x2a99, 0x9006, 0x080c, 0x2a99, 0x6827, 0x4000, 0x6824, 0x83ff, - 0x1180, 0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0150, 0x080c, - 0x9a48, 0x6044, 0xd0ac, 0x1118, 0x6003, 0x0002, 0x0010, 0x080c, - 0xb20a, 0x000e, 0x2071, 0x0380, 0xd08c, 0x1110, 0x701f, 0x0200, - 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, - 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, - 0x19e8, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091, - 0x8000, 0x2069, 0x19e8, 0x6a3e, 0x012e, 0x00de, 0x0005, 0x080c, - 0xa050, 0x7047, 0x1000, 0x0098, 0x080c, 0xa050, 0x7047, 0x4000, - 0x0070, 0x080c, 0xa050, 0x7047, 0x2000, 0x0048, 0x080c, 0xa050, - 0x7047, 0x0400, 0x0020, 0x080c, 0xa050, 0x7047, 0x0200, 0x785c, - 0x7032, 0x60c3, 0x0020, 0x0804, 0xa270, 0x00e6, 0x2071, 0x19e8, - 0x702c, 0x9005, 0x0110, 0x8001, 0x702e, 0x00ee, 0x0005, 0x00f6, - 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x19e8, 0x7620, 0x2660, 0x2678, 0x2039, 0x0001, - 0x87ff, 0x0904, 0xa702, 0x8cff, 0x0904, 0xa702, 0x6020, 0x9086, - 0x0006, 0x1904, 0xa6fd, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904, - 0xa6fd, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0xa6fd, - 0x85ff, 0x0120, 0x605c, 0x9106, 0x1904, 0xa6fd, 0x7030, 0x9c06, - 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084, - 0x0148, 0x6827, 0x0001, 0x080c, 0x8a4b, 0x080c, 0xa78a, 0x7033, - 0x0000, 0x0428, 0x080c, 0x8a4b, 0x6820, 0xd0b4, 0x0110, 0x68a7, - 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7033, + 0x76dc, 0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, + 0x96b4, 0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, + 0x636a, 0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, + 0x6067, 0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, + 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, + 0xffff, 0x7814, 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, + 0xa838, 0x60c6, 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, + 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0058, + 0x6028, 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x2011, 0xffff, 0x080c, + 0x2adc, 0x2001, 0x00b2, 0x2010, 0x900e, 0x080c, 0x2aeb, 0x2009, + 0x07d0, 0x080c, 0x88e9, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, + 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, + 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, + 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, + 0x3474, 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, + 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, + 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, + 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, + 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, + 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, + 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, + 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, + 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, + 0x95d5, 0x60d7, 0x0000, 0xba84, 0x629e, 0x00f6, 0x2079, 0x0140, + 0x7803, 0x0000, 0x00fe, 0x900e, 0x2011, 0x0092, 0x080c, 0x2aeb, + 0x2009, 0x07d0, 0x080c, 0x88e9, 0x003e, 0x004e, 0x005e, 0x006e, + 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, + 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, + 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, + 0x7480, 0x7820, 0x0002, 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fea, + 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fec, 0x9fea, 0x9fea, + 0x9fea, 0x9fea, 0x080c, 0x0d79, 0xb884, 0x609e, 0x7814, 0x2048, + 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, + 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, + 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, + 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, + 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb884, 0x609e, + 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, + 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, + 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, + 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x607a, 0x607f, 0x0000, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, + 0x60c6, 0xa834, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0x080c, 0xa8cc, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, + 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x88e9, 0x003e, 0x004e, + 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40, + 0x9294, 0x00ff, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x686b, + 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, + 0x080c, 0x88db, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, + 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x88db, 0x001e, + 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, + 0x0000, 0x2001, 0x19f5, 0x2003, 0x0000, 0x0c88, 0x0006, 0x0016, + 0x0026, 0x2009, 0x1804, 0x2011, 0x0009, 0x080c, 0x2aeb, 0x002e, + 0x001e, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x080c, 0xaaf7, + 0x0106, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026, + 0x2009, 0x1804, 0x2011, 0x0008, 0x080c, 0x2aeb, 0x002e, 0x001e, + 0x010e, 0x090c, 0xab13, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, + 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, + 0x0100, 0x2069, 0x0140, 0x080c, 0x769d, 0x1510, 0x2001, 0x1a0e, + 0x2004, 0x9005, 0x1904, 0xa11a, 0x080c, 0x773f, 0x11a8, 0x2069, + 0x0380, 0x6843, 0x0101, 0x6844, 0xd084, 0x1de8, 0x2061, 0x0100, + 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0d79, 0x6843, + 0x0100, 0x080c, 0x88db, 0x04b0, 0x00c6, 0x2061, 0x19e9, 0x00f0, + 0x6904, 0x9194, 0x4000, 0x0598, 0x080c, 0xa09b, 0x080c, 0x2ab2, + 0x00c6, 0x2061, 0x19e9, 0x6134, 0x9192, 0x0008, 0x1278, 0x8108, + 0x6136, 0x080c, 0xaaf7, 0x6130, 0x080c, 0xab13, 0x00ce, 0x81ff, + 0x01c8, 0x080c, 0x88db, 0x080c, 0xa08e, 0x00a0, 0x080c, 0xaaf7, + 0x6130, 0x91e5, 0x0000, 0x0150, 0x080c, 0xebfd, 0x080c, 0x88e4, + 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafec, 0x080c, 0xab13, + 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, + 0x1a0e, 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6134, + 0x9192, 0x0003, 0x1ad8, 0x8108, 0x6136, 0x00ce, 0x080c, 0x88db, + 0x080c, 0x6033, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, + 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x88f1, + 0x080c, 0xaaf7, 0x2001, 0x0387, 0x2003, 0x0202, 0x2071, 0x19e9, + 0x714c, 0x81ff, 0x0904, 0xa1d4, 0x2061, 0x0100, 0x2069, 0x0140, + 0x080c, 0x769d, 0x1518, 0x0036, 0x2019, 0x0002, 0x080c, 0xa391, + 0x003e, 0x080c, 0xebfd, 0x704c, 0x9065, 0x0180, 0x2009, 0x004a, + 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, + 0x2009, 0x004a, 0x6003, 0x0003, 0x080c, 0xafec, 0x2001, 0x0386, + 0x2003, 0x5040, 0x080c, 0x773f, 0x0804, 0xa1d4, 0x6904, 0xd1f4, + 0x0904, 0xa1e1, 0x080c, 0x2ab2, 0x00c6, 0x704c, 0x9065, 0x090c, + 0x0d79, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1520, 0x61c8, 0x60c4, + 0x9105, 0x1500, 0x714c, 0x9188, 0x0011, 0x2104, 0xd0e4, 0x01d0, + 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x15e0, + 0x0010, 0xc0e4, 0x200a, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, + 0x6016, 0x704c, 0x2060, 0x080c, 0x9851, 0x2009, 0x0049, 0x080c, + 0xafec, 0x0450, 0x080c, 0xebfd, 0x704c, 0x9065, 0x9086, 0x1b56, + 0x1158, 0x080c, 0xadbe, 0x1500, 0x2061, 0x1b56, 0x6064, 0x8000, + 0x6066, 0x080c, 0x6033, 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, + 0xa391, 0x003e, 0x714c, 0x2160, 0x2009, 0x004a, 0x6220, 0x9296, + 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, + 0x6003, 0x0003, 0x080c, 0xafec, 0x2001, 0x0387, 0x2003, 0x0200, + 0x080c, 0xab13, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, + 0x0005, 0xd1ec, 0x1904, 0xa17a, 0x0804, 0xa17c, 0x0026, 0x00e6, + 0x2071, 0x19e9, 0x706c, 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c, + 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, + 0x0006, 0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x2aeb, + 0x0048, 0x928e, 0x0009, 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016, + 0x080c, 0x2aeb, 0x00ee, 0x002e, 0x0005, 0x9036, 0x2001, 0x19f3, + 0x2004, 0x9005, 0x0128, 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8, + 0x9085, 0x0001, 0x0005, 0x00f6, 0x2079, 0x19e9, 0x610c, 0x9006, + 0x600e, 0x6044, 0xc0fc, 0x6046, 0x86ff, 0x1140, 0x7824, 0x9c06, + 0x1118, 0x7826, 0x782a, 0x0050, 0x792a, 0x0040, 0x00c6, 0x2660, + 0x610e, 0x00ce, 0x7824, 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa458, + 0x080c, 0xce24, 0x00fe, 0x0005, 0x080c, 0x9cf3, 0x7003, 0x1200, + 0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, + 0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, + 0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, + 0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa06b, 0x080c, + 0x9cf3, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, + 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b, + 0x0156, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x080c, 0x89a9, 0x20a9, + 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, + 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, + 0x0002, 0x1f04, 0xa27f, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa06b, + 0x0016, 0x0026, 0x080c, 0x9d1a, 0x080c, 0x9d2c, 0x9e80, 0x0004, + 0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, + 0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, + 0x0004, 0x8003, 0x60c2, 0x080c, 0xa06b, 0x002e, 0x001e, 0x0005, + 0x20a9, 0x0010, 0x4003, 0x080c, 0xa8d7, 0x20a1, 0x0240, 0x22a8, + 0x4003, 0x0c68, 0x080c, 0x9cf3, 0x7003, 0x6200, 0x7808, 0x700e, + 0x60c3, 0x0008, 0x0804, 0xa06b, 0x0016, 0x0026, 0x080c, 0x9cf3, + 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, + 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, + 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, + 0xa06b, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2071, 0x19e9, 0x7010, 0x2060, 0x8cff, 0x0188, + 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c, 0x600c, 0x0006, 0x080c, + 0xd0c6, 0x600f, 0x0000, 0x080c, 0xaf4e, 0x080c, 0xa458, 0x00ce, + 0x0c68, 0x2c00, 0x7012, 0x700e, 0x012e, 0x000e, 0x00ce, 0x00ee, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, + 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x19e9, 0x7030, 0x2060, 0x8cff, 0x0548, 0x080c, 0xa09b, 0x6ac0, + 0x68c3, 0x0000, 0x080c, 0x88e4, 0x00c6, 0x2061, 0x0100, 0x080c, + 0xaa28, 0x00ce, 0x20a9, 0x01f4, 0x04b1, 0x080c, 0x97f6, 0x6044, + 0xd0ac, 0x1128, 0x2001, 0x1989, 0x2004, 0x604a, 0x0020, 0x2009, + 0x0013, 0x080c, 0xafec, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, + 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, + 0x88e4, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, + 0x0008, 0x68c3, 0x0000, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x20a9, + 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, + 0x7804, 0x9084, 0x4000, 0x190c, 0x2ab2, 0x0090, 0xd084, 0x0118, + 0x6827, 0x0001, 0x0010, 0x1f04, 0xa373, 0x7804, 0x9084, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, + 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x0380, 0x701c, 0x0006, 0x701f, 0x0202, 0x2071, 0x19e9, 0x704c, + 0x2060, 0x8cff, 0x0904, 0xa414, 0x080c, 0xad70, 0x0904, 0xa414, + 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xa414, + 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, + 0x69c6, 0x68cb, 0x0008, 0x080c, 0x88f1, 0x080c, 0x1e61, 0x2001, + 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, + 0x0008, 0x692e, 0x0016, 0x2009, 0x0040, 0x080c, 0x223d, 0x001e, + 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, + 0x9084, 0x4000, 0x190c, 0x2ab2, 0x0090, 0xd08c, 0x0118, 0x6827, + 0x0002, 0x0010, 0x1f04, 0xa3e2, 0x7804, 0x9084, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x6827, + 0x4000, 0x6824, 0x83ff, 0x1180, 0x2009, 0x0049, 0x6020, 0x9086, + 0x0009, 0x0150, 0x080c, 0x9851, 0x6044, 0xd0ac, 0x1118, 0x6003, + 0x0002, 0x0010, 0x080c, 0xafec, 0x000e, 0x2071, 0x0380, 0xd08c, + 0x1110, 0x701f, 0x0200, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, + 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005, + 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a3e, 0x012e, + 0x00de, 0x0005, 0x080c, 0x9e4b, 0x7047, 0x1000, 0x0098, 0x080c, + 0x9e4b, 0x7047, 0x4000, 0x0070, 0x080c, 0x9e4b, 0x7047, 0x2000, + 0x0048, 0x080c, 0x9e4b, 0x7047, 0x0400, 0x0020, 0x080c, 0x9e4b, + 0x7047, 0x0200, 0x785c, 0x7032, 0x60c3, 0x0020, 0x0804, 0xa06b, + 0x00e6, 0x2071, 0x19e9, 0x702c, 0x9005, 0x0110, 0x8001, 0x702e, + 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7620, 0x2660, + 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xa4fd, 0x8cff, 0x0904, + 0xa4fd, 0x6020, 0x9086, 0x0006, 0x1904, 0xa4f8, 0x88ff, 0x0138, + 0x2800, 0x9c06, 0x1904, 0xa4f8, 0x2039, 0x0000, 0x0050, 0x6010, + 0x9b06, 0x1904, 0xa4f8, 0x85ff, 0x0120, 0x605c, 0x9106, 0x1904, + 0xa4f8, 0x7030, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, + 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x88e4, + 0x080c, 0xa585, 0x7033, 0x0000, 0x0428, 0x080c, 0x88e4, 0x6820, + 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, + 0x080c, 0xa585, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, + 0x080c, 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x7020, 0x9c36, 0x1110, 0x660c, 0x7622, 0x701c, + 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x701e, 0x0010, + 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, + 0x2048, 0x080c, 0xcc31, 0x0110, 0x080c, 0xe738, 0x009e, 0x080c, + 0xaf89, 0x080c, 0xa458, 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa473, + 0x2c78, 0x600c, 0x2060, 0x0804, 0xa473, 0x9006, 0x012e, 0x000e, + 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, + 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, + 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x19e9, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0904, 0xa574, + 0x6020, 0x9086, 0x0006, 0x1904, 0xa56f, 0x87ff, 0x0128, 0x2700, + 0x9c06, 0x1904, 0xa56f, 0x0048, 0x6010, 0x9b06, 0x1904, 0xa56f, + 0x85ff, 0x0118, 0x605c, 0x9106, 0x15d0, 0x704c, 0x9c06, 0x1178, + 0x0036, 0x2019, 0x0001, 0x080c, 0xa391, 0x703f, 0x0000, 0x9006, + 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xade0, 0x003e, 0x7048, + 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x6014, 0x2048, 0x080c, 0xcc31, 0x0110, 0x080c, 0xe738, + 0x080c, 0xaf89, 0x87ff, 0x1198, 0x00ce, 0x0804, 0xa51d, 0x2c78, + 0x600c, 0x2060, 0x0804, 0xa51d, 0x9006, 0x012e, 0x000e, 0x002e, + 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, + 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e9, + 0x9006, 0x7032, 0x700a, 0x7004, 0x9086, 0x0003, 0x0158, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, + 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x2c10, + 0x7648, 0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, + 0x7048, 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, + 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, + 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, 0x97f6, 0x9085, 0x0001, + 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, + 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, + 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904, 0xa672, + 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0xa66d, + 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, + 0xa644, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, - 0x2001, 0x0100, 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, - 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7020, - 0x9c36, 0x1110, 0x660c, 0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, - 0x9f36, 0x0118, 0x2f00, 0x701e, 0x0010, 0x701f, 0x0000, 0x660c, - 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, - 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c, 0xcf19, - 0x0110, 0x080c, 0xea30, 0x009e, 0x080c, 0xb1a7, 0x080c, 0xa65d, - 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa678, 0x2c78, 0x600c, 0x2060, - 0x0804, 0xa678, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5, - 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066, - 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x7648, - 0x2660, 0x2678, 0x8cff, 0x0904, 0xa779, 0x6020, 0x9086, 0x0006, - 0x1904, 0xa774, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0xa774, - 0x0048, 0x6010, 0x9b06, 0x1904, 0xa774, 0x85ff, 0x0118, 0x605c, - 0x9106, 0x15d0, 0x704c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001, - 0x080c, 0xa596, 0x703f, 0x0000, 0x9006, 0x704e, 0x706a, 0x7052, - 0x706e, 0x080c, 0xaff4, 0x003e, 0x7048, 0x9c36, 0x1110, 0x660c, - 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, - 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, - 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, - 0x080c, 0xcf19, 0x0110, 0x080c, 0xea30, 0x080c, 0xb1a7, 0x87ff, - 0x1198, 0x00ce, 0x0804, 0xa722, 0x2c78, 0x600c, 0x2060, 0x0804, - 0xa722, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, - 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, - 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e8, 0x9006, 0x7032, 0x700a, - 0x7004, 0x9086, 0x0003, 0x0158, 0x2001, 0x1800, 0x2004, 0x9086, - 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, - 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, - 0x2091, 0x8000, 0x2071, 0x19e8, 0x2c10, 0x7648, 0x2660, 0x2678, - 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7048, 0x9c36, 0x1110, - 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, - 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x2c00, 0x9f06, - 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, - 0x0040, 0x090c, 0x99ed, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, - 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, - 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, - 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x7610, - 0x2660, 0x2678, 0x8cff, 0x0904, 0xa877, 0x6010, 0x00b6, 0x2058, - 0xb8a0, 0x00be, 0x9206, 0x1904, 0xa872, 0x7030, 0x9c06, 0x1520, - 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xa849, 0x080c, 0xa2a0, - 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7033, 0x0000, 0x0036, 0x2069, - 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, - 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, 0x0100, 0x6824, 0xd084, - 0x0110, 0x6827, 0x0001, 0x003e, 0x7010, 0x9c36, 0x1110, 0x660c, - 0x7612, 0x700c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, - 0x700e, 0x0010, 0x700f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, - 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd121, - 0x1180, 0x080c, 0x3344, 0x080c, 0xd132, 0x1518, 0x080c, 0xbb5c, - 0x0400, 0x080c, 0xa78a, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, - 0x0898, 0x080c, 0xd132, 0x1118, 0x080c, 0xbb5c, 0x0090, 0x6014, - 0x2048, 0x080c, 0xcf19, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, - 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x7006, 0x080c, - 0xd10c, 0x080c, 0xd3ae, 0x080c, 0xb1a7, 0x080c, 0xa65d, 0x00ce, - 0x0804, 0xa7f2, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa7f2, 0x012e, - 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, - 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xea30, 0x0c08, - 0x00d6, 0x080c, 0x9f43, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, - 0x0014, 0x20e1, 0x0001, 0x2099, 0x1989, 0x20e9, 0x0000, 0x20a1, - 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, - 0x080c, 0xa270, 0x00de, 0x0005, 0x080c, 0x9f43, 0x700b, 0x0800, - 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, - 0x782c, 0x7026, 0x7860, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, - 0x7860, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0xa270, - 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, - 0xd5bb, 0x00de, 0x1904, 0xa925, 0x080c, 0x9ef8, 0x7003, 0x1300, - 0x782c, 0x080c, 0xaa34, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, - 0x7810, 0x2058, 0xbaa0, 0x080c, 0xb094, 0x11d8, 0x9286, 0x007e, - 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, - 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, - 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, - 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, - 0x00c0, 0xb884, 0x700e, 0x00a8, 0x080c, 0xb094, 0x1130, 0x7810, - 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181f, - 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, - 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, - 0x00de, 0x080c, 0xa270, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, - 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, - 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xa9a4, - 0x9186, 0x0005, 0x0904, 0xa98c, 0x9186, 0x0004, 0x05f0, 0x9186, - 0x0008, 0x0904, 0xa995, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, - 0x1700, 0x080c, 0xaa11, 0x0005, 0x080c, 0xa9d2, 0x00d6, 0x0026, - 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x6a44, 0xd2fc, 0x11f8, - 0x0002, 0xa96c, 0xa977, 0xa96e, 0xa977, 0xa973, 0xa96c, 0xa96c, - 0xa977, 0xa977, 0xa977, 0xa977, 0xa96c, 0xa96c, 0xa96c, 0xa96c, - 0xa96c, 0xa977, 0xa96c, 0xa977, 0x080c, 0x0d85, 0x6824, 0xd0e4, - 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, - 0x7022, 0x6830, 0x7026, 0x0804, 0xa9cb, 0x080c, 0xa9d2, 0x00d6, - 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, - 0x1108, 0x900e, 0x0804, 0xa9cb, 0x080c, 0xa9d2, 0x00d6, 0x0026, - 0x792c, 0x2168, 0x2009, 0x4000, 0x04b0, 0x04e1, 0x00d6, 0x0026, - 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005, 0x0118, 0x9286, - 0x0002, 0x1108, 0x900e, 0x0438, 0x0469, 0x00d6, 0x0026, 0x792c, - 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096, 0x2048, 0xa9ac, - 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103, 0x7022, 0x7226, - 0x792c, 0x9180, 0x0011, 0x2004, 0xd0fc, 0x1148, 0x9180, 0x0000, - 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, - 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, - 0x0804, 0xa270, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, - 0x9f43, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, - 0x7810, 0x2058, 0xb8a0, 0x080c, 0xb094, 0x1118, 0x9092, 0x007e, - 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, - 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0xbc84, - 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, - 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, - 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, - 0x0005, 0x080c, 0x9f43, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, - 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x080c, 0x9eef, - 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, - 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, - 0x60c3, 0x0010, 0x0804, 0xa270, 0x00e6, 0x2071, 0x0240, 0x0006, - 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8d4, 0xd084, 0x0120, - 0x784c, 0x702a, 0x7850, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, - 0x0005, 0x080c, 0x9f3a, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, - 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x00a9, 0x7914, 0x712a, - 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x2a04, 0x0228, - 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa293, - 0x080c, 0x8a42, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7860, - 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, - 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, - 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, - 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, - 0xaaf1, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, - 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, - 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, - 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, - 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, - 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, - 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, - 0xc1d5, 0x2102, 0x2009, 0x19b3, 0x210c, 0x009e, 0x918d, 0x0092, - 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x0026, 0x2110, 0x900e, - 0x080c, 0x2ae2, 0x002e, 0x0005, 0x2009, 0x0009, 0x00a0, 0x2009, - 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009, 0x000c, 0x0058, - 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028, 0x2009, 0x000f, - 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x080c, 0x9ef8, 0x0016, - 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, 0x2001, - 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, 0x2001, 0x197c, 0x2004, - 0x9086, 0xaaaa, 0x1904, 0xab96, 0x7003, 0x5400, 0x00c6, 0x2061, - 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, - 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, 0x918c, 0xff00, 0x7112, - 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, 0x9290, 0x0006, 0x2104, - 0x2012, 0x8108, 0x8210, 0x1f04, 0xab27, 0x20a9, 0x0004, 0x2009, - 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xab31, 0xa860, - 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2009, 0x0006, 0x20a9, - 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00d6, - 0x2069, 0x0200, 0x080c, 0xaadc, 0x00de, 0x2071, 0x0240, 0x2011, - 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, - 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, - 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0xa85c, 0x9080, 0x0031, - 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, - 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, - 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1168, - 0x080c, 0x779e, 0x0150, 0x6028, 0xc0bd, 0x602a, 0x2009, 0x1804, - 0x2011, 0x0029, 0x080c, 0x2ae2, 0x0010, 0x080c, 0xa270, 0x080c, - 0x8a42, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00e6, 0x2071, - 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, 0x7002, 0x7007, 0xffff, - 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, 0x0804, 0xab0c, 0x080c, - 0x9ef8, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, - 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, 0x9084, 0x00ff, 0xa998, - 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0xa99c, 0x918c, 0xff00, - 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, 0xa998, 0x918c, 0xff00, - 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0x910d, 0x7112, 0x6180, - 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, - 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, - 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, 0x0004, 0x2009, 0x1805, - 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xabe8, 0x20a9, 0x0002, - 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xabf2, - 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, 0xaadc, 0x001e, 0x00de, - 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, 0x1803, 0x2011, 0x0240, - 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xac08, 0x2009, 0x0008, - 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dd0, 0x9006, 0x20a9, - 0x0008, 0x2012, 0x8210, 0x1f04, 0xac19, 0x00ce, 0x60c3, 0x004c, - 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa270, 0x080c, 0x8a42, - 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00d6, 0x9290, 0x0018, - 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813, 0x0000, 0x22a8, - 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292, 0x0020, 0x0008, - 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff, 0x0120, 0x6810, - 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6, - 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071, - 0x19e8, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904, 0xacd9, 0x7030, - 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xacab, - 0x080c, 0xa2a0, 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7033, 0x0000, - 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, - 0x0100, 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7010, 0x9c36, - 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140, 0x2c00, 0x9f36, - 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000, 0x660c, 0x0066, - 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, - 0x080c, 0xd121, 0x1180, 0x080c, 0x3344, 0x080c, 0xd132, 0x1518, - 0x080c, 0xbb5c, 0x0400, 0x080c, 0xa78a, 0x6824, 0xd084, 0x09b0, - 0x6827, 0x0001, 0x0898, 0x080c, 0xd132, 0x1118, 0x080c, 0xbb5c, - 0x0090, 0x6014, 0x2048, 0x080c, 0xcf19, 0x0168, 0x6020, 0x9086, - 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, - 0x7012, 0x080c, 0xd10c, 0x080c, 0xd3ae, 0x080c, 0xb1a7, 0x080c, - 0xa65d, 0x00ce, 0x0804, 0xac5c, 0x2c78, 0x600c, 0x2060, 0x0804, - 0xac5c, 0x7013, 0x0000, 0x700f, 0x0000, 0x012e, 0x006e, 0x009e, - 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, - 0x0006, 0x1d08, 0x080c, 0xea30, 0x08f0, 0x00f6, 0x0036, 0x2079, - 0x0380, 0x7b18, 0xd3bc, 0x1de8, 0x7832, 0x7936, 0x7a3a, 0x781b, - 0x8080, 0x003e, 0x00fe, 0x0005, 0x0016, 0x2001, 0x0382, 0x2004, - 0x9084, 0x0007, 0x9086, 0x0001, 0x1188, 0x2001, 0x0015, 0x0c29, - 0x2009, 0x1000, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, - 0x0003, 0x0120, 0x8109, 0x1db0, 0x080c, 0x0d85, 0x001e, 0x0005, - 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0003, 0x1120, - 0x2001, 0x0380, 0x2003, 0x0001, 0x0005, 0x0156, 0x0016, 0x0026, - 0x00e6, 0x900e, 0x2071, 0x19e8, 0x0469, 0x0106, 0x0190, 0x7004, - 0x9086, 0x0003, 0x0148, 0x20a9, 0x1000, 0x6044, 0xd0fc, 0x01d8, - 0x1f04, 0xad35, 0x080c, 0x0d85, 0x080c, 0xacfc, 0x6044, 0xd0fc, - 0x0190, 0x7030, 0x9c06, 0x1148, 0x080c, 0x99ed, 0x6044, 0xd0dc, - 0x0150, 0xc0dc, 0x6046, 0x700a, 0x7042, 0x704c, 0x9c06, 0x190c, - 0x0d85, 0x080c, 0x9a48, 0x010e, 0x1919, 0x00ee, 0x002e, 0x001e, - 0x015e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, - 0x0003, 0x0005, 0x0126, 0x2091, 0x2400, 0x7808, 0xd0a4, 0x190c, - 0x0d7e, 0xd09c, 0x0128, 0x7820, 0x908c, 0xf000, 0x11b8, 0x0012, - 0x012e, 0x0005, 0xad82, 0xadc0, 0xadef, 0xae37, 0xae47, 0xae58, - 0xae67, 0xae75, 0xaea2, 0xaea6, 0xad82, 0xad82, 0xaea9, 0xaec5, - 0xad82, 0xad82, 0x080c, 0x0d85, 0x012e, 0x0005, 0x2060, 0x6044, - 0xd0bc, 0x0140, 0xc0bc, 0x6046, 0x6000, 0x908a, 0x0010, 0x1a0c, - 0x0d85, 0x0012, 0x012e, 0x0005, 0xada7, 0xada9, 0xada7, 0xadaf, - 0xada7, 0xada7, 0xada7, 0xada7, 0xada7, 0xada9, 0xada7, 0xada9, - 0xada7, 0xada9, 0xada7, 0xada7, 0xada7, 0xada9, 0xada7, 0x080c, - 0x0d85, 0x2009, 0x0013, 0x080c, 0xb20a, 0x012e, 0x0005, 0x6014, - 0x2048, 0xa87c, 0xd0dc, 0x0130, 0x080c, 0x8c19, 0x080c, 0xb16c, - 0x012e, 0x0005, 0x2009, 0x0049, 0x080c, 0xb20a, 0x012e, 0x0005, - 0x080c, 0xacfc, 0x2001, 0x1a0d, 0x2003, 0x0000, 0x7030, 0x9065, - 0x1130, 0x7004, 0x9086, 0x0003, 0x01e0, 0x080c, 0x0d85, 0x7034, - 0x9092, 0xc350, 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, - 0x0110, 0x7007, 0x0000, 0x781f, 0x0808, 0x0058, 0x080c, 0xb0c0, - 0x0140, 0x080c, 0xeeee, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, - 0xb20a, 0x781f, 0x0100, 0x080c, 0xad18, 0x012e, 0x0005, 0x080c, - 0xacfc, 0x714c, 0x81ff, 0x1128, 0x2011, 0x1a10, 0x2013, 0x0000, - 0x04c0, 0x2061, 0x0100, 0x7150, 0x9192, 0x7530, 0x1678, 0x8108, - 0x7152, 0x714c, 0x9186, 0x1b55, 0x0120, 0x2001, 0x0391, 0x2003, - 0x0400, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1160, 0x6014, - 0x9084, 0x1984, 0x9085, 0x0012, 0x714c, 0x918e, 0x1b55, 0x1108, - 0xc0fd, 0x6016, 0x00b0, 0x714c, 0x9188, 0x0008, 0x210c, 0x918e, - 0x0009, 0x0d68, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, 0x714c, - 0x918e, 0x1b55, 0x1108, 0xc0fd, 0x6016, 0x0018, 0x706c, 0xc085, - 0x706e, 0x781f, 0x0200, 0x080c, 0xad18, 0x012e, 0x0005, 0x080c, - 0xacfc, 0x714c, 0x2160, 0x6003, 0x0003, 0x2009, 0x004a, 0x080c, - 0xb20a, 0x781f, 0x0200, 0x080c, 0xad18, 0x012e, 0x0005, 0x7808, - 0xd09c, 0x0de8, 0x7820, 0x2060, 0x6003, 0x0003, 0x080c, 0xacfc, - 0x080c, 0x1dcc, 0x781f, 0x0400, 0x080c, 0xad18, 0x012e, 0x0005, - 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060, 0x080c, 0xacfc, 0x080c, - 0x1e14, 0x781f, 0x0400, 0x080c, 0xad18, 0x012e, 0x0005, 0x7030, - 0x9065, 0x0148, 0x6044, 0xc0bc, 0x6046, 0x7104, 0x9186, 0x0003, - 0x0110, 0x080c, 0x9ab4, 0x012e, 0x0005, 0x00f6, 0x703c, 0x9086, - 0x0002, 0x0528, 0x704c, 0x907d, 0x0510, 0x7844, 0xc0bc, 0x7846, - 0x7820, 0x9086, 0x0009, 0x0118, 0x080c, 0xa1ca, 0x00c0, 0x7828, - 0xd0fc, 0x1118, 0x080c, 0xa149, 0x0090, 0x2001, 0x1837, 0x2004, - 0x9084, 0x0028, 0x1130, 0x2001, 0x197c, 0x2004, 0x9086, 0xaaaa, - 0x1120, 0x2001, 0x0387, 0x2003, 0x1000, 0x080c, 0xa0ce, 0x00fe, - 0x012e, 0x0005, 0x080c, 0x7840, 0x012e, 0x0005, 0x080c, 0x0d85, - 0x0005, 0x2009, 0x1b66, 0x2104, 0xd0bc, 0x01a8, 0xc0bc, 0x200a, - 0x2009, 0x010b, 0x2104, 0x9085, 0x0002, 0x200a, 0x2009, 0x0101, - 0x2104, 0xc0ac, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0x1984, - 0x9085, 0x8092, 0x200a, 0x012e, 0x0005, 0x080c, 0x8a58, 0x2009, - 0x010b, 0x2104, 0xd08c, 0x01a8, 0xc08c, 0x200a, 0x2001, 0x1848, - 0x2004, 0xd094, 0x1130, 0x2009, 0x0101, 0x2104, 0x9085, 0x0020, - 0x200a, 0x2009, 0x1b66, 0x200b, 0x0000, 0x2001, 0x001b, 0x080c, - 0xaced, 0x012e, 0x0005, 0x00e6, 0x2071, 0x19e8, 0x6044, 0xc0bc, - 0x6046, 0xd0fc, 0x01b8, 0x704c, 0x9c06, 0x1190, 0x2019, 0x0001, - 0x080c, 0xa596, 0x704f, 0x0000, 0x2001, 0x0109, 0x2004, 0xd08c, - 0x1138, 0x2001, 0x0108, 0x2004, 0xd0bc, 0x1110, 0x703f, 0x0000, - 0x080c, 0xa7a1, 0x00ee, 0x0005, 0x0026, 0x7010, 0x9c06, 0x1178, - 0x080c, 0xa65d, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, - 0x7212, 0x600f, 0x0000, 0x0010, 0x7212, 0x720e, 0x9006, 0x002e, - 0x0005, 0x0026, 0x7020, 0x9c06, 0x1178, 0x080c, 0xa65d, 0x6044, - 0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, 0x7222, 0x600f, 0x0000, - 0x0010, 0x7222, 0x721e, 0x9006, 0x002e, 0x0005, 0x00d6, 0x0036, - 0x7830, 0x9c06, 0x1558, 0x2069, 0x0100, 0x68c0, 0x9005, 0x01f8, - 0x080c, 0x8a4b, 0x080c, 0xa2a0, 0x68c3, 0x0000, 0x080c, 0xa78a, - 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, - 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, 0x0100, 0x6824, - 0xd084, 0x0110, 0x6827, 0x0001, 0x9085, 0x0001, 0x0038, 0x7808, - 0xc0ad, 0x780a, 0x6003, 0x0009, 0x630a, 0x9006, 0x003e, 0x00de, - 0x0005, 0x0016, 0x0026, 0x0036, 0x6100, 0x2019, 0x0100, 0x2001, - 0x0382, 0x2004, 0xd09c, 0x0190, 0x00c6, 0x0126, 0x2091, 0x2800, - 0x0016, 0x0036, 0x080c, 0xad62, 0x003e, 0x001e, 0x012e, 0x00ce, - 0x6200, 0x2200, 0x9106, 0x0d58, 0x2200, 0x0010, 0x8319, 0x1d38, - 0x003e, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x080c, - 0xacfc, 0x0106, 0x2071, 0x19e8, 0x2069, 0x0100, 0x704c, 0x2060, - 0x9086, 0x1b55, 0x15b8, 0x6814, 0xd08c, 0x0188, 0x6817, 0x0010, - 0x2009, 0x0019, 0x8109, 0x1df0, 0x2001, 0x0032, 0x6920, 0xd1bc, - 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x6824, - 0xd08c, 0x0110, 0x6827, 0x0002, 0x68d0, 0x9005, 0x0118, 0x9082, - 0x0005, 0x0238, 0x6060, 0x8000, 0x6062, 0x2001, 0x0391, 0x2003, - 0x0400, 0x080c, 0x9a48, 0x682c, 0x9084, 0xfffd, 0x682e, 0x2001, - 0x1848, 0x2004, 0xd094, 0x1120, 0x6804, 0x9085, 0x0020, 0x6806, - 0x2069, 0x0000, 0x010e, 0x090c, 0xad18, 0x8dff, 0x00ce, 0x00de, - 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0xacfc, 0x0106, - 0x2071, 0x19e8, 0x2069, 0x0100, 0x080c, 0xaf84, 0x68d0, 0x9005, - 0x0158, 0x9082, 0x0005, 0x1240, 0x080c, 0x2b33, 0x2001, 0x0391, - 0x2003, 0x0400, 0x2069, 0x0000, 0x010e, 0x090c, 0xad18, 0x8dff, - 0x00ce, 0x00de, 0x00ee, 0x0005, 0x0016, 0x2001, 0x0134, 0x2004, - 0x9005, 0x0140, 0x9082, 0x0005, 0x1228, 0x2001, 0x0391, 0x2003, - 0x0404, 0x0020, 0x2001, 0x0391, 0x2003, 0x0400, 0x001e, 0x0005, - 0x00d6, 0x0156, 0x080c, 0x9f43, 0x7a14, 0x82ff, 0x0138, 0x7003, - 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, - 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, - 0x1110, 0xc38d, 0x0060, 0x080c, 0x779e, 0x1110, 0xc3ad, 0x0008, - 0xc3a5, 0x6adc, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, - 0x080c, 0x8b10, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, - 0x2071, 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, - 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xb03a, 0x60c3, 0x0020, - 0x080c, 0xa270, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x9f43, - 0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, - 0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, - 0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x19be, - 0x2204, 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, - 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, - 0x7022, 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, - 0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, - 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, - 0x001c, 0x015e, 0x0804, 0xa270, 0x0006, 0x2001, 0x1837, 0x2004, - 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, - 0x0002, 0x080c, 0xa635, 0x080c, 0xa516, 0x0036, 0x901e, 0x080c, - 0xa596, 0x003e, 0x0005, 0x080c, 0x3487, 0x0188, 0x0016, 0x00b6, - 0x00c6, 0x7010, 0x9085, 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, - 0x67b4, 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, - 0x00d6, 0x00f6, 0x7104, 0x9186, 0x0004, 0x1130, 0x7410, 0x9e90, - 0x0004, 0x9e98, 0x0003, 0x0088, 0x9186, 0x0001, 0x1130, 0x7420, - 0x9e90, 0x0008, 0x9e98, 0x0007, 0x0040, 0x9186, 0x0002, 0x1538, - 0x7428, 0x9e90, 0x000a, 0x9e98, 0x0009, 0x6110, 0x2468, 0x680c, - 0x907d, 0x01e8, 0x7810, 0x9106, 0x1128, 0x2f68, 0x780c, 0x907d, - 0x1dc8, 0x00a8, 0x780c, 0x680e, 0x7c0e, 0x2f12, 0x2304, 0x9f06, - 0x1108, 0x2d1a, 0x9006, 0x7032, 0x7036, 0x7004, 0x9086, 0x0003, - 0x0110, 0x7007, 0x0000, 0x9006, 0x00fe, 0x00de, 0x0005, 0x9085, - 0x0001, 0x0cd0, 0x2071, 0x188d, 0x7000, 0x9005, 0x0140, 0x2001, - 0x0812, 0x2071, 0x1800, 0x7076, 0x707a, 0x706b, 0xffd4, 0x2071, - 0x1800, 0x7074, 0x7056, 0x705b, 0x1ddc, 0x0005, 0x00e6, 0x0126, - 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0010, 0x0608, - 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x001c, - 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, 0x6003, - 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502, 0x1230, - 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1ddc, - 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7554, 0x9582, - 0x0010, 0x0600, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, + 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7010, + 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x080c, 0xce39, 0x1180, 0x080c, 0x332a, 0x080c, 0xce4a, + 0x1518, 0x080c, 0xb93c, 0x0400, 0x080c, 0xa585, 0x6824, 0xd084, + 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce4a, 0x1118, 0x080c, + 0xb93c, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc31, 0x0168, 0x6020, + 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, + 0x080c, 0x6f05, 0x080c, 0xce24, 0x080c, 0xd0c6, 0x080c, 0xaf89, + 0x080c, 0xa458, 0x00ce, 0x0804, 0xa5ed, 0x2c78, 0x600c, 0x2060, + 0x0804, 0xa5ed, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, + 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, + 0x080c, 0xe738, 0x0c08, 0x00d6, 0x080c, 0x9d3e, 0x7003, 0x0200, + 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x198a, + 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, + 0x0004, 0x7027, 0x7878, 0x080c, 0xa06b, 0x00de, 0x0005, 0x080c, + 0x9d3e, 0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, + 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, 0x7860, 0x9084, 0x00ff, + 0x9085, 0x0200, 0x7002, 0x7860, 0x9084, 0xff00, 0x8007, 0x7006, + 0x60c2, 0x0804, 0xa06b, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, + 0x2009, 0x0035, 0x080c, 0xd2d3, 0x00de, 0x1904, 0xa720, 0x080c, + 0x9cf3, 0x7003, 0x1300, 0x782c, 0x080c, 0xa82f, 0x2068, 0x6820, + 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0xae80, + 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, + 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, + 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, + 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, + 0x700a, 0xb814, 0x700e, 0x00c0, 0xb884, 0x700e, 0x00a8, 0x080c, + 0xae80, 0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, + 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, + 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, + 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, 0xa06b, 0x00be, 0x0005, + 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, + 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, + 0x0003, 0x0904, 0xa79f, 0x9186, 0x0005, 0x0904, 0xa787, 0x9186, + 0x0004, 0x05f0, 0x9186, 0x0008, 0x0904, 0xa790, 0x7807, 0x0037, + 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0xa80c, 0x0005, 0x080c, + 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, + 0x6a44, 0xd2fc, 0x11f8, 0x0002, 0xa767, 0xa772, 0xa769, 0xa772, + 0xa76e, 0xa767, 0xa767, 0xa772, 0xa772, 0xa772, 0xa772, 0xa767, + 0xa767, 0xa767, 0xa767, 0xa767, 0xa772, 0xa767, 0xa772, 0x080c, + 0x0d79, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, + 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0xa7c6, + 0x080c, 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, + 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x0804, 0xa7c6, 0x080c, + 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x04b0, + 0x04e1, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, + 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0438, 0x0469, + 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, + 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, + 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0011, 0x2004, 0xd0fc, + 0x1148, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, + 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, + 0x0018, 0x002e, 0x00de, 0x0804, 0xa06b, 0x00b6, 0x0036, 0x0046, + 0x0056, 0x0066, 0x080c, 0x9d3e, 0x9006, 0x7003, 0x0200, 0x7938, + 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0xae80, + 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c, + 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, + 0x0028, 0x901e, 0xbc84, 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, + 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, + 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, + 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9d3e, 0x7003, 0x0100, + 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, + 0xa06b, 0x080c, 0x9cea, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, + 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, + 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0xa06b, 0x00e6, + 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, + 0xb8d4, 0xd084, 0x0120, 0x784c, 0x702a, 0x7850, 0x702e, 0x00be, + 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9d35, 0x7003, 0x0100, + 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b, + 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, + 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, + 0x002e, 0x080c, 0xa08e, 0x080c, 0x88db, 0x0005, 0x0036, 0x0096, + 0x00d6, 0x00e6, 0x7860, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, + 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, + 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, + 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, + 0x2069, 0x0200, 0x080c, 0xa8ec, 0x00de, 0x20e9, 0x0000, 0x20a1, + 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, + 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, + 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, + 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, + 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, + 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, + 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b4, 0x210c, + 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, + 0x0026, 0x2110, 0x900e, 0x080c, 0x2aeb, 0x002e, 0x0005, 0x2009, + 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, + 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, + 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, + 0x080c, 0x9cf3, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, + 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, + 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xa991, 0x7003, + 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, + 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, + 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, + 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xa922, + 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, + 0x1f04, 0xa92c, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, + 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, + 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xa8d7, 0x00de, + 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, + 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, + 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, + 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x1168, 0x080c, 0x769d, 0x0150, 0x6028, 0xc0bd, + 0x602a, 0x2009, 0x1804, 0x2011, 0x0029, 0x080c, 0x2aeb, 0x0010, + 0x080c, 0xa06b, 0x080c, 0x88db, 0x00de, 0x009e, 0x002e, 0x001e, + 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, + 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, + 0x0804, 0xa907, 0x080c, 0x9cf3, 0x0016, 0x0026, 0x0096, 0x00d6, + 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, + 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, + 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, + 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, + 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, + 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, + 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, + 0xa9e3, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, + 0x8210, 0x1f04, 0xa9ed, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, + 0xa8d7, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, + 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, + 0xaa03, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, + 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaa14, + 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, + 0xa06b, 0x080c, 0x88db, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, + 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, + 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, + 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, + 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, + 0x2091, 0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff, + 0x0904, 0xaad4, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, + 0x9005, 0x0904, 0xaaa6, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c, + 0xa585, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, + 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, + 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x003e, 0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, + 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, + 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, + 0x2678, 0x600f, 0x0000, 0x080c, 0xce39, 0x1180, 0x080c, 0x332a, + 0x080c, 0xce4a, 0x1518, 0x080c, 0xb93c, 0x0400, 0x080c, 0xa585, + 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce4a, + 0x1118, 0x080c, 0xb93c, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc31, + 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, + 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x080c, 0xd0c6, + 0x080c, 0xaf89, 0x080c, 0xa458, 0x00ce, 0x0804, 0xaa57, 0x2c78, + 0x600c, 0x2060, 0x0804, 0xaa57, 0x7013, 0x0000, 0x700f, 0x0000, + 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe738, 0x08f0, + 0x00f6, 0x0036, 0x2079, 0x0380, 0x7b18, 0xd3bc, 0x1de8, 0x7832, + 0x7936, 0x7a3a, 0x781b, 0x8080, 0x003e, 0x00fe, 0x0005, 0x0016, + 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, 0x1188, + 0x2001, 0x0015, 0x0c29, 0x2009, 0x1000, 0x2001, 0x0382, 0x2004, + 0x9084, 0x0007, 0x9086, 0x0003, 0x0120, 0x8109, 0x1db0, 0x080c, + 0x0d79, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, + 0x9086, 0x0003, 0x1120, 0x2001, 0x0380, 0x2003, 0x0001, 0x0005, + 0x0156, 0x0016, 0x0026, 0x00e6, 0x900e, 0x2071, 0x19e9, 0x0469, + 0x0106, 0x0190, 0x7004, 0x9086, 0x0003, 0x0148, 0x20a9, 0x1000, + 0x6044, 0xd0fc, 0x01d8, 0x1f04, 0xab30, 0x080c, 0x0d79, 0x080c, + 0xaaf7, 0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06, 0x1148, 0x080c, + 0x97f6, 0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046, 0x700a, 0x7042, + 0x704c, 0x9c06, 0x190c, 0x0d79, 0x080c, 0x9851, 0x010e, 0x1919, + 0x00ee, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x0382, 0x2004, + 0x9084, 0x0007, 0x9086, 0x0003, 0x0005, 0x0126, 0x2091, 0x2400, + 0x7808, 0xd0a4, 0x190c, 0x0d72, 0xd09c, 0x0128, 0x7820, 0x908c, + 0xf000, 0x11b8, 0x0012, 0x012e, 0x0005, 0xab7d, 0xabbb, 0xabe5, + 0xac23, 0xac33, 0xac44, 0xac53, 0xac61, 0xac8e, 0xac92, 0xab7d, + 0xab7d, 0xac95, 0xacb1, 0xab7d, 0xab7d, 0x080c, 0x0d79, 0x012e, + 0x0005, 0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc, 0x6046, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0012, 0x012e, 0x0005, 0xaba2, + 0xaba4, 0xaba2, 0xabaa, 0xaba2, 0xaba2, 0xaba2, 0xaba2, 0xaba2, + 0xaba4, 0xaba2, 0xaba4, 0xaba2, 0xaba4, 0xaba2, 0xaba2, 0xaba2, + 0xaba4, 0xaba2, 0x080c, 0x0d79, 0x2009, 0x0013, 0x080c, 0xafec, + 0x012e, 0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc, 0x0130, 0x080c, + 0x8ab2, 0x080c, 0xaf4e, 0x012e, 0x0005, 0x2009, 0x0049, 0x080c, + 0xafec, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x2001, 0x1a0e, 0x2003, + 0x0000, 0x7030, 0x9065, 0x090c, 0x0d79, 0x7034, 0x9092, 0xc350, + 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, 0x0110, 0x7007, + 0x0000, 0x781f, 0x0808, 0x0058, 0x080c, 0xaeac, 0x0140, 0x080c, + 0xebfd, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafec, 0x781f, + 0x0100, 0x080c, 0xab13, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x714c, + 0x81ff, 0x1128, 0x2011, 0x1a11, 0x2013, 0x0000, 0x0470, 0x2061, + 0x0100, 0x7150, 0x9192, 0x7530, 0x1628, 0x8108, 0x7152, 0x714c, + 0x9186, 0x1b56, 0x0120, 0x2001, 0x0391, 0x2003, 0x0400, 0x9188, + 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984, + 0x9085, 0x0012, 0x6016, 0x0088, 0x714c, 0x9188, 0x0008, 0x210c, + 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, + 0x6016, 0x0018, 0x706c, 0xc085, 0x706e, 0x781f, 0x0200, 0x080c, + 0xab13, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x714c, 0x2160, 0x6003, + 0x0003, 0x2009, 0x004a, 0x080c, 0xafec, 0x781f, 0x0200, 0x080c, + 0xab13, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060, + 0x6003, 0x0003, 0x080c, 0xaaf7, 0x080c, 0x1de9, 0x781f, 0x0400, + 0x080c, 0xab13, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, + 0x2060, 0x080c, 0xaaf7, 0x080c, 0x1e31, 0x781f, 0x0400, 0x080c, + 0xab13, 0x012e, 0x0005, 0x7030, 0x9065, 0x0148, 0x6044, 0xc0bc, + 0x6046, 0x7104, 0x9186, 0x0003, 0x0110, 0x080c, 0x98bd, 0x012e, + 0x0005, 0x00f6, 0x703c, 0x9086, 0x0002, 0x0528, 0x704c, 0x907d, + 0x0510, 0x7844, 0xc0bc, 0x7846, 0x7820, 0x9086, 0x0009, 0x0118, + 0x080c, 0x9fc5, 0x00c0, 0x7828, 0xd0fc, 0x1118, 0x080c, 0x9f44, + 0x0090, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1130, 0x2001, + 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1120, 0x2001, 0x0387, 0x2003, + 0x1000, 0x080c, 0x9ec9, 0x00fe, 0x012e, 0x0005, 0x080c, 0x773f, + 0x012e, 0x0005, 0x080c, 0x0d79, 0x0005, 0x2009, 0x1b67, 0x2104, + 0xd0bc, 0x01a8, 0xc0bc, 0x200a, 0x2009, 0x010b, 0x2104, 0x9085, + 0x0002, 0x200a, 0x2009, 0x0101, 0x2104, 0xc0ac, 0x200a, 0x2009, + 0x0105, 0x2104, 0x9084, 0x1984, 0x9085, 0x8092, 0x200a, 0x012e, + 0x0005, 0x080c, 0x88f1, 0x2009, 0x010b, 0x2104, 0xd08c, 0x01a8, + 0xc08c, 0x200a, 0x2001, 0x1848, 0x2004, 0xd094, 0x1130, 0x2009, + 0x0101, 0x2104, 0x9085, 0x0020, 0x200a, 0x2009, 0x1b67, 0x200b, + 0x0000, 0x2001, 0x001b, 0x080c, 0xaae8, 0x012e, 0x0005, 0x00e6, + 0x2071, 0x19e9, 0x6044, 0xc0bc, 0x6046, 0xd0fc, 0x01b8, 0x704c, + 0x9c06, 0x1190, 0x2019, 0x0001, 0x080c, 0xa391, 0x704f, 0x0000, + 0x2001, 0x0109, 0x2004, 0xd08c, 0x1138, 0x2001, 0x0108, 0x2004, + 0xd0bc, 0x1110, 0x703f, 0x0000, 0x080c, 0xa59c, 0x00ee, 0x0005, + 0x0026, 0x7010, 0x9c06, 0x1178, 0x080c, 0xa458, 0x6044, 0xc0fc, + 0x6046, 0x600c, 0x9015, 0x0120, 0x7212, 0x600f, 0x0000, 0x0010, + 0x7212, 0x720e, 0x9006, 0x002e, 0x0005, 0x0026, 0x7020, 0x9c06, + 0x1178, 0x080c, 0xa458, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015, + 0x0120, 0x7222, 0x600f, 0x0000, 0x0010, 0x7222, 0x721e, 0x9006, + 0x002e, 0x0005, 0x00d6, 0x0036, 0x7830, 0x9c06, 0x1558, 0x2069, + 0x0100, 0x68c0, 0x9005, 0x01f8, 0x080c, 0x88e4, 0x080c, 0xa09b, + 0x68c3, 0x0000, 0x080c, 0xa585, 0x2069, 0x0140, 0x6b04, 0x9384, + 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, + 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x9085, 0x0001, 0x0038, 0x7808, 0xc0ad, 0x780a, 0x6003, 0x0009, + 0x630a, 0x9006, 0x003e, 0x00de, 0x0005, 0x0016, 0x0026, 0x0036, + 0x6100, 0x2019, 0x0100, 0x2001, 0x0382, 0x2004, 0xd09c, 0x0190, + 0x00c6, 0x0126, 0x2091, 0x2800, 0x0016, 0x0036, 0x080c, 0xab5d, + 0x003e, 0x001e, 0x012e, 0x00ce, 0x6200, 0x2200, 0x9106, 0x0d58, + 0x2200, 0x0010, 0x8319, 0x1d38, 0x003e, 0x002e, 0x001e, 0x0005, + 0x00e6, 0x00d6, 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x19e9, + 0x2069, 0x0100, 0x704c, 0x2060, 0x9086, 0x1b56, 0x15b8, 0x6814, + 0xd08c, 0x0188, 0x6817, 0x0010, 0x2009, 0x0019, 0x8109, 0x1df0, + 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, + 0x918d, 0x0008, 0x692e, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002, + 0x68d0, 0x9005, 0x0118, 0x9082, 0x0005, 0x0238, 0x6060, 0x8000, + 0x6062, 0x2001, 0x0391, 0x2003, 0x0400, 0x080c, 0x9851, 0x682c, + 0x9084, 0xfffd, 0x682e, 0x2001, 0x1848, 0x2004, 0xd094, 0x1120, + 0x6804, 0x9085, 0x0020, 0x6806, 0x2069, 0x0000, 0x010e, 0x090c, + 0xab13, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6, + 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x19e9, 0x2069, 0x0100, + 0x080c, 0xad70, 0x68d0, 0x9005, 0x0158, 0x9082, 0x0005, 0x1240, + 0x080c, 0x2b3c, 0x2001, 0x0391, 0x2003, 0x0400, 0x2069, 0x0000, + 0x010e, 0x090c, 0xab13, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, + 0x0016, 0x2001, 0x0134, 0x2004, 0x9005, 0x0140, 0x9082, 0x0005, + 0x1228, 0x2001, 0x0391, 0x2003, 0x0404, 0x0020, 0x2001, 0x0391, + 0x2003, 0x0400, 0x001e, 0x0005, 0x00d6, 0x0156, 0x080c, 0x9d3e, + 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, + 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069, 0x1800, + 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060, 0x080c, + 0x769d, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110, + 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x89a9, 0x20a9, 0x0006, + 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250, 0x2305, 0x2072, + 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, + 0x1f04, 0xae26, 0x60c3, 0x0020, 0x080c, 0xa06b, 0x015e, 0x00de, + 0x0005, 0x0156, 0x080c, 0x9d3e, 0x7a14, 0x82ff, 0x0168, 0x9286, + 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100, 0x700b, + 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007, 0x001c, + 0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, 0x8007, 0x701a, 0x8210, + 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0, 0x9082, 0x007f, + 0x0248, 0x2001, 0x181f, 0x2004, 0x7022, 0x2001, 0x1820, 0x2004, + 0x7026, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7026, + 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, + 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa06b, + 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011, + 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, 0x080c, + 0xa311, 0x0036, 0x901e, 0x080c, 0xa391, 0x003e, 0x0005, 0x080c, + 0x346d, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020, + 0x7012, 0x2009, 0x007e, 0x080c, 0x6783, 0xb85c, 0xc0ac, 0xb85e, + 0x00ce, 0x00be, 0x001e, 0x0005, 0x00d6, 0x00f6, 0x7104, 0x9186, + 0x0004, 0x1120, 0x7410, 0x9e90, 0x0004, 0x0068, 0x9186, 0x0001, + 0x1120, 0x7420, 0x9e90, 0x0008, 0x0030, 0x9186, 0x0002, 0x1508, + 0x7428, 0x9e90, 0x000a, 0x6110, 0x2468, 0x680c, 0x907d, 0x01c8, + 0x7810, 0x9106, 0x1128, 0x2f68, 0x780c, 0x907d, 0x1dc8, 0x0088, + 0x780c, 0x680e, 0x7c0e, 0x2f12, 0x9006, 0x7032, 0x7036, 0x7004, + 0x9086, 0x0003, 0x0110, 0x7007, 0x0000, 0x9006, 0x00fe, 0x00de, + 0x0005, 0x9085, 0x0001, 0x0cd0, 0x2071, 0x188d, 0x7000, 0x9005, + 0x0140, 0x2001, 0x0812, 0x2071, 0x1800, 0x7076, 0x707a, 0x706b, + 0xffd4, 0x2071, 0x1800, 0x7074, 0x7056, 0x705b, 0x1ddc, 0x0005, + 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, + 0x0010, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, - 0x9502, 0x1228, 0x755a, 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, - 0x1ddc, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1ddc, 0x0a0c, 0x0d85, - 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85, 0x9006, 0x6006, - 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, - 0x0000, 0x601e, 0x605e, 0x6062, 0x6026, 0x602a, 0x602e, 0x6032, - 0x6036, 0x603a, 0x603e, 0x604a, 0x602a, 0x6046, 0x6042, 0x2061, - 0x1800, 0x6054, 0x8000, 0x6056, 0x0005, 0x9006, 0x600e, 0x6016, - 0x601a, 0x6012, 0x6022, 0x6002, 0x601e, 0x605e, 0x6062, 0x604a, - 0x6046, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x0005, 0x0006, - 0x6000, 0x9086, 0x0000, 0x01d8, 0x601c, 0xd084, 0x190c, 0x1ad3, - 0x6023, 0x0007, 0x2001, 0x1986, 0x2004, 0x0006, 0x9082, 0x0051, - 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xece1, 0x604b, 0x0000, - 0x6044, 0xd0fc, 0x1131, 0x9006, 0x6046, 0x6016, 0x6012, 0x000e, - 0x0005, 0x080c, 0xacfc, 0x0106, 0x2001, 0x19fb, 0x2004, 0x9c06, - 0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0xa596, 0x003e, 0x080c, - 0xa7a1, 0x010e, 0x090c, 0xad18, 0x0005, 0x00e6, 0x0126, 0x2071, - 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058, - 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x001c, 0x7068, - 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, - 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502, 0x1230, 0x755a, - 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1ddc, 0x0cc0, - 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0xb21e, 0xb228, - 0xb243, 0xb25e, 0xd69a, 0xd6b7, 0xd6d2, 0xb21e, 0xb228, 0x92f7, - 0xb277, 0xb21e, 0xb21e, 0xb21e, 0xb21e, 0xb21e, 0x9186, 0x0013, - 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x99ed, 0x0005, 0x0005, - 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d85, 0x0013, 0x006e, - 0x0005, 0xb241, 0xb9bc, 0xbba3, 0xb241, 0xbc39, 0xb540, 0xb241, - 0xb241, 0xb93e, 0xc25a, 0xb241, 0xb241, 0xb241, 0xb241, 0xb241, - 0xb241, 0x080c, 0x0d85, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, - 0x0d85, 0x0013, 0x006e, 0x0005, 0xb25c, 0xc875, 0xb25c, 0xb25c, - 0xb25c, 0xb25c, 0xb25c, 0xb25c, 0xc80c, 0xc9f8, 0xb25c, 0xc8b2, - 0xc936, 0xc8b2, 0xc936, 0xb25c, 0x080c, 0x0d85, 0x6000, 0x9082, - 0x0010, 0x1a0c, 0x0d85, 0x6000, 0x0002, 0xb275, 0xc2a4, 0xc33e, - 0xc4c1, 0xc530, 0xb275, 0xb275, 0xb275, 0xc273, 0xc78d, 0xc790, - 0xb275, 0xb275, 0xb275, 0xb275, 0xc7c0, 0x080c, 0x0d85, 0x0066, - 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, - 0xb290, 0xb290, 0xb2ce, 0xb36d, 0xb3ed, 0xb290, 0xb290, 0xb290, - 0xb292, 0xb290, 0xb290, 0xb290, 0xb290, 0xb290, 0xb290, 0xb290, - 0x080c, 0x0d85, 0x9186, 0x004c, 0x0560, 0x9186, 0x0003, 0x190c, - 0x0d85, 0x0096, 0x601c, 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, - 0x6014, 0x2048, 0xa87c, 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, - 0xa836, 0xa8b0, 0xa83a, 0x9006, 0xa846, 0xa84a, 0xa884, 0x9092, - 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, - 0x621a, 0x009e, 0x080c, 0x1c26, 0x2009, 0x8030, 0x080c, 0x965e, - 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, - 0xb40f, 0x080c, 0xd65d, 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, - 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048, 0xa87c, 0xd0ec, - 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, - 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, - 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, - 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, - 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, 0x0015, - 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, 0x0118, - 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, - 0xb335, 0xb335, 0xb330, 0xb333, 0xb335, 0xb32d, 0xb320, 0xb320, - 0xb320, 0xb320, 0xb320, 0xb320, 0xb320, 0xb320, 0xb320, 0xb320, - 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, - 0x00fe, 0x009e, 0x00de, 0x080c, 0x0d85, 0x080c, 0xbe51, 0x0028, - 0x080c, 0xbf8f, 0x0010, 0x080c, 0xc085, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, 0xb4cd, - 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, - 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, - 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, 0x12c2, - 0x080c, 0xb691, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, - 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0xb16c, 0x2001, - 0x002c, 0x900e, 0x080c, 0xb533, 0x0c70, 0x91b6, 0x0015, 0x0170, - 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0d85, 0x91b2, - 0x0050, 0x1a0c, 0x0d85, 0x9182, 0x0047, 0x0042, 0x080c, 0xaf61, - 0x0120, 0x9086, 0x0002, 0x0904, 0xb2ce, 0x0005, 0xb38f, 0xb38f, - 0xb391, 0xb3c3, 0xb38f, 0xb38f, 0xb38f, 0xb38f, 0xb3d6, 0x080c, - 0x0d85, 0x00d6, 0x0016, 0x0096, 0x6003, 0x0004, 0x6114, 0x2148, - 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, - 0x9005, 0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb533, 0x080c, - 0xb16c, 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, - 0xa8ae, 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, - 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, - 0x001e, 0x00de, 0x0005, 0x080c, 0x9a48, 0x00d6, 0x0096, 0x6114, - 0x2148, 0x080c, 0xcf1b, 0x0120, 0xa87b, 0x0006, 0x080c, 0x7012, - 0x009e, 0x00de, 0x080c, 0xb16c, 0x0804, 0x9ab3, 0x080c, 0x9a48, - 0x080c, 0x3315, 0x080c, 0xd65a, 0x00d6, 0x0096, 0x6114, 0x2148, - 0x080c, 0xcf1b, 0x0120, 0xa87b, 0x0029, 0x080c, 0x7012, 0x009e, - 0x00de, 0x080c, 0xb16c, 0x0804, 0x9ab3, 0x9182, 0x0047, 0x0002, - 0xb3fd, 0xb3ff, 0xb3fd, 0xb3fd, 0xb3fd, 0xb3fd, 0xb3fd, 0xb3fd, - 0xb3fd, 0xb3fd, 0xb3fd, 0xb3fd, 0xb3ff, 0x080c, 0x0d85, 0x00d6, - 0x0096, 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, - 0x0000, 0x080c, 0x7012, 0x009e, 0x00de, 0x0804, 0xb16c, 0x0026, - 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, - 0x1059, 0x000e, 0x090c, 0x0d85, 0xa960, 0x21e8, 0xa95c, 0x9188, - 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, - 0x1800, 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, - 0x2950, 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, - 0x0001, 0x9182, 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xca7b, - 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xca7b, - 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110, 0x080c, 0x100b, 0x080c, - 0x1059, 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, - 0xb406, 0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, - 0xca7b, 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, - 0x001b, 0x080c, 0xca7b, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, - 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, - 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, - 0x0050, 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, - 0x7012, 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, - 0x006e, 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, - 0x0006, 0x080c, 0x1059, 0x000e, 0x090c, 0x0d85, 0xa960, 0x21e8, + 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, + 0x705b, 0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, + 0x7554, 0x9582, 0x0010, 0x0600, 0x7058, 0x2060, 0x6000, 0x9086, + 0x0000, 0x0148, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0, + 0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, + 0x001c, 0x7068, 0x9502, 0x1228, 0x755a, 0x9085, 0x0001, 0x00ee, + 0x0005, 0x705b, 0x1ddc, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1ddc, + 0x0a0c, 0x0d79, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d79, + 0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, + 0x0000, 0x6003, 0x0000, 0x601e, 0x605e, 0x6062, 0x6026, 0x602a, + 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x604a, 0x602a, 0x6046, + 0x6042, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x0005, 0x9006, + 0x600e, 0x6016, 0x601a, 0x6012, 0x6022, 0x6002, 0x601e, 0x605e, + 0x6062, 0x604a, 0x6046, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, + 0x0005, 0x0006, 0x6000, 0x9086, 0x0000, 0x01d8, 0x601c, 0xd084, + 0x190c, 0x1af0, 0x6023, 0x0007, 0x2001, 0x1987, 0x2004, 0x0006, + 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xe9f0, + 0x604b, 0x0000, 0x6044, 0xd0fc, 0x1131, 0x9006, 0x6046, 0x6016, + 0x6012, 0x000e, 0x0005, 0x080c, 0xaaf7, 0x0106, 0x2001, 0x19fc, + 0x2004, 0x9c06, 0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0xa391, + 0x003e, 0x080c, 0xa59c, 0x010e, 0x090c, 0xab13, 0x0005, 0x00e6, + 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001, + 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, + 0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, + 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502, + 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, + 0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, + 0xb000, 0xb00a, 0xb025, 0xb040, 0xd3b0, 0xd3cd, 0xd3e8, 0xb000, + 0xb00a, 0x9191, 0xb059, 0xb000, 0xb000, 0xb000, 0xb000, 0xb000, + 0x9186, 0x0013, 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x97f6, + 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, + 0x0013, 0x006e, 0x0005, 0xb023, 0xb79c, 0xb983, 0xb023, 0xba19, + 0xb322, 0xb023, 0xb023, 0xb71e, 0xbf8c, 0xb023, 0xb023, 0xb023, + 0xb023, 0xb023, 0xb023, 0x080c, 0x0d79, 0x0066, 0x6000, 0x90b2, + 0x0010, 0x1a0c, 0x0d79, 0x0013, 0x006e, 0x0005, 0xb03e, 0xc5a7, + 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xc53e, 0xc72a, + 0xb03e, 0xc5e4, 0xc668, 0xc5e4, 0xc668, 0xb03e, 0x080c, 0x0d79, + 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0d79, 0x6000, 0x0002, 0xb057, + 0xbfd6, 0xc070, 0xc1f3, 0xc262, 0xb057, 0xb057, 0xb057, 0xbfa5, + 0xc4bf, 0xc4c2, 0xb057, 0xb057, 0xb057, 0xb057, 0xc4f2, 0x080c, + 0x0d79, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x0013, + 0x006e, 0x0005, 0xb072, 0xb072, 0xb0b0, 0xb14f, 0xb1cf, 0xb072, + 0xb072, 0xb072, 0xb074, 0xb072, 0xb072, 0xb072, 0xb072, 0xb072, + 0xb072, 0xb072, 0x080c, 0x0d79, 0x9186, 0x004c, 0x0560, 0x9186, + 0x0003, 0x190c, 0x0d79, 0x0096, 0x601c, 0xc0ed, 0x601e, 0x6003, + 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, 0xa000, 0xc0b5, + 0xa87e, 0xa8ac, 0xa836, 0xa8b0, 0xa83a, 0x9006, 0xa846, 0xa84a, + 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, + 0x8213, 0x9210, 0x621a, 0x009e, 0x080c, 0x1c43, 0x2009, 0x8030, + 0x080c, 0x9467, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, + 0x2c00, 0x080c, 0xb1f1, 0x080c, 0xd375, 0x6003, 0x0007, 0x0005, + 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048, + 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, + 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, + 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, + 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, + 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, + 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, + 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, + 0x9405, 0x0002, 0xb117, 0xb117, 0xb112, 0xb115, 0xb117, 0xb10f, + 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, + 0xb102, 0xb102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, + 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0d79, 0x080c, + 0xbbda, 0x0028, 0x080c, 0xbcc1, 0x0010, 0x080c, 0xbdb7, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, + 0x080c, 0xb2af, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, + 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, + 0x2041, 0x12b6, 0x080c, 0xb473, 0x0160, 0x000e, 0x9005, 0x0120, + 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, + 0xaf4e, 0x2001, 0x002c, 0x900e, 0x080c, 0xb315, 0x0c70, 0x91b6, + 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, + 0x0d79, 0x91b2, 0x0050, 0x1a0c, 0x0d79, 0x9182, 0x0047, 0x0042, + 0x080c, 0xad4d, 0x0120, 0x9086, 0x0002, 0x0904, 0xb0b0, 0x0005, + 0xb171, 0xb171, 0xb173, 0xb1a5, 0xb171, 0xb171, 0xb171, 0xb171, + 0xb1b8, 0x080c, 0x0d79, 0x00d6, 0x0016, 0x0096, 0x6003, 0x0004, + 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, + 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000, 0x900e, 0x080c, + 0xb315, 0x080c, 0xaf4e, 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, + 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, + 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, + 0x0000, 0x009e, 0x001e, 0x00de, 0x0005, 0x080c, 0x9851, 0x00d6, + 0x0096, 0x6114, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0006, + 0x080c, 0x6f11, 0x009e, 0x00de, 0x080c, 0xaf4e, 0x0804, 0x98bc, + 0x080c, 0x9851, 0x080c, 0x32fb, 0x080c, 0xd372, 0x00d6, 0x0096, + 0x6114, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0029, 0x080c, + 0x6f11, 0x009e, 0x00de, 0x080c, 0xaf4e, 0x0804, 0x98bc, 0x9182, + 0x0047, 0x0002, 0xb1df, 0xb1e1, 0xb1df, 0xb1df, 0xb1df, 0xb1df, + 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1e1, 0x080c, + 0x0d79, 0x00d6, 0x0096, 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, + 0x0000, 0xa883, 0x0000, 0x080c, 0x6f11, 0x009e, 0x00de, 0x0804, + 0xaf4e, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, + 0x0006, 0x080c, 0x104d, 0x000e, 0x090c, 0x0d79, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, - 0xaa66, 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, - 0x9182, 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, - 0xac76, 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, - 0x200c, 0x918d, 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, - 0x7012, 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, - 0x0096, 0x0016, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, - 0x001e, 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, - 0x000c, 0x2098, 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, - 0x2011, 0x0020, 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, - 0x1059, 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, - 0xa85c, 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, - 0x2009, 0x0280, 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, - 0x2200, 0x9402, 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, - 0x2020, 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, - 0x83ff, 0x0180, 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, - 0x9085, 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb4e2, - 0x0804, 0xb4e4, 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, - 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, - 0xa87a, 0xa982, 0x080c, 0x7006, 0x009e, 0x003e, 0x00de, 0x0005, - 0x91b6, 0x0015, 0x1118, 0x080c, 0xb16c, 0x0030, 0x91b6, 0x0016, - 0x190c, 0x0d85, 0x080c, 0xb16c, 0x0005, 0x20a9, 0x000e, 0x20e1, - 0x0000, 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, - 0x20a0, 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, - 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, - 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, - 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, - 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, 0xcf1b, 0x0130, - 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, - 0xb16c, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, - 0x6010, 0x00b6, 0x2058, 0xb8d7, 0x0000, 0x00be, 0x6014, 0x9005, - 0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, - 0xb16c, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, - 0x0006, 0x0016, 0x080c, 0xd645, 0x0188, 0x6014, 0x9005, 0x1170, - 0x600b, 0x0003, 0x601b, 0x0000, 0x604b, 0x0000, 0x2009, 0x0022, - 0x080c, 0xb994, 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, - 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, - 0x0000, 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, - 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, - 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, - 0x0205, 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, - 0x2003, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, - 0x080c, 0xb16c, 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, - 0x7030, 0x9086, 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, - 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, - 0x2011, 0x0002, 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xca7b, - 0x080c, 0xcf1b, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, - 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb16c, 0x001e, 0x009e, 0x0005, - 0x0016, 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, - 0x0001, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d85, 0xa97a, 0x080c, - 0x7012, 0x009e, 0x080c, 0xb16c, 0x001e, 0x0005, 0x0016, 0x0096, - 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, - 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, - 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xca7b, 0x009e, - 0x080c, 0xcf1b, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, - 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb16c, 0x009e, 0x001e, - 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, - 0x080c, 0xbb5c, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, - 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, - 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, - 0xada4, 0x2031, 0x0000, 0x2041, 0x12a8, 0x0019, 0x0d08, 0x008e, - 0x0898, 0x0096, 0x0006, 0x080c, 0x1059, 0x000e, 0x01b0, 0xa8ab, - 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, - 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, - 0x080c, 0x114e, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, - 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, - 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, - 0xba14, 0x00be, 0x9206, 0x11e0, 0x604b, 0x0000, 0x2c68, 0x0016, - 0x2009, 0x0035, 0x080c, 0xd5bb, 0x001e, 0x1158, 0x622c, 0x2268, - 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, - 0x0128, 0x080c, 0xb16c, 0x0020, 0x0039, 0x0010, 0x080c, 0xb7c7, - 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, - 0x0015, 0x0904, 0xb7a6, 0x918e, 0x0016, 0x1904, 0xb7c5, 0x700c, - 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, - 0xb780, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb762, - 0x0804, 0xb7c3, 0x6808, 0x9086, 0xffff, 0x1904, 0xb7a8, 0xa87c, - 0x9084, 0x0060, 0x9086, 0x0020, 0x1150, 0xa8ac, 0xa934, 0x9106, - 0x1904, 0xb7a8, 0xa8b0, 0xa938, 0x9106, 0x1904, 0xb7a8, 0x6824, - 0xd084, 0x1904, 0xb7a8, 0xd0b4, 0x0158, 0x0016, 0x2001, 0x1986, - 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04, 0xb7a8, - 0x080c, 0xd10c, 0x6810, 0x0096, 0x2048, 0xa9a0, 0x009e, 0x685c, - 0xa87a, 0xa976, 0x6864, 0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, - 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c, 0x955b, - 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138, - 0x00c6, 0x2d60, 0x080c, 0xcc01, 0x00ce, 0x0804, 0xb7c3, 0x00c6, - 0xa868, 0xd0fc, 0x1118, 0x080c, 0x622f, 0x0010, 0x080c, 0x663a, - 0x00ce, 0x1904, 0xb7a8, 0x00c6, 0x2d60, 0x080c, 0xb16c, 0x00ce, - 0x0804, 0xb7c3, 0x00c6, 0x080c, 0xb1dd, 0x0198, 0x6017, 0x0000, - 0x6810, 0x6012, 0x080c, 0xd3b6, 0x6023, 0x0003, 0x6904, 0x00c6, - 0x2d60, 0x080c, 0xb16c, 0x00ce, 0x080c, 0xb20a, 0x00ce, 0x0804, - 0xb7c3, 0x2001, 0x1988, 0x2004, 0x684a, 0x00ce, 0x0804, 0xb7c3, - 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, - 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, - 0xd5ff, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, - 0x8020, 0x080c, 0x9617, 0x00ce, 0x0430, 0x700c, 0x9086, 0x2a00, - 0x1138, 0x2001, 0x1988, 0x2004, 0x684a, 0x00e8, 0x04c1, 0x00e8, - 0x89ff, 0x090c, 0x0d85, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, - 0xa87b, 0x0003, 0x080c, 0x6e27, 0x080c, 0xd10c, 0x080c, 0xb1a7, - 0x0026, 0x6010, 0x00b6, 0x2058, 0xba3c, 0x080c, 0x68df, 0x00be, - 0x002e, 0x00de, 0x00ce, 0x080c, 0xb16c, 0x009e, 0x0005, 0x9186, - 0x0015, 0x1128, 0x2001, 0x1988, 0x2004, 0x684a, 0x0068, 0x918e, - 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xece1, 0x080c, - 0x8c19, 0x080c, 0xb16c, 0x00ce, 0x080c, 0xb16c, 0x0005, 0x0026, - 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, - 0x1988, 0x2004, 0x684a, 0x0804, 0xb841, 0x00c6, 0x2d60, 0x080c, - 0xcadc, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, - 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, - 0x9617, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, - 0x090c, 0x0d85, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, - 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, - 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, - 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, - 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, - 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, - 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xd2a0, 0x080c, 0x9ab3, - 0x0010, 0x080c, 0xb16c, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, - 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, - 0xba10, 0x00be, 0x9206, 0x1904, 0xb8ac, 0x700c, 0x6210, 0x00b6, - 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb8ac, 0x6038, 0x2068, - 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb8ac, - 0x9286, 0x0002, 0x0904, 0xb8ac, 0x9286, 0x0000, 0x05e8, 0x6808, - 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, - 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, - 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, - 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, - 0x2048, 0x080c, 0xcf1b, 0x090c, 0x0d85, 0xa87b, 0x0003, 0x009e, - 0x080c, 0xd5ff, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x2009, 0x8020, 0x080c, 0x9617, 0x00ce, 0x0030, 0x6038, 0x2070, - 0x2001, 0x1988, 0x2004, 0x704a, 0x080c, 0xb16c, 0x002e, 0x00de, - 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, - 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, - 0xbc02, 0x0470, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, - 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc222, 0x002e, - 0x003e, 0x015e, 0x009e, 0x1904, 0xb91d, 0x0096, 0x0156, 0x0036, - 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, - 0x080c, 0xc222, 0x002e, 0x003e, 0x015e, 0x009e, 0x15b0, 0x7238, - 0xba0a, 0x733c, 0xbb0e, 0x83ff, 0x0118, 0xbc00, 0xc48d, 0xbc02, - 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb57c, + 0xa87a, 0x2079, 0x1800, 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, + 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, + 0x901e, 0x2029, 0x0001, 0x9182, 0x0035, 0x1228, 0x2011, 0x001f, + 0x080c, 0xc7ad, 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011, 0x001f, + 0x080c, 0xc7ad, 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110, 0x080c, + 0x0fff, 0x080c, 0x104d, 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, + 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230, 0x2608, 0x2011, + 0x001b, 0x080c, 0xc7ad, 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, + 0x2950, 0x2011, 0x001b, 0x080c, 0xc7ad, 0x0c18, 0x2001, 0x0205, + 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, + 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, + 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, + 0x0006, 0x080c, 0x6f11, 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, + 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, + 0x00f6, 0x0096, 0x0006, 0x080c, 0x104d, 0x000e, 0x090c, 0x0d79, + 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, + 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, + 0x9188, 0x000c, 0x9182, 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, + 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, + 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x4003, 0x2003, + 0x0000, 0x080c, 0x6f11, 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, + 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001, 0x0205, 0x200c, 0x918d, + 0x0080, 0x2102, 0x001e, 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, + 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021, 0x003e, 0x901e, 0x9282, + 0x0020, 0x0218, 0x2011, 0x0020, 0x2018, 0x9486, 0x003e, 0x1170, + 0x0096, 0x080c, 0x104d, 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, + 0x0260, 0x0140, 0x2009, 0x0280, 0x9102, 0x920a, 0x0218, 0x2010, + 0x2100, 0x9318, 0x2200, 0x9402, 0x1228, 0x2400, 0x9202, 0x2410, + 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, + 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300, 0x9086, 0x0280, 0x1130, + 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, + 0x0904, 0xb2c4, 0x0804, 0xb2c6, 0x9085, 0x0001, 0x7817, 0x0000, + 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, + 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x6f05, 0x009e, 0x003e, + 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c, 0xaf4e, 0x0030, + 0x91b6, 0x0016, 0x190c, 0x0d79, 0x080c, 0xaf4e, 0x0005, 0x20a9, + 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, + 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, + 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, + 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398, 0x8211, + 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, + 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, + 0xcc33, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, + 0x009e, 0x0804, 0xaf4e, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, + 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8d7, 0x0000, 0x00be, + 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, + 0xab32, 0x080c, 0xaf4e, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, + 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xd35d, 0x0188, 0x6014, + 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000, 0x604b, 0x0000, + 0x2009, 0x0022, 0x080c, 0xb774, 0x9006, 0x001e, 0x000e, 0x0005, + 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, + 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, + 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, + 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, + 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, + 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, + 0xa867, 0x0103, 0x080c, 0xaf4e, 0x001e, 0x009e, 0x0005, 0x0096, + 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140, 0x7038, 0x9084, + 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, + 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c, 0x6014, 0x2048, + 0x080c, 0xc7ad, 0x080c, 0xcc33, 0x0140, 0x6014, 0x2048, 0xa807, + 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xaf4e, 0x001e, + 0x009e, 0x0005, 0x0016, 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, + 0x0110, 0x2009, 0x0001, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d79, + 0xa97a, 0x080c, 0x6f11, 0x009e, 0x080c, 0xaf4e, 0x001e, 0x0005, + 0x0016, 0x0096, 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, + 0x0010, 0x7034, 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, + 0x6014, 0x2048, 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, + 0xc7ad, 0x009e, 0x080c, 0xcc33, 0x0148, 0xa804, 0x9005, 0x1158, + 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xaf4e, + 0x009e, 0x001e, 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, + 0x0100, 0x1118, 0x080c, 0xb93c, 0x00e0, 0xa034, 0x8007, 0x800c, + 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, + 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129c, 0x0019, + 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006, 0x080c, 0x104d, 0x000e, + 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, + 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, + 0x0086, 0x2940, 0x080c, 0x1142, 0x008e, 0x9085, 0x0001, 0x009e, + 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, + 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, + 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x11e0, 0x604b, 0x0000, + 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c, 0xd2d3, 0x001e, 0x1158, + 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, + 0x9386, 0x0006, 0x0128, 0x080c, 0xaf4e, 0x0020, 0x0039, 0x0010, + 0x080c, 0xb5a9, 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, + 0x2048, 0x9186, 0x0015, 0x0904, 0xb588, 0x918e, 0x0016, 0x1904, + 0xb5a7, 0x700c, 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, + 0x0300, 0x1904, 0xb562, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, + 0x0904, 0xb544, 0x0804, 0xb5a5, 0x6808, 0x9086, 0xffff, 0x1904, + 0xb58a, 0xa87c, 0x9084, 0x0060, 0x9086, 0x0020, 0x1150, 0xa8ac, + 0xa934, 0x9106, 0x1904, 0xb58a, 0xa8b0, 0xa938, 0x9106, 0x1904, + 0xb58a, 0x6824, 0xd084, 0x1904, 0xb58a, 0xd0b4, 0x0158, 0x0016, + 0x2001, 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, + 0x1a04, 0xb58a, 0x080c, 0xce24, 0x6810, 0x0096, 0x2048, 0xa9a0, + 0x009e, 0x685c, 0xa87a, 0xa976, 0x6864, 0xa882, 0xa87c, 0xc0dc, + 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, + 0x080c, 0x9364, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, + 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xc938, 0x00ce, 0x0804, + 0xb5a5, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x620a, 0x0010, + 0x080c, 0x6615, 0x00ce, 0x1904, 0xb58a, 0x00c6, 0x2d60, 0x080c, + 0xaf4e, 0x00ce, 0x0804, 0xb5a5, 0x00c6, 0x080c, 0xafbf, 0x0198, + 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xd0ce, 0x6023, 0x0003, + 0x6904, 0x00c6, 0x2d60, 0x080c, 0xaf4e, 0x00ce, 0x080c, 0xafec, + 0x00ce, 0x0804, 0xb5a5, 0x2001, 0x1989, 0x2004, 0x684a, 0x00ce, + 0x0804, 0xb5a5, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, + 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, + 0x0003, 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x0430, 0x700c, + 0x9086, 0x2a00, 0x1138, 0x2001, 0x1989, 0x2004, 0x684a, 0x00e8, + 0x04c1, 0x00e8, 0x89ff, 0x090c, 0x0d79, 0x00c6, 0x00d6, 0x2d60, + 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x6d26, 0x080c, 0xce24, + 0x080c, 0xaf89, 0x0026, 0x6010, 0x00b6, 0x2058, 0xba3c, 0x080c, + 0x68ae, 0x00be, 0x002e, 0x00de, 0x00ce, 0x080c, 0xaf4e, 0x009e, + 0x0005, 0x9186, 0x0015, 0x1128, 0x2001, 0x1989, 0x2004, 0x684a, + 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, + 0xe9f0, 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x00ce, 0x080c, 0xaf4e, + 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, + 0x0130, 0x2001, 0x1989, 0x2004, 0x684a, 0x0804, 0xb623, 0x00c6, + 0x2d60, 0x080c, 0xc80e, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, + 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009, + 0x8023, 0x080c, 0x9420, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, + 0x01a8, 0x89ff, 0x090c, 0x0d79, 0x6800, 0x9086, 0x0004, 0x1190, + 0xa87c, 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, + 0xc0fc, 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, + 0x6832, 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, + 0xd0f4, 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, + 0x1d68, 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, + 0x683e, 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xcfb8, + 0x080c, 0x98bc, 0x0010, 0x080c, 0xaf4e, 0x004e, 0x003e, 0x002e, + 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, + 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xb68e, 0x700c, + 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb68e, + 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, + 0x0904, 0xb68e, 0x9286, 0x0002, 0x0904, 0xb68e, 0x9286, 0x0000, + 0x05e8, 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, + 0x0015, 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, + 0x6104, 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, + 0x004d, 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, + 0x6014, 0x0096, 0x2048, 0x080c, 0xcc33, 0x090c, 0x0d79, 0xa87b, + 0x0003, 0x009e, 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, + 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x0030, + 0x6038, 0x2070, 0x2001, 0x1989, 0x2004, 0x704a, 0x080c, 0xaf4e, + 0x002e, 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, + 0x2048, 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, + 0xbc00, 0xc48c, 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, + 0x2b48, 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, + 0xbf54, 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xb6fd, 0x0096, + 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, + 0x20a9, 0x0004, 0x080c, 0xbf54, 0x002e, 0x003e, 0x015e, 0x009e, + 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, + 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb35e, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, - 0x12a8, 0x080c, 0xb691, 0x0130, 0x00fe, 0x009e, 0x080c, 0xb16c, - 0x00be, 0x0005, 0x080c, 0xbb5c, 0x0cb8, 0x2b78, 0x00f6, 0x080c, - 0x3315, 0x080c, 0xd65a, 0x00fe, 0x00c6, 0x080c, 0xb116, 0x2f00, + 0x129c, 0x080c, 0xb473, 0x0130, 0x00fe, 0x009e, 0x080c, 0xaf4e, + 0x00be, 0x0005, 0x080c, 0xb93c, 0x0cb8, 0x2b78, 0x00f6, 0x080c, + 0x32fb, 0x080c, 0xd372, 0x00fe, 0x00c6, 0x080c, 0xaef8, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, - 0x0001, 0x2001, 0x0007, 0x080c, 0x66fa, 0x080c, 0x6726, 0x080c, - 0x961e, 0x080c, 0x9ab3, 0x00ce, 0x0804, 0xb8f0, 0x2100, 0x91b2, - 0x0053, 0x1a0c, 0x0d85, 0x91b2, 0x0040, 0x1a04, 0xb9a6, 0x0002, - 0xb994, 0xb994, 0xb98a, 0xb994, 0xb994, 0xb994, 0xb988, 0xb988, - 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, - 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, - 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb994, - 0xb988, 0xb994, 0xb994, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, - 0xb98a, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, - 0xb988, 0xb988, 0xb994, 0xb994, 0xb988, 0xb988, 0xb988, 0xb988, - 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb994, 0xb988, 0xb988, - 0x080c, 0x0d85, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8d4, 0xc08c, + 0x0001, 0x2001, 0x0007, 0x080c, 0x66c9, 0x080c, 0x66f5, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x00ce, 0x0804, 0xb6d0, 0x2100, 0x91b2, + 0x0053, 0x1a0c, 0x0d79, 0x91b2, 0x0040, 0x1a04, 0xb786, 0x0002, + 0xb774, 0xb774, 0xb76a, 0xb774, 0xb774, 0xb774, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb774, + 0xb768, 0xb774, 0xb774, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb76a, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb774, 0xb774, 0xb768, 0xb768, 0xb768, 0xb768, + 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb774, 0xb768, 0xb768, + 0x080c, 0x0d79, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8d4, 0xc08c, 0xb8d6, 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, - 0x0032, 0x0118, 0x080c, 0x961e, 0x0010, 0x080c, 0x9617, 0x0126, - 0x2091, 0x8000, 0x080c, 0x9ab3, 0x012e, 0x0005, 0x2600, 0x0002, - 0xb994, 0xb994, 0xb9ba, 0xb994, 0xb994, 0xb9ba, 0xb9ba, 0xb9ba, - 0xb9ba, 0xb994, 0xb9ba, 0xb994, 0xb9ba, 0xb994, 0xb9ba, 0xb9ba, - 0xb9ba, 0xb9ba, 0x080c, 0x0d85, 0x6004, 0x90b2, 0x0053, 0x1a0c, - 0x0d85, 0x91b6, 0x0013, 0x0904, 0xba91, 0x91b6, 0x0027, 0x1904, - 0xba3d, 0x080c, 0x99ed, 0x6004, 0x080c, 0xd121, 0x01b0, 0x080c, - 0xd132, 0x01a8, 0x908e, 0x0021, 0x0904, 0xba3a, 0x908e, 0x0022, - 0x1130, 0x080c, 0xb5a8, 0x0904, 0xba36, 0x0804, 0xba37, 0x908e, - 0x003d, 0x0904, 0xba3a, 0x0804, 0xba30, 0x080c, 0x3344, 0x2001, - 0x0007, 0x080c, 0x66fa, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, - 0x080c, 0xbb5c, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, - 0xc285, 0x080c, 0x779e, 0x1108, 0xc2ad, 0x2202, 0x080c, 0xacfc, - 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xedee, 0x002e, + 0x0032, 0x0118, 0x080c, 0x9427, 0x0010, 0x080c, 0x9420, 0x0126, + 0x2091, 0x8000, 0x080c, 0x98bc, 0x012e, 0x0005, 0x2600, 0x0002, + 0xb774, 0xb774, 0xb79a, 0xb774, 0xb774, 0xb79a, 0xb79a, 0xb79a, + 0xb79a, 0xb774, 0xb79a, 0xb774, 0xb79a, 0xb774, 0xb79a, 0xb79a, + 0xb79a, 0xb79a, 0x080c, 0x0d79, 0x6004, 0x90b2, 0x0053, 0x1a0c, + 0x0d79, 0x91b6, 0x0013, 0x0904, 0xb871, 0x91b6, 0x0027, 0x1904, + 0xb81d, 0x080c, 0x97f6, 0x6004, 0x080c, 0xce39, 0x01b0, 0x080c, + 0xce4a, 0x01a8, 0x908e, 0x0021, 0x0904, 0xb81a, 0x908e, 0x0022, + 0x1130, 0x080c, 0xb38a, 0x0904, 0xb816, 0x0804, 0xb817, 0x908e, + 0x003d, 0x0904, 0xb81a, 0x0804, 0xb810, 0x080c, 0x332a, 0x2001, + 0x0007, 0x080c, 0x66c9, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, + 0x080c, 0xb93c, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, + 0xc285, 0x080c, 0x769d, 0x1108, 0xc2ad, 0x2202, 0x080c, 0xaaf7, + 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xeafd, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, - 0x97b0, 0x0076, 0x903e, 0x080c, 0x966d, 0x6010, 0x00b6, 0x905d, - 0x0100, 0x00be, 0x2c08, 0x080c, 0xe75d, 0x007e, 0x003e, 0x002e, - 0x001e, 0x080c, 0xad18, 0x080c, 0xd65a, 0x0016, 0x080c, 0xd3ae, - 0x080c, 0xb16c, 0x001e, 0x080c, 0x341e, 0x080c, 0x9ab3, 0x0030, - 0x080c, 0xd3ae, 0x080c, 0xb16c, 0x080c, 0x9ab3, 0x0005, 0x080c, - 0xbb5c, 0x0cb0, 0x080c, 0xbb98, 0x0c98, 0x9186, 0x0015, 0x0118, - 0x9186, 0x0016, 0x1140, 0x080c, 0xaf61, 0x0d80, 0x9086, 0x0002, - 0x0904, 0xbba3, 0x0c58, 0x9186, 0x0014, 0x1d40, 0x080c, 0x99ed, - 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb5a8, 0x09f8, 0x080c, - 0x3315, 0x080c, 0xd65a, 0x080c, 0xd121, 0x1190, 0x080c, 0x3344, - 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbb5c, 0x9186, + 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x6010, 0x00b6, 0x905d, + 0x0100, 0x00be, 0x2c08, 0x080c, 0xe465, 0x007e, 0x003e, 0x002e, + 0x001e, 0x080c, 0xab13, 0x080c, 0xd372, 0x0016, 0x080c, 0xd0c6, + 0x080c, 0xaf4e, 0x001e, 0x080c, 0x3404, 0x080c, 0x98bc, 0x0030, + 0x080c, 0xd0c6, 0x080c, 0xaf4e, 0x080c, 0x98bc, 0x0005, 0x080c, + 0xb93c, 0x0cb0, 0x080c, 0xb978, 0x0c98, 0x9186, 0x0015, 0x0118, + 0x9186, 0x0016, 0x1140, 0x080c, 0xad4d, 0x0d80, 0x9086, 0x0002, + 0x0904, 0xb983, 0x0c58, 0x9186, 0x0014, 0x1d40, 0x080c, 0x97f6, + 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb38a, 0x09f8, 0x080c, + 0x32fb, 0x080c, 0xd372, 0x080c, 0xce39, 0x1190, 0x080c, 0x332a, + 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xb93c, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185, 0x2102, 0x0800, - 0x080c, 0xd132, 0x1120, 0x080c, 0xbb5c, 0x0804, 0xba30, 0x6004, + 0x080c, 0xce4a, 0x1120, 0x080c, 0xb93c, 0x0804, 0xb810, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, - 0x0000, 0x080c, 0x36bf, 0x00fe, 0x00ee, 0x0804, 0xba30, 0x6004, - 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, 0x090c, 0xbb5c, 0x0804, - 0xba30, 0x90b2, 0x0040, 0x1a04, 0xbb3c, 0x2008, 0x0002, 0xbad9, - 0xbada, 0xbadd, 0xbae0, 0xbae3, 0xbaf0, 0xbad7, 0xbad7, 0xbad7, - 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, - 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, - 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbaf3, 0xbafe, 0xbad7, - 0xbaff, 0xbafe, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbafe, - 0xbafe, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, - 0xbad7, 0xbb27, 0xbafe, 0xbad7, 0xbafa, 0xbad7, 0xbad7, 0xbad7, - 0xbafb, 0xbad7, 0xbad7, 0xbad7, 0xbafe, 0xbb22, 0xbad7, 0x080c, - 0x0d85, 0x0420, 0x2001, 0x000b, 0x0448, 0x2001, 0x0003, 0x0430, + 0x0000, 0x080c, 0x36a5, 0x00fe, 0x00ee, 0x0804, 0xb810, 0x6004, + 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, 0x090c, 0xb93c, 0x0804, + 0xb810, 0x90b2, 0x0040, 0x1a04, 0xb91c, 0x2008, 0x0002, 0xb8b9, + 0xb8ba, 0xb8bd, 0xb8c0, 0xb8c3, 0xb8d0, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8d3, 0xb8de, 0xb8b7, + 0xb8df, 0xb8de, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8de, + 0xb8de, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8b7, 0xb907, 0xb8de, 0xb8b7, 0xb8da, 0xb8b7, 0xb8b7, 0xb8b7, + 0xb8db, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8de, 0xb902, 0xb8b7, 0x080c, + 0x0d79, 0x0420, 0x2001, 0x000b, 0x0448, 0x2001, 0x0003, 0x0430, 0x2001, 0x0005, 0x0418, 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x11d8, 0x2001, 0x0001, 0x00b0, - 0x2001, 0x0009, 0x0098, 0x6003, 0x0005, 0x080c, 0xd65d, 0x080c, - 0x9ab3, 0x0058, 0x0018, 0x0010, 0x080c, 0x66fa, 0x04b8, 0x080c, - 0xd65d, 0x6003, 0x0004, 0x080c, 0x9ab3, 0x0005, 0x080c, 0x66fa, + 0x2001, 0x0009, 0x0098, 0x6003, 0x0005, 0x080c, 0xd375, 0x080c, + 0x98bc, 0x0058, 0x0018, 0x0010, 0x080c, 0x66c9, 0x04b8, 0x080c, + 0xd375, 0x6003, 0x0004, 0x080c, 0x98bc, 0x0005, 0x080c, 0x66c9, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304, 0x9084, 0xff00, - 0x1120, 0x2001, 0x1986, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004, + 0x1120, 0x2001, 0x1987, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, 0x003e, 0x080c, - 0x9ab3, 0x0c18, 0x080c, 0xd3ae, 0x080c, 0xb16c, 0x08f0, 0x00e6, - 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x36bf, 0x00fe, - 0x00ee, 0x080c, 0x99ed, 0x080c, 0xb16c, 0x0878, 0x6003, 0x0002, - 0x080c, 0xd65d, 0x0804, 0x9ab3, 0x2600, 0x2008, 0x0002, 0xbb53, - 0xbb36, 0xbb51, 0xbb36, 0xbb36, 0xbb51, 0xbb51, 0xbb51, 0xbb51, - 0xbb36, 0xbb51, 0xbb36, 0xbb51, 0xbb36, 0xbb51, 0xbb51, 0xbb51, - 0xbb51, 0x080c, 0x0d85, 0x0096, 0x6014, 0x2048, 0x080c, 0x7012, - 0x009e, 0x080c, 0xb16c, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, - 0x080c, 0xcf1b, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, - 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x55cc, 0x0130, + 0x98bc, 0x0c18, 0x080c, 0xd0c6, 0x080c, 0xaf4e, 0x08f0, 0x00e6, + 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x36a5, 0x00fe, + 0x00ee, 0x080c, 0x97f6, 0x080c, 0xaf4e, 0x0878, 0x6003, 0x0002, + 0x080c, 0xd375, 0x0804, 0x98bc, 0x2600, 0x2008, 0x0002, 0xb933, + 0xb916, 0xb931, 0xb916, 0xb916, 0xb931, 0xb931, 0xb931, 0xb931, + 0xb916, 0xb931, 0xb916, 0xb931, 0xb916, 0xb931, 0xb931, 0xb931, + 0xb931, 0x080c, 0x0d79, 0x0096, 0x6014, 0x2048, 0x080c, 0x6f11, + 0x009e, 0x080c, 0xaf4e, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, + 0x080c, 0xcc33, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, + 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x55ac, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, - 0x900e, 0x2011, 0x4005, 0x080c, 0xd51f, 0x0090, 0xa868, 0xd0fc, + 0x900e, 0x2011, 0x4005, 0x080c, 0xd237, 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, - 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0d85, 0x6604, 0x96b6, 0x004d, - 0x1120, 0x080c, 0xd43e, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0043, - 0x1120, 0x080c, 0xd487, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x004b, - 0x1120, 0x080c, 0xd4b3, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0033, - 0x1120, 0x080c, 0xd3d0, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0028, - 0x1120, 0x080c, 0xd170, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0029, - 0x1120, 0x080c, 0xd1b1, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x001f, - 0x1120, 0x080c, 0xb54d, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0000, - 0x1118, 0x080c, 0xb8b2, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, - 0x080c, 0xb589, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, - 0xb6af, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb847, - 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb5c1, 0x0400, - 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb5fd, 0x00c8, 0x6604, - 0x96b6, 0x0049, 0x1118, 0x080c, 0xb63e, 0x0090, 0x6604, 0x96b6, - 0x0041, 0x1118, 0x080c, 0xb628, 0x0058, 0x91b6, 0x0015, 0x1110, - 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbf34, - 0x00be, 0x0005, 0x080c, 0xb227, 0x0cd8, 0xbc45, 0xbc53, 0xbc45, - 0xbc9a, 0xbc45, 0xbe51, 0xbf41, 0xbc45, 0xbc45, 0xbf0a, 0xbc45, - 0xbf20, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, - 0xa867, 0x0103, 0x009e, 0x0804, 0xb16c, 0xa001, 0xa001, 0x0005, - 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x66e6, - 0x0804, 0xb16c, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, - 0x0074, 0x1540, 0x080c, 0xe72e, 0x11b0, 0x6010, 0x00b6, 0x2058, + 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0d79, 0x6604, 0x96b6, 0x004d, + 0x1120, 0x080c, 0xd156, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0043, + 0x1120, 0x080c, 0xd19f, 0x0804, 0xba08, 0x6604, 0x96b6, 0x004b, + 0x1120, 0x080c, 0xd1cb, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0033, + 0x1120, 0x080c, 0xd0e8, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0028, + 0x1120, 0x080c, 0xce88, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0029, + 0x1120, 0x080c, 0xcec9, 0x0804, 0xba08, 0x6604, 0x96b6, 0x001f, + 0x1120, 0x080c, 0xb32f, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0000, + 0x1118, 0x080c, 0xb694, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, + 0x080c, 0xb36b, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, + 0xb491, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb629, + 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb3a3, 0x0400, + 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb3df, 0x00c8, 0x6604, + 0x96b6, 0x0049, 0x1118, 0x080c, 0xb420, 0x0090, 0x6604, 0x96b6, + 0x0041, 0x1118, 0x080c, 0xb40a, 0x0058, 0x91b6, 0x0015, 0x1110, + 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbc66, + 0x00be, 0x0005, 0x080c, 0xb009, 0x0cd8, 0xba25, 0xba33, 0xba25, + 0xba7a, 0xba25, 0xbbda, 0xbc73, 0xba25, 0xba25, 0xbc3c, 0xba25, + 0xbc52, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, + 0xa867, 0x0103, 0x009e, 0x0804, 0xaf4e, 0xa001, 0xa001, 0x0005, + 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x66b5, + 0x0804, 0xaf4e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, + 0x0074, 0x1540, 0x080c, 0xe436, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, - 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, 0x66fa, 0x080c, 0x3344, - 0x080c, 0xb16c, 0x0098, 0x2001, 0x000a, 0x080c, 0x66fa, 0x080c, - 0x3344, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x961e, 0x080c, - 0x9ab3, 0x0020, 0x2001, 0x0001, 0x080c, 0xbe21, 0x00ee, 0x0005, - 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x66e6, 0x2069, - 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x6726, + 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c, 0x332a, + 0x080c, 0xaf4e, 0x0098, 0x2001, 0x000a, 0x080c, 0x66c9, 0x080c, + 0x332a, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9427, 0x080c, + 0x98bc, 0x0020, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x00ee, 0x0005, + 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x66b5, 0x2069, + 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x66f5, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, - 0x9086, 0x0074, 0x1904, 0xbdf6, 0x6010, 0x2058, 0xbaa0, 0x9286, - 0x007e, 0x1120, 0x080c, 0xc090, 0x0804, 0xbd63, 0x2001, 0x180d, - 0x2004, 0xd08c, 0x0904, 0xbd05, 0x00d6, 0x080c, 0x779e, 0x01a0, - 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, 0x002e, 0x0904, 0xbd04, - 0x080c, 0x5854, 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, - 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, - 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, - 0x6c35, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, 0x0d85, 0x2048, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, - 0x900e, 0x2011, 0x4009, 0x080c, 0xd51f, 0x0040, 0x6014, 0x2048, - 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, - 0xb9a0, 0x0016, 0x080c, 0x3344, 0x080c, 0xb16c, 0x001e, 0x080c, - 0x341e, 0x00de, 0x0804, 0xbdfb, 0x00de, 0x080c, 0xc085, 0x6010, - 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, - 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, - 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd51f, 0x0030, 0xa807, - 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c, - 0x66fa, 0x080c, 0x3344, 0x080c, 0xb16c, 0x0804, 0xbdfb, 0x080c, - 0xbe09, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, - 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, - 0x900e, 0x2011, 0x4000, 0x080c, 0xd51f, 0x08f8, 0x080c, 0xbdff, - 0x0160, 0x9006, 0x080c, 0x66e6, 0x2001, 0x0004, 0x080c, 0x6726, - 0x2001, 0x0007, 0x080c, 0x66fa, 0x08a0, 0x2001, 0x0004, 0x080c, - 0x66fa, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x961e, 0x080c, - 0x9ab3, 0x0804, 0xbdfb, 0xb85c, 0xd0e4, 0x0178, 0x080c, 0xd348, - 0x080c, 0x779e, 0x0118, 0xd0dc, 0x1904, 0xbd25, 0x2011, 0x1837, - 0x2204, 0xc0ad, 0x2012, 0x0804, 0xbd25, 0x080c, 0xd389, 0x2011, - 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe905, 0x000e, - 0x1904, 0xbd25, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x66fa, - 0x9006, 0x080c, 0x66e6, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c, - 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c, - 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, 0x908c, - 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26d5, - 0x00f6, 0x2100, 0x900e, 0x080c, 0x268c, 0x795e, 0x00fe, 0x9186, - 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, 0x00f6, - 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, 0x780c, - 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26d5, 0x00f6, 0x2079, 0x1800, - 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x268c, 0x795e, 0x00fe, - 0x8108, 0x080c, 0x6749, 0x2b00, 0x00ce, 0x1904, 0xbd25, 0x6012, - 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c, - 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001, - 0x0002, 0x080c, 0x66fa, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0028, 0x080c, 0xbb5c, - 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, - 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac, - 0x0005, 0x00e6, 0x080c, 0xee47, 0x0190, 0x2071, 0x0260, 0x7108, - 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, - 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, - 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x66fa, - 0x080c, 0x5854, 0x1120, 0x2001, 0x0007, 0x080c, 0x6726, 0x2600, - 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, - 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, - 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4ca1, 0x004e, 0x003e, - 0x080c, 0x3344, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, - 0xb16c, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090, - 0x9086, 0x0014, 0x1904, 0xbf00, 0x2001, 0x180d, 0x2004, 0xd08c, - 0x0904, 0xbeb3, 0x00d6, 0x080c, 0x779e, 0x01a0, 0x0026, 0x2011, - 0x0010, 0x080c, 0x6c35, 0x002e, 0x0904, 0xbeb2, 0x080c, 0x5854, - 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, - 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, 0x00be, 0x9186, - 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, 0x6c35, 0x002e, - 0x0548, 0x6014, 0x9005, 0x090c, 0x0d85, 0x2048, 0xa864, 0x9084, - 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011, - 0x4009, 0x080c, 0xd51f, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000, - 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016, - 0x080c, 0x3344, 0x080c, 0xb16c, 0x001e, 0x080c, 0x341e, 0x00de, - 0x0804, 0xbf05, 0x00de, 0x080c, 0x5854, 0x1170, 0x6014, 0x9005, - 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, - 0x080c, 0x4e58, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, - 0x684f, 0x080c, 0xbc88, 0x00de, 0x080c, 0xc15b, 0x1588, 0x6010, - 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x66fa, - 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, - 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, - 0xd51f, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, - 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, - 0x3344, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xb16c, 0x0028, - 0x080c, 0xbb5c, 0x9006, 0x080c, 0xbe21, 0x001e, 0x002e, 0x00ee, - 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x1160, - 0x2001, 0x0002, 0x080c, 0x66fa, 0x6003, 0x0001, 0x6007, 0x0001, - 0x080c, 0x961e, 0x0804, 0x9ab3, 0x2001, 0x0001, 0x0804, 0xbe21, - 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, - 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x66fa, 0x0804, 0xb16c, - 0x2001, 0x0001, 0x0804, 0xbe21, 0x0002, 0xbc45, 0xbf4c, 0xbc45, - 0xbf8f, 0xbc45, 0xc03c, 0xbf41, 0xbc48, 0xbc45, 0xc050, 0xbc45, - 0xc062, 0x6604, 0x9686, 0x0003, 0x0904, 0xbe51, 0x96b6, 0x001e, - 0x1110, 0x080c, 0xb16c, 0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, - 0xc074, 0x11a0, 0x9006, 0x080c, 0x66e6, 0x080c, 0x3315, 0x080c, - 0xd65a, 0x2001, 0x0002, 0x080c, 0x66fa, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0428, 0x2009, 0x026e, - 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840, 0x9084, - 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, 0x000a, 0x0098, - 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, 0x1900, 0x0158, - 0x908e, 0x1e00, 0x0990, 0x080c, 0x3315, 0x080c, 0xd65a, 0x2001, - 0x0001, 0x080c, 0xbe21, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, - 0x00b6, 0x0026, 0x9016, 0x080c, 0xc082, 0x00d6, 0x2069, 0x197c, - 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, - 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, - 0x00de, 0x0088, 0x9006, 0x080c, 0x66e6, 0x2001, 0x0002, 0x080c, - 0x66fa, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x961e, 0x080c, - 0x9ab3, 0x0804, 0xc00c, 0x080c, 0xcf1b, 0x01b0, 0x6014, 0x2048, - 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, - 0x0002, 0x080c, 0xd57c, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, - 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, - 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, - 0x9006, 0x0c38, 0x080c, 0xbb5c, 0x2009, 0x026e, 0x2134, 0x96b4, - 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, - 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, - 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001, 0x0004, - 0x080c, 0x66fa, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0020, - 0x2001, 0x0001, 0x080c, 0xbe21, 0x002e, 0x00be, 0x009e, 0x0005, - 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0140, - 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, - 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, - 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, - 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6130, 0x00ee, - 0x0010, 0x080c, 0x3315, 0x0860, 0x2001, 0x0004, 0x080c, 0x66fa, - 0x080c, 0xc082, 0x1140, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, - 0x961e, 0x0804, 0x9ab3, 0x080c, 0xbb5c, 0x9006, 0x0804, 0xbe21, - 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x66fa, 0x6003, 0x0001, - 0x6007, 0x0005, 0x080c, 0x961e, 0x0804, 0x9ab3, 0x2001, 0x0001, - 0x0804, 0xbe21, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c, 0x66fa, - 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x961e, 0x0804, 0x9ab3, - 0x2001, 0x0001, 0x0804, 0xbe21, 0x2009, 0x026e, 0x2104, 0x9086, - 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, - 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, - 0x6110, 0x2158, 0x080c, 0x67c3, 0x001e, 0x00ce, 0x00be, 0x0005, - 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, - 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xc12d, - 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6c0d, - 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xea8d, 0x2001, - 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, - 0x080c, 0x32da, 0x00e6, 0x2071, 0x1800, 0x080c, 0x30bf, 0x00ee, - 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x341e, - 0x8108, 0x1f04, 0xc0c6, 0x015e, 0x00ce, 0x080c, 0xc085, 0x2071, - 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837, 0x200c, - 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, - 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102, 0x9184, - 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, 0x2e04, 0x9084, - 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, - 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084, - 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, 0x2200, 0x9084, - 0x00ff, 0x2008, 0x080c, 0x26d5, 0x080c, 0x779e, 0x0170, 0x2071, - 0x0260, 0x2069, 0x1982, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050, - 0x680a, 0x7054, 0x680e, 0x080c, 0xd348, 0x0040, 0x2001, 0x0006, - 0x080c, 0x66fa, 0x080c, 0x3344, 0x080c, 0xb16c, 0x001e, 0x003e, - 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036, - 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, 0x01f0, 0x2071, - 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205, - 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019, - 0x000a, 0x080c, 0xc222, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, - 0x2019, 0x0006, 0x080c, 0xc222, 0x1100, 0x015e, 0x00ee, 0x003e, - 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086, - 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec, - 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4, - 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee, - 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, - 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f4, 0x252c, 0x2021, - 0x19fb, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7254, 0x7074, - 0x9202, 0x1a04, 0xc1ee, 0x080c, 0x8eee, 0x0904, 0xc1e7, 0x080c, - 0xeabe, 0x0904, 0xc1e7, 0x6720, 0x9786, 0x0007, 0x0904, 0xc1e7, - 0x2500, 0x9c06, 0x0904, 0xc1e7, 0x2400, 0x9c06, 0x0904, 0xc1e7, - 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, - 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1590, 0x00c6, 0x6043, 0xffff, - 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x1ad3, 0x9786, 0x000a, - 0x0148, 0x080c, 0xd132, 0x1130, 0x00ce, 0x080c, 0xbb5c, 0x080c, - 0xb1a7, 0x00e8, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x01a8, 0x9786, - 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, - 0xa878, 0x2048, 0x080c, 0x100b, 0x009e, 0xab7a, 0xa877, 0x0000, - 0x080c, 0x7006, 0x080c, 0xd10c, 0x080c, 0xb1a7, 0x00ce, 0x9ce0, - 0x001c, 0x7068, 0x9c02, 0x1210, 0x0804, 0xc18e, 0x012e, 0x000e, - 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, - 0x9786, 0x0006, 0x1118, 0x080c, 0xea30, 0x0c30, 0x9786, 0x0009, - 0x1148, 0x6000, 0x9086, 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, - 0xb20a, 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, 0x220c, 0x2304, - 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xc20e, 0x9006, 0x0005, - 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, - 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, - 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, - 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, - 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, - 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, - 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, 0x2304, 0x9106, - 0x1130, 0x8210, 0x8318, 0x1f04, 0xc24c, 0x9006, 0x0005, 0x918d, - 0x0001, 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d85, 0x080c, - 0xd121, 0x0120, 0x080c, 0xd132, 0x0158, 0x0028, 0x080c, 0x3344, - 0x080c, 0xd132, 0x0128, 0x080c, 0x99ed, 0x080c, 0xb16c, 0x0005, - 0x080c, 0xbb5c, 0x0cc0, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, - 0x0208, 0x000a, 0x0005, 0xc292, 0xc292, 0xc292, 0xc292, 0xc292, - 0xc292, 0xc292, 0xc292, 0xc292, 0xc292, 0xc292, 0xc294, 0xc294, - 0xc294, 0xc294, 0xc292, 0xc292, 0xc292, 0xc294, 0xc292, 0xc292, - 0xc292, 0xc292, 0x080c, 0x0d85, 0x600b, 0xffff, 0x6003, 0x000f, - 0x6106, 0x0126, 0x2091, 0x8000, 0x080c, 0xd65d, 0x2009, 0x8000, - 0x080c, 0x9617, 0x012e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, - 0x9082, 0x0040, 0x0804, 0xc31c, 0x9186, 0x0027, 0x1520, 0x080c, - 0x99ed, 0x080c, 0x3315, 0x080c, 0xd65a, 0x0096, 0x6114, 0x2148, - 0x080c, 0xcf1b, 0x0198, 0x080c, 0xd132, 0x1118, 0x080c, 0xbb5c, - 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c, - 0xc1c5, 0xa97e, 0x080c, 0x7012, 0x080c, 0xd10c, 0x009e, 0x080c, - 0xb16c, 0x0804, 0x9ab3, 0x9186, 0x0014, 0x1120, 0x6004, 0x9082, - 0x0040, 0x0030, 0x9186, 0x0053, 0x0110, 0x080c, 0x0d85, 0x0005, - 0x0002, 0xc2fa, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, - 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc313, 0xc313, 0xc313, 0xc313, - 0xc2f8, 0xc313, 0xc2f8, 0xc313, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, - 0x080c, 0x0d85, 0x080c, 0x99ed, 0x0096, 0x6114, 0x2148, 0x080c, - 0xcf1b, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, - 0xa880, 0xc0ec, 0xa882, 0x080c, 0x7012, 0x080c, 0xd10c, 0x009e, - 0x080c, 0xb16c, 0x0005, 0x080c, 0x99ed, 0x080c, 0xd132, 0x090c, - 0xbb5c, 0x080c, 0xb16c, 0x0005, 0x0002, 0xc336, 0xc334, 0xc334, - 0xc334, 0xc334, 0xc334, 0xc334, 0xc334, 0xc334, 0xc334, 0xc334, - 0xc338, 0xc338, 0xc338, 0xc338, 0xc334, 0xc33a, 0xc334, 0xc338, - 0xc334, 0xc334, 0xc334, 0xc334, 0x080c, 0x0d85, 0x080c, 0x0d85, - 0x080c, 0x0d85, 0x080c, 0xb16c, 0x0804, 0x9ab3, 0x9182, 0x0057, - 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc35d, 0xc35d, - 0xc35d, 0xc35d, 0xc35d, 0xc396, 0xc488, 0xc35d, 0xc494, 0xc35d, - 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, - 0xc35d, 0xc494, 0xc35f, 0xc35d, 0xc492, 0x080c, 0x0d85, 0x00b6, - 0x0096, 0x6114, 0x2148, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1508, - 0xa87b, 0x0000, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87c, 0xd0ac, - 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc519, 0x080c, 0x6e27, - 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0xb8d0, - 0x9005, 0x0110, 0x080c, 0x68df, 0x080c, 0xb16c, 0x009e, 0x00be, - 0x0005, 0xa87c, 0xd0ac, 0x09e0, 0xa838, 0xa934, 0x9105, 0x09c0, - 0xa880, 0xd0bc, 0x19a8, 0x080c, 0xd267, 0x0c80, 0x00b6, 0x0096, - 0x6114, 0x2148, 0x601c, 0xd0fc, 0x1110, 0x7644, 0x0008, 0x9036, - 0x96b4, 0x0fff, 0x86ff, 0x1590, 0x6010, 0x2058, 0xb800, 0xd0bc, - 0x1904, 0xc477, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0xa87c, - 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc519, 0x080c, - 0x6e27, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, - 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68df, 0x601c, 0xd0fc, 0x1148, - 0x7044, 0xd0e4, 0x1904, 0xc458, 0x080c, 0xb16c, 0x009e, 0x00be, - 0x0005, 0x2009, 0x0211, 0x210c, 0x080c, 0x0d85, 0x968c, 0x0c00, - 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc45c, 0x7348, - 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508, - 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, - 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100, - 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118, - 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, - 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4, - 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, - 0x0804, 0xc3a2, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, - 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, - 0x0025, 0x080c, 0xca7b, 0x003e, 0xd6cc, 0x0904, 0xc3b7, 0x7154, - 0xa98a, 0x81ff, 0x0904, 0xc3b7, 0x9192, 0x0021, 0x1278, 0x8304, - 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xca7b, 0x2011, 0x0205, - 0x2013, 0x0000, 0x080c, 0xd5e8, 0x0804, 0xc3b7, 0xa868, 0xd0fc, - 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c, - 0xca1a, 0x00ae, 0x080c, 0xd5e8, 0x080c, 0xca6b, 0x0804, 0xc3b9, - 0x080c, 0xd22a, 0x0804, 0xc3ce, 0xa87c, 0xd0ac, 0x0904, 0xc3df, - 0xa880, 0xd0bc, 0x1904, 0xc3df, 0x9684, 0x0400, 0x0130, 0xa838, - 0xab34, 0x9305, 0x0904, 0xc3df, 0x00b8, 0x7348, 0xa838, 0x9306, - 0x1198, 0x734c, 0xa834, 0x931e, 0x0904, 0xc3df, 0x0068, 0xa87c, - 0xd0ac, 0x0904, 0xc3aa, 0xa838, 0xa934, 0x9105, 0x0904, 0xc3aa, - 0xa880, 0xd0bc, 0x1904, 0xc3aa, 0x080c, 0xd267, 0x0804, 0xc3ce, - 0x00f6, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x00fe, - 0x0021, 0x0005, 0x0011, 0x0005, 0x0005, 0x0096, 0x6003, 0x0002, - 0x6007, 0x0043, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0128, 0x009e, - 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, 0x2300, - 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, 0xac46, - 0xab4a, 0xae36, 0xad3a, 0x6044, 0xd0fc, 0x190c, 0xad25, 0x604b, - 0x0000, 0x080c, 0x1c9c, 0x1118, 0x6144, 0x080c, 0x9643, 0x009e, - 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, - 0x0005, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, - 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e2, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, - 0xc4f3, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc517, 0xc4e0, 0xc4e0, - 0x080c, 0x0d85, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c, 0x99ed, - 0x2019, 0x0001, 0x080c, 0xa596, 0x6003, 0x0002, 0x080c, 0xd662, - 0x080c, 0x9a48, 0x0005, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c, - 0x99ed, 0x2019, 0x0001, 0x080c, 0xa596, 0x080c, 0x9a48, 0x080c, - 0x3315, 0x080c, 0xd65a, 0x0096, 0x6114, 0x2148, 0x080c, 0xcf1b, - 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, - 0x7012, 0x080c, 0xd10c, 0x009e, 0x080c, 0xb16c, 0x0005, 0x080c, - 0x0d85, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, - 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009, 0x1a7c, - 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, - 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, - 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc551, 0xc54f, 0xc54f, - 0xc60e, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, - 0xc54f, 0xc54f, 0xc54f, 0xc74e, 0xc54f, 0xc758, 0xc54f, 0x080c, - 0x0d85, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168, 0xd0f4, 0x0120, - 0xc084, 0x601e, 0x0804, 0xc33e, 0x6114, 0x0096, 0x2148, 0xa87c, - 0xc0e5, 0xa87e, 0x009e, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, - 0x0260, 0x6114, 0x2150, 0x601c, 0xd0fc, 0x1110, 0x7644, 0x0008, - 0x9036, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, - 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, - 0x86ff, 0x0904, 0xc607, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, - 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc607, - 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, - 0x0c38, 0x080c, 0x1059, 0x090c, 0x0d85, 0x2900, 0xb07a, 0xb77c, - 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, - 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, - 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, - 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, - 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, - 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, - 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, - 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, - 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xca7b, 0x003e, - 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, - 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xca7b, - 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, - 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xca1a, 0x080c, - 0x1a9f, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1988, - 0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, - 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0x080c, 0xd66b, - 0x0904, 0xc749, 0x604b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, - 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc70d, 0xa978, 0xa868, - 0xd0fc, 0x0904, 0xc6ce, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, - 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, - 0xc69b, 0x9086, 0x0028, 0x1904, 0xc687, 0xa87b, 0x001c, 0xb07b, - 0x001c, 0x0804, 0xc6a3, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, - 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, - 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, - 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, - 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x601c, - 0xc0fc, 0x601e, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, - 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, - 0x080c, 0x100b, 0x009e, 0x080c, 0xd267, 0x0804, 0xc749, 0xd1dc, - 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd508, 0x0118, - 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, - 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, - 0x9115, 0x190c, 0xc519, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, - 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, - 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, - 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, - 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd5e8, 0x001e, 0xa874, 0x0006, - 0x2148, 0x080c, 0x100b, 0x001e, 0x0804, 0xc73a, 0x0016, 0x00a6, - 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, - 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, - 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd508, 0x0118, - 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, - 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, - 0x9115, 0x190c, 0xc519, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, - 0xb07e, 0x00ae, 0x080c, 0x100b, 0x009e, 0x080c, 0xd5e8, 0xa974, - 0x0016, 0x080c, 0xca6b, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, - 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, - 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, - 0xd508, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, - 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, - 0xa834, 0xa938, 0x9115, 0x190c, 0xc519, 0xa974, 0x0016, 0x080c, - 0x6e27, 0x001e, 0x6010, 0x00b6, 0x2058, 0xba3c, 0xb8d0, 0x0016, - 0x9005, 0x190c, 0x68df, 0x001e, 0x00be, 0xd1e4, 0x1120, 0x080c, - 0xb16c, 0x009e, 0x0005, 0x080c, 0xd22a, 0x0cd8, 0x6114, 0x0096, - 0x2148, 0xa97c, 0x080c, 0xd66b, 0x190c, 0x1abf, 0x009e, 0x0005, - 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x01e8, 0xa877, - 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103, 0x00b6, 0x6010, 0x2058, - 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c, 0x6e27, 0xba3c, 0x8211, - 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68df, 0x080c, - 0xb16c, 0x00be, 0x009e, 0x0005, 0xa87c, 0xc0dc, 0xa87e, 0x08f8, - 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c, 0xc519, 0x0c28, 0xa880, - 0xd0bc, 0x1dc8, 0x080c, 0xd267, 0x0c60, 0x080c, 0x99ed, 0x0010, - 0x080c, 0x9a48, 0x601c, 0xd084, 0x0110, 0x080c, 0x1ad3, 0x080c, - 0xcf1b, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xd132, 0x1118, - 0x080c, 0xbb5c, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, - 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108, 0xa97a, 0x918e, 0x0029, - 0x1110, 0x080c, 0xeddf, 0xa877, 0x0000, 0x080c, 0x7012, 0x009e, - 0x0804, 0xb1a7, 0xa87b, 0x0004, 0x0cb0, 0xa87b, 0x0004, 0x0c98, + 0x9086, 0x0074, 0x1904, 0xbb7f, 0x6010, 0x2058, 0xbaa0, 0x9286, + 0x007e, 0x1120, 0x080c, 0xbdc2, 0x0804, 0xbaec, 0x080c, 0xbdb7, + 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, + 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, + 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd237, 0x0030, + 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, + 0x080c, 0x66c9, 0x080c, 0x332a, 0x080c, 0xaf4e, 0x0804, 0xbb84, + 0x080c, 0xbb92, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, + 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, + 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd237, 0x08f8, 0x080c, + 0xbb88, 0x0160, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0004, 0x080c, + 0x66f5, 0x2001, 0x0007, 0x080c, 0x66c9, 0x08a0, 0x2001, 0x0004, + 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x9427, + 0x080c, 0x98bc, 0x0804, 0xbb84, 0xb85c, 0xd0e4, 0x0178, 0x080c, + 0xd060, 0x080c, 0x769d, 0x0118, 0xd0dc, 0x1904, 0xbaae, 0x2011, + 0x1837, 0x2204, 0xc0ad, 0x2012, 0x0804, 0xbaae, 0x080c, 0xd0a1, + 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe60d, + 0x000e, 0x1904, 0xbaae, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, + 0x66c9, 0x9006, 0x080c, 0x66b5, 0x00c6, 0x2001, 0x180f, 0x2004, + 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, + 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, + 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, + 0x26ea, 0x00f6, 0x2100, 0x900e, 0x080c, 0x26a1, 0x795e, 0x00fe, + 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, + 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, + 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26ea, 0x00f6, 0x2079, + 0x1800, 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x26a1, 0x795e, + 0x00fe, 0x8108, 0x080c, 0x6718, 0x2b00, 0x00ce, 0x1904, 0xbaae, + 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, + 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, + 0x2001, 0x0002, 0x080c, 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001, + 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0028, 0x080c, + 0xb93c, 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, + 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, + 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xeb56, 0x0190, 0x2071, 0x0260, + 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, + 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, + 0x00ee, 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, + 0x66c9, 0x080c, 0x5834, 0x1120, 0x2001, 0x0007, 0x080c, 0x66f5, + 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, + 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, + 0x00be, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4c28, 0x004e, + 0x003e, 0x080c, 0x332a, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, + 0x0804, 0xaf4e, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, + 0x7090, 0x9086, 0x0014, 0x1904, 0xbc32, 0x080c, 0x5834, 0x1170, + 0x6014, 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, + 0x2021, 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e, 0x00d6, 0x6010, + 0x2058, 0x080c, 0x681e, 0x080c, 0xba68, 0x00de, 0x080c, 0xbe8d, + 0x1588, 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, + 0x080c, 0x66c9, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, + 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, + 0x4000, 0x080c, 0xd237, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x0029, 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, + 0x009e, 0x080c, 0x332a, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, + 0xaf4e, 0x0028, 0x080c, 0xb93c, 0x9006, 0x080c, 0xbbaa, 0x001e, + 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, + 0x0014, 0x1160, 0x2001, 0x0002, 0x080c, 0x66c9, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x9427, 0x0804, 0x98bc, 0x2001, 0x0001, + 0x0804, 0xbbaa, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, + 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x66c9, + 0x0804, 0xaf4e, 0x2001, 0x0001, 0x0804, 0xbbaa, 0x0002, 0xba25, + 0xbc7e, 0xba25, 0xbcc1, 0xba25, 0xbd6e, 0xbc73, 0xba28, 0xba25, + 0xbd82, 0xba25, 0xbd94, 0x6604, 0x9686, 0x0003, 0x0904, 0xbbda, + 0x96b6, 0x001e, 0x1110, 0x080c, 0xaf4e, 0x0005, 0x00b6, 0x00d6, + 0x00c6, 0x080c, 0xbda6, 0x11a0, 0x9006, 0x080c, 0x66b5, 0x080c, + 0x32fb, 0x080c, 0xd372, 0x2001, 0x0002, 0x080c, 0x66c9, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0428, + 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, + 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, + 0x000a, 0x0098, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, + 0x1900, 0x0158, 0x908e, 0x1e00, 0x0990, 0x080c, 0x32fb, 0x080c, + 0xd372, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x00ce, 0x00de, 0x00be, + 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xbdb4, 0x00d6, + 0x2069, 0x197d, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, + 0x9086, 0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, + 0x00de, 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x66b5, 0x2001, + 0x0002, 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x0804, 0xbd3e, 0x080c, 0xcc33, 0x01b0, + 0x6014, 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, + 0x0016, 0x2001, 0x0002, 0x080c, 0xd294, 0x00b0, 0x6014, 0x2048, + 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, + 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, + 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c, 0xb93c, 0x2009, 0x026e, + 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, + 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, + 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, + 0x2001, 0x0004, 0x080c, 0x66c9, 0x2001, 0x0028, 0x601a, 0x6007, + 0x0052, 0x0020, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x002e, 0x00be, + 0x009e, 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, + 0xcc33, 0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, + 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, + 0x0138, 0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, + 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x610b, 0x00ee, 0x0010, 0x080c, 0x32fb, 0x0860, 0x2001, 0x0004, + 0x080c, 0x66c9, 0x080c, 0xbdb4, 0x1140, 0x6003, 0x0001, 0x6007, + 0x0003, 0x080c, 0x9427, 0x0804, 0x98bc, 0x080c, 0xb93c, 0x9006, + 0x0804, 0xbbaa, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x66c9, + 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x9427, 0x0804, 0x98bc, + 0x2001, 0x0001, 0x0804, 0xbbaa, 0x00f9, 0x1160, 0x2001, 0x000a, + 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9427, + 0x0804, 0x98bc, 0x2001, 0x0001, 0x0804, 0xbbaa, 0x2009, 0x026e, + 0x2104, 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, + 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, + 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c, 0x6792, 0x001e, 0x00ce, + 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, + 0x6010, 0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, + 0x080c, 0xbe5f, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, + 0x080c, 0x6bc9, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, + 0xe795, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, + 0x2009, 0x0001, 0x080c, 0x32c0, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x30c8, 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, + 0x080c, 0x3404, 0x8108, 0x1f04, 0xbdf8, 0x015e, 0x00ce, 0x080c, + 0xbdb7, 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, + 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, + 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, + 0x2102, 0x9184, 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, + 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, + 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, + 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, + 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26ea, 0x080c, 0x769d, + 0x0170, 0x2071, 0x0260, 0x2069, 0x1983, 0x7048, 0x206a, 0x704c, + 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xd060, 0x0040, + 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c, 0x332a, 0x080c, 0xaf4e, + 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, + 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, + 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, + 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, + 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf54, 0x1148, 0x2011, 0x027a, + 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xbf54, 0x1100, 0x015e, + 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, + 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, + 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, + 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, + 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, + 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f5, + 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, + 0x7254, 0x7074, 0x9202, 0x1a04, 0xbf20, 0x080c, 0x8d87, 0x0904, + 0xbf19, 0x080c, 0xe7c6, 0x0904, 0xbf19, 0x6720, 0x9786, 0x0007, + 0x0904, 0xbf19, 0x2500, 0x9c06, 0x0904, 0xbf19, 0x2400, 0x9c06, + 0x0904, 0xbf19, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, + 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1590, 0x00c6, + 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x1af0, + 0x9786, 0x000a, 0x0148, 0x080c, 0xce4a, 0x1130, 0x00ce, 0x080c, + 0xb93c, 0x080c, 0xaf89, 0x00e8, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, + 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fff, 0x009e, 0xab7a, + 0xa877, 0x0000, 0x080c, 0x6f05, 0x080c, 0xce24, 0x080c, 0xaf89, + 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1210, 0x0804, 0xbec0, + 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, + 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xe738, 0x0c30, + 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, 0x0004, 0x0d08, 0x2009, + 0x004c, 0x080c, 0xafec, 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, + 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xbf40, + 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, + 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, + 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, + 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, + 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, + 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, + 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, + 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xbf7e, 0x9006, + 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, + 0x0d79, 0x080c, 0xce39, 0x0120, 0x080c, 0xce4a, 0x0158, 0x0028, + 0x080c, 0x332a, 0x080c, 0xce4a, 0x0128, 0x080c, 0x97f6, 0x080c, + 0xaf4e, 0x0005, 0x080c, 0xb93c, 0x0cc0, 0x9182, 0x0057, 0x1220, + 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbfc4, 0xbfc4, 0xbfc4, + 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, + 0xbfc6, 0xbfc6, 0xbfc6, 0xbfc6, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc6, + 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0x080c, 0x0d79, 0x600b, 0xffff, + 0x6003, 0x000f, 0x6106, 0x0126, 0x2091, 0x8000, 0x080c, 0xd375, + 0x2009, 0x8000, 0x080c, 0x9420, 0x012e, 0x0005, 0x9186, 0x0013, + 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc04e, 0x9186, 0x0027, + 0x1520, 0x080c, 0x97f6, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096, + 0x6114, 0x2148, 0x080c, 0xcc33, 0x0198, 0x080c, 0xce4a, 0x1118, + 0x080c, 0xb93c, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6f11, 0x080c, 0xce24, + 0x009e, 0x080c, 0xaf4e, 0x0804, 0x98bc, 0x9186, 0x0014, 0x1120, + 0x6004, 0x9082, 0x0040, 0x0030, 0x9186, 0x0053, 0x0110, 0x080c, + 0x0d79, 0x0005, 0x0002, 0xc02c, 0xc02a, 0xc02a, 0xc02a, 0xc02a, + 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc045, 0xc045, + 0xc045, 0xc045, 0xc02a, 0xc045, 0xc02a, 0xc045, 0xc02a, 0xc02a, + 0xc02a, 0xc02a, 0x080c, 0x0d79, 0x080c, 0x97f6, 0x0096, 0x6114, + 0x2148, 0x080c, 0xcc33, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, + 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6f11, 0x080c, + 0xce24, 0x009e, 0x080c, 0xaf4e, 0x0005, 0x080c, 0x97f6, 0x080c, + 0xce4a, 0x090c, 0xb93c, 0x080c, 0xaf4e, 0x0005, 0x0002, 0xc068, + 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, + 0xc066, 0xc066, 0xc06a, 0xc06a, 0xc06a, 0xc06a, 0xc066, 0xc06c, + 0xc066, 0xc06a, 0xc066, 0xc066, 0xc066, 0xc066, 0x080c, 0x0d79, + 0x080c, 0x0d79, 0x080c, 0x0d79, 0x080c, 0xaf4e, 0x0804, 0x98bc, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, - 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7e1, 0xc7df, 0xc7df, - 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, - 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc805, 0xc7df, 0xc7df, 0x080c, - 0x0d85, 0x080c, 0x5848, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, - 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, - 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, - 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, - 0x080c, 0x7012, 0x009e, 0x0804, 0xb16c, 0x080c, 0x5848, 0x0dd8, - 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182, 0x0085, 0x0002, 0xc81e, - 0xc81c, 0xc81c, 0xc82a, 0xc81c, 0xc81c, 0xc81c, 0xc81c, 0xc81c, - 0xc81c, 0xc81c, 0xc81c, 0xc81c, 0x080c, 0x0d85, 0x6003, 0x0001, - 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c, 0x9617, - 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, 0x0260, - 0x7224, 0x6216, 0x7220, 0x080c, 0xcf09, 0x01f8, 0x2268, 0x6800, - 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, 0x00c6, - 0x2d60, 0x00d6, 0x080c, 0xcadc, 0x00de, 0x00ce, 0x0158, 0x702c, - 0xd084, 0x1118, 0x080c, 0xcaa6, 0x0010, 0x6803, 0x0002, 0x6007, - 0x0086, 0x0028, 0x080c, 0xcac8, 0x0d90, 0x6007, 0x0087, 0x6003, - 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x7220, 0x080c, 0xcf09, - 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, - 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xd267, 0x00ce, - 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, - 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092, 0x1a0c, - 0x0d85, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, 0x9186, - 0x0014, 0x190c, 0x0d85, 0x080c, 0x99ed, 0x0096, 0x6014, 0x2048, - 0x080c, 0xcf1b, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, - 0x0029, 0x080c, 0x7012, 0x009e, 0x080c, 0xb1a7, 0x0804, 0x9ab3, - 0xc8ad, 0xc8af, 0xc8af, 0xc8ad, 0xc8ad, 0xc8ad, 0xc8ad, 0xc8ad, - 0xc8ad, 0xc8ad, 0xc8ad, 0xc8ad, 0xc8ad, 0x080c, 0x0d85, 0x080c, - 0xb1a7, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004, 0x9082, 0x0085, - 0x2008, 0x0804, 0xc8fe, 0x9186, 0x0027, 0x1558, 0x080c, 0x99ed, - 0x080c, 0x3315, 0x080c, 0xd65a, 0x0096, 0x6014, 0x2048, 0x080c, - 0xcf1b, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, - 0x080c, 0x7012, 0x080c, 0xd10c, 0x009e, 0x080c, 0xb16c, 0x0005, - 0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140, 0x080c, 0xaf61, - 0x0128, 0x9086, 0x000c, 0x0904, 0xc936, 0x0000, 0x080c, 0xb227, - 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x99ed, 0x0096, 0x6014, - 0x2048, 0x080c, 0xcf1b, 0x0d00, 0xa867, 0x0103, 0xa877, 0x0000, - 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890, 0x0002, 0xc90e, - 0xc90c, 0xc90c, 0xc90c, 0xc90c, 0xc90c, 0xc922, 0xc90c, 0xc90c, - 0xc90c, 0xc90c, 0xc90c, 0xc90c, 0x080c, 0x0d85, 0x6034, 0x908c, - 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, - 0x2001, 0x1986, 0x0010, 0x2001, 0x1987, 0x2004, 0x601a, 0x6003, - 0x000c, 0x0005, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, - 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1986, 0x0010, 0x2001, - 0x1987, 0x2004, 0x601a, 0x6003, 0x000e, 0x0005, 0x9182, 0x0092, - 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xb227, 0xc94c, - 0xc94c, 0xc94c, 0xc94c, 0xc94e, 0xc99b, 0xc94c, 0xc94c, 0xc94c, - 0xc94c, 0xc94c, 0xc94c, 0xc94c, 0x080c, 0x0d85, 0x0096, 0x6010, - 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, - 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, - 0x009e, 0x0804, 0xc9af, 0x080c, 0xcf1b, 0x1118, 0x080c, 0xd10c, - 0x0068, 0x6014, 0x2048, 0x080c, 0xd671, 0x1110, 0x080c, 0xd10c, - 0xa867, 0x0103, 0x080c, 0xd625, 0x080c, 0x7012, 0x00d6, 0x2c68, - 0x080c, 0xb116, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, - 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, - 0x613e, 0x6910, 0x6112, 0x080c, 0xd3b6, 0x695c, 0x615e, 0x6023, - 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x2d60, 0x00de, 0x080c, - 0xb16c, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, - 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, - 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, - 0x2c68, 0x080c, 0xd5bb, 0x11f0, 0x080c, 0xb116, 0x01d8, 0x6106, - 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, - 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, - 0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xd3b6, 0x2009, 0x8020, - 0x080c, 0x9617, 0x2d60, 0x00de, 0x0804, 0xb16c, 0x0096, 0x6014, - 0x2048, 0x080c, 0xcf1b, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, - 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, - 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xd226, 0xa877, - 0x0000, 0x080c, 0x7012, 0x080c, 0xd10c, 0x009e, 0x0804, 0xb16c, - 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0140, 0xa867, - 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x7012, 0x009e, - 0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014, 0x0130, 0x9186, - 0x0027, 0x0118, 0x080c, 0xb227, 0x0020, 0x080c, 0x99ed, 0x080c, - 0xb1a7, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, - 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x8304, - 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c, 0xca7b, - 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x100b, 0x080c, - 0x1059, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, - 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, 0x001b, 0x0499, - 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, - 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, - 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, - 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, - 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, - 0x0130, 0xa807, 0x0000, 0x080c, 0x7012, 0x2a48, 0x0cb8, 0x080c, - 0x7012, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, - 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, - 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, - 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, 0x1148, 0x2018, - 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, - 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, - 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, - 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0150, 0x2001, - 0x0006, 0xa980, 0xc1d5, 0x080c, 0x725e, 0x080c, 0x7006, 0x080c, - 0xd10c, 0x009e, 0x080c, 0xb1a7, 0x00ee, 0x00de, 0x00ce, 0x0005, - 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, 0x6020, 0x9086, - 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, 0x9186, 0x008b, - 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, 0x2091, 0x8000, - 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, 0x012e, 0x006e, - 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000, 0x6020, - 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0xcb2a, 0xcb2a, - 0xcb25, 0xcb4e, 0xcb06, 0xcb25, 0xcb08, 0xcb25, 0xcb25, 0x9458, - 0xcb25, 0xcb25, 0xcb25, 0xcb06, 0xcb06, 0xcb06, 0x080c, 0x0d85, - 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c, 0xcb4e, 0x0036, - 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc, 0x0118, 0x2019, - 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d, 0x0010, 0x2019, - 0x0010, 0x080c, 0xe578, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, - 0x0001, 0x0005, 0x0096, 0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, - 0xcf1b, 0x01d0, 0x6043, 0xffff, 0xa864, 0x9086, 0x0139, 0x1128, - 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, - 0x080c, 0x725e, 0x080c, 0xd226, 0x080c, 0x7006, 0x080c, 0xb1a7, - 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x080c, 0xacfc, - 0x080c, 0xd67f, 0x908a, 0x0010, 0x1a0c, 0x0d85, 0x002b, 0x0106, - 0x080c, 0xad18, 0x010e, 0x0005, 0xcb6c, 0xcb9c, 0xcb6e, 0xcbc3, - 0xcb97, 0xcb6c, 0xcb25, 0xcb2a, 0xcb2a, 0xcb25, 0xcb25, 0xcb25, - 0xcb25, 0xcb25, 0xcb25, 0xcb25, 0x080c, 0x0d85, 0x86ff, 0x1520, - 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, - 0xcf1b, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, - 0xa878, 0x2048, 0x080c, 0x100b, 0x009e, 0x080c, 0xd226, 0x009e, - 0x080c, 0xd5ff, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x2009, 0x8020, 0x080c, 0x95f9, 0x9085, 0x0001, 0x0005, 0x0066, - 0x080c, 0x1ad3, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e8, 0x7030, - 0x9c06, 0x1120, 0x080c, 0xa516, 0x00ee, 0x0840, 0x6020, 0x9084, - 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, - 0x2c40, 0x080c, 0xa667, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c, - 0xa412, 0x190c, 0x0d85, 0x080c, 0xa420, 0x006e, 0x00ee, 0x1904, - 0xcb6e, 0x0804, 0xcb25, 0x0036, 0x00e6, 0x2071, 0x19e8, 0x704c, - 0x9c06, 0x1138, 0x901e, 0x080c, 0xa596, 0x00ee, 0x003e, 0x0804, - 0xcb6e, 0x080c, 0xa7a1, 0x00ee, 0x003e, 0x1904, 0xcb6e, 0x0804, - 0xcb25, 0x00c6, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, - 0x00ce, 0x0005, 0xcbf9, 0xcce2, 0xce50, 0xcc01, 0xb1a7, 0xcbf9, - 0xe56e, 0xd667, 0xcce2, 0x941f, 0xcedc, 0xcbf2, 0xcbf2, 0xcbf2, - 0xcbf2, 0xcbf2, 0x080c, 0x0d85, 0x080c, 0xd132, 0x1110, 0x080c, - 0xbb5c, 0x0005, 0x080c, 0x99ed, 0x0804, 0xb16c, 0x601b, 0x0001, - 0x0005, 0x080c, 0xcf1b, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, - 0xa896, 0x009e, 0x080c, 0xacfc, 0x080c, 0xd67f, 0x908a, 0x0010, - 0x1a0c, 0x0d85, 0x0013, 0x0804, 0xad18, 0xcc25, 0xcc27, 0xcc51, - 0xcc65, 0xcc92, 0xcc25, 0xcbf9, 0xcbf9, 0xcbf9, 0xcc6c, 0xcc6c, - 0xcc25, 0xcc25, 0xcc25, 0xcc25, 0xcc76, 0x080c, 0x0d85, 0x00e6, + 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc0c8, 0xc1ba, 0xc08f, + 0xc1c6, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, + 0xc08f, 0xc08f, 0xc08f, 0xc1c6, 0xc091, 0xc08f, 0xc1c4, 0x080c, + 0x0d79, 0x00b6, 0x0096, 0x6114, 0x2148, 0x6010, 0x2058, 0xb800, + 0xd0bc, 0x1508, 0xa87b, 0x0000, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, + 0x080c, 0x6d26, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, + 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68ae, 0x080c, 0xaf4e, + 0x009e, 0x00be, 0x0005, 0xa87c, 0xd0ac, 0x09e0, 0xa838, 0xa934, + 0x9105, 0x09c0, 0xa880, 0xd0bc, 0x19a8, 0x080c, 0xcf7f, 0x0c80, + 0x00b6, 0x0096, 0x6114, 0x2148, 0x601c, 0xd0fc, 0x1110, 0x7644, + 0x0008, 0x9036, 0x96b4, 0x0fff, 0x86ff, 0x1590, 0x6010, 0x2058, + 0xb800, 0xd0bc, 0x1904, 0xc1a9, 0xa87b, 0x0000, 0xa867, 0x0103, + 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, + 0xc24b, 0x080c, 0x6d26, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, + 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68ae, 0x601c, + 0xd0fc, 0x1148, 0x7044, 0xd0e4, 0x1904, 0xc18a, 0x080c, 0xaf4e, + 0x009e, 0x00be, 0x0005, 0x2009, 0x0211, 0x210c, 0x080c, 0x0d79, + 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, + 0xc18e, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, + 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8, + 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938, + 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c, + 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, + 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, + 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, + 0x1118, 0xc6c4, 0x0804, 0xc0d4, 0x735c, 0xab86, 0x83ff, 0x0170, + 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, + 0x0018, 0x2011, 0x0025, 0x080c, 0xc7ad, 0x003e, 0xd6cc, 0x0904, + 0xc0e9, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc0e9, 0x9192, 0x0021, + 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xc7ad, + 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd300, 0x0804, 0xc0e9, + 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6, + 0x2950, 0x080c, 0xc74c, 0x00ae, 0x080c, 0xd300, 0x080c, 0xc79d, + 0x0804, 0xc0eb, 0x080c, 0xcf42, 0x0804, 0xc100, 0xa87c, 0xd0ac, + 0x0904, 0xc111, 0xa880, 0xd0bc, 0x1904, 0xc111, 0x9684, 0x0400, + 0x0130, 0xa838, 0xab34, 0x9305, 0x0904, 0xc111, 0x00b8, 0x7348, + 0xa838, 0x9306, 0x1198, 0x734c, 0xa834, 0x931e, 0x0904, 0xc111, + 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xc0dc, 0xa838, 0xa934, 0x9105, + 0x0904, 0xc0dc, 0xa880, 0xd0bc, 0x1904, 0xc0dc, 0x080c, 0xcf7f, + 0x0804, 0xc100, 0x00f6, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, + 0x7d08, 0x00fe, 0x0021, 0x0005, 0x0011, 0x0005, 0x0005, 0x0096, + 0x6003, 0x0002, 0x6007, 0x0043, 0x6014, 0x2048, 0xa87c, 0xd0ac, + 0x0128, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, + 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, + 0x0e90, 0xac46, 0xab4a, 0xae36, 0xad3a, 0x6044, 0xd0fc, 0x190c, + 0xab20, 0x604b, 0x0000, 0x080c, 0x1cb9, 0x1118, 0x6144, 0x080c, + 0x944c, 0x009e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xc212, 0xc212, 0xc212, 0xc212, 0xc212, + 0xc212, 0xc212, 0xc212, 0xc212, 0xc212, 0xc214, 0xc212, 0xc212, + 0xc212, 0xc212, 0xc225, 0xc212, 0xc212, 0xc212, 0xc212, 0xc249, + 0xc212, 0xc212, 0x080c, 0x0d79, 0x6004, 0x9086, 0x0040, 0x1110, + 0x080c, 0x97f6, 0x2019, 0x0001, 0x080c, 0xa391, 0x6003, 0x0002, + 0x080c, 0xd37a, 0x080c, 0x9851, 0x0005, 0x6004, 0x9086, 0x0040, + 0x1110, 0x080c, 0x97f6, 0x2019, 0x0001, 0x080c, 0xa391, 0x080c, + 0x9851, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096, 0x6114, 0x2148, + 0x080c, 0xcc33, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e, 0x080c, 0xaf4e, + 0x0005, 0x080c, 0x0d79, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, + 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, + 0x2009, 0x1a7d, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, + 0xa88e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xc281, 0xc281, 0xc281, 0xc281, 0xc281, 0xc283, + 0xc281, 0xc281, 0xc340, 0xc281, 0xc281, 0xc281, 0xc281, 0xc281, + 0xc281, 0xc281, 0xc281, 0xc281, 0xc281, 0xc480, 0xc281, 0xc48a, + 0xc281, 0x080c, 0x0d79, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168, + 0xd0f4, 0x0120, 0xc084, 0x601e, 0x0804, 0xc070, 0x6114, 0x0096, + 0x2148, 0xa87c, 0xc0e5, 0xa87e, 0x009e, 0x0076, 0x00a6, 0x00e6, + 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x601c, 0xd0fc, 0x1110, + 0x7644, 0x0008, 0x9036, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, + 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, + 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc339, 0x9694, 0xff00, 0x9284, + 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, + 0x0904, 0xc339, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, + 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x104d, 0x090c, 0x0d79, 0x2900, + 0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, + 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, + 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, + 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, + 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, + 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, + 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, + 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, + 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, + 0xc7ad, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, + 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, + 0x080c, 0xc7ad, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, + 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, + 0xc74c, 0x080c, 0x1abc, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, + 0x2001, 0x1989, 0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c, + 0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, + 0x080c, 0xd383, 0x0904, 0xc47b, 0x604b, 0x0000, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc43f, + 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc400, 0x0016, 0xa87c, 0x0006, + 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, + 0x0002, 0x0904, 0xc3cd, 0x9086, 0x0028, 0x1904, 0xc3b9, 0xa87b, + 0x001c, 0xb07b, 0x001c, 0x0804, 0xc3d5, 0x6024, 0xd0f4, 0x11d0, + 0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, + 0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, + 0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, + 0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, + 0x00be, 0x601c, 0xc0fc, 0x601e, 0x9006, 0xa876, 0xa892, 0xa88e, + 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, + 0xa878, 0x2048, 0x080c, 0x0fff, 0x009e, 0x080c, 0xcf7f, 0x0804, + 0xc47b, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, + 0xd220, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, + 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, + 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa87c, 0xb07e, 0xa890, + 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, + 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, + 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, + 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd300, 0x001e, + 0xa874, 0x0006, 0x2148, 0x080c, 0x0fff, 0x001e, 0x0804, 0xc46c, + 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, + 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, + 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, + 0xd220, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, + 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, + 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa890, 0xb092, 0xa88c, + 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x0fff, 0x009e, 0x080c, + 0xd300, 0xa974, 0x0016, 0x080c, 0xc79d, 0x001e, 0x0468, 0xa867, + 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, + 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, + 0x0015, 0x080c, 0xd220, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, + 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, + 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa974, + 0x0016, 0x080c, 0x6d26, 0x001e, 0x6010, 0x00b6, 0x2058, 0xba3c, + 0xb8d0, 0x0016, 0x9005, 0x190c, 0x68ae, 0x001e, 0x00be, 0xd1e4, + 0x1120, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xcf42, 0x0cd8, + 0x6114, 0x0096, 0x2148, 0xa97c, 0x080c, 0xd383, 0x190c, 0x1adc, + 0x009e, 0x0005, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, + 0x01e8, 0xa877, 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103, 0x00b6, + 0x6010, 0x2058, 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c, 0x6d26, + 0xba3c, 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, + 0x68ae, 0x080c, 0xaf4e, 0x00be, 0x009e, 0x0005, 0xa87c, 0xc0dc, + 0xa87e, 0x08f8, 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c, 0xc24b, + 0x0c28, 0xa880, 0xd0bc, 0x1dc8, 0x080c, 0xcf7f, 0x0c60, 0x080c, + 0x97f6, 0x0010, 0x080c, 0x9851, 0x601c, 0xd084, 0x0110, 0x080c, + 0x1af0, 0x080c, 0xcc33, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, + 0xce4a, 0x1118, 0x080c, 0xb93c, 0x00a0, 0xa867, 0x0103, 0x2009, + 0x180c, 0x210c, 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108, 0xa97a, + 0x918e, 0x0029, 0x1110, 0x080c, 0xeaee, 0xa877, 0x0000, 0x080c, + 0x6f11, 0x009e, 0x0804, 0xaf89, 0xa87b, 0x0004, 0x0cb0, 0xa87b, + 0x0004, 0x0c98, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc513, + 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, + 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc537, 0xc511, + 0xc511, 0x080c, 0x0d79, 0x080c, 0x5828, 0x01f8, 0x6014, 0x7144, + 0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, + 0x0096, 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, + 0x0128, 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, + 0xa99a, 0xaa9e, 0x080c, 0x6f11, 0x009e, 0x0804, 0xaf4e, 0x080c, + 0x5828, 0x0dd8, 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182, 0x0085, + 0x0002, 0xc550, 0xc54e, 0xc54e, 0xc55c, 0xc54e, 0xc54e, 0xc54e, + 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0x080c, 0x0d79, + 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, + 0x080c, 0x9420, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, + 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xcc21, 0x01f8, + 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, + 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xc80e, 0x00de, 0x00ce, + 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xc7d8, 0x0010, 0x6803, + 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xc7fa, 0x0d90, 0x6007, + 0x0087, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x7220, + 0x080c, 0xcc21, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, + 0xcf7f, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, + 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d79, 0x908a, + 0x0092, 0x1a0c, 0x0d79, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, + 0x0120, 0x9186, 0x0014, 0x190c, 0x0d79, 0x080c, 0x97f6, 0x0096, + 0x6014, 0x2048, 0x080c, 0xcc33, 0x0140, 0xa867, 0x0103, 0xa877, + 0x0000, 0xa87b, 0x0029, 0x080c, 0x6f11, 0x009e, 0x080c, 0xaf89, + 0x0804, 0x98bc, 0xc5df, 0xc5e1, 0xc5e1, 0xc5df, 0xc5df, 0xc5df, + 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0x080c, + 0x0d79, 0x080c, 0xaf89, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004, + 0x9082, 0x0085, 0x2008, 0x0804, 0xc630, 0x9186, 0x0027, 0x1558, + 0x080c, 0x97f6, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096, 0x6014, + 0x2048, 0x080c, 0xcc33, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0029, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e, 0x080c, + 0xaf4e, 0x0005, 0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140, + 0x080c, 0xad4d, 0x0128, 0x9086, 0x000c, 0x0904, 0xc668, 0x0000, + 0x080c, 0xb009, 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x97f6, + 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, 0x0d00, 0xa867, 0x0103, + 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890, + 0x0002, 0xc640, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc654, + 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0x080c, 0x0d79, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, + 0x601a, 0x6003, 0x000c, 0x0005, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, + 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x0005, + 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, + 0xb009, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc680, 0xc6cd, 0xc67e, + 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0x080c, 0x0d79, + 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x009e, 0x0804, 0xc6e1, 0x080c, 0xcc33, 0x1118, + 0x080c, 0xce24, 0x0068, 0x6014, 0x2048, 0x080c, 0xd389, 0x1110, + 0x080c, 0xce24, 0xa867, 0x0103, 0x080c, 0xd33d, 0x080c, 0x6f11, + 0x00d6, 0x2c68, 0x080c, 0xaef8, 0x01d0, 0x6003, 0x0001, 0x6007, + 0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, + 0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd0ce, 0x695c, + 0x615e, 0x6023, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60, + 0x00de, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, + 0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, + 0x1538, 0x00d6, 0x2c68, 0x080c, 0xd2d3, 0x11f0, 0x080c, 0xaef8, + 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, + 0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, + 0x6938, 0x613a, 0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xd0ce, + 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60, 0x00de, 0x0804, 0xaf4e, + 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01c8, 0xa867, 0x0103, + 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, + 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, + 0xcf3e, 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e, + 0x0804, 0xaf4e, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, + 0x6f11, 0x009e, 0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014, + 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xb009, 0x0020, 0x080c, + 0x97f6, 0x080c, 0xaf89, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, + 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, + 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, + 0x080c, 0xc7ad, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, + 0x0fff, 0x080c, 0x104d, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, + 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, + 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, + 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, + 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, + 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, + 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, + 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6f11, 0x2a48, + 0x0cb8, 0x080c, 0x6f11, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, + 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, + 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, + 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, + 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, + 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, + 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, + 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x715d, 0x080c, + 0x6f05, 0x080c, 0xce24, 0x009e, 0x080c, 0xaf89, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, + 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, + 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, + 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, + 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, + 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, + 0xc860, 0xc860, 0xc85b, 0xc884, 0xc838, 0xc85b, 0xc83a, 0xc85b, + 0xc85b, 0x92df, 0xc85b, 0xc85b, 0xc85b, 0xc838, 0xc838, 0xc838, + 0x080c, 0x0d79, 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c, + 0xc884, 0x0036, 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc, + 0x0118, 0x2019, 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d, + 0x0010, 0x2019, 0x0010, 0x080c, 0xe28e, 0x6023, 0x0006, 0x6003, + 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, + 0x0096, 0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01d0, + 0x6043, 0xffff, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, + 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x715d, + 0x080c, 0xcf3e, 0x080c, 0x6f05, 0x080c, 0xaf89, 0x9085, 0x0001, + 0x009e, 0x0005, 0x9006, 0x0ce0, 0x080c, 0xaaf7, 0x080c, 0xd397, + 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x002b, 0x0106, 0x080c, + 0xab13, 0x010e, 0x0005, 0xc8a3, 0xc8d3, 0xc8a5, 0xc8fa, 0xc8ce, + 0xc8a3, 0xc85b, 0xc860, 0xc860, 0xc85b, 0xc85b, 0xc85b, 0xc85b, + 0xc85b, 0xc85b, 0xc85b, 0x080c, 0x0d79, 0x86ff, 0x1520, 0x6020, + 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, + 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, + 0x2048, 0x080c, 0x0fff, 0x009e, 0x080c, 0xcf3e, 0x009e, 0x080c, + 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, + 0x8020, 0x080c, 0x9402, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, + 0x1af0, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7030, 0x9c06, + 0x1120, 0x080c, 0xa311, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, + 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, + 0x080c, 0xa462, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c, 0xa20d, + 0x190c, 0x0d79, 0x080c, 0xa21b, 0x006e, 0x00ee, 0x1904, 0xc8a5, + 0x0804, 0xc85b, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06, + 0x1138, 0x901e, 0x080c, 0xa391, 0x00ee, 0x003e, 0x0804, 0xc8a5, + 0x080c, 0xa59c, 0x00ee, 0x003e, 0x1904, 0xc8a5, 0x0804, 0xc85b, + 0x00c6, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, + 0x0005, 0xc930, 0xc9fe, 0xcb68, 0xc938, 0xaf89, 0xc930, 0xe280, + 0xd37f, 0xc9fe, 0x92a6, 0xcbf4, 0xc929, 0xc929, 0xc929, 0xc929, + 0xc929, 0x080c, 0x0d79, 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c, + 0x0005, 0x080c, 0x97f6, 0x0804, 0xaf4e, 0x601b, 0x0001, 0x0005, + 0x080c, 0xcc33, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, + 0x009e, 0x080c, 0xaaf7, 0x080c, 0xd397, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0d79, 0x0013, 0x0804, 0xab13, 0xc95d, 0xc95f, 0xc989, + 0xc99d, 0xc9ca, 0xc95d, 0xc930, 0xc930, 0xc930, 0xc9a4, 0xc9a4, + 0xc95d, 0xc95d, 0xc95d, 0xc95d, 0xc9ae, 0x080c, 0x0d79, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, - 0x19e8, 0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0xa412, 0x190c, - 0x0d85, 0x080c, 0xa420, 0x006e, 0x080c, 0xd5ff, 0x6007, 0x0085, - 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1987, 0x2004, 0x601a, - 0x2009, 0x8020, 0x080c, 0x95f9, 0x00ee, 0x0005, 0x601b, 0x0001, + 0x19e9, 0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0xa20d, 0x190c, + 0x0d79, 0x080c, 0xa21b, 0x006e, 0x080c, 0xd317, 0x6007, 0x0085, + 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a, + 0x2009, 0x8020, 0x080c, 0x9402, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, - 0x080c, 0xd5ff, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, - 0x2009, 0x8020, 0x080c, 0x95f9, 0x0005, 0x080c, 0xacfc, 0x080c, - 0xaee3, 0x080c, 0xad18, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014, - 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x5848, + 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, + 0x2009, 0x8020, 0x080c, 0x9402, 0x0005, 0x080c, 0xaaf7, 0x080c, + 0xaccf, 0x080c, 0xab13, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014, + 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x5828, 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, - 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x7012, 0x009e, - 0x0804, 0xb16c, 0x6014, 0x0096, 0x904d, 0x0904, 0xccdd, 0xa97c, - 0xd1e4, 0x1160, 0x611c, 0xd1fc, 0x0904, 0xccdd, 0x6110, 0x00b6, - 0x2158, 0xb93c, 0x8109, 0x0208, 0xb93e, 0x00be, 0x080c, 0xad18, - 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, - 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0030, - 0x2c08, 0x080c, 0x16b9, 0x2001, 0x030c, 0x2004, 0x9086, 0x0041, - 0x1198, 0x6014, 0x0096, 0x904d, 0x090c, 0x0d85, 0xa880, 0xd0f4, - 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0068, 0x009e, - 0x00c6, 0x080c, 0x2185, 0x00ce, 0x6000, 0x9086, 0x0004, 0x1120, - 0x2009, 0x0048, 0x080c, 0xb20a, 0x0005, 0x009e, 0x080c, 0x1ad3, - 0x0804, 0xcc51, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d85, 0x000b, - 0x0005, 0xccf9, 0xcbfe, 0xccfb, 0xccf9, 0xccfb, 0xccfb, 0xcbfa, - 0xccf9, 0xcbf4, 0xcbf4, 0xccf9, 0xccf9, 0xccf9, 0xccf9, 0xccf9, - 0xccf9, 0x080c, 0x0d85, 0x6010, 0x00b6, 0x2058, 0xb804, 0x9084, - 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0d85, 0x00b6, 0x0013, - 0x00be, 0x0005, 0xcd16, 0xcde7, 0xcd18, 0xcd58, 0xcd18, 0xcd58, - 0xcd18, 0xcd26, 0xcd16, 0xcd58, 0xcd16, 0xcd47, 0x080c, 0x0d85, - 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e, - 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xcde3, 0x6004, 0x080c, - 0xd132, 0x0904, 0xce00, 0x908e, 0x0004, 0x1110, 0x080c, 0x3344, - 0x908e, 0x0021, 0x0904, 0xce04, 0x908e, 0x0022, 0x0904, 0xce4b, - 0x908e, 0x003d, 0x0904, 0xce04, 0x908e, 0x0039, 0x0904, 0xce08, - 0x908e, 0x0035, 0x0904, 0xce08, 0x908e, 0x001e, 0x0178, 0x908e, - 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff, 0x9086, - 0x0006, 0x0110, 0x080c, 0x3315, 0x080c, 0xbb5c, 0x0804, 0xb1a7, - 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xcdd4, 0x9186, - 0x0002, 0x1904, 0xcda9, 0x2001, 0x1837, 0x2004, 0xd08c, 0x11c8, - 0x080c, 0x779e, 0x11b0, 0x080c, 0xd645, 0x0138, 0x080c, 0x77c1, - 0x1120, 0x080c, 0x76a7, 0x0804, 0xce34, 0x2001, 0x197d, 0x2003, - 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x76cd, 0x0804, - 0xce34, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x0080, 0x0130, 0x2001, - 0x1837, 0x2004, 0xd0ac, 0x1904, 0xce34, 0xb8a0, 0x9082, 0x0081, - 0x1a04, 0xce34, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, + 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6f11, 0x009e, + 0x0804, 0xaf4e, 0x6014, 0x0096, 0x904d, 0x0558, 0xa97c, 0xd1e4, + 0x1158, 0x611c, 0xd1fc, 0x0528, 0x6110, 0x00b6, 0x2158, 0xb93c, + 0x8109, 0x0208, 0xb93e, 0x00be, 0x080c, 0xab13, 0x2001, 0x180f, + 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, + 0x800b, 0x810b, 0x9108, 0x611a, 0x00c6, 0x080c, 0x21a2, 0x00ce, + 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafec, + 0x0005, 0x009e, 0x080c, 0x1af0, 0x0804, 0xc989, 0x6000, 0x908a, + 0x0010, 0x1a0c, 0x0d79, 0x000b, 0x0005, 0xca15, 0xc935, 0xca17, + 0xca15, 0xca17, 0xca17, 0xc931, 0xca15, 0xc92b, 0xc92b, 0xca15, + 0xca15, 0xca15, 0xca15, 0xca15, 0xca15, 0x080c, 0x0d79, 0x6010, + 0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, + 0x1a0c, 0x0d79, 0x00b6, 0x0013, 0x00be, 0x0005, 0xca32, 0xcaff, + 0xca34, 0xca74, 0xca34, 0xca74, 0xca34, 0xca42, 0xca32, 0xca74, + 0xca32, 0xca63, 0x080c, 0x0d79, 0x6004, 0x908e, 0x0016, 0x05c0, + 0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, + 0x0904, 0xcafb, 0x6004, 0x080c, 0xce4a, 0x0904, 0xcb18, 0x908e, + 0x0004, 0x1110, 0x080c, 0x332a, 0x908e, 0x0021, 0x0904, 0xcb1c, + 0x908e, 0x0022, 0x0904, 0xcb63, 0x908e, 0x003d, 0x0904, 0xcb1c, + 0x908e, 0x0039, 0x0904, 0xcb20, 0x908e, 0x0035, 0x0904, 0xcb20, + 0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, + 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x32fb, + 0x080c, 0xb93c, 0x0804, 0xaf89, 0x00c6, 0x00d6, 0x6104, 0x9186, + 0x0016, 0x0904, 0xcaec, 0x9186, 0x0002, 0x1904, 0xcac1, 0x2001, + 0x1837, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x769d, 0x11b0, 0x080c, + 0xd35d, 0x0138, 0x080c, 0x76c0, 0x1120, 0x080c, 0x75a6, 0x0804, + 0xcb4c, 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, + 0x0001, 0x080c, 0x75cc, 0x0804, 0xcb4c, 0x6010, 0x2058, 0x2001, + 0x1837, 0x2004, 0xd0ac, 0x1904, 0xcb4c, 0xb8a0, 0x9084, 0xff80, + 0x1904, 0xcb4c, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, - 0x0000, 0x080c, 0xb116, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, + 0x0000, 0x080c, 0xaef8, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, 0x2104, - 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6130, 0x00ee, - 0x080c, 0xbb5c, 0x0030, 0x080c, 0xbb5c, 0x080c, 0x3315, 0x080c, - 0xd65a, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x3344, 0x012e, - 0x00ee, 0x080c, 0xb1a7, 0x0005, 0x2001, 0x0002, 0x080c, 0x66fa, - 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, - 0x00de, 0x00ce, 0x0c80, 0x080c, 0x3344, 0x0804, 0xcd54, 0x00c6, + 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x610b, 0x00ee, + 0x080c, 0xb93c, 0x0030, 0x080c, 0xb93c, 0x080c, 0x32fb, 0x080c, + 0xd372, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x332a, 0x012e, + 0x00ee, 0x080c, 0xaf89, 0x0005, 0x2001, 0x0002, 0x080c, 0x66c9, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc, + 0x00de, 0x00ce, 0x0c80, 0x080c, 0x332a, 0x0804, 0xca70, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, - 0x9084, 0x00ff, 0x9005, 0x0904, 0xcda9, 0x8001, 0xb842, 0x6003, - 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x00de, 0x00ce, 0x0898, - 0x080c, 0xbb5c, 0x0804, 0xcd56, 0x080c, 0xbb98, 0x0804, 0xcd56, - 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd5bb, 0x00de, 0x0118, 0x080c, - 0xb16c, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, + 0x9084, 0x00ff, 0x9005, 0x0904, 0xcac1, 0x8001, 0xb842, 0x6003, + 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x00de, 0x00ce, 0x0898, + 0x080c, 0xb93c, 0x0804, 0xca72, 0x080c, 0xb978, 0x0804, 0xca72, + 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd2d3, 0x00de, 0x0118, 0x080c, + 0xaf4e, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, - 0x600a, 0x2001, 0x1987, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, + 0x600a, 0x2001, 0x1988, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x2009, - 0x8020, 0x080c, 0x9617, 0x0005, 0x00de, 0x00ce, 0x080c, 0xbb5c, - 0x080c, 0x3315, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x3344, + 0x8020, 0x080c, 0x9420, 0x0005, 0x00de, 0x00ce, 0x080c, 0xb93c, + 0x080c, 0x32fb, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x332a, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, 0x0000, - 0x012e, 0x00ee, 0x0005, 0x080c, 0xb5a8, 0x1904, 0xce00, 0x0005, - 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d85, 0x0096, 0x00d6, 0x001b, - 0x00de, 0x009e, 0x0005, 0xce6b, 0xce6b, 0xce6b, 0xce6b, 0xce6b, - 0xce6b, 0xce6b, 0xce6b, 0xce6b, 0xcbf9, 0xce6b, 0xcbfe, 0xce6d, - 0xcbfe, 0xce87, 0xce6b, 0x080c, 0x0d85, 0x6004, 0x9086, 0x008b, + 0x012e, 0x00ee, 0x0005, 0x080c, 0xb38a, 0x1904, 0xcb18, 0x0005, + 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096, 0x00d6, 0x001b, + 0x00de, 0x009e, 0x0005, 0xcb83, 0xcb83, 0xcb83, 0xcb83, 0xcb83, + 0xcb83, 0xcb83, 0xcb83, 0xcb83, 0xc930, 0xcb83, 0xc935, 0xcb85, + 0xc935, 0xcb9f, 0xcb83, 0x080c, 0x0d79, 0x6004, 0x9086, 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, - 0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x9617, 0x0005, 0x080c, - 0xd639, 0x0118, 0x080c, 0xd64c, 0x0010, 0x080c, 0xd65a, 0x080c, - 0xd10c, 0x080c, 0xcf1b, 0x0570, 0x080c, 0x3315, 0x080c, 0xcf1b, + 0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x9420, 0x0005, 0x080c, + 0xd351, 0x0118, 0x080c, 0xd364, 0x0010, 0x080c, 0xd372, 0x080c, + 0xce24, 0x080c, 0xcc33, 0x0570, 0x080c, 0x32fb, 0x080c, 0xcc33, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, - 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x7012, 0x2c68, 0x080c, - 0xb116, 0x0150, 0x6810, 0x6012, 0x080c, 0xd3b6, 0x00c6, 0x2d60, - 0x080c, 0xb1a7, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, - 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x961e, 0x080c, - 0x9ab3, 0x00c8, 0x080c, 0xd639, 0x0138, 0x6034, 0x9086, 0x4000, - 0x1118, 0x080c, 0x3315, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, - 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3315, - 0x0868, 0x080c, 0xb1a7, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, - 0x0d85, 0x0002, 0xcef2, 0xcef2, 0xcefa, 0xcef4, 0xcf04, 0xcef2, - 0xcef2, 0xb1a7, 0xcef2, 0xcef2, 0xcef2, 0xcef2, 0xcef2, 0xcef2, - 0xcef2, 0xcef2, 0x080c, 0x0d85, 0x080c, 0xacfc, 0x080c, 0xaee3, - 0x080c, 0xad18, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, - 0x7012, 0x009e, 0x0804, 0xb16c, 0x601c, 0xd084, 0x190c, 0x1ad3, + 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6f11, 0x2c68, 0x080c, + 0xaef8, 0x0150, 0x6810, 0x6012, 0x080c, 0xd0ce, 0x00c6, 0x2d60, + 0x080c, 0xaf89, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, + 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, + 0x98bc, 0x00c8, 0x080c, 0xd351, 0x0138, 0x6034, 0x9086, 0x4000, + 0x1118, 0x080c, 0x32fb, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x32fb, + 0x0868, 0x080c, 0xaf89, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, + 0x0d79, 0x0002, 0xcc0a, 0xcc0a, 0xcc12, 0xcc0c, 0xcc1c, 0xcc0a, + 0xcc0a, 0xaf89, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a, + 0xcc0a, 0xcc0a, 0x080c, 0x0d79, 0x080c, 0xaaf7, 0x080c, 0xaccf, + 0x080c, 0xab13, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, + 0x6f11, 0x009e, 0x0804, 0xaf4e, 0x601c, 0xd084, 0x190c, 0x1af0, 0x0c88, 0x9284, 0x0003, 0x1158, 0x9282, 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, 0x6014, 0x2048, 0x000e, - 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x1104, + 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x10f8, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7354, 0x7074, - 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xd645, 0x0180, + 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xd35d, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c, - 0x3315, 0x080c, 0xd65a, 0x00c6, 0x080c, 0xb1a7, 0x00ce, 0x0060, - 0x080c, 0xd328, 0x0148, 0x080c, 0xd132, 0x1110, 0x080c, 0xbb5c, - 0x00c6, 0x080c, 0xb16c, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, + 0x32fb, 0x080c, 0xd372, 0x00c6, 0x080c, 0xaf89, 0x00ce, 0x0060, + 0x080c, 0xd040, 0x0148, 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c, + 0x00c6, 0x080c, 0xaf4e, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, - 0x2061, 0x1b39, 0x6112, 0x080c, 0x3315, 0x9006, 0x0010, 0x9085, + 0x2061, 0x1b3a, 0x6112, 0x080c, 0x32fb, 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x080c, 0xb116, 0x01b0, 0x665e, 0x2b00, 0x6012, 0x080c, - 0x5848, 0x0118, 0x080c, 0xd04e, 0x0168, 0x080c, 0xd3b6, 0x6023, - 0x0003, 0x2009, 0x004b, 0x080c, 0xb20a, 0x9085, 0x0001, 0x012e, + 0x8000, 0x080c, 0xaef8, 0x01b0, 0x665e, 0x2b00, 0x6012, 0x080c, + 0x5828, 0x0118, 0x080c, 0xcd66, 0x0168, 0x080c, 0xd0ce, 0x6023, + 0x0003, 0x2009, 0x004b, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, - 0xbaa0, 0x080c, 0xb1dd, 0x0580, 0x605f, 0x0000, 0x2b00, 0x6012, - 0x080c, 0xd3b6, 0x6023, 0x0003, 0x0016, 0x080c, 0xacfc, 0x080c, - 0x97b0, 0x0076, 0x903e, 0x080c, 0x966d, 0x2c08, 0x080c, 0xe75d, - 0x007e, 0x080c, 0xad18, 0x001e, 0xd184, 0x0128, 0x080c, 0xb16c, - 0x9085, 0x0001, 0x0070, 0x080c, 0x5848, 0x0128, 0xd18c, 0x1170, - 0x080c, 0xd04e, 0x0148, 0x2009, 0x004c, 0x080c, 0xb20a, 0x9085, + 0xbaa0, 0x080c, 0xafbf, 0x0580, 0x605f, 0x0000, 0x2b00, 0x6012, + 0x080c, 0xd0ce, 0x6023, 0x0003, 0x0016, 0x080c, 0xaaf7, 0x080c, + 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465, + 0x007e, 0x080c, 0xab13, 0x001e, 0xd184, 0x0128, 0x080c, 0xaf4e, + 0x9085, 0x0001, 0x0070, 0x080c, 0x5828, 0x0128, 0xd18c, 0x1170, + 0x080c, 0xcd66, 0x0148, 0x2009, 0x004c, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, - 0x0046, 0x0016, 0x080c, 0xb116, 0x2c78, 0x05a0, 0x7e5e, 0x2b00, - 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xd060, + 0x0046, 0x0016, 0x080c, 0xaef8, 0x2c78, 0x05a0, 0x7e5e, 0x2b00, + 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcd78, 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, - 0x1980, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb16c, 0x00d0, - 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb16c, - 0x0088, 0x2f60, 0x080c, 0x5848, 0x0138, 0xd18c, 0x1118, 0x04f1, - 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xb20a, + 0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xaf4e, 0x00d0, + 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xaf4e, + 0x0088, 0x2f60, 0x080c, 0x5828, 0x0138, 0xd18c, 0x1118, 0x04f1, + 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xafec, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, - 0x00c6, 0x0046, 0x080c, 0xb116, 0x2c78, 0x0508, 0x7e5e, 0x2b00, + 0x00c6, 0x0046, 0x080c, 0xaef8, 0x2c78, 0x0508, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, - 0x2001, 0x197e, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb16c, - 0x0060, 0x2f60, 0x080c, 0x5848, 0x0120, 0xd18c, 0x1160, 0x0071, - 0x0130, 0x2009, 0x0052, 0x080c, 0xb20a, 0x9085, 0x0001, 0x004e, + 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xaf4e, + 0x0060, 0x2f60, 0x080c, 0x5828, 0x0120, 0xd18c, 0x1160, 0x0071, + 0x0130, 0x2009, 0x0052, 0x080c, 0xafec, 0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, - 0x4c41, 0x00ce, 0x1120, 0x080c, 0xb16c, 0x9006, 0x0005, 0xa867, + 0x4bc8, 0x00ce, 0x1120, 0x080c, 0xaf4e, 0x9006, 0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, - 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0xacfc, 0x080c, - 0x699d, 0x0158, 0x2001, 0xd067, 0x0006, 0x900e, 0x2400, 0x080c, - 0x725e, 0x080c, 0x7012, 0x000e, 0x0807, 0x2418, 0x080c, 0x99b3, + 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0xaaf7, 0x080c, + 0x6963, 0x0158, 0x2001, 0xcd7f, 0x0006, 0x900e, 0x2400, 0x080c, + 0x715d, 0x080c, 0x6f11, 0x000e, 0x0807, 0x2418, 0x080c, 0x97bc, 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, - 0x97ca, 0x008e, 0x080c, 0x966d, 0x2f08, 0x2648, 0x080c, 0xe75d, - 0xb93c, 0x81ff, 0x090c, 0x98a3, 0x080c, 0xad18, 0x012e, 0x007e, - 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb116, - 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0001, - 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xb20a, 0x9085, 0x0001, + 0x95d3, 0x008e, 0x080c, 0x9476, 0x2f08, 0x2648, 0x080c, 0xe465, + 0xb93c, 0x81ff, 0x090c, 0x96ac, 0x080c, 0xab13, 0x012e, 0x007e, + 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8, + 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001, + 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x080c, 0xb1dd, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, - 0xd3b6, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, - 0x17ad, 0x00fe, 0x2009, 0x0021, 0x080c, 0xb20a, 0x9085, 0x0001, + 0x8000, 0x080c, 0xafbf, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, + 0xd0ce, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, + 0x17a1, 0x00fe, 0x2009, 0x0021, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, - 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0xb116, 0x0198, 0x660a, - 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0001, 0x2900, 0x6016, - 0x001e, 0x0016, 0x080c, 0xb20a, 0x9085, 0x0001, 0x001e, 0x012e, + 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0198, 0x660a, + 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x2900, 0x6016, + 0x001e, 0x0016, 0x080c, 0xafec, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x080c, 0xb1dd, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, - 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xb20a, 0x9085, + 0x080c, 0xafbf, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, + 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0118, 0x8211, 0xba3e, 0x1140, 0xb8d0, 0x9005, @@ -6477,62 +6384,62 @@ unsigned short risc_code01[] = { 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, 0x0096, 0x6020, 0x9086, 0x0004, - 0x01a8, 0x6014, 0x904d, 0x080c, 0xcf1b, 0x0180, 0xa864, 0x9086, + 0x01a8, 0x6014, 0x904d, 0x080c, 0xcc33, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x080c, 0xb1dd, 0x0198, 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, - 0x0001, 0x2900, 0x6016, 0x080c, 0x3315, 0x2009, 0x0028, 0x080c, - 0xb20a, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, + 0x080c, 0xafbf, 0x0198, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, + 0x0001, 0x2900, 0x6016, 0x080c, 0x32fb, 0x2009, 0x0028, 0x080c, + 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, - 0x1178, 0x00b6, 0x080c, 0xbe09, 0x00be, 0x080c, 0xc085, 0x6003, - 0x0001, 0x6007, 0x0029, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0078, + 0x1178, 0x00b6, 0x080c, 0xbb92, 0x00be, 0x080c, 0xbdb7, 0x6003, + 0x0001, 0x6007, 0x0029, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, - 0x0001, 0x080c, 0xd57c, 0x080c, 0xbb5c, 0x080c, 0xb16c, 0x0005, - 0x0096, 0x6014, 0x904d, 0x090c, 0x0d85, 0xa87b, 0x0030, 0xa883, + 0x0001, 0x080c, 0xd294, 0x080c, 0xb93c, 0x080c, 0xaf4e, 0x0005, + 0x0096, 0x6014, 0x904d, 0x090c, 0x0d79, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, - 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x009e, 0x080c, 0xb16c, + 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x009e, 0x080c, 0xaf4e, 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, - 0x66fa, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, - 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x684f, - 0x00be, 0x080c, 0xc15b, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, - 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x66fa, 0x6014, - 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xb57c, 0x0048, 0x6014, - 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xbb5c, 0x080c, 0xb16c, - 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0d85, + 0x66c9, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, + 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x681e, + 0x00be, 0x080c, 0xbe8d, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, + 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x66c9, 0x6014, + 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xb35e, 0x0048, 0x6014, + 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xb93c, 0x080c, 0xaf4e, + 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0d79, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, - 0x6aae, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, - 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x080c, 0xb16c, - 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d85, 0xa87b, 0x0030, 0xa883, + 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e, + 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d79, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, - 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x080c, 0xb16c, 0x0840, + 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x604b, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, - 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9617, 0x0005, 0x00c6, + 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9420, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0130, 0x0066, - 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, 0xcbf9, - 0xd259, 0xd259, 0xd25c, 0xeadc, 0xeaf7, 0xeafa, 0xcbf9, 0xcbf9, - 0xcbf9, 0xcbf9, 0xcbf9, 0xcbf9, 0xcbf9, 0xcbf9, 0xcbf9, 0x080c, - 0x0d85, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118, + 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, 0xc930, + 0xcf71, 0xcf71, 0xcf74, 0xe7e4, 0xe7ff, 0xe802, 0xc930, 0xc930, + 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0x080c, + 0x0d79, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, 0x1834, - 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xb116, 0x0508, - 0x7810, 0x6012, 0x080c, 0xd3b6, 0x7820, 0x9086, 0x0003, 0x0128, + 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xaef8, 0x0508, + 0x7810, 0x6012, 0x080c, 0xd0ce, 0x7820, 0x9086, 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, - 0x795c, 0x615e, 0x2009, 0x8020, 0x080c, 0x9617, 0x2f60, 0x00fe, - 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1988, 0x2004, 0x604a, 0x0005, + 0x795c, 0x615e, 0x2009, 0x8020, 0x080c, 0x9420, 0x2f60, 0x00fe, + 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0x681c, 0xd0fc, 0xc0fc, 0x681e, 0xa87c, 0x1108, 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, - 0xa878, 0x2048, 0x080c, 0x100b, 0x6830, 0x6036, 0x908e, 0x0001, + 0xa878, 0x2048, 0x080c, 0x0fff, 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x695c, 0x615e, 0x6023, 0x0001, 0x6007, 0x0039, - 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x009e, 0x001e, + 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, @@ -6543,615 +6450,613 @@ unsigned short risc_code01[] = { 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, - 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x1982, 0x200c, - 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x955b, 0x2001, 0x1986, - 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1984, 0x200c, - 0x8000, 0x2014, 0x2071, 0x196c, 0x711a, 0x721e, 0x2001, 0x0064, - 0x080c, 0x955b, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, - 0x2202, 0x2001, 0x1988, 0x9288, 0x000a, 0x2102, 0x2001, 0x0017, - 0x080c, 0xaced, 0x2001, 0x1a90, 0x2102, 0x2001, 0x0032, 0x080c, - 0x16b9, 0x080c, 0x6bf2, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, - 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1986, 0x2003, 0x0028, - 0x2001, 0x1987, 0x2003, 0x0014, 0x2071, 0x196c, 0x701b, 0x0000, - 0x701f, 0x07d0, 0x2001, 0x1988, 0x2009, 0x001e, 0x2102, 0x2001, - 0x0017, 0x080c, 0xaced, 0x2001, 0x1a90, 0x2102, 0x2001, 0x0032, - 0x080c, 0x16b9, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6060, - 0x904d, 0x0110, 0x080c, 0x108b, 0x009e, 0x0005, 0x0005, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x080c, 0xb116, 0x0180, 0x2b08, 0x6112, + 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x1983, 0x200c, + 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x9364, 0x2001, 0x1987, + 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1985, 0x200c, + 0x8000, 0x2014, 0x2071, 0x196d, 0x711a, 0x721e, 0x2001, 0x0064, + 0x080c, 0x9364, 0x2001, 0x1988, 0x82ff, 0x1110, 0x2011, 0x0014, + 0x2202, 0x2001, 0x1989, 0x9288, 0x000a, 0x2102, 0x2001, 0x0017, + 0x080c, 0xaae8, 0x2001, 0x1a91, 0x2102, 0x2001, 0x0032, 0x080c, + 0x16ad, 0x080c, 0x6bae, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003, 0x0028, + 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b, 0x0000, + 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102, 0x2001, + 0x0017, 0x080c, 0xaae8, 0x2001, 0x1a91, 0x2102, 0x2001, 0x0032, + 0x080c, 0x16ad, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6060, + 0x904d, 0x0110, 0x080c, 0x107f, 0x009e, 0x0005, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, - 0xb20a, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, + 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018, 0x0120, 0x7090, 0x9086, 0x0014, 0x11e0, - 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x9b83, + 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x998c, 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, - 0x3364, 0x080c, 0xb57c, 0x0020, 0x080c, 0xbb5c, 0x080c, 0xb16c, + 0x334a, 0x080c, 0xb35e, 0x0020, 0x080c, 0xb93c, 0x080c, 0xaf4e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48, - 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb116, 0x0188, - 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0001, 0x2900, 0x6016, - 0x2009, 0x004d, 0x080c, 0xb20a, 0x9085, 0x0001, 0x012e, 0x00ce, + 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0188, + 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x2900, 0x6016, + 0x2009, 0x004d, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, - 0x080c, 0xb116, 0x0180, 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, - 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xb20a, 0x9085, 0x0001, + 0x080c, 0xaef8, 0x0180, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, + 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, 0x7190, 0x6014, 0x2048, 0xa814, - 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, + 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, - 0x2001, 0x19a1, 0x0016, 0x200c, 0x080c, 0xdca1, 0x001e, 0xa804, + 0x2001, 0x19a2, 0x0016, 0x200c, 0x080c, 0xd9b7, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, - 0x0010, 0x080c, 0xbb5c, 0x080c, 0xb16c, 0x00fe, 0x00ee, 0x009e, + 0x0010, 0x080c, 0xb93c, 0x080c, 0xaf4e, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090, - 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, 0x9b83, + 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, 0x998c, 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206, - 0x1110, 0x080c, 0x3315, 0x080c, 0xb57c, 0x0020, 0x080c, 0xbb5c, - 0x080c, 0xb16c, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, + 0x1110, 0x080c, 0x32fb, 0x080c, 0xb35e, 0x0020, 0x080c, 0xb93c, + 0x080c, 0xaf4e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x7090, 0x9086, 0x0004, 0x1530, 0x6014, - 0x2048, 0x2c78, 0x080c, 0x9b83, 0x05f0, 0x707c, 0xaacc, 0x9206, - 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160, 0x080c, 0x3315, 0x0016, - 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57e9, 0x001e, - 0x0010, 0x080c, 0x55cc, 0x080c, 0xcf1b, 0x0508, 0xa87b, 0x0000, - 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xcf1b, 0x01b8, - 0x6014, 0x2048, 0x080c, 0x55cc, 0x1d70, 0xa87b, 0x0030, 0xa883, + 0x2048, 0x2c78, 0x080c, 0x998c, 0x05f0, 0x707c, 0xaacc, 0x9206, + 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160, 0x080c, 0x32fb, 0x0016, + 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57c9, 0x001e, + 0x0010, 0x080c, 0x55ac, 0x080c, 0xcc33, 0x0508, 0xa87b, 0x0000, + 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xcc33, 0x01b8, + 0x6014, 0x2048, 0x080c, 0x55ac, 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, - 0xa867, 0x0139, 0x080c, 0x7012, 0x012e, 0x080c, 0xb16c, 0x00fe, + 0xa867, 0x0139, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6, - 0x00d6, 0x0036, 0x080c, 0xcf1b, 0x0904, 0xd578, 0x0096, 0x6314, + 0x00d6, 0x0036, 0x080c, 0xcc33, 0x0904, 0xd290, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, - 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6aae, + 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, - 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6, + 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fca, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080, - 0x000a, 0x2098, 0x080c, 0x0fd6, 0x00ce, 0x0090, 0xaa96, 0x3918, + 0x000a, 0x2098, 0x080c, 0x0fca, 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, - 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x7006, 0x6017, 0x0000, 0x009e, + 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6f05, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, - 0x268c, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, - 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4ca1, 0x00a8, 0x9096, + 0x26a1, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, + 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4c28, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, - 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xcf09, 0x01f0, 0x2260, + 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xcc21, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0198, 0x918c, 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, 0x000f, 0x918e, 0x0001, 0x1140, 0xa87c, 0xd0ac, - 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc519, 0x0005, 0x0036, + 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, - 0xcf1b, 0x01c8, 0x080c, 0xd10c, 0x6037, 0x4000, 0x6014, 0x6017, - 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xd132, 0x1118, 0x080c, - 0xbb5c, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, - 0x080c, 0x7012, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, + 0xcc33, 0x01c8, 0x080c, 0xce24, 0x6037, 0x4000, 0x6014, 0x6017, + 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xce4a, 0x1118, 0x080c, + 0xb93c, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, + 0x080c, 0x6f11, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, - 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xd226, 0xa877, 0x0000, + 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf3e, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, - 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4e58, 0x004e, - 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1986, 0x2004, - 0x601a, 0x0005, 0x2001, 0x1988, 0x2004, 0x604a, 0x0005, 0x080c, - 0xb16c, 0x0804, 0x9ab3, 0x611c, 0xd1fc, 0xa97c, 0x1108, 0xd1e4, + 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4ddf, 0x004e, + 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1987, 0x2004, + 0x601a, 0x0005, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005, 0x080c, + 0xaf4e, 0x0804, 0x98bc, 0x611c, 0xd1fc, 0xa97c, 0x1108, 0xd1e4, 0x0005, 0x601c, 0xd0fc, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x601c, 0xd0fc, 0xc0fc, 0x601e, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x6044, - 0xd0fc, 0x1138, 0xd0bc, 0x01a0, 0xc0bc, 0x6046, 0x2001, 0x0002, - 0x0080, 0xd0ac, 0x1168, 0xd0dc, 0x1128, 0x908c, 0x000f, 0x9186, - 0x0005, 0x1118, 0x2001, 0x0003, 0x0020, 0x2001, 0x0001, 0x0008, - 0x6000, 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, - 0x0d85, 0x001b, 0x006e, 0x00be, 0x0005, 0xd6b5, 0xddfe, 0xdf62, - 0xd6b5, 0xd6b5, 0xd6b5, 0xd6b5, 0xd6b5, 0xd6ec, 0xdfe6, 0xd6b5, - 0xd6b5, 0xd6b5, 0xd6b5, 0xd6b5, 0xd6b5, 0x080c, 0x0d85, 0x0066, - 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, - 0xd6d0, 0xe50b, 0xd6d0, 0xd6d0, 0xd6d0, 0xd6d0, 0xd6d0, 0xd6d0, - 0xe4ba, 0xe55d, 0xd6d0, 0xec10, 0xec44, 0xec10, 0xec44, 0xd6d0, - 0x080c, 0x0d85, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0d85, 0x6000, - 0x000a, 0x0005, 0xd6ea, 0xe1c3, 0xe28e, 0xe2b1, 0xe32d, 0xd6ea, - 0xe42a, 0xe3b5, 0xdff0, 0xe492, 0xe4a7, 0xd6ea, 0xd6ea, 0xd6ea, - 0xd6ea, 0xd6ea, 0x080c, 0x0d85, 0x91b2, 0x0053, 0x1a0c, 0x0d85, - 0x2100, 0x91b2, 0x0040, 0x1a04, 0xdb70, 0x0002, 0xd736, 0xd93e, - 0xd736, 0xd736, 0xd736, 0xd947, 0xd736, 0xd736, 0xd736, 0xd736, - 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, - 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xd738, 0xd79f, 0xd7ae, - 0xd812, 0xd83d, 0xd8b6, 0xd929, 0xd736, 0xd736, 0xd94a, 0xd736, - 0xd736, 0xd95f, 0xd96c, 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, - 0xda12, 0xd736, 0xd736, 0xda26, 0xd736, 0xd736, 0xd9e1, 0xd736, - 0xd736, 0xd736, 0xda3e, 0xd736, 0xd736, 0xd736, 0xdabb, 0xd736, - 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xdb38, 0x080c, 0x0d85, - 0x080c, 0x6bcf, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, - 0x9084, 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, - 0x0009, 0x6017, 0x0000, 0x0804, 0xd937, 0x080c, 0x6b6b, 0x00e6, - 0x00c6, 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, - 0x2019, 0x0029, 0x080c, 0xacfc, 0x080c, 0x97b0, 0x0076, 0x903e, - 0x080c, 0x966d, 0x2c08, 0x080c, 0xe75d, 0x007e, 0x001e, 0x080c, - 0xad18, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, - 0x080c, 0x67c3, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, - 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, - 0x080c, 0xee6f, 0x002e, 0x001e, 0x1178, 0x080c, 0xe68b, 0x1904, - 0xd80a, 0x080c, 0xe627, 0x1120, 0x6007, 0x0008, 0x0804, 0xd937, - 0x6007, 0x0009, 0x0804, 0xd937, 0x080c, 0xe905, 0x0128, 0x080c, - 0xe68b, 0x0d78, 0x0804, 0xd80a, 0x6017, 0x1900, 0x0c88, 0x080c, - 0x344c, 0x1904, 0xdb6d, 0x6106, 0x080c, 0xe5c7, 0x6007, 0x0006, - 0x0804, 0xd937, 0x6007, 0x0007, 0x0804, 0xd937, 0x080c, 0xec80, - 0x1904, 0xdb6d, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x00d6, 0x6610, - 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, - 0x0001, 0x080c, 0x66e6, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, - 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, - 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, - 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, - 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, - 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, - 0x080c, 0xe6f3, 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, - 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3364, 0x002e, 0x080c, 0x684f, - 0x6007, 0x000a, 0x00de, 0x0804, 0xd937, 0x6007, 0x000b, 0x00de, - 0x0804, 0xd937, 0x080c, 0x3315, 0x080c, 0xd65a, 0x6007, 0x0001, - 0x0804, 0xd937, 0x080c, 0xec80, 0x1904, 0xdb6d, 0x080c, 0x344c, - 0x1904, 0xdb6d, 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, - 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, - 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, - 0xbaa0, 0x900e, 0x080c, 0x3364, 0x002e, 0x6007, 0x000c, 0x2001, - 0x0001, 0x080c, 0xee4e, 0x0804, 0xd937, 0x080c, 0x6bcf, 0x1140, - 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, - 0x0804, 0xd745, 0x080c, 0x6b6b, 0x6610, 0x2658, 0xbe04, 0x9684, - 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, - 0x080c, 0x6726, 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, - 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd80a, 0x080c, 0xe700, - 0x1120, 0x6007, 0x000e, 0x0804, 0xd937, 0x0046, 0x6410, 0x2458, - 0xbca0, 0x0046, 0x080c, 0x3315, 0x080c, 0xd65a, 0x004e, 0x0016, + 0xd0fc, 0x1138, 0xd0bc, 0x0198, 0xc0bc, 0x6046, 0x6003, 0x0002, + 0x0070, 0xd0ac, 0x1160, 0xd0dc, 0x1128, 0x908c, 0x000f, 0x9186, + 0x0005, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x0005, + 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x001b, + 0x006e, 0x00be, 0x0005, 0xd3cb, 0xdb14, 0xdc78, 0xd3cb, 0xd3cb, + 0xd3cb, 0xd3cb, 0xd3cb, 0xd402, 0xdcfc, 0xd3cb, 0xd3cb, 0xd3cb, + 0xd3cb, 0xd3cb, 0xd3cb, 0x080c, 0x0d79, 0x0066, 0x6000, 0x90b2, + 0x0010, 0x1a0c, 0x0d79, 0x0013, 0x006e, 0x0005, 0xd3e6, 0xe21d, + 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xe1cc, 0xe26f, + 0xd3e6, 0xe91f, 0xe953, 0xe91f, 0xe953, 0xd3e6, 0x080c, 0x0d79, + 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0d79, 0x6000, 0x000a, 0x0005, + 0xd400, 0xded9, 0xdfa4, 0xdfc7, 0xe043, 0xd400, 0xe13e, 0xe0cb, + 0xdd06, 0xe1a4, 0xe1b9, 0xd400, 0xd400, 0xd400, 0xd400, 0xd400, + 0x080c, 0x0d79, 0x91b2, 0x0053, 0x1a0c, 0x0d79, 0x2100, 0x91b2, + 0x0040, 0x1a04, 0xd886, 0x0002, 0xd44c, 0xd654, 0xd44c, 0xd44c, + 0xd44c, 0xd65d, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, + 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, + 0xd44c, 0xd44c, 0xd44c, 0xd44e, 0xd4b5, 0xd4c4, 0xd528, 0xd553, + 0xd5cc, 0xd63f, 0xd44c, 0xd44c, 0xd660, 0xd44c, 0xd44c, 0xd675, + 0xd682, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd728, 0xd44c, + 0xd44c, 0xd73c, 0xd44c, 0xd44c, 0xd6f7, 0xd44c, 0xd44c, 0xd44c, + 0xd754, 0xd44c, 0xd44c, 0xd44c, 0xd7d1, 0xd44c, 0xd44c, 0xd44c, + 0xd44c, 0xd44c, 0xd44c, 0xd84e, 0x080c, 0x0d79, 0x080c, 0x6b8b, + 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009, + 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017, + 0x0000, 0x0804, 0xd64d, 0x080c, 0x6b27, 0x00e6, 0x00c6, 0x0036, + 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, + 0x080c, 0xaaf7, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, + 0x2c08, 0x080c, 0xe465, 0x007e, 0x001e, 0x080c, 0xab13, 0x001e, + 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x6792, + 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, + 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xeb7e, + 0x002e, 0x001e, 0x1178, 0x080c, 0xe393, 0x1904, 0xd520, 0x080c, + 0xe32f, 0x1120, 0x6007, 0x0008, 0x0804, 0xd64d, 0x6007, 0x0009, + 0x0804, 0xd64d, 0x080c, 0xe60d, 0x0128, 0x080c, 0xe393, 0x0d78, + 0x0804, 0xd520, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3432, 0x1904, + 0xd883, 0x6106, 0x080c, 0xe2cf, 0x6007, 0x0006, 0x0804, 0xd64d, + 0x6007, 0x0007, 0x0804, 0xd64d, 0x080c, 0xe98f, 0x1904, 0xd883, + 0x080c, 0x3432, 0x1904, 0xd883, 0x00d6, 0x6610, 0x2658, 0xbe04, + 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, + 0x66b5, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, + 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, + 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, + 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, + 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, + 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe3fb, + 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, + 0x900e, 0x080c, 0x334a, 0x002e, 0x080c, 0x681e, 0x6007, 0x000a, + 0x00de, 0x0804, 0xd64d, 0x6007, 0x000b, 0x00de, 0x0804, 0xd64d, + 0x080c, 0x32fb, 0x080c, 0xd372, 0x6007, 0x0001, 0x0804, 0xd64d, + 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432, 0x1904, 0xd883, + 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, + 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, + 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, + 0x080c, 0x334a, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, + 0xeb5d, 0x0804, 0xd64d, 0x080c, 0x6b8b, 0x1140, 0x2001, 0x1837, + 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd45b, + 0x080c, 0x6b27, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, + 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x66f5, + 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, + 0x9686, 0x0006, 0x1904, 0xd520, 0x080c, 0xe408, 0x1120, 0x6007, + 0x000e, 0x0804, 0xd64d, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, + 0x080c, 0x32fb, 0x080c, 0xd372, 0x004e, 0x0016, 0x9006, 0x2009, + 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe795, + 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, + 0x0001, 0x0804, 0xd64d, 0x2001, 0x0001, 0x080c, 0x66b5, 0x0156, + 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, + 0x0270, 0x080c, 0xbf40, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, + 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xd520, + 0x9682, 0x0007, 0x0a04, 0xd57c, 0x0804, 0xd520, 0x6017, 0x1900, + 0x6007, 0x0009, 0x0804, 0xd64d, 0x080c, 0x6b8b, 0x1140, 0x2001, + 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, + 0xd45b, 0x080c, 0x6b27, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, + 0x0006, 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, + 0x001e, 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, 0x06a0, + 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, + 0x0006, 0x1904, 0xd520, 0x080c, 0xe436, 0x1138, 0x080c, 0xe32f, + 0x1120, 0x6007, 0x0010, 0x0804, 0xd64d, 0x0046, 0x6410, 0x2458, + 0xbca0, 0x0046, 0x080c, 0x32fb, 0x080c, 0xd372, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, - 0x080c, 0xea8d, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, - 0x004e, 0x6007, 0x0001, 0x0804, 0xd937, 0x2001, 0x0001, 0x080c, - 0x66e6, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, - 0x1805, 0x2011, 0x0270, 0x080c, 0xc20e, 0x003e, 0x002e, 0x001e, - 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, - 0x0a04, 0xd80a, 0x9682, 0x0007, 0x0a04, 0xd866, 0x0804, 0xd80a, - 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xd937, 0x080c, 0x6bcf, - 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, - 0x1110, 0x0804, 0xd745, 0x080c, 0x6b6b, 0x6610, 0x2658, 0xbe04, - 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, - 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, - 0x0006, 0x06a0, 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, - 0x0120, 0x9686, 0x0006, 0x1904, 0xd80a, 0x080c, 0xe72e, 0x1138, - 0x080c, 0xe627, 0x1120, 0x6007, 0x0010, 0x0804, 0xd937, 0x0046, - 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3315, 0x080c, 0xd65a, - 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, - 0x2009, 0x0029, 0x080c, 0xea8d, 0x6010, 0x2058, 0xb800, 0xc0e5, - 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, 0xe905, - 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, - 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, - 0x0920, 0x0804, 0xd80a, 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, - 0x0070, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x080c, 0xec80, 0x1904, - 0xdb6d, 0x080c, 0xdd3e, 0x1904, 0xd80a, 0x6007, 0x0012, 0x6003, - 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0005, 0x6007, 0x0001, - 0x6003, 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0cb0, 0x6007, - 0x0005, 0x0c68, 0x080c, 0xec80, 0x1904, 0xdb6d, 0x080c, 0x344c, - 0x1904, 0xdb6d, 0x080c, 0xdd3e, 0x1904, 0xd80a, 0x6007, 0x0020, - 0x6003, 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0005, 0x080c, - 0x344c, 0x1904, 0xdb6d, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, - 0x961e, 0x080c, 0x9ab3, 0x0005, 0x080c, 0xec80, 0x1904, 0xdb6d, - 0x080c, 0x344c, 0x1904, 0xdb6d, 0x080c, 0xdd3e, 0x1904, 0xd80a, - 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, - 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, - 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xcf09, 0x0570, - 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, - 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0xb16c, 0x04a0, - 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xcf09, 0x01b0, - 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, - 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, - 0xea57, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, - 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, - 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, - 0x0024, 0x1110, 0x080c, 0xb16c, 0x2160, 0x6007, 0x0025, 0x6003, - 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x00ee, 0x002e, 0x001e, - 0x0005, 0x2001, 0x0001, 0x080c, 0x66e6, 0x0156, 0x0016, 0x0026, - 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, - 0xc20e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, - 0x0804, 0xd937, 0x080c, 0xbe21, 0x080c, 0x779e, 0x1190, 0x0006, - 0x0026, 0x0036, 0x080c, 0x77b8, 0x1138, 0x080c, 0x7ab6, 0x080c, - 0x619d, 0x080c, 0x76cd, 0x0010, 0x080c, 0x7772, 0x003e, 0x002e, - 0x000e, 0x0005, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x080c, 0xdd3e, - 0x1904, 0xd80a, 0x6106, 0x080c, 0xdd5a, 0x1120, 0x6007, 0x002b, - 0x0804, 0xd937, 0x6007, 0x002c, 0x0804, 0xd937, 0x080c, 0xec80, - 0x1904, 0xdb6d, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x080c, 0xdd3e, - 0x1904, 0xd80a, 0x6106, 0x080c, 0xdd5f, 0x1120, 0x6007, 0x002e, - 0x0804, 0xd937, 0x6007, 0x002f, 0x0804, 0xd937, 0x080c, 0x344c, - 0x1904, 0xdb6d, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, - 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, - 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd93e, - 0x080c, 0x5844, 0xd0e4, 0x0904, 0xdab8, 0x2071, 0x026c, 0x7010, - 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x6c0d, 0x0140, - 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, - 0x080c, 0x6c09, 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, - 0x687c, 0x9106, 0x1578, 0x7210, 0x080c, 0xcf09, 0x0590, 0x080c, - 0xdc2b, 0x0578, 0x080c, 0xeb09, 0x0560, 0x622e, 0x6007, 0x0036, - 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x00ce, 0x00de, - 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xcf09, - 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, - 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xea57, 0x2c10, 0x2160, - 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, - 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, - 0x6007, 0x0012, 0x0868, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x6010, - 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, - 0xd93e, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x5844, 0xd0e4, 0x0904, - 0xdb30, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, - 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, - 0x0001, 0x080c, 0xea57, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xcf09, - 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, - 0x0026, 0x2260, 0x080c, 0xcadc, 0x002e, 0x00ce, 0x7118, 0x918c, - 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, - 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, - 0x080c, 0xdc2b, 0x0904, 0xdab1, 0x0056, 0x7510, 0x7614, 0x080c, - 0xeb22, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, - 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, - 0x080c, 0x9617, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, - 0x0300, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x0c10, - 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xda88, - 0x00e6, 0x0026, 0x080c, 0x6bcf, 0x0550, 0x080c, 0x6b6b, 0x080c, - 0xecf1, 0x1518, 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, - 0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, - 0x9284, 0xff00, 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, - 0x0000, 0x080c, 0x6c0d, 0x0120, 0x2011, 0x1a0a, 0x2013, 0x07d0, - 0xd0ac, 0x1128, 0x080c, 0x30bf, 0x0010, 0x080c, 0xed25, 0x002e, - 0x00ee, 0x080c, 0xb16c, 0x0804, 0xd93d, 0x080c, 0xb16c, 0x0005, - 0x2600, 0x0002, 0xdb84, 0xdbb2, 0xdbc3, 0xdb84, 0xdb84, 0xdb86, - 0xdbd4, 0xdb84, 0xdb84, 0xdb84, 0xdba0, 0xdb84, 0xdb84, 0xdb84, - 0xdbdf, 0xdbf5, 0xdc26, 0xdb84, 0x080c, 0x0d85, 0x080c, 0xec80, - 0x1d20, 0x080c, 0x344c, 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, - 0x6003, 0x0001, 0x080c, 0x961e, 0x0005, 0x080c, 0x3315, 0x080c, - 0xd65a, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x961e, 0x0005, - 0x080c, 0xec80, 0x1950, 0x080c, 0x344c, 0x1938, 0x080c, 0xdd3e, - 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, - 0x961e, 0x0005, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x2009, 0x0041, - 0x080c, 0xed2e, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x961e, - 0x080c, 0x9ab3, 0x0005, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x2009, - 0x0042, 0x080c, 0xed2e, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, - 0x961e, 0x080c, 0x9ab3, 0x0005, 0x080c, 0x344c, 0x1904, 0xdb6d, - 0x2009, 0x0046, 0x080c, 0xed2e, 0x080c, 0xb16c, 0x0005, 0x2001, - 0x1824, 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, 0xdc48, 0x0904, - 0xdb6d, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x961e, 0x080c, - 0x9ab3, 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, - 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, - 0x1160, 0x7140, 0x2001, 0x19be, 0x2004, 0x9106, 0x11b0, 0x7144, - 0x2001, 0x19bf, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, - 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, - 0x000a, 0x080c, 0xc222, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, - 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0005, 0x6007, 0x0050, - 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, - 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128, - 0x604c, 0x9106, 0x1120, 0x712c, 0x6050, 0x9106, 0x0110, 0x9006, - 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, - 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, - 0x8000, 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, - 0x0000, 0x080c, 0x1072, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, - 0xa816, 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, - 0x0016, 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, - 0x1072, 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, - 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, - 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, - 0x2071, 0x1800, 0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x100b, - 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, - 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, - 0x11b0, 0x080c, 0x21f9, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, - 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, - 0x22a8, 0x8108, 0x080c, 0x21f9, 0x2099, 0x0260, 0x0ca8, 0x080c, - 0x21f9, 0x2061, 0x19a1, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, - 0x0108, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, - 0x8108, 0x080c, 0x21f9, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a1, - 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, - 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, - 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, - 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x2211, - 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, - 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, - 0x080c, 0x2211, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x2211, 0x2061, - 0x19a4, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, - 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, - 0x080c, 0x2211, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a4, 0x2019, - 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, - 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, - 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, - 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, - 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, - 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, - 0x00be, 0x0005, 0x00d6, 0x080c, 0xddd4, 0x00de, 0x0005, 0x00d6, - 0x080c, 0xdde1, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, - 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, - 0x080c, 0xee4e, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, - 0x918c, 0x00ff, 0x6824, 0x080c, 0x268c, 0x1148, 0x2001, 0x0001, - 0x080c, 0xee4e, 0x2110, 0x900e, 0x080c, 0x3364, 0x0018, 0x9085, - 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, - 0xb1dd, 0x0598, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, - 0x8211, 0x220c, 0x080c, 0x268c, 0x1568, 0x080c, 0x6749, 0x1550, - 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, - 0xec80, 0x11c8, 0x080c, 0x344c, 0x11b0, 0x080c, 0xdd3e, 0x0500, - 0x2001, 0x0007, 0x080c, 0x66fa, 0x2001, 0x0007, 0x080c, 0x6726, - 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, - 0x080c, 0x961e, 0x0010, 0x080c, 0xb16c, 0x9085, 0x0001, 0x00ce, - 0x00be, 0x0005, 0x080c, 0xb16c, 0x00ce, 0x002e, 0x001e, 0x0ca8, - 0x080c, 0xb16c, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, - 0x0010, 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, - 0x0005, 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, - 0x9086, 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, - 0x0014, 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x6162, - 0x908e, 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, - 0x0053, 0x1a0c, 0x0d85, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, - 0x0040, 0x1a04, 0xdf36, 0x0402, 0x91b6, 0x0027, 0x0190, 0x9186, - 0x0015, 0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xaf61, 0x0120, - 0x9086, 0x0002, 0x0904, 0xbba3, 0x0005, 0x91b6, 0x0014, 0x190c, - 0x0d85, 0x2001, 0x0007, 0x080c, 0x6726, 0x080c, 0x99ed, 0x080c, - 0xb1a7, 0x080c, 0x9ab3, 0x0005, 0xde6c, 0xde6e, 0xde6c, 0xde6c, - 0xde6c, 0xde6e, 0xde7b, 0xdf33, 0xdebd, 0xdf33, 0xdee1, 0xdf33, - 0xde7b, 0xdf33, 0xdf2b, 0xdf33, 0xdf2b, 0xdf33, 0xdf33, 0xde6c, - 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xde6c, - 0xde6c, 0xde6c, 0xde6e, 0xde6c, 0xdf33, 0xde6c, 0xde6c, 0xdf33, - 0xde6c, 0xdf30, 0xdf33, 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xdf33, - 0xdf33, 0xde6c, 0xdf33, 0xdf33, 0xde6c, 0xde76, 0xde6c, 0xde6c, - 0xde6c, 0xde6c, 0xdf2f, 0xdf33, 0xde6c, 0xde6c, 0xdf33, 0xdf33, - 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0x080c, 0x0d85, 0x080c, 0xd65d, - 0x6003, 0x0002, 0x080c, 0x9ab3, 0x0804, 0xdf35, 0x9006, 0x080c, - 0x66e6, 0x0804, 0xdf33, 0x080c, 0x6c09, 0x1904, 0xdf33, 0x9006, - 0x080c, 0x66e6, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, - 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x00b8, - 0x6010, 0x2058, 0xb884, 0x9005, 0x0904, 0xdf33, 0x080c, 0x347d, - 0x1904, 0xdf33, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, - 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, - 0x0002, 0x080c, 0x66fa, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x6110, 0x2158, 0x2009, - 0x0001, 0x080c, 0x89a1, 0x0804, 0xdf35, 0x6610, 0x2658, 0xbe04, - 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, - 0x0130, 0x080c, 0x9228, 0x2001, 0x0004, 0x080c, 0x6726, 0x080c, - 0xee9d, 0x0904, 0xdf33, 0x2001, 0x0004, 0x080c, 0x66fa, 0x6023, - 0x0001, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x961e, 0x0804, - 0xdf35, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, - 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4e58, - 0x004e, 0x003e, 0x2001, 0x0006, 0x080c, 0xdf4f, 0x6610, 0x2658, - 0xbe04, 0x0066, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, - 0x0180, 0x2001, 0x0006, 0x080c, 0x6726, 0x9284, 0x00ff, 0x908e, - 0x0007, 0x0118, 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, - 0x66fa, 0x080c, 0x6c09, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, - 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, - 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xdea7, - 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0409, 0x0020, 0x0018, - 0x0010, 0x080c, 0x6726, 0x080c, 0xb16c, 0x0005, 0x2600, 0x0002, - 0xdf4a, 0xdf4a, 0xdf4a, 0xdf4a, 0xdf4a, 0xdf4c, 0xdf4a, 0xdf4c, - 0xdf4a, 0xdf4a, 0xdf4c, 0xdf4a, 0xdf4a, 0xdf4a, 0xdf4c, 0xdf4c, - 0xdf4c, 0xdf4c, 0x080c, 0x0d85, 0x080c, 0xb16c, 0x0005, 0x0016, - 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, - 0x66fa, 0x9006, 0x080c, 0x66e6, 0x080c, 0x3344, 0x00de, 0x00be, - 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, - 0x90b2, 0x000c, 0x1a0c, 0x0d85, 0x91b6, 0x0015, 0x1110, 0x003b, - 0x0028, 0x91b6, 0x0016, 0x190c, 0x0d85, 0x006b, 0x0005, 0xbc45, - 0xbc45, 0xbc45, 0xbc45, 0xdfe4, 0xbc45, 0xdfce, 0xdf8f, 0xbc45, - 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xdfe4, - 0xbc45, 0xdfce, 0xdfd5, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0x00f6, - 0x080c, 0x6c09, 0x11d8, 0x080c, 0xd645, 0x11c0, 0x6010, 0x905d, - 0x01a8, 0xb884, 0x9005, 0x0190, 0x9006, 0x080c, 0x66e6, 0x2001, - 0x0002, 0x080c, 0x66fa, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x00f0, 0x2011, 0x0263, - 0x2204, 0x8211, 0x220c, 0x080c, 0x268c, 0x11b0, 0x080c, 0x67b4, - 0x0118, 0x080c, 0xb16c, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, - 0xb884, 0x0006, 0x080c, 0x61b7, 0x000e, 0xb886, 0x000e, 0xb816, - 0x000e, 0xb812, 0x080c, 0xb16c, 0x00fe, 0x0005, 0x6604, 0x96b6, - 0x001e, 0x1110, 0x080c, 0xb16c, 0x0005, 0x080c, 0xc082, 0x1148, - 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, - 0x0010, 0x080c, 0xb16c, 0x0005, 0x0804, 0xb16c, 0x6004, 0x908a, - 0x0053, 0x1a0c, 0x0d85, 0x080c, 0x99ed, 0x080c, 0xb1a7, 0x0005, - 0x9182, 0x0040, 0x0002, 0xe007, 0xe007, 0xe007, 0xe007, 0xe009, - 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, - 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0x080c, - 0x0d85, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, - 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11b0, 0x6007, 0x0044, 0x2071, - 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xe070, 0x080c, 0xee42, - 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, - 0x080c, 0x8c44, 0x0020, 0x9026, 0x080c, 0xecc5, 0x0c30, 0x080c, - 0x1059, 0x090c, 0x0d85, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, - 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, - 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, - 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x7012, 0x001e, 0x080c, - 0xee42, 0x1904, 0xe0d0, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, - 0x080c, 0xe9f9, 0x0804, 0xe0d0, 0x9486, 0x0200, 0x1120, 0x080c, - 0xe984, 0x0804, 0xe0d0, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, - 0x1904, 0xe0d0, 0x2019, 0x0002, 0x080c, 0xe9a3, 0x0804, 0xe0d0, - 0x2069, 0x1a73, 0x6a00, 0xd284, 0x0904, 0xe13a, 0x9284, 0x0300, - 0x1904, 0xe133, 0x6804, 0x9005, 0x0904, 0xe11b, 0x2d78, 0x6003, - 0x0007, 0x080c, 0x1072, 0x0904, 0xe0dc, 0x7800, 0xd08c, 0x1118, - 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, - 0xd084, 0x1904, 0xe13e, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, - 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, - 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, - 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, - 0xe0d8, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, - 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, - 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, - 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x7015, - 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, - 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, - 0x0120, 0x080c, 0x1059, 0x1904, 0xe085, 0x6017, 0xf100, 0x6003, - 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9617, 0x0c00, - 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, - 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, - 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x2009, 0xa025, - 0x080c, 0x9617, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, - 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, - 0x9617, 0x0804, 0xe0d0, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, - 0x2011, 0x8049, 0x080c, 0x4ca1, 0x6017, 0xf300, 0x0010, 0x6017, - 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, - 0x9617, 0x0804, 0xe0d0, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, - 0x0804, 0xe0f0, 0x6017, 0xf200, 0x0804, 0xe0f0, 0xa867, 0x0146, - 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, - 0x0003, 0x9080, 0xe0d8, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, - 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, - 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, - 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, - 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0d85, 0x8210, 0x821c, - 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, - 0x20a0, 0x2011, 0xe1ba, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, - 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, - 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, - 0x2950, 0x080c, 0x1072, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, - 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, - 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x108b, - 0x0cc8, 0x080c, 0x108b, 0x0804, 0xe0dc, 0x2548, 0x8847, 0x9885, - 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xea30, - 0x0804, 0xe0d0, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, - 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, - 0x0057, 0x1a0c, 0x0d85, 0x9082, 0x0040, 0x0a0c, 0x0d85, 0x2008, - 0x0804, 0xe246, 0x9186, 0x0051, 0x0108, 0x0040, 0x080c, 0xaf61, - 0x01e8, 0x9086, 0x0002, 0x0904, 0xe28e, 0x00c0, 0x9186, 0x0027, - 0x0180, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0150, 0x190c, - 0x0d85, 0x080c, 0xaf61, 0x0150, 0x9086, 0x0004, 0x0904, 0xe32d, - 0x0028, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xb227, - 0x0005, 0xe20d, 0xe20f, 0xe20f, 0xe236, 0xe20d, 0xe20d, 0xe20d, - 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, - 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0x080c, 0x0d85, 0x080c, - 0x99ed, 0x080c, 0x9ab3, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, - 0x080c, 0xcf1b, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, - 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xea30, - 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1987, 0x2004, - 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, - 0x99ed, 0x080c, 0x9ab3, 0x080c, 0xcf1b, 0x0120, 0x6014, 0x2048, - 0x080c, 0x108b, 0x080c, 0xb1a7, 0x009e, 0x0005, 0x0002, 0xe25b, - 0xe270, 0xe25d, 0xe285, 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, - 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, - 0xe25b, 0xe25b, 0xe25b, 0x080c, 0x0d85, 0x0096, 0x6014, 0x2048, - 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, - 0xb20a, 0x0010, 0x6003, 0x0004, 0x080c, 0x9ab3, 0x009e, 0x0005, - 0x080c, 0xcf1b, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, - 0xd1ec, 0x1138, 0x080c, 0x8c19, 0x080c, 0xb16c, 0x080c, 0x9ab3, - 0x0005, 0x080c, 0xec89, 0x0db0, 0x0cc8, 0x6003, 0x0001, 0x6007, - 0x0041, 0x2009, 0xa022, 0x080c, 0x9617, 0x0005, 0x9182, 0x0040, - 0x0002, 0xe2a5, 0xe2a7, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, - 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, - 0xe2a5, 0xe2a5, 0xe2a8, 0xe2a5, 0xe2a5, 0x080c, 0x0d85, 0x0005, - 0x00d6, 0x080c, 0x8c19, 0x00de, 0x080c, 0xece1, 0x080c, 0xb16c, - 0x0005, 0x9182, 0x0040, 0x0002, 0xe2c8, 0xe2c8, 0xe2c8, 0xe2c8, - 0xe2c8, 0xe2c8, 0xe2c8, 0xe2c8, 0xe2c8, 0xe2ca, 0xe2f5, 0xe2c8, - 0xe2c8, 0xe2c8, 0xe2c8, 0xe2f5, 0xe2c8, 0xe2c8, 0xe2c8, 0xe2c8, - 0x080c, 0x0d85, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0168, - 0x908c, 0x0003, 0x918e, 0x0002, 0x0180, 0x6144, 0xd1e4, 0x1168, - 0x2009, 0x0041, 0x009e, 0x0804, 0xe3b5, 0x6003, 0x0007, 0x601b, - 0x0000, 0x080c, 0x8c19, 0x009e, 0x0005, 0x6014, 0x2048, 0xa97c, - 0xd1ec, 0x1130, 0x080c, 0x8c19, 0x080c, 0xb16c, 0x009e, 0x0005, - 0x080c, 0xec89, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, - 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9a48, 0x080c, 0x9ab3, 0x6014, - 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, - 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, - 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, - 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xea30, 0x6018, 0x9005, - 0x1128, 0x2001, 0x1987, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, - 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, - 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, - 0xe346, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, - 0xe344, 0xe344, 0xe344, 0xe391, 0x080c, 0x0d85, 0x6014, 0x0096, - 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, - 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, - 0x0041, 0x009e, 0x0804, 0xe3b5, 0x6003, 0x0007, 0x601b, 0x0000, - 0x080c, 0x8c19, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, - 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, - 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, - 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, - 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, - 0x00e9, 0x080c, 0x8c1b, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, - 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x16b0, 0x1904, 0xe346, - 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, - 0x1120, 0x080c, 0x16b0, 0x1904, 0xe346, 0x0005, 0xd2fc, 0x0140, - 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, - 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, - 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d85, - 0x6024, 0xd0dc, 0x090c, 0x0d85, 0x0005, 0xe3d9, 0xe3e5, 0xe3f1, - 0xe3fd, 0xe3d9, 0xe3d9, 0xe3d9, 0xe3d9, 0xe3e0, 0xe3db, 0xe3db, - 0xe3d9, 0xe3d9, 0xe3d9, 0xe3d9, 0xe3db, 0xe3d9, 0xe3db, 0xe3d9, - 0xe3e0, 0x080c, 0x0d85, 0x6024, 0xd0dc, 0x090c, 0x0d85, 0x0005, - 0x6014, 0x9005, 0x190c, 0x0d85, 0x0005, 0x6003, 0x0001, 0x6106, - 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x95f9, 0x012e, - 0x0005, 0x6003, 0x0004, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, - 0xa001, 0x080c, 0x9617, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, - 0x6047, 0x0000, 0x080c, 0x1c6f, 0x0126, 0x2091, 0x8000, 0x6014, - 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x9084, 0x0003, 0x9086, - 0x0002, 0x01a0, 0x6024, 0xd0cc, 0x1148, 0xd0c4, 0x1138, 0xa8a8, - 0x9005, 0x1120, 0x6144, 0x918d, 0xb035, 0x0018, 0x6144, 0x918d, - 0xa035, 0x009e, 0x080c, 0x965e, 0x012e, 0x0005, 0x6144, 0x918d, - 0xa032, 0x0cb8, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, - 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe44a, 0xe44c, - 0xe461, 0xe47b, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, - 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, - 0xe44a, 0xe44a, 0x080c, 0x0d85, 0x6014, 0x2048, 0xa87c, 0xd0fc, - 0x0510, 0x909c, 0x0003, 0x939e, 0x0003, 0x01e8, 0x6003, 0x0001, - 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x9617, - 0x0480, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, - 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x2009, 0xa001, - 0x080c, 0x9617, 0x00f0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, - 0x080c, 0xea30, 0x00b0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, - 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, - 0x6047, 0x0000, 0x080c, 0x1c6f, 0x6144, 0x918d, 0xa035, 0x080c, - 0x965e, 0x0005, 0x080c, 0x99ed, 0x6114, 0x81ff, 0x0158, 0x0096, - 0x2148, 0x080c, 0xeddf, 0x0036, 0x2019, 0x0029, 0x080c, 0xea30, - 0x003e, 0x009e, 0x080c, 0xb1a7, 0x080c, 0x9ab3, 0x0005, 0x080c, - 0x9a48, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xeddf, - 0x0036, 0x2019, 0x0029, 0x080c, 0xea30, 0x003e, 0x009e, 0x080c, - 0xb1a7, 0x0005, 0x9182, 0x0085, 0x0002, 0xe4cc, 0xe4ca, 0xe4ca, - 0xe4d8, 0xe4ca, 0xe4ca, 0xe4ca, 0xe4ca, 0xe4ca, 0xe4ca, 0xe4ca, - 0xe4ca, 0xe4ca, 0x080c, 0x0d85, 0x6003, 0x000b, 0x6106, 0x0126, - 0x2091, 0x8000, 0x2009, 0x8020, 0x080c, 0x9617, 0x012e, 0x0005, - 0x0026, 0x00e6, 0x080c, 0xec80, 0x0118, 0x080c, 0xb16c, 0x0440, - 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, - 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, - 0x014e, 0x080c, 0xb495, 0x7220, 0x080c, 0xe875, 0x0118, 0x6007, - 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, - 0x6007, 0x0086, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, - 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, - 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092, 0x1a0c, 0x0d85, 0x9082, - 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, - 0x080c, 0xb227, 0x0050, 0x2001, 0x0007, 0x080c, 0x6726, 0x080c, - 0x99ed, 0x080c, 0xb1a7, 0x080c, 0x9ab3, 0x0005, 0xe53b, 0xe53d, - 0xe53d, 0xe53b, 0xe53b, 0xe53b, 0xe53b, 0xe53b, 0xe53b, 0xe53b, - 0xe53b, 0xe53b, 0xe53b, 0x080c, 0x0d85, 0x080c, 0xb1a7, 0x080c, - 0x9ab3, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0d85, 0x9182, 0x0092, - 0x1a0c, 0x0d85, 0x9182, 0x0085, 0x0002, 0xe55a, 0xe55a, 0xe55a, - 0xe55c, 0xe55a, 0xe55a, 0xe55a, 0xe55a, 0xe55a, 0xe55a, 0xe55a, - 0xe55a, 0xe55a, 0x080c, 0x0d85, 0x0005, 0x9186, 0x0013, 0x0148, - 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xb227, - 0x0020, 0x080c, 0x99ed, 0x080c, 0xb1a7, 0x0005, 0x0036, 0x080c, - 0xece1, 0x604b, 0x0000, 0x2019, 0x000b, 0x0011, 0x003e, 0x0005, - 0x6010, 0x0006, 0x0059, 0x000e, 0x6012, 0x6023, 0x0006, 0x6003, - 0x0007, 0x601b, 0x0000, 0x604b, 0x0000, 0x0005, 0x0126, 0x0036, - 0x2091, 0x8000, 0x080c, 0xacfc, 0x0106, 0x0086, 0x2c40, 0x0096, - 0x904e, 0x080c, 0xa667, 0x009e, 0x008e, 0x1558, 0x0076, 0x2c38, - 0x080c, 0xa712, 0x007e, 0x1528, 0x6000, 0x9086, 0x0000, 0x0508, + 0x080c, 0xe795, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, + 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, 0xe60d, 0x0198, 0x0016, + 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, + 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0920, 0x0804, + 0xd520, 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, + 0x3432, 0x1904, 0xd883, 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, + 0xda54, 0x1904, 0xd520, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, + 0x080c, 0x9427, 0x080c, 0x98bc, 0x0cb0, 0x6007, 0x0005, 0x0c68, + 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432, 0x1904, 0xd883, + 0x080c, 0xda54, 0x1904, 0xd520, 0x6007, 0x0020, 0x6003, 0x0001, + 0x080c, 0x9427, 0x080c, 0x98bc, 0x0005, 0x080c, 0x3432, 0x1904, + 0xd883, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, + 0x98bc, 0x0005, 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432, + 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520, 0x0016, 0x0026, + 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c, + 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff, + 0x9206, 0x11a0, 0x7240, 0x080c, 0xcc21, 0x0570, 0x2260, 0x6008, + 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, + 0x9086, 0x0007, 0x1508, 0x080c, 0xaf4e, 0x04a0, 0x7244, 0x9286, + 0xffff, 0x0180, 0x2c08, 0x080c, 0xcc21, 0x01b0, 0x2260, 0x7240, + 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, + 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xe75f, 0x1180, + 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, + 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, + 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, + 0x080c, 0xaf4e, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, + 0x0001, 0x080c, 0x66b5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, + 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xbf40, 0x003e, + 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xd64d, + 0x080c, 0xbbaa, 0x080c, 0x769d, 0x1190, 0x0006, 0x0026, 0x0036, + 0x080c, 0x76b7, 0x1138, 0x080c, 0x799f, 0x080c, 0x6178, 0x080c, + 0x75cc, 0x0010, 0x080c, 0x7671, 0x003e, 0x002e, 0x000e, 0x0005, + 0x080c, 0x3432, 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520, + 0x6106, 0x080c, 0xda70, 0x1120, 0x6007, 0x002b, 0x0804, 0xd64d, + 0x6007, 0x002c, 0x0804, 0xd64d, 0x080c, 0xe98f, 0x1904, 0xd883, + 0x080c, 0x3432, 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520, + 0x6106, 0x080c, 0xda75, 0x1120, 0x6007, 0x002e, 0x0804, 0xd64d, + 0x6007, 0x002f, 0x0804, 0xd64d, 0x080c, 0x3432, 0x1904, 0xd883, + 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, + 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, + 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd654, 0x080c, 0x5824, + 0xd0e4, 0x0904, 0xd7ce, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, + 0x603e, 0x7108, 0x720c, 0x080c, 0x6bc9, 0x0140, 0x6010, 0x2058, + 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x6bc5, + 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c, 0x9106, + 0x1578, 0x7210, 0x080c, 0xcc21, 0x0590, 0x080c, 0xd941, 0x0578, + 0x080c, 0xe811, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, + 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x00de, 0x00ee, 0x0005, + 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xcc21, 0x01c0, 0x9280, + 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, + 0x9085, 0x0001, 0x080c, 0xe75f, 0x2c10, 0x2160, 0x0140, 0x0890, + 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, + 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, + 0x0868, 0x080c, 0x3432, 0x1904, 0xd883, 0x6010, 0x2058, 0xb804, + 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xd654, 0x00e6, + 0x00d6, 0x00c6, 0x080c, 0x5824, 0xd0e4, 0x0904, 0xd846, 0x2069, + 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, + 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, + 0xe75f, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xcc21, 0x05d0, 0x7108, + 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, + 0x080c, 0xc80e, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, + 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, + 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xd941, + 0x0904, 0xd7c7, 0x0056, 0x7510, 0x7614, 0x080c, 0xe82a, 0x005e, + 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, + 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, + 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, + 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x0c10, 0x6007, 0x003b, + 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xd79e, 0x00e6, 0x0026, + 0x080c, 0x6b8b, 0x0550, 0x080c, 0x6b27, 0x080c, 0xea00, 0x1518, + 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079, + 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00, + 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c, + 0x6bc9, 0x0120, 0x2011, 0x1a0b, 0x2013, 0x07d0, 0xd0ac, 0x1128, + 0x080c, 0x30c8, 0x0010, 0x080c, 0xea34, 0x002e, 0x00ee, 0x080c, + 0xaf4e, 0x0804, 0xd653, 0x080c, 0xaf4e, 0x0005, 0x2600, 0x0002, + 0xd89a, 0xd8c8, 0xd8d9, 0xd89a, 0xd89a, 0xd89c, 0xd8ea, 0xd89a, + 0xd89a, 0xd89a, 0xd8b6, 0xd89a, 0xd89a, 0xd89a, 0xd8f5, 0xd90b, + 0xd93c, 0xd89a, 0x080c, 0x0d79, 0x080c, 0xe98f, 0x1d20, 0x080c, + 0x3432, 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, + 0x080c, 0x9427, 0x0005, 0x080c, 0x32fb, 0x080c, 0xd372, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x0005, 0x080c, 0xe98f, + 0x1950, 0x080c, 0x3432, 0x1938, 0x080c, 0xda54, 0x1d60, 0x703c, + 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x9427, 0x0005, + 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0041, 0x080c, 0xea3d, + 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, + 0x0005, 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0042, 0x080c, + 0xea3d, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, + 0x98bc, 0x0005, 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0046, + 0x080c, 0xea3d, 0x080c, 0xaf4e, 0x0005, 0x2001, 0x1824, 0x2004, + 0x9082, 0x00e1, 0x1268, 0x080c, 0xd95e, 0x0904, 0xd883, 0x6007, + 0x004e, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0005, + 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, + 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, + 0x2001, 0x19bf, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x19c0, + 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, + 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, + 0xbf54, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, + 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, + 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128, 0x604c, 0x9106, + 0x1120, 0x712c, 0x6050, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, + 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, + 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, + 0x1800, 0x20e1, 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000, 0x080c, + 0x1066, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816, 0x908a, + 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, + 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1066, 0x01b0, + 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, + 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, + 0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x0fff, 0x9006, 0x012e, + 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, + 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, + 0x2216, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, + 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, + 0x080c, 0x2216, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x2216, 0x2061, + 0x19a2, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, + 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, + 0x2216, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a2, 0x2019, 0x0280, + 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, + 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, + 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x222e, 0x20a1, 0x024c, + 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, + 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x222e, + 0x20a1, 0x0240, 0x0c98, 0x080c, 0x222e, 0x2061, 0x19a5, 0x6004, + 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, + 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x222e, + 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a5, 0x2019, 0x0260, 0x3400, + 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, + 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, + 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, + 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, + 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, + 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, + 0x00d6, 0x080c, 0xdaea, 0x00de, 0x0005, 0x00d6, 0x080c, 0xdaf7, + 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, + 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xeb5d, + 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, + 0x6824, 0x080c, 0x26a1, 0x1148, 0x2001, 0x0001, 0x080c, 0xeb5d, + 0x2110, 0x900e, 0x080c, 0x334a, 0x0018, 0x9085, 0x0001, 0x0008, + 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xafbf, 0x0598, + 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, + 0x080c, 0x26a1, 0x1568, 0x080c, 0x6718, 0x1550, 0xbe12, 0xbd16, + 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xe98f, 0x11c8, + 0x080c, 0x3432, 0x11b0, 0x080c, 0xda54, 0x0500, 0x2001, 0x0007, + 0x080c, 0x66c9, 0x2001, 0x0007, 0x080c, 0x66f5, 0x6017, 0x0000, + 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, + 0x0010, 0x080c, 0xaf4e, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, + 0x080c, 0xaf4e, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xaf4e, + 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, + 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, + 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, + 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, + 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x6162, 0x908e, 0x0014, + 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, + 0x0d79, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, + 0xdc4c, 0x0402, 0x91b6, 0x0027, 0x0190, 0x9186, 0x0015, 0x0118, + 0x9186, 0x0016, 0x1140, 0x080c, 0xad4d, 0x0120, 0x9086, 0x0002, + 0x0904, 0xb983, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0d79, 0x2001, + 0x0007, 0x080c, 0x66f5, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x080c, + 0x98bc, 0x0005, 0xdb82, 0xdb84, 0xdb82, 0xdb82, 0xdb82, 0xdb84, + 0xdb91, 0xdc49, 0xdbd3, 0xdc49, 0xdbf7, 0xdc49, 0xdb91, 0xdc49, + 0xdc41, 0xdc49, 0xdc41, 0xdc49, 0xdc49, 0xdb82, 0xdb82, 0xdb82, + 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, + 0xdb84, 0xdb82, 0xdc49, 0xdb82, 0xdb82, 0xdc49, 0xdb82, 0xdc46, + 0xdc49, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdc49, 0xdc49, 0xdb82, + 0xdc49, 0xdc49, 0xdb82, 0xdb8c, 0xdb82, 0xdb82, 0xdb82, 0xdb82, + 0xdc45, 0xdc49, 0xdb82, 0xdb82, 0xdc49, 0xdc49, 0xdb82, 0xdb82, + 0xdb82, 0xdb82, 0x080c, 0x0d79, 0x080c, 0xd375, 0x6003, 0x0002, + 0x080c, 0x98bc, 0x0804, 0xdc4b, 0x9006, 0x080c, 0x66b5, 0x0804, + 0xdc49, 0x080c, 0x6bc5, 0x1904, 0xdc49, 0x9006, 0x080c, 0x66b5, + 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079, + 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x00b8, 0x6010, 0x2058, + 0xb884, 0x9005, 0x0904, 0xdc49, 0x080c, 0x3463, 0x1904, 0xdc49, + 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, + 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, + 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, + 0x883a, 0x0804, 0xdc4b, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, 0x080c, + 0x90be, 0x2001, 0x0004, 0x080c, 0x66f5, 0x080c, 0xebac, 0x0904, + 0xdc49, 0x2001, 0x0004, 0x080c, 0x66c9, 0x6023, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0003, 0x080c, 0x9427, 0x0804, 0xdc4b, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, + 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e, + 0x2001, 0x0006, 0x080c, 0xdc65, 0x6610, 0x2658, 0xbe04, 0x0066, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001, + 0x0006, 0x080c, 0x66f5, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118, + 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c, + 0x6bc5, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01d0, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, + 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xdbbd, 0x2001, 0x0004, + 0x0030, 0x2001, 0x0006, 0x0409, 0x0020, 0x0018, 0x0010, 0x080c, + 0x66f5, 0x080c, 0xaf4e, 0x0005, 0x2600, 0x0002, 0xdc60, 0xdc60, + 0xdc60, 0xdc60, 0xdc60, 0xdc62, 0xdc60, 0xdc62, 0xdc60, 0xdc60, + 0xdc62, 0xdc60, 0xdc60, 0xdc60, 0xdc62, 0xdc62, 0xdc62, 0xdc62, + 0x080c, 0x0d79, 0x080c, 0xaf4e, 0x0005, 0x0016, 0x00b6, 0x00d6, + 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x66c9, 0x9006, + 0x080c, 0x66b5, 0x080c, 0x332a, 0x00de, 0x00be, 0x001e, 0x0005, + 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, + 0x1a0c, 0x0d79, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, + 0x0016, 0x190c, 0x0d79, 0x006b, 0x0005, 0xba25, 0xba25, 0xba25, + 0xba25, 0xdcfa, 0xba25, 0xdce4, 0xdca5, 0xba25, 0xba25, 0xba25, + 0xba25, 0xba25, 0xba25, 0xba25, 0xba25, 0xdcfa, 0xba25, 0xdce4, + 0xdceb, 0xba25, 0xba25, 0xba25, 0xba25, 0x00f6, 0x080c, 0x6bc5, + 0x11d8, 0x080c, 0xd35d, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb884, + 0x9005, 0x0190, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, + 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9427, 0x080c, 0x98bc, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, + 0x220c, 0x080c, 0x26a1, 0x11b0, 0x080c, 0x6783, 0x0118, 0x080c, + 0xaf4e, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb884, 0x0006, + 0x080c, 0x6192, 0x000e, 0xb886, 0x000e, 0xb816, 0x000e, 0xb812, + 0x080c, 0xaf4e, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, + 0x080c, 0xaf4e, 0x0005, 0x080c, 0xbdb4, 0x1148, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0010, 0x080c, + 0xaf4e, 0x0005, 0x0804, 0xaf4e, 0x6004, 0x908a, 0x0053, 0x1a0c, + 0x0d79, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x0005, 0x9182, 0x0040, + 0x0002, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1f, 0xdd1d, 0xdd1d, + 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, + 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0x080c, 0x0d79, 0x0096, + 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258, + 0xb8bc, 0x9005, 0x11b0, 0x6007, 0x0044, 0x2071, 0x0260, 0x7444, + 0x94a4, 0xff00, 0x0904, 0xdd86, 0x080c, 0xeb51, 0x1170, 0x9486, + 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8add, + 0x0020, 0x9026, 0x080c, 0xe9d4, 0x0c30, 0x080c, 0x104d, 0x090c, + 0x0d79, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, + 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0, + 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000, + 0xa887, 0x0036, 0x080c, 0x6f11, 0x001e, 0x080c, 0xeb51, 0x1904, + 0xdde6, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xe701, + 0x0804, 0xdde6, 0x9486, 0x0200, 0x1120, 0x080c, 0xe68c, 0x0804, + 0xdde6, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xdde6, + 0x2019, 0x0002, 0x080c, 0xe6ab, 0x0804, 0xdde6, 0x2069, 0x1a74, + 0x6a00, 0xd284, 0x0904, 0xde50, 0x9284, 0x0300, 0x1904, 0xde49, + 0x6804, 0x9005, 0x0904, 0xde31, 0x2d78, 0x6003, 0x0007, 0x080c, + 0x1066, 0x0904, 0xddf2, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, + 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, + 0xde54, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2, + 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876, + 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6, + 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xddee, 0x2005, + 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021, + 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8, + 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c, + 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6f14, 0x002e, 0x004e, + 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080, + 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, + 0x104d, 0x1904, 0xdd9b, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, + 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0c00, 0x2069, 0x0260, + 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, + 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, + 0x6003, 0x0001, 0x6007, 0x0043, 0x2009, 0xa025, 0x080c, 0x9420, + 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003, + 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0804, + 0xdde6, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x4c28, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003, + 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0804, + 0xdde6, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xde06, + 0x6017, 0xf200, 0x0804, 0xde06, 0xa867, 0x0146, 0xa86b, 0x0000, + 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, + 0xddee, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876, + 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896, + 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a, + 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2, + 0x9282, 0x0111, 0x1a0c, 0x0d79, 0x8210, 0x821c, 0x2001, 0x026c, + 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, + 0xded0, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, + 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, + 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, + 0x1066, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, + 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x107f, 0x0cc8, 0x080c, + 0x107f, 0x0804, 0xddf2, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, + 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xe738, 0x0804, 0xdde6, + 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a, + 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0057, 0x1a0c, + 0x0d79, 0x9082, 0x0040, 0x0a0c, 0x0d79, 0x2008, 0x0804, 0xdf5c, + 0x9186, 0x0051, 0x0108, 0x0040, 0x080c, 0xad4d, 0x01e8, 0x9086, + 0x0002, 0x0904, 0xdfa4, 0x00c0, 0x9186, 0x0027, 0x0180, 0x9186, + 0x0048, 0x0128, 0x9186, 0x0014, 0x0150, 0x190c, 0x0d79, 0x080c, + 0xad4d, 0x0150, 0x9086, 0x0004, 0x0904, 0xe043, 0x0028, 0x6004, + 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xb009, 0x0005, 0xdf23, + 0xdf25, 0xdf25, 0xdf4c, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, + 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, + 0xdf23, 0xdf23, 0xdf23, 0x080c, 0x0d79, 0x080c, 0x97f6, 0x080c, + 0x98bc, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, 0xcc33, + 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xe738, 0x6017, 0x0000, + 0x6018, 0x9005, 0x1120, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, + 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, 0x97f6, 0x080c, + 0x98bc, 0x080c, 0xcc33, 0x0120, 0x6014, 0x2048, 0x080c, 0x107f, + 0x080c, 0xaf89, 0x009e, 0x0005, 0x0002, 0xdf71, 0xdf86, 0xdf73, + 0xdf9b, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, + 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, + 0xdf71, 0x080c, 0x0d79, 0x0096, 0x6014, 0x2048, 0xa87c, 0xd0b4, + 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xafec, 0x0010, + 0x6003, 0x0004, 0x080c, 0x98bc, 0x009e, 0x0005, 0x080c, 0xcc33, + 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, + 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x080c, 0x98bc, 0x0005, 0x080c, + 0xe998, 0x0db0, 0x0cc8, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, + 0xa022, 0x080c, 0x9420, 0x0005, 0x9182, 0x0040, 0x0002, 0xdfbb, + 0xdfbd, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, + 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, + 0xdfbe, 0xdfbb, 0xdfbb, 0x080c, 0x0d79, 0x0005, 0x00d6, 0x080c, + 0x8ab2, 0x00de, 0x080c, 0xe9f0, 0x080c, 0xaf4e, 0x0005, 0x9182, + 0x0040, 0x0002, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0xdfde, + 0xdfde, 0xdfde, 0xdfde, 0xdfe0, 0xe00b, 0xdfde, 0xdfde, 0xdfde, + 0xdfde, 0xe00b, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0x080c, 0x0d79, + 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x908c, 0x0003, + 0x918e, 0x0002, 0x0180, 0x6144, 0xd1e4, 0x1168, 0x2009, 0x0041, + 0x009e, 0x0804, 0xe0cb, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, + 0x8ab2, 0x009e, 0x0005, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130, + 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xe998, + 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, + 0x0036, 0x080c, 0x9851, 0x080c, 0x98bc, 0x6014, 0x0096, 0x2048, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c, + 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a, + 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080, + 0x2019, 0x0004, 0x080c, 0xe738, 0x6018, 0x9005, 0x1128, 0x2001, + 0x1988, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007, + 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xe05a, 0xe05a, + 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05c, 0xe05a, + 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, + 0xe05a, 0xe0a7, 0x080c, 0x0d79, 0x6014, 0x0096, 0x2048, 0xa834, + 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190, + 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e, + 0x0804, 0xe0cb, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8ab2, + 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac, + 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c, + 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158, + 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c, + 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c, + 0x8ab4, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024, + 0xd0f4, 0x0128, 0x080c, 0x16a4, 0x1904, 0xe05c, 0x0005, 0x6014, + 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c, + 0x16a4, 0x1904, 0xe05c, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, + 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, + 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186, + 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d79, 0x6024, 0xd0dc, + 0x090c, 0x0d79, 0x0005, 0xe0ef, 0xe0fb, 0xe107, 0xe113, 0xe0ef, + 0xe0ef, 0xe0ef, 0xe0ef, 0xe0f6, 0xe0f1, 0xe0f1, 0xe0ef, 0xe0ef, + 0xe0ef, 0xe0ef, 0xe0f1, 0xe0ef, 0xe0f1, 0xe0ef, 0xe0f6, 0x080c, + 0x0d79, 0x6024, 0xd0dc, 0x090c, 0x0d79, 0x0005, 0x6014, 0x9005, + 0x190c, 0x0d79, 0x0005, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, + 0x8000, 0x2009, 0xa022, 0x080c, 0x9402, 0x012e, 0x0005, 0x6003, + 0x0004, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa001, 0x080c, + 0x9420, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x080c, 0x1c8c, + 0x0126, 0x2091, 0x8000, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, + 0x0188, 0x9084, 0x0003, 0x9086, 0x0002, 0x01a0, 0x6024, 0xd0cc, + 0x1148, 0xd0c4, 0x1138, 0xa8a8, 0x9005, 0x1120, 0x6144, 0x918d, + 0xb035, 0x0018, 0x6144, 0x918d, 0xa035, 0x009e, 0x080c, 0x9467, + 0x012e, 0x0005, 0x6144, 0x918d, 0xa032, 0x0cb8, 0x0126, 0x2091, + 0x8000, 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, + 0x012e, 0x0005, 0xe15e, 0xe160, 0xe175, 0xe18f, 0xe15e, 0xe15e, + 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, + 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0x080c, 0x0d79, + 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0510, 0x909c, 0x0003, 0x939e, + 0x0003, 0x01e8, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, + 0x2009, 0xa022, 0x080c, 0x9420, 0x0470, 0x6014, 0x2048, 0xa87c, + 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140, 0x6003, + 0x0001, 0x6106, 0x2009, 0xa001, 0x080c, 0x9420, 0x00e0, 0x901e, + 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe738, 0x00a0, 0x6014, + 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e, 0x0003, + 0x0d70, 0x6003, 0x0003, 0x6106, 0x080c, 0x1c8c, 0x6144, 0x918d, + 0xa035, 0x080c, 0x9467, 0x0005, 0x080c, 0x97f6, 0x6114, 0x81ff, + 0x0158, 0x0096, 0x2148, 0x080c, 0xeaee, 0x0036, 0x2019, 0x0029, + 0x080c, 0xe738, 0x003e, 0x009e, 0x080c, 0xaf89, 0x080c, 0x98bc, + 0x0005, 0x080c, 0x9851, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, + 0x080c, 0xeaee, 0x0036, 0x2019, 0x0029, 0x080c, 0xe738, 0x003e, + 0x009e, 0x080c, 0xaf89, 0x0005, 0x9182, 0x0085, 0x0002, 0xe1de, + 0xe1dc, 0xe1dc, 0xe1ea, 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc, + 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc, 0x080c, 0x0d79, 0x6003, 0x000b, + 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c, 0x9420, + 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, 0xe98f, 0x0118, 0x080c, + 0xaf4e, 0x0440, 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, + 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, + 0x2c00, 0x2011, 0x014e, 0x080c, 0xb277, 0x7220, 0x080c, 0xe57d, + 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, + 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x2009, 0x8020, + 0x080c, 0x9420, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, + 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d79, 0x908a, 0x0092, 0x1a0c, + 0x0d79, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, + 0x0014, 0x0118, 0x080c, 0xb009, 0x0050, 0x2001, 0x0007, 0x080c, + 0x66f5, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x080c, 0x98bc, 0x0005, + 0xe24d, 0xe24f, 0xe24f, 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0xe24d, + 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0x080c, 0x0d79, 0x080c, + 0xaf89, 0x080c, 0x98bc, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0d79, + 0x9182, 0x0092, 0x1a0c, 0x0d79, 0x9182, 0x0085, 0x0002, 0xe26c, + 0xe26c, 0xe26c, 0xe26e, 0xe26c, 0xe26c, 0xe26c, 0xe26c, 0xe26c, + 0xe26c, 0xe26c, 0xe26c, 0xe26c, 0x080c, 0x0d79, 0x0005, 0x9186, + 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, + 0x080c, 0xb009, 0x0020, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x0005, + 0x0036, 0x080c, 0xe9f0, 0x604b, 0x0000, 0x2019, 0x000b, 0x0031, + 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, + 0x2091, 0x8000, 0x080c, 0xaaf7, 0x0106, 0x0086, 0x2c40, 0x0096, + 0x904e, 0x080c, 0xa462, 0x009e, 0x008e, 0x1558, 0x0076, 0x2c38, + 0x080c, 0xa50d, 0x007e, 0x1528, 0x6000, 0x9086, 0x0000, 0x0508, 0x6020, 0x9086, 0x0007, 0x01e8, 0x0096, 0x601c, 0xd084, 0x0140, - 0x080c, 0xece1, 0x080c, 0xd65d, 0x080c, 0x1ad3, 0x6023, 0x0007, - 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0110, 0x080c, 0xea30, 0x009e, - 0x9006, 0x6046, 0x6016, 0x080c, 0xece1, 0x6023, 0x0007, 0x080c, - 0xd65d, 0x010e, 0x090c, 0xad18, 0x003e, 0x012e, 0x0005, 0x00f6, + 0x080c, 0xe9f0, 0x080c, 0xd375, 0x080c, 0x1af0, 0x6023, 0x0007, + 0x6014, 0x2048, 0x080c, 0xcc33, 0x0110, 0x080c, 0xe738, 0x009e, + 0x9006, 0x6046, 0x6016, 0x080c, 0xe9f0, 0x6023, 0x0007, 0x080c, + 0xd375, 0x010e, 0x090c, 0xab13, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, - 0x080c, 0x268c, 0x1904, 0xe621, 0x0016, 0x00c6, 0x080c, 0x67b4, - 0x1904, 0xe61f, 0x001e, 0x00c6, 0x080c, 0xd645, 0x1130, 0xb884, - 0x9005, 0x0118, 0x080c, 0x347d, 0x0148, 0x2b10, 0x2160, 0x6010, - 0x0006, 0x6212, 0x080c, 0xd64c, 0x000e, 0x6012, 0x00ce, 0x002e, - 0x0026, 0x0016, 0x080c, 0xacfc, 0x2019, 0x0029, 0x080c, 0xa7e2, - 0x080c, 0x97b0, 0x0076, 0x903e, 0x080c, 0x966d, 0x007e, 0x001e, - 0x0076, 0x903e, 0x080c, 0xe75d, 0x007e, 0x080c, 0xad18, 0x0026, + 0x080c, 0x26a1, 0x1904, 0xe329, 0x0016, 0x00c6, 0x080c, 0x6783, + 0x1904, 0xe327, 0x001e, 0x00c6, 0x080c, 0xd35d, 0x1130, 0xb884, + 0x9005, 0x0118, 0x080c, 0x3463, 0x0148, 0x2b10, 0x2160, 0x6010, + 0x0006, 0x6212, 0x080c, 0xd364, 0x000e, 0x6012, 0x00ce, 0x002e, + 0x0026, 0x0016, 0x080c, 0xaaf7, 0x2019, 0x0029, 0x080c, 0xa5dd, + 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x007e, 0x001e, + 0x0076, 0x903e, 0x080c, 0xe465, 0x007e, 0x080c, 0xab13, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, - 0x0004, 0x1118, 0xbaa0, 0x080c, 0x33e0, 0x002e, 0xbc84, 0x001e, - 0x080c, 0x61b7, 0xbe12, 0xbd16, 0xbc86, 0x9006, 0x0010, 0x00ce, + 0x0004, 0x1118, 0xbaa0, 0x080c, 0x33c6, 0x002e, 0xbc84, 0x001e, + 0x080c, 0x6192, 0xbe12, 0xbd16, 0xbc86, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074, - 0x1904, 0xe680, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, - 0x6940, 0x9184, 0x8000, 0x0904, 0xe67d, 0x2001, 0x197c, 0x2004, + 0x1904, 0xe388, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, + 0x6940, 0x9184, 0x8000, 0x0904, 0xe385, 0x2001, 0x197d, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb884, 0x9005, 0x0118, 0x9184, - 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xee47, + 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xeb56, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, @@ -7162,125 +7067,125 @@ unsigned short risc_code01[] = { 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, - 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x67c3, 0x0804, 0xe6ec, + 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x6792, 0x0804, 0xe3f4, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, - 0x080c, 0xc222, 0x009e, 0x15c8, 0x2011, 0x027a, 0x20a9, 0x0004, - 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc222, 0x009e, 0x1568, + 0x080c, 0xbf54, 0x009e, 0x15c8, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x1568, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c, - 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xea8d, 0xb800, 0xc0e5, - 0xb802, 0x080c, 0xacfc, 0x2019, 0x0029, 0x080c, 0x97b0, 0x0076, - 0x2039, 0x0000, 0x080c, 0x966d, 0x2c08, 0x080c, 0xe75d, 0x007e, - 0x080c, 0xad18, 0x2001, 0x0007, 0x080c, 0x6726, 0x2001, 0x0007, - 0x080c, 0x66fa, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, + 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xe795, 0xb800, 0xc0e5, + 0xb802, 0x080c, 0xaaf7, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, + 0x2039, 0x0000, 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465, 0x007e, + 0x080c, 0xab13, 0x2001, 0x0007, 0x080c, 0x66f5, 0x2001, 0x0007, + 0x080c, 0x66c9, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c, - 0x7930, 0x7834, 0x080c, 0x268c, 0x11d0, 0x080c, 0x67b4, 0x11b8, + 0x7930, 0x7834, 0x080c, 0x26a1, 0x11d0, 0x080c, 0x6783, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, - 0x080c, 0xc222, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, - 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc222, 0x009e, 0x015e, + 0x080c, 0xbf54, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, + 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211, - 0x220c, 0x080c, 0x268c, 0x11d0, 0x080c, 0x67b4, 0x11b8, 0x2011, + 0x220c, 0x080c, 0x26a1, 0x11d0, 0x080c, 0x6783, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, - 0xc222, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, - 0x2b48, 0x2019, 0x0006, 0x080c, 0xc222, 0x009e, 0x015e, 0x003e, + 0xbf54, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, - 0x080c, 0xad5a, 0x0106, 0x190c, 0xacfc, 0x2740, 0x2029, 0x19f4, - 0x252c, 0x2021, 0x19fb, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, - 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1b39, 0x000e, - 0x0128, 0x8001, 0x9602, 0x1a04, 0xe803, 0x0018, 0x9606, 0x0904, - 0xe803, 0x080c, 0x8eee, 0x0904, 0xe7fa, 0x2100, 0x9c06, 0x0904, - 0xe7fa, 0x6720, 0x9786, 0x0007, 0x0904, 0xe7fa, 0x080c, 0xeace, - 0x1904, 0xe7fa, 0x080c, 0xee65, 0x0904, 0xe7fa, 0x080c, 0xeabe, - 0x0904, 0xe7fa, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x347d, - 0x0904, 0xe845, 0x6004, 0x9086, 0x0000, 0x1904, 0xe845, 0x9786, - 0x0004, 0x0904, 0xe845, 0x2500, 0x9c06, 0x0904, 0xe7fa, 0x2400, - 0x9c06, 0x0904, 0xe7fa, 0x88ff, 0x0118, 0x605c, 0x9906, 0x15d0, + 0x080c, 0xab55, 0x0106, 0x190c, 0xaaf7, 0x2740, 0x2029, 0x19f5, + 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, + 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1b3a, 0x000e, + 0x0128, 0x8001, 0x9602, 0x1a04, 0xe50b, 0x0018, 0x9606, 0x0904, + 0xe50b, 0x080c, 0x8d87, 0x0904, 0xe502, 0x2100, 0x9c06, 0x0904, + 0xe502, 0x6720, 0x9786, 0x0007, 0x0904, 0xe502, 0x080c, 0xe7d6, + 0x1904, 0xe502, 0x080c, 0xeb74, 0x0904, 0xe502, 0x080c, 0xe7c6, + 0x0904, 0xe502, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x3463, + 0x0904, 0xe54d, 0x6004, 0x9086, 0x0000, 0x1904, 0xe54d, 0x9786, + 0x0004, 0x0904, 0xe54d, 0x2500, 0x9c06, 0x0904, 0xe502, 0x2400, + 0x9c06, 0x0904, 0xe502, 0x88ff, 0x0118, 0x605c, 0x9906, 0x15d0, 0x0096, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, - 0x080c, 0x1ad3, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xd132, - 0x1130, 0x080c, 0xbb5c, 0x009e, 0x080c, 0xb1a7, 0x0418, 0x6014, - 0x2048, 0x080c, 0xcf1b, 0x01d8, 0x9786, 0x0003, 0x1588, 0xa867, + 0x080c, 0x1af0, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xce4a, + 0x1130, 0x080c, 0xb93c, 0x009e, 0x080c, 0xaf89, 0x0418, 0x6014, + 0x2048, 0x080c, 0xcc33, 0x01d8, 0x9786, 0x0003, 0x1588, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, - 0x100b, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xeddf, 0x0016, - 0x080c, 0xd220, 0x080c, 0x7006, 0x001e, 0x080c, 0xd10c, 0x009e, - 0x080c, 0xb1a7, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, - 0x1210, 0x0804, 0xe776, 0x010e, 0x190c, 0xad18, 0x012e, 0x002e, + 0x0fff, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xeaee, 0x0016, + 0x080c, 0xcf38, 0x080c, 0x6f05, 0x001e, 0x080c, 0xce24, 0x009e, + 0x080c, 0xaf89, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, + 0x1210, 0x0804, 0xe47e, 0x010e, 0x190c, 0xab13, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, - 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xeddf, - 0x080c, 0xea30, 0x08e0, 0x009e, 0x08e8, 0x9786, 0x0009, 0x11f8, + 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xeaee, + 0x080c, 0xe738, 0x08e0, 0x009e, 0x08e8, 0x9786, 0x0009, 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0, - 0x080c, 0x9a48, 0x0096, 0x6114, 0x2148, 0x080c, 0xcf1b, 0x0118, - 0x6010, 0x080c, 0x7012, 0x009e, 0x00c6, 0x080c, 0xb16c, 0x00ce, - 0x0036, 0x080c, 0x9ab3, 0x003e, 0x009e, 0x0804, 0xe7fa, 0x9786, - 0x000a, 0x0904, 0xe7ea, 0x0804, 0xe7df, 0x81ff, 0x0904, 0xe7fa, + 0x080c, 0x9851, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc33, 0x0118, + 0x6010, 0x080c, 0x6f11, 0x009e, 0x00c6, 0x080c, 0xaf4e, 0x00ce, + 0x0036, 0x080c, 0x98bc, 0x003e, 0x009e, 0x0804, 0xe502, 0x9786, + 0x000a, 0x0904, 0xe4f2, 0x0804, 0xe4e7, 0x81ff, 0x0904, 0xe502, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180, 0x0001, - 0x2004, 0x9086, 0x002d, 0x1904, 0xe7fa, 0x6000, 0x9086, 0x0002, - 0x1904, 0xe7fa, 0x080c, 0xd121, 0x0138, 0x080c, 0xd132, 0x1904, - 0xe7fa, 0x080c, 0xbb5c, 0x0038, 0x080c, 0x3344, 0x080c, 0xd132, - 0x1110, 0x080c, 0xbb5c, 0x080c, 0xb1a7, 0x0804, 0xe7fa, 0xa864, + 0x2004, 0x9086, 0x002d, 0x1904, 0xe502, 0x6000, 0x9086, 0x0002, + 0x1904, 0xe502, 0x080c, 0xce39, 0x0138, 0x080c, 0xce4a, 0x1904, + 0xe502, 0x080c, 0xb93c, 0x0038, 0x080c, 0x332a, 0x080c, 0xce4a, + 0x1110, 0x080c, 0xb93c, 0x080c, 0xaf89, 0x0804, 0xe502, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, - 0x2c08, 0x2170, 0x9006, 0x080c, 0xea57, 0x001e, 0x0120, 0x6020, - 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe894, 0xe894, - 0xe894, 0xe894, 0xe894, 0xe894, 0xe896, 0xe894, 0xe894, 0xe894, - 0xe8bf, 0xb1a7, 0xb1a7, 0xe894, 0x9006, 0x0005, 0x0036, 0x0046, + 0x2c08, 0x2170, 0x9006, 0x080c, 0xe75f, 0x001e, 0x0120, 0x6020, + 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe59c, 0xe59c, + 0xe59c, 0xe59c, 0xe59c, 0xe59c, 0xe59e, 0xe59c, 0xe59c, 0xe59c, + 0xe5c7, 0xaf89, 0xaf89, 0xe59c, 0x9006, 0x0005, 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, - 0x0020, 0x080c, 0xea8d, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, - 0xe586, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xcf1b, - 0x0140, 0x6014, 0x904d, 0x080c, 0xcae9, 0x687b, 0x0005, 0x080c, - 0x7012, 0x009e, 0x080c, 0xb1a7, 0x9085, 0x0001, 0x0005, 0x0019, - 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d85, - 0x000b, 0x0005, 0xe8da, 0xe8da, 0xe8f1, 0xe8e1, 0xe900, 0xe8da, - 0xe8da, 0xe8dc, 0xe8da, 0xe8da, 0xe8da, 0xe8da, 0xe8da, 0xe8da, - 0xe8da, 0xe8da, 0x080c, 0x0d85, 0x080c, 0xb1a7, 0x9085, 0x0001, - 0x0005, 0x0036, 0x00e6, 0x2071, 0x19e8, 0x704c, 0x9c06, 0x1128, - 0x2019, 0x0001, 0x080c, 0xa596, 0x0010, 0x080c, 0xa7a1, 0x00ee, + 0x0020, 0x080c, 0xe795, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, + 0xe28e, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xcc33, + 0x0140, 0x6014, 0x904d, 0x080c, 0xc81b, 0x687b, 0x0005, 0x080c, + 0x6f11, 0x009e, 0x080c, 0xaf89, 0x9085, 0x0001, 0x0005, 0x0019, + 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79, + 0x000b, 0x0005, 0xe5e2, 0xe5e2, 0xe5f9, 0xe5e9, 0xe608, 0xe5e2, + 0xe5e2, 0xe5e4, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2, + 0xe5e2, 0xe5e2, 0x080c, 0x0d79, 0x080c, 0xaf89, 0x9085, 0x0001, + 0x0005, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06, 0x1128, + 0x2019, 0x0001, 0x080c, 0xa391, 0x0010, 0x080c, 0xa59c, 0x00ee, 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, 0x0005, 0x080c, - 0x7012, 0x080c, 0xb1a7, 0x00de, 0x009e, 0x9085, 0x0001, 0x0005, - 0x601c, 0xd084, 0x190c, 0x1ad3, 0x0c60, 0x2001, 0x0001, 0x080c, - 0x66e6, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, - 0x1805, 0x2011, 0x0276, 0x080c, 0xc20e, 0x003e, 0x002e, 0x001e, + 0x6f11, 0x080c, 0xaf89, 0x00de, 0x009e, 0x9085, 0x0001, 0x0005, + 0x601c, 0xd084, 0x190c, 0x1af0, 0x0c60, 0x2001, 0x0001, 0x080c, + 0x66b5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, + 0x1805, 0x2011, 0x0276, 0x080c, 0xbf40, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1ddc, - 0x2079, 0x0001, 0x8fff, 0x0904, 0xe977, 0x2071, 0x1800, 0x7654, - 0x7074, 0x8001, 0x9602, 0x1a04, 0xe977, 0x88ff, 0x0120, 0x2800, - 0x9c06, 0x15a0, 0x2078, 0x080c, 0xeabe, 0x0580, 0x2400, 0x9c06, + 0x2079, 0x0001, 0x8fff, 0x0904, 0xe67f, 0x2071, 0x1800, 0x7654, + 0x7074, 0x8001, 0x9602, 0x1a04, 0xe67f, 0x88ff, 0x0120, 0x2800, + 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe7c6, 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584, 0x0118, 0x605c, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, - 0x080c, 0xece1, 0x080c, 0xd65d, 0x080c, 0x1ad3, 0x6023, 0x0007, - 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0120, 0x0046, 0x080c, 0xea30, - 0x004e, 0x009e, 0x080c, 0xb1a7, 0x88ff, 0x1198, 0x9ce0, 0x001c, - 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe92a, 0x9006, + 0x080c, 0xe9f0, 0x080c, 0xd375, 0x080c, 0x1af0, 0x6023, 0x0007, + 0x6014, 0x2048, 0x080c, 0xcc33, 0x0120, 0x0046, 0x080c, 0xe738, + 0x004e, 0x009e, 0x080c, 0xaf89, 0x88ff, 0x1198, 0x9ce0, 0x001c, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe632, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, - 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x080c, 0xacfc, 0x00b6, 0x0076, + 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x080c, 0xaaf7, 0x00b6, 0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, - 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa667, 0x009e, 0x008e, - 0x903e, 0x080c, 0xa712, 0x080c, 0xe91b, 0x005e, 0x007e, 0x00be, - 0x080c, 0xad18, 0x0005, 0x080c, 0xacfc, 0x00b6, 0x0046, 0x0056, + 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e, 0x008e, + 0x903e, 0x080c, 0xa50d, 0x080c, 0xe623, 0x005e, 0x007e, 0x00be, + 0x080c, 0xab13, 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, - 0x0016, 0x0036, 0x080c, 0x67b4, 0x1180, 0x0056, 0x0086, 0x9046, - 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0xa667, 0x009e, - 0x008e, 0x903e, 0x080c, 0xa712, 0x005e, 0x003e, 0x001e, 0x8108, - 0x1f04, 0xe9b0, 0x0036, 0x2508, 0x2029, 0x0003, 0x080c, 0xe91b, + 0x0016, 0x0036, 0x080c, 0x6783, 0x1180, 0x0056, 0x0086, 0x9046, + 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e, + 0x008e, 0x903e, 0x080c, 0xa50d, 0x005e, 0x003e, 0x001e, 0x8108, + 0x1f04, 0xe6b8, 0x0036, 0x2508, 0x2029, 0x0003, 0x080c, 0xe623, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, - 0xad18, 0x0005, 0x080c, 0xacfc, 0x00b6, 0x0076, 0x0056, 0x6210, + 0xab13, 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, - 0x904e, 0x080c, 0xa667, 0x009e, 0x008e, 0x903e, 0x080c, 0xa712, - 0x2c20, 0x080c, 0xe91b, 0x005e, 0x007e, 0x00be, 0x080c, 0xad18, - 0x0005, 0x080c, 0xacfc, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, + 0x904e, 0x080c, 0xa462, 0x009e, 0x008e, 0x903e, 0x080c, 0xa50d, + 0x2c20, 0x080c, 0xe623, 0x005e, 0x007e, 0x00be, 0x080c, 0xab13, + 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, - 0x67b4, 0x1190, 0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, - 0x080c, 0xecc5, 0x004e, 0x0096, 0x904e, 0x080c, 0xa667, 0x009e, - 0x008e, 0x903e, 0x080c, 0xa712, 0x003e, 0x001e, 0x8108, 0x1f04, - 0xea05, 0x0036, 0x2029, 0x0002, 0x080c, 0xe91b, 0x003e, 0x015e, - 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xad18, 0x0005, - 0x0016, 0x00f6, 0x080c, 0xcf19, 0x0198, 0xa864, 0x9084, 0x00ff, + 0x6783, 0x1190, 0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, + 0x080c, 0xe9d4, 0x004e, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e, + 0x008e, 0x903e, 0x080c, 0xa50d, 0x003e, 0x001e, 0x8108, 0x1f04, + 0xe70d, 0x0036, 0x2029, 0x0002, 0x080c, 0xe623, 0x003e, 0x015e, + 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xab13, 0x0005, + 0x0016, 0x00f6, 0x080c, 0xcc31, 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, - 0xab82, 0x080c, 0x7012, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x7012, + 0xab82, 0x080c, 0x6f11, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6f11, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, - 0x080c, 0x7012, 0x2f48, 0x0cb8, 0x080c, 0x7012, 0x0c88, 0x00e6, + 0x080c, 0x6f11, 0x2f48, 0x0cb8, 0x080c, 0x6f11, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1ddc, 0x9005, 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000, 0x0168, 0x6008, 0x9206, 0x1150, 0x6320, @@ -7288,157 +7193,157 @@ unsigned short risc_code01[] = { 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, - 0x1059, 0x000e, 0x090c, 0x0d85, 0xaae2, 0xa867, 0x010d, 0xa88e, - 0x0026, 0x2010, 0x080c, 0xcf09, 0x2001, 0x0000, 0x0120, 0x2200, + 0x104d, 0x000e, 0x090c, 0x0d79, 0xaae2, 0xa867, 0x010d, 0xa88e, + 0x0026, 0x2010, 0x080c, 0xcc21, 0x2001, 0x0000, 0x0120, 0x2200, 0x9080, 0x0017, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, - 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198e, + 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198f, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, - 0x8000, 0x080c, 0x7012, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786, + 0x8000, 0x080c, 0x6f11, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, - 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1987, 0x2004, - 0x601a, 0x2009, 0x8020, 0x080c, 0x9617, 0x001e, 0x0005, 0xa001, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1988, 0x2004, + 0x601a, 0x2009, 0x8020, 0x080c, 0x9420, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, - 0xd267, 0x0030, 0x080c, 0xece1, 0x080c, 0x8c19, 0x080c, 0xb16c, - 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xeb1d, - 0xeb1d, 0xeb1d, 0xeb1f, 0xeb1d, 0xeb1f, 0xeb1f, 0xeb1d, 0xeb1f, - 0xeb1d, 0xeb1d, 0xeb1d, 0xeb1d, 0xeb1d, 0x9006, 0x0005, 0x9085, + 0xcf7f, 0x0030, 0x080c, 0xe9f0, 0x080c, 0x8ab2, 0x080c, 0xaf4e, + 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xe825, + 0xe825, 0xe825, 0xe827, 0xe825, 0xe827, 0xe827, 0xe825, 0xe827, + 0xe825, 0xe825, 0xe825, 0xe825, 0xe825, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, - 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb43, 0xeb36, - 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0x6007, 0x003b, + 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe84b, 0xe83e, + 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, - 0x080c, 0x9617, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xece1, + 0x080c, 0x9420, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xe9f0, 0x604b, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, - 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xeb9c, 0x6814, + 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xe8a4, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, - 0x9617, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xec0c, - 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0d85, - 0x0804, 0xec0c, 0x2048, 0x080c, 0xcf1b, 0x1130, 0x0028, 0x2048, + 0x9420, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xe91b, + 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0d79, + 0x0804, 0xe91b, 0x2048, 0x080c, 0xcc33, 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, - 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xe3b5, 0x0804, 0xec0c, - 0x2009, 0x0041, 0x0804, 0xec06, 0x9186, 0x0005, 0x15a0, 0x6814, - 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xeb36, - 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0d85, 0x0804, 0xeb57, 0x6007, - 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x00c6, + 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xe0cb, 0x0804, 0xe91b, + 0x2009, 0x0041, 0x0804, 0xe915, 0x9186, 0x0005, 0x15a0, 0x6814, + 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xe83e, + 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0d79, 0x0804, 0xe85f, 0x6007, + 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, - 0xec0c, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, - 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, - 0x2009, 0x0042, 0x0498, 0x0036, 0x080c, 0x1059, 0x090c, 0x0d85, + 0xe91b, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, + 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x17a1, 0x00fe, + 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x104d, 0x090c, 0x0d79, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, 0x635c, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, - 0xa89f, 0x0001, 0x080c, 0x7012, 0x2019, 0x0045, 0x6008, 0x2068, - 0x080c, 0xe578, 0x2d00, 0x600a, 0x003e, 0x0038, 0x604b, 0x0000, - 0x6003, 0x0007, 0x080c, 0xe3b5, 0x00ce, 0x00de, 0x009e, 0x0005, - 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, - 0x9186, 0x0027, 0x1178, 0x080c, 0x99ed, 0x0036, 0x0096, 0x6014, - 0x2048, 0x2019, 0x0004, 0x080c, 0xea30, 0x009e, 0x003e, 0x080c, - 0x9ab3, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xb227, 0x0005, - 0xec3f, 0xec3d, 0xec3d, 0xec3d, 0xec3d, 0xec3d, 0xec3f, 0xec3d, - 0xec3d, 0xec3d, 0xec3d, 0xec3d, 0xec3d, 0x080c, 0x0d85, 0x6003, - 0x000c, 0x080c, 0x9ab3, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, - 0x0085, 0x0208, 0x001a, 0x080c, 0xb227, 0x0005, 0xec5b, 0xec5b, - 0xec5b, 0xec5b, 0xec5d, 0xec7d, 0xec5b, 0xec5b, 0xec5b, 0xec5b, - 0xec5b, 0xec5b, 0xec5b, 0x080c, 0x0d85, 0x00d6, 0x2c68, 0x080c, - 0xb116, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, - 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, - 0x6910, 0x6112, 0x6023, 0x0004, 0x2009, 0x8020, 0x080c, 0x9617, - 0x2d60, 0x080c, 0xb16c, 0x00de, 0x0005, 0x080c, 0xb16c, 0x0005, - 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, - 0x0005, 0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, - 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1988, 0x2004, - 0x604a, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, - 0x1867, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, - 0x00d8, 0x2001, 0x1988, 0x200c, 0x2001, 0x1986, 0x2004, 0x9100, - 0x9080, 0x000a, 0x604a, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, - 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, - 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, - 0x615c, 0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x605c, - 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x8c19, 0x080c, 0xb16c, - 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, - 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, 0x0130, - 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de, - 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084, - 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, 0x1508, - 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, - 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, - 0x080c, 0xc222, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, - 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xc222, 0x009e, - 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, - 0x080c, 0x6130, 0x080c, 0x30bf, 0x00ee, 0x0005, 0x0096, 0x0026, - 0x080c, 0x1059, 0x090c, 0x0d85, 0xa85c, 0x9080, 0x001a, 0x20a0, - 0x20a9, 0x000c, 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, - 0x1118, 0xa867, 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, 0x0041, - 0x0110, 0xa87b, 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, 0x9294, - 0xff00, 0x8007, 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, - 0x9084, 0x00ff, 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, - 0x9294, 0x00ff, 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, - 0x9294, 0xff00, 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, - 0x9186, 0x0046, 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, - 0x2204, 0x8007, 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, - 0x2204, 0x8007, 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, - 0x9186, 0x0046, 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, - 0x8210, 0x2204, 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, - 0x8210, 0x2204, 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, - 0x0001, 0x00b0, 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, - 0x2204, 0x8007, 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, 0x2011, - 0x0260, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, - 0x9186, 0x0046, 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, 0x026a, - 0x0146, 0x01d6, 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, - 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, - 0x8210, 0x8319, 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, - 0x2013, 0x0000, 0x002e, 0x080c, 0x7012, 0x009e, 0x0005, 0x00e6, - 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, - 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, - 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, - 0x2091, 0x8000, 0x2029, 0x19f4, 0x252c, 0x2021, 0x19fb, 0x2424, - 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, 0x0578, - 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, - 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xeabe, 0x01b8, - 0x080c, 0xeace, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, - 0x080c, 0x1ad3, 0x001e, 0x080c, 0xd121, 0x1110, 0x080c, 0x3344, - 0x080c, 0xd132, 0x1110, 0x080c, 0xbb5c, 0x080c, 0xb1a7, 0x9ce0, - 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, - 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, - 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, - 0x2001, 0x1837, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, - 0x0046, 0x080c, 0xd645, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, - 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, - 0x4e58, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, 0x0001, - 0x1128, 0x080c, 0xa7e2, 0x080c, 0xb1a7, 0x9006, 0x0005, 0x00e6, - 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7454, - 0x7074, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, - 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, - 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, - 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, - 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, - 0xd0a4, 0x0160, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, 0x2001, - 0x1848, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, 0x9006, - 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, - 0x1840, 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, 0x0118, - 0x7000, 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007, - 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, - 0x0118, 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, - 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xffee, - 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, 0x2077, - 0x1220, 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, 0x2071, - 0xffec, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, 0x0c69, - 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, - 0x1840, 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, 0x0005, - 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, - 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, - 0xaa6e + 0xa89f, 0x0001, 0x080c, 0x6f11, 0x2019, 0x0045, 0x6008, 0x2068, + 0x080c, 0xe28e, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, + 0x901e, 0x631a, 0x634a, 0x003e, 0x0038, 0x604b, 0x0000, 0x6003, + 0x0007, 0x080c, 0xe0cb, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, + 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, + 0x0027, 0x1178, 0x080c, 0x97f6, 0x0036, 0x0096, 0x6014, 0x2048, + 0x2019, 0x0004, 0x080c, 0xe738, 0x009e, 0x003e, 0x080c, 0x98bc, + 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xb009, 0x0005, 0xe94e, + 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0xe94e, 0xe94c, 0xe94c, + 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0x080c, 0x0d79, 0x6003, 0x000c, + 0x080c, 0x98bc, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, + 0x0208, 0x001a, 0x080c, 0xb009, 0x0005, 0xe96a, 0xe96a, 0xe96a, + 0xe96a, 0xe96c, 0xe98c, 0xe96a, 0xe96a, 0xe96a, 0xe96a, 0xe96a, + 0xe96a, 0xe96a, 0x080c, 0x0d79, 0x00d6, 0x2c68, 0x080c, 0xaef8, + 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, + 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, + 0x6112, 0x6023, 0x0004, 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60, + 0x080c, 0xaf4e, 0x00de, 0x0005, 0x080c, 0xaf4e, 0x0005, 0x00e6, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, + 0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, + 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1989, 0x2004, 0x604a, + 0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, + 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, + 0x2001, 0x1989, 0x200c, 0x2001, 0x1987, 0x2004, 0x9100, 0x9080, + 0x000a, 0x604a, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, + 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, + 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x615c, + 0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x605c, 0x9106, + 0x1138, 0x600c, 0x2072, 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x0010, + 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, + 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, + 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de, 0x0005, + 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, + 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, + 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, + 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, + 0xbf54, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, + 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x1100, + 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x610b, 0x080c, 0x30c8, 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, + 0x104d, 0x090c, 0x0d79, 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, + 0x000c, 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, + 0xa867, 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, + 0xa87b, 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, + 0x8007, 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, + 0x00ff, 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, + 0x00ff, 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, + 0xff00, 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, + 0x0046, 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, + 0x8007, 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, + 0x8007, 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, + 0x0046, 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, + 0x2204, 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, + 0x2204, 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, + 0x00b0, 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, + 0x8007, 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, + 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, + 0x0046, 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, + 0x01d6, 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, + 0x8319, 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, + 0x0000, 0x002e, 0x080c, 0x6f11, 0x009e, 0x0005, 0x00e6, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, + 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, + 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, + 0x8000, 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, + 0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, + 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, + 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xe7c6, 0x01b8, 0x080c, + 0xe7d6, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, + 0x1af0, 0x001e, 0x080c, 0xce39, 0x1110, 0x080c, 0x332a, 0x080c, + 0xce4a, 0x1110, 0x080c, 0xb93c, 0x080c, 0xaf89, 0x9ce0, 0x001c, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, + 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, + 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, + 0x1837, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, + 0x080c, 0xd35d, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, + 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4ddf, + 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, 0x0001, 0x1128, + 0x080c, 0xa5dd, 0x080c, 0xaf89, 0x9006, 0x0005, 0x00e6, 0x00c6, + 0x00b6, 0x0046, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7454, 0x7074, + 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, + 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, + 0x9086, 0x0002, 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, + 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, + 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, + 0x0160, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, + 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, + 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, 0x1840, + 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, + 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, + 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, + 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, + 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xffee, 0x0021, + 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, + 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, + 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, + 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, + 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0001, + 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x7163 }; #ifdef UNIQUE_FW_NAME -unsigned short fw2322ipx_length01 = 0xe719; +unsigned short fw2322ipx_length01 = 0xe428; #else -unsigned short risc_code_length01 = 0xe719; +unsigned short risc_code_length01 = 0xe428; #endif /* @@ -7447,7 +7352,7 @@ unsigned short risc_code_length01 = 0xe719; unsigned long rseqipx_code_addr01 = 0x0001c000 ; unsigned short rseqipx_code01[] = { -0x000b, 0x0003, 0x0000, 0x0a4e, 0x0001, 0xc000, 0x0008, 0x8064, +0x000b, 0x0003, 0x0000, 0x0a4a, 0x0001, 0xc000, 0x0008, 0x8064, 0x0000, 0x0010, 0x0000, 0x8066, 0x0008, 0x0101, 0x0003, 0xc007, 0x0008, 0x80e0, 0x0008, 0xff00, 0x0000, 0x80e2, 0x0008, 0xff00, 0x0008, 0x0162, 0x0000, 0x8066, 0x0008, 0xa101, 0x000b, 0xc00f, @@ -7650,7 +7555,7 @@ unsigned short rseqipx_code01[] = { 0x0003, 0x8b23, 0x0008, 0x3c1e, 0x000b, 0x0372, 0x0009, 0xbbe0, 0x0000, 0x003b, 0x000b, 0x8b28, 0x0000, 0x3cdc, 0x000b, 0x0372, 0x0009, 0xbbe0, 0x0008, 0x0035, 0x000b, 0x8b2e, 0x0000, 0x8072, - 0x0000, 0x8000, 0x000b, 0x04e5, 0x0009, 0xbbe0, 0x0008, 0x0036, + 0x0000, 0x8000, 0x000b, 0x04e3, 0x0009, 0xbbe0, 0x0008, 0x0036, 0x000b, 0x0c06, 0x0009, 0xbbe0, 0x0000, 0x0037, 0x000b, 0x8b53, 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x000b, 0x8b1b, 0x0008, 0x8076, 0x0000, 0x0040, 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x000d, @@ -7709,8 +7614,8 @@ unsigned short rseqipx_code01[] = { 0x0000, 0x8072, 0x0000, 0x8000, 0x0001, 0x43e0, 0x000b, 0x8c15, 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0009, 0x00e0, 0x000b, 0x0bf1, 0x0008, 0x0d08, 0x0003, 0x046a, 0x0000, 0x8072, - 0x0000, 0x8000, 0x0003, 0x0013, 0x000c, 0x04ee, 0x0008, 0x808c, - 0x0000, 0x0001, 0x0000, 0x04fc, 0x0003, 0x34d1, 0x0000, 0x0460, + 0x0000, 0x8000, 0x0003, 0x0013, 0x0004, 0x04ec, 0x0008, 0x808c, + 0x0000, 0x0001, 0x0000, 0x04fc, 0x0003, 0x34cf, 0x0000, 0x0460, 0x0008, 0x8062, 0x0000, 0x0001, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc424, 0x0000, 0x0004, 0x0009, 0x80c0, 0x0008, 0x00ff, 0x0000, 0x7f00, 0x0001, 0x80e0, 0x0000, 0x0004, 0x0003, 0x0c3e, @@ -7718,8 +7623,8 @@ unsigned short rseqipx_code01[] = { 0x0008, 0x0006, 0x0003, 0x0c3e, 0x0001, 0x82c0, 0x0008, 0xff00, 0x0008, 0x7f04, 0x0009, 0x82e0, 0x0008, 0x0600, 0x0003, 0x0c3e, 0x0009, 0x82e0, 0x0008, 0x0500, 0x0003, 0x0c3e, 0x0009, 0x82e0, - 0x0000, 0x0400, 0x0003, 0x8cd1, 0x0009, 0xc4c0, 0x0000, 0x7000, - 0x0009, 0xffe0, 0x0000, 0x1000, 0x000b, 0x0c6a, 0x0004, 0x04df, + 0x0000, 0x0400, 0x0003, 0x8ccf, 0x0009, 0xc4c0, 0x0000, 0x7000, + 0x0009, 0xffe0, 0x0000, 0x1000, 0x000b, 0x0c6a, 0x000c, 0x04dd, 0x0002, 0x3941, 0x0003, 0x0c49, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, 0x0000, 0x0460, 0x0008, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, 0x000b, 0xc44f, @@ -7729,56 +7634,56 @@ unsigned short rseqipx_code01[] = { 0x0008, 0xff00, 0x0009, 0x03e0, 0x000b, 0x8c62, 0x0000, 0x8072, 0x0000, 0x0400, 0x000b, 0x0056, 0x0001, 0x9180, 0x0008, 0x0003, 0x000b, 0x044c, 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010, - 0x0000, 0x0010, 0x000b, 0x04c4, 0x0004, 0x04df, 0x0002, 0x3941, + 0x0000, 0x0010, 0x000b, 0x04c2, 0x000c, 0x04dd, 0x0002, 0x3941, 0x0003, 0x0c70, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, - 0x000a, 0x6e42, 0x0003, 0x0c75, 0x000c, 0x04a9, 0x0008, 0x11fc, - 0x0003, 0xb47a, 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010, - 0x0000, 0x000e, 0x000b, 0x04c4, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0000, 0x04fc, 0x0003, 0xb48f, 0x0008, 0x808c, 0x0008, 0x0000, - 0x0001, 0x9180, 0x0008, 0x0005, 0x0008, 0x7f62, 0x0000, 0x8066, - 0x0008, 0x0009, 0x000b, 0xc485, 0x0008, 0x0060, 0x0008, 0x8062, - 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, 0x0000, 0x8066, - 0x0000, 0x0412, 0x0003, 0xc48d, 0x0003, 0x04a6, 0x0008, 0x808c, - 0x0000, 0x0001, 0x0000, 0x0460, 0x0008, 0x8062, 0x0008, 0x002b, - 0x0000, 0x8066, 0x0008, 0x0609, 0x0003, 0xc496, 0x0000, 0x8066, - 0x0008, 0x220a, 0x0003, 0xc499, 0x0000, 0x42fe, 0x0001, 0xffc0, - 0x0008, 0xff00, 0x0008, 0x7f04, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0001, 0x9180, 0x0000, 0x0002, 0x0008, 0x7f62, 0x0000, 0x8066, - 0x0008, 0x041a, 0x0003, 0xc4a5, 0x0000, 0x8072, 0x0000, 0x0400, - 0x000b, 0x0056, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x6b62, - 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc4ae, 0x0008, 0x02fe, - 0x0009, 0x03e0, 0x0003, 0x8cb4, 0x0000, 0x0d22, 0x000f, 0x4000, - 0x0009, 0x8280, 0x0000, 0x0002, 0x0001, 0x6b80, 0x0008, 0x7f62, - 0x0000, 0x8066, 0x0008, 0x2209, 0x000b, 0xc4ba, 0x000a, 0x0200, - 0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06, 0x0008, 0x6b62, - 0x0000, 0x8066, 0x0008, 0x060a, 0x000b, 0xc4c2, 0x000f, 0x4000, - 0x0002, 0x3a44, 0x0003, 0x8813, 0x000a, 0x2f44, 0x000a, 0x2f44, - 0x0003, 0x8bd0, 0x0008, 0x808a, 0x0008, 0x0003, 0x0000, 0x8074, - 0x0000, 0xf080, 0x0003, 0x5ccd, 0x0008, 0x8054, 0x0000, 0x0019, - 0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x808c, - 0x0008, 0x0000, 0x0008, 0x8010, 0x0008, 0x0011, 0x0004, 0x0387, - 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0008, 0x7f10, - 0x0004, 0x0387, 0x0008, 0x4310, 0x000b, 0x03dd, 0x0002, 0x3941, - 0x000b, 0x0ce2, 0x000f, 0x4000, 0x0000, 0x8072, 0x0008, 0x0404, - 0x000f, 0x4000, 0x0008, 0x8010, 0x0008, 0x0012, 0x0004, 0x0387, - 0x000c, 0x04a9, 0x0000, 0x1110, 0x0004, 0x0387, 0x0008, 0x11fc, - 0x000b, 0xb4e8, 0x0003, 0x0013, 0x0009, 0xc2c0, 0x0008, 0x00ff, - 0x0000, 0x7f00, 0x0001, 0xc3c0, 0x0008, 0xff00, 0x0009, 0x00d0, - 0x000b, 0x0d13, 0x0000, 0x0d0a, 0x0001, 0x8580, 0x0000, 0x1000, - 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, - 0x0000, 0x0809, 0x000b, 0xc4fd, 0x0000, 0x04fc, 0x000b, 0x350c, - 0x0000, 0x0460, 0x0008, 0x8062, 0x0000, 0x0004, 0x0000, 0x8066, - 0x0000, 0x0211, 0x000b, 0xc505, 0x0008, 0x01fe, 0x0009, 0x00e0, - 0x000b, 0x8d0c, 0x0008, 0x02fe, 0x0001, 0x43e0, 0x0003, 0x0d12, - 0x0002, 0x0500, 0x0000, 0x7f0a, 0x0009, 0xffe0, 0x0000, 0x0800, - 0x0003, 0x8cf6, 0x0008, 0x0d08, 0x000f, 0x4000, 0x0008, 0x43fe, - 0x0001, 0x3e80, 0x0000, 0x0d60, 0x0008, 0x7f62, 0x0000, 0x8066, - 0x0000, 0x0809, 0x0003, 0xc519, 0x0000, 0x8060, 0x0000, 0x0400, - 0x0001, 0x84c0, 0x0008, 0xff00, 0x0002, 0x7f70, 0x0009, 0xff80, - 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0809, - 0x000b, 0xc524, 0x000f, 0x4000, 0xe4a8, 0xa3b9 + 0x0004, 0x04a7, 0x0008, 0x11fc, 0x000b, 0xb478, 0x0000, 0x8072, + 0x0000, 0x0400, 0x0008, 0x8010, 0x0000, 0x000e, 0x000b, 0x04c2, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x04fc, 0x000b, 0xb48d, + 0x0008, 0x808c, 0x0008, 0x0000, 0x0001, 0x9180, 0x0008, 0x0005, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc483, + 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, + 0x0008, 0x4206, 0x0000, 0x8066, 0x0000, 0x0412, 0x0003, 0xc48b, + 0x000b, 0x04a4, 0x0008, 0x808c, 0x0000, 0x0001, 0x0000, 0x0460, + 0x0008, 0x8062, 0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0x0609, + 0x000b, 0xc494, 0x0000, 0x8066, 0x0008, 0x220a, 0x000b, 0xc497, + 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0xff00, 0x0008, 0x7f04, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9180, 0x0000, 0x0002, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc4a3, + 0x0000, 0x8072, 0x0000, 0x0400, 0x000b, 0x0056, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0008, 0x6b62, 0x0000, 0x8066, 0x0000, 0x0411, + 0x0003, 0xc4ac, 0x0008, 0x02fe, 0x0009, 0x03e0, 0x0003, 0x8cb2, + 0x0000, 0x0d22, 0x000f, 0x4000, 0x0009, 0x8280, 0x0000, 0x0002, + 0x0001, 0x6b80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, + 0x0003, 0xc4b8, 0x000a, 0x0200, 0x0001, 0xffc0, 0x0000, 0x0007, + 0x0000, 0x7f06, 0x0008, 0x6b62, 0x0000, 0x8066, 0x0008, 0x060a, + 0x0003, 0xc4c0, 0x000f, 0x4000, 0x0002, 0x3a44, 0x0003, 0x8813, + 0x000a, 0x2f44, 0x000a, 0x2f44, 0x0003, 0x8bd0, 0x0008, 0x808a, + 0x0008, 0x0003, 0x0000, 0x8074, 0x0000, 0xf080, 0x0003, 0x5ccb, + 0x0008, 0x8054, 0x0000, 0x0019, 0x0003, 0x0013, 0x0002, 0x3a44, + 0x0003, 0x8813, 0x0008, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010, + 0x0008, 0x0011, 0x0004, 0x0387, 0x0000, 0x42fe, 0x0001, 0xffc0, + 0x0008, 0x00ff, 0x0008, 0x7f10, 0x0004, 0x0387, 0x0008, 0x4310, + 0x000b, 0x03dd, 0x0002, 0x3941, 0x0003, 0x0ce0, 0x000f, 0x4000, + 0x0000, 0x8072, 0x0008, 0x0404, 0x000f, 0x4000, 0x0008, 0x8010, + 0x0008, 0x0012, 0x0004, 0x0387, 0x0004, 0x04a7, 0x0000, 0x1110, + 0x0004, 0x0387, 0x0008, 0x11fc, 0x0003, 0xb4e6, 0x0003, 0x0013, + 0x0009, 0xc2c0, 0x0008, 0x00ff, 0x0000, 0x7f00, 0x0001, 0xc3c0, + 0x0008, 0xff00, 0x0009, 0x00d0, 0x0003, 0x0d11, 0x0000, 0x0d0a, + 0x0001, 0x8580, 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc4fb, + 0x0000, 0x04fc, 0x000b, 0x350a, 0x0000, 0x0460, 0x0008, 0x8062, + 0x0000, 0x0004, 0x0000, 0x8066, 0x0000, 0x0211, 0x000b, 0xc503, + 0x0008, 0x01fe, 0x0009, 0x00e0, 0x000b, 0x8d0a, 0x0008, 0x02fe, + 0x0001, 0x43e0, 0x000b, 0x0d10, 0x0002, 0x0500, 0x0000, 0x7f0a, + 0x0009, 0xffe0, 0x0000, 0x0800, 0x000b, 0x8cf4, 0x0008, 0x0d08, + 0x000f, 0x4000, 0x0008, 0x43fe, 0x0001, 0x3e80, 0x0000, 0x0d60, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc517, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x84c0, 0x0008, 0xff00, + 0x0002, 0x7f70, 0x0009, 0xff80, 0x0000, 0x1000, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc522, 0x000f, 0x4000, + 0xe4ae, 0x1eb8 }; -unsigned short rseqipx_code_length01 = 0x0a4e; +unsigned short rseqipx_code_length01 = 0x0a4a; /* * */ @@ -7997,10 +7902,10 @@ unsigned short xseqipx_code01[] = { 0x0010, 0xc00a, 0x000b, 0x8345, 0x0013, 0x03a6, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x134e, 0x0005, 0x00ce, 0x0000, 0x0007, 0x0010, 0x0fcf, 0x0003, 0x08e1, 0x0002, 0xd142, 0x0013, 0x1367, - 0x0015, 0x00d1, 0x0000, 0x0400, 0x0011, 0x13e8, 0x0001, 0x1b55, - 0x000b, 0x1367, 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033, + 0x0015, 0x00d1, 0x0000, 0x0400, 0x0011, 0x13e8, 0x0001, 0x1b56, + 0x000b, 0x1367, 0x0005, 0x0031, 0x0011, 0x1b6e, 0x0015, 0x0033, 0x0010, 0xb409, 0x001b, 0x8359, 0x0002, 0xb400, 0x0010, 0xffb4, - 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033, 0x0010, 0xb40a, + 0x0005, 0x0031, 0x0011, 0x1b6e, 0x0015, 0x0033, 0x0010, 0xb40a, 0x001b, 0x8360, 0x0012, 0xd042, 0x0003, 0x1371, 0x0015, 0x00b8, 0x0000, 0x000d, 0x0014, 0x0925, 0x0003, 0x0054, 0x0000, 0x13b8, 0x0002, 0x1045, 0x0003, 0x136f, 0x0012, 0x103f, 0x0002, 0xff27, @@ -8075,7 +7980,7 @@ unsigned short xseqipx_code01[] = { 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0013, 0x1482, 0x0015, 0x003a, 0x0010, 0x8080, 0x0003, 0x0484, 0x0015, 0x003a, 0x0010, 0x4040, 0x0017, 0x4000, 0x0000, 0x12fe, 0x001b, 0x604f, 0x0015, 0x0012, - 0x0001, 0x1b55, 0x0015, 0x0011, 0x0001, 0x1b55, 0x0001, 0x1288, + 0x0001, 0x1b56, 0x0015, 0x0011, 0x0001, 0x1b56, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8490, 0x0005, 0x00b0, 0x0000, 0x8000, 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, @@ -8114,7 +8019,7 @@ unsigned short xseqipx_code01[] = { 0x0000, 0xb012, 0x000b, 0x8519, 0x0013, 0x046b, 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x0035, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8520, 0x0002, 0xb040, 0x0003, 0x153c, 0x0015, 0x0030, - 0x0000, 0x0400, 0x0005, 0x0031, 0x0001, 0x1b71, 0x0015, 0x0033, + 0x0000, 0x0400, 0x0005, 0x0031, 0x0001, 0x1b72, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x8529, 0x0002, 0xb100, 0x0010, 0xffb1, 0x001b, 0x2530, 0x0012, 0xb000, 0x0000, 0xffb0, 0x0013, 0x252a, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x8532, 0x0015, 0x0030, @@ -8206,7 +8111,7 @@ unsigned short xseqipx_code01[] = { 0x0000, 0x9575, 0x0004, 0x08a8, 0x0000, 0xb096, 0x0012, 0xb270, 0x0010, 0xff56, 0x0014, 0x08ca, 0x0010, 0xb052, 0x0010, 0xb153, 0x0000, 0xb6ff, 0x0011, 0xb2d0, 0x0010, 0xff50, 0x0010, 0xb351, - 0x0017, 0x4000, 0x0001, 0x12e8, 0x0001, 0x1b55, 0x0003, 0x1845, + 0x0017, 0x4000, 0x0001, 0x12e8, 0x0001, 0x1b56, 0x0003, 0x1845, 0x0015, 0x00d1, 0x0000, 0x0400, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x1009, 0x000b, 0x86a1, 0x0015, 0x000f, 0x0000, 0x0001, @@ -8316,15 +8221,15 @@ unsigned short xseqipx_code01[] = { 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x8843, 0x0003, 0x0703, 0x0015, 0x0030, 0x0000, 0x0400, 0x0000, 0xa4ff, 0x0003, 0x6893, 0x0011, 0xffa8, 0x0010, 0x0005, 0x000b, 0x2893, - 0x0005, 0x0031, 0x0001, 0x1b6c, 0x0015, 0x0033, 0x0010, 0xb211, + 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033, 0x0010, 0xb211, 0x000b, 0x8850, 0x0002, 0xb200, 0x0010, 0xffb2, 0x0005, 0x0031, - 0x0001, 0x1b6c, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8857, + 0x0011, 0x1b6d, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8857, 0x0015, 0x000f, 0x0000, 0x0001, 0x0000, 0x1213, 0x0005, 0x0010, 0x0000, 0x8000, 0x0015, 0x00a3, 0x0000, 0x0200, 0x0000, 0xc697, 0x0005, 0x0046, 0x0000, 0x0002, 0x0015, 0x00a5, 0x0000, 0x0010, 0x0011, 0xc4d8, 0x0000, 0x3200, 0x0010, 0xff88, 0x0000, 0xc589, 0x0010, 0xc48a, 0x0010, 0xc58b, 0x0010, 0xc08e, 0x0005, 0x008c, - 0x0010, 0xe109, 0x0010, 0xc08d, 0x0015, 0x0090, 0x0001, 0x1b55, + 0x0010, 0xe109, 0x0010, 0xc08d, 0x0015, 0x0090, 0x0001, 0x1b56, 0x0005, 0x0091, 0x0010, 0xffff, 0x0000, 0xb292, 0x0000, 0xb393, 0x0015, 0x009a, 0x0010, 0x0056, 0x0005, 0x009b, 0x0010, 0x95f5, 0x0012, 0xd042, 0x0003, 0x1886, 0x0005, 0x00b0, 0x0010, 0x8080, @@ -8371,6 +8276,6 @@ unsigned short xseqipx_code01[] = { 0x0010, 0xffb2, 0x0011, 0x1388, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8922, 0x0015, 0x00b8, 0x0000, 0x0007, 0x0013, 0x4925, 0x0000, 0xb838, 0x0017, 0x4000, - 0x9a8c, 0xaf3d + 0x9a6c, 0xaf33 }; unsigned short xseqipx_code_length01 = 0x1252; diff --git a/drivers/scsi/qla2xxx/ql2400.c b/drivers/scsi/qla2xxx/ql2400.c index 77914fcfa..6c7165f47 100644 --- a/drivers/scsi/qla2xxx/ql2400.c +++ b/drivers/scsi/qla2xxx/ql2400.c @@ -49,18 +49,6 @@ static struct qla_board_info qla_board_tbl[] = { .fw_info = qla_fw_tbl, .fw_fname = "ql2400_fw.bin", }, - { - .drv_name = qla_driver_name, - .isp_name = "ISP5422", - .fw_info = qla_fw_tbl, - .fw_fname = "ql2400_fw.bin", - }, - { - .drv_name = qla_driver_name, - .isp_name = "ISP5432", - .fw_info = qla_fw_tbl, - .fw_fname = "ql2400_fw.bin", - }, }; static struct pci_device_id qla24xx_pci_tbl[] = { @@ -78,21 +66,6 @@ static struct pci_device_id qla24xx_pci_tbl[] = { .subdevice = PCI_ANY_ID, .driver_data = (unsigned long)&qla_board_tbl[1], }, - { - .vendor = PCI_VENDOR_ID_QLOGIC, - .device = PCI_DEVICE_ID_QLOGIC_ISP5422, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long)&qla_board_tbl[2], - }, - { - .vendor = PCI_VENDOR_ID_QLOGIC, - .device = PCI_DEVICE_ID_QLOGIC_ISP5432, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long)&qla_board_tbl[3], - }, - {0, 0}, }; MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl); diff --git a/drivers/scsi/qla2xxx/ql2400_fw.c b/drivers/scsi/qla2xxx/ql2400_fw.c index 282b2d33e..597779585 100644 --- a/drivers/scsi/qla2xxx/ql2400_fw.c +++ b/drivers/scsi/qla2xxx/ql2400_fw.c @@ -7,7 +7,7 @@ #include /* - * Firmware Version 4.00.18 (14:53 Jan 30, 2006) + * Firmware Version 4.00.16 (08:09 Oct 26, 2005) */ #ifdef UNIQUE_FW_NAME @@ -17,15 +17,15 @@ uint32_t risc_code_version = 4*1024+0; #endif #ifdef UNIQUE_FW_NAME -uint32_t fw2400_version_str[] = {4, 0,18}; +uint32_t fw2400_version_str[] = {4, 0,16}; #else -uint32_t firmware_version[] = {4, 0,18}; +uint32_t firmware_version[] = {4, 0,16}; #endif #ifdef UNIQUE_FW_NAME -#define fw2400_VERSION_STRING "4.00.18" +#define fw2400_VERSION_STRING "4.00.16" #else -#define FW_VERSION_STRING "4.00.18" +#define FW_VERSION_STRING "4.00.16" #endif #ifdef UNIQUE_FW_NAME @@ -39,19 +39,19 @@ uint32_t fw2400_code01[] = { #else uint32_t risc_code01[] = { #endif - 0x0401f17c, 0x0010d000, 0x00100000, 0x0000a971, - 0x00000004, 0x00000000, 0x00000012, 0x00000002, + 0x0401f17c, 0x0010e000, 0x00100000, 0x0000ab4a, + 0x00000004, 0x00000000, 0x00000010, 0x00000002, 0x00000003, 0x00000000, 0x20434f50, 0x59524947, 0x48542032, 0x30303520, 0x514c4f47, 0x49432043, 0x4f52504f, 0x52415449, 0x4f4e2020, 0x20495350, 0x32347878, 0x20466972, 0x6d776172, 0x65202020, - 0x56657273, 0x696f6e20, 0x342e302e, 0x31382020, + 0x56657273, 0x696f6e20, 0x342e302e, 0x31362020, 0x20202024, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x42001800, 0x0010014f, 0x42002000, 0x0010b6fd, + 0x42001800, 0x0010014f, 0x42002000, 0x0010b8fe, 0x500c0800, 0x800c1800, 0x500c1000, 0x800c1800, 0x54042000, 0x80102000, 0x80040800, 0x80081040, 0x040207fc, 0x500c0800, 0x800409c0, 0x040207f6, @@ -138,7 +138,7 @@ uint32_t risc_code01[] = { 0x42000800, 0x00021f00, 0x45780800, 0x80040800, 0x80000040, 0x040207fd, 0x4203f000, 0x00021fff, 0x40000000, 0x4203e000, 0x90000100, 0x40000000, - 0x0201f800, 0x00100743, 0x42000000, 0x00001000, + 0x0201f800, 0x001006fd, 0x42000000, 0x00001000, 0x50000000, 0x82000480, 0x24320002, 0x04020015, 0x42000800, 0x00000064, 0x80040840, 0x04000007, 0x4a030000, 0x00000001, 0x40000000, 0x59800000, @@ -149,759 +149,742 @@ uint32_t risc_code01[] = { 0x59e00023, 0x8c000500, 0x04020039, 0x42000000, 0x00100001, 0x50000800, 0x82040c00, 0x00000004, 0x58042003, 0x42001000, 0xffffffff, 0x0201f800, - 0x0010073a, 0x0402004e, 0x58042003, 0x42001000, - 0xffffffff, 0x0201f800, 0x0010073a, 0x04020048, + 0x001006f4, 0x0402004e, 0x58042003, 0x42001000, + 0xffffffff, 0x0201f800, 0x001006f4, 0x04020048, 0x58042003, 0x42001000, 0x00ffffff, 0x0201f800, - 0x0010073a, 0x04020042, 0x58042003, 0x42001000, - 0x00ffffff, 0x0201f800, 0x0010073a, 0x0402003c, + 0x001006f4, 0x04020042, 0x58042003, 0x42001000, + 0x00ffffff, 0x0201f800, 0x001006f4, 0x0402003c, 0x42000000, 0x00100001, 0x5000a000, 0x8250a400, 0x00000004, 0x4200a800, 0x00020000, 0x5850b003, - 0x0201f800, 0x0010a93e, 0x8250a400, 0x00000005, + 0x0201f800, 0x0010ab17, 0x8250a400, 0x00000005, 0x4a0370e8, 0x00000003, 0x4200a800, 0x0000c000, - 0x5850b003, 0x0201f800, 0x0010a93e, 0x4a0378e8, + 0x5850b003, 0x0201f800, 0x0010ab17, 0x4a0378e8, 0x00000003, 0x4200a800, 0x00008000, 0x5850b003, - 0x0201f800, 0x0010a93e, 0x0401f02b, 0x42000800, + 0x0201f800, 0x0010ab17, 0x0401f02b, 0x42000800, 0x00020000, 0x58042003, 0x42001000, 0xffffffff, - 0x0201f800, 0x0010073a, 0x04020019, 0x4a0370e8, + 0x0201f800, 0x001006f4, 0x04020019, 0x4a0370e8, 0x00000003, 0x42000800, 0x0000c000, 0x58042003, 0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff, - 0x0201f800, 0x0010073a, 0x0402000d, 0x4a0378e8, + 0x0201f800, 0x001006f4, 0x0402000d, 0x4a0378e8, 0x00000003, 0x42000800, 0x00008000, 0x58042003, 0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff, - 0x0201f800, 0x0010073a, 0x0400000b, 0x4a03c020, + 0x0201f800, 0x001006f4, 0x0400000b, 0x4a03c020, 0x00004010, 0x4a03c011, 0x40100011, 0x04006000, 0x4203e000, 0x40000000, 0x4203e000, 0x30000001, - 0x0401f000, 0x0201f800, 0x001007d7, 0x42001000, - 0x0010a971, 0x40080000, 0x80140480, 0x82001d00, + 0x0401f000, 0x0201f800, 0x00100791, 0x42001000, + 0x0010ab4a, 0x40080000, 0x80140480, 0x82001d00, 0xffffff00, 0x04020003, 0x40001800, 0x0401f003, 0x42001800, 0x000000ff, 0x480bc840, 0x480fc842, 0x04011000, 0x400c0000, 0x80081400, 0x40140000, 0x80080580, 0x040207f0, 0x4817500d, 0x45782800, 0x59c40000, 0x82000500, 0xffff0000, 0x80000120, - 0x82000580, 0x00002422, 0x04020005, 0x59a8006f, - 0x84000540, 0x4803506f, 0x0401f00a, 0x59e00003, - 0x82000500, 0x00030000, 0x82000580, 0x00010000, - 0x04020004, 0x59a8006f, 0x84000542, 0x4803506f, - 0x42000800, 0x00000040, 0x59a8006f, 0x8c000502, - 0x0402000e, 0x42000800, 0x00001000, 0x82141480, - 0x0017ffff, 0x04021009, 0x80040902, 0x82141480, - 0x0013ffff, 0x04021005, 0x80040902, 0x82141480, - 0x0011ffff, 0x04001bc8, 0x4807500e, 0x42001000, - 0x00000024, 0x0201f800, 0x001063cf, 0x82040c00, - 0x0010cfc0, 0x4807500b, 0x4a03c810, 0x00100000, - 0x4a03c811, 0x0010a971, 0x4a03c829, 0x00000004, - 0x59e40001, 0x82000540, 0x0003001d, 0x4803c801, - 0x4a03c014, 0x001c001c, 0x42001000, 0x0000001c, - 0x0201f800, 0x00100728, 0x4202c000, 0x0010cfc0, - 0x59aab00b, 0x59aaa00b, 0x59aaa80b, 0x59aac80e, - 0x49675069, 0x59a8000b, 0x4803500c, 0x0201f800, - 0x001006a3, 0x0201f800, 0x0010768a, 0x0201f800, - 0x00100804, 0x0201f800, 0x0010084d, 0x0201f800, - 0x00101a60, 0x0201f800, 0x001013a4, 0x0201f800, - 0x001009b6, 0x0201f800, 0x001013a4, 0x0201f800, - 0x00100f9a, 0x0201f800, 0x0010640f, 0x0401fb54, - 0x0201f800, 0x00101fb5, 0x0201f800, 0x0010508b, - 0x0201f800, 0x00104b36, 0x0201f800, 0x00105ecd, - 0x0201f800, 0x00105c61, 0x0201f800, 0x0010143d, - 0x0201f800, 0x001012bf, 0x4203e000, 0xf0000001, - 0x4a035070, 0x00000014, 0x4a035071, 0x0000000b, - 0x4a035072, 0x00000001, 0x4a035073, 0x00000000, - 0x42000000, 0x00001000, 0x50000000, 0x82000480, - 0x24220001, 0x0400004a, 0x59e00002, 0x8c00051e, - 0x42000000, 0x7ffe00fe, 0x04000003, 0x42000000, - 0x7ffe01fe, 0x50000800, 0x48075058, 0x80040920, - 0x82040580, 0x0000013e, 0x0402000b, 0x59a8006f, - 0x84000548, 0x4803506f, 0x4a035070, 0x00000055, - 0x4a035071, 0x00000051, 0x4a035073, 0x0000000f, - 0x0401f033, 0x82040580, 0x0000013f, 0x0402000b, - 0x59a8006f, 0x8400054a, 0x4803506f, 0x4a035070, - 0x00000055, 0x4a035071, 0x00000051, 0x4a035073, - 0x0000000f, 0x0401f026, 0x59e00003, 0x82000500, - 0x00030000, 0x82000580, 0x00000000, 0x04020020, - 0x82040580, 0x00000147, 0x04000010, 0x82040580, - 0x00000145, 0x0402001a, 0x59a8006f, 0x84000546, - 0x4803506f, 0x4a035070, 0x00000033, 0x4a035071, - 0x00000030, 0x4a035072, 0x00000020, 0x4a035073, - 0x00000001, 0x0401f00c, 0x59a8006f, 0x84000544, - 0x4803506f, 0x4a035070, 0x00000033, 0x4a035071, - 0x00000030, 0x4a035072, 0x00000020, 0x4a035073, - 0x00000001, 0x4a0378e4, 0x000c0000, 0x59a8006f, - 0x8c000502, 0x04000004, 0x82000500, 0x00000030, - 0x04000b25, 0x4a03c018, 0x0000000f, 0x4203e000, - 0x20000511, 0x4203e000, 0x50010000, 0x4a03c020, - 0x00000000, 0x04027013, 0x59e00020, 0x82000580, - 0x00000002, 0x0402000f, 0x4a03c020, 0x00004000, - 0x4a03c011, 0x40000010, 0x04006000, 0x4203e000, - 0x40000000, 0x59e00017, 0x8c000508, 0x04000003, - 0x4a03c017, 0x00000000, 0x4203e000, 0x30000001, - 0x4202d800, 0x00000000, 0x4203e000, 0xb0600000, - 0x59a80873, 0x4007f800, 0x0201f000, 0x00020004, - 0x4df00000, 0x4203e000, 0x50000000, 0x416c0000, - 0x82000c80, 0x00000008, 0x04021afb, 0x0c01f804, - 0x5c03e000, 0x0201f000, 0x00020008, 0x00100328, - 0x0010033b, 0x00100411, 0x00100327, 0x0010048c, - 0x00100327, 0x00100327, 0x001005d0, 0x0401faee, - 0x42000800, 0x0010b2a0, 0x5804001d, 0x4803c857, - 0x8c000500, 0x0400000d, 0x84000500, 0x4800081d, - 0x4202d800, 0x00000004, 0x0401fbe8, 0x49f3c857, - 0x5c000800, 0x5c000000, 0x82000540, 0x00003e00, - 0x4c000000, 0x4c040000, 0x1c01f000, 0x0401fbd2, - 0x0201f800, 0x00104e0d, 0x04000010, 0x0201f800, - 0x00104e23, 0x04020035, 0x59940023, 0x82000580, - 0x0010401b, 0x04020004, 0x59940022, 0x800001c0, + 0x82000580, 0x00002422, 0x04020005, 0x59a80005, + 0x8400054e, 0x48035005, 0x0401f008, 0x59e00003, + 0x82000500, 0x00030000, 0x04000004, 0x59a80005, + 0x84000554, 0x48035005, 0x42000800, 0x00000040, + 0x59a80005, 0x8c000514, 0x0402000e, 0x42000800, + 0x00001000, 0x82141480, 0x0017ffff, 0x04021009, + 0x80040902, 0x82141480, 0x0013ffff, 0x04021005, + 0x80040902, 0x82141480, 0x0011ffff, 0x04001b8d, + 0x4807500e, 0x42001000, 0x00000024, 0x0201f800, + 0x00106681, 0x82040c00, 0x0010d1c0, 0x4807500b, + 0x4a03c810, 0x00100000, 0x4a03c811, 0x0010ab4a, + 0x4a03c829, 0x00000004, 0x59e40001, 0x82000540, + 0x0003001d, 0x4803c801, 0x4a03c014, 0x001c001c, + 0x42001000, 0x0000001c, 0x0201f800, 0x001006e2, + 0x4202c000, 0x0010d1c0, 0x59aab00b, 0x59aaa00b, + 0x59aaa80b, 0x59aac80e, 0x49675069, 0x59a8000b, + 0x4803500c, 0x0401fbf5, 0x0201f800, 0x00107903, + 0x0201f800, 0x001007be, 0x0201f800, 0x00100807, + 0x0201f800, 0x00101a05, 0x0201f800, 0x00101354, + 0x0201f800, 0x00100969, 0x0201f800, 0x00101354, + 0x0201f800, 0x00100f4c, 0x0201f800, 0x001066c1, + 0x0401fb1a, 0x0201f800, 0x0010220e, 0x0201f800, + 0x001053bb, 0x0201f800, 0x00104c90, 0x0201f800, + 0x00106194, 0x0201f800, 0x00105f28, 0x0201f800, + 0x001013ed, 0x0201f800, 0x0010126f, 0x4203e000, + 0xf0000001, 0x42000000, 0x00001000, 0x50000000, + 0x82000480, 0x24220001, 0x04000016, 0x59e00002, + 0x8c00051e, 0x42000000, 0x7ffe00fe, 0x04020003, + 0x42000000, 0x7ffe01fe, 0x50000800, 0x48075058, + 0x80040920, 0x82040580, 0x0000013a, 0x04000004, + 0x82040580, 0x0000013b, 0x04020006, 0x59a80005, + 0x84000552, 0x48035005, 0x4a0378e4, 0x000c0000, + 0x4a03c018, 0x0000000f, 0x4203e000, 0x20000511, + 0x4203e000, 0x50010000, 0x4a03c020, 0x00000000, + 0x04027013, 0x59e00020, 0x82000580, 0x00000002, + 0x0402000f, 0x4a03c020, 0x00004000, 0x4a03c011, + 0x40000010, 0x04006000, 0x4203e000, 0x40000000, + 0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017, + 0x00000000, 0x4203e000, 0x30000001, 0x4202d800, + 0x00000000, 0x4203e000, 0xb0600000, 0x59a80005, + 0x42000800, 0x00000002, 0x8c000512, 0x04020007, + 0x42000800, 0x0000000f, 0x8c000514, 0x04020003, + 0x42000800, 0x00000001, 0x4007f800, 0x59a80005, + 0x8c000514, 0x02020000, 0x00020004, 0x59e00003, + 0x82000500, 0x00030000, 0x82000580, 0x00000000, + 0x04020af8, 0x0201f000, 0x00020004, 0x4df00000, + 0x4203e000, 0x50000000, 0x416c0000, 0x82000c80, + 0x00000008, 0x04021aef, 0x0c01f804, 0x5c03e000, + 0x0201f000, 0x00020008, 0x001002f7, 0x0010030a, + 0x001003d7, 0x001002f6, 0x00100452, 0x001002f6, + 0x001002f6, 0x00100593, 0x0401fae2, 0x42000800, + 0x0010b4a4, 0x5804001d, 0x4803c857, 0x8c000500, + 0x0400000d, 0x84000500, 0x4800081d, 0x4202d800, + 0x00000004, 0x0401fbd3, 0x49f3c857, 0x5c000800, + 0x5c000000, 0x82000540, 0x00003e00, 0x4c000000, + 0x4c040000, 0x1c01f000, 0x0401fbbd, 0x0201f800, + 0x0010513b, 0x04000009, 0x0201f800, 0x00105151, 0x0402002e, 0x59c40006, 0x82000540, 0x000000c0, - 0x48038806, 0x0401f029, 0x0201f800, 0x00104d76, - 0x836c0580, 0x00000001, 0x040200be, 0x59a80017, - 0x82000580, 0x00000009, 0x040200ba, 0x497b5010, + 0x48038806, 0x0401f029, 0x0201f800, 0x001050a2, + 0x836c0580, 0x00000001, 0x040200bc, 0x59a80017, + 0x82000580, 0x00000009, 0x040200b8, 0x497b5010, 0x4a038893, 0x00000001, 0x42001000, 0x000000f0, - 0x0201f800, 0x001019aa, 0x0201f800, 0x00104e1b, + 0x0201f800, 0x0010193d, 0x0201f800, 0x00105149, 0x59c41006, 0x04020006, 0x82081540, 0x000000f1, 0x82081500, 0xbbffffff, 0x0401f003, 0x82081540, - 0x440000f1, 0x480b8806, 0x0201f800, 0x00105de2, - 0x0201f800, 0x001069b8, 0x42000000, 0x0010b638, - 0x0201f800, 0x0010a86e, 0x42001000, 0x00008030, - 0x497b5013, 0x0401f037, 0x0201f800, 0x00103951, + 0x440000f1, 0x480b8806, 0x0201f800, 0x0010609e, + 0x4a0378e4, 0x00002000, 0x42000000, 0x0010b83a, + 0x0201f800, 0x0010aa47, 0x42001000, 0x00008030, + 0x497b5013, 0x0401f035, 0x0201f800, 0x00103b38, 0x59c400a4, 0x82000500, 0x0000000f, 0x82000480, - 0x00000007, 0x04021093, 0x0201f800, 0x00105de2, + 0x00000007, 0x04021091, 0x0201f800, 0x0010609e, 0x59c400a3, 0x82000500, 0xffefffff, 0x480388a3, 0x59a8004b, 0x800001c0, 0x04020004, 0x0201f800, - 0x00103f53, 0x0401f087, 0x59a80015, 0x84000546, - 0x48035015, 0x0201f800, 0x00104e13, 0x59c41006, + 0x00104139, 0x0401f085, 0x59a80015, 0x84000546, + 0x48035015, 0x0201f800, 0x00105141, 0x59c41006, 0x04020006, 0x82081540, 0x44000001, 0x82081500, 0xffffff0f, 0x0401f003, 0x82081540, 0x440000f1, 0x480b8806, 0x497b9005, 0x4a038802, 0x0000ffff, - 0x4a0378e4, 0x00003000, 0x4a0378e4, 0x000c0000, - 0x42000000, 0x0010b60a, 0x0201f800, 0x0010a86e, - 0x59a81010, 0x42000800, 0x00000003, 0x0201f800, - 0x001069af, 0x42001000, 0x00008010, 0x59a8180a, - 0x0201f800, 0x00103857, 0x0201f800, 0x00101886, - 0x59a80805, 0x82040d00, 0xffffffdf, 0x48075005, - 0x0201f800, 0x0010468b, 0x0201f800, 0x00104e0d, - 0x0400000a, 0x0201f800, 0x00103f58, 0x04000007, - 0x4a035013, 0x00000001, 0x497b5021, 0x0201f800, - 0x00103a9f, 0x0401f04f, 0x0201f800, 0x0010473b, - 0x04000005, 0x59c41002, 0x8408150c, 0x480b8802, - 0x0401f012, 0x0201f800, 0x00104e0d, 0x04020006, - 0x59a8001d, 0x80000540, 0x02000800, 0x001090d5, - 0x0401f00a, 0x0201f800, 0x001090d5, 0x59a80026, - 0x8c000506, 0x04020005, 0x59a8001d, 0x80000540, - 0x02020800, 0x00104075, 0x497b5028, 0x497b5027, - 0x497b5018, 0x0201f800, 0x00104e0d, 0x59a81026, - 0x0402000a, 0x0201f800, 0x00101694, 0x80001580, - 0x59a8002a, 0x82000500, 0xffff0000, 0x80040d40, - 0x4807502a, 0x0401f005, 0x59a8002a, 0x82000500, - 0xffff0000, 0x4803502a, 0x599c0017, 0x8c00050a, - 0x04000002, 0x84081544, 0x480b5026, 0x0201f800, - 0x00104e0d, 0x04000004, 0x0201f800, 0x00101694, - 0x48078880, 0x42001000, 0x00000005, 0x0201f800, - 0x00106e07, 0x497b5028, 0x497b501b, 0x4a03501c, - 0x0000ffff, 0x4a0378e4, 0x000000c0, 0x4202d800, - 0x00000002, 0x0201f800, 0x00104e0d, 0x04000007, - 0x59a80026, 0x82000500, 0x0000000c, 0x82000580, - 0x00000004, 0x04000003, 0x0201f800, 0x00101bf0, - 0x1c01f000, 0x59a8001c, 0x82000580, 0x0000ffff, - 0x04000004, 0x0201f800, 0x00101bf0, 0x0401f074, - 0x59a80026, 0x8c00050a, 0x04020003, 0x8c000506, - 0x0400001c, 0x8c000500, 0x0400001a, 0x4a038802, - 0x0000ffbf, 0x8c000502, 0x04000016, 0x599c0018, - 0x8c000516, 0x04020010, 0x59a80027, 0x82000580, - 0x0000ffff, 0x0400000c, 0x0201f800, 0x00101d45, - 0x59a80026, 0x8c000504, 0x0402005d, 0x42001000, - 0x00000003, 0x417a5800, 0x0201f800, 0x00101d6a, - 0x0401f057, 0x59a80028, 0x80000540, 0x04020054, - 0x59a80026, 0x8c000508, 0x04020005, 0x59a8001b, - 0x80000540, 0x0402004e, 0x0401f003, 0x8c000516, - 0x0400004b, 0x0201f800, 0x0010473b, 0x04020048, - 0x599c0018, 0x8c000516, 0x04020004, 0x0201f800, - 0x00104abe, 0x04020042, 0x599c0017, 0x8c00050a, - 0x0400000d, 0x4200b000, 0x000007f0, 0x417a8800, - 0x0201f800, 0x00020267, 0x04020004, 0x59340200, - 0x8c00051a, 0x04020036, 0x81468800, 0x8058b040, - 0x040207f8, 0x4a038802, 0x0000ffff, 0x42001800, - 0x0010b2e7, 0x0401fb98, 0x42001800, 0x0010b2f4, - 0x0401fb95, 0x59a80005, 0x84000502, 0x48035005, - 0x4a0378e4, 0x00000080, 0x4202d800, 0x00000003, - 0x4a03501c, 0x0000ffff, 0x0401fa8b, 0x80000580, - 0x0201f800, 0x001015fa, 0x599c0018, 0x8c000516, - 0x04000004, 0x0201f800, 0x00103929, 0x0401f009, - 0x42001800, 0x0000ffff, 0x42002000, 0x00000006, - 0x42003000, 0x00000000, 0x0201f800, 0x001038c7, - 0x0201f800, 0x00104e23, 0x0400000b, 0x59c40006, - 0x0201f800, 0x00104e0d, 0x04000004, 0x82000500, - 0xffffff0f, 0x0401f003, 0x82000500, 0xfbffffff, - 0x48038806, 0x0201f800, 0x00106c8a, 0x1c01f000, - 0x4c040000, 0x4c080000, 0x4c100000, 0x59a8003e, - 0x82000c80, 0x00000004, 0x04021983, 0x0c01f805, - 0x5c002000, 0x5c001000, 0x5c000800, 0x1c01f000, - 0x0010049c, 0x00100527, 0x00100553, 0x001005b4, - 0x42000000, 0x00000001, 0x0201f800, 0x001015fa, - 0x0201f800, 0x00105de2, 0x59c408a3, 0x82040d00, - 0xfffffff7, 0x480788a3, 0x0201f800, 0x00104e13, - 0x0400000e, 0x0201f800, 0x00104e23, 0x0400000b, - 0x0201f800, 0x00104e1b, 0x04020967, 0x59c400a3, - 0x84000532, 0x84000570, 0x480388a3, 0x4a038808, - 0x00000008, 0x0401f013, 0x59c400a3, 0x84000530, - 0x82000500, 0xbf7fffff, 0x480388a3, 0x42000800, - 0x000000f8, 0x0201f800, 0x00104030, 0x59c400a3, - 0x82000540, 0x00018000, 0x8400051c, 0x480388a3, - 0x82000500, 0xfffeffff, 0x480388a3, 0x497b8808, - 0x59c40006, 0x82000500, 0xfbffff0e, 0x48038806, - 0x497b2822, 0x497b2823, 0x42000800, 0x000001f4, - 0x42001000, 0x001005ce, 0x0201f800, 0x00105cbc, - 0x59c40805, 0x42001000, 0x00000001, 0x0201f800, - 0x001019aa, 0x0201f800, 0x001016ac, 0x0402000a, - 0x42000000, 0x00000001, 0x0201f800, 0x001018fa, - 0x42000000, 0x00000001, 0x0201f800, 0x00101892, - 0x0401f022, 0x0201f800, 0x001016b3, 0x04020008, - 0x41780000, 0x0201f800, 0x001018fa, 0x41780000, - 0x0201f800, 0x00101892, 0x0401f018, 0x0201f800, - 0x001016ba, 0x0402000a, 0x42000000, 0x00000002, - 0x0201f800, 0x001018fa, 0x42000000, 0x00000002, - 0x0201f800, 0x00101892, 0x0401f00c, 0x0201f800, - 0x001016c1, 0x04020918, 0x59a80049, 0x800001c0, - 0x04000006, 0x0201f800, 0x001016c7, 0x4a03503e, - 0x00000001, 0x0401f021, 0x0201f800, 0x00101994, - 0x4a03503e, 0x00000001, 0x0201f800, 0x00104e13, - 0x0400000c, 0x0201f800, 0x00104e23, 0x04000009, - 0x0201f800, 0x00104e1b, 0x04020903, 0x4a035033, - 0x00000001, 0x0201f800, 0x00104d76, 0x0401f00f, - 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, - 0x00000008, 0x04000003, 0x4a038805, 0x04000000, - 0x59c400a3, 0x82000540, 0x0001c000, 0x480388a3, - 0x84000520, 0x480388a3, 0x1c01f000, 0x0401f8a3, - 0x04020004, 0x4a03503e, 0x00000003, 0x0401f027, - 0x0201f800, 0x001016c1, 0x04020011, 0x59a80049, - 0x800001c0, 0x0400000e, 0x0201f800, 0x001016c7, - 0x59a80048, 0x8c00051e, 0x0400001c, 0x0201f800, - 0x00104e1b, 0x04020009, 0x4a035033, 0x00000001, - 0x0201f800, 0x00104d76, 0x0401f004, 0x0201f800, - 0x00101941, 0x04020011, 0x0201f800, 0x00101886, - 0x4a03503e, 0x00000002, 0x497b5049, 0x59c400a3, - 0x84000520, 0x480388a3, 0x497b2822, 0x497b2823, - 0x42000800, 0x0000002d, 0x42001000, 0x001005ce, - 0x0201f800, 0x00105cbc, 0x1c01f000, 0x0401f877, - 0x04020004, 0x4a03503e, 0x00000003, 0x0401f05b, - 0x4a038805, 0x000000f0, 0x0201f800, 0x00101941, - 0x04020050, 0x0201f800, 0x00104e1b, 0x04000044, - 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, - 0x00000008, 0x04000020, 0x59c40005, 0x8c000534, - 0x0402001d, 0x59940022, 0x82000580, 0x00000001, - 0x04020046, 0x0201f800, 0x00104e23, 0x04020043, - 0x4a038805, 0x000000f0, 0x0201f800, 0x00104e67, - 0x4a035032, 0x0000aaaa, 0x4a035033, 0x00000000, - 0x59c408a3, 0x82040d40, 0x00000008, 0x480788a3, - 0x4202d800, 0x00000001, 0x4a03503e, 0x00000000, - 0x4a038805, 0x00000001, 0x497b2822, 0x497b2823, - 0x0401f01f, 0x0201f800, 0x00104e23, 0x04020007, - 0x59a80032, 0x82000580, 0x0000aaaa, 0x04020003, - 0x4a035010, 0x00ffffff, 0x497b5032, 0x59c40006, - 0x82000540, 0x04000001, 0x48038806, 0x59a80805, - 0x8c040d06, 0x04020005, 0x59c408a3, 0x82040d40, - 0x00000008, 0x480788a3, 0x4202d800, 0x00000001, - 0x4a03503e, 0x00000000, 0x4a038805, 0x00000001, - 0x497b2822, 0x497b2823, 0x0401f010, 0x59c40005, - 0x82000500, 0x000000c0, 0x0400000c, 0x59c40006, - 0x82000540, 0x000000f1, 0x48038806, 0x0401f7ef, - 0x0201f800, 0x001016c1, 0x04020004, 0x59a80049, - 0x800001c0, 0x040207a4, 0x497b8885, 0x1c01f000, - 0x4803c856, 0x42000000, 0x00000001, 0x0201f800, - 0x001015fa, 0x4a03503e, 0x00000000, 0x0201f800, - 0x001016c1, 0x0402000b, 0x59a80052, 0x800001c0, - 0x04000004, 0x80000040, 0x48035052, 0x04020005, - 0x4a035052, 0x0000000a, 0x4a035049, 0x00000001, - 0x497b8885, 0x0401f0f6, 0x59940022, 0x59940823, - 0x80040540, 0x1c01f000, 0x497b2823, 0x1c01f000, - 0x4c080000, 0x42001000, 0x000000f0, 0x0201f800, - 0x001019aa, 0x5c001000, 0x1c01f000, 0x4a03505c, - 0x00000004, 0x4a03505d, 0x00000000, 0x4a03505e, - 0x00000012, 0x4a03505f, 0x00000002, 0x4a035010, - 0x00ffffff, 0x0201f800, 0x001090d5, 0x4a03502a, - 0x20200000, 0x4a03502b, 0x88000200, 0x4a03502c, - 0x00ff001f, 0x4a03502d, 0x000007d0, 0x4a03502e, - 0x80000000, 0x4a03502f, 0x00000200, 0x4a035030, - 0x00ff0000, 0x4a035031, 0x00010000, 0x4a03503a, - 0x514c4f47, 0x4a03503b, 0x49432020, 0x1c01f000, - 0x4d440000, 0x417a8800, 0x41780800, 0x0201f800, - 0x00020267, 0x04020005, 0x0201f800, 0x00104836, - 0x04020002, 0x80040800, 0x81468800, 0x83440580, - 0x000007f0, 0x040207f6, 0x5c028800, 0x1c01f000, - 0x4803c857, 0x5c000000, 0x4c000000, 0x4803c857, - 0x0401f809, 0x485fc857, 0x4203e000, 0x50000000, - 0x5c000000, 0x4d780000, 0x4200b800, 0x00008002, - 0x0401f006, 0x485fc857, 0x4203e000, 0x50000000, - 0x4200b800, 0x00008002, 0x04006000, 0x4c000000, - 0x4c040000, 0x59bc00ea, 0x82000500, 0x00000007, - 0x82000580, 0x00000001, 0x04020005, 0x42000800, - 0x00000000, 0x0201f800, 0x001069a3, 0x5c000800, - 0x4807c025, 0x80040920, 0x4807c026, 0x5c000000, - 0x4803c023, 0x80000120, 0x4803c024, 0x5c000000, - 0x4803c857, 0x4803c021, 0x80000120, 0x4803c022, - 0x41f80000, 0x4803c027, 0x80000120, 0x4803c028, - 0x42000000, 0x00001000, 0x50000000, 0x82000480, - 0x24320001, 0x4803c857, 0x04001053, 0x42000800, - 0x00000064, 0x80040840, 0x04000007, 0x4a030000, - 0x00000001, 0x40000000, 0x59800000, 0x8c000500, - 0x040007f9, 0x04000046, 0x42000800, 0x0010bfa2, - 0x46000800, 0xfaceface, 0x80040800, 0x4c080000, - 0x4c0c0000, 0x42001000, 0x00007a00, 0x58080013, - 0x44000800, 0x80040800, 0x58080019, 0x44000800, - 0x80040800, 0x5808001a, 0x44000800, 0x80040800, - 0x5808001b, 0x44000800, 0x80040800, 0x5808001c, - 0x44000800, 0x80040800, 0x5808001f, 0x44000800, - 0x80040800, 0x42001000, 0x00007a40, 0x42001800, - 0x0000000b, 0x50080000, 0x44000800, 0x80081000, - 0x80040800, 0x800c1840, 0x040207fb, 0x42001800, - 0x00000003, 0x42001000, 0x00007b00, 0x480c1003, - 0x58080005, 0x44000800, 0x80040800, 0x800c1840, - 0x040217fb, 0x42001000, 0x00007c00, 0x58080002, - 0x44000800, 0x80040800, 0x58080003, 0x44000800, - 0x80040800, 0x58080020, 0x44000800, 0x80040800, - 0x58080021, 0x44000800, 0x80040800, 0x58080022, - 0x44000800, 0x80040800, 0x58080023, 0x44000800, - 0x80040800, 0x5c001800, 0x5c001000, 0x4a030000, - 0x00000000, 0x485fc020, 0x905cb9c0, 0x825cbd40, - 0x00000012, 0x485fc011, 0x4203e000, 0x40000000, - 0x4202d800, 0x00000005, 0x59e00017, 0x8c000508, - 0x04000003, 0x4a03c017, 0x00000002, 0x4203e000, - 0x30000001, 0x0401f81f, 0x0401f7ff, 0x4a03c850, - 0x0010bfbe, 0x4a03c851, 0x0010cfbd, 0x4a03c853, - 0x00000800, 0x4a03c855, 0x0001eb5a, 0x59e40001, - 0x82000540, 0x00003f00, 0x4803c801, 0x4a03b104, - 0x70000002, 0x4a03a804, 0x70000002, 0x4a03b004, - 0x70000002, 0x42000000, 0x0010b6eb, 0x49780001, - 0x49780002, 0x1c01f000, 0x5c036000, 0x4db00000, - 0x49b3c857, 0x4803c857, 0x1c01f000, 0x1c01f000, - 0x59a8006b, 0x8c000530, 0x040207fe, 0x4c080000, - 0x42001000, 0x00000004, 0x0401f862, 0x5c001000, - 0x4201d000, 0x00028b0a, 0x0201f800, 0x00105dd2, - 0x4c080000, 0x42001000, 0x00000008, 0x0401f859, - 0x5c001000, 0x4201d000, 0x00028b0a, 0x0201f800, - 0x00105dd2, 0x4c080000, 0x42001000, 0x00000010, - 0x0401f850, 0x5c001000, 0x4201d000, 0x00028b0a, - 0x0201f800, 0x00105dd2, 0x0401f7e2, 0x8c00050c, - 0x59a8086b, 0x04020003, 0x84040d30, 0x0401f006, - 0x84040d70, 0x4807506b, 0x42001000, 0x00000000, - 0x0401f040, 0x4807506b, 0x836c0500, 0x00000007, - 0x0c01f001, 0x00100727, 0x0010070d, 0x0010070d, - 0x001006f5, 0x0010071a, 0x0010070d, 0x0010070d, - 0x0010071a, 0x59a8006f, 0x8c000502, 0x04020013, - 0x59c40801, 0x82040d00, 0x00018000, 0x82040580, - 0x00010000, 0x0400000a, 0x82040580, 0x00008000, - 0x04000004, 0x42001000, 0x42004000, 0x0401f006, - 0x42001000, 0x22002000, 0x0401f003, 0x42001000, - 0x12001000, 0x0401f025, 0x42001000, 0x00001004, - 0x0401f022, 0x59a8006f, 0x8c000502, 0x04020008, - 0x59a8006b, 0x8c000534, 0x04020004, 0x42001000, - 0x74057005, 0x0401f819, 0x1c01f000, 0x42001000, - 0x00002008, 0x0401f7fc, 0x59a8006b, 0x8c000534, - 0x0402000a, 0x59a8006f, 0x8c000502, 0x04000004, - 0x42001000, 0x24052005, 0x0401f00c, 0x42001000, - 0x74057005, 0x0401f009, 0x1c01f000, 0x1c01f000, - 0x82081500, 0x0000001c, 0x82081540, 0x001c0000, - 0x480bc013, 0x1c01f000, 0x59a8006b, 0x8c000530, - 0x04000002, 0x84081570, 0x480b506b, 0x8c000530, - 0x04020005, 0x82081500, 0x00007000, 0x80081114, - 0x0401fff0, 0x1c01f000, 0x41780000, 0x50041800, - 0x800c0400, 0x80040800, 0x80102040, 0x040207fc, - 0x80080500, 0x80000540, 0x1c01f000, 0x4202f000, - 0x00000000, 0x41780000, 0x41780800, 0x41781000, - 0x41781800, 0x41782000, 0x41782800, 0x41783000, - 0x41783800, 0x41784000, 0x41784800, 0x41785000, - 0x41785800, 0x41786000, 0x41786800, 0x41787000, - 0x41787800, 0x41788000, 0x41788800, 0x41789000, - 0x41789800, 0x4178a000, 0x4178a800, 0x4178b000, - 0x4178b800, 0x4178c000, 0x4178c800, 0x4178d000, - 0x4178d800, 0x4178e000, 0x4178e800, 0x4178f000, - 0x4178f800, 0x41790000, 0x41790800, 0x41791000, - 0x41791800, 0x41792000, 0x41792800, 0x41793000, - 0x41793800, 0x41794000, 0x41794800, 0x41795000, - 0x41795800, 0x41796000, 0x41796800, 0x41797000, - 0x41797800, 0x41798000, 0x41798800, 0x42019000, - 0x0010b333, 0x42019800, 0x0010b30a, 0x4179a000, - 0x4179a800, 0x4179b000, 0x4179b800, 0x4179c800, - 0x4179c000, 0x4179d000, 0x4179d800, 0x4179e000, - 0x4179e800, 0x4179f000, 0x4179f800, 0x417a0000, - 0x417a0800, 0x417a1000, 0x417a1800, 0x417a2000, - 0x42022800, 0x00006100, 0x417a3000, 0x417a3800, - 0x417a4000, 0x417a4800, 0x417a5000, 0x417a5800, - 0x417a6000, 0x417a6800, 0x417a7000, 0x417a7800, - 0x417a8000, 0x417a8800, 0x417a9000, 0x417a9800, - 0x417ae800, 0x417af800, 0x42030000, 0x00007c00, - 0x42031000, 0x0010b604, 0x42031800, 0x0000bf1d, - 0x42032000, 0x0000bf32, 0x42032800, 0x0010b5cc, - 0x42033000, 0x0010b274, 0x42034000, 0x0010b2a0, - 0x42033800, 0x0010b2bf, 0x42034800, 0x0010b342, - 0x42035000, 0x0010b200, 0x42035800, 0x0010aa00, - 0x42030800, 0x0010b301, 0x417b6000, 0x42036800, - 0x00006f00, 0x4203c800, 0x00003000, 0x42037000, - 0x0000ff00, 0x42037800, 0x0000bf00, 0x42038000, - 0x00007700, 0x42038800, 0x00004000, 0x42039000, - 0x00006000, 0x42039800, 0x0010bcda, 0x4203a000, - 0x00007600, 0x4203a800, 0x00007400, 0x4203b000, - 0x00007200, 0x4203b800, 0x00007100, 0x4203c000, - 0x00007000, 0x4203d000, 0x00000000, 0x4203e800, - 0x000200f9, 0x417bd800, 0x1c01f000, 0x42000800, - 0x00100000, 0x50040000, 0x4c000000, 0x42000000, - 0x0000aaaa, 0x44000800, 0x42001800, 0x00005555, - 0x41782000, 0x82102400, 0x00010000, 0x40100000, - 0x80042c00, 0x440c2800, 0x42003000, 0x0000000a, - 0x80183040, 0x040207ff, 0x50140000, 0x800c0580, - 0x04020004, 0x50040000, 0x800c0580, 0x040207f2, - 0x5c000000, 0x44000800, 0x80142840, 0x4817c861, - 0x1c01f000, 0x59a8081f, 0x800409c0, 0x04020009, - 0x49781c0c, 0x4a001a0c, 0x00000200, 0x4a001804, - 0x07000000, 0x59a80010, 0x9c0001c0, 0x48001805, - 0x0401fdf8, 0x9c0409c0, 0x48041806, 0x1c01f000, - 0x59a8080c, 0x4006d000, 0x4202b800, 0x00000001, - 0x59a8180d, 0x480fc857, 0x82041400, 0x00000014, - 0x82082400, 0x00000014, 0x40100000, 0x800c0480, - 0x04001006, 0x44080800, 0x40080800, 0x40101000, - 0x815eb800, 0x0401f7f7, 0x45780800, 0x495f5020, - 0x1c01f000, 0x835c0480, 0x00000020, 0x04001009, - 0x496bc857, 0x815eb840, 0x416a5800, 0x592ed000, - 0x497a5800, 0x497a5801, 0x812e59c0, 0x1c01f000, - 0x42000000, 0x0010b652, 0x0201f800, 0x0010a86e, - 0x417a5800, 0x0401f7f9, 0x815eb840, 0x04001008, - 0x416a5800, 0x492fc857, 0x592ed000, 0x497a5800, - 0x497a5801, 0x812e59c0, 0x1c01f000, 0x42000000, - 0x0010b652, 0x0201f800, 0x0010a86e, 0x417ab800, - 0x417a5800, 0x0401f7f8, 0x492fc857, 0x496a5800, - 0x412ed000, 0x815eb800, 0x59c80000, 0x82000540, - 0x00001200, 0x48039000, 0x1c01f000, 0x492fc857, - 0x812e59c0, 0x04000007, 0x592c0001, 0x497a5801, - 0x4c000000, 0x0401fff1, 0x5c025800, 0x0401f7f9, - 0x1c01f000, 0x4807c856, 0x42007000, 0x0010b5f6, - 0x4a007001, 0x00000000, 0x59e00003, 0x82000540, - 0x00008080, 0x4803c003, 0x4a03b805, 0x90000001, - 0x59dc0006, 0x4a03b805, 0x70000000, 0x59dc0006, - 0x4a03b805, 0x30000000, 0x59dc0006, 0x4a03b805, - 0x80000000, 0x4200b000, 0x00000020, 0x497bb807, - 0x8058b040, 0x040207fe, 0x4a03b805, 0x30000000, - 0x59dc0006, 0x4a03b805, 0x60000001, 0x59dc0006, - 0x4a03b805, 0x70000001, 0x59dc0006, 0x4a03b805, - 0x30000002, 0x4200b000, 0x00000020, 0x497bb807, - 0x8058b040, 0x040207fe, 0x4a03b805, 0x30000000, - 0x59dc0006, 0x4a03b805, 0x60000001, 0x0401ff9e, - 0x04000d99, 0x42001000, 0x0010b5f4, 0x452c1000, - 0x4a025801, 0x00000001, 0x4a025802, 0x00000100, - 0x4a025809, 0x00106eac, 0x497a580a, 0x497a580b, - 0x497a580c, 0x0401ff90, 0x04000d8b, 0x42001000, - 0x0010b5f5, 0x452c1000, 0x4a025801, 0x00000000, - 0x4a025802, 0x00000100, 0x4a025809, 0x0010120c, - 0x497a5803, 0x497a5807, 0x497a5808, 0x497a580a, - 0x59a8006f, 0x8c000500, 0x04000006, 0x4a03b805, - 0xe0000001, 0x59dc0006, 0x8c000522, 0x040007fc, - 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, - 0x4c380000, 0x40087000, 0x4a007002, 0x00000000, - 0x42007000, 0x0010b5f6, 0x82080400, 0x00000000, + 0x4a0378e4, 0x00003000, 0x42000000, 0x0010b80c, + 0x0201f800, 0x0010aa47, 0x59a81010, 0x42000800, + 0x00000003, 0x0201f800, 0x00106c78, 0x42001000, + 0x00008010, 0x59a8180a, 0x0201f800, 0x00103a3e, + 0x0201f800, 0x00101815, 0x59a80805, 0x82040d00, + 0xffffffdf, 0x48075005, 0x0201f800, 0x0010483d, + 0x0201f800, 0x0010513b, 0x0400000a, 0x0201f800, + 0x0010413e, 0x04000007, 0x4a035013, 0x00000001, + 0x497b5021, 0x0201f800, 0x00103c80, 0x0401f04f, + 0x0201f800, 0x001048ec, 0x04000005, 0x59c41002, + 0x8408150c, 0x480b8802, 0x0401f012, 0x0201f800, + 0x0010513b, 0x04020006, 0x59a8001d, 0x80000540, + 0x02000800, 0x0010930f, 0x0401f00a, 0x0201f800, + 0x0010930f, 0x59a80026, 0x8c000506, 0x04020005, + 0x59a8001d, 0x80000540, 0x02020800, 0x00104245, + 0x497b5028, 0x497b5027, 0x497b5018, 0x0201f800, + 0x0010513b, 0x59a81026, 0x0402000a, 0x0201f800, + 0x0010162a, 0x80001580, 0x59a8002a, 0x82000500, + 0xffff0000, 0x80040d40, 0x4807502a, 0x0401f005, + 0x59a8002a, 0x82000500, 0xffff0000, 0x4803502a, + 0x599c0017, 0x8c00050a, 0x04000002, 0x84081544, + 0x480b5026, 0x0201f800, 0x0010513b, 0x04000004, + 0x0201f800, 0x0010162a, 0x48078880, 0x42001000, + 0x00000005, 0x0201f800, 0x001070b0, 0x497b5028, + 0x497b501b, 0x4a03501c, 0x0000ffff, 0x4a0378e4, + 0x000000c0, 0x4202d800, 0x00000002, 0x0201f800, + 0x0010513b, 0x04000007, 0x59a80026, 0x82000500, + 0x0000000c, 0x82000580, 0x00000004, 0x04000003, + 0x0201f800, 0x00101e45, 0x1c01f000, 0x59a8001c, + 0x82000580, 0x0000ffff, 0x04000004, 0x0201f800, + 0x00101e45, 0x0401f074, 0x59a80026, 0x8c00050a, + 0x04020003, 0x8c000506, 0x0400001c, 0x8c000500, + 0x0400001a, 0x4a038802, 0x0000ffbf, 0x8c000502, + 0x04000016, 0x599c0018, 0x8c000516, 0x04020010, + 0x59a80027, 0x82000580, 0x0000ffff, 0x0400000c, + 0x0201f800, 0x00101f9a, 0x59a80026, 0x8c000504, + 0x0402005d, 0x42001000, 0x00000003, 0x417a5800, + 0x0201f800, 0x00101fbf, 0x0401f057, 0x59a80028, + 0x80000540, 0x04020054, 0x59a80026, 0x8c000508, + 0x04020005, 0x59a8001b, 0x80000540, 0x0402004e, + 0x0401f003, 0x8c000516, 0x0400004b, 0x0201f800, + 0x001048ec, 0x04020048, 0x599c0018, 0x8c000516, + 0x04020004, 0x0201f800, 0x00104c51, 0x04020042, + 0x599c0017, 0x8c00050a, 0x0400000d, 0x4200b000, + 0x000007f0, 0x417a8800, 0x0201f800, 0x00020245, + 0x04020004, 0x59340200, 0x8c00051a, 0x04020036, + 0x81468800, 0x8058b040, 0x040207f8, 0x4a038802, + 0x0000ffff, 0x42001800, 0x0010b4eb, 0x0401fb8c, + 0x42001800, 0x0010b4f8, 0x0401fb89, 0x59a80005, + 0x84000502, 0x48035005, 0x4a0378e4, 0x00000080, + 0x4202d800, 0x00000003, 0x4a03501c, 0x0000ffff, + 0x0401fa7f, 0x80000580, 0x0201f800, 0x00101590, + 0x599c0018, 0x8c000516, 0x04000004, 0x0201f800, + 0x00103b10, 0x0401f009, 0x42001800, 0x0000ffff, + 0x42002000, 0x00000006, 0x42003000, 0x00000000, + 0x0201f800, 0x00103aae, 0x0201f800, 0x00105151, + 0x0400000b, 0x59c40006, 0x0201f800, 0x0010513b, + 0x04000004, 0x82000500, 0xffffff0f, 0x0401f003, + 0x82000500, 0xfbffffff, 0x48038806, 0x0201f800, + 0x00106f36, 0x1c01f000, 0x4c040000, 0x4c080000, + 0x4c100000, 0x59a8003e, 0x82000c80, 0x00000004, + 0x04021980, 0x0c01f805, 0x5c002000, 0x5c001000, + 0x5c000800, 0x1c01f000, 0x00100462, 0x001004ea, + 0x00100516, 0x00100577, 0x42000000, 0x00000001, + 0x0201f800, 0x00101590, 0x0201f800, 0x0010609e, + 0x59c408a3, 0x82040d00, 0xfffffff7, 0x480788a3, + 0x0201f800, 0x00105141, 0x0400000e, 0x0201f800, + 0x00105151, 0x0400000b, 0x0201f800, 0x00105149, + 0x04020964, 0x59c400a3, 0x84000532, 0x84000570, + 0x480388a3, 0x4a038808, 0x00000008, 0x0401f010, + 0x59c400a3, 0x84000530, 0x82000500, 0xbf7fffff, + 0x480388a3, 0x42000800, 0x000000f8, 0x0201f800, + 0x00104200, 0x59c400a3, 0x82000540, 0x00018000, + 0x8400051c, 0x480388a3, 0x497b8808, 0x59c40006, + 0x82000500, 0xfbffff0e, 0x48038806, 0x497b2822, + 0x497b2823, 0x42000800, 0x000001f4, 0x42001000, + 0x00100591, 0x0201f800, 0x00105f83, 0x59c40805, + 0x42001000, 0x00000001, 0x0201f800, 0x0010193d, + 0x0201f800, 0x0010163b, 0x0402000a, 0x42000000, + 0x00000001, 0x0201f800, 0x0010188c, 0x42000000, + 0x00000001, 0x0201f800, 0x00101821, 0x0401f022, + 0x0201f800, 0x00101642, 0x04020008, 0x41780000, + 0x0201f800, 0x0010188c, 0x41780000, 0x0201f800, + 0x00101821, 0x0401f018, 0x0201f800, 0x00101649, + 0x0402000a, 0x42000000, 0x00000002, 0x0201f800, + 0x0010188c, 0x42000000, 0x00000002, 0x0201f800, + 0x00101821, 0x0401f00c, 0x0201f800, 0x00101650, + 0x04020918, 0x59a80049, 0x800001c0, 0x04000006, + 0x0201f800, 0x00101656, 0x4a03503e, 0x00000001, + 0x0401f021, 0x0201f800, 0x00101927, 0x4a03503e, + 0x00000001, 0x0201f800, 0x00105141, 0x0400000c, + 0x0201f800, 0x00105151, 0x04000009, 0x0201f800, + 0x00105149, 0x04020903, 0x4a035033, 0x00000001, + 0x0201f800, 0x001050a2, 0x0401f00f, 0x59c400a4, + 0x82000500, 0x0000000f, 0x82000580, 0x00000008, + 0x04000003, 0x4a038805, 0x04000000, 0x59c400a3, + 0x82000540, 0x0001c000, 0x480388a3, 0x84000520, + 0x480388a3, 0x1c01f000, 0x0401f8a3, 0x04020004, + 0x4a03503e, 0x00000003, 0x0401f027, 0x0201f800, + 0x00101650, 0x04020011, 0x59a80049, 0x800001c0, + 0x0400000e, 0x0201f800, 0x00101656, 0x59a80048, + 0x8c00051e, 0x0400001c, 0x0201f800, 0x00105149, + 0x04020009, 0x4a035033, 0x00000001, 0x0201f800, + 0x001050a2, 0x0401f004, 0x0201f800, 0x001018d3, + 0x04020011, 0x0201f800, 0x00101815, 0x4a03503e, + 0x00000002, 0x497b5049, 0x59c400a3, 0x84000520, + 0x480388a3, 0x497b2822, 0x497b2823, 0x42000800, + 0x0000002d, 0x42001000, 0x00100591, 0x0201f800, + 0x00105f83, 0x1c01f000, 0x0401f877, 0x04020004, + 0x4a03503e, 0x00000003, 0x0401f05b, 0x4a038805, + 0x000000f0, 0x0201f800, 0x001018d3, 0x04020050, + 0x0201f800, 0x00105149, 0x04000044, 0x59c400a4, + 0x82000500, 0x0000000f, 0x82000580, 0x00000008, + 0x04000020, 0x59c40005, 0x8c000534, 0x0402001d, + 0x59940022, 0x82000580, 0x00000001, 0x04020046, + 0x0201f800, 0x00105151, 0x04020043, 0x4a038805, + 0x000000f0, 0x0201f800, 0x00105196, 0x4a035032, + 0x0000aaaa, 0x4a035033, 0x00000000, 0x59c408a3, + 0x82040d40, 0x00000008, 0x480788a3, 0x4202d800, + 0x00000001, 0x4a03503e, 0x00000000, 0x4a038805, + 0x00000001, 0x497b2822, 0x497b2823, 0x0401f01f, + 0x0201f800, 0x00105151, 0x04020007, 0x59a80032, + 0x82000580, 0x0000aaaa, 0x04020003, 0x4a035010, + 0x00ffffff, 0x497b5032, 0x59c40006, 0x82000540, + 0x04000001, 0x48038806, 0x59a80805, 0x8c040d06, + 0x04020005, 0x59c408a3, 0x82040d40, 0x00000008, + 0x480788a3, 0x4202d800, 0x00000001, 0x4a03503e, + 0x00000000, 0x4a038805, 0x00000001, 0x497b2822, + 0x497b2823, 0x0401f010, 0x59c40005, 0x82000500, + 0x000000c0, 0x0400000c, 0x59c40006, 0x82000540, + 0x000000f1, 0x48038806, 0x0401f7ef, 0x0201f800, + 0x00101650, 0x04020004, 0x59a80049, 0x800001c0, + 0x040207a4, 0x497b8885, 0x1c01f000, 0x4803c856, + 0x42000000, 0x00000001, 0x0201f800, 0x00101590, + 0x4a03503e, 0x00000000, 0x0201f800, 0x00101650, + 0x0402000b, 0x59a80052, 0x800001c0, 0x04000004, + 0x80000040, 0x48035052, 0x04020005, 0x4a035052, + 0x0000000a, 0x4a035049, 0x00000001, 0x497b8885, + 0x0401f0ed, 0x59940022, 0x59940823, 0x80040540, + 0x1c01f000, 0x497b2823, 0x1c01f000, 0x4c080000, + 0x42001000, 0x000000f0, 0x0201f800, 0x0010193d, + 0x5c001000, 0x1c01f000, 0x4a03505c, 0x00000004, + 0x4a03505d, 0x00000000, 0x4a03505e, 0x00000010, + 0x4a03505f, 0x00000002, 0x4a035010, 0x00ffffff, + 0x0201f800, 0x0010930f, 0x4a03502a, 0x20200000, + 0x4a03502b, 0x88000200, 0x4a03502c, 0x00ff001f, + 0x4a03502d, 0x000007d0, 0x4a03502e, 0x80000000, + 0x4a03502f, 0x00000200, 0x4a035030, 0x00ff0000, + 0x4a035031, 0x00010000, 0x4a03503a, 0x514c4f47, + 0x4a03503b, 0x49432020, 0x1c01f000, 0x4d440000, + 0x417a8800, 0x41780800, 0x0201f800, 0x00020245, + 0x04020005, 0x0201f800, 0x001049e7, 0x04020002, + 0x80040800, 0x81468800, 0x83440580, 0x000007f0, + 0x040207f6, 0x5c028800, 0x1c01f000, 0x4803c857, + 0x5c000000, 0x4c000000, 0x4803c857, 0x0401f809, + 0x485fc857, 0x4203e000, 0x50000000, 0x5c000000, + 0x4d780000, 0x4200b800, 0x00008002, 0x0401f006, + 0x485fc857, 0x4203e000, 0x50000000, 0x4200b800, + 0x00008002, 0x04006000, 0x4c000000, 0x4c040000, + 0x59bc00ea, 0x82000500, 0x00000007, 0x82000580, + 0x00000001, 0x04020005, 0x42000800, 0x00000000, + 0x0201f800, 0x00106c6c, 0x5c000800, 0x4807c025, + 0x80040920, 0x4807c026, 0x5c000000, 0x4803c023, + 0x80000120, 0x4803c024, 0x5c000000, 0x4803c857, + 0x4803c021, 0x80000120, 0x4803c022, 0x41f80000, + 0x4803c027, 0x80000120, 0x4803c028, 0x42000000, + 0x00001000, 0x50000000, 0x82000480, 0x24320001, + 0x4803c857, 0x0400104f, 0x42000800, 0x00000064, + 0x80040840, 0x04000007, 0x4a030000, 0x00000001, + 0x40000000, 0x59800000, 0x8c000500, 0x040007f9, + 0x04000042, 0x42000800, 0x0010c1a3, 0x46000800, + 0xfaceface, 0x80040800, 0x42001000, 0x00007a00, + 0x58080013, 0x44000800, 0x80040800, 0x58080019, + 0x44000800, 0x80040800, 0x5808001a, 0x44000800, + 0x80040800, 0x5808001b, 0x44000800, 0x80040800, + 0x5808001c, 0x44000800, 0x80040800, 0x5808001f, + 0x44000800, 0x80040800, 0x42001000, 0x00007a40, + 0x42001800, 0x0000000b, 0x50080000, 0x44000800, + 0x80081000, 0x80040800, 0x800c1840, 0x040207fb, + 0x42001800, 0x00000003, 0x42001000, 0x00007b00, + 0x480c1003, 0x58080005, 0x44000800, 0x80040800, + 0x800c1840, 0x040217fb, 0x42001000, 0x00007c00, + 0x58080002, 0x44000800, 0x80040800, 0x58080003, + 0x44000800, 0x80040800, 0x58080020, 0x44000800, + 0x80040800, 0x58080021, 0x44000800, 0x80040800, + 0x58080022, 0x44000800, 0x80040800, 0x58080023, + 0x44000800, 0x80040800, 0x4a030000, 0x00000000, + 0x485fc020, 0x905cb9c0, 0x825cbd40, 0x00000012, + 0x485fc011, 0x4203e000, 0x40000000, 0x4202d800, + 0x00000005, 0x59e00017, 0x8c000508, 0x04000003, + 0x4a03c017, 0x00000002, 0x4203e000, 0x30000001, + 0x0401f81a, 0x0401f7ff, 0x4a03c850, 0x0010c1bf, + 0x4a03c851, 0x0010d1be, 0x4a03c853, 0x00000800, + 0x4a03c855, 0x0001eb5a, 0x59e40001, 0x82000540, + 0x00003f00, 0x4803c801, 0x4a03b104, 0x70000002, + 0x4a03a804, 0x70000002, 0x4a03b004, 0x70000002, + 0x42000000, 0x0010b8ec, 0x49780001, 0x49780002, + 0x1c01f000, 0x1c01f000, 0x59a8006b, 0x8c000530, + 0x040207fe, 0x4c080000, 0x42001000, 0x00000004, + 0x0401f862, 0x5c001000, 0x4201d000, 0x00028b0a, + 0x0201f800, 0x0010608e, 0x4c080000, 0x42001000, + 0x00000008, 0x0401f859, 0x5c001000, 0x4201d000, + 0x00028b0a, 0x0201f800, 0x0010608e, 0x4c080000, + 0x42001000, 0x00000010, 0x0401f850, 0x5c001000, + 0x4201d000, 0x00028b0a, 0x0201f800, 0x0010608e, + 0x0401f7e2, 0x8c00050c, 0x59a8086b, 0x04020003, + 0x84040d30, 0x0401f006, 0x84040d70, 0x4807506b, + 0x42001000, 0x00000000, 0x0401f040, 0x4807506b, + 0x836c0500, 0x00000007, 0x0c01f001, 0x001006e1, + 0x001006c7, 0x001006c7, 0x001006af, 0x001006d4, + 0x001006c7, 0x001006c7, 0x001006d4, 0x59a80005, + 0x8c000514, 0x04020013, 0x59c40801, 0x82040d00, + 0x00018000, 0x82040580, 0x00010000, 0x0400000a, + 0x82040580, 0x00008000, 0x04000004, 0x42001000, + 0x42004000, 0x0401f006, 0x42001000, 0x22002000, + 0x0401f003, 0x42001000, 0x12001000, 0x0401f025, + 0x42001000, 0x00001004, 0x0401f022, 0x59a80005, + 0x8c000514, 0x04020008, 0x59a8006b, 0x8c000534, + 0x04020004, 0x42001000, 0x74057005, 0x0401f819, + 0x1c01f000, 0x42001000, 0x00002008, 0x0401f7fc, + 0x59a8006b, 0x8c000534, 0x0402000a, 0x59a80005, + 0x8c000514, 0x04000004, 0x42001000, 0x24052005, + 0x0401f00c, 0x42001000, 0x74057005, 0x0401f009, + 0x1c01f000, 0x1c01f000, 0x82081500, 0x0000001c, + 0x82081540, 0x001c0000, 0x480bc013, 0x1c01f000, + 0x59a8006b, 0x8c000530, 0x04000002, 0x84081570, + 0x480b506b, 0x8c000530, 0x04020005, 0x82081500, + 0x00007000, 0x80081114, 0x0401fff0, 0x1c01f000, + 0x41780000, 0x50041800, 0x800c0400, 0x80040800, + 0x80102040, 0x040207fc, 0x80080500, 0x80000540, + 0x1c01f000, 0x4202f000, 0x00000000, 0x41780000, + 0x41780800, 0x41781000, 0x41781800, 0x41782000, + 0x41782800, 0x41783000, 0x41783800, 0x41784000, + 0x41784800, 0x41785000, 0x41785800, 0x41786000, + 0x41786800, 0x41787000, 0x41787800, 0x41788000, + 0x41788800, 0x41789000, 0x41789800, 0x4178a000, + 0x4178a800, 0x4178b000, 0x4178b800, 0x4178c000, + 0x4178c800, 0x4178d000, 0x4178d800, 0x4178e000, + 0x4178e800, 0x4178f000, 0x4178f800, 0x41790000, + 0x41790800, 0x41791000, 0x41791800, 0x41792000, + 0x41792800, 0x41793000, 0x41793800, 0x41794000, + 0x41794800, 0x41795000, 0x41795800, 0x41796000, + 0x41796800, 0x41797000, 0x41797800, 0x41798000, + 0x41798800, 0x42019000, 0x0010b537, 0x42019800, + 0x0010b50e, 0x4179a000, 0x4179b000, 0x4179a800, + 0x4179b800, 0x4179c800, 0x4179c000, 0x4179d000, + 0x4179d800, 0x4179e000, 0x4179e800, 0x4179f000, + 0x4179f800, 0x417a0000, 0x417a0800, 0x417a1000, + 0x417a1800, 0x417a2000, 0x42022800, 0x00006100, + 0x417a3000, 0x417a3800, 0x417a4000, 0x417a4800, + 0x417a5000, 0x417a5800, 0x417a6000, 0x417a6800, + 0x417a7000, 0x417a7800, 0x417a8000, 0x417a8800, + 0x417a9000, 0x417a9800, 0x417ae800, 0x417af800, + 0x42030000, 0x00007c00, 0x42031000, 0x0010b806, + 0x42031800, 0x0000bf1d, 0x42032000, 0x0000bf32, + 0x42032800, 0x0010b7ce, 0x42033000, 0x0010b46e, + 0x42034000, 0x0010b4a4, 0x42033800, 0x0010b4c3, + 0x42034800, 0x0010b544, 0x42035000, 0x0010b400, + 0x42035800, 0x0010ac00, 0x42030800, 0x0010b505, + 0x417b6000, 0x42036800, 0x00006f00, 0x4203c800, + 0x00003000, 0x42037000, 0x0000ff00, 0x42037800, + 0x0000bf00, 0x42038000, 0x00007700, 0x42038800, + 0x00004000, 0x42039000, 0x00006000, 0x42039800, + 0x0010bedb, 0x4203a000, 0x00007600, 0x4203a800, + 0x00007400, 0x4203b000, 0x00007200, 0x4203b800, + 0x00007100, 0x4203c000, 0x00007000, 0x4203d000, + 0x00000000, 0x4203e800, 0x00101b95, 0x417bd800, + 0x1c01f000, 0x42000800, 0x00100000, 0x50040000, + 0x4c000000, 0x42000000, 0x0000aaaa, 0x44000800, + 0x42001800, 0x00005555, 0x41782000, 0x82102400, + 0x00010000, 0x40100000, 0x80042c00, 0x440c2800, + 0x42003000, 0x0000000a, 0x80183040, 0x040207ff, + 0x50140000, 0x800c0580, 0x04020004, 0x50040000, + 0x800c0580, 0x040207f2, 0x5c000000, 0x44000800, + 0x80142840, 0x4817c861, 0x1c01f000, 0x59a8081f, + 0x800409c0, 0x04020009, 0x49781c0c, 0x4a001a0c, + 0x00000200, 0x4a001804, 0x07000000, 0x59a80010, + 0x9c0001c0, 0x48001805, 0x0401fe01, 0x9c0409c0, + 0x48041806, 0x1c01f000, 0x59a8080c, 0x4006d000, + 0x4202b800, 0x00000001, 0x59a8180d, 0x480fc857, + 0x82041400, 0x00000014, 0x82082400, 0x00000014, + 0x40100000, 0x800c0480, 0x04001006, 0x44080800, + 0x40080800, 0x40101000, 0x815eb800, 0x0401f7f7, + 0x45780800, 0x495f5020, 0x1c01f000, 0x835c0480, + 0x00000020, 0x04001009, 0x496bc857, 0x815eb840, + 0x416a5800, 0x592ed000, 0x497a5800, 0x497a5801, + 0x812e59c0, 0x1c01f000, 0x42000000, 0x0010b853, + 0x0201f800, 0x0010aa47, 0x417a5800, 0x0401f7f9, + 0x815eb840, 0x04001008, 0x416a5800, 0x492fc857, + 0x592ed000, 0x497a5800, 0x497a5801, 0x812e59c0, + 0x1c01f000, 0x42000000, 0x0010b853, 0x0201f800, + 0x0010aa47, 0x417ab800, 0x417a5800, 0x0401f7f8, + 0x492fc857, 0x496a5800, 0x412ed000, 0x815eb800, + 0x59c80000, 0x82000540, 0x00001200, 0x48039000, + 0x1c01f000, 0x492fc857, 0x812e59c0, 0x04000007, + 0x592c0001, 0x497a5801, 0x4c000000, 0x0401fff1, + 0x5c025800, 0x0401f7f9, 0x1c01f000, 0x4807c856, + 0x42007000, 0x0010b7f8, 0x4a007001, 0x00000000, + 0x59e00003, 0x82000540, 0x00008080, 0x4803c003, + 0x4a03b805, 0x90000001, 0x59dc0006, 0x4a03b805, + 0x70000000, 0x59dc0006, 0x4a03b805, 0x30000000, + 0x4200b000, 0x00000020, 0x497bb807, 0x8058b040, + 0x040207fe, 0x4a03b805, 0x30000000, 0x59dc0006, + 0x4a03b805, 0x60000001, 0x59dc0006, 0x4a03b805, + 0x70000001, 0x59dc0006, 0x4a03b805, 0x30000002, + 0x4200b000, 0x00000020, 0x497bb807, 0x8058b040, + 0x040207fe, 0x4a03b805, 0x30000000, 0x59dc0006, + 0x4a03b805, 0x60000001, 0x0401ffa1, 0x04000da5, + 0x42001000, 0x0010b7f6, 0x452c1000, 0x4a025801, + 0x00000001, 0x4a025802, 0x00000100, 0x4a025809, + 0x00107149, 0x497a580a, 0x497a580b, 0x497a580c, + 0x0401ff93, 0x04000d97, 0x42001000, 0x0010b7f7, + 0x452c1000, 0x4a025801, 0x00000000, 0x4a025802, + 0x00000100, 0x4a025809, 0x001011bc, 0x497a5803, + 0x497a5807, 0x497a5808, 0x497a580a, 0x59a80005, + 0x8c00050e, 0x04000006, 0x4a03b805, 0xe0000001, + 0x59dc0006, 0x8c000522, 0x040007fc, 0x1c01f000, + 0x4df00000, 0x4203e000, 0x50000000, 0x4c380000, + 0x40087000, 0x480bc857, 0x4a007002, 0x00000000, + 0x42007000, 0x0010b7f8, 0x82080400, 0x00000000, 0x45780000, 0x58380005, 0x48087005, 0x80000540, - 0x04000006, 0x480bc857, 0x82000400, 0x00000000, - 0x44080000, 0x0401f003, 0x480bc857, 0x48087006, - 0x58380001, 0x80000540, 0x0400080c, 0x5c007000, - 0x5c03e000, 0x1c01f000, 0x4c380000, 0x42007000, - 0x0010b5f6, 0x58380001, 0x80000540, 0x04000803, - 0x5c007000, 0x1c01f000, 0x42007000, 0x0010b5f6, - 0x58380001, 0x82000580, 0x00000000, 0x04020012, - 0x58380000, 0x0c01f001, 0x001008d7, 0x001008d6, - 0x001008d6, 0x001008d6, 0x001008d6, 0x001008d6, - 0x001008d6, 0x001008d6, 0x0401fd3f, 0x58380808, - 0x800409c0, 0x04020027, 0x58380006, 0x80000540, - 0x04020002, 0x1c01f000, 0x4803c857, 0x48007002, - 0x40006800, 0x58340000, 0x80000540, 0x04020002, - 0x48007005, 0x48007006, 0x4a03b805, 0x20000000, - 0x59dc0006, 0x4a03b805, 0x30000000, 0x58340007, - 0x4803b800, 0x4803c857, 0x58340008, 0x4803b801, - 0x4803c857, 0x58340004, 0x48007003, 0x58340003, - 0x48007004, 0x4803b803, 0x4803c857, 0x58340001, + 0x04000005, 0x82000400, 0x00000000, 0x44080000, + 0x0401f003, 0x480bc857, 0x48087006, 0x58380001, + 0x80000540, 0x0400080c, 0x5c007000, 0x5c03e000, + 0x1c01f000, 0x4c380000, 0x42007000, 0x0010b7f8, + 0x58380001, 0x80000540, 0x04000803, 0x5c007000, + 0x1c01f000, 0x42007000, 0x0010b7f8, 0x58380001, + 0x82000580, 0x00000000, 0x04020012, 0x58380000, + 0x0c01f001, 0x0010088e, 0x0010088d, 0x0010088d, + 0x0010088d, 0x0010088d, 0x0010088d, 0x0010088d, + 0x0010088d, 0x0401fd4b, 0x58380808, 0x800409c0, + 0x04020024, 0x58380006, 0x80000540, 0x04020002, + 0x1c01f000, 0x4803c857, 0x48007002, 0x40006800, + 0x58340000, 0x80000540, 0x04020002, 0x48007005, + 0x48007006, 0x4a03b805, 0x20000000, 0x59dc0006, + 0x4a03b805, 0x30000000, 0x58340007, 0x4803b800, + 0x58340008, 0x4803b801, 0x58340004, 0x48007003, + 0x58340003, 0x48007004, 0x4803b803, 0x58340001, 0x8c000500, 0x04000004, 0x4a007001, 0x00000001, - 0x0401f028, 0x4a007001, 0x00000002, 0x0401f03e, - 0x0201f800, 0x001091b3, 0x0201f800, 0x0010a4b8, + 0x0401f028, 0x4a007001, 0x00000002, 0x0401f03d, + 0x0201f800, 0x001093ea, 0x0201f800, 0x0010a69d, 0x04000017, 0x4a03b805, 0x20000000, 0x59dc0006, 0x4a03b805, 0x30000000, 0x4807b800, 0x480bb801, 0x4a007003, 0x00000010, 0x480c7009, 0x42001000, - 0x001008be, 0x0201f800, 0x00105cd3, 0x58380008, + 0x00100875, 0x0201f800, 0x00105f9a, 0x58380008, 0x82000400, 0x00000004, 0x48007004, 0x4803b803, - 0x4a007001, 0x00000007, 0x0401f023, 0x0201f800, - 0x001091cb, 0x42000800, 0x00000001, 0x42001000, - 0x001008be, 0x0201f800, 0x00105caf, 0x0401f7b7, + 0x4a007001, 0x00000007, 0x0401f022, 0x0201f800, + 0x00109402, 0x42000800, 0x00000001, 0x42001000, + 0x00100875, 0x0201f800, 0x00105f76, 0x0401f7ba, 0x4c040000, 0x4c080000, 0x58380803, 0x42001000, 0x00003fff, 0x82040480, 0x00003fff, 0x04021003, - 0x40041000, 0x80000580, 0x48007003, 0x4803c857, - 0x800800c4, 0x4803b802, 0x4a03b805, 0x30000002, - 0x59dc0006, 0x4a03b805, 0x70000001, 0x59dc0006, - 0x4a03b805, 0x10000000, 0x5c001000, 0x5c000800, - 0x1c01f000, 0x483bc857, 0x4c040000, 0x4c080000, - 0x58380803, 0x42001000, 0x00003fff, 0x82040480, - 0x00003fff, 0x04021003, 0x40041000, 0x80000580, - 0x48007003, 0x800800c4, 0x4803b802, 0x4803c857, - 0x4a03b805, 0x10000002, 0x5c001000, 0x5c000800, - 0x1c01f000, 0x4c040000, 0x4c380000, 0x42007000, - 0x0010b5f6, 0x59dc0806, 0x4807c857, 0x4a03b805, - 0x20000000, 0x8c040d3e, 0x04000007, 0x8c040d08, - 0x04020cb9, 0x58380001, 0x82000500, 0x00000007, - 0x0c01f804, 0x5c007000, 0x5c000800, 0x1c01f000, - 0x001008c6, 0x0010096c, 0x0010097c, 0x00100615, - 0x00100615, 0x00100615, 0x00100615, 0x0010123a, - 0x4807c856, 0x82040d00, 0x43000f80, 0x04020009, - 0x58380003, 0x80000540, 0x0400001c, 0x59dc0000, - 0x4803b800, 0x59dc0001, 0x4803b801, 0x0401f7ad, - 0x58380802, 0x4a000802, 0x00000200, 0x0401f01d, - 0x4807c856, 0x82040d00, 0x43000f80, 0x04020009, - 0x58380003, 0x80000540, 0x0400000c, 0x59dc0000, - 0x4803b800, 0x59dc0001, 0x4803b801, 0x0401f7b6, - 0x58380002, 0x82000400, 0x00000002, 0x46000000, - 0x00000200, 0x0401f00b, 0x4c340000, 0x58386802, - 0x59dc0000, 0x4803c857, 0x48006807, 0x59dc0001, - 0x48006808, 0x4a006802, 0x00000100, 0x5c006800, - 0x4a007001, 0x00000000, 0x4c300000, 0x58386002, - 0x4833c857, 0x0401f80c, 0x04000009, 0x58300009, - 0x82000c80, 0x0010a971, 0x04021c73, 0x82000c80, - 0x00020000, 0x04001c70, 0x0801f800, 0x5c006000, - 0x0401f71e, 0x803061c0, 0x04000009, 0x59a8000c, - 0x80300480, 0x04001007, 0x59a8000d, 0x80300480, - 0x04021004, 0x82000540, 0x00000001, 0x1c01f000, - 0x80000580, 0x1c01f000, 0x4803c856, 0x4dc00000, - 0x42007000, 0x0010b601, 0x4a007400, 0x00000000, - 0x49787001, 0x42038000, 0x00007720, 0x4a038006, - 0x60000001, 0x4a038009, 0xf4f60000, 0x42038000, - 0x00007700, 0x4a038006, 0x60000001, 0x4a038009, - 0xf4f60000, 0x4a03c822, 0x00000010, 0x4a0370e8, - 0x00000000, 0x0401f809, 0x4a0370e9, 0x00003a0f, - 0x4a0370e8, 0x00000000, 0x4a0370e8, 0x00000001, - 0x5c038000, 0x1c01f000, 0x4c5c0000, 0x4178b800, - 0x0401f80a, 0x5c00b800, 0x1c01f000, 0x4803c856, - 0x4c5c0000, 0x825cbd40, 0x00000001, 0x0401f803, - 0x5c00b800, 0x1c01f000, 0x4803c856, 0x4dc00000, - 0x4c500000, 0x4c580000, 0x4c540000, 0x4a0370e8, - 0x00000000, 0x805cb9c0, 0x04000009, 0x4a038807, - 0x00000004, 0x59b800ea, 0x8c000510, 0x04000004, - 0x59b800e0, 0x0401f87b, 0x0401f7fb, 0x42038000, - 0x00007720, 0x0201f800, 0x00100f0f, 0x59c00007, - 0x4a038006, 0x20000000, 0x59c00007, 0x4a038006, - 0x8000000a, 0x59c00007, 0x4a038006, 0x8000000b, - 0x59c00007, 0x4a038006, 0x40000001, 0x83c00580, - 0x00007700, 0x04000004, 0x42038000, 0x00007700, - 0x0401f7ed, 0x42038000, 0x00007720, 0x42000800, - 0x00000800, 0x59c00007, 0x8c00051e, 0x04000006, - 0x4a038006, 0x90000001, 0x80040840, 0x040207fa, - 0x0401fc01, 0x83c00580, 0x00007700, 0x04000004, - 0x42038000, 0x00007700, 0x0401f7f1, 0x805cb9c0, - 0x0402001d, 0x4200b000, 0x00000020, 0x83b8ac00, - 0x00000020, 0x0201f800, 0x0010a947, 0x4a0370fb, - 0x00000001, 0x4a037020, 0x0010110d, 0x59a80039, - 0x82000500, 0x0000ffff, 0x48037021, 0x4a037035, - 0x0010bbda, 0x4a037030, 0x0010b210, 0x4a037031, - 0x0010aa00, 0x4a037032, 0x0010b315, 0x4a037036, - 0x0010b320, 0x59840002, 0x48037034, 0x4a037038, - 0x00101104, 0x4a0370fb, 0x00000001, 0x4178a000, - 0x4200b000, 0x00000020, 0x83b8ac00, 0x00000000, - 0x0201f800, 0x0010a947, 0x4200b000, 0x00000040, - 0x83b8ac00, 0x00000040, 0x0201f800, 0x0010a947, - 0x805cb9c0, 0x04020004, 0x4a0370e4, 0xaaaaaaaa, - 0x0401f003, 0x4a0370e4, 0xa2aaaa82, 0x4a0370e5, - 0xaaaaaaaa, 0x4a0370e6, 0xaaaaaaaa, 0x4a0370fb, - 0x00000000, 0x4a0370e6, 0xaaaaaaaa, 0x42038000, - 0x00007720, 0x4a038006, 0x90000000, 0x59c00007, - 0x8c00051e, 0x02020800, 0x00100615, 0x42038000, - 0x00007700, 0x4a038006, 0x90000000, 0x59c00007, - 0x8c00051e, 0x02020800, 0x00100615, 0x5c00a800, - 0x5c00b000, 0x5c00a000, 0x5c038000, 0x1c01f000, - 0x4d300000, 0x4d380000, 0x40026000, 0x82000500, - 0x7f000000, 0x82000580, 0x00000003, 0x0402000f, - 0x83326500, 0x00ffffff, 0x59300203, 0x82000580, - 0x00000004, 0x04020009, 0x59300c06, 0x82040580, - 0x00000009, 0x04020005, 0x42027000, 0x00000047, - 0x0201f800, 0x000208d8, 0x5c027000, 0x5c026000, - 0x1c01f000, 0x4d300000, 0x4d2c0000, 0x4d340000, - 0x4d400000, 0x4cfc0000, 0x4d380000, 0x4d3c0000, - 0x4d440000, 0x4d4c0000, 0x4d480000, 0x4c5c0000, - 0x4c600000, 0x4c640000, 0x4d040000, 0x4cc80000, - 0x4ccc0000, 0x4cf40000, 0x4cf80000, 0x4cfc0000, - 0x0201f800, 0x00020016, 0x5c01f800, 0x5c01f000, - 0x5c01e800, 0x5c019800, 0x5c019000, 0x5c020800, - 0x5c00c800, 0x5c00c000, 0x5c00b800, 0x5c029000, - 0x5c029800, 0x5c028800, 0x5c027800, 0x5c027000, - 0x5c01f800, 0x5c028000, 0x5c026800, 0x5c025800, - 0x5c026000, 0x1c01f000, 0x493bc857, 0x0201f000, - 0x00020045, 0x83300500, 0x1f000000, 0x04000008, - 0x81326580, 0x80000130, 0x82000c80, 0x00000014, - 0x02021800, 0x00100615, 0x0c01f013, 0x83300500, - 0x000000ff, 0x82000c80, 0x00000007, 0x02021800, - 0x00100615, 0x0c01f025, 0x1c01f000, 0x82000d00, - 0xc0000038, 0x02020800, 0x0010060d, 0x0201f800, - 0x00100615, 0x00000000, 0x00000048, 0x00000054, - 0x00000053, 0x00100ae4, 0x00100b08, 0x00100b03, - 0x00100b28, 0x00100aef, 0x00100afb, 0x00100ae4, - 0x00100b23, 0x00100b64, 0x00100ae4, 0x00100ae4, - 0x00100ae4, 0x00100ae4, 0x00100b67, 0x00100b6d, - 0x00100b7e, 0x00100b8f, 0x00100ae4, 0x00100b98, - 0x00100ba4, 0x00100ae4, 0x00100ae4, 0x00100ae4, - 0x0201f800, 0x00100615, 0x00100aed, 0x00100c3f, - 0x00100b35, 0x00100b59, 0x00100aed, 0x00100aed, - 0x00100aed, 0x0201f800, 0x00100615, 0x4803c856, - 0x59300004, 0x8c00053e, 0x04020005, 0x42027000, - 0x00000055, 0x0201f000, 0x000208d8, 0x0201f800, - 0x00106cb4, 0x040007fa, 0x1c01f000, 0x4803c856, - 0x0401f8aa, 0x40002800, 0x41782000, 0x42027000, - 0x00000056, 0x0201f000, 0x000208d8, 0x4803c856, - 0x42027000, 0x00000057, 0x0201f000, 0x000208d8, - 0x4803c856, 0x59300007, 0x8c00051a, 0x04020010, - 0x59325808, 0x812e59c0, 0x04000014, 0x592c0408, - 0x8c00051c, 0x04020003, 0x4a026011, 0xffffffff, - 0x59300004, 0x8c00053e, 0x04020009, 0x42027000, - 0x00000048, 0x0201f000, 0x000208d8, 0x59325808, - 0x4a025a06, 0x00000007, 0x0401f7f4, 0x0201f800, - 0x00106cb4, 0x040007f6, 0x1c01f000, 0x4803c856, - 0x83300500, 0x00ffffff, 0x0201f000, 0x0010620f, - 0x1c01f000, 0x4c040000, 0x59b808ea, 0x82040d00, - 0x00000007, 0x82040580, 0x00000003, 0x04000004, - 0x42000000, 0x60000000, 0x0401f8ac, 0x5c000800, - 0x1c01f000, 0x0401f8fa, 0x0400001b, 0x59325808, - 0x812e59c0, 0x04000018, 0x592c0204, 0x82000500, - 0x000000ff, 0x82000d80, 0x00000029, 0x04020012, - 0x59300203, 0x82000580, 0x00000003, 0x0400000b, - 0x59300807, 0x84040d26, 0x48066007, 0x0201f800, - 0x00020087, 0x4a03900d, 0x00000040, 0x4a0370e5, - 0x00000008, 0x1c01f000, 0x0201f800, 0x00106cb4, - 0x040007f4, 0x59880053, 0x80000000, 0x48031053, - 0x4a03900d, 0x00000040, 0x42000000, 0xc0000000, - 0x0401f05a, 0x42007800, 0x0010bbe1, 0x42002000, - 0x00003000, 0x42003000, 0x00000105, 0x0201f800, - 0x00105b3d, 0x4a0370e4, 0x02000000, 0x1c01f000, - 0x4933c857, 0x0201f000, 0x000208b4, 0x41300800, - 0x800409c0, 0x02020800, 0x00100615, 0x0201f800, - 0x0010060d, 0x4933c857, 0x813261c0, 0x02000800, - 0x00100615, 0x0401f835, 0x40002800, 0x0201f800, - 0x0010a7c3, 0x0401f8ae, 0x04000007, 0x59326809, - 0x59340200, 0x8c00050e, 0x59300414, 0x02020800, - 0x00109094, 0x1c01f000, 0x4933c857, 0x813261c0, - 0x02000800, 0x00100615, 0x0401f8a1, 0x0400000b, - 0x59325808, 0x0201f800, 0x00108df4, 0x04000007, - 0x592c0208, 0x8400054e, 0x48025a08, 0x417a7800, - 0x0201f800, 0x00108997, 0x1c01f000, 0x485fc857, - 0x5c000000, 0x4d780000, 0x4203e000, 0x50000000, - 0x4200b800, 0x00008005, 0x0201f000, 0x0010061a, - 0x4933c857, 0x83300480, 0x00000020, 0x02021800, - 0x00100615, 0x83300c00, 0x0010b6cb, 0x50040000, - 0x80000000, 0x04001002, 0x44000800, 0x1c01f000, - 0x4933c857, 0x0401f7f4, 0x4807c856, 0x59b800ea, - 0x8c000510, 0x040007fd, 0x59b800e0, 0x4803c857, - 0x1c01f000, 0x4803c856, 0x42000000, 0x10000000, - 0x41300800, 0x0401f02d, 0x82000500, 0xf0000000, - 0x82040d00, 0x0fffffff, 0x80040d40, 0x4807c857, - 0x59b800ea, 0x8c000516, 0x04020003, 0x480770e1, - 0x1c01f000, 0x8c000510, 0x040007fa, 0x4c040000, - 0x0401f809, 0x5c000800, 0x82100480, 0x00000008, - 0x040017f4, 0x4c040000, 0x0401febf, 0x5c000800, - 0x0401f7f0, 0x59b800e2, 0x59b820e2, 0x80100580, - 0x040207fd, 0x80102114, 0x0401f006, 0x59b800e2, - 0x59b820e2, 0x80100580, 0x040207fd, 0x0401f001, - 0x40101800, 0x800c190a, 0x82100500, 0x0000001f, - 0x820c1d00, 0x0000001f, 0x800c2480, 0x82102500, - 0x0000001f, 0x1c01f000, 0x82000500, 0xf0000000, - 0x82040d00, 0x0fffffff, 0x80040d40, 0x4807c857, - 0x42001000, 0x0010b602, 0x50080000, 0x80000540, - 0x04020005, 0x4a0370e5, 0x00000003, 0x4a0370e4, - 0x00000300, 0x80000000, 0x44001000, 0x42001000, - 0x00000400, 0x59b800ea, 0x8c000510, 0x0400000c, - 0x0401ffd5, 0x82100480, 0x00000008, 0x04001007, - 0x4c040000, 0x4c080000, 0x0401fe8b, 0x5c001000, - 0x5c000800, 0x0401f020, 0x59b800ea, 0x8c000516, - 0x0402001d, 0x4a0370e4, 0x00300000, 0x480770e1, - 0x42001000, 0x0000ff00, 0x80081040, 0x04000012, - 0x59b808e4, 0x8c040d28, 0x040207fc, 0x42001000, - 0x0010b602, 0x50080000, 0x80000040, 0x04020005, - 0x4a0370e5, 0x00000002, 0x4a0370e4, 0x00000200, - 0x02001800, 0x00100615, 0x44001000, 0x8c040d2c, - 0x1c01f000, 0x41f80000, 0x50000000, 0x0201f800, - 0x00100615, 0x80081040, 0x040207d3, 0x41f80000, - 0x50000000, 0x0201f800, 0x00100615, 0x4d380000, - 0x59300c06, 0x82040580, 0x00000009, 0x04020006, - 0x42027000, 0x00000047, 0x0201f800, 0x000208d8, - 0x80000580, 0x5c027000, 0x1c01f000, 0x4c500000, - 0x4a03900d, 0x00000001, 0x59c8a020, 0x4a03900d, - 0x00000002, 0x59c80820, 0x8c50a52e, 0x04000002, - 0x900409c0, 0x82040d00, 0x0000ffff, 0x0201f800, - 0x00105b0f, 0x5c00a000, 0x1c01f000, 0x0401fff0, - 0x04000045, 0x4933c857, 0x59300406, 0x82000580, - 0x00000000, 0x04000040, 0x59c82021, 0x4a03900d, - 0x00000001, 0x59c82821, 0x82142d00, 0x0000ffff, - 0x59325808, 0x812e59c0, 0x04000037, 0x59326809, - 0x0201f800, 0x00104728, 0x02020800, 0x0010907c, - 0x599c0019, 0x8c00050c, 0x04020018, 0x0201f800, - 0x00104728, 0x04020015, 0x59300811, 0x4807c857, - 0x592c0408, 0x8c00051c, 0x0402000e, 0x8400055c, - 0x48025c08, 0x592c0a04, 0x82040d00, 0x000000ff, - 0x82040580, 0x00000048, 0x04000004, 0x82040580, - 0x00000018, 0x04020003, 0x59300811, 0x48065803, - 0x4a026011, 0x7fffffff, 0x48166013, 0x0201f800, - 0x0010112d, 0x04020014, 0x0401fa07, 0x40280000, - 0x4802600d, 0x04000005, 0x4832600b, 0x50200000, - 0x4802600a, 0x4822600c, 0x59300414, 0x8c00051c, - 0x04020004, 0x599c0019, 0x8c00050c, 0x0402086e, - 0x4a03900d, 0x00000040, 0x4a0370e5, 0x00000008, - 0x1c01f000, 0x59880053, 0x80000000, 0x48031053, - 0x4a03900d, 0x00000040, 0x42000000, 0xc0000000, - 0x0401f726, 0x4cf80000, 0x58f40000, 0x8001f540, - 0x0401f820, 0x41781800, 0x0401f8e7, 0x04020014, - 0x44140800, 0x0401f82a, 0x04000011, 0x40043800, - 0x42001800, 0x00000001, 0x40142000, 0x0401f8de, - 0x0402000b, 0x801c3800, 0x501c0000, 0x44000800, - 0x0401f810, 0x801c0580, 0x04000004, 0x44103800, - 0x801c3840, 0x44143800, 0x0401f819, 0x5c01f000, - 0x1c01f000, 0x80f9f1c0, 0x04020003, 0x58f41202, - 0x0401f003, 0x42001000, 0x00000007, 0x1c01f000, - 0x80f9f1c0, 0x04020006, 0x58f40401, 0x82000480, - 0x00000002, 0x80f40400, 0x0401f005, 0x58f80401, - 0x82000480, 0x00000002, 0x80f80400, 0x50002800, - 0x80000000, 0x50002000, 0x1c01f000, 0x80f9f1c0, - 0x04020008, 0x58f40401, 0x82000480, 0x00000002, - 0x02001800, 0x00100615, 0x4801ec01, 0x0401f00b, - 0x58f80401, 0x82000480, 0x00000002, 0x02001800, - 0x00100615, 0x4801f401, 0x82000580, 0x00000002, - 0x04020002, 0x0401f809, 0x58f40202, 0x80000040, - 0x4801ea02, 0x02000800, 0x00100615, 0x82000580, - 0x00000001, 0x1c01f000, 0x4d2c0000, 0x40fa5800, - 0x0201f800, 0x0010083a, 0x4979e800, 0x4179f000, - 0x5c025800, 0x1c01f000, 0x80f5e9c0, 0x04000009, - 0x80f9f1c0, 0x04020ff5, 0x4d2c0000, 0x40f65800, - 0x0201f800, 0x0010083a, 0x4179e800, 0x5c025800, - 0x1c01f000, 0x4cf40000, 0x0201f800, 0x00104728, - 0x04020036, 0x59300807, 0x82040500, 0x00003100, + 0x40041000, 0x80000580, 0x48007003, 0x800800c4, + 0x4803b802, 0x4a03b805, 0x30000002, 0x59dc0006, + 0x4a03b805, 0x70000001, 0x59dc0006, 0x4a03b805, + 0x10000000, 0x5c001000, 0x5c000800, 0x1c01f000, + 0x483bc857, 0x4c040000, 0x4c080000, 0x58380803, + 0x42001000, 0x00003fff, 0x82040480, 0x00003fff, + 0x04021003, 0x40041000, 0x80000580, 0x48007003, + 0x800800c4, 0x4803b802, 0x4a03b805, 0x10000002, + 0x5c001000, 0x5c000800, 0x1c01f000, 0x4c040000, + 0x4c380000, 0x42007000, 0x0010b7f8, 0x59dc0806, + 0x4807c857, 0x4a03b805, 0x20000000, 0x8c040d3e, + 0x04000007, 0x8c040d08, 0x04020cca, 0x58380001, + 0x82000500, 0x00000007, 0x0c01f804, 0x5c007000, + 0x5c000800, 0x1c01f000, 0x0010087d, 0x0010091e, + 0x0010092e, 0x001005d8, 0x001005d8, 0x001005d8, + 0x001005d8, 0x001011ea, 0x4807c856, 0x82040d00, + 0x43000f80, 0x04020009, 0x58380003, 0x80000540, + 0x0400001c, 0x59dc0000, 0x4803b800, 0x59dc0001, + 0x4803b801, 0x0401f7af, 0x58380802, 0x4a000802, + 0x00000200, 0x0401f01e, 0x4807c856, 0x82040d00, + 0x43000f80, 0x04020009, 0x58380003, 0x80000540, + 0x0400000c, 0x59dc0000, 0x4803b800, 0x59dc0001, + 0x4803b801, 0x0401f7b7, 0x58380002, 0x82000400, + 0x00000002, 0x46000000, 0x00000200, 0x0401f00c, + 0x4c340000, 0x58386802, 0x59dc0000, 0x4803c857, + 0x48006807, 0x59dc0001, 0x4803c857, 0x48006808, + 0x4a006802, 0x00000100, 0x5c006800, 0x4a007001, + 0x00000000, 0x4c300000, 0x58386002, 0x0401f80c, + 0x04000009, 0x58300009, 0x82000c80, 0x0010ab4a, + 0x04021c84, 0x82000c80, 0x00020000, 0x04001c81, + 0x0801f800, 0x5c006000, 0x0401f723, 0x4833c857, + 0x803061c0, 0x04000009, 0x59a8000c, 0x80300480, + 0x04001007, 0x59a8000d, 0x80300480, 0x04021004, + 0x82000540, 0x00000001, 0x1c01f000, 0x80000580, + 0x1c01f000, 0x4803c856, 0x4dc00000, 0x42007000, + 0x0010b803, 0x4a007400, 0x00000000, 0x49787001, + 0x42038000, 0x00007720, 0x4a038006, 0x60000001, + 0x4a038009, 0xf4f60000, 0x42038000, 0x00007700, + 0x4a038006, 0x60000001, 0x4a038009, 0xf4f60000, + 0x4a03c822, 0x00000010, 0x4a0370e8, 0x00000000, + 0x0401f809, 0x4a0370e9, 0x00003a0f, 0x4a0370e8, + 0x00000000, 0x4a0370e8, 0x00000001, 0x5c038000, + 0x1c01f000, 0x4c5c0000, 0x4178b800, 0x0401f80a, + 0x5c00b800, 0x1c01f000, 0x4803c856, 0x4c5c0000, + 0x825cbd40, 0x00000001, 0x0401f803, 0x5c00b800, + 0x1c01f000, 0x4803c856, 0x4dc00000, 0x4c500000, + 0x4c580000, 0x4c540000, 0x4a0370e8, 0x00000000, + 0x805cb9c0, 0x04000009, 0x4a038807, 0x00000004, + 0x59b800ea, 0x8c000510, 0x04000004, 0x59b800e0, + 0x0401f87b, 0x0401f7fb, 0x42038000, 0x00007720, + 0x0201f800, 0x00100ec1, 0x59c00007, 0x4a038006, + 0x20000000, 0x59c00007, 0x4a038006, 0x8000000a, + 0x59c00007, 0x4a038006, 0x8000000b, 0x59c00007, + 0x4a038006, 0x40000001, 0x83c00580, 0x00007700, + 0x04000004, 0x42038000, 0x00007700, 0x0401f7ed, + 0x42038000, 0x00007720, 0x42000800, 0x00000800, + 0x59c00007, 0x8c00051e, 0x04000006, 0x4a038006, + 0x90000001, 0x80040840, 0x040207fa, 0x0401fc11, + 0x83c00580, 0x00007700, 0x04000004, 0x42038000, + 0x00007700, 0x0401f7f1, 0x805cb9c0, 0x0402001d, + 0x4200b000, 0x00000020, 0x83b8ac00, 0x00000020, + 0x0201f800, 0x0010ab20, 0x4a0370fb, 0x00000001, + 0x4a037020, 0x001010bd, 0x59a80039, 0x82000500, + 0x0000ffff, 0x48037021, 0x4a037035, 0x0010bddb, + 0x4a037030, 0x0010b410, 0x4a037031, 0x0010ac00, + 0x4a037032, 0x0010b519, 0x4a037036, 0x0010b524, + 0x59840002, 0x48037034, 0x4a037038, 0x001010b4, + 0x4a0370fb, 0x00000001, 0x4178a000, 0x4200b000, + 0x00000020, 0x83b8ac00, 0x00000000, 0x0201f800, + 0x0010ab20, 0x4200b000, 0x00000040, 0x83b8ac00, + 0x00000040, 0x0201f800, 0x0010ab20, 0x805cb9c0, + 0x04020004, 0x4a0370e4, 0xaaaaaaaa, 0x0401f003, + 0x4a0370e4, 0xa2aaaa82, 0x4a0370e5, 0xaaaaaaaa, + 0x4a0370e6, 0xaaaaaaaa, 0x4a0370fb, 0x00000000, + 0x4a0370e6, 0xaaaaaaaa, 0x42038000, 0x00007720, + 0x4a038006, 0x90000000, 0x59c00007, 0x8c00051e, + 0x02020800, 0x001005d8, 0x42038000, 0x00007700, + 0x4a038006, 0x90000000, 0x59c00007, 0x8c00051e, + 0x02020800, 0x001005d8, 0x5c00a800, 0x5c00b000, + 0x5c00a000, 0x5c038000, 0x1c01f000, 0x4d300000, + 0x4d380000, 0x40026000, 0x82000500, 0x7f000000, + 0x82000580, 0x00000003, 0x0402000f, 0x83326500, + 0x00ffffff, 0x59300203, 0x82000580, 0x00000004, + 0x04020009, 0x59300c06, 0x82040580, 0x00000009, + 0x04020005, 0x42027000, 0x00000047, 0x0201f800, + 0x000207a1, 0x5c027000, 0x5c026000, 0x1c01f000, + 0x4d300000, 0x4d2c0000, 0x4d340000, 0x4d400000, + 0x4cfc0000, 0x4d380000, 0x4d3c0000, 0x4d440000, + 0x4d4c0000, 0x4d480000, 0x4c5c0000, 0x4c600000, + 0x4c640000, 0x4cc80000, 0x4ccc0000, 0x4cf00000, + 0x4cf40000, 0x4cf80000, 0x4cfc0000, 0x4d000000, + 0x4d040000, 0x0201f800, 0x00020015, 0x5c020800, + 0x5c020000, 0x5c01f800, 0x5c01f000, 0x5c01e800, + 0x5c01e000, 0x5c019800, 0x5c019000, 0x5c00c800, + 0x5c00c000, 0x5c00b800, 0x5c029000, 0x5c029800, + 0x5c028800, 0x5c027800, 0x5c027000, 0x5c01f800, + 0x5c028000, 0x5c026800, 0x5c025800, 0x5c026000, + 0x1c01f000, 0x493bc857, 0x0201f000, 0x00020044, + 0x83300500, 0x1f000000, 0x04000008, 0x81326580, + 0x80000130, 0x82000c80, 0x00000014, 0x02021800, + 0x001005d8, 0x0c01f013, 0x83300500, 0x000000ff, + 0x82000c80, 0x00000007, 0x02021800, 0x001005d8, + 0x0c01f025, 0x1c01f000, 0x82000d00, 0xc0000038, + 0x02020800, 0x001005d0, 0x0201f800, 0x001005d8, + 0x00000000, 0x00000048, 0x00000054, 0x00000053, + 0x00100a9b, 0x00100abf, 0x00100aba, 0x00100adf, + 0x00100aa6, 0x00100ab2, 0x00100a9b, 0x00100ada, + 0x00100b1a, 0x00100a9b, 0x00100a9b, 0x00100a9b, + 0x00100a9b, 0x00100b1d, 0x00100b23, 0x00100b34, + 0x00100b45, 0x00100a9b, 0x00100b4e, 0x00100b5a, + 0x00100a9b, 0x00100a9b, 0x00100a9b, 0x0201f800, + 0x001005d8, 0x00100aa4, 0x00100bff, 0x00100aec, + 0x00100b0f, 0x00100aa4, 0x00100aa4, 0x00100aa4, + 0x0201f800, 0x001005d8, 0x4803c856, 0x59300004, + 0x8c00053e, 0x04020005, 0x42027000, 0x00000055, + 0x0201f000, 0x000207a1, 0x0201f800, 0x00106f60, + 0x040007fa, 0x1c01f000, 0x4803c856, 0x0401f8a9, + 0x40002800, 0x41782000, 0x42027000, 0x00000056, + 0x0201f000, 0x000207a1, 0x4803c856, 0x42027000, + 0x00000057, 0x0201f000, 0x000207a1, 0x4803c856, + 0x59300007, 0x8c00051a, 0x04020010, 0x59325808, + 0x812e59c0, 0x04000014, 0x592c0408, 0x8c00051c, + 0x04020003, 0x4a026011, 0xffffffff, 0x59300004, + 0x8c00053e, 0x04020009, 0x42027000, 0x00000048, + 0x0201f000, 0x000207a1, 0x59325808, 0x4a025a06, + 0x00000007, 0x0401f7f4, 0x0201f800, 0x00106f60, + 0x040007f6, 0x1c01f000, 0x4803c856, 0x83300500, + 0x00ffffff, 0x0201f000, 0x001064d7, 0x1c01f000, + 0x4c040000, 0x59b808ea, 0x82040d00, 0x00000007, + 0x82040580, 0x00000003, 0x04000004, 0x42000000, + 0x60000000, 0x0401f8ab, 0x5c000800, 0x1c01f000, + 0x0401f8f9, 0x59325808, 0x812e59c0, 0x04000018, + 0x592c0204, 0x82000500, 0x000000ff, 0x82000d80, + 0x00000029, 0x04020012, 0x59300203, 0x82000580, + 0x00000003, 0x0400000b, 0x59300807, 0x84040d26, + 0x48066007, 0x0201f800, 0x00020086, 0x4a03900d, + 0x00000040, 0x4a0370e5, 0x00000008, 0x1c01f000, + 0x0201f800, 0x00106f60, 0x040007f4, 0x59880052, + 0x80000000, 0x48031052, 0x4a03900d, 0x00000040, + 0x42000000, 0xc0000000, 0x0401f05a, 0x42007800, + 0x0010bde2, 0x42002000, 0x00003000, 0x42003000, + 0x00000105, 0x0201f800, 0x00105e04, 0x4a0370e4, + 0x02000000, 0x1c01f000, 0x4933c857, 0x0201f000, + 0x0002077d, 0x41300800, 0x800409c0, 0x02020800, + 0x001005d8, 0x0201f800, 0x001005d0, 0x4933c857, + 0x813261c0, 0x02000800, 0x001005d8, 0x0401f835, + 0x40002800, 0x0201f800, 0x0010a99c, 0x0401f8ae, + 0x04000007, 0x59326809, 0x59340200, 0x8c00050e, + 0x59300414, 0x02020800, 0x001092ce, 0x1c01f000, + 0x4933c857, 0x813261c0, 0x02000800, 0x001005d8, + 0x0401f8a1, 0x0400000b, 0x59325808, 0x0201f800, + 0x00109037, 0x04000007, 0x592c0208, 0x8400054e, + 0x48025a08, 0x417a7800, 0x0201f800, 0x00108be3, + 0x1c01f000, 0x485fc857, 0x5c000000, 0x4d780000, + 0x4203e000, 0x50000000, 0x4200b800, 0x00008005, + 0x0201f000, 0x001005dd, 0x4933c857, 0x83300480, + 0x00000020, 0x02021800, 0x001005d8, 0x83300c00, + 0x0010b8cc, 0x50040000, 0x80000000, 0x04001002, + 0x44000800, 0x1c01f000, 0x4933c857, 0x0401f7f4, + 0x4807c856, 0x59b800ea, 0x8c000510, 0x040007fd, + 0x59b800e0, 0x4803c857, 0x1c01f000, 0x4803c856, + 0x42000000, 0x10000000, 0x41300800, 0x0401f02d, + 0x82000500, 0xf0000000, 0x82040d00, 0x0fffffff, + 0x80040d40, 0x4807c857, 0x59b800ea, 0x8c000516, + 0x04020003, 0x480770e1, 0x1c01f000, 0x8c000510, + 0x040007fa, 0x4c040000, 0x0401f809, 0x5c000800, + 0x82100480, 0x00000008, 0x040017f4, 0x4c040000, + 0x0401febc, 0x5c000800, 0x0401f7f0, 0x59b800e2, + 0x59b820e2, 0x80100580, 0x040207fd, 0x80102114, + 0x0401f006, 0x59b800e2, 0x59b820e2, 0x80100580, + 0x040207fd, 0x0401f001, 0x40101800, 0x800c190a, + 0x82100500, 0x0000001f, 0x820c1d00, 0x0000001f, + 0x800c2480, 0x82102500, 0x0000001f, 0x1c01f000, + 0x82000500, 0xf0000000, 0x82040d00, 0x0fffffff, + 0x80040d40, 0x4807c857, 0x42001000, 0x0010b804, + 0x50080000, 0x80000540, 0x04020005, 0x4a0370e5, + 0x00000003, 0x4a0370e4, 0x00000300, 0x80000000, + 0x44001000, 0x42001000, 0x00000400, 0x59b800ea, + 0x8c000510, 0x0400000c, 0x0401ffd5, 0x82100480, + 0x00000008, 0x04001007, 0x4c040000, 0x4c080000, + 0x0401fe88, 0x5c001000, 0x5c000800, 0x0401f020, + 0x59b800ea, 0x8c000516, 0x0402001d, 0x4a0370e4, + 0x00300000, 0x480770e1, 0x42001000, 0x0000ff00, + 0x80081040, 0x04000012, 0x59b808e4, 0x8c040d28, + 0x040207fc, 0x42001000, 0x0010b804, 0x50080000, + 0x80000040, 0x04020005, 0x4a0370e5, 0x00000002, + 0x4a0370e4, 0x00000200, 0x02001800, 0x001005d8, + 0x44001000, 0x8c040d2c, 0x1c01f000, 0x41f80000, + 0x50000000, 0x0201f800, 0x001005d8, 0x80081040, + 0x040207d3, 0x41f80000, 0x50000000, 0x0201f800, + 0x001005d8, 0x4d380000, 0x59300c06, 0x82040580, + 0x00000009, 0x04020006, 0x42027000, 0x00000047, + 0x0201f800, 0x000207a1, 0x80000580, 0x5c027000, + 0x1c01f000, 0x4c500000, 0x4a03900d, 0x00000001, + 0x59c8a020, 0x4a03900d, 0x00000002, 0x59c80820, + 0x8c50a52e, 0x04000002, 0x900409c0, 0x82040d00, + 0x0000ffff, 0x0201f800, 0x00105dd7, 0x02000800, + 0x001005d8, 0x4933c857, 0x8250a500, 0xff000000, + 0x82500580, 0x05000000, 0x04000003, 0x82000540, + 0x00000001, 0x5c00a000, 0x1c01f000, 0x0401ffe6, + 0x4933c857, 0x59300406, 0x82000580, 0x00000000, + 0x04000040, 0x59c82021, 0x4a03900d, 0x00000001, + 0x59c82821, 0x82142d00, 0x0000ffff, 0x59325808, + 0x812e59c0, 0x04000037, 0x59326809, 0x0201f800, + 0x001048d9, 0x02020800, 0x001092b6, 0x599c0019, + 0x8c00050c, 0x04020018, 0x0201f800, 0x001048d9, + 0x04020015, 0x59300811, 0x4807c857, 0x592c0408, + 0x8c00051c, 0x0402000e, 0x8400055c, 0x48025c08, + 0x592c0a04, 0x82040d00, 0x000000ff, 0x82040580, + 0x00000048, 0x04000004, 0x82040580, 0x00000018, + 0x04020003, 0x59300811, 0x48065803, 0x4a026011, + 0x7fffffff, 0x48166013, 0x0201f800, 0x001010dd, + 0x04020014, 0x0401f9fd, 0x40280000, 0x4802600d, + 0x04000005, 0x4832600b, 0x50200000, 0x4802600a, + 0x4822600c, 0x59300414, 0x8c00051c, 0x04020004, + 0x599c0019, 0x8c00050c, 0x0402086e, 0x4a03900d, + 0x00000040, 0x4a0370e5, 0x00000008, 0x1c01f000, + 0x59880052, 0x80000000, 0x48031052, 0x4a03900d, + 0x00000040, 0x42000000, 0xc0000000, 0x0401f71d, + 0x4cf80000, 0x58f40000, 0x8001f540, 0x0401f820, + 0x41781800, 0x0401f8e4, 0x04020014, 0x44140800, + 0x0401f82a, 0x04000011, 0x40043800, 0x42001800, + 0x00000001, 0x40142000, 0x0401f8db, 0x0402000b, + 0x801c3800, 0x501c0000, 0x44000800, 0x0401f810, + 0x801c0580, 0x04000004, 0x44103800, 0x801c3840, + 0x44143800, 0x0401f819, 0x5c01f000, 0x1c01f000, + 0x80f9f1c0, 0x04020003, 0x58f41202, 0x0401f003, + 0x42001000, 0x00000007, 0x1c01f000, 0x80f9f1c0, + 0x04020006, 0x58f40401, 0x82000480, 0x00000002, + 0x80f40400, 0x0401f005, 0x58f80401, 0x82000480, + 0x00000002, 0x80f80400, 0x50002800, 0x80000000, + 0x50002000, 0x1c01f000, 0x80f9f1c0, 0x04020008, + 0x58f40401, 0x82000480, 0x00000002, 0x02001800, + 0x001005d8, 0x4801ec01, 0x0401f00b, 0x58f80401, + 0x82000480, 0x00000002, 0x02001800, 0x001005d8, + 0x4801f401, 0x82000580, 0x00000002, 0x04020002, + 0x0401f809, 0x58f40202, 0x80000040, 0x4801ea02, + 0x02000800, 0x001005d8, 0x82000580, 0x00000001, + 0x1c01f000, 0x4d2c0000, 0x40fa5800, 0x0201f800, + 0x001007f4, 0x4979e800, 0x4179f000, 0x5c025800, + 0x1c01f000, 0x80f5e9c0, 0x04000009, 0x80f9f1c0, + 0x04020ff5, 0x4d2c0000, 0x40f65800, 0x0201f800, + 0x001007f4, 0x4179e800, 0x5c025800, 0x1c01f000, + 0x4cf40000, 0x59300807, 0x82040500, 0x00003100, 0x04020032, 0x8c040d22, 0x04000032, 0x5930001f, - 0x8001ed40, 0x02000800, 0x00100615, 0x82000580, + 0x8001ed40, 0x02000800, 0x001005d8, 0x82000580, 0xffffffff, 0x04000029, 0x58f40201, 0x82000580, - 0x0000dcb3, 0x02020800, 0x00100615, 0x58f40a02, - 0x82040500, 0x0000fffe, 0x04000003, 0x0401ff86, + 0x0000dcb3, 0x02020800, 0x001005d8, 0x58f40a02, + 0x82040500, 0x0000fffe, 0x04000003, 0x0401ff89, 0x58f40a02, 0x82040480, 0x0000000f, 0x04021059, 0x80040800, 0x4805ea02, 0x82040580, 0x00000008, 0x0400005d, 0x82040480, 0x00000008, 0x0400100a, - 0x58f40000, 0x8001ed40, 0x02000800, 0x00100615, + 0x58f40000, 0x8001ed40, 0x02000800, 0x001005d8, 0x58f40201, 0x82000580, 0x0000ddb9, 0x02020800, - 0x00100615, 0x58f40401, 0x82000c00, 0x00000002, + 0x001005d8, 0x58f40401, 0x82000c00, 0x00000002, 0x4805ec01, 0x80f40400, 0x59300812, 0x44040000, 0x80000000, 0x45780000, 0x5c01e800, 0x1c01f000, 0x42001000, 0x00000400, 0x59b800e4, 0x8c000524, 0x04020023, 0x4a0370e4, 0x00030000, 0x40000000, 0x59b800e4, 0x8c000524, 0x0402001b, 0x59300807, 0x84040d62, 0x48066007, 0x4a0370e4, 0x00020000, - 0x4d2c0000, 0x0201f800, 0x00100819, 0x04000025, + 0x4d2c0000, 0x0201f800, 0x001007d3, 0x04000025, 0x492e601f, 0x4a025a01, 0x0000dcb3, 0x59300008, - 0x80001d40, 0x02000800, 0x00100615, 0x580c080f, + 0x80001d40, 0x02000800, 0x001005d8, 0x580c080f, 0x48065803, 0x59301811, 0x40040000, 0x800c0580, 0x0402000d, 0x497a5a02, 0x4a025c01, 0x00000004, 0x0401f011, 0x4a0370e4, 0x00020000, 0x40000000, - 0x40000000, 0x80081040, 0x02000800, 0x00100615, + 0x40000000, 0x80081040, 0x02000800, 0x001005d8, 0x0401f7d6, 0x4a025a02, 0x00000001, 0x4a025c01, 0x00000006, 0x497a5804, 0x400c0000, 0x80040480, 0x48025805, 0x412de800, 0x5c025800, 0x0401f7a9, 0x5c025800, 0x4a02601f, 0xffffffff, 0x0401f7c3, - 0x4d2c0000, 0x58f65800, 0x0201f800, 0x0010083a, - 0x40f65800, 0x0201f800, 0x0010083a, 0x5c025800, - 0x0401f7f5, 0x4d2c0000, 0x0201f800, 0x00100819, + 0x4d2c0000, 0x58f65800, 0x0201f800, 0x001007f4, + 0x40f65800, 0x0201f800, 0x001007f4, 0x5c025800, + 0x0401f7f5, 0x4d2c0000, 0x0201f800, 0x001007d3, 0x040007f8, 0x4a025a01, 0x0000ddb9, 0x4a025c01, 0x00000002, 0x492de800, 0x412de800, 0x5c025800, - 0x0401f7a5, 0x0401ff30, 0x82f40400, 0x00000004, + 0x0401f7a5, 0x0401ff33, 0x82f40400, 0x00000004, 0x800c0400, 0x40000800, 0x50040000, 0x80100580, 0x04000016, 0x82040c00, 0x00000002, 0x80081040, 0x040207fa, 0x80f9f1c0, 0x04000011, 0x58f41202, @@ -910,205 +893,202 @@ uint32_t risc_code01[] = { 0x04000006, 0x82040c00, 0x00000002, 0x80081040, 0x040207fa, 0x0401f002, 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fd, 0x4cf40000, 0x4cf80000, - 0x4001e800, 0x592c0a06, 0x800409c0, 0x04020021, - 0x82f40580, 0xffffffff, 0x0400001b, 0x58f40201, - 0x82000580, 0x0000dcb3, 0x02020800, 0x00100615, + 0x4001e800, 0x592c0a06, 0x800409c0, 0x0402001d, + 0x82f40580, 0xffffffff, 0x04000017, 0x58f40201, + 0x82000580, 0x0000dcb3, 0x02020800, 0x001005d8, 0x58f40000, 0x8001f540, 0x04000006, 0x58f80201, - 0x82000580, 0x0000ddb9, 0x02020800, 0x00100615, - 0x41783800, 0x58f44003, 0x0401f83d, 0x04020009, - 0x0401ff2e, 0x497a601f, 0x59300807, 0x84040d22, - 0x48066007, 0x5c01f000, 0x5c01e800, 0x1c01f000, - 0x0401ff26, 0x4a025a06, 0x00000011, 0x0401f7f6, - 0x82f40580, 0xffffffff, 0x04020f20, 0x0401f7f2, + 0x82000580, 0x0000ddb9, 0x02020800, 0x001005d8, + 0x41783800, 0x0401f839, 0x04020006, 0x0401ff32, + 0x497a601f, 0x5c01f000, 0x5c01e800, 0x1c01f000, + 0x0401ff2d, 0x4a025a06, 0x00000011, 0x0401f7f9, + 0x82f40580, 0xffffffff, 0x04020f27, 0x0401f7f5, 0x4cf40000, 0x4cf80000, 0x4001e800, 0x82040580, - 0x00000001, 0x04020020, 0x82f40580, 0xffffffff, - 0x0400001a, 0x58f40201, 0x82000580, 0x0000dcb3, - 0x02020800, 0x00100615, 0x58f40000, 0x8001f540, + 0x00000001, 0x0402001f, 0x82f40580, 0xffffffff, + 0x04000019, 0x58f40201, 0x82000580, 0x0000dcb3, + 0x02020800, 0x001005d8, 0x58f40000, 0x8001f540, 0x04000006, 0x58f80201, 0x82000580, 0x0000ddb9, - 0x02020800, 0x00100615, 0x41783800, 0x58f44003, - 0x0401f813, 0x04020008, 0x0401ff04, 0x42000800, - 0x00000001, 0x497a601f, 0x5c01f000, 0x5c01e800, - 0x1c01f000, 0x0401fefd, 0x42000800, 0x00000011, - 0x0401f7f9, 0x4c040000, 0x82f40580, 0xffffffff, - 0x04020ef6, 0x5c000800, 0x0401f7f3, 0x4803c856, - 0x401c2000, 0x41781800, 0x4c200000, 0x0401ff86, - 0x5c004000, 0x0402002c, 0x40202000, 0x42001800, - 0x00000001, 0x0401ff80, 0x04020027, 0x0401feae, - 0x40082800, 0x82f40400, 0x00000004, 0x40003000, - 0x50182000, 0x40100000, 0x801c0580, 0x04000005, - 0x42001800, 0x00000001, 0x0401ff73, 0x0402001a, - 0x82183400, 0x00000002, 0x80142840, 0x040207f5, - 0x80f9f1c0, 0x04000013, 0x58f42a02, 0x82142c80, - 0x00000007, 0x82f80400, 0x00000003, 0x40003000, - 0x50182000, 0x40100000, 0x801c0580, 0x04000005, - 0x42001800, 0x00000001, 0x0401ff5f, 0x04020006, - 0x82183400, 0x00000002, 0x80142840, 0x040207f5, - 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fd, - 0x0201f800, 0x00100615, 0x58380207, 0x8c000502, - 0x040007fc, 0x50200000, 0x80387c00, 0x583c2800, - 0x583c2001, 0x58380404, 0x80001540, 0x04020002, - 0x58381407, 0x58c83401, 0x58380c08, 0x59303807, - 0x497a6012, 0x497a6013, 0x0201f000, 0x000200bf, - 0x592c0408, 0x8c000502, 0x040007ea, 0x592c0409, - 0x80000540, 0x040007e7, 0x82000c80, 0x00000002, - 0x04001011, 0x58380001, 0x80007540, 0x02000800, - 0x00100615, 0x58380204, 0x82000500, 0x0000000f, - 0x82000400, 0x0010110d, 0x50004000, 0x40040000, - 0x800409c0, 0x04000005, 0x82040c80, 0x00000005, - 0x040217f1, 0x80204400, 0x50200000, 0x80387c00, - 0x583c2800, 0x583c2001, 0x583c1002, 0x592c0a07, - 0x592c4c08, 0x592c300d, 0x59303807, 0x497a6012, - 0x497a6013, 0x4816600e, 0x4812600f, 0x480a6010, - 0x481a6011, 0x80040840, 0x4806600d, 0x02000000, - 0x000200c7, 0x80204000, 0x50201800, 0x800c19c0, - 0x0402000c, 0x58380001, 0x80007540, 0x02000800, - 0x00100615, 0x58380204, 0x82000500, 0x0000000f, - 0x82000400, 0x0010110d, 0x50004000, 0x50201800, - 0x483a600b, 0x480e600a, 0x4822600c, 0x0201f000, - 0x000200c7, 0x4803c856, 0x592c0208, 0x8c00051e, - 0x04020017, 0x50200000, 0x80306c00, 0x40240000, - 0x0c01f001, 0x00100e91, 0x00100e91, 0x00100e9a, - 0x00100e91, 0x00100e91, 0x00100e91, 0x00100e91, - 0x00100e91, 0x00100e9a, 0x00100e91, 0x00100e9a, - 0x00100e91, 0x00100e91, 0x00100e9a, 0x00100e91, - 0x00100e91, 0x0201f800, 0x00100615, 0x8400051e, - 0x48025a08, 0x50200000, 0x80306c00, 0x58343801, - 0x481e600f, 0x0401f007, 0x58341802, 0x58342800, - 0x58343801, 0x480e6010, 0x4816600e, 0x481e600f, - 0x0401f24b, 0x4933c857, 0x5931f808, 0x59300a06, - 0x800409c0, 0x04000005, 0x80040906, 0x04020002, - 0x80040800, 0x4805fc06, 0x4a026206, 0x00000002, - 0x592c0409, 0x82000500, 0x00000008, 0x0400000b, - 0x0401f834, 0x59300203, 0x82000580, 0x00000004, - 0x04020005, 0x42027000, 0x00000048, 0x0201f800, - 0x000208d8, 0x1c01f000, 0x4cfc0000, 0x58fc0204, - 0x82000500, 0x000000ff, 0x82000580, 0x00000048, - 0x0402000c, 0x58fc000b, 0x800001c0, 0x04000009, - 0x58fc0407, 0x800001c0, 0x04000006, 0x58fc080b, - 0x8c040d16, 0x04000017, 0x58fc0007, 0x0401f00a, - 0x58fc0408, 0x8c000512, 0x04020014, 0x58fc0c09, - 0x8c040d16, 0x04020003, 0x5c01f800, 0x1c01f000, - 0x58fc000a, 0x59300811, 0x80040580, 0x04020009, - 0x59300007, 0x84000500, 0x48026007, 0x42027000, - 0x00000048, 0x5c01f800, 0x0201f000, 0x000208d8, - 0x5c01f800, 0x1c01f000, 0x58fdf809, 0x0401f7ec, - 0x5c000000, 0x4c000000, 0x4803c857, 0x4933c857, - 0x59b808ea, 0x82040d00, 0x00000007, 0x82040580, - 0x00000000, 0x0400001e, 0x82040580, 0x00000003, - 0x0400001b, 0x59300406, 0x4c000000, 0x4a026406, - 0x00000000, 0x42003000, 0x00000041, 0x42000000, - 0x50000000, 0x41300800, 0x4c180000, 0x0401fce3, - 0x5c003000, 0x0400000b, 0x42000000, 0x0000001e, - 0x80000040, 0x040207ff, 0x80183040, 0x040207f4, - 0x42000000, 0x40000000, 0x41300800, 0x0401fcd7, - 0x5c000000, 0x48026406, 0x1c01f000, 0x59300007, - 0x84000500, 0x48026007, 0x0401f7fc, 0x59c00007, - 0x4a038006, 0x30000000, 0x40000000, 0x59c00007, - 0x8c00050a, 0x040207fe, 0x1c01f000, 0x5c000000, - 0x4c000000, 0x4803c857, 0x4dc00000, 0x4a0370e8, - 0x00000000, 0x42038000, 0x00007720, 0x0401fff0, - 0x42038000, 0x00007700, 0x0401ffed, 0x0201f800, - 0x00104e0d, 0x04020013, 0x4a038891, 0x0000ffff, - 0x497b8880, 0x497b8892, 0x42001000, 0x00000190, - 0x40000000, 0x40000000, 0x80081040, 0x040207fd, - 0x42000000, 0x0010b6a5, 0x0201f800, 0x0010a86e, - 0x0401f80e, 0x5c038000, 0x0201f000, 0x00104f29, - 0x0401f82d, 0x42000000, 0x0010b6a6, 0x0201f800, - 0x0010a86e, 0x0401f805, 0x48178892, 0x480b8880, - 0x5c038000, 0x1c01f000, 0x496fc857, 0x836c0580, - 0x00000003, 0x0402000b, 0x4c080000, 0x4c0c0000, - 0x42001000, 0x00008048, 0x42001800, 0x0000ffff, - 0x0201f800, 0x00103857, 0x5c001800, 0x5c001000, - 0x42000800, 0x0000003c, 0x0201f800, 0x00101395, - 0x59a8006c, 0x80000540, 0x04000006, 0x59a8106d, - 0x800811c0, 0x04000003, 0x0201f800, 0x00101b0a, - 0x4a038891, 0x0000ffff, 0x4a03900d, 0x00000040, - 0x0201f800, 0x001009db, 0x4a0370e8, 0x00000001, + 0x02020800, 0x001005d8, 0x41783800, 0x0401f813, + 0x04020008, 0x0401ff0c, 0x42000800, 0x00000001, + 0x497a601f, 0x5c01f000, 0x5c01e800, 0x1c01f000, + 0x0401ff05, 0x42000800, 0x00000011, 0x0401f7f9, + 0x4c040000, 0x82f40580, 0xffffffff, 0x04020efe, + 0x5c000800, 0x0401f7f3, 0x4803c856, 0x401c2000, + 0x41781800, 0x0401ff8c, 0x0402002c, 0x58f42003, + 0x42001800, 0x00000001, 0x0401ff87, 0x04020027, + 0x0401feb8, 0x40082800, 0x82f40400, 0x00000004, + 0x40003000, 0x50182000, 0x40100000, 0x801c0580, + 0x04000005, 0x42001800, 0x00000001, 0x0401ff7a, + 0x0402001a, 0x82183400, 0x00000002, 0x80142840, + 0x040207f5, 0x80f9f1c0, 0x04000013, 0x58f42a02, + 0x82142c80, 0x00000007, 0x82f80400, 0x00000003, + 0x40003000, 0x50182000, 0x40100000, 0x801c0580, + 0x04000005, 0x42001800, 0x00000001, 0x0401ff66, + 0x04020006, 0x82183400, 0x00000002, 0x80142840, + 0x040207f5, 0x1c01f000, 0x82000540, 0x00000001, + 0x0401f7fd, 0x0201f800, 0x001005d8, 0x58380207, + 0x8c000502, 0x040007fc, 0x50200000, 0x80387c00, + 0x583c2800, 0x583c2001, 0x58380404, 0x80001540, + 0x04020002, 0x58381407, 0x58c83401, 0x58380c08, + 0x59303807, 0x497a6012, 0x497a6013, 0x0201f000, + 0x000200be, 0x592c0408, 0x8c000502, 0x040007ea, + 0x592c0409, 0x80000540, 0x040007e7, 0x82000c80, + 0x00000002, 0x04001011, 0x58380001, 0x80007540, + 0x02000800, 0x001005d8, 0x58380204, 0x82000500, + 0x0000000f, 0x82000400, 0x001010bd, 0x50004000, + 0x40040000, 0x800409c0, 0x04000005, 0x82040c80, + 0x00000005, 0x040217f1, 0x80204400, 0x50200000, + 0x80387c00, 0x583c2800, 0x583c2001, 0x583c1002, + 0x592c0a07, 0x592c4c08, 0x592c300d, 0x59303807, + 0x497a6012, 0x497a6013, 0x4816600e, 0x4812600f, + 0x480a6010, 0x481a6011, 0x80040840, 0x4806600d, + 0x02000000, 0x000200c6, 0x80204000, 0x50201800, + 0x800c19c0, 0x0402000c, 0x58380001, 0x80007540, + 0x02000800, 0x001005d8, 0x58380204, 0x82000500, + 0x0000000f, 0x82000400, 0x001010bd, 0x50004000, + 0x50201800, 0x483a600b, 0x480e600a, 0x4822600c, + 0x0201f000, 0x000200c6, 0x4803c856, 0x592c0208, + 0x8c00051e, 0x04020017, 0x50200000, 0x80306c00, + 0x40240000, 0x0c01f001, 0x00100e46, 0x00100e46, + 0x00100e4f, 0x00100e46, 0x00100e46, 0x00100e46, + 0x00100e46, 0x00100e46, 0x00100e4f, 0x00100e46, + 0x00100e4f, 0x00100e46, 0x00100e46, 0x00100e4f, + 0x00100e46, 0x00100e46, 0x0201f800, 0x001005d8, + 0x8400051e, 0x48025a08, 0x50200000, 0x80306c00, + 0x58343801, 0x481e600f, 0x0401f007, 0x58341802, + 0x58342800, 0x58343801, 0x480e6010, 0x4816600e, + 0x481e600f, 0x0401f246, 0x4933c857, 0x5931f808, + 0x59300a06, 0x800409c0, 0x04000005, 0x80040906, + 0x04020002, 0x80040800, 0x4805fc06, 0x4a026206, + 0x00000002, 0x592c0409, 0x82000500, 0x00000008, + 0x0400000b, 0x0401f834, 0x59300203, 0x82000580, + 0x00000004, 0x04020005, 0x42027000, 0x00000048, + 0x0201f800, 0x000207a1, 0x1c01f000, 0x4cfc0000, + 0x58fc0204, 0x82000500, 0x000000ff, 0x82000580, + 0x00000048, 0x0402000c, 0x58fc000b, 0x800001c0, + 0x04000009, 0x58fc0407, 0x800001c0, 0x04000006, + 0x58fc080b, 0x8c040d16, 0x04000017, 0x58fc0007, + 0x0401f00a, 0x58fc0408, 0x8c000512, 0x04020014, + 0x58fc0c09, 0x8c040d16, 0x04020003, 0x5c01f800, + 0x1c01f000, 0x58fc000a, 0x59300811, 0x80040580, + 0x04020009, 0x59300007, 0x84000500, 0x48026007, + 0x42027000, 0x00000048, 0x5c01f800, 0x0201f000, + 0x000207a1, 0x5c01f800, 0x1c01f000, 0x58fdf809, + 0x0401f7ec, 0x4933c857, 0x59b808ea, 0x82040d00, + 0x00000007, 0x82040580, 0x00000000, 0x0400001e, + 0x82040580, 0x00000003, 0x0400001b, 0x59300406, + 0x4c000000, 0x4a026406, 0x00000000, 0x42003000, + 0x00000041, 0x42000000, 0x50000000, 0x41300800, + 0x4c180000, 0x0401fce7, 0x5c003000, 0x0400000b, + 0x42000000, 0x0000001e, 0x80000040, 0x040207ff, + 0x80183040, 0x040207f4, 0x42000000, 0x40000000, + 0x41300800, 0x0401fcdb, 0x5c000000, 0x48026406, + 0x1c01f000, 0x59300007, 0x84000500, 0x48026007, + 0x0401f7fc, 0x59c00007, 0x4a038006, 0x30000000, + 0x40000000, 0x59c00007, 0x8c00050a, 0x040207fe, 0x1c01f000, 0x5c000000, 0x4c000000, 0x4803c857, - 0x59c41080, 0x497b8880, 0x59c42892, 0x497b8892, - 0x0201f800, 0x00104e0d, 0x04020002, 0x1c01f000, - 0x42002000, 0x00000260, 0x59c418a4, 0x820c1d00, - 0x0000000f, 0x820c0580, 0x00000000, 0x04000010, - 0x59c41805, 0x820c1d00, 0x00000001, 0x0402000e, - 0x59c418a4, 0x820c1d00, 0x0000000f, 0x820c0480, - 0x00000007, 0x04001004, 0x820c0480, 0x0000000c, - 0x04001003, 0x80102040, 0x040207ec, 0x497b8891, - 0x1c01f000, 0x4c100000, 0x42002000, 0x00000019, - 0x46000000, 0x00000001, 0x0201f800, 0x001019a4, - 0x50001800, 0x820c1d00, 0x00000001, 0x04000005, - 0x80102040, 0x040207f7, 0x5c002000, 0x0401f7f0, - 0x5c002000, 0x0401f7ec, 0x4803c856, 0x1c01f000, - 0x4d2c0000, 0x59325808, 0x592c0a04, 0x4807c857, - 0x82040d00, 0x000000ff, 0x82040500, 0x0000000f, - 0x0c01f001, 0x00100fb5, 0x00100fb5, 0x00100fb5, - 0x00100fcd, 0x00100fb5, 0x00100fb5, 0x00100fb5, - 0x00100fb5, 0x00100fb5, 0x00100fcd, 0x00100fb5, - 0x00100fb7, 0x00100fb5, 0x00100fb5, 0x00100fb5, - 0x00100fb5, 0x0201f800, 0x00100615, 0x82040580, - 0x0000003b, 0x02020800, 0x00100615, 0x592c020a, - 0x8c000500, 0x0400005f, 0x592c1a07, 0x82040500, - 0x0000000f, 0x82000400, 0x0010110d, 0x50001000, - 0x50080000, 0x59302013, 0x4802600a, 0x492e600b, - 0x480a600c, 0x480e600d, 0x48126012, 0x5c025800, - 0x1c01f000, 0x82040500, 0x0000000f, 0x82000400, - 0x0010110d, 0x50001000, 0x50080000, 0x592c1a07, + 0x4dc00000, 0x4a0370e8, 0x00000000, 0x42038000, + 0x00007720, 0x0401fff0, 0x42038000, 0x00007700, + 0x0401ffed, 0x0201f800, 0x0010513b, 0x04020013, + 0x4a038891, 0x0000ffff, 0x497b8880, 0x497b8892, + 0x42001000, 0x00000190, 0x40000000, 0x40000000, + 0x80081040, 0x040207fd, 0x42000000, 0x0010b8a6, + 0x0201f800, 0x0010aa47, 0x0401f80e, 0x5c038000, + 0x0201f000, 0x00105258, 0x0401f82d, 0x42000000, + 0x0010b8a7, 0x0201f800, 0x0010aa47, 0x0401f805, + 0x48178892, 0x480b8880, 0x5c038000, 0x1c01f000, + 0x496fc857, 0x836c0580, 0x00000003, 0x0402000b, + 0x4c080000, 0x4c0c0000, 0x42001000, 0x00008048, + 0x42001800, 0x0000ffff, 0x0201f800, 0x00103a3e, + 0x5c001800, 0x5c001000, 0x42000800, 0x0000003c, + 0x0201f800, 0x00101345, 0x59a8006c, 0x80000540, + 0x04000006, 0x59a8106d, 0x800811c0, 0x04000003, + 0x0201f800, 0x00101aaf, 0x4a038891, 0x0000ffff, + 0x4a03900d, 0x00000040, 0x0201f800, 0x0010098e, + 0x4a0370e8, 0x00000001, 0x1c01f000, 0x5c000000, + 0x4c000000, 0x4803c857, 0x59c41080, 0x497b8880, + 0x59c42892, 0x497b8892, 0x0201f800, 0x0010513b, + 0x04020002, 0x1c01f000, 0x42002000, 0x00000260, + 0x59c418a4, 0x820c1d00, 0x0000000f, 0x820c0580, + 0x00000000, 0x04000010, 0x59c41805, 0x820c1d00, + 0x00000001, 0x0402000e, 0x59c418a4, 0x820c1d00, + 0x0000000f, 0x820c0480, 0x00000007, 0x04001004, + 0x820c0480, 0x0000000c, 0x04001003, 0x80102040, + 0x040207ec, 0x497b8891, 0x1c01f000, 0x4c100000, + 0x42002000, 0x00000019, 0x46000000, 0x00000001, + 0x0201f800, 0x00101937, 0x50001800, 0x820c1d00, + 0x00000001, 0x04000005, 0x80102040, 0x040207f7, + 0x5c002000, 0x0401f7f0, 0x5c002000, 0x0401f7ec, + 0x4803c856, 0x1c01f000, 0x4d2c0000, 0x59325808, + 0x592c0a04, 0x4807c857, 0x82040d00, 0x000000ff, + 0x82040500, 0x0000000f, 0x0c01f001, 0x00100f67, + 0x00100f67, 0x00100f67, 0x00100f7f, 0x00100f67, + 0x00100f67, 0x00100f67, 0x00100f67, 0x00100f67, + 0x00100f7f, 0x00100f67, 0x00100f69, 0x00100f67, + 0x00100f67, 0x00100f67, 0x00100f67, 0x0201f800, + 0x001005d8, 0x82040580, 0x0000003b, 0x02020800, + 0x001005d8, 0x592c020a, 0x8c000500, 0x0400005f, + 0x592c1a07, 0x82040500, 0x0000000f, 0x82000400, + 0x001010bd, 0x50001000, 0x50080000, 0x59302013, 0x4802600a, 0x492e600b, 0x480a600c, 0x480e600d, - 0x497a6012, 0x0401f7f2, 0x8c040d00, 0x04020041, - 0x82040d00, 0x00000080, 0x0400003e, 0x0201f000, - 0x000200d0, 0x59300013, 0x59301012, 0x80080580, - 0x0402000c, 0x42007800, 0x80000005, 0x592c1208, - 0x82080500, 0xffff7fff, 0x48025a08, 0x8c08151e, - 0x0402002d, 0x823c7d40, 0x00000020, 0x0401f02a, - 0x480bc857, 0x42000000, 0x0010b64f, 0x0201f800, - 0x0010a86e, 0x59300414, 0x4803c857, 0x8c000514, - 0x04020007, 0x599c1819, 0x8c0c1d12, 0x04020004, - 0x820c1d40, 0x00000001, 0x0401f01d, 0x59302013, - 0x0401f92d, 0x0402001a, 0x42007800, 0x80000005, - 0x5930500d, 0x592c0208, 0x4803c857, 0x8c00051e, - 0x04020005, 0x823c7d40, 0x00000020, 0x5930400c, - 0x0401f004, 0x8400051e, 0x48025a08, 0x0401f8dc, - 0x50201800, 0x480e600a, 0x4832600b, 0x4822600c, - 0x482a600d, 0x480fc857, 0x4833c857, 0x4823c857, - 0x482bc857, 0x80000580, 0x483e6004, 0x1c01f000, - 0x0201f800, 0x00100615, 0x4933c857, 0x4d2c0000, - 0x59900004, 0x81300580, 0x02020800, 0x00100615, - 0x0201f800, 0x00108df4, 0x02000800, 0x00100615, - 0x59325808, 0x4d3c0000, 0x4d400000, 0x59300004, - 0x4803c857, 0x4c000000, 0x0201f800, 0x00106b13, - 0x0201f800, 0x001068c1, 0x5c000000, 0x8c000516, - 0x04000010, 0x592c000f, 0x4803c857, 0x48025807, - 0x41780800, 0x42028000, 0x00000002, 0x0201f800, - 0x00104bee, 0x4a025c06, 0x0000ffff, 0x0201f800, - 0x00020381, 0x0201f800, 0x00107698, 0x0401f015, - 0x4a026203, 0x00000002, 0x592c0208, 0x8400054e, - 0x48025a08, 0x59300406, 0x82000580, 0x00000006, - 0x04020009, 0x811800ca, 0x81c80c00, 0x58040939, - 0x592c000d, 0x80040480, 0x592c080f, 0x80040480, - 0x4802580b, 0x417a7800, 0x0201f800, 0x00108997, - 0x5c028000, 0x5c027800, 0x5c025800, 0x1c01f000, + 0x48126012, 0x5c025800, 0x1c01f000, 0x82040500, + 0x0000000f, 0x82000400, 0x001010bd, 0x50001000, + 0x50080000, 0x592c1a07, 0x4802600a, 0x492e600b, + 0x480a600c, 0x480e600d, 0x497a6012, 0x0401f7f2, + 0x8c040d00, 0x04020041, 0x82040d00, 0x00000080, + 0x0400003e, 0x0201f000, 0x000200cf, 0x59300013, + 0x59301012, 0x80080580, 0x0402000c, 0x42007800, + 0x80000005, 0x592c1208, 0x82080500, 0xffff7fff, + 0x48025a08, 0x8c08151e, 0x0402002d, 0x823c7d40, + 0x00000020, 0x0401f02a, 0x480bc857, 0x42000000, + 0x0010b851, 0x0201f800, 0x0010aa47, 0x59300414, + 0x4803c857, 0x8c000514, 0x04020007, 0x599c1819, + 0x8c0c1d12, 0x04020004, 0x820c1d40, 0x00000001, + 0x0401f01d, 0x59302013, 0x0401f92b, 0x0402001a, + 0x42007800, 0x80000005, 0x5930500d, 0x592c0208, + 0x4803c857, 0x8c00051e, 0x04020005, 0x823c7d40, + 0x00000020, 0x5930400c, 0x0401f004, 0x8400051e, + 0x48025a08, 0x0401f8da, 0x50201800, 0x480e600a, + 0x4832600b, 0x4822600c, 0x482a600d, 0x480fc857, + 0x4833c857, 0x4823c857, 0x482bc857, 0x80000580, + 0x483e6004, 0x1c01f000, 0x0201f800, 0x001005d8, 0x4933c857, 0x4d2c0000, 0x59900004, 0x81300580, - 0x02020800, 0x00100615, 0x0201f800, 0x00108df4, - 0x02000800, 0x00100615, 0x59325808, 0x592c0208, - 0x84000540, 0x48025a08, 0x0401f7bf, 0x491bc857, - 0x49d3c857, 0x4dd00000, 0x41780800, 0x8007a0ca, - 0x83d3a400, 0x00007600, 0x4a03a005, 0x80000002, - 0x42000000, 0x00001000, 0x50000000, 0x82000480, - 0x24220001, 0x04020029, 0x59d01006, 0x82080500, - 0x00006000, 0x82000580, 0x00006000, 0x04000031, - 0x82080500, 0x40008000, 0x040007f8, 0x800409c0, - 0x0402002c, 0x811a31c0, 0x0400002a, 0x42000000, - 0x00001002, 0x50001000, 0x46000000, 0x00000512, - 0x42001800, 0x0000000a, 0x59e00000, 0x8c00051a, - 0x040207fc, 0x800c1840, 0x040207fc, 0x42000000, - 0x00001002, 0x46000000, 0x00000514, 0x42001800, - 0x0000000a, 0x59e00000, 0x8c00053a, 0x040207fc, - 0x800c1840, 0x040207fc, 0x42000000, 0x00001002, - 0x44080000, 0x0401f00f, 0x02004800, 0x000207c8, + 0x02020800, 0x001005d8, 0x0201f800, 0x00109037, + 0x02000800, 0x001005d8, 0x59325808, 0x4d3c0000, + 0x4d400000, 0x59300004, 0x4803c857, 0x4c000000, + 0x0201f800, 0x00106dc3, 0x0201f800, 0x00106b8a, + 0x5c000000, 0x8c000516, 0x04000010, 0x592c000f, + 0x4803c857, 0x48025807, 0x41780800, 0x42028000, + 0x00000002, 0x0201f800, 0x00104e70, 0x4a025c06, + 0x0000ffff, 0x0201f800, 0x000202da, 0x0201f800, + 0x00107911, 0x0401f015, 0x4a026203, 0x00000002, + 0x592c0208, 0x8400054e, 0x48025a08, 0x59300406, + 0x82000580, 0x00000006, 0x04020009, 0x811800ca, + 0x81c80c00, 0x58040939, 0x592c000d, 0x80040480, + 0x592c080f, 0x80040480, 0x4802580b, 0x417a7800, + 0x0201f800, 0x00108be3, 0x5c028000, 0x5c027800, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x4d2c0000, + 0x59900004, 0x81300580, 0x02020800, 0x001005d8, + 0x0201f800, 0x00109037, 0x02000800, 0x001005d8, + 0x59325808, 0x592c0208, 0x84000540, 0x48025a08, + 0x0401f7bf, 0x491bc857, 0x49d3c857, 0x4dd00000, + 0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600, + 0x4a03a005, 0x80000002, 0x42000000, 0x00001000, + 0x50000000, 0x82000480, 0x24220001, 0x04020029, 0x59d01006, 0x82080500, 0x00006000, 0x82000580, - 0x00006000, 0x04000007, 0x8c08151e, 0x040007f7, - 0x59d01006, 0x82080500, 0x00006000, 0x040207f3, + 0x00006000, 0x0400002f, 0x82080500, 0x40008000, + 0x040007f8, 0x800409c0, 0x0402002a, 0x811a31c0, + 0x04000028, 0x42000000, 0x00001002, 0x50001000, + 0x46000000, 0x00000512, 0x42001800, 0x0000000a, + 0x59e00000, 0x8c00051a, 0x040207fc, 0x800c1840, + 0x040207fc, 0x42000000, 0x00001002, 0x46000000, + 0x00000514, 0x42001800, 0x0000000a, 0x59e00000, + 0x8c00053a, 0x040207fc, 0x800c1840, 0x040207fc, + 0x42000000, 0x00001002, 0x44080000, 0x0401f00d, + 0x59d01006, 0x82080500, 0x00006000, 0x82000580, + 0x00006000, 0x04000007, 0x8c08151e, 0x040007f9, + 0x59d01006, 0x82080500, 0x00006000, 0x040207f5, 0x83d3a400, 0x00000020, 0x80040800, 0x82040480, - 0x00000005, 0x040017bd, 0x5c03a000, 0x1c01f000, + 0x00000005, 0x040017bf, 0x5c03a000, 0x1c01f000, 0x491bc857, 0x49d3c857, 0x4dd00000, 0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600, 0x4a03a005, 0x80000001, 0x59d00006, 0x83d3a400, 0x00000020, @@ -1125,19 +1105,19 @@ uint32_t risc_code01[] = { 0x80204000, 0x50200000, 0x80000540, 0x04000003, 0x80285040, 0x1c01f000, 0x58300001, 0x80000540, 0x0400000e, 0x4802600b, 0x40006000, 0x58300204, - 0x82000500, 0x0000000f, 0x82000400, 0x0010110d, - 0x50004000, 0x802041c0, 0x02000800, 0x00100615, + 0x82000500, 0x0000000f, 0x82000400, 0x001010bd, + 0x50004000, 0x802041c0, 0x02000800, 0x001005d8, 0x80285040, 0x1c01f000, 0x40005000, 0x1c01f000, 0x00000005, 0x00000008, 0x0000000b, 0x0000000e, 0x00000011, 0x00000000, 0x00000000, 0x0000000b, - 0x00000000, 0x00000000, 0x00000000, 0x00101108, - 0x00101107, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00101108, 0x00101107, 0x00101104, - 0x00101108, 0x00101107, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00101108, + 0x00000000, 0x00000000, 0x00000000, 0x001010b8, + 0x001010b7, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x001010b8, 0x001010b7, 0x001010b4, + 0x001010b8, 0x001010b7, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x001010b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00101108, 0x00101108, 0x00101108, - 0x00000000, 0x00101108, 0x00000000, 0x00000000, + 0x00000000, 0x001010b8, 0x001010b8, 0x001010b8, + 0x00000000, 0x001010b8, 0x00000000, 0x00000000, 0x00000000, 0x4813c857, 0x492fc857, 0x4933c857, 0x48126012, 0x592c5207, 0x802851c0, 0x0400004a, 0x412c6000, 0x0401f84b, 0x04000009, 0x82240580, @@ -1150,34 +1130,34 @@ uint32_t risc_code01[] = { 0x80285040, 0x0400002c, 0x80204000, 0x50200000, 0x80000540, 0x0402000a, 0x58300001, 0x80006540, 0x04000025, 0x58300204, 0x82004d00, 0x0000000f, - 0x82244400, 0x0010110d, 0x50204000, 0x592c0208, + 0x82244400, 0x001010bd, 0x50204000, 0x592c0208, 0x8400051e, 0x48025a08, 0x0401f013, 0x80102080, 0x80102000, 0x48126010, 0x4813c857, 0x58080802, - 0x40100000, 0x80042480, 0x02001800, 0x00100615, + 0x40100000, 0x80042480, 0x02001800, 0x001005d8, 0x58080000, 0x58081801, 0x80102400, 0x4812600e, 0x480e600f, 0x4813c857, 0x592c0208, 0x8400055e, 0x48025a08, 0x4833c857, 0x4823c857, 0x482bc857, 0x4832600b, 0x4822600c, 0x482a600d, 0x80000580, 0x0401f003, 0x82000540, 0x00000001, 0x1c01f000, 0x58300204, 0x82004d00, 0x0000000f, 0x82244400, - 0x0010110d, 0x82000500, 0x000000ff, 0x82000580, + 0x001010bd, 0x82000500, 0x000000ff, 0x82000580, 0x00000029, 0x0402001b, 0x50204000, 0x592c0409, - 0x80000540, 0x02000800, 0x00100615, 0x82000c80, + 0x80000540, 0x02000800, 0x001005d8, 0x82000c80, 0x00000002, 0x04001011, 0x58300001, 0x80006540, - 0x02000800, 0x00100615, 0x58300204, 0x82000500, - 0x0000000f, 0x82000400, 0x0010110d, 0x50004000, + 0x02000800, 0x001005d8, 0x58300204, 0x82000500, + 0x0000000f, 0x82000400, 0x001010bd, 0x50004000, 0x40040000, 0x800409c0, 0x04000006, 0x82040c80, 0x00000005, 0x040217f1, 0x80204400, 0x80000580, 0x1c01f000, 0x59e00004, 0x8c00050e, 0x02020000, - 0x00100951, 0x1c01f000, 0x4c5c0000, 0x59e4b800, + 0x00100903, 0x1c01f000, 0x4c5c0000, 0x59e4b800, 0x485fc857, 0x825c0500, 0x0000001f, 0x04000004, - 0x59e40862, 0x0201f800, 0x00100615, 0x825c0500, - 0x000000e0, 0x02000800, 0x00100615, 0x8c5cbd0e, + 0x59e40862, 0x0201f800, 0x001005d8, 0x825c0500, + 0x000000e0, 0x02000800, 0x001005d8, 0x8c5cbd0e, 0x04020807, 0x8c5cbd0c, 0x04020809, 0x8c5cbd0a, 0x04020878, 0x5c00b800, 0x1c01f000, 0x4803c856, 0x4a03c800, 0x00000080, 0x1c01f000, 0x4d2c0000, - 0x42007800, 0x0010b6eb, 0x583c0001, 0x583c0802, - 0x80040540, 0x0400003f, 0x42000800, 0x0010b5f5, + 0x42007800, 0x0010b8ec, 0x583c0001, 0x583c0802, + 0x80040540, 0x0400003f, 0x42000800, 0x0010b7f7, 0x50065800, 0x592c0002, 0x82000580, 0x00000000, 0x0400000e, 0x59e40850, 0x59e41853, 0x400c0000, 0x80040400, 0x59e40852, 0x4807c857, 0x80041480, @@ -1190,12 +1170,12 @@ uint32_t risc_code01[] = { 0x04000007, 0x592c1007, 0x480bc857, 0x583c0003, 0x4803c857, 0x80080480, 0x04001003, 0x583c1001, 0x480bc857, 0x583c0802, 0x480bc857, 0x4807c857, - 0x4a025801, 0x00000000, 0x4a025809, 0x0010120c, + 0x4a025801, 0x00000000, 0x4a025809, 0x001011bc, 0x480a5807, 0x48065808, 0x59e40053, 0x48025804, - 0x412c1000, 0x492fc857, 0x0201f800, 0x001008a1, + 0x412c1000, 0x492fc857, 0x0201f800, 0x00100858, 0x5c025800, 0x4a03c800, 0x00000040, 0x1c01f000, - 0x42007800, 0x0010b5f5, 0x503c7800, 0x4a007802, - 0x00000100, 0x42007800, 0x0010b6eb, 0x583c0000, + 0x42007800, 0x0010b7f7, 0x503c7800, 0x4a007802, + 0x00000100, 0x42007800, 0x0010b8ec, 0x583c0000, 0x4803c857, 0x82000d80, 0x00000001, 0x04000004, 0x80000000, 0x48007800, 0x0401f019, 0x49787800, 0x583c1806, 0x583c0005, 0x800c1800, 0x480c7806, @@ -1203,73 +1183,73 @@ uint32_t risc_code01[] = { 0x800409c0, 0x0400000e, 0x583c0008, 0x80000000, 0x48007808, 0x80040580, 0x04020009, 0x49787808, 0x583c2006, 0x42001800, 0x00000001, 0x42001000, - 0x00008028, 0x0201f800, 0x00103857, 0x1c01f000, - 0x4a03c800, 0x00000020, 0x0201f800, 0x0010a867, + 0x00008028, 0x0201f800, 0x00103a3e, 0x1c01f000, + 0x4a03c800, 0x00000020, 0x0201f800, 0x0010aa40, 0x59e40000, 0x1c01f000, 0x4d2c0000, 0x4a007001, 0x00000000, 0x82040d00, 0x43000f80, 0x02020800, - 0x00100615, 0x58380009, 0x4803c00f, 0x0201f800, - 0x001091cb, 0x583a5808, 0x592c0000, 0x48007008, + 0x001005d8, 0x58380009, 0x4803c00f, 0x0201f800, + 0x00109402, 0x583a5808, 0x592c0000, 0x48007008, 0x800001c0, 0x04020002, 0x49787007, 0x0201f800, - 0x0010083a, 0x5c025800, 0x0201f000, 0x001008c6, + 0x001007f4, 0x5c025800, 0x0201f000, 0x0010087d, 0x4803c856, 0x4c3c0000, 0x4d2c0000, 0x4d300000, - 0x5830000a, 0x80025d40, 0x02000800, 0x00100615, - 0x592e6008, 0x4c300000, 0x0201f800, 0x001091e3, - 0x5c006000, 0x02000800, 0x00100615, 0x58300002, + 0x5830000a, 0x80025d40, 0x02000800, 0x001005d8, + 0x592e6008, 0x4c300000, 0x0201f800, 0x0010941a, + 0x5c006000, 0x02000800, 0x001005d8, 0x58300002, 0x82000580, 0x00000100, 0x04020010, 0x5930780b, 0x583c0001, 0x80000540, 0x0400000e, 0x4802600b, 0x40007800, 0x82000400, 0x00000002, 0x48006003, 0x583c0000, 0x48006004, 0x40301000, 0x0201f800, - 0x001008a1, 0x0401f00c, 0x4a025a06, 0x00000002, - 0x4c300000, 0x0201f800, 0x00020381, 0x5c006000, - 0x40325800, 0x0201f800, 0x0010083a, 0x0201f800, - 0x000208b4, 0x5c026000, 0x5c025800, 0x5c007800, + 0x00100858, 0x0401f00c, 0x4a025a06, 0x00000002, + 0x4c300000, 0x0201f800, 0x000202da, 0x5c006000, + 0x40325800, 0x0201f800, 0x001007f4, 0x0201f800, + 0x0002077d, 0x5c026000, 0x5c025800, 0x5c007800, 0x1c01f000, 0x4803c856, 0x4d2c0000, 0x4d300000, - 0x42007000, 0x0010b5f6, 0x58380801, 0x82040580, + 0x42007000, 0x0010b7f8, 0x58380801, 0x82040580, 0x00000002, 0x04020011, 0x58386002, 0x5830000a, 0x812c0580, 0x0402000d, 0x59e00004, 0x8c00050e, 0x040007fe, 0x59dc0006, 0x4803c857, 0x4a03b805, 0x20000000, 0x8c00053e, 0x040007f8, 0x4a007001, 0x00000000, 0x0401f019, 0x58386006, 0x40305000, - 0x803061c0, 0x02000800, 0x00100615, 0x5830000a, + 0x803061c0, 0x02000800, 0x001005d8, 0x5830000a, 0x812c0580, 0x04000004, 0x40305000, 0x58306000, 0x0401f7f8, 0x40280000, 0x80300580, 0x58300000, 0x04000006, 0x48005000, 0x800001c0, 0x04020007, 0x48287005, 0x0401f005, 0x800001c0, 0x04020002, 0x48007005, 0x48007006, 0x40325800, 0x0201f800, - 0x0010083a, 0x42007000, 0x0010b5f6, 0x58380001, - 0x82000580, 0x00000000, 0x02000800, 0x001008c6, + 0x001007f4, 0x42007000, 0x0010b7f8, 0x58380001, + 0x82000580, 0x00000000, 0x02000800, 0x0010087d, 0x5c026000, 0x5c025800, 0x1c01f000, 0x4803c856, 0x42000800, 0x0000003c, 0x48079000, 0x59c80000, 0x80040500, 0x040207fe, 0x497b9005, 0x4a039035, 0x00880200, 0x59a8000e, 0x800000e0, 0x4803900e, - 0x4a039011, 0x00000024, 0x4a03900f, 0x0010cfc0, - 0x4a039010, 0x0010cfc0, 0x4a039015, 0x0000007f, + 0x4a039011, 0x00000024, 0x4a03900f, 0x0010d1c0, + 0x4a039010, 0x0010d1c0, 0x4a039015, 0x0000007f, 0x4a03900d, 0x00000040, 0x4a039000, 0x00001600, 0x1c01f000, 0x59c80007, 0x8c000508, 0x040208b7, 0x59c80800, 0x8c040d16, 0x04020004, 0x82000500, 0x00000006, 0x0c01f005, 0x4807c857, 0x82000500, - 0x0000000e, 0x0c01f001, 0x001012f8, 0x001012f6, - 0x0010567d, 0x001012f6, 0x001012fa, 0x001012f6, - 0x001012fa, 0x001012fa, 0x001012f6, 0x001012f6, - 0x001012f6, 0x001012f6, 0x001012fa, 0x001012f6, - 0x001012fa, 0x001012f6, 0x0201f800, 0x00100615, + 0x0000000e, 0x0c01f001, 0x001012a8, 0x001012a6, + 0x00105999, 0x001012a6, 0x001012aa, 0x001012a6, + 0x001012aa, 0x001012aa, 0x001012a6, 0x001012a6, + 0x001012a6, 0x001012a6, 0x001012aa, 0x001012a6, + 0x001012aa, 0x001012a6, 0x0201f800, 0x001005d8, 0x4803c857, 0x1c01f000, 0x59c8080c, 0x4807c857, 0x82040500, 0x00006000, 0x04000004, 0x0201f800, - 0x0010a82a, 0x0401f006, 0x82040500, 0x007f0000, - 0x04000006, 0x0201f800, 0x0010a7fc, 0x0201f800, - 0x00106c07, 0x0401f02b, 0x82040500, 0x00000014, - 0x04000014, 0x0201f800, 0x0010a859, 0x836c0580, - 0x00000003, 0x0400000d, 0x0201f800, 0x00104e0d, - 0x04000004, 0x0201f800, 0x00103f37, 0x0401f007, + 0x0010aa03, 0x0401f006, 0x82040500, 0x007f0000, + 0x04000006, 0x0201f800, 0x0010a9d5, 0x0201f800, + 0x00106eb3, 0x0401f02b, 0x82040500, 0x00000014, + 0x04000014, 0x0201f800, 0x0010aa32, 0x836c0580, + 0x00000003, 0x0400000d, 0x0201f800, 0x0010513b, + 0x04000004, 0x0201f800, 0x0010411d, 0x0401f007, 0x4a035033, 0x00000001, 0x4202d800, 0x00000001, - 0x0201f800, 0x00104d76, 0x0401f817, 0x0401f015, + 0x0201f800, 0x001050a2, 0x0401f817, 0x0401f015, 0x82040500, 0x00001c00, 0x04000005, 0x0201f800, - 0x0010a838, 0x0401f810, 0x0401f00e, 0x82040500, - 0x00000140, 0x04000005, 0x0201f800, 0x0010a84b, + 0x0010aa11, 0x0401f810, 0x0401f00e, 0x82040500, + 0x00000140, 0x04000005, 0x0201f800, 0x0010aa24, 0x0401f809, 0x0401f007, 0x82040500, 0x00008000, - 0x04000004, 0x0201f800, 0x0010a823, 0x0401f802, + 0x04000004, 0x0201f800, 0x0010a9fc, 0x0401f802, 0x1c01f000, 0x4c0c0000, 0x4c100000, 0x4c140000, - 0x0201f800, 0x00100f17, 0x5c002800, 0x5c002000, + 0x0201f800, 0x00100ec9, 0x5c002800, 0x5c002000, 0x5c001800, 0x1c01f000, 0x4803c856, 0x59a80804, 0x59a8002b, 0x82000500, 0xfffff000, 0x80040540, 0x4803502b, 0x59a8002f, 0x82000500, 0xfffff000, @@ -1292,35 +1272,35 @@ uint32_t risc_code01[] = { 0x801020c2, 0x82100480, 0x00000110, 0x80000080, 0x80002000, 0x800800d0, 0x80140540, 0x80100540, 0x48039035, 0x1c01f000, 0x59c80815, 0x0201f800, - 0x0010060d, 0x82040d00, 0x0000007c, 0x48079000, + 0x001005d0, 0x82040d00, 0x0000007c, 0x48079000, 0x59c80000, 0x80040500, 0x040207fe, 0x8c040d04, 0x04000003, 0x59c80035, 0x48039035, 0x59c80000, 0x82000540, 0x00001200, 0x48039000, 0x1c01f000, 0x4803c856, 0x497b88a9, 0x4a038807, 0x00000001, 0x497b8807, 0x59c40005, 0x48038805, 0x0201f800, - 0x00101886, 0x4201d000, 0x000001f4, 0x0201f800, - 0x00105dd2, 0x497b880e, 0x4200b000, 0x000001f4, + 0x00101815, 0x4201d000, 0x000001f4, 0x0201f800, + 0x0010608e, 0x497b880e, 0x4200b000, 0x000001f4, 0x42000000, 0x00000001, 0x42000800, 0x00000014, - 0x0201f800, 0x001019b1, 0x42000800, 0x00000014, - 0x0201f800, 0x001019ac, 0x8c040d00, 0x04000005, - 0x8058b040, 0x040207f3, 0x0201f800, 0x00100615, + 0x0201f800, 0x00101944, 0x42000800, 0x00000014, + 0x0201f800, 0x0010193f, 0x8c040d00, 0x04000005, + 0x8058b040, 0x040207f3, 0x0201f800, 0x001005d8, 0x4200b000, 0x00000032, 0x42000000, 0x00000001, - 0x42000800, 0x000000b4, 0x0201f800, 0x001019b1, - 0x42000800, 0x000000b4, 0x0201f800, 0x001019ac, + 0x42000800, 0x000000b4, 0x0201f800, 0x00101944, + 0x42000800, 0x000000b4, 0x0201f800, 0x0010193f, 0x8c040d00, 0x04000005, 0x8058b040, 0x040207f3, - 0x0201f800, 0x00100615, 0x59c40005, 0x48038805, + 0x0201f800, 0x001005d8, 0x59c40005, 0x48038805, 0x42000000, 0x00000089, 0x800008d0, 0x48075054, 0x48075055, 0x48075056, 0x42000800, 0x000000e0, - 0x0201f800, 0x001019b1, 0x42000800, 0x000000f4, - 0x0201f800, 0x001019ac, 0x82040500, 0xffffffd1, + 0x0201f800, 0x00101944, 0x42000800, 0x000000f4, + 0x0201f800, 0x0010193f, 0x82040500, 0xffffffd1, 0x82000540, 0x00000002, 0x42000800, 0x000000f4, - 0x0201f800, 0x001019b1, 0x42000800, 0x000000a0, - 0x0201f800, 0x001019ac, 0x82040540, 0x00000001, - 0x42000800, 0x000000a0, 0x0201f800, 0x001019b1, - 0x42000800, 0x00000000, 0x0201f800, 0x001019ac, + 0x0201f800, 0x00101944, 0x42000800, 0x000000a0, + 0x0201f800, 0x0010193f, 0x82040540, 0x00000001, + 0x42000800, 0x000000a0, 0x0201f800, 0x00101944, + 0x42000800, 0x00000000, 0x0201f800, 0x0010193f, 0x82040540, 0x00000001, 0x42000800, 0x00000000, - 0x0201f800, 0x001019b1, 0x4201d000, 0x0001d4c0, - 0x0201f800, 0x00105dd2, 0x0401fa45, 0x4a0388a7, + 0x0201f800, 0x00101944, 0x4201d000, 0x0001d4c0, + 0x0201f800, 0x0010608e, 0x0401fa2b, 0x4a0388a7, 0x0000f7f7, 0x4a0388a3, 0x8000403c, 0x4a0388ae, 0x000061a8, 0x4a038801, 0x00032063, 0x4a038810, 0x00410108, 0x4a038811, 0x00520608, 0x4a038812, @@ -1335,2101 +1315,2246 @@ uint32_t risc_code01[] = { 0x4a0388a6, 0x0000001e, 0x4a0388b0, 0x00007530, 0x4a038802, 0x0000ffff, 0x4a038806, 0xc0e00800, 0x1c01f000, 0x497b5022, 0x4a035021, 0x00000001, - 0x42000800, 0x00000040, 0x0201f800, 0x001019ac, + 0x42000800, 0x00000040, 0x0201f800, 0x0010193f, 0x82040500, 0xffffffaf, 0x82000540, 0x00000000, - 0x42000800, 0x00000040, 0x0201f800, 0x001019b1, - 0x42000800, 0x000000f4, 0x0201f800, 0x001019ac, + 0x42000800, 0x00000040, 0x0201f800, 0x00101944, + 0x42000800, 0x000000f4, 0x0201f800, 0x0010193f, 0x4c040000, 0x40040000, 0x84000548, 0x42000800, - 0x000000f4, 0x0201f800, 0x001019b1, 0x42000800, - 0x00000000, 0x0201f800, 0x001019ac, 0x82040500, + 0x000000f4, 0x0201f800, 0x00101944, 0x42000800, + 0x00000000, 0x0201f800, 0x0010193f, 0x82040500, 0xffffffc1, 0x82000540, 0x00000038, 0x42000800, - 0x00000000, 0x0201f800, 0x001019b1, 0x5c000000, - 0x42000800, 0x000000f4, 0x0201f000, 0x001019b1, - 0x59c40805, 0x59c40006, 0x80040d00, 0x02000800, - 0x00100615, 0x82040500, 0x00e00800, 0x04020004, - 0x8c040d3e, 0x040208df, 0x0401f007, 0x82040500, - 0x00800800, 0x02020800, 0x0010060d, 0x0201f800, - 0x00100615, 0x4c5c0000, 0x4c600000, 0x59c4b805, - 0x59c40006, 0x8c000500, 0x04000003, 0x8c5cbd00, - 0x04020095, 0x485fc857, 0x0201f800, 0x00104e0d, - 0x0400001e, 0x59c40005, 0x82000500, 0x000000c0, - 0x0400004b, 0x0201f800, 0x00104e23, 0x04020048, - 0x59c40006, 0x82000500, 0x000000f0, 0x04020004, - 0x4a038805, 0x000000c0, 0x0401f041, 0x59a80015, - 0x84000506, 0x48035015, 0x42006000, 0xff203fff, - 0x42006800, 0x40000000, 0x0201f800, 0x001040ad, - 0x42000800, 0x00000010, 0x42001000, 0x00104020, - 0x0201f800, 0x00105dc7, 0x8c5cbd34, 0x04020030, - 0x4a035032, 0x0000aaaa, 0x59c40005, 0x8c00050c, - 0x04020012, 0x8c00050e, 0x0402001c, 0x8c00050a, - 0x0402001d, 0x8c000508, 0x0400000b, 0x59a80017, - 0x82000580, 0x00000009, 0x04020007, 0x42000000, - 0x0010b642, 0x0201f800, 0x0010a86e, 0x0201f800, - 0x00104fe9, 0x0401f05a, 0x0201f800, 0x00104e23, - 0x04020007, 0x42000800, 0x0000000f, 0x42001000, - 0x00103f37, 0x0201f800, 0x00105da7, 0x4a035033, + 0x00000000, 0x0201f800, 0x00101944, 0x5c000000, + 0x42000800, 0x000000f4, 0x0201f000, 0x00101944, + 0x59c40805, 0x4807c857, 0x59c40006, 0x80040d00, + 0x02000800, 0x001005d8, 0x82040500, 0x00e00800, + 0x04020004, 0x8c040d3e, 0x040208c4, 0x0401f007, + 0x82040500, 0x00800800, 0x02020800, 0x001005d0, + 0x0201f800, 0x001005d8, 0x4c5c0000, 0x4c600000, + 0x59c4b805, 0x485fc857, 0x59c40006, 0x8c000500, + 0x04000003, 0x8c5cbd00, 0x04020079, 0x0201f800, + 0x0010513b, 0x04000014, 0x59c40005, 0x82000500, + 0x000000c0, 0x04000036, 0x0201f800, 0x00105151, + 0x04020033, 0x4a038805, 0x04000000, 0x59c400a3, + 0x82000500, 0xbf203fff, 0x480388a3, 0x497b5049, + 0x4a038805, 0x000000c0, 0x0201f800, 0x00105065, + 0x0401f063, 0x8c5cbd34, 0x04020025, 0x59c40005, + 0x8c00050c, 0x04020012, 0x8c00050e, 0x04020013, + 0x8c00050a, 0x04020014, 0x8c000508, 0x0400000b, + 0x59a80017, 0x82000580, 0x00000009, 0x04020007, + 0x42000000, 0x0010b844, 0x0201f800, 0x0010aa47, + 0x0201f800, 0x00105318, 0x0401f04b, 0x4a035033, 0x00000000, 0x0401f00b, 0x4a035033, 0x00000002, - 0x0401f008, 0x42000000, 0x0010b644, 0x0201f800, - 0x0010a86e, 0x0201f800, 0x00104f93, 0x0401f044, - 0x0201f800, 0x00105049, 0x0401f041, 0x8c5cbd34, - 0x0400003d, 0x59c40005, 0x8c00053a, 0x04020005, - 0x42000000, 0x0010b616, 0x0201f800, 0x0010a86e, - 0x4a038805, 0x02000000, 0x0201f800, 0x00104e0d, + 0x0401f008, 0x42000000, 0x0010b846, 0x0201f800, + 0x0010aa47, 0x0201f800, 0x001052c2, 0x0401f03e, + 0x0201f800, 0x00105378, 0x0401f03b, 0x8c5cbd34, + 0x04000037, 0x59c40005, 0x8c00053a, 0x04020005, + 0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47, + 0x4a038805, 0x02000000, 0x0201f800, 0x0010513b, 0x04020010, 0x4a038805, 0x04000000, 0x0201f800, - 0x00104e1b, 0x04020008, 0x4a035033, 0x00000001, - 0x4202d800, 0x00000001, 0x0201f800, 0x00104d76, - 0x0401f061, 0x41780000, 0x0201f800, 0x00104de5, - 0x0201f800, 0x00101a59, 0x4000c000, 0x0201f800, - 0x001019d0, 0x836c1580, 0x00000004, 0x0402000d, - 0x8c5cbd00, 0x04020018, 0x59a81005, 0x8c081506, + 0x00105149, 0x04020008, 0x4a035033, 0x00000001, + 0x4202d800, 0x00000001, 0x0201f800, 0x001050a2, + 0x0401f05b, 0x41780000, 0x0201f800, 0x00105113, + 0x0201f800, 0x001019fe, 0x4000c000, 0x0201f800, + 0x00101963, 0x836c1580, 0x00000004, 0x0402000d, + 0x8c5cbd00, 0x04020012, 0x59a81005, 0x8c081506, 0x04020005, 0x59c410a3, 0x82081540, 0x00000008, 0x480b88a3, 0x59c41006, 0x84081540, 0x480b8806, 0x4a038805, 0x04000000, 0x4202d800, 0x00000001, - 0x497b5014, 0x59a80005, 0x8c000518, 0x04020004, - 0x0401f95c, 0x0201f800, 0x00103f5c, 0x0201f800, - 0x00103951, 0x8c5cbd3c, 0x04020858, 0x8c5cbd00, - 0x04000036, 0x42000000, 0x0010b6c9, 0x0201f800, - 0x0010a86e, 0x4a038805, 0x00000001, 0x4200b000, - 0x00000352, 0x4201d000, 0x00000064, 0x4c580000, - 0x0201f800, 0x00105dd2, 0x0201f800, 0x00101941, - 0x5c00b000, 0x04000004, 0x8058b040, 0x040207f6, - 0x0401f004, 0x4a038805, 0x00000001, 0x0401f01f, - 0x59c40006, 0x84000500, 0x48038806, 0x0201f800, - 0x00106c32, 0x497b8880, 0x0201f800, 0x0010a7e7, - 0x59c4000d, 0x8c000500, 0x02020800, 0x0010a7f5, - 0x59c400a3, 0x82000500, 0xfcf8ffff, 0x480388a3, - 0x4a03504c, 0x00000002, 0x4202d800, 0x00000004, - 0x4a038805, 0x00000001, 0x0201f800, 0x0010071a, - 0x0401fb42, 0x497b5052, 0x4a035049, 0x00000001, - 0x0201f800, 0x0010048c, 0x825cbd00, 0xbbfffffe, - 0x485f8805, 0x5c00c000, 0x5c00b800, 0x1c01f000, - 0x59c41004, 0x480bc857, 0x8c081500, 0x04000006, - 0x4803c856, 0x497b2807, 0x0201f800, 0x00106cf9, - 0x0401f00a, 0x82080500, 0x000001f0, 0x04000007, - 0x4803c856, 0x417a3000, 0x0201f800, 0x00105d9b, - 0x0201f800, 0x00106d1b, 0x4a038805, 0x80000000, - 0x1c01f000, 0x59c408a3, 0x4807c857, 0x84040d40, - 0x480788a3, 0x1c01f000, 0x4d900000, 0x4dd00000, - 0x4da40000, 0x4d140000, 0x4a038805, 0x40000000, - 0x42000000, 0x0010b6c5, 0x0201f800, 0x0010a86e, - 0x0201f800, 0x0010698c, 0x59c41004, 0x8c081500, - 0x04000054, 0x598e600d, 0x497b2807, 0x813261c0, - 0x04000032, 0x59300403, 0x82000580, 0x00000032, - 0x0402002e, 0x5930001c, 0x48038833, 0x4a038807, - 0x00018000, 0x4201d000, 0x00000002, 0x0201f800, - 0x00105dd2, 0x497b8807, 0x4201d000, 0x00000002, - 0x0201f800, 0x00105dd2, 0x0201f800, 0x00106b71, - 0x4201d000, 0x00007530, 0x0201f800, 0x00105dd2, - 0x59c408a4, 0x82040d00, 0x0000000f, 0x82040d80, - 0x00000000, 0x04000005, 0x42000000, 0x00200000, - 0x0201f800, 0x001019b6, 0x0201f800, 0x001068f6, - 0x59300008, 0x80000540, 0x02000800, 0x00100615, - 0x40025800, 0x4a025a04, 0x00000103, 0x5931d821, - 0x58ef400b, 0x58ec0009, 0x0801f800, 0x0201f800, - 0x000208b4, 0x0401f047, 0x598c000f, 0x82001c80, - 0x000000c8, 0x0402100f, 0x80000000, 0x4803180f, - 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, - 0x00000002, 0x04020004, 0x42000000, 0x00200000, - 0x0401fbfa, 0x0201f800, 0x00105d86, 0x0401f035, - 0x4933c857, 0x0201f800, 0x00106b71, 0x813261c0, - 0x04000030, 0x4a026203, 0x00000001, 0x42027000, - 0x00000027, 0x0201f800, 0x000208d8, 0x0401f029, - 0x8c081508, 0x04000027, 0x417a3000, 0x0201f800, - 0x00106e2f, 0x42032000, 0x0000bf32, 0x0201f800, - 0x00105d9b, 0x59926004, 0x813261c0, 0x04000012, - 0x42001800, 0x000000c8, 0x0201f800, 0x00106dfb, - 0x0402000d, 0x59c400a4, 0x82000500, 0x0000000f, - 0x82000580, 0x00000002, 0x04020004, 0x42000000, - 0x00200000, 0x0401fbd1, 0x0201f800, 0x00105d8b, - 0x0401f00c, 0x4933c857, 0x0201f800, 0x00106b13, - 0x813261c0, 0x04000007, 0x42027000, 0x0000004f, - 0x4a026203, 0x00000003, 0x0201f800, 0x000208d8, - 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, - 0x0201f000, 0x00106982, 0x4803c857, 0x59a80821, - 0x48035021, 0x80041580, 0x04000045, 0x800409c0, - 0x04000023, 0x497b504c, 0x42000000, 0x0010b60b, - 0x0201f800, 0x0010a86e, 0x0201f800, 0x0010a920, - 0x42001000, 0x00008011, 0x59c40001, 0x82000500, - 0x00018000, 0x82001d80, 0x00000000, 0x04000009, - 0x82001d80, 0x00008000, 0x04000009, 0x82001d80, - 0x00010000, 0x04000009, 0x0201f800, 0x00100615, - 0x42001800, 0x00000000, 0x0401f006, 0x42001800, - 0x00000001, 0x0401f003, 0x42001800, 0x00000003, - 0x0201f800, 0x00103857, 0x0401f021, 0x59a8084c, - 0x800409c0, 0x04020007, 0x59c4000d, 0x8c000520, - 0x04000004, 0x42001800, 0x00000003, 0x0401f002, - 0x40041800, 0x0201f800, 0x0010a904, 0x42001000, - 0x00008012, 0x0201f800, 0x00103857, 0x0201f800, - 0x0010071a, 0x0201f800, 0x0010a95a, 0x0402000c, - 0x0401f853, 0x4d400000, 0x4d3c0000, 0x42028000, - 0x00000028, 0x42027800, 0x00000008, 0x0201f800, - 0x00101d90, 0x5c027800, 0x5c028000, 0x1c01f000, - 0x4803c857, 0x82000400, 0x00101eb5, 0x50000800, - 0x82040d00, 0x000000ff, 0x1c01f000, 0x4803c856, - 0x4c580000, 0x4200b000, 0x00000010, 0x497b88ac, - 0x497b88ad, 0x8058b040, 0x040207fe, 0x5c00b000, - 0x1c01f000, 0x4807c857, 0x48075010, 0x80041108, - 0x4200b000, 0x00000010, 0x497b88ac, 0x80000580, - 0x800811c0, 0x04020006, 0x82040500, 0x0000000f, - 0x82000400, 0x0010a95f, 0x50000000, 0x480388ad, - 0x80081040, 0x8058b040, 0x040207f5, 0x1c01f000, - 0x59a80005, 0x04000003, 0x84000546, 0x0401f002, - 0x84000506, 0x48035005, 0x4803c857, 0x1c01f000, - 0x4803c857, 0x4c080000, 0x4c040000, 0x4c000000, - 0x59c40892, 0x4807c857, 0x80041580, 0x04000010, - 0x80041480, 0x04021007, 0x80081080, 0x80081000, - 0x4008b000, 0x42000000, 0x00000201, 0x0401f004, - 0x4008b000, 0x42000000, 0x00000210, 0x48038886, - 0x8058b040, 0x040207fe, 0x497b8886, 0x5c000000, - 0x5c000800, 0x5c001000, 0x1c01f000, 0x4803c856, - 0x0201f800, 0x0010393e, 0x04000005, 0x42028000, - 0x0000002e, 0x0201f000, 0x0010a25b, 0x1c01f000, - 0x59a8086f, 0x82040500, 0x00000010, 0x04000004, - 0x42000800, 0x00000002, 0x0401f010, 0x82040500, - 0x00000020, 0x42000800, 0x00000002, 0x0402000b, - 0x59c80835, 0x82040d00, 0x00001f00, 0x80040910, - 0x80040800, 0x59a8006c, 0x80000540, 0x04000003, - 0x42000800, 0x0000025a, 0x4807c857, 0x1c01f000, - 0x4c000000, 0x59a80053, 0x4803c857, 0x82000580, - 0x00000000, 0x5c000000, 0x1c01f000, 0x4c000000, - 0x59a80053, 0x4803c857, 0x82000580, 0x00000001, + 0x497b5014, 0x0201f800, 0x00103b38, 0x8c5cbd3c, + 0x04020858, 0x8c5cbd00, 0x04000036, 0x42000000, + 0x0010b8ca, 0x0201f800, 0x0010aa47, 0x4a038805, + 0x00000001, 0x4200b000, 0x000003e8, 0x4201d000, + 0x00000064, 0x4c580000, 0x0201f800, 0x0010608e, + 0x0201f800, 0x001018d3, 0x5c00b000, 0x04000004, + 0x8058b040, 0x040207f6, 0x0401f004, 0x4a038805, + 0x00000001, 0x0401f01f, 0x59c40006, 0x84000500, + 0x48038806, 0x0201f800, 0x00106ede, 0x497b8880, + 0x0201f800, 0x0010a9c0, 0x59c4000d, 0x8c000500, + 0x02020800, 0x0010a9ce, 0x59c400a3, 0x82000500, + 0xfcf8ffff, 0x480388a3, 0x4a03504c, 0x00000002, + 0x4202d800, 0x00000004, 0x4a038805, 0x00000001, + 0x0201f800, 0x001006d4, 0x0401fb3b, 0x497b5052, + 0x4a035049, 0x00000001, 0x0201f800, 0x00100452, + 0x825cbd00, 0xbbfffffe, 0x485f8805, 0x5c00c000, + 0x5c00b800, 0x1c01f000, 0x59c41004, 0x480bc857, + 0x8c081500, 0x04000006, 0x4803c856, 0x497b2807, + 0x0201f800, 0x00106fa4, 0x0401f00a, 0x82080500, + 0x000001f0, 0x04000007, 0x4803c856, 0x417a3000, + 0x0201f800, 0x00106062, 0x0201f800, 0x00106fc6, + 0x4a038805, 0x80000000, 0x1c01f000, 0x59c408a3, + 0x4807c857, 0x84040d40, 0x480788a3, 0x1c01f000, + 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, + 0x4a038805, 0x40000000, 0x42000000, 0x0010b8c6, + 0x0201f800, 0x0010aa47, 0x0201f800, 0x00106c55, + 0x59c41004, 0x8c081500, 0x04000054, 0x598e600d, + 0x497b2807, 0x813261c0, 0x04000032, 0x59300403, + 0x82000580, 0x00000032, 0x0402002e, 0x5930001c, + 0x48038833, 0x4a038807, 0x00018000, 0x4201d000, + 0x00000002, 0x0201f800, 0x0010608e, 0x497b8807, + 0x4201d000, 0x00000002, 0x0201f800, 0x0010608e, + 0x0201f800, 0x00106e21, 0x4201d000, 0x00007530, + 0x0201f800, 0x0010608e, 0x59c408a4, 0x82040d00, + 0x0000000f, 0x82040d80, 0x00000000, 0x04000005, + 0x42000000, 0x00200000, 0x0201f800, 0x00101949, + 0x0201f800, 0x00106bbf, 0x59300008, 0x80000540, + 0x02000800, 0x001005d8, 0x40025800, 0x4a025a04, + 0x00000103, 0x5931d821, 0x58ef400b, 0x58ec0009, + 0x0801f800, 0x0201f800, 0x0002077d, 0x0401f047, + 0x598c000f, 0x82001c80, 0x000000c8, 0x0402100f, + 0x80000000, 0x4803180f, 0x59c400a4, 0x82000500, + 0x0000000f, 0x82000580, 0x00000002, 0x04020004, + 0x42000000, 0x00200000, 0x0401fbf7, 0x0201f800, + 0x0010604d, 0x0401f035, 0x4933c857, 0x0201f800, + 0x00106e21, 0x813261c0, 0x04000030, 0x4a026203, + 0x00000001, 0x42027000, 0x00000027, 0x0201f800, + 0x000207a1, 0x0401f029, 0x8c081508, 0x04000027, + 0x417a3000, 0x0201f800, 0x001070d8, 0x42032000, + 0x0000bf32, 0x0201f800, 0x00106062, 0x59926004, + 0x813261c0, 0x04000012, 0x42001800, 0x000000c8, + 0x0201f800, 0x001070a4, 0x0402000d, 0x59c400a4, + 0x82000500, 0x0000000f, 0x82000580, 0x00000002, + 0x04020004, 0x42000000, 0x00200000, 0x0401fbce, + 0x0201f800, 0x00106052, 0x0401f00c, 0x4933c857, + 0x0201f800, 0x00106dc3, 0x813261c0, 0x04000007, + 0x42027000, 0x0000004f, 0x4a026203, 0x00000003, + 0x0201f800, 0x000207a1, 0x5c022800, 0x5c034800, + 0x5c03a000, 0x5c032000, 0x0201f000, 0x00106c4b, + 0x4803c857, 0x59a80821, 0x48035021, 0x80041580, + 0x04000045, 0x800409c0, 0x04000023, 0x497b504c, + 0x42000000, 0x0010b80d, 0x0201f800, 0x0010aa47, + 0x0201f800, 0x0010aaf9, 0x42001000, 0x00008011, + 0x59c40001, 0x82000500, 0x00018000, 0x82001d80, + 0x00000000, 0x04000009, 0x82001d80, 0x00008000, + 0x04000009, 0x82001d80, 0x00010000, 0x04000009, + 0x0201f800, 0x001005d8, 0x42001800, 0x00000000, + 0x0401f006, 0x42001800, 0x00000001, 0x0401f003, + 0x42001800, 0x00000003, 0x0201f800, 0x00103a3e, + 0x0401f021, 0x59a8084c, 0x800409c0, 0x04020007, + 0x59c4000d, 0x8c000520, 0x04000004, 0x42001800, + 0x00000003, 0x0401f002, 0x40041800, 0x0201f800, + 0x0010aadd, 0x42001000, 0x00008012, 0x0201f800, + 0x00103a3e, 0x0201f800, 0x001006d4, 0x0201f800, + 0x0010ab33, 0x0402000c, 0x0401f853, 0x4d400000, + 0x4d3c0000, 0x42028000, 0x00000028, 0x42027800, + 0x00000408, 0x0201f800, 0x00101fe5, 0x5c027800, + 0x5c028000, 0x1c01f000, 0x4803c857, 0x82000400, + 0x0010210e, 0x50000800, 0x82040d00, 0x000000ff, + 0x1c01f000, 0x4803c856, 0x4c580000, 0x4200b000, + 0x00000010, 0x497b88ac, 0x497b88ad, 0x8058b040, + 0x040207fe, 0x5c00b000, 0x1c01f000, 0x4807c857, + 0x48075010, 0x80041108, 0x4200b000, 0x00000010, + 0x497b88ac, 0x80000580, 0x800811c0, 0x04020006, + 0x82040500, 0x0000000f, 0x82000400, 0x0010ab38, + 0x50000000, 0x480388ad, 0x80081040, 0x8058b040, + 0x040207f5, 0x1c01f000, 0x59a80005, 0x04000003, + 0x84000546, 0x0401f002, 0x84000506, 0x48035005, + 0x4803c857, 0x1c01f000, 0x4803c857, 0x4c080000, + 0x4c040000, 0x4c000000, 0x59c40892, 0x4807c857, + 0x80041580, 0x04000010, 0x80041480, 0x04021007, + 0x80081080, 0x80081000, 0x4008b000, 0x42000000, + 0x00000201, 0x0401f004, 0x4008b000, 0x42000000, + 0x00000210, 0x48038886, 0x8058b040, 0x040207fe, + 0x497b8886, 0x5c000000, 0x5c000800, 0x5c001000, + 0x1c01f000, 0x4803c856, 0x0201f800, 0x00103b25, + 0x04000005, 0x42028000, 0x0000002e, 0x0201f000, + 0x0010a449, 0x1c01f000, 0x42000800, 0x00000002, + 0x59a80005, 0x8c000514, 0x0402000b, 0x59c80835, + 0x82040d00, 0x00001f00, 0x80040910, 0x80040800, + 0x59a8006c, 0x80000540, 0x04000003, 0x42000800, + 0x0000025a, 0x4807c857, 0x1c01f000, 0x4c000000, + 0x59a80053, 0x4803c857, 0x82000580, 0x00000000, 0x5c000000, 0x1c01f000, 0x4c000000, 0x59a80053, - 0x4803c857, 0x82000580, 0x00000003, 0x5c000000, - 0x1c01f000, 0x4c000000, 0x59a80053, 0x82000580, - 0x00000002, 0x5c000000, 0x1c01f000, 0x4c000000, - 0x4c040000, 0x4c080000, 0x4c380000, 0x59a80040, - 0x82000c80, 0x00000007, 0x02021800, 0x00100615, - 0x0c01f806, 0x5c007000, 0x5c001000, 0x5c000800, - 0x5c000000, 0x1c01f000, 0x001016dd, 0x001016f0, - 0x00101704, 0x00101706, 0x0010172d, 0x0010172f, - 0x00101731, 0x4803c856, 0x4a035042, 0x00000000, - 0x42000000, 0x00000002, 0x0401fa18, 0x42000000, - 0x00000002, 0x0401f9ad, 0x0401faae, 0x4803c856, - 0x4a035040, 0x00000006, 0x42000800, 0x0000001e, - 0x42001000, 0x00101732, 0x0201f000, 0x00105da7, - 0x497b5045, 0x4a035050, 0x00000036, 0x4a03504f, - 0x0000002a, 0x4803c856, 0x4a035042, 0x00000001, - 0x42000000, 0x00000002, 0x0401f998, 0x4803c856, + 0x4803c857, 0x82000580, 0x00000001, 0x5c000000, + 0x1c01f000, 0x4c000000, 0x59a80053, 0x4803c857, + 0x82000580, 0x00000003, 0x5c000000, 0x1c01f000, + 0x4c000000, 0x59a80053, 0x82000580, 0x00000002, + 0x5c000000, 0x1c01f000, 0x4c000000, 0x4c040000, + 0x4c080000, 0x4c380000, 0x59a80040, 0x82000c80, + 0x00000007, 0x02021800, 0x001005d8, 0x0c01f806, + 0x5c007000, 0x5c001000, 0x5c000800, 0x5c000000, + 0x1c01f000, 0x0010166c, 0x0010167f, 0x00101693, + 0x00101695, 0x001016bc, 0x001016be, 0x001016c0, + 0x4803c856, 0x4a035042, 0x00000000, 0x42000000, + 0x00000002, 0x0401fa1b, 0x42000000, 0x00000002, + 0x0401f9ad, 0x0401fab2, 0x4803c856, 0x4a035040, + 0x00000006, 0x42000800, 0x0000001e, 0x42001000, + 0x001016c1, 0x0201f000, 0x0010606e, 0x497b5045, + 0x4a035050, 0x00000036, 0x4a03504f, 0x0000002a, + 0x4803c856, 0x4a035042, 0x00000001, 0x42000000, + 0x00000002, 0x0401f998, 0x4803c856, 0x4a035040, + 0x00000006, 0x42000800, 0x0000001e, 0x42001000, + 0x001016c1, 0x0201f000, 0x0010606e, 0x0201f800, + 0x001005d8, 0x4a035050, 0x00000036, 0x4803c856, + 0x4a035042, 0x00000003, 0x42000800, 0x00000000, + 0x0401faa3, 0x82040d00, 0x00000090, 0x82040580, + 0x00000090, 0x04000009, 0x82040580, 0x00000010, + 0x04000009, 0x82040580, 0x00000000, 0x04000008, + 0x0201f800, 0x001005d8, 0x42000000, 0x00000001, + 0x0401f005, 0x41780000, 0x0401f003, 0x42000000, + 0x00000002, 0x0401f970, 0x497b5046, 0x4803c856, 0x4a035040, 0x00000006, 0x42000800, 0x0000001e, - 0x42001000, 0x00101732, 0x0201f000, 0x00105da7, - 0x0201f800, 0x00100615, 0x4a035050, 0x00000036, - 0x4803c856, 0x4a035042, 0x00000003, 0x42000800, - 0x00000000, 0x0401fa9f, 0x82040d00, 0x00000090, + 0x42001000, 0x001016c1, 0x0201f000, 0x0010606e, + 0x0201f800, 0x001005d8, 0x0201f800, 0x001005d8, + 0x1c01f000, 0x4c000000, 0x4c040000, 0x4c080000, + 0x4c380000, 0x59a80042, 0x82000c80, 0x00000007, + 0x02021800, 0x001005d8, 0x0c01f806, 0x5c007000, + 0x5c001000, 0x5c000800, 0x5c000000, 0x1c01f000, + 0x001016d7, 0x001016f6, 0x0010174a, 0x00101761, + 0x00101778, 0x00101781, 0x00101783, 0x0401f9fc, + 0x0402001b, 0x59a81048, 0x42000800, 0x00000000, + 0x0401fa63, 0x82040d00, 0x00000090, 0x82040580, + 0x00000090, 0x04000009, 0x82040580, 0x00000010, + 0x04000008, 0x82040580, 0x00000000, 0x04000007, + 0x0201f800, 0x001005d8, 0x84081540, 0x0401f004, + 0x84081542, 0x0401f002, 0x84081544, 0x480b5048, + 0x4a035040, 0x00000001, 0x0401f003, 0x0401f8cb, + 0x0401ff82, 0x1c01f000, 0x0401f88f, 0x04000052, + 0x0401f9db, 0x0402002a, 0x42000800, 0x00000000, + 0x0401fa43, 0x82040d00, 0x00000090, 0x82040580, + 0x00000000, 0x04000044, 0x82040580, 0x00000010, + 0x04000006, 0x82040580, 0x00000090, 0x04000009, + 0x0201f800, 0x001005d8, 0x59c40801, 0x82040d00, + 0x00018000, 0x82040580, 0x00000000, 0x04000036, + 0x42000800, 0x00000000, 0x0401fa2d, 0x82040d00, + 0x00000090, 0x82040580, 0x00000010, 0x04000006, + 0x82040580, 0x00000090, 0x04000006, 0x02020800, + 0x001005d8, 0x59a80048, 0x84000542, 0x0401f003, + 0x59a80048, 0x84000540, 0x48035048, 0x59a80045, + 0x80000000, 0x48035045, 0x82000580, 0x00000005, + 0x04000003, 0x0401f861, 0x0401f01e, 0x497b5045, + 0x59c40801, 0x82040d00, 0x00018000, 0x82040580, + 0x00000000, 0x04000009, 0x82040580, 0x00008000, + 0x04000009, 0x82040580, 0x00010000, 0x04000008, + 0x0201f800, 0x001005d8, 0x42000000, 0x00000001, + 0x0401f005, 0x41780000, 0x0401f003, 0x42000000, + 0x00000002, 0x0401f94b, 0x4a035042, 0x00000002, + 0x0401f004, 0x4a035040, 0x00000003, 0x0401f002, + 0x0401ff42, 0x1c01f000, 0x0401f83b, 0x04000015, + 0x59a8004f, 0x80000040, 0x4803504f, 0x0401f984, + 0x04020005, 0x4a035040, 0x00000003, 0x497b5041, + 0x0401f00c, 0x59a8004f, 0x80000540, 0x04020003, + 0x0401f89e, 0x0401f002, 0x0401f84b, 0x0401f82f, + 0x497b5045, 0x4a035042, 0x00000001, 0x0401ff2b, + 0x1c01f000, 0x0401f824, 0x04000015, 0x0401f970, + 0x0402000f, 0x59a80046, 0x80000000, 0x48035046, + 0x82000580, 0x00000007, 0x0402000c, 0x4a035052, + 0x0000000a, 0x497b5049, 0x59a80048, 0x8400055e, + 0x48035048, 0x4803c857, 0x0401f005, 0x0401f817, + 0x4a035042, 0x00000004, 0x0401ff3d, 0x1c01f000, + 0x0401f80d, 0x04000007, 0x0401f959, 0x04020003, + 0x0401ff1b, 0x0401f003, 0x0401f80c, 0x0401ff34, + 0x1c01f000, 0x0201f800, 0x001005d8, 0x0201f800, + 0x001005d8, 0x59a80050, 0x80000040, 0x48035050, + 0x0400088d, 0x1c01f000, 0x4c040000, 0x42000800, + 0x00000000, 0x0401f9b2, 0x82040d00, 0x00000090, 0x82040580, 0x00000090, 0x04000009, 0x82040580, 0x00000010, 0x04000009, 0x82040580, 0x00000000, - 0x04000008, 0x0201f800, 0x00100615, 0x42000000, - 0x00000001, 0x0401f005, 0x41780000, 0x0401f003, - 0x42000000, 0x00000002, 0x0401f970, 0x497b5046, - 0x4803c856, 0x4a035040, 0x00000006, 0x42000800, - 0x0000001e, 0x42001000, 0x00101732, 0x0201f000, - 0x00105da7, 0x0201f800, 0x00100615, 0x0201f800, - 0x00100615, 0x1c01f000, 0x4c000000, 0x4c040000, - 0x4c080000, 0x4c380000, 0x59a80042, 0x82000c80, - 0x00000007, 0x02021800, 0x00100615, 0x0c01f806, - 0x5c007000, 0x5c001000, 0x5c000800, 0x5c000000, - 0x1c01f000, 0x00101748, 0x00101767, 0x001017bb, - 0x001017d2, 0x001017e9, 0x001017f2, 0x001017f4, - 0x0401f9f9, 0x0402001b, 0x59a81048, 0x42000800, - 0x00000000, 0x0401fa5f, 0x82040d00, 0x00000090, - 0x82040580, 0x00000090, 0x04000009, 0x82040580, - 0x00000010, 0x04000008, 0x82040580, 0x00000000, - 0x04000007, 0x0201f800, 0x00100615, 0x84081540, - 0x0401f004, 0x84081542, 0x0401f002, 0x84081544, - 0x480b5048, 0x4a035040, 0x00000001, 0x0401f003, - 0x0401f8cb, 0x0401ff82, 0x1c01f000, 0x0401f88f, - 0x04000052, 0x0401f9d8, 0x0402002a, 0x42000800, - 0x00000000, 0x0401fa3f, 0x82040d00, 0x00000090, - 0x82040580, 0x00000000, 0x04000044, 0x82040580, - 0x00000010, 0x04000006, 0x82040580, 0x00000090, - 0x04000009, 0x0201f800, 0x00100615, 0x59c40801, - 0x82040d00, 0x00018000, 0x82040580, 0x00000000, - 0x04000036, 0x42000800, 0x00000000, 0x0401fa29, - 0x82040d00, 0x00000090, 0x82040580, 0x00000010, - 0x04000006, 0x82040580, 0x00000090, 0x04000006, - 0x02020800, 0x00100615, 0x59a80048, 0x84000542, - 0x0401f003, 0x59a80048, 0x84000540, 0x48035048, - 0x59a80045, 0x80000000, 0x48035045, 0x82000580, - 0x00000005, 0x04000003, 0x0401f861, 0x0401f01e, - 0x497b5045, 0x59c40801, 0x82040d00, 0x00018000, - 0x82040580, 0x00000000, 0x04000009, 0x82040580, - 0x00008000, 0x04000009, 0x82040580, 0x00010000, - 0x04000008, 0x0201f800, 0x00100615, 0x42000000, - 0x00000001, 0x0401f005, 0x41780000, 0x0401f003, - 0x42000000, 0x00000002, 0x0401f948, 0x4a035042, - 0x00000002, 0x0401f004, 0x4a035040, 0x00000003, - 0x0401f002, 0x0401ff42, 0x1c01f000, 0x0401f83b, - 0x04000015, 0x59a8004f, 0x80000040, 0x4803504f, - 0x0401f981, 0x04020005, 0x4a035040, 0x00000003, - 0x497b5041, 0x0401f00c, 0x59a8004f, 0x80000540, - 0x04020003, 0x0401f89e, 0x0401f002, 0x0401f84b, - 0x0401f82f, 0x497b5045, 0x4a035042, 0x00000001, - 0x0401ff2b, 0x1c01f000, 0x0401f824, 0x04000015, - 0x0401f96d, 0x0402000f, 0x59a80046, 0x80000000, - 0x48035046, 0x82000580, 0x00000007, 0x0402000c, - 0x4a035052, 0x0000000a, 0x497b5049, 0x59a80048, - 0x8400055e, 0x48035048, 0x4803c857, 0x0401f005, - 0x0401f817, 0x4a035042, 0x00000004, 0x0401ff3d, - 0x1c01f000, 0x0401f80d, 0x04000007, 0x0401f956, - 0x04020003, 0x0401ff1b, 0x0401f003, 0x0401f80c, - 0x0401ff34, 0x1c01f000, 0x0201f800, 0x00100615, - 0x0201f800, 0x00100615, 0x59a80050, 0x80000040, - 0x48035050, 0x0400088d, 0x1c01f000, 0x4c040000, - 0x42000800, 0x00000000, 0x0401f9ae, 0x82040d00, + 0x04000009, 0x0201f800, 0x001005d8, 0x42000000, + 0x00000002, 0x0401f005, 0x42000000, 0x00000001, + 0x0401f002, 0x41780000, 0x0401f8ea, 0x5c000800, + 0x1c01f000, 0x4c040000, 0x59c40801, 0x82040d00, + 0x00018000, 0x82040580, 0x00000000, 0x04000009, + 0x82040580, 0x00008000, 0x04000009, 0x82040580, + 0x00010000, 0x04000009, 0x0201f800, 0x001005d8, + 0x42000000, 0x00000002, 0x0401f005, 0x42000000, + 0x00000001, 0x0401f002, 0x41780000, 0x0401f866, + 0x5c000800, 0x1c01f000, 0x4c040000, 0x59a80045, + 0x80000000, 0x48035045, 0x82000580, 0x00000005, + 0x04020018, 0x497b5045, 0x59c40801, 0x82040d00, + 0x00018000, 0x82040580, 0x00000000, 0x04000009, + 0x82040580, 0x00008000, 0x04000009, 0x82040580, + 0x00010000, 0x04000009, 0x0201f800, 0x001005d8, + 0x42000000, 0x00000002, 0x0401f005, 0x42000000, + 0x00000001, 0x0401f002, 0x41780000, 0x0401f846, + 0x42000800, 0x00000000, 0x0401f961, 0x82040d00, 0x00000090, 0x82040580, 0x00000090, 0x04000009, 0x82040580, 0x00000010, 0x04000009, 0x82040580, - 0x00000000, 0x04000009, 0x0201f800, 0x00100615, + 0x00000000, 0x04000009, 0x0201f800, 0x001005d8, 0x42000000, 0x00000002, 0x0401f005, 0x42000000, - 0x00000001, 0x0401f002, 0x41780000, 0x0401f8e7, - 0x5c000800, 0x1c01f000, 0x4c040000, 0x59c40801, - 0x82040d00, 0x00018000, 0x82040580, 0x00000000, - 0x04000009, 0x82040580, 0x00008000, 0x04000009, - 0x82040580, 0x00010000, 0x04000009, 0x0201f800, - 0x00100615, 0x42000000, 0x00000002, 0x0401f005, - 0x42000000, 0x00000001, 0x0401f002, 0x41780000, - 0x0401f866, 0x5c000800, 0x1c01f000, 0x4c040000, - 0x59a80045, 0x80000000, 0x48035045, 0x82000580, - 0x00000005, 0x04020018, 0x497b5045, 0x59c40801, - 0x82040d00, 0x00018000, 0x82040580, 0x00000000, - 0x04000009, 0x82040580, 0x00008000, 0x04000009, - 0x82040580, 0x00010000, 0x04000009, 0x0201f800, - 0x00100615, 0x42000000, 0x00000002, 0x0401f005, - 0x42000000, 0x00000001, 0x0401f002, 0x41780000, - 0x0401f846, 0x42000800, 0x00000000, 0x0401f95d, - 0x82040d00, 0x00000090, 0x82040580, 0x00000090, - 0x04000009, 0x82040580, 0x00000010, 0x04000009, - 0x82040580, 0x00000000, 0x04000009, 0x0201f800, - 0x00100615, 0x42000000, 0x00000002, 0x0401f005, - 0x42000000, 0x00000001, 0x0401f002, 0x41780000, - 0x0401f896, 0x5c000800, 0x1c01f000, 0x4c200000, - 0x59a80048, 0x82000500, 0x00007fff, 0x02000800, - 0x00100615, 0x59a84047, 0x80204102, 0x02001800, - 0x00100615, 0x48235047, 0x80204500, 0x040007fa, - 0x8c000504, 0x04020007, 0x8c000502, 0x04020008, - 0x8c000500, 0x04020008, 0x0201f800, 0x00100615, - 0x42000000, 0x00000002, 0x0401f005, 0x41780000, - 0x0401f003, 0x42000000, 0x00000001, 0x0401f80f, - 0x5c004000, 0x1c01f000, 0x04011000, 0x4a03c840, - 0x0010b240, 0x4a03c842, 0x00000009, 0x40000000, - 0x040117ff, 0x4a035047, 0x00000004, 0x4a03503e, - 0x00000000, 0x1c01f000, 0x59a80858, 0x82040d80, - 0x01391077, 0x04020008, 0x59e00813, 0x8c040d00, - 0x04000005, 0x82000d80, 0x00000002, 0x04020002, - 0x41780000, 0x800001c0, 0x04000040, 0x82000d80, - 0x00000001, 0x0402001d, 0x42000800, 0x000000a0, - 0x0401f908, 0x82040540, 0x00000004, 0x42000800, - 0x000000a0, 0x0401f908, 0x42000800, 0x000000c0, - 0x0401f900, 0x82040540, 0x00000020, 0x42000800, - 0x000000c0, 0x0401f900, 0x59c40001, 0x82000500, - 0xfffe7fff, 0x82000540, 0x00000000, 0x48038801, - 0x59a80054, 0x80000110, 0x42000800, 0x000000e0, - 0x0401f8f5, 0x0401f03c, 0x82000d80, 0x00000002, - 0x02020800, 0x00100615, 0x42000800, 0x000000a0, - 0x0401f8e8, 0x82040500, 0xfffffffb, 0x42000800, - 0x000000a0, 0x0401f8e8, 0x42000800, 0x000000c0, - 0x0401f8e0, 0x82040500, 0xffffffdf, 0x42000800, - 0x000000c0, 0x0401f8e0, 0x59c40001, 0x82000500, - 0xfffe7fff, 0x82000540, 0x00010000, 0x48038801, - 0x59a80056, 0x80000110, 0x42000800, 0x000000e0, - 0x0401f8d5, 0x0401f01c, 0x42000800, 0x000000a0, - 0x0401f8cc, 0x82040540, 0x00000004, 0x42000800, - 0x000000a0, 0x0401f8cc, 0x42000800, 0x000000c0, - 0x0401f8c4, 0x82040500, 0xffffffdf, 0x42000800, - 0x000000c0, 0x0401f8c4, 0x59c40001, 0x82000500, - 0xfffe7fff, 0x82000540, 0x00008000, 0x48038801, - 0x59a80055, 0x80000110, 0x42000800, 0x000000e0, - 0x0401f8b9, 0x1c01f000, 0x4803c857, 0x59a80858, - 0x82040d80, 0x01391077, 0x04020008, 0x59e00813, - 0x8c040d00, 0x04000005, 0x82000d80, 0x00000002, - 0x04020002, 0x41780000, 0x4c000000, 0x0401f942, - 0x5c000000, 0x800001c0, 0x04000026, 0x82000d80, - 0x00000001, 0x04020010, 0x59a8006c, 0x80000540, - 0x04000004, 0x42001000, 0x00000000, 0x0401f9f7, - 0x42000800, 0x00000000, 0x0401f896, 0x82040540, - 0x00000090, 0x42000800, 0x00000000, 0x0401f896, - 0x0401f024, 0x82000d80, 0x00000002, 0x02020800, - 0x00100615, 0x59a8006c, 0x80000540, 0x04000004, - 0x42001000, 0x00010000, 0x0401f9e4, 0x42000800, - 0x00000000, 0x0401f883, 0x82040500, 0xffffff6f, - 0x42000800, 0x00000000, 0x0401f883, 0x0401f011, + 0x00000001, 0x0401f002, 0x41780000, 0x0401f899, + 0x5c000800, 0x1c01f000, 0x4c200000, 0x59a80048, + 0x82000500, 0x00007fff, 0x02000800, 0x001005d8, + 0x59a84047, 0x80204102, 0x02001800, 0x001005d8, + 0x48235047, 0x80204500, 0x040007fa, 0x8c000504, + 0x04020007, 0x8c000502, 0x04020008, 0x8c000500, + 0x04020008, 0x0201f800, 0x001005d8, 0x42000000, + 0x00000002, 0x0401f005, 0x41780000, 0x0401f003, + 0x42000000, 0x00000001, 0x0401f80f, 0x5c004000, + 0x1c01f000, 0x04011000, 0x4a03c840, 0x0010b440, + 0x4a03c842, 0x00000009, 0x40000000, 0x040117ff, + 0x4a035047, 0x00000004, 0x4a03503e, 0x00000000, + 0x1c01f000, 0x59a80858, 0x82040d80, 0x01391077, + 0x04020008, 0x59e00813, 0x8c040d00, 0x04000005, + 0x82000d80, 0x00000002, 0x04020002, 0x41780000, + 0x4c000000, 0x0401f9b1, 0x5c000000, 0x800001c0, + 0x04000040, 0x82000d80, 0x00000001, 0x0402001d, + 0x42000800, 0x000000a0, 0x0401f909, 0x82040540, + 0x00000004, 0x42000800, 0x000000a0, 0x0401f909, + 0x42000800, 0x000000c0, 0x0401f901, 0x82040540, + 0x00000020, 0x42000800, 0x000000c0, 0x0401f901, + 0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540, + 0x00000000, 0x48038801, 0x59a80054, 0x80000110, + 0x42000800, 0x000000e0, 0x0401f8f6, 0x0401f03c, + 0x82000d80, 0x00000002, 0x02020800, 0x001005d8, + 0x42000800, 0x000000a0, 0x0401f8e9, 0x82040500, + 0xfffffffb, 0x42000800, 0x000000a0, 0x0401f8e9, + 0x42000800, 0x000000c0, 0x0401f8e1, 0x82040500, + 0xffffffdf, 0x42000800, 0x000000c0, 0x0401f8e1, + 0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540, + 0x00010000, 0x48038801, 0x59a80056, 0x80000110, + 0x42000800, 0x000000e0, 0x0401f8d6, 0x0401f01c, + 0x42000800, 0x000000a0, 0x0401f8cd, 0x82040540, + 0x00000004, 0x42000800, 0x000000a0, 0x0401f8cd, + 0x42000800, 0x000000c0, 0x0401f8c5, 0x82040500, + 0xffffffdf, 0x42000800, 0x000000c0, 0x0401f8c5, + 0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540, + 0x00008000, 0x48038801, 0x59a80055, 0x80000110, + 0x42000800, 0x000000e0, 0x0401f8ba, 0x0401f163, + 0x4803c857, 0x59a80858, 0x82040d80, 0x01391077, + 0x04020008, 0x59e00813, 0x8c040d00, 0x04000005, + 0x82000d80, 0x00000002, 0x04020002, 0x41780000, + 0x4c000000, 0x0401f94d, 0x5c000000, 0x800001c0, + 0x04000026, 0x82000d80, 0x00000001, 0x04020010, 0x59a8006c, 0x80000540, 0x04000004, 0x42001000, - 0x00008000, 0x0401f9d5, 0x42000800, 0x00000000, - 0x0401f874, 0x82040500, 0xffffff6f, 0x82000540, - 0x00000010, 0x42000800, 0x00000000, 0x0401f872, - 0x0401f111, 0x4c580000, 0x4200b000, 0x00000014, - 0x8058b040, 0x04000042, 0x59c4000d, 0x8c000520, - 0x040207fc, 0x0401f85b, 0x59c4000d, 0x8c000520, - 0x040207f8, 0x59c40808, 0x84040d50, 0x48078808, - 0x4200b000, 0x000000c8, 0x8058b040, 0x040207ff, - 0x4200b000, 0x00000014, 0x8058b040, 0x04000030, - 0x59c4000d, 0x8c000520, 0x0402002d, 0x42000800, - 0x00001000, 0x50040800, 0x82040c80, 0x24220001, - 0x04020003, 0x8c000504, 0x040007f4, 0x0401f841, - 0x59c4000d, 0x8c000520, 0x04020021, 0x42000800, - 0x00001000, 0x50040800, 0x82040c80, 0x24220001, - 0x04020003, 0x8c000504, 0x040007e8, 0x4200b000, - 0x0000000a, 0x8058b040, 0x04000003, 0x0401f831, - 0x0401f7fd, 0x4200b000, 0x00000064, 0x59c4000d, - 0x8c00051e, 0x0400000e, 0x8058b040, 0x040207fc, - 0x42000000, 0x00001000, 0x50000000, 0x82000480, - 0x24220001, 0x04020004, 0x59c40808, 0x84040d10, - 0x48078808, 0x80000580, 0x0401f00c, 0x42000000, - 0x00001000, 0x50000000, 0x82000480, 0x24220001, - 0x04020004, 0x59c40808, 0x84040d10, 0x48078808, - 0x82000540, 0x00000001, 0x5c00b000, 0x1c01f000, - 0x42000800, 0x000000a0, 0x0401f816, 0x82040500, - 0xfffffffe, 0x42000800, 0x000000a0, 0x0401f816, - 0x42000800, 0x00000000, 0x0401f80e, 0x82040500, - 0xfffffffe, 0x42000800, 0x00000000, 0x0401f00e, + 0x00000000, 0x0401fa0a, 0x42000800, 0x00000000, + 0x0401f897, 0x82040540, 0x00000090, 0x42000800, + 0x00000000, 0x0401f897, 0x0401f024, 0x82000d80, + 0x00000002, 0x02020800, 0x001005d8, 0x59a8006c, + 0x80000540, 0x04000004, 0x42001000, 0x00010000, + 0x0401f9f7, 0x42000800, 0x00000000, 0x0401f884, + 0x82040500, 0xffffff6f, 0x42000800, 0x00000000, + 0x0401f884, 0x0401f011, 0x59a8006c, 0x80000540, + 0x04000004, 0x42001000, 0x00008000, 0x0401f9e8, + 0x42000800, 0x00000000, 0x0401f875, 0x82040500, + 0xffffff6f, 0x82000540, 0x00000010, 0x42000800, + 0x00000000, 0x0401f873, 0x0401f124, 0x4c580000, + 0x4200b000, 0x00000014, 0x8058b040, 0x04000043, + 0x59c4000d, 0x8c000520, 0x040207fc, 0x0401f85c, + 0x59c4000d, 0x8c000520, 0x040207f8, 0x59c40808, + 0x84040d50, 0x48078808, 0x4200b000, 0x000000c8, + 0x8058b040, 0x040207ff, 0x4200b000, 0x00000014, + 0x8058b040, 0x04000031, 0x59c4000d, 0x8c000520, + 0x0402002e, 0x42000800, 0x00001000, 0x50040800, + 0x82040c80, 0x24220001, 0x04020003, 0x8c000504, + 0x040007f4, 0x0401f842, 0x59c4000d, 0x8c000520, + 0x04020022, 0x42000800, 0x00001000, 0x50040800, + 0x82040c80, 0x24220001, 0x04020003, 0x8c000504, + 0x040007e8, 0x4200b000, 0x0000000a, 0x8058b040, + 0x04000003, 0x0401f832, 0x0401f7fd, 0x4200b000, + 0x00000064, 0x59c4000d, 0x8c00051e, 0x0400000f, + 0x8058b040, 0x040207fc, 0x42000000, 0x00001000, + 0x50000000, 0x82000480, 0x24220001, 0x04020004, + 0x59c40808, 0x84040d10, 0x48078808, 0x80000580, + 0x4803c857, 0x0401f00c, 0x42000000, 0x00001000, + 0x50000000, 0x82000480, 0x24220001, 0x04020004, + 0x59c40808, 0x84040d10, 0x48078808, 0x82000540, + 0x00000001, 0x5c00b000, 0x1c01f000, 0x42000800, + 0x000000a0, 0x0401f816, 0x82040500, 0xfffffffe, + 0x42000800, 0x000000a0, 0x0401f816, 0x42000800, + 0x00000000, 0x0401f80e, 0x82040500, 0xfffffffe, + 0x42000800, 0x00000000, 0x0401f00e, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x1c01f000, 0x480b8805, 0x1c01f000, - 0x4807880e, 0x59c4080f, 0x82040d00, 0x000000ff, - 0x1c01f000, 0x900001c0, 0x80040d40, 0x84040d40, - 0x4807880e, 0x1c01f000, 0x82000d80, 0x00200000, - 0x04000009, 0x82000d80, 0x02000000, 0x04000006, - 0x82000d80, 0x01000000, 0x04000006, 0x59c408a3, - 0x0401f006, 0x59c408a3, 0x84040d30, 0x0401f003, - 0x59c408a3, 0x84040d32, 0x80040540, 0x480388a3, - 0x480788a3, 0x1c01f000, 0x59c400a3, 0x84000556, - 0x480388a3, 0x84000516, 0x480388a3, 0x1c01f000, - 0x485fc857, 0x4863c857, 0x4c640000, 0x4d3c0000, - 0x4d400000, 0x0201f800, 0x00106c32, 0x4863500a, - 0x0201f800, 0x0010a95a, 0x0402006a, 0x82600d00, - 0x0000ff00, 0x800409c0, 0x0400000c, 0x4200c800, - 0x00000001, 0x59a80010, 0x82000500, 0x000000ff, - 0x80041110, 0x80081580, 0x04000021, 0x82041580, - 0x0000ff00, 0x0400000a, 0x59c410a3, 0x82081500, - 0x00008000, 0x04000009, 0x59c410a7, 0x82081500, - 0x0000ff00, 0x82081580, 0x0000ff00, 0x4200c800, - 0x00000000, 0x04000012, 0x59a80005, 0x8c000502, - 0x04020008, 0x8c000500, 0x0402000d, 0x599c1017, - 0x8c08151a, 0x0400003c, 0x84000542, 0x48035005, - 0x4200c800, 0x00000002, 0x42028000, 0x00000004, - 0x42027800, 0x00000008, 0x0401f007, 0x59a80805, - 0x84040d40, 0x48075005, 0x42028000, 0x00000004, - 0x417a7800, 0x59a80006, 0x8c000502, 0x04020006, - 0x59a80805, 0x8c040d0a, 0x04020032, 0x84040d4a, - 0x48075005, 0x42000000, 0x0010b610, 0x0201f800, - 0x0010a86e, 0x59a8180a, 0x42001000, 0x00008013, - 0x0201f800, 0x00103857, 0x0201f800, 0x0010393e, + 0x1c01f000, 0x480b8805, 0x1c01f000, 0x4807880e, + 0x59c4080f, 0x82040d00, 0x000000ff, 0x1c01f000, + 0x900001c0, 0x80040d40, 0x84040d40, 0x4807880e, + 0x1c01f000, 0x82000d80, 0x00200000, 0x04000009, + 0x82000d80, 0x02000000, 0x04000006, 0x82000d80, + 0x01000000, 0x04000006, 0x59c408a3, 0x0401f006, + 0x59c408a3, 0x84040d30, 0x0401f003, 0x59c408a3, + 0x84040d32, 0x80040540, 0x480388a3, 0x480788a3, + 0x1c01f000, 0x59c400a3, 0x84000556, 0x480388a3, + 0x84000516, 0x480388a3, 0x1c01f000, 0x485fc857, + 0x4863c857, 0x4c640000, 0x4d3c0000, 0x4d400000, + 0x0201f800, 0x00106ede, 0x4863500a, 0x0201f800, + 0x0010ab33, 0x0402006c, 0x82600d00, 0x0000ff00, + 0x800409c0, 0x0400000c, 0x4200c800, 0x00000001, + 0x59a80010, 0x82000500, 0x000000ff, 0x80041110, + 0x80081580, 0x04000021, 0x82041580, 0x0000ff00, + 0x0400000a, 0x59c410a3, 0x82081500, 0x00008000, + 0x04000009, 0x59c410a7, 0x82081500, 0x0000ff00, + 0x82081580, 0x0000ff00, 0x4200c800, 0x00000000, + 0x04000012, 0x59a80005, 0x8c000502, 0x04020008, + 0x8c000500, 0x0402000d, 0x599c1017, 0x8c08151a, + 0x0400003e, 0x84000542, 0x48035005, 0x4200c800, + 0x00000002, 0x42028000, 0x00000004, 0x42027800, + 0x00000008, 0x0401f008, 0x59a80805, 0x84040d40, + 0x48075005, 0x42028000, 0x00000004, 0x42027800, + 0x00000400, 0x59a80006, 0x8c000502, 0x04020006, + 0x59a80805, 0x8c040d0a, 0x04020033, 0x84040d4a, + 0x48075005, 0x42000000, 0x0010b812, 0x0201f800, + 0x0010aa47, 0x59a8180a, 0x42001000, 0x00008013, + 0x0201f800, 0x00103a3e, 0x0201f800, 0x00103b25, 0x04000015, 0x4d400000, 0x82600500, 0x000000ff, 0x42028800, 0x0000ffff, 0x40643000, 0x42028000, - 0x0000000e, 0x0201f800, 0x0010a258, 0x42000800, + 0x0000000e, 0x0201f800, 0x0010a446, 0x42000800, 0x00000001, 0x42001000, 0x00000100, 0x0201f800, - 0x00105ec4, 0x5c028000, 0x599c0817, 0x8c040d0a, - 0x04020010, 0x493fc857, 0x4943c857, 0x0401fb59, - 0x0401f00c, 0x0201f800, 0x0010393e, 0x04000009, - 0x42028000, 0x0000000f, 0x42028800, 0x0000ffff, - 0x42003000, 0x00000000, 0x0201f800, 0x0010a25b, - 0x497b8880, 0x5c028000, 0x5c027800, 0x5c00c800, - 0x1c01f000, 0x42000800, 0x00000000, 0x0401ff61, - 0x82040540, 0x00000002, 0x42000800, 0x00000000, - 0x0401f761, 0x42000800, 0x00000000, 0x0401ff59, - 0x82040500, 0xfffffffd, 0x42000800, 0x00000000, - 0x0401f759, 0x59c408a8, 0x0401ff4a, 0x0401ff49, - 0x59c400a8, 0x80040d80, 0x040207fb, 0x1c01f000, - 0x4803c856, 0x4a038807, 0x00000001, 0x497b8807, - 0x59c40005, 0x48038805, 0x497b506c, 0x497b506d, - 0x41785800, 0x42006000, 0x00000001, 0x42006800, - 0x00000003, 0x0401f824, 0x0401f82f, 0x40400000, - 0x4803c857, 0x82408580, 0x00000000, 0x0402001d, - 0x41785800, 0x42006000, 0x0000001e, 0x42006800, - 0x00000014, 0x0401f818, 0x0401f823, 0x40400000, - 0x4803c857, 0x82408580, 0x00000800, 0x04020011, - 0x42005800, 0x00000001, 0x42006000, 0x0000001e, - 0x42006800, 0x00000014, 0x0401f80b, 0x0401f816, - 0x40400000, 0x4803c857, 0x82408580, 0x0000ffff, - 0x04020004, 0x4a03506c, 0x00000001, 0x4803c856, - 0x1c01f000, 0x41785000, 0x0401f812, 0x0401f838, - 0x40347000, 0x40340800, 0x0401f03d, 0x42005000, - 0x00000001, 0x0401f80b, 0x0401f831, 0x40340800, - 0x0401f037, 0x42005000, 0x00000002, 0x0401f805, - 0x0401f81d, 0x0401f835, 0x40048000, 0x1c01f000, - 0x0401f808, 0x0401f814, 0x40280800, 0x0401f826, - 0x402c0800, 0x0401f827, 0x40300800, 0x0401f025, - 0x42000800, 0x0000ffff, 0x42001000, 0x00000001, - 0x0401f829, 0x42001000, 0x00000010, 0x0401f826, - 0x42000800, 0x0000ffff, 0x42001000, 0x00000010, - 0x0401f021, 0x41780800, 0x42001000, 0x00000002, - 0x0401f01d, 0x0401f92e, 0x4a03d000, 0x00050004, - 0x0401f92b, 0x4a03d000, 0x00050005, 0x0401f928, - 0x4a03d000, 0x00050004, 0x42000800, 0x00000001, - 0x42001000, 0x00000001, 0x0401f00f, 0x42000800, - 0x00000002, 0x42001000, 0x00000002, 0x0401f00a, - 0x42001000, 0x00000005, 0x0401f007, 0x42001000, - 0x00000010, 0x0401f004, 0x42001000, 0x00000010, - 0x0401f01b, 0x0401f912, 0x82082c00, 0x0010a95f, - 0x50142800, 0x82081500, 0xffffffff, 0x04000013, - 0x0401f90b, 0x80081040, 0x80142902, 0x40040000, - 0x80140500, 0x04000007, 0x4a03d000, 0x00070006, - 0x0401f903, 0x4a03d000, 0x00070007, 0x0401f006, - 0x4a03d000, 0x00070004, 0x0401f8fd, 0x4a03d000, - 0x00070005, 0x0401f7ec, 0x1c01f000, 0x41780800, - 0x82082c00, 0x0010a95f, 0x50142800, 0x82081500, - 0xffffffff, 0x04000010, 0x0401f8f1, 0x4a03d000, - 0x00050001, 0x0401f8ee, 0x59e81800, 0x80081040, - 0x80142902, 0x8c0c1d06, 0x04000004, 0x40140000, - 0x80040d40, 0x0401f8e6, 0x4a03d000, 0x00070000, - 0x0401f7ef, 0x1c01f000, 0x480bc857, 0x480b506d, - 0x59c40001, 0x82000500, 0xffffefff, 0x48038801, - 0x41781800, 0x0401f8c4, 0x41785800, 0x42006000, - 0x0000001e, 0x42006800, 0x00000004, 0x0401ff7a, - 0x42006800, 0x0000003c, 0x0401ff7d, 0x41785800, + 0x0010618b, 0x5c028000, 0x599c0817, 0x8c040d0a, + 0x04020011, 0x493fc857, 0x4943c857, 0x0201f800, + 0x00101fe5, 0x0401f00c, 0x0201f800, 0x00103b25, + 0x04000009, 0x42028000, 0x0000000f, 0x42028800, + 0x0000ffff, 0x42003000, 0x00000000, 0x0201f800, + 0x0010a449, 0x497b8880, 0x5c028000, 0x5c027800, + 0x5c00c800, 0x1c01f000, 0x42000800, 0x000000a0, + 0x0401ff5f, 0x82040540, 0x00000002, 0x42000800, + 0x000000a0, 0x0401f75f, 0x42000800, 0x00000000, + 0x0401ff57, 0x82040540, 0x00000002, 0x42000800, + 0x00000000, 0x0401f757, 0x42000800, 0x000000a0, + 0x0401ff4f, 0x82040500, 0xfffffffd, 0x42000800, + 0x000000a0, 0x0401f74f, 0x42000800, 0x00000000, + 0x0401ff47, 0x82040500, 0xfffffffd, 0x42000800, + 0x00000000, 0x0401f747, 0x59c408a8, 0x0401ff38, + 0x0401ff37, 0x59c400a8, 0x80040d80, 0x040207fb, + 0x1c01f000, 0x4803c856, 0x4a038807, 0x00000001, + 0x497b8807, 0x59c40005, 0x48038805, 0x497b506c, + 0x497b506d, 0x41785800, 0x42006000, 0x00000001, + 0x42006800, 0x00000003, 0x0401f824, 0x0401f82f, + 0x40400000, 0x4803c857, 0x82408580, 0x00000000, + 0x0402001d, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000014, 0x0401f818, 0x0401f823, + 0x40400000, 0x4803c857, 0x82408580, 0x00000800, + 0x04020011, 0x42005800, 0x00000001, 0x42006000, + 0x0000001e, 0x42006800, 0x00000014, 0x0401f80b, + 0x0401f816, 0x40400000, 0x4803c857, 0x82408580, + 0x0000ffff, 0x04020004, 0x4a03506c, 0x00000001, + 0x4803c856, 0x1c01f000, 0x41785000, 0x0401f812, + 0x0401f838, 0x40347000, 0x40340800, 0x0401f03d, + 0x42005000, 0x00000001, 0x0401f80b, 0x0401f831, + 0x40340800, 0x0401f037, 0x42005000, 0x00000002, + 0x0401f805, 0x0401f81d, 0x0401f835, 0x40048000, + 0x1c01f000, 0x0401f808, 0x0401f814, 0x40280800, + 0x0401f826, 0x402c0800, 0x0401f827, 0x40300800, + 0x0401f025, 0x42000800, 0x0000ffff, 0x42001000, + 0x00000001, 0x0401f829, 0x42001000, 0x00000010, + 0x0401f826, 0x42000800, 0x0000ffff, 0x42001000, + 0x00000010, 0x0401f021, 0x41780800, 0x42001000, + 0x00000002, 0x0401f01d, 0x0401f92e, 0x4a03d000, + 0x00050004, 0x0401f92b, 0x4a03d000, 0x00050005, + 0x0401f928, 0x4a03d000, 0x00050004, 0x42000800, + 0x00000001, 0x42001000, 0x00000001, 0x0401f00f, + 0x42000800, 0x00000002, 0x42001000, 0x00000002, + 0x0401f00a, 0x42001000, 0x00000005, 0x0401f007, + 0x42001000, 0x00000010, 0x0401f004, 0x42001000, + 0x00000010, 0x0401f01b, 0x0401f912, 0x82082c00, + 0x0010ab38, 0x50142800, 0x82081500, 0xffffffff, + 0x04000013, 0x0401f90b, 0x80081040, 0x80142902, + 0x40040000, 0x80140500, 0x04000007, 0x4a03d000, + 0x00070006, 0x0401f903, 0x4a03d000, 0x00070007, + 0x0401f006, 0x4a03d000, 0x00070004, 0x0401f8fd, + 0x4a03d000, 0x00070005, 0x0401f7ec, 0x1c01f000, + 0x41780800, 0x82082c00, 0x0010ab38, 0x50142800, + 0x82081500, 0xffffffff, 0x04000010, 0x0401f8f1, + 0x4a03d000, 0x00050001, 0x0401f8ee, 0x59e81800, + 0x80081040, 0x80142902, 0x8c0c1d06, 0x04000004, + 0x40140000, 0x80040d40, 0x0401f8e6, 0x4a03d000, + 0x00070000, 0x0401f7ef, 0x1c01f000, 0x480bc857, + 0x480b506d, 0x59c40001, 0x82000500, 0xffffefff, + 0x48038801, 0x41781800, 0x0401f8c4, 0x41785800, 0x42006000, 0x0000001e, 0x42006800, 0x00000004, - 0x0401ff71, 0x41786800, 0x0401ff75, 0x41785800, - 0x42006000, 0x0000001e, 0x41786800, 0x0401ff6a, - 0x42006800, 0x00000002, 0x0401ff6d, 0x42006800, - 0x00000001, 0x0401ff64, 0x42006800, 0x000000f5, - 0x0401ff67, 0x41785800, 0x42006000, 0x0000001e, - 0x42006800, 0x00000004, 0x0401ff5b, 0x42006800, - 0x00000020, 0x0401ff5e, 0x59a8106d, 0x0401f865, - 0x42001800, 0x000200f5, 0x0401f897, 0x59a8106d, - 0x0401f879, 0x41785800, 0x42006000, 0x0000001e, - 0x42006800, 0x00000004, 0x0401ff4b, 0x41786800, - 0x0401ff4f, 0x59c40001, 0x82000540, 0x00001000, - 0x48038801, 0x41785800, 0x42006000, 0x0000001e, - 0x42006800, 0x00000015, 0x0401ff3f, 0x0401ff4a, - 0x40400000, 0x82000540, 0x00000002, 0x4c000000, - 0x41785800, 0x42006000, 0x0000001e, 0x42006800, - 0x00000015, 0x0401ff34, 0x5c000000, 0x40006800, - 0x0401ff37, 0x41785800, 0x42006000, 0x0000001e, - 0x42006800, 0x00000015, 0x0401ff2b, 0x0401ff36, - 0x40400000, 0x82000500, 0x0000fffd, 0x4c000000, + 0x0401ff7a, 0x42006800, 0x0000003c, 0x0401ff7d, 0x41785800, 0x42006000, 0x0000001e, 0x42006800, - 0x00000015, 0x0401ff20, 0x5c000000, 0x40006800, - 0x0401ff23, 0x41785800, 0x42006000, 0x0000001e, - 0x42006800, 0x00000014, 0x0401ff17, 0x0401ff22, - 0x40400000, 0x82000540, 0x00000040, 0x4c000000, - 0x41785800, 0x42006000, 0x0000001e, 0x42006800, - 0x00000014, 0x0401ff0c, 0x5c000000, 0x40006800, - 0x0401ff0f, 0x41785800, 0x42006000, 0x0000001e, - 0x42006800, 0x00000014, 0x0401ff03, 0x0401ff0e, - 0x40400000, 0x82000500, 0x0000ffbf, 0x4c000000, - 0x41785800, 0x42006000, 0x0000001e, 0x42006800, - 0x00000014, 0x0401fef8, 0x5c000000, 0x40006800, - 0x0401fefb, 0x4a038886, 0x00002020, 0x0401f04c, - 0x480bc857, 0x82080580, 0x00010000, 0x04020007, - 0x82040d40, 0x00010000, 0x42001800, 0x00000001, - 0x0401f82d, 0x0401f00f, 0x82080580, 0x00008000, - 0x04000007, 0x82040d40, 0x00000000, 0x42001800, - 0x00900001, 0x0401f824, 0x0401f006, 0x82040d40, - 0x00008000, 0x42001800, 0x00100001, 0x0401f81e, - 0x1c01f000, 0x480bc857, 0x82080580, 0x00010000, - 0x04020008, 0x42001800, 0x000000a1, 0x0401f816, - 0x42001800, 0x000000c1, 0x0401f813, 0x0401f011, - 0x82080580, 0x00008000, 0x04000008, 0x42001800, - 0x000400a1, 0x0401f80c, 0x42001800, 0x002000c1, - 0x0401f809, 0x0401f007, 0x42001800, 0x000400a1, - 0x0401f805, 0x42001800, 0x000000c1, 0x0401f802, - 0x1c01f000, 0x480fc857, 0x41785800, 0x42006000, - 0x0000001e, 0x41786800, 0x0401feb7, 0x400c6800, - 0x80346960, 0x0401feba, 0x42006800, 0x00000001, - 0x0401feb1, 0x400c6800, 0x0401feb5, 0x42006800, - 0x00000003, 0x0401feac, 0x0401feb7, 0x40400000, - 0x8c000504, 0x040207fc, 0x1c01f000, 0x42000000, - 0x00000064, 0x80000040, 0x040207ff, 0x1c01f000, - 0x4c5c0000, 0x4c600000, 0x4178b800, 0x0201f800, - 0x0010473b, 0x040200fd, 0x59a8c026, 0x0201f800, - 0x00104e0d, 0x04000003, 0x8c60c506, 0x0400000e, - 0x8c60c500, 0x04020004, 0x8c60c50e, 0x040008f6, - 0x0401f0f2, 0x0401faaf, 0x040200f0, 0x0201f800, - 0x00104e0d, 0x04020004, 0x4a03501c, 0x0000ffff, - 0x0401f0ea, 0x8c60c504, 0x04000004, 0x4a03501c, - 0x0000ffff, 0x0401f0e5, 0x59a8c010, 0x8260c500, - 0x000000ff, 0x59a81013, 0x8c081500, 0x0400005d, - 0x8c081502, 0x0402005b, 0x59a8b81c, 0x825c0d80, - 0x0000ffff, 0x04020003, 0x4200b800, 0x00000001, - 0x805c1104, 0x82086400, 0x0010bc20, 0x50300800, - 0x825c0500, 0x00000003, 0x0c01f001, 0x00101c2c, - 0x00101c27, 0x00101c2b, 0x00101c29, 0x80040910, - 0x0401f004, 0x80040930, 0x0401f002, 0x80040920, - 0x82040500, 0x000000ff, 0x82000d80, 0x000000ff, - 0x0400000f, 0x4c000000, 0x82000400, 0x00101eb5, - 0x50000800, 0x80040910, 0x82040580, 0x00000080, - 0x5c000000, 0x04000030, 0x80600d80, 0x0400002e, - 0x80000540, 0x0400002c, 0x0401f00b, 0x59a81005, - 0x82081500, 0x00000003, 0x0402002b, 0x59a81013, - 0x84081542, 0x480b5013, 0x4a03501c, 0x0000ffff, - 0x0401f028, 0x4c000000, 0x59a8006f, 0x8c000502, - 0x42001000, 0x00000010, 0x02020800, 0x00104ada, - 0x5c000000, 0x0402001c, 0x417a8800, 0x0201f800, - 0x001059b9, 0x04020016, 0x0201f800, 0x0010443b, - 0x04000006, 0x0201f800, 0x00104acf, 0x0401f8b1, - 0x0400000f, 0x0401f00c, 0x599c0019, 0x8c00050e, - 0x04020009, 0x0201f800, 0x001043fc, 0x04020008, - 0x0201f800, 0x00104acf, 0x0401f9dd, 0x0401f8be, - 0x04000003, 0x805cb800, 0x0401f7b2, 0x485f501c, - 0x0401f086, 0x4a03501c, 0x0000ffff, 0x0401f083, - 0x42003000, 0x0000007e, 0x59a8001c, 0x82001580, - 0x0000ffff, 0x04020005, 0x80000d80, 0x4018b000, - 0x4803c856, 0x0401f009, 0x8018b480, 0x04001004, - 0x40000800, 0x4803c856, 0x0401f004, 0x4a03501c, - 0x0000ffff, 0x0401f071, 0x4c040000, 0x4c580000, - 0x82040400, 0x00101eb5, 0x50000000, 0x82000500, - 0x000000ff, 0x80604580, 0x0400005c, 0x0201f800, - 0x001059ba, 0x04020061, 0x59a8006f, 0x8c000502, - 0x42001000, 0x00000010, 0x02020800, 0x00104ada, - 0x5c00b000, 0x5c000800, 0x040207d7, 0x4c040000, - 0x4c580000, 0x845cbd00, 0x0201f800, 0x00020267, - 0x04000008, 0x599c0019, 0x8c00050e, 0x04020047, - 0x0201f800, 0x00104401, 0x0402004c, 0x0401f002, - 0x845cbd40, 0x0201f800, 0x00104acf, 0x0201f800, - 0x00104836, 0x04020007, 0x59a80005, 0x8c000502, - 0x04000033, 0x59340200, 0x8c00050e, 0x04020030, - 0x59a81013, 0x8c081502, 0x04000025, 0x0201f800, - 0x00104858, 0x04000031, 0x8c5cbd00, 0x04020004, - 0x0201f800, 0x00104455, 0x0401f02c, 0x0401f9c8, - 0x0400002a, 0x42026000, 0x0010bbe8, 0x49366009, - 0x497a6008, 0x417a7800, 0x0401f920, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x0201f800, - 0x0010393e, 0x0400001d, 0x41782800, 0x42003000, - 0x00000008, 0x4d400000, 0x4d440000, 0x59368c03, - 0x42028000, 0x00000029, 0x0201f800, 0x0010a258, - 0x5c028800, 0x5c028000, 0x0401f010, 0x4937c857, - 0x599c0019, 0x8c00050e, 0x0402000c, 0x0401f968, - 0x0401f849, 0x04000011, 0x0401f008, 0x59a80013, - 0x8c000500, 0x04000003, 0x0401f9a1, 0x04000003, - 0x0401f828, 0x04000009, 0x5c00b000, 0x5c000800, - 0x80040800, 0x8058b040, 0x04020798, 0x4a03501c, - 0x0000ffff, 0x0401f005, 0x4937c857, 0x5c00b000, - 0x5c000800, 0x4807501c, 0x5c00c000, 0x5c00b800, - 0x1c01f000, 0x4803c856, 0x4a03501c, 0x00000001, - 0x42028800, 0x000007fe, 0x42003000, 0x00fffffe, - 0x0201f800, 0x001043fc, 0x0402000c, 0x0401f944, - 0x0401f825, 0x04000009, 0x59a80026, 0x8400054e, - 0x48035026, 0x0201f800, 0x001090d5, 0x82000540, - 0x00000001, 0x1c01f000, 0x80000580, 0x0401f7fe, - 0x4937c857, 0x0201f800, 0x001076c9, 0x04000015, - 0x49366009, 0x4a026406, 0x00000001, 0x417a7800, - 0x0201f800, 0x001043bd, 0x59a8001b, 0x80000000, - 0x4803501b, 0x42027000, 0x00000004, 0x599c0019, - 0x8c00050e, 0x04000003, 0x42027000, 0x00000000, - 0x0201f800, 0x000208d8, 0x82000540, 0x00000001, - 0x1c01f000, 0x4937c857, 0x0201f800, 0x001076c9, - 0x0400001c, 0x49366009, 0x59340403, 0x82000580, - 0x000007fe, 0x04000005, 0x4d3c0000, 0x417a7800, - 0x0401f8b2, 0x5c027800, 0x4a026406, 0x00000001, - 0x417a7800, 0x0201f800, 0x001043bd, 0x42000800, - 0x00000003, 0x0201f800, 0x001043c7, 0x59a8001b, - 0x80000000, 0x4803501b, 0x42027000, 0x00000002, - 0x0201f800, 0x000208d8, 0x82000540, 0x00000001, - 0x1c01f000, 0x4803c856, 0x42028800, 0x000007fc, - 0x42003000, 0x00fffffc, 0x0201f800, 0x001043fc, - 0x04020005, 0x0401f805, 0x04000003, 0x4a035027, - 0x0000ffff, 0x1c01f000, 0x4937c857, 0x0201f800, - 0x001076c9, 0x04000014, 0x49366009, 0x4a026406, - 0x00000001, 0x417a7800, 0x0201f800, 0x001043bd, - 0x42000800, 0x00000003, 0x0201f800, 0x001043c7, - 0x59a80028, 0x80000000, 0x48035028, 0x42027000, - 0x00000002, 0x0201f800, 0x000208d8, 0x82000540, - 0x00000001, 0x1c01f000, 0x480bc857, 0x492fc857, - 0x4c5c0000, 0x4008b800, 0x42028800, 0x000007fd, - 0x42003000, 0x00fffffd, 0x0201f800, 0x001043fc, - 0x0402001a, 0x0201f800, 0x00020892, 0x04000017, - 0x49366009, 0x5934000a, 0x84000544, 0x4802680a, - 0x812e59c0, 0x04000005, 0x592c0404, 0x8c00051e, - 0x04000002, 0x48ee6021, 0x492e6008, 0x4a026406, - 0x00000001, 0x485e601c, 0x42027000, 0x00000022, - 0x0201f800, 0x000208d8, 0x82000540, 0x00000001, - 0x5c00b800, 0x1c01f000, 0x80000580, 0x0401f7fd, - 0x5c000000, 0x4c000000, 0x4803c857, 0x4943c857, - 0x493fc857, 0x4d340000, 0x4d440000, 0x4c580000, - 0x4d2c0000, 0x4c5c0000, 0x0201f800, 0x0010698c, - 0x4df00000, 0x0201f800, 0x0010673a, 0x0201f800, - 0x001067ee, 0x0201f800, 0x0010647f, 0x0201f800, - 0x0010822b, 0x5c03e000, 0x02000800, 0x00106982, - 0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800, - 0x00020267, 0x0402001a, 0x8d3e7d06, 0x04000004, - 0x59340200, 0x8c00050e, 0x04020015, 0x8d3e7d18, - 0x04000010, 0x5934b80f, 0x805cb9c0, 0x04000009, - 0x49425a06, 0x592cb800, 0x0201f800, 0x00020381, - 0x805cb9c0, 0x040207fb, 0x497a680f, 0x497a6810, - 0x4937c857, 0x4a026c00, 0x00000707, 0x0401f004, - 0x4937c857, 0x0201f800, 0x001040e4, 0x81468800, - 0x8058b040, 0x040207e2, 0x8d3e7d02, 0x04000011, - 0x497b501d, 0x42028800, 0x000007f0, 0x4200b000, - 0x00000010, 0x0201f800, 0x00020267, 0x04020006, - 0x4937c857, 0x4a026c00, 0x00000707, 0x0201f800, - 0x001040e4, 0x81468800, 0x8058b040, 0x040207f6, - 0x5c00b800, 0x5c025800, 0x5c00b000, 0x5c028800, - 0x5c026800, 0x1c01f000, 0x5c000000, 0x4c000000, - 0x4803c857, 0x4933c857, 0x493fc857, 0x4d340000, - 0x4d400000, 0x4d440000, 0x4d2c0000, 0x4c5c0000, - 0x0201f800, 0x0010698c, 0x4df00000, 0x59326809, - 0x813669c0, 0x04000021, 0x59368c03, 0x42028000, - 0x00000029, 0x0201f800, 0x0010679b, 0x0201f800, - 0x001067f6, 0x0201f800, 0x00106543, 0x0201f800, - 0x0010a0da, 0x4937c857, 0x8d3e7d18, 0x04000011, - 0x5934b80f, 0x805cb9c0, 0x0400000a, 0x405e5800, - 0x49425a06, 0x592cb800, 0x0201f800, 0x00020381, - 0x805cb9c0, 0x040207fa, 0x497a680f, 0x497a6810, - 0x4937c857, 0x4a026c00, 0x00000707, 0x0401f003, - 0x0201f800, 0x001040e4, 0x5c03e000, 0x02000800, - 0x00106982, 0x5c00b800, 0x5c025800, 0x5c028800, - 0x5c028000, 0x5c026800, 0x1c01f000, 0x4933c857, - 0x59a80026, 0x8c000508, 0x04020012, 0x59305009, - 0x482bc857, 0x836c0580, 0x00000002, 0x0402000d, - 0x0401f813, 0x0402000b, 0x58280403, 0x82000580, - 0x000007fc, 0x04000008, 0x59a8001b, 0x80000040, - 0x4803c857, 0x02001800, 0x00100615, 0x4803501b, - 0x1c01f000, 0x59a80028, 0x80000040, 0x4803c857, - 0x040017fc, 0x48035028, 0x1c01f000, 0x59300008, - 0x800001c0, 0x04020009, 0x59300403, 0x82000580, - 0x00000001, 0x04020004, 0x82000540, 0x00000001, - 0x0401f002, 0x80000580, 0x1c01f000, 0x4937c857, - 0x59340200, 0x84000502, 0x48026a00, 0x1c01f000, - 0x4933c857, 0x493fc857, 0x4947c857, 0x4d400000, - 0x4d340000, 0x4d440000, 0x4c580000, 0x0201f800, - 0x0010698c, 0x4df00000, 0x8060c1c0, 0x04020004, - 0x4200b000, 0x00000001, 0x0401f004, 0x4200b000, - 0x000007f0, 0x417a8800, 0x41440000, 0x81ac0400, - 0x50000000, 0x80026d40, 0x0400001a, 0x4d3c0000, - 0x42027800, 0x00000001, 0x0201f800, 0x00104745, - 0x5c027800, 0x42028000, 0x00000029, 0x0201f800, - 0x0010679b, 0x0201f800, 0x001067f6, 0x0201f800, - 0x00106543, 0x0201f800, 0x00104836, 0x04020005, - 0x4937c857, 0x4a026c00, 0x00000404, 0x0401f003, - 0x0201f800, 0x00104863, 0x0201f800, 0x0010a0da, - 0x81468800, 0x8058b040, 0x040207e0, 0x5c03e000, - 0x02000800, 0x00106982, 0x5c00b000, 0x5c028800, - 0x5c026800, 0x5c028000, 0x1c01f000, 0x4937c857, - 0x4947c857, 0x4c5c0000, 0x4c600000, 0x4c640000, - 0x59a80013, 0x8c000500, 0x0400001f, 0x599c0017, - 0x8c00050a, 0x0402001c, 0x5934ba02, 0x825cbd00, - 0x000000ff, 0x485fc857, 0x4178c000, 0x4178c800, - 0x82600400, 0x0010bc20, 0x50002000, 0x8060c1c0, - 0x04000008, 0x82100500, 0x000000ff, 0x82002d80, - 0x000000ff, 0x0400000c, 0x805c0580, 0x0400000d, - 0x80102110, 0x8064c800, 0x82640580, 0x00000004, - 0x040207f5, 0x8060c000, 0x82600580, 0x00000020, - 0x040207eb, 0x4813c857, 0x82000540, 0x00000001, - 0x5c00c800, 0x5c00c000, 0x5c00b800, 0x1c01f000, - 0x59a80026, 0x8c000512, 0x02020800, 0x001006ba, - 0x1c01f000, 0x00007eef, 0x00007de8, 0x00007ce4, - 0x000080e2, 0x00007be1, 0x000080e0, 0x000080dc, - 0x000080da, 0x00007ad9, 0x000080d6, 0x000080d5, - 0x000080d4, 0x000080d3, 0x000080d2, 0x000080d1, - 0x000079ce, 0x000078cd, 0x000080cc, 0x000080cb, - 0x000080ca, 0x000080c9, 0x000080c7, 0x000080c6, - 0x000077c5, 0x000076c3, 0x000080bc, 0x000080ba, - 0x000075b9, 0x000080b6, 0x000074b5, 0x000073b4, - 0x000072b3, 0x000080b2, 0x000080b1, 0x000080ae, - 0x000071ad, 0x000080ac, 0x000070ab, 0x00006faa, - 0x00006ea9, 0x000080a7, 0x00006da6, 0x00006ca5, - 0x00006ba3, 0x00006a9f, 0x0000699e, 0x0000689d, - 0x0000809b, 0x00008098, 0x00006797, 0x00006690, - 0x0000658f, 0x00006488, 0x00006384, 0x00006282, - 0x00008081, 0x00008080, 0x0000617c, 0x0000607a, - 0x00008079, 0x00005f76, 0x00008075, 0x00008074, - 0x00008073, 0x00008072, 0x00008071, 0x0000806e, - 0x00005e6d, 0x0000806c, 0x00005d6b, 0x00005c6a, - 0x00005b69, 0x00008067, 0x00005a66, 0x00005965, - 0x00005863, 0x0000575c, 0x0000565a, 0x00005559, - 0x00008056, 0x00008055, 0x00005454, 0x00005353, - 0x00005252, 0x00005151, 0x0000504e, 0x00004f4d, - 0x0000804c, 0x0000804b, 0x00004e4a, 0x00004d49, - 0x00008047, 0x00004c46, 0x00008045, 0x00008043, - 0x0000803c, 0x0000803a, 0x00008039, 0x00008036, - 0x00004b35, 0x00008034, 0x00004a33, 0x00004932, - 0x00004831, 0x0000802e, 0x0000472d, 0x0000462c, - 0x0000452b, 0x0000442a, 0x00004329, 0x00004227, - 0x00008026, 0x00008025, 0x00004123, 0x0000401f, - 0x00003f1e, 0x00003e1d, 0x00003d1b, 0x00003c18, - 0x00008017, 0x00008010, 0x00003b0f, 0x00003a08, - 0x00008004, 0x00003902, 0x00008001, 0x00008000, - 0x00008000, 0x00003800, 0x00003700, 0x00003600, - 0x00008000, 0x00003500, 0x00008000, 0x00008000, - 0x00008000, 0x00003400, 0x00008000, 0x00008000, + 0x00000004, 0x0401ff71, 0x41786800, 0x0401ff75, + 0x41785800, 0x42006000, 0x0000001e, 0x41786800, + 0x0401ff6a, 0x42006800, 0x00000002, 0x0401ff6d, + 0x42006800, 0x00000001, 0x0401ff64, 0x42006800, + 0x000000f5, 0x0401ff67, 0x41785800, 0x42006000, + 0x0000001e, 0x42006800, 0x00000004, 0x0401ff5b, + 0x42006800, 0x00000020, 0x0401ff5e, 0x59a8106d, + 0x0401f865, 0x42001800, 0x000200f5, 0x0401f897, + 0x59a8106d, 0x0401f879, 0x41785800, 0x42006000, + 0x0000001e, 0x42006800, 0x00000004, 0x0401ff4b, + 0x41786800, 0x0401ff4f, 0x59c40001, 0x82000540, + 0x00001000, 0x48038801, 0x41785800, 0x42006000, + 0x0000001e, 0x42006800, 0x00000015, 0x0401ff3f, + 0x0401ff4a, 0x40400000, 0x82000540, 0x00000002, + 0x4c000000, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000015, 0x0401ff34, 0x5c000000, + 0x40006800, 0x0401ff37, 0x41785800, 0x42006000, + 0x0000001e, 0x42006800, 0x00000015, 0x0401ff2b, + 0x0401ff36, 0x40400000, 0x82000500, 0x0000fffd, + 0x4c000000, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000015, 0x0401ff20, 0x5c000000, + 0x40006800, 0x0401ff23, 0x41785800, 0x42006000, + 0x0000001e, 0x42006800, 0x00000014, 0x0401ff17, + 0x0401ff22, 0x40400000, 0x82000540, 0x00000040, + 0x4c000000, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000014, 0x0401ff0c, 0x5c000000, + 0x40006800, 0x0401ff0f, 0x41785800, 0x42006000, + 0x0000001e, 0x42006800, 0x00000014, 0x0401ff03, + 0x0401ff0e, 0x40400000, 0x82000500, 0x0000ffbf, + 0x4c000000, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000014, 0x0401fef8, 0x5c000000, + 0x40006800, 0x0401fefb, 0x4a038886, 0x00002020, + 0x0401f04c, 0x480bc857, 0x82080580, 0x00010000, + 0x04020007, 0x82040d40, 0x00010000, 0x42001800, + 0x00000001, 0x0401f82d, 0x0401f00f, 0x82080580, + 0x00008000, 0x04000007, 0x82040d40, 0x00000000, + 0x42001800, 0x00900001, 0x0401f824, 0x0401f006, + 0x82040d40, 0x00008000, 0x42001800, 0x00100001, + 0x0401f81e, 0x1c01f000, 0x480bc857, 0x82080580, + 0x00010000, 0x04020008, 0x42001800, 0x000000a1, + 0x0401f816, 0x42001800, 0x000000c1, 0x0401f813, + 0x0401f011, 0x82080580, 0x00008000, 0x04000008, + 0x42001800, 0x000400a1, 0x0401f80c, 0x42001800, + 0x002000c1, 0x0401f809, 0x0401f007, 0x42001800, + 0x000400a1, 0x0401f805, 0x42001800, 0x000000c1, + 0x0401f802, 0x1c01f000, 0x480fc857, 0x41785800, + 0x42006000, 0x0000001e, 0x41786800, 0x0401feb7, + 0x400c6800, 0x80346960, 0x0401feba, 0x42006800, + 0x00000001, 0x0401feb1, 0x400c6800, 0x0401feb5, + 0x42006800, 0x00000003, 0x0401feac, 0x0401feb7, + 0x40400000, 0x8c000504, 0x040207fc, 0x1c01f000, + 0x42000000, 0x00000064, 0x80000040, 0x040207ff, + 0x1c01f000, 0x00020103, 0x00101bd5, 0x00101bdb, + 0x00101be1, 0x00101be9, 0x00101bef, 0x00101bf7, + 0x00101bff, 0x00101c09, 0x00101c0f, 0x00101c17, + 0x00101c1f, 0x00101c29, 0x00101c31, 0x00101c3b, + 0x00101c45, 0x000200f8, 0x00101c51, 0x00101c59, + 0x00101c61, 0x00101c6b, 0x00101c73, 0x00101c7d, + 0x00101c87, 0x00101c93, 0x00101c9b, 0x00101ca5, + 0x00101caf, 0x00101cbb, 0x00101cc5, 0x00101cd1, + 0x00101cdd, 0x000200fd, 0x00101ceb, 0x00101cf3, + 0x00101cfb, 0x00101d05, 0x00101d0d, 0x00101d17, + 0x00101d21, 0x00101d2d, 0x00101d35, 0x00101d3f, + 0x00101d49, 0x00101d55, 0x00101d5f, 0x00101d6b, + 0x00101d77, 0x00101d85, 0x00101d8d, 0x00101d97, + 0x00101da1, 0x00101dad, 0x00101db7, 0x00101dc3, + 0x00101dcf, 0x00101ddd, 0x00101de7, 0x00101df3, + 0x00101dff, 0x00101e0d, 0x00101e19, 0x00101e27, + 0x00101e35, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00101418, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101289, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101289, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00101289, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00101289, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00101289, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00101289, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00101418, 0x0201f800, 0x00101289, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00101418, 0x0201f800, + 0x00101289, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020729, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020729, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00020729, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020729, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00020729, 0x0201f800, + 0x00101289, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00020729, 0x0201f800, + 0x00101289, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020729, 0x0201f800, + 0x00101289, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00101289, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00020729, 0x0201f800, 0x00101289, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00020729, 0x0201f800, + 0x00101289, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00101289, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00101289, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00020015, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020015, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020015, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00020015, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00020015, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00101155, 0x0201f800, 0x00020015, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101418, 0x0201f800, 0x00101155, 0x0201f800, + 0x00020015, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101289, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f800, + 0x00101155, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101289, 0x0201f800, 0x00101155, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f800, + 0x00101155, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f800, + 0x00101155, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020729, 0x0201f800, + 0x00020015, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101155, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00020729, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101155, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101155, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101155, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101289, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00020729, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101289, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101289, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00020729, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00020729, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f800, + 0x00020104, 0x0201f000, 0x00020101, 0x4c000000, + 0x4df00000, 0x0201f800, 0x00101155, 0x0201f800, + 0x00101418, 0x0201f800, 0x00020729, 0x0201f800, + 0x00020015, 0x0201f800, 0x00101289, 0x0201f000, + 0x00020101, 0x4c000000, 0x4df00000, 0x0201f800, + 0x00101155, 0x0201f800, 0x00101418, 0x0201f800, + 0x00020729, 0x0201f800, 0x00020015, 0x0201f800, + 0x00101289, 0x0201f800, 0x00020104, 0x0201f000, + 0x00020101, 0x4c5c0000, 0x4c600000, 0x4178b800, + 0x0201f800, 0x001048ec, 0x040200fd, 0x59a8c026, + 0x0201f800, 0x0010513b, 0x04000003, 0x8c60c506, + 0x0400000e, 0x8c60c500, 0x04020004, 0x8c60c50e, + 0x040008f6, 0x0401f0f2, 0x0401fab4, 0x040200f0, + 0x0201f800, 0x0010513b, 0x04020004, 0x4a03501c, + 0x0000ffff, 0x0401f0ea, 0x8c60c504, 0x04000004, + 0x4a03501c, 0x0000ffff, 0x0401f0e5, 0x59a8c010, + 0x8260c500, 0x000000ff, 0x59a81013, 0x8c081500, + 0x0400005d, 0x8c081502, 0x0402005b, 0x59a8b81c, + 0x825c0d80, 0x0000ffff, 0x04020003, 0x4200b800, + 0x00000001, 0x805c1104, 0x82086400, 0x0010be21, + 0x50300800, 0x825c0500, 0x00000003, 0x0c01f001, + 0x00101e81, 0x00101e7c, 0x00101e80, 0x00101e7e, + 0x80040910, 0x0401f004, 0x80040930, 0x0401f002, + 0x80040920, 0x82040500, 0x000000ff, 0x82000d80, + 0x000000ff, 0x0400000f, 0x4c000000, 0x82000400, + 0x0010210e, 0x50000800, 0x80040910, 0x82040580, + 0x00000080, 0x5c000000, 0x04000030, 0x80600d80, + 0x0400002e, 0x80000540, 0x0400002c, 0x0401f00b, + 0x59a81005, 0x82081500, 0x00000003, 0x0402002b, + 0x59a81013, 0x84081542, 0x480b5013, 0x4a03501c, + 0x0000ffff, 0x0401f028, 0x4c000000, 0x59a80005, + 0x8c000514, 0x42001000, 0x00000010, 0x02020800, + 0x00104c6d, 0x5c000000, 0x0402001c, 0x417a8800, + 0x0201f800, 0x00105c9a, 0x04020016, 0x0201f800, + 0x001045e5, 0x04000006, 0x0201f800, 0x00104c62, + 0x0401f8b1, 0x0400000f, 0x0401f00c, 0x599c0019, + 0x8c00050e, 0x04020009, 0x0201f800, 0x001045a6, + 0x04020008, 0x0201f800, 0x00104c62, 0x0401f9e1, + 0x0401f8be, 0x04000003, 0x805cb800, 0x0401f7b2, + 0x485f501c, 0x0401f086, 0x4a03501c, 0x0000ffff, + 0x0401f083, 0x42003000, 0x0000007e, 0x59a8001c, + 0x82001580, 0x0000ffff, 0x04020005, 0x80000d80, + 0x4018b000, 0x4803c856, 0x0401f009, 0x8018b480, + 0x04001004, 0x40000800, 0x4803c856, 0x0401f004, + 0x4a03501c, 0x0000ffff, 0x0401f071, 0x4c040000, + 0x4c580000, 0x82040400, 0x0010210e, 0x50000000, + 0x82000500, 0x000000ff, 0x80604580, 0x0400005c, + 0x0201f800, 0x00105c9b, 0x04020061, 0x59a80005, + 0x8c000514, 0x42001000, 0x00000010, 0x02020800, + 0x00104c6d, 0x5c00b000, 0x5c000800, 0x040207d7, + 0x4c040000, 0x4c580000, 0x845cbd00, 0x0201f800, + 0x00020245, 0x04000008, 0x599c0019, 0x8c00050e, + 0x04020047, 0x0201f800, 0x001045ab, 0x0402004c, + 0x0401f002, 0x845cbd40, 0x0201f800, 0x00104c62, + 0x0201f800, 0x001049e7, 0x04020007, 0x59a80005, + 0x8c000502, 0x04000033, 0x59340200, 0x8c00050e, + 0x04020030, 0x59a81013, 0x8c081502, 0x04000025, + 0x0201f800, 0x00104a09, 0x04000031, 0x8c5cbd00, + 0x04020004, 0x0201f800, 0x001045ff, 0x0401f02c, + 0x0401f9cd, 0x0400002a, 0x42026000, 0x0010bde9, + 0x49366009, 0x497a6008, 0x417a7800, 0x0401f925, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x0201f800, 0x00103b25, 0x0400001d, 0x41782800, + 0x42003000, 0x00000008, 0x4d400000, 0x4d440000, + 0x59368c03, 0x42028000, 0x00000029, 0x0201f800, + 0x0010a446, 0x5c028800, 0x5c028000, 0x0401f010, + 0x4937c857, 0x599c0019, 0x8c00050e, 0x0402000c, + 0x0401f96c, 0x0401f849, 0x04000011, 0x0401f008, + 0x59a80013, 0x8c000500, 0x04000003, 0x0401f9a6, + 0x04000003, 0x0401f828, 0x04000009, 0x5c00b000, + 0x5c000800, 0x80040800, 0x8058b040, 0x04020798, + 0x4a03501c, 0x0000ffff, 0x0401f005, 0x4937c857, + 0x5c00b000, 0x5c000800, 0x4807501c, 0x5c00c000, + 0x5c00b800, 0x1c01f000, 0x4803c856, 0x4a03501c, + 0x00000001, 0x42028800, 0x000007fe, 0x42003000, + 0x00fffffe, 0x0201f800, 0x001045a6, 0x0402000c, + 0x0401f948, 0x0401f825, 0x04000009, 0x59a80026, + 0x8400054e, 0x48035026, 0x0201f800, 0x0010930f, + 0x82000540, 0x00000001, 0x1c01f000, 0x80000580, + 0x0401f7fe, 0x4937c857, 0x0201f800, 0x00107942, + 0x04000015, 0x49366009, 0x4a026406, 0x00000001, + 0x417a7800, 0x0201f800, 0x00104567, 0x59a8001b, + 0x80000000, 0x4803501b, 0x42027000, 0x00000004, + 0x599c0019, 0x8c00050e, 0x04000003, 0x42027000, + 0x00000000, 0x0201f800, 0x000207a1, 0x82000540, + 0x00000001, 0x1c01f000, 0x4937c857, 0x0201f800, + 0x00107942, 0x0400001c, 0x49366009, 0x59340403, + 0x82000580, 0x000007fe, 0x04000005, 0x4d3c0000, + 0x417a7800, 0x0401f8b7, 0x5c027800, 0x4a026406, + 0x00000001, 0x417a7800, 0x0201f800, 0x00104567, + 0x42000800, 0x00000003, 0x0201f800, 0x00104571, + 0x59a8001b, 0x80000000, 0x4803501b, 0x42027000, + 0x00000002, 0x0201f800, 0x000207a1, 0x82000540, + 0x00000001, 0x1c01f000, 0x4803c856, 0x42028800, + 0x000007fc, 0x42003000, 0x00fffffc, 0x0201f800, + 0x001045a6, 0x04020005, 0x0401f805, 0x04000003, + 0x4a035027, 0x0000ffff, 0x1c01f000, 0x4937c857, + 0x0201f800, 0x00107942, 0x04000014, 0x49366009, + 0x4a026406, 0x00000001, 0x417a7800, 0x0201f800, + 0x00104567, 0x42000800, 0x00000003, 0x0201f800, + 0x00104571, 0x59a80028, 0x80000000, 0x48035028, + 0x42027000, 0x00000002, 0x0201f800, 0x000207a1, + 0x82000540, 0x00000001, 0x1c01f000, 0x480bc857, + 0x492fc857, 0x4c5c0000, 0x4008b800, 0x42028800, + 0x000007fd, 0x42003000, 0x00fffffd, 0x0201f800, + 0x001045a6, 0x0402001a, 0x0201f800, 0x0002075a, + 0x04000017, 0x49366009, 0x5934000a, 0x84000544, + 0x4802680a, 0x812e59c0, 0x04000005, 0x592c0404, + 0x8c00051e, 0x04000002, 0x48ee6021, 0x492e6008, + 0x4a026406, 0x00000001, 0x485e601c, 0x42027000, + 0x00000022, 0x0201f800, 0x000207a1, 0x82000540, + 0x00000001, 0x5c00b800, 0x1c01f000, 0x80000580, + 0x0401f7fd, 0x5c000000, 0x4c000000, 0x4803c857, + 0x4943c857, 0x493fc857, 0x4d340000, 0x4d440000, + 0x4c580000, 0x4d2c0000, 0x4c5c0000, 0x0201f800, + 0x00106c55, 0x4df00000, 0x0201f800, 0x001069f1, + 0x0201f800, 0x00106aac, 0x0201f800, 0x00106737, + 0x0201f800, 0x0010848a, 0x5c03e000, 0x02000800, + 0x00106c4b, 0x4200b000, 0x000007f0, 0x417a8800, + 0x0201f800, 0x00020245, 0x0402001f, 0x8d3e7d14, + 0x04000005, 0x59340212, 0x82000500, 0x0000ff00, + 0x04000019, 0x8d3e7d06, 0x04000004, 0x59340200, + 0x8c00050e, 0x04020014, 0x8d3e7d18, 0x0400000f, + 0x5934b80f, 0x805cb9c0, 0x04000009, 0x49425a06, + 0x592cb800, 0x0201f800, 0x000202ce, 0x805cb9c0, + 0x040207fb, 0x497a680f, 0x497a6810, 0x4a026c00, + 0x00000707, 0x0401f004, 0x4937c857, 0x0201f800, + 0x001042b4, 0x81468800, 0x8058b040, 0x040207dd, + 0x8d3e7d02, 0x04000011, 0x497b501d, 0x42028800, + 0x000007f0, 0x4200b000, 0x00000010, 0x0201f800, + 0x00020245, 0x04020006, 0x4937c857, 0x4a026c00, + 0x00000707, 0x0201f800, 0x001042b4, 0x81468800, + 0x8058b040, 0x040207f6, 0x5c00b800, 0x5c025800, + 0x5c00b000, 0x5c028800, 0x5c026800, 0x1c01f000, + 0x5c000000, 0x4c000000, 0x4803c857, 0x4933c857, + 0x493fc857, 0x4d340000, 0x4d400000, 0x4d440000, + 0x4d2c0000, 0x4c5c0000, 0x0201f800, 0x00106c55, + 0x4df00000, 0x59326809, 0x813669c0, 0x04000020, + 0x59368c03, 0x42028000, 0x00000029, 0x0201f800, + 0x00106a50, 0x0201f800, 0x00106ab4, 0x0201f800, + 0x001067fd, 0x0201f800, 0x0010a2ff, 0x4937c857, + 0x8d3e7d18, 0x04000010, 0x5934b80f, 0x805cb9c0, + 0x0400000a, 0x405e5800, 0x49425a06, 0x592cb800, + 0x0201f800, 0x000202ce, 0x805cb9c0, 0x040207fa, + 0x497a680f, 0x497a6810, 0x4a026c00, 0x00000707, + 0x0401f003, 0x0201f800, 0x001042b4, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x5c00b800, 0x5c025800, + 0x5c028800, 0x5c028000, 0x5c026800, 0x1c01f000, + 0x4933c857, 0x59a80026, 0x8c000508, 0x04020012, + 0x59305009, 0x482bc857, 0x836c0580, 0x00000002, + 0x0402000d, 0x0401f813, 0x0402000b, 0x58280403, + 0x82000580, 0x000007fc, 0x04000008, 0x59a8001b, + 0x80000040, 0x4803c857, 0x02001800, 0x001005d8, + 0x4803501b, 0x1c01f000, 0x59a80028, 0x80000040, + 0x4803c857, 0x040017fc, 0x48035028, 0x1c01f000, + 0x59300008, 0x800001c0, 0x04020009, 0x59300403, + 0x82000580, 0x00000001, 0x04020004, 0x82000540, + 0x00000001, 0x0401f002, 0x80000580, 0x1c01f000, + 0x4937c857, 0x59340200, 0x84000502, 0x48026a00, + 0x1c01f000, 0x4933c857, 0x493fc857, 0x4947c857, + 0x4d3c0000, 0x4d400000, 0x4d340000, 0x4d440000, + 0x4c580000, 0x0201f800, 0x00106c55, 0x4df00000, + 0x813e79c0, 0x04020004, 0x4200b000, 0x00000001, + 0x0401f004, 0x4200b000, 0x000007f0, 0x417a8800, + 0x41440000, 0x81ac0400, 0x50000000, 0x80026d40, + 0x04000019, 0x42027800, 0x00000001, 0x0201f800, + 0x001048f6, 0x42028000, 0x00000029, 0x417a7800, + 0x0201f800, 0x00106a50, 0x0201f800, 0x00106ab4, + 0x0201f800, 0x001067fd, 0x0201f800, 0x001049e7, + 0x04020005, 0x4937c857, 0x4a026c00, 0x00000404, + 0x0401f003, 0x0201f800, 0x00104a14, 0x0201f800, + 0x0010a2ff, 0x81468800, 0x8058b040, 0x040207e1, + 0x5c03e000, 0x02000800, 0x00106c4b, 0x5c00b000, + 0x5c028800, 0x5c026800, 0x5c028000, 0x5c027800, + 0x1c01f000, 0x4937c857, 0x4947c857, 0x4c5c0000, + 0x4c600000, 0x4c640000, 0x59a80013, 0x8c000500, + 0x0400001f, 0x599c0017, 0x8c00050a, 0x0402001c, + 0x5934ba02, 0x825cbd00, 0x000000ff, 0x485fc857, + 0x4178c000, 0x4178c800, 0x82600400, 0x0010be21, + 0x50002000, 0x8060c1c0, 0x04000008, 0x82100500, + 0x000000ff, 0x82002d80, 0x000000ff, 0x0400000c, + 0x805c0580, 0x0400000d, 0x80102110, 0x8064c800, + 0x82640580, 0x00000004, 0x040207f5, 0x8060c000, + 0x82600580, 0x00000020, 0x040207eb, 0x4813c857, + 0x82000540, 0x00000001, 0x5c00c800, 0x5c00c000, + 0x5c00b800, 0x1c01f000, 0x59a80026, 0x4803c857, + 0x8c000512, 0x1c01f000, 0x00007eef, 0x00007de8, + 0x00007ce4, 0x000080e2, 0x00007be1, 0x000080e0, + 0x000080dc, 0x000080da, 0x00007ad9, 0x000080d6, + 0x000080d5, 0x000080d4, 0x000080d3, 0x000080d2, + 0x000080d1, 0x000079ce, 0x000078cd, 0x000080cc, + 0x000080cb, 0x000080ca, 0x000080c9, 0x000080c7, + 0x000080c6, 0x000077c5, 0x000076c3, 0x000080bc, + 0x000080ba, 0x000075b9, 0x000080b6, 0x000074b5, + 0x000073b4, 0x000072b3, 0x000080b2, 0x000080b1, + 0x000080ae, 0x000071ad, 0x000080ac, 0x000070ab, + 0x00006faa, 0x00006ea9, 0x000080a7, 0x00006da6, + 0x00006ca5, 0x00006ba3, 0x00006a9f, 0x0000699e, + 0x0000689d, 0x0000809b, 0x00008098, 0x00006797, + 0x00006690, 0x0000658f, 0x00006488, 0x00006384, + 0x00006282, 0x00008081, 0x00008080, 0x0000617c, + 0x0000607a, 0x00008079, 0x00005f76, 0x00008075, + 0x00008074, 0x00008073, 0x00008072, 0x00008071, + 0x0000806e, 0x00005e6d, 0x0000806c, 0x00005d6b, + 0x00005c6a, 0x00005b69, 0x00008067, 0x00005a66, + 0x00005965, 0x00005863, 0x0000575c, 0x0000565a, + 0x00005559, 0x00008056, 0x00008055, 0x00005454, + 0x00005353, 0x00005252, 0x00005151, 0x0000504e, + 0x00004f4d, 0x0000804c, 0x0000804b, 0x00004e4a, + 0x00004d49, 0x00008047, 0x00004c46, 0x00008045, + 0x00008043, 0x0000803c, 0x0000803a, 0x00008039, + 0x00008036, 0x00004b35, 0x00008034, 0x00004a33, + 0x00004932, 0x00004831, 0x0000802e, 0x0000472d, + 0x0000462c, 0x0000452b, 0x0000442a, 0x00004329, + 0x00004227, 0x00008026, 0x00008025, 0x00004123, + 0x0000401f, 0x00003f1e, 0x00003e1d, 0x00003d1b, + 0x00003c18, 0x00008017, 0x00008010, 0x00003b0f, + 0x00003a08, 0x00008004, 0x00003902, 0x00008001, + 0x00008000, 0x00008000, 0x00003800, 0x00003700, + 0x00003600, 0x00008000, 0x00003500, 0x00008000, + 0x00008000, 0x00008000, 0x00003400, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, - 0x00003300, 0x00003200, 0x00008000, 0x00008000, + 0x00008000, 0x00003300, 0x00003200, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, - 0x00003100, 0x00003000, 0x00008000, 0x00008000, - 0x00002f00, 0x00008000, 0x00002e00, 0x00002d00, - 0x00002c00, 0x00008000, 0x00008000, 0x00008000, - 0x00002b00, 0x00008000, 0x00002a00, 0x00002900, - 0x00002800, 0x00008000, 0x00002700, 0x00002600, - 0x00002500, 0x00002400, 0x00002300, 0x00002200, - 0x00008000, 0x00008000, 0x00002100, 0x00002000, - 0x00001f00, 0x00001e00, 0x00001d00, 0x00001c00, - 0x00008000, 0x00008000, 0x00001b00, 0x00001a00, - 0x00008000, 0x00001900, 0x00008000, 0x00008000, + 0x00008000, 0x00003100, 0x00003000, 0x00008000, + 0x00008000, 0x00002f00, 0x00008000, 0x00002e00, + 0x00002d00, 0x00002c00, 0x00008000, 0x00008000, + 0x00008000, 0x00002b00, 0x00008000, 0x00002a00, + 0x00002900, 0x00002800, 0x00008000, 0x00002700, + 0x00002600, 0x00002500, 0x00002400, 0x00002300, + 0x00002200, 0x00008000, 0x00008000, 0x00002100, + 0x00002000, 0x00001f00, 0x00001e00, 0x00001d00, + 0x00001c00, 0x00008000, 0x00008000, 0x00001b00, + 0x00001a00, 0x00008000, 0x00001900, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, - 0x00001800, 0x00008000, 0x00001700, 0x00001600, - 0x00001500, 0x00008000, 0x00001400, 0x00001300, - 0x00001200, 0x00001100, 0x00001000, 0x00000f00, - 0x00008000, 0x00008000, 0x00000e00, 0x00000d00, - 0x00000c00, 0x00000b00, 0x00000a00, 0x00000900, - 0x00008000, 0x00008000, 0x00000800, 0x00000700, - 0x00008000, 0x00000600, 0x00008000, 0x00008000, - 0x00008000, 0x00000500, 0x00000400, 0x00000300, - 0x00008000, 0x00000200, 0x00008000, 0x00008000, - 0x00008000, 0x00000100, 0x00008000, 0x00008000, + 0x00008000, 0x00001800, 0x00008000, 0x00001700, + 0x00001600, 0x00001500, 0x00008000, 0x00001400, + 0x00001300, 0x00001200, 0x00001100, 0x00001000, + 0x00000f00, 0x00008000, 0x00008000, 0x00000e00, + 0x00000d00, 0x00000c00, 0x00000b00, 0x00000a00, + 0x00000900, 0x00008000, 0x00008000, 0x00000800, + 0x00000700, 0x00008000, 0x00000600, 0x00008000, + 0x00008000, 0x00008000, 0x00000500, 0x00000400, + 0x00000300, 0x00008000, 0x00000200, 0x00008000, + 0x00008000, 0x00008000, 0x00000100, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, - 0x00000000, 0x00008000, 0x00008000, 0x00008000, + 0x00008000, 0x00000000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, - 0x00008000, 0x0201f800, 0x00100819, 0x02000800, - 0x00100615, 0x492f4016, 0x1c01f000, 0x83a0ac00, - 0x00000006, 0x83a00580, 0x0010b2a0, 0x0400000c, - 0x492fc857, 0x812e59c0, 0x02000800, 0x00100615, - 0x832ca400, 0x00000006, 0x4200b000, 0x0000000d, - 0x0201f800, 0x0010a93e, 0x0401f00f, 0x4200b000, - 0x00000010, 0x83e0a400, 0x00000020, 0x50500000, - 0x8050a000, 0x50500800, 0x900409c0, 0x80040540, - 0x4400a800, 0x8050a000, 0x8054a800, 0x8058b040, - 0x040207f7, 0x1c01f000, 0x59a00206, 0x82000c80, - 0x0000007f, 0x040210c9, 0x59a80821, 0x0c01f001, - 0x00102066, 0x001020a6, 0x001020a6, 0x001020f0, - 0x00102112, 0x001020a6, 0x00102066, 0x00102134, - 0x00102145, 0x001020a6, 0x001020a6, 0x00102152, - 0x0010216a, 0x00102182, 0x001020a6, 0x001021b1, - 0x001021e3, 0x001020a6, 0x0010220c, 0x001020a6, - 0x00102269, 0x001020a6, 0x001020a6, 0x001020a6, - 0x001020a6, 0x00102280, 0x001022b9, 0x001020a6, - 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, - 0x001022ee, 0x001020a6, 0x00102340, 0x001020a6, - 0x001020a6, 0x001020a6, 0x001020a6, 0x00102345, - 0x001023be, 0x001020a6, 0x001023c5, 0x001020a6, - 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, - 0x001023c7, 0x00102445, 0x00102585, 0x001020a6, - 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, - 0x00102594, 0x001020a6, 0x001020a6, 0x001020a6, - 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, - 0x001025b1, 0x00102604, 0x00102660, 0x00102674, - 0x00102696, 0x001028d1, 0x00102c60, 0x001020a6, - 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, - 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, - 0x001020a6, 0x001020a6, 0x001020a6, 0x00102d9f, - 0x00102e13, 0x001020a6, 0x001020a6, 0x00102e81, - 0x001020a6, 0x00102f1f, 0x00102fd1, 0x001020a6, - 0x001020a6, 0x00103008, 0x00103064, 0x001020a6, - 0x001030bc, 0x00103220, 0x001020a6, 0x00103234, - 0x001032bf, 0x001020a6, 0x001020a6, 0x001020a6, - 0x001020a6, 0x0010332f, 0x00103333, 0x00103352, - 0x001020a6, 0x001033f4, 0x001020a6, 0x001020a6, - 0x00103421, 0x001020a6, 0x0010344f, 0x001020a6, - 0x001020a6, 0x001034b6, 0x001035c3, 0x00103620, - 0x001020a6, 0x00103686, 0x001020a6, 0x001020a6, - 0x001036db, 0x0010373e, 0x001020a6, 0x48efc857, - 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, - 0x00000200, 0x04000045, 0x48efc857, 0x4a034206, - 0x00004000, 0x0201f800, 0x0010382f, 0x83a00580, - 0x0010b2a0, 0x0400000d, 0x58ee580a, 0x4d2c0000, - 0x0401f856, 0x41a25800, 0x0201f800, 0x0010083a, - 0x40ee5800, 0x0201f800, 0x0010083a, 0x5c025800, - 0x0201f000, 0x00020381, 0x04026007, 0x59a0001d, - 0x84000542, 0x4803401d, 0x4a01d809, 0x0010207a, - 0x1c01f000, 0x59a00206, 0x82000d80, 0x00004000, - 0x04000006, 0x900001c0, 0x82000540, 0x00000011, - 0x4803c011, 0x0401f005, 0x900001c0, 0x82000540, - 0x00000010, 0x4803c011, 0x0401f844, 0x59e00017, - 0x8c000508, 0x0402000c, 0x4203e000, 0x30000001, - 0x4203e000, 0x40000000, 0x40ee5800, 0x0201f800, - 0x0010083a, 0x59a0001d, 0x84000504, 0x4803401d, - 0x1c01f000, 0x4a03c017, 0x00000000, 0x59a00206, - 0x82000d80, 0x00004000, 0x040007f0, 0x4a03c017, - 0x00000001, 0x0401f7ed, 0x4803c856, 0x4a034206, - 0x00004001, 0x0401f7c0, 0x4803c856, 0x4a034206, - 0x00004002, 0x0401f7bc, 0x4803c856, 0x4a034206, - 0x00004003, 0x0401f7b8, 0x4803c856, 0x4a034206, - 0x00004005, 0x0401f7b4, 0x4803c856, 0x4a034206, - 0x00004006, 0x0401f7b0, 0x4803c856, 0x4a034206, - 0x0000400b, 0x0401f7ac, 0x4803c856, 0x4a034206, - 0x0000400c, 0x0401f7a8, 0x4803c856, 0x4a034206, - 0x0000400c, 0x0401f7a4, 0x58eca80a, 0x8054a9c0, - 0x02000800, 0x00100615, 0x83a0a400, 0x00000006, - 0x8254ac00, 0x00000006, 0x4200b000, 0x0000000d, - 0x0201f000, 0x0010a93e, 0x59a00206, 0x4803c857, - 0x59a00406, 0x4803c857, 0x59a00207, 0x4803c857, - 0x59a00407, 0x4803c857, 0x59a00208, 0x4803c857, - 0x59a00408, 0x4803c857, 0x59a00209, 0x4803c857, - 0x83e0ac00, 0x00000020, 0x83a0a400, 0x00000006, - 0x4200b000, 0x00000010, 0x50500000, 0x4400a800, - 0x8054a800, 0x900001c0, 0x4400a800, 0x8054a800, - 0x8050a000, 0x8058b040, 0x040207f8, 0x1c01f000, - 0x59a00406, 0x800000c2, 0x59a00a07, 0x900409c0, - 0x80040540, 0x84000540, 0x59a00c07, 0x8c040d00, - 0x04000018, 0x59a8086f, 0x8c040d00, 0x040207bb, - 0x42000800, 0x00000064, 0x80040840, 0x04000007, - 0x4a030000, 0x00000001, 0x40000000, 0x59801000, - 0x8c081500, 0x040007f9, 0x04000005, 0x48030004, - 0x4a030000, 0x00000000, 0x0401f75c, 0x4a030000, - 0x00000000, 0x4a034406, 0x00000004, 0x040007a3, - 0x4803880e, 0x0401f755, 0x59a00406, 0x800000c2, - 0x59a00c07, 0x8c040d00, 0x0400001a, 0x59a8086f, - 0x8c040d00, 0x0402079d, 0x42000800, 0x00000064, - 0x80040840, 0x04000007, 0x4a030000, 0x00000001, - 0x40000000, 0x59801000, 0x8c081500, 0x040007f9, - 0x04000007, 0x48030004, 0x59800805, 0x48074406, - 0x4a030000, 0x00000000, 0x0401f73c, 0x4a030000, - 0x00000000, 0x4a034406, 0x00000004, 0x04000783, - 0x4803880e, 0x59c4080f, 0x48074406, 0x0401f733, - 0x59a01c06, 0x59a00207, 0x900c19c0, 0x800c1d40, - 0x580c0803, 0x80000580, 0x500c1000, 0x80080400, - 0x800c1800, 0x80040840, 0x040207fc, 0x48034406, - 0x900001c0, 0x48034207, 0x800001c0, 0x04000723, - 0x0401f76a, 0x4a034406, 0x00000004, 0x4a034207, - 0x00000000, 0x4a034407, 0x00000012, 0x59a8000d, - 0x48034208, 0x900001c0, 0x48034408, 0x4a034209, - 0x00000002, 0x0401f715, 0x59a00407, 0x59a01207, - 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, - 0x900c19c0, 0x800c1d40, 0x59a00a08, 0x59a00408, - 0x900409c0, 0x80040d40, 0x59a0020a, 0x82002480, - 0x00000010, 0x04001755, 0x59a02406, 0x900001c0, - 0x80100540, 0x59a8280d, 0x80142480, 0x0400174f, - 0x0201f000, 0x0010383e, 0x59a00407, 0x59a01207, - 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, - 0x900c19c0, 0x800c1d40, 0x59a00a08, 0x59a00408, - 0x900409c0, 0x80040d40, 0x59a0020a, 0x82002480, - 0x00000010, 0x0400173d, 0x59a02406, 0x900001c0, - 0x80100540, 0x59a8280d, 0x80142480, 0x04001737, - 0x0201f000, 0x00103841, 0x59a02407, 0x59a00207, - 0x901021c0, 0x80102540, 0x59a01a0a, 0x59a00406, - 0x900c19c0, 0x800c1d40, 0x41781000, 0x42000000, - 0x00001000, 0x50000000, 0x82000480, 0x24320001, - 0x04001016, 0x820c0580, 0x00007c00, 0x04000013, - 0x820c0480, 0x00007a00, 0x04001010, 0x820c0480, - 0x00007cff, 0x0402100d, 0x42000800, 0x00000064, - 0x80040840, 0x04000007, 0x4a030000, 0x00000001, - 0x40000000, 0x59800000, 0x8c000500, 0x040007f9, - 0x04000008, 0x80081000, 0x44101800, 0x800811c0, - 0x040006be, 0x4a030000, 0x00000000, 0x0401f6bb, - 0x4a030000, 0x00000000, 0x4a034406, 0x00000004, - 0x0401f702, 0x59a01a0a, 0x59a00406, 0x900c19c0, - 0x800c1d40, 0x41781000, 0x42000000, 0x00001000, - 0x50000000, 0x82000480, 0x24320001, 0x04001016, - 0x820c0580, 0x00007c00, 0x04000013, 0x820c0480, - 0x00007a00, 0x04001010, 0x820c0480, 0x00007cff, - 0x0402100d, 0x42000800, 0x00000064, 0x80040840, + 0x00008000, 0x00008000, 0x0201f800, 0x001007d3, + 0x02000800, 0x001005d8, 0x492f4016, 0x1c01f000, + 0x83a0ac00, 0x00000006, 0x83a00580, 0x0010b4a4, + 0x0400000c, 0x492fc857, 0x812e59c0, 0x02000800, + 0x001005d8, 0x832ca400, 0x00000006, 0x4200b000, + 0x0000000d, 0x0201f800, 0x0010ab17, 0x0401f00f, + 0x4200b000, 0x00000010, 0x83e0a400, 0x00000020, + 0x50500000, 0x8050a000, 0x50500800, 0x900409c0, + 0x80040540, 0x4400a800, 0x8050a000, 0x8054a800, + 0x8058b040, 0x040207f7, 0x1c01f000, 0x59a00206, + 0x4803c857, 0x82000c80, 0x0000007f, 0x040210c9, + 0x59a80821, 0x0c01f001, 0x001022c0, 0x00102300, + 0x00102300, 0x0010234b, 0x0010236d, 0x00102300, + 0x001022c0, 0x0010238f, 0x001023a0, 0x00102300, + 0x00102300, 0x001023ad, 0x001023c5, 0x001023dd, + 0x00102300, 0x001023e7, 0x001023f4, 0x00102300, + 0x0010241d, 0x00102300, 0x0010247a, 0x00102300, + 0x00102300, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x00102300, 0x00102491, 0x00102300, + 0x001024e3, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x001024e8, 0x00102560, 0x00102300, + 0x00102567, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x00102300, 0x00102569, 0x001025ea, + 0x00102727, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x00102300, 0x00102736, 0x00102300, + 0x00102300, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x00102300, 0x00102753, 0x001027a6, + 0x00102802, 0x00102816, 0x00102835, 0x00102a70, + 0x00102dff, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x00102300, 0x00102300, 0x00102300, + 0x00102300, 0x00102fb4, 0x00103028, 0x00102300, + 0x00102300, 0x00103094, 0x00102300, 0x00103126, + 0x001031d8, 0x00102300, 0x00102300, 0x0010320f, + 0x0010326b, 0x00102300, 0x001032bd, 0x00103419, + 0x00102300, 0x0010342d, 0x001034b8, 0x00102300, + 0x00102300, 0x00102300, 0x00102300, 0x00103522, + 0x00103526, 0x00103545, 0x00102300, 0x001035e7, + 0x00102300, 0x00102300, 0x00103615, 0x00102300, + 0x00103643, 0x00102300, 0x00102300, 0x001036aa, + 0x001037b7, 0x00103814, 0x00102300, 0x0010387a, + 0x00102300, 0x00102300, 0x001038d3, 0x00103936, + 0x00102300, 0x48efc857, 0x4031d800, 0x58ef400b, + 0x58ec0002, 0x82000580, 0x00000200, 0x04000045, + 0x48efc857, 0x4a034206, 0x00004000, 0x0201f800, + 0x00103a15, 0x83a00580, 0x0010b4a4, 0x0400000d, + 0x58ee580a, 0x4d2c0000, 0x0401f856, 0x41a25800, + 0x0201f800, 0x001007f4, 0x40ee5800, 0x0201f800, + 0x001007f4, 0x5c025800, 0x0201f000, 0x000202da, + 0x04026007, 0x59a0001d, 0x84000542, 0x4803401d, + 0x4a01d809, 0x001022d4, 0x1c01f000, 0x59a00206, + 0x82000d80, 0x00004000, 0x04000006, 0x900001c0, + 0x82000540, 0x00000011, 0x4803c011, 0x0401f005, + 0x900001c0, 0x82000540, 0x00000010, 0x4803c011, + 0x0401f845, 0x59e00017, 0x8c000508, 0x0402000c, + 0x4203e000, 0x30000001, 0x4203e000, 0x40000000, + 0x40ee5800, 0x0201f800, 0x001007f4, 0x59a0001d, + 0x84000504, 0x4803401d, 0x1c01f000, 0x4a03c017, + 0x00000000, 0x59a00206, 0x82000d80, 0x00004000, + 0x040007f0, 0x4a03c017, 0x00000001, 0x0401f7ed, + 0x4803c856, 0x4a034206, 0x00004001, 0x0401f7c0, + 0x4803c856, 0x4a034206, 0x00004002, 0x0401f7bc, + 0x4803c856, 0x4a034206, 0x00004003, 0x0401f7b8, + 0x4803c856, 0x4a034206, 0x00004005, 0x0401f7b4, + 0x4803c856, 0x4a034206, 0x00004006, 0x0401f7b0, + 0x4803c856, 0x4a034206, 0x0000400b, 0x0401f7ac, + 0x4803c856, 0x4a034206, 0x0000400c, 0x0401f7a8, + 0x4803c856, 0x4a034206, 0x0000400c, 0x0401f7a4, + 0x48efc857, 0x58eca80a, 0x8054a9c0, 0x02000800, + 0x001005d8, 0x83a0a400, 0x00000006, 0x8254ac00, + 0x00000006, 0x4200b000, 0x0000000d, 0x0201f000, + 0x0010ab17, 0x59a00206, 0x4803c857, 0x59a00406, + 0x4803c857, 0x59a00207, 0x4803c857, 0x59a00407, + 0x4803c857, 0x59a00208, 0x4803c857, 0x59a00408, + 0x4803c857, 0x59a00209, 0x4803c857, 0x83e0ac00, + 0x00000020, 0x83a0a400, 0x00000006, 0x4200b000, + 0x00000010, 0x50500000, 0x4400a800, 0x8054a800, + 0x900001c0, 0x4400a800, 0x8054a800, 0x8050a000, + 0x8058b040, 0x040207f8, 0x1c01f000, 0x59a00406, + 0x800000c2, 0x59a00a07, 0x900409c0, 0x80040540, + 0x84000540, 0x59a00c07, 0x8c040d00, 0x04000018, + 0x59a80805, 0x8c040d0e, 0x040207ba, 0x42000800, + 0x00000064, 0x80040840, 0x04000007, 0x4a030000, + 0x00000001, 0x40000000, 0x59801000, 0x8c081500, + 0x040007f9, 0x04000005, 0x48030004, 0x4a030000, + 0x00000000, 0x0401f75b, 0x4a030000, 0x00000000, + 0x4a034406, 0x00000004, 0x040007a2, 0x4803880e, + 0x0401f754, 0x59a00406, 0x800000c2, 0x59a00c07, + 0x8c040d00, 0x0400001a, 0x59a80805, 0x8c040d0e, + 0x0402079c, 0x42000800, 0x00000064, 0x80040840, 0x04000007, 0x4a030000, 0x00000001, 0x40000000, - 0x59800000, 0x8c000500, 0x040007f9, 0x0400000f, - 0x80081000, 0x500c0000, 0x82000d00, 0x0000ffff, - 0x48074207, 0x82000d00, 0xffff0000, 0x900409c0, - 0x48074407, 0x800811c0, 0x0400068c, 0x4a030000, - 0x00000000, 0x0401f689, 0x4a030000, 0x00000000, - 0x4a034406, 0x00000004, 0x0401f6d0, 0x59a00406, - 0x8c000500, 0x04000020, 0x59a01207, 0x59a01c07, - 0x59a02208, 0x480b5054, 0x480f5055, 0x48135056, - 0x59c40801, 0x82040d00, 0x00018000, 0x82040580, - 0x00000000, 0x04000009, 0x82040580, 0x00008000, - 0x04000008, 0x82040580, 0x00010000, 0x04000007, - 0x0201f800, 0x00100615, 0x40080000, 0x0401f004, - 0x400c0000, 0x0401f002, 0x40100000, 0x80000110, - 0x42000800, 0x000000e0, 0x0201f800, 0x001019b1, - 0x0401f007, 0x59a81054, 0x59a81855, 0x59a82056, - 0x480b4207, 0x480f4407, 0x48134208, 0x0401f65b, - 0x4d2c0000, 0x4d340000, 0x4d300000, 0x4d440000, - 0x59a28c06, 0x0201f800, 0x00020267, 0x04000006, - 0x5c028800, 0x5c026000, 0x5c026800, 0x5c025800, - 0x0401f69e, 0x59a04407, 0x59a00207, 0x900001c0, - 0x80204540, 0x0401f81e, 0x04000009, 0x4a034208, - 0x00000001, 0x4a034406, 0x0000ffff, 0x4a034207, - 0x0000ffff, 0x497b4407, 0x0401f00b, 0x0401f822, - 0x0400000e, 0x4a034208, 0x00000002, 0x59300402, - 0x48034406, 0x59300202, 0x48034207, 0x59300206, - 0x48034407, 0x5c028800, 0x5c026000, 0x5c026800, - 0x5c025800, 0x0401f631, 0x5c028800, 0x5c026000, - 0x5c026800, 0x5c025800, 0x0401f678, 0x4937c856, - 0x4823c856, 0x4d2c0000, 0x5934000f, 0x80025d40, - 0x04000007, 0x592c0005, 0x80200580, 0x592c0000, - 0x040207fb, 0x82000540, 0x00000001, 0x5c025800, - 0x1c01f000, 0x4823c857, 0x4d2c0000, 0x4d300000, - 0x42026000, 0x0010cfc0, 0x59300406, 0x82000d80, - 0x00000003, 0x04000004, 0x82000d80, 0x00000006, - 0x04020007, 0x59325808, 0x812e59c0, 0x04000004, - 0x592c0005, 0x80200580, 0x0400000a, 0x83326400, - 0x00000024, 0x41580000, 0x81300480, 0x040017ef, - 0x80000580, 0x5c026000, 0x5c025800, 0x1c01f000, - 0x82000540, 0x00000001, 0x5c026000, 0x5c025800, - 0x1c01f000, 0x83a00580, 0x0010b2a0, 0x0402063b, - 0x59a8006f, 0x8c000500, 0x04020003, 0x4a030000, - 0x00000000, 0x4a034206, 0x00004000, 0x4a03c011, - 0x40000010, 0x0401fe5d, 0x59e00017, 0x8c000508, - 0x04000003, 0x4a03c017, 0x00000000, 0x4203e000, - 0x30000001, 0x4203e000, 0x40000000, 0x0401f000, - 0x59a00c06, 0x800409c0, 0x04000007, 0x836c0580, - 0x00000000, 0x04000004, 0x4a034406, 0x0000001a, - 0x0401f62a, 0x42007000, 0x0010b33f, 0x58381c01, - 0x58382202, 0x8c040d00, 0x0400000b, 0x59a01207, - 0x82080500, 0x0000f003, 0x04020624, 0x82080480, - 0x00000841, 0x04021621, 0x82080480, 0x00000100, - 0x0400161e, 0x8c040d06, 0x04000003, 0x4a0378e4, - 0x000c0000, 0x8c040d04, 0x0400000c, 0x42000000, - 0x00001000, 0x50000000, 0x82000480, 0x24220001, - 0x04020003, 0x84040d04, 0x0401f004, 0x59e00002, - 0x84000548, 0x4803c002, 0x8c040d02, 0x04000005, - 0x42002800, 0x00007600, 0x4a002805, 0xd0000000, - 0x40040000, 0x800c0540, 0x48007401, 0x8c040d00, - 0x04000002, 0x48087202, 0x480f4406, 0x48134207, - 0x0401f5ae, 0x4d440000, 0x4d340000, 0x59a28c06, - 0x0201f800, 0x00020267, 0x04020009, 0x0201f800, - 0x00104842, 0x04000009, 0x4a034406, 0x00000009, - 0x5c026800, 0x5c028800, 0x0401f5ec, 0x5c026800, - 0x5c028800, 0x0401f5ed, 0x59a01207, 0x59a01c07, - 0x5934400a, 0x82203d00, 0x0000e000, 0x801c391a, - 0x8c081500, 0x04000019, 0x820c0d00, 0x00000007, - 0x82040580, 0x00000000, 0x04000007, 0x82040580, - 0x00000001, 0x04000004, 0x82040580, 0x00000003, - 0x040207eb, 0x82204500, 0xffff1fff, 0x800400da, - 0x80200540, 0x4802680a, 0x4c1c0000, 0x0201f800, - 0x0010698c, 0x0201f800, 0x00104afd, 0x0201f800, - 0x00106982, 0x5c003800, 0x481f4407, 0x5c026800, - 0x5c028800, 0x0401f579, 0x800409c0, 0x04000004, - 0x4a034406, 0x00000001, 0x0401f5c0, 0x836c0580, - 0x00000003, 0x04020010, 0x59a80010, 0x497b4406, - 0x0201f800, 0x00104e0d, 0x0400000f, 0x82000d00, - 0x00ffff00, 0x0402000c, 0x82000c00, 0x00101eb5, - 0x50040800, 0x80040910, 0x82041580, 0x00000080, - 0x04020004, 0x4a034406, 0x00000007, 0x0401f5ab, - 0x48074406, 0x82000d00, 0x0000ffff, 0x48074207, - 0x80000120, 0x48034407, 0x59a80026, 0x82001500, - 0x00000100, 0x480b4409, 0x8c000502, 0x0400001f, - 0x8c000506, 0x04000009, 0x82000d00, 0x0000000a, - 0x82040d80, 0x0000000a, 0x04020004, 0x4a034209, - 0x00000001, 0x0401f022, 0x8c00050a, 0x04000009, - 0x82000d00, 0x00000022, 0x82040d80, 0x00000022, - 0x04020004, 0x4a034209, 0x00000003, 0x0401f018, - 0x8c000508, 0x04000009, 0x82000d00, 0x00000012, - 0x82040d80, 0x00000012, 0x04020004, 0x4a034209, - 0x00000002, 0x0401f00e, 0x0201f800, 0x00104e0d, - 0x04020004, 0x4a034209, 0x00000004, 0x0401f52f, - 0x8c000506, 0x04000004, 0x4a034406, 0x00000005, - 0x0401f576, 0x4a034209, 0x00000000, 0x0401f527, - 0x59a80037, 0x48034407, 0x59a80038, 0x48034209, - 0x0401f522, 0x42007800, 0x0010b6eb, 0x59a00406, - 0x4803c857, 0x82000c80, 0x00000007, 0x0402156b, - 0x0c01f001, 0x00102354, 0x00102355, 0x00102363, - 0x00102376, 0x00102397, 0x00102354, 0x00102354, - 0x0401f562, 0x836c0580, 0x00000000, 0x0400055b, - 0x59a00a07, 0x59a00407, 0x900001c0, 0x80040d40, - 0x4807c857, 0x59a00a08, 0x59a00408, 0x900001c0, - 0x80040d40, 0x4807c857, 0x0401f056, 0x836c0580, - 0x00000000, 0x0400054d, 0x59a00407, 0x59a01207, - 0x900001c0, 0x80081540, 0x59a00408, 0x59a01a08, - 0x900001c0, 0x800c1d40, 0x42000000, 0x0010bfbe, - 0x480fc857, 0x480bc857, 0x42000800, 0x00001000, - 0x0201f000, 0x00103841, 0x59a00a07, 0x59a00407, - 0x900001c0, 0x80041d40, 0x820c0c80, 0x0010a971, - 0x0402153a, 0x820c0c80, 0x00100000, 0x04001537, - 0x480fc857, 0x823c7c00, 0x00000009, 0x503c0800, - 0x800409c0, 0x04000006, 0x823c0580, 0x0000000d, - 0x0400052e, 0x803c7800, 0x0401f7f9, 0x59e41001, - 0x82080d00, 0xfffeffcf, 0x4807c801, 0x440c7800, - 0x46001800, 0x0201f800, 0x800c1800, 0x46001800, - 0x00100608, 0x480bc801, 0x0401f022, 0x59a01a07, - 0x59a00407, 0x900001c0, 0x800c1d40, 0x480c7801, - 0x59a02208, 0x59a00408, 0x900001c0, 0x80102540, - 0x48107802, 0x59a00209, 0x80000040, 0x04001513, - 0x48007806, 0x80000000, 0x48007805, 0x42000800, - 0x00004000, 0x40001000, 0x0201f800, 0x001063cf, - 0x80000540, 0x04000003, 0x49787801, 0x0401f507, - 0x40040000, 0x800c1c00, 0x04001504, 0x480c7803, - 0x48107804, 0x49787808, 0x59a00409, 0x48007807, - 0x59e40001, 0x4803c857, 0x82000540, 0x00040000, - 0x4803c801, 0x0401f4a9, 0x59a80006, 0x48034406, - 0x59a80007, 0x48034207, 0x59a80008, 0x48034407, - 0x0401f4a2, 0x0201f800, 0x00100615, 0x4803c856, - 0x4a03c013, 0x03800300, 0x4a03c014, 0x03800380, - 0x59a00c06, 0x82040580, 0x000000a0, 0x04000004, - 0x82040580, 0x000000a2, 0x04020028, 0x59a0140a, - 0x82080480, 0x00000100, 0x04021024, 0x59a0020b, - 0x8c000500, 0x0402002b, 0x59a00a0a, 0x800409c0, - 0x0400001e, 0x82040480, 0x00000041, 0x0402101b, - 0x82040c00, 0x00000003, 0x82040d00, 0x000000fc, - 0x80040904, 0x59a00407, 0x59a01207, 0x900811c0, + 0x59801000, 0x8c081500, 0x040007f9, 0x04000007, + 0x48030004, 0x59800805, 0x48074406, 0x4a030000, + 0x00000000, 0x0401f73b, 0x4a030000, 0x00000000, + 0x4a034406, 0x00000004, 0x04000782, 0x4803880e, + 0x59c4080f, 0x48074406, 0x0401f732, 0x59a01c06, + 0x59a00207, 0x900c19c0, 0x800c1d40, 0x580c0803, + 0x80000580, 0x500c1000, 0x80080400, 0x800c1800, + 0x80040840, 0x040207fc, 0x48034406, 0x900001c0, + 0x48034207, 0x800001c0, 0x04000722, 0x0401f769, + 0x4a034406, 0x00000004, 0x4a034207, 0x00000000, + 0x4a034407, 0x00000010, 0x59a8000d, 0x48034208, + 0x900001c0, 0x48034408, 0x4a034209, 0x00000002, + 0x0401f714, 0x59a00407, 0x59a01207, 0x900811c0, + 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, + 0x800c1d40, 0x59a00a08, 0x59a00408, 0x900409c0, + 0x80040d40, 0x59a0020a, 0x82002480, 0x00000010, + 0x04001754, 0x59a02406, 0x900001c0, 0x80100540, + 0x59a8280d, 0x80142480, 0x0400174e, 0x0201f000, + 0x00103a25, 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, - 0x800c1d40, 0x0201f800, 0x0010381a, 0x04020006, - 0x4a034406, 0x00000002, 0x4a03c014, 0x03800000, - 0x0401f4be, 0x0201f800, 0x0010383e, 0x4a01d809, - 0x001023fd, 0x1c01f000, 0x4a03c014, 0x03800000, - 0x0401f4ba, 0x4031d800, 0x58ef400b, 0x58ee580d, - 0x58ec0002, 0x82000580, 0x00000200, 0x040004a7, - 0x59a00c06, 0x59a0140a, 0x59a0020b, 0x8c000500, - 0x04020031, 0x832e5c00, 0x00000004, 0x41783800, - 0x59a04a0a, 0x401c0000, 0x812c0400, 0x50004000, - 0x82201d00, 0x000000ff, 0x4c040000, 0x0401f8af, - 0x5c000800, 0x0400002d, 0x80244840, 0x04000028, - 0x80081000, 0x82201d00, 0x0000ff00, 0x800c1910, - 0x4c040000, 0x0401f8a5, 0x5c000800, 0x04000023, - 0x80244840, 0x0400001e, 0x80081000, 0x82201d00, - 0x00ff0000, 0x800c1920, 0x4c040000, 0x0401f89b, - 0x5c000800, 0x04000019, 0x80244840, 0x04000014, - 0x80081000, 0x82201d00, 0xff000000, 0x800c1930, - 0x4c040000, 0x0401f891, 0x5c000800, 0x0400000f, - 0x80244840, 0x0400000a, 0x80081000, 0x801c3800, - 0x0401f7d5, 0x59a0020a, 0x82000500, 0x000000ff, - 0x40001800, 0x0401f885, 0x04000004, 0x4a03c014, - 0x03800000, 0x0401f425, 0x4a03c014, 0x03800000, - 0x0401f46e, 0x4803c856, 0x4a03c013, 0x03800300, + 0x800c1d40, 0x59a00a08, 0x59a00408, 0x900409c0, + 0x80040d40, 0x59a0020a, 0x82002480, 0x00000010, + 0x0400173c, 0x59a02406, 0x900001c0, 0x80100540, + 0x59a8280d, 0x80142480, 0x04001736, 0x0201f000, + 0x00103a28, 0x59a00a0a, 0x59a00406, 0x900409c0, + 0x80040d40, 0x59a01407, 0x59a00207, 0x900811c0, + 0x80081540, 0x44080800, 0x0401f6da, 0x59a00a0a, + 0x59a00406, 0x900409c0, 0x80040d40, 0x50040000, + 0x82000d00, 0x0000ffff, 0x48074207, 0x82000d00, + 0xffff0000, 0x900409c0, 0x48074407, 0x0401f6cd, + 0x59a00406, 0x8c000500, 0x04000020, 0x59a01207, + 0x59a01c07, 0x59a02208, 0x480b5054, 0x480f5055, + 0x48135056, 0x59c40801, 0x82040d00, 0x00018000, + 0x82040580, 0x00000000, 0x04000009, 0x82040580, + 0x00008000, 0x04000008, 0x82040580, 0x00010000, + 0x04000007, 0x0201f800, 0x001005d8, 0x40080000, + 0x0401f004, 0x400c0000, 0x0401f002, 0x40100000, + 0x80000110, 0x42000800, 0x000000e0, 0x0201f800, + 0x00101944, 0x0401f007, 0x59a81054, 0x59a81855, + 0x59a82056, 0x480b4207, 0x480f4407, 0x48134208, + 0x0401f6a4, 0x4d2c0000, 0x4d340000, 0x4d300000, + 0x4d440000, 0x59a28c06, 0x0201f800, 0x00020245, + 0x04000006, 0x5c028800, 0x5c026000, 0x5c026800, + 0x5c025800, 0x0401f6e7, 0x59a04407, 0x59a00207, + 0x900001c0, 0x80204540, 0x0401f81e, 0x04000009, + 0x4a034208, 0x00000001, 0x4a034406, 0x0000ffff, + 0x4a034207, 0x0000ffff, 0x497b4407, 0x0401f00b, + 0x0401f822, 0x0400000e, 0x4a034208, 0x00000002, + 0x59300402, 0x48034406, 0x59300202, 0x48034207, + 0x59300206, 0x48034407, 0x5c028800, 0x5c026000, + 0x5c026800, 0x5c025800, 0x0401f67a, 0x5c028800, + 0x5c026000, 0x5c026800, 0x5c025800, 0x0401f6c1, + 0x4937c856, 0x4823c856, 0x4d2c0000, 0x5934000f, + 0x80025d40, 0x04000007, 0x592c0005, 0x80200580, + 0x592c0000, 0x040207fb, 0x82000540, 0x00000001, + 0x5c025800, 0x1c01f000, 0x4823c857, 0x4d2c0000, + 0x4d300000, 0x42026000, 0x0010d1c0, 0x59300406, + 0x82000d80, 0x00000003, 0x04000004, 0x82000d80, + 0x00000006, 0x04020007, 0x59325808, 0x812e59c0, + 0x04000004, 0x592c0005, 0x80200580, 0x0400000a, + 0x83326400, 0x00000024, 0x41580000, 0x81300480, + 0x040017ef, 0x80000580, 0x5c026000, 0x5c025800, + 0x1c01f000, 0x82000540, 0x00000001, 0x5c026000, + 0x5c025800, 0x1c01f000, 0x83a00580, 0x0010b4a4, + 0x04020684, 0x59a80005, 0x8c00050e, 0x04020003, + 0x4a030000, 0x00000000, 0x4a034206, 0x00004000, + 0x4a03c011, 0x40000010, 0x0401fea7, 0x59e00017, + 0x8c000508, 0x04000003, 0x4a03c017, 0x00000000, + 0x4203e000, 0x30000001, 0x4203e000, 0x40000000, + 0x0401f000, 0x800409c0, 0x04000004, 0x4a034406, + 0x00000001, 0x0401f677, 0x836c0580, 0x00000003, + 0x04020010, 0x59a80010, 0x497b4406, 0x0201f800, + 0x0010513b, 0x0400000f, 0x82000d00, 0x00ffff00, + 0x0402000c, 0x82000c00, 0x0010210e, 0x50040800, + 0x80040910, 0x82041580, 0x00000080, 0x04020004, + 0x4a034406, 0x00000007, 0x0401f662, 0x48074406, + 0x82000d00, 0x0000ffff, 0x48074207, 0x80000120, + 0x48034407, 0x59a80026, 0x82001500, 0x00000100, + 0x480b4409, 0x8c000502, 0x0400001f, 0x8c000506, + 0x04000009, 0x82000d00, 0x0000000a, 0x82040d80, + 0x0000000a, 0x04020004, 0x4a034209, 0x00000001, + 0x0401f022, 0x8c00050a, 0x04000009, 0x82000d00, + 0x00000022, 0x82040d80, 0x00000022, 0x04020004, + 0x4a034209, 0x00000003, 0x0401f018, 0x8c000508, + 0x04000009, 0x82000d00, 0x00000012, 0x82040d80, + 0x00000012, 0x04020004, 0x4a034209, 0x00000002, + 0x0401f00e, 0x0201f800, 0x0010513b, 0x04020004, + 0x4a034209, 0x00000004, 0x0401f5e6, 0x8c000506, + 0x04000004, 0x4a034406, 0x00000005, 0x0401f62d, + 0x4a034209, 0x00000000, 0x0401f5de, 0x59a80037, + 0x48034407, 0x59a80038, 0x48034209, 0x0401f5d9, + 0x42007800, 0x0010b8ec, 0x59a00406, 0x4803c857, + 0x82000c80, 0x00000006, 0x04021622, 0x0c01f001, + 0x001024f6, 0x001024f7, 0x00102505, 0x00102518, + 0x00102539, 0x001024f6, 0x0401f61a, 0x836c0580, + 0x00000000, 0x04000613, 0x59a00a07, 0x59a00407, + 0x900001c0, 0x80040d40, 0x4807c857, 0x59a00a08, + 0x59a00408, 0x900001c0, 0x80040d40, 0x4807c857, + 0x0401f056, 0x836c0580, 0x00000000, 0x04000605, + 0x59a00407, 0x59a01207, 0x900001c0, 0x80081540, + 0x59a00408, 0x59a01a08, 0x900001c0, 0x800c1d40, + 0x42000000, 0x0010c1bf, 0x480fc857, 0x480bc857, + 0x42000800, 0x00001000, 0x0201f000, 0x00103a28, + 0x59a00a07, 0x59a00407, 0x900001c0, 0x80041d40, + 0x820c0c80, 0x0010ab4a, 0x040215f2, 0x820c0c80, + 0x00100000, 0x040015ef, 0x480fc857, 0x823c7c00, + 0x00000009, 0x503c0800, 0x800409c0, 0x04000006, + 0x823c0580, 0x0000000d, 0x040005e6, 0x803c7800, + 0x0401f7f9, 0x59e41001, 0x82080d00, 0xfffeffcf, + 0x4807c801, 0x440c7800, 0x46001800, 0x0201f800, + 0x800c1800, 0x46001800, 0x001005cb, 0x480bc801, + 0x0401f022, 0x59a01a07, 0x59a00407, 0x900001c0, + 0x800c1d40, 0x480c7801, 0x59a02208, 0x59a00408, + 0x900001c0, 0x80102540, 0x48107802, 0x59a00209, + 0x80000040, 0x040015cb, 0x48007806, 0x80000000, + 0x48007805, 0x42000800, 0x00004000, 0x40001000, + 0x0201f800, 0x00106681, 0x80000540, 0x04000003, + 0x49787801, 0x0401f5bf, 0x40040000, 0x800c1c00, + 0x040015bc, 0x480c7803, 0x48107804, 0x49787808, + 0x59a00409, 0x48007807, 0x59e40001, 0x4803c857, + 0x82000540, 0x00040000, 0x4803c801, 0x0401f561, + 0x59a80006, 0x48034406, 0x59a80007, 0x48034207, + 0x59a80008, 0x48034407, 0x0401f55a, 0x0201f800, + 0x001005d8, 0x4803c856, 0x4a03c013, 0x03800300, 0x4a03c014, 0x03800380, 0x59a00c06, 0x82040580, 0x000000a0, 0x04000004, 0x82040580, 0x000000a2, - 0x0402006e, 0x59a0140a, 0x82080480, 0x00000100, - 0x0402106a, 0x59a0020b, 0x8c000500, 0x0402005c, - 0x59a01a0a, 0x800c19c0, 0x04000064, 0x820c0480, - 0x00000041, 0x04021061, 0x0201f800, 0x0010381a, - 0x04020006, 0x4a034406, 0x00000002, 0x4a03c014, - 0x03800000, 0x0401f44d, 0x832e5c00, 0x00000004, + 0x0402002b, 0x59a0140a, 0x82080480, 0x00000100, + 0x04021027, 0x59a0020b, 0x8c000500, 0x0402002e, + 0x59a00a0a, 0x800409c0, 0x04000021, 0x82040480, + 0x00000041, 0x0402101e, 0x82040c00, 0x00000003, + 0x82040d00, 0x000000fc, 0x80040904, 0x59a00407, + 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, + 0x59a01a09, 0x900c19c0, 0x800c1d40, 0x0201f800, + 0x00103a00, 0x04020006, 0x4a034406, 0x00000002, + 0x4a03c014, 0x03800000, 0x0401f576, 0x832e5c00, + 0x00000004, 0x412c0000, 0x0201f800, 0x00103a25, + 0x4a01d809, 0x001025a2, 0x1c01f000, 0x4a03c014, + 0x03800000, 0x0401f56f, 0x4031d800, 0x58ef400b, + 0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200, + 0x0400055c, 0x59a00c06, 0x59a0140a, 0x59a0020b, + 0x8c000500, 0x04020031, 0x832e5c00, 0x00000004, 0x41783800, 0x59a04a0a, 0x401c0000, 0x812c0400, - 0x40004000, 0x4c040000, 0x4c080000, 0x0401f877, - 0x5c001000, 0x5c000800, 0x04000048, 0x44144000, - 0x80244840, 0x0400002b, 0x80081000, 0x4c040000, - 0x4c080000, 0x0401f86d, 0x5c001000, 0x5c000800, - 0x0400003e, 0x50200000, 0x801428d0, 0x80140540, - 0x44004000, 0x80244840, 0x0400001e, 0x80081000, - 0x4c040000, 0x4c080000, 0x0401f860, 0x5c001000, - 0x5c000800, 0x04000031, 0x50200000, 0x801428e0, - 0x80140540, 0x44004000, 0x80244840, 0x04000011, - 0x80081000, 0x4c040000, 0x4c080000, 0x0401f853, - 0x5c001000, 0x5c000800, 0x04000024, 0x50200000, - 0x801428f0, 0x80140540, 0x44004000, 0x80244840, - 0x04000004, 0x80081000, 0x801c3800, 0x0401f7cb, - 0x59a00a0a, 0x82040c00, 0x00000003, 0x82040d00, - 0x000000fc, 0x80040904, 0x59a00407, 0x59a01207, - 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, - 0x900c19c0, 0x800c1d40, 0x4a03c014, 0x03800000, - 0x412c0000, 0x0201f000, 0x00103841, 0x0401f833, - 0x04000006, 0x48174406, 0x4a03c014, 0x03800000, - 0x0201f000, 0x00102066, 0x4a03c014, 0x03800000, - 0x0201f000, 0x001020b2, 0x4a03c014, 0x03800000, - 0x0201f000, 0x001020b6, 0x0401f836, 0x04000010, - 0x0401f862, 0x0402000f, 0x40080800, 0x0401f85f, - 0x0402000c, 0x400c0800, 0x0401f85c, 0x04020009, - 0x0401f84b, 0x42000000, 0x00030d40, 0x80000040, - 0x040207ff, 0x82000540, 0x00000001, 0x1c01f000, - 0x0401f843, 0x80000580, 0x0401f7fd, 0x0401f821, - 0x0400000a, 0x82040d40, 0x00000001, 0x0401f84b, - 0x04020007, 0x0401f87e, 0x0401f898, 0x0401f838, - 0x82000540, 0x00000001, 0x1c01f000, 0x0401f834, - 0x80000580, 0x0401f7fd, 0x40041800, 0x0401f811, - 0x0400000c, 0x0401f83d, 0x0402000b, 0x40080800, - 0x0401f83a, 0x04020008, 0x400c0800, 0x0401ffe8, - 0x04000004, 0x0401f826, 0x82000540, 0x00000001, - 0x1c01f000, 0x0401f822, 0x80000580, 0x0401f7fd, - 0x4c040000, 0x42000800, 0x00000064, 0x4a03c013, - 0x03800300, 0x80040840, 0x04000016, 0x59e00013, - 0x82000500, 0x00000300, 0x82000580, 0x00000300, - 0x040207f7, 0x42000000, 0x00000064, 0x80000040, - 0x040207ff, 0x4a03c013, 0x01000000, 0x42000000, + 0x50004000, 0x82201d00, 0x000000ff, 0x4c040000, + 0x0401f8ac, 0x5c000800, 0x0400002d, 0x80244840, + 0x04000028, 0x80081000, 0x82201d00, 0x0000ff00, + 0x800c1910, 0x4c040000, 0x0401f8a2, 0x5c000800, + 0x04000023, 0x80244840, 0x0400001e, 0x80081000, + 0x82201d00, 0x00ff0000, 0x800c1920, 0x4c040000, + 0x0401f898, 0x5c000800, 0x04000019, 0x80244840, + 0x04000014, 0x80081000, 0x82201d00, 0xff000000, + 0x800c1930, 0x4c040000, 0x0401f88e, 0x5c000800, + 0x0400000f, 0x80244840, 0x0400000a, 0x80081000, + 0x801c3800, 0x0401f7d5, 0x59a0020a, 0x82000500, + 0x000000ff, 0x40001800, 0x0401f882, 0x04000004, + 0x4a03c014, 0x03800000, 0x0401f4da, 0x4a03c014, + 0x03800000, 0x0401f523, 0x4803c856, 0x4a03c013, + 0x03800300, 0x4a03c014, 0x03800380, 0x59a00c06, + 0x82040580, 0x000000a0, 0x04000004, 0x82040580, + 0x000000a2, 0x0402006c, 0x59a0140a, 0x82080480, + 0x00000100, 0x04021068, 0x59a0020b, 0x8c000500, + 0x0402005c, 0x59a01a0a, 0x800c19c0, 0x04000062, + 0x820c0480, 0x00000041, 0x0402105f, 0x0201f800, + 0x00103a00, 0x04020006, 0x4a034406, 0x00000002, + 0x4a03c014, 0x03800000, 0x0401f502, 0x832e5c00, + 0x00000004, 0x41783800, 0x59a04a0a, 0x401c0000, + 0x812c0400, 0x40004000, 0x4c040000, 0x4c080000, + 0x0401f874, 0x5c001000, 0x5c000800, 0x04000047, + 0x44144000, 0x80244840, 0x0400002b, 0x80081000, + 0x4c040000, 0x4c080000, 0x0401f86a, 0x5c001000, + 0x5c000800, 0x0400003d, 0x50200000, 0x801428d0, + 0x80140540, 0x44004000, 0x80244840, 0x0400001e, + 0x80081000, 0x4c040000, 0x4c080000, 0x0401f85d, + 0x5c001000, 0x5c000800, 0x04000030, 0x50200000, + 0x801428e0, 0x80140540, 0x44004000, 0x80244840, + 0x04000011, 0x80081000, 0x4c040000, 0x4c080000, + 0x0401f850, 0x5c001000, 0x5c000800, 0x04000023, + 0x50200000, 0x801428f0, 0x80140540, 0x44004000, + 0x80244840, 0x04000004, 0x80081000, 0x801c3800, + 0x0401f7cb, 0x59a00a0a, 0x82040c00, 0x00000003, + 0x82040d00, 0x000000fc, 0x80040904, 0x59a00407, + 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, + 0x59a01a09, 0x900c19c0, 0x800c1d40, 0x4a03c014, + 0x03800000, 0x412c0000, 0x0201f000, 0x00103a28, + 0x0401f830, 0x04000005, 0x48174406, 0x4a03c014, + 0x03800000, 0x0401f463, 0x4a03c014, 0x03800000, + 0x0401f4ac, 0x4a03c014, 0x03800000, 0x0401f4ad, + 0x0401f836, 0x04000010, 0x0401f862, 0x0402000f, + 0x40080800, 0x0401f85f, 0x0402000c, 0x400c0800, + 0x0401f85c, 0x04020009, 0x0401f84b, 0x42000000, + 0x00030d40, 0x80000040, 0x040207ff, 0x82000540, + 0x00000001, 0x1c01f000, 0x0401f843, 0x80000580, + 0x0401f7fd, 0x0401f821, 0x0400000a, 0x82040d40, + 0x00000001, 0x0401f84b, 0x04020007, 0x0401f87e, + 0x0401f898, 0x0401f838, 0x82000540, 0x00000001, + 0x1c01f000, 0x0401f834, 0x80000580, 0x0401f7fd, + 0x40041800, 0x0401f811, 0x0400000c, 0x0401f83d, + 0x0402000b, 0x40080800, 0x0401f83a, 0x04020008, + 0x400c0800, 0x0401ffe8, 0x04000004, 0x0401f826, + 0x82000540, 0x00000001, 0x1c01f000, 0x0401f822, + 0x80000580, 0x0401f7fd, 0x4c040000, 0x42000800, + 0x00000064, 0x4a03c013, 0x03800300, 0x80040840, + 0x04000016, 0x59e00013, 0x82000500, 0x00000300, + 0x82000580, 0x00000300, 0x040207f7, 0x42000000, 0x00000064, 0x80000040, 0x040207ff, 0x4a03c013, - 0x02000000, 0x82000540, 0x00000001, 0x0401f002, - 0x80000580, 0x5c000800, 0x1c01f000, 0x4a03c013, 0x01000000, 0x42000000, 0x00000064, 0x80000040, - 0x040207ff, 0x4a03c013, 0x02000200, 0x42000000, - 0x00000064, 0x80000040, 0x040207ff, 0x4a03c013, - 0x01000100, 0x1c01f000, 0x42002000, 0x00000008, - 0x82040500, 0x00000080, 0x800000c2, 0x82000540, - 0x01000000, 0x4803c013, 0x42000000, 0x00000064, - 0x80000040, 0x040207ff, 0x4a03c013, 0x02000200, - 0x42000000, 0x00000064, 0x80000040, 0x040207ff, - 0x4a03c013, 0x02000000, 0x800408c2, 0x80102040, - 0x040207ec, 0x4a03c013, 0x01000100, 0x42000000, + 0x040207ff, 0x4a03c013, 0x02000000, 0x82000540, + 0x00000001, 0x0401f002, 0x80000580, 0x5c000800, + 0x1c01f000, 0x4a03c013, 0x01000000, 0x42000000, 0x00000064, 0x80000040, 0x040207ff, 0x4a03c013, 0x02000200, 0x42000000, 0x00000064, 0x80000040, - 0x040207ff, 0x59e00013, 0x82000500, 0x00000100, - 0x4a03c013, 0x02000000, 0x4c040000, 0x42000800, - 0x00000064, 0x59e00013, 0x82000500, 0x00000100, - 0x80040840, 0x04000003, 0x80000540, 0x040207fa, - 0x80000540, 0x5c000800, 0x1c01f000, 0x4a03c013, - 0x01000100, 0x42001000, 0x00000008, 0x80000d80, - 0x42000000, 0x00000064, 0x80000040, 0x040207ff, - 0x4a03c013, 0x02000200, 0x42000000, 0x00000064, - 0x80000040, 0x040207ff, 0x59e00013, 0x82000500, - 0x00000100, 0x80000110, 0x800408c2, 0x80040d40, - 0x4a03c013, 0x02000000, 0x80081040, 0x040207ed, - 0x40042800, 0x1c01f000, 0x4a03c013, 0x01000100, + 0x040207ff, 0x4a03c013, 0x01000100, 0x1c01f000, + 0x42002000, 0x00000008, 0x82040500, 0x00000080, + 0x800000c2, 0x82000540, 0x01000000, 0x4803c013, 0x42000000, 0x00000064, 0x80000040, 0x040207ff, 0x4a03c013, 0x02000200, 0x42000000, 0x00000064, 0x80000040, 0x040207ff, 0x4a03c013, 0x02000000, - 0x1c01f000, 0x59a00407, 0x59a80837, 0x48035037, - 0x48074407, 0x59a00a09, 0x82040480, 0x00000014, - 0x04021003, 0x42000800, 0x000007d0, 0x59a80038, - 0x48075038, 0x48034209, 0x0201f000, 0x00102066, - 0x836c0580, 0x00000000, 0x0400000e, 0x59a80006, - 0x59a00c06, 0x80041580, 0x82081500, 0x00000040, - 0x02000000, 0x00102066, 0x80080580, 0x48035006, - 0x0201f800, 0x001006df, 0x0201f000, 0x00102066, - 0x59a00406, 0x59a80806, 0x48035006, 0x80040d80, - 0x8c040d0c, 0x02020800, 0x001006df, 0x59a00207, - 0x48035007, 0x59a00407, 0x48035008, 0x0201f000, - 0x00102066, 0x800409c0, 0x04000005, 0x4a034406, - 0x00000001, 0x0201f000, 0x001020b2, 0x0201f800, - 0x00104e0d, 0x04020005, 0x4a034406, 0x00000016, - 0x0201f000, 0x001020b2, 0x836c0580, 0x00000003, - 0x04000005, 0x4a034406, 0x00000007, 0x0201f000, - 0x001020b2, 0x59a00c06, 0x82040500, 0xffffff00, - 0x02020000, 0x001020b6, 0x82041580, 0x000000ff, - 0x04020007, 0x59a80010, 0x82000500, 0x000000ff, - 0x82001540, 0x0000ff00, 0x0401f011, 0x82040400, - 0x00101eb5, 0x50000000, 0x80000110, 0x82000580, - 0x00000080, 0x02000000, 0x001020b6, 0x59a80010, - 0x82000500, 0x000000ff, 0x80041580, 0x02000000, - 0x001020b6, 0x840409c0, 0x80041540, 0x0201f800, - 0x00020892, 0x04020005, 0x4a034406, 0x00000003, - 0x0201f000, 0x001020b2, 0x48ee6021, 0x480a621c, - 0x4a02641c, 0x0000bc09, 0x4a026406, 0x00000001, - 0x0201f800, 0x0010381a, 0x04020007, 0x0201f800, - 0x000208b4, 0x4a034406, 0x00000002, 0x0201f000, - 0x001020b2, 0x497a5a04, 0x497a5805, 0x4a025c04, - 0x00008000, 0x4a01d809, 0x00102657, 0x492e6008, - 0x42027000, 0x00000032, 0x0201f000, 0x000208d8, - 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, - 0x0201f000, 0x001020b2, 0x0201f800, 0x00104e0d, - 0x04020005, 0x4a034406, 0x00000016, 0x0201f000, - 0x001020b2, 0x836c0580, 0x00000003, 0x04000005, - 0x4a034406, 0x00000007, 0x0201f000, 0x001020b2, - 0x59a00c06, 0x82040500, 0xffffff00, 0x02020000, - 0x001020b6, 0x82041580, 0x000000ff, 0x04020007, - 0x59a80010, 0x82000500, 0x000000ff, 0x82001540, - 0x0000ff00, 0x0401f011, 0x82040400, 0x00101eb5, - 0x50000000, 0x80000110, 0x82000580, 0x00000080, - 0x02000000, 0x001020b6, 0x59a80010, 0x82000500, - 0x000000ff, 0x80041580, 0x02000000, 0x001020b6, - 0x840409c0, 0x80041540, 0x0201f800, 0x00020892, - 0x04020005, 0x4a034406, 0x00000003, 0x0201f000, - 0x001020b2, 0x48ee6021, 0x480a621c, 0x4a02641c, - 0x0000bc05, 0x4a026406, 0x00000001, 0x0201f800, - 0x0010381a, 0x04020007, 0x0201f800, 0x000208b4, - 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, - 0x497a5a04, 0x497a5805, 0x4a025c04, 0x00008000, - 0x4a01d809, 0x00102657, 0x492e6008, 0x42027000, - 0x00000032, 0x0201f000, 0x000208d8, 0x592c0005, - 0x82000580, 0x01000000, 0x02020000, 0x00102066, - 0x4a034406, 0x00000004, 0x0201f000, 0x001020b2, - 0x497b4406, 0x497b4207, 0x0201f800, 0x0010393e, - 0x04000008, 0x59a80066, 0x59a8086a, 0x80040480, - 0x59a80867, 0x48074406, 0x80041480, 0x480b4207, - 0x49674407, 0x59a8000e, 0x48034209, 0x495f4409, - 0x59a80020, 0x4803420b, 0x0201f000, 0x00102066, - 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, - 0x0201f000, 0x001020b2, 0x59a00406, 0x8c000500, - 0x0402000f, 0x59a80069, 0x81640480, 0x04001008, - 0x59a8000b, 0x81500580, 0x04000009, 0x59a8006a, - 0x59a81066, 0x80080580, 0x04000005, 0x4a034406, - 0x00000018, 0x0201f000, 0x001020b2, 0x59a80005, - 0x84000558, 0x48035005, 0x82000540, 0x00000001, - 0x0201f800, 0x00101668, 0x0201f800, 0x00103a9f, - 0x0201f000, 0x00102066, 0x4803c856, 0x800409c0, - 0x02020000, 0x001020ba, 0x59a00406, 0x8c00051e, - 0x04000008, 0x4803c856, 0x59a0020b, 0x82000480, - 0x00000800, 0x04001015, 0x0201f000, 0x001020b6, - 0x4803c856, 0x59a0020b, 0x599c0a01, 0x80040480, - 0x04021003, 0x0201f000, 0x001020b6, 0x59a8000e, - 0x81640580, 0x04000009, 0x4a034406, 0x00000018, - 0x0201f000, 0x001020b2, 0x4a034406, 0x00000005, - 0x0201f000, 0x001020b2, 0x59a80026, 0x8c00050a, - 0x040007fa, 0x59a00406, 0x8c00051e, 0x04000036, - 0x0201f800, 0x00020892, 0x040007f4, 0x0201f800, - 0x0010381a, 0x040007f1, 0x497a5a04, 0x59a00406, - 0x4802620a, 0x59a00209, 0x4802640a, 0x59a00409, - 0x4802620b, 0x59a0020d, 0x4802620c, 0x59a0040d, - 0x4802640c, 0x59a0020e, 0x4802620d, 0x59a0040e, - 0x4802640d, 0x59a00210, 0x4802620e, 0x59a00410, - 0x4802640e, 0x59a0020b, 0x82000500, 0x0000fffc, - 0x80000104, 0x4802640b, 0x0401f9d9, 0x040007d7, - 0x48ee6021, 0x58ee580d, 0x5930020e, 0x59301c0e, - 0x900c19c0, 0x800c1d40, 0x5930020c, 0x5930140c, - 0x900811c0, 0x80081540, 0x592c0a05, 0x832c0400, - 0x00000006, 0x0201f800, 0x0010383e, 0x4a01d809, - 0x00102846, 0x4a034000, 0x00000001, 0x49334001, - 0x1c01f000, 0x0201f800, 0x0010698c, 0x0201f800, - 0x00100b29, 0x0401f86d, 0x497b5057, 0x4201d000, - 0x00002710, 0x0201f800, 0x00105e06, 0x59c40880, - 0x4c040000, 0x59c408a3, 0x4c040000, 0x497b4002, - 0x0401f876, 0x0401f893, 0x4a03a005, 0x10000000, - 0x0401f8b4, 0x0401f901, 0x04000048, 0x59c80001, - 0x800001c0, 0x040007fc, 0x59c80018, 0x82000500, - 0xf0000000, 0x59c00808, 0x82040d00, 0x0fffffff, - 0x80040540, 0x48038008, 0x0201f800, 0x00100f0f, - 0x59c00006, 0x4a038006, 0x10000000, 0x59c00009, - 0x82000d00, 0x00e00000, 0x04020024, 0x4a03900d, - 0x00000000, 0x59c80020, 0x82000500, 0xff000000, - 0x82000580, 0x32000000, 0x0402001c, 0x4a03900d, - 0x00000001, 0x59c80020, 0x82000500, 0xff000000, - 0x82000580, 0xe1000000, 0x04020014, 0x4a03900d, - 0x00000000, 0x59c80020, 0x82000500, 0x00ffffff, - 0x4a03900d, 0x00000000, 0x59c80821, 0x82040d00, - 0x00ffffff, 0x80040580, 0x04020008, 0x59a80010, - 0x80040580, 0x04020005, 0x59c40005, 0x82000500, - 0x000000f0, 0x04000006, 0x4803c856, 0x0401f8d7, - 0x4a035057, 0x00000001, 0x0401f002, 0x0401f8e1, - 0x42000000, 0x00000064, 0x80000040, 0x02000800, - 0x00100615, 0x59c00807, 0x82040d00, 0x0000000c, - 0x040007fa, 0x0401f003, 0x4a035057, 0x00000001, - 0x0401f8da, 0x0201f800, 0x00106c8a, 0x0401f818, - 0x4201d000, 0x000186a0, 0x0201f800, 0x00105e06, - 0x5c000800, 0x480788a3, 0x5c000800, 0x48078880, - 0x59a80057, 0x800001c0, 0x02000000, 0x00102066, - 0x0201f000, 0x001020be, 0x599c0201, 0x48035059, - 0x41780800, 0x42001000, 0x00003b10, 0x0201f800, - 0x001063ee, 0x480b505a, 0x1c01f000, 0x0201f800, - 0x00106982, 0x59b800ea, 0x82000500, 0x00000007, - 0x82000580, 0x00000003, 0x04020003, 0x4a0370e8, - 0x00000001, 0x1c01f000, 0x42038000, 0x00007700, - 0x4a038006, 0x30000000, 0x59c00007, 0x8c00050a, - 0x040207fe, 0x59c00006, 0x59a00209, 0x59a00c09, - 0x900409c0, 0x80040d40, 0x48078001, 0x59a0020e, - 0x59a00c0e, 0x900409c0, 0x80040d40, 0x48078000, - 0x59a0020b, 0x82000500, 0x0000fffc, 0x48038002, - 0x48038003, 0x48038005, 0x497b9009, 0x59e00003, - 0x82000540, 0x00008060, 0x4803c003, 0x1c01f000, - 0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600, - 0x42000800, 0x00000040, 0x0201f800, 0x00101395, - 0x4a03a00a, 0x00000001, 0x4a03a005, 0x20000000, - 0x59d00006, 0x4a03a005, 0x30000000, 0x59d00006, - 0x8c00050a, 0x040207fe, 0x59d00005, 0x59a00210, - 0x59a00c10, 0x900409c0, 0x80040d40, 0x4807a001, - 0x59a0020d, 0x59a00c0d, 0x900409c0, 0x80040d40, - 0x4807a000, 0x59a0020b, 0x82000500, 0x0000fffc, - 0x4803a003, 0x4803a002, 0x4803a008, 0x1c01f000, - 0x59a00002, 0x4803c857, 0x800001c0, 0x0402004a, - 0x59a8005a, 0x48038880, 0x59c400a3, 0x82000540, - 0x00002008, 0x8400053a, 0x480388a3, 0x59c40008, - 0x8400054e, 0x82000500, 0xffffffe1, 0x48038808, - 0x59c80040, 0x84000534, 0x48039040, 0x0401f902, - 0x04020013, 0x59a80010, 0x800000d0, 0x82000540, - 0x00000011, 0x48039120, 0x59a80010, 0x82000500, - 0x00ffffff, 0x82000540, 0x32000000, 0x48039121, - 0x4a039123, 0xe1290008, 0x59a80010, 0x82000500, - 0x00ffffff, 0x48039122, 0x0401f016, 0x59a80010, - 0x82000500, 0x000000ff, 0x900009c0, 0x840001c0, - 0x80040540, 0x82000540, 0x00000000, 0x48039120, - 0x59a80010, 0x82000500, 0x000000ff, 0x82000540, - 0x01000000, 0x48039121, 0x4a039123, 0x08210008, - 0x59a80010, 0x82000500, 0x000000ff, 0x48039122, - 0x497b9124, 0x59a80c5b, 0x80040800, 0x4807545b, - 0x900409c0, 0x82040540, 0x0000aaaa, 0x48039125, - 0x497b9126, 0x497b9127, 0x0401f8cf, 0x04020004, - 0x4a039100, 0x0000e980, 0x0401f003, 0x4a039100, - 0x0000e9a0, 0x1c01f000, 0x82000540, 0x00000001, - 0x0402500d, 0x4203e000, 0x80000000, 0x40e81000, - 0x41780800, 0x42000000, 0x00000064, 0x0201f800, - 0x001063ee, 0x59940024, 0x80080400, 0x48032824, - 0x80000580, 0x1c01f000, 0x4d900000, 0x4dd00000, - 0x4da40000, 0x4d140000, 0x417a3000, 0x0201f800, - 0x00106e2f, 0x0201f800, 0x00106b13, 0x5c022800, - 0x5c034800, 0x5c03a000, 0x5c032000, 0x1c01f000, - 0x59c80007, 0x8c000500, 0x04000003, 0x4a03900d, - 0x00000030, 0x1c01f000, 0x4a038805, 0x00020000, - 0x42000800, 0x0000003c, 0x0201f800, 0x00101395, - 0x4a038891, 0x0000ffff, 0x59c80035, 0x48039035, - 0x4a03900d, 0x00000040, 0x42038000, 0x00007700, - 0x0201f800, 0x00100f0f, 0x42038000, 0x00007720, - 0x0201f800, 0x00100f0f, 0x4a03a005, 0x20000000, - 0x4a03a005, 0x30000000, 0x59d00806, 0x8c040d0a, - 0x040207fe, 0x1c01f000, 0x4d300000, 0x4031d800, - 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, - 0x00000200, 0x5c026000, 0x02000000, 0x001020aa, - 0x4d300000, 0x59a26001, 0x59a00000, 0x4000b000, - 0x80000000, 0x48034000, 0x592c0001, 0x80000540, - 0x0400001e, 0x40025800, 0x8058b040, 0x040207fb, - 0x58ec1007, 0x58ec1808, 0x592c0a05, 0x4d2c0000, - 0x58ec000d, 0x40025800, 0x592c0204, 0x5c025800, - 0x82000580, 0x00000103, 0x04000008, 0x832c0400, - 0x00000006, 0x0201f800, 0x0010383e, 0x4a01d809, - 0x00102846, 0x0401f007, 0x832c0400, 0x00000006, - 0x0201f800, 0x00103841, 0x4a01d809, 0x00102846, - 0x5c026000, 0x1c01f000, 0x58ec000d, 0x40025800, - 0x592c0204, 0x82000580, 0x00000103, 0x04020006, - 0x0201f800, 0x000208b4, 0x5c026000, 0x0201f000, - 0x00102066, 0x58ec000d, 0x40025800, 0x592c0404, - 0x8400055e, 0x48025c04, 0x42028800, 0x000007fd, - 0x42003000, 0x00fffffd, 0x0201f800, 0x001043fc, - 0x04000003, 0x80000580, 0x0401f004, 0x59a26001, - 0x0201f800, 0x00109146, 0x5c026000, 0x02000000, - 0x001020b2, 0x4d300000, 0x4a01d809, 0x00102899, - 0x0401f7dc, 0x592c0005, 0x82000580, 0x01000000, - 0x02000000, 0x001020be, 0x4d300000, 0x59a26001, - 0x5930020b, 0x59301c0a, 0x900001c0, 0x800c1d40, - 0x5930040d, 0x5930120d, 0x900001c0, 0x80081540, - 0x592c0a05, 0x832c0400, 0x00000006, 0x0201f800, - 0x00103841, 0x4a01d809, 0x00102846, 0x4a034000, - 0x00000001, 0x5c026000, 0x1c01f000, 0x4933c857, - 0x4c300000, 0x5930040b, 0x82000c80, 0x0000000e, - 0x04001004, 0x4a025a05, 0x0000000e, 0x0401f003, - 0x48025a05, 0x0401f00c, 0x800409c0, 0x0400000a, - 0x4c040000, 0x0201f800, 0x0010381a, 0x5c000800, - 0x04000003, 0x40040000, 0x0401f7f0, 0x80000580, - 0x0401f003, 0x82000540, 0x00000001, 0x5c006000, - 0x1c01f000, 0x59a00206, 0x82000580, 0x00000044, - 0x1c01f000, 0x4807c857, 0x800409c0, 0x0400000c, - 0x0201f800, 0x001016c1, 0x04020009, 0x42000000, - 0x00000002, 0x0201f800, 0x001018fa, 0x42000000, - 0x00000002, 0x0201f800, 0x00101892, 0x59a00406, - 0x82000500, 0x00000007, 0x0c01f001, 0x001028ed, - 0x00102902, 0x00102918, 0x001028eb, 0x001028eb, - 0x001028eb, 0x001028eb, 0x001028eb, 0x0201f000, - 0x001020b6, 0x42000800, 0x000000c0, 0x0201f800, - 0x001019ac, 0x82040540, 0x00000002, 0x42000800, - 0x000000c0, 0x0201f800, 0x001019b1, 0x42000800, - 0x00000000, 0x0201f800, 0x001019ac, 0x82040540, - 0x00000008, 0x42000800, 0x00000000, 0x0201f800, - 0x001019b1, 0x0401f00b, 0x42000800, 0x000000c0, - 0x0201f800, 0x001019ac, 0x82040540, 0x00000001, - 0x42000800, 0x000000c0, 0x0201f800, 0x001019b1, - 0x59c80040, 0x4c000000, 0x59a80010, 0x4c000000, - 0x59c400a3, 0x4c000000, 0x59c40008, 0x4c000000, - 0x0401f911, 0x04000021, 0x0201f800, 0x00100615, - 0x59a80821, 0x800409c0, 0x02020000, 0x001020ba, - 0x0201f800, 0x00104e0d, 0x04020005, 0x4a034406, - 0x00000016, 0x0201f000, 0x001020b2, 0x836c0580, - 0x00000003, 0x02020000, 0x001020ba, 0x59c408a4, - 0x82040d00, 0x0000000f, 0x82040580, 0x00000000, - 0x02020000, 0x001020ba, 0x59c80040, 0x4c000000, - 0x59a80010, 0x4c000000, 0x59c400a3, 0x4c000000, - 0x59c40008, 0x4c000000, 0x59c40080, 0x4c000000, - 0x59a0020f, 0x59a0bc0f, 0x905cb9c0, 0x805cbd40, - 0x41784800, 0x41785000, 0x41785800, 0x41789000, - 0x41789800, 0x0401fe21, 0x0201f800, 0x0010698c, - 0x0201f800, 0x00100b29, 0x4178c000, 0x497b4002, - 0x0401f95c, 0x0401f9aa, 0x59a0020c, 0x59a00c0c, - 0x80040d40, 0x04000002, 0x0401f9fb, 0x0401f9fa, - 0x0401fe68, 0x8060c1c0, 0x04020014, 0x0401fa98, - 0x0401feb2, 0x0402000e, 0x0201f800, 0x00101941, - 0x04020008, 0x4a034406, 0x00000017, 0x0201f800, - 0x001020b2, 0x4203e000, 0x50000000, 0x0401f000, - 0x42005800, 0x0000aaaa, 0x0401f058, 0x59c80001, - 0x800001c0, 0x040007ee, 0x59c80801, 0x800409c0, - 0x04000006, 0x0401fa70, 0x40240000, 0x80280540, - 0x802c0540, 0x0402004d, 0x59a00002, 0x82000580, - 0xfeedbeef, 0x04000004, 0x42008800, 0x10000000, - 0x0401f003, 0x42008800, 0x10000004, 0x0401fa19, - 0x4a034002, 0xfeedbeef, 0x0401fa71, 0x0401fa97, - 0x0401fea8, 0x59c40005, 0x8c000534, 0x04000004, - 0x42005800, 0x0000bbbb, 0x0401f038, 0x0401fe83, - 0x04020007, 0x42005800, 0x0000cccc, 0x485f420f, - 0x905cb9c0, 0x485f440f, 0x0401f030, 0x59a0040c, - 0x800001c0, 0x0400000e, 0x59a26000, 0x5930000d, - 0x800001c0, 0x040207be, 0x59a26001, 0x5930080d, - 0x800409c0, 0x040207ba, 0x804891c0, 0x040207b8, - 0x804c99c0, 0x040207b6, 0x0401f87a, 0x805cb840, - 0x04000005, 0x40240000, 0x80280540, 0x802c0540, - 0x0402001a, 0x42000000, 0x00030d40, 0x80000040, - 0x04020012, 0x59c00007, 0x82000500, 0x000501c0, - 0x0402000b, 0x0201f800, 0x00101941, 0x04020008, - 0x4a034406, 0x00000017, 0x0201f800, 0x001020b2, + 0x800408c2, 0x80102040, 0x040207ec, 0x4a03c013, + 0x01000100, 0x42000000, 0x00000064, 0x80000040, + 0x040207ff, 0x4a03c013, 0x02000200, 0x42000000, + 0x00000064, 0x80000040, 0x040207ff, 0x59e00013, + 0x82000500, 0x00000100, 0x4a03c013, 0x02000000, + 0x4c040000, 0x42000800, 0x00000064, 0x59e00013, + 0x82000500, 0x00000100, 0x80040840, 0x04000003, + 0x80000540, 0x040207fa, 0x80000540, 0x5c000800, + 0x1c01f000, 0x4a03c013, 0x01000100, 0x42001000, + 0x00000008, 0x80000d80, 0x42000000, 0x00000064, + 0x80000040, 0x040207ff, 0x4a03c013, 0x02000200, + 0x42000000, 0x00000064, 0x80000040, 0x040207ff, + 0x59e00013, 0x82000500, 0x00000100, 0x80000110, + 0x800408c2, 0x80040d40, 0x4a03c013, 0x02000000, + 0x80081040, 0x040207ed, 0x40042800, 0x1c01f000, + 0x4a03c013, 0x01000100, 0x42000000, 0x00000064, + 0x80000040, 0x040207ff, 0x4a03c013, 0x02000200, + 0x42000000, 0x00000064, 0x80000040, 0x040207ff, + 0x4a03c013, 0x02000000, 0x1c01f000, 0x59a00407, + 0x59a80837, 0x48035037, 0x48074407, 0x59a00a09, + 0x82040480, 0x00000014, 0x04021003, 0x42000800, + 0x000007d0, 0x59a80038, 0x48075038, 0x48034209, + 0x0201f000, 0x001022c0, 0x836c0580, 0x00000000, + 0x0400000e, 0x59a80006, 0x59a00c06, 0x80041580, + 0x82081500, 0x00000040, 0x02000000, 0x001022c0, + 0x80080580, 0x48035006, 0x0201f800, 0x00100699, + 0x0201f000, 0x001022c0, 0x59a00406, 0x59a80806, + 0x48035006, 0x80040d80, 0x8c040d0c, 0x02020800, + 0x00100699, 0x59a00207, 0x48035007, 0x59a00407, + 0x48035008, 0x0201f000, 0x001022c0, 0x800409c0, + 0x04000005, 0x4a034406, 0x00000001, 0x0201f000, + 0x0010230c, 0x0201f800, 0x0010513b, 0x04020005, + 0x4a034406, 0x00000016, 0x0201f000, 0x0010230c, + 0x836c0580, 0x00000003, 0x04000005, 0x4a034406, + 0x00000007, 0x0201f000, 0x0010230c, 0x59a00c06, + 0x82040500, 0xffffff00, 0x02020000, 0x00102310, + 0x82041580, 0x000000ff, 0x04020007, 0x59a80010, + 0x82000500, 0x000000ff, 0x82001540, 0x0000ff00, + 0x0401f011, 0x82040400, 0x0010210e, 0x50000000, + 0x80000110, 0x82000580, 0x00000080, 0x02000000, + 0x00102310, 0x59a80010, 0x82000500, 0x000000ff, + 0x80041580, 0x02000000, 0x00102310, 0x840409c0, + 0x80041540, 0x0201f800, 0x0002075a, 0x04020005, + 0x4a034406, 0x00000003, 0x0201f000, 0x0010230c, + 0x48ee6021, 0x480a621c, 0x4a02641c, 0x0000bc09, + 0x4a026406, 0x00000001, 0x0201f800, 0x00103a00, + 0x04020007, 0x0201f800, 0x0002077d, 0x4a034406, + 0x00000002, 0x0201f000, 0x0010230c, 0x497a5a04, + 0x497a5805, 0x4a025c04, 0x00008000, 0x4a01d809, + 0x001027f9, 0x492e6008, 0x42027000, 0x00000032, + 0x0201f000, 0x000207a1, 0x800409c0, 0x04000005, + 0x4a034406, 0x00000001, 0x0201f000, 0x0010230c, + 0x0201f800, 0x0010513b, 0x04020005, 0x4a034406, + 0x00000016, 0x0201f000, 0x0010230c, 0x836c0580, + 0x00000003, 0x04000005, 0x4a034406, 0x00000007, + 0x0201f000, 0x0010230c, 0x59a00c06, 0x82040500, + 0xffffff00, 0x02020000, 0x00102310, 0x82041580, + 0x000000ff, 0x04020007, 0x59a80010, 0x82000500, + 0x000000ff, 0x82001540, 0x0000ff00, 0x0401f011, + 0x82040400, 0x0010210e, 0x50000000, 0x80000110, + 0x82000580, 0x00000080, 0x02000000, 0x00102310, + 0x59a80010, 0x82000500, 0x000000ff, 0x80041580, + 0x02000000, 0x00102310, 0x840409c0, 0x80041540, + 0x0201f800, 0x0002075a, 0x04020005, 0x4a034406, + 0x00000003, 0x0201f000, 0x0010230c, 0x48ee6021, + 0x480a621c, 0x4a02641c, 0x0000bc05, 0x4a026406, + 0x00000001, 0x0201f800, 0x00103a00, 0x04020007, + 0x0201f800, 0x0002077d, 0x4a034406, 0x00000002, + 0x0201f000, 0x0010230c, 0x497a5a04, 0x497a5805, + 0x4a025c04, 0x00008000, 0x4a01d809, 0x001027f9, + 0x492e6008, 0x42027000, 0x00000032, 0x0201f000, + 0x000207a1, 0x592c0005, 0x82000580, 0x01000000, + 0x02020000, 0x001022c0, 0x4a034406, 0x00000004, + 0x0201f000, 0x0010230c, 0x497b4406, 0x497b4207, + 0x0201f800, 0x00103b25, 0x04000008, 0x59a80066, + 0x59a8086a, 0x80040480, 0x59a80867, 0x48074406, + 0x80041480, 0x480b4207, 0x49674407, 0x59a8000e, + 0x48034209, 0x495f4409, 0x59a80020, 0x4803420b, + 0x0201f000, 0x001022c0, 0x800409c0, 0x04000005, + 0x4a034406, 0x00000001, 0x0201f000, 0x0010230c, + 0x59a00406, 0x8c000500, 0x0402000f, 0x59a80069, + 0x81640480, 0x04001008, 0x59a8000b, 0x81500580, + 0x04000009, 0x59a8006a, 0x59a81066, 0x80080580, + 0x04000005, 0x4a034406, 0x00000018, 0x0201f000, + 0x0010230c, 0x82000540, 0x00000001, 0x0201f800, + 0x001015fe, 0x0201f800, 0x00103c80, 0x0201f000, + 0x001022c0, 0x4803c856, 0x800409c0, 0x02020000, + 0x00102314, 0x59a00406, 0x8c00051e, 0x04000008, + 0x4803c856, 0x59a0020b, 0x82000480, 0x00000800, + 0x04001015, 0x0201f000, 0x00102310, 0x4803c856, + 0x59a0020b, 0x599c0a01, 0x80040480, 0x04021003, + 0x0201f000, 0x00102310, 0x59a8000e, 0x81640580, + 0x04000009, 0x4a034406, 0x00000018, 0x0201f000, + 0x0010230c, 0x4a034406, 0x00000005, 0x0201f000, + 0x0010230c, 0x59a80026, 0x8c00050a, 0x040007fa, + 0x59a00406, 0x8c00051e, 0x04000036, 0x0201f800, + 0x0002075a, 0x040007f4, 0x0201f800, 0x00103a00, + 0x040007f1, 0x497a5a04, 0x59a00406, 0x4802620a, + 0x59a00209, 0x4802640a, 0x59a00409, 0x4802620b, + 0x59a0020d, 0x4802620c, 0x59a0040d, 0x4802640c, + 0x59a0020e, 0x4802620d, 0x59a0040e, 0x4802640d, + 0x59a00210, 0x4802620e, 0x59a00410, 0x4802640e, + 0x59a0020b, 0x82000500, 0x0000fffc, 0x80000104, + 0x4802640b, 0x0401f9d9, 0x040007d7, 0x48ee6021, + 0x58ee580d, 0x5930020e, 0x59301c0e, 0x900c19c0, + 0x800c1d40, 0x5930020c, 0x5930140c, 0x900811c0, + 0x80081540, 0x592c0a05, 0x832c0400, 0x00000006, + 0x0201f800, 0x00103a25, 0x4a01d809, 0x001029e5, + 0x4a034000, 0x00000001, 0x49334001, 0x1c01f000, + 0x0201f800, 0x00106c55, 0x0201f800, 0x00100ae0, + 0x0401f86d, 0x497b5057, 0x4201d000, 0x00002710, + 0x0201f800, 0x001060c6, 0x59c40880, 0x4c040000, + 0x59c408a3, 0x4c040000, 0x497b4002, 0x0401f876, + 0x0401f893, 0x4a03a005, 0x10000000, 0x0401f8b4, + 0x0401f901, 0x04000048, 0x59c80001, 0x800001c0, + 0x040007fc, 0x59c80018, 0x82000500, 0xf0000000, + 0x59c00808, 0x82040d00, 0x0fffffff, 0x80040540, + 0x48038008, 0x0201f800, 0x00100ec1, 0x59c00006, + 0x4a038006, 0x10000000, 0x59c00009, 0x82000d00, + 0x00e00000, 0x04020024, 0x4a03900d, 0x00000000, + 0x59c80020, 0x82000500, 0xff000000, 0x82000580, + 0x32000000, 0x0402001c, 0x4a03900d, 0x00000001, + 0x59c80020, 0x82000500, 0xff000000, 0x82000580, + 0xe1000000, 0x04020014, 0x4a03900d, 0x00000000, + 0x59c80020, 0x82000500, 0x00ffffff, 0x4a03900d, + 0x00000000, 0x59c80821, 0x82040d00, 0x00ffffff, + 0x80040580, 0x04020008, 0x59a80010, 0x80040580, + 0x04020005, 0x59c40005, 0x82000500, 0x000000f0, + 0x04000006, 0x4803c856, 0x0401f8d7, 0x4a035057, + 0x00000001, 0x0401f002, 0x0401f8e1, 0x42000000, + 0x00000064, 0x80000040, 0x02000800, 0x001005d8, + 0x59c00807, 0x82040d00, 0x0000000c, 0x040007fa, + 0x0401f003, 0x4a035057, 0x00000001, 0x0401f8da, + 0x0201f800, 0x00106f36, 0x0401f818, 0x4201d000, + 0x000186a0, 0x0201f800, 0x001060c6, 0x5c000800, + 0x480788a3, 0x5c000800, 0x48078880, 0x59a80057, + 0x800001c0, 0x02000000, 0x001022c0, 0x0201f000, + 0x00102318, 0x599c0201, 0x48035059, 0x41780800, + 0x42001000, 0x00003b10, 0x0201f800, 0x001066a0, + 0x480b505a, 0x1c01f000, 0x0201f800, 0x00106c4b, + 0x59b800ea, 0x82000500, 0x00000007, 0x82000580, + 0x00000003, 0x04020003, 0x4a0370e8, 0x00000001, + 0x1c01f000, 0x42038000, 0x00007700, 0x4a038006, + 0x30000000, 0x59c00007, 0x8c00050a, 0x040207fe, + 0x59c00006, 0x59a00209, 0x59a00c09, 0x900409c0, + 0x80040d40, 0x48078001, 0x59a0020e, 0x59a00c0e, + 0x900409c0, 0x80040d40, 0x48078000, 0x59a0020b, + 0x82000500, 0x0000fffc, 0x48038002, 0x48038003, + 0x48038005, 0x497b9009, 0x59e00003, 0x82000540, + 0x00008060, 0x4803c003, 0x1c01f000, 0x41780800, + 0x8007a0ca, 0x83d3a400, 0x00007600, 0x42000800, + 0x00000040, 0x0201f800, 0x00101345, 0x4a03a00a, + 0x00000001, 0x4a03a005, 0x20000000, 0x59d00006, + 0x4a03a005, 0x30000000, 0x59d00006, 0x8c00050a, + 0x040207fe, 0x59d00005, 0x59a00210, 0x59a00c10, + 0x900409c0, 0x80040d40, 0x4807a001, 0x59a0020d, + 0x59a00c0d, 0x900409c0, 0x80040d40, 0x4807a000, + 0x59a0020b, 0x82000500, 0x0000fffc, 0x4803a003, + 0x4803a002, 0x4803a008, 0x1c01f000, 0x59a00002, + 0x4803c857, 0x800001c0, 0x0402004a, 0x59a8005a, + 0x48038880, 0x59c400a3, 0x82000540, 0x00002008, + 0x8400053a, 0x480388a3, 0x59c40008, 0x8400054e, + 0x82000500, 0xffffffe1, 0x48038808, 0x59c80040, + 0x84000534, 0x48039040, 0x0401f902, 0x04020013, + 0x59a80010, 0x800000d0, 0x82000540, 0x00000011, + 0x48039120, 0x59a80010, 0x82000500, 0x00ffffff, + 0x82000540, 0x32000000, 0x48039121, 0x4a039123, + 0xe1290008, 0x59a80010, 0x82000500, 0x00ffffff, + 0x48039122, 0x0401f016, 0x59a80010, 0x82000500, + 0x000000ff, 0x900009c0, 0x840001c0, 0x80040540, + 0x82000540, 0x00000000, 0x48039120, 0x59a80010, + 0x82000500, 0x000000ff, 0x82000540, 0x01000000, + 0x48039121, 0x4a039123, 0x08210008, 0x59a80010, + 0x82000500, 0x000000ff, 0x48039122, 0x497b9124, + 0x59a80c5b, 0x80040800, 0x4807545b, 0x900409c0, + 0x82040540, 0x0000aaaa, 0x48039125, 0x497b9126, + 0x497b9127, 0x0401f8cf, 0x04020004, 0x4a039100, + 0x0000e980, 0x0401f003, 0x4a039100, 0x0000e9a0, + 0x1c01f000, 0x82000540, 0x00000001, 0x0402500d, + 0x4203e000, 0x80000000, 0x40e81000, 0x41780800, + 0x42000000, 0x00000064, 0x0201f800, 0x001066a0, + 0x59940024, 0x80080400, 0x48032824, 0x80000580, + 0x1c01f000, 0x4d900000, 0x4dd00000, 0x4da40000, + 0x4d140000, 0x417a3000, 0x0201f800, 0x001070d8, + 0x0201f800, 0x00106dc3, 0x5c022800, 0x5c034800, + 0x5c03a000, 0x5c032000, 0x1c01f000, 0x59c80007, + 0x8c000500, 0x04000003, 0x4a03900d, 0x00000030, + 0x1c01f000, 0x4a038805, 0x00020000, 0x42000800, + 0x0000003c, 0x0201f800, 0x00101345, 0x4a038891, + 0x0000ffff, 0x59c80035, 0x48039035, 0x4a03900d, + 0x00000040, 0x42038000, 0x00007700, 0x0201f800, + 0x00100ec1, 0x42038000, 0x00007720, 0x0201f800, + 0x00100ec1, 0x4a03a005, 0x20000000, 0x4a03a005, + 0x30000000, 0x59d00806, 0x8c040d0a, 0x040207fe, + 0x1c01f000, 0x4d300000, 0x4031d800, 0x58ef400b, + 0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200, + 0x5c026000, 0x02000000, 0x00102304, 0x4d300000, + 0x59a26001, 0x59a00000, 0x4000b000, 0x80000000, + 0x48034000, 0x592c0001, 0x80000540, 0x0400001e, + 0x40025800, 0x8058b040, 0x040207fb, 0x58ec1007, + 0x58ec1808, 0x592c0a05, 0x4d2c0000, 0x58ec000d, + 0x40025800, 0x592c0204, 0x5c025800, 0x82000580, + 0x00000103, 0x04000008, 0x832c0400, 0x00000006, + 0x0201f800, 0x00103a25, 0x4a01d809, 0x001029e5, + 0x0401f007, 0x832c0400, 0x00000006, 0x0201f800, + 0x00103a28, 0x4a01d809, 0x001029e5, 0x5c026000, + 0x1c01f000, 0x58ec000d, 0x40025800, 0x592c0204, + 0x82000580, 0x00000103, 0x04020006, 0x0201f800, + 0x0002077d, 0x5c026000, 0x0201f000, 0x001022c0, + 0x58ec000d, 0x40025800, 0x592c0404, 0x8400055e, + 0x48025c04, 0x42028800, 0x000007fd, 0x42003000, + 0x00fffffd, 0x0201f800, 0x001045a6, 0x04000003, + 0x80000580, 0x0401f004, 0x59a26001, 0x0201f800, + 0x0010937d, 0x5c026000, 0x02000000, 0x0010230c, + 0x4d300000, 0x4a01d809, 0x00102a38, 0x0401f7dc, + 0x592c0005, 0x82000580, 0x01000000, 0x02000000, + 0x00102318, 0x4d300000, 0x59a26001, 0x5930020b, + 0x59301c0a, 0x900001c0, 0x800c1d40, 0x5930040d, + 0x5930120d, 0x900001c0, 0x80081540, 0x592c0a05, + 0x832c0400, 0x00000006, 0x0201f800, 0x00103a28, + 0x4a01d809, 0x001029e5, 0x4a034000, 0x00000001, + 0x5c026000, 0x1c01f000, 0x4933c857, 0x4c300000, + 0x5930040b, 0x82000c80, 0x0000000e, 0x04001004, + 0x4a025a05, 0x0000000e, 0x0401f003, 0x48025a05, + 0x0401f00c, 0x800409c0, 0x0400000a, 0x4c040000, + 0x0201f800, 0x00103a00, 0x5c000800, 0x04000003, + 0x40040000, 0x0401f7f0, 0x80000580, 0x0401f003, + 0x82000540, 0x00000001, 0x5c006000, 0x1c01f000, + 0x59a00206, 0x82000580, 0x00000044, 0x1c01f000, + 0x4807c857, 0x800409c0, 0x0400000c, 0x0201f800, + 0x00101650, 0x04020009, 0x42000000, 0x00000002, + 0x0201f800, 0x0010188c, 0x42000000, 0x00000002, + 0x0201f800, 0x00101821, 0x59a00406, 0x82000500, + 0x00000007, 0x0c01f001, 0x00102a8c, 0x00102aa1, + 0x00102ab7, 0x00102a8a, 0x00102a8a, 0x00102a8a, + 0x00102a8a, 0x00102a8a, 0x0201f000, 0x00102310, + 0x42000800, 0x000000c0, 0x0201f800, 0x0010193f, + 0x82040540, 0x00000002, 0x42000800, 0x000000c0, + 0x0201f800, 0x00101944, 0x42000800, 0x00000000, + 0x0201f800, 0x0010193f, 0x82040540, 0x00000008, + 0x42000800, 0x00000000, 0x0201f800, 0x00101944, + 0x0401f00b, 0x42000800, 0x000000c0, 0x0201f800, + 0x0010193f, 0x82040540, 0x00000001, 0x42000800, + 0x000000c0, 0x0201f800, 0x00101944, 0x59c80040, + 0x4c000000, 0x59a80010, 0x4c000000, 0x59c400a3, + 0x4c000000, 0x59c40008, 0x4c000000, 0x0401f911, + 0x04000021, 0x0201f800, 0x001005d8, 0x59a80821, + 0x800409c0, 0x02020000, 0x00102314, 0x0201f800, + 0x0010513b, 0x04020005, 0x4a034406, 0x00000016, + 0x0201f000, 0x0010230c, 0x836c0580, 0x00000003, + 0x02020000, 0x00102314, 0x59c408a4, 0x82040d00, + 0x0000000f, 0x82040580, 0x00000000, 0x02020000, + 0x00102314, 0x59c80040, 0x4c000000, 0x59a80010, + 0x4c000000, 0x59c400a3, 0x4c000000, 0x59c40008, + 0x4c000000, 0x59c40080, 0x4c000000, 0x59a0020f, + 0x59a0bc0f, 0x905cb9c0, 0x805cbd40, 0x41784800, + 0x41785000, 0x41785800, 0x41789000, 0x41789800, + 0x0401fe21, 0x0201f800, 0x00106c55, 0x0201f800, + 0x00100ae0, 0x4178c000, 0x497b4002, 0x0401f95c, + 0x0401f9aa, 0x59a0020c, 0x59a00c0c, 0x80040d40, + 0x04000002, 0x0401f9fb, 0x0401f9fa, 0x0401fe68, + 0x8060c1c0, 0x04020014, 0x0401fa98, 0x0401feb2, + 0x0402000e, 0x0201f800, 0x001018d3, 0x04020008, + 0x4a034406, 0x00000017, 0x0201f800, 0x0010230c, 0x4203e000, 0x50000000, 0x0401f000, 0x42005800, - 0x0000dddd, 0x0401f005, 0x59c00807, 0x82040d00, - 0x0000000c, 0x040007ea, 0x0401fe5c, 0x59a0040c, - 0x800001c0, 0x04000002, 0x0401f856, 0x0401fe6b, - 0x40240000, 0x80280540, 0x802c0540, 0x04020003, - 0x805cb9c0, 0x04020781, 0x0201f800, 0x00106c8a, - 0x0401fda3, 0x4201d000, 0x000186a0, 0x0201f800, - 0x00105e06, 0x5c000800, 0x48078880, 0x5c000800, - 0x48078808, 0x5c000800, 0x480788a3, 0x5c000800, - 0x48075010, 0x5c000800, 0x48079040, 0x0201f800, - 0x001009b6, 0x59a00406, 0x82000500, 0x00000003, - 0x82000580, 0x00000002, 0x0400002c, 0x42000800, - 0x000000c0, 0x0201f800, 0x001019ac, 0x82040500, - 0xfffffffc, 0x42000800, 0x000000c0, 0x0201f800, - 0x001019b1, 0x42000800, 0x00000000, 0x0201f800, - 0x001019ac, 0x82040500, 0xfffffff7, 0x42000800, - 0x00000000, 0x0201f800, 0x001019b1, 0x42000800, - 0x00000000, 0x0201f800, 0x001019ac, 0x82040500, - 0xfffffffb, 0x42000800, 0x00000000, 0x0201f800, - 0x001019b1, 0x4a0388a7, 0x0000f7f7, 0x42006000, - 0xbeffffff, 0x42006800, 0x80018000, 0x0201f800, - 0x001040ad, 0x42006000, 0xfffeffff, 0x41786800, - 0x0201f800, 0x001040ad, 0x402c0000, 0x80280540, - 0x80240540, 0x02000000, 0x00102066, 0x48274406, - 0x482b4207, 0x482f4407, 0x0201f000, 0x001020c2, - 0x59a26000, 0x813261c0, 0x0400000e, 0x59325808, - 0x812e59c0, 0x0400000b, 0x0201f800, 0x000208b4, - 0x0201f800, 0x00100843, 0x59a26001, 0x59325808, - 0x0201f800, 0x000208b4, 0x0201f800, 0x00100843, - 0x1c01f000, 0x42000800, 0x000000ef, 0x0201f800, - 0x00101655, 0x59c400a3, 0x8400055a, 0x8400053a, - 0x480388a3, 0x0201f800, 0x001016ac, 0x0402000a, - 0x42000000, 0x00000001, 0x0201f800, 0x001018fa, - 0x42000000, 0x00000001, 0x0201f800, 0x00101892, - 0x0401f013, 0x0201f800, 0x001016b3, 0x04020008, - 0x41780000, 0x0201f800, 0x001018fa, 0x41780000, - 0x0201f800, 0x00101892, 0x0401f009, 0x42000000, - 0x00000002, 0x0201f800, 0x001018fa, 0x42000000, - 0x00000002, 0x0201f800, 0x00101892, 0x42000800, - 0x00000000, 0x0201f800, 0x001019ac, 0x82040540, - 0x00000004, 0x42000800, 0x00000000, 0x0201f800, - 0x001019b1, 0x4201d000, 0x00000014, 0x0201f800, - 0x00105dd2, 0x59c40008, 0x8400054e, 0x82000500, - 0xffffffe1, 0x48038808, 0x4a0388a7, 0x0000f7f7, - 0x42001000, 0x04000001, 0x0201f800, 0x001019aa, - 0x42006000, 0xbe20bfff, 0x42006800, 0x80018000, - 0x0201f800, 0x001040ad, 0x42006000, 0xfffeffff, - 0x41786800, 0x0201f800, 0x001040ad, 0x4200b000, - 0x00001388, 0x4201d000, 0x00000014, 0x4c580000, - 0x0201f800, 0x00105dd2, 0x0201f800, 0x00101941, - 0x5c00b000, 0x04000004, 0x8058b040, 0x040207f6, - 0x0401f025, 0x59c40005, 0x8c000534, 0x04020007, - 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, - 0x00000008, 0x0402001c, 0x42006000, 0x00020000, - 0x0201f800, 0x001040b2, 0x4201d000, 0x00000064, - 0x0201f800, 0x00105dd2, 0x42006000, 0xfeffffff, - 0x42006800, 0x02000000, 0x0201f800, 0x001040ad, - 0x42006000, 0xfdffffff, 0x41786800, 0x0201f800, - 0x001040ad, 0x4a038805, 0x04000001, 0x59c400a4, - 0x82000500, 0x0000000f, 0x82000580, 0x00000000, - 0x04000003, 0x82000540, 0x00000001, 0x1c01f000, - 0x4803c856, 0x42038000, 0x00007700, 0x0201f800, - 0x00100f0f, 0x59c00006, 0x59a0040c, 0x800001c0, - 0x0400003f, 0x59a03c0c, 0x59a00209, 0x59a01c09, - 0x900c19c0, 0x800c1d40, 0x59a0020e, 0x59a0240e, - 0x901021c0, 0x80102540, 0x59a0020b, 0x82000500, - 0x0000fffc, 0x59a0140b, 0x900811c0, 0x80081540, - 0x480b8003, 0x0201f800, 0x00020892, 0x02000800, - 0x00100615, 0x49334000, 0x0201f800, 0x0010082a, + 0x0000aaaa, 0x0401f058, 0x59c80001, 0x800001c0, + 0x040007ee, 0x59c80801, 0x800409c0, 0x04000006, + 0x0401fa70, 0x40240000, 0x80280540, 0x802c0540, + 0x0402004d, 0x59a00002, 0x82000580, 0xfeedbeef, + 0x04000004, 0x42008800, 0x10000000, 0x0401f003, + 0x42008800, 0x10000004, 0x0401fa19, 0x4a034002, + 0xfeedbeef, 0x0401fa71, 0x0401fa97, 0x0401fea8, + 0x59c40005, 0x8c000534, 0x04000004, 0x42005800, + 0x0000bbbb, 0x0401f038, 0x0401fe83, 0x04020007, + 0x42005800, 0x0000cccc, 0x485f420f, 0x905cb9c0, + 0x485f440f, 0x0401f030, 0x59a0040c, 0x800001c0, + 0x0400000e, 0x59a26000, 0x5930000d, 0x800001c0, + 0x040207be, 0x59a26001, 0x5930080d, 0x800409c0, + 0x040207ba, 0x804891c0, 0x040207b8, 0x804c99c0, + 0x040207b6, 0x0401f87a, 0x805cb840, 0x04000005, + 0x40240000, 0x80280540, 0x802c0540, 0x0402001a, + 0x42000000, 0x00030d40, 0x80000040, 0x04020012, + 0x59c00007, 0x82000500, 0x000501c0, 0x0402000b, + 0x0201f800, 0x001018d3, 0x04020008, 0x4a034406, + 0x00000017, 0x0201f800, 0x0010230c, 0x4203e000, + 0x50000000, 0x0401f000, 0x42005800, 0x0000dddd, + 0x0401f005, 0x59c00807, 0x82040d00, 0x0000000c, + 0x040007ea, 0x0401fe5c, 0x59a0040c, 0x800001c0, + 0x04000002, 0x0401f856, 0x0401fe6b, 0x40240000, + 0x80280540, 0x802c0540, 0x04020003, 0x805cb9c0, + 0x04020781, 0x0201f800, 0x00106f36, 0x0401fda3, + 0x4201d000, 0x000186a0, 0x0201f800, 0x001060c6, + 0x5c000800, 0x48078880, 0x5c000800, 0x48078808, + 0x5c000800, 0x480788a3, 0x5c000800, 0x48075010, + 0x5c000800, 0x48079040, 0x0201f800, 0x00100969, + 0x59a00406, 0x82000500, 0x00000003, 0x82000580, + 0x00000002, 0x0400002c, 0x42000800, 0x000000c0, + 0x0201f800, 0x0010193f, 0x82040500, 0xfffffffc, + 0x42000800, 0x000000c0, 0x0201f800, 0x00101944, + 0x42000800, 0x00000000, 0x0201f800, 0x0010193f, + 0x82040500, 0xfffffff7, 0x42000800, 0x00000000, + 0x0201f800, 0x00101944, 0x42000800, 0x00000000, + 0x0201f800, 0x0010193f, 0x82040500, 0xfffffffb, + 0x42000800, 0x00000000, 0x0201f800, 0x00101944, + 0x4a0388a7, 0x0000f7f7, 0x42006000, 0xbeffffff, + 0x42006800, 0x80018000, 0x0201f800, 0x0010427d, + 0x42006000, 0xfffeffff, 0x41786800, 0x0201f800, + 0x0010427d, 0x402c0000, 0x80280540, 0x80240540, + 0x02000000, 0x001022c0, 0x48274406, 0x482b4207, + 0x482f4407, 0x0201f000, 0x0010231c, 0x59a26000, + 0x813261c0, 0x0400000e, 0x59325808, 0x812e59c0, + 0x0400000b, 0x0201f800, 0x0002077d, 0x0201f800, + 0x001007fd, 0x59a26001, 0x59325808, 0x0201f800, + 0x0002077d, 0x0201f800, 0x001007fd, 0x1c01f000, + 0x42000800, 0x000000ef, 0x0201f800, 0x001015eb, + 0x59c400a3, 0x8400055a, 0x8400053a, 0x480388a3, + 0x0201f800, 0x0010163b, 0x0402000a, 0x42000000, + 0x00000001, 0x0201f800, 0x0010188c, 0x42000000, + 0x00000001, 0x0201f800, 0x00101821, 0x0401f013, + 0x0201f800, 0x00101642, 0x04020008, 0x41780000, + 0x0201f800, 0x0010188c, 0x41780000, 0x0201f800, + 0x00101821, 0x0401f009, 0x42000000, 0x00000002, + 0x0201f800, 0x0010188c, 0x42000000, 0x00000002, + 0x0201f800, 0x00101821, 0x42000800, 0x00000000, + 0x0201f800, 0x0010193f, 0x82040540, 0x00000004, + 0x42000800, 0x00000000, 0x0201f800, 0x00101944, + 0x4201d000, 0x00000014, 0x0201f800, 0x0010608e, + 0x59c40008, 0x8400054e, 0x82000500, 0xffffffe1, + 0x48038808, 0x4a0388a7, 0x0000f7f7, 0x42001000, + 0x04000001, 0x0201f800, 0x0010193d, 0x42006000, + 0xbe20bfff, 0x42006800, 0x80018000, 0x0201f800, + 0x0010427d, 0x42006000, 0xfffeffff, 0x41786800, + 0x0201f800, 0x0010427d, 0x4200b000, 0x00001388, + 0x4201d000, 0x00000014, 0x4c580000, 0x0201f800, + 0x0010608e, 0x0201f800, 0x001018d3, 0x5c00b000, + 0x04000004, 0x8058b040, 0x040207f6, 0x0401f025, + 0x59c40005, 0x8c000534, 0x04020007, 0x59c400a4, + 0x82000500, 0x0000000f, 0x82000580, 0x00000008, + 0x0402001c, 0x42006000, 0x00020000, 0x0201f800, + 0x00104282, 0x4201d000, 0x00000064, 0x0201f800, + 0x0010608e, 0x42006000, 0xfeffffff, 0x42006800, + 0x02000000, 0x0201f800, 0x0010427d, 0x42006000, + 0xfdffffff, 0x41786800, 0x0201f800, 0x0010427d, + 0x4a038805, 0x04000001, 0x59c400a4, 0x82000500, + 0x0000000f, 0x82000580, 0x00000000, 0x04000003, + 0x82000540, 0x00000001, 0x1c01f000, 0x4803c856, + 0x42038000, 0x00007700, 0x0201f800, 0x00100ec1, + 0x59c00006, 0x59a0040c, 0x800001c0, 0x0400003f, + 0x59a03c0c, 0x59a00209, 0x59a01c09, 0x900c19c0, + 0x800c1d40, 0x59a0020e, 0x59a0240e, 0x901021c0, + 0x80102540, 0x59a0020b, 0x82000500, 0x0000fffc, + 0x59a0140b, 0x900811c0, 0x80081540, 0x480b8003, + 0x0201f800, 0x0002075a, 0x02000800, 0x001005d8, + 0x49334000, 0x0201f800, 0x001007e4, 0x4a025a04, + 0x00000018, 0x4a025805, 0x00abcdef, 0x492e6008, + 0x492e600b, 0x481e600d, 0x4a02600c, 0x00000004, + 0x832c0400, 0x00000011, 0x4802600a, 0x42001000, + 0x0000000c, 0x821c0d80, 0x00000001, 0x04000004, + 0x801c3840, 0x0401f963, 0x0401f004, 0x41783800, + 0x0401f960, 0x0401f011, 0x821c0c80, 0x00000005, + 0x04001005, 0x40043800, 0x42001000, 0x0000003c, + 0x0401f006, 0x80001580, 0x82081400, 0x0000000c, + 0x801c3840, 0x040207fd, 0x832c0400, 0x00000005, + 0x0401f950, 0x040207f1, 0x497b9009, 0x59e00003, + 0x82000540, 0x00008060, 0x4803c003, 0x4a038009, + 0x00e00000, 0x1c01f000, 0x4803c856, 0x41780800, + 0x8007a0ca, 0x83d3a400, 0x00007600, 0x42000800, + 0x00000040, 0x0201f800, 0x00101345, 0x4a03a00a, + 0x00000001, 0x4a03a005, 0x20000000, 0x59d00006, + 0x4a03a005, 0x30000000, 0x59d00006, 0x8c00050a, + 0x040207fe, 0x59d00005, 0x59a0020c, 0x800001c0, + 0x0400003f, 0x59a03a0c, 0x59a00210, 0x59a01c10, + 0x900c19c0, 0x800c1d40, 0x59a0020d, 0x59a0240d, + 0x901021c0, 0x80102540, 0x59a0120b, 0x82081500, + 0x0000fffc, 0x59a0040b, 0x900001c0, 0x80081540, + 0x480ba003, 0x0201f800, 0x0002075a, 0x02000800, + 0x001005d8, 0x49334001, 0x0201f800, 0x001007e4, 0x4a025a04, 0x00000018, 0x4a025805, 0x00abcdef, 0x492e6008, 0x492e600b, 0x481e600d, 0x4a02600c, 0x00000004, 0x832c0400, 0x00000011, 0x4802600a, 0x42001000, 0x0000000c, 0x821c0d80, 0x00000001, - 0x04000004, 0x801c3840, 0x0401f963, 0x0401f004, - 0x41783800, 0x0401f960, 0x0401f011, 0x821c0c80, + 0x04000004, 0x801c3840, 0x0401f906, 0x0401f004, + 0x41783800, 0x0401f903, 0x0401f011, 0x821c0c80, 0x00000005, 0x04001005, 0x40043800, 0x42001000, 0x0000003c, 0x0401f006, 0x80001580, 0x82081400, 0x0000000c, 0x801c3840, 0x040207fd, 0x832c0400, - 0x00000005, 0x0401f950, 0x040207f1, 0x497b9009, - 0x59e00003, 0x82000540, 0x00008060, 0x4803c003, - 0x4a038009, 0x00e00000, 0x1c01f000, 0x4803c856, - 0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600, - 0x42000800, 0x00000040, 0x0201f800, 0x00101395, - 0x4a03a00a, 0x00000001, 0x4a03a005, 0x20000000, - 0x59d00006, 0x4a03a005, 0x30000000, 0x59d00006, - 0x8c00050a, 0x040207fe, 0x59d00005, 0x59a0020c, - 0x800001c0, 0x0400003f, 0x59a03a0c, 0x59a00210, - 0x59a01c10, 0x900c19c0, 0x800c1d40, 0x59a0020d, - 0x59a0240d, 0x901021c0, 0x80102540, 0x59a0120b, - 0x82081500, 0x0000fffc, 0x59a0040b, 0x900001c0, - 0x80081540, 0x480ba003, 0x0201f800, 0x00020892, - 0x02000800, 0x00100615, 0x49334001, 0x0201f800, - 0x0010082a, 0x4a025a04, 0x00000018, 0x4a025805, - 0x00abcdef, 0x492e6008, 0x492e600b, 0x481e600d, - 0x4a02600c, 0x00000004, 0x832c0400, 0x00000011, - 0x4802600a, 0x42001000, 0x0000000c, 0x821c0d80, - 0x00000001, 0x04000004, 0x801c3840, 0x0401f906, - 0x0401f004, 0x41783800, 0x0401f903, 0x0401f011, - 0x821c0c80, 0x00000005, 0x04001005, 0x40043800, - 0x42001000, 0x0000003c, 0x0401f006, 0x80001580, - 0x82081400, 0x0000000c, 0x801c3840, 0x040207fd, - 0x832c0400, 0x00000005, 0x0401f8f3, 0x040207f1, - 0x1c01f000, 0x4803c856, 0x59a0020c, 0x800001c0, - 0x04000024, 0x824c0580, 0x00000002, 0x04000040, - 0x59a26001, 0x5930380d, 0x801c39c0, 0x0400003c, - 0x801c3840, 0x481e600d, 0x5932580b, 0x5930080a, - 0x50042000, 0x58041801, 0x58041002, 0x82081500, - 0xfffffffc, 0x5930000c, 0x80000000, 0x82000d80, - 0x00000005, 0x04020009, 0x497a600c, 0x592e5801, - 0x812e59c0, 0x0400001a, 0x492e600b, 0x832c0c00, - 0x00000005, 0x0401f005, 0x4802600c, 0x5930080a, - 0x82040c00, 0x00000003, 0x4806600a, 0x0401f010, - 0x59a0120b, 0x82081500, 0x0000fffc, 0x59a0040b, - 0x900001c0, 0x80081540, 0x480ba003, 0x59a0020d, - 0x59a0240d, 0x901021c0, 0x80102540, 0x59a00210, - 0x59a01c10, 0x900c19c0, 0x800c1d40, 0x4201d000, - 0x00003a98, 0x0201f800, 0x00105e06, 0x480ba002, - 0x59a80059, 0x4803a008, 0x4813a000, 0x480fa001, - 0x4a03a005, 0x10000000, 0x02005800, 0x00100615, - 0x804c9800, 0x82000540, 0x00000001, 0x1c01f000, - 0x4847c857, 0x59a0040c, 0x800001c0, 0x04000024, - 0x82480580, 0x00000002, 0x04000042, 0x59a26000, - 0x5930380d, 0x801c39c0, 0x0400003e, 0x801c3840, + 0x00000005, 0x0401f8f3, 0x040207f1, 0x1c01f000, + 0x4803c856, 0x59a0020c, 0x800001c0, 0x04000024, + 0x824c0580, 0x00000002, 0x04000040, 0x59a26001, + 0x5930380d, 0x801c39c0, 0x0400003c, 0x801c3840, 0x481e600d, 0x5932580b, 0x5930080a, 0x50042000, 0x58041801, 0x58041002, 0x82081500, 0xfffffffc, 0x5930000c, 0x80000000, 0x82000d80, 0x00000005, 0x04020009, 0x497a600c, 0x592e5801, 0x812e59c0, - 0x0400001d, 0x492e600b, 0x832c0c00, 0x00000005, + 0x0400001a, 0x492e600b, 0x832c0c00, 0x00000005, 0x0401f005, 0x4802600c, 0x5930080a, 0x82040c00, - 0x00000003, 0x4806600a, 0x0401f013, 0x82440580, - 0x10000000, 0x0402001f, 0x59a0020e, 0x59a0240e, - 0x901021c0, 0x80102540, 0x59a00209, 0x59a01c09, - 0x900c19c0, 0x800c1d40, 0x59a0020b, 0x82000500, - 0x0000fffc, 0x59a0140b, 0x900811c0, 0x80081540, - 0x480b8003, 0x48138000, 0x480f8001, 0x480b8002, - 0x59c80018, 0x82000500, 0xf0000000, 0x59c02008, - 0x82102500, 0x0fffffff, 0x80100540, 0x48038008, - 0x48478006, 0x80489000, 0x8260c540, 0x00000001, - 0x1c01f000, 0x59c00009, 0x4803c857, 0x82000d00, - 0x00e00000, 0x0400000d, 0x485f420f, 0x905cb9c0, - 0x485f440f, 0x8c00052e, 0x04000002, 0x80285000, - 0x8c00052c, 0x04000002, 0x80244800, 0x8c00052a, - 0x04000002, 0x802c5800, 0x1c01f000, 0x59a0020c, - 0x800001c0, 0x04000024, 0x59d00806, 0x4807c857, - 0x8c040d3e, 0x04000020, 0x4a03a005, 0x20000000, - 0x4a03a005, 0x30000000, 0x59d00806, 0x8c040d0a, - 0x040207fe, 0x824c0480, 0x00000003, 0x02021800, - 0x00100615, 0x404c0000, 0x0c01f001, 0x00102c02, - 0x00102c04, 0x00102c0a, 0x0201f800, 0x00100615, - 0x80000040, 0x40009800, 0x0401ff43, 0x0400000a, - 0x0401ff41, 0x0401f008, 0x80000040, 0x40009800, - 0x59d00806, 0x4807c857, 0x8c040d3e, 0x040207e3, - 0x0401ff39, 0x1c01f000, 0x59a0040c, 0x800001c0, - 0x04000024, 0x59c00807, 0x4807c857, 0x8c040d3e, - 0x04000020, 0x59c00807, 0x4a038006, 0x20000000, - 0x82480480, 0x00000003, 0x02021800, 0x00100615, - 0x40480000, 0x0c01f001, 0x00102c25, 0x00102c27, - 0x00102c2f, 0x0201f800, 0x00100615, 0x80000040, - 0x40009000, 0x42008800, 0x10000004, 0x0401ff65, - 0x0400000c, 0x0401ff63, 0x0401f00a, 0x80000040, - 0x40009000, 0x59c00807, 0x4807c857, 0x8c040d3e, - 0x040207e5, 0x42008800, 0x10000004, 0x0401ff59, - 0x1c01f000, 0x492fc857, 0x4000a800, 0x4a03b805, - 0x20000000, 0x59dc0006, 0x4a03b805, 0x30000000, - 0x4813b800, 0x480fb801, 0x480bb802, 0x4857b803, - 0x4a03b805, 0x30000002, 0x59dc0006, 0x4a03b805, - 0x70000001, 0x59dc0006, 0x4a03b805, 0x10000000, - 0x59dc0006, 0x8c00053e, 0x040007fe, 0x4a03b805, - 0x20000000, 0x59dc0006, 0x59dc2000, 0x59dc1801, - 0x801c39c0, 0x0400000a, 0x4d2c0000, 0x0201f800, - 0x0010082a, 0x5c000800, 0x02000800, 0x00100615, - 0x4a025a04, 0x0000000a, 0x492c0801, 0x1c01f000, - 0x42006000, 0x00102d9d, 0x42000800, 0x0000007c, - 0x0201f800, 0x00101395, 0x4a03902c, 0x00200000, - 0x4200b000, 0x000001f4, 0x59c8002c, 0x8c00052c, + 0x00000003, 0x4806600a, 0x0401f010, 0x59a0120b, + 0x82081500, 0x0000fffc, 0x59a0040b, 0x900001c0, + 0x80081540, 0x480ba003, 0x59a0020d, 0x59a0240d, + 0x901021c0, 0x80102540, 0x59a00210, 0x59a01c10, + 0x900c19c0, 0x800c1d40, 0x4201d000, 0x00003a98, + 0x0201f800, 0x001060c6, 0x480ba002, 0x59a80059, + 0x4803a008, 0x4813a000, 0x480fa001, 0x4a03a005, + 0x10000000, 0x02005800, 0x001005d8, 0x804c9800, + 0x82000540, 0x00000001, 0x1c01f000, 0x4847c857, + 0x59a0040c, 0x800001c0, 0x04000024, 0x82480580, + 0x00000002, 0x04000042, 0x59a26000, 0x5930380d, + 0x801c39c0, 0x0400003e, 0x801c3840, 0x481e600d, + 0x5932580b, 0x5930080a, 0x50042000, 0x58041801, + 0x58041002, 0x82081500, 0xfffffffc, 0x5930000c, + 0x80000000, 0x82000d80, 0x00000005, 0x04020009, + 0x497a600c, 0x592e5801, 0x812e59c0, 0x0400001d, + 0x492e600b, 0x832c0c00, 0x00000005, 0x0401f005, + 0x4802600c, 0x5930080a, 0x82040c00, 0x00000003, + 0x4806600a, 0x0401f013, 0x82440580, 0x10000000, + 0x0402001f, 0x59a0020e, 0x59a0240e, 0x901021c0, + 0x80102540, 0x59a00209, 0x59a01c09, 0x900c19c0, + 0x800c1d40, 0x59a0020b, 0x82000500, 0x0000fffc, + 0x59a0140b, 0x900811c0, 0x80081540, 0x480b8003, + 0x48138000, 0x480f8001, 0x480b8002, 0x59c80018, + 0x82000500, 0xf0000000, 0x59c02008, 0x82102500, + 0x0fffffff, 0x80100540, 0x48038008, 0x48478006, + 0x80489000, 0x8260c540, 0x00000001, 0x1c01f000, + 0x59c00009, 0x4803c857, 0x82000d00, 0x00e00000, + 0x0400000d, 0x485f420f, 0x905cb9c0, 0x485f440f, + 0x8c00052e, 0x04000002, 0x80285000, 0x8c00052c, + 0x04000002, 0x80244800, 0x8c00052a, 0x04000002, + 0x802c5800, 0x1c01f000, 0x59a0020c, 0x800001c0, + 0x04000024, 0x59d00806, 0x4807c857, 0x8c040d3e, + 0x04000020, 0x4a03a005, 0x20000000, 0x4a03a005, + 0x30000000, 0x59d00806, 0x8c040d0a, 0x040207fe, + 0x824c0480, 0x00000003, 0x02021800, 0x001005d8, + 0x404c0000, 0x0c01f001, 0x00102da1, 0x00102da3, + 0x00102da9, 0x0201f800, 0x001005d8, 0x80000040, + 0x40009800, 0x0401ff43, 0x0400000a, 0x0401ff41, + 0x0401f008, 0x80000040, 0x40009800, 0x59d00806, + 0x4807c857, 0x8c040d3e, 0x040207e3, 0x0401ff39, + 0x1c01f000, 0x59a0040c, 0x800001c0, 0x04000024, + 0x59c00807, 0x4807c857, 0x8c040d3e, 0x04000020, + 0x59c00807, 0x4a038006, 0x20000000, 0x82480480, + 0x00000003, 0x02021800, 0x001005d8, 0x40480000, + 0x0c01f001, 0x00102dc4, 0x00102dc6, 0x00102dce, + 0x0201f800, 0x001005d8, 0x80000040, 0x40009000, + 0x42008800, 0x10000004, 0x0401ff65, 0x0400000c, + 0x0401ff63, 0x0401f00a, 0x80000040, 0x40009000, + 0x59c00807, 0x4807c857, 0x8c040d3e, 0x040207e5, + 0x42008800, 0x10000004, 0x0401ff59, 0x1c01f000, + 0x492fc857, 0x4000a800, 0x4a03b805, 0x20000000, + 0x59dc0006, 0x4a03b805, 0x30000000, 0x4813b800, + 0x480fb801, 0x480bb802, 0x4857b803, 0x4a03b805, + 0x30000002, 0x59dc0006, 0x4a03b805, 0x70000001, + 0x59dc0006, 0x4a03b805, 0x10000000, 0x59dc0006, + 0x8c00053e, 0x040007fe, 0x4a03b805, 0x20000000, + 0x59dc0006, 0x59dc2000, 0x59dc1801, 0x801c39c0, + 0x0400000a, 0x4d2c0000, 0x0201f800, 0x001007e4, + 0x5c000800, 0x02000800, 0x001005d8, 0x4a025a04, + 0x0000000a, 0x492c0801, 0x1c01f000, 0x42006000, + 0x00102fb2, 0x0201f800, 0x00101345, 0x4a03902c, + 0x00200000, 0x4200b000, 0x000001f4, 0x59c8002c, + 0x8c00052c, 0x04000007, 0x8058b040, 0x040207fc, + 0x42000000, 0x00004003, 0x41781000, 0x0401f196, + 0x50301000, 0x41784800, 0x4a03902d, 0x00008000, + 0x4200b000, 0x000001f4, 0x59c8002c, 0x8c000534, 0x04000007, 0x8058b040, 0x040207fc, 0x42000000, - 0x00004003, 0x41781000, 0x0401f11e, 0x50301000, - 0x41784800, 0x4a03902d, 0x00008000, 0x4200b000, - 0x000001f4, 0x59c8002c, 0x8c000534, 0x04000007, + 0x00004003, 0x41781000, 0x0401f187, 0x0401f8f8, + 0x80244800, 0x40240000, 0x82000580, 0x000003b1, + 0x040207fb, 0x0401f988, 0x41784800, 0x0401f920, + 0x80244800, 0x40240000, 0x82000580, 0x000003b1, + 0x040207fb, 0x80306000, 0x82300580, 0x00102fb4, + 0x040207e0, 0x59a80863, 0x800409c0, 0x04000007, + 0x42000000, 0x00004004, 0x42001000, 0x00000002, + 0x59a81862, 0x0401f16c, 0x42006000, 0x00102fb2, + 0x4a035064, 0x00000004, 0x50301000, 0x41784800, + 0x4a03902d, 0x00004000, 0x4200b000, 0x000001f4, + 0x59c8002c, 0x8c000532, 0x04000007, 0x8058b040, + 0x040207fc, 0x42000000, 0x00004003, 0x41781000, + 0x0401f159, 0x0401f8ca, 0x80244800, 0x40240000, + 0x82000580, 0x00000154, 0x040207fb, 0x0401f95a, + 0x41784800, 0x0401f8f2, 0x80244800, 0x40240000, + 0x82000580, 0x00000154, 0x040207fb, 0x80306000, + 0x82300580, 0x00102fb4, 0x040207e0, 0x59a80863, + 0x800409c0, 0x04000007, 0x42000000, 0x00004004, + 0x42001000, 0x00000004, 0x59a81862, 0x0401f13e, + 0x42006000, 0x00102fb2, 0x497b5064, 0x50301000, + 0x41784800, 0x4a03902d, 0x00001000, 0x4200b000, + 0x000001f4, 0x59c8002c, 0x8c00052e, 0x04000007, 0x8058b040, 0x040207fc, 0x42000000, 0x00004003, - 0x41781000, 0x0401f10f, 0x0401f895, 0x80244800, - 0x82240580, 0x000003b1, 0x040207fc, 0x0401f911, - 0x41784800, 0x0401f8bb, 0x80244800, 0x82240580, - 0x000003b1, 0x040207fc, 0x80306000, 0x82300580, - 0x00102d9f, 0x040207e2, 0x59a80863, 0x800409c0, - 0x04000007, 0x42000000, 0x00004004, 0x42001000, - 0x00000002, 0x59a81862, 0x0401f0f6, 0x42006000, - 0x00102d9d, 0x50301000, 0x41784800, 0x4a03902d, - 0x00000800, 0x0401f876, 0x80244800, 0x82240580, - 0x00000018, 0x040207fc, 0x0401f8f2, 0x41784800, - 0x0401f89c, 0x80244800, 0x82240580, 0x00000018, - 0x040207fc, 0x80306000, 0x82300580, 0x00102d9f, - 0x040207ed, 0x59a80863, 0x800409c0, 0x04000007, + 0x41781000, 0x0401f12c, 0x0401f89d, 0x80244800, + 0x40240000, 0x82000580, 0x00000088, 0x040207fb, + 0x0401f92d, 0x41784800, 0x0401f8c5, 0x80244800, + 0x40240000, 0x82000580, 0x00000088, 0x040207fb, + 0x80306000, 0x82300580, 0x00102fb4, 0x040207e0, + 0x59a80863, 0x800409c0, 0x04000007, 0x42000000, + 0x00004004, 0x42001000, 0x00000001, 0x59a81862, + 0x0401f111, 0x42006000, 0x00102fb2, 0x50301000, + 0x41784800, 0x4a03902d, 0x00000800, 0x0401f87c, + 0x80244800, 0x40240000, 0x82000580, 0x00000018, + 0x040207fb, 0x0401f90c, 0x41784800, 0x0401f8a4, + 0x80244800, 0x40240000, 0x82000580, 0x00000018, + 0x040207fb, 0x80306000, 0x82300580, 0x00102fb4, + 0x040207eb, 0x59a80863, 0x800409c0, 0x04000007, 0x42000000, 0x00004004, 0x42001000, 0x00000010, - 0x59a81862, 0x0401f0d7, 0x42006000, 0x00102d9d, + 0x59a81862, 0x0401f0f0, 0x42006000, 0x00102fb2, 0x50301000, 0x41784800, 0x4a03902d, 0x00000400, - 0x0401f857, 0x80244800, 0x82240580, 0x00000088, - 0x040207fc, 0x0401f8d3, 0x41784800, 0x0401f87d, - 0x80244800, 0x82240580, 0x00000088, 0x040207fc, - 0x80306000, 0x82300580, 0x00102d9f, 0x040207ed, - 0x59a80863, 0x800409c0, 0x04000007, 0x42000000, - 0x00004004, 0x42001000, 0x00000008, 0x59a81862, - 0x0401f0b8, 0x42006000, 0x00102d9d, 0x50301000, - 0x41784800, 0x4a03902d, 0x00002000, 0x4200b000, - 0x000001f4, 0x59c8002c, 0x8c000530, 0x04000007, - 0x8058b040, 0x040207fc, 0x42000000, 0x00004003, - 0x41781000, 0x0401f0a7, 0x59c8002c, 0x82000500, - 0xffe0ffff, 0x82080d00, 0x001f0000, 0x80040540, - 0x4803902c, 0x0401f826, 0x80244800, 0x82240580, - 0x00000110, 0x040207fc, 0x0401f8a2, 0x41784800, - 0x0401f84c, 0x59c80034, 0x82080d00, 0x001f0000, - 0x82000500, 0x001f0000, 0x80040580, 0x04000006, - 0x59a80063, 0x80000000, 0x48035063, 0x40240000, - 0x48035062, 0x80244800, 0x82240580, 0x00000110, - 0x040207f0, 0x80306000, 0x82300580, 0x00102d9f, - 0x040207cf, 0x59a80863, 0x800409c0, 0x04000006, + 0x0401f85b, 0x80244800, 0x40240000, 0x82000580, + 0x00000088, 0x040207fb, 0x0401f8eb, 0x41784800, + 0x0401f883, 0x80244800, 0x40240000, 0x82000580, + 0x00000088, 0x040207fb, 0x80306000, 0x82300580, + 0x00102fb4, 0x040207eb, 0x59a80863, 0x800409c0, + 0x04000007, 0x42000000, 0x00004004, 0x42001000, + 0x00000008, 0x59a81862, 0x0401f0cf, 0x42006000, + 0x00102fb2, 0x50301000, 0x41784800, 0x4a03902d, + 0x00002000, 0x4200b000, 0x000001f4, 0x59c8002c, + 0x8c000530, 0x04000007, 0x8058b040, 0x040207fc, + 0x42000000, 0x00004003, 0x41781000, 0x0401f0be, + 0x59c8002c, 0x82000500, 0xffe0ffff, 0x82080d00, + 0x001f0000, 0x80040540, 0x4803902c, 0x0401f828, + 0x80244800, 0x40240000, 0x82000580, 0x00000110, + 0x040207fb, 0x0401f8b8, 0x41784800, 0x0401f850, + 0x59c80034, 0x82080d00, 0x001f0000, 0x82000500, + 0x001f0000, 0x80040580, 0x04000006, 0x59a80063, + 0x80000000, 0x48035063, 0x40240000, 0x48035062, + 0x80244800, 0x40240000, 0x82000580, 0x00000110, + 0x040207ef, 0x80306000, 0x82300580, 0x00102fb4, + 0x040207cd, 0x59a80863, 0x800409c0, 0x04000006, 0x42000000, 0x00004004, 0x42001000, 0x00000020, - 0x59a81862, 0x0201f000, 0x00102066, 0x59c8002c, + 0x59a81862, 0x0201f000, 0x001022c0, 0x59c8002c, 0x82000500, 0xffff0000, 0x82080d00, 0x0000ffff, - 0x80040540, 0x4803902c, 0x480b9028, 0x480b9029, - 0x59a80064, 0x82000580, 0x00000004, 0x04000003, - 0x480b902a, 0x480b902b, 0x59c8002d, 0x82000500, - 0xfffffc00, 0x80240540, 0x4803902d, 0x4200b000, - 0x000001f4, 0x59c8002c, 0x82000500, 0x18000000, - 0x04000007, 0x8058b040, 0x040207fb, 0x42000000, - 0x00004003, 0x41781000, 0x0401f05a, 0x4a03902e, - 0x00000001, 0x4200b000, 0x000001f4, 0x59c8002e, - 0x8c000500, 0x04000006, 0x8058b040, 0x040207fc, - 0x42000000, 0x00004003, 0x0401f04e, 0x1c01f000, - 0x41783800, 0x59c8002d, 0x82000500, 0xfffffc00, - 0x80240d40, 0x4807902d, 0x4200b000, 0x000001f4, + 0x80040540, 0x4803902c, 0x40080000, 0x48039028, + 0x48039029, 0x59a80064, 0x82000580, 0x00000004, + 0x04000004, 0x40080000, 0x4803902a, 0x4803902b, + 0x59c8082d, 0x82040d00, 0xfffffc00, 0x40240000, + 0x80040d40, 0x4807902d, 0x4200b000, 0x000001f4, 0x59c8002c, 0x82000500, 0x18000000, 0x04000007, 0x8058b040, 0x040207fb, 0x42000000, 0x00004003, - 0x41781000, 0x0401f03b, 0x59c81830, 0x59c80030, - 0x800c0d80, 0x040207fd, 0x80080d80, 0x04000002, - 0x801c3800, 0x59c82031, 0x59c80031, 0x80100d80, - 0x040207fd, 0x80080d80, 0x04000002, 0x801c3800, - 0x59a80064, 0x82000580, 0x00000004, 0x04000019, - 0x59c82832, 0x59c80032, 0x80140d80, 0x040207fd, - 0x80080d80, 0x04000002, 0x801c3800, 0x59c83033, - 0x59c80033, 0x80180d80, 0x040207fd, 0x80080d80, - 0x04000002, 0x801c3800, 0x59c80034, 0x59c80834, - 0x80040d80, 0x040207fd, 0x80080d80, 0x82040d00, - 0x0000ffff, 0x0400000c, 0x801c3800, 0x0401f00a, - 0x59c80034, 0x59c80834, 0x80040d80, 0x040207fd, - 0x80080d80, 0x82040d00, 0x000000ff, 0x04000002, - 0x801c3800, 0x801c39c0, 0x04000005, 0x59a80063, - 0x801c0400, 0x48035063, 0x48275062, 0x1c01f000, - 0x48034206, 0x48074406, 0x480b4207, 0x480f4407, - 0x48134208, 0x48174408, 0x0201f000, 0x00102069, - 0x42000000, 0x00600000, 0x80000040, 0x040207ff, - 0x1c01f000, 0x5a5a5a5a, 0xa5a5a5a5, 0x59a00c0a, - 0x800409c0, 0x02000000, 0x001020b6, 0x82040480, - 0x00000021, 0x02021000, 0x001020b6, 0x82040480, - 0x00000011, 0x04001003, 0x42000800, 0x00000010, - 0x59a00208, 0x59a01407, 0x900811c0, 0x80081540, - 0x59a00207, 0x59a01c06, 0x900c19c0, 0x800c1d40, - 0x0201f800, 0x0010381a, 0x04000006, 0x0201f800, - 0x0010383e, 0x4a01d809, 0x00102dc0, 0x1c01f000, - 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, - 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, - 0x00000200, 0x02000000, 0x001020aa, 0x59a00c0a, + 0x41781000, 0x0401f06c, 0x4a03902e, 0x00000001, + 0x4200b000, 0x000001f4, 0x59c8002e, 0x8c000500, + 0x04000006, 0x8058b040, 0x040207fc, 0x42000000, + 0x00004003, 0x0401f060, 0x1c01f000, 0x41783800, + 0x59c8082d, 0x82040d00, 0xfffffc00, 0x40240000, + 0x80040d40, 0x4807902d, 0x4200b000, 0x000001f4, + 0x59c8002c, 0x82000500, 0x18000000, 0x04000007, + 0x8058b040, 0x040207fb, 0x42000000, 0x00004003, + 0x41781000, 0x0401f04c, 0x59c80030, 0x59c80830, + 0x80040580, 0x040207fd, 0x40041800, 0x59c80031, + 0x59c80831, 0x80040580, 0x040207fd, 0x40042000, + 0x59c80032, 0x59c80832, 0x80040580, 0x040207fd, + 0x40042800, 0x59c80033, 0x59c80833, 0x80040580, + 0x040207fd, 0x40043000, 0x400c0000, 0x80080580, + 0x04000002, 0x801c3800, 0x40100000, 0x80080580, + 0x04000002, 0x801c3800, 0x59a80064, 0x82000580, + 0x00000004, 0x04000009, 0x40140000, 0x80080580, + 0x04000002, 0x801c3800, 0x40180000, 0x80080580, + 0x04000002, 0x801c3800, 0x59a80064, 0x82000580, + 0x00000004, 0x0400000d, 0x59c80034, 0x59c80834, + 0x80040580, 0x040207fd, 0x82040500, 0x0000ffff, + 0x82080d00, 0x0000ffff, 0x80040580, 0x0400000e, + 0x801c3800, 0x0401f00c, 0x59c80034, 0x59c80834, + 0x80040580, 0x040207fd, 0x82040500, 0x000000ff, + 0x82080d00, 0x000000ff, 0x80040580, 0x04000002, + 0x801c3800, 0x801c39c0, 0x04000006, 0x59a80063, + 0x801c0400, 0x48035063, 0x40240000, 0x48035062, + 0x1c01f000, 0x48034206, 0x48074406, 0x480b4207, + 0x480f4407, 0x48134208, 0x48174408, 0x0201f000, + 0x001022c3, 0x42000000, 0x00600000, 0x80000040, + 0x040207ff, 0x1c01f000, 0x5a5a5a5a, 0xa5a5a5a5, + 0x59a00c0a, 0x800409c0, 0x02000000, 0x00102310, + 0x82040480, 0x00000021, 0x02021000, 0x00102310, 0x82040480, 0x00000011, 0x04001003, 0x42000800, - 0x00000010, 0x59a0040b, 0x59a0120b, 0x900811c0, - 0x80081540, 0x59a00209, 0x59a01c08, 0x900c19c0, - 0x800c1d40, 0x58ec0003, 0x0201f800, 0x00103841, - 0x4a01d809, 0x00102ddb, 0x1c01f000, 0x4031d800, - 0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200, - 0x02000000, 0x001020aa, 0x59a00c0a, 0x82040480, - 0x00000011, 0x02001000, 0x00102066, 0x82040c80, 0x00000010, 0x59a00208, 0x59a01407, 0x900811c0, 0x80081540, 0x59a00207, 0x59a01c06, 0x900c19c0, - 0x800c1d40, 0x82081400, 0x00000040, 0x58ec0003, - 0x0201f800, 0x0010383e, 0x4a01d809, 0x00102df9, - 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002, - 0x82000580, 0x00000200, 0x02000000, 0x001020aa, - 0x59a0040a, 0x82000c80, 0x00000010, 0x59a0040b, - 0x59a0120b, 0x900811c0, 0x80081540, 0x59a00209, - 0x59a01c08, 0x900c19c0, 0x800c1d40, 0x82081400, - 0x00000040, 0x58ec0003, 0x0201f800, 0x00103841, - 0x4a01d809, 0x0010205f, 0x1c01f000, 0x48efc857, - 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, - 0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40, - 0x59a00406, 0x48034000, 0x480b4001, 0x480f4002, - 0x0201f800, 0x0010381a, 0x04020005, 0x4a034406, - 0x00000002, 0x0201f000, 0x001020b2, 0x42000800, - 0x00000010, 0x0201f800, 0x0010383e, 0x4a01d809, - 0x00102e2e, 0x1c01f000, 0x4031d800, 0x58ef400b, - 0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200, - 0x02000000, 0x001020aa, 0x48efc857, 0x49a3c857, - 0x492fc857, 0x592c0a04, 0x80040910, 0x04020005, - 0x4a034406, 0x00000019, 0x0201f000, 0x001020b2, - 0x4805d80c, 0x0401f00a, 0x4031d800, 0x58ef400b, + 0x800c1d40, 0x0201f800, 0x00103a00, 0x04000006, + 0x0201f800, 0x00103a25, 0x4a01d809, 0x00102fd5, + 0x1c01f000, 0x4a034406, 0x00000002, 0x0201f000, + 0x0010230c, 0x4031d800, 0x58ef400b, 0x58ec0002, + 0x82000580, 0x00000200, 0x02000000, 0x00102304, + 0x59a00c0a, 0x82040480, 0x00000011, 0x04001003, + 0x42000800, 0x00000010, 0x59a0040b, 0x59a0120b, + 0x900811c0, 0x80081540, 0x59a00209, 0x59a01c08, + 0x900c19c0, 0x800c1d40, 0x58ec0003, 0x0201f800, + 0x00103a28, 0x4a01d809, 0x00102ff0, 0x1c01f000, + 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x00102304, 0x59a00c0a, + 0x82040480, 0x00000011, 0x02001000, 0x001022c0, + 0x82040c80, 0x00000010, 0x59a00208, 0x59a01407, + 0x900811c0, 0x80081540, 0x59a00207, 0x59a01c06, + 0x900c19c0, 0x800c1d40, 0x82081400, 0x00000040, + 0x58ec0003, 0x0201f800, 0x00103a25, 0x4a01d809, + 0x0010300e, 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, - 0x001020aa, 0x48efc857, 0x49a3c857, 0x48efc857, - 0x49a3c857, 0x58ec000c, 0x80000040, 0x04000012, - 0x4801d80c, 0x0201f800, 0x0010381a, 0x04020005, - 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, - 0x42000800, 0x00000010, 0x58ec1007, 0x58ec1808, - 0x0201f800, 0x0010383e, 0x4a01d809, 0x00102e42, + 0x00102304, 0x59a0040a, 0x82000c80, 0x00000010, + 0x59a0040b, 0x59a0120b, 0x900811c0, 0x80081540, + 0x59a00209, 0x59a01c08, 0x900c19c0, 0x800c1d40, + 0x82081400, 0x00000040, 0x58ec0003, 0x0201f800, + 0x00103a28, 0x4a01d809, 0x001022b9, 0x1c01f000, + 0x48efc857, 0x59a00207, 0x59a01407, 0x900001c0, + 0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0, + 0x800c1d40, 0x59a00406, 0x48034000, 0x480b4001, + 0x480f4002, 0x0201f800, 0x00103a00, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x0010230c, + 0x42000800, 0x00000010, 0x0201f800, 0x00103a25, + 0x4a01d809, 0x00103043, 0x1c01f000, 0x4031d800, + 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x00102304, 0x48efc857, + 0x49a3c857, 0x492fc857, 0x592c0a04, 0x80040910, + 0x04020005, 0x4a034406, 0x00000019, 0x0201f000, + 0x0010230c, 0x4805d80c, 0x0401f00a, 0x4031d800, + 0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200, + 0x02000000, 0x00102304, 0x48efc857, 0x49a3c857, + 0x48efc857, 0x49a3c857, 0x58ec000c, 0x80000040, + 0x04000012, 0x4801d80c, 0x0201f800, 0x00103a00, + 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, + 0x0010230c, 0x42000800, 0x00000010, 0x58ec1007, + 0x58ec1808, 0x0201f800, 0x00103a25, 0x4a01d809, + 0x00103057, 0x1c01f000, 0x58ee580d, 0x48efc857, + 0x49a3c857, 0x492fc857, 0x492f3006, 0x592c0404, + 0x8400055e, 0x48025c04, 0x4a01d809, 0x00103081, 0x1c01f000, 0x58ee580d, 0x48efc857, 0x49a3c857, - 0x492fc857, 0x492f3006, 0x592c0404, 0x8400055e, - 0x48025c04, 0x4a01d809, 0x00102e6c, 0x1c01f000, - 0x4d2c0000, 0x58ee580d, 0x48efc857, 0x49a3c857, 0x492fc857, 0x592c0404, 0x8400051e, 0x48025c04, 0x59a00000, 0x59a01001, 0x59a01802, 0x80081400, 0x820c1c40, 0x00000000, 0x832c0400, 0x00000004, - 0x42000800, 0x00000010, 0x5c025800, 0x0201f000, - 0x00103841, 0x800409c0, 0x04000005, 0x4a034406, - 0x00000001, 0x0201f000, 0x001020b2, 0x836c0580, - 0x00000003, 0x04000005, 0x4a034406, 0x00000007, - 0x0201f000, 0x001020b2, 0x59a0320b, 0x82183500, - 0x000000ff, 0x59a28c06, 0x0201f800, 0x00020267, - 0x02020000, 0x001020b6, 0x83440580, 0x000007fd, - 0x04000008, 0x0201f800, 0x00104836, 0x04000005, - 0x4a034406, 0x00000009, 0x0201f000, 0x001020b2, - 0x0201f800, 0x0010381a, 0x04020005, 0x4a034406, - 0x00000002, 0x0201f000, 0x001020b2, 0x801831c0, - 0x0400000a, 0x412c0800, 0x0201f800, 0x0010381a, - 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, - 0x001020b2, 0x40065800, 0x4a025c04, 0x00008000, - 0x497a5a04, 0x0201f800, 0x00108ebd, 0x04020005, - 0x4a034406, 0x00000003, 0x0201f000, 0x001020b2, - 0x4a01d809, 0x00102ebf, 0x1c01f000, 0x592c0005, - 0x82000580, 0x01000000, 0x04020005, 0x4a034406, - 0x00000004, 0x0201f000, 0x001020b2, 0x592c0406, - 0x82002d00, 0x0000ff00, 0x82000500, 0x000000ff, - 0x80000904, 0x80040800, 0x82040480, 0x00000006, - 0x04001003, 0x42000800, 0x00000005, 0x4c500000, - 0x4c540000, 0x4c580000, 0x832ca400, 0x00000006, - 0x4050a800, 0x4004b000, 0x0201f800, 0x0010a94f, + 0x42000800, 0x00000010, 0x0201f000, 0x00103a28, + 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, + 0x0201f000, 0x0010230c, 0x836c0580, 0x00000003, + 0x04000005, 0x4a034406, 0x00000007, 0x0201f000, + 0x0010230c, 0x59a0320b, 0x82183500, 0x000000ff, + 0x59a28c06, 0x0201f800, 0x00020245, 0x02020000, + 0x00102310, 0x83440580, 0x000007fd, 0x04000008, + 0x0201f800, 0x001049e7, 0x04000005, 0x4a034406, + 0x00000009, 0x0201f000, 0x0010230c, 0x0201f800, + 0x00103a00, 0x04020005, 0x4a034406, 0x00000002, + 0x0201f000, 0x0010230c, 0x801831c0, 0x0400000a, + 0x412c0800, 0x0201f800, 0x00103a00, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x0010230c, + 0x40065800, 0x4a025c04, 0x00008000, 0x497a5a04, + 0x0201f800, 0x00109100, 0x04020005, 0x4a034406, + 0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809, + 0x001030d2, 0x1c01f000, 0x592c0005, 0x82000580, + 0x01000000, 0x04020005, 0x4a034406, 0x00000004, + 0x0201f000, 0x0010230c, 0x592c0406, 0x82002d00, + 0x0000ff00, 0x82000500, 0x000000ff, 0x80000904, + 0x80040800, 0x82040480, 0x00000006, 0x04001003, + 0x42000800, 0x00000005, 0x832ca400, 0x00000006, + 0x4050a800, 0x4004b000, 0x0201f800, 0x0010ab28, 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40, 0x832c0400, 0x00000006, 0x4c140000, 0x0201f800, - 0x00103841, 0x5c002800, 0x801429c0, 0x04000003, - 0x4a01d809, 0x00102ef2, 0x5c00b000, 0x5c00a800, - 0x5c00a000, 0x1c01f000, 0x4031d800, 0x58ef400b, + 0x00103a28, 0x5c002800, 0x801429c0, 0x04000003, + 0x4a01d809, 0x001030ff, 0x1c01f000, 0x4031d800, + 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x00102304, 0x812e59c0, + 0x02000800, 0x001005d8, 0x592c0006, 0x82000500, + 0xff000000, 0x80000904, 0x800409c0, 0x02000000, + 0x00102304, 0x82040480, 0x0000000e, 0x04001003, + 0x42000800, 0x0000000d, 0x592e5801, 0x812e59c0, + 0x02000800, 0x001005d8, 0x832ca400, 0x00000005, + 0x4050a800, 0x4004b000, 0x0201f800, 0x0010ab28, + 0x58ec1007, 0x58ec1808, 0x832c0400, 0x00000005, + 0x0201f000, 0x00103a28, 0x0201f800, 0x00103a00, + 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, + 0x0010230c, 0x59a00c06, 0x82040500, 0x0000ff00, + 0x840001c0, 0x82001480, 0x00000007, 0x02021000, + 0x00102310, 0x0c01f001, 0x0010313d, 0x00103144, + 0x0010314b, 0x0010314b, 0x0010314b, 0x0010314d, + 0x00103152, 0x42000800, 0x0000000d, 0x42003800, + 0x00103166, 0x4a034000, 0x0010b4eb, 0x0401f013, + 0x42000800, 0x0000000d, 0x42003800, 0x00103166, + 0x4a034000, 0x0010b4f8, 0x0401f00c, 0x0201f000, + 0x00102310, 0x42000800, 0x00000008, 0x42003800, + 0x00103179, 0x0401f005, 0x42000800, 0x00000004, + 0x42003800, 0x001031c3, 0x59a00207, 0x59a01407, + 0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09, + 0x900001c0, 0x800c1d40, 0x832c0400, 0x00000005, + 0x4c1c0000, 0x0201f800, 0x00103a25, 0x5c003800, + 0x481dd809, 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200, - 0x02000000, 0x001020aa, 0x812e59c0, 0x02000800, - 0x00100615, 0x592c0006, 0x82000500, 0xff000000, - 0x80000904, 0x800409c0, 0x02000000, 0x001020aa, - 0x82040480, 0x0000000e, 0x04001003, 0x42000800, - 0x0000000d, 0x592e5801, 0x812e59c0, 0x02000800, - 0x00100615, 0x4c500000, 0x4c540000, 0x4c580000, - 0x832ca400, 0x00000005, 0x4050a800, 0x4004b000, - 0x0201f800, 0x0010a94f, 0x5c00b000, 0x5c00a800, - 0x5c00a000, 0x58ec1007, 0x58ec1808, 0x832c0400, - 0x00000005, 0x0201f000, 0x00103841, 0x0201f800, - 0x0010381a, 0x04020005, 0x4a034406, 0x00000002, - 0x0201f000, 0x001020b2, 0x59a00c06, 0x82040500, - 0x0000ff00, 0x840001c0, 0x82001480, 0x00000007, - 0x02021000, 0x001020b6, 0x0c01f001, 0x00102f36, - 0x00102f3d, 0x00102f44, 0x00102f44, 0x00102f44, - 0x00102f46, 0x00102f4b, 0x42000800, 0x0000000d, - 0x42003800, 0x00102f5f, 0x4a034000, 0x0010b2e7, - 0x0401f013, 0x42000800, 0x0000000d, 0x42003800, - 0x00102f5f, 0x4a034000, 0x0010b2f4, 0x0401f00c, - 0x0201f000, 0x001020b6, 0x42000800, 0x00000008, - 0x42003800, 0x00102f72, 0x0401f005, 0x42000800, - 0x00000004, 0x42003800, 0x00102fbc, 0x59a00207, + 0x02000000, 0x00102304, 0x4a03501f, 0x00000001, + 0x4200b000, 0x0000000d, 0x59a0a800, 0x832ca400, + 0x00000005, 0x0201f800, 0x0010ab17, 0x0201f000, + 0x001022c0, 0x4031d800, 0x58ef400b, 0x58ee580d, + 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, + 0x00102304, 0x832ca400, 0x00000005, 0x50500000, + 0x82001500, 0x000c0016, 0x02020000, 0x00102310, + 0x82500c00, 0x00000003, 0x50040000, 0x82001500, + 0x00000001, 0x02020000, 0x00102310, 0x50500000, + 0x82001500, 0x00000028, 0x0400001d, 0x82081580, + 0x00000028, 0x02020000, 0x00102310, 0x80500800, + 0x50040000, 0x82001500, 0x00000013, 0x82081580, + 0x00000013, 0x02020000, 0x00102310, 0x80040800, + 0x50040000, 0x82001500, 0x00010000, 0x82081580, + 0x00010000, 0x02020000, 0x00102310, 0x836c0580, + 0x00000000, 0x04000012, 0x599c0019, 0x8c00050e, + 0x0402000f, 0x0201f000, 0x00102310, 0x80500800, + 0x50040000, 0x82001500, 0x00000013, 0x02020000, + 0x00102310, 0x80040800, 0x50040000, 0x82001500, + 0x00010000, 0x02020000, 0x00102310, 0x4200b000, + 0x00000008, 0x4200a800, 0x0010b4e3, 0x0201f800, + 0x0010ab17, 0x0201f000, 0x001022c0, 0x4031d800, + 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x00102304, 0x4200b000, + 0x00000004, 0x4200a800, 0x0010b8fa, 0x832ca400, + 0x00000005, 0x0201f800, 0x0010ab17, 0x59a80005, + 0x84000550, 0x48035005, 0x0201f000, 0x001022c0, + 0x0201f800, 0x00103a00, 0x04020005, 0x4a034406, + 0x00000002, 0x0201f000, 0x0010230c, 0x59a00c06, + 0x82040500, 0x0000ff00, 0x840001c0, 0x82001480, + 0x00000006, 0x02021000, 0x00102310, 0x0c01f001, + 0x001031ee, 0x001031f3, 0x001031f8, 0x001031f8, + 0x001031f8, 0x001031fa, 0x42000800, 0x0000000d, + 0x4200a000, 0x0010b4eb, 0x0401f00c, 0x42000800, + 0x0000000d, 0x4200a000, 0x0010b4f8, 0x0401f007, + 0x0201f000, 0x00102310, 0x42000800, 0x00000008, + 0x4200a000, 0x0010b4e3, 0x4004b000, 0x832cac00, + 0x00000005, 0x0201f800, 0x0010ab17, 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40, 0x832c0400, - 0x00000005, 0x4c1c0000, 0x0201f800, 0x0010383e, - 0x5c003800, 0x481dd809, 0x1c01f000, 0x4031d800, - 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, - 0x00000200, 0x02000000, 0x001020aa, 0x4a03501f, - 0x00000001, 0x4200b000, 0x0000000d, 0x59a0a800, - 0x832ca400, 0x00000005, 0x0201f800, 0x0010a93e, - 0x0201f000, 0x00102066, 0x4031d800, 0x58ef400b, - 0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200, - 0x02000000, 0x001020aa, 0x832ca400, 0x00000005, - 0x50500000, 0x82001500, 0x000c0016, 0x02020000, - 0x001020b6, 0x82500c00, 0x00000003, 0x50040000, - 0x82001500, 0x00000001, 0x02020000, 0x001020b6, - 0x50500000, 0x82001500, 0x00000028, 0x0400001d, - 0x82081580, 0x00000028, 0x02020000, 0x001020b6, - 0x80500800, 0x50040000, 0x82001500, 0x00000013, - 0x82081580, 0x00000013, 0x02020000, 0x001020b6, - 0x80040800, 0x50040000, 0x82001500, 0x00010000, - 0x82081580, 0x00010000, 0x02020000, 0x001020b6, - 0x836c0580, 0x00000000, 0x04000012, 0x599c0019, - 0x8c00050e, 0x0402000f, 0x0201f000, 0x001020b6, - 0x80500800, 0x50040000, 0x82001500, 0x00000013, - 0x02020000, 0x001020b6, 0x80040800, 0x50040000, - 0x82001500, 0x00010000, 0x02020000, 0x001020b6, - 0x4200b000, 0x00000008, 0x4200a800, 0x0010b2df, - 0x0201f800, 0x0010a93e, 0x0201f000, 0x00102066, - 0x4031d800, 0x58ef400b, 0x58ee580d, 0x58ec0002, - 0x82000580, 0x00000200, 0x02000000, 0x001020aa, - 0x4200b000, 0x00000004, 0x4200a800, 0x0010b6f9, - 0x832ca400, 0x00000005, 0x0201f800, 0x0010a93e, - 0x59a80005, 0x84000550, 0x48035005, 0x0201f000, - 0x00102066, 0x0201f800, 0x0010381a, 0x04020005, - 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, - 0x59a00c06, 0x82040500, 0x0000ff00, 0x840001c0, - 0x82001480, 0x00000006, 0x02021000, 0x001020b6, - 0x0c01f001, 0x00102fe7, 0x00102fec, 0x00102ff1, - 0x00102ff1, 0x00102ff1, 0x00102ff3, 0x42000800, - 0x0000000d, 0x4200a000, 0x0010b2e7, 0x0401f00c, - 0x42000800, 0x0000000d, 0x4200a000, 0x0010b2f4, - 0x0401f007, 0x0201f000, 0x001020b6, 0x42000800, - 0x00000008, 0x4200a000, 0x0010b2df, 0x4004b000, - 0x832cac00, 0x00000005, 0x0201f800, 0x0010a93e, - 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, - 0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40, - 0x832c0400, 0x00000005, 0x0201f000, 0x00103841, - 0x836c0580, 0x00000000, 0x04020005, 0x4a034406, - 0x00000007, 0x0201f000, 0x001020b2, 0x59a01406, - 0x800811c0, 0x04020017, 0x59c40801, 0x82040d00, + 0x00000005, 0x0201f000, 0x00103a28, 0x836c0580, + 0x00000000, 0x04020005, 0x4a034406, 0x00000007, + 0x0201f000, 0x0010230c, 0x59a00406, 0x800001c0, + 0x0400001a, 0x59a80005, 0x8c000514, 0x04000005, + 0x42000000, 0x00000001, 0x40000800, 0x0401f003, + 0x59a00207, 0x59a80853, 0x48035053, 0x0201f800, + 0x0010163b, 0x04000022, 0x0201f800, 0x00101642, + 0x0400001f, 0x0201f800, 0x00101649, 0x0400001c, + 0x0201f800, 0x00101650, 0x04000019, 0x48075053, + 0x0201f000, 0x00102310, 0x59c40801, 0x82040d00, 0x00018000, 0x82040580, 0x00000000, 0x04020004, - 0x4a034406, 0x00000000, 0x0401f048, 0x82040580, + 0x4a034406, 0x00000000, 0x0401f00d, 0x82040580, 0x00008000, 0x04020004, 0x4a034406, 0x00000001, - 0x0401f042, 0x82040580, 0x00010000, 0x02020800, - 0x00100615, 0x4a034406, 0x00000003, 0x0401f03b, - 0x59a8006f, 0x8c000508, 0x04000005, 0x42000000, - 0x00000001, 0x40000800, 0x0401f003, 0x59a00207, - 0x59a80853, 0x48035053, 0x0201f800, 0x001016ac, - 0x0400000d, 0x0201f800, 0x001016b3, 0x0400000a, - 0x0201f800, 0x001016ba, 0x04000007, 0x0201f800, - 0x001016c1, 0x04000004, 0x48075053, 0x0201f000, - 0x001020b6, 0x82080580, 0x00000002, 0x0402001f, - 0x59c40006, 0x84000500, 0x48038806, 0x0201f800, - 0x00106c32, 0x497b8880, 0x0201f800, 0x0010a7e7, - 0x0201f800, 0x0010a7f5, 0x42000000, 0x0010b6c9, - 0x0201f800, 0x0010a86e, 0x82000540, 0x00000001, - 0x0201f800, 0x00104e5d, 0x4a038808, 0x00000000, - 0x4202d800, 0x00000004, 0x42001000, 0x00000001, - 0x0201f800, 0x001019aa, 0x4a035049, 0x00000001, - 0x0201f800, 0x0010071a, 0x0201f000, 0x00102066, - 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, - 0x0201f000, 0x001020b2, 0x836c0580, 0x00000003, - 0x04000005, 0x4a034406, 0x00000007, 0x0201f000, - 0x001020b2, 0x59a28c06, 0x59a0320b, 0x82183500, - 0x000000ff, 0x0201f800, 0x00020267, 0x02020000, - 0x001020b6, 0x83440580, 0x000007fd, 0x04000008, - 0x0201f800, 0x00104836, 0x04000005, 0x42000800, - 0x00000009, 0x0201f000, 0x001020b2, 0x0201f800, - 0x0010381a, 0x04020005, 0x4a034406, 0x00000002, - 0x0201f000, 0x001020b2, 0x497a5a04, 0x4a025c04, - 0x00008000, 0x0201f800, 0x00108ed2, 0x04020005, - 0x4a034406, 0x00000003, 0x0201f000, 0x001020b2, - 0x4a01d809, 0x00103097, 0x1c01f000, 0x592c0005, - 0x82000d00, 0x0000ffff, 0x82000500, 0xffff0000, - 0x82000580, 0x01000000, 0x04020005, 0x4a034406, - 0x00000004, 0x0201f000, 0x001020b2, 0x80040904, - 0x4c500000, 0x4c540000, 0x4c580000, 0x832ca400, + 0x0401f007, 0x82040580, 0x00010000, 0x02020800, + 0x001005d8, 0x4a034406, 0x00000003, 0x59a00406, + 0x82000580, 0x00000002, 0x0402001f, 0x59c40006, + 0x84000500, 0x48038806, 0x0201f800, 0x00106ede, + 0x497b8880, 0x0201f800, 0x0010a9c0, 0x0201f800, + 0x0010a9ce, 0x42000000, 0x0010b8ca, 0x0201f800, + 0x0010aa47, 0x82000540, 0x00000001, 0x0201f800, + 0x0010518c, 0x4a038808, 0x00000000, 0x4202d800, + 0x00000004, 0x42001000, 0x00000001, 0x0201f800, + 0x0010193d, 0x4a035049, 0x00000001, 0x0201f800, + 0x001006d4, 0x0201f000, 0x001022c0, 0x800409c0, + 0x04000005, 0x4a034406, 0x00000001, 0x0201f000, + 0x0010230c, 0x836c0580, 0x00000003, 0x04000005, + 0x4a034406, 0x00000007, 0x0201f000, 0x0010230c, + 0x59a28c06, 0x59a0320b, 0x82183500, 0x000000ff, + 0x0201f800, 0x00020245, 0x02020000, 0x00102310, + 0x83440580, 0x000007fd, 0x04000008, 0x0201f800, + 0x001049e7, 0x04000005, 0x42000800, 0x00000009, + 0x0201f000, 0x0010230c, 0x0201f800, 0x00103a00, + 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, + 0x0010230c, 0x497a5a04, 0x4a025c04, 0x00008000, + 0x0201f800, 0x00109115, 0x04020005, 0x4a034406, + 0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809, + 0x0010329e, 0x1c01f000, 0x592c0005, 0x82000d00, + 0x0000ffff, 0x82000500, 0xffff0000, 0x82000580, + 0x01000000, 0x04020005, 0x4a034406, 0x00000004, + 0x0201f000, 0x0010230c, 0x80040904, 0x832ca400, 0x00000005, 0x4050a800, 0x4004b000, 0x0201f800, - 0x0010a94f, 0x5c00b000, 0x5c00a800, 0x5c00a000, - 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, - 0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40, - 0x832c0400, 0x00000005, 0x0201f000, 0x00103841, - 0x496fc857, 0x836c0580, 0x00000000, 0x04000005, - 0x4a034406, 0x0000001a, 0x0201f000, 0x001020b2, - 0x0201f800, 0x00104e0d, 0x02020800, 0x00103f5c, + 0x0010ab28, 0x59a00207, 0x59a01407, 0x900001c0, + 0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0, + 0x800c1d40, 0x832c0400, 0x00000005, 0x0201f000, + 0x00103a28, 0x496fc857, 0x836c0580, 0x00000000, + 0x04000005, 0x4a034406, 0x0000001a, 0x0201f000, + 0x0010230c, 0x0201f800, 0x0010513b, 0x02020800, + 0x00104142, 0x42000800, 0x00000020, 0x59a00407, + 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, + 0x59a01a09, 0x900c19c0, 0x800c1d40, 0x419c0000, + 0x49a3c857, 0x0201f800, 0x00103a25, 0x4a01d809, + 0x001032da, 0x1c01f000, 0x4833c857, 0x4031d800, + 0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200, + 0x02000000, 0x00102304, 0x599c0200, 0x800001c0, + 0x02000000, 0x00102310, 0x59a80005, 0x8c000512, + 0x04000004, 0x599c0019, 0x8400050c, 0x48033819, + 0x0201f800, 0x001097d7, 0x59a80005, 0x8c000514, + 0x04000004, 0x599c0017, 0x84000508, 0x48033817, + 0x0201f800, 0x00103b25, 0x04020004, 0x8c00050a, + 0x02020000, 0x00102310, 0x4803c857, 0x8c000504, + 0x04020004, 0x59c408a3, 0x84040d7a, 0x480788a3, + 0x8c000502, 0x04020004, 0x59c408a3, 0x84040d08, + 0x480788a3, 0x599c0c02, 0x8c000500, 0x04020004, + 0x8c000516, 0x04000012, 0x0401f001, 0x82041480, + 0x0000007f, 0x02021000, 0x00102310, 0x82041400, + 0x0010210e, 0x50081000, 0x82081500, 0x000000ff, + 0x8c000500, 0x04020006, 0x480b5010, 0x42000800, + 0x00000003, 0x0201f800, 0x00106c78, 0x599c0019, + 0x8c00050e, 0x0402000b, 0x59a80806, 0x8c040d14, + 0x04000008, 0x42000800, 0x0010b4e3, 0x50040800, + 0x82040d00, 0x00000028, 0x02020000, 0x00102310, + 0x82000500, 0x00000030, 0x04000003, 0x80000108, + 0x0401f003, 0x42000000, 0x00000002, 0x48039040, + 0x42000800, 0x00000002, 0x82000400, 0x00103415, + 0x50001000, 0x0201f800, 0x00106c78, 0x599c0201, + 0x82000c80, 0x00000100, 0x02001000, 0x00102310, + 0x82000c80, 0x00000841, 0x02021000, 0x00102310, + 0x82000500, 0x00000007, 0x02020000, 0x00102310, + 0x599c0401, 0x80000540, 0x02000000, 0x00102310, + 0x599c0409, 0x599c0c07, 0x80040c80, 0x02021000, + 0x00102310, 0x80000040, 0x02000000, 0x00102310, + 0x599c0209, 0x599c0a07, 0x80040c80, 0x02021000, + 0x00102310, 0x80000040, 0x02000000, 0x00102310, + 0x0201f800, 0x001053cd, 0x0201f800, 0x00104cb6, + 0x599c0201, 0x48035004, 0x0201f800, 0x001012ee, + 0x599c020a, 0x800001c0, 0x04000003, 0x4803504d, + 0x0401f003, 0x4a03504d, 0x000000c8, 0x0201f800, + 0x00103b25, 0x04000004, 0x0201f800, 0x001060df, + 0x417a5000, 0x836c0580, 0x00000000, 0x04020098, + 0x599c0003, 0x599c0804, 0x9c0001c0, 0x9c0409c0, + 0x48035002, 0x48075003, 0x599c1017, 0x8c08151c, + 0x04000006, 0x599c0005, 0x599c0806, 0x9c0001c0, + 0x9c0409c0, 0x0401f003, 0x82000500, 0xf0ffffff, + 0x48035000, 0x48075001, 0x42001000, 0x0010b4eb, + 0x48001000, 0x48041001, 0x42001000, 0x0010b4f8, + 0x48001000, 0x48041001, 0x59a80005, 0x8c000514, + 0x04020015, 0x599c1019, 0x82081500, 0x0000e000, + 0x82080580, 0x00000000, 0x0402000c, 0x4a035053, + 0x00000000, 0x42000000, 0x00000001, 0x0201f800, + 0x0010188c, 0x42000000, 0x00000001, 0x0201f800, + 0x00101821, 0x0401f02b, 0x82080580, 0x00002000, + 0x0402000a, 0x4a035053, 0x00000001, 0x41780000, + 0x0201f800, 0x0010188c, 0x41780000, 0x0201f800, + 0x00101821, 0x0401f01f, 0x82080580, 0x00004000, + 0x04020006, 0x4a035053, 0x00000002, 0x4a035049, + 0x00000001, 0x0401f017, 0x82080580, 0x00006000, + 0x02020000, 0x00102310, 0x59a80858, 0x82040d80, + 0x01391077, 0x04020005, 0x59e00813, 0x8c040d00, + 0x02020000, 0x00102310, 0x4a035053, 0x00000003, + 0x42000000, 0x00000002, 0x0201f800, 0x0010188c, + 0x42000000, 0x00000002, 0x0201f800, 0x00101821, + 0x599c0019, 0x8c000520, 0x0400000d, 0x42000000, + 0x00000004, 0x42000800, 0x00000040, 0x0201f800, + 0x00101944, 0x42000000, 0x00000010, 0x42000800, + 0x000000c0, 0x0201f800, 0x00101944, 0x4a035032, + 0x0000aaaa, 0x599c1018, 0x82081500, 0x00000030, + 0x59a8006c, 0x80000540, 0x0400000c, 0x82080580, + 0x00000000, 0x02000000, 0x00102310, 0x599c1018, + 0x82081500, 0xffffffcf, 0x82081540, 0x00000010, + 0x480b3818, 0x0401f010, 0x82080d80, 0x00000000, + 0x04000007, 0x82080d80, 0x00000010, 0x0400000a, + 0x82080d80, 0x00000020, 0x04020002, 0x48075032, + 0x0201f800, 0x00103aba, 0x04000008, 0x0201f800, + 0x001015fe, 0x0201f800, 0x0010162a, 0x59a8002a, + 0x80040540, 0x4803502a, 0x49f3c857, 0x42001000, + 0x00105065, 0x0201f800, 0x00105f90, 0x42001000, + 0x00105058, 0x0201f800, 0x00106084, 0x4a038805, + 0xffffffff, 0x4a03c014, 0x00400040, 0x4a03c013, + 0x00400000, 0x0201f800, 0x001048c7, 0x59a0001d, + 0x84000540, 0x4803401d, 0x49f3c857, 0x0201f000, + 0x001022c0, 0x00000018, 0x0000000c, 0x00000018, + 0x00000020, 0x836c0580, 0x00000000, 0x04020005, + 0x42000800, 0x00000007, 0x0201f000, 0x0010230c, 0x42000800, 0x00000020, 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, - 0x900c19c0, 0x800c1d40, 0x419c0000, 0x49a3c857, - 0x0201f800, 0x0010383e, 0x4a01d809, 0x001030d9, - 0x1c01f000, 0x4833c857, 0x4031d800, 0x58ef400b, - 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, - 0x001020aa, 0x599c0200, 0x800001c0, 0x02000000, - 0x001020b6, 0x59a8006f, 0x8c000504, 0x04020003, - 0x8c000506, 0x04000004, 0x599c0019, 0x8400050c, - 0x48033819, 0x0201f800, 0x001095a3, 0x59a8006f, - 0x8c000502, 0x04000004, 0x599c0017, 0x84000508, - 0x48033817, 0x0201f800, 0x0010393e, 0x04020004, - 0x8c00050a, 0x02020000, 0x001020b6, 0x4803c857, - 0x8c000504, 0x04020004, 0x59c408a3, 0x84040d7a, - 0x480788a3, 0x8c000502, 0x04020004, 0x59c408a3, - 0x84040d08, 0x480788a3, 0x599c0c02, 0x8c000500, - 0x04020004, 0x8c000516, 0x04000012, 0x0401f001, - 0x82041480, 0x0000007f, 0x02021000, 0x001020b6, - 0x82041400, 0x00101eb5, 0x50081000, 0x82081500, - 0x000000ff, 0x8c000500, 0x04020006, 0x480b5010, - 0x42000800, 0x00000003, 0x0201f800, 0x001069af, - 0x599c0019, 0x8c000506, 0x04000003, 0x4a03b805, - 0x90000000, 0x8c00050e, 0x0402000b, 0x59a80806, - 0x8c040d14, 0x04000008, 0x42000800, 0x0010b2df, - 0x50040800, 0x82040d00, 0x00000028, 0x02020000, - 0x001020b6, 0x82000500, 0x00000030, 0x04000003, - 0x80000108, 0x0401f003, 0x42000000, 0x00000002, - 0x48039040, 0x42000800, 0x00000002, 0x82000400, - 0x0010321c, 0x50001000, 0x0201f800, 0x001069af, - 0x599c0201, 0x82000c80, 0x00000100, 0x02001000, - 0x001020b6, 0x82000c80, 0x00000841, 0x02021000, - 0x001020b6, 0x82000500, 0x00000007, 0x02020000, - 0x001020b6, 0x599c0401, 0x80000540, 0x02000000, - 0x001020b6, 0x599c0409, 0x599c0c07, 0x80040c80, - 0x02021000, 0x001020b6, 0x80000040, 0x02000000, - 0x001020b6, 0x599c0209, 0x599c0a07, 0x80040c80, - 0x02021000, 0x001020b6, 0x80000040, 0x02000000, - 0x001020b6, 0x0201f800, 0x0010509d, 0x0201f800, - 0x00104b53, 0x599c0201, 0x48035004, 0x0201f800, - 0x0010133e, 0x599c020a, 0x800001c0, 0x04000003, - 0x4803504d, 0x0401f003, 0x4a03504d, 0x000000c8, - 0x0201f800, 0x0010393e, 0x04000004, 0x0201f800, - 0x00105e18, 0x417a5000, 0x836c0580, 0x00000000, - 0x0402009a, 0x599c0003, 0x599c0804, 0x9c0001c0, - 0x9c0409c0, 0x48035002, 0x48075003, 0x599c1017, - 0x8c08151c, 0x04000006, 0x599c0005, 0x599c0806, - 0x9c0001c0, 0x9c0409c0, 0x0401f003, 0x82000500, - 0xf0ffffff, 0x48035000, 0x48075001, 0x42001000, - 0x0010b2e7, 0x48001000, 0x48041001, 0x42001000, - 0x0010b2f4, 0x48001000, 0x48041001, 0x59a8006f, - 0x8c000508, 0x04020017, 0x8c00050a, 0x04020021, - 0x599c1019, 0x82081500, 0x0000e000, 0x82080580, - 0x00000000, 0x0402000c, 0x4a035053, 0x00000000, - 0x42000000, 0x00000001, 0x0201f800, 0x001018fa, - 0x42000000, 0x00000001, 0x0201f800, 0x00101892, - 0x0401f02b, 0x82080580, 0x00002000, 0x0402000a, - 0x4a035053, 0x00000001, 0x41780000, 0x0201f800, - 0x001018fa, 0x41780000, 0x0201f800, 0x00101892, - 0x0401f01f, 0x82080580, 0x00004000, 0x04020006, - 0x4a035053, 0x00000002, 0x4a035049, 0x00000001, - 0x0401f017, 0x82080580, 0x00006000, 0x02020000, - 0x001020b6, 0x59a80858, 0x82040d80, 0x01391077, - 0x04020005, 0x59e00813, 0x8c040d00, 0x02020000, - 0x001020b6, 0x4a035053, 0x00000003, 0x42000000, - 0x00000002, 0x0201f800, 0x001018fa, 0x42000000, - 0x00000002, 0x0201f800, 0x00101892, 0x599c0019, - 0x8c000520, 0x0400000d, 0x42000000, 0x00000004, - 0x42000800, 0x00000040, 0x0201f800, 0x001019b1, - 0x42000000, 0x00000010, 0x42000800, 0x000000c0, - 0x0201f800, 0x001019b1, 0x4a035032, 0x0000aaaa, - 0x599c1018, 0x82081500, 0x00000030, 0x59a8006c, - 0x80000540, 0x0400000c, 0x82080580, 0x00000000, - 0x02000000, 0x001020b6, 0x599c1018, 0x82081500, - 0xffffffcf, 0x82081540, 0x00000010, 0x480b3818, - 0x0401f010, 0x82080d80, 0x00000000, 0x04000007, - 0x82080d80, 0x00000010, 0x0400000a, 0x82080d80, - 0x00000020, 0x04020002, 0x48075032, 0x0201f800, - 0x001038d3, 0x04000008, 0x0201f800, 0x00101668, - 0x0201f800, 0x00101694, 0x59a8002a, 0x80040540, - 0x4803502a, 0x49f3c857, 0x42001000, 0x00104d39, - 0x0201f800, 0x00105cc9, 0x42001000, 0x00104d2c, - 0x0201f800, 0x00105dbd, 0x4a038805, 0xffffffff, - 0x4a03c014, 0x00400040, 0x4a03c013, 0x00400000, - 0x0201f800, 0x00104717, 0x59a0001d, 0x84000540, - 0x4803401d, 0x49f3c857, 0x0201f000, 0x00102066, - 0x00000018, 0x0000000c, 0x00000018, 0x00000020, - 0x836c0580, 0x00000000, 0x04020005, 0x42000800, - 0x00000007, 0x0201f000, 0x001020b2, 0x42000800, + 0x900c19c0, 0x800c1d40, 0x419c0000, 0x0201f000, + 0x00103a28, 0x800409c0, 0x04000005, 0x4a034406, + 0x00000001, 0x0201f000, 0x0010230c, 0x0201f800, + 0x0010513b, 0x04020005, 0x4a034406, 0x00000016, + 0x0201f000, 0x0010230c, 0x59a80013, 0x8c000500, + 0x04000011, 0x4a034406, 0x00000000, 0x42000800, 0x00000020, 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, - 0x800c1d40, 0x419c0000, 0x0201f000, 0x00103841, - 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, - 0x0201f000, 0x001020b2, 0x0201f800, 0x00104e0d, - 0x04020005, 0x4a034406, 0x00000016, 0x0201f000, - 0x001020b2, 0x59a80013, 0x8c000500, 0x04000011, - 0x4a034406, 0x00000000, 0x42000800, 0x00000020, + 0x800c1d40, 0x42000000, 0x0010be21, 0x0201f000, + 0x00103a28, 0x4a034406, 0x00000001, 0x4200b000, + 0x00000020, 0x4200a800, 0x0010be21, 0x4200a000, + 0xffffffff, 0x4450a800, 0x8054a800, 0x8058b040, + 0x040207fd, 0x4d440000, 0x4d340000, 0x42028800, + 0xffffffff, 0x42002000, 0xffffffff, 0x42003000, + 0x00000001, 0x42003800, 0x00000001, 0x42001800, + 0x0010be21, 0x59a81010, 0x82081500, 0x000000ff, + 0x40180000, 0x0c01f001, 0x0010346e, 0x00103471, + 0x00103475, 0x00103479, 0x82102500, 0xffffff00, + 0x0401f014, 0x82102500, 0xffff00ff, 0x840811c0, + 0x0401f010, 0x82102500, 0xff00ffff, 0x900811c0, + 0x0401f00c, 0x82102500, 0x00ffffff, 0x9c0801c0, + 0x80102540, 0x44101800, 0x42003000, 0xffffffff, + 0x42002000, 0xffffffff, 0x800c1800, 0x0401f003, + 0x40080000, 0x80102540, 0x81468800, 0x83442c80, + 0x0000007f, 0x04021014, 0x4c080000, 0x4c0c0000, + 0x4c180000, 0x4c1c0000, 0x0201f800, 0x00020245, + 0x5c003800, 0x5c003000, 0x5c001800, 0x5c001000, + 0x040207f2, 0x0201f800, 0x001049f3, 0x040207ef, + 0x80183000, 0x801c3800, 0x59341202, 0x40180000, + 0x0c01f7ce, 0x82100580, 0xffffffff, 0x04000002, + 0x44101800, 0x42001800, 0x0010be21, 0x500c0000, + 0x82000500, 0xffffff00, 0x801c0540, 0x44001800, + 0x5c026800, 0x5c028800, 0x42000800, 0x00000020, 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40, - 0x42000000, 0x0010bc20, 0x0201f000, 0x00103841, - 0x4a034406, 0x00000001, 0x4200b000, 0x00000020, - 0x4200a800, 0x0010bc20, 0x4200a000, 0xffffffff, - 0x4450a800, 0x8054a800, 0x8058b040, 0x040207fd, - 0x4d440000, 0x4d340000, 0x42028800, 0xffffffff, - 0x42002000, 0xffffffff, 0x42003000, 0x00000001, - 0x42003800, 0x00000001, 0x42001800, 0x0010bc20, - 0x59a81010, 0x82081500, 0x000000ff, 0x40180000, - 0x0c01f001, 0x00103275, 0x00103278, 0x0010327c, - 0x00103280, 0x82102500, 0xffffff00, 0x0401f014, - 0x82102500, 0xffff00ff, 0x840811c0, 0x0401f010, - 0x82102500, 0xff00ffff, 0x900811c0, 0x0401f00c, - 0x82102500, 0x00ffffff, 0x9c0801c0, 0x80102540, - 0x44101800, 0x42003000, 0xffffffff, 0x42002000, - 0xffffffff, 0x800c1800, 0x0401f003, 0x40080000, - 0x80102540, 0x81468800, 0x83442c80, 0x0000007f, - 0x04021014, 0x4c080000, 0x4c0c0000, 0x4c180000, - 0x4c1c0000, 0x0201f800, 0x00020267, 0x5c003800, - 0x5c003000, 0x5c001800, 0x5c001000, 0x040207f2, - 0x0201f800, 0x00104842, 0x040207ef, 0x80183000, - 0x801c3800, 0x59341202, 0x40180000, 0x0c01f7ce, - 0x82100580, 0xffffffff, 0x04000002, 0x44101800, - 0x42001800, 0x0010bc20, 0x500c0000, 0x82000500, - 0xffffff00, 0x801c0540, 0x44001800, 0x5c026800, - 0x5c028800, 0x42000800, 0x00000020, 0x59a00407, + 0x42000000, 0x0010be21, 0x0201f000, 0x00103a28, + 0x59a28c06, 0x59a0020b, 0x8c000500, 0x0400000e, + 0x59a01208, 0x59a00408, 0x82000500, 0x000000ff, + 0x900001c0, 0x80081540, 0x41784000, 0x0201f800, + 0x00104919, 0x04000008, 0x48034406, 0x0201f000, + 0x00102310, 0x0201f800, 0x00020245, 0x02020000, + 0x00102310, 0x0201f800, 0x00103a00, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x0010230c, + 0x59a0020b, 0x8c000500, 0x04000005, 0x0201f800, + 0x001049f3, 0x02020000, 0x00103ac4, 0x59a0020b, + 0x8c000502, 0x04000019, 0x83440480, 0x000007f0, + 0x04021016, 0x0201f800, 0x001049fc, 0x04020013, + 0x497a5a04, 0x4a025c04, 0x00008000, 0x0201f800, + 0x001090e6, 0x04020005, 0x4a034406, 0x00000003, + 0x0201f000, 0x0010230c, 0x4a01d809, 0x001034f1, + 0x1c01f000, 0x59a28c06, 0x0201f800, 0x00020245, + 0x02020000, 0x00102310, 0x4200b000, 0x0000000a, + 0x4134a000, 0x832e5c00, 0x00000002, 0x412ca800, + 0x0201f800, 0x0010ab17, 0x832cac00, 0x00000006, + 0x4054a000, 0x4200b000, 0x00000004, 0x0201f800, + 0x0010ab28, 0x592c0802, 0x82040500, 0x00ff00ff, + 0x900001c0, 0x82041500, 0xff00ff00, 0x80080540, + 0x48025802, 0x592c0801, 0x82040500, 0x00ff00ff, + 0x900001c0, 0x82041500, 0xff00ff00, 0x80080540, + 0x48025801, 0x42000800, 0x0000000a, 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, - 0x59a01a09, 0x900c19c0, 0x800c1d40, 0x42000000, - 0x0010bc20, 0x0201f000, 0x00103841, 0x59a28c06, - 0x59a0020b, 0x8c000500, 0x0400000e, 0x59a01208, - 0x59a00408, 0x82000500, 0x000000ff, 0x900001c0, - 0x80081540, 0x41784000, 0x0201f800, 0x00104768, - 0x04000008, 0x48034406, 0x0201f000, 0x001020b6, - 0x0201f800, 0x00020267, 0x02020000, 0x001020b6, - 0x0201f800, 0x0010381a, 0x04020005, 0x4a034406, - 0x00000002, 0x0201f000, 0x001020b2, 0x59a0020b, - 0x8c000500, 0x04000005, 0x0201f800, 0x00104842, - 0x02020000, 0x001038dd, 0x59a0020b, 0x8c000502, - 0x04000019, 0x83440480, 0x000007f0, 0x04021016, - 0x0201f800, 0x0010484b, 0x04020013, 0x497a5a04, - 0x4a025c04, 0x00008000, 0x0201f800, 0x00108ea3, - 0x04020005, 0x4a034406, 0x00000003, 0x0201f000, - 0x001020b2, 0x4a01d809, 0x001032f8, 0x1c01f000, - 0x59a28c06, 0x0201f800, 0x00020267, 0x02020000, - 0x001020b6, 0x4c580000, 0x4c500000, 0x4c540000, - 0x4200b000, 0x0000000a, 0x4134a000, 0x832e5c00, - 0x00000002, 0x412ca800, 0x0201f800, 0x0010a93e, - 0x832cac00, 0x00000006, 0x4054a000, 0x4200b000, - 0x00000004, 0x0201f800, 0x0010a94f, 0x5c00a800, - 0x5c00a000, 0x5c00b000, 0x592c0802, 0x82040500, - 0x00ff00ff, 0x900001c0, 0x82041500, 0xff00ff00, - 0x80080540, 0x48025802, 0x592c0801, 0x82040500, - 0x00ff00ff, 0x900001c0, 0x82041500, 0xff00ff00, - 0x80080540, 0x48025801, 0x42000800, 0x0000000a, - 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, - 0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40, - 0x412c0000, 0x0201f000, 0x00103841, 0x496fc857, - 0x496f4406, 0x0201f000, 0x00102066, 0x59a28c06, - 0x0201f800, 0x00020267, 0x02020000, 0x001020b6, - 0x836c0580, 0x00000003, 0x04000005, 0x4a034406, - 0x00000007, 0x0201f000, 0x001020b2, 0x83340c00, - 0x00000006, 0x59a0020b, 0x8c000500, 0x04000003, - 0x83340c00, 0x00000008, 0x58040001, 0x48034409, - 0x900001c0, 0x48034209, 0x50040000, 0x48034407, - 0x900001c0, 0x48034207, 0x59340200, 0x48034406, - 0x0201f000, 0x00102066, 0x800409c0, 0x04000005, - 0x4a034406, 0x00000001, 0x0201f000, 0x001020b2, - 0x59a0220b, 0x8c102500, 0x0402002e, 0x8c102506, - 0x04020006, 0x59a03208, 0x82180480, 0x00000003, - 0x02021000, 0x001020b6, 0x59a28c06, 0x0201f800, - 0x00020267, 0x02020000, 0x001020b6, 0x0201f800, - 0x00104836, 0x04000005, 0x4a034406, 0x00000009, - 0x0201f000, 0x001020b2, 0x0201f800, 0x0010381a, - 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, - 0x001020b2, 0x59a0220b, 0x8c102506, 0x04000004, - 0x59343002, 0x82183500, 0x00ffffff, 0x497a5a04, - 0x4a025c04, 0x00008000, 0x0201f800, 0x00108e65, - 0x04020005, 0x4a034406, 0x00000003, 0x0201f000, - 0x001020b2, 0x4a01d809, 0x001033de, 0x1c01f000, - 0x59a28c06, 0x0201f800, 0x00020267, 0x02020000, - 0x001020b6, 0x0201f800, 0x00104836, 0x04000005, - 0x4a034406, 0x00000009, 0x0201f000, 0x001020b2, - 0x0201f800, 0x0010381a, 0x04020005, 0x4a034406, - 0x00000002, 0x0201f000, 0x001020b2, 0x497a5a04, - 0x4a025c04, 0x00008000, 0x0201f800, 0x0010381a, - 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, - 0x001020b2, 0x592e5800, 0x0201f800, 0x00108e7a, - 0x04020005, 0x4a034406, 0x00000003, 0x0201f000, - 0x001020b2, 0x4a01d809, 0x001033b0, 0x1c01f000, - 0x592c2805, 0x82140d80, 0x01000000, 0x04020005, - 0x4a034406, 0x00000004, 0x0201f000, 0x001020b2, - 0x42000800, 0x00000008, 0x59a00207, 0x59a01407, - 0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09, - 0x900001c0, 0x800c1d40, 0x832c0400, 0x00000005, - 0x0201f800, 0x00103841, 0x8c142d00, 0x04000003, - 0x4a01d809, 0x001033cb, 0x1c01f000, 0x4031d800, - 0x58ef400b, 0x58ee580e, 0x58ec0002, 0x82000580, - 0x00000200, 0x02000000, 0x001020aa, 0x812e59c0, - 0x02000800, 0x00100615, 0x42000800, 0x00000008, - 0x832c0400, 0x00000005, 0x58ec1007, 0x58ec1808, - 0x0201f000, 0x00103841, 0x592c0005, 0x82000580, - 0x01000000, 0x04020005, 0x4a034406, 0x00000004, - 0x0201f000, 0x001020b2, 0x59a00207, 0x59a01407, - 0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09, - 0x900001c0, 0x800c1d40, 0x42000800, 0x00000006, - 0x832c0400, 0x00000006, 0x0201f000, 0x00103841, - 0x59a00a0a, 0x800409c0, 0x02000000, 0x001020b6, - 0x82040480, 0x000000e8, 0x04001003, 0x42000800, - 0x000000e7, 0x59a00207, 0x59a01407, 0x900001c0, + 0x59a01a09, 0x900c19c0, 0x800c1d40, 0x412c0000, + 0x0201f000, 0x00103a28, 0x496fc857, 0x496f4406, + 0x0201f000, 0x001022c0, 0x59a28c06, 0x0201f800, + 0x00020245, 0x02020000, 0x00102310, 0x836c0580, + 0x00000003, 0x04000005, 0x4a034406, 0x00000007, + 0x0201f000, 0x0010230c, 0x83340c00, 0x00000006, + 0x59a0020b, 0x8c000500, 0x04000003, 0x83340c00, + 0x00000008, 0x58040001, 0x48034409, 0x900001c0, + 0x48034209, 0x50040000, 0x48034407, 0x900001c0, + 0x48034207, 0x59340200, 0x48034406, 0x0201f000, + 0x001022c0, 0x800409c0, 0x04000005, 0x4a034406, + 0x00000001, 0x0201f000, 0x0010230c, 0x59a0220b, + 0x8c102500, 0x0402002e, 0x8c102506, 0x04020006, + 0x59a03208, 0x82180480, 0x00000003, 0x02021000, + 0x00102310, 0x59a28c06, 0x0201f800, 0x00020245, + 0x02020000, 0x00102310, 0x0201f800, 0x001049e7, + 0x04000005, 0x4a034406, 0x00000009, 0x0201f000, + 0x0010230c, 0x0201f800, 0x00103a00, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x0010230c, + 0x59a0220b, 0x8c102506, 0x04000004, 0x59343002, + 0x82183500, 0x00ffffff, 0x497a5a04, 0x4a025c04, + 0x00008000, 0x0201f800, 0x001090a8, 0x04020005, + 0x4a034406, 0x00000003, 0x0201f000, 0x0010230c, + 0x4a01d809, 0x001035d1, 0x1c01f000, 0x59a28c06, + 0x0201f800, 0x00020245, 0x02020000, 0x00102310, + 0x0201f800, 0x001049e7, 0x04000005, 0x4a034406, + 0x00000009, 0x0201f000, 0x0010230c, 0x0201f800, + 0x00103a00, 0x04020005, 0x4a034406, 0x00000002, + 0x0201f000, 0x0010230c, 0x497a5a04, 0x4a025c04, + 0x00008000, 0x0201f800, 0x00103a00, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x0010230c, + 0x592e5800, 0x0201f800, 0x001090bd, 0x04020005, + 0x4a034406, 0x00000003, 0x0201f000, 0x0010230c, + 0x4a01d809, 0x001035a3, 0x1c01f000, 0x592c2805, + 0x82140d80, 0x01000000, 0x04020005, 0x4a034406, + 0x00000004, 0x0201f000, 0x0010230c, 0x42000800, + 0x00000008, 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0, - 0x800c1d40, 0x83880400, 0x00000000, 0x0201f800, - 0x00103841, 0x4a01d809, 0x0010340c, 0x1c01f000, - 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, - 0x00000200, 0x02000000, 0x001020aa, 0x59a0020b, + 0x800c1d40, 0x832c0400, 0x00000005, 0x0201f800, + 0x00103a28, 0x8c142d00, 0x04000003, 0x4a01d809, + 0x001035be, 0x1c01f000, 0x4031d800, 0x58ef400b, + 0x58ee580e, 0x58ec0002, 0x82000580, 0x00000200, + 0x02000000, 0x00102304, 0x812e59c0, 0x02000800, + 0x001005d8, 0x42000800, 0x00000008, 0x832c0400, + 0x00000005, 0x58ec1007, 0x58ec1808, 0x0201f000, + 0x00103a28, 0x592c0005, 0x82000580, 0x01000000, + 0x04020005, 0x4a034406, 0x00000004, 0x0201f000, + 0x0010230c, 0x59a00207, 0x59a01407, 0x900001c0, + 0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0, + 0x800c1d40, 0x42000800, 0x00000006, 0x832c0400, + 0x00000006, 0x0201f000, 0x00103a28, 0x59a00a0a, + 0x800409c0, 0x02000000, 0x00102310, 0x82040480, + 0x000000e7, 0x04001003, 0x42000800, 0x000000e6, + 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, + 0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40, + 0x83880400, 0x00000000, 0x0201f800, 0x00103a28, + 0x4a01d809, 0x001035ff, 0x1c01f000, 0x4031d800, + 0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200, + 0x02000000, 0x00102304, 0x58ef400b, 0x59a0020b, 0x8c000500, 0x04000008, 0x83880400, 0x00000000, 0x4803c840, 0x4a03c842, 0x00000006, 0x04011000, - 0x497b8885, 0x4a034207, 0x000000e7, 0x0201f000, - 0x00102066, 0x800409c0, 0x04000005, 0x4a034406, - 0x00000001, 0x0201f000, 0x001020b2, 0x0401fbf3, + 0x497b8885, 0x4a034207, 0x000000e6, 0x0201f000, + 0x001022c0, 0x800409c0, 0x04000005, 0x4a034406, + 0x00000001, 0x0201f000, 0x0010230c, 0x0401fbe5, 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, - 0x001020b2, 0x497a5a04, 0x4a025c04, 0x00008000, - 0x59a00406, 0x800001c0, 0x02000000, 0x001020b6, + 0x0010230c, 0x497a5a04, 0x4a025c04, 0x00008000, + 0x59a00406, 0x800001c0, 0x02000000, 0x00102310, 0x82001580, 0x000000ff, 0x04000005, 0x82001480, - 0x00000004, 0x02021000, 0x001020b6, 0x40001000, - 0x0201f800, 0x00101d6a, 0x04020005, 0x4a034406, - 0x00000003, 0x0201f000, 0x001020b2, 0x4a01d809, - 0x00103446, 0x1c01f000, 0x592c0005, 0x82000580, - 0x01000000, 0x02020000, 0x00102066, 0x4a034406, - 0x00000004, 0x0201f000, 0x001020b2, 0x59a01406, + 0x00000004, 0x02021000, 0x00102310, 0x40001000, + 0x0201f800, 0x00101fbf, 0x04020005, 0x4a034406, + 0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809, + 0x0010363a, 0x1c01f000, 0x592c0005, 0x82000580, + 0x01000000, 0x02020000, 0x001022c0, 0x4a034406, + 0x00000004, 0x0201f000, 0x0010230c, 0x59a01406, 0x8c081508, 0x04020007, 0x800409c0, 0x04000005, - 0x4a034406, 0x00000001, 0x0201f000, 0x001020b2, + 0x4a034406, 0x00000001, 0x0201f000, 0x0010230c, 0x59a01c07, 0x820c0480, 0x00001000, 0x02021000, - 0x001020b6, 0x497b2804, 0x497b2805, 0x497b281c, + 0x00102310, 0x497b2804, 0x497b2805, 0x497b281c, 0x497b281d, 0x497b281f, 0x497b2820, 0x497b2822, - 0x497b2823, 0x80000580, 0x0201f800, 0x00101668, + 0x497b2823, 0x80000580, 0x0201f800, 0x001015fe, 0x59a80805, 0x8c081500, 0x04000004, 0x82040d40, 0x00000011, 0x0401f004, 0x8c081506, 0x04000002, 0x84040d42, 0x84040d0a, 0x48075005, 0x4202d800, 0x00000001, 0x82081500, 0x000000e0, 0x8008010a, - 0x0c020036, 0x0201f800, 0x00104e0d, 0x04020009, - 0x4a035033, 0x00000001, 0x0201f800, 0x00104d76, + 0x0c020036, 0x0201f800, 0x0010513b, 0x04020009, + 0x4a035033, 0x00000001, 0x0201f800, 0x001050a2, 0x0401f01f, 0x4a035033, 0x00000000, 0x0401f7fb, - 0x497b5032, 0x0201f800, 0x00103f5c, 0x0201f800, - 0x0010698c, 0x0201f800, 0x00106c32, 0x0201f800, - 0x00106982, 0x59a00a07, 0x480788a7, 0x59c400a3, + 0x497b5032, 0x0201f800, 0x00104142, 0x0201f800, + 0x00106c55, 0x0201f800, 0x00106ede, 0x0201f800, + 0x00106c4b, 0x59a00a07, 0x480788a7, 0x59c400a3, 0x82000500, 0xfeffffff, 0x82000540, 0x80018000, 0x40000800, 0x84040d20, 0x480388a3, 0x480788a3, 0x497b504e, 0x42000800, 0x0000002d, 0x42001000, - 0x00103fe4, 0x0201f800, 0x00105ca2, 0x59a00407, + 0x001041bc, 0x0201f800, 0x00105f69, 0x59a00407, 0x800000c2, 0x800008c4, 0x8005d400, 0x42000000, - 0x0000ffff, 0x0201f800, 0x00104e0d, 0x04000003, - 0x59a00207, 0x80000110, 0x0201f800, 0x00103915, - 0x0201f000, 0x00102066, 0x00103479, 0x0010347c, - 0x00103484, 0x001020b6, 0x00103481, 0x001020b6, - 0x001020b6, 0x001020b6, 0x836c0580, 0x00000003, + 0x0000ffff, 0x0201f800, 0x0010513b, 0x04000003, + 0x59a00207, 0x80000110, 0x0201f800, 0x00103afc, + 0x0201f000, 0x001022c0, 0x0010366d, 0x00103670, + 0x00103678, 0x00102310, 0x00103675, 0x00102310, + 0x00102310, 0x00102310, 0x836c0580, 0x00000003, 0x04000005, 0x4a034406, 0x00000007, 0x0201f000, - 0x001020b2, 0x59a03c06, 0x59a00407, 0x59a04a07, + 0x0010230c, 0x59a03c06, 0x59a00407, 0x59a04a07, 0x902449c0, 0x80244d40, 0x59a00409, 0x59a05209, - 0x902851c0, 0x80285540, 0x0401fb54, 0x04020005, - 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, + 0x902851c0, 0x80285540, 0x0401fb46, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x0010230c, 0x417a8800, 0x41783000, 0x497b4001, 0x497b4004, 0x832c4400, 0x00000005, 0x48234002, 0x8c1c3d04, - 0x04020078, 0x0201f800, 0x00020267, 0x0402002a, - 0x0201f800, 0x00104836, 0x04000004, 0x0201f800, - 0x00104732, 0x04020024, 0x8c1c3d00, 0x04000008, + 0x04020078, 0x0201f800, 0x00020245, 0x0402002a, + 0x0201f800, 0x001049e7, 0x04000004, 0x0201f800, + 0x001048e3, 0x04020024, 0x8c1c3d00, 0x04000008, 0x59340009, 0x44004000, 0x59340008, 0x80204000, 0x44004000, 0x80204000, 0x0401f007, 0x59340007, 0x44004000, 0x59340006, 0x80204000, 0x44004000, 0x80204000, 0x83440580, 0x000007fe, 0x0400000d, 0x83440580, 0x000007fc, 0x0400000a, 0x0201f800, - 0x00104842, 0x04000003, 0x85468d5e, 0x0401f005, - 0x0201f800, 0x00104686, 0x04020002, 0x85468d5e, + 0x001049f3, 0x04000003, 0x85468d5e, 0x0401f005, + 0x0201f800, 0x00104838, 0x04020002, 0x85468d5e, 0x45444000, 0x85468d1e, 0x80204000, 0x82183400, 0x00000003, 0x81468800, 0x83440480, 0x000007f0, 0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580, @@ -3438,27 +3563,27 @@ uint32_t risc_code01[] = { 0x42028800, 0x000007fc, 0x82180580, 0x0000000f, 0x0400000b, 0x0401f7c0, 0x801831c0, 0x04020006, 0x59a00801, 0x800408c4, 0x48074406, 0x0201f000, - 0x00102066, 0x4a034004, 0x00000001, 0x49474000, + 0x001022c0, 0x4a034004, 0x00000001, 0x49474000, 0x59a00001, 0x80180400, 0x48034001, 0x481f4003, 0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002, 0x4801d803, 0x4825d807, 0x4829d808, 0x4000a800, - 0x4000a000, 0x4018b000, 0x0201f800, 0x0010a93e, - 0x40ec1000, 0x0201f800, 0x001008a1, 0x4a01d809, - 0x00103536, 0x1c01f000, 0x4031d800, 0x58ef400b, + 0x4000a000, 0x4018b000, 0x0201f800, 0x0010ab17, + 0x40ec1000, 0x0201f800, 0x00100858, 0x4a01d809, + 0x0010372a, 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, - 0x001020aa, 0x59a00004, 0x80000540, 0x04020008, + 0x00102304, 0x59a00004, 0x80000540, 0x04020008, 0x59a28800, 0x59a04002, 0x59a03803, 0x41783000, 0x58ec4807, 0x58ec5008, 0x0401f78f, 0x59a00801, - 0x800408c4, 0x48074406, 0x0201f000, 0x00102066, - 0x0201f800, 0x00020267, 0x0402002f, 0x0201f800, - 0x00104836, 0x04000004, 0x0201f800, 0x00104732, + 0x800408c4, 0x48074406, 0x0201f000, 0x001022c0, + 0x0201f800, 0x00020245, 0x0402002f, 0x0201f800, + 0x001049e7, 0x04000004, 0x0201f800, 0x001048e3, 0x04020029, 0x83440580, 0x000007fe, 0x04000011, 0x83440580, 0x000007fc, 0x0400000e, 0x0201f800, - 0x00104842, 0x04000005, 0x59340403, 0x8400055e, - 0x48026c03, 0x0401f007, 0x0201f800, 0x00104686, + 0x001049f3, 0x04000005, 0x59340403, 0x8400055e, + 0x48026c03, 0x0401f007, 0x0201f800, 0x00104838, 0x04020004, 0x59340403, 0x8400055e, 0x48026c03, 0x4134a000, 0x4020a800, 0x4200b000, 0x00000006, - 0x0201f800, 0x0010a93e, 0x59340007, 0x4400a800, + 0x0201f800, 0x0010ab17, 0x59340007, 0x4400a800, 0x59340006, 0x4800a801, 0x59340009, 0x4800a802, 0x59340008, 0x4800a803, 0x59340403, 0x8400051e, 0x48026c03, 0x82204400, 0x0000000a, 0x82183400, @@ -3469,657 +3594,650 @@ uint32_t risc_code01[] = { 0x42028800, 0x000007fc, 0x82180580, 0x0000000a, 0x0400000b, 0x0401f7bb, 0x801831c0, 0x04020006, 0x59a00801, 0x800408c4, 0x48074406, 0x0201f000, - 0x00102066, 0x4a034004, 0x00000001, 0x49474000, + 0x001022c0, 0x4a034004, 0x00000001, 0x49474000, 0x59a00001, 0x80180400, 0x48034001, 0x481f4003, 0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002, 0x4801d803, 0x4825d807, 0x4829d808, 0x40ec1000, - 0x0201f800, 0x001008a1, 0x4a01d809, 0x001035ad, + 0x0201f800, 0x00100858, 0x4a01d809, 0x001037a1, 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002, - 0x82000580, 0x00000200, 0x02000000, 0x001020aa, + 0x82000580, 0x00000200, 0x02000000, 0x00102304, 0x59a00004, 0x80000540, 0x04020008, 0x59a28800, 0x59a04002, 0x59a03803, 0x41783000, 0x58ec4807, 0x58ec5008, 0x0401f78f, 0x59a00801, 0x800408c4, - 0x48074406, 0x0201f000, 0x00102066, 0x42002800, + 0x48074406, 0x0201f000, 0x001022c0, 0x42002800, 0x0000007e, 0x59a00c06, 0x59a01207, 0x59a01c07, 0x59a02209, 0x82040500, 0x0000ff00, 0x840001c0, - 0x82003480, 0x00000020, 0x02001000, 0x001020b6, - 0x80140480, 0x02001000, 0x001020b6, 0x82040500, + 0x82003480, 0x00000020, 0x02001000, 0x00102310, + 0x80140480, 0x02001000, 0x00102310, 0x82040500, 0x000000ff, 0x82003480, 0x00000020, 0x02001000, - 0x001020b6, 0x80140480, 0x02001000, 0x001020b6, + 0x00102310, 0x80140480, 0x02001000, 0x00102310, 0x82080500, 0x0000ff00, 0x840001c0, 0x82003480, - 0x00000020, 0x02001000, 0x001020b6, 0x80140480, - 0x02001000, 0x001020b6, 0x82080500, 0x000000ff, - 0x82003480, 0x00000020, 0x02001000, 0x001020b6, - 0x80140480, 0x02001000, 0x001020b6, 0x820c0500, + 0x00000020, 0x02001000, 0x00102310, 0x80140480, + 0x02001000, 0x00102310, 0x82080500, 0x000000ff, + 0x82003480, 0x00000020, 0x02001000, 0x00102310, + 0x80140480, 0x02001000, 0x00102310, 0x820c0500, 0x0000ff00, 0x840001c0, 0x82003480, 0x00000020, - 0x02001000, 0x001020b6, 0x80140480, 0x02001000, - 0x001020b6, 0x820c0500, 0x000000ff, 0x82003480, - 0x00000020, 0x02001000, 0x001020b6, 0x80140480, - 0x02001000, 0x001020b6, 0x82100500, 0x0000ff00, + 0x02001000, 0x00102310, 0x80140480, 0x02001000, + 0x00102310, 0x820c0500, 0x000000ff, 0x82003480, + 0x00000020, 0x02001000, 0x00102310, 0x80140480, + 0x02001000, 0x00102310, 0x82100500, 0x0000ff00, 0x840001c0, 0x82003480, 0x00000020, 0x02001000, - 0x001020b6, 0x80140480, 0x02001000, 0x001020b6, + 0x00102310, 0x80140480, 0x02001000, 0x00102310, 0x82100500, 0x000000ff, 0x82003480, 0x00000020, - 0x02001000, 0x001020b6, 0x80140480, 0x02001000, - 0x001020b6, 0x900401c0, 0x80080d40, 0x900c01c0, + 0x02001000, 0x00102310, 0x80140480, 0x02001000, + 0x00102310, 0x900401c0, 0x80080d40, 0x900c01c0, 0x80101d40, 0x83a83400, 0x0000003a, 0x44043000, - 0x80183000, 0x440c3000, 0x0201f000, 0x00102066, - 0x0401f9fa, 0x04020005, 0x4a034406, 0x00000002, - 0x0201f000, 0x001020b2, 0x42000800, 0x0000000c, - 0x0401f853, 0x4a01d809, 0x0010362c, 0x1c01f000, + 0x80183000, 0x440c3000, 0x0201f000, 0x001022c0, + 0x0401f9ec, 0x04020005, 0x4a034406, 0x00000002, + 0x0201f000, 0x0010230c, 0x42000800, 0x0000000c, + 0x0401f853, 0x4a01d809, 0x00103820, 0x1c01f000, 0x4031d800, 0x58ee580d, 0x58ef400b, 0x58ec0002, - 0x82000580, 0x00000200, 0x02000000, 0x001020aa, + 0x82000580, 0x00000200, 0x02000000, 0x00102304, 0x832ca400, 0x00000004, 0x4200b000, 0x0000000c, - 0x40c8a800, 0x0201f800, 0x0010a93e, 0x58c80200, + 0x40c8a800, 0x0201f800, 0x0010ab17, 0x58c80200, 0x80000540, 0x04000034, 0x58c80400, 0x82000500, 0xfffffffb, 0x04020030, 0x58c80401, 0x80000540, 0x0400002d, 0x82000480, 0x0000ff01, 0x0402102a, 0x58c80202, 0x82000480, 0x0000005c, 0x04001026, - 0x0201f800, 0x001060db, 0x58c80c08, 0x58c80204, + 0x0201f800, 0x001063a3, 0x58c80c08, 0x58c80204, 0x80040480, 0x04001020, 0x58c80204, 0x82000480, 0x00000005, 0x0402101c, 0x58c80205, 0x58c80c08, 0x80040902, 0x80040480, 0x04001017, 0x58c80c08, - 0x0201f800, 0x0010602a, 0x0400001b, 0x0201f800, - 0x00105ef2, 0x04020012, 0x4979940b, 0x59c408a3, + 0x0201f800, 0x001062f1, 0x0400001b, 0x0201f800, + 0x001061b9, 0x04020012, 0x4979940b, 0x59c408a3, 0x82040d40, 0x00000002, 0x480788a3, 0x4a038830, 0x00000001, 0x4a038832, 0x01ffffff, 0x58c80202, - 0x48030804, 0x0201f800, 0x00105ed4, 0x0201f000, - 0x00102066, 0x0201f000, 0x001020b6, 0x0201f800, - 0x0010612d, 0x0201f800, 0x0010613a, 0x0201f800, - 0x0010601d, 0x0201f000, 0x001020b2, 0x4c000000, + 0x48030804, 0x0201f800, 0x0010619b, 0x0201f000, + 0x001022c0, 0x0201f000, 0x00102310, 0x0201f800, + 0x001063f5, 0x0201f800, 0x00106402, 0x0201f800, + 0x001062e4, 0x0201f000, 0x0010230c, 0x4c000000, 0x59a01207, 0x59a00407, 0x900811c0, 0x80081540, 0x59a01a09, 0x59a00409, 0x900c19c0, 0x800c1d40, - 0x5c000000, 0x0401f1b9, 0x59840000, 0x82000580, - 0x00000000, 0x04000050, 0x59840002, 0x8c000504, - 0x0400004d, 0x84000546, 0x48030802, 0x0201f800, - 0x0010601d, 0x59c408a3, 0x82040d00, 0xfffffffd, - 0x480788a3, 0x4c5c0000, 0x4200b800, 0x0010aa00, + 0x5c000000, 0x0401f1ac, 0x59840000, 0x82000580, + 0x00000000, 0x04000054, 0x59840002, 0x8c000504, + 0x04000051, 0x84000546, 0x48030802, 0x0201f800, + 0x001062e4, 0x59c408a3, 0x82040d00, 0xfffffffd, + 0x480788a3, 0x4c5c0000, 0x4200b800, 0x0010ac00, 0x505e6800, 0x813669c0, 0x04000008, 0x5936600e, - 0x813261c0, 0x04000005, 0x0201f800, 0x0010600e, - 0x02000800, 0x001061e5, 0x805cb800, 0x825c0580, - 0x0010b1f0, 0x040207f3, 0x59866003, 0x813261c0, + 0x813261c0, 0x04000005, 0x0201f800, 0x001062d5, + 0x02000800, 0x001064ad, 0x805cb800, 0x825c0580, + 0x0010b3f0, 0x040207f3, 0x59866003, 0x813261c0, 0x0400000b, 0x59300406, 0x82000580, 0x00000009, - 0x02020800, 0x00100615, 0x5930b800, 0x0201f800, - 0x00105ffa, 0x405e6000, 0x0401f7f5, 0x497b0803, - 0x4200b800, 0x0010b317, 0x505e6000, 0x813261c0, + 0x02020800, 0x001005d8, 0x5930b800, 0x0201f800, + 0x001062c1, 0x405e6000, 0x0401f7f5, 0x497b0803, + 0x4200b800, 0x0010b51b, 0x505e6000, 0x813261c0, 0x04000011, 0x59300406, 0x82000580, 0x00000009, 0x0402000d, 0x59300203, 0x82000580, 0x00000004, 0x04020009, 0x59326809, 0x813669c0, 0x02020800, - 0x00100615, 0x0201f800, 0x00100ee4, 0x0201f800, - 0x00105ffa, 0x4578b800, 0x805cb800, 0x825c0580, - 0x0010b31f, 0x040207e9, 0x42000800, 0x0010b315, - 0x49780801, 0x49780800, 0x0201f800, 0x0010612d, - 0x0201f800, 0x0010613a, 0x5c00b800, 0x0201f800, - 0x00105eed, 0x0201f000, 0x00102066, 0x836c0580, + 0x001005d8, 0x0201f800, 0x00100e99, 0x0201f800, + 0x001062c1, 0x4578b800, 0x805cb800, 0x825c0580, + 0x0010b523, 0x040207e9, 0x42000800, 0x0010b519, + 0x49780801, 0x49780800, 0x59a80069, 0x82000400, + 0x00000007, 0x48035069, 0x0201f800, 0x001063f5, + 0x0201f800, 0x00106402, 0x5c00b800, 0x0201f800, + 0x001061b4, 0x0201f000, 0x001022c0, 0x836c0580, 0x00000003, 0x04000005, 0x4a034406, 0x00000007, - 0x0201f000, 0x001020b2, 0x59a00407, 0x59a02207, + 0x0201f000, 0x0010230c, 0x59a00407, 0x59a02207, 0x901021c0, 0x80102540, 0x59a00409, 0x59a02a09, - 0x901429c0, 0x80142d40, 0x0401f930, 0x04020005, - 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, + 0x901429c0, 0x80142d40, 0x0401f91e, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x0010230c, 0x417a8800, 0x41781800, 0x497b4001, 0x497b4003, 0x832c3400, 0x00000004, 0x481b4002, 0x41440000, 0x81ac0400, 0x50026800, 0x813669c0, 0x0400000b, - 0x0201f800, 0x00104836, 0x04020008, 0x59340002, + 0x0201f800, 0x001049e7, 0x04020008, 0x59340002, 0x48003000, 0x49443001, 0x82183400, 0x00000002, 0x820c1c00, 0x00000002, 0x81468800, 0x83440480, 0x00000800, 0x04000005, 0x820c0480, 0x00000010, 0x0402100b, 0x0401f7ea, 0x800c19c0, 0x04020006, 0x59a00801, 0x80040902, 0x48074406, 0x0201f000, - 0x00102066, 0x4a034003, 0x00000001, 0x49474000, + 0x001022c0, 0x4a034003, 0x00000001, 0x49474000, 0x59a00001, 0x800c0400, 0x48034001, 0x40ec1000, 0x4a001001, 0x00000000, 0x480c1004, 0x59a00002, 0x48001003, 0x48101007, 0x48141008, 0x0201f800, - 0x001008a1, 0x4a01d809, 0x00103728, 0x1c01f000, + 0x00100858, 0x4a01d809, 0x00103920, 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, - 0x00000200, 0x02000000, 0x001020aa, 0x59a00003, + 0x00000200, 0x02000000, 0x00102304, 0x59a00003, 0x80000540, 0x04020008, 0x59a28800, 0x59a03002, 0x41781800, 0x40ec1000, 0x58082007, 0x58082808, 0x0401f7bf, 0x59a00801, 0x80040902, 0x48074406, - 0x0201f000, 0x00102066, 0x800409c0, 0x04000005, - 0x4a034406, 0x00000001, 0x0201f000, 0x001020b2, + 0x0201f000, 0x001022c0, 0x800409c0, 0x04000005, + 0x4a034406, 0x00000001, 0x0201f000, 0x0010230c, 0x59a80026, 0x8c00050a, 0x04020007, 0x8c000506, 0x04020005, 0x4a034406, 0x00000016, 0x0201f000, - 0x001020b2, 0x0401f8cd, 0x04020005, 0x4a034406, - 0x00000002, 0x0201f000, 0x001020b2, 0x59a00c06, + 0x0010230c, 0x0401f8bb, 0x04020005, 0x4a034406, + 0x00000002, 0x0201f000, 0x0010230c, 0x59a00c06, 0x80040902, 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, - 0x800c1d40, 0x832c0400, 0x00000005, 0x0401f8df, - 0x4a01d809, 0x00103763, 0x1c01f000, 0x4031d800, + 0x800c1d40, 0x832c0400, 0x00000005, 0x0401f8ce, + 0x4a01d809, 0x0010395b, 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, - 0x00000200, 0x02000000, 0x001020aa, 0x592c0009, - 0x0201f800, 0x001059b9, 0x02000800, 0x001043fc, - 0x02020000, 0x001020b6, 0x49474001, 0x481a6802, + 0x00000200, 0x02000000, 0x00102304, 0x592c0009, + 0x0201f800, 0x00105c9a, 0x02000800, 0x001045a6, + 0x02020000, 0x00102310, 0x49474001, 0x481a6802, 0x592c000a, 0x82001d80, 0x70000000, 0x04020007, - 0x0401f8a2, 0x04020011, 0x4a034406, 0x00000002, - 0x0201f000, 0x001020b2, 0x82001d80, 0x72000000, - 0x02020000, 0x001020b6, 0x0401f898, 0x04020897, - 0x04020896, 0x04020005, 0x4a034406, 0x00000002, - 0x0201f000, 0x001020b2, 0x58ee580d, 0x4a025c04, + 0x0401f890, 0x04020011, 0x4a034406, 0x00000002, + 0x0201f000, 0x0010230c, 0x82001d80, 0x72000000, + 0x02020000, 0x00102310, 0x0401f886, 0x04020885, + 0x04020884, 0x04020005, 0x4a034406, 0x00000002, + 0x0201f000, 0x0010230c, 0x58ee580d, 0x4a025c04, 0x00008000, 0x497a5a04, 0x592c3208, 0x80183102, 0x592c1801, 0x4a001805, 0x01000000, 0x0201f800, - 0x00108e8e, 0x04020005, 0x4a034406, 0x00000003, - 0x0201f000, 0x001020b2, 0x4a01d809, 0x0010379d, + 0x001090d1, 0x04020005, 0x4a034406, 0x00000003, + 0x0201f000, 0x0010230c, 0x4a01d809, 0x00103995, 0x1c01f000, 0x592c4000, 0x592c0005, 0x82000580, 0x01000000, 0x04020005, 0x4a034406, 0x00000004, - 0x0201f000, 0x001020b2, 0x4c580000, 0x4c500000, - 0x4c540000, 0x832c3c00, 0x00000005, 0x401ca000, - 0x401ca800, 0x5820280a, 0x4200b000, 0x00000002, - 0x82143580, 0x70000000, 0x04000003, 0x4200b000, - 0x0000000f, 0x0201f800, 0x0010a94f, 0x5c00a800, - 0x5c00a000, 0x5c00b000, 0x401c0000, 0x58201006, - 0x58201807, 0x58202205, 0x80102102, 0x82143580, - 0x70000000, 0x04020008, 0x82103480, 0x00000002, - 0x02001000, 0x001020b6, 0x42000800, 0x00000002, - 0x0401f079, 0x82143580, 0x72000000, 0x02020000, - 0x001020b6, 0x82103480, 0x0000002a, 0x02001000, - 0x001020b6, 0x42000800, 0x0000000f, 0x0401f86e, - 0x4a01d809, 0x001037d7, 0x1c01f000, 0x4031d800, - 0x58ef400b, 0x58ee580e, 0x58ec0002, 0x82000580, - 0x00000200, 0x02000000, 0x001020aa, 0x592e5800, - 0x832c0c00, 0x00000005, 0x4c580000, 0x4c500000, - 0x4c540000, 0x4004a000, 0x4004a800, 0x4200b000, - 0x0000000f, 0x0201f800, 0x0010a94f, 0x5c00a800, - 0x5c00a000, 0x5c00b000, 0x40ec1000, 0x4a001001, + 0x0201f000, 0x0010230c, 0x832c3c00, 0x00000005, + 0x401ca000, 0x401ca800, 0x5820280a, 0x4200b000, + 0x00000002, 0x82143580, 0x70000000, 0x04000003, + 0x4200b000, 0x0000000f, 0x0201f800, 0x0010ab28, + 0x401c0000, 0x58201006, 0x58201807, 0x58202205, + 0x80102102, 0x82143580, 0x70000000, 0x04020008, + 0x82103480, 0x00000002, 0x02001000, 0x00102310, + 0x42000800, 0x00000002, 0x0401f06e, 0x82143580, + 0x72000000, 0x02020000, 0x00102310, 0x82103480, + 0x0000002a, 0x02001000, 0x00102310, 0x42000800, + 0x0000000f, 0x0401f863, 0x4a01d809, 0x001039c9, + 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e, + 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, + 0x00102304, 0x592e5800, 0x832c0c00, 0x00000005, + 0x4004a000, 0x4004a800, 0x4200b000, 0x0000000f, + 0x0201f800, 0x0010ab28, 0x40ec1000, 0x4a001001, 0x00000000, 0x4a001004, 0x0000000f, 0x48041003, - 0x0201f800, 0x001008a1, 0x4a01d809, 0x001037f9, + 0x0201f800, 0x00100858, 0x4a01d809, 0x001039e5, 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e, 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, - 0x001020aa, 0x832c0c00, 0x00000005, 0x4c580000, - 0x4c500000, 0x4c540000, 0x4004a000, 0x4004a800, - 0x4200b000, 0x0000000c, 0x0201f800, 0x0010a94f, - 0x5c00a800, 0x5c00a000, 0x5c00b000, 0x40ec1000, - 0x4a001001, 0x00000000, 0x4a001004, 0x0000000c, - 0x48041003, 0x0201f800, 0x001008a1, 0x4a01d809, - 0x0010205f, 0x1c01f000, 0x0201f800, 0x0010082a, - 0x04000010, 0x497a5800, 0x58ec000d, 0x80000540, - 0x04020004, 0x492dd80d, 0x492dd80e, 0x0401f007, - 0x58ec000e, 0x48025800, 0x82000400, 0x00000001, - 0x452c0000, 0x492dd80e, 0x832c0400, 0x00000004, - 0x492fc857, 0x4803c857, 0x1c01f000, 0x4d2c0000, - 0x58ec400d, 0x802041c0, 0x04000008, 0x4823c857, - 0x40225800, 0x592c4001, 0x497a5801, 0x0201f800, - 0x0010083a, 0x0401f7f8, 0x4979d80d, 0x4979d80e, - 0x5c025800, 0x1c01f000, 0x42003000, 0x00000001, - 0x0401f003, 0x42003000, 0x00000000, 0x4803c857, - 0x4807c857, 0x480bc857, 0x480fc857, 0x481bc857, - 0x48efc857, 0x4819d801, 0x800409c0, 0x02000800, - 0x00100615, 0x4805d804, 0x4801d803, 0x4809d807, - 0x480dd808, 0x40ec1000, 0x0201f800, 0x001008a1, - 0x4a01d809, 0x0010205f, 0x1c01f000, 0x80002d80, - 0x480bc857, 0x480fc857, 0x4813c857, 0x4817c857, - 0x4d2c0000, 0x4da00000, 0x42034000, 0x0010b2a0, - 0x59a00017, 0x800001c0, 0x04020013, 0x04006012, - 0x480bc020, 0x480fc021, 0x4813c022, 0x4817c023, - 0x900811c0, 0x82081540, 0x00000012, 0x480bc011, - 0x59e00017, 0x8c000508, 0x04020004, 0x4203e000, - 0x30000001, 0x0401f053, 0x4a03c017, 0x00000002, - 0x0401f7fb, 0x4c040000, 0x4c1c0000, 0x80000800, - 0x48074017, 0x59a0381a, 0x481fc857, 0x801c39c0, - 0x04020027, 0x82000480, 0x0000000a, 0x04021010, - 0x59a00018, 0x80000000, 0x48034018, 0x59a00219, - 0x82000400, 0x00000002, 0x82000c80, 0x00000013, - 0x48034219, 0x04001003, 0x497b4219, 0x41780000, - 0x59a03816, 0x801c3c00, 0x0401f030, 0x4803c856, - 0x0201f800, 0x0010082a, 0x04000007, 0x492f401a, - 0x492f401b, 0x412c3800, 0x497b421c, 0x497a5813, - 0x0401f026, 0x59880052, 0x80000000, 0x48031052, - 0x59a00017, 0x80000040, 0x48034017, 0x59a00219, - 0x59a03816, 0x801c3c00, 0x0401f01c, 0x59a0021c, - 0x82000400, 0x00000002, 0x82000c80, 0x00000012, - 0x04021004, 0x4803421c, 0x801c3c00, 0x0401f013, - 0x0201f800, 0x0010082a, 0x0402000b, 0x59880052, - 0x80000000, 0x48031052, 0x59a00017, 0x80000040, - 0x48034017, 0x4803c856, 0x59a0021c, 0x801c3c00, - 0x0401f006, 0x492f401a, 0x492c3813, 0x412c3800, - 0x497b421c, 0x497a5813, 0x48083c00, 0x480c3a00, - 0x48103c01, 0x48143a01, 0x5c003800, 0x5c000800, - 0x5c034000, 0x5c025800, 0x1c01f000, 0x480fc857, - 0x4813c857, 0x481bc857, 0x42000000, 0x0010b611, - 0x0201f800, 0x0010a86e, 0x801800d0, 0x40002800, - 0x42001000, 0x00008014, 0x0401f786, 0x4c000000, - 0x599c0017, 0x8c000512, 0x5c000000, 0x1c01f000, - 0x4c000000, 0x599c0018, 0x8c00050e, 0x5c000000, - 0x1c01f000, 0x59a80821, 0x800409c0, 0x04000005, - 0x4a034406, 0x00000001, 0x0201f000, 0x001020b2, - 0x836c0580, 0x00000003, 0x04000005, 0x4a034406, - 0x00000007, 0x0201f000, 0x001020b2, 0x599c0017, - 0x8c00050a, 0x04000005, 0x4a034406, 0x00000008, - 0x0201f000, 0x001020b2, 0x59340405, 0x8c000508, - 0x04020004, 0x8c00050a, 0x02020000, 0x001032e2, - 0x497a5a04, 0x497a5805, 0x4a025c04, 0x00008000, - 0x0201f800, 0x00108f2d, 0x04020005, 0x4a034406, - 0x00000003, 0x0201f000, 0x001020b2, 0x4a01d809, - 0x00103906, 0x1c01f000, 0x592c0005, 0x82000580, - 0x01000000, 0x04020005, 0x4a034406, 0x00000004, - 0x0201f000, 0x001020b2, 0x59a28c06, 0x0201f800, - 0x00020267, 0x02020000, 0x001020b6, 0x0201f000, - 0x001032e2, 0x82001580, 0x0000ffff, 0x04000009, - 0x0201f800, 0x001059b9, 0x02000800, 0x00020267, - 0x0402000c, 0x0201f800, 0x00105ce7, 0x0401f009, - 0x42028800, 0x000007ef, 0x0201f800, 0x00020267, - 0x02000800, 0x00105ce7, 0x81468840, 0x040217fb, - 0x1c01f000, 0x4803c856, 0x4c0c0000, 0x4d340000, - 0x4d440000, 0x42028800, 0x000007fe, 0x0201f800, - 0x00020267, 0x04020009, 0x5934180a, 0x820c1d00, - 0x00000001, 0x820c1d80, 0x00000001, 0x42001000, - 0x0000801b, 0x0401ff1e, 0x5c028800, 0x5c026800, - 0x5c001800, 0x1c01f000, 0x599c0017, 0x8c000508, - 0x1c01f000, 0x48efc857, 0x04011000, 0x48efc840, - 0x4a03c842, 0x00000011, 0x40000000, 0x040117ff, - 0x4a01d80f, 0xbeefbeef, 0x1c01f000, 0x497b4000, - 0x497b4001, 0x497b4002, 0x497b4003, 0x497b4004, - 0x1c01f000, 0x59c400a4, 0x4c580000, 0x4c500000, - 0x4c540000, 0x82000500, 0x0000000f, 0x82000480, - 0x00000007, 0x0400100a, 0x82006c80, 0x00000007, - 0x02021800, 0x00100615, 0x0c01f807, 0x5c00a800, - 0x5c00a000, 0x5c00b000, 0x1c01f000, 0x0401f90c, - 0x0401f7fb, 0x0010396c, 0x00103972, 0x00103997, - 0x001039b9, 0x00103a78, 0x0010396b, 0x1c01f000, - 0x59c40806, 0x8c040d00, 0x04020003, 0x84040d40, - 0x48078806, 0x1c01f000, 0x59c40005, 0x8c000534, - 0x02020000, 0x001040ce, 0x4a038805, 0xffffffff, - 0x42006000, 0x00020000, 0x0201f800, 0x001040b2, - 0x59a80015, 0x82000500, 0xfffffffa, 0x84000542, - 0x48035015, 0x497b5026, 0x42000800, 0x0010bc20, - 0x45780800, 0x497b5013, 0x42006000, 0xffefffff, - 0x42006800, 0x40000000, 0x0201f800, 0x001040ad, - 0x59c40006, 0x82000500, 0xffffff0f, 0x48038806, - 0x42000800, 0x00000010, 0x42001000, 0x0010401b, - 0x0201f800, 0x00105cbc, 0x0401f001, 0x42006000, - 0xffffffff, 0x42006800, 0x00800000, 0x0201f800, - 0x001040ad, 0x4200b000, 0x000000c8, 0x59c400a4, - 0x82000500, 0x0000000f, 0x82000580, 0x0000000a, - 0x0400000f, 0x8058b040, 0x040207f9, 0x497b5014, - 0x42006000, 0xbf7fffff, 0x42006800, 0x00018000, - 0x0201f800, 0x001040ad, 0x42006000, 0xfffeffff, - 0x41786800, 0x0201f000, 0x001040ad, 0x497b5014, - 0x4a035012, 0x00000000, 0x80000580, 0x0201f000, - 0x001040b9, 0x4a038805, 0xffffffff, 0x59a80012, - 0x82000c80, 0x00000004, 0x02021800, 0x00100615, - 0x0c01f001, 0x001039c4, 0x001039f1, 0x00103a6e, - 0x4803c856, 0x59c400a3, 0x8400051e, 0x480388a3, - 0x4a035012, 0x00000001, 0x59c40008, 0x8400054e, - 0x48038808, 0x0201f800, 0x00104093, 0x42007800, - 0x0010b34a, 0x4a007806, 0x11010000, 0x4200a000, - 0x0010b202, 0x4200a800, 0x0010b351, 0x4200b000, - 0x00000002, 0x0201f800, 0x0010a93e, 0x497b8802, - 0x42000800, 0x00000003, 0x497b504a, 0x0201f800, - 0x00103f8e, 0x4a03504a, 0x00000001, 0x497b5016, - 0x0201f800, 0x001040c0, 0x42006000, 0xffffffff, - 0x42006800, 0x00080000, 0x0201f800, 0x001040ad, - 0x42006000, 0xfff7ffff, 0x41786800, 0x0201f000, - 0x001040ad, 0x59a80016, 0x497b5016, 0x80002540, - 0x0400006a, 0x59c40004, 0x82000500, 0x00000003, - 0x04020075, 0x59a80815, 0x8c040d02, 0x0400004f, - 0x82100580, 0x0000000c, 0x04020053, 0x82100400, - 0x00000018, 0x8000b104, 0x41cc1000, 0x42001800, - 0x0010b34a, 0x50080800, 0x500c0000, 0x80040580, - 0x0402001e, 0x80081000, 0x800c1800, 0x8058b040, - 0x040207f9, 0x0201f800, 0x001040c0, 0x42006000, - 0xffffffff, 0x42006800, 0x00500000, 0x0201f800, - 0x001040ad, 0x4a035012, 0x00000002, 0x4a035014, - 0x00000002, 0x0201f800, 0x0010164b, 0x42000800, - 0x000007d0, 0x42001000, 0x00103f62, 0x0201f800, - 0x00105da7, 0x59a80015, 0x84000506, 0x48035015, - 0x0201f000, 0x00104093, 0x59cc0806, 0x82040d80, - 0x11010000, 0x04020028, 0x59cc0800, 0x82040500, - 0x00ffffff, 0x0400001a, 0x82000580, 0x000000ef, - 0x04020017, 0x59cc0801, 0x82040500, 0x00ffffff, - 0x82000580, 0x000000ef, 0x04020011, 0x83cca400, - 0x00000007, 0x4200a800, 0x0010b202, 0x4200b000, - 0x00000002, 0x50500800, 0x50540000, 0x80040480, - 0x04001007, 0x04020010, 0x8050a000, 0x8054a800, - 0x8058b040, 0x040207f8, 0x0401f00b, 0x59a80015, - 0x84000502, 0x48035015, 0x41cca000, 0x4200a800, - 0x0010b34a, 0x4200b000, 0x00000009, 0x0201f800, - 0x0010a93e, 0x0201f800, 0x001040c0, 0x42006000, + 0x00102304, 0x832c0c00, 0x00000005, 0x4004a000, + 0x4004a800, 0x4200b000, 0x0000000c, 0x0201f800, + 0x0010ab28, 0x40ec1000, 0x4a001001, 0x00000000, + 0x4a001004, 0x0000000c, 0x48041003, 0x0201f800, + 0x00100858, 0x4a01d809, 0x001022b9, 0x1c01f000, + 0x0201f800, 0x001007e4, 0x04000010, 0x497a5800, + 0x58ec000d, 0x80000540, 0x04020004, 0x492dd80d, + 0x492dd80e, 0x0401f007, 0x58ec000e, 0x48025800, + 0x82000400, 0x00000001, 0x452c0000, 0x492dd80e, + 0x832c0400, 0x00000004, 0x492fc857, 0x4803c857, + 0x1c01f000, 0x4d2c0000, 0x48efc857, 0x58ec400d, + 0x4823c857, 0x802041c0, 0x04000007, 0x40225800, + 0x592c4001, 0x497a5801, 0x0201f800, 0x001007f4, + 0x0401f7f8, 0x4979d80d, 0x4979d80e, 0x5c025800, + 0x1c01f000, 0x42003000, 0x00000001, 0x0401f003, + 0x42003000, 0x00000000, 0x4803c857, 0x4807c857, + 0x480bc857, 0x480fc857, 0x481bc857, 0x48efc857, + 0x4819d801, 0x800409c0, 0x02000800, 0x001005d8, + 0x4805d804, 0x4801d803, 0x4809d807, 0x480dd808, + 0x40ec1000, 0x0201f800, 0x00100858, 0x4a01d809, + 0x001022b9, 0x1c01f000, 0x80002d80, 0x480bc857, + 0x480fc857, 0x4813c857, 0x4817c857, 0x4d2c0000, + 0x4da00000, 0x42034000, 0x0010b4a4, 0x59a00017, + 0x800001c0, 0x04020013, 0x04006012, 0x480bc020, + 0x480fc021, 0x4813c022, 0x4817c023, 0x900811c0, + 0x82081540, 0x00000012, 0x480bc011, 0x59e00017, + 0x8c000508, 0x04020004, 0x4203e000, 0x30000001, + 0x0401f053, 0x4a03c017, 0x00000002, 0x0401f7fb, + 0x4c040000, 0x4c1c0000, 0x80000800, 0x48074017, + 0x59a0381a, 0x481fc857, 0x801c39c0, 0x04020027, + 0x82000480, 0x0000000a, 0x04021010, 0x59a00018, + 0x80000000, 0x48034018, 0x59a00219, 0x82000400, + 0x00000002, 0x82000c80, 0x00000013, 0x48034219, + 0x04001003, 0x497b4219, 0x41780000, 0x59a03816, + 0x801c3c00, 0x0401f030, 0x4803c856, 0x0201f800, + 0x001007e4, 0x04000007, 0x492f401a, 0x492f401b, + 0x412c3800, 0x497b421c, 0x497a5813, 0x0401f026, + 0x59880051, 0x80000000, 0x48031051, 0x59a00017, + 0x80000040, 0x48034017, 0x59a00219, 0x59a03816, + 0x801c3c00, 0x0401f01c, 0x59a0021c, 0x82000400, + 0x00000002, 0x82000c80, 0x00000012, 0x04021004, + 0x4803421c, 0x801c3c00, 0x0401f013, 0x0201f800, + 0x001007e4, 0x0402000b, 0x59880051, 0x80000000, + 0x48031051, 0x59a00017, 0x80000040, 0x48034017, + 0x4803c856, 0x59a0021c, 0x801c3c00, 0x0401f006, + 0x492f401a, 0x492c3813, 0x412c3800, 0x497b421c, + 0x497a5813, 0x48083c00, 0x480c3a00, 0x48103c01, + 0x48143a01, 0x5c003800, 0x5c000800, 0x5c034000, + 0x5c025800, 0x1c01f000, 0x480fc857, 0x4813c857, + 0x481bc857, 0x42000000, 0x0010b813, 0x0201f800, + 0x0010aa47, 0x801800d0, 0x40002800, 0x42001000, + 0x00008014, 0x0401f786, 0x4c000000, 0x599c0017, + 0x8c000512, 0x5c000000, 0x1c01f000, 0x4c000000, + 0x599c0018, 0x8c00050e, 0x5c000000, 0x1c01f000, + 0x59a80821, 0x800409c0, 0x04000005, 0x4a034406, + 0x00000001, 0x0201f000, 0x0010230c, 0x836c0580, + 0x00000003, 0x04000005, 0x4a034406, 0x00000007, + 0x0201f000, 0x0010230c, 0x599c0017, 0x8c00050a, + 0x04000005, 0x4a034406, 0x00000008, 0x0201f000, + 0x0010230c, 0x59340405, 0x8c000508, 0x04020004, + 0x8c00050a, 0x02020000, 0x001034db, 0x497a5a04, + 0x497a5805, 0x4a025c04, 0x00008000, 0x0201f800, + 0x00109176, 0x04020005, 0x4a034406, 0x00000003, + 0x0201f000, 0x0010230c, 0x4a01d809, 0x00103aed, + 0x1c01f000, 0x592c0005, 0x82000580, 0x01000000, + 0x04020005, 0x4a034406, 0x00000004, 0x0201f000, + 0x0010230c, 0x59a28c06, 0x0201f800, 0x00020245, + 0x02020000, 0x00102310, 0x0201f000, 0x001034db, + 0x82001580, 0x0000ffff, 0x04000009, 0x0201f800, + 0x00105c9a, 0x02000800, 0x00020245, 0x0402000c, + 0x0201f800, 0x00105fae, 0x0401f009, 0x42028800, + 0x000007ef, 0x0201f800, 0x00020245, 0x02000800, + 0x00105fae, 0x81468840, 0x040217fb, 0x1c01f000, + 0x4803c856, 0x4c0c0000, 0x4d340000, 0x4d440000, + 0x42028800, 0x000007fe, 0x0201f800, 0x00020245, + 0x04020009, 0x5934180a, 0x820c1d00, 0x00000001, + 0x820c1d80, 0x00000001, 0x42001000, 0x0000801b, + 0x0401ff1e, 0x5c028800, 0x5c026800, 0x5c001800, + 0x1c01f000, 0x599c0017, 0x8c000508, 0x1c01f000, + 0x48efc857, 0x04011000, 0x48efc840, 0x4a03c842, + 0x00000011, 0x40000000, 0x040117ff, 0x4a01d80f, + 0xbeefbeef, 0x1c01f000, 0x497b4000, 0x497b4001, + 0x497b4002, 0x497b4003, 0x497b4004, 0x1c01f000, + 0x59c400a4, 0x4c580000, 0x4c500000, 0x4c540000, + 0x82000500, 0x0000000f, 0x82000480, 0x00000007, + 0x0400100a, 0x82006c80, 0x00000006, 0x02021800, + 0x001005d8, 0x0c01f807, 0x5c00a800, 0x5c00a000, + 0x5c00b000, 0x1c01f000, 0x0401f906, 0x0401f7fb, + 0x00103b51, 0x00103b57, 0x00103b7c, 0x00103b9e, + 0x00103c59, 0x59c40806, 0x8c040d00, 0x04020003, + 0x84040d40, 0x48078806, 0x1c01f000, 0x59c40005, + 0x8c000534, 0x02020000, 0x0010429e, 0x4a038805, + 0xffffffff, 0x42006000, 0x00020000, 0x0201f800, + 0x00104282, 0x59a80015, 0x82000500, 0xfffffffa, + 0x84000542, 0x48035015, 0x497b5026, 0x42000800, + 0x0010be21, 0x45780800, 0x497b5013, 0x42006000, + 0xffefffff, 0x42006800, 0x40000000, 0x0201f800, + 0x0010427d, 0x59c40006, 0x82000500, 0xffffff0f, + 0x48038806, 0x42000800, 0x00000010, 0x42001000, + 0x001041f3, 0x0201f800, 0x00105f83, 0x0401f001, + 0x42006000, 0xffffffff, 0x42006800, 0x00800000, + 0x0201f800, 0x0010427d, 0x4200b000, 0x000000c8, + 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, + 0x0000000a, 0x0400000f, 0x8058b040, 0x040207f9, + 0x497b5014, 0x42006000, 0xbf7fffff, 0x42006800, + 0x00018000, 0x0201f800, 0x0010427d, 0x42006000, + 0xfffeffff, 0x41786800, 0x0201f000, 0x0010427d, + 0x497b5014, 0x4a035012, 0x00000000, 0x80000580, + 0x0201f000, 0x00104289, 0x4a038805, 0xffffffff, + 0x59a80012, 0x82000c80, 0x00000004, 0x02021800, + 0x001005d8, 0x0c01f001, 0x00103ba9, 0x00103bd6, + 0x00103c4f, 0x4803c856, 0x59c400a3, 0x8400051e, + 0x480388a3, 0x4a035012, 0x00000001, 0x59c40008, + 0x8400054e, 0x48038808, 0x0201f800, 0x00104263, + 0x42007800, 0x0010b54c, 0x4a007806, 0x11010000, + 0x4200a000, 0x0010b402, 0x4200a800, 0x0010b553, + 0x4200b000, 0x00000002, 0x0201f800, 0x0010ab17, + 0x497b8802, 0x42000800, 0x00000003, 0x497b504a, + 0x0201f800, 0x0010416e, 0x4a03504a, 0x00000001, + 0x497b5016, 0x0201f800, 0x00104290, 0x42006000, 0xffffffff, 0x42006800, 0x00080000, 0x0201f800, - 0x001040ad, 0x42006000, 0xfff7ffff, 0x41786800, - 0x0201f800, 0x001040ad, 0x42006000, 0xffffffff, - 0x42006800, 0x00004000, 0x0201f800, 0x001040ad, - 0x59c40004, 0x82000500, 0x00000003, 0x04020006, - 0x497b5016, 0x42000800, 0x00000003, 0x0201f000, - 0x00103f8e, 0x1c01f000, 0x1c01f000, 0x59a80014, - 0x82006d80, 0x0000000f, 0x04000005, 0x82000580, - 0x0000001b, 0x02020800, 0x00103f53, 0x1c01f000, - 0x59a80015, 0x84000506, 0x48035015, 0x497b504a, - 0x59a80014, 0x82000c80, 0x0000001e, 0x02021800, - 0x00100615, 0x0c01f001, 0x00103ab6, 0x00103acd, - 0x00103af6, 0x00103b11, 0x00103b34, 0x00103b65, - 0x00103b87, 0x00103bba, 0x00103bdc, 0x00103c00, - 0x00103c3c, 0x00103c63, 0x00103c79, 0x00103c8b, - 0x00103ca3, 0x00103cba, 0x00103cbf, 0x00103ce7, - 0x00103d0a, 0x00103d30, 0x00103d53, 0x00103d86, - 0x00103dc8, 0x00103df2, 0x00103e0a, 0x00103e4a, - 0x00103e63, 0x00103e76, 0x00103e77, 0x4803c856, - 0x4202d800, 0x00000007, 0x0201f800, 0x00104e0d, - 0x04000007, 0x42006000, 0xffffffd7, 0x41786800, - 0x0201f800, 0x001040ad, 0x0401f00b, 0x59c40006, - 0x82000500, 0xffffff0f, 0x48038806, 0x42001000, - 0x000000f0, 0x0201f800, 0x001019aa, 0x0201f800, - 0x00104d6c, 0x1c01f000, 0x4803c856, 0x42006000, - 0xbf7fffff, 0x42006800, 0x00400000, 0x0201f800, - 0x001040ad, 0x0201f800, 0x0010164b, 0x4a035014, - 0x00000001, 0x42001000, 0x0010401b, 0x0201f800, - 0x00105cdd, 0x0201f800, 0x00104024, 0x42000800, - 0x000007d0, 0x42001000, 0x00103f62, 0x0201f000, - 0x00105da7, 0x59a80016, 0x82000580, 0x00000014, - 0x04020023, 0x4803c857, 0x42006000, 0xffbfffff, - 0x41786800, 0x0201f800, 0x001040ad, 0x59c40004, - 0x82000500, 0x00000003, 0x04020019, 0x42001000, - 0x00103f62, 0x0201f800, 0x00105cc9, 0x59cc1006, - 0x82081580, 0x11020000, 0x04020012, 0x59cc1007, - 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, - 0x04020008, 0x42000000, 0x0010b63d, 0x0201f800, - 0x0010a86e, 0x59a80015, 0x84000544, 0x48035015, - 0x4a035014, 0x00000010, 0x0401f1cd, 0x1c01f000, - 0x0201f000, 0x00103f53, 0x4803c856, 0x4a035014, - 0x00000003, 0x42006000, 0xbf3fffff, 0x42006800, - 0x00100000, 0x0201f800, 0x001040ad, 0x42001000, - 0x0010401b, 0x0201f800, 0x00105cdd, 0x0201f800, - 0x00104024, 0x42001000, 0x00103f62, 0x0201f800, - 0x00105cc9, 0x42007800, 0x0010b350, 0x46007800, - 0x11020000, 0x42000800, 0x00000005, 0x0201f000, - 0x00103f8e, 0x59a80016, 0x80000540, 0x0400001e, - 0x4803c857, 0x42001000, 0x00103f62, 0x0201f800, - 0x00105cc9, 0x59a80016, 0x82000580, 0x00000014, - 0x04020016, 0x59cc1006, 0x82081580, 0x11020000, - 0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b, - 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, - 0x0010b63d, 0x0201f800, 0x0010a86e, 0x59a80015, - 0x84000544, 0x48035015, 0x4a035014, 0x00000004, - 0x0401f004, 0x1c01f000, 0x0201f000, 0x00103f53, + 0x0010427d, 0x42006000, 0xfff7ffff, 0x41786800, + 0x0201f000, 0x0010427d, 0x59a80016, 0x497b5016, + 0x80002540, 0x04000066, 0x59c40004, 0x82000500, + 0x00000003, 0x04020071, 0x59a80815, 0x8c040d02, + 0x0400004b, 0x82100580, 0x0000000c, 0x0402004f, + 0x82100400, 0x00000018, 0x8000b104, 0x41cc1000, + 0x42001800, 0x0010b54c, 0x50080800, 0x500c0000, + 0x80040580, 0x0402001a, 0x80081000, 0x800c1800, + 0x8058b040, 0x040207f9, 0x0201f800, 0x00104290, + 0x42006000, 0xffffffff, 0x42006800, 0x00500000, + 0x0201f800, 0x0010427d, 0x4a035012, 0x00000002, + 0x4a035014, 0x00000002, 0x42000800, 0x000007d0, + 0x42001000, 0x00104148, 0x0201f800, 0x0010606e, + 0x0201f800, 0x00104263, 0x0401f048, 0x59cc0806, + 0x82040d80, 0x11010000, 0x04020028, 0x59cc0800, + 0x82040500, 0x00ffffff, 0x0400001a, 0x82000580, + 0x000000ef, 0x04020017, 0x59cc0801, 0x82040500, + 0x00ffffff, 0x82000580, 0x000000ef, 0x04020011, + 0x83cca400, 0x00000007, 0x4200a800, 0x0010b402, + 0x4200b000, 0x00000002, 0x50500800, 0x50540000, + 0x80040480, 0x04001007, 0x04020010, 0x8050a000, + 0x8054a800, 0x8058b040, 0x040207f8, 0x0401f00b, + 0x59a80015, 0x84000502, 0x48035015, 0x41cca000, + 0x4200a800, 0x0010b54c, 0x4200b000, 0x00000009, + 0x0201f800, 0x0010ab17, 0x0201f800, 0x00104290, + 0x42006000, 0xffffffff, 0x42006800, 0x00080000, + 0x0201f800, 0x0010427d, 0x42006000, 0xfff7ffff, + 0x41786800, 0x0201f800, 0x0010427d, 0x42006000, + 0xffffffff, 0x42006800, 0x00004000, 0x0201f800, + 0x0010427d, 0x59c40004, 0x82000500, 0x00000003, + 0x04020006, 0x497b5016, 0x42000800, 0x00000003, + 0x0201f000, 0x0010416e, 0x1c01f000, 0x1c01f000, + 0x59a80014, 0x82006d80, 0x0000000f, 0x04000005, + 0x82000580, 0x0000001b, 0x02020800, 0x00104139, + 0x1c01f000, 0x59a80015, 0x84000506, 0x48035015, + 0x497b504a, 0x59a80014, 0x82000c80, 0x0000001e, + 0x02021800, 0x001005d8, 0x0c01f001, 0x00103c97, + 0x00103cac, 0x00103cd5, 0x00103cf0, 0x00103d14, + 0x00103d45, 0x00103d68, 0x00103d9b, 0x00103dbe, + 0x00103de4, 0x00103e21, 0x00103e48, 0x00103e5f, + 0x00103e71, 0x00103e8a, 0x00103ea0, 0x00103ea5, + 0x00103ecd, 0x00103ef0, 0x00103f16, 0x00103f39, + 0x00103f6c, 0x00103fae, 0x00103fd8, 0x00103ff0, + 0x00104030, 0x00104049, 0x0010405c, 0x0010405d, + 0x4803c856, 0x4202d800, 0x00000007, 0x0201f800, + 0x0010513b, 0x04000007, 0x42006000, 0xffffffd7, + 0x41786800, 0x0201f800, 0x0010427d, 0x0401f00b, + 0x59c40006, 0x82000500, 0xffffff0f, 0x48038806, + 0x42001000, 0x000000f0, 0x0201f800, 0x0010193d, + 0x0201f800, 0x00105098, 0x1c01f000, 0x4803c856, + 0x42006000, 0xbf7fffff, 0x42006800, 0x00400000, + 0x0201f800, 0x0010427d, 0x4a035014, 0x00000001, + 0x42001000, 0x001041f3, 0x0201f800, 0x00105fa4, + 0x0201f800, 0x001041f8, 0x42000800, 0x000007d0, + 0x42001000, 0x00104148, 0x0201f000, 0x0010606e, + 0x59a80016, 0x82000580, 0x00000014, 0x04020025, + 0x4803c857, 0x42006000, 0xffbfffff, 0x41786800, + 0x0201f800, 0x0010427d, 0x59c40004, 0x82000500, + 0x00000003, 0x0402001b, 0x59cc1006, 0x82081580, + 0x11020000, 0x04020016, 0x59cc1007, 0x8c08153e, + 0x0400000b, 0x59a80015, 0x8c000504, 0x04020008, + 0x42000000, 0x0010b83f, 0x0201f800, 0x0010aa47, + 0x59a80015, 0x84000544, 0x48035015, 0x42001000, + 0x00104148, 0x0201f800, 0x00105f90, 0x4a035014, + 0x00000010, 0x0401f9d4, 0x0401f002, 0x497b5016, + 0x1c01f000, 0x4803c856, 0x4a035014, 0x00000003, + 0x42006000, 0xbf3fffff, 0x42006800, 0x00100000, + 0x0201f800, 0x0010427d, 0x42001000, 0x001041f3, + 0x0201f800, 0x00105fa4, 0x0201f800, 0x001041f8, + 0x42001000, 0x00104148, 0x0201f800, 0x00105f90, + 0x42007800, 0x0010b552, 0x46007800, 0x11020000, + 0x42000800, 0x00000005, 0x0201f000, 0x0010416e, + 0x59a80016, 0x80000540, 0x04000021, 0x4803c857, + 0x42001000, 0x00104148, 0x0201f800, 0x00105f90, + 0x59a80016, 0x82000580, 0x00000014, 0x04020016, + 0x59cc1006, 0x82081580, 0x11020000, 0x04020012, + 0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015, + 0x8c000504, 0x04020008, 0x42000000, 0x0010b83f, + 0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544, + 0x48035015, 0x4a035014, 0x00000004, 0x0401f805, + 0x0401f003, 0x0201f800, 0x00104139, 0x1c01f000, 0x4803c856, 0x4a035014, 0x00000005, 0x83cca400, - 0x00000006, 0x4200a800, 0x0010b350, 0x4200b000, - 0x00000005, 0x0201f800, 0x0010a93e, 0x42007800, - 0x0010b350, 0x46007800, 0x11030000, 0x0201f800, - 0x00103f58, 0x04020014, 0x59a80015, 0x8c000500, + 0x00000006, 0x4200a800, 0x0010b552, 0x4200b000, + 0x00000005, 0x0201f800, 0x0010ab17, 0x42007800, + 0x0010b552, 0x46007800, 0x11030000, 0x0201f800, + 0x0010413e, 0x04020014, 0x59a80015, 0x8c000500, 0x04020011, 0x59a80810, 0x82040580, 0x00ffffff, 0x0400000d, 0x82040d00, 0x000000ff, 0x82040400, - 0x00101eb5, 0x50000800, 0x80040910, 0x42001000, - 0x00000004, 0x0401fb95, 0x0400000b, 0x0201f800, - 0x0010403d, 0x4200b000, 0x00000004, 0x83cca400, - 0x00000007, 0x4200a800, 0x0010b351, 0x0201f800, - 0x0010a93e, 0x42000800, 0x00000005, 0x0201f000, - 0x00103f8e, 0x59a80016, 0x80000540, 0x0400001e, - 0x4803c857, 0x42001000, 0x00103f62, 0x0201f800, - 0x00105cc9, 0x59a80016, 0x82000580, 0x00000014, + 0x0010210e, 0x50000800, 0x80040910, 0x42001000, + 0x00000004, 0x0401fb9b, 0x0400000b, 0x0201f800, + 0x0010420d, 0x4200b000, 0x00000004, 0x83cca400, + 0x00000007, 0x4200a800, 0x0010b553, 0x0201f800, + 0x0010ab17, 0x42000800, 0x00000005, 0x0201f000, + 0x0010416e, 0x59a80016, 0x80000540, 0x04000020, + 0x4803c857, 0x42001000, 0x00104148, 0x0201f800, + 0x00105f90, 0x59a80016, 0x82000580, 0x00000014, 0x04020016, 0x59cc1006, 0x82081580, 0x11030000, 0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, - 0x0010b63d, 0x0201f800, 0x0010a86e, 0x59a80015, + 0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544, 0x48035015, 0x4a035014, 0x00000006, - 0x0401f003, 0x1c01f000, 0x0401f3cd, 0x4803c856, - 0x4a035014, 0x00000007, 0x83cca400, 0x00000006, - 0x4200a800, 0x0010b350, 0x4200b000, 0x00000005, - 0x0201f800, 0x0010a93e, 0x42007800, 0x0010b350, - 0x46007800, 0x11040000, 0x0401fbc2, 0x04020020, - 0x59a80015, 0x8c000500, 0x0402001d, 0x599c0017, - 0x8c000500, 0x0400001a, 0x599c1402, 0x82080480, - 0x0000007f, 0x02021800, 0x00100615, 0x4c080000, - 0x82081400, 0x00101eb5, 0x50081000, 0x82081500, - 0x000000ff, 0x480b5010, 0x42000800, 0x00000003, - 0x0201f800, 0x001069af, 0x5c000800, 0x42001000, - 0x00000004, 0x0401fb39, 0x04000005, 0x0401fd25, - 0x04000003, 0x0201f800, 0x00101668, 0x42000800, - 0x00000005, 0x0401f3d5, 0x59a80016, 0x80000540, - 0x0400001e, 0x4803c857, 0x42001000, 0x00103f62, - 0x0201f800, 0x00105cc9, 0x59a80016, 0x82000580, - 0x00000014, 0x04020016, 0x59cc1006, 0x82081580, - 0x11040000, 0x04020012, 0x59cc1007, 0x8c08153e, - 0x0400000b, 0x59a80015, 0x8c000504, 0x04020008, - 0x42000000, 0x0010b63d, 0x0201f800, 0x0010a86e, - 0x59a80015, 0x84000544, 0x48035015, 0x4a035014, - 0x00000008, 0x0401f003, 0x1c01f000, 0x0401f378, - 0x4803c856, 0x4a035014, 0x00000009, 0x83cca400, - 0x00000006, 0x4200a800, 0x0010b350, 0x4200b000, - 0x00000005, 0x0201f800, 0x0010a93e, 0x42007800, - 0x0010b350, 0x46007800, 0x11050100, 0x0401fb6d, - 0x0402000a, 0x59a80015, 0x8c000500, 0x04020007, - 0x0401fa88, 0x04020005, 0x82000540, 0x00000001, - 0x0201f800, 0x00101668, 0x42000800, 0x00000005, - 0x0401fb96, 0x4d3c0000, 0x42027800, 0x00000001, - 0x0201f800, 0x00109640, 0x5c027800, 0x1c01f000, - 0x59a80016, 0x80000540, 0x04000038, 0x4803c857, - 0x42001000, 0x00103f62, 0x0201f800, 0x00105cc9, + 0x0401f804, 0x0401f002, 0x0401fbd3, 0x1c01f000, + 0x4803c856, 0x4a035014, 0x00000007, 0x83cca400, + 0x00000006, 0x4200a800, 0x0010b552, 0x4200b000, + 0x00000005, 0x0201f800, 0x0010ab17, 0x42007800, + 0x0010b552, 0x46007800, 0x11040000, 0x0401fbc7, + 0x04020020, 0x59a80015, 0x8c000500, 0x0402001d, + 0x599c0017, 0x8c000500, 0x0400001a, 0x599c1402, + 0x82080480, 0x0000007f, 0x02021800, 0x001005d8, + 0x4c080000, 0x82081400, 0x0010210e, 0x50081000, + 0x82081500, 0x000000ff, 0x480b5010, 0x42000800, + 0x00000003, 0x0201f800, 0x00106c78, 0x5c000800, + 0x42001000, 0x00000004, 0x0401fb3e, 0x04000005, + 0x0401fd2b, 0x04000003, 0x0201f800, 0x001015fe, + 0x42000800, 0x00000005, 0x0401f3d4, 0x59a80016, + 0x80000540, 0x04000020, 0x4803c857, 0x42001000, + 0x00104148, 0x0201f800, 0x00105f90, 0x59a80016, + 0x82000580, 0x00000014, 0x04020016, 0x59cc1006, + 0x82081580, 0x11040000, 0x04020012, 0x59cc1007, + 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, + 0x04020008, 0x42000000, 0x0010b83f, 0x0201f800, + 0x0010aa47, 0x59a80015, 0x84000544, 0x48035015, + 0x4a035014, 0x00000008, 0x0401f804, 0x0401f002, + 0x0401fb7d, 0x1c01f000, 0x4803c856, 0x4a035014, + 0x00000009, 0x83cca400, 0x00000006, 0x4200a800, + 0x0010b552, 0x4200b000, 0x00000005, 0x0201f800, + 0x0010ab17, 0x42007800, 0x0010b552, 0x46007800, + 0x11050100, 0x0401fb71, 0x0402000a, 0x59a80015, + 0x8c000500, 0x04020007, 0x0401fa8c, 0x04020005, + 0x82000540, 0x00000001, 0x0201f800, 0x001015fe, + 0x42000800, 0x00000005, 0x0401fb94, 0x0401fb63, + 0x04020ea4, 0x4d3c0000, 0x42027800, 0x00000001, + 0x0201f800, 0x00109874, 0x5c027800, 0x1c01f000, + 0x59a80016, 0x80000540, 0x0400003a, 0x4803c857, + 0x42001000, 0x00104148, 0x0201f800, 0x00105f90, 0x59a80016, 0x82000580, 0x00000014, 0x04020030, 0x59cc1006, 0x82080500, 0x11050000, 0x82000580, 0x11050000, 0x0402002a, 0x8c081510, 0x04000014, 0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015, - 0x8c000504, 0x04020008, 0x42000000, 0x0010b63d, - 0x0201f800, 0x0010a86e, 0x59a80015, 0x84000544, + 0x8c000504, 0x04020008, 0x42000000, 0x0010b83f, + 0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544, 0x48035015, 0x4a035013, 0x00000001, 0x4a035014, - 0x0000000a, 0x0401f817, 0x0401f014, 0x80000540, + 0x0000000a, 0x0401f818, 0x0401f016, 0x80000540, 0x04020013, 0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, - 0x0010b63d, 0x0201f800, 0x0010a86e, 0x59a80015, + 0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544, 0x48035015, 0x497b5013, 0x4a035014, - 0x0000000e, 0x0401f06a, 0x1c01f000, 0x0401f318, - 0x4803c856, 0x4a035014, 0x0000000b, 0x42001000, - 0x0010b351, 0x4008a800, 0x4200b000, 0x00000020, - 0x4600a800, 0xffffffff, 0x8054a800, 0x8058b040, - 0x040207fc, 0x42007800, 0x0010b350, 0x46007800, - 0x11060000, 0x42001000, 0x0010b351, 0x0401fb09, - 0x04000005, 0x50080000, 0x46001000, 0x00ffffff, - 0x0401f00c, 0x50080800, 0x82040d00, 0x0000ffff, - 0x59a80010, 0x82000500, 0x000000ff, 0x82000540, - 0x00000100, 0x800000e0, 0x80040d40, 0x44041000, - 0x42000800, 0x00000021, 0x0401f32c, 0x59a80016, - 0x80000540, 0x04000012, 0x4803c857, 0x59a80016, - 0x42001000, 0x00103f62, 0x0201f800, 0x00105cc9, - 0x59a80016, 0x82000580, 0x00000084, 0x04020009, - 0x59cc1006, 0x82081580, 0x11060000, 0x04020005, - 0x4a035014, 0x0000000c, 0x0401f003, 0x1c01f000, - 0x0401f2db, 0x4803c856, 0x4a035014, 0x0000000d, - 0x83cca400, 0x00000006, 0x4200a800, 0x0010b350, - 0x4200b000, 0x00000021, 0x0201f800, 0x0010a93e, - 0x42007800, 0x0010b350, 0x46007800, 0x11070000, - 0x42000800, 0x00000021, 0x0401f304, 0x59a80016, - 0x80000540, 0x04000014, 0x4803c857, 0x59a80016, - 0x42001000, 0x00103f62, 0x0201f800, 0x00105cc9, - 0x82000580, 0x00000084, 0x0402000c, 0x59cc1006, - 0x82081580, 0x11070000, 0x04020008, 0x4a035013, - 0x00000001, 0x0401fa91, 0x4a035014, 0x0000000e, - 0x0401f003, 0x1c01f000, 0x0401f2b1, 0x4803c856, - 0x82040d40, 0x00000001, 0x0201f800, 0x001040b9, - 0x4a035014, 0x0000000f, 0x497b5016, 0x42006000, - 0xffffffff, 0x42006800, 0x00300000, 0x0401fbfe, - 0x42006000, 0xffdfffff, 0x41786800, 0x0401fbfa, - 0x42000800, 0x000007d0, 0x42001000, 0x00103f62, - 0x0201f000, 0x00105ca2, 0x4803c856, 0x59a80016, - 0x80000540, 0x04020296, 0x1c01f000, 0x4803c856, - 0x4a035014, 0x00000011, 0x83cca400, 0x00000006, - 0x4200a800, 0x0010b350, 0x4200b000, 0x00000005, - 0x0201f800, 0x0010a93e, 0x4200a800, 0x0010b350, - 0x4600a800, 0x11020000, 0x0401fa8a, 0x04020015, - 0x59a80010, 0x82000d00, 0xffff0000, 0x04000011, - 0x82000500, 0x000000ff, 0x0400000e, 0x82000c00, - 0x00101eb5, 0x50040800, 0x80040910, 0x82040580, - 0x0000007e, 0x04000007, 0x82040580, 0x00000080, - 0x04000004, 0x42001000, 0x00000004, 0x0401fa07, - 0x42000800, 0x00000005, 0x0401f2a8, 0x59a80016, - 0x80000540, 0x04000020, 0x4803c857, 0x42001000, - 0x00103f62, 0x0201f800, 0x00105cc9, 0x59a80016, - 0x82000580, 0x00000014, 0x04020016, 0x59cc1006, - 0x82081580, 0x11030000, 0x04020012, 0x59cc1007, - 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, - 0x04020008, 0x42000000, 0x0010b63d, 0x0201f800, - 0x0010a86e, 0x59a80015, 0x84000544, 0x48035015, - 0x4a035014, 0x00000012, 0x0401f804, 0x0401f002, - 0x0401fa4b, 0x1c01f000, 0x4803c856, 0x4a035014, - 0x00000013, 0x83cca400, 0x00000006, 0x4200a800, - 0x0010b350, 0x4200b000, 0x00000005, 0x0201f800, - 0x0010a93e, 0x4200a800, 0x0010b350, 0x4600a800, - 0x11030000, 0x0401fa3f, 0x04020013, 0x59a80015, - 0x8c000500, 0x04020010, 0x59a80810, 0x82040580, - 0x00ffffff, 0x0400000c, 0x82040d00, 0x000000ff, - 0x82040400, 0x00101eb5, 0x50000800, 0x80040910, - 0x42001000, 0x00000004, 0x0401f9c0, 0x04000002, - 0x0401fb11, 0x42000800, 0x00000005, 0x0401f25f, - 0x59a80016, 0x80000540, 0x04000020, 0x4803c857, - 0x42001000, 0x00103f62, 0x0201f800, 0x00105cc9, - 0x59a80016, 0x82000580, 0x00000014, 0x04020016, - 0x59cc1006, 0x82081580, 0x11040000, 0x04020012, - 0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015, - 0x8c000504, 0x04020008, 0x42000000, 0x0010b63d, - 0x0201f800, 0x0010a86e, 0x59a80015, 0x84000544, - 0x48035015, 0x4a035014, 0x00000014, 0x0401f804, - 0x0401f002, 0x0401fa02, 0x1c01f000, 0x4803c856, - 0x4a035014, 0x00000015, 0x83cca400, 0x00000006, - 0x4200a800, 0x0010b350, 0x4200b000, 0x00000005, - 0x0201f800, 0x0010a93e, 0x4200a800, 0x0010b350, - 0x4600a800, 0x11040000, 0x0401f9f6, 0x04020020, - 0x59a80015, 0x8c000500, 0x0402001d, 0x599c0017, - 0x8c000500, 0x0400001a, 0x599c1402, 0x82080480, - 0x0000007f, 0x02021800, 0x00100615, 0x4c080000, - 0x82081400, 0x00101eb5, 0x50081000, 0x82081500, - 0x000000ff, 0x480b5010, 0x42000800, 0x00000003, - 0x0201f800, 0x001069af, 0x5c000800, 0x42001000, - 0x00000004, 0x0401f96d, 0x04000005, 0x0201f800, - 0x001038d8, 0x02020800, 0x00101668, 0x42000800, - 0x00000005, 0x0401f209, 0x59a80016, 0x80000540, - 0x0400003f, 0x4803c857, 0x42001000, 0x00103f62, - 0x0201f800, 0x00105cc9, 0x59a80016, 0x82000580, - 0x00000014, 0x04020035, 0x59cc1006, 0x82080500, - 0x11050000, 0x82000580, 0x11050000, 0x0402002f, - 0x8c081510, 0x04000010, 0x0401fb1f, 0x59cc1007, - 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, - 0x04020008, 0x42000000, 0x0010b63d, 0x0201f800, - 0x0010a86e, 0x59a80015, 0x84000544, 0x48035015, - 0x0401f013, 0x59cc1007, 0x8c08153e, 0x0400000b, + 0x0000000e, 0x0401f86d, 0x0401f002, 0x0401fb1a, + 0x1c01f000, 0x4803c856, 0x4a035014, 0x0000000b, + 0x42001000, 0x0010b553, 0x4008a800, 0x4200b000, + 0x00000020, 0x4600a800, 0xffffffff, 0x8054a800, + 0x8058b040, 0x040207fc, 0x42007800, 0x0010b552, + 0x46007800, 0x11060000, 0x42001000, 0x0010b553, + 0x0401fb0a, 0x04000005, 0x50080000, 0x46001000, + 0x00ffffff, 0x0401f00c, 0x50080800, 0x82040d00, + 0x0000ffff, 0x59a80010, 0x82000500, 0x000000ff, + 0x82000540, 0x00000100, 0x800000e0, 0x80040d40, + 0x44041000, 0x42000800, 0x00000021, 0x0401f327, + 0x59a80016, 0x80000540, 0x04000014, 0x4803c857, + 0x59a80016, 0x42001000, 0x00104148, 0x0201f800, + 0x00105f90, 0x59a80016, 0x82000580, 0x00000084, + 0x04020009, 0x59cc1006, 0x82081580, 0x11060000, + 0x04020005, 0x4a035014, 0x0000000c, 0x0401f804, + 0x0401f002, 0x0401fadc, 0x1c01f000, 0x4803c856, + 0x4a035014, 0x0000000d, 0x83cca400, 0x00000006, + 0x4200a800, 0x0010b552, 0x4200b000, 0x00000021, + 0x0201f800, 0x0010ab17, 0x42007800, 0x0010b552, + 0x46007800, 0x11070000, 0x42000800, 0x00000021, + 0x0401f2fe, 0x59a80016, 0x80000540, 0x04000016, + 0x4803c857, 0x59a80016, 0x42001000, 0x00104148, + 0x0201f800, 0x00105f90, 0x82000580, 0x00000084, + 0x0402000c, 0x59cc1006, 0x82081580, 0x11070000, + 0x04020008, 0x4a035013, 0x00000001, 0x0401fa91, + 0x4a035014, 0x0000000e, 0x0401f804, 0x0401f002, + 0x0401fab1, 0x1c01f000, 0x4803c856, 0x82040d40, + 0x00000001, 0x0401fbfc, 0x4a035014, 0x0000000f, + 0x497b5016, 0x42006000, 0xffffffff, 0x42006800, + 0x00300000, 0x0401fbe8, 0x42006000, 0xffdfffff, + 0x41786800, 0x0401fbe4, 0x42000800, 0x000007d0, + 0x42001000, 0x00104148, 0x0201f000, 0x00105f69, + 0x4803c856, 0x59a80016, 0x80000540, 0x04020296, + 0x1c01f000, 0x4803c856, 0x4a035014, 0x00000011, + 0x83cca400, 0x00000006, 0x4200a800, 0x0010b552, + 0x4200b000, 0x00000005, 0x0201f800, 0x0010ab17, + 0x4200a800, 0x0010b552, 0x4600a800, 0x11020000, + 0x0401fa8a, 0x04020015, 0x59a80010, 0x82000d00, + 0xffff0000, 0x04000011, 0x82000500, 0x000000ff, + 0x0400000e, 0x82000c00, 0x0010210e, 0x50040800, + 0x80040910, 0x82040580, 0x0000007e, 0x04000007, + 0x82040580, 0x00000080, 0x04000004, 0x42001000, + 0x00000004, 0x0401fa07, 0x42000800, 0x00000005, + 0x0401f2a2, 0x59a80016, 0x80000540, 0x04000020, + 0x4803c857, 0x42001000, 0x00104148, 0x0201f800, + 0x00105f90, 0x59a80016, 0x82000580, 0x00000014, + 0x04020016, 0x59cc1006, 0x82081580, 0x11030000, + 0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, - 0x0010b63d, 0x0201f800, 0x0010a86e, 0x59a80015, - 0x84000544, 0x48035015, 0x82000540, 0x00000001, - 0x0401fb01, 0x497b5013, 0x0401f003, 0x4a035013, - 0x00000001, 0x59cc1007, 0x8c08153c, 0x04000003, - 0x4a035026, 0x00000008, 0x4a035014, 0x00000016, - 0x0401f804, 0x0401f002, 0x0401f98d, 0x1c01f000, - 0x4803c856, 0x83cca400, 0x00000006, 0x4200a800, - 0x0010b350, 0x4200b000, 0x00000005, 0x0201f800, - 0x0010a93e, 0x4a035014, 0x00000017, 0x59a80013, - 0x8c000500, 0x04000006, 0x42001000, 0x0010b350, - 0x46001000, 0x11050100, 0x0401f003, 0x4a035014, - 0x0000001b, 0x0401f97b, 0x0402000a, 0x59a80015, - 0x8c000500, 0x04020007, 0x0401f896, 0x04020005, - 0x82000540, 0x00000001, 0x0201f800, 0x00101668, - 0x42000800, 0x00000005, 0x0401f9a4, 0x4d3c0000, - 0x42027800, 0x00000001, 0x0201f800, 0x00109640, - 0x5c027800, 0x1c01f000, 0x59a80016, 0x80000540, - 0x04000015, 0x4803c857, 0x42001000, 0x00103f62, - 0x0201f800, 0x00105cc9, 0x59a80016, 0x82000580, - 0x00000084, 0x0402000b, 0x59cc1006, 0x82081580, - 0x11060000, 0x04020007, 0x80000580, 0x0401fab6, - 0x4a035014, 0x00000018, 0x0401f804, 0x0401f002, - 0x0401f94b, 0x1c01f000, 0x4803c856, 0x4a035014, - 0x00000019, 0x83cca400, 0x00000006, 0x4200a800, - 0x0010b350, 0x4200b000, 0x00000021, 0x0201f800, - 0x0010a93e, 0x42003800, 0x0010b351, 0x0401f941, - 0x04020018, 0x401c2800, 0x50141000, 0x80080130, - 0x80000000, 0x40001800, 0x82081500, 0x00ffffff, - 0x800000f0, 0x80080540, 0x44002800, 0x59a80810, - 0x82040d00, 0x000000ff, 0x400c1000, 0x80081104, - 0x82082400, 0x0010b351, 0x50101000, 0x820c0500, - 0x00000003, 0x0c01f806, 0x80081540, 0x44082000, - 0x42000800, 0x00000021, 0x0401f15c, 0x00103e37, - 0x00103e3c, 0x00103e41, 0x00103e46, 0x800408f0, - 0x40040000, 0x82081500, 0x00ffffff, 0x1c01f000, - 0x800408e0, 0x40040000, 0x82081500, 0xff00ffff, - 0x1c01f000, 0x800408d0, 0x40040000, 0x82081500, - 0xffff00ff, 0x1c01f000, 0x40040000, 0x82081500, - 0xffffff00, 0x1c01f000, 0x59a80016, 0x80000540, - 0x04000016, 0x4803c857, 0x42001000, 0x00103f62, - 0x0201f800, 0x00105cc9, 0x59a80016, 0x82000580, - 0x00000084, 0x0402000c, 0x59cc1006, 0x82081580, - 0x11070000, 0x04020008, 0x4a035013, 0x00000001, - 0x0401f8d2, 0x4a035014, 0x0000001a, 0x0401f804, - 0x0401f002, 0x0401f8f2, 0x1c01f000, 0x82000540, - 0x00000001, 0x0401fa54, 0x4a035014, 0x0000001b, - 0x83cca400, 0x00000006, 0x4200a800, 0x0010b350, - 0x59a82016, 0x40100000, 0x8000b104, 0x40580800, - 0x5450a800, 0x8050a000, 0x8054a800, 0x8058b040, - 0x040207fc, 0x0401f119, 0x1c01f000, 0x1c01f000, - 0x4803c856, 0x42003000, 0x00000004, 0x42004000, - 0x0010b351, 0x599c2817, 0x8c142d14, 0x0402001f, - 0x42001000, 0x00000003, 0x40200000, 0x80080400, - 0x50000800, 0x82042580, 0xffffffff, 0x04020005, - 0x80081040, 0x80183040, 0x040207f8, 0x0401f05e, - 0x800811c0, 0x04020006, 0x82042580, 0x3fffffff, - 0x04000058, 0x82040d40, 0xc0000000, 0x4200b000, - 0x00000020, 0x42001800, 0x00000001, 0x40042000, - 0x80102102, 0x04021021, 0x800c18c2, 0x8058b040, - 0x040207fc, 0x0401f04b, 0x41781000, 0x40200000, - 0x80080400, 0x50000800, 0x82042580, 0xffffffff, - 0x04020005, 0x80081000, 0x80183040, 0x040207f8, - 0x0401f040, 0x800811c0, 0x04020003, 0x82040d40, - 0xc0000000, 0x4200b000, 0x00000001, 0x42001800, - 0x80000000, 0x40042000, 0x801020c2, 0x04021007, - 0x800c1902, 0x8058b000, 0x82580480, 0x00000021, - 0x040017fa, 0x0401f02f, 0x40200000, 0x80082400, - 0x50100000, 0x800c0540, 0x44002000, 0x59a80015, - 0x84000540, 0x48035015, 0x40580000, 0x42002800, - 0x00000020, 0x80142c80, 0x40080000, 0x42003800, - 0x00000003, 0x801c0480, 0x800000ca, 0x80142d40, - 0x82144c00, 0x00101eb5, 0x50242800, 0x82142d00, - 0x000000ff, 0x48175010, 0x4c040000, 0x40140800, - 0x0201f800, 0x00101655, 0x5c000800, 0x40001800, - 0x500c0000, 0x80100540, 0x44001800, 0x59a80015, - 0x84000540, 0x48035015, 0x4200a800, 0x0010b351, - 0x4020a000, 0x4200b000, 0x00000004, 0x0201f800, - 0x0010a93e, 0x82000540, 0x00000001, 0x0401f002, - 0x80000580, 0x1c01f000, 0x4807c857, 0x480bc857, - 0x4008b000, 0x83cca400, 0x00000007, 0x4200a800, - 0x0010b351, 0x40541000, 0x0201f800, 0x0010a93e, - 0x40041800, 0x41782000, 0x42000000, 0x00000003, - 0x820c1c80, 0x00000020, 0x04001004, 0x80102000, - 0x80000040, 0x0401f7fb, 0x40041800, 0x801021c0, - 0x04000005, 0x820c1c80, 0x00000020, 0x80102040, - 0x040207fd, 0x42002000, 0x00000001, 0x800c19c0, - 0x04000004, 0x801020c2, 0x800c1840, 0x040207fe, - 0x80083c00, 0x83cc2c00, 0x00000007, 0x80142c00, - 0x50140000, 0x80102d00, 0x04020012, 0x80100540, - 0x44003800, 0x82042400, 0x00101eb5, 0x50102800, - 0x82142d00, 0x000000ff, 0x48175010, 0x4c040000, - 0x40140800, 0x0201f800, 0x00101655, 0x5c000800, - 0x59a80015, 0x84000540, 0x48035015, 0x80000580, - 0x1c01f000, 0x4807c856, 0x42001000, 0x00008017, - 0x59a8184e, 0x0201f800, 0x0010a876, 0x0201f800, - 0x00103857, 0x1c01f000, 0x4807c856, 0x4200b000, - 0x00000020, 0x83cca400, 0x00000007, 0x4200a800, - 0x0010bc20, 0x0201f000, 0x0010a94f, 0x4807c856, - 0x0201f800, 0x00106c32, 0x42000800, 0x000000f7, - 0x0401f8f4, 0x497b2804, 0x497b2805, 0x497b281c, - 0x497b281d, 0x4202d800, 0x00000001, 0x42006000, - 0xbf7fffff, 0x42006800, 0x00018000, 0x0401f966, - 0x42006000, 0xfffeffff, 0x41786800, 0x0401f962, - 0x497b504e, 0x42000800, 0x0000002d, 0x42001000, - 0x00103fe4, 0x0201f000, 0x00105ca2, 0x4807c856, - 0x0401ffe3, 0x497b5014, 0x497b5016, 0x1c01f000, - 0x4807c856, 0x59a80005, 0x8c000506, 0x1c01f000, - 0x4807c856, 0x42006000, 0xffffffff, 0x42006800, - 0x00000028, 0x0401f14c, 0x4807c856, 0x0401ffc2, - 0x0201f800, 0x0010698c, 0x4df00000, 0x0201f800, - 0x00106b71, 0x5c03e000, 0x02000800, 0x00106982, - 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, - 0x00000002, 0x0402000a, 0x42006000, 0xffffffff, - 0x42006800, 0x00200000, 0x0401f937, 0x42006000, - 0xffdfffff, 0x41786800, 0x0401f933, 0x497b5014, - 0x42000800, 0x000000f7, 0x0401f8b2, 0x59c400a3, - 0x82000500, 0xbf20bfff, 0x82000540, 0x0001c000, - 0x480388a3, 0x84000520, 0x480388a3, 0x497b504e, - 0x42000800, 0x0000002d, 0x42001000, 0x00103fe4, - 0x0201f000, 0x00105ca2, 0x497b5016, 0x59b400f5, + 0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015, + 0x84000544, 0x48035015, 0x4a035014, 0x00000012, + 0x0401f804, 0x0401f002, 0x0401fa4b, 0x1c01f000, + 0x4803c856, 0x4a035014, 0x00000013, 0x83cca400, + 0x00000006, 0x4200a800, 0x0010b552, 0x4200b000, + 0x00000005, 0x0201f800, 0x0010ab17, 0x4200a800, + 0x0010b552, 0x4600a800, 0x11030000, 0x0401fa3f, + 0x04020013, 0x59a80015, 0x8c000500, 0x04020010, + 0x59a80810, 0x82040580, 0x00ffffff, 0x0400000c, + 0x82040d00, 0x000000ff, 0x82040400, 0x0010210e, + 0x50000800, 0x80040910, 0x42001000, 0x00000004, + 0x0401f9c0, 0x04000002, 0x0401fafb, 0x42000800, + 0x00000005, 0x0401f259, 0x59a80016, 0x80000540, + 0x04000020, 0x4803c857, 0x42001000, 0x00104148, + 0x0201f800, 0x00105f90, 0x59a80016, 0x82000580, + 0x00000014, 0x04020016, 0x59cc1006, 0x82081580, + 0x11040000, 0x04020012, 0x59cc1007, 0x8c08153e, + 0x0400000b, 0x59a80015, 0x8c000504, 0x04020008, + 0x42000000, 0x0010b83f, 0x0201f800, 0x0010aa47, + 0x59a80015, 0x84000544, 0x48035015, 0x4a035014, + 0x00000014, 0x0401f804, 0x0401f002, 0x0401fa02, + 0x1c01f000, 0x4803c856, 0x4a035014, 0x00000015, + 0x83cca400, 0x00000006, 0x4200a800, 0x0010b552, + 0x4200b000, 0x00000005, 0x0201f800, 0x0010ab17, + 0x4200a800, 0x0010b552, 0x4600a800, 0x11040000, + 0x0401f9f6, 0x04020020, 0x59a80015, 0x8c000500, + 0x0402001d, 0x599c0017, 0x8c000500, 0x0400001a, + 0x599c1402, 0x82080480, 0x0000007f, 0x02021800, + 0x001005d8, 0x4c080000, 0x82081400, 0x0010210e, + 0x50081000, 0x82081500, 0x000000ff, 0x480b5010, + 0x42000800, 0x00000003, 0x0201f800, 0x00106c78, + 0x5c000800, 0x42001000, 0x00000004, 0x0401f96d, + 0x04000005, 0x0201f800, 0x00103abf, 0x02020800, + 0x001015fe, 0x42000800, 0x00000005, 0x0401f203, + 0x59a80016, 0x80000540, 0x0400003f, 0x4803c857, + 0x42001000, 0x00104148, 0x0201f800, 0x00105f90, + 0x59a80016, 0x82000580, 0x00000014, 0x04020035, + 0x59cc1006, 0x82080500, 0x11050000, 0x82000580, + 0x11050000, 0x0402002f, 0x8c081510, 0x04000010, + 0x0401fb09, 0x59cc1007, 0x8c08153e, 0x0400000b, + 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, + 0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015, + 0x84000544, 0x48035015, 0x0401f013, 0x59cc1007, + 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, + 0x04020008, 0x42000000, 0x0010b83f, 0x0201f800, + 0x0010aa47, 0x59a80015, 0x84000544, 0x48035015, + 0x82000540, 0x00000001, 0x0401faeb, 0x497b5013, + 0x0401f003, 0x4a035013, 0x00000001, 0x59cc1007, + 0x8c08153c, 0x04000003, 0x4a035026, 0x00000008, + 0x4a035014, 0x00000016, 0x0401f804, 0x0401f002, + 0x0401f98d, 0x1c01f000, 0x4803c856, 0x83cca400, + 0x00000006, 0x4200a800, 0x0010b552, 0x4200b000, + 0x00000005, 0x0201f800, 0x0010ab17, 0x4a035014, + 0x00000017, 0x59a80013, 0x8c000500, 0x04000006, + 0x42001000, 0x0010b552, 0x46001000, 0x11050100, + 0x0401f003, 0x4a035014, 0x0000001b, 0x0401f97b, + 0x0402000a, 0x59a80015, 0x8c000500, 0x04020007, + 0x0401f896, 0x04020005, 0x82000540, 0x00000001, + 0x0201f800, 0x001015fe, 0x42000800, 0x00000005, + 0x0401f99e, 0x4d3c0000, 0x42027800, 0x00000001, + 0x0201f800, 0x00109874, 0x5c027800, 0x1c01f000, + 0x59a80016, 0x80000540, 0x04000015, 0x4803c857, + 0x42001000, 0x00104148, 0x0201f800, 0x00105f90, + 0x59a80016, 0x82000580, 0x00000084, 0x0402000b, + 0x59cc1006, 0x82081580, 0x11060000, 0x04020007, + 0x80000580, 0x0401faa0, 0x4a035014, 0x00000018, + 0x0401f804, 0x0401f002, 0x0401f94b, 0x1c01f000, + 0x4803c856, 0x4a035014, 0x00000019, 0x83cca400, + 0x00000006, 0x4200a800, 0x0010b552, 0x4200b000, + 0x00000021, 0x0201f800, 0x0010ab17, 0x42003800, + 0x0010b553, 0x0401f941, 0x04020018, 0x401c2800, + 0x50141000, 0x80080130, 0x80000000, 0x40001800, + 0x82081500, 0x00ffffff, 0x800000f0, 0x80080540, + 0x44002800, 0x59a80810, 0x82040d00, 0x000000ff, + 0x400c1000, 0x80081104, 0x82082400, 0x0010b553, + 0x50101000, 0x820c0500, 0x00000003, 0x0c01f806, + 0x80081540, 0x44082000, 0x42000800, 0x00000021, + 0x0401f156, 0x0010401d, 0x00104022, 0x00104027, + 0x0010402c, 0x800408f0, 0x40040000, 0x82081500, + 0x00ffffff, 0x1c01f000, 0x800408e0, 0x40040000, + 0x82081500, 0xff00ffff, 0x1c01f000, 0x800408d0, + 0x40040000, 0x82081500, 0xffff00ff, 0x1c01f000, + 0x40040000, 0x82081500, 0xffffff00, 0x1c01f000, + 0x59a80016, 0x80000540, 0x04000016, 0x4803c857, + 0x42001000, 0x00104148, 0x0201f800, 0x00105f90, + 0x59a80016, 0x82000580, 0x00000084, 0x0402000c, + 0x59cc1006, 0x82081580, 0x11070000, 0x04020008, + 0x4a035013, 0x00000001, 0x0401f8d2, 0x4a035014, + 0x0000001a, 0x0401f804, 0x0401f002, 0x0401f8f2, + 0x1c01f000, 0x82000540, 0x00000001, 0x0401fa3e, + 0x4a035014, 0x0000001b, 0x83cca400, 0x00000006, + 0x4200a800, 0x0010b552, 0x59a82016, 0x40100000, + 0x8000b104, 0x40580800, 0x5450a800, 0x8050a000, + 0x8054a800, 0x8058b040, 0x040207fc, 0x0401f113, + 0x1c01f000, 0x1c01f000, 0x4803c856, 0x42003000, + 0x00000004, 0x42004000, 0x0010b553, 0x599c2817, + 0x8c142d14, 0x0402001f, 0x42001000, 0x00000003, + 0x40200000, 0x80080400, 0x50000800, 0x82042580, + 0xffffffff, 0x04020005, 0x80081040, 0x80183040, + 0x040207f8, 0x0401f05e, 0x800811c0, 0x04020006, + 0x82042580, 0x3fffffff, 0x04000058, 0x82040d40, + 0xc0000000, 0x4200b000, 0x00000020, 0x42001800, + 0x00000001, 0x40042000, 0x80102102, 0x04021021, + 0x800c18c2, 0x8058b040, 0x040207fc, 0x0401f04b, + 0x41781000, 0x40200000, 0x80080400, 0x50000800, + 0x82042580, 0xffffffff, 0x04020005, 0x80081000, + 0x80183040, 0x040207f8, 0x0401f040, 0x800811c0, + 0x04020003, 0x82040d40, 0xc0000000, 0x4200b000, + 0x00000001, 0x42001800, 0x80000000, 0x40042000, + 0x801020c2, 0x04021007, 0x800c1902, 0x8058b000, + 0x82580480, 0x00000021, 0x040017fa, 0x0401f02f, + 0x40200000, 0x80082400, 0x50100000, 0x800c0540, + 0x44002000, 0x59a80015, 0x84000540, 0x48035015, + 0x40580000, 0x42002800, 0x00000020, 0x80142c80, + 0x40080000, 0x42003800, 0x00000003, 0x801c0480, + 0x800000ca, 0x80142d40, 0x82144c00, 0x0010210e, + 0x50242800, 0x82142d00, 0x000000ff, 0x48175010, + 0x4c040000, 0x40140800, 0x0201f800, 0x001015eb, + 0x5c000800, 0x40001800, 0x500c0000, 0x80100540, + 0x44001800, 0x59a80015, 0x84000540, 0x48035015, + 0x4200a800, 0x0010b553, 0x4020a000, 0x4200b000, + 0x00000004, 0x0201f800, 0x0010ab17, 0x82000540, + 0x00000001, 0x0401f002, 0x80000580, 0x1c01f000, + 0x4807c857, 0x480bc857, 0x4008b000, 0x83cca400, + 0x00000007, 0x4200a800, 0x0010b553, 0x40541000, + 0x0201f800, 0x0010ab17, 0x40041800, 0x41782000, + 0x42000000, 0x00000003, 0x820c1c80, 0x00000020, + 0x04001004, 0x80102000, 0x80000040, 0x0401f7fb, + 0x40041800, 0x801021c0, 0x04000005, 0x820c1c80, + 0x00000020, 0x80102040, 0x040207fd, 0x42002000, + 0x00000001, 0x800c19c0, 0x04000004, 0x801020c2, + 0x800c1840, 0x040207fe, 0x80083c00, 0x83cc2c00, + 0x00000007, 0x80142c00, 0x50140000, 0x80102d00, + 0x04020012, 0x80100540, 0x44003800, 0x82042400, + 0x0010210e, 0x50102800, 0x82142d00, 0x000000ff, + 0x48175010, 0x4c040000, 0x40140800, 0x0201f800, + 0x001015eb, 0x5c000800, 0x59a80015, 0x84000540, + 0x48035015, 0x80000580, 0x1c01f000, 0x4807c856, + 0x42001000, 0x00008017, 0x59a8184e, 0x0201f800, + 0x0010aa4f, 0x0201f800, 0x00103a3e, 0x1c01f000, + 0x4807c856, 0x4200b000, 0x00000020, 0x83cca400, + 0x00000007, 0x4200a800, 0x0010be21, 0x0201f000, + 0x0010ab28, 0x4807c856, 0x0201f800, 0x00106ede, + 0x42000800, 0x000000f7, 0x0401f8de, 0x497b2804, + 0x497b2805, 0x497b281c, 0x497b281d, 0x4202d800, + 0x00000001, 0x42006000, 0xbf7fffff, 0x42006800, + 0x00018000, 0x0401f950, 0x42006000, 0xfffeffff, + 0x41786800, 0x0401f94c, 0x497b504e, 0x42000800, + 0x0000002d, 0x42001000, 0x001041bc, 0x0201f000, + 0x00105f69, 0x4807c856, 0x0401ffe3, 0x497b5014, + 0x497b5016, 0x1c01f000, 0x4807c856, 0x59a80005, + 0x8c000506, 0x1c01f000, 0x4807c856, 0x42006000, + 0xffffffff, 0x42006800, 0x00000028, 0x0401f136, + 0x4807c856, 0x0401ffc2, 0x0201f800, 0x00106c55, + 0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x59c400a4, 0x82000500, + 0x0000000f, 0x82000580, 0x00000002, 0x0402000a, + 0x42006000, 0xffffffff, 0x42006800, 0x00200000, + 0x0401f921, 0x42006000, 0xffdfffff, 0x41786800, + 0x0401f91d, 0x497b5014, 0x42000800, 0x000000f7, + 0x0401f89c, 0x59c400a3, 0x82000500, 0xbf20bfff, + 0x82000540, 0x0001c000, 0x480388a3, 0x84000520, + 0x480388a3, 0x1c01f000, 0x497b5016, 0x59b400f5, 0x8c000500, 0x04020004, 0x82000540, 0x00000001, 0x480368f5, 0x800400c4, 0x82000400, 0x00002000, 0x4803910a, 0x59b400f6, 0x82000500, 0x00000018, - 0x040207fd, 0x4a0368f0, 0x0010b349, 0x42000000, - 0x0010b350, 0x4c040000, 0x50000800, 0x82040d80, - 0x11010000, 0x04000003, 0x50000800, 0x4807c857, - 0x5c000800, 0x480368f1, 0x82040400, 0x0000dc00, + 0x040207fd, 0x4a0368f0, 0x0010b54b, 0x42000000, + 0x0010b552, 0x480368f1, 0x82040400, 0x0000dc00, 0x480368f3, 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, 0x00000008, 0x04020017, 0x4c5c0000, 0x4c600000, 0x59c4b805, 0x8c5cbd3a, 0x04020005, - 0x42000000, 0x0010b616, 0x0201f800, 0x0010a86e, - 0x4a038805, 0x02000000, 0x0201f800, 0x00101a59, - 0x4000c000, 0x0201f800, 0x001019d0, 0x4202d800, + 0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47, + 0x4a038805, 0x02000000, 0x0201f800, 0x001019fe, + 0x4000c000, 0x0201f800, 0x00101963, 0x4202d800, 0x00000001, 0x497b5014, 0x5c00c000, 0x5c00b800, 0x1c01f000, 0x59c8010b, 0x8c000502, 0x040007e2, 0x59c408a4, 0x82040d00, 0x0000000f, 0x82040d80, @@ -4127,54 +4245,52 @@ uint32_t risc_code01[] = { 0x00002000, 0x0401f004, 0x59a80812, 0x82040d40, 0x00001000, 0x4807504e, 0x59a8084a, 0x800409c0, 0x04020007, 0x42000800, 0x000007d0, 0x42001000, - 0x00103f62, 0x0201f800, 0x00105da7, 0x1c01f000, - 0x4807c856, 0x0401ff40, 0x0201f800, 0x0010698c, - 0x4df00000, 0x0201f800, 0x00106b71, 0x5c03e000, - 0x02000800, 0x00106982, 0x59c400a4, 0x82000500, + 0x00104148, 0x0201f800, 0x0010606e, 0x1c01f000, + 0x4807c856, 0x0401ff4e, 0x0201f800, 0x00106c55, + 0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, 0x00000002, 0x0402000a, 0x42006000, 0xffffffff, 0x42006800, 0x00200000, - 0x0401f8b5, 0x42006000, 0xffdfffff, 0x41786800, - 0x0401f8b1, 0x0201f800, 0x00104e13, 0x04000014, - 0x0201f800, 0x00104e23, 0x04020011, 0x4a035032, - 0x0000aaaa, 0x4c040000, 0x0201f800, 0x00101694, + 0x0401f8ad, 0x42006000, 0xffdfffff, 0x41786800, + 0x0401f8a9, 0x0201f800, 0x00105141, 0x04000014, + 0x0201f800, 0x00105151, 0x04020011, 0x4a035032, + 0x0000aaaa, 0x4c040000, 0x0201f800, 0x0010162a, 0x59a8002a, 0x82000500, 0xffff0000, 0x80040540, 0x4803502a, 0x5c000800, 0x4a035033, 0x00000000, - 0x0201f800, 0x00104d76, 0x0401f008, 0x4a03504c, + 0x0201f800, 0x001050a2, 0x0401f008, 0x4a03504c, 0x00000005, 0x42000000, 0x00000001, 0x0201f800, - 0x001015fa, 0x0401ff1e, 0x1c01f000, 0x0401f809, - 0x42006000, 0xbf7f7fff, 0x41786800, 0x0401f08e, - 0x42006000, 0xbf7f7fff, 0x41786800, 0x0401f08a, - 0x0201f800, 0x00104e23, 0x04020009, 0x59c40006, - 0x82000540, 0x000000f0, 0x48038806, 0x42006000, - 0xbfffffff, 0x41786800, 0x0401f87f, 0x1c01f000, + 0x00101590, 0x0401ff2c, 0x1c01f000, 0x0401f805, + 0x42006000, 0xbf7f7fff, 0x41786800, 0x0401f086, + 0x0201f800, 0x00105151, 0x04020005, 0x59c40006, + 0x82000540, 0x000000f0, 0x48038806, 0x1c01f000, 0x800408d0, 0x59a80015, 0x8c000506, 0x04000006, 0x59a80010, 0x82000500, 0x000000ff, 0x80040540, 0x0401f003, 0x82040540, 0x000000f7, 0x480388a7, - 0x1c01f000, 0x4807c856, 0x42000000, 0x0010b639, - 0x0201f800, 0x0010a86e, 0x42003000, 0x00000005, + 0x1c01f000, 0x4807c856, 0x42000000, 0x0010b83b, + 0x0201f800, 0x0010aa47, 0x42003000, 0x00000005, 0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000d, 0x42027800, 0x00000002, 0x0401f038, 0x4807c856, - 0x42000000, 0x0010b66a, 0x0201f800, 0x0010a86e, + 0x42000000, 0x0010b86b, 0x0201f800, 0x0010aa47, 0x42003000, 0x00000000, 0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000f, 0x42027800, 0x00000002, - 0x0401f02a, 0x4807c856, 0x42000000, 0x0010b669, - 0x0201f800, 0x0010a86e, 0x42003000, 0x00000003, + 0x0401f02a, 0x4807c856, 0x42000000, 0x0010b86a, + 0x0201f800, 0x0010aa47, 0x42003000, 0x00000003, 0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000e, 0x42027800, 0x00000202, 0x0401f01c, 0x4807c856, - 0x42000000, 0x0010b668, 0x0201f800, 0x0010a86e, + 0x42000000, 0x0010b869, 0x0201f800, 0x0010aa47, 0x42003000, 0x00000004, 0x4d3c0000, 0x4c180000, 0x42003000, 0x00000010, 0x42027800, 0x00000202, - 0x0401f00e, 0x4807c856, 0x42000000, 0x0010b63c, - 0x0201f800, 0x0010a86e, 0x42003000, 0x00000001, + 0x0401f00e, 0x4807c856, 0x42000000, 0x0010b83e, + 0x0201f800, 0x0010aa47, 0x42003000, 0x00000001, 0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000c, 0x42027800, 0x00000202, 0x42001800, 0x0000ffff, - 0x42002000, 0x00000007, 0x0201f800, 0x001038c7, - 0x5c003000, 0x4d400000, 0x0201f800, 0x0010a784, - 0x42028000, 0x0000002a, 0x0201f800, 0x00101d90, + 0x42002000, 0x00000007, 0x0201f800, 0x00103aae, + 0x5c003000, 0x4d400000, 0x0201f800, 0x0010a95d, + 0x42028000, 0x0000002a, 0x0201f800, 0x00101fe5, 0x5c028000, 0x5c027800, 0x1c01f000, 0x4807c856, - 0x04011000, 0x4a03c840, 0x0010b349, 0x4a03c842, + 0x04011000, 0x4a03c840, 0x0010b54b, 0x4a03c842, 0x00000040, 0x40000000, 0x040117ff, 0x42007800, - 0x0010b349, 0x46007800, 0x00000011, 0x803c7800, + 0x0010b54b, 0x46007800, 0x00000011, 0x803c7800, 0x4a007800, 0x220000ef, 0x4a007801, 0x000000ef, 0x4a007802, 0x01380000, 0x4a007803, 0x00000000, 0x4a007804, 0xffffffff, 0x4a007805, 0x00000000, @@ -4188,27 +4304,27 @@ uint32_t risc_code01[] = { 0x42000000, 0x00000006, 0x80000040, 0x040207ff, 0x0401f7f4, 0x1c01f000, 0x4c5c0000, 0x4c600000, 0x59c4b805, 0x485fc856, 0x8c5cbd3a, 0x04020005, - 0x42000000, 0x0010b616, 0x0201f800, 0x0010a86e, - 0x4a038805, 0x02000000, 0x0201f800, 0x00101a59, - 0x4000c000, 0x0201f800, 0x001019d0, 0x4a038805, + 0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47, + 0x4a038805, 0x02000000, 0x0201f800, 0x001019fe, + 0x4000c000, 0x0201f800, 0x00101963, 0x4a038805, 0x04000000, 0x5c00c000, 0x5c00b800, 0x1c01f000, - 0x497a6a00, 0x4a026c00, 0x00000707, 0x497a6801, - 0x497a6808, 0x497a6809, 0x497a6806, 0x497a6807, - 0x497a6c0b, 0x497a680c, 0x0201f800, 0x0010393e, - 0x04020006, 0x5934080f, 0x59340010, 0x80040540, - 0x02020800, 0x00100615, 0x4a026a04, 0x00000100, - 0x497a6a03, 0x59340402, 0x82000500, 0x000000ff, - 0x48026c02, 0x497a6c04, 0x497a6a05, 0x497a6c05, - 0x497a6811, 0x4d2c0000, 0x5934000d, 0x49466c03, - 0x80025d40, 0x04000004, 0x0201f800, 0x00100843, - 0x497a680d, 0x5c025800, 0x599c0401, 0x48026a0b, - 0x599c0208, 0x48026c12, 0x4a02680a, 0x00006000, - 0x0201f000, 0x00104acf, 0x42000000, 0x00000005, - 0x80000d80, 0x0401f02d, 0x0201f800, 0x00104858, + 0x497a6a00, 0x4937c857, 0x4a026c00, 0x00000707, + 0x497a6801, 0x497a6808, 0x497a6809, 0x497a6806, + 0x497a6807, 0x497a6c0b, 0x497a680c, 0x0201f800, + 0x00103b25, 0x04020006, 0x5934080f, 0x59340010, + 0x80040540, 0x02020800, 0x001005d8, 0x4a026a04, + 0x00000100, 0x497a6a03, 0x59340402, 0x82000500, + 0x000000ff, 0x48026c02, 0x497a6c04, 0x497a6a05, + 0x497a6c05, 0x497a6811, 0x4d2c0000, 0x5934000d, + 0x49466c03, 0x80025d40, 0x04000004, 0x0201f800, + 0x001007fd, 0x497a680d, 0x5c025800, 0x599c0401, + 0x48026a0b, 0x599c0208, 0x48026c12, 0x497a680a, + 0x0201f000, 0x00104c62, 0x42000000, 0x00000005, + 0x80000d80, 0x0401f02d, 0x0201f800, 0x00104a09, 0x04020017, 0x59a80026, 0x8c00050a, 0x04020010, 0x59340212, 0x82000500, 0x0000ff00, 0x4803c857, 0x0400000b, 0x59340a00, 0x8c040d1e, 0x02000000, - 0x000201f8, 0x42000000, 0x00000029, 0x42000800, + 0x000201c4, 0x42000000, 0x00000029, 0x42000800, 0x00001000, 0x492fc857, 0x0401f018, 0x492fc857, 0x42000000, 0x00000028, 0x0401f012, 0x59a80805, 0x8c040d02, 0x04020003, 0x8c040d00, 0x04000004, @@ -4217,25 +4333,25 @@ uint32_t risc_code01[] = { 0x492fc857, 0x42000800, 0x00001000, 0x0401f003, 0x492fc857, 0x80000d80, 0x4803c857, 0x80028540, 0x1c01f000, 0x4803c857, 0x59a80005, 0x8c000500, - 0x040207ec, 0x0201f800, 0x00104836, 0x040207e4, + 0x040207ec, 0x0201f800, 0x001049e7, 0x040207e4, 0x59340200, 0x8c00050e, 0x040007e1, 0x0201f000, - 0x000201f8, 0x0201f800, 0x00104639, 0x040007bf, - 0x0201f000, 0x000201fc, 0x592c0206, 0x492fc857, + 0x000201c4, 0x0201f800, 0x001047eb, 0x040007bf, + 0x0201f000, 0x000201c8, 0x592c0206, 0x492fc857, 0x82000d80, 0x000007ff, 0x04020006, 0x4a025c0a, - 0x00000030, 0x42026800, 0x0010b320, 0x0401f021, + 0x00000030, 0x42026800, 0x0010b524, 0x0401f021, 0x82000c80, 0x000007f0, 0x04021046, 0x81ac0400, 0x50000000, 0x80026d40, 0x04000038, 0x0201f800, - 0x00104732, 0x04020038, 0x592c040a, 0x8c00050a, - 0x04020014, 0x592e6009, 0x83300480, 0x0010cfc0, + 0x001048e3, 0x04020038, 0x592c040a, 0x8c00050a, + 0x04020014, 0x592e6009, 0x83300480, 0x0010d1c0, 0x0400103b, 0x41580000, 0x81300480, 0x04021038, 0x59300c06, 0x82040580, 0x00000009, 0x04020037, 0x4a025a06, 0x00000000, 0x497a5800, 0x59300008, 0x80000540, 0x04020018, 0x492e6008, 0x0401f010, - 0x0201f800, 0x00020892, 0x04000019, 0x592c0206, + 0x0201f800, 0x0002075a, 0x04000019, 0x592c0206, 0x49366009, 0x492e6008, 0x4a026406, 0x00000009, 0x497a6015, 0x49325809, 0x82000d80, 0x000007ff, 0x04020003, 0x4a026015, 0x00008000, 0x42027000, - 0x00000043, 0x0201f800, 0x000208d8, 0x80000580, + 0x00000043, 0x0201f800, 0x000207a1, 0x80000580, 0x0401f020, 0x40000800, 0x58040000, 0x80000d40, 0x040207fd, 0x492c0800, 0x0401f01a, 0x42000000, 0x0000002c, 0x0401f016, 0x42000000, 0x00000028, @@ -4246,207 +4362,198 @@ uint32_t risc_code01[] = { 0x040207fb, 0x42000000, 0x00000005, 0x80000540, 0x1c01f000, 0x492fc857, 0x592e8c06, 0x83440d80, 0x000007fc, 0x04000004, 0x83440480, 0x000007f0, - 0x04021014, 0x0201f800, 0x00020267, 0x04020011, - 0x0201f800, 0x00104842, 0x04020011, 0x0201f800, - 0x00020892, 0x0400001c, 0x49366009, 0x492e6008, + 0x04021014, 0x0201f800, 0x00020245, 0x04020011, + 0x0201f800, 0x001049f3, 0x04020011, 0x0201f800, + 0x0002075a, 0x0400001c, 0x49366009, 0x492e6008, 0x4a026406, 0x0000000a, 0x42027000, 0x00000040, - 0x0201f800, 0x000208d8, 0x80000580, 0x0401f011, + 0x0201f800, 0x000207a1, 0x80000580, 0x0401f011, 0x42000000, 0x00000028, 0x0401f00d, 0x0201f800, - 0x00104858, 0x040007fb, 0x59a80805, 0x82040d00, + 0x00104a09, 0x040007fb, 0x59a80805, 0x82040d00, 0x00000003, 0x04000004, 0x42000000, 0x00000004, 0x0401f003, 0x42000000, 0x00000029, 0x80000540, 0x1c01f000, 0x42000000, 0x0000002c, 0x0401f7fc, 0x492fc857, 0x592e8c06, 0x4947c857, 0x83440c80, - 0x00000800, 0x42000000, 0x0000000a, 0x0402119c, + 0x00000800, 0x42000000, 0x0000000a, 0x04021176, 0x592c4207, 0x4823c857, 0x82200500, 0x0000000f, - 0x0c01f001, 0x00104205, 0x0010428d, 0x001042dd, - 0x001042e8, 0x001042f3, 0x00104201, 0x00104201, - 0x00104201, 0x00104303, 0x00104361, 0x00104386, - 0x00104201, 0x00104201, 0x00104201, 0x00104201, - 0x00104201, 0x4803c857, 0x42000000, 0x0000000c, - 0x0401f183, 0x592c1008, 0x82081500, 0x00ffffff, + 0x0c01f001, 0x001043d5, 0x0010445d, 0x001044a9, + 0x001044b4, 0x001044bf, 0x001043d1, 0x001043d1, + 0x001043d1, 0x001044cf, 0x00104513, 0x00104530, + 0x001043d1, 0x001043d1, 0x001043d1, 0x001043d1, + 0x001043d1, 0x4803c857, 0x42000000, 0x0000000c, + 0x0401f15d, 0x592c1008, 0x82081500, 0x00ffffff, 0x59a80010, 0x80084d80, 0x42000000, 0x00000010, - 0x0400017b, 0x0201f800, 0x00104768, 0x04000036, + 0x04000155, 0x0201f800, 0x00104919, 0x04000036, 0x4803c857, 0x82004d80, 0x0000001d, 0x0402001a, - 0x0201f800, 0x00105439, 0x59340405, 0x4c000000, - 0x0201f800, 0x00104836, 0x5c000000, 0x04000004, + 0x0201f800, 0x00105755, 0x59340405, 0x4c000000, + 0x0201f800, 0x001049e7, 0x5c000000, 0x04000004, 0x8c20450a, 0x04000028, 0x80000580, 0x44002800, 0x59340008, 0x48002802, 0x59340009, 0x48002801, 0x59340006, 0x48002804, 0x59340007, 0x48002803, - 0x4200b000, 0x00000005, 0x0201f800, 0x00109328, - 0x0401f18c, 0x4803c857, 0x82004d80, 0x0000001a, - 0x04020003, 0x40101000, 0x0401f15c, 0x4803c857, + 0x4200b000, 0x00000005, 0x0201f800, 0x0010955f, + 0x0401f166, 0x4803c857, 0x82004d80, 0x0000001a, + 0x04020003, 0x40101000, 0x0401f136, 0x4803c857, 0x82004d80, 0x0000001b, 0x04020003, 0x40181000, - 0x0401f156, 0x4803c857, 0x82004d80, 0x0000001c, - 0x04000157, 0x82004d80, 0x00000019, 0x42000000, - 0x0000000a, 0x04000146, 0x42000000, 0x0000000a, - 0x0402015d, 0x59a8006f, 0x8c000502, 0x0400001b, - 0x0201f800, 0x00104836, 0x04000018, 0x59340212, + 0x0401f130, 0x4803c857, 0x82004d80, 0x0000001c, + 0x04000131, 0x82004d80, 0x00000019, 0x42000000, + 0x0000000a, 0x04000120, 0x42000000, 0x0000000a, + 0x04020137, 0x59a80005, 0x8c000514, 0x0400001b, + 0x0201f800, 0x001049e7, 0x04000018, 0x59340212, 0x82000500, 0x0000ff00, 0x42001000, 0x00000010, 0x0402000c, 0x42001000, 0x00000008, 0x59a80026, 0x8c000506, 0x04020009, 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000, 0x04000007, - 0x0201f800, 0x00104ada, 0x42000000, 0x0000001c, - 0x40181000, 0x0402012d, 0x0201f800, 0x00020892, - 0x04000137, 0x49366009, 0x492e6008, 0x4a026406, + 0x0201f800, 0x00104c6d, 0x42000000, 0x0000001c, + 0x40181000, 0x04020107, 0x0201f800, 0x0002075a, + 0x04000111, 0x49366009, 0x492e6008, 0x4a026406, 0x00000001, 0x8c20450a, 0x04000004, 0x592c0404, 0x8400055c, 0x48025c04, 0x4c200000, 0x4d3c0000, - 0x42027800, 0x00001800, 0x0201f800, 0x00101de2, + 0x42027800, 0x00001000, 0x0201f800, 0x0010203c, 0x5c027800, 0x5c004000, 0x8c204512, 0x0400000b, 0x599c0018, 0x8c000518, 0x04000008, 0x592c0009, 0x82000500, 0x00000380, 0x5934080a, 0x80040d40, - 0x84040d54, 0x4806680a, 0x417a7800, 0x0401f93a, - 0x42000800, 0x00000003, 0x0401f941, 0x42027000, - 0x00000002, 0x0201f800, 0x000208d8, 0x80000580, - 0x0401f130, 0x0201f800, 0x00020267, 0x04020112, - 0x0201f800, 0x0010483c, 0x0400000c, 0x0201f800, - 0x00104836, 0x04020112, 0x4c600000, 0x4178c000, - 0x42027800, 0x00001800, 0x417a6000, 0x0201f800, - 0x00101e48, 0x5c00c000, 0x59a8006f, 0x8c000502, - 0x0400001b, 0x0201f800, 0x00104836, 0x04000018, + 0x84040d54, 0x4806680a, 0x417a7800, 0x0401f914, + 0x42000800, 0x00000003, 0x0401f91b, 0x42027000, + 0x00000002, 0x0201f800, 0x000207a1, 0x80000580, + 0x0401f10a, 0x0201f800, 0x00020245, 0x040200ec, + 0x0201f800, 0x001049ed, 0x04000008, 0x0201f800, + 0x001049e7, 0x040200ec, 0x417a7800, 0x417a6000, + 0x0201f800, 0x001020a1, 0x59a80005, 0x8c000514, + 0x0400001b, 0x0201f800, 0x001049e7, 0x04000018, 0x59340212, 0x82000500, 0x0000ff00, 0x42001000, 0x00000010, 0x0402000c, 0x42001000, 0x00000008, 0x59a80026, 0x8c000506, 0x04020009, 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000, - 0x04000007, 0x0201f800, 0x00104ada, 0x42000000, - 0x0000001c, 0x40181000, 0x040200d4, 0x0201f800, - 0x00020892, 0x040000de, 0x5934080a, 0x8c204512, + 0x04000007, 0x0201f800, 0x00104c6d, 0x42000000, + 0x0000001c, 0x40181000, 0x040200b2, 0x0201f800, + 0x0002075a, 0x040000bc, 0x5934080a, 0x8c204512, 0x0400000c, 0x599c0018, 0x8c000518, 0x04000009, 0x592c0009, 0x82000500, 0x00000380, 0x82041500, 0xfffffc7f, 0x80080d40, 0x84040d54, 0x0401f002, 0x84040d14, 0x4806680a, 0x49366009, 0x492e6008, - 0x4a026406, 0x00000001, 0x417a7800, 0x0401f8ea, - 0x42000800, 0x00000005, 0x0401f8f1, 0x42027000, - 0x00000003, 0x0201f800, 0x000208d8, 0x80000580, - 0x0401f0e0, 0x0201f800, 0x00020267, 0x040200c2, - 0x0201f800, 0x0010484b, 0x040200c5, 0x0201f800, - 0x001092e0, 0x040000b6, 0x80000580, 0x0401f0d5, - 0x0201f800, 0x00020267, 0x040200b7, 0x0201f800, - 0x0010484b, 0x040200ba, 0x0201f800, 0x00108ea3, - 0x040000ab, 0x80000580, 0x0401f0ca, 0x0201f800, - 0x00020267, 0x040200ac, 0x83444d80, 0x000007fe, - 0x42000000, 0x0000000a, 0x0402008d, 0x0201f800, - 0x00104836, 0x040200aa, 0x0201f800, 0x001092f8, - 0x0400009b, 0x80000580, 0x0401f0ba, 0x82200500, + 0x4a026406, 0x00000001, 0x417a7800, 0x0401f8c8, + 0x42000800, 0x00000005, 0x0401f8cf, 0x42027000, + 0x00000003, 0x0201f800, 0x000207a1, 0x80000580, + 0x0401f0be, 0x0201f800, 0x00020245, 0x040200a0, + 0x0201f800, 0x001049fc, 0x040200a3, 0x0201f800, + 0x00109517, 0x04000094, 0x80000580, 0x0401f0b3, + 0x0201f800, 0x00020245, 0x04020095, 0x0201f800, + 0x001049fc, 0x04020098, 0x0201f800, 0x001090e6, + 0x04000089, 0x80000580, 0x0401f0a8, 0x0201f800, + 0x00020245, 0x0402008a, 0x83444d80, 0x000007fe, + 0x42000000, 0x0000000a, 0x0402006b, 0x0201f800, + 0x001049e7, 0x04020088, 0x0201f800, 0x0010952f, + 0x04000079, 0x80000580, 0x0401f098, 0x82200500, 0x00000070, 0x04020005, 0x8c20450e, 0x42000000, - 0x0000000c, 0x0402007e, 0x8c20450a, 0x0400000d, + 0x0000000c, 0x0402005c, 0x8c20450a, 0x0400000d, 0x4d3c0000, 0x42027800, 0x00001000, 0x8c20450e, 0x04020002, 0x853e7d56, 0x82200500, 0x000000a0, - 0x0201f800, 0x00104822, 0x5c027800, 0x0401f0a1, - 0x8c204508, 0x04020024, 0x592c1008, 0x82081500, - 0x00ffffff, 0x59a80010, 0x80084d80, 0x42000000, - 0x00000010, 0x04000066, 0x0201f800, 0x00104768, - 0x0400002b, 0x4803c857, 0x82004d80, 0x0000001a, - 0x04020003, 0x40101000, 0x0401f064, 0x4803c857, - 0x82004d80, 0x0000001b, 0x04020003, 0x40181000, - 0x0401f05e, 0x4803c857, 0x82004d80, 0x0000001c, - 0x0400005f, 0x82004d80, 0x00000019, 0x42000000, - 0x0000000a, 0x0400004e, 0x42000000, 0x0000000a, - 0x0401f065, 0x0201f800, 0x00020267, 0x04020062, - 0x4d3c0000, 0x42027800, 0x00001000, 0x8c20450e, - 0x04020002, 0x853e7d56, 0x82200500, 0x00000090, - 0x0201f800, 0x0010480a, 0x5c027800, 0x42000000, - 0x0000000a, 0x0402003a, 0x0401f06a, 0x836c0580, - 0x00000003, 0x42000800, 0x00000007, 0x04020006, - 0x0201f800, 0x0010928e, 0x04000007, 0x80000580, - 0x0401f064, 0x0201f800, 0x00104871, 0x04000059, - 0x0401f05c, 0x0201f800, 0x00104871, 0x0400003c, - 0x0401f058, 0x0201f800, 0x00020267, 0x0402003e, - 0x836c0580, 0x00000003, 0x04020048, 0x8c204508, - 0x0400000a, 0x4c600000, 0x4178c000, 0x42027800, - 0x00001800, 0x417a6000, 0x0201f800, 0x00101e48, - 0x5c00c000, 0x0401f047, 0x0201f800, 0x0010483c, - 0x0400000c, 0x0201f800, 0x00104836, 0x04020030, - 0x4c600000, 0x4178c000, 0x42027800, 0x00001800, - 0x417a6000, 0x0201f800, 0x00101e48, 0x5c00c000, - 0x480bc856, 0x0201f800, 0x001090f8, 0x04000018, - 0x80000580, 0x0401f037, 0x0401f7db, 0x480bc857, - 0x42000800, 0x00000019, 0x40001000, 0x4200b000, - 0x00000002, 0x0401f00a, 0x480bc857, 0x40000800, - 0x4200b000, 0x00000002, 0x0401f005, 0x480bc857, - 0x40000800, 0x4200b000, 0x00000001, 0x480bc857, - 0x42028000, 0x00000031, 0x0401f020, 0x480bc857, - 0x42000800, 0x00000003, 0x4200b000, 0x00000001, - 0x0401f7f7, 0x480bc857, 0x42000800, 0x0000000a, - 0x4200b000, 0x00000001, 0x0401f7f1, 0x480bc857, - 0x42000800, 0x00000009, 0x40001000, 0x4200b000, - 0x00000002, 0x0401f7ea, 0x480bc857, 0x42000800, - 0x00000007, 0x4200b000, 0x00000001, 0x0401f7e4, - 0x480bc857, 0x4200b000, 0x00000001, 0x0401f7e0, - 0x80028580, 0x4178b000, 0x82000540, 0x00000001, - 0x1c01f000, 0x4937c857, 0x59326809, 0x59341200, - 0x813e79c0, 0x04000003, 0x84081540, 0x0401f002, - 0x84081500, 0x480a6a00, 0x1c01f000, 0x59326809, - 0x5c000000, 0x4c000000, 0x4803c857, 0x4937c857, - 0x82040580, 0x00000006, 0x04020004, 0x42000000, - 0x00000606, 0x0401f021, 0x82040580, 0x00000004, - 0x04020004, 0x42000000, 0x00000404, 0x0401f01b, - 0x82040580, 0x00000007, 0x42000000, 0x00000707, - 0x04000016, 0x82040580, 0x00000003, 0x42000000, - 0x00000703, 0x04000011, 0x82040580, 0x00000005, - 0x42000000, 0x00000405, 0x0400000c, 0x82040580, - 0x00000009, 0x42000000, 0x00000409, 0x04000007, - 0x82040580, 0x0000000b, 0x42000000, 0x0000070b, - 0x02020800, 0x00100615, 0x4803c857, 0x48026c00, - 0x82040d80, 0x00000006, 0x04020005, 0x59341404, - 0x800811c0, 0x02000800, 0x00100615, 0x1c01f000, - 0x5c000000, 0x4c000000, 0x4803c857, 0x4947c857, - 0x481bc857, 0x83440480, 0x00000800, 0x04021034, - 0x83441400, 0x0010aa00, 0x50080000, 0x80026d40, - 0x04020011, 0x4c180000, 0x4d2c0000, 0x0201f800, - 0x00100819, 0x412e6800, 0x5c025800, 0x5c003000, - 0x04000027, 0x45341000, 0x497a680d, 0x497a6810, - 0x497a680f, 0x497a680e, 0x4c180000, 0x0401fccd, - 0x5c003000, 0x59340a12, 0x4c040000, 0x0201f800, - 0x00104e0d, 0x5c000800, 0x04000009, 0x82180500, - 0x00ffff00, 0x04000008, 0x59a81010, 0x82081500, - 0x00ffff00, 0x80080580, 0x04000003, 0x80000580, - 0x0401f004, 0x82180500, 0x000000ff, 0x800000d0, - 0x80040d80, 0x04000003, 0x4803c857, 0x48026a12, - 0x59340002, 0x80180580, 0x04000003, 0x481bc857, - 0x481a6802, 0x80000580, 0x1c01f000, 0x4803c856, - 0x82000540, 0x00000001, 0x0401f7fc, 0x4947c857, - 0x83440480, 0x00000800, 0x04021011, 0x83441400, - 0x0010aa00, 0x50080000, 0x80026d40, 0x0400000b, - 0x0401fbf2, 0x0402000a, 0x59a80005, 0x8c000502, - 0x04000004, 0x59340200, 0x8c00050e, 0x04000004, - 0x82000540, 0x00000001, 0x1c01f000, 0x80000580, - 0x0401f7fe, 0x5c000000, 0x4c000000, 0x4803c857, - 0x4947c857, 0x4d2c0000, 0x4d300000, 0x83440480, - 0x00000800, 0x04021024, 0x83441400, 0x0010aa00, - 0x50080000, 0x80026d40, 0x0400001b, 0x45781000, - 0x5934000d, 0x80025d40, 0x02020800, 0x00100843, - 0x59366011, 0x813261c0, 0x0400000e, 0x4c640000, - 0x5930c800, 0x59325808, 0x0201f800, 0x00108df4, - 0x02020800, 0x00100843, 0x0201f800, 0x000208b4, - 0x82666540, 0x00000000, 0x040207f6, 0x5c00c800, - 0x0201f800, 0x00104acf, 0x41365800, 0x0201f800, - 0x0010083b, 0x80000580, 0x5c026000, 0x5c025800, - 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fb, - 0x4937c857, 0x4c580000, 0x59cc0001, 0x82000500, - 0x00ffffff, 0x48026802, 0x497a6c01, 0x497a6a01, - 0x59340200, 0x84000502, 0x48026a00, 0x0201f800, - 0x00104e0d, 0x04020017, 0x59340403, 0x82000580, - 0x000007fe, 0x04000005, 0x59a80026, 0x8c00050a, - 0x04020010, 0x0401f008, 0x59cc0408, 0x8c000518, - 0x0400000c, 0x59cc0009, 0x48035035, 0x59cc000a, - 0x48035036, 0x59cc0207, 0x80000540, 0x04020003, - 0x42000000, 0x00000001, 0x48038893, 0x4803501e, - 0x59cc0a09, 0x82040d00, 0x00000010, 0x59cc0408, - 0x82000500, 0x00000020, 0x04000002, 0x84040d40, - 0x5934000a, 0x82000500, 0xffffffee, 0x80040540, - 0x4802680a, 0x83cca400, 0x0000000b, 0x8334ac00, - 0x00000006, 0x4200b000, 0x00000002, 0x0201f800, - 0x0010a93e, 0x83cca400, 0x0000000d, 0x8334ac00, - 0x00000008, 0x4200b000, 0x00000002, 0x0201f800, - 0x0010a93e, 0x59cc0a18, 0x82040480, 0x00000800, - 0x0402100c, 0x82040480, 0x00000400, 0x04001004, - 0x42000800, 0x00000400, 0x0401f006, 0x82040480, - 0x00000200, 0x04001003, 0x42000800, 0x00000200, - 0x42001000, 0x0010b33f, 0x58080202, 0x80041480, - 0x04001002, 0x40000800, 0x48066a04, 0x59340403, + 0x0201f800, 0x001049d3, 0x5c027800, 0x0401f07f, + 0x0201f800, 0x00020245, 0x04020065, 0x8c204508, + 0x04000010, 0x4d3c0000, 0x42027800, 0x00001000, + 0x8c20450e, 0x04020002, 0x853e7d56, 0x82200500, + 0x00000090, 0x0201f800, 0x001049bb, 0x5c027800, + 0x42000000, 0x0000000a, 0x0402003b, 0x0401f06b, + 0x836c0580, 0x00000003, 0x42000800, 0x00000007, + 0x0402000f, 0x0201f800, 0x001049f3, 0x04000007, + 0x4c000000, 0x0201f800, 0x00104a1f, 0x5c000000, + 0x0400004d, 0x0401f05d, 0x0201f800, 0x001094c5, + 0x04000007, 0x80000580, 0x0401f05c, 0x0201f800, + 0x00104a1f, 0x04000051, 0x0401f054, 0x0201f800, + 0x00104a1f, 0x04000034, 0x0401f050, 0x0201f800, + 0x00020245, 0x04020036, 0x836c0580, 0x00000003, + 0x04020040, 0x8c204508, 0x04000006, 0x417a7800, + 0x417a6000, 0x0201f800, 0x001020a1, 0x0401f043, + 0x0201f800, 0x001049ed, 0x04000008, 0x0201f800, + 0x001049e7, 0x0402002c, 0x417a7800, 0x417a6000, + 0x0201f800, 0x001020a1, 0x480bc856, 0x0201f800, + 0x00109332, 0x04000018, 0x80000580, 0x0401f037, + 0x0401f7e3, 0x480bc857, 0x42000800, 0x00000019, + 0x40001000, 0x4200b000, 0x00000002, 0x0401f00a, + 0x480bc857, 0x40000800, 0x4200b000, 0x00000002, + 0x0401f005, 0x480bc857, 0x40000800, 0x4200b000, + 0x00000001, 0x480bc857, 0x42028000, 0x00000031, + 0x0401f020, 0x480bc857, 0x42000800, 0x00000003, + 0x4200b000, 0x00000001, 0x0401f7f7, 0x480bc857, + 0x42000800, 0x0000000a, 0x4200b000, 0x00000001, + 0x0401f7f1, 0x480bc857, 0x42000800, 0x00000009, + 0x40001000, 0x4200b000, 0x00000002, 0x0401f7ea, + 0x480bc857, 0x42000800, 0x00000007, 0x4200b000, + 0x00000001, 0x0401f7e4, 0x480bc857, 0x4200b000, + 0x00000001, 0x0401f7e0, 0x80028580, 0x4178b000, + 0x82000540, 0x00000001, 0x1c01f000, 0x4937c857, + 0x59326809, 0x59341200, 0x813e79c0, 0x04000003, + 0x84081540, 0x0401f002, 0x84081500, 0x480a6a00, + 0x1c01f000, 0x59326809, 0x5c000000, 0x4c000000, + 0x4803c857, 0x4937c857, 0x82040580, 0x00000006, + 0x04020004, 0x42000000, 0x00000606, 0x0401f021, + 0x82040580, 0x00000004, 0x04020004, 0x42000000, + 0x00000404, 0x0401f01b, 0x82040580, 0x00000007, + 0x42000000, 0x00000707, 0x04000016, 0x82040580, + 0x00000003, 0x42000000, 0x00000703, 0x04000011, + 0x82040580, 0x00000005, 0x42000000, 0x00000405, + 0x0400000c, 0x82040580, 0x00000009, 0x42000000, + 0x00000409, 0x04000007, 0x82040580, 0x0000000b, + 0x42000000, 0x0000070b, 0x02020800, 0x001005d8, + 0x4803c857, 0x48026c00, 0x82040d80, 0x00000006, + 0x04020005, 0x59341404, 0x800811c0, 0x02000800, + 0x001005d8, 0x1c01f000, 0x5c000000, 0x4c000000, + 0x4803c857, 0x4947c857, 0x481bc857, 0x83440480, + 0x00000800, 0x04021034, 0x83441400, 0x0010ac00, + 0x50080000, 0x80026d40, 0x04020011, 0x4c180000, + 0x4d2c0000, 0x0201f800, 0x001007d3, 0x412e6800, + 0x5c025800, 0x5c003000, 0x04000027, 0x45341000, + 0x497a680d, 0x497a6810, 0x497a680f, 0x497a680e, + 0x4c180000, 0x0401fcf3, 0x5c003000, 0x59340a12, + 0x4c040000, 0x0201f800, 0x0010513b, 0x5c000800, + 0x04000009, 0x82180500, 0x00ffff00, 0x04000008, + 0x59a81010, 0x82081500, 0x00ffff00, 0x80080580, + 0x04000003, 0x80000580, 0x0401f004, 0x82180500, + 0x000000ff, 0x800000d0, 0x80040d80, 0x04000003, + 0x4803c857, 0x48026a12, 0x59340002, 0x80180580, + 0x04000003, 0x481bc857, 0x481a6802, 0x80000580, + 0x1c01f000, 0x4803c856, 0x82000540, 0x00000001, + 0x0401f7fc, 0x4947c857, 0x83440480, 0x00000800, + 0x04021011, 0x83441400, 0x0010ac00, 0x50080000, + 0x80026d40, 0x0400000b, 0x0401fbf9, 0x0402000a, + 0x59a80005, 0x8c000502, 0x04000004, 0x59340200, + 0x8c00050e, 0x04000004, 0x82000540, 0x00000001, + 0x1c01f000, 0x80000580, 0x0401f7fe, 0x5c000000, + 0x4c000000, 0x4803c857, 0x4947c857, 0x4d2c0000, + 0x4d300000, 0x83440480, 0x00000800, 0x04021024, + 0x83441400, 0x0010ac00, 0x50080000, 0x80026d40, + 0x0400001b, 0x45781000, 0x5934000d, 0x80025d40, + 0x02020800, 0x001007fd, 0x59366011, 0x813261c0, + 0x0400000e, 0x4c640000, 0x5930c800, 0x59325808, + 0x0201f800, 0x00109037, 0x02020800, 0x001007fd, + 0x0201f800, 0x0002077d, 0x82666540, 0x00000000, + 0x040207f6, 0x5c00c800, 0x0201f800, 0x00104c62, + 0x41365800, 0x0201f800, 0x001007f5, 0x80000580, + 0x5c026000, 0x5c025800, 0x1c01f000, 0x82000540, + 0x00000001, 0x0401f7fb, 0x4937c857, 0x4c580000, + 0x59cc0001, 0x82000500, 0x00ffffff, 0x48026802, + 0x497a6c01, 0x497a6a01, 0x59340200, 0x84000502, + 0x48026a00, 0x0201f800, 0x0010513b, 0x04020017, + 0x59340403, 0x82000580, 0x000007fe, 0x04000005, + 0x59a80026, 0x8c00050a, 0x04020010, 0x0401f008, + 0x59cc0408, 0x8c000518, 0x0400000c, 0x59cc0009, + 0x48035035, 0x59cc000a, 0x48035036, 0x59cc0207, + 0x80000540, 0x04020003, 0x42000000, 0x00000001, + 0x48038893, 0x4803501e, 0x59cc0a09, 0x82040d00, + 0x00000010, 0x59cc0408, 0x82000500, 0x00000020, + 0x04000002, 0x84040d40, 0x5934000a, 0x82000500, + 0xffffffee, 0x80040540, 0x4802680a, 0x83cca400, + 0x0000000b, 0x8334ac00, 0x00000006, 0x4200b000, + 0x00000002, 0x0201f800, 0x0010ab17, 0x83cca400, + 0x0000000d, 0x8334ac00, 0x00000008, 0x4200b000, + 0x00000002, 0x0201f800, 0x0010ab17, 0x59cc0a18, + 0x82040480, 0x00000800, 0x0402100c, 0x82040480, + 0x00000400, 0x04001004, 0x42000800, 0x00000400, + 0x0401f006, 0x82040480, 0x00000200, 0x04001003, + 0x42000800, 0x00000200, 0x48066a04, 0x59340403, 0x82000580, 0x000007fe, 0x04020003, 0x59cc0a08, - 0x48066a04, 0x0201f800, 0x00104afd, 0x5c00b000, + 0x48066a04, 0x42000800, 0x00000004, 0x59cc1207, + 0x800811c0, 0x04000005, 0x82080480, 0x00000004, + 0x04021002, 0x40080800, 0x48066c04, 0x5c00b000, 0x1c01f000, 0x4937c857, 0x59a80026, 0x8c000508, 0x04000004, 0x84000556, 0x4803c857, 0x48035026, 0x59cc0207, 0x4803c857, 0x48026a05, 0x59cc020a, @@ -4466,15 +4573,15 @@ uint32_t risc_code01[] = { 0x4c580000, 0x5934000d, 0x80025d40, 0x04000029, 0x592c0003, 0x82000480, 0x00000008, 0x0400100b, 0x412cb800, 0x592c0001, 0x80025d40, 0x040207f9, - 0x0201f800, 0x0010082a, 0x04000037, 0x492fc857, + 0x0201f800, 0x001007e4, 0x04000037, 0x492fc857, 0x492cb801, 0x0401f020, 0x832c0c00, 0x00000004, 0x4200b000, 0x00000008, 0x50040000, 0x82000580, 0xffffffff, 0x04020006, 0x80041000, 0x50080000, 0x82000580, 0xffffffff, 0x04000007, 0x82040c00, 0x00000002, 0x8058b040, 0x040207f4, 0x0201f800, - 0x00100615, 0x45480800, 0x454c1000, 0x592c1803, + 0x001005d8, 0x45480800, 0x454c1000, 0x592c1803, 0x800c1800, 0x480e5803, 0x480fc857, 0x0401f014, - 0x0201f800, 0x0010082a, 0x04000017, 0x492fc857, + 0x0201f800, 0x001007e4, 0x04000017, 0x492fc857, 0x492e680d, 0x497a5802, 0x4a025803, 0x00000001, 0x494a5804, 0x494e5805, 0x832c0c00, 0x00000006, 0x4200b000, 0x0000000e, 0x46000800, 0xffffffff, @@ -4483,311 +4590,307 @@ uint32_t risc_code01[] = { 0x1c01f000, 0x80000580, 0x0401f7fb, 0x4803c856, 0x4d3c0000, 0x4d2c0000, 0x5934000d, 0x80025d40, 0x0400001f, 0x592c0002, 0x80000540, 0x0402001f, - 0x412e7800, 0x0401f8c8, 0x0402001c, 0x46000800, + 0x412e7800, 0x0401f8ce, 0x0402001c, 0x46000800, 0xffffffff, 0x46001000, 0xffffffff, 0x4813c857, 0x480fc857, 0x580c0003, 0x82000c80, 0x00000002, 0x04021014, 0x480fc857, 0x400c0000, 0x812c0580, 0x04020004, 0x580c0001, 0x4802680d, 0x0401f003, 0x580c0001, 0x48002001, 0x400e5800, 0x0201f800, - 0x0010083a, 0x82000540, 0x00000001, 0x5c025800, + 0x001007f4, 0x82000540, 0x00000001, 0x5c025800, 0x5c027800, 0x1c01f000, 0x80000580, 0x0401f7fc, 0x80000040, 0x48001803, 0x4803c857, 0x0401f7f6, - 0x0201f800, 0x00020087, 0x59300007, 0x8400054e, + 0x0201f800, 0x00020086, 0x59300007, 0x8400054e, 0x48026007, 0x592c1a04, 0x820c1d00, 0x000000ff, 0x820c0580, 0x00000048, 0x04000013, 0x0201f000, - 0x000202b0, 0x8c000500, 0x02020800, 0x000200e6, + 0x0002028e, 0x8c000500, 0x02020800, 0x000200e5, 0x4a026203, 0x00000002, 0x592c1a04, 0x820c1d00, 0x000000ff, 0x820c0580, 0x00000018, 0x02000000, - 0x000202b0, 0x820c0580, 0x00000048, 0x02020000, - 0x000202b0, 0x42000800, 0x80000804, 0x0201f800, - 0x00106466, 0x0201f000, 0x000202b9, 0x4a025a06, - 0x00000008, 0x0201f000, 0x00020381, 0x4a025a06, - 0x00000029, 0x0201f000, 0x00020381, 0x4a025a06, - 0x0000002a, 0x0201f000, 0x00020381, 0x4a025a06, - 0x00000028, 0x0201f000, 0x00020381, 0x4943c857, + 0x0002028e, 0x820c0580, 0x00000048, 0x02020000, + 0x0002028e, 0x42000800, 0x80000804, 0x0201f800, + 0x00106721, 0x0201f000, 0x00020297, 0x4a025a06, + 0x00000008, 0x0201f000, 0x000202da, 0x4a025a06, + 0x00000029, 0x0201f000, 0x000202da, 0x4a025a06, + 0x0000002a, 0x0201f000, 0x000202da, 0x4a025a06, + 0x00000028, 0x0201f000, 0x000202da, 0x4943c857, 0x4d440000, 0x4d340000, 0x4d2c0000, 0x4c580000, 0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800, - 0x00020267, 0x04020007, 0x8d3e7d06, 0x04000004, - 0x59340200, 0x8c00050e, 0x04020002, 0x0401f813, - 0x81468800, 0x8058b040, 0x040207f5, 0x83440480, - 0x00000800, 0x04021008, 0x8d3e7d02, 0x04000006, - 0x42028800, 0x000007f0, 0x4200b000, 0x00000010, - 0x0401f7eb, 0x5c00b000, 0x5c025800, 0x5c026800, - 0x5c028800, 0x1c01f000, 0x4d2c0000, 0x41783000, - 0x5936580f, 0x812e59c0, 0x04000029, 0x592c0204, - 0x82000500, 0x000000ff, 0x82000580, 0x00000012, - 0x04000020, 0x8d3e7d00, 0x04000003, 0x0401f83c, - 0x0402001c, 0x592c2000, 0x497a5800, 0x801831c0, - 0x04020009, 0x59340010, 0x812c0580, 0x04020004, - 0x497a680f, 0x497a6810, 0x0401f008, 0x4812680f, - 0x0401f006, 0x48103000, 0x59340010, 0x812c0580, - 0x04020002, 0x481a6810, 0x4a025a04, 0x00000103, - 0x49425a06, 0x497a5c09, 0x0201f800, 0x00108f7d, - 0x0201f800, 0x00020381, 0x40125800, 0x0401f7da, - 0x412c3000, 0x592e5800, 0x0401f7d7, 0x5c025800, - 0x1c01f000, 0x4803c856, 0x41781800, 0x5934000f, - 0x80025d40, 0x04000010, 0x592c0005, 0x80200580, - 0x592c0000, 0x04000003, 0x412c1800, 0x0401f7f9, - 0x497a5800, 0x800c19c0, 0x04000008, 0x48001800, - 0x80000540, 0x04020004, 0x480e6810, 0x82000540, - 0x00000001, 0x1c01f000, 0x4802680f, 0x80000540, - 0x040207fd, 0x497a6810, 0x0401f7f9, 0x592c0008, - 0x81480580, 0x04020003, 0x592c0009, 0x814c0580, - 0x1c01f000, 0x4803c856, 0x4c580000, 0x413c1800, - 0x400c2000, 0x593c0002, 0x80000540, 0x04020018, - 0x4200b000, 0x00000008, 0x820c0c00, 0x00000004, - 0x50040000, 0x81480580, 0x04020005, 0x80041000, - 0x50080000, 0x814c0580, 0x0400000d, 0x82040c00, - 0x00000002, 0x8058b040, 0x040207f6, 0x400c2000, - 0x580c0001, 0x80001d40, 0x040207ee, 0x82000540, - 0x00000001, 0x5c00b000, 0x1c01f000, 0x80000580, - 0x0401f7fd, 0x4937c857, 0x4c580000, 0x4d2c0000, - 0x5934000d, 0x80025d40, 0x04020016, 0x0201f800, - 0x0010082a, 0x04000010, 0x492e680d, 0x4a025802, - 0x00000001, 0x497a5803, 0x832c0c00, 0x00000004, - 0x4200b000, 0x00000010, 0x46000800, 0xffffffff, - 0x80040800, 0x8058b040, 0x040207fc, 0x82000540, - 0x00000001, 0x5c025800, 0x5c00b000, 0x1c01f000, - 0x4d2c0000, 0x592e5801, 0x0201f800, 0x00100843, - 0x5c025800, 0x0401f7ea, 0x4d2c0000, 0x5936580d, - 0x812e59c0, 0x04000007, 0x4937c857, 0x497a680d, - 0x0201f800, 0x00100843, 0x82000540, 0x00000001, - 0x5c025800, 0x1c01f000, 0x59340405, 0x4937c857, - 0x4803c857, 0x8c000508, 0x1c01f000, 0x4803c856, - 0x0201f800, 0x00104e0d, 0x04000011, 0x59a80815, - 0x8c040d04, 0x0402000e, 0x59a80826, 0x8c040d06, - 0x0400000b, 0x83ac0400, 0x000007fe, 0x50000000, - 0x80026d40, 0x04000006, 0x0401f9a8, 0x04020004, - 0x59340200, 0x8400055a, 0x48026a00, 0x599c0017, - 0x8c000508, 0x04000015, 0x4200b000, 0x000007f0, - 0x417a8800, 0x0201f800, 0x00020267, 0x0402000c, - 0x0401f99a, 0x0402000a, 0x59a80010, 0x59340802, - 0x80040580, 0x82000500, 0x00ffff00, 0x04020004, - 0x59340200, 0x8400055a, 0x48026a00, 0x81468800, - 0x8058b040, 0x040207f0, 0x0401f885, 0x04000003, - 0x59a80836, 0x0401f006, 0x599c0017, 0x8c000508, + 0x00020245, 0x0402000d, 0x8d3e7d14, 0x04000005, + 0x59340212, 0x82000500, 0x0000ff00, 0x04000007, + 0x8d3e7d06, 0x04000004, 0x59340200, 0x8c00050e, + 0x04020002, 0x0401f813, 0x81468800, 0x8058b040, + 0x040207ef, 0x83440480, 0x00000800, 0x04021008, + 0x8d3e7d02, 0x04000006, 0x42028800, 0x000007f0, + 0x4200b000, 0x00000010, 0x0401f7e5, 0x5c00b000, + 0x5c025800, 0x5c026800, 0x5c028800, 0x1c01f000, + 0x4d2c0000, 0x41783000, 0x5936580f, 0x812e59c0, + 0x04000029, 0x592c0204, 0x82000500, 0x000000ff, + 0x82000580, 0x00000012, 0x04000020, 0x8d3e7d00, + 0x04000003, 0x0401f83c, 0x0402001c, 0x592c2000, + 0x497a5800, 0x801831c0, 0x04020009, 0x59340010, + 0x812c0580, 0x04020004, 0x497a680f, 0x497a6810, + 0x0401f008, 0x4812680f, 0x0401f006, 0x48103000, + 0x59340010, 0x812c0580, 0x04020002, 0x481a6810, + 0x4a025a04, 0x00000103, 0x49425a06, 0x497a5c09, + 0x0201f800, 0x001091c6, 0x0201f800, 0x000202da, + 0x40125800, 0x0401f7da, 0x412c3000, 0x592e5800, + 0x0401f7d7, 0x5c025800, 0x1c01f000, 0x4803c856, + 0x41781800, 0x5934000f, 0x80025d40, 0x04000010, + 0x592c0005, 0x80200580, 0x592c0000, 0x04000003, + 0x412c1800, 0x0401f7f9, 0x497a5800, 0x800c19c0, + 0x04000008, 0x48001800, 0x80000540, 0x04020004, + 0x480e6810, 0x82000540, 0x00000001, 0x1c01f000, + 0x4802680f, 0x80000540, 0x040207fd, 0x497a6810, + 0x0401f7f9, 0x592c0008, 0x81480580, 0x04020003, + 0x592c0009, 0x814c0580, 0x1c01f000, 0x4803c856, + 0x4c580000, 0x413c1800, 0x400c2000, 0x593c0002, + 0x80000540, 0x04020018, 0x4200b000, 0x00000008, + 0x820c0c00, 0x00000004, 0x50040000, 0x81480580, + 0x04020005, 0x80041000, 0x50080000, 0x814c0580, + 0x0400000d, 0x82040c00, 0x00000002, 0x8058b040, + 0x040207f6, 0x400c2000, 0x580c0001, 0x80001d40, + 0x040207ee, 0x82000540, 0x00000001, 0x5c00b000, + 0x1c01f000, 0x80000580, 0x0401f7fd, 0x4937c857, + 0x4c580000, 0x4d2c0000, 0x5934000d, 0x80025d40, + 0x04020016, 0x0201f800, 0x001007e4, 0x04000010, + 0x492e680d, 0x4a025802, 0x00000001, 0x497a5803, + 0x832c0c00, 0x00000004, 0x4200b000, 0x00000010, + 0x46000800, 0xffffffff, 0x80040800, 0x8058b040, + 0x040207fc, 0x82000540, 0x00000001, 0x5c025800, + 0x5c00b000, 0x1c01f000, 0x4d2c0000, 0x592e5801, + 0x0201f800, 0x001007fd, 0x5c025800, 0x0401f7ea, + 0x4d2c0000, 0x5936580d, 0x812e59c0, 0x04000007, + 0x4937c857, 0x497a680d, 0x0201f800, 0x001007fd, + 0x82000540, 0x00000001, 0x5c025800, 0x1c01f000, + 0x59340405, 0x4937c857, 0x4803c857, 0x8c000508, + 0x1c01f000, 0x4803c856, 0x0201f800, 0x0010513b, + 0x04000011, 0x59a80815, 0x8c040d04, 0x0402000e, + 0x59a80826, 0x8c040d06, 0x0400000b, 0x83ac0400, + 0x000007fe, 0x50000000, 0x80026d40, 0x04000006, + 0x0401f9a7, 0x04020004, 0x59340200, 0x8400055a, + 0x48026a00, 0x599c0017, 0x8c000508, 0x04000015, + 0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800, + 0x00020245, 0x0402000c, 0x0401f999, 0x0402000a, + 0x59a80010, 0x59340802, 0x80040580, 0x82000500, + 0x00ffff00, 0x04020004, 0x59340200, 0x8400055a, + 0x48026a00, 0x81468800, 0x8058b040, 0x040207f0, + 0x0401f884, 0x04000003, 0x59a80836, 0x0401f006, + 0x599c0017, 0x8c000508, 0x04000007, 0x42000800, + 0x000007d0, 0x42001000, 0x00104876, 0x0201f800, + 0x0010606e, 0x1c01f000, 0x4803c856, 0x4d340000, + 0x4d440000, 0x4d3c0000, 0x4c580000, 0x42001000, + 0x00104876, 0x0201f800, 0x00105f90, 0x59a80826, + 0x8c040d06, 0x04000015, 0x0401f86a, 0x04000013, + 0x83ae6c00, 0x000007fe, 0x51366800, 0x59340200, + 0x8400051a, 0x48026a00, 0x599c0017, 0x8c000508, 0x04000007, 0x42000800, 0x000007d0, 0x42001000, - 0x001046c4, 0x0201f800, 0x00105da7, 0x1c01f000, - 0x4803c856, 0x4d300000, 0x4d340000, 0x4d440000, - 0x4d3c0000, 0x4c580000, 0x42001000, 0x001046c4, - 0x0201f800, 0x00105cc9, 0x59a80826, 0x8c040d06, - 0x04000015, 0x0401f86a, 0x04000013, 0x83ae6c00, - 0x000007fe, 0x51366800, 0x59340200, 0x8400051a, - 0x48026a00, 0x599c0017, 0x8c000508, 0x04000007, - 0x42000800, 0x000007d0, 0x42001000, 0x001046c4, - 0x0201f800, 0x00105da7, 0x0201f800, 0x00101bf0, - 0x0401f027, 0x4200b000, 0x000007f0, 0x80028d80, - 0x0201f800, 0x00020267, 0x0402001e, 0x59340200, - 0x8c00051a, 0x0400001b, 0x59368c03, 0x417a7800, - 0x42028000, 0x00000029, 0x41783000, 0x0201f800, - 0x0010a258, 0x59340200, 0x84000558, 0x8400051a, - 0x48026a00, 0x4937c857, 0x4a026c00, 0x00000707, - 0x42028000, 0x00000029, 0x0201f800, 0x001067f6, - 0x417a7800, 0x0201f800, 0x00106543, 0x417a6000, - 0x0201f800, 0x0010a0da, 0x0201f800, 0x00106982, - 0x81468800, 0x8058b040, 0x040207de, 0x5c00b000, - 0x5c027800, 0x5c028800, 0x5c026800, 0x5c026000, + 0x00104876, 0x0201f800, 0x0010606e, 0x0201f800, + 0x00101e45, 0x0401f027, 0x4200b000, 0x000007f0, + 0x80028d80, 0x0201f800, 0x00020245, 0x0402001e, + 0x59340200, 0x8c00051a, 0x0400001b, 0x59368c03, + 0x417a7800, 0x42028000, 0x00000029, 0x41783000, + 0x0201f800, 0x0010a446, 0x59340200, 0x84000558, + 0x8400051a, 0x48026a00, 0x4937c857, 0x4a026c00, + 0x00000707, 0x42028000, 0x00000029, 0x0201f800, + 0x00106ab4, 0x417a7800, 0x0201f800, 0x001067fd, + 0x80000d80, 0x0201f800, 0x0010a2ff, 0x0201f800, + 0x00106c4b, 0x81468800, 0x8058b040, 0x040207de, + 0x5c00b000, 0x5c027800, 0x5c028800, 0x5c026800, 0x1c01f000, 0x4933c857, 0x59303809, 0x581c0200, - 0x8400051a, 0x48003a00, 0x1c01f000, 0x42026800, - 0x0010b320, 0x497a680e, 0x42028800, 0x000007ff, - 0x0201f800, 0x001040e4, 0x4937c857, 0x4a026c00, - 0x00000606, 0x4a026802, 0x00ffffff, 0x4a026a04, - 0x00000200, 0x4a026c04, 0x00000002, 0x1c01f000, - 0x59300009, 0x50000000, 0x4933c857, 0x4803c857, - 0x8c00050e, 0x1c01f000, 0x59300009, 0x50000000, - 0x8c00050a, 0x1c01f000, 0x4933c856, 0x0401f90f, - 0x04000006, 0x59340400, 0x82000d00, 0x000000ff, - 0x82041580, 0x00000005, 0x1c01f000, 0x4d340000, - 0x83ac0400, 0x000007fe, 0x50000000, 0x80026d40, - 0x04000003, 0x59340200, 0x8c00051a, 0x5c026800, - 0x1c01f000, 0x4937c857, 0x493fc857, 0x59340403, - 0x81ac0400, 0x50000000, 0x81340580, 0x02020800, - 0x00100615, 0x59341200, 0x813e79c0, 0x04000003, - 0x8408155e, 0x0401f002, 0x8408151e, 0x480a6a00, - 0x1c01f000, 0x4937c857, 0x0201f800, 0x00101eb0, - 0x04000006, 0x59a80835, 0x42001000, 0x0010475f, - 0x0201f800, 0x00105da7, 0x1c01f000, 0x4937c857, - 0x42001000, 0x0010475f, 0x0201f800, 0x00105cc9, - 0x59a81026, 0x84081512, 0x480b5026, 0x1c01f000, - 0x4c380000, 0x4c340000, 0x4c240000, 0x4c600000, - 0x4008c000, 0x83440480, 0x00000800, 0x04021045, - 0x80002d80, 0x41442000, 0x83447400, 0x0010aa00, - 0x4200b000, 0x000007f0, 0x83444c80, 0x000007f0, - 0x04001003, 0x4200b000, 0x00000010, 0x50380000, - 0x80000540, 0x0402001e, 0x41440000, 0x80100580, - 0x04020043, 0x40102800, 0x82104c80, 0x000007f0, - 0x04001015, 0x82104d80, 0x000007fc, 0x04020005, - 0x82604d80, 0x00fffffc, 0x0402002a, 0x0401f00e, - 0x82104d80, 0x000007fd, 0x04020005, 0x82604d80, - 0x00fffffd, 0x04020023, 0x0401f007, 0x82104d80, - 0x000007ff, 0x0402001f, 0x82604d80, 0x00ffffff, - 0x0402001c, 0x84142d5e, 0x0401f029, 0x40006800, - 0x58343002, 0x82183500, 0x00ffffff, 0x40180000, - 0x80600580, 0x04020019, 0x40100000, 0x81440580, - 0x0402000a, 0x40366800, 0x8c204508, 0x04000053, - 0x0401ff8a, 0x04020051, 0x4947c857, 0x42000000, - 0x0000001d, 0x0401f04e, 0x4947c857, 0x480bc857, - 0x4823c857, 0x42000000, 0x0000001a, 0x0401f048, - 0x4947c857, 0x4863c857, 0x4813c857, 0x42000000, - 0x00000019, 0x0401f042, 0x40100000, 0x81440580, - 0x04020007, 0x58343002, 0x4947c857, 0x481bc857, - 0x42000000, 0x0000001b, 0x0401f039, 0x80102000, - 0x80387000, 0x83444c80, 0x000007f0, 0x04001009, - 0x82104d80, 0x00000800, 0x0402000c, 0x42002000, - 0x000007f0, 0x42007000, 0x0010b1f0, 0x0401f007, - 0x82104d80, 0x000007f0, 0x04020004, 0x41782000, - 0x42007000, 0x0010aa00, 0x8058b040, 0x040207a4, - 0x801429c0, 0x04020007, 0x0201f800, 0x00100615, - 0x4947c857, 0x42000000, 0x0000000a, 0x0401f01c, - 0x4d2c0000, 0x4c180000, 0x40603000, 0x0401fc19, - 0x4947c857, 0x4937c857, 0x5c003000, 0x5c025800, - 0x040207f4, 0x497a6a12, 0x59a80026, 0x8c00050a, - 0x0402000d, 0x82600500, 0x00ffff00, 0x04000006, - 0x59a84810, 0x82244d00, 0x00ffff00, 0x80240580, - 0x04020005, 0x82600500, 0x000000ff, 0x800000d0, - 0x48026a12, 0x48626802, 0x80000580, 0x80000540, - 0x5c00c000, 0x5c004800, 0x5c006800, 0x5c007000, - 0x1c01f000, 0x5934000f, 0x5934140b, 0x80081040, - 0x04001002, 0x480a6c0b, 0x80000540, 0x02020800, - 0x00020275, 0x1c01f000, 0x4803c857, 0x4947c857, - 0x4c300000, 0x82006500, 0x00000030, 0x04000006, - 0x4c000000, 0x0201f800, 0x001091f3, 0x5c000000, - 0x0402000b, 0x8c00050e, 0x04000006, 0x0201f800, - 0x00020267, 0x04020006, 0x4937c857, 0x0401fc36, - 0x80000580, 0x5c006000, 0x1c01f000, 0x82000540, - 0x00000001, 0x0401f7fc, 0x4803c857, 0x4c580000, - 0x4d440000, 0x40001000, 0x80000d80, 0x4200b000, - 0x000007f0, 0x4c040000, 0x40068800, 0x4c080000, - 0x40080000, 0x0401ffdd, 0x5c001000, 0x5c000800, - 0x80040800, 0x8058b040, 0x040207f7, 0x5c028800, - 0x5c00b000, 0x1c01f000, 0x4c5c0000, 0x59340400, + 0x8400051a, 0x48003a00, 0x1c01f000, 0x4803c856, + 0x42026800, 0x0010b524, 0x497a680e, 0x42028800, + 0x000007ff, 0x0201f800, 0x001042b4, 0x4937c857, + 0x4a026c00, 0x00000606, 0x4a026802, 0x00ffffff, + 0x4a026a04, 0x00000200, 0x4a026c04, 0x00000002, + 0x1c01f000, 0x59300009, 0x50000000, 0x4933c857, + 0x4803c857, 0x8c00050e, 0x1c01f000, 0x59300009, + 0x50000000, 0x8c00050a, 0x1c01f000, 0x4933c856, + 0x0401f90f, 0x04000006, 0x59340400, 0x82000d00, + 0x000000ff, 0x82041580, 0x00000005, 0x1c01f000, + 0x4d340000, 0x83ac0400, 0x000007fe, 0x50000000, + 0x80026d40, 0x04000003, 0x59340200, 0x8c00051a, + 0x5c026800, 0x1c01f000, 0x4937c857, 0x493fc857, + 0x59340403, 0x81ac0400, 0x50000000, 0x81340580, + 0x02020800, 0x001005d8, 0x59341200, 0x813e79c0, + 0x04000003, 0x8408155e, 0x0401f002, 0x8408151e, + 0x480a6a00, 0x1c01f000, 0x4937c857, 0x0201f800, + 0x0010210a, 0x04000006, 0x59a80835, 0x42001000, + 0x00104910, 0x0201f800, 0x0010606e, 0x1c01f000, + 0x4937c857, 0x42001000, 0x00104910, 0x0201f800, + 0x00105f90, 0x59a81026, 0x84081512, 0x480b5026, + 0x1c01f000, 0x4c380000, 0x4c340000, 0x4c240000, + 0x4c600000, 0x4008c000, 0x83440480, 0x00000800, + 0x04021045, 0x80002d80, 0x41442000, 0x83447400, + 0x0010ac00, 0x4200b000, 0x000007f0, 0x83444c80, + 0x000007f0, 0x04001003, 0x4200b000, 0x00000010, + 0x50380000, 0x80000540, 0x0402001e, 0x41440000, + 0x80100580, 0x04020043, 0x40102800, 0x82104c80, + 0x000007f0, 0x04001015, 0x82104d80, 0x000007fc, + 0x04020005, 0x82604d80, 0x00fffffc, 0x0402002a, + 0x0401f00e, 0x82104d80, 0x000007fd, 0x04020005, + 0x82604d80, 0x00fffffd, 0x04020023, 0x0401f007, + 0x82104d80, 0x000007ff, 0x0402001f, 0x82604d80, + 0x00ffffff, 0x0402001c, 0x84142d5e, 0x0401f029, + 0x40006800, 0x58343002, 0x82183500, 0x00ffffff, + 0x40180000, 0x80600580, 0x04020019, 0x40100000, + 0x81440580, 0x0402000a, 0x40366800, 0x8c204508, + 0x04000053, 0x0401ff8a, 0x04020051, 0x4947c857, + 0x42000000, 0x0000001d, 0x0401f04e, 0x4947c857, + 0x480bc857, 0x4823c857, 0x42000000, 0x0000001a, + 0x0401f048, 0x4947c857, 0x4863c857, 0x4813c857, + 0x42000000, 0x00000019, 0x0401f042, 0x40100000, + 0x81440580, 0x04020007, 0x58343002, 0x4947c857, + 0x481bc857, 0x42000000, 0x0000001b, 0x0401f039, + 0x80102000, 0x80387000, 0x83444c80, 0x000007f0, + 0x04001009, 0x82104d80, 0x00000800, 0x0402000c, + 0x42002000, 0x000007f0, 0x42007000, 0x0010b3f0, + 0x0401f007, 0x82104d80, 0x000007f0, 0x04020004, + 0x41782000, 0x42007000, 0x0010ac00, 0x8058b040, + 0x040207a4, 0x801429c0, 0x04020007, 0x0201f800, + 0x001005d8, 0x4947c857, 0x42000000, 0x0000000a, + 0x0401f01c, 0x4d2c0000, 0x4c180000, 0x40603000, + 0x0401fc12, 0x4947c857, 0x4937c857, 0x5c003000, + 0x5c025800, 0x040207f4, 0x497a6a12, 0x59a80026, + 0x8c00050a, 0x0402000d, 0x82600500, 0x00ffff00, + 0x04000006, 0x59a84810, 0x82244d00, 0x00ffff00, + 0x80240580, 0x04020005, 0x82600500, 0x000000ff, + 0x800000d0, 0x48026a12, 0x48626802, 0x80000580, + 0x80000540, 0x5c00c000, 0x5c004800, 0x5c006800, + 0x5c007000, 0x1c01f000, 0x5934000f, 0x5934140b, + 0x80081040, 0x04001002, 0x480a6c0b, 0x80000540, + 0x02020800, 0x00020253, 0x1c01f000, 0x4803c857, + 0x4947c857, 0x4c300000, 0x82006500, 0x00000030, + 0x04000006, 0x4c000000, 0x0201f800, 0x0010942a, + 0x5c000000, 0x0402000b, 0x8c00050e, 0x04000006, + 0x0201f800, 0x00020245, 0x04020006, 0x4937c857, + 0x0401fc2f, 0x80000580, 0x5c006000, 0x1c01f000, + 0x82000540, 0x00000001, 0x0401f7fc, 0x4803c857, + 0x4c580000, 0x4d440000, 0x40001000, 0x80000d80, + 0x4200b000, 0x000007f0, 0x4c040000, 0x40068800, + 0x4c080000, 0x40080000, 0x0401ffdd, 0x5c001000, + 0x5c000800, 0x80040800, 0x8058b040, 0x040207f7, + 0x5c028800, 0x5c00b000, 0x1c01f000, 0x4c5c0000, + 0x59340400, 0x8200bd80, 0x00000606, 0x5c00b800, + 0x1c01f000, 0x4c5c0000, 0x59340400, 0x8200bd80, + 0x00000404, 0x5c00b800, 0x1c01f000, 0x4c5c0000, + 0x59340400, 0x8200bd80, 0x00000404, 0x04000003, 0x8200bd80, 0x00000606, 0x5c00b800, 0x1c01f000, - 0x4c5c0000, 0x59340400, 0x8200bd80, 0x00000404, - 0x5c00b800, 0x1c01f000, 0x4c5c0000, 0x59340400, - 0x8200bd80, 0x00000404, 0x04000003, 0x8200bd80, - 0x00000606, 0x5c00b800, 0x1c01f000, 0x4c5c0000, - 0x4c600000, 0x59340400, 0x8200bd00, 0x0000ff00, - 0x825cc580, 0x00000400, 0x04000003, 0x825cc580, - 0x00000600, 0x5c00c000, 0x5c00b800, 0x1c01f000, - 0x4c5c0000, 0x59340400, 0x82000500, 0x000000ff, - 0x8200bd80, 0x00000003, 0x04000003, 0x8200bd80, - 0x00000005, 0x5c00b800, 0x1c01f000, 0x5c000000, - 0x4c000000, 0x4803c857, 0x4c5c0000, 0x59340400, - 0x82000500, 0x0000ff00, 0x8400b9c0, 0x805c0580, - 0x4937c857, 0x4803c857, 0x48026c00, 0x5c00b800, - 0x1c01f000, 0x4c040000, 0x4c080000, 0x592c0207, - 0x8c00050c, 0x0400000f, 0x592e8c06, 0x82000500, - 0x00000080, 0x84000548, 0x4d3c0000, 0x42027800, - 0x00001000, 0x0401ff8d, 0x5c027800, 0x82000540, - 0x00000001, 0x5c001000, 0x5c000800, 0x1c01f000, - 0x80000580, 0x0401f7fc, 0x592c040b, 0x82000500, - 0x0000e000, 0x82000580, 0x00006000, 0x04000019, - 0x836c0580, 0x00000003, 0x04000016, 0x836c0580, - 0x00000002, 0x04020106, 0x59a80026, 0x82000d00, - 0x00000038, 0x04020005, 0x59a80832, 0x800409c0, - 0x0400000c, 0x0401f0fe, 0x82000d00, 0x00000003, - 0x82040d80, 0x00000003, 0x040200f9, 0x82000d00, - 0x00000028, 0x04020003, 0x8c00050c, 0x040000f4, - 0x592c100a, 0x82080500, 0xff000000, 0x040200d2, - 0x59a80010, 0x80080580, 0x040000cc, 0x592c0c0b, - 0x82040d00, 0x0000e000, 0x82040480, 0x00008000, - 0x040210cc, 0x592e8c06, 0x83440480, 0x00000800, - 0x04001007, 0x83440580, 0x0000ffff, 0x040200b3, - 0x800409c0, 0x040200fe, 0x0401f0b0, 0x800409c0, - 0x040200fb, 0x41784000, 0x0401feaa, 0x040200e2, - 0x59342204, 0x592c000d, 0x80100480, 0x040010bc, - 0x42027000, 0x00000053, 0x592c2409, 0x82100500, - 0xffffff00, 0x040200aa, 0x4813c857, 0x592c000c, - 0x800001c0, 0x04000083, 0x82100580, 0x00000004, - 0x040000a0, 0x82100580, 0x00000051, 0x0400009d, - 0x82100580, 0x00000003, 0x04000016, 0x82100580, - 0x00000020, 0x0400004b, 0x82100580, 0x00000024, - 0x04000042, 0x82100580, 0x00000021, 0x04000042, - 0x82100580, 0x00000050, 0x04000037, 0x82100580, - 0x00000052, 0x04000031, 0x82100580, 0x00000005, - 0x0402006b, 0x42027000, 0x00000001, 0x0401f01b, - 0x42027000, 0x00000002, 0x59a8006f, 0x8c000502, - 0x04000016, 0x0401ff45, 0x04000014, 0x59340212, - 0x82000500, 0x0000ff00, 0x42001000, 0x00000010, - 0x0402000c, 0x59a80026, 0x8c000506, 0x0402006f, - 0x42001000, 0x00000008, 0x59340002, 0x82000500, - 0x00ff0000, 0x82000580, 0x00ff0000, 0x04000003, - 0x0401f9d6, 0x04020065, 0x0201f800, 0x00020892, - 0x04000081, 0x4a026406, 0x00000010, 0x49366009, - 0x42000800, 0x00000003, 0x83380580, 0x00000002, - 0x04000003, 0x42000800, 0x0000000b, 0x0201f800, - 0x001043c7, 0x0401f044, 0x42027000, 0x00000000, - 0x0401f003, 0x42027000, 0x00000004, 0x0401ff30, - 0x04020074, 0x0401f036, 0x42027000, 0x00000033, - 0x0401f006, 0x42027000, 0x00000005, 0x0401f003, - 0x42027000, 0x00000003, 0x0401ff1c, 0x04020069, - 0x59a8006f, 0x8c000502, 0x04000016, 0x0401ff0b, + 0x4c5c0000, 0x4c600000, 0x59340400, 0x8200bd00, + 0x0000ff00, 0x825cc580, 0x00000400, 0x04000003, + 0x825cc580, 0x00000600, 0x5c00c000, 0x5c00b800, + 0x1c01f000, 0x4c5c0000, 0x59340400, 0x82000500, + 0x000000ff, 0x8200bd80, 0x00000003, 0x04000003, + 0x8200bd80, 0x00000005, 0x5c00b800, 0x1c01f000, + 0x4c5c0000, 0x59340400, 0x82000500, 0x0000ff00, + 0x8400b9c0, 0x805c0580, 0x4937c857, 0x4803c857, + 0x48026c00, 0x5c00b800, 0x1c01f000, 0x4c040000, + 0x4c080000, 0x592c0207, 0x8c00050c, 0x0400000f, + 0x592e8c06, 0x82000500, 0x00000080, 0x84000548, + 0x4d3c0000, 0x42027800, 0x00001000, 0x0401ff90, + 0x5c027800, 0x82000540, 0x00000001, 0x5c001000, + 0x5c000800, 0x1c01f000, 0x80000580, 0x0401f7fc, + 0x592c040b, 0x82000500, 0x0000e000, 0x82000580, + 0x00006000, 0x04000019, 0x836c0580, 0x00000003, + 0x04000016, 0x836c0580, 0x00000002, 0x040200ff, + 0x59a80026, 0x82000d00, 0x00000038, 0x04020005, + 0x59a80832, 0x800409c0, 0x0400000c, 0x0401f0f7, + 0x82000d00, 0x00000003, 0x82040d80, 0x00000003, + 0x040200f2, 0x82000d00, 0x00000028, 0x04020003, + 0x8c00050c, 0x040000ed, 0x592c100a, 0x82080500, + 0xff000000, 0x040200ce, 0x59a80010, 0x80080580, + 0x040000c8, 0x592c0c0b, 0x82040d00, 0x0000e000, + 0x82040480, 0x00008000, 0x040210c8, 0x592e8c06, + 0x83440480, 0x00000800, 0x04001007, 0x83440580, + 0x0000ffff, 0x040200af, 0x800409c0, 0x040200f7, + 0x0401f0ac, 0x800409c0, 0x040200f4, 0x41784000, + 0x0401fead, 0x040200db, 0x42027000, 0x00000053, + 0x592c2409, 0x82100500, 0xffffff00, 0x040200aa, + 0x4813c857, 0x592c000c, 0x800001c0, 0x04000083, + 0x82100580, 0x00000004, 0x040000a0, 0x82100580, + 0x00000051, 0x0400009d, 0x82100580, 0x00000003, + 0x04000016, 0x82100580, 0x00000020, 0x0400004b, + 0x82100580, 0x00000024, 0x04000042, 0x82100580, + 0x00000021, 0x04000042, 0x82100580, 0x00000050, + 0x04000037, 0x82100580, 0x00000052, 0x04000031, + 0x82100580, 0x00000005, 0x0402006b, 0x42027000, + 0x00000001, 0x0401f01b, 0x42027000, 0x00000002, + 0x59a80005, 0x8c000514, 0x04000016, 0x0401ff4c, 0x04000014, 0x59340212, 0x82000500, 0x0000ff00, 0x42001000, 0x00000010, 0x0402000c, 0x59a80026, - 0x8c000506, 0x04020035, 0x42001000, 0x00000008, + 0x8c000506, 0x0402006f, 0x42001000, 0x00000008, 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, - 0x00ff0000, 0x04000003, 0x0401f99c, 0x0402002b, - 0x0201f800, 0x00020892, 0x04000047, 0x4a026406, - 0x00000010, 0x49366009, 0x42000800, 0x00000005, - 0x83380580, 0x00000003, 0x04000003, 0x42000800, - 0x00000009, 0x0201f800, 0x001043c7, 0x0401f00a, - 0x82102580, 0x00000011, 0x04020030, 0x0201f800, - 0x00020892, 0x04000034, 0x4a026406, 0x00000010, - 0x49366009, 0x492e6008, 0x49325808, 0x813669c0, - 0x04000007, 0x592c0c0b, 0x8c040d18, 0x04000004, - 0x59340200, 0x84000514, 0x48026a00, 0x0201f800, - 0x000208d8, 0x80000580, 0x1c01f000, 0x82000540, - 0x00000001, 0x0401f7fd, 0x42001000, 0x0000000a, - 0x0401f018, 0x42001000, 0x00000010, 0x0401f015, - 0x42001000, 0x00000016, 0x0401f012, 0x42001000, - 0x00000017, 0x0401f00f, 0x42001000, 0x00000018, - 0x0401f00c, 0x42001000, 0x0000001b, 0x0401f009, - 0x42001000, 0x0000001e, 0x0401f006, 0x42001000, - 0x00000024, 0x0401f003, 0x42001000, 0x00000020, - 0x42000800, 0x00000019, 0x42028000, 0x00000031, - 0x0401f7df, 0x42000800, 0x00000003, 0x0401f003, - 0x42000800, 0x0000000a, 0x41781000, 0x0401f7f7, - 0x42000800, 0x00000009, 0x59341400, 0x0401f7f3, - 0x42028000, 0x00000008, 0x0401f005, 0x42000800, - 0x00000007, 0x416c1000, 0x0401f7ec, 0x41780800, - 0x41781000, 0x0401f7ca, 0x42028000, 0x00000000, - 0x0401f7fb, 0x82004d80, 0x0000001d, 0x02000800, - 0x00100615, 0x82004d80, 0x0000001a, 0x04020004, - 0x40101000, 0x40000800, 0x0401f7dc, 0x82004d80, - 0x0000001b, 0x04020003, 0x40181000, 0x0401f7fa, - 0x82004d80, 0x0000001c, 0x040007f7, 0x82004d80, - 0x00000019, 0x040007b5, 0x0401f7d6, 0x592e6008, - 0x0201f800, 0x001091e3, 0x040007b3, 0x59300c06, - 0x82040580, 0x00000011, 0x040207d6, 0x83440580, - 0x0000ffff, 0x04020005, 0x59326809, 0x813669c0, - 0x0400000e, 0x0401f7cf, 0x592c100a, 0x82081500, - 0x00ffffff, 0x41784000, 0x0401fd9e, 0x040207d6, - 0x59300009, 0x800001c0, 0x04000003, 0x81340580, - 0x040207c4, 0x49366009, 0x592c0c0b, 0x82041500, - 0x0000e000, 0x82080580, 0x00006000, 0x04000011, - 0x42000800, 0x00000100, 0x813669c0, 0x04000002, - 0x59340a04, 0x592c000d, 0x80040480, 0x040017a0, - 0x59300a03, 0x82040580, 0x00000007, 0x040207b1, - 0x492e6008, 0x42027000, 0x00000054, 0x0401f774, - 0x0201f800, 0x0010a6e6, 0x040007b4, 0x0401f7a9, - 0x492fc857, 0x592e6008, 0x4933c857, 0x0201f800, - 0x001091e3, 0x04000047, 0x59301406, 0x82080580, - 0x00000005, 0x04020061, 0x592c0207, 0x8c000500, - 0x04020085, 0x59a80021, 0x800001c0, 0x0402006a, + 0x00ff0000, 0x04000003, 0x0401f9bf, 0x04020065, + 0x0201f800, 0x0002075a, 0x0400007e, 0x4a026406, + 0x00000010, 0x49366009, 0x42000800, 0x00000003, + 0x83380580, 0x00000002, 0x04000003, 0x42000800, + 0x0000000b, 0x0201f800, 0x00104571, 0x0401f044, + 0x42027000, 0x00000000, 0x0401f003, 0x42027000, + 0x00000004, 0x0401ff37, 0x04020071, 0x0401f036, + 0x42027000, 0x00000033, 0x0401f006, 0x42027000, + 0x00000005, 0x0401f003, 0x42027000, 0x00000003, + 0x0401ff23, 0x04020066, 0x59a80005, 0x8c000514, + 0x04000016, 0x0401ff12, 0x04000014, 0x59340212, + 0x82000500, 0x0000ff00, 0x42001000, 0x00000010, + 0x0402000c, 0x59a80026, 0x8c000506, 0x04020035, + 0x42001000, 0x00000008, 0x59340002, 0x82000500, + 0x00ff0000, 0x82000580, 0x00ff0000, 0x04000003, + 0x0401f985, 0x0402002b, 0x0201f800, 0x0002075a, + 0x04000044, 0x4a026406, 0x00000010, 0x49366009, + 0x42000800, 0x00000005, 0x83380580, 0x00000003, + 0x04000003, 0x42000800, 0x00000009, 0x0201f800, + 0x00104571, 0x0401f00a, 0x82102580, 0x00000011, + 0x0402002d, 0x0201f800, 0x0002075a, 0x04000031, + 0x4a026406, 0x00000010, 0x49366009, 0x492e6008, + 0x49325808, 0x813669c0, 0x04000007, 0x592c0c0b, + 0x8c040d18, 0x04000004, 0x59340200, 0x84000514, + 0x48026a00, 0x0201f800, 0x000207a1, 0x80000580, + 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fd, + 0x42001000, 0x0000000a, 0x0401f015, 0x42001000, + 0x00000010, 0x0401f012, 0x42001000, 0x00000016, + 0x0401f00f, 0x42001000, 0x00000017, 0x0401f00c, + 0x42001000, 0x00000018, 0x0401f009, 0x42001000, + 0x0000001b, 0x0401f006, 0x42001000, 0x0000001e, + 0x0401f003, 0x42001000, 0x00000020, 0x42000800, + 0x00000019, 0x42028000, 0x00000031, 0x0401f7e2, + 0x42000800, 0x00000003, 0x0401f003, 0x42000800, + 0x0000000a, 0x41781000, 0x0401f7f7, 0x42000800, + 0x00000009, 0x59341400, 0x0401f7f3, 0x42028000, + 0x00000008, 0x0401f005, 0x42000800, 0x00000007, + 0x416c1000, 0x0401f7ec, 0x41780800, 0x41781000, + 0x0401f7cd, 0x42028000, 0x00000000, 0x0401f7fb, + 0x82004d80, 0x0000001d, 0x02000800, 0x001005d8, + 0x82004d80, 0x0000001a, 0x04020004, 0x40101000, + 0x40000800, 0x0401f7dc, 0x82004d80, 0x0000001b, + 0x04020003, 0x40181000, 0x0401f7fa, 0x82004d80, + 0x0000001c, 0x040007f7, 0x82004d80, 0x00000019, + 0x040007b8, 0x0401f7d6, 0x592e6008, 0x0201f800, + 0x0010941a, 0x040007b6, 0x59300c06, 0x82040580, + 0x00000011, 0x040207d6, 0x83440580, 0x0000ffff, + 0x04020005, 0x59326809, 0x813669c0, 0x0400000e, + 0x0401f7cf, 0x592c100a, 0x82081500, 0x00ffffff, + 0x41784000, 0x0401fda8, 0x040207d6, 0x59300009, + 0x800001c0, 0x04000003, 0x81340580, 0x040207c4, + 0x49366009, 0x592c0c0b, 0x82041500, 0x0000e000, + 0x82080580, 0x00006000, 0x04000009, 0x59300a03, + 0x82040580, 0x00000007, 0x040207b9, 0x492e6008, + 0x42027000, 0x00000054, 0x0401f77f, 0x0201f800, + 0x0010a8d4, 0x040007bc, 0x0401f7b1, 0x492fc857, + 0x59a80021, 0x800001c0, 0x04020073, 0x592e6008, + 0x4933c857, 0x0201f800, 0x0010941a, 0x04000041, + 0x59301406, 0x82080580, 0x00000005, 0x0402005b, 0x59301203, 0x82080580, 0x00000007, 0x04020057, 0x592e8c06, 0x83440480, 0x00000800, 0x04021032, 0x41784000, 0x592c1009, 0x82081500, 0x00ffffff, - 0x0401fd60, 0x0402005f, 0x59300009, 0x800001c0, + 0x0401fd75, 0x0402005f, 0x59300009, 0x800001c0, 0x04000003, 0x81340580, 0x04020048, 0x4d300000, 0x592e6013, 0x4933c857, 0x83300580, 0xffffffff, - 0x0400000d, 0x0201f800, 0x001091e3, 0x5c026000, + 0x0400000d, 0x0201f800, 0x0010941a, 0x5c026000, 0x04000029, 0x591c1406, 0x82080580, 0x00000006, 0x04000046, 0x82080580, 0x00000011, 0x04000043, 0x0401f002, 0x5c026000, 0x59a80010, 0x592c100a, 0x82081500, 0x00ffffff, 0x80081580, 0x04020017, 0x592c1009, 0x82081500, 0x00ffffff, 0x80081580, 0x0400000f, 0x49366009, 0x492e6008, 0x42027000, - 0x00000092, 0x0201f800, 0x000208d8, 0x80000580, + 0x00000092, 0x0201f800, 0x000207a1, 0x80000580, 0x1c01f000, 0x42001000, 0x0000000a, 0x0401f00c, 0x42001000, 0x00000010, 0x0401f009, 0x42001000, 0x00000014, 0x0401f006, 0x42001000, 0x00000018, @@ -4801,131 +4904,231 @@ uint32_t risc_code01[] = { 0x4803c857, 0x42028000, 0x00000008, 0x41780800, 0x41781000, 0x0401f7e8, 0x42000800, 0x0000001e, 0x0401f7f0, 0x42000800, 0x00000001, 0x0401f7ed, - 0x82004d80, 0x0000001d, 0x02000800, 0x00100615, + 0x82004d80, 0x0000001d, 0x02000800, 0x001005d8, 0x82004d80, 0x0000001a, 0x04020003, 0x40101000, 0x0401f7dc, 0x82004d80, 0x0000001b, 0x04020003, 0x40181000, 0x0401f7d7, 0x82004d80, 0x0000001c, 0x040007d4, 0x82004d80, 0x00000019, 0x040007d1, - 0x0401f7d5, 0x0201f800, 0x0010a6e6, 0x040207d7, - 0x42028000, 0x00000000, 0x0401f7dd, 0x5c000000, - 0x4c000000, 0x4803c857, 0x59302009, 0x801021c0, - 0x04000035, 0x58101400, 0x4813c857, 0x480bc857, - 0x82081d00, 0x000000ff, 0x59300c03, 0x82040580, - 0x00000008, 0x04000022, 0x82040580, 0x0000000a, - 0x04000017, 0x82040580, 0x0000000c, 0x04000010, - 0x82040580, 0x00000002, 0x04000019, 0x82040580, - 0x00000001, 0x04000012, 0x82040580, 0x00000003, - 0x0400000b, 0x82040580, 0x00000005, 0x04000004, - 0x82040580, 0x00000033, 0x04020017, 0x820c0580, - 0x00000009, 0x0400000d, 0x0401f013, 0x820c0580, - 0x00000005, 0x04000009, 0x0401f00f, 0x820c0580, - 0x0000000b, 0x04000005, 0x0401f00b, 0x820c0580, - 0x00000003, 0x04020008, 0x82081d00, 0xffffff00, - 0x840c01c0, 0x800c0540, 0x4807c857, 0x4803c857, - 0x48002400, 0x1c01f000, 0x599c0017, 0x8c00050a, - 0x04000003, 0x80000580, 0x1c01f000, 0x59a80026, - 0x82000500, 0x00000028, 0x04000008, 0x42028800, - 0x000007fd, 0x0201f800, 0x00020267, 0x04020003, - 0x5934000a, 0x8c000504, 0x1c01f000, 0x4d300000, - 0x5934000e, 0x80026540, 0x04000006, 0x0201f800, - 0x0010600e, 0x02000800, 0x001061e5, 0x497a680e, - 0x5c026000, 0x1c01f000, 0x4d440000, 0x4d340000, - 0x80000580, 0x40001800, 0x40028800, 0x82080580, - 0x00000008, 0x04020003, 0x42001800, 0x00000001, - 0x0201f800, 0x00020267, 0x0402000a, 0x0401fd4f, - 0x04020008, 0x800c19c0, 0x04000004, 0x59340405, - 0x8c000508, 0x04000003, 0x80081040, 0x04000009, - 0x81468800, 0x83440480, 0x00000800, 0x040017f1, - 0x80000580, 0x5c026800, 0x5c028800, 0x1c01f000, - 0x82000540, 0x00000001, 0x5c026800, 0x5c028800, - 0x1c01f000, 0x42000800, 0x00000001, 0x0401fb0e, - 0x04020034, 0x59a80026, 0x8c000508, 0x04020031, - 0x5934100a, 0x82081500, 0x0000e000, 0x42007000, - 0x0010b33f, 0x58380401, 0x8c000504, 0x0402001c, - 0x42000800, 0x00000001, 0x82080580, 0x00006000, - 0x04000024, 0x59341a04, 0x820c0480, 0x00000800, - 0x04001004, 0x42000800, 0x00000a00, 0x0401f009, - 0x820c0480, 0x00000400, 0x04001004, 0x42000800, - 0x00000500, 0x0401f003, 0x42000800, 0x00000200, - 0x82080580, 0x00002000, 0x04000002, 0x800408c2, - 0x82040d40, 0x00000001, 0x0401f00e, 0x42000800, - 0x00000008, 0x82080580, 0x00002000, 0x04020004, - 0x42000800, 0x00000004, 0x0401f006, 0x82080580, - 0x00000000, 0x04020003, 0x42000800, 0x00000002, - 0x48066c04, 0x1c01f000, 0x4a033020, 0x00000000, - 0x4a03b104, 0x80000000, 0x497b3026, 0x497b3027, + 0x0401f7d5, 0x59302009, 0x801021c0, 0x04000035, + 0x58101400, 0x82081d00, 0x000000ff, 0x59300c03, + 0x82040580, 0x00000008, 0x04000022, 0x82040580, + 0x0000000a, 0x04000017, 0x82040580, 0x0000000c, + 0x04000010, 0x82040580, 0x00000002, 0x04000019, + 0x82040580, 0x00000001, 0x04000012, 0x82040580, + 0x00000003, 0x0400000b, 0x82040580, 0x00000005, + 0x04000004, 0x82040580, 0x00000033, 0x04020019, + 0x820c0580, 0x00000009, 0x0400000d, 0x0401f015, + 0x820c0580, 0x00000005, 0x04000009, 0x0401f011, + 0x820c0580, 0x0000000b, 0x04000005, 0x0401f00d, + 0x820c0580, 0x00000003, 0x0402000a, 0x82081d00, + 0xffffff00, 0x840c01c0, 0x800c0540, 0x4813c857, + 0x480bc857, 0x4807c857, 0x4803c857, 0x48002400, + 0x1c01f000, 0x599c0017, 0x8c00050a, 0x04000003, + 0x80000580, 0x1c01f000, 0x59a80026, 0x82000500, + 0x00000028, 0x04000008, 0x42028800, 0x000007fd, + 0x0201f800, 0x00020245, 0x04020003, 0x5934000a, + 0x8c000504, 0x1c01f000, 0x4d300000, 0x5934000e, + 0x80026540, 0x04000006, 0x0201f800, 0x001062d5, + 0x02000800, 0x001064ad, 0x497a680e, 0x5c026000, + 0x1c01f000, 0x4d440000, 0x4d340000, 0x80000580, + 0x40001800, 0x40028800, 0x82080580, 0x00000008, + 0x04020003, 0x42001800, 0x00000001, 0x0201f800, + 0x00020245, 0x0402000a, 0x0401fd6d, 0x04020008, + 0x800c19c0, 0x04000004, 0x59340405, 0x8c000508, + 0x04000003, 0x80081040, 0x04000009, 0x81468800, + 0x83440480, 0x00000800, 0x040017f1, 0x80000580, + 0x5c026800, 0x5c028800, 0x1c01f000, 0x82000540, + 0x00000001, 0x5c026800, 0x5c028800, 0x1c01f000, + 0x4a033020, 0x00000000, 0x497b3026, 0x497b3027, 0x497b3028, 0x497b3029, 0x497b302b, 0x497b3021, - 0x4a03b104, 0x60000001, 0x1c01f000, 0x599c0018, - 0x4803c856, 0x497b3024, 0x497b3025, 0x82000500, - 0x0000000f, 0x48033022, 0x04000008, 0x599c0216, + 0x4a03b104, 0x60000001, 0x1c01f000, 0x4803c856, + 0x599c0018, 0x497b3024, 0x497b3025, 0x82000500, + 0x0000000f, 0x82000d80, 0x00000005, 0x04000006, + 0x82000580, 0x00000006, 0x0400000d, 0x497b3022, + 0x1c01f000, 0x4a033022, 0x00000005, 0x599c0216, 0x82000500, 0x0000ffff, 0x04020003, 0x42000000, - 0x00000002, 0x48033023, 0x1c01f000, 0x0401fff0, - 0x4a03c826, 0x00000004, 0x599c0209, 0x80000540, - 0x0400001f, 0x599c0207, 0x80000540, 0x04000007, - 0x800000cc, 0x599c080d, 0x80040400, 0x4803b100, - 0x497bb102, 0x59d80101, 0x599c000d, 0x4803b100, - 0x599c000e, 0x4803b101, 0x599c0207, 0x80000540, - 0x04020002, 0x497bb102, 0x599c0a09, 0x82040540, - 0x00400000, 0x59980822, 0x4803b103, 0x4a03b109, - 0x00000004, 0x4a03b104, 0x10000001, 0x800409c0, - 0x04020004, 0x4a033020, 0x00000001, 0x1c01f000, - 0x4a033020, 0x00000002, 0x0401f7fd, 0x592c0204, - 0x492fc857, 0x80000540, 0x04000008, 0x42034000, - 0x0010b2a0, 0x59a1d81e, 0x80edd9c0, 0x02000800, - 0x00100615, 0x0401f003, 0x5931d821, 0x58ef400b, - 0x58ec0009, 0x800001c0, 0x08020000, 0x0201f800, - 0x00100615, 0x5998002b, 0x84000540, 0x4803302b, - 0x0201f000, 0x00020403, 0x42000000, 0x0010b654, - 0x0201f800, 0x0010a86e, 0x492fc857, 0x59980026, - 0x59980828, 0x80000000, 0x48033026, 0x800409c0, - 0x492f3028, 0x04000003, 0x492c0800, 0x0401f002, - 0x492f3029, 0x592c0001, 0x80000d40, 0x02020000, - 0x000202fb, 0x1c01f000, 0x59980026, 0x59980828, + 0x00000002, 0x48033023, 0x1c01f000, 0x4a033022, + 0x00000006, 0x0401f7f6, 0x0401ffe5, 0x4a03c826, + 0x00000004, 0x599c0209, 0x80000540, 0x0400001f, + 0x599c0207, 0x80000540, 0x04000007, 0x800000cc, + 0x599c080d, 0x80040400, 0x4803b100, 0x497bb102, + 0x59d80101, 0x599c000d, 0x4803b100, 0x599c000e, + 0x4803b101, 0x599c0207, 0x80000540, 0x04020002, + 0x497bb102, 0x599c0a09, 0x82040540, 0x00400000, + 0x59980822, 0x4803b103, 0x4a03b109, 0x00000004, + 0x4a03b104, 0x10000001, 0x800409c0, 0x04020004, + 0x4a033020, 0x00000001, 0x1c01f000, 0x4a033020, + 0x00000002, 0x0401f7fd, 0x59980022, 0x4803c856, + 0x80000540, 0x02000000, 0x000202de, 0x0401f017, + 0x42034000, 0x0010b4a4, 0x59a1d81e, 0x80edd9c0, + 0x02000800, 0x001005d8, 0x58ec0009, 0x48efc857, + 0x49a3c857, 0x492fc857, 0x4803c857, 0x800001c0, + 0x08020000, 0x0201f800, 0x001005d8, 0x5931d821, + 0x58ef400b, 0x58ec0009, 0x800001c0, 0x08020000, + 0x0201f800, 0x001005d8, 0x497a5800, 0x59980026, + 0x80000540, 0x0402008c, 0x59d80105, 0x82000d00, + 0x00018780, 0x040201da, 0x80000106, 0x82000500, + 0x00000003, 0x0c01f001, 0x00104d0a, 0x00104d89, + 0x00104d22, 0x00104d50, 0x592c0001, 0x492fc857, + 0x492fb107, 0x80000d40, 0x04020007, 0x59940019, + 0x80000540, 0x04022003, 0x59980023, 0x48032819, + 0x1c01f000, 0x497a5801, 0x40065800, 0x592c0001, + 0x496a5800, 0x815eb800, 0x412ed000, 0x80000d40, + 0x040207f9, 0x59c80000, 0x82000540, 0x00001200, + 0x48039000, 0x0401f7ee, 0x492fc857, 0x492fb107, + 0x592c0001, 0x80000d40, 0x04020012, 0x59da5908, + 0x835c0480, 0x00000020, 0x0400101c, 0x0402b01a, + 0x492fb007, 0x0400e7fa, 0x59d80105, 0x82000500, + 0x00018780, 0x040201aa, 0x59940019, 0x80000540, + 0x04022003, 0x59980023, 0x48032819, 0x1c01f000, + 0x497a5801, 0x40065800, 0x592c0001, 0x496a5800, + 0x815eb800, 0x412ed000, 0x80000d40, 0x040207f9, + 0x59c80000, 0x82000540, 0x00001200, 0x48039000, + 0x0401f7e3, 0x0400f009, 0x496a5800, 0x412ed000, + 0x815eb800, 0x59c80000, 0x82000540, 0x00001200, + 0x48039000, 0x0401f7e0, 0x492fa807, 0x0401f7de, + 0x492fc857, 0x59d81108, 0x45681000, 0x400ad000, + 0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540, + 0x00001200, 0x48039000, 0x0402d00c, 0x592c0001, + 0x492fc857, 0x492fb107, 0x80000d40, 0x0402001d, + 0x59940019, 0x80000540, 0x04022003, 0x59980023, + 0x48032819, 0x1c01f000, 0x59d80105, 0x82000500, + 0x00018780, 0x04020172, 0x42000000, 0x0010b855, + 0x0201f800, 0x0010aa47, 0x59980026, 0x59980828, 0x80000000, 0x48033026, 0x492fc857, 0x800409c0, 0x492f3028, 0x04000003, 0x492c0800, 0x0401f002, - 0x492f3029, 0x592c0001, 0x80000d40, 0x02020800, - 0x000202fb, 0x0402d00e, 0x59980029, 0x80025d40, - 0x0400000f, 0x59980026, 0x80000040, 0x48033026, - 0x04020002, 0x48033028, 0x592c0000, 0x48033029, - 0x492fc857, 0x492fb107, 0x0400d7f4, 0x42000000, - 0x0010b654, 0x0201f800, 0x0010a86e, 0x0402e01d, + 0x492f3029, 0x592c0001, 0x80000d40, 0x040007e5, + 0x497a5801, 0x40065800, 0x592c0001, 0x496a5800, + 0x815eb800, 0x412ed000, 0x80000d40, 0x040207f9, + 0x59c80000, 0x82000540, 0x00001200, 0x48039000, + 0x0401f7d8, 0x59980026, 0x59980828, 0x80000000, + 0x48033026, 0x492fc857, 0x800409c0, 0x492f3028, + 0x04000003, 0x492c0800, 0x0401f002, 0x492f3029, + 0x592c0001, 0x80000d40, 0x04020027, 0x0402d00e, + 0x59980029, 0x80025d40, 0x0400000f, 0x59980026, + 0x80000040, 0x48033026, 0x04020002, 0x48033028, + 0x592c0000, 0x48033029, 0x492fc857, 0x492fb107, + 0x0400d7f4, 0x42000000, 0x0010b855, 0x0201f800, + 0x0010aa47, 0x0402e00a, 0x59da5908, 0x496a5800, + 0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x59d80105, + 0x82000500, 0x00018780, 0x04020125, 0x59940019, + 0x80000540, 0x04022003, 0x59980023, 0x48032819, + 0x1c01f000, 0x497a5801, 0x40065800, 0x592c0001, + 0x496a5800, 0x815eb800, 0x412ed000, 0x80000d40, + 0x040207f9, 0x59c80000, 0x82000540, 0x00001200, + 0x48039000, 0x0401f7ce, 0x592c0204, 0x4803c856, + 0x04000008, 0x42034000, 0x0010b4a4, 0x59a1d81e, + 0x80edd9c0, 0x02000800, 0x001005d8, 0x0401f003, + 0x5931d821, 0x58ef400b, 0x58ec0009, 0x800001c0, + 0x08020000, 0x0201f800, 0x001005d8, 0x497a5801, + 0x40065800, 0x592c0001, 0x496a5800, 0x412ed000, + 0x815eb800, 0x80000d40, 0x040207f9, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x1c01f000, + 0x497a5801, 0x40065800, 0x592c0001, 0x496a5800, + 0x412ed000, 0x815eb800, 0x80000d40, 0x040207f9, + 0x59c80000, 0x82000540, 0x00001200, 0x48039000, + 0x0200e000, 0x000202fb, 0x0201f000, 0x00020302, + 0x5998002b, 0x84000540, 0x4803302b, 0x0201f000, + 0x0002035e, 0x42000000, 0x0010b855, 0x0201f800, + 0x0010aa47, 0x492fc857, 0x59980026, 0x59980828, + 0x80000000, 0x48033026, 0x800409c0, 0x492f3028, + 0x04000003, 0x492c0800, 0x0401f002, 0x492f3029, + 0x592c0001, 0x80000d40, 0x04020002, 0x1c01f000, + 0x497a5801, 0x40065800, 0x592c0001, 0x496a5800, + 0x412ed000, 0x815eb800, 0x80000d40, 0x040207f9, + 0x59c80000, 0x82000540, 0x00001200, 0x48039000, + 0x1c01f000, 0x59980026, 0x59980828, 0x80000000, + 0x48033026, 0x492fc857, 0x800409c0, 0x492f3028, + 0x04000003, 0x492c0800, 0x0401f002, 0x492f3029, + 0x592c0001, 0x80000d40, 0x04020039, 0x0402d00e, + 0x59980029, 0x80025d40, 0x0400000f, 0x59980026, + 0x80000040, 0x48033026, 0x04020002, 0x48033028, + 0x592c0000, 0x48033029, 0x492fc857, 0x492fb107, + 0x0400d7f4, 0x42000000, 0x0010b855, 0x0201f800, + 0x0010aa47, 0x0402e01d, 0x59da5908, 0x496a5800, + 0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x04006018, + 0x59d8010a, 0x59d8090a, 0x80040d80, 0x040207fd, + 0x900001c0, 0x82000540, 0x00000013, 0x4803c011, + 0x5998002b, 0x84000500, 0x4803302b, 0x59e00017, + 0x8c000508, 0x04000003, 0x4a03c017, 0x00000003, + 0x4203e000, 0x30000001, 0x59d80105, 0x82000500, + 0x00018780, 0x0402007e, 0x1c01f000, 0x5998002b, + 0x84000540, 0x4803302b, 0x0401f7f8, 0x497a5801, + 0x40065800, 0x592c0001, 0x496a5800, 0x412ed000, + 0x815eb800, 0x80000d40, 0x040207f9, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x0401f7bc, + 0x5c000000, 0x4c000000, 0x4803c857, 0x492fc857, + 0x4943c857, 0x4807c857, 0x4a025a04, 0x00000103, + 0x49425a06, 0x48065a08, 0x4a025c06, 0x0000ffff, + 0x813261c0, 0x04000003, 0x59300402, 0x48025c06, + 0x832c0400, 0x00000009, 0x04011000, 0x4803c840, + 0x4a03c842, 0x0000000b, 0x04011000, 0x1c01f000, + 0x4df00000, 0x4203e000, 0x50000000, 0x599cb817, + 0x59940019, 0x80000540, 0x04002023, 0x0400000e, + 0x59980022, 0x82000580, 0x00000005, 0x0400001e, + 0x59a80069, 0x81640580, 0x0402001b, 0x8c5cbd08, + 0x04000005, 0x59a8006a, 0x59a80866, 0x80040580, + 0x04020015, 0x8c5cbd08, 0x04020030, 0x59d8090b, + 0x59d8010a, 0x80040580, 0x0400000d, 0x0400600e, + 0x4a03c011, 0x80400012, 0x4a03c020, 0x00008040, + 0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017, + 0x00000002, 0x4203e000, 0x30000001, 0x4a032819, + 0xffff0000, 0x04026835, 0x04006003, 0x8c5cbd08, + 0x04020860, 0x59980029, 0x80025d40, 0x04000010, + 0x59d80105, 0x82000500, 0x00018780, 0x04020020, + 0x0402d00d, 0x59980026, 0x492fc857, 0x80000040, + 0x48033026, 0x592c0000, 0x492fb107, 0x48033029, + 0x04020003, 0x4803c856, 0x48033028, 0x5c03e000, + 0x1c01f000, 0x42000000, 0x0010b855, 0x0201f800, + 0x0010aa47, 0x0401f7fa, 0x59e0000f, 0x59e0080f, + 0x80040580, 0x040207fd, 0x59e00010, 0x59e01010, + 0x80081580, 0x040207fd, 0x40065000, 0x80041580, + 0x040007c7, 0x040067dc, 0x0401f7ca, 0x4803c857, + 0x485fc857, 0x8c00050e, 0x02020800, 0x001005d0, + 0x4203e000, 0x50000000, 0x4200b800, 0x00008004, + 0x0201f000, 0x001005dd, 0x5998002b, 0x8c000500, + 0x04000013, 0x84000500, 0x4803302b, 0x59d8010a, + 0x59d8090a, 0x80040580, 0x040207fd, 0x800408e0, + 0x82040d40, 0x00000013, 0x4807c011, 0x59e00017, + 0x8c000508, 0x04000003, 0x4a03c017, 0x00000003, + 0x4203e000, 0x30000001, 0x1c01f000, 0x0402e014, 0x59da5908, 0x496a5800, 0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540, 0x00001200, - 0x48039000, 0x04006019, 0x59d8010a, 0x59d8090a, - 0x80040d80, 0x040207fd, 0x900001c0, 0x82000540, - 0x00000013, 0x4803c011, 0x5998002b, 0x84000500, - 0x4803302b, 0x59e00017, 0x8c000508, 0x04000003, - 0x4a03c017, 0x00000003, 0x4203e000, 0x30000001, - 0x59d80105, 0x82000500, 0x00018780, 0x02020000, - 0x00020482, 0x1c01f000, 0x5998002b, 0x84000540, - 0x4803302b, 0x0401f7f7, 0x5c000000, 0x4c000000, - 0x4803c857, 0x492fc857, 0x4943c857, 0x4807c857, - 0x4a025a04, 0x00000103, 0x49425a06, 0x48065a08, - 0x4a025c06, 0x0000ffff, 0x813261c0, 0x04000003, - 0x59300402, 0x48025c06, 0x832c0400, 0x00000009, - 0x04011000, 0x4803c840, 0x4a03c842, 0x0000000b, - 0x04011000, 0x1c01f000, 0x42000000, 0x0010b654, - 0x0201f800, 0x0010a86e, 0x0201f000, 0x00020464, + 0x48039000, 0x59d8090b, 0x59980024, 0x48073024, + 0x80040480, 0x04020004, 0x59940019, 0x80000540, + 0x04022003, 0x59980823, 0x48072819, 0x59d80105, + 0x82000500, 0x00018780, 0x040207c9, 0x1c01f000, + 0x59981025, 0x59e00010, 0x59e00810, 0x80041d80, + 0x040207fd, 0x80080580, 0x04000013, 0x48073025, + 0x59e0000f, 0x59e0100f, 0x80081d80, 0x040207fd, + 0x81280580, 0x04000008, 0x400a5000, 0x40080000, + 0x80040580, 0x04000003, 0x59980823, 0x48072819, + 0x1c01f000, 0x59940019, 0x80000540, 0x040227f8, + 0x0401f7fc, 0x59e0000f, 0x59e0100f, 0x80081d80, + 0x040207fd, 0x81280580, 0x040007f6, 0x400a5000, + 0x59940019, 0x80000540, 0x040027ed, 0x0401f7f1, 0x59a80017, 0x82000c80, 0x0000000a, 0x02021800, - 0x00100615, 0x0c01f809, 0x4a038805, 0x000000f0, + 0x001005d8, 0x0c01f809, 0x4a038805, 0x000000f0, 0x59c400a3, 0x82000500, 0x02870000, 0x02020800, - 0x00100615, 0x1c01f000, 0x00104c99, 0x00104c25, - 0x00104c40, 0x00104c69, 0x00104c8c, 0x00104cc6, - 0x00104cd8, 0x00104c40, 0x00104caa, 0x00104c24, + 0x001005d8, 0x1c01f000, 0x00104fc5, 0x00104f51, + 0x00104f6c, 0x00104f95, 0x00104fb8, 0x00104ff2, + 0x00105004, 0x00104f6c, 0x00104fd6, 0x00104f50, 0x1c01f000, 0x4a038808, 0x00000004, 0x0401f8f9, - 0x0201f800, 0x0010507b, 0x59c40805, 0x8c040d0e, + 0x0201f800, 0x001053ab, 0x59c40805, 0x8c040d0e, 0x04020013, 0x8c040d0a, 0x0402000b, 0x8c040d0c, 0x04020006, 0x8c040d08, 0x0400000d, 0x4a035017, 0x00000003, 0x0401f00a, 0x4a035017, 0x00000000, - 0x0401f007, 0x42000000, 0x0010b642, 0x0201f800, - 0x0010a86e, 0x4a035017, 0x00000002, 0x1c01f000, + 0x0401f007, 0x42000000, 0x0010b844, 0x0201f800, + 0x0010aa47, 0x4a035017, 0x00000002, 0x1c01f000, 0x4a038808, 0x00000002, 0x0401f8de, 0x59c40805, 0x8c040d08, 0x04020021, 0x8c040d0c, 0x0402001c, 0x8c040d0e, 0x04020017, 0x82040500, 0x000000f0, - 0x0402001c, 0x0201f800, 0x0010507b, 0x4a038808, + 0x0402001c, 0x0201f800, 0x001053ab, 0x4a038808, 0x00000080, 0x59c40002, 0x8400050c, 0x48038802, - 0x0401f9d7, 0x4d3c0000, 0x42027800, 0x00000001, - 0x0201f800, 0x00109640, 0x5c027800, 0x4a038808, + 0x0401f9d9, 0x4d3c0000, 0x42027800, 0x00000001, + 0x0201f800, 0x00109874, 0x5c027800, 0x4a038808, 0x00000080, 0x4a035017, 0x00000009, 0x0401f009, 0x4a035017, 0x00000001, 0x0401f006, 0x4a035017, 0x00000000, 0x0401f003, 0x4a035017, 0x00000003, @@ -4933,8 +5136,8 @@ uint32_t risc_code01[] = { 0x59c40805, 0x8c040d0a, 0x0402001b, 0x8c040d0c, 0x04020016, 0x8c040d0e, 0x04020011, 0x82040500, 0x000000f0, 0x04020016, 0x59c40002, 0x8400050c, - 0x48038802, 0x0401f9b2, 0x4d3c0000, 0x42027800, - 0x00000001, 0x0201f800, 0x00109640, 0x5c027800, + 0x48038802, 0x0401f9b4, 0x4d3c0000, 0x42027800, + 0x00000001, 0x0201f800, 0x00109874, 0x5c027800, 0x4a035017, 0x00000009, 0x0401f009, 0x4a035017, 0x00000001, 0x0401f006, 0x4a035017, 0x00000000, 0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000, @@ -4946,12 +5149,12 @@ uint32_t risc_code01[] = { 0x8c040d0a, 0x04020006, 0x8c040d0e, 0x04000006, 0x4a035017, 0x00000001, 0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000, 0x4a038808, 0x00000008, - 0x42001000, 0x00104d2c, 0x0201f800, 0x00105dbd, + 0x42001000, 0x00105058, 0x0201f800, 0x00106084, 0x59c40805, 0x8c040d0a, 0x0402000d, 0x8c040d08, 0x0402000b, 0x8c040d0c, 0x04020006, 0x8c040d0e, 0x0400000d, 0x4a035017, 0x00000001, 0x0401f00a, 0x4a035017, 0x00000000, 0x0401f007, 0x42000000, - 0x0010b642, 0x0201f800, 0x0010a86e, 0x4a035017, + 0x0010b844, 0x0201f800, 0x0010aa47, 0x4a035017, 0x00000004, 0x1c01f000, 0x0401f8a6, 0x0401f859, 0x59c40805, 0x8c040d0a, 0x0402000b, 0x8c040d0c, 0x04020006, 0x8c040d0e, 0x04000009, 0x4a035017, @@ -4963,242 +5166,243 @@ uint32_t risc_code01[] = { 0x4a035017, 0x00000001, 0x0401f009, 0x4a035017, 0x00000000, 0x0401f006, 0x4a035017, 0x00000003, 0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000, - 0x0401f91d, 0x02020800, 0x00100615, 0x59a80805, + 0x0401f91f, 0x02020800, 0x001005d8, 0x59a80805, 0x8c040d0c, 0x04000015, 0x84040d0c, 0x48075005, - 0x4a038805, 0x00000010, 0x0201f800, 0x001019a4, + 0x4a038805, 0x00000010, 0x0201f800, 0x00101937, 0x59c40005, 0x8c000508, 0x04000008, 0x4a038808, 0x00000008, 0x4a035033, 0x00000001, 0x4202d800, 0x00000001, 0x0401f01a, 0x59c40006, 0x84000548, 0x48038806, 0x0401f016, 0x59a80017, 0x82000580, 0x00000001, 0x0400000c, 0x59a80017, 0x82000580, - 0x00000005, 0x0402000c, 0x42000000, 0x0010b642, - 0x0201f800, 0x0010a86e, 0x4a035017, 0x00000008, - 0x0401f007, 0x42000000, 0x0010b642, 0x0201f800, - 0x0010a86e, 0x4a035017, 0x00000004, 0x1c01f000, + 0x00000005, 0x0402000c, 0x42000000, 0x0010b844, + 0x0201f800, 0x0010aa47, 0x4a035017, 0x00000008, + 0x0401f007, 0x42000000, 0x0010b844, 0x0201f800, + 0x0010aa47, 0x4a035017, 0x00000004, 0x1c01f000, 0x4803c856, 0x4c040000, 0x4c080000, 0x42000800, - 0x00000064, 0x42001000, 0x00104d2c, 0x0201f800, - 0x00105db2, 0x5c001000, 0x5c000800, 0x1c01f000, - 0x4803c856, 0x4c040000, 0x0201f800, 0x0010698c, - 0x4df00000, 0x0201f800, 0x00106b71, 0x5c03e000, - 0x02000800, 0x00106982, 0x0401ffba, 0x5c000800, + 0x00000064, 0x42001000, 0x00105058, 0x0201f800, + 0x00106079, 0x5c001000, 0x5c000800, 0x1c01f000, + 0x4803c856, 0x4c040000, 0x0201f800, 0x00106c55, + 0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x0401ffba, 0x5c000800, 0x1c01f000, 0x4803c856, 0x4c040000, 0x4c080000, - 0x0201f800, 0x0010698c, 0x4df00000, 0x0201f800, - 0x00106b71, 0x5c03e000, 0x02000800, 0x00106982, + 0x0201f800, 0x00106c55, 0x4df00000, 0x0201f800, + 0x00106e21, 0x5c03e000, 0x02000800, 0x00106c4b, 0x59c40006, 0x84000500, 0x48038806, 0x0201f800, - 0x00106c32, 0x497b8880, 0x0201f800, 0x0010a7e7, - 0x0201f800, 0x0010a7f5, 0x0201f800, 0x00101886, + 0x00106ede, 0x497b8880, 0x0201f800, 0x0010a9c0, + 0x0201f800, 0x0010a9ce, 0x0201f800, 0x00101815, 0x4a03504c, 0x00000004, 0x4202d800, 0x00000004, - 0x4a038805, 0x00000001, 0x42001000, 0x00104d2c, - 0x0201f800, 0x00105dbd, 0x0201f800, 0x0010071a, - 0x0401f8bf, 0x04000006, 0x42006000, 0xfeffffff, - 0x41786800, 0x0201f800, 0x001040ad, 0x0201f800, - 0x0010048c, 0x42000000, 0x00000001, 0x0201f800, - 0x001015fa, 0x5c001000, 0x5c000800, 0x1c01f000, + 0x4a038805, 0x00000001, 0x42001000, 0x00105058, + 0x0201f800, 0x00106084, 0x0201f800, 0x001006d4, + 0x0401f8c1, 0x04000006, 0x42006000, 0xfeffffff, + 0x41786800, 0x0201f800, 0x0010427d, 0x0201f800, + 0x00100452, 0x42000000, 0x00000001, 0x0201f800, + 0x00101590, 0x5c001000, 0x5c000800, 0x1c01f000, 0x59c40008, 0x8c000508, 0x04020007, 0x4a038808, 0x00000010, 0x4201d000, 0x00001388, 0x0201f800, - 0x00105dd2, 0x1c01f000, 0x4c040000, 0x59a80833, + 0x0010608e, 0x1c01f000, 0x4c040000, 0x59a80833, 0x82040580, 0x00000000, 0x0400000b, 0x82040580, 0x00000001, 0x0400000b, 0x82040580, 0x00000002, 0x0400000b, 0x82040580, 0x00000003, 0x0400000b, - 0x0401f055, 0x4a035017, 0x00000000, 0x0401f009, + 0x0401f057, 0x4a035017, 0x00000000, 0x0401f009, 0x4a035017, 0x00000004, 0x0401f006, 0x4a035017, 0x00000001, 0x0401f003, 0x4a035017, 0x00000007, 0x497b8880, 0x4a038893, 0x00000001, 0x41780000, - 0x0201f800, 0x00101670, 0x0201f800, 0x00106c32, + 0x0201f800, 0x00101606, 0x0201f800, 0x00106ede, 0x836c0d80, 0x00000004, 0x04000008, 0x59c40006, 0x82000500, 0xffffff0f, 0x82000540, 0x04000001, 0x48038806, 0x0401f007, 0x59c40006, 0x82000500, 0xffffff0f, 0x82000540, 0x04000000, 0x48038806, - 0x0401f873, 0x04020005, 0x59c40806, 0x82040d00, - 0xfbffff0f, 0x48078806, 0x59c40005, 0x8c000534, - 0x04020033, 0x42006000, 0xfc18ffff, 0x42006800, - 0x01000000, 0x0201f800, 0x001040ad, 0x0201f800, - 0x001019a4, 0x59c408a4, 0x82040d00, 0x0000000f, - 0x82040d80, 0x0000000c, 0x040208a9, 0x0401f85c, - 0x04000006, 0x42006000, 0xfeffffff, 0x41786800, - 0x0201f800, 0x001040ad, 0x836c0d80, 0x00000004, - 0x0400000f, 0x0401f85a, 0x04020008, 0x59940005, - 0x82000580, 0x00103f37, 0x04020004, 0x59940004, - 0x800001c0, 0x04020006, 0x59a8084d, 0x42001000, - 0x00104d39, 0x0201f800, 0x00105da7, 0x4a035033, - 0x00000004, 0x0401fe33, 0x0401f841, 0x04020008, - 0x59c408a4, 0x82040d00, 0x0000000f, 0x82040580, - 0x0000000c, 0x02020800, 0x00100615, 0x5c000800, - 0x1c01f000, 0x4803c856, 0x4c000000, 0x0201f800, - 0x00105de2, 0x4a035010, 0x00ffffff, 0x497b5032, - 0x59a8002a, 0x82000500, 0xffff0000, 0x4803502a, - 0x497b8880, 0x497b8893, 0x41780000, 0x0201f800, - 0x00101670, 0x59c40001, 0x82000500, 0xfffffcff, - 0x48038801, 0x42006000, 0xfc18ffff, 0x41786800, - 0x0201f800, 0x001040ad, 0x4a038808, 0x00000000, - 0x5c000000, 0x800001c0, 0x02020800, 0x00103f37, - 0x4a038805, 0x040000f0, 0x59c40006, 0x82000500, - 0xffffffcf, 0x82000540, 0x440000c1, 0x48038806, - 0x1c01f000, 0x4c5c0000, 0x59a8b832, 0x825cbd80, - 0x0000aaaa, 0x5c00b800, 0x1c01f000, 0x4c5c0000, - 0x599cb818, 0x825cbd00, 0x00000030, 0x825cbd80, - 0x00000000, 0x5c00b800, 0x1c01f000, 0x4c5c0000, - 0x599cb818, 0x825cbd00, 0x00000030, 0x825cbd80, - 0x00000010, 0x5c00b800, 0x1c01f000, 0x4c5c0000, - 0x599cb818, 0x825cbd00, 0x00000030, 0x825cbd80, - 0x00000020, 0x5c00b800, 0x1c01f000, 0x59a80005, - 0x4803c857, 0x82000d00, 0x00000013, 0x04000024, - 0x599c1017, 0x4d3c0000, 0x82000500, 0x00000011, - 0x04000006, 0x417a7800, 0x0201f800, 0x0010393e, - 0x0402000a, 0x0401f012, 0x42027800, 0x00000008, - 0x0201f800, 0x0010393e, 0x0400000d, 0x42003000, - 0x00000003, 0x0401f003, 0x42003000, 0x00000004, - 0x42028000, 0x0000000e, 0x0201f800, 0x0010a25b, - 0x599c1017, 0x8c08150a, 0x04020007, 0x42028000, - 0x00000004, 0x0201f800, 0x00101d90, 0x80000580, - 0x0401f80d, 0x5c027800, 0x0401f00a, 0x0201f800, - 0x0010393e, 0x04000007, 0x42028000, 0x0000000f, - 0x42003000, 0x00000001, 0x0201f800, 0x0010a25b, - 0x1c01f000, 0x59a80005, 0x04000004, 0x82000540, - 0x00000010, 0x0401f003, 0x82000500, 0xffffffef, - 0x48035005, 0x4803c857, 0x1c01f000, 0x4803c856, - 0x4c580000, 0x42000000, 0x0010b6ca, 0x0201f800, - 0x0010a86e, 0x42000800, 0x0010bef0, 0x59c40003, - 0x44000800, 0x59c40004, 0x48000801, 0x59c4000b, - 0x48000802, 0x59c4008e, 0x48000803, 0x59c4008f, - 0x48000804, 0x59c40090, 0x48000805, 0x59c40091, - 0x48000806, 0x59c40092, 0x48000807, 0x59c40093, - 0x48000808, 0x59c40099, 0x48000809, 0x59c4009e, - 0x4800080a, 0x59c400aa, 0x4800080b, 0x59c400af, - 0x4800080c, 0x59c400b2, 0x4800080d, 0x59c400b1, - 0x4800080e, 0x82040c00, 0x0000000f, 0x41c41800, - 0x4200b000, 0x00000030, 0x580c0050, 0x44000800, + 0x0401f875, 0x04020005, 0x59c40806, 0x82040d00, + 0xfbffff0f, 0x48078806, 0x4200b000, 0x00000005, + 0x59c40005, 0x8c000534, 0x04020033, 0x42006000, + 0xfc18ffff, 0x42006800, 0x01000000, 0x0201f800, + 0x0010427d, 0x0201f800, 0x00101937, 0x59c408a4, + 0x82040d00, 0x0000000f, 0x82040d80, 0x0000000c, + 0x0400000a, 0x42006000, 0xfeffffff, 0x42006800, + 0x02000000, 0x0201f800, 0x0010427d, 0x8058b040, + 0x040207e8, 0x0401f8a1, 0x0401f853, 0x04000006, + 0x42006000, 0xfeffffff, 0x41786800, 0x0201f800, + 0x0010427d, 0x836c0d80, 0x00000004, 0x04000006, + 0x59a8084d, 0x42001000, 0x00105065, 0x0201f800, + 0x0010606e, 0x4a035033, 0x00000004, 0x0401fe31, + 0x0401f841, 0x04020008, 0x59c408a4, 0x82040d00, + 0x0000000f, 0x82040580, 0x0000000c, 0x02020800, + 0x001005d8, 0x5c000800, 0x1c01f000, 0x4803c856, + 0x4c000000, 0x0201f800, 0x0010609e, 0x4a035010, + 0x00ffffff, 0x497b5032, 0x59a8002a, 0x82000500, + 0xffff0000, 0x4803502a, 0x497b8880, 0x497b8893, + 0x41780000, 0x0201f800, 0x00101606, 0x59c40001, + 0x82000500, 0xfffffcff, 0x48038801, 0x42006000, + 0xfc18ffff, 0x41786800, 0x0201f800, 0x0010427d, + 0x4a038808, 0x00000000, 0x5c000000, 0x800001c0, + 0x02020800, 0x0010411d, 0x4a038805, 0x040000f0, + 0x59c40006, 0x82000500, 0xffffffcf, 0x82000540, + 0x440000c1, 0x48038806, 0x1c01f000, 0x4c5c0000, + 0x59a8b832, 0x825cbd80, 0x0000aaaa, 0x5c00b800, + 0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00, + 0x00000030, 0x825cbd80, 0x00000000, 0x5c00b800, + 0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00, + 0x00000030, 0x825cbd80, 0x00000010, 0x5c00b800, + 0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00, + 0x00000030, 0x825cbd80, 0x00000020, 0x5c00b800, + 0x1c01f000, 0x59a80005, 0x4803c857, 0x82000d00, + 0x00000013, 0x04000025, 0x599c1017, 0x4d3c0000, + 0x82000500, 0x00000011, 0x04000007, 0x42027800, + 0x00000400, 0x0201f800, 0x00103b25, 0x0402000a, + 0x0401f012, 0x42027800, 0x00000408, 0x0201f800, + 0x00103b25, 0x0400000d, 0x42003000, 0x00000003, + 0x0401f003, 0x42003000, 0x00000004, 0x42028000, + 0x0000000e, 0x0201f800, 0x0010a449, 0x599c1017, + 0x8c08150a, 0x04020007, 0x42028000, 0x00000004, + 0x0201f800, 0x00101fe5, 0x80000580, 0x0401f80d, + 0x5c027800, 0x0401f00a, 0x0201f800, 0x00103b25, + 0x04000007, 0x42028000, 0x0000000f, 0x42003000, + 0x00000001, 0x0201f800, 0x0010a449, 0x1c01f000, + 0x59a80005, 0x04000004, 0x82000540, 0x00000010, + 0x0401f003, 0x82000500, 0xffffffef, 0x48035005, + 0x4803c857, 0x1c01f000, 0x4803c856, 0x4c580000, + 0x42000000, 0x0010b8cb, 0x0201f800, 0x0010aa47, + 0x42000800, 0x0010c0f1, 0x59c40003, 0x44000800, + 0x59c40004, 0x48000801, 0x59c4000b, 0x48000802, + 0x59c4008e, 0x48000803, 0x59c4008f, 0x48000804, + 0x59c40090, 0x48000805, 0x59c40091, 0x48000806, + 0x59c40092, 0x48000807, 0x59c40093, 0x48000808, + 0x59c40099, 0x48000809, 0x59c4009e, 0x4800080a, + 0x59c400aa, 0x4800080b, 0x59c400af, 0x4800080c, + 0x59c400b2, 0x4800080d, 0x59c400b1, 0x4800080e, + 0x82040c00, 0x0000000f, 0x41c41800, 0x4200b000, + 0x00000030, 0x580c0050, 0x44000800, 0x80040800, + 0x800c1800, 0x8058b040, 0x040207fb, 0x41c41800, + 0x4200b000, 0x00000020, 0x580c0010, 0x44000800, + 0x80040800, 0x800c1800, 0x8058b040, 0x040207fb, + 0x497b8830, 0x4200b000, 0x00000040, 0x59c40031, + 0x44000800, 0x80040800, 0x8058b040, 0x040207fc, + 0x497b88ac, 0x4200b000, 0x00000010, 0x59c400ad, + 0x44000800, 0x80040800, 0x8058b040, 0x040207fc, + 0x59c41001, 0x4c080000, 0x8408150c, 0x480b8801, + 0x4a0370e4, 0x00000300, 0x4a0370e5, 0xb0000000, + 0x42000800, 0x00000800, 0x80040840, 0x02000800, + 0x001005d8, 0x59b800e5, 0x8c000538, 0x040207fb, + 0x4a0370e4, 0x00000200, 0x42006000, 0xffffffff, + 0x42006800, 0x80000000, 0x0201f800, 0x0010427d, + 0x4a038807, 0x00000001, 0x497b8807, 0x4a038808, + 0x00000010, 0x42006000, 0xfcf8ffff, 0x42006800, + 0x01000000, 0x0201f800, 0x0010427d, 0x5c001000, + 0x480b8801, 0x42000800, 0x0010c0f1, 0x50040000, + 0x48038803, 0x58040001, 0x48038804, 0x58040002, + 0x4803880b, 0x58040003, 0x4803888e, 0x58040004, + 0x4803888f, 0x58040005, 0x48038890, 0x58040006, + 0x48038891, 0x58040007, 0x48038892, 0x58040008, + 0x48038893, 0x58040009, 0x48038899, 0x5804000a, + 0x4803889e, 0x5804000b, 0x480388aa, 0x5804000c, + 0x480388af, 0x5804000d, 0x480388b2, 0x5804000e, + 0x480388b1, 0x82040c00, 0x0000000f, 0x41c41800, + 0x4200b000, 0x00000030, 0x50040000, 0x48001850, 0x80040800, 0x800c1800, 0x8058b040, 0x040207fb, - 0x41c41800, 0x4200b000, 0x00000020, 0x580c0010, - 0x44000800, 0x80040800, 0x800c1800, 0x8058b040, + 0x41c41800, 0x4200b000, 0x00000020, 0x50040000, + 0x48001810, 0x80040800, 0x800c1800, 0x8058b040, 0x040207fb, 0x497b8830, 0x4200b000, 0x00000040, - 0x59c40031, 0x44000800, 0x80040800, 0x8058b040, + 0x50040000, 0x48038831, 0x80040800, 0x8058b040, 0x040207fc, 0x497b88ac, 0x4200b000, 0x00000010, - 0x59c400ad, 0x44000800, 0x80040800, 0x8058b040, - 0x040207fc, 0x59c41001, 0x4c080000, 0x8408150c, - 0x480b8801, 0x4a0370e4, 0x00000300, 0x4a0370e5, - 0xb0000000, 0x42000800, 0x00000800, 0x80040840, - 0x02000800, 0x00100615, 0x59b800e5, 0x8c000538, - 0x040207fb, 0x4a0370e4, 0x00000200, 0x42006000, - 0xffffffff, 0x42006800, 0x80000000, 0x0201f800, - 0x001040ad, 0x4a038807, 0x00000001, 0x497b8807, - 0x4a038808, 0x00000010, 0x42006000, 0xfcf8ffff, - 0x42006800, 0x01000000, 0x0201f800, 0x001040ad, - 0x5c001000, 0x480b8801, 0x42000800, 0x0010bef0, - 0x50040000, 0x48038803, 0x58040001, 0x48038804, - 0x58040002, 0x4803880b, 0x58040003, 0x4803888e, - 0x58040004, 0x4803888f, 0x58040005, 0x48038890, - 0x58040006, 0x48038891, 0x58040007, 0x48038892, - 0x58040008, 0x48038893, 0x58040009, 0x48038899, - 0x5804000a, 0x4803889e, 0x5804000b, 0x480388aa, - 0x5804000c, 0x480388af, 0x5804000d, 0x480388b2, - 0x5804000e, 0x480388b1, 0x82040c00, 0x0000000f, - 0x41c41800, 0x4200b000, 0x00000030, 0x50040000, - 0x48001850, 0x80040800, 0x800c1800, 0x8058b040, - 0x040207fb, 0x41c41800, 0x4200b000, 0x00000020, - 0x50040000, 0x48001810, 0x80040800, 0x800c1800, - 0x8058b040, 0x040207fb, 0x497b8830, 0x4200b000, - 0x00000040, 0x50040000, 0x48038831, 0x80040800, - 0x8058b040, 0x040207fc, 0x497b88ac, 0x4200b000, - 0x00000010, 0x50040000, 0x480388ad, 0x80040800, - 0x8058b040, 0x040207fc, 0x497b8880, 0x41780000, - 0x0201f800, 0x00101670, 0x59c408a4, 0x82040d00, - 0x0000000f, 0x82040580, 0x0000000c, 0x02020800, - 0x00100615, 0x4a038805, 0x04000000, 0x5c00b000, - 0x1c01f000, 0x4803c856, 0x4c580000, 0x4ce80000, - 0x42000000, 0x0010b643, 0x0201f800, 0x0010a86e, - 0x59c41008, 0x4c080000, 0x82080500, 0xffffff7f, - 0x48038808, 0x59c40004, 0x82000500, 0x00003e02, - 0x04000005, 0x4201d000, 0x00000014, 0x0201f800, - 0x00105dd2, 0x59c40006, 0x82000500, 0xffffff0f, - 0x48038806, 0x4a038805, 0x00000010, 0x4a038808, - 0x00000004, 0x4200b000, 0x00000065, 0x59c40005, - 0x8c000508, 0x04020012, 0x4201d000, 0x000003e8, - 0x0201f800, 0x00105dd2, 0x8058b040, 0x040207f8, - 0x0201f800, 0x00106c32, 0x4a038808, 0x00000008, - 0x4a035033, 0x00000001, 0x4202d800, 0x00000001, - 0x82000540, 0x00000001, 0x0401f030, 0x0201f800, - 0x00100b29, 0x42000000, 0x0010b6a7, 0x0201f800, - 0x0010a86e, 0x0201f800, 0x00100f42, 0x497b8880, - 0x59a8002a, 0x82000500, 0x0000ffff, 0x4c000000, - 0x0201f800, 0x00101670, 0x5c000000, 0x48038880, - 0x4a038808, 0x00000000, 0x4200b000, 0x00000065, - 0x4a038805, 0x000000f0, 0x0201f800, 0x001019a4, - 0x42000800, 0x000000f0, 0x59c40005, 0x80040d00, - 0x04000008, 0x4201d000, 0x000003e8, 0x0201f800, - 0x00105dd2, 0x8058b040, 0x040207f2, 0x0401f7d1, - 0x59c40006, 0x82000540, 0x000000f0, 0x48038806, - 0x59a8001e, 0x80000540, 0x04020002, 0x80000000, - 0x48038893, 0x80000580, 0x5c001000, 0x4df00000, - 0x0201f800, 0x001019ca, 0x5c03e000, 0x480b8808, - 0x5c01d000, 0x5c00b000, 0x1c01f000, 0x4803c856, - 0x4c580000, 0x4ce80000, 0x59c41008, 0x82080500, - 0xffffff7f, 0x48038808, 0x4c080000, 0x59c40004, - 0x82000500, 0x00003e02, 0x04000005, 0x4201d000, - 0x00000014, 0x0201f800, 0x00105dd2, 0x0201f800, - 0x00100b29, 0x42000000, 0x0010b6a8, 0x0201f800, - 0x0010a86e, 0x0201f800, 0x00100f42, 0x4a038808, - 0x00000002, 0x80000580, 0x48038880, 0x48038893, - 0x0201f800, 0x00101670, 0x4200b000, 0x00000384, - 0x4a038805, 0x000000f0, 0x0201f800, 0x001019a4, - 0x42000800, 0x000000f0, 0x59c40005, 0x80040d00, - 0x04000015, 0x82000500, 0x000000d0, 0x04020012, - 0x4201d000, 0x00000067, 0x0201f800, 0x00105dd2, - 0x8058b040, 0x040207ef, 0x0201f800, 0x00106c32, - 0x4a038808, 0x00000008, 0x4a035033, 0x00000001, - 0x4202d800, 0x00000001, 0x82000540, 0x00000001, - 0x0401f010, 0x497b8880, 0x59a8001e, 0x80000540, - 0x04020002, 0x80000000, 0x48038893, 0x59a8002a, + 0x50040000, 0x480388ad, 0x80040800, 0x8058b040, + 0x040207fc, 0x497b8880, 0x41780000, 0x0201f800, + 0x00101606, 0x59c408a4, 0x82040d00, 0x0000000f, + 0x82040580, 0x0000000c, 0x02020800, 0x001005d8, + 0x4a038805, 0x04000000, 0x5c00b000, 0x1c01f000, + 0x4803c856, 0x4c580000, 0x4ce80000, 0x42000000, + 0x0010b845, 0x0201f800, 0x0010aa47, 0x59c41008, + 0x4c080000, 0x82080500, 0xffffff7f, 0x48038808, + 0x59c40004, 0x82000500, 0x00003e02, 0x04000005, + 0x4201d000, 0x00000014, 0x0201f800, 0x0010608e, + 0x59c40006, 0x82000500, 0xffffff0f, 0x48038806, + 0x4a038805, 0x00000010, 0x4a038808, 0x00000004, + 0x4200b000, 0x00000065, 0x59c40005, 0x8c000508, + 0x04020012, 0x4201d000, 0x000003e8, 0x0201f800, + 0x0010608e, 0x8058b040, 0x040207f8, 0x0201f800, + 0x00106ede, 0x4a038808, 0x00000008, 0x4a035033, + 0x00000001, 0x4202d800, 0x00000001, 0x82000540, + 0x00000001, 0x0401f030, 0x0201f800, 0x00100ae0, + 0x42000000, 0x0010b8a8, 0x0201f800, 0x0010aa47, + 0x0201f800, 0x00100ef4, 0x497b8880, 0x59a8002a, 0x82000500, 0x0000ffff, 0x4c000000, 0x0201f800, - 0x00101670, 0x5c000000, 0x48038880, 0x80000580, - 0x5c001000, 0x4df00000, 0x0201f800, 0x001019ca, - 0x5c03e000, 0x480b8808, 0x5c01d000, 0x5c00b000, - 0x1c01f000, 0x4803c856, 0x59c40004, 0x82000500, - 0x00003e02, 0x0400000a, 0x0201f800, 0x00106c32, - 0x4a038808, 0x00000008, 0x4a035033, 0x00000001, - 0x4202d800, 0x00000001, 0x0401f052, 0x0201f800, - 0x00100b29, 0x42000000, 0x0010b6a9, 0x0201f800, - 0x0010a86e, 0x0201f800, 0x00100f42, 0x59c40006, - 0x84000508, 0x48038806, 0x4a038805, 0x00000010, - 0x59a80805, 0x84040d4c, 0x48075005, 0x42000800, - 0x00000064, 0x42001000, 0x00104d2c, 0x0201f800, - 0x00105da7, 0x4a038808, 0x00000000, 0x497b8880, - 0x4a038805, 0x000000f0, 0x0201f800, 0x001019a4, - 0x42000800, 0x000000f0, 0x59c40005, 0x80040d00, - 0x0400000e, 0x82000500, 0x000000e0, 0x0402000b, - 0x4201d000, 0x000003e8, 0x0201f800, 0x00105dd2, - 0x0201f800, 0x00105c81, 0x59940004, 0x80000540, - 0x040207ec, 0x0401f023, 0x4c080000, 0x42001000, - 0x00104d39, 0x0201f800, 0x00105cc9, 0x42001000, - 0x00104d2c, 0x0201f800, 0x00105dbd, 0x5c001000, + 0x00101606, 0x5c000000, 0x48038880, 0x4a038808, + 0x00000000, 0x4200b000, 0x00000065, 0x4a038805, + 0x000000f0, 0x0201f800, 0x00101937, 0x42000800, + 0x000000f0, 0x59c40005, 0x80040d00, 0x04000008, + 0x4201d000, 0x000003e8, 0x0201f800, 0x0010608e, + 0x8058b040, 0x040207f2, 0x0401f7d1, 0x59c40006, + 0x82000540, 0x000000f0, 0x48038806, 0x59a8001e, + 0x80000540, 0x04020002, 0x80000000, 0x48038893, + 0x80000580, 0x5c001000, 0x4df00000, 0x0201f800, + 0x0010195d, 0x5c03e000, 0x480b8808, 0x5c01d000, + 0x5c00b000, 0x1c01f000, 0x4803c856, 0x4c580000, + 0x4ce80000, 0x59c41008, 0x82080500, 0xffffff7f, + 0x48038808, 0x4c080000, 0x59c40004, 0x82000500, + 0x00003e02, 0x04000005, 0x4201d000, 0x00000014, + 0x0201f800, 0x0010608e, 0x0201f800, 0x00100ae0, + 0x42000000, 0x0010b8a9, 0x0201f800, 0x0010aa47, + 0x0201f800, 0x00100ef4, 0x4a038808, 0x00000002, + 0x80000580, 0x48038880, 0x48038893, 0x0201f800, + 0x00101606, 0x4200b000, 0x00000384, 0x4a038805, + 0x000000f0, 0x0201f800, 0x00101937, 0x42000800, + 0x000000f0, 0x59c40005, 0x80040d00, 0x04000015, + 0x82000500, 0x000000d0, 0x04020012, 0x4201d000, + 0x00000067, 0x0201f800, 0x0010608e, 0x8058b040, + 0x040207ef, 0x0201f800, 0x00106ede, 0x4a038808, + 0x00000008, 0x4a035033, 0x00000001, 0x4202d800, + 0x00000001, 0x82000540, 0x00000001, 0x0401f010, 0x497b8880, 0x59a8001e, 0x80000540, 0x04020002, 0x80000000, 0x48038893, 0x59a8002a, 0x82000500, - 0x0000ffff, 0x4c000000, 0x0201f800, 0x00101670, - 0x5c000000, 0x48038880, 0x59a80805, 0x84040d0c, - 0x48075005, 0x59c40006, 0x84000548, 0x48038806, - 0x0201f800, 0x001019ca, 0x4a038808, 0x00000080, - 0x1c01f000, 0x4803c856, 0x4d400000, 0x4d3c0000, - 0x0201f800, 0x00106c32, 0x0201f800, 0x0010a95a, - 0x04020024, 0x599c1017, 0x59a80805, 0x8c040d00, - 0x0402000c, 0x8c08151a, 0x0400001e, 0x84040d42, - 0x48075005, 0x42028000, 0x00000004, 0x42027800, - 0x00000008, 0x8c081508, 0x04020007, 0x0401f011, - 0x42028000, 0x00000004, 0x417a7800, 0x8c081508, + 0x0000ffff, 0x4c000000, 0x0201f800, 0x00101606, + 0x5c000000, 0x48038880, 0x80000580, 0x5c001000, + 0x4df00000, 0x0201f800, 0x0010195d, 0x5c03e000, + 0x480b8808, 0x5c01d000, 0x5c00b000, 0x1c01f000, + 0x4803c856, 0x59c40004, 0x82000500, 0x00003e02, + 0x0400000a, 0x0201f800, 0x00106ede, 0x4a038808, + 0x00000008, 0x4a035033, 0x00000001, 0x4202d800, + 0x00000001, 0x0401f052, 0x0201f800, 0x00100ae0, + 0x42000000, 0x0010b8aa, 0x0201f800, 0x0010aa47, + 0x0201f800, 0x00100ef4, 0x59c40006, 0x84000508, + 0x48038806, 0x4a038805, 0x00000010, 0x59a80805, + 0x84040d4c, 0x48075005, 0x42000800, 0x00000064, + 0x42001000, 0x00105058, 0x0201f800, 0x0010606e, + 0x4a038808, 0x00000000, 0x497b8880, 0x4a038805, + 0x000000f0, 0x0201f800, 0x00101937, 0x42000800, + 0x000000f0, 0x59c40005, 0x80040d00, 0x0400000e, + 0x82000500, 0x000000e0, 0x0402000b, 0x4201d000, + 0x000003e8, 0x0201f800, 0x0010608e, 0x0201f800, + 0x00105f48, 0x59940004, 0x80000540, 0x040207ec, + 0x0401f023, 0x4c080000, 0x42001000, 0x00105065, + 0x0201f800, 0x00105f90, 0x42001000, 0x00105058, + 0x0201f800, 0x00106084, 0x5c001000, 0x497b8880, + 0x59a8001e, 0x80000540, 0x04020002, 0x80000000, + 0x48038893, 0x59a8002a, 0x82000500, 0x0000ffff, + 0x4c000000, 0x0201f800, 0x00101606, 0x5c000000, + 0x48038880, 0x59a80805, 0x84040d0c, 0x48075005, + 0x59c40006, 0x84000548, 0x48038806, 0x0201f800, + 0x0010195d, 0x4a038808, 0x00000080, 0x1c01f000, + 0x4803c856, 0x4d400000, 0x4d3c0000, 0x0201f800, + 0x00106ede, 0x0201f800, 0x0010ab33, 0x04020025, + 0x599c1017, 0x59a80805, 0x8c040d00, 0x0402000c, + 0x8c08151a, 0x0400001f, 0x84040d42, 0x48075005, + 0x42028000, 0x00000004, 0x42027800, 0x0000000c, + 0x8c081508, 0x04020008, 0x0401f012, 0x42028000, + 0x00000004, 0x42027800, 0x00000004, 0x8c081508, 0x0400000c, 0x4d400000, 0x42028000, 0x0000000e, - 0x42028800, 0x0000ffff, 0x0201f800, 0x0010a258, + 0x42028800, 0x0000ffff, 0x0201f800, 0x0010a446, 0x5c028000, 0x599c0817, 0x8c040d0a, 0x04020005, - 0x4943c857, 0x493fc857, 0x0201f800, 0x00101d90, - 0x497b8880, 0x4202d800, 0x00000001, 0x0401fcff, + 0x4943c857, 0x493fc857, 0x0201f800, 0x00101fe5, + 0x497b8880, 0x4202d800, 0x00000001, 0x0401fcfb, 0x5c027800, 0x5c028000, 0x1c01f000, 0x0201f800, - 0x00100b29, 0x42000000, 0x0010b6aa, 0x0201f800, - 0x0010a86e, 0x0201f800, 0x00100f42, 0x42000000, - 0x00000001, 0x0201f800, 0x00101670, 0x4a038880, - 0x00000001, 0x0201f000, 0x001019ca, 0x4202e000, + 0x00100ae0, 0x42000000, 0x0010b8ab, 0x0201f800, + 0x0010aa47, 0x0201f800, 0x00100ef4, 0x42000000, + 0x00000001, 0x0201f800, 0x00101606, 0x4a038880, + 0x00000001, 0x0201f000, 0x0010195d, 0x4202e000, 0x00000000, 0x4a033015, 0x00000001, 0x497b301d, 0x497b3006, 0x4a03b004, 0x60000001, 0x59d80005, 0x4a03b004, 0x90000001, 0x4a03a804, 0x60000001, 0x59d40005, 0x4a03a804, 0x90000001, 0x0201f000, - 0x00105667, 0x4a03c825, 0x00000004, 0x4a03c827, + 0x00105983, 0x4a03c825, 0x00000004, 0x4a03c827, 0x00000004, 0x599c0409, 0x80000d40, 0x04000020, 0x599c0407, 0x80000540, 0x04000007, 0x800000cc, 0x599c100b, 0x80080400, 0x4803b000, 0x497bb002, @@ -5217,75 +5421,71 @@ uint32_t risc_code01[] = { 0x00000004, 0x4a03a804, 0x10000001, 0x59e00803, 0x82040d00, 0xfffffbff, 0x82040d40, 0x00008000, 0x4807c003, 0x800409c0, 0x04000007, 0x4202e000, - 0x00000001, 0x0200b800, 0x00020685, 0x0200f000, - 0x0002069a, 0x1c01f000, 0x0201f800, 0x00100615, + 0x00000001, 0x0200b800, 0x00020551, 0x0200f000, + 0x00020566, 0x1c01f000, 0x0201f800, 0x001005d8, 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, 0x59981005, 0x800811c0, 0x0400001e, 0x58080005, - 0x82000d00, 0x43018780, 0x02020000, 0x0010552a, + 0x82000d00, 0x43018780, 0x02020000, 0x00105846, 0x8c000508, 0x04000015, 0x580a5808, 0x592c0204, 0x497a5800, 0x497a5801, 0x82000500, 0x000000ff, 0x82000c80, 0x0000004b, 0x0402100b, 0x0c01f80f, 0x5c03e000, 0x83700580, 0x00000003, 0x040007e6, - 0x0200f800, 0x0002069a, 0x0200b000, 0x00020685, + 0x0200f800, 0x00020566, 0x0200b000, 0x00020551, 0x1c01f000, 0x0401f850, 0x5c03e000, 0x0401f7f9, - 0x0401f8ee, 0x0401f7fd, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105171, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x001051f9, 0x00105161, 0x00105161, 0x00105171, - 0x00105171, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x492fc857, 0x42000000, 0x0010b65d, - 0x0201f800, 0x0010a86e, 0x42000000, 0x00000400, - 0x0401f019, 0x492fc857, 0x42000000, 0x0010b65c, - 0x0201f800, 0x0010a86e, 0x42000000, 0x00001000, - 0x0401f011, 0x492fc857, 0x42000000, 0x0010b65b, - 0x0201f800, 0x0010a86e, 0x42000000, 0x00002000, - 0x0401f009, 0x492fc857, 0x42000000, 0x0010b65e, - 0x0201f800, 0x0010a86e, 0x42000000, 0x00000800, + 0x0401f8de, 0x0401f7fd, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x001054a1, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105519, 0x00105491, 0x00105491, 0x001054a1, + 0x001054a1, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x492fc857, 0x42000000, 0x0010b85e, + 0x0201f800, 0x0010aa47, 0x42000000, 0x00000400, + 0x0401f019, 0x492fc857, 0x42000000, 0x0010b85d, + 0x0201f800, 0x0010aa47, 0x42000000, 0x00001000, + 0x0401f011, 0x492fc857, 0x42000000, 0x0010b85c, + 0x0201f800, 0x0010aa47, 0x42000000, 0x00002000, + 0x0401f009, 0x492fc857, 0x42000000, 0x0010b85f, + 0x0201f800, 0x0010aa47, 0x42000000, 0x00000800, 0x0401f001, 0x4803c857, 0x4202e000, 0x00000001, 0x592c0c04, 0x82040d00, 0xffff80ff, 0x80040540, - 0x48025c04, 0x0201f000, 0x00020381, 0x592c0204, + 0x48025c04, 0x0201f000, 0x000202da, 0x592c0204, 0x492fc857, 0x80000110, 0x040007db, 0x80000040, - 0x04000035, 0x48033002, 0x492f3003, 0x492f3004, - 0x4a033008, 0x001051c5, 0x4202e000, 0x00000003, + 0x04000025, 0x48033002, 0x492f3003, 0x492f3004, + 0x4a033008, 0x001054e5, 0x4202e000, 0x00000003, 0x1c01f000, 0x592c0204, 0x492fc857, 0x80000110, - 0x040007cd, 0x80000040, 0x04000043, 0x48033002, - 0x492f3003, 0x492f3004, 0x4a033008, 0x001051e1, - 0x4202e000, 0x00000003, 0x1c01f000, 0x492fc857, - 0x0201f800, 0x0010a95a, 0x02020000, 0x0002060c, - 0x492fc857, 0x592e8a06, 0x83440c80, 0x000007f0, - 0x0402100b, 0x83440400, 0x0010aa00, 0x50000000, - 0x80026d40, 0x04000006, 0x4937c857, 0x59340200, - 0x8c00050e, 0x02020000, 0x0002060c, 0x42028000, + 0x040007cd, 0x80000040, 0x04000033, 0x48033002, + 0x492f3003, 0x492f3004, 0x4a033008, 0x00105501, + 0x4202e000, 0x00000003, 0x1c01f000, 0x0201f800, + 0x0010ab33, 0x02020000, 0x000204d9, 0x42028000, 0x00000028, 0x41780800, 0x417a6000, 0x0201f800, - 0x00104bee, 0x0201f800, 0x00108f7d, 0x0201f000, - 0x00020381, 0x592c0a0a, 0x8c040d02, 0x04020016, + 0x00104e70, 0x0201f800, 0x001091c6, 0x0201f000, + 0x000202da, 0x592c0a0a, 0x8c040d02, 0x04020016, 0x59a80021, 0x492fc857, 0x80000540, 0x0402000f, 0x592c0207, 0x80000540, 0x04000005, 0x0201f800, - 0x00104156, 0x04020004, 0x1c01f000, 0x42000000, + 0x00104326, 0x04020004, 0x1c01f000, 0x42000000, 0x00000000, 0x592c0a06, 0x48065c06, 0x48025a06, - 0x0201f000, 0x00020381, 0x42000000, 0x00000028, + 0x0201f000, 0x000202da, 0x42000000, 0x00000028, 0x0401f7f9, 0x42000800, 0x00000009, 0x0201f000, - 0x001063a9, 0x592c0208, 0x492fc857, 0x82000c80, - 0x0000199a, 0x04021794, 0x592c0408, 0x80000540, - 0x04020791, 0x59a80821, 0x800409c0, 0x04020009, - 0x592c0207, 0x80000540, 0x0400078b, 0x497a5a06, - 0x0201f800, 0x001041b5, 0x04020004, 0x1c01f000, + 0x0010665b, 0x592c0208, 0x492fc857, 0x82000c80, + 0x0000199a, 0x040217a4, 0x592c0408, 0x80000540, + 0x040207a1, 0x59a80821, 0x800409c0, 0x04020009, + 0x592c0207, 0x80000540, 0x0400079b, 0x497a5a06, + 0x0201f800, 0x00104385, 0x04020004, 0x1c01f000, 0x42000000, 0x00000028, 0x48025a06, 0x0201f000, - 0x00020381, 0x59980804, 0x59980002, 0x48065800, + 0x000202da, 0x59980804, 0x59980002, 0x48065800, 0x492c0801, 0x492f3004, 0x80000040, 0x48033002, 0x04000002, 0x1c01f000, 0x599a5803, 0x59980008, 0x4202e000, 0x00000001, 0x0801f000, 0x592e8a06, @@ -5293,70 +5493,69 @@ uint32_t risc_code01[] = { 0x4200b800, 0x00000001, 0x82000d80, 0x00000001, 0x04000015, 0x417a8800, 0x4200b800, 0x000007f0, 0x82000d80, 0x00000002, 0x0400000f, 0x80000540, - 0x02020000, 0x00020381, 0x592e8a06, 0x0201f800, - 0x00020267, 0x02020000, 0x00020381, 0x592e9008, - 0x592e9809, 0x0201f800, 0x00104567, 0x0201f000, - 0x00020381, 0x59a80805, 0x84040d00, 0x48075005, - 0x0201f800, 0x00020267, 0x02000800, 0x0010467a, + 0x02020000, 0x000202da, 0x592e8a06, 0x0201f800, + 0x00020245, 0x02020000, 0x000202da, 0x592e9008, + 0x592e9809, 0x0201f800, 0x00104713, 0x0201f000, + 0x000202da, 0x59a80805, 0x84040d00, 0x48075005, + 0x0201f800, 0x00020245, 0x02000800, 0x0010482c, 0x81468800, 0x805cb840, 0x040207fa, 0x0201f000, - 0x00020381, 0x592c0a08, 0x4807c857, 0x82040580, + 0x000202da, 0x592c0a08, 0x4807c857, 0x82040580, 0x0000000e, 0x04000045, 0x82040580, 0x00000046, 0x04000046, 0x82040580, 0x00000045, 0x04000020, 0x82040580, 0x00000029, 0x04000010, 0x82040580, 0x0000002a, 0x04000009, 0x82040580, 0x0000000f, - 0x04000200, 0x82040580, 0x0000002e, 0x040001fd, - 0x4807c856, 0x0401f1f6, 0x59a80805, 0x84040d04, - 0x48075005, 0x0401f1f7, 0x592e8a06, 0x0201f800, - 0x00020267, 0x040201f3, 0x59340200, 0x84000518, + 0x040001fc, 0x82040580, 0x0000002e, 0x040001f9, + 0x4807c856, 0x0401f1f2, 0x59a80805, 0x84040d04, + 0x48075005, 0x0401f1f3, 0x592e8a06, 0x0201f800, + 0x00020245, 0x040201ef, 0x59340200, 0x84000518, 0x48026a00, 0x592e6009, 0x4933c857, 0x83300580, - 0xffffffff, 0x0402002a, 0x0401f1ea, 0x592c1407, - 0x480bc857, 0x0201f800, 0x001091d9, 0x411e6000, - 0x04020003, 0x4803c856, 0x0401f1dd, 0x592e3809, + 0xffffffff, 0x0402002a, 0x0401f1e6, 0x592c1407, + 0x480bc857, 0x0201f800, 0x00109410, 0x411e6000, + 0x04020003, 0x4803c856, 0x0401f1d9, 0x592e3809, 0x591c1414, 0x84081516, 0x84081554, 0x480a3c14, 0x4a026403, 0x0000003a, 0x592c040b, 0x80000540, 0x04000007, 0x4a026403, 0x0000003b, 0x592c020c, 0x4802641a, 0x592c040c, 0x4802621a, 0x4a026203, 0x00000001, 0x42000800, 0x80000040, 0x0201f800, - 0x00020855, 0x0401f1cb, 0x59a80068, 0x84000510, - 0x48035068, 0x0401f1c7, 0x592c1207, 0x8c081500, - 0x040201c4, 0x592e8a06, 0x592e6009, 0x0201f800, - 0x001091e3, 0x04020003, 0x4803c856, 0x0401f1b8, + 0x00020721, 0x0401f1c7, 0x59a80068, 0x84000510, + 0x48035068, 0x0401f1c3, 0x592c1207, 0x8c081500, + 0x040201c0, 0x592e8a06, 0x592e6009, 0x0201f800, + 0x0010941a, 0x04020003, 0x4803c856, 0x0401f1b4, 0x59300c06, 0x82040580, 0x00000004, 0x04000003, - 0x4803c856, 0x0401f1b2, 0x59300a03, 0x82040580, - 0x00000007, 0x04000003, 0x4803c856, 0x0401f1ac, - 0x59300c03, 0x82040580, 0x00000001, 0x04000025, - 0x82040580, 0x00000003, 0x0400001a, 0x82040580, - 0x00000006, 0x04000024, 0x82040580, 0x00000008, - 0x04000019, 0x82040580, 0x0000000a, 0x0400000a, + 0x4803c856, 0x0401f1ae, 0x59300a03, 0x82040580, + 0x00000007, 0x04000003, 0x4803c856, 0x0401f1a8, + 0x59300c03, 0x82040580, 0x00000001, 0x04000021, + 0x82040580, 0x00000003, 0x04000016, 0x82040580, + 0x00000006, 0x04000020, 0x82040580, 0x00000008, + 0x04000015, 0x82040580, 0x0000000a, 0x0400000a, 0x82040580, 0x0000000c, 0x04000004, 0x82040580, - 0x0000002e, 0x0402001c, 0x42000800, 0x00000009, - 0x0401f017, 0x59326809, 0x0201f800, 0x0010484b, - 0x04020015, 0x42000800, 0x00000005, 0x0401f010, - 0x417a7800, 0x0201f800, 0x00101de2, 0x4a026406, + 0x0000002e, 0x04020018, 0x42000800, 0x00000009, + 0x0401f013, 0x42000800, 0x00000005, 0x0401f010, + 0x417a7800, 0x0201f800, 0x0010203c, 0x4a026406, 0x00000001, 0x42000800, 0x00000003, 0x0401f008, - 0x417a7800, 0x0201f800, 0x00101de2, 0x4a026406, + 0x417a7800, 0x0201f800, 0x0010203c, 0x4a026406, 0x00000001, 0x42000800, 0x0000000b, 0x0201f800, - 0x001043c7, 0x4a026203, 0x00000001, 0x0201f800, - 0x00106470, 0x0401f17b, 0x40000800, 0x58040000, + 0x00104571, 0x4a026203, 0x00000001, 0x0201f800, + 0x0010672b, 0x0401f17b, 0x40000800, 0x58040000, 0x80000540, 0x040207fd, 0x492c0800, 0x1c01f000, 0x492fc857, 0x59300c06, 0x82040580, 0x00000006, - 0x04020094, 0x0201f800, 0x00104836, 0x04020005, - 0x59340200, 0x8c00051a, 0x02000000, 0x00020667, + 0x04020094, 0x0201f800, 0x001049e7, 0x04020005, + 0x59340200, 0x8c00051a, 0x02000000, 0x00020533, 0x59340200, 0x8c00050e, 0x0400008a, 0x59300203, 0x42027800, 0x00000001, 0x82000580, 0x00000007, - 0x02020000, 0x00020667, 0x4a026203, 0x00000002, - 0x0201f000, 0x00020667, 0x42028000, 0x00000002, + 0x02020000, 0x00020533, 0x4a026203, 0x00000002, + 0x0201f000, 0x00020533, 0x42028000, 0x00000002, 0x4a026206, 0x00000014, 0x4d2c0000, 0x0201f800, - 0x00109fc0, 0x5c025800, 0x59300c06, 0x4807c857, + 0x0010a1d1, 0x5c025800, 0x59300c06, 0x4807c857, 0x82040580, 0x00000007, 0x04020063, 0x492fc857, - 0x4a025a06, 0x00000001, 0x0201f000, 0x00020381, + 0x4a025a06, 0x00000001, 0x0201f000, 0x000202da, 0x592c240a, 0x492fc857, 0x4813c857, 0x8c10251c, 0x04020016, 0x8c10251a, 0x04000003, 0x8c10250a, 0x04000069, 0x59340a00, 0x8c040d0e, 0x04000003, - 0x8c10251e, 0x04000064, 0x0201f800, 0x00020892, + 0x8c10251e, 0x04000064, 0x0201f800, 0x0002075a, 0x0400006b, 0x592c240a, 0x49366009, 0x49325809, 0x4a026406, 0x00000006, 0x4a026203, 0x00000007, - 0x0201f000, 0x00020663, 0x592c0a0c, 0x5934000f, + 0x0201f000, 0x0002052f, 0x592c0a0c, 0x5934000f, 0x41784000, 0x80001540, 0x0400006d, 0x58080204, 0x82000500, 0x000000ff, 0x82000580, 0x00000012, 0x04020004, 0x5808020c, 0x80040580, 0x04000004, @@ -5365,104 +5564,104 @@ uint32_t risc_code01[] = { 0x80000540, 0x04020007, 0x48226810, 0x0401f005, 0x4802680f, 0x80000540, 0x04020002, 0x497a6810, 0x4d2c0000, 0x400a5800, 0x4a025a06, 0x00000002, - 0x0201f800, 0x00020381, 0x5c025800, 0x0401f7bc, + 0x0201f800, 0x000202da, 0x5c025800, 0x0401f7bc, 0x592c040a, 0x8c00051c, 0x04000016, 0x592c0206, 0x82000580, 0x0000ffff, 0x04020012, 0x592e6009, 0x83300580, 0xffffffff, 0x040007b1, 0x83300480, - 0x0010cfc0, 0x04001010, 0x59a8000b, 0x81300480, + 0x0010d1c0, 0x04001010, 0x59a8000b, 0x81300480, 0x0402100d, 0x59300008, 0x800001c0, 0x04020005, 0x59300203, 0x82000580, 0x00000007, 0x04000797, 0x492fc857, 0x4a025a06, 0x00000029, 0x0201f000, - 0x00020381, 0x492fc857, 0x4a025a06, 0x00000008, - 0x0201f000, 0x00020381, 0x492fc857, 0x4a025a06, - 0x00000045, 0x0201f000, 0x00020381, 0x492fc857, - 0x4a025a06, 0x0000002a, 0x0201f000, 0x00020381, + 0x000202da, 0x492fc857, 0x4a025a06, 0x00000008, + 0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06, + 0x00000045, 0x0201f000, 0x000202da, 0x492fc857, + 0x4a025a06, 0x0000002a, 0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06, 0x00000028, 0x0201f000, - 0x00020381, 0x492fc857, 0x4a025a06, 0x00000006, - 0x0201f000, 0x00020381, 0x492fc857, 0x4a025a06, - 0x0000000e, 0x0201f000, 0x00020381, 0x59340010, + 0x000202da, 0x492fc857, 0x4a025a06, 0x00000006, + 0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06, + 0x0000000e, 0x0201f000, 0x000202da, 0x59340010, 0x492e6810, 0x492fc857, 0x80000d40, 0x04000003, 0x492c0800, 0x1c01f000, 0x5934040b, 0x492e680f, 0x492fc857, 0x4803c857, 0x80000540, 0x04020003, 0x4a026a03, 0x00000001, 0x1c01f000, 0x59a8000e, - 0x81640480, 0x0402176e, 0x42026000, 0x0010cfc0, + 0x81640480, 0x0402176e, 0x42026000, 0x0010d1c0, 0x59300009, 0x81340580, 0x04020004, 0x59300202, 0x80040580, 0x04000759, 0x83326400, 0x00000024, 0x41580000, 0x81300480, 0x040017f6, 0x0401f760, 0x492fc857, 0x592c0407, 0x82000c80, 0x0000199a, - 0x040215dd, 0x592c0204, 0x80000112, 0x040205ca, - 0x592e8a06, 0x0201f800, 0x00020267, 0x04020059, - 0x0201f800, 0x00104836, 0x04020059, 0x592e780a, + 0x040215f1, 0x592c0204, 0x80000112, 0x040205de, + 0x592e8a06, 0x0201f800, 0x00020245, 0x04020059, + 0x0201f800, 0x001049e7, 0x04020059, 0x592e780a, 0x493fc857, 0x8d3e7d3e, 0x04020007, 0x59a80021, - 0x80000540, 0x0402004f, 0x0201f800, 0x00104686, - 0x040005c9, 0x833c1d00, 0x0000001f, 0x040005c6, - 0x592c0207, 0x82000c80, 0x00001000, 0x040215c2, + 0x80000540, 0x0402004f, 0x0201f800, 0x00104838, + 0x040005dd, 0x833c1d00, 0x0000001f, 0x040005da, + 0x592c0207, 0x82000c80, 0x00001000, 0x040215d6, 0x800000c2, 0x800008c4, 0x8005d400, 0x592e9008, 0x592e9809, 0x5934080d, 0x800409c0, 0x0402002e, 0x833c1d00, 0x0000001f, 0x81780040, 0x80000000, - 0x800c1902, 0x040217fe, 0x040205b3, 0x0c01f001, - 0x001053cd, 0x001053d0, 0x001053dd, 0x001053e0, - 0x001053e3, 0x0201f800, 0x00108dfb, 0x0401f01a, - 0x0201f800, 0x00104659, 0x04000027, 0x80e9d1c0, - 0x02020800, 0x00105ce7, 0x42028000, 0x00000005, - 0x417a9000, 0x417a9800, 0x0201f800, 0x00108e0b, + 0x800c1902, 0x040217fe, 0x040205c7, 0x0c01f001, + 0x001056e9, 0x001056ec, 0x001056f9, 0x001056fc, + 0x001056ff, 0x0201f800, 0x0010903e, 0x0401f01a, + 0x0201f800, 0x0010480b, 0x04000027, 0x80e9d1c0, + 0x02020800, 0x00105fae, 0x42028000, 0x00000005, + 0x417a9000, 0x417a9800, 0x0201f800, 0x0010904e, 0x0401f00d, 0x42027000, 0x0000004d, 0x0401f006, 0x42027000, 0x0000004e, 0x0401f003, 0x42027000, - 0x00000052, 0x0201f800, 0x0010451d, 0x02020800, - 0x00108e3b, 0x04000010, 0x8d3e7d3e, 0x04020017, + 0x00000052, 0x0201f800, 0x001046c9, 0x02020800, + 0x0010907e, 0x04000010, 0x8d3e7d3e, 0x04020017, 0x1c01f000, 0x58040002, 0x80000540, 0x04020007, - 0x4d3c0000, 0x40067800, 0x0201f800, 0x00104639, + 0x4d3c0000, 0x40067800, 0x0201f800, 0x001047eb, 0x5c027800, 0x040207cb, 0x4a025a06, 0x00000030, 0x0401f00d, 0x4a025a06, 0x0000002c, 0x0401f00a, 0x4a025a06, 0x00000028, 0x0401f007, 0x4a025a06, 0x00000029, 0x0401f004, 0x497a5c09, 0x4a025a06, 0x00000000, 0x4a025a04, 0x00000103, 0x0201f000, - 0x00020381, 0x492fc857, 0x592c0204, 0x80000110, - 0x80000040, 0x04000002, 0x0401f55b, 0x592c0207, + 0x000202da, 0x492fc857, 0x592c0204, 0x80000110, + 0x80000040, 0x04000002, 0x0401f56f, 0x592c0207, 0x82000500, 0x000003ff, 0x48025a07, 0x8c000506, 0x04000004, 0x82000500, 0x00000070, 0x04020004, 0x59a80821, 0x800409c0, 0x04020018, 0x4a025a06, 0x0000dead, 0x592c0408, 0x82000500, 0x0000f0ff, - 0x48025c08, 0x0201f800, 0x001041e4, 0x04020002, + 0x48025c08, 0x0201f800, 0x001043b4, 0x04020002, 0x1c01f000, 0x49425a06, 0x8058b1c0, 0x04000009, - 0x0201f800, 0x00109328, 0x0401f80f, 0x44042800, + 0x0201f800, 0x0010955f, 0x0401f80f, 0x44042800, 0x82580580, 0x00000002, 0x04020002, 0x48082801, - 0x0201f000, 0x00020381, 0x42028000, 0x00000031, + 0x0201f000, 0x000202da, 0x42028000, 0x00000031, 0x42000800, 0x00000001, 0x4200b000, 0x00000001, 0x0401f7ed, 0x592c0408, 0x80000118, 0x832c2c00, 0x00000009, 0x80142c00, 0x1c01f000, 0x492fc857, - 0x4a025a08, 0x00000006, 0x0201f000, 0x00020381, + 0x4a025a08, 0x00000006, 0x0201f000, 0x000202da, 0x492fc857, 0x4a025a08, 0x00000001, 0x0201f000, - 0x00020381, 0x492fc857, 0x592c040a, 0x82000500, - 0x00000003, 0x04000020, 0x0201f800, 0x00020892, + 0x000202da, 0x492fc857, 0x592c040a, 0x82000500, + 0x00000003, 0x04000020, 0x0201f800, 0x0002075a, 0x04000021, 0x592c0204, 0x492e6008, 0x82000500, 0x000000ff, 0x82000580, 0x00000045, 0x0400000e, - 0x592c000b, 0x0201f800, 0x001059b9, 0x02000800, - 0x00020267, 0x04020018, 0x42027000, 0x00000041, + 0x592c000b, 0x0201f800, 0x00105c9a, 0x02000800, + 0x00020245, 0x04020018, 0x42027000, 0x00000041, 0x49366009, 0x4a026406, 0x00000001, 0x0201f000, - 0x000208d8, 0x59300015, 0x8400055e, 0x48026015, - 0x42026800, 0x0010b320, 0x42027000, 0x00000040, + 0x000207a1, 0x59300015, 0x8400055e, 0x48026015, + 0x42026800, 0x0010b524, 0x42027000, 0x00000040, 0x0401f7f4, 0x4a025a06, 0x00000101, 0x0201f000, - 0x00020381, 0x4a025a06, 0x0000002c, 0x0201f000, - 0x00020381, 0x4a025a06, 0x00000028, 0x0201f800, - 0x00020381, 0x0201f000, 0x000208b4, 0x492fc857, - 0x0201f800, 0x0010601a, 0x0400000b, 0x592c0204, - 0x80000110, 0x80000040, 0x040204e7, 0x592c0c06, + 0x000202da, 0x4a025a06, 0x0000002c, 0x0201f000, + 0x000202da, 0x4a025a06, 0x00000028, 0x0201f800, + 0x000202da, 0x0201f000, 0x0002077d, 0x492fc857, + 0x0201f800, 0x001062e1, 0x0400000b, 0x592c0204, + 0x80000110, 0x80000040, 0x040204fb, 0x592c0c06, 0x800409c0, 0x04000009, 0x42000000, 0x00000102, 0x0401f003, 0x42000000, 0x00000104, 0x48025a06, - 0x0201f000, 0x00020381, 0x592c0c07, 0x800409c0, + 0x0201f000, 0x000202da, 0x592c0c07, 0x800409c0, 0x04000024, 0x82040480, 0x00000005, 0x04021021, - 0x4c040000, 0x80040800, 0x0201f800, 0x0010603f, + 0x4c040000, 0x80040800, 0x0201f800, 0x00106306, 0x5c001000, 0x04020018, 0x832c0400, 0x00000008, - 0x4000a000, 0x0201f800, 0x00106068, 0x04020012, - 0x592c1207, 0x82cc0580, 0x0010b30a, 0x04020009, + 0x4000a000, 0x0201f800, 0x0010632f, 0x04020012, + 0x592c1207, 0x82cc0580, 0x0010b50e, 0x04020009, 0x58c80c0b, 0x84040d00, 0x84040d02, 0x8c081500, 0x04000002, 0x84040d5e, 0x4805940b, 0x0401f001, 0x42000000, 0x00000000, 0x48025a06, 0x0201f000, - 0x00020381, 0x42000000, 0x00000103, 0x0401f7fb, + 0x000202da, 0x42000000, 0x00000103, 0x0401f7fb, 0x42000000, 0x00000102, 0x0401f7f8, 0x492fc857, 0x592e7c06, 0x833c0500, 0xfffffffe, 0x04020043, - 0x592c4007, 0x42026000, 0x0010cfc0, 0x41581800, + 0x592c4007, 0x42026000, 0x0010d1c0, 0x41581800, 0x400c0000, 0x81300480, 0x04021023, 0x59300203, 0x82000580, 0x00000000, 0x04000007, 0x59300008, 0x80000d40, 0x04000004, 0x58040005, 0x80200580, @@ -5470,79 +5669,79 @@ uint32_t risc_code01[] = { 0x58040204, 0x82000500, 0x000000ff, 0x82000d80, 0x00000053, 0x04000007, 0x82000d80, 0x00000048, 0x04000004, 0x82000580, 0x00000018, 0x04020023, - 0x4d2c0000, 0x0201f800, 0x00108997, 0x5c025800, + 0x4d2c0000, 0x0201f800, 0x00108be3, 0x5c025800, 0x0400001e, 0x4a025a06, 0x00000000, 0x0201f000, - 0x00020381, 0x592e8a06, 0x83440480, 0x000007f0, - 0x04021016, 0x83440400, 0x0010aa00, 0x50000000, + 0x000202da, 0x592e8a06, 0x83440480, 0x000007f0, + 0x04021016, 0x83440400, 0x0010ac00, 0x50000000, 0x80026d40, 0x04000011, 0x4d2c0000, 0x0201f800, - 0x00104619, 0x0400000c, 0x42028000, 0x00000005, - 0x592c0a08, 0x0201f800, 0x00104bee, 0x0201f800, - 0x00108f83, 0x0201f800, 0x00020381, 0x5c025800, + 0x001047cb, 0x0400000c, 0x42028000, 0x00000005, + 0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800, + 0x001091cc, 0x0201f800, 0x000202da, 0x5c025800, 0x0401f7e5, 0x5c025800, 0x4a025a06, 0x00000031, - 0x0201f000, 0x00020381, 0x492fc857, 0x4d2c0000, - 0x0201f800, 0x0010082a, 0x04000016, 0x492fc857, - 0x412f4000, 0x0201f800, 0x0010082a, 0x0400000e, - 0x492fc857, 0x412dd800, 0x0201f800, 0x00103941, - 0x0201f800, 0x0010394b, 0x49a1d80b, 0x5c025800, - 0x492dd80a, 0x0201f800, 0x00101fbb, 0x0201f000, - 0x00101fda, 0x41a25800, 0x0201f800, 0x0010083a, + 0x0201f000, 0x000202da, 0x492fc857, 0x4d2c0000, + 0x0201f800, 0x001007e4, 0x04000016, 0x492fc857, + 0x412f4000, 0x0201f800, 0x001007e4, 0x0400000e, + 0x492fc857, 0x412dd800, 0x0201f800, 0x00103b28, + 0x0201f800, 0x00103b32, 0x49a1d80b, 0x5c025800, + 0x492dd80a, 0x0201f800, 0x00102214, 0x0201f000, + 0x00102233, 0x41a25800, 0x0201f800, 0x001007f4, 0x5c025800, 0x4a025a06, 0x00004005, 0x4a025c06, - 0x00000002, 0x0201f000, 0x00020381, 0x4807c857, + 0x00000002, 0x0201f000, 0x000202da, 0x4807c857, 0x485fc857, 0x4200b800, 0x00000001, 0x5c000800, 0x4c5c0000, 0x0401f005, 0x4807c857, 0x485fc857, 0x5c000800, 0x4d780000, 0x4803c857, 0x492fc857, - 0x8c00050e, 0x02020800, 0x0010060d, 0x4203e000, + 0x8c00050e, 0x02020800, 0x001005d0, 0x4203e000, 0x50000000, 0x4200b800, 0x00008003, 0x0201f000, - 0x0010061a, 0x592c0204, 0x80000110, 0x80000040, - 0x0402042d, 0x0201f800, 0x00104886, 0x04020002, + 0x001005dd, 0x592c0204, 0x80000110, 0x80000040, + 0x04020441, 0x0201f800, 0x00104a34, 0x04020002, 0x1c01f000, 0x49425a06, 0x4806580d, 0x480a580e, 0x4943c857, 0x4807c857, 0x480bc857, 0x0201f000, - 0x00020381, 0x592c0204, 0x80000110, 0x80000040, - 0x0402041d, 0x0201f800, 0x001049ec, 0x04020002, + 0x000202da, 0x592c0204, 0x80000110, 0x80000040, + 0x04020431, 0x0201f800, 0x00104b8b, 0x04020002, 0x1c01f000, 0x49425a06, 0x48065811, 0x480a5812, - 0x0201f000, 0x00020381, 0x592c0204, 0x80000110, - 0x04000411, 0x80000040, 0x0402000c, 0x4202e000, + 0x0201f000, 0x000202da, 0x592c0204, 0x80000110, + 0x04000425, 0x80000040, 0x0402000c, 0x4202e000, 0x00000001, 0x592c020a, 0x8c000504, 0x02000000, - 0x00020603, 0x592c0207, 0x82000c80, 0x00001001, - 0x04021415, 0x0401f009, 0x4202e000, 0x00000003, + 0x000204d0, 0x592c0207, 0x82000c80, 0x00001001, + 0x04021429, 0x0401f009, 0x4202e000, 0x00000003, 0x48033002, 0x492f3003, 0x492f3004, 0x4a033008, - 0x00020603, 0x1c01f000, 0x4202e000, 0x00000002, - 0x42000000, 0x0010bcd9, 0x50007000, 0x492c700b, + 0x000204d0, 0x1c01f000, 0x4202e000, 0x00000002, + 0x42000000, 0x0010beda, 0x50007000, 0x492c700b, 0x4978700e, 0x4978700c, 0x592c0011, 0x592c0812, 0x48007007, 0x48047008, 0x592c1013, 0x82080500, - 0xffff0000, 0x04000003, 0x0201f800, 0x00100615, + 0xffff0000, 0x04000003, 0x0201f800, 0x001005d8, 0x4978700d, 0x82080480, 0x00000180, 0x4803c857, 0x04001007, 0x4800700f, 0x4a007005, 0x00000180, 0x4a007004, 0x00000060, 0x0401f005, 0x4978700f, 0x48087005, 0x80081104, 0x48087004, 0x5838000a, - 0x48007003, 0x40381000, 0x0201f000, 0x001008a1, - 0x0201f800, 0x00100819, 0x04000003, 0x59980007, + 0x48007003, 0x40381000, 0x0201f000, 0x00100858, + 0x0201f800, 0x001007d3, 0x04000003, 0x59980007, 0x0801f000, 0x1c01f000, 0x40307000, 0x5838000b, 0x80025d40, 0x0400001b, 0x58380002, 0x82000580, 0x00000100, 0x0400001d, 0x4c380000, 0x592c0204, 0x82000500, 0x000000ff, 0x82000580, 0x00000012, 0x0400000b, 0x592c0208, 0x8400054e, 0x48025a08, 0x4a025a06, 0x00000002, 0x4a025a04, 0x00000103, - 0x0201f800, 0x00020381, 0x0401f005, 0x4a025a06, - 0x00000010, 0x0201f800, 0x00020381, 0x5c007000, + 0x0201f800, 0x000202c1, 0x0401f005, 0x4a025a06, + 0x00000010, 0x0201f800, 0x000202da, 0x5c007000, 0x4202e000, 0x00000001, 0x4a007002, 0x00000100, 0x49787010, 0x1c01f000, 0x58380004, 0x82000480, 0x00000003, 0x04000087, 0x58380010, 0x8c000500, 0x04020019, 0x4200b000, 0x00000003, 0x832cac00, 0x00000011, 0x5838000a, 0x5838100d, 0x8008a400, - 0x4c380000, 0x0201f800, 0x0010a93e, 0x5c007000, + 0x4c380000, 0x0201f800, 0x0010ab17, 0x5c007000, 0x5838000d, 0x82000400, 0x00000003, 0x4800700d, 0x4a007010, 0x00000001, 0x58380004, 0x82000480, 0x00000003, 0x48007004, 0x82000580, 0x00000003, 0x0400006c, 0x5838000e, 0x80001d40, 0x04020020, - 0x4c380000, 0x0201f800, 0x00100819, 0x5c007000, + 0x4c380000, 0x0201f800, 0x001007d3, 0x5c007000, 0x04000010, 0x4a025a04, 0x0000010a, 0x42001800, 0x00000005, 0x480c700e, 0x5838000c, 0x80000540, 0x04020002, 0x5838000b, 0x40000800, 0x492c0801, 0x492c700c, 0x42000800, 0x0000000f, 0x0401f011, - 0x4202e000, 0x00000008, 0x4a033007, 0x001055f9, + 0x4202e000, 0x00000008, 0x4a033007, 0x00105915, 0x1c01f000, 0x4202e000, 0x00000002, 0x42000000, - 0x0010bcd9, 0x50007000, 0x0401f7e7, 0x583a580c, + 0x0010beda, 0x50007000, 0x0401f7e7, 0x583a580c, 0x400c0000, 0x42000800, 0x00000014, 0x80040c80, 0x58381004, 0x5838000f, 0x41783000, 0x80000540, 0x04020005, 0x84183540, 0x82081480, 0x00000003, @@ -5550,7 +5749,7 @@ uint32_t risc_code01[] = { 0x40080800, 0x4004b000, 0x412c0000, 0x800c0400, 0x4000a800, 0x5838000a, 0x5838100d, 0x8008a400, 0x4c080000, 0x4c040000, 0x4c0c0000, 0x4c380000, - 0x0201f800, 0x0010a93e, 0x5c007000, 0x5c001800, + 0x0201f800, 0x0010ab17, 0x5c007000, 0x5c001800, 0x5c000800, 0x40040000, 0x58381004, 0x80080480, 0x48007004, 0x82000580, 0x00000003, 0x04000002, 0x84183500, 0x5c000000, 0x80041400, 0x82080480, @@ -5558,680 +5757,659 @@ uint32_t risc_code01[] = { 0x400c0000, 0x80041c00, 0x820c0480, 0x00000014, 0x04020003, 0x84183544, 0x40001800, 0x40080800, 0x4804700d, 0x480c700e, 0x40180000, 0x0c01f001, - 0x00105644, 0x00105648, 0x00105646, 0x00105644, - 0x001055e0, 0x00105648, 0x00105646, 0x00105644, - 0x0201f800, 0x00100615, 0x5838100f, 0x0401f739, + 0x00105960, 0x00105964, 0x00105962, 0x00105960, + 0x001058fc, 0x00105964, 0x00105962, 0x00105960, + 0x0201f800, 0x001005d8, 0x5838100f, 0x0401f739, 0x5838080d, 0x82040400, 0x00000002, 0x5838100a, 0x80080400, 0x50001000, 0x800811c0, 0x0402000f, 0x4202e000, 0x00000001, 0x583a580b, 0x4978700b, 0x49787010, 0x592c0204, 0x82000500, 0x000000ff, - 0x82000580, 0x00000012, 0x02000000, 0x0002063b, - 0x0201f000, 0x00020603, 0x5838000a, 0x80040c00, + 0x82000580, 0x00000012, 0x02000000, 0x00020507, + 0x0201f000, 0x000204d0, 0x5838000a, 0x80040c00, 0x82381c00, 0x00000007, 0x54041800, 0x80040800, 0x800c1800, 0x54041800, 0x0401f71a, 0x0201f800, - 0x00100819, 0x02000800, 0x00100615, 0x4a02580a, - 0x0010bc78, 0x42000800, 0x0010bcd9, 0x452c0800, + 0x001007d3, 0x02000800, 0x001005d8, 0x4a02580a, + 0x0010be79, 0x42000800, 0x0010beda, 0x452c0800, 0x497a580b, 0x497a580c, 0x497a580d, 0x497a580e, - 0x497a580f, 0x4a025809, 0x0010559a, 0x497a5810, + 0x497a580f, 0x4a025809, 0x001058b6, 0x497a5810, 0x4a025802, 0x00000100, 0x4a025801, 0x00000001, - 0x1c01f000, 0x59c80007, 0x8c000502, 0x04000071, - 0x835c2c80, 0x00000005, 0x02001000, 0x00105c5c, - 0x59c82817, 0x4817506e, 0x497b9005, 0x82140500, - 0x00e00000, 0x0402004f, 0x82140500, 0x000003ff, - 0x82001c00, 0x00000006, 0x41cc2000, 0x42003000, - 0x00006080, 0x820c0480, 0x00000040, 0x04001006, - 0x42001000, 0x00000040, 0x820c1c80, 0x00000040, - 0x0401f003, 0x400c1000, 0x41781800, 0x54182000, - 0x80102000, 0x80183000, 0x80081040, 0x040207fc, - 0x800c19c0, 0x04000005, 0x59c80005, 0x80000000, - 0x48039005, 0x0401f7ea, 0x82140500, 0x01f60000, - 0x04020029, 0x82140500, 0x0000f000, 0x0400000b, - 0x82000c80, 0x00002000, 0x0402100f, 0x4a039005, - 0x00000140, 0x82140500, 0x0e000000, 0x80000132, - 0x0c01f83e, 0x1c01f000, 0x59cc0400, 0x82000500, - 0x0000ff00, 0x82000580, 0x00008100, 0x040007f4, - 0x0401f01c, 0x4817c857, 0x82140500, 0x000003ff, - 0x04020007, 0x59cc0400, 0x82000500, 0x0000ff00, - 0x82000580, 0x00008100, 0x04020012, 0x42000000, - 0x0010b6bc, 0x0201f800, 0x0010a86e, 0x0201f800, - 0x00105b32, 0x4803c856, 0x4a039005, 0x00000140, - 0x0401f020, 0x4817c857, 0x82140500, 0x00f60000, - 0x04020004, 0x0201f800, 0x00105b6e, 0x040207d2, - 0x0201f800, 0x00104e0d, 0x04000010, 0x59c400a4, - 0x4803c857, 0x82000500, 0x0000000f, 0x82000580, - 0x0000000a, 0x04020009, 0x497b5016, 0x59c400a3, - 0x82000540, 0x00080000, 0x480388a3, 0x82000500, - 0xfff7ffff, 0x480388a3, 0x4817c856, 0x0201f800, - 0x0010a79f, 0x4a039005, 0x00000140, 0x0401f842, - 0x4803c856, 0x1c01f000, 0x00105702, 0x00105a13, - 0x001056fa, 0x001056fa, 0x001056fa, 0x001056fa, - 0x001056fa, 0x001056fa, 0x4803c857, 0x42000000, - 0x0010b659, 0x0201f800, 0x0010a86e, 0x4a039005, - 0x00000140, 0x1c01f000, 0x59cc0400, 0x82000d00, - 0x0000ff00, 0x82041500, 0x0000f000, 0x840409c0, - 0x82140500, 0x000003ff, 0x800018c4, 0x8c142d14, - 0x04000005, 0x59cc0002, 0x82000500, 0x00000003, - 0x800c1c80, 0x480f5016, 0x82080580, 0x00002000, - 0x04020013, 0x836c0580, 0x00000001, 0x0402000e, - 0x59cc0006, 0x82000500, 0xff000000, 0x82000580, - 0x11000000, 0x02020800, 0x001006ba, 0x04020011, - 0x0201f800, 0x00103951, 0x0201f800, 0x00105c81, - 0x0401f00c, 0x0401f81f, 0x0401f00a, 0x82080580, - 0x00003000, 0x04020003, 0x0401fa40, 0x0401f005, - 0x82080580, 0x00008000, 0x04020002, 0x0401fb36, - 0x1c01f000, 0x4817c857, 0x42000000, 0x0010b658, - 0x0201f800, 0x0010a86e, 0x836c0580, 0x00000003, - 0x0402000b, 0x4c080000, 0x4c0c0000, 0x42001000, - 0x00008048, 0x40141800, 0x80142120, 0x0201f800, - 0x00103857, 0x5c001800, 0x5c001000, 0x1c01f000, + 0x1c01f000, 0x59c80007, 0x8c000502, 0x04000070, + 0x835c2c80, 0x00000005, 0x02001000, 0x00105f23, + 0x59c82817, 0x497b9005, 0x82140500, 0x00e00000, + 0x0402004f, 0x82140500, 0x000003ff, 0x82001c00, + 0x00000006, 0x41cc2000, 0x42003000, 0x00006080, + 0x820c0480, 0x00000040, 0x04001006, 0x42001000, + 0x00000040, 0x820c1c80, 0x00000040, 0x0401f003, + 0x400c1000, 0x41781800, 0x54182000, 0x80102000, + 0x80183000, 0x80081040, 0x040207fc, 0x800c19c0, + 0x04000005, 0x59c80005, 0x80000000, 0x48039005, + 0x0401f7ea, 0x82140500, 0x01f60000, 0x04020029, + 0x82140500, 0x0000f000, 0x0400000b, 0x82000c80, + 0x00002000, 0x0402100f, 0x82140500, 0x0e000000, + 0x80000132, 0x0c01f840, 0x4a039005, 0x00000140, + 0x1c01f000, 0x59cc0400, 0x82000500, 0x0000ff00, + 0x82000580, 0x00008100, 0x040007f4, 0x0401f01c, + 0x4817c857, 0x82140500, 0x000003ff, 0x04020007, + 0x59cc0400, 0x82000500, 0x0000ff00, 0x82000580, + 0x00008100, 0x04020012, 0x42000000, 0x0010b8bd, + 0x0201f800, 0x0010aa47, 0x0201f800, 0x00105dfa, + 0x4803c856, 0x4a039005, 0x00000140, 0x0401f020, + 0x4817c857, 0x82140500, 0x00f60000, 0x04020004, + 0x0201f800, 0x00105e35, 0x040207d2, 0x0201f800, + 0x0010513b, 0x04000010, 0x59c400a4, 0x4803c857, + 0x82000500, 0x0000000f, 0x82000580, 0x0000000a, + 0x04020009, 0x497b5016, 0x59c400a3, 0x82000540, + 0x00080000, 0x480388a3, 0x82000500, 0xfff7ffff, + 0x480388a3, 0x4817c856, 0x0201f800, 0x0010a978, + 0x4a039005, 0x00000140, 0x0401f842, 0x4803c856, + 0x1c01f000, 0x00105a1d, 0x00105cf4, 0x00105a15, + 0x00105a15, 0x00105a15, 0x00105a15, 0x00105a15, + 0x00105a15, 0x4803c857, 0x42000000, 0x0010b85a, + 0x0201f800, 0x0010aa47, 0x4a039005, 0x00000140, + 0x1c01f000, 0x4817c857, 0x59cc0400, 0x4803c857, + 0x82000d00, 0x0000ff00, 0x82041500, 0x0000f000, + 0x840409c0, 0x82140500, 0x000003ff, 0x800018c4, + 0x8c142d14, 0x04000005, 0x59cc0002, 0x82000500, + 0x00000003, 0x800c1c80, 0x480f5016, 0x82080580, + 0x00002000, 0x04020011, 0x836c0580, 0x00000001, + 0x0402000c, 0x59cc0006, 0x82000500, 0xff000000, + 0x82000580, 0x11000000, 0x04020011, 0x0201f800, + 0x00103b38, 0x0201f800, 0x00105f48, 0x0401f00c, + 0x0401f81f, 0x0401f00a, 0x82080580, 0x00003000, + 0x04020003, 0x0401fa06, 0x0401f005, 0x82080580, + 0x00008000, 0x04020002, 0x0401fafc, 0x1c01f000, + 0x4817c857, 0x42000000, 0x0010b859, 0x0201f800, + 0x0010aa47, 0x836c0580, 0x00000003, 0x0402000b, + 0x4c080000, 0x4c0c0000, 0x42001000, 0x00008048, + 0x40141800, 0x80142120, 0x0201f800, 0x00103a3e, + 0x5c001800, 0x5c001000, 0x1c01f000, 0x4807c857, 0x59cc0002, 0x82000500, 0xff000000, 0x82001580, - 0x01000000, 0x04000006, 0x82001580, 0x23000000, - 0x02020800, 0x001006ba, 0x040201c9, 0x82040580, - 0x00000023, 0x04020055, 0x59cc0004, 0x4803c857, - 0x59cc0006, 0x82000500, 0xff000000, 0x59cc0801, - 0x82040d00, 0x00ffffff, 0x80040540, 0x4803c857, - 0x0401fbb2, 0x02000800, 0x001006ba, 0x040001b8, - 0x59300c06, 0x82040580, 0x00000010, 0x04000012, - 0x82040580, 0x00000011, 0x0400000f, 0x82040580, - 0x00000001, 0x0400000c, 0x82040580, 0x00000004, - 0x04000009, 0x82040580, 0x00000008, 0x04000006, - 0x82040580, 0x0000000a, 0x02020800, 0x001006ba, - 0x040201a3, 0x59300004, 0x82000500, 0x80010000, - 0x04000006, 0x0201f800, 0x00106cb4, 0x02020800, - 0x001006ba, 0x0402019a, 0x59cc0a04, 0x48066202, - 0x59a80016, 0x800001c0, 0x02000800, 0x001006ba, - 0x04000193, 0x59cc0006, 0x82000500, 0xffff0000, + 0x01000000, 0x04000004, 0x82001580, 0x23000000, + 0x04020192, 0x82040580, 0x00000023, 0x0402003f, + 0x0401fb6a, 0x0400018d, 0x59300c06, 0x82040580, + 0x00000010, 0x04000013, 0x82040580, 0x00000011, + 0x04000010, 0x82040580, 0x00000001, 0x0400000d, + 0x82040580, 0x00000004, 0x0400000a, 0x82040580, + 0x00000008, 0x04000007, 0x82040580, 0x0000000a, + 0x04000004, 0x4933c857, 0x4807c857, 0x0401f177, + 0x59300004, 0x82000500, 0x80010000, 0x04000004, + 0x0201f800, 0x00106f60, 0x04020170, 0x59cc0a04, + 0x48066202, 0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80, 0x02000000, 0x04020005, 0x42027000, - 0x00000015, 0x0201f000, 0x000208d8, 0x82000d80, + 0x00000015, 0x0201f000, 0x000207a1, 0x82000d80, 0x02140000, 0x040007fa, 0x82000d80, 0x02100000, 0x040007f7, 0x82000d80, 0x02100000, 0x040007f4, - 0x82000d80, 0x01000000, 0x02020800, 0x001006ba, - 0x0402017b, 0x59cc0006, 0x82000500, 0x0000ffff, - 0x02020800, 0x001006ba, 0x04020175, 0x42027000, - 0x00000016, 0x0401f7e8, 0x82040580, 0x00000022, - 0x02020800, 0x001006ba, 0x0402016d, 0x59cc0004, - 0x4803c857, 0x59cc0006, 0x4803c857, 0x59cc0001, - 0x4803c857, 0x59a80016, 0x800001c0, 0x02000800, - 0x001006ba, 0x04000162, 0x59a80806, 0x8c040d14, - 0x04000011, 0x0401f97d, 0x0402000f, 0x0401f993, - 0x0400000d, 0x42027000, 0x0000004c, 0x59cc0001, - 0x82000500, 0x00ffffff, 0x0201f800, 0x00105c25, - 0x0400013e, 0x42028800, 0x0000ffff, 0x417a6800, - 0x0401f13a, 0x59cc0006, 0x82000500, 0xffff0000, - 0x82000d80, 0x03000000, 0x04020023, 0x59a80026, - 0x8c000508, 0x04000017, 0x8400054c, 0x48035026, - 0x59cc0800, 0x82040d00, 0x00ffffff, 0x48075010, - 0x497b8830, 0x84040d70, 0x48078832, 0x59c40802, - 0x84040d4c, 0x48078802, 0x59cc0007, 0x82000500, - 0x0000ffff, 0x48038893, 0x4803501e, 0x42000800, - 0x00000003, 0x59a81010, 0x0201f800, 0x001069af, - 0x59cc0006, 0x82000500, 0x0000ffff, 0x02020800, - 0x001006ba, 0x0402012a, 0x42027000, 0x00000017, - 0x0401f0e5, 0x82000d80, 0x04000000, 0x04020013, - 0x59cc0006, 0x82000500, 0x0000ffff, 0x02020800, - 0x001006ba, 0x0402011e, 0x0201f800, 0x00104e0d, - 0x04000004, 0x42027000, 0x0000001d, 0x0401f0d6, - 0x59a80026, 0x84000548, 0x48035026, 0x42027000, - 0x00000030, 0x0401f0d0, 0x82000d80, 0x05000000, - 0x0402000a, 0x59cc0006, 0x82000500, 0x0000ffff, - 0x02020800, 0x001006ba, 0x04020109, 0x42027000, - 0x00000018, 0x0401f0c4, 0x82000d80, 0x20100000, - 0x04020004, 0x42027000, 0x00000019, 0x0401f0be, - 0x82000d80, 0x21100000, 0x04020004, 0x42027000, - 0x0000001a, 0x0401f0b8, 0x82000d80, 0x52000000, - 0x0402000a, 0x59cc0006, 0x82000500, 0x0000ffff, - 0x02020800, 0x001006ba, 0x040200f1, 0x42027000, - 0x0000001b, 0x0401f0ac, 0x82000d80, 0x50000000, - 0x0402000a, 0x59cc0006, 0x82000500, 0x0000ffff, - 0x02020800, 0x001006ba, 0x040200e5, 0x42027000, - 0x0000001c, 0x0401f0a0, 0x82000d80, 0x13000000, - 0x04020004, 0x42027000, 0x00000034, 0x0401f09a, - 0x82000d80, 0x12000000, 0x0402000a, 0x59cc0006, - 0x82000500, 0x0000ffff, 0x02020800, 0x001006ba, - 0x040200d3, 0x42027000, 0x00000024, 0x0401f08e, - 0x82000d00, 0xff000000, 0x82040d80, 0x24000000, - 0x04020004, 0x42027000, 0x0000002d, 0x0401f086, - 0x82000d00, 0xff000000, 0x82040d80, 0x53000000, - 0x04020004, 0x42027000, 0x0000002a, 0x0401f07e, - 0x82000d80, 0x0f000000, 0x04020004, 0x42027000, - 0x00000020, 0x0401f078, 0x82000d80, 0x61040000, - 0x04020036, 0x83cc1400, 0x00000006, 0x80080800, - 0x50080000, 0x82000500, 0x0000ffff, 0x82000480, - 0x00000004, 0x4c580000, 0x8000b104, 0x8058b1c0, - 0x04000026, 0x4c100000, 0x50041800, 0x820c1500, - 0x03000000, 0x80081130, 0x42000000, 0x0010b615, - 0x82082580, 0x00000000, 0x04020004, 0x42000000, - 0x0010b612, 0x0401f00c, 0x82082580, 0x00000001, - 0x04020004, 0x42000000, 0x0010b613, 0x0401f006, - 0x82082580, 0x00000002, 0x04020003, 0x42000000, - 0x0010b614, 0x0201f800, 0x0010a86e, 0x42001000, - 0x00008015, 0x820c2500, 0x0000ffff, 0x800c1920, - 0x0201f800, 0x00103857, 0x5c002000, 0x80040800, - 0x8058b040, 0x040207da, 0x5c00b000, 0x42027000, - 0x00000023, 0x0401f040, 0x82000d80, 0x60000000, - 0x04020004, 0x42027000, 0x0000003f, 0x0401f03a, - 0x82000d80, 0x54000000, 0x04020008, 0x0401fb36, - 0x02020800, 0x001006ba, 0x04020075, 0x42027000, - 0x00000046, 0x0401f030, 0x82000d80, 0x55000000, - 0x04020009, 0x0401fb54, 0x04020004, 0x42027000, - 0x00000041, 0x0401f028, 0x42027000, 0x00000042, - 0x0401f025, 0x82000d80, 0x78000000, 0x04020004, - 0x42027000, 0x00000045, 0x0401f01f, 0x82000d80, - 0x10000000, 0x04020004, 0x42027000, 0x0000004e, - 0x0401f019, 0x82000d80, 0x63000000, 0x04020004, - 0x42027000, 0x0000004a, 0x0401f013, 0x82000d00, - 0xff000000, 0x82040d80, 0x56000000, 0x04020004, - 0x42027000, 0x0000004f, 0x0401f00b, 0x82000d00, - 0xff000000, 0x82040d80, 0x57000000, 0x04020004, - 0x42027000, 0x00000050, 0x0401f003, 0x42027000, - 0x0000001d, 0x59cc3800, 0x821c3d00, 0x00ffffff, - 0x821c0580, 0x00fffffe, 0x59cc0001, 0x04020005, - 0x40003000, 0x42028800, 0x000007fe, 0x0401f005, - 0x0401f8da, 0x02020800, 0x001006ba, 0x04020034, - 0x0201f800, 0x00104401, 0x02020800, 0x001006ba, - 0x0402002f, 0x83380580, 0x00000046, 0x04020006, - 0x59a80010, 0x80180580, 0x02000800, 0x001006ba, - 0x04000027, 0x59340200, 0x8c000514, 0x0400000f, - 0x83380580, 0x00000030, 0x0400000c, 0x83380580, - 0x0000003f, 0x04000009, 0x83380580, 0x00000034, - 0x04000006, 0x83380580, 0x00000024, 0x04000003, - 0x42027000, 0x0000004c, 0x0201f800, 0x00020892, - 0x04000018, 0x49366009, 0x4a026406, 0x00000004, - 0x59cc0c04, 0x48066202, 0x83380580, 0x0000004c, - 0x04020009, 0x4a026406, 0x00000011, 0x813669c0, - 0x04020005, 0x59cc0001, 0x82000500, 0x00ffffff, - 0x4802601e, 0x0201f000, 0x000208d8, 0x59880053, - 0x4803c857, 0x80000000, 0x48031053, 0x1c01f000, - 0x42001000, 0x00008049, 0x59cc1806, 0x800c1930, - 0x0201f800, 0x00103857, 0x0201f800, 0x001076c9, - 0x02000800, 0x001006ba, 0x040007f1, 0x49366009, - 0x4a026406, 0x00000004, 0x59cc0c04, 0x48066202, - 0x4a026403, 0x00000009, 0x4a02641a, 0x00000009, - 0x4a02621a, 0x00002900, 0x4a026203, 0x00000001, - 0x0201f000, 0x00106470, 0x59a80026, 0x4803c857, - 0x8c000508, 0x04000010, 0x59cc0006, 0x82000500, - 0xff000000, 0x82000d80, 0x03000000, 0x0400000c, - 0x82000d80, 0x20000000, 0x04000009, 0x82000d80, - 0x05000000, 0x04000006, 0x82000d80, 0x21000000, - 0x04000003, 0x80000580, 0x1c01f000, 0x82000540, - 0x00000001, 0x0401f7fd, 0x59cc2006, 0x82102500, - 0xff000000, 0x9c1021c0, 0x0401f807, 0x820c1c00, - 0x0010b2df, 0x500c1800, 0x800c0500, 0x4803c857, - 0x1c01f000, 0x40100800, 0x41781800, 0x82040480, - 0x00000020, 0x04001004, 0x800c1800, 0x40000800, - 0x0401f7fb, 0x82040500, 0x0000000f, 0x82000400, - 0x0010a95f, 0x50000000, 0x8c040d08, 0x04000002, - 0x900001c0, 0x1c01f000, 0x4803c856, 0x0401fadd, - 0x0402000a, 0x0201f800, 0x00101eb0, 0x04020007, - 0x59cc0002, 0x82000500, 0xff000000, 0x82000d80, - 0x08000000, 0x04000802, 0x1c01f000, 0x4803c856, - 0x59cc0400, 0x82000d00, 0x0000ff00, 0x840409c0, - 0x82040580, 0x00000033, 0x0402001f, 0x0401f98f, - 0x04000038, 0x59cc0a04, 0x48066202, 0x59cc0006, - 0x4803c857, 0x82000500, 0xffff0000, 0x82000d80, - 0x02000000, 0x04020009, 0x59cc0006, 0x82000500, - 0x0000ffff, 0x0402002b, 0x42027000, 0x00000015, - 0x0201f000, 0x000208d8, 0x82000d80, 0x01000000, - 0x04020024, 0x59cc0006, 0x82000500, 0x0000ffff, - 0x04020020, 0x42027000, 0x00000016, 0x0201f000, - 0x000208d8, 0x82040580, 0x00000032, 0x04020019, + 0x82000d80, 0x01000000, 0x04020158, 0x59cc0006, + 0x82000500, 0x0000ffff, 0x04020154, 0x42027000, + 0x00000016, 0x0401f7ec, 0x82040580, 0x00000022, + 0x0402014e, 0x59a80806, 0x8c040d14, 0x04000011, + 0x0401f967, 0x0402000f, 0x0401f97d, 0x0400000d, + 0x42027000, 0x0000004c, 0x59cc0001, 0x82000500, + 0x00ffffff, 0x0201f800, 0x00105eec, 0x0400012a, + 0x42028800, 0x0000ffff, 0x417a6800, 0x0401f126, 0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80, - 0x14000000, 0x04020013, 0x42027000, 0x00000038, - 0x59cc0001, 0x0401f810, 0x0402000e, 0x0201f800, - 0x001043fc, 0x0402000b, 0x0201f800, 0x00020892, - 0x04000008, 0x49366009, 0x4a026406, 0x00000004, - 0x59cc0c04, 0x48066202, 0x0201f000, 0x000208d8, - 0x1c01f000, 0x4803c857, 0x4c580000, 0x4c100000, - 0x4c380000, 0x4c340000, 0x82003500, 0x00ffffff, - 0x82181500, 0x00ff0000, 0x82081580, 0x00ff0000, - 0x04020016, 0x82181480, 0x00fffffc, 0x04001013, - 0x82181580, 0x00fffffd, 0x04020004, 0x42028800, - 0x000007fd, 0x0401f040, 0x82181580, 0x00fffffe, - 0x04020004, 0x42028800, 0x000007fe, 0x0401f03a, - 0x82181580, 0x00fffffc, 0x04020004, 0x42028800, - 0x000007fc, 0x0401f034, 0x41781000, 0x42002000, - 0x00000000, 0x4200b000, 0x000007f0, 0x41ac7000, - 0x50380000, 0x80006d40, 0x04020005, 0x800811c0, - 0x0402001e, 0x8410155e, 0x0401f01c, 0x58340212, - 0x82000500, 0x0000ff00, 0x04000011, 0x59a84010, - 0x82204500, 0x00ffff00, 0x82180500, 0x00ffff00, - 0x04000002, 0x80200580, 0x58340002, 0x0402000f, - 0x82000500, 0x000000ff, 0x82184500, 0x000000ff, - 0x80204580, 0x04020009, 0x0401f006, 0x58340002, - 0x82000500, 0x00ffffff, 0x80184580, 0x04020003, - 0x40128800, 0x0401f00c, 0x80102000, 0x80387000, - 0x8058b040, 0x040207db, 0x800811c0, 0x04020005, - 0x481bc857, 0x82000540, 0x00000001, 0x0401f003, - 0x840a8d1e, 0x80000580, 0x5c006800, 0x5c007000, - 0x5c002000, 0x5c00b000, 0x1c01f000, 0x59a80026, - 0x8c00050e, 0x04000003, 0x8c000502, 0x04000006, - 0x59cc0c00, 0x80040910, 0x82040500, 0x0000000f, - 0x0c01f002, 0x1c01f000, 0x00105a2e, 0x00105a2e, - 0x00105a2e, 0x00105b1d, 0x00105a2e, 0x00105a30, - 0x00105a48, 0x00105a4b, 0x00105a2e, 0x00105a2e, - 0x00105a2e, 0x00105a2e, 0x00105a2e, 0x00105a2e, - 0x00105a2e, 0x00105a2e, 0x4803c856, 0x1c01f000, - 0x0401f8de, 0x04000014, 0x82140500, 0x000003ff, - 0x800000c4, 0x82000480, 0x00000008, 0x0400100e, - 0x59cc0001, 0x59326809, 0x59340802, 0x80040580, - 0x82000500, 0x00ffffff, 0x04020007, 0x59cc0a04, - 0x48066202, 0x42027000, 0x00000046, 0x0201f000, - 0x000208d8, 0x59cc0004, 0x4803c857, 0x1c01f000, - 0x59cc0004, 0x4803c857, 0x1c01f000, 0x0401f8c3, - 0x04000016, 0x82140500, 0x000003ff, 0x800000c4, - 0x82000480, 0x0000000c, 0x04001010, 0x59cc0001, - 0x82000500, 0x00ffffff, 0x59326809, 0x59340802, - 0x82040d00, 0x00ffffff, 0x80040580, 0x04020007, - 0x59cc0a04, 0x48066202, 0x42027000, 0x00000045, - 0x0201f000, 0x000208d8, 0x59cc0004, 0x4803c857, - 0x1c01f000, 0x59cc0004, 0x4803c857, 0x59cc0000, - 0x82000500, 0xff000000, 0x59cc1001, 0x82081500, - 0x00ffffff, 0x80080540, 0x4803c857, 0x4817c857, - 0x0401f9d8, 0x02020800, 0x001006ba, 0x04020016, - 0x0201f800, 0x00101eb0, 0x02020800, 0x001006ba, - 0x04020011, 0x59cc0002, 0x82000500, 0xff000000, - 0x82000580, 0x00000000, 0x02020800, 0x001006ba, - 0x04020009, 0x82040500, 0x0000000f, 0x82000c80, - 0x00000006, 0x02021800, 0x001006ba, 0x04021002, - 0x0c01f003, 0x4803c856, 0x1c01f000, 0x00105a91, - 0x00105a93, 0x00105a91, 0x00105a91, 0x00105aec, - 0x00105afb, 0x4803c856, 0x1c01f000, 0x59a80016, - 0x800001c0, 0x02020800, 0x001006ba, 0x040207fa, - 0x59cc0802, 0x4807c856, 0x8c040d2e, 0x0402001d, - 0x0201f800, 0x001076c9, 0x02000800, 0x00100615, - 0x59cc0001, 0x0401ff18, 0x0402000d, 0x0201f800, - 0x00020267, 0x0402000a, 0x4a026406, 0x00000005, - 0x49366009, 0x59cc0804, 0x4806601c, 0x42027000, - 0x00000088, 0x0201f000, 0x000208d8, 0x4803c857, + 0x03000000, 0x04020021, 0x59a80026, 0x8c000508, + 0x04000017, 0x8400054c, 0x48035026, 0x59cc0800, + 0x82040d00, 0x00ffffff, 0x48075010, 0x497b8830, + 0x84040d70, 0x48078832, 0x59c40802, 0x84040d4c, + 0x48078802, 0x59cc0007, 0x82000500, 0x0000ffff, + 0x48038893, 0x4803501e, 0x42000800, 0x00000003, + 0x59a81010, 0x0201f800, 0x00106c78, 0x59cc0006, + 0x82000500, 0x0000ffff, 0x04020118, 0x42027000, + 0x00000017, 0x0401f0d9, 0x82000d80, 0x04000000, + 0x04020011, 0x59cc0006, 0x82000500, 0x0000ffff, + 0x0402010e, 0x0201f800, 0x0010513b, 0x04000004, + 0x42027000, 0x0000001d, 0x0401f0cc, 0x59a80026, + 0x84000548, 0x48035026, 0x42027000, 0x00000030, + 0x0401f0c6, 0x82000d80, 0x05000000, 0x04020008, + 0x59cc0006, 0x82000500, 0x0000ffff, 0x040200fb, + 0x42027000, 0x00000018, 0x0401f0bc, 0x82000d80, + 0x20100000, 0x04020004, 0x42027000, 0x00000019, + 0x0401f0b6, 0x82000d80, 0x21100000, 0x04020004, + 0x42027000, 0x0000001a, 0x0401f0b0, 0x82000d80, + 0x52000000, 0x04020008, 0x59cc0006, 0x82000500, + 0x0000ffff, 0x040200e5, 0x42027000, 0x0000001b, + 0x0401f0a6, 0x82000d80, 0x50000000, 0x04020008, + 0x59cc0006, 0x82000500, 0x0000ffff, 0x040200db, + 0x42027000, 0x0000001c, 0x0401f09c, 0x82000d80, + 0x13000000, 0x04020004, 0x42027000, 0x00000034, + 0x0401f096, 0x82000d80, 0x12000000, 0x04020008, + 0x59cc0006, 0x82000500, 0x0000ffff, 0x040200cb, + 0x42027000, 0x00000024, 0x0401f08c, 0x82000d00, + 0xff000000, 0x82040d80, 0x24000000, 0x04020004, + 0x42027000, 0x0000002d, 0x0401f084, 0x82000d00, + 0xff000000, 0x82040d80, 0x53000000, 0x04020004, + 0x42027000, 0x0000002a, 0x0401f07c, 0x82000d80, + 0x0f000000, 0x04020004, 0x42027000, 0x00000020, + 0x0401f076, 0x82000d80, 0x61040000, 0x04020036, + 0x83cc1400, 0x00000006, 0x80080800, 0x50080000, + 0x82000500, 0x0000ffff, 0x82000480, 0x00000004, + 0x4c580000, 0x8000b104, 0x8058b1c0, 0x04000026, + 0x4c100000, 0x50041800, 0x820c1500, 0x03000000, + 0x80081130, 0x42000000, 0x0010b817, 0x82082580, + 0x00000000, 0x04020004, 0x42000000, 0x0010b814, + 0x0401f00c, 0x82082580, 0x00000001, 0x04020004, + 0x42000000, 0x0010b815, 0x0401f006, 0x82082580, + 0x00000002, 0x04020003, 0x42000000, 0x0010b816, + 0x0201f800, 0x0010aa47, 0x42001000, 0x00008015, + 0x820c2500, 0x0000ffff, 0x800c1920, 0x0201f800, + 0x00103a3e, 0x5c002000, 0x80040800, 0x8058b040, + 0x040207da, 0x5c00b000, 0x42027000, 0x00000023, + 0x0401f03e, 0x82000d80, 0x60000000, 0x04020004, + 0x42027000, 0x0000003f, 0x0401f038, 0x82000d80, + 0x54000000, 0x04020006, 0x0401fb12, 0x0402006f, + 0x42027000, 0x00000046, 0x0401f030, 0x82000d80, + 0x55000000, 0x04020009, 0x0401fb32, 0x04020004, + 0x42027000, 0x00000041, 0x0401f028, 0x42027000, + 0x00000042, 0x0401f025, 0x82000d80, 0x78000000, + 0x04020004, 0x42027000, 0x00000045, 0x0401f01f, + 0x82000d80, 0x10000000, 0x04020004, 0x42027000, + 0x0000004e, 0x0401f019, 0x82000d80, 0x63000000, + 0x04020004, 0x42027000, 0x0000004a, 0x0401f013, + 0x82000d00, 0xff000000, 0x82040d80, 0x56000000, + 0x04020004, 0x42027000, 0x0000004f, 0x0401f00b, + 0x82000d00, 0xff000000, 0x82040d80, 0x57000000, + 0x04020004, 0x42027000, 0x00000050, 0x0401f003, + 0x42027000, 0x0000001d, 0x59cc3800, 0x821c3d00, + 0x00ffffff, 0x821c0580, 0x00fffffe, 0x59cc0001, + 0x04020005, 0x40003000, 0x42028800, 0x000007fe, + 0x0401f003, 0x0401f8d1, 0x04020030, 0x0201f800, + 0x001045a6, 0x0402002d, 0x83380580, 0x00000046, + 0x04020004, 0x59a80010, 0x80180580, 0x04000027, + 0x59340200, 0x8c000514, 0x0400000f, 0x83380580, + 0x00000030, 0x0400000c, 0x83380580, 0x0000003f, + 0x04000009, 0x83380580, 0x00000034, 0x04000006, + 0x83380580, 0x00000024, 0x04000003, 0x42027000, + 0x0000004c, 0x0201f800, 0x0002075a, 0x04000018, + 0x49366009, 0x4a026406, 0x00000004, 0x59cc0c04, + 0x48066202, 0x83380580, 0x0000004c, 0x04020009, + 0x4a026406, 0x00000011, 0x813669c0, 0x04020005, + 0x59cc0001, 0x82000500, 0x00ffffff, 0x4802601e, + 0x0201f000, 0x000207a1, 0x59880052, 0x4803c857, + 0x80000000, 0x48031052, 0x1c01f000, 0x42001000, + 0x00008049, 0x59cc1806, 0x800c1930, 0x0201f800, + 0x00103a3e, 0x0201f800, 0x00107942, 0x040007f3, + 0x49366009, 0x4a026406, 0x00000004, 0x59cc0c04, + 0x48066202, 0x4a026403, 0x00000009, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00002900, 0x4a026203, + 0x00000001, 0x0201f000, 0x0010672b, 0x59a80026, + 0x4803c857, 0x8c000508, 0x04000010, 0x59cc0006, + 0x82000500, 0xff000000, 0x82000d80, 0x03000000, + 0x0400000c, 0x82000d80, 0x20000000, 0x04000009, + 0x82000d80, 0x05000000, 0x04000006, 0x82000d80, + 0x21000000, 0x04000003, 0x80000580, 0x1c01f000, + 0x82000540, 0x00000001, 0x0401f7fd, 0x59cc2006, + 0x82102500, 0xff000000, 0x9c1021c0, 0x0401f807, + 0x820c1c00, 0x0010b4e3, 0x500c1800, 0x800c0500, + 0x4803c857, 0x1c01f000, 0x40100800, 0x41781800, + 0x82040480, 0x00000020, 0x04001004, 0x800c1800, + 0x40000800, 0x0401f7fb, 0x82040500, 0x0000000f, + 0x82000400, 0x0010ab38, 0x50000000, 0x8c040d08, + 0x04000002, 0x900001c0, 0x1c01f000, 0x4803c856, + 0x0401fac3, 0x0402000a, 0x0201f800, 0x0010210a, + 0x04020007, 0x59cc0002, 0x82000500, 0xff000000, + 0x82000d80, 0x08000000, 0x04000802, 0x1c01f000, + 0x4803c856, 0x59cc0400, 0x82000d00, 0x0000ff00, + 0x840409c0, 0x82040580, 0x00000033, 0x0402001f, + 0x0401f976, 0x04000038, 0x59cc0a04, 0x48066202, + 0x59cc0006, 0x4803c857, 0x82000500, 0xffff0000, + 0x82000d80, 0x02000000, 0x04020009, 0x59cc0006, + 0x82000500, 0x0000ffff, 0x0402002b, 0x42027000, + 0x00000015, 0x0201f000, 0x000207a1, 0x82000d80, + 0x01000000, 0x04020024, 0x59cc0006, 0x82000500, + 0x0000ffff, 0x04020020, 0x42027000, 0x00000016, + 0x0201f000, 0x000207a1, 0x82040580, 0x00000032, + 0x04020019, 0x59cc0006, 0x82000500, 0xffff0000, + 0x82000d80, 0x14000000, 0x04020013, 0x42027000, + 0x00000038, 0x59cc0001, 0x0401f810, 0x0402000e, + 0x0201f800, 0x001045a6, 0x0402000b, 0x0201f800, + 0x0002075a, 0x04000008, 0x49366009, 0x4a026406, + 0x00000004, 0x59cc0c04, 0x48066202, 0x0201f000, + 0x000207a1, 0x1c01f000, 0x4803c857, 0x4c580000, + 0x4c100000, 0x4c380000, 0x4c340000, 0x82003500, + 0x00ffffff, 0x82181500, 0x00ff0000, 0x82081580, + 0x00ff0000, 0x04020016, 0x82181480, 0x00fffffc, + 0x04001013, 0x82181580, 0x00fffffd, 0x04020004, + 0x42028800, 0x000007fd, 0x0401f040, 0x82181580, + 0x00fffffe, 0x04020004, 0x42028800, 0x000007fe, + 0x0401f03a, 0x82181580, 0x00fffffc, 0x04020004, + 0x42028800, 0x000007fc, 0x0401f034, 0x41781000, + 0x42002000, 0x00000000, 0x4200b000, 0x000007f0, + 0x41ac7000, 0x50380000, 0x80006d40, 0x04020005, + 0x800811c0, 0x0402001e, 0x8410155e, 0x0401f01c, + 0x58340212, 0x82000500, 0x0000ff00, 0x04000011, + 0x59a84010, 0x82204500, 0x00ffff00, 0x82180500, + 0x00ffff00, 0x04000002, 0x80200580, 0x58340002, + 0x0402000f, 0x82000500, 0x000000ff, 0x82184500, + 0x000000ff, 0x80204580, 0x04020009, 0x0401f006, + 0x58340002, 0x82000500, 0x00ffffff, 0x80184580, + 0x04020003, 0x40128800, 0x0401f00c, 0x80102000, + 0x80387000, 0x8058b040, 0x040207db, 0x800811c0, + 0x04020005, 0x481bc857, 0x82000540, 0x00000001, + 0x0401f003, 0x840a8d1e, 0x80000580, 0x5c006800, + 0x5c007000, 0x5c002000, 0x5c00b000, 0x1c01f000, + 0x59a80026, 0x8c00050e, 0x04000003, 0x8c000502, + 0x04000006, 0x59cc0c00, 0x80040910, 0x82040500, + 0x0000000f, 0x0c01f002, 0x1c01f000, 0x00105d0f, + 0x00105d0f, 0x00105d0f, 0x00105de5, 0x00105d0f, + 0x00105d11, 0x00105d29, 0x00105d2c, 0x00105d0f, + 0x00105d0f, 0x00105d0f, 0x00105d0f, 0x00105d0f, + 0x00105d0f, 0x00105d0f, 0x00105d0f, 0x4803c856, + 0x1c01f000, 0x0401f8c5, 0x04000014, 0x82140500, + 0x000003ff, 0x800000c4, 0x82000480, 0x00000008, + 0x0400100e, 0x59cc0001, 0x59326809, 0x59340802, + 0x80040580, 0x82000500, 0x00ffffff, 0x04020007, + 0x59cc0a04, 0x48066202, 0x42027000, 0x00000046, + 0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857, + 0x1c01f000, 0x59cc0004, 0x4803c857, 0x1c01f000, + 0x0401f8aa, 0x04000016, 0x82140500, 0x000003ff, + 0x800000c4, 0x82000480, 0x0000000c, 0x04001010, + 0x59cc0001, 0x82000500, 0x00ffffff, 0x59326809, + 0x59340802, 0x82040d00, 0x00ffffff, 0x80040580, + 0x04020007, 0x59cc0a04, 0x48066202, 0x42027000, + 0x00000045, 0x0201f000, 0x000207a1, 0x59cc0004, + 0x4803c857, 0x1c01f000, 0x4817c857, 0x0401f9c8, + 0x04020011, 0x0201f800, 0x0010210a, 0x0402000e, + 0x59cc0002, 0x82000500, 0xff000000, 0x82000580, + 0x00000000, 0x04020008, 0x82040500, 0x0000000f, + 0x82000c80, 0x00000006, 0x04021003, 0x4803c857, + 0x0c01f002, 0x1c01f000, 0x00105d60, 0x00105d64, + 0x00105d60, 0x00105d60, 0x00105db2, 0x00105dc3, + 0x4803c857, 0x59cc0004, 0x4803c857, 0x1c01f000, + 0x59cc0004, 0x4803c857, 0x59a80016, 0x800001c0, + 0x040207f8, 0x59cc0802, 0x8c040d2e, 0x0402001d, + 0x0201f800, 0x00107942, 0x02000800, 0x001005d8, + 0x59cc0001, 0x4803c857, 0x0401ff28, 0x0402000d, + 0x0201f800, 0x00020245, 0x0402000a, 0x4a026406, + 0x00000005, 0x49366009, 0x59cc0c04, 0x48066202, + 0x42027000, 0x00000088, 0x0201f000, 0x000207a1, 0x42028800, 0x0000ffff, 0x417a6800, 0x59cc0001, - 0x82000500, 0x00ffffff, 0x4802601e, 0x0401f7ef, - 0x59cc0001, 0x4803c857, 0x0401feff, 0x02020800, - 0x001006ba, 0x040207d4, 0x0201f800, 0x001043fc, - 0x02020800, 0x001006ba, 0x040207cf, 0x59cc0005, - 0x8c000500, 0x04020006, 0x59340200, 0x8c00050e, - 0x02020800, 0x001006ba, 0x040207c7, 0x0201f800, - 0x00104842, 0x04020013, 0x0401f840, 0x02000800, - 0x001006ba, 0x040007c0, 0x0201f800, 0x00020892, - 0x02000800, 0x001006ba, 0x040007bb, 0x49366009, - 0x4a026406, 0x00000002, 0x59cc0804, 0x4806601c, - 0x42027000, 0x00000088, 0x0201f000, 0x000208d8, - 0x0201f800, 0x00020892, 0x040007af, 0x49366009, - 0x4a026406, 0x00000004, 0x59cc0c04, 0x48066202, - 0x42027000, 0x00000001, 0x0201f000, 0x000208d8, + 0x82000500, 0x00ffffff, 0x4802601e, 0x0401f7f0, + 0x59cc0001, 0x4803c857, 0x0401ff10, 0x040207d5, + 0x0201f800, 0x001045a6, 0x040207d2, 0x59cc0005, + 0x8c000500, 0x04020004, 0x59340200, 0x8c00050e, + 0x040207cc, 0x0201f800, 0x001049f3, 0x0402000f, + 0x0401f83e, 0x040007c7, 0x0201f800, 0x0002075a, + 0x040007c4, 0x49366009, 0x4a026406, 0x00000002, + 0x59cc0c04, 0x48066202, 0x42027000, 0x00000088, + 0x0201f000, 0x000207a1, 0x0201f800, 0x0002075a, + 0x040007b8, 0x49366009, 0x4a026406, 0x00000004, + 0x59cc0c04, 0x48066202, 0x42027000, 0x00000001, + 0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857, 0x59cc0802, 0x8c040d2e, 0x0400000b, 0x0401f81f, - 0x04000009, 0x0401f961, 0x04020007, 0x59cc0a04, + 0x04000009, 0x0401f960, 0x04020007, 0x59cc0a04, 0x48066202, 0x42027000, 0x00000089, 0x0201f000, - 0x000208d8, 0x4933c857, 0x1c01f000, 0x59cc0004, + 0x000207a1, 0x4933c857, 0x1c01f000, 0x59cc0004, 0x4803c857, 0x59cc0802, 0x8c040d2e, 0x0400000b, - 0x0401f80e, 0x04000009, 0x0401f950, 0x04020007, + 0x0401f80e, 0x04000009, 0x0401f94f, 0x04020007, 0x59cc0a04, 0x48066202, 0x42027000, 0x0000008a, - 0x0201f000, 0x000208d8, 0x4933c857, 0x1c01f000, + 0x0201f000, 0x000207a1, 0x4933c857, 0x1c01f000, 0x59cc0a04, 0x0401f002, 0x59cc0c04, 0x59a8000e, 0x59a81067, 0x80080400, 0x80040480, 0x04021008, 0x40040000, 0x800000c4, 0x800408ca, 0x80040c00, - 0x82066400, 0x0010cfc0, 0x1c01f000, 0x80000580, + 0x82066400, 0x0010d1c0, 0x1c01f000, 0x80000580, 0x0401f7fe, 0x59cc0802, 0x8c040d2e, 0x04020010, 0x0401ffec, 0x0400000e, 0x59cc0001, 0x82000500, 0x00ffffff, 0x59326809, 0x59340802, 0x82040d00, 0x00ffffff, 0x80040580, 0x04020005, 0x42027000, - 0x00000051, 0x0201f000, 0x000208d8, 0x59cc0004, + 0x00000051, 0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857, 0x1c01f000, 0x4803c856, 0x42003000, 0x00000105, 0x0401f001, 0x4803c856, 0x4c3c0000, - 0x41cc7800, 0x40142000, 0x0401f803, 0x5c007800, - 0x1c01f000, 0x4803c856, 0x4c580000, 0x583c0400, - 0x82000500, 0x0000f000, 0x82000580, 0x0000c000, - 0x04000024, 0x0201f800, 0x00020892, 0x04000021, - 0x4c180000, 0x583c0001, 0x0401fe6f, 0x0402001f, - 0x0201f800, 0x001043fc, 0x0402001c, 0x49366009, - 0x0201f800, 0x0010082a, 0x04000018, 0x492e6017, - 0x497a5800, 0x497a5a04, 0x48125c04, 0x832cac00, - 0x00000005, 0x4200b000, 0x00000007, 0x403ca000, - 0x0201f800, 0x0010a93e, 0x5c003000, 0x481a641a, - 0x4a026403, 0x0000003e, 0x4a026406, 0x00000001, - 0x4a026203, 0x00000001, 0x0201f800, 0x00106470, - 0x5c00b000, 0x1c01f000, 0x0201f800, 0x000208b4, - 0x5c003000, 0x0401f7fb, 0x4803c856, 0x59cc0400, - 0x82000d00, 0x0000ff00, 0x82040500, 0x0000f000, - 0x840409c0, 0x82000580, 0x00002000, 0x04020049, - 0x82040580, 0x00000022, 0x0402003a, 0x59c400a4, - 0x82000500, 0x0000000f, 0x82000c80, 0x00000007, - 0x04001004, 0x82000480, 0x0000000c, 0x0400103f, + 0x41cc7800, 0x0401f803, 0x5c007800, 0x1c01f000, + 0x4803c856, 0x4c580000, 0x583c0400, 0x82000500, + 0x0000f000, 0x82000580, 0x0000c000, 0x04000024, + 0x0201f800, 0x0002075a, 0x04000021, 0x4c180000, + 0x583c0001, 0x0401fe89, 0x0402001f, 0x0201f800, + 0x001045a6, 0x0402001c, 0x49366009, 0x0201f800, + 0x001007e4, 0x04000018, 0x492e6017, 0x497a5800, + 0x497a5a04, 0x48125c04, 0x832cac00, 0x00000005, + 0x4200b000, 0x00000007, 0x403ca000, 0x0201f800, + 0x0010ab17, 0x5c003000, 0x481a641a, 0x4a026403, + 0x0000003e, 0x4a026406, 0x00000001, 0x4a026203, + 0x00000001, 0x0201f800, 0x0010672b, 0x5c00b000, + 0x1c01f000, 0x0201f800, 0x0002077d, 0x5c003000, + 0x0401f7fb, 0x4803c856, 0x59cc0400, 0x82000d00, + 0x0000ff00, 0x82040500, 0x0000f000, 0x840409c0, + 0x82000580, 0x00002000, 0x04020049, 0x82040580, + 0x00000022, 0x0402003a, 0x59c400a4, 0x82000500, + 0x0000000f, 0x82000c80, 0x00000007, 0x04001004, + 0x82000480, 0x0000000c, 0x0400103f, 0x59cc0006, + 0x82000500, 0xffff0000, 0x82000d80, 0x04000000, + 0x04000039, 0x82000d80, 0x60000000, 0x04000036, + 0x82000d80, 0x54000000, 0x04000033, 0x82000d80, + 0x03000000, 0x04020015, 0x59a80826, 0x8c040d02, + 0x0402002d, 0x8c040d08, 0x0402002b, 0x0201f800, + 0x001048ec, 0x0400002b, 0x59a8001d, 0x800000d0, + 0x59a80810, 0x82040d00, 0x000000ff, 0x80040540, + 0x59cc0800, 0x82040d00, 0x00ffffff, 0x80040580, + 0x0402001b, 0x0401f01c, 0x59c40802, 0x8c040d0c, + 0x04020017, 0x82000d80, 0x52000000, 0x040007ec, + 0x82000d80, 0x05000000, 0x040007e9, 0x82000d80, + 0x50000000, 0x040007e6, 0x0401f00d, 0x82040580, + 0x00000023, 0x0402000a, 0x0401ff58, 0x04000008, + 0x59300c03, 0x82040580, 0x00000002, 0x04000006, + 0x82040580, 0x00000051, 0x04000003, 0x80000580, + 0x0401f003, 0x82000540, 0x00000001, 0x1c01f000, 0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80, - 0x04000000, 0x04000039, 0x82000d80, 0x60000000, - 0x04000036, 0x82000d80, 0x54000000, 0x04000033, - 0x82000d80, 0x03000000, 0x04020015, 0x59a80826, - 0x8c040d02, 0x0402002d, 0x8c040d08, 0x0402002b, - 0x0201f800, 0x0010473b, 0x0400002b, 0x59a8001d, - 0x800000d0, 0x59a80810, 0x82040d00, 0x000000ff, - 0x80040540, 0x59cc0800, 0x82040d00, 0x00ffffff, - 0x80040580, 0x0402001b, 0x0401f01c, 0x59c40802, - 0x8c040d0c, 0x04020017, 0x82000d80, 0x52000000, - 0x040007ec, 0x82000d80, 0x05000000, 0x040007e9, - 0x82000d80, 0x50000000, 0x040007e6, 0x0401f00d, - 0x82040580, 0x00000023, 0x0402000a, 0x0401ff57, - 0x04000008, 0x59300c03, 0x82040580, 0x00000002, - 0x04000006, 0x82040580, 0x00000051, 0x04000003, - 0x80000580, 0x0401f003, 0x82000540, 0x00000001, - 0x1c01f000, 0x59cc0006, 0x82000500, 0xffff0000, - 0x82000d80, 0x03000000, 0x04000004, 0x82000d80, - 0x52000000, 0x040207f3, 0x59a80026, 0x82000500, - 0x00000009, 0x82000580, 0x00000008, 0x040007ef, - 0x0401f7ec, 0x4803c856, 0x4c5c0000, 0x4c580000, - 0x59a80016, 0x82000580, 0x0000004c, 0x0402001f, - 0x59ccb807, 0x9c5cb9c0, 0x825cbd00, 0x00000007, - 0x8c5cbd00, 0x0400000a, 0x4200b000, 0x00000002, - 0x83a81c00, 0x00000002, 0x83cc1400, 0x0000000d, - 0x0201f800, 0x001082ff, 0x04020010, 0x8c5cbd02, + 0x03000000, 0x04000004, 0x82000d80, 0x52000000, + 0x040207f3, 0x59a80026, 0x82000500, 0x00000009, + 0x82000580, 0x00000008, 0x040007ef, 0x0401f7ec, + 0x4803c856, 0x4c5c0000, 0x4c580000, 0x59a80016, + 0x82000580, 0x0000004c, 0x0402001f, 0x59ccb807, + 0x9c5cb9c0, 0x825cbd00, 0x00000007, 0x8c5cbd00, 0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00, - 0x00000000, 0x83cc1400, 0x0000000f, 0x0201f800, - 0x001082ff, 0x04020005, 0x8c5cbd04, 0x04000003, - 0x82000540, 0x00000001, 0x5c00b000, 0x5c00b800, - 0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4c580000, - 0x59a80016, 0x82000580, 0x0000004c, 0x0402001f, - 0x59ccb807, 0x9c5cb9c0, 0x825cbd00, 0x00000007, - 0x8c5cbd00, 0x0400000a, 0x4200b000, 0x00000002, - 0x83a81c00, 0x00000002, 0x83cc1400, 0x00000009, - 0x0201f800, 0x001082ff, 0x04020010, 0x8c5cbd02, + 0x00000002, 0x83cc1400, 0x0000000d, 0x0201f800, + 0x0010855a, 0x04020010, 0x8c5cbd02, 0x0400000a, + 0x4200b000, 0x00000002, 0x83a81c00, 0x00000000, + 0x83cc1400, 0x0000000f, 0x0201f800, 0x0010855a, + 0x04020005, 0x8c5cbd04, 0x04000003, 0x82000540, + 0x00000001, 0x5c00b000, 0x5c00b800, 0x1c01f000, + 0x4803c856, 0x4c5c0000, 0x4c580000, 0x59a80016, + 0x82000580, 0x0000004c, 0x0402001f, 0x59ccb807, + 0x9c5cb9c0, 0x825cbd00, 0x00000007, 0x8c5cbd00, 0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00, - 0x00000000, 0x83cc1400, 0x0000000b, 0x0201f800, - 0x001082ff, 0x04020005, 0x8c5cbd04, 0x04000003, - 0x82000540, 0x00000001, 0x5c00b000, 0x5c00b800, - 0x1c01f000, 0x4803c857, 0x4c580000, 0x40003000, - 0x42002000, 0x000007f0, 0x4200b000, 0x00000010, - 0x83ac7400, 0x000007f0, 0x50380000, 0x80026d40, - 0x04000006, 0x59340002, 0x82000500, 0x00ffffff, - 0x80180580, 0x04000010, 0x80102000, 0x80387000, - 0x8058b040, 0x040207f5, 0x82100480, 0x00000800, - 0x42002000, 0x00000000, 0x4200b000, 0x000007f0, - 0x41ac7000, 0x040217ed, 0x82000540, 0x00000001, - 0x0401f002, 0x40128800, 0x5c00b000, 0x1c01f000, - 0x59a80026, 0x8c00050e, 0x04000004, 0x8c000502, - 0x04000003, 0x80000580, 0x1c01f000, 0x82000540, - 0x00000001, 0x0401f7fd, 0x59300c06, 0x82040580, - 0x00000002, 0x04000006, 0x82040580, 0x00000005, - 0x04000003, 0x82000540, 0x00000001, 0x1c01f000, - 0x59c80000, 0x84000558, 0x84000512, 0x48039000, - 0x1c01f000, 0x4a03281a, 0x000003e8, 0x4a032802, - 0x0010cfc0, 0x4a032800, 0x00000000, 0x4a032808, - 0x00106d9f, 0x42000000, 0x00000005, 0x83947c00, - 0x00000009, 0x49787801, 0x4a007802, 0x00106d54, - 0x823c7c00, 0x00000003, 0x80000040, 0x040207fa, - 0x4a032819, 0xffff0000, 0x4201d000, 0x00000064, - 0x0401f97c, 0x4201d000, 0x000186a0, 0x0401f18b, - 0x00000000, 0x00000003, 0x00000006, 0x00000009, - 0x0000000c, 0x4d300000, 0x4d2c0000, 0x4d340000, - 0x4d400000, 0x4cfc0000, 0x4d380000, 0x4d3c0000, - 0x4d440000, 0x4d4c0000, 0x4d480000, 0x4c5c0000, - 0x4c600000, 0x4c640000, 0x4cc80000, 0x4ccc0000, - 0x0201f800, 0x000206af, 0x5c019800, 0x5c019000, - 0x5c00c800, 0x5c00c000, 0x5c00b800, 0x5c029000, - 0x5c029800, 0x5c028800, 0x5c027800, 0x5c027000, - 0x5c01f800, 0x5c028000, 0x5c026800, 0x5c025800, - 0x5c026000, 0x1c01f000, 0x59940004, 0x80000540, + 0x00000002, 0x83cc1400, 0x00000009, 0x0201f800, + 0x0010855a, 0x04020010, 0x8c5cbd02, 0x0400000a, + 0x4200b000, 0x00000002, 0x83a81c00, 0x00000000, + 0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a, + 0x04020005, 0x8c5cbd04, 0x04000003, 0x82000540, + 0x00000001, 0x5c00b000, 0x5c00b800, 0x1c01f000, + 0x4803c857, 0x4c580000, 0x40003000, 0x42002000, + 0x000007f0, 0x4200b000, 0x00000010, 0x83ac7400, + 0x000007f0, 0x50380000, 0x80026d40, 0x04000006, + 0x59340002, 0x82000500, 0x00ffffff, 0x80180580, + 0x04000010, 0x80102000, 0x80387000, 0x8058b040, + 0x040207f5, 0x82100480, 0x00000800, 0x42002000, + 0x00000000, 0x4200b000, 0x000007f0, 0x41ac7000, + 0x040217ed, 0x82000540, 0x00000001, 0x0401f002, + 0x40128800, 0x5c00b000, 0x1c01f000, 0x59a80026, + 0x8c00050e, 0x04000004, 0x8c000502, 0x04000003, + 0x80000580, 0x1c01f000, 0x82000540, 0x00000001, + 0x0401f7fd, 0x59300c06, 0x82040580, 0x00000002, + 0x04000006, 0x82040580, 0x00000005, 0x04000003, + 0x82000540, 0x00000001, 0x1c01f000, 0x59c80000, + 0x84000558, 0x84000512, 0x48039000, 0x1c01f000, + 0x4a03281a, 0x000003e8, 0x4a032802, 0x0010d1c0, + 0x4a032800, 0x00000000, 0x4a032808, 0x00107049, + 0x42000000, 0x00000005, 0x83947c00, 0x00000009, + 0x49787801, 0x4a007802, 0x00106fff, 0x823c7c00, + 0x00000003, 0x80000040, 0x040207fa, 0x4a032819, + 0xffff0000, 0x4201d000, 0x00000064, 0x0401f96e, + 0x4201d000, 0x000186a0, 0x0401f184, 0x00000000, + 0x00000003, 0x00000006, 0x00000009, 0x0000000c, + 0x4d300000, 0x4d2c0000, 0x4d340000, 0x4d400000, + 0x4cfc0000, 0x4d380000, 0x4d3c0000, 0x4d440000, + 0x4d4c0000, 0x4d480000, 0x4c5c0000, 0x4c600000, + 0x4c640000, 0x4cc80000, 0x4ccc0000, 0x0201f800, + 0x0002057b, 0x5c019800, 0x5c019000, 0x5c00c800, + 0x5c00c000, 0x5c00b800, 0x5c029000, 0x5c029800, + 0x5c028800, 0x5c027800, 0x5c027000, 0x5c01f800, + 0x5c028000, 0x5c026800, 0x5c025800, 0x5c026000, + 0x1c01f000, 0x59940004, 0x80000540, 0x0402000a, + 0x59940025, 0x80040400, 0x02001800, 0x001005d8, + 0x48032804, 0x480b2805, 0x4a032803, 0x0000000a, + 0x80000580, 0x1c01f000, 0x5994001f, 0x80000540, 0x0402000a, 0x59940025, 0x80040400, 0x02001800, - 0x00100615, 0x48032804, 0x480b2805, 0x4a032803, - 0x0000000a, 0x80000580, 0x1c01f000, 0x5994001f, + 0x001005d8, 0x4803281f, 0x480b2820, 0x4a03281e, + 0x00000001, 0x80000580, 0x1c01f000, 0x59940022, 0x80000540, 0x0402000a, 0x59940025, 0x80040400, - 0x02001800, 0x00100615, 0x4803281f, 0x480b2820, - 0x4a03281e, 0x00000001, 0x80000580, 0x1c01f000, - 0x59940022, 0x80000540, 0x0402000a, 0x59940025, - 0x80040400, 0x02001800, 0x00100615, 0x48032822, - 0x480b2823, 0x4a032821, 0x0000000a, 0x80000580, - 0x1c01f000, 0x4c000000, 0x59940005, 0x4803c857, - 0x480bc857, 0x80080580, 0x04020003, 0x497b2804, - 0x497b2805, 0x5c000000, 0x1c01f000, 0x4c000000, - 0x59940020, 0x4803c857, 0x480bc857, 0x80080580, - 0x04020003, 0x497b281f, 0x497b2820, 0x5c000000, - 0x1c01f000, 0x4c000000, 0x59940023, 0x4803c857, - 0x480bc857, 0x80080580, 0x04020003, 0x497b2822, - 0x497b2823, 0x5c000000, 0x1c01f000, 0x4937c857, - 0x48ebc857, 0x59340203, 0x80e80480, 0x04001002, - 0x48ea6a03, 0x1c01f000, 0x5c03e000, 0x1c01f000, - 0x4d440000, 0x42007800, 0x00000010, 0x59968801, - 0x0201f800, 0x00020267, 0x04020012, 0x59341a03, - 0x800c1840, 0x0400100f, 0x59940027, 0x800c0480, - 0x04000003, 0x48026a03, 0x0402100a, 0x5934000f, - 0x497a6a03, 0x80000540, 0x04000006, 0x4c3c0000, - 0x5934140b, 0x0201f800, 0x00020275, 0x5c007800, - 0x81468800, 0x83440480, 0x00000800, 0x04021007, - 0x803c7840, 0x040207e7, 0x49472801, 0x5c028800, - 0x5c03e000, 0x1c01f000, 0x4a032800, 0x00000002, - 0x497b2801, 0x0401f7fa, 0x42007800, 0x00000010, - 0x59966002, 0x59300205, 0x80000d40, 0x04000006, - 0x59940027, 0x80040480, 0x48026205, 0x0400102d, - 0x0400002c, 0x59300206, 0x80000d40, 0x04000014, - 0x59b800e4, 0x8c000524, 0x04020011, 0x4a0370e4, - 0x00030000, 0x40000000, 0x59b800e4, 0x8c000524, - 0x04000004, 0x4a0370e4, 0x00020000, 0x0401f008, - 0x59940027, 0x80040480, 0x48026206, 0x4a0370e4, - 0x00020000, 0x0400101c, 0x0400001b, 0x83326400, - 0x00000024, 0x49332802, 0x41540000, 0x81300480, - 0x04021005, 0x803c7840, 0x040207db, 0x5c03e000, - 0x1c01f000, 0x59940026, 0x48032827, 0x4a032802, - 0x0010cfc0, 0x497b2826, 0x80000540, 0x0400000f, - 0x4a032800, 0x00000001, 0x5c03e000, 0x1c01f000, - 0x4c3c0000, 0x0201f800, 0x00108f92, 0x5c007800, - 0x0401f7d1, 0x4c3c0000, 0x0201f800, 0x00108b11, - 0x5c007800, 0x0401f7e2, 0x4a032800, 0x00000000, - 0x5c03e000, 0x1c01f000, 0x59a8086b, 0x8c040d30, - 0x04020029, 0x8c040d32, 0x0400000f, 0x59a80069, - 0x81640480, 0x04001019, 0x59a8000b, 0x81500580, - 0x04000005, 0x59a8006a, 0x59a81066, 0x80080580, - 0x04020012, 0x900411c0, 0x82081500, 0x00007000, - 0x0401f012, 0x82040500, 0x0000001f, 0x04000016, - 0x80040840, 0x82040500, 0x0000001f, 0x04000003, - 0x4807506b, 0x0401f010, 0x900401c0, 0x82000500, - 0x0000001f, 0x80040d40, 0x900401c0, 0x80040580, - 0x82001500, 0x00007000, 0x82040500, 0xffff8fff, - 0x80080540, 0x4803506b, 0x80081114, 0x0201f800, - 0x00100728, 0x1c01f000, 0x4a032807, 0x000007d0, - 0x4a032806, 0x0000000a, 0x1c01f000, 0x42000800, - 0x000007d0, 0x83180480, 0x00000005, 0x02021800, - 0x00100615, 0x83947c00, 0x00000009, 0x83180400, - 0x00105c7c, 0x50000000, 0x803c7c00, 0x48047801, - 0x4a007800, 0x0000000a, 0x1c01f000, 0x83180480, - 0x00000005, 0x02021800, 0x00100615, 0x83947c00, - 0x00000009, 0x83180400, 0x00105c7c, 0x50000000, - 0x803c7c00, 0x49787801, 0x1c01f000, 0x4807c857, - 0x480bc857, 0x59940025, 0x80040400, 0x02001800, - 0x00100615, 0x48032804, 0x480b2805, 0x4a032803, - 0x0000000a, 0x1c01f000, 0x4807c857, 0x480bc857, - 0x59940025, 0x80040400, 0x02001800, 0x00100615, - 0x4803281c, 0x480b281d, 0x4a03281b, 0x0000000a, - 0x1c01f000, 0x4c000000, 0x5994001d, 0x4803c857, - 0x480bc857, 0x80080580, 0x04020003, 0x4803281c, - 0x4803281d, 0x5c000000, 0x1c01f000, 0x4807c857, - 0x480bc857, 0x59940025, 0x80040400, 0x02001800, - 0x00100615, 0x48032822, 0x480b2823, 0x4a032821, - 0x0000000a, 0x1c01f000, 0x80e9d1c0, 0x0400000e, - 0x0401f832, 0x04025000, 0x4203e000, 0x80000000, + 0x02001800, 0x001005d8, 0x48032822, 0x480b2823, + 0x4a032821, 0x0000000a, 0x80000580, 0x1c01f000, + 0x4c000000, 0x59940005, 0x4803c857, 0x480bc857, + 0x80080580, 0x04020003, 0x497b2804, 0x497b2805, + 0x5c000000, 0x1c01f000, 0x4c000000, 0x59940020, + 0x4803c857, 0x480bc857, 0x80080580, 0x04020003, + 0x497b281f, 0x497b2820, 0x5c000000, 0x1c01f000, + 0x4c000000, 0x59940023, 0x4803c857, 0x480bc857, + 0x80080580, 0x04020003, 0x497b2822, 0x497b2823, + 0x5c000000, 0x1c01f000, 0x4937c857, 0x48ebc857, + 0x59340203, 0x80e80480, 0x04001002, 0x48ea6a03, + 0x1c01f000, 0x5c03e000, 0x1c01f000, 0x4d440000, + 0x42007800, 0x00000010, 0x59968801, 0x0201f800, + 0x00020245, 0x04020012, 0x59341a03, 0x800c1840, + 0x0400100f, 0x59940027, 0x800c0480, 0x04000003, + 0x48026a03, 0x0402100a, 0x5934000f, 0x497a6a03, + 0x80000540, 0x04000006, 0x4c3c0000, 0x5934140b, + 0x0201f800, 0x00020253, 0x5c007800, 0x81468800, + 0x83440480, 0x00000800, 0x04021007, 0x803c7840, + 0x040207e7, 0x49472801, 0x5c028800, 0x5c03e000, + 0x1c01f000, 0x4a032800, 0x00000002, 0x497b2801, + 0x0401f7fa, 0x42007800, 0x00000010, 0x59966002, + 0x59300205, 0x80000d40, 0x04000006, 0x59940027, + 0x80040480, 0x48026205, 0x0400102d, 0x0400002c, + 0x59300206, 0x80000d40, 0x04000014, 0x59b800e4, + 0x8c000524, 0x04020011, 0x4a0370e4, 0x00030000, + 0x40000000, 0x59b800e4, 0x8c000524, 0x04000004, + 0x4a0370e4, 0x00020000, 0x0401f008, 0x59940027, + 0x80040480, 0x48026206, 0x4a0370e4, 0x00020000, + 0x0400101c, 0x0400001b, 0x83326400, 0x00000024, + 0x49332802, 0x41540000, 0x81300480, 0x04021005, + 0x803c7840, 0x040207db, 0x5c03e000, 0x1c01f000, + 0x59940026, 0x48032827, 0x4a032802, 0x0010d1c0, + 0x497b2826, 0x80000540, 0x0400000f, 0x4a032800, + 0x00000001, 0x5c03e000, 0x1c01f000, 0x4c3c0000, + 0x0201f800, 0x001091db, 0x5c007800, 0x0401f7d1, + 0x4c3c0000, 0x0201f800, 0x00108d5d, 0x5c007800, + 0x0401f7e2, 0x4a032800, 0x00000000, 0x5c03e000, + 0x1c01f000, 0x59a8086b, 0x8c040d30, 0x04020029, + 0x8c040d32, 0x0400000f, 0x59a80069, 0x81640480, + 0x04001019, 0x59a8000b, 0x81500580, 0x04000005, + 0x59a8006a, 0x59a81066, 0x80080580, 0x04020012, + 0x900411c0, 0x82081500, 0x00007000, 0x0401f012, + 0x82040500, 0x0000001f, 0x04000016, 0x80040840, + 0x82040500, 0x0000001f, 0x04000003, 0x4807506b, + 0x0401f010, 0x900401c0, 0x82000500, 0x0000001f, + 0x80040d40, 0x900401c0, 0x80040580, 0x82001500, + 0x00007000, 0x82040500, 0xffff8fff, 0x80080540, + 0x4803506b, 0x80081114, 0x0201f800, 0x001006e2, + 0x1c01f000, 0x4a032807, 0x000007d0, 0x4a032806, + 0x0000000a, 0x1c01f000, 0x42000800, 0x000007d0, + 0x83180480, 0x00000005, 0x02021800, 0x001005d8, + 0x83947c00, 0x00000009, 0x83180400, 0x00105f43, + 0x50000000, 0x803c7c00, 0x48047801, 0x4a007800, + 0x0000000a, 0x1c01f000, 0x83180480, 0x00000005, + 0x02021800, 0x001005d8, 0x83947c00, 0x00000009, + 0x83180400, 0x00105f43, 0x50000000, 0x803c7c00, + 0x49787801, 0x1c01f000, 0x4807c857, 0x480bc857, + 0x59940025, 0x80040400, 0x02001800, 0x001005d8, + 0x48032804, 0x480b2805, 0x4a032803, 0x0000000a, + 0x1c01f000, 0x4807c857, 0x480bc857, 0x59940025, + 0x80040400, 0x02001800, 0x001005d8, 0x4803281c, + 0x480b281d, 0x4a03281b, 0x0000000a, 0x1c01f000, + 0x4c000000, 0x5994001d, 0x4803c857, 0x480bc857, + 0x80080580, 0x04020003, 0x4803281c, 0x4803281d, + 0x5c000000, 0x1c01f000, 0x80e9d1c0, 0x0400000e, + 0x0401f836, 0x04025000, 0x4203e000, 0x80000000, 0x40e81000, 0x41780800, 0x42000000, 0x00000064, - 0x0201f800, 0x001063ee, 0x59940024, 0x80080400, - 0x48032824, 0x1c01f000, 0x42001000, 0x00104d39, - 0x0401fee5, 0x42001000, 0x00104d2c, 0x0401ffd6, - 0x42001000, 0x00103f62, 0x0401fedf, 0x42001000, - 0x00103fe4, 0x0401fedc, 0x42001000, 0x00103f37, - 0x0401fed9, 0x42001000, 0x0010401b, 0x0401f6ea, - 0x4203e000, 0x70000000, 0x4203e000, 0xb0300000, - 0x40ebf800, 0x42000000, 0x0000003c, 0x04004004, + 0x0201f800, 0x001066a0, 0x59940024, 0x80080400, + 0x48032824, 0x1c01f000, 0x42001000, 0x00105065, + 0x0401fef0, 0x42001000, 0x00105058, 0x0401ffe1, + 0x42001000, 0x00104148, 0x0401feea, 0x42001000, + 0x001041bc, 0x0401fee7, 0x42001000, 0x001041f3, + 0x0401f6f8, 0x4203e000, 0x70000000, 0x4203e000, + 0xb0300000, 0x41fc0000, 0x40ebf800, 0x80e80480, + 0x04001011, 0x04000004, 0x82000480, 0x00000003, + 0x0402100d, 0x42000000, 0x0000000f, 0x04004004, 0x80000040, 0x040207fe, 0x0401f007, 0x4203e000, - 0x70000000, 0x42000000, 0x0010b67d, 0x0201f800, - 0x0010a86e, 0x1c01f000, 0x4203e000, 0x80000000, - 0x4203e000, 0xb0400000, 0x40ebf800, 0x42000000, - 0x0000003c, 0x04005004, 0x80000040, 0x040207fe, - 0x0401f007, 0x4203e000, 0x80000000, 0x42000000, - 0x0010b67e, 0x0201f800, 0x0010a86e, 0x1c01f000, - 0x59a8000e, 0x82000480, 0x00000100, 0x599c0a02, - 0x800409c0, 0x04020002, 0x80040800, 0x80041480, - 0x04001002, 0x40000800, 0x48075067, 0x59a8100e, - 0x40040000, 0x800acc80, 0x4967500e, 0x49675069, - 0x59aaa80b, 0x41640800, 0x42001000, 0x00000024, - 0x0201f800, 0x001063cf, 0x8206a400, 0x0010cfc0, - 0x49535065, 0x4152b000, 0x42006000, 0x0010bc64, - 0x4a006004, 0x0000012c, 0x4a006005, 0xda10da10, - 0x4a006008, 0x00000011, 0x4a006009, 0x0010bc64, - 0x4a00600a, 0x00101108, 0x599c0014, 0x48006011, - 0x599c0015, 0x48006012, 0x42006000, 0x0010bc40, - 0x4a006203, 0x00000008, 0x4a006406, 0x00000006, - 0x4a006002, 0xffff0000, 0x4a006008, 0x0010bc64, - 0x4a006014, 0x0010bc64, 0x599c0014, 0x48006015, - 0x599c0015, 0x48006016, 0x599c0413, 0x48006017, - 0x49506018, 0x49546019, 0x59a80067, 0x4800601a, - 0x4a00601b, 0x0010b265, 0x4a00601c, 0x0010b266, - 0x4a00601d, 0x0010b26a, 0x42000000, 0xb0000000, - 0x42000800, 0x0010bc40, 0x0201f800, 0x00100bb2, - 0x1c01f000, 0x82000d00, 0x000000c0, 0x04000004, - 0x82040d80, 0x000000c0, 0x04020055, 0x82000d00, - 0x00002020, 0x59300414, 0x84000512, 0x82040d80, - 0x00002020, 0x0400000b, 0x8c000514, 0x0402000f, - 0x48026414, 0x813e79c0, 0x02020000, 0x00020804, - 0x42027000, 0x00000043, 0x0201f000, 0x000208d8, - 0x59326809, 0x59340a00, 0x8c040d0a, 0x040007f3, - 0x84000552, 0x0401f7f1, 0x84000514, 0x592c080d, - 0x48066015, 0x0401f7ef, 0x59326809, 0x59340a00, - 0x8c040d0a, 0x02000000, 0x00020817, 0x59300c14, - 0x84040d52, 0x48066414, 0x0201f000, 0x00020817, - 0x0201f800, 0x00020087, 0x813e79c0, 0x02020000, - 0x00020804, 0x0201f000, 0x00020825, 0x8c00051e, - 0x02000000, 0x00020831, 0x82000d00, 0x00002020, - 0x82040d80, 0x00002020, 0x04000014, 0x82000500, - 0x000000c0, 0x82000d80, 0x00000080, 0x04000008, - 0x813e79c0, 0x02020000, 0x00020804, 0x42027000, - 0x00000041, 0x0201f000, 0x000208d8, 0x813e79c0, - 0x02020000, 0x00020804, 0x42027000, 0x00000043, - 0x0201f000, 0x000208d8, 0x59326809, 0x59340a00, - 0x8c040d0a, 0x040007ea, 0x59300c14, 0x84040d52, - 0x48066414, 0x0401f7e6, 0x492fc857, 0x42000800, - 0x00000006, 0x0201f000, 0x0002082c, 0x492fc857, - 0x42000800, 0x00000004, 0x0201f000, 0x0002082c, - 0x4807c856, 0x59a80068, 0x800409c0, 0x04000003, - 0x80080540, 0x0401f002, 0x80080500, 0x48035068, - 0x1c01f000, 0x4a030800, 0x00000000, 0x4a030802, - 0x00000001, 0x497b0803, 0x497b0804, 0x1c01f000, - 0x59840002, 0x8c000500, 0x04000004, 0x84000500, - 0x4a030800, 0x00000001, 0x84000544, 0x84000506, - 0x48030802, 0x82000d00, 0x0fffffff, 0x42000000, - 0x90000000, 0x0201f800, 0x00100bde, 0x59a80069, - 0x82000480, 0x00000007, 0x48035069, 0x80000580, - 0x42000800, 0x0010b315, 0x48000800, 0x48000801, - 0x1c01f000, 0x59a80069, 0x82000400, 0x00000007, - 0x48035069, 0x1c01f000, 0x83640480, 0x00000008, - 0x0400101b, 0x58c80a03, 0x80000580, 0x82000400, - 0x00000008, 0x80040840, 0x040207fd, 0x815c0480, - 0x04001013, 0x4200b000, 0x00000007, 0x0201f800, - 0x00020892, 0x4a026203, 0x00000004, 0x4a026406, - 0x00000009, 0x4a026203, 0x00000004, 0x4a026007, - 0x00000101, 0x0401f809, 0x0401f880, 0x8058b040, - 0x040207f3, 0x80000580, 0x1c01f000, 0x82000540, - 0x00000001, 0x0401f7fd, 0x0201f800, 0x0010082a, - 0x492e6008, 0x58c80a03, 0x4a025a04, 0x0000002c, - 0x497a5800, 0x497a5801, 0x497a5c04, 0x497a5c06, - 0x497a5805, 0x4a025a08, 0x00000005, 0x4a025a07, - 0x00000002, 0x58c80201, 0x48025c04, 0x58c80202, - 0x48025c07, 0x58c80204, 0x48025c08, 0x4a02580d, - 0x0000ffff, 0x80040840, 0x0400000c, 0x412c2000, - 0x0201f800, 0x0010082a, 0x4a025a04, 0x0000000a, - 0x497a5c04, 0x48125800, 0x492c2001, 0x412c2000, - 0x80040840, 0x040207f7, 0x1c01f000, 0x4d7c0000, - 0x4202f800, 0x00000010, 0x4df00000, 0x4203e000, - 0x50000000, 0x59847803, 0x803c79c0, 0x0400001e, - 0x4c5c0000, 0x583cb808, 0x585c3408, 0x801831c0, - 0x0400000b, 0x0401f84a, 0x04000016, 0x42001000, - 0x0010b315, 0x0401f87f, 0x04000012, 0x0201f800, - 0x00100819, 0x0400000f, 0x492cb805, 0x585c0005, - 0x80000540, 0x02000800, 0x00100615, 0x0401f830, - 0x585c5408, 0x0401f80b, 0x5c00b800, 0x5c03e000, - 0x817ef840, 0x040207e1, 0x5c02f800, 0x1c01f000, - 0x5c00b800, 0x5c03e000, 0x5c02f800, 0x1c01f000, - 0x4803c856, 0x405c6000, 0x802851c0, 0x04000018, - 0x585c0204, 0x82000d00, 0x0000000f, 0x82040c00, - 0x0010110d, 0x50044000, 0x4c600000, 0x4c640000, - 0x4d040000, 0x4020c000, 0x40320800, 0x5984c804, - 0x4c280000, 0x0401f934, 0x5c005000, 0x40604000, - 0x41046000, 0x0201f800, 0x001010eb, 0x040207f6, - 0x5c020800, 0x5c00c800, 0x5c00c000, 0x58c80204, - 0x4800bc08, 0x0201f800, 0x00020087, 0x4a026007, - 0x00000101, 0x497a6009, 0x0401f055, 0x4803c856, - 0x59840003, 0x80026540, 0x04000003, 0x59300000, - 0x48030803, 0x1c01f000, 0x4803c856, 0x59840003, - 0x48026000, 0x49330803, 0x1c01f000, 0x58cc0805, - 0x40180000, 0x80040480, 0x0400100d, 0x82cc0580, - 0x0010b30a, 0x02020800, 0x00100615, 0x58c80205, - 0x80040480, 0x0400101d, 0x82000540, 0x00000001, - 0x1c01f000, 0x80003580, 0x0401f7fe, 0x82cc0580, - 0x0010b30a, 0x02020800, 0x00100615, 0x58c80400, - 0x8c000504, 0x040007f8, 0x58c8040b, 0x8c00051e, - 0x040007f5, 0x8c000500, 0x040207f3, 0x84000540, - 0x4801940b, 0x42000000, 0x0010b637, 0x0201f800, - 0x0010a86e, 0x42001000, 0x00008026, 0x0201f800, - 0x00103857, 0x0401f7e8, 0x58c8040b, 0x8c00051e, - 0x040007e2, 0x8c000502, 0x040207e0, 0x84000542, - 0x4801940b, 0x42000000, 0x0010b636, 0x0201f800, - 0x0010a86e, 0x42001000, 0x00008025, 0x42001800, - 0x00000000, 0x0201f800, 0x00103857, 0x0401f7d3, - 0x4803c856, 0x58080000, 0x42001800, 0x00000007, - 0x58080801, 0x80040480, 0x04020004, 0x400c0000, - 0x80000540, 0x0401f005, 0x04001003, 0x800c0480, - 0x0401f002, 0x80000080, 0x1c01f000, 0x4803c856, - 0x59300008, 0x80000d40, 0x02000800, 0x00100615, - 0x58040005, 0x80000540, 0x02000800, 0x00100615, - 0x59300007, 0x82000500, 0x00000101, 0x82000580, - 0x00000101, 0x02020800, 0x00100615, 0x42001000, - 0x0010b315, 0x58080801, 0x82040400, 0x0010b317, - 0x497a6414, 0x4a026015, 0x0000ffff, 0x45300000, - 0x80040800, 0x82040480, 0x00000008, 0x04001002, - 0x80000d80, 0x48041001, 0x82040400, 0x0010b317, - 0x45780000, 0x1c01f000, 0x4933c857, 0x59300808, - 0x800409c0, 0x02000800, 0x00100615, 0x4d2c0000, - 0x58065805, 0x812e59c0, 0x02020800, 0x0010083a, - 0x49780805, 0x40065800, 0x0201f800, 0x00100843, - 0x5c025800, 0x4d300000, 0x0201f800, 0x000208b4, - 0x5c026000, 0x1c01f000, 0x59300406, 0x82000580, - 0x00000009, 0x04020006, 0x59300007, 0x8c000510, - 0x04000003, 0x80000580, 0x1c01f000, 0x82000540, - 0x00000001, 0x1c01f000, 0x59840802, 0x8c040d04, - 0x1c01f000, 0x4803c856, 0x59840802, 0x84040d04, - 0x84040d40, 0x4a030800, 0x00000000, 0x48070802, - 0x82040d00, 0x0fffffff, 0x42000000, 0x90000000, - 0x0201f000, 0x00100bde, 0x4807c857, 0x4805980a, - 0x49799801, 0x49799803, 0x49799806, 0x49799807, - 0x49799808, 0x49799805, 0x49799809, 0x0401f8c8, - 0x0400000a, 0x0401f8ea, 0x04000008, 0x48359800, - 0x48359802, 0x48359806, 0x4a019804, 0x00000001, - 0x4a019807, 0x00000005, 0x1c01f000, 0x4807c857, - 0x58cc1007, 0x40040000, 0x80080480, 0x04021020, - 0x4c040000, 0x4c080000, 0x0401f8d9, 0x5c001000, - 0x5c000800, 0x0400001c, 0x58cc0006, 0x80006540, - 0x0402000b, 0x48359800, 0x48359802, 0x48359806, - 0x49799801, 0x49799803, 0x49786801, 0x49786800, - 0x49799804, 0x49799807, 0x0401f005, 0x48306801, - 0x48346000, 0x48359806, 0x49786800, 0x58cc0004, - 0x58cc1007, 0x80000000, 0x82081400, 0x00000005, - 0x48019804, 0x48099807, 0x0401f7df, 0x80000580, - 0x1c01f000, 0x82000540, 0x00000001, 0x1c01f000, - 0x480bc857, 0x4c500000, 0x4c540000, 0x4c580000, - 0x40083000, 0x58cc0801, 0x82040480, 0x00000005, - 0x02021800, 0x00100615, 0x82040400, 0x00106150, - 0x50000000, 0x58cca800, 0x8054ac00, 0x42001800, - 0x00000005, 0x40040000, 0x800c0480, 0x80082480, - 0x04021002, 0x40080000, 0x8000b0c2, 0x8058b400, - 0x5450a800, 0x8050a000, 0x8054a800, 0x8058b040, - 0x040207fc, 0x40001000, 0x58cc2805, 0x58cc0807, - 0x58cc2001, 0x80142c00, 0x80040c80, 0x80102400, - 0x48159805, 0x48059807, 0x48119801, 0x82100580, - 0x00000005, 0x0400000c, 0x48119801, 0x40080000, - 0x80181480, 0x40083000, 0x04000003, 0x040217d6, - 0x80000580, 0x5c00b000, 0x5c00a800, 0x5c00a000, - 0x1c01f000, 0x58cc0800, 0x800409c0, 0x02000800, - 0x00100615, 0x58040800, 0x48059800, 0x41782000, - 0x0401f7ee, 0x0401f812, 0x50600000, 0x81041c00, + 0x70000000, 0x42000000, 0x0010b87e, 0x0201f800, + 0x0010aa47, 0x1c01f000, 0x4203e000, 0x80000000, + 0x4203e000, 0xb0400000, 0x41fc0000, 0x40ebf800, + 0x80e80480, 0x04001011, 0x04000004, 0x82000480, + 0x00000003, 0x0402100d, 0x42000000, 0x0000000f, + 0x04005004, 0x80000040, 0x040207fe, 0x0401f007, + 0x4203e000, 0x80000000, 0x42000000, 0x0010b87f, + 0x0201f800, 0x0010aa47, 0x1c01f000, 0x59a8000e, + 0x82000480, 0x00000100, 0x599c0a02, 0x800409c0, + 0x04020002, 0x80040800, 0x80041480, 0x04001002, + 0x40000800, 0x48075067, 0x59a8100e, 0x40040000, + 0x800acc80, 0x4967500e, 0x49675069, 0x59aaa80b, + 0x41640800, 0x42001000, 0x00000024, 0x0201f800, + 0x00106681, 0x8206a400, 0x0010d1c0, 0x49535065, + 0x4152b000, 0x42006000, 0x0010be65, 0x4a006004, + 0x0000012c, 0x4a006005, 0xda10da10, 0x4a006008, + 0x00000011, 0x4a006009, 0x0010be65, 0x4a00600a, + 0x001010b8, 0x599c0014, 0x48006011, 0x599c0015, + 0x48006012, 0x42006000, 0x0010be41, 0x4a006203, + 0x00000008, 0x4a006406, 0x00000006, 0x4a006002, + 0xffff0000, 0x4a006008, 0x0010be65, 0x4a006014, + 0x0010be65, 0x599c0014, 0x48006015, 0x599c0015, + 0x48006016, 0x599c0413, 0x48006017, 0x49506018, + 0x49546019, 0x59a80067, 0x4800601a, 0x4a00601b, + 0x0010b465, 0x4a00601c, 0x0010b466, 0x4a00601d, + 0x0010b46a, 0x42000000, 0xb0000000, 0x42000800, + 0x0010be41, 0x0201f800, 0x00100b68, 0x1c01f000, + 0x82000d00, 0x000000c0, 0x04000004, 0x82040d80, + 0x000000c0, 0x04020055, 0x82000d00, 0x00002020, + 0x59300414, 0x84000512, 0x82040d80, 0x00002020, + 0x0400000b, 0x8c000514, 0x0402000f, 0x48026414, + 0x813e79c0, 0x02020000, 0x000206d0, 0x42027000, + 0x00000043, 0x0201f000, 0x000207a1, 0x59326809, + 0x59340a00, 0x8c040d0a, 0x040007f3, 0x84000552, + 0x0401f7f1, 0x84000514, 0x592c080d, 0x48066015, + 0x0401f7ef, 0x59326809, 0x59340a00, 0x8c040d0a, + 0x02000000, 0x000206e3, 0x59300c14, 0x84040d52, + 0x48066414, 0x0201f000, 0x000206e3, 0x0201f800, + 0x00020086, 0x813e79c0, 0x02020000, 0x000206d0, + 0x0201f000, 0x000206f1, 0x8c00051e, 0x02000000, + 0x000206fd, 0x82000d00, 0x00002020, 0x82040d80, + 0x00002020, 0x04000014, 0x82000500, 0x000000c0, + 0x82000d80, 0x00000080, 0x04000008, 0x813e79c0, + 0x02020000, 0x000206d0, 0x42027000, 0x00000041, + 0x0201f000, 0x000207a1, 0x813e79c0, 0x02020000, + 0x000206d0, 0x42027000, 0x00000043, 0x0201f000, + 0x000207a1, 0x59326809, 0x59340a00, 0x8c040d0a, + 0x040007ea, 0x59300c14, 0x84040d52, 0x48066414, + 0x0401f7e6, 0x492fc857, 0x42000800, 0x00000006, + 0x0201f000, 0x000206f8, 0x492fc857, 0x42000800, + 0x00000004, 0x0201f000, 0x000206f8, 0x4807c856, + 0x59a80068, 0x800409c0, 0x04000003, 0x80080540, + 0x0401f002, 0x80080500, 0x48035068, 0x1c01f000, + 0x4a030800, 0x00000000, 0x4a030802, 0x00000001, + 0x497b0803, 0x497b0804, 0x1c01f000, 0x59840002, + 0x8c000500, 0x04000004, 0x84000500, 0x4a030800, + 0x00000001, 0x84000544, 0x84000506, 0x48030802, + 0x82000d00, 0x0fffffff, 0x42000000, 0x90000000, + 0x0201f800, 0x00100b94, 0x59a80069, 0x82000480, + 0x00000007, 0x48035069, 0x80000580, 0x42000800, + 0x0010b519, 0x48000800, 0x48000801, 0x1c01f000, + 0x59a80069, 0x82000480, 0x00000007, 0x48035069, + 0x1c01f000, 0x83640480, 0x00000008, 0x0400101b, + 0x58c80a03, 0x80000580, 0x82000400, 0x00000008, + 0x80040840, 0x040207fd, 0x815c0480, 0x04001013, + 0x4200b000, 0x00000007, 0x0201f800, 0x0002075a, + 0x4a026203, 0x00000004, 0x4a026406, 0x00000009, + 0x4a026203, 0x00000004, 0x4a026007, 0x00000101, + 0x0401f809, 0x0401f880, 0x8058b040, 0x040207f3, + 0x80000580, 0x1c01f000, 0x82000540, 0x00000001, + 0x0401f7fd, 0x0201f800, 0x001007e4, 0x492e6008, + 0x58c80a03, 0x4a025a04, 0x0000002c, 0x497a5800, + 0x497a5801, 0x497a5c04, 0x497a5c06, 0x497a5805, + 0x4a025a08, 0x00000005, 0x4a025a07, 0x00000002, + 0x58c80201, 0x48025c04, 0x58c80202, 0x48025c07, + 0x58c80204, 0x48025c08, 0x4a02580d, 0x0000ffff, + 0x80040840, 0x0400000c, 0x412c2000, 0x0201f800, + 0x001007e4, 0x4a025a04, 0x0000000a, 0x497a5c04, + 0x48125800, 0x492c2001, 0x412c2000, 0x80040840, + 0x040207f7, 0x1c01f000, 0x4d7c0000, 0x4202f800, + 0x00000010, 0x4df00000, 0x4203e000, 0x50000000, + 0x59847803, 0x803c79c0, 0x0400001e, 0x4c5c0000, + 0x583cb808, 0x585c3408, 0x801831c0, 0x0400000b, + 0x0401f84a, 0x04000016, 0x42001000, 0x0010b519, + 0x0401f87f, 0x04000012, 0x0201f800, 0x001007d3, + 0x0400000f, 0x492cb805, 0x585c0005, 0x80000540, + 0x02000800, 0x001005d8, 0x0401f830, 0x585c5408, + 0x0401f80b, 0x5c00b800, 0x5c03e000, 0x817ef840, + 0x040207e1, 0x5c02f800, 0x1c01f000, 0x5c00b800, + 0x5c03e000, 0x5c02f800, 0x1c01f000, 0x4803c856, + 0x405c6000, 0x802851c0, 0x04000018, 0x585c0204, + 0x82000d00, 0x0000000f, 0x82040c00, 0x001010bd, + 0x50044000, 0x4cf00000, 0x4d000000, 0x4d040000, + 0x4021e000, 0x40320800, 0x59860004, 0x4c280000, + 0x0401f934, 0x5c005000, 0x40f04000, 0x41046000, + 0x0201f800, 0x0010109b, 0x040207f6, 0x5c020800, + 0x5c020000, 0x5c01e000, 0x58c80204, 0x4800bc08, + 0x0201f800, 0x00020086, 0x4a026007, 0x00000101, + 0x497a6009, 0x0401f055, 0x4803c856, 0x59840003, + 0x80026540, 0x04000003, 0x59300000, 0x48030803, + 0x1c01f000, 0x4803c856, 0x59840003, 0x48026000, + 0x49330803, 0x1c01f000, 0x58cc0805, 0x40180000, + 0x80040480, 0x0400100d, 0x82cc0580, 0x0010b50e, + 0x02020800, 0x001005d8, 0x58c80205, 0x80040480, + 0x0400101d, 0x82000540, 0x00000001, 0x1c01f000, + 0x80003580, 0x0401f7fe, 0x82cc0580, 0x0010b50e, + 0x02020800, 0x001005d8, 0x58c80400, 0x8c000504, + 0x040007f8, 0x58c8040b, 0x8c00051e, 0x040007f5, + 0x8c000500, 0x040207f3, 0x84000540, 0x4801940b, + 0x42000000, 0x0010b839, 0x0201f800, 0x0010aa47, + 0x42001000, 0x00008026, 0x0201f800, 0x00103a3e, + 0x0401f7e8, 0x58c8040b, 0x8c00051e, 0x040007e2, + 0x8c000502, 0x040207e0, 0x84000542, 0x4801940b, + 0x42000000, 0x0010b838, 0x0201f800, 0x0010aa47, + 0x42001000, 0x00008025, 0x42001800, 0x00000000, + 0x0201f800, 0x00103a3e, 0x0401f7d3, 0x4803c856, + 0x58080000, 0x42001800, 0x00000007, 0x58080801, + 0x80040480, 0x04020004, 0x400c0000, 0x80000540, + 0x0401f005, 0x04001003, 0x800c0480, 0x0401f002, + 0x80000080, 0x1c01f000, 0x4803c856, 0x59300008, + 0x80000d40, 0x02000800, 0x001005d8, 0x58040005, + 0x80000540, 0x02000800, 0x001005d8, 0x59300007, + 0x82000500, 0x00000101, 0x82000580, 0x00000101, + 0x02020800, 0x001005d8, 0x42001000, 0x0010b519, + 0x58080801, 0x82040400, 0x0010b51b, 0x497a6414, + 0x4a026015, 0x0000ffff, 0x45300000, 0x80040800, + 0x82040480, 0x00000008, 0x04001002, 0x80000d80, + 0x48041001, 0x82040400, 0x0010b51b, 0x45780000, + 0x1c01f000, 0x4933c857, 0x59300808, 0x800409c0, + 0x02000800, 0x001005d8, 0x4d2c0000, 0x58065805, + 0x812e59c0, 0x02020800, 0x001007f4, 0x49780805, + 0x40065800, 0x0201f800, 0x001007fd, 0x5c025800, + 0x4d300000, 0x0201f800, 0x0002077d, 0x5c026000, + 0x1c01f000, 0x59300406, 0x82000580, 0x00000009, + 0x04020006, 0x59300007, 0x8c000510, 0x04000003, + 0x80000580, 0x1c01f000, 0x82000540, 0x00000001, + 0x1c01f000, 0x59840802, 0x8c040d04, 0x1c01f000, + 0x4803c856, 0x59840802, 0x84040d04, 0x84040d40, + 0x4a030800, 0x00000000, 0x48070802, 0x82040d00, + 0x0fffffff, 0x42000000, 0x90000000, 0x0201f000, + 0x00100b94, 0x4807c857, 0x4805980a, 0x49799801, + 0x49799803, 0x49799806, 0x49799807, 0x49799808, + 0x49799805, 0x49799809, 0x0401f8c9, 0x0400000a, + 0x0401f8eb, 0x04000008, 0x48359800, 0x48359802, + 0x48359806, 0x4a019804, 0x00000001, 0x4a019807, + 0x00000005, 0x1c01f000, 0x4807c857, 0x58cc1007, + 0x40040000, 0x80080480, 0x04021020, 0x4c040000, + 0x4c080000, 0x0401f8da, 0x5c001000, 0x5c000800, + 0x0400001c, 0x58cc0006, 0x80006540, 0x0402000b, + 0x48359800, 0x48359802, 0x48359806, 0x49799801, + 0x49799803, 0x49786801, 0x49786800, 0x49799804, + 0x49799807, 0x0401f005, 0x48306801, 0x48346000, + 0x48359806, 0x49786800, 0x58cc0004, 0x58cc1007, + 0x80000000, 0x82081400, 0x00000005, 0x48019804, + 0x48099807, 0x0401f7df, 0x80000580, 0x1c01f000, + 0x82000540, 0x00000001, 0x1c01f000, 0x480bc857, + 0x4c500000, 0x4c540000, 0x4c580000, 0x40083000, + 0x58cc0801, 0x82040480, 0x00000005, 0x02021800, + 0x001005d8, 0x82040400, 0x00106418, 0x50000000, + 0x58cca800, 0x8054ac00, 0x42001800, 0x00000005, + 0x40040000, 0x800c0480, 0x80082480, 0x04021002, + 0x40080000, 0x8000b0c2, 0x8058b400, 0x5450a800, + 0x8050a000, 0x8054a800, 0x8058b040, 0x040207fc, + 0x40001000, 0x58cc2805, 0x58cc0807, 0x58cc2001, + 0x80142c00, 0x80040c80, 0x80102400, 0x48159805, + 0x48059807, 0x48119801, 0x82100580, 0x00000005, + 0x0400000c, 0x48119801, 0x40080000, 0x80181480, + 0x40083000, 0x04000003, 0x040217d6, 0x80000580, + 0x5c00b000, 0x5c00a800, 0x5c00a000, 0x1c01f000, + 0x58cc0800, 0x800409c0, 0x02000800, 0x001005d8, + 0x58040800, 0x48059800, 0x41782000, 0x0401f7ee, + 0x0401f813, 0x50f00000, 0x81040400, 0x40001800, 0x585c0204, 0x4803c857, 0x82000580, 0x0000002c, - 0x02020800, 0x00100615, 0x58040202, 0x800000e0, - 0x80640540, 0x48001802, 0x58040000, 0x48001800, + 0x02020800, 0x001005d8, 0x58040202, 0x800000e0, + 0x81000540, 0x48001802, 0x58040000, 0x48001800, 0x58040001, 0x48001801, 0x1c01f000, 0x4807c856, - 0x58cc0005, 0x80000040, 0x02001800, 0x00100615, + 0x58cc0005, 0x80000040, 0x02001800, 0x001005d8, 0x48019805, 0x58cc1003, 0x82080480, 0x00000005, - 0x02021800, 0x00100615, 0x82080400, 0x00106150, + 0x02021800, 0x001005d8, 0x82080400, 0x00106418, 0x50000000, 0x58cc0802, 0x80040c00, 0x80081000, 0x82080480, 0x00000005, 0x0402000f, 0x58cc2002, 0x58100000, 0x80006d40, 0x04000009, 0x4c340000, @@ -6247,30 +6425,30 @@ uint32_t risc_code01[] = { 0x80102000, 0x82000480, 0x00000005, 0x04000002, 0x040217fc, 0x48119203, 0x1c01f000, 0x4807c856, 0x4d2c0000, 0x58cc000a, 0x80000540, 0x02000800, - 0x00100615, 0x82002400, 0x00000005, 0x0201f800, - 0x00100819, 0x04000012, 0x492d9809, 0x497a5800, - 0x497a5801, 0x0201f800, 0x00100819, 0x0400000c, + 0x001005d8, 0x82002400, 0x00000005, 0x0201f800, + 0x001007d3, 0x04000012, 0x492d9809, 0x497a5800, + 0x497a5801, 0x0201f800, 0x001007d3, 0x0400000c, 0x58cc0009, 0x48025800, 0x497a5801, 0x492d9809, 0x82102480, 0x00000005, 0x040217f7, 0x82000540, 0x00000001, 0x5c025800, 0x1c01f000, 0x58cc0009, 0x80025d40, 0x040007fc, 0x592c2000, 0x0201f800, - 0x0010083a, 0x40100000, 0x0401f7fa, 0x58cc0009, + 0x001007f4, 0x40100000, 0x0401f7fa, 0x58cc0009, 0x48cfc857, 0x80006d40, 0x04000005, 0x50340000, 0x48019809, 0x49786800, 0x49786801, 0x1c01f000, 0x4813c857, 0x58cc0009, 0x48002000, 0x48119809, 0x1c01f000, 0x4807c856, 0x4d2c0000, 0x58cc0009, 0x80025d40, 0x04000007, 0x592c0000, 0x4c000000, - 0x0201f800, 0x0010083a, 0x5c000000, 0x0401f7f9, + 0x0201f800, 0x001007f4, 0x5c000000, 0x0401f7f9, 0x5c025800, 0x1c01f000, 0x4807c856, 0x4d2c0000, 0x58cc0002, 0x80025d40, 0x04000007, 0x592c0000, - 0x4c000000, 0x0201f800, 0x0010083a, 0x5c000000, + 0x4c000000, 0x0201f800, 0x001007f4, 0x5c000000, 0x0401f7f9, 0x49799800, 0x49799802, 0x49799801, 0x49799803, 0x49799806, 0x49799807, 0x49799808, 0x49799809, 0x4979980a, 0x5c025800, 0x1c01f000, 0x00000003, 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 0x4803c856, 0x0401f857, 0x4a00c204, 0x0000003c, 0x59301009, 0x82080580, - 0x0010b320, 0x04000013, 0x58080802, 0x82040d00, + 0x0010b524, 0x04000013, 0x58080802, 0x82040d00, 0x00ffffff, 0x58080403, 0x4804c005, 0x4800c406, 0x4a00c207, 0x00000003, 0x59300811, 0x585c0404, 0x4978c206, 0x4804c407, 0x80000540, 0x0400000d, @@ -6279,17 +6457,17 @@ uint32_t risc_code01[] = { 0x4a00c406, 0x000007ff, 0x4978c207, 0x0401f7ef, 0x82603c00, 0x00000008, 0x58605404, 0x40282000, 0x405c6000, 0x585c0a04, 0x82040d00, 0x0000000f, - 0x82040c00, 0x0010110d, 0x50044000, 0x80004d80, + 0x82040c00, 0x001010bd, 0x50044000, 0x80004d80, 0x50200000, 0x80307400, 0x58380402, 0x8c244d00, 0x04020003, 0x48003a00, 0x0401f003, 0x48003c00, 0x801c3800, 0x80244800, 0x80102040, 0x04000006, - 0x0201f800, 0x001010eb, 0x02000800, 0x00100615, + 0x0201f800, 0x0010109b, 0x02000800, 0x001005d8, 0x0401f7f0, 0x1c01f000, 0x4803c856, 0x4d340000, - 0x59300009, 0x80026d40, 0x02000800, 0x00100615, + 0x59300009, 0x80026d40, 0x02000800, 0x001005d8, 0x59340401, 0x80000540, 0x0400000e, 0x59840000, 0x80000540, 0x0400000b, 0x836c0580, 0x00000003, 0x04020008, 0x59341c03, 0x42002000, 0x00000004, - 0x42003000, 0x00000004, 0x0201f800, 0x001038c7, + 0x42003000, 0x00000004, 0x0201f800, 0x00103aae, 0x5c026800, 0x1c01f000, 0x4803c856, 0x80001580, 0x58c80c01, 0x59300011, 0x80040c80, 0x48066011, 0x58c80201, 0x80000540, 0x04000005, 0x80081000, @@ -6302,176 +6480,172 @@ uint32_t risc_code01[] = { 0x5934000e, 0x80006d40, 0x04000010, 0x81300580, 0x04020004, 0x58340000, 0x4802680e, 0x0401f00a, 0x40347800, 0x58340000, 0x80006d40, 0x02000800, - 0x00100615, 0x81300580, 0x040207fa, 0x58340000, + 0x001005d8, 0x81300580, 0x040207fa, 0x58340000, 0x48007800, 0x497a6000, 0x4a0370e5, 0x00020000, 0x1c01f000, 0x4803c856, 0x4d300000, 0x4d2c0000, 0x42000800, 0x000003ff, 0x4a0370e5, 0x00020000, 0x59b800e5, 0x8c000524, 0x04000005, 0x80040840, - 0x040207fa, 0x0201f800, 0x00100615, 0x4a0370e5, + 0x040207fa, 0x0201f800, 0x001005d8, 0x4a0370e5, 0x00030000, 0x40000000, 0x40000000, 0x59b800e5, 0x8c000524, 0x040207f1, 0x5934000e, 0x80026540, 0x0400000e, 0x4933c857, 0x59300000, 0x4802680e, 0x4a026203, 0x00000004, 0x497a6206, 0x497a6009, 0x4a026007, 0x00000101, 0x59325808, 0x497a5c08, - 0x0401fd82, 0x0401f7f1, 0x4a0370e5, 0x00020000, + 0x0401fd81, 0x0401f7f1, 0x4a0370e5, 0x00020000, 0x5c025800, 0x5c026000, 0x1c01f000, 0x4803c856, - 0x4c000000, 0x0201f800, 0x001059b9, 0x04020011, - 0x0201f800, 0x001043fc, 0x02020800, 0x00100615, - 0x5c000000, 0x48026802, 0x0201f800, 0x00020892, + 0x4c000000, 0x0201f800, 0x00105c9a, 0x04020011, + 0x0201f800, 0x001045a6, 0x02020800, 0x001005d8, + 0x5c000000, 0x48026802, 0x0201f800, 0x0002075a, 0x04000009, 0x49366009, 0x4a026406, 0x00000001, - 0x42027000, 0x00000001, 0x0201f000, 0x000208d8, + 0x42027000, 0x00000001, 0x0201f000, 0x000207a1, 0x5c000000, 0x1c01f000, 0x59300203, 0x82000c80, - 0x0000000e, 0x02021800, 0x00100615, 0x4803c857, - 0x0c01f001, 0x0010623b, 0x0010623b, 0x0010623b, - 0x0010623d, 0x0010629d, 0x0010623b, 0x0010623b, - 0x001062ef, 0x001062f0, 0x0010623b, 0x0010623b, - 0x0010623b, 0x0010623b, 0x0010623b, 0x0201f800, - 0x00100615, 0x493bc857, 0x83380480, 0x00000050, - 0x02021800, 0x00100615, 0x83380480, 0x00000049, - 0x02001800, 0x00100615, 0x0c01f001, 0x00106250, - 0x00106272, 0x0010624e, 0x0010624e, 0x0010624e, - 0x0010624e, 0x00106281, 0x0201f800, 0x00100615, + 0x0000000e, 0x02021800, 0x001005d8, 0x4803c857, + 0x0c01f001, 0x00106503, 0x00106503, 0x00106503, + 0x00106505, 0x00106565, 0x00106503, 0x00106503, + 0x001065b7, 0x001065b8, 0x00106503, 0x00106503, + 0x00106503, 0x00106503, 0x00106503, 0x0201f800, + 0x001005d8, 0x493bc857, 0x83380480, 0x00000050, + 0x02021800, 0x001005d8, 0x83380480, 0x00000049, + 0x02001800, 0x001005d8, 0x0c01f001, 0x00106518, + 0x0010653a, 0x00106516, 0x00106516, 0x00106516, + 0x00106516, 0x00106549, 0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808, 0x592c0206, 0x48025c06, 0x4a025a06, 0x00000000, 0x4c5c0000, 0x592cbc0a, - 0x592c0000, 0x48026008, 0x0201f800, 0x00020385, + 0x592c0000, 0x48026008, 0x0201f800, 0x00104cde, 0x59300008, 0x80000540, 0x04000008, 0x4a026203, 0x00000007, 0x42027000, 0x00000043, 0x5c00b800, 0x5c025800, 0x0401f08a, 0x8c5cbd08, 0x04020006, 0x4a026203, 0x00000007, 0x497a6206, 0x497a6008, - 0x0401f003, 0x0201f800, 0x000208b4, 0x5c00b800, - 0x5c025800, 0x1c01f000, 0x0201f800, 0x001068c1, - 0x4d2c0000, 0x59325808, 0x0201f800, 0x00108df4, + 0x0401f003, 0x0201f800, 0x0002077d, 0x5c00b800, + 0x5c025800, 0x1c01f000, 0x0201f800, 0x00106b8a, + 0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037, 0x04000006, 0x4d400000, 0x42028000, 0x00000001, - 0x0401f90e, 0x5c028000, 0x5c025800, 0x0201f000, - 0x000208b4, 0x0201f800, 0x001068c1, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, - 0x42003000, 0x00000014, 0x0201f800, 0x0010a766, - 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, - 0x4d2c0000, 0x59325808, 0x0201f800, 0x00108df4, + 0x0401f8f8, 0x5c028000, 0x5c025800, 0x0201f000, + 0x0002077d, 0x0201f800, 0x00106b8a, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800, + 0x42003000, 0x00000014, 0x0201f800, 0x0010a942, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037, 0x04000006, 0x4d400000, 0x42028000, 0x00000029, - 0x0401f8f2, 0x5c028000, 0x5c025800, 0x0201f000, - 0x000208b4, 0x493bc857, 0x497a6206, 0x83380480, - 0x00000054, 0x02021800, 0x00100615, 0x83380480, - 0x00000047, 0x02001800, 0x00100615, 0x0c01f001, - 0x001062ee, 0x001062b7, 0x001062b5, 0x001062b5, - 0x001062b5, 0x001062b5, 0x001062b5, 0x001062b5, - 0x001062b5, 0x001062b5, 0x001062b5, 0x001062b5, - 0x001062bb, 0x0201f800, 0x00100615, 0x59300011, + 0x0401f8dc, 0x5c028000, 0x5c025800, 0x0201f000, + 0x0002077d, 0x493bc857, 0x497a6206, 0x83380480, + 0x00000054, 0x02021800, 0x001005d8, 0x83380480, + 0x00000047, 0x02001800, 0x001005d8, 0x0c01f001, + 0x001065b6, 0x0010657f, 0x0010657d, 0x0010657d, + 0x0010657d, 0x0010657d, 0x0010657d, 0x0010657d, + 0x0010657d, 0x0010657d, 0x0010657d, 0x0010657d, + 0x00106583, 0x0201f800, 0x001005d8, 0x59300011, 0x82000500, 0xffff0000, 0x04020034, 0x59840802, 0x8c040d04, 0x04000025, 0x59300009, 0x80026d40, 0x0400001f, 0x4c5c0000, 0x4c600000, 0x497a6206, 0x5930b808, 0x585c0005, 0x8000c540, 0x02000800, - 0x00100615, 0x0401fe8d, 0x40625800, 0x0201f800, - 0x00020385, 0x4978b805, 0x0401fef5, 0x497a6009, - 0x585c3408, 0x0401fcbe, 0x0400000e, 0x42001000, - 0x0010b315, 0x0401fcf3, 0x0400000a, 0x0201f800, - 0x0010082a, 0x04000007, 0x492cb805, 0x585c5408, - 0x0401fc84, 0x5c00c000, 0x5c00b800, 0x1c01f000, - 0x0401fcaa, 0x0401f7fc, 0x8c040d06, 0x040207fc, + 0x001005d8, 0x0401fe8d, 0x40625800, 0x0201f800, + 0x00104cde, 0x4978b805, 0x0401fef5, 0x497a6009, + 0x585c3408, 0x0401fcbd, 0x0400000e, 0x42001000, + 0x0010b519, 0x0401fcf2, 0x0400000a, 0x0201f800, + 0x001007e4, 0x04000007, 0x492cb805, 0x585c5408, + 0x0401fc83, 0x5c00c000, 0x5c00b800, 0x1c01f000, + 0x0401fca9, 0x0401f7fc, 0x8c040d06, 0x040207fc, 0x59300009, 0x80026d40, 0x04000006, 0x5934000e, - 0x80000540, 0x02020800, 0x00100615, 0x497a6009, - 0x0401fd0e, 0x0401f7f2, 0x0401f085, 0x4803c856, + 0x80000540, 0x02020800, 0x001005d8, 0x497a6009, + 0x0401fd0d, 0x0401f7f2, 0x0401f06f, 0x4803c856, 0x4803c856, 0x83380580, 0x00000043, 0x02020800, - 0x00100615, 0x4a026203, 0x00000003, 0x493a6403, + 0x001005d8, 0x4a026203, 0x00000003, 0x493a6403, 0x59325808, 0x592c000f, 0x48026011, 0x497a6013, 0x592c0406, 0x800000c2, 0x800010c4, 0x80081400, - 0x480a6206, 0x0201f800, 0x00100f9c, 0x42000800, - 0x80000060, 0x0401f161, 0x42000000, 0x0010b674, - 0x0201f800, 0x0010a86e, 0x59300203, 0x82000c80, - 0x0000000e, 0x02021800, 0x00100615, 0x4803c857, + 0x480a6206, 0x0201f800, 0x00100f4e, 0x42000800, + 0x80000060, 0x0401f154, 0x42000000, 0x0010b875, + 0x0201f800, 0x0010aa47, 0x59300203, 0x82000c80, + 0x0000000e, 0x02021800, 0x001005d8, 0x4803c857, 0x82000d80, 0x00000003, 0x04000006, 0x82000d80, - 0x00000004, 0x0400005b, 0x0201f800, 0x00100615, - 0x0201f800, 0x0010698c, 0x59300004, 0x8c00053e, - 0x04020007, 0x0201f800, 0x001068a3, 0x02020800, - 0x00100615, 0x0201f000, 0x00106982, 0x0401f9d3, - 0x0201f800, 0x00106982, 0x59325808, 0x42028000, - 0x00000006, 0x0401f861, 0x0201f000, 0x000208b4, + 0x00000004, 0x04000045, 0x0201f800, 0x001005d8, + 0x0201f800, 0x00106c55, 0x59300004, 0x8c00053e, + 0x04020007, 0x0201f800, 0x00106b6c, 0x02020800, + 0x001005d8, 0x0201f000, 0x00106c4b, 0x0401f9c3, + 0x0201f800, 0x00106c4b, 0x59325808, 0x42028000, + 0x00000006, 0x0401f84b, 0x0201f000, 0x0002077d, 0x4803c856, 0x59300203, 0x82000c80, 0x0000000e, - 0x02021800, 0x00100615, 0x82000d80, 0x00000002, - 0x04000009, 0x82000d80, 0x00000003, 0x04000019, - 0x82000d80, 0x00000004, 0x04000036, 0x0201f800, - 0x00100615, 0x4933c857, 0x4d2c0000, 0x59325808, - 0x812e59c0, 0x02000800, 0x00100615, 0x592c1a08, - 0x8c0c1d0e, 0x02000800, 0x00100615, 0x4d400000, - 0x42028000, 0x00000001, 0x0401f840, 0x0201f800, - 0x00107698, 0x5c028000, 0x5c025800, 0x1c01f000, - 0x4933c857, 0x0201f800, 0x0010698c, 0x4df00000, - 0x59300004, 0x8c00053e, 0x04020006, 0x0201f800, - 0x00106cb4, 0x02020800, 0x00100615, 0x0401f010, - 0x0201f800, 0x00108a8a, 0x04020004, 0x0201f800, - 0x00106bb2, 0x0402000a, 0x0401f994, 0x02020800, - 0x00100615, 0x5c03e000, 0x02000800, 0x00106982, - 0x82000540, 0x00000001, 0x1c01f000, 0x5c03e000, - 0x02000800, 0x00106982, 0x80000580, 0x1c01f000, - 0x4933c857, 0x0201f800, 0x00100ee4, 0x4933c857, - 0x4c5c0000, 0x4d340000, 0x497a6206, 0x5930b808, - 0x59300009, 0x80026d40, 0x04020e49, 0x42001000, - 0x0010b315, 0x0401fc4b, 0x04000009, 0x58c80204, - 0x4800bc08, 0x41785000, 0x0201f800, 0x00105f60, - 0x5c026800, 0x5c00b800, 0x1c01f000, 0x4978bc08, - 0x0401fc02, 0x0401f7fb, 0x4803c856, 0x0201f800, - 0x00108df4, 0x0400000f, 0x592c0000, 0x80000d40, - 0x04000009, 0x497a5800, 0x49425a06, 0x4c040000, - 0x0201f800, 0x00020381, 0x5c000800, 0x40065800, - 0x0401f7f6, 0x49425a06, 0x0201f800, 0x00020381, - 0x1c01f000, 0x4933c857, 0x59300c06, 0x82040580, - 0x0000000e, 0x04000004, 0x82040580, 0x00000009, - 0x04020004, 0x0401ffe5, 0x497a6008, 0x80000580, - 0x1c01f000, 0x592e6009, 0x83300480, 0x0010cfc0, - 0x04001016, 0x41580000, 0x81300480, 0x04021013, - 0x40040000, 0x59300c06, 0x80040580, 0x04020012, - 0x59300a03, 0x82040580, 0x00000007, 0x02020800, - 0x00100615, 0x59300008, 0x80000540, 0x02020800, - 0x00100615, 0x0201f800, 0x000208b4, 0x42000000, - 0x00000000, 0x0401f009, 0x42000000, 0x00000008, - 0x0401f006, 0x82040580, 0x00000007, 0x040207fb, - 0x42000000, 0x00000005, 0x592c0a06, 0x48065c06, - 0x48025a06, 0x0201f000, 0x00020381, 0x4c0c0000, - 0x4c100000, 0x4c140000, 0x4c180000, 0x80001d80, - 0x80002580, 0x42003000, 0x00000020, 0x82040500, - 0x00000001, 0x04000003, 0x40080000, 0x800c1c00, - 0x400c2800, 0x800c1902, 0x80102102, 0x82140500, - 0x00000001, 0x04000003, 0x82102540, 0x80000000, - 0x80040902, 0x80183040, 0x040207f1, 0x40100800, - 0x400c0000, 0x5c003000, 0x5c002800, 0x5c002000, - 0x5c001800, 0x1c01f000, 0x4c580000, 0x4200b000, - 0x00000020, 0x80000540, 0x04000018, 0x80041c80, - 0x04021016, 0x800810c2, 0x80040982, 0x04001006, - 0x80041c80, 0x04021005, 0x8058b040, 0x040207fa, - 0x0401f006, 0x80041c80, 0x400c0800, 0x80081000, - 0x8058b040, 0x040207f4, 0x4c000000, 0x41f00000, - 0x82000500, 0xf7ffffff, 0x4003e000, 0x5c000000, - 0x5c00b000, 0x1c01f000, 0x4c000000, 0x41f00000, - 0x82000540, 0x08000000, 0x0401f7f8, 0x42007000, - 0x0010b33f, 0x4a007000, 0x00000005, 0x4a007401, - 0x00000000, 0x4a007202, 0x00000840, 0x4a0378e8, - 0x00000000, 0x4a03c821, 0x00000010, 0x4a03c823, - 0x00000004, 0x0401f81d, 0x4a0378e9, 0x00003a0d, - 0x4a0378e8, 0x00000001, 0x42000800, 0x00000005, - 0x4203a000, 0x00007600, 0x4a03a005, 0xd0000001, - 0x59d00006, 0x4a03a005, 0x90000001, 0x83d3a400, - 0x00000020, 0x80040840, 0x040207fa, 0x59e00003, - 0x82000500, 0xffffffe0, 0x82000540, 0x00008000, - 0x4803c003, 0x59c40006, 0x82000500, 0xfffcffff, - 0x48038806, 0x1c01f000, 0x4d900000, 0x4d180000, - 0x4a0378e7, 0xaaaaaaaa, 0x4a0378e6, 0xaaaaaaaa, - 0x4a0378e5, 0xaaaaaaaa, 0x4a0378e4, 0xaaaaaaaa, - 0x4a03781a, 0x0010b5d2, 0x4a03781b, 0x0010110d, - 0x4a03781c, 0x0010111d, 0x4a031800, 0x00000000, - 0x4a031801, 0x0010b342, 0x4a031802, 0x0010b349, - 0x42000800, 0x0010b5d5, 0x417a3000, 0x811b20c8, - 0x83932400, 0x0000bf32, 0x48072000, 0x4a032001, - 0x00000000, 0x83180400, 0x00106e41, 0x50000000, - 0x48032002, 0x82040c00, 0x00000003, 0x811a3000, - 0x83180480, 0x00000005, 0x040017f1, 0x5c023000, - 0x5c032000, 0x1c01f000, 0x48066004, 0x497a6000, - 0x497a6001, 0x59bc00ea, 0x8c000516, 0x040207fe, - 0x83300400, 0xa0000000, 0x480378e1, 0x1c01f000, - 0x4933c857, 0x59300804, 0x82040d00, 0x00000100, - 0x82040d40, 0x80000040, 0x48066004, 0x497a6000, + 0x02021800, 0x001005d8, 0x82000d80, 0x00000003, + 0x04000006, 0x82000d80, 0x00000004, 0x04000023, + 0x0201f800, 0x001005d8, 0x4803c856, 0x0201f800, + 0x00106c55, 0x4df00000, 0x59300004, 0x8c00053e, + 0x04020006, 0x0201f800, 0x00106f60, 0x02020800, + 0x001005d8, 0x0401f010, 0x0201f800, 0x00108cd6, + 0x04020004, 0x0201f800, 0x00106e62, 0x0402000a, + 0x0401f99a, 0x02020800, 0x001005d8, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x82000540, 0x00000001, + 0x1c01f000, 0x5c03e000, 0x02000800, 0x00106c4b, + 0x80000580, 0x1c01f000, 0x4933c857, 0x0201f800, + 0x00100e99, 0x4933c857, 0x4c5c0000, 0x4d340000, + 0x497a6206, 0x5930b808, 0x59300009, 0x80026d40, + 0x04020e5f, 0x42001000, 0x0010b519, 0x0401fc60, + 0x04000009, 0x58c80204, 0x4800bc08, 0x41785000, + 0x0201f800, 0x00106227, 0x5c026800, 0x5c00b800, + 0x1c01f000, 0x4978bc08, 0x0401fc17, 0x0401f7fb, + 0x4803c856, 0x0201f800, 0x00109037, 0x0400000f, + 0x592c0000, 0x80000d40, 0x04000009, 0x497a5800, + 0x49425a06, 0x4c040000, 0x0201f800, 0x000202da, + 0x5c000800, 0x40065800, 0x0401f7f6, 0x49425a06, + 0x0201f800, 0x000202da, 0x1c01f000, 0x4933c857, + 0x59300c06, 0x82040580, 0x0000000e, 0x04000004, + 0x82040580, 0x00000009, 0x04020004, 0x0401ffe5, + 0x497a6008, 0x80000580, 0x1c01f000, 0x592e6009, + 0x83300480, 0x0010d1c0, 0x04001016, 0x41580000, + 0x81300480, 0x04021013, 0x40040000, 0x59300c06, + 0x80040580, 0x04020012, 0x59300a03, 0x82040580, + 0x00000007, 0x02020800, 0x001005d8, 0x59300008, + 0x80000540, 0x02020800, 0x001005d8, 0x0201f800, + 0x0002077d, 0x42000000, 0x00000000, 0x0401f009, + 0x42000000, 0x00000008, 0x0401f006, 0x82040580, + 0x00000007, 0x040207fb, 0x42000000, 0x00000005, + 0x592c0a06, 0x48065c06, 0x48025a06, 0x0201f000, + 0x000202da, 0x4c0c0000, 0x4c100000, 0x4c140000, + 0x4c180000, 0x80001d80, 0x80002580, 0x42003000, + 0x00000020, 0x82040500, 0x00000001, 0x04000003, + 0x40080000, 0x800c1c00, 0x400c2800, 0x800c1902, + 0x80102102, 0x82140500, 0x00000001, 0x04000003, + 0x82102540, 0x80000000, 0x80040902, 0x80183040, + 0x040207f1, 0x40100800, 0x400c0000, 0x5c003000, + 0x5c002800, 0x5c002000, 0x5c001800, 0x1c01f000, + 0x4c580000, 0x4200b000, 0x00000020, 0x80000540, + 0x04000018, 0x80041c80, 0x04021016, 0x800810c2, + 0x80040982, 0x04001006, 0x80041c80, 0x04021005, + 0x8058b040, 0x040207fa, 0x0401f006, 0x80041c80, + 0x400c0800, 0x80081000, 0x8058b040, 0x040207f4, + 0x4c000000, 0x41f00000, 0x82000500, 0xf7ffffff, + 0x4003e000, 0x5c000000, 0x5c00b000, 0x1c01f000, + 0x4c000000, 0x41f00000, 0x82000540, 0x08000000, + 0x0401f7f8, 0x4a0378e8, 0x00000000, 0x4a03c821, + 0x00000010, 0x4a03c823, 0x00000004, 0x0401f82c, + 0x4a0378e9, 0x00003a0d, 0x4a0378e8, 0x00000001, + 0x42000000, 0x00001000, 0x50000000, 0x82000480, + 0x24220001, 0x04000004, 0x59e00002, 0x84000548, + 0x4803c002, 0x42000800, 0x00000005, 0x4203a000, + 0x00007600, 0x42000000, 0x00001000, 0x50000000, + 0x82000480, 0x24320001, 0x04021003, 0x4a03a005, + 0xd0000001, 0x59d00006, 0x4a03a005, 0x90000001, + 0x83d3a400, 0x00000020, 0x80040840, 0x040207fa, + 0x59e00003, 0x82000500, 0xffffffe0, 0x82000540, + 0x00008000, 0x4803c003, 0x59c40006, 0x82000500, + 0xfffcffff, 0x48038806, 0x1c01f000, 0x4d900000, + 0x4d180000, 0x4a0378e7, 0xaaaaaaaa, 0x4a0378e6, + 0xaaaaaaaa, 0x4a0378e5, 0xaaaaaaaa, 0x4a0378e4, + 0xaaaaaaaa, 0x42000800, 0x0000bf00, 0x4a00081a, + 0x0010b7d4, 0x4a00081b, 0x001010bd, 0x4a00081c, + 0x001010cd, 0x4a031800, 0x00000000, 0x4a031801, + 0x0010b544, 0x4a031802, 0x0010b54b, 0x42000800, + 0x0010b7d7, 0x417a3000, 0x811b20c8, 0x83932400, + 0x0000bf32, 0x48072000, 0x4a032001, 0x00000000, + 0x83180400, 0x001070ea, 0x50000000, 0x48032002, + 0x82040c00, 0x00000003, 0x811a3000, 0x83180480, + 0x00000005, 0x040017f1, 0x5c023000, 0x5c032000, + 0x1c01f000, 0x48066004, 0x497a6000, 0x497a6001, + 0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400, + 0xa0000000, 0x480378e1, 0x1c01f000, 0x4933c857, + 0x42000800, 0x80000040, 0x48066004, 0x497a6000, 0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400, 0x60000000, 0x480378e1, 0x1c01f000, 0x0201f800, - 0x0010698c, 0x4df00000, 0x4d300000, 0x4d340000, + 0x00106c55, 0x4df00000, 0x4d300000, 0x4d340000, 0x4d2c0000, 0x4d180000, 0x4c5c0000, 0x4c600000, 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, 0x42003000, 0x0000bf2e, 0x581a6001, 0x813261c0, @@ -6480,440 +6654,438 @@ uint32_t risc_code01[] = { 0x82000d80, 0x00000006, 0x04020003, 0x8d3e7d18, 0x04000010, 0x8d3e7d06, 0x04000007, 0x82000580, 0x00000003, 0x04020004, 0x59340200, 0x8c00050e, - 0x04020008, 0x0401f92d, 0x4c0c0000, 0x4c140000, - 0x0401fb59, 0x5c002800, 0x5c001800, 0x0401f005, + 0x04020008, 0x0401f92f, 0x4c0c0000, 0x4c140000, + 0x0401fb5f, 0x5c002800, 0x5c001800, 0x0401f005, 0x41301800, 0x8060c1c0, 0x04020002, 0x400cc000, 0x805cb9c0, 0x04000003, 0x405e6000, 0x0401f7e3, 0x5c026000, 0x813261c0, 0x04000006, 0x8060c1c0, 0x04000002, 0x40602800, 0x4178c000, 0x0401f7d8, - 0x417a3000, 0x0201f800, 0x00106e2f, 0x59926004, + 0x417a3000, 0x0201f800, 0x001070d8, 0x59926004, 0x813261c0, 0x04000023, 0x59326809, 0x4130c000, 0x59300001, 0x8000bd40, 0x04000016, 0x40026000, 0x40602800, 0x5930b801, 0x59300406, 0x82000d80, 0x00000006, 0x0400000e, 0x8d3e7d06, 0x04000007, 0x82000580, 0x00000003, 0x04020004, 0x59340200, - 0x8c00050e, 0x04020006, 0x0401f8da, 0x4c140000, - 0x0401fb29, 0x5c002800, 0x0401f002, 0x41302800, + 0x8c00050e, 0x04020006, 0x0401f8dc, 0x4c140000, + 0x0401fb2f, 0x5c002800, 0x0401f002, 0x41302800, 0x405e6000, 0x813261c0, 0x040207eb, 0x8060c1c0, 0x04000004, 0x40626000, 0x4178c000, 0x0401f7e7, 0x811a3000, 0x83180480, 0x00000005, 0x040017d6, 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c00c000, 0x5c00b800, 0x5c023000, 0x5c025800, 0x5c026800, 0x5c026000, 0x5c03e000, 0x02000800, - 0x00106982, 0x1c01f000, 0x4933c857, 0x0201f800, - 0x0010698c, 0x4df00000, 0x4d340000, 0x4d180000, + 0x00106c4b, 0x1c01f000, 0x4933c857, 0x0201f800, + 0x00106c55, 0x4df00000, 0x4d340000, 0x4d180000, 0x4d900000, 0x42003000, 0x0000bf2e, 0x59326809, 0x58182001, 0x40102800, 0x801021c0, 0x04000016, 0x41300000, 0x80100580, 0x04000011, 0x58100009, 0x81340580, 0x0402000b, 0x40101800, 0x58102001, 0x41300000, 0x801021c0, 0x0400000b, 0x80100d80, 0x04000007, 0x40101800, 0x58102001, 0x0401f7fa, - 0x40102800, 0x58102000, 0x0401f7ec, 0x0401f8bb, + 0x40102800, 0x58102000, 0x0401f7ec, 0x0401f8bd, 0x0401f01a, 0x42032000, 0x0000bf32, 0x417a3000, 0x59902004, 0x40102800, 0x801021c0, 0x0400000b, 0x58100009, 0x81340580, 0x04020008, 0x41300000, 0x80100580, 0x0400000c, 0x40102800, 0x58102001, 0x801021c0, 0x040207fa, 0x811a3000, 0x83180480, 0x00000005, 0x0402100d, 0x83932400, 0x00000010, - 0x0401f7ec, 0x0401f87f, 0x5c032000, 0x5c023000, - 0x5c026800, 0x5c03e000, 0x02000800, 0x00106982, - 0x80000580, 0x1c01f000, 0x5c032000, 0x5c023000, - 0x5c026800, 0x5c03e000, 0x02000800, 0x00106982, - 0x82000540, 0x00000001, 0x1c01f000, 0x0201f800, - 0x0010698c, 0x4df00000, 0x4d300000, 0x4d340000, - 0x4d180000, 0x4d2c0000, 0x4c5c0000, 0x4c600000, - 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, - 0x42003000, 0x0000bf2e, 0x581a6001, 0x813261c0, - 0x04000023, 0x41302800, 0x5930b800, 0x59326809, - 0x59340403, 0x81440580, 0x04000006, 0x805cb9c0, - 0x0400001b, 0x41302800, 0x405e6000, 0x0401f7f7, - 0x5930b801, 0x8d3e7d00, 0x04000003, 0x0401fb58, - 0x0402000e, 0x59300406, 0x82000580, 0x00000006, - 0x04020003, 0x8d3e7d18, 0x04000008, 0x0401f867, - 0x4c0c0000, 0x4c140000, 0x0401fa93, 0x5c002800, - 0x5c001800, 0x0401f002, 0x41301800, 0x405e6000, - 0x813261c0, 0x040207eb, 0x0401f02d, 0x417a3000, - 0x0201f800, 0x00106e2f, 0x59926004, 0x813261c0, - 0x04000005, 0x59326809, 0x59340403, 0x81440580, - 0x04000006, 0x811a3000, 0x83180480, 0x00000005, - 0x040017f4, 0x0401f01e, 0x4130c000, 0x59300001, - 0x8000bd40, 0x04000012, 0x40026000, 0x40602800, - 0x5930b801, 0x8d3e7d00, 0x04000003, 0x0401fb2c, - 0x0402000a, 0x59300406, 0x82000580, 0x00000006, - 0x04000006, 0x0401f81b, 0x4c140000, 0x0401fa6a, - 0x5c002800, 0x0401f002, 0x41302800, 0x405e6000, - 0x813261c0, 0x040207ef, 0x8060c1c0, 0x04000004, - 0x40626000, 0x4178c000, 0x0401f7eb, 0x5c022800, - 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c00c000, - 0x5c00b800, 0x5c025800, 0x5c023000, 0x5c026800, - 0x5c026000, 0x5c03e000, 0x04000bd4, 0x1c01f000, - 0x0401fbb9, 0x59900004, 0x81300580, 0x04020018, - 0x4c140000, 0x0201f800, 0x00106b13, 0x0401fba9, - 0x5c002800, 0x59300001, 0x800001c0, 0x04020003, - 0x497a680c, 0x1c01f000, 0x42003000, 0x0000bf2e, - 0x497a6001, 0x58180801, 0x800409c0, 0x04020004, - 0x48003000, 0x48003001, 0x1c01f000, 0x58180800, - 0x48000800, 0x48003000, 0x1c01f000, 0x59300001, - 0x48002801, 0x800001c0, 0x04020002, 0x4816680c, - 0x497a6001, 0x1c01f000, 0x0401fb97, 0x42003000, - 0x0000bf2e, 0x58180001, 0x81300580, 0x0402001c, - 0x59300801, 0x800409c0, 0x0400000e, 0x59300000, - 0x800001c0, 0x04020005, 0x48043001, 0x48043000, - 0x497a6001, 0x1c01f000, 0x59300000, 0x48000800, - 0x48043001, 0x497a6000, 0x497a6001, 0x1c01f000, - 0x59300800, 0x800409c0, 0x04020005, 0x49783001, - 0x49783000, 0x497a680c, 0x1c01f000, 0x48043001, - 0x497a6000, 0x497a680c, 0x1c01f000, 0x58180000, - 0x81300580, 0x0402000c, 0x59300001, 0x800001c0, - 0x04020005, 0x48143000, 0x49782800, 0x497a680c, - 0x1c01f000, 0x48003000, 0x48002800, 0x497a6001, - 0x1c01f000, 0x59300000, 0x800001c0, 0x04020008, - 0x59300001, 0x48001801, 0x800001c0, 0x04020002, - 0x480e680c, 0x497a6001, 0x1c01f000, 0x59300801, - 0x800409c0, 0x04020006, 0x59300800, 0x48042800, - 0x497a6000, 0x497a680c, 0x1c01f000, 0x59300000, - 0x48000800, 0x48042800, 0x497a6000, 0x497a6001, - 0x1c01f000, 0x0401fb73, 0x4df00000, 0x0401f83a, - 0x040208c7, 0x0402094a, 0x04020005, 0x5c03e000, - 0x04000b62, 0x80000580, 0x1c01f000, 0x5c03e000, - 0x04000b5e, 0x82000540, 0x00000001, 0x1c01f000, - 0x4d2c0000, 0x4d340000, 0x4d300000, 0x41783000, - 0x598e6009, 0x813261c0, 0x04000023, 0x59300406, - 0x82000580, 0x00000006, 0x04020004, 0x8d3e7d18, - 0x0402000c, 0x0401f019, 0x82040580, 0x00000005, - 0x04020008, 0x8d3e7d18, 0x04000003, 0x8d3e7d16, - 0x04000004, 0x59300420, 0x8c000500, 0x0402000f, - 0x0401fa49, 0x59300000, 0x4c000000, 0x8d3e7d06, - 0x04000004, 0x0201f800, 0x0010909d, 0x04000005, - 0x0401f869, 0x4c180000, 0x0401f9b7, 0x5c003000, - 0x5c026000, 0x0401f7e0, 0x41303000, 0x59326000, - 0x0401f7dd, 0x5c026000, 0x5c026800, 0x5c025800, - 0x1c01f000, 0x4933c857, 0x4c5c0000, 0x813261c0, - 0x02000800, 0x00100615, 0x41300000, 0x598cb809, - 0x41783000, 0x805cb9c0, 0x04000013, 0x805c0d80, - 0x04000004, 0x405c3000, 0x5818b800, 0x0401f7fa, - 0x0401f84d, 0x598c000d, 0x81300580, 0x02000800, - 0x00106e10, 0x59300403, 0x82000580, 0x00000042, - 0x04020002, 0x497a6007, 0x80000580, 0x5c00b800, - 0x1c01f000, 0x82000540, 0x00000001, 0x5c00b800, - 0x1c01f000, 0x0401fb17, 0x4df00000, 0x4d2c0000, + 0x0401f7ec, 0x0401f881, 0x5c032000, 0x5c023000, + 0x5c026800, 0x5c03e000, 0x02000800, 0x00106c4b, + 0x80000580, 0x1c01f000, 0x0401fb6f, 0x040007f7, + 0x5c032000, 0x5c023000, 0x5c026800, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x82000540, 0x00000001, + 0x1c01f000, 0x0201f800, 0x00106c55, 0x4df00000, + 0x4d300000, 0x4d340000, 0x4d180000, 0x4d2c0000, + 0x4c5c0000, 0x4c600000, 0x4d900000, 0x4dd00000, + 0x4da40000, 0x4d140000, 0x42003000, 0x0000bf2e, + 0x581a6001, 0x813261c0, 0x04000023, 0x41302800, + 0x5930b800, 0x59326809, 0x59340403, 0x81440580, + 0x04000006, 0x805cb9c0, 0x0400001b, 0x41302800, + 0x405e6000, 0x0401f7f7, 0x5930b801, 0x8d3e7d00, + 0x04000003, 0x0401fb67, 0x0402000e, 0x59300406, + 0x82000580, 0x00000006, 0x04020003, 0x8d3e7d18, + 0x04000008, 0x0401f867, 0x4c0c0000, 0x4c140000, + 0x0401fa97, 0x5c002800, 0x5c001800, 0x0401f002, + 0x41301800, 0x405e6000, 0x813261c0, 0x040207eb, + 0x0401f02d, 0x417a3000, 0x0201f800, 0x001070d8, + 0x59926004, 0x813261c0, 0x04000005, 0x59326809, + 0x59340403, 0x81440580, 0x04000006, 0x811a3000, + 0x83180480, 0x00000005, 0x040017f4, 0x0401f01e, + 0x4130c000, 0x59300001, 0x8000bd40, 0x04000012, + 0x40026000, 0x40602800, 0x5930b801, 0x8d3e7d00, + 0x04000003, 0x0401fb3b, 0x0402000a, 0x59300406, + 0x82000580, 0x00000006, 0x04000006, 0x0401f81b, + 0x4c140000, 0x0401fa6e, 0x5c002800, 0x0401f002, + 0x41302800, 0x405e6000, 0x813261c0, 0x040207ef, + 0x8060c1c0, 0x04000004, 0x40626000, 0x4178c000, + 0x0401f7eb, 0x5c022800, 0x5c034800, 0x5c03a000, + 0x5c032000, 0x5c00c000, 0x5c00b800, 0x5c025800, + 0x5c023000, 0x5c026800, 0x5c026000, 0x5c03e000, + 0x04000be3, 0x1c01f000, 0x0401fbc8, 0x59900004, + 0x81300580, 0x04020018, 0x4c140000, 0x0201f800, + 0x00106dc3, 0x0401fbb8, 0x5c002800, 0x59300001, + 0x800001c0, 0x04020003, 0x497a680c, 0x1c01f000, + 0x42003000, 0x0000bf2e, 0x497a6001, 0x58180801, + 0x800409c0, 0x04020004, 0x48003000, 0x48003001, + 0x1c01f000, 0x58180800, 0x48000800, 0x48003000, + 0x1c01f000, 0x59300001, 0x48002801, 0x800001c0, + 0x04020002, 0x4816680c, 0x497a6001, 0x1c01f000, + 0x0401fba6, 0x42003000, 0x0000bf2e, 0x58180001, + 0x81300580, 0x0402001c, 0x59300801, 0x800409c0, + 0x0400000e, 0x59300000, 0x800001c0, 0x04020005, + 0x48043001, 0x48043000, 0x497a6001, 0x1c01f000, + 0x59300000, 0x48000800, 0x48043001, 0x497a6000, + 0x497a6001, 0x1c01f000, 0x59300800, 0x800409c0, + 0x04020005, 0x49783001, 0x49783000, 0x497a680c, + 0x1c01f000, 0x48043001, 0x497a6000, 0x497a680c, + 0x1c01f000, 0x58180000, 0x81300580, 0x0402000c, + 0x59300001, 0x800001c0, 0x04020005, 0x48143000, + 0x49782800, 0x497a680c, 0x1c01f000, 0x48003000, + 0x48002800, 0x497a6001, 0x1c01f000, 0x59300000, + 0x800001c0, 0x04020008, 0x59300001, 0x48001801, + 0x800001c0, 0x04020002, 0x480e680c, 0x497a6001, + 0x1c01f000, 0x59300801, 0x800409c0, 0x04020006, + 0x59300800, 0x48042800, 0x497a6000, 0x497a680c, + 0x1c01f000, 0x59300000, 0x48000800, 0x48042800, + 0x497a6000, 0x497a6001, 0x1c01f000, 0x0401fb82, + 0x4df00000, 0x0401f839, 0x040208c4, 0x04020945, + 0x04020a89, 0x04020005, 0x5c03e000, 0x04000b70, + 0x80000580, 0x1c01f000, 0x5c03e000, 0x04000b6c, + 0x82000540, 0x00000001, 0x1c01f000, 0x4d2c0000, 0x4d340000, 0x4d300000, 0x41783000, 0x598e6009, - 0x813261c0, 0x0400002e, 0x59300c06, 0x82040580, - 0x00000006, 0x04020004, 0x8d3e7d18, 0x0402000c, - 0x0401f024, 0x82040580, 0x00000005, 0x04020008, - 0x8d3e7d18, 0x04000003, 0x8d3e7d16, 0x04000004, - 0x59300420, 0x8c000500, 0x0402001a, 0x59326809, - 0x59340403, 0x81440580, 0x04020016, 0x8d3e7d00, - 0x04000006, 0x82040580, 0x00000003, 0x04020011, - 0x0401fa23, 0x0402000f, 0x0401f9ef, 0x59300000, - 0x4c000000, 0x8d3e7d06, 0x04000004, 0x0201f800, - 0x0010909d, 0x04000005, 0x0401f80f, 0x4c180000, - 0x0401f95d, 0x5c003000, 0x5c026000, 0x0401f7d5, - 0x41303000, 0x59326000, 0x0401f7d2, 0x5c026000, - 0x5c026800, 0x5c025800, 0x5c03e000, 0x04000ad3, - 0x1c01f000, 0x59300800, 0x497a6000, 0x0401fab6, - 0x801831c0, 0x04020009, 0x598c0008, 0x81300580, - 0x04020004, 0x48031808, 0x48031809, 0x0401f008, - 0x48071809, 0x0401f006, 0x48043000, 0x598c0008, - 0x81300580, 0x04020002, 0x481b1808, 0x0401f2b8, - 0x4d2c0000, 0x4d300000, 0x4d340000, 0x41783000, - 0x598e600b, 0x813261c0, 0x04000013, 0x8d3e7d06, - 0x04000005, 0x59326809, 0x59340200, 0x8c00050e, - 0x0402000a, 0x0401f9b8, 0x59300000, 0x4c000000, - 0x0401f853, 0x4c180000, 0x0401f92b, 0x5c003000, - 0x5c026000, 0x0401f7f0, 0x41303000, 0x59326000, - 0x0401f7ed, 0x0201f800, 0x001045c7, 0x5c026800, - 0x5c026000, 0x5c025800, 0x1c01f000, 0x4933c857, - 0x4c5c0000, 0x813261c0, 0x02000800, 0x00100615, - 0x41300000, 0x598cb80b, 0x41783000, 0x805cb9c0, - 0x0400000f, 0x805c0d80, 0x04000004, 0x405c3000, - 0x5818b800, 0x0401f7fa, 0x0401f835, 0x598c000d, - 0x81300580, 0x02000800, 0x00106e10, 0x497a6007, - 0x80000580, 0x5c00b800, 0x1c01f000, 0x82000540, - 0x00000001, 0x5c00b800, 0x1c01f000, 0x0401fa8d, - 0x4df00000, 0x4d340000, 0x4d300000, 0x4d2c0000, - 0x0201f800, 0x00020267, 0x02020800, 0x00100615, - 0x41783000, 0x598e600b, 0x813261c0, 0x04000014, - 0x59300009, 0x81340580, 0x0402000e, 0x8d3e7d00, - 0x04000003, 0x0401f9aa, 0x0402000a, 0x0401f976, - 0x59300000, 0x4c000000, 0x0401f811, 0x4c180000, - 0x0401f8e9, 0x5c003000, 0x5c026000, 0x0401f7ef, - 0x41303000, 0x59326000, 0x0401f7ec, 0x0201f800, - 0x001045ea, 0x5c025800, 0x5c026000, 0x5c026800, - 0x5c03e000, 0x04000a5d, 0x1c01f000, 0x59300800, - 0x497a6000, 0x0401fa40, 0x801831c0, 0x04020009, - 0x598c000a, 0x81300580, 0x04020004, 0x4803180a, - 0x4803180b, 0x0401f008, 0x4807180b, 0x0401f006, - 0x48043000, 0x598c000a, 0x81300580, 0x04020002, - 0x481b180a, 0x0401f242, 0x0401fa52, 0x4df00000, - 0x4d300000, 0x4c5c0000, 0x4178b800, 0x8d3e7d18, - 0x04000004, 0x8d3e7d16, 0x04020002, 0x805cb800, - 0x598e6005, 0x813261c0, 0x0400001a, 0x59300000, - 0x4c000000, 0x805cb9c0, 0x0402000b, 0x59300c06, - 0x82040580, 0x00000011, 0x04000010, 0x82040580, - 0x00000004, 0x04020004, 0x59300420, 0x8c000500, - 0x0402000a, 0x0201f800, 0x00108f05, 0x02000800, - 0x00107da6, 0x0201f800, 0x001090ec, 0x0201f800, - 0x000208b4, 0x0401fa1e, 0x5c026000, 0x0401f7e6, - 0x497b1805, 0x497b1804, 0x5c00b800, 0x5c026000, - 0x5c03e000, 0x04000a1d, 0x1c01f000, 0x4933c857, - 0x4c5c0000, 0x4c600000, 0x813261c0, 0x02000800, - 0x00100615, 0x41300000, 0x598cb805, 0x405cc000, - 0x805cb9c0, 0x04000025, 0x805c0d80, 0x04000004, - 0x405cc000, 0x5860b800, 0x0401f7fa, 0x598c000d, - 0x81300580, 0x02000800, 0x00106e10, 0x0401f9ee, - 0x598c0005, 0x805c0580, 0x04020009, 0x585c0000, - 0x48031805, 0x4978b800, 0x598c0004, 0x805c0580, - 0x0402000d, 0x497b1804, 0x0401f00b, 0x598c0004, - 0x805c0580, 0x04020005, 0x48631804, 0x4978b800, - 0x4978c000, 0x0401f004, 0x585c0000, 0x4800c000, - 0x4978b800, 0x0401f9ea, 0x80000580, 0x5c00c000, + 0x813261c0, 0x04000021, 0x59300406, 0x82000580, + 0x00000006, 0x04020004, 0x8d3e7d18, 0x0402000a, + 0x0401f017, 0x82040580, 0x00000005, 0x04020006, + 0x8d3e7d16, 0x04000004, 0x59300420, 0x8c000500, + 0x0402000f, 0x0401fa4e, 0x59300000, 0x4c000000, + 0x8d3e7d06, 0x04000004, 0x0201f800, 0x001092d7, + 0x04000005, 0x0401f867, 0x4c180000, 0x0401f9bc, + 0x5c003000, 0x5c026000, 0x0401f7e2, 0x41303000, + 0x59326000, 0x0401f7df, 0x5c026000, 0x5c026800, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x4c5c0000, + 0x813261c0, 0x02000800, 0x001005d8, 0x41300000, + 0x598cb809, 0x41783000, 0x805cb9c0, 0x04000013, + 0x805c0d80, 0x04000004, 0x405c3000, 0x5818b800, + 0x0401f7fa, 0x0401f84b, 0x598c000d, 0x81300580, + 0x02000800, 0x001070b9, 0x59300403, 0x82000580, + 0x00000042, 0x04020002, 0x497a6007, 0x80000580, + 0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001, + 0x5c00b800, 0x1c01f000, 0x0401fb27, 0x4df00000, + 0x4d2c0000, 0x4d340000, 0x4d300000, 0x41783000, + 0x598e6009, 0x813261c0, 0x0400002c, 0x59300c06, + 0x82040580, 0x00000006, 0x04020004, 0x8d3e7d18, + 0x0402000a, 0x0401f022, 0x82040580, 0x00000005, + 0x04020006, 0x8d3e7d18, 0x04000004, 0x59300420, + 0x8c000500, 0x0402001a, 0x59326809, 0x59340403, + 0x81440580, 0x04020016, 0x8d3e7d00, 0x04000006, + 0x82040580, 0x00000003, 0x04020011, 0x0401fa35, + 0x0402000f, 0x0401f9f6, 0x59300000, 0x4c000000, + 0x8d3e7d06, 0x04000004, 0x0201f800, 0x001092d7, + 0x04000005, 0x0401f80f, 0x4c180000, 0x0401f964, + 0x5c003000, 0x5c026000, 0x0401f7d7, 0x41303000, + 0x59326000, 0x0401f7d4, 0x5c026000, 0x5c026800, + 0x5c025800, 0x5c03e000, 0x04000ae5, 0x1c01f000, + 0x59300800, 0x497a6000, 0x0401fac8, 0x801831c0, + 0x04020009, 0x598c0008, 0x81300580, 0x04020004, + 0x48031808, 0x48031809, 0x0401f008, 0x48071809, + 0x0401f006, 0x48043000, 0x598c0008, 0x81300580, + 0x04020002, 0x481b1808, 0x0401f2ca, 0x4d2c0000, + 0x4d300000, 0x4d340000, 0x41783000, 0x598e600b, + 0x813261c0, 0x04000013, 0x8d3e7d06, 0x04000005, + 0x59326809, 0x59340200, 0x8c00050e, 0x0402000a, + 0x0401f9bf, 0x59300000, 0x4c000000, 0x0401f853, + 0x4c180000, 0x0401f932, 0x5c003000, 0x5c026000, + 0x0401f7f0, 0x41303000, 0x59326000, 0x0401f7ed, + 0x0201f800, 0x00104773, 0x5c026800, 0x5c026000, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x4c5c0000, + 0x813261c0, 0x02000800, 0x001005d8, 0x41300000, + 0x598cb80b, 0x41783000, 0x805cb9c0, 0x0400000f, + 0x805c0d80, 0x04000004, 0x405c3000, 0x5818b800, + 0x0401f7fa, 0x0401f835, 0x598c000d, 0x81300580, + 0x02000800, 0x001070b9, 0x497a6007, 0x80000580, 0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001, - 0x5c00c000, 0x5c00b800, 0x1c01f000, 0x4933c857, - 0x0401f9f0, 0x4df00000, 0x4d2c0000, 0x4d340000, - 0x4d300000, 0x4c5c0000, 0x4178b800, 0x8d3e7d18, - 0x04000004, 0x8d3e7d16, 0x04020002, 0x805cb800, - 0x41783000, 0x598e6005, 0x813261c0, 0x04000029, - 0x59326809, 0x813669c0, 0x04000023, 0x59340403, - 0x81440580, 0x04020020, 0x805cb9c0, 0x0402000b, + 0x5c00b800, 0x1c01f000, 0x0401fa9f, 0x4df00000, + 0x4d340000, 0x4d300000, 0x4d2c0000, 0x0201f800, + 0x00020245, 0x02020800, 0x001005d8, 0x41783000, + 0x598e600b, 0x813261c0, 0x04000014, 0x59300009, + 0x81340580, 0x0402000e, 0x8d3e7d00, 0x04000003, + 0x0401f9bc, 0x0402000a, 0x0401f97d, 0x59300000, + 0x4c000000, 0x0401f811, 0x4c180000, 0x0401f8f0, + 0x5c003000, 0x5c026000, 0x0401f7ef, 0x41303000, + 0x59326000, 0x0401f7ec, 0x0201f800, 0x0010479c, + 0x5c025800, 0x5c026000, 0x5c026800, 0x5c03e000, + 0x04000a6f, 0x1c01f000, 0x59300800, 0x497a6000, + 0x0401fa52, 0x801831c0, 0x04020009, 0x598c000a, + 0x81300580, 0x04020004, 0x4803180a, 0x4803180b, + 0x0401f008, 0x4807180b, 0x0401f006, 0x48043000, + 0x598c000a, 0x81300580, 0x04020002, 0x481b180a, + 0x0401f254, 0x0401fa64, 0x4df00000, 0x4d300000, + 0x598e6005, 0x813261c0, 0x04000020, 0x59300000, + 0x4c000000, 0x59300c06, 0x82040580, 0x00000011, + 0x04020007, 0x833c0500, 0x00001800, 0x04000015, + 0x8d3e7d16, 0x04020013, 0x0401f009, 0x82040580, + 0x00000004, 0x04020006, 0x8d3e7d16, 0x04000004, + 0x59300420, 0x8c000500, 0x0402000a, 0x0201f800, + 0x0010914e, 0x02000800, 0x0010801c, 0x0201f800, + 0x00109326, 0x0201f800, 0x0002077d, 0x0401fa31, + 0x5c026000, 0x0401f7e0, 0x497b1805, 0x497b1804, + 0x5c026000, 0x5c03e000, 0x04000a31, 0x1c01f000, + 0x4933c857, 0x4c5c0000, 0x4c600000, 0x813261c0, + 0x02000800, 0x001005d8, 0x41300000, 0x598cb805, + 0x405cc000, 0x805cb9c0, 0x04000025, 0x805c0d80, + 0x04000004, 0x405cc000, 0x5860b800, 0x0401f7fa, + 0x598c000d, 0x81300580, 0x02000800, 0x001070b9, + 0x0401fa02, 0x598c0005, 0x805c0580, 0x04020009, + 0x585c0000, 0x48031805, 0x4978b800, 0x598c0004, + 0x805c0580, 0x0402000d, 0x497b1804, 0x0401f00b, + 0x598c0004, 0x805c0580, 0x04020005, 0x48631804, + 0x4978b800, 0x4978c000, 0x0401f004, 0x585c0000, + 0x4800c000, 0x4978b800, 0x0401f9fe, 0x80000580, + 0x5c00c000, 0x5c00b800, 0x1c01f000, 0x82000540, + 0x00000001, 0x5c00c000, 0x5c00b800, 0x1c01f000, + 0x4933c857, 0x0401fa04, 0x4df00000, 0x4d2c0000, + 0x4d340000, 0x4d300000, 0x4c5c0000, 0x4178b800, + 0x8d3e7d18, 0x0400000d, 0x8d3e7d16, 0x0402000b, + 0x0201f800, 0x00109037, 0x04000008, 0x0201f800, + 0x00109597, 0x04020005, 0x592c0207, 0x492fc857, + 0x8200bd00, 0x0000000f, 0x41783000, 0x598e6005, + 0x813261c0, 0x04000029, 0x59326809, 0x813669c0, + 0x04000023, 0x59340403, 0x81440580, 0x04020020, 0x59300c06, 0x82040580, 0x00000011, 0x0400001a, 0x82040580, 0x00000004, 0x04020004, 0x59300420, - 0x8c000500, 0x04020014, 0x0201f800, 0x00108df4, - 0x04000008, 0x0201f800, 0x00109360, 0x04020005, - 0x59300403, 0x82000580, 0x00000043, 0x0400000a, - 0x0401f8c1, 0x59300000, 0x4c000000, 0x0401f810, - 0x4c180000, 0x0401f834, 0x5c003000, 0x5c026000, - 0x0401f7da, 0x41303000, 0x59326000, 0x0401f7d7, - 0x5c00b800, 0x5c026000, 0x5c026800, 0x5c025800, - 0x5c03e000, 0x040009a9, 0x1c01f000, 0x59300800, - 0x497a6000, 0x0401f98c, 0x801831c0, 0x04020009, - 0x598c0004, 0x81300580, 0x04020004, 0x48031804, - 0x48031805, 0x0401f008, 0x48071805, 0x0401f006, - 0x48043000, 0x598c0004, 0x81300580, 0x04020002, - 0x481b1804, 0x0401f18e, 0x4943c857, 0x0401f99d, - 0x4df00000, 0x0401fe37, 0x0401fed2, 0x5c03e000, - 0x0400098e, 0x1c01f000, 0x4947c857, 0x0401f995, - 0x4df00000, 0x4d3c0000, 0x853e7d00, 0x0401fe7a, - 0x0401ff03, 0x5c027800, 0x5c03e000, 0x04000983, - 0x1c01f000, 0x5c000000, 0x4c000000, 0x4803c857, - 0x4d340000, 0x4d2c0000, 0x59326809, 0x59325808, - 0x59300406, 0x82000c80, 0x00000012, 0x02021800, - 0x00100615, 0x4933c857, 0x4943c857, 0x493fc857, - 0x4803c857, 0x0c01f804, 0x5c025800, 0x5c026800, - 0x1c01f000, 0x00106827, 0x00106829, 0x00106833, - 0x0010684d, 0x00106829, 0x0010683d, 0x00106865, - 0x00106827, 0x00106827, 0x00106878, 0x0010686f, - 0x00106827, 0x00106827, 0x00106827, 0x00106827, - 0x00106827, 0x0010687e, 0x0010687e, 0x0201f800, - 0x00100615, 0x0201f800, 0x00108ef1, 0x02000800, - 0x00101e1b, 0x0201f800, 0x001090ec, 0x0201f800, - 0x00107da6, 0x0201f000, 0x00107698, 0x812e59c0, - 0x02020800, 0x00100615, 0x5930021d, 0x82000580, - 0x00000003, 0x02000800, 0x00108ee7, 0x0201f000, - 0x00107698, 0x0201f800, 0x00108df4, 0x02000000, - 0x00107698, 0x592c1204, 0x82081500, 0x000000ff, - 0x82080580, 0x00000055, 0x02020800, 0x00100615, - 0x49425a06, 0x0201f800, 0x00020381, 0x0201f000, - 0x00107698, 0x59300004, 0x8400055c, 0x48026004, - 0x59300007, 0x8c000500, 0x02020800, 0x00100ee4, - 0x0201f800, 0x00108df4, 0x0400000d, 0x4a025a04, - 0x00000103, 0x49425a06, 0x497a5c09, 0x0201f800, - 0x00108f7d, 0x0201f800, 0x0010a4ae, 0x0201f800, - 0x00020381, 0x0201f800, 0x00108ee7, 0x0201f000, - 0x00107698, 0x59300007, 0x8c000500, 0x02020800, - 0x00100ee4, 0x0201f800, 0x00108df4, 0x02020800, - 0x0010a201, 0x0201f000, 0x00107698, 0x0201f800, - 0x00108df4, 0x04000005, 0x49425a06, 0x497a5c09, - 0x0201f800, 0x00020381, 0x0201f000, 0x00107698, - 0x0201f800, 0x00108df4, 0x02020800, 0x0010639d, - 0x0201f000, 0x00107698, 0x0201f800, 0x00108df4, - 0x04000004, 0x49425a06, 0x0201f800, 0x00020381, - 0x59325817, 0x0201f800, 0x00100843, 0x0201f000, - 0x00107698, 0x598c000d, 0x81300580, 0x04000003, - 0x497a6007, 0x1c01f000, 0x59c40004, 0x82000500, - 0x0000000c, 0x04000005, 0x4a038804, 0x0000000c, - 0x497b2807, 0x0401f00a, 0x0401fadb, 0x59300403, - 0x82000d80, 0x00000040, 0x04000004, 0x82000580, - 0x00000042, 0x04020002, 0x497a6007, 0x0201f800, - 0x00106e10, 0x80000580, 0x1c01f000, 0x59300804, - 0x8c040d20, 0x04020004, 0x82000540, 0x00000001, - 0x1c01f000, 0x4933c857, 0x4d380000, 0x59300804, - 0x84040d20, 0x48066004, 0x42027000, 0x00000049, - 0x59300203, 0x82000580, 0x00000003, 0x04000003, - 0x42027000, 0x00000013, 0x0201f800, 0x000208d8, - 0x80000580, 0x5c027000, 0x1c01f000, 0x59300017, - 0x81480580, 0x04020003, 0x59300018, 0x814c0580, - 0x1c01f000, 0x4d2c0000, 0x4d300000, 0x0401f8c9, - 0x4df00000, 0x0201f800, 0x00105d9b, 0x59900001, - 0x82000500, 0x00000003, 0x0c01f001, 0x001068f1, - 0x001068d1, 0x001068cf, 0x001068cf, 0x0201f800, - 0x00100615, 0x59926004, 0x0401f88e, 0x813261c0, - 0x0400001d, 0x59300004, 0x8c000516, 0x04000004, - 0x59325808, 0x497a5808, 0x497a5809, 0x0401f88e, - 0x59300001, 0x800001c0, 0x0400000e, 0x497a6001, - 0x42003000, 0x0000bf2e, 0x58180801, 0x800409c0, - 0x04020004, 0x48003001, 0x48003000, 0x0401f00a, - 0x58180800, 0x48000800, 0x48003000, 0x0401f006, - 0x59300809, 0x800409c0, 0x02000800, 0x00100615, - 0x4978080c, 0x5c03e000, 0x04000890, 0x5c026000, - 0x5c025800, 0x1c01f000, 0x4d300000, 0x497b2807, - 0x0401f894, 0x4df00000, 0x598c0000, 0x82000500, - 0x00000007, 0x4803c857, 0x0c01f001, 0x00106926, - 0x00106909, 0x00106912, 0x00106916, 0x00106921, - 0x00106926, 0x00106907, 0x00106907, 0x0201f800, - 0x00100615, 0x598c000d, 0x80026540, 0x04000004, - 0x0401f81e, 0x02020800, 0x00100615, 0x0201f800, - 0x00106e10, 0x0401f015, 0x0401f827, 0x0201f800, - 0x00106e10, 0x0401f011, 0x598c000d, 0x80026540, - 0x0400000e, 0x0401f838, 0x04000004, 0x0401f80f, - 0x04000002, 0x0401f81c, 0x0201f800, 0x00106e10, - 0x0401f006, 0x0401f830, 0x02020800, 0x00100615, - 0x0201f800, 0x00106e10, 0x5c03e000, 0x0400085b, - 0x5c026000, 0x1c01f000, 0x598c0009, 0x81300580, - 0x0402000c, 0x0401f84e, 0x0401f83b, 0x59300000, - 0x800001c0, 0x04000004, 0x48031809, 0x497a6000, - 0x0401f003, 0x497b1809, 0x497b1808, 0x80000580, - 0x1c01f000, 0x4d2c0000, 0x59300406, 0x82000580, - 0x00000003, 0x04020012, 0x598c000b, 0x81300580, - 0x0402000f, 0x0401f83a, 0x59325808, 0x497a5808, - 0x497a5809, 0x0401f824, 0x59300000, 0x800001c0, - 0x04000004, 0x4803180b, 0x497a6000, 0x0401f003, - 0x497b180a, 0x497b180b, 0x80000580, 0x5c025800, - 0x1c01f000, 0x598c0005, 0x81300580, 0x0402000c, - 0x0401f827, 0x0401f814, 0x59300000, 0x800001c0, - 0x04000004, 0x48031805, 0x497a6000, 0x0401f003, - 0x497b1805, 0x497b1804, 0x80000580, 0x1c01f000, - 0x4a032001, 0x00000000, 0x497b2004, 0x497b2005, - 0x59900006, 0x82000500, 0x0000ffff, 0x48032006, - 0x1c01f000, 0x4c040000, 0x59300004, 0x82000500, - 0x7ffeffff, 0x48026004, 0x59bc00e4, 0x8c000514, - 0x04000009, 0x42000800, 0x0000bf00, 0x58040012, - 0x81300580, 0x04020004, 0x49780812, 0x4a0378e4, - 0x00000800, 0x5c000800, 0x1c01f000, 0x4803c856, - 0x598c000c, 0x80000540, 0x04000003, 0x80000040, - 0x4803180c, 0x1c01f000, 0x59bc00ea, 0x82000500, - 0x00000007, 0x82000580, 0x00000003, 0x04020004, - 0x4803c856, 0x4a0378e8, 0x00000001, 0x1c01f000, - 0x59bc00ea, 0x82000500, 0x00000007, 0x82000580, - 0x00000001, 0x04020011, 0x4803c856, 0x42000800, - 0x00000000, 0x0401f80e, 0x42000800, 0x00001000, + 0x8c000500, 0x04020016, 0x0201f800, 0x00109037, + 0x04000008, 0x0201f800, 0x00109597, 0x04020005, + 0x59300403, 0x82000580, 0x00000043, 0x0400000c, + 0x0401f8c3, 0x59300000, 0x4c000000, 0x0401f812, + 0x4c180000, 0x0401f836, 0x5c003000, 0x5c026000, + 0x0401f7dc, 0x805cb9c0, 0x040207ec, 0x41303000, + 0x59326000, 0x0401f7d7, 0x5c00b800, 0x5c026000, + 0x5c026800, 0x5c025800, 0x5c03e000, 0x040009b4, + 0x1c01f000, 0x59300800, 0x497a6000, 0x0401f997, + 0x801831c0, 0x04020009, 0x598c0004, 0x81300580, + 0x04020004, 0x48031804, 0x48031805, 0x0401f008, + 0x48071805, 0x0401f006, 0x48043000, 0x598c0004, + 0x81300580, 0x04020002, 0x481b1804, 0x0401f199, + 0x4943c857, 0x0401f9a8, 0x4df00000, 0x0401fe34, + 0x0401fecb, 0x5c03e000, 0x04000999, 0x1c01f000, + 0x4947c857, 0x0401f9a0, 0x4df00000, 0x4d3c0000, + 0x853e7d00, 0x0401fe75, 0x0401fefc, 0x5c027800, + 0x5c03e000, 0x0400098e, 0x1c01f000, 0x5c000000, + 0x4c000000, 0x4803c857, 0x4d340000, 0x4d2c0000, + 0x59326809, 0x59325808, 0x59300406, 0x82000c80, + 0x00000012, 0x02021800, 0x001005d8, 0x4933c857, + 0x4943c857, 0x493fc857, 0x4803c857, 0x0c01f804, + 0x5c025800, 0x5c026800, 0x1c01f000, 0x00106ae5, + 0x00106ae7, 0x00106af1, 0x00106b0b, 0x00106ae7, + 0x00106afb, 0x00106b23, 0x00106ae5, 0x00106ae5, + 0x00106b36, 0x00106b2d, 0x00106ae5, 0x00106ae5, + 0x00106ae5, 0x00106ae5, 0x00106ae5, 0x00106b3c, + 0x00106b3c, 0x0201f800, 0x001005d8, 0x0201f800, + 0x00109134, 0x02000800, 0x00102074, 0x0201f800, + 0x00109326, 0x0201f800, 0x0010801c, 0x0201f000, + 0x00107911, 0x812e59c0, 0x02020800, 0x001005d8, + 0x5930021d, 0x82000580, 0x00000003, 0x02000800, + 0x0010912a, 0x0201f000, 0x00107911, 0x0201f800, + 0x00109037, 0x02000000, 0x00107911, 0x592c1204, + 0x82081500, 0x000000ff, 0x82080580, 0x00000055, + 0x02020800, 0x001005d8, 0x49425a06, 0x0201f800, + 0x000202da, 0x0201f000, 0x00107911, 0x59300004, + 0x8400055c, 0x48026004, 0x59300007, 0x8c000500, + 0x02020800, 0x00100e99, 0x0201f800, 0x00109037, + 0x0400000d, 0x4a025a04, 0x00000103, 0x49425a06, + 0x497a5c09, 0x0201f800, 0x001091c6, 0x0201f800, + 0x0010a693, 0x0201f800, 0x000202da, 0x0201f800, + 0x0010912a, 0x0201f000, 0x00107911, 0x59300007, + 0x8c000500, 0x02020800, 0x00100e99, 0x0201f800, + 0x00109037, 0x02020800, 0x0010a3ef, 0x0201f000, + 0x00107911, 0x0201f800, 0x00109037, 0x04000005, + 0x49425a06, 0x497a5c09, 0x0201f800, 0x000202da, + 0x0201f000, 0x00107911, 0x0201f800, 0x00109037, + 0x02020800, 0x0010664f, 0x0201f000, 0x00107911, + 0x0201f800, 0x00109037, 0x04000004, 0x49425a06, + 0x0201f800, 0x000202da, 0x59325817, 0x0201f800, + 0x001007fd, 0x0201f000, 0x00107911, 0x598c000d, + 0x81300580, 0x04000003, 0x497a6007, 0x1c01f000, + 0x59c40004, 0x82000500, 0x0000000c, 0x04000005, + 0x4a038804, 0x0000000c, 0x497b2807, 0x0401f00a, + 0x0401facd, 0x59300403, 0x82000d80, 0x00000040, + 0x04000004, 0x82000580, 0x00000042, 0x04020002, + 0x497a6007, 0x0201f800, 0x001070b9, 0x80000580, + 0x1c01f000, 0x59300804, 0x8c040d3e, 0x04020004, + 0x82000540, 0x00000001, 0x0401f005, 0x4933c857, + 0x84040d3e, 0x48066004, 0x80000580, 0x1c01f000, + 0x59300804, 0x8c040d20, 0x04020004, 0x82000540, + 0x00000001, 0x1c01f000, 0x4933c857, 0x4d380000, + 0x59300804, 0x84040d20, 0x48066004, 0x42027000, + 0x00000049, 0x59300203, 0x82000580, 0x00000003, + 0x04000003, 0x42027000, 0x00000013, 0x0201f800, + 0x000207a1, 0x80000580, 0x5c027000, 0x1c01f000, + 0x59300017, 0x81480580, 0x04020003, 0x59300018, + 0x814c0580, 0x1c01f000, 0x4d2c0000, 0x4d300000, + 0x0401f8c9, 0x4df00000, 0x0201f800, 0x00106062, + 0x59900001, 0x82000500, 0x00000003, 0x0c01f001, + 0x00106bba, 0x00106b9a, 0x00106b98, 0x00106b98, + 0x0201f800, 0x001005d8, 0x59926004, 0x0401f88e, + 0x813261c0, 0x0400001d, 0x59300004, 0x8c000516, + 0x04000004, 0x59325808, 0x497a5808, 0x497a5809, + 0x0401f88e, 0x59300001, 0x800001c0, 0x0400000e, + 0x497a6001, 0x42003000, 0x0000bf2e, 0x58180801, + 0x800409c0, 0x04020004, 0x48003001, 0x48003000, + 0x0401f00a, 0x58180800, 0x48000800, 0x48003000, + 0x0401f006, 0x59300809, 0x800409c0, 0x02000800, + 0x001005d8, 0x4978080c, 0x5c03e000, 0x04000890, + 0x5c026000, 0x5c025800, 0x1c01f000, 0x4d300000, + 0x497b2807, 0x0401f894, 0x4df00000, 0x598c0000, + 0x82000500, 0x00000007, 0x4803c857, 0x0c01f001, + 0x00106bef, 0x00106bd2, 0x00106bdb, 0x00106bdf, + 0x00106bea, 0x00106bef, 0x00106bd0, 0x00106bd0, + 0x0201f800, 0x001005d8, 0x598c000d, 0x80026540, + 0x04000004, 0x0401f81e, 0x02020800, 0x001005d8, + 0x0201f800, 0x001070b9, 0x0401f015, 0x0401f827, + 0x0201f800, 0x001070b9, 0x0401f011, 0x598c000d, + 0x80026540, 0x0400000e, 0x0401f838, 0x04000004, + 0x0401f80f, 0x04000002, 0x0401f81c, 0x0201f800, + 0x001070b9, 0x0401f006, 0x0401f830, 0x02020800, + 0x001005d8, 0x0201f800, 0x001070b9, 0x5c03e000, + 0x0400085b, 0x5c026000, 0x1c01f000, 0x598c0009, + 0x81300580, 0x0402000c, 0x0401f84e, 0x0401f83b, + 0x59300000, 0x800001c0, 0x04000004, 0x48031809, + 0x497a6000, 0x0401f003, 0x497b1809, 0x497b1808, + 0x80000580, 0x1c01f000, 0x4d2c0000, 0x59300406, + 0x82000580, 0x00000003, 0x04020012, 0x598c000b, + 0x81300580, 0x0402000f, 0x0401f83a, 0x59325808, + 0x497a5808, 0x497a5809, 0x0401f824, 0x59300000, + 0x800001c0, 0x04000004, 0x4803180b, 0x497a6000, + 0x0401f003, 0x497b180a, 0x497b180b, 0x80000580, + 0x5c025800, 0x1c01f000, 0x598c0005, 0x81300580, + 0x0402000c, 0x0401f827, 0x0401f814, 0x59300000, + 0x800001c0, 0x04000004, 0x48031805, 0x497a6000, + 0x0401f003, 0x497b1805, 0x497b1804, 0x80000580, + 0x1c01f000, 0x4a032001, 0x00000000, 0x497b2004, + 0x497b2005, 0x59900006, 0x82000500, 0x0000ffff, + 0x48032006, 0x1c01f000, 0x4c040000, 0x59300004, + 0x82000500, 0x7ffeffff, 0x48026004, 0x59bc00e4, + 0x8c000514, 0x04000009, 0x42000800, 0x0000bf00, + 0x58040012, 0x81300580, 0x04020004, 0x49780812, + 0x4a0378e4, 0x00000800, 0x5c000800, 0x1c01f000, + 0x4803c856, 0x598c000c, 0x80000540, 0x04000003, + 0x80000040, 0x4803180c, 0x1c01f000, 0x59bc00ea, + 0x82000500, 0x00000007, 0x82000580, 0x00000003, + 0x04020004, 0x4803c856, 0x4a0378e8, 0x00000001, + 0x1c01f000, 0x59bc00ea, 0x82000500, 0x00000007, + 0x82000580, 0x00000001, 0x04020011, 0x4803c856, + 0x42000800, 0x00000000, 0x0401f80e, 0x42000800, + 0x00001000, 0x59bc00ea, 0x82000500, 0x00000007, + 0x82000580, 0x00000003, 0x04000005, 0x80040840, + 0x040207f9, 0x0201f800, 0x001005d8, 0x1c01f000, 0x59bc00ea, 0x82000500, 0x00000007, 0x82000580, - 0x00000003, 0x04000005, 0x80040840, 0x040207f9, - 0x0201f800, 0x00100615, 0x1c01f000, 0x59bc00ea, - 0x82000500, 0x00000007, 0x82000580, 0x00000001, - 0x02020800, 0x00100615, 0x59bc00ea, 0x8c000516, - 0x040207fe, 0x480778e1, 0x1c01f000, 0x59bc00ea, - 0x8c000516, 0x040207fe, 0x480778e1, 0x59bc00ea, - 0x8c000516, 0x040207fe, 0x480b78e1, 0x1c01f000, - 0x4a0378e4, 0x00002000, 0x59a8006f, 0x82000500, - 0x0000000c, 0x04020008, 0x42007000, 0x0010b33f, - 0x58380401, 0x8c000506, 0x04020003, 0x4a0378e4, - 0x00080000, 0x1c01f000, 0x82000d00, 0x80000018, - 0x02020800, 0x0010060d, 0x0201f800, 0x00100615, - 0x001069dc, 0x00106a81, 0x00106a9b, 0x001069dc, - 0x001069de, 0x001069ff, 0x00106a1e, 0x00106a53, - 0x001069dc, 0x00106a7f, 0x001069dc, 0x001069dc, - 0x001069dc, 0x001069dc, 0x001069dc, 0x001069dc, - 0x0201f800, 0x00100615, 0x4d300000, 0x4d900000, + 0x00000001, 0x02020800, 0x001005d8, 0x59bc00ea, + 0x8c000516, 0x040207fe, 0x480778e1, 0x1c01f000, + 0x59bc00ea, 0x8c000516, 0x040207fe, 0x480778e1, + 0x59bc00ea, 0x8c000516, 0x040207fe, 0x480b78e1, + 0x1c01f000, 0x82000d00, 0x80000018, 0x02020800, + 0x001005d0, 0x0201f800, 0x001005d8, 0x00106c97, + 0x00106d3b, 0x00106d55, 0x00106c97, 0x00106c99, + 0x00106cba, 0x00106cd9, 0x00106d0d, 0x00106c97, + 0x00106d39, 0x00106c97, 0x00106c97, 0x00106c97, + 0x00106c97, 0x00106c97, 0x00106c97, 0x0201f800, + 0x001005d8, 0x4d300000, 0x4d900000, 0x4dd00000, + 0x4da40000, 0x4d140000, 0x0201f800, 0x001070d8, + 0x59bc00ea, 0x8c000510, 0x040007fe, 0x59be60e0, + 0x59300004, 0x8c000520, 0x04000011, 0x82000500, + 0xfffefeff, 0x48026004, 0x4a026203, 0x00000003, + 0x0401ffa9, 0x0201f800, 0x00100fd0, 0x5c022800, + 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c026000, + 0x4a0378e4, 0x00000008, 0x0401f795, 0x84000510, + 0x48026004, 0x0401f7f6, 0x4d300000, 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, 0x0201f800, - 0x00106e2f, 0x59bc00ea, 0x8c000510, 0x040007fe, - 0x59be60e0, 0x59300004, 0x8c000520, 0x04000011, - 0x82000500, 0xfffefeff, 0x48026004, 0x4a026203, - 0x00000003, 0x0401ff9b, 0x0201f800, 0x0010101e, + 0x001070d8, 0x59bc00ea, 0x8c000510, 0x040007fe, + 0x59be60e0, 0x59300004, 0x8c000520, 0x0400000f, + 0x82000500, 0xfffefeff, 0x48026004, 0x0401ff8a, + 0x0201f800, 0x0010100e, 0x5c022800, 0x5c034800, + 0x5c03a000, 0x5c032000, 0x5c026000, 0x4a0378e4, + 0x00000008, 0x0401f776, 0x84000510, 0x48026004, + 0x0401f7f6, 0x4d300000, 0x4d2c0000, 0x4d340000, + 0x4da40000, 0x4cd00000, 0x59bc00ea, 0x8c000510, + 0x040007fe, 0x59be60e0, 0x813261c0, 0x02000800, + 0x001005d8, 0x59300004, 0x8c000520, 0x0400001d, + 0x82000500, 0xfffefeff, 0x48026004, 0x59326809, + 0x42034800, 0x0010b544, 0x04011000, 0x4a03c840, + 0x0010b54b, 0x4a03c842, 0x00000012, 0x04011000, + 0x4a03c840, 0x0010b55d, 0x4a03c842, 0x000000ff, + 0x04011000, 0x4a03c840, 0x0010b65c, 0x4a03c842, + 0x000000ff, 0x0401fbf2, 0x5c01a000, 0x5c034800, + 0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000, + 0x84000510, 0x48026004, 0x5c01a000, 0x5c034800, + 0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000, + 0x1c01f000, 0x4d300000, 0x4d2c0000, 0x4d340000, + 0x4cd00000, 0x4d900000, 0x4dd00000, 0x4da40000, + 0x4d140000, 0x0401fbc3, 0x59bc00ea, 0x8c000510, + 0x040007fe, 0x59be60e0, 0x813261c0, 0x02000800, + 0x001005d8, 0x59300004, 0x8c000520, 0x0400000f, + 0x82000500, 0xfffefeff, 0x48026004, 0x0201f800, + 0x0010783a, 0x5c022800, 0x5c034800, 0x5c03a000, + 0x5c032000, 0x5c01a000, 0x5c026800, 0x5c025800, + 0x5c026000, 0x1c01f000, 0x84000510, 0x48026004, 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, - 0x5c026000, 0x4a0378e4, 0x00000008, 0x0401f787, - 0x84000510, 0x48026004, 0x0401f7f6, 0x4d300000, + 0x5c01a000, 0x5c026800, 0x5c025800, 0x5c026000, + 0x1c01f000, 0x0201f800, 0x001005d8, 0x4d300000, + 0x4d380000, 0x42000000, 0x0010b8c4, 0x0201f800, + 0x0010aa47, 0x0401ff14, 0x598e600d, 0x59c40004, + 0x8c000506, 0x04000004, 0x0401f8db, 0x4a038804, + 0x00000008, 0x813261c0, 0x04000006, 0x0401fb87, + 0x42027000, 0x00000014, 0x0201f800, 0x000207a1, + 0x4a0378e4, 0x00000002, 0x5c027000, 0x5c026000, + 0x0401f6f7, 0x4d180000, 0x4d300000, 0x4d380000, 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, - 0x0201f800, 0x00106e2f, 0x59bc00ea, 0x8c000510, - 0x040007fe, 0x59be60e0, 0x59300004, 0x8c000520, - 0x0400000f, 0x82000500, 0xfffefeff, 0x48026004, - 0x0401ff7c, 0x0201f800, 0x0010105c, 0x5c022800, - 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c026000, - 0x4a0378e4, 0x00000008, 0x0401f768, 0x84000510, - 0x48026004, 0x0401f7f6, 0x4d300000, 0x4d2c0000, - 0x4d340000, 0x4da40000, 0x4cd00000, 0x59bc00ea, - 0x8c000510, 0x040007fe, 0x59be60e0, 0x813261c0, - 0x02000800, 0x00100615, 0x59300004, 0x8c000520, - 0x0400001e, 0x82000500, 0xfffefeff, 0x48026004, - 0x59326809, 0x42034800, 0x0010b342, 0x04011000, - 0x4a03c840, 0x0010b349, 0x4a03c842, 0x00000012, - 0x04011000, 0x4a03c840, 0x0010b35b, 0x4a03c842, - 0x000000ff, 0x04011000, 0x4a03c840, 0x0010b45a, - 0x4a03c842, 0x000000ff, 0x0201f800, 0x00106e46, - 0x5c01a000, 0x5c034800, 0x5c026800, 0x5c025800, - 0x5c026000, 0x1c01f000, 0x84000510, 0x48026004, - 0x5c01a000, 0x5c034800, 0x5c026800, 0x5c025800, - 0x5c026000, 0x1c01f000, 0x1c01f000, 0x4d300000, - 0x4d2c0000, 0x4d340000, 0x4cd00000, 0x4d900000, - 0x4dd00000, 0x4da40000, 0x4d140000, 0x0401fbd4, - 0x59bc00ea, 0x8c000510, 0x040007fe, 0x59be60e0, - 0x813261c0, 0x02000800, 0x00100615, 0x59300004, - 0x8c000520, 0x0400000f, 0x82000500, 0xfffefeff, - 0x48026004, 0x0201f800, 0x001075b9, 0x5c022800, - 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c01a000, - 0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000, - 0x84000510, 0x48026004, 0x5c022800, 0x5c034800, - 0x5c03a000, 0x5c032000, 0x5c01a000, 0x5c026800, - 0x5c025800, 0x5c026000, 0x1c01f000, 0x0201f800, - 0x00100615, 0x4d300000, 0x4d380000, 0x42000000, - 0x0010b6c3, 0x0201f800, 0x0010a86e, 0x0401ff05, - 0x598e600d, 0x59c40004, 0x8c000506, 0x04000004, - 0x0401f8e5, 0x4a038804, 0x00000008, 0x813261c0, - 0x04000006, 0x0401fb98, 0x42027000, 0x00000014, - 0x0201f800, 0x000208d8, 0x4a0378e4, 0x00000002, - 0x5c027000, 0x5c026000, 0x0401f6e8, 0x4d180000, - 0x4d300000, 0x4d380000, 0x4d900000, 0x4dd00000, - 0x4da40000, 0x4d140000, 0x0401feea, 0x417a3000, - 0x59c40804, 0x83180400, 0x00106df6, 0x50000000, - 0x80040500, 0x0400001b, 0x42000000, 0x0010b6c4, - 0x0201f800, 0x0010a86e, 0x0401fb81, 0x59926004, - 0x0401f863, 0x83180400, 0x00106df6, 0x50000000, - 0x48038804, 0x813261c0, 0x0400000a, 0x59300004, - 0x8c00050c, 0x04020003, 0x4a026203, 0x00000003, - 0x42027000, 0x0000004a, 0x0201f800, 0x000208d8, - 0x59c40004, 0x82000500, 0x00f80000, 0x04000005, - 0x811a3000, 0x83180480, 0x00000005, 0x040017dd, - 0x4a0378e4, 0x00000008, 0x5c022800, 0x5c034800, - 0x5c03a000, 0x5c032000, 0x5c027000, 0x5c026000, - 0x5c023000, 0x0401f6b1, 0x4d2c0000, 0x4d340000, - 0x59326809, 0x598c0800, 0x82040580, 0x00000004, - 0x04020006, 0x838c1400, 0x00000005, 0x838c1c00, - 0x00000004, 0x0401f010, 0x82040580, 0x00000001, - 0x04020006, 0x838c1400, 0x00000009, 0x838c1c00, - 0x00000008, 0x0401f008, 0x82040580, 0x00000002, - 0x04020028, 0x838c1400, 0x0000000b, 0x838c1c00, - 0x0000000a, 0x41306800, 0x58340000, 0x80007d40, - 0x04000020, 0x583c0009, 0x81340580, 0x04020006, + 0x0401fef9, 0x417a3000, 0x59c40804, 0x83180400, + 0x0010709f, 0x50000000, 0x80040500, 0x0400001b, + 0x42000000, 0x0010b8c5, 0x0201f800, 0x0010aa47, + 0x0401fb70, 0x59926004, 0x0401f859, 0x83180400, + 0x0010709f, 0x50000000, 0x48038804, 0x813261c0, + 0x0400000a, 0x59300004, 0x8c00050c, 0x04020003, + 0x4a026203, 0x00000003, 0x42027000, 0x0000004a, + 0x0201f800, 0x000207a1, 0x59c40004, 0x82000500, + 0x00f80000, 0x04000005, 0x811a3000, 0x83180480, + 0x00000005, 0x040017dd, 0x4a0378e4, 0x00000008, + 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, + 0x5c027000, 0x5c026000, 0x5c023000, 0x0401f6c0, + 0x4d2c0000, 0x4d340000, 0x59326809, 0x598c0800, + 0x82040580, 0x00000004, 0x04020004, 0x838c1400, + 0x00000005, 0x0401f00c, 0x82040580, 0x00000001, + 0x04020004, 0x838c1400, 0x00000009, 0x0401f006, + 0x82040580, 0x00000002, 0x04020022, 0x838c1400, + 0x0000000b, 0x41306800, 0x58340000, 0x80007d40, + 0x0400001c, 0x583c0009, 0x81340580, 0x04020006, 0x403c6800, 0x583c0000, 0x80007d40, 0x040207fa, - 0x0401f018, 0x4933c857, 0x483fc857, 0x583c0000, - 0x48006800, 0x49307800, 0x443c1000, 0x500c0000, - 0x803c0580, 0x04020002, 0x44341800, 0x80000580, + 0x0401f014, 0x4933c857, 0x483fc857, 0x583c0000, + 0x48006800, 0x49307800, 0x443c1000, 0x80000580, 0x4803180d, 0x4803180f, 0x598c0000, 0x82000580, 0x00000003, 0x04000003, 0x4a031800, 0x00000000, 0x80000580, 0x5c026800, 0x5c025800, 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fb, 0x491bc857, 0x59c80840, 0x82040540, 0x00000010, 0x48039040, 0x59c41008, 0x82080500, 0xffffff7f, 0x48038808, - 0x4c040000, 0x4c080000, 0x0401fac2, 0x04020007, - 0x0401fac6, 0x04000022, 0x48038804, 0x0201f800, - 0x001010ca, 0x0401f042, 0x4a038803, 0x00000008, + 0x4c040000, 0x4c080000, 0x0401fabb, 0x04020007, + 0x0401fabf, 0x04000022, 0x48038804, 0x0201f800, + 0x0010107a, 0x0401f042, 0x4a038803, 0x00000008, 0x59c40003, 0x82000500, 0x00000003, 0x040007fd, - 0x8c000502, 0x04020007, 0x0401fab8, 0x04000014, - 0x48038804, 0x0201f800, 0x001010ca, 0x0401f034, + 0x8c000502, 0x04020007, 0x0401fab1, 0x04000014, + 0x48038804, 0x0201f800, 0x0010107a, 0x0401f034, 0x59c80040, 0x8400056a, 0x48039040, 0x59c80040, 0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500, 0xc0000000, 0x04000006, 0x59c400a3, 0x84000540, 0x480388a3, 0x4a038805, 0xc0000000, 0x0201f800, - 0x0010106b, 0x4a03a005, 0x30000000, 0x59d00006, + 0x0010101d, 0x4a03a005, 0x30000000, 0x59d00006, 0x4a03a005, 0x30000000, 0x59900006, 0x82000500, 0xffff0000, 0x48032006, 0x59d00005, 0x8c000504, 0x040207fe, 0x42000800, 0x00007600, 0x83180540, 0x60000000, 0x480008a1, 0x811800dc, 0x59c80840, 0x80040540, 0x48039040, 0x82000540, 0x00003000, 0x48039040, 0x59c80040, 0x82000500, 0x00003000, - 0x040207fd, 0x0201f800, 0x001010b8, 0x83180400, - 0x00106df6, 0x50000000, 0x48038804, 0x80000580, - 0x4df00000, 0x0201f800, 0x00105d9b, 0x5c03e000, + 0x040207fd, 0x0201f800, 0x00101068, 0x83180400, + 0x0010709f, 0x50000000, 0x48038804, 0x80000580, + 0x4df00000, 0x0201f800, 0x00106062, 0x5c03e000, 0x5c001000, 0x5c000800, 0x480b8808, 0x48079040, 0x1c01f000, 0x4803c856, 0x59c80840, 0x82040540, 0x00000010, 0x48039040, 0x59c41008, 0x82080500, @@ -6931,297 +7103,287 @@ uint32_t risc_code01[] = { 0xc0000000, 0x04000007, 0x59c400a3, 0x84000540, 0x480388a3, 0x4a038805, 0xc0000000, 0x80000580, 0x497b2807, 0x5c001000, 0x5c000800, 0x480b8808, - 0x48079040, 0x1c01f000, 0x5c000000, 0x4c000000, - 0x4803c857, 0x491bc857, 0x4933c857, 0x4d900000, - 0x4dd00000, 0x4da40000, 0x4d140000, 0x0401fdd1, - 0x4df00000, 0x0401fa72, 0x59900004, 0x800001c0, + 0x48079040, 0x1c01f000, 0x4933c857, 0x4d900000, + 0x4dd00000, 0x4da40000, 0x4d140000, 0x0401fdee, + 0x4df00000, 0x0401fa6f, 0x59900004, 0x800001c0, 0x04000011, 0x81300580, 0x0402000f, 0x59300004, - 0x84000520, 0x48026004, 0x0401ff4d, 0x04020009, - 0x5c03e000, 0x04000db9, 0x80000580, 0x5c022800, + 0x84000520, 0x48026004, 0x0401ff51, 0x04020009, + 0x5c03e000, 0x04000dd6, 0x80000580, 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, 0x1c01f000, - 0x0401fcf1, 0x42027000, 0x00000049, 0x59300004, + 0x0401fd0e, 0x42027000, 0x00000049, 0x59300004, 0x84000520, 0x48026004, 0x8c00050c, 0x02020800, - 0x000208d8, 0x5c03e000, 0x04000da8, 0x82000540, + 0x000207a1, 0x5c03e000, 0x04000dc5, 0x82000540, 0x00000001, 0x5c022800, 0x5c034800, 0x5c03a000, - 0x5c032000, 0x1c01f000, 0x4933c857, 0x0401fda9, + 0x5c032000, 0x1c01f000, 0x4933c857, 0x0401fdc6, 0x4df00000, 0x598c000d, 0x80026540, 0x04000012, - 0x59300004, 0x84000520, 0x48026004, 0x0401ff86, - 0x04000017, 0x0401fd09, 0x42027000, 0x00000013, - 0x59300004, 0x8c00050c, 0x02020800, 0x000208d8, - 0x5c03e000, 0x04000d8d, 0x82000540, 0x00000001, + 0x59300004, 0x84000520, 0x48026004, 0x0401ff8a, + 0x04000017, 0x0401fd26, 0x42027000, 0x00000013, + 0x59300004, 0x8c00050c, 0x02020800, 0x000207a1, + 0x5c03e000, 0x04000daa, 0x82000540, 0x00000001, 0x1c01f000, 0x836c1580, 0x00000001, 0x040007f9, 0x836c1580, 0x00000004, 0x040007f6, 0x42001000, - 0x00103f62, 0x0201f800, 0x00105cc9, 0x5c03e000, - 0x04000d7e, 0x80000580, 0x1c01f000, 0x4d300000, - 0x4d180000, 0x4d3c0000, 0x0401fd82, 0x4df00000, - 0x4a0378e4, 0x0000000f, 0x0401fa02, 0x417a3000, + 0x00104148, 0x0201f800, 0x00105f90, 0x5c03e000, + 0x04000d9b, 0x80000580, 0x1c01f000, 0x4d300000, + 0x4d180000, 0x4d3c0000, 0x0401fd9f, 0x4df00000, + 0x4a0378e4, 0x0000000f, 0x0401f9ff, 0x417a3000, 0x59926004, 0x813261c0, 0x04000010, 0x417a7800, - 0x0201f800, 0x00104728, 0x0400000a, 0x59300c06, + 0x0201f800, 0x001048d9, 0x0400000a, 0x59300c06, 0x82040580, 0x00000003, 0x04000004, 0x82040580, 0x00000006, 0x04020003, 0x42027800, 0x00000002, - 0x0201f800, 0x00108997, 0x811a3000, 0x83180480, + 0x0201f800, 0x00108be3, 0x811a3000, 0x83180480, 0x00000005, 0x040017eb, 0x42000800, 0x00000040, - 0x0201f800, 0x00101395, 0x4a0378e4, 0x0000000a, - 0x5c03e000, 0x04000d55, 0x5c027800, 0x5c023000, + 0x0201f800, 0x00101345, 0x4a0378e4, 0x0000000a, + 0x5c03e000, 0x04000d72, 0x5c027800, 0x5c023000, 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, - 0x0401fd58, 0x4df00000, 0x59c80840, 0x82040540, + 0x0401fd75, 0x4df00000, 0x59c80840, 0x82040540, 0x00000010, 0x48039040, 0x59c41008, 0x82080500, 0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000, - 0x42001000, 0x00000003, 0x0401f9c5, 0x598e600d, - 0x813261c0, 0x04020f9d, 0x040009ca, 0x497b2807, + 0x42001000, 0x00000003, 0x0401f9c2, 0x598e600d, + 0x813261c0, 0x04020f9d, 0x040009c7, 0x497b2807, 0x0401f80a, 0x5c001000, 0x5c000800, 0x480b8808, - 0x84040d74, 0x48079040, 0x5c03e000, 0x04000d33, + 0x84040d74, 0x48079040, 0x5c03e000, 0x04000d50, 0x5c026000, 0x1c01f000, 0x4d380000, 0x4d180000, 0x4d300000, 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, 0x59c41004, 0x480bc857, 0x82080500, 0x00003ff0, 0x04000025, 0x417a3000, 0x4c080000, - 0x0201f800, 0x00105d9b, 0x5c001000, 0x82080500, + 0x0201f800, 0x00106062, 0x5c001000, 0x82080500, 0x00000210, 0x04020004, 0x811a3000, 0x80081102, - 0x0401f7f7, 0x0401f9c6, 0x59926004, 0x4933c857, + 0x0401f7f7, 0x0401f9c3, 0x59926004, 0x4933c857, 0x813261c0, 0x04020005, 0x59c400a3, 0x8c00051a, - 0x02000800, 0x00100615, 0x0401fea1, 0x04000009, - 0x0401fc4d, 0x42027000, 0x00000049, 0x59300004, - 0x8c00050c, 0x02020800, 0x000208d8, 0x0401f007, + 0x02000800, 0x001005d8, 0x0401fea5, 0x04000009, + 0x0401fc6a, 0x42027000, 0x00000049, 0x59300004, + 0x8c00050c, 0x02020800, 0x000207a1, 0x0401f007, 0x42027000, 0x0000004a, 0x4a026203, 0x00000003, - 0x0201f800, 0x000208d8, 0x5c022800, 0x5c034800, + 0x0201f800, 0x000207a1, 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c026000, 0x5c023000, 0x5c027000, 0x1c01f000, 0x4d300000, 0x4d180000, - 0x4d900000, 0x0401fcff, 0x42001000, 0x00000000, - 0x598c0000, 0x82000580, 0x00000005, 0x04000974, + 0x4d900000, 0x0401fd1c, 0x42001000, 0x00000000, + 0x598c0000, 0x82000580, 0x00000005, 0x04000971, 0x417a3000, 0x811b20c8, 0x83932400, 0x0000bf32, 0x59900001, 0x82000580, 0x00000001, 0x0402000d, 0x42000800, 0x000007d0, 0x59926004, 0x59300011, 0x82000500, 0xfff00000, 0x80000540, 0x04000003, - 0x42000800, 0x00001b58, 0x0201f800, 0x00105d8d, + 0x42000800, 0x00001b58, 0x0201f800, 0x00106054, 0x811a3000, 0x83180480, 0x00000005, 0x040017ea, - 0x59c81040, 0x84081534, 0x480b9040, 0x0401fcd3, + 0x59c81040, 0x84081534, 0x480b9040, 0x0401fcf0, 0x5c032000, 0x5c023000, 0x5c026000, 0x1c01f000, 0x4933c857, 0x4d900000, 0x4dd00000, 0x4da40000, - 0x4d140000, 0x4d380000, 0x0401fcd2, 0x4df00000, + 0x4d140000, 0x4d380000, 0x0401fcef, 0x4df00000, 0x59300004, 0x8c00053e, 0x04020007, 0x8c000520, - 0x04000026, 0x0201f800, 0x001068a3, 0x04000023, - 0x0401f02b, 0x598c000d, 0x81300580, 0x04000012, - 0x0201f800, 0x00108a8a, 0x04020025, 0x0401f91b, - 0x04000023, 0x48038804, 0x0401f961, 0x0201f800, - 0x001010ca, 0x0201f800, 0x001068c1, 0x42027000, - 0x00000049, 0x59300004, 0x8c00050c, 0x0402000d, - 0x0401f00e, 0x59c40004, 0x8c000504, 0x04000014, - 0x4a038804, 0x00000004, 0x0401fc18, 0x42027000, - 0x00000013, 0x59300004, 0x8c00050c, 0x04000003, - 0x0201f800, 0x000208d8, 0x5c03e000, 0x04000c9b, + 0x04000025, 0x0201f800, 0x00106b6c, 0x04000022, + 0x0401f02a, 0x598c000d, 0x81300580, 0x04000011, + 0x0201f800, 0x00108cd6, 0x04020024, 0x0401f918, + 0x04000022, 0x48038804, 0x0401f95e, 0x0201f800, + 0x0010107a, 0x0401fc0d, 0x42027000, 0x00000049, + 0x59300004, 0x8c00050c, 0x0402000d, 0x0401f00e, + 0x59c40004, 0x8c000504, 0x04000014, 0x4a038804, + 0x00000004, 0x0401fc36, 0x42027000, 0x00000013, + 0x59300004, 0x8c00050c, 0x04000003, 0x0201f800, + 0x000207a1, 0x5c03e000, 0x04000cb9, 0x5c027000, + 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, + 0x80000580, 0x1c01f000, 0x5c03e000, 0x04000cb0, 0x5c027000, 0x5c022800, 0x5c034800, 0x5c03a000, - 0x5c032000, 0x80000580, 0x1c01f000, 0x5c03e000, - 0x04000c92, 0x5c027000, 0x5c022800, 0x5c034800, - 0x5c03a000, 0x5c032000, 0x82000540, 0x00000001, - 0x1c01f000, 0x497b2807, 0x0401fc92, 0x59c400af, - 0x800001c0, 0x04020004, 0x0401fc84, 0x0201f000, - 0x00101565, 0x598c000f, 0x82001480, 0x00000002, - 0x04021007, 0x80000000, 0x4803180f, 0x80000580, - 0x0201f800, 0x00105d86, 0x0400000e, 0x0401fed7, - 0x0402000c, 0x0401fdc5, 0x0400000a, 0x0201f800, - 0x0010a7ee, 0x0401f918, 0x4d380000, 0x42027000, - 0x00000014, 0x0201f800, 0x000208d8, 0x5c027000, - 0x0401fc6a, 0x0201f000, 0x00101565, 0x4d900000, - 0x4dd00000, 0x4da40000, 0x4d140000, 0x4d300000, - 0x0201f800, 0x00105d9b, 0x0401fc6a, 0x59c400af, - 0x800001c0, 0x04000027, 0x0401f909, 0x59926004, - 0x4933c857, 0x59300004, 0x8c000516, 0x0400000b, - 0x0401fe86, 0x0402001f, 0x0201f800, 0x001068c1, - 0x0401fc52, 0x42000800, 0x80000804, 0x0201f800, - 0x00106466, 0x0401f017, 0x42001800, 0x00007530, - 0x0401f8c3, 0x04020004, 0x0201f800, 0x00105d8b, - 0x0401f010, 0x0401fe75, 0x0402000e, 0x0201f800, - 0x0010a7ee, 0x59300004, 0x8c00050c, 0x04020003, - 0x4a026203, 0x00000003, 0x4d380000, 0x42027000, - 0x0000004a, 0x0201f800, 0x000208d8, 0x5c027000, - 0x0401fc36, 0x5c026000, 0x5c022800, 0x5c034800, - 0x5c03a000, 0x5c032000, 0x0201f000, 0x00101565, - 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, - 0x4d300000, 0x4d2c0000, 0x0401fc32, 0x0401f8d4, - 0x59926004, 0x4933c857, 0x0401f882, 0x04000016, - 0x0201f800, 0x00105d9b, 0x813261c0, 0x04000034, - 0x59325808, 0x812e59c0, 0x02000800, 0x00100615, - 0x0201f800, 0x00104e0d, 0x0402001d, 0x592c0208, - 0x84000550, 0x48025a08, 0x0201f800, 0x00104f29, - 0x04020027, 0x592c0208, 0x84000510, 0x48025a08, - 0x0401f023, 0x0201f800, 0x00105d8b, 0x0401f020, - 0x0201f800, 0x0010a7ee, 0x0401fd99, 0x592c0208, - 0x84000550, 0x48025a08, 0x4d380000, 0x42027000, - 0x0000004a, 0x4a026203, 0x00000003, 0x0201f800, - 0x000208d8, 0x5c027000, 0x0401f011, 0x59900006, - 0x82000500, 0xffff0000, 0x040207ee, 0x59c408af, - 0x82040480, 0x000003e8, 0x040217ea, 0x59900006, - 0x82000400, 0x00010000, 0x48032006, 0x0201f800, - 0x00105d8b, 0x0201f800, 0x00103f37, 0x5c025800, + 0x5c032000, 0x82000540, 0x00000001, 0x1c01f000, + 0x497b2807, 0x0401fcb0, 0x59c400af, 0x800001c0, + 0x04020004, 0x0401fca2, 0x0201f000, 0x001014fb, + 0x598c000f, 0x82001480, 0x00000002, 0x04021007, + 0x80000000, 0x4803180f, 0x80000580, 0x0201f800, + 0x0010604d, 0x0400000e, 0x0401fed8, 0x0402000c, + 0x0401fdd4, 0x0400000a, 0x0201f800, 0x0010a9c7, + 0x0401f916, 0x4d380000, 0x42027000, 0x00000014, + 0x0201f800, 0x000207a1, 0x5c027000, 0x0401fc88, + 0x0201f000, 0x001014fb, 0x4d900000, 0x4dd00000, + 0x4da40000, 0x4d140000, 0x4d300000, 0x0201f800, + 0x00106062, 0x0401fc88, 0x59c400af, 0x800001c0, + 0x04000027, 0x0401f907, 0x59926004, 0x4933c857, + 0x59300004, 0x8c000516, 0x0400000b, 0x0401fe8b, + 0x0402001f, 0x0201f800, 0x00106b8a, 0x0401fc70, + 0x42000800, 0x80000804, 0x0201f800, 0x00106721, + 0x0401f017, 0x42001800, 0x00007530, 0x0401f8c1, + 0x04020004, 0x0201f800, 0x00106052, 0x0401f010, + 0x0401fe7a, 0x0402000e, 0x0201f800, 0x0010a9c7, + 0x59300004, 0x8c00050c, 0x04020003, 0x4a026203, + 0x00000003, 0x4d380000, 0x42027000, 0x0000004a, + 0x0201f800, 0x000207a1, 0x5c027000, 0x0401fc54, 0x5c026000, 0x5c022800, 0x5c034800, 0x5c03a000, - 0x5c032000, 0x0201f000, 0x00106982, 0x4d300000, - 0x4d2c0000, 0x0201f800, 0x0010698c, 0x598e600d, - 0x4933c857, 0x59c41004, 0x8c081500, 0x04000007, - 0x0201f800, 0x00104e0d, 0x04020007, 0x0201f800, - 0x00104f29, 0x0402002f, 0x0201f800, 0x00105d86, - 0x0401f02c, 0x598c000f, 0x80000540, 0x04020011, - 0x59c408af, 0x82040480, 0x000003e8, 0x0402100d, - 0x598c080f, 0x80040800, 0x4807180f, 0x0201f800, - 0x00105d86, 0x42000000, 0x0010b650, 0x0201f800, - 0x0010a86e, 0x0201f800, 0x00103f37, 0x0401f019, - 0x0401fdad, 0x813261c0, 0x04020003, 0x0401f849, - 0x0401f014, 0x0201f800, 0x0010a7ee, 0x59300406, - 0x82000580, 0x00000003, 0x04020007, 0x59325808, - 0x812e59c0, 0x04000004, 0x592c0208, 0x84000550, - 0x48025a08, 0x0401f854, 0x4d380000, 0x42027000, - 0x00000014, 0x0201f800, 0x000208d8, 0x5c027000, - 0x5c025800, 0x5c026000, 0x0201f000, 0x00106982, - 0x59c40804, 0x83180400, 0x00106dec, 0x50000000, - 0x80040500, 0x1c01f000, 0x59c40804, 0x83180400, - 0x00106df1, 0x50000000, 0x80040500, 0x1c01f000, - 0x00000210, 0x00000420, 0x00000840, 0x00001080, - 0x00002100, 0x00004000, 0x00008000, 0x00010000, - 0x00020000, 0x00040000, 0x00080000, 0x00100000, - 0x00200000, 0x00400000, 0x00800000, 0x59900806, - 0x80040120, 0x800c0480, 0x04021004, 0x82000540, - 0x00000001, 0x0401f005, 0x82040c00, 0x00010000, - 0x48072006, 0x80000580, 0x1c01f000, 0x480bc857, - 0x0201f800, 0x0010698c, 0x4df00000, 0x480b1800, - 0x5c03e000, 0x02000800, 0x00106982, 0x1c01f000, - 0x4803c856, 0x0201f800, 0x0010698c, 0x4df00000, - 0x497b180d, 0x497b1803, 0x497b180e, 0x497b180f, - 0x497b1810, 0x598c0000, 0x82000580, 0x00000003, - 0x04000009, 0x836c0580, 0x00000002, 0x04020004, - 0x4a031800, 0x00000005, 0x0401f003, 0x4a031800, - 0x00000000, 0x5c03e000, 0x02000800, 0x00106982, - 0x1c01f000, 0x59300004, 0x8c00050c, 0x04020003, - 0x4a026203, 0x00000001, 0x1c01f000, 0x83180480, - 0x00000005, 0x02021800, 0x00100615, 0x491bc857, - 0x811b20c8, 0x83932400, 0x0000bf32, 0x811ba0ca, - 0x83d3a400, 0x00007600, 0x83180400, 0x00106e41, - 0x50034800, 0x811a28c2, 0x83162c00, 0x00006100, - 0x1c01f000, 0x0010b559, 0x0010b570, 0x0010b587, - 0x0010b59e, 0x0010b5b5, 0x4933c857, 0x59300406, - 0x82000c80, 0x00000012, 0x04021016, 0x4803c857, - 0x04011000, 0x0c01f001, 0x00106e60, 0x00106f03, - 0x00107249, 0x001072cf, 0x00106f03, 0x00107249, - 0x001072cf, 0x00106e60, 0x00106f03, 0x00106e60, - 0x00106e60, 0x00106e60, 0x00106e60, 0x00106e60, - 0x00106e60, 0x00106e60, 0x00106e66, 0x00106e66, - 0x0201f800, 0x0010698c, 0x0201f800, 0x001068f6, - 0x0201f000, 0x00106982, 0x42001000, 0x0010b5f4, - 0x50081000, 0x4930100c, 0x58080002, 0x82000580, - 0x00000100, 0x0402003e, 0x59325808, 0x812e59c0, - 0x02000800, 0x00100615, 0x59326809, 0x813669c0, - 0x04000025, 0x592c040b, 0x82000500, 0x0000e000, - 0x04000003, 0x0401fbc9, 0x0401f002, 0x0401fbb9, - 0x592c000d, 0x82000500, 0x00000003, 0x04000007, - 0x82000580, 0x00000003, 0x80000000, 0x58d00802, - 0x80040540, 0x4801a002, 0x42001000, 0x0010b5f4, - 0x50081000, 0x4930100b, 0x492c100a, 0x82d00400, - 0x00000006, 0x48001003, 0x592c000d, 0x82000400, - 0x00000003, 0x80000104, 0x48001004, 0x592c000e, - 0x48001007, 0x592c000f, 0x48001008, 0x0201f000, - 0x001008a1, 0x42026800, 0x0010bc0c, 0x592c080a, - 0x48066802, 0x82040500, 0x00ffff00, 0x04000007, - 0x497a6a12, 0x59a81010, 0x82081500, 0x00ffff00, - 0x80080580, 0x040207d0, 0x82040d00, 0x000000ff, - 0x800408d0, 0x48066a12, 0x0401f7cb, 0x1c01f000, - 0x4d2c0000, 0x4d300000, 0x4c580000, 0x4c540000, - 0x4c500000, 0x5832580a, 0x812e59c0, 0x02000800, - 0x00100615, 0x58300002, 0x4a006002, 0x00000100, - 0x82000580, 0x00000100, 0x04020020, 0x5830000b, - 0x5832600c, 0x81300580, 0x04020012, 0x0401f82f, - 0x04020014, 0x592c080d, 0x82040c00, 0x00000003, - 0x80040904, 0x4004b000, 0x4200a000, 0x0010b349, - 0x4050a800, 0x0201f800, 0x0010a94f, 0x42001000, - 0x0000dc00, 0x0201f800, 0x0010763b, 0x0401f005, - 0x4803c857, 0x4933c857, 0x0401f81c, 0x04000f93, - 0x5c00a000, 0x5c00a800, 0x5c00b000, 0x5c026000, - 0x5c025800, 0x1c01f000, 0x5830000b, 0x5832600c, - 0x4803c857, 0x4933c857, 0x81300580, 0x040207f1, - 0x0401f80e, 0x040207f3, 0x4803c857, 0x0201f800, - 0x00106619, 0x02020800, 0x00100615, 0x4a025a06, - 0x00000002, 0x0201f800, 0x00020381, 0x0201f800, - 0x00107698, 0x0401f7e7, 0x0201f800, 0x0010698c, - 0x4df00000, 0x598c000d, 0x81300580, 0x04020009, - 0x598c0005, 0x81300580, 0x04020006, 0x5c03e000, - 0x02000800, 0x00106982, 0x80000580, 0x1c01f000, - 0x4803c857, 0x5c03e000, 0x02000800, 0x00106982, - 0x82000540, 0x00000001, 0x1c01f000, 0x59300403, - 0x82000c80, 0x00000056, 0x02021800, 0x00100615, - 0x4803c857, 0x0c01f001, 0x0010707a, 0x00107095, - 0x001070a6, 0x001071a9, 0x00107169, 0x0010716d, - 0x0010717e, 0x00107192, 0x00107187, 0x00107192, - 0x001071cd, 0x00107192, 0x0010720f, 0x00107192, - 0x0010721d, 0x00107192, 0x00107187, 0x00107192, - 0x00107221, 0x00106f60, 0x00106f60, 0x00106f60, - 0x00106f60, 0x00106f60, 0x00106f60, 0x00106f60, - 0x00106f60, 0x00106f60, 0x00106f60, 0x00106f60, - 0x001072ed, 0x0010730c, 0x00107316, 0x00106f60, - 0x0010732c, 0x0010717e, 0x00106f60, 0x0010717e, - 0x00107192, 0x00106f60, 0x001070a6, 0x001071a9, - 0x00106f60, 0x0010737c, 0x00107192, 0x00106f60, - 0x0010738c, 0x00107192, 0x00106f60, 0x00107187, - 0x0010706b, 0x00106f62, 0x00106f60, 0x001073a3, - 0x001073dc, 0x00107456, 0x00106f60, 0x00107466, - 0x0010717c, 0x00107459, 0x00106f60, 0x00107338, - 0x0010747f, 0x00106f60, 0x001074b4, 0x00107507, - 0x00106f60, 0x00106f77, 0x00106fdd, 0x00106fea, - 0x00106f60, 0x0010717e, 0x00106f60, 0x00107031, - 0x0010703c, 0x00106f60, 0x00106f60, 0x00106f8b, - 0x00106fb0, 0x00107546, 0x00107587, 0x001075ad, - 0x00106f60, 0x00106f60, 0x00106f60, 0x0010757b, - 0x0201f800, 0x00100615, 0x0401fad2, 0x59325808, - 0x592c0009, 0x4801a006, 0x592c000a, 0x4801a007, - 0x592c000b, 0x4801a008, 0x592c000c, 0x4801a009, - 0x592c000d, 0x4801a00a, 0x4979a00b, 0x592c0809, - 0x82040d00, 0x00000fff, 0x80040904, 0x42001000, - 0x0000dc00, 0x0201f000, 0x0010763b, 0x4a026202, - 0x0000ffff, 0x0401fabb, 0x4d2c0000, 0x4a01a006, - 0x05000000, 0x59325808, 0x592c0009, 0x4801a007, - 0x592c000a, 0x4801a008, 0x592c000b, 0x4801a009, - 0x42000800, 0x00000004, 0x42001000, 0x0000dc00, - 0x5c025800, 0x0201f000, 0x0010763b, 0x4c580000, - 0x4c500000, 0x4c540000, 0x4d2c0000, 0x0401faa5, - 0x59325808, 0x5930040b, 0x800000c2, 0x4200a800, - 0x0010b349, 0x592cb205, 0x832ca400, 0x00000006, - 0x0201f800, 0x0010a93e, 0x40580000, 0x8054ac00, - 0x592c0001, 0x80000540, 0x04000003, 0x40025800, - 0x0401f7f5, 0x4200a000, 0x0010b349, 0x4050a800, - 0x5930b40b, 0x0201f800, 0x0010a94f, 0x59300c0b, - 0x42001000, 0x0000dc00, 0x5c025800, 0x5c00a800, - 0x5c00b000, 0x5c00a000, 0x0201f000, 0x0010763b, + 0x5c032000, 0x0201f000, 0x001014fb, 0x4d900000, + 0x4dd00000, 0x4da40000, 0x4d140000, 0x4d300000, + 0x4d2c0000, 0x0401fc50, 0x0401f8d2, 0x59926004, + 0x4933c857, 0x0401f880, 0x04000016, 0x0201f800, + 0x00106062, 0x813261c0, 0x04000034, 0x59325808, + 0x812e59c0, 0x02000800, 0x001005d8, 0x0201f800, + 0x0010513b, 0x0402001d, 0x592c0208, 0x84000550, + 0x48025a08, 0x0201f800, 0x00105258, 0x04020027, + 0x592c0208, 0x84000510, 0x48025a08, 0x0401f023, + 0x0201f800, 0x00106052, 0x0401f020, 0x0201f800, + 0x0010a9c7, 0x0401fd9e, 0x592c0208, 0x84000550, + 0x48025a08, 0x4d380000, 0x42027000, 0x0000004a, + 0x4a026203, 0x00000003, 0x0201f800, 0x000207a1, + 0x5c027000, 0x0401f011, 0x59900006, 0x82000500, + 0xffff0000, 0x040207ee, 0x59c408af, 0x82040480, + 0x000003e8, 0x040217ea, 0x59900006, 0x82000400, + 0x00010000, 0x48032006, 0x0201f800, 0x00106052, + 0x0201f800, 0x0010411d, 0x5c025800, 0x5c026000, + 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, + 0x0401f403, 0x4d300000, 0x4d2c0000, 0x0401fc0a, + 0x598e600d, 0x4933c857, 0x59c41004, 0x8c081500, + 0x04000007, 0x0201f800, 0x0010513b, 0x04020007, + 0x0201f800, 0x00105258, 0x0402002f, 0x0201f800, + 0x0010604d, 0x0401f02c, 0x598c000f, 0x80000540, + 0x04020011, 0x59c408af, 0x82040480, 0x000003e8, + 0x0402100d, 0x598c080f, 0x80040800, 0x4807180f, + 0x0201f800, 0x0010604d, 0x42000000, 0x0010b852, + 0x0201f800, 0x0010aa47, 0x0201f800, 0x0010411d, + 0x0401f019, 0x0401fdb4, 0x813261c0, 0x04020003, + 0x0401f849, 0x0401f014, 0x0201f800, 0x0010a9c7, + 0x59300406, 0x82000580, 0x00000003, 0x04020007, + 0x59325808, 0x812e59c0, 0x04000004, 0x592c0208, + 0x84000550, 0x48025a08, 0x0401f854, 0x4d380000, + 0x42027000, 0x00000014, 0x0201f800, 0x000207a1, + 0x5c027000, 0x5c025800, 0x5c026000, 0x0201f000, + 0x00106c4b, 0x59c40804, 0x83180400, 0x00107095, + 0x50000000, 0x80040500, 0x1c01f000, 0x59c40804, + 0x83180400, 0x0010709a, 0x50000000, 0x80040500, + 0x1c01f000, 0x00000210, 0x00000420, 0x00000840, + 0x00001080, 0x00002100, 0x00004000, 0x00008000, + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000, 0x00800000, + 0x59900806, 0x80040120, 0x800c0480, 0x04021004, + 0x82000540, 0x00000001, 0x0401f005, 0x82040c00, + 0x00010000, 0x48072006, 0x80000580, 0x1c01f000, + 0x480bc857, 0x0201f800, 0x00106c55, 0x4df00000, + 0x480b1800, 0x5c03e000, 0x02000800, 0x00106c4b, + 0x1c01f000, 0x4803c856, 0x0201f800, 0x00106c55, + 0x4df00000, 0x497b180d, 0x497b1803, 0x497b180e, + 0x497b180f, 0x497b1810, 0x598c0000, 0x82000580, + 0x00000003, 0x04000009, 0x836c0580, 0x00000002, + 0x04020004, 0x4a031800, 0x00000005, 0x0401f003, + 0x4a031800, 0x00000000, 0x5c03e000, 0x02000800, + 0x00106c4b, 0x1c01f000, 0x59300004, 0x8c00050c, + 0x04020003, 0x4a026203, 0x00000001, 0x1c01f000, + 0x83180480, 0x00000005, 0x02021800, 0x001005d8, + 0x491bc857, 0x811b20c8, 0x83932400, 0x0000bf32, + 0x811ba0ca, 0x83d3a400, 0x00007600, 0x83180400, + 0x001070ea, 0x50034800, 0x811a28c2, 0x83162c00, + 0x00006100, 0x1c01f000, 0x0010b75b, 0x0010b772, + 0x0010b789, 0x0010b7a0, 0x0010b7b7, 0x4933c857, + 0x59300406, 0x82000c80, 0x00000012, 0x04021016, + 0x4803c857, 0x04011000, 0x0c01f001, 0x00107109, + 0x00107198, 0x001074d1, 0x00107556, 0x00107198, + 0x001074d1, 0x00107556, 0x00107109, 0x00107198, + 0x00107109, 0x00107109, 0x00107109, 0x00107109, + 0x00107109, 0x00107109, 0x00107109, 0x0010710f, + 0x0010710f, 0x0201f800, 0x00106c55, 0x0201f800, + 0x00106bbf, 0x0201f000, 0x00106c4b, 0x42001000, + 0x0010b7f6, 0x50081000, 0x4930100c, 0x58080002, + 0x82000580, 0x00000100, 0x04020032, 0x59325808, + 0x812e59c0, 0x02000800, 0x001005d8, 0x59326809, + 0x813669c0, 0x04000019, 0x592c040b, 0x82000500, + 0x0000e000, 0x04000003, 0x0401fba8, 0x0401f002, + 0x0401fb98, 0x42001000, 0x0010b7f6, 0x50081000, + 0x4930100b, 0x492c100a, 0x82d00400, 0x00000006, + 0x48001003, 0x592c000d, 0x80000104, 0x48001004, + 0x592c000e, 0x48001007, 0x592c000f, 0x48001008, + 0x0201f000, 0x00100858, 0x42026800, 0x0010be0d, + 0x592c080a, 0x48066802, 0x82040500, 0x00ffff00, + 0x04000007, 0x497a6a12, 0x59a81010, 0x82081500, + 0x00ffff00, 0x80080580, 0x040207dc, 0x82040d00, + 0x000000ff, 0x800408d0, 0x48066a12, 0x0401f7d7, + 0x1c01f000, 0x4d2c0000, 0x4d300000, 0x4c580000, + 0x4c540000, 0x4c500000, 0x5832580a, 0x812e59c0, + 0x02000800, 0x001005d8, 0x58300002, 0x4a006002, + 0x00000100, 0x82000580, 0x00000100, 0x0402001c, + 0x5830000b, 0x5832600c, 0x81300580, 0x04020010, + 0x0401f828, 0x04020010, 0x592c080d, 0x80040904, + 0x4004b000, 0x4200a000, 0x0010b54b, 0x4050a800, + 0x0201f800, 0x0010ab28, 0x42001000, 0x0000dc00, + 0x0201f800, 0x001078bc, 0x0401f003, 0x0401f819, + 0x04000fa3, 0x5c00a000, 0x5c00a800, 0x5c00b000, + 0x5c026000, 0x5c025800, 0x1c01f000, 0x5830000b, + 0x5832600c, 0x81300580, 0x040207f5, 0x0401f80d, + 0x040207f5, 0x0201f800, 0x001068d3, 0x02020800, + 0x001005d8, 0x4a025a06, 0x00000002, 0x0201f800, + 0x000202da, 0x0201f800, 0x00107911, 0x0401f7ea, + 0x0201f800, 0x00106c55, 0x4df00000, 0x598c000d, + 0x81300580, 0x04020009, 0x598c0005, 0x81300580, + 0x04020006, 0x5c03e000, 0x02000800, 0x00106c4b, + 0x80000580, 0x1c01f000, 0x5c03e000, 0x02000800, + 0x00106c4b, 0x82000540, 0x00000001, 0x1c01f000, + 0x59300403, 0x82000c80, 0x00000056, 0x02021800, + 0x001005d8, 0x4803c857, 0x0c01f001, 0x00107302, + 0x0010731d, 0x0010732e, 0x00107431, 0x001073f1, + 0x001073f5, 0x00107406, 0x0010741a, 0x0010740f, + 0x0010741a, 0x00107455, 0x0010741a, 0x00107497, + 0x0010741a, 0x001074a5, 0x0010741a, 0x0010740f, + 0x0010741a, 0x001074a9, 0x001071f5, 0x001071f5, + 0x001071f5, 0x001071f5, 0x001071f5, 0x001071f5, + 0x001071f5, 0x001071f5, 0x001071f5, 0x001071f5, + 0x001071f5, 0x00107574, 0x00107593, 0x0010759d, + 0x001071f5, 0x001075b3, 0x00107406, 0x001071f5, + 0x00107406, 0x0010741a, 0x001071f5, 0x0010732e, + 0x00107431, 0x001071f5, 0x00107603, 0x0010741a, + 0x001071f5, 0x00107613, 0x0010741a, 0x001071f5, + 0x0010740f, 0x001072f3, 0x001071f7, 0x001071f5, + 0x0010762a, 0x0010765d, 0x001076d7, 0x001071f5, + 0x001076e7, 0x00107404, 0x001076da, 0x001071f5, + 0x001075bf, 0x00107700, 0x001071f5, 0x00107735, + 0x00107788, 0x001071f5, 0x0010720c, 0x00107265, + 0x00107272, 0x001071f5, 0x00107406, 0x001071f5, + 0x001072b9, 0x001072c4, 0x001071f5, 0x001071f5, + 0x00107220, 0x00107245, 0x001077c7, 0x00107808, + 0x0010782e, 0x001071f5, 0x001071f5, 0x001071f5, + 0x001077fc, 0x0201f800, 0x001005d8, 0x0401fac5, + 0x59325808, 0x592c0009, 0x4801a006, 0x592c000a, + 0x4801a007, 0x592c000b, 0x4801a008, 0x592c000c, + 0x4801a009, 0x592c000d, 0x4801a00a, 0x4979a00b, + 0x592c0809, 0x82040d00, 0x00000fff, 0x80040904, + 0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc, + 0x4a026202, 0x0000ffff, 0x0401faae, 0x4d2c0000, + 0x4a01a006, 0x05000000, 0x59325808, 0x592c0009, + 0x4801a007, 0x592c000a, 0x4801a008, 0x592c000b, + 0x4801a009, 0x42000800, 0x00000004, 0x42001000, + 0x0000dc00, 0x5c025800, 0x0201f000, 0x001078bc, 0x4c580000, 0x4c500000, 0x4c540000, 0x4d2c0000, - 0x42034800, 0x0010b342, 0x0401fa8c, 0x59325808, - 0x592c0802, 0x4807c857, 0x40041000, 0x80040904, - 0x82081500, 0x00000003, 0x04000008, 0x80040800, - 0x82081580, 0x00000003, 0x80081000, 0x58d00002, - 0x80080540, 0x4801a002, 0x4a025805, 0x02000000, + 0x0401fa98, 0x59325808, 0x5930040b, 0x800000c2, + 0x4200a800, 0x0010b54b, 0x592cb205, 0x832ca400, + 0x00000006, 0x0201f800, 0x0010ab17, 0x40580000, + 0x8054ac00, 0x592c0001, 0x80000540, 0x04000003, + 0x40025800, 0x0401f7f5, 0x4200a000, 0x0010b54b, + 0x4050a800, 0x5930b40b, 0x0201f800, 0x0010ab28, + 0x59300c0b, 0x42001000, 0x0000dc00, 0x5c025800, + 0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000, + 0x001078bc, 0x4c580000, 0x4c500000, 0x4c540000, + 0x4d2c0000, 0x42034800, 0x0010b544, 0x0401fa7f, + 0x59325808, 0x4a025805, 0x02000000, 0x592c0802, 0x82d0ac00, 0x00000006, 0x592cb011, 0x832ca400, - 0x00000005, 0x0201f800, 0x0010a93e, 0x40580000, + 0x00000005, 0x0201f800, 0x0010ab17, 0x40580000, 0x8054ac00, 0x592e5801, 0x41780000, 0x812e5d40, 0x040207f6, 0x42001000, 0x0000dc00, 0x5c025800, 0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000, - 0x0010763b, 0x0401fa57, 0x4a01a006, 0x78000000, + 0x001078bc, 0x0401fa57, 0x4a01a006, 0x78000000, 0x5930001c, 0x840001c0, 0x4801a407, 0x4979a207, 0x42000800, 0x00000002, 0x42001000, 0x0000dc00, - 0x0201f000, 0x0010763b, 0x4c580000, 0x4c540000, + 0x0201f000, 0x001078bc, 0x4c580000, 0x4c540000, 0x4c500000, 0x0401fa55, 0x4a01a006, 0x02000000, 0x59a80002, 0x4801a008, 0x59a80003, 0x4801a009, 0x59a80000, 0x4801a00a, 0x59a80001, 0x4801a00b, 0x5930001c, 0x82000d80, 0x0000e000, 0x04000016, 0x82000d80, 0x0000df00, 0x04000006, 0x4a01a407, 0x00000010, 0x42000800, 0x00000006, 0x0401f027, - 0x4a03c840, 0x0010b2e7, 0x4a03c842, 0x0000000d, - 0x42001800, 0x0010b2e7, 0x0201f800, 0x001007f5, - 0x42000000, 0x0000df00, 0x4200a000, 0x0010b2e7, - 0x0401f00d, 0x4a03c840, 0x0010b2f4, 0x4a03c842, - 0x0000000d, 0x42001800, 0x0010b2f4, 0x0201f800, - 0x001007f5, 0x42000000, 0x0000e000, 0x4200a000, - 0x0010b2f4, 0x82000540, 0x00000010, 0x4801a407, + 0x4a03c840, 0x0010b4eb, 0x4a03c842, 0x0000000d, + 0x42001800, 0x0010b4eb, 0x0201f800, 0x001007af, + 0x42000000, 0x0000df00, 0x4200a000, 0x0010b4eb, + 0x0401f00d, 0x4a03c840, 0x0010b4f8, 0x4a03c842, + 0x0000000d, 0x42001800, 0x0010b4f8, 0x0201f800, + 0x001007af, 0x42000000, 0x0000e000, 0x4200a000, + 0x0010b4f8, 0x82000540, 0x00000010, 0x4801a407, 0x4a01a207, 0x00000034, 0x4200b000, 0x0000000d, - 0x82d0ac00, 0x0000000c, 0x0201f800, 0x0010a93e, + 0x82d0ac00, 0x0000000c, 0x0201f800, 0x0010ab17, 0x42000800, 0x00000013, 0x42001000, 0x0000dc00, 0x5c00a000, 0x5c00a800, 0x5c00b000, 0x0201f000, - 0x0010763b, 0x0401fa03, 0x4a01a006, 0x63000028, + 0x001078bc, 0x0401fa03, 0x4a01a006, 0x63000028, 0x5930001c, 0x4801a007, 0x42000800, 0x00000002, - 0x42001000, 0x0000dc00, 0x0201f000, 0x0010763b, + 0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc, 0x0401fa06, 0x41780000, 0x41780800, 0x42002000, 0x00080000, 0x0c01f81b, 0x80000000, 0x80040800, 0x42001000, 0x0000000c, 0x59841802, 0x8c0c1d00, @@ -7229,28 +7391,28 @@ uint32_t risc_code01[] = { 0x80000000, 0x80040800, 0x82081400, 0x00000004, 0x82080540, 0x02000000, 0x4801a006, 0x800408e0, 0x5930001c, 0x80040540, 0x4801a007, 0x80080904, - 0x42001000, 0x0000dc00, 0x0201f000, 0x0010763b, - 0x00107061, 0x00107063, 0x00107065, 0x00107067, - 0x00107069, 0x4811a008, 0x1c01f000, 0x4811a009, + 0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc, + 0x001072e9, 0x001072eb, 0x001072ed, 0x001072ef, + 0x001072f1, 0x4811a008, 0x1c01f000, 0x4811a009, 0x1c01f000, 0x4811a00a, 0x1c01f000, 0x4811a00b, 0x1c01f000, 0x4811a00c, 0x1c01f000, 0x4a026009, - 0x0010bc0c, 0x59a80010, 0x82000500, 0x000000ff, - 0x800000d0, 0x42026800, 0x0010bc0c, 0x48026a12, - 0x0401fa3c, 0x41780800, 0x42001000, 0x00005c00, - 0x0201f000, 0x0010763b, 0x0401f9ba, 0x4a01a006, + 0x0010be0d, 0x59a80010, 0x82000500, 0x000000ff, + 0x800000d0, 0x42026800, 0x0010be0d, 0x48026a12, + 0x0401fa3b, 0x41780800, 0x42001000, 0x00005c00, + 0x0201f000, 0x001078bc, 0x0401f9ba, 0x4a01a006, 0x52000000, 0x4979a007, 0x599c0017, 0x8c000500, - 0x04000005, 0x599c0402, 0x0201f800, 0x00101644, + 0x04000005, 0x599c0402, 0x0201f800, 0x001015da, 0x4805a007, 0x59a80002, 0x4801a008, 0x59a80003, 0x4801a009, 0x59a80000, 0x4801a00a, 0x59a80001, 0x4801a00b, 0x59a80010, 0x4801a00c, 0x42000800, 0x00000007, 0x42001000, 0x0000dc00, 0x0201f000, - 0x0010763b, 0x4a026202, 0x0000ffff, 0x0401f99d, + 0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f99d, 0x4a01a006, 0x05000000, 0x59a80010, 0x4801a007, 0x59a80002, 0x59a80803, 0x4801a008, 0x4805a009, 0x42000800, 0x00000004, 0x42001000, 0x0000dc00, - 0x0201f000, 0x0010763b, 0x4a026202, 0x0000ffff, + 0x0201f000, 0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f98c, 0x4d3c0000, 0x417a7800, 0x0201f800, - 0x00104745, 0x5c027800, 0x4a01a006, 0x03000000, + 0x001048f6, 0x5c027800, 0x4a01a006, 0x03000000, 0x59340403, 0x82000580, 0x000007fe, 0x0402006e, 0x4a01a006, 0x04000000, 0x81a40800, 0x4a000800, 0x22fffffe, 0x5934000a, 0x84000500, 0x4802680a, @@ -7260,18 +7422,18 @@ uint32_t risc_code01[] = { 0x8c040d16, 0x04000002, 0x8400056a, 0x4801a008, 0x4a01a009, 0x00002710, 0x59a8002d, 0x4801a00a, 0x0401f039, 0x59a8002a, 0x4801a007, 0x0201f800, - 0x00104e0d, 0x04020009, 0x497b8880, 0x82000500, - 0x0000ffff, 0x4c000000, 0x0201f800, 0x00101670, + 0x0010513b, 0x04020009, 0x497b8880, 0x82000500, + 0x0000ffff, 0x4c000000, 0x0201f800, 0x00101606, 0x5c000000, 0x48038880, 0x59a8002b, 0x0201f800, - 0x00104e0d, 0x04020004, 0x82000500, 0x37ffffff, + 0x0010513b, 0x04020004, 0x82000500, 0x37ffffff, 0x0401f003, 0x82000500, 0x3fffffff, 0x599c0818, 0x8c040d16, 0x04000002, 0x8400056a, 0x59a80805, 0x8c040d10, 0x04000019, 0x59300c03, 0x82041580, 0x00000051, 0x04000015, 0x82041580, 0x00000031, 0x04000012, 0x4c580000, 0x4c500000, 0x4c540000, - 0x4200b000, 0x00000004, 0x4200a000, 0x0010b6f9, + 0x4200b000, 0x00000004, 0x4200a000, 0x0010b8fa, 0x82d0ac00, 0x0000001f, 0x4c000000, 0x0201f800, - 0x0010a93e, 0x5c000000, 0x5c00a800, 0x5c00a000, + 0x0010ab17, 0x5c000000, 0x5c00a800, 0x5c00a000, 0x5c00b000, 0x8400057a, 0x4801a008, 0x4979a009, 0x4979a00a, 0x59a80002, 0x59a80803, 0x4801a00b, 0x4805a00c, 0x59a80000, 0x59a80801, 0x4801a00d, @@ -7282,10 +7444,10 @@ uint32_t risc_code01[] = { 0x0401f043, 0x59a80026, 0x8c000508, 0x0400000d, 0x59a8002a, 0x82000500, 0x0000ffff, 0x59c40880, 0x80040d80, 0x04000007, 0x497b8880, 0x4c000000, - 0x0201f800, 0x00101670, 0x5c000000, 0x48038880, + 0x0201f800, 0x00101606, 0x5c000000, 0x48038880, 0x59a8002a, 0x4801a007, 0x4c640000, 0x4d2c0000, - 0x59a8c82b, 0x0201f800, 0x00108df4, 0x0400000d, - 0x0201f800, 0x00109360, 0x0402000a, 0x592c0207, + 0x59a8c82b, 0x0201f800, 0x00109037, 0x0400000d, + 0x0201f800, 0x00109597, 0x0402000a, 0x592c0207, 0x8c00050e, 0x04000007, 0x8264cd00, 0x0000ffff, 0x592c0009, 0x82000500, 0xffff0000, 0x8064cd40, 0x4865a008, 0x5c025800, 0x5c00c800, 0x59a8002c, @@ -7297,14 +7459,14 @@ uint32_t risc_code01[] = { 0x4801a017, 0x59a8002f, 0x4801a018, 0x59a80030, 0x4801a019, 0x59a80031, 0x4801a01a, 0x42000800, 0x0000001d, 0x42001000, 0x0000dc00, 0x0201f000, - 0x0010763b, 0x0401f8cb, 0x4a01a006, 0x50000000, + 0x001078bc, 0x0401f8cb, 0x4a01a006, 0x50000000, 0x0401f7b5, 0x0401f8c7, 0x4a01a406, 0x21000010, 0x4a01a206, 0x00000014, 0x4979a007, 0x4979a008, 0x4979a009, 0x4979a00a, 0x42000800, 0x00000005, - 0x42001000, 0x0000dc00, 0x0201f000, 0x0010763b, + 0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f8bf, 0x0401f002, 0x0401f8c4, 0x4a01a006, 0x02000000, 0x42000800, 0x00000001, 0x42001000, - 0x0000dc00, 0x0201f000, 0x0010763b, 0x0401f8bb, + 0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f8bb, 0x4a01a006, 0x02000000, 0x59300403, 0x82000580, 0x00000031, 0x04020794, 0x81a40800, 0x4a000801, 0x00fffffe, 0x0401f72b, 0x0401f8b0, 0x4a01a006, @@ -7313,7 +7475,7 @@ uint32_t risc_code01[] = { 0x5930021a, 0x80000540, 0x04000003, 0x4801a207, 0x0401f003, 0x4a01a207, 0x00002a00, 0x42000800, 0x00000002, 0x42001000, 0x0000dc00, 0x0201f000, - 0x0010763b, 0x4a026202, 0x0000ffff, 0x0401f889, + 0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f889, 0x4a01a406, 0x00002010, 0x4a01a206, 0x00000014, 0x4a01a407, 0x00000800, 0x4a01a207, 0x00002000, 0x80000580, 0x599c0817, 0x8c040d0a, 0x04020003, @@ -7338,1462 +7500,1447 @@ uint32_t risc_code01[] = { 0x8c08150a, 0x04020004, 0x8c040d0a, 0x04000002, 0x8400054e, 0x8c040d1c, 0x04000002, 0x84000552, 0x4801a20a, 0x42000800, 0x00000005, 0x42001000, - 0x0000dc00, 0x0201f000, 0x0010763b, 0x0401f833, + 0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f833, 0x4a01a006, 0x02100014, 0x4a01a007, 0x01000000, 0x4979a008, 0x4979a009, 0x4979a00a, 0x42000800, 0x00000005, 0x42001000, 0x0000dc00, 0x0201f000, - 0x0010763b, 0x0401f825, 0x4a01a006, 0x02000000, + 0x001078bc, 0x0401f825, 0x4a01a006, 0x02000000, 0x0401f65d, 0x4933c857, 0x0401f820, 0x4a01a006, 0x01000000, 0x4a01a407, 0x0000000b, 0x42000800, 0x00000002, 0x42001000, 0x0000dc00, 0x0201f000, - 0x0010763b, 0x42005000, 0x32000000, 0x42006000, - 0x08290000, 0x41786800, 0x41787800, 0x0401f3e6, + 0x001078bc, 0x42005000, 0x32000000, 0x42006000, + 0x08290000, 0x41786800, 0x41787800, 0x0401f3df, 0x42005000, 0x22000000, 0x42006000, 0x01290000, - 0x41786800, 0x41787800, 0x0401f3df, 0x42005000, + 0x41786800, 0x41787800, 0x0401f3d8, 0x42005000, 0x33000000, 0x42006000, 0x08980000, 0x41786800, - 0x41787800, 0x0401f3d8, 0x42005000, 0x23000000, + 0x41787800, 0x0401f3d1, 0x42005000, 0x23000000, 0x42006000, 0x01980000, 0x41786800, 0x41787800, - 0x0401f3d1, 0x59300403, 0x82000c80, 0x00000085, - 0x02001800, 0x00100615, 0x82000c80, 0x00000093, - 0x02021800, 0x00100615, 0x82000480, 0x00000085, - 0x0c01f001, 0x00107263, 0x00107265, 0x00107272, - 0x00107263, 0x00107263, 0x00107263, 0x00107263, - 0x00107263, 0x00107263, 0x00107263, 0x00107263, - 0x00107263, 0x00107263, 0x0010727f, 0x0201f800, - 0x00100615, 0x4933c857, 0x0401f851, 0x5930001c, - 0x4801a004, 0x4801a007, 0x4979a408, 0x4a01a208, - 0x0000ffff, 0x42000800, 0x00000003, 0x42001000, - 0x0000dc00, 0x0401f3ca, 0x4933c857, 0x0401f850, - 0x5930001c, 0x4801a004, 0x4a01a406, 0x00000003, - 0x4a01a206, 0x00000300, 0x42000800, 0x00000001, - 0x42001000, 0x0000dc00, 0x0401f3bd, 0x4d2c0000, - 0x59325808, 0x4933c857, 0x492fc857, 0x812e59c0, - 0x02000800, 0x00100615, 0x59340a12, 0x82040d00, - 0x0000ff00, 0x592c000a, 0x82000500, 0x000000ff, - 0x900001c0, 0x80040540, 0x82000540, 0x00000011, - 0x44034800, 0x81a5a000, 0x42001000, 0x00000009, - 0x42000800, 0x00000003, 0x592c0009, 0x82000500, - 0xff000000, 0x82001d80, 0x84000000, 0x04000009, - 0x82001d80, 0x85000000, 0x02020800, 0x00100615, - 0x42001000, 0x00000007, 0x42000800, 0x00000001, - 0x832c1c00, 0x00000009, 0x500c0000, 0x4401a000, - 0x800c1800, 0x80d1a000, 0x80081040, 0x040207fb, - 0x42001000, 0x0000dc00, 0x5c025800, 0x0401f38c, - 0x42005000, 0x81000000, 0x42006000, 0x00090000, - 0x41786800, 0x41787800, 0x0401f363, 0x42005000, - 0x84000000, 0x42006000, 0x00990000, 0x59300406, - 0x82000580, 0x00000005, 0x04000002, 0x8430652e, - 0x41786800, 0x41787800, 0x0401f357, 0x42005000, - 0x85000000, 0x42006000, 0x00990000, 0x59300406, - 0x82000580, 0x00000005, 0x04000002, 0x8430652e, - 0x41786800, 0x41787800, 0x0401f34b, 0x59300403, - 0x82000c80, 0x00000053, 0x02021800, 0x00100615, - 0x82000480, 0x0000004b, 0x02001800, 0x00100615, - 0x59326809, 0x59368c03, 0x4803c857, 0x0c01f001, - 0x00107353, 0x0010735b, 0x00107363, 0x0010736b, - 0x001072e4, 0x001072e4, 0x001072e4, 0x0010734b, - 0x0201f800, 0x00100615, 0x42005000, 0x06000000, - 0x42006000, 0x08290000, 0x41786800, 0x41787800, - 0x0401f32d, 0x4933c857, 0x0401ff46, 0x4a01a006, - 0x12000000, 0x59300406, 0x82000580, 0x00000004, - 0x04020003, 0x59340002, 0x0401f002, 0x59a80010, - 0x82000500, 0x00ffffff, 0x4801a007, 0x59300419, - 0x4801a408, 0x59300219, 0x4801a208, 0x4979a009, - 0x4979a00a, 0x4979a00b, 0x4979a00c, 0x4979a00d, - 0x4979a00e, 0x4979a00f, 0x4979a010, 0x42000800, - 0x0000000b, 0x42001000, 0x0000dc00, 0x0401f330, - 0x0401ff28, 0x4a01a006, 0x0f000000, 0x5930001c, - 0x4801a007, 0x42000800, 0x00000002, 0x42001000, - 0x0000dc00, 0x0401f326, 0x0401ff2c, 0x4a01a006, - 0x02000000, 0x59c40085, 0x48031004, 0x59880000, - 0x4801a007, 0x59880001, 0x4801a008, 0x59880002, - 0x4801a009, 0x59880003, 0x4801a00a, 0x59880004, - 0x4801a00b, 0x59880005, 0x4801a00c, 0x42000800, - 0x00000007, 0x42001000, 0x0000dc00, 0x0401f310, - 0x4a026202, 0x0000ffff, 0x0401ff06, 0x4a01a006, - 0x62000000, 0x5930001c, 0x4801a007, 0x42000800, - 0x00000002, 0x42001000, 0x0000dc00, 0x0401f304, - 0x0401fefc, 0x59300808, 0x4c500000, 0x4c540000, - 0x4c580000, 0x8204a400, 0x0000000a, 0x5930b01c, - 0x82d0ac00, 0x00000006, 0x0201f800, 0x0010a93e, - 0x5930081c, 0x42001000, 0x0000dc00, 0x5c00b000, - 0x5c00a800, 0x5c00a000, 0x0401f2f1, 0x0401ff9b, - 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, - 0x4a01a008, 0x00001000, 0x0401f020, 0x0401ff93, - 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, - 0x4a01a008, 0x00004000, 0x0401f018, 0x0401ff8b, - 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, - 0x4a01a008, 0x00002000, 0x0401f010, 0x0401ff83, - 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, - 0x4a01a008, 0x00000400, 0x0401f008, 0x0401ff7b, - 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, - 0x4a01a008, 0x00000200, 0x4979a009, 0x4979a00a, - 0x4979a00b, 0x4979a00c, 0x4979a00d, 0x42000800, - 0x00000008, 0x42001000, 0x0000dc00, 0x0401f2c0, - 0x0401fec6, 0x4a01a006, 0x02000014, 0x4979a407, - 0x4979a207, 0x59a8003a, 0x4801a008, 0x59a8003b, - 0x4801a009, 0x4a01a00a, 0x00047878, 0x42000800, - 0x00000005, 0x42001000, 0x0000dc00, 0x0401f2b0, - 0x0401feb6, 0x4a01a006, 0x02140018, 0x4a01a407, - 0x00000800, 0x5930001c, 0x82000d00, 0xff000000, - 0x900409c0, 0x4805a207, 0x82000500, 0x00ffffff, - 0x4801a00a, 0x4979a408, 0x4979a208, 0x4979a409, - 0x4979a209, 0x4979a00b, 0x42000800, 0x00000006, - 0x42001000, 0x0000dc00, 0x0401f299, 0x4933c857, - 0x4937c857, 0x4d380000, 0x4d1c0000, 0x42027000, - 0x00000035, 0x0201f800, 0x00109183, 0x04020022, - 0x0401fe88, 0x4a01a006, 0x13000000, 0x5932381e, - 0x591c0414, 0x8c000502, 0x02000800, 0x00100615, - 0x591c0019, 0x4801a005, 0x591c0406, 0x82000580, - 0x00000003, 0x04000007, 0x59300809, 0x58040002, - 0x82000500, 0x00ffffff, 0x4801a007, 0x0401f003, - 0x59a80010, 0x4801a007, 0x59300419, 0x4801a408, - 0x59300219, 0x4801a208, 0x42000800, 0x00000003, - 0x42001000, 0x0000dc00, 0x5c023800, 0x5c027000, - 0x0401f26f, 0x4803c856, 0x0201f800, 0x0010698c, - 0x598c000d, 0x81300580, 0x02020800, 0x00100615, - 0x0201f800, 0x001068f6, 0x0201f800, 0x000208b4, - 0x5c023800, 0x5c027000, 0x0201f000, 0x00106982, - 0x4803c856, 0x4d2c0000, 0x4d1c0000, 0x5932381e, - 0x811e39c0, 0x02000800, 0x00100615, 0x591c0c06, - 0x82040580, 0x00000006, 0x0400000d, 0x82040580, - 0x00000003, 0x04000036, 0x4a026403, 0x00000037, - 0x4a02641a, 0x00000003, 0x4a02621a, 0x00001700, - 0x5c023800, 0x5c025800, 0x0401f064, 0x0401f84b, - 0x42001000, 0x40000000, 0x591c0203, 0x591c0804, - 0x8c040d3e, 0x04020023, 0x82000c80, 0x0000000e, - 0x0c001003, 0x0201f800, 0x00100615, 0x00107410, - 0x0010741c, 0x00107412, 0x0010741c, 0x00107418, - 0x00107410, 0x00107410, 0x0010741c, 0x0010741c, - 0x00107410, 0x00107410, 0x00107410, 0x00107410, - 0x00107410, 0x0010741c, 0x00107410, 0x0010741c, - 0x0201f800, 0x00100615, 0x591c0414, 0x4803c857, - 0x8c000518, 0x04000003, 0x8c000512, 0x04000003, - 0x80001580, 0x0401f003, 0x42001000, 0x20000000, - 0x591c0015, 0x4801a00a, 0x0401f018, 0x0401f81f, - 0x591e5808, 0x812e59c0, 0x02000800, 0x00100615, - 0x592c100f, 0x591c0011, 0x80080480, 0x4801a00a, - 0x591c0203, 0x591c0804, 0x8c040d3e, 0x04020007, - 0x82000d80, 0x00000002, 0x04000007, 0x82000d80, - 0x00000004, 0x04000004, 0x42001000, 0x40000000, - 0x0401f002, 0x80001580, 0x4809a00b, 0x42000800, - 0x00000006, 0x42001000, 0x0000dc00, 0x5c023800, - 0x5c025800, 0x0401f1fe, 0x4803c856, 0x0401fe03, - 0x4a01a006, 0x02000000, 0x59300c19, 0x4805a407, - 0x59300a19, 0x4805a207, 0x59a81010, 0x59300809, - 0x58041802, 0x820c1d00, 0x00ffffff, 0x5930081e, - 0x58040406, 0x82000580, 0x00000003, 0x04020004, - 0x4809a008, 0x480da009, 0x0401f003, 0x480da008, - 0x4809a009, 0x1c01f000, 0x4803c856, 0x0401fdeb, - 0x0401f003, 0x4803c856, 0x0401fde1, 0x4a01a006, - 0x01000000, 0x5930041a, 0x4801a407, 0x5930021a, - 0x4801a207, 0x42000800, 0x00000002, 0x42001000, - 0x0000dc00, 0x0401f1d6, 0x4803c856, 0x4d1c0000, - 0x0401fdc5, 0x4a01a006, 0x14000000, 0x5932381e, - 0x591c0019, 0x4801a005, 0x59300419, 0x4801a407, - 0x59300219, 0x4801a207, 0x59300015, 0x4801a008, - 0x59300216, 0x82000500, 0x000000ff, 0x840001c0, - 0x4801a409, 0x42000800, 0x00000004, 0x42001000, - 0x0000dc00, 0x5c023800, 0x0401f1bd, 0x4803c856, - 0x0401f80b, 0x5930041a, 0x900001c0, 0x4801a005, - 0x0401f9f4, 0x41780800, 0x42001000, 0x00005c00, - 0x0401f9b3, 0x0201f000, 0x00105d86, 0x4803c856, - 0x59300817, 0x82041c00, 0x00000005, 0x46034800, - 0x00000021, 0x58040404, 0x82000500, 0x0000f000, - 0x82000580, 0x00003000, 0x04000003, 0x46034800, - 0x00000041, 0x81a5a000, 0x580c0001, 0x82000d00, - 0x00ffffff, 0x82040d40, 0xc2000000, 0x4805a000, - 0x580c0800, 0x82041500, 0x00ffffff, 0x82000500, - 0xff000000, 0x80080540, 0x4801a001, 0x580c0002, - 0x82000580, 0x00c00000, 0x82000500, 0x00fd0300, - 0x4801a002, 0x580c0003, 0x4801a003, 0x580c0404, - 0x4801a404, 0x580c0204, 0x4801a204, 0x1c01f000, - 0x4803c856, 0x59a80026, 0x82000500, 0x00000028, - 0x04020009, 0x59a80026, 0x82000500, 0x00000028, - 0x04000003, 0x497a6a12, 0x0401f003, 0x4a026a12, - 0x0000ff00, 0x42005000, 0x22000000, 0x42006000, - 0x01380000, 0x41786800, 0x41787800, 0x0401f952, - 0x59301008, 0x4a01a006, 0x54000000, 0x59a80010, + 0x0401f3ca, 0x59300403, 0x82000c80, 0x00000085, + 0x02001800, 0x001005d8, 0x82000c80, 0x00000093, + 0x02021800, 0x001005d8, 0x82000480, 0x00000085, + 0x0c01f001, 0x001074eb, 0x001074ed, 0x001074fb, + 0x001074eb, 0x001074eb, 0x001074eb, 0x001074eb, + 0x001074eb, 0x001074eb, 0x001074eb, 0x001074eb, + 0x001074eb, 0x001074eb, 0x00107506, 0x0201f800, + 0x001005d8, 0x4933c857, 0x0401f850, 0x59300402, + 0x4801a407, 0x5930001c, 0x4801a207, 0x4979a408, + 0x4a01a208, 0x0000ffff, 0x42000800, 0x00000003, + 0x42001000, 0x0000dc00, 0x0401f3c2, 0x4933c857, + 0x0401f84e, 0x4a01a406, 0x00000003, 0x4a01a206, + 0x00000300, 0x42000800, 0x00000001, 0x42001000, + 0x0000dc00, 0x0401f3b7, 0x4d2c0000, 0x59325808, + 0x4933c857, 0x492fc857, 0x812e59c0, 0x02000800, + 0x001005d8, 0x59340a12, 0x82040d00, 0x0000ff00, + 0x592c000a, 0x82000500, 0x000000ff, 0x900001c0, + 0x80040540, 0x82000540, 0x00000011, 0x44034800, + 0x81a5a000, 0x42001000, 0x00000009, 0x42000800, + 0x00000003, 0x592c0009, 0x82000500, 0xff000000, + 0x82001d80, 0x84000000, 0x04000009, 0x82001d80, + 0x85000000, 0x02020800, 0x001005d8, 0x42001000, + 0x00000007, 0x42000800, 0x00000001, 0x832c1c00, + 0x00000009, 0x500c0000, 0x4401a000, 0x800c1800, + 0x80d1a000, 0x80081040, 0x040207fb, 0x42001000, + 0x0000dc00, 0x5c025800, 0x0401f386, 0x42005000, + 0x81000000, 0x42006000, 0x00090000, 0x41786800, + 0x41787800, 0x0401f35d, 0x42005000, 0x84000000, + 0x42006000, 0x00990000, 0x59300406, 0x82000580, + 0x00000005, 0x04000002, 0x8430652e, 0x41786800, + 0x41787800, 0x0401f351, 0x42005000, 0x85000000, + 0x42006000, 0x00990000, 0x59300406, 0x82000580, + 0x00000005, 0x04000002, 0x8430652e, 0x41786800, + 0x41787800, 0x0401f345, 0x59300403, 0x82000c80, + 0x00000053, 0x02021800, 0x001005d8, 0x82000480, + 0x0000004b, 0x02001800, 0x001005d8, 0x59326809, + 0x59368c03, 0x4803c857, 0x0c01f001, 0x001075da, + 0x001075e2, 0x001075ea, 0x001075f2, 0x0010756b, + 0x0010756b, 0x0010756b, 0x001075d2, 0x0201f800, + 0x001005d8, 0x42005000, 0x06000000, 0x42006000, + 0x08290000, 0x41786800, 0x41787800, 0x0401f327, + 0x4933c857, 0x0401ff47, 0x4a01a006, 0x12000000, + 0x59300406, 0x82000580, 0x00000004, 0x04020003, + 0x59340002, 0x0401f002, 0x59a80010, 0x82000500, + 0x00ffffff, 0x4801a007, 0x59300419, 0x4801a408, + 0x59300219, 0x4801a208, 0x4979a009, 0x4979a00a, + 0x4979a00b, 0x4979a00c, 0x4979a00d, 0x4979a00e, + 0x4979a00f, 0x4979a010, 0x42000800, 0x0000000b, + 0x42001000, 0x0000dc00, 0x0401f32a, 0x0401ff29, + 0x4a01a006, 0x0f000000, 0x5930001c, 0x4801a007, + 0x42000800, 0x00000002, 0x42001000, 0x0000dc00, + 0x0401f320, 0x0401ff2d, 0x4a01a006, 0x02000000, + 0x59c40085, 0x48031004, 0x59880000, 0x4801a007, + 0x59880001, 0x4801a008, 0x59880002, 0x4801a009, + 0x59880003, 0x4801a00a, 0x59880004, 0x4801a00b, + 0x59880005, 0x4801a00c, 0x42000800, 0x00000007, + 0x42001000, 0x0000dc00, 0x0401f30a, 0x4a026202, + 0x0000ffff, 0x0401ff07, 0x4a01a006, 0x62000000, + 0x5930001c, 0x4801a007, 0x42000800, 0x00000002, + 0x42001000, 0x0000dc00, 0x0401f2fe, 0x0401fefd, + 0x59300808, 0x4c500000, 0x4c540000, 0x4c580000, + 0x8204a400, 0x0000000a, 0x5930b01c, 0x82d0ac00, + 0x00000006, 0x0201f800, 0x0010ab17, 0x5930081c, + 0x42001000, 0x0000dc00, 0x5c00b000, 0x5c00a800, + 0x5c00a000, 0x0401f2eb, 0x0401ff9b, 0x59300017, + 0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008, + 0x00001000, 0x0401f020, 0x0401ff93, 0x59300017, + 0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008, + 0x00004000, 0x0401f018, 0x0401ff8b, 0x59300017, + 0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008, + 0x00002000, 0x0401f010, 0x0401ff83, 0x59300017, + 0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008, + 0x00000400, 0x0401f008, 0x0401ff7b, 0x59300017, + 0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008, + 0x00000200, 0x4979a009, 0x4979a00a, 0x4979a00b, + 0x4979a00c, 0x4979a00d, 0x42000800, 0x00000008, + 0x42001000, 0x0000dc00, 0x0401f2ba, 0x0401fec7, + 0x4a01a006, 0x02000014, 0x4979a407, 0x4979a207, + 0x59a8003a, 0x4801a008, 0x59a8003b, 0x4801a009, + 0x4a01a00a, 0x00047878, 0x42000800, 0x00000005, + 0x42001000, 0x0000dc00, 0x0401f2aa, 0x0401feb7, + 0x4a01a006, 0x02140018, 0x4a01a407, 0x00000800, + 0x5930001c, 0x82000d00, 0xff000000, 0x900409c0, + 0x4805a207, 0x82000500, 0x00ffffff, 0x4801a00a, + 0x4979a408, 0x4979a208, 0x4979a409, 0x4979a209, + 0x4979a00b, 0x42000800, 0x00000006, 0x42001000, + 0x0000dc00, 0x0401f293, 0x4803c856, 0x4d380000, + 0x4d1c0000, 0x42027000, 0x00000035, 0x0201f800, + 0x001093ba, 0x0402001e, 0x0401fe8a, 0x4a01a006, + 0x13000000, 0x5932381e, 0x591c0019, 0x4801a005, + 0x591c0406, 0x82000580, 0x00000003, 0x04000007, + 0x59300809, 0x58040002, 0x82000500, 0x00ffffff, + 0x4801a007, 0x0401f003, 0x59a80010, 0x4801a007, + 0x59300419, 0x4801a408, 0x59300219, 0x4801a208, + 0x42000800, 0x00000003, 0x42001000, 0x0000dc00, + 0x5c023800, 0x5c027000, 0x0401f26e, 0x0201f800, + 0x00106c55, 0x598c000d, 0x81300580, 0x02020800, + 0x001005d8, 0x0201f800, 0x00106bbf, 0x0201f800, + 0x0002077d, 0x5c023800, 0x5c027000, 0x0201f000, + 0x00106c4b, 0x4803c856, 0x4d2c0000, 0x4d1c0000, + 0x5932381e, 0x811e39c0, 0x02000800, 0x001005d8, + 0x591c0c06, 0x82040580, 0x00000006, 0x0400000d, + 0x82040580, 0x00000003, 0x04000036, 0x4a026403, + 0x00000037, 0x4a02641a, 0x00000003, 0x4a02621a, + 0x00001700, 0x5c023800, 0x5c025800, 0x0401f064, + 0x0401f84b, 0x42001000, 0x40000000, 0x591c0203, + 0x591c0804, 0x8c040d3e, 0x04020023, 0x82000c80, + 0x0000000e, 0x0c001003, 0x0201f800, 0x001005d8, + 0x00107691, 0x0010769d, 0x00107693, 0x0010769d, + 0x00107699, 0x00107691, 0x00107691, 0x0010769d, + 0x0010769d, 0x00107691, 0x00107691, 0x00107691, + 0x00107691, 0x00107691, 0x0010769d, 0x00107691, + 0x0010769d, 0x0201f800, 0x001005d8, 0x591c0414, + 0x4803c857, 0x8c000518, 0x04000003, 0x8c000512, + 0x04000003, 0x80001580, 0x0401f003, 0x42001000, + 0x20000000, 0x591c0015, 0x4801a00a, 0x0401f018, + 0x0401f81f, 0x591e5808, 0x812e59c0, 0x02000800, + 0x001005d8, 0x592c100f, 0x591c0011, 0x80080480, + 0x4801a00a, 0x591c0203, 0x591c0804, 0x8c040d3e, + 0x04020007, 0x82000d80, 0x00000002, 0x04000007, + 0x82000d80, 0x00000004, 0x04000004, 0x42001000, + 0x40000000, 0x0401f002, 0x80001580, 0x4809a00b, + 0x42000800, 0x00000006, 0x42001000, 0x0000dc00, + 0x5c023800, 0x5c025800, 0x0401f1fe, 0x4803c856, + 0x0401fe0a, 0x4a01a006, 0x02000000, 0x59300c19, + 0x4805a407, 0x59300a19, 0x4805a207, 0x59a81010, + 0x59300809, 0x58041802, 0x820c1d00, 0x00ffffff, + 0x5930081e, 0x58040406, 0x82000580, 0x00000003, + 0x04020004, 0x4809a008, 0x480da009, 0x0401f003, + 0x480da008, 0x4809a009, 0x1c01f000, 0x4803c856, + 0x0401fdf2, 0x0401f003, 0x4803c856, 0x0401fde8, + 0x4a01a006, 0x01000000, 0x5930041a, 0x4801a407, + 0x5930021a, 0x4801a207, 0x42000800, 0x00000002, + 0x42001000, 0x0000dc00, 0x0401f1d6, 0x4803c856, + 0x4d1c0000, 0x0401fdcc, 0x4a01a006, 0x14000000, + 0x5932381e, 0x591c0019, 0x4801a005, 0x59300419, + 0x4801a407, 0x59300219, 0x4801a207, 0x59300015, + 0x4801a008, 0x59300216, 0x82000500, 0x000000ff, + 0x840001c0, 0x4801a409, 0x42000800, 0x00000004, + 0x42001000, 0x0000dc00, 0x5c023800, 0x0401f1bd, + 0x4803c856, 0x0401f80b, 0x5930041a, 0x900001c0, + 0x4801a005, 0x0401f9ec, 0x41780800, 0x42001000, + 0x00005c00, 0x0401f9b3, 0x0201f000, 0x0010604d, + 0x4803c856, 0x59300817, 0x82041c00, 0x00000005, + 0x46034800, 0x00000021, 0x58040404, 0x82000500, + 0x0000f000, 0x82000580, 0x00003000, 0x04000003, + 0x46034800, 0x00000041, 0x81a5a000, 0x580c0001, + 0x82000d00, 0x00ffffff, 0x82040d40, 0xc2000000, + 0x4805a000, 0x580c0800, 0x82041500, 0x00ffffff, + 0x82000500, 0xff000000, 0x80080540, 0x4801a001, + 0x580c0002, 0x82000580, 0x00c00000, 0x82000500, + 0x00fd0300, 0x4801a002, 0x580c0003, 0x4801a003, + 0x580c0404, 0x4801a404, 0x580c0204, 0x4801a204, + 0x1c01f000, 0x4803c856, 0x59a80026, 0x82000500, + 0x00000028, 0x04020009, 0x59a80026, 0x82000500, + 0x00000028, 0x04000003, 0x497a6a12, 0x0401f003, + 0x4a026a12, 0x0000ff00, 0x42005000, 0x22000000, + 0x42006000, 0x01380000, 0x41786800, 0x41787800, + 0x0401f952, 0x59301008, 0x4a01a006, 0x54000000, + 0x59a80010, 0x82000500, 0x00ffffff, 0x58080c0a, + 0x800408f0, 0x80040540, 0x4801a007, 0x5808000a, + 0x82000500, 0xff000000, 0x4801a008, 0x59a80002, + 0x4801a009, 0x59a80003, 0x4801a00a, 0x59a80000, + 0x4801a00b, 0x59a80001, 0x4801a00c, 0x5808000c, + 0x9c0001c0, 0x4801a00d, 0x5808000d, 0x9c0001c0, + 0x4801a00e, 0x5808000e, 0x9c0001c0, 0x4801a00f, + 0x5808000f, 0x9c0001c0, 0x4801a010, 0x58080010, + 0x9c0001c0, 0x4801a011, 0x58080011, 0x9c0001c0, + 0x4801a012, 0x58080012, 0x9c0001c0, 0x4801a013, + 0x58080013, 0x9c0001c0, 0x4801a014, 0x58080010, + 0x9c0001c0, 0x4801a015, 0x58080011, 0x9c0001c0, + 0x4801a016, 0x58080012, 0x9c0001c0, 0x4801a017, + 0x58080013, 0x9c0001c0, 0x4801a018, 0x42000800, + 0x00000013, 0x42001000, 0x0000dc00, 0x0401f135, + 0x4803c856, 0x42005000, 0x22000000, 0x42006000, + 0x01290000, 0x41786800, 0x41787800, 0x0401f90b, + 0x59301008, 0x4a01a006, 0x55000000, 0x5808000b, 0x82000500, 0x00ffffff, 0x58080c0a, 0x800408f0, - 0x80040540, 0x4801a007, 0x5808000a, 0x82000500, - 0xff000000, 0x4801a008, 0x59a80002, 0x4801a009, - 0x59a80003, 0x4801a00a, 0x59a80000, 0x4801a00b, - 0x59a80001, 0x4801a00c, 0x5808000c, 0x9c0001c0, - 0x4801a00d, 0x5808000d, 0x9c0001c0, 0x4801a00e, - 0x5808000e, 0x9c0001c0, 0x4801a00f, 0x5808000f, - 0x9c0001c0, 0x4801a010, 0x58080010, 0x9c0001c0, - 0x4801a011, 0x58080011, 0x9c0001c0, 0x4801a012, - 0x58080012, 0x9c0001c0, 0x4801a013, 0x58080013, - 0x9c0001c0, 0x4801a014, 0x58080010, 0x9c0001c0, - 0x4801a015, 0x58080011, 0x9c0001c0, 0x4801a016, - 0x58080012, 0x9c0001c0, 0x4801a017, 0x58080013, - 0x9c0001c0, 0x4801a018, 0x42000800, 0x00000013, - 0x42001000, 0x0000dc00, 0x0401f135, 0x4803c856, - 0x42005000, 0x22000000, 0x42006000, 0x01290000, - 0x41786800, 0x41787800, 0x0401f90b, 0x59301008, - 0x4a01a006, 0x55000000, 0x5808000b, 0x82000500, - 0x00ffffff, 0x58080c0a, 0x800408f0, 0x80040540, - 0x4801a007, 0x5808080a, 0x82040d00, 0xff000000, - 0x59a80010, 0x82000500, 0x00ffffff, 0x80040540, - 0x4801a008, 0x5808000c, 0x9c0001c0, 0x4801a009, - 0x5808000d, 0x9c0001c0, 0x4801a00a, 0x5808000e, - 0x9c0001c0, 0x4801a00b, 0x5808000f, 0x9c0001c0, - 0x4801a00c, 0x59a80002, 0x4801a00d, 0x59a80003, - 0x4801a00e, 0x59a80000, 0x4801a00f, 0x59a80001, - 0x4801a010, 0x58080010, 0x4801a011, 0x58080011, - 0x4801a012, 0x58080012, 0x4801a013, 0x58080013, - 0x4801a014, 0x4979a015, 0x4979a016, 0x4979a017, - 0x4979a018, 0x42000800, 0x00000013, 0x42001000, - 0x0000dc00, 0x0401f0f6, 0x0401fcfc, 0x5930001c, - 0x800001c0, 0x04000008, 0x4a01a006, 0x01000000, - 0x4a01a407, 0x00000003, 0x42000800, 0x00000002, - 0x0401f028, 0x4a01a006, 0x02000000, 0x41780800, - 0x836c0580, 0x00000004, 0x04020003, 0x84040d42, - 0x0401f00d, 0x0201f800, 0x00104e0d, 0x04020003, - 0x84040d4a, 0x0401f002, 0x84040d48, 0x59a80026, - 0x8c000506, 0x04020003, 0x8c00050a, 0x04000002, - 0x84040d46, 0x4805a207, 0x59c40085, 0x48031004, - 0x4c580000, 0x4c500000, 0x4c540000, 0x4200b000, - 0x00000006, 0x8388a400, 0x00000000, 0x82d0ac00, - 0x00000008, 0x0201f800, 0x0010a93e, 0x5c00a800, - 0x5c00a000, 0x5c00b000, 0x42000800, 0x00000008, - 0x42001000, 0x0000dc00, 0x0401f0c1, 0x0401fcb9, - 0x4a01a006, 0x56000000, 0x59340006, 0x4801a007, - 0x59340007, 0x4801a008, 0x42000800, 0x00000003, - 0x42001000, 0x0000dc00, 0x0401f0b5, 0x4803c856, - 0x0401fcba, 0x5930081c, 0x800409c0, 0x0400000e, - 0x82040580, 0x0000ffff, 0x04000004, 0x82040480, - 0x00000007, 0x04021008, 0x4a01a006, 0x01000000, - 0x4a01a407, 0x00000003, 0x42000800, 0x00000002, - 0x0401f012, 0x4a01a006, 0x0200001c, 0x4a01a007, - 0x00000001, 0x42001000, 0x0010b2ec, 0x50080000, - 0x9c0001c0, 0x4801a009, 0x59a80010, 0x4801a00a, - 0x59a80002, 0x59a80803, 0x4801a00b, 0x4805a00c, - 0x42000800, 0x00000007, 0x42001000, 0x0000dc00, - 0x0401f08f, 0x4d2c0000, 0x0401fc86, 0x59325808, - 0x592c0008, 0x82000500, 0x00ffffff, 0x4801a001, - 0x4a01a006, 0x51000000, 0x5c025800, 0x0201f000, - 0x001070bc, 0x4803c856, 0x59a80810, 0x82040d00, - 0x000000ff, 0x59325808, 0x59326809, 0x59a83026, - 0x8c18350a, 0x04020008, 0x8c00050e, 0x04020006, - 0x80001d80, 0x59a82010, 0x82102500, 0x000000ff, - 0x0401f001, 0x59300406, 0x4803c857, 0x82000d80, - 0x00000009, 0x04000006, 0x82000d80, 0x0000000a, - 0x0400002e, 0x0201f800, 0x00100615, 0x59300015, - 0x8c00051e, 0x04020020, 0x42005000, 0x04000000, - 0x42006000, 0x05000000, 0x592c040a, 0x82000500, - 0x00000030, 0x800000e0, 0x80306540, 0x5934000a, - 0x8c000508, 0x04000002, 0x84306546, 0x41786800, - 0x41787800, 0x0401f831, 0x59300c14, 0x80040000, - 0x48026414, 0x40040000, 0x800000d0, 0x82000540, - 0x00000020, 0x4801a403, 0x83180d40, 0x00000038, - 0x42001000, 0x0000c920, 0x0401f868, 0x0201f000, - 0x00105d8b, 0x59a80026, 0x82000500, 0x00000028, - 0x04000003, 0x497a6a12, 0x0401f7dc, 0x4a026a12, - 0x0000ff00, 0x0401f7d9, 0x42005000, 0x02000000, - 0x42006000, 0x20290000, 0x41786800, 0x41787800, - 0x0401f812, 0x83180d40, 0x00000038, 0x42001000, - 0x0000c9a0, 0x0401f851, 0x42000800, 0x000007d0, - 0x59300011, 0x82000500, 0xfff00000, 0x80000540, - 0x04000003, 0x42000800, 0x00001b58, 0x41781000, - 0x0201f000, 0x00105d8d, 0x4201a000, 0x00000000, - 0x0401f003, 0x4201a000, 0x00000011, 0x59340a12, - 0x82040d00, 0x0000ff00, 0x59a80010, 0x82000500, - 0x000000ff, 0x900001c0, 0x80040540, 0x80d00540, - 0x44034800, 0x81a5a000, 0x59340002, 0x82000500, - 0x00ffffff, 0x80280540, 0x4801a000, 0x59a80010, - 0x4801a001, 0x4831a002, 0x82340540, 0x00000000, - 0x4801a003, 0x59300402, 0x4801a404, 0x59300a02, - 0x4805a204, 0x8c30652e, 0x04000003, 0x4805a404, - 0x4801a204, 0x483da005, 0x1c01f000, 0x4807c857, - 0x4c040000, 0x0401f82a, 0x5c000800, 0x40040000, - 0x80081540, 0x800000c4, 0x82000540, 0x00002000, - 0x4803910a, 0x59b400f6, 0x82000500, 0x00000018, - 0x040207fd, 0x4a0368f0, 0x0010b342, 0x42001800, - 0x0010b343, 0x580c0000, 0x4803c857, 0x580c0002, - 0x4803c857, 0x580c0004, 0x4803c857, 0x4a0368f1, - 0x0010b349, 0x480b68f3, 0x4a0378e4, 0x00008000, - 0x0201f000, 0x00105d86, 0x4807c857, 0x480a2800, - 0x4c040000, 0x0401f80a, 0x5c000800, 0x59b400f6, - 0x8c00050a, 0x040207fe, 0x49a768f2, 0x480768f4, - 0x4a0378e4, 0x00008000, 0x1c01f000, 0x4a0378e4, - 0x0000c000, 0x59bc00e4, 0x8c000520, 0x0400000c, - 0x4a0378e4, 0x00008000, 0x42007000, 0x000003e8, - 0x59bc00e4, 0x8c000520, 0x040007f5, 0x80387040, - 0x02000800, 0x00100615, 0x0401f7fa, 0x1c01f000, - 0x82000500, 0xffff0000, 0x82000580, 0x01050000, - 0x0402000d, 0x599c0818, 0x8c040d10, 0x0400000a, - 0x59a80807, 0x8c040d0a, 0x04000007, 0x42001000, - 0x0000804f, 0x41781800, 0x41782000, 0x0201f800, - 0x00103857, 0x1c01f000, 0x41781000, 0x42026000, - 0x0010cfc0, 0x59a8180e, 0x480a6402, 0x4a026202, - 0x0000ffff, 0x80081000, 0x800c1840, 0x04000004, - 0x83326400, 0x00000024, 0x0401f7f8, 0x1c01f000, - 0x4933c857, 0x59300203, 0x82000580, 0x00000000, - 0x0400002c, 0x59300406, 0x4803c857, 0x82000d80, - 0x00000004, 0x04000011, 0x82000d80, 0x00000001, - 0x0400000e, 0x82000d80, 0x00000003, 0x04000006, - 0x82000d80, 0x00000006, 0x04020011, 0x0201f800, - 0x0010a3fa, 0x5930001c, 0x800001c0, 0x02020800, - 0x0010961a, 0x0401f00a, 0x5930081e, 0x4807c857, - 0x800409c0, 0x04000006, 0x5804001c, 0x4803c857, - 0x81300580, 0x04020002, 0x4978081c, 0x497a6008, - 0x4a026004, 0x00004000, 0x59a80037, 0x82000c80, - 0x00000051, 0x04001002, 0x80000102, 0x48026206, - 0x497a6205, 0x497a6009, 0x4a026406, 0x00000007, - 0x1c01f000, 0x8166c9c0, 0x0400001c, 0x41626000, - 0x41580000, 0x59300a03, 0x82040d80, 0x00000000, - 0x04000008, 0x83326400, 0x00000024, 0x81300c80, - 0x040017f9, 0x42026000, 0x0010cfc0, 0x0401f7f6, - 0x4933c857, 0x8166c840, 0x83300c00, 0x00000024, - 0x80040480, 0x04021006, 0x4006c000, 0x4a026203, - 0x00000008, 0x813261c0, 0x1c01f000, 0x4202c000, - 0x0010cfc0, 0x0401f7fa, 0x42000000, 0x0010b653, - 0x0201f800, 0x0010a86e, 0x4933c856, 0x417a6000, - 0x0401f7f5, 0x4933c857, 0x83380580, 0x00000013, - 0x0402000b, 0x59300004, 0x8c00053e, 0x04000007, - 0x0201f800, 0x0010698c, 0x0201f800, 0x001068f6, - 0x0201f800, 0x00106982, 0x1c01f000, 0x4933c857, - 0x59880053, 0x80000000, 0x48031053, 0x1c01f000, - 0x4933c857, 0x59300203, 0x82003480, 0x0000000e, - 0x02021800, 0x00100615, 0x4d2c0000, 0x0c01f803, - 0x5c025800, 0x1c01f000, 0x00107718, 0x00107c84, - 0x00107dd4, 0x00107718, 0x00107e3a, 0x0010787c, - 0x00107718, 0x00107718, 0x00107c1a, 0x00107718, - 0x00107718, 0x00107718, 0x00107718, 0x00107718, - 0x0201f800, 0x00100615, 0x4933c857, 0x59300203, - 0x82003480, 0x0000000e, 0x02021800, 0x00100615, - 0x0c01f001, 0x0010772f, 0x001087f0, 0x0010772f, - 0x0010772f, 0x0010772f, 0x0010772f, 0x0010772f, - 0x0010772f, 0x0010879a, 0x0010880c, 0x0010887a, - 0x0010880c, 0x0010887a, 0x0010772f, 0x0201f800, - 0x00100615, 0x0201f800, 0x00100615, 0x4933c857, - 0x4d2c0000, 0x59325808, 0x59300203, 0x82003480, - 0x0000000e, 0x02021800, 0x00100615, 0x0c01f803, - 0x5c025800, 0x1c01f000, 0x0010774c, 0x0010774c, - 0x0010774c, 0x00107768, 0x001077b4, 0x0010774c, - 0x0010774c, 0x0010774c, 0x0010774e, 0x0010774c, - 0x0010774c, 0x0010774c, 0x0010774c, 0x0010774c, - 0x0201f800, 0x00100615, 0x4933c857, 0x83380580, - 0x00000040, 0x02020800, 0x00100615, 0x4a026007, - 0x00082000, 0x4a026203, 0x00000003, 0x493a6403, - 0x4a025c08, 0x00000001, 0x592c000d, 0x48026011, - 0x497a6013, 0x592c0208, 0x800000c2, 0x800010c4, - 0x80081400, 0x480a6206, 0x0201f800, 0x00100f9c, - 0x42000800, 0x80000060, 0x0201f000, 0x00106466, - 0x4933c857, 0x83380480, 0x00000050, 0x02021800, - 0x00100615, 0x83380480, 0x00000049, 0x02001800, - 0x00100615, 0x0c01f001, 0x0010777b, 0x00107786, - 0x00107779, 0x00107779, 0x00107779, 0x00107779, - 0x00107791, 0x0201f800, 0x00100615, 0x4a026203, - 0x00000004, 0x4a025c08, 0x00000002, 0x592c0207, - 0x48025c09, 0x592c0209, 0x48025a07, 0x592c000c, - 0x4802580d, 0x1c01f000, 0x0201f800, 0x001068c1, - 0x0201f800, 0x00108df4, 0x04000005, 0x4a025a06, - 0x00000006, 0x0201f800, 0x00020381, 0x0201f000, - 0x000208b4, 0x0201f800, 0x001068c1, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, - 0x42003000, 0x00000014, 0x41782800, 0x42002000, - 0x00000002, 0x4d400000, 0x4d440000, 0x59368c03, - 0x42028000, 0x00000029, 0x0201f800, 0x0010962a, - 0x5c028800, 0x5c028000, 0x42000000, 0x0010b663, - 0x0201f800, 0x0010a86e, 0x0201f800, 0x00108df4, - 0x02000000, 0x000208b4, 0x4a025a06, 0x00000029, - 0x0201f800, 0x00020381, 0x0201f000, 0x000208b4, - 0x4933c857, 0x83380580, 0x00000048, 0x04000005, - 0x83380580, 0x00000053, 0x02020800, 0x00100615, - 0x592c0206, 0x82000580, 0x00000007, 0x04000009, - 0x59300011, 0x80000540, 0x04000006, 0x592c080c, - 0x80040480, 0x4802580c, 0x4a025a06, 0x00000015, - 0x592c0206, 0x80000540, 0x04020003, 0x4a025a06, - 0x00000000, 0x0201f800, 0x00020381, 0x0201f000, - 0x000208b4, 0x4933c857, 0x4d2c0000, 0x4c500000, - 0x4c540000, 0x4c580000, 0x0201f800, 0x0010082a, - 0x02000800, 0x00100615, 0x497a5a06, 0x59a8006e, - 0x82000500, 0x0000f000, 0x48025c07, 0x59a80816, - 0x82040c00, 0x00000018, 0x48065a07, 0x412c7800, - 0x4d2c0000, 0x41cca000, 0x42002800, 0x00000001, - 0x42001000, 0x0000002c, 0x82040480, 0x0000002d, - 0x04021006, 0x832cac00, 0x00000009, 0x0201f800, - 0x0010894a, 0x0401f02e, 0x40043000, 0x42000800, - 0x0000002c, 0x832cac00, 0x00000009, 0x0201f800, - 0x0010894a, 0x82183480, 0x0000002c, 0x0201f800, - 0x0010082a, 0x0400001a, 0x80142800, 0x4a025804, - 0x00000110, 0x492c7801, 0x82180c80, 0x0000003d, - 0x04021007, 0x40180800, 0x832cac00, 0x00000005, - 0x0201f800, 0x0010894a, 0x0401f015, 0x82081400, - 0x0000003c, 0x82183480, 0x0000003c, 0x42000800, - 0x0000003c, 0x412c7800, 0x832cac00, 0x00000005, - 0x0201f800, 0x0010894a, 0x0401f7e5, 0x5c025800, - 0x592c0206, 0x8400055e, 0x48025a06, 0x592c0407, - 0x80080540, 0x48025c07, 0x0401f002, 0x5c025800, - 0x813669c0, 0x04000003, 0x59343403, 0x0401f003, - 0x42003000, 0x0000ffff, 0x49325808, 0x481a5c06, - 0x82100580, 0x00000054, 0x04020002, 0x491e5813, - 0x841401c0, 0x80100540, 0x48025804, 0x592c0001, - 0x497a5801, 0x4c000000, 0x0201f800, 0x00020381, - 0x5c025800, 0x812e59c0, 0x040207f9, 0x5c00b000, - 0x5c00a800, 0x5c00a000, 0x5c025800, 0x1c01f000, - 0x4803c856, 0x4c5c0000, 0x4d2c0000, 0x4c500000, - 0x4c540000, 0x4c580000, 0x412cb800, 0x592c040b, - 0x8c000516, 0x04000003, 0x41cca000, 0x0401f003, - 0x83cca400, 0x00000006, 0x4008b000, 0x41781000, - 0x82580480, 0x00000012, 0x04001004, 0x4200b000, - 0x00000012, 0x40001000, 0x4c080000, 0x4d2c0000, - 0x0201f800, 0x0010082a, 0x04000023, 0x5c001800, - 0x492c1801, 0x485a5800, 0x832cac00, 0x00000002, - 0x0201f800, 0x0010a94f, 0x585c040b, 0x8c000500, - 0x0400000e, 0x832c1400, 0x00000002, 0x8c000516, - 0x04000003, 0x82081400, 0x00000006, 0x46001000, - 0x00000001, 0x80081000, 0x46001000, 0x00000900, - 0x84000500, 0x4800bc0b, 0x5c001000, 0x800811c0, - 0x040207da, 0x82000540, 0x00000001, 0x5c00b000, - 0x5c00a800, 0x5c00a000, 0x5c025800, 0x5c00b800, - 0x1c01f000, 0x5c025800, 0x5c001000, 0x0401f7f8, - 0x4933c857, 0x83380d80, 0x00000015, 0x04020003, - 0x0201f000, 0x000208b4, 0x83380d80, 0x00000016, - 0x02020800, 0x00100615, 0x0201f000, 0x000208b4, - 0x4933c857, 0x4d2c0000, 0x4c500000, 0x4c540000, - 0x4c580000, 0x59325808, 0x83cca400, 0x00000006, - 0x59cc1806, 0x820c0580, 0x01000000, 0x04020004, - 0x4200b000, 0x00000002, 0x0401f00f, 0x4200b000, - 0x00000008, 0x832cac00, 0x00000005, 0x0201f800, - 0x0010a93e, 0x8c0c1d00, 0x0400000b, 0x4200b000, - 0x00000008, 0x592e5801, 0x812e59c0, 0x02000800, - 0x00100615, 0x832cac00, 0x00000005, 0x0201f800, - 0x0010a93e, 0x0401f816, 0x5c00b000, 0x5c00a800, - 0x5c00a000, 0x5c025800, 0x1c01f000, 0x4933c857, - 0x4c500000, 0x4c540000, 0x4c580000, 0x83cca400, - 0x00000006, 0x5930a808, 0x8254ac00, 0x00000005, - 0x4200b000, 0x00000007, 0x0201f800, 0x0010a93e, - 0x5c00b000, 0x5c00a800, 0x5c00a000, 0x4933c857, - 0x0201f800, 0x00108df4, 0x02000000, 0x000208b4, - 0x4d2c0000, 0x0201f800, 0x00109360, 0x0402000b, - 0x41780800, 0x4d400000, 0x42028000, 0x00000000, - 0x0201f800, 0x00109204, 0x5c028000, 0x5c025800, - 0x0201f000, 0x000208b4, 0x5931d821, 0x58ef400b, - 0x58ee580d, 0x4a025a04, 0x00000103, 0x58ec0009, - 0x0801f800, 0x5c025800, 0x0201f000, 0x000208b4, - 0x4933c857, 0x59cc1806, 0x820c0580, 0x02000000, - 0x04020014, 0x4a026802, 0x00fffffd, 0x5934000a, - 0x84000504, 0x4802680a, 0x59300808, 0x800409c0, - 0x02000000, 0x000208b4, 0x4a000a04, 0x00000103, - 0x480c0805, 0x5931d821, 0x58ef400b, 0x58ee580d, - 0x58ec0009, 0x0801f800, 0x0201f000, 0x000208b4, - 0x42000000, 0x0010b66b, 0x0201f800, 0x0010a86e, - 0x4c0c0000, 0x0401f804, 0x5c001800, 0x040207eb, - 0x1c01f000, 0x4933c857, 0x4d2c0000, 0x59325808, - 0x812e59c0, 0x04020009, 0x497a6206, 0x497a6205, - 0x4d380000, 0x42027000, 0x00000022, 0x0401fb77, - 0x5c027000, 0x80000580, 0x5c025800, 0x1c01f000, - 0x4933c857, 0x4d2c0000, 0x4c500000, 0x4c540000, - 0x4c580000, 0x59325808, 0x592e5801, 0x832cac00, - 0x00000005, 0x83cca400, 0x00000006, 0x59a8086e, - 0x82040d00, 0x000003ff, 0x82041480, 0x0000000f, - 0x0400101b, 0x4200b000, 0x0000000f, 0x0201f800, - 0x0010a93e, 0x592e5801, 0x832cac00, 0x00000005, - 0x82080c80, 0x0000000f, 0x0400100d, 0x4200b000, - 0x0000000f, 0x0201f800, 0x0010a93e, 0x592e5801, - 0x832cac00, 0x00000005, 0x82041480, 0x0000000f, - 0x04001007, 0x42001000, 0x0000000f, 0x4008b000, - 0x0201f800, 0x0010a93e, 0x0401f004, 0x4004b000, - 0x0201f800, 0x0010a93e, 0x5931d821, 0x58ef400b, - 0x58ee580d, 0x4a025a04, 0x00000103, 0x592e5801, - 0x58ec0009, 0x0801f800, 0x0201f800, 0x000208b4, + 0x80040540, 0x4801a007, 0x5808080a, 0x82040d00, + 0xff000000, 0x59a80010, 0x82000500, 0x00ffffff, + 0x80040540, 0x4801a008, 0x5808000c, 0x9c0001c0, + 0x4801a009, 0x5808000d, 0x9c0001c0, 0x4801a00a, + 0x5808000e, 0x9c0001c0, 0x4801a00b, 0x5808000f, + 0x9c0001c0, 0x4801a00c, 0x59a80002, 0x4801a00d, + 0x59a80003, 0x4801a00e, 0x59a80000, 0x4801a00f, + 0x59a80001, 0x4801a010, 0x58080010, 0x4801a011, + 0x58080011, 0x4801a012, 0x58080012, 0x4801a013, + 0x58080013, 0x4801a014, 0x4979a015, 0x4979a016, + 0x4979a017, 0x4979a018, 0x42000800, 0x00000013, + 0x42001000, 0x0000dc00, 0x0401f0f6, 0x0401fd03, + 0x5930001c, 0x800001c0, 0x04000008, 0x4a01a006, + 0x01000000, 0x4a01a407, 0x00000003, 0x42000800, + 0x00000002, 0x0401f028, 0x4a01a006, 0x02000000, + 0x41780800, 0x836c0580, 0x00000004, 0x04020003, + 0x84040d42, 0x0401f00d, 0x0201f800, 0x0010513b, + 0x04020003, 0x84040d4a, 0x0401f002, 0x84040d48, + 0x59a80026, 0x8c000506, 0x04020003, 0x8c00050a, + 0x04000002, 0x84040d46, 0x4805a207, 0x59c40085, + 0x48031004, 0x4c580000, 0x4c500000, 0x4c540000, + 0x4200b000, 0x00000006, 0x8388a400, 0x00000000, + 0x82d0ac00, 0x00000008, 0x0201f800, 0x0010ab17, + 0x5c00a800, 0x5c00a000, 0x5c00b000, 0x42000800, + 0x00000008, 0x42001000, 0x0000dc00, 0x0401f0c1, + 0x0401fcc0, 0x4a01a006, 0x56000000, 0x59340006, + 0x4801a007, 0x59340007, 0x4801a008, 0x42000800, + 0x00000003, 0x42001000, 0x0000dc00, 0x0401f0b5, + 0x4803c856, 0x0401fcc1, 0x5930081c, 0x800409c0, + 0x0400000e, 0x82040580, 0x0000ffff, 0x04000004, + 0x82040480, 0x00000007, 0x04021008, 0x4a01a006, + 0x01000000, 0x4a01a407, 0x00000003, 0x42000800, + 0x00000002, 0x0401f012, 0x4a01a006, 0x0200001c, + 0x4a01a007, 0x00000001, 0x42001000, 0x0010b4f0, + 0x50080000, 0x9c0001c0, 0x4801a009, 0x59a80010, + 0x4801a00a, 0x59a80002, 0x59a80803, 0x4801a00b, + 0x4805a00c, 0x42000800, 0x00000007, 0x42001000, + 0x0000dc00, 0x0401f08f, 0x4d2c0000, 0x0401fc8d, + 0x59325808, 0x592c0008, 0x82000500, 0x00ffffff, + 0x4801a001, 0x4a01a006, 0x51000000, 0x5c025800, + 0x0201f000, 0x00107344, 0x4803c856, 0x59a80810, + 0x82040d00, 0x000000ff, 0x59325808, 0x59326809, + 0x59a83026, 0x8c18350a, 0x04020008, 0x8c00050e, + 0x04020006, 0x80001d80, 0x59a82010, 0x82102500, + 0x000000ff, 0x0401f001, 0x59300406, 0x4803c857, + 0x82000d80, 0x00000009, 0x04000006, 0x82000d80, + 0x0000000a, 0x0400002e, 0x0201f800, 0x001005d8, + 0x59300015, 0x8c00051e, 0x04020020, 0x42005000, + 0x04000000, 0x42006000, 0x05000000, 0x592c040a, + 0x82000500, 0x00000030, 0x800000e0, 0x80306540, + 0x5934000a, 0x8c000508, 0x04000002, 0x84306546, + 0x41786800, 0x41787800, 0x0401f831, 0x59300c14, + 0x80040000, 0x48026414, 0x40040000, 0x800000d0, + 0x82000540, 0x00000020, 0x4801a403, 0x83180d40, + 0x00000038, 0x42001000, 0x0000c920, 0x0401f860, + 0x0201f000, 0x00106052, 0x59a80026, 0x82000500, + 0x00000028, 0x04000003, 0x497a6a12, 0x0401f7dc, + 0x4a026a12, 0x0000ff00, 0x0401f7d9, 0x42005000, + 0x02000000, 0x42006000, 0x20290000, 0x41786800, + 0x41787800, 0x0401f812, 0x83180d40, 0x00000038, + 0x42001000, 0x0000c9a0, 0x0401f849, 0x42000800, + 0x000007d0, 0x59300011, 0x82000500, 0xfff00000, + 0x80000540, 0x04000003, 0x42000800, 0x00001b58, + 0x41781000, 0x0201f000, 0x00106054, 0x4201a000, + 0x00000000, 0x0401f003, 0x4201a000, 0x00000011, + 0x59340a12, 0x82040d00, 0x0000ff00, 0x59a80010, + 0x82000500, 0x000000ff, 0x900001c0, 0x80040540, + 0x80d00540, 0x44034800, 0x81a5a000, 0x59340002, + 0x82000500, 0x00ffffff, 0x80280540, 0x4801a000, + 0x59a80010, 0x4801a001, 0x4831a002, 0x82340540, + 0x00000000, 0x4801a003, 0x59300402, 0x4801a404, + 0x59300a02, 0x4805a204, 0x8c30652e, 0x04000003, + 0x4805a404, 0x4801a204, 0x483da005, 0x1c01f000, + 0x4803c856, 0x4c040000, 0x0401f822, 0x5c000800, + 0x40040000, 0x80081540, 0x800000c4, 0x82000540, + 0x00002000, 0x4803910a, 0x59b400f6, 0x82000500, + 0x00000018, 0x040207fd, 0x4a0368f0, 0x0010b544, + 0x4a0368f1, 0x0010b54b, 0x480b68f3, 0x4a0378e4, + 0x00008000, 0x0201f000, 0x0010604d, 0x4807c857, + 0x480a2800, 0x4c040000, 0x0401f80a, 0x5c000800, + 0x59b400f6, 0x8c00050a, 0x040207fe, 0x49a768f2, + 0x480768f4, 0x4a0378e4, 0x00008000, 0x1c01f000, + 0x4a0378e4, 0x0000c000, 0x59bc00e4, 0x8c000520, + 0x0400000c, 0x4a0378e4, 0x00008000, 0x42007000, + 0x000003e8, 0x59bc00e4, 0x8c000520, 0x040007f5, + 0x80387040, 0x02000800, 0x001005d8, 0x0401f7fa, + 0x1c01f000, 0x82000500, 0xffff0000, 0x82000580, + 0x01050000, 0x0402000d, 0x599c0818, 0x8c040d10, + 0x0400000a, 0x59a80807, 0x8c040d0a, 0x04000007, + 0x42001000, 0x0000804f, 0x41781800, 0x41782000, + 0x0201f800, 0x00103a3e, 0x1c01f000, 0x41781000, + 0x42026000, 0x0010d1c0, 0x59a8180e, 0x480a6402, + 0x4a026202, 0x0000ffff, 0x80081000, 0x800c1840, + 0x04000004, 0x83326400, 0x00000024, 0x0401f7f8, + 0x1c01f000, 0x4933c857, 0x59300203, 0x82000580, + 0x00000000, 0x0400002c, 0x59300406, 0x4803c857, + 0x82000d80, 0x00000004, 0x04000011, 0x82000d80, + 0x00000001, 0x0400000e, 0x82000d80, 0x00000003, + 0x04000006, 0x82000d80, 0x00000006, 0x04020011, + 0x0201f800, 0x0010a5df, 0x5930001c, 0x800001c0, + 0x02020800, 0x0010984e, 0x0401f00a, 0x5930081e, + 0x4807c857, 0x800409c0, 0x04000006, 0x5804001c, + 0x4803c857, 0x81300580, 0x04020002, 0x4978081c, + 0x497a6008, 0x4a026004, 0x00004000, 0x59a80037, + 0x82000c80, 0x00000051, 0x04001002, 0x80000102, + 0x48026206, 0x497a6205, 0x497a6009, 0x4a026406, + 0x00000007, 0x1c01f000, 0x8166c9c0, 0x0400001c, + 0x41626000, 0x41580000, 0x59300a03, 0x82040d80, + 0x00000000, 0x04000008, 0x83326400, 0x00000024, + 0x81300c80, 0x040017f9, 0x42026000, 0x0010d1c0, + 0x0401f7f6, 0x4933c857, 0x8166c840, 0x83300c00, + 0x00000024, 0x80040480, 0x04021006, 0x4006c000, + 0x4a026203, 0x00000008, 0x813261c0, 0x1c01f000, + 0x4202c000, 0x0010d1c0, 0x0401f7fa, 0x42000000, + 0x0010b854, 0x0201f800, 0x0010aa47, 0x4933c856, + 0x417a6000, 0x0401f7f5, 0x4933c857, 0x83380580, + 0x00000013, 0x0402000b, 0x59300004, 0x8c00053e, + 0x04000007, 0x0201f800, 0x00106c55, 0x0201f800, + 0x00106bbf, 0x0201f800, 0x00106c4b, 0x1c01f000, + 0x4933c857, 0x59880052, 0x80000000, 0x48031052, + 0x1c01f000, 0x4933c857, 0x59300203, 0x82003480, + 0x0000000e, 0x02021800, 0x001005d8, 0x4d2c0000, + 0x0c01f803, 0x5c025800, 0x1c01f000, 0x00107991, + 0x00107efd, 0x0010804a, 0x00107991, 0x001080b0, + 0x00107af5, 0x00107991, 0x00107991, 0x00107e93, + 0x00107991, 0x00107991, 0x00107991, 0x00107991, + 0x00107991, 0x0201f800, 0x001005d8, 0x4933c857, + 0x59300203, 0x82003480, 0x0000000e, 0x02021800, + 0x001005d8, 0x0c01f001, 0x001079a8, 0x00108a3d, + 0x001079a8, 0x001079a8, 0x001079a8, 0x001079a8, + 0x001079a8, 0x001079a8, 0x001089e5, 0x00108a58, + 0x00108ac6, 0x00108a58, 0x00108ac6, 0x001079a8, + 0x0201f800, 0x001005d8, 0x0201f800, 0x001005d8, + 0x4933c857, 0x4d2c0000, 0x59325808, 0x59300203, + 0x82003480, 0x0000000e, 0x02021800, 0x001005d8, + 0x0c01f803, 0x5c025800, 0x1c01f000, 0x001079c5, + 0x001079c5, 0x001079c5, 0x001079e1, 0x00107a2d, + 0x001079c5, 0x001079c5, 0x001079c5, 0x001079c7, + 0x001079c5, 0x001079c5, 0x001079c5, 0x001079c5, + 0x001079c5, 0x0201f800, 0x001005d8, 0x4933c857, + 0x83380580, 0x00000040, 0x02020800, 0x001005d8, + 0x4a026007, 0x00082000, 0x4a026203, 0x00000003, + 0x493a6403, 0x4a025c08, 0x00000001, 0x592c000d, + 0x48026011, 0x497a6013, 0x592c0208, 0x800000c2, + 0x800010c4, 0x80081400, 0x480a6206, 0x0201f800, + 0x00100f4e, 0x42000800, 0x80000060, 0x0201f000, + 0x00106721, 0x4933c857, 0x83380480, 0x00000050, + 0x02021800, 0x001005d8, 0x83380480, 0x00000049, + 0x02001800, 0x001005d8, 0x0c01f001, 0x001079f4, + 0x001079ff, 0x001079f2, 0x001079f2, 0x001079f2, + 0x001079f2, 0x00107a0a, 0x0201f800, 0x001005d8, + 0x4a026203, 0x00000004, 0x4a025c08, 0x00000002, + 0x592c0207, 0x48025c09, 0x592c0209, 0x48025a07, + 0x592c000c, 0x4802580d, 0x1c01f000, 0x0201f800, + 0x00106b8a, 0x0201f800, 0x00109037, 0x04000005, + 0x4a025a06, 0x00000006, 0x0201f800, 0x000202da, + 0x0201f000, 0x0002077d, 0x0201f800, 0x00106b8a, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c, + 0x5c027800, 0x42003000, 0x00000014, 0x41782800, + 0x42002000, 0x00000002, 0x4d400000, 0x4d440000, + 0x59368c03, 0x42028000, 0x00000029, 0x0201f800, + 0x0010985e, 0x5c028800, 0x5c028000, 0x42000000, + 0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800, + 0x00109037, 0x02000000, 0x0002077d, 0x4a025a06, + 0x00000029, 0x0201f800, 0x000202da, 0x0201f000, + 0x0002077d, 0x4933c857, 0x83380580, 0x00000048, + 0x04000005, 0x83380580, 0x00000053, 0x02020800, + 0x001005d8, 0x592c0206, 0x82000580, 0x00000007, + 0x04000009, 0x59300011, 0x80000540, 0x04000006, + 0x592c080c, 0x80040480, 0x4802580c, 0x4a025a06, + 0x00000015, 0x592c0206, 0x80000540, 0x04020003, + 0x4a025a06, 0x00000000, 0x0201f800, 0x000202da, + 0x0201f000, 0x0002077d, 0x4933c857, 0x4d2c0000, + 0x4c500000, 0x4c540000, 0x4c580000, 0x0201f800, + 0x001007e4, 0x02000800, 0x001005d8, 0x497a5a06, + 0x59c80017, 0x82000500, 0x0000f000, 0x48025c07, + 0x59a80816, 0x82040c00, 0x00000018, 0x48065a07, + 0x412c7800, 0x4d2c0000, 0x41cca000, 0x42002800, + 0x00000001, 0x42001000, 0x0000002c, 0x82040480, + 0x0000002d, 0x04021006, 0x832cac00, 0x00000009, + 0x0201f800, 0x00108b96, 0x0401f02e, 0x40043000, + 0x42000800, 0x0000002c, 0x832cac00, 0x00000009, + 0x0201f800, 0x00108b96, 0x82183480, 0x0000002c, + 0x0201f800, 0x001007e4, 0x0400001a, 0x80142800, + 0x4a025804, 0x00000110, 0x492c7801, 0x82180c80, + 0x0000003d, 0x04021007, 0x40180800, 0x832cac00, + 0x00000005, 0x0201f800, 0x00108b96, 0x0401f015, + 0x82081400, 0x0000003c, 0x82183480, 0x0000003c, + 0x42000800, 0x0000003c, 0x412c7800, 0x832cac00, + 0x00000005, 0x0201f800, 0x00108b96, 0x0401f7e5, + 0x5c025800, 0x592c0206, 0x8400055e, 0x48025a06, + 0x592c0407, 0x80080540, 0x48025c07, 0x0401f002, + 0x5c025800, 0x813669c0, 0x04000003, 0x59343403, + 0x0401f003, 0x42003000, 0x0000ffff, 0x49325808, + 0x481a5c06, 0x82100580, 0x00000054, 0x04020002, + 0x491e5813, 0x841401c0, 0x80100540, 0x48025804, + 0x592c0001, 0x497a5801, 0x4c000000, 0x0201f800, + 0x000202da, 0x5c025800, 0x812e59c0, 0x040207f9, 0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800, - 0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c500000, - 0x4c540000, 0x4c580000, 0x59cc0006, 0x82000d80, - 0x01000000, 0x0400002c, 0x59cc0007, 0x9000b1c0, - 0x8258b500, 0x000000ff, 0x8058b104, 0x8258b400, - 0x00000002, 0x82580c80, 0x00000007, 0x04001003, - 0x4200b000, 0x00000006, 0x83cca400, 0x00000006, - 0x59301008, 0x800811c0, 0x02000800, 0x00100615, - 0x8208ac00, 0x00000005, 0x0201f800, 0x0010a93e, - 0x82000d00, 0xff000000, 0x800409c0, 0x04000019, - 0x8200b500, 0x000000ff, 0x8058b104, 0x82580c80, - 0x0000000e, 0x04001003, 0x4200b000, 0x0000000d, - 0x58081001, 0x800811c0, 0x02000800, 0x00100615, - 0x8208ac00, 0x00000005, 0x0201f800, 0x0010a93e, - 0x0401f008, 0x59301008, 0x800811c0, 0x02000800, - 0x00100615, 0x48001005, 0x59cc0007, 0x48001006, - 0x0401ff3b, 0x5c00b000, 0x5c00a800, 0x5c00a000, - 0x5c025800, 0x1c01f000, 0x4933c857, 0x42000800, - 0x00000000, 0x59cc0006, 0x82000580, 0x02000000, - 0x04000003, 0x42000800, 0x00000001, 0x4d2c0000, - 0x59325808, 0x812e59c0, 0x02000800, 0x00100615, - 0x48065a06, 0x0201f800, 0x00020381, 0x5c025800, - 0x0201f000, 0x000208b4, 0x4933c857, 0x4d2c0000, - 0x4c500000, 0x4c540000, 0x4c580000, 0x4200b000, - 0x00000002, 0x59cc0806, 0x82040580, 0x01000000, - 0x04000004, 0x8204b500, 0x0000ffff, 0x8058b104, - 0x83cca400, 0x00000006, 0x59300008, 0x8200ac00, - 0x00000005, 0x0201f800, 0x0010a93e, 0x0401ff0c, + 0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4d2c0000, + 0x4c500000, 0x4c540000, 0x4c580000, 0x412cb800, + 0x592c040b, 0x8c000516, 0x04000003, 0x41cca000, + 0x0401f003, 0x83cca400, 0x00000006, 0x4008b000, + 0x41781000, 0x82580480, 0x00000012, 0x04001004, + 0x4200b000, 0x00000012, 0x40001000, 0x4c080000, + 0x4d2c0000, 0x0201f800, 0x001007e4, 0x04000023, + 0x5c001800, 0x492c1801, 0x485a5800, 0x832cac00, + 0x00000002, 0x0201f800, 0x0010ab28, 0x585c040b, + 0x8c000500, 0x0400000e, 0x832c1400, 0x00000002, + 0x8c000516, 0x04000003, 0x82081400, 0x00000006, + 0x46001000, 0x00000001, 0x80081000, 0x46001000, + 0x00000900, 0x84000500, 0x4800bc0b, 0x5c001000, + 0x800811c0, 0x040207da, 0x82000540, 0x00000001, 0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800, - 0x1c01f000, 0x4933c857, 0x4803c857, 0x4807c857, - 0x480bc857, 0x480fc857, 0x4813c857, 0x481bc857, - 0x492fc857, 0x4d2c0000, 0x4c000000, 0x0201f800, - 0x00100819, 0x5c000000, 0x0400000f, 0x48025803, - 0x5c000000, 0x4802580a, 0x4c000000, 0x481a5801, - 0x48125809, 0x48065804, 0x480a5807, 0x480e5808, - 0x412c1000, 0x0201f800, 0x001008a1, 0x82000540, - 0x00000001, 0x5c025800, 0x1c01f000, 0x4933c857, - 0x4d1c0000, 0x59cc0001, 0x82000500, 0x00ffffff, - 0x59341002, 0x82081500, 0x00ffffff, 0x80080580, - 0x0402001f, 0x497a6205, 0x4d380000, 0x42027000, - 0x00000035, 0x0201f800, 0x00109183, 0x5c027000, - 0x04020012, 0x591c001c, 0x800001c0, 0x0400000f, - 0x497a381c, 0x591c0414, 0x8c000502, 0x02000800, - 0x00100615, 0x84000502, 0x48023c14, 0x591c1406, - 0x82080580, 0x00000003, 0x04000006, 0x82080580, - 0x00000006, 0x04000005, 0x0401fc9e, 0x0401f004, - 0x0401f805, 0x0401f002, 0x0401f8c0, 0x5c023800, - 0x1c01f000, 0x4d2c0000, 0x591e5808, 0x4933c857, - 0x491fc857, 0x493bc857, 0x492fc857, 0x83380580, - 0x00000015, 0x040000b3, 0x83380580, 0x00000016, - 0x040200ae, 0x4d300000, 0x411e6000, 0x59cc0207, - 0x4803c857, 0x82000d00, 0x0000ff00, 0x82040580, - 0x00001700, 0x04000004, 0x82040580, 0x00000300, - 0x0402005b, 0x591c0203, 0x4803c857, 0x82000580, - 0x0000000d, 0x0400003f, 0x812e59c0, 0x0400009a, - 0x591c0202, 0x4803c857, 0x82000580, 0x0000ffff, - 0x0402007e, 0x592c020a, 0x4803c857, 0x82000500, - 0x00000003, 0x82000580, 0x00000002, 0x04020007, - 0x592c080f, 0x591c0011, 0x4803c857, 0x4807c857, - 0x80040580, 0x04020071, 0x591c0414, 0x4803c857, - 0x8c000500, 0x0402006d, 0x41780800, 0x591c1206, - 0x42000000, 0x0000000a, 0x0201f800, 0x001063ee, - 0x592c0406, 0x4803c857, 0x800001c0, 0x0400000c, - 0x80080c80, 0x04001004, 0x02020800, 0x00100615, - 0x80001040, 0x480a5c06, 0x800811c0, 0x04020004, - 0x0201f800, 0x00108b3c, 0x0401f06b, 0x0201f800, - 0x00108ee7, 0x591c0817, 0x591c0018, 0x48065808, - 0x48025809, 0x59300007, 0x8c000500, 0x02020800, - 0x00100ee4, 0x497a3808, 0x0201f800, 0x000201ee, - 0x0402004a, 0x411e6000, 0x0401fc3e, 0x0401f05a, - 0x0401fc6d, 0x04000013, 0x49366009, 0x4a026406, - 0x00000003, 0x492e6008, 0x591c0817, 0x591c1018, - 0x48066017, 0x480a6018, 0x4d380000, 0x591e7403, - 0x4d300000, 0x411e6000, 0x0401fc2e, 0x5c026000, - 0x0201f800, 0x000208d8, 0x5c027000, 0x0401f046, - 0x59a80039, 0x48023a05, 0x0401f043, 0x59cc0407, - 0x82000580, 0x0000000b, 0x04020025, 0x59340a00, - 0x84040d0e, 0x48066a00, 0x592c0a04, 0x82040d00, - 0x000000ff, 0x82040d80, 0x00000014, 0x04000003, - 0x4a02621d, 0x00000003, 0x59300007, 0x8c000500, - 0x02020800, 0x00100ee4, 0x4d400000, 0x42028000, - 0x00000003, 0x592c0a08, 0x0201f800, 0x00104bee, - 0x0201f800, 0x00020381, 0x5c028000, 0x497a6008, - 0x4a026403, 0x00000085, 0x4a026203, 0x00000009, - 0x4a026406, 0x00000002, 0x42000800, 0x8000404b, - 0x0201f800, 0x00020855, 0x0401f01b, 0x59cc0207, - 0x82000580, 0x00002a00, 0x04020004, 0x59a80039, - 0x48023a05, 0x0401f014, 0x812e59c0, 0x02000800, - 0x00100615, 0x4a025a04, 0x00000103, 0x591c0007, - 0x8c000500, 0x02020800, 0x00100ee4, 0x591c0402, - 0x48025c06, 0x4a025a06, 0x00000003, 0x0201f800, - 0x00020381, 0x0201f800, 0x00107698, 0x0201f800, - 0x00104801, 0x5c026000, 0x0201f800, 0x000208b4, - 0x0401f002, 0x5c026000, 0x5c025800, 0x1c01f000, - 0x0401f819, 0x0401f7fd, 0x4933c857, 0x83380580, - 0x00000015, 0x04020004, 0x59a80039, 0x48023a05, - 0x0401f00d, 0x83380580, 0x00000016, 0x0402000d, - 0x4d300000, 0x411e6000, 0x0201f800, 0x0010a3fa, - 0x0201f800, 0x00020831, 0x0201f800, 0x000208b4, - 0x5c026000, 0x497a381c, 0x0201f800, 0x000208b4, - 0x1c01f000, 0x591c0414, 0x84000540, 0x48023c14, - 0x59cc100b, 0x4933c857, 0x491fc857, 0x492fc857, - 0x4803c857, 0x480bc857, 0x8c08153c, 0x04000006, - 0x59a80039, 0x48023a05, 0x497a381c, 0x0201f000, - 0x000208b4, 0x4d300000, 0x411e6000, 0x0201f800, - 0x0010898b, 0x5c026000, 0x591c0406, 0x82000580, - 0x00000000, 0x02000000, 0x000208b4, 0x591c0403, - 0x82000580, 0x00000050, 0x0402000d, 0x4d300000, - 0x411e6000, 0x4a026203, 0x00000001, 0x42000800, - 0x80000043, 0x0201f800, 0x00020855, 0x5c026000, - 0x497a381c, 0x0201f000, 0x000208b4, 0x591c0203, - 0x82000580, 0x0000000d, 0x04000014, 0x812e59c0, - 0x02000800, 0x00100615, 0x591c0203, 0x82000580, - 0x00000004, 0x04020011, 0x592c020a, 0x8c000502, - 0x0400000e, 0x4a023812, 0x0fffffff, 0x592c0208, - 0x8400051e, 0x48025a08, 0x42000000, 0x00000001, - 0x48023a14, 0x0401f021, 0x42000000, 0x00000007, - 0x48023a14, 0x0401f01d, 0x592c020a, 0x4803c857, - 0x8c000500, 0x0402000b, 0x8c000502, 0x040007f7, - 0x591c0414, 0x8c00051c, 0x040207eb, 0x591c0011, - 0x4803c857, 0x800001c0, 0x040007f0, 0x0401f7e6, - 0x8c08153a, 0x040207ed, 0x59cc000a, 0x592c180f, - 0x4803c857, 0x480fc857, 0x800c0580, 0x040007e7, - 0x59cc000a, 0x4803c857, 0x48023816, 0x42000000, - 0x00000005, 0x48023a14, 0x0201f000, 0x0010901b, - 0x4933c857, 0x4d1c0000, 0x59cc0001, 0x59341002, - 0x80080580, 0x82000500, 0x00ffffff, 0x04020041, - 0x59301419, 0x0201f800, 0x001091d9, 0x02000800, - 0x00100615, 0x591c1406, 0x82080580, 0x00000007, - 0x04000038, 0x82080580, 0x00000002, 0x04000035, - 0x82080580, 0x00000000, 0x04000032, 0x591c0202, - 0x82000d80, 0x0000ffff, 0x04000004, 0x59301a19, - 0x800c0580, 0x0402002b, 0x83380580, 0x00000015, - 0x04000026, 0x4d300000, 0x4d2c0000, 0x411e6000, - 0x59325808, 0x0201f800, 0x00108df4, 0x02000800, - 0x00100615, 0x592c0204, 0x82000500, 0x000000ff, - 0x82000580, 0x00000014, 0x04000003, 0x4a02621d, - 0x00000003, 0x42028000, 0x00000003, 0x592c0a08, - 0x0201f800, 0x00104bee, 0x0201f800, 0x00020381, - 0x5c025800, 0x497a6008, 0x4a026403, 0x00000085, - 0x4a026203, 0x00000009, 0x4a026406, 0x00000002, - 0x42000800, 0x8000404b, 0x0201f800, 0x00020855, - 0x5c026000, 0x0401f003, 0x59a80039, 0x48023a05, - 0x497a381c, 0x0201f800, 0x000208b4, 0x5c023800, - 0x1c01f000, 0x4933c857, 0x4c580000, 0x4d2c0000, - 0x59325808, 0x83383580, 0x00000015, 0x04000010, - 0x59342200, 0x84102502, 0x48126a00, 0x0201f800, - 0x00108df4, 0x04000066, 0x0201f800, 0x00109360, - 0x04020005, 0x4200b000, 0x00000002, 0x0201f800, - 0x00109346, 0x0401fa0d, 0x0401f079, 0x83cc1400, - 0x00000008, 0x4200b000, 0x00000002, 0x83341c00, - 0x00000006, 0x0201f800, 0x001082ff, 0x04020015, - 0x83cc1400, 0x0000000a, 0x4200b000, 0x00000002, - 0x83341c00, 0x00000008, 0x0201f800, 0x001082ff, - 0x0402000c, 0x0201f800, 0x00101e1b, 0x59342200, - 0x59cc1007, 0x800811c0, 0x04000003, 0x480a6801, - 0x84102542, 0x8410251a, 0x48126a00, 0x0401f05f, - 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, - 0x5c027800, 0x42000000, 0x0010b663, 0x0201f800, - 0x0010a86e, 0x59340200, 0x84000558, 0x48026a00, - 0x4d300000, 0x0201f800, 0x00020892, 0x02000800, - 0x00100615, 0x49366009, 0x497a6008, 0x4a026406, - 0x00000001, 0x4a026403, 0x00000001, 0x42003000, - 0x00000003, 0x0201f800, 0x0010a766, 0x0201f800, - 0x0010393e, 0x04000011, 0x41782800, 0x42003000, - 0x00000001, 0x4d400000, 0x42028000, 0x00000029, - 0x0201f800, 0x0010a250, 0x5c028000, 0x4a026406, - 0x00000004, 0x4a026203, 0x00000007, 0x4a026420, - 0x00000001, 0x0401f009, 0x4a026203, 0x00000001, - 0x42000800, 0x0000000b, 0x0201f800, 0x001043c7, - 0x0201f800, 0x00106470, 0x5c026000, 0x0201f800, - 0x00108df4, 0x04000022, 0x0201f800, 0x00109360, - 0x04020022, 0x0401f9b1, 0x0401f01d, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x00101de2, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x59340200, - 0x84000558, 0x48026a00, 0x42003000, 0x00000003, - 0x41782800, 0x42002000, 0x00000005, 0x4d400000, - 0x4d440000, 0x59368c03, 0x42028000, 0x00000029, - 0x0201f800, 0x0010962a, 0x5c028800, 0x5c028000, - 0x5c027800, 0x0201f800, 0x00101e1b, 0x0201f800, - 0x000208b4, 0x0401f002, 0x0401fca9, 0x5c025800, - 0x5c00b000, 0x1c01f000, 0x4933c857, 0x41380000, - 0x83383480, 0x00000056, 0x02021800, 0x00100615, - 0x0c01f001, 0x00107c7e, 0x00107c79, 0x00107c7e, - 0x00107c7e, 0x00107c7e, 0x00107c7e, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c7e, 0x00107c77, 0x00107c7e, 0x00107c7e, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c7e, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c7e, - 0x00107c7e, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c7e, 0x00107c77, - 0x00107c77, 0x00107c7e, 0x00107c7e, 0x00107c77, - 0x00107c7e, 0x00107c7e, 0x00107c77, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c7e, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c7e, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c7e, 0x00107c77, - 0x00107c77, 0x00107c77, 0x00107c7e, 0x0201f800, - 0x00100615, 0x4a026203, 0x00000001, 0x493a6403, - 0x0201f000, 0x00106470, 0x4933c857, 0x4a026203, - 0x00000001, 0x493a6403, 0x0201f000, 0x00106470, - 0x59300403, 0x82003480, 0x00000056, 0x02021800, - 0x00100615, 0x83383580, 0x00000013, 0x04000096, - 0x83383580, 0x00000027, 0x0402004c, 0x4933c857, - 0x0201f800, 0x001068f6, 0x0201f800, 0x00108ef1, - 0x0400000b, 0x0201f800, 0x00108f05, 0x04000041, - 0x59300403, 0x82000d80, 0x00000022, 0x04020038, - 0x0401fc61, 0x0400003a, 0x0401f03a, 0x0201f800, - 0x00101e1b, 0x42000800, 0x00000007, 0x0201f800, - 0x001043c7, 0x0401f901, 0x4d440000, 0x59368c03, - 0x83440580, 0x000007fe, 0x04020008, 0x59a81026, - 0x84081540, 0x0201f800, 0x00104e0d, 0x04020002, - 0x8408154a, 0x480b5026, 0x42028000, 0x00000029, - 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, - 0x5c027800, 0x836c0580, 0x00000003, 0x0400000c, - 0x59326809, 0x59340008, 0x800001c0, 0x04020008, - 0x59368c03, 0x4933c857, 0x4937c857, 0x4947c857, - 0x0201f800, 0x00104451, 0x0401f00c, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x42003000, - 0x00000015, 0x41782800, 0x42002000, 0x00000003, - 0x0201f800, 0x0010962a, 0x5c028800, 0x0201f800, - 0x001090ec, 0x0201f000, 0x000208b4, 0x1c01f000, - 0x0401f8ce, 0x0401f7fa, 0x83380580, 0x00000014, - 0x0400000c, 0x4933c857, 0x0201f800, 0x00106cb4, - 0x02020000, 0x001076fb, 0x59300203, 0x82000580, - 0x00000002, 0x040000ef, 0x0201f800, 0x00100615, - 0x4933c857, 0x0201f800, 0x001068f6, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, - 0x42003000, 0x00000016, 0x41782800, 0x4d400000, - 0x4d440000, 0x59368c03, 0x42002000, 0x00000009, - 0x42028000, 0x00000029, 0x0201f800, 0x0010962a, - 0x5c028800, 0x5c028000, 0x42000000, 0x0010b663, - 0x0201f800, 0x0010a86e, 0x0201f800, 0x00108ef1, - 0x0402000c, 0x0201f800, 0x00101e1b, 0x0401f89f, - 0x59340c03, 0x82040580, 0x000007fe, 0x040207c8, - 0x59a80826, 0x84040d40, 0x48075026, 0x0401f7c4, - 0x0201f800, 0x00108f05, 0x04020003, 0x0401f893, - 0x0401f7bf, 0x59300403, 0x82000d80, 0x00000032, - 0x04020004, 0x0201f800, 0x001020b2, 0x0401f7b8, - 0x59300403, 0x82000d80, 0x00000022, 0x04000887, - 0x0401f7b3, 0x4933c857, 0x4803c857, 0x0c01f001, - 0x00107da0, 0x00107da0, 0x00107da0, 0x00107da0, - 0x00107da0, 0x00107da0, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d83, 0x00107da0, - 0x00107d7a, 0x00107da0, 0x00107da0, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, - 0x00107da0, 0x00107da0, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d7a, 0x00107d91, 0x00107da0, - 0x00107d7a, 0x00107d8a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107d8a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107da0, 0x00107d8d, 0x00107d7a, - 0x00107d7c, 0x00107da0, 0x00107d7a, 0x00107da0, - 0x00107da0, 0x00107d7a, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107da0, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107da0, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107da0, 0x00107d7a, 0x00107d7a, - 0x00107d7a, 0x00107da0, 0x0201f800, 0x00100615, - 0x4d2c0000, 0x59325808, 0x0201f800, 0x00020381, - 0x5c025800, 0x0201f000, 0x000208b4, 0x4a026203, - 0x00000005, 0x59a80039, 0x48026205, 0x59a80037, - 0x48026206, 0x1c01f000, 0x5930081e, 0x49780a05, - 0x0401f014, 0x0201f800, 0x001090ec, 0x0201f000, - 0x000208b4, 0x0201f800, 0x001020b2, 0x0201f800, - 0x0010698c, 0x04000005, 0x0201f800, 0x001068f6, - 0x0201f000, 0x000208b4, 0x0201f800, 0x001068f6, - 0x0201f800, 0x000208b4, 0x0201f000, 0x00106982, - 0x4933c857, 0x4a026203, 0x00000002, 0x59a80037, - 0x48026206, 0x1c01f000, 0x4933c857, 0x0201f800, - 0x00108df4, 0x0400002a, 0x4d2c0000, 0x0201f800, - 0x00109360, 0x0402000a, 0x4d400000, 0x42028000, - 0x00000031, 0x42000800, 0x00000004, 0x0201f800, - 0x00109204, 0x5c028000, 0x0401f01c, 0x59300c06, - 0x82040580, 0x00000010, 0x04000004, 0x82040580, - 0x00000011, 0x0402000a, 0x4a025a06, 0x00000031, - 0x4a02580d, 0x00000004, 0x4a02580e, 0x000000ff, - 0x0201f800, 0x00020381, 0x0401f00c, 0x592c0404, - 0x8c00051e, 0x04000009, 0x4a025a04, 0x00000103, - 0x4a025805, 0x01000000, 0x5931d821, 0x58ef400b, - 0x58ec0009, 0x0801f800, 0x5c025800, 0x1c01f000, - 0x4933c857, 0x59340400, 0x82000500, 0x000000ff, - 0x82003480, 0x0000000c, 0x02021800, 0x00100615, - 0x59303403, 0x82180d80, 0x0000004d, 0x02000000, - 0x00109154, 0x82180d80, 0x00000033, 0x02000000, - 0x0010910f, 0x82180d80, 0x00000028, 0x02000000, - 0x00108f46, 0x82180d80, 0x00000029, 0x02000000, - 0x00108f5a, 0x82180d80, 0x0000001f, 0x02000000, - 0x001078af, 0x82180d80, 0x00000055, 0x02000000, - 0x00107888, 0x82180d80, 0x00000000, 0x0400058e, - 0x82180d80, 0x00000022, 0x02000000, 0x001078dc, - 0x82180d80, 0x00000035, 0x02000000, 0x001079d7, - 0x82180d80, 0x00000039, 0x04000536, 0x82180d80, - 0x0000003d, 0x02000000, 0x0010790c, 0x82180d80, - 0x00000044, 0x02000000, 0x00107949, 0x82180d80, - 0x00000049, 0x02000000, 0x0010799e, 0x82180d80, - 0x00000041, 0x02000000, 0x0010798a, 0x82180d80, - 0x00000043, 0x02000000, 0x001092a5, 0x82180d80, - 0x00000051, 0x02000000, 0x0010930b, 0x82180d80, - 0x00000004, 0x04020003, 0x42000000, 0x00000001, - 0x83380d80, 0x00000015, 0x04000006, 0x83380d80, - 0x00000016, 0x02020000, 0x001076fb, 0x0401f226, - 0x4d2c0000, 0x4d3c0000, 0x0c01f804, 0x5c027800, - 0x5c025800, 0x1c01f000, 0x00107e42, 0x00107e46, - 0x00107e42, 0x00107ebb, 0x00107e42, 0x00107fc7, - 0x00108060, 0x00107e42, 0x00107e42, 0x00108029, - 0x00107e42, 0x0010803b, 0x4933c857, 0x497a6007, - 0x59300808, 0x58040000, 0x4a000a04, 0x00000103, - 0x0201f000, 0x000208b4, 0x4933c857, 0x40000000, - 0x40000000, 0x1c01f000, 0x4933c857, 0x59a80016, - 0x82000580, 0x00000074, 0x0402005c, 0x0201f800, - 0x0010a0b1, 0x04020016, 0x0401f85c, 0x0201f800, - 0x00108df4, 0x0400000c, 0x0201f800, 0x00109360, - 0x04020009, 0x41780800, 0x4d400000, 0x42028000, - 0x00000000, 0x0201f800, 0x00109204, 0x5c028000, - 0x0401f003, 0x0201f800, 0x00101e1b, 0x0201f800, - 0x00104711, 0x0201f000, 0x000208b4, 0x0201f800, - 0x00108df4, 0x04000007, 0x0201f800, 0x00109360, - 0x04020004, 0x0401ff3d, 0x0201f000, 0x000208b4, - 0x417a7800, 0x0201f800, 0x00101de2, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x59340200, - 0x84000558, 0x48026a00, 0x42003000, 0x00000003, - 0x0201f800, 0x0010a766, 0x4d300000, 0x0201f800, - 0x00020892, 0x02000800, 0x00100615, 0x49366009, - 0x497a6008, 0x4a026406, 0x00000001, 0x4a026403, - 0x00000001, 0x0201f800, 0x0010393e, 0x04000011, + 0x5c00b800, 0x1c01f000, 0x5c025800, 0x5c001000, + 0x0401f7f8, 0x4933c857, 0x83380d80, 0x00000015, + 0x04020003, 0x0201f000, 0x0002077d, 0x83380d80, + 0x00000016, 0x02020800, 0x001005d8, 0x0201f000, + 0x0002077d, 0x4933c857, 0x4d2c0000, 0x4c500000, + 0x4c540000, 0x4c580000, 0x59325808, 0x83cca400, + 0x00000006, 0x59cc1806, 0x820c0580, 0x01000000, + 0x04020004, 0x4200b000, 0x00000002, 0x0401f00f, + 0x4200b000, 0x00000008, 0x832cac00, 0x00000005, + 0x0201f800, 0x0010ab17, 0x8c0c1d00, 0x0400000b, + 0x4200b000, 0x00000008, 0x592e5801, 0x812e59c0, + 0x02000800, 0x001005d8, 0x832cac00, 0x00000005, + 0x0201f800, 0x0010ab17, 0x0401f816, 0x5c00b000, + 0x5c00a800, 0x5c00a000, 0x5c025800, 0x1c01f000, + 0x4933c857, 0x4c500000, 0x4c540000, 0x4c580000, + 0x83cca400, 0x00000006, 0x5930a808, 0x8254ac00, + 0x00000005, 0x4200b000, 0x00000007, 0x0201f800, + 0x0010ab17, 0x5c00b000, 0x5c00a800, 0x5c00a000, + 0x4933c857, 0x0201f800, 0x00109037, 0x02000000, + 0x0002077d, 0x4d2c0000, 0x0201f800, 0x00109597, + 0x0402000b, 0x41780800, 0x4d400000, 0x42028000, + 0x00000000, 0x0201f800, 0x0010943b, 0x5c028000, + 0x5c025800, 0x0201f000, 0x0002077d, 0x5931d821, + 0x58ef400b, 0x58ee580d, 0x4a025a04, 0x00000103, + 0x58ec0009, 0x0801f800, 0x5c025800, 0x0201f000, + 0x0002077d, 0x4933c857, 0x59cc1806, 0x820c0580, + 0x02000000, 0x04020014, 0x4a026802, 0x00fffffd, + 0x5934000a, 0x84000504, 0x4802680a, 0x59300808, + 0x800409c0, 0x02000000, 0x0002077d, 0x4a000a04, + 0x00000103, 0x480c0805, 0x5931d821, 0x58ef400b, + 0x58ee580d, 0x58ec0009, 0x0801f800, 0x0201f000, + 0x0002077d, 0x42000000, 0x0010b86c, 0x0201f800, + 0x0010aa47, 0x4c0c0000, 0x0401f804, 0x5c001800, + 0x040207eb, 0x1c01f000, 0x4933c857, 0x4d2c0000, + 0x59325808, 0x812e59c0, 0x04020009, 0x497a6206, + 0x497a6205, 0x4d380000, 0x42027000, 0x00000022, + 0x0401fb77, 0x5c027000, 0x80000580, 0x5c025800, + 0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c500000, + 0x4c540000, 0x4c580000, 0x59325808, 0x592e5801, + 0x832cac00, 0x00000005, 0x83cca400, 0x00000006, + 0x59c80817, 0x82040d00, 0x000003ff, 0x82041480, + 0x0000000f, 0x0400101b, 0x4200b000, 0x0000000f, + 0x0201f800, 0x0010ab17, 0x592e5801, 0x832cac00, + 0x00000005, 0x82080c80, 0x0000000f, 0x0400100d, + 0x4200b000, 0x0000000f, 0x0201f800, 0x0010ab17, + 0x592e5801, 0x832cac00, 0x00000005, 0x82041480, + 0x0000000f, 0x04001007, 0x42001000, 0x0000000f, + 0x4008b000, 0x0201f800, 0x0010ab17, 0x0401f004, + 0x4004b000, 0x0201f800, 0x0010ab17, 0x5931d821, + 0x58ef400b, 0x58ee580d, 0x4a025a04, 0x00000103, + 0x592e5801, 0x58ec0009, 0x0801f800, 0x0201f800, + 0x0002077d, 0x5c00b000, 0x5c00a800, 0x5c00a000, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x4d2c0000, + 0x4c500000, 0x4c540000, 0x4c580000, 0x59cc0006, + 0x82000d80, 0x01000000, 0x0400002c, 0x59cc0007, + 0x9000b1c0, 0x8258b500, 0x000000ff, 0x8058b104, + 0x8258b400, 0x00000002, 0x82580c80, 0x00000007, + 0x04001003, 0x4200b000, 0x00000006, 0x83cca400, + 0x00000006, 0x59301008, 0x800811c0, 0x02000800, + 0x001005d8, 0x8208ac00, 0x00000005, 0x0201f800, + 0x0010ab17, 0x82000d00, 0xff000000, 0x800409c0, + 0x04000019, 0x8200b500, 0x000000ff, 0x8058b104, + 0x82580c80, 0x0000000e, 0x04001003, 0x4200b000, + 0x0000000d, 0x58081001, 0x800811c0, 0x02000800, + 0x001005d8, 0x8208ac00, 0x00000005, 0x0201f800, + 0x0010ab17, 0x0401f008, 0x59301008, 0x800811c0, + 0x02000800, 0x001005d8, 0x48001005, 0x59cc0007, + 0x48001006, 0x0401ff3b, 0x5c00b000, 0x5c00a800, + 0x5c00a000, 0x5c025800, 0x1c01f000, 0x4933c857, + 0x42000800, 0x00000000, 0x59cc0006, 0x82000580, + 0x02000000, 0x04000003, 0x42000800, 0x00000001, + 0x4d2c0000, 0x59325808, 0x812e59c0, 0x02000800, + 0x001005d8, 0x48065a06, 0x0201f800, 0x000202da, + 0x5c025800, 0x0201f000, 0x0002077d, 0x4933c857, + 0x4d2c0000, 0x4c500000, 0x4c540000, 0x4c580000, + 0x4200b000, 0x00000002, 0x59cc0806, 0x82040580, + 0x01000000, 0x04000004, 0x8204b500, 0x0000ffff, + 0x8058b104, 0x83cca400, 0x00000006, 0x59300008, + 0x8200ac00, 0x00000005, 0x0201f800, 0x0010ab17, + 0x0401ff0c, 0x5c00b000, 0x5c00a800, 0x5c00a000, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x4803c857, + 0x4807c857, 0x480bc857, 0x480fc857, 0x4813c857, + 0x481bc857, 0x492fc857, 0x4d2c0000, 0x4c000000, + 0x0201f800, 0x001007d3, 0x5c000000, 0x0400000f, + 0x48025803, 0x5c000000, 0x4802580a, 0x4c000000, + 0x481a5801, 0x48125809, 0x48065804, 0x480a5807, + 0x480e5808, 0x412c1000, 0x0201f800, 0x00100858, + 0x82000540, 0x00000001, 0x5c025800, 0x1c01f000, + 0x4933c857, 0x4d1c0000, 0x59cc0001, 0x82000500, + 0x00ffffff, 0x59341002, 0x82081500, 0x00ffffff, + 0x80080580, 0x0402001f, 0x497a6205, 0x4d380000, + 0x42027000, 0x00000035, 0x0201f800, 0x001093ba, + 0x5c027000, 0x04020012, 0x591c001c, 0x800001c0, + 0x0400000f, 0x497a381c, 0x591c0414, 0x8c000502, + 0x02000800, 0x001005d8, 0x84000502, 0x48023c14, + 0x591c1406, 0x82080580, 0x00000003, 0x04000006, + 0x82080580, 0x00000006, 0x04000005, 0x0401fc9e, + 0x0401f004, 0x0401f805, 0x0401f002, 0x0401f8c0, + 0x5c023800, 0x1c01f000, 0x4d2c0000, 0x591e5808, + 0x4933c857, 0x491fc857, 0x493bc857, 0x492fc857, + 0x83380580, 0x00000015, 0x040000b3, 0x83380580, + 0x00000016, 0x040200ae, 0x4d300000, 0x411e6000, + 0x59cc0207, 0x4803c857, 0x82000d00, 0x0000ff00, + 0x82040580, 0x00001700, 0x04000004, 0x82040580, + 0x00000300, 0x0402005b, 0x591c0203, 0x4803c857, + 0x82000580, 0x0000000d, 0x0400003f, 0x812e59c0, + 0x0400009a, 0x591c0202, 0x4803c857, 0x82000580, + 0x0000ffff, 0x0402007e, 0x592c020a, 0x4803c857, + 0x82000500, 0x00000003, 0x82000580, 0x00000002, + 0x04020007, 0x592c080f, 0x591c0011, 0x4803c857, + 0x4807c857, 0x80040580, 0x04020071, 0x591c0414, + 0x4803c857, 0x8c000500, 0x0402006d, 0x41780800, + 0x591c1206, 0x42000000, 0x0000000a, 0x0201f800, + 0x001066a0, 0x592c0406, 0x4803c857, 0x800001c0, + 0x0400000c, 0x80080c80, 0x04001004, 0x02020800, + 0x001005d8, 0x80001040, 0x480a5c06, 0x800811c0, + 0x04020004, 0x0201f800, 0x00108d88, 0x0401f06b, + 0x0201f800, 0x0010912a, 0x591c0817, 0x591c0018, + 0x48065808, 0x48025809, 0x59300007, 0x8c000500, + 0x02020800, 0x00100e99, 0x497a3808, 0x0201f800, + 0x000201ba, 0x0402004a, 0x411e6000, 0x0401fc3e, + 0x0401f05a, 0x0401fc6d, 0x04000013, 0x49366009, + 0x4a026406, 0x00000003, 0x492e6008, 0x591c0817, + 0x591c1018, 0x48066017, 0x480a6018, 0x4d380000, + 0x591e7403, 0x4d300000, 0x411e6000, 0x0401fc2e, + 0x5c026000, 0x0201f800, 0x000207a1, 0x5c027000, + 0x0401f046, 0x59a80039, 0x48023a05, 0x0401f043, + 0x59cc0407, 0x82000580, 0x0000000b, 0x04020025, + 0x59340a00, 0x84040d0e, 0x48066a00, 0x592c0a04, + 0x82040d00, 0x000000ff, 0x82040d80, 0x00000014, + 0x04000003, 0x4a02621d, 0x00000003, 0x59300007, + 0x8c000500, 0x02020800, 0x00100e99, 0x4d400000, + 0x42028000, 0x00000003, 0x592c0a08, 0x0201f800, + 0x00104e70, 0x0201f800, 0x000202da, 0x5c028000, + 0x497a6008, 0x4a026403, 0x00000085, 0x4a026203, + 0x00000009, 0x4a026406, 0x00000002, 0x42000800, + 0x8000404b, 0x0201f800, 0x00020721, 0x0401f01b, + 0x59cc0207, 0x82000580, 0x00002a00, 0x04020004, + 0x59a80039, 0x48023a05, 0x0401f014, 0x812e59c0, + 0x02000800, 0x001005d8, 0x4a025a04, 0x00000103, + 0x591c0007, 0x8c000500, 0x02020800, 0x00100e99, + 0x591c0402, 0x48025c06, 0x4a025a06, 0x00000003, + 0x0201f800, 0x000202c1, 0x0201f800, 0x00107911, + 0x0201f800, 0x001049b2, 0x5c026000, 0x0201f800, + 0x0002077d, 0x0401f002, 0x5c026000, 0x5c025800, + 0x1c01f000, 0x0401f819, 0x0401f7fd, 0x4933c857, + 0x83380580, 0x00000015, 0x04020004, 0x59a80039, + 0x48023a05, 0x0401f00d, 0x83380580, 0x00000016, + 0x0402000d, 0x4d300000, 0x411e6000, 0x0201f800, + 0x0010a5df, 0x0201f800, 0x000206fd, 0x0201f800, + 0x0002077d, 0x5c026000, 0x497a381c, 0x0201f800, + 0x0002077d, 0x1c01f000, 0x591c0414, 0x84000540, + 0x48023c14, 0x59cc100b, 0x4933c857, 0x491fc857, + 0x492fc857, 0x4803c857, 0x480bc857, 0x8c08153c, + 0x04000006, 0x59a80039, 0x48023a05, 0x497a381c, + 0x0201f000, 0x0002077d, 0x4d300000, 0x411e6000, + 0x0201f800, 0x00108bd7, 0x5c026000, 0x591c0406, + 0x82000580, 0x00000000, 0x02000000, 0x0002077d, + 0x591c0403, 0x82000580, 0x00000050, 0x0402000d, + 0x4d300000, 0x411e6000, 0x4a026203, 0x00000001, + 0x42000800, 0x80000043, 0x0201f800, 0x00020721, + 0x5c026000, 0x497a381c, 0x0201f000, 0x0002077d, + 0x591c0203, 0x82000580, 0x0000000d, 0x04000014, + 0x812e59c0, 0x02000800, 0x001005d8, 0x591c0203, + 0x82000580, 0x00000004, 0x04020011, 0x592c020a, + 0x8c000502, 0x0400000e, 0x4a023812, 0x0fffffff, + 0x592c0208, 0x8400051e, 0x48025a08, 0x42000000, + 0x00000001, 0x48023a14, 0x0401f021, 0x42000000, + 0x00000007, 0x48023a14, 0x0401f01d, 0x592c020a, + 0x4803c857, 0x8c000500, 0x0402000b, 0x8c000502, + 0x040007f7, 0x591c0414, 0x8c00051c, 0x040207eb, + 0x591c0011, 0x4803c857, 0x800001c0, 0x040007f0, + 0x0401f7e6, 0x8c08153a, 0x040207ed, 0x59cc000a, + 0x592c180f, 0x4803c857, 0x480fc857, 0x800c0580, + 0x040007e7, 0x59cc000a, 0x4803c857, 0x48023816, + 0x42000000, 0x00000005, 0x48023a14, 0x0201f000, + 0x00109259, 0x4933c857, 0x4d1c0000, 0x59cc0001, + 0x59341002, 0x80080580, 0x82000500, 0x00ffffff, + 0x04020041, 0x59301419, 0x0201f800, 0x00109410, + 0x02000800, 0x001005d8, 0x591c1406, 0x82080580, + 0x00000007, 0x04000038, 0x82080580, 0x00000002, + 0x04000035, 0x82080580, 0x00000000, 0x04000032, + 0x591c0202, 0x82000d80, 0x0000ffff, 0x04000004, + 0x59301a19, 0x800c0580, 0x0402002b, 0x83380580, + 0x00000015, 0x04000026, 0x4d300000, 0x4d2c0000, + 0x411e6000, 0x59325808, 0x0201f800, 0x00109037, + 0x02000800, 0x001005d8, 0x592c0204, 0x82000500, + 0x000000ff, 0x82000580, 0x00000014, 0x04000003, + 0x4a02621d, 0x00000003, 0x42028000, 0x00000003, + 0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800, + 0x000202da, 0x5c025800, 0x497a6008, 0x4a026403, + 0x00000085, 0x4a026203, 0x00000009, 0x4a026406, + 0x00000002, 0x42000800, 0x8000404b, 0x0201f800, + 0x00020721, 0x5c026000, 0x0401f003, 0x59a80039, + 0x48023a05, 0x497a381c, 0x0201f800, 0x0002077d, + 0x5c023800, 0x1c01f000, 0x4933c857, 0x4c580000, + 0x4d2c0000, 0x59325808, 0x83383580, 0x00000015, + 0x04000010, 0x59342200, 0x84102502, 0x48126a00, + 0x0201f800, 0x00109037, 0x04000066, 0x0201f800, + 0x00109597, 0x04020005, 0x4200b000, 0x00000002, + 0x0201f800, 0x0010957d, 0x0401fa0a, 0x0401f079, + 0x83cc1400, 0x00000008, 0x4200b000, 0x00000002, + 0x83341c00, 0x00000006, 0x0201f800, 0x0010855a, + 0x04020015, 0x83cc1400, 0x0000000a, 0x4200b000, + 0x00000002, 0x83341c00, 0x00000008, 0x0201f800, + 0x0010855a, 0x0402000c, 0x0201f800, 0x00102074, + 0x59342200, 0x59cc1007, 0x800811c0, 0x04000003, + 0x480a6801, 0x84102542, 0x8410251a, 0x48126a00, + 0x0401f05f, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x0010203c, 0x5c027800, 0x42000000, 0x0010b864, + 0x0201f800, 0x0010aa47, 0x59340200, 0x84000558, + 0x48026a00, 0x4d300000, 0x0201f800, 0x0002075a, + 0x02000800, 0x001005d8, 0x49366009, 0x497a6008, + 0x4a026406, 0x00000001, 0x4a026403, 0x00000001, + 0x42003000, 0x00000003, 0x0201f800, 0x0010a942, + 0x0201f800, 0x00103b25, 0x04000011, 0x41782800, + 0x42003000, 0x00000001, 0x4d400000, 0x42028000, + 0x00000029, 0x0201f800, 0x0010a43e, 0x5c028000, 0x4a026406, 0x00000004, 0x4a026203, 0x00000007, - 0x4a026420, 0x00000001, 0x42003000, 0x00000001, - 0x4d400000, 0x42028000, 0x00000029, 0x41782800, - 0x0201f800, 0x0010a250, 0x5c028000, 0x0401f009, - 0x42000800, 0x0000000b, 0x0201f800, 0x001043c7, - 0x4a026203, 0x00000001, 0x0201f800, 0x00106470, - 0x5c026000, 0x0401ff05, 0x0201f800, 0x00101e1b, - 0x0201f000, 0x000208b4, 0x0401ff00, 0x42000000, - 0x00000001, 0x0401f0de, 0x4933c857, 0x59340200, - 0x8c000500, 0x0400000d, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x001043bd, 0x5c027800, 0x0201f800, - 0x0010393e, 0x04000005, 0x42000800, 0x00000006, - 0x0201f800, 0x001043c7, 0x1c01f000, 0x4933c857, - 0x59a80816, 0x82040580, 0x00000074, 0x0400000e, - 0x4807c857, 0x82040580, 0x00000100, 0x040200b7, - 0x59cc0408, 0x4803c857, 0x8c000500, 0x040000b3, - 0x59341403, 0x82080580, 0x000007fe, 0x04000006, - 0x0401f0ae, 0x59341403, 0x82080580, 0x000007fe, - 0x0402001a, 0x59a80026, 0x8c000506, 0x04000015, - 0x59cc0000, 0x82000500, 0x000000ff, 0x59a80810, - 0x82040d00, 0x000000ff, 0x80040580, 0x0400000d, - 0x0201f800, 0x00101e1b, 0x0201f800, 0x000208b4, - 0x42000000, 0x0010b651, 0x0201f800, 0x0010a86e, - 0x4202d800, 0x00000001, 0x0201f000, 0x00103f37, - 0x0401fa9c, 0x0401f04c, 0x0201f800, 0x00104480, - 0x59341403, 0x82080580, 0x000007fc, 0x0402001f, - 0x4a026802, 0x00fffffc, 0x0201f800, 0x00108df4, - 0x04000012, 0x0201f800, 0x00109360, 0x0402000f, - 0x0401f8a9, 0x41780800, 0x4d400000, 0x42028000, - 0x00000000, 0x0201f800, 0x00109204, 0x5c028000, - 0x42000800, 0x00000004, 0x0201f800, 0x001043c7, - 0x0201f000, 0x000208b4, 0x42000800, 0x00000004, - 0x0201f800, 0x001043c7, 0x0201f800, 0x00101e1b, - 0x0201f000, 0x000208b4, 0x59a8006f, 0x8c000502, - 0x04000011, 0x0201f800, 0x00104e0d, 0x42001000, - 0x00000010, 0x04020009, 0x59340002, 0x82000500, - 0x00ff0000, 0x82000580, 0x00ff0000, 0x04000006, - 0x42001000, 0x00000008, 0x0201f800, 0x00104ada, - 0x0402005a, 0x0201f800, 0x00108df4, 0x0400005b, - 0x0201f800, 0x00109360, 0x04020005, 0x592c0404, - 0x8c00051c, 0x040207c9, 0x0401f877, 0x42000800, - 0x00000005, 0x0201f800, 0x001043c7, 0x4a026203, - 0x00000001, 0x4a026403, 0x00000003, 0x0201f000, - 0x00106470, 0x59cc0408, 0x8c000518, 0x04000010, - 0x0201f800, 0x001090ab, 0x0201f800, 0x00104e0d, - 0x04000004, 0x59cc0408, 0x8c000516, 0x040207b3, - 0x59a80026, 0x8400054a, 0x48035026, 0x59a80010, - 0x84000570, 0x48038832, 0x0401f7ac, 0x42001000, - 0x000000ef, 0x480b5010, 0x497b8830, 0x84081570, - 0x480b8832, 0x59c40802, 0x84040d4c, 0x48078802, - 0x0201f800, 0x001090d5, 0x59a80026, 0x84000548, - 0x48035026, 0x0201f800, 0x0010a1ec, 0x0402079b, - 0x59a80026, 0x8400054c, 0x48035026, 0x42000800, - 0x00000006, 0x0201f800, 0x001043c7, 0x417a7800, - 0x0201f800, 0x001043bd, 0x42000000, 0x000000e8, - 0x0201f800, 0x001059b9, 0x02000800, 0x001043fc, - 0x02020800, 0x00100615, 0x49366009, 0x59340200, - 0x8400051a, 0x48026a00, 0x42000800, 0x00000003, - 0x0201f800, 0x001043c7, 0x4a026406, 0x00000001, - 0x4a026203, 0x00000001, 0x4a026403, 0x00000002, - 0x0201f000, 0x00106470, 0x0401fe2c, 0x42000000, - 0x00000001, 0x0401f00a, 0x599c0017, 0x8c00050a, - 0x040007ab, 0x42000800, 0x00000004, 0x0201f800, - 0x001043c7, 0x0201f000, 0x000208b4, 0x4933c857, - 0x80003540, 0x04000005, 0x42000800, 0x00000007, - 0x0201f800, 0x001043c7, 0x801831c0, 0x0402000e, - 0x59302008, 0x801021c0, 0x04000004, 0x58100404, - 0x8c00051e, 0x04020008, 0x59341c03, 0x42002000, - 0x00000004, 0x42003000, 0x00000012, 0x0201f800, - 0x001038c7, 0x0201f800, 0x00101e1b, 0x0201f000, - 0x000208b4, 0x4c5c0000, 0x4d2c0000, 0x59325808, - 0x0201f800, 0x00105439, 0x5c025800, 0x59cc0008, - 0x48002805, 0x59cc0009, 0x48002806, 0x49782807, - 0x49782808, 0x49782809, 0x4978280a, 0x59cc0013, - 0x8c00053e, 0x04000009, 0x59cc0414, 0x900001c0, - 0x59ccbc15, 0x805c0540, 0x48002807, 0x59cc0416, - 0x900001c0, 0x48002808, 0x59cc0017, 0x8c00053e, - 0x04000009, 0x59cc0418, 0x900001c0, 0x59ccbc19, - 0x805c0540, 0x48002809, 0x59cc041a, 0x900001c0, - 0x4800280a, 0x5c00b800, 0x1c01f000, 0x4933c857, - 0x59a80016, 0x82000580, 0x00000014, 0x04020048, - 0x59a8006f, 0x8c000502, 0x04000015, 0x0201f800, - 0x00104e0d, 0x42001000, 0x00000010, 0x04020009, - 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, - 0x00ff0000, 0x0400000a, 0x42001000, 0x00000008, - 0x0201f800, 0x00104ada, 0x04000005, 0x59a8006f, - 0x8400054c, 0x4803506f, 0x0401f031, 0x836c0580, - 0x00000003, 0x0402000b, 0x59300008, 0x80000540, - 0x04020008, 0x59341c03, 0x42002000, 0x00000006, - 0x42003000, 0x00000013, 0x0201f800, 0x001038c7, - 0x0201f800, 0x001044e1, 0x0401feb8, 0x0401fa1d, - 0x0402001f, 0x59340404, 0x80000540, 0x0400001c, - 0x42000800, 0x00000006, 0x0201f800, 0x001043c7, - 0x0201f800, 0x00108df4, 0x04000011, 0x0201f800, - 0x00109360, 0x0402000a, 0x41780800, 0x4d400000, - 0x42028000, 0x00000000, 0x0201f800, 0x00109204, - 0x5c028000, 0x0201f000, 0x000208b4, 0x4a025a04, - 0x00000103, 0x4a025805, 0x02000000, 0x0201f800, - 0x00101e1b, 0x0201f000, 0x000208b4, 0x0201f800, - 0x00104a83, 0x0201f800, 0x00108df4, 0x04000007, - 0x0201f800, 0x00109360, 0x04020004, 0x0401fd8b, - 0x0201f000, 0x000208b4, 0x0401fd88, 0x80000580, - 0x59a8006f, 0x8c00050c, 0x04000005, 0x8400050c, - 0x4803506f, 0x82000540, 0x00000001, 0x0401ff60, - 0x1c01f000, 0x4933c857, 0x59a80016, 0x82000580, - 0x00000014, 0x0402000b, 0x42000800, 0x0000000b, - 0x0201f800, 0x001043c7, 0x4a026203, 0x00000001, - 0x4a026403, 0x00000001, 0x0201f000, 0x00106470, - 0x42000000, 0x00000001, 0x0401f74d, 0x4933c857, - 0x40003000, 0x59a80016, 0x82000580, 0x00000004, - 0x0402000a, 0x82183580, 0x0000000b, 0x04020005, - 0x42000800, 0x00000007, 0x0201f800, 0x001043c7, - 0x0201f000, 0x000208b4, 0x42000000, 0x00000001, - 0x0401f73b, 0x4803c857, 0x4d2c0000, 0x4d3c0000, + 0x4a026420, 0x00000001, 0x0401f009, 0x4a026203, + 0x00000001, 0x42000800, 0x0000000b, 0x0201f800, + 0x00104571, 0x0201f800, 0x0010672b, 0x5c026000, + 0x0201f800, 0x00109037, 0x04000022, 0x0201f800, + 0x00109597, 0x04020022, 0x0401f9ae, 0x0401f01d, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x59340200, 0x84000558, 0x48026a00, 0x42003000, + 0x00000003, 0x41782800, 0x42002000, 0x00000005, + 0x4d400000, 0x4d440000, 0x59368c03, 0x42028000, + 0x00000029, 0x0201f800, 0x0010985e, 0x5c028800, + 0x5c028000, 0x5c027800, 0x0201f800, 0x00102074, + 0x0201f800, 0x0002077d, 0x0401f002, 0x0401fca9, + 0x5c025800, 0x5c00b000, 0x1c01f000, 0x4933c857, + 0x41380000, 0x83383480, 0x00000056, 0x02021800, + 0x001005d8, 0x0c01f001, 0x00107ef7, 0x00107ef2, + 0x00107ef7, 0x00107ef7, 0x00107ef7, 0x00107ef7, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef7, 0x00107ef0, 0x00107ef7, + 0x00107ef7, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef7, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef7, 0x00107ef7, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7, + 0x00107ef0, 0x00107ef0, 0x00107ef7, 0x00107ef7, + 0x00107ef0, 0x00107ef7, 0x00107ef7, 0x00107ef0, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7, + 0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7, + 0x0201f800, 0x001005d8, 0x4a026203, 0x00000001, + 0x493a6403, 0x0201f000, 0x0010672b, 0x4933c857, + 0x4a026203, 0x00000001, 0x493a6403, 0x0201f000, + 0x0010672b, 0x4933c857, 0x59300403, 0x82003480, + 0x00000056, 0x02021800, 0x001005d8, 0x83383580, + 0x00000013, 0x04000093, 0x83383580, 0x00000027, + 0x0402004b, 0x0201f800, 0x00106bbf, 0x0201f800, + 0x00109134, 0x0400000b, 0x0201f800, 0x0010914e, + 0x04000041, 0x59300403, 0x82000d80, 0x00000022, + 0x04020038, 0x0401fc61, 0x0400003a, 0x0401f03a, + 0x0201f800, 0x00102074, 0x42000800, 0x00000007, + 0x0201f800, 0x00104571, 0x0401f8fe, 0x4d440000, + 0x59368c03, 0x83440580, 0x000007fe, 0x04020008, + 0x59a81026, 0x84081540, 0x0201f800, 0x0010513b, + 0x04020002, 0x8408154a, 0x480b5026, 0x42028000, + 0x00000029, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x0010203c, 0x5c027800, 0x836c0580, 0x00000003, + 0x0400000c, 0x59326809, 0x59340008, 0x800001c0, + 0x04020008, 0x59368c03, 0x4933c857, 0x4937c857, + 0x4947c857, 0x0201f800, 0x001045fb, 0x0401f00c, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x42003000, 0x00000015, 0x41782800, 0x42002000, + 0x00000003, 0x0201f800, 0x0010985e, 0x5c028800, + 0x0201f800, 0x00109326, 0x0201f000, 0x0002077d, + 0x1c01f000, 0x0401f8cb, 0x0401f7fa, 0x83380580, + 0x00000014, 0x0400000b, 0x0201f800, 0x00106f60, + 0x02020000, 0x00107974, 0x59300203, 0x82000580, + 0x00000002, 0x040000ed, 0x0201f800, 0x001005d8, + 0x0201f800, 0x00106bbf, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x0010203c, 0x5c027800, 0x42003000, + 0x00000016, 0x41782800, 0x4d400000, 0x4d440000, + 0x59368c03, 0x42002000, 0x00000009, 0x42028000, + 0x00000029, 0x0201f800, 0x0010985e, 0x5c028800, + 0x5c028000, 0x42000000, 0x0010b864, 0x0201f800, + 0x0010aa47, 0x0201f800, 0x00109134, 0x0402000c, + 0x0201f800, 0x00102074, 0x0401f89e, 0x59340c03, + 0x82040580, 0x000007fe, 0x040207ca, 0x59a80826, + 0x84040d40, 0x48075026, 0x0401f7c6, 0x0201f800, + 0x0010914e, 0x04020003, 0x0401f892, 0x0401f7c1, + 0x59300403, 0x82000d80, 0x00000032, 0x04020004, + 0x0201f800, 0x0010230c, 0x0401f7ba, 0x59300403, + 0x82000d80, 0x00000022, 0x04000886, 0x0401f7b5, + 0x4803c857, 0x0c01f001, 0x00108016, 0x00108016, + 0x00108016, 0x00108016, 0x00108016, 0x00108016, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00107ff9, 0x00108016, 0x00107ff0, 0x00108016, + 0x00108016, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00107ff0, 0x00107ff0, 0x00108016, 0x00108016, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0, + 0x00108007, 0x00108016, 0x00107ff0, 0x00108000, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108000, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016, + 0x00108003, 0x00107ff0, 0x00107ff2, 0x00108016, + 0x00107ff0, 0x00108016, 0x00108016, 0x00107ff0, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016, + 0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016, + 0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808, + 0x0201f800, 0x000202da, 0x5c025800, 0x0201f000, + 0x0002077d, 0x4a026203, 0x00000005, 0x59a80039, + 0x48026205, 0x59a80037, 0x48026206, 0x1c01f000, + 0x5930081e, 0x49780a05, 0x0401f014, 0x0201f800, + 0x00109326, 0x0201f000, 0x0002077d, 0x0201f800, + 0x0010230c, 0x0201f800, 0x00106c55, 0x04000005, + 0x0201f800, 0x00106bbf, 0x0201f000, 0x0002077d, + 0x0201f800, 0x00106bbf, 0x0201f800, 0x0002077d, + 0x0201f000, 0x00106c4b, 0x4933c857, 0x4a026203, + 0x00000002, 0x59a80037, 0x48026206, 0x1c01f000, + 0x4933c857, 0x0201f800, 0x00109037, 0x0400002a, + 0x4d2c0000, 0x0201f800, 0x00109597, 0x0402000a, + 0x4d400000, 0x42028000, 0x00000031, 0x42000800, + 0x00000004, 0x0201f800, 0x0010943b, 0x5c028000, + 0x0401f01c, 0x59300c06, 0x82040580, 0x00000010, + 0x04000004, 0x82040580, 0x00000011, 0x0402000a, + 0x4a025a06, 0x00000031, 0x4a02580d, 0x00000004, + 0x4a02580e, 0x000000ff, 0x0201f800, 0x000202da, + 0x0401f00c, 0x592c0404, 0x8c00051e, 0x04000009, + 0x4a025a04, 0x00000103, 0x4a025805, 0x01000000, + 0x5931d821, 0x58ef400b, 0x58ec0009, 0x0801f800, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x59340400, + 0x82000500, 0x000000ff, 0x82003480, 0x0000000c, + 0x02021800, 0x001005d8, 0x59303403, 0x82180d80, + 0x0000004d, 0x02000000, 0x0010938b, 0x82180d80, + 0x00000033, 0x02000000, 0x00109349, 0x82180d80, + 0x00000028, 0x02000000, 0x0010918f, 0x82180d80, + 0x00000029, 0x02000000, 0x001091a3, 0x82180d80, + 0x0000001f, 0x02000000, 0x00107b28, 0x82180d80, + 0x00000055, 0x02000000, 0x00107b01, 0x82180d80, + 0x00000000, 0x04000591, 0x82180d80, 0x00000022, + 0x02000000, 0x00107b55, 0x82180d80, 0x00000035, + 0x02000000, 0x00107c50, 0x82180d80, 0x00000039, + 0x04000539, 0x82180d80, 0x0000003d, 0x02000000, + 0x00107b85, 0x82180d80, 0x00000044, 0x02000000, + 0x00107bc2, 0x82180d80, 0x00000049, 0x02000000, + 0x00107c17, 0x82180d80, 0x00000041, 0x02000000, + 0x00107c03, 0x82180d80, 0x00000043, 0x02000000, + 0x001094dc, 0x82180d80, 0x00000051, 0x02000000, + 0x00109542, 0x82180d80, 0x00000004, 0x04020003, + 0x42000000, 0x00000001, 0x83380d80, 0x00000015, + 0x04000006, 0x83380d80, 0x00000016, 0x02020000, + 0x00107974, 0x0401f20f, 0x4d2c0000, 0x4d3c0000, 0x0c01f804, 0x5c027800, 0x5c025800, 0x1c01f000, - 0x00107e42, 0x0010806f, 0x00107e42, 0x001080c4, - 0x00107e42, 0x00108132, 0x00108060, 0x00107e42, - 0x00107e42, 0x00108152, 0x00107e42, 0x00108162, - 0x4933c857, 0x4d1c0000, 0x59301403, 0x82080580, - 0x00000003, 0x04000008, 0x82081580, 0x0000001e, - 0x04020003, 0x0201f800, 0x000208b4, 0x5c023800, - 0x1c01f000, 0x0401ff5a, 0x0401f7fd, 0x4933c857, - 0x0201f800, 0x00108df4, 0x0400000b, 0x0201f800, - 0x00109360, 0x04020008, 0x4200b000, 0x00000002, - 0x0201f800, 0x00109346, 0x0401fd2c, 0x0201f000, - 0x000208b4, 0x0401f8f5, 0x04020030, 0x417a7800, - 0x0201f800, 0x001043bd, 0x417a7800, 0x0201f800, - 0x00101de2, 0x42000000, 0x0010b663, 0x0201f800, - 0x0010a86e, 0x59340200, 0x84000558, 0x48026a00, - 0x4a026403, 0x00000002, 0x42003000, 0x00000003, - 0x0201f800, 0x0010a766, 0x0201f800, 0x0010393e, - 0x04000011, 0x4d400000, 0x41782800, 0x42003000, - 0x00000005, 0x42028000, 0x00000029, 0x0201f800, - 0x0010a250, 0x5c028000, 0x4a026203, 0x00000007, - 0x4a026406, 0x00000004, 0x4a026420, 0x00000001, - 0x1c01f000, 0x42000800, 0x00000003, 0x0201f800, - 0x001043c7, 0x4a026203, 0x00000001, 0x0201f800, - 0x00106470, 0x0401f7f7, 0x59cc0407, 0x82000580, - 0x00000009, 0x0402000a, 0x59340412, 0x82000500, - 0x000000ff, 0x0400000c, 0x80000040, 0x48026c12, - 0x4a026206, 0x0000000a, 0x0401f7ea, 0x59cc0207, - 0x82000500, 0x0000ff00, 0x82000580, 0x00001900, - 0x040007c2, 0x0401fce5, 0x80000580, 0x0401f6c4, - 0x4933c857, 0x59a80032, 0x80000540, 0x04000015, - 0x59340403, 0x82000580, 0x000007fe, 0x04020011, - 0x59a80010, 0x80000000, 0x48035010, 0x417a7800, - 0x0201f800, 0x001043bd, 0x42000800, 0x00000003, - 0x0201f800, 0x001043c7, 0x4a026203, 0x00000001, - 0x4a026403, 0x00000002, 0x0201f000, 0x00106470, - 0x0201f800, 0x00108df4, 0x04000011, 0x0201f800, - 0x00109360, 0x0402000e, 0x4c580000, 0x4200b000, - 0x00000002, 0x0201f800, 0x00109346, 0x5c00b000, - 0x0401fcbe, 0x42000800, 0x00000007, 0x0201f800, - 0x001043c7, 0x0201f000, 0x000208b4, 0x0401fcb7, - 0x59cc3407, 0x82183500, 0x000000ff, 0x82180580, - 0x00000005, 0x0400001c, 0x82180580, 0x0000000b, - 0x04000016, 0x59cc0207, 0x82000500, 0x0000ff00, - 0x04020004, 0x82180580, 0x00000009, 0x04000012, - 0x82000580, 0x00001900, 0x0402000c, 0x82180580, - 0x00000009, 0x0400000c, 0x42000800, 0x00000004, - 0x0201f800, 0x001043c7, 0x0201f800, 0x00101e1b, - 0x0201f000, 0x000208b4, 0x42000000, 0x00000001, - 0x0401f677, 0x0201f800, 0x00108df4, 0x59325808, - 0x04000008, 0x592c0204, 0x82000580, 0x00000139, - 0x040007f6, 0x592c0404, 0x8c00051e, 0x040207f3, - 0x59340403, 0x82000580, 0x000007fe, 0x04020007, - 0x59a80026, 0x84000540, 0x48035026, 0x0201f800, - 0x00104059, 0x0401f7e9, 0x417a7800, 0x0201f800, - 0x00101de2, 0x42003000, 0x00000005, 0x0201f800, - 0x0010a766, 0x42000000, 0x0010b663, 0x0201f800, - 0x0010a86e, 0x0401f7dd, 0x4933c857, 0x0401f84d, - 0x0402000b, 0x42000800, 0x00000005, 0x0201f800, - 0x001043c7, 0x4a026203, 0x00000001, 0x4a026403, - 0x00000003, 0x0201f000, 0x00106470, 0x42000800, - 0x00000004, 0x0201f800, 0x001043c7, 0x0201f800, - 0x00109360, 0x0402000a, 0x4c580000, 0x4200b000, - 0x00000002, 0x0201f800, 0x00109346, 0x5c00b000, - 0x0401fc5a, 0x0201f000, 0x000208b4, 0x0401fc57, - 0x80000580, 0x0401f636, 0x4933c857, 0x0401f82d, - 0x0402000b, 0x42000800, 0x00000009, 0x0201f800, - 0x001043c7, 0x4a026203, 0x00000001, 0x4a026403, - 0x00000005, 0x0201f000, 0x00106470, 0x42000000, - 0x00000001, 0x0401f626, 0x4933c857, 0x0401f81d, + 0x001080b8, 0x001080bc, 0x001080b8, 0x00108131, + 0x001080b8, 0x00108226, 0x001082bf, 0x001080b8, + 0x001080b8, 0x00108288, 0x001080b8, 0x0010829a, + 0x4933c857, 0x497a6007, 0x59300808, 0x58040000, + 0x4a000a04, 0x00000103, 0x0201f000, 0x0002077d, + 0x4933c857, 0x40000000, 0x40000000, 0x1c01f000, + 0x4933c857, 0x59a80016, 0x82000580, 0x00000074, + 0x0402005c, 0x0201f800, 0x0010a2c8, 0x04020016, + 0x0401f85c, 0x0201f800, 0x00109037, 0x0400000c, + 0x0201f800, 0x00109597, 0x04020009, 0x41780800, + 0x4d400000, 0x42028000, 0x00000000, 0x0201f800, + 0x0010943b, 0x5c028000, 0x0401f003, 0x0201f800, + 0x00102074, 0x0201f800, 0x001048c1, 0x0201f000, + 0x0002077d, 0x0201f800, 0x00109037, 0x04000007, + 0x0201f800, 0x00109597, 0x04020004, 0x0401ff3d, + 0x0201f000, 0x0002077d, 0x417a7800, 0x0201f800, + 0x0010203c, 0x42000000, 0x0010b864, 0x0201f800, + 0x0010aa47, 0x59340200, 0x84000558, 0x48026a00, + 0x42003000, 0x00000003, 0x0201f800, 0x0010a942, + 0x4d300000, 0x0201f800, 0x0002075a, 0x02000800, + 0x001005d8, 0x49366009, 0x497a6008, 0x4a026406, + 0x00000001, 0x4a026403, 0x00000001, 0x0201f800, + 0x00103b25, 0x04000011, 0x4a026406, 0x00000004, + 0x4a026203, 0x00000007, 0x4a026420, 0x00000001, + 0x42003000, 0x00000001, 0x4d400000, 0x42028000, + 0x00000029, 0x41782800, 0x0201f800, 0x0010a43e, + 0x5c028000, 0x0401f009, 0x42000800, 0x0000000b, + 0x0201f800, 0x00104571, 0x4a026203, 0x00000001, + 0x0201f800, 0x0010672b, 0x5c026000, 0x0401ff05, + 0x0201f800, 0x00102074, 0x0201f000, 0x0002077d, + 0x0401ff00, 0x42000000, 0x00000001, 0x0401f0c7, + 0x4933c857, 0x59340200, 0x8c000500, 0x0400000d, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00104567, + 0x5c027800, 0x0201f800, 0x00103b25, 0x04000005, + 0x42000800, 0x00000006, 0x0201f800, 0x00104571, + 0x1c01f000, 0x4933c857, 0x59a80816, 0x82040580, + 0x00000074, 0x0400000e, 0x4807c857, 0x82040580, + 0x00000100, 0x040200a0, 0x59cc0408, 0x4803c857, + 0x8c000500, 0x0400009c, 0x59341403, 0x82080580, + 0x000007fe, 0x04000006, 0x0401f097, 0x59341403, + 0x82080580, 0x000007fe, 0x04020003, 0x0401fa9c, + 0x0401f04c, 0x0201f800, 0x0010462a, 0x59341403, + 0x82080580, 0x000007fc, 0x0402001f, 0x4a026802, + 0x00fffffc, 0x0201f800, 0x00109037, 0x04000012, + 0x0201f800, 0x00109597, 0x0402000f, 0x0401f8a9, + 0x41780800, 0x4d400000, 0x42028000, 0x00000000, + 0x0201f800, 0x0010943b, 0x5c028000, 0x42000800, + 0x00000004, 0x0201f800, 0x00104571, 0x0201f000, + 0x0002077d, 0x42000800, 0x00000004, 0x0201f800, + 0x00104571, 0x0201f800, 0x00102074, 0x0201f000, + 0x0002077d, 0x59a80005, 0x8c000514, 0x04000011, + 0x0201f800, 0x0010513b, 0x42001000, 0x00000010, + 0x04020009, 0x59340002, 0x82000500, 0x00ff0000, + 0x82000580, 0x00ff0000, 0x04000006, 0x42001000, + 0x00000008, 0x0201f800, 0x00104c6d, 0x0402005a, + 0x0201f800, 0x00109037, 0x0400005b, 0x0201f800, + 0x00109597, 0x04020005, 0x592c0404, 0x8c00051c, + 0x040207c9, 0x0401f877, 0x42000800, 0x00000005, + 0x0201f800, 0x00104571, 0x4a026203, 0x00000001, + 0x4a026403, 0x00000003, 0x0201f000, 0x0010672b, + 0x59cc0408, 0x8c000518, 0x04000010, 0x0201f800, + 0x001092e5, 0x0201f800, 0x0010513b, 0x04000004, + 0x59cc0408, 0x8c000516, 0x040207b3, 0x59a80026, + 0x8400054a, 0x48035026, 0x59a80010, 0x84000570, + 0x48038832, 0x0401f7ac, 0x42001000, 0x000000ef, + 0x480b5010, 0x497b8830, 0x84081570, 0x480b8832, + 0x59c40802, 0x84040d4c, 0x48078802, 0x0201f800, + 0x0010930f, 0x59a80026, 0x84000548, 0x48035026, + 0x0201f800, 0x0010a3da, 0x0402079b, 0x59a80026, + 0x8400054c, 0x48035026, 0x42000800, 0x00000006, + 0x0201f800, 0x00104571, 0x417a7800, 0x0201f800, + 0x00104567, 0x42000000, 0x000000e8, 0x0201f800, + 0x00105c9a, 0x02000800, 0x001045a6, 0x02020800, + 0x001005d8, 0x49366009, 0x59340200, 0x8400051a, + 0x48026a00, 0x42000800, 0x00000003, 0x0201f800, + 0x00104571, 0x4a026406, 0x00000001, 0x4a026203, + 0x00000001, 0x4a026403, 0x00000002, 0x0201f000, + 0x0010672b, 0x0401fe43, 0x42000000, 0x00000001, + 0x0401f00a, 0x599c0017, 0x8c00050a, 0x040007ab, + 0x42000800, 0x00000004, 0x0201f800, 0x00104571, + 0x0201f000, 0x0002077d, 0x4933c857, 0x80003540, + 0x04000005, 0x42000800, 0x00000007, 0x0201f800, + 0x00104571, 0x801831c0, 0x0402000e, 0x59302008, + 0x801021c0, 0x04000004, 0x58100404, 0x8c00051e, + 0x04020008, 0x59341c03, 0x42002000, 0x00000004, + 0x42003000, 0x00000012, 0x0201f800, 0x00103aae, + 0x0201f800, 0x00102074, 0x0201f000, 0x0002077d, + 0x4c5c0000, 0x4d2c0000, 0x59325808, 0x0201f800, + 0x00105755, 0x5c025800, 0x59cc0008, 0x48002805, + 0x59cc0009, 0x48002806, 0x49782807, 0x49782808, + 0x49782809, 0x4978280a, 0x59cc0013, 0x8c00053e, + 0x04000009, 0x59cc0414, 0x900001c0, 0x59ccbc15, + 0x805c0540, 0x48002807, 0x59cc0416, 0x900001c0, + 0x48002808, 0x59cc0017, 0x8c00053e, 0x04000009, + 0x59cc0418, 0x900001c0, 0x59ccbc19, 0x805c0540, + 0x48002809, 0x59cc041a, 0x900001c0, 0x4800280a, + 0x5c00b800, 0x1c01f000, 0x4933c857, 0x59a80016, + 0x82000580, 0x00000014, 0x04020048, 0x59a80005, + 0x8c000514, 0x04000015, 0x0201f800, 0x0010513b, + 0x42001000, 0x00000010, 0x04020009, 0x59340002, + 0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000, + 0x0400000a, 0x42001000, 0x00000008, 0x0201f800, + 0x00104c6d, 0x04000005, 0x59a80005, 0x84000556, + 0x48035005, 0x0401f031, 0x836c0580, 0x00000003, + 0x0402000b, 0x59300008, 0x80000540, 0x04020008, + 0x59341c03, 0x42002000, 0x00000006, 0x42003000, + 0x00000013, 0x0201f800, 0x00103aae, 0x0201f800, + 0x0010468d, 0x0401fecf, 0x0401fa1d, 0x0402001f, + 0x59340404, 0x80000540, 0x0400001c, 0x42000800, + 0x00000006, 0x0201f800, 0x00104571, 0x0201f800, + 0x00109037, 0x04000011, 0x0201f800, 0x00109597, + 0x0402000a, 0x41780800, 0x4d400000, 0x42028000, + 0x00000000, 0x0201f800, 0x0010943b, 0x5c028000, + 0x0201f000, 0x0002077d, 0x4a025a04, 0x00000103, + 0x4a025805, 0x02000000, 0x0201f800, 0x00102074, + 0x0201f000, 0x0002077d, 0x0201f800, 0x00104c19, + 0x0201f800, 0x00109037, 0x04000007, 0x0201f800, + 0x00109597, 0x04020004, 0x0401fda2, 0x0201f000, + 0x0002077d, 0x0401fd9f, 0x80000580, 0x59a80005, + 0x8c000516, 0x04000005, 0x84000516, 0x48035005, + 0x82000540, 0x00000001, 0x0401ff60, 0x1c01f000, + 0x4933c857, 0x59a80016, 0x82000580, 0x00000014, 0x0402000b, 0x42000800, 0x0000000b, 0x0201f800, - 0x001043c7, 0x4a026203, 0x00000001, 0x4a026403, - 0x00000001, 0x0201f000, 0x00106470, 0x42000000, - 0x00000001, 0x0401f616, 0x4933c857, 0x59cc0407, - 0x82000580, 0x00000003, 0x04020009, 0x59cc0207, - 0x82000500, 0x0000ff00, 0x82000d80, 0x00002a00, - 0x04000003, 0x82000d80, 0x00001e00, 0x1c01f000, - 0x4933c857, 0x82000540, 0x00000001, 0x1c01f000, - 0x4933c857, 0x4d400000, 0x4c580000, 0x59a80026, - 0x82000540, 0x00000003, 0x48035026, 0x0401f85c, - 0x04000038, 0x4d340000, 0x4d440000, 0x59a80026, - 0x84000552, 0x48035026, 0x0201f800, 0x0010393e, - 0x0400000c, 0x42028000, 0x0000002a, 0x42028800, - 0x0000ffff, 0x42003000, 0x00000002, 0x0201f800, - 0x0010a258, 0x59a80805, 0x84040d44, 0x48075005, - 0x42028000, 0x0000002a, 0x4d3c0000, 0x42027800, - 0x00000200, 0x0201f800, 0x00101d90, 0x5c027800, - 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, - 0x0201f800, 0x00101bf0, 0x4200b000, 0x00000010, - 0x42028800, 0x000007f0, 0x4d2c0000, 0x83440580, - 0x000007fe, 0x04000003, 0x0201f800, 0x00104451, - 0x81468800, 0x8058b040, 0x040207f9, 0x5c025800, - 0x59cc0408, 0x8c00051e, 0x04000004, 0x59a80026, - 0x84000512, 0x48035026, 0x5c028800, 0x5c026800, - 0x0201f800, 0x00104480, 0x4a026802, 0x00fffffe, - 0x59a80826, 0x84040d50, 0x59cc0013, 0x8c00053e, - 0x04000003, 0x8c000536, 0x04000004, 0x59cc0017, - 0x8c000536, 0x04020002, 0x84040d10, 0x48075026, - 0x59cc0800, 0x82040d00, 0x00ffffff, 0x48075010, - 0x80040110, 0x4803501d, 0x48038881, 0x0201f800, - 0x00104e0d, 0x04000007, 0x59cc0009, 0x48035035, - 0x59cc000a, 0x48035036, 0x0201f800, 0x001090ab, - 0x5c00b000, 0x5c028000, 0x1c01f000, 0x4933c857, - 0x4c580000, 0x59a80010, 0x82000500, 0x00ffff00, - 0x04000022, 0x59cc1000, 0x82081500, 0x00ffff00, - 0x80080580, 0x04000004, 0x42000000, 0x0010b639, - 0x0401f016, 0x83cc1400, 0x0000000b, 0x4200b000, - 0x00000002, 0x83341c00, 0x00000006, 0x0401f904, - 0x04000004, 0x42000000, 0x0010b63a, 0x0401f00b, - 0x83cc1400, 0x0000000d, 0x4200b000, 0x00000002, - 0x83341c00, 0x00000008, 0x0401f8f9, 0x04000007, - 0x42000000, 0x0010b63b, 0x0201f800, 0x0010a86e, - 0x82000540, 0x00000001, 0x5c00b000, 0x1c01f000, - 0x4933c857, 0x59cc0206, 0x82000580, 0x00000014, - 0x04020016, 0x59cc0407, 0x82000580, 0x00000800, - 0x04020012, 0x59cc0207, 0x8c00051a, 0x0400000d, - 0x82000500, 0x00000f00, 0x82000580, 0x00000100, - 0x04020008, 0x59cc020a, 0x8c000508, 0x04020003, - 0x8c00050a, 0x04000003, 0x80000580, 0x1c01f000, + 0x00104571, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000001, 0x0201f000, 0x0010672b, 0x42000000, + 0x00000001, 0x0401f74d, 0x4933c857, 0x40003000, + 0x59a80016, 0x82000580, 0x00000004, 0x0402000a, + 0x82183580, 0x0000000b, 0x04020005, 0x42000800, + 0x00000007, 0x0201f800, 0x00104571, 0x0201f000, + 0x0002077d, 0x42000000, 0x00000001, 0x0401f73b, + 0x4803c857, 0x4d2c0000, 0x4d3c0000, 0x0c01f804, + 0x5c027800, 0x5c025800, 0x1c01f000, 0x001080b8, + 0x001082ce, 0x001080b8, 0x00108323, 0x001080b8, + 0x00108391, 0x001082bf, 0x001080b8, 0x001080b8, + 0x001083b1, 0x001080b8, 0x001083c1, 0x4933c857, + 0x4d1c0000, 0x59301403, 0x82080580, 0x00000003, + 0x04000008, 0x82081580, 0x0000001e, 0x04020003, + 0x0201f800, 0x0002077d, 0x5c023800, 0x1c01f000, + 0x0401ff5a, 0x0401f7fd, 0x4933c857, 0x0201f800, + 0x00109037, 0x0400000b, 0x0201f800, 0x00109597, + 0x04020008, 0x4200b000, 0x00000002, 0x0201f800, + 0x0010957d, 0x0401fd43, 0x0201f000, 0x0002077d, + 0x0401f8f5, 0x04020030, 0x417a7800, 0x0201f800, + 0x00104567, 0x417a7800, 0x0201f800, 0x0010203c, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x59340200, 0x84000558, 0x48026a00, 0x4a026403, + 0x00000002, 0x42003000, 0x00000003, 0x0201f800, + 0x0010a942, 0x0201f800, 0x00103b25, 0x04000011, + 0x4d400000, 0x41782800, 0x42003000, 0x00000005, + 0x42028000, 0x00000029, 0x0201f800, 0x0010a43e, + 0x5c028000, 0x4a026203, 0x00000007, 0x4a026406, + 0x00000004, 0x4a026420, 0x00000001, 0x1c01f000, + 0x42000800, 0x00000003, 0x0201f800, 0x00104571, + 0x4a026203, 0x00000001, 0x0201f800, 0x0010672b, + 0x0401f7f7, 0x59cc0407, 0x82000580, 0x00000009, + 0x0402000a, 0x59340412, 0x82000500, 0x000000ff, + 0x0400000c, 0x80000040, 0x48026c12, 0x4a026206, + 0x0000000a, 0x0401f7ea, 0x59cc0207, 0x82000500, + 0x0000ff00, 0x82000580, 0x00001900, 0x040007c2, + 0x0401fcfc, 0x80000580, 0x0401f6c4, 0x4933c857, + 0x59a80032, 0x80000540, 0x04000015, 0x59340403, + 0x82000580, 0x000007fe, 0x04020011, 0x59a80010, + 0x80000000, 0x48035010, 0x417a7800, 0x0201f800, + 0x00104567, 0x42000800, 0x00000003, 0x0201f800, + 0x00104571, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000002, 0x0201f000, 0x0010672b, 0x0201f800, + 0x00109037, 0x04000011, 0x0201f800, 0x00109597, + 0x0402000e, 0x4c580000, 0x4200b000, 0x00000002, + 0x0201f800, 0x0010957d, 0x5c00b000, 0x0401fcd5, + 0x42000800, 0x00000007, 0x0201f800, 0x00104571, + 0x0201f000, 0x0002077d, 0x0401fcce, 0x59cc3407, + 0x82183500, 0x000000ff, 0x82180580, 0x00000005, + 0x0400001c, 0x82180580, 0x0000000b, 0x04000016, + 0x59cc0207, 0x82000500, 0x0000ff00, 0x04020004, + 0x82180580, 0x00000009, 0x04000012, 0x82000580, + 0x00001900, 0x0402000c, 0x82180580, 0x00000009, + 0x0400000c, 0x42000800, 0x00000004, 0x0201f800, + 0x00104571, 0x0201f800, 0x00102074, 0x0201f000, + 0x0002077d, 0x42000000, 0x00000001, 0x0401f677, + 0x0201f800, 0x00109037, 0x59325808, 0x04000008, + 0x592c0204, 0x82000580, 0x00000139, 0x040007f6, + 0x592c0404, 0x8c00051e, 0x040207f3, 0x59340403, + 0x82000580, 0x000007fe, 0x04020007, 0x59a80026, + 0x84000540, 0x48035026, 0x0201f800, 0x00104229, + 0x0401f7e9, 0x417a7800, 0x0201f800, 0x0010203c, + 0x42003000, 0x00000005, 0x0201f800, 0x0010a942, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x0401f7dd, 0x4933c857, 0x0401f84d, 0x0402000b, + 0x42000800, 0x00000005, 0x0201f800, 0x00104571, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000003, + 0x0201f000, 0x0010672b, 0x42000800, 0x00000004, + 0x0201f800, 0x00104571, 0x0201f800, 0x00109597, + 0x0402000a, 0x4c580000, 0x4200b000, 0x00000002, + 0x0201f800, 0x0010957d, 0x5c00b000, 0x0401fc71, + 0x0201f000, 0x0002077d, 0x0401fc6e, 0x80000580, + 0x0401f636, 0x4933c857, 0x0401f82d, 0x0402000b, + 0x42000800, 0x00000009, 0x0201f800, 0x00104571, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000005, + 0x0201f000, 0x0010672b, 0x42000000, 0x00000001, + 0x0401f626, 0x4933c857, 0x0401f81d, 0x0402000b, + 0x42000800, 0x0000000b, 0x0201f800, 0x00104571, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000001, + 0x0201f000, 0x0010672b, 0x42000000, 0x00000001, + 0x0401f616, 0x4933c857, 0x59cc0407, 0x82000580, + 0x00000003, 0x04020009, 0x59cc0207, 0x82000500, + 0x0000ff00, 0x82000d80, 0x00002a00, 0x04000003, + 0x82000d80, 0x00001e00, 0x1c01f000, 0x4933c857, 0x82000540, 0x00000001, 0x1c01f000, 0x4933c857, - 0x4943c857, 0x493fc857, 0x4c5c0000, 0x4d300000, - 0x4d340000, 0x4d2c0000, 0x4d380000, 0x4130b800, - 0x42026000, 0x0010cfc0, 0x59a8000e, 0x81640480, - 0x040210c1, 0x8d3e7d12, 0x04000004, 0x405c0000, - 0x81300580, 0x040000b7, 0x59300406, 0x82000c80, - 0x00000012, 0x04021015, 0x59326809, 0x0c01f001, - 0x001082f4, 0x0010825f, 0x00108278, 0x00108283, - 0x00108258, 0x00108271, 0x001082ac, 0x001082f4, - 0x00108256, 0x001082c0, 0x001082cf, 0x00108256, - 0x00108256, 0x00108256, 0x00108256, 0x001082f4, - 0x001082e5, 0x001082dd, 0x0201f800, 0x00100615, - 0x8d3e7d18, 0x04000003, 0x8d3e7d16, 0x04000004, - 0x59300420, 0x8c000500, 0x04020096, 0x59300403, - 0x82000580, 0x00000043, 0x04000092, 0x0201f800, - 0x00108ef1, 0x02000800, 0x00101e1b, 0x0201f800, - 0x00108f05, 0x02000800, 0x00107da6, 0x8d3e7d06, - 0x04000086, 0x0201f800, 0x0010909d, 0x04000085, - 0x0401f082, 0x8d3e7d18, 0x04000003, 0x8d3e7d16, - 0x04000004, 0x59300420, 0x8c000500, 0x0402007d, - 0x59325808, 0x0201f800, 0x00108df4, 0x04000077, - 0x49425a06, 0x497a5c09, 0x0201f800, 0x00020381, - 0x0201f800, 0x00108ee7, 0x0401f070, 0x813669c0, - 0x02000800, 0x00100615, 0x8d3e7d06, 0x04000004, - 0x59340200, 0x8c00050e, 0x0402006a, 0x59300004, - 0x8400055c, 0x48026004, 0x59300203, 0x82000580, - 0x00000004, 0x02000800, 0x00100ee4, 0x59325808, - 0x0201f800, 0x00108df4, 0x0400005c, 0x4a025a04, - 0x00000103, 0x59300402, 0x48025c06, 0x592c0408, - 0x8c000512, 0x04000006, 0x4d2c0000, 0x592e5809, - 0x0201f800, 0x00100843, 0x5c025800, 0x49425a06, - 0x497a5c09, 0x0201f800, 0x00109365, 0x0201f800, - 0x00020381, 0x0201f800, 0x00108ee7, 0x0401f047, - 0x8c000518, 0x04000047, 0x59300203, 0x82000580, - 0x00000004, 0x02000800, 0x00100ee4, 0x59325808, - 0x0201f800, 0x00108df4, 0x0400003c, 0x49425a06, - 0x497a5c09, 0x0201f800, 0x0010a4ae, 0x0201f800, - 0x00109365, 0x0201f800, 0x00020381, 0x0401f033, - 0x0201f800, 0x0010600e, 0x04000032, 0x59300203, - 0x82000580, 0x00000004, 0x04020004, 0x0201f800, - 0x00100ee4, 0x0401f02b, 0x42027000, 0x00000047, - 0x0201f800, 0x000208d8, 0x0401f026, 0x59300203, - 0x82000580, 0x00000004, 0x02000800, 0x00100ee4, - 0x59325808, 0x0201f800, 0x00108df4, 0x0400001b, - 0x49425a06, 0x497a5c09, 0x0201f800, 0x00020381, - 0x0401f016, 0x833c0500, 0x00001800, 0x04000015, - 0x8d3e7d16, 0x04020013, 0x59325817, 0x0201f800, - 0x00100843, 0x59300203, 0x82000580, 0x00000004, - 0x02000800, 0x00100ee4, 0x59325808, 0x0201f800, - 0x00108df4, 0x04000005, 0x49425a06, 0x497a5c09, - 0x0201f800, 0x00020381, 0x0201f800, 0x00107698, - 0x83326400, 0x00000024, 0x41580000, 0x81300480, - 0x0400173e, 0x5c027000, 0x5c025800, 0x5c026800, - 0x5c026000, 0x5c00b800, 0x1c01f000, 0x5c000000, - 0x4c000000, 0x4803c857, 0x480bc857, 0x480fc857, - 0x485bc857, 0x50080800, 0x500c0000, 0x80042580, - 0x04020007, 0x80081000, 0x800c1800, 0x8058b040, - 0x040207f9, 0x80000580, 0x1c01f000, 0x4803c857, - 0x4807c857, 0x480bc857, 0x480fc857, 0x80040480, - 0x04001006, 0x42000000, 0x00000001, 0x82040d40, - 0x00000001, 0x1c01f000, 0x41780000, 0x0401f7fc, - 0x83380480, 0x00000053, 0x02021800, 0x00100615, - 0x83380480, 0x0000004b, 0x02001800, 0x00100615, - 0x0c01f001, 0x0010832f, 0x0010832f, 0x0010832f, - 0x0010832f, 0x0010832d, 0x0010832d, 0x0010832d, - 0x0010832f, 0x0201f800, 0x00100615, 0x493bc857, - 0x4a026203, 0x0000000d, 0x493a6403, 0x42000800, - 0x80000000, 0x0201f000, 0x00020855, 0x83380580, - 0x00000013, 0x04020008, 0x59300403, 0x82000580, - 0x00000050, 0x02020800, 0x00100615, 0x0201f000, - 0x000208b4, 0x4933c857, 0x83380580, 0x00000027, - 0x04020030, 0x4933c857, 0x0201f800, 0x001068f6, - 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, - 0x5c027800, 0x42000000, 0x0010b663, 0x0201f800, - 0x0010a86e, 0x4d2c0000, 0x59325808, 0x0201f800, - 0x00108df4, 0x492fc857, 0x0400000d, 0x4a025a04, - 0x00000103, 0x59300c02, 0x48065c06, 0x4a025a06, - 0x00000029, 0x497a5c09, 0x592c0c08, 0x84040d50, - 0x48065c08, 0x0201f800, 0x00020381, 0x5c025800, - 0x42003000, 0x00000015, 0x41782800, 0x42002000, - 0x00000003, 0x4d400000, 0x4d440000, 0x59368c03, - 0x42028000, 0x00000029, 0x0201f800, 0x0010962a, - 0x5c028800, 0x5c028000, 0x0201f000, 0x000208b4, - 0x83380580, 0x00000014, 0x0402000d, 0x59300403, - 0x82000c80, 0x00000053, 0x02021800, 0x00100615, - 0x82000480, 0x00000040, 0x02001800, 0x00100615, - 0x4933c857, 0x4803c857, 0x0c01f00e, 0x83380580, - 0x00000053, 0x0400000a, 0x83380580, 0x00000048, - 0x02020800, 0x00100615, 0x59300403, 0x82000580, - 0x00000050, 0x02020800, 0x00100615, 0x1c01f000, - 0x001083a5, 0x001083a3, 0x001083a3, 0x001083a3, - 0x001083a3, 0x001083a3, 0x001083a3, 0x001083a3, - 0x001083a3, 0x001083a3, 0x001083a3, 0x001083bc, - 0x001083bc, 0x001083bc, 0x001083bc, 0x001083a3, - 0x001083bc, 0x001083a3, 0x001083bc, 0x0201f800, - 0x00100615, 0x4933c857, 0x0201f800, 0x001068f6, - 0x0201f800, 0x00108df4, 0x02000000, 0x000208b4, - 0x4d2c0000, 0x59325808, 0x4a025a04, 0x00000103, - 0x59300402, 0x48025c06, 0x4a025a06, 0x00000006, - 0x497a5c09, 0x0201f800, 0x00020381, 0x5c025800, - 0x0201f800, 0x00108ee7, 0x0201f000, 0x000208b4, - 0x4933c857, 0x0201f800, 0x001068f6, 0x0201f000, - 0x000208b4, 0x0201f800, 0x00100615, 0x5930001c, - 0x800001c0, 0x02020800, 0x0010961a, 0x59300004, - 0x8c00053e, 0x04020029, 0x59325808, 0x592c0c08, - 0x59cc2a08, 0x82141d00, 0x00000c00, 0x04000002, - 0x59cc1809, 0x84040d58, 0x48065c08, 0x82143500, - 0x00000fff, 0x04020027, 0x59340200, 0x8c00050e, - 0x04020080, 0x0201f800, 0x00020962, 0x04020006, - 0x4a025a06, 0x00000000, 0x59300811, 0x800409c0, - 0x04020951, 0x4a025a04, 0x00000103, 0x48065807, - 0x480e580a, 0x48165c09, 0x59300c02, 0x48065c06, - 0x0201f800, 0x00020381, 0x0201f800, 0x00104801, - 0x59cc0208, 0x8c000518, 0x02020000, 0x00108f88, - 0x0201f000, 0x000208b4, 0x0201f800, 0x00106cb4, - 0x040007d6, 0x4d3c0000, 0x42027800, 0x00000002, - 0x0201f800, 0x00108997, 0x5c027800, 0x0401f7cf, - 0x4817c857, 0x480fc857, 0x82180500, 0x000000ff, - 0x0400000e, 0x592c0204, 0x82000500, 0x000000ff, - 0x82000580, 0x00000048, 0x04020008, 0x592c0407, - 0x800001c0, 0x04000005, 0x0201f800, 0x0010950b, - 0x0201f000, 0x00109553, 0x82180d00, 0x00000c00, - 0x04000004, 0x59340200, 0x8c00050e, 0x04020032, - 0x4a025a06, 0x00000000, 0x41782000, 0x8c183510, - 0x04000007, 0x59cc000c, 0x82000500, 0x000000ff, - 0x04000002, 0x4803c857, 0x59cc200b, 0x4812580c, - 0x41780000, 0x8c183512, 0x04000002, 0x59cc000a, - 0x4802580b, 0x80100c00, 0x040007b8, 0x82041480, - 0x0000001d, 0x04001006, 0x592c0404, 0x8c00051e, - 0x0400000e, 0x42000800, 0x0000001c, 0x4c500000, - 0x4c540000, 0x83cca400, 0x0000000c, 0x832cac00, - 0x0000000d, 0x0201f800, 0x00108953, 0x5c00a800, - 0x5c00a000, 0x0401f7a5, 0x59300011, 0x59301402, - 0x480a5c06, 0x48025807, 0x480e580a, 0x48165c09, - 0x0201f800, 0x001088fc, 0x0201f800, 0x00108938, - 0x0401f7a6, 0x592c020a, 0x8c000502, 0x040007cd, - 0x592c0208, 0x8c00050e, 0x040207ca, 0x59300011, - 0x800c0d80, 0x040007c7, 0x4803c857, 0x480fc857, - 0x8c183514, 0x02000000, 0x00108fc6, 0x80000540, - 0x040007c0, 0x4807c856, 0x0201f000, 0x00108fc6, - 0x592c020a, 0x8c000502, 0x04000782, 0x59300011, - 0x800001c0, 0x0400077f, 0x592c0208, 0x8c00050e, - 0x0402077c, 0x0201f000, 0x00108fc6, 0x59cc2006, - 0x59cc2807, 0x0401f037, 0x0401f036, 0x1c01f000, - 0x4933c857, 0x5930001c, 0x800001c0, 0x02020800, - 0x0010961a, 0x59325808, 0x592c0c08, 0x41782800, - 0x41781800, 0x84040d58, 0x48065c08, 0x41783000, - 0x59340200, 0x8c00050e, 0x0402001a, 0x0201f800, - 0x00020962, 0x04020007, 0x4a025a06, 0x00000000, - 0x59300811, 0x4807c857, 0x800409c0, 0x040208b2, - 0x4a025a04, 0x00000103, 0x48065807, 0x480e580a, - 0x48165c09, 0x4933c857, 0x59300c02, 0x48065c06, - 0x0201f800, 0x00109365, 0x0201f800, 0x00020381, - 0x0201f800, 0x00104801, 0x0201f000, 0x000208b4, - 0x592c020a, 0x8c000502, 0x040007e8, 0x59300011, - 0x4803c857, 0x800001c0, 0x040007e4, 0x592c0208, - 0x8c00050e, 0x040207e1, 0x0201f000, 0x00108fc6, + 0x4d400000, 0x4c580000, 0x59a80026, 0x82000540, + 0x00000003, 0x48035026, 0x0401f85c, 0x04000038, + 0x4d340000, 0x4d440000, 0x59a80026, 0x84000552, + 0x48035026, 0x0201f800, 0x00103b25, 0x0400000c, + 0x42028000, 0x0000002a, 0x42028800, 0x0000ffff, + 0x42003000, 0x00000002, 0x0201f800, 0x0010a446, + 0x59a80805, 0x84040d44, 0x48075005, 0x42028000, + 0x0000002a, 0x4d3c0000, 0x42027800, 0x00000204, + 0x0201f800, 0x00101fe5, 0x5c027800, 0x42000000, + 0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800, + 0x00101e45, 0x4200b000, 0x00000010, 0x42028800, + 0x000007f0, 0x4d2c0000, 0x83440580, 0x000007fe, + 0x04000003, 0x0201f800, 0x001045fb, 0x81468800, + 0x8058b040, 0x040207f9, 0x5c025800, 0x59cc0408, + 0x8c00051e, 0x04000004, 0x59a80026, 0x84000512, + 0x48035026, 0x5c028800, 0x5c026800, 0x0201f800, + 0x0010462a, 0x4a026802, 0x00fffffe, 0x59a80826, + 0x84040d50, 0x59cc0013, 0x8c00053e, 0x04000003, + 0x8c000536, 0x04000004, 0x59cc0017, 0x8c000536, + 0x04020002, 0x84040d10, 0x48075026, 0x59cc0800, + 0x82040d00, 0x00ffffff, 0x48075010, 0x80040110, + 0x4803501d, 0x48038881, 0x0201f800, 0x0010513b, + 0x04000007, 0x59cc0009, 0x48035035, 0x59cc000a, + 0x48035036, 0x0201f800, 0x001092e5, 0x5c00b000, + 0x5c028000, 0x1c01f000, 0x4933c857, 0x4c580000, + 0x59a80010, 0x82000500, 0x00ffff00, 0x04000022, + 0x59cc1000, 0x82081500, 0x00ffff00, 0x80080580, + 0x04000004, 0x42000000, 0x0010b83b, 0x0401f016, + 0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002, + 0x83341c00, 0x00000006, 0x0401f900, 0x04000004, + 0x42000000, 0x0010b83c, 0x0401f00b, 0x83cc1400, + 0x0000000d, 0x4200b000, 0x00000002, 0x83341c00, + 0x00000008, 0x0401f8f5, 0x04000007, 0x42000000, + 0x0010b83d, 0x0201f800, 0x0010aa47, 0x82000540, + 0x00000001, 0x5c00b000, 0x1c01f000, 0x4933c857, + 0x59cc0206, 0x82000580, 0x00000014, 0x04020016, + 0x59cc0407, 0x82000580, 0x00000800, 0x04020012, + 0x59cc0207, 0x8c00051a, 0x0400000d, 0x82000500, + 0x00000f00, 0x82000580, 0x00000100, 0x04020008, + 0x59cc020a, 0x8c000508, 0x04020003, 0x8c00050a, + 0x04000003, 0x80000580, 0x1c01f000, 0x82000540, + 0x00000001, 0x1c01f000, 0x4933c857, 0x4943c857, + 0x493fc857, 0x4c5c0000, 0x4d300000, 0x4d340000, + 0x4d2c0000, 0x4d380000, 0x4130b800, 0x42026000, + 0x0010d1c0, 0x59a8000e, 0x81640480, 0x040210bd, + 0x8d3e7d12, 0x04000004, 0x405c0000, 0x81300580, + 0x040000b3, 0x59300406, 0x82000c80, 0x00000012, + 0x04021015, 0x59326809, 0x0c01f001, 0x0010854f, + 0x001084bc, 0x001084d3, 0x001084de, 0x001084b7, + 0x001084ce, 0x00108507, 0x0010854f, 0x001084b5, + 0x0010851b, 0x0010852a, 0x001084b5, 0x001084b5, + 0x001084b5, 0x001084b5, 0x0010854f, 0x00108540, + 0x00108538, 0x0201f800, 0x001005d8, 0x8d3e7d18, + 0x04000004, 0x59300420, 0x8c000500, 0x04020094, + 0x59300403, 0x82000580, 0x00000043, 0x04000090, + 0x0201f800, 0x00109134, 0x02000800, 0x00102074, + 0x0201f800, 0x0010914e, 0x02000800, 0x0010801c, + 0x8d3e7d06, 0x04000084, 0x0201f800, 0x001092d7, + 0x04000083, 0x0401f080, 0x8d3e7d16, 0x04000004, + 0x59300420, 0x8c000500, 0x0402007d, 0x59325808, + 0x0201f800, 0x00109037, 0x04000077, 0x49425a06, + 0x497a5c09, 0x0201f800, 0x000202da, 0x0201f800, + 0x0010912a, 0x0401f070, 0x813669c0, 0x02000800, + 0x001005d8, 0x8d3e7d06, 0x04000004, 0x59340200, + 0x8c00050e, 0x0402006a, 0x59300004, 0x8400055c, + 0x48026004, 0x59300203, 0x82000580, 0x00000004, + 0x02000800, 0x00100e99, 0x59325808, 0x0201f800, + 0x00109037, 0x0400005c, 0x4a025a04, 0x00000103, + 0x59300402, 0x48025c06, 0x592c0408, 0x8c000512, + 0x04000006, 0x4d2c0000, 0x592e5809, 0x0201f800, + 0x001007fd, 0x5c025800, 0x49425a06, 0x497a5c09, + 0x0201f800, 0x0010959c, 0x0201f800, 0x000202da, + 0x0201f800, 0x0010912a, 0x0401f047, 0x8c000518, + 0x04000047, 0x59300203, 0x82000580, 0x00000004, + 0x02000800, 0x00100e99, 0x59325808, 0x0201f800, + 0x00109037, 0x0400003c, 0x49425a06, 0x497a5c09, + 0x0201f800, 0x0010a693, 0x0201f800, 0x0010959c, + 0x0201f800, 0x000202da, 0x0401f033, 0x0201f800, + 0x001062d5, 0x04000032, 0x59300203, 0x82000580, + 0x00000004, 0x04020004, 0x0201f800, 0x00100e99, + 0x0401f02b, 0x42027000, 0x00000047, 0x0201f800, + 0x000207a1, 0x0401f026, 0x59300203, 0x82000580, + 0x00000004, 0x02000800, 0x00100e99, 0x59325808, + 0x0201f800, 0x00109037, 0x0400001b, 0x49425a06, + 0x497a5c09, 0x0201f800, 0x000202da, 0x0401f016, + 0x833c0500, 0x00001800, 0x04000015, 0x8d3e7d16, + 0x04020013, 0x59325817, 0x0201f800, 0x001007fd, + 0x59300203, 0x82000580, 0x00000004, 0x02000800, + 0x00100e99, 0x59325808, 0x0201f800, 0x00109037, + 0x04000005, 0x49425a06, 0x497a5c09, 0x0201f800, + 0x000202da, 0x0201f800, 0x00107911, 0x83326400, + 0x00000024, 0x41580000, 0x81300480, 0x04001742, + 0x5c027000, 0x5c025800, 0x5c026800, 0x5c026000, + 0x5c00b800, 0x1c01f000, 0x5c000000, 0x4c000000, + 0x4803c857, 0x480bc857, 0x480fc857, 0x485bc857, + 0x50080800, 0x500c0000, 0x80042580, 0x04020007, + 0x80081000, 0x800c1800, 0x8058b040, 0x040207f9, + 0x80000580, 0x1c01f000, 0x4803c857, 0x4807c857, + 0x480bc857, 0x480fc857, 0x80040480, 0x04001006, + 0x42000000, 0x00000001, 0x82040d40, 0x00000001, + 0x1c01f000, 0x41780000, 0x0401f7fc, 0x83380480, + 0x00000053, 0x02021800, 0x001005d8, 0x83380480, + 0x0000004b, 0x02001800, 0x001005d8, 0x0c01f001, + 0x0010858a, 0x0010858a, 0x0010858a, 0x0010858a, + 0x00108588, 0x00108588, 0x00108588, 0x0010858a, + 0x0201f800, 0x001005d8, 0x493bc857, 0x4a026203, + 0x0000000d, 0x493a6403, 0x42000800, 0x80000000, + 0x0201f000, 0x00020721, 0x83380580, 0x00000013, + 0x04020008, 0x59300403, 0x82000580, 0x00000050, + 0x02020800, 0x001005d8, 0x0201f000, 0x0002077d, + 0x4933c857, 0x83380580, 0x00000027, 0x04020030, + 0x4933c857, 0x0201f800, 0x00106bbf, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037, + 0x492fc857, 0x0400000d, 0x4a025a04, 0x00000103, + 0x59300c02, 0x48065c06, 0x4a025a06, 0x00000029, + 0x497a5c09, 0x592c0c08, 0x84040d50, 0x48065c08, + 0x0201f800, 0x000202da, 0x5c025800, 0x42003000, + 0x00000015, 0x41782800, 0x42002000, 0x00000003, + 0x4d400000, 0x4d440000, 0x59368c03, 0x42028000, + 0x00000029, 0x0201f800, 0x0010985e, 0x5c028800, + 0x5c028000, 0x0201f000, 0x0002077d, 0x83380580, + 0x00000014, 0x0402000c, 0x59300403, 0x82000c80, + 0x00000053, 0x02021800, 0x001005d8, 0x82000480, + 0x00000040, 0x02001800, 0x001005d8, 0x4803c857, + 0x0c01f00e, 0x83380580, 0x00000053, 0x0400000a, + 0x83380580, 0x00000048, 0x02020800, 0x001005d8, + 0x59300403, 0x82000580, 0x00000050, 0x02020800, + 0x001005d8, 0x1c01f000, 0x001085ff, 0x001085fd, + 0x001085fd, 0x001085fd, 0x001085fd, 0x001085fd, + 0x001085fd, 0x001085fd, 0x001085fd, 0x001085fd, + 0x001085fd, 0x00108616, 0x00108616, 0x00108616, + 0x00108616, 0x001085fd, 0x00108616, 0x001085fd, + 0x00108616, 0x0201f800, 0x001005d8, 0x4933c857, + 0x0201f800, 0x00106bbf, 0x0201f800, 0x00109037, + 0x02000000, 0x0002077d, 0x4d2c0000, 0x59325808, + 0x4a025a04, 0x00000103, 0x59300402, 0x48025c06, + 0x4a025a06, 0x00000006, 0x497a5c09, 0x0201f800, + 0x000202da, 0x5c025800, 0x0201f800, 0x0010912a, + 0x0201f000, 0x0002077d, 0x4933c857, 0x0201f800, + 0x00106bbf, 0x0201f000, 0x0002077d, 0x0201f800, + 0x001005d8, 0x5930001c, 0x800001c0, 0x02020800, + 0x0010984e, 0x59300004, 0x8c00053e, 0x04020029, + 0x59325808, 0x592c0c08, 0x59cc2a08, 0x82141d00, + 0x00000c00, 0x04000002, 0x59cc1809, 0x84040d58, + 0x48065c08, 0x82143500, 0x00000fff, 0x04020027, + 0x59340200, 0x8c00050e, 0x04020080, 0x0201f800, + 0x0002082b, 0x04020006, 0x4a025a06, 0x00000000, + 0x59300811, 0x800409c0, 0x0402094b, 0x4a025a04, + 0x00000103, 0x48065807, 0x480e580a, 0x48165c09, + 0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1, + 0x0201f800, 0x001049b2, 0x59cc0208, 0x8c000518, + 0x02020000, 0x001091d1, 0x0201f000, 0x0002077d, + 0x0201f800, 0x00106f60, 0x040007d6, 0x4d3c0000, + 0x42027800, 0x00000002, 0x0201f800, 0x00108be3, + 0x5c027800, 0x0401f7cf, 0x4817c857, 0x480fc857, + 0x82180500, 0x000000ff, 0x0400000e, 0x592c0204, + 0x82000500, 0x000000ff, 0x82000580, 0x00000048, + 0x04020008, 0x592c0407, 0x800001c0, 0x04000005, + 0x0201f800, 0x0010973f, 0x0201f000, 0x00109787, + 0x82180d00, 0x00000c00, 0x04000004, 0x59340200, + 0x8c00050e, 0x04020032, 0x4a025a06, 0x00000000, + 0x41782000, 0x8c183510, 0x04000007, 0x59cc000c, + 0x82000500, 0x000000ff, 0x04000002, 0x4803c857, + 0x59cc200b, 0x4812580c, 0x41780000, 0x8c183512, + 0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00, + 0x040007b8, 0x82041480, 0x0000001d, 0x04001006, + 0x592c0404, 0x8c00051e, 0x0400000e, 0x42000800, + 0x0000001c, 0x4c500000, 0x4c540000, 0x83cca400, + 0x0000000c, 0x832cac00, 0x0000000d, 0x0201f800, + 0x00108b9f, 0x5c00a800, 0x5c00a000, 0x0401f7a5, + 0x59300011, 0x59301402, 0x480a5c06, 0x48025807, + 0x480e580a, 0x48165c09, 0x0201f800, 0x00108b48, + 0x0201f800, 0x00108b84, 0x0401f7a6, 0x592c020a, + 0x8c000502, 0x040007cd, 0x592c0208, 0x8c00050e, + 0x040207ca, 0x59300011, 0x800c0d80, 0x040007c7, + 0x4803c857, 0x480fc857, 0x8c183514, 0x02000000, + 0x0010920f, 0x80000540, 0x040007c0, 0x4807c856, + 0x0201f000, 0x0010920f, 0x592c020a, 0x8c000502, + 0x04000782, 0x59300011, 0x800001c0, 0x0400077f, + 0x592c0208, 0x8c00050e, 0x0402077c, 0x0201f000, + 0x0010920f, 0x59cc2006, 0x59cc2807, 0x0401f035, + 0x0401f034, 0x1c01f000, 0x4933c857, 0x5930001c, + 0x800001c0, 0x02020800, 0x0010984e, 0x59325808, + 0x592c0c08, 0x41782800, 0x41781800, 0x84040d58, + 0x48065c08, 0x41783000, 0x59340200, 0x8c00050e, + 0x04020018, 0x0201f800, 0x0002082b, 0x04020007, + 0x4a025a06, 0x00000000, 0x59300811, 0x4807c857, + 0x800409c0, 0x040208ac, 0x4a025a04, 0x00000103, + 0x48065807, 0x480e580a, 0x48165c09, 0x4933c857, + 0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1, + 0x0201f800, 0x001049b2, 0x0201f000, 0x0002077d, + 0x592c020a, 0x8c000502, 0x040007ea, 0x59300011, + 0x4803c857, 0x800001c0, 0x040007e6, 0x592c0208, + 0x8c00050e, 0x040207e3, 0x0201f000, 0x0010920f, 0x5930001c, 0x800001c0, 0x4c100000, 0x4c140000, - 0x02020800, 0x0010961a, 0x5c002800, 0x5c002000, + 0x02020800, 0x0010984e, 0x5c002800, 0x5c002000, 0x4a026203, 0x00000002, 0x4a026403, 0x00000043, - 0x59325808, 0x592c020a, 0x8c000502, 0x0402001c, + 0x59325808, 0x592c020a, 0x8c000502, 0x04020018, 0x40100000, 0x592c080f, 0x80040c80, 0x40140000, - 0x80040480, 0x04001018, 0x59300004, 0x8c00053e, - 0x0402000a, 0x48126013, 0x48166011, 0x497a6205, - 0x0201f800, 0x00100fe1, 0x0402000d, 0x59300804, - 0x0201f000, 0x00106466, 0x4c100000, 0x4c140000, - 0x0201f800, 0x00106cb4, 0x5c002800, 0x5c002000, - 0x040007f1, 0x0201f000, 0x001076fb, 0x4933c857, - 0x1c01f000, 0x4807c857, 0x40042800, 0x0401f7e7, + 0x80040480, 0x04001014, 0x48126013, 0x48166011, + 0x59300004, 0x8c00053e, 0x04020008, 0x497a6205, + 0x0201f800, 0x00100f93, 0x04020009, 0x59300804, + 0x0201f000, 0x00106721, 0x0201f800, 0x00106f60, + 0x040007f7, 0x0201f000, 0x00107974, 0x4933c857, + 0x1c01f000, 0x4807c857, 0x40042800, 0x0401f7eb, 0x83380480, 0x00000058, 0x04021005, 0x83380480, 0x00000040, 0x04001002, 0x0c01f002, 0x1c01f000, - 0x001084ec, 0x001084ec, 0x001084ec, 0x001084ec, - 0x001084ec, 0x001084ec, 0x001084ec, 0x001084ec, - 0x001084ec, 0x001084ec, 0x001084ee, 0x001084ec, - 0x001084ec, 0x001084ec, 0x001084ec, 0x001084fb, - 0x001084ec, 0x001084ec, 0x001084ec, 0x001084ec, - 0x00108529, 0x001084ec, 0x001084ec, 0x001084ec, - 0x0201f800, 0x00100615, 0x4933c857, 0x0201f800, - 0x00106b13, 0x4a026203, 0x00000002, 0x59a80039, + 0x00108740, 0x00108740, 0x00108740, 0x00108740, + 0x00108740, 0x00108740, 0x00108740, 0x00108740, + 0x00108740, 0x00108740, 0x00108742, 0x00108740, + 0x00108740, 0x00108740, 0x00108740, 0x0010874f, + 0x00108740, 0x00108740, 0x00108740, 0x00108740, + 0x0010877d, 0x00108740, 0x00108740, 0x00108740, + 0x0201f800, 0x001005d8, 0x4933c857, 0x0201f800, + 0x00106dc3, 0x4a026203, 0x00000002, 0x59a80039, 0x48026205, 0x59300011, 0x59300815, 0x80040c80, - 0x48066015, 0x0201f000, 0x001068c1, 0x4933c857, - 0x0201f800, 0x001068c1, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x00101de2, 0x5c027800, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x0201f800, - 0x00108df4, 0x04000010, 0x4d2c0000, 0x59325808, + 0x48066015, 0x0201f000, 0x00106b8a, 0x4933c857, + 0x0201f800, 0x00106b8a, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x0010203c, 0x5c027800, 0x42000000, + 0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800, + 0x00109037, 0x04000010, 0x4d2c0000, 0x59325808, 0x4a025a04, 0x00000103, 0x59300402, 0x48025c06, 0x4a025a06, 0x00000029, 0x497a5c09, 0x592c0c08, - 0x84040d50, 0x48065c08, 0x0201f800, 0x00020381, + 0x84040d50, 0x48065c08, 0x0201f800, 0x000202da, 0x5c025800, 0x42003000, 0x00000014, 0x41782800, 0x4d400000, 0x4d440000, 0x59368c03, 0x42002000, 0x00000002, 0x42028000, 0x00000029, 0x0201f800, - 0x0010962a, 0x5c028800, 0x5c028000, 0x0201f000, - 0x000208b4, 0x4933c857, 0x59300808, 0x49780c09, + 0x0010985e, 0x5c028800, 0x5c028000, 0x0201f000, + 0x0002077d, 0x4933c857, 0x59300808, 0x49780c09, 0x4978080a, 0x58041408, 0x84081558, 0x48080c08, - 0x1c01f000, 0x4807c857, 0x8c040d3e, 0x04020024, - 0x497a5a06, 0x5930001f, 0x80000540, 0x04000018, + 0x1c01f000, 0x4807c857, 0x8c040d3e, 0x04020023, + 0x497a5a06, 0x5930001f, 0x80000540, 0x04000017, 0x497a5a06, 0x4c040000, 0x4c080000, 0x4c0c0000, - 0x4c100000, 0x4c140000, 0x40002800, 0x58141003, - 0x40040000, 0x80081480, 0x48082803, 0x40140000, - 0x0201f800, 0x00100d9a, 0x5c002800, 0x5c002000, - 0x5c001800, 0x5c001000, 0x5c000800, 0x592c0206, - 0x80000540, 0x04020009, 0x0401f005, 0x592c0408, - 0x8c00051c, 0x04000002, 0x592c0803, 0x4807c857, - 0x4a025a06, 0x00000015, 0x1c01f000, 0x5930001f, - 0x80000540, 0x04000009, 0x4a025a06, 0x00000011, - 0x5930001f, 0x4c040000, 0x0201f800, 0x00100d9a, - 0x5c000800, 0x0401f7f5, 0x4807c856, 0x4a025a06, - 0x00000007, 0x1c01f000, 0x83380480, 0x00000058, - 0x04021007, 0x83380480, 0x00000040, 0x04001004, - 0x4d2c0000, 0x0c01f803, 0x5c025800, 0x1c01f000, - 0x00108588, 0x00108588, 0x00108588, 0x00108588, - 0x00108588, 0x0010858a, 0x00108588, 0x00108588, - 0x0010860d, 0x00108588, 0x00108588, 0x00108588, - 0x00108588, 0x00108588, 0x00108588, 0x00108588, - 0x00108588, 0x00108588, 0x00108588, 0x001086c5, - 0x001086ee, 0x001086cd, 0x00108588, 0x001086fa, - 0x0201f800, 0x00100615, 0x5930001c, 0x800001c0, - 0x02020800, 0x0010961a, 0x59300007, 0x8c00050e, - 0x0400007c, 0x8c000500, 0x0400006e, 0x8c00051c, - 0x04000009, 0x84000500, 0x48026007, 0x59325808, - 0x592c3c08, 0x841c3d58, 0x481e5c08, 0x0201f000, - 0x00020914, 0x59325808, 0x592c3c08, 0x841c3d58, - 0x59300007, 0x8c00051c, 0x040207f3, 0x481e5c08, - 0x42000000, 0x00000005, 0x40000000, 0x80000040, - 0x040207fe, 0x59300007, 0x8c00051c, 0x040207ea, - 0x59cc0a08, 0x592c0204, 0x82000500, 0x000000ff, - 0x82000580, 0x00000048, 0x0402000c, 0x497a580b, - 0x82040500, 0x000000ff, 0x04000008, 0x592c0407, - 0x800001c0, 0x04000005, 0x0201f800, 0x0010950b, - 0x0201f000, 0x00100ea1, 0x48065c09, 0x41782000, - 0x82040500, 0x00000c00, 0x04000002, 0x59cc2009, - 0x82043500, 0x00000fff, 0x04020027, 0x481e5c08, - 0x4a025a06, 0x00000000, 0x801831c0, 0x02000000, - 0x00100ea1, 0x41782000, 0x8c183510, 0x04000002, - 0x59cc200b, 0x4812580c, 0x41780000, 0x8c183512, - 0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00, - 0x02001800, 0x00100615, 0x02000000, 0x00100ea1, - 0x82041480, 0x0000001d, 0x0402100c, 0x4c500000, - 0x4c540000, 0x83cca400, 0x0000000c, 0x832cac00, - 0x0000000d, 0x0401fb6e, 0x5c00a800, 0x5c00a000, - 0x0201f000, 0x00100ea1, 0x0401fb12, 0x0201f000, - 0x00100ea1, 0x412c7800, 0x0201f800, 0x0010082a, - 0x02000800, 0x00100615, 0x492c7809, 0x841c3d52, - 0x481c7c08, 0x4a025a04, 0x00000103, 0x4812580a, - 0x48065c09, 0x583c0404, 0x583c1005, 0x583c2208, - 0x48025c04, 0x480a5805, 0x48125a08, 0x0401f7c8, - 0x8c000524, 0x04000794, 0x59325808, 0x4c000000, - 0x592c0408, 0x8c00051c, 0x5c000000, 0x04020003, - 0x4a026011, 0xffffffff, 0x84000524, 0x0401f78a, - 0x1c01f000, 0x59a80039, 0x48026205, 0x59325808, - 0x4a026203, 0x00000002, 0x592c2408, 0x59300807, - 0x4933c857, 0x4807c857, 0x592c0204, 0x82000500, - 0x000000ff, 0x82000580, 0x00000048, 0x04020004, - 0x8c102500, 0x02020000, 0x00109553, 0x4a025a06, - 0x00000000, 0x8c040d1e, 0x04000027, 0x41780800, - 0x497a5c09, 0x592c1c09, 0x59300011, 0x59341200, - 0x497a6205, 0x8c08150e, 0x0402006e, 0x4807c857, - 0x4806580a, 0x80000d40, 0x04020f03, 0x59300402, - 0x48025c06, 0x48065807, 0x4a025a04, 0x00000103, - 0x4c040000, 0x4c0c0000, 0x4c100000, 0x0201f800, - 0x00109365, 0x5c002000, 0x5c001800, 0x5c000800, - 0x8c102512, 0x0402001a, 0x4c0c0000, 0x0201f800, - 0x00020381, 0x0201f800, 0x00104801, 0x5c001800, - 0x8c0c1d18, 0x02000000, 0x000208b4, 0x0201f000, - 0x00108f88, 0x4813c857, 0x8c102518, 0x0400004b, - 0x41780800, 0x592c1c09, 0x820c0580, 0x00001000, - 0x040007d6, 0x8c102512, 0x040007d4, 0x592c7809, - 0x583c080a, 0x583c1c09, 0x0401f7d0, 0x4807c857, - 0x592c7809, 0x59300402, 0x592c1404, 0x8c08151e, - 0x0402000d, 0x592c1206, 0x48007c06, 0x48047807, - 0x48087a06, 0x84102512, 0x48107c08, 0x4c0c0000, - 0x0201f800, 0x00100843, 0x403e5800, 0x0401fad1, - 0x0401f7d9, 0x48025c06, 0x48065807, 0x583c080c, - 0x583c000b, 0x80040c00, 0x82041480, 0x0000001d, - 0x04001006, 0x583c1001, 0x480a5801, 0x49787801, - 0x42000800, 0x0000001c, 0x82040c00, 0x00000014, - 0x4c0c0000, 0x4c500000, 0x4c540000, 0x823ca400, - 0x00000008, 0x832cac00, 0x00000008, 0x4c100000, - 0x4c3c0000, 0x0401fad2, 0x5c007800, 0x5c002000, - 0x5c00a800, 0x5c00a000, 0x84102512, 0x48125c08, - 0x403e5800, 0x0201f800, 0x00100843, 0x42034000, - 0x0010b2a0, 0x59a1d81e, 0x80edd9c0, 0x02000800, - 0x00100615, 0x48efc857, 0x58ec0009, 0x4803c857, - 0x0801f800, 0x0401f7ac, 0x4933c857, 0x1c01f000, - 0x59301414, 0x480bc857, 0x8c08151c, 0x0402000e, - 0x80000540, 0x4803c857, 0x0400078d, 0x80042c80, - 0x0402178b, 0x8c081514, 0x04020005, 0x592c080f, - 0x4807c857, 0x80040480, 0x48026016, 0x8408155c, - 0x480a6414, 0x59301007, 0x8408151e, 0x480a6007, - 0x4c100000, 0x4c3c0000, 0x4d400000, 0x592e8206, - 0x4a025a06, 0x00000001, 0x0201f800, 0x00109365, - 0x49425a06, 0x5c028000, 0x5c007800, 0x5c002000, - 0x497a5c09, 0x8c102512, 0x04000006, 0x4d2c0000, - 0x403e5800, 0x0201f800, 0x00100843, 0x5c025800, - 0x82102500, 0xffffedff, 0x48125c08, 0x0201f000, - 0x00108fc6, 0x59325808, 0x592c0408, 0x8c000518, - 0x04000004, 0x412df800, 0x0201f000, 0x00100eba, - 0x1c01f000, 0x4933c857, 0x59325808, 0x497a5c09, - 0x4a025a06, 0x00000000, 0x4a025a04, 0x00000103, - 0x59300811, 0x4807c857, 0x800409c0, 0x0402000a, - 0x48065807, 0x59300c02, 0x48065c06, 0x0201f800, - 0x00020381, 0x0201f800, 0x00104801, 0x0201f000, - 0x000208b4, 0x59340200, 0x8c00050e, 0x04020005, - 0x59300811, 0x0401fe4c, 0x48065807, 0x0401f7f2, - 0x592c0208, 0x8c00050e, 0x040207fa, 0x4933c857, - 0x0201f000, 0x00108fc6, 0x4933c857, 0x59325808, - 0x812e59c0, 0x02000800, 0x00100615, 0x592c020a, - 0x8c000502, 0x02000800, 0x00100615, 0x4a026206, - 0x00000002, 0x1c01f000, 0x5930001c, 0x800001c0, - 0x02020800, 0x0010961a, 0x59300007, 0x4933c857, - 0x4803c857, 0x8c00050e, 0x04000037, 0x8c000500, - 0x04000029, 0x8c00051c, 0x0400000a, 0x84000500, - 0x48026007, 0x59325808, 0x592c3c08, 0x481fc857, - 0x841c3d58, 0x481e5c08, 0x0201f000, 0x00020914, + 0x4c100000, 0x4c140000, 0x58f41003, 0x40040000, + 0x80081480, 0x5930001f, 0x4809e803, 0x0201f800, + 0x00100d56, 0x5c002800, 0x5c002000, 0x5c001800, + 0x5c001000, 0x5c000800, 0x592c0206, 0x80000540, + 0x04020009, 0x0401f005, 0x592c0408, 0x8c00051c, + 0x04000002, 0x592c0803, 0x4807c857, 0x4a025a06, + 0x00000015, 0x1c01f000, 0x5930001f, 0x80000540, + 0x04000009, 0x4a025a06, 0x00000011, 0x5930001f, + 0x4c040000, 0x0201f800, 0x00100d56, 0x5c000800, + 0x0401f7f5, 0x4807c856, 0x4a025a06, 0x00000007, + 0x1c01f000, 0x83380480, 0x00000058, 0x04021007, + 0x83380480, 0x00000040, 0x04001004, 0x4d2c0000, + 0x0c01f803, 0x5c025800, 0x1c01f000, 0x001087db, + 0x001087db, 0x001087db, 0x001087db, 0x001087db, + 0x001087dd, 0x001087db, 0x001087db, 0x00108860, + 0x001087db, 0x001087db, 0x001087db, 0x001087db, + 0x001087db, 0x001087db, 0x001087db, 0x001087db, + 0x001087db, 0x001087db, 0x00108910, 0x00108939, + 0x00108918, 0x001087db, 0x00108945, 0x0201f800, + 0x001005d8, 0x5930001c, 0x800001c0, 0x02020800, + 0x0010984e, 0x59300007, 0x8c00050e, 0x0400007c, + 0x8c000500, 0x0400006e, 0x8c00051c, 0x04000009, + 0x84000500, 0x48026007, 0x59325808, 0x592c3c08, + 0x841c3d58, 0x481e5c08, 0x0201f000, 0x000207dd, 0x59325808, 0x592c3c08, 0x841c3d58, 0x59300007, - 0x8c00051c, 0x040207f2, 0x481e5c08, 0x42000000, + 0x8c00051c, 0x040207f3, 0x481e5c08, 0x42000000, 0x00000005, 0x40000000, 0x80000040, 0x040207fe, - 0x59300007, 0x8c00051c, 0x040207e9, 0x592c0204, - 0x82000500, 0x000000ff, 0x82000580, 0x00000048, - 0x04020003, 0x497a580b, 0x0401f002, 0x497a5c09, - 0x481e5c08, 0x4a025a06, 0x00000000, 0x0201f000, - 0x00100ea1, 0x8c000524, 0x040007d9, 0x59325808, - 0x4c000000, 0x592c0408, 0x8c00051c, 0x5c000000, - 0x04020003, 0x4a026011, 0xffffffff, 0x84000524, - 0x0401f7cf, 0x1c01f000, 0x4933c857, 0x41780800, - 0x83380480, 0x00000058, 0x0402100b, 0x83380480, - 0x00000040, 0x04001008, 0x4d2c0000, 0x59325808, - 0x812e59c0, 0x0c020806, 0x5c025800, 0x0201f000, - 0x000208b4, 0x493bc857, 0x1c01f000, 0x00108763, - 0x00108763, 0x00108763, 0x00108763, 0x00108763, - 0x00108765, 0x00108763, 0x00108763, 0x00108763, - 0x00108763, 0x00108763, 0x00108763, 0x00108763, - 0x00108763, 0x00108763, 0x00108763, 0x00108763, - 0x00108763, 0x00108763, 0x00108763, 0x0010876a, - 0x00108763, 0x00108763, 0x00108763, 0x0201f800, - 0x00100615, 0x59cc0a08, 0x497a5807, 0x4807c857, - 0x82040d00, 0x00000fff, 0x59300402, 0x48025c06, - 0x4a025a04, 0x00000103, 0x48065c09, 0x4a025a06, - 0x00000000, 0x800409c0, 0x02000000, 0x00020381, - 0x59cc0009, 0x4802580a, 0x82042500, 0x00000100, - 0x04000002, 0x59cc200b, 0x4812580c, 0x82040500, - 0x00000200, 0x04000002, 0x59cc000a, 0x4802580b, - 0x80100c00, 0x02001800, 0x00100615, 0x02000000, - 0x00020381, 0x82041480, 0x0000001d, 0x04001006, - 0x592c0404, 0x8c00051e, 0x0400000e, 0x42000800, - 0x0000001c, 0x4c500000, 0x4c540000, 0x83cca400, - 0x0000000c, 0x832cac00, 0x0000000d, 0x0401f9c0, - 0x5c00a800, 0x5c00a000, 0x0201f000, 0x00020381, - 0x0401f964, 0x0401f19f, 0x83380480, 0x00000093, - 0x02021800, 0x00100615, 0x83380480, 0x00000085, - 0x02001800, 0x00100615, 0x0c01f001, 0x001087b2, - 0x001087b0, 0x001087b0, 0x001087b9, 0x001087b0, - 0x001087b0, 0x001087b0, 0x001087b0, 0x001087b0, - 0x001087b0, 0x001087b0, 0x001087b0, 0x001087b0, - 0x0201f800, 0x00100615, 0x4a026203, 0x00000001, - 0x493a6403, 0x42000800, 0x80000040, 0x0201f000, - 0x00020855, 0x4933c857, 0x59cc1404, 0x0201f800, - 0x001091d9, 0x0400001b, 0x591c0203, 0x82000580, - 0x00000000, 0x04000017, 0x591c0009, 0x81340580, - 0x04020014, 0x4d300000, 0x4d1c0000, 0x411e6000, - 0x0401f9c3, 0x5c023800, 0x5c026000, 0x0400000b, - 0x59cc0005, 0x8c000500, 0x04020003, 0x0401f98d, - 0x0401f003, 0x4a023a03, 0x00000002, 0x4a026403, - 0x00000086, 0x0401f005, 0x0401f9a7, 0x040007f5, - 0x4a026403, 0x00000087, 0x4a026203, 0x00000001, - 0x42000800, 0x80000040, 0x0201f800, 0x00020855, - 0x59340200, 0x8c00050e, 0x0400000d, 0x59cc1404, - 0x0201f800, 0x001091d9, 0x04000009, 0x591c0414, - 0x8c00051a, 0x04000006, 0x4d300000, 0x411e6000, - 0x0201f800, 0x00108fdb, 0x5c026000, 0x1c01f000, - 0x83380580, 0x00000013, 0x0402000b, 0x59300403, - 0x4803c857, 0x82000d80, 0x00000086, 0x04000012, - 0x82000d80, 0x00000087, 0x02020800, 0x00100615, + 0x59300007, 0x8c00051c, 0x040207ea, 0x59cc0a08, + 0x592c0204, 0x82000500, 0x000000ff, 0x82000580, + 0x00000048, 0x0402000c, 0x497a580b, 0x82040500, + 0x000000ff, 0x04000008, 0x592c0407, 0x800001c0, + 0x04000005, 0x0201f800, 0x0010973f, 0x0201f000, + 0x00100e56, 0x48065c09, 0x41782000, 0x82040500, + 0x00000c00, 0x04000002, 0x59cc2009, 0x82043500, + 0x00000fff, 0x04020027, 0x481e5c08, 0x4a025a06, + 0x00000000, 0x801831c0, 0x02000000, 0x00100e56, + 0x41782000, 0x8c183510, 0x04000002, 0x59cc200b, + 0x4812580c, 0x41780000, 0x8c183512, 0x04000002, + 0x59cc000a, 0x4802580b, 0x80100c00, 0x02001800, + 0x001005d8, 0x02000000, 0x00100e56, 0x82041480, + 0x0000001d, 0x0402100c, 0x4c500000, 0x4c540000, + 0x83cca400, 0x0000000c, 0x832cac00, 0x0000000d, + 0x0401fb67, 0x5c00a800, 0x5c00a000, 0x0201f000, + 0x00100e56, 0x0401fb0b, 0x0201f000, 0x00100e56, + 0x412c7800, 0x0201f800, 0x001007e4, 0x02000800, + 0x001005d8, 0x492c7809, 0x841c3d52, 0x481c7c08, + 0x4a025a04, 0x00000103, 0x4812580a, 0x48065c09, + 0x583c0404, 0x583c1005, 0x583c2208, 0x48025c04, + 0x480a5805, 0x48125a08, 0x0401f7c8, 0x8c000524, + 0x04000794, 0x59325808, 0x4c000000, 0x592c0408, + 0x8c00051c, 0x5c000000, 0x04020003, 0x4a026011, + 0xffffffff, 0x84000524, 0x0401f78a, 0x1c01f000, + 0x59a80039, 0x48026205, 0x59325808, 0x4a026203, + 0x00000002, 0x592c2408, 0x59300807, 0x4933c857, + 0x4807c857, 0x592c0204, 0x82000500, 0x000000ff, + 0x82000580, 0x00000048, 0x04020004, 0x8c102500, + 0x02020000, 0x00109787, 0x4a025a06, 0x00000000, + 0x8c040d1e, 0x04000027, 0x41780800, 0x497a5c09, + 0x592c1c09, 0x59300011, 0x59341200, 0x497a6205, + 0x8c08150e, 0x0402006e, 0x4807c857, 0x4806580a, + 0x80000d40, 0x04020f04, 0x59300402, 0x48025c06, + 0x48065807, 0x4a025a04, 0x00000103, 0x4c040000, + 0x4c0c0000, 0x4c100000, 0x0201f800, 0x0010959c, + 0x5c002000, 0x5c001800, 0x5c000800, 0x8c102512, + 0x0402001a, 0x4c0c0000, 0x0201f800, 0x000202c1, + 0x0201f800, 0x001049b2, 0x5c001800, 0x8c0c1d18, + 0x02000000, 0x0002077d, 0x0201f000, 0x001091d1, + 0x4813c857, 0x8c102518, 0x0400004b, 0x41780800, + 0x592c1c09, 0x820c0580, 0x00001000, 0x040007d6, + 0x8c102512, 0x040007d4, 0x592c7809, 0x583c080a, + 0x583c1c09, 0x0401f7d0, 0x4807c857, 0x592c7809, + 0x59300402, 0x592c1404, 0x8c08151e, 0x0402000d, + 0x592c1206, 0x48007c06, 0x48047807, 0x48087a06, + 0x84102512, 0x48107c08, 0x4c0c0000, 0x0201f800, + 0x001007fd, 0x403e5800, 0x0401faca, 0x0401f7d9, + 0x48025c06, 0x48065807, 0x583c080c, 0x583c000b, + 0x80040c00, 0x82041480, 0x0000001d, 0x04001006, + 0x583c1001, 0x480a5801, 0x49787801, 0x42000800, + 0x0000001c, 0x82040c00, 0x00000014, 0x4c0c0000, + 0x4c500000, 0x4c540000, 0x823ca400, 0x00000008, + 0x832cac00, 0x00000008, 0x4c100000, 0x4c3c0000, + 0x0401facb, 0x5c007800, 0x5c002000, 0x5c00a800, + 0x5c00a000, 0x84102512, 0x48125c08, 0x403e5800, + 0x0201f800, 0x001007fd, 0x42034000, 0x0010b4a4, + 0x59a1d81e, 0x80edd9c0, 0x02000800, 0x001005d8, + 0x48efc857, 0x58ec0009, 0x4803c857, 0x0801f800, + 0x0401f7ac, 0x4933c857, 0x1c01f000, 0x59301414, + 0x480bc857, 0x8c08151c, 0x0402000e, 0x80000540, + 0x4803c857, 0x0400078d, 0x80042c80, 0x0402178b, + 0x8c081514, 0x04020005, 0x592c080f, 0x4807c857, + 0x80040480, 0x48026016, 0x8408155c, 0x480a6414, + 0x59301007, 0x8408151e, 0x480a6007, 0x4a025c09, + 0x00000001, 0x0201f800, 0x0010959c, 0x497a5c09, + 0x8c102512, 0x04000006, 0x4d2c0000, 0x403e5800, + 0x0201f800, 0x001007fd, 0x5c025800, 0x82102500, + 0xffffedff, 0x48125c08, 0x0201f000, 0x0010920f, + 0x59325808, 0x592c0408, 0x8c000518, 0x04000004, + 0x412df800, 0x0201f000, 0x00100e6f, 0x1c01f000, + 0x4933c857, 0x59325808, 0x497a5c09, 0x4a025a06, + 0x00000000, 0x4a025a04, 0x00000103, 0x59300811, + 0x4807c857, 0x800409c0, 0x0402000a, 0x48065807, + 0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1, + 0x0201f800, 0x001049b2, 0x0201f000, 0x0002077d, + 0x59340200, 0x8c00050e, 0x04020005, 0x59300811, + 0x0401fe55, 0x48065807, 0x0401f7f2, 0x592c0208, + 0x8c00050e, 0x040207fa, 0x4933c857, 0x0201f000, + 0x0010920f, 0x4933c857, 0x59325808, 0x812e59c0, + 0x02000800, 0x001005d8, 0x592c020a, 0x8c000502, + 0x02000800, 0x001005d8, 0x4a026206, 0x00000002, + 0x1c01f000, 0x5930001c, 0x800001c0, 0x02020800, + 0x0010984e, 0x59300007, 0x4933c857, 0x4803c857, + 0x8c00050e, 0x04000037, 0x8c000500, 0x04000029, + 0x8c00051c, 0x0400000a, 0x84000500, 0x48026007, + 0x59325808, 0x592c3c08, 0x481fc857, 0x841c3d58, + 0x481e5c08, 0x0201f000, 0x000207dd, 0x59325808, + 0x592c3c08, 0x841c3d58, 0x59300007, 0x8c00051c, + 0x040207f2, 0x481e5c08, 0x42000000, 0x00000005, + 0x40000000, 0x80000040, 0x040207fe, 0x59300007, + 0x8c00051c, 0x040207e9, 0x592c0204, 0x82000500, + 0x000000ff, 0x82000580, 0x00000048, 0x04020003, + 0x497a580b, 0x0401f002, 0x497a5c09, 0x481e5c08, + 0x4a025a06, 0x00000000, 0x0201f000, 0x00100e56, + 0x8c000524, 0x040007d9, 0x59325808, 0x4c000000, + 0x592c0408, 0x8c00051c, 0x5c000000, 0x04020003, + 0x4a026011, 0xffffffff, 0x84000524, 0x0401f7cf, + 0x1c01f000, 0x4933c857, 0x41780800, 0x83380480, + 0x00000058, 0x0402100b, 0x83380480, 0x00000040, + 0x04001008, 0x4d2c0000, 0x59325808, 0x812e59c0, + 0x0c020806, 0x5c025800, 0x0201f000, 0x0002077d, + 0x493bc857, 0x1c01f000, 0x001089ae, 0x001089ae, + 0x001089ae, 0x001089ae, 0x001089ae, 0x001089b0, + 0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae, + 0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae, + 0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae, + 0x001089ae, 0x001089ae, 0x001089b5, 0x001089ae, + 0x001089ae, 0x001089ae, 0x0201f800, 0x001005d8, + 0x59cc0a08, 0x497a5807, 0x4807c857, 0x82040d00, + 0x00000fff, 0x59300402, 0x48025c06, 0x4a025a04, + 0x00000103, 0x48065c09, 0x4a025a06, 0x00000000, + 0x800409c0, 0x02000000, 0x000202c1, 0x59cc0009, + 0x4802580a, 0x82042500, 0x00000100, 0x04000002, + 0x59cc200b, 0x4812580c, 0x82040500, 0x00000200, + 0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00, + 0x02001800, 0x001005d8, 0x02000000, 0x000202da, + 0x82041480, 0x0000001d, 0x04001006, 0x592c0404, + 0x8c00051e, 0x0400000e, 0x42000800, 0x0000001c, + 0x4c500000, 0x4c540000, 0x83cca400, 0x0000000c, + 0x832cac00, 0x0000000d, 0x0401f9c1, 0x5c00a800, + 0x5c00a000, 0x0201f000, 0x000202da, 0x0401f965, + 0x0401f1a0, 0x83380480, 0x00000093, 0x02021800, + 0x001005d8, 0x83380480, 0x00000085, 0x02001800, + 0x001005d8, 0x0c01f001, 0x001089fd, 0x001089fb, + 0x001089fb, 0x00108a04, 0x001089fb, 0x001089fb, + 0x001089fb, 0x001089fb, 0x001089fb, 0x001089fb, + 0x001089fb, 0x001089fb, 0x001089fb, 0x0201f800, + 0x001005d8, 0x4a026203, 0x00000001, 0x493a6403, + 0x42000800, 0x80000040, 0x0201f000, 0x00020721, + 0x4933c857, 0x59cc1204, 0x480a601c, 0x59cc1404, + 0x0201f800, 0x00109410, 0x0400001b, 0x591c0203, + 0x82000580, 0x00000000, 0x04000017, 0x591c0009, + 0x81340580, 0x04020014, 0x4d300000, 0x4d1c0000, + 0x411e6000, 0x0401f9c2, 0x5c023800, 0x5c026000, + 0x0400000b, 0x59cc0005, 0x8c000500, 0x04020003, + 0x0401f98c, 0x0401f003, 0x4a023a03, 0x00000002, + 0x4a026403, 0x00000086, 0x0401f005, 0x0401f9a6, + 0x040007f5, 0x4a026403, 0x00000087, 0x4a026203, + 0x00000001, 0x42000800, 0x80000040, 0x0201f800, + 0x00020721, 0x59340200, 0x8c00050e, 0x0400000d, + 0x59cc1404, 0x0201f800, 0x00109410, 0x04000009, + 0x591c0414, 0x8c00051a, 0x04000006, 0x4d300000, + 0x411e6000, 0x0201f800, 0x0010921e, 0x5c026000, + 0x1c01f000, 0x83380580, 0x00000013, 0x0402000a, + 0x59300403, 0x82000d80, 0x00000086, 0x04000012, + 0x82000d80, 0x00000087, 0x02020800, 0x001005d8, 0x0401f00d, 0x83380580, 0x00000027, 0x04000005, - 0x83380580, 0x00000014, 0x02020800, 0x00100615, - 0x493bc857, 0x0201f800, 0x001068f6, 0x0201f000, - 0x00107698, 0x4933c857, 0x0201f000, 0x00107698, + 0x83380580, 0x00000014, 0x02020800, 0x001005d8, + 0x493bc857, 0x0201f800, 0x00106bbf, 0x0201f000, + 0x00107911, 0x4933c857, 0x0201f000, 0x00107911, 0x83380580, 0x00000013, 0x04020005, 0x59300403, 0x82000480, 0x00000085, 0x0c01f04d, 0x83380580, 0x00000027, 0x04020041, 0x4933c857, 0x0201f800, - 0x001068f6, 0x4d3c0000, 0x417a7800, 0x0201f800, - 0x00101de2, 0x5c027800, 0x42003000, 0x00000015, + 0x00106bbf, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x0010203c, 0x5c027800, 0x42003000, 0x00000015, 0x41782800, 0x42002000, 0x00000003, 0x42028000, 0x00000029, 0x4d400000, 0x4d440000, 0x59368c03, - 0x0201f800, 0x0010962a, 0x5c028800, 0x5c028000, - 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, - 0x0201f800, 0x00108df4, 0x0400000c, 0x4d2c0000, + 0x0201f800, 0x0010985e, 0x5c028800, 0x5c028000, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x0201f800, 0x00109037, 0x0400000c, 0x4d2c0000, 0x59325808, 0x4a025a04, 0x00000103, 0x59300402, 0x48025c06, 0x497a5c09, 0x49425a06, 0x0201f800, - 0x00020381, 0x5c025800, 0x0201f800, 0x00108ee7, - 0x0201f000, 0x000208b4, 0x83380580, 0x00000089, + 0x000202da, 0x5c025800, 0x0201f800, 0x0010912a, + 0x0201f000, 0x0002077d, 0x83380580, 0x00000089, 0x04000005, 0x83380580, 0x0000008a, 0x02020000, - 0x001076fb, 0x0201f800, 0x00106cb4, 0x02020000, - 0x001076fb, 0x59300a03, 0x82040580, 0x0000000a, + 0x00107974, 0x0201f800, 0x00106f60, 0x02020000, + 0x00107974, 0x59300a03, 0x82040580, 0x0000000a, 0x0400002a, 0x82040580, 0x0000000c, 0x04000027, - 0x0201f800, 0x00100615, 0x83380580, 0x00000014, - 0x040207ea, 0x4933c857, 0x0201f800, 0x001068f6, - 0x42028000, 0x00000006, 0x0401f7d2, 0x0010886e, - 0x0010886c, 0x0010886c, 0x0010886c, 0x0010886c, - 0x0010886c, 0x00108874, 0x0010886c, 0x0010886c, - 0x0010886c, 0x0010886c, 0x0010886c, 0x0010886c, - 0x0201f800, 0x00100615, 0x4933c857, 0x59a80037, + 0x0201f800, 0x001005d8, 0x83380580, 0x00000014, + 0x040207ea, 0x4933c857, 0x0201f800, 0x00106bbf, + 0x42028000, 0x00000006, 0x0401f7d2, 0x00108aba, + 0x00108ab8, 0x00108ab8, 0x00108ab8, 0x00108ab8, + 0x00108ab8, 0x00108ac0, 0x00108ab8, 0x00108ab8, + 0x00108ab8, 0x00108ab8, 0x00108ab8, 0x00108ab8, + 0x0201f800, 0x001005d8, 0x4933c857, 0x59a80037, 0x48026206, 0x4a026203, 0x0000000a, 0x1c01f000, 0x4933c857, 0x59a80037, 0x48026206, 0x4a026203, 0x0000000c, 0x1c01f000, 0x83380580, 0x00000089, 0x04000008, 0x83380580, 0x0000008a, 0x04000032, - 0x4933c857, 0x493bc857, 0x0201f000, 0x001076fb, + 0x4933c857, 0x493bc857, 0x0201f000, 0x00107974, 0x4933c857, 0x59325808, 0x59300a1d, 0x82040580, - 0x00000003, 0x04020004, 0x0201f800, 0x00104801, + 0x00000003, 0x04020004, 0x0201f800, 0x001049b2, 0x0401f00c, 0x5930021d, 0x82000580, 0x00000001, 0x04020008, 0x59300c16, 0x82040580, 0x00000039, 0x0400002c, 0x82040580, 0x00000035, 0x04000029, - 0x4c5c0000, 0x4130b800, 0x0201f800, 0x00020892, + 0x4c340000, 0x41306800, 0x0201f800, 0x0002075a, 0x04000010, 0x4a026203, 0x00000001, 0x4a026403, 0x0000001e, 0x59cc0c07, 0x48066419, 0x59cc0a07, 0x48066219, 0x49366009, 0x4a026406, 0x00000001, - 0x42000800, 0x80000040, 0x0201f800, 0x00020855, - 0x405e6000, 0x0201f800, 0x000208b4, 0x5c00b800, + 0x42000800, 0x80000040, 0x0201f800, 0x00020721, + 0x40366000, 0x0201f800, 0x0002077d, 0x5c006800, 0x1c01f000, 0x4933c857, 0x5930021d, 0x82000580, 0x00000001, 0x04020040, 0x59300c16, 0x82040580, 0x00000035, 0x04000007, 0x82040580, 0x0000001e, 0x04000004, 0x82040580, 0x00000039, 0x04020036, 0x4933c857, 0x4c500000, 0x4d1c0000, 0x4130a000, - 0x40067000, 0x0201f800, 0x00109183, 0x04020029, - 0x0201f800, 0x00020892, 0x04000026, 0x491fc857, + 0x40067000, 0x0201f800, 0x001093ba, 0x04020029, + 0x0201f800, 0x0002075a, 0x04000026, 0x491fc857, 0x4933c857, 0x83380580, 0x00000035, 0x04000004, 0x83380580, 0x00000039, 0x04020002, 0x4932381c, 0x493a6403, 0x4a026203, 0x00000001, 0x4a026406, @@ -8802,17 +8949,17 @@ uint32_t risc_code01[] = { 0x4807c857, 0x48066215, 0x58500a16, 0x4807c857, 0x48066216, 0x58500c19, 0x4807c857, 0x48066419, 0x58500a19, 0x4807c857, 0x48066219, 0x491e601e, - 0x42000800, 0x80000040, 0x0201f800, 0x00020855, + 0x42000800, 0x80000040, 0x0201f800, 0x00020721, 0x40526000, 0x5c023800, 0x5c00a000, 0x0201f000, - 0x000208b4, 0x5930021d, 0x82000580, 0x00000003, - 0x02000800, 0x00104801, 0x0201f000, 0x000208b4, + 0x0002077d, 0x5930021d, 0x82000580, 0x00000003, + 0x02000800, 0x001049b2, 0x0201f000, 0x0002077d, 0x4803c856, 0x4c500000, 0x4c540000, 0x412c7800, 0x4c3c0000, 0x42002800, 0x00000001, 0x82040480, 0x00000101, 0x04001003, 0x42000800, 0x00000100, 0x40043000, 0x42000800, 0x0000001c, 0x83cca400, 0x0000000c, 0x832cac00, 0x0000000d, 0x0401f844, 0x82183480, 0x0000001c, 0x592e5801, 0x812e59c0, - 0x02020800, 0x00100843, 0x0201f800, 0x0010082a, + 0x02020800, 0x001007fd, 0x0201f800, 0x001007e4, 0x04000017, 0x80142800, 0x4a025a04, 0x00000110, 0x497a5c04, 0x492c7801, 0x82180c80, 0x0000003d, 0x04021006, 0x40180800, 0x832cac00, 0x00000005, @@ -8823,89 +8970,89 @@ uint32_t risc_code01[] = { 0x403e5800, 0x5c00a800, 0x5c00a000, 0x1c01f000, 0x492fc857, 0x812e59c0, 0x0400000f, 0x4d2c0000, 0x4c3c0000, 0x592c7801, 0x803c79c0, 0x04000006, - 0x497a5801, 0x0201f800, 0x00020381, 0x403e5800, - 0x0401f7f9, 0x5c007800, 0x0201f800, 0x00020381, + 0x497a5801, 0x0201f800, 0x000202da, 0x403e5800, + 0x0401f7f9, 0x5c007800, 0x0201f800, 0x000202da, 0x5c025800, 0x1c01f000, 0x4803c856, 0x4c580000, 0x82040c00, 0x00000003, 0x8004b104, 0x0201f800, - 0x0010a93e, 0x5c00b000, 0x1c01f000, 0x4803c856, + 0x0010ab17, 0x5c00b000, 0x1c01f000, 0x4803c856, 0x4c580000, 0x82040c00, 0x00000003, 0x8004b104, - 0x0201f800, 0x0010a93e, 0x5c00b000, 0x1c01f000, + 0x0201f800, 0x0010ab17, 0x5c00b000, 0x1c01f000, 0x591c0c06, 0x82040580, 0x00000003, 0x04000004, 0x82040580, 0x00000002, 0x0402001a, 0x4d300000, 0x4d2c0000, 0x411e6000, 0x59325808, 0x0201f800, - 0x00108df4, 0x0400000f, 0x4d400000, 0x42028000, + 0x00109037, 0x0400000f, 0x4d400000, 0x42028000, 0x00000013, 0x592c0a08, 0x84040d54, 0x0201f800, - 0x00104bee, 0x5c028000, 0x0201f800, 0x00109365, - 0x0201f800, 0x00020381, 0x0201f800, 0x00108ee7, - 0x0201f800, 0x00107698, 0x5c025800, 0x5c026000, + 0x00104e70, 0x5c028000, 0x0201f800, 0x0010959c, + 0x0201f800, 0x000202da, 0x0201f800, 0x0010912a, + 0x0201f800, 0x00107911, 0x5c025800, 0x5c026000, 0x1c01f000, 0x59cc0005, 0x8c000500, 0x0402000b, 0x591c0406, 0x82000580, 0x00000002, 0x04020007, 0x591c0c03, 0x82040580, 0x00000085, 0x04000003, 0x82040580, 0x0000008b, 0x1c01f000, 0x4933c857, 0x4d3c0000, 0x42027800, 0x00000002, 0x59300406, - 0x82000c80, 0x00000012, 0x02021800, 0x00100615, + 0x82000c80, 0x00000012, 0x02021800, 0x001005d8, 0x0c01f80a, 0x5c027800, 0x1c01f000, 0x4933c857, 0x59300406, 0x82000c80, 0x00000012, 0x02021800, - 0x00100615, 0x0c01f001, 0x001089b5, 0x001089b2, - 0x001089b2, 0x001089dd, 0x001089b0, 0x001089b2, - 0x001089ce, 0x001089b2, 0x001089b0, 0x0010632c, - 0x001089b2, 0x001089b2, 0x001089b2, 0x001089b0, - 0x001089b0, 0x001089b0, 0x00108aad, 0x001089b2, - 0x0201f800, 0x00100615, 0x4803c856, 0x80000580, + 0x001005d8, 0x0c01f001, 0x00108c01, 0x00108bfe, + 0x00108bfe, 0x00108c29, 0x00108bfc, 0x00108bfe, + 0x00108c1a, 0x00108bfe, 0x00108bfc, 0x001065f4, + 0x00108bfe, 0x00108bfe, 0x00108bfe, 0x00108bfc, + 0x00108bfc, 0x00108bfc, 0x00108cf9, 0x00108bfe, + 0x0201f800, 0x001005d8, 0x4803c856, 0x80000580, 0x1c01f000, 0x4803c856, 0x8d3e7d02, 0x04020016, - 0x0201f800, 0x00108df4, 0x0400000f, 0x59325808, + 0x0201f800, 0x00109037, 0x0400000f, 0x59325808, 0x41780800, 0x4d400000, 0x42028000, 0x00000005, - 0x0201f800, 0x00104bee, 0x5c028000, 0x0201f800, - 0x00109365, 0x0201f800, 0x00108f83, 0x0201f800, - 0x00020381, 0x0201f800, 0x00107698, 0x82000540, + 0x0201f800, 0x00104e70, 0x5c028000, 0x0201f800, + 0x0010959c, 0x0201f800, 0x001091cc, 0x0201f800, + 0x000202da, 0x0201f800, 0x00107911, 0x82000540, 0x00000001, 0x1c01f000, 0x4933c857, 0x0201f800, - 0x00104728, 0x0402000c, 0x4d400000, 0x42028000, - 0x00000010, 0x0201f800, 0x00109fc0, 0x4a026406, + 0x001048d9, 0x0402000c, 0x4d400000, 0x42028000, + 0x00000010, 0x0201f800, 0x0010a1d1, 0x4a026406, 0x00000006, 0x4a026203, 0x00000007, 0x5c028000, - 0x1c01f000, 0x4933c857, 0x0201f800, 0x0010698c, + 0x1c01f000, 0x4933c857, 0x0201f800, 0x00106c55, 0x4df00000, 0x0401f8b8, 0x82000c80, 0x0000000e, - 0x02021800, 0x00100615, 0x0c01f001, 0x001089f7, - 0x00108a64, 0x00108a0e, 0x00108a77, 0x00108a5f, - 0x001089f5, 0x001089f7, 0x001089f7, 0x001089fb, - 0x001089f7, 0x001089f7, 0x001089f7, 0x001089f7, - 0x00108a0e, 0x0201f800, 0x00100615, 0x5c03e000, - 0x02000800, 0x00106982, 0x0401f7b8, 0x5c03e000, - 0x02000800, 0x00106982, 0x59300406, 0x82000580, + 0x02021800, 0x001005d8, 0x0c01f001, 0x00108c43, + 0x00108cb0, 0x00108c5a, 0x00108cc3, 0x00108cab, + 0x00108c41, 0x00108c43, 0x00108c43, 0x00108c47, + 0x00108c43, 0x00108c43, 0x00108c43, 0x00108c43, + 0x00108c5a, 0x0201f800, 0x001005d8, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x0401f7b8, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x59300406, 0x82000580, 0x00000003, 0x040207b4, 0x59300203, 0x82000580, 0x0000000d, 0x040007b0, 0x8d3e7d02, 0x040207ae, - 0x4d340000, 0x59326809, 0x0201f800, 0x00104801, + 0x4d340000, 0x59326809, 0x0201f800, 0x001049b2, 0x5c026800, 0x0401f7a8, 0x59300004, 0x8400055c, - 0x48026004, 0x0201f800, 0x00106982, 0x59300406, + 0x48026004, 0x0201f800, 0x00106c4b, 0x59300406, 0x82000580, 0x00000006, 0x04000043, 0x8d3e7d02, 0x04020041, 0x497a621d, 0x59300203, 0x82000580, 0x0000000d, 0x04000003, 0x4a02621d, 0x00000003, - 0x0401fbd4, 0x04000024, 0x4d2c0000, 0x4d400000, - 0x59325808, 0x0201f800, 0x00108f83, 0x592c0408, + 0x0401fbcb, 0x04000024, 0x4d2c0000, 0x4d400000, + 0x59325808, 0x0201f800, 0x001091cc, 0x592c0408, 0x8c000512, 0x04000009, 0x4d2c0000, 0x84000512, 0x48025c08, 0x592c0809, 0x40065800, 0x0201f800, - 0x00100843, 0x5c025800, 0x4d400000, 0x42028000, + 0x001007fd, 0x5c025800, 0x4d400000, 0x42028000, 0x00000005, 0x592c0a08, 0x8c040d0e, 0x04000004, 0x42028000, 0x00000002, 0x0401f001, 0x0201f800, - 0x00104bee, 0x5c028000, 0x0201f800, 0x00109365, - 0x0201f800, 0x00020381, 0x497a6008, 0x5c028000, + 0x00104e70, 0x5c028000, 0x0201f800, 0x0010959c, + 0x0201f800, 0x000202da, 0x497a6008, 0x5c028000, 0x5c025800, 0x8d3e7d00, 0x04000009, 0x4d340000, - 0x59326809, 0x0201f800, 0x00104801, 0x5c026800, - 0x0201f800, 0x00107698, 0x0401f00b, 0x4a026403, + 0x59326809, 0x0201f800, 0x001049b2, 0x5c026800, + 0x0201f800, 0x00107911, 0x0401f00b, 0x4a026403, 0x00000085, 0x4a026203, 0x00000009, 0x4a026406, 0x00000002, 0x42000800, 0x8000404b, 0x0201f800, - 0x00020855, 0x5c03e000, 0x02020800, 0x0010698c, + 0x00020721, 0x5c03e000, 0x02020800, 0x00106c55, 0x82000540, 0x00000001, 0x1c01f000, 0x0201f800, - 0x00106982, 0x0201f800, 0x00100ee4, 0x0401f7ab, + 0x00106c4b, 0x0201f800, 0x00100e99, 0x0401f7ab, 0x598c000d, 0x81300580, 0x04020004, 0x0201f800, - 0x00106be2, 0x0402001b, 0x0201f800, 0x00106619, + 0x00106e8e, 0x0402001b, 0x0201f800, 0x001068d3, 0x04020006, 0x59300c03, 0x82040580, 0x00000040, - 0x0400078b, 0x0401f79d, 0x0201f800, 0x001068a3, - 0x04000010, 0x0201f800, 0x00100615, 0x0401f813, - 0x04020004, 0x0201f800, 0x00106bb2, 0x04020009, - 0x0201f800, 0x001064f6, 0x040207f4, 0x59300c03, + 0x0400078b, 0x0401f79d, 0x0201f800, 0x00106b6c, + 0x04000010, 0x0201f800, 0x001005d8, 0x0401f813, + 0x04020004, 0x0201f800, 0x00106e62, 0x04020009, + 0x0201f800, 0x001067ae, 0x040207f4, 0x59300c03, 0x82040580, 0x00000040, 0x04000779, 0x0401f78b, 0x59300203, 0x82000c80, 0x0000000e, 0x02021800, - 0x00100615, 0x0c01f75e, 0x417a3000, 0x42032000, + 0x001005d8, 0x0c01f75e, 0x417a3000, 0x42032000, 0x0000bf32, 0x59900004, 0x81300580, 0x04000009, 0x83932400, 0x00000010, 0x811a3000, 0x83180480, 0x00000005, 0x040017f8, 0x82000540, 0x00000001, @@ -8914,591 +9061,585 @@ uint32_t risc_code01[] = { 0x82000d00, 0x0000001f, 0x82040580, 0x00000005, 0x04020004, 0x42000000, 0x00000003, 0x0401f005, 0x42000000, 0x00000001, 0x0401f002, 0x59300203, - 0x1c01f000, 0x4933c857, 0x0201f800, 0x0010698c, + 0x1c01f000, 0x4933c857, 0x0201f800, 0x00106c55, 0x4df00000, 0x59300203, 0x82000c80, 0x0000000e, - 0x02021800, 0x00100615, 0x0c01f001, 0x00108ac7, - 0x00108ae4, 0x00108acb, 0x00108ac5, 0x00108ac5, - 0x00108ac5, 0x00108ac5, 0x00108ac5, 0x00108ac5, - 0x00108ac5, 0x00108ac5, 0x00108ac5, 0x00108ac5, - 0x00108ac5, 0x0201f800, 0x00100615, 0x5c03e000, - 0x02000800, 0x00106982, 0x0401f6e8, 0x5c03e000, - 0x02000800, 0x00106982, 0x4d2c0000, 0x59325808, + 0x02021800, 0x001005d8, 0x0c01f001, 0x00108d13, + 0x00108d30, 0x00108d17, 0x00108d11, 0x00108d11, + 0x00108d11, 0x00108d11, 0x00108d11, 0x00108d11, + 0x00108d11, 0x00108d11, 0x00108d11, 0x00108d11, + 0x00108d11, 0x0201f800, 0x001005d8, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x0401f6e8, 0x5c03e000, + 0x02000800, 0x00106c4b, 0x4d2c0000, 0x59325808, 0x59300403, 0x82000580, 0x00000052, 0x02000800, - 0x00101281, 0x0401fb1f, 0x02000800, 0x00100615, - 0x4a025a06, 0x00000005, 0x0201f800, 0x00020381, - 0x0201f800, 0x00104a83, 0x0201f800, 0x00107698, + 0x00101231, 0x0401fb16, 0x02000800, 0x001005d8, + 0x4a025a06, 0x00000005, 0x0201f800, 0x000202da, + 0x0201f800, 0x00104c19, 0x0201f800, 0x00107911, 0x5c025800, 0x82000540, 0x00000001, 0x1c01f000, 0x598c000d, 0x81300580, 0x0402001a, 0x59300004, 0x8c000520, 0x04000004, 0x84000520, 0x48026004, - 0x0401f01a, 0x42001000, 0x0010b5f4, 0x50081000, + 0x0401f01a, 0x42001000, 0x0010b7f6, 0x50081000, 0x58080002, 0x82000580, 0x00000100, 0x0400000a, - 0x5808000c, 0x81300580, 0x02020800, 0x00100615, - 0x0201f800, 0x00106619, 0x02020800, 0x00100615, - 0x0401f7cf, 0x0201f800, 0x00106be2, 0x0402000c, + 0x5808000c, 0x81300580, 0x02020800, 0x001005d8, + 0x0201f800, 0x001068d3, 0x02020800, 0x001005d8, + 0x0401f7cf, 0x0201f800, 0x00106e8e, 0x0402000c, 0x59300004, 0x8c000520, 0x04000004, 0x84000520, - 0x48026004, 0x0401f7c6, 0x0201f800, 0x00106619, - 0x040007c3, 0x0201f800, 0x00100615, 0x59300203, - 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, + 0x48026004, 0x0401f7c6, 0x0201f800, 0x001068d3, + 0x040007c3, 0x0201f800, 0x001005d8, 0x59300203, + 0x82000c80, 0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7a7, 0x59300406, 0x4933c857, 0x4803c857, - 0x82000c80, 0x00000012, 0x02021800, 0x00100615, - 0x0c01f001, 0x00108b30, 0x00108bfe, 0x00108d36, - 0x00108b3c, 0x00107698, 0x00108b30, 0x00109faf, - 0x000208b4, 0x00108bfe, 0x00106306, 0x00108d97, - 0x00108b2b, 0x00108b2b, 0x00108b2b, 0x00108b2b, - 0x00108b2b, 0x001094b7, 0x001094b7, 0x0201f800, - 0x00100615, 0x0401fbd8, 0x02000000, 0x00107da6, - 0x1c01f000, 0x0201f800, 0x0010698c, 0x0201f800, - 0x001068f6, 0x0201f800, 0x00106982, 0x0201f000, - 0x000208b4, 0x4a026206, 0x00000001, 0x1c01f000, - 0x42000000, 0x0010b671, 0x0201f800, 0x0010a86e, - 0x4d2c0000, 0x4d400000, 0x417a5800, 0x0401fab1, + 0x82000c80, 0x00000012, 0x02021800, 0x001005d8, + 0x0c01f001, 0x00108d7c, 0x00108e41, 0x00108f79, + 0x00108d88, 0x00107911, 0x00108d7c, 0x0010a1c0, + 0x0002077d, 0x00108e41, 0x001065ce, 0x00108fda, + 0x00108d77, 0x00108d77, 0x00108d77, 0x00108d77, + 0x00108d77, 0x001096eb, 0x001096eb, 0x0201f800, + 0x001005d8, 0x0401fbd5, 0x02000000, 0x0010801c, + 0x1c01f000, 0x0201f800, 0x00106c55, 0x0201f800, + 0x00106bbf, 0x0201f800, 0x00106c4b, 0x0201f000, + 0x0002077d, 0x4a026206, 0x00000001, 0x1c01f000, + 0x42000000, 0x0010b872, 0x0201f800, 0x0010aa47, + 0x4d2c0000, 0x4d400000, 0x417a5800, 0x0401faa8, 0x04000007, 0x59325808, 0x592c0208, 0x8400054c, 0x48025a08, 0x42028000, 0x00000006, 0x0201f800, - 0x0010698c, 0x0401ff4c, 0x4803c857, 0x82000c80, - 0x0000000e, 0x02021800, 0x00100615, 0x0c01f806, - 0x0201f800, 0x00106982, 0x5c028000, 0x5c025800, - 0x1c01f000, 0x00108bfd, 0x00108b69, 0x00108b79, - 0x00108ba0, 0x00108bce, 0x00108b67, 0x00108b30, - 0x00108b30, 0x00108b30, 0x00108b67, 0x00108b67, - 0x00108b67, 0x00108b67, 0x00108b79, 0x0201f800, - 0x00100615, 0x598c000d, 0x4803c857, 0x81300580, - 0x04020004, 0x0201f800, 0x00106be2, 0x0402003f, - 0x0201f800, 0x00106619, 0x04000043, 0x4803c856, - 0x0201f800, 0x001068a3, 0x04000038, 0x0201f800, - 0x00100615, 0x497a621d, 0x812e59c0, 0x02000800, - 0x00100615, 0x592c0204, 0x4803c857, 0x82000500, - 0x000000ff, 0x82000580, 0x00000014, 0x04000003, - 0x4a02621d, 0x00000003, 0x592c0a08, 0x0201f800, - 0x00104bee, 0x0201f800, 0x00109365, 0x0201f800, - 0x00020381, 0x497a6008, 0x4a026403, 0x00000085, - 0x4a026203, 0x00000009, 0x4a026406, 0x00000002, - 0x59300804, 0x82040d00, 0x00000100, 0x82040d40, - 0x8000404b, 0x48066004, 0x0201f800, 0x00106982, - 0x42000800, 0x8000404b, 0x0201f000, 0x00020855, - 0x0401feea, 0x04020004, 0x0201f800, 0x00106bb2, - 0x0402000a, 0x0201f800, 0x001064f6, 0x040207cc, - 0x59300c03, 0x4807c857, 0x82040580, 0x00000040, - 0x04000009, 0x0401f7cc, 0x59300203, 0x4803c857, - 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, - 0x0c01f7a5, 0x0201f800, 0x00106982, 0x812e59c0, - 0x04000013, 0x592c0a08, 0x0201f800, 0x00104bee, - 0x0201f800, 0x00109365, 0x0201f800, 0x00020381, - 0x59300203, 0x82000580, 0x0000000d, 0x04000008, - 0x0201f800, 0x00106982, 0x4d340000, 0x59326809, - 0x0201f800, 0x00104801, 0x5c026800, 0x0201f800, - 0x00107698, 0x0401f030, 0x812e59c0, 0x02000800, - 0x00100615, 0x0201f800, 0x001091d3, 0x04020004, - 0x0201f800, 0x00100ee4, 0x0401f7a3, 0x0201f800, - 0x00106982, 0x592c0208, 0x8400050c, 0x48025a08, - 0x592c0406, 0x800000c2, 0x800008c4, 0x80040c00, - 0x48066206, 0x42000000, 0x10000000, 0x41300800, - 0x0201f800, 0x00100bde, 0x0400000d, 0x592c0208, - 0x8c00051c, 0x04020006, 0x8400055c, 0x48025a08, - 0x4a026206, 0x00000002, 0x0401f00f, 0x4d300000, - 0x0201f800, 0x00101335, 0x5c026000, 0x59300203, - 0x82000580, 0x00000004, 0x04020007, 0x4d380000, - 0x42027000, 0x00000048, 0x0201f800, 0x000208d8, - 0x5c027000, 0x1c01f000, 0x42000000, 0x0010b66d, - 0x0201f800, 0x0010a86e, 0x59300203, 0x82000c80, - 0x0000000e, 0x02021800, 0x00100615, 0x4803c857, - 0x0c01f001, 0x00108c17, 0x00108b39, 0x00108c19, - 0x00108c17, 0x00108c19, 0x00108c19, 0x00108b31, - 0x00108c17, 0x00108b2d, 0x00108c17, 0x00108c17, - 0x00108c17, 0x00108c17, 0x00108c17, 0x0201f800, - 0x00100615, 0x4d340000, 0x4d2c0000, 0x59326809, - 0x59340400, 0x82000500, 0x000000ff, 0x82000c80, - 0x0000000c, 0x02021800, 0x00100615, 0x59303403, - 0x82180d80, 0x00000004, 0x04020004, 0x42000000, - 0x00000001, 0x0401f006, 0x82180d80, 0x00000000, - 0x04020003, 0x42000000, 0x00000001, 0x4803c857, - 0x0c01f804, 0x5c025800, 0x5c026800, 0x1c01f000, - 0x00108c40, 0x00108cdf, 0x00108c42, 0x00108c77, - 0x00108c42, 0x00108cfc, 0x00108c42, 0x00108c4c, - 0x00108c40, 0x00108cfc, 0x00108c40, 0x00108c5b, - 0x0201f800, 0x00100615, 0x59300403, 0x82000d80, - 0x00000016, 0x0400002e, 0x82000d80, 0x00000004, - 0x0400002b, 0x82000d80, 0x00000002, 0x04000028, - 0x0401fab9, 0x04000079, 0x59300403, 0x82000d80, - 0x00000022, 0x040000ae, 0x82000d80, 0x00000039, - 0x040000b3, 0x82000d80, 0x00000035, 0x040000b0, - 0x82000d80, 0x0000001e, 0x0400001b, 0x0401f999, - 0x04000007, 0x0201f800, 0x00109360, 0x04020004, - 0x0201f800, 0x00104863, 0x0401f011, 0x59300403, - 0x82000d80, 0x00000001, 0x04020004, 0x0201f800, - 0x00104836, 0x0400000a, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x00101de2, 0x5c027800, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x0201f800, - 0x00107da6, 0x0201f000, 0x00107698, 0x0401f97d, - 0x04000004, 0x0201f800, 0x00109360, 0x040000a9, - 0x59300c03, 0x82040580, 0x00000016, 0x04000056, - 0x82040580, 0x00000002, 0x04020034, 0x59a80026, - 0x8c000502, 0x04020013, 0x0201f800, 0x00104e0d, - 0x04020010, 0x0201f800, 0x00104e23, 0x04020006, - 0x42000000, 0x00000001, 0x0201f800, 0x00104de5, - 0x0401f094, 0x4a035033, 0x00000001, 0x4202d800, - 0x00000001, 0x0201f800, 0x00104d76, 0x0401f08d, - 0x59340403, 0x82000580, 0x000007fc, 0x04000008, - 0x59a80026, 0x8c00050a, 0x04020084, 0x59340212, - 0x82000500, 0x0000ff00, 0x04000082, 0x59340412, - 0x82000500, 0x000000ff, 0x04000010, 0x80000040, - 0x48026c12, 0x497a6008, 0x4a026406, 0x00000007, - 0x4a026206, 0x00000398, 0x497a6205, 0x0201f800, - 0x00020892, 0x04000005, 0x49366009, 0x4a026406, - 0x00000001, 0x0401f020, 0x59300403, 0x82000d80, - 0x00000002, 0x0402000d, 0x59340403, 0x82000580, - 0x000007fe, 0x04020009, 0x59a80026, 0x84000540, - 0x48035026, 0x0201f800, 0x00104067, 0x0201f800, - 0x00107da6, 0x0401f00c, 0x0201f800, 0x00107da6, - 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, - 0x5c027800, 0x42000000, 0x0010b663, 0x0201f800, - 0x0010a86e, 0x0201f800, 0x00101e1b, 0x0201f000, - 0x00107698, 0x42000800, 0x00000003, 0x0201f800, - 0x001043c7, 0x4a026203, 0x00000001, 0x4a026403, - 0x00000002, 0x0201f000, 0x00106470, 0x0401f915, - 0x04020793, 0x0201f800, 0x00101e1b, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, - 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, - 0x42003000, 0x00000018, 0x41782800, 0x42002000, - 0x00000000, 0x4d400000, 0x4d440000, 0x59368c03, - 0x42028000, 0x00000029, 0x0201f800, 0x0010962a, - 0x5c028800, 0x5c028000, 0x0201f000, 0x00107698, - 0x0201f800, 0x00104863, 0x0401f7c8, 0x42000000, - 0x0010b66c, 0x0201f800, 0x0010a86e, 0x0201f800, - 0x001078fd, 0x040207c1, 0x1c01f000, 0x4d380000, - 0x59327403, 0x0201f800, 0x00109183, 0x5c027000, - 0x02020000, 0x000208b4, 0x836c0580, 0x00000003, - 0x04000004, 0x4a026206, 0x00000002, 0x1c01f000, - 0x59300403, 0x48026416, 0x4a02621d, 0x00000001, - 0x4a026403, 0x00000085, 0x4a026203, 0x00000009, - 0x4a026406, 0x00000002, 0x42000800, 0x8000004b, - 0x0201f000, 0x00020855, 0x0201f800, 0x00101e1b, - 0x0201f800, 0x00107da6, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x00101de2, 0x5c027800, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x497a6008, - 0x4a026406, 0x00000007, 0x4a026206, 0x00000398, - 0x497a6205, 0x1c01f000, 0x42000000, 0x0010b66f, - 0x0201f800, 0x0010a86e, 0x4d340000, 0x59326809, - 0x59300203, 0x82000c80, 0x0000000e, 0x02021800, - 0x00100615, 0x4803c857, 0x0c01f803, 0x5c026800, - 0x1c01f000, 0x00108d53, 0x00108b39, 0x00108d53, - 0x00108d53, 0x00108d53, 0x00108d53, 0x00108d53, - 0x00108d53, 0x00108d53, 0x00108b39, 0x00108d55, - 0x00108b39, 0x00108d5d, 0x00108d53, 0x0201f800, - 0x00100615, 0x4a026403, 0x0000008b, 0x4a026203, - 0x0000000b, 0x42000800, 0x8000404b, 0x0201f000, - 0x00020855, 0x59300a1d, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x00101de2, 0x5c027800, 0x42003000, - 0x00000011, 0x0201f800, 0x0010a766, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x41306800, - 0x0201f800, 0x00020892, 0x04000008, 0x49366009, - 0x4d300000, 0x40366000, 0x0201f800, 0x00107698, - 0x5c026000, 0x0401f002, 0x40366000, 0x497a6008, - 0x4a026406, 0x00000001, 0x4a026403, 0x00000001, - 0x0201f800, 0x0010393e, 0x04000011, 0x4a026406, - 0x00000004, 0x4a026203, 0x00000007, 0x4a026420, - 0x00000001, 0x42003000, 0x00000004, 0x4d400000, - 0x42028000, 0x00000029, 0x41782800, 0x0201f800, - 0x0010a250, 0x5c028000, 0x1c01f000, 0x42000800, - 0x0000000b, 0x0201f800, 0x001043c7, 0x4a026203, - 0x00000001, 0x0201f000, 0x00106470, 0x42000000, - 0x0010b675, 0x0201f800, 0x0010a86e, 0x59300203, - 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, - 0x4803c857, 0x0c01f001, 0x00108dc8, 0x00108db0, - 0x00108db4, 0x00108dc9, 0x00108db2, 0x00108db0, - 0x00108db0, 0x00108db0, 0x00108db0, 0x00108db0, - 0x00108db0, 0x00108db0, 0x00108db0, 0x00108db0, - 0x0201f800, 0x00100615, 0x0201f800, 0x00100ee4, - 0x4d2c0000, 0x59325808, 0x4a025a06, 0x00000006, - 0x0201f800, 0x00020381, 0x5c025800, 0x497a6008, - 0x4a02621d, 0x0000000a, 0x4a026403, 0x00000085, - 0x4a026203, 0x00000009, 0x4a026406, 0x00000002, - 0x42000800, 0x8000404b, 0x0201f000, 0x00020855, - 0x1c01f000, 0x0201f800, 0x0010698c, 0x4df00000, - 0x0401fcbe, 0x04020004, 0x0201f800, 0x00106bb2, - 0x0402000c, 0x0201f800, 0x001064f6, 0x04020005, - 0x5c03e000, 0x0201f800, 0x00106982, 0x0401f7dd, - 0x0201f800, 0x001068a3, 0x02020800, 0x00100615, - 0x5c03e000, 0x0201f800, 0x00106982, 0x59300203, - 0x82000d80, 0x00000003, 0x02000800, 0x00100615, - 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, - 0x0c01f7ba, 0x4803c856, 0x59a8000e, 0x59a80867, - 0x80040400, 0x80080480, 0x04021004, 0x82000540, - 0x00000001, 0x1c01f000, 0x80000580, 0x1c01f000, - 0x4803c856, 0x4c080000, 0x59301008, 0x82081500, - 0xfff00000, 0x5c001000, 0x1c01f000, 0x4803c856, - 0x4d300000, 0x0201f800, 0x00020892, 0x0400000a, - 0x0401f82f, 0x4d380000, 0x42027000, 0x0000004b, - 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, - 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, - 0x4d300000, 0x0201f800, 0x001076c9, 0x0400001b, - 0x0401f81f, 0x4d300000, 0x0201f800, 0x0010698c, - 0x4d3c0000, 0x417a7800, 0x0201f800, 0x001067f6, - 0x0201f800, 0x00106543, 0x5c027800, 0x0201f800, - 0x0010a0da, 0x0201f800, 0x00106982, 0x5c026000, - 0x8d3e7d3e, 0x0402000b, 0x4d380000, 0x42027000, - 0x0000004c, 0x0201f800, 0x000208d8, 0x5c027000, - 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, - 0x0201f800, 0x000208b4, 0x0401f7fa, 0x592c0407, - 0x494a6017, 0x494e6018, 0x49366009, 0x492e6008, - 0x4a026406, 0x00000003, 0x800000c2, 0x800008c4, - 0x80040400, 0x48026206, 0x1c01f000, 0x493bc857, - 0x4d300000, 0x0201f800, 0x00020892, 0x0400000d, - 0x0401ffef, 0x4d400000, 0x42028000, 0x00000005, - 0x0401f80d, 0x5c028000, 0x8d3e7d3e, 0x04020007, - 0x0201f800, 0x000208d8, 0x82000540, 0x00000001, - 0x5c026000, 0x1c01f000, 0x0201f800, 0x000208b4, - 0x0401f7fa, 0x4803c856, 0x0201f800, 0x0010698c, - 0x4d3c0000, 0x4d440000, 0x59368c03, 0x42027800, - 0x00000001, 0x0201f800, 0x001066ff, 0x0201f800, - 0x00106675, 0x0201f800, 0x00106543, 0x0201f800, - 0x0010a0da, 0x5c028800, 0x5c027800, 0x0201f000, - 0x00106982, 0x4803c856, 0x4d300000, 0x0201f800, - 0x00020892, 0x0400000f, 0x481a601c, 0x48ee6021, - 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, - 0x4d380000, 0x42027000, 0x0000001f, 0x0201f800, - 0x000208d8, 0x5c027000, 0x82000540, 0x00000001, - 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, - 0x0201f800, 0x00020892, 0x0400000e, 0x48ee6021, - 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, - 0x4d380000, 0x42027000, 0x00000055, 0x0201f800, - 0x000208d8, 0x5c027000, 0x82000540, 0x00000001, + 0x00106c55, 0x0401ff4c, 0x4803c857, 0x82000c80, + 0x0000000e, 0x02021800, 0x001005d8, 0x0c01f806, + 0x0201f800, 0x00106c4b, 0x5c028000, 0x5c025800, + 0x1c01f000, 0x00108e40, 0x00108db5, 0x00108dc3, + 0x00108de5, 0x00108e11, 0x00108db3, 0x00108d7c, + 0x00108d7c, 0x00108d7c, 0x00108db3, 0x00108db3, + 0x00108db3, 0x00108db3, 0x00108dc3, 0x0201f800, + 0x001005d8, 0x598c000d, 0x81300580, 0x04020004, + 0x0201f800, 0x00106e8e, 0x04020038, 0x0201f800, + 0x001068d3, 0x0400003b, 0x0201f800, 0x00106b6c, + 0x04000032, 0x0201f800, 0x001005d8, 0x497a621d, + 0x812e59c0, 0x02000800, 0x001005d8, 0x592c0204, + 0x82000500, 0x000000ff, 0x82000580, 0x00000014, + 0x04000003, 0x4a02621d, 0x00000003, 0x592c0a08, + 0x0201f800, 0x00104e70, 0x0201f800, 0x0010959c, + 0x0201f800, 0x000202da, 0x497a6008, 0x4a026403, + 0x00000085, 0x4a026203, 0x00000009, 0x4a026406, + 0x00000002, 0x4a026004, 0x8000404b, 0x0201f800, + 0x00106c4b, 0x42000800, 0x8000404b, 0x0201f000, + 0x00020721, 0x0401fef1, 0x04020004, 0x0201f800, + 0x00106e62, 0x04020009, 0x0201f800, 0x001067ae, + 0x040207d2, 0x59300c03, 0x82040580, 0x00000040, + 0x04000008, 0x0401f7d2, 0x59300203, 0x82000c80, + 0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7ae, + 0x0201f800, 0x00106c4b, 0x812e59c0, 0x04000013, + 0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800, + 0x0010959c, 0x0201f800, 0x000202da, 0x59300203, + 0x82000580, 0x0000000d, 0x04000008, 0x0201f800, + 0x00106c4b, 0x4d340000, 0x59326809, 0x0201f800, + 0x001049b2, 0x5c026800, 0x0201f800, 0x00107911, + 0x0401f030, 0x812e59c0, 0x02000800, 0x001005d8, + 0x0201f800, 0x0010940a, 0x04020004, 0x0201f800, + 0x00100e99, 0x0401f7aa, 0x0201f800, 0x00106c4b, + 0x592c0208, 0x8400050c, 0x48025a08, 0x592c0406, + 0x800000c2, 0x800008c4, 0x80040c00, 0x48066206, + 0x42000000, 0x10000000, 0x41300800, 0x0201f800, + 0x00100b94, 0x0400000d, 0x592c0208, 0x8c00051c, + 0x04020006, 0x8400055c, 0x48025a08, 0x4a026206, + 0x00000002, 0x0401f00f, 0x4d300000, 0x0201f800, + 0x001012e5, 0x5c026000, 0x59300203, 0x82000580, + 0x00000004, 0x04020007, 0x4d380000, 0x42027000, + 0x00000048, 0x0201f800, 0x000207a1, 0x5c027000, + 0x1c01f000, 0x42000000, 0x0010b86e, 0x0201f800, + 0x0010aa47, 0x59300203, 0x82000c80, 0x0000000e, + 0x02021800, 0x001005d8, 0x4803c857, 0x0c01f001, + 0x00108e5a, 0x00108d85, 0x00108e5c, 0x00108e5a, + 0x00108e5c, 0x00108e5c, 0x00108d7d, 0x00108e5a, + 0x00108d79, 0x00108e5a, 0x00108e5a, 0x00108e5a, + 0x00108e5a, 0x00108e5a, 0x0201f800, 0x001005d8, + 0x4d340000, 0x4d2c0000, 0x59326809, 0x59340400, + 0x82000500, 0x000000ff, 0x82000c80, 0x0000000c, + 0x02021800, 0x001005d8, 0x59303403, 0x82180d80, + 0x00000004, 0x04020004, 0x42000000, 0x00000001, + 0x0401f006, 0x82180d80, 0x00000000, 0x04020003, + 0x42000000, 0x00000001, 0x4803c857, 0x0c01f804, + 0x5c025800, 0x5c026800, 0x1c01f000, 0x00108e83, + 0x00108f22, 0x00108e85, 0x00108eba, 0x00108e85, + 0x00108f3f, 0x00108e85, 0x00108e8f, 0x00108e83, + 0x00108f3f, 0x00108e83, 0x00108e9e, 0x0201f800, + 0x001005d8, 0x59300403, 0x82000d80, 0x00000016, + 0x0400002e, 0x82000d80, 0x00000004, 0x0400002b, + 0x82000d80, 0x00000002, 0x04000028, 0x0401fabf, + 0x04000079, 0x59300403, 0x82000d80, 0x00000022, + 0x040000ae, 0x82000d80, 0x00000039, 0x040000b3, + 0x82000d80, 0x00000035, 0x040000b0, 0x82000d80, + 0x0000001e, 0x0400001b, 0x0401f999, 0x04000007, + 0x0201f800, 0x00109597, 0x04020004, 0x0201f800, + 0x00104a14, 0x0401f011, 0x59300403, 0x82000d80, + 0x00000001, 0x04020004, 0x0201f800, 0x001049e7, + 0x0400000a, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x0010203c, 0x5c027800, 0x42000000, 0x0010b864, + 0x0201f800, 0x0010aa47, 0x0201f800, 0x0010801c, + 0x0201f000, 0x00107911, 0x0401f97d, 0x04000004, + 0x0201f800, 0x00109597, 0x040000a9, 0x59300c03, + 0x82040580, 0x00000016, 0x04000056, 0x82040580, + 0x00000002, 0x04020034, 0x59a80026, 0x8c000502, + 0x04020013, 0x0201f800, 0x0010513b, 0x04020010, + 0x0201f800, 0x00105151, 0x04020006, 0x42000000, + 0x00000001, 0x0201f800, 0x00105113, 0x0401f094, + 0x4a035033, 0x00000001, 0x4202d800, 0x00000001, + 0x0201f800, 0x001050a2, 0x0401f08d, 0x59340403, + 0x82000580, 0x000007fc, 0x04000008, 0x59a80026, + 0x8c00050a, 0x04020084, 0x59340212, 0x82000500, + 0x0000ff00, 0x04000082, 0x59340412, 0x82000500, + 0x000000ff, 0x04000010, 0x80000040, 0x48026c12, + 0x497a6008, 0x4a026406, 0x00000007, 0x4a026206, + 0x00000398, 0x497a6205, 0x0201f800, 0x0002075a, + 0x04000005, 0x49366009, 0x4a026406, 0x00000001, + 0x0401f020, 0x59300403, 0x82000d80, 0x00000002, + 0x0402000d, 0x59340403, 0x82000580, 0x000007fe, + 0x04020009, 0x59a80026, 0x84000540, 0x48035026, + 0x0201f800, 0x00104237, 0x0201f800, 0x0010801c, + 0x0401f00c, 0x0201f800, 0x0010801c, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800, + 0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47, + 0x0201f800, 0x00102074, 0x0201f000, 0x00107911, + 0x42000800, 0x00000003, 0x0201f800, 0x00104571, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000002, + 0x0201f000, 0x0010672b, 0x0401f915, 0x04020793, + 0x0201f800, 0x00102074, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x0010203c, 0x5c027800, 0x42000000, + 0x0010b864, 0x0201f800, 0x0010aa47, 0x42003000, + 0x00000018, 0x41782800, 0x42002000, 0x00000000, + 0x4d400000, 0x4d440000, 0x59368c03, 0x42028000, + 0x00000029, 0x0201f800, 0x0010985e, 0x5c028800, + 0x5c028000, 0x0201f000, 0x00107911, 0x0201f800, + 0x00104a14, 0x0401f7c8, 0x42000000, 0x0010b86d, + 0x0201f800, 0x0010aa47, 0x0201f800, 0x00107b76, + 0x040207c1, 0x1c01f000, 0x4d380000, 0x59327403, + 0x0201f800, 0x001093ba, 0x5c027000, 0x02020000, + 0x0002077d, 0x836c0580, 0x00000003, 0x04000004, + 0x4a026206, 0x00000002, 0x1c01f000, 0x59300403, + 0x48026416, 0x4a02621d, 0x00000001, 0x4a026403, + 0x00000085, 0x4a026203, 0x00000009, 0x4a026406, + 0x00000002, 0x42000800, 0x8000004b, 0x0201f000, + 0x00020721, 0x0201f800, 0x00102074, 0x0201f800, + 0x0010801c, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x0010203c, 0x5c027800, 0x42000000, 0x0010b864, + 0x0201f800, 0x0010aa47, 0x497a6008, 0x4a026406, + 0x00000007, 0x4a026206, 0x00000398, 0x497a6205, + 0x1c01f000, 0x42000000, 0x0010b870, 0x0201f800, + 0x0010aa47, 0x4d340000, 0x59326809, 0x59300203, + 0x82000c80, 0x0000000e, 0x02021800, 0x001005d8, + 0x4803c857, 0x0c01f803, 0x5c026800, 0x1c01f000, + 0x00108f96, 0x00108d85, 0x00108f96, 0x00108f96, + 0x00108f96, 0x00108f96, 0x00108f96, 0x00108f96, + 0x00108f96, 0x00108d85, 0x00108f98, 0x00108d85, + 0x00108fa0, 0x00108f96, 0x0201f800, 0x001005d8, + 0x4a026403, 0x0000008b, 0x4a026203, 0x0000000b, + 0x42000800, 0x8000404b, 0x0201f000, 0x00020721, + 0x59300a1d, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x0010203c, 0x5c027800, 0x42003000, 0x00000011, + 0x0201f800, 0x0010a942, 0x42000000, 0x0010b864, + 0x0201f800, 0x0010aa47, 0x41306800, 0x0201f800, + 0x0002075a, 0x04000008, 0x49366009, 0x4d300000, + 0x40366000, 0x0201f800, 0x00107911, 0x5c026000, + 0x0401f002, 0x40366000, 0x497a6008, 0x4a026406, + 0x00000001, 0x4a026403, 0x00000001, 0x0201f800, + 0x00103b25, 0x04000011, 0x4a026406, 0x00000004, + 0x4a026203, 0x00000007, 0x4a026420, 0x00000001, + 0x42003000, 0x00000004, 0x4d400000, 0x42028000, + 0x00000029, 0x41782800, 0x0201f800, 0x0010a43e, + 0x5c028000, 0x1c01f000, 0x42000800, 0x0000000b, + 0x0201f800, 0x00104571, 0x4a026203, 0x00000001, + 0x0201f000, 0x0010672b, 0x42000000, 0x0010b876, + 0x0201f800, 0x0010aa47, 0x59300203, 0x82000c80, + 0x0000000e, 0x02021800, 0x001005d8, 0x4803c857, + 0x0c01f001, 0x0010900b, 0x00108ff3, 0x00108ff7, + 0x0010900c, 0x00108ff5, 0x00108ff3, 0x00108ff3, + 0x00108ff3, 0x00108ff3, 0x00108ff3, 0x00108ff3, + 0x00108ff3, 0x00108ff3, 0x00108ff3, 0x0201f800, + 0x001005d8, 0x0201f800, 0x00100e99, 0x4d2c0000, + 0x59325808, 0x4a025a06, 0x00000006, 0x0201f800, + 0x000202da, 0x5c025800, 0x497a6008, 0x4a02621d, + 0x0000000a, 0x4a026403, 0x00000085, 0x4a026203, + 0x00000009, 0x4a026406, 0x00000002, 0x42000800, + 0x8000404b, 0x0201f000, 0x00020721, 0x1c01f000, + 0x0201f800, 0x00106c55, 0x4df00000, 0x0401fcc7, + 0x04020004, 0x0201f800, 0x00106e62, 0x0402000c, + 0x0201f800, 0x001067ae, 0x04020005, 0x5c03e000, + 0x0201f800, 0x00106c4b, 0x0401f7dd, 0x0201f800, + 0x00106b6c, 0x02020800, 0x001005d8, 0x5c03e000, + 0x0201f800, 0x00106c4b, 0x59300203, 0x82000d80, + 0x00000003, 0x02000800, 0x001005d8, 0x82000c80, + 0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7ba, + 0x4803c856, 0x59a8000e, 0x59a80867, 0x80040400, + 0x80080480, 0x04021004, 0x82000540, 0x00000001, + 0x1c01f000, 0x80000580, 0x1c01f000, 0x4803c856, + 0x4c080000, 0x59301008, 0x82081500, 0xfff00000, + 0x5c001000, 0x1c01f000, 0x4803c856, 0x4d300000, + 0x0201f800, 0x0002075a, 0x0400000a, 0x0401f82f, + 0x4d380000, 0x42027000, 0x0000004b, 0x0201f800, + 0x000207a1, 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, - 0x0201f800, 0x00020892, 0x0400000f, 0x481a601c, - 0x48ee6021, 0x49366009, 0x4a026406, 0x00000001, - 0x492e6008, 0x4d380000, 0x42027000, 0x0000003d, - 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, - 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, - 0x4d300000, 0x0201f800, 0x001076c9, 0x04000014, - 0x49366009, 0x492fc857, 0x4933c857, 0x592c0404, - 0x8c00051e, 0x04000003, 0x48efc857, 0x48ee6021, + 0x0201f800, 0x00107942, 0x0400001b, 0x0401f81f, + 0x4d300000, 0x0201f800, 0x00106c55, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00106ab4, 0x0201f800, + 0x001067fd, 0x5c027800, 0x0201f800, 0x0010a2ff, + 0x0201f800, 0x00106c4b, 0x5c026000, 0x8d3e7d3e, + 0x0402000b, 0x4d380000, 0x42027000, 0x0000004c, + 0x0201f800, 0x000207a1, 0x5c027000, 0x82000540, + 0x00000001, 0x5c026000, 0x1c01f000, 0x0201f800, + 0x0002077d, 0x0401f7fa, 0x592c0407, 0x494a6017, + 0x494e6018, 0x49366009, 0x492e6008, 0x4a026406, + 0x00000003, 0x800000c2, 0x800008c4, 0x80040400, + 0x48026206, 0x1c01f000, 0x493bc857, 0x4d300000, + 0x0201f800, 0x0002075a, 0x0400000d, 0x0401ffef, + 0x4d400000, 0x42028000, 0x00000005, 0x0401f80d, + 0x5c028000, 0x8d3e7d3e, 0x04020007, 0x0201f800, + 0x000207a1, 0x82000540, 0x00000001, 0x5c026000, + 0x1c01f000, 0x0201f800, 0x0002077d, 0x0401f7fa, + 0x4803c856, 0x0201f800, 0x00106c55, 0x4d3c0000, + 0x4d440000, 0x59368c03, 0x42027800, 0x00000001, + 0x0201f800, 0x001069b6, 0x0201f800, 0x0010692e, + 0x0201f800, 0x001067fd, 0x0201f800, 0x0010a2ff, + 0x5c028800, 0x5c027800, 0x0201f000, 0x00106c4b, + 0x4803c856, 0x4d300000, 0x0201f800, 0x0002075a, + 0x0400000f, 0x481a601c, 0x48ee6021, 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, 0x4d380000, - 0x42027000, 0x00000000, 0x0201f800, 0x000208d8, + 0x42027000, 0x0000001f, 0x0201f800, 0x000207a1, 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800, - 0x00020892, 0x0400000f, 0x48ee6021, 0x481a601c, + 0x0002075a, 0x0400000e, 0x48ee6021, 0x49366009, + 0x4a026406, 0x00000001, 0x492e6008, 0x4d380000, + 0x42027000, 0x00000055, 0x0201f800, 0x000207a1, + 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, + 0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800, + 0x0002075a, 0x0400000f, 0x481a601c, 0x48ee6021, 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, - 0x4d380000, 0x42027000, 0x00000044, 0x0201f800, - 0x000208d8, 0x5c027000, 0x82000540, 0x00000001, + 0x4d380000, 0x42027000, 0x0000003d, 0x0201f800, + 0x000207a1, 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, - 0x0201f800, 0x00020892, 0x0400000f, 0x481a601c, - 0x48ee6021, 0x49366009, 0x4a026406, 0x00000001, - 0x492e6008, 0x4d380000, 0x42027000, 0x00000049, - 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, - 0x00000001, 0x5c026000, 0x1c01f000, 0x59300009, - 0x80001540, 0x02000800, 0x00100615, 0x5808040b, - 0x4803c856, 0x80000040, 0x04001002, 0x4800140b, - 0x1c01f000, 0x4803c856, 0x59300403, 0x82000d80, - 0x00000002, 0x0400000f, 0x82000d80, 0x00000003, - 0x0400000c, 0x82000d80, 0x00000004, 0x04000009, - 0x599c0819, 0x8c040d0e, 0x04000004, 0x82000d80, - 0x00000000, 0x04000003, 0x82000540, 0x00000001, - 0x1c01f000, 0x4803c856, 0x4c000000, 0x4d2c0000, - 0x59300406, 0x82000580, 0x00000004, 0x0400001d, - 0x59300008, 0x80025d40, 0x800001c0, 0x04000019, - 0x0201f800, 0x00109360, 0x04000014, 0x59300406, - 0x82004580, 0x00000010, 0x04000010, 0x82004580, - 0x00000011, 0x0400000d, 0x82004580, 0x00000003, - 0x0400000c, 0x82004580, 0x00000002, 0x04000009, - 0x82004580, 0x0000000a, 0x04000006, 0x592c0404, - 0x8c00051e, 0x04000003, 0x80000580, 0x0401f003, - 0x82000540, 0x00000001, 0x5c025800, 0x5c000000, + 0x0201f800, 0x00107942, 0x04000014, 0x49366009, + 0x492fc857, 0x4933c857, 0x592c0404, 0x8c00051e, + 0x04000003, 0x48efc857, 0x48ee6021, 0x4a026406, + 0x00000001, 0x492e6008, 0x4d380000, 0x42027000, + 0x00000000, 0x0201f800, 0x000207a1, 0x5c027000, + 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, + 0x4803c856, 0x4d300000, 0x0201f800, 0x0002075a, + 0x0400000f, 0x48ee6021, 0x481a601c, 0x49366009, + 0x4a026406, 0x00000001, 0x492e6008, 0x4d380000, + 0x42027000, 0x00000044, 0x0201f800, 0x000207a1, + 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800, - 0x001076c9, 0x04000013, 0x49366009, 0x48ee6021, - 0x4a026406, 0x00000001, 0x492e6008, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, - 0x4d380000, 0x42027000, 0x00000028, 0x0201f800, - 0x000208d8, 0x5c027000, 0x82000540, 0x00000001, - 0x5c026000, 0x1c01f000, 0x4803c856, 0x83380580, - 0x00000015, 0x0402000d, 0x59a80016, 0x82000580, - 0x00000074, 0x04020009, 0x0201f800, 0x00104480, - 0x4a026203, 0x00000001, 0x4a026403, 0x00000029, - 0x0201f000, 0x00106470, 0x0201f800, 0x00107da6, - 0x0201f000, 0x000208b4, 0x4803c856, 0x83380580, - 0x00000016, 0x04020007, 0x42000800, 0x00000004, - 0x0201f800, 0x001043c7, 0x0201f000, 0x001078bf, - 0x83380580, 0x00000015, 0x04020013, 0x59a80016, - 0x82000580, 0x00000014, 0x0402000f, 0x0201f800, - 0x001044e1, 0x0201f800, 0x00108210, 0x0402000a, - 0x59340404, 0x80000540, 0x04000007, 0x42000800, - 0x00000006, 0x0201f800, 0x001043c7, 0x0201f000, - 0x001078bf, 0x0201f800, 0x00107da6, 0x0201f000, - 0x000208b4, 0x4803c856, 0x592c0206, 0x82000580, - 0x00000005, 0x04000002, 0x1c01f000, 0x4803c856, - 0x592c0208, 0x8400054a, 0x48025a08, 0x1c01f000, - 0x497a6205, 0x497a6008, 0x4a026203, 0x00000001, - 0x4a026403, 0x00000050, 0x42000800, 0x80000043, - 0x0201f000, 0x00020855, 0x4933c857, 0x4d340000, - 0x59326809, 0x59340200, 0x8c00050e, 0x04000006, - 0x59300406, 0x82000c80, 0x00000012, 0x04021004, - 0x0c01f806, 0x5c026800, 0x1c01f000, 0x0201f800, - 0x00108b30, 0x0401f7fc, 0x00108b30, 0x00108fb4, - 0x00108fb8, 0x00108fbb, 0x0010a2b9, 0x0010a2d6, - 0x0010a2da, 0x00108b30, 0x00108b30, 0x00108b30, - 0x00108b30, 0x00108b30, 0x00108b30, 0x00108b30, - 0x00108b30, 0x00108b30, 0x00108b30, 0x00108b30, - 0x4803c856, 0x40000000, 0x40000000, 0x1c01f000, - 0x40000000, 0x40000000, 0x1c01f000, 0x5930001c, - 0x4803c857, 0x59300414, 0x4933c857, 0x4803c857, - 0x8c000502, 0x04000005, 0x4803c857, 0x84000540, - 0x48026414, 0x1c01f000, 0x42000000, 0xd0000000, - 0x41300800, 0x0201f800, 0x00100bde, 0x0401f810, - 0x0402000e, 0x59300c14, 0x59300403, 0x82000580, - 0x00000040, 0x04000003, 0x84040d40, 0x0401f005, - 0x59a80037, 0x82000400, 0x0000000a, 0x48026205, - 0x84040d42, 0x48066414, 0x1c01f000, 0x4933c857, + 0x0002075a, 0x0400000f, 0x481a601c, 0x48ee6021, + 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, + 0x4d380000, 0x42027000, 0x00000049, 0x0201f800, + 0x000207a1, 0x5c027000, 0x82000540, 0x00000001, + 0x5c026000, 0x1c01f000, 0x59300009, 0x80001540, + 0x02000800, 0x001005d8, 0x5808040b, 0x4803c856, + 0x80000040, 0x04001002, 0x4800140b, 0x1c01f000, + 0x4803c856, 0x59300403, 0x82000d80, 0x00000002, + 0x04000015, 0x82000d80, 0x00000003, 0x04000012, + 0x82000d80, 0x00000004, 0x0400000f, 0x82000d80, + 0x00000008, 0x0400000c, 0x82000d80, 0x0000000a, + 0x04000009, 0x599c0819, 0x8c040d0e, 0x04000004, + 0x82000d80, 0x00000000, 0x04000003, 0x82000540, + 0x00000001, 0x1c01f000, 0x4803c856, 0x4c000000, + 0x4d2c0000, 0x59300406, 0x82000580, 0x00000004, + 0x0400001d, 0x59300008, 0x80025d40, 0x800001c0, + 0x04000019, 0x0201f800, 0x00109597, 0x04000014, + 0x59300406, 0x82004580, 0x00000010, 0x04000010, + 0x82004580, 0x00000011, 0x0400000d, 0x82004580, + 0x00000003, 0x0400000c, 0x82004580, 0x00000002, + 0x04000009, 0x82004580, 0x0000000a, 0x04000006, + 0x592c0404, 0x8c00051e, 0x04000003, 0x80000580, + 0x0401f003, 0x82000540, 0x00000001, 0x5c025800, + 0x5c000000, 0x1c01f000, 0x4803c856, 0x4d300000, + 0x0201f800, 0x00107942, 0x04000013, 0x49366009, + 0x48ee6021, 0x4a026406, 0x00000001, 0x492e6008, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c, + 0x5c027800, 0x4d380000, 0x42027000, 0x00000028, + 0x0201f800, 0x000207a1, 0x5c027000, 0x82000540, + 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, + 0x83380580, 0x00000015, 0x0402000d, 0x59a80016, + 0x82000580, 0x00000074, 0x04020009, 0x0201f800, + 0x0010462a, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000029, 0x0201f000, 0x0010672b, 0x0201f800, + 0x0010801c, 0x0201f000, 0x0002077d, 0x4803c856, + 0x83380580, 0x00000016, 0x04020007, 0x42000800, + 0x00000004, 0x0201f800, 0x00104571, 0x0201f000, + 0x00107b38, 0x83380580, 0x00000015, 0x04020013, + 0x59a80016, 0x82000580, 0x00000014, 0x0402000f, + 0x0201f800, 0x0010468d, 0x0201f800, 0x0010846f, + 0x0402000a, 0x59340404, 0x80000540, 0x04000007, + 0x42000800, 0x00000006, 0x0201f800, 0x00104571, + 0x0201f000, 0x00107b38, 0x0201f800, 0x0010801c, + 0x0201f000, 0x0002077d, 0x4803c856, 0x592c0206, + 0x82000580, 0x00000005, 0x04000002, 0x1c01f000, + 0x4803c856, 0x592c0208, 0x8400054a, 0x48025a08, + 0x1c01f000, 0x497a6205, 0x497a6008, 0x4a026203, + 0x00000001, 0x4a026403, 0x00000050, 0x42000800, + 0x80000043, 0x0201f000, 0x00020721, 0x4933c857, 0x4d340000, 0x59326809, 0x59340200, 0x8c00050e, - 0x02000800, 0x00100615, 0x5930001c, 0x80000540, - 0x04020034, 0x59300403, 0x4803c857, 0x82000580, - 0x00000040, 0x04000004, 0x59a80021, 0x80000540, - 0x0402002a, 0x4d1c0000, 0x41323800, 0x0201f800, - 0x00020892, 0x04000023, 0x4932381c, 0x591c0414, - 0x84000542, 0x48023c14, 0x49366009, 0x591c0406, - 0x82000580, 0x00000003, 0x04000006, 0x591c0202, - 0x48026419, 0x591c0402, 0x48026219, 0x0401f005, - 0x591c0202, 0x48026219, 0x591c0402, 0x48026419, - 0x491e601e, 0x4a026406, 0x00000001, 0x4a026403, - 0x00000035, 0x4a026203, 0x00000001, 0x42000800, - 0x80000040, 0x0201f800, 0x00020855, 0x411e6000, - 0x5c023800, 0x80000580, 0x5c026800, 0x1c01f000, - 0x411e6000, 0x5c023800, 0x59a80039, 0x48026205, - 0x82000540, 0x00000001, 0x0401f7f8, 0x4933c857, - 0x4d2c0000, 0x4932381c, 0x4a026202, 0x0000ffff, - 0x591e5808, 0x591c0007, 0x8c00051e, 0x04000005, - 0x8400051e, 0x48023807, 0x497a5c09, 0x0401f018, - 0x592c0408, 0x8c000518, 0x04000015, 0x84000518, - 0x48025c08, 0x4d400000, 0x592e8206, 0x4a025a06, - 0x00000001, 0x0401fb34, 0x49425a06, 0x5c028000, - 0x497a5c09, 0x592c0408, 0x8c000512, 0x04000008, - 0x4d2c0000, 0x84000512, 0x48025c08, 0x592e5809, - 0x0201f800, 0x00100843, 0x5c025800, 0x59a80039, - 0x48026205, 0x591c0214, 0x48026216, 0x82000d80, - 0x00000001, 0x04000008, 0x4a023a03, 0x00000002, - 0x82000580, 0x00000005, 0x04000008, 0x497a6015, - 0x0401f01e, 0x591c0007, 0x84000540, 0x48023807, - 0x4a023a03, 0x00000004, 0x591c0414, 0x4803c857, - 0x8400051c, 0x84000554, 0x48023c14, 0x592c000f, - 0x40001000, 0x591c0816, 0x80040480, 0x040217f0, - 0x591c0016, 0x82000500, 0xfffffffc, 0x48026015, - 0x48023816, 0x591c0a14, 0x4807c857, 0x82040d80, - 0x00000005, 0x04020005, 0x480bc857, 0x4803c857, - 0x4a023812, 0xffffffff, 0x591c0402, 0x48026419, - 0x591c0202, 0x48026219, 0x591e6809, 0x49366009, - 0x4a026406, 0x00000001, 0x4a026403, 0x00000039, - 0x4a026203, 0x00000001, 0x42000800, 0x80000040, - 0x0201f800, 0x00020855, 0x5c025800, 0x1c01f000, - 0x4933c857, 0x59300414, 0x8c000514, 0x04000015, - 0x8c00051c, 0x04020012, 0x59300016, 0x80100480, - 0x04001006, 0x04000005, 0x59300414, 0x84000514, - 0x8400055c, 0x0401f009, 0x48126016, 0x48126012, - 0x40100000, 0x592c180f, 0x800c0480, 0x48026011, - 0x59300414, 0x84000514, 0x48026414, 0x1c01f000, - 0x4933c857, 0x8c00051c, 0x04020006, 0x59300012, - 0x48026016, 0x59300414, 0x8400055c, 0x48026414, - 0x1c01f000, 0x59300c03, 0x4933c857, 0x4807c857, - 0x82040480, 0x00000034, 0x04001006, 0x82040480, - 0x0000003c, 0x04021003, 0x80000580, 0x1c01f000, - 0x82000540, 0x00000001, 0x0401f7fd, 0x41780800, - 0x59a81035, 0x42000000, 0x00000032, 0x0201f800, - 0x001063ee, 0x800811c0, 0x04020003, 0x42001000, - 0x00000014, 0x480b5037, 0x59a81036, 0x480b502d, - 0x41780800, 0x42000000, 0x00000064, 0x0201f800, - 0x001063ee, 0x800811c0, 0x04020003, 0x42001000, - 0x00000014, 0x480b5038, 0x82081400, 0x0000000a, - 0x480b5039, 0x42000800, 0x00000001, 0x0201f800, - 0x001069af, 0x42000000, 0x30000000, 0x40080800, - 0x0201f800, 0x00100bb2, 0x42000800, 0x00000003, - 0x59a81010, 0x0201f800, 0x001069af, 0x0201f000, - 0x00104755, 0x4a035037, 0x00000028, 0x4a035038, - 0x00000014, 0x4a03502d, 0x000007d0, 0x42001000, - 0x0000001e, 0x480b5039, 0x42000800, 0x00000001, - 0x0201f800, 0x001069af, 0x42000000, 0x30000000, - 0x40080800, 0x0201f800, 0x00100bb2, 0x42000800, - 0x00000003, 0x59a81010, 0x0201f000, 0x001069af, - 0x4933c857, 0x4d2c0000, 0x59300403, 0x82000580, - 0x0000003e, 0x04020005, 0x59325817, 0x812e59c0, - 0x02020800, 0x0010083a, 0x5c025800, 0x1c01f000, - 0x4937c857, 0x4d300000, 0x0201f800, 0x00020892, - 0x04000011, 0x49366009, 0x4a026406, 0x00000001, - 0x492e6008, 0x42000800, 0x00000009, 0x0201f800, - 0x001043c7, 0x4d380000, 0x42027000, 0x00000033, - 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, - 0x00000001, 0x5c026000, 0x1c01f000, 0x4933c857, - 0x4d2c0000, 0x4c580000, 0x4d3c0000, 0x59325808, - 0x83380580, 0x00000015, 0x04020025, 0x59a8b016, - 0x82580c80, 0x00000019, 0x04001003, 0x4200b000, - 0x00000018, 0x8058b104, 0x0401fa0a, 0x80000580, - 0x0401fa1a, 0x832cac00, 0x00000009, 0x83cca400, - 0x00000006, 0x0201f800, 0x0010a93e, 0x4c600000, - 0x4200c000, 0x00000001, 0x592c100a, 0x8c081518, - 0x04020006, 0x59a80010, 0x592c100d, 0x80080580, - 0x04020007, 0x4178c000, 0x59301009, 0x58081403, - 0x417a7800, 0x0201f800, 0x00101e48, 0x5c00c000, - 0x0201f800, 0x001078bf, 0x0401f008, 0x4200b000, - 0x00000002, 0x0401fa09, 0x0201f800, 0x00107da6, - 0x0201f800, 0x000208b4, 0x5c027800, 0x5c00b000, - 0x5c025800, 0x1c01f000, 0x4933c856, 0x49366009, - 0x4a026406, 0x00000001, 0x492e6008, 0x4d380000, - 0x42027000, 0x0000004d, 0x0201f800, 0x000208d8, - 0x5c027000, 0x82000540, 0x00000001, 0x1c01f000, - 0x4803c856, 0x4d2c0000, 0x83380580, 0x00000015, - 0x04020027, 0x59a80816, 0x59325808, 0x5930040b, - 0x800000c4, 0x80040580, 0x04020021, 0x4c500000, - 0x4c540000, 0x4c580000, 0x83cca400, 0x00000006, - 0x4050a800, 0x5930b40b, 0x0201f800, 0x0010a94f, - 0x83cca400, 0x00000006, 0x592cb205, 0x832cac00, - 0x00000006, 0x0201f800, 0x0010a93e, 0x592e5801, - 0x812e59c0, 0x040207f9, 0x5931d821, 0x58ef400b, - 0x58ee580d, 0x4a025a04, 0x00000103, 0x58ec0009, - 0x0801f800, 0x59300402, 0x5c00b000, 0x5c00a800, - 0x5c00a000, 0x5c025800, 0x1c01f000, 0x0201f800, - 0x00107da6, 0x5c025800, 0x1c01f000, 0x4933c857, - 0x83380580, 0x00000035, 0x04000005, 0x59301419, - 0x0401f851, 0x04000027, 0x0401f006, 0x4d300000, - 0x5932601e, 0x0401f856, 0x5c026000, 0x04000020, - 0x591c0c06, 0x82040580, 0x00000003, 0x04000004, - 0x82040580, 0x00000006, 0x0402001c, 0x591c0c02, - 0x59300419, 0x80040580, 0x04000009, 0x59300219, - 0x80040580, 0x04020015, 0x591c0a02, 0x59300419, - 0x80040580, 0x04020011, 0x0401f009, 0x59300a19, - 0x82040580, 0x0000ffff, 0x04000005, 0x591c0202, - 0x59300a19, 0x80040580, 0x04020008, 0x591c0009, - 0x59300809, 0x80040580, 0x1c01f000, 0x417a3800, - 0x82000540, 0x00000001, 0x1c01f000, 0x4803c856, - 0x59b800e4, 0x8c000538, 0x02020800, 0x00100615, - 0x42000800, 0x0000012c, 0x4a0370e4, 0x20000000, - 0x59b800e4, 0x80040840, 0x02000800, 0x00100615, - 0x8c00053c, 0x040207f9, 0x4a0370e4, 0x30000000, - 0x40000000, 0x40000000, 0x40000000, 0x59b800e4, - 0x8c00053c, 0x040207f1, 0x1c01f000, 0x4803c856, - 0x4a0370e4, 0x20000000, 0x40000000, 0x59b800e4, - 0x8c000538, 0x040207fb, 0x1c01f000, 0x59300807, - 0x8c040d1e, 0x592c0c08, 0x04020002, 0x8c040d18, - 0x1c01f000, 0x0401fc10, 0x04000008, 0x42000800, - 0x00000024, 0x0201f800, 0x001063cf, 0x82063c00, - 0x0010cfc0, 0x491fc857, 0x1c01f000, 0x83300480, - 0x0010cfc0, 0x0400100a, 0x59a8000b, 0x81300480, - 0x04021007, 0x59301402, 0x0401ffef, 0x04000007, - 0x411c0000, 0x81300580, 0x04000003, 0x81780500, - 0x0401f002, 0x81300540, 0x1c01f000, 0x4947c857, - 0x4d300000, 0x0201f800, 0x00020267, 0x0402000a, - 0x42026000, 0x0010bbe8, 0x49366009, 0x492e6008, - 0x0201f800, 0x00101de2, 0x80000580, 0x5c026000, - 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fc, - 0x4933c857, 0x0201f800, 0x00108df4, 0x02000800, - 0x00100615, 0x4d2c0000, 0x4d340000, 0x4d440000, - 0x4c580000, 0x59325808, 0x59326809, 0x49425a06, - 0x0201f800, 0x00105439, 0x592e8c06, 0x592c4207, - 0x82200500, 0x0000000f, 0x0c01f806, 0x5c00b000, - 0x5c028800, 0x5c026800, 0x5c025800, 0x1c01f000, - 0x0010922f, 0x00109251, 0x00109258, 0x0010925c, - 0x00109265, 0x0010922c, 0x0010922c, 0x0010922c, - 0x00109269, 0x00109275, 0x00109275, 0x0010922c, - 0x0010922c, 0x0010922c, 0x0010922c, 0x0010922c, - 0x4803c857, 0x0201f800, 0x00100615, 0x814281c0, - 0x04020012, 0x41785800, 0x592c0404, 0x8c00051c, - 0x04020002, 0x59345c05, 0x442c2800, 0x59340008, - 0x48002802, 0x59340009, 0x48002801, 0x59340006, - 0x48002804, 0x59340007, 0x48002803, 0x4200b000, - 0x0000000b, 0x0401f037, 0x592c0207, 0x8c00051e, - 0x4200b000, 0x00000002, 0x04020032, 0x8204b540, - 0x00000000, 0x0400002f, 0x44042800, 0x59326809, - 0x59340400, 0x48002801, 0x4200b000, 0x00000002, - 0x0401f028, 0x814281c0, 0x04020030, 0x59345c05, - 0x442c2800, 0x4200b000, 0x00000001, 0x0401f021, - 0x8340b540, 0x00000000, 0x0400001e, 0x0401f027, - 0x814281c0, 0x04020025, 0x59340200, 0x44002800, - 0x59340001, 0x48002801, 0x4200b000, 0x00000002, - 0x0401f014, 0x8340b540, 0x00000000, 0x0402001b, - 0x0401f010, 0x8340b540, 0x00000000, 0x0400000d, - 0x0201f800, 0x00104871, 0x04000014, 0x8c20450e, - 0x04000002, 0x497a6009, 0x4178b000, 0x497a5a06, - 0x0401f004, 0x8340b540, 0x00000000, 0x0402000b, - 0x592c0404, 0x8400051c, 0x48025c04, 0x592c0207, - 0x8400051e, 0x48025a07, 0x0401f8aa, 0x497a6008, - 0x0201f000, 0x00020381, 0x592c0207, 0x8c00051e, - 0x4200b000, 0x00000002, 0x040207f2, 0x8204b540, - 0x00000000, 0x040007ef, 0x44042800, 0x4200b000, - 0x00000001, 0x0401f7eb, 0x4937c857, 0x4d300000, - 0x0201f800, 0x00020892, 0x04000011, 0x49366009, + 0x04000006, 0x59300406, 0x82000c80, 0x00000012, + 0x04021004, 0x0c01f806, 0x5c026800, 0x1c01f000, + 0x0201f800, 0x00108d7c, 0x0401f7fc, 0x00108d7c, + 0x001091fd, 0x00109201, 0x00109204, 0x0010a49b, + 0x0010a4b8, 0x0010a4bc, 0x00108d7c, 0x00108d7c, + 0x00108d7c, 0x00108d7c, 0x00108d7c, 0x00108d7c, + 0x00108d7c, 0x00108d7c, 0x00108d7c, 0x00108d7c, + 0x00108d7c, 0x4803c856, 0x40000000, 0x40000000, + 0x1c01f000, 0x40000000, 0x40000000, 0x1c01f000, + 0x5930001c, 0x4803c857, 0x59300414, 0x4933c857, + 0x4803c857, 0x8c000502, 0x04000005, 0x84000502, + 0x84000540, 0x48026414, 0x1c01f000, 0x42000000, + 0xd0000000, 0x41300800, 0x0201f800, 0x00100b94, + 0x0401f80a, 0x04020008, 0x59a80037, 0x82000400, + 0x0000000a, 0x48026205, 0x59300414, 0x84000542, + 0x48026414, 0x1c01f000, 0x4933c857, 0x4d340000, + 0x59326809, 0x59340200, 0x8c00050e, 0x02000800, + 0x001005d8, 0x5930001c, 0x80000540, 0x0402002f, + 0x59a80021, 0x80000540, 0x0402002a, 0x4d1c0000, + 0x41323800, 0x0201f800, 0x0002075a, 0x04000023, + 0x4932381c, 0x591c0414, 0x84000542, 0x48023c14, + 0x49366009, 0x591c0406, 0x82000580, 0x00000003, + 0x04000006, 0x591c0202, 0x48026419, 0x591c0402, + 0x48026219, 0x0401f005, 0x591c0202, 0x48026219, + 0x591c0402, 0x48026419, 0x491e601e, 0x4a026406, + 0x00000001, 0x4a026403, 0x00000035, 0x4a026203, + 0x00000001, 0x42000800, 0x80000040, 0x0201f800, + 0x00020721, 0x411e6000, 0x5c023800, 0x80000580, + 0x5c026800, 0x1c01f000, 0x411e6000, 0x5c023800, + 0x59a80039, 0x48026205, 0x82000540, 0x00000001, + 0x0401f7f8, 0x4933c857, 0x4d2c0000, 0x4932381c, + 0x4a026202, 0x0000ffff, 0x591e5808, 0x591c0007, + 0x8c00051e, 0x04000005, 0x8400051e, 0x48023807, + 0x497a5c09, 0x0401f014, 0x592c0408, 0x8c000518, + 0x04000011, 0x84000518, 0x48025c08, 0x4a025c09, + 0x00000001, 0x0401fb2f, 0x497a5c09, 0x592c0408, + 0x8c000512, 0x04000008, 0x4d2c0000, 0x84000512, + 0x48025c08, 0x592e5809, 0x0201f800, 0x001007fd, + 0x5c025800, 0x59a80039, 0x48026205, 0x591c0214, + 0x48026216, 0x82000d80, 0x00000001, 0x04000008, + 0x4a023a03, 0x00000002, 0x82000580, 0x00000005, + 0x04000008, 0x497a6015, 0x0401f01e, 0x591c0007, + 0x84000540, 0x48023807, 0x4a023a03, 0x00000004, + 0x591c0414, 0x4803c857, 0x8400051c, 0x84000554, + 0x48023c14, 0x592c000f, 0x40001000, 0x591c0816, + 0x80040480, 0x040217f0, 0x591c0016, 0x82000500, + 0xfffffffc, 0x48026015, 0x48023816, 0x591c0a14, + 0x4807c857, 0x82040d80, 0x00000005, 0x04020005, + 0x480bc857, 0x4803c857, 0x4a023812, 0xffffffff, + 0x591c0402, 0x48026419, 0x591c0202, 0x48026219, + 0x591e6809, 0x49366009, 0x4a026406, 0x00000001, + 0x4a026403, 0x00000039, 0x4a026203, 0x00000001, + 0x42000800, 0x80000040, 0x0201f800, 0x00020721, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x59300414, + 0x8c000514, 0x04000015, 0x8c00051c, 0x04020012, + 0x59300016, 0x80100480, 0x04001006, 0x04000005, + 0x59300414, 0x84000514, 0x8400055c, 0x0401f009, + 0x48126016, 0x48126012, 0x40100000, 0x592c180f, + 0x800c0480, 0x48026011, 0x59300414, 0x84000514, + 0x48026414, 0x1c01f000, 0x4933c857, 0x8c00051c, + 0x04020006, 0x59300012, 0x48026016, 0x59300414, + 0x8400055c, 0x48026414, 0x1c01f000, 0x59300c03, + 0x4933c857, 0x4807c857, 0x82040480, 0x00000034, + 0x04001006, 0x82040480, 0x0000003c, 0x04021003, + 0x80000580, 0x1c01f000, 0x82000540, 0x00000001, + 0x0401f7fd, 0x41780800, 0x59a81035, 0x42000000, + 0x00000032, 0x0201f800, 0x001066a0, 0x800811c0, + 0x04020003, 0x42001000, 0x00000014, 0x480b5037, + 0x59a81036, 0x480b502d, 0x41780800, 0x42000000, + 0x00000064, 0x0201f800, 0x001066a0, 0x800811c0, + 0x04020003, 0x42001000, 0x00000014, 0x480b5038, + 0x82081400, 0x0000000a, 0x480b5039, 0x42000800, + 0x00000001, 0x0201f800, 0x00106c78, 0x42000000, + 0x30000000, 0x40080800, 0x0201f800, 0x00100b68, + 0x42000800, 0x00000003, 0x59a81010, 0x0201f800, + 0x00106c78, 0x0201f000, 0x00104906, 0x4a035037, + 0x00000028, 0x4a035038, 0x00000014, 0x4a03502d, + 0x000007d0, 0x42001000, 0x0000001e, 0x480b5039, + 0x42000800, 0x00000001, 0x0201f800, 0x00106c78, + 0x42000000, 0x30000000, 0x40080800, 0x0201f800, + 0x00100b68, 0x42000800, 0x00000003, 0x59a81010, + 0x0201f000, 0x00106c78, 0x4933c857, 0x4d2c0000, + 0x59300403, 0x82000580, 0x0000003e, 0x04020005, + 0x59325817, 0x812e59c0, 0x02020800, 0x001007f4, + 0x5c025800, 0x1c01f000, 0x4937c857, 0x4d300000, + 0x0201f800, 0x0002075a, 0x04000011, 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, 0x42000800, - 0x0000000b, 0x0201f800, 0x001043c7, 0x4d380000, - 0x42027000, 0x00000043, 0x0201f800, 0x000208d8, + 0x00000009, 0x0201f800, 0x00104571, 0x4d380000, + 0x42027000, 0x00000033, 0x0201f800, 0x000207a1, 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, - 0x1c01f000, 0x4937c857, 0x4d2c0000, 0x59325808, - 0x83380580, 0x00000015, 0x04020025, 0x59a80016, - 0x82000580, 0x00000004, 0x04020021, 0x59a80010, - 0x592c1009, 0x80080580, 0x04020010, 0x4d440000, - 0x592e8c06, 0x592c0207, 0x4803c856, 0x82000500, - 0x00000080, 0x84000548, 0x4d3c0000, 0x42027800, - 0x00001000, 0x0201f800, 0x0010480a, 0x5c027800, - 0x5c028800, 0x0401f004, 0x4803c856, 0x0201f800, - 0x00104871, 0x0201f800, 0x00108df4, 0x04000017, - 0x4d400000, 0x42028000, 0x00000000, 0x41780800, - 0x0401ff38, 0x5c028000, 0x0401f00e, 0x0201f800, - 0x00104871, 0x040207f4, 0x0201f800, 0x00108df4, - 0x0400000a, 0x4c580000, 0x4200b000, 0x00000002, - 0x0401f86e, 0x5c00b000, 0x0201f800, 0x00107da6, - 0x0201f800, 0x000208b4, 0x5c025800, 0x1c01f000, - 0x4937c857, 0x4d300000, 0x0201f800, 0x00020892, - 0x04000012, 0x49366009, 0x4a026406, 0x00000001, - 0x4d3c0000, 0x4d380000, 0x417a7800, 0x0201f800, - 0x001043bd, 0x492e6008, 0x42027000, 0x00000004, - 0x0201f800, 0x000208d8, 0x5c027000, 0x5c027800, + 0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c580000, + 0x4d3c0000, 0x59325808, 0x83380580, 0x00000015, + 0x04020022, 0x59a8b016, 0x82580c80, 0x00000019, + 0x04001003, 0x4200b000, 0x00000018, 0x8058b104, + 0x0401fa07, 0x80000580, 0x0401fa17, 0x832cac00, + 0x00000009, 0x83cca400, 0x00000006, 0x0201f800, + 0x0010ab17, 0x42027800, 0x00000001, 0x592c100a, + 0x8c081518, 0x04020006, 0x59a80010, 0x592c100d, + 0x80080580, 0x04020006, 0x417a7800, 0x59301009, + 0x58081403, 0x0201f800, 0x001020a1, 0x0201f800, + 0x00107b38, 0x0401f008, 0x4200b000, 0x00000002, + 0x0401fa09, 0x0201f800, 0x0010801c, 0x0201f800, + 0x0002077d, 0x5c027800, 0x5c00b000, 0x5c025800, + 0x1c01f000, 0x4933c856, 0x49366009, 0x4a026406, + 0x00000001, 0x492e6008, 0x4d380000, 0x42027000, + 0x0000004d, 0x0201f800, 0x000207a1, 0x5c027000, + 0x82000540, 0x00000001, 0x1c01f000, 0x4803c856, + 0x4d2c0000, 0x83380580, 0x00000015, 0x04020027, + 0x59a80816, 0x59325808, 0x5930040b, 0x800000c4, + 0x80040580, 0x04020021, 0x4c500000, 0x4c540000, + 0x4c580000, 0x83cca400, 0x00000006, 0x4050a800, + 0x5930b40b, 0x0201f800, 0x0010ab28, 0x83cca400, + 0x00000006, 0x592cb205, 0x832cac00, 0x00000006, + 0x0201f800, 0x0010ab17, 0x592e5801, 0x812e59c0, + 0x040207f9, 0x5931d821, 0x58ef400b, 0x58ee580d, + 0x4a025a04, 0x00000103, 0x58ec0009, 0x0801f800, + 0x59300402, 0x5c00b000, 0x5c00a800, 0x5c00a000, + 0x5c025800, 0x1c01f000, 0x0201f800, 0x0010801c, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x83380580, + 0x00000035, 0x04000005, 0x59301419, 0x0401f851, + 0x04000027, 0x0401f006, 0x4d300000, 0x5932601e, + 0x0401f856, 0x5c026000, 0x04000020, 0x591c0c06, + 0x82040580, 0x00000003, 0x04000004, 0x82040580, + 0x00000006, 0x0402001c, 0x591c0c02, 0x59300419, + 0x80040580, 0x04000009, 0x59300219, 0x80040580, + 0x04020015, 0x591c0a02, 0x59300419, 0x80040580, + 0x04020011, 0x0401f009, 0x59300a19, 0x82040580, + 0x0000ffff, 0x04000005, 0x591c0202, 0x59300a19, + 0x80040580, 0x04020008, 0x591c0009, 0x59300809, + 0x80040580, 0x1c01f000, 0x417a3800, 0x82000540, + 0x00000001, 0x1c01f000, 0x4803c856, 0x59b800e4, + 0x8c000538, 0x02020800, 0x001005d8, 0x42000800, + 0x0000012c, 0x4a0370e4, 0x20000000, 0x59b800e4, + 0x80040840, 0x02000800, 0x001005d8, 0x8c00053c, + 0x040207f9, 0x4a0370e4, 0x30000000, 0x40000000, + 0x40000000, 0x40000000, 0x59b800e4, 0x8c00053c, + 0x040207f1, 0x1c01f000, 0x4803c856, 0x4a0370e4, + 0x20000000, 0x40000000, 0x59b800e4, 0x8c000538, + 0x040207fb, 0x1c01f000, 0x59300807, 0x8c040d1e, + 0x592c0c08, 0x04020002, 0x8c040d18, 0x1c01f000, + 0x0401fc1c, 0x04000008, 0x42000800, 0x00000024, + 0x0201f800, 0x00106681, 0x82063c00, 0x0010d1c0, + 0x491fc857, 0x1c01f000, 0x83300480, 0x0010d1c0, + 0x0400100a, 0x59a8000b, 0x81300480, 0x04021007, + 0x59301402, 0x0401ffef, 0x04000007, 0x411c0000, + 0x81300580, 0x04000003, 0x81780500, 0x0401f002, + 0x81300540, 0x1c01f000, 0x4947c857, 0x4d300000, + 0x0201f800, 0x00020245, 0x0402000a, 0x42026000, + 0x0010bde9, 0x49366009, 0x492e6008, 0x0201f800, + 0x0010203c, 0x80000580, 0x5c026000, 0x1c01f000, + 0x82000540, 0x00000001, 0x0401f7fc, 0x4933c857, + 0x0201f800, 0x00109037, 0x02000800, 0x001005d8, + 0x4d2c0000, 0x4d340000, 0x4d440000, 0x4c580000, + 0x59325808, 0x59326809, 0x49425a06, 0x0201f800, + 0x00105755, 0x592e8c06, 0x592c4207, 0x82200500, + 0x0000000f, 0x0c01f806, 0x5c00b000, 0x5c028800, + 0x5c026800, 0x5c025800, 0x1c01f000, 0x00109466, + 0x00109488, 0x0010948f, 0x00109493, 0x0010949c, + 0x00109463, 0x00109463, 0x00109463, 0x001094a0, + 0x001094ac, 0x001094ac, 0x00109463, 0x00109463, + 0x00109463, 0x00109463, 0x00109463, 0x4803c857, + 0x0201f800, 0x001005d8, 0x814281c0, 0x04020012, + 0x41785800, 0x592c0404, 0x8c00051c, 0x04020002, + 0x59345c05, 0x442c2800, 0x59340008, 0x48002802, + 0x59340009, 0x48002801, 0x59340006, 0x48002804, + 0x59340007, 0x48002803, 0x4200b000, 0x0000000b, + 0x0401f037, 0x592c0207, 0x8c00051e, 0x4200b000, + 0x00000002, 0x04020032, 0x8204b540, 0x00000000, + 0x0400002f, 0x44042800, 0x59326809, 0x59340400, + 0x48002801, 0x4200b000, 0x00000002, 0x0401f028, + 0x814281c0, 0x04020030, 0x59345c05, 0x442c2800, + 0x4200b000, 0x00000001, 0x0401f021, 0x8340b540, + 0x00000000, 0x0400001e, 0x0401f027, 0x814281c0, + 0x04020025, 0x59340200, 0x44002800, 0x59340001, + 0x48002801, 0x4200b000, 0x00000002, 0x0401f014, + 0x8340b540, 0x00000000, 0x0402001b, 0x0401f010, + 0x8340b540, 0x00000000, 0x0400000d, 0x0201f800, + 0x00104a1f, 0x04000014, 0x8c20450e, 0x04000002, + 0x497a6009, 0x4178b000, 0x497a5a06, 0x0401f004, + 0x8340b540, 0x00000000, 0x0402000b, 0x592c0404, + 0x8400051c, 0x48025c04, 0x592c0207, 0x8400051e, + 0x48025a07, 0x0401f8aa, 0x497a6008, 0x0201f000, + 0x000202da, 0x592c0207, 0x8c00051e, 0x4200b000, + 0x00000002, 0x040207f2, 0x8204b540, 0x00000000, + 0x040007ef, 0x44042800, 0x4200b000, 0x00000001, + 0x0401f7eb, 0x4937c857, 0x4d300000, 0x0201f800, + 0x0002075a, 0x04000011, 0x49366009, 0x4a026406, + 0x00000001, 0x492e6008, 0x42000800, 0x0000000b, + 0x0201f800, 0x00104571, 0x4d380000, 0x42027000, + 0x00000043, 0x0201f800, 0x000207a1, 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, - 0x4937c857, 0x4d300000, 0x0201f800, 0x001076c9, - 0x0400000d, 0x49366009, 0x4a026406, 0x00000001, - 0x492e6008, 0x4d380000, 0x42027000, 0x00000051, - 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, - 0x00000001, 0x5c026000, 0x1c01f000, 0x4933c857, - 0x4c580000, 0x59325808, 0x83383580, 0x00000015, - 0x04020011, 0x592c0008, 0x82000500, 0x00ffffff, - 0x0402000a, 0x0201f800, 0x00105439, 0x59cc0000, - 0x82000500, 0x00ffffff, 0x44002800, 0x4200b000, - 0x00000001, 0x0401f80b, 0x0201f800, 0x001078bf, - 0x0401f006, 0x4200b000, 0x00000002, 0x0401f823, - 0x0201f800, 0x00107da6, 0x5c00b000, 0x1c01f000, - 0x492fc857, 0x4c580000, 0x4c000000, 0x8058b1c0, - 0x0400000b, 0x82580500, 0xfffffff0, 0x02020800, - 0x00100615, 0x8058b0d0, 0x592c0408, 0x82000500, - 0xfffff0ff, 0x80580540, 0x48025c08, 0x5c000000, - 0x5c00b000, 0x1c01f000, 0x492fc857, 0x4c000000, - 0x4c040000, 0x800000d8, 0x592c0c08, 0x82040d00, - 0xffff0fff, 0x80040540, 0x48025c08, 0x5c000800, - 0x5c000000, 0x1c01f000, 0x4933c857, 0x4d2c0000, - 0x59325808, 0x592c0207, 0x8400055e, 0x48025a07, - 0x4c500000, 0x4c540000, 0x4c580000, 0x0401ffd9, - 0x0201f800, 0x00105439, 0x46002800, 0x00000018, - 0x80142800, 0x8058b040, 0x83cca400, 0x00000007, - 0x4014a800, 0x0201f800, 0x0010a93e, 0x5c00b000, - 0x5c00a800, 0x5c00a000, 0x5c025800, 0x1c01f000, - 0x59325808, 0x592c0204, 0x82000580, 0x00000152, - 0x1c01f000, 0x5930001f, 0x80000540, 0x02020800, - 0x00100d9a, 0x1c01f000, 0x4d2c0000, 0x59325808, - 0x59300203, 0x4933c857, 0x492fc857, 0x493bc857, - 0x4803c857, 0x82003480, 0x0000000e, 0x02021800, - 0x00100615, 0x0c01f803, 0x5c025800, 0x1c01f000, - 0x00109386, 0x00109391, 0x001093cf, 0x00109386, - 0x00109386, 0x00109386, 0x00109386, 0x00109386, - 0x00109388, 0x00109386, 0x00109386, 0x00109386, - 0x00109386, 0x00109386, 0x0201f800, 0x00100615, - 0x83383480, 0x00000056, 0x02021800, 0x00100615, - 0x493a6403, 0x4a026203, 0x00000001, 0x0201f000, - 0x00106470, 0x83380580, 0x00000013, 0x04020010, - 0x4937c857, 0x592c000c, 0x800001c0, 0x04000006, - 0x4a026203, 0x00000002, 0x59a80037, 0x48026206, - 0x1c01f000, 0x4a025a06, 0x00000000, 0x0201f800, - 0x00020381, 0x0201f000, 0x000208b4, 0x83380580, - 0x00000027, 0x0400001b, 0x83380580, 0x00000014, - 0x04000012, 0x83380580, 0x00000015, 0x04000005, - 0x83380580, 0x00000016, 0x02020800, 0x00100615, - 0x0201f800, 0x00106cb4, 0x02020000, 0x001076fb, - 0x59300203, 0x82000580, 0x00000002, 0x02020800, - 0x00100615, 0x0401f016, 0x4937c857, 0x0201f800, - 0x001068f6, 0x4a02580e, 0x00000011, 0x0401f006, - 0x4937c857, 0x0201f800, 0x001068f6, 0x4a02580e, + 0x4937c857, 0x4d2c0000, 0x59325808, 0x83380580, + 0x00000015, 0x04020025, 0x59a80016, 0x82000580, + 0x00000004, 0x04020021, 0x59a80010, 0x592c1009, + 0x80080580, 0x04020010, 0x4d440000, 0x592e8c06, + 0x592c0207, 0x4803c856, 0x82000500, 0x00000080, + 0x84000548, 0x4d3c0000, 0x42027800, 0x00001000, + 0x0201f800, 0x001049bb, 0x5c027800, 0x5c028800, + 0x0401f004, 0x4803c856, 0x0201f800, 0x00104a1f, + 0x0201f800, 0x00109037, 0x04000017, 0x4d400000, + 0x42028000, 0x00000000, 0x41780800, 0x0401ff38, + 0x5c028000, 0x0401f00e, 0x0201f800, 0x00104a1f, + 0x040207f4, 0x0201f800, 0x00109037, 0x0400000a, + 0x4c580000, 0x4200b000, 0x00000002, 0x0401f86e, + 0x5c00b000, 0x0201f800, 0x0010801c, 0x0201f800, + 0x0002077d, 0x5c025800, 0x1c01f000, 0x4937c857, + 0x4d300000, 0x0201f800, 0x0002075a, 0x04000012, + 0x49366009, 0x4a026406, 0x00000001, 0x4d3c0000, + 0x4d380000, 0x417a7800, 0x0201f800, 0x00104567, + 0x492e6008, 0x42027000, 0x00000004, 0x0201f800, + 0x000207a1, 0x5c027000, 0x5c027800, 0x82000540, + 0x00000001, 0x5c026000, 0x1c01f000, 0x4937c857, + 0x4d300000, 0x0201f800, 0x00107942, 0x0400000d, + 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, + 0x4d380000, 0x42027000, 0x00000051, 0x0201f800, + 0x000207a1, 0x5c027000, 0x82000540, 0x00000001, + 0x5c026000, 0x1c01f000, 0x4933c857, 0x4c580000, + 0x59325808, 0x83383580, 0x00000015, 0x04020011, + 0x592c0008, 0x82000500, 0x00ffffff, 0x0402000a, + 0x0201f800, 0x00105755, 0x59cc0000, 0x82000500, + 0x00ffffff, 0x44002800, 0x4200b000, 0x00000001, + 0x0401f80b, 0x0201f800, 0x00107b38, 0x0401f006, + 0x4200b000, 0x00000002, 0x0401f823, 0x0201f800, + 0x0010801c, 0x5c00b000, 0x1c01f000, 0x492fc857, + 0x4c580000, 0x4c000000, 0x8058b1c0, 0x0400000b, + 0x82580500, 0xfffffff0, 0x02020800, 0x001005d8, + 0x8058b0d0, 0x592c0408, 0x82000500, 0xfffff0ff, + 0x80580540, 0x48025c08, 0x5c000000, 0x5c00b000, + 0x1c01f000, 0x492fc857, 0x4c000000, 0x4c040000, + 0x800000d8, 0x592c0c08, 0x82040d00, 0xffff0fff, + 0x80040540, 0x48025c08, 0x5c000800, 0x5c000000, + 0x1c01f000, 0x4933c857, 0x4d2c0000, 0x59325808, + 0x592c0207, 0x8400055e, 0x48025a07, 0x4c500000, + 0x4c540000, 0x4c580000, 0x0401ffd9, 0x0201f800, + 0x00105755, 0x46002800, 0x00000018, 0x80142800, + 0x8058b040, 0x83cca400, 0x00000007, 0x4014a800, + 0x0201f800, 0x0010ab17, 0x5c00b000, 0x5c00a800, + 0x5c00a000, 0x5c025800, 0x1c01f000, 0x59325808, + 0x592c0204, 0x82000580, 0x00000152, 0x1c01f000, + 0x5930001f, 0x80000540, 0x02020800, 0x00100d56, + 0x1c01f000, 0x4d2c0000, 0x59325808, 0x59300203, + 0x4933c857, 0x492fc857, 0x493bc857, 0x4803c857, + 0x82003480, 0x0000000e, 0x02021800, 0x001005d8, + 0x0c01f803, 0x5c025800, 0x1c01f000, 0x001095bd, + 0x001095c8, 0x00109603, 0x001095bd, 0x001095bd, + 0x001095bd, 0x001095bd, 0x001095bd, 0x001095bf, + 0x001095bd, 0x001095bd, 0x001095bd, 0x001095bd, + 0x001095bd, 0x0201f800, 0x001005d8, 0x83383480, + 0x00000056, 0x02021800, 0x001005d8, 0x493a6403, + 0x4a026203, 0x00000001, 0x0201f000, 0x0010672b, + 0x83380580, 0x00000013, 0x0402000f, 0x592c000c, + 0x800001c0, 0x04000006, 0x4a026203, 0x00000002, + 0x59a80037, 0x48026206, 0x1c01f000, 0x4a025a06, + 0x00000000, 0x0201f800, 0x000202da, 0x0201f000, + 0x0002077d, 0x83380580, 0x00000027, 0x0400001a, + 0x83380580, 0x00000014, 0x04000012, 0x83380580, + 0x00000015, 0x04000005, 0x83380580, 0x00000016, + 0x02020800, 0x001005d8, 0x0201f800, 0x00106f60, + 0x02020000, 0x00107974, 0x59300203, 0x82000580, + 0x00000002, 0x02020800, 0x001005d8, 0x0401f014, + 0x0201f800, 0x00106bbf, 0x4a02580e, 0x00000011, + 0x0401f005, 0x0201f800, 0x00106bbf, 0x4a02580e, 0x00000010, 0x4a025a06, 0x00000031, 0x4a02580d, - 0x00000004, 0x0201f800, 0x00020381, 0x0201f800, - 0x00104a83, 0x0201f000, 0x00107698, 0x59341400, + 0x00000004, 0x0201f800, 0x000202da, 0x0201f800, + 0x00104c19, 0x0201f000, 0x00107911, 0x59341400, 0x82081d00, 0x000000ff, 0x59300c03, 0x480bc857, 0x4807c857, 0x82040580, 0x00000053, 0x0400002e, 0x82040580, 0x00000002, 0x04000016, 0x82040580, @@ -9506,10 +9647,10 @@ uint32_t risc_code01[] = { 0x0400001c, 0x82040580, 0x00000005, 0x0400001d, 0x82040580, 0x00000033, 0x0400001a, 0x82040580, 0x00000000, 0x0400001b, 0x82040580, 0x00000004, - 0x02020800, 0x00100615, 0x0401f8a1, 0x0401f016, + 0x02020800, 0x001005d8, 0x0401f8a1, 0x0401f016, 0x820c0580, 0x00000003, 0x0400084c, 0x0401f012, 0x820c0580, 0x0000000b, 0x0402000f, 0x42000800, - 0x00000007, 0x0201f800, 0x001043c7, 0x0401f00a, + 0x00000007, 0x0201f800, 0x00104571, 0x0401f00a, 0x820c0580, 0x00000005, 0x04000864, 0x0401f006, 0x820c0580, 0x00000009, 0x04000889, 0x0401f002, 0x0401f893, 0x4a026403, 0x00000052, 0x59a81016, @@ -9520,80 +9661,80 @@ uint32_t risc_code01[] = { 0x4a025a06, 0x00000007, 0x40001000, 0x0401f006, 0x4a025a06, 0x00000015, 0x0401f003, 0x4a025a06, 0x00000000, 0x480a580c, 0x82081400, 0x00000003, - 0x80081104, 0x0201f800, 0x0010783c, 0x04000010, + 0x80081104, 0x0201f800, 0x00107ab5, 0x04000010, 0x592c1001, 0x480a600b, 0x58080800, 0x82080400, 0x00000002, 0x592c1011, 0x592c1812, 0x42003000, - 0x00000000, 0x42002000, 0x00101250, 0x0201f800, - 0x001079b9, 0x04000002, 0x1c01f000, 0x4a025a06, - 0x0000002c, 0x497a580c, 0x0201f800, 0x00020381, - 0x0201f000, 0x000208b4, 0x83380580, 0x00000015, - 0x0402000a, 0x59a8006f, 0x8c000502, 0x0402000b, - 0x0201f800, 0x00104480, 0x42000800, 0x00000004, - 0x0201f000, 0x001043c7, 0x42000800, 0x00000007, - 0x0201f000, 0x001043c7, 0x0201f800, 0x00104e0d, + 0x00000000, 0x42002000, 0x00101200, 0x0201f800, + 0x00107c32, 0x04000002, 0x1c01f000, 0x4a025a06, + 0x0000002c, 0x497a580c, 0x0201f800, 0x000202da, + 0x0201f000, 0x0002077d, 0x83380580, 0x00000015, + 0x0402000a, 0x59a80005, 0x8c000514, 0x0402000b, + 0x0201f800, 0x0010462a, 0x42000800, 0x00000004, + 0x0201f000, 0x00104571, 0x42000800, 0x00000007, + 0x0201f000, 0x00104571, 0x0201f800, 0x0010513b, 0x42001000, 0x00000010, 0x04020009, 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000, 0x040007ec, 0x42001000, 0x00000008, 0x0201f800, - 0x00104ada, 0x040007e7, 0x592c040b, 0x84000540, + 0x00104c6d, 0x040007e7, 0x592c040b, 0x84000540, 0x48025c0b, 0x0401f7e9, 0x83380580, 0x00000015, - 0x0402000f, 0x59a8006f, 0x8c000502, 0x04020010, - 0x0201f800, 0x001044e1, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x001043bd, 0x5c027800, 0x42000800, - 0x00000006, 0x0201f000, 0x001043c7, 0x42000800, - 0x00000004, 0x0201f000, 0x001043c7, 0x0201f800, - 0x00104e0d, 0x42001000, 0x00000010, 0x04020009, + 0x0402000f, 0x59a80005, 0x8c000514, 0x04020010, + 0x0201f800, 0x0010468d, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x00104567, 0x5c027800, 0x42000800, + 0x00000006, 0x0201f000, 0x00104571, 0x42000800, + 0x00000004, 0x0201f000, 0x00104571, 0x0201f800, + 0x0010513b, 0x42001000, 0x00000010, 0x04020009, 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000, 0x040007e7, 0x42001000, 0x00000008, - 0x0201f800, 0x00104ada, 0x040007e2, 0x592c040b, + 0x0201f800, 0x00104c6d, 0x040007e2, 0x592c040b, 0x84000540, 0x48025c0b, 0x0401f7e9, 0x42000800, - 0x00000004, 0x0201f000, 0x001043c7, 0x83380580, - 0x00000015, 0x04020005, 0x0201f800, 0x0010a0b1, - 0x02000800, 0x00104711, 0x1c01f000, 0x83380580, + 0x00000004, 0x0201f000, 0x00104571, 0x83380580, + 0x00000015, 0x04020005, 0x0201f800, 0x0010a2c8, + 0x02000800, 0x001048c1, 0x1c01f000, 0x83380580, 0x00000015, 0x0402001d, 0x4c580000, 0x83cc1400, 0x00000008, 0x4200b000, 0x00000002, 0x83341c00, - 0x00000006, 0x0201f800, 0x001082ff, 0x04020012, + 0x00000006, 0x0201f800, 0x0010855a, 0x04020012, 0x83cc1400, 0x0000000a, 0x4200b000, 0x00000002, - 0x83341c00, 0x00000008, 0x0201f800, 0x001082ff, + 0x83341c00, 0x00000008, 0x0201f800, 0x0010855a, 0x04020009, 0x59342200, 0x59cc1007, 0x800811c0, 0x04000003, 0x480a6801, 0x84102542, 0x8410251a, 0x48126a00, 0x5c00b000, 0x1c01f000, 0x42000000, - 0x0010b67a, 0x0201f800, 0x0010a86e, 0x0201f800, - 0x0010698c, 0x59300203, 0x4933c857, 0x4803c857, - 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, - 0x0c01f803, 0x0201f000, 0x00106982, 0x001094d7, - 0x001094e6, 0x001094d8, 0x001094d5, 0x001094d5, - 0x001094d5, 0x001094d5, 0x001094d5, 0x001094d5, - 0x001094d5, 0x001094d5, 0x001094d5, 0x001094d5, - 0x001094d5, 0x0201f800, 0x00100615, 0x1c01f000, + 0x0010b87b, 0x0201f800, 0x0010aa47, 0x0201f800, + 0x00106c55, 0x59300203, 0x4933c857, 0x4803c857, + 0x82000c80, 0x0000000e, 0x02021800, 0x001005d8, + 0x0c01f803, 0x0201f000, 0x00106c4b, 0x0010970b, + 0x0010971a, 0x0010970c, 0x00109709, 0x00109709, + 0x00109709, 0x00109709, 0x00109709, 0x00109709, + 0x00109709, 0x00109709, 0x00109709, 0x00109709, + 0x00109709, 0x0201f800, 0x001005d8, 0x1c01f000, 0x59300403, 0x82000580, 0x00000052, 0x02000000, - 0x00108b39, 0x0201f800, 0x00104a83, 0x59325808, - 0x4a025a06, 0x00000006, 0x0201f800, 0x00020381, - 0x0201f000, 0x00107698, 0x59301804, 0x840c0520, + 0x00108d85, 0x0201f800, 0x00104c19, 0x59325808, + 0x4a025a06, 0x00000006, 0x0201f800, 0x000202da, + 0x0201f000, 0x00107911, 0x59301804, 0x840c0520, 0x48026004, 0x598c000d, 0x81300580, 0x04020010, - 0x8c0c1d20, 0x04020010, 0x42001000, 0x0010b5f4, + 0x8c0c1d20, 0x04020010, 0x42001000, 0x0010b7f6, 0x50081000, 0x58080002, 0x82000580, 0x00000100, 0x0400000e, 0x5808000c, 0x81300580, 0x02020800, - 0x00100615, 0x4978100c, 0x0401f003, 0x8c0c1d20, - 0x040207dc, 0x0201f800, 0x00106619, 0x040007d9, - 0x0201f800, 0x00100615, 0x0201f800, 0x00106be2, + 0x001005d8, 0x4978100c, 0x0401f003, 0x8c0c1d20, + 0x040207dc, 0x0201f800, 0x001068d3, 0x040007d9, + 0x0201f800, 0x001005d8, 0x0201f800, 0x00106e8e, 0x040007f9, 0x59300203, 0x82000c80, 0x0000000e, - 0x02021800, 0x00100615, 0x0c01f7bd, 0x4933c857, + 0x02021800, 0x001005d8, 0x0c01f7bd, 0x4933c857, 0x4c500000, 0x4c540000, 0x4c580000, 0x592c0c07, 0x4806580a, 0x59cc0809, 0x48065807, 0x59cc0a08, - 0x4806580b, 0x59a8086e, 0x82040500, 0x000003ff, + 0x4806580b, 0x59c80817, 0x82040500, 0x000003ff, 0x800010c4, 0x8c040d14, 0x04000005, 0x59cc0002, 0x82000500, 0x00000003, 0x80081480, 0x82080480, - 0x000000f1, 0x02021800, 0x00100615, 0x480a621a, - 0x412c0800, 0x0201f800, 0x00100819, 0x02000800, - 0x00100615, 0x492c0809, 0x58040408, 0x84000552, + 0x000000f1, 0x02021800, 0x001005d8, 0x480a621a, + 0x412c0800, 0x0201f800, 0x001007d3, 0x02000800, + 0x001005d8, 0x492c0809, 0x58040408, 0x84000552, 0x84000540, 0x48000c08, 0x82081400, 0x00000003, 0x80081104, 0x83cca400, 0x00000006, 0x832cac00, 0x00000004, 0x42000800, 0x00000010, 0x82080480, 0x00000010, 0x04021003, 0x40080800, 0x80000580, - 0x4004b000, 0x4c000000, 0x0201f800, 0x0010a94f, + 0x4004b000, 0x4c000000, 0x0201f800, 0x0010ab28, 0x5c000000, 0x800001c0, 0x0400000d, 0x412c1000, - 0x4c000000, 0x0201f800, 0x00100819, 0x02000800, - 0x00100615, 0x492c1001, 0x832cac00, 0x00000004, + 0x4c000000, 0x0201f800, 0x001007d3, 0x02000800, + 0x001005d8, 0x492c1001, 0x832cac00, 0x00000004, 0x5c000000, 0x40001000, 0x0401f7e9, 0x5c00b000, 0x5c00a800, 0x5c00a000, 0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c380000, 0x59325808, 0x5930021a, @@ -9602,7 +9743,7 @@ uint32_t risc_code01[] = { 0x00000c00, 0x0400000b, 0x0401f00b, 0x8c08153e, 0x04000006, 0x4a025a06, 0x00000007, 0x80081080, 0x80081000, 0x0401f003, 0x4a025a06, 0x00000015, - 0x480a5807, 0x42000000, 0x0010bcd8, 0x50007000, + 0x480a5807, 0x42000000, 0x0010bed9, 0x50007000, 0x5838000b, 0x80000540, 0x04020008, 0x4930700c, 0x4930700b, 0x58380002, 0x82000580, 0x00000000, 0x04020809, 0x0401f005, 0x82001400, 0x00000000, @@ -9615,622 +9756,613 @@ uint32_t risc_code01[] = { 0x82080480, 0x00000010, 0x04021003, 0x80000580, 0x0401f003, 0x42001000, 0x00000010, 0x4800700d, 0x48087004, 0x800810c4, 0x48087005, 0x40381000, - 0x0201f800, 0x001008a1, 0x1c01f000, 0x4d2c0000, - 0x0201f800, 0x00100819, 0x02000800, 0x00100615, - 0x42000800, 0x0010bcd8, 0x452c0800, 0x497a580b, - 0x497a580c, 0x497a580d, 0x4a025809, 0x001095b6, + 0x0201f800, 0x00100858, 0x1c01f000, 0x4d2c0000, + 0x0201f800, 0x001007d3, 0x02000800, 0x001005d8, + 0x42000800, 0x0010bed9, 0x452c0800, 0x497a580b, + 0x497a580c, 0x497a580d, 0x4a025809, 0x001097ea, 0x4a025802, 0x00000100, 0x4a025801, 0x00000000, 0x5c025800, 0x1c01f000, 0x4833c857, 0x4d300000, 0x4d2c0000, 0x4c5c0000, 0x4030b800, 0x585c000a, 0x80025d40, 0x04020004, 0x585c000c, 0x4c000000, 0x0401f044, 0x585c0002, 0x82000580, 0x00000100, 0x04020022, 0x592c0801, 0x4c040000, 0x0201f800, - 0x0010083a, 0x5c000800, 0x800409c0, 0x0400001c, + 0x001007f4, 0x5c000800, 0x800409c0, 0x0400001c, 0x4804b80a, 0x585c100d, 0x800811c0, 0x04020005, - 0x40065800, 0x0201f800, 0x00100843, 0x0401f014, + 0x40065800, 0x0201f800, 0x001007fd, 0x0401f014, 0x82080480, 0x00000010, 0x04021003, 0x80000580, 0x0401f003, 0x42001000, 0x00000010, 0x4800b80d, 0x4808b804, 0x800810c4, 0x4808b805, 0x82040400, 0x00000004, 0x4800b803, 0x405c1000, 0x0201f800, - 0x001008a1, 0x0401f025, 0x0401f828, 0x585c000c, + 0x00100858, 0x0401f025, 0x0401f828, 0x585c000c, 0x80026540, 0x59300000, 0x80000d40, 0x04020002, 0x4800b80b, 0x4800b80c, 0x497a6000, 0x4c000000, 0x4978b80a, 0x59325808, 0x4a025a04, 0x00000103, 0x59300402, 0x48025c06, 0x592c100b, 0x4c080000, - 0x0201f800, 0x00020381, 0x0201f800, 0x00108ee7, + 0x0201f800, 0x000202c1, 0x0201f800, 0x0010912a, 0x5c001000, 0x8c081518, 0x04000004, 0x0201f800, - 0x00108f88, 0x0401f003, 0x0201f800, 0x000208b4, + 0x001091d1, 0x0401f003, 0x0201f800, 0x0002077d, 0x405c7000, 0x5c000000, 0x80026540, 0x04000003, 0x59325808, 0x0401ff78, 0x5c00b800, 0x5c025800, 0x5c026000, 0x1c01f000, 0x483bc857, 0x5838000a, - 0x40025800, 0x0201f800, 0x00100843, 0x5838000c, + 0x40025800, 0x0201f800, 0x001007fd, 0x5838000c, 0x80026540, 0x59300008, 0x80025d40, 0x4a025a06, 0x00000002, 0x1c01f000, 0x4803c857, 0x4d1c0000, 0x497a601c, 0x41323800, 0x40026000, 0x4d3c0000, - 0x42027800, 0x00000005, 0x0401f840, 0x5c027800, + 0x42027800, 0x00000005, 0x0401f83c, 0x5c027800, 0x411e6000, 0x59300414, 0x84000502, 0x48026414, 0x5c023800, 0x1c01f000, 0x481bc857, 0x4933c857, 0x4c5c0000, 0x4c600000, 0x4010b800, 0x4014c000, - 0x0201f800, 0x0010a766, 0x0201f800, 0x0010393e, + 0x0201f800, 0x0010a942, 0x0201f800, 0x00103b25, 0x04000008, 0x40602800, 0x405c3000, 0x0201f800, - 0x0010a258, 0x82000540, 0x00000001, 0x0401f002, + 0x0010a446, 0x82000540, 0x00000001, 0x0401f002, 0x80000580, 0x5c00c000, 0x5c00b800, 0x1c01f000, - 0x4803c856, 0x4d300000, 0x42026000, 0x0010cfc0, - 0x59a8000e, 0x81640580, 0x0400001a, 0x59300c06, - 0x82040580, 0x00000001, 0x0400000d, 0x82040580, + 0x4803c856, 0x4d300000, 0x42026000, 0x0010d1c0, + 0x59a8000e, 0x81640580, 0x04000016, 0x59300c06, + 0x82040580, 0x00000001, 0x04000009, 0x82040580, 0x00000004, 0x04000006, 0x82040580, 0x00000010, - 0x02000800, 0x00108aad, 0x0401f009, 0x59300203, - 0x82000d80, 0x00000007, 0x04000005, 0x4807c857, - 0x0201f800, 0x0010909d, 0x04020808, 0x83326400, - 0x00000024, 0x41580000, 0x81300480, 0x040017e5, + 0x02000800, 0x00108cf9, 0x0401f005, 0x4807c857, + 0x0201f800, 0x001092d7, 0x04020808, 0x83326400, + 0x00000024, 0x41580000, 0x81300480, 0x040017e9, 0x5c026000, 0x1c01f000, 0x4933c857, 0x59300403, - 0x4803c857, 0x0201f800, 0x0010698c, 0x4df00000, + 0x4803c857, 0x0201f800, 0x00106c55, 0x4df00000, 0x59300406, 0x4803c857, 0x82000d80, 0x00000002, 0x04000018, 0x82000d80, 0x00000001, 0x04000009, 0x82000d80, 0x00000004, 0x04000006, 0x4933c856, - 0x5c03e000, 0x02000800, 0x00106982, 0x0401f03c, + 0x5c03e000, 0x02000800, 0x00106c4b, 0x0401f03c, 0x59300203, 0x82000d80, 0x00000001, 0x04000018, 0x82000d80, 0x00000002, 0x04000026, 0x82000d80, - 0x00000005, 0x04000023, 0x0201f800, 0x00100615, + 0x00000005, 0x04000023, 0x0201f800, 0x001005d8, 0x59300203, 0x82000d80, 0x00000009, 0x0400000c, 0x82000d80, 0x0000000b, 0x04000009, 0x82000d80, 0x0000000a, 0x04000017, 0x82000d80, 0x0000000c, - 0x04000014, 0x0201f800, 0x00100615, 0x598c000d, - 0x81300580, 0x04020004, 0x0201f800, 0x00106be2, + 0x04000014, 0x0201f800, 0x001005d8, 0x598c000d, + 0x81300580, 0x04020004, 0x0201f800, 0x00106e8e, 0x0402000c, 0x59300004, 0x4803c857, 0x8c000520, 0x04000004, 0x84000520, 0x48026004, 0x0401f005, - 0x0201f800, 0x00106619, 0x02020800, 0x00100615, - 0x5c03e000, 0x02000800, 0x00106982, 0x59300406, + 0x0201f800, 0x001068d3, 0x02020800, 0x001005d8, + 0x5c03e000, 0x02000800, 0x00106c4b, 0x59300406, 0x82000d80, 0x00000002, 0x04000009, 0x0201f800, - 0x00104a83, 0x0201f800, 0x00108f05, 0x02000800, - 0x00107da6, 0x8d3e7d00, 0x04000003, 0x0201f000, - 0x00107698, 0x4a02621d, 0x00000001, 0x4a026403, + 0x00104c19, 0x0201f800, 0x0010914e, 0x02000800, + 0x0010801c, 0x8d3e7d00, 0x04000003, 0x0201f000, + 0x00107911, 0x4a02621d, 0x00000001, 0x4a026403, 0x00000085, 0x4a026203, 0x00000009, 0x4a026406, 0x00000002, 0x42000800, 0x8000004b, 0x0201f000, - 0x00020855, 0x4933c857, 0x59368c03, 0x4c180000, + 0x00020721, 0x4933c857, 0x59368c03, 0x4c180000, 0x59300203, 0x82003480, 0x0000000e, 0x02021800, - 0x00100615, 0x0c01f803, 0x5c003000, 0x1c01f000, - 0x001096da, 0x00109bb9, 0x00109cbd, 0x001096da, - 0x001096da, 0x001096da, 0x001096da, 0x001096da, - 0x001096fd, 0x001096da, 0x001096da, 0x001096da, - 0x001096da, 0x001096da, 0x0201f800, 0x00100615, + 0x001005d8, 0x0c01f803, 0x5c003000, 0x1c01f000, + 0x0010990a, 0x00109dcf, 0x00109edb, 0x0010990a, + 0x0010990a, 0x0010990a, 0x0010990a, 0x0010990a, + 0x0010992d, 0x0010990a, 0x0010990a, 0x0010990a, + 0x0010990a, 0x0010990a, 0x0201f800, 0x001005d8, 0x4933c857, 0x42028800, 0x0000ffff, 0x813669c0, 0x04000002, 0x59368c03, 0x4c180000, 0x59300203, - 0x82003480, 0x0000000e, 0x02021800, 0x00100615, - 0x0c01f803, 0x5c003000, 0x1c01f000, 0x001096f9, - 0x00109f70, 0x001096f9, 0x001096f9, 0x001096f9, - 0x001096f9, 0x001096f9, 0x0010a779, 0x00109edd, - 0x0010a34a, 0x0010a380, 0x0010a34a, 0x0010a380, - 0x001096f9, 0x0201f800, 0x00100615, 0x0201f800, - 0x00100615, 0x83383480, 0x00000051, 0x02021800, - 0x00100615, 0x41380000, 0x493bc857, 0x4d1c0000, + 0x82003480, 0x0000000e, 0x02021800, 0x001005d8, + 0x0c01f803, 0x5c003000, 0x1c01f000, 0x00109929, + 0x0010a180, 0x00109929, 0x00109929, 0x00109929, + 0x00109929, 0x00109929, 0x0010a952, 0x0010a0ed, + 0x0010a52c, 0x0010a562, 0x0010a52c, 0x0010a562, + 0x00109929, 0x0201f800, 0x001005d8, 0x0201f800, + 0x001005d8, 0x83383480, 0x00000051, 0x02021800, + 0x001005d8, 0x41380000, 0x493bc857, 0x4d1c0000, 0x4d400000, 0x0c01f804, 0x5c028000, 0x5c023800, - 0x1c01f000, 0x0010975a, 0x0010993d, 0x0010975a, - 0x0010975a, 0x0010975a, 0x00109948, 0x0010975a, - 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, - 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, - 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, - 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, - 0x0010977c, 0x001097ba, 0x001097d1, 0x0010982d, - 0x00109894, 0x001098d2, 0x00109902, 0x0010975a, - 0x0010975a, 0x00109950, 0x0010975a, 0x0010975a, - 0x0010995e, 0x00109967, 0x0010975a, 0x0010975a, - 0x0010975a, 0x0010975a, 0x0010975a, 0x001099e9, - 0x0010975a, 0x0010975a, 0x00109868, 0x0010975a, - 0x0010975a, 0x001099c0, 0x0010975a, 0x0010975a, - 0x0010975a, 0x001099f7, 0x0010975a, 0x0010975a, - 0x0010975a, 0x00109a40, 0x0010975a, 0x0010975a, - 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, - 0x00109a8d, 0x0010975a, 0x00109ab9, 0x00109ac4, - 0x0010975a, 0x0010975a, 0x0010975c, 0x00109acf, - 0x0010975a, 0x0010975a, 0x0010975a, 0x0010976b, - 0x0010975a, 0x0010975a, 0x0010975a, 0x00109ad6, - 0x00109ade, 0x00109afc, 0x0201f800, 0x00100615, - 0x4933c857, 0x0201f800, 0x0010a3b0, 0x040203a8, - 0x0201f800, 0x00101eb0, 0x040203a5, 0x59cc0407, + 0x1c01f000, 0x0010998a, 0x00109b69, 0x0010998a, + 0x0010998a, 0x0010998a, 0x00109b74, 0x0010998a, + 0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a, + 0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a, + 0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a, + 0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a, + 0x001099ac, 0x001099f5, 0x00109a0c, 0x00109a62, + 0x00109ac6, 0x00109b04, 0x00109b34, 0x0010998a, + 0x0010998a, 0x00109b7c, 0x0010998a, 0x0010998a, + 0x00109b8a, 0x00109b93, 0x0010998a, 0x0010998a, + 0x0010998a, 0x0010998a, 0x0010998a, 0x00109c15, + 0x0010998a, 0x0010998a, 0x00109a9a, 0x0010998a, + 0x0010998a, 0x00109bec, 0x0010998a, 0x0010998a, + 0x0010998a, 0x00109c23, 0x0010998a, 0x0010998a, + 0x0010998a, 0x00109c6c, 0x0010998a, 0x0010998a, + 0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a, + 0x00109cb9, 0x0010998a, 0x00109ce5, 0x00109cf0, + 0x0010998a, 0x0010998a, 0x0010998c, 0x00109cfb, + 0x0010998a, 0x0010998a, 0x0010998a, 0x0010999b, + 0x0010998a, 0x0010998a, 0x0010998a, 0x00109d02, + 0x00109d0a, 0x00109d28, 0x0201f800, 0x001005d8, + 0x4933c857, 0x0201f800, 0x0010a592, 0x040203a4, + 0x0201f800, 0x0010210a, 0x040203a1, 0x59cc0407, 0x4802601c, 0x4a026403, 0x00000045, 0x4a026203, - 0x00000001, 0x0201f000, 0x00106470, 0x4933c857, - 0x0201f800, 0x0010a3b0, 0x04020399, 0x0201f800, - 0x00101eb0, 0x04020396, 0x0401fbd6, 0x0402019e, + 0x00000001, 0x0201f000, 0x0010672b, 0x4933c857, + 0x0201f800, 0x0010a592, 0x04020395, 0x0201f800, + 0x0010210a, 0x04020392, 0x0401fbce, 0x040201a0, 0x59cc0007, 0x4802601c, 0x4a026403, 0x0000004a, - 0x4a026203, 0x00000001, 0x0201f000, 0x00106470, - 0x4933c857, 0x0201f800, 0x00101eb0, 0x04020009, - 0x0201f800, 0x0010473b, 0x04020006, 0x82000500, + 0x4a026203, 0x00000001, 0x0201f000, 0x0010672b, + 0x4933c857, 0x0201f800, 0x0010210a, 0x04020009, + 0x0201f800, 0x001048ec, 0x04020006, 0x82000500, 0x00000009, 0x82000580, 0x00000008, 0x04020008, 0x4a026403, 0x00000009, 0x4a02641a, 0x00000009, - 0x4a02621a, 0x00000000, 0x0401f1b6, 0x0201f800, - 0x00104858, 0x04000018, 0x0201f800, 0x0010a041, - 0x0402001f, 0x42028000, 0x00000029, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, - 0x0201f800, 0x00104480, 0x4a026403, 0x00000008, - 0x42003000, 0x00000003, 0x0201f800, 0x0010393e, - 0x040001a0, 0x4a026203, 0x00000007, 0x41782800, - 0x0401f18b, 0x0201f800, 0x0010a1ec, 0x040207e7, - 0x4a026403, 0x00000009, 0x4a02641a, 0x0000000e, - 0x4a02621a, 0x00001900, 0x0401f192, 0x4a026403, - 0x00000009, 0x4a02641a, 0x00000003, 0x4a02621a, - 0x00000f00, 0x0401f18b, 0x4933c857, 0x0201f800, - 0x00101eb0, 0x0402034a, 0x0201f800, 0x0010473b, - 0x04020347, 0x493a6403, 0x0201f800, 0x0010a01c, - 0x04020006, 0x42003000, 0x00000005, 0x4a026403, - 0x00000006, 0x0401f7d9, 0x4a026403, 0x00000007, - 0x4a02641a, 0x00000009, 0x4a02621a, 0x00000000, - 0x0401f174, 0x4933c857, 0x0201f800, 0x0010473b, - 0x04020333, 0x0201f800, 0x0010a3b0, 0x02000800, - 0x00101eb0, 0x0402032e, 0x0201f800, 0x00104858, - 0x04020005, 0x42027800, 0x00000001, 0x0201f800, - 0x001043bd, 0x0201f800, 0x0010484b, 0x04020031, - 0x59cc0206, 0x82003500, 0x00000003, 0x04020034, - 0x82003480, 0x00000014, 0x04001031, 0x5934300a, - 0x84183516, 0x82000580, 0x00000014, 0x04020002, - 0x84183556, 0x481a680a, 0x59cc0406, 0x82000500, - 0x00000003, 0x04020026, 0x0201f800, 0x0010a08e, - 0x0402002e, 0x0201f800, 0x00104836, 0x04020007, - 0x4c600000, 0x4178c000, 0x417a7800, 0x0201f800, - 0x00101e48, 0x5c00c000, 0x836c0580, 0x00000003, - 0x04020009, 0x42003000, 0x00000006, 0x0201f800, - 0x0010a75e, 0x42000000, 0x0010b664, 0x0201f800, - 0x0010a86e, 0x0201f800, 0x001044e1, 0x4a026403, - 0x0000000a, 0x42003000, 0x00000020, 0x0401f78f, - 0x4a026403, 0x0000000b, 0x4a02641a, 0x00000009, - 0x4a02621a, 0x00001e00, 0x0401f12a, 0x42000000, - 0x0010b65f, 0x0201f800, 0x0010a86e, 0x4a026403, - 0x0000000b, 0x4a02641a, 0x00000007, 0x4a02621a, - 0x00000000, 0x0401f11f, 0x4a026403, 0x0000000b, - 0x4a02641a, 0x00000003, 0x4a02621a, 0x00000000, - 0x0401f118, 0x4933c857, 0x0201f800, 0x0010473b, - 0x040202d7, 0x0201f800, 0x0010a3b0, 0x040202d4, - 0x0201f800, 0x00101eb0, 0x040202d1, 0x59cc0206, - 0x82003500, 0x00000003, 0x04020020, 0x82003480, - 0x00000014, 0x0400101d, 0x59cc0406, 0x82000500, - 0x00000003, 0x04020019, 0x59340400, 0x82000580, - 0x00000707, 0x0400001c, 0x417a7800, 0x4c600000, - 0x4178c000, 0x0201f800, 0x00101e48, 0x5c00c000, - 0x42003000, 0x0000000a, 0x0201f800, 0x0010a75e, - 0x42000000, 0x0010b661, 0x0201f800, 0x0010a86e, - 0x4a026403, 0x0000000c, 0x41782800, 0x42003000, - 0x00000021, 0x0401f749, 0x4a026403, 0x0000000d, - 0x4a02641a, 0x00000007, 0x4a02621a, 0x00000000, - 0x0401f0e4, 0x4a026403, 0x0000000d, 0x4a02641a, - 0x00000009, 0x4a02621a, 0x00001e00, 0x0401f0dd, - 0x4933c857, 0x0201f800, 0x0010473b, 0x0402029c, - 0x0201f800, 0x0010a3b0, 0x04020299, 0x0201f800, - 0x00101eb0, 0x04020296, 0x0401fad6, 0x0402001a, - 0x493a6403, 0x4c5c0000, 0x0401fadc, 0x0402000e, - 0x4a026403, 0x0000002e, 0x4014b800, 0x0201f800, - 0x0010393e, 0x0400000e, 0x4a026203, 0x00000007, - 0x405c2800, 0x42003000, 0x00000024, 0x5c00b800, - 0x0401f0af, 0x4a026403, 0x0000000d, 0x4a02641a, - 0x00000007, 0x4a02621a, 0x00000000, 0x5c00b800, - 0x0401f0b8, 0x4a026403, 0x0000000d, 0x4a02641a, - 0x00000009, 0x4a02621a, 0x00001e00, 0x0401f0b1, - 0x4933c857, 0x0201f800, 0x0010473b, 0x040206f1, + 0x4a02621a, 0x00000000, 0x0401f1b2, 0x0201f800, + 0x001048c1, 0x0201f800, 0x00104a09, 0x04000021, + 0x0201f800, 0x001049ed, 0x0400001e, 0x0201f800, + 0x0010a252, 0x04020025, 0x42028000, 0x00000029, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c, + 0x5c027800, 0x0201f800, 0x0010462a, 0x836c0580, + 0x00000002, 0x04020004, 0x59a8001b, 0x80000000, + 0x4803501b, 0x4a026403, 0x00000008, 0x42003000, + 0x00000003, 0x0201f800, 0x00103b25, 0x04000191, + 0x4a026203, 0x00000007, 0x41782800, 0x0401f180, + 0x0201f800, 0x0010a3da, 0x040207e1, 0x4a026403, + 0x00000009, 0x4a02641a, 0x0000000e, 0x4a02621a, + 0x00001900, 0x0401f183, 0x4a026403, 0x00000009, + 0x4a02641a, 0x00000003, 0x4a02621a, 0x00000f00, + 0x0401f17c, 0x4933c857, 0x0201f800, 0x0010210a, + 0x0402033b, 0x0201f800, 0x001048ec, 0x04020338, + 0x493a6403, 0x0201f800, 0x0010a22d, 0x04020006, + 0x42003000, 0x00000005, 0x4a026403, 0x00000006, + 0x0401f7d9, 0x4a026403, 0x00000007, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00000000, 0x0401f165, + 0x4933c857, 0x0201f800, 0x001048ec, 0x04020324, + 0x0201f800, 0x0010a592, 0x02000800, 0x0010210a, + 0x0402031f, 0x0201f800, 0x00104a09, 0x04020005, + 0x42027800, 0x00000001, 0x0201f800, 0x00104567, + 0x0201f800, 0x001049fc, 0x0402002b, 0x59cc0206, + 0x82003500, 0x00000003, 0x0402002e, 0x82003480, + 0x00000014, 0x0400102b, 0x5934300a, 0x84183516, + 0x82000580, 0x00000014, 0x04020002, 0x84183556, + 0x481a680a, 0x59cc0406, 0x82000500, 0x00000003, + 0x04020020, 0x0201f800, 0x0010a29f, 0x04020028, + 0x0201f800, 0x001049e7, 0x0402000c, 0x417a7800, + 0x0201f800, 0x001020a1, 0x42003000, 0x00000006, + 0x0201f800, 0x0010a93a, 0x42000000, 0x0010b865, + 0x0201f800, 0x0010aa47, 0x0201f800, 0x0010468d, + 0x4a026403, 0x0000000a, 0x42003000, 0x00000020, + 0x0401f795, 0x4a026403, 0x0000000b, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00001e00, 0x0401f121, + 0x42000000, 0x0010b860, 0x0201f800, 0x0010aa47, + 0x4a026403, 0x0000000b, 0x4a02641a, 0x00000007, + 0x4a02621a, 0x00000000, 0x0401f116, 0x4a026403, + 0x0000000b, 0x4a02641a, 0x00000003, 0x4a02621a, + 0x00000000, 0x0401f10f, 0x4933c857, 0x0201f800, + 0x001048ec, 0x040202ce, 0x0201f800, 0x0010a592, + 0x040202cb, 0x0201f800, 0x0010210a, 0x040202c8, + 0x59cc0206, 0x82003500, 0x00000003, 0x0402001d, + 0x82003480, 0x00000014, 0x0400101a, 0x59cc0406, + 0x82000500, 0x00000003, 0x04020016, 0x59340400, + 0x82000580, 0x00000707, 0x04000019, 0x417a7800, + 0x0201f800, 0x001020a1, 0x42003000, 0x0000000a, + 0x0201f800, 0x0010a93a, 0x42000000, 0x0010b862, + 0x0201f800, 0x0010aa47, 0x4a026403, 0x0000000c, + 0x41782800, 0x42003000, 0x00000021, 0x0401f752, + 0x4a026403, 0x0000000d, 0x4a02641a, 0x00000007, + 0x4a02621a, 0x00000000, 0x0401f0de, 0x4a026403, + 0x0000000d, 0x4a02641a, 0x00000009, 0x4a02621a, + 0x00001e00, 0x0401f0d7, 0x4933c857, 0x0201f800, + 0x001048ec, 0x04020296, 0x0201f800, 0x0010a592, + 0x04020293, 0x0201f800, 0x0010210a, 0x04020290, + 0x0401facc, 0x0402001a, 0x493a6403, 0x4c5c0000, + 0x0401fad2, 0x0402000e, 0x4a026403, 0x0000002e, + 0x405c2800, 0x42003000, 0x00000024, 0x0201f800, + 0x00103b25, 0x0400000c, 0x4a026203, 0x00000007, + 0x405c2800, 0x5c00b800, 0x0401f0ad, 0x4a026403, + 0x0000000d, 0x4a02641a, 0x00000007, 0x4a02621a, + 0x00000000, 0x5c00b800, 0x0401f0b2, 0x4a026403, + 0x0000000d, 0x4a02641a, 0x00000009, 0x4a02621a, + 0x00001e00, 0x0401f0ab, 0x4933c857, 0x0201f800, + 0x001048ec, 0x040206ef, 0x59a80026, 0x82000500, + 0x00000009, 0x82000580, 0x00000008, 0x040006e9, + 0x0201f800, 0x001049fc, 0x0402002d, 0x0201f800, + 0x0010a2a7, 0x04020007, 0x4a026403, 0x0000000e, + 0x41782800, 0x42003000, 0x00000052, 0x0401f702, + 0x4933c857, 0x42003000, 0x00000003, 0x0201f800, + 0x0010a942, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x0010203c, 0x5c027800, 0x42000000, 0x0010b864, + 0x0201f800, 0x0010aa47, 0x59340200, 0x84000558, + 0x48026a00, 0x42000800, 0x0000000b, 0x0201f800, + 0x00104571, 0x0201f800, 0x00103b25, 0x04000076, + 0x42003000, 0x00000007, 0x0401f062, 0x4933c857, + 0x4a026403, 0x0000000f, 0x4a02641a, 0x00000003, + 0x4a02621a, 0x00001e00, 0x0401f072, 0x59340400, + 0x82000580, 0x00000703, 0x040007f5, 0x0401f040, + 0x4933c857, 0x0201f800, 0x001048ec, 0x0402022c, 0x59a80026, 0x82000500, 0x00000009, 0x82000580, - 0x00000008, 0x040006eb, 0x0201f800, 0x0010484b, - 0x0402002d, 0x0201f800, 0x0010a096, 0x04020007, - 0x4a026403, 0x0000000e, 0x41782800, 0x42003000, - 0x00000052, 0x0401f6f9, 0x4933c857, 0x42003000, - 0x00000003, 0x0201f800, 0x0010a766, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, - 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, - 0x59340200, 0x84000558, 0x48026a00, 0x42000800, - 0x0000000b, 0x0201f800, 0x001043c7, 0x0201f800, - 0x0010393e, 0x0400007c, 0x42003000, 0x00000007, - 0x0401f061, 0x4933c857, 0x4a026403, 0x0000000f, - 0x4a02641a, 0x00000003, 0x4a02621a, 0x00001e00, - 0x0401f078, 0x59340400, 0x82000580, 0x00000703, - 0x040007f5, 0x0401f040, 0x4933c857, 0x0201f800, - 0x0010473b, 0x04020232, 0x59a80026, 0x82000500, - 0x00000009, 0x82000580, 0x00000008, 0x0400022c, - 0x0201f800, 0x00104842, 0x0402002f, 0x0201f800, - 0x0010a0b1, 0x02000800, 0x0010a041, 0x04020007, - 0x4a026403, 0x00000010, 0x41782800, 0x42003000, - 0x00000050, 0x0401f6b9, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x00101de2, 0x5c027800, 0x42003000, - 0x00000003, 0x0201f800, 0x0010a766, 0x42000000, - 0x0010b663, 0x0201f800, 0x0010a86e, 0x59340200, - 0x84000558, 0x48026a00, 0x0401f7c5, 0x4a026403, - 0x00000011, 0x4a02641a, 0x00000003, 0x4a02621a, - 0x00001e00, 0x0401f043, 0x4933c857, 0x0201f800, - 0x00101eb0, 0x02000800, 0x0010a3b0, 0x04020200, - 0x0401fa40, 0x04020008, 0x4a026403, 0x00000012, - 0x0401f038, 0x59340400, 0x82000580, 0x00000703, - 0x040007eb, 0x4d3c0000, 0x417a7800, 0x42028000, - 0x00000029, 0x0201f800, 0x00101de2, 0x5c027800, - 0x42003000, 0x00000017, 0x0201f800, 0x0010a766, - 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, - 0x0201f800, 0x0010393e, 0x0400001b, 0x42003000, - 0x00000006, 0x42028000, 0x00000029, 0x4933c857, - 0x4a026403, 0x00000001, 0x4a026203, 0x00000007, - 0x4c180000, 0x0201f800, 0x0010a79b, 0x5c003000, - 0x41782800, 0x0201f000, 0x0010a250, 0x42028000, - 0x00000046, 0x4c140000, 0x4c180000, 0x0201f800, - 0x0010a79b, 0x5c003000, 0x5c002800, 0x0201f000, - 0x0010a250, 0x4933c857, 0x4a026403, 0x00000001, - 0x42000800, 0x0000000b, 0x0201f800, 0x001043c7, - 0x4a026203, 0x00000001, 0x0201f000, 0x00106470, + 0x00000008, 0x04000226, 0x0201f800, 0x001049f3, + 0x0402002f, 0x0201f800, 0x0010a2c8, 0x02000800, + 0x0010a252, 0x04020007, 0x4a026403, 0x00000010, + 0x41782800, 0x42003000, 0x00000050, 0x0401f6c2, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c, + 0x5c027800, 0x42003000, 0x00000003, 0x0201f800, + 0x0010a942, 0x42000000, 0x0010b864, 0x0201f800, + 0x0010aa47, 0x59340200, 0x84000558, 0x48026a00, + 0x0401f7c5, 0x4a026403, 0x00000011, 0x4a02641a, + 0x00000003, 0x4a02621a, 0x00001e00, 0x0401f03d, + 0x4933c857, 0x0201f800, 0x0010210a, 0x02000800, + 0x0010a592, 0x040201fa, 0x0401fa36, 0x04020008, + 0x4a026403, 0x00000012, 0x0401f032, 0x59340400, + 0x82000580, 0x00000703, 0x040007eb, 0x4d3c0000, + 0x417a7800, 0x42028000, 0x00000029, 0x0201f800, + 0x0010203c, 0x5c027800, 0x42003000, 0x00000017, + 0x0201f800, 0x0010a942, 0x42000000, 0x0010b864, + 0x0201f800, 0x0010aa47, 0x0201f800, 0x00103b25, + 0x04000015, 0x42003000, 0x00000006, 0x41782800, + 0x42028000, 0x00000029, 0x4933c857, 0x4a026403, + 0x00000001, 0x4a026203, 0x00000007, 0x0201f800, + 0x0010a974, 0x0201f000, 0x0010a43e, 0x42028000, + 0x00000046, 0x0201f800, 0x0010a974, 0x0201f000, + 0x0010a43e, 0x4933c857, 0x4a026403, 0x00000001, + 0x42000800, 0x0000000b, 0x0201f800, 0x00104571, + 0x4a026203, 0x00000001, 0x0201f000, 0x0010672b, 0x4933c857, 0x42000800, 0x00000009, 0x0201f800, - 0x001043c7, 0x4a026403, 0x00000005, 0x0401f7f5, - 0x0201f800, 0x0010a3b0, 0x040201b5, 0x0201f800, - 0x00101eb0, 0x040201b2, 0x0401f9f2, 0x040207ba, + 0x00104571, 0x4a026403, 0x00000005, 0x0401f7f5, + 0x0201f800, 0x0010a592, 0x040201b5, 0x0201f800, + 0x0010210a, 0x040201b2, 0x0401f9ee, 0x040207c0, 0x4a026403, 0x00000020, 0x4a026203, 0x00000001, - 0x0201f000, 0x00106470, 0x0201f800, 0x00101eb0, + 0x0201f000, 0x0010672b, 0x0201f800, 0x0010210a, 0x040201a7, 0x4a026403, 0x00000023, 0x4a026203, - 0x00000001, 0x0201f000, 0x00106470, 0x0201f800, - 0x0010a3b0, 0x02000800, 0x00101eb0, 0x0402019c, - 0x0401f9dc, 0x040207a4, 0x40300800, 0x59a81010, + 0x00000001, 0x0201f000, 0x0010672b, 0x0201f800, + 0x0010a592, 0x02000800, 0x0010210a, 0x0402019c, + 0x0401f9d8, 0x040207aa, 0x40300800, 0x59a81010, 0x59cc0007, 0x82000500, 0x00ffffff, 0x80080580, - 0x04000019, 0x59cc1408, 0x0201f800, 0x00108de9, + 0x04000019, 0x59cc1408, 0x0201f800, 0x0010902c, 0x0400002d, 0x59cc0c08, 0x4d300000, 0x0201f800, - 0x00105b0f, 0x41323800, 0x5c026000, 0x04000026, + 0x00105dd7, 0x41323800, 0x5c026000, 0x04000026, 0x591c0202, 0x82000580, 0x0000ffff, 0x04000005, 0x59cc1208, 0x591c0202, 0x80080580, 0x0402001e, 0x591c0406, 0x82000580, 0x00000007, 0x0402001a, 0x0401f02c, 0x59cc1208, 0x82080580, 0x0000ffff, - 0x0400000c, 0x0201f800, 0x001091d9, 0x04000012, + 0x0400000c, 0x0201f800, 0x00109410, 0x04000012, 0x59cc1408, 0x591c0202, 0x80080580, 0x0402000e, 0x591c0009, 0x81340580, 0x04000016, 0x0401f00a, - 0x59cc1408, 0x417a7800, 0x0201f800, 0x0010a217, + 0x59cc1408, 0x417a7800, 0x0201f800, 0x0010a405, 0x04020010, 0x59cc1208, 0x82080580, 0x0000ffff, 0x04000019, 0x4a026403, 0x00000026, 0x4a02621a, 0x00001700, 0x59cc1204, 0x82081580, 0x0000ffff, 0x04020798, 0x4a026403, 0x00000025, 0x0401f795, 0x591c0406, 0x82000580, 0x00000007, 0x040207f2, 0x591c0403, 0x82000580, 0x00000024, 0x04020006, - 0x4d300000, 0x411e6000, 0x0201f800, 0x000208b4, + 0x4d300000, 0x411e6000, 0x0201f800, 0x0002077d, 0x5c026000, 0x4a026403, 0x00000025, 0x0401f785, 0x4933c857, 0x4d3c0000, 0x42027800, 0x00000001, - 0x0201f800, 0x001043bd, 0x5c027800, 0x4c580000, + 0x0201f800, 0x00104567, 0x5c027800, 0x4c580000, 0x4200b000, 0x00000002, 0x83a81c00, 0x00000002, - 0x83cc1400, 0x0000000b, 0x0201f800, 0x001082ff, + 0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a, 0x5c00b000, 0x04000004, 0x4a026403, 0x00000031, - 0x0401f770, 0x0201f800, 0x00107698, 0x0201f800, - 0x00104e0d, 0x0402000f, 0x0201f800, 0x00104e1b, + 0x0401f770, 0x0201f800, 0x00107911, 0x0201f800, + 0x0010513b, 0x0402000f, 0x0201f800, 0x00105149, 0x04020008, 0x4a035033, 0x00000001, 0x4202d800, - 0x00000001, 0x0201f800, 0x00104d76, 0x0401f005, - 0x42000000, 0x00000001, 0x0201f800, 0x00104de5, - 0x1c01f000, 0x0201f800, 0x00101eb0, 0x0402011c, - 0x0401f95c, 0x04020724, 0x493a6403, 0x0401f9ac, + 0x00000001, 0x0201f800, 0x001050a2, 0x0401f005, + 0x42000000, 0x00000001, 0x0201f800, 0x00105113, + 0x1c01f000, 0x0201f800, 0x0010210a, 0x0402011c, + 0x0401f958, 0x0402072a, 0x493a6403, 0x0401f996, 0x04020004, 0x4a026403, 0x0000002b, 0x0401f751, 0x4a026403, 0x0000002c, 0x0401f74e, 0x4933c857, - 0x0201f800, 0x00101eb0, 0x0402010d, 0x0201f800, - 0x00104836, 0x04020740, 0x0201f800, 0x00104728, + 0x0201f800, 0x0010210a, 0x0402010d, 0x0201f800, + 0x001049e7, 0x04020740, 0x0201f800, 0x001048d9, 0x0400003c, 0x59cc0408, 0x48026419, 0x59cc0208, 0x48026219, 0x59cc0807, 0x59340002, 0x82000500, 0x00ffffff, 0x80040580, 0x04000012, 0x59a80010, 0x80040580, 0x04020021, 0x59cc1408, 0x0201f800, - 0x001091d9, 0x04000023, 0x0201f800, 0x0010a2e8, - 0x04000020, 0x0201f800, 0x0010a745, 0x0400001d, + 0x00109410, 0x04000023, 0x0201f800, 0x0010a4ca, + 0x04000020, 0x0201f800, 0x0010a921, 0x0400001d, 0x491e601e, 0x4a026403, 0x00000036, 0x0401f0e6, 0x59cc1208, 0x82080580, 0x0000ffff, 0x04000009, - 0x0201f800, 0x001091d9, 0x04000012, 0x591c0202, + 0x0201f800, 0x00109410, 0x04000012, 0x591c0202, 0x59cc0c08, 0x80040580, 0x0402000e, 0x0401f7eb, - 0x59cc1408, 0x41327800, 0x0201f800, 0x0010a217, + 0x59cc1408, 0x41327800, 0x0201f800, 0x0010a405, 0x04000008, 0x0401f7e5, 0x4803c856, 0x4a02641a, 0x00000009, 0x4a02621a, 0x00001500, 0x0401f006, 0x4803c856, 0x4a02641a, 0x00000003, 0x4a02621a, 0x00001700, 0x4a026403, 0x00000037, 0x0401f0c6, 0x4803c856, 0x4a026403, 0x00000012, 0x0401f0c2, - 0x4933c857, 0x0201f800, 0x00101eb0, 0x040200c4, - 0x0201f800, 0x00104836, 0x040206f7, 0x0201f800, - 0x00104728, 0x0400003e, 0x59cc0407, 0x48026419, + 0x4933c857, 0x0201f800, 0x0010210a, 0x040200c4, + 0x0201f800, 0x001049e7, 0x040206f7, 0x0201f800, + 0x001048d9, 0x0400003e, 0x59cc0407, 0x48026419, 0x59cc1207, 0x480a6219, 0x82080580, 0x0000ffff, - 0x04000005, 0x0201f800, 0x001091d9, 0x0400002c, + 0x04000005, 0x0201f800, 0x00109410, 0x0400002c, 0x0401f006, 0x59cc1407, 0x41327800, 0x0201f800, - 0x0010a217, 0x04000026, 0x59cc0c07, 0x591c0202, + 0x0010a405, 0x04000026, 0x59cc0c07, 0x591c0202, 0x80040580, 0x04020022, 0x4d300000, 0x411e6000, - 0x0201f800, 0x0010898b, 0x5c026000, 0x59cc0c09, + 0x0201f800, 0x00108bd7, 0x5c026000, 0x59cc0c09, 0x82040d00, 0x0000ff00, 0x840409c0, 0x0201f800, - 0x0010a745, 0x04000016, 0x82040580, 0x00000001, + 0x0010a921, 0x04000016, 0x82040580, 0x00000001, 0x0400000a, 0x82040580, 0x00000005, 0x04000004, 0x82040580, 0x00000007, 0x04020007, 0x591c0008, 0x80000540, 0x04000004, 0x59cc2808, 0x0201f000, - 0x0010a2fc, 0x4803c856, 0x4a02641a, 0x00000009, + 0x0010a4de, 0x4803c856, 0x4a02641a, 0x00000009, 0x4a02621a, 0x00002a00, 0x0401f006, 0x4803c856, 0x4a02641a, 0x00000003, 0x4a02621a, 0x00000300, 0x4a026403, 0x0000003b, 0x0401f07b, 0x4803c856, 0x4a02641a, 0x0000000b, 0x4a02621a, 0x00000000, - 0x0401f7f8, 0x4c080000, 0x0201f800, 0x0010473b, - 0x04000026, 0x0201f800, 0x00104711, 0x0201f800, - 0x0010a41c, 0x0402001e, 0x59a80026, 0x82000540, + 0x0401f7f8, 0x4c080000, 0x0201f800, 0x001048ec, + 0x04000026, 0x0201f800, 0x001048c1, 0x0201f800, + 0x0010a601, 0x0402001e, 0x59a80026, 0x82000540, 0x00000003, 0x48035026, 0x59a8001d, 0x800000d0, 0x59a80810, 0x82040d00, 0x000000ff, 0x80041540, 0x480b5010, 0x42000800, 0x00000003, 0x0201f800, - 0x001069af, 0x497b5028, 0x0201f800, 0x0010393e, + 0x00106c78, 0x497b5028, 0x0201f800, 0x00103b25, 0x04000003, 0x4a032804, 0x000007d0, 0x8c00050a, - 0x0402000a, 0x0201f800, 0x000208b4, 0x0201f800, - 0x00101bf0, 0x5c001000, 0x1c01f000, 0x0201f800, - 0x0010a43e, 0x0401f7fc, 0x5c001000, 0x0201f000, - 0x000208b4, 0x0201f800, 0x00101eb0, 0x0402004c, - 0x0201f800, 0x0010a443, 0x4a026403, 0x00000047, - 0x4a026203, 0x00000001, 0x0201f000, 0x00106470, - 0x0201f800, 0x00101eb0, 0x04020041, 0x0201f800, - 0x0010a443, 0x4a026403, 0x00000047, 0x4a026203, - 0x00000001, 0x0201f000, 0x00106470, 0x0201f800, - 0x00101eb0, 0x04020036, 0x0201f800, 0x0010a443, - 0x0201f000, 0x000208b4, 0x0401f834, 0x04000030, + 0x0402000a, 0x0201f800, 0x0002077d, 0x0201f800, + 0x00101e45, 0x5c001000, 0x1c01f000, 0x0201f800, + 0x0010a623, 0x0401f7fc, 0x5c001000, 0x0201f000, + 0x0002077d, 0x0201f800, 0x0010210a, 0x0402004c, + 0x0201f800, 0x0010a628, 0x4a026403, 0x00000047, + 0x4a026203, 0x00000001, 0x0201f000, 0x0010672b, + 0x0201f800, 0x0010210a, 0x04020041, 0x0201f800, + 0x0010a628, 0x4a026403, 0x00000047, 0x4a026203, + 0x00000001, 0x0201f000, 0x0010672b, 0x0201f800, + 0x0010210a, 0x04020036, 0x0201f800, 0x0010a628, + 0x0201f000, 0x0002077d, 0x0401f834, 0x04000030, 0x4a026403, 0x0000004e, 0x4a026203, 0x00000001, - 0x0201f000, 0x00106470, 0x4a026403, 0x0000004f, + 0x0201f000, 0x0010672b, 0x4a026403, 0x0000004f, 0x497a601c, 0x59cc0a06, 0x82040d00, 0x000000ff, 0x800409c0, 0x0400065f, 0x82040580, 0x00000001, 0x04020005, 0x59cc0808, 0x59a80005, 0x80040580, 0x04000658, 0x82040580, 0x00000002, 0x0402000a, 0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002, - 0x83341c00, 0x00000006, 0x0201f800, 0x001082ff, + 0x83341c00, 0x00000006, 0x0201f800, 0x0010855a, 0x0400064c, 0x4a02601c, 0x00000001, 0x0401f649, 0x4a026403, 0x00000050, 0x59cc0207, 0x4802601c, 0x0401f644, 0x4a026203, 0x00000001, 0x42000800, - 0x80000040, 0x0201f000, 0x00020855, 0x4803c857, - 0x0201f000, 0x000208b4, 0x4d2c0000, 0x4c500000, + 0x80000040, 0x0201f000, 0x00020721, 0x4803c857, + 0x0201f000, 0x0002077d, 0x4d2c0000, 0x4c500000, 0x4c580000, 0x4c540000, 0x59a80016, 0x82000c80, - 0x00000841, 0x0402102d, 0x0201f800, 0x00100819, - 0x0400002a, 0x492e6008, 0x59a80016, 0x48025802, - 0x82000400, 0x00000003, 0x80000104, 0x83cca400, - 0x00000006, 0x82000c80, 0x0000000b, 0x04001015, - 0x4a025811, 0x0000000b, 0x4200b000, 0x0000000b, - 0x832c0400, 0x00000005, 0x4000a800, 0x0201f800, - 0x0010a93e, 0x412c7000, 0x800409c0, 0x04020003, - 0x49787001, 0x0401f00e, 0x0201f800, 0x00100819, - 0x0400000e, 0x492c7001, 0x40040000, 0x0401f7ea, + 0x00000829, 0x04021029, 0x0201f800, 0x001007d3, + 0x04000026, 0x492e6008, 0x59a80016, 0x80000104, + 0x48025802, 0x83cca400, 0x00000006, 0x82000c80, + 0x0000000b, 0x04001013, 0x4a025811, 0x0000000b, + 0x4200b000, 0x0000000b, 0x832c0400, 0x00000005, + 0x4000a800, 0x0201f800, 0x0010ab17, 0x412c7000, + 0x0201f800, 0x001007d3, 0x04000010, 0x492c7001, + 0x40040000, 0x800409c0, 0x04000009, 0x0401f7ec, 0x48025811, 0x4000b000, 0x832c0400, 0x00000005, - 0x4000a800, 0x0201f800, 0x0010a93e, 0x82000540, + 0x4000a800, 0x0201f800, 0x0010ab17, 0x82000540, 0x00000001, 0x0401f006, 0x497b5016, 0x59325808, - 0x0201f800, 0x00100843, 0x80000580, 0x5c00a800, + 0x0201f800, 0x001007fd, 0x80000580, 0x5c00a800, 0x5c00b000, 0x5c00a000, 0x5c025800, 0x1c01f000, 0x4d340000, 0x59326809, 0x59343400, 0x4933c857, - 0x4937c857, 0x481bc857, 0x0201f800, 0x00104842, - 0x5c026800, 0x1c01f000, 0x4933c857, 0x4c600000, - 0x4c5c0000, 0x4d3c0000, 0x4d440000, 0x4d340000, - 0x0401f84f, 0x04020037, 0x59cc0207, 0x82000d00, - 0x0000ff00, 0x900411c0, 0x59cc000a, 0x82000500, - 0x00ffffff, 0x80081540, 0x480a601c, 0x8c040d18, - 0x04000011, 0x42003000, 0x00000008, 0x0201f800, - 0x0010a756, 0x42000000, 0x0010b662, 0x0201f800, - 0x0010a86e, 0x4200b800, 0x00000002, 0x4200c000, - 0x00000001, 0x417a7800, 0x0201f800, 0x00101e48, - 0x0401f01f, 0x4178b800, 0x8c040d1a, 0x04000019, - 0x59cc000a, 0x0201f800, 0x001059b9, 0x02000800, - 0x00020267, 0x04020013, 0x59300009, 0x4c000000, - 0x49366009, 0x42003000, 0x00000009, 0x0201f800, - 0x0010a75e, 0x42000000, 0x0010b662, 0x0201f800, - 0x0010a86e, 0x417a7800, 0x4178c000, 0x0201f800, - 0x00101e48, 0x5c000000, 0x48026009, 0x0401f004, - 0x82000540, 0x00000001, 0x0401f003, 0x405c2800, - 0x80000580, 0x5c026800, 0x5c028800, 0x5c027800, - 0x5c00b800, 0x5c00c000, 0x1c01f000, 0x4933c857, - 0x59cc0206, 0x82000480, 0x00000010, 0x04021006, - 0x4a02621a, 0x00000000, 0x82000540, 0x00000001, - 0x0401f002, 0x80000580, 0x1c01f000, 0x4933c857, - 0x4a02621a, 0x00000000, 0x59cc0407, 0x82000500, - 0x0000ff00, 0x82000580, 0x00000800, 0x04020009, - 0x59cc0006, 0x82000500, 0x00ff0000, 0x82000d80, - 0x00140000, 0x04000003, 0x82000d80, 0x00100000, - 0x1c01f000, 0x59300403, 0x82003480, 0x00000051, - 0x02021800, 0x00100615, 0x83383580, 0x00000013, - 0x04020003, 0x4803c857, 0x0c01f016, 0x4933c857, - 0x493bc857, 0x83383580, 0x00000027, 0x04000005, - 0x83383580, 0x00000014, 0x02020800, 0x00100615, - 0x493bc857, 0x4937c857, 0x0201f800, 0x00104711, - 0x42000800, 0x00000007, 0x0201f800, 0x001043c7, - 0x0201f800, 0x001068f6, 0x0201f000, 0x00107698, - 0x00109c29, 0x00109c32, 0x00109c29, 0x00109c29, - 0x00109c29, 0x00109c32, 0x00109c3d, 0x00109cb0, - 0x00109c82, 0x00109cb0, 0x00109c9a, 0x00109cb0, - 0x00109ca1, 0x00109cb0, 0x00109ca9, 0x00109cb0, - 0x00109ca9, 0x00109cb0, 0x00109cb0, 0x00109c29, - 0x00109c29, 0x00109c29, 0x00109c29, 0x00109c29, - 0x00109c29, 0x00109c29, 0x00109c29, 0x00109c29, - 0x00109c29, 0x00109c29, 0x00109c32, 0x00109c29, - 0x00109cb0, 0x00109c29, 0x00109c29, 0x00109cb0, - 0x00109c29, 0x00109cad, 0x00109cb0, 0x00109c29, - 0x00109c29, 0x00109c29, 0x00109c29, 0x00109cb0, - 0x00109cb0, 0x00109c29, 0x00109ca6, 0x00109cb0, - 0x00109c29, 0x00109c37, 0x00109c29, 0x00109c29, - 0x00109c29, 0x00109c29, 0x00109cac, 0x00109cb0, - 0x00109c29, 0x00109c29, 0x00109cb0, 0x00109cb0, - 0x00109c29, 0x00109c29, 0x00109c29, 0x00109c29, - 0x00109c29, 0x00109c29, 0x00109c29, 0x00109c29, - 0x00109c29, 0x00109c2b, 0x00109c29, 0x00109c2b, - 0x00109c29, 0x00109c29, 0x00109c2b, 0x00109c29, - 0x00109c29, 0x00109c29, 0x00109c2b, 0x00109c2b, - 0x00109c2b, 0x0201f800, 0x00100615, 0x4d2c0000, - 0x59325808, 0x0201f800, 0x00100843, 0x5c025800, - 0x0201f000, 0x000208b4, 0x59a80037, 0x48026206, - 0x4a026203, 0x00000002, 0x1c01f000, 0x4d3c0000, - 0x417a7800, 0x0201f800, 0x001043bd, 0x5c027800, - 0x0401f074, 0x42000800, 0x00000007, 0x0201f800, - 0x001043c7, 0x59a80026, 0x8c000508, 0x04000012, - 0x59326809, 0x4c580000, 0x4200b000, 0x00000002, - 0x83a81c00, 0x00000002, 0x83341400, 0x00000006, - 0x0201f800, 0x001082ff, 0x80000540, 0x5c00b000, - 0x04020060, 0x59340200, 0x8400051a, 0x48026a00, - 0x0401f01b, 0x599c0017, 0x8c00050a, 0x04020059, - 0x4d3c0000, 0x417a7800, 0x0201f800, 0x001043bd, - 0x5c027800, 0x42000800, 0x00000007, 0x0201f800, - 0x001043c7, 0x59340212, 0x82000500, 0x0000ff00, - 0x0400004c, 0x599c0019, 0x8c00050e, 0x04020049, - 0x416c0000, 0x82000580, 0x00000002, 0x04020004, - 0x59a8001b, 0x80000000, 0x4803501b, 0x42000800, - 0x00000003, 0x0201f800, 0x001043c7, 0x4a026406, - 0x00000001, 0x4a026203, 0x00000001, 0x4a026403, - 0x00000002, 0x0201f800, 0x00106470, 0x4ce80000, - 0x4201d000, 0x00000001, 0x0201f800, 0x00105ce7, - 0x5c01d000, 0x1c01f000, 0x0201f800, 0x00104842, - 0x0400002c, 0x0201f800, 0x00106196, 0x42000800, - 0x00000004, 0x0201f800, 0x001043c7, 0x0201f800, - 0x0010a791, 0x04020023, 0x42000800, 0x00000005, - 0x0201f800, 0x001043c7, 0x4a026406, 0x00000001, - 0x4a026203, 0x00000001, 0x4a026403, 0x00000003, - 0x0201f000, 0x00106470, 0x0201f800, 0x0010484b, - 0x04020014, 0x42000800, 0x00000006, 0x0401f813, - 0x0401f010, 0x42000800, 0x00000004, 0x0201f800, - 0x001043c7, 0x0401f79c, 0x42000800, 0x00000004, - 0x0401f006, 0x0201f800, 0x00104711, 0x0401f005, - 0x0401f004, 0x0401f003, 0x0201f800, 0x001043c7, - 0x0201f000, 0x000208b4, 0x4933c857, 0x4807c857, - 0x0201f800, 0x001043c7, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x001043bd, 0x5c027800, 0x0201f000, - 0x00104711, 0x59340400, 0x4803c857, 0x80000110, - 0x82003480, 0x0000000c, 0x02021800, 0x00100615, - 0x83383580, 0x00000015, 0x04020002, 0x0c01f006, - 0x83383580, 0x00000016, 0x02020800, 0x00100615, - 0x0c01f00d, 0x00107e42, 0x00107e42, 0x00107e42, - 0x00107e42, 0x00107e42, 0x00107e42, 0x00109d11, - 0x00109ce5, 0x00107e42, 0x00107e42, 0x00107e42, - 0x00107e42, 0x00107e42, 0x00107e42, 0x00107e42, - 0x00107e42, 0x00107e42, 0x00107e42, 0x00109d11, - 0x00109d18, 0x00107e42, 0x00107e42, 0x00107e42, - 0x00107e42, 0x4933c857, 0x599c0017, 0x8c00050a, - 0x0402001b, 0x813669c0, 0x04000019, 0x59340212, - 0x82000500, 0x0000ff00, 0x04000015, 0x599c0019, - 0x8c00050e, 0x04020012, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x001043bd, 0x5c027800, 0x42000800, - 0x00000003, 0x0201f800, 0x001043c7, 0x4a026406, - 0x00000001, 0x4a026203, 0x00000001, 0x4a026403, - 0x00000002, 0x0201f000, 0x00106470, 0x59cc0001, - 0x59340802, 0x80040580, 0x82000500, 0x00ffffff, - 0x02020000, 0x000208b4, 0x59345002, 0x0201f800, - 0x001040e4, 0x482a6802, 0x0201f000, 0x000208b4, - 0x1c01f000, 0x4933c857, 0x59303403, 0x82183580, - 0x0000001e, 0x02000000, 0x000208b4, 0x1c01f000, - 0x4933c857, 0x0201f800, 0x00108180, 0x02020000, - 0x000208b4, 0x4a026203, 0x00000001, 0x4a026403, - 0x00000001, 0x0201f000, 0x00106470, 0x493bc857, - 0x83380580, 0x00000051, 0x0402000b, 0x0201f800, - 0x00106cb4, 0x02020000, 0x001076fb, 0x59300203, - 0x82000580, 0x00000002, 0x0400006e, 0x0201f800, - 0x00100615, 0x83380580, 0x00000027, 0x04000014, - 0x83380580, 0x00000048, 0x04000006, 0x83380580, - 0x00000014, 0x0400000e, 0x02020800, 0x00100615, - 0x0201f800, 0x00106cb4, 0x02020000, 0x001076fb, - 0x59300203, 0x82000580, 0x00000004, 0x02000000, - 0x000209a5, 0x0201f800, 0x00100615, 0x4933c857, - 0x59300403, 0x82000c80, 0x00000044, 0x02021800, - 0x00100615, 0x82000480, 0x00000040, 0x02001800, - 0x00100615, 0x40027000, 0x4803c857, 0x0c01f001, - 0x00109d58, 0x00109d5a, 0x00109d5a, 0x00109d75, - 0x0201f800, 0x00100615, 0x0201f800, 0x001068f6, - 0x59325808, 0x812e59c0, 0x04000016, 0x832c0500, - 0x00ff0000, 0x04000013, 0x4a026203, 0x00000002, - 0x59326809, 0x59340200, 0x8c00050e, 0x0402000d, - 0x42028000, 0x00000004, 0x0201f800, 0x0010a201, - 0x497a6008, 0x59300206, 0x80000540, 0x04020003, - 0x59a80038, 0x48026206, 0x4a026203, 0x00000007, - 0x1c01f000, 0x0201f800, 0x001068f6, 0x0201f800, - 0x00108df4, 0x02000000, 0x00107698, 0x59325808, - 0x0201f800, 0x0010083a, 0x0201f000, 0x00107698, - 0x0201f800, 0x00100615, 0x59325808, 0x592c040a, - 0x8c000502, 0x04000007, 0x4a026203, 0x00000007, - 0x42027000, 0x00000043, 0x0201f000, 0x000208d8, - 0x4a026203, 0x00000004, 0x1c01f000, 0x0201f800, - 0x0010a3b6, 0x02000000, 0x000209a3, 0x1c01f000, - 0x4a026203, 0x00000001, 0x4a026403, 0x00000041, - 0x42027800, 0x80002042, 0x0201f000, 0x00020855, - 0x83380580, 0x00000051, 0x04000006, 0x83380580, - 0x00000041, 0x02020800, 0x00100615, 0x1c01f000, - 0x0201f800, 0x00020831, 0x0201f800, 0x0010a3fa, - 0x0201f000, 0x000208b4, 0x83380480, 0x00000052, - 0x02021800, 0x00100615, 0x83380480, 0x00000049, - 0x02001800, 0x00100615, 0x0c01f001, 0x00109dbe, - 0x00109ddf, 0x00109dbc, 0x00109dbc, 0x00109dbc, - 0x00109dbc, 0x00109ddf, 0x00109dbc, 0x00109e01, - 0x0201f800, 0x00100615, 0x59325808, 0x592c040a, + 0x4937c857, 0x481bc857, 0x0201f800, 0x001049f3, + 0x5c026800, 0x1c01f000, 0x4933c857, 0x4c5c0000, + 0x4d3c0000, 0x0401f840, 0x0402002c, 0x59cc0207, + 0x82000d00, 0x0000ff00, 0x900411c0, 0x59cc000a, + 0x82000500, 0x00ffffff, 0x80081540, 0x480a601c, + 0x8c040d18, 0x0400000e, 0x42003000, 0x00000008, + 0x0201f800, 0x0010a932, 0x42000000, 0x0010b863, + 0x0201f800, 0x0010aa47, 0x4200b800, 0x00000002, + 0x42027800, 0x00000001, 0x0401f011, 0x4178b800, + 0x8c040d1a, 0x04000011, 0x59cc000a, 0x0201f800, + 0x00105c9a, 0x0402000d, 0x42003000, 0x00000009, + 0x0201f800, 0x0010a93a, 0x42000000, 0x0010b863, + 0x0201f800, 0x0010aa47, 0x417a7800, 0x0201f800, + 0x001020a1, 0x0401f004, 0x82000540, 0x00000001, + 0x0401f002, 0x80000580, 0x5c027800, 0x5c00b800, + 0x1c01f000, 0x4933c857, 0x59cc0206, 0x82000480, + 0x00000010, 0x04021006, 0x4a02621a, 0x00000000, + 0x82000540, 0x00000001, 0x0401f002, 0x80000580, + 0x1c01f000, 0x4933c857, 0x4a02621a, 0x00000000, + 0x59cc0407, 0x82000500, 0x0000ff00, 0x82000580, + 0x00000800, 0x04020009, 0x59cc0006, 0x82000500, + 0x00ff0000, 0x82000d80, 0x00140000, 0x04000003, + 0x82000d80, 0x00100000, 0x1c01f000, 0x4933c857, + 0x59300403, 0x82003480, 0x00000051, 0x02021800, + 0x001005d8, 0x83383580, 0x00000013, 0x04020003, + 0x4803c857, 0x0c01f012, 0x83383580, 0x00000027, + 0x04000005, 0x83383580, 0x00000014, 0x02020800, + 0x001005d8, 0x0201f800, 0x001048c1, 0x42000800, + 0x00000007, 0x0201f800, 0x00104571, 0x0201f800, + 0x00106bbf, 0x0201f000, 0x00107911, 0x00109e3c, + 0x00109e45, 0x00109e3c, 0x00109e3c, 0x00109e3c, + 0x00109e45, 0x00109e50, 0x00109ecd, 0x00109e95, + 0x00109ecd, 0x00109ead, 0x00109ecd, 0x00109ebe, + 0x00109ecd, 0x00109ec6, 0x00109ecd, 0x00109ec6, + 0x00109ecd, 0x00109ecd, 0x00109e3c, 0x00109e3c, + 0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c, + 0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c, + 0x00109e3c, 0x00109e45, 0x00109e3c, 0x00109ecd, + 0x00109e3c, 0x00109e3c, 0x00109ecd, 0x00109e3c, + 0x00109eca, 0x00109ecd, 0x00109e3c, 0x00109e3c, + 0x00109e3c, 0x00109e3c, 0x00109ecd, 0x00109ecd, + 0x00109e3c, 0x00109ec3, 0x00109ecd, 0x00109e3c, + 0x00109e4a, 0x00109e3c, 0x00109e3c, 0x00109e3c, + 0x00109e3c, 0x00109ec9, 0x00109ecd, 0x00109e3c, + 0x00109e3c, 0x00109ecd, 0x00109ecd, 0x00109e3c, + 0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c, + 0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c, + 0x00109e3e, 0x00109e3c, 0x00109e3e, 0x00109e3c, + 0x00109e3c, 0x00109e3e, 0x00109e3c, 0x00109e3c, + 0x00109e3c, 0x00109e3e, 0x00109e3e, 0x00109e3e, + 0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808, + 0x0201f800, 0x001007fd, 0x5c025800, 0x0201f000, + 0x0002077d, 0x59a80037, 0x48026206, 0x4a026203, + 0x00000002, 0x1c01f000, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x00104567, 0x5c027800, 0x0401f07e, + 0x42000800, 0x00000007, 0x0201f800, 0x00104571, + 0x59a80026, 0x8c000508, 0x04000012, 0x59326809, + 0x4c580000, 0x4200b000, 0x00000002, 0x83a81c00, + 0x00000002, 0x83341400, 0x00000006, 0x0201f800, + 0x0010855a, 0x80000540, 0x5c00b000, 0x0402006a, + 0x59340200, 0x8400051a, 0x48026a00, 0x0401f01b, + 0x599c0017, 0x8c00050a, 0x04020063, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00104567, 0x5c027800, + 0x42000800, 0x00000007, 0x0201f800, 0x00104571, + 0x59340212, 0x82000500, 0x0000ff00, 0x04000056, + 0x599c0019, 0x8c00050e, 0x04020053, 0x416c0000, + 0x82000580, 0x00000002, 0x04020004, 0x59a8001b, + 0x80000000, 0x4803501b, 0x42000800, 0x00000003, + 0x0201f800, 0x00104571, 0x4a026406, 0x00000001, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000002, + 0x0201f800, 0x0010672b, 0x4ce80000, 0x4201d000, + 0x00000001, 0x0201f800, 0x00105fae, 0x5c01d000, + 0x1c01f000, 0x0201f800, 0x001049f3, 0x04000036, + 0x0201f800, 0x0010645e, 0x42000800, 0x00000004, + 0x0201f800, 0x00104571, 0x0201f800, 0x0010a96a, + 0x0402002d, 0x42000800, 0x00000005, 0x0201f800, + 0x00104571, 0x4a026406, 0x00000001, 0x4a026203, + 0x00000001, 0x4a026403, 0x00000003, 0x0201f000, + 0x0010672b, 0x42000800, 0x00000006, 0x0401f820, + 0x59303009, 0x599c0017, 0x8c00050a, 0x0402001a, + 0x59a80026, 0x8c000508, 0x04000017, 0x0201f800, + 0x001049e7, 0x04000014, 0x59a8001b, 0x80000000, + 0x4803501b, 0x0401f7c5, 0x42000800, 0x00000004, + 0x0201f800, 0x00104571, 0x0401f792, 0x42000800, + 0x00000004, 0x0401f006, 0x0201f800, 0x001048c1, + 0x0401f005, 0x0401f004, 0x0401f003, 0x0201f800, + 0x00104571, 0x0201f000, 0x0002077d, 0x4933c857, + 0x4807c857, 0x0201f800, 0x00104571, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00104567, 0x5c027800, + 0x0201f800, 0x00102074, 0x1c01f000, 0x4933c857, + 0x59340400, 0x80000110, 0x82003480, 0x0000000c, + 0x02021800, 0x001005d8, 0x83383580, 0x00000015, + 0x04020002, 0x0c01f006, 0x83383580, 0x00000016, + 0x02020800, 0x001005d8, 0x0c01f00d, 0x001080b8, + 0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8, + 0x001080b8, 0x00109f30, 0x00109f03, 0x001080b8, + 0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8, + 0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8, + 0x001080b8, 0x00109f30, 0x00109f37, 0x001080b8, + 0x001080b8, 0x001080b8, 0x001080b8, 0x4933c857, + 0x599c0017, 0x8c00050a, 0x0402001b, 0x813669c0, + 0x04000019, 0x59340212, 0x82000500, 0x0000ff00, + 0x04000015, 0x599c0019, 0x8c00050e, 0x04020012, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00104567, + 0x5c027800, 0x42000800, 0x00000003, 0x0201f800, + 0x00104571, 0x4a026406, 0x00000001, 0x4a026203, + 0x00000001, 0x4a026403, 0x00000002, 0x0201f000, + 0x0010672b, 0x59cc0001, 0x0201f800, 0x00105c9a, + 0x0402000b, 0x0201f800, 0x00020245, 0x02020000, + 0x0002077d, 0x59345002, 0x0201f800, 0x001042b4, + 0x482a6802, 0x0201f000, 0x0002077d, 0x1c01f000, + 0x4933c857, 0x59303403, 0x82183580, 0x0000001e, + 0x02000000, 0x0002077d, 0x1c01f000, 0x4933c857, + 0x0201f800, 0x001083df, 0x02020000, 0x0002077d, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000001, + 0x0201f000, 0x0010672b, 0x493bc857, 0x83380580, + 0x00000051, 0x0402000b, 0x0201f800, 0x00106f60, + 0x02020000, 0x00107974, 0x59300203, 0x82000580, + 0x00000002, 0x0400006d, 0x0201f800, 0x001005d8, + 0x83380580, 0x00000027, 0x04000014, 0x83380580, + 0x00000048, 0x04000006, 0x83380580, 0x00000014, + 0x0400000e, 0x02020800, 0x001005d8, 0x0201f800, + 0x00106f60, 0x02020000, 0x00107974, 0x59300203, + 0x82000580, 0x00000004, 0x02000000, 0x0002086e, + 0x0201f800, 0x001005d8, 0x59300403, 0x82000c80, + 0x00000044, 0x02021800, 0x001005d8, 0x82000480, + 0x00000040, 0x02001800, 0x001005d8, 0x40027000, + 0x4803c857, 0x0c01f001, 0x00109f76, 0x00109f78, + 0x00109f78, 0x00109f93, 0x0201f800, 0x001005d8, + 0x0201f800, 0x00106bbf, 0x59325808, 0x812e59c0, + 0x04000016, 0x832c0500, 0x00ff0000, 0x04000013, + 0x4a026203, 0x00000002, 0x59326809, 0x59340200, + 0x8c00050e, 0x0402000d, 0x42028000, 0x00000004, + 0x0201f800, 0x0010a3ef, 0x497a6008, 0x59300206, + 0x80000540, 0x04020003, 0x59a80038, 0x48026206, + 0x4a026203, 0x00000007, 0x1c01f000, 0x0201f800, + 0x00106bbf, 0x0201f800, 0x00109037, 0x02000000, + 0x00107911, 0x59325808, 0x0201f800, 0x001007f4, + 0x0201f000, 0x00107911, 0x0201f800, 0x001005d8, + 0x59325808, 0x592c040a, 0x8c000502, 0x04000007, + 0x4a026203, 0x00000007, 0x42027000, 0x00000043, + 0x0201f000, 0x000207a1, 0x4a026203, 0x00000004, + 0x1c01f000, 0x0201f800, 0x0010a597, 0x02000000, + 0x0002086c, 0x1c01f000, 0x4a026203, 0x00000001, + 0x4a026403, 0x00000041, 0x42027800, 0x80002042, + 0x0201f000, 0x00020721, 0x83380580, 0x00000051, + 0x04000006, 0x83380580, 0x00000041, 0x02020800, + 0x001005d8, 0x1c01f000, 0x0201f800, 0x000206fd, + 0x0201f800, 0x0010a5df, 0x0201f000, 0x0002077d, + 0x83380480, 0x00000050, 0x02021800, 0x001005d8, + 0x83380480, 0x00000049, 0x02001800, 0x001005d8, + 0x0c01f001, 0x00109fda, 0x00109ffb, 0x00109fd8, + 0x00109fd8, 0x00109fd8, 0x00109fd8, 0x00109ffb, + 0x0201f800, 0x001005d8, 0x59325808, 0x592c040a, 0x8c00051e, 0x0400000d, 0x82000d00, 0x000000c0, 0x82040d80, 0x00000080, 0x0400000d, 0x59300804, 0x8c040d18, 0x0402000a, 0x42027000, 0x00000041, - 0x0201f000, 0x000209c4, 0x4a026203, 0x00000007, - 0x497a6206, 0x0201f000, 0x00020831, 0x59325808, + 0x0201f000, 0x0002088d, 0x4a026203, 0x00000007, + 0x497a6206, 0x0201f000, 0x000206fd, 0x59325808, 0x592c0c0a, 0x8c040d1a, 0x04020005, 0x0201f800, - 0x00020831, 0x0201f000, 0x000208b4, 0x0201f800, - 0x0010a3b6, 0x040007fa, 0x1c01f000, 0x0201f800, - 0x001068c1, 0x59325808, 0x59326809, 0x59340200, + 0x000206fd, 0x0201f000, 0x0002077d, 0x0201f800, + 0x0010a597, 0x040007fa, 0x1c01f000, 0x0201f800, + 0x00106b8a, 0x59325808, 0x59326809, 0x59340200, 0x8c00050e, 0x0400000e, 0x592c040a, 0x82000500, 0x000000c0, 0x82000580, 0x00000080, 0x04000005, 0x592c000f, 0x59301815, 0x800c1c80, 0x480e6015, - 0x4a026203, 0x00000002, 0x0401f00e, 0x42028000, - 0x00000004, 0x0201f800, 0x0010a201, 0x59300206, - 0x80000540, 0x04020004, 0x59a80038, 0x800000c2, - 0x48026206, 0x497a6008, 0x4a026203, 0x00000007, - 0x1c01f000, 0x4933c857, 0x0201f800, 0x00106cb4, - 0x02020800, 0x00100615, 0x59300203, 0x82000580, - 0x00000002, 0x04000793, 0x0201f800, 0x00100615, + 0x4a026203, 0x00000002, 0x0401f00d, 0x42028000, + 0x00000004, 0x0401fbde, 0x59300206, 0x80000540, + 0x04020004, 0x59a80038, 0x800000c2, 0x48026206, + 0x497a6008, 0x4a026203, 0x00000007, 0x1c01f000, 0x4a026203, 0x00000007, 0x497a6206, 0x0201f000, - 0x00020831, 0x4a026203, 0x00000007, 0x497a6206, - 0x0201f000, 0x0002082c, 0x59300414, 0x8c00051c, - 0x02020000, 0x000209b5, 0x59325808, 0x592c200f, + 0x000206fd, 0x4a026203, 0x00000007, 0x497a6206, + 0x0201f000, 0x000206f8, 0x59300414, 0x8c00051c, + 0x02020000, 0x0002087e, 0x59325808, 0x592c200f, 0x40080000, 0x80102480, 0x59300015, 0x80102400, - 0x48126015, 0x0201f000, 0x000209b5, 0x8c040d0e, + 0x48126015, 0x0201f000, 0x0002087e, 0x8c040d0e, 0x0402000a, 0x4a026203, 0x00000006, 0x0401f823, - 0x5930001f, 0x80000540, 0x02020800, 0x00100dc4, - 0x0201f000, 0x0002082c, 0x4a026203, 0x00000002, + 0x5930001f, 0x80000540, 0x02020800, 0x00100d7c, + 0x0201f000, 0x000206f8, 0x4a026203, 0x00000002, 0x1c01f000, 0x42000800, 0x00000001, 0x0201f800, - 0x00100dc4, 0x82040580, 0x00000001, 0x02000000, - 0x000209bc, 0x0401f7d8, 0x59300414, 0x8c00051c, - 0x04000006, 0x0201f800, 0x00100bad, 0x02000000, - 0x000209ae, 0x1c01f000, 0x59300011, 0x80000540, - 0x04020005, 0x0201f800, 0x00100bad, 0x02000000, - 0x000209ae, 0x1c01f000, 0x492fc857, 0x480bc857, + 0x00100d7c, 0x82040580, 0x00000001, 0x02000000, + 0x00020885, 0x0401f7d8, 0x59300414, 0x8c00051c, + 0x04000006, 0x0201f800, 0x00100b63, 0x02000000, + 0x00020877, 0x1c01f000, 0x59300011, 0x80000540, + 0x04020005, 0x0201f800, 0x00100b63, 0x02000000, + 0x00020877, 0x1c01f000, 0x492fc857, 0x480bc857, 0x8c08153e, 0x04000006, 0x80081080, 0x80081000, 0x42000800, 0x00000009, 0x0401f003, 0x42000800, 0x00000015, 0x480a580b, 0x1c01f000, 0x83380580, 0x00000013, 0x04000005, 0x83380580, 0x00000014, - 0x02020800, 0x00100615, 0x59300414, 0x8c000516, - 0x02000800, 0x00100615, 0x1c01f000, 0x0201f800, - 0x00100615, 0x59300008, 0x80000540, 0x02020800, - 0x00100615, 0x1c01f000, 0x59300414, 0x8c000516, - 0x02000800, 0x00100615, 0x1c01f000, 0x4a026203, + 0x02020800, 0x001005d8, 0x59300414, 0x8c000516, + 0x02000800, 0x001005d8, 0x1c01f000, 0x0201f800, + 0x001005d8, 0x59300008, 0x80000540, 0x02020800, + 0x001005d8, 0x1c01f000, 0x59300414, 0x8c000516, + 0x02000800, 0x001005d8, 0x1c01f000, 0x4a026203, 0x00000004, 0x493a6403, 0x42000800, 0x80002001, - 0x0201f000, 0x00020855, 0x4a026203, 0x00000003, - 0x493a6403, 0x0201f800, 0x000200ca, 0x59325808, + 0x0201f000, 0x00020721, 0x4a026203, 0x00000003, + 0x493a6403, 0x0201f800, 0x000200c9, 0x59325808, 0x592c040a, 0x8c00051e, 0x04000012, 0x82000500, 0x000000c0, 0x82000580, 0x00000080, 0x04000011, 0x59300414, 0x8c000512, 0x0402000a, 0x8c000510, 0x04020008, 0x592c040c, 0x80000540, 0x04020005, - 0x82080d40, 0x80003065, 0x0201f000, 0x00106466, - 0x82080d40, 0x80002065, 0x0201f000, 0x00106466, - 0x82080d40, 0x80002042, 0x0201f000, 0x00106466, + 0x82080d40, 0x80003065, 0x0201f000, 0x00106721, + 0x82080d40, 0x80002065, 0x0201f000, 0x00106721, + 0x82080d40, 0x80002042, 0x0201f000, 0x00106721, 0x4933c857, 0x493bc857, 0x83380480, 0x00000044, - 0x02021800, 0x00100615, 0x83380480, 0x00000041, - 0x02001800, 0x00100615, 0x0c01f001, 0x00109ea6, - 0x00109eb6, 0x00109ecb, 0x59325808, 0x592c040a, + 0x02021800, 0x001005d8, 0x83380480, 0x00000041, + 0x02001800, 0x001005d8, 0x0c01f001, 0x0010a0b6, + 0x0010a0c6, 0x0010a0db, 0x59325808, 0x592c040a, 0x8c00051e, 0x0400001d, 0x82001d00, 0x000000c0, 0x820c1d80, 0x000000c0, 0x04000018, 0x4a026203, 0x00000001, 0x493a6403, 0x42000800, 0x80002042, - 0x0201f000, 0x00020855, 0x59325808, 0x592c040a, + 0x0201f000, 0x00020721, 0x59325808, 0x592c040a, 0x8c00051e, 0x0400000d, 0x82001d00, 0x000000c0, 0x820c1d80, 0x000000c0, 0x04000008, 0x4a026203, 0x00000001, 0x493a6403, 0x42000800, 0x80002001, - 0x0201f000, 0x00020855, 0x497a6008, 0x497a6206, - 0x42028000, 0x00000004, 0x0401f337, 0x59325808, + 0x0201f000, 0x00020721, 0x497a6008, 0x497a6206, + 0x42028000, 0x00000004, 0x0401f315, 0x59325808, 0x592c040a, 0x8c00051e, 0x040007f8, 0x82001d00, 0x000000c0, 0x820c1d80, 0x000000c0, 0x040007f3, 0x4a026203, 0x00000003, 0x493a6403, 0x0201f800, - 0x000200ca, 0x82080d40, 0x80002065, 0x0201f000, - 0x00106466, 0x4933c857, 0x493bc857, 0x83380580, + 0x000200c9, 0x82080d40, 0x80002065, 0x0201f000, + 0x00106721, 0x4933c857, 0x493bc857, 0x83380580, 0x00000085, 0x04000006, 0x83380580, 0x00000088, - 0x0400000a, 0x0201f800, 0x00100615, 0x4a026203, + 0x0400000a, 0x0201f800, 0x001005d8, 0x4a026203, 0x00000009, 0x493a6403, 0x42000800, 0x8000004b, - 0x0201f000, 0x00020855, 0x4d1c0000, 0x813669c0, - 0x04000004, 0x0201f800, 0x0010a3b0, 0x04020044, + 0x0201f000, 0x00020721, 0x4d1c0000, 0x813669c0, + 0x04000004, 0x0201f800, 0x0010a592, 0x04020044, 0x59cc1404, 0x0401f846, 0x04000018, 0x591c0406, 0x82000500, 0x0000001f, 0x82002580, 0x00000006, 0x04000007, 0x82002580, 0x00000004, 0x0400002e, 0x82002580, 0x00000011, 0x0402000c, 0x497a3a05, - 0x42002000, 0x00000054, 0x0201f800, 0x001077d1, + 0x42002000, 0x00000054, 0x0201f800, 0x00107a4a, 0x4a026203, 0x00000007, 0x493a6403, 0x0201f800, - 0x0010a79b, 0x0401f02c, 0x0201f800, 0x0010393e, + 0x0010a974, 0x0401f02c, 0x0201f800, 0x00103b25, 0x04000004, 0x42023800, 0xffffffff, 0x0401f7f1, 0x813669c0, 0x04020009, 0x59cc0001, 0x0201f800, - 0x001059b9, 0x0402001e, 0x0201f800, 0x001043fc, + 0x00105c9a, 0x0402001e, 0x0201f800, 0x001045a6, 0x0402001b, 0x49366009, 0x4a026403, 0x00000087, 0x59cc1204, 0x82081580, 0x0000ffff, 0x04020003, 0x4a026403, 0x00000086, 0x4a026203, 0x00000001, - 0x42000800, 0x80000040, 0x0201f800, 0x00020855, + 0x42000800, 0x80000040, 0x0201f800, 0x00020721, 0x0401f00d, 0x591c0203, 0x82000580, 0x00000007, 0x040207de, 0x4d300000, 0x411e6000, 0x0201f800, - 0x00107698, 0x5c026000, 0x0401f7d8, 0x0201f800, - 0x00107698, 0x5c023800, 0x1c01f000, 0x4933c857, - 0x480bc857, 0x42002800, 0x0010cfc0, 0x41300000, + 0x00107911, 0x5c026000, 0x0401f7d8, 0x0201f800, + 0x00107911, 0x5c023800, 0x1c01f000, 0x4933c857, + 0x480bc857, 0x42002800, 0x0010d1c0, 0x41300000, 0x80140580, 0x04000017, 0x58140203, 0x82000580, 0x00000000, 0x04000013, 0x58140202, 0x80080580, 0x04020010, 0x58141c06, 0x820c0580, 0x00000005, @@ -10243,660 +10375,646 @@ uint32_t risc_code01[] = { 0x0401f7f2, 0x5810201e, 0x0401f7f0, 0x40163800, 0x81300540, 0x0401f002, 0x80000580, 0x1c01f000, 0x58141807, 0x8c0c1d10, 0x040207ea, 0x0401f7e1, - 0x83380580, 0x00000013, 0x0402000e, 0x59300403, - 0x4803c857, 0x82000c80, 0x00000085, 0x02001800, - 0x00100615, 0x82000c80, 0x00000093, 0x02021800, - 0x00100615, 0x82000480, 0x00000085, 0x0c01f019, - 0x83380580, 0x00000027, 0x04000005, 0x83380580, - 0x00000014, 0x02020000, 0x001076fb, 0x493bc857, - 0x0201f800, 0x001068f6, 0x59325808, 0x812e59c0, - 0x02000000, 0x00107698, 0x4a025a06, 0x00000031, - 0x4a025811, 0x00000004, 0x4a025812, 0x000000ff, - 0x0201f800, 0x00020381, 0x0201f000, 0x00107698, - 0x00109fa6, 0x00109fad, 0x00109fad, 0x00109fa6, - 0x00109fa6, 0x00109fa6, 0x00109fa6, 0x00109fa6, - 0x00109fa6, 0x00109fa6, 0x00109fa6, 0x00109fa6, - 0x00109fa6, 0x00109fa8, 0x0201f800, 0x00100615, - 0x59325808, 0x4a025a06, 0x00000000, 0x0201f800, - 0x00020381, 0x0201f000, 0x000208b4, 0x4933c857, - 0x42000000, 0x0010b672, 0x0201f800, 0x0010a86e, - 0x0201f800, 0x0010a3fa, 0x497a6205, 0x42028000, - 0x0000000b, 0x0401f807, 0x4a026406, 0x00000006, - 0x4a026203, 0x00000007, 0x497a6206, 0x1c01f000, - 0x4933c857, 0x4943c857, 0x59300406, 0x82000580, - 0x00000007, 0x04020002, 0x1c01f000, 0x0201f800, - 0x0010698c, 0x4df00000, 0x0201f800, 0x00108a99, - 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, - 0x0c01f001, 0x00109ff4, 0x00109ff8, 0x00109fdf, - 0x0010a006, 0x0010a019, 0x00109fdf, 0x00109fdf, - 0x00109fdf, 0x00109fdf, 0x00109fdf, 0x00109fdf, - 0x00109fdf, 0x00109fdf, 0x00109fdf, 0x4d400000, - 0x5930001f, 0x80000540, 0x04000005, 0x41400800, - 0x0201f800, 0x00100dc4, 0x40068000, 0x4d2c0000, - 0x59325808, 0x0201f800, 0x00108df4, 0x04020a16, - 0x4c5c0000, 0x5930b809, 0x0201f800, 0x00107698, - 0x485e6009, 0x5c00b800, 0x5c025800, 0x5c028000, - 0x5c03e000, 0x02000000, 0x00106982, 0x1c01f000, - 0x598c000d, 0x81300580, 0x04020004, 0x0201f800, - 0x00106be2, 0x04020016, 0x0201f800, 0x00106619, - 0x040007df, 0x0201f800, 0x001068a3, 0x04000010, - 0x0201f800, 0x00100615, 0x0201f800, 0x00108a8a, - 0x04020004, 0x0201f800, 0x00106bb2, 0x04020008, - 0x0201f800, 0x001064f6, 0x040007d1, 0x0201f800, - 0x001068a3, 0x02020800, 0x00100615, 0x59300203, - 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, - 0x0c01f7b9, 0x0201f800, 0x00100ee4, 0x0401f7c4, - 0x4933c857, 0x4d440000, 0x4d340000, 0x59cc0007, - 0x0201f800, 0x001059b9, 0x02000800, 0x00020267, - 0x0402001a, 0x59300009, 0x4c000000, 0x49366009, - 0x42003000, 0x0000000b, 0x0201f800, 0x0010a766, - 0x42000000, 0x0010b660, 0x0201f800, 0x0010a86e, - 0x4d3c0000, 0x4d400000, 0x42028000, 0x00000029, - 0x417a7800, 0x0201f800, 0x00101de2, 0x5c028000, - 0x5c027800, 0x5c000000, 0x48026009, 0x59cc0007, - 0x48026802, 0x80000580, 0x5c026800, 0x5c028800, - 0x1c01f000, 0x4933c857, 0x4c040000, 0x59a80016, - 0x82000580, 0x00000074, 0x04020040, 0x59cc0a08, - 0x82040480, 0x00000100, 0x04001033, 0x59cc0c08, - 0x82040500, 0x00008000, 0x04000035, 0x59a80032, - 0x80000540, 0x04020009, 0x59301009, 0x58080212, - 0x82000500, 0x0000ff00, 0x04000004, 0x82040500, - 0x00000800, 0x0400002a, 0x59cc0c09, 0x80040840, - 0x04001024, 0x59a80826, 0x8c040d06, 0x04000004, - 0x59cc0c0f, 0x8c040d1e, 0x04020012, 0x59cc0a17, - 0x800409c0, 0x04020012, 0x59cc0a18, 0x82040480, - 0x00000100, 0x04001014, 0x59cc0c18, 0x800409c0, - 0x0402000e, 0x59cc0c19, 0x80040840, 0x04001011, - 0x59cc0c1a, 0x80040840, 0x04001011, 0x0401f018, - 0x4a02621a, 0x00000100, 0x0401f012, 0x4a02621a, - 0x00000300, 0x0401f00f, 0x4a02621a, 0x00000500, - 0x0401f00c, 0x4a02621a, 0x00000700, 0x0401f009, - 0x4a02621a, 0x00000900, 0x0401f006, 0x4a02621a, - 0x00000f00, 0x0401f003, 0x4a02621a, 0x00002d00, - 0x82000540, 0x00000001, 0x0401f002, 0x80000580, - 0x5c000800, 0x1c01f000, 0x59cc0407, 0x4803c857, - 0x82000580, 0x00000800, 0x04000003, 0x4a02621a, - 0x00000000, 0x1c01f000, 0x4933c857, 0x4c580000, - 0x59cc000c, 0x59340802, 0x82040d00, 0x00ffffff, - 0x80040580, 0x04020012, 0x83cc1400, 0x00000008, + 0x4933c857, 0x493bc857, 0x83380580, 0x00000013, + 0x0402000e, 0x59300403, 0x82000c80, 0x00000085, + 0x02001800, 0x001005d8, 0x82000c80, 0x00000093, + 0x02021800, 0x001005d8, 0x82000480, 0x00000085, + 0x4803c857, 0x0c01f018, 0x83380580, 0x00000027, + 0x04000005, 0x83380580, 0x00000014, 0x02020000, + 0x00107974, 0x0201f800, 0x00106bbf, 0x59325808, + 0x812e59c0, 0x02000000, 0x00107911, 0x4a025a06, + 0x00000031, 0x4a025811, 0x00000004, 0x4a025812, + 0x000000ff, 0x0201f800, 0x000202da, 0x0201f000, + 0x00107911, 0x0010a1b7, 0x0010a1be, 0x0010a1be, + 0x0010a1b7, 0x0010a1b7, 0x0010a1b7, 0x0010a1b7, + 0x0010a1b7, 0x0010a1b7, 0x0010a1b7, 0x0010a1b7, + 0x0010a1b7, 0x0010a1b7, 0x0010a1b9, 0x0201f800, + 0x001005d8, 0x59325808, 0x4a025a06, 0x00000000, + 0x0201f800, 0x000202da, 0x0201f000, 0x00107911, + 0x4933c857, 0x42000000, 0x0010b873, 0x0201f800, + 0x0010aa47, 0x0201f800, 0x0010a5df, 0x497a6205, + 0x42028000, 0x0000000b, 0x0401f807, 0x4a026406, + 0x00000006, 0x4a026203, 0x00000007, 0x497a6206, + 0x1c01f000, 0x4933c857, 0x4943c857, 0x59300406, + 0x82000580, 0x00000007, 0x04020002, 0x1c01f000, + 0x0201f800, 0x00106c55, 0x4df00000, 0x0201f800, + 0x00108ce5, 0x82000c80, 0x0000000e, 0x02021800, + 0x001005d8, 0x0c01f001, 0x0010a205, 0x0010a209, + 0x0010a1f0, 0x0010a217, 0x0010a22a, 0x0010a1f0, + 0x0010a1f0, 0x0010a1f0, 0x0010a1f0, 0x0010a1f0, + 0x0010a1f0, 0x0010a1f0, 0x0010a1f0, 0x0010a1f0, + 0x4d400000, 0x5930001f, 0x80000540, 0x04000005, + 0x41400800, 0x0201f800, 0x00100d7c, 0x40068000, + 0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037, + 0x040209f3, 0x4c5c0000, 0x5930b809, 0x0201f800, + 0x00107911, 0x485e6009, 0x5c00b800, 0x5c025800, + 0x5c028000, 0x5c03e000, 0x02000000, 0x00106c4b, + 0x1c01f000, 0x598c000d, 0x81300580, 0x04020004, + 0x0201f800, 0x00106e8e, 0x04020016, 0x0201f800, + 0x001068d3, 0x040007df, 0x0201f800, 0x00106b6c, + 0x04000010, 0x0201f800, 0x001005d8, 0x0201f800, + 0x00108cd6, 0x04020004, 0x0201f800, 0x00106e62, + 0x04020008, 0x0201f800, 0x001067ae, 0x040007d1, + 0x0201f800, 0x00106b6c, 0x02020800, 0x001005d8, + 0x59300203, 0x82000c80, 0x0000000e, 0x02021800, + 0x001005d8, 0x0c01f7b9, 0x0201f800, 0x00100e99, + 0x0401f7c4, 0x4933c857, 0x4d440000, 0x4d340000, + 0x59cc0007, 0x0201f800, 0x00105c9a, 0x02000800, + 0x00020245, 0x0402001a, 0x59300009, 0x4c000000, + 0x49366009, 0x42003000, 0x0000000b, 0x0201f800, + 0x0010a942, 0x42000000, 0x0010b861, 0x0201f800, + 0x0010aa47, 0x4d3c0000, 0x4d400000, 0x42028000, + 0x00000029, 0x417a7800, 0x0201f800, 0x0010203c, + 0x5c028000, 0x5c027800, 0x5c000000, 0x48026009, + 0x59cc0007, 0x48026802, 0x80000580, 0x5c026800, + 0x5c028800, 0x1c01f000, 0x4933c857, 0x4c040000, + 0x59a80016, 0x82000580, 0x00000074, 0x04020040, + 0x59cc0a08, 0x82040480, 0x00000100, 0x04001033, + 0x59cc0c08, 0x82040500, 0x00008000, 0x04000035, + 0x59a80032, 0x80000540, 0x04020009, 0x59301009, + 0x58080212, 0x82000500, 0x0000ff00, 0x04000004, + 0x82040500, 0x00000800, 0x0400002a, 0x59cc0c09, + 0x80040840, 0x04001024, 0x59a80826, 0x8c040d06, + 0x04000004, 0x59cc0c0f, 0x8c040d1e, 0x04020012, + 0x59cc0a17, 0x800409c0, 0x04020012, 0x59cc0a18, + 0x82040480, 0x00000100, 0x04001014, 0x59cc0c18, + 0x800409c0, 0x0402000e, 0x59cc0c19, 0x80040840, + 0x04001011, 0x59cc0c1a, 0x80040840, 0x04001011, + 0x0401f018, 0x4a02621a, 0x00000100, 0x0401f012, + 0x4a02621a, 0x00000300, 0x0401f00f, 0x4a02621a, + 0x00000500, 0x0401f00c, 0x4a02621a, 0x00000700, + 0x0401f009, 0x4a02621a, 0x00000900, 0x0401f006, + 0x4a02621a, 0x00000f00, 0x0401f003, 0x4a02621a, + 0x00002d00, 0x82000540, 0x00000001, 0x0401f002, + 0x80000580, 0x5c000800, 0x1c01f000, 0x59cc0407, + 0x4803c857, 0x82000580, 0x00000800, 0x04000003, + 0x4a02621a, 0x00000000, 0x1c01f000, 0x4933c857, + 0x4c040000, 0x4c080000, 0x4c0c0000, 0x4c580000, + 0x59cc000c, 0x0201f800, 0x00105c9a, 0x02000800, + 0x00020245, 0x04020012, 0x83cc1400, 0x00000008, 0x4200b000, 0x00000002, 0x83341c00, 0x00000006, - 0x0201f800, 0x001082ff, 0x04020009, 0x83cc1400, + 0x0201f800, 0x0010855a, 0x04020009, 0x83cc1400, 0x0000000a, 0x4200b000, 0x00000002, 0x83341c00, - 0x00000008, 0x0201f800, 0x001082ff, 0x5c00b000, - 0x1c01f000, 0x4933c857, 0x4c580000, 0x83cc1400, - 0x0000000b, 0x4200b000, 0x00000002, 0x83341c00, - 0x00000006, 0x0201f800, 0x001082ff, 0x0402000c, - 0x83cc1400, 0x0000000d, 0x4200b000, 0x00000002, - 0x83341c00, 0x00000008, 0x0201f800, 0x001082ff, - 0x04000014, 0x4933c856, 0x4933c856, 0x4933c857, - 0x59340009, 0x4803c857, 0x5934000e, 0x4803c857, - 0x59340008, 0x4803c857, 0x5934000d, 0x4803c857, - 0x59340007, 0x4803c857, 0x5934000c, 0x4803c857, - 0x59340006, 0x4803c857, 0x5934000b, 0x4803c857, - 0x5c00b000, 0x1c01f000, 0x4933c857, 0x4947c857, - 0x4943c857, 0x4c600000, 0x0201f800, 0x0010698c, - 0x4df00000, 0x4d2c0000, 0x4d300000, 0x4d340000, - 0x0401f8d8, 0x4130c000, 0x42026000, 0x0010cfc0, + 0x00000008, 0x0201f800, 0x0010855a, 0x5c00b000, + 0x5c001800, 0x5c001000, 0x5c000800, 0x1c01f000, + 0x4933c857, 0x4c000000, 0x4c040000, 0x4c080000, + 0x4c0c0000, 0x4c580000, 0x59cc0001, 0x0201f800, + 0x00105c9a, 0x02000800, 0x00020245, 0x04020014, + 0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002, + 0x83341c00, 0x00000006, 0x0201f800, 0x0010855a, + 0x0402000c, 0x83cc1400, 0x0000000d, 0x4200b000, + 0x00000002, 0x83341c00, 0x00000008, 0x0201f800, + 0x0010855a, 0x04000014, 0x4933c856, 0x4933c856, + 0x4933c857, 0x59340009, 0x4803c857, 0x5934000e, + 0x4803c857, 0x59340008, 0x4803c857, 0x5934000d, + 0x4803c857, 0x59340007, 0x4803c857, 0x5934000c, + 0x4803c857, 0x59340006, 0x4803c857, 0x5934000b, + 0x4803c857, 0x5c00b000, 0x5c001800, 0x5c001000, + 0x5c000800, 0x5c000000, 0x1c01f000, 0x4933c857, + 0x4947c857, 0x4943c857, 0x4c600000, 0x0201f800, + 0x00106c55, 0x4df00000, 0x4d2c0000, 0x4d300000, + 0x4d340000, 0x4130c000, 0x42026000, 0x0010d1c0, 0x59a8000e, 0x8060c1c0, 0x04000005, 0x82601580, - 0x0010bbe8, 0x04000002, 0x80000040, 0x81640480, - 0x040210c4, 0x40600000, 0x81300580, 0x040000bc, - 0x0401f9bc, 0x040200ba, 0x59326809, 0x59300406, - 0x82000c80, 0x00000012, 0x02021800, 0x00100615, - 0x0c01f001, 0x0010a1af, 0x0010a118, 0x0010a133, - 0x0010a13e, 0x0010a111, 0x0010a12c, 0x0010a169, - 0x0010a1af, 0x0010a10f, 0x0010a17c, 0x0010a190, - 0x0010a10f, 0x0010a10f, 0x0010a10f, 0x0010a10f, - 0x0010a1af, 0x0010a1a6, 0x0010a19e, 0x0201f800, - 0x00100615, 0x8d3e7d18, 0x04000003, 0x8d3e7d16, - 0x04000004, 0x59300420, 0x8c000500, 0x04020098, - 0x59300403, 0x82000580, 0x00000043, 0x04000094, - 0x0201f800, 0x00108ef1, 0x04000007, 0x0201f800, - 0x00108f05, 0x0402008c, 0x0201f800, 0x00107da6, - 0x0401f089, 0x0201f800, 0x00101e1b, 0x0201f800, - 0x00108f05, 0x02000800, 0x00107da6, 0x0401f082, - 0x8d3e7d18, 0x04000003, 0x8d3e7d16, 0x04000004, - 0x59300420, 0x8c000500, 0x0402007d, 0x59325808, - 0x0201f800, 0x00108df4, 0x04000077, 0x49425a06, - 0x497a5c09, 0x0201f800, 0x00020381, 0x0201f800, - 0x00108ee7, 0x0401f070, 0x8d3e7d00, 0x04000007, - 0x59300017, 0x81480580, 0x0402006d, 0x59300018, - 0x814c0580, 0x0402006a, 0x59300203, 0x82000580, - 0x00000004, 0x02000800, 0x00100ee4, 0x59325808, - 0x0201f800, 0x00108df4, 0x0400005f, 0x4a025a04, - 0x00000103, 0x59300004, 0x8400055c, 0x48026004, - 0x592c0408, 0x8c000512, 0x04000007, 0x4d2c0000, - 0x592c0009, 0x40025800, 0x0201f800, 0x00100843, - 0x5c025800, 0x49425a06, 0x497a5c09, 0x0401fb4f, - 0x0201f800, 0x00109365, 0x0201f800, 0x00108f7d, - 0x0201f800, 0x00020381, 0x0201f800, 0x00108ee7, - 0x0401f045, 0x8d3e7d18, 0x04000045, 0x59300203, - 0x82000580, 0x00000004, 0x02000800, 0x00100ee4, - 0x59325808, 0x0201f800, 0x00108df4, 0x0400003a, - 0x49425a06, 0x497a5c09, 0x0401fb38, 0x0201f800, - 0x00109365, 0x0201f800, 0x00020381, 0x0401f032, - 0x0201f800, 0x0010600e, 0x04000031, 0x59300203, - 0x82000580, 0x00000004, 0x0400002d, 0x59300203, - 0x82000580, 0x00000003, 0x04020029, 0x0201f800, - 0x001068c1, 0x59325808, 0x0201f800, 0x00108df4, - 0x04000021, 0x0201f800, 0x00020381, 0x0401f01e, + 0x0010bde9, 0x04000002, 0x80000040, 0x81640480, + 0x040210be, 0x40600000, 0x81300580, 0x040000b6, + 0x0401f97a, 0x040200b4, 0x59326809, 0x59300406, + 0x82000c80, 0x00000012, 0x02021800, 0x001005d8, + 0x0c01f001, 0x0010a3cd, 0x0010a338, 0x0010a351, + 0x0010a35c, 0x0010a335, 0x0010a34c, 0x0010a387, + 0x0010a3cd, 0x0010a333, 0x0010a39a, 0x0010a3ae, + 0x0010a333, 0x0010a333, 0x0010a333, 0x0010a333, + 0x0010a3cd, 0x0010a3c4, 0x0010a3bc, 0x0201f800, + 0x001005d8, 0x59300420, 0x8c000500, 0x04020096, + 0x59300403, 0x82000580, 0x00000043, 0x04000092, + 0x0201f800, 0x00109134, 0x04000007, 0x0201f800, + 0x0010914e, 0x0402008a, 0x0201f800, 0x0010801c, + 0x0401f087, 0x0201f800, 0x00102074, 0x0201f800, + 0x0010914e, 0x02000800, 0x0010801c, 0x0401f080, + 0x8d3e7d18, 0x04000004, 0x59300420, 0x8c000500, + 0x0402007d, 0x59325808, 0x0201f800, 0x00109037, + 0x04000077, 0x49425a06, 0x497a5c09, 0x0201f800, + 0x000202da, 0x0201f800, 0x0010912a, 0x0401f070, + 0x8d3e7d00, 0x04000007, 0x59300017, 0x81480580, + 0x0402006d, 0x59300018, 0x814c0580, 0x0402006a, 0x59300203, 0x82000580, 0x00000004, 0x02000800, - 0x00100ee4, 0x59325808, 0x0201f800, 0x00108df4, - 0x04000015, 0x49425a06, 0x497a5c09, 0x0201f800, - 0x00020381, 0x0401f010, 0x833c0500, 0x00001800, - 0x0400000f, 0x8d3e7d16, 0x0402000d, 0x59325817, - 0x0201f800, 0x00100843, 0x59325808, 0x0201f800, - 0x00108df4, 0x04000004, 0x49425a06, 0x0201f800, - 0x00020381, 0x0201f800, 0x00107698, 0x83326400, - 0x00000024, 0x41580000, 0x81300480, 0x04001735, - 0x5c026800, 0x5c026000, 0x5c025800, 0x5c03e000, - 0x02000800, 0x00106982, 0x5c00c000, 0x1c01f000, - 0x4933c857, 0x813261c0, 0x0400002d, 0x83300d80, - 0x0010bbe8, 0x0400002a, 0x8d3e7d06, 0x04020028, - 0x59300c06, 0x82040580, 0x00000001, 0x0400000a, - 0x82040580, 0x00000002, 0x04020021, 0x5930021d, - 0x82000580, 0x00000001, 0x0402001d, 0x59300c16, - 0x0401f002, 0x59300c03, 0x82040580, 0x00000039, - 0x04000004, 0x82040580, 0x00000035, 0x04020014, - 0x4d300000, 0x4d1c0000, 0x5932601e, 0x4933c857, - 0x0201f800, 0x001091e3, 0x02000800, 0x00100615, - 0x591c001c, 0x497a381c, 0x591c0c14, 0x84040d02, - 0x48063c14, 0x5c023800, 0x5c026000, 0x81300580, - 0x02020800, 0x00100615, 0x497a601e, 0x1c01f000, - 0x5c000000, 0x4c000000, 0x4803c857, 0x4d3c0000, - 0x42027800, 0x00000001, 0x0201f800, 0x001043bd, - 0x5c027800, 0x4c580000, 0x4200b000, 0x00000002, - 0x83a81c00, 0x00000002, 0x83cc1400, 0x0000000b, - 0x0201f800, 0x001082ff, 0x5c00b000, 0x80000540, - 0x1c01f000, 0x492fc857, 0x4943c857, 0x59a8000c, - 0x812c0480, 0x04001011, 0x59a8000d, 0x812c0480, - 0x0402100e, 0x592c0000, 0x80005d40, 0x04000008, - 0x497a5800, 0x49425a06, 0x4c2c0000, 0x0201f800, - 0x00020381, 0x5c025800, 0x0401f7f7, 0x49425a06, - 0x0201f000, 0x00020381, 0x1c01f000, 0x493fc857, - 0x4933c857, 0x480bc857, 0x0201f800, 0x0010393e, - 0x0400002e, 0x41502800, 0x813e79c0, 0x04020006, - 0x59a80066, 0x80000000, 0x59a8086a, 0x80040580, - 0x04000026, 0x41300000, 0x80140580, 0x0400001a, - 0x58140203, 0x82000580, 0x00000000, 0x04000016, - 0x58140202, 0x80080580, 0x04020013, 0x58141c06, - 0x820c0580, 0x00000005, 0x0400000f, 0x820c0580, - 0x00000009, 0x04000017, 0x59300009, 0x58142009, - 0x801021c0, 0x04020006, 0x5814201e, 0x59301809, - 0x580c0002, 0x82000500, 0x00ffffff, 0x80100580, - 0x04000007, 0x82142c00, 0x00000024, 0x41540000, - 0x80140480, 0x04021005, 0x0401f7df, 0x40163800, - 0x81300540, 0x0401f002, 0x80000580, 0x1c01f000, - 0x58141807, 0x8c0c1d10, 0x040207f3, 0x0401f7e7, - 0x42002000, 0x0000ffff, 0x59301009, 0x800811c0, - 0x04000002, 0x58082403, 0x41301000, 0x0401f007, - 0x41781000, 0x41442000, 0x0401f004, 0x41781000, - 0x42002000, 0x0000ffff, 0x5c000000, 0x4c000000, - 0x4803c857, 0x480bc857, 0x4813c857, 0x492fc857, - 0x4943c857, 0x4d2c0000, 0x4c080000, 0x4c100000, - 0x4c140000, 0x4c180000, 0x0201f800, 0x0010082a, - 0x02000800, 0x00100615, 0x5c003000, 0x5c002800, - 0x5c002000, 0x5c001000, 0x4a025a04, 0x0000010d, - 0x800811c0, 0x04000017, 0x83400580, 0x00000029, - 0x04020010, 0x82180580, 0x00000002, 0x0400000a, - 0x82180580, 0x00000003, 0x04000007, 0x82180580, - 0x00000008, 0x04000004, 0x82180580, 0x00000009, - 0x04020004, 0x4a025809, 0xffffffff, 0x0401f002, - 0x480a5809, 0x58080202, 0x48025c13, 0x0401f005, - 0x4a025809, 0xffffffff, 0x4a025c13, 0x0000ffff, - 0x49425a08, 0x48125a06, 0x82100580, 0x0000ffff, - 0x04000012, 0x4c140000, 0x4c180000, 0x4d440000, - 0x4d340000, 0x40128800, 0x0201f800, 0x00020267, - 0x02020800, 0x00100615, 0x59340002, 0x82000500, + 0x00100e99, 0x59325808, 0x0201f800, 0x00109037, + 0x0400005f, 0x4a025a04, 0x00000103, 0x59300004, + 0x8400055c, 0x48026004, 0x592c0408, 0x8c000512, + 0x04000007, 0x4d2c0000, 0x592c0009, 0x40025800, + 0x0201f800, 0x001007fd, 0x5c025800, 0x49425a06, + 0x497a5c09, 0x0401fb16, 0x0201f800, 0x0010959c, + 0x0201f800, 0x001091c6, 0x0201f800, 0x000202da, + 0x0201f800, 0x0010912a, 0x0401f045, 0x8d3e7d18, + 0x04000045, 0x59300203, 0x82000580, 0x00000004, + 0x02000800, 0x00100e99, 0x59325808, 0x0201f800, + 0x00109037, 0x0400003a, 0x49425a06, 0x497a5c09, + 0x0401faff, 0x0201f800, 0x0010959c, 0x0201f800, + 0x000202da, 0x0401f032, 0x0201f800, 0x001062d5, + 0x04000031, 0x59300203, 0x82000580, 0x00000004, + 0x0400002d, 0x59300203, 0x82000580, 0x00000003, + 0x04020029, 0x0201f800, 0x00106b8a, 0x59325808, + 0x0201f800, 0x00109037, 0x04000021, 0x0201f800, + 0x000202da, 0x0401f01e, 0x59300203, 0x82000580, + 0x00000004, 0x02000800, 0x00100e99, 0x59325808, + 0x0201f800, 0x00109037, 0x04000015, 0x49425a06, + 0x497a5c09, 0x0201f800, 0x000202da, 0x0401f010, + 0x833c0500, 0x00001800, 0x0400000f, 0x8d3e7d16, + 0x0402000d, 0x59325817, 0x0201f800, 0x001007fd, + 0x59325808, 0x0201f800, 0x00109037, 0x04000004, + 0x49425a06, 0x0201f800, 0x000202da, 0x0201f800, + 0x00107911, 0x83326400, 0x00000024, 0x41580000, + 0x81300480, 0x0400173b, 0x5c026800, 0x5c026000, + 0x5c025800, 0x5c03e000, 0x02000800, 0x00106c4b, + 0x5c00c000, 0x1c01f000, 0x5c000000, 0x4c000000, + 0x4803c857, 0x4d3c0000, 0x42027800, 0x00000001, + 0x0201f800, 0x00104567, 0x5c027800, 0x4c580000, + 0x4200b000, 0x00000002, 0x83a81c00, 0x00000002, + 0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a, + 0x5c00b000, 0x80000540, 0x1c01f000, 0x492fc857, + 0x4943c857, 0x59a8000c, 0x812c0480, 0x04001011, + 0x59a8000d, 0x812c0480, 0x0402100e, 0x592c0000, + 0x80005d40, 0x04000008, 0x497a5800, 0x49425a06, + 0x4c2c0000, 0x0201f800, 0x000202da, 0x5c025800, + 0x0401f7f7, 0x49425a06, 0x0201f000, 0x000202da, + 0x1c01f000, 0x493fc857, 0x4933c857, 0x480bc857, + 0x0201f800, 0x00103b25, 0x0400002e, 0x41502800, + 0x813e79c0, 0x04020006, 0x59a80066, 0x80000000, + 0x59a8086a, 0x80040580, 0x04000026, 0x41300000, + 0x80140580, 0x0400001a, 0x58140203, 0x82000580, + 0x00000000, 0x04000016, 0x58140202, 0x80080580, + 0x04020013, 0x58141c06, 0x820c0580, 0x00000005, + 0x0400000f, 0x820c0580, 0x00000009, 0x04000017, + 0x59300009, 0x58142009, 0x801021c0, 0x04020006, + 0x5814201e, 0x59301809, 0x580c0002, 0x82000500, + 0x00ffffff, 0x80100580, 0x04000007, 0x82142c00, + 0x00000024, 0x41540000, 0x80140480, 0x04021005, + 0x0401f7df, 0x40163800, 0x81300540, 0x0401f002, + 0x80000580, 0x1c01f000, 0x58141807, 0x8c0c1d10, + 0x040207f3, 0x0401f7e7, 0x42002000, 0x0000ffff, + 0x59301009, 0x800811c0, 0x04000002, 0x58082403, + 0x41301000, 0x0401f007, 0x41781000, 0x41442000, + 0x0401f004, 0x41781000, 0x42002000, 0x0000ffff, + 0x5c000000, 0x4c000000, 0x4803c857, 0x480bc857, + 0x4813c857, 0x492fc857, 0x4943c857, 0x4d2c0000, + 0x0201f800, 0x001007e4, 0x02000800, 0x001005d8, + 0x4a025a04, 0x0000010d, 0x800811c0, 0x04000017, + 0x83400580, 0x00000029, 0x04020010, 0x82180580, + 0x00000002, 0x0400000a, 0x82180580, 0x00000003, + 0x04000007, 0x82180580, 0x00000008, 0x04000004, + 0x82180580, 0x00000009, 0x04020004, 0x4a025809, + 0xffffffff, 0x0401f002, 0x480a5809, 0x58080202, + 0x48025c13, 0x0401f005, 0x4a025809, 0xffffffff, + 0x4a025c13, 0x0000ffff, 0x49425a08, 0x48125a06, + 0x82100580, 0x0000ffff, 0x0400000e, 0x4d440000, + 0x4d340000, 0x40128800, 0x0201f800, 0x00020245, + 0x02020800, 0x001005d8, 0x59340002, 0x82000500, 0x00ffffff, 0x48025812, 0x5c026800, 0x5c028800, - 0x5c003000, 0x5c002800, 0x497a5800, 0x497a5c04, - 0x83400580, 0x00000046, 0x04020002, 0x48165a07, - 0x481a5c08, 0x0401fbe0, 0x5c025800, 0x1c01f000, - 0x59300809, 0x800409c0, 0x04000004, 0x58040403, - 0x81440580, 0x1c01f000, 0x82000540, 0x00000001, - 0x0401f7fd, 0x4933c857, 0x4c040000, 0x59300403, - 0x82000d80, 0x0000001e, 0x04020016, 0x800000d0, - 0x59300a16, 0x82040d00, 0x000000ff, 0x80040540, - 0x4803c857, 0x48026416, 0x4a026403, 0x00000085, - 0x4a026203, 0x00000009, 0x4a026406, 0x00000005, - 0x4a02621d, 0x00000004, 0x59a80038, 0x48026206, - 0x42000800, 0x8000004b, 0x0201f800, 0x00020855, - 0x5c000800, 0x1c01f000, 0x4933c857, 0x40000000, - 0x40000000, 0x1c01f000, 0x59300414, 0x4933c857, - 0x4803c857, 0x8c000518, 0x04000009, 0x8c000512, - 0x02020000, 0x00108fdb, 0x0401f918, 0x0201f800, - 0x00020831, 0x0201f800, 0x000208b4, 0x1c01f000, - 0x591c0406, 0x4803c857, 0x82000c80, 0x00000009, - 0x0402100b, 0x0c01f001, 0x0010a2f7, 0x0010a2f7, - 0x0010a2f7, 0x0010a2f9, 0x0010a2f7, 0x0010a2f9, - 0x0010a2f9, 0x0010a2f7, 0x0010a2f9, 0x80000580, - 0x1c01f000, 0x82000540, 0x00000001, 0x1c01f000, - 0x591c0406, 0x82000500, 0x0000001f, 0x82000580, - 0x00000006, 0x0400000e, 0x4803c857, 0x4a026403, - 0x0000003b, 0x4a02641a, 0x00000009, 0x4a02621a, - 0x00002a00, 0x4a026203, 0x00000001, 0x42000800, - 0x80000040, 0x0201f000, 0x00020855, 0x4803c856, - 0x4c040000, 0x4c140000, 0x4d300000, 0x411e6000, - 0x0401f8e6, 0x497a6205, 0x59300414, 0x4803c857, - 0x82000500, 0xffffadff, 0x48026414, 0x497a6405, - 0x5c026000, 0x0201f800, 0x0010082a, 0x02000800, - 0x00100615, 0x5c002800, 0x5c000800, 0x4a025a04, - 0x0000010d, 0x497a5800, 0x497a5c04, 0x4a025a08, - 0x00000045, 0x491e5809, 0x59300402, 0x48025c07, - 0x59300419, 0x48025c0b, 0x591c0414, 0x84000556, - 0x48023c14, 0x591c1809, 0x580c0403, 0x48025a06, - 0x4816580a, 0x48065a0b, 0x0401fb57, 0x4d400000, - 0x42028000, 0x00000045, 0x591c0202, 0x4c000000, - 0x4d300000, 0x411e6000, 0x0401fc82, 0x5c026000, - 0x5c000000, 0x48023a02, 0x5c028000, 0x4a023c06, - 0x00000006, 0x4a023a03, 0x00000007, 0x497a3a06, - 0x497a3a05, 0x1c01f000, 0x4933c857, 0x83380580, - 0x00000013, 0x0402000b, 0x59300403, 0x4803c857, - 0x82000d80, 0x00000085, 0x0400002b, 0x82000d80, - 0x0000008b, 0x04000028, 0x0201f800, 0x00100615, - 0x83380580, 0x00000027, 0x0402000c, 0x0201f800, - 0x001068f6, 0x4d2c0000, 0x4d400000, 0x59325808, - 0x42028000, 0x00000004, 0x0401fe9f, 0x5c028000, - 0x5c025800, 0x1c01f000, 0x83380580, 0x00000014, - 0x040007f3, 0x83380580, 0x00000089, 0x04000005, - 0x83380580, 0x0000008a, 0x02020000, 0x001076fb, - 0x0201f800, 0x00106cb4, 0x02020000, 0x001076fb, - 0x59300a03, 0x82040580, 0x0000000a, 0x04000009, - 0x82040580, 0x0000000c, 0x04000006, 0x0201f800, - 0x00100615, 0x4a026203, 0x0000000a, 0x1c01f000, - 0x83380480, 0x00000093, 0x0402100c, 0x83380480, - 0x00000085, 0x04001009, 0x83380580, 0x00000089, - 0x0400000a, 0x83380580, 0x0000008a, 0x04000022, - 0x0201f800, 0x00100615, 0x493bc857, 0x4933c857, - 0x0201f000, 0x001076fb, 0x4933c857, 0x4c340000, - 0x41306800, 0x0201f800, 0x00020892, 0x04000011, - 0x4a026203, 0x00000001, 0x4a026403, 0x0000001e, - 0x59cc0c07, 0x48066419, 0x59cc0a07, 0x48066219, - 0x58340809, 0x48066009, 0x4a026406, 0x00000004, - 0x42000800, 0x80000040, 0x0201f800, 0x00020855, - 0x40366000, 0x0201f800, 0x000208b4, 0x5c006800, - 0x1c01f000, 0x4933c857, 0x0201f000, 0x000208b4, - 0x59300809, 0x58040200, 0x8c00051a, 0x02020800, - 0x001006ba, 0x1c01f000, 0x0201f800, 0x0010472e, - 0x0400001e, 0x4a026203, 0x00000002, 0x59300414, - 0x84000558, 0x48026414, 0x8c000512, 0x04000004, - 0x59a80039, 0x48026205, 0x0401f007, 0x59a80839, - 0x59a80037, 0x80040400, 0x82000400, 0x0000001e, - 0x48026205, 0x59300009, 0x82000c00, 0x00000011, - 0x50040000, 0x80000540, 0x04000004, 0x82000c00, - 0x00000000, 0x0401f7fb, 0x45300800, 0x497a6000, - 0x82000540, 0x00000001, 0x1c01f000, 0x82100500, - 0xfffffeef, 0x0402001c, 0x4d2c0000, 0x4937c857, - 0x59340811, 0x83341400, 0x00000011, 0x800409c0, - 0x0400000e, 0x40040000, 0x81300580, 0x04000005, - 0x58040800, 0x82041400, 0x00000000, 0x0401f7f8, - 0x59300800, 0x497a6000, 0x44041000, 0x0201f800, - 0x00020831, 0x0401f002, 0x4933c857, 0x5c025800, - 0x492e6008, 0x0201f800, 0x00020831, 0x0201f000, - 0x000208b4, 0x492fc857, 0x4a025a06, 0x00000006, - 0x0201f000, 0x00020381, 0x4c340000, 0x59300009, - 0x800001c0, 0x04000010, 0x82006c00, 0x00000011, - 0x50340000, 0x80000540, 0x04000009, 0x81300580, - 0x04000005, 0x50340000, 0x82006c00, 0x00000000, - 0x0401f7f8, 0x59300000, 0x44006800, 0x5c006800, - 0x1c01f000, 0x59300c06, 0x82040580, 0x00000005, - 0x040007fb, 0x82040580, 0x00000011, 0x040007f8, - 0x82040580, 0x00000006, 0x040007f5, 0x82040580, - 0x00000001, 0x040007f2, 0x0201f800, 0x00100615, - 0x4933c857, 0x4c080000, 0x4c0c0000, 0x4c580000, - 0x59a8101d, 0x59cc1807, 0x820c1d00, 0x00ffffff, - 0x800c0110, 0x80083580, 0x04020014, 0x83cc1400, - 0x00000008, 0x4200b000, 0x00000002, 0x59300009, - 0x82001c00, 0x00000006, 0x0201f800, 0x001082ff, - 0x0402000a, 0x83cc1400, 0x0000000a, 0x4200b000, - 0x00000002, 0x59300009, 0x82001c00, 0x00000008, - 0x0201f800, 0x001082ff, 0x5c00b000, 0x5c001800, - 0x5c001000, 0x1c01f000, 0x4933c856, 0x0201f800, - 0x0010404b, 0x0201f000, 0x00101bf0, 0x493bc857, - 0x4d2c0000, 0x0201f800, 0x0010082a, 0x02000800, - 0x00100615, 0x832cac00, 0x00000005, 0x4c580000, - 0x4c540000, 0x4200b000, 0x00000006, 0x4578a800, - 0x8054a800, 0x8058b040, 0x040207fd, 0x83380580, - 0x00000046, 0x04020004, 0x4a025a04, 0x00000144, - 0x0401f008, 0x4a025a04, 0x00000146, 0x83380580, - 0x00000041, 0x04000003, 0x4a025a06, 0x00000001, - 0x59cc0007, 0x82000500, 0xff000000, 0x80000110, - 0x59cc1008, 0x82081500, 0xff000000, 0x80081540, - 0x480a580a, 0x83380580, 0x00000046, 0x04020006, - 0x59cc0007, 0x82000500, 0x00ffffff, 0x4802580b, - 0x0401f005, 0x59cc0008, 0x82000500, 0x00ffffff, - 0x4802580b, 0x83380580, 0x00000046, 0x04020004, - 0x83cc1400, 0x00000009, 0x0401f003, 0x83cc1400, - 0x0000000d, 0x50080000, 0x9c0001c0, 0x4802580c, - 0x80081000, 0x50080000, 0x9c0001c0, 0x4802580d, - 0x83380580, 0x00000046, 0x04020008, 0x59cc000b, - 0x9c0001c0, 0x4802580e, 0x59cc000c, 0x9c0001c0, - 0x4802580f, 0x0401f007, 0x59cc000f, 0x9c0001c0, - 0x4802580e, 0x59cc0010, 0x9c0001c0, 0x4802580f, - 0x83380580, 0x00000046, 0x04020004, 0x83cc1400, - 0x00000011, 0x0401f003, 0x83cc1400, 0x00000015, - 0x412c3000, 0x82183400, 0x00000010, 0x4200b000, - 0x00000004, 0x50080000, 0x9c0001c0, 0x44003000, - 0x80081000, 0x80183000, 0x8058b040, 0x040207fa, - 0x5c00a800, 0x5c00b000, 0x0201f800, 0x00020381, - 0x5c025800, 0x1c01f000, 0x4933c857, 0x492fc857, - 0x59300809, 0x58040200, 0x8c00051e, 0x04000004, - 0x592c0208, 0x84000558, 0x48025a08, 0x1c01f000, - 0x59e0180f, 0x599c0413, 0x800c1000, 0x80080580, - 0x04020002, 0x41781000, 0x59e00010, 0x59e00810, - 0x80040d80, 0x040207fd, 0x80080580, 0x0400000b, - 0x4c080000, 0x599c0814, 0x599c1015, 0x800c00cc, - 0x80040c00, 0x82081440, 0x00000000, 0x5c001800, - 0x82000540, 0x00000001, 0x4803c857, 0x1c01f000, - 0x59300203, 0x4933c857, 0x4937c857, 0x493bc857, - 0x4803c857, 0x82003480, 0x0000000e, 0x02021800, - 0x00100615, 0x0c01f001, 0x0010a4e8, 0x0010a63a, - 0x0010a4e8, 0x0010a4e8, 0x0010a4e8, 0x0010a4e8, - 0x0010a4e8, 0x0010a59f, 0x0010a4ea, 0x0010a4e8, - 0x0010a4e8, 0x0010a4e8, 0x0010a4e8, 0x0010a4e8, - 0x0201f800, 0x00100615, 0x83380580, 0x0000004c, - 0x02020800, 0x00100615, 0x0201f800, 0x0010473b, - 0x04020020, 0x59a80826, 0x82040500, 0x00000009, - 0x82000580, 0x00000008, 0x0400001a, 0x8c040d12, - 0x0400003d, 0x59cc0806, 0x82040d00, 0xff000000, - 0x82040580, 0x03000000, 0x0400001f, 0x82040580, - 0x50000000, 0x04000005, 0x82040580, 0x52000000, - 0x02020000, 0x000208b4, 0x813669c0, 0x04000006, - 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, - 0x5c027800, 0x4a026403, 0x00000001, 0x0401f014, - 0x59cc0806, 0x82040d00, 0xff000000, 0x82040580, - 0x03000000, 0x04000008, 0x82040580, 0x50000000, - 0x04000005, 0x82040580, 0x52000000, 0x02020000, - 0x000208b4, 0x4a026403, 0x00000009, 0x4a02641a, - 0x00000009, 0x4a02621a, 0x00000000, 0x813669c0, - 0x0402000b, 0x59cc0001, 0x0201f800, 0x001059b9, - 0x02020000, 0x000208b4, 0x0201f800, 0x001043fc, - 0x02020000, 0x000208b4, 0x49366009, 0x4a026406, - 0x00000004, 0x4a026203, 0x00000001, 0x0201f000, - 0x00106470, 0x0201f800, 0x0010393e, 0x04000023, - 0x59cc0806, 0x4807c857, 0x82040d00, 0xff000000, - 0x82040580, 0x03000000, 0x04000033, 0x82040580, - 0x20000000, 0x04000041, 0x82040580, 0x21000000, - 0x04000052, 0x82040580, 0x24000000, 0x0400004f, - 0x82040580, 0x50000000, 0x0400004c, 0x82040580, - 0x52000000, 0x04000049, 0x82040580, 0x05000000, - 0x0402000d, 0x59cc0806, 0x82040d00, 0xff000000, - 0x9c0431c0, 0x42028000, 0x00000046, 0x42002800, - 0x00000001, 0x0401fcf7, 0x0401f940, 0x02000800, - 0x00100615, 0x42002000, 0x00000051, 0x0201f800, - 0x001077d1, 0x59cc0000, 0x82000500, 0x00ffffff, - 0x82000580, 0x00ffffff, 0x04000005, 0x4a026203, - 0x00000007, 0x493a6403, 0x1c01f000, 0x59325817, - 0x812e59c0, 0x02020800, 0x00100843, 0x0201f000, - 0x000208b4, 0x813669c0, 0x040007df, 0x59340400, - 0x82000500, 0x000000ff, 0x82000580, 0x00000003, - 0x040207d9, 0x0401fc73, 0x040207d7, 0x4a026403, - 0x00000009, 0x4a02641a, 0x0000000e, 0x4a02621a, - 0x00001900, 0x0401f7a2, 0x813669c0, 0x0400000c, - 0x59340c00, 0x82040500, 0x000000ff, 0x82000580, - 0x00000009, 0x04000794, 0x82040500, 0x0000ff00, - 0x82000580, 0x00000700, 0x040207c3, 0x4a026403, + 0x497a5800, 0x497a5c04, 0x83400580, 0x00000046, + 0x04020002, 0x48165a07, 0x481a5c08, 0x0401fbed, + 0x5c025800, 0x1c01f000, 0x59300809, 0x800409c0, + 0x04000004, 0x58040403, 0x81440580, 0x1c01f000, + 0x82000540, 0x00000001, 0x0401f7fd, 0x4933c857, + 0x4c040000, 0x59300403, 0x82000d80, 0x0000001e, + 0x04020016, 0x800000d0, 0x59300a16, 0x82040d00, + 0x000000ff, 0x80040540, 0x4803c857, 0x48026416, + 0x4a026403, 0x00000085, 0x4a026203, 0x00000009, + 0x4a026406, 0x00000005, 0x4a02621d, 0x00000004, + 0x59a80038, 0x48026206, 0x42000800, 0x8000004b, + 0x0201f800, 0x00020721, 0x5c000800, 0x1c01f000, + 0x4933c857, 0x40000000, 0x40000000, 0x1c01f000, + 0x59300414, 0x4933c857, 0x4803c857, 0x8c000518, + 0x04000009, 0x8c000512, 0x02020000, 0x0010921e, + 0x0401f91b, 0x0201f800, 0x000206fd, 0x0201f800, + 0x0002077d, 0x1c01f000, 0x591c0406, 0x4803c857, + 0x82000c80, 0x00000009, 0x0402100b, 0x0c01f001, + 0x0010a4d9, 0x0010a4d9, 0x0010a4d9, 0x0010a4db, + 0x0010a4d9, 0x0010a4db, 0x0010a4db, 0x0010a4d9, + 0x0010a4db, 0x80000580, 0x1c01f000, 0x82000540, + 0x00000001, 0x1c01f000, 0x591c0406, 0x82000500, + 0x0000001f, 0x82000580, 0x00000006, 0x0400000e, + 0x4803c857, 0x4a026403, 0x0000003b, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00002a00, 0x4a026203, + 0x00000001, 0x42000800, 0x80000040, 0x0201f000, + 0x00020721, 0x4803c856, 0x4c040000, 0x4c140000, + 0x4d300000, 0x411e6000, 0x0401f8e9, 0x497a6205, + 0x59300414, 0x4803c857, 0x82000500, 0xffffadff, + 0x48026414, 0x497a6405, 0x5c026000, 0x0201f800, + 0x001007e4, 0x02000800, 0x001005d8, 0x5c002800, + 0x5c000800, 0x4a025a04, 0x0000010d, 0x497a5800, + 0x497a5c04, 0x4a025a08, 0x00000045, 0x491e5809, + 0x59300402, 0x48025c07, 0x59300419, 0x48025c0b, + 0x591c0414, 0x84000556, 0x48023c14, 0x591c1809, + 0x580c0403, 0x48025a06, 0x4816580a, 0x48065a0b, + 0x0401f99d, 0x4d400000, 0x42028000, 0x00000045, + 0x591c0202, 0x4c000000, 0x4d300000, 0x411e6000, + 0x0401fcb1, 0x5c026000, 0x5c000000, 0x48023a02, + 0x5c028000, 0x4a023c06, 0x00000006, 0x4a023a03, + 0x00000007, 0x497a3a06, 0x497a3a05, 0x1c01f000, + 0x4933c857, 0x83380580, 0x00000013, 0x0402000b, + 0x59300403, 0x4803c857, 0x82000d80, 0x00000085, + 0x0400002b, 0x82000d80, 0x0000008b, 0x04000028, + 0x0201f800, 0x001005d8, 0x83380580, 0x00000027, + 0x0402000c, 0x0201f800, 0x00106bbf, 0x4d2c0000, + 0x4d400000, 0x59325808, 0x42028000, 0x00000004, + 0x0401feab, 0x5c028000, 0x5c025800, 0x1c01f000, + 0x83380580, 0x00000014, 0x040007f3, 0x83380580, + 0x00000089, 0x04000005, 0x83380580, 0x0000008a, + 0x02020000, 0x00107974, 0x0201f800, 0x00106f60, + 0x02020000, 0x00107974, 0x59300a03, 0x82040580, + 0x0000000a, 0x04000009, 0x82040580, 0x0000000c, + 0x04000006, 0x0201f800, 0x001005d8, 0x4a026203, + 0x0000000a, 0x1c01f000, 0x83380480, 0x00000093, + 0x0402100c, 0x83380480, 0x00000085, 0x04001009, + 0x83380580, 0x00000089, 0x0400000a, 0x83380580, + 0x0000008a, 0x04000022, 0x0201f800, 0x001005d8, + 0x493bc857, 0x4933c857, 0x0201f000, 0x00107974, + 0x4933c857, 0x4c340000, 0x41306800, 0x0201f800, + 0x0002075a, 0x04000011, 0x4a026203, 0x00000001, + 0x4a026403, 0x0000001e, 0x59cc0c07, 0x48066419, + 0x59cc0a07, 0x48066219, 0x58340809, 0x48066009, + 0x4a026406, 0x00000004, 0x42000800, 0x80000040, + 0x0201f800, 0x00020721, 0x40366000, 0x0201f800, + 0x0002077d, 0x5c006800, 0x1c01f000, 0x4933c857, + 0x0201f000, 0x0002077d, 0x4933c857, 0x59300809, + 0x58040200, 0x8c00051a, 0x1c01f000, 0x0201f800, + 0x001048df, 0x0400001e, 0x4a026203, 0x00000002, + 0x59300414, 0x84000558, 0x48026414, 0x8c000512, + 0x04000004, 0x59a80039, 0x48026205, 0x0401f007, + 0x59a80839, 0x59a80037, 0x80040400, 0x82000400, + 0x0000000a, 0x48026205, 0x59300009, 0x82000c00, + 0x00000011, 0x50040000, 0x80000540, 0x04000004, + 0x82000c00, 0x00000000, 0x0401f7fb, 0x45300800, + 0x497a6000, 0x82000540, 0x00000001, 0x1c01f000, + 0x82100500, 0xfffffeef, 0x04020020, 0x4d2c0000, + 0x4937c857, 0x59340811, 0x83341400, 0x00000011, + 0x800409c0, 0x0400000e, 0x40040000, 0x81300580, + 0x04000005, 0x58040800, 0x82041400, 0x00000000, + 0x0401f7f8, 0x59300800, 0x497a6000, 0x44041000, + 0x0201f800, 0x000206fd, 0x0401f002, 0x4933c857, + 0x592c0000, 0x80000540, 0x02020800, 0x001005d8, + 0x5c025800, 0x492e6008, 0x0201f800, 0x000206fd, + 0x0201f000, 0x0002077d, 0x492fc857, 0x4a025a06, + 0x00000006, 0x0201f000, 0x000202da, 0x4c340000, + 0x59300009, 0x800001c0, 0x04000010, 0x82006c00, + 0x00000011, 0x50340000, 0x80000540, 0x04000009, + 0x81300580, 0x04000005, 0x50340000, 0x82006c00, + 0x00000000, 0x0401f7f8, 0x59300000, 0x44006800, + 0x5c006800, 0x1c01f000, 0x59300c06, 0x82040580, + 0x00000005, 0x040007fb, 0x82040580, 0x00000011, + 0x040007f8, 0x82040580, 0x00000006, 0x040007f5, + 0x82040580, 0x00000001, 0x040007f2, 0x0201f800, + 0x001005d8, 0x4933c857, 0x4c080000, 0x4c0c0000, + 0x4c580000, 0x59a8101d, 0x59cc1807, 0x820c1d00, + 0x00ffffff, 0x800c0110, 0x80083580, 0x04020014, + 0x83cc1400, 0x00000008, 0x4200b000, 0x00000002, + 0x59300009, 0x82001c00, 0x00000006, 0x0201f800, + 0x0010855a, 0x0402000a, 0x83cc1400, 0x0000000a, + 0x4200b000, 0x00000002, 0x59300009, 0x82001c00, + 0x00000008, 0x0201f800, 0x0010855a, 0x5c00b000, + 0x5c001800, 0x5c001000, 0x1c01f000, 0x4933c856, + 0x0201f800, 0x0010421b, 0x0201f000, 0x00101e45, + 0x493bc857, 0x4d2c0000, 0x0201f800, 0x001007e4, + 0x02000800, 0x001005d8, 0x832cac00, 0x00000005, + 0x4c580000, 0x4c540000, 0x4200b000, 0x00000006, + 0x4578a800, 0x8054a800, 0x8058b040, 0x040207fd, + 0x83380580, 0x00000046, 0x04020004, 0x4a025a04, + 0x00000144, 0x0401f008, 0x4a025a04, 0x00000146, + 0x83380580, 0x00000041, 0x04000003, 0x4a025a06, + 0x00000001, 0x59cc0007, 0x82000500, 0xff000000, + 0x80000110, 0x59cc1008, 0x82081500, 0xff000000, + 0x80081540, 0x480a580a, 0x83380580, 0x00000046, + 0x04020006, 0x59cc0007, 0x82000500, 0x00ffffff, + 0x4802580b, 0x0401f005, 0x59cc0008, 0x82000500, + 0x00ffffff, 0x4802580b, 0x83380580, 0x00000046, + 0x04020004, 0x83cc1400, 0x00000009, 0x0401f003, + 0x83cc1400, 0x0000000d, 0x50080000, 0x9c0001c0, + 0x4802580c, 0x80081000, 0x50080000, 0x9c0001c0, + 0x4802580d, 0x83380580, 0x00000046, 0x04020008, + 0x59cc000b, 0x9c0001c0, 0x4802580e, 0x59cc000c, + 0x9c0001c0, 0x4802580f, 0x0401f007, 0x59cc000f, + 0x9c0001c0, 0x4802580e, 0x59cc0010, 0x9c0001c0, + 0x4802580f, 0x83380580, 0x00000046, 0x04020004, + 0x83cc1400, 0x00000011, 0x0401f003, 0x83cc1400, + 0x00000015, 0x412c3000, 0x82183400, 0x00000010, + 0x4200b000, 0x00000004, 0x50080000, 0x9c0001c0, + 0x44003000, 0x80081000, 0x80183000, 0x8058b040, + 0x040207fa, 0x5c00a800, 0x5c00b000, 0x0201f800, + 0x000202da, 0x5c025800, 0x1c01f000, 0x4933c857, + 0x492fc857, 0x59300809, 0x58040200, 0x8c00051e, + 0x04000004, 0x592c0208, 0x84000558, 0x48025a08, + 0x1c01f000, 0x59e0180f, 0x599c0413, 0x800c1000, + 0x80080580, 0x04020002, 0x41781000, 0x59e00010, + 0x59e00810, 0x80040d80, 0x040207fd, 0x80080580, + 0x0400000b, 0x4c080000, 0x599c0814, 0x599c1015, + 0x800c00cc, 0x80040c00, 0x82081440, 0x00000000, + 0x5c001800, 0x82000540, 0x00000001, 0x4803c857, + 0x1c01f000, 0x492fc857, 0x42007000, 0x0010b7f8, + 0x58380807, 0x800409c0, 0x04020005, 0x492c7008, + 0x492c7007, 0x0201f000, 0x00100875, 0x492c0800, + 0x492c7007, 0x1c01f000, 0x59300203, 0x4933c857, + 0x4937c857, 0x493bc857, 0x4803c857, 0x82003480, + 0x0000000e, 0x02021800, 0x001005d8, 0x0c01f001, + 0x0010a6da, 0x0010a82c, 0x0010a6da, 0x0010a6da, + 0x0010a6da, 0x0010a6da, 0x0010a6da, 0x0010a791, + 0x0010a6dc, 0x0010a6da, 0x0010a6da, 0x0010a6da, + 0x0010a6da, 0x0010a6da, 0x0201f800, 0x001005d8, + 0x83380580, 0x0000004c, 0x02020800, 0x001005d8, + 0x0201f800, 0x001048ec, 0x04020020, 0x59a80826, + 0x82040500, 0x00000009, 0x82000580, 0x00000008, + 0x0400001a, 0x8c040d12, 0x0400003d, 0x59cc0806, + 0x82040d00, 0xff000000, 0x82040580, 0x03000000, + 0x0400001f, 0x82040580, 0x50000000, 0x04000005, + 0x82040580, 0x52000000, 0x02020000, 0x0002077d, + 0x813669c0, 0x04000006, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x0010203c, 0x5c027800, 0x4a026403, + 0x00000001, 0x0401f014, 0x59cc0806, 0x82040d00, + 0xff000000, 0x82040580, 0x03000000, 0x04000008, + 0x82040580, 0x50000000, 0x04000005, 0x82040580, + 0x52000000, 0x02020000, 0x0002077d, 0x4a026403, 0x00000009, 0x4a02641a, 0x00000009, 0x4a02621a, - 0x00001e00, 0x0401f78e, 0x813669c0, 0x040007f8, - 0x59340c00, 0x82040500, 0x0000ff00, 0x82000580, - 0x00000700, 0x040007f2, 0x0401f7b3, 0x4d2c0000, - 0x4c580000, 0x4c500000, 0x4c540000, 0x41385000, - 0x83380580, 0x00000054, 0x02020800, 0x00100615, - 0x59325808, 0x592c0c0b, 0x82040d00, 0x0000e000, - 0x82040580, 0x00002000, 0x04020076, 0x59300817, - 0x800409c0, 0x04000014, 0x58041404, 0x41cca800, - 0x8204a400, 0x00000005, 0x82080480, 0x00000010, - 0x04021004, 0x4008b000, 0x0401fb84, 0x0401f00a, - 0x40001000, 0x4200b000, 0x0000000f, 0x0401fb7f, - 0x58040801, 0x800409c0, 0x040207f2, 0x0201f800, - 0x00100615, 0x813669c0, 0x0400005e, 0x59344c00, - 0x592c0c09, 0x4807c857, 0x4827c857, 0x82040d00, - 0x000000ff, 0x82040580, 0x00000003, 0x0400002a, - 0x82040580, 0x00000005, 0x04000032, 0x82040580, - 0x00000020, 0x04000036, 0x82040580, 0x00000052, - 0x04000042, 0x82040580, 0x00000050, 0x04000042, - 0x82040580, 0x00000021, 0x04000004, 0x82040580, - 0x00000024, 0x04020043, 0x82240500, 0x0000ff00, - 0x82000580, 0x00000007, 0x04000008, 0x42000800, - 0x00000009, 0x0201f800, 0x001043c7, 0x42005000, - 0x0000000c, 0x0401f037, 0x4a025a06, 0x00000031, - 0x4a02580d, 0x00000009, 0x59340400, 0x4802580e, - 0x0201f800, 0x00020381, 0x0201f800, 0x00107698, - 0x0401f03d, 0x0201f800, 0x001040e4, 0x0201f800, - 0x00104480, 0x42000800, 0x00000003, 0x0201f800, - 0x001043c7, 0x42005000, 0x00000008, 0x0401f021, - 0x59cc0007, 0x0201f800, 0x00105c25, 0x0402001d, - 0x0201f800, 0x001040e4, 0x0401f01a, 0x82240500, - 0x0000ff00, 0x82000580, 0x00000007, 0x040007df, - 0x82240500, 0x000000ff, 0x82000580, 0x00000009, - 0x040007da, 0x0201f800, 0x001044e1, 0x42005000, - 0x0000000a, 0x0401f00b, 0x42005000, 0x0000000e, - 0x0401f003, 0x42005000, 0x00000010, 0x82240500, - 0x0000ff00, 0x82000580, 0x00000007, 0x040007cb, - 0x482a6403, 0x4a026203, 0x00000001, 0x592c000d, - 0x48026011, 0x497a6013, 0x59a80038, 0x48026206, - 0x417a7800, 0x0201f800, 0x00106470, 0x59325817, - 0x812e59c0, 0x04000004, 0x0201f800, 0x00100843, - 0x497a6017, 0x5c00a800, 0x5c00a000, 0x5c00b000, - 0x5c025800, 0x1c01f000, 0x4d2c0000, 0x59325808, - 0x83380580, 0x00000013, 0x0402002a, 0x492fc857, - 0x59300c03, 0x82040580, 0x00000054, 0x0400001e, - 0x82040580, 0x00000010, 0x04000018, 0x82040580, - 0x0000000e, 0x04000015, 0x82040580, 0x00000008, - 0x0400000d, 0x82040580, 0x0000000c, 0x0400000a, - 0x82040580, 0x0000000a, 0x02020800, 0x00100615, - 0x42000800, 0x00000006, 0x0201f800, 0x001043c7, - 0x0401f009, 0x42000800, 0x00000004, 0x0201f800, - 0x001043c7, 0x0401f004, 0x59340200, 0x8400051a, - 0x48026a00, 0x4a025a06, 0x00000000, 0x0201f800, - 0x00020381, 0x0201f800, 0x000208b4, 0x0401f024, - 0x83380580, 0x00000027, 0x0400000f, 0x83380580, - 0x00000014, 0x02020800, 0x00100615, 0x492fc857, - 0x0201f800, 0x001068f6, 0x42028000, 0x00000031, + 0x00000000, 0x813669c0, 0x0402000b, 0x59cc0001, + 0x0201f800, 0x00105c9a, 0x02020000, 0x0002077d, + 0x0201f800, 0x001045a6, 0x02020000, 0x0002077d, + 0x49366009, 0x4a026406, 0x00000004, 0x4a026203, + 0x00000001, 0x0201f000, 0x0010672b, 0x0201f800, + 0x00103b25, 0x04000023, 0x59cc0806, 0x4807c857, + 0x82040d00, 0xff000000, 0x82040580, 0x03000000, + 0x04000033, 0x82040580, 0x20000000, 0x04000041, + 0x82040580, 0x21000000, 0x04000052, 0x82040580, + 0x24000000, 0x0400004f, 0x82040580, 0x50000000, + 0x0400004c, 0x82040580, 0x52000000, 0x04000049, + 0x82040580, 0x05000000, 0x0402000d, 0x59cc0806, + 0x82040d00, 0xff000000, 0x9c0431c0, 0x42028000, + 0x00000046, 0x42002800, 0x00000001, 0x0401fcf3, + 0x0401f93c, 0x02000800, 0x001005d8, 0x42002000, + 0x00000051, 0x0201f800, 0x00107a4a, 0x59cc0000, + 0x82000500, 0x00ffffff, 0x82000580, 0x00ffffff, + 0x04000005, 0x4a026203, 0x00000007, 0x493a6403, + 0x1c01f000, 0x59325817, 0x812e59c0, 0x02020800, + 0x001007fd, 0x0201f000, 0x0002077d, 0x813669c0, + 0x040007df, 0x59340400, 0x82000500, 0x000000ff, + 0x82000580, 0x00000003, 0x040207d9, 0x0401fc6f, + 0x040207d7, 0x4a026403, 0x00000009, 0x4a02641a, + 0x0000000e, 0x4a02621a, 0x00001900, 0x0401f7a2, + 0x813669c0, 0x0400000c, 0x59340c00, 0x82040500, + 0x000000ff, 0x82000580, 0x00000009, 0x04000794, + 0x82040500, 0x0000ff00, 0x82000580, 0x00000700, + 0x040207c3, 0x4a026403, 0x00000009, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00001e00, 0x0401f78e, + 0x813669c0, 0x040007f8, 0x59340c00, 0x82040500, + 0x0000ff00, 0x82000580, 0x00000700, 0x040007f2, + 0x0401f7b3, 0x4d2c0000, 0x4c580000, 0x4c500000, + 0x4c540000, 0x41385000, 0x83380580, 0x00000054, + 0x02020800, 0x001005d8, 0x59325808, 0x592c0c0b, + 0x82040d00, 0x0000e000, 0x82040580, 0x00002000, + 0x04020076, 0x59300817, 0x800409c0, 0x04000014, + 0x58041404, 0x41cca800, 0x8204a400, 0x00000005, + 0x82080480, 0x00000010, 0x04021004, 0x4008b000, + 0x0401fb6b, 0x0401f00a, 0x40001000, 0x4200b000, + 0x0000000f, 0x0401fb66, 0x58040801, 0x800409c0, + 0x040207f2, 0x0201f800, 0x001005d8, 0x813669c0, + 0x0400005e, 0x59344c00, 0x592c0c09, 0x4807c857, + 0x4827c857, 0x82040d00, 0x000000ff, 0x82040580, + 0x00000003, 0x0400002a, 0x82040580, 0x00000005, + 0x04000032, 0x82040580, 0x00000020, 0x04000036, + 0x82040580, 0x00000052, 0x04000042, 0x82040580, + 0x00000050, 0x04000042, 0x82040580, 0x00000021, + 0x04000004, 0x82040580, 0x00000024, 0x04020043, + 0x82240500, 0x0000ff00, 0x82000580, 0x00000007, + 0x04000008, 0x42000800, 0x00000009, 0x0201f800, + 0x00104571, 0x42005000, 0x0000000c, 0x0401f037, + 0x4a025a06, 0x00000031, 0x4a02580d, 0x00000009, + 0x59340400, 0x4802580e, 0x0201f800, 0x000202da, + 0x0201f800, 0x00107911, 0x0401f03d, 0x0201f800, + 0x001042b4, 0x0201f800, 0x0010462a, 0x42000800, + 0x00000003, 0x0201f800, 0x00104571, 0x42005000, + 0x00000008, 0x0401f021, 0x59cc0007, 0x0201f800, + 0x00105eec, 0x0402001d, 0x0201f800, 0x001042b4, + 0x0401f01a, 0x82240500, 0x0000ff00, 0x82000580, + 0x00000007, 0x040007df, 0x82240500, 0x000000ff, + 0x82000580, 0x00000009, 0x040007da, 0x0201f800, + 0x0010468d, 0x42005000, 0x0000000a, 0x0401f00b, + 0x42005000, 0x0000000e, 0x0401f003, 0x42005000, + 0x00000010, 0x82240500, 0x0000ff00, 0x82000580, + 0x00000007, 0x040007cb, 0x482a6403, 0x4a026203, + 0x00000001, 0x592c000d, 0x48026011, 0x497a6013, + 0x59a80038, 0x48026206, 0x417a7800, 0x0201f800, + 0x0010672b, 0x59325817, 0x812e59c0, 0x04000004, + 0x0201f800, 0x001007fd, 0x497a6017, 0x5c00a800, + 0x5c00a000, 0x5c00b000, 0x5c025800, 0x1c01f000, + 0x4d2c0000, 0x59325808, 0x83380580, 0x00000013, + 0x04020029, 0x59300c03, 0x82040580, 0x00000054, + 0x0400001e, 0x82040580, 0x00000010, 0x04000018, + 0x82040580, 0x0000000e, 0x04000015, 0x82040580, + 0x00000008, 0x0400000d, 0x82040580, 0x0000000c, + 0x0400000a, 0x82040580, 0x0000000a, 0x02020800, + 0x001005d8, 0x42000800, 0x00000006, 0x0201f800, + 0x00104571, 0x0401f009, 0x42000800, 0x00000004, + 0x0201f800, 0x00104571, 0x0401f004, 0x59340200, + 0x8400051a, 0x48026a00, 0x4a025a06, 0x00000000, + 0x0201f800, 0x000202da, 0x0201f800, 0x0002077d, + 0x0401f022, 0x83380580, 0x00000027, 0x0400000e, + 0x83380580, 0x00000014, 0x02020800, 0x001005d8, + 0x0201f800, 0x00106bbf, 0x42028000, 0x00000031, 0x42000800, 0x00000004, 0x42001000, 0x000000ff, - 0x0401f00a, 0x492fc857, 0x0201f800, 0x001068f6, - 0x42028000, 0x00000031, 0x42000800, 0x00000004, - 0x42001000, 0x00000010, 0x49425a06, 0x4806580d, - 0x480a580e, 0x0201f800, 0x00020381, 0x0201f800, - 0x00104a83, 0x0201f800, 0x00107698, 0x5c025800, - 0x1c01f000, 0x492fc857, 0x42007000, 0x0010b5f6, - 0x58380807, 0x800409c0, 0x04020005, 0x492c7008, - 0x492c7007, 0x0201f000, 0x001008be, 0x492c0800, - 0x492c7007, 0x1c01f000, 0x4d2c0000, 0x4c580000, - 0x4c500000, 0x4c540000, 0x4933c857, 0x4937c857, - 0x59cc0806, 0x4807c857, 0x82040d00, 0xff000000, - 0x82040580, 0x03000000, 0x0400000d, 0x82040580, - 0x05000000, 0x0400000a, 0x82040580, 0x21000000, - 0x04000030, 0x82040580, 0x24000000, 0x0400002d, - 0x82040580, 0x20000000, 0x0402002f, 0x0201f800, - 0x0010082a, 0x0400002c, 0x492fc857, 0x492e6017, - 0x59a8b016, 0x8258b400, 0x0000001b, 0x8258b500, - 0xfffffffc, 0x8058b104, 0x485a5c04, 0x412c7800, - 0x41cca000, 0x82580480, 0x00000010, 0x04021005, - 0x832cac00, 0x00000005, 0x0401fa78, 0x0401f015, - 0x40580800, 0x4200b000, 0x0000000f, 0x832cac00, - 0x00000005, 0x0401fa71, 0x8204b480, 0x0000000f, - 0x0201f800, 0x0010082a, 0x04000004, 0x492c7801, - 0x412c7800, 0x0401f7ec, 0x59325817, 0x0201f800, - 0x00100843, 0x497a6017, 0x80000580, 0x0401f006, - 0x59340200, 0x84000554, 0x48026a00, 0x82000540, - 0x00000001, 0x5c00a800, 0x5c00a000, 0x5c00b000, - 0x5c025800, 0x1c01f000, 0x4933c857, 0x492fc857, - 0x4d2c0000, 0x4c5c0000, 0x5930bc06, 0x59300a03, - 0x82040580, 0x00000007, 0x0400003c, 0x82040580, - 0x00000001, 0x02020800, 0x00100615, 0x0201f800, - 0x0010698c, 0x4df00000, 0x598c000d, 0x81300580, - 0x04020019, 0x59300004, 0x8c000520, 0x04000004, - 0x84000520, 0x48026004, 0x0401f019, 0x825c0580, - 0x00000011, 0x0402000d, 0x42001000, 0x0010b5f4, - 0x50081000, 0x58080002, 0x82000580, 0x00000100, - 0x04000006, 0x5808000c, 0x81300580, 0x02020800, - 0x00100615, 0x0401f00a, 0x0201f800, 0x00106be2, - 0x04020027, 0x59300004, 0x8c000520, 0x04000004, - 0x84000520, 0x48026004, 0x0401f003, 0x0201f800, - 0x00106619, 0x5c03e000, 0x02000800, 0x00106982, - 0x0201f800, 0x00108df4, 0x02000800, 0x00100615, - 0x59325808, 0x4a025a06, 0x00000005, 0x0201f800, - 0x00020381, 0x825c0580, 0x00000005, 0x0400001b, - 0x0201f800, 0x00104a83, 0x825c0580, 0x00000005, - 0x04000016, 0x59325817, 0x812e59c0, 0x02020800, - 0x00100843, 0x0201f800, 0x00107698, 0x80000580, - 0x5c00b800, 0x5c025800, 0x1c01f000, 0x5c03e000, - 0x02000800, 0x00106982, 0x59300c06, 0x82040580, - 0x00000011, 0x040007ae, 0x82040580, 0x00000005, - 0x040007ab, 0x0401f7f3, 0x0201f800, 0x000208b4, - 0x0401f7ef, 0x4c040000, 0x59340200, 0x4803c857, + 0x0401f009, 0x0201f800, 0x00106bbf, 0x42028000, + 0x00000031, 0x42000800, 0x00000004, 0x42001000, + 0x00000010, 0x49425a06, 0x4806580d, 0x480a580e, + 0x0201f800, 0x000202da, 0x0201f800, 0x00104c19, + 0x0201f800, 0x00107911, 0x5c025800, 0x1c01f000, + 0x42007000, 0x0010b7f8, 0x58380807, 0x800409c0, + 0x04020005, 0x492c7008, 0x492c7007, 0x0201f000, + 0x00100875, 0x492c0800, 0x492c7007, 0x1c01f000, + 0x4d2c0000, 0x4c580000, 0x4c500000, 0x4c540000, + 0x4933c857, 0x4937c857, 0x59cc0806, 0x4807c857, + 0x82040d00, 0xff000000, 0x82040580, 0x03000000, + 0x0400000d, 0x82040580, 0x05000000, 0x0400000a, + 0x82040580, 0x21000000, 0x04000030, 0x82040580, + 0x24000000, 0x0400002d, 0x82040580, 0x20000000, + 0x0402002f, 0x0201f800, 0x001007e4, 0x0400002c, + 0x492fc857, 0x492e6017, 0x59a8b016, 0x8258b400, + 0x0000001b, 0x8258b500, 0xfffffffc, 0x8058b104, + 0x485a5c04, 0x412c7800, 0x41cca000, 0x82580480, + 0x00000010, 0x04021005, 0x832cac00, 0x00000005, + 0x0401fa63, 0x0401f015, 0x40580800, 0x4200b000, + 0x0000000f, 0x832cac00, 0x00000005, 0x0401fa5c, + 0x8204b480, 0x0000000f, 0x0201f800, 0x001007e4, + 0x04000004, 0x492c7801, 0x412c7800, 0x0401f7ec, + 0x59325817, 0x0201f800, 0x001007fd, 0x497a6017, + 0x80000580, 0x0401f006, 0x59340200, 0x84000554, + 0x48026a00, 0x82000540, 0x00000001, 0x5c00a800, + 0x5c00a000, 0x5c00b000, 0x5c025800, 0x1c01f000, + 0x4933c857, 0x492fc857, 0x4d2c0000, 0x59300a03, + 0x82040580, 0x00000007, 0x04000036, 0x82040580, + 0x00000001, 0x02020800, 0x001005d8, 0x0201f800, + 0x00106c55, 0x4df00000, 0x598c000d, 0x81300580, + 0x04020016, 0x59300004, 0x8c000520, 0x04000004, + 0x84000520, 0x48026004, 0x0401f016, 0x42001000, + 0x0010b7f6, 0x50081000, 0x58080002, 0x82000580, + 0x00000100, 0x04000006, 0x5808000c, 0x81300580, + 0x02020800, 0x001005d8, 0x0401f00a, 0x0201f800, + 0x00106e8e, 0x04020020, 0x59300004, 0x8c000520, + 0x04000004, 0x84000520, 0x48026004, 0x0401f003, + 0x0201f800, 0x001068d3, 0x5c03e000, 0x02000800, + 0x00106c4b, 0x0201f800, 0x00109037, 0x02000800, + 0x001005d8, 0x59325808, 0x4a025a06, 0x00000005, + 0x0201f800, 0x000202da, 0x0201f800, 0x00104c19, + 0x59325817, 0x812e59c0, 0x02020800, 0x001007fd, + 0x0201f800, 0x00107911, 0x80000580, 0x5c025800, + 0x1c01f000, 0x5c03e000, 0x02000800, 0x00106c4b, + 0x59300406, 0x82000580, 0x00000011, 0x040007b8, + 0x0401f7f7, 0x4c040000, 0x59340200, 0x4803c857, 0x8c00051c, 0x04000009, 0x59cc0805, 0x591c0019, 0x4803c857, 0x80040580, 0x04000004, 0x80000580, 0x4803c856, 0x0401f003, 0x82000540, 0x00000001, 0x5c000800, 0x1c01f000, 0x4c000000, 0x4c0c0000, 0x4c100000, 0x42001800, 0x0000ffff, 0x42002000, - 0x00000004, 0x0401f013, 0x4c000000, 0x4c0c0000, + 0x00000004, 0x0401f010, 0x4c000000, 0x4c0c0000, + 0x4c100000, 0x59302009, 0x58101c03, 0x42002000, + 0x00000004, 0x0401f008, 0x4c000000, 0x4c0c0000, 0x4c100000, 0x59302009, 0x58101c03, 0x42002000, - 0x00000004, 0x0401f00b, 0x4c000000, 0x4c0c0000, - 0x4c100000, 0x59302009, 0x801021c0, 0x02000800, - 0x00100615, 0x58101c03, 0x42002000, 0x00000007, - 0x480fc857, 0x4813c857, 0x481bc857, 0x0201f800, - 0x001038c7, 0x5c002000, 0x5c001800, 0x5c000000, - 0x1c01f000, 0x83380580, 0x00000092, 0x02020800, - 0x00100615, 0x42000800, 0x80000040, 0x4a026203, - 0x00000001, 0x493a6403, 0x0201f000, 0x00020855, - 0x4d400000, 0x0201f800, 0x0010393e, 0x04000008, - 0x59a80005, 0x84000544, 0x48035005, 0x42028000, - 0x0000002a, 0x0201f800, 0x0010a25b, 0x5c028000, - 0x1c01f000, 0x59a80026, 0x8c000508, 0x04000005, - 0x599c0017, 0x8c00050a, 0x04020002, 0x1c01f000, - 0x82000540, 0x00000001, 0x1c01f000, 0x59300420, - 0x84000540, 0x48026420, 0x1c01f000, 0x4817c857, - 0x4c000000, 0x4c040000, 0x8c142d2a, 0x04000004, - 0x598800b9, 0x80000000, 0x480310b9, 0x8c142d2e, - 0x04000004, 0x598800ba, 0x80000000, 0x480310ba, - 0x8c142d2c, 0x04000013, 0x40140000, 0x82000500, - 0x00070000, 0x82000d80, 0x00030000, 0x0400000d, - 0x82000d80, 0x00040000, 0x0400000a, 0x82000d80, - 0x00050000, 0x04000007, 0x59880005, 0x80000000, - 0x48031005, 0x598800bb, 0x80000000, 0x480310bb, - 0x5c000800, 0x5c000000, 0x1c01f000, 0x4817c857, - 0x4c000000, 0x4c040000, 0x8c142d2a, 0x04000004, - 0x598800bc, 0x80000000, 0x480310bc, 0x8c142d2e, - 0x04000004, 0x598800bd, 0x80000000, 0x480310bd, - 0x8c142d2c, 0x04000013, 0x40140000, 0x82000500, - 0x00070000, 0x82000d80, 0x00030000, 0x0400000d, - 0x82000d80, 0x00040000, 0x0400000a, 0x82000d80, - 0x00050000, 0x04000007, 0x59880005, 0x80000000, - 0x48031005, 0x598800be, 0x80000000, 0x480310be, - 0x5c000800, 0x5c000000, 0x1c01f000, 0x4c000000, - 0x59880001, 0x80000000, 0x4803c857, 0x48031001, - 0x5c000000, 0x1c01f000, 0x4c000000, 0x59880000, - 0x80000000, 0x4803c857, 0x48031000, 0x5c000000, - 0x1c01f000, 0x4c000000, 0x59880002, 0x80000000, - 0x4803c857, 0x48031002, 0x5c000000, 0x1c01f000, - 0x4807c857, 0x4c000000, 0x8c040d2c, 0x04000004, - 0x598800a7, 0x80000000, 0x480310a7, 0x8c040d2a, - 0x04000004, 0x598800a8, 0x80000000, 0x480310a8, - 0x8c040d28, 0x04000004, 0x598800a9, 0x80000000, - 0x480310a9, 0x8c040d26, 0x04000004, 0x598800aa, - 0x80000000, 0x480310aa, 0x8c040d24, 0x04000004, - 0x598800ab, 0x80000000, 0x480310ab, 0x8c040d22, - 0x04000004, 0x598800ac, 0x80000000, 0x480310ac, - 0x8c040d20, 0x04000004, 0x598800ad, 0x80000000, + 0x00000007, 0x480fc857, 0x4813c857, 0x481bc857, + 0x0201f800, 0x00103aae, 0x5c002000, 0x5c001800, + 0x5c000000, 0x1c01f000, 0x83380580, 0x00000092, + 0x02020800, 0x001005d8, 0x42000800, 0x80000040, + 0x4a026203, 0x00000001, 0x493a6403, 0x0201f000, + 0x00020721, 0x4d400000, 0x0201f800, 0x00103b25, + 0x04000008, 0x59a80005, 0x84000544, 0x48035005, + 0x42028000, 0x0000002a, 0x0201f800, 0x0010a449, + 0x5c028000, 0x1c01f000, 0x59a80026, 0x8c000508, + 0x04000005, 0x599c0017, 0x8c00050a, 0x04020002, + 0x1c01f000, 0x82000540, 0x00000001, 0x1c01f000, + 0x59300420, 0x84000540, 0x48026420, 0x1c01f000, + 0x4817c857, 0x4c000000, 0x4c040000, 0x8c142d2a, + 0x04000004, 0x598800b8, 0x80000000, 0x480310b8, + 0x8c142d2e, 0x04000004, 0x598800b9, 0x80000000, + 0x480310b9, 0x8c142d2c, 0x04000013, 0x40140000, + 0x82000500, 0x00070000, 0x82000d80, 0x00030000, + 0x0400000d, 0x82000d80, 0x00040000, 0x0400000a, + 0x82000d80, 0x00050000, 0x04000007, 0x59880005, + 0x80000000, 0x48031005, 0x598800ba, 0x80000000, + 0x480310ba, 0x5c000800, 0x5c000000, 0x1c01f000, + 0x4817c857, 0x4c000000, 0x4c040000, 0x8c142d2a, + 0x04000004, 0x598800bb, 0x80000000, 0x480310bb, + 0x8c142d2e, 0x04000004, 0x598800bc, 0x80000000, + 0x480310bc, 0x8c142d2c, 0x04000013, 0x40140000, + 0x82000500, 0x00070000, 0x82000d80, 0x00030000, + 0x0400000d, 0x82000d80, 0x00040000, 0x0400000a, + 0x82000d80, 0x00050000, 0x04000007, 0x59880005, + 0x80000000, 0x48031005, 0x598800bd, 0x80000000, + 0x480310bd, 0x5c000800, 0x5c000000, 0x1c01f000, + 0x4c000000, 0x59880001, 0x80000000, 0x4803c857, + 0x48031001, 0x5c000000, 0x1c01f000, 0x4c000000, + 0x59880000, 0x80000000, 0x4803c857, 0x48031000, + 0x5c000000, 0x1c01f000, 0x4c000000, 0x59880002, + 0x80000000, 0x4803c857, 0x48031002, 0x5c000000, + 0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d2c, + 0x04000004, 0x598800a6, 0x80000000, 0x480310a6, + 0x8c040d2a, 0x04000004, 0x598800a7, 0x80000000, + 0x480310a7, 0x8c040d28, 0x04000004, 0x598800a8, + 0x80000000, 0x480310a8, 0x8c040d26, 0x04000004, + 0x598800a9, 0x80000000, 0x480310a9, 0x8c040d24, + 0x04000004, 0x598800aa, 0x80000000, 0x480310aa, + 0x8c040d22, 0x04000004, 0x598800ab, 0x80000000, + 0x480310ab, 0x8c040d20, 0x04000004, 0x598800ac, + 0x80000000, 0x480310ac, 0x5c000000, 0x1c01f000, + 0x4807c857, 0x4c000000, 0x598800ad, 0x80000000, 0x480310ad, 0x5c000000, 0x1c01f000, 0x4807c857, - 0x4c000000, 0x598800ae, 0x80000000, 0x480310ae, + 0x4c000000, 0x8c040d1c, 0x04000004, 0x598800ae, + 0x80000000, 0x480310ae, 0x8c040d1a, 0x04000004, + 0x598800af, 0x80000000, 0x480310af, 0x5c000000, + 0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d18, + 0x04000004, 0x598800b0, 0x80000000, 0x480310b0, + 0x8c040d16, 0x04000004, 0x598800b1, 0x80000000, + 0x480310b1, 0x8c040d14, 0x04000004, 0x598800b2, + 0x80000000, 0x480310b2, 0x5c000000, 0x1c01f000, + 0x4807c857, 0x4c000000, 0x8c040d10, 0x04000004, + 0x598800b3, 0x80000000, 0x480310b3, 0x8c040d0c, + 0x04000004, 0x598800b4, 0x80000000, 0x480310b4, 0x5c000000, 0x1c01f000, 0x4807c857, 0x4c000000, - 0x8c040d1c, 0x04000004, 0x598800af, 0x80000000, - 0x480310af, 0x8c040d1a, 0x04000004, 0x598800b0, - 0x80000000, 0x480310b0, 0x5c000000, 0x1c01f000, - 0x4807c857, 0x4c000000, 0x8c040d18, 0x04000004, - 0x598800b1, 0x80000000, 0x480310b1, 0x8c040d16, - 0x04000004, 0x598800b2, 0x80000000, 0x480310b2, - 0x8c040d14, 0x04000004, 0x598800b3, 0x80000000, - 0x480310b3, 0x5c000000, 0x1c01f000, 0x4807c857, - 0x4c000000, 0x8c040d10, 0x04000004, 0x598800b4, - 0x80000000, 0x480310b4, 0x8c040d0c, 0x04000004, - 0x598800b5, 0x80000000, 0x480310b5, 0x5c000000, - 0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d08, - 0x04000004, 0x598800b6, 0x80000000, 0x480310b6, - 0x8c040d04, 0x04000004, 0x598800b7, 0x80000000, - 0x480310b7, 0x5c000000, 0x1c01f000, 0x4807c856, - 0x4c000000, 0x59880080, 0x80000000, 0x48031080, - 0x5c000000, 0x1c01f000, 0x4803c857, 0x4c040000, - 0x50000800, 0x80040800, 0x4807c857, 0x44040000, - 0x5c000800, 0x1c01f000, 0x480fc857, 0x4c000000, - 0x820c0580, 0x00000000, 0x04020004, 0x42000000, - 0x0010b617, 0x0401f014, 0x820c0580, 0x00001001, - 0x04020004, 0x42000000, 0x0010b618, 0x0401f00e, - 0x820c0580, 0x00001002, 0x04020004, 0x42000000, - 0x0010b619, 0x0401f008, 0x820c0c80, 0x0000201c, - 0x02021800, 0x00100615, 0x820c0500, 0x0000001f, - 0x0c01f804, 0x0401ffdd, 0x5c000000, 0x1c01f000, - 0x0010a8b0, 0x0010a8b3, 0x0010a8b6, 0x0010a8b9, - 0x0010a8bc, 0x0010a8bf, 0x0010a8c2, 0x0010a8c5, - 0x0010a8c8, 0x0010a8cb, 0x0010a8ce, 0x0010a8d1, - 0x0010a8d4, 0x0010a8d7, 0x0010a8da, 0x0010a8dd, - 0x0010a8e0, 0x0010a8e3, 0x0010a8e6, 0x0010a8e9, - 0x0010a8ec, 0x0010a8ef, 0x0010a8f2, 0x0010a8f5, - 0x0010a8f8, 0x0010a8fb, 0x0010a8fe, 0x0010a901, - 0x42000000, 0x0010b61a, 0x1c01f000, 0x42000000, - 0x0010b61b, 0x1c01f000, 0x42000000, 0x0010b61c, - 0x1c01f000, 0x42000000, 0x0010b61d, 0x1c01f000, - 0x42000000, 0x0010b61e, 0x1c01f000, 0x42000000, - 0x0010b61f, 0x1c01f000, 0x42000000, 0x0010b620, - 0x1c01f000, 0x42000000, 0x0010b621, 0x1c01f000, - 0x42000000, 0x0010b622, 0x1c01f000, 0x42000000, - 0x0010b623, 0x1c01f000, 0x42000000, 0x0010b624, - 0x1c01f000, 0x42000000, 0x0010b625, 0x1c01f000, - 0x42000000, 0x0010b626, 0x1c01f000, 0x42000000, - 0x0010b627, 0x1c01f000, 0x42000000, 0x0010b628, - 0x1c01f000, 0x42000000, 0x0010b629, 0x1c01f000, - 0x42000000, 0x0010b62a, 0x1c01f000, 0x42000000, - 0x0010b62b, 0x1c01f000, 0x42000000, 0x0010b62c, - 0x1c01f000, 0x42000000, 0x0010b62d, 0x1c01f000, - 0x42000000, 0x0010b62e, 0x1c01f000, 0x42000000, - 0x0010b62f, 0x1c01f000, 0x42000000, 0x0010b630, - 0x1c01f000, 0x42000000, 0x0010b631, 0x1c01f000, - 0x42000000, 0x0010b632, 0x1c01f000, 0x42000000, - 0x0010b633, 0x1c01f000, 0x42000000, 0x0010b634, - 0x1c01f000, 0x42000000, 0x0010b635, 0x1c01f000, - 0x480fc857, 0x4c000000, 0x820c0580, 0x00000001, - 0x04020004, 0x42000000, 0x0010b60c, 0x0401f012, - 0x820c0580, 0x00000002, 0x04020004, 0x42000000, - 0x0010b60d, 0x0401f00c, 0x820c0580, 0x00000003, - 0x04020004, 0x42000000, 0x0010b60e, 0x0401f006, - 0x820c0580, 0x00000004, 0x04020004, 0x42000000, - 0x0010b60f, 0x0401ff51, 0x5c000000, 0x1c01f000, - 0x4c000000, 0x59a80026, 0x4803c857, 0x8c000502, - 0x04000010, 0x8c000506, 0x04000004, 0x42000000, - 0x0010b63f, 0x0401f012, 0x8c00050a, 0x04000004, - 0x42000000, 0x0010b63e, 0x0401f00d, 0x8c000508, - 0x04000004, 0x42000000, 0x0010b641, 0x0401f008, - 0x0201f800, 0x00104e0d, 0x04000006, 0x8c000506, - 0x04020004, 0x42000000, 0x0010b640, 0x0401ff33, - 0x5c000000, 0x1c01f000, 0x8058b1c0, 0x02000800, - 0x00100615, 0x5450a800, 0x8050a000, 0x8054a800, - 0x8058b040, 0x040207fc, 0x1c01f000, 0x8058b1c0, - 0x02000800, 0x00100615, 0x4450a800, 0x8054a800, - 0x8058b040, 0x040207fd, 0x1c01f000, 0x8058b1c0, - 0x02000800, 0x00100615, 0x50500000, 0x9c0001c0, - 0x4400a800, 0x8050a000, 0x8054a800, 0x8058b040, - 0x040207fa, 0x1c01f000, 0x4c000000, 0x59a80008, - 0x8c00051c, 0x5c000000, 0x1c01f000, 0x00000001, - 0x00000002, 0x00000004, 0x00000008, 0x00000010, - 0x00000020, 0x00000040, 0x00000080, 0x00000100, - 0x00000200, 0x00000400, 0x00000800, 0x00001000, - 0x00002000, 0x00004000, 0x00008000, 0x00010000, - 0xd2764e14 + 0x8c040d08, 0x04000004, 0x598800b5, 0x80000000, + 0x480310b5, 0x8c040d04, 0x04000004, 0x598800b6, + 0x80000000, 0x480310b6, 0x5c000000, 0x1c01f000, + 0x4807c856, 0x4c000000, 0x5988007f, 0x80000000, + 0x4803107f, 0x5c000000, 0x1c01f000, 0x4803c857, + 0x4c040000, 0x50000800, 0x80040800, 0x4807c857, + 0x44040000, 0x5c000800, 0x1c01f000, 0x480fc857, + 0x4c000000, 0x820c0580, 0x00000000, 0x04020004, + 0x42000000, 0x0010b819, 0x0401f014, 0x820c0580, + 0x00001001, 0x04020004, 0x42000000, 0x0010b81a, + 0x0401f00e, 0x820c0580, 0x00001002, 0x04020004, + 0x42000000, 0x0010b81b, 0x0401f008, 0x820c0c80, + 0x0000201c, 0x02021800, 0x001005d8, 0x820c0500, + 0x0000001f, 0x0c01f804, 0x0401ffdd, 0x5c000000, + 0x1c01f000, 0x0010aa89, 0x0010aa8c, 0x0010aa8f, + 0x0010aa92, 0x0010aa95, 0x0010aa98, 0x0010aa9b, + 0x0010aa9e, 0x0010aaa1, 0x0010aaa4, 0x0010aaa7, + 0x0010aaaa, 0x0010aaad, 0x0010aab0, 0x0010aab3, + 0x0010aab6, 0x0010aab9, 0x0010aabc, 0x0010aabf, + 0x0010aac2, 0x0010aac5, 0x0010aac8, 0x0010aacb, + 0x0010aace, 0x0010aad1, 0x0010aad4, 0x0010aad7, + 0x0010aada, 0x42000000, 0x0010b81c, 0x1c01f000, + 0x42000000, 0x0010b81d, 0x1c01f000, 0x42000000, + 0x0010b81e, 0x1c01f000, 0x42000000, 0x0010b81f, + 0x1c01f000, 0x42000000, 0x0010b820, 0x1c01f000, + 0x42000000, 0x0010b821, 0x1c01f000, 0x42000000, + 0x0010b822, 0x1c01f000, 0x42000000, 0x0010b823, + 0x1c01f000, 0x42000000, 0x0010b824, 0x1c01f000, + 0x42000000, 0x0010b825, 0x1c01f000, 0x42000000, + 0x0010b826, 0x1c01f000, 0x42000000, 0x0010b827, + 0x1c01f000, 0x42000000, 0x0010b828, 0x1c01f000, + 0x42000000, 0x0010b829, 0x1c01f000, 0x42000000, + 0x0010b82a, 0x1c01f000, 0x42000000, 0x0010b82b, + 0x1c01f000, 0x42000000, 0x0010b82c, 0x1c01f000, + 0x42000000, 0x0010b82d, 0x1c01f000, 0x42000000, + 0x0010b82e, 0x1c01f000, 0x42000000, 0x0010b82f, + 0x1c01f000, 0x42000000, 0x0010b830, 0x1c01f000, + 0x42000000, 0x0010b831, 0x1c01f000, 0x42000000, + 0x0010b832, 0x1c01f000, 0x42000000, 0x0010b833, + 0x1c01f000, 0x42000000, 0x0010b834, 0x1c01f000, + 0x42000000, 0x0010b835, 0x1c01f000, 0x42000000, + 0x0010b836, 0x1c01f000, 0x42000000, 0x0010b837, + 0x1c01f000, 0x480fc857, 0x4c000000, 0x820c0580, + 0x00000001, 0x04020004, 0x42000000, 0x0010b80e, + 0x0401f012, 0x820c0580, 0x00000002, 0x04020004, + 0x42000000, 0x0010b80f, 0x0401f00c, 0x820c0580, + 0x00000003, 0x04020004, 0x42000000, 0x0010b810, + 0x0401f006, 0x820c0580, 0x00000004, 0x04020004, + 0x42000000, 0x0010b811, 0x0401ff51, 0x5c000000, + 0x1c01f000, 0x4c000000, 0x59a80026, 0x4803c857, + 0x8c000502, 0x04000010, 0x8c000506, 0x04000004, + 0x42000000, 0x0010b841, 0x0401f012, 0x8c00050a, + 0x04000004, 0x42000000, 0x0010b840, 0x0401f00d, + 0x8c000508, 0x04000004, 0x42000000, 0x0010b843, + 0x0401f008, 0x0201f800, 0x0010513b, 0x04000006, + 0x8c000506, 0x04020004, 0x42000000, 0x0010b842, + 0x0401ff33, 0x5c000000, 0x1c01f000, 0x8058b1c0, + 0x02000800, 0x001005d8, 0x5450a800, 0x8050a000, + 0x8054a800, 0x8058b040, 0x040207fc, 0x1c01f000, + 0x8058b1c0, 0x02000800, 0x001005d8, 0x4450a800, + 0x8054a800, 0x8058b040, 0x040207fd, 0x1c01f000, + 0x8058b1c0, 0x02000800, 0x001005d8, 0x50500000, + 0x9c0001c0, 0x4400a800, 0x8050a000, 0x8054a800, + 0x8058b040, 0x040207fa, 0x1c01f000, 0x4c000000, + 0x59a80008, 0x8c00051c, 0x5c000000, 0x1c01f000, + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, + 0x00010000, 0xa5f2b3ac }; #ifdef UNIQUE_FW_NAME -uint32_t fw2400_length01 = 0x0000a971 ; +uint32_t fw2400_length01 = 0x0000ab4a ; #else -uint32_t risc_code_length01 = 0x0000a971 ; +uint32_t risc_code_length01 = 0x0000ab4a ; #endif #ifdef UNIQUE_FW_NAME -uint32_t fw2400_addr02 = 0x0010d000 ; +uint32_t fw2400_addr02 = 0x0010e000 ; #else -uint32_t risc_code_addr02 = 0x0010d000 ; +uint32_t risc_code_addr02 = 0x0010e000 ; #endif #ifdef UNIQUE_FW_NAME @@ -10904,113 +11022,100 @@ uint32_t fw2400_code02[] = { #else uint32_t risc_code02[] = { #endif - 0x00000000, 0x00000000, 0x0010d000, 0x0000165e, - 0x00000000, 0x00000000, 0x00020000, 0x000009f7, - 0x836c0580, 0x00000003, 0x02020000, 0x00100314, - 0x42000000, 0x0010b2b7, 0x50000000, 0x800001c0, - 0x0402098a, 0x0401f94d, 0x0201f800, 0x00020524, - 0x0401fbfe, 0x0201f800, 0x0002084c, 0x0201f800, - 0x000206af, 0x0401f7ef, 0x59b800ea, 0x82000d00, - 0xf0000038, 0x02020000, 0x00100ac3, 0x8c000510, - 0x02000000, 0x00100ac2, 0x59ba60e0, 0x81300182, - 0x0402104e, 0x04002030, 0x8532653e, 0x59300406, - 0x82000580, 0x00000003, 0x04020028, 0x59300203, - 0x82000580, 0x00000004, 0x04020024, 0x59325808, - 0x59300402, 0x4a025a04, 0x00000103, 0x900001c0, - 0x48025806, 0x497a5807, 0x497a5c09, 0x5930001f, - 0x80000540, 0x02020800, 0x00100d9a, 0x59300004, - 0x8c00053e, 0x04020010, 0x0401fb47, 0x59326809, - 0x0201f800, 0x000208b4, 0x5934000f, 0x5934140b, + 0x00000000, 0x00000000, 0x0010e000, 0x000014ff, + 0x00000000, 0x00000000, 0x00020000, 0x000008c0, + 0x836c0580, 0x00000003, 0x02020000, 0x001002e3, + 0x42000000, 0x0010b4bb, 0x50000000, 0x800001c0, + 0x04020956, 0x0401f923, 0x0401fbe3, 0x0401fb5c, + 0x0201f800, 0x00020718, 0x0201f800, 0x0002057b, + 0x0401f7f0, 0x59b800ea, 0x82000d00, 0xf0000038, + 0x02020000, 0x00100a7a, 0x8c000510, 0x02000000, + 0x00100a79, 0x59ba60e0, 0x81300182, 0x0402104e, + 0x04002030, 0x8532653e, 0x59300406, 0x82000580, + 0x00000003, 0x04020028, 0x59300203, 0x82000580, + 0x00000004, 0x04020024, 0x59325808, 0x59300402, + 0x4a025a04, 0x00000103, 0x900001c0, 0x48025806, + 0x497a5807, 0x497a5c09, 0x5930001f, 0x80000540, + 0x02020800, 0x00100d56, 0x59300004, 0x8c00053e, + 0x04020010, 0x0401fa88, 0x59326809, 0x0201f800, + 0x0002077d, 0x5934000f, 0x5934140b, 0x80081040, + 0x04001002, 0x480a6c0b, 0x80000540, 0x04020a10, + 0x59b800ea, 0x8c000510, 0x040207d7, 0x1c01f000, + 0x0201f800, 0x00106f60, 0x040007ef, 0x0201f000, + 0x00100a65, 0x42027000, 0x00000055, 0x0401f027, + 0x83326500, 0x3fffffff, 0x59300406, 0x82000580, + 0x00000003, 0x04020015, 0x59325808, 0x59326809, + 0x59301402, 0x4a025a04, 0x00000103, 0x900811c0, + 0x480a5806, 0x497a5c09, 0x497a5807, 0x0401fa62, + 0x0201f800, 0x0002077d, 0x5934000f, 0x5934140b, 0x80081040, 0x04001002, 0x480a6c0b, 0x80000540, - 0x04020a31, 0x59b800ea, 0x8c000510, 0x040207d7, - 0x1c01f000, 0x0201f800, 0x00106cb4, 0x040007ef, - 0x0201f000, 0x00100aae, 0x42027000, 0x00000055, - 0x0401f027, 0x83326500, 0x3fffffff, 0x59300406, - 0x82000580, 0x00000003, 0x04020015, 0x59325808, - 0x59326809, 0x59301402, 0x4a025a04, 0x00000103, - 0x900811c0, 0x480a5806, 0x497a5c09, 0x497a5807, - 0x0401fb21, 0x0201f800, 0x000208b4, 0x5934000f, - 0x5934140b, 0x80081040, 0x04001002, 0x480a6c0b, - 0x80000540, 0x04020a0c, 0x0401f7db, 0x42027000, - 0x00000054, 0x0401f00a, 0x83300500, 0x60000000, - 0x02000000, 0x00100ab1, 0x81326580, 0x8000013a, - 0x82000400, 0x00100ac9, 0x50027000, 0x59300c06, - 0x82040580, 0x00000002, 0x02000000, 0x00100aae, - 0x59300004, 0x8c00053e, 0x04020004, 0x0201f800, - 0x000208d8, 0x0401f7c4, 0x0201f800, 0x00106cb4, - 0x040007fb, 0x0201f000, 0x00100aae, 0x59325808, - 0x412c7000, 0x58380a04, 0x82040500, 0x0000000f, - 0x82000c00, 0x0010110d, 0x50044000, 0x0c01f001, - 0x00100e24, 0x00100e24, 0x000200a0, 0x00100e24, - 0x00100e24, 0x00100e24, 0x00100e24, 0x00100e24, - 0x000200b0, 0x00100e38, 0x00100e24, 0x00100e24, - 0x00100e26, 0x00100e24, 0x00100e24, 0x00100e24, - 0x5838040a, 0x8c000500, 0x02000800, 0x00100615, - 0x50200000, 0x80387c00, 0x583c1002, 0x583c2800, - 0x583c2001, 0x58380a07, 0x5838300f, 0x59303807, - 0x58384c08, 0x5838000d, 0x48026012, 0x0401f010, - 0x5838020a, 0x8c000502, 0x02000000, 0x00100e24, - 0x50200000, 0x80387c00, 0x583c2800, 0x583c2001, - 0x583c1002, 0x592c0a07, 0x592c4c08, 0x592c300f, - 0x59303807, 0x497a6012, 0x497a6013, 0x4816600e, - 0x4812600f, 0x480a6010, 0x481a6011, 0x80040840, - 0x4806600d, 0x02020000, 0x00100e65, 0x841c3d40, - 0x481e6007, 0x1c01f000, 0x41787800, 0x59325808, - 0x592c0c0a, 0x8c040d02, 0x02000000, 0x00100fda, - 0x592c000d, 0x592c100f, 0x592c0a04, 0x480a6011, - 0x48026012, 0x48026013, 0x412c3000, 0x82040500, - 0x0000000f, 0x82000400, 0x0010110d, 0x50003800, - 0x501c0000, 0x401c1000, 0x592c1a07, 0x4802600a, - 0x481a600b, 0x480a600c, 0x480e600d, 0x843c7d4a, - 0x403c1000, 0x1c01f000, 0x41787800, 0x497a6012, - 0x592c0a04, 0x412c3000, 0x592c1a07, 0x82040500, - 0x0000000f, 0x82000400, 0x0010110d, 0x50004000, - 0x50200000, 0x40201000, 0x4802600a, 0x481a600b, - 0x480a600c, 0x480e600d, 0x80000580, 0x483e6004, - 0x1c01f000, 0x0002014c, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x00020139, 0x00020139, 0x00020139, - 0x00020139, 0x4c000000, 0x4df00000, 0x4203e000, - 0xb0100000, 0x41f00000, 0x81fe1500, 0x8d0a1512, - 0x02020800, 0x00101468, 0x8d0a1518, 0x02020800, - 0x00020861, 0x8d0a151a, 0x04020ed0, 0x83080500, - 0x00000d00, 0x04020804, 0x5c03e000, 0x5c000000, - 0x1801f000, 0x8d0a1516, 0x02020800, 0x001012d9, - 0x8d0a1514, 0x02020800, 0x001011a5, 0x8d0a1508, - 0x02020800, 0x001011aa, 0x8d0a1500, 0x02020000, - 0x000207c8, 0x1c01f000, 0x42000000, 0x0010b2bd, - 0x50000000, 0x8c000504, 0x04000014, 0x42000000, - 0x0010b2bd, 0x50000000, 0x8c000502, 0x04020002, - 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, - 0x42034000, 0x0010b2a0, 0x59a0001d, 0x59a1d81e, - 0x84000502, 0x4803401d, 0x58ec0009, 0x0801f800, - 0x5c03e000, 0x1c01f000, 0x04027002, 0x04026002, - 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, - 0x0201f800, 0x0010082a, 0x0400001a, 0x412dd800, - 0x48efc857, 0x0201f800, 0x00103941, 0x42034000, - 0x0010b2a0, 0x49a1d80b, 0x48ef401e, 0x59a0001d, - 0x84000544, 0x4803401d, 0x59e00020, 0x4803c857, - 0x59e00021, 0x4803c857, 0x59e00022, 0x4803c857, - 0x59e00023, 0x4803c857, 0x59e00024, 0x4803c857, - 0x0201f800, 0x00101fbb, 0x0201f800, 0x00101fda, + 0x040209eb, 0x0401f7db, 0x42027000, 0x00000054, + 0x0401f00a, 0x83300500, 0x60000000, 0x02000000, + 0x00100a68, 0x81326580, 0x8000013a, 0x82000400, + 0x00100a80, 0x50027000, 0x59300c06, 0x82040580, + 0x00000002, 0x02000000, 0x00100a65, 0x59300004, + 0x8c00053e, 0x04020004, 0x0201f800, 0x000207a1, + 0x0401f7c4, 0x0201f800, 0x00106f60, 0x040007fb, + 0x0201f000, 0x00100a65, 0x59325808, 0x412c7000, + 0x58380a04, 0x82040500, 0x0000000f, 0x82000c00, + 0x001010bd, 0x50044000, 0x0c01f001, 0x00100dd9, + 0x00100dd9, 0x0002009f, 0x00100dd9, 0x00100dd9, + 0x00100dd9, 0x00100dd9, 0x00100dd9, 0x000200af, + 0x00100ded, 0x00100dd9, 0x00100dd9, 0x00100ddb, + 0x00100dd9, 0x00100dd9, 0x00100dd9, 0x5838040a, + 0x8c000500, 0x02000800, 0x001005d8, 0x50200000, + 0x80387c00, 0x583c1002, 0x583c2800, 0x583c2001, + 0x58380a07, 0x5838300f, 0x59303807, 0x58384c08, + 0x5838000d, 0x48026012, 0x0401f010, 0x5838020a, + 0x8c000502, 0x02000000, 0x00100dd9, 0x50200000, + 0x80387c00, 0x583c2800, 0x583c2001, 0x583c1002, + 0x592c0a07, 0x592c4c08, 0x592c300f, 0x59303807, + 0x497a6012, 0x497a6013, 0x4816600e, 0x4812600f, + 0x480a6010, 0x481a6011, 0x80040840, 0x4806600d, + 0x02020000, 0x00100e1a, 0x841c3d40, 0x481e6007, + 0x1c01f000, 0x41787800, 0x59325808, 0x592c0c0a, + 0x8c040d02, 0x02000000, 0x00100f8c, 0x592c000d, + 0x592c100f, 0x592c0a04, 0x480a6011, 0x48026012, + 0x48026013, 0x412c3000, 0x82040500, 0x0000000f, + 0x82000400, 0x001010bd, 0x50003800, 0x501c0000, + 0x401c1000, 0x592c1a07, 0x4802600a, 0x481a600b, + 0x480a600c, 0x480e600d, 0x843c7d4a, 0x403c1000, + 0x1c01f000, 0x41787800, 0x497a6012, 0x592c0a04, + 0x412c3000, 0x592c1a07, 0x82040500, 0x0000000f, + 0x82000400, 0x001010bd, 0x50004000, 0x50200000, + 0x40201000, 0x4802600a, 0x481a600b, 0x480a600c, + 0x480e600d, 0x80000580, 0x483e6004, 0x1c01f000, + 0x4c000000, 0x4df00000, 0x0201f800, 0x00020729, + 0x0401f005, 0x4c000000, 0x4df00000, 0x0401ff16, + 0x0401f001, 0x5c03e000, 0x5c000000, 0x1801f000, + 0x4203e000, 0xb0100000, 0x41fc0000, 0x82000500, + 0x00000011, 0x0c01f001, 0x0002012a, 0x00020697, + 0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a, + 0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a, + 0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a, + 0x0002012a, 0x0002012a, 0x0010115a, 0x0002012c, + 0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a, + 0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a, + 0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a, + 0x0002012a, 0x0002012a, 0x0201f800, 0x001005d8, + 0x0201f800, 0x00020697, 0x0201f000, 0x0010115a, + 0x42000000, 0x0010b4c1, 0x50000000, 0x8c000504, + 0x04000014, 0x42000000, 0x0010b4c1, 0x50000000, + 0x8c000502, 0x04020002, 0x1c01f000, 0x4df00000, + 0x4203e000, 0x50000000, 0x42034000, 0x0010b4a4, + 0x59a0001d, 0x59a1d81e, 0x84000502, 0x4803401d, + 0x58ec0009, 0x0801f800, 0x5c03e000, 0x1c01f000, + 0x04027002, 0x04026002, 0x1c01f000, 0x4df00000, + 0x4203e000, 0x50000000, 0x0201f800, 0x001007e4, + 0x04000010, 0x412dd800, 0x48efc857, 0x0201f800, + 0x00103b28, 0x42034000, 0x0010b4a4, 0x49a1d80b, + 0x48ef401e, 0x59a0001d, 0x84000544, 0x4803401d, + 0x0201f800, 0x00102214, 0x0201f800, 0x00102233, 0x5c03e000, 0x1c01f000, 0x4da00000, 0x4df00000, - 0x4203e000, 0x50000000, 0x04006051, 0x42034000, - 0x0010b2a0, 0x59a01017, 0x59a01818, 0x800c19c0, + 0x4203e000, 0x50000000, 0x04006051, 0x40001000, + 0x42034000, 0x0010b4a4, 0x59a01818, 0x800c19c0, 0x04020008, 0x59a0381b, 0x801c39c0, 0x02000800, - 0x00100615, 0x59a0041c, 0x801c3c00, 0x0401f00c, + 0x001005d8, 0x59a0041c, 0x801c3c00, 0x0401f00c, 0x59a00419, 0x82000400, 0x00000002, 0x48034419, 0x82000c80, 0x00000013, 0x04001003, 0x497b4419, 0x41780000, 0x59a03816, 0x801c3c00, 0x80081040, @@ -11022,319 +11127,255 @@ uint32_t risc_code02[] = { 0x800c19c0, 0x04000007, 0x800c1840, 0x480f4018, 0x0402001f, 0x497b4419, 0x497b4219, 0x0401f01c, 0x800811c0, 0x0402000b, 0x4d2c0000, 0x59a2581b, - 0x0201f800, 0x0010083a, 0x5c025800, 0x497b401b, + 0x0201f800, 0x001007f4, 0x5c025800, 0x497b401b, 0x497b401a, 0x497b441c, 0x497b421c, 0x0401f010, 0x59a0041c, 0x82000400, 0x00000002, 0x82000c80, 0x00000012, 0x4803441c, 0x04001009, 0x4d2c0000, 0x59a2581b, 0x592c3813, 0x481f401b, 0x497b441c, - 0x0201f800, 0x0010083a, 0x5c025800, 0x5c03e000, + 0x0201f800, 0x001007f4, 0x5c025800, 0x5c03e000, 0x5c034000, 0x1c01f000, 0x59a80005, 0x82000500, - 0x00000003, 0x02020000, 0x00104145, 0x59340400, - 0x82000580, 0x00000606, 0x02020000, 0x00104116, - 0x5934000d, 0x80027d40, 0x02020000, 0x00104151, + 0x00000003, 0x02020000, 0x00104315, 0x59340400, + 0x82000580, 0x00000606, 0x02020000, 0x001042e6, + 0x5934000d, 0x80027d40, 0x02020000, 0x00104321, 0x0401f803, 0x80000580, 0x1c01f000, 0x5934000f, - 0x59341203, 0x80080540, 0x0402005d, 0x5934020b, - 0x5934140b, 0x80080480, 0x04021059, 0x0201f800, - 0x00020892, 0x04000052, 0x592c0406, 0x49366009, - 0x492e6008, 0x4a026406, 0x00000003, 0x4a026403, - 0x00000040, 0x80081000, 0x480a6c0b, 0x800000c2, + 0x59341203, 0x80080540, 0x0402006f, 0x5934020b, + 0x5934140b, 0x80080480, 0x0402106b, 0x0201f800, + 0x0002075a, 0x04000064, 0x80081000, 0x592c0406, + 0x480a6c0b, 0x49366009, 0x492e6008, 0x4a026406, + 0x00000003, 0x4a026403, 0x00000040, 0x800000c2, 0x800018c4, 0x800c0400, 0x48026206, 0x592c0808, 0x592c1809, 0x592c020a, 0x48066017, 0x480e6018, - 0x8c000502, 0x0400002a, 0x4a026203, 0x00000004, - 0x592c0207, 0x80000040, 0x0402001a, 0x59a80070, - 0x80000040, 0x040207ff, 0x592c0204, 0x82000500, - 0x000000ff, 0x82000580, 0x00000018, 0x04020011, - 0x592c180f, 0x59300007, 0x82000540, 0x00000091, - 0x480e6011, 0x48026007, 0x42000000, 0x80000004, - 0x48026004, 0x59bc00ea, 0x8c000516, 0x040207fe, - 0x83300400, 0x20000000, 0x480378e1, 0x1c01f000, - 0x0401fe4b, 0x59300007, 0x8400054e, 0x48026007, - 0x592c1a04, 0x820c1d00, 0x000000ff, 0x820c0580, - 0x00000048, 0x04000012, 0x0401f7ec, 0x8c000500, - 0x04020e9e, 0x4a026203, 0x00000002, 0x59a80071, - 0x80000040, 0x040207ff, 0x592c1a04, 0x820c1d00, - 0x000000ff, 0x820c0580, 0x00000018, 0x040007df, - 0x820c0580, 0x00000048, 0x040207dc, 0x42000800, - 0x80000804, 0x0201f000, 0x00106466, 0x800811c0, - 0x04020003, 0x4a026a03, 0x00000001, 0x59340010, - 0x492e6810, 0x80000d40, 0x04020003, 0x492e680f, - 0x1c01f000, 0x492c0800, 0x1c01f000, 0x83440c80, - 0x00000800, 0x04021009, 0x83440400, 0x0010aa00, - 0x50000000, 0x80000540, 0x04000004, 0x40026800, - 0x80000580, 0x1c01f000, 0x82000540, 0x00000001, - 0x1c01f000, 0x59340203, 0x80000540, 0x0402004b, - 0x4d300000, 0x4d2c0000, 0x5934000f, 0x80025d40, - 0x04000044, 0x0201f800, 0x00020892, 0x0400003f, - 0x592c0000, 0x4802680f, 0x80000540, 0x04020002, - 0x48026810, 0x592c2a04, 0x80081000, 0x480a6c0b, - 0x49366009, 0x492e6008, 0x82142d00, 0x000000ff, - 0x82140580, 0x00000012, 0x04000035, 0x4a026406, - 0x00000003, 0x4a026403, 0x00000040, 0x592c0406, - 0x800000c2, 0x800018c4, 0x800c0400, 0x48026206, - 0x592c0808, 0x592c1809, 0x592c020a, 0x48066017, - 0x480e6018, 0x8c000502, 0x02000000, 0x001045a1, - 0x4a026203, 0x00000004, 0x592c0207, 0x80000040, - 0x02020000, 0x00104594, 0x82140580, 0x00000018, - 0x02020000, 0x00104594, 0x592c180f, 0x59300007, + 0x8c000502, 0x04000030, 0x4a026203, 0x00000004, + 0x592c0207, 0x80000040, 0x04020020, 0x59a80005, + 0x8c000514, 0x42000000, 0x00000055, 0x04020003, + 0x42000000, 0x00000033, 0x80000040, 0x040207ff, + 0x592c0204, 0x82000500, 0x000000ff, 0x82000580, + 0x00000018, 0x04020011, 0x592c180f, 0x59300007, 0x82000540, 0x00000091, 0x480e6011, 0x48026007, 0x42000000, 0x80000004, 0x48026004, 0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400, 0x20000000, - 0x480378e1, 0x5934020b, 0x5934140b, 0x80080480, - 0x040017be, 0x0401f003, 0x4a026a03, 0x00000001, - 0x5c025800, 0x5c026000, 0x1c01f000, 0x497a5800, - 0x49325809, 0x4a026406, 0x00000006, 0x4a026203, - 0x00000007, 0x0401f802, 0x0401f7ef, 0x59a80021, - 0x800001c0, 0x02020000, 0x001045c3, 0x59a80005, - 0x8c000504, 0x02020000, 0x001045bf, 0x59340200, - 0x8c000518, 0x02020000, 0x001045bb, 0x592c0a0c, - 0x48066202, 0x4a025a06, 0x00000000, 0x8c000508, - 0x02020000, 0x001045b7, 0x4d3c0000, 0x417a7800, - 0x0201f800, 0x000207ce, 0x5c027800, 0x1c01f000, - 0x59980026, 0x497a5800, 0x80000540, 0x04020067, - 0x59d80105, 0x82000d00, 0x00018780, 0x04020197, - 0x800000f6, 0x8000013c, 0x0c01f001, 0x000202f3, - 0x0002034e, 0x00020308, 0x00020326, 0x592c0001, - 0x492fb107, 0x80000d40, 0x04020805, 0x59940019, - 0x80000540, 0x04002085, 0x1c01f000, 0x497a5801, - 0x40065800, 0x592c0001, 0x496a5800, 0x815eb800, - 0x412ed000, 0x80000d40, 0x040207f9, 0x59c80000, - 0x82000540, 0x00001200, 0x48039000, 0x1c01f000, - 0x492fb107, 0x592c0001, 0x80000d40, 0x04020ff0, - 0x59da5908, 0x835c0480, 0x00000020, 0x0400100d, - 0x0402b00b, 0x492fb007, 0x0400e7fa, 0x59d80105, - 0x82000500, 0x00018780, 0x0402016c, 0x59940019, - 0x80000540, 0x04002065, 0x1c01f000, 0x0400f009, - 0x496a5800, 0x412ed000, 0x815eb800, 0x59c80000, - 0x82000540, 0x00001200, 0x48039000, 0x0401f7ef, - 0x492fa807, 0x0401f7ed, 0x59d81108, 0x45681000, - 0x400ad000, 0x815eb800, 0x0400e7fc, 0x59c80000, - 0x82000540, 0x00001200, 0x48039000, 0x0402d009, - 0x592c0001, 0x492fb107, 0x80000d40, 0x04020fc8, - 0x59940019, 0x80000540, 0x04002048, 0x1c01f000, - 0x59d80105, 0x82000500, 0x00018780, 0x04020147, - 0x42000000, 0x0010b654, 0x0201f800, 0x0010a86e, - 0x59980026, 0x59980828, 0x80000000, 0x48033026, - 0x492f3028, 0x800409c0, 0x04000003, 0x492c0800, - 0x0401f002, 0x492f3029, 0x592c0001, 0x80000d40, - 0x04020faf, 0x0401f7e7, 0x59980026, 0x59980828, - 0x80000000, 0x48033026, 0x492f3028, 0x800409c0, - 0x04000003, 0x492c0800, 0x0401f002, 0x492f3029, - 0x592c0001, 0x80000d40, 0x04020fa1, 0x0402d00d, - 0x59980029, 0x80025d40, 0x0400000e, 0x59980026, - 0x80000040, 0x48033026, 0x04020002, 0x48033028, - 0x592c0000, 0x48033029, 0x492fb107, 0x0400d7f5, - 0x42000000, 0x0010b654, 0x0201f800, 0x0010a86e, - 0x0402e00a, 0x59da5908, 0x496a5800, 0x412ed000, - 0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540, - 0x00001200, 0x48039000, 0x59d80105, 0x82000500, - 0x00018780, 0x04020109, 0x59940019, 0x80000540, - 0x04002002, 0x1c01f000, 0x59980023, 0x48032819, + 0x480378e1, 0x1c01f000, 0x0401fe78, 0x59300007, + 0x8400054e, 0x48026007, 0x592c1a04, 0x820c1d00, + 0x000000ff, 0x820c0580, 0x00000048, 0x04000017, + 0x0401f7ec, 0x8c000500, 0x04020ecb, 0x4a026203, + 0x00000002, 0x59a80805, 0x82040500, 0x00000600, + 0x04020012, 0x42000000, 0x00000030, 0x80000040, + 0x040207ff, 0x592c1a04, 0x820c1d00, 0x000000ff, + 0x820c0580, 0x00000018, 0x040007da, 0x820c0580, + 0x00000048, 0x040207d7, 0x42000800, 0x80000804, + 0x0201f000, 0x00106721, 0x8c040d12, 0x42000000, + 0x00000010, 0x040207ee, 0x42000000, 0x00000051, + 0x0401f7eb, 0x800811c0, 0x04020003, 0x4a026a03, + 0x00000001, 0x59340010, 0x492e6810, 0x80000d40, + 0x04020003, 0x492e680f, 0x1c01f000, 0x492c0800, + 0x1c01f000, 0x83440c80, 0x00000800, 0x04021009, + 0x83440400, 0x0010ac00, 0x50000000, 0x80000540, + 0x04000004, 0x40026800, 0x80000580, 0x1c01f000, + 0x82000540, 0x00000001, 0x1c01f000, 0x59340203, + 0x80000540, 0x0402004b, 0x4d300000, 0x4d2c0000, + 0x5934000f, 0x80025d40, 0x04000044, 0x0201f800, + 0x0002075a, 0x0400003f, 0x592c0000, 0x4802680f, + 0x80000540, 0x04020002, 0x48026810, 0x592c2a04, + 0x80081000, 0x480a6c0b, 0x49366009, 0x492e6008, + 0x82142d00, 0x000000ff, 0x82140580, 0x00000012, + 0x04000035, 0x4a026406, 0x00000003, 0x4a026403, + 0x00000040, 0x592c0406, 0x800000c2, 0x800018c4, + 0x800c0400, 0x48026206, 0x592c0808, 0x592c1809, + 0x592c020a, 0x48066017, 0x480e6018, 0x8c000502, + 0x02000000, 0x0010474d, 0x4a026203, 0x00000004, + 0x592c0207, 0x80000040, 0x02020000, 0x00104740, + 0x82140580, 0x00000018, 0x02020000, 0x00104740, + 0x592c180f, 0x59300007, 0x82000540, 0x00000091, + 0x480e6011, 0x48026007, 0x42000000, 0x80000004, + 0x48026004, 0x59bc00ea, 0x8c000516, 0x040207fe, + 0x83300400, 0x20000000, 0x480378e1, 0x5934020b, + 0x5934140b, 0x80080480, 0x040017be, 0x0401f003, + 0x4a026a03, 0x00000001, 0x5c025800, 0x5c026000, + 0x1c01f000, 0x497a5800, 0x49325809, 0x4a026406, + 0x00000006, 0x4a026203, 0x00000007, 0x0401f802, + 0x0401f7ef, 0x59a80021, 0x800001c0, 0x02020000, + 0x0010476f, 0x59a80005, 0x8c000504, 0x02020000, + 0x0010476b, 0x59340200, 0x8c000518, 0x02020000, + 0x00104767, 0x592c0a0c, 0x48066202, 0x4a025a06, + 0x00000000, 0x8c000508, 0x02020000, 0x00104763, + 0x4d3c0000, 0x417a7800, 0x0401fbdf, 0x5c027800, 0x1c01f000, 0x592c0404, 0x8c00051e, 0x02020000, - 0x00104b7b, 0x59980022, 0x80000540, 0x0402075d, - 0x59980026, 0x497a5800, 0x80000540, 0x02020000, - 0x00104ba6, 0x59d80105, 0x82000d00, 0x00018780, - 0x040200f2, 0x800000f6, 0x8000013c, 0x0c01f001, - 0x00020398, 0x00104ba6, 0x0002039d, 0x000203e6, - 0x592c0001, 0x492fb107, 0x80000d40, 0x04020760, - 0x1c01f000, 0x592c0001, 0x492fb107, 0x80000d40, - 0x04020f5b, 0x59da5908, 0x835c0480, 0x00000020, - 0x0400102b, 0x0402b033, 0x492fb007, 0x0400e7fa, - 0x59d80105, 0x82000500, 0x00018780, 0x040200d7, - 0x0400601f, 0x59d8010a, 0x59d8090a, 0x80040580, - 0x040207fd, 0x800408e0, 0x599c1017, 0x8c081508, - 0x04020028, 0x82040d40, 0x00000013, 0x5998002b, - 0x4807c011, 0x84000500, 0x4803302b, 0x59e00017, - 0x8c000508, 0x04020004, 0x4203e000, 0x30000001, - 0x1c01f000, 0x4a03c017, 0x00000003, 0x82040500, - 0x000000ff, 0x82000580, 0x0000001d, 0x040207f7, - 0x4a03c017, 0x0000000d, 0x0401f7f4, 0x5998082b, - 0x84040d40, 0x4807302b, 0x1c01f000, 0x496a5800, - 0x412ed000, 0x815eb800, 0x59c80000, 0x82000540, - 0x00001200, 0x48039000, 0x0400e7cb, 0x0401f7d1, - 0x0402f7f7, 0x492fa807, 0x0400e7c7, 0x0401f7cd, - 0x59e0000f, 0x59e0100f, 0x80081580, 0x040207fd, - 0x81281580, 0x040007d4, 0x40025000, 0x82040d40, - 0x0000001d, 0x0401f7d2, 0x59d80908, 0x45680800, - 0x4006d000, 0x815eb800, 0x0400e7fc, 0x59c80000, - 0x82000540, 0x00001200, 0x48039000, 0x02006000, - 0x00104b8d, 0x59d8010a, 0x59d8090a, 0x80040d80, - 0x040207fd, 0x900001c0, 0x82000540, 0x00000013, - 0x4803c011, 0x5998002b, 0x84000500, 0x4803302b, - 0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017, - 0x00000003, 0x4203e000, 0x30000001, 0x59d80105, - 0x82000500, 0x00018780, 0x0402007c, 0x0202d000, - 0x00104b92, 0x592c0001, 0x492fb107, 0x80000d40, - 0x040206ef, 0x1c01f000, 0x59980020, 0x0c01f001, - 0x00020413, 0x00020414, 0x00020434, 0x1c01f000, - 0x4df00000, 0x4203e000, 0x50000000, 0x04026876, - 0x04006004, 0x599c0017, 0x8c000508, 0x040208f5, - 0x59980029, 0x80025d40, 0x0400000a, 0x0402d00b, - 0x59980026, 0x80000040, 0x48033026, 0x592c0000, - 0x492fb107, 0x48033029, 0x04020002, 0x48033028, - 0x5c03e000, 0x1c01f000, 0x59d80105, 0x82000500, - 0x00018780, 0x04020055, 0x42000000, 0x0010b654, - 0x0201f800, 0x0010a86e, 0x5c03e000, 0x1c01f000, - 0x4df00000, 0x4203e000, 0x50000000, 0x599cb817, - 0x59940019, 0x80000540, 0x04002023, 0x0400000e, - 0x59980022, 0x82000580, 0x00000005, 0x0400001e, - 0x59a80069, 0x81640580, 0x0402001b, 0x8c5cbd08, - 0x04000007, 0x59a8006a, 0x59a80866, 0x80040580, - 0x04020015, 0x8c5cbd08, 0x0402002b, 0x59d8090b, - 0x59d8010a, 0x80040580, 0x0400000d, 0x0400600e, - 0x4a03c011, 0x80400012, 0x4a03c020, 0x00008040, - 0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017, - 0x00000002, 0x4203e000, 0x30000001, 0x4a032819, - 0xffff0000, 0x0400e879, 0x04006003, 0x8c5cbd08, - 0x0402088e, 0x59980029, 0x80025d40, 0x04020003, - 0x5c03e000, 0x1c01f000, 0x59d80105, 0x82000500, - 0x00018780, 0x04020019, 0x0202d000, 0x00104c06, - 0x59980826, 0x592c0000, 0x80040840, 0x48073026, - 0x492fb107, 0x48033029, 0x040207f2, 0x48033028, - 0x0401f7f0, 0x59e0000f, 0x59e0080f, 0x80040580, - 0x040207fd, 0x59e00010, 0x59e01010, 0x80081580, - 0x040207fd, 0x40065000, 0x80041580, 0x040007cc, - 0x040067e1, 0x0401f7cf, 0x4803c857, 0x485fc857, - 0x8c00050e, 0x02020800, 0x0010060d, 0x4203e000, - 0x50000000, 0x4200b800, 0x00008004, 0x0201f000, - 0x0010061a, 0x5998002b, 0x8c000500, 0x04020039, - 0x0400e006, 0x59d80105, 0x82000500, 0x00018780, - 0x040207ee, 0x1c01f000, 0x59da5908, 0x835c0c80, - 0x00000020, 0x04001003, 0x0400b028, 0x0400f02a, - 0x496a5800, 0x412ed000, 0x815eb800, 0x59c80000, - 0x82000540, 0x00001200, 0x48039000, 0x0400e7f3, + 0x00104ce4, 0x59980022, 0x80000540, 0x04000017, + 0x592c0a06, 0x592c0409, 0x80040540, 0x04020013, + 0x0201f000, 0x00104cfa, 0x592c0404, 0x8c00051e, + 0x02020000, 0x00104cf3, 0x59980022, 0x80000540, + 0x0400000a, 0x82040580, 0x00000001, 0x04020007, + 0x0201f000, 0x00104cfa, 0x592c0404, 0x8c00051e, + 0x02020000, 0x00104dca, 0x59980026, 0x497a5800, + 0x80000540, 0x02020000, 0x00104e1d, 0x59d80105, + 0x82000d00, 0x00018780, 0x02020000, 0x00104edb, + 0x80000106, 0x82000500, 0x00000003, 0x0c01f001, + 0x000202f0, 0x00104e1d, 0x000202f6, 0x00020341, + 0x592c0001, 0x492fb107, 0x80000d40, 0x02020000, + 0x00104ddb, 0x1c01f000, 0x592c0001, 0x492fb107, + 0x80000d40, 0x02020000, 0x00104de8, 0x59da5908, + 0x835c0480, 0x00000020, 0x0400102c, 0x0402b034, + 0x492fb007, 0x0400e7fa, 0x59d80105, 0x82000500, + 0x00018780, 0x02020000, 0x00104edb, 0x0400601f, 0x59d8010a, 0x59d8090a, 0x80040580, 0x040207fd, - 0x800408e0, 0x599c1017, 0x8c081508, 0x04020021, - 0x82040d40, 0x00000013, 0x4807c011, 0x59e00017, - 0x8c000508, 0x0400000a, 0x4a03c017, 0x00000003, - 0x82040500, 0x000000ff, 0x82000580, 0x0000001d, - 0x04020003, 0x4a03c017, 0x0000000d, 0x4203e000, - 0x30000001, 0x59d80105, 0x82000500, 0x00018780, - 0x040207c2, 0x1c01f000, 0x492fb007, 0x0400e7d3, - 0x0401f7e0, 0x492fa807, 0x0400e7d0, 0x0401f7dd, - 0x84000500, 0x4803302b, 0x0400e7cc, 0x0401f7d9, - 0x59e0000f, 0x59e0100f, 0x80081580, 0x040207fd, - 0x81281580, 0x040007db, 0x40025000, 0x82040d40, - 0x0000001d, 0x0401f7d9, 0x59da5908, 0x496a5800, - 0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000, - 0x82000540, 0x00001200, 0x48039000, 0x59d8090b, - 0x59980024, 0x48073024, 0x80040480, 0x04020004, - 0x59940019, 0x80000540, 0x04022003, 0x59980823, - 0x48072819, 0x59d80105, 0x82000500, 0x00018780, - 0x04020796, 0x1c01f000, 0x59981025, 0x59e00010, - 0x59e00810, 0x80041d80, 0x040207fd, 0x80080580, - 0x04000011, 0x48073025, 0x59e0000f, 0x59e0100f, - 0x80081d80, 0x040207fd, 0x81280580, 0x04000006, - 0x400a5000, 0x40080000, 0x80040580, 0x0402067f, - 0x1c01f000, 0x59940019, 0x80000540, 0x040227fa, - 0x1c01f000, 0x59e0000f, 0x59e0100f, 0x80081d80, - 0x040207fd, 0x81280580, 0x040007f6, 0x400a5000, - 0x59940019, 0x80000540, 0x040027ef, 0x1c01f000, - 0x59e0000f, 0x59e0100f, 0x80080d80, 0x040207fd, - 0x81280580, 0x04020002, 0x1c01f000, 0x400a5000, - 0x900811c0, 0x82081540, 0x0000001c, 0x480bc011, - 0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017, - 0x0000000c, 0x4203e000, 0x30000001, 0x1c01f000, - 0x41700000, 0x0c01f001, 0x001050f0, 0x0002052f, - 0x001050f0, 0x001050f1, 0x001050ee, 0x001050ee, - 0x001050ee, 0x001050ee, 0x00105594, 0x04010037, - 0x59980006, 0x80000540, 0x0402003c, 0x0402c01c, - 0x4202f800, 0x00000010, 0x4df00000, 0x4203e000, - 0x50000000, 0x49db3005, 0x59da5808, 0x592c0204, - 0x497a5800, 0x497a5801, 0x82000500, 0x000000ff, - 0x82000c80, 0x00000079, 0x04021036, 0x0c01f839, - 0x5c03e000, 0x817ef840, 0x04000009, 0x836c0580, - 0x00000003, 0x04020006, 0x83700580, 0x00000001, - 0x04020010, 0x0401001b, 0x0400c7e8, 0x0400f94b, - 0x0400b135, 0x59d40005, 0x82000500, 0x43018780, - 0x02020000, 0x00105523, 0x59d80005, 0x82000500, - 0x43018780, 0x02020000, 0x0010552a, 0x1c01f000, - 0x83700580, 0x00000003, 0x02000800, 0x001050f1, - 0x83700580, 0x00000001, 0x040207ed, 0x04010005, - 0x0400c7d2, 0x0401f7ea, 0x4202f800, 0x00000010, - 0x4df00000, 0x4203e000, 0x50000000, 0x49d73005, - 0x59d65808, 0x0401f7ce, 0x4df00000, 0x4203e000, - 0x50000000, 0x40025800, 0x592c0204, 0x497b3005, - 0x497b3006, 0x4202f800, 0x00000010, 0x0401f7c7, - 0x0201f800, 0x00105161, 0x5c03e000, 0x0401f7d4, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105207, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105171, 0x00105161, - 0x00105161, 0x00105161, 0x00105231, 0x00105161, - 0x00105161, 0x00105161, 0x00020623, 0x00105161, - 0x00105398, 0x00105161, 0x00105161, 0x00105161, - 0x000205f5, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105199, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x001054b7, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105502, 0x00105161, 0x0010518b, - 0x00105161, 0x0010547b, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105449, 0x00105161, 0x00105449, - 0x00105556, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105409, 0x00105539, - 0x00105161, 0x00105549, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x00105161, 0x00105161, 0x00105161, - 0x00105161, 0x592c0204, 0x80000110, 0x80000040, - 0x0400000b, 0x02001000, 0x00105169, 0x48033002, - 0x492f3003, 0x492f3004, 0x4a033008, 0x00020603, - 0x4202e000, 0x00000003, 0x1c01f000, 0x592c0406, - 0x82000c80, 0x0000199a, 0x02021000, 0x00105179, - 0x59a80021, 0x80000540, 0x02020000, 0x001051a7, - 0x592e8a06, 0x83440c80, 0x000007f0, 0x02021000, - 0x00105179, 0x83440400, 0x0010aa00, 0x50000000, - 0x80026d40, 0x02000000, 0x001051bb, 0x59340002, - 0x592c0810, 0x80040580, 0x82000500, 0x00ffffff, - 0x02020000, 0x00105179, 0x0201f800, 0x000201ee, - 0x02020000, 0x001051be, 0x1c01f000, 0x592c0204, - 0x80000110, 0x02000000, 0x00105169, 0x80000040, + 0x800408e0, 0x599c1017, 0x8c081508, 0x04020028, + 0x82040d40, 0x00000013, 0x5998002b, 0x4807c011, + 0x84000500, 0x4803302b, 0x59e00017, 0x8c000508, + 0x04020004, 0x4203e000, 0x30000001, 0x1c01f000, + 0x4a03c017, 0x00000003, 0x82040500, 0x000000ff, + 0x82000580, 0x0000001d, 0x040207f7, 0x4a03c017, + 0x0000000d, 0x0401f7f4, 0x5998082b, 0x84040d40, + 0x4807302b, 0x1c01f000, 0x496a5800, 0x412ed000, + 0x815eb800, 0x59c80000, 0x82000540, 0x00001200, + 0x48039000, 0x0400e7ca, 0x0401f7d0, 0x0402f7f7, + 0x492fa807, 0x0400e7c6, 0x0401f7cc, 0x59e0000f, + 0x59e0100f, 0x80081580, 0x040207fd, 0x81281580, + 0x040007d4, 0x40025000, 0x82040d40, 0x0000001d, + 0x0401f7d2, 0x59d80908, 0x45680800, 0x4006d000, + 0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540, + 0x00001200, 0x48039000, 0x02006000, 0x00104df8, + 0x59d8010a, 0x59d8090a, 0x80040d80, 0x040207fd, + 0x900001c0, 0x82000540, 0x00000013, 0x4803c011, + 0x5998002b, 0x84000500, 0x4803302b, 0x59e00017, + 0x8c000508, 0x04000003, 0x4a03c017, 0x00000003, + 0x4203e000, 0x30000001, 0x59d80105, 0x82000500, + 0x00018780, 0x02020000, 0x00104edb, 0x0202d000, + 0x00104dfd, 0x592c0001, 0x492fb107, 0x80000d40, + 0x02020000, 0x00104e10, 0x1c01f000, 0x59980020, + 0x0c01f001, 0x00020370, 0x00020371, 0x00104e88, + 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, + 0x0402681e, 0x04006004, 0x599c0017, 0x8c000508, + 0x04020865, 0x59980029, 0x80025d40, 0x0400000a, + 0x0402d00b, 0x59980026, 0x80000040, 0x48033026, + 0x592c0000, 0x492fb107, 0x48033029, 0x04020002, + 0x48033028, 0x5c03e000, 0x1c01f000, 0x59d80105, + 0x82000500, 0x00018780, 0x02020000, 0x00104edb, + 0x42000000, 0x0010b855, 0x0201f800, 0x0010aa47, + 0x5c03e000, 0x1c01f000, 0x5998002b, 0x8c000500, + 0x0402003b, 0x0400e007, 0x59d80105, 0x82000500, + 0x00018780, 0x02020000, 0x00104edb, 0x1c01f000, + 0x59da5908, 0x835c0c80, 0x00000020, 0x04001003, + 0x0400b029, 0x0400f02b, 0x496a5800, 0x412ed000, + 0x815eb800, 0x59c80000, 0x82000540, 0x00001200, + 0x48039000, 0x0400e7f3, 0x59d8010a, 0x59d8090a, + 0x80040580, 0x040207fd, 0x800408e0, 0x599c1017, + 0x8c081508, 0x04020022, 0x82040d40, 0x00000013, + 0x4807c011, 0x59e00017, 0x8c000508, 0x0400000a, + 0x4a03c017, 0x00000003, 0x82040500, 0x000000ff, + 0x82000580, 0x0000001d, 0x04020003, 0x4a03c017, + 0x0000000d, 0x4203e000, 0x30000001, 0x59d80105, + 0x82000500, 0x00018780, 0x02020000, 0x00104edb, + 0x1c01f000, 0x492fb007, 0x0400e7d2, 0x0401f7df, + 0x492fa807, 0x0400e7cf, 0x0401f7dc, 0x84000500, + 0x4803302b, 0x0400e7cb, 0x0401f7d8, 0x59e0000f, + 0x59e0100f, 0x80081580, 0x040207fd, 0x81281580, + 0x040007da, 0x40025000, 0x82040d40, 0x0000001d, + 0x0401f7d8, 0x59e0000f, 0x59e0100f, 0x80080d80, + 0x040207fd, 0x81280580, 0x04020002, 0x1c01f000, + 0x400a5000, 0x900811c0, 0x82081540, 0x0000001c, + 0x480bc011, 0x59e00017, 0x8c000508, 0x04000003, + 0x4a03c017, 0x0000000c, 0x4203e000, 0x30000001, + 0x1c01f000, 0x41700000, 0x0c01f001, 0x00105420, + 0x000203fc, 0x00105420, 0x00105421, 0x0010541e, + 0x0010541e, 0x0010541e, 0x0010541e, 0x001058b0, + 0x04010037, 0x59980006, 0x80000540, 0x0402003c, + 0x0402c01c, 0x4202f800, 0x00000010, 0x4df00000, + 0x4203e000, 0x50000000, 0x49db3005, 0x59da5808, + 0x592c0204, 0x497a5800, 0x497a5801, 0x82000500, + 0x000000ff, 0x82000c80, 0x00000079, 0x04021036, + 0x0c01f839, 0x5c03e000, 0x817ef840, 0x04000009, + 0x836c0580, 0x00000003, 0x04020006, 0x83700580, + 0x00000001, 0x04020010, 0x0401001b, 0x0400c7e8, + 0x0400f94a, 0x0400b134, 0x59d40005, 0x82000500, + 0x43018780, 0x02020000, 0x0010583f, 0x59d80005, + 0x82000500, 0x43018780, 0x02020000, 0x00105846, + 0x1c01f000, 0x83700580, 0x00000003, 0x02000800, + 0x00105421, 0x83700580, 0x00000001, 0x040207ed, + 0x04010005, 0x0400c7d2, 0x0401f7ea, 0x4202f800, + 0x00000010, 0x4df00000, 0x4203e000, 0x50000000, + 0x49d73005, 0x59d65808, 0x0401f7ce, 0x4df00000, + 0x4203e000, 0x50000000, 0x40025800, 0x592c0204, + 0x497b3005, 0x497b3006, 0x4202f800, 0x00000010, + 0x0401f7c7, 0x0201f800, 0x00105491, 0x5c03e000, + 0x0401f7d4, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105527, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x001054a1, + 0x00105491, 0x00105491, 0x00105491, 0x00105551, + 0x00105491, 0x00105491, 0x00105491, 0x000204ef, + 0x00105491, 0x001056b4, 0x00105491, 0x00105491, + 0x00105491, 0x000204c2, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x001054c9, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x001057d3, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x0010581e, 0x00105491, + 0x001054bb, 0x00105491, 0x00105797, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105765, 0x00105491, + 0x00105765, 0x00105872, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105725, + 0x00105855, 0x00105491, 0x00105865, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x00105491, 0x00105491, + 0x00105491, 0x00105491, 0x592c0204, 0x80000110, + 0x02000000, 0x00105499, 0x80000040, 0x04000009, + 0x48033002, 0x492f3003, 0x492f3004, 0x4a033008, + 0x000204d0, 0x4202e000, 0x00000003, 0x1c01f000, + 0x592c0406, 0x82000c80, 0x0000199a, 0x02021000, + 0x001054a9, 0x59a80021, 0x80000540, 0x02020000, + 0x001054d7, 0x592e8a06, 0x83440c80, 0x000007f0, + 0x02021000, 0x001054a9, 0x83440400, 0x0010ac00, + 0x50000000, 0x80026d40, 0x02000000, 0x001054db, + 0x59340002, 0x592c0810, 0x80040580, 0x82000500, + 0x00ffffff, 0x02020000, 0x001054a9, 0x0401fccf, + 0x02020000, 0x001054de, 0x1c01f000, 0x592c0204, + 0x80000110, 0x02000000, 0x00105499, 0x80000040, 0x0402000b, 0x592c040a, 0x8c000504, 0x04000010, 0x592c0207, 0x82000c80, 0x00001001, 0x02021000, - 0x00105179, 0x0201f000, 0x0010556e, 0x48033002, - 0x492f3003, 0x492f3004, 0x4a033008, 0x0002063b, + 0x001054a9, 0x0201f000, 0x0010588a, 0x48033002, + 0x492f3003, 0x492f3004, 0x4a033008, 0x00020507, 0x4202e000, 0x00000003, 0x1c01f000, 0x592c0406, - 0x82000c80, 0x0000199a, 0x02021000, 0x00105179, - 0x592e8a06, 0x417a7800, 0x0401fc25, 0x02020000, - 0x0010533c, 0x59340002, 0x592c0808, 0x80040580, - 0x82000500, 0x00ffffff, 0x02020000, 0x00105179, + 0x82000c80, 0x0000199a, 0x02021000, 0x001054a9, + 0x592e8a06, 0x417a7800, 0x0401fd37, 0x02020000, + 0x00105658, 0x59340002, 0x592c0808, 0x80040580, + 0x82000500, 0x00ffffff, 0x02020000, 0x001054a9, 0x497a5808, 0x592e6009, 0x83300580, 0xffffffff, - 0x02000000, 0x001052fc, 0x83300480, 0x0010cfc0, - 0x02001000, 0x00105359, 0x59a8000b, 0x81300480, - 0x02021000, 0x00105359, 0x592c240a, 0x49366009, - 0x8c10251c, 0x02020000, 0x001052ea, 0x59a80068, - 0x8c000510, 0x02020000, 0x00105372, 0x59a80821, - 0x800409c0, 0x02020000, 0x001052d0, 0x59a80805, - 0x8c040d04, 0x02020000, 0x00105363, 0x59340200, - 0x8c000518, 0x02020000, 0x00105354, 0x59300c06, - 0x82040580, 0x00000006, 0x02020000, 0x001052f4, - 0x59300414, 0x8c000516, 0x02020000, 0x0010535e, - 0x8c102508, 0x02020000, 0x0010a3d7, 0x59300808, + 0x02000000, 0x00105618, 0x83300480, 0x0010d1c0, + 0x02001000, 0x00105675, 0x59a8000b, 0x81300480, + 0x02021000, 0x00105675, 0x592c240a, 0x49366009, + 0x8c10251c, 0x02020000, 0x00105606, 0x59a80068, + 0x8c000510, 0x02020000, 0x0010568e, 0x59a80821, + 0x800409c0, 0x02020000, 0x001055ec, 0x59a80805, + 0x8c040d04, 0x02020000, 0x0010567f, 0x59340200, + 0x8c000518, 0x02020000, 0x00105670, 0x59300c06, + 0x82040580, 0x00000006, 0x02020000, 0x00105610, + 0x59300414, 0x8c000516, 0x02020000, 0x0010567a, + 0x8c102508, 0x02020000, 0x0010a5b8, 0x59300808, 0x4a025a06, 0x00000000, 0x800409c0, 0x02020000, - 0x001052cb, 0x592c0a0c, 0x48066202, 0x492e6008, - 0x0401f14a, 0x4df00000, 0x4203e000, 0x50000000, + 0x001055e7, 0x592c0a0c, 0x48066202, 0x492e6008, + 0x0401f14d, 0x4df00000, 0x4203e000, 0x50000000, 0x0402b00b, 0x835c0480, 0x00000020, 0x0400100d, 0x815eb840, 0x416a5800, 0x592ed000, 0x492fb007, 0x497a5800, 0x497a5801, 0x0400b7f7, 0x59d80005, - 0x82000500, 0x43018780, 0x02020000, 0x0010552a, + 0x82000500, 0x43018780, 0x02020000, 0x00105846, 0x5c03e000, 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, 0x0402f00b, 0x835c0480, 0x00000020, 0x0400100d, 0x815eb840, 0x416a5800, 0x592ed000, 0x492fa807, 0x497a5800, 0x497a5801, 0x0400f7f7, 0x59d40005, 0x82000500, 0x43018780, 0x02020000, - 0x00105523, 0x5c03e000, 0x1c01f000, 0x4df00000, + 0x0010583f, 0x5c03e000, 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, 0x59940024, 0x80000540, - 0x0400010f, 0x4c000000, 0x42000000, 0x00001000, + 0x04000112, 0x4c000000, 0x42000000, 0x00001000, 0x50000000, 0x82000480, 0x24320001, 0x04020015, 0x42000800, 0x00000064, 0x80040840, 0x04000007, 0x4a030000, 0x00000001, 0x40000000, 0x59800000, @@ -11356,7 +11397,7 @@ uint32_t risc_code02[] = { 0x483fc857, 0x59e40852, 0x59a80025, 0x80040580, 0x04000004, 0x480bc857, 0x59e40052, 0x48035025, 0x59940026, 0x803c0400, 0x48032826, 0x0201f800, - 0x00105d5a, 0x59940000, 0x82000580, 0x00000000, + 0x00106021, 0x59940000, 0x82000580, 0x00000000, 0x04020006, 0x59940026, 0x48032827, 0x497b2826, 0x4a032800, 0x00000001, 0x4c0c0000, 0x59940007, 0x80000d40, 0x0400001d, 0x59941006, 0x59940025, @@ -11377,54 +11418,54 @@ uint32_t risc_code02[] = { 0x0000000a, 0x48007800, 0x040027fa, 0x82040500, 0x0000007f, 0x0401f7e8, 0x583c0002, 0x4c3c0000, 0x0801f800, 0x5c007800, 0x0401f7e3, 0x5c023000, - 0x59940019, 0x80001540, 0x04000007, 0x04002006, - 0x59940025, 0x80080480, 0x04021002, 0x80000580, - 0x48032819, 0x5994001c, 0x80000d40, 0x04000013, - 0x5994101b, 0x59940025, 0x80080480, 0x04001005, - 0x04000004, 0x4803281b, 0x80000040, 0x0402100b, - 0x80040840, 0x4807281c, 0x04020004, 0x5994001d, + 0x59940019, 0x80001540, 0x04000008, 0x04002007, + 0x59940025, 0x80080480, 0x497b2819, 0x04001003, + 0x04000002, 0x48032819, 0x59940004, 0x80000d40, + 0x0400002a, 0x4c040000, 0x5994001c, 0x80000d40, + 0x04000013, 0x5994101b, 0x59940025, 0x80080480, + 0x04001005, 0x04000004, 0x4803281b, 0x80000040, + 0x0402100b, 0x80040840, 0x4807281c, 0x04020004, + 0x5994001d, 0x0801f800, 0x0401f005, 0x82000400, + 0x0000000a, 0x4803281b, 0x040027f7, 0x5c000800, + 0x59941003, 0x59940025, 0x80080480, 0x04001005, + 0x04000004, 0x48032803, 0x80000040, 0x0402100b, + 0x80040840, 0x48072804, 0x04020004, 0x59940005, 0x0801f800, 0x0401f005, 0x82000400, 0x0000000a, - 0x4803281b, 0x040027f7, 0x59940004, 0x80000d40, - 0x04000013, 0x59941003, 0x59940025, 0x80080480, - 0x04001005, 0x04000004, 0x48032803, 0x80000040, - 0x0402100b, 0x80040840, 0x48072804, 0x04020004, - 0x59940005, 0x0801f800, 0x0401f005, 0x82000400, - 0x0000000a, 0x48032803, 0x040027f7, 0x5994001f, - 0x80000d40, 0x04000013, 0x5994101e, 0x59940025, - 0x80080480, 0x04001005, 0x04000004, 0x4803281e, - 0x80000040, 0x0402100b, 0x80040840, 0x4807281f, - 0x04020004, 0x59940020, 0x0801f800, 0x0401f005, - 0x82000400, 0x00000001, 0x4803281e, 0x040027f7, - 0x59940022, 0x80000d40, 0x04000013, 0x59941021, - 0x59940025, 0x80080480, 0x04001005, 0x04000004, - 0x48032821, 0x80000040, 0x0402100b, 0x80040840, - 0x48072822, 0x04020004, 0x59940023, 0x0801f800, - 0x0401f005, 0x82000400, 0x0000000a, 0x48032821, - 0x040027f7, 0x59940824, 0x59940025, 0x80040480, - 0x02001800, 0x00100615, 0x48032824, 0x59940000, - 0x0c01f001, 0x00105cee, 0x00105cf0, 0x00105d16, - 0x59940024, 0x80000000, 0x48032824, 0x4203e000, - 0x70000000, 0x1c01f000, 0x592c0406, 0x800000c2, - 0x800008c4, 0x80040c00, 0x592c040a, 0x48066206, - 0x82000d00, 0x00000003, 0x02000000, 0x00105e97, - 0x8c000500, 0x0402002c, 0x59a80872, 0x80040840, - 0x040207ff, 0x8c00051e, 0x02000000, 0x00105e72, - 0x82000d00, 0x000000c0, 0x02020000, 0x00105e68, - 0x82000d00, 0x00002020, 0x02020000, 0x00105e65, - 0x813e79c0, 0x02020000, 0x00105e65, 0x592c0c0c, - 0x800409c0, 0x02020000, 0x00105e65, 0x59300a03, - 0x82040d80, 0x00000007, 0x02020000, 0x00105e65, + 0x48032803, 0x040027f7, 0x5994001f, 0x80000d40, + 0x04000013, 0x5994101e, 0x59940025, 0x80080480, + 0x04001005, 0x04000004, 0x4803281e, 0x80000040, + 0x0402100b, 0x80040840, 0x4807281f, 0x04020004, + 0x59940020, 0x0801f800, 0x0401f005, 0x82000400, + 0x00000001, 0x4803281e, 0x040027f7, 0x59940022, + 0x80000d40, 0x04000013, 0x59941021, 0x59940025, + 0x80080480, 0x04001005, 0x04000004, 0x48032821, + 0x80000040, 0x0402100b, 0x80040840, 0x48072822, + 0x04020004, 0x59940023, 0x0801f800, 0x0401f005, + 0x82000400, 0x0000000a, 0x48032821, 0x040027f7, + 0x59940824, 0x59940025, 0x80040480, 0x02001800, + 0x001005d8, 0x48032824, 0x59940000, 0x0c01f001, + 0x00105fb5, 0x00105fb7, 0x00105fdd, 0x59940024, + 0x80000000, 0x48032824, 0x4203e000, 0x70000000, + 0x1c01f000, 0x592c0406, 0x800000c2, 0x800008c4, + 0x80040c00, 0x592c040a, 0x48066206, 0x82000d00, + 0x00000003, 0x02000000, 0x0010615e, 0x8c000500, + 0x04020029, 0x8c00051e, 0x02000000, 0x00106139, + 0x82000d00, 0x000000c0, 0x02020000, 0x0010612f, + 0x82000d00, 0x00002020, 0x02020000, 0x0010612c, + 0x813e79c0, 0x02020000, 0x0010612c, 0x592c0c0c, + 0x800409c0, 0x02020000, 0x0010612c, 0x59300a03, + 0x82040d80, 0x00000007, 0x02020000, 0x0010612c, 0x4a026203, 0x00000003, 0x4a026403, 0x00000043, - 0x0201f800, 0x000200ca, 0x82080d40, 0x80003465, + 0x0201f800, 0x000200c9, 0x82080d40, 0x80003465, 0x48066004, 0x497a6000, 0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400, 0xa0000000, 0x480378e1, - 0x1c01f000, 0x8c000502, 0x02020000, 0x00105eba, + 0x1c01f000, 0x8c000502, 0x02020000, 0x00106181, 0x8c00051e, 0x0400000e, 0x82000d00, 0x000000c0, 0x04000005, 0x82040d80, 0x000000c0, 0x02020000, - 0x00105ebf, 0x82000d00, 0x00002020, 0x82040d80, - 0x00002020, 0x02000000, 0x00105e86, 0x592c0207, - 0x80000040, 0x02020000, 0x00105e90, 0x592c180d, - 0x800c19c0, 0x02020000, 0x00105e90, 0x592c180f, + 0x00106186, 0x82000d00, 0x00002020, 0x82040d80, + 0x00002020, 0x02000000, 0x0010614d, 0x592c0207, + 0x80000040, 0x02020000, 0x00106157, 0x592c180d, + 0x800c19c0, 0x02020000, 0x00106157, 0x592c180f, 0x59300007, 0x82000540, 0x00000011, 0x480e6011, 0x48026007, 0x4a026203, 0x00000004, 0x4a026403, 0x00000042, 0x42000800, 0x80002001, 0x0401f02a, @@ -11432,915 +11473,904 @@ uint32_t risc_code02[] = { 0x0401f003, 0x42000800, 0x00000001, 0x59325808, 0x832c0500, 0x00ff0000, 0x0400000d, 0x592c0000, 0x48065a06, 0x48026008, 0x592c040a, 0x8c000510, - 0x04020008, 0x0201f800, 0x00020381, 0x417a7800, - 0x59300008, 0x80025d40, 0x0402078c, 0x1c01f000, + 0x04020008, 0x0201f800, 0x000202ce, 0x417a7800, + 0x59300008, 0x80025d40, 0x0402078f, 0x1c01f000, 0x456a5800, 0x412ed000, 0x815eb800, 0x59c80000, 0x82000540, 0x00001200, 0x48039000, 0x0401f7f4, 0x59840000, 0x80000540, 0x04020002, 0x1c01f000, - 0x59840003, 0x80000540, 0x02020000, 0x00105f37, - 0x1c01f000, 0x59300004, 0x82000500, 0x00000100, - 0x80040d40, 0x48066004, 0x59bc00ea, 0x8c000516, + 0x59840003, 0x80000540, 0x02020000, 0x001061fe, + 0x1c01f000, 0x48066004, 0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400, 0x40000000, 0x480378e1, 0x1c01f000, 0x59bc00ea, 0x82001500, 0xb0000018, - 0x02020000, 0x001069c6, 0x8c000510, 0x0400002a, + 0x02020000, 0x00106c81, 0x8c000510, 0x0400002a, 0x59bc10e0, 0x82080500, 0xfffff000, 0x0402000a, 0x80080108, 0x820a3500, 0x0000000f, 0x4803c857, - 0x1201f000, 0x001069cc, 0x84000510, 0x48026004, + 0x1201f000, 0x00106c87, 0x84000510, 0x48026004, 0x0401f016, 0x840a653e, 0x59300004, 0x8c000520, 0x040007fa, 0x82000500, 0xfffefeff, 0x48026004, 0x8c08153e, 0x04020005, 0x42027000, 0x00000013, - 0x0401f858, 0x0401f009, 0x59300004, 0x8c000514, - 0x04000003, 0x0401ffac, 0x0401f02e, 0x42027000, - 0x00000049, 0x0401f84f, 0x59bc00ea, 0x82001500, - 0xb0000018, 0x02020000, 0x001069c6, 0x8c000510, + 0x0401f859, 0x0401f009, 0x59300004, 0x8c000514, + 0x04000003, 0x0401ffb0, 0x0401f02f, 0x42027000, + 0x00000049, 0x0401f850, 0x59bc00ea, 0x82001500, + 0xb0000018, 0x02020000, 0x00106c81, 0x8c000510, 0x040207d8, 0x1c01f000, 0x83640480, 0x00000010, - 0x04001019, 0x41626000, 0x41580000, 0x59300a03, + 0x0400101a, 0x41626000, 0x41580000, 0x59300a03, 0x82040d80, 0x00000000, 0x04000008, 0x83326400, 0x00000024, 0x81300c80, 0x040017f9, 0x42026000, - 0x0010cfc0, 0x0401f7f6, 0x4a026203, 0x00000008, - 0x8166c840, 0x8332c400, 0x00000024, 0x81600480, - 0x04021002, 0x1c01f000, 0x837ac540, 0x0010cfc0, - 0x1c01f000, 0x42000000, 0x0010b653, 0x0201f800, - 0x0010a86e, 0x4967c857, 0x80026580, 0x1c01f000, - 0x83300480, 0x0010cfc0, 0x02001800, 0x00100615, - 0x41580000, 0x81300480, 0x0402100c, 0x04011000, + 0x0010d1c0, 0x0401f7f6, 0x8166c840, 0x83300c00, + 0x00000024, 0x80040480, 0x04021005, 0x4006c000, + 0x4a026203, 0x00000008, 0x1c01f000, 0x837ac540, + 0x0010d1c0, 0x0401f7fb, 0x42000000, 0x0010b854, + 0x0201f800, 0x0010aa47, 0x4967c857, 0x80026580, + 0x1c01f000, 0x83300480, 0x0010d1c0, 0x02001800, + 0x001005d8, 0x41580000, 0x81300480, 0x0402100c, + 0x04011000, 0x457a6000, 0x4a026202, 0x0000ffff, + 0x83300400, 0x00000003, 0x4803c840, 0x4a03c842, + 0x00000021, 0x8166c800, 0x1c01f000, 0x41540000, + 0x81300480, 0x02021800, 0x001005d8, 0x04011000, 0x457a6000, 0x4a026202, 0x0000ffff, 0x83300400, 0x00000003, 0x4803c840, 0x4a03c842, 0x00000021, - 0x8166c800, 0x1c01f000, 0x41540000, 0x81300480, - 0x02021800, 0x00100615, 0x04011000, 0x457a6000, - 0x4a026202, 0x0000ffff, 0x83300400, 0x00000003, - 0x4803c840, 0x4a03c842, 0x00000021, 0x59a80066, - 0x49335065, 0x80000000, 0x48035066, 0x1c01f000, - 0x4d340000, 0x59326809, 0x59300406, 0x82000500, - 0x0000001f, 0x0c01f803, 0x5c026800, 0x1c01f000, - 0x001076ed, 0x00107700, 0x0010771a, 0x00020900, - 0x001096c1, 0x001096dc, 0x00020975, 0x001076ed, - 0x00107700, 0x00106226, 0x00107733, 0x001076ed, - 0x001076ed, 0x001076ed, 0x001076ed, 0x001076ed, - 0x0010936a, 0x0010a4d0, 0x001076ed, 0x001076ed, - 0x001076ed, 0x001076ed, 0x001076ed, 0x001076ed, - 0x001076ed, 0x001076ed, 0x001076ed, 0x001076ed, - 0x001076ed, 0x001076ed, 0x001076ed, 0x001076ed, - 0x59300203, 0x82000c80, 0x0000000e, 0x02021800, - 0x00100615, 0x0c01f001, 0x00107731, 0x00108337, - 0x00020914, 0x001084cc, 0x00108566, 0x00107731, - 0x00107731, 0x00107731, 0x0010831c, 0x00107731, - 0x00107731, 0x00107731, 0x00107731, 0x0010873a, - 0x83380480, 0x00000058, 0x04021007, 0x83380480, - 0x00000040, 0x04001004, 0x4d2c0000, 0x0c01f803, - 0x5c025800, 0x1c01f000, 0x001083c1, 0x001083c1, - 0x001083c1, 0x001083c1, 0x001083c1, 0x001083c3, - 0x00108463, 0x001083c1, 0x001083c1, 0x001083c1, - 0x001083c1, 0x001083c1, 0x001083c1, 0x001083c1, - 0x001083c1, 0x001083c1, 0x001083c1, 0x001083c1, - 0x001083c1, 0x00108467, 0x00020936, 0x001083c1, - 0x00108466, 0x00108468, 0x59325808, 0x59300811, - 0x59301402, 0x59340200, 0x8c00050e, 0x0402001c, - 0x0401f826, 0x04000005, 0x4a025a04, 0x00000103, - 0x497a5c09, 0x0401f009, 0x4a025a04, 0x00000103, - 0x4a025a06, 0x00000000, 0x497a5c09, 0x800409c0, - 0x02020800, 0x00108531, 0x48065807, 0x480a5c06, - 0x0201f800, 0x00020381, 0x5934000f, 0x5934140b, - 0x80081040, 0x04001002, 0x480a6c0b, 0x80000540, - 0x02020800, 0x00020275, 0x0401f75e, 0x592c020a, - 0x8c000502, 0x040007e9, 0x800409c0, 0x040007e7, - 0x592c0208, 0x8c00050e, 0x040207e4, 0x4933c857, - 0x0201f000, 0x00108fc6, 0x592c020a, 0x8c000500, - 0x04000010, 0x59300015, 0x592c380f, 0x801c3c80, - 0x0400000c, 0x4a025a06, 0x00000015, 0x8c1c3d3e, - 0x04000005, 0x4a025a06, 0x00000007, 0x801c3880, - 0x801c3800, 0x481fc857, 0x821c0d40, 0x00000000, - 0x1c01f000, 0x59300203, 0x82003480, 0x0000000e, - 0x02021800, 0x00100615, 0x0c01f001, 0x001096fb, - 0x00020989, 0x00109d9c, 0x00109daa, 0x000209a5, - 0x001096fb, 0x00109e98, 0x000209c4, 0x001096fb, - 0x001096fb, 0x001096fb, 0x001096fb, 0x001096fb, - 0x001096fb, 0x83380580, 0x00000013, 0x02020000, - 0x00109d23, 0x59300403, 0x82027480, 0x00000044, - 0x02021800, 0x00100615, 0x82000480, 0x00000040, - 0x02001800, 0x00100615, 0x0c01f001, 0x00109d80, - 0x0002099b, 0x00109d82, 0x00109d94, 0x59325808, - 0x832c0500, 0x00ff0000, 0x04000005, 0x592c0c0a, - 0x8c040d1a, 0x02020000, 0x00109d8f, 0x0401fe8e, - 0x0401f710, 0x83380580, 0x00000048, 0x04000007, - 0x83380580, 0x00000053, 0x02000000, 0x00109e3a, - 0x0201f800, 0x00100615, 0x5930001f, 0x59301011, - 0x59300809, 0x58040a00, 0x8c040d0e, 0x02020000, - 0x00109e16, 0x800811c0, 0x02020000, 0x00109e23, - 0x5930001f, 0x80000540, 0x02020000, 0x00109e31, - 0x59325808, 0x592c040a, 0x8c00051e, 0x02000000, - 0x00109e0c, 0x42027000, 0x00000041, 0x0401f001, - 0x83380480, 0x00000054, 0x02021800, 0x00100615, - 0x83380480, 0x00000040, 0x02001000, 0x00109e57, - 0x0c01f001, 0x00109e63, 0x000209e1, 0x00109e6f, - 0x00109e76, 0x00109e63, 0x00109e63, 0x00109e63, - 0x00109e63, 0x00109e65, 0x00109e6a, 0x00109e6a, - 0x00109e63, 0x00109e63, 0x00109e63, 0x00109e63, - 0x00109e6a, 0x00109e63, 0x00109e6a, 0x00109e63, - 0x00109e65, 0x4a026203, 0x00000001, 0x493a6403, - 0x42000800, 0x80002042, 0x0401f66f, 0x00000000, + 0x59a80066, 0x49335065, 0x80000000, 0x48035066, + 0x1c01f000, 0x4d340000, 0x59326809, 0x59300406, + 0x82000500, 0x0000001f, 0x0c01f803, 0x5c026800, + 0x1c01f000, 0x00107966, 0x00107979, 0x00107993, + 0x000207c9, 0x001098f1, 0x0010990c, 0x0002083e, + 0x00107966, 0x00107979, 0x001064ee, 0x001079ac, + 0x00107966, 0x00107966, 0x00107966, 0x00107966, + 0x00107966, 0x001095a1, 0x0010a6c2, 0x00107966, + 0x00107966, 0x00107966, 0x00107966, 0x00107966, + 0x00107966, 0x00107966, 0x00107966, 0x00107966, + 0x00107966, 0x00107966, 0x00107966, 0x00107966, + 0x00107966, 0x59300203, 0x82000c80, 0x0000000e, + 0x02021800, 0x001005d8, 0x0c01f001, 0x001079aa, + 0x00108592, 0x000207dd, 0x00108720, 0x001087b9, + 0x001079aa, 0x001079aa, 0x001079aa, 0x00108577, + 0x001079aa, 0x001079aa, 0x001079aa, 0x001079aa, + 0x00108985, 0x83380480, 0x00000058, 0x04021007, + 0x83380480, 0x00000040, 0x04001004, 0x4d2c0000, + 0x0c01f803, 0x5c025800, 0x1c01f000, 0x0010861b, + 0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b, + 0x0010861d, 0x001086bd, 0x0010861b, 0x0010861b, + 0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b, + 0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b, + 0x0010861b, 0x0010861b, 0x001086c1, 0x000207ff, + 0x0010861b, 0x001086c0, 0x001086c2, 0x59325808, + 0x59300811, 0x59301402, 0x59340200, 0x8c00050e, + 0x0402001c, 0x0401f826, 0x04000005, 0x4a025a04, + 0x00000103, 0x497a5c09, 0x0401f009, 0x4a025a04, + 0x00000103, 0x4a025a06, 0x00000000, 0x497a5c09, + 0x800409c0, 0x02020800, 0x00108785, 0x48065807, + 0x480a5c06, 0x0201f800, 0x000202c1, 0x5934000f, + 0x5934140b, 0x80081040, 0x04001002, 0x480a6c0b, + 0x80000540, 0x02020800, 0x00020253, 0x0401f75e, + 0x592c020a, 0x8c000502, 0x040007e9, 0x800409c0, + 0x040007e7, 0x592c0208, 0x8c00050e, 0x040207e4, + 0x4933c857, 0x0201f000, 0x0010920f, 0x592c020a, + 0x8c000500, 0x04000010, 0x59300015, 0x592c380f, + 0x801c3c80, 0x0400000c, 0x4a025a06, 0x00000015, + 0x8c1c3d3e, 0x04000005, 0x4a025a06, 0x00000007, + 0x801c3880, 0x801c3800, 0x481fc857, 0x821c0d40, + 0x00000000, 0x1c01f000, 0x59300203, 0x82003480, + 0x0000000e, 0x02021800, 0x001005d8, 0x0c01f001, + 0x0010992b, 0x00020852, 0x00109fba, 0x00109fc8, + 0x0002086e, 0x0010992b, 0x0010a0a8, 0x0002088d, + 0x0010992b, 0x0010992b, 0x0010992b, 0x0010992b, + 0x0010992b, 0x0010992b, 0x83380580, 0x00000013, + 0x02020000, 0x00109f42, 0x59300403, 0x82027480, + 0x00000044, 0x02021800, 0x001005d8, 0x82000480, + 0x00000040, 0x02001800, 0x001005d8, 0x0c01f001, + 0x00109f9e, 0x00020864, 0x00109fa0, 0x00109fb2, + 0x59325808, 0x832c0500, 0x00ff0000, 0x04000005, + 0x592c0c0a, 0x8c040d1a, 0x02020000, 0x00109fad, + 0x0401fe91, 0x0401f710, 0x83380580, 0x00000048, + 0x04000007, 0x83380580, 0x00000053, 0x02000000, + 0x0010a04a, 0x0201f800, 0x001005d8, 0x5930001f, + 0x59301011, 0x59300809, 0x58040a00, 0x8c040d0e, + 0x02020000, 0x0010a026, 0x800811c0, 0x02020000, + 0x0010a033, 0x5930001f, 0x80000540, 0x02020000, + 0x0010a041, 0x59325808, 0x592c040a, 0x8c00051e, + 0x02000000, 0x0010a01c, 0x42027000, 0x00000041, + 0x0401f001, 0x83380480, 0x00000054, 0x02021800, + 0x001005d8, 0x83380480, 0x00000040, 0x02001000, + 0x0010a067, 0x0c01f001, 0x0010a073, 0x000208aa, + 0x0010a07f, 0x0010a086, 0x0010a073, 0x0010a073, + 0x0010a073, 0x0010a073, 0x0010a075, 0x0010a07a, + 0x0010a07a, 0x0010a073, 0x0010a073, 0x0010a073, + 0x0010a073, 0x0010a07a, 0x0010a073, 0x0010a07a, + 0x0010a073, 0x0010a075, 0x4a026203, 0x00000001, + 0x493a6403, 0x42000800, 0x80002042, 0x0401f672, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0xa36ec441, 0x00000000, - 0x00000000, 0x00000000, 0x00000005, 0xfffffffb, - 0x02800004, 0x00000000, 0x0000c000, 0x0000071b, - 0x073fca5a, 0x0705a5a5, 0x01928009, 0x070ff0e1, - 0x03800006, 0x04958010, 0x05308000, 0x05008000, - 0x0600902f, 0x04a004dc, 0x0202f051, 0x042e4020, - 0x018f021b, 0x033e5000, 0x03020000, 0x078d0018, - 0x0493041a, 0x0092041c, 0x038a0305, 0x078b0303, - 0x048e8010, 0x0678aae5, 0x06000001, 0x07818174, - 0x040010e6, 0x0448e0e6, 0x04818010, 0x002fb008, - 0x0448e0e6, 0x04818010, 0x060ff0e6, 0x00580401, - 0x054880ff, 0x04818010, 0x022a5001, 0x030430d4, - 0x06780043, 0x030e0000, 0x030450ff, 0x06780043, - 0x03019000, 0x048185c4, 0x027c0045, 0x03020000, - 0x06810037, 0x027c0045, 0x03040000, 0x068100c7, - 0x027c0045, 0x03080000, 0x0681061c, 0x04908037, - 0x029105c2, 0x010410a6, 0x0379ff41, 0x037fffff, - 0x072d6000, 0x07601241, 0x050f80ff, 0x032fa009, - 0x05600400, 0x050f80ff, 0x056c04ff, 0x068105da, - 0x073fa009, 0x06000001, 0x0279ff02, 0x0700ffff, - 0x070ff0d1, 0x0179feff, 0x0700ffff, 0x045c0402, - 0x048185da, 0x060ff0d0, 0x0179feff, 0x0700ffff, - 0x057dfeff, 0x0700ffff, 0x068105bc, 0x05600e41, - 0x050f80ff, 0x032fa069, 0x07480000, 0x068105ce, - 0x06780043, 0x070000f0, 0x0781005f, 0x037c00ff, - 0x06000010, 0x0781005f, 0x038005ca, 0x0379ff00, - 0x070fffff, 0x06780043, 0x07f00000, 0x075a0000, - 0x020ef001, 0x038605cc, 0x05484000, 0x02a1819e, - 0x062d6001, 0x002fb001, 0x070ff069, 0x01868072, - 0x060ff079, 0x055c0441, 0x06810010, 0x012fb000, - 0x060560fb, 0x03800078, 0x060ff079, 0x02868198, - 0x070ff069, 0x055c0441, 0x06810010, 0x060560fb, - 0x0400d0d0, 0x062d6002, 0x0648300d, 0x06810086, - 0x070ff0d1, 0x062d6001, 0x045c040b, 0x06810089, - 0x05488000, 0x04818086, 0x072e500c, 0x00208001, - 0x05a004e1, 0x02800010, 0x062d6001, 0x07f00000, - 0x07f00000, 0x070ff0d1, 0x0179feff, 0x070000ff, - 0x055c040c, 0x058180bb, 0x0007b001, 0x03079041, - 0x0307a000, 0x06600a79, 0x050f80ff, 0x053fa80a, - 0x06000010, 0x072d5003, 0x078d0096, 0x0307c003, - 0x0007d004, 0x0107e005, 0x0307f006, 0x02080007, - 0x00081008, 0x01082009, 0x0308300a, 0x0008400b, - 0x0308500c, 0x068d00a1, 0x0678007a, 0x07f00000, - 0x010880ff, 0x03386000, 0x03010000, 0x072e6300, - 0x020ef07f, 0x02860010, 0x070ff07d, 0x0450047c, - 0x050f80ff, 0x002fa819, 0x068d00ae, 0x02080001, - 0x00081002, 0x0448807a, 0x068100b5, 0x0379ff03, - 0x070000ff, 0x01082003, 0x068d00b6, 0x02386004, - 0x03010000, 0x072e6c00, 0x02800010, 0x06780043, - 0x070000f0, 0x068105d5, 0x050020ff, 0x027c0002, - 0x06000010, 0x078100c3, 0x028005d5, 0x0700c0d1, - 0x0379ff0c, 0x070000ff, 0x0380008e, 0x0204a051, - 0x06780043, 0x070000f0, 0x037c00ff, 0x06000010, - 0x0781816a, 0x072d6000, 0x019485be, 0x050fb056, - 0x044880e6, 0x04818010, 0x060ff0d0, 0x0179feff, - 0x0700ffff, 0x057dfeff, 0x0700ffff, 0x068105bc, - 0x05a00212, 0x0349c0e4, 0x0781811d, 0x070ff093, - 0x050010ff, 0x070ff093, 0x045c0401, 0x058180db, - 0x02046092, 0x04002046, 0x04600202, 0x00540401, - 0x048280e6, 0x04500425, 0x070060ff, 0x0730ffff, - 0x0700000f, 0x0742000f, 0x05810190, 0x06a005a4, - 0x0648a002, 0x048180e9, 0x00047089, 0x070ff047, - 0x045c0443, 0x077800ff, 0x07f00000, 0x0781818e, - 0x07780047, 0x0500e000, 0x048185ab, 0x070ff006, - 0x01860117, 0x0179fe47, 0x0700000f, 0x010480ff, - 0x056c7048, 0x06818102, 0x007a0d4a, 0x04003801, - 0x0220f001, 0x0180010f, 0x07608e48, 0x034a60ff, - 0x0700f0ff, 0x074b88ff, 0x037000ff, 0x07000600, - 0x05500448, 0x074d00ff, 0x045a044a, 0x0304a0ff, - 0x070ff00f, 0x01540406, 0x05820117, 0x04950120, - 0x05a001bd, 0x02868123, 0x0134bfff, 0x070fffff, - 0x0104102e, 0x050fd041, 0x00800126, 0x0595011d, - 0x05a001bd, 0x0186011d, 0x0202f00e, 0x052e4030, - 0x040fd02f, 0x070fc0ff, 0x05a00218, 0x02800010, - 0x0400e02f, 0x042e4020, 0x0202f051, 0x0004100e, - 0x0004b00e, 0x050fd041, 0x024a6c46, 0x04500423, - 0x050070ff, 0x03620024, 0x050080ff, 0x04004046, - 0x0700500f, 0x03206000, 0x05601048, 0x0700a0ff, - 0x0700900a, 0x070ff005, 0x04500446, 0x00540425, - 0x04820157, 0x05601622, 0x050f80ff, 0x063fa032, - 0x06000002, 0x03203000, 0x01204000, 0x03205000, - 0x0120b000, 0x0320c000, 0x07601441, 0x050f80ff, - 0x043fa852, 0x06000001, 0x070ff056, 0x056c02ff, - 0x050fb0ff, 0x070560ff, 0x03079041, 0x05600e41, - 0x050f80ff, 0x073fa011, 0x0600003d, 0x06780043, - 0x07f00000, 0x065a007a, 0x010880ff, 0x04a001b6, - 0x058d0150, 0x0208a04a, 0x0108b04b, 0x02386001, - 0x03010000, 0x072e6300, 0x028000a8, 0x0500d00a, - 0x05500405, 0x014a68ff, 0x070090ff, 0x0154040a, - 0x0700c0ff, 0x0600a023, 0x0500b024, 0x02206001, - 0x05601622, 0x050f80ff, 0x063fa04a, 0x06000002, - 0x05601022, 0x050f80ff, 0x043fa819, 0x06000001, - 0x0600a00d, 0x0180013c, 0x06780043, 0x070000f0, - 0x050010ff, 0x027c0001, 0x07000030, 0x078105b2, - 0x027c0001, 0x06000020, 0x078105b2, 0x038005ca, - 0x054880ff, 0x06810010, 0x070ff056, 0x050fb0ff, - 0x044880e5, 0x0581017d, 0x044880e6, 0x04818010, - 0x00800183, 0x056c02ff, 0x050fb0ff, 0x070560ff, - 0x072e5300, 0x044880e6, 0x04818010, 0x072d5003, - 0x06780043, 0x07f00000, 0x010880ff, 0x058d0187, - 0x03386005, 0x03010000, 0x033e6000, 0x0700000c, - 0x052e5200, 0x02800010, 0x0120918e, 0x018004e4, - 0x01209190, 0x018004e4, 0x00209192, 0x018004e4, - 0x03209000, 0x018004e4, 0x01209196, 0x018004e4, - 0x00209198, 0x018004e4, 0x02493075, 0x0681050b, - 0x0120919a, 0x018004e4, 0x06601e01, 0x050f80ff, - 0x063fa029, 0x06000008, 0x02015010, 0x02016051, - 0x00017051, 0x00011051, 0x05601a41, 0x050f80ff, - 0x053fa83a, 0x06000008, 0x05600e41, 0x050f80ff, - 0x01464000, 0x032fa00a, 0x07006011, 0x05007012, - 0x04008013, 0x07009014, 0x0600a015, 0x0400b016, - 0x0700c017, 0x07c00000, 0x072d5003, 0x06601479, - 0x050f80ff, 0x048d01b9, 0x063fa051, 0x0600003e, - 0x07c00000, 0x06005051, 0x0400e02c, 0x0660060e, - 0x050f80ff, 0x032fa009, 0x0379ff00, 0x070000ff, - 0x076c0000, 0x058101dd, 0x0660480e, 0x0500e0ff, - 0x034000ff, 0x01540427, 0x0582020a, 0x03400005, - 0x070ff005, 0x055c0428, 0x0481020e, 0x01680e05, - 0x056c0405, 0x068181bf, 0x040f8029, 0x053fa809, - 0x07000024, 0x06600649, 0x050f80ff, 0x032fa009, - 0x0379ff00, 0x070000ff, 0x076c0000, 0x068181bf, - 0x0400e049, 0x0340002d, 0x050f802b, 0x053fa80a, - 0x06000016, 0x0660480e, 0x0302c0ff, 0x034000ff, - 0x01540427, 0x0582020c, 0x072d6000, 0x0460040e, - 0x050f80ff, 0x0104e0d1, 0x0379ff4e, 0x0700ffff, - 0x062d6002, 0x032fa009, 0x0004d0d0, 0x074b004d, - 0x07780000, 0x07ffff00, 0x055a044d, 0x070000ff, - 0x00201008, 0x04002051, 0x06003051, 0x05304000, - 0x07000060, 0x03205009, 0x07006022, 0x0460040e, - 0x050f80ff, 0x032fa03a, 0x06603c0e, 0x050f80ff, - 0x073fa00a, 0x07000027, 0x050010d1, 0x0460320e, - 0x050f80ff, 0x012fa80a, 0x060ff00e, 0x055c042e, - 0x04810210, 0x07c00000, 0x0400e026, 0x008001cb, - 0x0202c026, 0x008001e6, 0x0500e02e, 0x008001e6, - 0x0400e051, 0x01800209, 0x0349c0e4, 0x04810215, - 0x07c00000, 0x013e4000, 0x070c0000, 0x07c00000, - 0x013e4000, 0x03080000, 0x07c00000, 0x009702f4, - 0x022a5002, 0x0790821d, 0x00910291, 0x030400a6, - 0x0678aae5, 0x06000001, 0x01a1860c, 0x06600c40, - 0x050f80ff, 0x032fa021, 0x074b0000, 0x076c0600, - 0x07818293, 0x05600403, 0x050f80ff, 0x073fa009, - 0x06000002, 0x0279ff04, 0x0700ffff, 0x010440d7, - 0x0179fe44, 0x0700ffff, 0x045c0404, 0x07818295, - 0x0349f044, 0x0681829e, 0x02495001, 0x06818297, - 0x060ff079, 0x045c0440, 0x0781823c, 0x0644f07a, - 0x002fb008, 0x060ff079, 0x045c0440, 0x07818241, - 0x0644f07a, 0x002fb008, 0x0648f001, 0x07818288, - 0x04600e40, 0x050f80ff, 0x06480001, 0x04810257, - 0x0448e001, 0x04810273, 0x02460001, 0x0644f001, - 0x012fa80a, 0x04008040, 0x05a004ee, 0x0286828c, - 0x05a004d8, 0x062da001, 0x013e4000, 0x06000080, - 0x06930013, 0x02920013, 0x02800010, 0x0644f001, - 0x012fa80a, 0x020ef002, 0x00860275, 0x04600840, - 0x050f80ff, 0x053fa809, 0x06000002, 0x05780105, - 0x00800440, 0x017c0105, 0x05000400, 0x06818275, - 0x06601e02, 0x050f80ff, 0x053fa809, 0x06000002, - 0x04602a40, 0x050f80ff, 0x070ff005, 0x053fa809, - 0x06000002, 0x055c0405, 0x06818275, 0x04008040, - 0x0045e008, 0x05a004d8, 0x00800251, 0x0644f001, - 0x012fa80a, 0x050020d8, 0x04600440, 0x050f80ff, - 0x073fa00a, 0x06000001, 0x06480001, 0x07818281, - 0x05308000, 0x03040000, 0x06009040, 0x04a004dc, - 0x00800251, 0x07a0060c, 0x054b0800, 0x056a0700, - 0x06600c40, 0x050f80ff, 0x032fa00a, 0x00800251, - 0x013e4000, 0x06000080, 0x01209288, 0x018004e4, - 0x06009008, 0x05308000, 0x05004000, 0x04a004dc, - 0x00800251, 0x02209002, 0x008002e5, 0x03209000, - 0x008002e5, 0x02209004, 0x008002e5, 0x04a002fd, - 0x062da001, 0x05308000, 0x05002000, 0x06009040, - 0x04a004dc, 0x00800252, 0x013e4000, 0x06000080, - 0x02495001, 0x078182db, 0x04600840, 0x050f80ff, - 0x053fa809, 0x06000001, 0x0721f000, 0x0349f003, - 0x058102aa, 0x0245f01f, 0x06000002, 0x018602db, - 0x07601400, 0x050f80ff, 0x012fa809, 0x06480001, - 0x058102db, 0x06602440, 0x050f80ff, 0x012fa809, - 0x020ef001, 0x038682db, 0x019b02db, 0x050020d8, - 0x062da001, 0x06303002, 0x05000430, 0x04600440, - 0x050f80ff, 0x073fa012, 0x06000001, 0x028f82bf, - 0x050040d8, 0x062da001, 0x07601e00, 0x050f80ff, - 0x073fa009, 0x06000001, 0x060ff004, 0x00540402, - 0x048202d9, 0x06005051, 0x06006051, 0x06602240, - 0x050f80ff, 0x063fa01a, 0x06000002, 0x06600a40, - 0x050f80ff, 0x073fa00a, 0x07000003, 0x060ff040, - 0x045a041f, 0x010eb0ff, 0x06930013, 0x02920013, - 0x02800010, 0x04004002, 0x018002c9, 0x04a002fd, - 0x062da001, 0x05308000, 0x07005000, 0x06009040, - 0x04a004dc, 0x050080d8, 0x05a004e1, 0x062da001, - 0x02800013, 0x050fd009, 0x050fd041, 0x013e4000, - 0x06000080, 0x05308000, 0x03013000, 0x04a004dc, - 0x010440d7, 0x0349f044, 0x048102f2, 0x062da001, - 0x008f02f2, 0x03e00000, 0x062da001, 0x02800013, - 0x0249c0e5, 0x06810013, 0x062da001, 0x07f00000, - 0x07f00000, 0x033e5000, 0x070c0000, 0x018f02f6, - 0x03800011, 0x050020d8, 0x04600440, 0x050f80ff, - 0x073fa00a, 0x06000001, 0x07c00000, 0x002fb001, - 0x03800306, 0x012fb000, 0x03075087, 0x068d0307, - 0x03386000, 0x03020000, 0x04482075, 0x06810352, - 0x0648a0e6, 0x07810347, 0x0642007f, 0x06810345, - 0x0340007e, 0x060ff038, 0x0154047e, 0x02d00334, - 0x0560027d, 0x050f80ff, 0x032fa009, 0x030ef000, - 0x02860504, 0x0107d000, 0x05600800, 0x050f80ff, - 0x032fa009, 0x03681e00, 0x04500420, 0x050f80ff, - 0x073fa009, 0x0700003f, 0x03800311, 0x070ff07d, - 0x0450047c, 0x050f80ff, 0x002fa819, 0x078d0327, - 0x02080001, 0x00081002, 0x0448807a, 0x0781032e, - 0x0379ff03, 0x070000ff, 0x01082003, 0x068d032f, - 0x02386004, 0x03010000, 0x072e6c00, 0x02800352, - 0x0380033a, 0x0380033c, 0x0280033e, 0x02800340, - 0x03800342, 0x03800344, 0x0727c005, 0x02800323, - 0x0627c008, 0x02800323, 0x0627c00b, 0x02800323, - 0x0627c00e, 0x02800323, 0x0727c011, 0x02800323, - 0x03800314, 0x052e6800, 0x02800352, 0x044880e6, - 0x06810531, 0x052e6200, 0x070ff088, 0x0179feff, - 0x070fffff, 0x04818501, 0x060ff083, 0x0086836d, - 0x033e6000, 0x07000003, 0x068d0352, 0x07286000, - 0x07f00000, 0x078d0355, 0x038c0306, 0x0648c0e6, - 0x05818372, 0x0448e0e6, 0x0781036a, 0x004920e6, - 0x07810365, 0x06a0056d, 0x05001088, 0x00700101, - 0x03100000, 0x00088001, 0x033e6000, 0x07000088, - 0x0280055e, 0x02386001, 0x07030000, 0x033e6000, - 0x06000008, 0x028003f1, 0x02799075, 0x0500040f, - 0x06810010, 0x06601479, 0x050080ff, 0x06309052, - 0x0600003e, 0x02800376, 0x06602279, 0x050080ff, - 0x05309812, 0x07000041, 0x0648007a, 0x0781037e, - 0x04488075, 0x0581837e, 0x040f8008, 0x070fa009, - 0x0049107a, 0x01a183f3, 0x00798075, 0x06000507, - 0x0481851c, 0x0448b075, 0x06810385, 0x02493075, - 0x07810509, 0x0249c0e6, 0x048183e0, 0x0648c0e6, - 0x0581839a, 0x068d0389, 0x02386001, 0x07030000, - 0x0049107a, 0x07810390, 0x020ef083, 0x0386039a, - 0x06483075, 0x068103ef, 0x0678007a, 0x07000035, - 0x03a184cf, 0x05308000, 0x07060000, 0x06009079, - 0x04a004dc, 0x028003ef, 0x0448807a, 0x0681039e, - 0x06483075, 0x058104f9, 0x0448d07a, 0x068103a2, - 0x06483075, 0x058104f9, 0x068d03a2, 0x02386001, - 0x07030000, 0x0444e07a, 0x0648307a, 0x048183c7, - 0x0448707a, 0x068103ea, 0x0648f07a, 0x078103b2, - 0x05a004cf, 0x04008079, 0x05a004ee, 0x008683c2, - 0x05a004d8, 0x028003ef, 0x0560107b, 0x050f80ff, - 0x032fa009, 0x0349c000, 0x058183c0, 0x04600e79, - 0x050f80ff, 0x073fa00a, 0x0600003d, 0x06600a79, - 0x050f80ff, 0x053fa80a, 0x06000010, 0x028003ef, - 0x0046e07a, 0x028003ea, 0x06009008, 0x05308000, - 0x05004000, 0x04a004dc, 0x028003ef, 0x0560167b, - 0x050f80ff, 0x032fa011, 0x070ff000, 0x04500401, - 0x030460ff, 0x060ff025, 0x00540446, 0x078203d1, - 0x030460ff, 0x04092046, 0x05a00218, 0x06600679, - 0x050f80ff, 0x00201007, 0x012fa80a, 0x0046047a, - 0x034630ff, 0x050020ff, 0x06003051, 0x04600e79, - 0x050f80ff, 0x073fa012, 0x06000001, 0x028003ef, - 0x033e6a00, 0x0202000e, 0x02079051, 0x07000088, - 0x078d03e4, 0x0744c000, 0x01088000, 0x03386006, - 0x03010000, 0x02800010, 0x05a004cf, 0x05308000, - 0x03020000, 0x06009079, 0x04a004dc, 0x033e6a00, - 0x0302000a, 0x02079051, 0x02800010, 0x04603e79, - 0x050f80ff, 0x032fa009, 0x070ff000, 0x0186040c, - 0x057dfeff, 0x07ffffff, 0x0581040c, 0x050f8000, - 0x012fa811, 0x0079fe02, 0x070000ff, 0x077d66ff, - 0x060000dc, 0x0781840c, 0x060ff001, 0x0286840d, - 0x064b0002, 0x06420002, 0x060ff002, 0x05500400, - 0x050f80ff, 0x05004084, 0x073fa00a, 0x06000002, - 0x07c00000, 0x04600201, 0x050f80ff, 0x073fa009, - 0x06000001, 0x0079fe02, 0x070000ff, 0x077d72ff, - 0x070000dd, 0x0781840c, 0x064b0002, 0x06420002, - 0x06000001, 0x01800406, 0x0605004c, 0x0180041e, - 0x0493041a, 0x04a004d5, 0x054bc450, 0x05810421, - 0x01d00422, 0x01800421, 0x00800432, 0x00800434, - 0x00800432, 0x008004a7, 0x0180043f, 0x00800434, - 0x01800471, 0x00800432, 0x00800432, 0x008004ab, - 0x00800432, 0x018004af, 0x008004c4, 0x01800488, - 0x00800432, 0x00800432, 0x00209432, 0x018004e4, - 0x0379ff50, 0x070fffff, 0x060ff079, 0x055c0450, - 0x048104a4, 0x002fb008, 0x060ff079, 0x055c0450, - 0x058104a3, 0x04a004c7, 0x0180049c, 0x0179fe50, - 0x070fffff, 0x070050ff, 0x060ff079, 0x055c0405, - 0x04810449, 0x002fb008, 0x060ff079, 0x055c0405, - 0x078184a0, 0x070ff087, 0x017980ff, 0x06000507, - 0x06818451, 0x02203040, 0x05002087, 0x0049d002, - 0x0481046b, 0x04930458, 0x01257000, 0x073c3fff, - 0x0700000f, 0x052e4003, 0x072e5030, 0x0304c050, - 0x02400057, 0x06740057, 0x06000002, 0x06820016, - 0x04002083, 0x07003084, 0x04004085, 0x06602279, - 0x050f80ff, 0x063fa01a, 0x06000001, 0x05a004cf, - 0x06a00576, 0x033e6a00, 0x0302000a, 0x062e5020, - 0x003e4002, 0x07000a00, 0x028003f1, 0x07420003, - 0x0781844e, 0x00798002, 0x06000507, 0x06818451, - 0x0180045c, 0x05930478, 0x01257000, 0x073c3fff, - 0x0700000f, 0x052e4003, 0x072e5030, 0x0304c050, - 0x067800e6, 0x07000041, 0x0581047d, 0x06a0057f, - 0x04818016, 0x002fb008, 0x067800e6, 0x07000041, - 0x04810483, 0x06a0057f, 0x04818016, 0x062e5020, - 0x003e4002, 0x07000a00, 0x03e00000, 0x02800010, - 0x0379ff50, 0x070fffff, 0x060ff079, 0x055c0450, - 0x0781848e, 0x0245507a, 0x002fb008, 0x060ff079, - 0x055c0450, 0x07818493, 0x0245507a, 0x002fb008, - 0x05600e50, 0x050f80ff, 0x012fa809, 0x02455001, - 0x05600e50, 0x050f80ff, 0x012fa80a, 0x0080049d, - 0x002fb008, 0x003e4002, 0x07000a00, 0x02800016, - 0x079384a3, 0x062e5020, 0x042e4002, 0x002fb008, - 0x013e4000, 0x05000e00, 0x02800016, 0x0179fe50, - 0x070fffff, 0x010210ff, 0x02800016, 0x0179fe50, - 0x070fffff, 0x050340ff, 0x0080049d, 0x0179fe50, - 0x070fffff, 0x0102e0ff, 0x0760282e, 0x050f80ff, - 0x05222000, 0x07223000, 0x05224000, 0x07225000, - 0x07226000, 0x05227000, 0x05228000, 0x07229000, - 0x0722a000, 0x0522b000, 0x063fa051, 0x07000011, - 0x0202c026, 0x0522d000, 0x052e400c, 0x02800016, - 0x030430d4, 0x062e5008, 0x00800176, 0x05600e50, - 0x050f80ff, 0x032fa009, 0x03460000, 0x018004d2, - 0x0246007a, 0x0045207a, 0x008004d0, 0x0246007a, - 0x0600007a, 0x04600e79, 0x050f80ff, 0x032fa00a, - 0x07c00000, 0x029284d5, 0x070500e1, 0x07c00000, - 0x0245f008, 0x048404d9, 0x020e0008, 0x07c00000, - 0x070ff009, 0x065a0008, 0x058404de, 0x020e0008, - 0x07c00000, 0x058404e1, 0x020e0008, 0x07c00000, - 0x05308000, 0x0500d000, 0x04a004dc, 0x04a004e9, - 0x02800010, 0x052e4300, 0x072e500c, 0x073c3fff, - 0x0700000f, 0x07c00000, 0x06602208, 0x050f80ff, - 0x032fa011, 0x076a0000, 0x068184f7, 0x066a0001, - 0x048104f7, 0x04002051, 0x07c00000, 0x00202001, - 0x07c00000, 0x0648307a, 0x01a18606, 0x05a004cc, - 0x05308000, 0x05001000, 0x06009079, 0x04a004dc, - 0x0280055e, 0x0249c0e6, 0x058104f9, 0x0280036d, - 0x0648307a, 0x07818196, 0x05a004cf, 0x02209504, - 0x018004e4, 0x02490075, 0x06810519, 0x04002089, - 0x04780102, 0x07f00000, 0x05001088, 0x06a0056d, - 0x04740101, 0x03100000, 0x060ff002, 0x045c0401, - 0x0481851a, 0x00088001, 0x033e6000, 0x070000c0, - 0x0380055a, 0x07f00000, 0x0220951a, 0x018004e4, - 0x040fd075, 0x040fd07a, 0x040fd079, 0x0648307a, - 0x06810525, 0x06780075, 0x06000007, 0x0481852c, - 0x07a00606, 0x06486075, 0x06818194, 0x02490075, - 0x0781819a, 0x04487075, 0x04818534, 0x0280053b, - 0x05308000, 0x03010000, 0x06009079, 0x04a004dc, - 0x02800010, 0x0448e0e6, 0x04818352, 0x00800192, - 0x05308000, 0x0500e000, 0x06009079, 0x04a004dc, - 0x04008089, 0x05a004e1, 0x0380055a, 0x05a004cc, - 0x05308000, 0x0700f000, 0x06009079, 0x07000088, - 0x06a00543, 0x04a004dc, 0x02800010, 0x03386000, - 0x07030000, 0x07f00000, 0x068d0546, 0x033e6a00, - 0x0202000e, 0x02079051, 0x0448b075, 0x06810551, - 0x02493075, 0x06810551, 0x05301005, 0x03010000, - 0x03800553, 0x05301006, 0x03010000, 0x05002087, - 0x06485002, 0x05818553, 0x0744c000, 0x01088000, - 0x02086001, 0x07c00000, 0x05001088, 0x06a0056d, - 0x0644c001, 0x00088001, 0x033e6a00, 0x0202000e, - 0x004920e6, 0x05818563, 0x02079051, 0x078d0563, - 0x060ff089, 0x034990ff, 0x0781056a, 0x03386005, - 0x03010000, 0x02800010, 0x03386006, 0x03010000, - 0x02800010, 0x068d056d, 0x03386000, 0x07030000, - 0x07f00000, 0x078d0571, 0x070ff087, 0x074850ff, - 0x05818572, 0x07c00000, 0x068d0576, 0x02386001, - 0x07030000, 0x07f00000, 0x068d057a, 0x070ff087, - 0x074850ff, 0x0581857b, 0x07c00000, 0x05002087, - 0x0049d002, 0x0581858e, 0x002fb008, 0x067800e6, - 0x07000041, 0x002fb008, 0x0581858e, 0x06a005a4, - 0x0448e002, 0x06810591, 0x0648a002, 0x0481859b, - 0x06486002, 0x07810595, 0x02400057, 0x056a02ff, - 0x07c00000, 0x06a005a4, 0x06788102, 0x06000004, - 0x0581858e, 0x04002089, 0x070ff0d4, 0x045c0402, - 0x077800ff, 0x07f00000, 0x0581858e, 0x00202010, - 0x038c058e, 0x07f00000, 0x06420002, 0x0581859c, - 0x06a00576, 0x033e6a00, 0x0302000a, 0x07c00000, - 0x07f00000, 0x060ff0a2, 0x050020ff, 0x060ff0a2, - 0x045c0402, 0x058185a5, 0x07c00000, 0x05a00218, - 0x03495047, 0x068105b0, 0x0320901d, 0x02800602, - 0x0220901f, 0x02800602, 0x014980e4, 0x04818010, - 0x013e4000, 0x07003000, 0x05600e35, 0x050f80ff, - 0x07a006fa, 0x01208003, 0x05a004e1, 0x038005ca, - 0x03209009, 0x02800602, 0x03209011, 0x02800602, - 0x02209007, 0x02800602, 0x03209003, 0x02800602, - 0x00498043, 0x048185bc, 0x00497043, 0x058185c0, - 0x02209001, 0x02800602, 0x0220900d, 0x02800602, - 0x0320900f, 0x02800602, 0x03493000, 0x068105d3, - 0x027c0045, 0x070a0000, 0x068105dc, 0x0220900b, - 0x02800602, 0x02209013, 0x05308000, 0x01012000, - 0x04a004dc, 0x00800183, 0x03209005, 0x02800602, - 0x072e500c, 0x00208002, 0x05a004e1, 0x02800010, - 0x02209015, 0x02800602, 0x072d6000, 0x05308000, - 0x05007000, 0x07f00000, 0x070090d1, 0x0379ff09, - 0x0700ffff, 0x04a004dc, 0x03209017, 0x02800602, - 0x033e5000, 0x06000080, 0x02209019, 0x02800602, - 0x072d6000, 0x033e5000, 0x06000080, 0x07f00000, - 0x060ff0d0, 0x0179feff, 0x0700ffff, 0x057dfeff, - 0x0700ffff, 0x04818010, 0x02400058, 0x00642058, - 0x06820010, 0x033e5000, 0x06000080, 0x04058051, - 0x0320901b, 0x02800602, 0x05308000, 0x01012000, - 0x04a004dc, 0x00800176, 0x05a00218, 0x05308000, - 0x05008000, 0x06009079, 0x04a004dc, 0x07c00000, - 0x034900e4, 0x04818616, 0x013e4000, 0x070000c0, - 0x07f00000, 0x034900e4, 0x05818614, 0x07c00000, - 0x013e4000, 0x06000080, 0x07f00000, 0x07f00000, - 0x07f00000, 0x034900e4, 0x0681060e, 0x02800616, - 0x072d6000, 0x00498043, 0x07810630, 0x060ff0d0, + 0x00000000, 0x00000000, 0x00000000, 0x14aa62b1, + 0x00000000, 0x00000000, 0x00000000, 0x00000005, + 0xfffffffb, 0x02800004, 0x00000000, 0x0000c000, + 0x0000071d, 0x073fca5a, 0x0705a5a5, 0x01928009, + 0x070ff0e1, 0x03800006, 0x04958010, 0x05308000, + 0x05008000, 0x0600902f, 0x04a004dc, 0x0202f051, + 0x042e4020, 0x018f021b, 0x033e5000, 0x03020000, + 0x078d0018, 0x0493041a, 0x0092041c, 0x038a0305, + 0x078b0303, 0x048e8010, 0x0678aae5, 0x06000001, + 0x07818174, 0x040010e6, 0x0448e0e6, 0x04818010, + 0x002fb008, 0x0448e0e6, 0x04818010, 0x060ff0e6, + 0x00580401, 0x054880ff, 0x04818010, 0x022a5001, + 0x030430d4, 0x06780043, 0x030e0000, 0x030450ff, + 0x06780043, 0x03019000, 0x058185c6, 0x027c0045, + 0x03020000, 0x06810037, 0x027c0045, 0x03040000, + 0x068100c7, 0x027c0045, 0x03080000, 0x0781061e, + 0x04908037, 0x029105c4, 0x010410a6, 0x0379ff41, + 0x037fffff, 0x072d6000, 0x07601241, 0x050f80ff, + 0x032fa009, 0x05600400, 0x050f80ff, 0x056c04ff, + 0x068105dc, 0x073fa009, 0x06000001, 0x0279ff02, + 0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff, + 0x045c0402, 0x048185dc, 0x060ff0d0, 0x0179feff, + 0x0700ffff, 0x057dfeff, 0x0700ffff, 0x078105be, + 0x05600e41, 0x050f80ff, 0x032fa069, 0x07480000, + 0x068105d0, 0x06780043, 0x070000f0, 0x0781005f, + 0x037c00ff, 0x06000010, 0x0781005f, 0x038005cc, + 0x0379ff00, 0x070fffff, 0x06780043, 0x07f00000, + 0x075a0000, 0x020ef001, 0x028605ce, 0x05484000, + 0x02a1819e, 0x062d6001, 0x002fb001, 0x070ff069, + 0x01868072, 0x060ff079, 0x055c0441, 0x06810010, + 0x012fb000, 0x060560fb, 0x03800078, 0x060ff079, + 0x02868198, 0x070ff069, 0x055c0441, 0x06810010, + 0x060560fb, 0x0400d0d0, 0x062d6002, 0x0648300d, + 0x06810086, 0x070ff0d1, 0x062d6001, 0x045c040b, + 0x06810089, 0x05488000, 0x04818086, 0x072e500c, + 0x00208001, 0x05a004e1, 0x02800010, 0x062d6001, + 0x07f00000, 0x07f00000, 0x070ff0d1, 0x0179feff, + 0x070000ff, 0x055c040c, 0x058180bb, 0x0007b001, + 0x03079041, 0x0307a000, 0x06600a79, 0x050f80ff, + 0x053fa80a, 0x06000010, 0x072d5003, 0x078d0096, + 0x0307c003, 0x0007d004, 0x0107e005, 0x0307f006, + 0x02080007, 0x00081008, 0x01082009, 0x0308300a, + 0x0008400b, 0x0308500c, 0x068d00a1, 0x0678007a, + 0x07f00000, 0x010880ff, 0x03386000, 0x03010000, + 0x072e6300, 0x020ef07f, 0x02860010, 0x070ff07d, + 0x0450047c, 0x050f80ff, 0x002fa819, 0x068d00ae, + 0x02080001, 0x00081002, 0x0448807a, 0x068100b5, + 0x0379ff03, 0x070000ff, 0x01082003, 0x068d00b6, + 0x02386004, 0x03010000, 0x072e6c00, 0x02800010, + 0x06780043, 0x070000f0, 0x078105d7, 0x050020ff, + 0x027c0002, 0x06000010, 0x078100c3, 0x038005d7, + 0x0700c0d1, 0x0379ff0c, 0x070000ff, 0x0380008e, + 0x0204a051, 0x06780043, 0x070000f0, 0x037c00ff, + 0x06000010, 0x0781816a, 0x072d6000, 0x019485c0, + 0x050fb056, 0x044880e6, 0x04818010, 0x060ff0d0, + 0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff, + 0x078105be, 0x05a00212, 0x0349c0e4, 0x0781811d, + 0x070ff093, 0x050010ff, 0x070ff093, 0x045c0401, + 0x058180db, 0x02046092, 0x04002046, 0x04600202, + 0x00540401, 0x048280e6, 0x04500425, 0x070060ff, + 0x0730ffff, 0x0700000f, 0x0742000f, 0x05810190, + 0x07a005a6, 0x0648a002, 0x048180e9, 0x00047089, + 0x070ff047, 0x045c0443, 0x077800ff, 0x07f00000, + 0x0781818e, 0x07780047, 0x0500e000, 0x048185ad, + 0x070ff006, 0x01860117, 0x0179fe47, 0x0700000f, + 0x010480ff, 0x056c7048, 0x06818102, 0x007a0d4a, + 0x04003801, 0x0220f001, 0x0180010f, 0x07608e48, + 0x034a60ff, 0x0700f0ff, 0x074b88ff, 0x037000ff, + 0x07000600, 0x05500448, 0x074d00ff, 0x045a044a, + 0x0304a0ff, 0x070ff00f, 0x01540406, 0x05820117, + 0x04950120, 0x05a001bd, 0x02868123, 0x0134bfff, + 0x070fffff, 0x0104102e, 0x050fd041, 0x00800126, + 0x0595011d, 0x05a001bd, 0x0186011d, 0x0202f00e, + 0x052e4030, 0x040fd02f, 0x070fc0ff, 0x05a00218, + 0x02800010, 0x0400e02f, 0x042e4020, 0x0202f051, + 0x0004100e, 0x0004b00e, 0x050fd041, 0x024a6c46, + 0x04500423, 0x050070ff, 0x03620024, 0x050080ff, + 0x04004046, 0x0700500f, 0x03206000, 0x05601048, + 0x0700a0ff, 0x0700900a, 0x070ff005, 0x04500446, + 0x00540425, 0x04820157, 0x05601622, 0x050f80ff, + 0x063fa032, 0x06000002, 0x03203000, 0x01204000, + 0x03205000, 0x0120b000, 0x0320c000, 0x07601441, + 0x050f80ff, 0x043fa852, 0x06000001, 0x070ff056, + 0x056c02ff, 0x050fb0ff, 0x070560ff, 0x03079041, + 0x05600e41, 0x050f80ff, 0x073fa011, 0x0600003d, + 0x06780043, 0x07f00000, 0x065a007a, 0x010880ff, + 0x04a001b6, 0x058d0150, 0x0208a04a, 0x0108b04b, + 0x02386001, 0x03010000, 0x072e6300, 0x028000a8, + 0x0500d00a, 0x05500405, 0x014a68ff, 0x070090ff, + 0x0154040a, 0x0700c0ff, 0x0600a023, 0x0500b024, + 0x02206001, 0x05601622, 0x050f80ff, 0x063fa04a, + 0x06000002, 0x05601022, 0x050f80ff, 0x043fa819, + 0x06000001, 0x0600a00d, 0x0180013c, 0x06780043, + 0x070000f0, 0x050010ff, 0x027c0001, 0x07000030, + 0x078105b4, 0x027c0001, 0x06000020, 0x078105b4, + 0x038005cc, 0x054880ff, 0x06810010, 0x070ff056, + 0x050fb0ff, 0x044880e5, 0x0581017d, 0x044880e6, + 0x04818010, 0x00800183, 0x056c02ff, 0x050fb0ff, + 0x070560ff, 0x072e5300, 0x044880e6, 0x04818010, + 0x072d5003, 0x06780043, 0x07f00000, 0x010880ff, + 0x058d0187, 0x03386005, 0x03010000, 0x033e6000, + 0x0700000c, 0x052e5200, 0x02800010, 0x0120918e, + 0x018004e4, 0x01209190, 0x018004e4, 0x00209192, + 0x018004e4, 0x03209000, 0x018004e4, 0x01209196, + 0x018004e4, 0x00209198, 0x018004e4, 0x02493075, + 0x06810510, 0x0120919a, 0x018004e4, 0x06601e01, + 0x050f80ff, 0x063fa029, 0x06000008, 0x02015010, + 0x02016051, 0x00017051, 0x00011051, 0x05601a41, + 0x050f80ff, 0x053fa83a, 0x06000008, 0x05600e41, + 0x050f80ff, 0x01464000, 0x032fa00a, 0x07006011, + 0x05007012, 0x04008013, 0x07009014, 0x0600a015, + 0x0400b016, 0x0700c017, 0x07c00000, 0x072d5003, + 0x06601479, 0x050f80ff, 0x048d01b9, 0x063fa051, + 0x0600003e, 0x07c00000, 0x06005051, 0x0400e02c, + 0x0660060e, 0x050f80ff, 0x032fa009, 0x0379ff00, + 0x070000ff, 0x076c0000, 0x058101dd, 0x0660480e, + 0x0500e0ff, 0x034000ff, 0x01540427, 0x0582020a, + 0x03400005, 0x070ff005, 0x055c0428, 0x0481020e, + 0x01680e05, 0x056c0405, 0x068181bf, 0x040f8029, + 0x053fa809, 0x07000024, 0x06600649, 0x050f80ff, + 0x032fa009, 0x0379ff00, 0x070000ff, 0x076c0000, + 0x068181bf, 0x0400e049, 0x0340002d, 0x050f802b, + 0x053fa80a, 0x06000016, 0x0660480e, 0x0302c0ff, + 0x034000ff, 0x01540427, 0x0582020c, 0x072d6000, + 0x0460040e, 0x050f80ff, 0x0104e0d1, 0x0379ff4e, + 0x0700ffff, 0x062d6002, 0x032fa009, 0x0004d0d0, + 0x074b004d, 0x07780000, 0x07ffff00, 0x055a044d, + 0x070000ff, 0x00201008, 0x04002051, 0x06003051, + 0x05304000, 0x07000060, 0x03205009, 0x07006022, + 0x0460040e, 0x050f80ff, 0x032fa03a, 0x06603c0e, + 0x050f80ff, 0x073fa00a, 0x07000027, 0x050010d1, + 0x0460320e, 0x050f80ff, 0x012fa80a, 0x060ff00e, + 0x055c042e, 0x04810210, 0x07c00000, 0x0400e026, + 0x008001cb, 0x0202c026, 0x008001e6, 0x0500e02e, + 0x008001e6, 0x0400e051, 0x01800209, 0x0349c0e4, + 0x04810215, 0x07c00000, 0x013e4000, 0x070c0000, + 0x07c00000, 0x013e4000, 0x03080000, 0x07c00000, + 0x009702f4, 0x022a5002, 0x0790821d, 0x00910291, + 0x030400a6, 0x0678aae5, 0x06000001, 0x00a1860e, + 0x06600c40, 0x050f80ff, 0x032fa021, 0x074b0000, + 0x076c0600, 0x07818293, 0x05600403, 0x050f80ff, + 0x073fa009, 0x06000002, 0x0279ff04, 0x0700ffff, + 0x010440d7, 0x0179fe44, 0x0700ffff, 0x045c0404, + 0x07818295, 0x0349f044, 0x0681829e, 0x02495001, + 0x06818297, 0x060ff079, 0x045c0440, 0x0781823c, + 0x0644f07a, 0x002fb008, 0x060ff079, 0x045c0440, + 0x07818241, 0x0644f07a, 0x002fb008, 0x0648f001, + 0x07818288, 0x04600e40, 0x050f80ff, 0x06480001, + 0x04810257, 0x0448e001, 0x04810273, 0x02460001, + 0x0644f001, 0x012fa80a, 0x04008040, 0x05a004ee, + 0x0286828c, 0x05a004d8, 0x062da001, 0x013e4000, + 0x06000080, 0x06930013, 0x02920013, 0x02800010, + 0x0644f001, 0x012fa80a, 0x020ef002, 0x00860275, + 0x04600840, 0x050f80ff, 0x053fa809, 0x06000002, + 0x05780105, 0x00800440, 0x017c0105, 0x05000400, + 0x06818275, 0x06601e02, 0x050f80ff, 0x053fa809, + 0x06000002, 0x04602a40, 0x050f80ff, 0x070ff005, + 0x053fa809, 0x06000002, 0x055c0405, 0x06818275, + 0x04008040, 0x0045e008, 0x05a004d8, 0x00800251, + 0x0644f001, 0x012fa80a, 0x050020d8, 0x04600440, + 0x050f80ff, 0x073fa00a, 0x06000001, 0x06480001, + 0x07818281, 0x05308000, 0x03040000, 0x06009040, + 0x04a004dc, 0x00800251, 0x06a0060e, 0x054b0800, + 0x056a0700, 0x06600c40, 0x050f80ff, 0x032fa00a, + 0x00800251, 0x013e4000, 0x06000080, 0x01209288, + 0x018004e4, 0x06009008, 0x05308000, 0x05004000, + 0x04a004dc, 0x00800251, 0x02209002, 0x008002e5, + 0x03209000, 0x008002e5, 0x02209004, 0x008002e5, + 0x04a002fd, 0x062da001, 0x05308000, 0x05002000, + 0x06009040, 0x04a004dc, 0x02800013, 0x013e4000, + 0x06000080, 0x02495001, 0x078182db, 0x04600840, + 0x050f80ff, 0x053fa809, 0x06000001, 0x0721f000, + 0x0349f003, 0x058102aa, 0x0245f01f, 0x06000002, + 0x018602db, 0x07601400, 0x050f80ff, 0x012fa809, + 0x06480001, 0x058102db, 0x06602440, 0x050f80ff, + 0x012fa809, 0x020ef001, 0x038682db, 0x019b02db, + 0x050020d8, 0x062da001, 0x06303002, 0x05000430, + 0x04600440, 0x050f80ff, 0x073fa012, 0x06000001, + 0x028f82bf, 0x050040d8, 0x062da001, 0x07601e00, + 0x050f80ff, 0x073fa009, 0x06000001, 0x060ff004, + 0x00540402, 0x048202d9, 0x06005051, 0x06006051, + 0x06602240, 0x050f80ff, 0x063fa01a, 0x06000002, + 0x06600a40, 0x050f80ff, 0x073fa00a, 0x07000003, + 0x060ff040, 0x045a041f, 0x010eb0ff, 0x06930013, + 0x02920013, 0x02800010, 0x04004002, 0x018002c9, + 0x04a002fd, 0x062da001, 0x05308000, 0x07005000, + 0x06009040, 0x04a004dc, 0x050080d8, 0x05a004e1, + 0x062da001, 0x02800013, 0x050fd009, 0x050fd041, + 0x013e4000, 0x06000080, 0x05308000, 0x03013000, + 0x04a004dc, 0x010440d7, 0x0349f044, 0x048102f2, + 0x062da001, 0x008f02f2, 0x03e00000, 0x062da001, + 0x02800013, 0x0249c0e5, 0x06810013, 0x062da001, + 0x07f00000, 0x07f00000, 0x033e5000, 0x070c0000, + 0x018f02f6, 0x03800011, 0x050020d8, 0x04600440, + 0x050f80ff, 0x073fa00a, 0x06000001, 0x07c00000, + 0x002fb001, 0x03800306, 0x012fb000, 0x03075087, + 0x068d0307, 0x03386000, 0x03020000, 0x04482075, + 0x06810352, 0x0648a0e6, 0x07810347, 0x0642007f, + 0x06810345, 0x0340007e, 0x060ff038, 0x0154047e, + 0x02d00334, 0x0560027d, 0x050f80ff, 0x032fa009, + 0x030ef000, 0x02860504, 0x0107d000, 0x05600800, + 0x050f80ff, 0x032fa009, 0x03681e00, 0x04500420, + 0x050f80ff, 0x073fa009, 0x0700003f, 0x03800311, + 0x070ff07d, 0x0450047c, 0x050f80ff, 0x002fa819, + 0x078d0327, 0x02080001, 0x00081002, 0x0448807a, + 0x0781032e, 0x0379ff03, 0x070000ff, 0x01082003, + 0x068d032f, 0x02386004, 0x03010000, 0x072e6c00, + 0x02800352, 0x0380033a, 0x0380033c, 0x0280033e, + 0x02800340, 0x03800342, 0x03800344, 0x0727c005, + 0x02800323, 0x0627c008, 0x02800323, 0x0627c00b, + 0x02800323, 0x0627c00e, 0x02800323, 0x0727c011, + 0x02800323, 0x03800314, 0x052e6800, 0x02800352, + 0x044880e6, 0x07810533, 0x052e6200, 0x070ff088, + 0x0179feff, 0x070fffff, 0x04818501, 0x060ff083, + 0x0086836d, 0x033e6000, 0x07000003, 0x068d0352, + 0x07286000, 0x07f00000, 0x078d0355, 0x038c0306, + 0x0648c0e6, 0x05818372, 0x0448e0e6, 0x0781036a, + 0x004920e6, 0x07810365, 0x07a0056f, 0x05001088, + 0x00700101, 0x03100000, 0x00088001, 0x033e6000, + 0x07000088, 0x03800560, 0x02386001, 0x07030000, + 0x033e6000, 0x06000008, 0x028003f1, 0x02799075, + 0x0500040f, 0x06810010, 0x06601479, 0x050080ff, + 0x06309052, 0x0600003e, 0x02800376, 0x06602279, + 0x050080ff, 0x05309812, 0x07000041, 0x0648007a, + 0x0781037e, 0x04488075, 0x0581837e, 0x040f8008, + 0x070fa009, 0x0049107a, 0x01a183f3, 0x00798075, + 0x06000507, 0x05818521, 0x0448b075, 0x06810385, + 0x02493075, 0x0681050e, 0x0249c0e6, 0x048183e0, + 0x0648c0e6, 0x0581839a, 0x068d0389, 0x02386001, + 0x07030000, 0x0049107a, 0x07810390, 0x020ef083, + 0x0386039a, 0x06483075, 0x068103ef, 0x0678007a, + 0x07000035, 0x03a184cf, 0x05308000, 0x07060000, + 0x06009079, 0x04a004dc, 0x028003ef, 0x0448807a, + 0x0681039e, 0x06483075, 0x058104f9, 0x0448d07a, + 0x068103a2, 0x06483075, 0x058104f9, 0x068d03a2, + 0x02386001, 0x07030000, 0x0444e07a, 0x0648307a, + 0x048183c7, 0x0448707a, 0x068103ea, 0x0648f07a, + 0x078103b2, 0x05a004cf, 0x04008079, 0x05a004ee, + 0x008683c2, 0x05a004d8, 0x028003ef, 0x0560107b, + 0x050f80ff, 0x032fa009, 0x0349c000, 0x058183c0, + 0x04600e79, 0x050f80ff, 0x073fa00a, 0x0600003d, + 0x06600a79, 0x050f80ff, 0x053fa80a, 0x06000010, + 0x028003ef, 0x0046e07a, 0x028003ea, 0x06009008, + 0x05308000, 0x05004000, 0x04a004dc, 0x028003ef, + 0x0560167b, 0x050f80ff, 0x032fa011, 0x070ff000, + 0x04500401, 0x030460ff, 0x060ff025, 0x00540446, + 0x078203d1, 0x030460ff, 0x04092046, 0x05a00218, + 0x06600679, 0x050f80ff, 0x00201007, 0x012fa80a, + 0x0046047a, 0x034630ff, 0x050020ff, 0x06003051, + 0x04600e79, 0x050f80ff, 0x073fa012, 0x06000001, + 0x028003ef, 0x033e6a00, 0x0202000e, 0x02079051, + 0x07000088, 0x078d03e4, 0x0744c000, 0x01088000, + 0x03386006, 0x03010000, 0x02800010, 0x05a004cf, + 0x05308000, 0x03020000, 0x06009079, 0x04a004dc, + 0x033e6a00, 0x0302000a, 0x02079051, 0x02800010, + 0x04603e79, 0x050f80ff, 0x032fa009, 0x070ff000, + 0x0186040c, 0x057dfeff, 0x07ffffff, 0x0581040c, + 0x050f8000, 0x012fa811, 0x0079fe02, 0x070000ff, + 0x077d66ff, 0x060000dc, 0x0781840c, 0x060ff001, + 0x0286840d, 0x064b0002, 0x06420002, 0x060ff002, + 0x05500400, 0x050f80ff, 0x05004084, 0x073fa00a, + 0x06000002, 0x07c00000, 0x04600201, 0x050f80ff, + 0x073fa009, 0x06000001, 0x0079fe02, 0x070000ff, + 0x077d72ff, 0x070000dd, 0x0781840c, 0x064b0002, + 0x06420002, 0x06000001, 0x01800406, 0x0605004c, + 0x0180041e, 0x0493041a, 0x04a004d5, 0x054bc450, + 0x05810421, 0x01d00422, 0x01800421, 0x00800432, + 0x00800434, 0x00800432, 0x008004a7, 0x0180043f, + 0x00800434, 0x01800471, 0x00800432, 0x00800432, + 0x008004ab, 0x00800432, 0x018004af, 0x008004c4, + 0x01800488, 0x00800432, 0x00800432, 0x00209432, + 0x018004e4, 0x0379ff50, 0x070fffff, 0x060ff079, + 0x055c0450, 0x048104a4, 0x002fb008, 0x060ff079, + 0x055c0450, 0x058104a3, 0x04a004c7, 0x0180049c, + 0x0179fe50, 0x070fffff, 0x070050ff, 0x060ff079, + 0x055c0405, 0x04810449, 0x002fb008, 0x060ff079, + 0x055c0405, 0x078184a0, 0x070ff087, 0x017980ff, + 0x06000507, 0x06818451, 0x02203040, 0x05002087, + 0x0049d002, 0x0481046b, 0x04930458, 0x01257000, + 0x073c3fff, 0x0700000f, 0x052e4003, 0x072e5030, + 0x0304c050, 0x02400057, 0x06740057, 0x06000002, + 0x06820016, 0x04002083, 0x07003084, 0x04004085, + 0x06602279, 0x050f80ff, 0x063fa01a, 0x06000001, + 0x05a004cf, 0x07a00578, 0x033e6a00, 0x0302000a, + 0x062e5020, 0x003e4002, 0x07000a00, 0x028003f1, + 0x07420003, 0x0781844e, 0x00798002, 0x06000507, + 0x06818451, 0x0180045c, 0x05930478, 0x01257000, + 0x073c3fff, 0x0700000f, 0x052e4003, 0x072e5030, + 0x0304c050, 0x067800e6, 0x07000041, 0x0581047d, + 0x07a00581, 0x04818016, 0x002fb008, 0x067800e6, + 0x07000041, 0x04810483, 0x07a00581, 0x04818016, + 0x062e5020, 0x003e4002, 0x07000a00, 0x03e00000, + 0x02800010, 0x0379ff50, 0x070fffff, 0x060ff079, + 0x055c0450, 0x0781848e, 0x0245507a, 0x002fb008, + 0x060ff079, 0x055c0450, 0x07818493, 0x0245507a, + 0x002fb008, 0x05600e50, 0x050f80ff, 0x012fa809, + 0x02455001, 0x05600e50, 0x050f80ff, 0x012fa80a, + 0x0080049d, 0x002fb008, 0x003e4002, 0x07000a00, + 0x02800016, 0x079384a3, 0x062e5020, 0x042e4002, + 0x002fb008, 0x013e4000, 0x05000e00, 0x02800016, + 0x0179fe50, 0x070fffff, 0x010210ff, 0x02800016, + 0x0179fe50, 0x070fffff, 0x050340ff, 0x0080049d, + 0x0179fe50, 0x070fffff, 0x0102e0ff, 0x0760282e, + 0x050f80ff, 0x05222000, 0x07223000, 0x05224000, + 0x07225000, 0x07226000, 0x05227000, 0x05228000, + 0x07229000, 0x0722a000, 0x0522b000, 0x063fa051, + 0x07000011, 0x0202c026, 0x0522d000, 0x052e400c, + 0x02800016, 0x030430d4, 0x062e5008, 0x00800176, + 0x05600e50, 0x050f80ff, 0x032fa009, 0x03460000, + 0x018004d2, 0x0246007a, 0x0045207a, 0x008004d0, + 0x0246007a, 0x0600007a, 0x04600e79, 0x050f80ff, + 0x032fa00a, 0x07c00000, 0x029284d5, 0x070500e1, + 0x07c00000, 0x0245f008, 0x048404d9, 0x020e0008, + 0x07c00000, 0x070ff009, 0x065a0008, 0x058404de, + 0x020e0008, 0x07c00000, 0x058404e1, 0x020e0008, + 0x07c00000, 0x05308000, 0x0500d000, 0x04a004dc, + 0x04a004e9, 0x02800010, 0x052e4300, 0x072e500c, + 0x073c3fff, 0x0700000f, 0x07c00000, 0x06602208, + 0x050f80ff, 0x032fa011, 0x076a0000, 0x068184f7, + 0x066a0001, 0x048104f7, 0x04002051, 0x07c00000, + 0x00202001, 0x07c00000, 0x0648307a, 0x00a18608, + 0x05a004cc, 0x05308000, 0x05001000, 0x06009079, + 0x04a004dc, 0x03800560, 0x0249c0e6, 0x058104f9, + 0x0280036d, 0x0648307a, 0x07818196, 0x05a004cf, + 0x05308000, 0x03013000, 0x03209006, 0x04a004dc, + 0x033e6000, 0x07030000, 0x02800345, 0x02490075, + 0x0781051e, 0x04002089, 0x04780102, 0x07f00000, + 0x05001088, 0x07a0056f, 0x04740101, 0x03100000, + 0x060ff002, 0x045c0401, 0x0481851f, 0x00088001, + 0x033e6000, 0x070000c0, 0x0380055c, 0x07f00000, + 0x0220951f, 0x018004e4, 0x0648307a, 0x07810527, + 0x06780075, 0x06000007, 0x0581852e, 0x06a00608, + 0x06486075, 0x06818194, 0x02490075, 0x0781819a, + 0x04487075, 0x05818536, 0x0280053d, 0x05308000, + 0x03010000, 0x06009079, 0x04a004dc, 0x02800010, + 0x0448e0e6, 0x04818352, 0x00800192, 0x05308000, + 0x0500e000, 0x06009079, 0x04a004dc, 0x04008089, + 0x05a004e1, 0x0380055c, 0x05a004cc, 0x05308000, + 0x0700f000, 0x06009079, 0x07000088, 0x06a00545, + 0x04a004dc, 0x02800010, 0x03386000, 0x07030000, + 0x07f00000, 0x078d0548, 0x033e6a00, 0x0202000e, + 0x02079051, 0x0448b075, 0x07810553, 0x02493075, + 0x07810553, 0x05301005, 0x03010000, 0x03800555, + 0x05301006, 0x03010000, 0x05002087, 0x06485002, + 0x05818555, 0x0744c000, 0x01088000, 0x02086001, + 0x07c00000, 0x05001088, 0x07a0056f, 0x0644c001, + 0x00088001, 0x033e6a00, 0x0202000e, 0x004920e6, + 0x05818565, 0x02079051, 0x078d0565, 0x060ff089, + 0x034990ff, 0x0781056c, 0x03386005, 0x03010000, + 0x02800010, 0x03386006, 0x03010000, 0x02800010, + 0x078d056f, 0x03386000, 0x07030000, 0x07f00000, + 0x068d0573, 0x070ff087, 0x074850ff, 0x05818574, + 0x07c00000, 0x078d0578, 0x02386001, 0x07030000, + 0x07f00000, 0x068d057c, 0x070ff087, 0x074850ff, + 0x0581857d, 0x07c00000, 0x05002087, 0x0049d002, + 0x05818590, 0x002fb008, 0x067800e6, 0x07000041, + 0x002fb008, 0x05818590, 0x07a005a6, 0x0448e002, + 0x07810593, 0x0648a002, 0x0481859d, 0x06486002, + 0x06810597, 0x02400057, 0x056a02ff, 0x07c00000, + 0x07a005a6, 0x06788102, 0x06000004, 0x05818590, + 0x04002089, 0x070ff0d4, 0x045c0402, 0x077800ff, + 0x07f00000, 0x05818590, 0x00202010, 0x038c0590, + 0x07f00000, 0x06420002, 0x0481859e, 0x07a00578, + 0x033e6a00, 0x0302000a, 0x07c00000, 0x07f00000, + 0x060ff0a2, 0x050020ff, 0x060ff0a2, 0x045c0402, + 0x048185a7, 0x07c00000, 0x05a00218, 0x03495047, + 0x078105b2, 0x0320901d, 0x02800604, 0x0220901f, + 0x02800604, 0x014980e4, 0x04818010, 0x013e4000, + 0x07003000, 0x05600e35, 0x050f80ff, 0x07a006fc, + 0x01208003, 0x05a004e1, 0x038005cc, 0x03209009, + 0x02800604, 0x03209011, 0x02800604, 0x02209007, + 0x02800604, 0x03209003, 0x02800604, 0x00498043, + 0x058185be, 0x00497043, 0x048185c2, 0x02209001, + 0x02800604, 0x0220900d, 0x02800604, 0x0320900f, + 0x02800604, 0x03493000, 0x068105d5, 0x027c0045, + 0x070a0000, 0x078105de, 0x0220900b, 0x02800604, + 0x02209013, 0x05308000, 0x01012000, 0x04a004dc, + 0x00800183, 0x03209005, 0x02800604, 0x072e500c, + 0x00208002, 0x05a004e1, 0x02800010, 0x02209015, + 0x02800604, 0x072d6000, 0x05308000, 0x05007000, + 0x07f00000, 0x070090d1, 0x0379ff09, 0x0700ffff, + 0x04a004dc, 0x03209017, 0x02800604, 0x033e5000, + 0x06000080, 0x02209019, 0x02800604, 0x072d6000, + 0x033e5000, 0x06000080, 0x07f00000, 0x060ff0d0, 0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff, - 0x048185e0, 0x050f8030, 0x032fa009, 0x0379ff00, + 0x04818010, 0x02400058, 0x00642058, 0x06820010, + 0x033e5000, 0x06000080, 0x04058051, 0x0320901b, + 0x02800604, 0x05308000, 0x01012000, 0x04a004dc, + 0x00800176, 0x05a00218, 0x05308000, 0x05008000, + 0x06009079, 0x04a004dc, 0x07c00000, 0x034900e4, + 0x05818618, 0x013e4000, 0x070000c0, 0x07f00000, + 0x034900e4, 0x04818616, 0x07c00000, 0x013e4000, + 0x06000080, 0x07f00000, 0x07f00000, 0x07f00000, + 0x034900e4, 0x06810610, 0x03800618, 0x072d6000, + 0x00498043, 0x06810632, 0x060ff0d0, 0x0179feff, + 0x0700ffff, 0x057dfeff, 0x0700ffff, 0x058185e2, + 0x050f8030, 0x032fa009, 0x0379ff00, 0x0700ffff, + 0x070ff0d1, 0x0179feff, 0x0700ffff, 0x055c0400, + 0x078105e2, 0x04004051, 0x0280067a, 0x06a006dc, + 0x062d6001, 0x020ef004, 0x038605e4, 0x06600004, + 0x050f80ff, 0x032fa009, 0x074b0000, 0x05002000, + 0x0769ff00, 0x01640800, 0x078205e4, 0x01640e00, + 0x058285e4, 0x070ff036, 0x045c0404, 0x0581864d, + 0x072d6000, 0x050f8030, 0x032fa009, 0x0379ff00, 0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff, - 0x055c0400, 0x068105e0, 0x04004051, 0x03800678, - 0x06a006da, 0x062d6001, 0x020ef004, 0x038605e2, - 0x06600004, 0x050f80ff, 0x032fa009, 0x074b0000, - 0x05002000, 0x0769ff00, 0x01640800, 0x078205e2, - 0x01640e00, 0x058285e2, 0x070ff036, 0x045c0404, - 0x0581864b, 0x072d6000, 0x050f8030, 0x032fa009, - 0x0379ff00, 0x0700ffff, 0x070ff0d1, 0x0179feff, - 0x0700ffff, 0x055c0400, 0x068105e0, 0x04482034, - 0x068105fd, 0x06483034, 0x048185fd, 0x070ff0d4, - 0x077800ff, 0x070000f0, 0x037c00ff, 0x06000010, - 0x07810678, 0x07a006d4, 0x024900e5, 0x0681065b, - 0x033e5000, 0x06000080, 0x02800010, 0x04601c04, - 0x050f80ff, 0x053fa809, 0x06000020, 0x030ef041, - 0x028605ec, 0x062d6002, 0x05602a41, 0x050f80ff, - 0x012fa809, 0x060ff0d0, 0x074b00ff, 0x045c0401, - 0x04818676, 0x062d6001, 0x07602841, 0x050f80ff, - 0x053fa809, 0x06000001, 0x070ff0d1, 0x054b80ff, - 0x074b0003, 0x055c0403, 0x04818676, 0x033e5000, - 0x06000080, 0x0180070c, 0x07600041, 0x0380065c, - 0x07a006d4, 0x024900e5, 0x0781067e, 0x033e5000, - 0x06000080, 0x02800010, 0x07a006c0, 0x030ef041, - 0x038605f0, 0x04058051, 0x072d6000, 0x05601041, - 0x050f80ff, 0x012fa809, 0x0600a0d0, 0x0500b0d1, - 0x062d6001, 0x07f00000, 0x07f00000, 0x0600c0d0, - 0x0500d0d1, 0x062d6002, 0x0279ff0d, 0x07ff0000, - 0x044d800d, 0x060ff0d0, 0x074b00ff, 0x065a000d, - 0x06601201, 0x050f80ff, 0x073fa022, 0x07000005, - 0x0079fe0d, 0x070000ff, 0x050020ff, 0x05602a41, - 0x050f80ff, 0x073fa00a, 0x06000001, 0x020ef004, - 0x038606bd, 0x04601c04, 0x050f80ff, 0x053fa809, - 0x06000001, 0x050f80ff, 0x053fa80a, 0x06000020, - 0x07602841, 0x050f80ff, 0x073fa009, 0x06000001, - 0x0279ff02, 0x070000ff, 0x0678000d, 0x0700ff00, - 0x065a0002, 0x07602841, 0x050f80ff, 0x073fa00a, - 0x06000001, 0x07600041, 0x050f80ff, 0x053fa80a, - 0x06000001, 0x07601241, 0x050f80ff, 0x073fa00a, - 0x06000002, 0x033e5000, 0x06000080, 0x0180070c, - 0x040f8032, 0x073fa011, 0x06000001, 0x060ff002, - 0x055c0403, 0x048186c8, 0x00041051, 0x07c00000, - 0x04600402, 0x04500432, 0x050f80ff, 0x053fa809, - 0x06000020, 0x00400402, 0x01680eff, 0x070030ff, - 0x040f8032, 0x053fa80a, 0x06000001, 0x07c00000, - 0x024900e5, 0x078106d7, 0x07c00000, 0x033e5000, - 0x070000c0, 0x07c00000, 0x05004036, 0x060000d0, - 0x0179fe00, 0x0700ffff, 0x057dfeff, 0x0700ffff, - 0x078106f9, 0x070000d1, 0x0379ff00, 0x0700ffff, - 0x06005051, 0x060ff031, 0x05500405, 0x050f80ff, - 0x073fa009, 0x06000002, 0x020ef004, 0x038606f3, - 0x04600404, 0x050f80ff, 0x012fa809, 0x0079fe01, - 0x0700ffff, 0x055c0400, 0x078106f9, 0x01400405, - 0x070050ff, 0x057de0ff, 0x06000007, 0x048186e5, - 0x04004051, 0x07c00000, 0x072d6000, 0x07f00000, - 0x07f00000, 0x000110d0, 0x010120d1, 0x062d6001, - 0x07f00000, 0x07f00000, 0x020130d0, 0x010140d1, - 0x062d6002, 0x010170d4, 0x07f00000, 0x020150d0, - 0x030160d1, 0x053fa83a, 0x06000008, 0x07c00000, - 0x07600c41, 0x050f80ff, 0x073fa009, 0x06000001, - 0x04780102, 0x07ffff00, 0x046a0702, 0x050f80ff, - 0x073fa00a, 0x06000001, 0x05600e41, 0x050f80ff, - 0x032fa069, 0x03800053, 0xdb4ee9e2, 0x02800004, - 0x00000000, 0x00008000, 0x00000542, 0x040f801f, - 0x012fa8c9, 0x040f801f, 0x073fa081, 0x06000010, - 0x03200005, 0x07420000, 0x050fb000, 0x040f801f, - 0x073fa011, 0x06000038, 0x040f801f, 0x053fa859, - 0x0700003a, 0x050fe000, 0x0581800a, 0x0784003c, - 0x04958019, 0x030e0011, 0x072e4200, 0x03800014, - 0x0291001f, 0x050010c0, 0x04482001, 0x058180fa, - 0x06483001, 0x0681815d, 0x02920029, 0x068b0029, - 0x008a0162, 0x050010c0, 0x06780001, 0x050007c0, - 0x06818240, 0x06780001, 0x0500f800, 0x06818280, - 0x03910030, 0x040fe029, 0x03860030, 0x076c001d, - 0x058102b1, 0x076c0a1d, 0x048102da, 0x029200ab, - 0x040fe02f, 0x0386003c, 0x06000013, 0x050fb000, - 0x066c0073, 0x068103ec, 0x014920e4, 0x0581803c, - 0x03400000, 0x076c0a00, 0x04818034, 0x0696003e, - 0x03b900ca, 0x05908014, 0x010170e1, 0x07780017, - 0x03e00000, 0x06810091, 0x050010ff, 0x0179fe17, + 0x055c0400, 0x078105e2, 0x04482034, 0x078105ff, + 0x06483034, 0x058185ff, 0x070ff0d4, 0x077800ff, + 0x070000f0, 0x037c00ff, 0x06000010, 0x0681067a, + 0x06a006d6, 0x024900e5, 0x0681065d, 0x033e5000, + 0x06000080, 0x02800010, 0x04601c04, 0x050f80ff, + 0x053fa809, 0x06000020, 0x030ef041, 0x038605ee, + 0x062d6002, 0x05602a41, 0x050f80ff, 0x012fa809, + 0x060ff0d0, 0x074b00ff, 0x045c0401, 0x05818678, + 0x062d6001, 0x07602841, 0x050f80ff, 0x053fa809, + 0x06000001, 0x070ff0d1, 0x054b80ff, 0x074b0003, + 0x055c0403, 0x05818678, 0x033e5000, 0x06000080, + 0x0080070e, 0x07600041, 0x0280065e, 0x06a006d6, + 0x024900e5, 0x06810680, 0x033e5000, 0x06000080, + 0x02800010, 0x06a006c2, 0x030ef041, 0x028605f2, + 0x04058051, 0x072d6000, 0x05601041, 0x050f80ff, + 0x012fa809, 0x0600a0d0, 0x0500b0d1, 0x062d6001, + 0x07f00000, 0x07f00000, 0x0600c0d0, 0x0500d0d1, + 0x062d6002, 0x0279ff0d, 0x07ff0000, 0x044d800d, + 0x060ff0d0, 0x074b00ff, 0x065a000d, 0x06601201, + 0x050f80ff, 0x073fa022, 0x07000005, 0x0079fe0d, + 0x070000ff, 0x050020ff, 0x05602a41, 0x050f80ff, + 0x073fa00a, 0x06000001, 0x020ef004, 0x028606bf, + 0x04601c04, 0x050f80ff, 0x053fa809, 0x06000001, + 0x050f80ff, 0x053fa80a, 0x06000020, 0x07602841, + 0x050f80ff, 0x073fa009, 0x06000001, 0x0279ff02, + 0x070000ff, 0x0678000d, 0x0700ff00, 0x065a0002, + 0x07602841, 0x050f80ff, 0x073fa00a, 0x06000001, + 0x07600041, 0x050f80ff, 0x053fa80a, 0x06000001, + 0x07601241, 0x050f80ff, 0x073fa00a, 0x06000002, + 0x033e5000, 0x06000080, 0x0080070e, 0x040f8032, + 0x073fa011, 0x06000001, 0x060ff002, 0x055c0403, + 0x058186ca, 0x00041051, 0x07c00000, 0x04600402, + 0x04500432, 0x050f80ff, 0x053fa809, 0x06000020, + 0x00400402, 0x01680eff, 0x070030ff, 0x040f8032, + 0x053fa80a, 0x06000001, 0x07c00000, 0x024900e5, + 0x068106d9, 0x07c00000, 0x033e5000, 0x070000c0, + 0x07c00000, 0x05004036, 0x060000d0, 0x0179fe00, + 0x0700ffff, 0x057dfeff, 0x0700ffff, 0x068106fb, + 0x070000d1, 0x0379ff00, 0x0700ffff, 0x06005051, + 0x060ff031, 0x05500405, 0x050f80ff, 0x073fa009, + 0x06000002, 0x020ef004, 0x038606f5, 0x04600404, + 0x050f80ff, 0x012fa809, 0x0079fe01, 0x0700ffff, + 0x055c0400, 0x068106fb, 0x01400405, 0x070050ff, + 0x057de0ff, 0x06000007, 0x058186e7, 0x04004051, + 0x07c00000, 0x072d6000, 0x07f00000, 0x07f00000, + 0x000110d0, 0x010120d1, 0x062d6001, 0x07f00000, + 0x07f00000, 0x020130d0, 0x010140d1, 0x062d6002, + 0x010170d4, 0x07f00000, 0x020150d0, 0x030160d1, + 0x053fa83a, 0x06000008, 0x07c00000, 0x07600c41, + 0x050f80ff, 0x073fa009, 0x06000001, 0x04780102, + 0x07ffff00, 0x046a0702, 0x050f80ff, 0x073fa00a, + 0x06000001, 0x05600e41, 0x050f80ff, 0x032fa069, + 0x03800053, 0xba6b4e34, 0x02800004, 0x00000000, + 0x00008000, 0x00000518, 0x040f801f, 0x012fa8c9, + 0x040f801f, 0x073fa081, 0x06000010, 0x03200005, + 0x07420000, 0x050fb000, 0x040f801f, 0x073fa011, + 0x06000038, 0x040f801f, 0x053fa859, 0x0700003a, + 0x050fe000, 0x0581800a, 0x0684003d, 0x04958019, + 0x030e0011, 0x072e4200, 0x03800014, 0x0291001f, + 0x050010c0, 0x04482001, 0x058180e8, 0x06483001, + 0x0781814b, 0x02920029, 0x068b0029, 0x018a0150, + 0x050010c0, 0x06780001, 0x050007c0, 0x06818223, + 0x06780001, 0x0500f800, 0x07818263, 0x03910030, + 0x040fe029, 0x03860030, 0x076c001d, 0x04810294, + 0x076c0a1d, 0x048102b9, 0x0292003d, 0x040fe02f, + 0x0286003d, 0x06000013, 0x050fb000, 0x066c0073, + 0x068103c2, 0x0297003d, 0x014920e4, 0x0481803d, + 0x03400000, 0x076c0a00, 0x04818034, 0x0796003f, + 0x03b900b8, 0x05908014, 0x010170e1, 0x07780017, + 0x03e00000, 0x06810092, 0x050010ff, 0x0179fe17, 0x031fffff, 0x070000ff, 0x05600800, 0x050f80ff, 0x073fa009, 0x06000001, 0x06780002, 0x02800040, - 0x037c00ff, 0x03800000, 0x0681005d, 0x0249f002, - 0x078100aa, 0x0448e002, 0x0681005d, 0x07600c00, + 0x037c00ff, 0x03800000, 0x0681005e, 0x0249f002, + 0x068100ab, 0x0448e002, 0x0681005e, 0x07600c00, 0x050f80ff, 0x073fa009, 0x06000001, 0x06780002, - 0x07ffff00, 0x037c00ff, 0x05000200, 0x058180aa, - 0x064bd401, 0x03d0005f, 0x028000a8, 0x02800067, - 0x03800071, 0x0380007b, 0x02800085, 0x0280008f, - 0x028000a8, 0x028000a8, 0x050fe027, 0x0086806b, - 0x01028000, 0x0280006e, 0x07600027, 0x050f80ff, - 0x032fa00a, 0x01027000, 0x02400029, 0x038000aa, - 0x040fe025, 0x00868075, 0x03026000, 0x03800078, + 0x07ffff00, 0x037c00ff, 0x05000200, 0x048180ab, + 0x064bd401, 0x03d00060, 0x038000a9, 0x02800068, + 0x03800072, 0x0280007c, 0x02800086, 0x03800090, + 0x038000a9, 0x038000a9, 0x050fe027, 0x0186806c, + 0x01028000, 0x0380006f, 0x07600027, 0x050f80ff, + 0x032fa00a, 0x01027000, 0x02400029, 0x028000ab, + 0x040fe025, 0x00868076, 0x03026000, 0x02800079, 0x06600025, 0x050f80ff, 0x032fa00a, 0x03025000, - 0x02400029, 0x038000aa, 0x050fe021, 0x0086807f, - 0x01022000, 0x03800082, 0x07600021, 0x050f80ff, - 0x032fa00a, 0x01021000, 0x02400029, 0x038000aa, - 0x040fe023, 0x00868089, 0x01024000, 0x0280008c, + 0x02400029, 0x028000ab, 0x050fe021, 0x00868080, + 0x01022000, 0x02800083, 0x07600021, 0x050f80ff, + 0x032fa00a, 0x01021000, 0x02400029, 0x028000ab, + 0x040fe023, 0x0086808a, 0x01024000, 0x0380008d, 0x06600023, 0x050f80ff, 0x032fa00a, 0x03023000, - 0x02400029, 0x038000aa, 0x06a000da, 0x038000aa, - 0x01640817, 0x048280a8, 0x070ff017, 0x03d00095, - 0x0280009d, 0x0380009f, 0x028000a2, 0x038000a5, - 0x028000a8, 0x028000a8, 0x028000a8, 0x028000a8, - 0x03e00000, 0x03800014, 0x0590809f, 0x030160e1, - 0x038000aa, 0x049080a2, 0x030150e1, 0x038000aa, - 0x059080a5, 0x010140e1, 0x038000aa, 0x060fc013, - 0x07a0053a, 0x03800014, 0x014940e4, 0x00a180ae, - 0x0380003c, 0x02681e0d, 0x050fb0ff, 0x04600876, - 0x050f80ff, 0x053fa809, 0x06000001, 0x05488003, - 0x058180bd, 0x0400800d, 0x0120d000, 0x013e4000, - 0x05000200, 0x06009076, 0x04002075, 0x06a00526, - 0x07c00000, 0x072e4800, 0x07000012, 0x028000cd, - 0x0747f000, 0x05600800, 0x050f80ff, 0x012fa809, - 0x0249f001, 0x068100cd, 0x01012000, 0x052e4c00, - 0x07c00000, 0x070000eb, 0x0349f000, 0x048180c1, - 0x05600800, 0x050f80ff, 0x012fa809, 0x0448e001, - 0x068100d3, 0x07c00000, 0x0079c101, 0x07ffffff, - 0x027a4b01, 0x03800000, 0x05600800, 0x050f80ff, - 0x012fa80a, 0x07600c00, 0x050f80ff, 0x012fa821, - 0x06780001, 0x07ffff00, 0x037c00ff, 0x05000700, - 0x068100ef, 0x06601804, 0x070030ff, 0x050f80ff, - 0x012fa809, 0x05002000, 0x050f8003, 0x073fa00a, - 0x06000001, 0x040fe001, 0x038600f0, 0x04600201, - 0x050f80ff, 0x032fa00a, 0x07c00000, 0x050fe02e, - 0x018680f5, 0x0102e000, 0x0302f000, 0x038000f9, - 0x0760002e, 0x050f80ff, 0x032fa00a, 0x0102e000, - 0x07c00000, 0x022c0004, 0x056c041d, 0x0481010e, - 0x056c021d, 0x04810125, 0x056c081d, 0x04810137, - 0x076c061d, 0x04810151, 0x0521d000, 0x0202c013, - 0x0202a013, 0x02020013, 0x0460021a, 0x050f80ff, - 0x053fa80a, 0x07000009, 0x03b600be, 0x0484801f, - 0x0380003c, 0x040fe02a, 0x00860104, 0x06000013, - 0x04001013, 0x0560102b, 0x050f80ff, 0x032fa012, - 0x06420029, 0x0660002a, 0x050f80ff, 0x053fa809, - 0x06000001, 0x050fe003, 0x01860122, 0x01028003, - 0x0660002a, 0x050f80ff, 0x053fa80a, 0x07000009, - 0x00800152, 0x00028013, 0x00027013, 0x00800152, - 0x040fe02a, 0x01860103, 0x06420029, 0x0660002a, - 0x050f80ff, 0x053fa809, 0x06000001, 0x050fe003, - 0x00860134, 0x03026003, 0x0660002a, 0x050f80ff, - 0x053fa80a, 0x07000009, 0x00800152, 0x02026013, - 0x02025013, 0x00800152, 0x040fe02a, 0x01860103, - 0x06420029, 0x0660002a, 0x050f80ff, 0x053fa809, - 0x06000001, 0x050fe003, 0x00860146, 0x01022003, - 0x0660002a, 0x050f80ff, 0x053fa80a, 0x07000009, - 0x01800148, 0x00022013, 0x00021013, 0x0647f020, - 0x007a0120, 0x04000101, 0x04a002a2, 0x0400802a, - 0x06a0051f, 0x03948103, 0x0521d005, 0x00800104, - 0x0180010c, 0x0647f020, 0x06486020, 0x06818157, - 0x04a002a2, 0x01800103, 0x007a0120, 0x04000101, - 0x04a002a2, 0x0400802a, 0x06a0051f, 0x01800103, - 0x040fd02a, 0x052e4003, 0x00208010, 0x06a0051f, - 0x0180010c, 0x00018098, 0x07480018, 0x06818173, - 0x05481018, 0x07818171, 0x05482018, 0x0781816f, - 0x07483018, 0x0681816d, 0x002fb004, 0x01800174, - 0x012fb003, 0x01800174, 0x002fb002, 0x01800174, - 0x002fb001, 0x01800174, 0x012fb000, 0x0179fe78, - 0x070000ff, 0x030190ff, 0x00017086, 0x058b0178, - 0x03385000, 0x03020000, 0x07780017, 0x00430407, - 0x07818200, 0x046c0419, 0x058101b4, 0x046c0219, - 0x05810184, 0x07219000, 0x00800198, 0x07219000, - 0x07483017, 0x0481019e, 0x05482017, 0x058101a5, - 0x0448b075, 0x06818198, 0x06601476, 0x050f80ff, - 0x073fa022, 0x0600003e, 0x06000080, 0x05001081, - 0x05002082, 0x06003083, 0x05004084, 0x04601c76, - 0x050f80ff, 0x022fa02a, 0x07219000, 0x07780078, - 0x07ffff00, 0x045a0419, 0x010780ff, 0x0484801f, - 0x0380003c, 0x040fe07f, 0x008601ad, 0x04a001cd, - 0x00920198, 0x040fe07f, 0x06a681cd, 0x00800198, - 0x0560107b, 0x050f80ff, 0x032fa009, 0x0744f000, - 0x0560107b, 0x050f80ff, 0x032fa00a, 0x0180018b, - 0x052e400c, 0x040080fb, 0x046aa108, 0x06009076, - 0x04002075, 0x06a00526, 0x00800198, 0x06219001, - 0x05482017, 0x048101c1, 0x058b01b7, 0x060ff086, - 0x0349f0ff, 0x07818177, 0x07483017, 0x058101be, - 0x050fd0ff, 0x040fe07f, 0x06a681cd, 0x00800198, - 0x05004084, 0x05a00222, 0x00920198, 0x070ff07d, - 0x0450047c, 0x056004ff, 0x050f80ff, 0x032fa009, - 0x070ff000, 0x00540479, 0x030790ff, 0x018001a5, - 0x060ff079, 0x0054047a, 0x058201f9, 0x058101f9, - 0x070ff07d, 0x0450047c, 0x050f80ff, 0x002fa819, - 0x048b01d5, 0x02080001, 0x00081002, 0x01082003, - 0x048b01d9, 0x03385000, 0x03010000, 0x02400019, - 0x070ff003, 0x04500479, 0x030790ff, 0x0340007e, - 0x0642007f, 0x058101f9, 0x070ff07e, 0x050f80ff, - 0x032fa009, 0x050fe000, 0x028681f8, 0x070ff07d, - 0x056002ff, 0x050f80ff, 0x032fa009, 0x0107d000, - 0x018601fa, 0x0560087d, 0x050f80ff, 0x032fa009, - 0x03681e00, 0x0550041b, 0x050f80ff, 0x032fa009, - 0x0107e000, 0x070ff07e, 0x018001e4, 0x0307c000, - 0x07c00000, 0x052e400c, 0x040080fb, 0x046aa108, - 0x06009076, 0x04002075, 0x02800526, 0x040fd076, - 0x050fd017, 0x060ff086, 0x077800ff, 0x07000060, - 0x037c00ff, 0x07000060, 0x06818202, 0x07780078, - 0x07ffff00, 0x045a0419, 0x010780ff, 0x06601476, - 0x050f80ff, 0x073fa022, 0x0600003e, 0x052e400c, - 0x04600876, 0x050f80ff, 0x053fa809, 0x06000001, - 0x05488003, 0x0481021c, 0x0400d0fb, 0x066a810d, - 0x013e4000, 0x07000300, 0x02800029, 0x040080fb, - 0x066a8108, 0x06009076, 0x04002075, 0x06a00526, - 0x02800029, 0x0240007f, 0x0742007e, 0x050f807e, - 0x032fa009, 0x050fe000, 0x0386823c, 0x070ff07d, - 0x055c047b, 0x04810231, 0x0760007d, 0x050f80ff, - 0x032fa009, 0x050fe000, 0x02868231, 0x070ff07b, - 0x0107d0ff, 0x0560087d, 0x050f80ff, 0x032fa009, - 0x03681e00, 0x0450041c, 0x0107e0ff, 0x050f80ff, - 0x032fa009, 0x050fe000, 0x0086023e, 0x0307c000, - 0x07c00000, 0x040fd076, 0x0380053a, 0x010180c0, - 0x0548e018, 0x07818259, 0x0748f018, 0x07818255, - 0x03490018, 0x06818251, 0x01491018, 0x0781824d, - 0x073c0000, 0x06000040, 0x02200004, 0x0180025c, - 0x073c0000, 0x06000020, 0x03200003, 0x0180025c, - 0x073c0000, 0x06000010, 0x02200002, 0x0180025c, - 0x073c0000, 0x06000008, 0x02200001, 0x0180025c, - 0x073c0000, 0x06000004, 0x06000013, 0x050fb000, - 0x040fe076, 0x00860275, 0x046c0273, 0x04810285, - 0x066c0073, 0x05810266, 0x040fd076, 0x07a0053a, - 0x03800014, 0x040fd076, 0x01800269, 0x00452075, - 0x00077013, 0x0647f075, 0x06486075, 0x0781826f, - 0x04a002a8, 0x00800275, 0x007a0175, 0x04000101, - 0x04a002a8, 0x04008076, 0x0245f008, 0x06a0051f, - 0x07273000, 0x05600272, 0x050f80ff, 0x053fa80a, - 0x07000009, 0x0379ff78, 0x070000ff, 0x02076013, - 0x02075013, 0x0484801f, 0x0380003c, 0x070fc0ff, - 0x052e400c, 0x00208020, 0x06a0051f, 0x0180027e, - 0x04600276, 0x050010ff, 0x040f8001, 0x032fa009, - 0x040f8001, 0x053fa80a, 0x07000009, 0x070ff000, - 0x02868297, 0x06601276, 0x050f80ff, 0x073fa009, - 0x0700000c, 0x07601818, 0x050f80ff, 0x053fa80a, - 0x07000009, 0x00800298, 0x07a000f0, 0x0448b075, - 0x04810268, 0x06000013, 0x04001013, 0x0560107b, - 0x050f80ff, 0x032fa012, 0x0046b075, 0x03b600be, - 0x01800269, 0x06000020, 0x04001016, 0x0460082a, - 0x050f80ff, 0x032fa012, 0x07c00000, 0x06000075, - 0x040010a2, 0x044b0801, 0x060ff016, 0x065a0001, - 0x04600876, 0x050f80ff, 0x032fa012, 0x07c00000, - 0x050fe022, 0x008602bc, 0x0421d004, 0x0302a022, - 0x04a002e9, 0x04488020, 0x048102ce, 0x040fd02a, - 0x0521d000, 0x0202a013, 0x02020013, 0x040fe026, - 0x018602d4, 0x0421d001, 0x0202a026, 0x04a002e9, - 0x0202c013, 0x00683e20, 0x070060ff, 0x056c0206, - 0x0681031c, 0x056c0406, 0x06810332, 0x076c0606, - 0x078103a3, 0x04488020, 0x068182d0, 0x056c1606, - 0x078103b1, 0x06a00516, 0x018002e2, 0x040fd02a, - 0x0521d000, 0x0202a013, 0x02020013, 0x050fe028, - 0x018602e2, 0x0302a028, 0x0421d002, 0x04a002e9, - 0x018002f0, 0x050fe022, 0x018602e2, 0x0421d004, - 0x0302a022, 0x04a002e9, 0x04488020, 0x078182e4, - 0x06a00516, 0x05848030, 0x0380003c, 0x040fd02a, - 0x0521d000, 0x0202a013, 0x02020013, 0x018002e2, - 0x0460082a, 0x050f80ff, 0x022fa031, 0x03020000, - 0x0002b004, 0x01018005, 0x07c00000, 0x0400702a, - 0x07a003e4, 0x007a0101, 0x07060000, 0x07303000, - 0x07008290, 0x07600018, 0x050f80ff, 0x053fa809, - 0x07000003, 0x0448e007, 0x068182fe, 0x06006013, - 0x03800305, 0x02400010, 0x048102fe, 0x06006010, - 0x0460322a, 0x050f80ff, 0x073fa00a, 0x07000003, - 0x050f801e, 0x032fa03a, 0x063aa020, 0x06000002, - 0x013e4000, 0x07000030, 0x0298030b, 0x070ff0f6, - 0x036830ff, 0x0581830c, 0x070f001e, 0x0560102b, - 0x050f10ff, 0x063f3c08, 0x0600000d, 0x013e4000, - 0x06000020, 0x040f801a, 0x0320000a, 0x022017d0, - 0x032fa012, 0x0202c013, 0x018002e2, 0x04007013, - 0x07a003e4, 0x007a0101, 0x07050000, 0x07303000, - 0x07008890, 0x074d0005, 0x06006013, 0x050f801e, - 0x032fa03a, 0x05601a2b, 0x050f80ff, 0x022fa019, - 0x04001002, 0x04002013, 0x040f801f, 0x022fa01a, - 0x073aa00c, 0x06000002, 0x07300c03, 0x0600000d, - 0x038003d1, 0x04007013, 0x07a003e4, 0x007a0101, - 0x03070000, 0x0660282a, 0x050f80ff, 0x073fa009, - 0x06000004, 0x02499008, 0x0781033f, 0x07303000, - 0x07008890, 0x03800341, 0x07303000, 0x04008980, - 0x05007003, 0x074d0005, 0x06006013, 0x050f801e, - 0x032fa03a, 0x0760142b, 0x050f80ff, 0x032fa021, - 0x064b0002, 0x02499008, 0x0781034d, 0x0644c002, - 0x054b0400, 0x050040ff, 0x06698104, 0x04818362, - 0x06000013, 0x04001013, 0x04780102, 0x06000010, - 0x06003013, 0x04004013, 0x06005013, 0x06006013, - 0x04007013, 0x00644015, 0x0682035e, 0x04448002, - 0x02205008, 0x040f801f, 0x032fa042, 0x04008015, - 0x0280039b, 0x046c8004, 0x04818370, 0x01208018, - 0x06780002, 0x07000003, 0x04818373, 0x06003001, - 0x06000013, 0x04001013, 0x04004013, 0x06005013, - 0x040f801f, 0x022fa032, 0x0280039b, 0x040fd02a, - 0x07a0053a, 0x03800014, 0x0379ff03, 0x070000ff, - 0x04488002, 0x0681037a, 0x070ff003, 0x04500408, - 0x050080ff, 0x0379ff00, 0x070000ff, 0x06489002, - 0x07810381, 0x070ff000, 0x04500408, 0x050080ff, - 0x07005003, 0x05004000, 0x06003001, 0x06000013, - 0x04001013, 0x040f801f, 0x022fa032, 0x05601c2b, - 0x050f80ff, 0x022fa031, 0x06600c1f, 0x050f80ff, - 0x022fa032, 0x02680608, 0x0681039b, 0x016408ff, - 0x057dfeff, 0x07ffffff, 0x034000ff, 0x045a0407, - 0x070000ff, 0x0760061e, 0x050f80ff, 0x032fa00a, - 0x06600908, 0x0669f908, 0x027a0008, 0x06000020, - 0x070aa0ff, 0x014a20ff, 0x037a00ff, 0x060000dc, - 0x070000ff, 0x038003d1, 0x04007013, 0x07a003e4, - 0x007a0101, 0x07030000, 0x07303000, 0x07008190, - 0x06006013, 0x050f801e, 0x032fa03a, 0x073aa000, - 0x06000002, 0x07300c00, 0x07000005, 0x038003d1, - 0x04007013, 0x07a003e4, 0x007a0101, 0x07810000, - 0x07303000, 0x07000090, 0x06006013, 0x06600c2a, - 0x050f80ff, 0x053fa809, 0x07000003, 0x04780107, - 0x07ffff00, 0x007c0107, 0x07000500, 0x048183c4, - 0x07303000, 0x05000890, 0x074d0005, 0x0660282a, - 0x050f80ff, 0x053fa809, 0x07000003, 0x0049d007, - 0x068103cb, 0x02206001, 0x050f801e, 0x032fa03a, - 0x073aa000, 0x06000002, 0x07300c00, 0x07000005, - 0x013e4000, 0x07000030, 0x029803d3, 0x070ff0f6, - 0x036830ff, 0x058183d4, 0x070f001e, 0x040f101f, - 0x070f3000, 0x013e4000, 0x06000020, 0x040f801a, - 0x0320000a, 0x022017d0, 0x032fa012, 0x018002e2, - 0x03200000, 0x06006076, 0x028003e6, 0x03200011, - 0x0600602a, 0x04a0046b, 0x05600406, 0x050f80ff, - 0x053fa809, 0x06000002, 0x07c00000, 0x0207602f, - 0x04600876, 0x050f80ff, 0x022fa031, 0x03075000, - 0x0007b004, 0x01018005, 0x06600076, 0x050020ff, - 0x050f80ff, 0x012fa809, 0x0202f001, 0x018683fa, - 0x0002e013, 0x040f8002, 0x053fa80a, 0x07000009, - 0x06273001, 0x0448b075, 0x06818404, 0x04602076, - 0x050f80ff, 0x053fa811, 0x0700003c, 0x0179fe78, - 0x070000ff, 0x030190ff, 0x0386840c, 0x04a00420, - 0x00078019, 0x0092041f, 0x00800464, 0x040fd076, - 0x040fd019, 0x04600276, 0x050020ff, 0x050f80ff, - 0x032fa009, 0x040f8002, 0x053fa80a, 0x07000009, - 0x050fe000, 0x0286841c, 0x07601818, 0x050f80ff, - 0x053fa80a, 0x07000009, 0x0180041d, 0x07a000f0, - 0x07273000, 0x02076013, 0x0380003c, 0x048b0420, - 0x03385000, 0x07030000, 0x05600818, 0x050f80ff, - 0x032fa009, 0x054b0400, 0x0308a0ff, 0x0179fe00, - 0x070000ff, 0x010880ff, 0x0448b075, 0x0581043a, - 0x0760147b, 0x050f80ff, 0x002fa819, 0x064b0001, - 0x02080002, 0x01081003, 0x00082001, 0x02083001, - 0x02079001, 0x0207a001, 0x00084013, 0x0207f013, - 0x0180045c, 0x06485075, 0x04810452, 0x02465075, - 0x06601476, 0x050f80ff, 0x073fa021, 0x0600003e, - 0x070ff07d, 0x0450047c, 0x050f80ff, 0x002fa819, - 0x048b0445, 0x02080001, 0x00081002, 0x01082003, - 0x03079003, 0x0208307a, 0x0340007e, 0x0642007f, - 0x04810457, 0x070ff07e, 0x05a001e4, 0x02928457, - 0x01800463, 0x048b0452, 0x06601476, 0x050f80ff, - 0x073fa041, 0x0600003e, 0x06602476, 0x050f80ff, - 0x073fa009, 0x06000007, 0x0008400e, 0x058b045c, - 0x03385000, 0x03010000, 0x06219001, 0x040fe07f, - 0x01860463, 0x008001cd, 0x07c00000, 0x00683e75, - 0x05810469, 0x0448d075, 0x0481048f, 0x018004bd, - 0x06a0051a, 0x0080041f, 0x02978476, 0x07602418, - 0x050f80ff, 0x012fa809, 0x06780001, 0x070000ff, - 0x075a0000, 0x070ff014, 0x0569feff, 0x054b08ff, - 0x075a0000, 0x05600418, 0x050f80ff, 0x012fa809, - 0x040fe007, 0x0386847d, 0x01204000, 0x0180048b, - 0x00700101, 0x03010000, 0x06780001, 0x07ff0000, - 0x076c00ff, 0x06818485, 0x00700101, 0x03010000, - 0x05600418, 0x050f80ff, 0x012fa80a, 0x06780001, - 0x07ff0000, 0x050040ff, 0x0279ff01, 0x0700ffff, - 0x05002014, 0x07c00000, 0x04007076, 0x0448b075, - 0x058104a9, 0x03200011, 0x06006076, 0x06a003e6, + 0x02400029, 0x028000ab, 0x06a000c8, 0x028000ab, + 0x01640817, 0x058280a9, 0x070ff017, 0x03d00096, + 0x0280009e, 0x038000a0, 0x038000a3, 0x038000a6, + 0x038000a9, 0x038000a9, 0x038000a9, 0x038000a9, + 0x03e00000, 0x03800014, 0x059080a0, 0x030160e1, + 0x028000ab, 0x059080a3, 0x030150e1, 0x028000ab, + 0x059080a6, 0x010140e1, 0x028000ab, 0x060fc013, + 0x06a00510, 0x03800014, 0x072e4800, 0x07000012, + 0x038000bb, 0x0747f000, 0x05600800, 0x050f80ff, + 0x012fa809, 0x0249f001, 0x078100bb, 0x01012000, + 0x052e4c00, 0x07c00000, 0x070000eb, 0x0349f000, + 0x058180af, 0x05600800, 0x050f80ff, 0x012fa809, + 0x0448e001, 0x068100c1, 0x07c00000, 0x0079c101, + 0x07ffffff, 0x027a4b01, 0x03800000, 0x05600800, + 0x050f80ff, 0x012fa80a, 0x07600c00, 0x050f80ff, + 0x012fa821, 0x06780001, 0x07ffff00, 0x037c00ff, + 0x05000700, 0x078100dd, 0x06601804, 0x070030ff, + 0x050f80ff, 0x012fa809, 0x05002000, 0x050f8003, + 0x073fa00a, 0x06000001, 0x040fe001, 0x038600de, + 0x04600201, 0x050f80ff, 0x032fa00a, 0x07c00000, + 0x050fe02e, 0x008680e3, 0x0102e000, 0x0302f000, + 0x038000e7, 0x0760002e, 0x050f80ff, 0x032fa00a, + 0x0102e000, 0x07c00000, 0x022c0004, 0x056c041d, + 0x078100fc, 0x056c021d, 0x04810113, 0x056c081d, + 0x04810125, 0x076c061d, 0x0581013f, 0x0521d000, + 0x0202c013, 0x0202a013, 0x02020013, 0x0460021a, + 0x050f80ff, 0x053fa80a, 0x07000009, 0x03b600ac, + 0x0484801f, 0x0280003d, 0x040fe02a, 0x028600f2, + 0x06000013, 0x04001013, 0x0560102b, 0x050f80ff, + 0x032fa012, 0x06420029, 0x0660002a, 0x050f80ff, + 0x053fa809, 0x06000001, 0x050fe003, 0x00860110, + 0x01028003, 0x0660002a, 0x050f80ff, 0x053fa80a, + 0x07000009, 0x00800140, 0x00028013, 0x00027013, + 0x00800140, 0x040fe02a, 0x028600f1, 0x06420029, + 0x0660002a, 0x050f80ff, 0x053fa809, 0x06000001, + 0x050fe003, 0x01860122, 0x03026003, 0x0660002a, + 0x050f80ff, 0x053fa80a, 0x07000009, 0x00800140, + 0x02026013, 0x02025013, 0x00800140, 0x040fe02a, + 0x028600f1, 0x06420029, 0x0660002a, 0x050f80ff, + 0x053fa809, 0x06000001, 0x050fe003, 0x00860134, + 0x01022003, 0x0660002a, 0x050f80ff, 0x053fa80a, + 0x07000009, 0x01800136, 0x00022013, 0x00021013, + 0x0647f020, 0x007a0120, 0x04000101, 0x04a00285, + 0x0400802a, 0x05a004f5, 0x009480f1, 0x0521d005, + 0x028000f2, 0x038000fa, 0x0647f020, 0x06486020, + 0x06818145, 0x04a00285, 0x028000f1, 0x007a0120, + 0x04000101, 0x04a00285, 0x0400802a, 0x05a004f5, + 0x028000f1, 0x040fd02a, 0x052e4003, 0x00208010, + 0x05a004f5, 0x038000fa, 0x00018098, 0x07480018, + 0x06818161, 0x05481018, 0x0781815f, 0x05482018, + 0x0681815d, 0x07483018, 0x0681815b, 0x002fb004, + 0x00800162, 0x012fb003, 0x00800162, 0x002fb002, + 0x00800162, 0x002fb001, 0x00800162, 0x012fb000, + 0x0179fe78, 0x070000ff, 0x030190ff, 0x00017086, + 0x058b0166, 0x03385000, 0x03020000, 0x07780017, + 0x00430407, 0x078181ee, 0x046c0419, 0x048101a2, + 0x046c0219, 0x05810172, 0x07219000, 0x00800186, + 0x07219000, 0x07483017, 0x0481018c, 0x05482017, + 0x05810193, 0x0448b075, 0x06818186, 0x06601476, + 0x050f80ff, 0x073fa022, 0x0600003e, 0x06000080, + 0x05001081, 0x05002082, 0x06003083, 0x05004084, + 0x04601c76, 0x050f80ff, 0x022fa02a, 0x07219000, + 0x07780078, 0x07ffff00, 0x045a0419, 0x010780ff, + 0x0484801f, 0x0280003d, 0x040fe07f, 0x0086019b, + 0x05a001bb, 0x00920186, 0x040fe07f, 0x07a681bb, + 0x00800186, 0x0560107b, 0x050f80ff, 0x032fa009, + 0x0744f000, 0x0560107b, 0x050f80ff, 0x032fa00a, + 0x00800179, 0x052e400c, 0x040080fb, 0x046aa108, + 0x06009076, 0x04002075, 0x05a004fc, 0x00800186, + 0x06219001, 0x05482017, 0x058101af, 0x058b01a5, + 0x060ff086, 0x0349f0ff, 0x07818165, 0x07483017, + 0x058101ac, 0x050fd0ff, 0x040fe07f, 0x07a681bb, + 0x00800186, 0x05004084, 0x05a00205, 0x00920186, + 0x070ff07d, 0x0450047c, 0x056004ff, 0x050f80ff, + 0x032fa009, 0x070ff000, 0x00540479, 0x030790ff, + 0x01800193, 0x060ff079, 0x0054047a, 0x058201e7, + 0x058101e7, 0x070ff07d, 0x0450047c, 0x050f80ff, + 0x002fa819, 0x058b01c3, 0x02080001, 0x00081002, + 0x01082003, 0x048b01c7, 0x03385000, 0x03010000, + 0x02400019, 0x070ff003, 0x04500479, 0x030790ff, + 0x0340007e, 0x0642007f, 0x058101e7, 0x070ff07e, + 0x050f80ff, 0x032fa009, 0x050fe000, 0x028681e6, + 0x070ff07d, 0x056002ff, 0x050f80ff, 0x032fa009, + 0x0107d000, 0x018601e8, 0x0560087d, 0x050f80ff, + 0x032fa009, 0x0569fe00, 0x0550041b, 0x050f80ff, + 0x032fa009, 0x0107e000, 0x070ff07e, 0x018001d2, + 0x0307c000, 0x07c00000, 0x052e400c, 0x040080fb, + 0x046aa108, 0x06009076, 0x04002075, 0x018004fc, + 0x040fd076, 0x050fd017, 0x060ff086, 0x077800ff, + 0x07000060, 0x037c00ff, 0x07000060, 0x078181f0, + 0x07780078, 0x07ffff00, 0x045a0419, 0x010780ff, + 0x06601476, 0x050f80ff, 0x073fa022, 0x0600003e, + 0x052e400c, 0x040080fb, 0x066a8108, 0x06009076, + 0x04002075, 0x05a004fc, 0x02800029, 0x0240007f, + 0x0742007e, 0x050f807e, 0x032fa009, 0x050fe000, + 0x0286821f, 0x070ff07d, 0x055c047b, 0x05810214, + 0x0760007d, 0x050f80ff, 0x032fa009, 0x050fe000, + 0x03868214, 0x070ff07b, 0x0107d0ff, 0x0560087d, + 0x050f80ff, 0x032fa009, 0x03681e00, 0x0450041c, + 0x0107e0ff, 0x050f80ff, 0x032fa009, 0x050fe000, + 0x01860221, 0x0307c000, 0x07c00000, 0x040fd076, + 0x02800510, 0x010180c0, 0x0548e018, 0x0781823c, + 0x0748f018, 0x06818238, 0x03490018, 0x06818234, + 0x01491018, 0x07818230, 0x073c0000, 0x06000040, + 0x02200004, 0x0180023f, 0x073c0000, 0x06000020, + 0x03200003, 0x0180023f, 0x073c0000, 0x06000010, + 0x02200002, 0x0180023f, 0x073c0000, 0x06000008, + 0x02200001, 0x0180023f, 0x073c0000, 0x06000004, + 0x06000013, 0x050fb000, 0x040fe076, 0x00860258, + 0x046c0273, 0x04810268, 0x066c0073, 0x04810249, + 0x040fd076, 0x06a00510, 0x03800014, 0x040fd076, + 0x0080024c, 0x00452075, 0x00077013, 0x0647f075, + 0x06486075, 0x06818252, 0x05a0028b, 0x00800258, + 0x007a0175, 0x04000101, 0x05a0028b, 0x04008076, + 0x0245f008, 0x05a004f5, 0x07273000, 0x05600272, + 0x050f80ff, 0x053fa80a, 0x07000009, 0x0379ff78, + 0x070000ff, 0x02076013, 0x02075013, 0x0484801f, + 0x0280003d, 0x070fc0ff, 0x052e400c, 0x00208020, + 0x05a004f5, 0x00800261, 0x04600276, 0x050010ff, + 0x040f8001, 0x032fa009, 0x040f8001, 0x053fa80a, + 0x07000009, 0x070ff000, 0x0286827a, 0x06601276, + 0x050f80ff, 0x073fa009, 0x0700000c, 0x07601818, + 0x050f80ff, 0x053fa80a, 0x07000009, 0x0180027b, + 0x07a000de, 0x0448b075, 0x0581024b, 0x06000013, + 0x04001013, 0x0560107b, 0x050f80ff, 0x032fa012, + 0x0046b075, 0x03b600ac, 0x0080024c, 0x06000020, + 0x04001016, 0x0460082a, 0x050f80ff, 0x032fa012, + 0x07c00000, 0x06000075, 0x040010a2, 0x044b0801, + 0x060ff016, 0x065a0001, 0x04600876, 0x050f80ff, + 0x032fa012, 0x07c00000, 0x050fe022, 0x0186029a, + 0x0421d004, 0x0302a022, 0x04a002c1, 0x018002b1, + 0x040fe026, 0x008602b3, 0x0421d001, 0x0202a026, + 0x04a002c1, 0x0202c013, 0x00683e20, 0x070060ff, + 0x056c0206, 0x048102f4, 0x056c0406, 0x0781030a, + 0x076c0606, 0x06810379, 0x056c1606, 0x078182b1, + 0x04488020, 0x07810387, 0x040fd02a, 0x0521d000, + 0x0202a013, 0x02020013, 0x008002b3, 0x04a004ec, + 0x008002bf, 0x050fe028, 0x008602bf, 0x0302a028, + 0x0421d002, 0x04a002c1, 0x008002c8, 0x050fe022, + 0x008602bf, 0x0421d004, 0x0302a022, 0x04a002c1, + 0x04a004ec, 0x05848030, 0x0280003d, 0x0460082a, + 0x050f80ff, 0x022fa031, 0x03020000, 0x0002b004, + 0x01018005, 0x07c00000, 0x0400702a, 0x06a003ba, 0x007a0101, 0x07060000, 0x07303000, 0x07008290, 0x07600018, 0x050f80ff, 0x053fa809, 0x07000003, - 0x0448e007, 0x068184a1, 0x06006013, 0x018004b8, - 0x02400010, 0x048104a1, 0x06006010, 0x04603276, - 0x050f80ff, 0x073fa00a, 0x07000003, 0x018004b8, + 0x0448e007, 0x068182d6, 0x06006013, 0x018002dd, + 0x02400010, 0x048102d6, 0x06006010, 0x0460322a, + 0x050f80ff, 0x073fa00a, 0x07000003, 0x050f801e, + 0x032fa03a, 0x063aa020, 0x06000002, 0x013e4000, + 0x07000030, 0x009802e3, 0x070ff0f6, 0x036830ff, + 0x078182e4, 0x070f001e, 0x0560102b, 0x050f10ff, + 0x063f3c08, 0x0600000d, 0x013e4000, 0x06000020, + 0x040f801a, 0x0320000a, 0x022017d0, 0x032fa012, + 0x0202c013, 0x008002bf, 0x04007013, 0x06a003ba, + 0x007a0101, 0x07050000, 0x07303000, 0x07008890, + 0x074d0005, 0x06006013, 0x050f801e, 0x032fa03a, + 0x05601a2b, 0x050f80ff, 0x022fa019, 0x04001002, + 0x04002013, 0x040f801f, 0x022fa01a, 0x073aa00c, + 0x06000002, 0x07300c03, 0x0600000d, 0x028003a7, + 0x04007013, 0x06a003ba, 0x007a0101, 0x03070000, + 0x0660282a, 0x050f80ff, 0x073fa009, 0x06000004, + 0x02499008, 0x07810317, 0x07303000, 0x07008890, + 0x02800319, 0x07303000, 0x04008980, 0x05007003, + 0x074d0005, 0x06006013, 0x050f801e, 0x032fa03a, + 0x0760142b, 0x050f80ff, 0x032fa021, 0x064b0002, + 0x02499008, 0x06810325, 0x0644c002, 0x054b0400, + 0x050040ff, 0x06698104, 0x0581833a, 0x06000013, + 0x04001013, 0x04780102, 0x06000010, 0x06003013, + 0x04004013, 0x06005013, 0x06006013, 0x04007013, + 0x00644015, 0x07820336, 0x04448002, 0x02205008, + 0x040f801f, 0x032fa042, 0x04008015, 0x03800371, + 0x046c8004, 0x05818348, 0x01208018, 0x06780002, + 0x07000003, 0x0581834b, 0x06003001, 0x06000013, + 0x04001013, 0x04004013, 0x06005013, 0x040f801f, + 0x022fa032, 0x03800371, 0x040fd02a, 0x06a00510, + 0x03800014, 0x04488002, 0x07810350, 0x070ff003, + 0x04500408, 0x050080ff, 0x06489002, 0x06810357, + 0x0379ff00, 0x070000ff, 0x070ff000, 0x04500408, + 0x050080ff, 0x07005003, 0x05004000, 0x06003001, + 0x06000013, 0x04001013, 0x040f801f, 0x022fa032, + 0x05601c2b, 0x050f80ff, 0x022fa031, 0x06600c1f, + 0x050f80ff, 0x022fa032, 0x02680608, 0x07810371, + 0x016408ff, 0x057dfeff, 0x07ffffff, 0x034000ff, + 0x045a0407, 0x070000ff, 0x0760061e, 0x050f80ff, + 0x032fa00a, 0x06600908, 0x0669f908, 0x027a0008, + 0x06000020, 0x070aa0ff, 0x014a20ff, 0x037a00ff, + 0x060000dc, 0x070000ff, 0x028003a7, 0x04007013, + 0x06a003ba, 0x007a0101, 0x07030000, 0x07303000, + 0x07008190, 0x06006013, 0x050f801e, 0x032fa03a, + 0x073aa000, 0x06000002, 0x07300c00, 0x07000005, + 0x028003a7, 0x04007013, 0x06a003ba, 0x007a0101, + 0x07810000, 0x07303000, 0x07000090, 0x06006013, + 0x06600c2a, 0x050f80ff, 0x053fa809, 0x07000003, + 0x04780107, 0x07ffff00, 0x007c0107, 0x07000500, + 0x0581839a, 0x07303000, 0x05000890, 0x074d0005, + 0x0660282a, 0x050f80ff, 0x053fa809, 0x07000003, + 0x0049d007, 0x068103a1, 0x02206001, 0x050f801e, + 0x032fa03a, 0x073aa000, 0x06000002, 0x07300c00, + 0x07000005, 0x013e4000, 0x07000030, 0x039803a9, + 0x070ff0f6, 0x036830ff, 0x058183aa, 0x070f001e, + 0x040f101f, 0x070f3000, 0x013e4000, 0x06000020, + 0x040f801a, 0x0320000a, 0x022017d0, 0x032fa012, + 0x008002bf, 0x03200000, 0x06006076, 0x028003bc, + 0x03200011, 0x0600602a, 0x05a00441, 0x05600406, + 0x050f80ff, 0x053fa809, 0x06000002, 0x07c00000, + 0x0207602f, 0x04600876, 0x050f80ff, 0x022fa031, + 0x03075000, 0x0007b004, 0x01018005, 0x06600076, + 0x050020ff, 0x050f80ff, 0x012fa809, 0x0202f001, + 0x008683d0, 0x0002e013, 0x040f8002, 0x053fa80a, + 0x07000009, 0x06273001, 0x0448b075, 0x048183da, + 0x04602076, 0x050f80ff, 0x053fa811, 0x0700003c, + 0x0179fe78, 0x070000ff, 0x030190ff, 0x018683e2, + 0x07a003f6, 0x00078019, 0x039203f5, 0x0180043a, + 0x040fd076, 0x040fd019, 0x04600276, 0x050020ff, + 0x050f80ff, 0x032fa009, 0x040f8002, 0x053fa80a, + 0x07000009, 0x050fe000, 0x008683f2, 0x07601818, + 0x050f80ff, 0x053fa80a, 0x07000009, 0x038003f3, + 0x07a000de, 0x07273000, 0x02076013, 0x0280003d, + 0x078b03f6, 0x03385000, 0x07030000, 0x05600818, + 0x050f80ff, 0x032fa009, 0x054b0400, 0x0308a0ff, + 0x0179fe00, 0x070000ff, 0x010880ff, 0x0448b075, + 0x04810410, 0x0760147b, 0x050f80ff, 0x002fa819, + 0x064b0001, 0x02080002, 0x01081003, 0x00082001, + 0x02083001, 0x02079001, 0x0207a001, 0x00084013, + 0x0207f013, 0x00800432, 0x06485075, 0x05810428, + 0x02465075, 0x06601476, 0x050f80ff, 0x073fa021, + 0x0600003e, 0x070ff07d, 0x0450047c, 0x050f80ff, + 0x002fa819, 0x058b041b, 0x02080001, 0x00081002, + 0x01082003, 0x03079003, 0x0208307a, 0x0340007e, + 0x0642007f, 0x0581042d, 0x070ff07e, 0x05a001d2, + 0x0392842d, 0x01800439, 0x058b0428, 0x06601476, + 0x050f80ff, 0x073fa041, 0x0600003e, 0x06602476, + 0x050f80ff, 0x073fa009, 0x06000007, 0x0008400e, + 0x048b0432, 0x03385000, 0x03010000, 0x06219001, + 0x040fe07f, 0x01860439, 0x018001bb, 0x07c00000, + 0x00683e75, 0x0581043f, 0x0448d075, 0x05810465, + 0x01800493, 0x05a004f0, 0x038003f5, 0x0297844c, + 0x07602418, 0x050f80ff, 0x012fa809, 0x06780001, + 0x070000ff, 0x075a0000, 0x070ff014, 0x0569feff, + 0x054b08ff, 0x075a0000, 0x05600418, 0x050f80ff, + 0x012fa809, 0x040fe007, 0x03868453, 0x01204000, + 0x00800461, 0x00700101, 0x03010000, 0x06780001, + 0x07ff0000, 0x076c00ff, 0x0681845b, 0x00700101, + 0x03010000, 0x05600418, 0x050f80ff, 0x012fa80a, + 0x06780001, 0x07ff0000, 0x050040ff, 0x0279ff01, + 0x0700ffff, 0x05002014, 0x07c00000, 0x04007076, + 0x0448b075, 0x0481047f, 0x03200011, 0x06006076, + 0x06a003bc, 0x007a0101, 0x07060000, 0x07303000, + 0x07008290, 0x07600018, 0x050f80ff, 0x053fa809, + 0x07000003, 0x0448e007, 0x07818477, 0x06006013, + 0x0180048e, 0x02400010, 0x05810477, 0x06006010, + 0x04603276, 0x050f80ff, 0x073fa00a, 0x07000003, + 0x0180048e, 0x04602a76, 0x050f80ff, 0x032fa009, + 0x060ff07a, 0x05500400, 0x070000ff, 0x04602a76, + 0x050f80ff, 0x032fa00a, 0x07a003b7, 0x007a0101, + 0x03010000, 0x06303008, 0x05008000, 0x0600600e, + 0x050f8074, 0x032fa03a, 0x053079a0, 0x0700000c, + 0x008004d3, 0x00683e75, 0x076c0aff, 0x058104b2, + 0x04007013, 0x03200011, 0x06006076, 0x06a003bc, + 0x007a0101, 0x03070000, 0x06602876, 0x050f80ff, + 0x053fa809, 0x06000001, 0x03499003, 0x048104a7, + 0x07303000, 0x07008890, 0x053079a0, 0x0700000c, + 0x008004ab, 0x07303000, 0x04008980, 0x04307920, + 0x0700000c, 0x074d0005, 0x06006013, 0x050f8074, + 0x032fa03a, 0x04307920, 0x0700000c, 0x008004d3, 0x04602a76, 0x050f80ff, 0x032fa009, 0x060ff07a, 0x05500400, 0x070000ff, 0x04602a76, 0x050f80ff, - 0x032fa00a, 0x07a003e1, 0x007a0101, 0x03010000, - 0x06303008, 0x05008000, 0x0600600e, 0x050f8074, - 0x032fa03a, 0x053079a0, 0x0700000c, 0x008004fd, - 0x00683e75, 0x076c0aff, 0x048104dc, 0x04007013, - 0x03200011, 0x06006076, 0x06a003e6, 0x007a0101, - 0x03070000, 0x06602876, 0x050f80ff, 0x053fa809, - 0x06000001, 0x03499003, 0x058104d1, 0x07303000, - 0x07008890, 0x053079a0, 0x0700000c, 0x008004d5, - 0x07303000, 0x04008980, 0x04307920, 0x0700000c, - 0x074d0005, 0x06006013, 0x050f8074, 0x032fa03a, - 0x04307920, 0x0700000c, 0x008004fd, 0x04602a76, - 0x050f80ff, 0x032fa009, 0x060ff07a, 0x05500400, - 0x070000ff, 0x04602a76, 0x050f80ff, 0x032fa00a, - 0x04007076, 0x07a003e1, 0x007a0101, 0x03010000, - 0x06303008, 0x07008800, 0x074d0005, 0x06600a76, - 0x050f80ff, 0x073fa009, 0x07000003, 0x054b0406, - 0x045a0404, 0x050040ff, 0x0600600e, 0x050f8074, - 0x032fa03a, 0x0648c075, 0x048104fb, 0x06307d20, - 0x0700000c, 0x008004fd, 0x04307920, 0x0700000c, - 0x013e4000, 0x07000030, 0x019804ff, 0x070ff0f6, - 0x074850ff, 0x05818500, 0x050f2074, 0x060a0007, - 0x040070fb, 0x046a7007, 0x050f40ff, 0x013e4000, - 0x06000020, 0x0678007a, 0x07fff000, 0x04818510, - 0x0320000a, 0x022017d0, 0x02800513, 0x0320000a, - 0x06301b58, 0x06000001, 0x050f8072, 0x032fa012, - 0x0080041f, 0x01208060, 0x0600902a, 0x04002020, - 0x02800526, 0x040080fb, 0x066ae108, 0x06009076, - 0x04002075, 0x02800526, 0x03201100, 0x05848524, - 0x06420001, 0x04818520, 0x0280053d, 0x020e0008, - 0x07c00000, 0x050fd009, 0x040fd008, 0x03201100, - 0x0584852d, 0x06420001, 0x04818529, 0x0280053d, - 0x007a0102, 0x04000101, 0x05600809, 0x050f80ff, - 0x073fa00a, 0x06000001, 0x020e0008, 0x06840537, - 0x030e0009, 0x07c00000, 0x01011009, 0x052e4300, - 0x07c00000, 0x052e400f, 0x01208090, 0x0280051f, - 0x070fc0ff, 0x040f8013, 0x032fa009, 0x02800540, - 0x6321d92e, 0xffef19a2 + 0x032fa00a, 0x04007076, 0x07a003b7, 0x007a0101, + 0x03010000, 0x06303008, 0x07008800, 0x074d0005, + 0x06600a76, 0x050f80ff, 0x073fa009, 0x07000003, + 0x054b0406, 0x045a0404, 0x050040ff, 0x0600600e, + 0x050f8074, 0x032fa03a, 0x0648c075, 0x058104d1, + 0x06307d20, 0x0700000c, 0x008004d3, 0x04307920, + 0x0700000c, 0x013e4000, 0x07000030, 0x009804d5, + 0x070ff0f6, 0x074850ff, 0x068184d6, 0x050f2074, + 0x060a0007, 0x040070fb, 0x046a7007, 0x050f40ff, + 0x013e4000, 0x06000020, 0x0678007a, 0x07fff000, + 0x068184e6, 0x0320000a, 0x022017d0, 0x008004e9, + 0x0320000a, 0x06301b58, 0x06000001, 0x050f8072, + 0x032fa012, 0x038003f5, 0x01208060, 0x0600902a, + 0x04002020, 0x018004fc, 0x040080fb, 0x066ae108, + 0x06009076, 0x04002075, 0x018004fc, 0x03201100, + 0x078484fa, 0x06420001, 0x078184f6, 0x02800513, + 0x020e0008, 0x07c00000, 0x050fd009, 0x040fd008, + 0x03201100, 0x05848503, 0x06420001, 0x078184ff, + 0x02800513, 0x007a0102, 0x04000101, 0x05600809, + 0x050f80ff, 0x073fa00a, 0x06000001, 0x020e0008, + 0x0684050d, 0x030e0009, 0x07c00000, 0x01011009, + 0x052e4300, 0x07c00000, 0x052e400f, 0x01208090, + 0x018004f5, 0x070fc0ff, 0x040f8013, 0x032fa009, + 0x02800516, 0x15416ea9, 0xffef0b01 }; #ifdef UNIQUE_FW_NAME -uint32_t fw2400_length02 = 0x0000165e ; +uint32_t fw2400_length02 = 0x000014ff ; #else -uint32_t risc_code_length02 = 0x0000165e ; +uint32_t risc_code_length02 = 0x000014ff ; #endif diff --git a/drivers/scsi/qla2xxx/ql6312.c b/drivers/scsi/qla2xxx/ql6312.c new file mode 100644 index 000000000..de55397f6 --- /dev/null +++ b/drivers/scsi/qla2xxx/ql6312.c @@ -0,0 +1,101 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include +#include +#include + +#include "qla_def.h" + +static char qla_driver_name[] = "qla6312"; + +extern unsigned char fw2300flx_version[]; +extern unsigned char fw2300flx_version_str[]; +extern unsigned short fw2300flx_addr01; +extern unsigned short fw2300flx_code01[]; +extern unsigned short fw2300flx_length01; + +static struct qla_fw_info qla_fw_tbl[] = { + { + .addressing = FW_INFO_ADDR_NORMAL, + .fwcode = &fw2300flx_code01[0], + .fwlen = &fw2300flx_length01, + .fwstart = &fw2300flx_addr01, + }, + { FW_INFO_ADDR_NOMORE, }, +}; + +static struct qla_board_info qla_board_tbl[] = { + { + .drv_name = qla_driver_name, + .isp_name = "ISP6312", + .fw_info = qla_fw_tbl, + }, + { + .drv_name = qla_driver_name, + .isp_name = "ISP6322", + .fw_info = qla_fw_tbl, + }, +}; + +static struct pci_device_id qla6312_pci_tbl[] = { + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP6312, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[0], + }, + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP6322, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[1], + }, + {0, 0}, +}; +MODULE_DEVICE_TABLE(pci, qla6312_pci_tbl); + +static int __devinit +qla6312_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return qla2x00_probe_one(pdev, + (struct qla_board_info *)id->driver_data); +} + +static void __devexit +qla6312_remove_one(struct pci_dev *pdev) +{ + qla2x00_remove_one(pdev); +} + +static struct pci_driver qla6312_pci_driver = { + .name = "qla6312", + .id_table = qla6312_pci_tbl, + .probe = qla6312_probe_one, + .remove = __devexit_p(qla6312_remove_one), +}; + +static int __init +qla6312_init(void) +{ + return pci_module_init(&qla6312_pci_driver); +} + +static void __exit +qla6312_exit(void) +{ + pci_unregister_driver(&qla6312_pci_driver); +} + +module_init(qla6312_init); +module_exit(qla6312_exit); + +MODULE_AUTHOR("QLogic Corporation"); +MODULE_DESCRIPTION("QLogic ISP63xx FC-SCSI Host Bus Adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(QLA2XXX_VERSION); diff --git a/drivers/scsi/qla2xxx/ql6312_fw.c b/drivers/scsi/qla2xxx/ql6312_fw.c new file mode 100644 index 000000000..5bb837052 --- /dev/null +++ b/drivers/scsi/qla2xxx/ql6312_fw.c @@ -0,0 +1,7078 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ + +/* + * Firmware Version 3.03.18 (12:07 Sep 20, 2005) + */ + +#ifdef UNIQUE_FW_NAME +unsigned short fw2300flx_version = 3*1024+3; +#else +unsigned short risc_code_version = 3*1024+3; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned char fw2300flx_version_str[] = {3, 3,18}; +#else +unsigned char firmware_version[] = {3, 3,18}; +#endif + +#ifdef UNIQUE_FW_NAME +#define fw2300flx_VERSION_STRING "3.03.18" +#else +#define FW_VERSION_STRING "3.03.18" +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2300flx_addr01 = 0x0800 ; +#else +unsigned short risc_code_addr01 = 0x0800 ; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2300flx_code01[] = { +#else +unsigned short risc_code01[] = { +#endif + 0x0470, 0x0000, 0x0000, 0xdbb7, 0x0000, 0x0003, 0x0003, 0x0012, + 0x0317, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, + 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, + 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972, + 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, + 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9, + 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f, + 0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001, + 0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000, + 0x400f, 0x2091, 0x2800, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, + 0x2091, 0x2a00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, + 0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00, + 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001, + 0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78, + 0x7883, 0x0004, 0x2089, 0x2c06, 0x2051, 0x1800, 0x2a70, 0x20e1, + 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e7b, 0x2029, + 0x2480, 0x2031, 0xffff, 0x2039, 0x2450, 0x2021, 0x0050, 0x20e9, + 0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9, + 0x0001, 0x20a1, 0x1000, 0x900e, 0x2001, 0x0cc0, 0x9084, 0x0fff, + 0x20a8, 0x4104, 0x2001, 0x0000, 0x9086, 0x0000, 0x0120, 0x21a8, + 0x4104, 0x8001, 0x1de0, 0x756a, 0x766e, 0x7766, 0x7472, 0x7476, + 0x00e6, 0x2071, 0x1aa2, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x716c, + 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x000f, 0x2001, 0x0001, + 0x9112, 0x900e, 0x21a8, 0x4104, 0x8211, 0x1de0, 0x716c, 0x3400, + 0x8001, 0x9102, 0x0120, 0x0218, 0x20a8, 0x900e, 0x4104, 0x2009, + 0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f, + 0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e, + 0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f4f, 0x080c, + 0x5e3d, 0x080c, 0x9f80, 0x080c, 0x1106, 0x080c, 0x12fe, 0x080c, + 0x1a75, 0x080c, 0x0d88, 0x080c, 0x108b, 0x080c, 0x32f3, 0x080c, + 0x748e, 0x080c, 0x6784, 0x080c, 0x8194, 0x080c, 0x22b3, 0x080c, + 0x84a5, 0x080c, 0x7b18, 0x080c, 0x20df, 0x080c, 0x2213, 0x080c, + 0x22a8, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091d, 0x7880, + 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, + 0x0010, 0x0e04, 0x0911, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11e6, 0x2071, 0x1800, 0x7003, + 0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, 0x1168, 0x080c, + 0x4adc, 0x080c, 0x331a, 0x080c, 0x74f6, 0x080c, 0x6c82, 0x080c, + 0x81bd, 0x080c, 0x2b13, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941, + 0x0ad8, 0x093e, 0x0b8f, 0x0d87, 0x0d87, 0x0d87, 0x080c, 0x0df6, + 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, 0x0001, + 0x1904, 0x0aab, 0x080c, 0x0ebd, 0x080c, 0x717e, 0x0150, 0x080c, + 0x71a1, 0x15a0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a, + 0x0468, 0x080c, 0x709e, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aab, + 0x7094, 0x9086, 0x0029, 0x1904, 0x0aab, 0x080c, 0x817d, 0x080c, + 0x816f, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827, + 0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a, 0x2011, 0x6fed, 0x080c, + 0x8259, 0x2011, 0x6fe0, 0x080c, 0x832d, 0x2011, 0x5c98, 0x080c, + 0x8259, 0x2011, 0x8030, 0x901e, 0x7392, 0x04d0, 0x080c, 0x5545, + 0x2079, 0x0100, 0x7844, 0x9005, 0x1904, 0x0aab, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x2011, 0x6fed, 0x080c, 0x8259, 0x2011, 0x6fe0, + 0x080c, 0x832d, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, + 0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, 0x1981, 0x2004, 0x9005, + 0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, 0x5de5, 0x00ce, 0x0804, + 0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x7186, 0x0118, 0x9295, + 0x5e2f, 0x0010, 0x9295, 0x402f, 0x7a2a, 0x2011, 0x8010, 0x73d4, + 0x2001, 0x1982, 0x2003, 0x0001, 0x080c, 0x2974, 0x080c, 0x4a17, + 0x7244, 0xc284, 0x7246, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc, + 0x2102, 0x080c, 0x9818, 0x2011, 0x0004, 0x080c, 0xbd5e, 0x080c, + 0x65c6, 0x080c, 0x717e, 0x1120, 0x080c, 0x29e1, 0x02e0, 0x0400, + 0x080c, 0x5dec, 0x0140, 0x7093, 0x0001, 0x70cf, 0x0000, 0x080c, + 0x5712, 0x0804, 0x0aab, 0x080c, 0x54db, 0xd094, 0x0188, 0x2011, + 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x54df, 0xd0d4, 0x1118, + 0x080c, 0x29e1, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088, + 0x080c, 0x54df, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd, + 0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x66c1, + 0x0008, 0x2012, 0x080c, 0x6687, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, + 0x00a8, 0x707b, 0x0000, 0x080c, 0x717e, 0x1130, 0x70ac, 0x9005, + 0x1168, 0x080c, 0xc1a1, 0x0050, 0x080c, 0xc1a1, 0x70d8, 0xd09c, + 0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5dc2, 0x70e3, 0x0000, + 0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x29e9, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x717e, 0x1178, + 0x9016, 0x0016, 0x2009, 0x0002, 0x2019, 0x1947, 0x211a, 0x001e, + 0x705b, 0xffff, 0x705f, 0x00ef, 0x707f, 0x0000, 0x0020, 0x2019, + 0x1947, 0x201b, 0x0000, 0x2079, 0x185b, 0x7804, 0xd0ac, 0x0108, + 0xc295, 0x72da, 0x080c, 0x717e, 0x0118, 0x9296, 0x0004, 0x0548, + 0x2011, 0x0001, 0x080c, 0xbd5e, 0x70a7, 0x0000, 0x70ab, 0xffff, + 0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, + 0x0003, 0x782a, 0x00fe, 0x080c, 0x2e73, 0x2011, 0x0005, 0x080c, + 0x9923, 0x080c, 0x8b8f, 0x080c, 0x717e, 0x0148, 0x00c6, 0x2061, + 0x0100, 0x0016, 0x2009, 0x0002, 0x61e2, 0x001e, 0x00ce, 0x012e, + 0x0420, 0x70a7, 0x0000, 0x70ab, 0xffff, 0x7003, 0x0002, 0x00f6, + 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a, + 0x00fe, 0x2011, 0x0005, 0x080c, 0x9923, 0x080c, 0x8b8f, 0x080c, + 0x717e, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002, + 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, + 0x080c, 0x717e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, + 0x080c, 0x717e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, + 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, + 0x090c, 0x3190, 0x8108, 0x1f04, 0x0abf, 0x707b, 0x0000, 0x707c, + 0x9084, 0x00ff, 0x707e, 0x70af, 0x0000, 0x00be, 0x00ce, 0x0005, + 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, + 0x0b8c, 0x70a8, 0x9086, 0xffff, 0x0130, 0x080c, 0x2e73, 0x080c, + 0x8b8f, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540, + 0xd084, 0x0530, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, + 0xd08c, 0x01f0, 0x70dc, 0x9086, 0xffff, 0x01b0, 0x080c, 0x3001, + 0x080c, 0x8b8f, 0x70d8, 0xd094, 0x1904, 0x0b8c, 0x2011, 0x0001, + 0x080c, 0xc459, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x303b, + 0x080c, 0x8b8f, 0x0804, 0x0b8c, 0x70e0, 0x9005, 0x1904, 0x0b8c, + 0x70a4, 0x9005, 0x1904, 0x0b8c, 0x70d8, 0xd0a4, 0x0118, 0xd0b4, + 0x0904, 0x0b8c, 0x080c, 0x6687, 0x1904, 0x0b8c, 0x080c, 0x66da, + 0x1904, 0x0b8c, 0x080c, 0x66c1, 0x01c0, 0x0156, 0x00c6, 0x20a9, + 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1118, 0xb800, 0xd0ec, + 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b32, 0x00ce, 0x015e, 0x0028, + 0x001e, 0x00ce, 0x015e, 0x0804, 0x0b8c, 0x0006, 0x2001, 0x0103, + 0x2003, 0x006b, 0x000e, 0x2011, 0x198e, 0x080c, 0x0fbf, 0x2011, + 0x19a8, 0x080c, 0x0fbf, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, + 0x70ab, 0xffff, 0x080c, 0x0e9f, 0x9006, 0x080c, 0x2616, 0x0036, + 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4bb4, 0x004e, + 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x71a1, 0x0150, 0x080c, + 0x717e, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf, + 0x782a, 0x00fe, 0x2001, 0x19c3, 0x2004, 0x9086, 0x0005, 0x1120, + 0x2011, 0x0000, 0x080c, 0x9923, 0x2011, 0x0000, 0x080c, 0x992d, + 0x080c, 0x8b8f, 0x080c, 0x8c6c, 0x012e, 0x00be, 0x0005, 0x0016, + 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x7904, + 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x7940, + 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, + 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x1904, 0x0c23, 0x7954, 0xd1ac, + 0x1904, 0x0c23, 0x2001, 0x1982, 0x2004, 0x9005, 0x1518, 0x080c, + 0x2a7f, 0x1148, 0x2001, 0x0001, 0x080c, 0x29a3, 0x2001, 0x0001, + 0x080c, 0x2986, 0x00b8, 0x080c, 0x2a87, 0x1138, 0x9006, 0x080c, + 0x29a3, 0x9006, 0x080c, 0x2986, 0x0068, 0x080c, 0x2a8f, 0x1d50, + 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27b1, + 0x0804, 0x0d2f, 0x080c, 0x718f, 0x0148, 0x080c, 0x71a1, 0x1118, + 0x080c, 0x7489, 0x0050, 0x080c, 0x7186, 0x0dd0, 0x080c, 0x7484, + 0x080c, 0x747a, 0x080c, 0x709e, 0x0058, 0x080c, 0x717e, 0x0140, + 0x2009, 0x00f8, 0x080c, 0x5dab, 0x7843, 0x0090, 0x7843, 0x0010, + 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x717e, 0x0138, + 0x7824, 0xd0ac, 0x1904, 0x0d34, 0x1f04, 0x0c02, 0x0070, 0x7824, + 0x080c, 0x7198, 0x0118, 0xd0ac, 0x1904, 0x0d34, 0x9084, 0x1800, + 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d34, 0x2001, 0x0001, 0x080c, + 0x2616, 0x0804, 0x0d56, 0x2001, 0x1982, 0x2004, 0x9005, 0x1518, + 0x080c, 0x2a7f, 0x1148, 0x2001, 0x0001, 0x080c, 0x29a3, 0x2001, + 0x0001, 0x080c, 0x2986, 0x00b8, 0x080c, 0x2a87, 0x1138, 0x9006, + 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x0068, 0x080c, 0x2a8f, + 0x1d50, 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, + 0x27b1, 0x0804, 0x0d2f, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, + 0x01f8, 0x7850, 0x9085, 0x0040, 0x7852, 0x7938, 0x7850, 0x9084, + 0xfbcf, 0x7852, 0x080c, 0x2a97, 0x9085, 0x2000, 0x7852, 0x793a, + 0x20a9, 0x0046, 0x1d04, 0x0c62, 0x080c, 0x830d, 0x1f04, 0x0c62, + 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x793a, 0x0040, + 0x20a9, 0x003a, 0x1d04, 0x0c72, 0x080c, 0x830d, 0x1f04, 0x0c72, + 0x080c, 0x718f, 0x0148, 0x080c, 0x71a1, 0x1118, 0x080c, 0x7489, + 0x0050, 0x080c, 0x7186, 0x0dd0, 0x080c, 0x7484, 0x080c, 0x747a, + 0x080c, 0x709e, 0x0020, 0x2009, 0x00f8, 0x080c, 0x5dab, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x0168, 0x20a9, 0x0028, 0xa001, + 0x1f04, 0x0c97, 0x7850, 0x9085, 0x1400, 0x7852, 0x080c, 0x717e, + 0x0158, 0x0030, 0x7850, 0xc0e5, 0x7852, 0x080c, 0x717e, 0x0120, + 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, + 0x0d0c, 0x830d, 0x7820, 0xd09c, 0x1590, 0x080c, 0x717e, 0x0904, + 0x0d13, 0x7824, 0xd0ac, 0x1904, 0x0d34, 0x080c, 0x71a1, 0x1538, + 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, + 0x080c, 0x2a97, 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, + 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, + 0x0d64, 0x8421, 0x1160, 0x1d04, 0x0cdf, 0x080c, 0x830d, 0x080c, + 0x7484, 0x080c, 0x747a, 0x7003, 0x0001, 0x0804, 0x0d34, 0x8319, + 0x1938, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x1140, 0x2001, + 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d64, 0x1d04, + 0x0cfb, 0x080c, 0x830d, 0x2009, 0x1975, 0x2104, 0x9005, 0x0118, + 0x8001, 0x200a, 0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9, + 0x0002, 0x080c, 0x2a78, 0x7924, 0x080c, 0x2a97, 0xd19c, 0x0110, + 0x080c, 0x2974, 0x00e0, 0x080c, 0x718f, 0x1140, 0x94a2, 0x03e8, + 0x1128, 0x080c, 0x7156, 0x7003, 0x0001, 0x00b0, 0x7827, 0x1800, + 0x080c, 0x2a97, 0x7824, 0x080c, 0x7198, 0x0110, 0xd0ac, 0x1160, + 0x9084, 0x1800, 0x0904, 0x0ce7, 0x7003, 0x0001, 0x0028, 0x2001, + 0x0001, 0x080c, 0x2616, 0x00c0, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x1118, 0x7850, 0xc0e4, 0x7852, 0x2009, 0x180c, 0x210c, + 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906, 0x7827, 0x0048, + 0x7828, 0x9085, 0x0028, 0x782a, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x0120, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x1982, + 0x2003, 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, + 0x00fe, 0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, + 0x830d, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, + 0x003e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189c, 0x7004, + 0x9086, 0x0001, 0x1110, 0x080c, 0x331a, 0x00ee, 0x0005, 0x0005, + 0x2a70, 0x2061, 0x1986, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, + 0x0012, 0x600f, 0x0317, 0x2001, 0x1956, 0x900e, 0x2102, 0x7192, + 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705b, 0xffff, + 0x0008, 0x715a, 0x7063, 0xffff, 0x717a, 0x717e, 0x080c, 0xc1a1, + 0x70e7, 0x00c0, 0x2061, 0x1946, 0x6003, 0x0909, 0x6106, 0x600b, + 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x000f, 0x611a, + 0x601f, 0x07d0, 0x2061, 0x194e, 0x6003, 0x8000, 0x6106, 0x610a, + 0x600f, 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, + 0x2061, 0x1963, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, + 0x600f, 0x2020, 0x2001, 0x182b, 0x2102, 0x0005, 0x9016, 0x080c, + 0x63a3, 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, + 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, + 0x8210, 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, + 0x8000, 0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, + 0x0e04, 0x0df8, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, + 0x0000, 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, + 0x000e, 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, + 0x78ae, 0x681c, 0x78b2, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, + 0x2091, 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, + 0x2069, 0x1a7a, 0x7a08, 0x226a, 0x2069, 0x1a7b, 0x7a18, 0x226a, + 0x8d68, 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1a88, 0x201a, 0x2019, + 0x1a8b, 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, + 0x8318, 0x9386, 0x1aa0, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, + 0x2011, 0xdead, 0x2019, 0x1a89, 0x782c, 0x201a, 0x8318, 0x221a, + 0x7803, 0x0000, 0x2069, 0x1a5a, 0x901e, 0x20a9, 0x0020, 0x7b26, + 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0e4f, 0x002e, 0x003e, + 0x00de, 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x19f6, 0x2004, + 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, + 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x54ea, 0x1108, + 0x0099, 0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, + 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d, 0x6400, + 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, + 0x080c, 0x0f17, 0x20a9, 0x0900, 0x080c, 0x0f38, 0x2011, 0x0040, + 0x080c, 0x0f17, 0x20a9, 0x0900, 0x080c, 0x0f38, 0x0c78, 0x0026, + 0x080c, 0x0f24, 0x1118, 0x2011, 0x0040, 0x0098, 0x2011, 0x010e, + 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, + 0x0010, 0x2011, 0x6840, 0xd0e4, 0x70eb, 0x0000, 0x1120, 0x70eb, + 0x0fa0, 0x080c, 0x0f29, 0x002e, 0x0005, 0x0026, 0x080c, 0x0f24, + 0x0128, 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, + 0x080c, 0x0f29, 0x002e, 0x0005, 0x0026, 0x70eb, 0x0000, 0x080c, + 0x0f24, 0x1148, 0x080c, 0x2a8f, 0x1118, 0x2011, 0x8484, 0x0058, + 0x2011, 0x8282, 0x0040, 0x080c, 0x2a8f, 0x1118, 0x2011, 0xcdc5, + 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f29, 0x002e, 0x0005, 0x00e6, + 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70e4, 0x1110, 0xc0e4, 0x0048, + 0x0006, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x70eb, 0x0000, + 0xc0e5, 0x0079, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, + 0xd0e4, 0x70e4, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0011, 0x00ee, + 0x0005, 0x70e6, 0x7000, 0x9084, 0x0007, 0x000b, 0x0005, 0x0ee6, + 0x0ebd, 0x0ebd, 0x0e9f, 0x0ecc, 0x0ebd, 0x0ebd, 0x0ecc, 0x0016, + 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, + 0x9205, 0x20d0, 0x001e, 0x0005, 0x2001, 0x1839, 0x2004, 0xd0dc, + 0x0005, 0x9e86, 0x1800, 0x190c, 0x0df6, 0x70e4, 0xd0e4, 0x0108, + 0xc2e5, 0x72e6, 0xd0e4, 0x1118, 0x9294, 0x00c0, 0x0c01, 0x0005, + 0x1d04, 0x0f38, 0x2091, 0x6000, 0x1f04, 0x0f38, 0x0005, 0x890e, + 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006, + 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6, + 0x0146, 0x0036, 0x0096, 0x2061, 0x188b, 0x600b, 0x0000, 0x600f, + 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105, + 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049, + 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105, + 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f, + 0x2001, 0x189b, 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011, + 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff, + 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007, + 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0, + 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e, + 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016, + 0x0026, 0x0096, 0x3348, 0x080c, 0x0f3f, 0x2100, 0x9300, 0x2098, + 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001, + 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9, + 0x0001, 0x71b4, 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9, + 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9, + 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x7078, 0x8007, 0x717c, + 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e, + 0x080c, 0x0dd6, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001, + 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, + 0x1069, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x10e2, 0x090c, 0x0df6, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006, + 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800, + 0x73bc, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c, + 0x0df6, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0df6, 0xa000, 0x0c98, + 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086, + 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x190e, 0x7010, + 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0df6, + 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6, + 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70bc, 0x8001, 0x0270, + 0x70be, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803, + 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x70bc, 0x90ca, + 0x0040, 0x0268, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800, 0x702e, + 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, + 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, + 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, + 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, + 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, + 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, + 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, + 0x0040, 0x0c90, 0x2071, 0x188b, 0x7000, 0x9005, 0x11a0, 0x2001, + 0x0492, 0xa802, 0x2048, 0x2009, 0x2480, 0x8940, 0x2800, 0xa802, + 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848, + 0x9188, 0x0040, 0x0c90, 0x2071, 0x188b, 0x7104, 0x7200, 0x82ff, + 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319, + 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e, + 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040, + 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74ba, + 0x74be, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c, + 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278, + 0x9982, 0x0492, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982, + 0x0800, 0x0250, 0x2071, 0x188b, 0x7010, 0x9902, 0x1228, 0x9085, + 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, + 0x19f5, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071, + 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006, + 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x1158, + 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x1124, 0x702b, + 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x112d, + 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, + 0xa06f, 0x0000, 0x2071, 0x19f5, 0x701c, 0x9088, 0x19ff, 0x280a, + 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0df6, + 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe, + 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, + 0x19f5, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021, + 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110, + 0x7007, 0x0006, 0x7000, 0x0002, 0x1176, 0x1174, 0x1174, 0x1174, + 0x12ed, 0x12ed, 0x12ed, 0x12ed, 0x080c, 0x0df6, 0x701c, 0x7120, + 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110, + 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x19ff, 0x2004, 0x700a, + 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b, 0x0026, 0xa88c, + 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0xa878, + 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868, 0x009e, 0xd084, + 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, + 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, + 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203, 0x7812, 0x782b, + 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, + 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9, + 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c, 0x2011, 0x0040, + 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006, + 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001, + 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x2009, 0x19f5, + 0x2104, 0xc095, 0x200a, 0x080c, 0x1153, 0x0005, 0x0016, 0x00e6, + 0x2071, 0x19f5, 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c, + 0x0def, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004, + 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1164, 0x120c, 0x1240, + 0x0df6, 0x0df6, 0x12f9, 0x0df6, 0x918c, 0x0700, 0x1550, 0x0136, + 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000, + 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8, 0x4005, 0x3400, + 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005, 0x0578, 0x7800, + 0x7802, 0x7804, 0x7806, 0x080c, 0x11a9, 0x0005, 0x7008, 0x0096, + 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x080c, 0x1164, + 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0, + 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, 0x7800, 0x7802, + 0x7804, 0x7806, 0x080c, 0x11be, 0x0005, 0x7008, 0x0096, 0x2048, + 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080, 0x0096, 0x7008, + 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808, 0xa896, 0x780c, + 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x0096, 0x00d6, + 0x7008, 0x2048, 0x2001, 0x18b7, 0x2004, 0x9906, 0x1128, 0xa89c, + 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e, 0x0096, 0x00d6, + 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086, 0x2940, 0x080f, + 0x008e, 0x00de, 0x009e, 0x080c, 0x1153, 0x0005, 0x00de, 0x009e, + 0x080c, 0x1153, 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0, + 0x904d, 0x090c, 0x0df6, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b, + 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, 0x6a15, 0xa09f, + 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x1069, 0x009e, 0x0005, + 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0df6, 0xa06c, 0x908e, 0x0100, + 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050, + 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007, + 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172, + 0xb000, 0xa07a, 0x2810, 0x080c, 0x1134, 0x00e8, 0xa97c, 0xa894, + 0x0016, 0x0006, 0x080c, 0x6a15, 0x000e, 0x001e, 0xd1fc, 0x1138, + 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0x9fea, 0x00ce, 0x7008, + 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, 0x1069, 0x7007, + 0x0000, 0x080c, 0x1153, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000, + 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e, + 0x0005, 0x7007, 0x0000, 0x080c, 0x1164, 0x0005, 0x0126, 0x2091, + 0x2200, 0x2079, 0x0300, 0x2071, 0x1a3f, 0x7003, 0x0000, 0x78bf, + 0x00f6, 0x0419, 0x7803, 0x0003, 0x780f, 0x0000, 0x2001, 0x0100, + 0x2004, 0x9086, 0x000a, 0x0128, 0x20a9, 0x01e8, 0x2061, 0xdc0a, + 0x0020, 0x20a9, 0x01e8, 0x2061, 0xdfd8, 0x2c0d, 0x7912, 0xe104, + 0x9ce0, 0x0002, 0x7916, 0x1f04, 0x131d, 0x7807, 0x0007, 0x7803, + 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, + 0x7808, 0xd09c, 0x0110, 0x7820, 0x0cd8, 0x2001, 0x1a40, 0x2003, + 0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, + 0x7807, 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, + 0x782b, 0x1a5a, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001, 0x0200, + 0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a5a, 0x602f, + 0x1cd0, 0x2001, 0x1819, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, + 0x1ebe, 0x783f, 0x31f3, 0x00ce, 0x0005, 0x0126, 0x2091, 0x2200, + 0x7908, 0x9184, 0x0070, 0x190c, 0x0def, 0xd19c, 0x0158, 0x7820, + 0x908c, 0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0df6, 0x0023, + 0x012e, 0x0005, 0x012e, 0x0005, 0x13a0, 0x13a0, 0x13b7, 0x13bc, + 0x13c0, 0x13c5, 0x13ed, 0x13f1, 0x13ff, 0x1403, 0x13a0, 0x148f, + 0x1493, 0x1503, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, + 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13c7, + 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a4, 0x13a2, + 0x080c, 0x0df6, 0x080c, 0x0def, 0x080c, 0x150a, 0x2009, 0x1a56, + 0x2104, 0x8000, 0x200a, 0x080c, 0x7bec, 0x080c, 0x1977, 0x0005, + 0x2009, 0x0048, 0x2060, 0x080c, 0xa068, 0x012e, 0x0005, 0x7004, + 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, + 0x080c, 0x150a, 0x080c, 0x15e4, 0x0005, 0x080c, 0x0df6, 0x080c, + 0x150a, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, + 0x2009, 0x0048, 0x080c, 0xa068, 0x2001, 0x015d, 0x2003, 0x0000, + 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, + 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x150f, + 0x2001, 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, + 0x0005, 0x080c, 0x150a, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, + 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005, 0x080c, + 0x150a, 0x080c, 0x0df6, 0x080c, 0x150a, 0x080c, 0x147a, 0x7827, + 0x0018, 0x79ac, 0xd1dc, 0x0540, 0x7827, 0x0015, 0x7828, 0x782b, + 0x0000, 0x9065, 0x0138, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x0400, 0x7004, 0x9005, 0x1180, 0x78ab, 0x0004, 0x7827, + 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0df6, 0x2001, 0x020d, + 0x2003, 0x0050, 0x2003, 0x0020, 0x0490, 0x78ab, 0x0004, 0x7803, + 0x0001, 0x080c, 0x1493, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, + 0x090c, 0x0df6, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, + 0x01a8, 0x080c, 0x7bec, 0x080c, 0x1977, 0x080c, 0xbd4e, 0x0158, + 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, + 0xa880, 0xc0bd, 0xa882, 0x080c, 0xb983, 0x0005, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xc13a, 0x2029, + 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, + 0x7dbc, 0x080c, 0xdbb3, 0xd5a4, 0x1118, 0x080c, 0x150f, 0x0005, + 0x080c, 0x7bec, 0x080c, 0x1977, 0x0005, 0x781f, 0x0300, 0x7803, + 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, + 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, + 0x080c, 0x1580, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, + 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0df6, + 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c, + 0x15c7, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x080c, 0x150f, 0x0005, 0x81ff, 0x190c, 0x0df6, 0x0005, + 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904, + 0x14f8, 0x2071, 0x0200, 0x080c, 0x15bb, 0x080c, 0x15c7, 0x05a8, + 0x6014, 0x9005, 0x05a8, 0x0096, 0x2048, 0xa864, 0x009e, 0x9084, + 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1548, 0x601c, + 0xd084, 0x11d8, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x00a8, + 0x00f6, 0x2c78, 0x080c, 0x179b, 0x00fe, 0x2009, 0x01f4, 0x8109, + 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, + 0x2004, 0xd0ec, 0x1110, 0x0419, 0x0040, 0x2001, 0x020d, 0x2003, + 0x0020, 0x080c, 0x132d, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, + 0x080c, 0x15c7, 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x0069, 0x0c90, 0x0031, 0x2060, 0x2009, 0x0053, 0x080c, + 0xa068, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c, + 0x147a, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, 0x0510, + 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000, 0x79bc, + 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182, 0x0841, + 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c, 0x810c, + 0x080c, 0x1572, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827, + 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500, + 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c, + 0x7bec, 0x080c, 0x1977, 0x0090, 0x7827, 0x0015, 0x782b, 0x0000, + 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, 0x0020, + 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, 0x0005, + 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, 0x0015, + 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800, 0x6802, + 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005, 0x2001, + 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041, 0x0005, + 0x00f6, 0x2079, 0x0300, 0x0006, 0x7808, 0xd09c, 0x0140, 0x0016, + 0x0026, 0x00c6, 0x080c, 0x1365, 0x00ce, 0x002e, 0x001e, 0x000e, + 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0059, 0x1118, + 0x000e, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000, 0x2004, + 0x080c, 0x0df6, 0x2009, 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc, + 0x1dd8, 0x0005, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, + 0x781b, 0x8080, 0x0c79, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, + 0x2004, 0x080c, 0x0df6, 0x7037, 0x0001, 0x7150, 0x7037, 0x0002, + 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x0005, 0x0006, + 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, + 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a57, 0x2404, + 0x8000, 0x0208, 0x2022, 0x080c, 0x7bec, 0x080c, 0x1977, 0x9006, + 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, + 0x0016, 0x2071, 0x0200, 0x0879, 0x6124, 0xd1dc, 0x01f8, 0x701c, + 0xd08c, 0x0904, 0x1646, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, + 0xd0bc, 0x0904, 0x1646, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, + 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x1646, 0x9c06, 0x15f0, + 0x0126, 0x2091, 0x2600, 0x080c, 0x7b33, 0x012e, 0x7358, 0x745c, + 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x190c, 0xc115, 0xab42, 0xac3e, 0x2001, 0x187d, + 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, + 0xffff, 0x080c, 0x1ede, 0x1190, 0x080c, 0x17f8, 0x2a00, 0xa816, + 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, + 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, + 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x150f, 0x0005, 0x080c, + 0x0df6, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001, 0xa001, + 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, + 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, + 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1ebe, 0x2165, 0x0002, 0x1686, + 0x16d3, 0x1686, 0x1686, 0x1686, 0x16b5, 0x1686, 0x168a, 0x167f, + 0x16ca, 0x1686, 0x1686, 0x1686, 0x1790, 0x169e, 0x1694, 0xa964, + 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x16ca, 0x9085, 0x0001, + 0x0804, 0x1786, 0xa87c, 0xd0bc, 0x0dc8, 0xa890, 0xa842, 0xa88c, + 0xa83e, 0xa888, 0x0804, 0x16da, 0xa87c, 0xd0bc, 0x0d78, 0xa890, + 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1729, 0xa87c, 0xd0bc, + 0x0d28, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, + 0x0df6, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ebe, 0x2065, + 0xa888, 0xd19c, 0x1904, 0x1729, 0x0428, 0xa87c, 0xd0ac, 0x0970, + 0xa804, 0x9045, 0x090c, 0x0df6, 0xa164, 0xa91a, 0x91ec, 0x000f, + 0x9d80, 0x1ebe, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, + 0x1729, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1686, 0x9006, 0xa842, + 0xa83e, 0x0804, 0x1729, 0xa87c, 0xd0ac, 0x0904, 0x1686, 0x9006, + 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082, + 0x001b, 0x0002, 0x16fd, 0x16fd, 0x16ff, 0x16fd, 0x16fd, 0x16fd, + 0x1705, 0x16fd, 0x16fd, 0x16fd, 0x170b, 0x16fd, 0x16fd, 0x16fd, + 0x1711, 0x16fd, 0x16fd, 0x16fd, 0x1717, 0x16fd, 0x16fd, 0x16fd, + 0x171d, 0x16fd, 0x16fd, 0x16fd, 0x1723, 0x080c, 0x0df6, 0xa574, + 0xa478, 0xa37c, 0xa280, 0x0804, 0x176e, 0xa584, 0xa488, 0xa38c, + 0xa290, 0x0804, 0x176e, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, + 0x176e, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x176e, 0xa5b4, + 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x176e, 0xa5c4, 0xa4c8, 0xa3cc, + 0xa2d0, 0x0804, 0x176e, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, + 0x176e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, + 0x0002, 0x174c, 0x174a, 0x174a, 0x174a, 0x174a, 0x174a, 0x1753, + 0x174a, 0x174a, 0x174a, 0x174a, 0x174a, 0x175a, 0x174a, 0x174a, + 0x174a, 0x174a, 0x174a, 0x1761, 0x174a, 0x174a, 0x174a, 0x174a, + 0x174a, 0x1768, 0x080c, 0x0df6, 0xa56c, 0xa470, 0xa774, 0xa678, + 0xa37c, 0xa280, 0x00d8, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, + 0xa298, 0x00a0, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, + 0x0068, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0030, + 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, + 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, + 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, + 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, + 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, + 0x0804, 0x1686, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001, + 0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, + 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1eb9, + 0xa813, 0x1eb9, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, + 0x090c, 0x0df6, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, + 0x1a0c, 0x0df6, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, + 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, + 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, + 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, + 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, + 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, + 0x0df6, 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1ebe, + 0x2015, 0x82ff, 0x090c, 0x0df6, 0xaa12, 0x2205, 0xa80a, 0x0c08, + 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x18ed, + 0x184f, 0x184f, 0x18ed, 0x18ed, 0x18e7, 0x18ed, 0x184f, 0x189e, + 0x189e, 0x189e, 0x18ed, 0x18ed, 0x18ed, 0x18e4, 0x189e, 0xc0fc, + 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x18ef, + 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, + 0x183b, 0x1839, 0x1839, 0x1839, 0x1839, 0x1839, 0x183f, 0x1839, + 0x1839, 0x1839, 0x1839, 0x1839, 0x1843, 0x1839, 0x1839, 0x1839, + 0x1839, 0x1839, 0x1847, 0x1839, 0x1839, 0x1839, 0x1839, 0x1839, + 0x184b, 0x080c, 0x0df6, 0xa774, 0xa678, 0x0804, 0x18ef, 0xa78c, + 0xa690, 0x0804, 0x18ef, 0xa7a4, 0xa6a8, 0x0804, 0x18ef, 0xa7bc, + 0xa6c0, 0x0804, 0x18ef, 0xa7d4, 0xa6d8, 0x0804, 0x18ef, 0x2c05, + 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x1872, + 0x1872, 0x1874, 0x1872, 0x1872, 0x1872, 0x187a, 0x1872, 0x1872, + 0x1872, 0x1880, 0x1872, 0x1872, 0x1872, 0x1886, 0x1872, 0x1872, + 0x1872, 0x188c, 0x1872, 0x1872, 0x1872, 0x1892, 0x1872, 0x1872, + 0x1872, 0x1898, 0x080c, 0x0df6, 0xa574, 0xa478, 0xa37c, 0xa280, + 0x0804, 0x18ef, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x18ef, + 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x18ef, 0xa5a4, 0xa4a8, + 0xa3ac, 0xa2b0, 0x0804, 0x18ef, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, + 0x0804, 0x18ef, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x18ef, + 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x18ef, 0x2c05, 0x908a, + 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x18c1, 0x18bf, + 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18c8, 0x18bf, 0x18bf, 0x18bf, + 0x18bf, 0x18bf, 0x18cf, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18bf, + 0x18d6, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18dd, 0x080c, + 0x0df6, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x0438, + 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x0400, 0xa59c, + 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x00c8, 0xa5b4, 0xa4b8, + 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0090, 0xa5cc, 0xa4d0, 0xa7d4, + 0xa6d8, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c, + 0x1e7c, 0x1904, 0x17f8, 0x900e, 0x0050, 0x080c, 0x0df6, 0xab2e, + 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x1e7c, 0x0005, + 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c, + 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002, + 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000, + 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005, + 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158, + 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009, + 0x0048, 0x0804, 0xa068, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, + 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186, + 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008, + 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x1365, + 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6, + 0x7808, 0xd09c, 0x190c, 0x1365, 0x00ce, 0x2001, 0x0038, 0x080c, + 0x1a07, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c, + 0x0df6, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c, + 0x1a16, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1a03, 0x7827, + 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6, + 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x2001, 0xf000, + 0x8001, 0x090c, 0x0df6, 0x7aac, 0xd2ac, 0x1dd0, 0x00fe, 0x080c, + 0x717e, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160, + 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0, + 0x0059, 0x0804, 0x7246, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502, + 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c, + 0x2aa3, 0x2009, 0x003c, 0x080c, 0x2200, 0x2001, 0x015d, 0x2003, + 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x816f, 0x70a0, + 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003, + 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x132d, 0x7803, 0x0001, + 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, + 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x717e, 0x1108, + 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, + 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111, + 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003, + 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001, + 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e, + 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08, + 0x621c, 0x080c, 0x1580, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c, + 0x15ad, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064, + 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186, + 0x0040, 0x0904, 0x1a74, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80, + 0x080c, 0x0df6, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000, + 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0, + 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084, + 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037, + 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1a0d, + 0x9186, 0x0040, 0x190c, 0x0df6, 0x00d6, 0x2069, 0x0200, 0x692c, + 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085, + 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0, + 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0df6, + 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400, + 0x2071, 0x1a42, 0x2079, 0x0090, 0x012e, 0x0005, 0x9280, 0x0005, + 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904, 0x1b09, 0xa964, 0x9184, + 0x0007, 0x0002, 0x1a92, 0x1af4, 0x1aa9, 0x1aa9, 0x1aa9, 0x1adc, + 0x1abc, 0x1aab, 0x918c, 0x00ff, 0x9186, 0x0008, 0x1170, 0xa87c, + 0xd0b4, 0x0904, 0x1cbf, 0x9006, 0xa842, 0xa83e, 0xa988, 0x2900, + 0xa85a, 0xa813, 0x1eb9, 0x0804, 0x1b05, 0x9186, 0x0048, 0x0904, + 0x1af4, 0x080c, 0x0df6, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa890, + 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, + 0xa84a, 0xa988, 0x0804, 0x1afc, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x001e, 0x1d38, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa890, 0xa842, + 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, + 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ebe, + 0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015, + 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa804, 0xa85a, 0x2040, + 0xa064, 0x9084, 0x000f, 0x9080, 0x1ebe, 0x2005, 0xa812, 0xa988, + 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, + 0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084, + 0x000f, 0x9080, 0x1ebe, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd, + 0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c, + 0x1d00, 0x00e6, 0x2071, 0x1a42, 0x7000, 0x9005, 0x1904, 0x1b61, + 0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b, + 0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6, + 0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200, + 0x7803, 0x0040, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, + 0x781a, 0x78d7, 0x0000, 0x00fe, 0xa814, 0x2050, 0xa858, 0x2040, + 0xa810, 0x2060, 0xa064, 0x90ec, 0x000f, 0xa944, 0x791a, 0x7116, + 0xa848, 0x781e, 0x701a, 0x9006, 0x700e, 0x7012, 0x7004, 0xa940, + 0xa838, 0x9106, 0x1188, 0xa93c, 0xa834, 0x9106, 0x1168, 0x8aff, + 0x01a8, 0x0126, 0x2091, 0x8000, 0x00a1, 0x0108, 0x0091, 0x012e, + 0x9006, 0x00ee, 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34, + 0x080c, 0x1ede, 0x004e, 0x003e, 0x0d50, 0x0c98, 0x9085, 0x0001, + 0x0c80, 0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, + 0x0904, 0x1cb8, 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, + 0x0a04, 0x1cb7, 0x9705, 0x0904, 0x1cb7, 0x903e, 0x2730, 0xa880, + 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1c9b, 0x1bdc, 0x1bdc, 0x1c9b, + 0x1c9b, 0x1c79, 0x1c9b, 0x1bdc, 0x1c7f, 0x1c2b, 0x1c2b, 0x1c9b, + 0x1c9b, 0x1c9b, 0x1c73, 0x1c2b, 0xc0fc, 0xa882, 0xab2c, 0xaa30, + 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1c9d, 0x2c05, 0x908a, 0x0034, + 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x1bc8, 0x1bc6, 0x1bc6, + 0x1bc6, 0x1bc6, 0x1bc6, 0x1bcc, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, + 0x1bc6, 0x1bd0, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bd4, + 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bd8, 0x080c, 0x0df6, + 0xa774, 0xa678, 0x0804, 0x1c9d, 0xa78c, 0xa690, 0x0804, 0x1c9d, + 0xa7a4, 0xa6a8, 0x0804, 0x1c9d, 0xa7bc, 0xa6c0, 0x0804, 0x1c9d, + 0xa7d4, 0xa6d8, 0x0804, 0x1c9d, 0x2c05, 0x908a, 0x0036, 0x1a0c, + 0x0df6, 0x9082, 0x001b, 0x0002, 0x1bff, 0x1bff, 0x1c01, 0x1bff, + 0x1bff, 0x1bff, 0x1c07, 0x1bff, 0x1bff, 0x1bff, 0x1c0d, 0x1bff, + 0x1bff, 0x1bff, 0x1c13, 0x1bff, 0x1bff, 0x1bff, 0x1c19, 0x1bff, + 0x1bff, 0x1bff, 0x1c1f, 0x1bff, 0x1bff, 0x1bff, 0x1c25, 0x080c, + 0x0df6, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x1c9d, 0xa584, + 0xa488, 0xa38c, 0xa290, 0x0804, 0x1c9d, 0xa594, 0xa498, 0xa39c, + 0xa2a0, 0x0804, 0x1c9d, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, + 0x1c9d, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1c9d, 0xa5c4, + 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x1c9d, 0xa5d4, 0xa4d8, 0xa3dc, + 0xa2e0, 0x0804, 0x1c9d, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, + 0x9082, 0x001b, 0x0002, 0x1c4e, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, + 0x1c4c, 0x1c56, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c5e, + 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c65, 0x1c4c, 0x1c4c, + 0x1c4c, 0x1c4c, 0x1c4c, 0x1c6c, 0x080c, 0x0df6, 0xa56c, 0xa470, + 0xa774, 0xa678, 0xa37c, 0xa280, 0x0804, 0x1c9d, 0xa584, 0xa488, + 0xa78c, 0xa690, 0xa394, 0xa298, 0x0804, 0x1c9d, 0xa59c, 0xa4a0, + 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x04c0, 0xa5b4, 0xa4b8, 0xa7bc, + 0xa6c0, 0xa3c4, 0xa2c8, 0x0488, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, + 0xa3dc, 0xa2e0, 0x0450, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, + 0x1510, 0x080c, 0x1e7c, 0x1904, 0x1b77, 0x900e, 0x04c8, 0xab64, + 0x939c, 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060, + 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1c2b, 0xab9c, 0x9016, + 0xad8c, 0xac90, 0xaf94, 0xae98, 0x0040, 0x9386, 0x0008, 0x0904, + 0x1c2b, 0x080c, 0x0df6, 0x080c, 0x0df6, 0x7b12, 0x7a16, 0x7d02, + 0x7c06, 0x7f0a, 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002, + 0xa83c, 0x9300, 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300, + 0x700e, 0x7010, 0x9201, 0x7012, 0x080c, 0x1e7c, 0x0008, 0x9006, + 0x002e, 0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, + 0x0df6, 0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, 0x9086, 0x0006, 0x1180, + 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, + 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, 0xa896, 0x7004, 0x2060, + 0x00c6, 0x080c, 0xb983, 0x00ce, 0x2001, 0x19d1, 0x2004, 0x9c06, + 0x1160, 0x2009, 0x0040, 0x080c, 0x2200, 0x080c, 0x9a8f, 0x2011, + 0x0000, 0x080c, 0x992d, 0x080c, 0x8c6c, 0x002e, 0x0804, 0x1e2e, + 0x0126, 0x2091, 0x2400, 0xa858, 0x2040, 0x792c, 0x782b, 0x0002, + 0x9184, 0x0700, 0x1904, 0x1cc1, 0x7000, 0x0002, 0x1e2e, 0x1d12, + 0x1d7f, 0x1e2c, 0x8001, 0x7002, 0xd19c, 0x1150, 0x8aff, 0x05b0, + 0x080c, 0x1b71, 0x0904, 0x1e2e, 0x080c, 0x1b71, 0x0804, 0x1e2e, + 0x782b, 0x0004, 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, + 0x11d8, 0xa87c, 0xc0f5, 0xa87e, 0x00b8, 0x0026, 0x0036, 0xab3c, + 0xaa40, 0x7810, 0xa82e, 0x931a, 0x7814, 0xa832, 0x9213, 0x7800, + 0xa81e, 0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, + 0x1e94, 0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, + 0x2c00, 0xa812, 0x7003, 0x0000, 0x0804, 0x1e2e, 0x00f6, 0x0026, + 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, + 0x1984, 0x9085, 0x0012, 0x7816, 0x0036, 0x2019, 0x1000, 0x8319, + 0x090c, 0x0df6, 0x7820, 0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e, + 0x9102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, + 0x000e, 0x78ca, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x002e, + 0x00fe, 0x782b, 0x0008, 0x7003, 0x0000, 0x0804, 0x1e2e, 0x8001, + 0x7002, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, 0x1d05, 0xd19c, + 0x1904, 0x1e2a, 0x8aff, 0x0904, 0x1e2e, 0x080c, 0x1b71, 0x0804, + 0x1e2e, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, 0x1e94, 0xdd9c, + 0x1904, 0x1de9, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082, + 0x001b, 0x0002, 0x1dbd, 0x1dbd, 0x1dbf, 0x1dbd, 0x1dbd, 0x1dbd, + 0x1dc5, 0x1dbd, 0x1dbd, 0x1dbd, 0x1dcb, 0x1dbd, 0x1dbd, 0x1dbd, + 0x1dd1, 0x1dbd, 0x1dbd, 0x1dbd, 0x1dd7, 0x1dbd, 0x1dbd, 0x1dbd, + 0x1ddd, 0x1dbd, 0x1dbd, 0x1dbd, 0x1de3, 0x080c, 0x0df6, 0xa07c, + 0x931a, 0xa080, 0x9213, 0x0804, 0x1d31, 0xa08c, 0x931a, 0xa090, + 0x9213, 0x0804, 0x1d31, 0xa09c, 0x931a, 0xa0a0, 0x9213, 0x0804, + 0x1d31, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1d31, 0xa0bc, + 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1d31, 0xa0cc, 0x931a, 0xa0d0, + 0x9213, 0x0804, 0x1d31, 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804, + 0x1d31, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, + 0x0002, 0x1e0c, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e12, + 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e18, 0x1e0a, 0x1e0a, + 0x1e0a, 0x1e0a, 0x1e0a, 0x1e1e, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, + 0x1e0a, 0x1e24, 0x080c, 0x0df6, 0xa07c, 0x931a, 0xa080, 0x9213, + 0x0804, 0x1d31, 0xa094, 0x931a, 0xa098, 0x9213, 0x0804, 0x1d31, + 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1d31, 0xa0c4, 0x931a, + 0xa0c8, 0x9213, 0x0804, 0x1d31, 0xa0dc, 0x931a, 0xa0e0, 0x9213, + 0x0804, 0x1d31, 0x0804, 0x1d2d, 0x080c, 0x0df6, 0x012e, 0x0005, + 0x00f6, 0x00e6, 0x2071, 0x1a42, 0x7000, 0x9086, 0x0000, 0x0904, + 0x1e79, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, + 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, 0xdbfc, + 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0df6, 0x0016, 0x2009, + 0x0040, 0x080c, 0x2200, 0x001e, 0x2001, 0x020c, 0x2102, 0x2009, + 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, + 0x0040, 0x080c, 0x2200, 0x782c, 0xd0fc, 0x09a8, 0x080c, 0x1d00, + 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, 0x782c, 0xd0ac, + 0x1de8, 0x2009, 0x0040, 0x080c, 0x2200, 0x782b, 0x0002, 0x7003, + 0x0000, 0x00ee, 0x00fe, 0x0005, 0x8c60, 0x2c05, 0x9005, 0x0110, + 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, + 0x9084, 0x000f, 0x9080, 0x1ebe, 0x2065, 0x8cff, 0x090c, 0x0df6, + 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8c61, 0x2c05, 0x9005, + 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005, 0x1108, 0x2900, + 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ece, 0x2065, + 0x8cff, 0x090c, 0x0df6, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025, + 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027, + 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x1eb1, + 0x1ead, 0x0000, 0x0000, 0x1ebb, 0x0000, 0x1eb1, 0x1eb8, 0x1eb8, + 0x1eb5, 0x0000, 0x0000, 0x0000, 0x1ebb, 0x1eb8, 0x0000, 0x1eb3, + 0x1eb3, 0x0000, 0x0000, 0x1ebb, 0x0000, 0x1eb3, 0x1eb9, 0x1eb9, + 0x1eb9, 0x0000, 0x0000, 0x0000, 0x1ebb, 0x1eb9, 0x00c6, 0x00d6, + 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x20bd, 0x2940, + 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118, + 0x2061, 0x1eb9, 0x00d0, 0x9de0, 0x1ebe, 0x9d86, 0x0007, 0x0130, + 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, + 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x20bd, + 0xa004, 0x9045, 0x0904, 0x20bd, 0x08d8, 0x2c05, 0x9005, 0x0904, + 0x1fa5, 0xdd9c, 0x1904, 0x1f61, 0x908a, 0x0036, 0x1a0c, 0x0df6, + 0x9082, 0x001b, 0x0002, 0x1f36, 0x1f36, 0x1f38, 0x1f36, 0x1f36, + 0x1f36, 0x1f3e, 0x1f36, 0x1f36, 0x1f36, 0x1f44, 0x1f36, 0x1f36, + 0x1f36, 0x1f4a, 0x1f36, 0x1f36, 0x1f36, 0x1f50, 0x1f36, 0x1f36, + 0x1f36, 0x1f56, 0x1f36, 0x1f36, 0x1f36, 0x1f5c, 0x080c, 0x0df6, + 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x1f9b, 0xa08c, 0x9422, + 0xa090, 0x931b, 0x0804, 0x1f9b, 0xa09c, 0x9422, 0xa0a0, 0x931b, + 0x0804, 0x1f9b, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x1f9b, + 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x1f9b, 0xa0cc, 0x9422, + 0xa0d0, 0x931b, 0x0804, 0x1f9b, 0xa0dc, 0x9422, 0xa0e0, 0x931b, + 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, + 0x1f83, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f88, 0x1f81, + 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f8d, 0x1f81, 0x1f81, 0x1f81, + 0x1f81, 0x1f81, 0x1f92, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f81, + 0x1f97, 0x080c, 0x0df6, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0098, + 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0, + 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc, + 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, 0x8a51, + 0x0904, 0x20bd, 0x8c60, 0x0804, 0x1f0d, 0xa004, 0x9045, 0x0904, + 0x20bd, 0x0804, 0x1ee8, 0x8a51, 0x0904, 0x20bd, 0x8c60, 0x2c05, + 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x20bd, 0xa064, 0x90ec, + 0x000f, 0x9de0, 0x1ebe, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882, + 0x0804, 0x20b2, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000, + 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x204f, 0x9082, 0x001b, 0x0002, + 0x1feb, 0x1feb, 0x1fed, 0x1feb, 0x1feb, 0x1feb, 0x1ffb, 0x1feb, + 0x1feb, 0x1feb, 0x2009, 0x1feb, 0x1feb, 0x1feb, 0x2017, 0x1feb, + 0x1feb, 0x1feb, 0x2025, 0x1feb, 0x1feb, 0x1feb, 0x2033, 0x1feb, + 0x1feb, 0x1feb, 0x2041, 0x080c, 0x0df6, 0xa17c, 0x2400, 0x9122, + 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa074, 0x9420, 0xa078, + 0x9319, 0x0804, 0x20ad, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, + 0x911b, 0x0a0c, 0x0df6, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804, + 0x20ad, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, + 0x0df6, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x20ad, 0xa1ac, + 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0a4, + 0x9420, 0xa0a8, 0x9319, 0x0804, 0x20ad, 0xa1bc, 0x2400, 0x9122, + 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0b4, 0x9420, 0xa0b8, + 0x9319, 0x0804, 0x20ad, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, + 0x911b, 0x0a0c, 0x0df6, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804, + 0x20ad, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, + 0x0df6, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x20ad, 0x9082, + 0x001b, 0x0002, 0x206d, 0x206b, 0x206b, 0x206b, 0x206b, 0x206b, + 0x207a, 0x206b, 0x206b, 0x206b, 0x206b, 0x206b, 0x2087, 0x206b, + 0x206b, 0x206b, 0x206b, 0x206b, 0x2094, 0x206b, 0x206b, 0x206b, + 0x206b, 0x206b, 0x20a1, 0x080c, 0x0df6, 0xa17c, 0x2400, 0x9122, + 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa06c, 0x9420, 0xa070, + 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b, + 0x0a0c, 0x0df6, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac, + 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa09c, + 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8, + 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0b4, 0x9420, 0xa0b8, 0x9319, + 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, + 0x0df6, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, 0xa880, + 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816, + 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, 0x00ce, + 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c, + 0x0def, 0x9084, 0x0007, 0x0002, 0x20de, 0x1d00, 0x20de, 0x20d4, + 0x20d7, 0x20da, 0x20d7, 0x20da, 0x080c, 0x1d00, 0x0005, 0x080c, + 0x11ee, 0x0005, 0x080c, 0x1d00, 0x080c, 0x11ee, 0x0005, 0x0126, + 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800, + 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410, + 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f, + 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600, + 0x781c, 0xd0a4, 0x190c, 0x21fd, 0x7900, 0xd1dc, 0x1118, 0x9084, + 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x2125, 0x211d, 0x7b33, + 0x211d, 0x211f, 0x211f, 0x211f, 0x211f, 0x7b19, 0x211d, 0x2121, + 0x211d, 0x211f, 0x211d, 0x211f, 0x211d, 0x080c, 0x0df6, 0x0031, + 0x0020, 0x080c, 0x7b19, 0x080c, 0x7b33, 0x0005, 0x0006, 0x0016, + 0x0026, 0x080c, 0xdbfc, 0x7930, 0x9184, 0x0003, 0x01c0, 0x2001, + 0x19d1, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133, 0x2004, 0x9005, + 0x090c, 0x0df6, 0x00c6, 0x2001, 0x19d1, 0x2064, 0x080c, 0xb983, + 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2200, 0x00d0, 0x9184, + 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, 0x717e, + 0x1138, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c, 0x709e, 0x0010, + 0x080c, 0x5cee, 0x080c, 0x7be2, 0x0041, 0x0018, 0x9184, 0x9540, + 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, + 0x0056, 0x2071, 0x1a3f, 0x080c, 0x1977, 0x005e, 0x004e, 0x003e, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128, + 0x2001, 0x1949, 0x2102, 0x2001, 0x1951, 0x2102, 0x2001, 0x013b, + 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200, + 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, 0x2320, + 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, 0x8423, + 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, 0x8003, + 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011, + 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c, + 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, 0x9182, + 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, 0x9182, + 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, 0x2011, + 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, 0x9402, + 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, 0x012e, + 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0, + 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200, + 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de, + 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8, + 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, 0x0def, + 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, + 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, + 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, + 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2a9d, 0x080c, 0x2974, + 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0558, 0x6054, 0x8004, + 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, 0x6150, 0x918c, 0xfff3, + 0x9105, 0x6052, 0x6050, 0x9084, 0xb17f, 0x9085, 0x2000, 0x6052, + 0x2009, 0x1977, 0x2011, 0x1978, 0x6358, 0x939c, 0x38f0, 0x2320, + 0x080c, 0x29e1, 0x1238, 0x939d, 0x4003, 0x94a5, 0x8603, 0x230a, + 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, 0x8603, 0x230a, 0x2412, + 0x0050, 0x2001, 0x1977, 0x2003, 0x0700, 0x2001, 0x1978, 0x2003, + 0x0700, 0x080c, 0x2ba9, 0x9006, 0x080c, 0x29a3, 0x9006, 0x080c, + 0x2986, 0x20a9, 0x0012, 0x1d04, 0x2263, 0x2091, 0x6000, 0x1f04, + 0x2263, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, + 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x26a6, 0x2009, + 0x00ef, 0x6132, 0x6136, 0x080c, 0x26b6, 0x60e7, 0x0000, 0x61ea, + 0x60e3, 0x0002, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, + 0x602f, 0x0000, 0x6007, 0x149f, 0x60bb, 0x0000, 0x20a9, 0x0018, + 0x60bf, 0x0000, 0x1f04, 0x2290, 0x60bb, 0x0000, 0x60bf, 0x0108, + 0x60bf, 0x0012, 0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, + 0x601f, 0x001e, 0x600f, 0x006b, 0x602b, 0x402f, 0x012e, 0x0005, + 0x00f6, 0x2079, 0x0140, 0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, + 0x0000, 0x00fe, 0x0005, 0x2001, 0x1834, 0x2003, 0x0000, 0x2001, + 0x1833, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x6124, 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, + 0x002a, 0x9195, 0x0004, 0x9284, 0x0007, 0x0002, 0x22f0, 0x22d6, + 0x22d9, 0x22dc, 0x22e1, 0x22e3, 0x22e7, 0x22eb, 0x080c, 0x84e2, + 0x00b8, 0x080c, 0x85b1, 0x00a0, 0x080c, 0x85b1, 0x080c, 0x84e2, + 0x0078, 0x0099, 0x0068, 0x080c, 0x84e2, 0x0079, 0x0048, 0x080c, + 0x85b1, 0x0059, 0x0028, 0x080c, 0x85b1, 0x080c, 0x84e2, 0x0029, + 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, + 0xd09c, 0x0118, 0xd19c, 0x1904, 0x2547, 0xd1f4, 0x190c, 0x0def, + 0x080c, 0x717e, 0x0904, 0x234b, 0x080c, 0xc459, 0x1120, 0x7000, + 0x9086, 0x0003, 0x0570, 0x6024, 0x9084, 0x1800, 0x0550, 0x080c, + 0x71a1, 0x0118, 0x080c, 0x718f, 0x1520, 0x6027, 0x0020, 0x6043, + 0x0000, 0x080c, 0xc459, 0x0168, 0x080c, 0x71a1, 0x1150, 0x2001, + 0x1982, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x6fed, 0x0804, + 0x254a, 0x70a0, 0x9005, 0x1150, 0x70a3, 0x0001, 0x00d6, 0x2069, + 0x0140, 0x080c, 0x71d2, 0x00de, 0x1904, 0x254a, 0x080c, 0x7484, + 0x0428, 0x080c, 0x71a1, 0x1590, 0x6024, 0x9084, 0x1800, 0x1108, + 0x0468, 0x080c, 0x7484, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c, + 0x709e, 0x0804, 0x2547, 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170, + 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7094, 0x9086, + 0x0029, 0x1110, 0x080c, 0x7369, 0x0804, 0x2547, 0x080c, 0x747f, + 0x0048, 0x2001, 0x1957, 0x2003, 0x0002, 0x0020, 0x080c, 0x72cd, + 0x0804, 0x2547, 0x080c, 0x7403, 0x0804, 0x2547, 0xd1ac, 0x0904, + 0x2468, 0x080c, 0x717e, 0x11c0, 0x6027, 0x0020, 0x0006, 0x0026, + 0x0036, 0x080c, 0x7198, 0x1158, 0x080c, 0x747a, 0x080c, 0x5e2f, + 0x080c, 0x709e, 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, 0x003e, + 0x002e, 0x000e, 0x080c, 0x7156, 0x0016, 0x0046, 0x00c6, 0x644c, + 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, + 0x6043, 0x0010, 0x74d6, 0x948c, 0xff00, 0x7038, 0xd084, 0x0190, + 0x080c, 0xc459, 0x1118, 0x9186, 0xf800, 0x1160, 0x7044, 0xd084, + 0x1148, 0xc085, 0x7046, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, + 0x4a17, 0x003e, 0x080c, 0xc452, 0x1904, 0x2445, 0x9196, 0xff00, + 0x05a8, 0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, + 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x31ee, 0x0128, 0xc18d, + 0x7132, 0x080c, 0x66c1, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, + 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, + 0x0904, 0x2445, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, + 0xd1ac, 0x1904, 0x2445, 0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, + 0x8013, 0x080c, 0x4a17, 0x003e, 0x0804, 0x2445, 0x7038, 0xd08c, + 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2445, 0xc1ad, + 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x4a17, 0x003e, + 0x7130, 0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0, 0x0016, + 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8450, 0x2019, 0x000e, + 0x00c6, 0x2061, 0x0000, 0x080c, 0xd7af, 0x00ce, 0x9484, 0x00ff, + 0x9080, 0x31f3, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, + 0x2009, 0x000e, 0x080c, 0xd837, 0x001e, 0xd1ac, 0x1148, 0x0016, + 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3060, 0x001e, 0x00a8, + 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a3, 0x1140, + 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x5e49, + 0x8108, 0x1f04, 0x2435, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, + 0x9f70, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, 0x9296, + 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, 0xd29c, + 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, 0x622a, + 0x2003, 0x0001, 0x2001, 0x1825, 0x2003, 0x0000, 0x6027, 0x0020, + 0xd194, 0x0904, 0x2547, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x24f0, + 0x080c, 0x82d9, 0x080c, 0x961a, 0x6027, 0x0004, 0x00f6, 0x2019, + 0x19cb, 0x2304, 0x907d, 0x0904, 0x24bf, 0x7804, 0x9086, 0x0032, + 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, 0x782c, + 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, + 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, 0x080c, + 0x2b7f, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, 0x080c, + 0x2a78, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x080c, 0x8a83, 0x080c, 0x8b8f, + 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0x9fea, 0x009e, + 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, 0x00fe, + 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, + 0x2b7f, 0x00de, 0x00c6, 0x2061, 0x19c2, 0x6028, 0x080c, 0xc459, + 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, 0x1238, + 0x8000, 0x602a, 0x00ce, 0x080c, 0x95f6, 0x0804, 0x2546, 0x2061, + 0x0100, 0x62c0, 0x080c, 0x9df6, 0x2019, 0x19cb, 0x2304, 0x9065, + 0x0120, 0x2009, 0x0027, 0x080c, 0xa068, 0x00ce, 0x0804, 0x2546, + 0xd2bc, 0x0904, 0x2533, 0x080c, 0x82e6, 0x6014, 0x9084, 0x1984, + 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, + 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b7f, 0x00de, 0x00c6, + 0x2061, 0x19c2, 0x6044, 0x080c, 0xc459, 0x0120, 0x909a, 0x0003, + 0x1628, 0x0018, 0x909a, 0x00c8, 0x1608, 0x8000, 0x6046, 0x603c, + 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0, 0x080c, 0x82de, 0x9080, + 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, 0x1984, + 0x918d, 0x0012, 0x6116, 0x00d0, 0x6114, 0x918c, 0x1984, 0x918d, + 0x0016, 0x6116, 0x0098, 0x6027, 0x0004, 0x0080, 0x0036, 0x2019, + 0x0001, 0x080c, 0x98b1, 0x003e, 0x2019, 0x19d1, 0x2304, 0x9065, + 0x0120, 0x2009, 0x004f, 0x080c, 0xa068, 0x00ce, 0x001e, 0xd19c, + 0x0904, 0x2611, 0x7038, 0xd0ac, 0x1904, 0x25e6, 0x0016, 0x0156, + 0x6027, 0x0008, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0904, + 0x25c3, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, + 0x6052, 0x080c, 0x2a97, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, + 0x1d04, 0x2568, 0x080c, 0x830d, 0x1f04, 0x2568, 0x6050, 0x9085, + 0x0400, 0x9084, 0xdfbf, 0x6052, 0x20a9, 0x0028, 0xa001, 0x1f04, + 0x2576, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04, + 0x257f, 0x080c, 0x830d, 0x6020, 0xd09c, 0x1138, 0x015e, 0x6152, + 0x001e, 0x6027, 0x0008, 0x0804, 0x2611, 0x080c, 0x2a5f, 0x1f04, + 0x257f, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016, 0x6028, + 0xc09c, 0x602a, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0xdbdb, + 0x080c, 0xdbf6, 0x080c, 0x54df, 0xd0fc, 0x1138, 0x080c, 0xc452, + 0x1120, 0x9085, 0x0001, 0x080c, 0x71c2, 0x9006, 0x080c, 0x2b6f, + 0x2009, 0x0002, 0x080c, 0x2a9d, 0x00e6, 0x2071, 0x1800, 0x7003, + 0x0004, 0x080c, 0x0ecc, 0x00ee, 0x6027, 0x0008, 0x080c, 0x0b8f, + 0x001e, 0x0804, 0x2611, 0x080c, 0x2ba9, 0x080c, 0x2bdc, 0x6050, + 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x0f04, 0x25e4, 0x1d04, 0x25ce, + 0x080c, 0x830d, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x29f1, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052, 0x6027, + 0x0008, 0x015e, 0x001e, 0x0468, 0x015e, 0x001e, 0x0016, 0x6028, + 0xc09c, 0x602a, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0xdbdb, + 0x080c, 0xdbf6, 0x080c, 0x54df, 0xd0fc, 0x1138, 0x080c, 0xc452, + 0x1120, 0x9085, 0x0001, 0x080c, 0x71c2, 0x9006, 0x080c, 0x2b6f, + 0x2009, 0x0002, 0x080c, 0x2a9d, 0x00e6, 0x2071, 0x1800, 0x7003, + 0x0004, 0x080c, 0x0ecc, 0x00ee, 0x6027, 0x0008, 0x080c, 0x0b8f, + 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0006, 0x0016, + 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, + 0x1800, 0x71cc, 0x70ce, 0x9116, 0x0904, 0x2665, 0x81ff, 0x01a0, + 0x2009, 0x0000, 0x080c, 0x2a9d, 0x2011, 0x8011, 0x2019, 0x010e, + 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, + 0x0000, 0x080c, 0x4a17, 0x0448, 0x2001, 0x1983, 0x200c, 0x81ff, + 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, + 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4a17, 0x080c, 0x0ecc, + 0x080c, 0x54df, 0xd0fc, 0x1188, 0x080c, 0xc452, 0x1170, 0x00c6, + 0x080c, 0x2701, 0x080c, 0x9818, 0x2061, 0x0100, 0x2019, 0x0028, + 0x2009, 0x0002, 0x080c, 0x3060, 0x00ce, 0x012e, 0x00fe, 0x00ee, + 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, + 0x2130, 0x9094, 0xff00, 0x11f0, 0x2011, 0x1836, 0x2214, 0xd2ac, + 0x11c8, 0x81ff, 0x01e8, 0x2011, 0x181e, 0x2204, 0x9106, 0x1190, + 0x2011, 0x181f, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, + 0x1148, 0x2011, 0x181f, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, + 0x9206, 0x1120, 0x2500, 0x080c, 0x7e3f, 0x0048, 0x9584, 0x00ff, + 0x9080, 0x31f3, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, + 0x9080, 0x31f3, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, + 0x0140, 0x2001, 0x1817, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, + 0x6852, 0x6856, 0x1f04, 0x26b1, 0x00de, 0x0005, 0x0006, 0x00d6, + 0x0026, 0x2069, 0x0140, 0x2001, 0x1817, 0x2102, 0x8114, 0x8214, + 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, + 0x1128, 0x9184, 0x000f, 0x9080, 0xe3a6, 0x2005, 0x6856, 0x8211, + 0x1f04, 0x26c6, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, + 0x1800, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, + 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, + 0x6980, 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, + 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, + 0x26f6, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, + 0x0005, 0x080c, 0x54db, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, + 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xd837, 0x004e, 0x0005, + 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, + 0x276d, 0x080c, 0x29e1, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, + 0x1120, 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, + 0x2011, 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, + 0x2009, 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, + 0x0002, 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, + 0x0078, 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, + 0x9084, 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, + 0x2300, 0x9080, 0x0020, 0x2018, 0x080c, 0x847e, 0x928c, 0xff00, + 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, + 0x2009, 0x0138, 0x220a, 0x080c, 0x717e, 0x1118, 0x2009, 0x1947, + 0x220a, 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, + 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, + 0x200c, 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0def, + 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, 0x2004, + 0xd0dc, 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, + 0x004c, 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, + 0x2001, 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, + 0x2001, 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, + 0x0005, 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, + 0x1800, 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x196a, + 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0df6, 0x0033, 0x00ee, 0x002e, + 0x001e, 0x000e, 0x015e, 0x0005, 0x27cb, 0x27e9, 0x280d, 0x280f, + 0x2838, 0x283a, 0x283c, 0x2001, 0x0001, 0x080c, 0x2616, 0x080c, + 0x2a51, 0x2001, 0x196c, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, + 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c, 0x29fd, 0x2001, 0x196a, + 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283d, 0x080c, 0x82eb, + 0x0005, 0x2009, 0x196f, 0x200b, 0x0000, 0x2001, 0x1974, 0x2003, + 0x0036, 0x2001, 0x1973, 0x2003, 0x002a, 0x2001, 0x196c, 0x2003, + 0x0001, 0x9006, 0x080c, 0x2986, 0x2001, 0xffff, 0x20a9, 0x0009, + 0x080c, 0x29fd, 0x2001, 0x196a, 0x2003, 0x0006, 0x2009, 0x001e, + 0x2011, 0x283d, 0x080c, 0x82eb, 0x0005, 0x080c, 0x0df6, 0x2001, + 0x1974, 0x2003, 0x0036, 0x2001, 0x196c, 0x2003, 0x0003, 0x7a38, + 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x2986, 0x2001, 0x1970, 0x2003, 0x0000, 0x2001, + 0xffff, 0x20a9, 0x0009, 0x080c, 0x29fd, 0x2001, 0x196a, 0x2003, + 0x0006, 0x2009, 0x001e, 0x2011, 0x283d, 0x080c, 0x82eb, 0x0005, + 0x080c, 0x0df6, 0x080c, 0x0df6, 0x0005, 0x0006, 0x0016, 0x0026, + 0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, + 0x2001, 0x196c, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0df6, 0x0043, + 0x012e, 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, + 0x285f, 0x287b, 0x28b7, 0x28e3, 0x2903, 0x290f, 0x2911, 0x080c, + 0x29f1, 0x1190, 0x2009, 0x1972, 0x2104, 0x7a38, 0x9294, 0x0005, + 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, + 0x196a, 0x2003, 0x0001, 0x0030, 0x080c, 0x2935, 0x2001, 0xffff, + 0x080c, 0x27da, 0x0005, 0x080c, 0x2913, 0x05c0, 0x2009, 0x1973, + 0x2104, 0x8001, 0x200a, 0x080c, 0x29f1, 0x1158, 0x7a38, 0x9294, + 0x0005, 0x9296, 0x0005, 0x0518, 0x2009, 0x1972, 0x2104, 0xc085, + 0x200a, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, + 0x0118, 0x080c, 0x291b, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, + 0x0006, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, + 0x080c, 0x29a3, 0x2001, 0x196c, 0x2003, 0x0002, 0x0028, 0x2001, + 0x196a, 0x2003, 0x0003, 0x0010, 0x080c, 0x27fc, 0x0005, 0x080c, + 0x2913, 0x0540, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a, 0x080c, + 0x29f1, 0x1148, 0x2001, 0x196a, 0x2003, 0x0003, 0x2001, 0x196b, + 0x2003, 0x0000, 0x00b8, 0x2009, 0x1973, 0x2104, 0x9005, 0x1118, + 0x080c, 0x2958, 0x0010, 0x080c, 0x2928, 0x080c, 0x291b, 0x2009, + 0x196f, 0x200b, 0x0000, 0x2001, 0x196c, 0x2003, 0x0001, 0x080c, + 0x27fc, 0x0000, 0x0005, 0x0479, 0x01e8, 0x080c, 0x29f1, 0x1198, + 0x2009, 0x1970, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, + 0x0078, 0x2001, 0x1975, 0x2003, 0x000a, 0x2009, 0x1972, 0x2104, + 0xc0fd, 0x200a, 0x0038, 0x00f9, 0x2001, 0x196c, 0x2003, 0x0004, + 0x080c, 0x2827, 0x0005, 0x0079, 0x0148, 0x080c, 0x29f1, 0x1118, + 0x080c, 0x2813, 0x0018, 0x0079, 0x080c, 0x2827, 0x0005, 0x080c, + 0x0df6, 0x080c, 0x0df6, 0x2009, 0x1974, 0x2104, 0x8001, 0x200a, + 0x090c, 0x2974, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, + 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29a3, 0x0005, + 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, + 0x2001, 0x0001, 0x080c, 0x2986, 0x0005, 0x2009, 0x196f, 0x2104, + 0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, + 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, + 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, + 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29a3, 0x0005, + 0x0086, 0x2001, 0x1972, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0df6, + 0x2009, 0x1971, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, + 0x1120, 0xd084, 0x1120, 0x080c, 0x0df6, 0x9006, 0x0010, 0x2001, + 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x196a, + 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x297a, 0x2001, + 0x1971, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, + 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, + 0x0004, 0x783a, 0x2009, 0x1977, 0x210c, 0x795a, 0x0050, 0x7838, + 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x1978, 0x210c, + 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, + 0x0188, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x1120, 0x7850, 0x9084, 0xfff0, + 0x7852, 0x0428, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, + 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x11c8, 0x7850, 0x9084, + 0xfff0, 0x0016, 0x2009, 0x017f, 0x210c, 0x918e, 0x0005, 0x0140, + 0x2009, 0x0003, 0x210c, 0x918c, 0x0600, 0x918e, 0x0400, 0x0118, + 0x9085, 0x000a, 0x0010, 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, + 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, + 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, + 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2a97, 0xd09c, + 0x1110, 0x1f04, 0x29f4, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, + 0x2091, 0x8000, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0170, + 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, + 0x080c, 0x2a97, 0x9085, 0x2000, 0x7852, 0x0000, 0x000e, 0x2008, + 0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, + 0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, + 0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, + 0x0006, 0x1d04, 0x2a31, 0x080c, 0x830d, 0x1f04, 0x2a31, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x0160, 0x7850, 0x9085, 0x0400, + 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2a97, 0x9085, 0x1000, 0x7852, + 0x0020, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e, 0x012e, + 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128, 0x7850, + 0x9084, 0xffcf, 0x7852, 0x0010, 0x080c, 0x2bdc, 0x0005, 0x0006, + 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, + 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2a69, 0x0028, 0x7854, + 0xd08c, 0x1110, 0x1f04, 0x2a6f, 0x00fe, 0x015e, 0x000e, 0x0005, + 0x1d04, 0x2a78, 0x080c, 0x830d, 0x1f04, 0x2a78, 0x0005, 0x0006, + 0x2001, 0x1976, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, + 0x2001, 0x1976, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, 0x0006, + 0x2001, 0x1976, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, 0xa001, + 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, 0x1983, + 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140, + 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, 0x200a, + 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, 0x918c, 0xff00, + 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, 0x0170, 0x9186, 0x0100, + 0x1904, 0x2b10, 0x0048, 0x0016, 0x2009, 0x1a58, 0x2104, 0x8000, + 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, 0x080c, 0x0e7b, + 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169, 0x2104, + 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, 0x1db0, 0x9086, + 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, 0x2031, 0x0002, 0x233c, + 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a59, 0x263c, 0x8738, + 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, 0x9402, 0x02a0, 0x19d0, + 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, 0x200c, 0x918c, + 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, 0x180c, 0x2104, 0xc0dd, + 0x200a, 0x0008, 0x0421, 0x2001, 0x195b, 0x200c, 0x080c, 0x0e7b, + 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0dc, 0x01b0, + 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001, 0x0141, 0x2004, + 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126, 0x2091, 0x8000, + 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e, 0x0005, 0x00c6, + 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, 0x0161, 0x2003, 0x0000, + 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, 0x0008, 0x6104, 0x918e, + 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, 0x6017, 0x0040, 0x04b9, + 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, 0x0016, 0x2019, 0x0141, + 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, 0x9084, 0x2800, 0x0dc0, + 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, 0x9385, 0x0009, + 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012, 0x6016, 0x003e, + 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, 0x0005, 0x0016, + 0x0026, 0x080c, 0x7198, 0x0108, 0xc0bc, 0x2009, 0x0140, 0x2114, + 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, + 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9285, 0x1000, + 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, + 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, + 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, 0x1128, 0x080c, + 0x7198, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, 0x001e, 0x000e, + 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, + 0x9084, 0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, + 0x2a78, 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, + 0x0005, 0x080c, 0x2a78, 0x6054, 0xd0bc, 0x090c, 0x0df6, 0x20a9, + 0x0005, 0x080c, 0x2a78, 0x6054, 0xd0ac, 0x090c, 0x0df6, 0x2009, + 0x198a, 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, + 0x6050, 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0006, 0x0156, + 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, + 0x080c, 0x2a97, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, + 0x2bf7, 0x080c, 0x830d, 0x1f04, 0x2bf7, 0x6050, 0x9085, 0x0400, + 0x9084, 0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x2e72, 0x2e72, + 0x2c96, 0x2c96, 0x2ca2, 0x2ca2, 0x2cae, 0x2cae, 0x2cbc, 0x2cbc, + 0x2cc8, 0x2cc8, 0x2cd6, 0x2cd6, 0x2ce4, 0x2ce4, 0x2cf6, 0x2cf6, + 0x2d02, 0x2d02, 0x2d10, 0x2d10, 0x2d2e, 0x2d2e, 0x2d4e, 0x2d4e, + 0x2d1e, 0x2d1e, 0x2d3e, 0x2d3e, 0x2d5c, 0x2d5c, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2d6e, 0x2d6e, + 0x2d7a, 0x2d7a, 0x2d88, 0x2d88, 0x2d96, 0x2d96, 0x2da6, 0x2da6, + 0x2db4, 0x2db4, 0x2dc4, 0x2dc4, 0x2dd4, 0x2dd4, 0x2de6, 0x2de6, + 0x2df4, 0x2df4, 0x2e04, 0x2e04, 0x2e26, 0x2e26, 0x2e48, 0x2e48, + 0x2e14, 0x2e14, 0x2e37, 0x2e37, 0x2e57, 0x2e57, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, + 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22bc, + 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x20c3, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, + 0x080c, 0x22bc, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20fe, 0x0804, 0x2e6a, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x22bc, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, 0x080c, 0x22bc, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0xa001, 0x0cf0, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1365, + 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x22bc, 0x080c, 0x1365, 0x0804, 0x2e6a, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x20c3, 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22bc, + 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, + 0x080c, 0x22bc, 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, + 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1365, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, 0x080c, 0x22bc, + 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, 0x0804, 0x2e6a, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x2770, 0x080c, 0x20c3, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x080c, 0x20c3, 0x080c, 0x22bc, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3, + 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3, + 0x080c, 0x22bc, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, + 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3, + 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, + 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, + 0x080c, 0x20c3, 0x080c, 0x22bc, 0x080c, 0x1365, 0x0498, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2770, 0x080c, 0x20c3, 0x080c, 0x1365, 0x080c, 0x20fe, 0x0410, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x2770, 0x080c, 0x1365, 0x080c, 0x20fe, 0x0098, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2770, 0x080c, 0x20c3, 0x080c, 0x22bc, 0x080c, 0x1365, 0x080c, + 0x20fe, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, + 0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, + 0x080c, 0x6687, 0x1904, 0x2f7c, 0x72d8, 0x2001, 0x1956, 0x2004, + 0x9005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, + 0x2f7c, 0x080c, 0x2f81, 0x0804, 0x2f7c, 0xd2cc, 0x1904, 0x2f7c, + 0x080c, 0x717e, 0x1120, 0x70ab, 0xffff, 0x0804, 0x2f7c, 0xd294, + 0x0120, 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x080c, 0x31e9, 0x0160, + 0x080c, 0xc459, 0x0128, 0x2001, 0x1817, 0x203c, 0x0804, 0x2f0b, + 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x2001, 0x1817, 0x203c, 0x7290, + 0xd284, 0x0904, 0x2f0b, 0xd28c, 0x1904, 0x2f0b, 0x0036, 0x73a8, + 0x938e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, + 0x2c04, 0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, + 0x9084, 0x00ff, 0x970e, 0x05a8, 0x908e, 0x0000, 0x0590, 0x908e, + 0x00ff, 0x1150, 0x7230, 0xd284, 0x1588, 0x7290, 0xc28d, 0x7292, + 0x70ab, 0xffff, 0x003e, 0x0478, 0x0026, 0x2011, 0x0010, 0x080c, + 0x66ed, 0x002e, 0x0118, 0x70ab, 0xffff, 0x0410, 0x900e, 0x080c, + 0x266d, 0x080c, 0x6343, 0x11c0, 0x080c, 0x66c9, 0x1168, 0x7030, + 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, 0x65c3, 0x0120, + 0x080c, 0x2f9a, 0x0148, 0x0028, 0x080c, 0x30da, 0x080c, 0x2fc6, + 0x0118, 0x8318, 0x0804, 0x2ebd, 0x73aa, 0x0010, 0x70ab, 0xffff, + 0x003e, 0x0804, 0x2f7c, 0x9780, 0x31f3, 0x203d, 0x97bc, 0xff00, + 0x873f, 0x2041, 0x007e, 0x70a8, 0x9096, 0xffff, 0x1118, 0x900e, + 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802, 0x20a8, 0x0020, + 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x2700, 0x0156, 0x0016, 0x9106, + 0x0904, 0x2f71, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e, + 0x0120, 0x2009, 0xffff, 0x0804, 0x2f79, 0xc484, 0x080c, 0x63a3, + 0x0150, 0x080c, 0xc459, 0x15a8, 0x080c, 0x31e9, 0x1590, 0x080c, + 0x6343, 0x15b8, 0x0008, 0xc485, 0x080c, 0x66c9, 0x1130, 0x7030, + 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7290, 0xd28c, 0x0180, + 0x080c, 0x66c9, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, + 0x6367, 0x0028, 0x080c, 0x3165, 0x01a0, 0x080c, 0x3190, 0x0088, + 0x080c, 0x30da, 0x080c, 0xc459, 0x1160, 0x080c, 0x2fc6, 0x0188, + 0x0040, 0x080c, 0xc459, 0x1118, 0x080c, 0x3165, 0x0110, 0x0451, + 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2f24, 0x70ab, 0xffff, + 0x0018, 0x001e, 0x015e, 0x71aa, 0x004e, 0x002e, 0x00ce, 0x00be, + 0x0005, 0x00c6, 0x0016, 0x70ab, 0x0001, 0x2009, 0x007e, 0x080c, + 0x6343, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x30da, + 0x04a9, 0x0128, 0x70d8, 0xc0bd, 0x70da, 0x080c, 0xc1a1, 0x001e, + 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x1860, + 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xa03b, 0x01d0, 0x2b00, + 0x6012, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x9006, 0x080c, 0x62e0, + 0x2001, 0x0000, 0x080c, 0x62f4, 0x0126, 0x2091, 0x8000, 0x70a4, + 0x8000, 0x70a6, 0x012e, 0x2009, 0x0004, 0x080c, 0xa068, 0x9085, + 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, + 0x00d6, 0x00c6, 0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, + 0x080c, 0xa03b, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, + 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x1110, 0x080c, 0x3095, 0x080c, 0xc1ca, 0x6023, 0x0001, + 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x0126, + 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0002, + 0x080c, 0xa068, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, + 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6343, + 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70df, + 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, + 0x00c6, 0x080c, 0x9f94, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xc1ca, + 0x6023, 0x0001, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, + 0x62f4, 0x0126, 0x2091, 0x8000, 0x70e0, 0x8000, 0x70e2, 0x012e, + 0x2009, 0x0002, 0x080c, 0xa068, 0x9085, 0x0001, 0x00ce, 0x00de, + 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, + 0x2009, 0x007f, 0x080c, 0x6343, 0x11b8, 0xb813, 0x00ff, 0xb817, + 0xfffd, 0xb8bf, 0x0004, 0x080c, 0x9f94, 0x0170, 0x2b00, 0x6012, + 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xc1ca, 0x2009, 0x0022, + 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, + 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, + 0x878d, 0x080c, 0x8717, 0x080c, 0x9e3d, 0x080c, 0xaf81, 0x3e08, + 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, + 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1140, 0x9686, 0x0002, + 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x5e49, 0x001e, 0x8108, + 0x1f04, 0x307a, 0x9686, 0x0001, 0x190c, 0x31bd, 0x00be, 0x002e, + 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, + 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, + 0x2019, 0x0029, 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c, + 0x8670, 0x2c08, 0x080c, 0xd556, 0x007e, 0x001e, 0xba10, 0xbb14, + 0xbcb0, 0x080c, 0x5e49, 0xba12, 0xbb16, 0xbcb2, 0x00be, 0x001e, + 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, + 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, + 0x2071, 0x1800, 0x70a4, 0x9005, 0x0110, 0x8001, 0x70a6, 0x000e, + 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e0, 0x9005, 0x0dc0, 0x8001, + 0x70e2, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, + 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, + 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0070, 0x080c, 0x54db, 0xd0c4, + 0x0138, 0x0030, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xd837, + 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x3144, + 0x928e, 0x007f, 0x0904, 0x3144, 0x928e, 0x0080, 0x05e8, 0x9288, + 0x1000, 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x1968, + 0x0006, 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, + 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6693, 0x00ce, 0x00be, + 0x2019, 0x0029, 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c, + 0x8670, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, + 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, + 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, + 0x080c, 0xd556, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x30fb, + 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x54db, 0xd0c4, + 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, + 0xd837, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x7290, 0x82ff, 0x01e8, 0x080c, 0x66c1, 0x11d0, 0x2100, + 0x080c, 0x26a0, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, + 0x1c80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, + 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, + 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, + 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029, + 0x00a9, 0x003e, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, + 0x00c6, 0x2061, 0x1a88, 0x001e, 0x6112, 0x080c, 0x3095, 0x001e, + 0x080c, 0x6367, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, + 0x2110, 0x080c, 0x9ad0, 0x080c, 0xdaf0, 0x002e, 0x001e, 0x0005, + 0x2001, 0x1836, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, + 0x717e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, + 0x717e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, + 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, + 0x6367, 0x8108, 0x1f04, 0x31ce, 0x2061, 0x1800, 0x607b, 0x0000, + 0x607c, 0x9084, 0x00ff, 0x607e, 0x60af, 0x0000, 0x00be, 0x00ce, + 0x0005, 0x2001, 0x187d, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x185c, + 0x2214, 0xd2ec, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, + 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, + 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, + 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, + 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, + 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, + 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, + 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, + 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, + 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, + 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, + 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, + 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, + 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, + 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, + 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, + 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, + 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, + 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, + 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, + 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, + 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, + 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, + 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, + 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, + 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, + 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x2071, 0x189c, 0x7003, 0x0002, 0x9006, + 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, + 0x18b8, 0x703f, 0x18b8, 0x7007, 0x0001, 0x080c, 0x1050, 0x090c, + 0x0df6, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, + 0x1050, 0x090c, 0x0df6, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, + 0xdcb0, 0x0005, 0x2071, 0x189c, 0x7004, 0x0002, 0x3322, 0x3323, + 0x3336, 0x334a, 0x0005, 0x1004, 0x3333, 0x0e04, 0x3333, 0x2079, + 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, + 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, + 0x2061, 0x18b6, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, + 0x0200, 0x0904, 0x341e, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, + 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, + 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, + 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, + 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61cc, 0x0042, + 0x2100, 0x908a, 0x003f, 0x1a04, 0x341b, 0x61cc, 0x0804, 0x33b0, + 0x33f2, 0x342a, 0x341b, 0x3436, 0x3440, 0x3446, 0x344a, 0x345a, + 0x345e, 0x3474, 0x347a, 0x3480, 0x348b, 0x3496, 0x34a5, 0x34b4, + 0x34c2, 0x34d9, 0x34f4, 0x341b, 0x359d, 0x35db, 0x3681, 0x3692, + 0x36b5, 0x341b, 0x341b, 0x341b, 0x36ed, 0x3709, 0x3712, 0x3741, + 0x3747, 0x341b, 0x378d, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, + 0x3798, 0x37a1, 0x37a9, 0x37ab, 0x341b, 0x341b, 0x341b, 0x341b, + 0x341b, 0x341b, 0x37d7, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, + 0x37f4, 0x3868, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, + 0x0002, 0x3892, 0x3895, 0x38f4, 0x390d, 0x393d, 0x3bdf, 0x341b, + 0x509e, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, + 0x341b, 0x3474, 0x347a, 0x416d, 0x54ff, 0x4183, 0x512d, 0x517f, + 0x528a, 0x341b, 0x52ec, 0x5328, 0x5359, 0x5461, 0x5386, 0x53e1, + 0x341b, 0x4187, 0x4336, 0x434c, 0x4371, 0x43d6, 0x444a, 0x446a, + 0x44e1, 0x453d, 0x4599, 0x459c, 0x45c1, 0x4636, 0x469c, 0x46a4, + 0x47d9, 0x4941, 0x4975, 0x4bbf, 0x341b, 0x4bdd, 0x4c9a, 0x4d77, + 0x341b, 0x341b, 0x341b, 0x341b, 0x4ddd, 0x4df8, 0x46a4, 0x503e, + 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x49f3, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x33fc, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, + 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, + 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11e6, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, + 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, + 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, + 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, + 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4a00, 0x2039, 0x0001, + 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4a03, + 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x33f2, 0x7984, 0x2114, + 0x0804, 0x33f2, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, + 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, + 0x0804, 0x33f2, 0x7884, 0x2060, 0x0804, 0x34a7, 0x2009, 0x0003, + 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0317, 0x7893, 0xffff, + 0x2001, 0x188d, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x33f2, + 0x7897, 0x0001, 0x0804, 0x33f2, 0x2039, 0x0001, 0x7d98, 0x7c9c, + 0x0804, 0x342e, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x343a, + 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x3427, 0x2138, 0x7d98, + 0x7c9c, 0x0804, 0x342e, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, + 0x3427, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x343a, 0x79a0, 0x9182, + 0x0040, 0x0210, 0x0804, 0x3427, 0x21e8, 0x7984, 0x7888, 0x20a9, + 0x0001, 0x21a0, 0x4004, 0x0804, 0x33f2, 0x2061, 0x0800, 0xe10c, + 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, + 0x0904, 0x33f2, 0x0804, 0x3421, 0x79a0, 0x9182, 0x0040, 0x0210, + 0x0804, 0x3427, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, + 0x0804, 0x33f2, 0x2069, 0x185b, 0x7884, 0x7990, 0x911a, 0x1a04, + 0x3427, 0x8019, 0x0904, 0x3427, 0x684a, 0x6942, 0x788c, 0x6852, + 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x74ab, 0x0804, + 0x33f2, 0x2069, 0x185b, 0x7884, 0x7994, 0x911a, 0x1a04, 0x3427, + 0x8019, 0x0904, 0x3427, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, + 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, + 0x67f9, 0x012e, 0x0804, 0x33f2, 0x902e, 0x2520, 0x81ff, 0x0120, + 0x2009, 0x0001, 0x0804, 0x3424, 0x7984, 0x7b88, 0x7a8c, 0x20a9, + 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a4, 0x4101, 0x080c, 0x49b7, + 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x2009, 0x0020, 0xa85c, + 0x9080, 0x0019, 0xaf60, 0x080c, 0x4a00, 0x701f, 0x3518, 0x0005, + 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, + 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, + 0x9096, 0x0029, 0x1904, 0x3424, 0x810f, 0x918c, 0x00ff, 0x0904, + 0x3424, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x49b7, + 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x2009, 0x0020, 0x7068, + 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, + 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, + 0xaf60, 0x080c, 0x4a00, 0x701f, 0x3556, 0x0005, 0xa864, 0x9084, + 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x3424, + 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, + 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x5f3b, + 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, + 0x080c, 0x6259, 0x1128, 0x7007, 0x0003, 0x701f, 0x3582, 0x0005, + 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, + 0x0001, 0x2099, 0x18a4, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, + 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, + 0x0020, 0x012e, 0xaf60, 0x0804, 0x4a03, 0x2091, 0x8000, 0x7837, + 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, + 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, + 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, + 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, + 0x19f6, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, + 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, + 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x3424, 0x7984, 0x080c, + 0x63a3, 0x1904, 0x3427, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x1a04, 0x3427, 0x7c88, 0x7d8c, 0x080c, 0x6506, 0x080c, 0x64d5, + 0x0000, 0x1518, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, + 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, + 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, + 0x1819, 0x2004, 0x9c02, 0x1a04, 0x3424, 0x0c30, 0x080c, 0xb983, + 0x012e, 0x0904, 0x3424, 0x0804, 0x33f2, 0x900e, 0x2001, 0x0005, + 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc04a, 0x080c, + 0x6a22, 0x012e, 0x0804, 0x33f2, 0x00a6, 0x2950, 0xb198, 0x080c, + 0x63a3, 0x1904, 0x366e, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x6506, 0x080c, 0x64d5, 0x1520, + 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, + 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, + 0x9506, 0x0158, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, + 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xb983, 0x012e, + 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, + 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc04a, 0x080c, 0x6a15, + 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, + 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, + 0x0005, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ce, 0x0904, 0x3427, + 0x080c, 0x646a, 0x0904, 0x3424, 0x080c, 0x650c, 0x0904, 0x3424, + 0x0804, 0x4461, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ea, 0x0904, + 0x3427, 0x080c, 0x659a, 0x0904, 0x3424, 0x2019, 0x0005, 0x79a8, + 0x080c, 0x6527, 0x0904, 0x3424, 0x7888, 0x908a, 0x1000, 0x1a04, + 0x3427, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8267, 0x79a8, + 0xd184, 0x1904, 0x33f2, 0x0804, 0x4461, 0x0126, 0x2091, 0x8000, + 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x6458, + 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x63a3, 0x11d8, 0x080c, + 0x659a, 0x1128, 0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0, 0x2019, + 0x0004, 0x900e, 0x080c, 0x6527, 0x1118, 0x2009, 0x0006, 0x0078, + 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, + 0x080c, 0x8267, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x33f2, 0x012e, + 0x0804, 0x3424, 0x012e, 0x0804, 0x3427, 0x080c, 0x49ce, 0x0904, + 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0xbaa0, 0x2019, 0x0005, + 0x00c6, 0x9066, 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, + 0x900e, 0x080c, 0xd556, 0x007e, 0x00ce, 0x080c, 0x6506, 0x0804, + 0x33f2, 0x080c, 0x49ce, 0x0904, 0x3427, 0x080c, 0x6506, 0x2208, + 0x0804, 0x33f2, 0x0156, 0x00d6, 0x00e6, 0x2069, 0x190e, 0x6810, + 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, + 0x007e, 0x2069, 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, + 0x9210, 0x8d68, 0x1f04, 0x3723, 0x2300, 0x9218, 0x00ee, 0x00de, + 0x015e, 0x0804, 0x33f2, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, + 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, + 0x0005, 0x2069, 0x190e, 0x6910, 0x62b8, 0x0804, 0x33f2, 0x81ff, + 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x0126, 0x2091, 0x8000, + 0x080c, 0x54ef, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x3424, + 0x012e, 0x6158, 0x9190, 0x31f3, 0x2215, 0x9294, 0x00ff, 0x6378, + 0x83ff, 0x0108, 0x627c, 0x67d8, 0x97c4, 0x000a, 0x98c6, 0x000a, + 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, + 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, + 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x717e, 0x1118, 0x2031, + 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x3424, + 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x33f2, 0x6148, 0x624c, 0x2019, + 0x1960, 0x231c, 0x2001, 0x1961, 0x2004, 0x789a, 0x0804, 0x33f2, + 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, + 0x33f2, 0x080c, 0x49ea, 0x0904, 0x3427, 0xba44, 0xbb38, 0x0804, + 0x33f2, 0x080c, 0x0df6, 0x080c, 0x49ea, 0x2110, 0x0904, 0x3427, + 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, + 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x3424, 0x0126, 0x2091, + 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x9ad0, 0x080c, + 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x900e, 0x080c, 0xd556, + 0x007e, 0x00ce, 0xb807, 0x0407, 0x012e, 0x0804, 0x33f2, 0x6148, + 0x624c, 0x7884, 0x604a, 0x7b88, 0x634e, 0x2069, 0x185b, 0x831f, + 0x9305, 0x6816, 0x788c, 0x2069, 0x1960, 0x2d1c, 0x206a, 0x7e98, + 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1961, 0x2d04, + 0x266a, 0x789a, 0x0804, 0x33f2, 0x0126, 0x2091, 0x8000, 0x6138, + 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0ee7, 0xd0c4, 0x01a8, + 0x00d6, 0x78a8, 0x2009, 0x1977, 0x200a, 0x78ac, 0x2011, 0x1978, + 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, + 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2001, 0x0100, 0x2004, + 0x9086, 0x000a, 0x0168, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, + 0x0118, 0x918d, 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x0060, + 0x2011, 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, + 0x0010, 0x918c, 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, + 0x910d, 0x788c, 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, + 0xd1e4, 0x190c, 0x0efd, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, + 0x0114, 0x2012, 0x012e, 0x0804, 0x33f2, 0x00f6, 0x2079, 0x1800, + 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, + 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, + 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, + 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x3427, 0x788c, + 0x902d, 0x0904, 0x3427, 0x900e, 0x080c, 0x63a3, 0x1120, 0xba44, + 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, + 0x080c, 0x49ea, 0x0904, 0x3427, 0x7888, 0x900d, 0x0904, 0x3427, + 0x788c, 0x9005, 0x0904, 0x3427, 0xba44, 0xb946, 0xbb38, 0xb83a, + 0x0804, 0x33f2, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, + 0x54ef, 0x1904, 0x3424, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, + 0x00ff, 0x1130, 0x2001, 0x1817, 0x2004, 0x9085, 0xff00, 0x0088, + 0x9182, 0x007f, 0x16e0, 0x9188, 0x31f3, 0x210d, 0x918c, 0x00ff, + 0x2001, 0x1817, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, + 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x9f94, 0x000e, + 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x6349, 0x2b08, + 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x49b7, 0x01d0, + 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, + 0x701f, 0x38ed, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xa068, + 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x3424, 0x00ce, + 0x0804, 0x3427, 0x080c, 0x9fea, 0x0cb0, 0xa830, 0x9086, 0x0100, + 0x0904, 0x3424, 0x0804, 0x33f2, 0x2061, 0x1a4c, 0x0126, 0x2091, + 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, + 0x6350, 0x6070, 0x789a, 0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e, + 0x0804, 0x33f2, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x3424, + 0x080c, 0x717e, 0x0904, 0x3424, 0x0126, 0x2091, 0x8000, 0x6250, + 0x6070, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x26d6, 0x080c, + 0x5712, 0x012e, 0x0804, 0x33f2, 0x012e, 0x0804, 0x3427, 0x0006, + 0x0016, 0x00c6, 0x00e6, 0x2001, 0x1984, 0x2070, 0x2061, 0x185b, + 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x847e, 0x7206, + 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, + 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x33f4, 0x7884, + 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, + 0x00e1, 0x0298, 0x012e, 0x0804, 0x3427, 0x2001, 0x002a, 0x2004, + 0x9005, 0x0128, 0x2069, 0x185b, 0x6908, 0x9102, 0x1230, 0x012e, + 0x0804, 0x3427, 0x012e, 0x0804, 0x3424, 0x080c, 0x9f69, 0x0dd0, + 0x7884, 0xd0fc, 0x0904, 0x39bc, 0x00c6, 0x080c, 0x49b7, 0x00ce, + 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, + 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, + 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, + 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, + 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, + 0x8004, 0xa816, 0x080c, 0x3b42, 0x0928, 0x7014, 0x2048, 0xad2c, + 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, + 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4a00, 0x701f, 0x3a7f, + 0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3927, 0x2001, + 0x197a, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, + 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, + 0x3bb1, 0x080c, 0x3b70, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, + 0x1a42, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, + 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, + 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x3fb1, 0x008e, 0x00ee, + 0x00fe, 0x080c, 0x3ed3, 0x080c, 0x3d98, 0x05b8, 0x2001, 0x020b, + 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x4025, 0x00f6, 0x2079, + 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, + 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, + 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, + 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, + 0x2001, 0x181f, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, + 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3da2, 0x080c, + 0x3b6b, 0x0058, 0x080c, 0x3b6b, 0x080c, 0x3f49, 0x080c, 0x3ec9, + 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, + 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, + 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, + 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, + 0x12fe, 0x2009, 0x0028, 0x080c, 0x2200, 0x2001, 0x0227, 0x200c, + 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, + 0x008e, 0x004e, 0x2001, 0x197a, 0x2004, 0x9005, 0x1118, 0x012e, + 0x0804, 0x33f2, 0x012e, 0x2021, 0x400c, 0x0804, 0x33f4, 0x0016, + 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, + 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, + 0x9005, 0x0904, 0x3adb, 0x2048, 0x1f04, 0x3a8f, 0x7068, 0x2040, + 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, + 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, + 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4a00, 0x701f, + 0x3a7f, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, + 0x0006, 0x080c, 0x0fb4, 0x000e, 0x080c, 0x4a03, 0x701f, 0x3a7f, + 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, + 0x1118, 0x701f, 0x3b40, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, + 0xa86a, 0x2009, 0x007f, 0x080c, 0x6343, 0x0110, 0x9006, 0x0030, + 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xc21d, 0x015e, 0x00de, + 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, + 0x0904, 0x3424, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, + 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3b12, 0x7007, 0x0003, + 0x0804, 0x3ad0, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, + 0x33f4, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, + 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, + 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fb4, 0x000e, + 0x080c, 0x4a03, 0x007e, 0x701f, 0x3a7f, 0x7023, 0x0001, 0x0005, + 0x0804, 0x33f2, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, + 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, + 0x080c, 0x49b7, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, + 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, + 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, + 0x00fe, 0x000e, 0x0005, 0x2001, 0x197a, 0x2003, 0x0001, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x1985, 0x2004, + 0x601a, 0x2061, 0x0100, 0x2001, 0x1984, 0x2004, 0x60ce, 0x6104, + 0xc1ac, 0x6106, 0x080c, 0x49b7, 0xa813, 0x0019, 0xa817, 0x0001, + 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, + 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1984, + 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2200, 0x2001, 0x002a, + 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, + 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x00e6, 0x080c, 0x49b7, 0x2940, 0xa013, 0x0019, 0xa017, + 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, + 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, + 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, + 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2a8f, 0x1130, 0x9006, + 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x2001, 0x1979, 0x2003, + 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3c00, 0x3c0f, 0x3c1e, + 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x012e, 0x0804, 0x3427, + 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0db8, 0x2009, 0x0114, + 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3dec, 0x00f0, 0x2001, + 0x0100, 0x2004, 0x9086, 0x000a, 0x0d40, 0x2009, 0x0114, 0x2104, + 0x9085, 0x4000, 0x200a, 0x080c, 0x3dec, 0x0078, 0x080c, 0x717e, + 0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x3424, 0x81ff, 0x0128, + 0x012e, 0x2021, 0x400b, 0x0804, 0x33f4, 0x2001, 0x0141, 0x2004, + 0xd0dc, 0x0db0, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, + 0x00e6, 0x00f6, 0x080c, 0x3927, 0x2009, 0x0101, 0x210c, 0x0016, + 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x4100, + 0x080c, 0x4050, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, + 0x2071, 0x1a42, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, + 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, + 0x0001, 0x080c, 0x3fb1, 0x080c, 0x2a97, 0x080c, 0x2a97, 0x080c, + 0x2a97, 0x080c, 0x2a97, 0x080c, 0x3fb1, 0x008e, 0x00ee, 0x00fe, + 0x080c, 0x3ed3, 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3da2, + 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, + 0x0017, 0x080c, 0x3424, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, + 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, + 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x3eb1, + 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c, 0x3da2, 0x0804, 0x3d42, + 0x080c, 0x4025, 0x080c, 0x3f49, 0x080c, 0x3e94, 0x080c, 0x3ec9, + 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, + 0x3da2, 0x00fe, 0x0804, 0x3d42, 0x00fe, 0x080c, 0x3d98, 0x1150, + 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, + 0x3da2, 0x0080, 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, + 0x1908, 0x8739, 0x0038, 0x2001, 0x1a3f, 0x2004, 0x9086, 0x0000, + 0x1904, 0x3c92, 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, + 0x8529, 0x2500, 0x9605, 0x0904, 0x3d42, 0x7884, 0xd0bc, 0x0128, + 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3d42, 0xa013, 0x0019, 0x2001, + 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a3f, + 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, + 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, + 0x0040, 0x080c, 0x2200, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, + 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, + 0x0090, 0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3d19, + 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, + 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, + 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, + 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, + 0x0804, 0x3c4c, 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, + 0x2061, 0x0100, 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, + 0x0020, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, + 0x12fe, 0x7884, 0x9084, 0x0003, 0x9086, 0x0002, 0x0508, 0x2009, + 0x0028, 0x080c, 0x2200, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, + 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0118, + 0x9084, 0xb7ef, 0x0020, 0x9084, 0xb7ff, 0x080c, 0x2bdc, 0x6052, + 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, + 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, + 0x012e, 0x0804, 0x33f2, 0x012e, 0x2021, 0x400c, 0x0804, 0x33f4, + 0x9085, 0x0001, 0x1d04, 0x3da1, 0x2091, 0x6000, 0x8420, 0x9486, + 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, + 0x2003, 0x0004, 0x2001, 0x1a3f, 0x2003, 0x0000, 0x0071, 0x2009, + 0x0048, 0x080c, 0x2200, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, + 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, + 0x1a42, 0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, + 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, + 0x0040, 0x080c, 0x2200, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4025, + 0x7000, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, + 0x1de8, 0x2009, 0x0040, 0x080c, 0x2200, 0x782b, 0x0002, 0x7003, + 0x0000, 0x00ee, 0x00fe, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x15d0, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c, + 0x7932, 0x7936, 0x080c, 0x26b6, 0x080c, 0x2ba9, 0x080c, 0x2bdc, + 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, + 0x7852, 0x2019, 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, + 0x7850, 0xc0e4, 0x7852, 0x7827, 0x0048, 0x7843, 0x0040, 0x2019, + 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b6f, + 0x7827, 0x0048, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, + 0x1817, 0x200c, 0x7932, 0x7936, 0x080c, 0x26b6, 0x7850, 0x9084, + 0xfbff, 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, + 0x9084, 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, + 0x3e47, 0x2091, 0x6000, 0x1f04, 0x3e47, 0x7850, 0x9085, 0x0400, + 0x9084, 0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, + 0x9086, 0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, + 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, + 0x1f04, 0x3e67, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, + 0x7854, 0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, + 0x0048, 0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, + 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b6f, + 0x7827, 0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, + 0x00e6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, + 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, + 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, + 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, + 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, + 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, + 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x1985, + 0x2004, 0x70e2, 0x080c, 0x3b61, 0x1188, 0x2001, 0x181f, 0x2004, + 0x2009, 0x181e, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, + 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, + 0x0002, 0x702e, 0x2009, 0x1817, 0x210c, 0x716e, 0x7063, 0x0100, + 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, + 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, + 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, + 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, + 0x080c, 0x4025, 0x00f6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x00d6, + 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, + 0x780a, 0x00de, 0x080c, 0x3b61, 0x0140, 0x2001, 0x1979, 0x200c, + 0x2003, 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, 0x8109, + 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, + 0x080c, 0x3fb1, 0x2011, 0x0001, 0x080c, 0x3fb1, 0x00fe, 0x00ee, + 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x792c, + 0xd1fc, 0x0904, 0x3fae, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, + 0x3faa, 0x7000, 0x0002, 0x3fae, 0x3f5f, 0x3f8f, 0x3faa, 0xd1bc, + 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, + 0x3fb1, 0x0904, 0x3fae, 0x080c, 0x3fb1, 0x0804, 0x3fae, 0x00f6, + 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, + 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, + 0x080c, 0x3eb1, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, + 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, + 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x3f53, + 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, + 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, + 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, + 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, + 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, + 0x938a, 0x0007, 0x1a0c, 0x0df6, 0x9398, 0x3fdf, 0x231d, 0x083f, + 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, + 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, + 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x401c, + 0x4013, 0x400a, 0x4001, 0x3ff8, 0x3fef, 0x3fe6, 0xa964, 0x7902, + 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, + 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, + 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, + 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, + 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, + 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, + 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, + 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, + 0x2071, 0x1a42, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, + 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, 0x404c, 0x4038, 0x4043, + 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x3fb1, + 0x190c, 0x3fb1, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, 0x1d38, + 0x2011, 0x0001, 0x080c, 0x3fb1, 0x008e, 0x00ee, 0x00fe, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x1985, + 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x1984, 0x2004, 0x60ce, + 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, + 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, + 0x49b7, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, + 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, + 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x40c8, + 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x49b7, 0xa813, 0x0019, + 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, + 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, + 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, + 0x2079, 0x0100, 0x2001, 0x1984, 0x2004, 0x6036, 0x2009, 0x0040, + 0x080c, 0x2200, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, + 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, + 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, + 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, + 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, + 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, + 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, + 0x080c, 0x49b7, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, + 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, + 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, + 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x49b7, 0x2940, + 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, + 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, + 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x40c8, 0x1d68, + 0x2900, 0xa85a, 0x00d8, 0x080c, 0x49b7, 0x2940, 0xa013, 0x0019, + 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, + 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, + 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, + 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, + 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a3f, 0x2003, + 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, + 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, + 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, + 0x20a9, 0x001b, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, + 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, + 0x0005, 0x0804, 0x33f2, 0x7d98, 0x7c9c, 0x0804, 0x34f6, 0x080c, + 0x717e, 0x190c, 0x5df4, 0x2069, 0x185b, 0x2d00, 0x2009, 0x0030, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a00, + 0x701f, 0x419b, 0x0005, 0x080c, 0x54ea, 0x1130, 0x3b00, 0x3a08, + 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, 0x185b, 0x6800, 0x9005, + 0x0904, 0x3427, 0x6804, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, + 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010, + 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, + 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106, + 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x3427, + 0x9288, 0x31f3, 0x210d, 0x918c, 0x00ff, 0x6162, 0xd0dc, 0x0130, + 0x6828, 0x908a, 0x007f, 0x1a04, 0x3427, 0x605a, 0x6888, 0x9084, + 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x198c, + 0x9080, 0x27a9, 0x2005, 0x200a, 0x000e, 0x2009, 0x198d, 0x9080, + 0x27ad, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x3427, + 0x908a, 0x0841, 0x1a04, 0x3427, 0x9084, 0x0007, 0x1904, 0x3427, + 0x680c, 0x9005, 0x0904, 0x3427, 0x6810, 0x9005, 0x0904, 0x3427, + 0x6848, 0x6940, 0x910a, 0x1a04, 0x3427, 0x8001, 0x0904, 0x3427, + 0x684c, 0x6944, 0x910a, 0x1a04, 0x3427, 0x8001, 0x0904, 0x3427, + 0x2009, 0x195b, 0x200b, 0x0000, 0x2001, 0x187d, 0x2004, 0xd0c4, + 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, 0x0e7b, 0x3b00, 0xc085, + 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614a, 0x8007, 0x9084, 0x00ff, + 0x604e, 0x080c, 0x74ab, 0x080c, 0x6796, 0x080c, 0x67f9, 0x6808, + 0x602a, 0x080c, 0x2172, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, + 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2710, 0x003e, + 0x6000, 0x9086, 0x0000, 0x1904, 0x4326, 0x6818, 0x691c, 0x6a20, + 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, + 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, + 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006, + 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9, + 0x0004, 0x20a1, 0x198e, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004, + 0x20a1, 0x19a8, 0x20e9, 0x0001, 0x4001, 0x080c, 0x8362, 0x00c6, + 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, + 0x12b0, 0x3508, 0x8109, 0x080c, 0x7a77, 0x6878, 0x6016, 0x6874, + 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, + 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, + 0x4287, 0x00ce, 0x00c6, 0x2061, 0x1976, 0x2063, 0x0001, 0x9006, + 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x0000, 0x00ce, 0x00e6, + 0x2c70, 0x080c, 0x0ecc, 0x00ee, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x1120, 0x080c, 0x2ba9, 0x080c, 0x2bdc, 0x6888, 0xd0ec, + 0x0198, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0138, 0x2011, + 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x0030, 0x2011, 0x0114, + 0x2204, 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, + 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, + 0x1956, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, + 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, + 0x2785, 0x2001, 0x1947, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, + 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x717e, + 0x0128, 0x080c, 0x4dd1, 0x0110, 0x080c, 0x26d6, 0x60d0, 0x9005, + 0x01c0, 0x6003, 0x0001, 0x2009, 0x430e, 0x00d0, 0x080c, 0x717e, + 0x1168, 0x2011, 0x6fed, 0x080c, 0x8259, 0x2011, 0x6fe0, 0x080c, + 0x832d, 0x080c, 0x747f, 0x080c, 0x709e, 0x0040, 0x080c, 0x5cee, + 0x0028, 0x6003, 0x0004, 0x2009, 0x4326, 0x0010, 0x0804, 0x33f2, + 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, + 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000, 0x9086, + 0x0000, 0x0904, 0x3424, 0x2069, 0x185b, 0x7890, 0x6842, 0x7894, + 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x2039, 0x0001, 0x0804, 0x4a03, 0x9006, 0x080c, 0x26d6, 0x81ff, + 0x1904, 0x3424, 0x080c, 0x717e, 0x11b0, 0x080c, 0x747a, 0x080c, + 0x5e2f, 0x080c, 0x31ee, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, + 0xc459, 0x0130, 0x080c, 0x71a1, 0x1118, 0x080c, 0x7156, 0x0038, + 0x080c, 0x709e, 0x0020, 0x080c, 0x5df4, 0x080c, 0x5cee, 0x0804, + 0x33f2, 0x81ff, 0x1904, 0x3424, 0x080c, 0x717e, 0x1110, 0x0804, + 0x3424, 0x0126, 0x2091, 0x8000, 0x6190, 0x81ff, 0x0190, 0x704f, + 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a03, 0x701f, 0x33f0, 0x012e, + 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9, 0x0040, + 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304, 0x6558, + 0x9588, 0x31f3, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, + 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x63a3, 0x1190, 0xb814, + 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007, 0x201a, + 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, + 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, + 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1c80, + 0x2099, 0x1c80, 0x080c, 0x5d7f, 0x0804, 0x4381, 0x080c, 0x49ea, + 0x0904, 0x3427, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, + 0x3424, 0x080c, 0x54db, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, + 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, + 0x31e9, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0x080c, 0xbf19, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, + 0x0003, 0x701f, 0x440c, 0x0005, 0x080c, 0x49ea, 0x0904, 0x3427, + 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, + 0x0006, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, + 0x080c, 0x0fb4, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, + 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, + 0x0fb4, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0x0804, 0x4a03, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ce, 0x0904, + 0x3427, 0x080c, 0x6515, 0x0904, 0x3424, 0x0058, 0xa878, 0x9005, + 0x0120, 0x2009, 0x0004, 0x0804, 0x3424, 0xa974, 0xaa94, 0x0804, + 0x33f2, 0x080c, 0x54e3, 0x0904, 0x33f2, 0x701f, 0x4456, 0x7007, + 0x0003, 0x0005, 0x81ff, 0x1904, 0x3424, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x3427, 0x080c, 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9, + 0x0120, 0x080c, 0x66d1, 0x1904, 0x3427, 0x080c, 0x659a, 0x0904, + 0x3424, 0x2019, 0x0004, 0x900e, 0x080c, 0x6527, 0x0904, 0x3424, + 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, + 0x080c, 0x49e8, 0x01e0, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, + 0x11b0, 0x080c, 0x659a, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, + 0x2019, 0x0004, 0x080c, 0x6527, 0x2009, 0x0003, 0x0120, 0xa998, + 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, + 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x6458, 0x2400, 0x9506, + 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x63a3, + 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8267, + 0x0005, 0x81ff, 0x1904, 0x3424, 0x798c, 0x2001, 0x195a, 0x918c, + 0x8000, 0x2102, 0x080c, 0x49ce, 0x0904, 0x3427, 0x080c, 0x66c9, + 0x0120, 0x080c, 0x66d1, 0x1904, 0x3427, 0x080c, 0x646a, 0x0904, + 0x3424, 0x080c, 0x651e, 0x0904, 0x3424, 0x2001, 0x195a, 0x2004, + 0xd0fc, 0x1904, 0x33f2, 0x0804, 0x4461, 0xa9a0, 0x2001, 0x195a, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49db, 0x01a0, 0x080c, + 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1170, 0x080c, 0x646a, 0x2009, + 0x0002, 0x0128, 0x080c, 0x651e, 0x1170, 0x2009, 0x0003, 0xa897, + 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x195a, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x3424, + 0x798c, 0x2001, 0x1959, 0x918c, 0x8000, 0x2102, 0x080c, 0x49ce, + 0x0904, 0x3427, 0x080c, 0x66c9, 0x0120, 0x080c, 0x66d1, 0x1904, + 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0x080c, 0x650c, 0x0904, + 0x3424, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1904, 0x33f2, 0x0804, + 0x4461, 0xa9a0, 0x2001, 0x1959, 0x918c, 0x8000, 0xc18d, 0x2102, + 0x080c, 0x49db, 0x01a0, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, + 0x1170, 0x080c, 0x646a, 0x2009, 0x0002, 0x0128, 0x080c, 0x650c, + 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, + 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, + 0x4000, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e3, + 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x0005, 0x6100, 0x0804, 0x33f2, 0x080c, 0x49ea, 0x0904, 0x3427, + 0x080c, 0x54ef, 0x1904, 0x3424, 0x79a8, 0xd184, 0x1158, 0xb834, + 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, + 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, + 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, + 0x33f2, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, + 0x939a, 0x0003, 0x1a04, 0x3424, 0x6258, 0x7884, 0x9206, 0x1560, + 0x2031, 0x1848, 0x2009, 0x013c, 0x2136, 0x2001, 0x1840, 0x2009, + 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0006, + 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, 0x0804, 0x4a03, 0x000e, + 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a, 0xa772, + 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1134, 0x7007, + 0x0002, 0x701f, 0x461c, 0x0005, 0x81ff, 0x1904, 0x3424, 0x080c, + 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9, 0x1904, 0x3424, 0x00c6, + 0x080c, 0x49b7, 0x00ce, 0x0904, 0x3424, 0xa867, 0x0000, 0xa868, + 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xbebf, 0x0904, 0x3424, 0x7007, + 0x0003, 0x701f, 0x4620, 0x0005, 0x080c, 0x416d, 0x0804, 0x33f2, + 0xa830, 0x9086, 0x0100, 0x0904, 0x3424, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a03, 0x9006, 0x080c, + 0x26d6, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, + 0x1904, 0x3424, 0x080c, 0x717e, 0x0110, 0x080c, 0x5df4, 0x7888, + 0x908a, 0x1000, 0x1a04, 0x3427, 0x7984, 0x9186, 0x00ff, 0x0138, + 0x9182, 0x007f, 0x1a04, 0x3427, 0x2100, 0x080c, 0x26a0, 0x0026, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19d5, 0x601b, 0x0000, + 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x080c, 0x717e, + 0x1158, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085, 0x0001, 0x080c, + 0x71c2, 0x080c, 0x709e, 0x00d0, 0x080c, 0x9f70, 0x2061, 0x0100, + 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, + 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000, + 0x2009, 0x002d, 0x2011, 0x5d1a, 0x080c, 0x82eb, 0x7984, 0x080c, + 0x717e, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x44c4, 0x012e, + 0x00ce, 0x002e, 0x0804, 0x33f2, 0x7984, 0x080c, 0x6343, 0x2b08, + 0x1904, 0x3427, 0x0804, 0x33f2, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x3424, 0x60d8, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, + 0x0005, 0x0804, 0x3424, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, + 0x0804, 0x3424, 0x7984, 0x81ff, 0x0904, 0x3427, 0x9192, 0x0021, + 0x1a04, 0x3427, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, + 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4a00, 0x701f, 0x46d7, + 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x4f83, 0x0005, 0x2009, + 0x0080, 0x080c, 0x63a3, 0x1118, 0x080c, 0x66c9, 0x0120, 0x2021, + 0x400a, 0x0804, 0x33f4, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, + 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4770, + 0x90be, 0x0112, 0x0904, 0x4770, 0x90be, 0x0113, 0x0904, 0x4770, + 0x90be, 0x0114, 0x0904, 0x4770, 0x90be, 0x0117, 0x0904, 0x4770, + 0x90be, 0x011a, 0x0904, 0x4770, 0x90be, 0x011c, 0x0904, 0x4770, + 0x90be, 0x0121, 0x0904, 0x4757, 0x90be, 0x0131, 0x0904, 0x4757, + 0x90be, 0x0171, 0x0904, 0x4770, 0x90be, 0x0173, 0x0904, 0x4770, + 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x477b, + 0x90be, 0x0212, 0x0904, 0x4764, 0x90be, 0x0213, 0x05e8, 0x90be, + 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, 0x1120, + 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be, + 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x3427, 0x7028, 0x9080, + 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, + 0x080c, 0x47b9, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, + 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47b9, 0x00c8, 0x7028, + 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, + 0x0001, 0x080c, 0x47c6, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, + 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47c6, + 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, + 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x49b7, 0x0550, 0xa868, + 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020, + 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe, + 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822, + 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xbeda, 0x1120, + 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x47b0, + 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x3424, + 0xa820, 0x9086, 0x8001, 0x1904, 0x33f2, 0x2009, 0x0004, 0x0804, + 0x3424, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104, + 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, + 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204, + 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e, + 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x60d8, + 0xd0ac, 0x1160, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, 0x3424, + 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x3424, 0x7984, 0x78a8, + 0x2040, 0x080c, 0x9f69, 0x1120, 0x9182, 0x007f, 0x0a04, 0x3427, + 0x9186, 0x00ff, 0x0904, 0x3427, 0x9182, 0x0800, 0x1a04, 0x3427, + 0x7a8c, 0x7b88, 0x6078, 0x9306, 0x1158, 0x607c, 0x924e, 0x0904, + 0x3427, 0x080c, 0x9f69, 0x1120, 0x99cc, 0xff00, 0x0904, 0x3427, + 0x0126, 0x2091, 0x8000, 0x9386, 0x00ff, 0x0178, 0x0026, 0x2011, + 0x8008, 0x080c, 0x66ed, 0x002e, 0x0140, 0x918d, 0x8000, 0x080c, + 0x6737, 0x1118, 0x2001, 0x4009, 0x0458, 0x080c, 0x48d1, 0x0560, + 0x90c6, 0x4000, 0x1170, 0x00c6, 0x0006, 0x900e, 0x080c, 0x65c3, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, + 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, + 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, + 0x2020, 0x012e, 0x0804, 0x33f4, 0x2b00, 0x7026, 0x0016, 0x00b6, + 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xa03b, 0x0904, 0x489e, 0x2b00, + 0x6012, 0x080c, 0xc1ca, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, + 0x49b7, 0x00ce, 0x2b70, 0x1158, 0x080c, 0x9fea, 0x00ee, 0x00ce, + 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x3424, 0x900e, + 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, + 0x0108, 0xc0f5, 0xa86a, 0x080c, 0x3095, 0x6023, 0x0001, 0x9006, + 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x2009, 0x0002, + 0x080c, 0xa068, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, + 0x2058, 0xb8bc, 0xc08d, 0xb8be, 0x9085, 0x0001, 0x00ee, 0x00ce, + 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, + 0x7007, 0x0003, 0x701f, 0x48ad, 0x0005, 0xa830, 0x2008, 0x918e, + 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x33f4, 0x9086, 0x0100, + 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, + 0x0804, 0x542f, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x33f2, 0x080c, + 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, + 0x33f2, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4919, 0x902e, + 0x080c, 0x9f69, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, + 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04, + 0x9005, 0x11b0, 0x2100, 0x9406, 0x15e8, 0x2428, 0x94ce, 0x007f, + 0x1120, 0x92ce, 0xfffd, 0x1528, 0x0030, 0x94ce, 0x0080, 0x1130, + 0x92ce, 0xfffc, 0x11f0, 0x93ce, 0x00ff, 0x11d8, 0xc5fd, 0x0450, + 0x2058, 0xbf10, 0x2700, 0x9306, 0x11b8, 0xbe14, 0x2600, 0x9206, + 0x1198, 0x2400, 0x9106, 0x1150, 0xd884, 0x0568, 0xd894, 0x1558, + 0x080c, 0x66c9, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007, + 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, + 0x87ff, 0x1128, 0x86ff, 0x0948, 0x080c, 0x9f69, 0x1930, 0x2001, + 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x48e7, 0x85ff, 0x1130, + 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x6343, + 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, + 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x080c, + 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0xa867, 0x0000, + 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x3427, 0x9096, + 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x3427, 0x2010, 0x2918, + 0x080c, 0x303b, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, + 0x0003, 0x701f, 0x496c, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904, + 0x33f2, 0x2009, 0x0004, 0x0804, 0x3424, 0x7984, 0x080c, 0x9f69, + 0x1120, 0x9182, 0x007f, 0x0a04, 0x3427, 0x9186, 0x00ff, 0x0904, + 0x3427, 0x9182, 0x0800, 0x1a04, 0x3427, 0x2001, 0x9400, 0x080c, + 0x548a, 0x1904, 0x3424, 0x0804, 0x33f2, 0xa998, 0x080c, 0x9f69, + 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, + 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x548a, 0x11a8, 0x0060, + 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c, + 0x1037, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900, + 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900, + 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c, + 0x63a3, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, + 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x63a3, 0x1130, 0xae9c, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, + 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x63a3, 0x1108, 0x0008, + 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148, + 0xa904, 0x080c, 0x1069, 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005, + 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, + 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, + 0x080c, 0x1134, 0x7007, 0x0002, 0x701f, 0x33f2, 0x0005, 0x00f6, + 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18ae, 0x2004, + 0x9005, 0x1190, 0x0e04, 0x4a34, 0x7a36, 0x7833, 0x0012, 0x7a82, + 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11e6, 0x0804, 0x4a9a, 0x0016, 0x0086, 0x0096, 0x00c6, + 0x00e6, 0x2071, 0x189c, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182, + 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1037, 0x0904, 0x4a92, + 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ebe, + 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, 0x18b8, + 0x9c82, 0x18f8, 0x0210, 0x2061, 0x18b8, 0x2c00, 0x703a, 0x7148, + 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, 0x8108, + 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, 0x0036, + 0x1a0c, 0x0df6, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa146, + 0x1520, 0x080c, 0x1037, 0x1130, 0x8109, 0xa946, 0x7148, 0x8109, + 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802, + 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ebe, 0x2005, + 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, + 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, + 0x0002, 0x4abc, 0x4abc, 0x4abe, 0x4abc, 0x4abc, 0x4abc, 0x4ac2, + 0x4abc, 0x4abc, 0x4abc, 0x4ac6, 0x4abc, 0x4abc, 0x4abc, 0x4aca, + 0x4abc, 0x4abc, 0x4abc, 0x4ace, 0x4abc, 0x4abc, 0x4abc, 0x4ad2, + 0x4abc, 0x4abc, 0x4abc, 0x4ad7, 0x080c, 0x0df6, 0xa276, 0xa37a, + 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a, + 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, + 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4a95, 0xa2d6, + 0xa3da, 0xa4de, 0x0804, 0x4a95, 0x00e6, 0x2071, 0x189c, 0x7048, + 0x9005, 0x0904, 0x4b6e, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4b6d, + 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006, + 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, 0x0016, + 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x2060, 0x001e, 0x8108, 0x2105, + 0x9005, 0xa94a, 0x1904, 0x4b70, 0xa804, 0x9005, 0x090c, 0x0df6, + 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080, + 0x1ebe, 0x2005, 0xa04a, 0x0804, 0x4b70, 0x703c, 0x2060, 0x2c14, + 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, 0x7882, + 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11e6, 0x87ff, 0x0118, 0x2748, 0x080c, + 0x1069, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, 0x2048, + 0x9005, 0x0128, 0x080c, 0x1069, 0x9006, 0x7042, 0x7046, 0x703b, + 0x18b8, 0x703f, 0x18b8, 0x0420, 0x7040, 0x9005, 0x1508, 0x7238, + 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18f8, 0x0210, + 0x2001, 0x18b8, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044, + 0x9005, 0x090c, 0x0df6, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, + 0x7042, 0x2001, 0x0002, 0x9080, 0x1ebe, 0x2005, 0xa84a, 0x0000, + 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, + 0x2c00, 0x9082, 0x001b, 0x0002, 0x4b8f, 0x4b8f, 0x4b91, 0x4b8f, + 0x4b8f, 0x4b8f, 0x4b96, 0x4b8f, 0x4b8f, 0x4b8f, 0x4b9b, 0x4b8f, + 0x4b8f, 0x4b8f, 0x4ba0, 0x4b8f, 0x4b8f, 0x4b8f, 0x4ba5, 0x4b8f, + 0x4b8f, 0x4b8f, 0x4baa, 0x4b8f, 0x4b8f, 0x4b8f, 0x4baf, 0x080c, + 0x0df6, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4b1b, 0xaa84, 0xab88, + 0xac8c, 0x0804, 0x4b1b, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4b1b, + 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4b1b, 0xaab4, 0xabb8, 0xacbc, + 0x0804, 0x4b1b, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4b1b, 0xaad4, + 0xabd8, 0xacdc, 0x0804, 0x4b1b, 0x0026, 0x080c, 0x54db, 0xd0c4, + 0x0120, 0x2011, 0x8014, 0x080c, 0x4a17, 0x002e, 0x0005, 0x81ff, + 0x1904, 0x3424, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, + 0xc0ac, 0x6032, 0x080c, 0x717e, 0x1158, 0x080c, 0x747a, 0x080c, + 0x5e2f, 0x9085, 0x0001, 0x080c, 0x71c2, 0x080c, 0x709e, 0x0010, + 0x080c, 0x5cee, 0x012e, 0x0804, 0x33f2, 0x81ff, 0x0120, 0x2009, + 0x0001, 0x0804, 0x3424, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, + 0x0804, 0x3424, 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804, + 0x3424, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e, 0x0140, + 0x7984, 0x080c, 0x6737, 0x1120, 0x2009, 0x4009, 0x0804, 0x3424, + 0x7984, 0x080c, 0x6343, 0x1904, 0x3427, 0x080c, 0x49ea, 0x0904, + 0x3427, 0x2b00, 0x7026, 0x080c, 0x66c9, 0x7888, 0x1170, 0x9084, + 0x0005, 0x1158, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x33f2, 0x080c, 0x49b7, 0x0904, + 0x3424, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, + 0xbf78, 0x0904, 0x3424, 0x7888, 0xd094, 0x0118, 0xb8bc, 0xc08d, + 0xb8be, 0x7007, 0x0003, 0x701f, 0x4c7f, 0x0005, 0x2061, 0x1800, + 0x080c, 0x54ef, 0x2009, 0x0007, 0x1560, 0x080c, 0x66c1, 0x0118, + 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x6343, 0x1530, 0x080c, + 0x49e8, 0x0518, 0x080c, 0x66c9, 0xa89c, 0x1168, 0x9084, 0x0005, + 0x1150, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xbf78, + 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x2009, + 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, + 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, + 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x33f4, + 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x542f, 0x900e, + 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, + 0x0804, 0x33f2, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, + 0x3424, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x49b7, + 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x900e, 0x2130, 0x7126, + 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, + 0x20a0, 0x080c, 0x63a3, 0x1904, 0x4d24, 0x080c, 0x66c9, 0x0120, + 0x080c, 0x66d1, 0x1904, 0x4d24, 0x080c, 0x66c1, 0x1130, 0x080c, + 0x65c3, 0x1118, 0xd79c, 0x0904, 0x4d24, 0xd794, 0x1110, 0xd784, + 0x01a8, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x3400, + 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, + 0x20e0, 0x20a9, 0x0002, 0x080c, 0x47c6, 0x0080, 0xb8b4, 0x20e0, + 0xb8b8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, + 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47c6, 0x4104, 0xd794, + 0x0528, 0xb8b4, 0x20e0, 0xb8b8, 0x2060, 0x9c80, 0x0000, 0x2098, + 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, + 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, + 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47b9, 0x9c80, 0x0026, + 0x2098, 0xb8b4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, + 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0x9f69, 0x0118, + 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, + 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, + 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4cb9, 0x86ff, 0x1120, + 0x7124, 0x810b, 0x0804, 0x33f2, 0x7033, 0x0001, 0x7122, 0x7024, + 0x9600, 0x7026, 0x772e, 0x2061, 0x18b6, 0x2c44, 0xa06b, 0x0000, + 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, + 0xa59a, 0x080c, 0x1134, 0x7007, 0x0002, 0x701f, 0x4d60, 0x0005, + 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, + 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390, 0xa494, + 0xa598, 0x0804, 0x4cb9, 0x7124, 0x810b, 0x0804, 0x33f2, 0x2029, + 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, + 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9184, + 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, + 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, + 0x0a04, 0x3427, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427, + 0x9502, 0x0a04, 0x3427, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, + 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9384, 0x00ff, 0x90e2, + 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9484, 0xff00, + 0x8007, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, + 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, + 0x3427, 0x2061, 0x1963, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, + 0x33f2, 0x0006, 0x080c, 0x54db, 0xd0cc, 0x000e, 0x0005, 0x0006, + 0x080c, 0x54df, 0xd0bc, 0x000e, 0x0005, 0x6170, 0x7a84, 0x6300, + 0x82ff, 0x1118, 0x7986, 0x0804, 0x33f2, 0x83ff, 0x1904, 0x3427, + 0x2001, 0xfff0, 0x9200, 0x1a04, 0x3427, 0x2019, 0xffff, 0x6074, + 0x9302, 0x9200, 0x0a04, 0x3427, 0x7986, 0x6272, 0x0804, 0x33f2, + 0x080c, 0x54ef, 0x1904, 0x3424, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, + 0x080c, 0x49b7, 0x0904, 0x3424, 0x900e, 0x901e, 0x7326, 0x7332, + 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, + 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118, + 0x080c, 0x66d1, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, + 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, + 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, + 0x2001, 0x0003, 0x080c, 0x847e, 0x2208, 0x0804, 0x33f2, 0x7033, + 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b6, 0x2c44, + 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, + 0xa592, 0xa696, 0xa79a, 0x080c, 0x1134, 0x7007, 0x0002, 0x701f, + 0x4e52, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, + 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa48c, 0xa590, + 0xa694, 0xa798, 0x0804, 0x4e10, 0x7224, 0x900e, 0x2001, 0x0003, + 0x080c, 0x847e, 0x2208, 0x0804, 0x33f2, 0x00f6, 0x00e6, 0x080c, + 0x54ef, 0x2009, 0x0007, 0x1904, 0x4ee5, 0x2071, 0x189c, 0x745c, + 0x84ff, 0x2009, 0x000e, 0x1904, 0x4ee5, 0xac9c, 0xad98, 0xaea4, + 0xafa0, 0x0096, 0x080c, 0x1050, 0x2009, 0x0002, 0x0904, 0x4ee5, + 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, + 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, + 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1148, + 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, + 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, + 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, + 0x847e, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, + 0x090c, 0x0df6, 0x2148, 0x080c, 0x1069, 0x9006, 0x705e, 0x918d, + 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, + 0x7056, 0x2061, 0x18b7, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, + 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x4ef1, 0x000e, + 0xa0a2, 0x080c, 0x1134, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, + 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, + 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0df6, 0x00e6, 0x2071, + 0x189c, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, + 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, + 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x847e, 0xaa9a, 0x715c, + 0x81ff, 0x090c, 0x0df6, 0x2148, 0x080c, 0x1069, 0x705f, 0x0000, + 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e, + 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, + 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118, 0x080c, + 0x66d1, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, + 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, + 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, + 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0df6, 0x2148, 0x080c, + 0x1069, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e, 0xa09f, 0x0000, + 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, + 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1134, + 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, + 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, + 0x3427, 0xa884, 0xa988, 0x080c, 0x266d, 0x1518, 0x080c, 0x6343, + 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x49b7, 0x01c8, + 0x080c, 0x49b7, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, + 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xbefa, 0x1120, + 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x4fbe, + 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x3424, 0x7124, 0x080c, + 0x3190, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, + 0x3424, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, + 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, + 0x080c, 0x0fb4, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b6, + 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, + 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, + 0x000e, 0x007e, 0x0804, 0x4a03, 0x97c6, 0x7200, 0x11b8, 0x96c2, + 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b6, 0x2c44, 0xa076, + 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, + 0x1134, 0x7007, 0x0002, 0x701f, 0x501a, 0x0005, 0x000e, 0x007e, + 0x0804, 0x3427, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, + 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, + 0x0fb4, 0x2100, 0x2238, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390, + 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4a03, 0x81ff, 0x1904, + 0x3424, 0x798c, 0x2001, 0x1958, 0x918c, 0x8000, 0x2102, 0x080c, + 0x49ce, 0x0904, 0x3427, 0x080c, 0x66c9, 0x0120, 0x080c, 0x66d1, + 0x1904, 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6530, 0x012e, 0x0904, 0x3424, 0x2001, 0x1958, + 0x2004, 0xd0fc, 0x1904, 0x33f2, 0x0804, 0x4461, 0xa9a0, 0x2001, + 0x1958, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49db, 0x01a0, + 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1170, 0x080c, 0x646a, + 0x2009, 0x0002, 0x0128, 0x080c, 0x6530, 0x1170, 0x2009, 0x0003, + 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1958, + 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, + 0x1118, 0xd084, 0x0904, 0x43d6, 0x080c, 0x49ea, 0x0904, 0x3427, + 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x080c, + 0x66c9, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, + 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, + 0x54db, 0xd0b4, 0x0904, 0x4410, 0x7884, 0x908e, 0x007e, 0x0904, + 0x4410, 0x908e, 0x007f, 0x0904, 0x4410, 0x908e, 0x0080, 0x0904, + 0x4410, 0xb800, 0xd08c, 0x1904, 0x4410, 0xa867, 0x0000, 0xa868, + 0xc0fd, 0xa86a, 0x080c, 0xbf19, 0x1120, 0x2009, 0x0003, 0x0804, + 0x3424, 0x7007, 0x0003, 0x701f, 0x50e6, 0x0005, 0x080c, 0x49ea, + 0x0904, 0x3427, 0x0804, 0x4410, 0x080c, 0x31e9, 0x0108, 0x0005, + 0x2009, 0x1833, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x3424, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424, + 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804, 0x3424, 0xb89c, + 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4410, 0x9006, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf78, 0x1120, 0x2009, 0x0003, + 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x511f, 0x0005, 0xa830, + 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x542f, 0x080c, + 0x49ea, 0x0904, 0x3427, 0x0804, 0x50b8, 0x81ff, 0x2009, 0x0001, + 0x1904, 0x3424, 0x080c, 0x54ef, 0x2009, 0x0007, 0x1904, 0x3424, + 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804, 0x3424, 0x080c, + 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9, 0x2009, 0x0009, 0x1904, + 0x3424, 0x080c, 0x49b7, 0x2009, 0x0002, 0x0904, 0x3424, 0x9006, + 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, + 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, + 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x3427, 0xc0e5, + 0xa952, 0xa956, 0xa83e, 0x080c, 0xc1cb, 0x2009, 0x0003, 0x0904, + 0x3424, 0x7007, 0x0003, 0x701f, 0x5176, 0x0005, 0xa830, 0x9086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x3424, 0x0804, 0x33f2, 0x7aa8, + 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x54ef, 0x1188, + 0x2009, 0x0014, 0x0804, 0x3424, 0xd2dc, 0x1578, 0x81ff, 0x2009, + 0x0001, 0x1904, 0x3424, 0x080c, 0x54ef, 0x2009, 0x0007, 0x1904, + 0x3424, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x54b5, + 0x0804, 0x33f2, 0xd2fc, 0x0160, 0x080c, 0x49ea, 0x0904, 0x3427, + 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548a, 0x0804, 0x33f2, + 0x080c, 0x49ea, 0x0904, 0x3427, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x2009, 0x0009, 0x1904, 0x5265, 0x080c, 0x49b7, 0x2009, + 0x0002, 0x0904, 0x5265, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, + 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4a00, 0x701f, + 0x51d2, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, + 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x3427, 0xa866, + 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x49ea, 0x1110, 0x0804, + 0x3427, 0x2009, 0x0043, 0x080c, 0xc237, 0x2009, 0x0003, 0x0904, + 0x5265, 0x7007, 0x0003, 0x701f, 0x51f6, 0x0005, 0xa830, 0x9086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x5265, 0x7984, 0x7aa8, 0x9284, + 0x1000, 0xc0d5, 0x080c, 0x548a, 0x0804, 0x33f2, 0x00c6, 0xaab0, + 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x54ef, 0x1158, + 0x2009, 0x0014, 0x0804, 0x5254, 0x2061, 0x1800, 0x080c, 0x54ef, + 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, + 0x080c, 0x54b5, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x49e8, 0x0590, + 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548a, 0xa87b, 0x0000, + 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x49e8, 0x0510, + 0x080c, 0x66c9, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, + 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, + 0x080c, 0x49e8, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xc237, + 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, + 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, + 0x3424, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x548a, + 0x001e, 0x1904, 0x3424, 0x0804, 0x33f2, 0x00f6, 0x2d78, 0xaab0, + 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, + 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x548a, 0x001e, 0x9085, + 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, + 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424, 0x7984, + 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a3, 0x1904, 0x3427, 0x9186, + 0x007f, 0x0138, 0x080c, 0x66c9, 0x0120, 0x2009, 0x0009, 0x0804, + 0x3424, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, + 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, + 0xa80a, 0x080c, 0xbf33, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, + 0x7007, 0x0003, 0x701f, 0x52c5, 0x0005, 0xa808, 0x8007, 0x9086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3424, 0xa8e0, 0xa866, + 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, + 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x0804, 0x4a03, 0x080c, 0x49b7, 0x1120, 0x2009, + 0x0002, 0x0804, 0x3424, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, + 0x8217, 0x82ff, 0x1118, 0x7023, 0x198e, 0x0040, 0x92c6, 0x0001, + 0x1118, 0x7023, 0x19a8, 0x0010, 0x0804, 0x3427, 0x2009, 0x001a, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, + 0x080c, 0x4a00, 0x701f, 0x5315, 0x0005, 0x2001, 0x182d, 0x2003, + 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, + 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x33f2, + 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x7984, + 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, + 0x198e, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19a8, 0x0010, + 0x0804, 0x3427, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, + 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, + 0x4a03, 0x7884, 0x908a, 0x1000, 0x1a04, 0x3427, 0x0126, 0x2091, + 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x19d5, + 0x614a, 0x00ce, 0x012e, 0x0804, 0x33f2, 0x00c6, 0x080c, 0x717e, + 0x1160, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085, 0x0001, 0x080c, + 0x71c2, 0x080c, 0x709e, 0x080c, 0x0df6, 0x2061, 0x1800, 0x6030, + 0xc09d, 0x6032, 0x080c, 0x5cee, 0x00ce, 0x0005, 0x00c6, 0x2001, + 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x3424, 0x7884, 0x9005, + 0x0188, 0x7888, 0x2061, 0x1976, 0x2c0c, 0x2062, 0x080c, 0x2a7f, + 0x01a0, 0x080c, 0x2a87, 0x0188, 0x080c, 0x2a8f, 0x0170, 0x2162, + 0x0804, 0x3427, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, + 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, + 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, 0x2011, + 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, 0x002e, + 0x080c, 0x983b, 0x0036, 0x901e, 0x080c, 0x98b1, 0x003e, 0x60e3, + 0x0000, 0x080c, 0xdbdb, 0x080c, 0xdbf6, 0x9085, 0x0001, 0x080c, + 0x71c2, 0x9006, 0x080c, 0x2b6f, 0x2001, 0x1800, 0x2003, 0x0004, + 0x2001, 0x1982, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce, 0x0804, + 0x33f2, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x080c, + 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424, 0x7984, 0x7ea8, + 0x96b4, 0x00ff, 0x080c, 0x63a3, 0x1904, 0x3427, 0x9186, 0x007f, + 0x0138, 0x080c, 0x66c9, 0x0120, 0x2009, 0x0009, 0x0804, 0x3424, + 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf36, 0x1120, 0x2009, + 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x5418, 0x0005, + 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3424, + 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4a03, 0xa898, + 0x9086, 0x000d, 0x1904, 0x3424, 0x2021, 0x4005, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x543c, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, + 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, + 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, + 0x49f3, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11e6, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19d5, 0x7984, + 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, + 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x19e5, + 0x2044, 0x2001, 0x19ec, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, + 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, + 0x0804, 0x33f2, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, + 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019, 0x0029, + 0x080c, 0x31ae, 0x003e, 0x080c, 0xbd9b, 0x000e, 0x1198, 0xd0e4, + 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x5e49, + 0x080c, 0x9f69, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, + 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, + 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, + 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, 0x007f, + 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, + 0x2200, 0x080c, 0x548a, 0x002e, 0x001e, 0x8108, 0x1f04, 0x54bd, + 0x015e, 0x012e, 0x0005, 0x2001, 0x185c, 0x2004, 0x0005, 0x2001, + 0x187b, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4, + 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071, + 0x189c, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, + 0x81ff, 0x0904, 0x3427, 0x9182, 0x0081, 0x1a04, 0x3427, 0x810c, + 0x0016, 0x080c, 0x49b7, 0x0170, 0x080c, 0x0f3f, 0x2100, 0x2238, + 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4a00, 0x701f, + 0x551f, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x3424, 0x2079, + 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, + 0x18b6, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189c, 0x080c, 0x4a03, + 0x701f, 0x5533, 0x0005, 0x2061, 0x18b6, 0x2c44, 0x0016, 0x0026, + 0xa270, 0xa174, 0x080c, 0x0f47, 0x002e, 0x001e, 0x080c, 0x0ff4, + 0x9006, 0xa802, 0xa806, 0x0804, 0x33f2, 0x0126, 0x0156, 0x0136, + 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, + 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, + 0xd084, 0x0118, 0x080c, 0x56ee, 0x0068, 0xd08c, 0x0118, 0x080c, + 0x55f7, 0x0040, 0xd094, 0x0118, 0x080c, 0x55c7, 0x0018, 0xd09c, + 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, + 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, + 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7094, 0x9005, + 0x000e, 0x0120, 0x7097, 0x0000, 0x708f, 0x0000, 0x624c, 0x9286, + 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, + 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, + 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, + 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x00f0, + 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, + 0x7083, 0x0000, 0x709f, 0x0001, 0x70c3, 0x0000, 0x70db, 0x0000, + 0x2009, 0x1c80, 0x200b, 0x0000, 0x7093, 0x0000, 0x7087, 0x000f, + 0x2009, 0x000f, 0x2011, 0x5c91, 0x080c, 0x82eb, 0x0005, 0x2001, + 0x187d, 0x2004, 0xd08c, 0x0110, 0x705b, 0xffff, 0x7084, 0x9005, + 0x1528, 0x2011, 0x5c91, 0x080c, 0x8259, 0x6040, 0x9094, 0x0010, + 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, + 0x1f04, 0x55dd, 0x6242, 0x7097, 0x0000, 0x6040, 0x9094, 0x0010, + 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x7097, 0x0000, + 0x708b, 0x0000, 0x9006, 0x080c, 0x5e34, 0x0000, 0x0005, 0x7088, + 0x908a, 0x0003, 0x1a0c, 0x0df6, 0x000b, 0x0005, 0x5601, 0x5652, + 0x56ed, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708b, 0x0001, + 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, + 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5610, 0x080c, 0x0df6, + 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, + 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x5e10, 0x2079, + 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, + 0x080c, 0x9df2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, + 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, + 0x0000, 0x080c, 0x5cc2, 0x00fe, 0x9006, 0x708e, 0x6043, 0x0008, + 0x6042, 0x0005, 0x00f6, 0x708c, 0x708f, 0x0000, 0x9025, 0x0904, + 0x56ca, 0x6020, 0xd0b4, 0x1904, 0x56c8, 0x719c, 0x81ff, 0x0904, + 0x56b6, 0x9486, 0x000c, 0x1904, 0x56c3, 0x9480, 0x0018, 0x8004, + 0x20a8, 0x080c, 0x5e09, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, + 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x566f, 0x6043, + 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, + 0x0100, 0x6043, 0x0006, 0x708b, 0x0002, 0x7097, 0x0002, 0x2009, + 0x07d0, 0x2011, 0x5c98, 0x080c, 0x82eb, 0x080c, 0x5e10, 0x04c0, + 0x080c, 0x5e09, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, + 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, + 0x9005, 0x0190, 0x080c, 0x5e09, 0x2011, 0x026e, 0x2019, 0x1805, + 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, + 0x8318, 0x1f04, 0x56aa, 0x0078, 0x709f, 0x0000, 0x080c, 0x5e09, + 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00, + 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, + 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, + 0x1db8, 0x080c, 0x9df2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, + 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, + 0x2011, 0x19cc, 0x2013, 0x0000, 0x708f, 0x0000, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x080c, 0x9611, 0x08d8, 0x0005, 0x7094, 0x908a, + 0x001d, 0x1a0c, 0x0df6, 0x000b, 0x0005, 0x571f, 0x5732, 0x575b, + 0x577b, 0x57a1, 0x57d0, 0x57f6, 0x582e, 0x5854, 0x5882, 0x58bd, + 0x58f5, 0x5913, 0x593e, 0x5960, 0x597b, 0x5985, 0x59b9, 0x59df, + 0x5a0e, 0x5a34, 0x5a6c, 0x5ab0, 0x5aed, 0x5b0e, 0x5b67, 0x5b89, + 0x5bb7, 0x5bb7, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, + 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, + 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, + 0x0002, 0x7097, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5c98, 0x080c, + 0x82eb, 0x0005, 0x00f6, 0x708c, 0x9086, 0x0014, 0x1510, 0x6042, + 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, + 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x7097, 0x0010, 0x080c, 0x5985, 0x0010, 0x708f, + 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0003, 0x6043, 0x0004, + 0x2011, 0x5c98, 0x080c, 0x8259, 0x080c, 0x5d8d, 0x2079, 0x0240, + 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, + 0x200b, 0x0000, 0x8108, 0x1f04, 0x5770, 0x60c3, 0x0014, 0x080c, + 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, + 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, + 0x0001, 0x7097, 0x0004, 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe, + 0x0005, 0x00f6, 0x7097, 0x0005, 0x080c, 0x5d8d, 0x2079, 0x0240, + 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec, + 0x1170, 0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, + 0x2011, 0x0008, 0x080c, 0x5c45, 0x0168, 0x080c, 0x5dc2, 0x20a9, + 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, + 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005, + 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0006, + 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, + 0x0007, 0x080c, 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, + 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec, 0x11b8, 0x7080, 0x9005, + 0x11a0, 0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x31f3, 0x200d, + 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c45, 0x0180, + 0x080c, 0x4dd7, 0x0110, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, + 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, + 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0008, 0x0029, 0x0010, + 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0009, 0x080c, + 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, + 0x5dec, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c, 0x5bb8, 0x1188, + 0x9085, 0x0001, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x080c, 0x5e09, + 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x0010, 0x080c, 0x5712, + 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05a8, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x9086, 0x0014, 0x1560, 0x080c, 0x5e09, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, + 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, + 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x000a, 0x00b1, 0x0098, + 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, + 0x70c3, 0x0001, 0x7093, 0x0000, 0x7097, 0x000e, 0x080c, 0x5960, + 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000b, + 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, + 0xffff, 0x4304, 0x080c, 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1106, + 0x7837, 0x0000, 0x080c, 0x5dec, 0x0118, 0x2013, 0x0000, 0x0020, + 0x705c, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, + 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, + 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x58e2, 0x60c3, + 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, + 0x01c0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084, 0x1178, + 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, + 0x7834, 0x9005, 0x1120, 0x7097, 0x000c, 0x0029, 0x0010, 0x080c, + 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000d, 0x080c, 0x5d8d, + 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x5e09, + 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, + 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, + 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5926, + 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, + 0x9005, 0x01e0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084, + 0x1198, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, + 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c, 0x5d5f, + 0x7097, 0x000e, 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005, + 0x918d, 0x0001, 0x080c, 0x5e34, 0x7097, 0x000f, 0x708f, 0x0000, + 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, + 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5c98, + 0x080c, 0x824d, 0x0005, 0x708c, 0x9005, 0x0130, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x7097, 0x0000, 0x0005, 0x7097, 0x0011, 0x080c, + 0x9df2, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, + 0x0000, 0x20a1, 0x0240, 0x748c, 0x9480, 0x0018, 0x9080, 0x0007, + 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x5dec, 0x11a0, + 0x7178, 0x81ff, 0x0188, 0x900e, 0x707c, 0x9084, 0x00ff, 0x0160, + 0x080c, 0x266d, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, + 0x2011, 0x0008, 0x080c, 0x5c45, 0x60c3, 0x0014, 0x080c, 0x5cc2, + 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, + 0x8259, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, + 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, + 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, + 0x0012, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, + 0x7097, 0x0013, 0x080c, 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1103, + 0x7837, 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec, 0x1170, 0x7080, + 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, + 0x080c, 0x5c45, 0x0168, 0x080c, 0x5dc2, 0x20a9, 0x0008, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, + 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, + 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, + 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, + 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0014, 0x0029, 0x0010, + 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0015, 0x080c, + 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, + 0x5e09, 0x080c, 0x5dec, 0x11b8, 0x7080, 0x9005, 0x11a0, 0x7160, + 0x9186, 0xffff, 0x0180, 0x9180, 0x31f3, 0x200d, 0x918c, 0xff00, + 0x810f, 0x2011, 0x0008, 0x080c, 0x5c45, 0x0180, 0x080c, 0x4dd7, + 0x0110, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, + 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, + 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05f0, + 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, 0x15a8, 0x080c, + 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, + 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, + 0x080c, 0x5e34, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, + 0x70c3, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, + 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x9085, 0x0001, 0x080c, + 0x5e34, 0x7093, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70db, 0x0008, + 0x7097, 0x0016, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, + 0x080c, 0x9df2, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x0260, + 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, + 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, + 0x026e, 0x7097, 0x0017, 0x080c, 0x5dec, 0x1150, 0x7080, 0x9005, + 0x1138, 0x080c, 0x5bb8, 0x1188, 0x9085, 0x0001, 0x080c, 0x26d6, + 0x20a9, 0x0008, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, + 0x5cc2, 0x0010, 0x080c, 0x5712, 0x0005, 0x00f6, 0x708c, 0x9005, + 0x01d8, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084, 0x1190, + 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, + 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x5e34, 0x7097, 0x0018, + 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, + 0x0019, 0x080c, 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, + 0x0000, 0x080c, 0x5e09, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, + 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, + 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5b21, 0x2039, 0x1c0e, + 0x080c, 0x5dec, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, + 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x705c, + 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118, + 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, + 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, + 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, + 0x5b54, 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, + 0x708c, 0x9005, 0x01e0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, + 0x0084, 0x1198, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c, + 0x5d5f, 0x7097, 0x001a, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, + 0x0005, 0x9085, 0x0001, 0x080c, 0x5e34, 0x7097, 0x001b, 0x080c, + 0x9df2, 0x080c, 0x5e09, 0x2011, 0x0260, 0x2009, 0x0240, 0x748c, + 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, + 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, + 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, + 0x1f04, 0x5ba0, 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x0005, 0x0005, + 0x0086, 0x0096, 0x2029, 0x185c, 0x252c, 0x20a9, 0x0008, 0x2041, + 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x5e09, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, + 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, + 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5bd2, 0x0804, + 0x5c41, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, + 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5c41, 0x918d, 0xc000, 0x20a9, + 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, + 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, + 0x8319, 0x0008, 0x8318, 0x1f04, 0x5bf8, 0x04d8, 0x23a8, 0x2021, + 0x0001, 0x8426, 0x8425, 0x1f04, 0x5c0a, 0x2328, 0x8529, 0x92be, + 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, + 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5c19, 0x755a, 0x95c8, 0x31f3, + 0x292d, 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, + 0x080c, 0x26b6, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, + 0x9405, 0x201a, 0x7083, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, + 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, + 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, + 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, + 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, + 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, + 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, + 0x11b8, 0x9405, 0x203a, 0x715a, 0x91a0, 0x31f3, 0x242d, 0x95ac, + 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26b6, + 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7083, 0x0001, 0x9084, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x7087, 0x0000, 0x00ee, 0x0005, + 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x5d4e, + 0x080c, 0x961a, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b7f, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1825, 0x2073, 0x0000, 0x7840, + 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x001e, 0x9094, + 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x29e9, 0x0228, + 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19cc, 0x2013, + 0x0000, 0x708f, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, + 0x080c, 0x9611, 0x6144, 0xd184, 0x0120, 0x7194, 0x918d, 0x2000, + 0x0018, 0x7188, 0x918d, 0x1000, 0x2011, 0x1973, 0x2112, 0x2009, + 0x07d0, 0x2011, 0x5c98, 0x080c, 0x82eb, 0x0005, 0x0016, 0x0026, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f70, 0x2009, 0x00f7, + 0x080c, 0x5dab, 0x2061, 0x19d5, 0x900e, 0x611a, 0x611e, 0x617a, + 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, + 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000, 0x2009, + 0x002d, 0x2011, 0x5d1a, 0x080c, 0x824d, 0x012e, 0x00ce, 0x002e, + 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, + 0x2071, 0x0100, 0x080c, 0x961a, 0x2071, 0x0140, 0x7004, 0x9084, + 0x4000, 0x0110, 0x080c, 0x2b7f, 0x080c, 0x7186, 0x0188, 0x080c, + 0x71a1, 0x1170, 0x080c, 0x7484, 0x0016, 0x080c, 0x2785, 0x2001, + 0x1947, 0x2102, 0x001e, 0x080c, 0x747f, 0x080c, 0x709e, 0x0050, + 0x2009, 0x0001, 0x080c, 0x2a9d, 0x2001, 0x0001, 0x080c, 0x2616, + 0x080c, 0x5cee, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, + 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, + 0x1973, 0x201c, 0x080c, 0x4a17, 0x003e, 0x002e, 0x0005, 0x20a9, + 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x5e09, 0x20e9, + 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x5e03, + 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, + 0x5e06, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016, + 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, + 0x1f04, 0x5d83, 0x002e, 0x001e, 0x0005, 0x080c, 0x9df2, 0x20e1, + 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x000c, 0x4003, 0x0005, 0x080c, 0x9df2, 0x080c, 0x5e09, 0x20e1, + 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, + 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, + 0x2001, 0x1833, 0x2004, 0x9005, 0x1138, 0x2001, 0x1817, 0x2004, + 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, + 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x66c5, 0x0158, 0x9006, + 0x2020, 0x2009, 0x002a, 0x080c, 0xd837, 0x2001, 0x180c, 0x200c, + 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3060, 0x080c, + 0xc459, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, + 0x4bb4, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5cee, 0x7097, + 0x0000, 0x708f, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, + 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, + 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, + 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, + 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, + 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, + 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200, + 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, + 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, + 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x1981, 0x0118, 0x2003, + 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, + 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x5e43, 0x015e, + 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x185b, + 0x9006, 0xb802, 0xb8be, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, + 0x9198, 0x31f3, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, + 0xb8b2, 0x080c, 0x9f69, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbb2, + 0x20a9, 0x0004, 0xb8b4, 0x20e8, 0xb9b8, 0x9198, 0x0006, 0x9006, + 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, + 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a, + 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, + 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, + 0xb8ae, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1069, + 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, + 0xb846, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, + 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x5f19, 0x9182, 0x0800, + 0x1a04, 0x5f1d, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, + 0x5f23, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084, + 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x5f35, + 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, + 0x8615, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002, + 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e, + 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, + 0x080c, 0x9f69, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, + 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, + 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, + 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, + 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, + 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, + 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, + 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x66c9, 0x1990, + 0xb800, 0xd0bc, 0x0978, 0x0804, 0x5ecc, 0x080c, 0x653f, 0x0904, + 0x5ee5, 0x0804, 0x5ed0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, + 0xa974, 0x9182, 0x0800, 0x1a04, 0x5fb9, 0x9188, 0x1000, 0x2104, + 0x905d, 0x0904, 0x5f91, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, + 0xd0fc, 0x1178, 0x080c, 0x66d1, 0x0160, 0xa994, 0x81ff, 0x0130, + 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x66c9, + 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, + 0x0026, 0x2010, 0x080c, 0xbd3c, 0x002e, 0x1120, 0x2001, 0x0008, + 0x0804, 0x5fbb, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, + 0x0804, 0x5fbb, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, + 0x080c, 0x9f94, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, + 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xa068, 0x9006, + 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, + 0x9f69, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, + 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, + 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, + 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, + 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, + 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, + 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, + 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, + 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, + 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, + 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, + 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, + 0x00be, 0x00fe, 0x0005, 0x6050, 0x600b, 0x6022, 0x6050, 0x6050, + 0x6050, 0x6050, 0x6050, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, + 0x6343, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6058, 0xb814, + 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x48d1, + 0x0150, 0x04b0, 0x080c, 0x63a3, 0x1598, 0xb810, 0x9306, 0x1580, + 0xb814, 0x9206, 0x1568, 0x080c, 0x9f94, 0x0530, 0x2b00, 0x6012, + 0x080c, 0xc1ca, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, + 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x3095, 0x9006, 0x080c, + 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x2001, 0x0200, 0xb86e, + 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xa068, 0x9006, 0x0068, + 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, + 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, + 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, + 0x90c6, 0x0015, 0x0904, 0x6231, 0x90c6, 0x0056, 0x0904, 0x6235, + 0x90c6, 0x0066, 0x0904, 0x6239, 0x90c6, 0x0067, 0x0904, 0x623d, + 0x90c6, 0x0068, 0x0904, 0x6241, 0x90c6, 0x0071, 0x0904, 0x6245, + 0x90c6, 0x0074, 0x0904, 0x6249, 0x90c6, 0x007c, 0x0904, 0x624d, + 0x90c6, 0x007e, 0x0904, 0x6251, 0x90c6, 0x0037, 0x0904, 0x6255, + 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x622c, + 0x9182, 0x0800, 0x1a04, 0x622c, 0x080c, 0x63a3, 0x1198, 0xb804, + 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, + 0x0148, 0x080c, 0x9f69, 0x1904, 0x6215, 0xb8a0, 0x9084, 0xff80, + 0x1904, 0x6215, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, + 0x0904, 0x6175, 0x90c6, 0x0064, 0x0904, 0x619e, 0x2008, 0x0804, + 0x6138, 0xa998, 0xa8b0, 0x2040, 0x080c, 0x9f69, 0x1120, 0x9182, + 0x007f, 0x0a04, 0x6138, 0x9186, 0x00ff, 0x0904, 0x6138, 0x9182, + 0x0800, 0x1a04, 0x6138, 0xaaa0, 0xab9c, 0x7878, 0x9306, 0x11a8, + 0x787c, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, + 0x6138, 0x080c, 0x9f69, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, + 0x2208, 0x2310, 0x0804, 0x6138, 0x009e, 0x080c, 0x48d1, 0x0904, + 0x6141, 0x900e, 0x9016, 0x90c6, 0x4000, 0x1558, 0x0006, 0x080c, + 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, + 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8b4, + 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fb4, 0x20a9, + 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8b4, + 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fb4, 0x000e, + 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, + 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, + 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, + 0x0470, 0x080c, 0x9f94, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003, + 0x9016, 0x0c80, 0x2b00, 0x6012, 0x080c, 0xc1ca, 0x2900, 0x6016, + 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, + 0x2091, 0x8000, 0x080c, 0x3095, 0x012e, 0x9006, 0x080c, 0x62e0, + 0x2001, 0x0002, 0x080c, 0x62f4, 0x2009, 0x0002, 0x080c, 0xa068, + 0xa8b0, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x9006, 0x9005, + 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x54ef, 0x0118, + 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x63a3, 0x1904, + 0x6133, 0x9186, 0x007f, 0x0130, 0x080c, 0x66c9, 0x0118, 0x2009, + 0x0009, 0x0080, 0x0096, 0x080c, 0x1037, 0x1120, 0x009e, 0x2009, + 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xbf36, 0x19b0, + 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613a, 0xa998, 0xaeb0, + 0x080c, 0x63a3, 0x1904, 0x6133, 0x0096, 0x080c, 0x1037, 0x1128, + 0x009e, 0x2009, 0x0002, 0x0804, 0x61f2, 0x2900, 0x009e, 0xa806, + 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, + 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbb8, 0x9398, 0x0006, 0x2398, + 0x080c, 0x0fb4, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, + 0x4000, 0xd684, 0x1168, 0x080c, 0x54db, 0xd0b4, 0x1118, 0xa89b, + 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, + 0x080c, 0x66c9, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x54ef, + 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xbf19, 0x1904, 0x616e, + 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613a, 0xa87b, 0x0030, + 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, + 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x128e, 0x080c, 0xa4f1, + 0x1904, 0x616e, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, + 0x0804, 0x616f, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, + 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, + 0x0029, 0x900e, 0x0804, 0x616f, 0x2001, 0x0029, 0x900e, 0x0804, + 0x616f, 0x080c, 0x3624, 0x0804, 0x6170, 0x080c, 0x5206, 0x0804, + 0x6170, 0x080c, 0x448c, 0x0804, 0x6170, 0x080c, 0x4505, 0x0804, + 0x6170, 0x080c, 0x4561, 0x0804, 0x6170, 0x080c, 0x498d, 0x0804, + 0x6170, 0x080c, 0x4c36, 0x0804, 0x6170, 0x080c, 0x4e6d, 0x0804, + 0x6170, 0x080c, 0x5066, 0x0804, 0x6170, 0x080c, 0x384d, 0x0804, + 0x6170, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, 0x905d, + 0x0140, 0x080c, 0x66c9, 0x1148, 0x00e9, 0x080c, 0x64ce, 0x9006, + 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, + 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, + 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, + 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, 0x0150, + 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, 0xb852, + 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, + 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071, + 0x19c2, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802, + 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, + 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050, + 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, + 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, 0x904d, + 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x0005, + 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, + 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, + 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, + 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, + 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x66c5, 0x0140, 0x9284, 0xff00, + 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, + 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, + 0x82ff, 0x090c, 0x0df6, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, + 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, + 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, + 0x66c1, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, + 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, + 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, + 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1180, + 0x0096, 0x080c, 0x1037, 0x2958, 0x009e, 0x0160, 0x2b00, 0x2012, + 0xb85c, 0xb8ba, 0xb860, 0xb8b6, 0x9006, 0xb8a6, 0x080c, 0x5e49, + 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, + 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, + 0x9085, 0x0001, 0x0458, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, + 0x0518, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1069, + 0x00d6, 0x00c6, 0xb8ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, + 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0110, 0x080c, 0x0fe9, 0x080c, + 0x9fea, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x2b48, 0xb8b8, 0xb85e, + 0xb8b4, 0xb862, 0x080c, 0x1079, 0x00de, 0x9006, 0x002e, 0x012e, + 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085, + 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006, + 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a, + 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x717e, 0x1510, 0xb8a0, + 0x9086, 0x007e, 0x0120, 0x080c, 0x9f69, 0x11d8, 0x0078, 0x7040, + 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x195c, 0x7048, 0x2062, 0x704c, + 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, + 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800, + 0x68b2, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1, + 0x0000, 0x2099, 0x0276, 0xb8b4, 0x20e8, 0xb8b8, 0x9088, 0x000a, + 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006, + 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001, + 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876, + 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110, + 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, + 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1, + 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009, + 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, + 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, + 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, + 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054, + 0xb89e, 0x0036, 0xbbbc, 0xc384, 0xba00, 0x2009, 0x187b, 0x210c, + 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, + 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108, + 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbbe, 0x003e, 0x00ee, 0x002e, + 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, + 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8, + 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c, + 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009, + 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109, + 0x1dd0, 0x080c, 0x0df6, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0, + 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060, + 0x080c, 0x1037, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c, + 0x655f, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e, + 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4, + 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x656e, 0x1158, + 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c, + 0x1069, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0126, 0x2091, + 0x8000, 0x080c, 0x8615, 0x012e, 0x0005, 0x901e, 0x0010, 0x2019, + 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, 0x2048, 0xb800, + 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878, 0x9606, + 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120, + 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0x9955, 0xaa00, 0xb84c, + 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202, 0x00ae, + 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, 0x9016, 0x0489, + 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x65c3, 0x0128, 0x080c, + 0xbe0b, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c3, 0x0128, + 0x080c, 0xbdb0, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c3, + 0x0128, 0x080c, 0xbe08, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, + 0x65c3, 0x0128, 0x080c, 0xbdcf, 0x0010, 0x9085, 0x0001, 0x0005, + 0x080c, 0x65c3, 0x0128, 0x080c, 0xbe4e, 0x0010, 0x9085, 0x0001, + 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005, 0x0136, + 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, + 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, + 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, + 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0146, + 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0, 0x20a9, + 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136, 0x01c6, + 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, + 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, + 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085, + 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, 0x3c00, + 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006, 0x01ce, + 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, + 0x1128, 0x080c, 0x1037, 0x0168, 0x2900, 0xb8a6, 0x080c, 0x655f, + 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, 0x009e, + 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, + 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1069, 0x9085, 0x0001, + 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, 0x00f6, + 0x080c, 0x717e, 0x01b0, 0x71c0, 0x81ff, 0x1198, 0x71d8, 0xd19c, + 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d, 0x0148, + 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, + 0xb802, 0x2079, 0x185b, 0x7804, 0x00d0, 0x0156, 0x20a9, 0x007f, + 0x900e, 0x0016, 0x080c, 0x63a3, 0x1168, 0xb804, 0x9084, 0xff00, + 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, 0x1118, 0xb800, + 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x65e9, 0x015e, 0x080c, + 0x6687, 0x0120, 0x2001, 0x195f, 0x200c, 0x0030, 0x2079, 0x185b, + 0x7804, 0x0030, 0x2009, 0x07d0, 0x2011, 0x6613, 0x080c, 0x82eb, + 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x6613, 0x080c, 0x8259, + 0x080c, 0x6687, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, + 0xc1ec, 0xb902, 0x080c, 0x66c5, 0x0130, 0x2009, 0x07d0, 0x2011, + 0x6613, 0x080c, 0x82eb, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707a, + 0x705c, 0x707e, 0x080c, 0x2e73, 0x00ee, 0x04c0, 0x0156, 0x00c6, + 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1548, 0xb800, + 0xd0ec, 0x0530, 0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220, 0x9006, + 0x2009, 0x0029, 0x080c, 0xd837, 0xb800, 0xc0e5, 0xc0ec, 0xb802, + 0x080c, 0x66c1, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, + 0x9085, 0x0700, 0xb806, 0x2019, 0x0029, 0x080c, 0x8782, 0x0076, + 0x903e, 0x080c, 0x8670, 0x900e, 0x080c, 0xd556, 0x007e, 0x004e, + 0x001e, 0x8108, 0x1f04, 0x663b, 0x00ce, 0x015e, 0x00be, 0x0005, + 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, + 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, + 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc, 0x0005, 0x00b6, + 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0ec, + 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, 0x0006, + 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0df6, 0x000e, + 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, 0x002e, + 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc, 0x0138, 0x2001, + 0x195d, 0x200c, 0x2011, 0x66b7, 0x080c, 0x82eb, 0x0005, 0x2011, + 0x66b7, 0x080c, 0x8259, 0x2011, 0x1836, 0x2204, 0xc0cc, 0x2012, + 0x0005, 0x080c, 0x54db, 0xd0ac, 0x0005, 0x080c, 0x54db, 0xd0a4, + 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, 0x001e, + 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, 0x0006, + 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xc459, 0x0158, 0x70d8, + 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, 0x0110, + 0xb8bc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016, 0x0036, + 0x0046, 0x0076, 0x00b6, 0x2001, 0x1817, 0x203c, 0x9780, 0x31f3, + 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, 0x2008, 0x9284, + 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, 0x2100, 0x9706, + 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, 0xb804, 0x9084, + 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, 0xb89c, 0xd0a4, + 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, 0x9182, 0x0800, + 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, 0x00be, 0x007e, + 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, 0x0005, 0x00be, + 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, 0x0005, 0x0046, + 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, 0x9080, 0x1000, + 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, + 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1817, 0x203c, 0x9780, + 0x31f3, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2020, 0x2400, + 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, 0x0178, 0xb804, + 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, 0xd0a4, 0x0130, + 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, 0x8420, 0x9482, + 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, 0x007e, 0x005e, + 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, 0x00be, 0x007e, + 0x005e, 0x004e, 0x9006, 0x0005, 0x2071, 0x190e, 0x7003, 0x0001, + 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, 0x700a, + 0x7046, 0x2001, 0x1920, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, + 0x2071, 0x1923, 0x900e, 0x710a, 0x080c, 0x54db, 0xd0fc, 0x1140, + 0x080c, 0x54db, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0438, + 0x2001, 0x187b, 0x200c, 0x9184, 0x0007, 0x9006, 0x0002, 0x67a0, + 0x67a0, 0x67a0, 0x67a0, 0x67a0, 0x67b7, 0x67cc, 0x67da, 0x7003, + 0x0003, 0x2009, 0x187c, 0x210c, 0x9184, 0xff00, 0x908e, 0xff00, + 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, 0x7006, + 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, 0x2071, + 0x190e, 0x704f, 0x0000, 0x2071, 0x1800, 0x70ef, 0x0001, 0x00ee, + 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x190e, 0x2009, 0x187c, + 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160, 0x714e, + 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c, 0x0007, + 0x0128, 0x70ee, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70ef, 0x0005, + 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6, + 0x2071, 0x190e, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001, + 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x74ec, 0x6a60, 0x9200, + 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6860, + 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, 0x6844, + 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, 0x9085, + 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071, + 0x190e, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, 0x0000, + 0x00ee, 0x9006, 0x00ee, 0x0005, 0xa868, 0xd0fc, 0x1508, 0x00e6, + 0x0026, 0x2001, 0x1923, 0x2004, 0x9015, 0x0904, 0x6a28, 0xa978, + 0xa874, 0x9105, 0x1904, 0x6a28, 0x9286, 0x0003, 0x0904, 0x68c1, + 0x9286, 0x0005, 0x0904, 0x68c1, 0xa87c, 0xd0bc, 0x1904, 0x6a28, + 0x2200, 0x0002, 0x6a28, 0x6885, 0x68c1, 0x68c1, 0x6a28, 0x68c1, + 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, 0x1923, + 0x210c, 0x81ff, 0x0904, 0x6a28, 0xa880, 0x9084, 0x00ff, 0x9086, + 0x0001, 0x1904, 0x6a28, 0x9186, 0x0003, 0x0904, 0x68c1, 0x9186, + 0x0005, 0x0904, 0x68c1, 0xa87c, 0xd0cc, 0x0904, 0x6a28, 0xa84f, + 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, + 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904, 0x6bf6, 0x0e04, + 0x6c41, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, + 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11e6, 0x2071, 0x1800, 0x2011, 0x0001, + 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e, 0x70bc, + 0x9200, 0x70be, 0x080c, 0x816f, 0x002e, 0x00ee, 0x0005, 0x0096, + 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e, + 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x190e, + 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x69ac, 0x782c, 0x908c, + 0x0780, 0x190c, 0x6d6a, 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, + 0x0002, 0x68df, 0x69ac, 0x6903, 0x6949, 0x080c, 0x0df6, 0x2071, + 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, 0x19d5, + 0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, + 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, + 0x080c, 0x816f, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, + 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, + 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0218, 0x7022, + 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, + 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, + 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x2071, 0x19d5, 0x7044, 0x9005, + 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, + 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x1d60, 0x00ee, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x1198, 0x009e, + 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19d5, 0x7044, + 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, + 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, + 0x900d, 0x1168, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320, 0x2001, + 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, + 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, + 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, + 0xa804, 0x900d, 0x1904, 0x6a00, 0x782c, 0x9094, 0x0780, 0x190c, + 0x6d6a, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, + 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, + 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x0d68, 0x782c, 0x9094, + 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, + 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, + 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, + 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320, + 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, + 0x080c, 0x816f, 0x00ee, 0x0804, 0x69bc, 0xa868, 0xd0fc, 0x1904, + 0x6a76, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fe9, + 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6a76, 0x00e6, 0x0026, + 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, 0x70e8, + 0x8001, 0x0558, 0x1a04, 0x6a73, 0x2071, 0x190e, 0xa803, 0x0000, + 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, + 0x1904, 0x6b72, 0x782c, 0x908c, 0x0780, 0x190c, 0x6d6a, 0x8004, + 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6a77, 0x6b72, 0x6a92, + 0x6b03, 0x080c, 0x0df6, 0x2009, 0x1923, 0x2104, 0x0002, 0x6a3e, + 0x6a3e, 0x6a3e, 0x68ca, 0x6a3e, 0x68ca, 0x70eb, 0x0fa0, 0x71e4, + 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x70e6, + 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, + 0x9205, 0x20d0, 0x0808, 0x70ea, 0x0804, 0x6a34, 0x0005, 0x2071, + 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, + 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, + 0x816f, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, + 0x1904, 0x6af2, 0x7830, 0x8007, 0x908c, 0x001f, 0x70ec, 0x9102, + 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, + 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, + 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x0e04, + 0x6ae9, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, + 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x191f, 0x200c, 0xc184, + 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11e6, 0x2001, 0x1920, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x2001, 0x191f, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, + 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, + 0x816f, 0x0804, 0x6aa5, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, + 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, + 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, + 0x1d60, 0x00ee, 0x0e04, 0x6b45, 0x7838, 0x7938, 0x910e, 0x1de0, + 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, + 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11e6, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, + 0x6d6a, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, + 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, + 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, + 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, + 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1904, 0x6be1, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, + 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, + 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x0d50, 0x782c, + 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x05b8, 0x00e6, 0x7824, + 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, + 0x8000, 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, + 0x6d6a, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6bda, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x11e6, 0x704b, 0x0000, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, + 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, + 0x70be, 0x080c, 0x816f, 0x00ee, 0x0804, 0x6b82, 0x2071, 0x190e, + 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1128, 0x1e04, 0x6c21, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, + 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, 0x0e04, + 0x6c0b, 0x2071, 0x190e, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, + 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, + 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11e6, 0x2071, 0x190e, 0x080c, 0x6d56, 0x002e, 0x00ee, + 0x0005, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, + 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, + 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071, + 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, + 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, 0x0103, + 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, 0x20a0, + 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, 0xa87a, + 0xa982, 0x0005, 0x2071, 0x190e, 0x7004, 0x0002, 0x6c8e, 0x6c8f, + 0x6d55, 0x6c8f, 0x6c8c, 0x6d55, 0x080c, 0x0df6, 0x0005, 0x2001, + 0x1923, 0x2004, 0x0002, 0x6c99, 0x6c99, 0x6cee, 0x6cef, 0x6c99, + 0x6cef, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6d75, 0x701c, 0x904d, + 0x01e0, 0xa84c, 0x9005, 0x01d8, 0x0e04, 0x6cbd, 0xa94c, 0x2071, + 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, + 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11e6, 0x2071, 0x190e, 0x080c, 0x6d56, 0x012e, 0x0470, 0x2001, + 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x2071, + 0x190e, 0x1510, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964, 0x9184, + 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, + 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, + 0x2071, 0x190e, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, + 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, + 0x2008, 0x2069, 0x19d5, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, + 0x0003, 0x0540, 0x2001, 0x1814, 0x2004, 0x2009, 0x1aa2, 0x210c, + 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, + 0x6838, 0x9106, 0x0190, 0x0e04, 0x6d21, 0x2069, 0x0000, 0x6837, + 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x11e6, 0x2069, 0x19d5, 0x6847, + 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6de0, + 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, + 0x15c9, 0xd09c, 0x1500, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964, + 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, + 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, + 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, + 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, + 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1069, 0x0005, + 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x6d6c, 0x0006, 0x0016, + 0x2001, 0x8004, 0x0006, 0x0804, 0x0dff, 0x0096, 0x00f6, 0x2079, + 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11e6, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, + 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, + 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, + 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, + 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, + 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x7838, + 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, + 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11e6, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, + 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, + 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, + 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11e6, 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, + 0x190c, 0x6d6a, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, + 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, + 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, + 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1923, 0x6808, + 0x690a, 0x2069, 0x19d5, 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, + 0x2001, 0x1924, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x7094, 0x908a, 0x002a, 0x1a0c, 0x0df6, 0x9082, 0x001d, 0x001b, + 0x6027, 0x1e00, 0x0005, 0x6f21, 0x6e8e, 0x6eaa, 0x6ed4, 0x6f10, + 0x6f50, 0x6f62, 0x6eaa, 0x6f38, 0x6e49, 0x6e77, 0x6efa, 0x6e48, + 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, + 0x9005, 0x1518, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, + 0x080c, 0x72cd, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x7097, + 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, + 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f, 0x080c, + 0x1977, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, + 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, + 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x080c, 0x7369, + 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, + 0x0090, 0x080c, 0x2b6f, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, + 0x6fcf, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x7097, + 0x0020, 0x080c, 0x6fcf, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, + 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2b6f, 0x6124, 0xd1cc, + 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, + 0x080c, 0x19a4, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, + 0x71aa, 0x2001, 0x0080, 0x080c, 0x2b6f, 0x7097, 0x0029, 0x0058, + 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097, 0x0020, + 0x0010, 0x7097, 0x001f, 0x0005, 0x080c, 0x19a4, 0x60e3, 0x0001, + 0x600c, 0xc0b4, 0x600e, 0x080c, 0x71aa, 0x2001, 0x0080, 0x080c, + 0x2b6f, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, + 0x9184, 0x1e00, 0x1118, 0x7097, 0x0029, 0x0058, 0x7097, 0x0028, + 0x0040, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, + 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, + 0x1130, 0x9184, 0x1e00, 0x1158, 0x7097, 0x0029, 0x0040, 0x7097, + 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f, 0x0005, + 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x6124, 0xd1dc, 0x1138, 0xd1e4, + 0x0138, 0x080c, 0x19a4, 0x7097, 0x001e, 0x0010, 0x7097, 0x001d, + 0x0005, 0x080c, 0x7052, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x6fcf, + 0x0016, 0x080c, 0x19a4, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, + 0x7097, 0x001e, 0x0020, 0x7097, 0x001f, 0x080c, 0x6fcf, 0x0005, + 0x0006, 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x000e, 0x6124, 0xd1d4, + 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x7097, + 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x0021, 0x0005, + 0x080c, 0x7052, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, + 0x0140, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, + 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2b6f, 0x000e, + 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, + 0x0158, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097, + 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, + 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, + 0x2091, 0x8000, 0x080c, 0x717e, 0x11d8, 0x2001, 0x180c, 0x200c, + 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, 0x2a97, + 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x080c, + 0x747a, 0x080c, 0x5e2f, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, + 0x080c, 0x7198, 0x0150, 0x080c, 0x718f, 0x1138, 0x2001, 0x0001, + 0x080c, 0x2616, 0x080c, 0x7156, 0x00a0, 0x080c, 0x704f, 0x0178, + 0x2001, 0x0001, 0x080c, 0x2616, 0x7094, 0x9086, 0x001e, 0x0120, + 0x7094, 0x9086, 0x0022, 0x1118, 0x7097, 0x0025, 0x0010, 0x7097, + 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, + 0x2011, 0x6fe0, 0x080c, 0x832d, 0x002e, 0x0016, 0x0026, 0x2009, + 0x0064, 0x2011, 0x6fe0, 0x080c, 0x8324, 0x002e, 0x001e, 0x0005, + 0x00e6, 0x00f6, 0x0016, 0x080c, 0x961a, 0x2071, 0x1800, 0x080c, + 0x6f7d, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, + 0x961a, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, + 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, + 0x080c, 0x992d, 0x080c, 0x983b, 0x080c, 0x82d9, 0x0036, 0x901e, + 0x080c, 0x98b1, 0x003e, 0x60e3, 0x0000, 0x080c, 0xdbdb, 0x080c, + 0xdbf6, 0x2009, 0x0004, 0x080c, 0x2a9d, 0x080c, 0x2974, 0x2001, + 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x6fe0, 0x080c, + 0x832d, 0x080c, 0x7198, 0x0118, 0x9006, 0x080c, 0x2b6f, 0x080c, + 0x0b8f, 0x2001, 0x0001, 0x080c, 0x2616, 0x012e, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6, + 0x2011, 0x6fed, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1118, 0x7018, + 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, + 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8, + 0x2001, 0x00c0, 0x080c, 0x2b6f, 0x0156, 0x20a9, 0x002d, 0x1d04, + 0x705f, 0x2091, 0x6000, 0x1f04, 0x705f, 0x015e, 0x00d6, 0x2069, + 0x1800, 0x6898, 0x8001, 0x0220, 0x0118, 0x689a, 0x00de, 0x0005, + 0x689b, 0x0014, 0x68e4, 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001, + 0x1da8, 0x080c, 0x8339, 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, + 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x7489, 0x2001, + 0x1947, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, + 0x26e1, 0x9006, 0x080c, 0x2b6f, 0x080c, 0x5cee, 0x6027, 0xffff, + 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, + 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, + 0x1957, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, + 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7146, + 0x7097, 0x0022, 0x0040, 0x7097, 0x0021, 0x0028, 0x7097, 0x0023, + 0x0010, 0x7097, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, + 0x0001, 0x080c, 0x26e1, 0x0026, 0x080c, 0x9f70, 0x002e, 0x7000, + 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, + 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, + 0x0150, 0x012e, 0x015e, 0x080c, 0xc459, 0x0118, 0x9006, 0x080c, + 0x2b99, 0x0804, 0x7152, 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, + 0x080c, 0x2a97, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x1f04, 0x70de, 0x080c, 0x71d2, 0x012e, 0x015e, 0x080c, + 0x718f, 0x0538, 0x6044, 0x9005, 0x01f8, 0x2001, 0x0100, 0x2004, + 0x9086, 0x000a, 0x0158, 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, + 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, 0x71d2, + 0x9006, 0x8001, 0x1df0, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, + 0x0140, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, + 0x71d2, 0x080c, 0xc459, 0x0118, 0x9006, 0x080c, 0x2b99, 0x0016, + 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8, 0x2011, + 0x6fed, 0x080c, 0x82eb, 0x002e, 0x001e, 0x080c, 0x8166, 0x7034, + 0xc085, 0x7036, 0x2001, 0x1957, 0x2003, 0x0004, 0x080c, 0x6e30, + 0x080c, 0x718f, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100, + 0x080c, 0x747f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, + 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, + 0x817d, 0x080c, 0x816f, 0x080c, 0x7489, 0x2001, 0x1947, 0x2003, + 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x26e1, 0x9006, + 0x080c, 0x2b6f, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027, 0xffff, + 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, + 0x1956, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, + 0x54df, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, + 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, + 0x0006, 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, + 0x0005, 0x0006, 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0020, + 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, + 0x0013, 0x0168, 0x0020, 0x080c, 0x2701, 0x900e, 0x0010, 0x2009, + 0x0002, 0x2019, 0x0028, 0x080c, 0x3060, 0x9006, 0x0019, 0x001e, + 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, + 0xc452, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, + 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, + 0x6004, 0x0006, 0x6028, 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x0510, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, + 0x2000, 0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x71ed, 0x2091, + 0x6000, 0x1f04, 0x71ed, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, + 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, + 0x0040, 0x602f, 0x0000, 0x00a0, 0x080c, 0x2ba9, 0x080c, 0x2bdc, + 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, + 0x20a9, 0x0002, 0x080c, 0x2a78, 0x0026, 0x6027, 0x0040, 0x002e, + 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, + 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x26e1, + 0x2001, 0x00a0, 0x0006, 0x080c, 0xc459, 0x000e, 0x0130, 0x080c, + 0x2b8d, 0x9006, 0x080c, 0x2b99, 0x0010, 0x080c, 0x2b6f, 0x000e, + 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x29f1, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, + 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001, + 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x72bf, 0x2001, 0x180c, + 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027, + 0x0200, 0x2001, 0x0090, 0x080c, 0x2b6f, 0x20a9, 0x0366, 0x6024, + 0xd0cc, 0x1518, 0x1d04, 0x726f, 0x2091, 0x6000, 0x1f04, 0x726f, + 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, + 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2001, 0x00a0, 0x080c, + 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c, 0xc459, 0x0110, + 0x080c, 0x0d64, 0x9085, 0x0001, 0x0480, 0x080c, 0x19a4, 0x60e3, + 0x0000, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2, 0x2001, 0x0080, + 0x080c, 0x2b6f, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, 0x1e00, + 0x080c, 0x2a97, 0x6024, 0x910c, 0x0138, 0x1d04, 0x72a4, 0x2091, + 0x6000, 0x1f04, 0x72a4, 0x0820, 0x6028, 0x9085, 0x1e00, 0x602a, + 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, + 0xc459, 0x0110, 0x080c, 0x0d64, 0x9006, 0x00ee, 0x00de, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, + 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, + 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, + 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a54, 0x2d04, 0x8000, + 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, + 0x9005, 0x1904, 0x7332, 0x2001, 0x0088, 0x080c, 0x2b6f, 0x9006, + 0x60e2, 0x6886, 0x080c, 0x26e1, 0x2069, 0x0200, 0x6804, 0x9005, + 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, 0x602a, + 0x6027, 0x0400, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0026, + 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7314, 0x2091, 0x6000, + 0x1f04, 0x7314, 0x0804, 0x7361, 0x2069, 0x0140, 0x20a9, 0x0384, + 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2a97, 0x6024, 0x910c, + 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x7320, 0x2091, 0x6000, + 0x1f04, 0x7320, 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, + 0x080c, 0x992d, 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2001, + 0x00a0, 0x080c, 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085, + 0x0001, 0x00b8, 0x080c, 0x19a4, 0x2001, 0x0080, 0x080c, 0x2b6f, + 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887, + 0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2, + 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, + 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, + 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01c8, + 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, + 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2069, 0x0140, 0x2001, + 0x00a0, 0x080c, 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x0804, + 0x73fb, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102, + 0x080c, 0x6fd5, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c, 0x2b6f, + 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, + 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027, 0x0200, + 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0027, 0x7003, 0x0001, + 0x0804, 0x73fb, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2a97, + 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x73ba, + 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x81bd, 0x00ee, + 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19d5, 0x7078, + 0x00ee, 0x9005, 0x19f8, 0x00f8, 0x0026, 0x2011, 0x6fed, 0x080c, + 0x8259, 0x2011, 0x6fe0, 0x080c, 0x832d, 0x002e, 0x2069, 0x0140, + 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, + 0x6886, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2, 0x2001, 0x180c, + 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, + 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xc452, + 0x1904, 0x7468, 0x7130, 0xd184, 0x1170, 0x080c, 0x31ee, 0x0138, + 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214, 0xd2ac, 0x1120, 0x7030, + 0xd08c, 0x0904, 0x7468, 0x2011, 0x185c, 0x220c, 0x0438, 0x0016, + 0x2019, 0x000e, 0x080c, 0xd7af, 0x0156, 0x00b6, 0x20a9, 0x007f, + 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, + 0x63a3, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, + 0xd837, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8450, 0x001e, + 0x8108, 0x1f04, 0x7431, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, + 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3060, 0x001e, + 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a3, + 0x1110, 0x080c, 0x5e49, 0x8108, 0x1f04, 0x745e, 0x00be, 0x015e, + 0x080c, 0x19a4, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0x5e2f, + 0x080c, 0x709e, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, + 0x015e, 0x0005, 0x2001, 0x1957, 0x2003, 0x0001, 0x0005, 0x2001, + 0x1957, 0x2003, 0x0000, 0x0005, 0x2001, 0x1956, 0x2003, 0xaaaa, + 0x0005, 0x2001, 0x1956, 0x2003, 0x0000, 0x0005, 0x2071, 0x18f8, + 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x1050, 0x090c, 0x0df6, + 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x1050, 0x090c, 0x0df6, + 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, + 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, + 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, + 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, + 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, + 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, + 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, + 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, + 0x2102, 0x00d6, 0x2069, 0x18f8, 0x6807, 0x0001, 0x00de, 0x080c, + 0x7a7c, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, + 0x8003, 0x818d, 0x1f04, 0x74f0, 0x015e, 0x0005, 0x2079, 0x0040, + 0x2071, 0x18f8, 0x7004, 0x0002, 0x7506, 0x7507, 0x753f, 0x759a, + 0x76df, 0x7504, 0x7504, 0x7709, 0x080c, 0x0df6, 0x0005, 0x2079, + 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x7b08, 0xd0a4, 0x01f8, + 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, + 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, + 0x0003, 0x1168, 0x7004, 0x0002, 0x752f, 0x7509, 0x752f, 0x752d, + 0x752f, 0x752f, 0x752f, 0x752f, 0x752f, 0x080c, 0x759a, 0x782c, + 0xd09c, 0x090c, 0x7a7c, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, + 0x003b, 0x0c10, 0x080c, 0x75d0, 0x0c90, 0x00e3, 0x08e8, 0x0005, + 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75f2, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75dc, 0x75d0, 0x77e3, 0x75d0, + 0x75d0, 0x75d0, 0x75f2, 0x75d0, 0x75dc, 0x7824, 0x7865, 0x78ac, + 0x78c0, 0x75d0, 0x75d0, 0x75f2, 0x75dc, 0x75d0, 0x75d0, 0x76b3, + 0x796b, 0x7986, 0x75d0, 0x75f2, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x76a9, 0x7986, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x7606, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x7aac, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x75d0, 0x761a, 0x75d0, 0x75d0, 0x75d0, 0x75d0, + 0x75d0, 0x75d0, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, + 0x782c, 0x080c, 0x7aa5, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, + 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, + 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7a7c, 0x0005, 0x75d0, 0x75dc, + 0x77cf, 0x75d0, 0x75dc, 0x75d0, 0x75dc, 0x75dc, 0x75d0, 0x75dc, + 0x77cf, 0x75dc, 0x75dc, 0x75dc, 0x75dc, 0x75dc, 0x75d0, 0x75dc, + 0x77cf, 0x75d0, 0x75d0, 0x75dc, 0x75d0, 0x75d0, 0x75d0, 0x75dc, + 0x00e6, 0x2071, 0x18f8, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, + 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, + 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, + 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, + 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, + 0x1120, 0x7007, 0x0001, 0x0804, 0x7788, 0x7007, 0x0003, 0x7012, + 0x2900, 0x7016, 0x701a, 0x704b, 0x7788, 0x0005, 0xa864, 0x8007, + 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, + 0x77a3, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, + 0x77a3, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, + 0x1904, 0x75d8, 0x7007, 0x0001, 0x2009, 0x1833, 0x210c, 0x81ff, + 0x1904, 0x7680, 0xa99c, 0x9186, 0x00ff, 0x05e8, 0xa994, 0x9186, + 0x006f, 0x0188, 0x9186, 0x0074, 0x15b0, 0x0026, 0x2011, 0x0010, + 0x080c, 0x66ed, 0x002e, 0x0578, 0x0016, 0xa998, 0x080c, 0x6737, + 0x001e, 0x1548, 0x0400, 0x080c, 0x717e, 0x0140, 0xa897, 0x4005, + 0xa89b, 0x0016, 0x2001, 0x0030, 0x900e, 0x0438, 0x0026, 0x2011, + 0x8008, 0x080c, 0x66ed, 0x002e, 0x01b0, 0x0016, 0x0026, 0x0036, + 0xa998, 0xaaa0, 0xab9c, 0x918d, 0x8000, 0x080c, 0x6737, 0x003e, + 0x002e, 0x001e, 0x1140, 0xa897, 0x4005, 0xa89b, 0x4009, 0x2001, + 0x0030, 0x900e, 0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, + 0x0000, 0x080c, 0x6061, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, + 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6a22, 0x012e, 0x0ca0, + 0xa994, 0x9186, 0x0071, 0x0904, 0x762a, 0x9186, 0x0064, 0x0904, + 0x762a, 0x9186, 0x007c, 0x0904, 0x762a, 0x9186, 0x0028, 0x0904, + 0x762a, 0x9186, 0x0038, 0x0904, 0x762a, 0x9186, 0x0078, 0x0904, + 0x762a, 0x9186, 0x005f, 0x0904, 0x762a, 0x9186, 0x0056, 0x0904, + 0x762a, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, + 0x0860, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, + 0x0001, 0x0804, 0x799d, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040, + 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888, + 0x7012, 0x9082, 0x0401, 0x1a04, 0x75e0, 0xaab4, 0x928a, 0x0002, + 0x1a04, 0x75e0, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, + 0x2001, 0x7746, 0x0018, 0x9280, 0x773c, 0x2005, 0x7056, 0x7010, + 0x9015, 0x0904, 0x7727, 0x080c, 0x1050, 0x1118, 0x7007, 0x0004, + 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050, + 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008, + 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, + 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c, + 0x1134, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, + 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1069, 0x7014, + 0x2048, 0x0804, 0x75e0, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, + 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x76df, 0x7014, + 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, + 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, + 0x0904, 0x799d, 0x0804, 0x7788, 0x773e, 0x7742, 0x0002, 0x001d, + 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d, + 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050, + 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, + 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, + 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, + 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a, + 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e, + 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e, + 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005, + 0x2009, 0x1833, 0x210c, 0x81ff, 0x1178, 0x080c, 0x5eab, 0x1108, + 0x0005, 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc044, + 0x080c, 0x6a22, 0x012e, 0x0ca0, 0x080c, 0xc452, 0x1d70, 0x2001, + 0x0028, 0x900e, 0x0c70, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, + 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x5fc3, 0x1138, + 0x0005, 0x9006, 0xa87a, 0x080c, 0x5f3b, 0x1108, 0x0005, 0x0126, + 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6a22, 0x012e, 0x0cb0, + 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, + 0x2061, 0x1800, 0x60cc, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, + 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, + 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, + 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, + 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, + 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, + 0x9005, 0x11d8, 0xa974, 0x080c, 0x63a3, 0x11b8, 0x0066, 0xae80, + 0x080c, 0x64b3, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, + 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x63a3, 0x1110, 0x080c, + 0x65b3, 0x8108, 0x1f04, 0x780c, 0x00ce, 0xa87c, 0xd084, 0x1120, + 0x080c, 0x1069, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6a22, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x080c, 0x66c5, 0x0580, 0x2061, 0x1a4c, 0x6100, 0xd184, + 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, + 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, + 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, + 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, + 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, + 0x6202, 0x012e, 0x0804, 0x7a66, 0x012e, 0x0804, 0x7a60, 0x012e, + 0x0804, 0x7a5a, 0x012e, 0x0804, 0x7a5d, 0x0126, 0x2091, 0x8000, + 0x7007, 0x0001, 0x080c, 0x66c5, 0x05e0, 0x2061, 0x1a4c, 0x6000, + 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, + 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, + 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, + 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, + 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, + 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, + 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7a66, 0x012e, 0x0804, + 0x7a63, 0x012e, 0x0804, 0x7a60, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x2061, 0x1a4c, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, + 0x0220, 0x630a, 0x012e, 0x0804, 0x7a74, 0x012e, 0x0804, 0x7a63, + 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, + 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x9084, 0xfcff, + 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, + 0x0598, 0x2001, 0x1833, 0x2004, 0x9005, 0x0118, 0x080c, 0xa01c, + 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110, + 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xa068, 0xa988, 0x918c, + 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, + 0x080c, 0x8450, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a4c, + 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, + 0x012e, 0x00be, 0x0804, 0x7a66, 0x00ce, 0x012e, 0x00be, 0x0804, + 0x7a60, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, + 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, + 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, + 0x0029, 0x1d10, 0xa974, 0x080c, 0x63a3, 0x1968, 0xb800, 0xc0e4, + 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, + 0x1960, 0x2004, 0x601a, 0x0804, 0x78fb, 0xa88c, 0x9065, 0x0960, + 0x00e6, 0xa890, 0x9075, 0x2001, 0x1833, 0x2004, 0x9005, 0x0150, + 0x080c, 0xa01c, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xa01c, 0x00ee, + 0x0804, 0x78fb, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, + 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, + 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, + 0x00ee, 0x0804, 0x78fb, 0x2061, 0x1a4c, 0x6000, 0xd084, 0x0190, + 0xd08c, 0x1904, 0x7a74, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, + 0x0220, 0x6206, 0x012e, 0x0804, 0x7a74, 0x012e, 0xa883, 0x0016, + 0x0804, 0x7a6d, 0xa883, 0x0007, 0x0804, 0x7a6d, 0xa864, 0x8007, + 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, + 0x0005, 0x080c, 0x75d8, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, + 0x7016, 0x701a, 0x704b, 0x799d, 0x0005, 0x00b6, 0x00e6, 0x0126, + 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61cc, 0x81ff, 0x1904, + 0x7a1f, 0x6130, 0xd194, 0x1904, 0x7a49, 0xa878, 0x2070, 0x9e82, + 0x1cd0, 0x0a04, 0x7a13, 0x6064, 0x9e02, 0x1a04, 0x7a13, 0x7120, + 0x9186, 0x0006, 0x1904, 0x7a05, 0x7010, 0x905d, 0x0904, 0x7a1f, + 0xb800, 0xd0e4, 0x1904, 0x7a43, 0x2061, 0x1a4c, 0x6100, 0x9184, + 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7a4c, + 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, + 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7a4f, 0x080c, 0x54db, 0xd09c, + 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8370, 0x012e, + 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, + 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7a4f, 0x012e, 0x00ee, 0x00be, + 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7a6d, + 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x63a3, + 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, + 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, + 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, + 0x54df, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0, + 0x6064, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, + 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, + 0x9086, 0x0007, 0x1904, 0x79a9, 0x7003, 0x0002, 0x0804, 0x79a9, + 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, + 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, + 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd38f, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, + 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, + 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6a22, 0x012e, 0x0005, 0x080c, 0x1069, 0x0005, 0x00d6, + 0x080c, 0x8367, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, + 0x190c, 0x7b08, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70bc, 0x90ea, + 0x0040, 0x0278, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800, 0x702e, + 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, + 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, + 0x190c, 0x7b08, 0x000e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, + 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, + 0x7af9, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, + 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, + 0x04b0, 0x2b10, 0x080c, 0x9f94, 0x1118, 0x080c, 0xa03b, 0x05a8, + 0x6212, 0xa874, 0x0002, 0x7ad7, 0x7adc, 0x7adf, 0x7ae5, 0x2019, + 0x0002, 0x080c, 0xd7af, 0x0060, 0x080c, 0xd746, 0x0048, 0x2019, + 0x0002, 0xa980, 0x080c, 0xd761, 0x0018, 0xa980, 0x080c, 0xd746, + 0x080c, 0x9fea, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6a22, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, + 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, + 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, + 0x2091, 0x8000, 0x0e04, 0x7b0a, 0x0006, 0x0016, 0x2001, 0x8003, + 0x0006, 0x0804, 0x0dff, 0x2001, 0x1833, 0x2004, 0x9005, 0x0005, + 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, + 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, + 0x150f, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, + 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7b8a, 0x68bc, + 0x90aa, 0x0005, 0x0a04, 0x8166, 0x7d44, 0x7c40, 0x9584, 0x00f6, + 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, 0x1260, 0x9584, + 0x0700, 0x8007, 0x0804, 0x7b91, 0x7000, 0x9084, 0xff00, 0x9086, + 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084, + 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xdbb3, 0x080c, 0x809b, + 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x80f9, + 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x7bec, 0x080c, + 0x2165, 0x005e, 0x004e, 0x0020, 0x080c, 0xdbb3, 0x7817, 0x0140, + 0x080c, 0x717e, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, + 0x688f, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000, + 0x080c, 0x7bcd, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f, + 0x0005, 0x0002, 0x7ba3, 0x7ea3, 0x7b9a, 0x7b9a, 0x7b9a, 0x7b9a, + 0x7b9a, 0x7b9a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, + 0x090c, 0x8b8f, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000, + 0x810f, 0x9484, 0x0fff, 0x688e, 0x9286, 0x2000, 0x1150, 0x6800, + 0x9086, 0x0001, 0x1118, 0x080c, 0x5545, 0x0070, 0x080c, 0x7c0c, + 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x7ddb, 0x0028, 0x9286, + 0x8000, 0x1110, 0x080c, 0x7fc2, 0x7817, 0x0140, 0x2001, 0x19cb, + 0x2004, 0x9005, 0x090c, 0x8b8f, 0x0005, 0x2001, 0x1810, 0x2004, + 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1148, + 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4a17, 0x003e, + 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, + 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056, 0x00f6, + 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001, 0x1810, + 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, + 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4a17, 0x002e, 0x00fe, + 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084, + 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, + 0x7dac, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8060, 0x0904, 0x7dac, + 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, 0x9186, + 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7dac, 0x7124, 0x610a, + 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, 0xa068, + 0x0804, 0x7dac, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130, + 0x2009, 0x0015, 0x080c, 0xa068, 0x0804, 0x7dac, 0x908e, 0x0100, + 0x1904, 0x7dac, 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x0016, + 0x080c, 0xa068, 0x0804, 0x7dac, 0x9186, 0x0022, 0x1904, 0x7dac, + 0x7030, 0x908e, 0x0300, 0x1580, 0x68d8, 0xd0a4, 0x0528, 0xc0b5, + 0x68da, 0x7100, 0x918c, 0x00ff, 0x697a, 0x7004, 0x687e, 0x00f6, + 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, + 0x2008, 0x080c, 0x26b6, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, + 0x080c, 0x266d, 0x695a, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, + 0x2071, 0x1800, 0x70b2, 0x00ee, 0x7034, 0x9005, 0x1904, 0x7dac, + 0x2009, 0x0017, 0x0804, 0x7d5c, 0x908e, 0x0400, 0x1190, 0x7034, + 0x9005, 0x1904, 0x7dac, 0x080c, 0x717e, 0x0120, 0x2009, 0x001d, + 0x0804, 0x7d5c, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030, 0x0804, + 0x7d5c, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dac, + 0x2009, 0x0018, 0x0804, 0x7d5c, 0x908e, 0x2010, 0x1120, 0x2009, + 0x0019, 0x0804, 0x7d5c, 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, + 0x0804, 0x7d5c, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, + 0x7dac, 0x2009, 0x001b, 0x0804, 0x7d5c, 0x908e, 0x5000, 0x1140, + 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x001c, 0x0804, 0x7d5c, + 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7d5c, 0x908e, + 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x0024, + 0x0804, 0x7d5c, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, 0x2009, + 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7d5c, 0x080c, + 0xcb61, 0x1904, 0x7dac, 0x0804, 0x7d5a, 0x908c, 0xff00, 0x918e, + 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7d5c, 0x908e, 0x0f00, + 0x1120, 0x2009, 0x0020, 0x0804, 0x7d5c, 0x908e, 0x6104, 0x1528, + 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, 0x0004, + 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, + 0x2124, 0x080c, 0x4a17, 0x004e, 0x8108, 0x0f04, 0x7d28, 0x9186, + 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58, + 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e, 0x6000, 0x1118, + 0x2009, 0x003f, 0x0448, 0x908e, 0x7800, 0x1118, 0x2009, 0x0045, + 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, + 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, + 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, 0xff00, 0x918e, + 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, 0x001d, 0x6838, + 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, 0x0263, 0x2204, + 0x8211, 0x220c, 0x080c, 0x266d, 0x1904, 0x7daf, 0x080c, 0x6343, + 0x1904, 0x7daf, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c, 0x717e, + 0x01c0, 0x68d8, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff, 0x1188, + 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x6878, 0x9606, 0x1148, + 0x687c, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff, 0xb8b2, + 0x0080, 0xb8b0, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150, 0x6878, + 0x9606, 0x1138, 0x687c, 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, + 0x0098, 0x080c, 0x9f94, 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004, + 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a, + 0x0016, 0x001e, 0x080c, 0xa068, 0x00ce, 0x00be, 0x0005, 0x001e, + 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x4a17, 0x080c, 0xa03b, 0x0d90, 0x2b08, 0x6112, 0x6023, + 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017, 0x0118, + 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900, 0x0020, + 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, + 0x080c, 0x8640, 0x08a0, 0x080c, 0x8185, 0x1158, 0x080c, 0x31b8, + 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008, 0x1108, + 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, + 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8060, 0x0904, 0x7e3b, + 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034, 0x9005, + 0x15d0, 0x2009, 0x0015, 0x080c, 0xa068, 0x04a8, 0x908e, 0x0100, + 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, 0x080c, 0xa068, + 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, 0x1400, 0x1518, + 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, + 0x080c, 0x266d, 0x11b8, 0x080c, 0x6343, 0x11a0, 0xbe12, 0xbd16, + 0x080c, 0x9f94, 0x0178, 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023, + 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xa068, 0x080c, 0x8b8f, + 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005, 0x00b6, + 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff, 0x11b8, + 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009, 0x007f, + 0x0804, 0x7e9d, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, + 0x7e9d, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0, 0x2011, + 0x0000, 0x2019, 0x1836, 0x231c, 0xd3ac, 0x0130, 0x9026, 0x20a9, + 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, 0x077f, + 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff, 0x11d0, + 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10, 0x2600, + 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0, 0x9745, + 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118, 0x94c6, + 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x7e72, 0x82ff, 0x1118, + 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee, + 0x004e, 0x00be, 0x0005, 0x2001, 0x1836, 0x200c, 0x9184, 0x0080, + 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, 0x810f, 0x9184, + 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, + 0x090c, 0x8b8f, 0x0005, 0x7ecb, 0x7ecb, 0x7ecb, 0x8072, 0x7ecb, + 0x7ed4, 0x7eff, 0x7f8d, 0x7ecb, 0x7ecb, 0x7ecb, 0x7ecb, 0x7ecb, + 0x7ecb, 0x7ecb, 0x7ecb, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, + 0x9005, 0x090c, 0x8b8f, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, + 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a, 0x1cd0, 0x02a8, + 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, + 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, + 0x610a, 0x2009, 0x0046, 0x080c, 0xa068, 0x7817, 0x0140, 0x2001, + 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f, 0x00be, 0x0005, 0x00b6, + 0x00c6, 0x9484, 0x0fff, 0x0904, 0x7f63, 0x7110, 0xd1bc, 0x1904, + 0x7f63, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, + 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x31f3, 0x200d, 0x918c, + 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x7f63, 0x080c, + 0x6343, 0x1904, 0x7f63, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15d8, + 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c, 0x9f94, + 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, 0x6112, 0x6023, + 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, 0x0044, 0x080c, + 0xcdd7, 0x0408, 0x080c, 0x66c9, 0x1138, 0xb807, 0x0606, 0x0c30, + 0x190c, 0x7e3f, 0x11c0, 0x0898, 0x080c, 0x9f94, 0x2b08, 0x0198, + 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400, 0x1118, + 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, + 0x8640, 0x080c, 0x8b8f, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, + 0x9005, 0x090c, 0x8b8f, 0x00ce, 0x00be, 0x0005, 0x2001, 0x180e, + 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a17, 0x080c, + 0xa03b, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, + 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007, 0x0041, + 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x08b0, 0x00b6, 0x7110, 0xd1bc, + 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0, 0x9c82, 0x1cd0, + 0x02a8, 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, + 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, + 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xa068, 0x7817, 0x0140, + 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f, 0x00be, 0x0005, + 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110, 0x9085, + 0x0001, 0x0005, 0x080c, 0x8185, 0x1180, 0x080c, 0x31b8, 0x1168, + 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130, 0x9184, + 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x7fdc, 0x7fdd, + 0x7fdc, 0x7fdc, 0x8042, 0x8051, 0x0005, 0x00b6, 0x700c, 0x7108, + 0x080c, 0x266d, 0x1904, 0x8040, 0x080c, 0x6343, 0x1904, 0x8040, + 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084, 0x1120, + 0xb800, 0xd0bc, 0x1904, 0x8040, 0x080c, 0x66c9, 0x0148, 0x9086, + 0x0004, 0x0130, 0x080c, 0x66d1, 0x0118, 0x9086, 0x0004, 0x1588, + 0x00c6, 0x080c, 0x8060, 0x00ce, 0x05d8, 0x080c, 0x9f94, 0x2b08, + 0x05b8, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0002, 0x7120, 0x610a, + 0x2009, 0x0088, 0x080c, 0xa068, 0x0458, 0x080c, 0x66c9, 0x0148, + 0x9086, 0x0004, 0x0130, 0x080c, 0x66d1, 0x0118, 0x9086, 0x0004, + 0x1180, 0x080c, 0x9f94, 0x2b08, 0x01d8, 0x6112, 0x080c, 0xc1ca, + 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xa068, + 0x0078, 0x080c, 0x9f94, 0x2b08, 0x0158, 0x6112, 0x080c, 0xc1ca, + 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0xa068, + 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c, + 0x7fb8, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0xa068, + 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, 0x7fb8, + 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xa068, 0x0005, + 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, 0x1cd0, 0x0240, + 0x2001, 0x1819, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, 0x0005, + 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, 0x2060, + 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298, 0x6864, 0x9c02, + 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, + 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, 0x0051, 0x080c, + 0xa068, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, + 0x8b8f, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005, 0x2031, + 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005, 0x2031, + 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084, + 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0x9f94, 0x05b8, 0x0066, + 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, + 0x266d, 0x15a0, 0x080c, 0x6343, 0x1588, 0xbe12, 0xbd16, 0x2b00, + 0x004e, 0x00ce, 0x6012, 0x080c, 0xc1ca, 0x080c, 0x1037, 0x0510, + 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8, + 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0, + 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, 0x6023, 0x0001, + 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00fe, 0x009e, + 0x00ce, 0x0005, 0x080c, 0x9fea, 0x006e, 0x0cc0, 0x004e, 0x00ce, + 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, 0xf000, 0x810f, + 0x9086, 0x2000, 0x1904, 0x8150, 0x9186, 0x0022, 0x15f0, 0x2001, + 0x0111, 0x2004, 0x9005, 0x1904, 0x8152, 0x7030, 0x908e, 0x0400, + 0x0904, 0x8152, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0, + 0x908e, 0x0300, 0x11d8, 0x2009, 0x1836, 0x210c, 0xd18c, 0x1590, + 0xd1a4, 0x1580, 0x080c, 0x6687, 0x0588, 0x68ac, 0x9084, 0x00ff, + 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x687c, 0x69ac, 0x918c, + 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009, 0x0103, + 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e, 0x0500, + 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023, 0x1140, + 0x080c, 0x8060, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, 0x0000, + 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030, 0x908e, + 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1836, 0x2004, + 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 0x00f6, 0x2079, + 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005, 0x00f6, + 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, 0x0200, 0x7800, + 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x1800, + 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001, 0x1836, + 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006, 0x001e, + 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19d5, 0x7003, 0x0003, + 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, 0x7017, 0x1cd0, + 0x7007, 0x0000, 0x7026, 0x702b, 0x9630, 0x7032, 0x7037, 0x9698, + 0x7047, 0xffff, 0x704a, 0x704f, 0x536d, 0x7052, 0x7063, 0x82f4, + 0x080c, 0x1050, 0x090c, 0x0df6, 0x2900, 0x7042, 0xa867, 0x0003, + 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19d5, 0x1d04, + 0x8248, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1510, 0x2001, + 0x187d, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, + 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0df6, 0x700f, + 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c, 0x8339, + 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c, 0x080f, + 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, + 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, + 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, + 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, 0x702f, + 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, 0x9716, + 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310, 0x8001, + 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052, 0x1148, + 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156, 0x7060, + 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d, 0x0158, + 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109, 0x717a, + 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138, + 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e, + 0x7004, 0x0002, 0x8270, 0x8271, 0x828d, 0x00e6, 0x2071, 0x19d5, + 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, + 0x0005, 0x00e6, 0x0006, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1120, + 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x00e6, + 0x2071, 0x19d5, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005, + 0x0005, 0x00b6, 0x7110, 0x080c, 0x63a3, 0x1168, 0xb888, 0x8001, + 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, + 0x8b8f, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e, + 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126, + 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110, + 0x080c, 0xc05b, 0x6018, 0x9005, 0x0528, 0x8001, 0x601a, 0x1510, + 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x11c8, 0x080c, + 0xbd4e, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, + 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, + 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, + 0x080c, 0xba50, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x1819, + 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005, + 0x00e6, 0x2071, 0x19d5, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, + 0x0005, 0x2001, 0x19de, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, + 0x19d5, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x19e1, + 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x711a, 0x721e, + 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000, + 0x705e, 0x2001, 0x19e5, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, + 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e, + 0x080c, 0x1134, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, + 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, + 0x81bd, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, + 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x717a, + 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, + 0x19d5, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee, + 0x0005, 0x2069, 0x1800, 0x69e4, 0xd1e4, 0x1518, 0x0026, 0xd1ec, + 0x0140, 0x6a50, 0x6870, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0, + 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, + 0x69e6, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106, + 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68e6, 0x080c, 0x0f17, + 0x002e, 0x0005, 0x00c6, 0x2061, 0x1a4c, 0x00ce, 0x0005, 0x9184, + 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a4c, 0x2060, 0x0005, + 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, + 0x1a4c, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, + 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, + 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x83fa, 0xd0b4, + 0x1168, 0xd0bc, 0x1904, 0x83d3, 0x2009, 0x0006, 0x080c, 0x8427, + 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160, + 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8421, 0x908c, + 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, + 0x187d, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, + 0x0804, 0xa068, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, + 0xa068, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, + 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, + 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, + 0x918e, 0x0003, 0x1904, 0x8421, 0x908c, 0x2020, 0x918e, 0x2020, + 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x007e, + 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xa068, 0x0005, 0x6110, + 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, + 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, + 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, + 0x2009, 0x0041, 0x080c, 0xa068, 0x0005, 0x00b9, 0x0ce8, 0x87ff, + 0x1dd8, 0x2009, 0x0043, 0x080c, 0xa068, 0x0cb0, 0x6110, 0x00b6, + 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, + 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, + 0x080c, 0xbd4e, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, + 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, + 0x1158, 0x00c6, 0x2061, 0x1a4c, 0x6200, 0xd28c, 0x1120, 0x6204, + 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6861, 0x6014, 0x904d, + 0x0076, 0x2039, 0x0000, 0x190c, 0x8370, 0x007e, 0x009e, 0x0005, + 0x0156, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x81ff, 0x0110, 0x9205, + 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, + 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, + 0x9006, 0x8004, 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x8472, + 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, + 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a, + 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x8489, + 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x8489, 0x0006, 0x3200, + 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, + 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, + 0x2079, 0x19c2, 0x012e, 0x00d6, 0x2069, 0x19c2, 0x6803, 0x0005, + 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, + 0x9df2, 0x0401, 0x080c, 0x9ddd, 0x00e9, 0x080c, 0x9de0, 0x00d1, + 0x080c, 0x9de3, 0x00b9, 0x080c, 0x9de6, 0x00a1, 0x080c, 0x9de9, + 0x0089, 0x080c, 0x9dec, 0x0071, 0x080c, 0x9def, 0x0059, 0x01de, + 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, 0x206a, + 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, + 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, 0x0007, + 0x0002, 0x84f3, 0x8517, 0x8558, 0x84f9, 0x8517, 0x84f3, 0x84f1, + 0x84f1, 0x080c, 0x0df6, 0x080c, 0x82d9, 0x080c, 0x8b8f, 0x00ce, + 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x5c98, + 0x080c, 0x8259, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, 0x782a, + 0x080c, 0x5cd8, 0x0c88, 0x62c0, 0x080c, 0x9df6, 0x080c, 0x5c98, + 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, 0x080c, + 0x82d9, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, 0x0000, + 0x7824, 0x9065, 0x090c, 0x0df6, 0x2009, 0x0013, 0x080c, 0xa068, + 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0df6, 0x7828, + 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x29e9, + 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0df6, + 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x8b8f, 0x0c00, + 0x080c, 0x95f6, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0x9df6, + 0x080c, 0xdbf0, 0x2009, 0x0014, 0x080c, 0xa068, 0x00ce, 0x0880, + 0x2001, 0x19de, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, + 0x0000, 0x7824, 0x9065, 0x090c, 0x0df6, 0x2009, 0x0013, 0x080c, + 0xa0ba, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005, + 0x090c, 0x0df6, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a, + 0x00de, 0x00ce, 0x00be, 0x080c, 0x29e9, 0x02f0, 0x00b6, 0x00c6, + 0x00d6, 0x781c, 0x905d, 0x090c, 0x0df6, 0xb800, 0xc0dc, 0xb802, + 0x7924, 0x2160, 0x080c, 0x9fea, 0xb93c, 0x81ff, 0x090c, 0x0df6, + 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, + 0x00be, 0x080c, 0x8b8f, 0x0868, 0x080c, 0x95f6, 0x0850, 0x2011, + 0x0130, 0x2214, 0x080c, 0x9df6, 0x080c, 0xdbf0, 0x7824, 0x9065, + 0x2009, 0x0014, 0x080c, 0xa068, 0x00de, 0x00ce, 0x00be, 0x0804, + 0x8569, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1d00, + 0x6024, 0x6027, 0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4, 0x9205, + 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0xa068, + 0x00ce, 0x0005, 0x2011, 0x19e1, 0x2013, 0x0000, 0x0cc8, 0x793c, + 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x12f0, 0x8108, 0x7946, + 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, + 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10, 0x6014, 0x9084, + 0x1984, 0x9085, 0x0016, 0x6016, 0x08d8, 0x793c, 0x2160, 0x2009, + 0x004a, 0x080c, 0xa068, 0x08a0, 0x7848, 0xc085, 0x784a, 0x0880, + 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6010, 0x9005, + 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, + 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x19c2, + 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086, 0x0001, + 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, 0x8b8f, 0x00de, 0x0005, + 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b, 0x0000, + 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e, 0x2069, + 0x19c2, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e, 0x08d8, + 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6008, 0x9005, + 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, + 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x19c2, 0x6034, 0x9005, 0x0130, 0x9080, 0x0003, + 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce, 0x0005, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, + 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, + 0x19c2, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, + 0x86ec, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x86e7, 0x87ff, + 0x0120, 0x6054, 0x9106, 0x1904, 0x86e7, 0x703c, 0x9c06, 0x1178, + 0x0036, 0x2019, 0x0001, 0x080c, 0x98b1, 0x7033, 0x0000, 0x9006, + 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001, 0x7038, + 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x080c, 0xbd4e, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, + 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a7f, 0xa867, + 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, + 0xc044, 0x080c, 0xdae1, 0x080c, 0x6a22, 0x007e, 0x003e, 0x001e, + 0x080c, 0xbf39, 0x080c, 0xa01c, 0x00ce, 0x0804, 0x8686, 0x2c78, + 0x600c, 0x2060, 0x0804, 0x8686, 0x85ff, 0x0120, 0x0036, 0x080c, + 0x8c6c, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, + 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, + 0x080c, 0xdae1, 0x080c, 0xd7e2, 0x007e, 0x003e, 0x001e, 0x0890, + 0x6020, 0x9086, 0x000a, 0x0904, 0x86d1, 0x0804, 0x86ca, 0x0006, + 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, + 0x8000, 0x2079, 0x19c2, 0x7838, 0x9065, 0x0904, 0x876c, 0x600c, + 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019, + 0x0001, 0x080c, 0x98b1, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42, + 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbd4e, 0x0548, 0x6014, 0x2048, + 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, 0x1188, + 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1962, 0x2004, 0x6042, + 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a7f, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c, + 0xa01c, 0x000e, 0x0804, 0x8724, 0x7e3a, 0x7e36, 0x012e, 0x00fe, + 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, + 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c50, 0x6020, 0x9086, 0x000a, + 0x09f8, 0x08b8, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c, + 0x886d, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, + 0x19c2, 0x2091, 0x8000, 0x080c, 0x8904, 0x080c, 0x8994, 0x012e, + 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, + 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, + 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x8832, 0x6010, 0x2058, + 0xb8a0, 0x9206, 0x1904, 0x882d, 0x88ff, 0x0120, 0x6054, 0x9106, + 0x1904, 0x882d, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820, + 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82d9, 0x080c, 0x961a, + 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, + 0x0804, 0x882d, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, + 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, + 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xbf56, 0x1118, + 0x080c, 0xa9a7, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, + 0x0016, 0x0036, 0x0086, 0x080c, 0xc044, 0x080c, 0xdae1, 0x080c, + 0x6a22, 0x008e, 0x003e, 0x001e, 0x080c, 0xbf39, 0x080c, 0xa01c, + 0x080c, 0x9955, 0x00ce, 0x0804, 0x87ab, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x87ab, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, + 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, + 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xdae1, 0x080c, 0xd7e2, + 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xa9a7, 0x6020, 0x9086, + 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, + 0x8813, 0x9086, 0x008b, 0x0904, 0x8813, 0x0840, 0x6020, 0x9086, + 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, + 0x9086, 0x008b, 0x09b0, 0x0804, 0x8826, 0x00b6, 0x00a6, 0x0096, + 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, + 0x905d, 0x0904, 0x88fd, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, + 0x19c2, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06, + 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858, + 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a, + 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802, + 0x080c, 0x62d6, 0x0904, 0x88f9, 0x7624, 0x86ff, 0x0904, 0x88e8, + 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100, + 0x68c0, 0x9005, 0x0560, 0x080c, 0x82d9, 0x080c, 0x961a, 0x68c3, + 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, + 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, + 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, + 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110, + 0x8001, 0xb83e, 0x2660, 0x080c, 0xa01c, 0x00ce, 0x0048, 0x00de, + 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x88a0, + 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, + 0xc044, 0x080c, 0xdae1, 0x080c, 0x6a22, 0x080c, 0x9955, 0x0804, + 0x88a0, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, + 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, + 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x8967, 0x600c, 0x0006, + 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, + 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82d9, 0x080c, 0x961a, + 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7827, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x667f, 0x1520, + 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, + 0xbd4c, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xbf56, + 0x1118, 0x080c, 0xa9a7, 0x0060, 0x080c, 0x667f, 0x1168, 0xa867, + 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39, + 0x080c, 0xa01c, 0x080c, 0x9955, 0x000e, 0x0804, 0x890b, 0x7e16, + 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, + 0x9086, 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c50, 0x080c, 0xa9a7, + 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, + 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, + 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, + 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6, + 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x8a14, 0xb854, 0x0006, + 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, + 0x62d6, 0x0904, 0x8a11, 0x7e24, 0x86ff, 0x0904, 0x8a04, 0x9680, + 0x0005, 0x2004, 0x9906, 0x1904, 0x8a04, 0x00d6, 0x2069, 0x0100, + 0x68c0, 0x9005, 0x0904, 0x89fb, 0x080c, 0x82d9, 0x080c, 0x961a, + 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7827, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e, + 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c, + 0x81ff, 0x1518, 0x2009, 0x1962, 0x210c, 0x2102, 0x00f0, 0xb83c, + 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c, + 0xa01c, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, + 0x630a, 0x00ce, 0x0804, 0x89a7, 0x89ff, 0x0138, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a22, 0x080c, 0x9955, 0x0804, + 0x89a7, 0x000e, 0x0804, 0x899b, 0x781e, 0x781a, 0x00de, 0x00ce, + 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, + 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878, + 0x9606, 0x1170, 0x2071, 0x19c2, 0x7024, 0x9035, 0x0148, 0x9080, + 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029, + 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, + 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, + 0x00ce, 0x04b8, 0x080c, 0x961a, 0x78c3, 0x0000, 0x080c, 0x9a7f, + 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, + 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, + 0x9a7f, 0x003e, 0x080c, 0x62d6, 0x00c6, 0xb83c, 0x9005, 0x0110, + 0x8001, 0xb83e, 0x2660, 0x080c, 0x9fea, 0x00ce, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0xc044, 0x080c, 0x6a22, 0x080c, + 0x9955, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101, + 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202, + 0x2071, 0x19c2, 0x7004, 0x9084, 0x0007, 0x0002, 0x8aa0, 0x8aa4, + 0x8ac2, 0x8aeb, 0x8b29, 0x8aa0, 0x8abb, 0x8a9e, 0x080c, 0x0df6, + 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020, + 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000, + 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, + 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, + 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x62d6, 0xb800, 0xc0dc, + 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022, + 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee, + 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x8b8f, + 0x0ca8, 0x7218, 0x721e, 0x080c, 0x8b8f, 0x0c80, 0xc2ec, 0x2202, + 0x080c, 0x8c6c, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06, + 0x1160, 0x080c, 0x9955, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f, + 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160, + 0x080c, 0x9955, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000, + 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198, + 0x6010, 0x2058, 0x080c, 0x62d6, 0xb800, 0xc0dc, 0xb802, 0x080c, + 0x9955, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e, + 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, + 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0x9955, 0x600c, 0x9015, + 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, + 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6, + 0x2069, 0x19c2, 0x6830, 0x9084, 0x0003, 0x0002, 0x8b4c, 0x8b4e, + 0x8b72, 0x8b4a, 0x080c, 0x0df6, 0x00de, 0x0005, 0x00c6, 0x6840, + 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015, + 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, + 0x2011, 0x19e1, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, + 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003, + 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c, + 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000, + 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de, + 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001, + 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x8c6c, + 0x2001, 0x19ce, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069, + 0x19c2, 0x6804, 0x9084, 0x0007, 0x0002, 0x8baf, 0x8c54, 0x8c54, + 0x8c54, 0x8c54, 0x8c56, 0x8c54, 0x8bad, 0x080c, 0x0df6, 0x6820, + 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, 0x0150, + 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x8cc3, 0x00ce, + 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, 0x6826, + 0x682b, 0x0000, 0x080c, 0x8cc3, 0x00ce, 0x00de, 0x0005, 0x00b6, + 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x8c3e, 0xb84c, 0x900d, + 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, 0x920e, + 0x0904, 0x8c3e, 0x0028, 0x6818, 0x920e, 0x0904, 0x8c3e, 0x2058, + 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, 0x681e, + 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0x9fc1, 0x0904, 0x8c3e, + 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148, 0xa880, + 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e, 0x908a, + 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0x9318, + 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, 0x00ff, + 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100, 0xbab0, + 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0x923f, 0x2069, + 0x19c2, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18, 0x6b26, + 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, + 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee, 0x00be, + 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820, 0x8001, + 0x6822, 0x682b, 0x0000, 0x080c, 0x62d6, 0x080c, 0x9e16, 0x00ee, + 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6, 0x680c, + 0x9065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, + 0x8cc3, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed, + 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x19c2, + 0x6830, 0x9086, 0x0000, 0x1548, 0x2001, 0x180c, 0x2014, 0xd2e4, + 0x0130, 0xc2e4, 0x2202, 0x080c, 0x8b9e, 0x2069, 0x19c2, 0x2001, + 0x180c, 0x200c, 0xd1c4, 0x11e0, 0x6838, 0x907d, 0x01b0, 0x6a04, + 0x9296, 0x0000, 0x1568, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, + 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, + 0x1b0a, 0x1158, 0x012e, 0x080c, 0x9477, 0x00de, 0x00fe, 0x0005, + 0xc1c4, 0x2102, 0x080c, 0x7246, 0x08f8, 0x012e, 0x6843, 0x0000, + 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f, 0x0000, + 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836, 0x0cc0, + 0x6a04, 0x9296, 0x0006, 0x1904, 0x8c64, 0x6a30, 0x9296, 0x0000, + 0x0950, 0x0804, 0x8c64, 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, + 0x8cd7, 0x8cdc, 0x916f, 0x9208, 0x8cdc, 0x916f, 0x9208, 0x8cd7, + 0x8cdc, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x080c, + 0x8a83, 0x080c, 0x8b8f, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, + 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, + 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6, 0x6110, + 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, + 0x1a04, 0x8d48, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, + 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8ee3, 0x8f1e, + 0x8f47, 0x9000, 0x9021, 0x9027, 0x9034, 0x903c, 0x9048, 0x904e, + 0x905f, 0x904e, 0x90b6, 0x903c, 0x90c2, 0x90c8, 0x9048, 0x90c8, + 0x90d4, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46, + 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x9768, 0x978b, 0x979c, 0x97bc, + 0x97ee, 0x9034, 0x8d46, 0x9034, 0x904e, 0x8d46, 0x8f47, 0x9000, + 0x8d46, 0x9b76, 0x904e, 0x8d46, 0x9b92, 0x904e, 0x8d46, 0x9048, + 0x8edd, 0x8d69, 0x8d46, 0x9bae, 0x9c1b, 0x9cf6, 0x8d46, 0x9d03, + 0x9031, 0x9d2e, 0x8d46, 0x97f8, 0x9d5b, 0x8d46, 0x080c, 0x0df6, + 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, + 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8d67, 0x8d67, 0x8d67, + 0x8da1, 0x8e4d, 0x8e58, 0x8d67, 0x8d67, 0x8d67, 0x8eb2, 0x8ebe, + 0x8dbc, 0x8d67, 0x8dd7, 0x8e0b, 0x9edd, 0x9f22, 0x904e, 0x080c, + 0x0df6, 0x00d6, 0x0096, 0x080c, 0x90e7, 0x0026, 0x0036, 0x7814, + 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, + 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, + 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, + 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0x95ee, 0x003e, 0x002e, + 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, + 0x080c, 0x9f69, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, + 0x0005, 0x00d6, 0x0096, 0x080c, 0x90e7, 0x7003, 0x0500, 0x7814, + 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, + 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, + 0x95ee, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x90e7, + 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, + 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, + 0x60c3, 0x0010, 0x080c, 0x95ee, 0x009e, 0x00de, 0x0005, 0x00d6, + 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x90e7, 0x20e9, 0x0000, + 0x2001, 0x197e, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, + 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, + 0x2098, 0x2001, 0x197e, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, + 0x21e5, 0x080c, 0xcac3, 0x9006, 0x080c, 0x21e5, 0x001e, 0xa804, + 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0x95ee, 0x012e, + 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, + 0x080c, 0x9132, 0x20e9, 0x0000, 0x2001, 0x197e, 0x2003, 0x0000, + 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, + 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, + 0x2098, 0x2001, 0x197e, 0x0016, 0x200c, 0x080c, 0xcac3, 0x001e, + 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, + 0x080c, 0x0fe9, 0x080c, 0x95ee, 0x012e, 0x009e, 0x00de, 0x0005, + 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, + 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x90e7, 0x7003, + 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0x95ee, + 0x00d6, 0x00e6, 0x080c, 0x9132, 0x7814, 0x9084, 0xff00, 0x2073, + 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, + 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, + 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, + 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e78, 0x2069, 0x1801, 0x20a9, + 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e81, 0x9096, 0xdf00, + 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, + 0x198e, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19a8, 0x20a9, 0x001a, + 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, + 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, + 0x8e70, 0x1f04, 0x8e98, 0x60c3, 0x004c, 0x080c, 0x95ee, 0x00ee, + 0x00de, 0x0005, 0x080c, 0x90e7, 0x7003, 0x6300, 0x7007, 0x0028, + 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x00d6, 0x0026, + 0x0016, 0x080c, 0x9132, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, + 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073, 0x0800, + 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, + 0x95ee, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1817, 0x2004, + 0x609a, 0x0804, 0x95ee, 0x080c, 0x90e7, 0x7003, 0x5200, 0x2069, + 0x185b, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26a0, + 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, + 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, + 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0x9f69, 0x1120, 0xb8a0, + 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7032, 0x2001, + 0x181f, 0x2004, 0x7036, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, + 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0x95ee, 0x080c, 0x90e7, + 0x7003, 0x0500, 0x080c, 0x9f69, 0x1120, 0xb8a0, 0x9082, 0x007f, + 0x0248, 0x2001, 0x181e, 0x2004, 0x700a, 0x2001, 0x181f, 0x2004, + 0x700e, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x700e, + 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, + 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0x95ee, 0x080c, + 0x90e7, 0x9006, 0x080c, 0x6693, 0xb8a0, 0x9086, 0x007e, 0x1170, + 0x2011, 0x0240, 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, + 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, + 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, + 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x8fc8, 0x00d6, 0x2069, + 0x1946, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0178, 0x6800, 0x700a, + 0x6808, 0x9084, 0x2000, 0x7012, 0x680c, 0x7016, 0x701f, 0x2710, + 0x6818, 0x7022, 0x681c, 0x7026, 0x00f0, 0x6800, 0x700a, 0x6804, + 0x700e, 0x2001, 0x0002, 0x00f6, 0x2079, 0x0100, 0x080c, 0x717e, + 0x1128, 0x78e3, 0x0000, 0x080c, 0x26e1, 0x78e2, 0x00fe, 0x6808, + 0x080c, 0x717e, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, + 0x7012, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, + 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, + 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, + 0x9ddd, 0x2069, 0x194e, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, + 0x080c, 0x54df, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04a0, + 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0168, 0x0016, 0x2009, 0x0002, + 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x26e1, + 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x1946, 0x20e9, 0x0000, + 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, + 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, + 0x20a1, 0x025a, 0x4003, 0x080c, 0x9ddd, 0x20a1, 0x024e, 0x20a9, + 0x0008, 0x2099, 0x194e, 0x4003, 0x60c3, 0x0074, 0x0804, 0x95ee, + 0x080c, 0x90e7, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, + 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x185b, 0x7904, 0x00fe, + 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010, 0x9085, 0x0010, 0x9085, + 0x0002, 0x00d6, 0x0804, 0x9097, 0x7026, 0x60c3, 0x0014, 0x0804, + 0x95ee, 0x080c, 0x90e7, 0x7003, 0x5000, 0x0804, 0x8f69, 0x080c, + 0x90e7, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, + 0x95ee, 0x080c, 0x9129, 0x0010, 0x080c, 0x9132, 0x7003, 0x0200, + 0x60c3, 0x0004, 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0100, + 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x95ee, + 0x080c, 0x9132, 0x7003, 0x0200, 0x0804, 0x8f69, 0x080c, 0x9132, + 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, + 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x00d6, + 0x080c, 0x9132, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, + 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, + 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, + 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, + 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x185b, 0x7904, + 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010, 0x9085, 0x0010, + 0x2009, 0x187d, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, + 0x2009, 0x187b, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbabc, 0xd28c, + 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec, + 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e, + 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0x95ee, 0x080c, 0x9132, + 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, + 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0200, 0x0804, 0x8ee7, + 0x080c, 0x9132, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, + 0x60c3, 0x0008, 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0100, + 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x0026, 0x00d6, + 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, + 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, + 0x9df2, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x6878, 0x700a, 0x687c, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e, + 0x003e, 0x00de, 0x080c, 0x95dc, 0x721a, 0x9f95, 0x0000, 0x7222, + 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c, + 0x9df2, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800, + 0x6878, 0x700a, 0x687c, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10, + 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000, + 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, + 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300, + 0x2021, 0x0100, 0x080c, 0x9df2, 0xb810, 0x9305, 0x7002, 0xb814, + 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x6878, 0x700a, + 0x687c, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e, + 0x00de, 0x080c, 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, + 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0x95dc, 0x721a, 0x7a08, + 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, + 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0df6, 0x908a, 0x0092, 0x1a0c, + 0x0df6, 0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, + 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, + 0x0005, 0x91a0, 0x91af, 0x91ba, 0x919e, 0x919e, 0x919e, 0x91a0, + 0x919e, 0x919e, 0x919e, 0x919e, 0x919e, 0x919e, 0x080c, 0x0df6, + 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x29e9, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0x95ee, 0x0431, + 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, + 0x0804, 0x95ee, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, + 0x0004, 0x0804, 0x95ee, 0x0026, 0x080c, 0x9df2, 0xb810, 0x9085, + 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, + 0x687c, 0x700e, 0x7013, 0x0009, 0x0804, 0x9102, 0x0026, 0x080c, + 0x9df2, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001, 0x0099, 0x7a20, + 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9164, 0x0026, + 0x080c, 0x9df2, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001, 0x0099, + 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9164, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, + 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0df6, 0x908a, + 0x0054, 0x1a0c, 0x0df6, 0x7910, 0x2158, 0xb9b0, 0x2061, 0x0100, + 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x0005, 0x923f, 0x9306, 0x92d9, 0x9428, 0x923d, 0x923d, + 0x923d, 0x923d, 0x923d, 0x923d, 0x923d, 0x993c, 0x9941, 0x9946, + 0x994b, 0x923d, 0x9d3a, 0x923d, 0x9937, 0x080c, 0x0df6, 0x0096, + 0x780b, 0xffff, 0x080c, 0x92aa, 0x7914, 0x2148, 0xa978, 0x7956, + 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032, + 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132, + 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, + 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010, + 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158, + 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c, 0x1792, 0x0010, + 0x080c, 0x1651, 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028, + 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a, + 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813, + 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009, + 0x2001, 0x19de, 0x2003, 0x07d0, 0x2001, 0x19dd, 0x2003, 0x0009, + 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8bc, 0xd084, + 0x0180, 0x2001, 0x1aa1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1aa0, + 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46, + 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, + 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a78, 0x720a, + 0x6a7c, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, + 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002, + 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c, + 0x009e, 0x00de, 0x0804, 0x95ee, 0x6813, 0x0008, 0xb810, 0x9085, + 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, + 0x687c, 0x700e, 0x7013, 0x0889, 0x080c, 0x95dc, 0x721a, 0x7a08, + 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, + 0x080c, 0x9406, 0x7814, 0x2048, 0x080c, 0xbd4c, 0x1130, 0x7814, + 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e, + 0x00de, 0x0005, 0x9324, 0x938d, 0x939d, 0x93c3, 0x93cf, 0x93e0, + 0x93e8, 0x9322, 0x080c, 0x0df6, 0x0016, 0x0036, 0xa97c, 0x918c, + 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc, + 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e, + 0x2001, 0x198c, 0x2004, 0x60c2, 0x0804, 0x95ee, 0xc3e5, 0x0c88, + 0x9186, 0x0001, 0x190c, 0x0df6, 0xaba8, 0x7824, 0xd0cc, 0x1904, + 0x938a, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026, + 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4, + 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810, + 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0, + 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c, + 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0, + 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184, + 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e, + 0x0804, 0x95ee, 0xc3e5, 0x0804, 0x9349, 0x2011, 0x0008, 0x2001, + 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc, + 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016, + 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e, + 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f, + 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069, + 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3, + 0x0032, 0x0804, 0x95ee, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, + 0x7216, 0x60c3, 0x0018, 0x0804, 0x95ee, 0x0cd0, 0xc2e5, 0x2011, + 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, + 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0x95ee, + 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08, + 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, + 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888, + 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, + 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813, + 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7824, 0xd0cc, 0x1168, + 0x7013, 0x0898, 0x080c, 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10, + 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, + 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, + 0x9438, 0x9438, 0x943a, 0x9438, 0x9438, 0x9438, 0x9454, 0x9438, + 0x080c, 0x0df6, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, + 0x2009, 0x0003, 0x00b9, 0x2069, 0x185b, 0x6804, 0xd0bc, 0x0130, + 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, + 0x60c3, 0x0001, 0x0804, 0x95ee, 0x2009, 0x0003, 0x0019, 0x7033, + 0x7f00, 0x0cb0, 0x0016, 0x080c, 0x9df2, 0x001e, 0xb810, 0x9085, + 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a78, 0x720a, + 0x6a7c, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, + 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, + 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, + 0x0100, 0x2071, 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, + 0xba14, 0x7378, 0x747c, 0x7820, 0x90be, 0x0006, 0x0904, 0x954b, + 0x90be, 0x000a, 0x1904, 0x9507, 0xb8b0, 0x609e, 0x7814, 0x2048, + 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, + 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, + 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, + 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, + 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb8b0, 0x609e, + 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, + 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, + 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, + 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x607a, 0x607f, 0x0000, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, + 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0x080c, 0x9dd7, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, + 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x82de, 0x003e, 0x004e, + 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, + 0x9086, 0x0040, 0x0904, 0x9587, 0x9185, 0x0100, 0x6062, 0x6266, + 0x636a, 0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x60af, 0x95d5, + 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7814, + 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, + 0x60ca, 0xb86c, 0x60ce, 0xbab0, 0x629e, 0x080c, 0x9dd7, 0x2009, + 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, + 0x080c, 0x82de, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, + 0x009e, 0x00be, 0x0005, 0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, + 0x9086, 0x0002, 0x0904, 0x95a3, 0x9185, 0x0100, 0x6062, 0x6266, + 0x636a, 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0xb88c, 0x8000, + 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x7838, 0x607e, 0x2f00, + 0x6086, 0x7808, 0x6082, 0xa890, 0x608a, 0xa88c, 0x608e, 0xa8b0, + 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930, 0x9108, 0x7932, 0xa8b0, + 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0xbab0, 0x629e, 0x080c, 0x9db4, 0x0804, 0x9537, 0xb8bc, + 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048, 0xb88c, 0x784a, 0xa836, + 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600, 0x6062, 0x6266, 0x636a, + 0x646e, 0x6073, 0x0829, 0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, + 0x0000, 0x0804, 0x951a, 0x9185, 0x0700, 0x6062, 0x6266, 0x636a, + 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118, 0x6073, 0x0889, 0x0010, + 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, + 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, + 0x6082, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, + 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbab0, + 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c, 0x9dd7, 0x0804, 0x9537, + 0x080c, 0x9db4, 0x0804, 0x9537, 0x7a10, 0x00b6, 0x2258, 0xba8c, + 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, + 0x2069, 0x19c2, 0x6843, 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x00f1, 0x080c, 0x82d0, 0x0005, 0x0016, 0x2001, + 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, + 0x080c, 0x82d0, 0x001e, 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, + 0x2001, 0x19c3, 0x2003, 0x0000, 0x2001, 0x19cb, 0x2003, 0x0000, + 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804, 0x9085, 0x0009, 0x6016, + 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4, + 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804, 0x9085, 0x0008, 0x6016, + 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, + 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, + 0x080c, 0x717e, 0x11c0, 0x2001, 0x19de, 0x2004, 0x9005, 0x15d0, + 0x080c, 0x7246, 0x1160, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, + 0x6024, 0xd084, 0x090c, 0x0df6, 0x080c, 0x82d0, 0x0458, 0x00c6, + 0x2061, 0x19c2, 0x00c8, 0x6904, 0x9194, 0x4000, 0x0540, 0x0811, + 0x080c, 0x2b7f, 0x00c6, 0x2061, 0x19c2, 0x6128, 0x9192, 0x0008, + 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, + 0x82d0, 0x080c, 0x9611, 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, + 0x080c, 0xdbf0, 0x080c, 0x82d9, 0x2009, 0x0014, 0x080c, 0xa068, + 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, + 0x19de, 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19c2, 0x6128, + 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x82d0, + 0x080c, 0x5cee, 0x2009, 0x185a, 0x2114, 0x8210, 0x220a, 0x0c10, + 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x82e6, + 0x2071, 0x19c2, 0x713c, 0x81ff, 0x0904, 0x970a, 0x2061, 0x0100, + 0x2069, 0x0140, 0x080c, 0x717e, 0x1190, 0x0036, 0x2019, 0x0002, + 0x080c, 0x98b1, 0x003e, 0x713c, 0x2160, 0x080c, 0xdbf0, 0x2009, + 0x004a, 0x080c, 0xa068, 0x080c, 0x7246, 0x0804, 0x970a, 0x6904, + 0xd1f4, 0x0904, 0x9711, 0x080c, 0x2b7f, 0x00c6, 0x703c, 0x9065, + 0x090c, 0x0df6, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1568, 0x61c8, + 0x60c4, 0x9105, 0x1548, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0520, + 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x1550, + 0x0070, 0xc0d4, 0x200a, 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, + 0x000a, 0x000e, 0x0120, 0xd0cc, 0x0110, 0x080c, 0x2ab1, 0x6014, + 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c, 0x2060, 0x2009, + 0x0049, 0x080c, 0xa068, 0x0070, 0x0036, 0x2019, 0x0001, 0x080c, + 0x98b1, 0x003e, 0x713c, 0x2160, 0x080c, 0xdbf0, 0x2009, 0x004a, + 0x080c, 0xa068, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, + 0x0005, 0xd1ec, 0x1904, 0x96c3, 0x0804, 0x96c5, 0x0026, 0x00e6, + 0x2071, 0x19c2, 0x7048, 0xd084, 0x01c0, 0x713c, 0x81ff, 0x01a8, + 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, 0x1138, + 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x0030, 0x7014, + 0x9084, 0x1984, 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005, + 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, + 0x0126, 0x2091, 0x8000, 0x6010, 0x2058, 0xbca0, 0x2071, 0x19c2, + 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0, 0x9406, 0x0118, 0xb854, + 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048, 0xac6c, 0xad70, 0xae78, + 0x009e, 0x080c, 0x64d5, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, + 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, + 0x080c, 0x90e7, 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, 0x7016, + 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, 0x0130, + 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, 0x1800, + 0x6078, 0x617c, 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, 0x60c3, + 0x002c, 0x0804, 0x95ee, 0x080c, 0x90e7, 0x7003, 0x0f00, 0x7808, + 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, + 0x60c3, 0x0008, 0x0804, 0x95ee, 0x0156, 0x080c, 0x9132, 0x7003, + 0x0200, 0x2011, 0x1848, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011, + 0x1840, 0x2019, 0x1841, 0x9ef0, 0x0002, 0x2376, 0x8e70, 0x2276, + 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0x97ad, 0x60c3, + 0x001c, 0x015e, 0x0804, 0x95ee, 0x0016, 0x0026, 0x080c, 0x910e, + 0x080c, 0x9120, 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, 0x7814, + 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x9192, + 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, 0x080c, + 0x95ee, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, + 0x9ddd, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x90e7, + 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee, + 0x0016, 0x0026, 0x080c, 0x90e7, 0x20e9, 0x0000, 0x20a1, 0x024c, + 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, + 0x4003, 0x8003, 0x60c2, 0x080c, 0x95ee, 0x002e, 0x001e, 0x0005, + 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, + 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c, 0xbf56, 0x1110, 0x080c, + 0xa9a7, 0x600c, 0x0006, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c, + 0x9955, 0x00ce, 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e, + 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, + 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, + 0x0140, 0x2071, 0x19c2, 0x7024, 0x2060, 0x8cff, 0x01f8, 0x080c, + 0x961a, 0x6ac0, 0x68c3, 0x0000, 0x080c, 0x82d9, 0x00c6, 0x2061, + 0x0100, 0x080c, 0x9df6, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009, + 0x0013, 0x080c, 0xa068, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, + 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, + 0x82d9, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, + 0x0008, 0x68c3, 0x0000, 0x2011, 0x5c98, 0x080c, 0x8259, 0x20a9, + 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, + 0x7804, 0x9084, 0x4000, 0x190c, 0x2b7f, 0x0090, 0xd084, 0x0118, + 0x6827, 0x0001, 0x0010, 0x1f04, 0x9893, 0x7804, 0x9084, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, + 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x19c2, 0x703c, 0x2060, 0x8cff, 0x0904, 0x9918, 0x9386, 0x0002, + 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0x9918, 0x68af, 0x95f5, + 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, + 0x0008, 0x080c, 0x82e6, 0x080c, 0x1e30, 0x2001, 0x0032, 0x6920, + 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, + 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, + 0x9084, 0x4000, 0x190c, 0x2b7f, 0x0090, 0xd08c, 0x0118, 0x6827, + 0x0002, 0x0010, 0x1f04, 0x98f2, 0x7804, 0x9084, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x6827, + 0x4000, 0x6824, 0x83ff, 0x1120, 0x2009, 0x0049, 0x080c, 0xa068, + 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, + 0x19c2, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2069, 0x19c2, 0x6a32, 0x012e, 0x00de, 0x0005, 0x080c, + 0x92aa, 0x7047, 0x1000, 0x0098, 0x080c, 0x92aa, 0x7047, 0x4000, + 0x0070, 0x080c, 0x92aa, 0x7047, 0x2000, 0x0048, 0x080c, 0x92aa, + 0x7047, 0x0400, 0x0020, 0x080c, 0x92aa, 0x7047, 0x0200, 0x7854, + 0x7032, 0x60c3, 0x0020, 0x0804, 0x95ee, 0x00e6, 0x2071, 0x19c2, + 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0x19c2, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, + 0x87ff, 0x0904, 0x99fa, 0x8cff, 0x0904, 0x99fa, 0x6020, 0x9086, + 0x0006, 0x1904, 0x99f5, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904, + 0x99f5, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0x99f5, + 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x99f5, 0x7024, 0x9c06, + 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084, + 0x0148, 0x6827, 0x0001, 0x080c, 0x82d9, 0x080c, 0x9a7f, 0x7027, + 0x0000, 0x0428, 0x080c, 0x82d9, 0x6820, 0xd0b4, 0x0110, 0x68a7, + 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7014, + 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, + 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c, 0xbd4c, + 0x0110, 0x080c, 0xd7e2, 0x009e, 0x080c, 0xa01c, 0x080c, 0x9955, + 0x88ff, 0x1190, 0x00ce, 0x0804, 0x9970, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x9970, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5, + 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x7638, + 0x2660, 0x2678, 0x8cff, 0x0904, 0x9a6e, 0x6020, 0x9086, 0x0006, + 0x1904, 0x9a69, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0x9a69, + 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106, + 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, + 0x98b1, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, + 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, + 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, + 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, + 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xbd4c, 0x0110, + 0x080c, 0xd7e2, 0x080c, 0xa01c, 0x87ff, 0x1198, 0x00ce, 0x0804, + 0x9a1a, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9a1a, 0x9006, 0x012e, + 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, + 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, + 0x2071, 0x19c2, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, + 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, + 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x19c2, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0540, + 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, + 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, + 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, + 0x8a83, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, + 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x760c, 0x2660, 0x2678, + 0x8cff, 0x0904, 0x9b65, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, + 0x9206, 0x1904, 0x9b60, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, + 0x68c0, 0x9005, 0x0904, 0x9b37, 0x080c, 0x961a, 0x68c3, 0x0000, + 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, + 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, + 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, + 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xbf45, 0x1180, 0x080c, + 0x30be, 0x080c, 0xbf56, 0x1518, 0x080c, 0xa9a7, 0x0400, 0x080c, + 0x9a7f, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, + 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0090, 0x6014, 0x2048, 0x080c, + 0xbd4c, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c, + 0xc1c2, 0x080c, 0xa01c, 0x080c, 0x9955, 0x00ce, 0x0804, 0x9ae0, + 0x2c78, 0x600c, 0x2060, 0x0804, 0x9ae0, 0x012e, 0x000e, 0x002e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, + 0x9086, 0x0006, 0x1d20, 0x080c, 0xd7e2, 0x0c08, 0x00d6, 0x080c, + 0x9132, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, + 0x0001, 0x2099, 0x1963, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, + 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0x95ee, + 0x00de, 0x0005, 0x080c, 0x9132, 0x700b, 0x0800, 0x7814, 0x9084, + 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, + 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, 0x7858, 0x9084, + 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0x95ee, 0x00b6, 0x00d6, + 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xc3cf, 0x00de, + 0x1904, 0x9c13, 0x080c, 0x90e7, 0x7003, 0x1300, 0x782c, 0x080c, + 0x9d19, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, + 0xbaa0, 0x080c, 0x9f69, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, + 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, + 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, + 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, + 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0x6098, + 0x700e, 0x00a8, 0x080c, 0x9f69, 0x1130, 0x7810, 0x2058, 0xb8a0, + 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181e, 0x2d04, 0x700a, + 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, + 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, + 0x95ee, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, + 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, + 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0x9c8e, 0x9186, 0x0005, + 0x0904, 0x9c76, 0x9186, 0x0004, 0x05d8, 0x9186, 0x0008, 0x0904, + 0x9c7f, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, + 0x9cf6, 0x0005, 0x080c, 0x9cb7, 0x00d6, 0x0026, 0x792c, 0x2168, + 0x2009, 0x4000, 0x6800, 0x0002, 0x9c57, 0x9c62, 0x9c59, 0x9c62, + 0x9c5e, 0x9c57, 0x9c57, 0x9c62, 0x9c62, 0x9c62, 0x9c62, 0x9c57, + 0x9c57, 0x9c57, 0x9c57, 0x9c57, 0x9c62, 0x9c57, 0x9c62, 0x080c, + 0x0df6, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, + 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0x9cb0, + 0x080c, 0x9cb7, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, + 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, 0x080c, 0x9cb7, + 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x0488, 0x04b9, + 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005, + 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, 0x0441, 0x00d6, + 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096, + 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103, + 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, + 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, + 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0x95ee, 0x00b6, + 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9132, 0x9006, 0x7003, + 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, + 0x080c, 0x9f69, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, + 0x181e, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, + 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, 0x0000, 0x6634, + 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, + 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, + 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9132, + 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, + 0x0008, 0x0804, 0x95ee, 0x080c, 0x90de, 0x7003, 0x1400, 0x7838, + 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, + 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, + 0x95ee, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, + 0x00b6, 0x2058, 0xb8bc, 0xd084, 0x0120, 0x7844, 0x702a, 0x7848, + 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9129, + 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, + 0x0804, 0x95ee, 0x0021, 0x60c3, 0x0000, 0x0804, 0x95ee, 0x00d6, + 0x080c, 0x9df2, 0xb810, 0x9085, 0x0300, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0819, + 0x080c, 0x95dc, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226, 0x2071, + 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, + 0x60a7, 0x9575, 0x0026, 0x080c, 0x29e9, 0x0228, 0x2011, 0x0101, + 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0x9611, 0x080c, 0x82d0, + 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, 0x2048, 0xaa7c, + 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, + 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, + 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, + 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, 0x9df2, 0x00de, + 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, + 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, + 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, + 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, + 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, + 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, + 0x2009, 0x198d, 0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, + 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, 0x0009, 0x00a0, + 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009, 0x000c, + 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028, 0x2009, + 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x00d6, 0x9290, + 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813, 0x0000, + 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292, 0x0020, + 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff, 0x0120, + 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00d6, 0x0096, + 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, 0xa83a, 0xa99c, + 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, 0x6003, 0x0003, + 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, 0x2900, 0xa85a, + 0xa813, 0x1ebc, 0x080c, 0x865d, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8c6c, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071, + 0x19c2, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9ec9, 0x7024, + 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x9e9b, + 0x080c, 0x961a, 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, + 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, + 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, + 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, + 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0x080c, 0xbf45, 0x1180, 0x080c, 0x30be, 0x080c, 0xbf56, 0x1518, + 0x080c, 0xa9a7, 0x0400, 0x080c, 0x9a7f, 0x6824, 0xd084, 0x09b0, + 0x6827, 0x0001, 0x0898, 0x080c, 0xbf56, 0x1118, 0x080c, 0xa9a7, + 0x0090, 0x6014, 0x2048, 0x080c, 0xbd4c, 0x0168, 0x6020, 0x9086, + 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, + 0x6a22, 0x080c, 0xbf39, 0x080c, 0xc1c2, 0x080c, 0xa01c, 0x080c, + 0x9955, 0x00ce, 0x0804, 0x9e4c, 0x2c78, 0x600c, 0x2060, 0x0804, + 0x9e4c, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x006e, 0x009e, + 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, + 0x0006, 0x1d08, 0x080c, 0xd7e2, 0x08f0, 0x00d6, 0x0156, 0x080c, + 0x9132, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003, + 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069, + 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060, + 0x080c, 0x717e, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6ad8, 0xd29c, + 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x2011, 0x1848, 0x63f0, + 0x2312, 0x20a9, 0x0006, 0x2011, 0x1840, 0x2019, 0x1841, 0x2071, + 0x0250, 0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002, 0x9290, + 0x0002, 0x1f04, 0x9f11, 0x60c3, 0x0020, 0x080c, 0x95ee, 0x015e, + 0x00de, 0x0005, 0x0156, 0x080c, 0x9132, 0x7a14, 0x82ff, 0x0168, + 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100, + 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007, + 0x001c, 0x700f, 0x0001, 0x2011, 0x1998, 0x2204, 0x8007, 0x701a, + 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0, 0x9082, + 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7022, 0x2001, 0x181f, + 0x2004, 0x7026, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, + 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, + 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, + 0x95ee, 0x0006, 0x2001, 0x1836, 0x2004, 0xd0ac, 0x000e, 0x0005, + 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, + 0x080c, 0x983b, 0x0036, 0x901e, 0x080c, 0x98b1, 0x003e, 0x0005, + 0x2071, 0x188b, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976, 0x2071, + 0x1800, 0x7072, 0x7076, 0x7067, 0xffe0, 0x2071, 0x1800, 0x7070, + 0x7052, 0x7057, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, + 0x2091, 0x8000, 0x7550, 0x9582, 0x0010, 0x0608, 0x7054, 0x2060, + 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, + 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, + 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230, 0x7556, 0x9085, + 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc0, 0x9006, + 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7550, 0x9582, 0x0010, 0x0600, + 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, + 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, + 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1228, + 0x7556, 0x9085, 0x0001, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc8, + 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0df6, 0x2001, 0x1819, + 0x2004, 0x9c02, 0x1a0c, 0x0df6, 0x9006, 0x6006, 0x600a, 0x600e, + 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, + 0x6056, 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, + 0x603e, 0x6042, 0x2061, 0x1800, 0x6050, 0x8000, 0x6052, 0x9086, + 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, + 0x8b8f, 0x001e, 0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000, + 0x01c0, 0x601c, 0xd084, 0x190c, 0x192c, 0x6017, 0x0000, 0x6023, + 0x0007, 0x2001, 0x1960, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e, + 0x0208, 0x8004, 0x601a, 0x080c, 0xda94, 0x6043, 0x0000, 0x6013, + 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, + 0x8000, 0x7550, 0x9582, 0x0001, 0x0608, 0x7054, 0x2060, 0x6000, + 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208, + 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7552, + 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230, 0x7556, 0x9085, 0x0001, + 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, + 0x6020, 0x9084, 0x000f, 0x0002, 0xa07b, 0xa084, 0xa09f, 0xa0ba, + 0xc4a1, 0xc4be, 0xc4d9, 0xa07b, 0xa084, 0xa07b, 0xa0d3, 0xa07b, + 0xa07b, 0xa07b, 0xa07b, 0x9186, 0x0013, 0x1128, 0x080c, 0x8a83, + 0x080c, 0x8b8f, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010, + 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005, 0xa09d, 0xa803, 0xa9ee, + 0xa09d, 0xaa7c, 0xa3b6, 0xa09d, 0xa09d, 0xa785, 0xb041, 0xa09d, + 0xa09d, 0xa09d, 0xa09d, 0xa09d, 0xa09d, 0x080c, 0x0df6, 0x0066, + 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005, + 0xa0b8, 0xb70e, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8, + 0xb6a5, 0xb890, 0xa0b8, 0xb74f, 0xb7ce, 0xb74f, 0xb7ce, 0xa0b8, + 0x080c, 0x0df6, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0df6, 0x6000, + 0x0002, 0xa0d1, 0xb088, 0xb150, 0xb283, 0xb432, 0xa0d1, 0xa0d1, + 0xa0d1, 0xb05c, 0xb631, 0xb634, 0xa0d1, 0xa0d1, 0xa0d1, 0xa0d1, + 0xb663, 0x080c, 0x0df6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, + 0x0df6, 0x0013, 0x006e, 0x0005, 0xa0ec, 0xa0ec, 0xa12f, 0xa1ce, + 0xa263, 0xa0ec, 0xa0ec, 0xa0ec, 0xa0ee, 0xa0ec, 0xa0ec, 0xa0ec, + 0xa0ec, 0xa0ec, 0xa0ec, 0xa0ec, 0x080c, 0x0df6, 0x9186, 0x004c, + 0x0588, 0x9186, 0x0003, 0x190c, 0x0df6, 0x0096, 0x601c, 0xc0ed, + 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, + 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006, + 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, + 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c, + 0x1a7e, 0x080c, 0x865d, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c6c, + 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, + 0x080c, 0xa285, 0x080c, 0xc471, 0x6003, 0x0007, 0x0005, 0x00d6, + 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a8c, 0x6014, 0x2048, 0xa87c, + 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, + 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, + 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, + 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, + 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, + 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, + 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, + 0x0002, 0xa196, 0xa196, 0xa191, 0xa194, 0xa196, 0xa18e, 0xa181, + 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, + 0xa181, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, + 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0df6, 0x080c, 0xac6e, + 0x0028, 0x080c, 0xad9f, 0x0010, 0x080c, 0xae8d, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, + 0xa343, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, + 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, + 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, + 0x12a8, 0x080c, 0xa4f1, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, + 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0x9fea, + 0x2001, 0x002c, 0x900e, 0x080c, 0xa3a9, 0x0c70, 0x91b6, 0x0015, + 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0df6, + 0x91b2, 0x0050, 0x1a0c, 0x0df6, 0x9182, 0x0047, 0x00ca, 0x2001, + 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x080c, 0x85b1, 0x002e, 0x001e, 0x000e, 0x012e, + 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xa12f, 0x0005, + 0xa201, 0xa201, 0xa203, 0xa239, 0xa201, 0xa201, 0xa201, 0xa201, + 0xa24c, 0x080c, 0x0df6, 0x00d6, 0x0016, 0x0096, 0x080c, 0x8b3f, + 0x080c, 0x8c6c, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, + 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, + 0x2001, 0x0000, 0x900e, 0x080c, 0xa3a9, 0x080c, 0x9fea, 0x00a8, + 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, + 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, + 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, + 0x0005, 0x080c, 0x8b3f, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, + 0xbd4e, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6a22, 0x009e, 0x00de, + 0x080c, 0x9fea, 0x0804, 0x8c6c, 0x080c, 0x8b3f, 0x080c, 0x3095, + 0x080c, 0xc46e, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd4e, + 0x0120, 0xa87b, 0x0029, 0x080c, 0x6a22, 0x009e, 0x00de, 0x080c, + 0x9fea, 0x0804, 0x8c6c, 0x9182, 0x0047, 0x0002, 0xa273, 0xa275, + 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, + 0xa273, 0xa273, 0xa275, 0x080c, 0x0df6, 0x00d6, 0x0096, 0x080c, + 0x1577, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, + 0x6a22, 0x009e, 0x00de, 0x0804, 0x9fea, 0x0026, 0x0036, 0x0056, + 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1037, 0x000e, + 0x090c, 0x0df6, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, + 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x798c, + 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, + 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, + 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xb915, 0x04c0, 0x2130, + 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xb915, 0x96b2, 0x0034, + 0xb004, 0x904d, 0x0110, 0x080c, 0x0fe9, 0x080c, 0x1037, 0x01d0, + 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, + 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xb915, 0x00b8, + 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, + 0xb915, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, + 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, + 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, + 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6a22, 0x000e, + 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, + 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, + 0x1037, 0x000e, 0x090c, 0x0df6, 0xa960, 0x21e8, 0xa95c, 0x9188, + 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, + 0x2079, 0x1800, 0x798c, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, + 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, + 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, + 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6a22, 0x009e, + 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, + 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, + 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, + 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, + 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x1037, 0x2900, + 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, + 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, + 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, + 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, + 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, + 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xa358, 0x0804, 0xa35a, + 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, + 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, + 0x080c, 0x6a15, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, + 0x1118, 0x080c, 0x9fea, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0df6, + 0x080c, 0x9fea, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, + 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, + 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, + 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, + 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, + 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, + 0x8211, 0x1db8, 0x0096, 0x080c, 0xbd4e, 0x0130, 0x6014, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fea, 0x0096, + 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, + 0x2058, 0xb8bf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0x9fea, 0x003e, + 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, + 0x080c, 0xc459, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, + 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xa7db, + 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, + 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, + 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, + 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, + 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, + 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, + 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0x9fea, + 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, + 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, + 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, + 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xb915, 0x080c, 0xbd4e, + 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, + 0x0103, 0x080c, 0x9fea, 0x001e, 0x009e, 0x0005, 0x0016, 0x0096, + 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, + 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, + 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xb915, 0x009e, + 0x080c, 0xbd4e, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, + 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0x9fea, 0x009e, 0x001e, + 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, + 0x080c, 0xa9a7, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, + 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, + 0xada4, 0x2031, 0x0000, 0x2041, 0x128e, 0x0019, 0x0d08, 0x008e, + 0x0898, 0x0096, 0x0006, 0x080c, 0x1037, 0x000e, 0x01b0, 0xa8ab, + 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, + 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, + 0x080c, 0x1134, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, + 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, + 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, + 0xba14, 0x00be, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, + 0x2009, 0x0035, 0x080c, 0xc3cf, 0x001e, 0x1158, 0x622c, 0x2268, + 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, + 0x0128, 0x080c, 0x9fea, 0x0020, 0x0039, 0x0010, 0x080c, 0xa610, + 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, + 0x0015, 0x0904, 0xa5f8, 0x918e, 0x0016, 0x1904, 0xa60e, 0x700c, + 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, + 0xa5d2, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xa5b5, + 0x0804, 0xa60c, 0x6808, 0x9086, 0xffff, 0x1904, 0xa5fa, 0xa87c, + 0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, + 0x1904, 0xa5fa, 0x6824, 0xd084, 0x1904, 0xa5fa, 0xd0b4, 0x0158, + 0x0016, 0x2001, 0x1960, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, + 0x001e, 0x1a04, 0xa5fa, 0x080c, 0xbf39, 0x685c, 0xa882, 0xa87c, + 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, + 0x000a, 0x080c, 0x847e, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, + 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xba77, 0x00ce, + 0x0804, 0xa60c, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x5eab, + 0x0010, 0x080c, 0x6259, 0x00ce, 0x1904, 0xa5fa, 0x00c6, 0x2d60, + 0x080c, 0x9fea, 0x00ce, 0x0804, 0xa60c, 0x00c6, 0x080c, 0xa03b, + 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xc1ca, 0x6023, + 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0x9fea, 0x00ce, 0x080c, + 0xa068, 0x00ce, 0x0804, 0xa60c, 0x2001, 0x1962, 0x2004, 0x6842, + 0x00ce, 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, + 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, + 0x0003, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce, 0x00e8, 0x700c, + 0x9086, 0x2a00, 0x1138, 0x2001, 0x1962, 0x2004, 0x6842, 0x00a0, + 0x0479, 0x00a0, 0x89ff, 0x090c, 0x0df6, 0x00c6, 0x00d6, 0x2d60, + 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x683c, 0x080c, 0xbf39, + 0x080c, 0xa01c, 0x00de, 0x00ce, 0x080c, 0x9fea, 0x009e, 0x0005, + 0x9186, 0x0015, 0x1128, 0x2001, 0x1962, 0x2004, 0x6842, 0x0068, + 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xda94, + 0x080c, 0x8425, 0x080c, 0x9fea, 0x00ce, 0x080c, 0x9fea, 0x0005, + 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, + 0x2001, 0x1962, 0x2004, 0x6842, 0x0804, 0xa68a, 0x00c6, 0x2d60, + 0x080c, 0xb976, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, + 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, + 0x89ff, 0x090c, 0x0df6, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, + 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, + 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, + 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, + 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, + 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, + 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xc0c1, 0x080c, + 0x8b8f, 0x0010, 0x080c, 0x9fea, 0x004e, 0x003e, 0x002e, 0x0005, + 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, + 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xa6f5, 0x700c, 0x6210, + 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xa6f5, 0x6038, + 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, + 0xa6f5, 0x9286, 0x0002, 0x0904, 0xa6f5, 0x9286, 0x0000, 0x05e8, + 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, + 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, + 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, + 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, + 0x0096, 0x2048, 0x080c, 0xbd4e, 0x090c, 0x0df6, 0xa87b, 0x0003, + 0x009e, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce, 0x0030, 0x6038, + 0x2070, 0x2001, 0x1962, 0x2004, 0x7042, 0x080c, 0x9fea, 0x002e, + 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, + 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, + 0xc48c, 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, + 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xb017, + 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xa764, 0x0096, 0x0156, + 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, + 0x0004, 0x080c, 0xb017, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, + 0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, + 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xa3f2, 0x0096, + 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, + 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x128e, + 0x080c, 0xa4f1, 0x0130, 0x00fe, 0x009e, 0x080c, 0x9fea, 0x00be, + 0x0005, 0x080c, 0xa9a7, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x3095, + 0x080c, 0xc46e, 0x00fe, 0x00c6, 0x080c, 0x9f94, 0x2f00, 0x6012, + 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, + 0x2001, 0x0007, 0x080c, 0x62f4, 0x080c, 0x6320, 0x080c, 0x8640, + 0x080c, 0x8b8f, 0x00ce, 0x0804, 0xa737, 0x2100, 0x91b2, 0x0053, + 0x1a0c, 0x0df6, 0x91b2, 0x0040, 0x1a04, 0xa7ed, 0x0002, 0xa7db, + 0xa7db, 0xa7d1, 0xa7db, 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7db, 0xa7cf, + 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7d1, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, + 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7db, 0xa7cf, 0xa7cf, 0x080c, + 0x0df6, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8bc, 0xc08c, 0xb8be, + 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, + 0x0118, 0x080c, 0x8640, 0x0010, 0x080c, 0x85f8, 0x0126, 0x2091, + 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x2600, 0x0002, 0xa801, + 0xa801, 0xa801, 0xa7db, 0xa7db, 0xa801, 0xa801, 0xa801, 0xa801, + 0xa7db, 0xa801, 0xa7db, 0xa801, 0xa7db, 0xa801, 0xa801, 0xa801, + 0xa801, 0x080c, 0x0df6, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0df6, + 0x91b6, 0x0013, 0x0904, 0xa8d6, 0x91b6, 0x0027, 0x1904, 0xa880, + 0x080c, 0x8a83, 0x6004, 0x080c, 0xbf45, 0x01b0, 0x080c, 0xbf56, + 0x01a8, 0x908e, 0x0021, 0x0904, 0xa87d, 0x908e, 0x0022, 0x1130, + 0x080c, 0xa41e, 0x0904, 0xa879, 0x0804, 0xa87a, 0x908e, 0x003d, + 0x0904, 0xa87d, 0x0804, 0xa873, 0x080c, 0x30be, 0x2001, 0x0007, + 0x080c, 0x62f4, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, + 0xa9a7, 0x9186, 0x007e, 0x1148, 0x2001, 0x1836, 0x2014, 0xc285, + 0x080c, 0x717e, 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, + 0x0028, 0x2110, 0x080c, 0xdaf0, 0x002e, 0x003e, 0x0016, 0x0026, + 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x8782, 0x0076, 0x903e, + 0x080c, 0x8670, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, + 0x080c, 0xd556, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xc46e, + 0x0016, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x001e, 0x080c, 0x3190, + 0x080c, 0x8b8f, 0x0030, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c, + 0x8b8f, 0x0005, 0x080c, 0xa9a7, 0x0cb0, 0x080c, 0xa9e3, 0x0c98, + 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc47f, + 0x0d80, 0x6000, 0x9086, 0x0002, 0x0904, 0xa9ee, 0x0c50, 0x9186, + 0x0014, 0x1d38, 0x080c, 0x8a83, 0x6004, 0x908e, 0x0022, 0x1118, + 0x080c, 0xa41e, 0x09f0, 0x080c, 0x3095, 0x080c, 0xc46e, 0x080c, + 0xbf45, 0x1198, 0x080c, 0x30be, 0x6010, 0x00b6, 0x2058, 0xb9a0, + 0x00be, 0x080c, 0xa9a7, 0x9186, 0x007e, 0x1128, 0x2001, 0x1836, + 0x200c, 0xc185, 0x2102, 0x0804, 0xa873, 0x080c, 0xbf56, 0x1120, + 0x080c, 0xa9a7, 0x0804, 0xa873, 0x6004, 0x908e, 0x0032, 0x1160, + 0x00e6, 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x3424, + 0x00fe, 0x00ee, 0x0804, 0xa873, 0x6004, 0x908e, 0x0021, 0x0d40, + 0x908e, 0x0022, 0x090c, 0xa9a7, 0x0804, 0xa873, 0x90b2, 0x0040, + 0x1a04, 0xa990, 0x2008, 0x0002, 0xa91e, 0xa91f, 0xa922, 0xa925, + 0xa928, 0xa935, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, + 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, + 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, + 0xa91c, 0xa91c, 0xa938, 0xa945, 0xa91c, 0xa947, 0xa945, 0xa91c, + 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa945, 0xa945, 0xa91c, 0xa91c, + 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa977, 0xa945, + 0xa91c, 0xa941, 0xa91c, 0xa91c, 0xa91c, 0xa942, 0xa91c, 0xa91c, + 0xa91c, 0xa945, 0xa96e, 0xa91c, 0x080c, 0x0df6, 0x0430, 0x2001, + 0x000b, 0x0470, 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, + 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, + 0x0000, 0x1500, 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, + 0x080c, 0x8a83, 0x6003, 0x0005, 0x080c, 0xc471, 0x080c, 0x8b8f, + 0x0070, 0x0018, 0x0010, 0x080c, 0x62f4, 0x0804, 0xa988, 0x080c, + 0x8a83, 0x080c, 0xc471, 0x6003, 0x0004, 0x080c, 0x8b8f, 0x0005, + 0x080c, 0x62f4, 0x080c, 0x8a83, 0x6003, 0x0002, 0x0036, 0x2019, + 0x1866, 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1960, 0x201c, + 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, + 0x9318, 0x631a, 0x003e, 0x080c, 0x8b8f, 0x0c08, 0x080c, 0x8a83, + 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x08c0, 0x00e6, + 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x3424, 0x00fe, + 0x00ee, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0838, + 0x080c, 0x8a83, 0x6003, 0x0002, 0x080c, 0xc471, 0x0804, 0x8b8f, + 0x2600, 0x2008, 0x0002, 0xa9a5, 0xa9a5, 0xa9a5, 0xa988, 0xa988, + 0xa9a5, 0xa9a5, 0xa9a5, 0xa9a5, 0xa988, 0xa9a5, 0xa988, 0xa9a5, + 0xa988, 0xa9a5, 0xa9a5, 0xa9a5, 0xa9a5, 0x080c, 0x0df6, 0x00e6, + 0x0096, 0x0026, 0x0016, 0x080c, 0xbd4e, 0x0568, 0x6014, 0x2048, + 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, + 0x080c, 0x5275, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, + 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xc333, + 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, + 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, + 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, + 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, + 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, + 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0df6, + 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, 0xc252, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xc29b, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xc2c7, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xc1e4, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xbf94, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xbfd5, 0x0804, 0xaa6b, + 0x6604, 0x96b6, 0x001f, 0x1118, 0x080c, 0xa3c3, 0x04e0, 0x6604, + 0x96b6, 0x0000, 0x1118, 0x080c, 0xa6fb, 0x04a8, 0x6604, 0x96b6, + 0x0022, 0x1118, 0x080c, 0xa3ff, 0x0470, 0x6604, 0x96b6, 0x0035, + 0x1118, 0x080c, 0xa50f, 0x0438, 0x6604, 0x96b6, 0x0039, 0x1118, + 0x080c, 0xa690, 0x0400, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, + 0xa437, 0x00c8, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xa473, + 0x0090, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xa49e, 0x0058, + 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, + 0x00be, 0x0804, 0xad46, 0x00be, 0x0005, 0x080c, 0xa083, 0x0cd8, + 0xaa88, 0xaa96, 0xaa88, 0xaada, 0xaa88, 0xac6e, 0xad53, 0xaa88, + 0xaa88, 0xad20, 0xaa88, 0xad34, 0x0096, 0x080c, 0x1577, 0x6014, + 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fea, + 0xa001, 0xa001, 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, + 0x0001, 0x080c, 0x62e0, 0x0804, 0x9fea, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x708c, 0x9086, 0x0074, 0x1540, 0x080c, 0xd527, 0x11b0, + 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, + 0x0110, 0xc0c5, 0xb802, 0x00e9, 0x00be, 0x2001, 0x0006, 0x080c, + 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x0088, 0x2001, 0x000a, + 0x080c, 0x62f4, 0x080c, 0x30be, 0x6003, 0x0001, 0x6007, 0x0001, + 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0010, 0x080c, 0xac59, 0x00ee, + 0x0005, 0x00d6, 0xb800, 0xd084, 0x0158, 0x9006, 0x080c, 0x62e0, + 0x2069, 0x185b, 0x6804, 0x0020, 0x2001, 0x0006, 0x080c, 0x6320, + 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1823, 0x2204, + 0x9086, 0x0074, 0x1904, 0xac30, 0x6010, 0x2058, 0xbaa0, 0x9286, + 0x007e, 0x1120, 0x080c, 0xae98, 0x0804, 0xab9d, 0x00d6, 0x080c, + 0x717e, 0x01a0, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e, + 0x0904, 0xab3e, 0x080c, 0x54ef, 0x1598, 0x6014, 0x2048, 0xa807, + 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, + 0x2058, 0xb910, 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, + 0x8008, 0x080c, 0x66ed, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, + 0x0df6, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, + 0x2001, 0x0030, 0x900e, 0x2011, 0x4009, 0x080c, 0xc333, 0x0040, + 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, + 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c, 0x30be, 0x080c, 0x9fea, + 0x001e, 0x080c, 0x3190, 0x00de, 0x0804, 0xac33, 0x00de, 0x080c, + 0xae8d, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, + 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, + 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333, + 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, + 0x0006, 0x080c, 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x0804, + 0xac33, 0x080c, 0xac41, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, + 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, + 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333, 0x08f8, + 0x080c, 0xac37, 0x0160, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0004, + 0x080c, 0x6320, 0x2001, 0x0007, 0x080c, 0x62f4, 0x08a0, 0x2001, + 0x0004, 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, + 0x8640, 0x080c, 0x8b8f, 0x0804, 0xac33, 0xb85c, 0xd0e4, 0x0178, + 0x080c, 0xc164, 0x080c, 0x717e, 0x0118, 0xd0dc, 0x1904, 0xab5f, + 0x2011, 0x1836, 0x2204, 0xc0ad, 0x2012, 0x0804, 0xab5f, 0x080c, + 0xc1a1, 0x2011, 0x1836, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, + 0xd6c7, 0x000e, 0x1904, 0xab5f, 0xc0b5, 0x2012, 0x2001, 0x0006, + 0x080c, 0x62f4, 0x9006, 0x080c, 0x62e0, 0x00c6, 0x2001, 0x180f, + 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, + 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707a, 0x7010, 0x78ea, + 0x707e, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, + 0x080c, 0x26b6, 0x00f6, 0x2100, 0x900e, 0x080c, 0x266d, 0x795a, + 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, + 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, + 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26b6, 0x00f6, + 0x2079, 0x1800, 0x797e, 0x2100, 0x900e, 0x797a, 0x080c, 0x266d, + 0x795a, 0x00fe, 0x8108, 0x080c, 0x6343, 0x2b00, 0x00ce, 0x1904, + 0xab5f, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, + 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, + 0xb916, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6023, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0018, + 0x080c, 0xa9a7, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, + 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x185c, 0x2004, 0xd0ac, + 0x0005, 0x00e6, 0x080c, 0xdb49, 0x0190, 0x2071, 0x0260, 0x7108, + 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, + 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, + 0x0005, 0x2030, 0x2001, 0x0007, 0x080c, 0x62f4, 0x080c, 0x54ef, + 0x1120, 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x30be, 0x6020, + 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0x9fea, 0x00b6, 0x00e6, + 0x0026, 0x0016, 0x2071, 0x1800, 0x708c, 0x9086, 0x0014, 0x1904, + 0xad17, 0x00d6, 0x080c, 0x717e, 0x01a0, 0x0026, 0x2011, 0x0010, + 0x080c, 0x66ed, 0x002e, 0x0904, 0xacc9, 0x080c, 0x54ef, 0x1598, + 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, + 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, 0x00be, 0x9186, 0x00ff, + 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, 0x66ed, 0x002e, 0x0548, + 0x6014, 0x9005, 0x090c, 0x0df6, 0x2048, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011, 0x4009, + 0x080c, 0xc333, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, + 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c, + 0x30be, 0x080c, 0x9fea, 0x001e, 0x080c, 0x3190, 0x00de, 0x0804, + 0xad1b, 0x00de, 0x080c, 0x54ef, 0x1170, 0x6014, 0x9005, 0x1158, + 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, + 0x4bb4, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x643e, + 0x080c, 0xaac9, 0x00de, 0x080c, 0xaf63, 0x1588, 0x6010, 0x2058, + 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x62f4, 0x0096, + 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, + 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333, + 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807, + 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x30be, + 0x6020, 0x9086, 0x000a, 0x0138, 0x080c, 0x9fea, 0x0020, 0x080c, + 0xa9a7, 0x080c, 0xac59, 0x001e, 0x002e, 0x00ee, 0x00be, 0x0005, + 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, 0x0002, + 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8640, + 0x0804, 0x8b8f, 0x0804, 0xac59, 0x2030, 0x2011, 0x1823, 0x2204, + 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, + 0x080c, 0x62f4, 0x0804, 0x9fea, 0x0804, 0xac59, 0x0002, 0xaa88, + 0xad5e, 0xaa88, 0xad9f, 0xaa88, 0xae4a, 0xad53, 0xaa8b, 0xaa88, + 0xae5c, 0xaa88, 0xae6c, 0x6604, 0x9686, 0x0003, 0x0904, 0xac6e, + 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fea, 0x0005, 0x00b6, 0x00d6, + 0x00c6, 0x080c, 0xae7c, 0x11a0, 0x9006, 0x080c, 0x62e0, 0x080c, + 0x3095, 0x080c, 0xc46e, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0418, + 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, + 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, + 0x000a, 0x0088, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, + 0x1900, 0x0148, 0x908e, 0x1e00, 0x0990, 0x080c, 0x3095, 0x080c, + 0xc46e, 0x080c, 0xac59, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, + 0x00b6, 0x0026, 0x9016, 0x080c, 0xae8a, 0x00d6, 0x2069, 0x1956, + 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, + 0x1138, 0x2069, 0x181f, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, + 0x00de, 0x0088, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, + 0x62f4, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, + 0x8b8f, 0x0804, 0xae1a, 0x080c, 0xbd4e, 0x01b0, 0x6014, 0x2048, + 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, + 0x0002, 0x080c, 0xc390, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, + 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, + 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, + 0x9006, 0x0c38, 0x080c, 0xa9a7, 0x2009, 0x026e, 0x2134, 0x96b4, + 0x00ff, 0x9686, 0x0005, 0x0510, 0x9686, 0x000b, 0x01c8, 0x2009, + 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01b0, + 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0180, 0x2001, 0x0004, + 0x080c, 0x62f4, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0010, + 0x080c, 0xac59, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, 0x0139, + 0x0160, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa864, 0x9086, + 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c50, 0x6010, 0x2058, + 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842, 0x601b, + 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e, 0x1138, + 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x00ee, 0x0010, 0x080c, + 0x3095, 0x0870, 0x2001, 0x0004, 0x080c, 0x62f4, 0x04d9, 0x1140, + 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8640, 0x0804, 0x8b8f, + 0x080c, 0xa9a7, 0x0804, 0xac59, 0x0469, 0x1160, 0x2001, 0x0008, + 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x8640, + 0x0804, 0x8b8f, 0x0804, 0xac59, 0x00e9, 0x1160, 0x2001, 0x000a, + 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8640, + 0x0804, 0x8b8f, 0x0804, 0xac59, 0x2009, 0x026e, 0x2104, 0x9086, + 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, + 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, + 0x6110, 0x2158, 0x080c, 0x63b2, 0x001e, 0x00ce, 0x00be, 0x0005, + 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, + 0x2009, 0x1836, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xaf35, + 0x0560, 0x2009, 0x1836, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x66c5, + 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd837, 0x2001, + 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, + 0x080c, 0x3060, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2e73, 0x00ee, + 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x3190, + 0x8108, 0x1f04, 0xaece, 0x015e, 0x00ce, 0x080c, 0xae8d, 0x2071, + 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1836, 0x200c, + 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, + 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1836, 0x2102, 0x9184, + 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, 0x2e04, 0x9084, + 0x00ff, 0x2069, 0x181e, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, + 0x2069, 0x181f, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084, + 0xff00, 0x001e, 0x9105, 0x2009, 0x182b, 0x200a, 0x2200, 0x9084, + 0x00ff, 0x2008, 0x080c, 0x26b6, 0x080c, 0x717e, 0x0170, 0x2071, + 0x0260, 0x2069, 0x195c, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050, + 0x680a, 0x7054, 0x680e, 0x080c, 0xc164, 0x0040, 0x2001, 0x0006, + 0x080c, 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x001e, 0x003e, + 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036, + 0x00e6, 0x0156, 0x2019, 0x182b, 0x231c, 0x83ff, 0x01f0, 0x2071, + 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205, + 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019, + 0x000a, 0x080c, 0xb017, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x2019, 0x0006, 0x080c, 0xb017, 0x1100, 0x015e, 0x00ee, 0x003e, + 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086, + 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec, + 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4, + 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee, + 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021, + 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7250, 0x7070, + 0x9202, 0x1a04, 0xafef, 0x080c, 0xd868, 0x0904, 0xafe8, 0x6720, + 0x9786, 0x0007, 0x0904, 0xafe8, 0x2500, 0x9c06, 0x0904, 0xafe8, + 0x2400, 0x9c06, 0x05e8, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, + 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1580, + 0x00c6, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x192c, 0x9786, + 0x000a, 0x0148, 0x080c, 0xbf56, 0x1130, 0x00ce, 0x080c, 0xa9a7, + 0x080c, 0xa01c, 0x00e8, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x01a8, + 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, + 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e, 0xab7a, 0xa877, + 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c, 0xa01c, 0x00ce, + 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1210, 0x0804, 0xaf96, 0x012e, + 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, + 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c30, 0x9786, + 0x000a, 0x09e0, 0x0880, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, + 0x8318, 0x1f04, 0xb003, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, + 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, + 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, + 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, + 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, + 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, + 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, + 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6, 0x080c, 0xbf45, + 0x0120, 0x080c, 0xbf56, 0x0168, 0x0028, 0x080c, 0x30be, 0x080c, + 0xbf56, 0x0138, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f, + 0x0005, 0x080c, 0xa9a7, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, + 0x0040, 0x0208, 0x000a, 0x0005, 0xb078, 0xb078, 0xb078, 0xb078, + 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb07a, + 0xb07a, 0xb07a, 0xb07a, 0xb078, 0xb078, 0xb078, 0xb07a, 0xb078, + 0x080c, 0x0df6, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, + 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, + 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xb112, + 0x9186, 0x0027, 0x1520, 0x080c, 0x8a83, 0x080c, 0x3095, 0x080c, + 0xc46e, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd4e, 0x0198, 0x080c, + 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0068, 0xa867, 0x0103, 0xa87b, + 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6a22, + 0x080c, 0xbf39, 0x009e, 0x080c, 0x9fea, 0x0804, 0x8b8f, 0x9186, + 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046, + 0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186, + 0x0048, 0x190c, 0x0df6, 0x080c, 0xc47f, 0x0130, 0x6000, 0x9086, + 0x0002, 0x1110, 0x0804, 0xb150, 0x0005, 0x0002, 0xb0ec, 0xb0ea, + 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, + 0xb0ea, 0xb107, 0xb107, 0xb107, 0xb107, 0xb0ea, 0xb107, 0xb0ea, + 0xb107, 0xb0ea, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x0096, 0x6114, + 0x2148, 0x080c, 0xbd4e, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, + 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6a22, 0x080c, + 0xbf39, 0x009e, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c, + 0x8a83, 0x080c, 0xbf56, 0x090c, 0xa9a7, 0x080c, 0x9fea, 0x080c, + 0x8b8f, 0x0005, 0x0002, 0xb129, 0xb127, 0xb127, 0xb127, 0xb127, + 0xb127, 0xb127, 0xb127, 0xb127, 0xb127, 0xb127, 0xb140, 0xb140, + 0xb140, 0xb140, 0xb127, 0xb14a, 0xb127, 0xb140, 0xb127, 0x080c, + 0x0df6, 0x0096, 0x080c, 0x8a83, 0x6014, 0x2048, 0x2001, 0x1962, + 0x2004, 0x6042, 0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, + 0x9085, 0x0400, 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, + 0x080c, 0x8a83, 0x080c, 0xc471, 0x080c, 0xc476, 0x6003, 0x000f, + 0x0804, 0x8b8f, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x0804, 0x8b8f, + 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, + 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16e, 0xb24e, 0xb16c, + 0xb282, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, + 0xb16c, 0xb16c, 0xb16c, 0xb282, 0x080c, 0x0df6, 0x00b6, 0x0096, + 0x6114, 0x2148, 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, + 0x2058, 0xb800, 0xd0bc, 0x1904, 0xb23d, 0xa87b, 0x0000, 0xa867, + 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xb41b, 0x080c, 0x683c, 0x6210, 0x2258, 0xba3c, 0x82ff, + 0x0110, 0x8211, 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xb21e, 0x080c, + 0x9fea, 0x009e, 0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, + 0x2058, 0xb800, 0xd0bc, 0x1904, 0xb222, 0x7348, 0xab92, 0x734c, + 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, + 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, + 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, + 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, + 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, + 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xb175, + 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, + 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, + 0xb915, 0x003e, 0xd6cc, 0x0904, 0xb18a, 0x7154, 0xa98a, 0x81ff, + 0x0904, 0xb18a, 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, + 0x2011, 0x0029, 0x080c, 0xb915, 0x2011, 0x0205, 0x2013, 0x0000, + 0x080c, 0xc3fc, 0x0804, 0xb18a, 0xa868, 0xd0fc, 0x0120, 0x2009, + 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c, 0xb8b4, 0x00ae, + 0x080c, 0xc3fc, 0x080c, 0xb905, 0x0804, 0xb18c, 0x080c, 0xc04e, + 0x0804, 0xb199, 0xa87c, 0xd0ac, 0x0904, 0xb1a5, 0xa880, 0xd0bc, + 0x1904, 0xb1a5, 0x9684, 0x0400, 0x0130, 0xa838, 0xab34, 0x9305, + 0x0904, 0xb1a5, 0x00b8, 0x7348, 0xa838, 0x9306, 0x1198, 0x734c, + 0xa834, 0x931e, 0x0904, 0xb1a5, 0x0068, 0xa87c, 0xd0ac, 0x0904, + 0xb17d, 0xa838, 0xa934, 0x9105, 0x0904, 0xb17d, 0xa880, 0xd0bc, + 0x1904, 0xb17d, 0x080c, 0xc088, 0x0804, 0xb199, 0x0096, 0x00f6, + 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, 0x7b00, + 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, 0x6003, + 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, + 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, + 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, 0x6043, + 0x0000, 0x2c10, 0x080c, 0x1a7e, 0x080c, 0x865d, 0x080c, 0x8c6c, + 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xb29f, 0xb29f, 0xb29f, 0xb29f, 0xb29f, + 0xb2a1, 0xb337, 0xb29f, 0xb29f, 0xb34e, 0xb3de, 0xb29f, 0xb29f, + 0xb29f, 0xb29f, 0xb3f3, 0xb29f, 0xb29f, 0xb29f, 0xb29f, 0x080c, + 0x0df6, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, + 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, + 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, + 0x00be, 0x86ff, 0x0904, 0xb332, 0x9694, 0xff00, 0x9284, 0x0c00, + 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, + 0xb332, 0x080c, 0x1037, 0x090c, 0x0df6, 0x2900, 0xb07a, 0xb77c, + 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, + 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, + 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, + 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, + 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, + 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, + 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, + 0x080c, 0xb915, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, + 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, + 0x0029, 0x080c, 0xb915, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, + 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, + 0x080c, 0xb8b4, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x00f6, + 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, + 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, 0x00ae, + 0x00fe, 0x2c10, 0x080c, 0x1a7e, 0x0804, 0x95e7, 0x6003, 0x0002, + 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, + 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, + 0x080c, 0x1651, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, + 0x009e, 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x0096, 0x2001, 0x1962, + 0x2004, 0x6042, 0x080c, 0x8b3f, 0x080c, 0x8c6c, 0x6114, 0x2148, + 0xa97c, 0xd1e4, 0x0904, 0xb3d9, 0xd1cc, 0x05c8, 0xa978, 0xa868, + 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0xa860, + 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, 0x810f, + 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, 0x2098, + 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, 0x000e, + 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fe9, + 0x001e, 0x0458, 0x0016, 0x080c, 0x0fe9, 0x009e, 0xa87c, 0xc0cc, + 0xa87e, 0xa974, 0x0016, 0x080c, 0xb905, 0x001e, 0x00f0, 0xa867, + 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086, + 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0xa87b, + 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0x0016, 0x080c, 0x683c, 0x001e, 0xd1e4, 0x1120, 0x080c, + 0x9fea, 0x009e, 0x0005, 0x080c, 0xc04e, 0x0cd8, 0x6004, 0x9086, + 0x0040, 0x1120, 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x2019, 0x0001, + 0x080c, 0x98b1, 0x6003, 0x0002, 0x080c, 0xc476, 0x080c, 0x8b3f, + 0x080c, 0x8c6c, 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, + 0x8a83, 0x080c, 0x8b8f, 0x2019, 0x0001, 0x080c, 0x98b1, 0x080c, + 0x8b3f, 0x080c, 0x3095, 0x080c, 0xc46e, 0x0096, 0x6114, 0x2148, + 0x080c, 0xbd4e, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39, 0x009e, 0x080c, 0x9fea, + 0x080c, 0x8c6c, 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, + 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, + 0x2009, 0x1a55, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, + 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb450, + 0xb44e, 0xb44e, 0xb4f6, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e, + 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb628, 0x080c, 0x0df6, + 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, + 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, + 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, + 0x86ff, 0x0904, 0xb4ef, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, + 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xb4ef, + 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, + 0x0c38, 0x080c, 0x1037, 0x090c, 0x0df6, 0x2900, 0xb07a, 0xb77c, + 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, + 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, + 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, + 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, + 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, + 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, + 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, + 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, + 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xb915, 0x003e, + 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, + 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb915, + 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, + 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xb8b4, 0x080c, + 0x18f8, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1962, + 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, + 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, 0xd1e4, + 0x0904, 0xb623, 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xb5f2, 0xa978, 0xa868, + 0xd0fc, 0x0904, 0xb5b3, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, + 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, + 0xb580, 0x9086, 0x0028, 0x1904, 0xb56c, 0xa87b, 0x001c, 0xb07b, + 0x001c, 0x0804, 0xb588, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, + 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, + 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, + 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, + 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x9006, + 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, + 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e, + 0x080c, 0xc088, 0x0804, 0xb623, 0xd1dc, 0x0158, 0xa87b, 0x0015, + 0xb07b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xb174, 0xc1dc, 0xb176, + 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb41b, + 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, + 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, + 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, + 0x080c, 0xc3fc, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fe9, + 0x001e, 0x0804, 0xb61f, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, + 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, + 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, + 0xb07b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xb174, 0xc1dc, 0xb176, + 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb41b, + 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, + 0x0fe9, 0x009e, 0x080c, 0xc3fc, 0xa974, 0x0016, 0x080c, 0xb905, + 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, + 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, + 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xa974, + 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, + 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xb41b, 0xa974, 0x0016, 0x080c, 0x683c, 0x001e, 0xd1e4, + 0x1120, 0x080c, 0x9fea, 0x009e, 0x0005, 0x080c, 0xc04e, 0x0cd8, + 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1918, 0x009e, + 0x0005, 0x080c, 0x8a83, 0x0010, 0x080c, 0x8b3f, 0x080c, 0xbd4e, + 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xbf56, 0x1118, 0x080c, + 0xa9a7, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, + 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, + 0x080c, 0xdae1, 0xa877, 0x0000, 0x080c, 0x6a22, 0x009e, 0x080c, + 0x9fea, 0x080c, 0x8b8f, 0x0804, 0x8c6c, 0xa87b, 0x0004, 0x0c90, + 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, + 0xb681, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, + 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0x080c, + 0x0df6, 0x080c, 0x54e3, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, + 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, + 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, + 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, + 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x9182, 0x0085, 0x0002, + 0xb6b7, 0xb6b5, 0xb6b5, 0xb6c3, 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5, + 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5, 0x080c, 0x0df6, 0x6003, + 0x0001, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8b8f, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, + 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xbd3c, 0x01f8, 0x2268, + 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, + 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xb976, 0x00de, 0x00ce, 0x0158, + 0x702c, 0xd084, 0x1118, 0x080c, 0xb940, 0x0010, 0x6803, 0x0002, + 0x6007, 0x0086, 0x0028, 0x080c, 0xb962, 0x0d90, 0x6007, 0x0087, + 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x7220, 0x080c, + 0xbd3c, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xc088, + 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, + 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0df6, 0x908a, 0x0092, + 0x1a0c, 0x0df6, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, + 0x9186, 0x0014, 0x190c, 0x0df6, 0x080c, 0x8a83, 0x0096, 0x6014, + 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0029, 0x080c, 0x6a22, 0x009e, 0x080c, 0xa01c, 0x0804, + 0x8b8f, 0xb746, 0xb748, 0xb748, 0xb746, 0xb746, 0xb746, 0xb746, + 0xb746, 0xb746, 0xb746, 0xb746, 0xb746, 0xb746, 0x080c, 0x0df6, + 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x9186, + 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, + 0x0027, 0x11f8, 0x080c, 0x8a83, 0x080c, 0x3095, 0x080c, 0xc46e, + 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0150, 0xa867, 0x0103, + 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6a22, 0x080c, 0xbf39, + 0x009e, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xa083, + 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x8a83, 0x0096, 0x6014, + 0x2048, 0x080c, 0xbd4e, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xb79e, + 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0xb7b6, 0xb79c, 0xb79c, + 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0x080c, 0x0df6, 0x080c, 0x8a83, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961, 0x2004, + 0x601a, 0x6003, 0x000c, 0x080c, 0x8b8f, 0x0005, 0x080c, 0x8a83, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961, 0x2004, + 0x601a, 0x6003, 0x000e, 0x080c, 0x8b8f, 0x0005, 0x9182, 0x0092, + 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xa083, 0xb7e4, + 0xb7e4, 0xb7e4, 0xb7e4, 0xb7e6, 0xb833, 0xb7e4, 0xb7e4, 0xb7e4, + 0xb7e4, 0xb7e4, 0xb7e4, 0xb7e4, 0x080c, 0x0df6, 0x0096, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, + 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, + 0x009e, 0x0804, 0xb847, 0x080c, 0xbd4e, 0x1118, 0x080c, 0xbf39, + 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xbf39, + 0xa867, 0x0103, 0x080c, 0xc439, 0x080c, 0x6a22, 0x00d6, 0x2c68, + 0x080c, 0x9f94, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, + 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, + 0x613e, 0x6910, 0x6112, 0x080c, 0xc1ca, 0x6954, 0x6156, 0x6023, + 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x2d60, 0x00de, 0x080c, + 0x9fea, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, + 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, + 0x2c68, 0x080c, 0xc3cf, 0x11f0, 0x080c, 0x9f94, 0x01d8, 0x6106, + 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, + 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, + 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xc1ca, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x2d60, 0x00de, 0x0804, 0x9fea, 0x0096, 0x6014, + 0x2048, 0x080c, 0xbd4e, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, + 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, + 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xc04a, 0xa877, + 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39, 0x009e, 0x0804, 0x9fea, + 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa867, + 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6a22, 0x009e, + 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, + 0x0027, 0x0118, 0x080c, 0xa083, 0x0030, 0x080c, 0x8a83, 0x080c, + 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, + 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, + 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, + 0x080c, 0xb915, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, + 0x0fe9, 0x080c, 0x1037, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, + 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, + 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, + 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, + 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, + 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, + 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, + 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6a22, 0x2a48, + 0x0cb8, 0x080c, 0x6a22, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, + 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, + 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, + 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, + 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, + 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, + 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, + 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x6c6b, 0x080c, + 0x6a15, 0x080c, 0xbf39, 0x009e, 0x080c, 0xa01c, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, + 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, + 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, + 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, + 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, + 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, + 0xb9b1, 0xb9b1, 0xb9ac, 0xb9d3, 0xb99f, 0xb9ac, 0xb9d3, 0xb9ac, + 0xb9ac, 0xb99f, 0xb9ac, 0xb9ac, 0xb9ac, 0xb99f, 0xb99f, 0x080c, + 0x0df6, 0x0036, 0x2019, 0x0010, 0x080c, 0xd38f, 0x6023, 0x0006, + 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, + 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883, + 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6b, 0x080c, + 0xc04a, 0x080c, 0x6a15, 0x080c, 0xa01c, 0x9085, 0x0001, 0x009e, + 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6, + 0x0002, 0xb9e9, 0xba19, 0xb9eb, 0xba3a, 0xba14, 0xb9e9, 0xb9ac, + 0xb9b1, 0xb9b1, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac, + 0xb9ac, 0x080c, 0x0df6, 0x86ff, 0x1520, 0x6020, 0x9086, 0x0006, + 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0168, 0xa87c, + 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, + 0x0fe9, 0x009e, 0x080c, 0xc04a, 0x009e, 0x080c, 0xc413, 0x6007, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f8, 0x080c, + 0x8b8f, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x192c, 0x006e, + 0x0890, 0x00e6, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x1120, 0x080c, + 0x983b, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006, + 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x995f, + 0x009e, 0x008e, 0x0010, 0x080c, 0x9738, 0x00ee, 0x1904, 0xb9eb, + 0x0804, 0xb9ac, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c, 0x9c06, + 0x1138, 0x901e, 0x080c, 0x98b1, 0x00ee, 0x003e, 0x0804, 0xb9eb, + 0x080c, 0x9a8f, 0x00ee, 0x003e, 0x1904, 0xb9eb, 0x0804, 0xb9ac, + 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xba6d, + 0xbb1d, 0xbc87, 0xba77, 0xa01c, 0xba6d, 0xd381, 0xc47b, 0xbb1d, + 0xba66, 0xbd13, 0xba66, 0xba66, 0xba66, 0xba66, 0x080c, 0x0df6, + 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x0005, 0x080c, 0x8a83, + 0x080c, 0x8b8f, 0x0804, 0x9fea, 0x601b, 0x0001, 0x0005, 0x080c, + 0xbd4e, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, + 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6, 0x0002, 0xba96, 0xba98, + 0xbabc, 0xbad0, 0xbaf6, 0xba96, 0xba6d, 0xba6d, 0xba6d, 0xbad0, + 0xbad0, 0xba96, 0xba96, 0xba96, 0xba96, 0xbada, 0x080c, 0x0df6, + 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, + 0x2071, 0x19c2, 0x7024, 0x9c06, 0x01a0, 0x080c, 0x9738, 0x080c, + 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, + 0x1961, 0x2004, 0x601a, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ee, + 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, + 0xc0b5, 0xa882, 0x009e, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003, + 0x000b, 0x6023, 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005, + 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, + 0x009e, 0x0005, 0x080c, 0x54e3, 0x01b8, 0x6014, 0x0096, 0x904d, + 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, + 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, + 0x0004, 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x6014, 0x0096, + 0x904d, 0x01f0, 0xa97c, 0xd1e4, 0x01d8, 0x2001, 0x180f, 0x2004, + 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b, + 0x810b, 0x9108, 0x611a, 0x00c6, 0x080c, 0x2165, 0x00ce, 0x6000, + 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005, + 0x009e, 0x080c, 0x192c, 0x0804, 0xbabc, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0df6, 0x000b, 0x0005, 0xbb34, 0xba74, 0xbb36, 0xbb34, + 0xbb36, 0xbb36, 0xba6e, 0xbb34, 0xba68, 0xba68, 0xbb34, 0xbb34, + 0xbb34, 0xbb34, 0xbb34, 0xbb34, 0x080c, 0x0df6, 0x6010, 0x00b6, + 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, + 0x0df6, 0x00b6, 0x0013, 0x00be, 0x0005, 0xbb51, 0xbc1e, 0xbb53, + 0xbb93, 0xbb53, 0xbb93, 0xbb53, 0xbb61, 0xbb51, 0xbb93, 0xbb51, + 0xbb82, 0x080c, 0x0df6, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, + 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, + 0xbc1a, 0x6004, 0x080c, 0xbf56, 0x0904, 0xbc37, 0x908e, 0x0004, + 0x1110, 0x080c, 0x30be, 0x908e, 0x0021, 0x0904, 0xbc3b, 0x908e, + 0x0022, 0x0904, 0xbc82, 0x908e, 0x003d, 0x0904, 0xbc3b, 0x908e, + 0x0039, 0x0904, 0xbc3f, 0x908e, 0x0035, 0x0904, 0xbc3f, 0x908e, + 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, + 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3095, 0x080c, + 0xa9a7, 0x0804, 0xa01c, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, + 0x0904, 0xbc0b, 0x9186, 0x0002, 0x1904, 0xbbe0, 0x2001, 0x1836, + 0x2004, 0xd08c, 0x11c8, 0x080c, 0x717e, 0x11b0, 0x080c, 0xc459, + 0x0138, 0x080c, 0x71a1, 0x1120, 0x080c, 0x707c, 0x0804, 0xbc6b, + 0x2001, 0x1957, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, + 0x080c, 0x709e, 0x0804, 0xbc6b, 0x6010, 0x2058, 0x2001, 0x1836, + 0x2004, 0xd0ac, 0x1904, 0xbc6b, 0xb8a0, 0x9084, 0xff80, 0x1904, + 0xbc6b, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, + 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, + 0x080c, 0x9f94, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, + 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, + 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1836, 0x2104, 0xc085, + 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x00ee, 0x080c, + 0xa9a7, 0x0030, 0x080c, 0xa9a7, 0x080c, 0x3095, 0x080c, 0xc46e, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30be, 0x012e, 0x00ee, + 0x080c, 0xa01c, 0x0005, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00de, + 0x00ce, 0x0c80, 0x080c, 0x30be, 0x0804, 0xbb8f, 0x00c6, 0x00d6, + 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, + 0x00ff, 0x9005, 0x0904, 0xbbe0, 0x8001, 0xb842, 0x6003, 0x0001, + 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00de, 0x00ce, 0x0898, 0x080c, + 0xa9a7, 0x0804, 0xbb91, 0x080c, 0xa9e3, 0x0804, 0xbb91, 0x00d6, + 0x2c68, 0x6104, 0x080c, 0xc3cf, 0x00de, 0x0118, 0x080c, 0x9fea, + 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, + 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, + 0x2001, 0x1961, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, + 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x0005, 0x00de, 0x00ce, 0x080c, 0xa9a7, 0x080c, + 0x3095, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30be, 0x6017, + 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e, + 0x00ee, 0x0005, 0x080c, 0xa41e, 0x1904, 0xbc37, 0x0005, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0df6, 0x0096, 0x00d6, 0x001b, 0x00de, + 0x009e, 0x0005, 0xbca2, 0xbca2, 0xbca2, 0xbca2, 0xbca2, 0xbca2, + 0xbca2, 0xbca2, 0xbca2, 0xba6d, 0xbca2, 0xba74, 0xbca4, 0xba74, + 0xbcbe, 0xbca2, 0x080c, 0x0df6, 0x6004, 0x9086, 0x008b, 0x01b0, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, + 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003, + 0x000d, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xc44d, + 0x0118, 0x080c, 0xc460, 0x0010, 0x080c, 0xc46e, 0x080c, 0xbf39, + 0x080c, 0xbd4e, 0x0570, 0x080c, 0x3095, 0x080c, 0xbd4e, 0x0168, + 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, + 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6a22, 0x2c68, 0x080c, 0x9f94, + 0x0150, 0x6810, 0x6012, 0x080c, 0xc1ca, 0x00c6, 0x2d60, 0x080c, + 0xa01c, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, + 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, + 0x00c8, 0x080c, 0xc44d, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118, + 0x080c, 0x3095, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, + 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3095, 0x0868, + 0x080c, 0xa01c, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6, + 0x0002, 0xbd29, 0xbd29, 0xbd2d, 0xbd2b, 0xbd37, 0xbd29, 0xbd29, + 0xa01c, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29, + 0xbd29, 0x080c, 0x0df6, 0x080c, 0x9a8f, 0x6114, 0x0096, 0x2148, + 0xa87b, 0x0006, 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x601c, + 0xd084, 0x190c, 0x192c, 0x0c88, 0x9284, 0x0007, 0x1158, 0x9282, + 0x1cd0, 0x0240, 0x2001, 0x1819, 0x2004, 0x9202, 0x1218, 0x9085, + 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, + 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, + 0x0110, 0x080c, 0x10e2, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, + 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071, + 0x1800, 0x7350, 0x7070, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, + 0x080c, 0xc459, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, + 0x0004, 0x1148, 0x080c, 0x3095, 0x080c, 0xc46e, 0x00c6, 0x080c, + 0xa01c, 0x00ce, 0x0060, 0x080c, 0xc144, 0x0148, 0x080c, 0xbf56, + 0x1110, 0x080c, 0xa9a7, 0x00c6, 0x080c, 0x9fea, 0x00ce, 0x9ce0, + 0x0018, 0x7064, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, + 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, + 0x210c, 0x81ff, 0x0128, 0x2061, 0x1a88, 0x6112, 0x080c, 0x3095, + 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f94, 0x01b0, 0x6656, + 0x2b00, 0x6012, 0x080c, 0x54e3, 0x0118, 0x080c, 0xbe7d, 0x0168, + 0x080c, 0xc1ca, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xa068, + 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xa03b, 0x0560, 0x6057, + 0x0000, 0x2b00, 0x6012, 0x080c, 0xc1ca, 0x6023, 0x0003, 0x0016, + 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x2c08, 0x080c, + 0xd556, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0x9fea, 0x9085, + 0x0001, 0x0070, 0x080c, 0x54e3, 0x0128, 0xd18c, 0x1170, 0x080c, + 0xbe7d, 0x0148, 0x2009, 0x004c, 0x080c, 0xa068, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, + 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, + 0x0016, 0x080c, 0x9f94, 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812, + 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xbe8f, 0x001e, + 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, 0x195a, + 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0x9fea, 0x00d0, 0x2001, + 0x1959, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0x9fea, 0x0088, + 0x2f60, 0x080c, 0x54e3, 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148, + 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xa068, 0x9085, + 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, + 0x0046, 0x080c, 0x9f94, 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812, + 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, 0x2001, + 0x1958, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0x9fea, 0x0060, + 0x2f60, 0x080c, 0x54e3, 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130, + 0x2009, 0x0052, 0x080c, 0xa068, 0x9085, 0x0001, 0x004e, 0x00ce, + 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, 0x49b7, + 0x00ce, 0x1120, 0x080c, 0x9fea, 0x9006, 0x0005, 0xa867, 0x0000, + 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, 0x0096, + 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x64d7, 0x0158, 0x2001, + 0xbe94, 0x0006, 0x900e, 0x2400, 0x080c, 0x6c6b, 0x080c, 0x6a22, + 0x000e, 0x0807, 0x2418, 0x080c, 0x8a1d, 0xbaa0, 0x0086, 0x2041, + 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x879a, 0x008e, 0x080c, + 0x8670, 0x2f08, 0x2648, 0x080c, 0xd556, 0xb93c, 0x81ff, 0x090c, + 0x886d, 0x080c, 0x8b8f, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0x9f94, 0x0190, 0x660a, 0x2b08, + 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, + 0x001f, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b, + 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0008, + 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x2009, + 0x0021, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, + 0x8000, 0x080c, 0x9f94, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, + 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, + 0xa068, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, + 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b, 0x0188, + 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, + 0x2009, 0x0000, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, + 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, + 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, + 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, + 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, + 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, + 0xbd4e, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, + 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, + 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b, 0x0198, 0x2b08, + 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, + 0x3095, 0x2009, 0x0028, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, + 0x1823, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xac41, + 0x00be, 0x080c, 0xae8d, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, + 0x8640, 0x080c, 0x8b8f, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, + 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xc390, 0x080c, + 0xa9a7, 0x080c, 0x9fea, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, + 0x0df6, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, + 0x012e, 0x009e, 0x080c, 0x9fea, 0x0c30, 0x0096, 0x9186, 0x0016, + 0x1128, 0x2001, 0x0004, 0x080c, 0x62f4, 0x00e8, 0x9186, 0x0015, + 0x1510, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, + 0x00b6, 0x2058, 0x080c, 0x643e, 0x00be, 0x080c, 0xaf63, 0x1198, + 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, + 0x0006, 0x080c, 0x62f4, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, + 0x080c, 0xa3f2, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, + 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x009e, 0x0005, 0x6014, 0x6310, + 0x2358, 0x904d, 0x090c, 0x0df6, 0xa87b, 0x0000, 0xa883, 0x0000, + 0xa897, 0x4000, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6a22, 0x012e, 0x080c, 0x9fea, 0x08f8, 0x6014, 0x904d, 0x090c, + 0x0df6, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, + 0x012e, 0x080c, 0x9fea, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, + 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000, + 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, + 0x0005, 0xba6d, 0xc07a, 0xc07a, 0xc07d, 0xd886, 0xd8a1, 0xd8a4, + 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, + 0x080c, 0x0df6, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, + 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, + 0x1833, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0x9f94, + 0x0508, 0x7810, 0x6012, 0x080c, 0xc1ca, 0x7820, 0x9086, 0x0003, + 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, + 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, + 0x0001, 0x7954, 0x6156, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x2f60, + 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1962, 0x2004, 0x6042, + 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180, + 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, + 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fe9, + 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, + 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, + 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, + 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, + 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, + 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954, 0x6156, + 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x85f8, + 0x080c, 0x8b8f, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, + 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, + 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, + 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, + 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, + 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, + 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, + 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, + 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, + 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, + 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, + 0x00e6, 0x2001, 0x195c, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, + 0x080c, 0x847e, 0x2001, 0x1960, 0x82ff, 0x1110, 0x2011, 0x0014, + 0x2202, 0x2001, 0x195e, 0x200c, 0x8000, 0x2014, 0x2071, 0x1946, + 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x847e, 0x2001, 0x1961, + 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1962, 0x9288, + 0x000a, 0x2102, 0x2001, 0x1a69, 0x2102, 0x2001, 0x0032, 0x080c, + 0x1580, 0x080c, 0x66aa, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1960, 0x2003, 0x0028, + 0x2001, 0x1961, 0x2003, 0x0014, 0x2071, 0x1946, 0x701b, 0x0000, + 0x701f, 0x07d0, 0x2001, 0x1962, 0x2009, 0x001e, 0x2102, 0x2001, + 0x1a69, 0x2102, 0x2001, 0x0032, 0x080c, 0x1580, 0x00ee, 0x001e, + 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c, 0x1069, + 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, + 0x9f94, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, + 0x6016, 0x2009, 0x0033, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, + 0x1800, 0x9186, 0x0015, 0x1520, 0x708c, 0x9086, 0x0018, 0x0120, + 0x708c, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, + 0x1160, 0x2c78, 0x080c, 0x8d93, 0x01d8, 0x7078, 0xaa50, 0x9206, + 0x1160, 0x707c, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, + 0xbaa0, 0x00be, 0x900e, 0x080c, 0x30de, 0x080c, 0xa3f2, 0x0020, + 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x0005, + 0x705c, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0x9f94, 0x0188, 0x2b08, 0x6112, 0x080c, 0xc1ca, + 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xa068, + 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0x9f94, 0x0180, 0x2b08, + 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, + 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, + 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, + 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, + 0x718c, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, + 0x0000, 0x2001, 0x197b, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, + 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c, + 0x080c, 0xca75, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, + 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xa9a7, 0x080c, + 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, + 0x9186, 0x0015, 0x11b8, 0x708c, 0x9086, 0x0004, 0x1198, 0x6014, + 0x2048, 0x2c78, 0x080c, 0x8d93, 0x01a8, 0x7078, 0xaa74, 0x9206, + 0x1130, 0x707c, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3095, 0x080c, + 0xa3f2, 0x0020, 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x00fe, 0x00ee, + 0x009e, 0x0005, 0x705c, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, + 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x708c, + 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x8d93, + 0x05f0, 0x7078, 0xaacc, 0x9206, 0x1180, 0x707c, 0xaad0, 0x9206, + 0x1160, 0x080c, 0x3095, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, + 0xc0fd, 0x080c, 0x548a, 0x001e, 0x0010, 0x080c, 0x5275, 0x080c, + 0xbd4e, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, + 0x0080, 0x080c, 0xbd4e, 0x01b8, 0x6014, 0x2048, 0x080c, 0x5275, + 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, + 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6a22, + 0x012e, 0x080c, 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, + 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, + 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, + 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, + 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xbd4e, + 0x0904, 0xc38c, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, + 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, + 0xd0f4, 0x1140, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, + 0x0006, 0x2098, 0x080c, 0x0fb4, 0x20a9, 0x0004, 0xa85c, 0x9080, + 0x0035, 0x20a0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fb4, + 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, + 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, + 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, + 0x6a15, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, + 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, + 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, + 0x9084, 0x00ff, 0x900e, 0x080c, 0x266d, 0x2118, 0x831f, 0x939c, + 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, + 0x080c, 0x4a17, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, + 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, + 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, + 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, + 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, + 0x080c, 0xbd3c, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, + 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, + 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, + 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, + 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0198, 0x918c, + 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, 0x000f, 0x918e, + 0x0001, 0x1140, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xb41b, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, + 0x901e, 0x0499, 0x01e0, 0x080c, 0xbd4e, 0x01c8, 0x080c, 0xbf39, + 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, + 0x080c, 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0040, 0xa867, 0x0103, + 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6a22, 0x009e, 0x003e, + 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, + 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, + 0x080c, 0xc04a, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, + 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, + 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, + 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, + 0x0007, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, + 0x0005, 0x2001, 0x1960, 0x2004, 0x601a, 0x0005, 0x2001, 0x1962, + 0x2004, 0x6042, 0x0005, 0x080c, 0x9fea, 0x0804, 0x8b8f, 0x2001, + 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19c2, + 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x84e2, 0x00ce, 0x00ee, + 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001, + 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0df6, + 0x001b, 0x006e, 0x00be, 0x0005, 0xc4bc, 0xcbd4, 0xcd47, 0xc4bc, + 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4f3, 0xcdcb, 0xc4bc, 0xc4bc, + 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0x080c, 0x0df6, 0x0066, 0x6000, + 0x90b2, 0x0010, 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005, 0xc4d7, + 0xd31a, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xd2c7, + 0xd36e, 0xc4d7, 0xd9c1, 0xd9f7, 0xd9c1, 0xd9f7, 0xc4d7, 0x080c, + 0x0df6, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0df6, 0x6000, 0x000a, + 0x0005, 0xc4f1, 0xcfa9, 0xd078, 0xd09b, 0xd15b, 0xc4f1, 0xd23a, + 0xd1e3, 0xcdd7, 0xd29d, 0xd2b2, 0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1, + 0xc4f1, 0x080c, 0x0df6, 0x91b2, 0x0053, 0x1a0c, 0x0df6, 0x2100, + 0x91b2, 0x0040, 0x1a04, 0xc971, 0x0002, 0xc53d, 0xc73f, 0xc53d, + 0xc53d, 0xc53d, 0xc748, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, + 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, + 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53f, 0xc5a2, 0xc5b1, 0xc615, + 0xc640, 0xc6b8, 0xc72a, 0xc53d, 0xc53d, 0xc74b, 0xc53d, 0xc53d, + 0xc760, 0xc76d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc813, + 0xc53d, 0xc53d, 0xc827, 0xc53d, 0xc53d, 0xc7e2, 0xc53d, 0xc53d, + 0xc53d, 0xc83f, 0xc53d, 0xc53d, 0xc53d, 0xc8bc, 0xc53d, 0xc53d, + 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc939, 0x080c, 0x0df6, 0x080c, + 0x6687, 0x1150, 0x2001, 0x1836, 0x2004, 0xd0cc, 0x1128, 0x9084, + 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, + 0x6017, 0x0000, 0x0804, 0xc738, 0x080c, 0x6670, 0x00e6, 0x00c6, + 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, + 0x0029, 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x2c08, + 0x080c, 0xd556, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, + 0x00ee, 0x6610, 0x2658, 0x080c, 0x63b2, 0xbe04, 0x9684, 0x00ff, + 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, + 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xdb71, 0x002e, 0x001e, 0x1178, + 0x080c, 0xd489, 0x1904, 0xc60d, 0x080c, 0xd425, 0x1120, 0x6007, + 0x0008, 0x0804, 0xc738, 0x6007, 0x0009, 0x0804, 0xc738, 0x080c, + 0xd6c7, 0x0128, 0x080c, 0xd489, 0x0d78, 0x0804, 0xc60d, 0x6017, + 0x1900, 0x0c88, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x6106, 0x080c, + 0xd3c9, 0x6007, 0x0006, 0x0804, 0xc738, 0x6007, 0x0007, 0x0804, + 0xc738, 0x080c, 0xda33, 0x1904, 0xc96e, 0x080c, 0x31b8, 0x1904, + 0xc96e, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, + 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x62e0, 0x96b4, 0xff00, + 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, + 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, + 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, + 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, + 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, + 0x0007, 0x00b0, 0x00ee, 0x080c, 0xd4ec, 0x1190, 0x9686, 0x0006, + 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x30de, + 0x002e, 0x080c, 0x643e, 0x6007, 0x000a, 0x00de, 0x0804, 0xc738, + 0x6007, 0x000b, 0x00de, 0x0804, 0xc738, 0x080c, 0x3095, 0x080c, + 0xc46e, 0x6007, 0x0001, 0x0804, 0xc738, 0x080c, 0xda33, 0x1904, + 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x2071, 0x0260, 0x7034, + 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, + 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, + 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x30de, 0x002e, + 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xdb50, 0x0804, 0xc738, + 0x080c, 0x6687, 0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009, + 0x9086, 0x0008, 0x1110, 0x0804, 0xc54c, 0x080c, 0x6670, 0x6610, + 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c0, 0x1138, + 0x0026, 0x2001, 0x0006, 0x080c, 0x6320, 0x002e, 0x0050, 0x96b4, + 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, + 0xc60d, 0x080c, 0xd4f9, 0x1120, 0x6007, 0x000e, 0x0804, 0xc738, + 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3095, 0x080c, + 0xc46e, 0x004e, 0x0016, 0x9006, 0x2009, 0x185c, 0x210c, 0x0048, + 0x2009, 0x0029, 0x080c, 0xd837, 0x6010, 0x2058, 0xb800, 0xc0e5, + 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xc738, 0x2001, + 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, + 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xb003, 0x003e, + 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, + 0x9682, 0x0004, 0x0a04, 0xc60d, 0x9682, 0x0007, 0x0a04, 0xc669, + 0x0804, 0xc60d, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xc738, + 0x080c, 0x6687, 0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009, + 0x9086, 0x0008, 0x1110, 0x0804, 0xc54c, 0x080c, 0x6670, 0x6610, + 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001, + 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, 0x001e, + 0x000e, 0x9082, 0x0006, 0x0698, 0x0150, 0x96b4, 0xff00, 0x8637, + 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xc60d, 0x080c, + 0xd527, 0x1138, 0x080c, 0xd425, 0x1120, 0x6007, 0x0010, 0x0804, + 0xc738, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3095, + 0x080c, 0xc46e, 0x004e, 0x0016, 0x9006, 0x2009, 0x185c, 0x210c, + 0x0048, 0x2009, 0x0029, 0x080c, 0xd837, 0x6010, 0x2058, 0xb800, + 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, + 0xd6c7, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, + 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, + 0x0006, 0x0928, 0x0804, 0xc60d, 0x001e, 0x6017, 0x1900, 0x6007, + 0x0009, 0x0070, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, 0xda33, + 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904, 0xc60d, 0x6007, 0x0012, + 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0cb0, + 0x6007, 0x0005, 0x0c68, 0x080c, 0xda33, 0x1904, 0xc96e, 0x080c, + 0x31b8, 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904, 0xc60d, 0x6007, + 0x0020, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, + 0x080c, 0x31b8, 0x1904, 0xc96e, 0x6007, 0x0023, 0x6003, 0x0001, + 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xda33, 0x1904, + 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904, + 0xc60d, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, + 0x181f, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181e, 0x2214, + 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xbd3c, + 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, + 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0x9fea, + 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xbd3c, + 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, + 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, + 0x080c, 0xd809, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, + 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, + 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, + 0x9086, 0x0024, 0x1110, 0x080c, 0x9fea, 0x2160, 0x6007, 0x0025, + 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00ee, 0x002e, + 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016, + 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, + 0x080c, 0xb003, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, + 0x0031, 0x0804, 0xc738, 0x080c, 0xac59, 0x080c, 0x717e, 0x1190, + 0x0006, 0x0026, 0x0036, 0x080c, 0x7198, 0x1138, 0x080c, 0x747a, + 0x080c, 0x5e2f, 0x080c, 0x709e, 0x0010, 0x080c, 0x7156, 0x003e, + 0x002e, 0x000e, 0x0005, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, + 0xcb12, 0x1904, 0xc60d, 0x6106, 0x080c, 0xcb2e, 0x1120, 0x6007, + 0x002b, 0x0804, 0xc738, 0x6007, 0x002c, 0x0804, 0xc738, 0x080c, + 0xda33, 0x1904, 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, + 0xcb12, 0x1904, 0xc60d, 0x6106, 0x080c, 0xcb33, 0x1120, 0x6007, + 0x002e, 0x0804, 0xc738, 0x6007, 0x002f, 0x0804, 0xc738, 0x080c, + 0x31b8, 0x1904, 0xc96e, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, + 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, + 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, + 0xc73f, 0x080c, 0x54df, 0xd0e4, 0x0904, 0xc8b9, 0x2071, 0x026c, + 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x66c5, + 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, + 0x0510, 0x080c, 0x66c1, 0x15b8, 0x2069, 0x1800, 0x687c, 0x9206, + 0x1590, 0x6878, 0x9106, 0x1578, 0x7210, 0x080c, 0xbd3c, 0x0590, + 0x080c, 0xc9ff, 0x0578, 0x080c, 0xd8b3, 0x0560, 0x622e, 0x6007, + 0x0036, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce, + 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, + 0xbd3c, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, + 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xd809, 0x2c10, + 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, + 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, + 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x31b8, 0x1904, 0xc96e, + 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, + 0x1904, 0xc73f, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x54df, 0xd0e4, + 0x0904, 0xc931, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, + 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, + 0x9085, 0x0001, 0x080c, 0xd809, 0x2c10, 0x00ce, 0x05e8, 0x080c, + 0xbd3c, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, + 0x00c6, 0x0026, 0x2260, 0x080c, 0xb976, 0x002e, 0x00ce, 0x7118, + 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, + 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, + 0x0170, 0x080c, 0xc9ff, 0x0904, 0xc8b2, 0x0056, 0x7510, 0x7614, + 0x080c, 0xd8cc, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, + 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c, + 0x85f8, 0x080c, 0x8b8f, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, + 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, + 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, + 0xc889, 0x00e6, 0x0026, 0x080c, 0x6687, 0x0550, 0x080c, 0x6670, + 0x080c, 0xdaa4, 0x1518, 0x2071, 0x1800, 0x70d8, 0x9085, 0x0003, + 0x70da, 0x00f6, 0x2079, 0x0100, 0x72ac, 0x9284, 0x00ff, 0x707a, + 0x78e6, 0x9284, 0xff00, 0x727c, 0x9205, 0x707e, 0x78ea, 0x00fe, + 0x70e3, 0x0000, 0x080c, 0x66c5, 0x0120, 0x2011, 0x19db, 0x2013, + 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2e73, 0x0010, 0x080c, 0xdad8, + 0x002e, 0x00ee, 0x080c, 0x9fea, 0x0804, 0xc73e, 0x080c, 0x9fea, + 0x0005, 0x2600, 0x0002, 0xc985, 0xc985, 0xc985, 0xc985, 0xc985, + 0xc987, 0xc985, 0xc985, 0xc985, 0xc985, 0xc9a1, 0xc985, 0xc985, + 0xc985, 0xc9b3, 0xc9c9, 0xc9fa, 0xc985, 0x080c, 0x0df6, 0x080c, + 0xda33, 0x1d20, 0x080c, 0x31b8, 0x1d08, 0x7038, 0x6016, 0x6007, + 0x0045, 0x6003, 0x0001, 0x080c, 0x8640, 0x0005, 0x080c, 0x3095, + 0x080c, 0xc46e, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, + 0x0005, 0x080c, 0xda33, 0x1950, 0x080c, 0x31b8, 0x1938, 0x080c, + 0xcb12, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, + 0x080c, 0x8640, 0x0005, 0x2001, 0x1823, 0x2004, 0x9082, 0x00e1, + 0x1268, 0x080c, 0xca1c, 0x0904, 0xc96e, 0x6007, 0x004e, 0x6003, + 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x6007, 0x0012, + 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, + 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x1998, + 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x1999, 0x2004, 0x9106, + 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, + 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xb017, 0x009e, + 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, + 0x8b8f, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, + 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, + 0xb8bc, 0xd084, 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c, + 0x6048, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, + 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, + 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1, + 0x0000, 0x2001, 0x197b, 0x2003, 0x0000, 0x080c, 0x1050, 0x05a0, + 0x2900, 0x6016, 0x708c, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0, + 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c, 0x0471, 0x001e, + 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1050, 0x01b0, 0x2900, 0xa006, + 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c, 0x00b1, 0x001e, + 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x708f, 0x0000, + 0x6014, 0x2048, 0x080c, 0x0fe9, 0x9006, 0x012e, 0x01de, 0x01ce, + 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, + 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, 0x21d9, 0x2099, + 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, + 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x21d9, + 0x2099, 0x0260, 0x0ca8, 0x080c, 0x21d9, 0x2061, 0x197b, 0x6004, + 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, + 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x21d9, 0x2099, + 0x0260, 0x0ca8, 0x2061, 0x197b, 0x2019, 0x0280, 0x3300, 0x931e, + 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, + 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x81ff, 0x11b8, 0x080c, 0x21f1, 0x20a1, 0x024c, 0x2001, 0x0014, + 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, + 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x21f1, 0x20a1, 0x0240, + 0x0c98, 0x080c, 0x21f1, 0x2061, 0x197e, 0x6004, 0x20a0, 0x6008, + 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, + 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x21f1, 0x20a1, 0x0240, + 0x0c98, 0x2061, 0x197e, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, + 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, + 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, + 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, + 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, + 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, + 0xcbaa, 0x00de, 0x0005, 0x00d6, 0x080c, 0xcbb7, 0x1520, 0x680c, + 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, + 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xdb50, 0x2009, 0x0001, + 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, + 0x266d, 0x1148, 0x2001, 0x0001, 0x080c, 0xdb50, 0x2110, 0x900e, + 0x080c, 0x30de, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, + 0x0005, 0x00b6, 0x00c6, 0x080c, 0xa03b, 0x05a8, 0x0016, 0x0026, + 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x266d, + 0x1578, 0x080c, 0x6343, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, + 0x001e, 0x2b00, 0x6012, 0x080c, 0xda33, 0x11d8, 0x080c, 0x31b8, + 0x11c0, 0x080c, 0xcb12, 0x0510, 0x2001, 0x0007, 0x080c, 0x62f4, + 0x2001, 0x0007, 0x080c, 0x6320, 0x6017, 0x0000, 0x6023, 0x0001, + 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, + 0x0010, 0x080c, 0x9fea, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, + 0x080c, 0x9fea, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0x9fea, + 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, + 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, + 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, + 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, + 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, + 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, + 0x0df6, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, + 0xcd17, 0x040a, 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118, + 0x9186, 0x0016, 0x1148, 0x080c, 0xc47f, 0x0128, 0x6000, 0x9086, + 0x0002, 0x0904, 0xa9ee, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0df6, + 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x8a83, 0x080c, 0xa01c, + 0x080c, 0x8b8f, 0x0005, 0xcc43, 0xcc45, 0xcc43, 0xcc43, 0xcc43, + 0xcc45, 0xcc54, 0xcd10, 0xcc98, 0xcd10, 0xccbe, 0xcd10, 0xcc54, + 0xcd10, 0xcd08, 0xcd10, 0xcd08, 0xcd10, 0xcd10, 0xcc43, 0xcc43, + 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, + 0xcc43, 0xcc45, 0xcc43, 0xcd10, 0xcc43, 0xcc43, 0xcd10, 0xcc43, + 0xcd0d, 0xcd10, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcd10, 0xcd10, + 0xcc43, 0xcd10, 0xcd10, 0xcc43, 0xcc4f, 0xcc43, 0xcc43, 0xcc43, + 0xcc43, 0xcd0c, 0xcd10, 0xcc43, 0xcc43, 0xcd10, 0xcd10, 0xcc43, + 0xcc43, 0xcc43, 0xcc43, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c, + 0xc471, 0x6003, 0x0002, 0x080c, 0x8b8f, 0x0804, 0xcd16, 0x9006, + 0x080c, 0x62e0, 0x0804, 0xcd10, 0x080c, 0x66c1, 0x1904, 0xcd10, + 0x9006, 0x080c, 0x62e0, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, + 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, + 0x00b8, 0x6010, 0x2058, 0xb8b0, 0x9005, 0x0904, 0xcd10, 0x080c, + 0x31e9, 0x1904, 0xcd10, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, + 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, + 0x2001, 0x0002, 0x080c, 0x62f4, 0x080c, 0x8a83, 0x6023, 0x0001, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, + 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8267, 0x0804, 0xcd16, + 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, + 0x0138, 0x9686, 0x0004, 0x0120, 0x2001, 0x0004, 0x080c, 0x6320, + 0x080c, 0xdb9f, 0x0904, 0xcd10, 0x080c, 0x8a83, 0x2001, 0x0004, + 0x080c, 0x62f4, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0003, + 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0804, 0xcd16, 0x2001, 0x1800, + 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, + 0xbba0, 0x2021, 0x0006, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x2001, + 0x0006, 0x080c, 0xcd34, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, + 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001, 0x0006, + 0x080c, 0x6320, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118, 0x908e, + 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x62f4, 0x080c, 0x66c1, + 0x11f8, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, + 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a4, + 0x8000, 0x78a6, 0x00fe, 0x0804, 0xcc80, 0x2001, 0x0004, 0x0030, + 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, 0x0010, 0x080c, 0x6320, + 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x2600, + 0x0002, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d, 0xcd2b, + 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d, + 0xcd2d, 0xcd2d, 0xcd2d, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c, + 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, + 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x62f4, 0x9006, 0x080c, + 0x62e0, 0x080c, 0x30be, 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, + 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, + 0x0df6, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, + 0x190c, 0x0df6, 0x006b, 0x0005, 0xaa88, 0xaa88, 0xaa88, 0xaa88, + 0xcdc9, 0xaa88, 0xcdb3, 0xcd74, 0xaa88, 0xaa88, 0xaa88, 0xaa88, + 0xaa88, 0xaa88, 0xaa88, 0xaa88, 0xcdc9, 0xaa88, 0xcdb3, 0xcdba, + 0xaa88, 0xaa88, 0xaa88, 0xaa88, 0x00f6, 0x080c, 0x66c1, 0x11d8, + 0x080c, 0xc459, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8b0, 0x9005, + 0x0190, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, + 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, + 0x080c, 0x8b8f, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, + 0x080c, 0x266d, 0x11b0, 0x080c, 0x63a3, 0x0118, 0x080c, 0x9fea, + 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb8b0, 0x0006, 0x080c, + 0x5e49, 0x000e, 0xb8b2, 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, + 0x9fea, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, + 0x9fea, 0x0005, 0x080c, 0xae8a, 0x1148, 0x6003, 0x0001, 0x6007, + 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0010, 0x080c, 0x9fea, + 0x0005, 0x0804, 0x9fea, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6, + 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x9182, + 0x0040, 0x0002, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdf0, 0xcdee, + 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, + 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0x080c, 0x0df6, + 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, + 0x2258, 0xb8ac, 0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, 0x7444, + 0x94a4, 0xff00, 0x0904, 0xce56, 0x080c, 0xdb44, 0x1170, 0x9486, + 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8450, + 0x0020, 0x9026, 0x080c, 0xda78, 0x0c38, 0x080c, 0x1037, 0x090c, + 0x0df6, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, + 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0, + 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000, + 0xa887, 0x0036, 0x080c, 0x6a22, 0x001e, 0x080c, 0xdb44, 0x1904, + 0xceb6, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xd7af, + 0x0804, 0xceb6, 0x9486, 0x0200, 0x1120, 0x080c, 0xd746, 0x0804, + 0xceb6, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xceb6, + 0x2019, 0x0002, 0x080c, 0xd761, 0x0804, 0xceb6, 0x2069, 0x1a4c, + 0x6a00, 0xd284, 0x0904, 0xcf20, 0x9284, 0x0300, 0x1904, 0xcf19, + 0x6804, 0x9005, 0x0904, 0xcf01, 0x2d78, 0x6003, 0x0007, 0x080c, + 0x1050, 0x0904, 0xcec2, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, + 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, + 0xcf24, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2, + 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876, + 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6, + 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xcebe, 0x2005, + 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021, + 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8, + 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c, + 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6a22, 0x002e, 0x004e, + 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080, + 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, + 0x1037, 0x1904, 0xce6b, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, + 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0c00, 0x2069, 0x0260, + 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, + 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, + 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x85f8, 0x080c, 0x8b8f, + 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003, + 0x0001, 0x6007, 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0804, + 0xceb6, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x4a17, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003, + 0x0001, 0x6007, 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0804, + 0xceb6, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xced6, + 0x6017, 0xf200, 0x0804, 0xced6, 0xa867, 0x0146, 0xa86b, 0x0000, + 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, + 0xcebe, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876, + 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896, + 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a, + 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2, + 0x9282, 0x0111, 0x1a0c, 0x0df6, 0x8210, 0x821c, 0x2001, 0x026c, + 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, + 0xcfa0, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, + 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, + 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, + 0x1050, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, + 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x1069, 0x0cc8, 0x080c, + 0x1069, 0x0804, 0xcec2, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, + 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xd7e2, 0x0804, 0xceb6, + 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a, + 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, + 0x0df6, 0x9082, 0x0040, 0x0a0c, 0x0df6, 0x2008, 0x0804, 0xd02f, + 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, 0xc47f, 0x0500, 0x6000, + 0x9086, 0x0002, 0x11e0, 0x0804, 0xd078, 0x9186, 0x0027, 0x0190, + 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0160, 0x190c, 0x0df6, + 0x080c, 0xc47f, 0x0160, 0x6000, 0x9086, 0x0004, 0x190c, 0x0df6, + 0x0804, 0xd15b, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, + 0xa083, 0x0005, 0xcff6, 0xcff8, 0xcff8, 0xd01f, 0xcff6, 0xcff6, + 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, + 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0x080c, 0x0df6, + 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x0036, 0x0096, 0x6014, 0x904d, + 0x01d8, 0x080c, 0xbd4e, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, + 0xd7e2, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1961, + 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, + 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x080c, 0xbd4e, 0x0120, 0x6014, + 0x2048, 0x080c, 0x1069, 0x080c, 0xa01c, 0x009e, 0x0005, 0x0002, + 0xd044, 0xd05b, 0xd046, 0xd072, 0xd044, 0xd044, 0xd044, 0xd044, + 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, + 0xd044, 0xd044, 0xd044, 0xd044, 0x080c, 0x0df6, 0x0096, 0x080c, + 0x8a83, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, + 0x2009, 0x0043, 0x080c, 0xa068, 0x0010, 0x6003, 0x0004, 0x080c, + 0x8b8f, 0x009e, 0x0005, 0x080c, 0x8a83, 0x080c, 0xbd4e, 0x0138, + 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c, + 0x8425, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xda3c, + 0x0db0, 0x0cc8, 0x080c, 0x8a83, 0x2009, 0x0041, 0x0804, 0xd1e3, + 0x9182, 0x0040, 0x0002, 0xd08f, 0xd091, 0xd08f, 0xd08f, 0xd08f, + 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, + 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd092, 0xd08f, 0xd08f, 0x080c, + 0x0df6, 0x0005, 0x00d6, 0x080c, 0x8425, 0x00de, 0x080c, 0xda94, + 0x080c, 0x9fea, 0x0005, 0x9182, 0x0040, 0x0002, 0xd0b2, 0xd0b2, + 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b4, + 0xd123, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd123, 0xd0b2, 0xd0b2, + 0xd0b2, 0xd0b2, 0x080c, 0x0df6, 0x2001, 0x0105, 0x2004, 0x9084, + 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004, + 0x9105, 0x1904, 0xd123, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0904, + 0xd123, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd, + 0x9085, 0x0010, 0x200a, 0x2001, 0x187b, 0x2004, 0xd0e4, 0x1528, + 0x603b, 0x0000, 0x080c, 0x8b3f, 0x6014, 0x0096, 0x2048, 0xa87c, + 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001, + 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x8c6c, 0x2009, 0x0041, + 0x009e, 0x0804, 0xd1e3, 0x080c, 0x8c6c, 0x6003, 0x0007, 0x601b, + 0x0000, 0x080c, 0x8425, 0x009e, 0x0005, 0x2001, 0x0100, 0x2004, + 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890, + 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c, + 0x2ab1, 0x080c, 0x8c6c, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130, + 0x080c, 0x8425, 0x080c, 0x9fea, 0x009e, 0x0005, 0x080c, 0xda3c, + 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, + 0x0036, 0x080c, 0x8b3f, 0x080c, 0x8c6c, 0x6014, 0x0096, 0x2048, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c, + 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a, + 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080, + 0x2019, 0x0004, 0x080c, 0xd7e2, 0x6018, 0x9005, 0x1128, 0x2001, + 0x1961, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007, + 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xd172, 0xd172, + 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd174, 0xd172, + 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, + 0xd172, 0xd1bf, 0x080c, 0x0df6, 0x6014, 0x0096, 0x2048, 0xa834, + 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190, + 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e, + 0x0804, 0xd1e3, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8425, + 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac, + 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c, + 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158, + 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c, + 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c, + 0x8427, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024, + 0xd0f4, 0x0128, 0x080c, 0x1577, 0x1904, 0xd174, 0x0005, 0x6014, + 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c, + 0x1577, 0x1904, 0xd174, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, + 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, + 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186, + 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0df6, 0x6024, 0xd0dc, + 0x090c, 0x0df6, 0x0005, 0xd207, 0xd213, 0xd21f, 0xd22b, 0xd207, + 0xd207, 0xd207, 0xd207, 0xd20e, 0xd209, 0xd209, 0xd207, 0xd207, + 0xd207, 0xd207, 0xd209, 0xd207, 0xd209, 0xd207, 0xd20e, 0x080c, + 0x0df6, 0x6024, 0xd0dc, 0x090c, 0x0df6, 0x0005, 0x6014, 0x9005, + 0x190c, 0x0df6, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x85f8, + 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x6003, + 0x0001, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8b8f, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, + 0x1a7e, 0x0126, 0x2091, 0x8000, 0x080c, 0x865d, 0x080c, 0x8c6c, + 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, + 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xd25a, 0xd25c, + 0xd26e, 0xd288, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, + 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, + 0xd25a, 0xd25a, 0x080c, 0x0df6, 0x6014, 0x2048, 0xa87c, 0xd0fc, + 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, 0x0001, + 0x6106, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0470, 0x6014, 0x2048, + 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140, + 0x6003, 0x0001, 0x6106, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00e0, + 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xd7e2, 0x00a0, + 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e, + 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a7e, + 0x080c, 0x865d, 0x080c, 0x8c6c, 0x0005, 0x080c, 0x8a83, 0x6114, + 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xdae1, 0x0036, 0x2019, + 0x0029, 0x080c, 0xd7e2, 0x003e, 0x009e, 0x080c, 0xa01c, 0x080c, + 0x8b8f, 0x0005, 0x080c, 0x8b3f, 0x6114, 0x81ff, 0x0158, 0x0096, + 0x2148, 0x080c, 0xdae1, 0x0036, 0x2019, 0x0029, 0x080c, 0xd7e2, + 0x003e, 0x009e, 0x080c, 0xa01c, 0x080c, 0x8c6c, 0x0005, 0x9182, + 0x0085, 0x0002, 0xd2d9, 0xd2d7, 0xd2d7, 0xd2e5, 0xd2d7, 0xd2d7, + 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0x080c, + 0x0df6, 0x6003, 0x000b, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091, + 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, + 0xda33, 0x0118, 0x080c, 0x9fea, 0x0450, 0x2071, 0x0260, 0x7224, + 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, + 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xa30b, + 0x7220, 0x080c, 0xd637, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, + 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, + 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x080c, 0x8c6c, 0x00ee, + 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, + 0x0a0c, 0x0df6, 0x908a, 0x0092, 0x1a0c, 0x0df6, 0x9082, 0x0085, + 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, + 0xa083, 0x0050, 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x8a83, + 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0xd34a, 0xd34c, 0xd34c, + 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, + 0xd34a, 0xd34a, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c, 0xa01c, + 0x080c, 0x8b8f, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0df6, 0x9182, + 0x0092, 0x1a0c, 0x0df6, 0x9182, 0x0085, 0x0002, 0xd36b, 0xd36b, + 0xd36b, 0xd36d, 0xd36b, 0xd36b, 0xd36b, 0xd36b, 0xd36b, 0xd36b, + 0xd36b, 0xd36b, 0xd36b, 0x080c, 0x0df6, 0x0005, 0x9186, 0x0013, + 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, + 0xa083, 0x0030, 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f, + 0x0005, 0x0036, 0x080c, 0xda94, 0x6043, 0x0000, 0x2019, 0x000b, + 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, + 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, + 0x995f, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, 0x9a0a, + 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, 0x9086, + 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xda94, + 0x080c, 0xc471, 0x080c, 0x192c, 0x6023, 0x0007, 0x6014, 0x2048, + 0x080c, 0xbd4e, 0x0110, 0x080c, 0xd7e2, 0x009e, 0x6017, 0x0000, + 0x080c, 0xda94, 0x6023, 0x0007, 0x080c, 0xc471, 0x003e, 0x012e, + 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, + 0x7938, 0x783c, 0x080c, 0x266d, 0x1904, 0xd41f, 0x0016, 0x00c6, + 0x080c, 0x63a3, 0x1904, 0xd41d, 0x001e, 0x00c6, 0x080c, 0xc459, + 0x1130, 0xb8b0, 0x9005, 0x0118, 0x080c, 0x31e9, 0x0148, 0x2b10, + 0x2160, 0x6010, 0x0006, 0x6212, 0x080c, 0xc460, 0x000e, 0x6012, + 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x9ad0, + 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x007e, 0x001e, + 0x0076, 0x903e, 0x080c, 0xd556, 0x007e, 0x0026, 0xba04, 0x9294, + 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, + 0xbaa0, 0x080c, 0x3152, 0x002e, 0xbcb0, 0x001e, 0x080c, 0x5e49, + 0xbe12, 0xbd16, 0xbcb2, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, + 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, + 0x0016, 0x2009, 0x1823, 0x2104, 0x9086, 0x0074, 0x1904, 0xd47e, + 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, + 0x8000, 0x0904, 0xd47b, 0x2001, 0x1956, 0x2004, 0x9005, 0x1140, + 0x6010, 0x2058, 0xb8b0, 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, + 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xdb49, 0x0118, 0x6978, + 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, + 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, + 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, 0x0001, 0x0298, + 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, + 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, 0x0900, 0x0040, + 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, + 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, + 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, + 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, + 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, 0x0138, 0x9286, + 0x0004, 0x0120, 0x080c, 0x63b2, 0x0804, 0xd4e5, 0x2011, 0x0276, + 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb017, + 0x009e, 0x15a0, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, + 0x2019, 0x0006, 0x080c, 0xb017, 0x009e, 0x1540, 0x0046, 0x0016, + 0xbaa0, 0x2220, 0x9006, 0x2009, 0x185c, 0x210c, 0x0038, 0x2009, + 0x0029, 0x080c, 0xd837, 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029, + 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c, 0x8670, 0x2c08, + 0x080c, 0xd556, 0x007e, 0x2001, 0x0007, 0x080c, 0x6320, 0x2001, + 0x0007, 0x080c, 0x62f4, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, + 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, + 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, + 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, + 0x026c, 0x7930, 0x7834, 0x080c, 0x266d, 0x11d0, 0x080c, 0x63a3, + 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, + 0x000a, 0x080c, 0xb017, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, + 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xb017, 0x009e, + 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, + 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, + 0x8211, 0x220c, 0x080c, 0x266d, 0x11d0, 0x080c, 0x63a3, 0x11b8, + 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, + 0x080c, 0xb017, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xb017, 0x009e, 0x015e, + 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, + 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, + 0x8000, 0x2740, 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424, + 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, 0x81ff, 0x0150, + 0x0006, 0x9186, 0x1a88, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, + 0xd5f0, 0x0018, 0x9606, 0x0904, 0xd5f0, 0x2100, 0x9c06, 0x0904, + 0xd5e7, 0x6720, 0x9786, 0x0007, 0x0904, 0xd5e7, 0x080c, 0xd878, + 0x1904, 0xd5e7, 0x080c, 0xdb67, 0x0904, 0xd5e7, 0x080c, 0xd868, + 0x0904, 0xd5e7, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x31e9, + 0x0904, 0xd60b, 0x6004, 0x9086, 0x0000, 0x1904, 0xd60b, 0x9786, + 0x0004, 0x0904, 0xd60b, 0x2500, 0x9c06, 0x0904, 0xd5e7, 0x2400, + 0x9c06, 0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, + 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x192c, 0x001e, + 0x9786, 0x000a, 0x0148, 0x080c, 0xbf56, 0x1130, 0x080c, 0xa9a7, + 0x009e, 0x080c, 0xa01c, 0x0418, 0x6014, 0x2048, 0x080c, 0xbd4e, + 0x01d8, 0x9786, 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, + 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e, 0xab7a, + 0xa877, 0x0000, 0x080c, 0xdae1, 0x0016, 0x080c, 0xc044, 0x080c, + 0x6a15, 0x001e, 0x080c, 0xbf39, 0x009e, 0x080c, 0xa01c, 0x9ce0, + 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd56a, + 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, + 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, + 0x080c, 0xdae1, 0x080c, 0xd7e2, 0x08f8, 0x009e, 0x0c00, 0x9786, + 0x000a, 0x0968, 0x0808, 0x81ff, 0x09d0, 0x9180, 0x0001, 0x2004, + 0x9086, 0x0018, 0x0130, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, + 0x1970, 0x6000, 0x9086, 0x0002, 0x1950, 0x080c, 0xbf45, 0x0130, + 0x080c, 0xbf56, 0x1920, 0x080c, 0xa9a7, 0x0038, 0x080c, 0x30be, + 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x080c, 0xa01c, 0x0804, + 0xd5e7, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, + 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xd809, 0x001e, + 0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, + 0xd656, 0xd656, 0xd656, 0xd656, 0xd656, 0xd656, 0xd658, 0xd656, + 0xd656, 0xd656, 0xd681, 0xa01c, 0xa01c, 0xd656, 0x9006, 0x0005, + 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, + 0x2c00, 0x2009, 0x0020, 0x080c, 0xd837, 0x001e, 0x004e, 0x2019, + 0x0002, 0x080c, 0xd38f, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, + 0x080c, 0xbd4e, 0x0140, 0x6014, 0x904d, 0x080c, 0xb983, 0x687b, + 0x0005, 0x080c, 0x6a22, 0x009e, 0x080c, 0xa01c, 0x9085, 0x0001, + 0x0005, 0x0019, 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0df6, 0x000b, 0x0005, 0xd69c, 0xd69c, 0xd6b3, 0xd6a3, + 0xd6c2, 0xd69c, 0xd69c, 0xd69e, 0xd69c, 0xd69c, 0xd69c, 0xd69c, + 0xd69c, 0xd69c, 0xd69c, 0xd69c, 0x080c, 0x0df6, 0x080c, 0xa01c, + 0x9085, 0x0001, 0x0005, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c, + 0x9c06, 0x1128, 0x2019, 0x0001, 0x080c, 0x98b1, 0x0010, 0x080c, + 0x9a8f, 0x00ee, 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, + 0x0005, 0x080c, 0x6a22, 0x080c, 0xa01c, 0x00de, 0x009e, 0x9085, + 0x0001, 0x0005, 0x601c, 0xd084, 0x190c, 0x192c, 0x0c60, 0x2001, + 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, + 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xb003, 0x003e, + 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, + 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, + 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd739, 0x2071, + 0x1800, 0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd739, 0x88ff, + 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xd868, 0x0580, + 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, + 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, + 0x11f8, 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, + 0xd084, 0x0140, 0x080c, 0xda94, 0x080c, 0xc471, 0x080c, 0x192c, + 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0120, 0x0046, + 0x080c, 0xd7e2, 0x004e, 0x009e, 0x080c, 0xa01c, 0x88ff, 0x1198, + 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, + 0xd6ec, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, + 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076, + 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, + 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, + 0x903e, 0x080c, 0x9a0a, 0x080c, 0xd6dd, 0x005e, 0x007e, 0x00be, + 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, + 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x63a3, + 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, + 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a, + 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xd76c, 0x0036, 0x2508, + 0x2029, 0x0003, 0x080c, 0xd6dd, 0x003e, 0x015e, 0x00ce, 0x007e, + 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, + 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, + 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a, + 0x2c20, 0x080c, 0xd6dd, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, + 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, + 0x900e, 0x0016, 0x0036, 0x080c, 0x63a3, 0x1190, 0x0086, 0x9046, + 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xda78, 0x004e, 0x0096, + 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a, + 0x003e, 0x001e, 0x8108, 0x1f04, 0xd7b9, 0x0036, 0x2029, 0x0002, + 0x080c, 0xd6dd, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, + 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xbd4c, 0x0198, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, + 0xa803, 0x0000, 0xab82, 0x080c, 0x6a22, 0x2f48, 0x0cb0, 0xab82, + 0x080c, 0x6a22, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, + 0xa803, 0x0000, 0x080c, 0x6a22, 0x2f48, 0x0cb8, 0x080c, 0x6a22, + 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, + 0x2071, 0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, + 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6008, 0x9206, + 0x1130, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, + 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, + 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x0096, + 0x0006, 0x080c, 0x1037, 0x000e, 0x090c, 0x0df6, 0xaae2, 0xa867, + 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, 0xbd3c, 0x2001, 0x0000, + 0x0120, 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, + 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, + 0x2001, 0x1968, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e, 0x009e, 0x0005, + 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, + 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, + 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, + 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, + 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, + 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, + 0x1961, 0x2004, 0x601a, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x001e, + 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, + 0x0118, 0x080c, 0xc088, 0x0030, 0x080c, 0xda94, 0x080c, 0x8425, + 0x080c, 0x9fea, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, + 0x0002, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c9, 0xd8c7, 0xd8c9, 0xd8c9, + 0xd8c7, 0xd8c9, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0x9006, + 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, + 0x000f, 0x0002, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, + 0xd8ed, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, + 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, + 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005, 0x0096, 0x00c6, 0x2260, + 0x080c, 0xda94, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, + 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, + 0xd946, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, + 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, + 0x85f8, 0x080c, 0x8b8f, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, + 0x1904, 0xd9bd, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, + 0x190c, 0x0df6, 0x0804, 0xd9bd, 0x2048, 0x080c, 0xbd4e, 0x1130, + 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, + 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, + 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xd1e3, + 0x0804, 0xd9bd, 0x2009, 0x0041, 0x0804, 0xd9b7, 0x9186, 0x0005, + 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, + 0x0804, 0xd8e0, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0df6, 0x0804, + 0xd901, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, + 0x8b8f, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, + 0x0004, 0x1904, 0xd9bd, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, + 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, + 0x1651, 0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x1037, + 0x090c, 0x0df6, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, + 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, + 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, + 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, + 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, 0x6a22, 0x2019, 0x0045, + 0x6008, 0x2068, 0x080c, 0xd38f, 0x2d00, 0x600a, 0x6023, 0x0006, + 0x6003, 0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, + 0x0000, 0x6003, 0x0007, 0x080c, 0xd1e3, 0x00ce, 0x00de, 0x009e, + 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, + 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, 0x8a83, 0x0036, 0x0096, + 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, 0xd7e2, 0x009e, 0x003e, + 0x080c, 0x8b8f, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xa083, + 0x0005, 0xd9f0, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9f0, + 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0x080c, 0x0df6, + 0x080c, 0x8a83, 0x6003, 0x000c, 0x080c, 0x8b8f, 0x0005, 0x9182, + 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xa083, + 0x0005, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda10, 0xda30, 0xda0e, + 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0x080c, 0x0df6, + 0x00d6, 0x2c68, 0x080c, 0x9f94, 0x01b0, 0x6003, 0x0001, 0x6007, + 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, + 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, + 0x85f8, 0x080c, 0x8b8f, 0x2d60, 0x080c, 0x9fea, 0x00de, 0x0005, + 0x080c, 0x9fea, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x187b, 0x210c, 0xd1ec, + 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, + 0x2001, 0x1962, 0x2004, 0x6042, 0x2009, 0x187b, 0x210c, 0xd1f4, + 0x1520, 0x00a0, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x0128, 0x6024, + 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1962, 0x200c, 0x2001, + 0x1960, 0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, + 0x2058, 0xb8ac, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, + 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, + 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8ac, 0x2060, 0x8cff, 0x0180, + 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, + 0x8425, 0x080c, 0x9fea, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, + 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, + 0xb8ac, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, + 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, + 0x182b, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, + 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, + 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, + 0x2048, 0x2019, 0x000a, 0x080c, 0xb017, 0x009e, 0x1168, 0x2011, + 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, + 0x080c, 0xb017, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x080c, 0x2e73, 0x00ee, + 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, + 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, + 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, + 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021, + 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, + 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, + 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, + 0xd868, 0x01b8, 0x080c, 0xd878, 0x11a0, 0x6000, 0x9086, 0x0004, + 0x1120, 0x0016, 0x080c, 0x192c, 0x001e, 0x080c, 0xbf45, 0x1110, + 0x080c, 0x30be, 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x080c, + 0xa01c, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1208, + 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, + 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, + 0x0005, 0x0006, 0x2001, 0x1836, 0x2004, 0xd09c, 0x000e, 0x0005, + 0x0006, 0x0036, 0x0046, 0x080c, 0xc459, 0x0168, 0x2019, 0xffff, + 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, + 0x0004, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, + 0x9086, 0x0001, 0x1128, 0x080c, 0x9ad0, 0x080c, 0xa01c, 0x9006, + 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071, + 0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, + 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, + 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018, + 0x2001, 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, + 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, + 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1836, 0x2004, 0xd0a4, + 0x0138, 0x2001, 0x185c, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, + 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, + 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7054, 0x8000, 0x7056, + 0xd5b4, 0x0118, 0x7050, 0x8000, 0x7052, 0xd5ac, 0x0178, 0x2500, + 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, + 0x908e, 0x0005, 0x0118, 0x2071, 0x184a, 0x0089, 0x001e, 0x00ee, + 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, + 0x2071, 0x1842, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04, + 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005, + 0x00e6, 0x2071, 0x1840, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, + 0x1844, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, + 0x8000, 0x2071, 0x1840, 0x7064, 0x8000, 0x7066, 0x00ee, 0x000e, + 0x012e, 0x0005, 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, + 0x8064, 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, + 0x4407, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, + 0x7924, 0x0003, 0x5096, 0x000b, 0x4c0a, 0x0003, 0xbac0, 0x0009, + 0x008a, 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, + 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, + 0x15bf, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, + 0x4047, 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, + 0x4022, 0x0000, 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, + 0x0de3, 0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, + 0x0ca0, 0x0001, 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, + 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, + 0x0009, 0x0008, 0x4430, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, + 0x0060, 0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, + 0x0411, 0x0000, 0x4438, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, + 0x0dc2, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, + 0x0dc2, 0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, + 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, + 0x4447, 0x000b, 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, + 0x31c2, 0x000b, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, + 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, + 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, + 0x0011, 0x0008, 0x4458, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, + 0x0db5, 0x000b, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0db5, 0x000b, + 0x1734, 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, + 0x9880, 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x446a, 0x000b, + 0x808a, 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, + 0x0002, 0x0000, 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, + 0x4473, 0x0003, 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, + 0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, + 0x007d, 0x0004, 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, + 0x8066, 0x0000, 0x0231, 0x0008, 0x4481, 0x000b, 0x5882, 0x0003, + 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, 0x0c8c, 0x0003, + 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, + 0x0090, 0x000b, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, + 0x064a, 0x0000, 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, + 0x8074, 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, + 0x0c0d, 0x0003, 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, + 0x589b, 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, + 0x08e1, 0x0003, 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, + 0x7f3c, 0x0000, 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, + 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, + 0x44ab, 0x0003, 0x00fe, 0x0000, 0x34ca, 0x0003, 0x1c60, 0x0000, + 0x8062, 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, + 0x44b3, 0x0003, 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, + 0x0060, 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, + 0x0009, 0x0008, 0x44bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, + 0x7f3e, 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44c6, 0x000b, + 0x003a, 0x0008, 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, + 0x007d, 0x0004, 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, + 0x00e1, 0x000b, 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, + 0x1000, 0x0000, 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, + 0x359b, 0x0003, 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, + 0xa6d0, 0x0009, 0x0000, 0x0008, 0x00d0, 0x0009, 0x0cf1, 0x0003, + 0x8074, 0x0000, 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, + 0x3a46, 0x000a, 0x0cf1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, + 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, + 0x0118, 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, + 0x1246, 0x000a, 0x0d95, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, + 0x0002, 0x0000, 0x8066, 0x0000, 0x367a, 0x0000, 0x44f6, 0x000b, + 0x92c0, 0x0009, 0x0780, 0x0008, 0x0daf, 0x0003, 0x124b, 0x0002, + 0x08ff, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, + 0x3a46, 0x000a, 0x0d0c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, + 0x0004, 0x0000, 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, + 0x000d, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, + 0x0116, 0x000b, 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, + 0x09a5, 0x000b, 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, + 0x017e, 0x000c, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, + 0xf000, 0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0d1e, 0x0003, + 0x15fe, 0x0008, 0x3451, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, + 0x0501, 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, + 0x000a, 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0d34, 0x000b, + 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, + 0x3ce0, 0x0009, 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, + 0x0040, 0x0000, 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, + 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0d39, 0x0003, + 0x3c1e, 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, + 0x0d5b, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0d31, 0x000b, + 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, + 0x000d, 0x0000, 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, + 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, + 0x0000, 0x0008, 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, + 0x7f0a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x4552, 0x000b, + 0x017e, 0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, + 0xf000, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, + 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0d6d, 0x000b, 0x18fe, 0x0000, + 0x3ce0, 0x0009, 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, + 0x0d2d, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, + 0x8072, 0x0000, 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, + 0x0042, 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, + 0x0d76, 0x000b, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8072, 0x0000, + 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, + 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, + 0xbc80, 0x0001, 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, + 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, + 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, + 0x4587, 0x0003, 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, + 0x4000, 0x000f, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, + 0x8074, 0x0000, 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, + 0x0703, 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, + 0x01cd, 0x000b, 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, + 0x8010, 0x0008, 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, + 0x8010, 0x0008, 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, + 0x0189, 0x0004, 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, + 0x001b, 0x0008, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, + 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, + 0x8010, 0x0008, 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, + 0x0005, 0x0008, 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, + 0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, + 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, + 0x8010, 0x0008, 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, + 0x000b, 0x0000, 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, + 0x01cf, 0x0003, 0x3a47, 0x0002, 0x0ce1, 0x000b, 0x8010, 0x0008, + 0x0006, 0x0008, 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, + 0x0189, 0x0004, 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, + 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, + 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, + 0x2e4d, 0x0002, 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, + 0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, + 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x01c2, 0x000b, 0x0a0b, 0xf5dd, + 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008, + 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0xc007, 0x0003, + 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924, 0x0003, + 0x5096, 0x000b, 0xc80a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000, + 0x880a, 0x000b, 0x15fe, 0x0008, 0xb00a, 0x0003, 0xc4c0, 0x0009, + 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x91bf, 0x000b, + 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047, 0x000a, + 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022, 0x0000, + 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x89e3, 0x000b, + 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0, 0x0001, + 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, + 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, + 0xc030, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, + 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, + 0xc038, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x89c2, 0x000b, + 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x89c2, 0x000b, + 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0xc047, 0x000b, + 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2, 0x000b, + 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002, + 0x880a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008, + 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008, + 0xc058, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x89b5, 0x000b, + 0x00fe, 0x0000, 0x43e0, 0x0001, 0x89b5, 0x000b, 0x1734, 0x0000, + 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001, + 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, + 0x8066, 0x0000, 0x1e0a, 0x0008, 0xc06a, 0x000b, 0x808a, 0x0008, + 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, + 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0xc073, 0x0003, + 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, + 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d, 0x0004, + 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, + 0x0231, 0x0008, 0xc081, 0x000b, 0x5882, 0x0003, 0x0140, 0x0008, + 0x0242, 0x0000, 0x1f43, 0x0002, 0x888c, 0x0003, 0x0d44, 0x0000, + 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090, 0x000b, + 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, + 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, + 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x880d, 0x0003, + 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b, 0x000b, + 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1, 0x0003, + 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c, 0x0000, + 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0ab, 0x0003, + 0x00fe, 0x0000, 0xb0ca, 0x0003, 0x1c60, 0x0000, 0x8062, 0x0008, + 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0b3, 0x0003, + 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, + 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, + 0xc0bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, + 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, + 0x8066, 0x0000, 0x0009, 0x0008, 0xc0c6, 0x000b, 0x003a, 0x0008, + 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d, 0x0004, + 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1, 0x000b, + 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000, + 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0xb19b, 0x0003, + 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0, 0x0009, + 0x0000, 0x0008, 0x00d0, 0x0009, 0x88f1, 0x0003, 0x8074, 0x0000, + 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46, 0x000a, + 0x88f1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054, 0x0008, + 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, + 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, + 0x8995, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, + 0x8066, 0x0000, 0x367a, 0x0000, 0xc0f6, 0x000b, 0x92c0, 0x0009, + 0x0780, 0x0008, 0x89af, 0x0003, 0x124b, 0x0002, 0x08ff, 0x0003, + 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46, 0x000a, + 0x890c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, + 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, + 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116, 0x000b, + 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5, 0x000b, + 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e, 0x000c, + 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000, 0x0008, + 0x0d30, 0x0000, 0x3a42, 0x0002, 0x891e, 0x0003, 0x15fe, 0x0008, + 0xb051, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, + 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, + 0xbbe0, 0x0009, 0x0030, 0x0008, 0x8934, 0x000b, 0x18fe, 0x0000, + 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, + 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, + 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176, 0x000b, + 0xbbe0, 0x0009, 0x0032, 0x0000, 0x8939, 0x0003, 0x3c1e, 0x0008, + 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x895b, 0x000b, + 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x8931, 0x000b, 0x8076, 0x0008, + 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, + 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0, 0x0001, + 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000, 0x0008, + 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a, 0x0000, + 0x8066, 0x0000, 0x0422, 0x0000, 0xc152, 0x000b, 0x017e, 0x000c, + 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, + 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0, 0x0009, + 0x0038, 0x0000, 0x896d, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, + 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x892d, 0x0003, + 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, + 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042, 0x0008, + 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x8976, 0x000b, + 0x3a44, 0x0002, 0x880c, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, + 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, + 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, + 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00, 0x0000, + 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0xc187, 0x0003, + 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000, 0x000f, + 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074, 0x0000, + 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703, 0x0000, + 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd, 0x000b, + 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010, 0x0008, + 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010, 0x0008, + 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, + 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, + 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, + 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, + 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005, 0x0008, + 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008, + 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44, 0x0002, + 0x880a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, + 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b, 0x0000, + 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf, 0x0003, + 0x3a47, 0x0002, 0x88e1, 0x000b, 0x8010, 0x0008, 0x0006, 0x0008, + 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189, 0x0004, + 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, + 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074, 0x0000, + 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002, + 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, + 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002, + 0x880a, 0x000b, 0x01c2, 0x000b, 0x460b, 0xf5c6, 0x0001, 0x0002, + 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, + 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x92c4 +}; +#ifdef UNIQUE_FW_NAME +unsigned short fw2300flx_length01 = 0xdbb7; +#else +unsigned short risc_code_length01 = 0xdbb7; +#endif + diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index fee0c4937..92b3e13e9 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -50,7 +50,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, ha->host_no); vfree(ha->fw_dump_buffer); - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) + if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order); @@ -64,7 +64,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, if ((ha->fw_dump || ha->fw_dumped) && !ha->fw_dump_reading) { ha->fw_dump_reading = 1; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) dump_size = FW_DUMP_SIZE_24XX; else { dump_size = FW_DUMP_SIZE_1M; @@ -138,7 +138,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off, return 0; /* Checksum NVRAM. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { uint32_t *iter; uint32_t chksum; @@ -308,61 +308,6 @@ static struct bin_attribute sysfs_optrom_ctl_attr = { .write = qla2x00_sysfs_write_optrom_ctl, }; -static ssize_t -qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off, - size_t count) -{ - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, - struct device, kobj))); - unsigned long flags; - - if (!capable(CAP_SYS_ADMIN) || off != 0) - return 0; - - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) - return -ENOTSUPP; - - /* Read NVRAM. */ - spin_lock_irqsave(&ha->hardware_lock, flags); - ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return ha->vpd_size; -} - -static ssize_t -qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off, - size_t count) -{ - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, - struct device, kobj))); - unsigned long flags; - - if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) - return 0; - - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) - return -ENOTSUPP; - - /* Write NVRAM. */ - spin_lock_irqsave(&ha->hardware_lock, flags); - ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return count; -} - -static struct bin_attribute sysfs_vpd_attr = { - .attr = { - .name = "vpd", - .mode = S_IRUSR | S_IWUSR, - .owner = THIS_MODULE, - }, - .size = 0, - .read = qla2x00_sysfs_read_vpd, - .write = qla2x00_sysfs_write_vpd, -}; - void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) { @@ -373,7 +318,6 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_ctl_attr); - sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); } void @@ -386,7 +330,6 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_ctl_attr); - sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); if (ha->beacon_blink_led == 1) ha->isp_ops.beacon_off(ha); @@ -507,6 +450,9 @@ qla2x00_zio_show(struct class_device *cdev, char *buf) int len = 0; switch (ha->zio_mode) { + case QLA_ZIO_MODE_5: + len += snprintf(buf + len, PAGE_SIZE-len, "Mode 5\n"); + break; case QLA_ZIO_MODE_6: len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n"); break; @@ -524,16 +470,20 @@ qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) int val = 0; uint16_t zio_mode; - if (!IS_ZIO_SUPPORTED(ha)) - return -ENOTSUPP; - if (sscanf(buf, "%d", &val) != 1) return -EINVAL; - if (val) + switch (val) { + case 1: + zio_mode = QLA_ZIO_MODE_5; + break; + case 2: zio_mode = QLA_ZIO_MODE_6; - else + break; + default: zio_mode = QLA_ZIO_DISABLED; + break; + } /* Update per-hba values and queue a reset. */ if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) { @@ -800,7 +750,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) pfc_host_stat = &ha->fc_host_stat; memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, sizeof(stat_buf) / 4, mb_stat); } else { diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 53508f3c4..b31a03bbd 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -31,6 +31,82 @@ #include #include +#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) +#if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE) +#define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100) +#else +#define IS_QLA2100(ha) 0 +#endif + +#if defined(CONFIG_SCSI_QLA22XX) || defined(CONFIG_SCSI_QLA22XX_MODULE) +#define IS_QLA2200(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2200) +#else +#define IS_QLA2200(ha) 0 +#endif + +#if defined(CONFIG_SCSI_QLA2300) || defined(CONFIG_SCSI_QLA2300_MODULE) +#define IS_QLA2300(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2300) +#define IS_QLA2312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2312) +#else +#define IS_QLA2300(ha) 0 +#define IS_QLA2312(ha) 0 +#endif + +#if defined(CONFIG_SCSI_QLA2322) || defined(CONFIG_SCSI_QLA2322_MODULE) +#define IS_QLA2322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322) +#else +#define IS_QLA2322(ha) 0 +#endif + +#if defined(CONFIG_SCSI_QLA6312) || defined(CONFIG_SCSI_QLA6312_MODULE) +#define IS_QLA6312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312) +#define IS_QLA6322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322) +#else +#define IS_QLA6312(ha) 0 +#define IS_QLA6322(ha) 0 +#endif + +#if defined(CONFIG_SCSI_QLA24XX) || defined(CONFIG_SCSI_QLA24XX_MODULE) +#define IS_QLA2422(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422) +#define IS_QLA2432(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) +#else +#define IS_QLA2422(ha) 0 +#define IS_QLA2432(ha) 0 +#endif + +#if defined(CONFIG_SCSI_QLA25XX) || defined(CONFIG_SCSI_QLA25XX_MODULE) +#define IS_QLA2512(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512) +#define IS_QLA2522(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522) +#else +#define IS_QLA2512(ha) 0 +#define IS_QLA2522(ha) 0 +#endif + +#else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */ + +#define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100) +#define IS_QLA2200(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2200) +#define IS_QLA2300(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2300) +#define IS_QLA2312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2312) +#define IS_QLA2322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322) +#define IS_QLA6312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312) +#define IS_QLA6322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322) +#define IS_QLA2422(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422) +#define IS_QLA2432(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) +#define IS_QLA2512(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512) +#define IS_QLA2522(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522) +#endif + +#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ + IS_QLA6312(ha) || IS_QLA6322(ha)) +#define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) +#define IS_QLA25XX(ha) (IS_QLA2512(ha) || IS_QLA2522(ha)) + +/* + * Only non-ISP2[12]00 have extended addressing support in the firmware. + */ +#define HAS_EXTENDED_IDS(ha) (!IS_QLA2100(ha) && !IS_QLA2200(ha)) + /* * We have MAILBOX_REGISTER_COUNT sized arrays in a few places, * but that's fine as we don't look at the last 24 ones for @@ -762,6 +838,7 @@ typedef struct { #define PD_STATE_WAIT_PORT_LOGOUT_ACK 11 +#define QLA_ZIO_MODE_5 (BIT_2 | BIT_0) #define QLA_ZIO_MODE_6 (BIT_2 | BIT_1) #define QLA_ZIO_DISABLED 0 #define QLA_ZIO_DEFAULT_TIMER 2 @@ -2223,47 +2300,6 @@ typedef struct scsi_qla_host { #define SWITCH_FOUND BIT_3 #define DFLG_NO_CABLE BIT_4 - uint32_t device_type; -#define DT_ISP2100 BIT_0 -#define DT_ISP2200 BIT_1 -#define DT_ISP2300 BIT_2 -#define DT_ISP2312 BIT_3 -#define DT_ISP2322 BIT_4 -#define DT_ISP6312 BIT_5 -#define DT_ISP6322 BIT_6 -#define DT_ISP2422 BIT_7 -#define DT_ISP2432 BIT_8 -#define DT_ISP5422 BIT_9 -#define DT_ISP5432 BIT_10 -#define DT_ISP_LAST (DT_ISP5432 << 1) - -#define DT_ZIO_SUPPORTED BIT_28 -#define DT_OEM_001 BIT_29 -#define DT_ISP2200A BIT_30 -#define DT_EXTENDED_IDS BIT_31 - -#define DT_MASK(ha) ((ha)->device_type & (DT_ISP_LAST - 1)) -#define IS_QLA2100(ha) (DT_MASK(ha) & DT_ISP2100) -#define IS_QLA2200(ha) (DT_MASK(ha) & DT_ISP2200) -#define IS_QLA2300(ha) (DT_MASK(ha) & DT_ISP2300) -#define IS_QLA2312(ha) (DT_MASK(ha) & DT_ISP2312) -#define IS_QLA2322(ha) (DT_MASK(ha) & DT_ISP2322) -#define IS_QLA6312(ha) (DT_MASK(ha) & DT_ISP6312) -#define IS_QLA6322(ha) (DT_MASK(ha) & DT_ISP6322) -#define IS_QLA2422(ha) (DT_MASK(ha) & DT_ISP2422) -#define IS_QLA2432(ha) (DT_MASK(ha) & DT_ISP2432) -#define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) -#define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) - -#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ - IS_QLA6312(ha) || IS_QLA6322(ha)) -#define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) -#define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) - -#define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED) -#define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001) -#define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) - /* SRB cache. */ #define SRB_MIN_REQ 128 mempool_t *srb_mempool; @@ -2345,8 +2381,6 @@ typedef struct scsi_qla_host { /* NVRAM configuration data */ uint16_t nvram_size; uint16_t nvram_base; - uint16_t vpd_size; - uint16_t vpd_base; uint16_t loop_reset_delay; uint8_t retry_count; @@ -2380,7 +2414,11 @@ typedef struct scsi_qla_host { struct sns_cmd_pkt *sns_cmd; dma_addr_t sns_cmd_dma; - struct task_struct *dpc_thread; + pid_t dpc_pid; + int dpc_should_die; + struct completion dpc_inited; + struct completion dpc_exited; + struct semaphore *dpc_wait; uint8_t dpc_active; /* DPC routine is active */ /* Timeout timers. */ diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h index a8fc0ffc7..5109735dd 100644 --- a/drivers/scsi/qla2xxx/qla_devtbl.h +++ b/drivers/scsi/qla2xxx/qla_devtbl.h @@ -1,81 +1,146 @@ -#define QLA_MODEL_NAMES 0x4A +#define QLA_MODEL_NAMES 0x44 /* - * Adapter model names and descriptions. + * Adapter model names. */ -static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = { - "QLA2340", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x100 */ - "QLA2342", "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x101 */ - "QLA2344", "133MHz PCI-X to 2Gb FC, Quad Channel", /* 0x102 */ - "QCP2342", "cPCI to 2Gb FC, Dual Channel", /* 0x103 */ - "QSB2340", "SBUS to 2Gb FC, Single Channel", /* 0x104 */ - "QSB2342", "SBUS to 2Gb FC, Dual Channel", /* 0x105 */ - "QLA2310", "Sun 66MHz PCI-X to 2Gb FC, Single Channel", /* 0x106 */ - "QLA2332", "Sun 66MHz PCI-X to 2Gb FC, Single Channel", /* 0x107 */ - "QCP2332", "Sun cPCI to 2Gb FC, Dual Channel", /* 0x108 */ - "QCP2340", "cPCI to 2Gb FC, Single Channel", /* 0x109 */ - "QLA2342", "Sun 133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x10a */ - "QCP2342", "Sun - cPCI to 2Gb FC, Dual Channel", /* 0x10b */ - "QLA2350", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x10c */ - "QLA2352", "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x10d */ - "QLA2352", "Sun 133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x10e */ - " ", " ", /* 0x10f */ - " ", " ", /* 0x110 */ - " ", " ", /* 0x111 */ - " ", " ", /* 0x112 */ - " ", " ", /* 0x113 */ - " ", " ", /* 0x114 */ - "QLA2360", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x115 */ - "QLA2362", "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x116 */ - "QLE2360", "PCI-Express to 2Gb FC, Single Channel", /* 0x117 */ - "QLE2362", "PCI-Express to 2Gb FC, Dual Channel", /* 0x118 */ - "QLA200", "133MHz PCI-X to 2Gb FC Optical", /* 0x119 */ - " ", " ", /* 0x11a */ - " ", " ", /* 0x11b */ - "QLA200P", "133MHz PCI-X to 2Gb FC SFP", /* 0x11c */ - " ", " ", /* 0x11d */ - " ", " ", /* 0x11e */ - " ", " ", /* 0x11f */ - " ", " ", /* 0x120 */ - " ", " ", /* 0x121 */ - " ", " ", /* 0x122 */ - " ", " ", /* 0x123 */ - " ", " ", /* 0x124 */ - " ", " ", /* 0x125 */ - " ", " ", /* 0x126 */ - " ", " ", /* 0x127 */ - " ", " ", /* 0x128 */ - " ", " ", /* 0x129 */ - " ", " ", /* 0x12a */ - " ", " ", /* 0x12b */ - " ", " ", /* 0x12c */ - " ", " ", /* 0x12d */ - " ", " ", /* 0x12e */ - "QLA210", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x12f */ - "EMC 250", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x130 */ - "HP A7538A", "HP 1p2g PCI-X to 2Gb FC, Single Channel", /* 0x131 */ - "QLA210", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x132 */ - "QLA2460", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x133 */ - "QLA2462", "PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x134 */ - "QMC2462", "IBM eServer BC 4Gb FC Expansion Card", /* 0x135 */ - "QMC2462S", "IBM eServer BC 4Gb FC Expansion Card SFF", /* 0x136 */ - "QLE2460", "PCI-Express to 4Gb FC, Single Channel", /* 0x137 */ - "QLE2462", "PCI-Express to 4Gb FC, Dual Channel", /* 0x138 */ - "QME2462", "Dell BS PCI-Express to 4Gb FC, Dual Channel", /* 0x139 */ - " ", " ", /* 0x13a */ - " ", " ", /* 0x13b */ - " ", " ", /* 0x13c */ - "QEM2462", "Sun Server I/O Module 4Gb FC, Dual Channel", /* 0x13d */ - "QLE210", "PCI-Express to 2Gb FC, Single Channel", /* 0x13e */ - "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x13f */ - "QLA2460", "Sun PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x140 */ - "QLA2462", "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */ - "QLE2460", "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */ - "QLE2462", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x143 */ - "QEM2462" "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */ - "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ - "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ - "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ - " ", " ", /* 0x148 */ - "QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */ +static char *qla2x00_model_name[QLA_MODEL_NAMES] = { + "QLA2340", /* 0x100 */ + "QLA2342", /* 0x101 */ + "QLA2344", /* 0x102 */ + "QCP2342", /* 0x103 */ + "QSB2340", /* 0x104 */ + "QSB2342", /* 0x105 */ + "QLA2310", /* 0x106 */ + "QLA2332", /* 0x107 */ + "QCP2332", /* 0x108 */ + "QCP2340", /* 0x109 */ + "QLA2342", /* 0x10a */ + "QCP2342", /* 0x10b */ + "QLA2350", /* 0x10c */ + "QLA2352", /* 0x10d */ + "QLA2352", /* 0x10e */ + "HPQ SVS", /* 0x10f */ + "HPQ SVS", /* 0x110 */ + " ", /* 0x111 */ + " ", /* 0x112 */ + " ", /* 0x113 */ + " ", /* 0x114 */ + "QLA2360", /* 0x115 */ + "QLA2362", /* 0x116 */ + "QLE2360", /* 0x117 */ + "QLE2362", /* 0x118 */ + "QLA200", /* 0x119 */ + "QLA200C", /* 0x11a */ + "QLA200P", /* 0x11b */ + "QLA200P", /* 0x11c */ + " ", /* 0x11d */ + " ", /* 0x11e */ + " ", /* 0x11f */ + " ", /* 0x120 */ + " ", /* 0x121 */ + " ", /* 0x122 */ + " ", /* 0x123 */ + " ", /* 0x124 */ + " ", /* 0x125 */ + " ", /* 0x126 */ + " ", /* 0x127 */ + " ", /* 0x128 */ + " ", /* 0x129 */ + " ", /* 0x12a */ + " ", /* 0x12b */ + " ", /* 0x12c */ + " ", /* 0x12d */ + " ", /* 0x12e */ + "QLA210", /* 0x12f */ + "EMC 250", /* 0x130 */ + "HP A7538A", /* 0x131 */ + "QLA210", /* 0x132 */ + "QLA2460", /* 0x133 */ + "QLA2462", /* 0x134 */ + "QMC2462", /* 0x135 */ + "QMC2462S", /* 0x136 */ + "QLE2460", /* 0x137 */ + "QLE2462", /* 0x138 */ + "QME2462", /* 0x139 */ + "QLA2440", /* 0x13a */ + "QLA2442", /* 0x13b */ + "QSM2442", /* 0x13c */ + "QSM2462", /* 0x13d */ + "QLE210", /* 0x13e */ + "QLE220", /* 0x13f */ + "QLA2460", /* 0x140 */ + "QLA2462", /* 0x141 */ + "QLE2460", /* 0x142 */ + "QLE2462" /* 0x143 */ +}; + +static char *qla2x00_model_desc[QLA_MODEL_NAMES] = { + "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x100 */ + "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x101 */ + "133MHz PCI-X to 2Gb FC, Quad Channel", /* 0x102 */ + " ", /* 0x103 */ + " ", /* 0x104 */ + " ", /* 0x105 */ + " ", /* 0x106 */ + " ", /* 0x107 */ + " ", /* 0x108 */ + " ", /* 0x109 */ + " ", /* 0x10a */ + " ", /* 0x10b */ + "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x10c */ + "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x10d */ + " ", /* 0x10e */ + "HPQ SVS HBA- Initiator device", /* 0x10f */ + "HPQ SVS HBA- Target device", /* 0x110 */ + " ", /* 0x111 */ + " ", /* 0x112 */ + " ", /* 0x113 */ + " ", /* 0x114 */ + "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x115 */ + "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x116 */ + "PCI-Express to 2Gb FC, Single Channel", /* 0x117 */ + "PCI-Express to 2Gb FC, Dual Channel", /* 0x118 */ + "133MHz PCI-X to 2Gb FC Optical", /* 0x119 */ + "133MHz PCI-X to 2Gb FC Copper", /* 0x11a */ + "133MHz PCI-X to 2Gb FC SFP", /* 0x11b */ + "133MHz PCI-X to 2Gb FC SFP", /* 0x11c */ + " ", /* 0x11d */ + " ", /* 0x11e */ + " ", /* 0x11f */ + " ", /* 0x120 */ + " ", /* 0x121 */ + " ", /* 0x122 */ + " ", /* 0x123 */ + " ", /* 0x124 */ + " ", /* 0x125 */ + " ", /* 0x126 */ + " ", /* 0x127 */ + " ", /* 0x128 */ + " ", /* 0x129 */ + " ", /* 0x12a */ + " ", /* 0x12b */ + " ", /* 0x12c */ + " ", /* 0x12d */ + " ", /* 0x12e */ + "133MHz PCI-X to 2Gb FC SFF", /* 0x12f */ + "133MHz PCI-X to 2Gb FC SFF", /* 0x130 */ + "HP 1p2g QLA2340", /* 0x131 */ + "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x132 */ + "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x133 */ + "PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x134 */ + "IBM eServer BC 4Gb FC Expansion Card", /* 0x135 */ + "IBM eServer BC 4Gb FC Expansion Card SFF", /* 0x136 */ + "PCI-Express to 4Gb FC, Single Channel", /* 0x137 */ + "PCI-Express to 4Gb FC, Dual Channel", /* 0x138 */ + "Dell PCI-Express to 4Gb FC, Dual Channel", /* 0x139 */ + "PCI-X 1.0 to 4Gb FC, Single Channel", /* 0x13a */ + "PCI-X 1.0 to 4Gb FC, Dual Channel", /* 0x13b */ + "Server I/O Module 4Gb FC, Single Channel", /* 0x13c */ + "Server I/O Module 4Gb FC, Single Channel", /* 0x13d */ + "PCI-Express to 2Gb FC, Single Channel", /* 0x13e */ + "PCI-Express to 4Gb FC, Single Channel", /* 0x13f */ + "Sun PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x140 */ + "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */ + "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */ + "Sun PCI-Express to 4Gb FC, Single Channel" /* 0x143 */ }; diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 1ee58ad2f..9fb562aa4 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -759,7 +759,7 @@ struct device_reg_24xx { #define FA_NVRAM_FUNC0_ADDR 0x80 #define FA_NVRAM_FUNC1_ADDR 0x180 -#define FA_NVRAM_VPD_SIZE 0x200 +#define FA_NVRAM_VPD_SIZE 0x80 #define FA_NVRAM_VPD0_ADDR 0x00 #define FA_NVRAM_VPD1_ADDR 0x100 /* diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 91e83e2c1..ffdc2680f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -42,7 +42,7 @@ extern int qla2x00_loop_resync(scsi_qla_host_t *); extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *); extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); -extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); +extern int qla2x00_local_device_login(scsi_qla_host_t *, uint16_t); extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t); @@ -81,8 +81,6 @@ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *); -extern void qla2xxx_wake_dpc(scsi_qla_host_t *); - /* * Global Function Prototypes in qla_iocb.c source file. */ @@ -166,8 +164,7 @@ qla24xx_login_fabric(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t, uint16_t *, uint8_t); extern int -qla2x00_login_local_device(scsi_qla_host_t *, fc_port_t *, uint16_t *, - uint8_t); +qla2x00_login_local_device(scsi_qla_host_t *, uint16_t, uint16_t *, uint8_t); extern int qla2x00_fabric_logout(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t); diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 2ebf259fc..d620a8e8a 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -126,7 +126,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt, DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n", ha->host_no, routine, ms_pkt->entry_status)); } else { - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) comp_status = ((struct ct_entry_24xx *)ms_pkt)->comp_status; else @@ -1200,7 +1200,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size) ms_iocb_entry_t *ms_pkt = ha->ms_iocb; struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { ct_pkt->cmd_byte_count = cpu_to_le32(req_size); ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; } else { @@ -1529,7 +1529,9 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); eiter->len = __constant_cpu_to_be16(4 + 4); - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA25XX(ha)) + eiter->a.sup_speed = __constant_cpu_to_be32(8); + else if (IS_QLA24XX(ha)) eiter->a.sup_speed = __constant_cpu_to_be32(4); else if (IS_QLA23XX(ha)) eiter->a.sup_speed = __constant_cpu_to_be32(2); @@ -1564,7 +1566,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); eiter->len = __constant_cpu_to_be16(4 + 4); - max_frame_size = IS_QLA24XX(ha) || IS_QLA54XX(ha) ? + max_frame_size = IS_QLA24XX(ha) || IS_QLA25XX(ha) ? (uint32_t) icb24->frame_payload_size: (uint32_t) ha->init_cb->frame_payload_size; eiter->a.max_frame_size = cpu_to_be32(max_frame_size); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 89a3fc059..634ee174b 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -387,7 +387,7 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha) /* Verify checksum of loaded RISC code. */ rval = qla2x00_verify_checksum(ha, - IS_QLA24XX(ha) || IS_QLA54XX(ha) ? RISC_SADDRESS : + IS_QLA24XX(ha) || IS_QLA25XX(ha) ? RISC_SADDRESS : *ha->brd_info->fw_info[0].fwstart); } @@ -727,7 +727,6 @@ qla2x00_chip_diag(scsi_qla_host_t *ha) DEBUG3(printk("scsi(%ld): Found QLA2200A chip.\n", ha->host_no)); - ha->device_type |= DT_ISP2200A; ha->fw_transfer_size = 128; } @@ -822,7 +821,7 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) if (IS_QLA2100(ha) || IS_QLA2200(ha)) return; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) qla2x00_alloc_fw_dump(ha); /* Retrieve IOCB counts available to the firmware. */ @@ -1003,10 +1002,6 @@ qla2x00_update_fw_options(scsi_qla_host_t *ha) if (ha->flags.enable_led_scheme) ha->fw_options[2] |= BIT_12; - /* Detect ISP6312. */ - if (IS_QLA6312(ha)) - ha->fw_options[2] |= BIT_13; - /* Update firmware options. */ qla2x00_set_fw_options(ha, ha->fw_options); } @@ -1505,9 +1500,9 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) index = (ha->pdev->subsystem_device & 0xff); if (index < QLA_MODEL_NAMES) { strcpy(ha->model_number, - qla2x00_model_name[index * 2]); + qla2x00_model_name[index]); ha->model_desc = - qla2x00_model_name[index * 2 + 1]; + qla2x00_model_desc[index]; } else { strcpy(ha->model_number, "QLA23xx"); } @@ -1659,8 +1654,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) ~(BIT_3 | BIT_2 | BIT_1 | BIT_0); ha->flags.process_response_queue = 0; if (ha->zio_mode != QLA_ZIO_DISABLED) { - ha->zio_mode = QLA_ZIO_MODE_6; - DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer " "delay (%d us).\n", ha->host_no, ha->zio_mode, ha->zio_timer * 100)); @@ -2129,7 +2122,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) LIST_HEAD(new_fcports); /* If FL port exists, then SNS is present */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) loop_id = NPH_F_PORT; else loop_id = SNS_FL_PORT; @@ -2155,7 +2148,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) qla2x00_fdmi_register(ha); /* Ensure we are logged into the SNS. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) loop_id = NPH_SNS; else loop_id = SIMPLE_NAME_SERVER; @@ -2646,7 +2639,7 @@ qla2x00_device_resync(scsi_qla_host_t *ha) if (ql2xprocessrscn && !IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) && !IS_QLA6322(ha) && - !IS_QLA24XX(ha) && !IS_QLA54XX(ha) && + !IS_QLA24XX(ha) && !IS_QLA25XX(ha) && ha->flags.init_done) { /* Handle port RSCN via asyncronous IOCBs */ rval2 = qla2x00_handle_port_rscn(ha, rscn_entry, @@ -2888,13 +2881,13 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, * 3 - Fatal error */ int -qla2x00_local_device_login(scsi_qla_host_t *ha, fc_port_t *fcport) +qla2x00_local_device_login(scsi_qla_host_t *ha, uint16_t loop_id) { int rval; uint16_t mb[MAILBOX_REGISTER_COUNT]; memset(mb, 0, sizeof(mb)); - rval = qla2x00_login_local_device(ha, fcport, mb, BIT_0); + rval = qla2x00_login_local_device(ha, loop_id, mb, BIT_0); if (rval == QLA_SUCCESS) { /* Interrogate mailbox registers for any errors */ if (mb[0] == MBS_COMMAND_ERROR) @@ -3136,7 +3129,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) spin_lock_irqsave(&ha->hardware_lock, flags); - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) { + if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) { /* * Disable SRAM, Instruction RAM and GP RAM * parity. @@ -3152,7 +3145,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) spin_lock_irqsave(&ha->hardware_lock, flags); - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) { + if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) { /* Enable proper parity */ if (IS_QLA2300(ha)) /* SRAM parity */ @@ -3265,12 +3258,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) /* Determine NVRAM starting address. */ ha->nvram_size = sizeof(struct nvram_24xx); 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)) { + if (PCI_FUNC(ha->pdev->devfn)) ha->nvram_base = FA_NVRAM_FUNC1_ADDR; - ha->vpd_base = FA_NVRAM_VPD1_ADDR; - } /* Get NVRAM data and calculate checksum. */ dptr = (uint32_t *)nv; @@ -3379,7 +3368,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) index = (ha->pdev->subsystem_device & 0xff); if (index < QLA_MODEL_NAMES) - ha->model_desc = qla2x00_model_name[index * 2 + 1]; + ha->model_desc = qla2x00_model_desc[index]; } else strcpy(ha->model_number, "QLA2462"); @@ -3476,8 +3465,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) ~(BIT_3 | BIT_2 | BIT_1 | BIT_0)); ha->flags.process_response_queue = 0; if (ha->zio_mode != QLA_ZIO_DISABLED) { - ha->zio_mode = QLA_ZIO_MODE_6; - DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer delay " "(%d us).\n", ha->host_no, ha->zio_mode, ha->zio_timer * 100)); diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 45007ee58..ecc3741a4 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -163,7 +163,7 @@ static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t); static inline int qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) { - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) return (loop_id > NPH_LAST_HANDLE); return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) || diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 8f0f4a298..6544b6d08 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -466,7 +466,7 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun, mrk->entry_type = MARKER_TYPE; mrk->modifier = type; if (type != MK_SYNC_ALL) { - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mrk24 = (struct mrk_entry_24xx *) mrk; mrk24->nport_handle = cpu_to_le16(loop_id); mrk24->lun[1] = LSB(lun); @@ -519,7 +519,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha) for (timer = HZ; timer; timer--) { if ((req_cnt + 2) >= ha->req_q_cnt) { /* Calculate number of free request entries. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) cnt = (uint16_t)RD_REG_DWORD( ®->isp24.req_q_out); else @@ -593,7 +593,7 @@ qla2x00_isp_cmd(scsi_qla_host_t *ha) ha->request_ring_ptr++; /* Set chip new ring index. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { WRT_REG_DWORD(®->isp24.req_q_in, ha->req_ring_index); RD_REG_DWORD_RELAXED(®->isp24.req_q_in); } else { diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 2003dbb70..42aa7a7c1 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -343,7 +343,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) ha->isp_ops.fw_dump(ha, 1); - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { if (mb[1] == 0 && mb[2] == 0) { qla_printk(KERN_ERR, ha, "Unrecoverable Hardware Error: adapter " @@ -521,7 +521,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) */ if (ql2xprocessrscn && !IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) && - !IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA54XX(ha) && + !IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA25XX(ha) && ha->flags.init_done && mb[1] != 0xffff && ((ha->operating_mode == P2P && mb[1] != 0) || (ha->operating_mode != P2P && mb[1] != @@ -638,7 +638,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) "scsi(%ld): [R|Z]IO update completion.\n", ha->host_no)); - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) qla24xx_process_response_queue(ha); else qla2x00_process_response_queue(ha); @@ -810,7 +810,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) sts = (sts_entry_t *) pkt; sts24 = (struct sts_entry_24xx *) pkt; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { comp_status = le16_to_cpu(sts24->comp_status); scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK; } else { @@ -838,7 +838,9 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n"); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); - qla2xxx_wake_dpc(ha); + if (ha->dpc_wait && !ha->dpc_active) + up(ha->dpc_wait); + return; } cp = sp->cmd; @@ -860,7 +862,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) fcport = sp->fcport; sense_len = rsp_info_len = resid_len = 0; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { sense_len = le32_to_cpu(sts24->sense_len); rsp_info_len = le32_to_cpu(sts24->rsp_data_len); resid_len = le32_to_cpu(sts24->rsp_residual_count); @@ -878,7 +880,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) /* Check for any FCP transport errors. */ if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) { /* Sense data lies beyond any FCP RESPONSE data. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) sense_data += rsp_info_len; if (rsp_info_len > 3 && rsp_info[3]) { DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol " @@ -1117,7 +1119,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) case CS_TIMEOUT: cp->result = DID_BUS_BUSY << 16; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { DEBUG2(printk(KERN_INFO "scsi(%ld:%d:%d:%d): TIMEOUT status detected " "0x%x-0x%x\n", ha->host_no, cp->device->channel, @@ -1197,7 +1199,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt) } /* Move sense data. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) host_to_fcp_swap(pkt->data, sizeof(pkt->data)); memcpy(sp->request_sense_ptr, pkt->data, sense_sz); DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz)); @@ -1269,7 +1271,8 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) "Error entry - invalid handle\n"); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); - qla2xxx_wake_dpc(ha); + if (ha->dpc_wait && !ha->dpc_active) + up(ha->dpc_wait); } } diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index d6cb3bd1a..363dfdd04 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -91,7 +91,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) spin_lock_irqsave(&ha->hardware_lock, flags); /* Load mailbox registers. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) optr = (uint16_t __iomem *)®->isp24.mailbox0; else optr = (uint16_t __iomem *)MAILBOX_REG(ha, ®->isp, 0); @@ -155,7 +155,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); else WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); @@ -179,7 +179,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, ha->host_no, command);) - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); else WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); @@ -237,7 +237,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) uint16_t mb0; uint32_t ictrl; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mb0 = RD_REG_WORD(®->isp24.mailbox0); ictrl = RD_REG_DWORD(®->isp24.ictrl); } else { @@ -284,7 +284,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) "Mailbox command timeout occured. Scheduling ISP " "abort.\n"); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); - qla2xxx_wake_dpc(ha); + if (ha->dpc_wait && !ha->dpc_active) + up(ha->dpc_wait); + } else if (!abort_active) { /* call abort directly since we are in the DPC thread */ DEBUG(printk("%s(%ld): timeout calling abort_isp\n", @@ -334,7 +336,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr, DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); - if (MSW(risc_addr) || IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (MSW(risc_addr) || IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED; mcp->mb[8] = MSW(risc_addr); mcp->out_mb = MBX_8|MBX_0; @@ -348,7 +350,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr, mcp->mb[6] = MSW(MSD(req_dma)); mcp->mb[7] = LSW(MSD(req_dma)); mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[4] = MSW(risc_code_size); mcp->mb[5] = LSW(risc_code_size); mcp->out_mb |= MBX_5|MBX_4; @@ -399,7 +401,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) mcp->mb[0] = MBC_EXECUTE_FIRMWARE; mcp->out_mb = MBX_0; mcp->in_mb = MBX_0; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[1] = MSW(risc_addr); mcp->mb[2] = LSW(risc_addr); mcp->mb[3] = 0; @@ -422,7 +424,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__, ha->host_no, rval, mcp->mb[0])); } else { - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { DEBUG11(printk("%s(%ld): done exchanges=%x.\n", __func__, ha->host_no, mcp->mb[1]);) } else { @@ -563,7 +565,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) mcp->mb[3] = fwopts[3]; mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->in_mb |= MBX_1; } else { mcp->mb[10] = fwopts[10]; @@ -676,7 +678,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) mcp->mb[0] = MBC_VERIFY_CHECKSUM; mcp->out_mb = MBX_0; mcp->in_mb = MBX_0; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[1] = MSW(risc_addr); mcp->mb[2] = LSW(risc_addr); mcp->out_mb |= MBX_2|MBX_1; @@ -693,7 +695,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, - ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? + ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA25XX(ha) ? (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));) } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) @@ -751,7 +753,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, /* Mask reserved bits. */ sts_entry->entry_status &= - IS_QLA24XX(ha) || IS_QLA54XX(ha) ? RF_MASK_24XX :RF_MASK; + IS_QLA24XX(ha) || IS_QLA25XX(ha) ? RF_MASK_24XX :RF_MASK; } return rval; @@ -1091,7 +1093,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE)); mcp->mb[0] = MBC_GET_PORT_DATABASE; - if (opt != 0 && !IS_QLA24XX(ha) && !IS_QLA54XX(ha)) + if (opt != 0 && !IS_QLA24XX(ha) && !IS_QLA25XX(ha)) mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE; mcp->mb[2] = MSW(pd_dma); mcp->mb[3] = LSW(pd_dma); @@ -1099,7 +1101,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) mcp->mb[7] = LSW(MSD(pd_dma)); mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; mcp->in_mb = MBX_0; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[1] = fcport->loop_id; mcp->mb[10] = opt; mcp->out_mb |= MBX_10|MBX_1; @@ -1112,7 +1114,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) mcp->mb[1] = fcport->loop_id << 8 | opt; mcp->out_mb |= MBX_1; } - mcp->buf_size = (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? + mcp->buf_size = (IS_QLA24XX(ha) || IS_QLA25XX(ha) ? PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE); mcp->flags = MBX_DMA_IN; mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); @@ -1120,7 +1122,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) if (rval != QLA_SUCCESS) goto gpd_error_out; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { pd24 = (struct port_database_24xx *) pd; /* Check for logged in state. */ @@ -1337,7 +1339,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[0] = MBC_LIP_FULL_LOGIN; mcp->mb[1] = BIT_0; mcp->mb[2] = 0xff; @@ -1631,25 +1633,20 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, * */ int -qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport, +qla2x00_login_local_device(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t *mb_ret, uint8_t opt) { int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) - return qla24xx_login_fabric(ha, fcport->loop_id, - fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa, mb_ret, opt); - DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);) mcp->mb[0] = MBC_LOGIN_LOOP_PORT; if (HAS_EXTENDED_IDS(ha)) - mcp->mb[1] = fcport->loop_id; + mcp->mb[1] = loop_id; else - mcp->mb[1] = fcport->loop_id << 8; + mcp->mb[1] = loop_id << 8; mcp->mb[2] = opt; mcp->out_mb = MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0; @@ -1871,7 +1868,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, mcp->mb[0] = MBC_GET_ID_LIST; mcp->out_mb = MBX_0; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[2] = MSW(id_list_dma); mcp->mb[3] = LSW(id_list_dma); mcp->mb[6] = MSW(MSD(id_list_dma)); @@ -2062,7 +2059,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, mcp->mb[7] = LSW(MSD(stat_buf_dma)); mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; mcp->in_mb = MBX_0; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { mcp->mb[1] = loop_id; mcp->mb[4] = 0; mcp->mb[10] = 0; @@ -2329,7 +2326,7 @@ qla2x00_system_error(scsi_qla_host_t *ha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) + if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) return QLA_FUNCTION_FAILED; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); @@ -2411,9 +2408,9 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g, mcp->mb[0] = MBC_SERDES_PARAMS; mcp->mb[1] = BIT_0; - mcp->mb[2] = sw_em_1g | BIT_15; - mcp->mb[3] = sw_em_2g | BIT_15; - mcp->mb[4] = sw_em_4g | BIT_15; + mcp->mb[2] = sw_em_1g; + mcp->mb[3] = sw_em_2g; + mcp->mb[4] = sw_em_4g; mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; mcp->tov = 30; @@ -2439,7 +2436,7 @@ qla2x00_stop_firmware(scsi_qla_host_t *ha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) + if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) return QLA_FUNCTION_FAILED; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 584fe5d8e..9f91f1a20 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -8,8 +8,8 @@ #include #include +#include #include -#include #include #include @@ -599,7 +599,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) * Either SUCCESS or FAILED. * * Note: -* Only return FAILED if command not returned by firmware. **************************************************************************/ int qla2xxx_eh_abort(struct scsi_cmnd *cmd) @@ -610,12 +609,11 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) unsigned int id, lun; unsigned long serial; unsigned long flags; - int wait = 0; if (!CMD_SP(cmd)) - return SUCCESS; + return FAILED; - ret = SUCCESS; + ret = FAILED; id = cmd->device->id; lun = cmd->device->lun; @@ -644,7 +642,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) } else { DEBUG3(printk("%s(%ld): abort_command " "mbx success.\n", __func__, ha->host_no)); - wait = 1; + ret = SUCCESS; } spin_lock_irqsave(&ha->hardware_lock, flags); @@ -653,18 +651,17 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Wait for the command to be returned. */ - if (wait) { + if (ret == SUCCESS) { if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { qla_printk(KERN_ERR, ha, "scsi(%ld:%d:%d): Abort handler timed out -- %lx " "%x.\n", ha->host_no, id, lun, serial, ret); - ret = FAILED; } } qla_printk(KERN_INFO, ha, - "scsi(%ld:%d:%d): Abort command issued -- %d %lx %x.\n", - ha->host_no, id, lun, wait, serial, ret); + "scsi(%ld:%d:%d): Abort command issued -- %lx %x.\n", ha->host_no, + id, lun, serial, ret); return ret; } @@ -1149,57 +1146,6 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha) pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK); } -static inline void -qla2x00_set_isp_flags(scsi_qla_host_t *ha) -{ - ha->device_type = DT_EXTENDED_IDS; - switch (ha->pdev->device) { - case PCI_DEVICE_ID_QLOGIC_ISP2100: - ha->device_type |= DT_ISP2100; - ha->device_type &= ~DT_EXTENDED_IDS; - break; - case PCI_DEVICE_ID_QLOGIC_ISP2200: - ha->device_type |= DT_ISP2200; - ha->device_type &= ~DT_EXTENDED_IDS; - break; - case PCI_DEVICE_ID_QLOGIC_ISP2300: - ha->device_type |= DT_ISP2300; - ha->device_type |= DT_ZIO_SUPPORTED; - break; - case PCI_DEVICE_ID_QLOGIC_ISP2312: - ha->device_type |= DT_ISP2312; - ha->device_type |= DT_ZIO_SUPPORTED; - break; - case PCI_DEVICE_ID_QLOGIC_ISP2322: - ha->device_type |= DT_ISP2322; - ha->device_type |= DT_ZIO_SUPPORTED; - if (ha->pdev->subsystem_vendor == 0x1028 && - ha->pdev->subsystem_device == 0x0170) - ha->device_type |= DT_OEM_001; - break; - case PCI_DEVICE_ID_QLOGIC_ISP6312: - ha->device_type |= DT_ISP6312; - break; - case PCI_DEVICE_ID_QLOGIC_ISP6322: - ha->device_type |= DT_ISP6322; - break; - case PCI_DEVICE_ID_QLOGIC_ISP2422: - ha->device_type |= DT_ISP2422; - ha->device_type |= DT_ZIO_SUPPORTED; - break; - case PCI_DEVICE_ID_QLOGIC_ISP2432: - ha->device_type |= DT_ISP2432; - ha->device_type |= DT_ZIO_SUPPORTED; - break; - case PCI_DEVICE_ID_QLOGIC_ISP5422: - ha->device_type |= DT_ISP5422; - break; - case PCI_DEVICE_ID_QLOGIC_ISP5432: - ha->device_type |= DT_ISP5432; - break; - } -} - static int qla2x00_iospace_config(scsi_qla_host_t *ha) { @@ -1361,8 +1307,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->brd_info = brd_info; sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no); - /* Set ISP-type information. */ - qla2x00_set_isp_flags(ha); + ha->dpc_pid = -1; /* Configure PCI I/O space */ ret = qla2x00_iospace_config(ha); @@ -1441,7 +1386,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->gid_list_info_size = 6; if (IS_QLA2322(ha) || IS_QLA6322(ha)) ha->optrom_size = OPTROM_SIZE_2322; - } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { host->max_id = MAX_TARGETS_2200; ha->mbx_count = MAILBOX_REGISTER_COUNT; ha->request_q_length = REQUEST_ENTRY_CNT_24XX; @@ -1504,6 +1449,9 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) */ spin_lock_init(&ha->mbx_reg_lock); + init_completion(&ha->dpc_inited); + init_completion(&ha->dpc_exited); + qla2x00_config_dma_addressing(ha); if (qla2x00_mem_alloc(ha)) { qla_printk(KERN_WARNING, ha, @@ -1530,14 +1478,16 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) /* * Startup the kernel thread for this host adapter */ - ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha, - "%s_dpc", ha->host_str); - if (IS_ERR(ha->dpc_thread)) { + ha->dpc_should_die = 0; + ha->dpc_pid = kernel_thread(qla2x00_do_dpc, ha, 0); + if (ha->dpc_pid < 0) { qla_printk(KERN_WARNING, ha, "Unable to start DPC thread!\n"); - ret = PTR_ERR(ha->dpc_thread); + + ret = -ENODEV; goto probe_failed; } + wait_for_completion(&ha->dpc_inited); host->this_id = 255; host->cmd_per_lun = 3; @@ -1567,7 +1517,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) spin_lock_irqsave(&ha->hardware_lock, flags); reg = ha->iobase; - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); } else { @@ -1671,6 +1621,8 @@ EXPORT_SYMBOL_GPL(qla2x00_remove_one); static void qla2x00_free_device(scsi_qla_host_t *ha) { + int ret; + /* Abort any outstanding IO descriptors. */ if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) qla2x00_cancel_io_descriptors(ha); @@ -1680,15 +1632,18 @@ qla2x00_free_device(scsi_qla_host_t *ha) qla2x00_stop_timer(ha); /* Kill the kernel thread for this host */ - if (ha->dpc_thread) { - struct task_struct *t = ha->dpc_thread; + if (ha->dpc_pid >= 0) { + ha->dpc_should_die = 1; + wmb(); + ret = kill_proc(ha->dpc_pid, SIGHUP, 1); + if (ret) { + qla_printk(KERN_ERR, ha, + "Unable to signal DPC thread -- (%d)\n", ret); - /* - * qla2xxx_wake_dpc checks for ->dpc_thread - * so we need to zero it out. - */ - ha->dpc_thread = NULL; - kthread_stop(t); + /* TODO: SOMETHING MORE??? */ + } else { + wait_for_completion(&ha->dpc_exited); + } } /* Stop currently executing firmware. */ @@ -1703,8 +1658,8 @@ qla2x00_free_device(scsi_qla_host_t *ha) ha->flags.online = 0; /* Detach interrupts */ - if (ha->host->irq) - free_irq(ha->host->irq, ha); + if (ha->pdev->irq) + free_irq(ha->pdev->irq, ha); /* release io space registers */ if (ha->iobase) @@ -1820,8 +1775,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) atomic_set(&fcport->state, FCS_DEVICE_LOST); } - if (defer) - qla2xxx_wake_dpc(ha); + if (defer && ha->dpc_wait && !ha->dpc_active) + up(ha->dpc_wait); } /* @@ -2038,6 +1993,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha) { struct list_head *fcpl, *fcptemp; fc_port_t *fcport; + unsigned int wtime;/* max wait time if mbx cmd is busy. */ if (ha == NULL) { /* error */ @@ -2045,6 +2001,11 @@ qla2x00_mem_free(scsi_qla_host_t *ha) return; } + /* Make sure all other threads are stopped. */ + wtime = 60 * 1000; + while (ha->dpc_wait && wtime) + wtime = msleep_interruptible(wtime); + /* free ioctl memory */ qla2x00_free_ioctl_mem(ha); @@ -2157,7 +2118,8 @@ qla2x00_allocate_sp_pool(scsi_qla_host_t *ha) int rval; rval = QLA_SUCCESS; - ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep); + ha->srb_mempool = mempool_create(SRB_MIN_REQ, mempool_alloc_slab, + mempool_free_slab, srb_cachep); if (ha->srb_mempool == NULL) { qla_printk(KERN_INFO, ha, "Unable to allocate SRB mempool.\n"); rval = QLA_FUNCTION_FAILED; @@ -2194,6 +2156,7 @@ qla2x00_free_sp_pool( scsi_qla_host_t *ha) static int qla2x00_do_dpc(void *data) { + DECLARE_MUTEX_LOCKED(sem); scsi_qla_host_t *ha; fc_port_t *fcport; uint8_t status; @@ -2201,19 +2164,32 @@ qla2x00_do_dpc(void *data) ha = (scsi_qla_host_t *)data; + lock_kernel(); + + daemonize("%s_dpc", ha->host_str); + allow_signal(SIGHUP); + + ha->dpc_wait = &sem; + set_user_nice(current, -20); - while (!kthread_should_stop()) { + unlock_kernel(); + + complete(&ha->dpc_inited); + + while (1) { DEBUG3(printk("qla2x00: DPC handler sleeping\n")); - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - __set_current_state(TASK_RUNNING); + if (down_interruptible(&sem)) + break; + + if (ha->dpc_should_die) + break; DEBUG3(printk("qla2x00: DPC handler waking up\n")); /* Initialization not yet finished. Don't do anything yet. */ - if (!ha->flags.init_done) + if (!ha->flags.init_done || ha->dpc_active) continue; DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no)); @@ -2297,7 +2273,7 @@ qla2x00_do_dpc(void *data) } else status = qla2x00_local_device_login( - ha, fcport); + ha, fcport->loop_id); if (status == QLA_SUCCESS) { fcport->old_loop_id = fcport->loop_id; @@ -2380,16 +2356,10 @@ qla2x00_do_dpc(void *data) /* * Make sure that nobody tries to wake us up again. */ + ha->dpc_wait = NULL; ha->dpc_active = 0; - return 0; -} - -void -qla2xxx_wake_dpc(scsi_qla_host_t *ha) -{ - if (ha->dpc_thread) - wake_up_process(ha->dpc_thread); + complete_and_exit(&ha->dpc_exited, 0); } /* @@ -2570,8 +2540,11 @@ qla2x00_timer(scsi_qla_host_t *ha) test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || - test_bit(RELOGIN_NEEDED, &ha->dpc_flags))) - qla2xxx_wake_dpc(ha); + test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && + ha->dpc_wait && !ha->dpc_active) { + + up(ha->dpc_wait); + } qla2x00_restart_timer(ha, WATCH_INTERVAL); } @@ -2603,12 +2576,13 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) /* Firmware interface routines. */ -#define FW_BLOBS 5 +#define FW_BLOBS 6 #define FW_ISP21XX 0 #define FW_ISP22XX 1 #define FW_ISP2300 2 #define FW_ISP2322 3 -#define FW_ISP24XX 4 +#define FW_ISP63XX 4 +#define FW_ISP24XX 5 static DECLARE_MUTEX(qla_fw_lock); @@ -2617,6 +2591,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = { { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, }, { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, }, { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, + { .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, }, { .name = "ql2400_fw.bin", }, }; @@ -2630,11 +2605,13 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) blob = &qla_fw_blobs[FW_ISP21XX]; } else if (IS_QLA2200(ha)) { blob = &qla_fw_blobs[FW_ISP22XX]; - } else if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) { + } else if (IS_QLA2300(ha) || IS_QLA2312(ha)) { blob = &qla_fw_blobs[FW_ISP2300]; - } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { + } else if (IS_QLA2322(ha)) { blob = &qla_fw_blobs[FW_ISP2322]; - } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + } else if (IS_QLA6312(ha) || IS_QLA6322(ha)) { + blob = &qla_fw_blobs[FW_ISP63XX]; + } else if (IS_QLA24XX(ha)) { blob = &qla_fw_blobs[FW_ISP24XX]; } @@ -2690,10 +2667,6 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432, PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422, - PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432, - PCI_ANY_ID, PCI_ANY_ID, }, { 0 }, }; MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 8b0121dce..3866a5760 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -1191,6 +1191,11 @@ qla2x00_poll_flash(scsi_qla_host_t *ha, uint32_t addr, uint8_t poll_data, return status; } +#define IS_OEM_001(ha) \ + ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322 && \ + (ha)->pdev->subsystem_vendor == 0x1028 && \ + (ha)->pdev->subsystem_device == 0x0170) + /** * qla2x00_program_flash_address() - Programs a flash address * @ha: HA context @@ -1349,7 +1354,7 @@ qla2x00_resume_hba(struct scsi_qla_host *ha) /* Resume HBA. */ clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); - qla2xxx_wake_dpc(ha); + up(ha->dpc_wait); qla2x00_wait_for_hba_online(ha); scsi_unblock_requests(ha->host); } @@ -1647,7 +1652,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, /* Resume HBA -- RISC reset needed. */ clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); - qla2xxx_wake_dpc(ha); + up(ha->dpc_wait); qla2x00_wait_for_hba_online(ha); scsi_unblock_requests(ha->host); diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c new file mode 100644 index 000000000..94ef3f08d --- /dev/null +++ b/drivers/scsi/qlogicfc.c @@ -0,0 +1,2226 @@ +/* + * QLogic ISP2x00 SCSI-FCP + * Written by Erik H. Moe, ehm@cris.com + * Copyright 1995, Erik H. Moe + * + * This program is free software; you can redistribute 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. + */ + +/* Renamed and updated to 1.3.x by Michael Griffith */ + +/* This is a version of the isp1020 driver which was modified by + * Chris Loveland to support the isp2100 and isp2200 + * + * Big endian support and dynamic DMA mapping added + * by Jakub Jelinek . + * + * Conversion to final pci64 DMA interfaces + * by David S. Miller . + */ + +/* + * $Date: 1995/09/22 02:23:15 $ + * $Revision: 0.5 $ + * + * $Log: isp1020.c,v $ + * Revision 0.5 1995/09/22 02:23:15 root + * do auto request sense + * + * Revision 0.4 1995/08/07 04:44:33 root + * supply firmware with driver. + * numerous bug fixes/general cleanup of code. + * + * Revision 0.3 1995/07/16 16:15:39 root + * added reset/abort code. + * + * Revision 0.2 1995/06/29 03:14:19 root + * fixed biosparam. + * added queue protocol. + * + * Revision 0.1 1995/06/25 01:55:45 root + * Initial release. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi.h" +#include + +#define pci64_dma_hi32(a) ((u32) (0xffffffff & (((u64)(a))>>32))) +#define pci64_dma_lo32(a) ((u32) (0xffffffff & (((u64)(a))))) +#define pci64_dma_build(hi,lo) \ + ((dma_addr_t)(((u64)(lo))|(((u64)(hi))<<32))) + +/* + * With the qlogic interface, every queue slot can hold a SCSI + * command with up to 2 scatter/gather entries. If we need more + * than 2 entries, continuation entries can be used that hold + * another 5 entries each. Unlike for other drivers, this means + * that the maximum number of scatter/gather entries we can + * support at any given time is a function of the number of queue + * slots available. That is, host->can_queue and host->sg_tablesize + * are dynamic and _not_ independent. This all works fine because + * requests are queued serially and the scatter/gather limit is + * determined for each queue request anew. + */ + +#define DATASEGS_PER_COMMAND 2 +#define DATASEGS_PER_CONT 5 + +#define QLOGICFC_REQ_QUEUE_LEN 255 /* must be power of two - 1 */ +#define QLOGICFC_MAX_SG(ql) (DATASEGS_PER_COMMAND + (((ql) > 0) ? DATASEGS_PER_CONT*((ql) - 1) : 0)) +#define QLOGICFC_CMD_PER_LUN 8 + +/* Configuration section **************************************************** */ + +/* Set the following macro to 1 to reload the ISP2x00's firmware. This is + version 1.17.30 of the isp2100's firmware and version 2.00.40 of the + isp2200's firmware. +*/ + +#define USE_NVRAM_DEFAULTS 1 + +#define ISP2x00_PORTDB 1 + +/* Set the following to 1 to include fabric support, fabric support is + * currently not as well tested as the other aspects of the driver */ + +#define ISP2x00_FABRIC 1 + +/* Macros used for debugging */ +#define DEBUG_ISP2x00 0 +#define DEBUG_ISP2x00_INT 0 +#define DEBUG_ISP2x00_INTR 0 +#define DEBUG_ISP2x00_SETUP 0 +#define DEBUG_ISP2x00_FABRIC 0 +#define TRACE_ISP 0 + + +#define DEFAULT_LOOP_COUNT 1000000000 + +#define ISP_TIMEOUT (2*HZ) +/* End Configuration section ************************************************ */ + +#include + +#if TRACE_ISP + +#define TRACE_BUF_LEN (32*1024) + +struct { + u_long next; + struct { + u_long time; + u_int index; + u_int addr; + u_char *name; + } buf[TRACE_BUF_LEN]; +} trace; + +#define TRACE(w, i, a) \ +{ \ + unsigned long flags; \ + \ + save_flags(flags); \ + cli(); \ + trace.buf[trace.next].name = (w); \ + trace.buf[trace.next].time = jiffies; \ + trace.buf[trace.next].index = (i); \ + trace.buf[trace.next].addr = (long) (a); \ + trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1); \ + restore_flags(flags); \ +} + +#else +#define TRACE(w, i, a) +#endif + +#if DEBUG_ISP2x00_FABRIC +#define DEBUG_FABRIC(x) x +#else +#define DEBUG_FABRIC(x) +#endif /* DEBUG_ISP2x00_FABRIC */ + + +#if DEBUG_ISP2x00 +#define ENTER(x) printk("isp2x00 : entering %s()\n", x); +#define LEAVE(x) printk("isp2x00 : leaving %s()\n", x); +#define DEBUG(x) x +#else +#define ENTER(x) +#define LEAVE(x) +#define DEBUG(x) +#endif /* DEBUG_ISP2x00 */ + +#if DEBUG_ISP2x00_INTR +#define ENTER_INTR(x) printk("isp2x00 : entering %s()\n", x); +#define LEAVE_INTR(x) printk("isp2x00 : leaving %s()\n", x); +#define DEBUG_INTR(x) x +#else +#define ENTER_INTR(x) +#define LEAVE_INTR(x) +#define DEBUG_INTR(x) +#endif /* DEBUG ISP2x00_INTR */ + + +#define ISP2100_REV_ID1 1 +#define ISP2100_REV_ID3 3 +#define ISP2200_REV_ID5 5 + +/* host configuration and control registers */ +#define HOST_HCCR 0xc0 /* host command and control */ + +/* pci bus interface registers */ +#define FLASH_BIOS_ADDR 0x00 +#define FLASH_BIOS_DATA 0x02 +#define ISP_CTRL_STATUS 0x06 /* configuration register #1 */ +#define PCI_INTER_CTL 0x08 /* pci interrupt control */ +#define PCI_INTER_STS 0x0a /* pci interrupt status */ +#define PCI_SEMAPHORE 0x0c /* pci semaphore */ +#define PCI_NVRAM 0x0e /* pci nvram interface */ + +/* mailbox registers */ +#define MBOX0 0x10 /* mailbox 0 */ +#define MBOX1 0x12 /* mailbox 1 */ +#define MBOX2 0x14 /* mailbox 2 */ +#define MBOX3 0x16 /* mailbox 3 */ +#define MBOX4 0x18 /* mailbox 4 */ +#define MBOX5 0x1a /* mailbox 5 */ +#define MBOX6 0x1c /* mailbox 6 */ +#define MBOX7 0x1e /* mailbox 7 */ + +/* mailbox command complete status codes */ +#define MBOX_COMMAND_COMPLETE 0x4000 +#define INVALID_COMMAND 0x4001 +#define HOST_INTERFACE_ERROR 0x4002 +#define TEST_FAILED 0x4003 +#define COMMAND_ERROR 0x4005 +#define COMMAND_PARAM_ERROR 0x4006 +#define PORT_ID_USED 0x4007 +#define LOOP_ID_USED 0x4008 +#define ALL_IDS_USED 0x4009 + +/* async event status codes */ +#define RESET_DETECTED 0x8001 +#define SYSTEM_ERROR 0x8002 +#define REQUEST_TRANSFER_ERROR 0x8003 +#define RESPONSE_TRANSFER_ERROR 0x8004 +#define REQUEST_QUEUE_WAKEUP 0x8005 +#define LIP_OCCURRED 0x8010 +#define LOOP_UP 0x8011 +#define LOOP_DOWN 0x8012 +#define LIP_RECEIVED 0x8013 +#define PORT_DB_CHANGED 0x8014 +#define CHANGE_NOTIFICATION 0x8015 +#define SCSI_COMMAND_COMPLETE 0x8020 +#define POINT_TO_POINT_UP 0x8030 +#define CONNECTION_MODE 0x8036 + +struct Entry_header { + u_char entry_type; + u_char entry_cnt; + u_char sys_def_1; + u_char flags; +}; + +/* entry header type commands */ +#define ENTRY_COMMAND 0x19 +#define ENTRY_CONTINUATION 0x0a + +#define ENTRY_STATUS 0x03 +#define ENTRY_MARKER 0x04 + + +/* entry header flag definitions */ +#define EFLAG_BUSY 2 +#define EFLAG_BAD_HEADER 4 +#define EFLAG_BAD_PAYLOAD 8 + +struct dataseg { + u_int d_base; + u_int d_base_hi; + u_int d_count; +}; + +struct Command_Entry { + struct Entry_header hdr; + u_int handle; + u_char target_lun; + u_char target_id; + u_short expanded_lun; + u_short control_flags; + u_short rsvd2; + u_short time_out; + u_short segment_cnt; + u_char cdb[16]; + u_int total_byte_cnt; + struct dataseg dataseg[DATASEGS_PER_COMMAND]; +}; + +/* command entry control flag definitions */ +#define CFLAG_NODISC 0x01 +#define CFLAG_HEAD_TAG 0x02 +#define CFLAG_ORDERED_TAG 0x04 +#define CFLAG_SIMPLE_TAG 0x08 +#define CFLAG_TAR_RTN 0x10 +#define CFLAG_READ 0x20 +#define CFLAG_WRITE 0x40 + +struct Continuation_Entry { + struct Entry_header hdr; + struct dataseg dataseg[DATASEGS_PER_CONT]; +}; + +struct Marker_Entry { + struct Entry_header hdr; + u_int reserved; + u_char target_lun; + u_char target_id; + u_char modifier; + u_char expanded_lun; + u_char rsvds[52]; +}; + +/* marker entry modifier definitions */ +#define SYNC_DEVICE 0 +#define SYNC_TARGET 1 +#define SYNC_ALL 2 + +struct Status_Entry { + struct Entry_header hdr; + u_int handle; + u_short scsi_status; + u_short completion_status; + u_short state_flags; + u_short status_flags; + u_short res_info_len; + u_short req_sense_len; + u_int residual; + u_char res_info[8]; + u_char req_sense_data[32]; +}; + +/* status entry completion status definitions */ +#define CS_COMPLETE 0x0000 +#define CS_DMA_ERROR 0x0002 +#define CS_RESET_OCCURRED 0x0004 +#define CS_ABORTED 0x0005 +#define CS_TIMEOUT 0x0006 +#define CS_DATA_OVERRUN 0x0007 +#define CS_DATA_UNDERRUN 0x0015 +#define CS_QUEUE_FULL 0x001c +#define CS_PORT_UNAVAILABLE 0x0028 +#define CS_PORT_LOGGED_OUT 0x0029 +#define CS_PORT_CONFIG_CHANGED 0x002a + +/* status entry state flag definitions */ +#define SF_SENT_CDB 0x0400 +#define SF_TRANSFERRED_DATA 0x0800 +#define SF_GOT_STATUS 0x1000 + +/* status entry status flag definitions */ +#define STF_BUS_RESET 0x0008 +#define STF_DEVICE_RESET 0x0010 +#define STF_ABORTED 0x0020 +#define STF_TIMEOUT 0x0040 + +/* interrupt control commands */ +#define ISP_EN_INT 0x8000 +#define ISP_EN_RISC 0x0008 + +/* host control commands */ +#define HCCR_NOP 0x0000 +#define HCCR_RESET 0x1000 +#define HCCR_PAUSE 0x2000 +#define HCCR_RELEASE 0x3000 +#define HCCR_SINGLE_STEP 0x4000 +#define HCCR_SET_HOST_INTR 0x5000 +#define HCCR_CLEAR_HOST_INTR 0x6000 +#define HCCR_CLEAR_RISC_INTR 0x7000 +#define HCCR_BP_ENABLE 0x8000 +#define HCCR_BIOS_DISABLE 0x9000 +#define HCCR_TEST_MODE 0xf000 + +#define RISC_BUSY 0x0004 + +/* mailbox commands */ +#define MBOX_NO_OP 0x0000 +#define MBOX_LOAD_RAM 0x0001 +#define MBOX_EXEC_FIRMWARE 0x0002 +#define MBOX_DUMP_RAM 0x0003 +#define MBOX_WRITE_RAM_WORD 0x0004 +#define MBOX_READ_RAM_WORD 0x0005 +#define MBOX_MAILBOX_REG_TEST 0x0006 +#define MBOX_VERIFY_CHECKSUM 0x0007 +#define MBOX_ABOUT_FIRMWARE 0x0008 +#define MBOX_LOAD_RISC_RAM 0x0009 +#define MBOX_DUMP_RISC_RAM 0x000a +#define MBOX_CHECK_FIRMWARE 0x000e +#define MBOX_INIT_REQ_QUEUE 0x0010 +#define MBOX_INIT_RES_QUEUE 0x0011 +#define MBOX_EXECUTE_IOCB 0x0012 +#define MBOX_WAKE_UP 0x0013 +#define MBOX_STOP_FIRMWARE 0x0014 +#define MBOX_ABORT_IOCB 0x0015 +#define MBOX_ABORT_DEVICE 0x0016 +#define MBOX_ABORT_TARGET 0x0017 +#define MBOX_BUS_RESET 0x0018 +#define MBOX_STOP_QUEUE 0x0019 +#define MBOX_START_QUEUE 0x001a +#define MBOX_SINGLE_STEP_QUEUE 0x001b +#define MBOX_ABORT_QUEUE 0x001c +#define MBOX_GET_DEV_QUEUE_STATUS 0x001d +#define MBOX_GET_FIRMWARE_STATUS 0x001f +#define MBOX_GET_INIT_SCSI_ID 0x0020 +#define MBOX_GET_RETRY_COUNT 0x0022 +#define MBOX_GET_TARGET_PARAMS 0x0028 +#define MBOX_GET_DEV_QUEUE_PARAMS 0x0029 +#define MBOX_SET_RETRY_COUNT 0x0032 +#define MBOX_SET_TARGET_PARAMS 0x0038 +#define MBOX_SET_DEV_QUEUE_PARAMS 0x0039 +#define MBOX_EXECUTE_IOCB64 0x0054 +#define MBOX_INIT_FIRMWARE 0x0060 +#define MBOX_GET_INIT_CB 0x0061 +#define MBOX_INIT_LIP 0x0062 +#define MBOX_GET_POS_MAP 0x0063 +#define MBOX_GET_PORT_DB 0x0064 +#define MBOX_CLEAR_ACA 0x0065 +#define MBOX_TARGET_RESET 0x0066 +#define MBOX_CLEAR_TASK_SET 0x0067 +#define MBOX_ABORT_TASK_SET 0x0068 +#define MBOX_GET_FIRMWARE_STATE 0x0069 +#define MBOX_GET_PORT_NAME 0x006a +#define MBOX_SEND_SNS 0x006e +#define MBOX_PORT_LOGIN 0x006f +#define MBOX_SEND_CHANGE_REQUEST 0x0070 +#define MBOX_PORT_LOGOUT 0x0071 + +/* + * Firmware if needed (note this is a hack, it belongs in a separate + * module. + */ + +#ifdef CONFIG_SCSI_QLOGIC_FC_FIRMWARE +#include "qlogicfc_asm.c" +#else +static unsigned short risc_code_addr01 = 0x1000 ; +#endif + +/* Each element in mbox_param is an 8 bit bitmap where each bit indicates + if that mbox should be copied as input. For example 0x2 would mean + only copy mbox1. */ + +static const u_char mbox_param[] = +{ + 0x01, /* MBOX_NO_OP */ + 0x1f, /* MBOX_LOAD_RAM */ + 0x03, /* MBOX_EXEC_FIRMWARE */ + 0x1f, /* MBOX_DUMP_RAM */ + 0x07, /* MBOX_WRITE_RAM_WORD */ + 0x03, /* MBOX_READ_RAM_WORD */ + 0xff, /* MBOX_MAILBOX_REG_TEST */ + 0x03, /* MBOX_VERIFY_CHECKSUM */ + 0x01, /* MBOX_ABOUT_FIRMWARE */ + 0xff, /* MBOX_LOAD_RISC_RAM */ + 0xff, /* MBOX_DUMP_RISC_RAM */ + 0x00, /* 0x000b */ + 0x00, /* 0x000c */ + 0x00, /* 0x000d */ + 0x01, /* MBOX_CHECK_FIRMWARE */ + 0x00, /* 0x000f */ + 0x1f, /* MBOX_INIT_REQ_QUEUE */ + 0x2f, /* MBOX_INIT_RES_QUEUE */ + 0x0f, /* MBOX_EXECUTE_IOCB */ + 0x03, /* MBOX_WAKE_UP */ + 0x01, /* MBOX_STOP_FIRMWARE */ + 0x0f, /* MBOX_ABORT_IOCB */ + 0x03, /* MBOX_ABORT_DEVICE */ + 0x07, /* MBOX_ABORT_TARGET */ + 0x03, /* MBOX_BUS_RESET */ + 0x03, /* MBOX_STOP_QUEUE */ + 0x03, /* MBOX_START_QUEUE */ + 0x03, /* MBOX_SINGLE_STEP_QUEUE */ + 0x03, /* MBOX_ABORT_QUEUE */ + 0x03, /* MBOX_GET_DEV_QUEUE_STATUS */ + 0x00, /* 0x001e */ + 0x01, /* MBOX_GET_FIRMWARE_STATUS */ + 0x01, /* MBOX_GET_INIT_SCSI_ID */ + 0x00, /* 0x0021 */ + 0x01, /* MBOX_GET_RETRY_COUNT */ + 0x00, /* 0x0023 */ + 0x00, /* 0x0024 */ + 0x00, /* 0x0025 */ + 0x00, /* 0x0026 */ + 0x00, /* 0x0027 */ + 0x03, /* MBOX_GET_TARGET_PARAMS */ + 0x03, /* MBOX_GET_DEV_QUEUE_PARAMS */ + 0x00, /* 0x002a */ + 0x00, /* 0x002b */ + 0x00, /* 0x002c */ + 0x00, /* 0x002d */ + 0x00, /* 0x002e */ + 0x00, /* 0x002f */ + 0x00, /* 0x0030 */ + 0x00, /* 0x0031 */ + 0x07, /* MBOX_SET_RETRY_COUNT */ + 0x00, /* 0x0033 */ + 0x00, /* 0x0034 */ + 0x00, /* 0x0035 */ + 0x00, /* 0x0036 */ + 0x00, /* 0x0037 */ + 0x0f, /* MBOX_SET_TARGET_PARAMS */ + 0x0f, /* MBOX_SET_DEV_QUEUE_PARAMS */ + 0x00, /* 0x003a */ + 0x00, /* 0x003b */ + 0x00, /* 0x003c */ + 0x00, /* 0x003d */ + 0x00, /* 0x003e */ + 0x00, /* 0x003f */ + 0x00, /* 0x0040 */ + 0x00, /* 0x0041 */ + 0x00, /* 0x0042 */ + 0x00, /* 0x0043 */ + 0x00, /* 0x0044 */ + 0x00, /* 0x0045 */ + 0x00, /* 0x0046 */ + 0x00, /* 0x0047 */ + 0x00, /* 0x0048 */ + 0x00, /* 0x0049 */ + 0x00, /* 0x004a */ + 0x00, /* 0x004b */ + 0x00, /* 0x004c */ + 0x00, /* 0x004d */ + 0x00, /* 0x004e */ + 0x00, /* 0x004f */ + 0x00, /* 0x0050 */ + 0x00, /* 0x0051 */ + 0x00, /* 0x0052 */ + 0x00, /* 0x0053 */ + 0xcf, /* MBOX_EXECUTE_IOCB64 */ + 0x00, /* 0x0055 */ + 0x00, /* 0x0056 */ + 0x00, /* 0x0057 */ + 0x00, /* 0x0058 */ + 0x00, /* 0x0059 */ + 0x00, /* 0x005a */ + 0x00, /* 0x005b */ + 0x00, /* 0x005c */ + 0x00, /* 0x005d */ + 0x00, /* 0x005e */ + 0x00, /* 0x005f */ + 0xff, /* MBOX_INIT_FIRMWARE */ + 0xcd, /* MBOX_GET_INIT_CB */ + 0x01, /* MBOX_INIT_LIP */ + 0xcd, /* MBOX_GET_POS_MAP */ + 0xcf, /* MBOX_GET_PORT_DB */ + 0x03, /* MBOX_CLEAR_ACA */ + 0x03, /* MBOX_TARGET_RESET */ + 0x03, /* MBOX_CLEAR_TASK_SET */ + 0x03, /* MBOX_ABORT_TASK_SET */ + 0x01, /* MBOX_GET_FIRMWARE_STATE */ + 0x03, /* MBOX_GET_PORT_NAME */ + 0x00, /* 0x006b */ + 0x00, /* 0x006c */ + 0x00, /* 0x006d */ + 0xcf, /* MBOX_SEND_SNS */ + 0x0f, /* MBOX_PORT_LOGIN */ + 0x03, /* MBOX_SEND_CHANGE_REQUEST */ + 0x03, /* MBOX_PORT_LOGOUT */ +}; + +#define MAX_MBOX_COMMAND (sizeof(mbox_param)/sizeof(u_short)) + + +struct id_name_map { + u64 wwn; + u_char loop_id; +}; + +struct sns_cb { + u_short len; + u_short res1; + u_int response_low; + u_int response_high; + u_short sub_len; + u_short res2; + u_char data[44]; +}; + +/* address of instance of this struct is passed to adapter to initialize things + */ +struct init_cb { + u_char version; + u_char reseverd1[1]; + u_short firm_opts; + u_short max_frame_len; + u_short max_iocb; + u_short exec_throttle; + u_char retry_cnt; + u_char retry_delay; + u_short node_name[4]; + u_short hard_addr; + u_char reserved2[10]; + u_short req_queue_out; + u_short res_queue_in; + u_short req_queue_len; + u_short res_queue_len; + u_int req_queue_addr_lo; + u_int req_queue_addr_high; + u_int res_queue_addr_lo; + u_int res_queue_addr_high; + /* the rest of this structure only applies to the isp2200 */ + u_short lun_enables; + u_char cmd_resource_cnt; + u_char notify_resource_cnt; + u_short timeout; + u_short reserved3; + u_short add_firm_opts; + u_char res_accum_timer; + u_char irq_delay_timer; + u_short special_options; + u_short reserved4[13]; +}; + +/* + * The result queue can be quite a bit smaller since continuation entries + * do not show up there: + */ +#define RES_QUEUE_LEN ((QLOGICFC_REQ_QUEUE_LEN + 1) / 8 - 1) +#define QUEUE_ENTRY_LEN 64 + +#if ISP2x00_FABRIC +#define QLOGICFC_MAX_ID 0xff +#else +#define QLOGICFC_MAX_ID 0x7d +#endif + +#define QLOGICFC_MAX_LUN 128 +#define QLOGICFC_MAX_LOOP_ID 0x7d + +/* the following connection options only apply to the 2200. i have only + * had success with LOOP_ONLY and P2P_ONLY. + */ + +#define LOOP_ONLY 0 +#define P2P_ONLY 1 +#define LOOP_PREFERED 2 +#define P2P_PREFERED 3 + +#define CONNECTION_PREFERENCE LOOP_ONLY + +/* adapter_state values */ +#define AS_FIRMWARE_DEAD -1 +#define AS_LOOP_DOWN 0 +#define AS_LOOP_GOOD 1 +#define AS_REDO_FABRIC_PORTDB 2 +#define AS_REDO_LOOP_PORTDB 4 + +#define RES_SIZE ((RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN) +#define REQ_SIZE ((QLOGICFC_REQ_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN) + +struct isp2x00_hostdata { + u_char revision; + struct pci_dev *pci_dev; + /* result and request queues (shared with isp2x00): */ + u_int req_in_ptr; /* index of next request slot */ + u_int res_out_ptr; /* index of next result slot */ + + /* this is here so the queues are nicely aligned */ + long send_marker; /* do we need to send a marker? */ + + char * res; + char * req; + struct init_cb control_block; + int adapter_state; + unsigned long int tag_ages[QLOGICFC_MAX_ID + 1]; + Scsi_Cmnd *handle_ptrs[QLOGICFC_REQ_QUEUE_LEN + 1]; + unsigned long handle_serials[QLOGICFC_REQ_QUEUE_LEN + 1]; + struct id_name_map port_db[QLOGICFC_MAX_ID + 1]; + u_char mbox_done; + u64 wwn; + u_int port_id; + u_char queued; + u_char host_id; + struct timer_list explore_timer; + struct id_name_map tempmap[QLOGICFC_MAX_ID + 1]; +}; + + +/* queue length's _must_ be power of two: */ +#define QUEUE_DEPTH(in, out, ql) ((in - out) & (ql)) +#define REQ_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, \ + QLOGICFC_REQ_QUEUE_LEN) +#define RES_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, RES_QUEUE_LEN) + +static void isp2x00_enable_irqs(struct Scsi_Host *); +static void isp2x00_disable_irqs(struct Scsi_Host *); +static int isp2x00_init(struct Scsi_Host *); +static int isp2x00_reset_hardware(struct Scsi_Host *); +static int isp2x00_mbox_command(struct Scsi_Host *, u_short[]); +static int isp2x00_return_status(Scsi_Cmnd *, struct Status_Entry *); +static void isp2x00_intr_handler(int, void *, struct pt_regs *); +static irqreturn_t do_isp2x00_intr_handler(int, void *, struct pt_regs *); +static int isp2x00_make_portdb(struct Scsi_Host *); + +#if ISP2x00_FABRIC +static int isp2x00_init_fabric(struct Scsi_Host *, struct id_name_map *, int); +#endif + +#if USE_NVRAM_DEFAULTS +static int isp2x00_get_nvram_defaults(struct Scsi_Host *, struct init_cb *); +static u_short isp2x00_read_nvram_word(struct Scsi_Host *, u_short); +#endif + +#if DEBUG_ISP2x00 +static void isp2x00_print_scsi_cmd(Scsi_Cmnd *); +#endif + +#if DEBUG_ISP2x00_INTR +static void isp2x00_print_status_entry(struct Status_Entry *); +#endif + +static inline void isp2x00_enable_irqs(struct Scsi_Host *host) +{ + outw(ISP_EN_INT | ISP_EN_RISC, host->io_port + PCI_INTER_CTL); +} + + +static inline void isp2x00_disable_irqs(struct Scsi_Host *host) +{ + outw(0x0, host->io_port + PCI_INTER_CTL); +} + + +static int isp2x00_detect(struct scsi_host_template * tmpt) +{ + int hosts = 0; + unsigned long wait_time; + struct Scsi_Host *host = NULL; + struct isp2x00_hostdata *hostdata; + struct pci_dev *pdev; + unsigned short device_ids[2]; + dma_addr_t busaddr; + int i; + + + ENTER("isp2x00_detect"); + + device_ids[0] = PCI_DEVICE_ID_QLOGIC_ISP2100; + device_ids[1] = PCI_DEVICE_ID_QLOGIC_ISP2200; + + tmpt->proc_name = "isp2x00"; + + for (i=0; i<2; i++){ + pdev = NULL; + while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, device_ids[i], pdev))) { + if (pci_enable_device(pdev)) + continue; + + /* Try to configure DMA attributes. */ + if (pci_set_dma_mask(pdev, 0xffffffffffffffffULL) && + pci_set_dma_mask(pdev, 0xffffffffULL)) + continue; + + host = scsi_register(tmpt, sizeof(struct isp2x00_hostdata)); + if (!host) { + printk("qlogicfc%d : could not register host.\n", hosts); + continue; + } + host->max_id = QLOGICFC_MAX_ID + 1; + host->max_lun = QLOGICFC_MAX_LUN; + hostdata = (struct isp2x00_hostdata *) host->hostdata; + + memset(hostdata, 0, sizeof(struct isp2x00_hostdata)); + hostdata->pci_dev = pdev; + hostdata->res = pci_alloc_consistent(pdev, RES_SIZE + REQ_SIZE, &busaddr); + + if (!hostdata->res){ + printk("qlogicfc%d : could not allocate memory for request and response queue.\n", hosts); + scsi_unregister(host); + continue; + } + hostdata->req = hostdata->res + (RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN; + hostdata->queued = 0; + /* set up the control block */ + hostdata->control_block.version = 0x1; + hostdata->control_block.firm_opts = cpu_to_le16(0x800e); + hostdata->control_block.max_frame_len = cpu_to_le16(2048); + hostdata->control_block.max_iocb = cpu_to_le16(QLOGICFC_REQ_QUEUE_LEN); + hostdata->control_block.exec_throttle = cpu_to_le16(QLOGICFC_CMD_PER_LUN); + hostdata->control_block.retry_delay = 5; + hostdata->control_block.retry_cnt = 1; + hostdata->control_block.node_name[0] = cpu_to_le16(0x0020); + hostdata->control_block.node_name[1] = cpu_to_le16(0xE000); + hostdata->control_block.node_name[2] = cpu_to_le16(0x008B); + hostdata->control_block.node_name[3] = cpu_to_le16(0x0000); + hostdata->control_block.hard_addr = cpu_to_le16(0x0003); + hostdata->control_block.req_queue_len = cpu_to_le16(QLOGICFC_REQ_QUEUE_LEN + 1); + hostdata->control_block.res_queue_len = cpu_to_le16(RES_QUEUE_LEN + 1); + hostdata->control_block.res_queue_addr_lo = cpu_to_le32(pci64_dma_lo32(busaddr)); + hostdata->control_block.res_queue_addr_high = cpu_to_le32(pci64_dma_hi32(busaddr)); + hostdata->control_block.req_queue_addr_lo = cpu_to_le32(pci64_dma_lo32(busaddr + RES_SIZE)); + hostdata->control_block.req_queue_addr_high = cpu_to_le32(pci64_dma_hi32(busaddr + RES_SIZE)); + + + hostdata->control_block.add_firm_opts |= cpu_to_le16(CONNECTION_PREFERENCE<<4); + hostdata->adapter_state = AS_LOOP_DOWN; + hostdata->explore_timer.data = 1; + hostdata->host_id = hosts; + + if (isp2x00_init(host) || isp2x00_reset_hardware(host)) { + pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr); + scsi_unregister(host); + continue; + } + host->this_id = 0; + + if (request_irq(host->irq, do_isp2x00_intr_handler, SA_INTERRUPT | SA_SHIRQ, "qlogicfc", host)) { + printk("qlogicfc%d : interrupt %d already in use\n", + hostdata->host_id, host->irq); + pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr); + scsi_unregister(host); + continue; + } + if (!request_region(host->io_port, 0xff, "qlogicfc")) { + printk("qlogicfc%d : i/o region 0x%lx-0x%lx already " + "in use\n", + hostdata->host_id, host->io_port, host->io_port + 0xff); + free_irq(host->irq, host); + pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr); + scsi_unregister(host); + continue; + } + + outw(0x0, host->io_port + PCI_SEMAPHORE); + outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR); + isp2x00_enable_irqs(host); + /* wait for the loop to come up */ + for (wait_time = jiffies + 10 * HZ; time_before(jiffies, wait_time) && hostdata->adapter_state == AS_LOOP_DOWN;) { + barrier(); + cpu_relax(); + } + if (hostdata->adapter_state == AS_LOOP_DOWN) { + printk("qlogicfc%d : link is not up\n", hostdata->host_id); + } + hosts++; + hostdata->explore_timer.data = 0; + } + } + + + /* this busy loop should not be needed but the isp2x00 seems to need + some time before recognizing it is attached to a fabric */ + +#if ISP2x00_FABRIC + if (hosts) { + for (wait_time = jiffies + 5 * HZ; time_before(jiffies, wait_time);) { + barrier(); + cpu_relax(); + } + } +#endif + + LEAVE("isp2x00_detect"); + + return hosts; +} + + +static int isp2x00_make_portdb(struct Scsi_Host *host) +{ + + short param[8]; + int i, j; + struct isp2x00_hostdata *hostdata; + + isp2x00_disable_irqs(host); + + hostdata = (struct isp2x00_hostdata *) host->hostdata; + memset(hostdata->tempmap, 0, sizeof(hostdata->tempmap)); + +#if ISP2x00_FABRIC + for (i = 0x81; i < QLOGICFC_MAX_ID; i++) { + param[0] = MBOX_PORT_LOGOUT; + param[1] = i << 8; + param[2] = 0; + param[3] = 0; + + isp2x00_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + + DEBUG_FABRIC(printk("qlogicfc%d : logout failed %x %x\n", hostdata->host_id, i, param[0])); + } + } +#endif + + + param[0] = MBOX_GET_INIT_SCSI_ID; + + isp2x00_mbox_command(host, param); + + if (param[0] == MBOX_COMMAND_COMPLETE) { + hostdata->port_id = ((u_int) param[3]) << 16; + hostdata->port_id |= param[2]; + hostdata->tempmap[0].loop_id = param[1]; + hostdata->tempmap[0].wwn = hostdata->wwn; + } + else { + printk("qlogicfc%d : error getting scsi id.\n", hostdata->host_id); + } + + for (i = 0; i <=QLOGICFC_MAX_ID; i++) + hostdata->tempmap[i].loop_id = hostdata->tempmap[0].loop_id; + + for (i = 0, j = 1; i <= QLOGICFC_MAX_LOOP_ID; i++) { + param[0] = MBOX_GET_PORT_NAME; + param[1] = (i << 8) & 0xff00; + + isp2x00_mbox_command(host, param); + + if (param[0] == MBOX_COMMAND_COMPLETE) { + hostdata->tempmap[j].loop_id = i; + hostdata->tempmap[j].wwn = ((u64) (param[2] & 0xff)) << 56; + hostdata->tempmap[j].wwn |= ((u64) ((param[2] >> 8) & 0xff)) << 48; + hostdata->tempmap[j].wwn |= ((u64) (param[3] & 0xff)) << 40; + hostdata->tempmap[j].wwn |= ((u64) ((param[3] >> 8) & 0xff)) << 32; + hostdata->tempmap[j].wwn |= ((u64) (param[6] & 0xff)) << 24; + hostdata->tempmap[j].wwn |= ((u64) ((param[6] >> 8) & 0xff)) << 16; + hostdata->tempmap[j].wwn |= ((u64) (param[7] & 0xff)) << 8; + hostdata->tempmap[j].wwn |= ((u64) ((param[7] >> 8) & 0xff)); + + j++; + + } + } + + +#if ISP2x00_FABRIC + isp2x00_init_fabric(host, hostdata->tempmap, j); +#endif + + for (i = 0; i <= QLOGICFC_MAX_ID; i++) { + if (hostdata->tempmap[i].wwn != hostdata->port_db[i].wwn) { + for (j = 0; j <= QLOGICFC_MAX_ID; j++) { + if (hostdata->tempmap[j].wwn == hostdata->port_db[i].wwn) { + hostdata->port_db[i].loop_id = hostdata->tempmap[j].loop_id; + break; + } + } + if (j == QLOGICFC_MAX_ID + 1) + hostdata->port_db[i].loop_id = hostdata->tempmap[0].loop_id; + + for (j = 0; j <= QLOGICFC_MAX_ID; j++) { + if (hostdata->port_db[j].wwn == hostdata->tempmap[i].wwn || !hostdata->port_db[j].wwn) { + break; + } + } + if (j == QLOGICFC_MAX_ID + 1) + printk("qlogicfc%d : Too many scsi devices, no more room in port map.\n", hostdata->host_id); + if (!hostdata->port_db[j].wwn) { + hostdata->port_db[j].loop_id = hostdata->tempmap[i].loop_id; + hostdata->port_db[j].wwn = hostdata->tempmap[i].wwn; + } + } else + hostdata->port_db[i].loop_id = hostdata->tempmap[i].loop_id; + + } + + isp2x00_enable_irqs(host); + + return 0; +} + + +#if ISP2x00_FABRIC + +#define FABRIC_PORT 0x7e +#define FABRIC_CONTROLLER 0x7f +#define FABRIC_SNS 0x80 + +int isp2x00_init_fabric(struct Scsi_Host *host, struct id_name_map *port_db, int cur_scsi_id) +{ + + u_short param[8]; + u64 wwn; + int done = 0; + u_short loop_id = 0x81; + u_short scsi_id = cur_scsi_id; + u_int port_id; + struct sns_cb *req; + u_char *sns_response; + dma_addr_t busaddr; + struct isp2x00_hostdata *hostdata; + + hostdata = (struct isp2x00_hostdata *) host->hostdata; + + DEBUG_FABRIC(printk("qlogicfc%d : Checking for a fabric.\n", hostdata->host_id)); + param[0] = MBOX_GET_PORT_NAME; + param[1] = (u16)FABRIC_PORT << 8; + + isp2x00_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + DEBUG_FABRIC(printk("qlogicfc%d : fabric check result %x\n", hostdata->host_id, param[0])); + return 0; + } + printk("qlogicfc%d : Fabric found.\n", hostdata->host_id); + + req = (struct sns_cb *)pci_alloc_consistent(hostdata->pci_dev, sizeof(*req) + 608, &busaddr); + + if (!req){ + printk("qlogicfc%d : Could not allocate DMA resources for fabric initialization\n", hostdata->host_id); + return 0; + } + sns_response = (u_char *)(req + 1); + + if (hostdata->adapter_state & AS_REDO_LOOP_PORTDB){ + memset(req, 0, sizeof(*req)); + + req->len = cpu_to_le16(8); + req->response_low = cpu_to_le32(pci64_dma_lo32(busaddr + sizeof(*req))); + req->response_high = cpu_to_le32(pci64_dma_hi32(busaddr + sizeof(*req))); + req->sub_len = cpu_to_le16(22); + req->data[0] = 0x17; + req->data[1] = 0x02; + req->data[8] = (u_char) (hostdata->port_id & 0xff); + req->data[9] = (u_char) (hostdata->port_id >> 8 & 0xff); + req->data[10] = (u_char) (hostdata->port_id >> 16 & 0xff); + req->data[13] = 0x01; + param[0] = MBOX_SEND_SNS; + param[1] = 30; + param[2] = pci64_dma_lo32(busaddr) >> 16; + param[3] = pci64_dma_lo32(busaddr); + param[6] = pci64_dma_hi32(busaddr) >> 16; + param[7] = pci64_dma_hi32(busaddr); + + isp2x00_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) + printk("qlogicfc%d : error sending RFC-4\n", hostdata->host_id); + } + + port_id = hostdata->port_id; + while (!done) { + memset(req, 0, sizeof(*req)); + + req->len = cpu_to_le16(304); + req->response_low = cpu_to_le32(pci64_dma_lo32(busaddr + sizeof(*req))); + req->response_high = cpu_to_le32(pci64_dma_hi32(busaddr + sizeof(*req))); + req->sub_len = cpu_to_le16(6); + req->data[0] = 0x00; + req->data[1] = 0x01; + req->data[8] = (u_char) (port_id & 0xff); + req->data[9] = (u_char) (port_id >> 8 & 0xff); + req->data[10] = (u_char) (port_id >> 16 & 0xff); + + param[0] = MBOX_SEND_SNS; + param[1] = 14; + param[2] = pci64_dma_lo32(busaddr) >> 16; + param[3] = pci64_dma_lo32(busaddr); + param[6] = pci64_dma_hi32(busaddr) >> 16; + param[7] = pci64_dma_hi32(busaddr); + + isp2x00_mbox_command(host, param); + + if (param[0] == MBOX_COMMAND_COMPLETE) { + DEBUG_FABRIC(printk("qlogicfc%d : found node %02x%02x%02x%02x%02x%02x%02x%02x ", hostdata->host_id, sns_response[20], sns_response[21], sns_response[22], sns_response[23], sns_response[24], sns_response[25], sns_response[26], sns_response[27])); + DEBUG_FABRIC(printk(" port id: %02x%02x%02x\n", sns_response[17], sns_response[18], sns_response[19])); + port_id = ((u_int) sns_response[17]) << 16; + port_id |= ((u_int) sns_response[18]) << 8; + port_id |= ((u_int) sns_response[19]); + wwn = ((u64) sns_response[20]) << 56; + wwn |= ((u64) sns_response[21]) << 48; + wwn |= ((u64) sns_response[22]) << 40; + wwn |= ((u64) sns_response[23]) << 32; + wwn |= ((u64) sns_response[24]) << 24; + wwn |= ((u64) sns_response[25]) << 16; + wwn |= ((u64) sns_response[26]) << 8; + wwn |= ((u64) sns_response[27]); + if (hostdata->port_id >> 8 != port_id >> 8) { + DEBUG_FABRIC(printk("qlogicfc%d : adding a fabric port: %x\n", hostdata->host_id, port_id)); + param[0] = MBOX_PORT_LOGIN; + param[1] = loop_id << 8; + param[2] = (u_short) (port_id >> 16); + param[3] = (u_short) (port_id); + + isp2x00_mbox_command(host, param); + + if (param[0] == MBOX_COMMAND_COMPLETE) { + port_db[scsi_id].wwn = wwn; + port_db[scsi_id].loop_id = loop_id; + loop_id++; + scsi_id++; + } else { + printk("qlogicfc%d : Error performing port login %x\n", hostdata->host_id, param[0]); + DEBUG_FABRIC(printk("qlogicfc%d : loop_id: %x\n", hostdata->host_id, loop_id)); + param[0] = MBOX_PORT_LOGOUT; + param[1] = loop_id << 8; + param[2] = 0; + param[3] = 0; + + isp2x00_mbox_command(host, param); + + } + + } + if (hostdata->port_id == port_id) + done = 1; + } else { + printk("qlogicfc%d : Get All Next failed %x.\n", hostdata->host_id, param[0]); + pci_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr); + return 0; + } + } + + pci_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr); + return 1; +} + +#endif /* ISP2x00_FABRIC */ + + +static int isp2x00_release(struct Scsi_Host *host) +{ + struct isp2x00_hostdata *hostdata; + dma_addr_t busaddr; + + ENTER("isp2x00_release"); + + hostdata = (struct isp2x00_hostdata *) host->hostdata; + + outw(0x0, host->io_port + PCI_INTER_CTL); + free_irq(host->irq, host); + + release_region(host->io_port, 0xff); + + busaddr = pci64_dma_build(le32_to_cpu(hostdata->control_block.res_queue_addr_high), + le32_to_cpu(hostdata->control_block.res_queue_addr_lo)); + pci_free_consistent(hostdata->pci_dev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr); + + LEAVE("isp2x00_release"); + + return 0; +} + + +static const char *isp2x00_info(struct Scsi_Host *host) +{ + static char buf[80]; + struct isp2x00_hostdata *hostdata; + ENTER("isp2x00_info"); + + hostdata = (struct isp2x00_hostdata *) host->hostdata; + sprintf(buf, + "QLogic ISP%04x SCSI on PCI bus %02x device %02x irq %d base 0x%lx", + hostdata->pci_dev->device, hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq, + host->io_port); + + + LEAVE("isp2x00_info"); + + return buf; +} + + +/* + * The middle SCSI layer ensures that queuecommand never gets invoked + * concurrently with itself or the interrupt handler (though the + * interrupt handler may call this routine as part of + * request-completion handling). + */ +static int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *)) +{ + int i, sg_count, n, num_free; + u_int in_ptr, out_ptr; + struct dataseg *ds; + struct scatterlist *sg; + struct Command_Entry *cmd; + struct Continuation_Entry *cont; + struct Scsi_Host *host; + struct isp2x00_hostdata *hostdata; + + ENTER("isp2x00_queuecommand"); + + host = Cmnd->device->host; + hostdata = (struct isp2x00_hostdata *) host->hostdata; + Cmnd->scsi_done = done; + + DEBUG(isp2x00_print_scsi_cmd(Cmnd)); + + if (hostdata->adapter_state & AS_REDO_FABRIC_PORTDB || hostdata->adapter_state & AS_REDO_LOOP_PORTDB) { + isp2x00_make_portdb(host); + hostdata->adapter_state = AS_LOOP_GOOD; + printk("qlogicfc%d : Port Database\n", hostdata->host_id); + for (i = 0; hostdata->port_db[i].wwn != 0; i++) { + printk("wwn: %08x%08x scsi_id: %x loop_id: ", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i); + if (hostdata->port_db[i].loop_id != hostdata->port_db[0].loop_id || i == 0) + printk("%x", hostdata->port_db[i].loop_id); + else + printk("Not Available"); + printk("\n"); + } + } + if (hostdata->adapter_state == AS_FIRMWARE_DEAD) { + printk("qlogicfc%d : The firmware is dead, just return.\n", hostdata->host_id); + host->max_id = 0; + return 0; + } + + out_ptr = inw(host->io_port + MBOX4); + in_ptr = hostdata->req_in_ptr; + + DEBUG(printk("qlogicfc%d : request queue depth %d\n", hostdata->host_id, + REQ_QUEUE_DEPTH(in_ptr, out_ptr))); + + cmd = (struct Command_Entry *) &hostdata->req[in_ptr*QUEUE_ENTRY_LEN]; + in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; + if (in_ptr == out_ptr) { + DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id)); + return 1; + } + if (hostdata->send_marker) { + struct Marker_Entry *marker; + + TRACE("queue marker", in_ptr, 0); + + DEBUG(printk("qlogicfc%d : adding marker entry\n", hostdata->host_id)); + marker = (struct Marker_Entry *) cmd; + memset(marker, 0, sizeof(struct Marker_Entry)); + + marker->hdr.entry_type = ENTRY_MARKER; + marker->hdr.entry_cnt = 1; + marker->modifier = SYNC_ALL; + + hostdata->send_marker = 0; + + if (((in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN) == out_ptr) { + outw(in_ptr, host->io_port + MBOX4); + hostdata->req_in_ptr = in_ptr; + DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id)); + return 1; + } + cmd = (struct Command_Entry *) &hostdata->req[in_ptr*QUEUE_ENTRY_LEN]; + in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; + } + TRACE("queue command", in_ptr, Cmnd); + + memset(cmd, 0, sizeof(struct Command_Entry)); + + /* find a free handle mapping slot */ + for (i = in_ptr; i != (in_ptr - 1) && hostdata->handle_ptrs[i]; i = ((i + 1) % (QLOGICFC_REQ_QUEUE_LEN + 1))); + + if (!hostdata->handle_ptrs[i]) { + cmd->handle = cpu_to_le32(i); + hostdata->handle_ptrs[i] = Cmnd; + hostdata->handle_serials[i] = Cmnd->serial_number; + } else { + printk("qlogicfc%d : no handle slots, this should not happen.\n", hostdata->host_id); + printk("hostdata->queued is %x, in_ptr: %x\n", hostdata->queued, in_ptr); + for (i = 0; i <= QLOGICFC_REQ_QUEUE_LEN; i++){ + if (!hostdata->handle_ptrs[i]){ + printk("slot %d has %p\n", i, hostdata->handle_ptrs[i]); + } + } + return 1; + } + + cmd->hdr.entry_type = ENTRY_COMMAND; + cmd->hdr.entry_cnt = 1; + cmd->target_lun = Cmnd->device->lun; + cmd->expanded_lun = cpu_to_le16(Cmnd->device->lun); +#if ISP2x00_PORTDB + cmd->target_id = hostdata->port_db[Cmnd->device->id].loop_id; +#else + cmd->target_id = Cmnd->target; +#endif + cmd->total_byte_cnt = cpu_to_le32(Cmnd->request_bufflen); + cmd->time_out = 0; + memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len); + + if (Cmnd->use_sg) { + sg = (struct scatterlist *) Cmnd->request_buffer; + sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, Cmnd->sc_data_direction); + cmd->segment_cnt = cpu_to_le16(sg_count); + ds = cmd->dataseg; + /* fill in first two sg entries: */ + n = sg_count; + if (n > DATASEGS_PER_COMMAND) + n = DATASEGS_PER_COMMAND; + + for (i = 0; i < n; i++) { + ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma_address(sg))); + ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma_address(sg))); + ds[i].d_count = cpu_to_le32(sg_dma_len(sg)); + ++sg; + } + sg_count -= DATASEGS_PER_COMMAND; + + while (sg_count > 0) { + ++cmd->hdr.entry_cnt; + cont = (struct Continuation_Entry *) + &hostdata->req[in_ptr*QUEUE_ENTRY_LEN]; + memset(cont, 0, sizeof(struct Continuation_Entry)); + in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; + if (in_ptr == out_ptr) { + DEBUG(printk("qlogicfc%d : unexpected request queue overflow\n", hostdata->host_id)); + return 1; + } + TRACE("queue continuation", in_ptr, 0); + cont->hdr.entry_type = ENTRY_CONTINUATION; + ds = cont->dataseg; + n = sg_count; + if (n > DATASEGS_PER_CONT) + n = DATASEGS_PER_CONT; + for (i = 0; i < n; ++i) { + ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma_address(sg))); + ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma_address(sg))); + ds[i].d_count = cpu_to_le32(sg_dma_len(sg)); + ++sg; + } + sg_count -= n; + } + } else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE) { + struct page *page = virt_to_page(Cmnd->request_buffer); + unsigned long offset = offset_in_page(Cmnd->request_buffer); + dma_addr_t busaddr = pci_map_page(hostdata->pci_dev, + page, offset, + Cmnd->request_bufflen, + Cmnd->sc_data_direction); + Cmnd->SCp.dma_handle = busaddr; + + cmd->dataseg[0].d_base = cpu_to_le32(pci64_dma_lo32(busaddr)); + cmd->dataseg[0].d_base_hi = cpu_to_le32(pci64_dma_hi32(busaddr)); + cmd->dataseg[0].d_count = cpu_to_le32(Cmnd->request_bufflen); + cmd->segment_cnt = cpu_to_le16(1); + } else { + cmd->dataseg[0].d_base = 0; + cmd->dataseg[0].d_base_hi = 0; + cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */ + } + + if (Cmnd->sc_data_direction == DMA_TO_DEVICE) + cmd->control_flags = cpu_to_le16(CFLAG_WRITE); + else + cmd->control_flags = cpu_to_le16(CFLAG_READ); + + if (Cmnd->device->tagged_supported) { + if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * ISP_TIMEOUT)) { + cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG); + hostdata->tag_ages[Cmnd->device->id] = jiffies; + } else + switch (Cmnd->tag) { + case HEAD_OF_QUEUE_TAG: + cmd->control_flags |= cpu_to_le16(CFLAG_HEAD_TAG); + break; + case ORDERED_QUEUE_TAG: + cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG); + break; + default: + cmd->control_flags |= cpu_to_le16(CFLAG_SIMPLE_TAG); + break; + } + } + /* + * TEST_UNIT_READY commands from scsi_scan will fail due to "overlapped + * commands attempted" unless we setup at least a simple queue (midlayer + * will embelish this once it can do an INQUIRY command to the device) + */ + else + cmd->control_flags |= cpu_to_le16(CFLAG_SIMPLE_TAG); + outw(in_ptr, host->io_port + MBOX4); + hostdata->req_in_ptr = in_ptr; + + hostdata->queued++; + + num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr); + num_free = (num_free > 2) ? num_free - 2 : 0; + host->can_queue = host->host_busy + num_free; + if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN) + host->can_queue = QLOGICFC_REQ_QUEUE_LEN; + host->sg_tablesize = QLOGICFC_MAX_SG(num_free); + + LEAVE("isp2x00_queuecommand"); + + return 0; +} + + +/* we have received an event, such as a lip or an RSCN, which may mean that + * our port database is incorrect so the port database must be recreated. + */ +static void redo_port_db(unsigned long arg) +{ + + struct Scsi_Host * host = (struct Scsi_Host *) arg; + struct isp2x00_hostdata * hostdata; + unsigned long flags; + int i; + + hostdata = (struct isp2x00_hostdata *) host->hostdata; + hostdata->explore_timer.data = 0; + del_timer(&hostdata->explore_timer); + + spin_lock_irqsave(host->host_lock, flags); + + if (hostdata->adapter_state & AS_REDO_FABRIC_PORTDB || hostdata->adapter_state & AS_REDO_LOOP_PORTDB) { + isp2x00_make_portdb(host); + printk("qlogicfc%d : Port Database\n", hostdata->host_id); + for (i = 0; hostdata->port_db[i].wwn != 0; i++) { + printk("wwn: %08x%08x scsi_id: %x loop_id: ", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i); + if (hostdata->port_db[i].loop_id != hostdata->port_db[0].loop_id || i == 0) + printk("%x", hostdata->port_db[i].loop_id); + else + printk("Not Available"); + printk("\n"); + } + + for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++){ + if (hostdata->handle_ptrs[i] && (hostdata->port_db[hostdata->handle_ptrs[i]->device->id].loop_id > QLOGICFC_MAX_LOOP_ID || hostdata->adapter_state & AS_REDO_LOOP_PORTDB)){ + if (hostdata->port_db[hostdata->handle_ptrs[i]->device->id].loop_id != hostdata->port_db[0].loop_id){ + Scsi_Cmnd *Cmnd = hostdata->handle_ptrs[i]; + + if (Cmnd->use_sg) + pci_unmap_sg(hostdata->pci_dev, + (struct scatterlist *)Cmnd->buffer, + Cmnd->use_sg, + Cmnd->sc_data_direction); + else if (Cmnd->request_bufflen && + Cmnd->sc_data_direction != PCI_DMA_NONE) { + pci_unmap_page(hostdata->pci_dev, + Cmnd->SCp.dma_handle, + Cmnd->request_bufflen, + Cmnd->sc_data_direction); + } + + hostdata->handle_ptrs[i]->result = DID_SOFT_ERROR << 16; + + if (hostdata->handle_ptrs[i]->scsi_done){ + (*hostdata->handle_ptrs[i]->scsi_done) (hostdata->handle_ptrs[i]); + } + else printk("qlogicfc%d : done is null?\n", hostdata->host_id); + hostdata->handle_ptrs[i] = NULL; + hostdata->handle_serials[i] = 0; + } + } + } + + hostdata->adapter_state = AS_LOOP_GOOD; + } + + spin_unlock_irqrestore(host->host_lock, flags); + +} + +#define ASYNC_EVENT_INTERRUPT 0x01 + +irqreturn_t do_isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + struct Scsi_Host *host = dev_id; + unsigned long flags; + + spin_lock_irqsave(host->host_lock, flags); + isp2x00_intr_handler(irq, dev_id, regs); + spin_unlock_irqrestore(host->host_lock, flags); + + return IRQ_HANDLED; +} + +void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + Scsi_Cmnd *Cmnd; + struct Status_Entry *sts; + struct Scsi_Host *host = dev_id; + struct isp2x00_hostdata *hostdata; + u_int in_ptr, out_ptr, handle, num_free; + u_short status; + + ENTER_INTR("isp2x00_intr_handler"); + + hostdata = (struct isp2x00_hostdata *) host->hostdata; + + DEBUG_INTR(printk("qlogicfc%d : interrupt on line %d\n", hostdata->host_id, irq)); + + if (!(inw(host->io_port + PCI_INTER_STS) & 0x08)) { + /* spurious interrupts can happen legally */ + DEBUG_INTR(printk("qlogicfc%d : got spurious interrupt\n", hostdata->host_id)); + return; + } + in_ptr = inw(host->io_port + MBOX5); + out_ptr = hostdata->res_out_ptr; + + if ((inw(host->io_port + PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) { + status = inw(host->io_port + MBOX0); + + DEBUG_INTR(printk("qlogicfc%d : mbox completion status: %x\n", + hostdata->host_id, status)); + + switch (status) { + case LOOP_UP: + case POINT_TO_POINT_UP: + printk("qlogicfc%d : Link is Up\n", hostdata->host_id); + hostdata->adapter_state = AS_REDO_FABRIC_PORTDB | AS_REDO_LOOP_PORTDB; + break; + case LOOP_DOWN: + printk("qlogicfc%d : Link is Down\n", hostdata->host_id); + hostdata->adapter_state = AS_LOOP_DOWN; + break; + case CONNECTION_MODE: + printk("received CONNECTION_MODE irq %x\n", inw(host->io_port + MBOX1)); + break; + case CHANGE_NOTIFICATION: + printk("qlogicfc%d : RSCN Received\n", hostdata->host_id); + if (hostdata->adapter_state == AS_LOOP_GOOD) + hostdata->adapter_state = AS_REDO_FABRIC_PORTDB; + break; + case LIP_OCCURRED: + case LIP_RECEIVED: + printk("qlogicfc%d : Loop Reinitialized\n", hostdata->host_id); + if (hostdata->adapter_state == AS_LOOP_GOOD) + hostdata->adapter_state = AS_REDO_LOOP_PORTDB; + break; + case SYSTEM_ERROR: + printk("qlogicfc%d : The firmware just choked.\n", hostdata->host_id); + hostdata->adapter_state = AS_FIRMWARE_DEAD; + break; + case SCSI_COMMAND_COMPLETE: + handle = inw(host->io_port + MBOX1) | (inw(host->io_port + MBOX2) << 16); + Cmnd = hostdata->handle_ptrs[handle]; + hostdata->handle_ptrs[handle] = NULL; + hostdata->handle_serials[handle] = 0; + hostdata->queued--; + if (Cmnd != NULL) { + if (Cmnd->use_sg) + pci_unmap_sg(hostdata->pci_dev, + (struct scatterlist *)Cmnd->buffer, + Cmnd->use_sg, + Cmnd->sc_data_direction); + else if (Cmnd->request_bufflen && + Cmnd->sc_data_direction != PCI_DMA_NONE) + pci_unmap_page(hostdata->pci_dev, + Cmnd->SCp.dma_handle, + Cmnd->request_bufflen, + Cmnd->sc_data_direction); + Cmnd->result = 0x0; + (*Cmnd->scsi_done) (Cmnd); + } else + printk("qlogicfc%d.c : got a null value out of handle_ptrs, this sucks\n", hostdata->host_id); + break; + case MBOX_COMMAND_COMPLETE: + case INVALID_COMMAND: + case HOST_INTERFACE_ERROR: + case TEST_FAILED: + case COMMAND_ERROR: + case COMMAND_PARAM_ERROR: + case PORT_ID_USED: + case LOOP_ID_USED: + case ALL_IDS_USED: + hostdata->mbox_done = 1; + outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR); + return; + default: + printk("qlogicfc%d : got an unknown status? %x\n", hostdata->host_id, status); + } + if ((hostdata->adapter_state & AS_REDO_LOOP_PORTDB || hostdata->adapter_state & AS_REDO_FABRIC_PORTDB) && hostdata->explore_timer.data == 0){ + hostdata->explore_timer.function = redo_port_db; + hostdata->explore_timer.data = (unsigned long)host; + hostdata->explore_timer.expires = jiffies + (HZ/4); + init_timer(&hostdata->explore_timer); + add_timer(&hostdata->explore_timer); + } + outw(0x0, host->io_port + PCI_SEMAPHORE); + } else { + DEBUG_INTR(printk("qlogicfc%d : response queue update\n", hostdata->host_id)); + DEBUG_INTR(printk("qlogicfc%d : response queue depth %d\n", hostdata->host_id, RES_QUEUE_DEPTH(in_ptr, out_ptr))); + + while (out_ptr != in_ptr) { + unsigned le_hand; + sts = (struct Status_Entry *) &hostdata->res[out_ptr*QUEUE_ENTRY_LEN]; + out_ptr = (out_ptr + 1) & RES_QUEUE_LEN; + + TRACE("done", out_ptr, Cmnd); + DEBUG_INTR(isp2x00_print_status_entry(sts)); + le_hand = le32_to_cpu(sts->handle); + if (sts->hdr.entry_type == ENTRY_STATUS && (Cmnd = hostdata->handle_ptrs[le_hand])) { + Cmnd->result = isp2x00_return_status(Cmnd, sts); + hostdata->queued--; + + if (Cmnd->use_sg) + pci_unmap_sg(hostdata->pci_dev, + (struct scatterlist *)Cmnd->buffer, Cmnd->use_sg, + Cmnd->sc_data_direction); + else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE) + pci_unmap_page(hostdata->pci_dev, + Cmnd->SCp.dma_handle, + Cmnd->request_bufflen, + Cmnd->sc_data_direction); + + /* + * if any of the following are true we do not + * call scsi_done. if the status is CS_ABORTED + * we don't have to call done because the upper + * level should already know its aborted. + */ + if (hostdata->handle_serials[le_hand] != Cmnd->serial_number + || le16_to_cpu(sts->completion_status) == CS_ABORTED){ + hostdata->handle_serials[le_hand] = 0; + hostdata->handle_ptrs[le_hand] = NULL; + outw(out_ptr, host->io_port + MBOX5); + continue; + } + /* + * if we get back an error indicating the port + * is not there or if the link is down and + * this is a device that used to be there + * allow the command to timeout. + * the device may well be back in a couple of + * seconds. + */ + if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == cpu_to_le16(CS_PORT_UNAVAILABLE) || sts->completion_status == cpu_to_le16(CS_PORT_LOGGED_OUT) || sts->completion_status == cpu_to_le16(CS_PORT_CONFIG_CHANGED)) && hostdata->port_db[Cmnd->device->id].wwn){ + outw(out_ptr, host->io_port + MBOX5); + continue; + } + } else { + outw(out_ptr, host->io_port + MBOX5); + continue; + } + + hostdata->handle_ptrs[le_hand] = NULL; + + if (sts->completion_status == cpu_to_le16(CS_RESET_OCCURRED) + || (sts->status_flags & cpu_to_le16(STF_BUS_RESET))) + hostdata->send_marker = 1; + + if (le16_to_cpu(sts->scsi_status) & 0x0200) + memcpy(Cmnd->sense_buffer, sts->req_sense_data, + sizeof(Cmnd->sense_buffer)); + + outw(out_ptr, host->io_port + MBOX5); + + if (Cmnd->scsi_done != NULL) { + (*Cmnd->scsi_done) (Cmnd); + } else + printk("qlogicfc%d : Ouch, scsi done is NULL\n", hostdata->host_id); + } + hostdata->res_out_ptr = out_ptr; + } + + + out_ptr = inw(host->io_port + MBOX4); + in_ptr = hostdata->req_in_ptr; + + num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr); + num_free = (num_free > 2) ? num_free - 2 : 0; + host->can_queue = host->host_busy + num_free; + if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN) + host->can_queue = QLOGICFC_REQ_QUEUE_LEN; + host->sg_tablesize = QLOGICFC_MAX_SG(num_free); + + outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR); + LEAVE_INTR("isp2x00_intr_handler"); +} + + +static int isp2x00_return_status(Scsi_Cmnd *Cmnd, struct Status_Entry *sts) +{ + int host_status = DID_ERROR; +#if DEBUG_ISP2x00_INTR + static char *reason[] = + { + "DID_OK", + "DID_NO_CONNECT", + "DID_BUS_BUSY", + "DID_TIME_OUT", + "DID_BAD_TARGET", + "DID_ABORT", + "DID_PARITY", + "DID_ERROR", + "DID_RESET", + "DID_BAD_INTR" + }; +#endif /* DEBUG_ISP2x00_INTR */ + + ENTER("isp2x00_return_status"); + + DEBUG(printk("qlogicfc : completion status = 0x%04x\n", + le16_to_cpu(sts->completion_status))); + + switch (le16_to_cpu(sts->completion_status)) { + case CS_COMPLETE: + host_status = DID_OK; + break; + case CS_DMA_ERROR: + host_status = DID_ERROR; + break; + case CS_RESET_OCCURRED: + host_status = DID_RESET; + break; + case CS_ABORTED: + host_status = DID_ABORT; + break; + case CS_TIMEOUT: + host_status = DID_TIME_OUT; + break; + case CS_DATA_OVERRUN: + host_status = DID_ERROR; + break; + case CS_DATA_UNDERRUN: + if (Cmnd->underflow <= (Cmnd->request_bufflen - le32_to_cpu(sts->residual))) + host_status = DID_OK; + else + host_status = DID_ERROR; + break; + case CS_PORT_UNAVAILABLE: + case CS_PORT_LOGGED_OUT: + case CS_PORT_CONFIG_CHANGED: + host_status = DID_BAD_TARGET; + break; + case CS_QUEUE_FULL: + host_status = DID_ERROR; + break; + default: + printk("qlogicfc : unknown completion status 0x%04x\n", + le16_to_cpu(sts->completion_status)); + host_status = DID_ERROR; + break; + } + + DEBUG_INTR(printk("qlogicfc : host status (%s) scsi status %x\n", + reason[host_status], le16_to_cpu(sts->scsi_status))); + + LEAVE("isp2x00_return_status"); + + return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16); +} + + +static int isp2x00_abort(Scsi_Cmnd * Cmnd) +{ + u_short param[8]; + int i; + struct Scsi_Host *host; + struct isp2x00_hostdata *hostdata; + int return_status = SUCCESS; + + ENTER("isp2x00_abort"); + + host = Cmnd->device->host; + hostdata = (struct isp2x00_hostdata *) host->hostdata; + + for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++) + if (hostdata->handle_ptrs[i] == Cmnd) + break; + + if (i == QLOGICFC_REQ_QUEUE_LEN){ + return SUCCESS; + } + + isp2x00_disable_irqs(host); + + param[0] = MBOX_ABORT_IOCB; +#if ISP2x00_PORTDB + param[1] = (((u_short) hostdata->port_db[Cmnd->device->id].loop_id) << 8) | Cmnd->device->lun; +#else + param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun; +#endif + param[2] = i & 0xffff; + param[3] = i >> 16; + + isp2x00_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc%d : scsi abort failure: %x\n", hostdata->host_id, param[0]); + if (param[0] == 0x4005) + Cmnd->result = DID_ERROR << 16; + if (param[0] == 0x4006) + Cmnd->result = DID_BAD_TARGET << 16; + return_status = FAILED; + } + + if (return_status != SUCCESS){ + param[0] = MBOX_GET_FIRMWARE_STATE; + isp2x00_mbox_command(host, param); + printk("qlogicfc%d : abort failed\n", hostdata->host_id); + printk("qlogicfc%d : firmware status is %x %x\n", hostdata->host_id, param[0], param[1]); + } + + isp2x00_enable_irqs(host); + + LEAVE("isp2x00_abort"); + + return return_status; +} + + +static int isp2x00_biosparam(struct scsi_device *sdev, struct block_device *n, + sector_t capacity, int ip[]) +{ + int size = capacity; + + ENTER("isp2x00_biosparam"); + + ip[0] = 64; + ip[1] = 32; + ip[2] = size >> 11; + if (ip[2] > 1024) { + ip[0] = 255; + ip[1] = 63; + ip[2] = size / (ip[0] * ip[1]); + } + LEAVE("isp2x00_biosparam"); + + return 0; +} + +static int isp2x00_reset_hardware(struct Scsi_Host *host) +{ + u_short param[8]; + struct isp2x00_hostdata *hostdata; + int loop_count; + dma_addr_t busaddr; + + ENTER("isp2x00_reset_hardware"); + + hostdata = (struct isp2x00_hostdata *) host->hostdata; + + /* + * This cannot be right - PCI writes are posted + * (apparently this is hardware design flaw not software ?) + */ + + outw(0x01, host->io_port + ISP_CTRL_STATUS); + udelay(100); + outw(HCCR_RESET, host->io_port + HOST_HCCR); + udelay(100); + outw(HCCR_RELEASE, host->io_port + HOST_HCCR); + outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR); + + loop_count = DEFAULT_LOOP_COUNT; + while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY) { + barrier(); + cpu_relax(); + } + if (!loop_count) + printk("qlogicfc%d : reset_hardware loop timeout\n", hostdata->host_id); + + + +#if DEBUG_ISP2x00 + printk("qlogicfc%d : mbox 0 0x%04x \n", hostdata->host_id, inw(host->io_port + MBOX0)); + printk("qlogicfc%d : mbox 1 0x%04x \n", hostdata->host_id, inw(host->io_port + MBOX1)); + printk("qlogicfc%d : mbox 2 0x%04x \n", hostdata->host_id, inw(host->io_port + MBOX2)); + printk("qlogicfc%d : mbox 3 0x%04x \n", hostdata->host_id, inw(host->io_port + MBOX3)); + printk("qlogicfc%d : mbox 4 0x%04x \n", hostdata->host_id, inw(host->io_port + MBOX4)); + printk("qlogicfc%d : mbox 5 0x%04x \n", hostdata->host_id, inw(host->io_port + MBOX5)); + printk("qlogicfc%d : mbox 6 0x%04x \n", hostdata->host_id, inw(host->io_port + MBOX6)); + printk("qlogicfc%d : mbox 7 0x%04x \n", hostdata->host_id, inw(host->io_port + MBOX7)); +#endif /* DEBUG_ISP2x00 */ + + DEBUG(printk("qlogicfc%d : verifying checksum\n", hostdata->host_id)); + +#if defined(CONFIG_SCSI_QLOGIC_FC_FIRMWARE) + { + int i; + unsigned short * risc_code = NULL; + unsigned short risc_code_len = 0; + if (hostdata->pci_dev->device == PCI_DEVICE_ID_QLOGIC_ISP2100){ + risc_code = risc_code2100; + risc_code_len = risc_code_length2100; + } + else if (hostdata->pci_dev->device == PCI_DEVICE_ID_QLOGIC_ISP2200){ + risc_code = risc_code2200; + risc_code_len = risc_code_length2200; + } + + for (i = 0; i < risc_code_len; i++) { + param[0] = MBOX_WRITE_RAM_WORD; + param[1] = risc_code_addr01 + i; + param[2] = risc_code[i]; + + isp2x00_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc%d : firmware load failure\n", hostdata->host_id); + return 1; + } + } + } +#endif /* RELOAD_FIRMWARE */ + + param[0] = MBOX_VERIFY_CHECKSUM; + param[1] = risc_code_addr01; + + isp2x00_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc%d : ram checksum failure\n", hostdata->host_id); + return 1; + } + DEBUG(printk("qlogicfc%d : executing firmware\n", hostdata->host_id)); + + param[0] = MBOX_EXEC_FIRMWARE; + param[1] = risc_code_addr01; + + isp2x00_mbox_command(host, param); + + param[0] = MBOX_ABOUT_FIRMWARE; + + isp2x00_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc%d : about firmware failure\n", hostdata->host_id); + return 1; + } + DEBUG(printk("qlogicfc%d : firmware major revision %d\n", hostdata->host_id, param[1])); + DEBUG(printk("qlogicfc%d : firmware minor revision %d\n", hostdata->host_id, param[2])); + +#ifdef USE_NVRAM_DEFAULTS + + if (isp2x00_get_nvram_defaults(host, &hostdata->control_block) != 0) { + printk("qlogicfc%d : Could not read from NVRAM\n", hostdata->host_id); + } +#endif + + hostdata->wwn = (u64) (cpu_to_le16(hostdata->control_block.node_name[0])) << 56; + hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[0]) & 0xff00) << 48; + hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[1]) & 0xff00) << 24; + hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[1]) & 0x00ff) << 48; + hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[2]) & 0x00ff) << 24; + hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[2]) & 0xff00) << 8; + hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[3]) & 0x00ff) << 8; + hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[3]) & 0xff00) >> 8; + + /* FIXME: If the DMA transfer goes one way only, this should use + * PCI_DMA_TODEVICE and below as well. + */ + busaddr = pci_map_page(hostdata->pci_dev, + virt_to_page(&hostdata->control_block), + offset_in_page(&hostdata->control_block), + sizeof(hostdata->control_block), + PCI_DMA_BIDIRECTIONAL); + + param[0] = MBOX_INIT_FIRMWARE; + param[2] = (u_short) (pci64_dma_lo32(busaddr) >> 16); + param[3] = (u_short) (pci64_dma_lo32(busaddr) & 0xffff); + param[4] = 0; + param[5] = 0; + param[6] = (u_short) (pci64_dma_hi32(busaddr) >> 16); + param[7] = (u_short) (pci64_dma_hi32(busaddr) & 0xffff); + isp2x00_mbox_command(host, param); + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc%d.c: Ouch 0x%04x\n", hostdata->host_id, param[0]); + pci_unmap_page(hostdata->pci_dev, busaddr, + sizeof(hostdata->control_block), + PCI_DMA_BIDIRECTIONAL); + return 1; + } + param[0] = MBOX_GET_FIRMWARE_STATE; + isp2x00_mbox_command(host, param); + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc%d.c: 0x%04x\n", hostdata->host_id, param[0]); + pci_unmap_page(hostdata->pci_dev, busaddr, + sizeof(hostdata->control_block), + PCI_DMA_BIDIRECTIONAL); + return 1; + } + + pci_unmap_page(hostdata->pci_dev, busaddr, + sizeof(hostdata->control_block), + PCI_DMA_BIDIRECTIONAL); + LEAVE("isp2x00_reset_hardware"); + + return 0; +} + +#ifdef USE_NVRAM_DEFAULTS + +static int isp2x00_get_nvram_defaults(struct Scsi_Host *host, struct init_cb *control_block) +{ + + u_short value; + if (isp2x00_read_nvram_word(host, 0) != 0x5349) + return 1; + + value = isp2x00_read_nvram_word(host, 8); + control_block->node_name[0] = cpu_to_le16(isp2x00_read_nvram_word(host, 9)); + control_block->node_name[1] = cpu_to_le16(isp2x00_read_nvram_word(host, 10)); + control_block->node_name[2] = cpu_to_le16(isp2x00_read_nvram_word(host, 11)); + control_block->node_name[3] = cpu_to_le16(isp2x00_read_nvram_word(host, 12)); + control_block->hard_addr = cpu_to_le16(isp2x00_read_nvram_word(host, 13)); + + return 0; + +} + +#endif + +static int isp2x00_init(struct Scsi_Host *sh) +{ + u_long io_base; + struct isp2x00_hostdata *hostdata; + u_char revision; + u_int irq; + u_short command; + struct pci_dev *pdev; + + + ENTER("isp2x00_init"); + + hostdata = (struct isp2x00_hostdata *) sh->hostdata; + pdev = hostdata->pci_dev; + + if (pci_read_config_word(pdev, PCI_COMMAND, &command) + || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) { + printk("qlogicfc%d : error reading PCI configuration\n", hostdata->host_id); + return 1; + } + io_base = pci_resource_start(pdev, 0); + irq = pdev->irq; + + + if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) { + printk("qlogicfc%d : 0x%04x is not QLogic vendor ID\n", hostdata->host_id, + pdev->vendor); + return 1; + } + if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2100 && pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2200) { + printk("qlogicfc%d : 0x%04x does not match ISP2100 or ISP2200 device id\n", hostdata->host_id, + pdev->device); + return 1; + } + if (!(command & PCI_COMMAND_IO) || + !(pdev->resource[0].flags & IORESOURCE_IO)) { + printk("qlogicfc%d : i/o mapping is disabled\n", hostdata->host_id); + return 1; + } + + pci_set_master(pdev); + if (revision != ISP2100_REV_ID1 && revision != ISP2100_REV_ID3 && revision != ISP2200_REV_ID5) + printk("qlogicfc%d : new isp2x00 revision ID (%d)\n", hostdata->host_id, revision); + + + hostdata->revision = revision; + + sh->irq = irq; + sh->io_port = io_base; + + LEAVE("isp2x00_init"); + + return 0; +} + +#if USE_NVRAM_DEFAULTS + +#define NVRAM_DELAY() udelay(10) /* 10 microsecond delay */ + + +u_short isp2x00_read_nvram_word(struct Scsi_Host * host, u_short byte) +{ + int i; + u_short value, output, input; + + outw(0x2, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + outw(0x3, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + + byte &= 0xff; + byte |= 0x0600; + for (i = 10; i >= 0; i--) { + output = ((byte >> i) & 0x1) ? 0x4 : 0x0; + outw(output | 0x2, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + outw(output | 0x3, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + outw(output | 0x2, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + } + + for (i = 0xf, value = 0; i >= 0; i--) { + value <<= 1; + outw(0x3, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + input = inw(host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + outw(0x2, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + if (input & 0x8) + value |= 1; + } + + outw(0x0, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + + return value; +} + + +#endif /* USE_NVRAM_DEFAULTS */ + + + +/* + * currently, this is only called during initialization or abort/reset, + * at which times interrupts are disabled, so polling is OK, I guess... + */ +static int isp2x00_mbox_command(struct Scsi_Host *host, u_short param[]) +{ + int loop_count; + struct isp2x00_hostdata *hostdata = (struct isp2x00_hostdata *) host->hostdata; + + if (mbox_param[param[0]] == 0 || hostdata->adapter_state == AS_FIRMWARE_DEAD) + return 1; + + loop_count = DEFAULT_LOOP_COUNT; + while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080) { + barrier(); + cpu_relax(); + } + if (!loop_count) { + printk("qlogicfc%d : mbox_command loop timeout #1\n", hostdata->host_id); + param[0] = 0x4006; + hostdata->adapter_state = AS_FIRMWARE_DEAD; + return 1; + } + hostdata->mbox_done = 0; + + if (mbox_param[param[0]] == 0) + printk("qlogicfc%d : invalid mbox command\n", hostdata->host_id); + + if (mbox_param[param[0]] & 0x80) + outw(param[7], host->io_port + MBOX7); + if (mbox_param[param[0]] & 0x40) + outw(param[6], host->io_port + MBOX6); + if (mbox_param[param[0]] & 0x20) + outw(param[5], host->io_port + MBOX5); + if (mbox_param[param[0]] & 0x10) + outw(param[4], host->io_port + MBOX4); + if (mbox_param[param[0]] & 0x08) + outw(param[3], host->io_port + MBOX3); + if (mbox_param[param[0]] & 0x04) + outw(param[2], host->io_port + MBOX2); + if (mbox_param[param[0]] & 0x02) + outw(param[1], host->io_port + MBOX1); + if (mbox_param[param[0]] & 0x01) + outw(param[0], host->io_port + MBOX0); + + + outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR); + + while (1) { + loop_count = DEFAULT_LOOP_COUNT; + while (--loop_count && !(inw(host->io_port + PCI_INTER_STS) & 0x08)) { + barrier(); + cpu_relax(); + } + + if (!loop_count) { + hostdata->adapter_state = AS_FIRMWARE_DEAD; + printk("qlogicfc%d : mbox_command loop timeout #2\n", hostdata->host_id); + break; + } + isp2x00_intr_handler(host->irq, host, NULL); + + if (hostdata->mbox_done == 1) + break; + + } + + loop_count = DEFAULT_LOOP_COUNT; + while (--loop_count && inw(host->io_port + MBOX0) == 0x04) { + barrier(); + cpu_relax(); + } + if (!loop_count) + printk("qlogicfc%d : mbox_command loop timeout #3\n", hostdata->host_id); + + param[7] = inw(host->io_port + MBOX7); + param[6] = inw(host->io_port + MBOX6); + param[5] = inw(host->io_port + MBOX5); + param[4] = inw(host->io_port + MBOX4); + param[3] = inw(host->io_port + MBOX3); + param[2] = inw(host->io_port + MBOX2); + param[1] = inw(host->io_port + MBOX1); + param[0] = inw(host->io_port + MBOX0); + + + outw(0x0, host->io_port + PCI_SEMAPHORE); + + if (inw(host->io_port + HOST_HCCR) & 0x0080) { + hostdata->adapter_state = AS_FIRMWARE_DEAD; + printk("qlogicfc%d : mbox op is still pending\n", hostdata->host_id); + } + return 0; +} + +#if DEBUG_ISP2x00_INTR + +void isp2x00_print_status_entry(struct Status_Entry *status) +{ + printk("qlogicfc : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n", + status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags); + printk("qlogicfc : scsi status = 0x%04x, completion status = 0x%04x\n", + le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status)); + printk("qlogicfc : state flags = 0x%04x, status flags = 0x%04x\n", + le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags)); + printk("qlogicfc : response info length = 0x%04x, request sense length = 0x%04x\n", + le16_to_cpu(status->res_info_len), le16_to_cpu(status->req_sense_len)); + printk("qlogicfc : residual transfer length = 0x%08x, response = 0x%02x\n", le32_to_cpu(status->residual), status->res_info[3]); + +} + +#endif /* DEBUG_ISP2x00_INTR */ + + +#if DEBUG_ISP2x00 + +void isp2x00_print_scsi_cmd(Scsi_Cmnd * cmd) +{ + int i; + + printk("qlogicfc : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", + cmd->target, cmd->lun, cmd->cmd_len); + printk("qlogicfc : command = "); + for (i = 0; i < cmd->cmd_len; i++) + printk("0x%02x ", cmd->cmnd[i]); + printk("\n"); +} + +#endif /* DEBUG_ISP2x00 */ + +MODULE_LICENSE("GPL"); + +static struct scsi_host_template driver_template = { + .detect = isp2x00_detect, + .release = isp2x00_release, + .info = isp2x00_info, + .queuecommand = isp2x00_queuecommand, + .eh_abort_handler = isp2x00_abort, + .bios_param = isp2x00_biosparam, + .can_queue = QLOGICFC_REQ_QUEUE_LEN, + .this_id = -1, + .sg_tablesize = QLOGICFC_MAX_SG(QLOGICFC_REQ_QUEUE_LEN), + .cmd_per_lun = QLOGICFC_CMD_PER_LUN, + .use_clustering = ENABLE_CLUSTERING, +}; +#include "scsi_module.c" diff --git a/drivers/scsi/qlogicfc_asm.c b/drivers/scsi/qlogicfc_asm.c new file mode 100644 index 000000000..b1d45102d --- /dev/null +++ b/drivers/scsi/qlogicfc_asm.c @@ -0,0 +1,9751 @@ +/************************************************************************ + * * + * --- ISP2100 Fabric Initiator/Target Firmware --- * + * with expanded LUN addressing * + * and FcTape (FCP-2) support * + * * + * * + ************************************************************************ + Copyright (C) 2000 and 2001 Qlogic Corporation + (www.qlogic.com) + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. +************************************************************************/ + +/* + * Firmware Version 1.19.16 (10:36 Nov 02, 2000) + */ + +static unsigned short risc_code_addr01 = 0x1000 ; + +static unsigned short risc_code_length2100 = 0x9260; +static unsigned short risc_code2100[] = { + 0x0078, 0x102d, 0x0000, 0x9260, 0x0000, 0x0001, 0x0013, 0x0010, + 0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, + 0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, + 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972, + 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, + 0x312e, 0x3139, 0x2020, 0x2020, 0x2400, 0x2091, 0x2000, 0x20c1, + 0x0021, 0x2039, 0xffff, 0x2019, 0xaaaa, 0x2760, 0x2069, 0x7fff, + 0x20c1, 0x0020, 0x2c2c, 0x2d34, 0x2762, 0x236a, 0x2c24, 0x2d04, + 0x266a, 0x2562, 0xa406, 0x00c0, 0x1052, 0x20c1, 0x0021, 0x2c2c, + 0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020, + 0x2039, 0x8fff, 0x20a1, 0xaa00, 0x2708, 0x810d, 0x810d, 0x810d, + 0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8, + 0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102, + 0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1, + 0xa260, 0x2009, 0x0000, 0x20a9, 0x07a0, 0x41a4, 0x3400, 0x20c9, + 0xa7ff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x255d, + 0x2051, 0xa300, 0x2a70, 0x775e, 0xa786, 0x8fff, 0x0040, 0x1092, + 0x705b, 0xca00, 0x7057, 0xc9f1, 0x7063, 0x0200, 0x7067, 0x0200, + 0x0078, 0x109a, 0x7057, 0xba01, 0x7063, 0x0100, 0x7067, 0x0100, + 0x705b, 0xba00, 0x1078, 0x12df, 0x1078, 0x13c0, 0x1078, 0x1569, + 0x1078, 0x1ca4, 0x1078, 0x4229, 0x1078, 0x74cf, 0x1078, 0x134b, + 0x1078, 0x2a3f, 0x1078, 0x4da2, 0x1078, 0x48b2, 0x1078, 0x57df, + 0x1078, 0x21f7, 0x1078, 0x5abf, 0x1078, 0x5369, 0x1078, 0x210d, + 0x1078, 0x21d4, 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x10cf, + 0x7820, 0xa086, 0x0002, 0x00c0, 0x10cf, 0x7823, 0x4000, 0x0068, + 0x10c7, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, + 0x7003, 0x0000, 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000, + 0xa08e, 0x0003, 0x00c0, 0x10ef, 0x1078, 0x35bc, 0x1078, 0x2a67, + 0x1078, 0x4df2, 0x1078, 0x4a75, 0x2009, 0x0100, 0x2104, 0xa082, + 0x0002, 0x0048, 0x10f3, 0x1078, 0x57fb, 0x0078, 0x10d6, 0x1079, + 0x10f7, 0x0078, 0x10dc, 0x1078, 0x6fa9, 0x0078, 0x10eb, 0x1101, + 0x1102, 0x11be, 0x10ff, 0x1246, 0x12dc, 0x12dd, 0x12de, 0x1078, + 0x1328, 0x007c, 0x127e, 0x0f7e, 0x2091, 0x8000, 0x7000, 0xa086, + 0x0001, 0x00c0, 0x1198, 0x1078, 0x3a43, 0x2079, 0x0100, 0x7844, + 0xa005, 0x00c0, 0x1198, 0x2011, 0x4129, 0x1078, 0x58d4, 0x1078, + 0x1ab1, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, + 0x8010, 0x73c0, 0x1078, 0x3579, 0x2001, 0xffff, 0x1078, 0x5975, + 0x7238, 0xc284, 0x723a, 0x2001, 0xa30c, 0x2014, 0xc2ac, 0x2202, + 0x1078, 0x6db5, 0x2011, 0x0004, 0x1078, 0x8a59, 0x1078, 0x47ce, + 0x1078, 0x4211, 0x0040, 0x1144, 0x7083, 0x0001, 0x70bb, 0x0000, + 0x1078, 0x3bf5, 0x0078, 0x1198, 0x1078, 0x4897, 0x0040, 0x114d, + 0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x8ddf, 0x70c8, + 0xd09c, 0x00c0, 0x1159, 0x7094, 0xa005, 0x0040, 0x1159, 0x1078, + 0x41f5, 0x70d3, 0x0000, 0x70cf, 0x0000, 0x72c8, 0x2079, 0xa351, + 0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ca, 0xa296, 0x0004, + 0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8a59, 0x708f, 0x0000, + 0x7093, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x260d, 0x2011, + 0x0005, 0x1078, 0x6ef2, 0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100, + 0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x708f, 0x0000, + 0x7093, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, 0x1078, 0x6ef2, + 0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, + 0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e, + 0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078, + 0x71e0, 0x027f, 0x1078, 0xa190, 0x037f, 0x027f, 0x017f, 0x1078, + 0x2921, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706b, 0x0000, 0x706c, + 0xa084, 0x00ff, 0x706e, 0x7097, 0x0000, 0x007c, 0x127e, 0x2091, + 0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7090, 0xa086, + 0xffff, 0x0040, 0x11d1, 0x1078, 0x260d, 0x1078, 0x6109, 0x0078, + 0x1244, 0x70c8, 0xd09c, 0x0040, 0x11fd, 0xd084, 0x0040, 0x11fd, + 0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c, + 0x0040, 0x11fd, 0x70cc, 0xa086, 0xffff, 0x0040, 0x11f9, 0x1078, + 0x278a, 0x1078, 0x6109, 0x70c8, 0xd094, 0x00c0, 0x1244, 0x2011, + 0x0001, 0x2019, 0x0000, 0x1078, 0x27c2, 0x1078, 0x6109, 0x0078, + 0x1244, 0x70d0, 0xa005, 0x00c0, 0x1244, 0x708c, 0xa005, 0x00c0, + 0x1244, 0x1078, 0x4897, 0x00c0, 0x1244, 0x2001, 0xa352, 0x2004, + 0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009, + 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x121a, 0x6000, 0xd0ec, + 0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f, + 0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003, + 0x0003, 0x7093, 0xffff, 0x2001, 0x0000, 0x1078, 0x2480, 0x1078, + 0x35f7, 0x2001, 0xa5ac, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c, + 0x2011, 0x0000, 0x1078, 0x6ef2, 0x2011, 0x0000, 0x1078, 0x6efc, + 0x1078, 0x6109, 0x1078, 0x61d3, 0x127f, 0x007c, 0x017e, 0x0f7e, + 0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078, + 0x41de, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0040, + 0x125b, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1260, 0x7827, 0x0008, + 0x007e, 0x037e, 0x157e, 0xa006, 0x1078, 0x5975, 0x7900, 0xa18a, + 0x0003, 0x0050, 0x1289, 0x7954, 0xd1ac, 0x00c0, 0x1289, 0x2009, + 0x00f8, 0x1078, 0x41de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, + 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x1281, 0x7824, 0xd0ac, 0x00c0, + 0x12ca, 0x00f0, 0x1279, 0x2001, 0x0001, 0x1078, 0x2480, 0x0078, + 0x12d5, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0, + 0x128f, 0x2091, 0x6000, 0x00f0, 0x128f, 0x7853, 0x0400, 0x782f, + 0x0000, 0x2009, 0x00f8, 0x1078, 0x41de, 0x20a9, 0x000e, 0x0005, + 0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010, + 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4, + 0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009, + 0xa331, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4, + 0x200b, 0x0000, 0x1078, 0x251e, 0x2001, 0x0001, 0x1078, 0x2480, + 0x0078, 0x12d3, 0x2001, 0xa331, 0x2003, 0x0000, 0x7828, 0xc09d, + 0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f, + 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70, + 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x12eb, 0x704f, + 0xffff, 0x0078, 0x12ed, 0x704f, 0x0000, 0x7053, 0xffff, 0x706b, + 0x0000, 0x706f, 0x0000, 0x1078, 0x8ddf, 0x2061, 0xa58c, 0x6003, + 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, + 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061, + 0xa594, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f, + 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f, + 0x0000, 0x2061, 0xa5a3, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, + 0x4943, 0x600f, 0x2020, 0x2001, 0xa325, 0x2003, 0x0000, 0x007c, + 0x2091, 0x8000, 0x0068, 0x132a, 0x007e, 0x017e, 0x2079, 0x0000, + 0x7818, 0xd084, 0x00c0, 0x1330, 0x017f, 0x792e, 0x007f, 0x782a, + 0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, + 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa300, 0x7803, 0x0005, + 0x0078, 0x1348, 0x007c, 0x2071, 0xa300, 0x7158, 0x712e, 0x2021, + 0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048, 0x1361, 0x705c, + 0xa302, 0x00c8, 0x1361, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078, + 0x1353, 0x200b, 0x0000, 0x74a6, 0x74aa, 0x007c, 0x0e7e, 0x127e, + 0x2091, 0x8000, 0x2071, 0xa300, 0x70a8, 0xa0ea, 0x0010, 0x00c8, + 0x1374, 0xa06e, 0x0078, 0x137e, 0x8001, 0x70aa, 0x702c, 0x2068, + 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, + 0x007c, 0x0e7e, 0x2071, 0xa300, 0x127e, 0x2091, 0x8000, 0x70a8, + 0x8001, 0x00c8, 0x138e, 0xa06e, 0x0078, 0x1397, 0x70aa, 0x702c, + 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, + 0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa300, + 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa, 0x127f, + 0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13b6, 0x6804, 0x6807, 0x0000, + 0x007e, 0x1078, 0x139a, 0x0d7f, 0x0078, 0x13aa, 0x007c, 0x0e7e, + 0x2071, 0xa300, 0x70a8, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c, + 0x0e7e, 0x2071, 0xa5d0, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, + 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f, + 0x007c, 0x0e7e, 0x2270, 0x700b, 0x0000, 0x2071, 0xa5d0, 0x7018, + 0xa088, 0xa5d9, 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, + 0xa005, 0x00c0, 0x13e9, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa, + 0x0f7f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa5d0, 0x7004, 0xa005, + 0x00c0, 0x13f8, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa, 0x0f7f, + 0x0e7f, 0x007c, 0x7000, 0x0079, 0x13fd, 0x1401, 0x146b, 0x1488, + 0x1488, 0x7018, 0x711c, 0xa106, 0x00c0, 0x1409, 0x7007, 0x0000, + 0x007c, 0x0d7e, 0xa180, 0xa5d9, 0x2004, 0x700a, 0x2068, 0x8108, + 0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, + 0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, + 0x7016, 0x6804, 0x0d7f, 0xd084, 0x0040, 0x142b, 0x7007, 0x0001, + 0x1078, 0x1430, 0x007c, 0x7007, 0x0002, 0x1078, 0x1446, 0x007c, + 0x017e, 0x027e, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, + 0x143b, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, + 0x0020, 0x7803, 0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e, + 0x137e, 0x147e, 0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, + 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x145a, + 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, + 0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f, + 0x027f, 0x017f, 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa3f9, + 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, + 0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, + 0x7002, 0x700b, 0xa3f4, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, + 0x137e, 0x147e, 0x157e, 0x2001, 0xa428, 0x209c, 0x20a1, 0x0014, + 0x7803, 0x0026, 0x2001, 0xa429, 0x20ac, 0x53a6, 0x2099, 0xa42a, + 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, + 0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, + 0x7002, 0x700b, 0xa425, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, + 0x017e, 0x0e7e, 0x2071, 0xa5d0, 0x0f7e, 0x2079, 0x0010, 0x7904, + 0x7803, 0x0002, 0xd1fc, 0x0040, 0x14c2, 0xa18c, 0x0700, 0x7004, + 0x1079, 0x14c6, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x13fa, 0x14ce, + 0x14fb, 0x1523, 0x1556, 0x14cc, 0x0078, 0x14cc, 0xa18c, 0x0700, + 0x00c0, 0x14f4, 0x137e, 0x147e, 0x157e, 0x7014, 0x20a0, 0x2099, + 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016, + 0x157f, 0x147f, 0x137f, 0x700c, 0xa005, 0x0040, 0x1510, 0x1078, + 0x1430, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, + 0x0000, 0x1078, 0x13fa, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, + 0x0200, 0x0078, 0x14ef, 0xa18c, 0x0700, 0x00c0, 0x1506, 0x700c, + 0xa005, 0x0040, 0x1510, 0x1078, 0x1446, 0x007c, 0x7008, 0xa080, + 0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x1078, 0x13fa, 0x007c, + 0x0d7e, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, + 0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, + 0x1078, 0x13fa, 0x007c, 0xa18c, 0x0700, 0x00c0, 0x1550, 0x137e, + 0x147e, 0x157e, 0x2001, 0xa3f7, 0x2004, 0xa080, 0x000d, 0x20a0, + 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, + 0xa3f9, 0x2004, 0xd0bc, 0x0040, 0x1546, 0x2001, 0xa402, 0x2004, + 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f, + 0x137f, 0x7007, 0x0000, 0x1078, 0x4e9b, 0x1078, 0x13fa, 0x007c, + 0x2011, 0x8003, 0x1078, 0x3579, 0x0078, 0x1554, 0xa18c, 0x0700, + 0x00c0, 0x1563, 0x2001, 0xa427, 0x2003, 0x0100, 0x7007, 0x0000, + 0x1078, 0x13fa, 0x007c, 0x2011, 0x8004, 0x1078, 0x3579, 0x0078, + 0x1567, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa5e1, + 0x7803, 0x0004, 0x7003, 0x0000, 0x700f, 0xa5e7, 0x7013, 0xa5e7, + 0x780f, 0x0076, 0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184, + 0x0007, 0x0079, 0x1583, 0x158b, 0x15d1, 0x158b, 0x158b, 0x158b, + 0x15b6, 0x159a, 0x158f, 0xa085, 0x0001, 0x0078, 0x15eb, 0x684c, + 0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, + 0x0078, 0x15d9, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x158b, + 0x684c, 0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a, + 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, + 0x2015, 0x2004, 0x6832, 0x6858, 0x0078, 0x15e1, 0xa18c, 0x00ff, + 0xa186, 0x0015, 0x00c0, 0x158b, 0x684c, 0xd0ac, 0x0040, 0x158b, + 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, + 0x2015, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078, + 0x15e1, 0x684c, 0xd0ac, 0x0040, 0x158b, 0xa006, 0x682e, 0x682a, + 0x6858, 0xa18c, 0x000f, 0xa188, 0x2015, 0x210c, 0x6932, 0x2d08, + 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, + 0x6912, 0x6980, 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000, + 0x2001, 0x020a, 0x2004, 0x82ff, 0x0040, 0x160e, 0xa280, 0x0004, + 0x0d7e, 0x206c, 0x684c, 0xd0dc, 0x00c0, 0x160a, 0x1078, 0x157e, + 0x0040, 0x160a, 0x0d7f, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016, + 0x0078, 0x160e, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, + 0x037e, 0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, + 0xa005, 0x00c0, 0x1622, 0x7206, 0x2001, 0x1643, 0x007e, 0x2260, + 0x0078, 0x17be, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, + 0x8108, 0xa182, 0xa602, 0x0048, 0x162f, 0x2009, 0xa5e7, 0x710e, + 0x7010, 0xa102, 0xa082, 0x0009, 0x0040, 0x163a, 0xa080, 0x001b, + 0x00c0, 0x163d, 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0, + 0x1643, 0x1078, 0x179f, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e, + 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f, + 0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005, + 0x0040, 0x16cf, 0x6808, 0xa005, 0x0040, 0x173c, 0x7000, 0xa005, + 0x00c0, 0x1664, 0x0078, 0x16c4, 0x700c, 0x7110, 0xa106, 0x00c0, + 0x1745, 0x7004, 0xa406, 0x00c0, 0x16c4, 0x2001, 0x0005, 0x2004, + 0xd08c, 0x0040, 0x1681, 0x047e, 0x1078, 0x18e2, 0x047f, 0x2460, + 0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x0040, 0x173c, 0x0078, + 0x165e, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x166d, 0x7804, + 0xa084, 0x6000, 0x0040, 0x1692, 0xa086, 0x6000, 0x0040, 0x1692, + 0x0078, 0x166d, 0x7100, 0xa186, 0x0002, 0x00c0, 0x16b2, 0x0e7e, + 0x2b68, 0x6818, 0x2060, 0x1078, 0x1fea, 0x2804, 0xac70, 0x6034, + 0xd09c, 0x00c0, 0x16a7, 0x7108, 0x720c, 0x0078, 0x16a9, 0x7110, + 0x7214, 0x6810, 0xa100, 0x6812, 0x6814, 0xa201, 0x6816, 0x0e7f, + 0x0078, 0x16b6, 0xa186, 0x0001, 0x00c0, 0x16be, 0x7820, 0x6910, + 0xa100, 0x6812, 0x7824, 0x6914, 0xa101, 0x6816, 0x7803, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0, + 0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0078, 0x1745, 0x6808, + 0xa005, 0x0040, 0x173c, 0x7000, 0xa005, 0x00c0, 0x16d9, 0x0078, + 0x173c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x16e2, 0x7004, 0xa406, + 0x00c0, 0x173c, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, 0x16f6, + 0x047e, 0x1078, 0x18e2, 0x047f, 0x2460, 0x6010, 0xa080, 0x0002, + 0x2004, 0xa005, 0x0040, 0x173c, 0x0078, 0x16d3, 0x2001, 0x0207, + 0x2004, 0xd09c, 0x00c0, 0x16e2, 0x2001, 0x0005, 0x2004, 0xd08c, + 0x00c0, 0x16e8, 0x7804, 0xa084, 0x6000, 0x0040, 0x170d, 0xa086, + 0x6000, 0x0040, 0x170d, 0x0078, 0x16e2, 0x7007, 0x0000, 0xa016, + 0x2218, 0x7000, 0xa08e, 0x0001, 0x0040, 0x172e, 0xa08e, 0x0002, + 0x00c0, 0x173c, 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x1fea, + 0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, 0x172a, 0x7308, 0x720c, + 0x0078, 0x172c, 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318, + 0x7824, 0xa211, 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816, + 0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0, + 0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0c7f, 0x0d7f, 0x127f, + 0x007c, 0x0f7e, 0x0e7e, 0x027e, 0x037e, 0x047e, 0x1078, 0x1af7, + 0x027e, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0000, 0x0040, 0x1790, + 0x7004, 0xac06, 0x00c0, 0x1781, 0x2079, 0x0030, 0x7000, 0xa086, + 0x0003, 0x0040, 0x1781, 0x7804, 0xd0fc, 0x00c0, 0x177d, 0x2001, + 0x0207, 0x2004, 0xd09c, 0x00c0, 0x1763, 0x7803, 0x0004, 0x7804, + 0xd0ac, 0x00c0, 0x176f, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, + 0x0003, 0x7007, 0x0000, 0x0078, 0x1781, 0x1078, 0x18e2, 0x0078, + 0x1753, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa5e7, 0x2104, 0xac06, + 0x00c0, 0x178b, 0x200a, 0xa188, 0x0003, 0x00f0, 0x1786, 0x157f, + 0x027f, 0x2001, 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138, + 0x2202, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f, 0x007c, 0x700c, + 0x7110, 0xa106, 0x00c0, 0x17a7, 0x7003, 0x0000, 0x007c, 0x2104, + 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, + 0xa602, 0x0048, 0x17b5, 0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106, + 0x00c0, 0x17be, 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x00c0, + 0x17c5, 0x1078, 0x1b22, 0x0078, 0x1823, 0x6010, 0x2068, 0x2d58, + 0x6828, 0xa406, 0x00c0, 0x17d0, 0x682c, 0xa306, 0x0040, 0x17fe, + 0x601c, 0xa086, 0x0008, 0x0040, 0x17fe, 0x6024, 0xd0f4, 0x00c0, + 0x17fa, 0xd0d4, 0x0040, 0x17f6, 0x6038, 0xa402, 0x6034, 0xa303, + 0x0040, 0x17e4, 0x00c8, 0x17f6, 0x643a, 0x6336, 0x6c2a, 0x6b2e, + 0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80, + 0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x17fa, 0x1078, 0x8d8e, + 0x0040, 0x17c1, 0x1078, 0x2035, 0x00c0, 0x17c1, 0x0c7e, 0x7004, + 0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4, 0x0040, + 0x180f, 0x6817, 0xffff, 0x6813, 0xffff, 0x0078, 0x17c1, 0x6824, + 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, + 0x2009, 0x0011, 0x1078, 0x1824, 0x0040, 0x1822, 0x2009, 0x0001, + 0x1078, 0x1824, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x18bb, 0xa03e, + 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1846, 0xd0f4, 0x00c0, 0x1856, + 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1836, 0x189d, 0x185d, + 0x185d, 0x189d, 0x189d, 0x1895, 0x189d, 0x185d, 0x189d, 0x1863, + 0x1863, 0x189d, 0x189d, 0x189d, 0x188c, 0x1863, 0xc0fc, 0x6852, + 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x0d7e, 0xd99c, 0x0040, 0x18a0, + 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x18a0, 0xc0f4, 0x6852, + 0x6b6c, 0x6a70, 0x0d7e, 0x0078, 0x18a7, 0x6b08, 0x6a0c, 0x6d00, + 0x6c04, 0x0078, 0x18a0, 0x7b0c, 0xd3bc, 0x0040, 0x1884, 0x7004, + 0x0e7e, 0x2070, 0x701c, 0x0e7f, 0xa086, 0x0008, 0x00c0, 0x1884, + 0x7b08, 0xa39c, 0x0fff, 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, 0x82ff, + 0x00c0, 0x187f, 0x6810, 0xa302, 0x0048, 0x187f, 0x6b10, 0x2011, + 0x0000, 0x2468, 0x0078, 0x1886, 0x6b10, 0x6a14, 0x6d00, 0x6c04, + 0x6f08, 0x6e0c, 0x0078, 0x18a0, 0x0d7f, 0x0d7e, 0x6834, 0xa084, + 0x00ff, 0xa086, 0x001e, 0x00c0, 0x189d, 0x0d7f, 0x1078, 0x1fd1, + 0x00c0, 0x1824, 0xa00e, 0x0078, 0x18bb, 0x0d7f, 0x1078, 0x1328, + 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, + 0x8000, 0x7002, 0x0d7f, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, + 0x682e, 0x2300, 0x6b10, 0xa302, 0x6812, 0x2200, 0x6a14, 0xa203, + 0x6816, 0x1078, 0x1fd1, 0x007c, 0x1078, 0x1328, 0x1078, 0x1c52, + 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000, 0x1078, + 0x1ac6, 0x1078, 0x8a44, 0x0040, 0x18db, 0x6808, 0x8001, 0x680a, + 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff, + 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758, 0x0078, 0x1aad, + 0x1078, 0x1328, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e, 0x2b68, + 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0, + 0x18be, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x18e0, 0x7000, + 0x0079, 0x18fa, 0x1902, 0x1904, 0x1a06, 0x1a84, 0x1a9b, 0x1902, + 0x1902, 0x1902, 0x1078, 0x1328, 0x8001, 0x7002, 0xa184, 0x0880, + 0x00c0, 0x1919, 0x8aff, 0x0040, 0x199b, 0x2009, 0x0001, 0x1078, + 0x1824, 0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078, + 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x00c0, 0x1979, + 0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1930, 0x7c20, 0x7d24, + 0x7e30, 0x7f34, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1932, + 0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500, + 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x0c7e, 0x7004, 0x2060, 0x6024, + 0xd0f4, 0x00c0, 0x1945, 0x633a, 0x6236, 0x0c7f, 0x2400, 0x6910, + 0xa100, 0x6812, 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, 0x027f, + 0x2600, 0x681e, 0x2700, 0x6822, 0x1078, 0x1fea, 0x2a00, 0x6826, + 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808, + 0x8001, 0x680a, 0x00c0, 0x196e, 0x684c, 0xd0e4, 0x0040, 0x196e, + 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x7000, 0xa086, + 0x0004, 0x0040, 0x1aad, 0x7003, 0x0000, 0x1078, 0x179f, 0x0078, + 0x1aad, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x1980, 0x1078, 0xa20c, + 0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4893, + 0x0040, 0x198d, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff, + 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, + 0x6916, 0x0078, 0x1aad, 0x7004, 0x0c7e, 0x2060, 0x6024, 0x0c7f, + 0xd0f4, 0x0040, 0x19a8, 0x6808, 0x8001, 0x680a, 0x0078, 0x1aad, + 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x19c0, 0x7003, + 0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, 0x19bc, 0x7004, 0x2060, + 0x2009, 0x0048, 0x1078, 0x756c, 0x1078, 0x179f, 0x0078, 0x1aad, + 0x7814, 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816, + 0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, + 0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, + 0x810b, 0x1078, 0x1b4d, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, + 0x0001, 0x7804, 0xd0fc, 0x0040, 0x19e1, 0x7803, 0x0002, 0x7803, + 0x0004, 0x780f, 0x0076, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, + 0x0048, 0x1078, 0x756c, 0x1078, 0x1b81, 0x0040, 0x19bc, 0x7908, + 0xd1ec, 0x00c0, 0x19ff, 0x2009, 0x0009, 0x0078, 0x1a01, 0x2009, + 0x0019, 0x7902, 0x7003, 0x0003, 0x0078, 0x1aad, 0x8001, 0x7002, + 0xd194, 0x0040, 0x1a18, 0x7804, 0xd0fc, 0x00c0, 0x18ea, 0x8aff, + 0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078, 0x1aad, + 0xa184, 0x0880, 0x00c0, 0x1a25, 0x8aff, 0x0040, 0x1aad, 0x2009, + 0x0001, 0x1078, 0x1824, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, + 0x0000, 0xd1bc, 0x00c0, 0x1a65, 0x027e, 0x037e, 0x7808, 0xd0ec, + 0x00c0, 0x1a38, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1a3a, + 0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x1078, 0x1fea, 0x0d7e, 0x0f7e, + 0x2d78, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1a55, 0x6808, + 0x2008, 0xa31a, 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, + 0x7814, 0xa101, 0x7816, 0x0078, 0x1a61, 0x6810, 0x2008, 0xa31a, + 0x6814, 0xa213, 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, + 0x7816, 0x0f7f, 0x0d7f, 0x0078, 0x1934, 0x057e, 0x7d0c, 0x1078, + 0xa20c, 0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078, + 0x4893, 0x0040, 0x1a76, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, + 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, + 0x6980, 0x6916, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, + 0x7004, 0xa00d, 0x0040, 0x1a97, 0x6808, 0x8001, 0x680a, 0x00c0, + 0x1a97, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x1078, + 0x179f, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, + 0x2060, 0x6010, 0xa005, 0x0040, 0x1a97, 0x2068, 0x6808, 0x8000, + 0x680a, 0x6c28, 0x6b2c, 0x1078, 0x17be, 0x017f, 0x007f, 0x127f, + 0x007c, 0x127e, 0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0, + 0x1ac4, 0x700c, 0x7110, 0xa106, 0x0040, 0x1ac4, 0x20e1, 0x9028, + 0x700f, 0xa5e7, 0x7013, 0xa5e7, 0x127f, 0x007c, 0x0c7e, 0x1078, + 0x1af7, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1aed, + 0x2104, 0xa005, 0x0040, 0x1ada, 0x2060, 0x6010, 0x2060, 0x6008, + 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xa602, 0x0048, 0x1ae2, + 0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106, 0x00c0, 0x1acb, 0x2001, + 0x0138, 0x2003, 0x0008, 0x0078, 0x1acb, 0x2001, 0x015d, 0x200c, + 0x810a, 0x2102, 0x2001, 0x0138, 0x2202, 0x0c7f, 0x007c, 0x2001, + 0x0138, 0x2014, 0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141, + 0x201c, 0xd3dc, 0x00c0, 0x1b14, 0x2001, 0x0109, 0x201c, 0xa39c, + 0x0048, 0x00c0, 0x1b14, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0, + 0x1b14, 0x8421, 0x00c0, 0x1afe, 0x007c, 0x2011, 0x0201, 0x2009, + 0x003c, 0x2204, 0xa005, 0x00c0, 0x1b21, 0x8109, 0x00c0, 0x1b19, + 0x007c, 0x007c, 0x1078, 0x1b15, 0x0040, 0x1b4a, 0x7908, 0xd1ec, + 0x00c0, 0x1b3a, 0x1078, 0x1b81, 0x0040, 0x1b3a, 0x7803, 0x0009, + 0x7904, 0xd1fc, 0x0040, 0x1b30, 0x7803, 0x0006, 0x1078, 0x1b15, + 0x0040, 0x1b4a, 0x780c, 0xd0a4, 0x00c0, 0x1b4a, 0x7007, 0x0000, + 0x1078, 0x1b81, 0x0040, 0x1b4c, 0x7803, 0x0019, 0x7003, 0x0003, + 0x0078, 0x1b4c, 0x1078, 0x1ac6, 0x007c, 0x0e7e, 0x2071, 0x0200, + 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1af7, 0x2019, 0x5000, + 0x8319, 0x0040, 0x1b6b, 0x2001, 0xa602, 0x2004, 0xa086, 0x0000, + 0x0040, 0x1b6b, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b58, 0x1078, + 0x1e5d, 0x0078, 0x1b56, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028, + 0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100, + 0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, 0x0e7f, + 0x007c, 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x1b8c, + 0xa085, 0x0001, 0x0078, 0x1b9e, 0x2001, 0x020a, 0x81ff, 0x0040, + 0x1b97, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1, + 0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x007c, 0x7c20, + 0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, 0x1c24, + 0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1c24, 0x0d7e, + 0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1c22, 0x6824, 0xd0d4, + 0x00c0, 0x1c22, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1bec, + 0x8108, 0x2104, 0x6b2c, 0xa306, 0x00c0, 0x1c22, 0x8108, 0x2104, + 0x6a28, 0xa206, 0x00c0, 0x1c22, 0x6850, 0xc0fc, 0xc0f5, 0x6852, + 0x686c, 0x7822, 0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, + 0x6818, 0x2060, 0x6034, 0xd09c, 0x0040, 0x1be7, 0x6830, 0x2004, + 0xac68, 0x6808, 0x783a, 0x680c, 0x783e, 0x0078, 0x1c20, 0xa006, + 0x783a, 0x783e, 0x0078, 0x1c20, 0x8108, 0x2104, 0xa005, 0x00c0, + 0x1c22, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c22, 0x6850, 0xc0f5, + 0x6852, 0x6830, 0x2004, 0x6918, 0xa160, 0xa180, 0x000d, 0x2004, + 0xd09c, 0x00c0, 0x1c12, 0x6008, 0x7822, 0x686e, 0x600c, 0x7826, + 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006, 0x783a, 0x783e, + 0x0078, 0x1c20, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826, 0x6872, + 0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c, 0x783e, + 0x7803, 0x0011, 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e, + 0x027e, 0x2071, 0xa5e1, 0x2079, 0x0030, 0x2011, 0x0050, 0x7000, + 0xa086, 0x0000, 0x0040, 0x1c4d, 0x8211, 0x0040, 0x1c4b, 0x2001, + 0x0005, 0x2004, 0xd08c, 0x0040, 0x1c34, 0x7904, 0xa18c, 0x0780, + 0x017e, 0x1078, 0x18e2, 0x017f, 0x81ff, 0x00c0, 0x1c4b, 0x2011, + 0x0050, 0x0078, 0x1c2f, 0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f, + 0x0f7f, 0x007c, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac, + 0x0040, 0x1ca3, 0x8109, 0x00c0, 0x1c56, 0x2009, 0x0100, 0x210c, + 0xa18a, 0x0003, 0x1048, 0x1328, 0x1078, 0x1f75, 0x0e7e, 0x0f7e, + 0x2071, 0xa5d0, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0040, + 0x1c9b, 0x7800, 0x007e, 0x7820, 0x007e, 0x7830, 0x007e, 0x7834, + 0x007e, 0x7838, 0x007e, 0x783c, 0x007e, 0x7803, 0x0004, 0x7823, + 0x0000, 0x0005, 0x0005, 0x2079, 0x0030, 0x7804, 0xd0ac, 0x10c0, + 0x1328, 0x2079, 0x0010, 0x007f, 0x783e, 0x007f, 0x783a, 0x007f, + 0x7836, 0x007f, 0x7832, 0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f, + 0x0e7f, 0x0078, 0x1ca1, 0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0, + 0x1328, 0x1078, 0x61d3, 0x007c, 0x0e7e, 0x2071, 0xa602, 0x7003, + 0x0000, 0x0e7f, 0x007c, 0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c, + 0xd1dc, 0x00c0, 0x1d26, 0x6934, 0xa184, 0x0007, 0x0079, 0x1cb8, + 0x1cc0, 0x1d11, 0x1cc0, 0x1cc0, 0x1cc0, 0x1cf6, 0x1cd3, 0x1cc2, + 0x1078, 0x1328, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e, + 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, + 0x6958, 0x0078, 0x1d19, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, + 0x00c0, 0x1cc0, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e, + 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, + 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, + 0x2015, 0x2004, 0x6832, 0x6958, 0x0078, 0x1d22, 0xa18c, 0x00ff, + 0xa186, 0x0015, 0x00c0, 0x1d26, 0x684c, 0xd0b4, 0x0040, 0x1e34, + 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, + 0x2015, 0x2004, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0078, + 0x1d22, 0x684c, 0xd0b4, 0x0040, 0x18bc, 0x6958, 0xa006, 0x682e, + 0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2015, + 0x2004, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c, + 0x0f7e, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x10c0, 0x1e5d, 0x0e7e, + 0x0d7e, 0x2071, 0xa602, 0x7000, 0xa005, 0x00c0, 0x1dab, 0x0c7e, + 0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, + 0x6818, 0x0d7e, 0x2068, 0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1, + 0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, + 0x0f7f, 0x0d7f, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, + 0x2040, 0x6034, 0xa0cc, 0x000f, 0x6908, 0x2001, 0x04fd, 0x2004, + 0xa086, 0x0007, 0x0040, 0x1d6d, 0xa184, 0x0007, 0x0040, 0x1d6d, + 0x017e, 0x2009, 0x0008, 0xa102, 0x017f, 0xa108, 0x791a, 0x7116, + 0x701e, 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, + 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x00c0, 0x1d84, 0x6928, + 0x6810, 0xa106, 0x0040, 0x1d91, 0x037e, 0x047e, 0x6b14, 0x6c10, + 0x1078, 0x2035, 0x047f, 0x037f, 0x0040, 0x1d91, 0x0c7f, 0x0078, + 0x1dab, 0x8aff, 0x00c0, 0x1d99, 0x0c7f, 0xa085, 0x0001, 0x0078, + 0x1dab, 0x127e, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001, + 0x1078, 0x1daf, 0x0040, 0x1da8, 0x2009, 0x0001, 0x1078, 0x1daf, + 0x127f, 0x0c7f, 0xa006, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, + 0x067e, 0x057e, 0x047e, 0x037e, 0x027e, 0x8aff, 0x0040, 0x1e2d, + 0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0048, 0x1e2c, + 0xa705, 0x0040, 0x1e2c, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0, + 0x1ddf, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1dcf, 0x1e0e, + 0x1def, 0x1def, 0x1e0e, 0x1e0e, 0x1e06, 0x1e0e, 0x1def, 0x1e0e, + 0x1df5, 0x1df5, 0x1e0e, 0x1e0e, 0x1e0e, 0x1dfd, 0x1df5, 0xc0fc, + 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0040, 0x1e12, + 0x0d7e, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x6b08, + 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1e11, 0x6b10, 0x6a14, 0x6d00, + 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x0d7f, 0x0d7e, 0x6834, + 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1e0e, 0x0d7f, 0x1078, + 0x1fd1, 0x00c0, 0x1db5, 0xa00e, 0x0078, 0x1e2d, 0x0d7f, 0x1078, + 0x1328, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, + 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c, + 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012, + 0x1078, 0x1fd1, 0x0078, 0x1e2d, 0xa006, 0x027f, 0x037f, 0x047f, + 0x057f, 0x067f, 0x077f, 0x007c, 0x1078, 0x1328, 0x027e, 0x2001, + 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, + 0x0000, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, + 0x0040, 0x1e4d, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758, + 0x20e1, 0x9040, 0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc, + 0x1078, 0x61d3, 0x027f, 0x0078, 0x1f29, 0x127e, 0x2091, 0x2200, + 0x007e, 0x017e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, + 0x2071, 0xa602, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, + 0xa184, 0x0700, 0x00c0, 0x1e36, 0x7000, 0x0079, 0x1e77, 0x1f29, + 0x1e7b, 0x1ef6, 0x1f27, 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1e8f, + 0x8aff, 0x0040, 0x1eae, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0040, + 0x1f29, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0078, 0x1f29, 0x7803, + 0x0004, 0xd194, 0x0040, 0x1e9f, 0x6850, 0xc0fc, 0x6852, 0x8aff, + 0x00c0, 0x1ea4, 0x684c, 0xc0f5, 0x684e, 0x0078, 0x1ea4, 0x1078, + 0x1fea, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, + 0x2800, 0x6832, 0x7003, 0x0000, 0x0078, 0x1f29, 0x711c, 0x81ff, + 0x0040, 0x1ec4, 0x7918, 0x7922, 0x7827, 0x0000, 0x7803, 0x0001, + 0x7000, 0x8000, 0x7002, 0x700c, 0xa100, 0x700e, 0x7010, 0xa081, + 0x0000, 0x7012, 0x0078, 0x1f29, 0x0f7e, 0x027e, 0x781c, 0x007e, + 0x7818, 0x007e, 0x2079, 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, + 0x0012, 0x7816, 0x037e, 0x2019, 0x1000, 0x8319, 0x1040, 0x1328, + 0x7820, 0xd0bc, 0x00c0, 0x1ed5, 0x037f, 0x79c8, 0x007f, 0xa102, + 0x017f, 0x007e, 0x017e, 0x79c4, 0x007f, 0xa103, 0x78c6, 0x007f, + 0x78ca, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f, + 0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1f29, 0x8001, 0x7002, + 0xd194, 0x0040, 0x1f0b, 0x7804, 0xd0fc, 0x00c0, 0x1e6d, 0xd19c, + 0x00c0, 0x1f25, 0x8aff, 0x0040, 0x1f29, 0x2009, 0x0001, 0x1078, + 0x1daf, 0x0078, 0x1f29, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078, + 0x1fea, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1f1e, + 0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1f22, 0x6810, 0xa31a, + 0x6814, 0xa213, 0x0d7f, 0x0078, 0x1e9f, 0x0078, 0x1e9f, 0x1078, + 0x1328, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f, + 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0xa602, 0x7000, 0xa086, 0x0000, + 0x0040, 0x1f72, 0x2079, 0x0020, 0x017e, 0x2009, 0x0207, 0x210c, + 0xd194, 0x0040, 0x1f4f, 0x2009, 0x020c, 0x210c, 0xa184, 0x0003, + 0x0040, 0x1f4f, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102, 0x2009, + 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x00c0, 0x1f5a, + 0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0040, 0x1f3d, 0x1078, 0x1e5d, + 0x7000, 0xa086, 0x0000, 0x00c0, 0x1f3d, 0x017f, 0x7803, 0x0004, + 0x7804, 0xd0ac, 0x00c0, 0x1f68, 0x20e1, 0x9040, 0x7803, 0x0002, + 0x7003, 0x0000, 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e, + 0x0e7e, 0x0f7e, 0x2071, 0xa602, 0x2079, 0x0020, 0x7000, 0xa086, + 0x0000, 0x0040, 0x1fae, 0x7004, 0x2060, 0x6010, 0x2068, 0x1078, + 0x8a44, 0x0040, 0x1f98, 0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c, + 0xa206, 0x00c0, 0x1f98, 0x6808, 0x7a18, 0xa206, 0x0040, 0x1fb4, + 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x1078, 0x8758, 0x20e1, 0x9040, + 0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc, 0x0f7f, 0x0e7f, + 0x0d7f, 0x0c7f, 0x027f, 0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0, + 0x1f98, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x1078, 0x1cab, 0x2001, + 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, + 0x0000, 0x2069, 0xa5ab, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078, + 0x1fae, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1fe5, 0x6004, 0xa005, + 0x0040, 0x1fe7, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, + 0x2015, 0x2044, 0x88ff, 0x1040, 0x1328, 0x8a51, 0x007c, 0x2051, + 0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0, 0x2004, + 0x2c00, 0xad06, 0x0040, 0x1ff9, 0x6000, 0xa005, 0x00c0, 0x1ff9, + 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, 0x2025, + 0x2044, 0x88ff, 0x1040, 0x1328, 0x007c, 0x0000, 0x0011, 0x0015, + 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, 0x0015, + 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x200a, 0x2006, + 0x0000, 0x0000, 0x2014, 0x0000, 0x200a, 0x0000, 0x2011, 0x200e, + 0x0000, 0x0000, 0x0000, 0x2014, 0x2011, 0x0000, 0x200c, 0x200c, + 0x0000, 0x0000, 0x2014, 0x0000, 0x200c, 0x0000, 0x2012, 0x2012, + 0x0000, 0x0000, 0x0000, 0x2014, 0x2012, 0x0a7e, 0x097e, 0x087e, + 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0040, 0x20d8, 0x2d60, 0x6034, + 0xa0cc, 0x000f, 0xa9c0, 0x2015, 0xa986, 0x0007, 0x0040, 0x2050, + 0xa986, 0x000e, 0x0040, 0x2050, 0xa986, 0x000f, 0x00c0, 0x2054, + 0x605c, 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x2062, + 0x0050, 0x205c, 0x0078, 0x20d8, 0x6004, 0xa065, 0x0040, 0x20d8, + 0x0078, 0x203f, 0x2804, 0xa005, 0x0040, 0x2080, 0xac68, 0xd99c, + 0x00c0, 0x2070, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x2074, + 0x6810, 0xa422, 0x6814, 0xa31b, 0x0048, 0x209f, 0x2300, 0xa405, + 0x0040, 0x2086, 0x8a51, 0x0040, 0x20d8, 0x8840, 0x0078, 0x2062, + 0x6004, 0xa065, 0x0040, 0x20d8, 0x0078, 0x203f, 0x8a51, 0x0040, + 0x20d8, 0x8840, 0x2804, 0xa005, 0x00c0, 0x2099, 0x6004, 0xa065, + 0x0040, 0x20d8, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2015, 0x2804, + 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x20cc, 0x8422, + 0x8420, 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, + 0x0d7f, 0xd99c, 0x00c0, 0x20ba, 0x6908, 0x2400, 0xa122, 0x690c, + 0x2300, 0xa11b, 0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319, + 0x0078, 0x20c6, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, + 0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, + 0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, + 0x2a00, 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x20dd, + 0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005, + 0x2004, 0xa084, 0x0007, 0x0079, 0x20e5, 0x20ed, 0x20ee, 0x20f1, + 0x20f4, 0x20f9, 0x20fc, 0x2101, 0x2106, 0x007c, 0x1078, 0x1e5d, + 0x007c, 0x1078, 0x18e2, 0x007c, 0x1078, 0x18e2, 0x1078, 0x1e5d, + 0x007c, 0x1078, 0x14b0, 0x007c, 0x1078, 0x1e5d, 0x1078, 0x14b0, + 0x007c, 0x1078, 0x18e2, 0x1078, 0x14b0, 0x007c, 0x1078, 0x18e2, + 0x1078, 0x1e5d, 0x1078, 0x14b0, 0x007c, 0x127e, 0x2091, 0x2300, + 0x2079, 0x0200, 0x2071, 0xa880, 0x2069, 0xa300, 0x2009, 0x0004, + 0x7912, 0x7817, 0x0004, 0x1078, 0x24b5, 0x781b, 0x0002, 0x20e1, + 0x8700, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, + 0x0007, 0x0079, 0x212b, 0x214f, 0x2133, 0x2137, 0x213b, 0x2141, + 0x2145, 0x2149, 0x214d, 0x1078, 0x5372, 0x0078, 0x214f, 0x1078, + 0x53b3, 0x0078, 0x214f, 0x1078, 0x5372, 0x1078, 0x53b3, 0x0078, + 0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x0078, + 0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x127f, + 0x007c, 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040, + 0x215d, 0x20e1, 0x9040, 0x0078, 0x2186, 0xa184, 0x0030, 0x0040, + 0x216e, 0x6a00, 0xa286, 0x0003, 0x00c0, 0x2168, 0x0078, 0x216a, + 0x1078, 0x4171, 0x20e1, 0x9010, 0x0078, 0x2186, 0xa184, 0x00c0, + 0x0040, 0x2180, 0x0e7e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa5e1, + 0x1078, 0x1ac6, 0x057f, 0x047f, 0x037f, 0x0e7f, 0x0078, 0x2186, + 0xa184, 0x0300, 0x0040, 0x2186, 0x20e1, 0x9020, 0x7932, 0x027f, + 0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071, 0xa300, + 0x7128, 0x2001, 0xa58f, 0x2102, 0x2001, 0xa597, 0x2102, 0xa182, + 0x0211, 0x00c8, 0x219f, 0x2009, 0x0008, 0x0078, 0x21c9, 0xa182, + 0x0259, 0x00c8, 0x21a7, 0x2009, 0x0007, 0x0078, 0x21c9, 0xa182, + 0x02c1, 0x00c8, 0x21af, 0x2009, 0x0006, 0x0078, 0x21c9, 0xa182, + 0x0349, 0x00c8, 0x21b7, 0x2009, 0x0005, 0x0078, 0x21c9, 0xa182, + 0x0421, 0x00c8, 0x21bf, 0x2009, 0x0004, 0x0078, 0x21c9, 0xa182, + 0x0581, 0x00c8, 0x21c7, 0x2009, 0x0003, 0x0078, 0x21c9, 0x2009, + 0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x1078, 0x24b5, + 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061, + 0x0100, 0x2071, 0xa300, 0x6024, 0x6026, 0x6053, 0x0030, 0x6033, + 0x00ef, 0x60e7, 0x0000, 0x60eb, 0x00ef, 0x60e3, 0x0008, 0x604b, + 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, + 0x0eaf, 0x600f, 0x00ff, 0x602b, 0x002f, 0x127f, 0x007c, 0x2001, + 0xa32f, 0x2003, 0x0000, 0x2001, 0xa32e, 0x2003, 0x0001, 0x007c, + 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184, + 0x002c, 0x00c0, 0x220f, 0xa184, 0x0007, 0x0079, 0x2215, 0xa195, + 0x0004, 0xa284, 0x0007, 0x0079, 0x2215, 0x2241, 0x221d, 0x2221, + 0x2225, 0x222b, 0x222f, 0x2235, 0x223b, 0x1078, 0x5ad2, 0x0078, + 0x2241, 0x1078, 0x5bc1, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078, + 0x5ad2, 0x0078, 0x2241, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078, + 0x5ad2, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078, + 0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078, 0x5ad2, 0x1078, + 0x2246, 0x027f, 0x017f, 0x007f, 0x127f, 0x007c, 0x6124, 0xd1ac, + 0x0040, 0x2342, 0x017e, 0x047e, 0x0c7e, 0x644c, 0xa486, 0xf0f0, + 0x00c0, 0x2259, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, + 0x0010, 0x74c2, 0xa48c, 0xff00, 0x7034, 0xd084, 0x0040, 0x2271, + 0xa186, 0xf800, 0x00c0, 0x2271, 0x7038, 0xd084, 0x00c0, 0x2271, + 0xc085, 0x703a, 0x037e, 0x2418, 0x2011, 0x8016, 0x1078, 0x3579, + 0x037f, 0xa196, 0xff00, 0x0040, 0x22b3, 0x6030, 0xa084, 0x00ff, + 0x810f, 0xa116, 0x0040, 0x22b3, 0x7130, 0xd184, 0x00c0, 0x22b3, + 0x2011, 0xa352, 0x2214, 0xd2ec, 0x0040, 0x228e, 0xc18d, 0x7132, + 0x2011, 0xa352, 0x2214, 0xd2ac, 0x00c0, 0x22b3, 0x6240, 0xa294, + 0x0010, 0x0040, 0x229a, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00, + 0x0040, 0x22b3, 0x7030, 0xd08c, 0x0040, 0x2305, 0x7034, 0xd08c, + 0x00c0, 0x22aa, 0x2001, 0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305, + 0xc1ad, 0x2102, 0x037e, 0x73c0, 0x2011, 0x8013, 0x1078, 0x3579, + 0x037f, 0x0078, 0x2305, 0x7034, 0xd08c, 0x00c0, 0x22bf, 0x2001, + 0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305, 0xc1ad, 0x2102, 0x037e, + 0x73c0, 0x2011, 0x8013, 0x1078, 0x3579, 0x037f, 0x7130, 0xc185, + 0x7132, 0x2011, 0xa352, 0x220c, 0xd1a4, 0x0040, 0x22e9, 0x017e, + 0x2009, 0x0001, 0x2011, 0x0100, 0x1078, 0x5a6d, 0x2019, 0x000e, + 0x1078, 0x9e3b, 0xa484, 0x00ff, 0xa080, 0x293f, 0x200c, 0xa18c, + 0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x1078, 0x9ec0, + 0x017f, 0xd1ac, 0x00c0, 0x22f6, 0x017e, 0x2009, 0x0000, 0x2019, + 0x0004, 0x1078, 0x27e2, 0x017f, 0x0078, 0x2305, 0x157e, 0x20a9, + 0x007f, 0x2009, 0x0000, 0x1078, 0x4501, 0x00c0, 0x2301, 0x1078, + 0x4235, 0x8108, 0x00f0, 0x22fb, 0x157f, 0x0c7f, 0x047f, 0x0f7e, + 0x2079, 0xa5be, 0x783c, 0xa086, 0x0000, 0x0040, 0x2317, 0x6027, + 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x0000, 0x0f7f, + 0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011, 0x0002, 0x1078, 0x6efc, + 0x1078, 0x6dda, 0x1078, 0x595a, 0x037e, 0x2019, 0x0000, 0x1078, + 0x6e6c, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, 0xa300, 0x2014, + 0xa296, 0x0004, 0x00c0, 0x233a, 0xd19c, 0x00c0, 0x233a, 0x6228, + 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa321, 0x2003, 0x0000, + 0x6027, 0x0020, 0xd194, 0x0040, 0x2426, 0x0f7e, 0x2079, 0xa5be, + 0x783c, 0xa086, 0x0001, 0x00c0, 0x2366, 0x017e, 0x6027, 0x0004, + 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000, 0x7803, 0x0000, + 0x2079, 0xa5ab, 0x7807, 0x0000, 0x7833, 0x0000, 0x1078, 0x6109, + 0x1078, 0x61d3, 0x017f, 0x0f7f, 0x0078, 0x2426, 0x0f7f, 0x017e, + 0x3900, 0xa082, 0xa6cd, 0x00c8, 0x2371, 0x017e, 0x1078, 0x728a, + 0x017f, 0x6220, 0xd2b4, 0x0040, 0x23dc, 0x1078, 0x595a, 0x1078, + 0x6c41, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa5b4, 0x2304, 0xa07d, + 0x0040, 0x23b2, 0x7804, 0xa086, 0x0032, 0x00c0, 0x23b2, 0x0d7e, + 0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e, + 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x00c0, + 0x2396, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, + 0x628a, 0x1078, 0x6010, 0x1078, 0x6109, 0x7810, 0x2070, 0x7037, + 0x0103, 0x2f60, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0d7f, 0x0f7f, + 0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, + 0x4000, 0x0040, 0x23bf, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, + 0x0c7e, 0x2061, 0xa5ab, 0x6028, 0xa09a, 0x00c8, 0x00c8, 0x23cf, + 0x8000, 0x602a, 0x0c7f, 0x1078, 0x6c33, 0x0078, 0x2425, 0x2019, + 0xa5b4, 0x2304, 0xa065, 0x0040, 0x23d9, 0x2009, 0x0027, 0x1078, + 0x756c, 0x0c7f, 0x0078, 0x2425, 0xd2bc, 0x0040, 0x2425, 0x1078, + 0x5967, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140, + 0x6804, 0xa084, 0x4000, 0x0040, 0x23f1, 0x6803, 0x1000, 0x6803, + 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa5ab, 0x6044, 0xa09a, 0x00c8, + 0x00c8, 0x2414, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040, + 0x2425, 0x2009, 0x07d0, 0x1078, 0x595f, 0xa080, 0x0007, 0x2004, + 0xa086, 0x0006, 0x00c0, 0x2410, 0x6017, 0x0012, 0x0078, 0x2425, + 0x6017, 0x0016, 0x0078, 0x2425, 0x037e, 0x2019, 0x0001, 0x1078, + 0x6e6c, 0x037f, 0x2019, 0xa5ba, 0x2304, 0xa065, 0x0040, 0x2424, + 0x2009, 0x004f, 0x1078, 0x756c, 0x0c7f, 0x017f, 0xd19c, 0x0040, + 0x247c, 0x7034, 0xd0ac, 0x00c0, 0x2457, 0x017e, 0x157e, 0x6027, + 0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0, 0x2435, 0x602f, + 0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, 0x0320, 0x00e0, + 0x243f, 0x2091, 0x6000, 0x6020, 0xd09c, 0x00c0, 0x244e, 0x157f, + 0x6152, 0x017f, 0x6027, 0x0008, 0x0078, 0x247c, 0x1078, 0x250d, + 0x00f0, 0x243f, 0x157f, 0x6152, 0x017f, 0x6027, 0x0008, 0x017e, + 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011, + 0x0002, 0x1078, 0x6efc, 0x1078, 0x6dda, 0x1078, 0x595a, 0x037e, + 0x2019, 0x0000, 0x1078, 0x6e6c, 0x037f, 0x60e3, 0x0000, 0x1078, + 0xa22a, 0x1078, 0xa248, 0x2001, 0xa300, 0x2003, 0x0004, 0x6027, + 0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c, + 0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000, + 0x2071, 0xa300, 0x71b8, 0x70ba, 0xa116, 0x0040, 0x24ae, 0x81ff, + 0x0040, 0x2498, 0x2011, 0x8011, 0x1078, 0x3579, 0x0078, 0x24ae, + 0x2011, 0x8012, 0x1078, 0x3579, 0x2001, 0xa371, 0x2004, 0xd0fc, + 0x00c0, 0x24ae, 0x037e, 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028, + 0x2009, 0x0000, 0x1078, 0x27e2, 0x0c7f, 0x037f, 0x127f, 0x0f7f, + 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x0f7e, 0x007e, + 0x027e, 0x2061, 0x0100, 0xa190, 0x24d1, 0x2204, 0x60f2, 0x2011, + 0x24de, 0x6000, 0xa082, 0x0003, 0x00c8, 0x24ca, 0x2001, 0x00ff, + 0x0078, 0x24cb, 0x2204, 0x60ee, 0x027f, 0x007f, 0x0f7f, 0x0c7f, + 0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0, + 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8, + 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094, + 0xff00, 0x00c0, 0x24ee, 0x81ff, 0x0040, 0x24f2, 0x1078, 0x5623, + 0x0078, 0x24f9, 0xa080, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f, + 0xa006, 0x007c, 0xa080, 0x293f, 0x200c, 0xa18c, 0x00ff, 0x007c, + 0x0c7e, 0x2061, 0xa300, 0x6030, 0x0040, 0x2509, 0xc09d, 0x0078, + 0x250a, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e, 0x157e, 0x0f7e, + 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, 0x00c0, 0x251a, + 0x00f0, 0x2514, 0x0f7f, 0x157f, 0x007f, 0x007c, 0x0c7e, 0x007e, + 0x2061, 0x0100, 0x6030, 0x007e, 0x6048, 0x007e, 0x60e4, 0x007e, + 0x60e8, 0x007e, 0x6050, 0x007e, 0x60f0, 0x007e, 0x60ec, 0x007e, + 0x600c, 0x007e, 0x6004, 0x007e, 0x6028, 0x007e, 0x60e0, 0x007e, + 0x602f, 0x0100, 0x602f, 0x0000, 0x0005, 0x0005, 0x0005, 0x0005, + 0x602f, 0x0040, 0x602f, 0x0000, 0x007f, 0x60e2, 0x007f, 0x602a, + 0x007f, 0x6006, 0x007f, 0x600e, 0x007f, 0x60ee, 0x007f, 0x60f2, + 0x007f, 0x6052, 0x007f, 0x60ea, 0x007f, 0x60e6, 0x007f, 0x604a, + 0x007f, 0x6032, 0x007f, 0x0c7f, 0x007c, 0x257d, 0x2581, 0x2585, + 0x258b, 0x2591, 0x2597, 0x259d, 0x25a5, 0x25ad, 0x25b3, 0x25b9, + 0x25c1, 0x25c9, 0x25d1, 0x25d9, 0x25e3, 0x25ed, 0x25ed, 0x25ed, + 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, + 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x107e, 0x007e, 0x0078, + 0x2606, 0x107e, 0x007e, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, + 0x2200, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x0078, + 0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, + 0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, + 0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, + 0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, + 0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2123, 0x0078, + 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078, + 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078, + 0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078, + 0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078, + 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x20de, 0x1078, + 0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, + 0x20de, 0x1078, 0x2123, 0x0078, 0x2606, 0x0005, 0x0078, 0x25ed, + 0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x25f6, 0x2606, 0x2583, + 0x2587, 0x258d, 0x2593, 0x2599, 0x259f, 0x25a7, 0x25af, 0x25b5, + 0x25bb, 0x25c3, 0x25cb, 0x25d3, 0x25db, 0x25e5, 0x0008, 0x25f0, + 0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, 0x027e, 0x047e, + 0x2021, 0x0000, 0x1078, 0x4897, 0x00c0, 0x2705, 0x70c8, 0xd09c, + 0x0040, 0x2624, 0xd084, 0x00c0, 0x2624, 0xd0bc, 0x00c0, 0x2705, + 0x1078, 0x2709, 0x0078, 0x2705, 0xd094, 0x0040, 0x262b, 0x7093, + 0xffff, 0x0078, 0x2705, 0x2001, 0x010c, 0x203c, 0x7280, 0xd284, + 0x0040, 0x2694, 0xd28c, 0x00c0, 0x2694, 0x037e, 0x7390, 0xa38e, + 0xffff, 0x0040, 0x263e, 0x83ff, 0x00c0, 0x2640, 0x2019, 0x0001, + 0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x264d, + 0xa084, 0xff00, 0x8007, 0x0078, 0x264f, 0xa084, 0x00ff, 0xa70e, + 0x0040, 0x2689, 0xa08e, 0x0000, 0x0040, 0x2689, 0xa08e, 0x00ff, + 0x00c0, 0x2666, 0x7230, 0xd284, 0x00c0, 0x268f, 0x7280, 0xc28d, + 0x7282, 0x7093, 0xffff, 0x037f, 0x0078, 0x2694, 0x2009, 0x0000, + 0x1078, 0x24e3, 0x1078, 0x4499, 0x00c0, 0x268c, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2683, 0x7030, 0xd08c, 0x0040, + 0x267d, 0x6000, 0xd0bc, 0x0040, 0x2683, 0x1078, 0x271f, 0x0040, + 0x268c, 0x0078, 0x2689, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040, + 0x268c, 0x8318, 0x0078, 0x2640, 0x7392, 0x0078, 0x2691, 0x7093, + 0xffff, 0x037f, 0x0078, 0x2705, 0xa780, 0x293f, 0x203c, 0xa7bc, + 0xff00, 0x873f, 0x2041, 0x007e, 0x7090, 0xa096, 0xffff, 0x00c0, + 0x26a6, 0x2009, 0x0000, 0x28a8, 0x0078, 0x26b2, 0xa812, 0x0048, + 0x26ae, 0x2008, 0xa802, 0x20a8, 0x0078, 0x26b2, 0x7093, 0xffff, + 0x0078, 0x2705, 0x2700, 0x157e, 0x017e, 0xa106, 0x0040, 0x26f9, + 0xc484, 0x1078, 0x4501, 0x0040, 0x26c3, 0x1078, 0x4499, 0x00c0, + 0x2702, 0x0078, 0x26c4, 0xc485, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0006, 0x00c0, 0x26d3, 0x7030, 0xd08c, 0x0040, 0x26f1, 0x6000, + 0xd0bc, 0x00c0, 0x26f1, 0x7280, 0xd28c, 0x0040, 0x26e9, 0x6004, + 0xa084, 0x00ff, 0xa082, 0x0006, 0x0048, 0x26f9, 0xd484, 0x00c0, + 0x26e5, 0x1078, 0x44bc, 0x0078, 0x26e7, 0x1078, 0x2921, 0x0078, + 0x26f9, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040, 0x2702, 0x0078, + 0x26f9, 0x1078, 0x28ec, 0x0040, 0x26f9, 0x1078, 0x271f, 0x0040, + 0x2702, 0x017f, 0x8108, 0x157f, 0x00f0, 0x26b2, 0x7093, 0xffff, + 0x0078, 0x2705, 0x017f, 0x157f, 0x7192, 0x047f, 0x027f, 0x0c7f, + 0x007c, 0x0c7e, 0x017e, 0x7093, 0x0000, 0x2009, 0x007e, 0x1078, + 0x4499, 0x00c0, 0x271c, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040, + 0x271c, 0x70c8, 0xc0bd, 0x70ca, 0x017f, 0x0c7f, 0x007c, 0x017e, + 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa356, 0x2004, 0xa084, + 0x00ff, 0x6842, 0x1078, 0x74d7, 0x0040, 0x2747, 0x2d00, 0x601a, + 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0000, + 0x1078, 0x443f, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, + 0x127f, 0x2009, 0x0004, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, + 0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, + 0x2c68, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078, + 0x74d7, 0x0040, 0x2785, 0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802, + 0x68a0, 0xa086, 0x007e, 0x0040, 0x276e, 0x6804, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x00c0, 0x276e, 0x1078, 0x2813, 0x601f, 0x0001, + 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f, + 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, 0x127f, 0x2009, + 0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, + 0x017f, 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078, 0x4499, + 0x00c0, 0x2798, 0x1078, 0x279b, 0x0040, 0x2798, 0x70cf, 0xffff, + 0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, + 0x1078, 0x74d7, 0x0040, 0x27bd, 0x2d00, 0x601a, 0x601f, 0x0001, + 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f, + 0x127e, 0x2091, 0x8000, 0x70d0, 0x8000, 0x70d2, 0x127f, 0x2009, + 0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, + 0x017f, 0x007c, 0x0c7e, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2009, + 0x007f, 0x1078, 0x4499, 0x00c0, 0x27de, 0x2c68, 0x1078, 0x74d7, + 0x0040, 0x27de, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a, + 0x2009, 0x0022, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0d7f, + 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078, + 0x5d60, 0x1078, 0x5d02, 0x1078, 0x7ddf, 0x2130, 0x81ff, 0x0040, + 0x27f7, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0078, 0x27fb, 0x20a9, + 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x2804, + 0x1078, 0x471b, 0x1078, 0x4235, 0x017f, 0x8108, 0x00f0, 0x27fb, + 0x86ff, 0x00c0, 0x280d, 0x1078, 0x119b, 0x027f, 0x037f, 0x067f, + 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, + 0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53, + 0x077e, 0x2039, 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, + 0x077f, 0x017f, 0x2e60, 0x1078, 0x471b, 0x6210, 0x6314, 0x1078, + 0x4235, 0x6212, 0x6316, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, + 0x007c, 0x0e7e, 0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, + 0x00c0, 0x284d, 0x2071, 0xa300, 0x708c, 0xa005, 0x0040, 0x284a, + 0x8001, 0x708e, 0x007f, 0x0e7f, 0x007c, 0x2071, 0xa300, 0x70d0, + 0xa005, 0x0040, 0x284a, 0x8001, 0x70d2, 0x0078, 0x284a, 0x6000, + 0xc08c, 0x6002, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x037e, 0x027e, + 0x017e, 0x157e, 0x2178, 0x81ff, 0x00c0, 0x286a, 0x20a9, 0x0001, + 0x0078, 0x2885, 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x2881, + 0xd0a4, 0x0040, 0x2881, 0x047e, 0x6018, 0xa080, 0x0028, 0x2024, + 0xa4a4, 0x00ff, 0x8427, 0xa006, 0x2009, 0x002d, 0x1078, 0x9ec0, + 0x047f, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x027e, 0xa28e, 0x007e, + 0x0040, 0x28c9, 0xa28e, 0x007f, 0x0040, 0x28c9, 0xa28e, 0x0080, + 0x0040, 0x28c9, 0xa288, 0xa434, 0x210c, 0x81ff, 0x0040, 0x28c9, + 0x8fff, 0x1040, 0x28d5, 0x0c7e, 0x2160, 0x2001, 0x0001, 0x1078, + 0x48a2, 0x0c7f, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, + 0x0000, 0x1078, 0x5c78, 0x0c7e, 0x027e, 0x2160, 0x6204, 0xa294, + 0x00ff, 0xa286, 0x0006, 0x00c0, 0x28b9, 0x6007, 0x0404, 0x0078, + 0x28be, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x027f, 0x0c7f, + 0x017e, 0x2c08, 0x1078, 0x9c38, 0x017f, 0x077f, 0x2160, 0x1078, + 0x471b, 0x027f, 0x8210, 0x00f0, 0x2885, 0x157f, 0x017f, 0x027f, + 0x037f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e, + 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x28e8, 0xd0a4, 0x0040, + 0x28e8, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x1078, 0x9ec0, + 0x017f, 0x027f, 0x047f, 0x007c, 0x017e, 0x027e, 0x037e, 0x0c7e, + 0x7280, 0x82ff, 0x0040, 0x291a, 0xa290, 0xa352, 0x2214, 0xd2ac, + 0x00c0, 0x291a, 0x2100, 0x1078, 0x24fa, 0x81ff, 0x0040, 0x291c, + 0x2019, 0x0001, 0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xd384, 0x0040, + 0x290e, 0xa084, 0xff00, 0x8007, 0x0078, 0x2910, 0xa084, 0x00ff, + 0xa116, 0x0040, 0x291c, 0xa096, 0x00ff, 0x0040, 0x291a, 0x8318, + 0x0078, 0x2902, 0xa085, 0x0001, 0x0c7f, 0x037f, 0x027f, 0x017f, + 0x007c, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0xa180, 0xa434, + 0x2004, 0xa065, 0x0040, 0x293b, 0x017e, 0x0c7e, 0x1078, 0x8ec0, + 0x017f, 0x1040, 0x1328, 0x611a, 0x1078, 0x2813, 0x1078, 0x753d, + 0x017f, 0x1078, 0x44bc, 0x127f, 0x0c7f, 0x017f, 0x007c, 0x7eef, + 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, + 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, + 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, + 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, + 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, + 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, + 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, + 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, + 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, + 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, + 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, + 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, + 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, + 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, + 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, + 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, + 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, + 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, + 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, + 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, + 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, + 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, + 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, + 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, + 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, + 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, + 0xa381, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e, + 0x7033, 0xa391, 0x7037, 0xa391, 0x7007, 0x0001, 0x2061, 0xa3d1, + 0x6003, 0x0002, 0x007c, 0x0090, 0x2a66, 0x0068, 0x2a66, 0x2071, + 0xa381, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2a66, 0x2a60, 0x7820, + 0xa08e, 0x0069, 0x00c0, 0x2b56, 0x0079, 0x2aea, 0x007c, 0x2071, + 0xa381, 0x7004, 0x0079, 0x2a6c, 0x2a70, 0x2a71, 0x2a7b, 0x2a8d, + 0x007c, 0x0090, 0x2a7a, 0x0068, 0x2a7a, 0x2b78, 0x7818, 0xd084, + 0x0040, 0x2a99, 0x007c, 0x2b78, 0x2061, 0xa3d1, 0x6008, 0xa08e, + 0x0100, 0x0040, 0x2a88, 0xa086, 0x0200, 0x0040, 0x2b4e, 0x007c, + 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, 0x2068, 0x6834, + 0xa086, 0x0103, 0x0040, 0x2a95, 0x007c, 0x2a60, 0x2b78, 0x7018, + 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, 0x2aa2, 0x61b8, + 0x0079, 0x2aaa, 0x2100, 0xa08a, 0x003f, 0x00c8, 0x2b4a, 0x61b8, + 0x0079, 0x2aea, 0x2b2c, 0x2b5e, 0x2b66, 0x2b6a, 0x2b72, 0x2b78, + 0x2b7c, 0x2b88, 0x2b8c, 0x2b96, 0x2b9a, 0x2b4a, 0x2b4a, 0x2b4a, + 0x2b9e, 0x2b4a, 0x2bae, 0x2bc5, 0x2bdc, 0x2c58, 0x2c5d, 0x2c8a, + 0x2ce4, 0x2cf5, 0x2d13, 0x2d54, 0x2d5e, 0x2d6b, 0x2d7e, 0x2d9d, + 0x2da6, 0x2de3, 0x2de9, 0x2b4a, 0x2e05, 0x2b4a, 0x2b4a, 0x2b4a, + 0x2b4a, 0x2b4a, 0x2e0c, 0x2e16, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, + 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2e1e, 0x2b4a, 0x2b4a, 0x2b4a, + 0x2b4a, 0x2b4a, 0x2e30, 0x2e47, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, + 0x2b4a, 0x2b4a, 0x2e59, 0x2eb0, 0x2f0e, 0x2f1f, 0x2b4a, 0x2b4a, + 0x2b4a, 0x38f1, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, + 0x2b4a, 0x2b4a, 0x2b96, 0x2b9a, 0x2f36, 0x2b4a, 0x2f43, 0x397d, + 0x39da, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, + 0x2b4a, 0x2b4a, 0x2f90, 0x30c5, 0x30e1, 0x30ed, 0x3150, 0x31a9, + 0x31b4, 0x31f3, 0x3202, 0x3211, 0x3214, 0x2f47, 0x3238, 0x3284, + 0x3291, 0x33a2, 0x34cd, 0x34f7, 0x3604, 0x3614, 0x3621, 0x365b, + 0x372a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x3792, 0x37ae, 0x3828, + 0x38e2, 0x713c, 0x0078, 0x2b2c, 0x2021, 0x4000, 0x1078, 0x3553, + 0x127e, 0x2091, 0x8000, 0x0068, 0x2b39, 0x7818, 0xd084, 0x0040, + 0x2b3c, 0x127f, 0x0078, 0x2b30, 0x7c22, 0x7926, 0x7a2a, 0x7b2e, + 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, + 0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x2b2e, 0x2021, 0x4002, + 0x0078, 0x2b2e, 0x2021, 0x4003, 0x0078, 0x2b2e, 0x2021, 0x4005, + 0x0078, 0x2b2e, 0x2021, 0x4006, 0x0078, 0x2b2e, 0xa02e, 0x2520, + 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3562, 0x7823, 0x0004, + 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, + 0x0078, 0x3566, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078, 0x2b2c, + 0x7924, 0x2114, 0x0078, 0x2b2c, 0x2099, 0x0009, 0x20a1, 0x0009, + 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0078, 0x2b2c, + 0x7824, 0x2060, 0x0078, 0x2ba0, 0x2009, 0x0001, 0x2011, 0x0013, + 0x2019, 0x0010, 0x783b, 0x0017, 0x0078, 0x2b2c, 0x7d38, 0x7c3c, + 0x0078, 0x2b60, 0x7d38, 0x7c3c, 0x0078, 0x2b6c, 0x2061, 0x1000, + 0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, 0x2ba2, + 0x2010, 0xa005, 0x0040, 0x2b2c, 0x0078, 0x2b52, 0x2069, 0xa351, + 0x7824, 0x7930, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a, + 0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, + 0x685e, 0x1078, 0x4dbd, 0x0078, 0x2b2c, 0x2069, 0xa351, 0x7824, + 0x7934, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a, 0x684e, + 0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, + 0x1078, 0x494d, 0x0078, 0x2b2c, 0xa02e, 0x2520, 0x81ff, 0x00c0, + 0x2b56, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xa388, + 0x41a1, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0020, 0x1078, + 0x3562, 0x701b, 0x2bf4, 0x007c, 0x6834, 0x2008, 0xa084, 0x00ff, + 0xa096, 0x0011, 0x0040, 0x2c00, 0xa096, 0x0019, 0x00c0, 0x2b56, + 0x810f, 0xa18c, 0x00ff, 0x0040, 0x2b56, 0x710e, 0x700c, 0x8001, + 0x0040, 0x2c31, 0x700e, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, + 0x0020, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290, + 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078, + 0x3562, 0x701b, 0x2c24, 0x007c, 0x6834, 0xa084, 0x00ff, 0xa096, + 0x0002, 0x0040, 0x2c2f, 0xa096, 0x000a, 0x00c0, 0x2b56, 0x0078, + 0x2c06, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x436e, + 0x00c0, 0x2c3f, 0x7007, 0x0003, 0x701b, 0x2c41, 0x007c, 0x1078, + 0x4a60, 0x127e, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xa388, + 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, + 0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x127f, 0x0078, 0x3566, + 0x61a0, 0x7824, 0x60a2, 0x0078, 0x2b2c, 0x2091, 0x8000, 0x7823, + 0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009, + 0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, + 0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, + 0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, + 0x2071, 0x0010, 0x20c1, 0x00f0, 0xa08a, 0x0003, 0x00c8, 0x0427, + 0x0078, 0x0423, 0x81ff, 0x00c0, 0x2b56, 0x7924, 0x810f, 0xa18c, + 0x00ff, 0x1078, 0x4501, 0x00c0, 0x2b5a, 0x7e38, 0xa684, 0x3fff, + 0xa082, 0x4000, 0x0048, 0x2c9e, 0x0078, 0x2b5a, 0x7c28, 0x7d2c, + 0x1078, 0x46d6, 0xd28c, 0x00c0, 0x2ca9, 0x1078, 0x466a, 0x0078, + 0x2cab, 0x1078, 0x46a4, 0x00c0, 0x2cd5, 0x2061, 0xaa00, 0x127e, + 0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0040, 0x2cc3, 0x6010, + 0xa06d, 0x0040, 0x2cc3, 0x683c, 0xa406, 0x00c0, 0x2cc3, 0x6840, + 0xa506, 0x0040, 0x2cce, 0x127f, 0xace0, 0x0010, 0x2001, 0xa315, + 0x2004, 0xac02, 0x00c8, 0x2b56, 0x0078, 0x2caf, 0x1078, 0x8758, + 0x127f, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0xa00e, 0x2001, 0x0005, + 0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cc0, 0x1078, + 0x4982, 0x127f, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, + 0x3530, 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, + 0x46e4, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, + 0x1078, 0x3542, 0x0040, 0x2b5a, 0x1078, 0x475f, 0x0040, 0x2b56, + 0x2019, 0x0005, 0x1078, 0x4705, 0x0040, 0x2b56, 0x7828, 0xa08a, + 0x1000, 0x00c8, 0x2b5a, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, + 0x58e1, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x81ff, 0x0040, + 0x2d1d, 0x2009, 0x0001, 0x0078, 0x2d4e, 0x2029, 0x00ff, 0x644c, + 0x2400, 0xa506, 0x0040, 0x2d48, 0x2508, 0x1078, 0x4501, 0x00c0, + 0x2d48, 0x1078, 0x475f, 0x00c0, 0x2d33, 0x2009, 0x0002, 0x62a8, + 0x2518, 0x0078, 0x2d4e, 0x2019, 0x0004, 0x1078, 0x4705, 0x00c0, + 0x2d3d, 0x2009, 0x0006, 0x0078, 0x2d4e, 0x7824, 0xa08a, 0x1000, + 0x00c8, 0x2d51, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x58e1, + 0x8529, 0x00c8, 0x2d20, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, + 0x2b56, 0x127f, 0x0078, 0x2b5a, 0x1078, 0x3530, 0x0040, 0x2b5a, + 0x1078, 0x461b, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0, + 0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a, 0x1078, 0x460a, 0x1078, + 0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, + 0x0040, 0x2b5a, 0x1078, 0x46a7, 0x0040, 0x2b56, 0x1078, 0x43c1, + 0x1078, 0x4663, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530, + 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x62a0, 0x2019, + 0x0005, 0x0c7e, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e, + 0x2039, 0x0000, 0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38, + 0x077f, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530, 0x0040, + 0x2b5a, 0x1078, 0x46d6, 0x2208, 0x0078, 0x2b2c, 0x157e, 0x0d7e, + 0x0e7e, 0x2069, 0xa413, 0x6810, 0x6914, 0xa10a, 0x00c8, 0x2db2, + 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, + 0x00ff, 0x2069, 0xa434, 0x2d04, 0xa075, 0x0040, 0x2dc7, 0x704c, + 0x1078, 0x2dd1, 0xa210, 0x7080, 0x1078, 0x2dd1, 0xa318, 0x8d68, + 0x00f0, 0x2dbb, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078, + 0x2b2c, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x2de0, 0x2001, 0x0000, + 0x8000, 0x2f0c, 0x81ff, 0x0040, 0x2de0, 0x2178, 0x0078, 0x2dd8, + 0x017f, 0x0f7f, 0x007c, 0x2069, 0xa413, 0x6910, 0x62a4, 0x0078, + 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x614c, 0xa190, 0x293f, 0x2214, + 0xa294, 0x00ff, 0x606c, 0xa084, 0xff00, 0xa215, 0x6368, 0x67c8, + 0xd79c, 0x0040, 0x2dff, 0x2031, 0x0001, 0x0078, 0x2e01, 0x2031, + 0x0000, 0x7e3a, 0x7f3e, 0x0078, 0x2b2c, 0x613c, 0x6240, 0x2019, + 0xa5a0, 0x231c, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x6134, + 0xa006, 0x2010, 0x2018, 0x127f, 0x0078, 0x2b2c, 0x1078, 0x3542, + 0x0040, 0x2b5a, 0x6244, 0x6338, 0x0078, 0x2b2c, 0x613c, 0x6240, + 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xa351, 0x831f, 0xa305, + 0x6816, 0x782c, 0x2069, 0xa5a0, 0x2d1c, 0x206a, 0x0078, 0x2b2c, + 0x017e, 0x127e, 0x2091, 0x8000, 0x7824, 0x6036, 0xd094, 0x0040, + 0x2e43, 0x7828, 0xa085, 0x0001, 0x2009, 0xa5a9, 0x200a, 0x2001, + 0xffff, 0x1078, 0x5975, 0x127f, 0x017f, 0x0078, 0x2b2c, 0x1078, + 0x3542, 0x0040, 0x2b5a, 0x7828, 0xa00d, 0x0040, 0x2b5a, 0x782c, + 0xa005, 0x0040, 0x2b5a, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078, + 0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, + 0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, + 0x00ff, 0x00c0, 0x2e70, 0x6030, 0xa085, 0xff00, 0x0078, 0x2e7f, + 0xa182, 0x007f, 0x00c8, 0x2ea9, 0xa188, 0x293f, 0x210c, 0xa18c, + 0x00ff, 0x6030, 0xa116, 0x0040, 0x2ea9, 0x810f, 0xa105, 0x127e, + 0x2091, 0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2ea5, + 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040, + 0x2eac, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032, + 0x1078, 0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, + 0x2b56, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2ea5, + 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0c7e, + 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, + 0x00c0, 0x2ec7, 0x6030, 0xa085, 0xff00, 0x0078, 0x2ed6, 0xa182, + 0x007f, 0x00c8, 0x2f00, 0xa188, 0x293f, 0x210c, 0xa18c, 0x00ff, + 0x6030, 0xa116, 0x0040, 0x2f00, 0x810f, 0xa105, 0x127e, 0x2091, + 0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2efc, 0x601a, + 0x600b, 0xbc05, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040, 0x2f03, + 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, + 0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2b56, + 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2efc, 0x6830, + 0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x2061, 0xa62d, + 0x127e, 0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2f1c, 0x6104, + 0x6208, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x81ff, + 0x00c0, 0x2b56, 0x127e, 0x2091, 0x8000, 0x6244, 0x6060, 0xa202, + 0x0048, 0x2f33, 0xa085, 0x0001, 0x1078, 0x2500, 0x1078, 0x3bf5, + 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x127e, 0x2091, + 0x8000, 0x20a9, 0x0011, 0x2001, 0xa340, 0x20a0, 0xa006, 0x40a4, + 0x127f, 0x0078, 0x2b2c, 0x7d38, 0x7c3c, 0x0078, 0x2bde, 0x7824, + 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x2b56, 0x624c, 0xa084, + 0xff00, 0x8007, 0xa206, 0x00c0, 0x2f5f, 0x2001, 0xa340, 0x2009, + 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566, 0x81ff, + 0x00c0, 0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518, + 0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, + 0x1078, 0x8b85, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x2f81, + 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0xad80, 0x000e, + 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566, + 0x1078, 0x3518, 0x0040, 0x2b56, 0x1078, 0x421a, 0x2009, 0x001c, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x2fa1, + 0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040, 0x2b5a, 0x6804, + 0xd0ac, 0x0040, 0x2fae, 0xd0a4, 0x0040, 0x2b5a, 0xd094, 0x0040, + 0x2fb9, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c, 0xffdf, 0x6106, + 0x0c7f, 0xd08c, 0x0040, 0x2fc4, 0x0c7e, 0x2061, 0x0100, 0x6104, + 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100, 0x210c, 0xa18a, + 0x0002, 0x0048, 0x2fd9, 0xd084, 0x0040, 0x2fd9, 0x6a28, 0xa28a, + 0x007f, 0x00c8, 0x2b5a, 0xa288, 0x293f, 0x210c, 0xa18c, 0x00ff, + 0x6152, 0xd0dc, 0x0040, 0x2fe2, 0x6828, 0xa08a, 0x007f, 0x00c8, + 0x2b5a, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0048, 0x2b5a, 0xa08a, + 0x0841, 0x00c8, 0x2b5a, 0xa084, 0x0007, 0x00c0, 0x2b5a, 0x680c, + 0xa005, 0x0040, 0x2b5a, 0x6810, 0xa005, 0x0040, 0x2b5a, 0x6848, + 0x6940, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x684c, + 0x6944, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x6804, + 0xd0fc, 0x0040, 0x3038, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, + 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, 0x0038, 0xa399, + 0x0000, 0x1078, 0x3562, 0x701b, 0x301e, 0x007c, 0xade8, 0x000d, + 0x20a9, 0x0014, 0x2d98, 0x2069, 0xa36d, 0x2da0, 0x53a3, 0x7010, + 0xa0e8, 0x000d, 0x2001, 0xa371, 0x200c, 0xd1e4, 0x0040, 0x3038, + 0x0c7e, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00, 0x6006, 0x0c7f, + 0x20a9, 0x001c, 0x2d98, 0x2069, 0xa351, 0x2da0, 0x53a3, 0x6814, + 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, 0x00ff, 0x6042, 0x1078, + 0x4dbd, 0x1078, 0x48dd, 0x1078, 0x494d, 0x6000, 0xa086, 0x0000, + 0x00c0, 0x30c3, 0x6808, 0x602a, 0x1078, 0x218b, 0x6818, 0x691c, + 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, + 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x3070, 0x6830, 0x6934, + 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0078, 0x3072, + 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x1078, 0x59a8, + 0x6904, 0xd1fc, 0x0040, 0x30a5, 0x0c7e, 0x2009, 0x0000, 0x20a9, + 0x0001, 0x6b70, 0xd384, 0x0040, 0x30a2, 0x0078, 0x308c, 0x839d, + 0x00c8, 0x30a2, 0x3508, 0x8109, 0x1078, 0x5364, 0x6878, 0x6016, + 0x6874, 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff, + 0x6006, 0x8108, 0x00c0, 0x30a0, 0x6003, 0x0003, 0x0078, 0x30a2, + 0x6003, 0x0001, 0x00f0, 0x3087, 0x0c7f, 0x0c7e, 0x2061, 0x0100, + 0x602f, 0x0040, 0x602f, 0x0000, 0x0c7f, 0x1078, 0x3784, 0x0040, + 0x30b3, 0x1078, 0x2500, 0x60bc, 0xa005, 0x0040, 0x30bf, 0x6003, + 0x0001, 0x2091, 0x301d, 0x1078, 0x4171, 0x0078, 0x30c3, 0x6003, + 0x0004, 0x2091, 0x301d, 0x0078, 0x2b2c, 0x6000, 0xa086, 0x0000, + 0x0040, 0x2b56, 0x2069, 0xa351, 0x7830, 0x6842, 0x7834, 0x6846, + 0x6804, 0xd0fc, 0x0040, 0x30d8, 0x2009, 0x0030, 0x0078, 0x30da, + 0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, + 0x3566, 0xa006, 0x1078, 0x2500, 0x81ff, 0x00c0, 0x2b56, 0x1078, + 0x421a, 0x1078, 0x4171, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, + 0x6180, 0x81ff, 0x0040, 0x3107, 0x703f, 0x0000, 0x2001, 0xa9c0, + 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x127e, 0x2091, + 0x8000, 0x1078, 0x3566, 0x701b, 0x2b29, 0x127f, 0x007c, 0x703f, + 0x0001, 0x0d7e, 0x2069, 0xa9c0, 0x20a9, 0x0040, 0x20a1, 0xa9c0, + 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x293f, 0x210c, 0xa18c, + 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506, 0x0040, + 0x3139, 0x1078, 0x4501, 0x00c0, 0x3139, 0x6014, 0x821c, 0x0048, + 0x3131, 0xa398, 0xa9c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0078, + 0x3138, 0xa398, 0xa9c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a, + 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x3140, 0x0078, 0x311d, + 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, 0x20a9, 0x0040, + 0x20a1, 0xa9c0, 0x2099, 0xa9c0, 0x1078, 0x41be, 0x0078, 0x30f6, + 0x1078, 0x3542, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f, + 0x00c0, 0x315e, 0x2009, 0x0002, 0x0078, 0x2b56, 0x2001, 0xa352, + 0x2004, 0xd0b4, 0x0040, 0x3185, 0x6000, 0xd08c, 0x00c0, 0x3185, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3185, 0x6837, + 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8bd9, 0x00c0, 0x317c, + 0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3181, + 0x007c, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x20a9, 0x002b, 0x2c98, + 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, + 0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x41be, 0x20a9, 0x0004, + 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x1078, 0x41be, + 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, + 0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a, + 0x1078, 0x46ef, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x7828, + 0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x1078, 0x3542, 0x0040, 0x2b5a, + 0x1078, 0x475f, 0x0040, 0x2b56, 0x2019, 0x0004, 0x1078, 0x4705, + 0x7924, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x0078, 0x2b2c, 0xa186, + 0x00ff, 0x0040, 0x31d7, 0x1078, 0x31e7, 0x0078, 0x31e6, 0x2029, + 0x007e, 0x2061, 0xa300, 0x644c, 0x2400, 0xa506, 0x0040, 0x31e3, + 0x2508, 0x1078, 0x31e7, 0x8529, 0x00c8, 0x31dc, 0x007c, 0x1078, + 0x4501, 0x00c0, 0x31f2, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, + 0x1078, 0x58e1, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, + 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46fa, + 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040, + 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46e4, 0x0078, + 0x2b2c, 0x6100, 0x0078, 0x2b2c, 0x1078, 0x3542, 0x0040, 0x2b5a, + 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0d7e, + 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x3228, 0xace8, 0x0006, + 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, + 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, 0x2b2c, + 0xa006, 0x1078, 0x2500, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff, + 0x0040, 0x3245, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x421a, 0x7828, + 0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x7924, 0xa18c, 0xff00, 0x810f, + 0xa186, 0x00ff, 0x0040, 0x325b, 0xa182, 0x007f, 0x00c8, 0x2b5a, + 0x2100, 0x1078, 0x24fa, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, + 0x2061, 0xa5be, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x0100, + 0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090, + 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078, 0x596c, + 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x127f, + 0x0c7f, 0x027f, 0x0078, 0x2b2c, 0x7924, 0xa18c, 0xff00, 0x810f, + 0x0c7e, 0x1078, 0x4499, 0x2c08, 0x0c7f, 0x00c0, 0x2b5a, 0x0078, + 0x2b2c, 0x81ff, 0x0040, 0x3298, 0x2009, 0x0001, 0x0078, 0x2b56, + 0x60c8, 0xd09c, 0x00c0, 0x32a0, 0x2009, 0x0005, 0x0078, 0x2b56, + 0x1078, 0x3518, 0x00c0, 0x32a8, 0x2009, 0x0002, 0x0078, 0x2b56, + 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, + 0x32b2, 0x007c, 0x2009, 0x0080, 0x1078, 0x4501, 0x00c0, 0x32bf, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x32c3, 0x2021, + 0x400a, 0x0078, 0x2b2e, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08, + 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040, + 0x3336, 0xa0be, 0x0112, 0x0040, 0x3336, 0xa0be, 0x0113, 0x0040, + 0x3336, 0xa0be, 0x0114, 0x0040, 0x3336, 0xa0be, 0x0117, 0x0040, + 0x3336, 0xa0be, 0x011a, 0x0040, 0x3336, 0xa0be, 0x0121, 0x0040, + 0x332c, 0xa0be, 0x0131, 0x0040, 0x332c, 0xa0be, 0x0171, 0x0040, + 0x3336, 0xa0be, 0x0173, 0x0040, 0x3336, 0xa0be, 0x01a1, 0x00c0, + 0x32fe, 0x6830, 0x8007, 0x6832, 0x0078, 0x333c, 0xa0be, 0x0212, + 0x0040, 0x3332, 0xa0be, 0x0213, 0x0040, 0x3332, 0xa0be, 0x0214, + 0x0040, 0x3324, 0xa0be, 0x0217, 0x0040, 0x331e, 0xa0be, 0x021a, + 0x00c0, 0x3317, 0x6838, 0x8007, 0x683a, 0x0078, 0x3336, 0xa0be, + 0x0300, 0x0040, 0x3336, 0x0d7f, 0x0078, 0x2b5a, 0xad80, 0x0010, + 0x20a9, 0x0007, 0x1078, 0x337e, 0xad80, 0x000e, 0x20a9, 0x0001, + 0x1078, 0x337e, 0x0078, 0x3336, 0xad80, 0x000c, 0x1078, 0x338c, + 0x0078, 0x333c, 0xad80, 0x000e, 0x1078, 0x338c, 0xad80, 0x000c, + 0x20a9, 0x0001, 0x1078, 0x337e, 0x0c7e, 0x1078, 0x3518, 0x0040, + 0x336f, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853, 0x0000, + 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883, 0x0000, + 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000, 0x0c7f, + 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, + 0x6804, 0x2068, 0x1078, 0x8ba1, 0x00c0, 0x336a, 0x2009, 0x0003, + 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3375, 0x007c, 0x0c7f, + 0x0d7f, 0x2009, 0x0002, 0x0078, 0x2b56, 0x6820, 0xa086, 0x8001, + 0x00c0, 0x2b2c, 0x2009, 0x0004, 0x0078, 0x2b56, 0x017e, 0x2008, + 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108, + 0x00f0, 0x3380, 0x017f, 0x007c, 0x017e, 0x0a7e, 0x0b7e, 0x2008, + 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a, + 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x0b7f, 0x0a7f, + 0x017f, 0x007c, 0x81ff, 0x0040, 0x33a9, 0x2009, 0x0001, 0x0078, + 0x2b56, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, + 0x0048, 0x2b5a, 0xa182, 0x00ff, 0x00c8, 0x2b5a, 0x7a2c, 0x7b28, + 0x6068, 0xa306, 0x00c0, 0x33c4, 0x606c, 0xa24e, 0x0040, 0x2b5a, + 0xa9cc, 0xff00, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x346d, 0x2c68, + 0x0c7f, 0x0040, 0x33fc, 0xa0c6, 0x4000, 0x00c0, 0x33e2, 0x0c7e, + 0x007e, 0x2d60, 0x2009, 0x0000, 0x1078, 0x47cb, 0x00c0, 0x33d9, + 0xc185, 0x6000, 0xd0bc, 0x0040, 0x33de, 0xc18d, 0x007f, 0x0c7f, + 0x0078, 0x33f9, 0xa0c6, 0x4007, 0x00c0, 0x33e9, 0x2408, 0x0078, + 0x33f9, 0xa0c6, 0x4008, 0x00c0, 0x33f1, 0x2708, 0x2610, 0x0078, + 0x33f9, 0xa0c6, 0x4009, 0x00c0, 0x33f7, 0x0078, 0x33f9, 0x2001, + 0x4006, 0x2020, 0x0078, 0x2b2e, 0x2d00, 0x7022, 0x017e, 0x0b7e, + 0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x74d7, 0x0040, 0x3442, 0x2d00, + 0x601a, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x2e58, + 0x0e7f, 0x0e7e, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2b70, 0x00c0, + 0x3423, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x2009, + 0x0002, 0x0078, 0x2b56, 0x6837, 0x0000, 0x2d00, 0x6012, 0x6833, + 0x0000, 0x6838, 0xc0fd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, + 0x2813, 0x127f, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b, + 0x2001, 0x0002, 0x1078, 0x443f, 0x2009, 0x0002, 0x1078, 0x756c, + 0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x00c0, 0x344c, + 0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3451, + 0x007c, 0x6830, 0xa086, 0x0100, 0x7020, 0x2060, 0x00c0, 0x345f, + 0x2009, 0x0004, 0x6204, 0xa294, 0x00ff, 0x0078, 0x2b56, 0x2009, + 0x0000, 0x1078, 0x47cb, 0x00c0, 0x3466, 0xc185, 0x6000, 0xd0bc, + 0x0040, 0x346b, 0xc18d, 0x0078, 0x2b2c, 0x0e7e, 0x0d7e, 0x2029, + 0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xa4b4, 0x2e04, + 0xa005, 0x00c0, 0x3482, 0x2100, 0xa406, 0x00c0, 0x34b3, 0x2428, + 0x0078, 0x34b3, 0x2068, 0x6f10, 0x2700, 0xa306, 0x00c0, 0x34a4, + 0x6e14, 0x2600, 0xa206, 0x00c0, 0x34a4, 0x2400, 0xa106, 0x00c0, + 0x34a0, 0x2d60, 0xd884, 0x0040, 0x34c8, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x00c0, 0x34c8, 0x2001, 0x4000, 0x0078, 0x34c9, + 0x2001, 0x4007, 0x0078, 0x34c9, 0x2400, 0xa106, 0x00c0, 0x34b3, + 0x6e14, 0x87ff, 0x00c0, 0x34af, 0x86ff, 0x0040, 0x347f, 0x2001, + 0x4008, 0x0078, 0x34c9, 0x8420, 0x8e70, 0x00f0, 0x3477, 0x85ff, + 0x00c0, 0x34c2, 0x2001, 0x4009, 0x0078, 0x34c9, 0x2001, 0x0001, + 0x0078, 0x34c9, 0x1078, 0x4499, 0x00c0, 0x34be, 0x6312, 0x6216, + 0xa006, 0xa005, 0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x2b56, + 0x1078, 0x3518, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x7824, 0xa005, 0x0040, 0x2b5a, 0xa096, 0x00ff, 0x0040, + 0x34e5, 0xa092, 0x0004, 0x00c8, 0x2b5a, 0x2010, 0x2d18, 0x1078, + 0x27c2, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x34f0, 0x007c, + 0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x7924, + 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, 0x2b5a, 0xa182, + 0x00ff, 0x00c8, 0x2b5a, 0x127e, 0x2091, 0x8000, 0x1078, 0x8a89, + 0x00c0, 0x3515, 0xa190, 0xa434, 0x2204, 0xa065, 0x0040, 0x3515, + 0x1078, 0x4235, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b56, + 0x1078, 0x1381, 0x0040, 0x352f, 0xa006, 0x6802, 0x7010, 0xa005, + 0x00c0, 0x3527, 0x2d00, 0x7012, 0x7016, 0x0078, 0x352d, 0x7014, + 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x007c, + 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501, 0x00c0, 0x353f, + 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x3540, 0xa066, + 0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, 0x4501, + 0x00c0, 0x3550, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, 0x3551, + 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, 0x355e, + 0x2168, 0x6904, 0x1078, 0x139a, 0x0078, 0x3555, 0x7112, 0x7116, + 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x3568, 0x2031, 0x0000, + 0x2061, 0xa3d1, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e, + 0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x2b2c, + 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, + 0xa38f, 0x2004, 0xa005, 0x00c0, 0x3594, 0x0068, 0x3594, 0x7818, + 0xd084, 0x00c0, 0x3594, 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001, + 0x2091, 0x4080, 0x0078, 0x35b9, 0x017e, 0x0c7e, 0x0e7e, 0x2071, + 0xa381, 0x7138, 0xa182, 0x0008, 0x0048, 0x35a2, 0x7030, 0x2060, + 0x0078, 0x35b3, 0x7030, 0xa0e0, 0x0008, 0xac82, 0xa3d1, 0x0048, + 0x35ab, 0x2061, 0xa391, 0x2c00, 0x7032, 0x81ff, 0x00c0, 0x35b1, + 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, 0x0c7f, + 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0xa381, 0x7038, + 0xa005, 0x0040, 0x35f5, 0x127e, 0x2091, 0x8000, 0x0068, 0x35f4, + 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x35f3, 0x0c7e, + 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, 0x782a, + 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005, + 0x00c0, 0x35e9, 0x7033, 0xa391, 0x7037, 0xa391, 0x0c7f, 0x0078, + 0x35f3, 0xac80, 0x0008, 0xa0fa, 0xa3d1, 0x0048, 0x35f1, 0x2001, + 0xa391, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, 0x027e, + 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x3602, 0x2011, 0x8014, + 0x1078, 0x3579, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x127e, + 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x1078, + 0x4171, 0x127f, 0x0078, 0x2b2c, 0x7824, 0x2008, 0xa18c, 0xfffd, + 0x00c0, 0x361f, 0x61d4, 0xa10d, 0x61d6, 0x0078, 0x2b2c, 0x0078, + 0x2b5a, 0x81ff, 0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x00c0, + 0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x2b56, 0x1078, + 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x00c0, 0x363e, 0x7828, 0xa005, 0x0040, 0x2b2c, 0x0c7e, 0x1078, + 0x3518, 0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6833, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8c4d, 0x0040, 0x2b56, 0x7007, + 0x0003, 0x701b, 0x3654, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, + 0x2b56, 0x0078, 0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, + 0x00c0, 0x2b56, 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, + 0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, + 0x0000, 0x702f, 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078, + 0x4501, 0x00c0, 0x36d8, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, + 0x0040, 0x3688, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x00c0, 0x36d8, + 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x3695, 0x1078, 0x47cb, + 0x00c0, 0x3695, 0xd79c, 0x0040, 0x36d8, 0xd794, 0x00c0, 0x369b, + 0xd784, 0x0040, 0x36a7, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, + 0x0004, 0x53a3, 0x1078, 0x338c, 0xd794, 0x0040, 0x36b0, 0xac80, + 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x338c, + 0x21a2, 0xd794, 0x0040, 0x36d0, 0xac80, 0x0000, 0x2098, 0x94a0, + 0x20a9, 0x0002, 0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, + 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x53a3, 0x1078, 0x337e, + 0xac80, 0x0026, 0x2098, 0x20a9, 0x0002, 0x53a3, 0x0078, 0x36d1, + 0x94a0, 0xd794, 0x0040, 0x36d6, 0xa6b0, 0x000b, 0xa6b0, 0x0005, + 0x8108, 0xd78c, 0x0040, 0x36e2, 0xa186, 0x0100, 0x0040, 0x36f3, + 0x0078, 0x36e6, 0xa186, 0x007e, 0x0040, 0x36f3, 0xd794, 0x0040, + 0x36ed, 0xa686, 0x0020, 0x0078, 0x36ef, 0xa686, 0x0028, 0x0040, + 0x36fc, 0x0078, 0x3677, 0x86ff, 0x00c0, 0x36fa, 0x7120, 0x810b, + 0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, + 0x772a, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, + 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007, + 0x0002, 0x701b, 0x3714, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3726, + 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0xa3d1, + 0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3677, 0x7120, 0x810b, + 0x0078, 0x2b2c, 0x2029, 0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38, + 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, + 0x0048, 0x2b5a, 0xa184, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a, + 0xa502, 0x0048, 0x2b5a, 0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020, + 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa284, 0x00ff, 0xa0e2, + 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa384, 0xff00, + 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, + 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, + 0x2b5a, 0xa484, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, + 0xa502, 0x0048, 0x2b5a, 0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048, + 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0x2061, 0xa5a3, 0x6102, 0x6206, + 0x630a, 0x640e, 0x0078, 0x2b2c, 0x007e, 0x2001, 0xa352, 0x2004, + 0xd0cc, 0x007f, 0x007c, 0x007e, 0x2001, 0xa371, 0x2004, 0xd0bc, + 0x007f, 0x007c, 0x6160, 0x7a24, 0x6300, 0x82ff, 0x00c0, 0x379b, + 0x7926, 0x0078, 0x2b2c, 0x83ff, 0x00c0, 0x2b5a, 0x2001, 0xfff0, + 0xa200, 0x00c8, 0x2b5a, 0x2019, 0xffff, 0x6064, 0xa302, 0xa200, + 0x0048, 0x2b5a, 0x7926, 0x6262, 0x0078, 0x2b2c, 0x2001, 0xa300, + 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x7c28, 0x7d24, 0x7e38, + 0x7f2c, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2019, + 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, 0x7026, + 0x20a0, 0xa1e0, 0xa434, 0x2c64, 0x8cff, 0x0040, 0x37e8, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x37dd, 0x6004, 0xa084, + 0xff00, 0xa086, 0x0600, 0x00c0, 0x37e8, 0x6014, 0x20a2, 0x94a0, + 0x6010, 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, + 0x8108, 0xa182, 0x00ff, 0x0040, 0x37f3, 0xa386, 0x002a, 0x0040, + 0x37fc, 0x0078, 0x37c9, 0x83ff, 0x00c0, 0x37fa, 0x7120, 0x810c, + 0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022, + 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426, + 0x652a, 0x662e, 0x6732, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, + 0x701b, 0x3813, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3824, 0x711c, + 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xa3d1, 0x6424, 0x6528, + 0x662c, 0x6730, 0x0078, 0x37c9, 0x7120, 0x810c, 0x0078, 0x2b2c, + 0x81ff, 0x00c0, 0x2b56, 0x60c8, 0xd09c, 0x0040, 0x2b56, 0x1078, + 0x3518, 0x0040, 0x2b56, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x1078, 0x3562, 0x701b, 0x383d, 0x007c, 0x0d7e, 0xade8, 0x000d, + 0x6828, 0xa0be, 0x7000, 0x0040, 0x3850, 0xa0be, 0x7100, 0x0040, + 0x3850, 0xa0be, 0x7200, 0x0040, 0x3850, 0x0d7f, 0x0078, 0x2b5a, + 0x6820, 0x6924, 0x1078, 0x24e3, 0x00c0, 0x387b, 0x1078, 0x4499, + 0x00c0, 0x387b, 0x7122, 0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078, + 0x3518, 0x0040, 0x387b, 0x1078, 0x3518, 0x0040, 0x387b, 0x0c7f, + 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, + 0x6804, 0x2068, 0x1078, 0x8bbd, 0x0040, 0x2b56, 0x7007, 0x0003, + 0x701b, 0x387e, 0x007c, 0x0d7f, 0x0078, 0x2b56, 0x7120, 0x1078, + 0x2921, 0x6820, 0xa086, 0x8001, 0x0040, 0x2b56, 0x2d00, 0x701e, + 0x6804, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, + 0x1078, 0x41be, 0x007f, 0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, + 0x6d14, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, + 0x7000, 0x00c0, 0x38a5, 0x0078, 0x38a9, 0xa7c6, 0x7100, 0x00c0, + 0x38b1, 0xa6c2, 0x0004, 0x0048, 0x2b5a, 0x2009, 0x0004, 0x0078, + 0x3566, 0xa7c6, 0x7200, 0x00c0, 0x2b5a, 0xa6c2, 0x0054, 0x0048, + 0x2b5a, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, 0x6532, + 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x38c8, 0x007c, + 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, + 0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x41be, 0x007f, + 0x2009, 0x002a, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530, + 0x0078, 0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040, + 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x4710, 0x0078, + 0x2b2c, 0x7824, 0xd084, 0x0040, 0x3150, 0x1078, 0x3542, 0x0040, + 0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x00c0, 0x3903, 0x2009, + 0x0002, 0x0078, 0x2b56, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x0040, 0x3910, 0xa08e, 0x0004, 0x0040, 0x3910, 0xa08e, 0x0005, + 0x00c0, 0x3934, 0x2001, 0xa352, 0x2004, 0xd0b4, 0x0040, 0x3185, + 0x6000, 0xd08c, 0x00c0, 0x3185, 0x6837, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x1078, 0x8bd9, 0x00c0, 0x3929, 0x2009, 0x0003, 0x0078, + 0x2b56, 0x7007, 0x0003, 0x701b, 0x392e, 0x007c, 0x1078, 0x3542, + 0x0040, 0x2b5a, 0x0078, 0x3185, 0x2009, 0xa32e, 0x210c, 0x81ff, + 0x0040, 0x393e, 0x2009, 0x0001, 0x0078, 0x2b56, 0x2001, 0xa300, + 0x2004, 0xa086, 0x0003, 0x0040, 0x3949, 0x2009, 0x0007, 0x0078, + 0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x0040, 0x3953, 0x2009, + 0x0008, 0x0078, 0x2b56, 0x609c, 0xd0a4, 0x00c0, 0x395a, 0xd0ac, + 0x00c0, 0x3185, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x1078, 0x8c4d, 0x00c0, 0x3969, 0x2009, 0x0003, 0x0078, + 0x2b56, 0x7007, 0x0003, 0x701b, 0x396e, 0x007c, 0x6830, 0xa086, + 0x0100, 0x00c0, 0x3977, 0x2009, 0x0004, 0x0078, 0x2b56, 0x1078, + 0x3542, 0x0040, 0x2b5a, 0x0078, 0x3912, 0x81ff, 0x2009, 0x0001, + 0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, + 0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x00c0, + 0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x2009, 0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078, + 0x3518, 0x0c7f, 0x2009, 0x0002, 0x0040, 0x2b56, 0x6837, 0x0000, + 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, + 0xa18c, 0x00ff, 0xa006, 0x82ff, 0x00c0, 0x39bc, 0xc0ed, 0x6952, + 0x792c, 0x6956, 0x0078, 0x39c5, 0xa28e, 0x0100, 0x00c0, 0x2b5a, + 0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000, 0x683e, 0x1078, 0x8df6, + 0x2009, 0x0003, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x39d1, + 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040, 0x2b56, + 0x0078, 0x2b2c, 0x81ff, 0x2009, 0x0001, 0x00c0, 0x2b56, 0x6000, + 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, 0x2b56, 0x1078, 0x3542, + 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x2009, + 0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2009, + 0x0002, 0x0040, 0x2b56, 0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c, + 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x3a08, 0x007c, + 0x0d7e, 0xade8, 0x000f, 0x6800, 0xa086, 0x0500, 0x00c0, 0x3a1b, + 0x6804, 0xa005, 0x00c0, 0x3a1b, 0x6808, 0xa084, 0xff00, 0x00c0, + 0x3a1b, 0x0078, 0x3a1e, 0x0d7f, 0x00c0, 0x2b5a, 0x0d7f, 0x6837, + 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0c7e, 0x1078, + 0x3542, 0x00c0, 0x3a2e, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x8e52, + 0x2009, 0x0003, 0x0c7f, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, + 0x3a3a, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040, + 0x2b56, 0x0078, 0x2b2c, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100, + 0x2071, 0xa300, 0x6044, 0xd0a4, 0x00c0, 0x3a6c, 0xd084, 0x0040, + 0x3a55, 0x1078, 0x3bcc, 0x0078, 0x3a68, 0xd08c, 0x0040, 0x3a5c, + 0x1078, 0x3ae3, 0x0078, 0x3a68, 0xd094, 0x0040, 0x3a63, 0x1078, + 0x3ab7, 0x0078, 0x3a68, 0xd09c, 0x0040, 0x3a68, 0x1078, 0x3a76, + 0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0, + 0x3a73, 0xc19d, 0x612a, 0x017f, 0x0078, 0x3a68, 0x624c, 0xa286, + 0xf0f0, 0x00c0, 0x3a87, 0x6048, 0xa086, 0xf0f0, 0x0040, 0x3a87, + 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x3ab6, 0xa294, + 0xff00, 0xa296, 0xf700, 0x0040, 0x3a9c, 0x7134, 0xd1a4, 0x00c0, + 0x3a9c, 0x6240, 0xa294, 0x0010, 0x0040, 0x3a9c, 0x2009, 0x00f7, + 0x1078, 0x41de, 0x0078, 0x3ab6, 0x6043, 0x0040, 0x6043, 0x0000, + 0x7073, 0x0000, 0x708b, 0x0001, 0x70af, 0x0000, 0x70cb, 0x0000, + 0x2009, 0xa9c0, 0x200b, 0x0000, 0x7083, 0x0000, 0x7077, 0x000f, + 0x2009, 0x000f, 0x2011, 0x4122, 0x1078, 0x596c, 0x007c, 0x157e, + 0x7074, 0xa005, 0x00c0, 0x3ae1, 0x2011, 0x4122, 0x1078, 0x58d4, + 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8, + 0x6044, 0xd08c, 0x00c0, 0x3ada, 0x00f0, 0x3ac8, 0x6242, 0x7087, + 0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242, + 0x0078, 0x3ae1, 0x6242, 0x7087, 0x0000, 0x707b, 0x0000, 0x0078, + 0x3ae1, 0x157f, 0x007c, 0x7078, 0xa08a, 0x0003, 0x00c8, 0x3aec, + 0x1079, 0x3aef, 0x0078, 0x3aee, 0x1078, 0x1328, 0x007c, 0x3af2, + 0x3b41, 0x3bcb, 0x0f7e, 0x707b, 0x0001, 0x20e1, 0xa000, 0x20e1, + 0x8700, 0x1078, 0x218b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079, + 0xa800, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, 0x780f, + 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, 0x781f, + 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, 0x782f, + 0x0000, 0x2079, 0xa80c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099, + 0xa305, 0x20a1, 0xa80e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0xa812, + 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xa800, 0x20a1, 0x020b, + 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x1078, + 0x4158, 0x0f7f, 0x707f, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000, + 0x007c, 0x0d7e, 0x707c, 0x707f, 0x0000, 0xa025, 0x0040, 0x3bb5, + 0x6020, 0xd0b4, 0x00c0, 0x3bb3, 0x7188, 0x81ff, 0x0040, 0x3ba2, + 0xa486, 0x000c, 0x00c0, 0x3bad, 0xa480, 0x0018, 0x8004, 0x20a8, + 0x2011, 0xa880, 0x2019, 0xa800, 0x220c, 0x2304, 0xa106, 0x00c0, + 0x3b79, 0x8210, 0x8318, 0x00f0, 0x3b5c, 0x6043, 0x0004, 0x608b, + 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707b, 0x0002, 0x7087, + 0x0002, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c, 0x0078, + 0x3bb3, 0x2069, 0xa880, 0x6930, 0xa18e, 0x1101, 0x00c0, 0x3bad, + 0x6834, 0xa005, 0x00c0, 0x3bad, 0x6900, 0xa18c, 0x00ff, 0x00c0, + 0x3b8d, 0x6804, 0xa005, 0x0040, 0x3ba2, 0x2011, 0xa88e, 0x2019, + 0xa305, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048, 0x3ba0, + 0x00c0, 0x3bad, 0x8210, 0x8318, 0x00f0, 0x3b93, 0x0078, 0x3bad, + 0x708b, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, + 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, 0x6043, + 0x0000, 0x0078, 0x3bb5, 0x0d7f, 0x007c, 0x6020, 0xd0b4, 0x00c0, + 0x3bb3, 0x60c3, 0x000c, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f, + 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078, + 0x6c38, 0x0078, 0x3bb3, 0x007c, 0x7084, 0xa08a, 0x001d, 0x00c8, + 0x3bd5, 0x1079, 0x3bd8, 0x0078, 0x3bd7, 0x1078, 0x1328, 0x007c, + 0x3c02, 0x3c11, 0x3c40, 0x3c59, 0x3c85, 0x3cb1, 0x3cdd, 0x3d13, + 0x3d3f, 0x3d67, 0x3daa, 0x3dd4, 0x3df6, 0x3e0c, 0x3e32, 0x3e45, + 0x3e4e, 0x3e7e, 0x3eaa, 0x3ed6, 0x3f02, 0x3f38, 0x3f7d, 0x3fac, + 0x3fce, 0x4010, 0x4036, 0x404f, 0x4050, 0x0c7e, 0x2061, 0xa300, + 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006, + 0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002, + 0x7087, 0x0001, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c, + 0x007c, 0x0f7e, 0x707c, 0xa086, 0x0014, 0x00c0, 0x3c3e, 0x6043, + 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3c3e, 0x2079, 0xa880, 0x7a30, + 0xa296, 0x1102, 0x00c0, 0x3c3c, 0x7834, 0xa005, 0x00c0, 0x3c3c, + 0x7a38, 0xd2fc, 0x0040, 0x3c32, 0x70ac, 0xa005, 0x00c0, 0x3c32, + 0x70af, 0x0001, 0x2011, 0x4129, 0x1078, 0x58d4, 0x7087, 0x0010, + 0x1078, 0x3e4e, 0x0078, 0x3c3e, 0x1078, 0x4171, 0x0f7f, 0x007c, + 0x7087, 0x0003, 0x6043, 0x0004, 0x2011, 0x4129, 0x1078, 0x58d4, + 0x1078, 0x41c6, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a, + 0x20a3, 0x0000, 0x00f0, 0x3c50, 0x60c3, 0x0014, 0x1078, 0x4158, + 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3c83, 0x2011, 0x4129, + 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3c81, 0x2079, 0xa880, + 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3c81, 0x7834, 0xa005, 0x00c0, + 0x3c81, 0x7a38, 0xd2fc, 0x0040, 0x3c7b, 0x70ac, 0xa005, 0x00c0, + 0x3c7b, 0x70af, 0x0001, 0x7087, 0x0004, 0x1078, 0x3c85, 0x0078, + 0x3c83, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0005, 0x1078, + 0x41c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, + 0x1078, 0x4211, 0x00c0, 0x3ca3, 0x7070, 0xa005, 0x00c0, 0x3ca3, + 0x714c, 0xa186, 0xffff, 0x0040, 0x3ca3, 0x1078, 0x40ea, 0x0040, + 0x3ca3, 0x1078, 0x41f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, + 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3cdb, 0x2011, 0x4129, + 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3cd9, 0x2079, 0xa880, + 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3cd9, 0x7834, 0xa005, 0x00c0, + 0x3cd9, 0x7a38, 0xd2fc, 0x0040, 0x3cd3, 0x70ac, 0xa005, 0x00c0, + 0x3cd3, 0x70af, 0x0001, 0x7087, 0x0006, 0x1078, 0x3cdd, 0x0078, + 0x3cdb, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0007, 0x1078, + 0x41c6, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, + 0x1078, 0x4211, 0x00c0, 0x3d05, 0x7070, 0xa005, 0x00c0, 0x3d05, + 0x7150, 0xa186, 0xffff, 0x0040, 0x3d05, 0xa180, 0x293f, 0x200c, + 0xa18c, 0xff00, 0x810f, 0x1078, 0x40ea, 0x0040, 0x3d05, 0x1078, + 0x378b, 0x0040, 0x3d05, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2298, + 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3d3d, + 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3d3b, + 0x2079, 0xa880, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3d3b, 0x7834, + 0xa005, 0x00c0, 0x3d3b, 0x7a38, 0xd2fc, 0x0040, 0x3d35, 0x70ac, + 0xa005, 0x00c0, 0x3d35, 0x70af, 0x0001, 0x7087, 0x0008, 0x1078, + 0x3d3f, 0x0078, 0x3d3d, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, + 0x0009, 0x1078, 0x41c6, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, + 0x1078, 0x4211, 0x00c0, 0x3d58, 0x7070, 0xa005, 0x00c0, 0x3d58, + 0x1078, 0x4051, 0x00c0, 0x3d62, 0xa085, 0x0001, 0x1078, 0x2500, + 0x20a9, 0x0008, 0x2099, 0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, + 0x707c, 0xa005, 0x0040, 0x3da8, 0x2011, 0x4129, 0x1078, 0x58d4, + 0xa086, 0x0014, 0x00c0, 0x3da6, 0x2079, 0xa880, 0x7a30, 0xa296, + 0x1105, 0x00c0, 0x3da6, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0, + 0x3d91, 0x7a38, 0xd2fc, 0x0040, 0x3d8b, 0x70ac, 0xa005, 0x00c0, + 0x3d8b, 0x70af, 0x0001, 0x7087, 0x000a, 0x1078, 0x3daa, 0x0078, + 0x3da8, 0xa005, 0x00c0, 0x3da6, 0x7a38, 0xd2fc, 0x0040, 0x3d9e, + 0x70ac, 0xa005, 0x00c0, 0x3d9e, 0x70af, 0x0001, 0x7083, 0x0000, + 0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3da8, 0x1078, 0x4171, + 0x0f7f, 0x007c, 0x7087, 0x000b, 0x2011, 0xa80e, 0x22a0, 0x20a9, + 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000, + 0x41a4, 0x1078, 0x41c6, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x1078, + 0x4211, 0x0040, 0x3dc7, 0x2013, 0x0000, 0x0078, 0x3dcb, 0x6030, + 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3, + 0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, + 0x3df4, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0, + 0x3df2, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3df2, + 0x7834, 0xa005, 0x00c0, 0x3df2, 0x7087, 0x000c, 0x1078, 0x3df6, + 0x0078, 0x3df4, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x000d, + 0x1078, 0x41c6, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099, 0xa88e, + 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, + 0x3e30, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0, + 0x3e2e, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3e2e, + 0x7834, 0xa005, 0x00c0, 0x3e2e, 0x7083, 0x0001, 0x1078, 0x41b8, + 0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3e30, 0x1078, 0x4171, + 0x0f7f, 0x007c, 0x7087, 0x000f, 0x707f, 0x0000, 0x608b, 0xbc85, + 0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, + 0x2011, 0x4129, 0x1078, 0x58c7, 0x007c, 0x707c, 0xa005, 0x0040, + 0x3e4d, 0x2011, 0x4129, 0x1078, 0x58d4, 0x007c, 0x7087, 0x0011, + 0x1078, 0x4211, 0x00c0, 0x3e67, 0x7168, 0x81ff, 0x0040, 0x3e67, + 0x2009, 0x0000, 0x706c, 0xa084, 0x00ff, 0x1078, 0x24e3, 0xa186, + 0x0080, 0x0040, 0x3e67, 0x2011, 0xa88e, 0x1078, 0x40ea, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x747c, + 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, + 0x53a6, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, + 0xa005, 0x0040, 0x3ea8, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, + 0x0014, 0x00c0, 0x3ea6, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1103, + 0x00c0, 0x3ea6, 0x7834, 0xa005, 0x00c0, 0x3ea6, 0x7a38, 0xd2fc, + 0x0040, 0x3ea0, 0x70ac, 0xa005, 0x00c0, 0x3ea0, 0x70af, 0x0001, + 0x7087, 0x0012, 0x1078, 0x3eaa, 0x0078, 0x3ea8, 0x1078, 0x4171, + 0x0f7f, 0x007c, 0x7087, 0x0013, 0x1078, 0x41d2, 0x20a3, 0x1103, + 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0, + 0x3ec8, 0x7070, 0xa005, 0x00c0, 0x3ec8, 0x714c, 0xa186, 0xffff, + 0x0040, 0x3ec8, 0x1078, 0x40ea, 0x0040, 0x3ec8, 0x1078, 0x41f5, + 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, + 0xa005, 0x0040, 0x3f00, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, + 0x0014, 0x00c0, 0x3efe, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1104, + 0x00c0, 0x3efe, 0x7834, 0xa005, 0x00c0, 0x3efe, 0x7a38, 0xd2fc, + 0x0040, 0x3ef8, 0x70ac, 0xa005, 0x00c0, 0x3ef8, 0x70af, 0x0001, + 0x7087, 0x0014, 0x1078, 0x3f02, 0x0078, 0x3f00, 0x1078, 0x4171, + 0x0f7f, 0x007c, 0x7087, 0x0015, 0x1078, 0x41d2, 0x20a3, 0x1104, + 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0, + 0x3f2a, 0x7070, 0xa005, 0x00c0, 0x3f2a, 0x7150, 0xa186, 0xffff, + 0x0040, 0x3f2a, 0xa180, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f, + 0x1078, 0x40ea, 0x0040, 0x3f2a, 0x1078, 0x378b, 0x0040, 0x3f2a, + 0x1078, 0x2500, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, + 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3f7b, 0x2011, 0x4129, 0x1078, + 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3f79, 0x2079, 0xa880, 0x7a30, + 0xa296, 0x1105, 0x00c0, 0x3f79, 0x7834, 0x2011, 0x0100, 0xa21e, + 0x00c0, 0x3f5e, 0x7a38, 0xd2fc, 0x0040, 0x3f5c, 0x70ac, 0xa005, + 0x00c0, 0x3f5c, 0x70af, 0x0001, 0x0078, 0x3f6d, 0xa005, 0x00c0, + 0x3f79, 0x7a38, 0xd2fc, 0x0040, 0x3f6b, 0x70ac, 0xa005, 0x00c0, + 0x3f6b, 0x70af, 0x0001, 0x7083, 0x0000, 0x7a38, 0xd2f4, 0x0040, + 0x3f73, 0x70cb, 0x0008, 0x7087, 0x0016, 0x1078, 0x3f7d, 0x0078, + 0x3f7b, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6, + 0x3430, 0x2011, 0xa88e, 0x7087, 0x0017, 0x1078, 0x4211, 0x00c0, + 0x3f9d, 0x7070, 0xa005, 0x00c0, 0x3f9d, 0x1078, 0x4051, 0x00c0, + 0x3fa7, 0xa085, 0x0001, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2099, + 0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, + 0x3fcc, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0, + 0x3fca, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3fca, + 0x7834, 0xa005, 0x00c0, 0x3fca, 0x7087, 0x0018, 0x1078, 0x3fce, + 0x0078, 0x3fcc, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0019, + 0x1078, 0x41d2, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, + 0xa88e, 0x2039, 0xa80e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x1078, + 0x4211, 0x00c0, 0x4002, 0x2728, 0x2514, 0x8207, 0xa084, 0x00ff, + 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, 0x6030, + 0x2310, 0x8214, 0xa2a0, 0xa80e, 0x2414, 0xa38c, 0x0001, 0x0040, + 0x3ffd, 0xa294, 0xff00, 0x0078, 0x4000, 0xa294, 0x00ff, 0x8007, + 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c, + 0x0f7e, 0x707c, 0xa005, 0x0040, 0x4034, 0x2011, 0x4129, 0x1078, + 0x58d4, 0xa086, 0x0084, 0x00c0, 0x4032, 0x2079, 0xa880, 0x7a30, + 0xa296, 0x1107, 0x00c0, 0x4032, 0x7834, 0xa005, 0x00c0, 0x4032, + 0x7083, 0x0001, 0x1078, 0x41b8, 0x7087, 0x001a, 0x1078, 0x4036, + 0x0078, 0x4034, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x001b, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, + 0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, + 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c, 0x007c, + 0x007c, 0x087e, 0x097e, 0x2029, 0xa352, 0x252c, 0x20a9, 0x0008, + 0x2041, 0xa80e, 0x28a0, 0x2099, 0xa88e, 0x53a3, 0x20a9, 0x0008, + 0x2011, 0x0007, 0xd5d4, 0x0040, 0x4067, 0x2011, 0x0000, 0x2800, + 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, 0x4079, 0xd5d4, 0x0040, + 0x4074, 0x8210, 0x0078, 0x4075, 0x8211, 0x00f0, 0x4067, 0x0078, + 0x40e1, 0x82ff, 0x00c0, 0x408b, 0xd5d4, 0x0040, 0x4085, 0xa1a6, + 0x3fff, 0x0040, 0x4071, 0x0078, 0x4089, 0xa1a6, 0x3fff, 0x0040, + 0x40e1, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, + 0x0040, 0x4094, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0040, 0x409b, + 0x8423, 0x0078, 0x409c, 0x8424, 0x00c8, 0x40a9, 0xd5d4, 0x0040, + 0x40a4, 0x8319, 0x0078, 0x40a5, 0x8318, 0x00f0, 0x4095, 0x0078, + 0x40e1, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x00f0, 0x40ad, + 0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, 0x40c1, 0x007e, 0x2039, + 0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, 0xa5a8, 0x0010, 0x00f0, + 0x40bd, 0x754e, 0xa5c8, 0x293f, 0x292c, 0xa5ac, 0x00ff, 0x6532, + 0x60e7, 0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x2018, 0x2304, + 0xa405, 0x201a, 0x7073, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, + 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0078, + 0x40e7, 0xa006, 0x0078, 0x40e7, 0xa006, 0x1078, 0x1328, 0x097f, + 0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, + 0x0010, 0x0048, 0x40f7, 0x8420, 0x8001, 0x0078, 0x40ef, 0x2118, + 0x84ff, 0x0040, 0x4100, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x40fb, + 0x2021, 0x0001, 0x83ff, 0x0040, 0x4109, 0x8423, 0x8319, 0x00c0, + 0x4105, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x4121, 0xa405, 0x203a, + 0x714e, 0xa1a0, 0x293f, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7, + 0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x7073, 0x0001, 0xa084, + 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x7077, 0x0000, 0x0e7f, + 0x007c, 0x0e7e, 0x0f7e, 0x2001, 0x0002, 0x1078, 0x5975, 0x2079, + 0x0100, 0x2071, 0x0140, 0x1078, 0x6c41, 0x7004, 0xa084, 0x4000, + 0x0040, 0x413e, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e, 0x2091, + 0x8000, 0x2071, 0xa321, 0x2073, 0x0000, 0x7840, 0x027e, 0x017e, + 0x2009, 0x00f7, 0x1078, 0x41de, 0x017f, 0xa094, 0x0010, 0xa285, + 0x0080, 0x7842, 0x7a42, 0x027f, 0x127f, 0x0f7f, 0x0e7f, 0x007c, + 0x127e, 0x2091, 0x8000, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f, + 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, + 0x1078, 0x6c38, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c, + 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x2009, + 0x00f7, 0x1078, 0x41de, 0x2061, 0xa5be, 0x601b, 0x0000, 0x601f, + 0x0000, 0x2061, 0xa300, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, + 0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078, + 0x58c7, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, 0x0e7e, 0x007e, + 0x127e, 0x2091, 0x8000, 0x2001, 0x0001, 0x1078, 0x5975, 0x2071, + 0x0100, 0x1078, 0x6c41, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000, + 0x0040, 0x41ae, 0x7003, 0x1000, 0x7003, 0x0000, 0x2001, 0x0001, + 0x1078, 0x2480, 0x1078, 0x4171, 0x127f, 0x007f, 0x0e7f, 0x007c, + 0x20a9, 0x0040, 0x20a1, 0xa9c0, 0x2099, 0xa88e, 0x3304, 0x8007, + 0x20a2, 0x9398, 0x94a0, 0x00f0, 0x41be, 0x007c, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x2099, 0xa800, 0x20a1, 0x020b, 0x20a9, 0x000c, + 0x53a6, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, + 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e, + 0x2061, 0x0100, 0x810f, 0x2001, 0xa32e, 0x2004, 0xa005, 0x00c0, + 0x41ef, 0x6030, 0xa084, 0x00ff, 0xa105, 0x0078, 0x41f1, 0xa185, + 0x00f7, 0x604a, 0x007f, 0x0c7f, 0x007c, 0x017e, 0x047e, 0x2001, + 0xa352, 0x2004, 0xd0a4, 0x0040, 0x4208, 0xa006, 0x2020, 0x2009, + 0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195, 0x2102, + 0x2019, 0x002a, 0x2009, 0x0000, 0x1078, 0x27e2, 0x047f, 0x017f, + 0x007c, 0x007e, 0x2001, 0xa30c, 0x2004, 0xd09c, 0x0040, 0x4218, + 0x007f, 0x007c, 0x007e, 0x017e, 0x127e, 0x2091, 0x8000, 0x2001, + 0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x127f, 0x017f, 0x007f, + 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0xa434, 0xa006, 0x200a, + 0x8108, 0x00f0, 0x422f, 0x157f, 0x007c, 0x0d7e, 0x037e, 0x157e, + 0x137e, 0x147e, 0x2069, 0xa351, 0xa006, 0x6002, 0x6007, 0x0707, + 0x600a, 0x600e, 0x6012, 0xa198, 0x293f, 0x231c, 0xa39c, 0x00ff, + 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9, + 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e, + 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, 0x606a, 0x606e, + 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, 0x608a, 0x608e, + 0x6092, 0x6096, 0x609a, 0x609e, 0x60ae, 0x61a2, 0x0d7e, 0x60a4, + 0xa06d, 0x0040, 0x4275, 0x1078, 0x139a, 0x60a7, 0x0000, 0x60a8, + 0xa06d, 0x0040, 0x427d, 0x1078, 0x139a, 0x60ab, 0x0000, 0x0d7f, + 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084, + 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f, 0x007c, + 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, + 0x4000, 0x00c8, 0x4361, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, + 0x00c8, 0x4367, 0x2001, 0xa30c, 0x2004, 0xa084, 0x0003, 0x0040, + 0x42c2, 0x2001, 0xa30c, 0x2004, 0xd084, 0x00c0, 0x4342, 0xa188, + 0xa434, 0x2104, 0xa065, 0x0040, 0x4342, 0x6004, 0xa084, 0x00ff, + 0xa08e, 0x0006, 0x00c0, 0x4342, 0x6000, 0xd0c4, 0x0040, 0x4342, + 0x0078, 0x42cf, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4326, + 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x432c, 0x60a4, + 0xa00d, 0x0040, 0x42d7, 0x1078, 0x4749, 0x0040, 0x4320, 0x60a8, + 0xa00d, 0x0040, 0x42f1, 0x1078, 0x479a, 0x00c0, 0x42f1, 0x694c, + 0xd1fc, 0x00c0, 0x42e7, 0x1078, 0x441c, 0x0078, 0x431b, 0x1078, + 0x43d6, 0x694c, 0xd1ec, 0x00c0, 0x431b, 0x1078, 0x460a, 0x0078, + 0x431b, 0x694c, 0xa184, 0xa000, 0x0040, 0x430b, 0xd1ec, 0x0040, + 0x4304, 0xd1fc, 0x0040, 0x4300, 0x1078, 0x461b, 0x0078, 0x4307, + 0x1078, 0x461b, 0x0078, 0x430b, 0xd1fc, 0x0040, 0x430b, 0x1078, + 0x43d6, 0x0078, 0x431b, 0x6050, 0xa00d, 0x0040, 0x4316, 0x2d00, + 0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x431b, 0x2d00, 0x6052, + 0x604e, 0x6803, 0x0000, 0x1078, 0x5c17, 0xa006, 0x127f, 0x007c, + 0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001, 0x0028, + 0x2009, 0x0000, 0x0078, 0x436b, 0xa082, 0x0006, 0x00c8, 0x4342, + 0x60a0, 0xd0bc, 0x00c0, 0x433e, 0x6100, 0xd1fc, 0x0040, 0x42cf, + 0x2001, 0x0029, 0x2009, 0x1000, 0x0078, 0x436b, 0x2001, 0x0028, + 0x0078, 0x435d, 0x2009, 0xa30c, 0x210c, 0xd18c, 0x0040, 0x434c, + 0x2001, 0x0004, 0x0078, 0x435d, 0xd184, 0x0040, 0x4353, 0x2001, + 0x0004, 0x0078, 0x435d, 0x2001, 0x0029, 0x6100, 0xd1fc, 0x0040, + 0x435d, 0x2009, 0x1000, 0x0078, 0x436b, 0x2009, 0x0000, 0x0078, + 0x436b, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001, + 0x0029, 0x2009, 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48, + 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x43bb, 0xa18c, 0xff00, + 0x810f, 0xa182, 0x00ff, 0x00c8, 0x43a1, 0xa188, 0xa434, 0x2104, + 0xa065, 0x0040, 0x43a1, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, + 0x00c0, 0x43a7, 0x684c, 0xd0ec, 0x0040, 0x4394, 0x1078, 0x461b, + 0x1078, 0x43d6, 0x0078, 0x439c, 0x1078, 0x43d6, 0x684c, 0xd0fc, + 0x0040, 0x439c, 0x1078, 0x460a, 0x1078, 0x4663, 0xa006, 0x0078, + 0x43bf, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x43bf, 0xa082, + 0x0006, 0x00c8, 0x43b5, 0x6100, 0xd1fc, 0x0040, 0x438a, 0x2001, + 0x0029, 0x2009, 0x1000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009, + 0x0000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, + 0x007c, 0x127e, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0040, 0x43cf, + 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x127f, 0x007c, 0x2d00, + 0x6052, 0x604e, 0x6803, 0x0000, 0x0078, 0x43cd, 0x127e, 0x2091, + 0x8000, 0x604c, 0xa005, 0x0040, 0x43ec, 0x0e7e, 0x2071, 0xa5ab, + 0x7004, 0xa086, 0x0002, 0x0040, 0x43f3, 0x0e7f, 0x604c, 0x6802, + 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, + 0x0000, 0x0078, 0x43ea, 0x701c, 0xac06, 0x00c0, 0x43e5, 0x604c, + 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x0e7f, 0x127f, 0x007c, + 0x127e, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0040, 0x440e, 0x6800, + 0xa005, 0x00c0, 0x440c, 0x6052, 0x604e, 0xad05, 0x127f, 0x007c, + 0x604c, 0xa06d, 0x0040, 0x441b, 0x6800, 0xa005, 0x00c0, 0x4419, + 0x6052, 0x604e, 0xad05, 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d, + 0x0040, 0x4426, 0x2d00, 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086, + 0x6082, 0x0078, 0x4425, 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000, + 0x6218, 0x2260, 0x6200, 0xa005, 0x0040, 0x4439, 0xc285, 0x0078, + 0x443a, 0xc284, 0x6202, 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e, + 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086, + 0x0006, 0x00c0, 0x445e, 0x609c, 0xd0ac, 0x0040, 0x445e, 0x2001, + 0xa352, 0x2004, 0xd0a4, 0x0040, 0x445e, 0xa284, 0xff00, 0x8007, + 0xa086, 0x0007, 0x00c0, 0x445e, 0x2011, 0x0600, 0x007f, 0xa294, + 0xff00, 0xa215, 0x6206, 0x007e, 0xa086, 0x0006, 0x00c0, 0x446e, + 0x6290, 0x82ff, 0x00c0, 0x446e, 0x1078, 0x1328, 0x007f, 0x0c7f, + 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, + 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x4490, 0x609c, 0xd0a4, + 0x0040, 0x4490, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x4490, + 0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0, 0x4490, 0x2011, 0x0006, + 0x007f, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f, + 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x44a2, 0xa085, 0x0001, + 0x0078, 0x44ba, 0xa190, 0xa434, 0x2204, 0xa065, 0x00c0, 0x44b9, + 0x017e, 0x0d7e, 0x1078, 0x1366, 0x2d60, 0x0d7f, 0x017f, 0x0040, + 0x449e, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x1078, + 0x4235, 0xa006, 0x027f, 0x007c, 0x127e, 0x2091, 0x8000, 0x027e, + 0xa182, 0x00ff, 0x0048, 0x44c8, 0xa085, 0x0001, 0x0078, 0x44fe, + 0x0d7e, 0xa190, 0xa434, 0x2204, 0xa06d, 0x0040, 0x44fc, 0x2013, + 0x0000, 0x0d7e, 0x0c7e, 0x2d60, 0x60a4, 0xa06d, 0x0040, 0x44da, + 0x1078, 0x139a, 0x60a8, 0xa06d, 0x0040, 0x44e0, 0x1078, 0x139a, + 0x0c7f, 0x0d7f, 0x0d7e, 0x0c7e, 0x68ac, 0x2060, 0x8cff, 0x0040, + 0x44f8, 0x600c, 0x007e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, + 0x44f3, 0x1078, 0x13aa, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x44e6, + 0x0c7f, 0x0d7f, 0x1078, 0x139a, 0x0d7f, 0xa006, 0x027f, 0x127f, + 0x007c, 0x017e, 0xa182, 0x00ff, 0x0048, 0x450a, 0xa085, 0x0001, + 0x0078, 0x4511, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4506, + 0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b, + 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x2069, 0xa88e, + 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0048, 0x4529, + 0x603a, 0x6814, 0x6066, 0x2099, 0xa896, 0xac88, 0x000a, 0x21a0, + 0x20a9, 0x0004, 0x53a3, 0x2099, 0xa89a, 0xac88, 0x0006, 0x21a0, + 0x20a9, 0x0004, 0x53a3, 0x2069, 0xa8ae, 0x6808, 0x606a, 0x690c, + 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x00c8, + 0x454d, 0x2009, 0x0008, 0x0078, 0x4577, 0xa182, 0x0259, 0x00c8, + 0x4555, 0x2009, 0x0007, 0x0078, 0x4577, 0xa182, 0x02c1, 0x00c8, + 0x455d, 0x2009, 0x0006, 0x0078, 0x4577, 0xa182, 0x0349, 0x00c8, + 0x4565, 0x2009, 0x0005, 0x0078, 0x4577, 0xa182, 0x0421, 0x00c8, + 0x456d, 0x2009, 0x0004, 0x0078, 0x4577, 0xa182, 0x0581, 0x00c8, + 0x4575, 0x2009, 0x0003, 0x0078, 0x4577, 0x2009, 0x0002, 0x6192, + 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x017e, 0x027e, 0x0e7e, + 0x2071, 0xa88d, 0x2e04, 0x6896, 0x2071, 0xa88e, 0x7004, 0x689a, + 0x701c, 0x689e, 0x6a00, 0x2009, 0xa371, 0x210c, 0xd0bc, 0x0040, + 0x4597, 0xd1ec, 0x0040, 0x4597, 0xc2ad, 0x0078, 0x4598, 0xc2ac, + 0xd0c4, 0x0040, 0x45a1, 0xd1e4, 0x0040, 0x45a1, 0xc2bd, 0x0078, + 0x45a2, 0xc2bc, 0x6a02, 0x0e7f, 0x027f, 0x017f, 0x007c, 0x0d7e, + 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x0040, 0x45cb, 0x6900, + 0x81ff, 0x00c0, 0x45df, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x45e4, + 0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040, + 0x45c6, 0x8108, 0x00f0, 0x45bc, 0x1078, 0x1328, 0x260a, 0x8210, + 0x6a06, 0x0078, 0x45df, 0x1078, 0x1381, 0x0040, 0x45e4, 0x2d00, + 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, + 0xffff, 0x8108, 0x00f0, 0x45d7, 0x6807, 0x0001, 0x6e12, 0xa085, + 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x45e1, 0x127e, + 0x2091, 0x8000, 0x0d7e, 0x60a4, 0xa00d, 0x0040, 0x4607, 0x2168, + 0x6800, 0xa005, 0x00c0, 0x4603, 0x1078, 0x4749, 0x00c0, 0x4607, + 0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0048, 0x4603, 0x8001, + 0x6806, 0x0078, 0x4607, 0x1078, 0x139a, 0x60a7, 0x0000, 0x0d7f, + 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x47af, 0x0078, + 0x4613, 0x1078, 0x43c1, 0x1078, 0x46a7, 0x00c0, 0x4611, 0x1078, + 0x4663, 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8, + 0xa06d, 0x0040, 0x463f, 0x6950, 0x81ff, 0x00c0, 0x4653, 0x6a54, + 0xa282, 0x0010, 0x00c8, 0x4660, 0xad88, 0x0018, 0x20a9, 0x0010, + 0x2104, 0xa086, 0xffff, 0x0040, 0x463a, 0x8108, 0x00f0, 0x4630, + 0x1078, 0x1328, 0x260a, 0x8210, 0x6a56, 0x0078, 0x4653, 0x1078, + 0x1381, 0x0040, 0x4660, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88, + 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x464b, + 0x6857, 0x0001, 0x6e62, 0x0078, 0x4657, 0x1078, 0x441c, 0x1078, + 0x466d, 0x00c0, 0x4655, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, + 0xa006, 0x0078, 0x465d, 0x127e, 0x2091, 0x8000, 0x1078, 0x5c17, + 0x127f, 0x007c, 0xa01e, 0x0078, 0x466f, 0x2019, 0x0001, 0xa00e, + 0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0, + 0x468d, 0x8dff, 0x0040, 0x46a2, 0x83ff, 0x0040, 0x4685, 0x6848, + 0xa606, 0x0040, 0x4692, 0x0078, 0x468d, 0x683c, 0xa406, 0x00c0, + 0x468d, 0x6840, 0xa506, 0x0040, 0x4692, 0x2d08, 0x6800, 0x2068, + 0x0078, 0x4679, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x469a, 0x624e, + 0x0078, 0x469d, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x46a2, + 0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x46a9, 0x2019, + 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x46d5, 0x83ff, + 0x0040, 0x46b8, 0x6848, 0xa606, 0x0040, 0x46c5, 0x0078, 0x46c0, + 0x683c, 0xa406, 0x00c0, 0x46c0, 0x6840, 0xa506, 0x0040, 0x46c5, + 0x2d08, 0x6800, 0x2068, 0x0078, 0x46ac, 0x6a00, 0x6080, 0xad06, + 0x00c0, 0x46cd, 0x6282, 0x0078, 0x46d0, 0xa180, 0x0000, 0x2202, + 0x82ff, 0x00c0, 0x46d5, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078, + 0x4742, 0x00c0, 0x46dd, 0x2011, 0x0001, 0x1078, 0x4793, 0x00c0, + 0x46e3, 0xa295, 0x0002, 0x007c, 0x1078, 0x47cb, 0x0040, 0x46ec, + 0x1078, 0x8b12, 0x0078, 0x46ee, 0xa085, 0x0001, 0x007c, 0x1078, + 0x47cb, 0x0040, 0x46f7, 0x1078, 0x8aaa, 0x0078, 0x46f9, 0xa085, + 0x0001, 0x007c, 0x1078, 0x47cb, 0x0040, 0x4702, 0x1078, 0x8af4, + 0x0078, 0x4704, 0xa085, 0x0001, 0x007c, 0x1078, 0x47cb, 0x0040, + 0x470d, 0x1078, 0x8ac6, 0x0078, 0x470f, 0xa085, 0x0001, 0x007c, + 0x1078, 0x47cb, 0x0040, 0x4718, 0x1078, 0x8b30, 0x0078, 0x471a, + 0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000, + 0x6080, 0xa06d, 0x0040, 0x473a, 0x6800, 0x007e, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x007e, 0x6000, 0xd0fc, + 0x0040, 0x4734, 0x1078, 0xa18c, 0x007f, 0x1078, 0x4982, 0x007f, + 0x0078, 0x4721, 0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f, + 0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0, 0x4749, 0xa085, 0x0001, + 0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005, 0x00c0, 0x475c, 0x20a9, + 0x0010, 0xae88, 0x0004, 0x2104, 0xa606, 0x0040, 0x475c, 0x8108, + 0x00f0, 0x4753, 0xa085, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0d7e, + 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x476d, 0x1078, + 0x1381, 0x0040, 0x477f, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807, + 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, + 0x00f0, 0x4775, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, + 0x0078, 0x477c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, + 0x0040, 0x4790, 0x60a7, 0x0000, 0x1078, 0x139a, 0xa085, 0x0001, + 0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x479a, 0xa085, + 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x47ad, + 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x47ad, + 0x8108, 0x00f0, 0x47a4, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e, + 0x2091, 0x8000, 0x1078, 0x4793, 0x00c0, 0x47c9, 0x200b, 0xffff, + 0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x47c4, + 0x8001, 0x6856, 0x0078, 0x47c8, 0x1078, 0x139a, 0x60ab, 0x0000, + 0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x71ac, + 0x81ff, 0x00c0, 0x47e9, 0x71c8, 0xd19c, 0x0040, 0x47e9, 0x2001, + 0x007e, 0xa080, 0xa434, 0x2004, 0xa07d, 0x0040, 0x47e9, 0x7804, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x47e9, 0x7800, 0xc0ed, + 0x7802, 0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x480f, 0x157e, + 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, + 0x00c0, 0x4809, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, + 0x0040, 0x4806, 0xa086, 0x0006, 0x00c0, 0x4809, 0x6000, 0xc0ed, + 0x6002, 0x017f, 0x8108, 0x00f0, 0x47f5, 0x0c7f, 0x157f, 0x1078, + 0x4897, 0x0040, 0x4818, 0x2001, 0xa59f, 0x200c, 0x0078, 0x4820, + 0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x4824, 0x2009, 0x07d0, + 0x2011, 0x4826, 0x1078, 0x596c, 0x0f7f, 0x007c, 0x2011, 0x4826, + 0x1078, 0x58d4, 0x1078, 0x4897, 0x0040, 0x484e, 0x2001, 0xa4b2, + 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa352, + 0x2004, 0xd0a4, 0x0040, 0x4842, 0x2009, 0x07d0, 0x2011, 0x4826, + 0x1078, 0x596c, 0x0e7e, 0x2071, 0xa300, 0x706b, 0x0000, 0x706f, + 0x0000, 0x1078, 0x260d, 0x0e7f, 0x0078, 0x4886, 0x157e, 0x0c7e, + 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, + 0x4880, 0x6000, 0xd0ec, 0x0040, 0x4880, 0x047e, 0x62a0, 0xa294, + 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6000, + 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, + 0x6006, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, + 0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38, 0x077f, 0x047f, + 0x017f, 0x8108, 0x00f0, 0x4854, 0x0c7f, 0x157f, 0x007c, 0x0c7e, + 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x7818, + 0x2004, 0xd0ac, 0x007c, 0x7818, 0x2004, 0xd0bc, 0x007c, 0x0f7e, + 0x2001, 0xa4b2, 0x2004, 0xa07d, 0x0040, 0x48a0, 0x7800, 0xd0ec, + 0x0f7f, 0x007c, 0x127e, 0x027e, 0x2091, 0x8000, 0x6200, 0xa005, + 0x0040, 0x48ad, 0xc2fd, 0x0078, 0x48ae, 0xc2fc, 0x6202, 0x027f, + 0x127f, 0x007c, 0x2071, 0xa413, 0x7003, 0x0001, 0x7007, 0x0000, + 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, + 0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020, + 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa57c, 0x7003, 0xa413, + 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa55c, 0x7013, 0x0020, + 0x7017, 0x0040, 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e, 0x2071, + 0xa534, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0xa352, + 0x2004, 0xd0fc, 0x00c0, 0x48f7, 0x2001, 0xa352, 0x2004, 0xa00e, + 0xd09c, 0x0040, 0x48f4, 0x8108, 0x7102, 0x0078, 0x494a, 0x2001, + 0xa371, 0x200c, 0xa184, 0x000f, 0x2009, 0xa372, 0x210c, 0x0079, + 0x4901, 0x48ec, 0x4922, 0x492a, 0x4935, 0x493b, 0x48ec, 0x48ec, + 0x48ec, 0x4911, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec, + 0x48ec, 0x7003, 0x0004, 0x137e, 0x147e, 0x157e, 0x2099, 0xa375, + 0x20a1, 0xa585, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f, 0x137f, + 0x0078, 0x494a, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, + 0x0078, 0x4930, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003, + 0x7002, 0x7097, 0x0001, 0x0078, 0x4947, 0x7007, 0x0122, 0x2001, + 0x0002, 0x0078, 0x493f, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, + 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184, + 0x00ff, 0x7092, 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071, 0xa413, + 0x684c, 0xa005, 0x00c0, 0x495b, 0x7028, 0xc085, 0x702a, 0xa085, + 0x0001, 0x0078, 0x4980, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868, + 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844, + 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007, 0x8006, + 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, + 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006, + 0x0e7f, 0x007c, 0x0e7e, 0x027e, 0x6838, 0xd0fc, 0x00c0, 0x49d8, + 0x6804, 0xa00d, 0x0040, 0x499e, 0x0d7e, 0x2071, 0xa300, 0xa016, + 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x00c0, + 0x4991, 0x702e, 0x70a8, 0xa200, 0x70aa, 0x0d7f, 0x2071, 0xa413, + 0x701c, 0xa005, 0x00c0, 0x49ea, 0x0068, 0x49e8, 0x2071, 0xa534, + 0x7200, 0x82ff, 0x0040, 0x49e8, 0x6934, 0xa186, 0x0103, 0x00c0, + 0x49fb, 0x6948, 0x6844, 0xa105, 0x00c0, 0x49db, 0x2009, 0x8020, + 0x2200, 0x0079, 0x49bb, 0x49e8, 0x49c0, 0x4a18, 0x4a26, 0x49e8, + 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x49e8, 0x7122, 0x683c, + 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x2071, + 0xa300, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa, + 0x027f, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0, 0x49e8, + 0x6868, 0xa005, 0x00c0, 0x49e8, 0x2009, 0x8020, 0x0078, 0x49b8, + 0x2071, 0xa413, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012, + 0x7018, 0xa06d, 0x711a, 0x0040, 0x49f8, 0x6902, 0x0078, 0x49f9, + 0x711e, 0x0078, 0x49d8, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040, + 0x4a09, 0xa186, 0x001e, 0x0040, 0x4a09, 0xa18e, 0x001f, 0x00c0, + 0x49e8, 0x684c, 0xd0cc, 0x0040, 0x49e8, 0x6850, 0xa084, 0x00ff, + 0xa086, 0x0001, 0x00c0, 0x49e8, 0x2009, 0x8021, 0x0078, 0x49b8, + 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x49e8, 0x7186, 0xae90, + 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x4a36, 0x7084, 0x8008, + 0xa092, 0x000f, 0x00c8, 0x49e8, 0x7186, 0xae90, 0x0003, 0x8003, + 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a, + 0x0048, 0x49cf, 0x718c, 0x7084, 0xa10a, 0x0048, 0x49cf, 0x2071, + 0x0000, 0x7018, 0xd084, 0x00c0, 0x49cf, 0x2071, 0xa534, 0x7000, + 0xa086, 0x0002, 0x00c0, 0x4a56, 0x1078, 0x4cd2, 0x2071, 0x0000, + 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf, 0x1078, 0x4cfd, + 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf, + 0x007e, 0x684c, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, + 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0xa084, 0x00ff, + 0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa413, 0x7004, + 0x0079, 0x4a7a, 0x4a84, 0x4a95, 0x4ca3, 0x4ca4, 0x4ccb, 0x4cd1, + 0x4a85, 0x4c91, 0x4c32, 0x4cb4, 0x007c, 0x127e, 0x2091, 0x8000, + 0x0068, 0x4a94, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080, + 0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa5be, 0x6844, + 0xa005, 0x0050, 0x4abd, 0x00c0, 0x4abd, 0x127e, 0x2091, 0x8000, + 0x2069, 0x0000, 0x6934, 0x2001, 0xa41f, 0x2004, 0xa10a, 0x0040, + 0x4ab8, 0x0068, 0x4abc, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, + 0x4abc, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, + 0x2069, 0xa5be, 0x6847, 0xffff, 0x127f, 0x2069, 0xa300, 0x6844, + 0x6960, 0xa102, 0x2069, 0xa534, 0x688a, 0x6984, 0x701c, 0xa06d, + 0x0040, 0x4acf, 0x81ff, 0x0040, 0x4b17, 0x0078, 0x4ae5, 0x81ff, + 0x0040, 0x4be9, 0x2071, 0xa534, 0x7184, 0x7088, 0xa10a, 0x00c8, + 0x4ae5, 0x7190, 0x2071, 0xa5be, 0x7040, 0xa005, 0x0040, 0x4ae5, + 0x00d0, 0x4be9, 0x7142, 0x0078, 0x4be9, 0x2071, 0xa534, 0x718c, + 0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, 0x4c06, 0x0068, + 0x4b9b, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4b9b, 0x2001, + 0xffff, 0x2071, 0xa5be, 0x7042, 0x2071, 0xa534, 0x7000, 0xa086, + 0x0002, 0x00c0, 0x4b0d, 0x1078, 0x4cd2, 0x2071, 0x0000, 0x701b, + 0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x1078, 0x4cfd, 0x2071, + 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x2071, + 0xa534, 0x7000, 0xa005, 0x0040, 0x4bc8, 0x6934, 0xa186, 0x0103, + 0x00c0, 0x4b9e, 0x684c, 0xd0bc, 0x00c0, 0x4bc8, 0x6948, 0x6844, + 0xa105, 0x00c0, 0x4bbb, 0x2009, 0x8020, 0x2071, 0xa534, 0x7000, + 0x0079, 0x4b32, 0x4bc8, 0x4b80, 0x4b58, 0x4b6a, 0x4b37, 0x137e, + 0x147e, 0x157e, 0x2099, 0xa375, 0x20a1, 0xa585, 0x20a9, 0x0004, + 0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa57c, 0xad80, 0x000f, + 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10, + 0x1078, 0x13d1, 0x2071, 0xa413, 0x7007, 0x0009, 0x0078, 0x4be9, + 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4be9, 0xae90, 0x0003, + 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b, + 0x0078, 0x4be9, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x4be9, + 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, + 0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b, 0x0078, 0x4be9, + 0x127e, 0x2091, 0x8000, 0x0068, 0x4b9b, 0x2071, 0x0000, 0x7018, + 0xd084, 0x00c0, 0x4b9b, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, + 0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa413, 0x1078, + 0x4d5b, 0x0078, 0x4be9, 0x127f, 0x0078, 0x4be9, 0xa18c, 0x00ff, + 0xa186, 0x0017, 0x0040, 0x4bac, 0xa186, 0x001e, 0x0040, 0x4bac, + 0xa18e, 0x001f, 0x00c0, 0x4bc8, 0x684c, 0xd0cc, 0x0040, 0x4bc8, + 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4bc8, 0x2009, + 0x8021, 0x0078, 0x4b2d, 0x6844, 0xa086, 0x0100, 0x00c0, 0x4bc8, + 0x6868, 0xa005, 0x00c0, 0x4bc8, 0x2009, 0x8020, 0x0078, 0x4b2d, + 0x2071, 0xa413, 0x1078, 0x4d6f, 0x0040, 0x4be9, 0x2071, 0xa413, + 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x00c0, + 0x4be0, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x4be0, 0x710e, + 0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100, 0x0040, + 0x4ca4, 0x127e, 0x2091, 0x8000, 0x2071, 0xa413, 0x7008, 0xa086, + 0x0001, 0x00c0, 0x4c04, 0x0068, 0x4c04, 0x2009, 0x000d, 0x7030, + 0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006, + 0x00c0, 0x4c04, 0x7007, 0x0001, 0x127f, 0x007c, 0x2071, 0xa413, + 0x1078, 0x4d6f, 0x0040, 0x4c2f, 0x2071, 0xa534, 0x7084, 0x700a, + 0x20a9, 0x0020, 0x2099, 0xa535, 0x20a1, 0xa55c, 0x53a3, 0x7087, + 0x0000, 0x2071, 0xa413, 0x2069, 0xa57c, 0x706c, 0x6826, 0x7070, + 0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078, 0x13d1, + 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa5be, 0x7042, 0x127f, + 0x0078, 0x4be9, 0x2069, 0xa57c, 0x6808, 0xa08e, 0x0000, 0x0040, + 0x4c90, 0xa08e, 0x0200, 0x0040, 0x4c8e, 0xa08e, 0x0100, 0x00c0, + 0x4c90, 0x127e, 0x2091, 0x8000, 0x0068, 0x4c8b, 0x2069, 0x0000, + 0x6818, 0xd084, 0x00c0, 0x4c8b, 0x702c, 0x7130, 0x8108, 0xa102, + 0x0048, 0x4c59, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078, + 0x4c63, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4c63, 0x7070, + 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001, + 0xa559, 0x2004, 0xa005, 0x00c0, 0x4c82, 0x6934, 0x2069, 0xa534, + 0x689c, 0x699e, 0x2069, 0xa5be, 0xa102, 0x00c0, 0x4c7b, 0x6844, + 0xa005, 0x00d0, 0x4c89, 0x2001, 0xa55a, 0x200c, 0x810d, 0x6946, + 0x0078, 0x4c89, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, + 0x4080, 0x7007, 0x0001, 0x127f, 0x0078, 0x4c90, 0x7007, 0x0005, + 0x007c, 0x701c, 0xa06d, 0x0040, 0x4ca2, 0x1078, 0x4d6f, 0x0040, + 0x4ca2, 0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100, + 0x0040, 0x4ca4, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100, 0x00c0, + 0x4cad, 0x7007, 0x0004, 0x0078, 0x4ccb, 0xa086, 0x0200, 0x00c0, + 0x4cb3, 0x7007, 0x0005, 0x007c, 0x2001, 0xa57e, 0x2004, 0xa08e, + 0x0100, 0x00c0, 0x4cc0, 0x7007, 0x0001, 0x1078, 0x4d5b, 0x007c, + 0xa08e, 0x0000, 0x0040, 0x4cbf, 0xa08e, 0x0200, 0x00c0, 0x4cbf, + 0x7007, 0x0005, 0x007c, 0x1078, 0x4d25, 0x7006, 0x1078, 0x4d5b, + 0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa534, 0x7184, 0x81ff, + 0x0040, 0x4cfa, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, + 0x21a8, 0x2014, 0x7226, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x722a, + 0x8000, 0x0070, 0x4cf7, 0x2014, 0x722e, 0x8000, 0x0070, 0x4cf7, + 0x2014, 0x723a, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x723e, 0xa180, + 0x8030, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x0e7e, 0x157e, 0x2071, + 0xa534, 0x7184, 0x81ff, 0x0040, 0x4d22, 0xa006, 0x7086, 0xae80, + 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014, + 0x722a, 0x8000, 0x0070, 0x4d1b, 0x2014, 0x723a, 0x8000, 0x2014, + 0x723e, 0x0078, 0x4d1f, 0x2001, 0x8020, 0x0078, 0x4d21, 0x2001, + 0x8042, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x702c, 0x7130, 0x8108, + 0xa102, 0x0048, 0x4d32, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, + 0x0078, 0x4d3c, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4d3c, + 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e, + 0x00c0, 0x4d52, 0x127e, 0x2091, 0x8000, 0x0068, 0x4d55, 0x2001, + 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b, 0x0000, + 0x127f, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x700b, + 0x0001, 0x127f, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4d6e, 0x127e, + 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005, + 0x00c0, 0x4d6b, 0x701a, 0x127f, 0x1078, 0x139a, 0x007c, 0x2019, + 0x000d, 0x2304, 0x230c, 0xa10e, 0x0040, 0x4d7e, 0x2304, 0x230c, + 0xa10e, 0x0040, 0x4d7e, 0xa006, 0x0078, 0x4d8e, 0x732c, 0x8319, + 0x7130, 0xa102, 0x00c0, 0x4d88, 0x2300, 0xa005, 0x0078, 0x4d8e, + 0x0048, 0x4d8d, 0xa302, 0x0078, 0x4d8e, 0x8002, 0x007c, 0x2d00, + 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x127e, 0x2091, + 0x8000, 0x2009, 0xa5d0, 0x2104, 0xc08d, 0x200a, 0x127f, 0x1078, + 0x13eb, 0x007c, 0x2071, 0xa3e1, 0x7003, 0x0000, 0x7007, 0x0000, + 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001, + 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000, + 0x708f, 0x0001, 0x70bf, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa3e1, + 0x6848, 0xa005, 0x00c0, 0x4dcb, 0x7028, 0xc085, 0x702a, 0xa085, + 0x0001, 0x0078, 0x4df0, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, + 0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, + 0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, + 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, + 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, + 0x0e7f, 0x007c, 0x2b78, 0x2071, 0xa3e1, 0x7004, 0x1079, 0x4e50, + 0x700c, 0x0079, 0x4dfb, 0x4e00, 0x4df5, 0x4df5, 0x4df5, 0x4df5, + 0x007c, 0x700c, 0x0079, 0x4e04, 0x4e09, 0x4e4e, 0x4e4e, 0x4e4f, + 0x4e4f, 0x7830, 0x7930, 0xa106, 0x0040, 0x4e13, 0x7830, 0x7930, + 0xa106, 0x00c0, 0x4e39, 0x7030, 0xa10a, 0x0040, 0x4e39, 0x00c8, + 0x4e1b, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4e3a, 0x1078, + 0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, + 0x0003, 0x7057, 0x0000, 0x127e, 0x007e, 0x2091, 0x8000, 0x2009, + 0xa5d0, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f, 0x1078, + 0x13eb, 0x007c, 0x1078, 0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a, + 0x1078, 0x1366, 0x00c0, 0x4e46, 0x0078, 0x4e25, 0x2d00, 0x7086, + 0x7063, 0x0080, 0x2001, 0x0004, 0x0078, 0x4e29, 0x007c, 0x007c, + 0x4e61, 0x4e62, 0x4e99, 0x4e9a, 0x4e4e, 0x4ed0, 0x4ed5, 0x4f0c, + 0x4f0d, 0x4f28, 0x4f29, 0x4f2a, 0x4f2b, 0x4f2c, 0x4f2d, 0x4fad, + 0x4fd7, 0x007c, 0x700c, 0x0079, 0x4e65, 0x4e6a, 0x4e6d, 0x4e7d, + 0x4e98, 0x4e98, 0x1078, 0x4e01, 0x007c, 0x127e, 0x8001, 0x700e, + 0x7058, 0x007e, 0x1078, 0x5348, 0x0040, 0x4e7a, 0x2091, 0x8000, + 0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4e86, 0x127e, 0x8001, 0x700e, + 0x1078, 0x5348, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, + 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x00c8, + 0x4e95, 0x1079, 0x4eb0, 0x127f, 0x007c, 0x127f, 0x1078, 0x4f2e, + 0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa3e1, 0x700c, 0x0079, + 0x4ea1, 0x4ea6, 0x4ea6, 0x4ea6, 0x4ea8, 0x4eac, 0x0e7f, 0x007c, + 0x700f, 0x0001, 0x0078, 0x4eae, 0x700f, 0x0002, 0x0e7f, 0x007c, + 0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x5080, 0x4f2e, 0x4f2e, 0x4f2e, + 0x4f2e, 0x4f2e, 0x4f4a, 0x50ca, 0x5117, 0x5170, 0x5186, 0x4f2e, + 0x4f2e, 0x4f66, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f87, 0x5245, 0x5263, + 0x4f2e, 0x4f66, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f7c, 0x5263, + 0x7020, 0x2068, 0x1078, 0x139a, 0x007c, 0x700c, 0x0079, 0x4ed8, + 0x4edd, 0x4ee0, 0x4ef0, 0x4f0b, 0x4f0b, 0x1078, 0x4e01, 0x007c, + 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x5348, 0x0040, + 0x4eed, 0x2091, 0x8000, 0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4ef9, + 0x127e, 0x8001, 0x700e, 0x1078, 0x5348, 0x7058, 0x2068, 0x7084, + 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, + 0xa08a, 0x001a, 0x00c8, 0x4f08, 0x1079, 0x4f0e, 0x127f, 0x007c, + 0x127f, 0x1078, 0x4f2e, 0x007c, 0x007c, 0x007c, 0x4f2e, 0x4f4a, + 0x506a, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a, + 0x506a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a, + 0x506a, 0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f4a, + 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x7007, 0x0001, + 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091, 0x8000, + 0x1078, 0x4982, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, + 0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982, + 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, + 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c, + 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x127e, + 0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c, 0x6834, 0x8007, + 0xa084, 0x00ff, 0x0040, 0x4f3c, 0x8001, 0x00c0, 0x4f73, 0x7007, + 0x0001, 0x0078, 0x5049, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, + 0x701a, 0x704b, 0x5049, 0x007c, 0x684c, 0xa084, 0x00c0, 0xa086, + 0x00c0, 0x00c0, 0x4f87, 0x7007, 0x0001, 0x0078, 0x5280, 0x2d00, + 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1, + 0xa40c, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, 0x4f58, + 0x6884, 0xa08a, 0x0002, 0x00c8, 0x4f58, 0x82ff, 0x00c0, 0x4fa9, + 0x6888, 0x698c, 0xa105, 0x0040, 0x4fa9, 0x2001, 0x5019, 0x0078, + 0x4fac, 0xa280, 0x500f, 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040, + 0x4ff7, 0x1078, 0x1366, 0x00c0, 0x4fb8, 0x7007, 0x000f, 0x007c, + 0x2d00, 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004, 0xad00, + 0x7096, 0x6008, 0xa20a, 0x00c8, 0x4fc7, 0xa00e, 0x2200, 0x7112, + 0x620c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x4fd0, 0xa108, + 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x13d1, 0x7090, + 0xa08e, 0x0100, 0x0040, 0x4feb, 0xa086, 0x0200, 0x0040, 0x4fe3, + 0x7007, 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x139a, 0x7014, + 0x2068, 0x0078, 0x4f58, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, + 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x4fad, 0x7014, + 0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x00c0, 0x5006, 0x6888, + 0x698c, 0xa105, 0x0040, 0x5006, 0x1078, 0x501d, 0x6834, 0xa084, + 0x00ff, 0xa086, 0x001e, 0x0040, 0x5280, 0x0078, 0x5049, 0x5011, + 0x5015, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f, 0x0005, + 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x0f7e, 0x0e7e, 0x0c7e, + 0x077e, 0x067e, 0x6f88, 0x6e8c, 0x6804, 0x2060, 0xacf0, 0x0021, + 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816, 0x7008, 0x7812, + 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, 0x8109, 0x0040, + 0x503f, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0078, 0x502c, 0x6004, + 0xa065, 0x00c0, 0x5026, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x0f7f, + 0x007c, 0x2009, 0xa32e, 0x210c, 0x81ff, 0x00c0, 0x5064, 0x6838, + 0xa084, 0x00ff, 0x683a, 0x1078, 0x4290, 0x00c0, 0x5058, 0x007c, + 0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cb8, 0x1078, + 0x4982, 0x127f, 0x0078, 0x5057, 0x2001, 0x0028, 0x2009, 0x0000, + 0x0078, 0x5058, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a, + 0x7010, 0x8001, 0x7012, 0x0040, 0x5079, 0x7007, 0x0006, 0x0078, + 0x507f, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, 0x007c, + 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, + 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x50a9, 0x2009, + 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0040, 0x50a9, 0xa005, + 0x00c0, 0x50bc, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501, + 0x00c0, 0x50bc, 0x067e, 0x6e50, 0x1078, 0x45e7, 0x067f, 0x0078, + 0x50bc, 0x047e, 0x2011, 0xa30c, 0x2224, 0xc484, 0xc48c, 0x2412, + 0x047f, 0x0c7e, 0x1078, 0x4501, 0x00c0, 0x50b8, 0x1078, 0x4782, + 0x8108, 0x00f0, 0x50b2, 0x0c7f, 0x684c, 0xd084, 0x00c0, 0x50c3, + 0x1078, 0x139a, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982, + 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, + 0xa352, 0x2004, 0xd0a4, 0x0040, 0x510e, 0x2061, 0xa62d, 0x6100, + 0xd184, 0x0040, 0x50ee, 0x6858, 0xa084, 0x00ff, 0x00c0, 0x5111, + 0x6000, 0xd084, 0x0040, 0x510e, 0x6004, 0xa005, 0x00c0, 0x5114, + 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x510b, 0x2011, 0x0001, + 0x6860, 0xa005, 0x00c0, 0x50f6, 0x2001, 0x001e, 0x8000, 0x6016, + 0x6858, 0xa084, 0x00ff, 0x0040, 0x510e, 0x6006, 0x6858, 0x8007, + 0xa084, 0x00ff, 0x0040, 0x510e, 0x600a, 0x6858, 0x8000, 0x00c0, + 0x510a, 0xc28d, 0x6202, 0x127f, 0x0078, 0x5337, 0x127f, 0x0078, + 0x532f, 0x127f, 0x0078, 0x5327, 0x127f, 0x0078, 0x532b, 0x127e, + 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa352, 0x2004, 0xd0a4, + 0x0040, 0x516d, 0x2061, 0xa62d, 0x6000, 0xd084, 0x0040, 0x516d, + 0x6204, 0x6308, 0xd08c, 0x00c0, 0x515f, 0x6c48, 0xa484, 0x0003, + 0x0040, 0x5145, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x513e, + 0x2100, 0xa210, 0x0048, 0x516a, 0x0078, 0x5145, 0x8001, 0x00c0, + 0x516a, 0x2100, 0xa212, 0x0048, 0x516a, 0xa484, 0x000c, 0x0040, + 0x515f, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0, + 0x5157, 0x2100, 0xa318, 0x0048, 0x516a, 0x0078, 0x515f, 0xa082, + 0x0004, 0x00c0, 0x516a, 0x2100, 0xa31a, 0x0048, 0x516a, 0x6860, + 0xa005, 0x0040, 0x5165, 0x8000, 0x6016, 0x6206, 0x630a, 0x127f, + 0x0078, 0x5337, 0x127f, 0x0078, 0x5333, 0x127f, 0x0078, 0x532f, + 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xa62d, 0x6300, + 0xd38c, 0x00c0, 0x5180, 0x6308, 0x8318, 0x0048, 0x5183, 0x630a, + 0x127f, 0x0078, 0x5345, 0x127f, 0x0078, 0x5333, 0x127e, 0x0c7e, + 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040, 0x519a, + 0x0c7e, 0x2061, 0xa62d, 0x6000, 0xa084, 0xfcff, 0x6002, 0x0c7f, + 0x0078, 0x51c9, 0x6858, 0xa005, 0x0040, 0x51e0, 0x685c, 0xa065, + 0x0040, 0x51dc, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x51ac, + 0x1078, 0x8c01, 0x0078, 0x51ba, 0x6013, 0x0400, 0x6037, 0x0000, + 0x694c, 0xd1a4, 0x0040, 0x51b6, 0x6950, 0x6136, 0x2009, 0x0041, + 0x1078, 0x756c, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x00c0, + 0x51c9, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, 0x5a6d, + 0x027f, 0x684c, 0xd0c4, 0x0040, 0x51d8, 0x2061, 0xa62d, 0x6000, + 0xd08c, 0x00c0, 0x51d8, 0x6008, 0x8000, 0x0048, 0x51dc, 0x600a, + 0x0c7f, 0x127f, 0x0078, 0x5337, 0x0c7f, 0x127f, 0x0078, 0x532f, + 0x6954, 0xa186, 0x0045, 0x0040, 0x5213, 0xa186, 0x002a, 0x00c0, + 0x51f0, 0x2001, 0xa30c, 0x200c, 0xc194, 0x2102, 0x0078, 0x51c9, + 0xa186, 0x0020, 0x0040, 0x5209, 0xa186, 0x0029, 0x0040, 0x51fc, + 0xa186, 0x002d, 0x00c0, 0x51dc, 0x6944, 0xa18c, 0xff00, 0x810f, + 0x1078, 0x4501, 0x00c0, 0x51c9, 0x6000, 0xc0e4, 0x6002, 0x0078, + 0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x2001, 0xa5a1, 0x2004, + 0x6016, 0x0078, 0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x0e7e, + 0x6860, 0xa075, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x522b, + 0x1078, 0x8c01, 0x8eff, 0x0040, 0x5228, 0x2e60, 0x1078, 0x8c01, + 0x0e7f, 0x0078, 0x51c9, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, + 0x6007, 0x003a, 0x6870, 0xa005, 0x0040, 0x523c, 0x6007, 0x003b, + 0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x1078, 0x5bf8, + 0x1078, 0x6109, 0x0e7f, 0x0078, 0x51c9, 0x2061, 0xa62d, 0x6000, + 0xd084, 0x0040, 0x525f, 0xd08c, 0x00c0, 0x5345, 0x2091, 0x8000, + 0x6204, 0x8210, 0x0048, 0x5259, 0x6206, 0x2091, 0x8001, 0x0078, + 0x5345, 0x2091, 0x8001, 0x6853, 0x0016, 0x0078, 0x533e, 0x6853, + 0x0007, 0x0078, 0x533e, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0, + 0x526d, 0x1078, 0x4f3c, 0x0078, 0x527f, 0x2030, 0x8001, 0x00c0, + 0x5277, 0x7007, 0x0001, 0x1078, 0x5280, 0x0078, 0x527f, 0x7007, + 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5280, 0x007c, + 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2009, 0xa32e, 0x210c, 0x81ff, + 0x00c0, 0x530b, 0x2009, 0xa30c, 0x210c, 0xd194, 0x00c0, 0x5315, + 0x6848, 0x2070, 0xae82, 0xaa00, 0x0048, 0x52fb, 0x2001, 0xa315, + 0x2004, 0xae02, 0x00c8, 0x52fb, 0x2061, 0xa62d, 0x6100, 0xa184, + 0x0301, 0xa086, 0x0001, 0x00c0, 0x52de, 0x711c, 0xa186, 0x0006, + 0x00c0, 0x52e6, 0x7018, 0xa005, 0x0040, 0x530b, 0x2004, 0xd0e4, + 0x00c0, 0x530f, 0x7024, 0xd0dc, 0x00c0, 0x5319, 0x6853, 0x0000, + 0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x00c0, 0x52ca, 0x7112, + 0x684c, 0xd0f4, 0x00c0, 0x531d, 0x2e60, 0x1078, 0x59b6, 0x127f, + 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x52ca, 0x6902, + 0x2168, 0x684c, 0xd0f4, 0x00c0, 0x531d, 0x127f, 0x0e7f, 0x007c, + 0x127f, 0x0e7f, 0x6853, 0x0006, 0x0078, 0x533e, 0xd184, 0x0040, + 0x52d8, 0xd1c4, 0x00c0, 0x52ff, 0x0078, 0x5303, 0x6944, 0xa18c, + 0xff00, 0x810f, 0x1078, 0x4501, 0x00c0, 0x530f, 0x6000, 0xd0e4, + 0x00c0, 0x530f, 0x711c, 0xa186, 0x0007, 0x00c0, 0x52fb, 0x6853, + 0x0002, 0x0078, 0x5311, 0x6853, 0x0008, 0x0078, 0x5311, 0x6853, + 0x000e, 0x0078, 0x5311, 0x6853, 0x0017, 0x0078, 0x5311, 0x6853, + 0x0035, 0x0078, 0x5311, 0x6853, 0x0028, 0x0078, 0x5311, 0x6853, + 0x0029, 0x127f, 0x0e7f, 0x0078, 0x533e, 0x6853, 0x002a, 0x0078, + 0x5311, 0x6853, 0x0045, 0x0078, 0x5311, 0x2e60, 0x2019, 0x0002, + 0x6017, 0x0014, 0x1078, 0x9a6a, 0x127f, 0x0e7f, 0x007c, 0x2009, + 0x003e, 0x0078, 0x5339, 0x2009, 0x0004, 0x0078, 0x5339, 0x2009, + 0x0006, 0x0078, 0x5339, 0x2009, 0x0016, 0x0078, 0x5339, 0x2009, + 0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000, + 0x1078, 0x4982, 0x2091, 0x8001, 0x007c, 0x1078, 0x139a, 0x007c, + 0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x5355, 0xa00e, 0x7034, + 0x7072, 0x7038, 0x7076, 0x0078, 0x5361, 0x7070, 0xa080, 0x0040, + 0x7072, 0x00c8, 0x5361, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, + 0x0001, 0x7932, 0x7132, 0x007c, 0x0d7e, 0x1078, 0x59ad, 0x0d7f, + 0x007c, 0x0d7e, 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012, + 0x0d7f, 0x007c, 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, + 0xa084, 0x7000, 0x0040, 0x5380, 0xa086, 0x1000, 0x00c0, 0x53ac, + 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217, 0xa084, 0xf000, + 0xa086, 0x3000, 0x00c0, 0x5390, 0x1078, 0x5570, 0x0078, 0x53a7, + 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x5397, 0x3e60, 0xac84, + 0x000f, 0x00c0, 0x53ac, 0xac82, 0xaa00, 0x0048, 0x53ac, 0x6854, + 0xac02, 0x00c8, 0x53ac, 0x2009, 0x0047, 0x1078, 0x756c, 0x7a1c, + 0xd284, 0x00c0, 0x5372, 0x007c, 0xa016, 0x1078, 0x15ec, 0x0078, + 0x53a7, 0x0078, 0x53ac, 0x781c, 0xd08c, 0x0040, 0x53db, 0x157e, + 0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076, + 0x00c0, 0x53f1, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x53e0, + 0x1078, 0x540c, 0x0040, 0x53f1, 0x20e1, 0x3000, 0x7828, 0x7828, + 0x1078, 0x542a, 0x147f, 0x137f, 0x157f, 0x2009, 0xa5b3, 0x2104, + 0xa005, 0x00c0, 0x53dc, 0x007c, 0x1078, 0x6109, 0x0078, 0x53db, + 0xa484, 0x7000, 0x00c0, 0x53f1, 0x1078, 0x540c, 0x0040, 0x5403, + 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x53cc, 0x0078, + 0x5403, 0x1078, 0xa1ee, 0xd5a4, 0x0040, 0x53ff, 0x1078, 0x1af7, + 0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x5407, 0x1078, + 0x540c, 0x687f, 0x0000, 0x20e1, 0x3000, 0x7828, 0x7828, 0x147f, + 0x137f, 0x157f, 0x0078, 0x53db, 0xa484, 0x01ff, 0x687e, 0xa005, + 0x0040, 0x541e, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1, + 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9, 0x000c, + 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001, + 0x0078, 0x541d, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007, + 0xa196, 0x0000, 0x00c0, 0x5437, 0x0078, 0x567c, 0x007c, 0xa196, + 0x2000, 0x00c0, 0x5448, 0x6900, 0xa18e, 0x0001, 0x00c0, 0x5444, + 0x1078, 0x3a43, 0x0078, 0x5436, 0x1078, 0x5450, 0x0078, 0x5436, + 0xa196, 0x8000, 0x00c0, 0x5436, 0x1078, 0x570c, 0x0078, 0x5436, + 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0040, + 0x545d, 0xa196, 0x0023, 0x00c0, 0x5568, 0xa08e, 0x0023, 0x00c0, + 0x5492, 0x1078, 0x57b2, 0x0040, 0x5568, 0x7124, 0x610a, 0x7030, + 0xa08e, 0x0200, 0x00c0, 0x5476, 0x7034, 0xa005, 0x00c0, 0x5568, + 0x2009, 0x0015, 0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0214, + 0x0040, 0x547e, 0xa08e, 0x0210, 0x00c0, 0x5484, 0x2009, 0x0015, + 0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0100, 0x00c0, 0x5568, + 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009, 0x0016, 0x1078, 0x756c, + 0x0078, 0x5568, 0xa08e, 0x0022, 0x00c0, 0x5568, 0x7030, 0xa08e, + 0x0300, 0x00c0, 0x54a3, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009, + 0x0017, 0x0078, 0x5534, 0xa08e, 0x0500, 0x00c0, 0x54af, 0x7034, + 0xa005, 0x00c0, 0x5568, 0x2009, 0x0018, 0x0078, 0x5534, 0xa08e, + 0x2010, 0x00c0, 0x54b7, 0x2009, 0x0019, 0x0078, 0x5534, 0xa08e, + 0x2110, 0x00c0, 0x54bf, 0x2009, 0x001a, 0x0078, 0x5534, 0xa08e, + 0x5200, 0x00c0, 0x54cb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009, + 0x001b, 0x0078, 0x5534, 0xa08e, 0x5000, 0x00c0, 0x54d7, 0x7034, + 0xa005, 0x00c0, 0x5568, 0x2009, 0x001c, 0x0078, 0x5534, 0xa08e, + 0x1300, 0x00c0, 0x54df, 0x2009, 0x0034, 0x0078, 0x5534, 0xa08e, + 0x1200, 0x00c0, 0x54eb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009, + 0x0024, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x00c0, + 0x54f5, 0x2009, 0x002d, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e, + 0x5300, 0x00c0, 0x54ff, 0x2009, 0x002a, 0x0078, 0x5534, 0xa08e, + 0x0f00, 0x00c0, 0x5507, 0x2009, 0x0020, 0x0078, 0x5534, 0xa08e, + 0x5300, 0x00c0, 0x550d, 0x0078, 0x552a, 0xa08e, 0x6104, 0x00c0, + 0x552a, 0x2011, 0xa88d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, + 0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, 0x047e, 0x2124, + 0x1078, 0x3579, 0x047f, 0x8108, 0x00f0, 0x551a, 0x2009, 0x0023, + 0x0078, 0x5534, 0xa08e, 0x6000, 0x00c0, 0x5532, 0x2009, 0x003f, + 0x0078, 0x5534, 0x2009, 0x001d, 0x017e, 0x2011, 0xa883, 0x2204, + 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x556a, 0x1078, 0x4499, + 0x00c0, 0x556a, 0x6612, 0x6516, 0x86ff, 0x0040, 0x555a, 0x017f, + 0x017e, 0xa186, 0x0017, 0x00c0, 0x555a, 0x6868, 0xa606, 0x00c0, + 0x555a, 0x686c, 0xa506, 0xa084, 0xff00, 0x00c0, 0x555a, 0x6000, + 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x74d7, 0x0040, 0x556d, 0x017f, + 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x756c, + 0x0c7f, 0x007c, 0x017f, 0x0078, 0x5568, 0x0c7f, 0x0078, 0x556a, + 0x0c7e, 0x1078, 0x55d4, 0x00c0, 0x55d2, 0xa184, 0xff00, 0x8007, + 0xa086, 0x0008, 0x00c0, 0x55d2, 0xa28e, 0x0033, 0x00c0, 0x55a3, + 0x1078, 0x57b2, 0x0040, 0x55d2, 0x7124, 0x610a, 0x7030, 0xa08e, + 0x0200, 0x00c0, 0x5595, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009, + 0x0015, 0x1078, 0x756c, 0x0078, 0x55d2, 0xa08e, 0x0100, 0x00c0, + 0x55d2, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009, 0x0016, 0x1078, + 0x756c, 0x0078, 0x55d2, 0xa28e, 0x0032, 0x00c0, 0x55d2, 0x7030, + 0xa08e, 0x1400, 0x00c0, 0x55d2, 0x2009, 0x0038, 0x017e, 0x2011, + 0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x55d1, + 0x1078, 0x4499, 0x00c0, 0x55d1, 0x6612, 0x6516, 0x0c7e, 0x1078, + 0x74d7, 0x0040, 0x55d0, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120, + 0x610a, 0x017f, 0x1078, 0x756c, 0x1078, 0x6109, 0x0078, 0x55d2, + 0x0c7f, 0x017f, 0x0c7f, 0x007c, 0x0f7e, 0x0d7e, 0x027e, 0x017e, + 0x137e, 0x147e, 0x157e, 0x3c00, 0x007e, 0x2079, 0x0030, 0x2069, + 0x0200, 0x1078, 0x1c25, 0x00c0, 0x5615, 0x1078, 0x1b15, 0x0040, + 0x561f, 0x7908, 0xa18c, 0x1fff, 0xa182, 0x0011, 0x00c8, 0x561f, + 0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0, 0x2099, 0x020a, 0x53a5, + 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x7a0c, 0x7808, 0xa080, + 0x0007, 0xa084, 0x1ff8, 0xa08a, 0x0140, 0x10c8, 0x1328, 0x80ac, + 0x20e1, 0x6000, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, + 0x6828, 0x7803, 0x0004, 0xa294, 0x0070, 0x007f, 0x20e0, 0x157f, + 0x147f, 0x137f, 0x017f, 0x027f, 0x0d7f, 0x0f7f, 0x007c, 0xa085, + 0x0001, 0x0078, 0x5615, 0x047e, 0x0e7e, 0x0d7e, 0x2028, 0x2130, + 0xa696, 0x00ff, 0x00c0, 0x5644, 0xa596, 0xfffd, 0x00c0, 0x5634, + 0x2009, 0x007f, 0x0078, 0x5677, 0xa596, 0xfffe, 0x00c0, 0x563c, + 0x2009, 0x007e, 0x0078, 0x5677, 0xa596, 0xfffc, 0x00c0, 0x5644, + 0x2009, 0x0080, 0x0078, 0x5677, 0x2011, 0x0000, 0x2021, 0x0081, + 0x20a9, 0x007e, 0x2071, 0xa4b5, 0x2e1c, 0x83ff, 0x00c0, 0x5656, + 0x82ff, 0x00c0, 0x566b, 0x2410, 0x0078, 0x566b, 0x2368, 0x6f10, + 0x007e, 0x2100, 0xa706, 0x007f, 0x6b14, 0x00c0, 0x5665, 0xa346, + 0x00c0, 0x5665, 0x2408, 0x0078, 0x5677, 0x87ff, 0x00c0, 0x566b, + 0x83ff, 0x0040, 0x5650, 0x8420, 0x8e70, 0x00f0, 0x564c, 0x82ff, + 0x00c0, 0x5676, 0xa085, 0x0001, 0x0078, 0x5678, 0x2208, 0xa006, + 0x0d7f, 0x0e7f, 0x047f, 0x007c, 0xa084, 0x0007, 0x0079, 0x5681, + 0x007c, 0x5689, 0x5689, 0x5689, 0x57c8, 0x5689, 0x568a, 0x56a3, + 0x56f3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x56a2, 0x7120, 0x2160, + 0xac8c, 0x000f, 0x00c0, 0x56a2, 0xac8a, 0xaa00, 0x0048, 0x56a2, + 0x6854, 0xac02, 0x00c8, 0x56a2, 0x7124, 0x610a, 0x2009, 0x0046, + 0x1078, 0x756c, 0x007c, 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x56f1, + 0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, + 0x56f1, 0x1078, 0x4499, 0x00c0, 0x56f1, 0x6612, 0x6516, 0x6000, + 0xd0ec, 0x00c0, 0x56f1, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, + 0x0006, 0x00c0, 0x56d6, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, + 0x56f1, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6122, + 0x2009, 0x0044, 0x1078, 0x756c, 0x0078, 0x56f1, 0x0c7e, 0x1078, + 0x74d7, 0x017f, 0x0040, 0x56f1, 0x611a, 0x601f, 0x0004, 0x7120, + 0x610a, 0xa286, 0x0004, 0x00c0, 0x56e9, 0x6007, 0x0005, 0x0078, + 0x56eb, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078, + 0x6109, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x570b, 0x7020, + 0x2060, 0xac84, 0x000f, 0x00c0, 0x570b, 0xac82, 0xaa00, 0x0048, + 0x570b, 0x6854, 0xac02, 0x00c8, 0x570b, 0x7124, 0x610a, 0x2009, + 0x0045, 0x1078, 0x756c, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f, + 0xa18e, 0x0000, 0x00c0, 0x571c, 0xa084, 0x000f, 0xa08a, 0x0006, + 0x00c8, 0x571c, 0x1079, 0x571d, 0x007c, 0x5723, 0x5724, 0x5723, + 0x5723, 0x5794, 0x57a3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x572c, + 0x702c, 0xd084, 0x0040, 0x5793, 0x700c, 0x7108, 0x1078, 0x24e3, + 0x00c0, 0x5793, 0x1078, 0x4499, 0x00c0, 0x5793, 0x6612, 0x6516, + 0x6204, 0x7110, 0xd1bc, 0x0040, 0x575e, 0xa28c, 0x00ff, 0xa186, + 0x0004, 0x0040, 0x5747, 0xa186, 0x0006, 0x00c0, 0x5784, 0x0c7e, + 0x1078, 0x57b2, 0x0c7f, 0x0040, 0x5793, 0x0c7e, 0x1078, 0x74d7, + 0x017f, 0x0040, 0x5793, 0x611a, 0x601f, 0x0002, 0x7120, 0x610a, + 0x2009, 0x0088, 0x1078, 0x756c, 0x0078, 0x5793, 0xa28c, 0x00ff, + 0xa186, 0x0006, 0x0040, 0x5773, 0xa186, 0x0004, 0x0040, 0x5773, + 0xa294, 0xff00, 0x8217, 0xa286, 0x0004, 0x0040, 0x5773, 0xa286, + 0x0006, 0x00c0, 0x5784, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, + 0x5793, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, + 0x1078, 0x756c, 0x0078, 0x5793, 0x0c7e, 0x1078, 0x74d7, 0x017f, + 0x0040, 0x5793, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x2009, + 0x0001, 0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57a2, + 0x1078, 0x57b2, 0x0040, 0x57a2, 0x7124, 0x610a, 0x2009, 0x0089, + 0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57b1, 0x1078, + 0x57b2, 0x0040, 0x57b1, 0x7124, 0x610a, 0x2009, 0x008a, 0x1078, + 0x756c, 0x007c, 0x7020, 0x2060, 0xac84, 0x000f, 0x00c0, 0x57c5, + 0xac82, 0xaa00, 0x0048, 0x57c5, 0x2001, 0xa315, 0x2004, 0xac02, + 0x00c8, 0x57c5, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x57c4, + 0x7110, 0xd1bc, 0x00c0, 0x57de, 0x7024, 0x2060, 0xac84, 0x000f, + 0x00c0, 0x57de, 0xac82, 0xaa00, 0x0048, 0x57de, 0x6854, 0xac02, + 0x00c8, 0x57de, 0x2009, 0x0051, 0x1078, 0x756c, 0x007c, 0x2071, + 0xa5be, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012, + 0x7017, 0xaa00, 0x7007, 0x0000, 0x7026, 0x702b, 0x6c4e, 0x7032, + 0x7037, 0x6ca0, 0x703b, 0x0002, 0x703f, 0x0000, 0x7043, 0xffff, + 0x7047, 0xffff, 0x007c, 0x2071, 0xa5be, 0x00e0, 0x58c1, 0x2091, + 0x6000, 0x700c, 0x8001, 0x700e, 0x00c0, 0x5873, 0x700f, 0x0361, + 0x7007, 0x0001, 0x127e, 0x2091, 0x8000, 0x7138, 0x8109, 0x713a, + 0x00c0, 0x5871, 0x703b, 0x0002, 0x2009, 0x0100, 0x2104, 0xa082, + 0x0003, 0x00c8, 0x5871, 0x703c, 0xa086, 0x0001, 0x00c0, 0x584e, + 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x582c, + 0x6803, 0x1000, 0x0078, 0x5833, 0x6804, 0xa084, 0x1000, 0x0040, + 0x5833, 0x6803, 0x0100, 0x6803, 0x0000, 0x703f, 0x0000, 0x2069, + 0xa5ab, 0x6804, 0xa082, 0x0006, 0x00c0, 0x5840, 0x6807, 0x0000, + 0x6830, 0xa082, 0x0003, 0x00c0, 0x5847, 0x6833, 0x0000, 0x1078, + 0x6109, 0x1078, 0x61d3, 0x0d7f, 0x0078, 0x5871, 0x0d7e, 0x2069, + 0xa300, 0x6944, 0x6860, 0xa102, 0x00c8, 0x5870, 0x2069, 0xa5ab, + 0x6804, 0xa086, 0x0000, 0x00c0, 0x5870, 0x6830, 0xa086, 0x0000, + 0x00c0, 0x5870, 0x703f, 0x0001, 0x6807, 0x0006, 0x6833, 0x0003, + 0x2069, 0x0100, 0x6830, 0x689e, 0x2069, 0x0140, 0x6803, 0x0600, + 0x0d7f, 0x0078, 0x5876, 0x127e, 0x2091, 0x8000, 0x7024, 0xa00d, + 0x0040, 0x588e, 0x7020, 0x8001, 0x7022, 0x00c0, 0x588e, 0x7023, + 0x0009, 0x8109, 0x7126, 0xa186, 0x03e8, 0x00c0, 0x5889, 0x7028, + 0x107a, 0x81ff, 0x00c0, 0x588e, 0x7028, 0x107a, 0x7030, 0xa00d, + 0x0040, 0x589f, 0x702c, 0x8001, 0x702e, 0x00c0, 0x589f, 0x702f, + 0x0009, 0x8109, 0x7132, 0x00c0, 0x589f, 0x7034, 0x107a, 0x7040, + 0xa005, 0x0040, 0x58a7, 0x0050, 0x58a7, 0x8001, 0x7042, 0x7044, + 0xa005, 0x0040, 0x58af, 0x0050, 0x58af, 0x8001, 0x7046, 0x7018, + 0xa00d, 0x0040, 0x58c0, 0x7008, 0x8001, 0x700a, 0x00c0, 0x58c0, + 0x700b, 0x0009, 0x8109, 0x711a, 0x00c0, 0x58c0, 0x701c, 0x107a, + 0x127f, 0x7004, 0x0079, 0x58c4, 0x58eb, 0x58ec, 0x5908, 0x0e7e, + 0x2071, 0xa5be, 0x7018, 0xa005, 0x00c0, 0x58d2, 0x711a, 0x721e, + 0x700b, 0x0009, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071, 0xa5be, + 0x701c, 0xa206, 0x00c0, 0x58de, 0x701a, 0x701e, 0x007f, 0x0e7f, + 0x007c, 0x0e7e, 0x2071, 0xa5be, 0x6088, 0xa102, 0x0048, 0x58e9, + 0x618a, 0x0e7f, 0x007c, 0x007c, 0x7110, 0x1078, 0x4501, 0x00c0, + 0x58fe, 0x6088, 0x8001, 0x0048, 0x58fe, 0x608a, 0x00c0, 0x58fe, + 0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x8108, 0xa182, + 0x00ff, 0x0048, 0x5906, 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c, + 0x7014, 0x2060, 0x127e, 0x2091, 0x8000, 0x603c, 0xa005, 0x0040, + 0x5917, 0x8001, 0x603e, 0x00c0, 0x5917, 0x1078, 0x8cd7, 0x6014, + 0xa005, 0x0040, 0x5941, 0x8001, 0x6016, 0x00c0, 0x5941, 0x611c, + 0xa186, 0x0003, 0x0040, 0x5928, 0xa186, 0x0006, 0x00c0, 0x593f, + 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0048, 0x593f, 0xa082, + 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, 0x5938, 0x2001, 0x1999, + 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0078, 0x5941, 0x1078, + 0x8810, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xca00, 0xa102, + 0x0048, 0x594e, 0x7017, 0xaa00, 0x7007, 0x0000, 0x007c, 0x0e7e, + 0x2071, 0xa5be, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b, 0x0002, + 0x0e7f, 0x007c, 0x2001, 0xa5c7, 0x2003, 0x0000, 0x007c, 0x0e7e, + 0x2071, 0xa5be, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011, + 0xa5ca, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa5be, 0x711a, + 0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x027e, 0x0e7e, 0x0f7e, + 0x2079, 0xa300, 0x7a34, 0xd294, 0x0040, 0x59a4, 0x2071, 0xa5aa, + 0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5991, 0xa0fe, 0x0001, 0x0040, + 0x5995, 0xa0fe, 0x0002, 0x00c0, 0x59a0, 0xa292, 0x0085, 0x0078, + 0x5997, 0xa292, 0x0005, 0x0078, 0x5997, 0xa292, 0x0002, 0x2272, + 0x0040, 0x599c, 0x00c8, 0x59a4, 0x2011, 0x8037, 0x1078, 0x3579, + 0x2011, 0xa5a9, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f, 0x007c, + 0x0c7e, 0x2061, 0xa62d, 0x0c7f, 0x007c, 0xa184, 0x000f, 0x8003, + 0x8003, 0x8003, 0xa080, 0xa62d, 0x2060, 0x007c, 0x6854, 0xa08a, + 0x199a, 0x0048, 0x59bd, 0x2001, 0x1999, 0xa005, 0x00c0, 0x59cc, + 0x0c7e, 0x2061, 0xa62d, 0x6014, 0x0c7f, 0xa005, 0x00c0, 0x59d1, + 0x2001, 0x001e, 0x0078, 0x59d1, 0xa08e, 0xffff, 0x00c0, 0x59d1, + 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, + 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x5a24, 0xd0b4, 0x00c0, 0x59e8, + 0xd0bc, 0x00c0, 0x5a14, 0x2009, 0x0006, 0x1078, 0x5a43, 0x007c, + 0xd0fc, 0x0040, 0x59f3, 0xa084, 0x0003, 0x0040, 0x59f3, 0xa086, + 0x0003, 0x00c0, 0x5a3c, 0x6024, 0xd0d4, 0x0040, 0x59fd, 0xc0d4, + 0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa373, 0x2104, + 0xd084, 0x0040, 0x5a0f, 0x6118, 0xa188, 0x0027, 0x2104, 0xd08c, + 0x00c0, 0x5a0f, 0x2009, 0x0042, 0x1078, 0x756c, 0x007c, 0x2009, + 0x0043, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a1f, 0xa084, + 0x0003, 0x0040, 0x5a1f, 0xa086, 0x0003, 0x00c0, 0x5a3c, 0x2009, + 0x0042, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a32, 0xa084, + 0x0003, 0xa08e, 0x0002, 0x0040, 0x5a36, 0x2009, 0x0041, 0x1078, + 0x756c, 0x007c, 0x1078, 0x5a41, 0x0078, 0x5a31, 0x2009, 0x0043, + 0x1078, 0x756c, 0x0078, 0x5a31, 0x2009, 0x0004, 0x1078, 0x5a43, + 0x007c, 0x2009, 0x0001, 0x0d7e, 0x6010, 0xa0ec, 0xf000, 0x0040, + 0x5a6b, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0, + 0x5a65, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x5a65, + 0x0c7e, 0x2061, 0xa62d, 0x6200, 0xd28c, 0x00c0, 0x5a64, 0x6204, + 0x8210, 0x0048, 0x5a64, 0x6206, 0x0c7f, 0x1078, 0x4982, 0x6010, + 0xa06d, 0x10c0, 0x59b6, 0x0d7f, 0x007c, 0x157e, 0x0c7e, 0x2061, + 0xa62d, 0x6000, 0x81ff, 0x0040, 0x5a78, 0xa205, 0x0078, 0x5a79, + 0xa204, 0x6002, 0x0c7f, 0x157f, 0x007c, 0x6800, 0xd08c, 0x00c0, + 0x5a89, 0x6808, 0xa005, 0x0040, 0x5a89, 0x8001, 0x680a, 0xa085, + 0x0001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, + 0x00c8, 0x5a93, 0xa200, 0x00f0, 0x5a8e, 0x8086, 0x818e, 0x007c, + 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x5ab9, 0xa11a, 0x00c8, + 0x5ab9, 0x8213, 0x818d, 0x0048, 0x5aac, 0xa11a, 0x00c8, 0x5aad, + 0x00f0, 0x5aa1, 0x0078, 0x5ab1, 0xa11a, 0x2308, 0x8210, 0x00f0, + 0x5aa1, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, + 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x5ab5, 0x127e, + 0x2091, 0x2200, 0x2079, 0xa5ab, 0x127f, 0x0d7e, 0x2069, 0xa5ab, + 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a, + 0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007, + 0x0079, 0x5ada, 0x5ae4, 0x5b09, 0x5b64, 0x5aea, 0x5b09, 0x5ae4, + 0x5ae2, 0x5ae2, 0x1078, 0x1328, 0x1078, 0x595a, 0x1078, 0x6109, + 0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x5af0, 0x0c7f, 0x007c, + 0x2011, 0x4129, 0x1078, 0x58d4, 0x7828, 0xa092, 0x00c8, 0x00c8, + 0x5aff, 0x8000, 0x782a, 0x1078, 0x4168, 0x0078, 0x5aee, 0x1078, + 0x4129, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0078, + 0x5aee, 0x1078, 0x595a, 0x3c00, 0x007e, 0x2011, 0x0209, 0x20e1, + 0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x5b27, 0x62c0, + 0x82ff, 0x00c0, 0x5b27, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040, + 0x1328, 0x2009, 0x0013, 0x1078, 0x756c, 0x0c7f, 0x007c, 0x3900, + 0xa082, 0xa6cd, 0x00c8, 0x5b2e, 0x1078, 0x728a, 0x0c7e, 0x7824, + 0xa065, 0x1040, 0x1328, 0x7804, 0xa086, 0x0004, 0x0040, 0x5ba9, + 0x7828, 0xa092, 0x2710, 0x00c8, 0x5b44, 0x8000, 0x782a, 0x0c7f, + 0x1078, 0x6c33, 0x0078, 0x5b25, 0x6104, 0xa186, 0x0003, 0x00c0, + 0x5b5b, 0x0e7e, 0x2071, 0xa300, 0x70d4, 0x0e7f, 0xd08c, 0x0040, + 0x5b5b, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0xa300, 0x1078, + 0x4171, 0x0e7f, 0x0c7f, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078, + 0x756c, 0x0c7f, 0x0078, 0x5b25, 0x2001, 0xa5c7, 0x2003, 0x0000, + 0x62c0, 0x82ff, 0x00c0, 0x5b78, 0x782b, 0x0000, 0x7824, 0xa065, + 0x1040, 0x1328, 0x2009, 0x0013, 0x1078, 0x75c3, 0x0c7f, 0x007c, + 0x0c7e, 0x0d7e, 0x3900, 0xa082, 0xa6cd, 0x00c8, 0x5b81, 0x1078, + 0x728a, 0x7824, 0xa005, 0x1040, 0x1328, 0x781c, 0xa06d, 0x1040, + 0x1328, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, 0x753d, + 0x693c, 0x81ff, 0x1040, 0x1328, 0x8109, 0x693e, 0x6854, 0xa015, + 0x0040, 0x5b9d, 0x7a1e, 0x0078, 0x5b9f, 0x7918, 0x791e, 0x7807, + 0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x6109, 0x0078, + 0x5b76, 0x6104, 0xa186, 0x0002, 0x0040, 0x5bb4, 0xa186, 0x0004, + 0x0040, 0x5bb4, 0x0078, 0x5b38, 0x7808, 0xac06, 0x0040, 0x5b38, + 0x1078, 0x6010, 0x1078, 0x5c45, 0x0c7f, 0x1078, 0x6109, 0x0078, + 0x5b25, 0x0c7e, 0x6027, 0x0002, 0x62c8, 0x82ff, 0x00c0, 0x5bdb, + 0x62c4, 0x82ff, 0x00c0, 0x5bdb, 0x793c, 0xa1e5, 0x0000, 0x0040, + 0x5bd5, 0x2009, 0x0049, 0x1078, 0x756c, 0x2011, 0xa5ca, 0x2013, + 0x0000, 0x0c7f, 0x007c, 0x3908, 0xa192, 0xa6cd, 0x00c8, 0x5be2, + 0x1078, 0x728a, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x5bd5, + 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x5bf4, + 0x6017, 0x0012, 0x0078, 0x5bd9, 0x6017, 0x0016, 0x0078, 0x5bd9, + 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, + 0x2c08, 0x2061, 0xa5ab, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005, + 0x0040, 0x5c13, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, 0x0c7f, + 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x5c0e, 0x0d7e, + 0x2069, 0xa5ab, 0x6000, 0xd0d4, 0x0040, 0x5c2c, 0x6820, 0x8000, + 0x6822, 0xa086, 0x0001, 0x00c0, 0x5c27, 0x2c00, 0x681e, 0x6804, + 0xa084, 0x0007, 0x0079, 0x6111, 0xc0d5, 0x6002, 0x6818, 0xa005, + 0x0040, 0x5c3e, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00, 0x681a, + 0x0d7f, 0x685a, 0x2069, 0xa5ab, 0x0078, 0x5c1e, 0x6056, 0x605a, + 0x2c00, 0x681a, 0x681e, 0x0078, 0x5c1e, 0x007e, 0x017e, 0x0c7e, + 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xa5ab, + 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x5c60, 0xa080, + 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f, 0x007c, + 0x610e, 0x610a, 0x0078, 0x5c5b, 0x0c7e, 0x600f, 0x0000, 0x2c08, + 0x2061, 0xa5ab, 0x6034, 0xa005, 0x0040, 0x5c74, 0xa080, 0x0003, + 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078, 0x5c72, + 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x017e, 0x007e, + 0x127e, 0x2071, 0xa5ab, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, + 0x8cff, 0x0040, 0x5ced, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, + 0x00c0, 0x5ce8, 0x87ff, 0x0040, 0x5c99, 0x6020, 0xa106, 0x00c0, + 0x5ce8, 0x703c, 0xac06, 0x00c0, 0x5cab, 0x037e, 0x2019, 0x0001, + 0x1078, 0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, + 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5cb1, 0x660c, + 0x763a, 0x7034, 0xac36, 0x00c0, 0x5cbf, 0x2c00, 0xaf36, 0x0040, + 0x5cbd, 0x2f00, 0x7036, 0x0078, 0x5cbf, 0x7037, 0x0000, 0x660c, + 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5cc8, 0x7e0e, 0x0078, 0x5cc9, + 0x2678, 0x600f, 0x0000, 0x1078, 0x8a44, 0x0040, 0x5ce3, 0x6010, + 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5cf7, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078, + 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5c88, + 0x2c78, 0x600c, 0x2060, 0x0078, 0x5c88, 0x127f, 0x007f, 0x017f, + 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, + 0xa086, 0x0006, 0x00c0, 0x5cd6, 0x1078, 0xa181, 0x1078, 0x9e70, + 0x0078, 0x5ce3, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031, + 0x0000, 0x127e, 0x2091, 0x8000, 0x2079, 0xa5ab, 0x7838, 0xa065, + 0x0040, 0x5d41, 0x600c, 0x007e, 0x600f, 0x0000, 0x783c, 0xac06, + 0x00c0, 0x5d28, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x7833, + 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, 0x037f, + 0x1078, 0x8a44, 0x0040, 0x5d3c, 0x6010, 0x2068, 0x601c, 0xa086, + 0x0003, 0x00c0, 0x5d4a, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, + 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x007f, 0x0078, + 0x5d0f, 0x7e3a, 0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f, + 0x007f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5d33, 0x1078, + 0x9e70, 0x0078, 0x5d3c, 0x017e, 0x027e, 0x087e, 0x2041, 0x0000, + 0x1078, 0x5d6d, 0x1078, 0x5e21, 0x087f, 0x027f, 0x017f, 0x007c, + 0x0f7e, 0x127e, 0x2079, 0xa5ab, 0x2091, 0x8000, 0x1078, 0x5ebc, + 0x1078, 0x5f32, 0x127f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, + 0x0c7e, 0x067e, 0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, + 0xa5ab, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5e01, 0x6018, + 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x5dfc, 0x88ff, 0x0040, + 0x5d8d, 0x6020, 0xa106, 0x00c0, 0x5dfc, 0x7024, 0xac06, 0x00c0, + 0x5dbd, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5db8, 0x1078, + 0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, + 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, + 0x5dad, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0040, 0x5db5, 0x6827, 0x0001, 0x037f, 0x0078, 0x5dbd, + 0x6003, 0x0009, 0x630a, 0x0078, 0x5dfc, 0x7014, 0xac36, 0x00c0, + 0x5dc3, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x5dd1, 0x2c00, + 0xaf36, 0x0040, 0x5dcf, 0x2f00, 0x7012, 0x0078, 0x5dd1, 0x7013, + 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5dda, 0x7e0e, + 0x0078, 0x5ddb, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, + 0x8a44, 0x0040, 0x5df5, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5e0a, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, + 0xa181, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078, + 0x7045, 0x0c7f, 0x0078, 0x5d7c, 0x2c78, 0x600c, 0x2060, 0x0078, + 0x5d7c, 0x127f, 0x007f, 0x017f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, + 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5e15, 0x1078, + 0xa181, 0x1078, 0x9e70, 0x0078, 0x5df5, 0x601c, 0xa086, 0x0002, + 0x00c0, 0x5df5, 0x6004, 0xa086, 0x0085, 0x0040, 0x5de8, 0x0078, + 0x5df5, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0xa280, 0xa434, + 0x2004, 0xa065, 0x0040, 0x5eb8, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e, + 0x2071, 0xa5ab, 0x6654, 0x7018, 0xac06, 0x00c0, 0x5e38, 0x761a, + 0x701c, 0xac06, 0x00c0, 0x5e44, 0x86ff, 0x00c0, 0x5e43, 0x7018, + 0x701e, 0x0078, 0x5e44, 0x761e, 0x6058, 0xa07d, 0x0040, 0x5e49, + 0x7e56, 0xa6ed, 0x0000, 0x0040, 0x5e4f, 0x2f00, 0x685a, 0x6057, + 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, + 0x4410, 0x0040, 0x5eb4, 0x7624, 0x86ff, 0x0040, 0x5ea2, 0xa680, + 0x0004, 0x2004, 0xad06, 0x00c0, 0x5ea2, 0x0d7e, 0x2069, 0x0100, + 0x68c0, 0xa005, 0x0040, 0x5e99, 0x1078, 0x595a, 0x1078, 0x6c41, + 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069, + 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5e82, 0x6803, 0x0100, + 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5e8a, + 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, + 0x5e93, 0x8001, 0x603e, 0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078, + 0x5ea2, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, + 0x0078, 0x5e57, 0x8dff, 0x0040, 0x5eb0, 0x6837, 0x0103, 0x6b4a, + 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078, 0x4982, + 0x1078, 0x7045, 0x0078, 0x5e57, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e, + 0x2031, 0x0000, 0x7814, 0xa065, 0x0040, 0x5f16, 0x600c, 0x007e, + 0x600f, 0x0000, 0x7824, 0xac06, 0x00c0, 0x5efb, 0x2069, 0x0100, + 0x68c0, 0xa005, 0x0040, 0x5ef5, 0x1078, 0x595a, 0x1078, 0x6c41, + 0x68c3, 0x0000, 0x1078, 0x7188, 0x7827, 0x0000, 0x037e, 0x2069, + 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5eea, 0x6803, 0x0100, + 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5ef2, + 0x6827, 0x0001, 0x037f, 0x0078, 0x5efb, 0x6003, 0x0009, 0x630a, + 0x2c30, 0x0078, 0x5f13, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, + 0x5f0f, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5f1d, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, + 0x8c01, 0x1078, 0x7045, 0x007f, 0x0078, 0x5ec3, 0x7e16, 0x7e12, + 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006, + 0x00c0, 0x5f26, 0x1078, 0x9e70, 0x0078, 0x5f0f, 0x601c, 0xa086, + 0x0002, 0x00c0, 0x5f0f, 0x6004, 0xa086, 0x0085, 0x0040, 0x5f06, + 0x0078, 0x5f0f, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065, + 0x0040, 0x5fa0, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000, + 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x4410, 0x0040, 0x5f9d, + 0x7e24, 0x86ff, 0x0040, 0x5f8f, 0xa680, 0x0004, 0x2004, 0xad06, + 0x00c0, 0x5f8f, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, + 0x5f86, 0x1078, 0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, + 0x7188, 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, + 0x1000, 0x0040, 0x5f6f, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0040, 0x5f77, 0x6827, 0x0001, 0x037f, + 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5f80, 0x8001, 0x603e, + 0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5f8f, 0x0d7f, 0x0c7e, + 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x5f44, 0x8dff, + 0x0040, 0x5f99, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, + 0x4982, 0x1078, 0x7045, 0x0078, 0x5f44, 0x007f, 0x0078, 0x5f37, + 0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e, + 0x0d7e, 0x067e, 0x6000, 0xd0dc, 0x0040, 0x5fc4, 0x604c, 0xa06d, + 0x0040, 0x5fc4, 0x6848, 0xa606, 0x00c0, 0x5fc4, 0x2071, 0xa5ab, + 0x7024, 0xa035, 0x0040, 0x5fc4, 0xa080, 0x0004, 0x2004, 0xad06, + 0x00c0, 0x5fc4, 0x1078, 0x5fc8, 0x067f, 0x0d7f, 0x0e7f, 0x007c, + 0x0f7e, 0x2079, 0x0100, 0x78c0, 0xa005, 0x00c0, 0x5fd7, 0x0c7e, + 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x600e, 0x1078, + 0x6c41, 0x78c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, + 0x2079, 0x0140, 0x7b04, 0xa384, 0x1000, 0x0040, 0x5feb, 0x7803, + 0x0100, 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, 0x0040, + 0x5ff3, 0x7827, 0x0001, 0x1078, 0x7188, 0x037f, 0x1078, 0x4410, + 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5fff, 0x8001, 0x603e, 0x2660, + 0x1078, 0x753d, 0x0c7f, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, + 0x1078, 0x8cb8, 0x1078, 0x4982, 0x1078, 0x7045, 0x0f7f, 0x007c, + 0x0e7e, 0x0c7e, 0x2071, 0xa5ab, 0x7004, 0xa084, 0x0007, 0x0079, + 0x6019, 0x6023, 0x6026, 0x603f, 0x605b, 0x60a0, 0x6023, 0x6023, + 0x6021, 0x1078, 0x1328, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, + 0x0040, 0x6034, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0040, + 0x603b, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, + 0x0c7f, 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x6034, 0x6018, + 0x2060, 0x1078, 0x4410, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, + 0x7022, 0x0040, 0x6050, 0x6054, 0xa015, 0x0040, 0x6057, 0x721e, + 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218, + 0x721e, 0x0078, 0x6050, 0x7024, 0xa065, 0x0040, 0x609d, 0x700c, + 0xac06, 0x00c0, 0x6072, 0x1078, 0x7045, 0x600c, 0xa015, 0x0040, + 0x606e, 0x720e, 0x600f, 0x0000, 0x0078, 0x609b, 0x720e, 0x720a, + 0x0078, 0x609b, 0x7014, 0xac06, 0x00c0, 0x6085, 0x1078, 0x7045, + 0x600c, 0xa015, 0x0040, 0x6081, 0x7216, 0x600f, 0x0000, 0x0078, + 0x609b, 0x7216, 0x7212, 0x0078, 0x609b, 0x6018, 0x2060, 0x1078, + 0x4410, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x7045, 0x701c, 0xa065, + 0x0040, 0x609b, 0x6054, 0xa015, 0x0040, 0x6099, 0x721e, 0x0078, + 0x609b, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, + 0x7024, 0xa065, 0x0040, 0x60ad, 0x1078, 0x7045, 0x600c, 0xa015, + 0x0040, 0x60b4, 0x720e, 0x600f, 0x0000, 0x1078, 0x7188, 0x7027, + 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078, 0x60ad, + 0x0d7e, 0x2069, 0xa5ab, 0x6830, 0xa084, 0x0003, 0x0079, 0x60c0, + 0x60c6, 0x60c8, 0x60ee, 0x60c6, 0x1078, 0x1328, 0x0d7f, 0x007c, + 0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x60e4, 0x683c, 0xa065, + 0x0040, 0x60d9, 0x600c, 0xa015, 0x0040, 0x60e0, 0x6a3a, 0x600f, + 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c, + 0x683a, 0x6836, 0x0078, 0x60d9, 0x6843, 0x0000, 0x6838, 0xa065, + 0x0040, 0x60d9, 0x6003, 0x0003, 0x0078, 0x60d9, 0x0c7e, 0x6843, + 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x6106, 0x600c, + 0xa015, 0x0040, 0x6102, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, + 0x0078, 0x6106, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f, + 0x007c, 0x0d7e, 0x2069, 0xa5ab, 0x6804, 0xa084, 0x0007, 0x0079, + 0x6111, 0x611b, 0x61c2, 0x61c2, 0x61c2, 0x61c2, 0x61c4, 0x61c2, + 0x6119, 0x1078, 0x1328, 0x6820, 0xa005, 0x00c0, 0x6121, 0x0d7f, + 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x6130, 0x6807, 0x0004, + 0x6826, 0x682b, 0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c, + 0x6814, 0xa065, 0x0040, 0x613e, 0x6807, 0x0001, 0x6826, 0x682b, + 0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e, + 0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x61bd, 0x704c, 0xa00d, 0x0040, + 0x614d, 0x7088, 0xa005, 0x0040, 0x6165, 0x7054, 0xa075, 0x0040, + 0x6156, 0xa20e, 0x0040, 0x61bd, 0x0078, 0x615b, 0x6818, 0xa20e, + 0x0040, 0x61bd, 0x2070, 0x704c, 0xa00d, 0x0040, 0x614d, 0x7088, + 0xa005, 0x00c0, 0x614d, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, + 0x00c8, 0x614d, 0x1078, 0x750c, 0x0040, 0x61bd, 0x8318, 0x733e, + 0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff, + 0x6032, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004, + 0xa08a, 0x199a, 0x0048, 0x6186, 0x2001, 0x1999, 0x8003, 0x801b, + 0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc, + 0x0040, 0x619f, 0x7100, 0xd1f4, 0x0040, 0x619b, 0x7114, 0xa18c, + 0x00ff, 0x0078, 0x61a4, 0x2009, 0x0000, 0x0078, 0x61a4, 0xa1e0, + 0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078, + 0x679b, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26, + 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, + 0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f, + 0x0078, 0x61bb, 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, + 0x61d0, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x620a, + 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa5ab, 0x6830, + 0xa086, 0x0000, 0x00c0, 0x61f1, 0x6838, 0xa07d, 0x0040, 0x61f1, + 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091, + 0x2200, 0x027f, 0x1078, 0x1d28, 0x00c0, 0x61f4, 0x127f, 0x1078, + 0x6ae5, 0x0d7f, 0x0f7f, 0x007c, 0x127f, 0x6843, 0x0000, 0x7803, + 0x0002, 0x780c, 0xa015, 0x0040, 0x6206, 0x6a3a, 0x780f, 0x0000, + 0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x61f1, 0x683a, 0x6836, + 0x0078, 0x6200, 0x601c, 0xa084, 0x000f, 0x1079, 0x6210, 0x007c, + 0x6219, 0x621e, 0x663f, 0x6758, 0x621e, 0x663f, 0x6758, 0x6219, + 0x621e, 0x1078, 0x6010, 0x1078, 0x6109, 0x007c, 0x157e, 0x137e, + 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0044, 0x10c8, 0x1328, + 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x623b, 0x7900, 0xd1f4, + 0x0040, 0x6237, 0x7914, 0xa18c, 0x00ff, 0x0078, 0x6240, 0x2009, + 0x0000, 0x0078, 0x6240, 0xa1f8, 0x293f, 0x2f0c, 0xa18c, 0x00ff, + 0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x00c8, 0x6292, + 0x1079, 0x6250, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c, + 0x62f8, 0x6340, 0x6368, 0x6403, 0x6433, 0x643b, 0x6462, 0x6473, + 0x6484, 0x648c, 0x64a4, 0x648c, 0x650f, 0x6473, 0x6530, 0x6538, + 0x6484, 0x6538, 0x6549, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290, + 0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6d05, 0x6d2a, + 0x6d3f, 0x6d62, 0x6d83, 0x6462, 0x6290, 0x6462, 0x648c, 0x6290, + 0x6368, 0x6403, 0x6290, 0x72ac, 0x648c, 0x6290, 0x72cc, 0x648c, + 0x6290, 0x6290, 0x62f3, 0x62a1, 0x6290, 0x72f1, 0x7368, 0x7450, + 0x6290, 0x7461, 0x645c, 0x747d, 0x6290, 0x6d98, 0x6290, 0x6290, + 0x1078, 0x1328, 0x2100, 0x1079, 0x629b, 0x0f7f, 0x0c7f, 0x147f, + 0x137f, 0x157f, 0x007c, 0x629f, 0x629f, 0x629f, 0x62d5, 0x1078, + 0x1328, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x6567, 0x7810, 0x2068, + 0x20a3, 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x6850, 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0018, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x0d7e, 0x7818, + 0x2068, 0x68a0, 0xa082, 0x007e, 0x0048, 0x62d2, 0xa085, 0x0001, + 0x0d7f, 0x007c, 0xa006, 0x0078, 0x62d0, 0x0d7e, 0x20a1, 0x020b, + 0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8, + 0x000f, 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814, + 0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x1078, + 0x6c2d, 0x0d7f, 0x007c, 0x6030, 0x609a, 0x1078, 0x6c2d, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x5200, 0x20a3, 0x0000, + 0x0d7e, 0x2069, 0xa351, 0x6804, 0xd084, 0x0040, 0x6312, 0x6828, + 0x20a3, 0x0000, 0x017e, 0x1078, 0x24fa, 0x21a2, 0x017f, 0x0d7f, + 0x0078, 0x6317, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, + 0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301, + 0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048, + 0x6331, 0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078, + 0x6337, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000, + 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048, 0x6358, + 0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078, 0x635e, + 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9, 0x0004, + 0x2099, 0xa305, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x6567, 0x0c7e, 0x7818, 0x2060, 0x2001, + 0x0000, 0x1078, 0x48a2, 0x0c7f, 0x7818, 0xa080, 0x0028, 0x2004, + 0xa086, 0x007e, 0x00c0, 0x6383, 0x20a3, 0x0400, 0x620c, 0xc2b4, + 0x620e, 0x0078, 0x6385, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818, + 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x63d2, 0x2099, + 0xa58c, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084, 0x3fff, + 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0xa305, 0x53a6, + 0x20a9, 0x0004, 0x2099, 0xa301, 0x53a6, 0x20a9, 0x0010, 0x20a3, + 0x0000, 0x00f0, 0x63af, 0x2099, 0xa594, 0x3304, 0xc0dd, 0x20a2, + 0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040, 0x63ca, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9, 0x0004, + 0x0078, 0x63cc, 0x20a9, 0x0007, 0x20a3, 0x0000, 0x00f0, 0x63cc, + 0x0078, 0x63f2, 0x2099, 0xa58c, 0x20a9, 0x0008, 0x53a6, 0x20a9, + 0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301, + 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e3, 0x20a9, + 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e9, 0x2099, 0xa594, 0x20a9, + 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63f4, + 0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x63fa, 0x60c3, 0x0074, + 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, + 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, + 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351, + 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x641f, 0xa085, 0x0020, 0xd1a4, + 0x0040, 0x6424, 0xa085, 0x0010, 0xa085, 0x0002, 0x0d7e, 0x0078, + 0x64ed, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, + 0x5000, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, + 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0014, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65ef, + 0x0078, 0x6466, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004, + 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, + 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, + 0x0008, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8, + 0x20a3, 0x0200, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x65f8, + 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0040, 0x649b, + 0x20a2, 0x0078, 0x649d, 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, + 0x0008, 0x1078, 0x6c2d, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, + 0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, + 0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x64ca, 0x6998, 0xa184, + 0xc000, 0x00c0, 0x64c6, 0xd1ec, 0x0040, 0x64c2, 0x20a3, 0x2100, + 0x0078, 0x64cc, 0x20a3, 0x0100, 0x0078, 0x64cc, 0x20a3, 0x0400, + 0x0078, 0x64cc, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351, 0x7904, 0x0f7f, 0xd1ac, + 0x00c0, 0x64dc, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x64e1, 0xa085, + 0x0010, 0x2009, 0xa373, 0x210c, 0xd184, 0x0040, 0x64eb, 0x699c, + 0xd18c, 0x0040, 0x64ed, 0xa085, 0x0002, 0x027e, 0x2009, 0xa371, + 0x210c, 0xd1e4, 0x0040, 0x64fb, 0xc0c5, 0xa094, 0x0030, 0xa296, + 0x0010, 0x0040, 0x6505, 0xd1ec, 0x0040, 0x6505, 0xa094, 0x0030, + 0xa296, 0x0010, 0x0040, 0x6505, 0xc0bd, 0x027f, 0x20a2, 0x20a2, + 0x20a2, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1, + 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, + 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x0078, 0x62fe, + 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000, + 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x6c2d, + 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x1078, + 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, + 0x0000, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x027e, 0x037e, + 0x047e, 0x2019, 0x3200, 0x2021, 0x0800, 0x0078, 0x656e, 0x027e, + 0x037e, 0x047e, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, + 0x00c0, 0x6581, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x0078, + 0x65b6, 0xa286, 0x007f, 0x00c0, 0x658d, 0x0d7e, 0xa385, 0x00ff, + 0x20a2, 0x20a3, 0xfffd, 0x0078, 0x65a4, 0xd2bc, 0x0040, 0x65ac, + 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x659c, 0xa385, 0x00ff, 0x20a2, + 0x20a3, 0xfffc, 0x0078, 0x65a4, 0xa2e8, 0xa434, 0x2d6c, 0x6810, + 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, + 0x2da6, 0x0d7f, 0x0078, 0x65ba, 0x0d7e, 0xa2e8, 0xa434, 0x2d6c, + 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, + 0x6230, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x047f, 0x037f, 0x20a3, + 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, + 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc, + 0x22a2, 0x0d7e, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, + 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x65c1, 0x20a3, 0x0100, + 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x007c, 0x027e, + 0x037e, 0x047e, 0x2019, 0x3300, 0x2021, 0x0800, 0x0078, 0x65ff, + 0x027e, 0x037e, 0x047e, 0x2019, 0x2300, 0x2021, 0x0100, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, + 0x007e, 0x0048, 0x661c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, + 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, + 0x2da6, 0x0d7f, 0x0078, 0x662a, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, + 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, + 0x6230, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, 0x0000, 0x047f, + 0x037f, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, + 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0c7e, + 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a, 0x008c, + 0x10c8, 0x1328, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x665d, + 0x7900, 0xd1f4, 0x0040, 0x6659, 0x7914, 0xa18c, 0x00ff, 0x0078, + 0x6662, 0x2009, 0x0000, 0x0078, 0x6662, 0xa1f8, 0x293f, 0x2f0c, + 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085, + 0x1079, 0x666d, 0x0f7f, 0x0c7f, 0x007c, 0x6676, 0x6681, 0x669c, + 0x6674, 0x6674, 0x6674, 0x6676, 0x1078, 0x1328, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x66af, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f, + 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x66e3, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, + 0x1078, 0x6c2d, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, + 0x6724, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0004, 0x1078, 0x6c2d, 0x147f, 0x007c, 0x027e, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, + 0xa092, 0x007e, 0x0048, 0x66ce, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, + 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x66dd, 0x0d7e, 0xa0e8, + 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, + 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3, + 0x0000, 0x0078, 0x65c1, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x6702, + 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, + 0x0078, 0x6711, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, + 0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, + 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, + 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7a10, 0x22a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, + 0x6743, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8500, + 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, + 0x0d7f, 0x0078, 0x6752, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, + 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, + 0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x0078, 0x6715, + 0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x1048, 0x1328, + 0xa08a, 0x0053, 0x10c8, 0x1328, 0x7918, 0x2160, 0x61a0, 0xd1bc, + 0x0040, 0x6777, 0x6100, 0xd1f4, 0x0040, 0x6773, 0x6114, 0xa18c, + 0x00ff, 0x0078, 0x677c, 0x2009, 0x0000, 0x0078, 0x677c, 0xa1e0, + 0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, + 0x0040, 0x1079, 0x6786, 0x0f7f, 0x0c7f, 0x007c, 0x679b, 0x68a9, + 0x684a, 0x6a59, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799, + 0x6799, 0x6f5e, 0x6f6f, 0x6f80, 0x6f91, 0x6799, 0x748e, 0x6799, + 0x6f4d, 0x1078, 0x1328, 0x0d7e, 0x157e, 0x147e, 0x780b, 0xffff, + 0x20a1, 0x020b, 0x1078, 0x6806, 0x7910, 0x2168, 0x6948, 0x7922, + 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x000f, + 0x00c0, 0x67b6, 0x2001, 0x0005, 0x0078, 0x67c0, 0xd184, 0x0040, + 0x67bd, 0x2001, 0x0004, 0x0078, 0x67c0, 0xa084, 0x0006, 0x8004, + 0x017e, 0x2008, 0x7830, 0xa084, 0x00ff, 0x8007, 0xa105, 0x017f, + 0x20a2, 0xd1ac, 0x0040, 0x67d0, 0x20a3, 0x0002, 0x0078, 0x67dc, + 0xd1b4, 0x0040, 0x67d7, 0x20a3, 0x0001, 0x0078, 0x67dc, 0x20a3, + 0x0000, 0x2230, 0x0078, 0x67de, 0x6a80, 0x6e7c, 0x20a9, 0x0008, + 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0, 0x67e2, + 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084, + 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa5c7, 0x2003, 0x07d0, + 0x2001, 0xa5c6, 0x2003, 0x0009, 0x2001, 0xa5cc, 0x2003, 0x0002, + 0x1078, 0x157e, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, + 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, + 0x0040, 0x682c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, + 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, + 0x2da6, 0x0d7f, 0x0078, 0x683b, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, + 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, + 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2, + 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b, + 0x1078, 0x686a, 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, + 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, + 0x20a2, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x147f, 0x137f, 0x157f, + 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, + 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6888, 0x0d7e, 0xa0e8, + 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6897, + 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, + 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, + 0x0889, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, + 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, + 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x7810, 0xa06d, 0x1078, + 0x488f, 0x0040, 0x68bd, 0x684c, 0xa084, 0x2020, 0xa086, 0x2020, + 0x00c0, 0x68bd, 0x7824, 0xc0cd, 0x7826, 0x20a1, 0x020b, 0x1078, + 0x6a12, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, + 0xa084, 0xf000, 0x00c0, 0x68d4, 0x7810, 0xa084, 0x0700, 0x8007, + 0x1079, 0x68dc, 0x0078, 0x68d7, 0xa006, 0x1079, 0x68dc, 0x147f, + 0x137f, 0x157f, 0x0d7f, 0x007c, 0x68e6, 0x697e, 0x6989, 0x69b3, + 0x69c7, 0x69e3, 0x69ee, 0x68e4, 0x1078, 0x1328, 0x017e, 0x037e, + 0x694c, 0xa18c, 0x0003, 0x0040, 0x68f1, 0xa186, 0x0003, 0x00c0, + 0x6900, 0x6b78, 0x7824, 0xd0cc, 0x0040, 0x68f7, 0xc3e5, 0x23a2, + 0x6868, 0x20a2, 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x69be, + 0xa186, 0x0001, 0x10c0, 0x1328, 0x6b78, 0x7824, 0xd0cc, 0x0040, + 0x690a, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, + 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384, + 0x0300, 0x0040, 0x6978, 0xd3c4, 0x0040, 0x6920, 0x687c, 0xa108, + 0xd3cc, 0x0040, 0x6925, 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d, + 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, 0x692a, + 0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, 0x6978, + 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, 0x7818, + 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6958, 0x0d7e, 0xa0e8, + 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6967, + 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, + 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x007f, + 0x7b24, 0xd3cc, 0x0040, 0x6970, 0x20a3, 0x0889, 0x0078, 0x6972, + 0x20a3, 0x0898, 0x20a2, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, + 0x61c2, 0x037f, 0x017f, 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008, + 0x7824, 0xd0cc, 0x0040, 0x6985, 0xc2e5, 0x22a2, 0xa016, 0x0078, + 0x69bc, 0x2011, 0x0302, 0x7824, 0xd0cc, 0x0040, 0x6990, 0xc2e5, + 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, + 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, + 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, + 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, + 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x0040, + 0x69ba, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, + 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x1078, 0x6c2d, 0x007c, 0x2011, + 0x0100, 0x7824, 0xd0cc, 0x0040, 0x69ce, 0xc2e5, 0x22a2, 0xa016, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2, + 0x7834, 0xa084, 0x00ff, 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020, + 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0040, + 0x69ea, 0xc2e5, 0x22a2, 0xa016, 0x0078, 0x69bc, 0x037e, 0x7b10, + 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x6a01, + 0x7824, 0xd0cc, 0x0040, 0x69fd, 0xc2e5, 0x22a2, 0x037f, 0x0078, + 0x69bc, 0x047e, 0x2021, 0x0800, 0x007e, 0x7824, 0xd0cc, 0x007f, + 0x0040, 0x6a0b, 0xc4e5, 0x24a2, 0x047f, 0x22a2, 0x20a2, 0x037f, + 0x0078, 0x69be, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, + 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6a30, 0x0d7e, 0xa0e8, + 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6a3f, + 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, + 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x7824, + 0xd0cc, 0x0040, 0x6a47, 0x20a3, 0x0889, 0x0078, 0x6a49, 0x20a3, + 0x0898, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, + 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, + 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810, + 0xa084, 0x0700, 0x8007, 0x1079, 0x6a6c, 0x037f, 0x017f, 0x147f, + 0x137f, 0x157f, 0x0d7f, 0x007c, 0x6a74, 0x6a74, 0x6a76, 0x6a74, + 0x6a74, 0x6a74, 0x6a9b, 0x6a74, 0x1078, 0x1328, 0x7910, 0xa18c, + 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, + 0x1078, 0x6aa5, 0x0d7e, 0x2069, 0xa351, 0x6804, 0xd0bc, 0x0040, + 0x6a90, 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x6a92, + 0x20a3, 0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, + 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, + 0x6aa5, 0x20a3, 0x7f00, 0x0078, 0x6a93, 0x027e, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, + 0x6ac3, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0100, + 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, + 0x0d7f, 0x0078, 0x6ad2, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, + 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, + 0x6230, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078, + 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, + 0x057e, 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0xa300, 0x6130, + 0x7818, 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6afc, 0x6910, + 0x6a14, 0x6430, 0x0078, 0x6b00, 0x6910, 0x6a14, 0x7368, 0x746c, + 0x781c, 0xa086, 0x0006, 0x0040, 0x6b5f, 0xd5bc, 0x0040, 0x6b10, + 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6b17, + 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, + 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, + 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, + 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, + 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, + 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6b49, 0x6a00, 0xd2f4, + 0x0040, 0x6b47, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6b49, 0x2011, + 0x0000, 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084, + 0xfff0, 0xa005, 0x0040, 0x6b56, 0x2009, 0x1b58, 0x1078, 0x595f, + 0x037f, 0x047f, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810, + 0x2070, 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x6bb7, + 0xd5bc, 0x0040, 0x6b73, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, + 0x646e, 0x0078, 0x6b7a, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, + 0x0000, 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, + 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, + 0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, + 0x60c6, 0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, + 0x7928, 0xa109, 0x792a, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, + 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6bb2, 0x6a00, + 0xd2f4, 0x0040, 0x6bb0, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6bb2, + 0x2011, 0x0000, 0x629e, 0x6017, 0x0012, 0x0078, 0x6b4c, 0xd5bc, + 0x0040, 0x6bc2, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, + 0x0078, 0x6bc9, 0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000, + 0x646e, 0x1078, 0x488f, 0x0040, 0x6bdf, 0x0d7e, 0x7810, 0xa06d, + 0x684c, 0x0d7f, 0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6bdf, + 0x7824, 0xc0cd, 0x7826, 0x6073, 0x0889, 0x0078, 0x6be1, 0x6073, + 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, + 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, + 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, + 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0xa582, 0x0080, 0x0048, 0x6c0f, 0x6a00, 0xd2f4, 0x0040, 0x6c0d, + 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6c0f, 0x2011, 0x0000, 0x629e, + 0x7824, 0xd0cc, 0x0040, 0x6c18, 0x6017, 0x0016, 0x0078, 0x6b4c, + 0x6017, 0x0012, 0x0078, 0x6b4c, 0x7a18, 0xa280, 0x0023, 0x2014, + 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069, + 0xa5ab, 0x6843, 0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x60a3, + 0x0056, 0x60a7, 0x9575, 0x1078, 0x6c38, 0x1078, 0x594f, 0x007c, + 0x007e, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x007f, + 0x007c, 0x007e, 0x0c7e, 0x2061, 0x0100, 0x6014, 0xa084, 0x0004, + 0xa085, 0x0008, 0x6016, 0x0c7f, 0x007f, 0x007c, 0x0c7e, 0x0d7e, + 0x017e, 0x027e, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, + 0x4000, 0x0040, 0x6c89, 0x1078, 0x6c41, 0x6803, 0x1000, 0x6803, + 0x0000, 0x0c7e, 0x2061, 0xa5ab, 0x6128, 0xa192, 0x00c8, 0x00c8, + 0x6c76, 0x8108, 0x612a, 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x6c84, + 0x1078, 0x594f, 0x1078, 0x6c38, 0x0078, 0x6c84, 0x6124, 0xa1e5, + 0x0000, 0x0040, 0x6c81, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078, + 0x756c, 0x0c7f, 0x0078, 0x6c84, 0x027f, 0x017f, 0x0d7f, 0x0c7f, + 0x007c, 0x2001, 0xa5c7, 0x2004, 0xa005, 0x00c0, 0x6c84, 0x0c7e, + 0x2061, 0xa5ab, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6c76, 0x8108, + 0x612a, 0x0c7f, 0x1078, 0x594f, 0x1078, 0x4171, 0x0078, 0x6c84, + 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x5967, 0x2071, + 0xa5ab, 0x713c, 0x81ff, 0x0040, 0x6cca, 0x2061, 0x0100, 0x2069, + 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x6cd0, 0x6803, 0x1000, + 0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x037f, + 0x713c, 0x2160, 0x1078, 0xa241, 0x2009, 0x004a, 0x1078, 0x756c, + 0x0078, 0x6cca, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, + 0x0078, 0x6cba, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, 0x047e, + 0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071, + 0xa5ab, 0x7018, 0x2068, 0x8dff, 0x0040, 0x6cfc, 0x68a0, 0xa406, + 0x0040, 0x6cee, 0x6854, 0x2068, 0x0078, 0x6ce3, 0x6010, 0x2060, + 0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078, 0x466a, 0x0040, 0x6cfc, + 0x1078, 0x7045, 0xa085, 0x0001, 0x127f, 0x007f, 0x047f, 0x057f, + 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x6567, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c, + 0xa086, 0x0004, 0x00c0, 0x6d17, 0x6098, 0x0078, 0x6d18, 0x6030, + 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006, + 0x20a2, 0x00f0, 0x6d20, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x1078, + 0x6c2d, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6567, + 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, + 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c, 0x157e, + 0x147e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x20a3, + 0x0000, 0x20a9, 0x0006, 0x2011, 0xa340, 0x2019, 0xa341, 0x23a6, + 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0, 0x6d4f, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x147f, + 0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, + 0x1078, 0x65cf, 0x1078, 0x65e6, 0x7810, 0xa080, 0x0000, 0x2004, + 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, + 0xa080, 0x0004, 0x8003, 0x60c2, 0x1078, 0x6c2d, 0x027f, 0x017f, + 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, + 0x6567, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, + 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c, + 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x6567, + 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808, + 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x1078, 0x6c2d, + 0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e, 0x0c7e, 0x007e, + 0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x700c, 0x2060, 0x8cff, + 0x0040, 0x6dd1, 0x1078, 0x8c3b, 0x00c0, 0x6dc8, 0x1078, 0x7a05, + 0x600c, 0x007e, 0x1078, 0x753d, 0x1078, 0x7045, 0x0c7f, 0x0078, + 0x6dbf, 0x700f, 0x0000, 0x700b, 0x0000, 0x127f, 0x007f, 0x0c7f, + 0x0e7f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, + 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, + 0x0140, 0x2071, 0xa5ab, 0x7024, 0x2060, 0x8cff, 0x0040, 0x6e2a, + 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x595a, 0x2009, 0x0013, + 0x1078, 0x756c, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x6e0d, + 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6e1f, 0x7803, + 0x1000, 0x7803, 0x0000, 0x0078, 0x6e1f, 0xd084, 0x0040, 0x6e14, + 0x6827, 0x0001, 0x0078, 0x6e16, 0x00f0, 0x6dfc, 0x7804, 0xa084, + 0x1000, 0x0040, 0x6e1f, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, + 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, + 0x127f, 0x007c, 0x2001, 0xa300, 0x2004, 0xa096, 0x0001, 0x0040, + 0x6e62, 0xa096, 0x0004, 0x0040, 0x6e62, 0x6817, 0x0008, 0x68c3, + 0x0000, 0x2011, 0x4129, 0x1078, 0x58d4, 0x20a9, 0x01f4, 0x6824, + 0xd094, 0x0040, 0x6e50, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, + 0x0040, 0x6e62, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x6e62, + 0xd084, 0x0040, 0x6e57, 0x6827, 0x0001, 0x0078, 0x6e59, 0x00f0, + 0x6e3f, 0x7804, 0xa084, 0x1000, 0x0040, 0x6e62, 0x7803, 0x0100, + 0x7803, 0x0000, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, + 0x0f7f, 0x157f, 0x127f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e, + 0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069, + 0x0100, 0x2079, 0x0140, 0x2071, 0xa5ab, 0x703c, 0x2060, 0x8cff, + 0x0040, 0x6ee8, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x00c0, + 0x6e86, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x1078, 0x5967, 0x1078, + 0x1f31, 0x047e, 0x057e, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5, + 0x2021, 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, + 0x6eb7, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x0e7e, 0x0f7e, 0x2079, + 0x0020, 0x2071, 0xa602, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012, + 0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x0f7f, 0x0e7f, 0x250a, + 0x057f, 0x047f, 0xa39d, 0x0000, 0x00c0, 0x6ec2, 0x2009, 0x0049, + 0x1078, 0x756c, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x6ed5, + 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6ee7, 0x7803, + 0x1000, 0x7803, 0x0000, 0x0078, 0x6ee7, 0xd08c, 0x0040, 0x6edc, + 0x6827, 0x0002, 0x0078, 0x6ede, 0x00f0, 0x6ec4, 0x7804, 0xa084, + 0x1000, 0x0040, 0x6ee7, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, + 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, + 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa5ab, + 0x6a06, 0x127f, 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, + 0x2069, 0xa5ab, 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, + 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2071, 0xa5ab, 0x7614, 0x2660, + 0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x6f46, 0x601c, 0xa206, + 0x00c0, 0x6f41, 0x7014, 0xac36, 0x00c0, 0x6f20, 0x660c, 0x7616, + 0x7010, 0xac36, 0x00c0, 0x6f2e, 0x2c00, 0xaf36, 0x0040, 0x6f2c, + 0x2f00, 0x7012, 0x0078, 0x6f2e, 0x7013, 0x0000, 0x660c, 0x067e, + 0x2c00, 0xaf06, 0x0040, 0x6f37, 0x7e0e, 0x0078, 0x6f38, 0x2678, + 0x600f, 0x0000, 0x1078, 0x8c01, 0x1078, 0x7045, 0x0c7f, 0x0078, + 0x6f13, 0x2c78, 0x600c, 0x2060, 0x0078, 0x6f13, 0x127f, 0x007f, + 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0078, 0x6fa0, 0x157e, 0x147e, + 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0078, 0x6fa0, 0x157e, + 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, + 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x6fa0, + 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, + 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, + 0x6fa0, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, + 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, + 0x1078, 0x7050, 0x60c3, 0x0020, 0x1078, 0x6c2d, 0x147f, 0x157f, + 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120, + 0xd1b4, 0x00c0, 0x6fb8, 0xd1bc, 0x00c0, 0x7002, 0x0078, 0x7042, + 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, + 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, + 0x0040, 0x6ff9, 0x6020, 0xd0b4, 0x0040, 0x6ff9, 0x6024, 0xd094, + 0x00c0, 0x6ff9, 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, + 0x6ff9, 0x00f0, 0x6fc5, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107, + 0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b, + 0xbc91, 0x6043, 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024, + 0xd094, 0x00c0, 0x6ff8, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x6fef, + 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, + 0x0078, 0x7042, 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, + 0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, + 0xa084, 0x4000, 0x0040, 0x703b, 0x6020, 0xd0bc, 0x0040, 0x703b, + 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x703b, 0x00f0, + 0x700f, 0x027e, 0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, + 0x00ff, 0xa10d, 0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, + 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, + 0x00c0, 0x7035, 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, + 0x200b, 0x0000, 0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa5ab, + 0x7020, 0xa005, 0x0040, 0x704e, 0x8001, 0x7022, 0x0e7f, 0x007c, + 0x20a9, 0x0008, 0x20a2, 0x00f0, 0x7052, 0x20a2, 0x20a2, 0x007c, + 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, + 0x2091, 0x8000, 0x2071, 0xa5ab, 0x7614, 0x2660, 0x2678, 0x2039, + 0x0001, 0x87ff, 0x0040, 0x70f4, 0x8cff, 0x0040, 0x70f4, 0x601c, + 0xa086, 0x0006, 0x00c0, 0x70ef, 0x88ff, 0x0040, 0x707f, 0x2800, + 0xac06, 0x00c0, 0x70ef, 0x2039, 0x0000, 0x0078, 0x708a, 0x6018, + 0xa206, 0x00c0, 0x70ef, 0x85ff, 0x0040, 0x708a, 0x6020, 0xa106, + 0x00c0, 0x70ef, 0x7024, 0xac06, 0x00c0, 0x70ba, 0x2069, 0x0100, + 0x68c0, 0xa005, 0x0040, 0x70b5, 0x1078, 0x595a, 0x6817, 0x0008, + 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069, + 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x70aa, 0x6803, 0x0100, + 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x70b2, + 0x6827, 0x0001, 0x037f, 0x0078, 0x70ba, 0x6003, 0x0009, 0x630a, + 0x0078, 0x70ef, 0x7014, 0xac36, 0x00c0, 0x70c0, 0x660c, 0x7616, + 0x7010, 0xac36, 0x00c0, 0x70ce, 0x2c00, 0xaf36, 0x0040, 0x70cc, + 0x2f00, 0x7012, 0x0078, 0x70ce, 0x7013, 0x0000, 0x660c, 0x067e, + 0x2c00, 0xaf06, 0x0040, 0x70d7, 0x7e0e, 0x0078, 0x70d8, 0x2678, + 0x89ff, 0x00c0, 0x70e7, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, + 0x8a44, 0x0040, 0x70e5, 0x1078, 0x9e70, 0x1078, 0x8c01, 0x1078, + 0x7045, 0x88ff, 0x00c0, 0x70fe, 0x0c7f, 0x0078, 0x7069, 0x2c78, + 0x600c, 0x2060, 0x0078, 0x7069, 0xa006, 0x127f, 0x007f, 0x067f, + 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, + 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x70f5, 0x0f7e, 0x0e7e, 0x0d7e, + 0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, + 0xa5ab, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x7177, 0x601c, + 0xa086, 0x0006, 0x00c0, 0x7172, 0x87ff, 0x0040, 0x7125, 0x2700, + 0xac06, 0x00c0, 0x7172, 0x0078, 0x7130, 0x6018, 0xa206, 0x00c0, + 0x7172, 0x85ff, 0x0040, 0x7130, 0x6020, 0xa106, 0x00c0, 0x7172, + 0x703c, 0xac06, 0x00c0, 0x7142, 0x037e, 0x2019, 0x0001, 0x1078, + 0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, + 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x7148, 0x660c, 0x763a, + 0x7034, 0xac36, 0x00c0, 0x7156, 0x2c00, 0xaf36, 0x0040, 0x7154, + 0x2f00, 0x7036, 0x0078, 0x7156, 0x7037, 0x0000, 0x660c, 0x067e, + 0x2c00, 0xaf06, 0x0040, 0x715f, 0x7e0e, 0x0078, 0x7160, 0x2678, + 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x716a, + 0x1078, 0x9e70, 0x1078, 0x8c01, 0x87ff, 0x00c0, 0x7181, 0x0c7f, + 0x0078, 0x7114, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7114, 0xa006, + 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa7bd, 0x0001, 0x0078, 0x7178, + 0x0e7e, 0x2071, 0xa5ab, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002, + 0x00c0, 0x7196, 0x7007, 0x0005, 0x0078, 0x7198, 0x7007, 0x0000, + 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, 0x007e, + 0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x2c10, 0x7638, 0x2660, + 0x2678, 0x8cff, 0x0040, 0x71d8, 0x2200, 0xac06, 0x00c0, 0x71d3, + 0x7038, 0xac36, 0x00c0, 0x71b6, 0x660c, 0x763a, 0x7034, 0xac36, + 0x00c0, 0x71c4, 0x2c00, 0xaf36, 0x0040, 0x71c2, 0x2f00, 0x7036, + 0x0078, 0x71c4, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0040, + 0x71cc, 0x7e0e, 0x0078, 0x71cd, 0x2678, 0x600f, 0x0000, 0xa085, + 0x0001, 0x0078, 0x71d8, 0x2c78, 0x600c, 0x2060, 0x0078, 0x71a9, + 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, + 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091, + 0x8000, 0x2071, 0xa5ab, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040, + 0x7279, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x7274, + 0x7024, 0xac06, 0x00c0, 0x721f, 0x2069, 0x0100, 0x68c0, 0xa005, + 0x0040, 0x724d, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188, + 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, + 0x0040, 0x7216, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0040, 0x721e, 0x6827, 0x0001, 0x037f, 0x700c, + 0xac36, 0x00c0, 0x7225, 0x660c, 0x760e, 0x7008, 0xac36, 0x00c0, + 0x7233, 0x2c00, 0xaf36, 0x0040, 0x7231, 0x2f00, 0x700a, 0x0078, + 0x7233, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, + 0x723c, 0x7e0e, 0x0078, 0x723d, 0x2678, 0x600f, 0x0000, 0x1078, + 0x8c27, 0x00c0, 0x7251, 0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0, + 0x726d, 0x1078, 0x7a05, 0x0078, 0x726d, 0x1078, 0x7188, 0x0078, + 0x721f, 0x1078, 0x8c3b, 0x00c0, 0x7259, 0x1078, 0x7a05, 0x0078, + 0x726d, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x726d, 0x601c, + 0xa086, 0x0003, 0x00c0, 0x7281, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078, + 0x7045, 0x0c7f, 0x0078, 0x71ee, 0x2c78, 0x600c, 0x2060, 0x0078, + 0x71ee, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x726d, 0x1078, 0x9e70, + 0x0078, 0x726d, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, 0xa006, + 0xa190, 0x0020, 0x221c, 0xa39e, 0x260c, 0x00c0, 0x729b, 0x8210, + 0x8000, 0x0078, 0x7292, 0xa005, 0x0040, 0x72a7, 0x20a9, 0x0020, + 0x2198, 0x8211, 0xa282, 0x0020, 0x20c8, 0x20a0, 0x53a3, 0x147f, + 0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, + 0x65f8, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x2099, 0xa5a3, 0x20a9, 0x0004, 0x53a6, + 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8, + 0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, + 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6c2d, + 0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x8ef5, + 0x00c0, 0x7361, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x1300, + 0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0040, + 0x733d, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0, + 0x7317, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0078, 0x7352, 0xa286, + 0x007f, 0x00c0, 0x7321, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0078, + 0x7352, 0xd2bc, 0x0040, 0x7337, 0xa286, 0x0080, 0x00c0, 0x732e, + 0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7352, 0xa2e8, 0xa434, + 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x0078, 0x7352, 0x20a3, + 0x0000, 0x6098, 0x20a2, 0x0078, 0x7352, 0x7818, 0xa080, 0x0028, + 0x2004, 0xa082, 0x007e, 0x0048, 0x734e, 0x0d7e, 0x2069, 0xa31a, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x7352, 0x20a3, 0x0000, + 0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x017f, 0x0d7f, + 0x007c, 0x7817, 0x0001, 0x7803, 0x0006, 0x017f, 0x0d7f, 0x007c, + 0x0d7e, 0x027e, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x0040, + 0x738a, 0xa186, 0x0003, 0x0040, 0x73e5, 0xa186, 0x0005, 0x0040, + 0x73c8, 0xa186, 0x0004, 0x0040, 0x73b8, 0xa186, 0x0008, 0x0040, + 0x73d2, 0x7807, 0x0037, 0x7813, 0x1700, 0x1078, 0x7450, 0x027f, + 0x0d7f, 0x007c, 0x1078, 0x740d, 0x2009, 0x4000, 0x6800, 0x0079, + 0x7391, 0x73a4, 0x73b2, 0x73a6, 0x73b2, 0x73ad, 0x73a4, 0x73a4, + 0x73b2, 0x73b2, 0x73b2, 0x73b2, 0x73a4, 0x73a4, 0x73a4, 0x73a4, + 0x73a4, 0x73b2, 0x73a4, 0x73b2, 0x1078, 0x1328, 0x6824, 0xd0e4, + 0x0040, 0x73ad, 0xd0cc, 0x0040, 0x73b0, 0xa00e, 0x0078, 0x73b2, + 0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0078, 0x7403, + 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, + 0x6a00, 0xa286, 0x0002, 0x00c0, 0x73c6, 0xa00e, 0x0078, 0x7403, + 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, + 0x0078, 0x7403, 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x2009, 0x4000, 0xa286, 0x0005, 0x0040, 0x73e2, 0xa286, 0x0002, + 0x00c0, 0x73e3, 0xa00e, 0x0078, 0x7403, 0x1078, 0x740d, 0x6810, + 0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2, + 0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002, 0x0040, + 0x7401, 0xa08e, 0x0004, 0x0040, 0x7401, 0x2009, 0x4000, 0x0078, + 0x7403, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018, + 0x1078, 0x6c2d, 0x027f, 0x0d7f, 0x007c, 0x037e, 0x047e, 0x057e, + 0x067e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0xa006, 0x20a3, 0x0200, + 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028, + 0x2004, 0xa092, 0x007e, 0x0048, 0x7433, 0x0d7e, 0x2069, 0xa31a, + 0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa434, 0x2d6c, 0x6b10, 0x6c14, + 0x0d7f, 0x0078, 0x7439, 0x2019, 0x0000, 0x6498, 0x2029, 0x0000, + 0x6630, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, 0x00c0, + 0x7447, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0078, 0x744b, 0x23a2, + 0x24a2, 0x25a2, 0x26a2, 0x067f, 0x057f, 0x047f, 0x037f, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000, + 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, + 0x007c, 0x20a1, 0x020b, 0x1078, 0x655e, 0x20a3, 0x1400, 0x20a3, + 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c, + 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000, + 0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x65ef, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810, + 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x7499, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f, + 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0xd0bc, 0x0040, 0x74b6, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, + 0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x74be, 0x20a3, 0x0300, + 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0819, + 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2, + 0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c, 0x2061, + 0xaa00, 0x2a70, 0x7060, 0x7046, 0x704b, 0xaa00, 0x007c, 0x0e7e, + 0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582, 0x0010, + 0x0048, 0x7509, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, + 0x74f5, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x74f1, 0x0078, + 0x74e4, 0x2061, 0xaa00, 0x0078, 0x74e4, 0x6003, 0x0008, 0x8529, + 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x7505, 0x754a, + 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00, 0x0078, + 0x7500, 0xa006, 0x0078, 0x7502, 0x0e7e, 0x2071, 0xa300, 0x7544, + 0xa582, 0x0010, 0x0048, 0x753a, 0x7048, 0x2060, 0x6000, 0xa086, + 0x0000, 0x0040, 0x7527, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, + 0x7523, 0x0078, 0x7516, 0x2061, 0xaa00, 0x0078, 0x7516, 0x6003, + 0x0008, 0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, + 0x7536, 0x754a, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704b, 0xaa00, + 0x0078, 0x7532, 0xa006, 0x0078, 0x7534, 0xac82, 0xaa00, 0x1048, + 0x1328, 0x2001, 0xa315, 0x2004, 0xac02, 0x10c8, 0x1328, 0xa006, + 0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, + 0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, + 0x603a, 0x603e, 0x2061, 0xa300, 0x6044, 0x8000, 0x6046, 0xa086, + 0x0001, 0x0040, 0x7564, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, + 0x6109, 0x127f, 0x0078, 0x7563, 0x601c, 0xa084, 0x000f, 0x0079, + 0x7571, 0x757a, 0x758b, 0x75a7, 0x75c3, 0x8f2d, 0x8f49, 0x8f65, + 0x757a, 0x758b, 0xa186, 0x0013, 0x00c0, 0x7583, 0x1078, 0x6010, + 0x1078, 0x6109, 0x007c, 0xa18e, 0x0047, 0x00c0, 0x758a, 0xa016, + 0x1078, 0x15ec, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, + 0x1328, 0x1079, 0x7595, 0x067f, 0x007c, 0x75a5, 0x7891, 0x7a34, + 0x75a5, 0x7ab8, 0x75df, 0x75a5, 0x75a5, 0x7823, 0x7e6d, 0x75a5, + 0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x1078, 0x1328, 0x067e, + 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079, 0x75b1, 0x067f, + 0x007c, 0x75c1, 0x8522, 0x75c1, 0x75c1, 0x75c1, 0x75c1, 0x75c1, + 0x75c1, 0x84c5, 0x86a8, 0x75c1, 0x8552, 0x85d8, 0x8552, 0x85d8, + 0x75c1, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, + 0x1328, 0x1079, 0x75cd, 0x067f, 0x007c, 0x75dd, 0x7eb4, 0x7f81, + 0x80c6, 0x8242, 0x75dd, 0x75dd, 0x75dd, 0x7e8d, 0x846d, 0x8471, + 0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x84a1, 0x1078, 0x1328, 0xa1b6, + 0x0015, 0x00c0, 0x75e7, 0x1078, 0x753d, 0x0078, 0x75ed, 0xa1b6, + 0x0016, 0x10c0, 0x1328, 0x1078, 0x753d, 0x007c, 0x20a9, 0x000e, + 0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, + 0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, + 0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x75fc, + 0x0e7e, 0x1078, 0x8a44, 0x0040, 0x7613, 0x6010, 0x2070, 0x7007, + 0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c, 0x0d7e, + 0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x7624, 0x6018, 0x2068, + 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x762e, + 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x753d, + 0x037f, 0x0d7f, 0x007c, 0x017e, 0x20a9, 0x002a, 0xae80, 0x000c, + 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a, + 0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3, + 0x0e7e, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, + 0x753d, 0x017f, 0x007c, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2c68, + 0x017e, 0x2009, 0x0035, 0x1078, 0x8ef5, 0x017f, 0x00c0, 0x766f, + 0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xa88c, 0x6b1c, 0xa386, + 0x0003, 0x0040, 0x7673, 0xa386, 0x0006, 0x0040, 0x7677, 0x1078, + 0x753d, 0x0078, 0x7679, 0x1078, 0x767c, 0x0078, 0x7679, 0x1078, + 0x771e, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x6810, 0x2078, 0xa186, + 0x0015, 0x0040, 0x7705, 0xa18e, 0x0016, 0x00c0, 0x771c, 0x700c, + 0xa084, 0xff00, 0xa086, 0x1700, 0x00c0, 0x76e0, 0x8fff, 0x0040, + 0x771a, 0x6808, 0xa086, 0xffff, 0x00c0, 0x7709, 0x784c, 0xa084, + 0x0060, 0xa086, 0x0020, 0x00c0, 0x76a7, 0x797c, 0x7810, 0xa106, + 0x00c0, 0x7709, 0x7980, 0x7814, 0xa106, 0x00c0, 0x7709, 0x1078, + 0x8bf4, 0x6830, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, 0x784e, + 0x027e, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x1078, 0x5a98, 0x7854, + 0xa20a, 0x0048, 0x76bc, 0x8011, 0x7a56, 0x82ff, 0x027f, 0x00c0, + 0x76c8, 0x0c7e, 0x2d60, 0x1078, 0x8832, 0x0c7f, 0x0078, 0x771a, + 0x0c7e, 0x0d7e, 0x2f68, 0x6838, 0xd0fc, 0x00c0, 0x76d3, 0x1078, + 0x4290, 0x0078, 0x76d5, 0x1078, 0x436e, 0x0d7f, 0x0c7f, 0x00c0, + 0x7709, 0x0c7e, 0x2d60, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x771a, + 0x7008, 0xa086, 0x000b, 0x00c0, 0x76fa, 0x6018, 0x200c, 0xc1bc, + 0x2102, 0x0c7e, 0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003, + 0x000b, 0x601f, 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, + 0x0078, 0x771a, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x7709, 0x2001, + 0xa5a2, 0x2004, 0x683e, 0x0078, 0x771a, 0x1078, 0x7739, 0x0078, + 0x771c, 0x8fff, 0x1040, 0x1328, 0x0c7e, 0x0d7e, 0x2d60, 0x2f68, + 0x684b, 0x0003, 0x1078, 0x8726, 0x1078, 0x8bf4, 0x1078, 0x8c01, + 0x0d7f, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0xa186, 0x0015, + 0x00c0, 0x7728, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x7736, + 0xa18e, 0x0016, 0x00c0, 0x7738, 0x0c7e, 0x2d00, 0x2060, 0x1078, + 0xa134, 0x1078, 0x5a41, 0x1078, 0x753d, 0x0c7f, 0x1078, 0x753d, + 0x007c, 0x027e, 0x037e, 0x047e, 0x7228, 0x7c80, 0x7b7c, 0xd2f4, + 0x0040, 0x7748, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x77ac, + 0x0c7e, 0x2d60, 0x1078, 0x874a, 0x0c7f, 0x6804, 0xa086, 0x0050, + 0x00c0, 0x7760, 0x0c7e, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, + 0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x77ac, + 0x6800, 0xa086, 0x000f, 0x0040, 0x7782, 0x8fff, 0x1040, 0x1328, + 0x6824, 0xd0dc, 0x00c0, 0x7782, 0x6800, 0xa086, 0x0004, 0x00c0, + 0x7787, 0x784c, 0xd0ac, 0x0040, 0x7787, 0x784c, 0xc0dc, 0xc0f4, + 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001, 0x0001, 0x682e, + 0x0078, 0x77a6, 0x2001, 0x0007, 0x682e, 0x0078, 0x77a6, 0x784c, + 0xd0b4, 0x00c0, 0x7794, 0xd0ac, 0x0040, 0x7782, 0x784c, 0xd0f4, + 0x00c0, 0x7782, 0x0078, 0x7775, 0xd2ec, 0x00c0, 0x7782, 0x7024, + 0xa306, 0x00c0, 0x779f, 0x7020, 0xa406, 0x0040, 0x7782, 0x7020, + 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, 0x1078, 0x8d2b, + 0x1078, 0x6109, 0x0078, 0x77ae, 0x1078, 0x753d, 0x047f, 0x037f, + 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x027e, 0x6034, 0x2068, 0x6a1c, + 0xa286, 0x0007, 0x0040, 0x7806, 0xa286, 0x0002, 0x0040, 0x7806, + 0xa286, 0x0000, 0x0040, 0x7806, 0x6808, 0x6338, 0xa306, 0x00c0, + 0x7806, 0x2071, 0xa88c, 0xa186, 0x0015, 0x0040, 0x7800, 0xa18e, + 0x0016, 0x00c0, 0x77e8, 0x6030, 0xa084, 0x00ff, 0xa086, 0x0001, + 0x00c0, 0x77e8, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x77e8, 0x6034, + 0xa080, 0x0009, 0x200c, 0xc1dd, 0xc1f5, 0x2102, 0x0078, 0x7800, + 0x0c7e, 0x6034, 0x2060, 0x6010, 0x2068, 0x1078, 0x8a44, 0x1040, + 0x1328, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, + 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x7806, + 0x6034, 0x2068, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x1078, 0x753d, + 0x027f, 0x0d7f, 0x0e7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98, + 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x7820, 0x6018, + 0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, + 0x0d7f, 0x0078, 0x7608, 0x2100, 0xa1b2, 0x0044, 0x10c8, 0x1328, + 0xa1b2, 0x0040, 0x00c8, 0x7888, 0x0079, 0x782e, 0x787c, 0x7870, + 0x787c, 0x787c, 0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e, + 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, + 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, + 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x787c, + 0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e, + 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, + 0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, + 0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x786e, 0x1078, 0x1328, + 0x6003, 0x0001, 0x6106, 0x1078, 0x5c45, 0x127e, 0x2091, 0x8000, + 0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, + 0x5c45, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, + 0x2600, 0x0079, 0x788b, 0x788f, 0x788f, 0x788f, 0x787c, 0x1078, + 0x1328, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328, 0xa1b6, 0x0013, + 0x00c0, 0x78a1, 0xa0b2, 0x0040, 0x00c8, 0x79fb, 0x2008, 0x0079, + 0x7941, 0xa1b6, 0x0027, 0x00c0, 0x78fe, 0x1078, 0x6010, 0x6004, + 0x1078, 0x8c27, 0x0040, 0x78be, 0x1078, 0x8c3b, 0x0040, 0x78f6, + 0xa08e, 0x0021, 0x0040, 0x78fa, 0xa08e, 0x0022, 0x0040, 0x78f6, + 0xa08e, 0x003d, 0x0040, 0x78fa, 0x0078, 0x78f1, 0x1078, 0x2839, + 0x2001, 0x0007, 0x1078, 0x443f, 0x6018, 0xa080, 0x0028, 0x200c, + 0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x78d3, 0x2001, 0xa332, + 0x2014, 0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, + 0x0028, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078, 0x5c78, + 0x0c7e, 0x6018, 0xa065, 0x0040, 0x78e7, 0x1078, 0x471b, 0x0c7f, + 0x2c08, 0x1078, 0x9c38, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078, + 0x44bc, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x7a05, + 0x0078, 0x78f1, 0x1078, 0x7a28, 0x0078, 0x78f1, 0xa186, 0x0014, + 0x00c0, 0x78f5, 0x1078, 0x6010, 0x1078, 0x2813, 0x1078, 0x8c27, + 0x00c0, 0x791d, 0x1078, 0x2839, 0x6018, 0xa080, 0x0028, 0x200c, + 0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x791b, 0x2001, 0xa332, + 0x200c, 0xc185, 0x2102, 0x0078, 0x78f1, 0x1078, 0x8c3b, 0x00c0, + 0x7925, 0x1078, 0x7a05, 0x0078, 0x78f1, 0x6004, 0xa08e, 0x0032, + 0x00c0, 0x7936, 0x0e7e, 0x0f7e, 0x2071, 0xa381, 0x2079, 0x0000, + 0x1078, 0x2b56, 0x0f7f, 0x0e7f, 0x0078, 0x78f1, 0x6004, 0xa08e, + 0x0021, 0x0040, 0x7921, 0xa08e, 0x0022, 0x1040, 0x7a05, 0x0078, + 0x78f1, 0x7983, 0x7985, 0x7989, 0x798d, 0x7991, 0x7995, 0x7981, + 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, + 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, + 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7999, + 0x79ab, 0x7981, 0x79ad, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981, + 0x7981, 0x79ab, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, + 0x7981, 0x7981, 0x7981, 0x79de, 0x79ab, 0x7981, 0x79a5, 0x7981, + 0x7981, 0x7981, 0x79a7, 0x7981, 0x7981, 0x7981, 0x79ab, 0x7981, + 0x7981, 0x1078, 0x1328, 0x0078, 0x79ab, 0x2001, 0x000b, 0x0078, + 0x79b8, 0x2001, 0x0003, 0x0078, 0x79b8, 0x2001, 0x0005, 0x0078, + 0x79b8, 0x2001, 0x0001, 0x0078, 0x79b8, 0x2001, 0x0009, 0x0078, + 0x79b8, 0x1078, 0x6010, 0x6003, 0x0005, 0x2001, 0xa5a2, 0x2004, + 0x603e, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0078, 0x79ab, 0x0078, + 0x79ab, 0x1078, 0x443f, 0x0078, 0x79f0, 0x1078, 0x6010, 0x6003, + 0x0004, 0x2001, 0xa5a0, 0x2004, 0x6016, 0x1078, 0x6109, 0x007c, + 0x1078, 0x443f, 0x1078, 0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e, + 0x6003, 0x0002, 0x037e, 0x2019, 0xa35c, 0x2304, 0xa084, 0xff00, + 0x00c0, 0x79cf, 0x2019, 0xa5a0, 0x231c, 0x0078, 0x79d8, 0x8007, + 0xa09a, 0x0004, 0x0048, 0x79ca, 0x8003, 0x801b, 0x831b, 0xa318, + 0x6316, 0x037f, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0e7e, 0x0f7e, + 0x2071, 0xa381, 0x2079, 0x0000, 0x1078, 0x2b56, 0x0f7f, 0x0e7f, + 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x0078, 0x79b7, + 0x1078, 0x6010, 0x6003, 0x0002, 0x2001, 0xa5a0, 0x2004, 0x6016, + 0x1078, 0x6109, 0x007c, 0x2600, 0x2008, 0x0079, 0x79ff, 0x7a03, + 0x7a03, 0x7a03, 0x79f0, 0x1078, 0x1328, 0x0e7e, 0x1078, 0x8a44, + 0x0040, 0x7a21, 0x6010, 0x2070, 0x7038, 0xd0fc, 0x0040, 0x7a21, + 0x7007, 0x0000, 0x017e, 0x6004, 0xa08e, 0x0021, 0x0040, 0x7a23, + 0xa08e, 0x003d, 0x0040, 0x7a23, 0x017f, 0x7037, 0x0103, 0x7033, + 0x0100, 0x0e7f, 0x007c, 0x017f, 0x1078, 0x7a28, 0x0078, 0x7a21, + 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, + 0x7023, 0x8001, 0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, + 0xa084, 0x00ff, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0x6604, + 0xa6b6, 0x0043, 0x00c0, 0x7a48, 0x1078, 0x8e6d, 0x0078, 0x7aa7, + 0x6604, 0xa6b6, 0x0033, 0x00c0, 0x7a51, 0x1078, 0x8e11, 0x0078, + 0x7aa7, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x7a5a, 0x1078, 0x8c6a, + 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7a63, 0x1078, + 0x8c84, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x7a6c, + 0x1078, 0x75ee, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0000, 0x00c0, + 0x7a75, 0x1078, 0x780c, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0022, + 0x00c0, 0x7a7e, 0x1078, 0x7617, 0x0078, 0x7aa7, 0x6604, 0xa6b6, + 0x0035, 0x00c0, 0x7a87, 0x1078, 0x7653, 0x0078, 0x7aa7, 0x6604, + 0xa6b6, 0x0039, 0x00c0, 0x7a90, 0x1078, 0x77b2, 0x0078, 0x7aa7, + 0x6604, 0xa6b6, 0x003d, 0x00c0, 0x7a99, 0x1078, 0x7633, 0x0078, + 0x7aa7, 0xa1b6, 0x0015, 0x00c0, 0x7aa1, 0x1079, 0x7aac, 0x0078, + 0x7aa7, 0xa1b6, 0x0016, 0x00c0, 0x7aa8, 0x1079, 0x7bfd, 0x007c, + 0x1078, 0x7583, 0x0078, 0x7aa7, 0x7ad0, 0x7ad3, 0x7ad0, 0x7b1e, + 0x7ad0, 0x7b91, 0x7c09, 0x7ad0, 0x7ad0, 0x7bd5, 0x7ad0, 0x7beb, + 0xa1b6, 0x0048, 0x0040, 0x7ac4, 0x20e1, 0x0005, 0x3d18, 0x3e20, + 0x2c10, 0x1078, 0x15ec, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, + 0x7000, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c, + 0x0005, 0x0005, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086, + 0x0074, 0x00c0, 0x7b07, 0x1078, 0x9c0c, 0x00c0, 0x7af9, 0x0d7e, + 0x6018, 0x2068, 0x7030, 0xd08c, 0x0040, 0x7aec, 0x6800, 0xd0bc, + 0x0040, 0x7aec, 0xc0c5, 0x6802, 0x1078, 0x7b0b, 0x0d7f, 0x2001, + 0x0006, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078, + 0x7b09, 0x2001, 0x000a, 0x1078, 0x443f, 0x1078, 0x2839, 0x6003, + 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7b09, 0x1078, + 0x7b81, 0x0e7f, 0x007c, 0x6800, 0xd084, 0x0040, 0x7b1d, 0x2001, + 0x0000, 0x1078, 0x442b, 0x2069, 0xa351, 0x6804, 0xd0a4, 0x0040, + 0x7b1d, 0x2001, 0x0006, 0x1078, 0x4472, 0x007c, 0x0d7e, 0x2011, + 0xa31f, 0x2204, 0xa086, 0x0074, 0x00c0, 0x7b7d, 0x6018, 0x2068, + 0x6aa0, 0xa286, 0x007e, 0x00c0, 0x7b31, 0x1078, 0x7d17, 0x0078, + 0x7b7f, 0x1078, 0x7d0d, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, + 0xa286, 0x0080, 0x00c0, 0x7b55, 0x6813, 0x00ff, 0x6817, 0xfffc, + 0x6010, 0xa005, 0x0040, 0x7b4b, 0x2068, 0x6807, 0x0000, 0x6837, + 0x0103, 0x6833, 0x0200, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078, + 0x2839, 0x1078, 0x753d, 0x0078, 0x7b7f, 0x0e7e, 0x2071, 0xa332, + 0x2e04, 0xd09c, 0x0040, 0x7b70, 0x2071, 0xa880, 0x7108, 0x720c, + 0xa18c, 0x00ff, 0x00c0, 0x7b68, 0xa284, 0xff00, 0x0040, 0x7b70, + 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x00c0, 0x7b70, 0x7112, 0x7216, + 0x0e7f, 0x2001, 0x0004, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007, + 0x0003, 0x1078, 0x5c45, 0x0078, 0x7b7f, 0x1078, 0x7b81, 0x0d7f, + 0x007c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x0040, 0x7b8c, + 0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d, + 0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086, 0x0014, 0x00c0, + 0x7bcf, 0x7000, 0xa086, 0x0003, 0x00c0, 0x7ba4, 0x6010, 0xa005, + 0x00c0, 0x7ba4, 0x1078, 0x35f7, 0x0d7e, 0x6018, 0x2068, 0x1078, + 0x457d, 0x1078, 0x7b0b, 0x0d7f, 0x1078, 0x7dba, 0x00c0, 0x7bcf, + 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x7bcf, + 0x2001, 0x0006, 0x1078, 0x443f, 0x0e7e, 0x6010, 0xa005, 0x0040, + 0x7bc8, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, + 0x0e7f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078, 0x7bd3, 0x1078, + 0x7a05, 0x1078, 0x7b81, 0x0e7f, 0x007c, 0x2011, 0xa31f, 0x2204, + 0xa086, 0x0014, 0x00c0, 0x7be8, 0x2001, 0x0002, 0x1078, 0x443f, + 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7bea, + 0x1078, 0x7b81, 0x007c, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0004, + 0x00c0, 0x7bfa, 0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x753d, + 0x0078, 0x7bfc, 0x1078, 0x7b81, 0x007c, 0x7ad0, 0x7c11, 0x7ad0, + 0x7c4e, 0x7ad0, 0x7cc0, 0x7c09, 0x7ad0, 0x7ad0, 0x7cd5, 0x7ad0, + 0x7ce8, 0x6604, 0xa6b6, 0x001e, 0x00c0, 0x7c10, 0x1078, 0x753d, + 0x007c, 0x0d7e, 0x0c7e, 0x1078, 0x7cfb, 0x00c0, 0x7c27, 0x2001, + 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003, + 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x0078, 0x7c4b, 0x2009, + 0xa88e, 0x2104, 0xa086, 0x0009, 0x00c0, 0x7c3c, 0x6018, 0x2068, + 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x7c49, 0x8001, 0x6842, + 0x6017, 0x000a, 0x0078, 0x7c4b, 0x2009, 0xa88f, 0x2104, 0xa084, + 0xff00, 0xa086, 0x1900, 0x00c0, 0x7c49, 0x1078, 0x753d, 0x0078, + 0x7c4b, 0x1078, 0x7b81, 0x0c7f, 0x0d7f, 0x007c, 0x1078, 0x7d0a, + 0x00c0, 0x7c62, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, + 0x1078, 0x443f, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, + 0x0078, 0x7c8e, 0x1078, 0x7a05, 0x2009, 0xa88e, 0x2134, 0xa6b4, + 0x00ff, 0xa686, 0x0005, 0x0040, 0x7c8f, 0xa686, 0x000b, 0x0040, + 0x7c8c, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0x00c0, 0x7c7c, + 0xa686, 0x0009, 0x0040, 0x7c8f, 0xa086, 0x1900, 0x00c0, 0x7c8c, + 0xa686, 0x0009, 0x0040, 0x7c8f, 0x2001, 0x0004, 0x1078, 0x443f, + 0x1078, 0x753d, 0x0078, 0x7c8e, 0x1078, 0x7b81, 0x007c, 0x0d7e, + 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x7c9d, 0x6838, 0xd0fc, + 0x0040, 0x7c9d, 0x0d7f, 0x0078, 0x7c8c, 0x6018, 0x2068, 0x6840, + 0xa084, 0x00ff, 0xa005, 0x0040, 0x7cae, 0x8001, 0x6842, 0x6017, + 0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x7c8e, 0x68a0, 0xa086, + 0x007e, 0x00c0, 0x7cbb, 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, + 0x0e7f, 0x0078, 0x7cbd, 0x1078, 0x2813, 0x0d7f, 0x0078, 0x7c8c, + 0x1078, 0x7d0a, 0x00c0, 0x7cd0, 0x2001, 0x0004, 0x1078, 0x443f, + 0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x5c45, 0x0078, 0x7cd4, + 0x1078, 0x7a05, 0x1078, 0x7b81, 0x007c, 0x1078, 0x7d0a, 0x00c0, + 0x7ce5, 0x2001, 0x0008, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007, + 0x0005, 0x1078, 0x5c45, 0x0078, 0x7ce7, 0x1078, 0x7b81, 0x007c, + 0x1078, 0x7d0a, 0x00c0, 0x7cf8, 0x2001, 0x000a, 0x1078, 0x443f, + 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7cfa, + 0x1078, 0x7b81, 0x007c, 0x2009, 0xa88e, 0x2104, 0xa086, 0x0003, + 0x00c0, 0x7d09, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0xa086, + 0x2a00, 0x007c, 0xa085, 0x0001, 0x007c, 0x0c7e, 0x017e, 0xac88, + 0x0006, 0x2164, 0x1078, 0x4513, 0x017f, 0x0c7f, 0x007c, 0x0f7e, + 0x0e7e, 0x0d7e, 0x037e, 0x017e, 0x6018, 0x2068, 0x2071, 0xa332, + 0x2e04, 0xa085, 0x0003, 0x2072, 0x1078, 0x7d8b, 0x0040, 0x7d50, + 0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x7d39, 0xa006, 0x2020, + 0x2009, 0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195, + 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x1078, 0x27e2, 0x2071, + 0xa300, 0x1078, 0x260d, 0x0c7e, 0x157e, 0x20a9, 0x0081, 0x2009, + 0x007f, 0x1078, 0x2921, 0x8108, 0x00f0, 0x7d49, 0x157f, 0x0c7f, + 0x1078, 0x7d0d, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0xa880, + 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa31a, 0x206a, + 0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa31b, 0x206a, 0x78ea, + 0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa325, 0x200a, 0x2069, + 0xa88e, 0x2071, 0xa59c, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818, + 0x700a, 0x681c, 0x700e, 0x1078, 0x8da9, 0x2001, 0x0006, 0x1078, + 0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x017f, 0x037f, 0x0d7f, + 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x037e, 0x0e7e, 0x157e, 0x2019, + 0xa325, 0x231c, 0x83ff, 0x0040, 0x7db5, 0x2071, 0xa880, 0x2e14, + 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x00c0, + 0x7db5, 0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078, + 0x7e55, 0x00c0, 0x7db5, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9, + 0x0004, 0x1078, 0x7e55, 0x00c0, 0x7db5, 0x157f, 0x0e7f, 0x037f, + 0x027f, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7004, 0xa086, 0x0014, + 0x00c0, 0x7ddd, 0x7008, 0xa086, 0x0800, 0x00c0, 0x7ddd, 0x700c, + 0xd0ec, 0x0040, 0x7ddb, 0xa084, 0x0f00, 0xa086, 0x0100, 0x00c0, + 0x7ddb, 0x7024, 0xd0a4, 0x00c0, 0x7dd8, 0xd0ac, 0x0040, 0x7ddb, + 0xa006, 0x0078, 0x7ddd, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e, + 0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e, + 0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba, 0x2424, + 0x2061, 0xaa00, 0x2071, 0xa300, 0x7244, 0x7060, 0xa202, 0x00c8, + 0x7e43, 0x1078, 0x9ee5, 0x0040, 0x7e3b, 0x671c, 0xa786, 0x0001, + 0x0040, 0x7e3b, 0xa786, 0x0007, 0x0040, 0x7e3b, 0x2500, 0xac06, + 0x0040, 0x7e3b, 0x2400, 0xac06, 0x0040, 0x7e3b, 0x0c7e, 0x6000, + 0xa086, 0x0004, 0x00c0, 0x7e16, 0x1078, 0x1749, 0xa786, 0x0008, + 0x00c0, 0x7e25, 0x1078, 0x8c3b, 0x00c0, 0x7e25, 0x0c7f, 0x1078, + 0x7a05, 0x1078, 0x8c01, 0x0078, 0x7e3b, 0x6010, 0x2068, 0x1078, + 0x8a44, 0x0040, 0x7e38, 0xa786, 0x0003, 0x00c0, 0x7e4d, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, + 0x1078, 0x8c01, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, + 0x7e43, 0x0078, 0x7df4, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f, + 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0, + 0x7e2f, 0x1078, 0x9e70, 0x0078, 0x7e38, 0x220c, 0x2304, 0xa106, + 0x00c0, 0x7e60, 0x8210, 0x8318, 0x00f0, 0x7e55, 0xa006, 0x007c, + 0x2304, 0xa102, 0x0048, 0x7e68, 0x2001, 0x0001, 0x0078, 0x7e6a, + 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0044, + 0x10c8, 0x1328, 0x1078, 0x8c27, 0x0040, 0x7e7c, 0x1078, 0x8c3b, + 0x0040, 0x7e89, 0x0078, 0x7e82, 0x1078, 0x2839, 0x1078, 0x8c3b, + 0x0040, 0x7e89, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, + 0x007c, 0x1078, 0x7a05, 0x0078, 0x7e82, 0xa182, 0x0040, 0x0079, + 0x7e91, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, + 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x7ea6, 0x7ea6, 0x7ea6, + 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x1078, 0x1328, 0x600b, 0xffff, + 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000, + 0x1078, 0x6109, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x7ebd, + 0x6004, 0xa082, 0x0040, 0x0079, 0x7f48, 0xa186, 0x0027, 0x00c0, + 0x7edf, 0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168, + 0x1078, 0x8a44, 0x0040, 0x7ed9, 0x6837, 0x0103, 0x684b, 0x0029, + 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x1078, 0x4982, 0x1078, + 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0xa186, + 0x0014, 0x00c0, 0x7ee8, 0x6004, 0xa082, 0x0040, 0x0079, 0x7f10, + 0xa186, 0x0046, 0x0040, 0x7ef4, 0xa186, 0x0045, 0x0040, 0x7ef4, + 0xa186, 0x0047, 0x10c0, 0x1328, 0x2001, 0x0109, 0x2004, 0xd084, + 0x0040, 0x7f0d, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, + 0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086, + 0x0002, 0x00c0, 0x7f0d, 0x0078, 0x7f81, 0x1078, 0x7583, 0x007c, + 0x7f25, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, + 0x7f23, 0x7f23, 0x7f23, 0x7f41, 0x7f41, 0x7f41, 0x7f41, 0x7f23, + 0x7f41, 0x7f23, 0x7f41, 0x1078, 0x1328, 0x1078, 0x6010, 0x0d7e, + 0x6110, 0x2168, 0x1078, 0x8a44, 0x0040, 0x7f3b, 0x6837, 0x0103, + 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x1078, + 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, + 0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, + 0x7f5d, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, + 0x7f5b, 0x7f5b, 0x7f5b, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f5b, + 0x7f7a, 0x7f5b, 0x7f6f, 0x1078, 0x1328, 0x1078, 0x6010, 0x2001, + 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x6109, 0x6010, + 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078, + 0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x000f, 0x1078, + 0x6109, 0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, + 0x007c, 0xa182, 0x0040, 0x0079, 0x7f85, 0x7f98, 0x7f98, 0x7f98, + 0x7f98, 0x7f98, 0x7f9a, 0x8095, 0x80b7, 0x7f98, 0x7f98, 0x7f98, + 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, + 0x1078, 0x1328, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2071, 0xa880, + 0x7124, 0x610a, 0x2071, 0xa88c, 0x6110, 0x2168, 0x7614, 0xa6b4, + 0x0fff, 0x86ff, 0x0040, 0x8058, 0xa68c, 0x0c00, 0x0040, 0x7fd1, + 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x7fcd, 0x684c, + 0xd0ac, 0x0040, 0x7fcd, 0x6024, 0xd0dc, 0x00c0, 0x7fcd, 0x6850, + 0xd0bc, 0x00c0, 0x7fcd, 0x7318, 0x6814, 0xa306, 0x00c0, 0x806f, + 0x731c, 0x6810, 0xa306, 0x00c0, 0x806f, 0x7318, 0x6b62, 0x731c, + 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x8004, 0xa186, + 0x0028, 0x00c0, 0x7fe1, 0x1078, 0x8c15, 0x684b, 0x001c, 0x0078, + 0x8006, 0xd6dc, 0x0040, 0x7ffd, 0x684b, 0x0015, 0x684c, 0xd0ac, + 0x0040, 0x7ffb, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x7ffb, + 0x7018, 0xa106, 0x00c0, 0x7ff8, 0x701c, 0xa206, 0x0040, 0x7ffb, + 0x6962, 0x6a5e, 0xc6dc, 0x0078, 0x8006, 0xd6d4, 0x0040, 0x8004, + 0x684b, 0x0007, 0x0078, 0x8006, 0x684b, 0x0000, 0x6837, 0x0103, + 0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x802f, 0xa686, 0x0100, 0x00c0, + 0x801a, 0x2001, 0xa899, 0x2004, 0xa005, 0x00c0, 0x801a, 0xc6c4, + 0x0078, 0x7fa9, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x802f, + 0xa38a, 0x0009, 0x0048, 0x8026, 0x2019, 0x0008, 0x037e, 0x2308, + 0x2019, 0xa898, 0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc, + 0x0040, 0x8085, 0x7124, 0x695a, 0x81ff, 0x0040, 0x8085, 0xa192, + 0x0021, 0x00c8, 0x8046, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18, + 0xad90, 0x001d, 0x1078, 0x8739, 0x0078, 0x8085, 0x6838, 0xd0fc, + 0x0040, 0x804f, 0x2009, 0x0020, 0x695a, 0x0078, 0x803b, 0x0f7e, + 0x2d78, 0x1078, 0x86d1, 0x0f7f, 0x1078, 0x8726, 0x0078, 0x8087, + 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8075, 0x684c, + 0xd0ac, 0x0040, 0x8075, 0x6024, 0xd0dc, 0x00c0, 0x8075, 0x6850, + 0xd0bc, 0x00c0, 0x8075, 0x684c, 0xd0f4, 0x00c0, 0x8075, 0x1078, + 0x8cfa, 0x0d7f, 0x0e7f, 0x0078, 0x8094, 0x684b, 0x0000, 0x6837, + 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x8085, 0x6810, 0x6914, + 0xa115, 0x0040, 0x8085, 0x1078, 0x8233, 0x1078, 0x4982, 0x6218, + 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x1078, 0x8cc4, 0x0d7f, 0x0e7f, + 0x00c0, 0x8094, 0x1078, 0x753d, 0x007c, 0x0f7e, 0x6003, 0x0003, + 0x2079, 0xa88c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, + 0x784c, 0xd0ac, 0x0040, 0x80a8, 0x6003, 0x0002, 0x0f7f, 0x007c, + 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x603f, 0x0000, 0x2c10, + 0x1078, 0x1cab, 0x1078, 0x5c64, 0x1078, 0x61d3, 0x007c, 0x2001, + 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, + 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0xa182, 0x0040, + 0x0079, 0x80ca, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80df, + 0x8182, 0x80dd, 0x80dd, 0x8198, 0x8209, 0x80dd, 0x80dd, 0x80dd, + 0x80dd, 0x8218, 0x80dd, 0x80dd, 0x80dd, 0x1078, 0x1328, 0x077e, + 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xa88c, 0x6110, 0x2178, 0x7614, + 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, + 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x817d, 0xa694, 0xff00, + 0xa284, 0x0c00, 0x0040, 0x8100, 0x7018, 0x7862, 0x701c, 0x785e, + 0xa284, 0x0300, 0x0040, 0x817d, 0x1078, 0x1381, 0x1040, 0x1328, + 0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, + 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, + 0x0040, 0x811e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, + 0xa186, 0x0002, 0x0040, 0x813a, 0xa186, 0x0028, 0x00c0, 0x812c, + 0x684b, 0x001c, 0x0078, 0x813c, 0xd6dc, 0x0040, 0x8133, 0x684b, + 0x0015, 0x0078, 0x813c, 0xd6d4, 0x0040, 0x813a, 0x684b, 0x0007, + 0x0078, 0x813c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, + 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x815a, 0x7328, 0x732c, 0x6b56, + 0x83ff, 0x0040, 0x815a, 0xa38a, 0x0009, 0x0048, 0x8151, 0x2019, + 0x0008, 0x037e, 0x2308, 0x2019, 0xa898, 0xad90, 0x0019, 0x1078, + 0x8739, 0x037f, 0xd6cc, 0x0040, 0x817d, 0x7124, 0x695a, 0x81ff, + 0x0040, 0x817d, 0xa192, 0x0021, 0x00c8, 0x8171, 0x2071, 0xa898, + 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x8739, 0x0078, + 0x817d, 0x7838, 0xd0fc, 0x0040, 0x817a, 0x2009, 0x0020, 0x695a, + 0x0078, 0x8166, 0x2d78, 0x1078, 0x86d1, 0x0d7f, 0x0e7f, 0x0f7f, + 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xa88c, 0x7c04, + 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, + 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x6c26, 0x007c, + 0x0d7e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x81a4, + 0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x60b8, + 0x1078, 0x61d3, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x8207, + 0xd1cc, 0x0040, 0x81de, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x81d6, + 0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198, + 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, + 0x8210, 0x00f0, 0x81c5, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e, + 0x017f, 0x2168, 0x1078, 0x13aa, 0x0078, 0x8201, 0x017e, 0x1078, + 0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8201, 0x6837, 0x0103, + 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x81fd, 0xa086, + 0x0028, 0x00c0, 0x81ef, 0x684b, 0x001c, 0x0078, 0x81ff, 0xd1dc, + 0x0040, 0x81f6, 0x684b, 0x0015, 0x0078, 0x81ff, 0xd1d4, 0x0040, + 0x81fd, 0x684b, 0x0007, 0x0078, 0x81ff, 0x684b, 0x0000, 0x1078, + 0x4982, 0x1078, 0x8cc4, 0x00c0, 0x8207, 0x1078, 0x753d, 0x0d7f, + 0x007c, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x6003, 0x0002, 0x2001, + 0xa5a2, 0x2004, 0x603e, 0x1078, 0x60b8, 0x1078, 0x61d3, 0x007c, + 0x1078, 0x60b8, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168, 0x1078, + 0x8a44, 0x0040, 0x822d, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, + 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, + 0x1078, 0x61d3, 0x007c, 0x684b, 0x0015, 0xd1fc, 0x0040, 0x823f, + 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, + 0x685e, 0x007c, 0xa182, 0x0040, 0x0079, 0x8246, 0x8259, 0x8259, + 0x8259, 0x8259, 0x8259, 0x825b, 0x8259, 0x8333, 0x833f, 0x8259, + 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, + 0x8259, 0x1078, 0x1328, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, + 0xa88c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x0f7e, 0x2c78, + 0x1078, 0x4893, 0x0f7f, 0x0040, 0x827e, 0xa684, 0x00ff, 0x00c0, + 0x827e, 0x6024, 0xd0f4, 0x00c0, 0x827a, 0x7808, 0xa086, 0x0000, + 0x00c0, 0x827e, 0x1078, 0x8cfa, 0x0078, 0x832e, 0x7e46, 0x7f4c, + 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, + 0x0040, 0x8323, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x8294, + 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x8320, + 0xa686, 0x0100, 0x00c0, 0x82a6, 0x2001, 0xa899, 0x2004, 0xa005, + 0x00c0, 0x82a6, 0xc6c4, 0x7e46, 0x0078, 0x8287, 0x1078, 0x1381, + 0x1040, 0x1328, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, + 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, + 0x6e46, 0xa68c, 0x0c00, 0x0040, 0x82c1, 0x7318, 0x6b62, 0x731c, + 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x82dd, 0xa186, + 0x0028, 0x00c0, 0x82cf, 0x684b, 0x001c, 0x0078, 0x82df, 0xd6dc, + 0x0040, 0x82d6, 0x684b, 0x0015, 0x0078, 0x82df, 0xd6d4, 0x0040, + 0x82dd, 0x684b, 0x0007, 0x0078, 0x82df, 0x684b, 0x0000, 0x6f4e, + 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x82fd, + 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x82fd, 0xa38a, 0x0009, + 0x0048, 0x82f4, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xa898, + 0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc, 0x0040, 0x8320, + 0x7124, 0x695a, 0x81ff, 0x0040, 0x8320, 0xa192, 0x0021, 0x00c8, + 0x8314, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, + 0x1078, 0x8739, 0x0078, 0x8320, 0x7838, 0xd0fc, 0x0040, 0x831d, + 0x2009, 0x0020, 0x695a, 0x0078, 0x8309, 0x2d78, 0x1078, 0x86d1, + 0xd6dc, 0x00c0, 0x8326, 0xa006, 0x0078, 0x832c, 0x2001, 0x0001, + 0x2071, 0xa88c, 0x7218, 0x731c, 0x1078, 0x1645, 0x0d7f, 0x0e7f, + 0x0f7f, 0x077f, 0x007c, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x20e1, + 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x2001, + 0xa5a2, 0x2004, 0x603e, 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, + 0x694c, 0xd1e4, 0x0040, 0x846b, 0x603f, 0x0000, 0x0f7e, 0x2c78, + 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8385, 0x6814, 0x6910, 0xa115, + 0x0040, 0x8385, 0x6a60, 0xa206, 0x00c0, 0x8362, 0x685c, 0xa106, + 0x0040, 0x8385, 0x684c, 0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863, + 0x0000, 0x685f, 0x0000, 0x6024, 0xd0f4, 0x00c0, 0x837a, 0x697c, + 0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6024, + 0xc0f5, 0x6026, 0x0d7e, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e, + 0x0d7f, 0x1078, 0x8cfa, 0x0078, 0x846b, 0x694c, 0xd1cc, 0x0040, + 0x8430, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x83ea, 0x017e, 0x684c, + 0x007e, 0x6850, 0x007e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, + 0xa0b6, 0x0002, 0x0040, 0x83bf, 0xa086, 0x0028, 0x00c0, 0x83a6, + 0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x83ca, 0xd1dc, 0x0040, + 0x83b6, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040, + 0x83b4, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x83ca, 0xd1d4, 0x0040, + 0x83bf, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x83ca, 0x684c, + 0xd0ac, 0x0040, 0x83ca, 0x6810, 0x6914, 0xa115, 0x0040, 0x83ca, + 0x1078, 0x8233, 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, + 0xad90, 0x000d, 0xaf98, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, + 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x83d8, 0x157f, 0x0f7f, + 0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x13aa, + 0x0078, 0x8465, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, + 0xa0b6, 0x0002, 0x0040, 0x8417, 0xa086, 0x0028, 0x00c0, 0x83fe, + 0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x8422, 0xd1dc, 0x0040, + 0x840e, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040, + 0x840c, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x8422, 0xd1d4, 0x0040, + 0x8417, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x8422, 0x684c, + 0xd0ac, 0x0040, 0x8422, 0x6810, 0x6914, 0xa115, 0x0040, 0x8422, + 0x1078, 0x8233, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, + 0x0f7f, 0x1078, 0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8465, + 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, + 0x8456, 0xa086, 0x0028, 0x00c0, 0x8441, 0x684b, 0x001c, 0x0078, + 0x8463, 0xd1dc, 0x0040, 0x844f, 0x684b, 0x0015, 0x1078, 0x8ea5, + 0x0040, 0x844d, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8463, 0xd1d4, + 0x0040, 0x8456, 0x684b, 0x0007, 0x0078, 0x8463, 0x684b, 0x0000, + 0x684c, 0xd0ac, 0x0040, 0x8463, 0x6810, 0x6914, 0xa115, 0x0040, + 0x8463, 0x1078, 0x8233, 0x1078, 0x4982, 0x1078, 0x8cc4, 0x00c0, + 0x846b, 0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x6010, 0x0078, + 0x8473, 0x1078, 0x60b8, 0x1078, 0x8a44, 0x0040, 0x8492, 0x0d7e, + 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa30c, 0x210c, 0xd18c, + 0x00c0, 0x849d, 0xd184, 0x00c0, 0x8499, 0x6108, 0x694a, 0xa18e, + 0x0029, 0x00c0, 0x848d, 0x1078, 0xa181, 0x6847, 0x0000, 0x1078, + 0x4982, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x1078, 0x61d3, + 0x007c, 0x684b, 0x0004, 0x0078, 0x848d, 0x684b, 0x0004, 0x0078, + 0x848d, 0xa182, 0x0040, 0x0079, 0x84a5, 0x84b8, 0x84b8, 0x84b8, + 0x84b8, 0x84b8, 0x84ba, 0x84b8, 0x84bd, 0x84b8, 0x84b8, 0x84b8, + 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, + 0x1078, 0x1328, 0x1078, 0x753d, 0x007c, 0x007e, 0x027e, 0xa016, + 0x1078, 0x15ec, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, 0x0079, + 0x84c9, 0x84d2, 0x84d0, 0x84d0, 0x84de, 0x84d0, 0x84d0, 0x84d0, + 0x1078, 0x1328, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e, + 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x057e, + 0x0d7e, 0x0e7e, 0x2071, 0xa880, 0x7224, 0x6212, 0x7220, 0x1078, + 0x8a30, 0x0040, 0x8503, 0x2268, 0x6800, 0xa086, 0x0000, 0x0040, + 0x8503, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x8503, 0x0c7e, 0x2d60, + 0x1078, 0x874a, 0x0c7f, 0x0040, 0x8503, 0x6803, 0x0002, 0x6007, + 0x0086, 0x0078, 0x8505, 0x6007, 0x0087, 0x6003, 0x0001, 0x1078, + 0x5bf8, 0x1078, 0x6109, 0x0f7e, 0x2278, 0x1078, 0x4893, 0x0f7f, + 0x0040, 0x851d, 0x6824, 0xd0ec, 0x0040, 0x851d, 0x0c7e, 0x2260, + 0x603f, 0x0000, 0x1078, 0x8cfa, 0x0c7f, 0x0e7f, 0x0d7f, 0x057f, + 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x8533, 0x6004, 0xa08a, + 0x0085, 0x1048, 0x1328, 0xa08a, 0x008c, 0x10c8, 0x1328, 0xa082, + 0x0085, 0x0079, 0x8542, 0xa186, 0x0027, 0x0040, 0x853b, 0xa186, + 0x0014, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, + 0x6109, 0x007c, 0x8549, 0x854b, 0x854b, 0x8549, 0x8549, 0x8549, + 0x8549, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, + 0x6109, 0x007c, 0xa186, 0x0013, 0x00c0, 0x855c, 0x6004, 0xa082, + 0x0085, 0x2008, 0x0078, 0x8597, 0xa186, 0x0027, 0x00c0, 0x857f, + 0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6010, 0x2068, 0x1078, + 0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, + 0x0029, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, + 0x1078, 0x6109, 0x007c, 0x1078, 0x7583, 0x0078, 0x857a, 0xa186, + 0x0014, 0x00c0, 0x857b, 0x1078, 0x6010, 0x0d7e, 0x6010, 0x2068, + 0x1078, 0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000, + 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8571, 0x0079, + 0x8599, 0x85a2, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85bd, + 0x1078, 0x1328, 0x1078, 0x6010, 0x6030, 0xa08c, 0xff00, 0x810f, + 0xa186, 0x0039, 0x0040, 0x85b0, 0xa186, 0x0035, 0x00c0, 0x85b4, + 0x2001, 0xa5a0, 0x0078, 0x85b6, 0x2001, 0xa5a1, 0x2004, 0x6016, + 0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x6030, + 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x85cb, 0xa186, + 0x0035, 0x00c0, 0x85cf, 0x2001, 0xa5a0, 0x0078, 0x85d1, 0x2001, + 0xa5a1, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x6109, 0x007c, + 0xa182, 0x008c, 0x00c8, 0x85e2, 0xa182, 0x0085, 0x0048, 0x85e2, + 0x0079, 0x85e5, 0x1078, 0x7583, 0x007c, 0x85ec, 0x85ec, 0x85ec, + 0x85ec, 0x85ee, 0x8643, 0x85ec, 0x1078, 0x1328, 0x0f7e, 0x2c78, + 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8601, 0x6030, 0xa08c, 0xff00, + 0x810f, 0xa186, 0x0039, 0x0040, 0x865a, 0xa186, 0x0035, 0x0040, + 0x865a, 0x0d7e, 0x1078, 0x8bf4, 0x1078, 0x8a44, 0x0040, 0x8625, + 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x8616, + 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x8621, 0xd0bc, 0x0040, + 0x861d, 0x684b, 0x0002, 0x0078, 0x8621, 0x684b, 0x0005, 0x1078, + 0x8cc0, 0x6847, 0x0000, 0x1078, 0x4982, 0x2c68, 0x1078, 0x74d7, + 0x0040, 0x863e, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xa88e, + 0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x6918, 0x611a, + 0x6920, 0x6122, 0x601f, 0x0001, 0x1078, 0x5bf8, 0x2d60, 0x1078, + 0x753d, 0x0d7f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, + 0x0040, 0x8680, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035, + 0x0040, 0x865a, 0xa186, 0x001e, 0x0040, 0x865a, 0xa186, 0x0039, + 0x00c0, 0x8680, 0x0d7e, 0x2c68, 0x1078, 0x8ef5, 0x00c0, 0x86a4, + 0x1078, 0x74d7, 0x0040, 0x867d, 0x6106, 0x6003, 0x0001, 0x601f, + 0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c, 0x612e, 0x6930, + 0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938, 0x613a, 0x6920, + 0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x2d60, 0x0078, 0x86a4, + 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86a4, 0x6837, + 0x0103, 0x6850, 0xd0b4, 0x0040, 0x8693, 0xc0ec, 0x6852, 0x684b, + 0x0006, 0x0078, 0x869e, 0xd0bc, 0x0040, 0x869a, 0x684b, 0x0002, + 0x0078, 0x869e, 0x684b, 0x0005, 0x1078, 0x8cc0, 0x6847, 0x0000, + 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x007c, + 0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86b8, + 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078, 0x4982, + 0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x86ca, 0xa186, 0x0014, + 0x0040, 0x86ca, 0xa186, 0x0027, 0x0040, 0x86ca, 0x1078, 0x7583, + 0x0078, 0x86d0, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, + 0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, 0xa182, + 0x0101, 0x00c8, 0x86dd, 0x0078, 0x86df, 0x2009, 0x0100, 0x2130, + 0x2069, 0xa898, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90, + 0x001d, 0x1078, 0x8739, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040, + 0x86f3, 0x1078, 0x13aa, 0x1078, 0x1381, 0x0040, 0x871d, 0x8528, + 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, + 0x00c8, 0x8709, 0x2608, 0xad90, 0x000f, 0x1078, 0x8739, 0x0078, + 0x871d, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f, + 0x1078, 0x8739, 0x0078, 0x86f3, 0x0f7f, 0x852f, 0xa5ad, 0x0003, + 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x8722, 0x0f7f, 0x852f, 0xa5ad, + 0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, 0x8dff, + 0x0040, 0x8737, 0x6804, 0xa07d, 0x0040, 0x8735, 0x6807, 0x0000, + 0x1078, 0x4982, 0x2f68, 0x0078, 0x872a, 0x1078, 0x4982, 0x0f7f, + 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x873f, 0x8108, 0x810c, + 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x8741, + 0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031, 0x0001, + 0x601c, 0xa084, 0x000f, 0x1079, 0x8766, 0x127f, 0x067f, 0x007c, + 0x127e, 0x2091, 0x8000, 0x067e, 0x2031, 0x0000, 0x601c, 0xa084, + 0x000f, 0x1079, 0x8766, 0x067f, 0x127f, 0x007c, 0x8780, 0x876e, + 0x877b, 0x879c, 0x876e, 0x877b, 0x879c, 0x877b, 0x1078, 0x1328, + 0x037e, 0x2019, 0x0010, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003, + 0x0007, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, + 0x0d7e, 0x86ff, 0x00c0, 0x8797, 0x6010, 0x2068, 0x1078, 0x8a44, + 0x0040, 0x8799, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4a60, 0x1078, + 0x8cc0, 0x1078, 0x4982, 0x1078, 0x753d, 0xa085, 0x0001, 0x0d7f, + 0x007c, 0xa006, 0x0078, 0x8797, 0x6000, 0xa08a, 0x0010, 0x10c8, + 0x1328, 0x1079, 0x87a4, 0x007c, 0x87b4, 0x87d4, 0x87b6, 0x87f7, + 0x87d0, 0x87b4, 0x877b, 0x8780, 0x8780, 0x877b, 0x877b, 0x877b, + 0x877b, 0x877b, 0x877b, 0x877b, 0x1078, 0x1328, 0x86ff, 0x00c0, + 0x87cd, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x87c2, + 0x1078, 0x8cc0, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, + 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0xa085, 0x0001, 0x007c, + 0x1078, 0x1749, 0x0078, 0x87b6, 0x0e7e, 0x2071, 0xa5ab, 0x7024, + 0xac06, 0x00c0, 0x87dd, 0x1078, 0x6dda, 0x601c, 0xa084, 0x000f, + 0xa086, 0x0006, 0x00c0, 0x87ef, 0x087e, 0x097e, 0x2049, 0x0001, + 0x2c40, 0x1078, 0x7058, 0x097f, 0x087f, 0x0078, 0x87f1, 0x1078, + 0x6cd2, 0x0e7f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c, 0x037e, + 0x0e7e, 0x2071, 0xa5ab, 0x703c, 0xac06, 0x00c0, 0x8807, 0x2019, + 0x0000, 0x1078, 0x6e6c, 0x0e7f, 0x037f, 0x0078, 0x87b6, 0x1078, + 0x719a, 0x0e7f, 0x037f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c, + 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x8818, 0x0c7f, 0x007c, + 0x8827, 0x8895, 0x89cd, 0x8832, 0x8c01, 0x8827, 0x9a5b, 0x753d, + 0x8895, 0x1078, 0x8c3b, 0x00c0, 0x8827, 0x1078, 0x7a05, 0x007c, + 0x1078, 0x6010, 0x1078, 0x6109, 0x1078, 0x753d, 0x007c, 0x6017, + 0x0001, 0x007c, 0x6010, 0xa080, 0x0019, 0x2c02, 0x6000, 0xa08a, + 0x0010, 0x10c8, 0x1328, 0x1079, 0x883e, 0x007c, 0x884e, 0x8850, + 0x8872, 0x8884, 0x8891, 0x884e, 0x8827, 0x8827, 0x8827, 0x8884, + 0x8884, 0x884e, 0x884e, 0x884e, 0x884e, 0x888e, 0x1078, 0x1328, + 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0xa5ab, + 0x7024, 0xac06, 0x0040, 0x886e, 0x1078, 0x6cd2, 0x6007, 0x0085, + 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa5a1, 0x2004, 0x6016, + 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x6017, 0x0001, + 0x0078, 0x886c, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, + 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, + 0x5bf8, 0x1078, 0x6109, 0x007c, 0x0d7e, 0x6017, 0x0001, 0x6010, + 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, 0x753d, + 0x007c, 0x1078, 0x1749, 0x0078, 0x8872, 0x6000, 0xa08a, 0x0010, + 0x10c8, 0x1328, 0x1079, 0x889d, 0x007c, 0x88ad, 0x882f, 0x88af, + 0x88ad, 0x88af, 0x88af, 0x8828, 0x88ad, 0x8821, 0x8821, 0x88ad, + 0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x1078, 0x1328, 0x0d7e, + 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a, 0x000c, + 0x10c8, 0x1328, 0x1079, 0x88bd, 0x007c, 0x88c9, 0x8971, 0x88cb, + 0x890b, 0x88cb, 0x890b, 0x88cb, 0x88d8, 0x88c9, 0x890b, 0x88c9, + 0x88f5, 0x1078, 0x1328, 0x6004, 0xa08e, 0x0016, 0x0040, 0x8906, + 0xa08e, 0x0004, 0x0040, 0x8906, 0xa08e, 0x0002, 0x0040, 0x8906, + 0x6004, 0x1078, 0x8c3b, 0x0040, 0x898c, 0xa08e, 0x0021, 0x0040, + 0x8990, 0xa08e, 0x0022, 0x0040, 0x898c, 0xa08e, 0x003d, 0x0040, + 0x8990, 0xa08e, 0x0039, 0x0040, 0x8994, 0xa08e, 0x0035, 0x0040, + 0x8994, 0xa08e, 0x001e, 0x0040, 0x8908, 0xa08e, 0x0001, 0x00c0, + 0x8904, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, + 0xa086, 0x0006, 0x0040, 0x8906, 0x1078, 0x2813, 0x1078, 0x7a05, + 0x1078, 0x8c01, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, + 0x0040, 0x8961, 0xa186, 0x0002, 0x00c0, 0x8934, 0x6018, 0x2068, + 0x68a0, 0xd0bc, 0x00c0, 0x89b8, 0x6840, 0xa084, 0x00ff, 0xa005, + 0x0040, 0x8934, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007, + 0x6017, 0x0398, 0x1078, 0x74d7, 0x0040, 0x8934, 0x2d00, 0x601a, + 0x601f, 0x0001, 0x0078, 0x8961, 0x0d7f, 0x0c7f, 0x6004, 0xa08e, + 0x0002, 0x00c0, 0x8952, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, + 0x007e, 0x00c0, 0x8952, 0x2009, 0xa332, 0x2104, 0xc085, 0x200a, + 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x0e7f, 0x1078, 0x7a05, + 0x0078, 0x8956, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e, + 0x2091, 0x8000, 0x1078, 0x2839, 0x127f, 0x0e7f, 0x1078, 0x8c01, + 0x007c, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007, + 0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0d7f, 0x0c7f, 0x0078, + 0x8960, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, 0x0040, 0x8961, + 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x8934, + 0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078, 0x6109, + 0x0d7f, 0x0c7f, 0x0078, 0x8960, 0x1078, 0x7a05, 0x0078, 0x8908, + 0x1078, 0x7a28, 0x0078, 0x8908, 0x0d7e, 0x2c68, 0x6104, 0x1078, + 0x8ef5, 0x0d7f, 0x0040, 0x89a0, 0x1078, 0x753d, 0x0078, 0x89b7, + 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, + 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038, 0x600a, 0x2001, + 0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c, + 0x0d7f, 0x0c7f, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e, + 0x2091, 0x8000, 0x1078, 0x2839, 0x6013, 0x0000, 0x601f, 0x0007, + 0x6017, 0x0398, 0x127f, 0x0e7f, 0x007c, 0x6000, 0xa08a, 0x0010, + 0x10c8, 0x1328, 0x1079, 0x89d5, 0x007c, 0x89e5, 0x89e5, 0x89e5, + 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x8827, 0x89e5, + 0x882f, 0x89e7, 0x882f, 0x89f5, 0x89e5, 0x1078, 0x1328, 0x6004, + 0xa086, 0x008b, 0x0040, 0x89f5, 0x6007, 0x008b, 0x6003, 0x000d, + 0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c, 0x1078, 0x8bf4, 0x1078, + 0x8a44, 0x0040, 0x8a2d, 0x1078, 0x2813, 0x0d7e, 0x1078, 0x8a44, + 0x0040, 0x8a0f, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006, + 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078, 0x4982, 0x2c68, + 0x1078, 0x74d7, 0x0040, 0x8a1d, 0x6818, 0x601a, 0x0c7e, 0x2d60, + 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x8a1e, 0x2d60, 0x0d7f, 0x6013, + 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, + 0x5c45, 0x1078, 0x6109, 0x0078, 0x8a2f, 0x1078, 0x8c01, 0x007c, + 0xa284, 0x000f, 0x00c0, 0x8a41, 0xa282, 0xaa00, 0x0048, 0x8a41, + 0x2001, 0xa315, 0x2004, 0xa202, 0x00c8, 0x8a41, 0xa085, 0x0001, + 0x007c, 0xa006, 0x0078, 0x8a40, 0x027e, 0x0e7e, 0x2071, 0xa300, + 0x6210, 0x7058, 0xa202, 0x0048, 0x8a56, 0x705c, 0xa202, 0x00c8, + 0x8a56, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c, 0xa006, 0x0078, + 0x8a53, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e, 0x2091, 0x8000, + 0x2061, 0xaa00, 0x2071, 0xa300, 0x7344, 0x7060, 0xa302, 0x00c8, + 0x8a83, 0x601c, 0xa206, 0x00c0, 0x8a7b, 0x1078, 0x8d66, 0x0040, + 0x8a7b, 0x1078, 0x8c3b, 0x00c0, 0x8a77, 0x1078, 0x7a05, 0x0c7e, + 0x1078, 0x753d, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, + 0x8a83, 0x0078, 0x8a64, 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f, + 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa434, 0x210c, 0x81ff, + 0x0040, 0x8aa1, 0x2061, 0xaa00, 0x2071, 0xa300, 0x017e, 0x1078, + 0x74d7, 0x017f, 0x0040, 0x8aa4, 0x611a, 0x1078, 0x2813, 0x1078, + 0x753d, 0xa006, 0x0078, 0x8aa6, 0xa085, 0x0001, 0x017f, 0x0c7f, + 0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e, + 0x1078, 0x74d7, 0x057f, 0x0040, 0x8ac3, 0x6612, 0x651a, 0x601f, + 0x0003, 0x2009, 0x004b, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, + 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8abf, 0x0c7e, 0x057e, + 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x74d7, 0x057f, + 0x0040, 0x8af1, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e, + 0x2560, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e, 0x2039, + 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2009, + 0x004c, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, + 0x007c, 0xa006, 0x0078, 0x8aed, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, + 0x1078, 0x74d7, 0x2c78, 0x0c7f, 0x0040, 0x8b0e, 0x7e12, 0x2c00, + 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60, + 0x2009, 0x004d, 0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f, + 0x0f7f, 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7, + 0x2c78, 0x0c7f, 0x0040, 0x8b2c, 0x7e12, 0x2c00, 0x781a, 0x781f, + 0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x004e, + 0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c, + 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7, 0x2c78, 0x0c7f, + 0x0040, 0x8b4a, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, + 0x0004, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x0052, 0x1078, 0x756c, + 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c, 0x097e, 0x077e, + 0x127e, 0x2091, 0x8000, 0x1078, 0x46a7, 0x0040, 0x8b5b, 0x2001, + 0x8b53, 0x0078, 0x8b61, 0x1078, 0x466d, 0x0040, 0x8b6a, 0x2001, + 0x8b5b, 0x007e, 0xa00e, 0x2400, 0x1078, 0x4a60, 0x1078, 0x4982, + 0x007f, 0x007a, 0x2418, 0x1078, 0x5fa7, 0x62a0, 0x087e, 0x2041, + 0x0001, 0x2039, 0x0001, 0x2608, 0x1078, 0x5d6d, 0x087f, 0x1078, + 0x5c78, 0x2f08, 0x2648, 0x1078, 0x9c38, 0x613c, 0x81ff, 0x1040, + 0x5e21, 0x127f, 0x077f, 0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091, + 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8b9e, 0x660a, + 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078, + 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, + 0x8b9b, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7, + 0x017f, 0x0040, 0x8bba, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, + 0x6012, 0x2009, 0x0021, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, + 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8bb7, 0x0c7e, 0x127e, 0x2091, + 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8bd6, 0x660a, + 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x1078, + 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, + 0x8bd3, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7, + 0x017f, 0x0040, 0x8bf1, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, + 0x2009, 0x0000, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, + 0x007c, 0xa006, 0x0078, 0x8bee, 0x027e, 0x0d7e, 0x6218, 0x2268, + 0x6a3c, 0x82ff, 0x0040, 0x8bfe, 0x8211, 0x6a3e, 0x0d7f, 0x027f, + 0x007c, 0x007e, 0x6000, 0xa086, 0x0000, 0x0040, 0x8c13, 0x6013, + 0x0000, 0x601f, 0x0007, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078, + 0xa134, 0x603f, 0x0000, 0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e, + 0x2031, 0xa352, 0x2634, 0xd6e4, 0x0040, 0x8c23, 0x6618, 0x2660, + 0x6e48, 0x1078, 0x461b, 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e, + 0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x8c38, 0xa08e, 0x0003, + 0x0040, 0x8c38, 0xa08e, 0x0004, 0x0040, 0x8c38, 0xa085, 0x0001, + 0x017f, 0x007f, 0x007c, 0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040, + 0x8c48, 0x6838, 0xd0fc, 0x0040, 0x8c48, 0xa006, 0x0078, 0x8c4a, + 0xa085, 0x0001, 0x0d7f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, + 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8c67, 0x611a, + 0x601f, 0x0001, 0x2d00, 0x6012, 0x1078, 0x2813, 0x2009, 0x0028, + 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, + 0x0078, 0x8c64, 0xa186, 0x0015, 0x00c0, 0x8c7f, 0x2011, 0xa31f, + 0x2204, 0xa086, 0x0074, 0x00c0, 0x8c7f, 0x1078, 0x7d0d, 0x6003, + 0x0001, 0x6007, 0x0029, 0x1078, 0x5c45, 0x0078, 0x8c83, 0x1078, + 0x7a05, 0x1078, 0x753d, 0x007c, 0xa186, 0x0016, 0x00c0, 0x8c8e, + 0x2001, 0x0004, 0x1078, 0x443f, 0x0078, 0x8caf, 0xa186, 0x0015, + 0x00c0, 0x8cb3, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0014, 0x00c0, + 0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x1078, 0x457d, 0x0d7f, 0x1078, + 0x7dba, 0x00c0, 0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, + 0xa005, 0x0040, 0x8cb3, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078, + 0x7608, 0x0078, 0x8cb7, 0x1078, 0x7a05, 0x1078, 0x753d, 0x007c, + 0x6848, 0xa086, 0x0005, 0x00c0, 0x8cbf, 0x1078, 0x8cc0, 0x007c, + 0x6850, 0xc0ad, 0x6852, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7014, + 0xd0e4, 0x0040, 0x8cd5, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, + 0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x0c7e, + 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8ce4, 0x601c, + 0xa084, 0x000f, 0x1079, 0x8ce6, 0x0c7f, 0x007c, 0x8827, 0x8cf1, + 0x8cf4, 0x8cf7, 0x9f00, 0x9f1c, 0x9f1f, 0x8827, 0x8827, 0x1078, + 0x1328, 0x0005, 0x0005, 0x007c, 0x0005, 0x0005, 0x007c, 0x1078, + 0x8cfa, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0040, 0x8d29, + 0x1078, 0x74d7, 0x00c0, 0x8d0a, 0x2001, 0xa5a2, 0x2004, 0x783e, + 0x0078, 0x8d29, 0x7818, 0x601a, 0x781c, 0xa086, 0x0003, 0x0040, + 0x8d17, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0078, 0x8d1b, 0x7808, + 0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007, 0x0035, + 0x6003, 0x0001, 0x7920, 0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109, + 0x2f60, 0x0f7f, 0x007c, 0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e, + 0x0001, 0x0040, 0x8d3c, 0xa086, 0x0005, 0x0040, 0x8d40, 0xa006, + 0x602a, 0x602e, 0x0078, 0x8d51, 0x6824, 0xc0f4, 0xc0d5, 0x6826, + 0x6810, 0x2078, 0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103, + 0x00c8, 0x8d37, 0x6834, 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, + 0x602e, 0x2d00, 0x6036, 0x6808, 0x603a, 0x6918, 0x611a, 0x6920, + 0x6122, 0x601f, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x1078, + 0x5bf8, 0x6803, 0x0002, 0x0f7f, 0x017f, 0x007c, 0x007e, 0x017e, + 0x6004, 0xa08e, 0x0034, 0x0040, 0x8d8b, 0xa08e, 0x0035, 0x0040, + 0x8d8b, 0xa08e, 0x0036, 0x0040, 0x8d8b, 0xa08e, 0x0037, 0x0040, + 0x8d8b, 0xa08e, 0x0038, 0x0040, 0x8d8b, 0xa08e, 0x0039, 0x0040, + 0x8d8b, 0xa08e, 0x003a, 0x0040, 0x8d8b, 0xa08e, 0x003b, 0x0040, + 0x8d8b, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x0f7e, 0x2c78, + 0x1078, 0x4893, 0x00c0, 0x8d98, 0xa085, 0x0001, 0x0078, 0x8da7, + 0x6024, 0xd0f4, 0x00c0, 0x8da6, 0xc0f5, 0x6026, 0x6010, 0x2078, + 0x7828, 0x603a, 0x782c, 0x6036, 0x1078, 0x1749, 0xa006, 0x0f7f, + 0x007c, 0x007e, 0x017e, 0x027e, 0x037e, 0x0e7e, 0x2001, 0xa59c, + 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x1078, 0x5a98, 0x2001, + 0xa5a0, 0x82ff, 0x00c0, 0x8dbe, 0x2011, 0x0002, 0x2202, 0x2001, + 0xa59e, 0x200c, 0x8000, 0x2014, 0x2071, 0xa58c, 0x711a, 0x721e, + 0x2001, 0x0064, 0x1078, 0x5a98, 0x2001, 0xa5a1, 0x82ff, 0x00c0, + 0x8dd3, 0x2011, 0x0002, 0x2202, 0x2009, 0xa5a2, 0xa280, 0x000a, + 0x200a, 0x0e7f, 0x037f, 0x027f, 0x017f, 0x007f, 0x007c, 0x007e, + 0x0e7e, 0x2001, 0xa5a0, 0x2003, 0x0028, 0x2001, 0xa5a1, 0x2003, + 0x0014, 0x2071, 0xa58c, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, + 0xa5a2, 0x2003, 0x001e, 0x0e7f, 0x007f, 0x007c, 0x0c7e, 0x127e, + 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8e0e, + 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x1078, + 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, + 0x8e0b, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa300, 0xa186, 0x0015, + 0x00c0, 0x8e40, 0x707c, 0xa086, 0x0018, 0x00c0, 0x8e40, 0x6010, + 0x2068, 0x6a3c, 0xd2e4, 0x00c0, 0x8e34, 0x2c78, 0x1078, 0x62c6, + 0x0040, 0x8e48, 0x7068, 0x6a50, 0xa206, 0x00c0, 0x8e3c, 0x706c, + 0x6a54, 0xa206, 0x00c0, 0x8e3c, 0x6218, 0xa290, 0x0028, 0x2214, + 0x2009, 0x0000, 0x1078, 0x285b, 0x1078, 0x7608, 0x0078, 0x8e44, + 0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, + 0x704c, 0xa080, 0x293f, 0x2004, 0x6a54, 0xa206, 0x0040, 0x8e34, + 0x0078, 0x8e3c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, + 0x74d7, 0x017f, 0x0040, 0x8e6a, 0x611a, 0x601f, 0x0001, 0x2d00, + 0x6012, 0x2009, 0x0043, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, + 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e67, 0x0d7e, 0x0e7e, 0x0f7e, + 0x2071, 0xa300, 0xa186, 0x0015, 0x00c0, 0x8e93, 0x707c, 0xa086, + 0x0004, 0x00c0, 0x8e93, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078, + 0x62c6, 0x0040, 0x8e9b, 0x7068, 0x6a08, 0xa206, 0x00c0, 0x8e8f, + 0x706c, 0x6a0c, 0xa206, 0x00c0, 0x8e8f, 0x1078, 0x2813, 0x1078, + 0x7608, 0x0078, 0x8e97, 0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f, + 0x0e7f, 0x0d7f, 0x007c, 0x704c, 0xa080, 0x293f, 0x2004, 0x6a0c, + 0xa206, 0x0040, 0x8e8d, 0x0078, 0x8e8f, 0x017e, 0x027e, 0x684c, + 0xd0ac, 0x0040, 0x8ebd, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, + 0x8ebd, 0x6860, 0xa106, 0x00c0, 0x8eb9, 0x685c, 0xa206, 0x0040, + 0x8ebd, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x027f, 0x017f, 0x007c, + 0x0e7e, 0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582, + 0x0001, 0x0048, 0x8ef2, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, + 0x0040, 0x8ede, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x8eda, + 0x0078, 0x8ecd, 0x2061, 0xaa00, 0x0078, 0x8ecd, 0x6003, 0x0008, + 0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x8eee, + 0x754a, 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00, + 0x0078, 0x8ee9, 0xa006, 0x0078, 0x8eeb, 0x0c7e, 0x027e, 0x017e, + 0xa186, 0x0035, 0x0040, 0x8eff, 0x6a34, 0x0078, 0x8f00, 0x6a28, + 0x1078, 0x8a30, 0x0040, 0x8f29, 0x2260, 0x611c, 0xa186, 0x0003, + 0x0040, 0x8f0e, 0xa186, 0x0006, 0x00c0, 0x8f25, 0x6834, 0xa206, + 0x0040, 0x8f1d, 0x6838, 0xa206, 0x00c0, 0x8f25, 0x6108, 0x6834, + 0xa106, 0x00c0, 0x8f25, 0x0078, 0x8f22, 0x6008, 0x6938, 0xa106, + 0x00c0, 0x8f25, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f, + 0x007c, 0xa085, 0x0001, 0x0078, 0x8f25, 0x067e, 0x6000, 0xa0b2, + 0x0010, 0x10c8, 0x1328, 0x1079, 0x8f37, 0x067f, 0x007c, 0x8f47, + 0x93bb, 0x94d3, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f81, + 0x955e, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x1078, + 0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079, + 0x8f53, 0x067f, 0x007c, 0x8f63, 0x99f6, 0x8f63, 0x8f63, 0x8f63, + 0x8f63, 0x8f63, 0x8f63, 0x99b4, 0x9a44, 0x8f63, 0xa053, 0xa087, + 0xa053, 0xa087, 0x8f63, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2, + 0x0010, 0x10c8, 0x1328, 0x1079, 0x8f6f, 0x067f, 0x007c, 0x8f7f, + 0x969f, 0x976a, 0x9798, 0x9813, 0x8f7f, 0x9919, 0x98c1, 0x956a, + 0x9988, 0x999e, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x1078, + 0x1328, 0xa1b2, 0x0044, 0x10c8, 0x1328, 0x2100, 0x0079, 0x8f88, + 0x8fc8, 0x919a, 0x8fc8, 0x8fc8, 0x8fc8, 0x91a2, 0x8fc8, 0x8fc8, + 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, + 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fca, + 0x902d, 0x9038, 0x9081, 0x909c, 0x911b, 0x918b, 0x8fc8, 0x8fc8, + 0x91a6, 0x8fc8, 0x8fc8, 0x91b5, 0x91bc, 0x8fc8, 0x8fc8, 0x8fc8, + 0x8fc8, 0x8fc8, 0x91ea, 0x8fc8, 0x8fc8, 0x91f5, 0x8fc8, 0x8fc8, + 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x920a, 0x8fc8, 0x8fc8, 0x8fc8, + 0x9291, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x9305, + 0x1078, 0x1328, 0x1078, 0x4897, 0x00c0, 0x8fd7, 0x2001, 0xa332, + 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x8fdf, 0x6007, + 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195, 0x1078, + 0x4887, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270, + 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, + 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x017f, + 0x2e60, 0x1078, 0x471b, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, + 0x6618, 0x0c7e, 0x2660, 0x1078, 0x4513, 0x0c7f, 0xa6b0, 0x0001, + 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x901f, 0x1078, + 0x9b6c, 0x00c0, 0x907b, 0x1078, 0x9afd, 0x00c0, 0x901b, 0x6007, + 0x0008, 0x0078, 0x9195, 0x6007, 0x0009, 0x0078, 0x9195, 0x1078, + 0x9d45, 0x0040, 0x9029, 0x1078, 0x9b6c, 0x0040, 0x9013, 0x0078, + 0x907b, 0x6013, 0x1900, 0x0078, 0x901b, 0x6106, 0x1078, 0x9aa8, + 0x6007, 0x0006, 0x0078, 0x9195, 0x6007, 0x0007, 0x0078, 0x9195, + 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x0d7e, 0x6618, 0x2668, 0x6e04, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x905d, 0xa686, + 0x0004, 0x0040, 0x905d, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, + 0x0040, 0x905d, 0xa686, 0x0004, 0x0040, 0x905d, 0xa686, 0x0005, + 0x0040, 0x905d, 0x0d7f, 0x0078, 0x907b, 0x1078, 0x9bd2, 0x00c0, + 0x9076, 0xa686, 0x0006, 0x00c0, 0x906f, 0x027e, 0x6218, 0xa290, + 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f, 0x1078, + 0x457d, 0x6007, 0x000a, 0x0d7f, 0x0078, 0x9195, 0x6007, 0x000b, + 0x0d7f, 0x0078, 0x9195, 0x1078, 0x2813, 0x6007, 0x0001, 0x0078, + 0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x6618, 0x0d7e, 0x2668, + 0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x907b, 0x027e, 0x6218, + 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f, + 0x6007, 0x000c, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x90a9, + 0x2001, 0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, + 0x90b1, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, + 0x9195, 0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, + 0x00ff, 0xa082, 0x0006, 0x0048, 0x90f5, 0xa6b4, 0xff00, 0x8637, + 0xa686, 0x0004, 0x0040, 0x90c8, 0xa686, 0x0006, 0x00c0, 0x907b, + 0x1078, 0x9be1, 0x00c0, 0x90d0, 0x6007, 0x000e, 0x0078, 0x9195, + 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, + 0x047e, 0x1078, 0x2813, 0x047f, 0x017e, 0xa006, 0x2009, 0xa352, + 0x210c, 0xd1a4, 0x0040, 0x90ef, 0x2009, 0x0029, 0x1078, 0x9ec0, + 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f, + 0x047f, 0x6007, 0x0001, 0x0078, 0x9195, 0x2001, 0x0001, 0x1078, + 0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, + 0xa305, 0x2011, 0xa890, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f, + 0x157f, 0xa005, 0x0040, 0x9115, 0xa6b4, 0xff00, 0x8637, 0xa686, + 0x0006, 0x0040, 0x90c8, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007, + 0x0009, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x9128, 0x2001, + 0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x9130, + 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195, + 0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, + 0xa082, 0x0006, 0x0048, 0x9178, 0xa6b4, 0xff00, 0x8637, 0xa686, + 0x0004, 0x0040, 0x9147, 0xa686, 0x0006, 0x00c0, 0x907b, 0x1078, + 0x9c0c, 0x00c0, 0x9153, 0x1078, 0x9afd, 0x00c0, 0x9153, 0x6007, + 0x0010, 0x0078, 0x9195, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, + 0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x2813, 0x047f, 0x017e, + 0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040, 0x9172, 0x2009, + 0x0029, 0x1078, 0x9ec0, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, + 0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x9195, + 0x1078, 0x9d45, 0x0040, 0x9185, 0xa6b4, 0xff00, 0x8637, 0xa686, + 0x0006, 0x0040, 0x9147, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007, + 0x0009, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x1078, + 0x9343, 0x00c0, 0x907b, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078, + 0x5c45, 0x007c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45, + 0x0078, 0x9199, 0x6007, 0x0005, 0x0078, 0x919c, 0x1078, 0xa0bf, + 0x00c0, 0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6007, 0x0020, + 0x6003, 0x0001, 0x1078, 0x5c45, 0x007c, 0x6007, 0x0023, 0x6003, + 0x0001, 0x1078, 0x5c45, 0x007c, 0x1078, 0xa0bf, 0x00c0, 0x9340, + 0x1078, 0x9343, 0x00c0, 0x907b, 0x017e, 0x027e, 0x2011, 0xa890, + 0x2214, 0x2c08, 0x1078, 0x9e8c, 0x00c0, 0x91de, 0x2160, 0x6007, + 0x0026, 0x6013, 0x1700, 0x2011, 0xa889, 0x2214, 0xa296, 0xffff, + 0x00c0, 0x91e3, 0x6007, 0x0025, 0x0078, 0x91e3, 0x1078, 0x753d, + 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x5c45, 0x027f, + 0x017f, 0x007c, 0x6106, 0x1078, 0x9363, 0x6007, 0x002b, 0x0078, + 0x9195, 0x6007, 0x002c, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0, + 0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6106, 0x1078, 0x9368, + 0x00c0, 0x9206, 0x6007, 0x002e, 0x0078, 0x9195, 0x6007, 0x002f, + 0x0078, 0x9195, 0x0e7e, 0x0d7e, 0x0c7e, 0x6018, 0xa080, 0x0001, + 0x200c, 0xa184, 0x00ff, 0xa086, 0x0006, 0x0040, 0x9223, 0xa184, + 0xff00, 0x8007, 0xa086, 0x0006, 0x0040, 0x9223, 0x0c7f, 0x0d7f, + 0x0e7f, 0x0078, 0x919a, 0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040, + 0x928d, 0x2071, 0xa88c, 0x7010, 0x6036, 0x7014, 0x603a, 0x7108, + 0x720c, 0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x9241, 0x6018, + 0x2068, 0x6810, 0xa106, 0x00c0, 0x9241, 0x6814, 0xa206, 0x0040, + 0x9265, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x9281, 0x2069, + 0xa300, 0x686c, 0xa206, 0x00c0, 0x9281, 0x6868, 0xa106, 0x00c0, + 0x9281, 0x7210, 0x1078, 0x8a30, 0x0040, 0x9287, 0x1078, 0x9f31, + 0x0040, 0x9287, 0x622a, 0x6007, 0x0036, 0x6003, 0x0001, 0x1078, + 0x5bf8, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7214, 0xa286, 0xffff, + 0x0040, 0x9277, 0x1078, 0x8a30, 0x0040, 0x9287, 0xa280, 0x0002, + 0x2004, 0x7110, 0xa106, 0x00c0, 0x9287, 0x0078, 0x9252, 0x7210, + 0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x2160, 0x0040, 0x9287, 0x0078, + 0x9252, 0x6007, 0x0037, 0x6013, 0x1500, 0x0078, 0x925d, 0x6007, + 0x0037, 0x6013, 0x1700, 0x0078, 0x925d, 0x6007, 0x0012, 0x0078, + 0x925d, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084, 0xff00, 0x8007, + 0xa086, 0x0006, 0x00c0, 0x919a, 0x0e7e, 0x0d7e, 0x0c7e, 0x2001, + 0xa371, 0x2004, 0xd0e4, 0x0040, 0x92fd, 0x2069, 0xa300, 0x2071, + 0xa88c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286, 0xffff, 0x00c0, + 0x92ba, 0x7208, 0x0c7e, 0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x0c7f, + 0x0040, 0x92f1, 0x1078, 0x8a30, 0x0040, 0x92f1, 0x0c7e, 0x027e, + 0x2260, 0x1078, 0x874a, 0x027f, 0x0c7f, 0x7118, 0xa18c, 0xff00, + 0x810f, 0xa186, 0x0001, 0x0040, 0x92db, 0xa186, 0x0005, 0x0040, + 0x92d5, 0xa186, 0x0007, 0x00c0, 0x92e5, 0xa280, 0x0004, 0x2004, + 0xa005, 0x0040, 0x92e5, 0x057e, 0x7510, 0x7614, 0x1078, 0x9f46, + 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x6007, 0x003b, 0x602b, + 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x0078, + 0x92e1, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x1700, 0x6003, + 0x0001, 0x1078, 0x5bf8, 0x0078, 0x92e1, 0x6007, 0x003b, 0x602b, + 0x000b, 0x6013, 0x0000, 0x0078, 0x925d, 0x0e7e, 0x027e, 0x1078, + 0x4897, 0x0040, 0x933a, 0x1078, 0x4887, 0x1078, 0xa148, 0x00c0, + 0x9338, 0x2071, 0xa300, 0x70c8, 0xc085, 0x70ca, 0x0f7e, 0x2079, + 0x0100, 0x7294, 0xa284, 0x00ff, 0x706a, 0x78e6, 0xa284, 0xff00, + 0x726c, 0xa205, 0x706e, 0x78ea, 0x0f7f, 0x70d3, 0x0000, 0x2001, + 0xa352, 0x2004, 0xd0a4, 0x0040, 0x9331, 0x2011, 0xa5c4, 0x2013, + 0x07d0, 0xd0ac, 0x00c0, 0x933a, 0x1078, 0x260d, 0x0078, 0x933a, + 0x1078, 0xa178, 0x027f, 0x0e7f, 0x1078, 0x753d, 0x0078, 0x9199, + 0x1078, 0x753d, 0x007c, 0x0d7e, 0x067e, 0x6618, 0x2668, 0x6e04, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x9360, 0xa686, + 0x0004, 0x0040, 0x9360, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, + 0x0040, 0x9360, 0xa686, 0x0004, 0x0040, 0x9360, 0xa085, 0x0001, + 0x067f, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x9397, 0x0d7f, 0x007c, + 0x0d7e, 0x1078, 0x93a6, 0x00c0, 0x9390, 0x680c, 0xa08c, 0xff00, + 0x6820, 0xa084, 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4, + 0x0040, 0x937e, 0x2009, 0x0001, 0x0078, 0x938c, 0xd1ec, 0x0040, + 0x9390, 0x6920, 0xa18c, 0x00ff, 0x6824, 0x1078, 0x24e3, 0x00c0, + 0x9390, 0x2110, 0x2009, 0x0000, 0x1078, 0x285b, 0x0078, 0x9394, + 0xa085, 0x0001, 0x0078, 0x9395, 0xa006, 0x0d7f, 0x007c, 0x2069, + 0xa88d, 0x6800, 0xa082, 0x0010, 0x00c8, 0x93a4, 0x6013, 0x0000, + 0xa085, 0x0001, 0x0078, 0x93a5, 0xa006, 0x007c, 0x6013, 0x0000, + 0x2069, 0xa88c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x00c0, + 0x93ba, 0x6800, 0xa084, 0x00ff, 0xa08e, 0x0014, 0x0040, 0x93ba, + 0xa08e, 0x0010, 0x007c, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328, + 0xa1b6, 0x0013, 0x00c0, 0x93c7, 0x2008, 0x0079, 0x93da, 0xa1b6, + 0x0027, 0x0040, 0x93cf, 0xa1b6, 0x0014, 0x10c0, 0x1328, 0x2001, + 0x0007, 0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, + 0x6109, 0x007c, 0x941a, 0x941c, 0x941a, 0x941a, 0x941a, 0x941c, + 0x9424, 0x94ae, 0x9471, 0x94ae, 0x9485, 0x94ae, 0x9424, 0x94ae, + 0x94a6, 0x94ae, 0x94a6, 0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a, + 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, + 0x941c, 0x941a, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x941a, 0x94ae, + 0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a, + 0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941c, + 0x94ae, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a, 0x941a, + 0x941a, 0x941a, 0x1078, 0x1328, 0x1078, 0x6010, 0x6003, 0x0002, + 0x1078, 0x6109, 0x0078, 0x94b4, 0x0f7e, 0x2079, 0xa351, 0x7804, + 0x0f7f, 0xd0ac, 0x00c0, 0x94ae, 0x2001, 0x0000, 0x1078, 0x442b, + 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x94ae, + 0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9448, 0x6010, + 0xa005, 0x0040, 0x9448, 0x0c7f, 0x1078, 0x35f7, 0x0078, 0x94ae, + 0x0c7f, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002, 0x00c0, 0x9457, + 0x0f7e, 0x2079, 0xa300, 0x788c, 0x8000, 0x788e, 0x0f7f, 0x2001, + 0x0002, 0x1078, 0x443f, 0x1078, 0x6010, 0x601f, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0c7e, + 0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x58e1, 0x0c7f, 0x0078, + 0x94b4, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0xa686, 0x0004, 0x0040, + 0x94ae, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0xa300, 0x2004, + 0xa086, 0x0003, 0x00c0, 0x948e, 0x1078, 0x35f7, 0x2001, 0x0006, + 0x1078, 0x94b5, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0x2001, 0x0006, + 0x0078, 0x94ac, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0x0006, + 0x1078, 0x94b5, 0x0078, 0x94ae, 0x1078, 0x4472, 0x1078, 0x6010, + 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x017e, 0x0d7e, 0x6118, + 0x2168, 0x6900, 0xd184, 0x0040, 0x94d0, 0x6104, 0xa18e, 0x000a, + 0x00c0, 0x94c8, 0x699c, 0xd1a4, 0x00c0, 0x94c8, 0x2001, 0x0007, + 0x1078, 0x443f, 0x2001, 0x0000, 0x1078, 0x442b, 0x1078, 0x2839, + 0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, + 0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0xa1b6, + 0x0015, 0x00c0, 0x94e7, 0x1079, 0x94ee, 0x0078, 0x94ed, 0xa1b6, + 0x0016, 0x10c0, 0x1328, 0x1079, 0x94fa, 0x007c, 0x7ad0, 0x7ad0, + 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x9547, 0x9506, 0x7ad0, 0x7ad0, + 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, + 0x9547, 0x954f, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x0f7e, 0x2079, + 0xa351, 0x7804, 0xd0ac, 0x00c0, 0x952d, 0x6018, 0xa07d, 0x0040, + 0x952d, 0x7800, 0xd0f4, 0x00c0, 0x9519, 0x7810, 0xa005, 0x00c0, + 0x952d, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, + 0x443f, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, + 0x5c45, 0x1078, 0x6109, 0x0078, 0x9545, 0x2011, 0xa883, 0x2204, + 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x9545, 0x0c7e, 0x1078, + 0x4501, 0x0040, 0x9540, 0x0c7f, 0x1078, 0x753d, 0x0078, 0x9545, + 0x1078, 0x4235, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0x6604, + 0xa6b6, 0x001e, 0x00c0, 0x954e, 0x1078, 0x753d, 0x007c, 0x1078, + 0x7d0a, 0x00c0, 0x955b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, + 0x5c45, 0x0078, 0x955d, 0x1078, 0x753d, 0x007c, 0x6004, 0xa08a, + 0x0044, 0x10c8, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, + 0x6109, 0x007c, 0xa182, 0x0040, 0x0079, 0x956e, 0x9581, 0x9581, + 0x9581, 0x9581, 0x9583, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, + 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, + 0x9581, 0x1078, 0x1328, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e, + 0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x9594, + 0x2021, 0x0000, 0x1078, 0xa111, 0x6106, 0x2071, 0xa880, 0x7444, + 0xa4a4, 0xff00, 0x0040, 0x95eb, 0xa486, 0x2000, 0x00c0, 0x95a6, + 0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x5a6d, 0x1078, 0x1381, + 0x1040, 0x1328, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803, + 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2, + 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x017e, 0xa084, + 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x4982, + 0x017f, 0xa486, 0x2000, 0x00c0, 0x95d3, 0x2019, 0x0017, 0x1078, + 0x9e3b, 0x0078, 0x9645, 0xa486, 0x0400, 0x00c0, 0x95dd, 0x2019, + 0x0002, 0x1078, 0x9dec, 0x0078, 0x9645, 0xa486, 0x0200, 0x00c0, + 0x95e3, 0x1078, 0x9dd1, 0xa486, 0x1000, 0x00c0, 0x95e9, 0x1078, + 0x9e20, 0x0078, 0x9645, 0x2069, 0xa62d, 0x6a00, 0xd284, 0x0040, + 0x969b, 0xa284, 0x0300, 0x00c0, 0x9693, 0x6804, 0xa005, 0x0040, + 0x9683, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1366, 0x0040, 0x964c, + 0x7800, 0xd08c, 0x00c0, 0x9607, 0x7804, 0x8001, 0x7806, 0x6013, + 0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008, + 0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, + 0x6986, 0x6846, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286, + 0x0002, 0x00c0, 0x9627, 0x684f, 0x0040, 0x0078, 0x9631, 0xa286, + 0x0001, 0x00c0, 0x962f, 0x684f, 0x0080, 0x0078, 0x9631, 0x684f, + 0x0000, 0x20a9, 0x000a, 0x2001, 0xa890, 0xad90, 0x0015, 0x200c, + 0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x9637, 0x200c, 0x6982, + 0x8000, 0x200c, 0x697e, 0x1078, 0x4982, 0x027f, 0x047f, 0x157f, + 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, 0x0100, 0x6003, 0x0001, + 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645, + 0x2069, 0xa892, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x00c0, + 0x9677, 0x2069, 0xa880, 0x686c, 0xa084, 0x00ff, 0x017e, 0x6110, + 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, 0x0001, 0x6007, + 0x0043, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645, 0x6013, + 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078, + 0x6109, 0x0078, 0x9645, 0x6013, 0x0300, 0x0078, 0x9689, 0x6013, + 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078, + 0x6109, 0x0078, 0x9645, 0x6013, 0x0500, 0x0078, 0x9689, 0x6013, + 0x0600, 0x0078, 0x9658, 0x6013, 0x0200, 0x0078, 0x9658, 0xa186, + 0x0013, 0x00c0, 0x96b1, 0x6004, 0xa08a, 0x0040, 0x1048, 0x1328, + 0xa08a, 0x0053, 0x10c8, 0x1328, 0xa082, 0x0040, 0x2008, 0x0079, + 0x9725, 0xa186, 0x0051, 0x0040, 0x96be, 0xa186, 0x0047, 0x00c0, + 0x96d7, 0x6004, 0xa086, 0x0041, 0x0040, 0x96e5, 0x2001, 0x0109, + 0x2004, 0xd084, 0x0040, 0x96e5, 0x127e, 0x2091, 0x2200, 0x007e, + 0x017e, 0x027e, 0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f, + 0x6000, 0xa086, 0x0002, 0x00c0, 0x96e5, 0x0078, 0x976a, 0xa186, + 0x0027, 0x0040, 0x96df, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6004, + 0xa082, 0x0040, 0x2008, 0x0079, 0x96e8, 0x1078, 0x7583, 0x007c, + 0x96fb, 0x96fd, 0x96fd, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, + 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, + 0x96fb, 0x96fb, 0x96fb, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078, + 0x6109, 0x037e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x9722, 0xad84, + 0xf000, 0x0040, 0x9722, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc, + 0x00c0, 0x9722, 0x2019, 0x0004, 0x1078, 0x9e70, 0x6013, 0x0000, + 0x6014, 0xa005, 0x00c0, 0x9720, 0x2001, 0xa5a1, 0x2004, 0x6016, + 0x6003, 0x0007, 0x0d7f, 0x037f, 0x007c, 0x9738, 0x9757, 0x9741, + 0x9764, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, + 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, + 0x1078, 0x1328, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, + 0x200a, 0x1078, 0x6010, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, + 0x0040, 0x9752, 0x6003, 0x0007, 0x2009, 0x0043, 0x1078, 0x756c, + 0x0078, 0x9754, 0x6003, 0x0002, 0x1078, 0x6109, 0x007c, 0x1078, + 0x6010, 0x1078, 0xa0c6, 0x00c0, 0x9761, 0x1078, 0x5a41, 0x1078, + 0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x2009, 0x0041, + 0x0078, 0x98c1, 0xa182, 0x0040, 0x0079, 0x976e, 0x9781, 0x9783, + 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9784, 0x9781, 0x9781, + 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x978f, + 0x9781, 0x1078, 0x1328, 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, + 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x0d7e, + 0x1078, 0x5a41, 0x0d7f, 0x1078, 0xa134, 0x1078, 0x753d, 0x007c, + 0xa182, 0x0040, 0x0079, 0x979c, 0x97af, 0x97af, 0x97af, 0x97af, + 0x97af, 0x97af, 0x97af, 0x97b1, 0x97af, 0x97b4, 0x97df, 0x97af, + 0x97af, 0x97af, 0x97af, 0x97df, 0x97af, 0x97af, 0x97af, 0x1078, + 0x1328, 0x1078, 0x7583, 0x007c, 0x1078, 0x60b8, 0x1078, 0x61d3, + 0x6010, 0x0d7e, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x97ca, 0xa08c, + 0x0003, 0xa18e, 0x0002, 0x0040, 0x97d2, 0x2009, 0x0041, 0x0d7f, + 0x0078, 0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41, + 0x0d7f, 0x007c, 0x1078, 0xa0c6, 0x0040, 0x97d8, 0x0d7f, 0x007c, + 0x1078, 0x5a41, 0x1078, 0x753d, 0x0d7f, 0x0078, 0x97d1, 0x037e, + 0x1078, 0x60b8, 0x1078, 0x61d3, 0x6010, 0x0d7e, 0x2068, 0x6018, + 0x2004, 0xd0bc, 0x0040, 0x97ff, 0x684c, 0xa084, 0x0003, 0xa086, + 0x0002, 0x0040, 0x97fb, 0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, + 0x6328, 0xa31b, 0x632a, 0x6003, 0x0002, 0x0078, 0x9810, 0x2019, + 0x0004, 0x1078, 0x9e70, 0x6014, 0xa005, 0x00c0, 0x980c, 0x2001, + 0xa5a1, 0x2004, 0x8003, 0x6016, 0x6013, 0x0000, 0x6003, 0x0007, + 0x0d7f, 0x037f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9821, 0x6004, + 0xa086, 0x0042, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x6109, + 0x007c, 0xa186, 0x0027, 0x0040, 0x9829, 0xa186, 0x0014, 0x00c0, + 0x9839, 0x6004, 0xa086, 0x0042, 0x10c0, 0x1328, 0x2001, 0x0007, + 0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, + 0x007c, 0xa182, 0x0040, 0x0079, 0x983d, 0x9850, 0x9850, 0x9850, + 0x9850, 0x9850, 0x9850, 0x9850, 0x9852, 0x985e, 0x9850, 0x9850, + 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, + 0x1078, 0x1328, 0x037e, 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20, + 0x2c10, 0x1078, 0x15ec, 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e, + 0x2068, 0x6810, 0x6a14, 0x6118, 0x210c, 0xd1bc, 0x0040, 0x987d, + 0x6124, 0xd1f4, 0x00c0, 0x987d, 0x007e, 0x047e, 0x057e, 0x6c7c, + 0xa422, 0x6d80, 0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, + 0xa529, 0x652a, 0x057f, 0x047f, 0x007f, 0xa20d, 0x00c0, 0x9891, + 0x684c, 0xd0fc, 0x0040, 0x9889, 0x2009, 0x0041, 0x0d7f, 0x0078, + 0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41, 0x0d7f, + 0x007c, 0x007e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x007f, + 0x0040, 0x989e, 0x6003, 0x0002, 0x0d7f, 0x007c, 0x2009, 0xa30d, + 0x210c, 0xd19c, 0x0040, 0x98a8, 0x6003, 0x0007, 0x0078, 0x98aa, + 0x6003, 0x0006, 0x1078, 0x98b0, 0x1078, 0x5a43, 0x0d7f, 0x007c, + 0xd2fc, 0x0040, 0x98bc, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, + 0x2009, 0x0009, 0x0078, 0x98be, 0x2009, 0x0015, 0x6a6a, 0x6866, + 0x007c, 0xa182, 0x0040, 0x0048, 0x98c7, 0x0079, 0x98d4, 0xa186, + 0x0013, 0x0040, 0x98cf, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6024, + 0xd0dc, 0x1040, 0x1328, 0x007c, 0x98e7, 0x98ee, 0x98fa, 0x9906, + 0x98e7, 0x98e7, 0x98e7, 0x9915, 0x98e7, 0x98e9, 0x98e9, 0x98e7, + 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x1078, + 0x1328, 0x6024, 0xd0dc, 0x1040, 0x1328, 0x007c, 0x6003, 0x0001, + 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109, + 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e, + 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0003, + 0x6106, 0x2c10, 0x1078, 0x1cab, 0x127e, 0x2091, 0x8000, 0x1078, + 0x5c64, 0x1078, 0x61d3, 0x127f, 0x007c, 0xa016, 0x1078, 0x15ec, + 0x007c, 0x127e, 0x2091, 0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040, + 0x1079, 0x9926, 0x0d7f, 0x037f, 0x127f, 0x007c, 0x9936, 0x9938, + 0x994d, 0x996c, 0x9936, 0x9936, 0x9936, 0x9984, 0x9936, 0x9936, + 0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x1078, 0x1328, + 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003, + 0xa39e, 0x0003, 0x0040, 0x9962, 0x6003, 0x0001, 0x6106, 0x1078, + 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c, + 0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, + 0x9962, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x1078, 0x6109, + 0x0078, 0x9987, 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004, + 0x1078, 0x9e70, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c, 0xd0fc, + 0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9962, + 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x5c64, + 0x1078, 0x61d3, 0x0078, 0x9987, 0xa016, 0x1078, 0x15ec, 0x007c, + 0x1078, 0x6010, 0x6110, 0x81ff, 0x0040, 0x9999, 0x0d7e, 0x2168, + 0x1078, 0xa181, 0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f, + 0x0d7f, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x1078, 0x60b8, + 0x6110, 0x81ff, 0x0040, 0x99af, 0x0d7e, 0x2168, 0x1078, 0xa181, + 0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f, 0x0d7f, 0x1078, + 0x8c01, 0x1078, 0x61d3, 0x007c, 0xa182, 0x0085, 0x0079, 0x99b8, + 0x99c1, 0x99bf, 0x99bf, 0x99cd, 0x99bf, 0x99bf, 0x99bf, 0x1078, + 0x1328, 0x6003, 0x000b, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, + 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078, + 0xa0bf, 0x0040, 0x99d7, 0x1078, 0x753d, 0x0078, 0x99f3, 0x2071, + 0xa880, 0x7224, 0x6212, 0x7220, 0x1078, 0x9d10, 0x0040, 0x99e4, + 0x6007, 0x0086, 0x0078, 0x99ed, 0x6007, 0x0087, 0x7224, 0xa296, + 0xffff, 0x00c0, 0x99ed, 0x6007, 0x0086, 0x6003, 0x0001, 0x1078, + 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, + 0x00c0, 0x9a07, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a, + 0x008c, 0x10c8, 0x1328, 0xa082, 0x0085, 0x0079, 0x9a1e, 0xa186, + 0x0027, 0x0040, 0x9a13, 0xa186, 0x0014, 0x0040, 0x9a13, 0x1078, + 0x7583, 0x0078, 0x9a1d, 0x2001, 0x0007, 0x1078, 0x4472, 0x1078, + 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x9a25, 0x9a27, + 0x9a27, 0x9a25, 0x9a25, 0x9a25, 0x9a25, 0x1078, 0x1328, 0x1078, + 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0xa182, 0x0085, + 0x1048, 0x1328, 0xa182, 0x008c, 0x10c8, 0x1328, 0xa182, 0x0085, + 0x0079, 0x9a3a, 0x9a41, 0x9a41, 0x9a41, 0x9a43, 0x9a41, 0x9a41, + 0x9a41, 0x1078, 0x1328, 0x007c, 0xa186, 0x0013, 0x0040, 0x9a54, + 0xa186, 0x0014, 0x0040, 0x9a54, 0xa186, 0x0027, 0x0040, 0x9a54, + 0x1078, 0x7583, 0x0078, 0x9a5a, 0x1078, 0x6010, 0x1078, 0x8c01, + 0x1078, 0x6109, 0x007c, 0x037e, 0x1078, 0xa134, 0x603f, 0x0000, + 0x2019, 0x000b, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003, 0x0007, + 0x037f, 0x007c, 0x127e, 0x037e, 0x2091, 0x8000, 0x087e, 0x2c40, + 0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x00c0, + 0x9aa5, 0x077e, 0x2c38, 0x1078, 0x7105, 0x077f, 0x00c0, 0x9aa5, + 0x6000, 0xa086, 0x0000, 0x0040, 0x9aa5, 0x601c, 0xa086, 0x0007, + 0x0040, 0x9aa5, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x9a96, + 0x1078, 0xa134, 0x601f, 0x0007, 0x1078, 0x1749, 0x6010, 0x2068, + 0x1078, 0x8a44, 0x0040, 0x9a9e, 0x1078, 0x9e70, 0x0d7f, 0x6013, + 0x0000, 0x1078, 0xa134, 0x601f, 0x0007, 0x037f, 0x127f, 0x007c, + 0x0f7e, 0x0c7e, 0x037e, 0x157e, 0x2079, 0xa880, 0x7938, 0x783c, + 0x1078, 0x24e3, 0x00c0, 0x9af6, 0x017e, 0x0c7e, 0x1078, 0x4501, + 0x00c0, 0x9af6, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9, 0x0004, + 0x1078, 0x7e55, 0x00c0, 0x9af6, 0x017f, 0x027f, 0x027e, 0x017e, + 0x2019, 0x0029, 0x1078, 0x71e0, 0x1078, 0x5d53, 0x077e, 0x2039, + 0x0000, 0x1078, 0x5c78, 0x077f, 0x017f, 0x077e, 0x2039, 0x0000, + 0x1078, 0x9c38, 0x077f, 0x1078, 0x471b, 0x027e, 0x6204, 0xa294, + 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9aea, 0xa286, 0x0004, + 0x00c0, 0x9aed, 0x62a0, 0x1078, 0x28d5, 0x027f, 0x017f, 0x1078, + 0x4235, 0x6612, 0x6516, 0xa006, 0x0078, 0x9af8, 0x0c7f, 0x017f, + 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x0e7e, + 0x017e, 0x2009, 0xa31f, 0x2104, 0xa086, 0x0074, 0x00c0, 0x9b60, + 0x2069, 0xa88e, 0x690c, 0xa182, 0x0100, 0x0048, 0x9b50, 0x6908, + 0xa184, 0x8000, 0x0040, 0x9b5c, 0x6018, 0x2070, 0x7010, 0xa084, + 0x00ff, 0x0040, 0x9b1f, 0x7000, 0xd0f4, 0x0040, 0x9b23, 0xa184, + 0x0800, 0x0040, 0x9b5c, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54, + 0x6914, 0x2069, 0xa8ae, 0x6904, 0x81ff, 0x00c0, 0x9b48, 0x690c, + 0xa182, 0x0100, 0x0048, 0x9b50, 0x6908, 0x81ff, 0x00c0, 0x9b4c, + 0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54, 0x6918, 0xa18a, 0x0001, + 0x0048, 0x9b5c, 0x0078, 0x9b66, 0x6013, 0x0100, 0x0078, 0x9b62, + 0x6013, 0x0300, 0x0078, 0x9b62, 0x6013, 0x0500, 0x0078, 0x9b62, + 0x6013, 0x0700, 0x0078, 0x9b62, 0x6013, 0x0900, 0x0078, 0x9b62, + 0x6013, 0x0b00, 0x0078, 0x9b62, 0x6013, 0x0f00, 0x0078, 0x9b62, + 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, 0x9b67, 0xa006, 0x017f, + 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x027e, 0x037e, + 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006, + 0x0040, 0x9b90, 0xa286, 0x0004, 0x0040, 0x9b90, 0xa394, 0xff00, + 0x8217, 0xa286, 0x0006, 0x0040, 0x9b90, 0xa286, 0x0004, 0x0040, + 0x9b90, 0x0c7e, 0x2d60, 0x1078, 0x4513, 0x0c7f, 0x0078, 0x9bcb, + 0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, + 0x00c0, 0x9bcc, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9, 0x0004, + 0x1078, 0x7e55, 0x00c0, 0x9bcc, 0x047e, 0x017e, 0x6aa0, 0xa294, + 0x00ff, 0x8227, 0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040, + 0x9bb8, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6800, 0xc0e5, 0x6802, + 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078, + 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2001, 0x0007, 0x1078, + 0x4472, 0x017f, 0x047f, 0xa006, 0x157f, 0x037f, 0x027f, 0x0d7f, + 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xa88e, 0x6800, 0xa086, 0x0800, + 0x0040, 0x9bde, 0x6013, 0x0000, 0x0078, 0x9bdf, 0xa006, 0x0d7f, + 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2079, + 0xa88c, 0x7930, 0x7834, 0x1078, 0x24e3, 0x00c0, 0x9c05, 0x1078, + 0x4501, 0x00c0, 0x9c05, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9, + 0x0004, 0x1078, 0x7e55, 0x00c0, 0x9c05, 0x2011, 0xa894, 0xac98, + 0x0006, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x157f, 0x037f, 0x027f, + 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e, 0x017e, 0x027e, + 0x037e, 0x157e, 0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078, + 0x24e3, 0x00c0, 0x9c31, 0x1078, 0x4501, 0x00c0, 0x9c31, 0x2011, + 0xa896, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0, + 0x9c31, 0x2011, 0xa89a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, + 0x7e55, 0x157f, 0x037f, 0x027f, 0x017f, 0x007f, 0x0c7f, 0x007c, + 0x0e7e, 0x0c7e, 0x087e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, + 0x127e, 0x2091, 0x8000, 0x2740, 0x2029, 0xa5b4, 0x252c, 0x2021, + 0xa5ba, 0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060, + 0x81ff, 0x0040, 0x9c59, 0x8001, 0xa602, 0x00c8, 0x9cc3, 0x0078, + 0x9c5c, 0xa606, 0x0040, 0x9cc3, 0x2100, 0xac06, 0x0040, 0x9cb9, + 0x1078, 0x9ee5, 0x0040, 0x9cb9, 0x671c, 0xa786, 0x0001, 0x0040, + 0x9cde, 0xa786, 0x0004, 0x0040, 0x9cde, 0xa786, 0x0007, 0x0040, + 0x9cb9, 0x2500, 0xac06, 0x0040, 0x9cb9, 0x2400, 0xac06, 0x0040, + 0x9cb9, 0x1078, 0x9ef9, 0x00c0, 0x9cb9, 0x88ff, 0x0040, 0x9c84, + 0x6020, 0xa906, 0x00c0, 0x9cb9, 0x0d7e, 0x6000, 0xa086, 0x0004, + 0x00c0, 0x9c8e, 0x017e, 0x1078, 0x1749, 0x017f, 0xa786, 0x0008, + 0x00c0, 0x9c9d, 0x1078, 0x8c3b, 0x00c0, 0x9c9d, 0x1078, 0x7a05, + 0x0d7f, 0x1078, 0x8c01, 0x0078, 0x9cb9, 0x6010, 0x2068, 0x1078, + 0x8a44, 0x0040, 0x9cb6, 0xa786, 0x0003, 0x00c0, 0x9ccd, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa181, 0x017e, 0x1078, + 0x8cb8, 0x1078, 0x4982, 0x017f, 0x1078, 0x8bf4, 0x0d7f, 0x1078, + 0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8, + 0x9cc3, 0x0078, 0x9c4c, 0x127f, 0x027f, 0x047f, 0x057f, 0x067f, + 0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0, + 0x9ca7, 0xa386, 0x0005, 0x0040, 0x9cdb, 0x1078, 0xa181, 0x1078, + 0x9e70, 0x0078, 0x9cb6, 0x0d7f, 0x0078, 0x9cb9, 0x1078, 0x9ef9, + 0x00c0, 0x9cb9, 0x81ff, 0x0040, 0x9cb9, 0xa180, 0x0001, 0x2004, + 0xa086, 0x0018, 0x0040, 0x9cf3, 0xa180, 0x0001, 0x2004, 0xa086, + 0x002d, 0x00c0, 0x9cb9, 0x6000, 0xa086, 0x0002, 0x00c0, 0x9cb9, + 0x1078, 0x8c27, 0x0040, 0x9d04, 0x1078, 0x8c3b, 0x00c0, 0x9cb9, + 0x1078, 0x7a05, 0x0078, 0x9d0c, 0x1078, 0x2839, 0x1078, 0x8c3b, + 0x00c0, 0x9d0c, 0x1078, 0x7a05, 0x1078, 0x8c01, 0x0078, 0x9cb9, + 0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x9e8c, 0x017f, + 0x0040, 0x9d1f, 0x601c, 0xa084, 0x000f, 0x1079, 0x9d22, 0x0e7f, + 0x0c7f, 0x007c, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, + 0x9d2c, 0x9d2a, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, 0xa080, + 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, + 0x1078, 0x9ec0, 0x017f, 0x047f, 0x037e, 0x2019, 0x0002, 0x1078, + 0x9a6a, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0001, 0x1078, + 0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, + 0xa305, 0x2011, 0xa896, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f, + 0x157f, 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x087e, 0x077e, + 0x067e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, 0x2061, 0xaa00, + 0x2079, 0x0001, 0x8fff, 0x0040, 0x9dc3, 0x2071, 0xa300, 0x7644, + 0x7060, 0x8001, 0xa602, 0x00c8, 0x9dc3, 0x88ff, 0x0040, 0x9d7e, + 0x2800, 0xac06, 0x00c0, 0x9db9, 0x2079, 0x0000, 0x1078, 0x9ee5, + 0x0040, 0x9db9, 0x2400, 0xac06, 0x0040, 0x9db9, 0x671c, 0xa786, + 0x0006, 0x00c0, 0x9db9, 0xa786, 0x0007, 0x0040, 0x9db9, 0x88ff, + 0x00c0, 0x9d9d, 0x6018, 0xa206, 0x00c0, 0x9db9, 0x85ff, 0x0040, + 0x9d9d, 0x6020, 0xa106, 0x00c0, 0x9db9, 0x0d7e, 0x6000, 0xa086, + 0x0004, 0x00c0, 0x9da9, 0x1078, 0xa134, 0x601f, 0x0007, 0x1078, + 0x1749, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x9db3, 0x047e, + 0x1078, 0x9e70, 0x047f, 0x0d7f, 0x1078, 0x8c01, 0x88ff, 0x00c0, + 0x9dcd, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8, + 0x9dc3, 0x0078, 0x9d6a, 0xa006, 0x127f, 0x027f, 0x067f, 0x077f, + 0x087f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078, + 0x9dc4, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001, + 0x2c20, 0x2019, 0x0002, 0x6218, 0x097e, 0x2049, 0x0000, 0x1078, + 0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x1078, + 0x9d5b, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e, + 0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000, + 0x017e, 0x037e, 0x1078, 0x4501, 0x00c0, 0x9e14, 0x2c10, 0x057e, + 0x087e, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x097e, 0x2049, + 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, + 0x7105, 0x1078, 0x9d5b, 0x057f, 0x037f, 0x017f, 0x8108, 0x00f0, + 0x9df8, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c, + 0x077e, 0x057e, 0x6218, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001, + 0x2019, 0x0048, 0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f, + 0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x2c20, 0x1078, 0x9d5b, + 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e, 0x0c7e, + 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x037e, + 0x1078, 0x4501, 0x00c0, 0x9e64, 0x2c10, 0x087e, 0x2041, 0x0000, + 0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa111, 0x047f, 0x097e, + 0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000, + 0x1078, 0x7105, 0x1078, 0x9d5b, 0x037f, 0x017f, 0x8108, 0x00f0, + 0x9e46, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c, + 0x017e, 0x0f7e, 0xad82, 0xca00, 0x0048, 0x9e89, 0xad82, 0xffff, + 0x00c8, 0x9e89, 0x6800, 0xa07d, 0x0040, 0x9e86, 0x6803, 0x0000, + 0x6b52, 0x1078, 0x4982, 0x2f68, 0x0078, 0x9e7a, 0x6b52, 0x1078, + 0x4982, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061, + 0xaa00, 0x2071, 0xa300, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8, + 0x9ebb, 0x2100, 0xac06, 0x0040, 0x9ead, 0x6000, 0xa086, 0x0000, + 0x0040, 0x9ead, 0x6008, 0xa206, 0x00c0, 0x9ead, 0x6018, 0xa1a0, + 0x0006, 0x2424, 0xa406, 0x0040, 0x9eb7, 0xace0, 0x0010, 0x2001, + 0xa315, 0x2004, 0xac02, 0x00c8, 0x9ebb, 0x0078, 0x9e91, 0xa085, + 0x0001, 0x0078, 0x9ebc, 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c, + 0x0d7e, 0x007e, 0x1078, 0x1381, 0x007f, 0x1040, 0x1328, 0x6837, + 0x010d, 0x685e, 0x027e, 0x2010, 0x1078, 0x8a30, 0x2001, 0x0000, + 0x0040, 0x9ed6, 0x2200, 0xa080, 0x0008, 0x2004, 0x027f, 0x684a, + 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802, 0x683a, + 0x685a, 0x1078, 0x4982, 0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000, + 0x0040, 0x9ef8, 0xa786, 0x0001, 0x0040, 0x9ef8, 0xa786, 0x000a, + 0x0040, 0x9ef8, 0xa786, 0x0009, 0x0040, 0x9ef8, 0xa085, 0x0001, + 0x007c, 0x0e7e, 0x6018, 0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c, + 0x017e, 0x6004, 0xa08e, 0x001e, 0x00c0, 0x9f1a, 0x8007, 0x6130, + 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, + 0x601f, 0x0005, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8, + 0x1078, 0x6109, 0x017f, 0x007c, 0x0005, 0x0005, 0x007c, 0x6024, + 0xd0e4, 0x0040, 0x9f30, 0xd0cc, 0x0040, 0x9f2a, 0x1078, 0x8cfa, + 0x0078, 0x9f30, 0x1078, 0xa134, 0x1078, 0x5a41, 0x1078, 0x753d, + 0x007c, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f, 0x0079, 0x9f38, + 0x9f41, 0x9f41, 0x9f41, 0x9f43, 0x9f41, 0x9f43, 0x9f43, 0x9f41, + 0x9f43, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa280, 0x0007, + 0x2004, 0xa084, 0x000f, 0x0079, 0x9f4d, 0x9f56, 0x9f56, 0x9f56, + 0x9f56, 0x9f56, 0x9f56, 0x9f61, 0x9f56, 0x9f56, 0x6007, 0x003b, + 0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8, + 0x007c, 0x0c7e, 0x2260, 0x1078, 0xa134, 0x603f, 0x0000, 0x6024, + 0xc0f4, 0xc0cc, 0x6026, 0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007, + 0x00c0, 0x9fc2, 0x6810, 0xa005, 0x0040, 0x9f7f, 0xa080, 0x0013, + 0x2004, 0xd0fc, 0x00c0, 0x9f7f, 0x0d7f, 0x0078, 0x9f56, 0x6007, + 0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7e, + 0x2d60, 0x6100, 0xa186, 0x0002, 0x00c0, 0xa050, 0x6010, 0xa005, + 0x00c0, 0x9f99, 0x6000, 0xa086, 0x0007, 0x10c0, 0x1328, 0x0078, + 0xa050, 0xa08c, 0xf000, 0x00c0, 0x9fa5, 0x0078, 0x9fa5, 0x2068, + 0x6800, 0xa005, 0x00c0, 0x9f9f, 0x2d00, 0xa080, 0x0013, 0x2004, + 0xa084, 0x0003, 0xa086, 0x0002, 0x00c0, 0x9fbe, 0x6010, 0x2068, + 0x684c, 0xc0dc, 0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, + 0x2009, 0x0043, 0x1078, 0x98c1, 0x0078, 0xa050, 0x2009, 0x0041, + 0x0078, 0xa04a, 0xa186, 0x0005, 0x00c0, 0xa009, 0x6810, 0xa080, + 0x0013, 0x2004, 0xd0bc, 0x00c0, 0x9fd0, 0x0d7f, 0x0078, 0x9f56, + 0xd0b4, 0x0040, 0x9fd8, 0xd0fc, 0x1040, 0x1328, 0x0078, 0x9f72, + 0x6007, 0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109, + 0x0c7e, 0x2d60, 0x6100, 0xa186, 0x0002, 0x0040, 0x9feb, 0xa186, + 0x0004, 0x00c0, 0xa050, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0003, + 0x00c0, 0x9ff8, 0x7004, 0xac06, 0x00c0, 0x9ff8, 0x7003, 0x0000, + 0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000, + 0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078, + 0xa04a, 0x037e, 0x0d7e, 0x0d7e, 0x1078, 0x1381, 0x037f, 0x1040, + 0x1328, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b, + 0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872, + 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6018, 0xa080, 0x0028, 0x2004, + 0xa084, 0x00ff, 0x8007, 0x6320, 0x6b4a, 0x6846, 0x684f, 0x0000, + 0x6d6a, 0x6e66, 0x686f, 0x0001, 0x1078, 0x4982, 0x2019, 0x0045, + 0x6008, 0x2068, 0x1078, 0x9a6a, 0x2d00, 0x600a, 0x601f, 0x0006, + 0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f, + 0x0078, 0xa051, 0x603f, 0x0000, 0x6003, 0x0007, 0x1078, 0x98c1, + 0x0c7f, 0x0d7f, 0x007c, 0xa186, 0x0013, 0x00c0, 0xa05d, 0x6004, + 0xa082, 0x0085, 0x2008, 0x0079, 0xa077, 0xa186, 0x0027, 0x00c0, + 0xa070, 0x1078, 0x6010, 0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019, + 0x0004, 0x1078, 0x9e70, 0x0d7f, 0x037f, 0x1078, 0x6109, 0x007c, + 0xa186, 0x0014, 0x0040, 0xa061, 0x1078, 0x7583, 0x007c, 0xa080, + 0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa080, 0x1078, 0x1328, + 0x1078, 0x6010, 0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0xa182, + 0x008c, 0x00c8, 0xa091, 0xa182, 0x0085, 0x0048, 0xa091, 0x0079, + 0xa094, 0x1078, 0x7583, 0x007c, 0xa09b, 0xa09b, 0xa09b, 0xa09b, + 0xa09d, 0xa0bc, 0xa09b, 0x1078, 0x1328, 0x0d7e, 0x2c68, 0x1078, + 0x74d7, 0x0040, 0xa0b7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, + 0xa88e, 0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x600b, + 0xffff, 0x6918, 0x611a, 0x601f, 0x0004, 0x1078, 0x5bf8, 0x2d60, + 0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x753d, 0x007c, 0x0e7e, + 0x6018, 0x2070, 0x7000, 0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa080, + 0x0013, 0x200c, 0xd1ec, 0x0040, 0xa110, 0x2001, 0xa371, 0x2004, + 0xd0ec, 0x0040, 0xa110, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, + 0xd1ac, 0x0040, 0xa0ee, 0x0f7e, 0x2c78, 0x1078, 0x488f, 0x0f7f, + 0x0040, 0xa0ee, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x2009, 0xa371, + 0x210c, 0xd1f4, 0x00c0, 0xa10e, 0x0078, 0xa100, 0x2009, 0xa371, + 0x210c, 0xd1f4, 0x0040, 0xa0fa, 0x6024, 0xc0e4, 0x6026, 0xa006, + 0x0078, 0xa110, 0x2001, 0xa5a2, 0x200c, 0x8103, 0xa100, 0x603e, + 0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa10b, 0xa088, + 0x0003, 0x0078, 0xa103, 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, + 0x007c, 0x017e, 0x0c7e, 0x0e7e, 0x6120, 0xa2f0, 0x002b, 0x2e04, + 0x2060, 0x8cff, 0x0040, 0xa130, 0x84ff, 0x00c0, 0xa123, 0x6020, + 0xa106, 0x00c0, 0xa12b, 0x600c, 0x2072, 0x1078, 0x5a41, 0x1078, + 0x753d, 0x0078, 0xa12d, 0xacf0, 0x0003, 0x2e64, 0x0078, 0xa119, + 0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8, 0x002b, + 0x2d04, 0xa005, 0x0040, 0xa146, 0xac06, 0x0040, 0xa144, 0x2d04, + 0xa0e8, 0x0003, 0x0078, 0xa138, 0x600c, 0x206a, 0x0d7f, 0x007c, + 0x027e, 0x037e, 0x157e, 0x2011, 0xa325, 0x2204, 0xa084, 0x00ff, + 0x2019, 0xa88e, 0x2334, 0xa636, 0x00c0, 0xa174, 0x8318, 0x2334, + 0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa174, 0x2011, 0xa890, + 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0, + 0xa174, 0x2011, 0xa894, 0x6018, 0xa098, 0x0006, 0x20a9, 0x0004, + 0x1078, 0x7e55, 0x00c0, 0xa174, 0x157f, 0x037f, 0x027f, 0x007c, + 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x1078, 0x260d, 0x0e7f, + 0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0040, 0xa18a, + 0x1078, 0xa18c, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852, 0x007c, + 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, 0x017e, + 0x127e, 0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba, + 0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060, 0xa606, + 0x0040, 0xa1e4, 0x671c, 0xa786, 0x0001, 0x0040, 0xa1b3, 0xa786, + 0x0008, 0x00c0, 0xa1da, 0x2500, 0xac06, 0x0040, 0xa1da, 0x2400, + 0xac06, 0x0040, 0xa1da, 0x1078, 0x9ee5, 0x0040, 0xa1da, 0x1078, + 0x9ef9, 0x00c0, 0xa1da, 0x6000, 0xa086, 0x0004, 0x00c0, 0xa1cc, + 0x017e, 0x1078, 0x1749, 0x017f, 0x1078, 0x8c27, 0x00c0, 0xa1d2, + 0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0, 0xa1d8, 0x1078, 0x7a05, + 0x1078, 0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, + 0x00c8, 0xa1e4, 0x0078, 0xa1a3, 0x127f, 0x017f, 0x027f, 0x047f, + 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x007e, + 0x0e7e, 0x2091, 0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa1fb, + 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa201, 0x7030, 0x8000, + 0x7032, 0xd5ac, 0x0040, 0xa208, 0x2071, 0xa34a, 0x1078, 0xa237, + 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, + 0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa219, 0x7034, 0x8000, + 0x7036, 0xd5b4, 0x0040, 0xa21f, 0x7030, 0x8000, 0x7032, 0xd5ac, + 0x0040, 0xa226, 0x2071, 0xa34a, 0x1078, 0xa237, 0x0e7f, 0x007f, + 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, + 0xa342, 0x1078, 0xa237, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04, + 0x8000, 0x2072, 0x00c8, 0xa240, 0x8e70, 0x2e04, 0x8000, 0x2072, + 0x007c, 0x0e7e, 0x2071, 0xa340, 0x1078, 0xa237, 0x0e7f, 0x007c, + 0x0e7e, 0x2071, 0xa344, 0x1078, 0xa237, 0x0e7f, 0x007c, 0x0001, + 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x6286 +}; + +/************************************************************************ + * * + * --- ISP2200 Initiator/Target Firmware --- * + * with Fabric (Public Loop), Point-point, and * + * expanded LUN addressing for FCTAPE * + * * + ************************************************************************ + Copyright (C) 2000 and 2100 Qlogic Corporation + (www.qlogic.com) + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. +************************************************************************/ + +/* + * Firmware Version 2.01.27 (11:07 Dec 18, 2000) + */ + +static unsigned short risc_code_length2200 = 0x9cbf; +static unsigned short risc_code2200[] = { + 0x0470, 0x0000, 0x0000, 0x9cbf, 0x0000, 0x0002, 0x0001, 0x001b, + 0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, + 0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, + 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972, + 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, + 0x322e, 0x3031, 0x2e32, 0x3720, 0x2020, 0x2020, 0x2400, 0x20c1, + 0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xb1ff, 0x2091, + 0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x27b5, + 0x2051, 0xad00, 0x2a70, 0x2029, 0xe400, 0x2031, 0xffff, 0x2039, + 0xe3e9, 0x2021, 0x0200, 0x0804, 0x1449, 0x20a1, 0xacbf, 0xa00e, + 0x20a9, 0x0741, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466, + 0x746a, 0x20a1, 0xb400, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d, + 0xa18c, 0x000f, 0x2001, 0x000b, 0xa112, 0xa00e, 0x21a8, 0x41a4, + 0x3400, 0x8211, 0x1dd8, 0x7160, 0x3400, 0xa102, 0x0120, 0x0218, + 0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xad00, + 0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001, + 0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0, + 0x2009, 0xad00, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e, + 0x41a4, 0x080c, 0x13fc, 0x080c, 0x1613, 0x080c, 0x17ac, 0x080c, + 0x1e67, 0x080c, 0x492e, 0x080c, 0x801a, 0x080c, 0x159c, 0x080c, + 0x2ce6, 0x080c, 0x5a01, 0x080c, 0x5045, 0x080c, 0x6487, 0x080c, + 0x236a, 0x080c, 0x6686, 0x080c, 0x5fae, 0x080c, 0x226b, 0x080c, + 0x2338, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820, + 0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b, + 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000, + 0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3c98, 0x080c, + 0x2d0d, 0x080c, 0x5a4f, 0x080c, 0x51f4, 0x080c, 0x64a2, 0x0c80, + 0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1203, 0x10e2, 0x12cc, 0x13f9, + 0x13fa, 0x13fb, 0x080c, 0x14f6, 0x0005, 0x0126, 0x00f6, 0x2091, + 0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11d1, 0x080c, 0x1569, + 0x080c, 0x574f, 0x0150, 0x080c, 0x5775, 0x1580, 0x2079, 0x0100, + 0x7828, 0xa085, 0x1800, 0x782a, 0x0448, 0x080c, 0x569a, 0x7000, + 0xa086, 0x0001, 0x1904, 0x11d1, 0x7088, 0xa086, 0x0028, 0x1904, + 0x11d1, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0xa295, 0x1e2f, + 0x7a2a, 0x2011, 0x566e, 0x080c, 0x650d, 0x2011, 0x567b, 0x080c, + 0x650d, 0x2011, 0x481b, 0x080c, 0x650d, 0x2011, 0x8030, 0x2019, + 0x0000, 0x7087, 0x0000, 0x080c, 0x1d0f, 0x00e8, 0x080c, 0x41d1, + 0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11d1, 0x2011, 0x481b, + 0x080c, 0x650d, 0x2011, 0x567b, 0x080c, 0x650d, 0x080c, 0x1d0f, + 0x2001, 0xaf8c, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842, + 0x2011, 0x8010, 0x73c8, 0x080c, 0x3c5c, 0x7238, 0xc284, 0x723a, + 0x2001, 0xad0c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x79bd, 0x2011, + 0x0004, 0x080c, 0x959c, 0x080c, 0x4f71, 0x080c, 0x574f, 0x0158, + 0x080c, 0x4917, 0x0140, 0x7087, 0x0001, 0x70c3, 0x0000, 0x080c, + 0x436e, 0x0804, 0x11d1, 0x080c, 0x502d, 0x0120, 0x7a0c, 0xc2b4, + 0x7a0e, 0x0050, 0x080c, 0x9937, 0x70d0, 0xd09c, 0x1128, 0x709c, + 0xa005, 0x0110, 0x080c, 0x48f5, 0x70db, 0x0000, 0x70d7, 0x0000, + 0x72d0, 0x080c, 0x574f, 0x1178, 0x2011, 0x0000, 0x0016, 0x080c, + 0x2744, 0x2019, 0xaf8e, 0x211a, 0x001e, 0x704f, 0xffff, 0x7053, + 0x00ef, 0x7073, 0x0000, 0x2079, 0xad51, 0x7804, 0xd0ac, 0x0108, + 0xc295, 0x72d2, 0x080c, 0x574f, 0x0118, 0xa296, 0x0004, 0x0508, + 0x2011, 0x0001, 0x080c, 0x959c, 0x7097, 0x0000, 0x709b, 0xffff, + 0x7003, 0x0002, 0x00fe, 0x080c, 0x28fa, 0x2011, 0x0005, 0x080c, + 0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148, 0x00c6, 0x2061, + 0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e, 0x00ce, 0x012e, + 0x00d0, 0x7097, 0x0000, 0x709b, 0xffff, 0x7003, 0x0002, 0x2011, + 0x0005, 0x080c, 0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148, + 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e, + 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1118, + 0x20a9, 0x0100, 0x0010, 0x20a9, 0x0082, 0x080c, 0x574f, 0x1118, + 0x2009, 0x0000, 0x0010, 0x2009, 0x007e, 0x0016, 0x0026, 0x0036, + 0x2110, 0x0026, 0x2019, 0x0029, 0x080c, 0x7cf4, 0x002e, 0x080c, + 0xac07, 0x003e, 0x002e, 0x001e, 0x080c, 0x2bc9, 0x8108, 0x1f04, + 0x11e5, 0x00ce, 0x706f, 0x0000, 0x7070, 0xa084, 0x00ff, 0x7072, + 0x709f, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x7000, 0xa086, + 0x0002, 0x1904, 0x12ca, 0x7098, 0xa086, 0xffff, 0x0130, 0x080c, + 0x28fa, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d0, 0xd0ac, 0x1110, + 0xd09c, 0x0540, 0xd084, 0x0530, 0x0006, 0x0016, 0x2001, 0x0103, + 0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e, 0xd08c, 0x01d0, + 0x70d4, 0xa086, 0xffff, 0x0190, 0x080c, 0x2a56, 0x080c, 0x6c50, + 0x70d0, 0xd094, 0x1904, 0x12ca, 0x2011, 0x0001, 0x2019, 0x0000, + 0x080c, 0x2a8c, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d8, 0xa005, + 0x1904, 0x12ca, 0x7094, 0xa005, 0x1904, 0x12ca, 0x70d0, 0xd0a4, + 0x0118, 0xd0b4, 0x0904, 0x12ca, 0x080c, 0x502d, 0x1904, 0x12ca, + 0x2001, 0xad52, 0x2004, 0xd0ac, 0x01c8, 0x0156, 0x00c6, 0x20a9, + 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1118, 0x6000, + 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x125b, 0x00ce, 0x015e, + 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x12ca, 0x0006, 0x0016, + 0x2001, 0x0103, 0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e, + 0xa006, 0x2009, 0x0700, 0x20a9, 0x0002, 0x20a1, 0xafb5, 0x40a1, + 0x706c, 0x8007, 0x7170, 0x810f, 0x20a9, 0x0002, 0x40a1, 0x2009, + 0x0000, 0x080c, 0x14dc, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, + 0x40a1, 0xa006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x20a1, 0xafc5, + 0x40a1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x709b, 0xffff, + 0x080c, 0x1562, 0xa006, 0x080c, 0x261e, 0x080c, 0x3cce, 0x00f6, + 0x2079, 0x0100, 0x080c, 0x5775, 0x0150, 0x080c, 0x574f, 0x7828, + 0x0118, 0xa084, 0xe1ff, 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe, + 0x2001, 0xafc8, 0x2004, 0xa086, 0x0005, 0x1120, 0x2011, 0x0000, + 0x080c, 0x7adf, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c, 0x6c50, + 0x080c, 0x6d0d, 0x012e, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126, + 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0xad33, 0x2104, 0xa005, + 0x1110, 0x080c, 0x2770, 0x2009, 0x00f7, 0x080c, 0x48de, 0x7940, + 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, + 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954, + 0xd1ac, 0x1904, 0x133a, 0x080c, 0x5761, 0x0158, 0x080c, 0x5775, + 0x1128, 0x2001, 0xaf9d, 0x2003, 0x0000, 0x0070, 0x080c, 0x5757, + 0x0dc0, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, + 0x0001, 0x080c, 0x569a, 0x0058, 0x080c, 0x574f, 0x0140, 0x2009, + 0x00f8, 0x080c, 0x48de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, + 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x574f, 0x0138, 0x7824, + 0xd0ac, 0x1904, 0x13e0, 0x1f04, 0x1319, 0x0070, 0x7824, 0x080c, + 0x576b, 0x0118, 0xd0ac, 0x1904, 0x13e0, 0xa084, 0x1800, 0x0d98, + 0x7003, 0x0001, 0x0804, 0x13e0, 0x2001, 0x0001, 0x080c, 0x261e, + 0x0804, 0x13ef, 0x7850, 0xa084, 0x0180, 0x7852, 0x782f, 0x0020, + 0x20a9, 0x0046, 0x1d04, 0x1342, 0x2091, 0x6000, 0x1f04, 0x1342, + 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x782f, 0x0000, + 0x080c, 0x5761, 0x0158, 0x080c, 0x5775, 0x1128, 0x2001, 0xaf9d, + 0x2003, 0x0000, 0x0070, 0x080c, 0x5757, 0x0dc0, 0x2001, 0xaf9d, + 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x080c, 0x569a, + 0x0020, 0x2009, 0x00f8, 0x080c, 0x48de, 0x20a9, 0x000e, 0xe000, + 0x1f04, 0x136f, 0x7850, 0xa084, 0x0180, 0xa085, 0x1400, 0x7852, + 0x080c, 0x574f, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, + 0xe678, 0x2019, 0xea60, 0x7820, 0xd09c, 0x1558, 0x080c, 0x574f, + 0x05b8, 0x7824, 0xd0ac, 0x1904, 0x13e0, 0x080c, 0x5775, 0x1508, + 0x0046, 0x2021, 0x0190, 0x8421, 0x1df0, 0x004e, 0x8421, 0x11c8, + 0x7827, 0x0048, 0x20a9, 0x01f4, 0x1d04, 0x139c, 0x2091, 0x6000, + 0x1f04, 0x139c, 0x7824, 0xa084, 0x0068, 0x15a8, 0x2001, 0xaf9d, + 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x7003, 0x0001, + 0x0478, 0x8319, 0x1980, 0x2009, 0xad33, 0x2104, 0x8000, 0x200a, + 0xa084, 0xfff0, 0x0120, 0x200b, 0x0000, 0x080c, 0x2770, 0x00d8, + 0x080c, 0x5761, 0x1140, 0xa4a2, 0x0064, 0x1128, 0x080c, 0x5726, + 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0xe000, 0xe000, 0x7824, + 0x080c, 0x576b, 0x0110, 0xd0ac, 0x1158, 0xa084, 0x1800, 0x09c8, + 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x261e, 0x0048, + 0x2001, 0xad33, 0x2003, 0x0000, 0x7827, 0x0048, 0x7828, 0xc09d, + 0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x015e, + 0x003e, 0x000e, 0x080c, 0x1539, 0x012e, 0x00fe, 0x004e, 0x001e, + 0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2001, 0xaf9d, 0x2003, + 0x0000, 0x7087, 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, + 0x0218, 0x704f, 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff, + 0x706f, 0x0000, 0x7073, 0x0000, 0x080c, 0x9937, 0x2061, 0xaf8d, + 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, + 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, + 0x2061, 0xaf95, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, + 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, + 0x601f, 0x0000, 0x2061, 0xafa6, 0x6003, 0x514c, 0x6007, 0x4f47, + 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xad27, 0x2003, 0x0000, + 0x0005, 0x04a0, 0x2011, 0x0000, 0x81ff, 0x0570, 0xa186, 0x0001, + 0x1148, 0x2031, 0x8fff, 0x2039, 0xcc01, 0x2021, 0x0100, 0x2029, + 0xcc00, 0x00e8, 0xa186, 0x0002, 0x1118, 0x2011, 0x0000, 0x00b8, + 0xa186, 0x0005, 0x1118, 0x2011, 0x0001, 0x0088, 0xa186, 0x0009, + 0x1118, 0x2011, 0x0002, 0x0058, 0xa186, 0x000a, 0x1118, 0x2011, + 0x0002, 0x0028, 0xa186, 0x0055, 0x1110, 0x2011, 0x0003, 0x3800, + 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0804, 0x104d, 0xa00e, 0x2011, + 0x0003, 0x2019, 0x1485, 0x0804, 0x14d6, 0x2019, 0xaaaa, 0x2061, + 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0xa306, 0x2262, + 0x1110, 0xc1b5, 0xc1a5, 0x2011, 0x0000, 0x2019, 0x1498, 0x04f0, + 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, + 0x2c1c, 0x2061, 0x7fff, 0xe000, 0xe000, 0x2c04, 0x2061, 0xffff, + 0x2262, 0xa306, 0x0110, 0xc18d, 0x0008, 0xc185, 0x2011, 0x0002, + 0x2019, 0x14b3, 0x0418, 0x2061, 0xffff, 0x2019, 0xaaaa, 0x2c14, + 0x2362, 0xe000, 0xe000, 0x2c04, 0x2262, 0xa306, 0x1180, 0x2c14, + 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0x2c04, 0x2061, + 0xffff, 0x2262, 0xa306, 0x1110, 0xc195, 0x0008, 0xc19d, 0x2011, + 0x0001, 0x2019, 0x14d4, 0x0010, 0x0804, 0x144a, 0x3800, 0xa084, + 0xfffc, 0xa205, 0x20c0, 0x0837, 0x2011, 0x0000, 0x080c, 0x4cdc, + 0x1178, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0128, 0xa0c4, + 0xff00, 0xa8c6, 0x0600, 0x1120, 0xa186, 0x0080, 0x0108, 0x8210, + 0x8108, 0xa186, 0x0100, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, + 0x0e04, 0x14f8, 0x0006, 0x0016, 0x2079, 0x0000, 0x7818, 0xd084, + 0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e, 0x7826, 0x3900, + 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, 0x0126, + 0x0156, 0x0146, 0x20a9, 0x0010, 0x20a1, 0xb0c8, 0x2091, 0x2000, + 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, 0x0010, + 0x2091, 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, 0x40a1, + 0x20a9, 0x0010, 0x2091, 0x2800, 0x40a1, 0x014e, 0x015e, 0x012e, + 0x2079, 0xad00, 0x7803, 0x0005, 0x2091, 0x4080, 0x04c9, 0x0cf8, + 0x0005, 0x0006, 0x080c, 0x1584, 0x1518, 0x00f6, 0x2079, 0xad23, + 0x2f04, 0x8000, 0x207a, 0xa082, 0x000f, 0x0258, 0xa006, 0x207a, + 0x2079, 0xad25, 0x2f04, 0xa084, 0x0001, 0xa086, 0x0001, 0x207a, + 0x0070, 0x2079, 0xad25, 0x2f7c, 0x8fff, 0x1128, 0x2001, 0x0c03, + 0x2003, 0x0040, 0x0020, 0x2001, 0x0c03, 0x2003, 0x00c0, 0x00fe, + 0x000e, 0x0005, 0x0409, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0080, + 0x0005, 0x00d1, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0005, + 0x0006, 0x0091, 0x1178, 0x2001, 0x0c03, 0x2003, 0x0040, 0x2009, + 0x0fff, 0x00a1, 0x2001, 0x0c03, 0x2003, 0x0080, 0x2009, 0x0fff, + 0x0069, 0x0c88, 0x000e, 0x0005, 0x00c6, 0x2061, 0x0c00, 0x2c04, + 0xa084, 0x00ff, 0xa086, 0x00aa, 0x00ce, 0x0005, 0x0156, 0x0126, + 0xa18c, 0x0fff, 0x21a8, 0x1d04, 0x1593, 0x2091, 0x6000, 0x1f04, + 0x1593, 0x012e, 0x015e, 0x0005, 0x2071, 0xad00, 0x715c, 0x712e, + 0x2021, 0x0001, 0xa190, 0x0030, 0xa298, 0x0030, 0x0240, 0x7060, + 0xa302, 0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800, + 0xd08c, 0x0148, 0x7060, 0xa086, 0xad00, 0x0128, 0x7063, 0xad00, + 0x2011, 0x1000, 0x0c48, 0x200b, 0x0000, 0x74ae, 0x74b2, 0x0005, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x70b0, 0xa0ea, + 0x0010, 0x0268, 0x8001, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e, + 0x206b, 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, + 0x0cd8, 0x00e6, 0x2071, 0xad00, 0x0126, 0x2091, 0x8000, 0x70b0, + 0x8001, 0x0260, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, + 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x702c, 0x206a, + 0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x012e, 0x00ee, 0x0005, + 0x8dff, 0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de, + 0x0cb8, 0x0005, 0x00e6, 0x2071, 0xad00, 0x70b0, 0xa08a, 0x0010, + 0xa00d, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7007, 0x0000, + 0x701b, 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, + 0x8004, 0x7012, 0x00ee, 0x0005, 0x00e6, 0x2270, 0x700b, 0x0000, + 0x2071, 0xafec, 0x7018, 0xa088, 0xaff5, 0x220a, 0x8000, 0xa084, + 0x0007, 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, + 0x0081, 0x00fe, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7004, + 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee, + 0x0005, 0x7000, 0x0002, 0x164f, 0x16b3, 0x16d0, 0x16d0, 0x7018, + 0x711c, 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180, + 0xaff5, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e, + 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, 0x783a, + 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, 0x00de, + 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, + 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, + 0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, + 0x7803, 0x0020, 0x7803, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, + 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x2098, 0x20a1, 0x0014, + 0x7803, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210, + 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, + 0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x015e, 0x014e, 0x013e, + 0x002e, 0x001e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2099, 0xadf9, + 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, + 0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, + 0x7002, 0x700b, 0xadf4, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, + 0x0136, 0x0146, 0x0156, 0x2001, 0xae28, 0x209c, 0x20a1, 0x0014, + 0x7803, 0x0026, 0x2001, 0xae29, 0x20ac, 0x53a6, 0x2099, 0xae2a, + 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, + 0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, + 0x7002, 0x700b, 0xae25, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, + 0x0016, 0x00e6, 0x2071, 0xafec, 0x00f6, 0x2079, 0x0010, 0x7904, + 0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023, + 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1649, 0x1713, 0x1741, 0x176b, + 0x179b, 0x1712, 0x0cf8, 0xa18c, 0x0700, 0x1528, 0x0136, 0x0146, + 0x0156, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, + 0x20a8, 0x53a5, 0x3400, 0x7016, 0x015e, 0x014e, 0x013e, 0x700c, + 0xa005, 0x0570, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x167a, + 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000, + 0x080c, 0x1649, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, + 0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830, + 0x7832, 0x7834, 0x7836, 0x080c, 0x168f, 0x0005, 0x7008, 0xa080, + 0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005, + 0x00d6, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, + 0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000, + 0x080c, 0x1649, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146, + 0x0156, 0x2001, 0xadf7, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, + 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xadf9, + 0x2004, 0xd0bc, 0x0148, 0x2001, 0xae02, 0x2004, 0xa080, 0x000d, + 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007, + 0x0000, 0x080c, 0x5ae6, 0x080c, 0x1649, 0x0005, 0x2011, 0x8003, + 0x080c, 0x3c5c, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0xae27, + 0x2003, 0x0100, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005, 0x2011, + 0x8004, 0x080c, 0x3c5c, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079, + 0x0030, 0x2071, 0xaffd, 0x7003, 0x0000, 0x700f, 0xb003, 0x7013, + 0xb003, 0x780f, 0x00f6, 0x7803, 0x0004, 0x012e, 0x0005, 0x6934, + 0xa184, 0x0007, 0x0002, 0x17cb, 0x1809, 0x17cb, 0x17cb, 0x17cb, + 0x17f1, 0x17d8, 0x17cf, 0xa085, 0x0001, 0x0804, 0x1823, 0x684c, + 0xd0bc, 0x0dc8, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x04c8, + 0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d70, 0x684c, 0xd0bc, 0x0d58, + 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, 0xa080, 0x000d, + 0x2004, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832, 0x6858, + 0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac, + 0x0990, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, + 0xa080, 0x2186, 0x2005, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, + 0x0080, 0x684c, 0xd0ac, 0x0904, 0x17cb, 0xa006, 0x682e, 0x682a, + 0x6858, 0xa18c, 0x000f, 0xa188, 0x2186, 0x210d, 0x6932, 0x2d08, + 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, + 0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000, + 0x2001, 0x020a, 0x2004, 0x82ff, 0x01a8, 0xa280, 0x0004, 0x00d6, + 0x206c, 0x684c, 0xd0dc, 0x1150, 0x080c, 0x17bf, 0x0138, 0x00de, + 0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0020, 0x6808, 0x8000, + 0x680a, 0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200, + 0x002e, 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a, + 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0xb01e, 0x0210, + 0x2009, 0xb003, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118, + 0xa080, 0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005, + 0x7206, 0x2001, 0x1866, 0x0006, 0x2260, 0x0804, 0x197a, 0x0126, + 0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e, + 0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62, + 0x6b5e, 0xa005, 0x0904, 0x18c8, 0x6808, 0xa005, 0x0904, 0x18ff, + 0x7000, 0xa005, 0x1108, 0x0488, 0x700c, 0x7110, 0xa106, 0x1904, + 0x1907, 0x7004, 0xa406, 0x1548, 0x2001, 0x0005, 0x2004, 0xd08c, + 0x0168, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010, 0xa080, + 0x0002, 0x2004, 0xa005, 0x0904, 0x18ff, 0x0c10, 0x2001, 0x0207, + 0x2004, 0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086, + 0x6000, 0x0108, 0x0c08, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803, + 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, + 0x1904, 0x1907, 0x2009, 0x0048, 0x080c, 0x80a7, 0x0804, 0x1907, + 0x6808, 0xa005, 0x05a0, 0x7000, 0xa005, 0x0588, 0x700c, 0x7110, + 0xa106, 0x1118, 0x7004, 0xa406, 0x1550, 0x2001, 0x0005, 0x2004, + 0xd08c, 0x0160, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010, + 0xa080, 0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28, 0x2001, 0x0207, + 0x2004, 0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d50, + 0x7804, 0xa084, 0x6000, 0x0118, 0xa086, 0x6000, 0x19f0, 0x7818, + 0x6812, 0x781c, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x6100, + 0xa18e, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x80a7, 0x00ce, + 0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046, + 0x0056, 0x080c, 0x1d86, 0x0026, 0x0056, 0x2071, 0xaffd, 0x7000, + 0xa086, 0x0000, 0x0580, 0x7004, 0xac06, 0x11f8, 0x2079, 0x0030, + 0x7000, 0xa086, 0x0003, 0x01c8, 0x7804, 0xd0fc, 0x1198, 0x2001, + 0x0207, 0x2004, 0xd09c, 0x1dc0, 0x7803, 0x0004, 0x7804, 0xd0ac, + 0x1de8, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007, + 0x0000, 0x0018, 0x080c, 0x1a6c, 0x08d0, 0x0156, 0x20a9, 0x0009, + 0x2009, 0xb003, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003, + 0x1f04, 0x1942, 0x015e, 0x005e, 0x002e, 0x2001, 0x015d, 0x201c, + 0x831a, 0x2302, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, + 0x005e, 0x004e, 0x003e, 0x002e, 0x00ee, 0x00fe, 0x0005, 0x700c, + 0x7110, 0xa106, 0x0904, 0x19dd, 0x2104, 0x7006, 0x2060, 0x8108, + 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0xb01e, 0x0210, 0x2009, + 0xb003, 0x7112, 0x700c, 0xa106, 0x1128, 0x080c, 0x2744, 0x2001, + 0x0138, 0x2102, 0x8cff, 0x0588, 0x6010, 0x2068, 0x2d58, 0x6828, + 0xa406, 0x1580, 0x682c, 0xa306, 0x1568, 0x7004, 0x2060, 0x6020, + 0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128, 0x6817, 0xffff, 0x6813, + 0xffff, 0x00d8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810, + 0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, + 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x04c9, 0x0118, + 0x2009, 0x0001, 0x04a9, 0x2d58, 0x0005, 0x080c, 0x1ced, 0x0904, + 0x195f, 0x0cd0, 0x6020, 0xd0d4, 0x01b8, 0x6038, 0xa402, 0x6034, + 0xa303, 0x0108, 0x1288, 0x643a, 0x6336, 0x6c2a, 0x6b2e, 0x0046, + 0x0036, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80, 0xa303, + 0x6816, 0x003e, 0x004e, 0x0018, 0x080c, 0x98cb, 0x09f0, 0x601c, + 0xa08e, 0x0008, 0x0904, 0x1985, 0xa08e, 0x000a, 0x0904, 0x1985, + 0x080c, 0x21a6, 0x1990, 0x0804, 0x1985, 0x7003, 0x0000, 0x0005, + 0x8aff, 0x0904, 0x1a46, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11b8, + 0xd0f4, 0x1528, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1a30, + 0x1a15, 0x1a15, 0x1a30, 0x1a30, 0x1a29, 0x1a30, 0x1a15, 0x1a30, + 0x1a1a, 0x1a1a, 0x1a30, 0x1a30, 0x1a30, 0x1a21, 0x1a1a, 0x7803, + 0x0004, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x00d6, + 0xd99c, 0x0548, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x0420, 0xc0f4, + 0x6852, 0x6b6c, 0x6a70, 0x00d6, 0x0428, 0x6b08, 0x6a0c, 0x6d00, + 0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, + 0x0090, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, + 0x1138, 0x00de, 0x080c, 0x2148, 0x1904, 0x19e0, 0xa00e, 0x00b0, + 0x00de, 0x080c, 0x14f6, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, + 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x00de, 0x6828, 0xa300, + 0x682a, 0x682c, 0xa201, 0x682e, 0x080c, 0x2148, 0x0005, 0x080c, + 0x14f6, 0x080c, 0x1e1a, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, + 0x7003, 0x0000, 0x080c, 0x1d22, 0x080c, 0x9596, 0x0170, 0x6808, + 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, + 0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c, + 0x0804, 0x1c5e, 0x080c, 0x14f6, 0x0126, 0x2091, 0x2200, 0x0006, + 0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, + 0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000, + 0x0002, 0x1a89, 0x1a8f, 0x1b92, 0x1c39, 0x1c4d, 0x1a89, 0x1a89, + 0x1a89, 0x7804, 0xd09c, 0x1904, 0x1c5e, 0x080c, 0x14f6, 0x8001, + 0x7002, 0xa184, 0x0880, 0x1190, 0xd19c, 0x1904, 0x1b20, 0x8aff, + 0x0904, 0x1b20, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0904, 0x1c5e, + 0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7803, 0x0004, + 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1b00, 0x0026, 0x0036, 0x7c20, + 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, + 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, + 0x0009, 0x7003, 0x0004, 0x0010, 0x080c, 0x1c62, 0x6b28, 0x6a2c, + 0x2400, 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e, + 0x00c6, 0x7004, 0x2060, 0x6020, 0xd0f4, 0x1110, 0x633a, 0x6236, + 0x00ce, 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x080c, 0x215e, 0x2a00, + 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, + 0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004, + 0x2060, 0x2009, 0x0048, 0x080c, 0x80a7, 0x7000, 0xa086, 0x0004, + 0x0904, 0x1c5e, 0x7003, 0x0000, 0x080c, 0x195f, 0x0804, 0x1c5e, + 0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0xac73, 0x005e, 0x080c, + 0x1d22, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5029, 0x0118, 0x7820, + 0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, + 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0804, 0x1c5e, + 0x7004, 0x00c6, 0x2060, 0x6020, 0x00ce, 0xd0f4, 0x0128, 0x6808, + 0x8001, 0x680a, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x7a1c, 0x6a16, + 0xd19c, 0x0160, 0xa205, 0x0150, 0x7004, 0xa080, 0x0007, 0x2004, + 0xa084, 0xfffd, 0xa086, 0x0008, 0x1904, 0x1aa6, 0x684c, 0xc0f5, + 0x684e, 0x7814, 0xa005, 0x1180, 0x7003, 0x0000, 0x6808, 0x8001, + 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x80a7, + 0x080c, 0x195f, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x781c, 0x6816, + 0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, + 0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, + 0x810b, 0x080c, 0x1da5, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, + 0x0001, 0x7804, 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803, 0x0004, + 0x780f, 0x00f6, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, + 0x080c, 0x80a7, 0x080c, 0x1dd7, 0x0958, 0x7908, 0xd1ec, 0x1118, + 0x2009, 0x0009, 0x0010, 0x2009, 0x0019, 0x7902, 0x7003, 0x0003, + 0x0804, 0x1c5e, 0x8001, 0x7002, 0xd194, 0x01a8, 0x7804, 0xd0fc, + 0x1904, 0x1c2c, 0xd09c, 0x0130, 0x7804, 0xd0fc, 0x1904, 0x1a74, + 0xd09c, 0x11a8, 0x8aff, 0x0904, 0x1c5e, 0x2009, 0x0001, 0x080c, + 0x19e0, 0x0804, 0x1c5e, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904, + 0x1c5e, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7818, + 0x6812, 0x7a1c, 0x6a16, 0xa205, 0x0904, 0x1b3e, 0x7803, 0x0004, + 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1c0f, 0x6834, 0xa084, 0x00ff, + 0xa086, 0x0029, 0x1118, 0xd19c, 0x1904, 0x1b3e, 0x0026, 0x0036, + 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, + 0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, + 0x7803, 0x0009, 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1c62, + 0x001e, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6, 0x2805, 0xac68, + 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020, + 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x1ac8, + 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001, + 0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1b50, 0x0056, + 0x7d0c, 0x080c, 0xac73, 0x005e, 0x080c, 0x1d22, 0x00f6, 0x7004, + 0x2078, 0x080c, 0x5029, 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe, + 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, + 0x791a, 0x6980, 0x791e, 0x0490, 0x7804, 0xd09c, 0x0904, 0x1a74, + 0x7c20, 0x7824, 0xa405, 0x1904, 0x1a74, 0x7803, 0x0002, 0x0804, + 0x1bb7, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0150, + 0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048, + 0x080c, 0x80a7, 0x080c, 0x195f, 0x0088, 0x7803, 0x0004, 0x7003, + 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068, 0x6808, + 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x197a, 0x001e, 0x000e, + 0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1ce1, 0x7004, + 0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1ce1, 0x00d6, 0x00c6, + 0x216c, 0x2d00, 0xa005, 0x0904, 0x1cdf, 0x6820, 0xd0d4, 0x1904, + 0x1cdf, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104, + 0x6b2c, 0xa306, 0x1904, 0x1cdf, 0x8108, 0x2104, 0x6a28, 0xa206, + 0x1904, 0x1cdf, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, + 0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, + 0x6034, 0xd09c, 0x0150, 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808, + 0x783a, 0x680c, 0x783e, 0x00de, 0x04a0, 0xa006, 0x783a, 0x783e, + 0x0480, 0x8108, 0x2104, 0xa005, 0x1590, 0x8108, 0x2104, 0xa005, + 0x1570, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160, + 0xa180, 0x000d, 0x2004, 0xd09c, 0x1170, 0x6008, 0x7822, 0x686e, + 0x600c, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006, + 0x783a, 0x783e, 0x0070, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826, + 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c, + 0x783e, 0x6810, 0x781a, 0x6814, 0x781e, 0x7803, 0x0011, 0x00ce, + 0x00de, 0x0005, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005, + 0x1118, 0x8109, 0x1dd8, 0x0005, 0x0005, 0x0ca1, 0x01e0, 0x7908, + 0xd1ec, 0x1160, 0x080c, 0x1dd7, 0x0148, 0x7803, 0x0009, 0x7904, + 0xd1fc, 0x0de8, 0x7803, 0x0006, 0x0c29, 0x0168, 0x780c, 0xd0a4, + 0x1150, 0x7007, 0x0000, 0x080c, 0x1dd7, 0x0140, 0x7803, 0x0019, + 0x7003, 0x0003, 0x0018, 0x00b1, 0xa085, 0x0001, 0x0005, 0x0126, + 0x2091, 0x2200, 0x7000, 0xa086, 0x0003, 0x1150, 0x700c, 0x7110, + 0xa106, 0x0130, 0x20e1, 0x9028, 0x700f, 0xb003, 0x7013, 0xb003, + 0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1550, 0x2001, 0x0160, + 0x2003, 0x0000, 0x2001, 0x0138, 0x2003, 0x0000, 0x2011, 0x00c8, + 0xe000, 0xe000, 0x8211, 0x1de0, 0x080c, 0x1d7e, 0x700c, 0x7110, + 0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, + 0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xb01e, 0x0210, + 0x2009, 0xb003, 0x7112, 0x0c50, 0x080c, 0x57d1, 0x00ce, 0x0005, + 0x04a9, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01d0, 0x2104, + 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a, + 0xa188, 0x0003, 0xa182, 0xb01e, 0x0210, 0x2009, 0xb003, 0x7112, + 0x700c, 0xa106, 0x1d40, 0x080c, 0x2744, 0x2001, 0x0138, 0x2102, + 0x0c10, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x2001, 0x0160, + 0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x20e1, 0x9028, + 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x0005, 0x2001, 0x0138, + 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, + 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, + 0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, 0x2001, 0x0111, 0x201c, + 0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, 0x00e6, 0x2071, 0x0200, + 0x7808, 0xa084, 0xf000, 0xa10d, 0x08c9, 0x2019, 0x5000, 0x8319, + 0x0168, 0x2001, 0xb01e, 0x2004, 0xa086, 0x0000, 0x0138, 0x2001, + 0x0021, 0xd0fc, 0x0da0, 0x080c, 0x1ff4, 0x0c78, 0x20e1, 0x7000, + 0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f, + 0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001, + 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x0005, 0x7908, + 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0218, 0xa085, 0x0001, 0x0088, + 0x2001, 0x020a, 0x81ff, 0x0130, 0x20e1, 0x6000, 0x200c, 0x200c, + 0x200c, 0x200c, 0x20e1, 0x7000, 0x200c, 0x200c, 0x7003, 0x0000, + 0xa006, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x0026, 0x2071, 0xaffd, + 0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x01a8, + 0x8211, 0x0188, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0dc8, 0x7904, + 0xa18c, 0x0780, 0x0016, 0x080c, 0x1a6c, 0x001e, 0x81ff, 0x1118, + 0x2011, 0x0050, 0x0c48, 0xa085, 0x0001, 0x002e, 0x001e, 0x00ee, + 0x00fe, 0x0005, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac, + 0x0904, 0x1e66, 0x8109, 0x1dd0, 0x2009, 0x0100, 0x210c, 0xa18a, + 0x0003, 0x0a0c, 0x14f6, 0x080c, 0x20f2, 0x00e6, 0x00f6, 0x2071, + 0xafec, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0538, 0x7800, + 0x0006, 0x7820, 0x0006, 0x7830, 0x0006, 0x7834, 0x0006, 0x7838, + 0x0006, 0x783c, 0x0006, 0x7803, 0x0004, 0xe000, 0xe000, 0x2079, + 0x0030, 0x7804, 0xd0ac, 0x190c, 0x14f6, 0x2079, 0x0010, 0x000e, + 0x783e, 0x000e, 0x783a, 0x000e, 0x7836, 0x000e, 0x7832, 0x000e, + 0x7822, 0x000e, 0x7802, 0x00fe, 0x00ee, 0x0030, 0x00fe, 0x00ee, + 0x7804, 0xd0ac, 0x190c, 0x14f6, 0x080c, 0x6d0d, 0x0005, 0x00e6, + 0x2071, 0xb01e, 0x7003, 0x0000, 0x00ee, 0x0005, 0x00d6, 0xa280, + 0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1ee4, 0x6934, 0xa184, + 0x0007, 0x0002, 0x1e82, 0x1ecf, 0x1e82, 0x1e82, 0x1e82, 0x1eb6, + 0x1e95, 0x1e84, 0x080c, 0x14f6, 0x684c, 0xd0b4, 0x0904, 0x1fcc, + 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, + 0x6880, 0x680e, 0x6958, 0x0804, 0x1ed7, 0x6834, 0xa084, 0x00ff, + 0xa086, 0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6860, + 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, + 0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, + 0xa080, 0x2186, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c, 0x00ff, + 0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6804, + 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x2186, + 0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088, 0x684c, + 0xd0b4, 0x0904, 0x1a47, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, + 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832, + 0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6, 0x2079, + 0x0020, 0x7804, 0xd0fc, 0x190c, 0x1ff4, 0x00e6, 0x00d6, 0x2071, + 0xb01e, 0x7000, 0xa005, 0x1904, 0x1f4c, 0x00c6, 0x7206, 0xa280, + 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x00d6, + 0x2068, 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, 0x9040, 0x2079, + 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe, 0x00de, + 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, + 0xa0cc, 0x000f, 0x6908, 0x791a, 0x7116, 0x680c, 0x781e, 0x701a, + 0xa006, 0x700e, 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120, + 0x6928, 0x6810, 0xa106, 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10, + 0x080c, 0x21a6, 0x004e, 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff, + 0x1120, 0x00ce, 0xa085, 0x0001, 0x0078, 0x0126, 0x2091, 0x8000, + 0x2079, 0x0020, 0x2009, 0x0001, 0x0059, 0x0118, 0x2009, 0x0001, + 0x0039, 0x012e, 0x00ce, 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, + 0x1fc5, 0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04, + 0x1fc4, 0xa705, 0x0904, 0x1fc4, 0xa03e, 0x2730, 0x6850, 0xd0fc, + 0x11a8, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1fa7, 0x1f8c, + 0x1f8c, 0x1fa7, 0x1fa7, 0x1fa0, 0x1fa7, 0x1f8c, 0x1fa7, 0x1f91, + 0x1f91, 0x1fa7, 0x1fa7, 0x1fa7, 0x1f98, 0x1f91, 0xc0fc, 0x6852, + 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6, 0x2805, + 0xac68, 0x6f08, 0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, + 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0090, + 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138, + 0x00de, 0x080c, 0x2148, 0x1904, 0x1f56, 0xa00e, 0x00f0, 0x00de, + 0x080c, 0x14f6, 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, + 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, + 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, + 0x7012, 0x080c, 0x2148, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e, + 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x14f6, 0x0026, 0x2001, + 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, + 0x0000, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, + 0x0118, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c, 0x20e1, + 0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c, + 0x6d0d, 0x002e, 0x0804, 0x20ad, 0x0126, 0x2091, 0x2400, 0x0006, + 0x0016, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071, + 0xb01e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, + 0x0700, 0x1920, 0x7000, 0x0002, 0x20ad, 0x2010, 0x2080, 0x20ab, + 0x8001, 0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0, 0x2009, 0x0001, + 0x080c, 0x1f50, 0x0904, 0x20ad, 0x2009, 0x0001, 0x080c, 0x1f50, + 0x0804, 0x20ad, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc, + 0x6852, 0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e, 0x00b8, 0x0026, + 0x0036, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872, + 0xa213, 0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a, 0x6a2e, 0x003e, + 0x002e, 0x080c, 0x215e, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, + 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0804, 0x20ad, + 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, + 0x7a14, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x0036, 0x2019, + 0x1000, 0x8319, 0x090c, 0x14f6, 0x7820, 0xd0bc, 0x1dd0, 0x003e, + 0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, + 0xa103, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012, + 0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468, + 0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x2004, + 0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x1f50, + 0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6, + 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, + 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804, + 0x2033, 0x0804, 0x202f, 0x080c, 0x14f6, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, + 0xb01e, 0x7000, 0xa086, 0x0000, 0x0590, 0x2079, 0x0020, 0x0016, + 0x2009, 0x0207, 0x210c, 0xd194, 0x0158, 0x2009, 0x020c, 0x210c, + 0xa184, 0x0003, 0x0128, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102, + 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x1110, + 0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0d18, 0x080c, 0x1ff4, 0x7000, + 0xa086, 0x0000, 0x19e8, 0x001e, 0x7803, 0x0004, 0x7804, 0xd0ac, + 0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee, + 0x00fe, 0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2071, + 0xb01e, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0540, 0x7004, + 0x2060, 0x6010, 0x2068, 0x080c, 0x9596, 0x0158, 0x6850, 0xc0b5, + 0x6852, 0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808, 0x7a18, 0xa206, + 0x01e0, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, + 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x080c, 0x929c, 0x20e1, + 0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x002e, 0x0005, 0x6810, 0x6a14, 0xa205, + 0x1d00, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c, 0x1e6e, 0x2001, + 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, + 0x0000, 0x2069, 0xafc7, 0x6833, 0x0000, 0x683f, 0x0000, 0x08f8, + 0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a, + 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x2186, 0x2045, 0x88ff, + 0x090c, 0x14f6, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841, + 0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005, + 0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, + 0x2196, 0x2045, 0x88ff, 0x090c, 0x14f6, 0x0005, 0x0000, 0x0011, + 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, + 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x217b, + 0x2177, 0x0000, 0x0000, 0x2185, 0x0000, 0x217b, 0x0000, 0x2182, + 0x217f, 0x0000, 0x0000, 0x0000, 0x2185, 0x2182, 0x0000, 0x217d, + 0x217d, 0x0000, 0x0000, 0x2185, 0x0000, 0x217d, 0x0000, 0x2183, + 0x2183, 0x0000, 0x0000, 0x0000, 0x2185, 0x2183, 0x00a6, 0x0096, + 0x0086, 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904, 0x2237, 0x2d60, + 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2186, 0xa986, 0x0007, 0x0130, + 0xa986, 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422, + 0x6060, 0xa31a, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2237, + 0x6004, 0xa065, 0x0904, 0x2237, 0x0c18, 0x2805, 0xa005, 0x01a8, + 0xac68, 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020, + 0x6810, 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150, + 0x8a51, 0x0904, 0x2237, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904, + 0x2237, 0x0830, 0x8a51, 0x0904, 0x2237, 0x8840, 0x2805, 0xa005, + 0x1158, 0x6004, 0xa065, 0x0904, 0x2237, 0x6034, 0xa0cc, 0x000f, + 0xa9c0, 0x2186, 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, + 0x0458, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68, + 0x6c6e, 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122, + 0x690c, 0x2300, 0xa11b, 0x0a0c, 0x14f6, 0x6800, 0xa420, 0x6804, + 0xa319, 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, + 0x0a0c, 0x14f6, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, + 0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, + 0x2a00, 0x6826, 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e, + 0x009e, 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, + 0xa084, 0x0007, 0x0002, 0x224b, 0x224c, 0x224f, 0x2252, 0x2257, + 0x225a, 0x225f, 0x2264, 0x0005, 0x080c, 0x1ff4, 0x0005, 0x080c, + 0x1a6c, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4, 0x0005, 0x080c, + 0x16f8, 0x0005, 0x080c, 0x1ff4, 0x080c, 0x16f8, 0x0005, 0x080c, + 0x1a6c, 0x080c, 0x16f8, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4, + 0x080c, 0x16f8, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, + 0x2071, 0xb280, 0x2069, 0xad00, 0x2009, 0x0004, 0x7912, 0x7817, + 0x0004, 0x080c, 0x2651, 0x781b, 0x0002, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x20a9, 0x0080, 0x782f, 0x0000, 0x1f04, 0x2283, 0x20e1, + 0x9080, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e, 0x0005, 0x0126, + 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2335, 0xa084, 0x0007, + 0x0002, 0x22b3, 0x22a1, 0x22a4, 0x22a7, 0x22ac, 0x22ae, 0x22b0, + 0x22b2, 0x080c, 0x5fb7, 0x0078, 0x080c, 0x5ff0, 0x0060, 0x080c, + 0x5fb7, 0x080c, 0x5ff0, 0x0038, 0x0041, 0x0028, 0x0031, 0x0018, + 0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006, 0x0016, 0x0026, + 0x7930, 0xa184, 0x0003, 0x0118, 0x20e1, 0x9040, 0x04a0, 0xa184, + 0x0030, 0x01e0, 0x6a00, 0xa286, 0x0003, 0x1108, 0x00a0, 0x080c, + 0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, + 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, + 0x0010, 0x080c, 0x485e, 0x20e1, 0x9010, 0x00a8, 0xa184, 0x00c0, + 0x0168, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c, + 0x1d22, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0028, 0xa184, 0x0300, + 0x0110, 0x20e1, 0x9020, 0x7932, 0x002e, 0x001e, 0x000e, 0x0005, + 0x0016, 0x00e6, 0x00f6, 0x2071, 0xad00, 0x7128, 0x2001, 0xaf90, + 0x2102, 0x2001, 0xaf98, 0x2102, 0xa182, 0x0211, 0x1218, 0x2009, + 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, + 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, + 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, + 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, + 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x080c, + 0x2651, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c, 0x14f6, + 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0xad00, 0x6024, + 0x6026, 0x6053, 0x0030, 0x080c, 0x2690, 0x6050, 0xa084, 0xfe7f, + 0x6052, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26a0, 0x60e7, + 0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, + 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0e9f, 0x601b, 0x001e, + 0x600f, 0x00ff, 0x2001, 0xaf8c, 0x2003, 0x00ff, 0x602b, 0x002f, + 0x012e, 0x0005, 0x2001, 0xad31, 0x2003, 0x0000, 0x2001, 0xad30, + 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, + 0x0026, 0x6124, 0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a, + 0xa195, 0x0004, 0xa284, 0x0007, 0x0002, 0x23a7, 0x238d, 0x2390, + 0x2393, 0x2398, 0x239a, 0x239e, 0x23a2, 0x080c, 0x6699, 0x00b8, + 0x080c, 0x6774, 0x00a0, 0x080c, 0x6774, 0x080c, 0x6699, 0x0078, + 0x0099, 0x0068, 0x080c, 0x6699, 0x0079, 0x0048, 0x080c, 0x6774, + 0x0059, 0x0028, 0x080c, 0x6774, 0x080c, 0x6699, 0x0029, 0x002e, + 0x001e, 0x000e, 0x012e, 0x0005, 0x6124, 0xd19c, 0x1904, 0x25bf, + 0x080c, 0x574f, 0x0578, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024, + 0xa084, 0x1800, 0x0178, 0x080c, 0x5775, 0x0118, 0x080c, 0x5761, + 0x1148, 0x6027, 0x0020, 0x6043, 0x0000, 0x2001, 0xaf9d, 0x2003, + 0xaaaa, 0x0458, 0x080c, 0x5775, 0x15d0, 0x6024, 0xa084, 0x1800, + 0x1108, 0x04a8, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, + 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a, + 0x0804, 0x25bf, 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170, 0xd0e4, + 0x1188, 0xd0d4, 0x11a0, 0xd0cc, 0x0130, 0x7088, 0xa086, 0x0028, + 0x1110, 0x080c, 0x58da, 0x0804, 0x25bf, 0x2001, 0xaf9e, 0x2003, + 0x0000, 0x0048, 0x2001, 0xaf9e, 0x2003, 0x0002, 0x0020, 0x080c, + 0x584d, 0x0804, 0x25bf, 0x080c, 0x597a, 0x0804, 0x25bf, 0xd1ac, + 0x0904, 0x2507, 0x080c, 0x574f, 0x11d8, 0x6027, 0x0020, 0x0006, + 0x0026, 0x0036, 0x080c, 0x576b, 0x1170, 0x2001, 0xaf9e, 0x2003, + 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a, 0x003e, + 0x002e, 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x5726, + 0x0016, 0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061, + 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74ca, 0xa48c, + 0xff00, 0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x7038, + 0xd084, 0x1148, 0xc085, 0x703a, 0x0036, 0x2418, 0x2011, 0x8016, + 0x080c, 0x3c5c, 0x003e, 0xa196, 0xff00, 0x05b8, 0x7050, 0xa084, + 0x00ff, 0x810f, 0xa116, 0x0588, 0x7130, 0xd184, 0x1570, 0x2011, + 0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, 0xad52, + 0x2214, 0xd2ac, 0x1510, 0x6240, 0xa294, 0x0010, 0x0130, 0x6248, + 0xa294, 0xff00, 0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, + 0x24d2, 0x7034, 0xd08c, 0x1140, 0x2001, 0xad0c, 0x200c, 0xd1ac, + 0x1904, 0x24d2, 0xc1ad, 0x2102, 0x0036, 0x73c8, 0x2011, 0x8013, + 0x080c, 0x3c5c, 0x003e, 0x0804, 0x24d2, 0x7034, 0xd08c, 0x1140, + 0x2001, 0xad0c, 0x200c, 0xd1ac, 0x1904, 0x24d2, 0xc1ad, 0x2102, + 0x0036, 0x73c8, 0x2011, 0x8013, 0x080c, 0x3c5c, 0x003e, 0x7130, + 0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x01d0, 0x0016, + 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019, 0x000e, + 0x080c, 0xa8eb, 0xa484, 0x00ff, 0xa080, 0x2be6, 0x200d, 0xa18c, + 0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0xa96c, + 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, + 0x080c, 0x2aac, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, + 0x0000, 0x080c, 0x4cdc, 0x1110, 0x080c, 0x493a, 0x8108, 0x1f04, + 0x24c9, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, 0x7adf, + 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, + 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3, 0x0000, + 0x001e, 0x2001, 0xad00, 0x2014, 0xa296, 0x0004, 0x1128, 0xd19c, + 0x1118, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xad22, + 0x2003, 0x0000, 0x6027, 0x0020, 0x080c, 0x5775, 0x1140, 0x0016, + 0x2009, 0x07d0, 0x2011, 0x567b, 0x080c, 0x6593, 0x001e, 0xd194, + 0x0904, 0x25bf, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2570, 0x080c, + 0x6581, 0x080c, 0x7834, 0x6027, 0x0004, 0x00f6, 0x2019, 0xafd0, + 0x2304, 0xa07d, 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6, + 0x00c6, 0x00e6, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e, + 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, + 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a, + 0x080c, 0x6b73, 0x080c, 0x6c50, 0x7810, 0x2070, 0x7037, 0x0103, + 0x2f60, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, + 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, + 0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, + 0xafc7, 0x6028, 0xa09a, 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce, + 0x080c, 0x7827, 0x0804, 0x25be, 0x2019, 0xafd0, 0x2304, 0xa065, + 0x0120, 0x2009, 0x0027, 0x080c, 0x80a7, 0x00ce, 0x0804, 0x25be, + 0xd2bc, 0x0904, 0x25be, 0x080c, 0x658e, 0x6014, 0xa084, 0x0184, + 0xa085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, + 0x6804, 0xa084, 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, 0x0000, + 0x00de, 0x00c6, 0x2061, 0xafc7, 0x6044, 0xa09a, 0x00c8, 0x12f0, + 0x8000, 0x6046, 0x603c, 0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0, + 0x080c, 0x6586, 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x1138, + 0x6114, 0xa18c, 0x0184, 0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114, + 0xa18c, 0x0184, 0xa18d, 0x0016, 0x6116, 0x0080, 0x0036, 0x2019, + 0x0001, 0x080c, 0x7a64, 0x003e, 0x2019, 0xafd6, 0x2304, 0xa065, + 0x0120, 0x2009, 0x004f, 0x080c, 0x80a7, 0x00ce, 0x001e, 0xd19c, + 0x0904, 0x261a, 0x7034, 0xd0ac, 0x1560, 0x0016, 0x0156, 0x6027, + 0x0008, 0x602f, 0x0020, 0x20a9, 0x0006, 0x1d04, 0x25cd, 0x2091, + 0x6000, 0x1f04, 0x25cd, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400, + 0x6052, 0x20a9, 0x0366, 0x1d04, 0x25db, 0x2091, 0x6000, 0x6020, + 0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0490, + 0x080c, 0x2760, 0x1f04, 0x25db, 0x015e, 0x6152, 0x001e, 0x6027, + 0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, + 0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c, + 0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3, + 0x0000, 0x080c, 0xac8d, 0x080c, 0xaca8, 0xa085, 0x0001, 0x080c, + 0x5793, 0x2001, 0xad00, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c, + 0x12cc, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005, 0x0006, 0x0016, + 0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, + 0x71c0, 0x70c2, 0xa116, 0x01f0, 0x81ff, 0x0128, 0x2011, 0x8011, + 0x080c, 0x3c5c, 0x00b8, 0x2011, 0x8012, 0x080c, 0x3c5c, 0x2001, + 0xad71, 0x2004, 0xd0fc, 0x1170, 0x0036, 0x00c6, 0x080c, 0x26eb, + 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0000, 0x080c, 0x2aac, + 0x00ce, 0x003e, 0x012e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, + 0x0005, 0x00c6, 0x00f6, 0x0006, 0x0026, 0x2061, 0x0100, 0xa190, + 0x2664, 0x2205, 0x60f2, 0x2011, 0x2671, 0x2205, 0x60ee, 0x002e, + 0x000e, 0x00fe, 0x00ce, 0x0005, 0x0840, 0x0840, 0x0840, 0x0580, + 0x0420, 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, + 0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, + 0x00ff, 0x2130, 0xa094, 0xff00, 0x1110, 0x81ff, 0x0118, 0x080c, + 0x6278, 0x0038, 0xa080, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f, + 0xa006, 0x0005, 0xa080, 0x2be6, 0x200d, 0xa18c, 0x00ff, 0x0005, + 0x00d6, 0x2069, 0x0140, 0x2001, 0xad14, 0x2003, 0x00ef, 0x20a9, + 0x0010, 0xa006, 0x6852, 0x6856, 0x1f04, 0x269b, 0x00de, 0x0005, + 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0xad14, 0x2102, + 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, + 0xa006, 0x82ff, 0x1128, 0xa184, 0x000f, 0xa080, 0xacae, 0x2005, + 0x6856, 0x8211, 0x1f04, 0x26b0, 0x002e, 0x00de, 0x000e, 0x0005, + 0x00c6, 0x2061, 0xad00, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, + 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, + 0x2069, 0x0140, 0x6980, 0xa116, 0x0180, 0xa112, 0x1230, 0x8212, + 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, + 0x680e, 0x1f04, 0x26e0, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, + 0x00de, 0x015e, 0x0005, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150, + 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, + 0xa96c, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, + 0x78c4, 0xd0dc, 0x0548, 0xa084, 0x0700, 0xa08e, 0x0300, 0x1520, + 0x2011, 0x0000, 0x2009, 0x0002, 0x2300, 0xa080, 0x0020, 0x2018, + 0x2300, 0x080c, 0x6665, 0x2011, 0x0030, 0x2200, 0x8007, 0xa085, + 0x004c, 0x78c2, 0x2009, 0x0204, 0x210c, 0x2200, 0xa100, 0x2009, + 0x0138, 0x200a, 0x080c, 0x574f, 0x1118, 0x2009, 0xaf8e, 0x200a, + 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, + 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, + 0x8000, 0x2014, 0xa184, 0x0003, 0x0110, 0x0804, 0x1a6a, 0x002e, + 0x001e, 0x000e, 0x012e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, + 0xa082, 0x0005, 0x000e, 0x0268, 0x2001, 0x0170, 0x200c, 0xa18c, + 0x00ff, 0xa18e, 0x004c, 0x1128, 0x200c, 0xa18c, 0xff00, 0x810f, + 0x0010, 0x2009, 0x0000, 0x2001, 0x0204, 0x2004, 0xa108, 0x0005, + 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, + 0xd08c, 0x1110, 0x1f04, 0x2767, 0x00fe, 0x015e, 0x000e, 0x0005, + 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x6030, 0x0006, 0x6048, + 0x0006, 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60f0, + 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, + 0x0006, 0x60e0, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xe000, + 0xe000, 0xe000, 0xe000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, + 0x60e2, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, + 0x60ee, 0x000e, 0x60f2, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, + 0x60e6, 0x000e, 0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c, + 0x26a0, 0x000e, 0x00ce, 0x001e, 0x0005, 0x2845, 0x2849, 0x284d, + 0x2853, 0x2859, 0x285f, 0x2865, 0x286d, 0x2875, 0x287b, 0x2881, + 0x2889, 0x2891, 0x2899, 0x28a1, 0x28ab, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b7, 0x28b7, 0x28bc, + 0x28bc, 0x28c3, 0x28c3, 0x28ca, 0x28ca, 0x28d3, 0x28d3, 0x28da, + 0x28da, 0x28e3, 0x28e3, 0x28ec, 0x28ec, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, + 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x0106, 0x0006, 0x0804, + 0x28f7, 0x0106, 0x0006, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, + 0x2373, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x0804, + 0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, + 0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, + 0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, + 0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, + 0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x228f, 0x0804, + 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804, + 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804, + 0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804, + 0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804, + 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x223d, 0x080c, + 0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, + 0x223d, 0x080c, 0x228f, 0x0804, 0x28f7, 0xe000, 0x0cf0, 0x0106, + 0x0006, 0x080c, 0x272f, 0x04d8, 0x0106, 0x0006, 0x080c, 0x272f, + 0x080c, 0x2373, 0x04a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, + 0x223d, 0x0468, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373, + 0x080c, 0x223d, 0x0420, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, + 0x228f, 0x00e8, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373, + 0x080c, 0x228f, 0x00a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, + 0x223d, 0x080c, 0x228f, 0x0058, 0x0106, 0x0006, 0x080c, 0x272f, + 0x080c, 0x2373, 0x080c, 0x223d, 0x080c, 0x228f, 0x0000, 0x000e, + 0x010e, 0x000d, 0x00c6, 0x0026, 0x0046, 0x2021, 0x0000, 0x080c, + 0x502d, 0x1904, 0x29d4, 0x72d0, 0x2001, 0xaf9d, 0x2004, 0xa005, + 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x29d4, + 0x080c, 0x29d8, 0x0804, 0x29d4, 0x080c, 0x574f, 0x1120, 0x709b, + 0xffff, 0x0804, 0x29d4, 0xd294, 0x0120, 0x709b, 0xffff, 0x0804, + 0x29d4, 0x2001, 0xad14, 0x203c, 0x7284, 0xd284, 0x0904, 0x2976, + 0xd28c, 0x1904, 0x2976, 0x0036, 0x7398, 0xa38e, 0xffff, 0x1110, + 0x2019, 0x0001, 0x8314, 0xa2e0, 0xb3c0, 0x2c04, 0xa38c, 0x0001, + 0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e, + 0x0560, 0xa08e, 0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150, 0x7230, + 0xd284, 0x1538, 0x7284, 0xc28d, 0x7286, 0x709b, 0xffff, 0x003e, + 0x0428, 0x2009, 0x0000, 0x080c, 0x2676, 0x080c, 0x4c80, 0x11b8, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1150, 0x7030, 0xd08c, + 0x0118, 0x6000, 0xd0bc, 0x0120, 0x080c, 0x29eb, 0x0140, 0x0028, + 0x080c, 0x2b1a, 0x080c, 0x2a19, 0x0110, 0x8318, 0x0818, 0x739a, + 0x0010, 0x709b, 0xffff, 0x003e, 0x0804, 0x29d4, 0xa780, 0x2be6, + 0x203d, 0xa7bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x7098, 0xa096, + 0xffff, 0x1120, 0x2009, 0x0000, 0x28a8, 0x0050, 0xa812, 0x0220, + 0x2008, 0xa802, 0x20a8, 0x0020, 0x709b, 0xffff, 0x0804, 0x29d4, + 0x2700, 0x0156, 0x0016, 0xa106, 0x05a0, 0xc484, 0x080c, 0x4cdc, + 0x0120, 0x080c, 0x4c80, 0x15a8, 0x0008, 0xc485, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000, + 0xd0bc, 0x11d0, 0x7284, 0xd28c, 0x0188, 0x6004, 0xa084, 0x00ff, + 0xa082, 0x0006, 0x02b0, 0xd484, 0x1118, 0x080c, 0x4c9f, 0x0028, + 0x080c, 0x2b9c, 0x0170, 0x080c, 0x2bc9, 0x0058, 0x080c, 0x2b1a, + 0x080c, 0x2a19, 0x0170, 0x0028, 0x080c, 0x2b9c, 0x0110, 0x0419, + 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2990, 0x709b, 0xffff, + 0x0018, 0x001e, 0x015e, 0x719a, 0x004e, 0x002e, 0x00ce, 0x0005, + 0x00c6, 0x0016, 0x709b, 0x0000, 0x2009, 0x007e, 0x080c, 0x4c80, + 0x1138, 0x080c, 0x2b1a, 0x04a9, 0x0118, 0x70d0, 0xc0bd, 0x70d2, + 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, + 0x2001, 0xad56, 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807, + 0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2001, + 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0000, 0x080c, 0x4c30, 0x0126, + 0x2091, 0x8000, 0x7094, 0x8000, 0x7096, 0x012e, 0x2009, 0x0004, + 0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, + 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xad56, + 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807, 0x0550, 0x2d00, + 0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, 0x0140, + 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1110, 0x080c, 0x2ad9, + 0x080c, 0x9956, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, + 0x2001, 0x0002, 0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x7094, + 0x8000, 0x7096, 0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085, + 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026, + 0x2009, 0x0080, 0x080c, 0x4c80, 0x1120, 0x0031, 0x0110, 0x70d7, + 0xffff, 0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, + 0x2c68, 0x080c, 0x8022, 0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956, + 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, + 0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x70d8, 0x8000, 0x70da, + 0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce, + 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2009, 0x007f, 0x080c, 0x4c80, 0x1190, 0x2c68, 0x080c, + 0x8022, 0x0170, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a, + 0x080c, 0x9956, 0x2009, 0x0022, 0x080c, 0x80a7, 0xa085, 0x0001, + 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, + 0x0026, 0x080c, 0x68f3, 0x080c, 0x689d, 0x080c, 0x8a15, 0x2130, + 0x81ff, 0x0128, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0020, 0x20a9, + 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1120, 0x080c, + 0x4ecf, 0x080c, 0x493a, 0x001e, 0x8108, 0x1f04, 0x2ac3, 0x86ff, + 0x1110, 0x080c, 0x11d4, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, + 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, 0x2270, + 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039, + 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x001e, + 0x2e60, 0x080c, 0x4ecf, 0x6210, 0x6314, 0x080c, 0x493a, 0x6212, + 0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, + 0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x0080, 0x0150, + 0x2071, 0xad00, 0x7094, 0xa005, 0x0110, 0x8001, 0x7096, 0x000e, + 0x00ee, 0x0005, 0x2071, 0xad00, 0x70d8, 0xa005, 0x0dc0, 0x8001, + 0x70da, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6, + 0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118, + 0x20a9, 0x0001, 0x0098, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150, + 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c, + 0xa96c, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x0026, 0xa28e, + 0x007e, 0x05c8, 0xa28e, 0x007f, 0x05b0, 0xa28e, 0x0080, 0x0598, + 0xa288, 0xae34, 0x210c, 0x81ff, 0x0570, 0x8fff, 0x05c1, 0x00c6, + 0x2160, 0x2001, 0x0001, 0x080c, 0x5037, 0x00ce, 0x2019, 0x0029, + 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x00c6, + 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x1118, + 0x6007, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, + 0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c, 0xa712, 0x001e, 0x007e, + 0x2160, 0x080c, 0x4ecf, 0x002e, 0x8210, 0x1f04, 0x2b3e, 0x015e, + 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, + 0x0026, 0x0016, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0148, 0xd0a4, + 0x0138, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x080c, 0xa96c, + 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x7284, 0x82ff, 0x01f8, 0x2011, 0xad52, 0x2214, 0xd2ac, 0x11d0, + 0x2100, 0x080c, 0x268a, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, + 0xa2e0, 0xb3c0, 0x2c04, 0xd384, 0x0120, 0xa084, 0xff00, 0x8007, + 0x0010, 0xa084, 0x00ff, 0xa116, 0x0138, 0xa096, 0x00ff, 0x0110, + 0x8318, 0x0c68, 0xa085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0xa180, 0xae34, + 0x2004, 0xa065, 0x0178, 0x0016, 0x00c6, 0x080c, 0x9807, 0x001e, + 0x090c, 0x14f6, 0x611a, 0x080c, 0x2ad9, 0x080c, 0x8078, 0x001e, + 0x080c, 0x4c9f, 0x012e, 0x00ce, 0x001e, 0x0005, 0x7eef, 0x7de8, + 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, + 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, + 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, + 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, + 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, + 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, + 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, + 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, + 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, + 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, + 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, + 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, + 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, + 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, + 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, + 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, + 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, + 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, + 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, + 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, + 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, + 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, + 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, + 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, + 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, + 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0xad81, + 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e, 0x7033, + 0xad91, 0x7037, 0xad91, 0x7007, 0x0001, 0x2061, 0xadd1, 0x6003, + 0x0002, 0x0005, 0x1004, 0x2d0c, 0x0e04, 0x2d0c, 0x2071, 0xad81, + 0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60, 0x7820, 0xa08e, 0x0069, + 0x1904, 0x2df1, 0x0804, 0x2d8a, 0x0005, 0x2071, 0xad81, 0x7004, + 0x0002, 0x2d15, 0x2d16, 0x2d1f, 0x2d30, 0x0005, 0x1004, 0x2d1e, + 0x0e04, 0x2d1e, 0x2b78, 0x7818, 0xd084, 0x01e8, 0x0005, 0x2b78, + 0x2061, 0xadd1, 0x6008, 0xa08e, 0x0100, 0x0128, 0xa086, 0x0200, + 0x0904, 0x2deb, 0x0005, 0x7014, 0x2068, 0x2a60, 0x7018, 0x0807, + 0x7010, 0x2068, 0x6834, 0xa086, 0x0103, 0x0108, 0x0005, 0x2a60, + 0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x1210, + 0x61c0, 0x0042, 0x2100, 0xa08a, 0x003f, 0x1a04, 0x2de8, 0x61c0, + 0x0804, 0x2d8a, 0x2dcc, 0x2df7, 0x2dff, 0x2e03, 0x2e0b, 0x2e11, + 0x2e15, 0x2e21, 0x2e24, 0x2e2e, 0x2e31, 0x2de8, 0x2de8, 0x2de8, + 0x2e34, 0x2de8, 0x2e43, 0x2e5a, 0x2e71, 0x2ee8, 0x2eed, 0x2f16, + 0x2f67, 0x2f78, 0x2f96, 0x2fcd, 0x2fd7, 0x2fe4, 0x2ff7, 0x3018, + 0x3021, 0x3057, 0x305d, 0x2de8, 0x3086, 0x2de8, 0x2de8, 0x2de8, + 0x2de8, 0x2de8, 0x308d, 0x3097, 0x2de8, 0x2de8, 0x2de8, 0x2de8, + 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x309f, 0x2de8, 0x2de8, 0x2de8, + 0x2de8, 0x2de8, 0x30b1, 0x30b9, 0x2de8, 0x2de8, 0x2de8, 0x2de8, + 0x2de8, 0x2de8, 0x0002, 0x30cb, 0x311f, 0x317a, 0x318a, 0x2de8, + 0x31a4, 0x35cb, 0x3fbb, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x2de8, + 0x2de8, 0x2de8, 0x2de8, 0x2e2e, 0x2e31, 0x35cd, 0x2de8, 0x35da, + 0x403c, 0x4097, 0x40fb, 0x2de8, 0x415a, 0x4180, 0x419f, 0x2de8, + 0x2de8, 0x2de8, 0x2de8, 0x35de, 0x376b, 0x3785, 0x37a3, 0x3804, + 0x3858, 0x3863, 0x389a, 0x38a9, 0x38b8, 0x38bb, 0x38de, 0x3928, + 0x398e, 0x399b, 0x3a9c, 0x3bb3, 0x3bdc, 0x3cda, 0x3cfc, 0x3d08, + 0x3d41, 0x3e05, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x3e6d, 0x3e88, + 0x3efa, 0x3fac, 0x713c, 0x0000, 0x2021, 0x4000, 0x080c, 0x3c39, + 0x0126, 0x2091, 0x8000, 0x0e04, 0x2dd8, 0x7818, 0xd084, 0x0110, + 0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001, + 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, 0x012e, 0x0005, + 0x2021, 0x4001, 0x0c18, 0x2021, 0x4002, 0x0c00, 0x2021, 0x4003, + 0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021, 0x4006, 0x08b8, 0xa02e, + 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3c46, 0x7823, + 0x0004, 0x7824, 0x0807, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, + 0x7930, 0x0804, 0x3c49, 0x7924, 0x7828, 0x2114, 0x200a, 0x0804, + 0x2dcc, 0x7924, 0x2114, 0x0804, 0x2dcc, 0x2099, 0x0009, 0x20a1, + 0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0804, + 0x2dcc, 0x7824, 0x2060, 0x0090, 0x2009, 0x0002, 0x2011, 0x0001, + 0x2019, 0x001b, 0x783b, 0x0017, 0x0804, 0x2dcc, 0x7d38, 0x7c3c, + 0x0840, 0x7d38, 0x7c3c, 0x0888, 0x2061, 0x1000, 0xe10c, 0xa006, + 0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0xa005, 0x0904, + 0x2dcc, 0x0804, 0x2dee, 0x2069, 0xad51, 0x7824, 0x7930, 0xa11a, + 0x1a04, 0x2df4, 0x8019, 0x0904, 0x2df4, 0x684a, 0x6942, 0x782c, + 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x080c, 0x5a1c, + 0x0804, 0x2dcc, 0x2069, 0xad51, 0x7824, 0x7934, 0xa11a, 0x1a04, + 0x2df4, 0x8019, 0x0904, 0x2df4, 0x684e, 0x6946, 0x782c, 0x6862, + 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x080c, 0x50d9, 0x0804, + 0x2dcc, 0xa02e, 0x2520, 0x81ff, 0x1904, 0x2df1, 0x7924, 0x7b28, + 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xad88, 0x41a1, 0x080c, 0x3c05, + 0x0904, 0x2df1, 0x2009, 0x0020, 0x080c, 0x3c46, 0x701b, 0x2e89, + 0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0120, + 0xa096, 0x0019, 0x1904, 0x2df1, 0x810f, 0xa18c, 0x00ff, 0x0904, + 0x2df1, 0x710e, 0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3c05, + 0x0904, 0x2df1, 0x2009, 0x0020, 0x2061, 0xadd1, 0x6224, 0x6328, + 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, + 0xa5a9, 0x0000, 0x080c, 0x3c46, 0x701b, 0x2eb7, 0x0005, 0x6834, + 0xa084, 0x00ff, 0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904, + 0x2df1, 0x08c0, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c, + 0x4b7c, 0x1128, 0x7007, 0x0003, 0x701b, 0x2ed1, 0x0005, 0x080c, + 0x51df, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xad88, + 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, + 0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x012e, 0x0804, 0x3c49, + 0x61a8, 0x7824, 0x60aa, 0x0804, 0x2dcc, 0x2091, 0x8000, 0x7823, + 0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009, + 0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, + 0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, + 0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, + 0x2071, 0x0010, 0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904, + 0x2df1, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x1904, + 0x2df4, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804, + 0x2df4, 0x7c28, 0x7d2c, 0x080c, 0x4e96, 0xd28c, 0x1118, 0x080c, + 0x4e41, 0x0010, 0x080c, 0x4e6f, 0x1518, 0x2061, 0xb400, 0x0126, + 0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d, + 0x0130, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e, + 0xace0, 0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1a04, 0x2df1, + 0x0c30, 0x080c, 0x929c, 0x012e, 0x0904, 0x2df1, 0x0804, 0x2dcc, + 0xa00e, 0x2001, 0x0005, 0x080c, 0x51df, 0x0126, 0x2091, 0x8000, + 0x080c, 0x9803, 0x080c, 0x510c, 0x012e, 0x0804, 0x2dcc, 0x81ff, + 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, + 0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0904, 0x2df1, 0x0804, 0x2dcc, + 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c, + 0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0005, 0x080c, 0x4ebd, 0x0904, + 0x2df1, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x8003, 0x800b, + 0x810b, 0xa108, 0x080c, 0x6519, 0x0804, 0x2dcc, 0x0126, 0x2091, + 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0448, 0x2029, 0x00ff, + 0x644c, 0x2400, 0xa506, 0x01f0, 0x2508, 0x080c, 0x4cdc, 0x11d0, + 0x080c, 0x4f0d, 0x1128, 0x2009, 0x0002, 0x62b0, 0x2518, 0x00b8, + 0x2019, 0x0004, 0x080c, 0x4ebd, 0x1118, 0x2009, 0x0006, 0x0078, + 0x7824, 0xa08a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0xa108, + 0x080c, 0x6519, 0x8529, 0x1ae8, 0x012e, 0x0804, 0x2dcc, 0x012e, + 0x0804, 0x2df1, 0x012e, 0x0804, 0x2df4, 0x080c, 0x3c1a, 0x0904, + 0x2df4, 0x080c, 0x4dfc, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff, + 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4ded, + 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, + 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e71, 0x0904, 0x2df1, 0x080c, + 0x4bc0, 0x080c, 0x4e3a, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x080c, + 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x62a0, + 0x2019, 0x0005, 0x00c6, 0x080c, 0x4ecf, 0x2061, 0x0000, 0x080c, + 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2009, 0x0000, + 0x080c, 0xa712, 0x007e, 0x00ce, 0x080c, 0x4e96, 0x0804, 0x2dcc, + 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e96, 0x2208, 0x0804, + 0x2dcc, 0x0156, 0x00d6, 0x00e6, 0x2069, 0xae13, 0x6810, 0x6914, + 0xa10a, 0x1210, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, + 0x0000, 0x20a9, 0x007e, 0x2069, 0xae34, 0x2d04, 0xa075, 0x0130, + 0x704c, 0x0071, 0xa210, 0x7080, 0x0059, 0xa318, 0x8d68, 0x1f04, + 0x3035, 0x2300, 0xa218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x2dcc, + 0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001, 0x0000, 0x8000, 0x2f0c, + 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, + 0xae13, 0x6910, 0x62ac, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, + 0x614c, 0xa190, 0x2be6, 0x2215, 0xa294, 0x00ff, 0x636c, 0x83ff, + 0x0108, 0x6270, 0x67d0, 0xd79c, 0x0118, 0x2031, 0x0001, 0x0090, + 0xd7ac, 0x0118, 0x2031, 0x0003, 0x0068, 0xd7a4, 0x0118, 0x2031, + 0x0002, 0x0040, 0x080c, 0x574f, 0x1118, 0x2031, 0x0004, 0x0010, + 0x2031, 0x0000, 0x7e3a, 0x7f3e, 0x0804, 0x2dcc, 0x613c, 0x6240, + 0x2019, 0xafa3, 0x231c, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000, + 0x6134, 0xa006, 0x2010, 0x2018, 0x012e, 0x0804, 0x2dcc, 0x080c, + 0x3c2a, 0x0904, 0x2df4, 0x6244, 0x6338, 0x0804, 0x2dcc, 0x613c, + 0x6240, 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xad51, 0x831f, + 0xa305, 0x6816, 0x782c, 0x2069, 0xafa3, 0x2d1c, 0x206a, 0x0804, + 0x2dcc, 0x0126, 0x2091, 0x8000, 0x7824, 0x6036, 0x012e, 0x0804, + 0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x7828, 0xa00d, 0x0904, + 0x2df4, 0x782c, 0xa005, 0x0904, 0x2df4, 0x6244, 0x6146, 0x6338, + 0x603a, 0x0804, 0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, + 0x1904, 0x2df1, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, + 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xad14, 0x2004, 0xa085, + 0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188, 0x2be6, 0x210d, + 0xa18c, 0x00ff, 0x2001, 0xad14, 0x2004, 0xa116, 0x0550, 0x810f, + 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x8022, 0x000e, + 0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x080c, 0x3c05, + 0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x701b, 0x3173, 0x2d00, 0x6012, 0x2009, 0x0032, + 0x080c, 0x80a7, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, + 0x2df1, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x8078, 0x0cb0, 0x2001, + 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00c6, 0x2061, + 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130, + 0x2001, 0xad14, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f, + 0x16a0, 0xa188, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x2001, 0xad14, + 0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000, + 0x0006, 0x080c, 0x8022, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc05, + 0x601f, 0x0001, 0x080c, 0x3c05, 0x01d8, 0x6837, 0x0000, 0x7007, + 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x3173, + 0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x80a7, 0x012e, 0x00ce, + 0x0005, 0x012e, 0x00ce, 0x0804, 0x2df1, 0x00ce, 0x0804, 0x2df4, + 0x080c, 0x8078, 0x0cb0, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, + 0x0804, 0x2dcc, 0x2061, 0xb048, 0x0126, 0x2091, 0x8000, 0x6000, + 0xd084, 0x0128, 0x6104, 0x6208, 0x012e, 0x0804, 0x2dcc, 0x012e, + 0x0804, 0x2df4, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0904, + 0x2df1, 0x0126, 0x2091, 0x8000, 0x6244, 0x6064, 0xa202, 0x0248, + 0xa085, 0x0001, 0x080c, 0x26c0, 0x080c, 0x436e, 0x012e, 0x0804, + 0x2dcc, 0x012e, 0x0804, 0x2df4, 0x0126, 0x2091, 0x8000, 0x7824, + 0xa084, 0x0007, 0x0002, 0x31b6, 0x31bf, 0x31c6, 0x31b3, 0x31b3, + 0x31b3, 0x31b3, 0x31b3, 0x012e, 0x0804, 0x2df4, 0x2009, 0x0114, + 0x2104, 0xa085, 0x0800, 0x200a, 0x080c, 0x332f, 0x0070, 0x2009, + 0x010b, 0x200b, 0x0010, 0x080c, 0x332f, 0x0038, 0x81ff, 0x0128, + 0x012e, 0x2021, 0x400b, 0x0804, 0x2dce, 0x0086, 0x0096, 0x00a6, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2009, 0x0101, 0x210c, + 0x0016, 0x2001, 0x0138, 0x200c, 0x2003, 0x0001, 0x0016, 0x2001, + 0x007a, 0x2034, 0x2001, 0x007b, 0x202c, 0xa006, 0x2048, 0x2050, + 0x2058, 0x080c, 0x3570, 0x080c, 0x34da, 0xa03e, 0x2720, 0x00f6, + 0x00e6, 0x00c6, 0x2d60, 0x2071, 0xb01e, 0x2079, 0x0020, 0x00d6, + 0x2069, 0x0000, 0x6824, 0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004, + 0x783e, 0x2001, 0x007c, 0x2004, 0x783a, 0x00de, 0x2011, 0x0001, + 0x080c, 0x3486, 0x080c, 0x3486, 0x00ce, 0x00ee, 0x00fe, 0x080c, + 0x33d5, 0x080c, 0x34ae, 0x080c, 0x342b, 0x080c, 0x3394, 0x080c, + 0x33c5, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd094, 0x0530, 0x7814, + 0xa084, 0x0184, 0xa085, 0x0010, 0x7816, 0x2079, 0x0140, 0x080c, + 0x330d, 0x1110, 0x00fe, 0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079, + 0x0100, 0x7827, 0x0086, 0x7814, 0xa084, 0x0184, 0xa085, 0x0032, + 0x7816, 0x080c, 0x330d, 0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc, + 0x0dc0, 0x7827, 0x0080, 0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130, + 0x8b58, 0x080c, 0x3317, 0x00fe, 0x0804, 0x32d7, 0x00fe, 0x080c, + 0x330d, 0x1150, 0x8948, 0x2001, 0x007a, 0x2602, 0x2001, 0x007b, + 0x2502, 0x080c, 0x3317, 0x0088, 0x87ff, 0x0140, 0x2001, 0x0201, + 0x2004, 0xa005, 0x1904, 0x3211, 0x8739, 0x0038, 0x2001, 0xaffd, + 0x2004, 0xa086, 0x0000, 0x1904, 0x3211, 0x2001, 0x0033, 0x2003, + 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0xa605, 0x0904, 0x32d7, + 0x7824, 0xd0bc, 0x0128, 0x2900, 0xaa05, 0xab05, 0x1904, 0x32d7, + 0x6033, 0x000d, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac, + 0x1148, 0x2001, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003, + 0x0009, 0x0040, 0x6027, 0x0001, 0x2001, 0x0075, 0x2004, 0xa005, + 0x0108, 0x6026, 0x2c00, 0x601a, 0x20e1, 0x9040, 0x2d00, 0x681a, + 0x6833, 0x000d, 0x7824, 0xd0a4, 0x1180, 0x6827, 0x0000, 0x00c6, + 0x20a9, 0x0004, 0x2061, 0x0020, 0x6003, 0x0008, 0x2001, 0x0203, + 0x2004, 0x1f04, 0x32ac, 0x00ce, 0x0040, 0x6827, 0x0001, 0x2001, + 0x0074, 0x2004, 0xa005, 0x0108, 0x6826, 0x00f6, 0x00c6, 0x2079, + 0x0100, 0x2061, 0x0020, 0x7827, 0x0002, 0x2001, 0x0072, 0x2004, + 0xa084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x0073, 0x2004, 0x601e, + 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x31ef, 0x2061, + 0x0100, 0x6027, 0x0002, 0x001e, 0x61e2, 0x001e, 0x6106, 0x7824, + 0xa084, 0x0003, 0xa086, 0x0002, 0x0188, 0x20e1, 0x9028, 0x6050, + 0xa084, 0xf7ef, 0x6052, 0x602f, 0x0000, 0x602c, 0xc0ac, 0x602e, + 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x2908, 0x2a10, + 0x2b18, 0x2b00, 0xaa05, 0xa905, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x2dcc, + 0x012e, 0x2021, 0x400c, 0x0804, 0x2dce, 0xa085, 0x0001, 0x1d04, + 0x3316, 0x2091, 0x6000, 0x8420, 0xa486, 0x0064, 0x0005, 0x2001, + 0x0105, 0x2003, 0x0010, 0x2001, 0x0030, 0x2003, 0x0004, 0x2001, + 0x0020, 0x2003, 0x0004, 0x2001, 0xaffd, 0x2003, 0x0000, 0x2001, + 0xb01e, 0x2003, 0x0000, 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6, + 0x2079, 0x0100, 0x2001, 0xad14, 0x200c, 0x7932, 0x7936, 0x080c, + 0x26a0, 0x7850, 0xa084, 0x0980, 0xa085, 0x0030, 0x7852, 0x2019, + 0x01f4, 0x8319, 0x1df0, 0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad, + 0x782e, 0x20a9, 0x0046, 0x1d04, 0x334b, 0x2091, 0x6000, 0x1f04, + 0x334b, 0x7850, 0xa085, 0x0400, 0x7852, 0x2001, 0x0009, 0x2004, + 0xa084, 0x0003, 0xa086, 0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e, + 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e, + 0xe000, 0x1f04, 0x3368, 0x7850, 0xa085, 0x1400, 0x7852, 0x2019, + 0x61a8, 0x7854, 0xe000, 0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8, + 0x7827, 0x0048, 0x7850, 0xa085, 0x0400, 0x7852, 0x7843, 0x0040, + 0x2019, 0x01f4, 0xe000, 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140, + 0x2003, 0x0100, 0x7827, 0x0020, 0x7843, 0x0000, 0x2003, 0x0000, + 0x7827, 0x0048, 0x00fe, 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6, + 0x00e6, 0x2071, 0xaffd, 0x2079, 0x0030, 0x2001, 0x0201, 0x2004, + 0xa005, 0x0160, 0x7000, 0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc, + 0x0108, 0x8738, 0x7003, 0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe, + 0x0005, 0x780c, 0xa08c, 0x0070, 0x0178, 0x2009, 0x007a, 0x260a, + 0x2009, 0x007b, 0x250a, 0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108, + 0x8948, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, + 0x781c, 0xd084, 0x0140, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, + 0x020a, 0x2004, 0x0ca8, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, + 0x2009, 0xad14, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, + 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0xa080, + 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0xa006, + 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, + 0x7027, 0x0080, 0x7014, 0xa084, 0x0184, 0xa085, 0x0032, 0x7016, + 0x080c, 0x34ae, 0x080c, 0x330d, 0x1110, 0x8421, 0x0028, 0x7024, + 0xd0bc, 0x0db0, 0x7027, 0x0080, 0x00f6, 0x00e6, 0x2071, 0xaffd, + 0x2079, 0x0030, 0x00d6, 0x2069, 0x0000, 0x6824, 0xd0b4, 0x0120, + 0x683c, 0x783e, 0x6838, 0x783a, 0x00de, 0x2011, 0x0011, 0x080c, + 0x3486, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ee, 0x00fe, 0x7017, + 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xaffd, 0x2079, + 0x0030, 0x7904, 0xd1fc, 0x0904, 0x3483, 0x7803, 0x0002, 0xa026, + 0xd19c, 0x1904, 0x347f, 0x7000, 0x0002, 0x3483, 0x3441, 0x3465, + 0x347f, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002, 0x2011, + 0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000, 0x7820, + 0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201, 0x200c, + 0x81ff, 0x0de8, 0x080c, 0x33b1, 0x2009, 0x0001, 0x7808, 0xd0ec, + 0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002, 0xa184, + 0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001, 0x00b1, + 0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120, 0x6000, + 0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870, 0x7803, + 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024, 0xa005, + 0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804, 0x7832, + 0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840, 0x2804, + 0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018, 0xa802, + 0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004, 0x601a, + 0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, + 0x00c6, 0x2071, 0xb01e, 0x2079, 0x0020, 0x7904, 0xd1fc, 0x01f0, + 0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x34d6, 0x34c1, + 0x34cd, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, 0x080c, + 0x3486, 0x0160, 0x080c, 0x3486, 0x0048, 0x8001, 0x7002, 0x7804, + 0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x601b, + 0x0004, 0x2061, 0x0100, 0x60cf, 0x0400, 0x6004, 0xc0ac, 0xa085, + 0x0200, 0x6006, 0x2001, 0x0074, 0x2004, 0xa005, 0x01f8, 0x2038, + 0x2001, 0x0076, 0x2024, 0x2001, 0x0077, 0x201c, 0x080c, 0x3c05, + 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, + 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, + 0x000d, 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088, 0x080c, 0x3c05, + 0x6833, 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00, 0x681a, 0x2001, + 0x0076, 0x2004, 0x2072, 0x2001, 0x0077, 0x2004, 0x7006, 0x2061, + 0x0020, 0x2079, 0x0100, 0x6013, 0x0400, 0x20e1, 0x9040, 0x2001, + 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001, + 0x0073, 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006, + 0x603a, 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, + 0x0010, 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336, + 0xa006, 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122, + 0x7003, 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003, + 0x0040, 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6, + 0x2d60, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x6018, 0x2070, 0x2d00, + 0x7006, 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005, + 0x00e6, 0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001, + 0x0078, 0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3c05, 0x2d60, + 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, + 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, + 0x000d, 0x080c, 0x353e, 0x1d88, 0x2d00, 0x681a, 0x00e0, 0x080c, + 0x3c05, 0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00, + 0x601a, 0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004, + 0x7006, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001, + 0x0073, 0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, + 0xd0ac, 0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027, + 0x0000, 0x2001, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003, + 0x0009, 0x00ee, 0x0005, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000, + 0x20a9, 0x0011, 0x2001, 0xad40, 0x20a0, 0xa006, 0x40a4, 0x012e, + 0x0804, 0x2dcc, 0x7d38, 0x7c3c, 0x0804, 0x2e73, 0x080c, 0x3c05, + 0x0904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c, 0x491f, 0x2009, + 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b, + 0x35f2, 0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x2df4, + 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x2df4, 0xd094, 0x00c6, + 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218, + 0xa18c, 0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c, + 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010, + 0xa18c, 0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a, + 0x0002, 0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04, + 0x2df4, 0xa288, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x6156, 0xd0dc, + 0x0130, 0x6828, 0xa08a, 0x007f, 0x1a04, 0x2df4, 0x604e, 0x6808, + 0xa08a, 0x0100, 0x0a04, 0x2df4, 0xa08a, 0x0841, 0x1a04, 0x2df4, + 0xa084, 0x0007, 0x1904, 0x2df4, 0x680c, 0xa005, 0x0904, 0x2df4, + 0x6810, 0xa005, 0x0904, 0x2df4, 0x6848, 0x6940, 0xa10a, 0x1a04, + 0x2df4, 0x8001, 0x0904, 0x2df4, 0x684c, 0x6944, 0xa10a, 0x1a04, + 0x2df4, 0x8001, 0x0904, 0x2df4, 0x6804, 0xd0fc, 0x0560, 0x080c, + 0x3c05, 0x0904, 0x2df1, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, + 0x7d38, 0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3c46, 0x701b, + 0x3672, 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, + 0xad6d, 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xad71, + 0x200c, 0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0xa085, + 0x0b00, 0x6006, 0x00ce, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xad51, + 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, + 0x00ff, 0x6042, 0x080c, 0x5a1c, 0x080c, 0x5070, 0x080c, 0x50d9, + 0x6000, 0xa086, 0x0000, 0x1904, 0x3755, 0x6808, 0x602a, 0x080c, + 0x22f8, 0x0006, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e, + 0x0268, 0x2009, 0x0170, 0x200b, 0x0080, 0xe000, 0xe000, 0x200b, + 0x0000, 0x0036, 0x6b08, 0x080c, 0x26fb, 0x003e, 0x6818, 0x691c, + 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, + 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, + 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0xa084, 0xf0ff, + 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, + 0x20a9, 0x0004, 0x20a1, 0xafad, 0x40a1, 0x080c, 0x659c, 0x6904, + 0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000, 0x20a9, 0x0001, 0x6b70, + 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, + 0x5fa9, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, 0x8007, + 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, + 0x0010, 0x6003, 0x0001, 0x1f04, 0x36f3, 0x00ce, 0x2069, 0xad51, + 0x2001, 0xaf9d, 0x6a80, 0xa294, 0x0030, 0xa28e, 0x0000, 0x0170, + 0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020, 0x0140, 0x2003, 0xaaaa, + 0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x0008, 0x2102, 0x00c6, + 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, + 0x574f, 0x0128, 0x080c, 0x3e5f, 0x0110, 0x080c, 0x26c0, 0x60c4, + 0xa005, 0x01b0, 0x6003, 0x0001, 0x2009, 0x373f, 0x00c0, 0x080c, + 0x574f, 0x1158, 0x2011, 0x566e, 0x080c, 0x650d, 0x2001, 0xaf9e, + 0x2003, 0x0000, 0x080c, 0x569a, 0x0040, 0x080c, 0x485e, 0x0028, + 0x6003, 0x0004, 0x2009, 0x3755, 0x0010, 0x0804, 0x2dcc, 0x2001, + 0x0100, 0x2004, 0xa082, 0x0005, 0x0258, 0x2001, 0x0170, 0x2004, + 0xa084, 0x00ff, 0xa086, 0x004c, 0x1118, 0x2091, 0x309d, 0x0817, + 0x2091, 0x301d, 0x0817, 0x6000, 0xa086, 0x0000, 0x0904, 0x2df1, + 0x2069, 0xad51, 0x7830, 0x6842, 0x7834, 0x6846, 0x6804, 0xd0fc, + 0x0118, 0x2009, 0x0030, 0x0010, 0x2009, 0x001c, 0x2d00, 0x7a2c, + 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0xa006, 0x080c, 0x26c0, + 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x1178, 0x2001, 0xaf9e, + 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085, 0x0001, + 0x080c, 0x5793, 0x080c, 0x569a, 0x0020, 0x080c, 0x491f, 0x080c, + 0x485e, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, + 0x1110, 0x0804, 0x2df1, 0x6184, 0x81ff, 0x0198, 0x703f, 0x0000, + 0x2001, 0xb3c0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x0126, 0x2091, 0x8000, 0x080c, 0x3c49, 0x701b, 0x2dca, 0x012e, + 0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, 0xb3c0, 0x20a9, 0x0040, + 0x20a1, 0xb3c0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x2be6, + 0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, + 0xa506, 0x01a8, 0x080c, 0x4cdc, 0x1190, 0x6014, 0x821c, 0x0238, + 0xa398, 0xb3c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0038, 0xa398, + 0xb3c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a, 0x8210, 0x8108, + 0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0xa105, + 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb3c0, + 0x080c, 0x48be, 0x0804, 0x37b0, 0x080c, 0x3c2a, 0x0904, 0x2df4, + 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804, + 0x2df1, 0x2001, 0xad52, 0x2004, 0xd0b4, 0x01f0, 0x6000, 0xd08c, + 0x11d8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x11a8, 0x6837, + 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x970b, 0x1120, 0x2009, + 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3830, 0x0005, + 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x20a9, 0x002b, 0x2c98, 0xade8, + 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, + 0xad80, 0x0006, 0x20a0, 0x080c, 0x48be, 0x20a9, 0x0004, 0xac80, + 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x48be, 0x2d00, + 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, + 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, + 0x4eab, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x7828, 0xa08a, + 0x1000, 0x1a04, 0x2df4, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c, + 0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0004, 0x080c, 0x4ebd, 0x7924, + 0x810f, 0x7a28, 0x0011, 0x0804, 0x2dcc, 0xa186, 0x00ff, 0x0110, + 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0xad00, 0x644c, 0x2400, + 0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, + 0x4cdc, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, + 0x6519, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, + 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4eb4, 0x0804, + 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, + 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0804, 0x2dcc, + 0x6100, 0x0804, 0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x2001, + 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00d6, 0xace8, + 0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007, + 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217, + 0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x2dcc, 0x7824, 0xa09c, + 0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2df1, 0x624c, 0xa294, 0x00ff, + 0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, 0xad40, 0x2009, + 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x81ff, + 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05, + 0x00ce, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, + 0x080c, 0x96b7, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3919, + 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0xad80, 0x000e, + 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, + 0xa006, 0x080c, 0x26c0, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff, + 0x0118, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c, + 0x491f, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x7924, 0xa18c, + 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, 0x007f, 0x1a04, + 0x2df4, 0x2100, 0x080c, 0x268a, 0x0026, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x080c, + 0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, + 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, + 0x00a0, 0x2061, 0x0100, 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, + 0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, + 0x002d, 0x2011, 0x4883, 0x080c, 0x6593, 0x7924, 0xa18c, 0xff00, + 0x810f, 0x080c, 0x574f, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c, + 0x387d, 0x012e, 0x00ce, 0x002e, 0x0804, 0x2dcc, 0x7924, 0xa18c, + 0xff00, 0x810f, 0x00c6, 0x080c, 0x4c80, 0x2c08, 0x00ce, 0x1904, + 0x2df4, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x2df1, 0x60d0, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, + 0x0804, 0x2df1, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804, + 0x2df1, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, + 0x701b, 0x39bb, 0x0005, 0x2009, 0x0080, 0x080c, 0x4cdc, 0x1130, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a, + 0x0804, 0x2dce, 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c, + 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x3a32, + 0xa0be, 0x0112, 0x0904, 0x3a32, 0xa0be, 0x0113, 0x0904, 0x3a32, + 0xa0be, 0x0114, 0x0904, 0x3a32, 0xa0be, 0x0117, 0x0904, 0x3a32, + 0xa0be, 0x011a, 0x0904, 0x3a32, 0xa0be, 0x011c, 0x0904, 0x3a32, + 0xa0be, 0x0121, 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171, + 0x05c8, 0xa0be, 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830, + 0x8007, 0x6832, 0x04a8, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213, + 0x0528, 0xa0be, 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be, + 0x021a, 0x1120, 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300, + 0x01c8, 0x00de, 0x0804, 0x2df4, 0xad80, 0x0010, 0x20a9, 0x0007, + 0x080c, 0x3a78, 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x3a78, + 0x0048, 0xad80, 0x000c, 0x080c, 0x3a86, 0x0050, 0xad80, 0x000e, + 0x080c, 0x3a86, 0xad80, 0x000c, 0x20a9, 0x0001, 0x080c, 0x3a78, + 0x00c6, 0x080c, 0x3c05, 0x0568, 0x6838, 0xc0fd, 0x683a, 0x6837, + 0x0119, 0x6853, 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, + 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, + 0x689b, 0x0000, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, 0x96d3, 0x1120, + 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3a6f, + 0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6820, + 0xa086, 0x8001, 0x1904, 0x2dcc, 0x2009, 0x0004, 0x0804, 0x2df1, + 0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, + 0x280a, 0x8108, 0x1f04, 0x3a7a, 0x001e, 0x0005, 0x0016, 0x00a6, + 0x00b6, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, + 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, + 0x00be, 0x00ae, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x2df1, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60d0, + 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182, 0x00ff, + 0x1a04, 0x2df4, 0x7a2c, 0x7b28, 0x606c, 0xa306, 0x1140, 0x6070, + 0xa24e, 0x0904, 0x2df4, 0xa9cc, 0xff00, 0x0904, 0x2df4, 0x00c6, + 0x080c, 0x3b58, 0x2c68, 0x00ce, 0x0538, 0xa0c6, 0x4000, 0x1180, + 0x00c6, 0x0006, 0x2d60, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108, + 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x0088, + 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, 0x1118, + 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, 0x2001, + 0x4006, 0x2020, 0x0804, 0x2dce, 0x2d00, 0x7022, 0x0016, 0x00b6, + 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x8022, 0x05d8, 0x2d00, 0x601a, + 0x080c, 0x9956, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x3c05, + 0x00ce, 0x2b70, 0x1150, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00be, + 0x001e, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6837, 0x0000, 0x683b, + 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0xd88c, + 0x0108, 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9, + 0x012e, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, + 0x0002, 0x080c, 0x4c30, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085, + 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120, 0x2009, 0x0003, + 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3b3f, 0x0005, 0x6830, + 0xa086, 0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004, 0x6204, + 0xa294, 0x00ff, 0x0804, 0x2df1, 0x2009, 0x0000, 0x080c, 0x4f6e, + 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x2dcc, + 0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, 0xad34, 0x2004, 0xd0ac, + 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34, 0x0030, + 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xaeb4, 0x2e04, 0xa005, + 0x1130, 0x2100, 0xa406, 0x1548, 0x2428, 0xc5fd, 0x0430, 0x2068, + 0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14, 0x2600, 0xa206, 0x1190, + 0x2400, 0xa106, 0x1160, 0x2d60, 0xd884, 0x0540, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x1510, 0x2001, 0x4000, 0x0400, 0x2001, + 0x4007, 0x00e8, 0x2400, 0xa106, 0x1140, 0x6e14, 0x87ff, 0x1110, + 0x86ff, 0x09d0, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, + 0x3b6e, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, + 0x0030, 0x080c, 0x4c80, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005, + 0x00de, 0x00ee, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c05, + 0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824, + 0xa005, 0x0904, 0x2df4, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004, + 0x1a04, 0x2df4, 0x2010, 0x2d18, 0x080c, 0x2a8c, 0x0904, 0x2df1, + 0x7007, 0x0003, 0x701b, 0x3bd5, 0x0005, 0x6830, 0xa086, 0x0100, + 0x0904, 0x2df1, 0x0804, 0x2dcc, 0x7924, 0xa18c, 0xff00, 0x810f, + 0x60d0, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182, + 0x00ff, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x080c, 0x95c6, + 0x1188, 0xa190, 0xae34, 0x2204, 0xa065, 0x0160, 0x080c, 0x493a, + 0x2001, 0xad34, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e, + 0x0804, 0x2dcc, 0x012e, 0x0804, 0x2df1, 0x080c, 0x15d9, 0x0188, + 0xa006, 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016, + 0x0030, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, + 0x000d, 0x0005, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, + 0x1130, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066, + 0x8cff, 0x0005, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, + 0x1128, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff, + 0x0005, 0x0016, 0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c, + 0x15f0, 0x0cc8, 0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001, + 0x0010, 0x2031, 0x0000, 0x2061, 0xadd1, 0x6606, 0x6112, 0x600e, + 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007, + 0x0002, 0x701b, 0x2dcc, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, + 0x2079, 0x0000, 0x2001, 0xad8f, 0x2004, 0xa005, 0x1168, 0x0e04, + 0x3c74, 0x7818, 0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b, + 0x0001, 0x2091, 0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071, + 0xad81, 0x7138, 0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078, + 0x7030, 0xa0e0, 0x0004, 0xac82, 0xadd1, 0x0210, 0x2061, 0xad91, + 0x2c00, 0x7032, 0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262, + 0x6306, 0x640a, 0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005, + 0x00e6, 0x2071, 0xad81, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x3ccb, 0x00f6, 0x2079, 0x0000, 0x7818, 0xd084, + 0x1508, 0x00c6, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, + 0x6008, 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, + 0x703a, 0xa005, 0x1130, 0x7033, 0xad91, 0x7037, 0xad91, 0x00ce, + 0x0048, 0xac80, 0x0004, 0xa0fa, 0xadd1, 0x0210, 0x2001, 0xad91, + 0x7036, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001, + 0xad52, 0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3c5c, + 0x002e, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x0126, 0x2091, 0x8000, + 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x574f, 0x1178, + 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, + 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x0010, 0x080c, + 0x485e, 0x012e, 0x0804, 0x2dcc, 0x7824, 0x2008, 0xa18c, 0xfffd, + 0x1128, 0x61dc, 0xa10d, 0x61de, 0x0804, 0x2dcc, 0x0804, 0x2df4, + 0x81ff, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x1904, 0x2df1, + 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1904, 0x2df1, 0x080c, 0x3c2a, + 0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120, + 0x7828, 0xa005, 0x0904, 0x2dcc, 0x00c6, 0x080c, 0x3c05, 0x00ce, + 0x0904, 0x2df1, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x080c, 0x979c, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, + 0x3d3a, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0x0804, + 0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, + 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c05, 0x0904, + 0x2df1, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, + 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x080c, 0x4cdc, 0x1904, + 0x3db4, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4, + 0xff00, 0xa8c6, 0x0600, 0x1904, 0x3db4, 0x2001, 0xad52, 0x2004, + 0xd0ac, 0x1128, 0x080c, 0x4f6e, 0x1110, 0xd79c, 0x05e8, 0xd794, + 0x1110, 0xd784, 0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, + 0x0004, 0x53a3, 0x080c, 0x3a86, 0xd794, 0x0148, 0xac80, 0x000a, + 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, 0x3a86, 0x21a2, + 0xd794, 0x01d8, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002, + 0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098, + 0x3400, 0x20a9, 0x0002, 0x53a3, 0x080c, 0x3a78, 0xac80, 0x0026, + 0x2098, 0x20a9, 0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110, + 0xa6b0, 0x000b, 0xa6b0, 0x0005, 0x8108, 0x2001, 0xad34, 0x2004, + 0xd0ac, 0x0118, 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186, + 0x0100, 0x0170, 0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118, + 0xa686, 0x0020, 0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x3d5d, + 0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x702f, 0x0001, + 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xadd1, 0x6007, + 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532, + 0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b, 0x3df0, 0x0005, + 0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, + 0x0000, 0x2061, 0xadd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804, + 0x3d5d, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x2029, 0x007e, 0x7924, + 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, + 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa184, 0x00ff, 0xa0e2, + 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa284, 0xff00, + 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, + 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, + 0x2df4, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4, + 0xa502, 0x0a04, 0x2df4, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04, + 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0xff00, 0x8007, 0xa0e2, + 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0x00ff, + 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0x2061, + 0xafa6, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2dcc, 0x0006, + 0x2001, 0xad52, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001, + 0xad71, 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6164, 0x7a24, 0x6300, + 0x82ff, 0x1118, 0x7926, 0x0804, 0x2dcc, 0x83ff, 0x1904, 0x2df4, + 0x2001, 0xfff0, 0xa200, 0x1a04, 0x2df4, 0x2019, 0xffff, 0x6068, + 0xa302, 0xa200, 0x0a04, 0x2df4, 0x7926, 0x6266, 0x0804, 0x2dcc, + 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x7c28, + 0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x2009, + 0x0000, 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, + 0x0003, 0x7026, 0x20a0, 0xa1e0, 0xae34, 0x2c64, 0x8cff, 0x01b8, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084, + 0xff00, 0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010, + 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, + 0xa182, 0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff, + 0x1120, 0x7120, 0x810c, 0x0804, 0x2dcc, 0x702f, 0x0001, 0x711e, + 0x7020, 0xa300, 0x7022, 0x2061, 0xadd1, 0x6007, 0x0000, 0x6312, + 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c, + 0x1624, 0x7007, 0x0002, 0x701b, 0x3ee6, 0x0005, 0x702c, 0xa005, + 0x1168, 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xadd1, + 0x6424, 0x6528, 0x662c, 0x6730, 0x0804, 0x3ea3, 0x7120, 0x810c, + 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x60d0, 0xd0ac, 0x1118, + 0xd09c, 0x0904, 0x2df1, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x7924, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b, 0x3f11, + 0x0005, 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148, + 0xa0be, 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804, + 0x2df4, 0x6820, 0x6924, 0x080c, 0x2676, 0x1510, 0x080c, 0x4c80, + 0x11f8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3c05, + 0x01b8, 0x080c, 0x3c05, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, + 0x96ef, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3f4b, 0x0005, + 0x00de, 0x0804, 0x2df1, 0x7120, 0x080c, 0x2bc9, 0x6820, 0xa086, + 0x8001, 0x0904, 0x2df1, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, + 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x48be, 0x000e, + 0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xadd1, + 0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018, + 0xa7c6, 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2df4, 0x2009, + 0x0004, 0x0804, 0x3c49, 0xa7c6, 0x7200, 0x1904, 0x2df4, 0xa6c2, + 0x0054, 0x0a04, 0x2df4, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, + 0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b, + 0x3f92, 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, + 0xa080, 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, + 0x48be, 0x000e, 0x2009, 0x002a, 0x2061, 0xadd1, 0x6224, 0x6328, + 0x642c, 0x6530, 0x0804, 0x3c49, 0x81ff, 0x1904, 0x2df1, 0x080c, + 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, + 0x4ec6, 0x0804, 0x2dcc, 0x7824, 0xd084, 0x0904, 0x3804, 0x080c, + 0x3c2a, 0x0904, 0x2df4, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, + 0x2009, 0x0002, 0x0804, 0x2df1, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e, 0x0005, 0x1508, + 0x2001, 0xad52, 0x2004, 0xd0b4, 0x0904, 0x3834, 0x6000, 0xd08c, + 0x1904, 0x3834, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, + 0x970b, 0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, + 0x701b, 0x3ff3, 0x0005, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x0804, + 0x3834, 0x2009, 0xad30, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x2df1, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x0120, + 0x2009, 0x0007, 0x0804, 0x2df1, 0x2001, 0xad52, 0x2004, 0xd0ac, + 0x0120, 0x2009, 0x0008, 0x0804, 0x2df1, 0x609c, 0xd0a4, 0x1118, + 0xd0ac, 0x1904, 0x3834, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x080c, 0x979c, 0x1120, 0x2009, 0x0003, 0x0804, + 0x2df1, 0x7007, 0x0003, 0x701b, 0x402e, 0x0005, 0x6830, 0xa086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x2df1, 0x080c, 0x3c2a, + 0x0904, 0x2df4, 0x0804, 0x3fd8, 0x81ff, 0x2009, 0x0001, 0x1904, + 0x2df1, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x2df1, + 0x2001, 0xad52, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x2df1, + 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0006, 0x2009, 0x0009, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05, + 0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6833, + 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c, + 0x00ff, 0xa006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956, + 0x0048, 0xa28e, 0x0100, 0x1904, 0x2df4, 0xc0e5, 0x6853, 0x0000, + 0x6857, 0x0000, 0x683e, 0x080c, 0x9957, 0x2009, 0x0003, 0x0904, + 0x2df1, 0x7007, 0x0003, 0x701b, 0x408e, 0x0005, 0x6830, 0xa086, + 0x0100, 0x2009, 0x0004, 0x0904, 0x2df1, 0x0804, 0x2dcc, 0x81ff, + 0x2009, 0x0001, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x2009, + 0x0007, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2df1, + 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1, + 0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x080c, 0x3c46, 0x701b, 0x40c5, 0x0005, 0x00d6, 0xade8, 0x000f, + 0x6800, 0xa086, 0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808, + 0xa084, 0xff00, 0x1108, 0x0018, 0x00de, 0x1904, 0x2df4, 0x00de, + 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6, + 0x080c, 0x3c2a, 0x1118, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x99a6, + 0x2009, 0x0003, 0x00ce, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, + 0x40f2, 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904, + 0x2df1, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x2df1, 0x6000, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804, + 0x2df1, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c, + 0x4cdc, 0x1904, 0x2df4, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x2df1, + 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804, + 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9726, + 0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, + 0x413a, 0x0005, 0x6808, 0x8007, 0xa086, 0x0100, 0x1120, 0x2009, + 0x0004, 0x0804, 0x2df1, 0x68b0, 0x6836, 0x6810, 0x8007, 0xa084, + 0x00ff, 0x808e, 0x6814, 0x8007, 0xa084, 0x00ff, 0x8086, 0xa080, + 0x0002, 0xa108, 0xad80, 0x0004, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x0804, 0x3c49, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804, + 0x2df1, 0x7924, 0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, + 0x0110, 0x0804, 0x2df4, 0x2009, 0x001a, 0x7a2c, 0x7b28, 0x7c3c, + 0x7d38, 0x080c, 0x3c46, 0x701b, 0x4176, 0x0005, 0xad80, 0x000d, + 0x2098, 0x20a9, 0x001a, 0x20a1, 0xafad, 0x53a3, 0x0804, 0x2dcc, + 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804, 0x2df1, 0x7924, + 0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804, + 0x2df4, 0x2099, 0xafad, 0x20a0, 0x20a9, 0x001a, 0x53a3, 0x2009, + 0x001a, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x7824, + 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x8003, + 0x800b, 0x810b, 0xa108, 0x00c6, 0x2061, 0xafda, 0x6142, 0x00ce, + 0x012e, 0x0804, 0x2dcc, 0x00c6, 0x080c, 0x574f, 0x1188, 0x2001, + 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085, + 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x080c, 0x14f6, 0x0038, + 0x2061, 0xad00, 0x6030, 0xc09d, 0x6032, 0x080c, 0x485e, 0x00ce, + 0x0005, 0x0126, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, + 0x6044, 0xd0a4, 0x11b0, 0xd084, 0x0118, 0x080c, 0x4348, 0x0068, + 0xd08c, 0x0118, 0x080c, 0x4269, 0x0040, 0xd094, 0x0118, 0x080c, + 0x423a, 0x0018, 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e, + 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, + 0x0ca0, 0x624c, 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0, + 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0xa294, + 0xff00, 0xa296, 0xf700, 0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240, + 0xa295, 0x0100, 0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7, + 0x080c, 0x48de, 0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0040, + 0x6042, 0x6043, 0x0000, 0x7077, 0x0000, 0x7093, 0x0001, 0x70b7, + 0x0000, 0x70d3, 0x0000, 0x2009, 0xb3c0, 0x200b, 0x0000, 0x7087, + 0x0000, 0x707b, 0x000a, 0x2009, 0x000a, 0x2011, 0x4814, 0x080c, + 0x6593, 0x0005, 0x0156, 0x2001, 0xad73, 0x2004, 0xd08c, 0x0110, + 0x704f, 0xffff, 0x7078, 0xa005, 0x1510, 0x2011, 0x4814, 0x080c, + 0x650d, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, + 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x4251, 0x6242, 0x708b, + 0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242, + 0x0030, 0x6242, 0x708b, 0x0000, 0x707f, 0x0000, 0x0000, 0x015e, + 0x0005, 0x707c, 0xa08a, 0x0003, 0x1210, 0x0023, 0x0010, 0x080c, + 0x14f6, 0x0005, 0x4275, 0x42c5, 0x4347, 0x00f6, 0x707f, 0x0001, + 0x20e1, 0xa000, 0xe000, 0x20e1, 0x8700, 0x080c, 0x22f8, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x2079, 0xb200, 0x207b, 0x2200, 0x7807, + 0x00ef, 0x780b, 0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, + 0x0000, 0x781b, 0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, + 0xffff, 0x782b, 0x0000, 0x782f, 0x0000, 0x2079, 0xb20c, 0x207b, + 0x1101, 0x7807, 0x0000, 0x2099, 0xad05, 0x20a1, 0xb20e, 0x20a9, + 0x0004, 0x53a3, 0x2079, 0xb212, 0x207b, 0x0000, 0x7807, 0x0000, + 0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, + 0x000c, 0x600f, 0x0000, 0x080c, 0x4845, 0x00fe, 0x7083, 0x0000, + 0x6043, 0x0008, 0x6043, 0x0000, 0x0005, 0x00d6, 0x7080, 0x7083, + 0x0000, 0xa025, 0x0904, 0x432f, 0x6020, 0xd0b4, 0x1904, 0x432d, + 0x7190, 0x81ff, 0x0904, 0x431d, 0xa486, 0x000c, 0x1904, 0x4328, + 0xa480, 0x0018, 0x8004, 0x20a8, 0x2011, 0xb280, 0x2019, 0xb200, + 0x220c, 0x2304, 0xa106, 0x11b8, 0x8210, 0x8318, 0x1f04, 0x42e0, + 0x6043, 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, + 0x707f, 0x0002, 0x708b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x481b, + 0x080c, 0x6593, 0x0490, 0x2069, 0xb280, 0x6930, 0xa18e, 0x1101, + 0x1538, 0x6834, 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118, + 0x6804, 0xa005, 0x0190, 0x2011, 0xb28e, 0x2019, 0xad05, 0x20a9, + 0x0004, 0x220c, 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318, + 0x1f04, 0x4311, 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, + 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00de, 0x0005, 0x6040, + 0xa085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c, + 0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x20e1, 0x9080, + 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x0c30, 0x0005, + 0x7088, 0xa08a, 0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x14f6, + 0x0005, 0x437b, 0x438a, 0x43b2, 0x43cb, 0x43ef, 0x4417, 0x443b, + 0x446c, 0x4490, 0x44b8, 0x44ef, 0x4517, 0x4533, 0x4549, 0x4569, + 0x457c, 0x4584, 0x45b1, 0x45d5, 0x45fd, 0x4621, 0x4652, 0x468f, + 0x46be, 0x46da, 0x4719, 0x4739, 0x4752, 0x4753, 0x00c6, 0x2061, + 0xad00, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, + 0x6006, 0x00ce, 0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, + 0x0002, 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x481b, 0x080c, + 0x6593, 0x0005, 0x00f6, 0x7080, 0xa086, 0x0014, 0x1508, 0x6043, + 0x0000, 0x6020, 0xd0b4, 0x11e0, 0x2079, 0xb280, 0x7a30, 0xa296, + 0x1102, 0x11a0, 0x7834, 0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128, + 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x2011, 0x481b, 0x080c, + 0x650d, 0x708b, 0x0010, 0x080c, 0x4584, 0x0010, 0x080c, 0x485e, + 0x00fe, 0x0005, 0x708b, 0x0003, 0x6043, 0x0004, 0x2011, 0x481b, + 0x080c, 0x650d, 0x080c, 0x48c6, 0x20a3, 0x1102, 0x20a3, 0x0000, + 0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x43c2, 0x60c3, 0x0014, + 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011, + 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280, + 0x7a30, 0xa296, 0x1102, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, + 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, + 0x0004, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b, + 0x0005, 0x080c, 0x48c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, + 0x2011, 0xb28e, 0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148, + 0x714c, 0xa186, 0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c, + 0x48f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, + 0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, + 0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1103, 0x1178, + 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, + 0x1110, 0x70b7, 0x0001, 0x708b, 0x0006, 0x0029, 0x0010, 0x080c, + 0x485e, 0x00fe, 0x0005, 0x708b, 0x0007, 0x080c, 0x48c6, 0x20a3, + 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917, + 0x11a8, 0x7074, 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, + 0xa180, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df, + 0x0128, 0x080c, 0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008, + 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, + 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, + 0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005, 0x1160, + 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, + 0x708b, 0x0008, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, + 0x708b, 0x0009, 0x080c, 0x48c6, 0x20a3, 0x1105, 0x20a3, 0x0100, + 0x3430, 0x080c, 0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c, + 0x4754, 0x1170, 0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008, + 0x2099, 0xb28e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005, + 0x00f6, 0x7080, 0xa005, 0x0588, 0x2011, 0x481b, 0x080c, 0x650d, + 0xa086, 0x0014, 0x1540, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1105, + 0x1510, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x000a, + 0x00b1, 0x0098, 0xa005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b4, + 0xa005, 0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x708b, 0x000e, + 0x080c, 0x4569, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b, + 0x000b, 0x2011, 0xb20e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, + 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x48c6, + 0x20a3, 0x1106, 0x20a3, 0x0000, 0x080c, 0x4917, 0x0118, 0x2013, + 0x0000, 0x0020, 0x7050, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, + 0x0042, 0x53a6, 0x60c3, 0x0084, 0x080c, 0x4845, 0x0005, 0x00f6, + 0x7080, 0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, + 0x0084, 0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138, + 0x7834, 0xa005, 0x1120, 0x708b, 0x000c, 0x0029, 0x0010, 0x080c, + 0x485e, 0x00fe, 0x0005, 0x708b, 0x000d, 0x080c, 0x48c6, 0x20a3, + 0x1107, 0x20a3, 0x0000, 0x2099, 0xb28e, 0x20a9, 0x0040, 0x53a6, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845, + 0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c, + 0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296, + 0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c, + 0x48b8, 0x708b, 0x000e, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, + 0x0005, 0x708b, 0x000f, 0x7083, 0x0000, 0x608b, 0xbc85, 0x608f, + 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, + 0x481b, 0x080c, 0x6501, 0x0005, 0x7080, 0xa005, 0x0120, 0x2011, + 0x481b, 0x080c, 0x650d, 0x0005, 0x708b, 0x0011, 0x080c, 0x4917, + 0x1188, 0x716c, 0x81ff, 0x0170, 0x2009, 0x0000, 0x7070, 0xa084, + 0x00ff, 0x080c, 0x2676, 0xa186, 0x0080, 0x0120, 0x2011, 0xb28e, + 0x080c, 0x47df, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280, + 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, + 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c, 0x4845, + 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c, + 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296, + 0x1103, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, + 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x0012, 0x0029, + 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b, 0x0013, 0x080c, + 0x48d2, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e, + 0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148, 0x714c, 0xa186, + 0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c, 0x48f5, 0x20a9, + 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, + 0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, + 0x2079, 0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, + 0x0001, 0x708b, 0x0014, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, + 0x0005, 0x708b, 0x0015, 0x080c, 0x48d2, 0x20a3, 0x1104, 0x20a3, + 0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917, 0x11a8, 0x7074, + 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x2be6, + 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df, 0x0128, 0x080c, + 0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2298, 0x26a0, + 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, + 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05b8, 0x2011, 0x481b, + 0x080c, 0x650d, 0xa086, 0x0014, 0x1570, 0x2079, 0xb280, 0x7a30, + 0xa296, 0x1105, 0x1540, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1148, + 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, + 0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, + 0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0138, + 0x2001, 0xad73, 0x2004, 0xd0a4, 0x1110, 0x70d3, 0x0008, 0x708b, + 0x0016, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9, + 0x000e, 0x53a6, 0x3430, 0x2011, 0xb28e, 0x708b, 0x0017, 0x080c, + 0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c, 0x4754, 0x1170, + 0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2099, 0xb28e, + 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005, 0x00f6, 0x7080, + 0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0084, + 0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, + 0xa005, 0x1120, 0x708b, 0x0018, 0x0029, 0x0010, 0x080c, 0x485e, + 0x00fe, 0x0005, 0x708b, 0x0019, 0x080c, 0x48d2, 0x20a3, 0x1106, + 0x20a3, 0x0000, 0x3430, 0x2099, 0xb28e, 0x2039, 0xb20e, 0x27a0, + 0x20a9, 0x0040, 0x53a3, 0x080c, 0x4917, 0x11e8, 0x2728, 0x2514, + 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, + 0xa205, 0x202a, 0x7050, 0x2310, 0x8214, 0xa2a0, 0xb20e, 0x2414, + 0xa38c, 0x0001, 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff, + 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845, + 0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c, + 0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296, + 0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c, + 0x48b8, 0x708b, 0x001a, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, + 0x0005, 0x708b, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, + 0xb280, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, + 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c, + 0x4845, 0x0005, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0xad52, + 0x252c, 0x20a9, 0x0008, 0x2041, 0xb20e, 0x28a0, 0x2099, 0xb28e, + 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011, + 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4, + 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4769, 0x0804, 0x47d7, + 0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020, + 0xa1a6, 0x3fff, 0x0904, 0x47d7, 0xa18d, 0xc000, 0x20a9, 0x0010, + 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, + 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, + 0x0008, 0x8318, 0x1f04, 0x478f, 0x04d0, 0x23a8, 0x2021, 0x0001, + 0x8426, 0x8425, 0x1f04, 0x47a1, 0x2328, 0x8529, 0xa2be, 0x0007, + 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8, + 0xa5a8, 0x0010, 0x1f04, 0x47b0, 0x754e, 0xa5c8, 0x2be6, 0x292d, + 0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, + 0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405, + 0x201a, 0x7077, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0028, 0xa006, + 0x0018, 0xa006, 0x080c, 0x14f6, 0x009e, 0x008e, 0x0005, 0x2118, + 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010, 0x0218, 0x8420, + 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0xa39a, 0x0010, 0x8421, + 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, + 0xa238, 0x2704, 0xa42c, 0x11b8, 0xa405, 0x203a, 0x714e, 0xa1a0, + 0x2be6, 0x242d, 0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016, + 0x2508, 0x080c, 0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7077, + 0x0001, 0xa084, 0x0000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x707b, + 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, + 0x0140, 0x080c, 0x7834, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003, + 0x1000, 0x7003, 0x0000, 0x0126, 0x2091, 0x8000, 0x2071, 0xad22, + 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, + 0x48de, 0x001e, 0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42, + 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, + 0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1, + 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x2009, + 0x07d0, 0x2011, 0x481b, 0x080c, 0x6593, 0x0005, 0x0016, 0x0026, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x48de, + 0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xad00, + 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, + 0x2009, 0x002d, 0x2011, 0x4883, 0x080c, 0x6501, 0x012e, 0x00ce, + 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x0100, 0x080c, 0x7834, 0x2071, 0x0140, 0x7004, 0xa084, + 0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x5757, + 0x01a8, 0x080c, 0x5775, 0x1190, 0x2001, 0xaf9d, 0x2003, 0xaaaa, + 0x0016, 0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x001e, 0x2001, + 0xaf9e, 0x2003, 0x0000, 0x080c, 0x569a, 0x0030, 0x2001, 0x0001, + 0x080c, 0x261e, 0x080c, 0x485e, 0x012e, 0x000e, 0x00ee, 0x0005, + 0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb28e, 0x3304, 0x8007, + 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x48be, 0x0005, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x000c, + 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280, + 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x00c6, 0x0006, + 0x2061, 0x0100, 0x810f, 0x2001, 0xad30, 0x2004, 0xa005, 0x1138, + 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185, + 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x2001, + 0xad52, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a, + 0x080c, 0xa96c, 0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019, + 0x002a, 0x2009, 0x0000, 0x080c, 0x2aac, 0x004e, 0x001e, 0x0005, + 0x080c, 0x485e, 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006, + 0x2001, 0xad0c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, + 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d, + 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x0156, 0x20a9, + 0x00ff, 0x2009, 0xae34, 0xa006, 0x200a, 0x8108, 0x1f04, 0x4934, + 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, + 0xad51, 0xa006, 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, + 0xa198, 0x2be6, 0x231d, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, + 0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, + 0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, + 0x605e, 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, + 0x607e, 0x6082, 0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, + 0x609e, 0x60ae, 0x61a2, 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c, + 0x15f0, 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0, + 0x60ab, 0x0000, 0x00de, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, + 0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x014e, 0x013e, 0x015e, + 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0x6944, 0x6e48, + 0xa684, 0x3fff, 0xa082, 0x4000, 0x1a04, 0x4a49, 0xa18c, 0xff00, + 0x810f, 0xa182, 0x00ff, 0x1a04, 0x4a4e, 0x2001, 0xad0c, 0x2004, + 0xa084, 0x0003, 0x01c0, 0x2001, 0xad0c, 0x2004, 0xd084, 0x1904, + 0x4a31, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904, 0x4a31, 0x6004, + 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a31, 0x6000, 0xd0c4, + 0x0904, 0x4a31, 0x0068, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904, + 0x4a15, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a1a, + 0x60a4, 0xa00d, 0x0118, 0x080c, 0x4ef9, 0x05d0, 0x60a8, 0xa00d, + 0x0188, 0x080c, 0x4f43, 0x1170, 0x694c, 0xd1fc, 0x1118, 0x080c, + 0x4c11, 0x0448, 0x080c, 0x4bd3, 0x694c, 0xd1ec, 0x1520, 0x080c, + 0x4ded, 0x0408, 0x694c, 0xa184, 0xa000, 0x0178, 0xd1ec, 0x0140, + 0xd1fc, 0x0118, 0x080c, 0x4dfc, 0x0028, 0x080c, 0x4dfc, 0x0028, + 0xd1fc, 0x0118, 0x080c, 0x4bd3, 0x0070, 0x6050, 0xa00d, 0x0130, + 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0028, 0x2d00, 0x6052, + 0x604e, 0x6803, 0x0000, 0x080c, 0x67c5, 0xa006, 0x012e, 0x0005, + 0x2001, 0x0005, 0x2009, 0x0000, 0x04e8, 0x2001, 0x0028, 0x2009, + 0x0000, 0x04c0, 0xa082, 0x0006, 0x12a0, 0x2001, 0xad34, 0x2004, + 0xd0ac, 0x1160, 0x60a0, 0xd0bc, 0x1148, 0x6100, 0xd1fc, 0x0904, + 0x49d0, 0x2001, 0x0029, 0x2009, 0x1000, 0x0420, 0x2001, 0x0028, + 0x00a8, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, + 0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0060, 0x2009, 0x0000, + 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029, + 0x2009, 0x0000, 0xa005, 0x012e, 0x0005, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x6844, 0x8007, 0xa084, 0x00ff, 0x2008, 0xa182, 0x00ff, + 0x1a04, 0x4aa8, 0xa188, 0xae34, 0x2104, 0xa065, 0x01c0, 0x6004, + 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8, 0x2c70, 0x080c, 0x8022, + 0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012, 0x600b, 0xffff, 0x601f, + 0x000a, 0x2009, 0x0003, 0x080c, 0x80a7, 0xa006, 0x0460, 0x2001, + 0x0028, 0x0440, 0xa082, 0x0006, 0x1298, 0x2001, 0xad34, 0x2004, + 0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140, 0x6100, 0xd1fc, 0x09e8, + 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, + 0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, + 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, + 0x2001, 0x0029, 0xa005, 0x012e, 0x00ee, 0x0005, 0x2001, 0x002c, + 0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2011, 0x0000, + 0x2079, 0xad00, 0x6944, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, + 0x1a04, 0x4b77, 0x2001, 0xad0c, 0x2004, 0xa084, 0x0003, 0x1904, + 0x4b65, 0x080c, 0x4cdc, 0x1180, 0x6004, 0xa084, 0x00ff, 0xa082, + 0x0006, 0x1250, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1904, 0x4b60, + 0x60a0, 0xd0bc, 0x1904, 0x4b60, 0x6864, 0xa0c6, 0x006f, 0x0118, + 0x2008, 0x0804, 0x4b28, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f, + 0x78d0, 0xd0ac, 0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff, + 0x16b8, 0x6a70, 0x6b6c, 0x786c, 0xa306, 0x1160, 0x7870, 0xa24e, + 0x1118, 0x2208, 0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208, + 0x2310, 0x0430, 0x080c, 0x3b58, 0x2c70, 0x0550, 0x2009, 0x0000, + 0x2011, 0x0000, 0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c, + 0x4f6e, 0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e, + 0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, + 0x2001, 0x4006, 0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0458, + 0x080c, 0x8022, 0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011, + 0x0000, 0x0c80, 0x2e00, 0x601a, 0x080c, 0x9956, 0x2d00, 0x6012, + 0x601f, 0x0001, 0xa006, 0xd88c, 0x0110, 0x2001, 0x4000, 0x683a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9, 0x012e, 0x2001, 0x0000, + 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x2009, 0x0002, + 0x080c, 0x80a7, 0xa006, 0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005, + 0x2001, 0x0028, 0x2009, 0x0000, 0x0cb0, 0x2009, 0xad0c, 0x210c, + 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, + 0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0c20, 0x2001, + 0x0029, 0x2009, 0x0000, 0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff, + 0xa082, 0x4000, 0x16b8, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, + 0x12e0, 0xa188, 0xae34, 0x2104, 0xa065, 0x01b8, 0x6004, 0xa084, + 0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c, + 0x4dfc, 0x04c9, 0x0030, 0x04b9, 0x684c, 0xd0fc, 0x0110, 0x080c, + 0x4ded, 0x080c, 0x4e3a, 0xa006, 0x00c8, 0x2001, 0x0028, 0x2009, + 0x0000, 0x00a0, 0xa082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20, + 0x2001, 0x0029, 0x2009, 0x1000, 0x0048, 0x2001, 0x0029, 0x2009, + 0x0000, 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x0005, + 0x0126, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00, 0x200a, + 0x6803, 0x0000, 0x6052, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, + 0x6803, 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c, 0xa005, + 0x0170, 0x00e6, 0x2071, 0xafc7, 0x7004, 0xa086, 0x0002, 0x0168, + 0x00ee, 0x604c, 0x6802, 0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00, + 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06, 0x1d80, + 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0130, 0x6800, + 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x012e, 0x0005, 0x604c, + 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, + 0x0005, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00, 0x200a, + 0x6086, 0x0005, 0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126, 0x00c6, + 0x0026, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0110, + 0xc285, 0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005, + 0x0126, 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x0006, + 0xa086, 0x0006, 0x1180, 0x609c, 0xd0ac, 0x0168, 0x2001, 0xad52, + 0x2004, 0xd0a4, 0x0140, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007, + 0x1110, 0x2011, 0x0600, 0x000e, 0xa294, 0xff00, 0xa215, 0x6206, + 0x0006, 0xa086, 0x0006, 0x1128, 0x6290, 0x82ff, 0x1110, 0x080c, + 0x14f6, 0x000e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, + 0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1178, + 0x609c, 0xd0a4, 0x0160, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1138, + 0xa284, 0x00ff, 0xa086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, + 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, + 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190, + 0xae34, 0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x15c0, + 0x2d60, 0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000, + 0x60ab, 0x0000, 0x080c, 0x493a, 0xa006, 0x002e, 0x0005, 0x0126, + 0x2091, 0x8000, 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, + 0x0480, 0x00d6, 0xa190, 0xae34, 0x2204, 0xa06d, 0x0540, 0x2013, + 0x0000, 0x00d6, 0x00c6, 0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c, + 0x15f0, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0, 0x00ce, 0x00de, + 0x00d6, 0x00c6, 0x68ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, + 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x1600, 0x080c, + 0x8078, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x080c, 0x15f0, 0x00de, + 0xa006, 0x002e, 0x012e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218, + 0xa085, 0x0001, 0x0030, 0xa188, 0xae34, 0x2104, 0xa065, 0x0dc0, + 0xa006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b, + 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x574f, + 0x1538, 0x60a0, 0xa086, 0x007e, 0x2069, 0xb290, 0x0130, 0x2001, + 0xad34, 0x2004, 0xd0ac, 0x11e0, 0x0098, 0x2d04, 0xd0e4, 0x01c0, + 0x00d6, 0x2069, 0xb28e, 0x00c6, 0x2061, 0xaf9f, 0x6810, 0x2062, + 0x6814, 0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de, + 0x8d69, 0x2d04, 0x2069, 0x0140, 0x6886, 0x2069, 0xad00, 0x68a2, + 0x2069, 0xb28e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, + 0x0208, 0x603a, 0x6814, 0x6066, 0x2099, 0xb296, 0xac88, 0x000a, + 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xb29a, 0xac88, 0x0006, + 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xb2ae, 0x6808, 0x606a, + 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, + 0x1218, 0x2009, 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, + 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, + 0xa182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, + 0x1218, 0x2009, 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, + 0x0003, 0x0010, 0x2009, 0x0002, 0x6192, 0x014e, 0x013e, 0x015e, + 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0xb28d, 0x2e04, + 0x6896, 0x2071, 0xb28e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00, + 0x2009, 0xad71, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, + 0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4, 0x0110, 0xc2bd, 0x0008, + 0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0126, + 0x2091, 0x8000, 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff, 0x1540, + 0x6a04, 0xa282, 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9, 0x0010, + 0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x4da8, 0x080c, + 0x14f6, 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c, 0x15d9, 0x01a8, + 0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, + 0x200b, 0xffff, 0x8108, 0x1f04, 0x4dc0, 0x6807, 0x0001, 0x6e12, + 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126, + 0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800, + 0xa005, 0x1160, 0x080c, 0x4ef9, 0x1168, 0x200b, 0xffff, 0x6804, + 0xa08a, 0x0002, 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x15f0, + 0x60a7, 0x0000, 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, + 0x080c, 0x4f56, 0x0010, 0x080c, 0x4bc0, 0x080c, 0x4e71, 0x1dd8, + 0x080c, 0x4e3a, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, + 0x60a8, 0xa06d, 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54, 0xa282, + 0x0010, 0x1670, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086, + 0xffff, 0x0128, 0x8108, 0x1f04, 0x4e0e, 0x080c, 0x14f6, 0x260a, + 0x8210, 0x6a56, 0x0098, 0x080c, 0x15d9, 0x01d0, 0x2d00, 0x60aa, + 0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, + 0x8108, 0x1f04, 0x4e26, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c, + 0x4c11, 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, + 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c, 0x67c5, 0x012e, + 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126, 0x2091, + 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01e8, + 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, + 0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, + 0x6a00, 0x604c, 0xad06, 0x1110, 0x624e, 0x0018, 0xa180, 0x0000, + 0x2202, 0x82ff, 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e, + 0x0010, 0x2019, 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8, + 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, + 0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, + 0x6a00, 0x6080, 0xad06, 0x1110, 0x6282, 0x0018, 0xa180, 0x0000, + 0x2202, 0x82ff, 0x1110, 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c, + 0x4ef3, 0x1110, 0x2011, 0x0001, 0x080c, 0x4f3d, 0x1110, 0xa295, + 0x0002, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x964b, 0x0010, + 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x95e4, + 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, + 0x962e, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, + 0x080c, 0x9600, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, + 0x0118, 0x080c, 0x9667, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126, + 0x0006, 0x00d6, 0x2091, 0x8000, 0x6080, 0xa06d, 0x01a0, 0x6800, + 0x0006, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, + 0x0006, 0x6000, 0xd0fc, 0x0110, 0x080c, 0xac03, 0x000e, 0x080c, + 0x510c, 0x000e, 0x0c50, 0x6083, 0x0000, 0x6087, 0x0000, 0x00de, + 0x000e, 0x012e, 0x0005, 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001, + 0x0005, 0x00e6, 0x2170, 0x7000, 0xa005, 0x1160, 0x20a9, 0x0010, + 0xae88, 0x0004, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x4f02, + 0xa085, 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x60a4, 0xa06d, 0x1128, 0x080c, 0x15d9, 0x01a0, 0x2d00, + 0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, + 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x4f21, 0xa085, 0x0001, + 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x15f0, + 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118, + 0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160, + 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108, + 0x1f04, 0x4f4c, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, + 0x8000, 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068, + 0x6854, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c, + 0x15f0, 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4, + 0x0005, 0x00f6, 0x080c, 0x574f, 0x01b0, 0x71b4, 0x81ff, 0x1198, + 0x71d0, 0xd19c, 0x0180, 0x2001, 0x007e, 0xa080, 0xae34, 0x2004, + 0xa07d, 0x0148, 0x7804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1118, + 0x7800, 0xc0ed, 0x7802, 0x2079, 0xad51, 0x7804, 0xd0a4, 0x01e8, + 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, + 0x4cdc, 0x1168, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, + 0x0118, 0xa086, 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, + 0x8108, 0x1f04, 0x4f96, 0x00ce, 0x015e, 0x080c, 0x502d, 0x0120, + 0x2001, 0xafa2, 0x200c, 0x0038, 0x2079, 0xad51, 0x7804, 0xd0a4, + 0x0130, 0x2009, 0x07d0, 0x2011, 0x4fc1, 0x080c, 0x6593, 0x00fe, + 0x0005, 0x2011, 0x4fc1, 0x080c, 0x650d, 0x080c, 0x502d, 0x01f0, + 0x2001, 0xaeb2, 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, + 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011, + 0x4fc1, 0x080c, 0x6593, 0x00e6, 0x2071, 0xad00, 0x706f, 0x0000, + 0x7073, 0x0000, 0x080c, 0x28fa, 0x00ee, 0x04b0, 0x0156, 0x00c6, + 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1530, + 0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff, 0x8227, + 0xa006, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6000, 0xc0e5, 0xc0ec, + 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019, + 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, + 0x2009, 0x0000, 0x080c, 0xa712, 0x007e, 0x004e, 0x001e, 0x8108, + 0x1f04, 0x4fec, 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018, 0x2060, + 0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x7818, 0x2004, 0xd0ac, + 0x0005, 0x7818, 0x2004, 0xd0bc, 0x0005, 0x00f6, 0x2001, 0xaeb2, + 0x2004, 0xa07d, 0x0110, 0x7800, 0xd0ec, 0x00fe, 0x0005, 0x0126, + 0x0026, 0x2091, 0x8000, 0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008, + 0xc2fc, 0x6202, 0x002e, 0x012e, 0x0005, 0x2071, 0xae13, 0x7003, + 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, + 0x0000, 0x701f, 0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f, + 0x0000, 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, + 0xaf7c, 0x7003, 0xae13, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, + 0xaf5c, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005, + 0x0016, 0x00e6, 0x2071, 0xaf34, 0xa00e, 0x7186, 0x718a, 0x7097, + 0x0001, 0x2001, 0xad52, 0x2004, 0xd0fc, 0x1150, 0x2001, 0xad52, + 0x2004, 0xa00e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0804, 0x50d6, + 0x2001, 0xad71, 0x200c, 0xa184, 0x000f, 0x2009, 0xad72, 0x210c, + 0x0002, 0x507e, 0x50b1, 0x50b8, 0x50c2, 0x50c7, 0x507e, 0x507e, + 0x507e, 0x50a1, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e, + 0x507e, 0x7003, 0x0004, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75, + 0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e, + 0x0428, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0030, + 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097, + 0x0001, 0x0088, 0x7007, 0x0122, 0x2001, 0x0002, 0x0020, 0x7007, + 0x0121, 0x2001, 0x0003, 0x7002, 0xa006, 0x7096, 0x708e, 0xa184, + 0xff00, 0x8007, 0x709a, 0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e, + 0x0005, 0x00e6, 0x2071, 0xae13, 0x684c, 0xa005, 0x1130, 0x7028, + 0xc085, 0x702a, 0xa085, 0x0001, 0x0428, 0x6a60, 0x7236, 0x6b64, + 0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, + 0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, + 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, + 0x2100, 0xa319, 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, + 0x0001, 0xa006, 0x00ee, 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838, + 0xd0fc, 0x1904, 0x5165, 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071, + 0xad00, 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, + 0x81ff, 0x1dc8, 0x702e, 0x70b0, 0xa200, 0x70b2, 0x00de, 0x2071, + 0xae13, 0x701c, 0xa005, 0x1904, 0x5175, 0x20a9, 0x0032, 0x0f04, + 0x5173, 0x0e04, 0x512f, 0x2071, 0xaf34, 0x7200, 0x82ff, 0x05d8, + 0x6934, 0xa186, 0x0103, 0x1904, 0x5183, 0x6948, 0x6844, 0xa105, + 0x1540, 0x2009, 0x8020, 0x2200, 0x0002, 0x5173, 0x514a, 0x519b, + 0x51a7, 0x5173, 0x2071, 0x0000, 0x20a9, 0x0032, 0x0f04, 0x5173, + 0x7018, 0xd084, 0x1dd8, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, + 0x701b, 0x0001, 0x2091, 0x4080, 0x2071, 0xad00, 0x702c, 0x206a, + 0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x002e, 0x00ee, 0x015e, + 0x0005, 0x6844, 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118, + 0x2009, 0x8020, 0x0880, 0x2071, 0xae13, 0x2d08, 0x206b, 0x0000, + 0x7010, 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0110, 0x6902, + 0x0008, 0x711e, 0x0c10, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, + 0xa186, 0x001e, 0x0118, 0xa18e, 0x001f, 0x1d28, 0x684c, 0xd0cc, + 0x0d10, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x19e0, 0x2009, + 0x8021, 0x0804, 0x5143, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a98, + 0x7186, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x7084, + 0x8008, 0xa092, 0x000f, 0x1a38, 0x7186, 0xae90, 0x0003, 0x8003, + 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a, + 0x0a04, 0x515c, 0x718c, 0x7084, 0xa10a, 0x0a04, 0x515c, 0x2071, + 0x0000, 0x7018, 0xd084, 0x1904, 0x515c, 0x2071, 0xaf34, 0x7000, + 0xa086, 0x0002, 0x1150, 0x080c, 0x5426, 0x2071, 0x0000, 0x701b, + 0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x080c, 0x5450, 0x2071, + 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x0006, + 0x684c, 0x0006, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011, + 0x20a0, 0x2001, 0x0000, 0x40a4, 0x000e, 0xa084, 0x00ff, 0x684e, + 0x000e, 0x684a, 0x6952, 0x0005, 0x2071, 0xae13, 0x7004, 0x0002, + 0x5202, 0x5213, 0x5411, 0x5412, 0x541f, 0x5425, 0x5203, 0x5402, + 0x5398, 0x53ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5212, + 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, + 0x700b, 0x0000, 0x012e, 0x2069, 0xafda, 0x683c, 0xa005, 0x03f8, + 0x11f0, 0x0126, 0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001, + 0xae1f, 0x2004, 0xa10a, 0x0170, 0x0e04, 0x5236, 0x2069, 0x0000, + 0x6818, 0xd084, 0x1158, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, + 0x2091, 0x4080, 0x2069, 0xafda, 0x683f, 0xffff, 0x012e, 0x2069, + 0xad00, 0x6844, 0x6964, 0xa102, 0x2069, 0xaf34, 0x688a, 0x6984, + 0x701c, 0xa06d, 0x0120, 0x81ff, 0x0904, 0x528c, 0x00a0, 0x81ff, + 0x0904, 0x5352, 0x2071, 0xaf34, 0x7184, 0x7088, 0xa10a, 0x1258, + 0x7190, 0x2071, 0xafda, 0x7038, 0xa005, 0x0128, 0x1b04, 0x5352, + 0x713a, 0x0804, 0x5352, 0x2071, 0xaf34, 0x718c, 0x0126, 0x2091, + 0x8000, 0x7084, 0xa10a, 0x0a04, 0x536d, 0x0e04, 0x530e, 0x2071, + 0x0000, 0x7018, 0xd084, 0x1904, 0x530e, 0x2001, 0xffff, 0x2071, + 0xafda, 0x703a, 0x2071, 0xaf34, 0x7000, 0xa086, 0x0002, 0x1150, + 0x080c, 0x5426, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, + 0x0804, 0x530e, 0x080c, 0x5450, 0x2071, 0x0000, 0x701b, 0x0001, + 0x2091, 0x4080, 0x0804, 0x530e, 0x2071, 0xaf34, 0x7000, 0xa005, + 0x0904, 0x5334, 0x6934, 0xa186, 0x0103, 0x1904, 0x5311, 0x684c, + 0xd0bc, 0x1904, 0x5334, 0x6948, 0x6844, 0xa105, 0x1904, 0x5329, + 0x2009, 0x8020, 0x2071, 0xaf34, 0x7000, 0x0002, 0x5334, 0x52f4, + 0x52cc, 0x52de, 0x52ab, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75, + 0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e, + 0x2071, 0xaf7c, 0xad80, 0x000f, 0x700e, 0x7013, 0x0002, 0x7007, + 0x0002, 0x700b, 0x0000, 0x2e10, 0x080c, 0x1624, 0x2071, 0xae13, + 0x7007, 0x0009, 0x0804, 0x5352, 0x7084, 0x8008, 0xa092, 0x001e, + 0x1a04, 0x5352, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x7186, + 0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x7084, 0x8008, + 0xa092, 0x000f, 0x1a04, 0x5352, 0xae90, 0x0003, 0x8003, 0xa210, + 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7186, 0x2071, 0xae13, + 0x080c, 0x54a7, 0x0804, 0x5352, 0x0126, 0x2091, 0x8000, 0x0e04, + 0x530e, 0x2071, 0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c, + 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e, + 0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x012e, 0x0804, + 0x5352, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, + 0x0118, 0xa18e, 0x001f, 0x11c0, 0x684c, 0xd0cc, 0x01a8, 0x6850, + 0xa084, 0x00ff, 0xa086, 0x0001, 0x1178, 0x2009, 0x8021, 0x0804, + 0x52a2, 0x6844, 0xa086, 0x0100, 0x1138, 0x6868, 0xa005, 0x1120, + 0x2009, 0x8020, 0x0804, 0x52a2, 0x2071, 0xae13, 0x080c, 0x54b9, + 0x01c8, 0x2071, 0xae13, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, + 0xa086, 0x0003, 0x1130, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108, + 0x710e, 0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100, + 0x0904, 0x5412, 0x0126, 0x2091, 0x8000, 0x2071, 0xae13, 0x7008, + 0xa086, 0x0001, 0x1180, 0x0e04, 0x536b, 0x2009, 0x000d, 0x7030, + 0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006, + 0x1110, 0x7007, 0x0001, 0x012e, 0x0005, 0x2071, 0xae13, 0x080c, + 0x54b9, 0x0518, 0x2071, 0xaf34, 0x7084, 0x700a, 0x20a9, 0x0020, + 0x2099, 0xaf35, 0x20a1, 0xaf5c, 0x53a3, 0x7087, 0x0000, 0x2071, + 0xae13, 0x2069, 0xaf7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074, + 0x682e, 0x7078, 0x6832, 0x2d10, 0x080c, 0x1624, 0x7007, 0x0008, + 0x2001, 0xffff, 0x2071, 0xafda, 0x703a, 0x012e, 0x0804, 0x5352, + 0x2069, 0xaf7c, 0x6808, 0xa08e, 0x0000, 0x0904, 0x53ed, 0xa08e, + 0x0200, 0x0904, 0x53eb, 0xa08e, 0x0100, 0x1904, 0x53ed, 0x0126, + 0x2091, 0x8000, 0x0e04, 0x53e9, 0x2069, 0x0000, 0x6818, 0xd084, + 0x15c0, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, + 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e, + 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, + 0x0000, 0x2001, 0xaf59, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069, + 0xaf34, 0x689c, 0x699e, 0x2069, 0xafda, 0xa102, 0x1118, 0x683c, + 0xa005, 0x1368, 0x2001, 0xaf5a, 0x200c, 0x810d, 0x693e, 0x0038, + 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007, + 0x0001, 0x012e, 0x0010, 0x7007, 0x0005, 0x0005, 0x2001, 0xaf7e, + 0x2004, 0xa08e, 0x0100, 0x1128, 0x7007, 0x0001, 0x080c, 0x54a7, + 0x0005, 0xa08e, 0x0000, 0x0de0, 0xa08e, 0x0200, 0x1dc8, 0x7007, + 0x0005, 0x0005, 0x701c, 0xa06d, 0x0158, 0x080c, 0x54b9, 0x0140, + 0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100, 0x0110, + 0x0005, 0x0005, 0x7050, 0xa09e, 0x0100, 0x1118, 0x7007, 0x0004, + 0x0030, 0xa086, 0x0200, 0x1110, 0x7007, 0x0005, 0x0005, 0x080c, + 0x5475, 0x7006, 0x080c, 0x54a7, 0x0005, 0x0005, 0x00e6, 0x0156, + 0x2071, 0xaf34, 0x7184, 0x81ff, 0x0500, 0xa006, 0x7086, 0xae80, + 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0f04, + 0x544a, 0x2014, 0x722a, 0x8000, 0x0f04, 0x544a, 0x2014, 0x722e, + 0x8000, 0x0f04, 0x544a, 0x2014, 0x723a, 0x8000, 0x0f04, 0x544a, + 0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x015e, 0x00ee, 0x0005, + 0x00e6, 0x0156, 0x2071, 0xaf34, 0x7184, 0x81ff, 0x01d8, 0xa006, + 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, + 0x8000, 0x2014, 0x722a, 0x8000, 0x0f04, 0x546c, 0x2014, 0x723a, + 0x8000, 0x2014, 0x723e, 0x0018, 0x2001, 0x8020, 0x0010, 0x2001, + 0x8042, 0x7022, 0x015e, 0x00ee, 0x0005, 0x702c, 0x7130, 0x8108, + 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048, + 0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000, + 0x7072, 0x7132, 0x700c, 0x8001, 0x700e, 0x1180, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x54a1, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080, + 0x2001, 0x0001, 0x700b, 0x0000, 0x012e, 0x0005, 0x2001, 0x0007, + 0x0005, 0x2001, 0x0006, 0x700b, 0x0001, 0x012e, 0x0005, 0x701c, + 0xa06d, 0x0170, 0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, + 0x2d04, 0x701e, 0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x15f0, + 0x0005, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, 0x0130, 0x2304, + 0x230c, 0xa10e, 0x0110, 0xa006, 0x0060, 0x732c, 0x8319, 0x7130, + 0xa102, 0x1118, 0x2300, 0xa005, 0x0020, 0x0210, 0xa302, 0x0008, + 0x8002, 0x0005, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, + 0x0000, 0x0126, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc08d, + 0x200a, 0x012e, 0x080c, 0x163c, 0x0005, 0x7088, 0xa08a, 0x0029, + 0x1220, 0xa082, 0x001d, 0x0033, 0x0010, 0x080c, 0x14f6, 0x6027, + 0x1e00, 0x0005, 0x55c1, 0x555b, 0x5571, 0x5595, 0x55b4, 0x55e6, + 0x55f8, 0x5571, 0x55d2, 0x54ff, 0x552d, 0x54fe, 0x0005, 0x00d6, + 0x2069, 0x0200, 0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518, + 0x708b, 0x0028, 0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x584d, + 0x6028, 0xa085, 0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069, + 0xafac, 0x2d04, 0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, + 0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e, + 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, + 0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518, 0x708b, 0x0028, + 0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x58da, 0x6028, 0xa085, + 0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069, 0xafac, 0x2d04, + 0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, + 0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e, 0x004e, 0x003e, + 0x00ee, 0x00de, 0x0005, 0x6803, 0x0090, 0x6124, 0xd1e4, 0x1180, + 0x080c, 0x5663, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140, + 0x708b, 0x0020, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, + 0x0005, 0x6803, 0x0088, 0x6124, 0xd1cc, 0x11c8, 0xd1dc, 0x11a0, + 0xd1e4, 0x1178, 0xa184, 0x1e00, 0x11b8, 0x60e3, 0x0001, 0x600c, + 0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x708b, 0x0028, + 0x0058, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028, 0x708b, + 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x60e3, 0x0001, 0x600c, + 0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x6124, 0xd1d4, + 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0xa184, 0x1e00, 0x1158, + 0x708b, 0x0028, 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d, + 0x0010, 0x708b, 0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1dc, + 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d, + 0x0005, 0x080c, 0x568d, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x5663, + 0xd1d4, 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, + 0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1d4, 0x1160, 0xd1cc, + 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028, + 0x708b, 0x001d, 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x568d, + 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, + 0x001e, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005, + 0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, + 0x1128, 0xd1e4, 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, + 0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x0016, + 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, + 0x2071, 0xad00, 0x2091, 0x8000, 0x080c, 0x574f, 0x11e8, 0x2001, + 0xad0c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4, 0x2102, 0x6027, 0x0200, + 0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158, 0x6803, 0x00a0, 0x2001, + 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0428, + 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x576b, 0x0150, 0x080c, + 0x5761, 0x1138, 0x2001, 0x0001, 0x080c, 0x261e, 0x080c, 0x5726, + 0x00a0, 0x080c, 0x568a, 0x0178, 0x2001, 0x0001, 0x080c, 0x261e, + 0x7088, 0xa086, 0x001e, 0x0120, 0x7088, 0xa086, 0x0022, 0x1118, + 0x708b, 0x0025, 0x0010, 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de, + 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, + 0x566e, 0x080c, 0x6501, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, + 0x0016, 0x080c, 0x7834, 0x2071, 0xad00, 0x080c, 0x560f, 0x001e, + 0x00fe, 0x00ee, 0x0005, 0x2001, 0xad00, 0x2004, 0xa086, 0x0004, + 0x0140, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, + 0x0000, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6803, 0x00c0, 0x0156, + 0x20a9, 0x002d, 0x1d04, 0x5692, 0x2091, 0x6000, 0x1f04, 0x5692, + 0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, + 0x0140, 0x2071, 0xad00, 0x2001, 0xaf9e, 0x200c, 0xa186, 0x0000, + 0x0158, 0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186, + 0x0003, 0x0158, 0x0804, 0x5714, 0x708b, 0x0022, 0x0040, 0x708b, + 0x0021, 0x0028, 0x708b, 0x0023, 0x0020, 0x708b, 0x0024, 0x6043, + 0x0000, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, + 0x26cb, 0x0026, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, + 0x080c, 0x7ae9, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b, + 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, + 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04d0, + 0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130, + 0x6803, 0x0100, 0x1f04, 0x56e2, 0x080c, 0x57a0, 0x012e, 0x015e, + 0x080c, 0x5761, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006, + 0xa085, 0x0020, 0x6052, 0x080c, 0x57a0, 0xa006, 0x8001, 0x1df0, + 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x57a0, + 0x2001, 0xaf9e, 0x2003, 0x0004, 0x080c, 0x54e5, 0x080c, 0x5761, + 0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0xaf9e, + 0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, + 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x2001, + 0xaf9d, 0x2003, 0x0000, 0x2001, 0xaf8e, 0x2003, 0x0000, 0x708b, + 0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c, + 0x26cb, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027, + 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, + 0x2001, 0xaf9d, 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005, 0x0006, + 0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0000, 0x000e, + 0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086, + 0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084, + 0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71, + 0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e, 0x0005, 0x2001, + 0xad0c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x26eb, 0x0036, 0x0016, + 0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2aac, 0x001e, 0x003e, + 0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xad0c, 0x2e04, 0x0118, + 0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, 0x00ee, 0x0005, + 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, + 0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, + 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006, + 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3, 0x0000, + 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x26cb, 0x6800, 0xa084, + 0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e, 0x6052, 0x6050, + 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, + 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x6020, 0xa084, + 0x0080, 0x0138, 0x2001, 0xad0c, 0x200c, 0xc1bd, 0x2102, 0x0804, + 0x5845, 0x2001, 0xad0c, 0x200c, 0xc1bc, 0x2102, 0x6028, 0xa084, + 0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090, 0x20a9, 0x0384, + 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x57f8, 0x2091, 0x6000, 0x1f04, + 0x57f8, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c, + 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c, + 0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, + 0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x0438, 0x60e3, 0x0000, + 0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x6803, 0x0080, + 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, + 0xa10c, 0x0138, 0x1d04, 0x582a, 0x2091, 0x6000, 0x1f04, 0x582a, + 0x0840, 0x6028, 0xa085, 0x1e00, 0x602a, 0x70a0, 0xa005, 0x1118, + 0x6887, 0x0001, 0x0008, 0x6886, 0xa006, 0x00ee, 0x00de, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, + 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, + 0x2069, 0x0140, 0x6020, 0xa084, 0x00c0, 0x0120, 0x6884, 0xa005, + 0x1904, 0x58a1, 0x6803, 0x0088, 0x60e3, 0x0000, 0x6887, 0x0000, + 0x2001, 0x0000, 0x080c, 0x26cb, 0x2069, 0x0200, 0x6804, 0xa005, + 0x1118, 0x6808, 0xa005, 0x01c0, 0x6028, 0xa084, 0xfbff, 0x602a, + 0x6027, 0x0400, 0x2069, 0xafac, 0x7000, 0x206a, 0x708b, 0x0026, + 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x5884, 0x2091, 0x6000, + 0x1f04, 0x5884, 0x0804, 0x58d2, 0x2069, 0x0140, 0x20a9, 0x0384, + 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0530, + 0xa084, 0x1a00, 0x1518, 0x1d04, 0x5890, 0x2091, 0x6000, 0x1f04, + 0x5890, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c, + 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c, + 0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, + 0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x00a0, 0x6803, 0x0080, + 0x2069, 0x0140, 0x60e3, 0x0000, 0x70a0, 0xa005, 0x1118, 0x6887, + 0x0001, 0x0008, 0x6886, 0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb, + 0x60e2, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, + 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x6020, 0xa084, 0x00c0, + 0x01f0, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c, + 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c, + 0x7a64, 0x2069, 0x0140, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, + 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0804, 0x5972, 0x2001, + 0xad0c, 0x200c, 0xd1b4, 0x1150, 0xc1b5, 0x2102, 0x080c, 0x5663, + 0x2069, 0x0140, 0x6803, 0x0080, 0x60e3, 0x0000, 0x2069, 0x0200, + 0x6804, 0xa005, 0x1118, 0x6808, 0xa005, 0x01b8, 0x6028, 0xa084, + 0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0xafac, 0x7000, 0x206a, + 0x708b, 0x0027, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x592e, + 0x2091, 0x6000, 0x1f04, 0x592e, 0x04e8, 0x6027, 0x1e00, 0x2009, + 0x1e00, 0xe000, 0x6024, 0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0, + 0x1d04, 0x5935, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, + 0x64a2, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, + 0xafda, 0x7018, 0x00ee, 0xa005, 0x1d00, 0x01e0, 0x0026, 0x2011, + 0x566e, 0x080c, 0x650d, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, + 0x70a0, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, + 0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x2001, 0xad0c, 0x200c, + 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, + 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x7130, 0xd184, 0x1180, + 0x2011, 0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, + 0xad52, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x59df, + 0x7130, 0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x0530, + 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019, + 0x000e, 0x080c, 0xa8eb, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, + 0xa186, 0x007e, 0x0170, 0xa186, 0x0080, 0x0158, 0x080c, 0x4cdc, + 0x1140, 0x8127, 0xa006, 0x0016, 0x2009, 0x000e, 0x080c, 0xa96c, + 0x001e, 0x8108, 0x1f04, 0x59b0, 0x015e, 0x001e, 0xd1ac, 0x1148, + 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c, 0x2aac, 0x001e, + 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c, 0x4cdc, + 0x1110, 0x080c, 0x493a, 0x8108, 0x1f04, 0x59d6, 0x015e, 0x2011, + 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, + 0x79e1, 0x080c, 0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, + 0x003e, 0x60e3, 0x0000, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, + 0x569a, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, + 0x0005, 0x2071, 0xade1, 0x7003, 0x0000, 0x7007, 0x0000, 0x700f, + 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001, 0x705f, + 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000, 0x708f, + 0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, 0x2071, 0xade1, 0x6848, + 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0428, + 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, 0x685c, + 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, 0x000c, + 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, + 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, 0x702a, + 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee, 0x0005, 0x2b78, + 0x2071, 0xade1, 0x7004, 0x0043, 0x700c, 0x0002, 0x5a5b, 0x5a52, + 0x5a52, 0x5a52, 0x5a52, 0x0005, 0x5ab1, 0x5ab2, 0x5ae4, 0x5ae5, + 0x5aaf, 0x5b33, 0x5b38, 0x5b69, 0x5b6a, 0x5b85, 0x5b86, 0x5b87, + 0x5b88, 0x5b89, 0x5b8a, 0x5c40, 0x5c67, 0x700c, 0x0002, 0x5a74, + 0x5aaf, 0x5aaf, 0x5ab0, 0x5ab0, 0x7830, 0x7930, 0xa106, 0x0120, + 0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a, 0x01f8, 0x1210, + 0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c, 0x15c0, 0x01b0, + 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000, + 0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc085, + 0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x163c, 0x0005, 0x080c, + 0x15c0, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x15c0, 0x1108, 0x0c10, + 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x08f8, 0x0005, + 0x0005, 0x0005, 0x700c, 0x0002, 0x5ab9, 0x5abc, 0x5aca, 0x5ae3, + 0x5ae3, 0x080c, 0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, + 0x0006, 0x080c, 0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d, + 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058, + 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, + 0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218, 0x00db, 0x012e, 0x0005, + 0x012e, 0x080c, 0x5b8b, 0x0005, 0x0005, 0x0005, 0x00e6, 0x2071, + 0xade1, 0x700c, 0x0002, 0x5af0, 0x5af0, 0x5af0, 0x5af2, 0x5af5, + 0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f, 0x0002, 0x00ee, + 0x0005, 0x5b8b, 0x5b8b, 0x5ba7, 0x5b8b, 0x5d22, 0x5b8b, 0x5b8b, + 0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x5d64, 0x5da7, 0x5df0, 0x5e04, + 0x5b8b, 0x5b8b, 0x5bc3, 0x5ba7, 0x5b8b, 0x5b8b, 0x5c1d, 0x5ead, + 0x5ec8, 0x5b8b, 0x5bc3, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5c13, + 0x5ec8, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, + 0x5b8b, 0x5b8b, 0x5bd7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, + 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, + 0x5b8b, 0x5b8b, 0x5bec, 0x7020, 0x2068, 0x080c, 0x15f0, 0x0005, + 0x700c, 0x0002, 0x5b3f, 0x5b42, 0x5b50, 0x5b68, 0x5b68, 0x080c, + 0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c, + 0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d, 0x00de, 0x0048, + 0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058, 0x2068, 0x7084, + 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, + 0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, 0x0005, 0x012e, 0x0419, + 0x0005, 0x0005, 0x0005, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5ba7, + 0x5b8b, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5ba7, 0x5ba7, + 0x5ba7, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5b8b, + 0x5ba7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, + 0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e, + 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007, + 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, + 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, + 0x510c, 0x012e, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0988, + 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x5cd0, 0x7007, 0x0006, + 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5cd0, 0x0005, 0x6834, + 0x8007, 0xa084, 0x00ff, 0x0904, 0x5b99, 0x8001, 0x1120, 0x7007, + 0x0001, 0x0804, 0x5ced, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, + 0x701a, 0x704b, 0x5ced, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, + 0xa086, 0x0001, 0x1904, 0x5b99, 0x7007, 0x0001, 0x2009, 0xad30, + 0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853, + 0x0000, 0x080c, 0x4ab1, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, + 0x6837, 0x0139, 0x684a, 0x6952, 0x080c, 0x510c, 0x012e, 0x0ca0, + 0x2001, 0x0028, 0x0c90, 0x684c, 0xa084, 0x00c0, 0xa086, 0x00c0, + 0x1120, 0x7007, 0x0001, 0x0804, 0x5ee0, 0x2d00, 0x7016, 0x701a, + 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1, 0xae0c, 0x53a3, + 0x6858, 0x7012, 0xa082, 0x0401, 0x1a04, 0x5bb5, 0x6a84, 0xa28a, + 0x0002, 0x1a04, 0x5bb5, 0x82ff, 0x1138, 0x6888, 0x698c, 0xa105, + 0x0118, 0x2001, 0x5ca3, 0x0018, 0xa280, 0x5c99, 0x2005, 0x70c6, + 0x7010, 0xa015, 0x0904, 0x5c85, 0x080c, 0x15c0, 0x1118, 0x7007, + 0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, 0x2060, 0x2c05, 0x6836, + 0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, 0x1210, 0xa00e, 0x2200, + 0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0108, 0xa108, + 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x080c, 0x1624, 0x7090, + 0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118, 0x7007, 0x0010, + 0x0005, 0x7020, 0x2068, 0x080c, 0x15f0, 0x7014, 0x2068, 0x0804, + 0x5bb5, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08, + 0x2068, 0x6906, 0x711a, 0x0804, 0x5c40, 0x7014, 0x2068, 0x7007, + 0x0001, 0x6884, 0xa005, 0x1128, 0x6888, 0x698c, 0xa105, 0x0108, + 0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0904, 0x5ee0, + 0x04b8, 0x5c9b, 0x5c9f, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, + 0x000f, 0x0005, 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x00f6, + 0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88, 0x6e8c, 0x6804, 0x2060, + 0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816, + 0x7008, 0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, + 0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0c78, 0x6004, + 0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x2009, 0xad30, 0x210c, 0x81ff, 0x1198, 0x6838, 0xa084, 0x00ff, + 0x683a, 0x080c, 0x4993, 0x1108, 0x0005, 0x080c, 0x51df, 0x0126, + 0x2091, 0x8000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x012e, 0x0ca0, + 0x2001, 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009, 0xad30, 0x210c, + 0x81ff, 0x11b0, 0x6858, 0xa005, 0x01b0, 0x6838, 0xa084, 0x00ff, + 0x683a, 0x6853, 0x0000, 0x080c, 0x4a55, 0x1108, 0x0005, 0x0126, + 0x2091, 0x8000, 0x080c, 0x51df, 0x080c, 0x510c, 0x012e, 0x0cb0, + 0x2001, 0x0028, 0x0ca0, 0x2001, 0x0000, 0x0c88, 0x7018, 0x6802, + 0x2d08, 0x2068, 0x6906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, + 0x7007, 0x0006, 0x0030, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, + 0x080f, 0x0005, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, + 0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x01b0, + 0x2009, 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0178, 0xa005, + 0x11f0, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x11b8, + 0x0066, 0x6e50, 0x080c, 0x4dcf, 0x006e, 0x0088, 0x0046, 0x2011, + 0xad0c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x4cdc, + 0x1110, 0x080c, 0x4f2d, 0x8108, 0x1f04, 0x5d4e, 0x00ce, 0x684c, + 0xd084, 0x1118, 0x080c, 0x15f0, 0x0005, 0x0126, 0x2091, 0x8000, + 0x080c, 0x510c, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0580, 0x2061, 0xb048, + 0x6100, 0xd184, 0x0178, 0x6858, 0xa084, 0x00ff, 0x1550, 0x6000, + 0xd084, 0x0520, 0x6004, 0xa005, 0x1538, 0x6003, 0x0000, 0x600b, + 0x0000, 0x00c8, 0x2011, 0x0001, 0x6860, 0xa005, 0x1110, 0x2001, + 0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, 0x0178, 0x6006, + 0x6858, 0x8007, 0xa084, 0x00ff, 0x0148, 0x600a, 0x6858, 0x8000, + 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x5f7f, 0x012e, 0x0804, + 0x5f79, 0x012e, 0x0804, 0x5f73, 0x012e, 0x0804, 0x5f76, 0x0126, + 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4, + 0x05e0, 0x2061, 0xb048, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, + 0xd08c, 0x1530, 0x6c48, 0xa484, 0x0003, 0x0170, 0x6958, 0xa18c, + 0x00ff, 0x8001, 0x1120, 0x2100, 0xa210, 0x0620, 0x0028, 0x8001, + 0x1508, 0x2100, 0xa212, 0x02f0, 0xa484, 0x000c, 0x0188, 0x6958, + 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x1120, 0x2100, 0xa318, + 0x0288, 0x0030, 0xa082, 0x0004, 0x1168, 0x2100, 0xa31a, 0x0250, + 0x6860, 0xa005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, + 0x0804, 0x5f7f, 0x012e, 0x0804, 0x5f7c, 0x012e, 0x0804, 0x5f79, + 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xb048, 0x6300, + 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, + 0x5f8d, 0x012e, 0x0804, 0x5f7c, 0x0126, 0x00c6, 0x2091, 0x8000, + 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0xb048, + 0x6000, 0xa084, 0xfcff, 0x6002, 0x00ce, 0x0448, 0x6858, 0xa005, + 0x05d0, 0x685c, 0xa065, 0x0598, 0x2001, 0xad30, 0x2004, 0xa005, + 0x0118, 0x080c, 0x974e, 0x0068, 0x6013, 0x0400, 0x6057, 0x0000, + 0x694c, 0xd1a4, 0x0110, 0x6950, 0x6156, 0x2009, 0x0041, 0x080c, + 0x80a7, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x1140, 0x0026, + 0x2009, 0x0000, 0x2011, 0xfdff, 0x080c, 0x663f, 0x002e, 0x684c, + 0xd0c4, 0x0148, 0x2061, 0xb048, 0x6000, 0xd08c, 0x1120, 0x6008, + 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x0804, 0x5f7f, 0x00ce, + 0x012e, 0x0804, 0x5f79, 0x6954, 0xa186, 0x002e, 0x0d40, 0xa186, + 0x002d, 0x0d28, 0xa186, 0x0045, 0x0510, 0xa186, 0x002a, 0x1130, + 0x2001, 0xad0c, 0x200c, 0xc194, 0x2102, 0x08c8, 0xa186, 0x0020, + 0x0170, 0xa186, 0x0029, 0x1d18, 0x6944, 0xa18c, 0xff00, 0x810f, + 0x080c, 0x4cdc, 0x1960, 0x6000, 0xc0e4, 0x6002, 0x0840, 0x685c, + 0xa065, 0x09a8, 0x2001, 0xafa3, 0x2004, 0x6016, 0x0800, 0x685c, + 0xa065, 0x0968, 0x00e6, 0x6860, 0xa075, 0x2001, 0xad30, 0x2004, + 0xa005, 0x0150, 0x080c, 0x974e, 0x8eff, 0x0118, 0x2e60, 0x080c, + 0x974e, 0x00ee, 0x0804, 0x5e3f, 0x6020, 0xc0dc, 0xc0d5, 0x6022, + 0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b, + 0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x67a8, + 0x080c, 0x6c50, 0x00ee, 0x0804, 0x5e3f, 0x2061, 0xb048, 0x6000, + 0xd084, 0x0190, 0xd08c, 0x1904, 0x5f8d, 0x0126, 0x2091, 0x8000, + 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x5f8d, 0x012e, + 0x6853, 0x0016, 0x0804, 0x5f86, 0x6853, 0x0007, 0x0804, 0x5f86, + 0x6834, 0x8007, 0xa084, 0x00ff, 0x1118, 0x080c, 0x5b99, 0x0078, + 0x2030, 0x8001, 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007, + 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5ee0, 0x0005, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x2009, 0xad30, 0x210c, 0x81ff, + 0x1904, 0x5f5b, 0x2009, 0xad0c, 0x210c, 0xd194, 0x1904, 0x5f63, + 0x6848, 0x2070, 0xae82, 0xb400, 0x0a04, 0x5f4f, 0x2001, 0xad16, + 0x2004, 0xae02, 0x1a04, 0x5f4f, 0x2061, 0xb048, 0x6100, 0xa184, + 0x0301, 0xa086, 0x0001, 0x15a8, 0x711c, 0xa186, 0x0006, 0x15b0, + 0x7018, 0xa005, 0x0904, 0x5f5b, 0x2004, 0xd0e4, 0x1904, 0x5f5e, + 0x7020, 0xd0dc, 0x1904, 0x5f66, 0x6853, 0x0000, 0x6803, 0x0000, + 0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c, 0xd0f4, 0x1904, + 0x5f69, 0x2e60, 0x080c, 0x65aa, 0x012e, 0x00ee, 0x0005, 0x2068, + 0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c, 0xd0f4, 0x15c8, + 0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853, 0x0006, 0x0804, + 0x5f86, 0xd184, 0x0dc0, 0xd1c4, 0x11a8, 0x00b8, 0x6944, 0xa18c, + 0xff00, 0x810f, 0x080c, 0x4cdc, 0x11c8, 0x6000, 0xd0e4, 0x11b0, + 0x711c, 0xa186, 0x0007, 0x1118, 0x6853, 0x0002, 0x0088, 0x6853, + 0x0008, 0x0070, 0x6853, 0x000e, 0x0058, 0x6853, 0x0017, 0x0040, + 0x6853, 0x0035, 0x0028, 0x6853, 0x0028, 0x0010, 0x6853, 0x0029, + 0x012e, 0x00ee, 0x0418, 0x6853, 0x002a, 0x0cd0, 0x6853, 0x0045, + 0x0cb8, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x080c, 0xa566, + 0x012e, 0x00ee, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, + 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, + 0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x0126, 0x2091, + 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x080c, 0x15f0, 0x0005, + 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x7072, + 0x7038, 0x7076, 0x0058, 0x7070, 0xa080, 0x0040, 0x7072, 0x1230, + 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, 0x7132, + 0x0005, 0x00d6, 0x080c, 0x65a1, 0x00de, 0x0005, 0x00d6, 0x2011, + 0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005, 0x20e1, + 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0118, + 0xa086, 0x1000, 0x1540, 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, + 0x8217, 0xa084, 0xf000, 0xa086, 0x3000, 0x1118, 0x080c, 0x61c6, + 0x00b0, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84, + 0x0007, 0x1188, 0xac82, 0xb400, 0x0270, 0x6858, 0xac02, 0x1258, + 0x6120, 0xd1f4, 0x1160, 0x2009, 0x0047, 0x080c, 0x80a7, 0x7a1c, + 0xd284, 0x1968, 0x0005, 0xa016, 0x080c, 0x1824, 0x0cc0, 0x0cd8, + 0x781c, 0xd08c, 0x0500, 0x0156, 0x0136, 0x0146, 0x20e1, 0x3000, + 0x3d20, 0x3e28, 0xa584, 0x0076, 0x1530, 0xa484, 0x7000, 0xa086, + 0x1000, 0x11a8, 0x080c, 0x604e, 0x01f0, 0x20e1, 0x3000, 0x7828, + 0x7828, 0x080c, 0x606a, 0x014e, 0x013e, 0x015e, 0x2009, 0xafcf, + 0x2104, 0xa005, 0x1108, 0x0005, 0x080c, 0x6c50, 0x0ce0, 0xa484, + 0x7000, 0x1518, 0x0499, 0x01b8, 0x7000, 0xa084, 0xff00, 0xa086, + 0x8100, 0x0d18, 0x0080, 0xd5a4, 0x0158, 0x080c, 0x1d86, 0x20e1, + 0x9010, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0048, + 0x00e9, 0x6883, 0x0000, 0x080c, 0xac59, 0x20e1, 0x3000, 0x7828, + 0x7828, 0x014e, 0x013e, 0x015e, 0x08b0, 0x0081, 0x1130, 0x7000, + 0xa084, 0xff00, 0xa086, 0x8100, 0x1d70, 0x080c, 0xac59, 0x20e1, + 0x3000, 0x7828, 0x7828, 0x080c, 0x642d, 0x0c58, 0xa484, 0x01ff, + 0x6882, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, + 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x0005, 0x20a9, + 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, + 0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007, + 0xa196, 0x0000, 0x1118, 0x0804, 0x62cf, 0x0005, 0xa196, 0x2000, + 0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x41d1, 0x0ca8, + 0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x6372, 0x0c68, + 0x00c6, 0x6a80, 0x82ff, 0x0904, 0x61c0, 0x7110, 0xa18c, 0xff00, + 0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904, 0x61c0, + 0xa08e, 0x0023, 0x1570, 0x080c, 0x6408, 0x0904, 0x61c0, 0x7124, + 0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005, 0x1904, + 0x61c0, 0x2009, 0x0015, 0x080c, 0x80a7, 0x0804, 0x61c0, 0xa08e, + 0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, + 0x80a7, 0x0804, 0x61c0, 0xa08e, 0x0100, 0x1904, 0x61c0, 0x7034, + 0xa005, 0x1904, 0x61c0, 0x2009, 0x0016, 0x080c, 0x80a7, 0x0804, + 0x61c0, 0xa08e, 0x0022, 0x1904, 0x61c0, 0x7030, 0xa08e, 0x0300, + 0x1580, 0x68d0, 0xd0a4, 0x0528, 0xc0b5, 0x68d2, 0x7100, 0xa18c, + 0x00ff, 0x696e, 0x7004, 0x6872, 0x00f6, 0x2079, 0x0100, 0x79e6, + 0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26a0, + 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2676, 0x694e, + 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0xad00, 0x70a2, + 0x00ee, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0017, 0x0804, + 0x6193, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005, 0x1904, 0x61c0, + 0x68d0, 0xc0a5, 0x68d2, 0x2009, 0x0030, 0x0804, 0x6193, 0xa08e, + 0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0018, + 0x0804, 0x6193, 0xa08e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, + 0x6193, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x6193, + 0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, + 0x001b, 0x0804, 0x6193, 0xa08e, 0x5000, 0x1140, 0x7034, 0xa005, + 0x1904, 0x61c0, 0x2009, 0x001c, 0x0804, 0x6193, 0xa08e, 0x1300, + 0x1120, 0x2009, 0x0034, 0x0804, 0x6193, 0xa08e, 0x1200, 0x1140, + 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0024, 0x0804, 0x6193, + 0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, 0x002d, 0x04d8, + 0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, 0x002a, 0x0498, + 0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468, 0xa08e, 0x5300, + 0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011, 0xb28d, 0x8208, + 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015, + 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3c5c, 0x004e, 0x8108, + 0x1f04, 0x6176, 0x2009, 0x0023, 0x0070, 0xa08e, 0x6000, 0x1118, + 0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118, 0x2009, 0x0045, + 0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xb283, 0x2204, 0x8211, + 0x220c, 0x080c, 0x2676, 0x1530, 0x080c, 0x4c80, 0x1518, 0x6612, + 0x6516, 0x86ff, 0x0180, 0x001e, 0x0016, 0xa186, 0x0017, 0x1158, + 0x686c, 0xa606, 0x1140, 0x6870, 0xa506, 0xa084, 0xff00, 0x1118, + 0x6000, 0xc0f5, 0x6002, 0x00c6, 0x080c, 0x8022, 0x0168, 0x001e, + 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x80a7, + 0x00ce, 0x0005, 0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046, + 0x080c, 0x6221, 0x1904, 0x621e, 0xa184, 0xff00, 0x8007, 0xa086, + 0x0008, 0x1904, 0x621e, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x6408, + 0x0904, 0x621e, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140, + 0x7034, 0xa005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x80a7, 0x04b0, + 0xa08e, 0x0100, 0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016, + 0x080c, 0x80a7, 0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e, + 0x1400, 0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0xb283, 0x2204, + 0x8211, 0x220c, 0x080c, 0x2676, 0x11c0, 0x080c, 0x4c80, 0x11a8, + 0x6612, 0x6516, 0x00c6, 0x080c, 0x8022, 0x0170, 0x001e, 0x611a, + 0x080c, 0x9956, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, + 0x80a7, 0x080c, 0x6c50, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, + 0x0005, 0x00f6, 0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156, + 0x3c00, 0x0006, 0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1df2, + 0x1590, 0x080c, 0x1ce2, 0x05c8, 0x04d9, 0x1130, 0x7908, 0xa18c, + 0x1fff, 0xa182, 0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000, + 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a, + 0x2004, 0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0401, + 0x1120, 0xa08a, 0x0140, 0x1a0c, 0x14f6, 0x80ac, 0x20e1, 0x6000, + 0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803, + 0x0004, 0xa294, 0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e, + 0x001e, 0x002e, 0x00de, 0x00fe, 0x0005, 0xa085, 0x0001, 0x0c98, + 0x0006, 0x2001, 0x0111, 0x2004, 0xa084, 0x0003, 0x000e, 0x0005, + 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0xa696, 0x00ff, 0x1198, + 0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x62ca, 0xa596, + 0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8, 0xa596, 0xfffc, 0x1118, + 0x2009, 0x0080, 0x04b8, 0x2011, 0x0000, 0x2019, 0xad34, 0x231c, + 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34, + 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071, 0xaeb5, 0x2e1c, + 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, 0xc2fd, 0x0080, 0x2368, + 0x6f10, 0x0006, 0x2100, 0xa706, 0x000e, 0x6b14, 0x1120, 0xa346, + 0x1110, 0x2408, 0x0078, 0x87ff, 0x1110, 0x83ff, 0x0d58, 0x8420, + 0x8e70, 0x1f04, 0x62a7, 0x82ff, 0x1118, 0xa085, 0x0001, 0x0018, + 0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, 0x004e, 0x0005, 0xa084, + 0x0007, 0x000a, 0x0005, 0x62db, 0x62db, 0x62db, 0x641a, 0x62db, + 0x62dc, 0x62f1, 0x635d, 0x0005, 0x7110, 0xd1bc, 0x0188, 0x7120, + 0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a, 0xb400, 0x0248, 0x6858, + 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0x80a7, + 0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x6344, 0x2011, 0xb283, + 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1904, 0x6344, 0x080c, + 0x4c80, 0x1904, 0x6344, 0x6612, 0x6516, 0x6000, 0xd0ec, 0x15e0, + 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0160, 0x080c, + 0x574f, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0, + 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0530, + 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6152, 0x2009, + 0x0044, 0x080c, 0x80a7, 0x00c0, 0x00c6, 0x080c, 0x8022, 0x001e, + 0x0198, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004, + 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, + 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00ce, 0x0005, 0x00c6, 0x080c, + 0x9807, 0x001e, 0x0dc8, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, + 0x7130, 0x6152, 0x6013, 0x0300, 0x6003, 0x0001, 0x6007, 0x0041, + 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c38, 0x7110, 0xd1bc, 0x0188, + 0x7020, 0x2060, 0xac84, 0x0007, 0x1160, 0xac82, 0xb400, 0x0248, + 0x6858, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, + 0x80a7, 0x0005, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, + 0x1130, 0xa084, 0x000f, 0xa08a, 0x0006, 0x1208, 0x000b, 0x0005, + 0x6386, 0x6387, 0x6386, 0x6386, 0x63f0, 0x63fc, 0x0005, 0x7110, + 0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x63ef, 0x700c, 0x7108, + 0x080c, 0x2676, 0x1904, 0x63ef, 0x080c, 0x4c80, 0x1904, 0x63ef, + 0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0xa28c, 0x00ff, + 0xa186, 0x0004, 0x0118, 0xa186, 0x0006, 0x15c8, 0x00c6, 0x080c, + 0x6408, 0x00ce, 0x0904, 0x63ef, 0x00c6, 0x080c, 0x8022, 0x001e, + 0x05f0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0002, 0x7120, 0x610a, + 0x2009, 0x0088, 0x080c, 0x80a7, 0x0490, 0xa28c, 0x00ff, 0xa186, + 0x0006, 0x0160, 0xa186, 0x0004, 0x0148, 0xa294, 0xff00, 0x8217, + 0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1188, 0x00c6, 0x080c, + 0x8022, 0x001e, 0x01e0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0005, + 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x80a7, 0x0080, 0x00c6, + 0x080c, 0x8022, 0x001e, 0x0158, 0x611a, 0x080c, 0x9956, 0x601f, + 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x80a7, 0x0005, + 0x7110, 0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a, 0x2009, + 0x0089, 0x080c, 0x80a7, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x0041, + 0x0130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x80a7, 0x0005, + 0x7020, 0x2060, 0xac84, 0x0007, 0x1158, 0xac82, 0xb400, 0x0240, + 0x2001, 0xad16, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001, 0x0005, + 0xa006, 0x0ce8, 0x7110, 0xd1bc, 0x1178, 0x7024, 0x2060, 0xac84, + 0x0007, 0x1150, 0xac82, 0xb400, 0x0238, 0x6858, 0xac02, 0x1220, + 0x2009, 0x0051, 0x080c, 0x80a7, 0x0005, 0x2031, 0x0105, 0x0069, + 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, + 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6, 0x00f6, + 0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x05b0, 0x080c, 0x8022, + 0x0598, 0x0066, 0x00c6, 0x0046, 0x2011, 0xb283, 0x2204, 0x8211, + 0x220c, 0x080c, 0x2676, 0x1580, 0x080c, 0x4c80, 0x1568, 0x6612, + 0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0x9956, 0x080c, + 0x15d9, 0x01f0, 0x2d00, 0x6056, 0x6803, 0x0000, 0x6837, 0x0000, + 0x6c3a, 0xadf8, 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, 0x53a3, + 0x006e, 0x6612, 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, 0x0001, + 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00fe, 0x00de, 0x00ce, 0x0005, + 0x080c, 0x8078, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x2071, + 0xafda, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012, + 0x7017, 0xb400, 0x7007, 0x0000, 0x7026, 0x702b, 0x7841, 0x7032, + 0x7037, 0x789d, 0x703b, 0xffff, 0x703f, 0xffff, 0x7042, 0x7047, + 0x41b3, 0x0005, 0x2071, 0xafda, 0x1d04, 0x64fc, 0x2091, 0x6000, + 0x700c, 0x8001, 0x700e, 0x1180, 0x700f, 0x0361, 0x7007, 0x0001, + 0x0126, 0x2091, 0x8000, 0x7040, 0xa00d, 0x0148, 0x8109, 0x7142, + 0x1130, 0x7044, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, + 0xa00d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, + 0x8109, 0x7126, 0xa186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, + 0x1110, 0x7028, 0x080f, 0x7030, 0xa00d, 0x0158, 0x702c, 0x8001, + 0x702e, 0x1138, 0x702f, 0x0009, 0x8109, 0x7132, 0x1110, 0x7034, + 0x080f, 0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a, 0x703c, + 0xa005, 0x0118, 0x0310, 0x8001, 0x703e, 0x7018, 0xa00d, 0x0158, + 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, + 0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x6522, 0x6523, + 0x653b, 0x00e6, 0x2071, 0xafda, 0x7018, 0xa005, 0x1120, 0x711a, + 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, + 0xafda, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, 0x00ee, + 0x0005, 0x00e6, 0x2071, 0xafda, 0x6088, 0xa102, 0x0208, 0x618a, + 0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x4cdc, 0x1158, 0x6088, + 0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6c50, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, 0x7007, + 0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000, + 0x603c, 0xa005, 0x0128, 0x8001, 0x603e, 0x1110, 0x080c, 0x9846, + 0x6014, 0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c, 0xa186, + 0x0003, 0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068, 0x6854, + 0xa08a, 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, + 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, + 0x0010, 0x080c, 0x9350, 0x012e, 0xac88, 0x0018, 0x7116, 0x2001, + 0xe400, 0xa102, 0x0220, 0x7017, 0xb400, 0x7007, 0x0000, 0x0005, + 0x00e6, 0x2071, 0xafda, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, + 0x0005, 0x2001, 0xafe3, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, + 0xafda, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0xafe6, + 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0xafda, 0x711a, 0x721e, + 0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0xb048, 0x00ce, + 0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0xb048, + 0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, + 0xa005, 0x1150, 0x00c6, 0x2061, 0xb048, 0x6014, 0x00ce, 0xa005, + 0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006, + 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0, + 0xa18e, 0x00c0, 0x05b0, 0xd0b4, 0x1138, 0xd0bc, 0x1528, 0x2009, + 0x0006, 0x080c, 0x661a, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003, + 0x0118, 0xa086, 0x0003, 0x15c0, 0x6020, 0xd0d4, 0x0130, 0xc0d4, + 0x6022, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xad73, 0x2104, + 0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x80a7, 0x0005, 0x2009, + 0x0043, 0x080c, 0x80a7, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003, + 0x0118, 0xa086, 0x0003, 0x11c0, 0x2009, 0x0042, 0x080c, 0x80a7, + 0x0005, 0xd0fc, 0x0150, 0xa084, 0x0003, 0xa08e, 0x0002, 0x0138, + 0x2009, 0x0041, 0x080c, 0x80a7, 0x0005, 0x0051, 0x0ce8, 0x2009, + 0x0043, 0x080c, 0x80a7, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005, + 0x2009, 0x0001, 0x00d6, 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068, + 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c, + 0x8100, 0xa18e, 0x8100, 0x1158, 0x00c6, 0x2061, 0xb048, 0x6200, + 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, + 0x510c, 0x6010, 0xa06d, 0x190c, 0x65aa, 0x00de, 0x0005, 0x0156, + 0x00c6, 0x2061, 0xb048, 0x6000, 0x81ff, 0x0110, 0xa205, 0x0008, + 0xa204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, + 0x6808, 0xa005, 0x0120, 0x8001, 0x680a, 0xa085, 0x0001, 0x0005, + 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200, + 0x1f04, 0x665c, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, + 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, + 0x1220, 0x1f04, 0x666c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, + 0x666c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e, + 0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091, + 0x2800, 0x2079, 0xafc7, 0x012e, 0x00d6, 0x2069, 0xafc7, 0x6803, + 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de, + 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007, 0x0002, + 0x66aa, 0x66cb, 0x671e, 0x66b0, 0x66cb, 0x66aa, 0x66a8, 0x66a8, + 0x080c, 0x14f6, 0x080c, 0x6581, 0x080c, 0x6c50, 0x00ce, 0x0005, + 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x481b, 0x080c, + 0x650d, 0x7828, 0xa092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, + 0x4855, 0x0c88, 0x080c, 0x481b, 0x7807, 0x0003, 0x7827, 0x0000, + 0x782b, 0x0000, 0x0c40, 0x080c, 0x6581, 0x3c00, 0x0006, 0x2011, + 0x0209, 0x20e1, 0x4000, 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178, + 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c, + 0x14f6, 0x2009, 0x0013, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x3900, + 0xa082, 0xb0e8, 0x1210, 0x080c, 0x7d8d, 0x00c6, 0x7824, 0xa065, + 0x090c, 0x14f6, 0x7804, 0xa086, 0x0004, 0x0904, 0x675e, 0x7828, + 0xa092, 0x2710, 0x1230, 0x8000, 0x782a, 0x00ce, 0x080c, 0x7827, + 0x0c20, 0x6104, 0xa186, 0x0003, 0x1188, 0x00e6, 0x2071, 0xad00, + 0x70dc, 0x00ee, 0xd08c, 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100, + 0x2071, 0xad00, 0x080c, 0x485e, 0x00ee, 0x00ce, 0x080c, 0xaca2, + 0x2009, 0x0014, 0x080c, 0x80a7, 0x00ce, 0x0838, 0x2001, 0xafe3, + 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, + 0xa065, 0x090c, 0x14f6, 0x2009, 0x0013, 0x080c, 0x80fb, 0x00ce, + 0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082, 0xb0e8, 0x1210, 0x080c, + 0x7d8d, 0x7824, 0xa005, 0x090c, 0x14f6, 0x781c, 0xa06d, 0x090c, + 0x14f6, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x080c, 0x8078, + 0x693c, 0x81ff, 0x090c, 0x14f6, 0x8109, 0x693e, 0x6854, 0xa015, + 0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807, 0x0000, 0x7827, + 0x0000, 0x00de, 0x00ce, 0x080c, 0x6c50, 0x0888, 0x6104, 0xa186, + 0x0002, 0x0128, 0xa186, 0x0004, 0x0110, 0x0804, 0x66f7, 0x7808, + 0xac06, 0x0904, 0x66f7, 0x080c, 0x6b73, 0x080c, 0x67ee, 0x00ce, + 0x080c, 0x6c50, 0x0804, 0x66e5, 0x00c6, 0x6027, 0x0002, 0x62c8, + 0x60c4, 0xa205, 0x1178, 0x793c, 0xa1e5, 0x0000, 0x0130, 0x2009, + 0x0049, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x2011, 0xafe6, 0x2013, + 0x0000, 0x0cc8, 0x3908, 0xa192, 0xb0e8, 0x1210, 0x080c, 0x7d8d, + 0x793c, 0x81ff, 0x0d90, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, + 0x0006, 0x1138, 0x6014, 0xa084, 0x0184, 0xa085, 0x0012, 0x6016, + 0x0c10, 0x6014, 0xa084, 0x0184, 0xa085, 0x0016, 0x6016, 0x08d8, + 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, + 0x2c08, 0x2061, 0xafc7, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005, + 0x0148, 0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, + 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0xafc7, + 0x6000, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001, + 0x1110, 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x6c56, + 0xc0d5, 0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000, + 0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0xafc7, 0x0c18, + 0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, + 0xafc7, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080, + 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, + 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, + 0xafc7, 0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136, + 0x00ce, 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x0076, 0x0066, 0x0026, 0x0016, 0x0006, 0x0126, 0x2071, + 0xafc7, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, + 0x6889, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6884, + 0x87ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6884, 0x703c, 0xac06, + 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x7033, 0x0000, + 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x003e, 0x7038, + 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, + 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, + 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x080c, 0x9596, 0x0198, 0x6010, 0x2068, 0x601c, 0xa086, + 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, + 0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c, 0x9742, 0x080c, + 0x974e, 0x00ce, 0x0804, 0x682e, 0x2c78, 0x600c, 0x2060, 0x0804, + 0x682e, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e, 0x007e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19d0, + 0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x0006, 0x0066, 0x00c6, + 0x00d6, 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079, + 0xafc7, 0x7838, 0xa065, 0x0558, 0x600c, 0x0006, 0x600f, 0x0000, + 0x783c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, + 0x7833, 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, + 0x003e, 0x080c, 0x9596, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086, + 0x0003, 0x11b0, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, + 0x510c, 0x080c, 0x9742, 0x080c, 0x974e, 0x000e, 0x0898, 0x7e3a, + 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, + 0x601c, 0xa086, 0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c60, 0x0016, + 0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x69a9, 0x008e, + 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0xafc7, 0x2091, + 0x8000, 0x080c, 0x6a36, 0x080c, 0x6aa8, 0x012e, 0x00fe, 0x0005, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x8cff, + 0x0904, 0x6985, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, + 0x6980, 0x88ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6980, 0x7024, + 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, + 0x6581, 0x080c, 0x7834, 0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7027, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, + 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, + 0x04b8, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, + 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, + 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, + 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x9596, 0x0188, + 0x601c, 0xa086, 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c, + 0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804, 0x690f, + 0x2c78, 0x600c, 0x2060, 0x0804, 0x690f, 0x012e, 0x000e, 0x001e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, + 0x0006, 0x1128, 0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x601c, + 0xa086, 0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x0968, 0x08c8, + 0x601c, 0xa086, 0x0005, 0x19a8, 0x6004, 0xa086, 0x0085, 0x0d50, + 0x0880, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0xa280, 0xae34, + 0x2004, 0xa065, 0x0904, 0x6a32, 0x00f6, 0x00e6, 0x00d6, 0x0066, + 0x2071, 0xafc7, 0x6654, 0x7018, 0xac06, 0x1108, 0x761a, 0x701c, + 0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, + 0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000, 0x0110, 0x2f00, + 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, + 0x6002, 0x080c, 0x4c07, 0x0904, 0x6a2e, 0x7624, 0x86ff, 0x05e8, + 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, + 0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834, 0x68c3, + 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, + 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, + 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, + 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660, + 0x080c, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, + 0x0009, 0x630a, 0x00ce, 0x0804, 0x69d9, 0x8dff, 0x0158, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa, + 0x080c, 0x510c, 0x080c, 0x7b88, 0x0804, 0x69d9, 0x006e, 0x00de, + 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066, + 0x00c6, 0x00d6, 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x6a88, + 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069, + 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x6581, 0x080c, 0x7834, + 0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7827, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, + 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010, + 0x2068, 0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, + 0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x000e, 0x0804, 0x6a3d, + 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c, + 0xa086, 0x0006, 0x1118, 0x080c, 0xa91f, 0x0c58, 0x601c, 0xa086, + 0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x09d0, 0x0c10, 0x601c, + 0xa086, 0x0005, 0x19f0, 0x6004, 0xa086, 0x0085, 0x0d60, 0x08c8, + 0x0006, 0x0066, 0x00c6, 0x00d6, 0x7818, 0xa065, 0x0904, 0x6b0e, + 0x6054, 0x0006, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, + 0xc0dc, 0x6002, 0x080c, 0x4c07, 0x0904, 0x6b0b, 0x7e24, 0x86ff, + 0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, + 0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834, + 0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7827, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, + 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, + 0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, + 0x2660, 0x080c, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, + 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6aba, 0x8dff, 0x0138, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, + 0x7b88, 0x0804, 0x6aba, 0x000e, 0x0804, 0x6aad, 0x781e, 0x781a, + 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0066, + 0x6000, 0xd0dc, 0x0188, 0x604c, 0xa06d, 0x0170, 0x6848, 0xa606, + 0x1158, 0x2071, 0xafc7, 0x7024, 0xa035, 0x0130, 0xa080, 0x0004, + 0x2004, 0xad06, 0x1108, 0x0021, 0x006e, 0x00de, 0x00ee, 0x0005, + 0x00f6, 0x2079, 0x0100, 0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660, + 0x6003, 0x0009, 0x630a, 0x00ce, 0x04a0, 0x080c, 0x7834, 0x78c3, + 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, + 0x7b04, 0xa384, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, + 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, + 0x7ca8, 0x003e, 0x080c, 0x4c07, 0x00c6, 0x603c, 0xa005, 0x0110, + 0x8001, 0x603e, 0x2660, 0x080c, 0x8078, 0x00ce, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x080c, + 0x7b88, 0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2071, 0xafc7, 0x7004, + 0xa084, 0x0007, 0x0002, 0x6b85, 0x6b88, 0x6b9e, 0x6bb7, 0x6bf0, + 0x6b85, 0x6b83, 0x6b83, 0x080c, 0x14f6, 0x00ce, 0x00ee, 0x0005, + 0x7024, 0xa065, 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, + 0x0150, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, + 0x00ce, 0x00ee, 0x0005, 0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060, + 0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, + 0x0120, 0x6054, 0xa015, 0x0140, 0x721e, 0x7007, 0x0000, 0x7027, + 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024, + 0xa065, 0x0598, 0x700c, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c, + 0xa015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0428, 0x720e, 0x720a, + 0x0410, 0x7014, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c, 0xa015, + 0x0120, 0x7216, 0x600f, 0x0000, 0x00b0, 0x7216, 0x7212, 0x0098, + 0x6018, 0x2060, 0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x080c, + 0x7b88, 0x701c, 0xa065, 0x0138, 0x6054, 0xa015, 0x0110, 0x721e, + 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, + 0x7024, 0xa065, 0x0140, 0x080c, 0x7b88, 0x600c, 0xa015, 0x0150, + 0x720e, 0x600f, 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x00ce, + 0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069, 0xafc7, + 0x6830, 0xa084, 0x0003, 0x0002, 0x6c12, 0x6c14, 0x6c38, 0x6c10, + 0x080c, 0x14f6, 0x00de, 0x0005, 0x00c6, 0x6840, 0xa086, 0x0001, + 0x01b8, 0x683c, 0xa065, 0x0130, 0x600c, 0xa015, 0x0170, 0x6a3a, + 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0xafe6, + 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90, + 0x6843, 0x0000, 0x6838, 0xa065, 0x0d68, 0x6003, 0x0003, 0x0c50, + 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0168, + 0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, + 0x0020, 0x683f, 0x0000, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, + 0x00d6, 0x2069, 0xafc7, 0x6804, 0xa084, 0x0007, 0x0002, 0x6c61, + 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cff, 0x6c5f, 0x6c5f, 0x080c, + 0x14f6, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, + 0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, + 0x6d49, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150, 0x6807, + 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x6d49, 0x00ce, 0x00de, + 0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x6cf9, + 0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054, 0xa075, + 0x0120, 0xa20e, 0x0904, 0x6cf9, 0x0028, 0x6818, 0xa20e, 0x0904, + 0x6cf9, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70, + 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c, 0x804f, + 0x0904, 0x6cf9, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180, + 0x0014, 0x2004, 0xa084, 0x00ff, 0x605a, 0xa180, 0x0014, 0x2003, + 0x0000, 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001, + 0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6, + 0x2c78, 0x71a0, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd1bc, + 0x0150, 0x7100, 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040, + 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c, 0x00ff, + 0x2061, 0x0100, 0x619a, 0x080c, 0x736f, 0x7300, 0xc3dd, 0x7302, + 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, + 0x7803, 0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de, + 0x0005, 0x003e, 0x00ee, 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6, + 0x680c, 0xa065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, + 0x080c, 0x6d49, 0x00ce, 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069, + 0xafc7, 0x6830, 0xa086, 0x0000, 0x11c0, 0x2001, 0xad0c, 0x200c, + 0xd1bc, 0x1550, 0x6838, 0xa07d, 0x0180, 0x6833, 0x0001, 0x683e, + 0x6847, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, + 0x1ee6, 0x1130, 0x012e, 0x080c, 0x76a5, 0x00de, 0x00fe, 0x0005, + 0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, + 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, + 0x0c60, 0x683a, 0x6836, 0x0cc0, 0xc1bc, 0x2102, 0x080c, 0x57d1, + 0x0888, 0x601c, 0xa084, 0x000f, 0x000b, 0x0005, 0x6d57, 0x6d5c, + 0x7210, 0x732c, 0x6d5c, 0x7210, 0x732c, 0x6d57, 0x6d5c, 0x080c, + 0x6b73, 0x080c, 0x6c50, 0x0005, 0x0156, 0x0136, 0x0146, 0x00c6, + 0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x6118, 0x2178, + 0x79a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, + 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009, + 0x0000, 0x0028, 0xa1f8, 0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78, + 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x1a04, 0x6dd0, 0x0033, + 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x6e7c, 0x6ec7, + 0x6ef4, 0x6fc1, 0x6fef, 0x6ff7, 0x701d, 0x702e, 0x703f, 0x7047, + 0x705d, 0x7047, 0x70b7, 0x702e, 0x70d8, 0x70e0, 0x703f, 0x70e0, + 0x70f1, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, + 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x790d, 0x7932, 0x7947, 0x796a, + 0x798b, 0x701d, 0x6dce, 0x701d, 0x7047, 0x6dce, 0x6ef4, 0x6fc1, + 0x6dce, 0x7daa, 0x7047, 0x6dce, 0x7dca, 0x7047, 0x6dce, 0x703f, + 0x6e75, 0x6de0, 0x6dce, 0x7def, 0x7e64, 0x7f3b, 0x6dce, 0x7f4c, + 0x7018, 0x7f68, 0x6dce, 0x79a0, 0x7fc3, 0x6dce, 0x080c, 0x14f6, + 0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, + 0x6dde, 0x6dde, 0x6dde, 0x6e14, 0x6e32, 0x6e48, 0x080c, 0x14f6, + 0x00d6, 0x20a1, 0x020b, 0x080c, 0x710e, 0x7810, 0x2068, 0x20a3, + 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6850, + 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0018, 0x080c, 0x7821, 0x00de, 0x0005, 0x00d6, 0x7818, 0x2068, + 0x68a0, 0x2069, 0xad00, 0x6ad0, 0xd2ac, 0x1110, 0xd0bc, 0x0110, + 0xa085, 0x0001, 0x00de, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, + 0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8, 0x000f, + 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814, 0x20a2, + 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x080c, 0x7821, + 0x00de, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e, + 0x20a3, 0x7800, 0x20a3, 0x0000, 0x7808, 0x8007, 0x20a2, 0x20a3, + 0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, + 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, + 0x20a3, 0x0000, 0x20a3, 0xdf10, 0x20a3, 0x0034, 0x2099, 0xad05, + 0x20a9, 0x0004, 0x53a6, 0x2099, 0xad01, 0x20a9, 0x0004, 0x53a6, + 0x2099, 0xafad, 0x20a9, 0x001a, 0x3304, 0x8007, 0x20a2, 0x9398, + 0x1f04, 0x6e64, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x004c, + 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x2001, 0xad14, 0x2004, + 0x609a, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e, + 0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0xad51, 0x6804, + 0xd084, 0x0150, 0x6828, 0x20a3, 0x0000, 0x0016, 0x080c, 0x268a, + 0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004, + 0x2099, 0xad01, 0x53a6, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1138, + 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0238, 0x2001, + 0xad1b, 0x20a6, 0x2001, 0xad1c, 0x20a6, 0x0040, 0x20a3, 0x0000, + 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001, + 0xad34, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, + 0xa082, 0x007f, 0x0238, 0x2001, 0xad1b, 0x20a6, 0x2001, 0xad1c, + 0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xad14, 0x2004, 0xa084, + 0x00ff, 0x20a2, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x60c3, + 0x0010, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e, + 0x00c6, 0x7818, 0x2060, 0x2001, 0x0000, 0x080c, 0x5037, 0x00ce, + 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1130, 0x20a3, + 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3, + 0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1904, + 0x6f83, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x01c8, 0x2099, 0xaf8d, + 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x3304, 0xa084, 0x2000, + 0x20a2, 0x9398, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x2001, + 0x2710, 0x20a2, 0x9398, 0x33a6, 0x9398, 0x33a6, 0x00d0, 0x2099, + 0xaf8d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0x080c, 0x574f, + 0x1118, 0xa084, 0x37ff, 0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398, + 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004, + 0x2099, 0xad01, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, + 0x6f5d, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6f63, 0x2099, + 0xaf95, 0x3304, 0xc0dd, 0x20a2, 0x2001, 0xad71, 0x2004, 0xd0e4, + 0x0158, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, + 0x33a6, 0x20a9, 0x0004, 0x0010, 0x20a9, 0x0007, 0x20a3, 0x0000, + 0x1f04, 0x6f7e, 0x0468, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x0140, + 0x2001, 0xaf8e, 0x2004, 0x60e3, 0x0000, 0x080c, 0x26cb, 0x60e2, + 0x2099, 0xaf8d, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, + 0xad05, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xad01, 0x53a6, 0x20a9, + 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fa1, 0x20a9, 0x0008, 0x20a3, + 0x0000, 0x1f04, 0x6fa7, 0x2099, 0xaf95, 0x20a9, 0x0008, 0x53a6, + 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fb2, 0x20a9, 0x000a, + 0x20a3, 0x0000, 0x1f04, 0x6fb8, 0x60c3, 0x0074, 0x080c, 0x7821, + 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x2010, 0x20a3, + 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51, 0x7904, 0x00fe, + 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, + 0xa085, 0x0002, 0x00d6, 0x0804, 0x7099, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x710e, 0x20a3, 0x5000, 0x0804, 0x6f0f, 0x20a1, + 0x020b, 0x080c, 0x710e, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005, + 0x20a1, 0x020b, 0x080c, 0x71a2, 0x0020, 0x20a1, 0x020b, 0x080c, + 0x71aa, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, + 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, + 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6f0f, 0x20a1, + 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, + 0xa005, 0x0110, 0x20a2, 0x0010, 0x20a3, 0x0003, 0x7810, 0x20a2, + 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x00d6, 0x20a1, 0x020b, + 0x080c, 0x71aa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, + 0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x1178, 0x6998, 0xa184, + 0xc000, 0x1140, 0xd1ec, 0x0118, 0x20a3, 0x2100, 0x0040, 0x20a3, + 0x0100, 0x0028, 0x20a3, 0x0400, 0x0010, 0x20a3, 0x0700, 0xa006, + 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51, + 0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, + 0xa085, 0x0010, 0x2009, 0xad73, 0x210c, 0xd184, 0x1110, 0xa085, + 0x0002, 0x0026, 0x2009, 0xad71, 0x210c, 0xd1e4, 0x0130, 0xc0c5, + 0xa094, 0x0030, 0xa296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0xa094, + 0x0030, 0xa296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x20a2, 0x20a2, + 0x20a2, 0x60c3, 0x0014, 0x080c, 0x7821, 0x00de, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, + 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005, + 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6e82, + 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, + 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821, + 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c, + 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, + 0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x0026, 0x0036, + 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0038, 0x0026, 0x0036, + 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x11a0, + 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011, + 0xad14, 0x2214, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x0118, 0x2011, + 0xad1c, 0x2214, 0x22a2, 0x04d0, 0xa286, 0x007f, 0x1138, 0x00d6, + 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0xad34, + 0x2004, 0xd0ac, 0x1110, 0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6, + 0x1130, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0040, 0xa2e8, + 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, + 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa2e8, + 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, + 0x20a3, 0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0029, + 0x20a2, 0x004e, 0x003e, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2, + 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x002e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x20a3, 0x02ff, 0x2011, 0xfffc, 0x22a2, 0x00d6, 0x2069, 0xad1b, + 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000, + 0x08e0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, + 0x0000, 0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, + 0x0800, 0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021, + 0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, + 0x02d8, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, + 0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005, 0x1128, + 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0xad1b, 0x2da6, + 0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, + 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, + 0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, + 0x0000, 0x004e, 0x003e, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000, + 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, + 0x0005, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, + 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, + 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a, + 0x008c, 0x1a0c, 0x14f6, 0x6118, 0x2178, 0x79a0, 0x2011, 0xad34, + 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, + 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, + 0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, + 0xa082, 0x0085, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x7247, 0x7251, + 0x726c, 0x7245, 0x7245, 0x7245, 0x7247, 0x080c, 0x14f6, 0x0146, + 0x20a1, 0x020b, 0x04a1, 0x60c3, 0x0000, 0x080c, 0x7821, 0x014e, + 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x72b8, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, + 0x080c, 0x7821, 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, + 0x72f2, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x014e, 0x0005, 0x0026, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, + 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, + 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100, + 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, + 0x2214, 0x22a2, 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804, 0x7175, + 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, + 0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8400, + 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, + 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, + 0x8400, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, + 0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000, + 0x0804, 0x7201, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, + 0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, + 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, + 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, + 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, + 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, + 0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, + 0x20a3, 0x0000, 0x0804, 0x7201, 0x00c6, 0x00f6, 0x2c78, 0x7804, + 0xa08a, 0x0040, 0x0a0c, 0x14f6, 0xa08a, 0x0053, 0x1a0c, 0x14f6, + 0x7918, 0x2160, 0x61a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, + 0xd1bc, 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff, + 0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c, + 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x001b, 0x00fe, + 0x00ce, 0x0005, 0x736f, 0x747b, 0x7418, 0x761a, 0x736d, 0x736d, + 0x736d, 0x736d, 0x736d, 0x736d, 0x736d, 0x7b41, 0x7b51, 0x7b61, + 0x7b71, 0x736d, 0x7f79, 0x736d, 0x7b30, 0x080c, 0x14f6, 0x00d6, + 0x0156, 0x0146, 0x780b, 0xffff, 0x20a1, 0x020b, 0x080c, 0x73cf, + 0x7910, 0x2168, 0x6948, 0x7952, 0x21a2, 0xa016, 0x22a2, 0x22a2, + 0x22a2, 0x694c, 0xa184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, + 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0xa084, 0x0006, 0x8004, + 0x0016, 0x2008, 0x7858, 0xa084, 0x00ff, 0x8007, 0xa105, 0x001e, + 0x20a2, 0xd1ac, 0x0118, 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118, + 0x20a3, 0x0001, 0x0020, 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80, + 0x6e7c, 0x20a9, 0x0008, 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1, + 0x021b, 0x53a6, 0x013e, 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3, + 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, + 0x6016, 0x2001, 0xafe3, 0x2003, 0x07d0, 0x2001, 0xafe2, 0x2003, + 0x0009, 0x080c, 0x17bf, 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, + 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, + 0x2019, 0xad34, 0x231c, 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, + 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, + 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, + 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2009, 0xad14, 0x210c, + 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000, + 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, + 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810, + 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, + 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, + 0x080c, 0x7821, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, + 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, + 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, + 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, + 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, 0x2214, + 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2, + 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x7810, + 0xa06d, 0x080c, 0x5025, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086, + 0x2020, 0x1118, 0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c, + 0x75d0, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, + 0xa084, 0xf000, 0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043, + 0x0010, 0xa006, 0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, + 0x74b2, 0x7547, 0x7550, 0x7579, 0x758c, 0x75a7, 0x75b0, 0x74b0, + 0x080c, 0x14f6, 0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118, + 0xa186, 0x0003, 0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5, + 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804, + 0x7583, 0xa186, 0x0001, 0x190c, 0x14f6, 0x6b78, 0x7820, 0xd0cc, + 0x0108, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, + 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384, + 0x0300, 0x0904, 0x7541, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc, + 0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020, + 0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x74f0, 0x015e, 0x22a2, + 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0904, 0x7541, 0x20a1, 0x020b, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028, + 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, + 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, + 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, + 0x2214, 0x22a2, 0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889, + 0x0010, 0x20a3, 0x0898, 0x20a2, 0x080c, 0x7810, 0x22a2, 0x20a3, + 0x0000, 0x61c2, 0x003e, 0x001e, 0x080c, 0x7821, 0x0005, 0x2011, + 0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0488, + 0x2011, 0x0302, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, + 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500, + 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x080c, 0x7821, + 0x0005, 0x2011, 0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, + 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, + 0x0018, 0x080c, 0x7821, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc, + 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, + 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2, + 0x22a2, 0x22a2, 0x60c3, 0x0020, 0x080c, 0x7821, 0x0005, 0x2011, + 0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888, + 0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, + 0x1138, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808, + 0x0046, 0x2021, 0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108, + 0xc4e5, 0x24a2, 0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7583, + 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, + 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, + 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, + 0x2214, 0x22a2, 0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010, + 0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2, 0x20a3, + 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x0016, 0x0036, + 0x7810, 0xa084, 0x0700, 0x8007, 0x003b, 0x003e, 0x001e, 0x014e, + 0x013e, 0x015e, 0x00de, 0x0005, 0x7634, 0x7634, 0x7636, 0x7634, + 0x7634, 0x7634, 0x7658, 0x7634, 0x080c, 0x14f6, 0x7910, 0xa18c, + 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, + 0x00f9, 0x00d6, 0x2069, 0xad51, 0x6804, 0xd0bc, 0x0130, 0x682c, + 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de, + 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x080c, 0x7821, 0x0005, + 0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80, + 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, + 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100, + 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, + 0x2214, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c, + 0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6, + 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0xad00, 0x7150, + 0x7818, 0x2068, 0x68a0, 0x2028, 0x76d0, 0xd6ac, 0x1130, 0xd0bc, + 0x1120, 0x6910, 0x6a14, 0x7450, 0x0020, 0x6910, 0x6a14, 0x736c, + 0x7470, 0x781c, 0xa0be, 0x0006, 0x0904, 0x775b, 0xa0be, 0x000a, + 0x15e8, 0xa185, 0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, + 0x2029, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, + 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, + 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, + 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0x609f, 0x0000, 0x080c, 0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084, + 0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x6586, 0x003e, + 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d0, 0xd0ac, + 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, + 0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, + 0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, + 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, + 0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, + 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, + 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, + 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, + 0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110, + 0x2009, 0x1b58, 0x080c, 0x6586, 0x003e, 0x004e, 0x005e, 0x00ce, + 0x00de, 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, + 0xa086, 0x0002, 0x0904, 0x77b1, 0x2001, 0xad34, 0x2004, 0xd0ac, + 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, + 0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, + 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, + 0x00ff, 0x688e, 0x8007, 0x607a, 0x7834, 0x607e, 0x2f00, 0x6086, + 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, + 0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928, + 0xa109, 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, + 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x8011, 0x0804, + 0x7749, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, + 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185, + 0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x5025, + 0x0180, 0x00d6, 0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020, + 0xa086, 0x2020, 0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889, + 0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, + 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, + 0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, + 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, + 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x7820, 0xd0cc, 0x0120, + 0x080c, 0x8014, 0x0804, 0x7749, 0x080c, 0x8011, 0x0804, 0x7749, + 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, + 0x8217, 0x0005, 0x00d6, 0x2069, 0xafc7, 0x6843, 0x0001, 0x00de, + 0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019, + 0x080c, 0x6578, 0x0005, 0x0006, 0x6014, 0xa084, 0x0004, 0xa085, + 0x0009, 0x6016, 0x000e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, + 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, 0x00ce, 0x000e, + 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, + 0x0140, 0x080c, 0x574f, 0x1178, 0x2001, 0xafe3, 0x2004, 0xa005, + 0x1598, 0x080c, 0x57d1, 0x1118, 0x080c, 0x6578, 0x0468, 0x00c6, + 0x2061, 0xafc7, 0x00d8, 0x6904, 0xa194, 0x4000, 0x0550, 0x08a1, + 0x6803, 0x1000, 0x6803, 0x0000, 0x00c6, 0x2061, 0xafc7, 0x6128, + 0xa192, 0x00c8, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, + 0x0198, 0x080c, 0x6578, 0x080c, 0x782b, 0x0070, 0x6124, 0xa1e5, + 0x0000, 0x0140, 0x080c, 0xaca2, 0x2009, 0x0014, 0x080c, 0x80a7, + 0x080c, 0x6581, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, + 0x0005, 0x2001, 0xafe3, 0x2004, 0xa005, 0x1db0, 0x00c6, 0x2061, + 0xafc7, 0x6128, 0xa192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, + 0x080c, 0x6578, 0x080c, 0x485e, 0x0c38, 0x00c6, 0x00d6, 0x00e6, + 0x0016, 0x0026, 0x080c, 0x658e, 0x2071, 0xafc7, 0x713c, 0x81ff, + 0x0570, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x574f, 0x1188, + 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c, 0x2160, + 0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x080c, 0x57d1, + 0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, 0x6803, + 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c, + 0x2160, 0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x002e, + 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, + 0x6018, 0x2068, 0x6ca0, 0x2071, 0xafc7, 0x7018, 0x2068, 0x8dff, + 0x0198, 0x68a0, 0xa406, 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010, + 0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x080c, 0x4e41, 0x0120, + 0x080c, 0x7b88, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1, 0x020b, 0x080c, + 0x710e, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c, + 0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001, 0xad14, 0x2004, + 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006, + 0x20a2, 0x1f04, 0x7928, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x080c, + 0x7821, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e, + 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, + 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x0156, + 0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x20a3, + 0x0000, 0x20a9, 0x0006, 0x2011, 0xad40, 0x2019, 0xad41, 0x23a6, + 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x7957, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x014e, + 0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, + 0x080c, 0x7183, 0x080c, 0x7199, 0x7810, 0xa080, 0x0000, 0x2004, + 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, + 0xa080, 0x0004, 0x8003, 0x60c2, 0x080c, 0x7821, 0x002e, 0x001e, + 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, + 0x710e, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, + 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, + 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x710e, + 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808, + 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x080c, 0x7821, + 0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x700c, 0x2060, 0x8cff, + 0x0178, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x600c, 0x0006, + 0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x7b88, 0x00ce, 0x0c78, + 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce, 0x00ee, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026, + 0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, + 0x2071, 0xafc7, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, 0x7834, + 0x68c3, 0x0000, 0x080c, 0x6581, 0x2009, 0x0013, 0x080c, 0x80a7, + 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, + 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, + 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x7a02, 0x7804, + 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, + 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, + 0x012e, 0x0005, 0x2001, 0xad00, 0x2004, 0xa096, 0x0001, 0x0550, + 0xa096, 0x0004, 0x0538, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, + 0x481b, 0x080c, 0x650d, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, + 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, + 0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, + 0x1f04, 0x7a3d, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, + 0x7803, 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, + 0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069, + 0x0100, 0x2079, 0x0140, 0x2071, 0xafc7, 0x703c, 0x2060, 0x8cff, + 0x0904, 0x7ad5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, + 0x68c7, 0x0000, 0x68cb, 0x0008, 0x080c, 0x658e, 0x080c, 0x20b5, + 0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404, + 0xa084, 0x000f, 0xa086, 0x0004, 0x11b0, 0x68c7, 0x0000, 0x68cb, + 0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020, 0x2071, 0xb01e, 0x6814, + 0xa084, 0x0184, 0xa085, 0x0012, 0x6816, 0x7803, 0x0008, 0x7003, + 0x0000, 0x00fe, 0x00ee, 0x200b, 0x0000, 0x004e, 0xa39d, 0x0000, + 0x1120, 0x2009, 0x0049, 0x080c, 0x80a7, 0x20a9, 0x03e8, 0x6824, + 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, + 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd08c, 0x0118, 0x6827, + 0x0002, 0x0010, 0x1f04, 0x7ab7, 0x7804, 0xa084, 0x1000, 0x0120, + 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e, + 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, + 0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a06, 0x012e, 0x00de, + 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a32, + 0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006, + 0x0126, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000, + 0x8cff, 0x0538, 0x601c, 0xa206, 0x1500, 0x7014, 0xac36, 0x1110, + 0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, + 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, + 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, + 0x974e, 0x080c, 0x7b88, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060, + 0x08b8, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, 0x20a2, + 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804, + 0x7b80, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, + 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, + 0x0478, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, + 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, + 0x00f8, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, + 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, + 0x0078, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, + 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, + 0x0089, 0x60c3, 0x0020, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, + 0x00e6, 0x2071, 0xafc7, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022, + 0x00ee, 0x0005, 0x20a9, 0x0008, 0x20a2, 0x1f04, 0x7b94, 0x20a2, + 0x20a2, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660, + 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x7c24, 0x8cff, 0x0904, + 0x7c24, 0x601c, 0xa086, 0x0006, 0x1904, 0x7c1f, 0x88ff, 0x0138, + 0x2800, 0xac06, 0x1904, 0x7c1f, 0x2039, 0x0000, 0x0050, 0x6018, + 0xa206, 0x1904, 0x7c1f, 0x85ff, 0x0120, 0x6050, 0xa106, 0x1904, + 0x7c1f, 0x7024, 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, + 0x01f0, 0x080c, 0x6581, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, + 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, + 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, + 0x0009, 0x630a, 0x0460, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, + 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, + 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, + 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1158, 0x600f, 0x0000, 0x6010, + 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e, + 0x080c, 0x7b88, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x7bab, 0x2c78, + 0x600c, 0x2060, 0x0804, 0x7bab, 0xa006, 0x012e, 0x000e, 0x006e, + 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000, + 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x00c6, + 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, + 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x7c98, 0x601c, 0xa086, + 0x0006, 0x1904, 0x7c93, 0x87ff, 0x0128, 0x2700, 0xac06, 0x1904, + 0x7c93, 0x0040, 0x6018, 0xa206, 0x15f0, 0x85ff, 0x0118, 0x6050, + 0xa106, 0x15c8, 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, + 0x080c, 0x7a64, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, + 0x7047, 0x0000, 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, + 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, + 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, + 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, + 0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e, 0x87ff, 0x1190, + 0x00ce, 0x0804, 0x7c43, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7c43, + 0xa006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa7bd, 0x0001, 0x0c88, + 0x00e6, 0x2071, 0xafc7, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002, + 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0xafc7, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, + 0x0518, 0x2200, 0xac06, 0x11e0, 0x7038, 0xac36, 0x1110, 0x660c, + 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, + 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0110, + 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0020, + 0x2c78, 0x600c, 0x2060, 0x08d8, 0x012e, 0x000e, 0x002e, 0x006e, + 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, + 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x760c, + 0x2660, 0x2678, 0x8cff, 0x0904, 0x7d7e, 0x6018, 0xa080, 0x0028, + 0x2004, 0xa206, 0x1904, 0x7d79, 0x7024, 0xac06, 0x1508, 0x2069, + 0x0100, 0x68c0, 0xa005, 0x0904, 0x7d55, 0x080c, 0x7834, 0x68c3, + 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, + 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, + 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, + 0x700c, 0xac36, 0x1110, 0x660c, 0x760e, 0x7008, 0xac36, 0x1140, + 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, + 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, + 0x600f, 0x0000, 0x080c, 0x9778, 0x1158, 0x080c, 0x2aff, 0x080c, + 0x9789, 0x11f0, 0x080c, 0x85f3, 0x00d8, 0x080c, 0x7ca8, 0x08c0, + 0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0090, 0x6010, 0x2068, + 0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742, + 0x080c, 0x994e, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804, + 0x7d02, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7d02, 0x012e, 0x000e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, + 0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c18, 0x0036, 0x0156, 0x0136, + 0x0146, 0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x28f9, + 0x1118, 0x8210, 0x8000, 0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020, + 0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e, + 0x003e, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, + 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x2099, 0xafa6, 0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004, + 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x080c, 0x7821, + 0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0214, + 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7821, 0x0005, 0x00d6, + 0x0016, 0x2f68, 0x2009, 0x0035, 0x080c, 0x9a34, 0x1904, 0x7e5d, + 0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x1300, 0x20a3, 0x0000, + 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0580, 0x7818, 0xa080, + 0x0028, 0x2014, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x11d0, 0xa286, + 0x007e, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x04b8, 0xa286, + 0x007f, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0478, 0xd2bc, + 0x0180, 0xa286, 0x0080, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffc, + 0x0428, 0xa2e8, 0xae34, 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, + 0x00e8, 0x20a3, 0x0000, 0x6098, 0x20a2, 0x00c0, 0x2001, 0xad34, + 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, + 0x007e, 0x0240, 0x00d6, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, + 0x00de, 0x0020, 0x20a3, 0x0000, 0x6034, 0x20a2, 0x7834, 0x20a2, + 0x7838, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, + 0x080c, 0x7821, 0x001e, 0x00de, 0x0005, 0x7817, 0x0001, 0x7803, + 0x0006, 0x001e, 0x00de, 0x0005, 0x00d6, 0x0026, 0x7928, 0x2168, + 0x691c, 0xa186, 0x0006, 0x01c0, 0xa186, 0x0003, 0x0904, 0x7ed3, + 0xa186, 0x0005, 0x0904, 0x7ebc, 0xa186, 0x0004, 0x05b8, 0xa186, + 0x0008, 0x0904, 0x7ec4, 0x7807, 0x0037, 0x7813, 0x1700, 0x080c, + 0x7f3b, 0x002e, 0x00de, 0x0005, 0x080c, 0x7ef7, 0x2009, 0x4000, + 0x6800, 0x0002, 0x7e9d, 0x7ea8, 0x7e9f, 0x7ea8, 0x7ea4, 0x7e9d, + 0x7e9d, 0x7ea8, 0x7ea8, 0x7ea8, 0x7ea8, 0x7e9d, 0x7e9d, 0x7e9d, + 0x7e9d, 0x7e9d, 0x7ea8, 0x7e9d, 0x7ea8, 0x080c, 0x14f6, 0x6820, + 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0xa00e, 0x0010, 0x2009, 0x2000, + 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0804, 0x7eed, 0x080c, 0x7ef7, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0x6a00, 0xa286, + 0x0002, 0x1108, 0xa00e, 0x0488, 0x04d1, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x2009, 0x4000, 0x0448, 0x0491, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x2009, 0x4000, 0xa286, 0x0005, 0x0118, 0xa286, 0x0002, + 0x1108, 0xa00e, 0x00d0, 0x0419, 0x6810, 0x2068, 0x697c, 0x6810, + 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2, 0x22a2, 0x7928, 0xa180, + 0x0000, 0x2004, 0xa08e, 0x0002, 0x0130, 0xa08e, 0x0004, 0x0118, + 0x2009, 0x4000, 0x0010, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, + 0x60c3, 0x0018, 0x080c, 0x7821, 0x002e, 0x00de, 0x0005, 0x0036, + 0x0046, 0x0056, 0x0066, 0x20a1, 0x020b, 0x080c, 0x71aa, 0xa006, + 0x20a3, 0x0200, 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, + 0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, + 0xa092, 0x007e, 0x0268, 0x00d6, 0x2069, 0xad1b, 0x2d2c, 0x8d68, + 0x2d34, 0xa0e8, 0xae34, 0x2d6c, 0x6b10, 0x6c14, 0x00de, 0x0030, + 0x2019, 0x0000, 0x6498, 0x2029, 0x0000, 0x6634, 0x7828, 0xa080, + 0x0007, 0x2004, 0xa086, 0x0003, 0x1128, 0x25a2, 0x26a2, 0x23a2, + 0x24a2, 0x0020, 0x23a2, 0x24a2, 0x25a2, 0x26a2, 0x006e, 0x005e, + 0x004e, 0x003e, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, + 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, + 0x0008, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7106, + 0x20a3, 0x1400, 0x20a3, 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, + 0x7828, 0x20a2, 0x782c, 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, + 0x20a2, 0x20a3, 0x0000, 0x60c3, 0x0010, 0x080c, 0x7821, 0x0005, + 0x20a1, 0x020b, 0x080c, 0x71a2, 0x20a3, 0x0100, 0x20a3, 0x0000, + 0x7828, 0x20a2, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821, + 0x0005, 0x0146, 0x20a1, 0x020b, 0x0031, 0x60c3, 0x0000, 0x080c, + 0x7821, 0x014e, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, + 0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, + 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, + 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, + 0x2da6, 0x00de, 0x0078, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, + 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, + 0x6234, 0x22a2, 0x20a3, 0x0819, 0x20a3, 0x0000, 0x080c, 0x7810, + 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x7a08, 0x22a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x0005, 0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2, + 0x20a3, 0x0000, 0x60c3, 0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575, + 0x080c, 0x782b, 0x080c, 0x6578, 0x0005, 0x0156, 0x0136, 0x0036, + 0x00d6, 0x00e6, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7854, 0x2068, + 0xadf0, 0x000f, 0x7210, 0xa296, 0x00c0, 0xa294, 0xfffd, 0x7212, + 0x7214, 0xa294, 0x0300, 0x7216, 0x7100, 0xa194, 0x00ff, 0x7308, + 0xa384, 0x00ff, 0xa08d, 0xc200, 0x7102, 0xa384, 0xff00, 0xa215, + 0x720a, 0x7004, 0x720c, 0x700e, 0x7206, 0x20a9, 0x000a, 0x2e98, + 0x53a6, 0x60a3, 0x0035, 0x6a38, 0xa294, 0x7000, 0xa286, 0x3000, + 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x003e, 0x013e, 0x015e, + 0x0005, 0x2009, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, + 0x6116, 0x0005, 0x2061, 0xb400, 0x2a70, 0x7064, 0x7046, 0x704b, + 0xb400, 0x0005, 0x00e6, 0x0126, 0x2071, 0xad00, 0x2091, 0x8000, + 0x7544, 0xa582, 0x0010, 0x0608, 0x7048, 0x2060, 0x6000, 0xa086, + 0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0, + 0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, + 0x0018, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085, 0x0001, 0x012e, + 0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, + 0x2071, 0xad00, 0x7544, 0xa582, 0x0010, 0x0600, 0x7048, 0x2060, + 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02, + 0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529, + 0x7546, 0xaca8, 0x0018, 0x7058, 0xa502, 0x1228, 0x754a, 0xa085, + 0x0001, 0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc8, 0xa006, 0x0cc8, + 0xac82, 0xb400, 0x0a0c, 0x14f6, 0x2001, 0xad16, 0x2004, 0xac02, + 0x1a0c, 0x14f6, 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016, + 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6052, 0x6056, 0x6022, + 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x2061, + 0xad00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108, 0x0005, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0cc0, 0x601c, + 0xa084, 0x000f, 0x0002, 0x80b6, 0x80c5, 0x80e0, 0x80fb, 0x9a61, + 0x9a7c, 0x9a97, 0x80b6, 0x80c5, 0x80b6, 0x8116, 0xa186, 0x0013, + 0x1128, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x0005, 0xa18e, 0x0047, + 0x1118, 0xa016, 0x080c, 0x1824, 0x0005, 0x0066, 0x6000, 0xa0b2, + 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x80de, 0x8478, + 0x862d, 0x80de, 0x86a2, 0x81cf, 0x80de, 0x80de, 0x840a, 0x8a91, + 0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x080c, 0x14f6, + 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, + 0x0005, 0x80f9, 0x909a, 0x80f9, 0x80f9, 0x80f9, 0x80f9, 0x80f9, + 0x80f9, 0x9045, 0x9200, 0x80f9, 0x90c7, 0x913e, 0x90c7, 0x913e, + 0x80f9, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, + 0x14f6, 0x0013, 0x006e, 0x0005, 0x8114, 0x8ad2, 0x8b98, 0x8cb8, + 0x8e12, 0x8114, 0x8114, 0x8114, 0x8aac, 0x8ff5, 0x8ff8, 0x8114, + 0x8114, 0x8114, 0x8114, 0x9022, 0x080c, 0x14f6, 0x0066, 0x6000, + 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x812f, + 0x812f, 0x812f, 0x8152, 0x81a5, 0x812f, 0x812f, 0x812f, 0x8131, + 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x080c, + 0x14f6, 0xa186, 0x0003, 0x190c, 0x14f6, 0x00d6, 0x6003, 0x0003, + 0x6106, 0x6010, 0x2068, 0x684f, 0x0040, 0x687c, 0x680a, 0x6880, + 0x680e, 0x6813, 0x0000, 0x6817, 0x0000, 0x00de, 0x2c10, 0x080c, + 0x1e6e, 0x080c, 0x680b, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d0d, + 0x012e, 0x0005, 0xa182, 0x0047, 0x0002, 0x815e, 0x815e, 0x8160, + 0x817f, 0x815e, 0x815e, 0x815e, 0x815e, 0x8191, 0x080c, 0x14f6, + 0x00d6, 0x0016, 0x080c, 0x6c05, 0x080c, 0x6d0d, 0x6003, 0x0004, + 0x6110, 0x2168, 0x6854, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, + 0x684f, 0x0020, 0x685c, 0x685a, 0x6874, 0x687e, 0x6878, 0x6882, + 0x6897, 0x0000, 0x689b, 0x0000, 0x001e, 0x00de, 0x0005, 0x080c, + 0x6c05, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0120, 0x684b, + 0x0006, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c, 0x6d0d, + 0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110, 0x2168, + 0x080c, 0x9596, 0x0120, 0x684b, 0x0029, 0x080c, 0x510c, 0x00de, + 0x080c, 0x8078, 0x080c, 0x6d0d, 0x0005, 0xa182, 0x0047, 0x0002, + 0x81b3, 0x81c2, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1, + 0x81b1, 0x080c, 0x14f6, 0x00d6, 0x6010, 0x2068, 0x684c, 0xc0f4, + 0x684e, 0x00de, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, + 0x1824, 0x0005, 0x00d6, 0x6110, 0x2168, 0x684b, 0x0000, 0x6853, + 0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x0005, 0xa1b6, + 0x0015, 0x1118, 0x080c, 0x8078, 0x0030, 0xa1b6, 0x0016, 0x190c, + 0x14f6, 0x080c, 0x8078, 0x0005, 0x20a9, 0x000e, 0x2e98, 0x6010, + 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, + 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, + 0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x81ea, 0x00e6, 0x080c, + 0x9596, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, + 0x00ee, 0x080c, 0x8078, 0x0005, 0x00d6, 0x0036, 0x7330, 0xa386, + 0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd, + 0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, + 0x6b32, 0x080c, 0x8078, 0x003e, 0x00de, 0x0005, 0x0016, 0x20a9, + 0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, + 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001, 0x2004, 0xa080, + 0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004, 0x2070, 0x7037, + 0x0103, 0x00ee, 0x080c, 0x8078, 0x001e, 0x0005, 0x0016, 0x2009, + 0x0000, 0x7030, 0xa086, 0x0100, 0x0140, 0x7038, 0xa084, 0x00ff, + 0x808e, 0x703c, 0xa084, 0x00ff, 0x8086, 0xa080, 0x0004, 0xa108, + 0x21a8, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, + 0x080c, 0x48be, 0x00e6, 0x080c, 0x9596, 0x0140, 0x6010, 0x2070, + 0x7007, 0x0000, 0x7034, 0x70b2, 0x7037, 0x0103, 0x00ee, 0x080c, + 0x8078, 0x001e, 0x0005, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2c68, + 0x0016, 0x2009, 0x0035, 0x080c, 0x9a34, 0x001e, 0x1168, 0x0026, + 0x6228, 0x2268, 0x002e, 0x2071, 0xb28c, 0x6b1c, 0xa386, 0x0003, + 0x0130, 0xa386, 0x0006, 0x0128, 0x080c, 0x8078, 0x0020, 0x0031, + 0x0010, 0x080c, 0x8323, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x6810, + 0x2078, 0xa186, 0x0015, 0x0904, 0x830c, 0xa18e, 0x0016, 0x1904, + 0x8321, 0x700c, 0xa084, 0xff00, 0xa086, 0x1700, 0x1904, 0x82eb, + 0x8fff, 0x0904, 0x831f, 0x6808, 0xa086, 0xffff, 0x1904, 0x830e, + 0x784c, 0xa084, 0x0060, 0xa086, 0x0020, 0x1150, 0x797c, 0x7810, + 0xa106, 0x1904, 0x830e, 0x7980, 0x7814, 0xa106, 0x1904, 0x830e, + 0x080c, 0x9742, 0x6858, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, + 0x784e, 0x0026, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x080c, 0x6665, + 0x7854, 0xa20a, 0x0208, 0x8011, 0x7a56, 0x82ff, 0x002e, 0x1138, + 0x00c6, 0x2d60, 0x080c, 0x9374, 0x00ce, 0x0804, 0x831f, 0x00c6, + 0x00d6, 0x2f68, 0x6838, 0xd0fc, 0x1118, 0x080c, 0x4993, 0x0010, + 0x080c, 0x4b7c, 0x00de, 0x00ce, 0x1548, 0x00c6, 0x2d60, 0x080c, + 0x8078, 0x00ce, 0x04a0, 0x7008, 0xa086, 0x000b, 0x11a0, 0x6018, + 0x200c, 0xc1bc, 0x2102, 0x00c6, 0x2d60, 0x7853, 0x0003, 0x6007, + 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8, 0x080c, + 0x6c50, 0x00ce, 0x00e0, 0x700c, 0xa086, 0x2a00, 0x1138, 0x2001, + 0xafa5, 0x2004, 0x683e, 0x0098, 0x0471, 0x0098, 0x8fff, 0x090c, + 0x14f6, 0x00c6, 0x00d6, 0x2d60, 0x2f68, 0x684b, 0x0003, 0x080c, + 0x926f, 0x080c, 0x9742, 0x080c, 0x974e, 0x00de, 0x00ce, 0x080c, + 0x8078, 0x00fe, 0x0005, 0xa186, 0x0015, 0x1128, 0x2001, 0xafa5, + 0x2004, 0x683e, 0x0068, 0xa18e, 0x0016, 0x1160, 0x00c6, 0x2d00, + 0x2060, 0x080c, 0xabb4, 0x080c, 0x6618, 0x080c, 0x8078, 0x00ce, + 0x080c, 0x8078, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0x7c80, + 0x7b7c, 0xd2f4, 0x0130, 0x2001, 0xafa5, 0x2004, 0x683e, 0x0804, + 0x839d, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x6804, 0xa086, + 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, + 0x0050, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x04f0, 0x6800, + 0xa086, 0x000f, 0x01c8, 0x8fff, 0x090c, 0x14f6, 0x6820, 0xd0dc, + 0x1198, 0x6800, 0xa086, 0x0004, 0x1198, 0x784c, 0xd0ac, 0x0180, + 0x784c, 0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, + 0x2001, 0x0001, 0x682e, 0x00e0, 0x2001, 0x0007, 0x682e, 0x00c0, + 0x784c, 0xd0b4, 0x1130, 0xd0ac, 0x0db8, 0x784c, 0xd0f4, 0x1da0, + 0x0c38, 0xd2ec, 0x1d88, 0x7024, 0xa306, 0x1118, 0x7020, 0xa406, + 0x0d58, 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, + 0x080c, 0x9894, 0x080c, 0x6c50, 0x0010, 0x080c, 0x8078, 0x004e, + 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x6034, 0x2068, + 0x6a1c, 0xa286, 0x0007, 0x0904, 0x83ee, 0xa286, 0x0002, 0x05f0, + 0xa286, 0x0000, 0x05d8, 0x6808, 0x6338, 0xa306, 0x15b8, 0x2071, + 0xb28c, 0xa186, 0x0015, 0x0560, 0xa18e, 0x0016, 0x1190, 0x6030, + 0xa084, 0x00ff, 0xa086, 0x0001, 0x1160, 0x700c, 0xa086, 0x2a00, + 0x1140, 0x6034, 0xa080, 0x0008, 0x200c, 0xc1dd, 0xc1f5, 0x2102, + 0x00b8, 0x00c6, 0x6034, 0x2060, 0x6010, 0x2068, 0x080c, 0x9596, + 0x090c, 0x14f6, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, + 0x601f, 0x0002, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x0030, + 0x6034, 0x2070, 0x2001, 0xafa5, 0x2004, 0x703e, 0x080c, 0x8078, + 0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x20a9, 0x000e, 0x2e98, + 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x1148, 0x6018, 0x2068, + 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, 0x00de, + 0x0804, 0x81f6, 0x2100, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b2, + 0x0040, 0x1a04, 0x846e, 0x0002, 0x8462, 0x8456, 0x8462, 0x8462, + 0x8462, 0x8462, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, + 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, + 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, + 0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8462, 0x8462, 0x8454, + 0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8454, 0x8454, + 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8462, + 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, + 0x8454, 0x8462, 0x8454, 0x8454, 0x080c, 0x14f6, 0x6003, 0x0001, + 0x6106, 0x080c, 0x67ee, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, + 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x67ee, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x2600, 0x0002, + 0x8462, 0x8476, 0x8476, 0x8462, 0x8462, 0x8476, 0x080c, 0x14f6, + 0x6004, 0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x0904, + 0x8518, 0xa1b6, 0x0027, 0x1904, 0x84de, 0x080c, 0x6b73, 0x6004, + 0x080c, 0x9778, 0x0188, 0x080c, 0x9789, 0x0904, 0x84d8, 0xa08e, + 0x0021, 0x0904, 0x84db, 0xa08e, 0x0022, 0x0904, 0x84d8, 0xa08e, + 0x003d, 0x0904, 0x84db, 0x04a8, 0x080c, 0x2aff, 0x2001, 0x0007, + 0x080c, 0x4c30, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3, + 0xa186, 0x007e, 0x1148, 0x2001, 0xad34, 0x2014, 0xc285, 0x080c, + 0x574f, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110, + 0x2019, 0x0028, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, + 0x681d, 0x00c6, 0x6018, 0xa065, 0x0110, 0x080c, 0x4ecf, 0x00ce, + 0x2c08, 0x080c, 0xa712, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, + 0x4c9f, 0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, + 0x080c, 0x85f3, 0x0cb0, 0x080c, 0x8621, 0x0c98, 0xa186, 0x0014, + 0x1db0, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x080c, 0x9778, 0x1188, + 0x080c, 0x2aff, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3, + 0xa186, 0x007e, 0x1128, 0x2001, 0xad34, 0x200c, 0xc185, 0x2102, + 0x08c0, 0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0890, 0x6004, + 0xa08e, 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079, + 0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e, + 0x0021, 0x0d50, 0xa08e, 0x0022, 0x090c, 0x85f3, 0x0804, 0x84d1, + 0xa0b2, 0x0040, 0x1a04, 0x85db, 0x2008, 0x0002, 0x8560, 0x8561, + 0x8564, 0x8567, 0x856a, 0x856d, 0x855e, 0x855e, 0x855e, 0x855e, + 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, + 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, + 0x855e, 0x855e, 0x855e, 0x855e, 0x8570, 0x857f, 0x855e, 0x8581, + 0x857f, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x857f, 0x857f, + 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, + 0x85bb, 0x857f, 0x855e, 0x857b, 0x855e, 0x855e, 0x855e, 0x857c, + 0x855e, 0x855e, 0x855e, 0x857f, 0x85b2, 0x855e, 0x080c, 0x14f6, + 0x00f0, 0x2001, 0x000b, 0x0460, 0x2001, 0x0003, 0x0448, 0x2001, + 0x0005, 0x0430, 0x2001, 0x0001, 0x0418, 0x2001, 0x0009, 0x0400, + 0x080c, 0x6b73, 0x6003, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, + 0x080c, 0x6c50, 0x00a0, 0x0018, 0x0010, 0x080c, 0x4c30, 0x0804, + 0x85cc, 0x080c, 0x6b73, 0x2001, 0xafa3, 0x2004, 0x6016, 0x2001, + 0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x080c, 0x6c50, 0x0005, + 0x080c, 0x4c30, 0x080c, 0x6b73, 0x6003, 0x0002, 0x2001, 0xafa5, + 0x2004, 0x603e, 0x0036, 0x2019, 0xad5c, 0x2304, 0xa084, 0xff00, + 0x1120, 0x2001, 0xafa3, 0x201c, 0x0040, 0x8007, 0xa09a, 0x0004, + 0x0ec0, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x080c, + 0x6c50, 0x08e8, 0x080c, 0x6b73, 0x080c, 0x994e, 0x080c, 0x8078, + 0x080c, 0x6c50, 0x08a0, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079, + 0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x080c, 0x6b73, 0x080c, + 0x8078, 0x080c, 0x6c50, 0x0818, 0x080c, 0x6b73, 0x2001, 0xafa5, + 0x2004, 0x603e, 0x6003, 0x0002, 0x2001, 0xafa3, 0x2004, 0x6016, + 0x080c, 0x6c50, 0x0005, 0x2600, 0x2008, 0x0002, 0x85e6, 0x85e4, + 0x85e4, 0x85cc, 0x85cc, 0x85e4, 0x080c, 0x14f6, 0x080c, 0x6b73, + 0x00d6, 0x6010, 0x2068, 0x080c, 0x15f0, 0x00de, 0x080c, 0x8078, + 0x080c, 0x6c50, 0x0005, 0x00e6, 0x0026, 0x0016, 0x080c, 0x9596, + 0x0508, 0x6010, 0x2070, 0x7034, 0xa086, 0x0139, 0x1148, 0x2001, + 0x0030, 0x2009, 0x0000, 0x2011, 0x4005, 0x080c, 0x9a05, 0x0090, + 0x7038, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016, 0x6004, 0xa08e, + 0x0021, 0x0160, 0xa08e, 0x003d, 0x0148, 0x001e, 0x7037, 0x0103, + 0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005, 0x001e, 0x0009, + 0x0cc8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, + 0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618, 0x2668, + 0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x14f6, + 0x6604, 0xa6b6, 0x0043, 0x1120, 0x080c, 0x99c1, 0x0804, 0x8692, + 0x6604, 0xa6b6, 0x0033, 0x1120, 0x080c, 0x9971, 0x0804, 0x8692, + 0x6604, 0xa6b6, 0x0028, 0x1120, 0x080c, 0x97b9, 0x0804, 0x8692, + 0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x97d0, 0x04d8, 0x6604, + 0xa6b6, 0x001f, 0x1118, 0x080c, 0x81dc, 0x04a0, 0x6604, 0xa6b6, + 0x0000, 0x1118, 0x080c, 0x83f4, 0x0468, 0x6604, 0xa6b6, 0x0022, + 0x1118, 0x080c, 0x8204, 0x0430, 0x6604, 0xa6b6, 0x0035, 0x1118, + 0x080c, 0x826b, 0x00f8, 0x6604, 0xa6b6, 0x0039, 0x1118, 0x080c, + 0x83a3, 0x00c0, 0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c, 0x821e, + 0x0088, 0x6604, 0xa6b6, 0x0044, 0x1118, 0x080c, 0x823e, 0x0050, + 0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016, 0x1118, + 0x0804, 0x883f, 0x0005, 0x080c, 0x80be, 0x0ce0, 0x86b9, 0x86bc, + 0x86b9, 0x86fe, 0x86b9, 0x87cc, 0x884d, 0x86b9, 0x86b9, 0x881b, + 0x86b9, 0x882f, 0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005, 0x3d18, + 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x00e6, 0xacf0, 0x0004, + 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x8078, + 0x0005, 0xe000, 0xe000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x7080, + 0xa086, 0x0074, 0x1530, 0x080c, 0xa6e9, 0x11b0, 0x00d6, 0x6018, + 0x2068, 0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc, 0x0110, 0xc0c5, + 0x6802, 0x00d9, 0x00de, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, + 0x2aff, 0x080c, 0x8078, 0x0078, 0x2001, 0x000a, 0x080c, 0x4c30, + 0x080c, 0x2aff, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, + 0x0010, 0x080c, 0x87bd, 0x00ee, 0x0005, 0x6800, 0xd084, 0x0168, + 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2069, 0xad51, 0x6804, 0xd0a4, + 0x0120, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x0005, 0x00d6, 0x2011, + 0xad20, 0x2204, 0xa086, 0x0074, 0x1904, 0x87ba, 0x6018, 0x2068, + 0x6aa0, 0xa286, 0x007e, 0x1120, 0x080c, 0x894d, 0x0804, 0x875e, + 0x080c, 0x8943, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286, + 0x0080, 0x11c0, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, + 0x0138, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200, + 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078, + 0x0804, 0x87bb, 0x00e6, 0x2071, 0xad34, 0x2e04, 0xd09c, 0x0188, + 0x2071, 0xb280, 0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118, 0xa284, + 0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110, 0x7112, + 0x7216, 0x00ee, 0x6010, 0xa005, 0x0128, 0x2068, 0x6838, 0xd0f4, + 0x0108, 0x0880, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001, + 0x6007, 0x0003, 0x080c, 0x67ee, 0x0804, 0x87bb, 0x685c, 0xd0e4, + 0x01d0, 0x080c, 0x9903, 0x080c, 0x574f, 0x0110, 0xd0dc, 0x1900, + 0x2011, 0xad34, 0x2204, 0xc0ad, 0x2012, 0x2001, 0xaf8e, 0x2004, + 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x26cb, 0x78e2, + 0x00fe, 0x0804, 0x8728, 0x080c, 0x9937, 0x2011, 0xad34, 0x2204, + 0xc0a5, 0x2012, 0x0006, 0x080c, 0xa801, 0x000e, 0x1904, 0x8728, + 0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x00c6, 0x2009, + 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe, + 0x080c, 0x26a0, 0x00f6, 0x2079, 0xad00, 0x7972, 0x2100, 0x2009, + 0x0000, 0x080c, 0x2676, 0x794e, 0x00fe, 0x8108, 0x080c, 0x4c80, + 0x2c00, 0x00ce, 0x1904, 0x8728, 0x601a, 0x2001, 0x0002, 0x080c, + 0x4c30, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x67ee, 0x0008, 0x0011, 0x00de, 0x0005, 0x2001, 0xad00, 0x2004, + 0xa086, 0x0003, 0x0120, 0x2001, 0x0007, 0x080c, 0x4c30, 0x080c, + 0x2aff, 0x080c, 0x8078, 0x0005, 0x00e6, 0x0026, 0x0016, 0x2071, + 0xad00, 0x7080, 0xa086, 0x0014, 0x15f0, 0x7000, 0xa086, 0x0003, + 0x1128, 0x6010, 0xa005, 0x1110, 0x080c, 0x3cce, 0x00d6, 0x6018, + 0x2068, 0x080c, 0x4d72, 0x080c, 0x86ed, 0x00de, 0x080c, 0x89f7, + 0x1550, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, 0x0518, + 0x2001, 0x0006, 0x080c, 0x4c30, 0x00e6, 0x6010, 0xa075, 0x01a8, + 0x7034, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1148, 0x2001, 0x0000, + 0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0x9a05, 0x0030, 0x7007, + 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2aff, + 0x080c, 0x8078, 0x0020, 0x080c, 0x85f3, 0x080c, 0x87bd, 0x001e, + 0x002e, 0x00ee, 0x0005, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014, + 0x1158, 0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007, + 0x0001, 0x080c, 0x67ee, 0x0010, 0x080c, 0x87bd, 0x0005, 0x2011, + 0xad20, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c, + 0x4c30, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x000b, + 0x0005, 0x86b9, 0x8854, 0x86b9, 0x888a, 0x86b9, 0x88ff, 0x884d, + 0x86b9, 0x86b9, 0x8912, 0x86b9, 0x8922, 0x6604, 0xa6b6, 0x001e, + 0x1110, 0x080c, 0x8078, 0x0005, 0x00d6, 0x00c6, 0x080c, 0x8932, + 0x1178, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c, + 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x00f8, + 0x2009, 0xb28e, 0x2104, 0xa086, 0x0009, 0x1160, 0x6018, 0x2068, + 0x6840, 0xa084, 0x00ff, 0xa005, 0x0180, 0x8001, 0x6842, 0x6017, + 0x000a, 0x0068, 0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086, + 0x1900, 0x1118, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x00ce, + 0x00de, 0x0005, 0x080c, 0x8940, 0x00d6, 0x2069, 0xaf9d, 0x2d04, + 0xa005, 0x0168, 0x6018, 0x2068, 0x68a0, 0xa086, 0x007e, 0x1138, + 0x2069, 0xad1c, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de, + 0x0078, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c, + 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x0428, + 0x080c, 0x85f3, 0x2009, 0xb28e, 0x2134, 0xa6b4, 0x00ff, 0xa686, + 0x0005, 0x01e0, 0xa686, 0x000b, 0x01b0, 0x2009, 0xb28f, 0x2104, + 0xa084, 0xff00, 0x1118, 0xa686, 0x0009, 0x0180, 0xa086, 0x1900, + 0x1150, 0xa686, 0x0009, 0x0150, 0x2001, 0x0004, 0x080c, 0x4c30, + 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x00d6, 0x6010, + 0x2068, 0x080c, 0x9596, 0x0128, 0x6838, 0xd0fc, 0x0110, 0x00de, + 0x0c90, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0140, + 0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x00de, 0x0c28, + 0x68a0, 0xa086, 0x007e, 0x1138, 0x00e6, 0x2071, 0xad00, 0x080c, + 0x48f5, 0x00ee, 0x0010, 0x080c, 0x2ad9, 0x00de, 0x08a0, 0x080c, + 0x8940, 0x1158, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001, + 0x6007, 0x0003, 0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c, + 0x87bd, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c, 0x4c30, + 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x67ee, 0x0010, 0x080c, + 0x87bd, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c, 0x4c30, + 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010, 0x080c, + 0x87bd, 0x0005, 0x2009, 0xb28e, 0x2104, 0xa086, 0x0003, 0x1138, + 0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x0005, + 0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006, 0x2164, + 0x080c, 0x4ceb, 0x001e, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6, + 0x0036, 0x0016, 0x6018, 0x2068, 0x2071, 0xad34, 0x2e04, 0xa085, + 0x0003, 0x2072, 0x080c, 0x89cc, 0x0538, 0x2001, 0xad52, 0x2004, + 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a, 0x080c, 0xa96c, + 0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, + 0x0001, 0x080c, 0x2aac, 0x2071, 0xad00, 0x080c, 0x28fa, 0x00c6, + 0x0156, 0x20a9, 0x0081, 0x2009, 0x007f, 0x080c, 0x2bc9, 0x8108, + 0x1f04, 0x897d, 0x015e, 0x00ce, 0x080c, 0x8943, 0x6813, 0x00ff, + 0x6817, 0xfffe, 0x2071, 0xb280, 0x2079, 0x0100, 0x2e04, 0xa084, + 0x00ff, 0x2069, 0xad1b, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, + 0x2069, 0xad1c, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0xa084, + 0xff00, 0x001e, 0xa105, 0x2009, 0xad27, 0x200a, 0x2200, 0xa084, + 0x00ff, 0x2008, 0x080c, 0x26a0, 0x080c, 0x574f, 0x0170, 0x2069, + 0xb28e, 0x2071, 0xaf9f, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818, + 0x700a, 0x681c, 0x700e, 0x080c, 0x9903, 0x0040, 0x2001, 0x0006, + 0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078, 0x001e, 0x003e, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x0036, 0x00e6, 0x0156, + 0x2019, 0xad27, 0x231c, 0x83ff, 0x01e8, 0x2071, 0xb280, 0x2e14, + 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x1190, + 0x2011, 0xb296, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, + 0x1148, 0x2011, 0xb29a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, + 0x8a7c, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x0005, 0x00e6, + 0x2071, 0xb28c, 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086, + 0x0800, 0x1188, 0x700c, 0xd0ec, 0x0160, 0xa084, 0x0f00, 0xa086, + 0x0100, 0x1138, 0x7024, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0xa006, + 0x0010, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, + 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400, + 0x2071, 0xad00, 0x7244, 0x7064, 0xa202, 0x16f0, 0x080c, 0xa990, + 0x05a0, 0x671c, 0xa786, 0x0001, 0x0580, 0xa786, 0x0007, 0x0568, + 0x2500, 0xac06, 0x0550, 0x2400, 0xac06, 0x0538, 0x00c6, 0x6000, + 0xa086, 0x0004, 0x1110, 0x080c, 0x190b, 0xa786, 0x0008, 0x1148, + 0x080c, 0x9789, 0x1130, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x974e, + 0x00a0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0160, 0xa786, 0x0003, + 0x11e8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, + 0x080c, 0x9742, 0x080c, 0x974e, 0x00ce, 0xace0, 0x0018, 0x7058, + 0xac02, 0x1210, 0x0804, 0x8a2a, 0x012e, 0x000e, 0x002e, 0x004e, + 0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0xa786, 0x0006, + 0x1d00, 0x080c, 0xa91f, 0x0c30, 0x220c, 0x2304, 0xa106, 0x1130, + 0x8210, 0x8318, 0x1f04, 0x8a7c, 0xa006, 0x0005, 0x2304, 0xa102, + 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0xa18d, 0x0001, + 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x080c, 0x9778, + 0x0120, 0x080c, 0x9789, 0x0168, 0x0028, 0x080c, 0x2aff, 0x080c, + 0x9789, 0x0138, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, + 0x0005, 0x080c, 0x85f3, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x8ac2, + 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, + 0x8ac2, 0x8ac2, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac2, 0x8ac2, + 0x8ac2, 0x8ac4, 0x080c, 0x14f6, 0x600b, 0xffff, 0x6003, 0x0001, + 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, + 0x012e, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0040, + 0x0804, 0x8b5e, 0xa186, 0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c, + 0x2ad9, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0168, 0x6837, + 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, + 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x080c, + 0x6c50, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004, 0xa082, 0x0040, + 0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045, 0x0120, 0xa186, + 0x0047, 0x190c, 0x14f6, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198, + 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699, + 0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000, 0xa086, 0x0002, + 0x1110, 0x0804, 0x8b98, 0x080c, 0x80be, 0x0005, 0x0002, 0x8b3c, + 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, + 0x8b3a, 0x8b3a, 0x8b57, 0x8b57, 0x8b57, 0x8b57, 0x8b3a, 0x8b57, + 0x8b3a, 0x8b57, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x00d6, 0x6110, + 0x2168, 0x080c, 0x9596, 0x0168, 0x6837, 0x0103, 0x684b, 0x0006, + 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c, 0x510c, 0x080c, + 0x9742, 0x00de, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c, + 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x0002, 0x8b74, + 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, + 0x8b72, 0x8b72, 0x8b86, 0x8b86, 0x8b86, 0x8b86, 0x8b72, 0x8b91, + 0x8b72, 0x8b86, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x2001, 0xafa5, + 0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c50, 0x6010, 0xa088, + 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x6b73, + 0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x000f, 0x080c, 0x6c50, + 0x0005, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, + 0xa182, 0x0040, 0x0002, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, + 0x8bb0, 0x8c88, 0x8ca9, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, + 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x080c, 0x14f6, + 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2071, 0xb280, 0x7124, 0x610a, + 0x2071, 0xb28c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, + 0x0904, 0x8c54, 0xa68c, 0x0c00, 0x01e8, 0x00f6, 0x2c78, 0x080c, + 0x5029, 0x00fe, 0x0198, 0x684c, 0xd0ac, 0x0180, 0x6020, 0xd0dc, + 0x1168, 0x6850, 0xd0bc, 0x1150, 0x7318, 0x6814, 0xa306, 0x1904, + 0x8c66, 0x731c, 0x6810, 0xa306, 0x1904, 0x8c66, 0x7318, 0x6b62, + 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0518, 0xa186, + 0x0028, 0x1128, 0x080c, 0x9767, 0x684b, 0x001c, 0x00e8, 0xd6dc, + 0x01a0, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0170, 0x6914, 0x6a10, + 0x2100, 0xa205, 0x0148, 0x7018, 0xa106, 0x1118, 0x701c, 0xa206, + 0x0118, 0x6962, 0x6a5e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0x684b, + 0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e, + 0xd6c4, 0x01f0, 0xa686, 0x0100, 0x1140, 0x2001, 0xb299, 0x2004, + 0xa005, 0x1118, 0xc6c4, 0x0804, 0x8bbf, 0x7328, 0x732c, 0x6b56, + 0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, + 0x2308, 0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e, + 0xd6cc, 0x0904, 0x8c79, 0x7124, 0x695a, 0x81ff, 0x0904, 0x8c79, + 0xa192, 0x0021, 0x1250, 0x2071, 0xb298, 0x831c, 0x2300, 0xae18, + 0xad90, 0x001d, 0x080c, 0x927f, 0x04a0, 0x6838, 0xd0fc, 0x0120, + 0x2009, 0x0020, 0x695a, 0x0c78, 0x00f6, 0x2d78, 0x080c, 0x9224, + 0x00fe, 0x080c, 0x926f, 0x0438, 0x00f6, 0x2c78, 0x080c, 0x5029, + 0x00fe, 0x0188, 0x684c, 0xd0ac, 0x0170, 0x6020, 0xd0dc, 0x1158, + 0x6850, 0xd0bc, 0x1140, 0x684c, 0xd0f4, 0x1128, 0x080c, 0x9866, + 0x00de, 0x00ee, 0x00e0, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, + 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, + 0x8e04, 0x080c, 0x510c, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, + 0x080c, 0x9834, 0x00de, 0x00ee, 0x1110, 0x080c, 0x8078, 0x0005, + 0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00, 0x7e0c, + 0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0120, 0x6003, 0x0002, + 0x00fe, 0x0005, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x603f, + 0x0000, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b, 0x080c, 0x6d0d, + 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110, + 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, + 0xa182, 0x0040, 0x0002, 0x8cce, 0x8cce, 0x8cce, 0x8cce, 0x8cce, + 0x8cd0, 0x8d61, 0x8cce, 0x8cce, 0x8d77, 0x8ddb, 0x8cce, 0x8cce, + 0x8cce, 0x8cce, 0x8dea, 0x8cce, 0x8cce, 0x8cce, 0x080c, 0x14f6, + 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c, 0x6110, 0x2178, + 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, + 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x8d5c, 0xa694, + 0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, + 0xa284, 0x0300, 0x0904, 0x8d5c, 0x080c, 0x15d9, 0x090c, 0x14f6, + 0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, + 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, + 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, + 0x0002, 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, + 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, + 0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, + 0x6856, 0xa01e, 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, + 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, + 0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc, + 0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, + 0x2071, 0xb298, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, + 0x927f, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, + 0x0c78, 0x2d78, 0x080c, 0x9224, 0x00de, 0x00ee, 0x00fe, 0x007e, + 0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00, + 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, + 0x00fe, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x781a, 0x0005, 0x00d6, + 0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x2001, 0xafa5, + 0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c05, 0x080c, 0x6d0d, + 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x8dd9, 0xd1cc, 0x0540, + 0x6948, 0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850, + 0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156, + 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x8da1, 0x015e, + 0x000e, 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600, + 0x0418, 0x0016, 0x080c, 0x1600, 0x00de, 0x080c, 0x926f, 0x00e0, + 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180, + 0xa086, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd1dc, 0x0118, + 0x684b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0010, + 0x684b, 0x0000, 0x080c, 0x510c, 0x080c, 0x9834, 0x1110, 0x080c, + 0x8078, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x7a64, 0x6003, + 0x0002, 0x2001, 0xafa5, 0x2004, 0x603e, 0x080c, 0x6c05, 0x080c, + 0x6d0d, 0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110, + 0x2168, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029, + 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, + 0x8078, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138, + 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, + 0x685e, 0x0005, 0xa182, 0x0040, 0x0002, 0x8e28, 0x8e28, 0x8e28, + 0x8e28, 0x8e28, 0x8e2a, 0x8e28, 0x8ee3, 0x8eef, 0x8e28, 0x8e28, + 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, + 0x080c, 0x14f6, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c, + 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x00f6, 0x2c78, 0x080c, + 0x5029, 0x00fe, 0x0150, 0xa684, 0x00ff, 0x1138, 0x6020, 0xd0f4, + 0x0120, 0x080c, 0x9866, 0x0804, 0x8ede, 0x7e46, 0x7f4c, 0xc7e5, + 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, + 0x8ed4, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, + 0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x8ed2, 0xa686, 0x0100, + 0x1140, 0x2001, 0xb299, 0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46, + 0x0c28, 0x080c, 0x15d9, 0x090c, 0x14f6, 0x2d00, 0x784a, 0x7f4c, + 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, + 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318, + 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180, + 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, + 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, + 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, + 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a, + 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xb298, + 0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc, 0x01d8, 0x7124, + 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071, 0xb298, + 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x927f, 0x0050, + 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78, + 0x080c, 0x9224, 0xd6dc, 0x1110, 0xa006, 0x0030, 0x2001, 0x0001, + 0x2071, 0xb28c, 0x7218, 0x731c, 0x080c, 0x186f, 0x00de, 0x00ee, + 0x00fe, 0x007e, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x20e1, + 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x2001, + 0xafa5, 0x2004, 0x603e, 0x00d6, 0x6003, 0x0002, 0x6110, 0x2168, + 0x694c, 0xd1e4, 0x0904, 0x8ff3, 0x603f, 0x0000, 0x00f6, 0x2c78, + 0x080c, 0x5029, 0x00fe, 0x0548, 0x6814, 0x6910, 0xa115, 0x0528, + 0x6a60, 0xa206, 0x1118, 0x685c, 0xa106, 0x01f8, 0x684c, 0xc0e4, + 0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000, 0x697c, + 0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6020, + 0xc0f5, 0x6022, 0x00d6, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e, + 0x00de, 0x080c, 0x9866, 0x0804, 0x8ff3, 0x694c, 0xd1cc, 0x0904, + 0x8fc3, 0x6948, 0x6838, 0xd0fc, 0x0904, 0x8f88, 0x0016, 0x684c, + 0x0006, 0x6850, 0x0006, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, + 0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, + 0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, + 0x0015, 0x080c, 0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, + 0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c, + 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04, + 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d, + 0xaf98, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304, 0x2012, + 0x8318, 0x8210, 0x1f04, 0x8f76, 0x015e, 0x00fe, 0x000e, 0x6852, + 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600, 0x0804, 0x8fee, + 0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002, + 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c, + 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c, + 0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128, + 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130, + 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04, 0x6860, 0x7862, + 0x685c, 0x785e, 0x684c, 0x784e, 0x00fe, 0x080c, 0x1600, 0x00de, + 0x080c, 0x926f, 0x0458, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, + 0xa0b6, 0x0002, 0x01b0, 0xa086, 0x0028, 0x1118, 0x684b, 0x001c, + 0x00d8, 0xd1dc, 0x0148, 0x684b, 0x0015, 0x080c, 0x99ee, 0x0118, + 0x6944, 0xc1dc, 0x6946, 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007, + 0x0058, 0x684b, 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, + 0xa115, 0x0110, 0x080c, 0x8e04, 0x080c, 0x510c, 0x080c, 0x9834, + 0x1110, 0x080c, 0x8078, 0x00de, 0x0005, 0x080c, 0x6b73, 0x0010, + 0x080c, 0x6c05, 0x080c, 0x9596, 0x01c0, 0x00d6, 0x6110, 0x2168, + 0x6837, 0x0103, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x11c0, 0xd184, + 0x1198, 0x6108, 0x694a, 0xa18e, 0x0029, 0x1110, 0x080c, 0xabfa, + 0x6847, 0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c, + 0x6c50, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0004, 0x0c88, 0x684b, + 0x0004, 0x0c70, 0xa182, 0x0040, 0x0002, 0x9038, 0x9038, 0x9038, + 0x9038, 0x9038, 0x903a, 0x9038, 0x903d, 0x9038, 0x9038, 0x9038, + 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, + 0x080c, 0x14f6, 0x080c, 0x8078, 0x0005, 0x0006, 0x0026, 0xa016, + 0x080c, 0x1824, 0x002e, 0x000e, 0x0005, 0xa182, 0x0085, 0x0002, + 0x9051, 0x904f, 0x904f, 0x905d, 0x904f, 0x904f, 0x904f, 0x080c, + 0x14f6, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, + 0x00e6, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0x9586, + 0x01a0, 0x2268, 0x6800, 0xa086, 0x0000, 0x0178, 0x6018, 0x6d18, + 0xa52e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x0128, + 0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003, + 0x0001, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00f6, 0x2278, 0x080c, + 0x5029, 0x00fe, 0x0150, 0x6820, 0xd0ec, 0x0138, 0x00c6, 0x2260, + 0x603f, 0x0000, 0x080c, 0x9866, 0x00ce, 0x00ee, 0x00de, 0x005e, + 0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085, + 0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c, 0x14f6, 0xa082, 0x0085, + 0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x14f6, + 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x90be, + 0x90c0, 0x90c0, 0x90be, 0x90be, 0x90be, 0x90be, 0x080c, 0x14f6, + 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa186, + 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04a8, 0xa186, + 0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x00d6, 0x6010, + 0x2068, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000, + 0x684b, 0x0029, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, + 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c, 0x80be, 0x0ce0, 0xa186, + 0x0014, 0x1dd0, 0x080c, 0x6b73, 0x00d6, 0x6010, 0x2068, 0x080c, + 0x9596, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006, + 0x6850, 0xc0ec, 0x6852, 0x08f0, 0x0002, 0x910e, 0x910c, 0x910c, + 0x910c, 0x910c, 0x910c, 0x9126, 0x080c, 0x14f6, 0x080c, 0x6b73, + 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186, + 0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004, + 0x6016, 0x6003, 0x000c, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73, + 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186, + 0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004, + 0x6016, 0x6003, 0x000e, 0x080c, 0x6c50, 0x0005, 0xa182, 0x008c, + 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x80be, 0x0005, + 0x914f, 0x914f, 0x914f, 0x914f, 0x9151, 0x91a4, 0x914f, 0x080c, + 0x14f6, 0x00d6, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0168, + 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186, + 0x0035, 0x1118, 0x00de, 0x0804, 0x91b7, 0x080c, 0x9742, 0x080c, + 0x9596, 0x01c8, 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, + 0x0128, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118, + 0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847, + 0x0000, 0x080c, 0x510c, 0x2c68, 0x080c, 0x8022, 0x01c0, 0x6003, + 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0xb28e, 0x210c, + 0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x6918, 0x611a, 0x080c, + 0x9956, 0x6950, 0x6152, 0x601f, 0x0001, 0x080c, 0x67a8, 0x2d60, + 0x080c, 0x8078, 0x00de, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029, + 0x00fe, 0x0598, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035, + 0x0130, 0xa186, 0x001e, 0x0118, 0xa186, 0x0039, 0x1530, 0x00d6, + 0x2c68, 0x080c, 0x9a34, 0x1904, 0x91fc, 0x080c, 0x8022, 0x01d8, + 0x6106, 0x6003, 0x0001, 0x601f, 0x0001, 0x6918, 0x611a, 0x6928, + 0x612a, 0x692c, 0x612e, 0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934, + 0x6136, 0x6938, 0x613a, 0x6950, 0x6152, 0x080c, 0x9956, 0x080c, + 0x67a8, 0x080c, 0x6c50, 0x2d60, 0x00f8, 0x00d6, 0x6010, 0x2068, + 0x080c, 0x9596, 0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128, + 0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b, + 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847, 0x0000, + 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x0005, + 0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0140, 0x6837, + 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c, 0x510c, 0x00de, + 0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186, + 0x0027, 0x0118, 0x080c, 0x80be, 0x0030, 0x080c, 0x6b73, 0x080c, + 0x974e, 0x080c, 0x6c50, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6, + 0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, + 0x2130, 0x2069, 0xb298, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, + 0xaf90, 0x001d, 0x080c, 0x927f, 0xa6b2, 0x0020, 0x7804, 0xa06d, + 0x0110, 0x080c, 0x1600, 0x080c, 0x15d9, 0x0500, 0x8528, 0x6837, + 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228, + 0x2608, 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009, + 0x003c, 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f, + 0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f, + 0xa5ad, 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6, + 0x8dff, 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c, + 0x510c, 0x2f68, 0x0cb8, 0x080c, 0x510c, 0x00fe, 0x0005, 0x0156, + 0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007, + 0x2012, 0x8318, 0x8210, 0x1f04, 0x9286, 0x015e, 0x0005, 0x0066, + 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x601c, 0xa084, 0x000f, + 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, + 0x2031, 0x0000, 0x601c, 0xa084, 0x000f, 0x001b, 0x006e, 0x012e, + 0x0005, 0x92c3, 0x92c3, 0x92be, 0x92e5, 0x92b1, 0x92be, 0x92e5, + 0x92be, 0x080c, 0x14f6, 0x0036, 0x2019, 0x0010, 0x080c, 0xa566, + 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0xa006, 0x0005, + 0xa085, 0x0001, 0x0005, 0x00d6, 0x86ff, 0x11d8, 0x6010, 0x2068, + 0x080c, 0x9596, 0x01c0, 0x6834, 0xa086, 0x0139, 0x1128, 0x684b, + 0x0005, 0x6853, 0x0000, 0x0028, 0xa00e, 0x2001, 0x0005, 0x080c, + 0x51df, 0x080c, 0x9803, 0x080c, 0x510c, 0x080c, 0x8078, 0xa085, + 0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010, + 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x92fc, 0x9319, 0x92fe, 0x9338, + 0x9316, 0x92fc, 0x92be, 0x92c3, 0x92c3, 0x92be, 0x92be, 0x92be, + 0x92be, 0x92be, 0x92be, 0x92be, 0x080c, 0x14f6, 0x86ff, 0x1198, + 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x9803, + 0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, + 0x67a8, 0x080c, 0x6c50, 0xa085, 0x0001, 0x0005, 0x080c, 0x190b, + 0x0c28, 0x00e6, 0x2071, 0xafc7, 0x7024, 0xac06, 0x1110, 0x080c, + 0x79e1, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006, 0x1150, 0x0086, + 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x7b9a, 0x009e, 0x008e, + 0x0010, 0x080c, 0x78de, 0x00ee, 0x1948, 0x080c, 0x92be, 0x0005, + 0x0036, 0x00e6, 0x2071, 0xafc7, 0x703c, 0xac06, 0x1140, 0x2019, + 0x0000, 0x080c, 0x7a64, 0x00ee, 0x003e, 0x0804, 0x92fe, 0x080c, + 0x7cb8, 0x00ee, 0x003e, 0x1904, 0x92fe, 0x080c, 0x92be, 0x0005, + 0x00c6, 0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, 0x9369, + 0x93d3, 0x9501, 0x9374, 0x974e, 0x9369, 0xa558, 0x8078, 0x93d3, + 0x9362, 0x955f, 0x080c, 0x14f6, 0x080c, 0x9789, 0x1110, 0x080c, + 0x85f3, 0x0005, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x080c, 0x8078, + 0x0005, 0x6017, 0x0001, 0x0005, 0x6010, 0xa080, 0x0019, 0x2c02, + 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x938f, + 0x9391, 0x93b1, 0x93c3, 0x93d0, 0x938f, 0x9369, 0x9369, 0x9369, + 0x93c3, 0x93c3, 0x938f, 0x938f, 0x938f, 0x938f, 0x93cd, 0x080c, + 0x14f6, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, + 0xafc7, 0x7024, 0xac06, 0x0190, 0x080c, 0x78de, 0x6007, 0x0085, + 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xafa4, 0x2004, 0x6016, + 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x6017, 0x0001, + 0x0cd8, 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de, + 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8, + 0x080c, 0x6c50, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010, 0x2068, + 0x6850, 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005, + 0x080c, 0x190b, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, + 0x000b, 0x0005, 0x93ea, 0x9371, 0x93ec, 0x93ea, 0x93ec, 0x93ec, + 0x936a, 0x93ea, 0x9364, 0x9364, 0x93ea, 0x93ea, 0x93ea, 0x93ea, + 0x93ea, 0x93ea, 0x080c, 0x14f6, 0x00d6, 0x6018, 0x2068, 0x6804, + 0xa084, 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x14f6, 0x000b, + 0x0005, 0x9405, 0x94a7, 0x9407, 0x9441, 0x9407, 0x9441, 0x9407, + 0x9411, 0x9405, 0x9441, 0x9405, 0x942d, 0x080c, 0x14f6, 0x6004, + 0xa08e, 0x0016, 0x0588, 0xa08e, 0x0004, 0x0570, 0xa08e, 0x0002, + 0x0558, 0x6004, 0x080c, 0x9789, 0x0904, 0x94c0, 0xa08e, 0x0021, + 0x0904, 0x94c4, 0xa08e, 0x0022, 0x0904, 0x94c0, 0xa08e, 0x003d, + 0x0904, 0x94c4, 0xa08e, 0x0039, 0x0904, 0x94c8, 0xa08e, 0x0035, + 0x0904, 0x94c8, 0xa08e, 0x001e, 0x0188, 0xa08e, 0x0001, 0x1150, + 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa086, + 0x0006, 0x0110, 0x080c, 0x2ad9, 0x080c, 0x85f3, 0x080c, 0x974e, + 0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0904, 0x9498, + 0xa186, 0x0002, 0x1518, 0x6018, 0x2068, 0x2001, 0xad34, 0x2004, + 0xd0ac, 0x1904, 0x94ea, 0x68a0, 0xd0bc, 0x1904, 0x94ea, 0x6840, + 0xa084, 0x00ff, 0xa005, 0x0190, 0x8001, 0x6842, 0x6013, 0x0000, + 0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x080c, 0x8022, + 0x0128, 0x2d00, 0x601a, 0x601f, 0x0001, 0x0450, 0x00de, 0x00ce, + 0x6004, 0xa08e, 0x0002, 0x11a8, 0x6018, 0xa080, 0x0028, 0x2004, + 0xa086, 0x007e, 0x1170, 0x2009, 0xad34, 0x2104, 0xc085, 0x200a, + 0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x00ee, 0x080c, 0x85f3, + 0x0020, 0x080c, 0x85f3, 0x080c, 0x2ad9, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x080c, 0x2aff, 0x012e, 0x00ee, 0x080c, 0x974e, 0x0005, + 0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, + 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x0c80, 0x00c6, + 0x00d6, 0x6104, 0xa186, 0x0016, 0x0d58, 0x6018, 0x2068, 0x6840, + 0xa084, 0x00ff, 0xa005, 0x0904, 0x946e, 0x8001, 0x6842, 0x6003, + 0x0001, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x08b8, + 0x080c, 0x85f3, 0x0804, 0x943e, 0x080c, 0x8621, 0x0804, 0x943e, + 0x00d6, 0x2c68, 0x6104, 0x080c, 0x9a34, 0x00de, 0x0118, 0x080c, + 0x8078, 0x00b8, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, + 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038, + 0x600a, 0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c, + 0x6c50, 0x0005, 0x00de, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x2ad9, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2aff, 0x6013, 0x0000, + 0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x012e, 0x00ee, + 0x0005, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, + 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, + 0x9518, 0x9369, 0x9518, 0x9371, 0x951a, 0x9371, 0x9527, 0x9518, + 0x080c, 0x14f6, 0x6004, 0xa086, 0x008b, 0x0148, 0x6007, 0x008b, + 0x6003, 0x000d, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0005, 0x080c, + 0x9742, 0x080c, 0x9596, 0x0580, 0x080c, 0x2ad9, 0x00d6, 0x080c, + 0x9596, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006, + 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c, 0x510c, 0x2c68, + 0x080c, 0x8022, 0x0150, 0x6818, 0x601a, 0x080c, 0x9956, 0x00c6, + 0x2d60, 0x080c, 0x974e, 0x00ce, 0x0008, 0x2d60, 0x00de, 0x6013, + 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, + 0x67ee, 0x080c, 0x6c50, 0x0010, 0x080c, 0x974e, 0x0005, 0x6000, + 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x9576, 0x9576, + 0x9576, 0x9578, 0x9579, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576, + 0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x080c, 0x14f6, + 0x0005, 0x080c, 0x7cb8, 0x190c, 0x14f6, 0x6110, 0x2168, 0x684b, + 0x0006, 0x080c, 0x510c, 0x080c, 0x8078, 0x0005, 0xa284, 0x0007, + 0x1158, 0xa282, 0xb400, 0x0240, 0x2001, 0xad16, 0x2004, 0xa202, + 0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210, + 0xa294, 0xf000, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2061, 0xb400, 0x2071, 0xad00, 0x7344, + 0x7064, 0xa302, 0x12a8, 0x601c, 0xa206, 0x1160, 0x080c, 0x98e3, + 0x0148, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x00c6, 0x080c, + 0x8078, 0x00ce, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0c38, + 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, + 0x0016, 0xa188, 0xae34, 0x210c, 0x81ff, 0x0170, 0x2061, 0xb400, + 0x2071, 0xad00, 0x0016, 0x080c, 0x8022, 0x001e, 0x0138, 0x611a, + 0x080c, 0x2ad9, 0x080c, 0x8078, 0xa006, 0x0010, 0xa085, 0x0001, + 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091, + 0x8000, 0x00c6, 0x080c, 0x8022, 0x005e, 0x0180, 0x6612, 0x651a, + 0x080c, 0x9956, 0x601f, 0x0003, 0x2009, 0x004b, 0x080c, 0x80a7, + 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, + 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c, + 0x8022, 0x005e, 0x0508, 0x6013, 0x0000, 0x651a, 0x080c, 0x9956, + 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x4ecf, 0x00ce, 0x080c, + 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, + 0xa712, 0x007e, 0x2009, 0x004c, 0x080c, 0x80a7, 0xa085, 0x0001, + 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00f6, 0x00c6, + 0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0180, 0x7e12, + 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x080c, 0x9683, + 0x2f60, 0x2009, 0x004d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e, + 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c, + 0x8022, 0x2c78, 0x00ce, 0x0178, 0x7e12, 0x2c00, 0x781a, 0x781f, + 0x0003, 0x2021, 0x0005, 0x0439, 0x2f60, 0x2009, 0x004e, 0x080c, + 0x80a7, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, + 0x00c6, 0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0178, + 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0004, 0x0059, + 0x2f60, 0x2009, 0x0052, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e, + 0x00ce, 0x00fe, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, + 0x080c, 0x4e71, 0x0118, 0x2001, 0x9688, 0x0028, 0x080c, 0x4e43, + 0x0158, 0x2001, 0x968e, 0x0006, 0xa00e, 0x2400, 0x080c, 0x51df, + 0x080c, 0x510c, 0x000e, 0x0807, 0x2418, 0x080c, 0x6b15, 0x62a0, + 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x6900, + 0x008e, 0x080c, 0x681d, 0x2f08, 0x2648, 0x080c, 0xa712, 0x613c, + 0x81ff, 0x090c, 0x69a9, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188, + 0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, + 0x2009, 0x001f, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, + 0x080c, 0x8022, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0x9956, + 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x80a7, + 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188, + 0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, + 0x2009, 0x003d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, + 0x080c, 0x9807, 0x001e, 0x0180, 0x611a, 0x080c, 0x9956, 0x601f, + 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x80a7, 0xa085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, + 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188, 0x660a, + 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, + 0x0044, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0xa006, 0x0cd8, 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff, + 0x0110, 0x8211, 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6000, + 0xa086, 0x0000, 0x0190, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001, + 0xafa3, 0x2004, 0x0006, 0xa082, 0x0051, 0x000e, 0x0208, 0x8004, + 0x6016, 0x080c, 0xabb4, 0x603f, 0x0000, 0x000e, 0x0005, 0x0066, + 0x00c6, 0x00d6, 0x2031, 0xad52, 0x2634, 0xd6e4, 0x0128, 0x6618, + 0x2660, 0x6e48, 0x080c, 0x4dfc, 0x00de, 0x00ce, 0x006e, 0x0005, + 0x0006, 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003, + 0x0128, 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e, + 0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0148, 0x6834, 0xa086, + 0x0139, 0x0138, 0x6838, 0xd0fc, 0x0110, 0xa006, 0x0010, 0xa085, + 0x0001, 0x00de, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, + 0x00c6, 0x080c, 0x8022, 0x001e, 0x0190, 0x611a, 0x080c, 0x9956, + 0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x2ad9, 0x2009, 0x0028, + 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, + 0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0xad20, 0x2204, 0xa086, + 0x0074, 0x1148, 0x080c, 0x8943, 0x6003, 0x0001, 0x6007, 0x0029, + 0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x0005, + 0xa186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x4c30, 0x00e8, + 0xa186, 0x0015, 0x11e8, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014, + 0x11b8, 0x00d6, 0x6018, 0x2068, 0x080c, 0x4d72, 0x00de, 0x080c, + 0x89f7, 0x1170, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, + 0x0138, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x81f6, 0x0020, + 0x080c, 0x85f3, 0x080c, 0x8078, 0x0005, 0x6848, 0xa086, 0x0005, + 0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852, 0x0005, 0x00e6, + 0x0126, 0x2071, 0xad00, 0x2091, 0x8000, 0x7544, 0xa582, 0x0001, + 0x0608, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, + 0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98, + 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0018, 0x7058, 0xa502, + 0x1230, 0x754a, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704b, + 0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xb28c, 0x7014, + 0xd0e4, 0x0150, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, + 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x00c6, 0x00f6, + 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x601c, 0xa084, 0x000f, + 0x0013, 0x00ce, 0x0005, 0x9369, 0x985e, 0x9861, 0x9864, 0xa9a7, + 0xa9c2, 0xa9c5, 0x9369, 0x9369, 0x080c, 0x14f6, 0xe000, 0xe000, + 0x0005, 0xe000, 0xe000, 0x0005, 0x0009, 0x0005, 0x00f6, 0x2c78, + 0x080c, 0x5029, 0x0538, 0x080c, 0x8022, 0x1128, 0x2001, 0xafa5, + 0x2004, 0x783e, 0x00f8, 0x7818, 0x601a, 0x080c, 0x9956, 0x781c, + 0xa086, 0x0003, 0x0128, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0020, + 0x7808, 0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007, + 0x0035, 0x6003, 0x0001, 0x7950, 0x6152, 0x080c, 0x67a8, 0x080c, + 0x6c50, 0x2f60, 0x00fe, 0x0005, 0x0016, 0x00f6, 0x682c, 0x6032, + 0xa08e, 0x0001, 0x0138, 0xa086, 0x0005, 0x0140, 0xa006, 0x602a, + 0x602e, 0x00a0, 0x6820, 0xc0f4, 0xc0d5, 0x6822, 0x6810, 0x2078, + 0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x1e78, 0x6834, + 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036, + 0x6808, 0x603a, 0x6918, 0x611a, 0x6950, 0x6152, 0x601f, 0x0001, + 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x67a8, 0x6803, 0x0002, + 0x00fe, 0x001e, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x1118, + 0xa085, 0x0001, 0x0070, 0x6020, 0xd0f4, 0x1150, 0xc0f5, 0x6022, + 0x6010, 0x2078, 0x7828, 0x603a, 0x782c, 0x6036, 0x080c, 0x190b, + 0xa006, 0x00fe, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0034, + 0x01b8, 0xa08e, 0x0035, 0x01a0, 0xa08e, 0x0036, 0x0188, 0xa08e, + 0x0037, 0x0170, 0xa08e, 0x0038, 0x0158, 0xa08e, 0x0039, 0x0140, + 0xa08e, 0x003a, 0x0128, 0xa08e, 0x003b, 0x0110, 0xa085, 0x0001, + 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, + 0x2001, 0xaf9f, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, + 0x6665, 0x2001, 0xafa3, 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202, + 0x2001, 0xafa1, 0x200c, 0x8000, 0x2014, 0x2071, 0xaf8d, 0x711a, + 0x721e, 0x2001, 0x0064, 0x080c, 0x6665, 0x2001, 0xafa4, 0x82ff, + 0x1110, 0x2011, 0x0002, 0x2202, 0x2009, 0xafa5, 0xa280, 0x000a, + 0x200a, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, + 0x00e6, 0x2001, 0xafa3, 0x2003, 0x0028, 0x2001, 0xafa4, 0x2003, + 0x0014, 0x2071, 0xaf8d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, + 0xafa5, 0x2003, 0x001e, 0x00ee, 0x000e, 0x0005, 0x00d6, 0x6054, + 0xa06d, 0x0110, 0x080c, 0x15f0, 0x00de, 0x0005, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0178, + 0x611a, 0x0ca1, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, + 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, + 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015, + 0x1500, 0x7080, 0xa086, 0x0018, 0x11e0, 0x6010, 0x2068, 0x6a3c, + 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x6e05, 0x01d8, 0x706c, 0x6a50, + 0xa206, 0x1160, 0x7070, 0x6a54, 0xa206, 0x1140, 0x6218, 0xa290, + 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2b1e, 0x080c, 0x81f6, + 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de, + 0x0005, 0x7050, 0x6a54, 0xa206, 0x0d48, 0x0c80, 0x00c6, 0x0126, + 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0180, 0x611a, + 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0043, + 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, + 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015, + 0x11c0, 0x7080, 0xa086, 0x0004, 0x11a0, 0x6010, 0xa0e8, 0x000f, + 0x2c78, 0x080c, 0x6e05, 0x01a8, 0x706c, 0x6a08, 0xa206, 0x1130, + 0x7070, 0x6a0c, 0xa206, 0x1110, 0x080c, 0x2ad9, 0x080c, 0x81f6, + 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de, + 0x0005, 0x7050, 0x6a0c, 0xa206, 0x0d78, 0x0c80, 0x0016, 0x0026, + 0x684c, 0xd0ac, 0x0178, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0150, + 0x6860, 0xa106, 0x1118, 0x685c, 0xa206, 0x0120, 0x6962, 0x6a5e, + 0xa085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0036, 0x6310, + 0x2368, 0x684a, 0x6952, 0xa29e, 0x4000, 0x1188, 0x00c6, 0x6318, + 0x2360, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108, 0xc185, 0x6000, + 0xd0bc, 0x0108, 0xc18d, 0x6a66, 0x696a, 0x00ce, 0x0080, 0x6a66, + 0x3918, 0xa398, 0x0006, 0x231c, 0x686b, 0x0004, 0x6b72, 0x00c6, + 0x6318, 0x2360, 0x6004, 0xa084, 0x00ff, 0x686e, 0x00ce, 0x080c, + 0x510c, 0x003e, 0x00de, 0x0005, 0x00c6, 0x0026, 0x0016, 0xa186, + 0x0035, 0x0110, 0x6a34, 0x0008, 0x6a28, 0x080c, 0x9586, 0x01f0, + 0x2260, 0x611c, 0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x1190, + 0x6834, 0xa206, 0x0140, 0x6838, 0xa206, 0x1160, 0x6108, 0x6834, + 0xa106, 0x1140, 0x0020, 0x6008, 0x6938, 0xa106, 0x1118, 0x6018, + 0x6918, 0xa106, 0x001e, 0x002e, 0x00ce, 0x0005, 0xa085, 0x0001, + 0x0cc8, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, + 0x006e, 0x0005, 0x9a7a, 0x9eff, 0xa027, 0x9a7a, 0x9a7a, 0x9a7a, + 0x9a7a, 0x9a7a, 0x9ab2, 0xa0a3, 0x9a7a, 0x9a7a, 0x9a7a, 0x9a7a, + 0x9a7a, 0x9a7a, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010, + 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x9a95, 0xa4fd, 0x9a95, + 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0xa4c1, 0xa545, 0x9a95, + 0xaaea, 0xab1a, 0xaaea, 0xab1a, 0x9a95, 0x080c, 0x14f6, 0x0066, + 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, + 0x9ab0, 0xa1d8, 0xa295, 0xa2c2, 0xa346, 0x9ab0, 0xa433, 0xa3de, + 0xa0af, 0xa497, 0xa4ac, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0, + 0x080c, 0x14f6, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0x2100, 0xa1b2, + 0x0040, 0x1a04, 0x9e79, 0x0002, 0x9afc, 0x9cab, 0x9afc, 0x9afc, + 0x9afc, 0x9cb2, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, + 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, + 0x9afc, 0x9afc, 0x9afc, 0x9afe, 0x9b5a, 0x9b65, 0x9ba6, 0x9bc0, + 0x9c3e, 0x9c9c, 0x9afc, 0x9afc, 0x9cb5, 0x9afc, 0x9afc, 0x9cc4, + 0x9ccb, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9d42, 0x9afc, + 0x9afc, 0x9d4d, 0x9afc, 0x9afc, 0x9d18, 0x9afc, 0x9afc, 0x9afc, + 0x9d61, 0x9afc, 0x9afc, 0x9afc, 0x9dd5, 0x9afc, 0x9afc, 0x9afc, + 0x9afc, 0x9afc, 0x9afc, 0x9e40, 0x080c, 0x14f6, 0x080c, 0x502d, + 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, + 0x1140, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0804, + 0x9ca6, 0x080c, 0x501d, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, + 0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7, + 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, + 0x007e, 0x001e, 0x2e60, 0x080c, 0x4ecf, 0x001e, 0x002e, 0x003e, + 0x00ce, 0x00ee, 0x6618, 0x00c6, 0x2660, 0x080c, 0x4ceb, 0x00ce, + 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0278, + 0x080c, 0xa656, 0x1904, 0x9ba0, 0x080c, 0xa5f6, 0x1120, 0x6007, + 0x0008, 0x0804, 0x9ca6, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c, + 0xa801, 0x0128, 0x080c, 0xa656, 0x0d78, 0x0804, 0x9ba0, 0x6013, + 0x1900, 0x0c88, 0x6106, 0x080c, 0xa5a6, 0x6007, 0x0006, 0x0804, + 0x9ca6, 0x6007, 0x0007, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904, + 0x9e76, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, + 0xa686, 0x0006, 0x0188, 0xa686, 0x0004, 0x0170, 0x6e04, 0xa6b4, + 0x00ff, 0xa686, 0x0006, 0x0140, 0xa686, 0x0004, 0x0128, 0xa686, + 0x0005, 0x0110, 0x00de, 0x00e0, 0x080c, 0xa6b4, 0x11a0, 0xa686, + 0x0006, 0x1150, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, + 0x0000, 0x080c, 0x2b1e, 0x002e, 0x080c, 0x4d72, 0x6007, 0x000a, + 0x00de, 0x0804, 0x9ca6, 0x6007, 0x000b, 0x00de, 0x0804, 0x9ca6, + 0x080c, 0x2ad9, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x080c, 0xab4e, + 0x1904, 0x9e76, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686, + 0x0707, 0x0d70, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, + 0x0000, 0x080c, 0x2b1e, 0x002e, 0x6007, 0x000c, 0x0804, 0x9ca6, + 0x080c, 0x502d, 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, + 0xa086, 0x0008, 0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618, + 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06e8, + 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x002e, 0x0050, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, + 0x1904, 0x9ba0, 0x080c, 0xa6c1, 0x1120, 0x6007, 0x000e, 0x0804, + 0x9ca6, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, + 0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009, + 0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c, + 0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e, + 0x004e, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x2001, 0x0001, 0x080c, + 0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, + 0xad05, 0x2011, 0xb290, 0x080c, 0x8a7c, 0x003e, 0x002e, 0x001e, + 0x015e, 0xa005, 0x0168, 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004, + 0x0a04, 0x9ba0, 0xa682, 0x0007, 0x0a04, 0x9bea, 0x0804, 0x9ba0, + 0x6013, 0x1900, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c, 0x502d, + 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, + 0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618, 0xa6b0, 0x0001, + 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06b0, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x9ba0, + 0x080c, 0xa6e9, 0x1130, 0x080c, 0xa5f6, 0x1118, 0x6007, 0x0010, + 0x04e8, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, + 0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009, + 0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c, + 0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e, + 0x004e, 0x6007, 0x0001, 0x00d0, 0x080c, 0xa801, 0x0140, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x0958, 0x0804, 0x9ba0, 0x6013, + 0x1900, 0x6007, 0x0009, 0x0050, 0x080c, 0xab4e, 0x1904, 0x9e76, + 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0012, 0x6003, 0x0001, + 0x080c, 0x67ee, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, + 0x67ee, 0x0cc0, 0x6007, 0x0005, 0x0cc0, 0x080c, 0xab4e, 0x1904, + 0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0020, 0x6003, + 0x0001, 0x080c, 0x67ee, 0x0005, 0x6007, 0x0023, 0x6003, 0x0001, + 0x080c, 0x67ee, 0x0005, 0x080c, 0xab4e, 0x1904, 0x9e76, 0x080c, + 0x9e98, 0x1904, 0x9ba0, 0x0016, 0x0026, 0x2011, 0xb291, 0x2214, + 0xa286, 0xffff, 0x0190, 0x2c08, 0x080c, 0x9586, 0x01d8, 0x2260, + 0x2011, 0xb290, 0x2214, 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190, + 0x0006, 0x2214, 0xa206, 0x01e0, 0x0068, 0x2011, 0xb290, 0x2214, + 0x2c08, 0x080c, 0xa940, 0x11a0, 0x2011, 0xb291, 0x2214, 0xa286, + 0xffff, 0x01a0, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, + 0xb289, 0x2214, 0xa296, 0xffff, 0x1160, 0x6007, 0x0025, 0x0048, + 0x601c, 0xa086, 0x0007, 0x1d70, 0x080c, 0x8078, 0x2160, 0x6007, + 0x0025, 0x6003, 0x0001, 0x080c, 0x67ee, 0x002e, 0x001e, 0x0005, + 0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036, + 0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c, 0x8a7c, + 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, + 0x9ca6, 0x080c, 0x87bd, 0x080c, 0x574f, 0x1158, 0x0006, 0x0026, + 0x0036, 0x080c, 0x576b, 0x0110, 0x080c, 0x5726, 0x003e, 0x002e, + 0x000e, 0x0005, 0x6106, 0x080c, 0x9eb4, 0x6007, 0x002b, 0x0804, + 0x9ca6, 0x6007, 0x002c, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904, + 0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6106, 0x080c, 0x9eb8, + 0x1120, 0x6007, 0x002e, 0x0804, 0x9ca6, 0x6007, 0x002f, 0x0804, + 0x9ca6, 0x00e6, 0x00d6, 0x00c6, 0x6018, 0xa080, 0x0001, 0x200c, + 0xa184, 0x00ff, 0xa086, 0x0006, 0x0158, 0xa184, 0xff00, 0x8007, + 0xa086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0x9cab, + 0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904, 0x9dd2, 0x2071, 0xb28c, + 0x7010, 0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xad52, + 0x2004, 0xd0a4, 0x0140, 0x6018, 0x2068, 0x6810, 0xa106, 0x1118, + 0x6814, 0xa206, 0x01f8, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1580, + 0x2069, 0xad00, 0x6870, 0xa206, 0x1558, 0x686c, 0xa106, 0x1540, + 0x7210, 0x080c, 0x9586, 0x0548, 0x080c, 0xa9d4, 0x0530, 0x622a, + 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x67a8, 0x00ce, 0x00de, + 0x00ee, 0x0005, 0x7214, 0xa286, 0xffff, 0x0150, 0x080c, 0x9586, + 0x01a0, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x1170, 0x0c08, + 0x7210, 0x2c08, 0x080c, 0xa940, 0x2c10, 0x2160, 0x0130, 0x08c8, + 0x6007, 0x0037, 0x6013, 0x1500, 0x08e8, 0x6007, 0x0037, 0x6013, + 0x1700, 0x08c0, 0x6007, 0x0012, 0x08a8, 0x6018, 0xa080, 0x0001, + 0x2004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x1904, 0x9cab, + 0x00e6, 0x00d6, 0x00c6, 0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904, + 0x9e38, 0x2069, 0xad00, 0x2071, 0xb28c, 0x7008, 0x6036, 0x720c, + 0x623a, 0xa286, 0xffff, 0x1140, 0x7208, 0x00c6, 0x2c08, 0x080c, + 0xa940, 0x2c10, 0x00ce, 0x0588, 0x080c, 0x9586, 0x0570, 0x00c6, + 0x0026, 0x2260, 0x080c, 0x928f, 0x002e, 0x00ce, 0x7118, 0xa18c, + 0xff00, 0x810f, 0xa186, 0x0001, 0x0158, 0xa186, 0x0005, 0x0118, + 0xa186, 0x0007, 0x1178, 0xa280, 0x0004, 0x2004, 0xa005, 0x0150, + 0x0056, 0x7510, 0x7614, 0x080c, 0xa9eb, 0x005e, 0x00ce, 0x00de, + 0x00ee, 0x0005, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00, + 0x6003, 0x0001, 0x080c, 0x67a8, 0x0c88, 0x6007, 0x003b, 0x602b, + 0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x080c, 0x67a8, 0x0c30, + 0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0804, 0x9daa, + 0x00e6, 0x0026, 0x080c, 0x502d, 0x0558, 0x080c, 0x501d, 0x080c, + 0xabc5, 0x1520, 0x2071, 0xad00, 0x70d0, 0xc085, 0x70d2, 0x00f6, + 0x2079, 0x0100, 0x729c, 0xa284, 0x00ff, 0x706e, 0x78e6, 0xa284, + 0xff00, 0x7270, 0xa205, 0x7072, 0x78ea, 0x00fe, 0x70db, 0x0000, + 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0120, 0x2011, 0xafe0, 0x2013, + 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x28fa, 0x0010, 0x080c, 0xabf1, + 0x002e, 0x00ee, 0x080c, 0x8078, 0x0804, 0x9caa, 0x080c, 0x8078, + 0x0005, 0x2600, 0x0002, 0x9e81, 0x9e81, 0x9e81, 0x9e81, 0x9e81, + 0x9e83, 0x080c, 0x14f6, 0x080c, 0xab4e, 0x1d80, 0x0089, 0x1138, + 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005, 0x080c, + 0x2ad9, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005, + 0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, + 0xa686, 0x0006, 0x0170, 0xa686, 0x0004, 0x0158, 0x6e04, 0xa6b4, + 0x00ff, 0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085, + 0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0449, 0x00de, 0x0005, + 0x00d6, 0x0491, 0x11f0, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084, + 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4, 0x0118, 0x2009, + 0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824, + 0x080c, 0x2676, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x2b1e, + 0x0018, 0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069, + 0xb28d, 0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085, + 0x0001, 0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0xb28c, + 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x1140, 0x6800, 0xa084, + 0x00ff, 0xa08e, 0x0014, 0x0110, 0xa08e, 0x0010, 0x0005, 0x6004, + 0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x1130, 0x2008, + 0xa1b2, 0x0040, 0x1a04, 0x9ffb, 0x0092, 0xa1b6, 0x0027, 0x0120, + 0xa1b6, 0x0014, 0x190c, 0x14f6, 0x2001, 0x0007, 0x080c, 0x4c5d, + 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x9f5f, + 0x9f61, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f6f, 0x9ff4, 0x9fbf, + 0x9ff4, 0x9fd0, 0x9ff4, 0x9f6f, 0x9ff4, 0x9fec, 0x9ff4, 0x9fec, + 0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, + 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f5f, 0x9ff4, + 0x9f5f, 0x9f5f, 0x9ff4, 0x9f5f, 0x9ff1, 0x9ff4, 0x9f5f, 0x9f5f, + 0x9f5f, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, + 0x9f69, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9ff0, 0x9ff4, 0x9f5f, + 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x080c, + 0x14f6, 0x080c, 0x6b73, 0x6003, 0x0002, 0x080c, 0x6c50, 0x0804, + 0x9ffa, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x0804, 0x9ff4, 0x00f6, + 0x2079, 0xad51, 0x7804, 0x00fe, 0xd0ac, 0x1904, 0x9ff4, 0x2001, + 0x0000, 0x080c, 0x4c1e, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, + 0x00ff, 0x1140, 0x00f6, 0x2079, 0xad00, 0x7894, 0x8000, 0x7896, + 0x00fe, 0x00e0, 0x00c6, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x1140, + 0x6010, 0xa005, 0x0128, 0x00ce, 0x080c, 0x3cce, 0x0804, 0x9ff4, + 0x00ce, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002, 0x1138, 0x00f6, + 0x2079, 0xad00, 0x7894, 0x8000, 0x7896, 0x00fe, 0x2001, 0x0002, + 0x080c, 0x4c30, 0x080c, 0x6b73, 0x601f, 0x0001, 0x6003, 0x0001, + 0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00c6, 0x6118, + 0x2160, 0x2009, 0x0001, 0x080c, 0x6519, 0x00ce, 0x04d8, 0x6618, + 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686, + 0x0006, 0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410, + 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3cce, + 0x2001, 0x0006, 0x0489, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006, + 0x0048, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x00e9, 0x0020, + 0x0018, 0x0010, 0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x8078, + 0x080c, 0x6c50, 0x0005, 0x2600, 0x0002, 0xa003, 0xa003, 0xa003, + 0xa003, 0xa003, 0xa005, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x080c, + 0x8078, 0x080c, 0x6c50, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168, + 0x6900, 0xd184, 0x0188, 0x6104, 0xa18e, 0x000a, 0x1128, 0x699c, + 0xd1a4, 0x1110, 0x2001, 0x0007, 0x080c, 0x4c30, 0x2001, 0x0000, + 0x080c, 0x4c1e, 0x080c, 0x2aff, 0x00de, 0x001e, 0x0005, 0x00d6, + 0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2, + 0x000c, 0x1a0c, 0x14f6, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028, + 0xa1b6, 0x0016, 0x190c, 0x14f6, 0x006b, 0x0005, 0x86b9, 0x86b9, + 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0xa08f, 0xa056, 0x86b9, 0x86b9, + 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, + 0xa08f, 0xa096, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x00f6, 0x2079, + 0xad51, 0x7804, 0xd0ac, 0x11e0, 0x6018, 0xa07d, 0x01c8, 0x7800, + 0xd0f4, 0x1118, 0x7810, 0xa005, 0x1198, 0x2001, 0x0000, 0x080c, + 0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x601f, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00a8, + 0x2011, 0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1168, + 0x00c6, 0x080c, 0x4cdc, 0x0120, 0x00ce, 0x080c, 0x8078, 0x0028, + 0x080c, 0x493a, 0x00ce, 0x080c, 0x8078, 0x00fe, 0x0005, 0x6604, + 0xa6b6, 0x001e, 0x1110, 0x080c, 0x8078, 0x0005, 0x080c, 0x8940, + 0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010, + 0x080c, 0x8078, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, + 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa182, + 0x0040, 0x0002, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c7, 0xa0c5, + 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, + 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0x080c, 0x14f6, 0x00d6, + 0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6218, 0xa280, 0x002b, + 0x2004, 0xa005, 0x0120, 0x2021, 0x0000, 0x080c, 0xab96, 0x6106, + 0x2071, 0xb280, 0x7444, 0xa4a4, 0xff00, 0x0904, 0xa129, 0xa486, + 0x2000, 0x1130, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x663f, + 0x080c, 0x15d9, 0x090c, 0x14f6, 0x6003, 0x0007, 0x2d00, 0x6837, + 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, + 0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, + 0x0016, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, + 0x080c, 0x510c, 0x001e, 0xa486, 0x2000, 0x1130, 0x2019, 0x0017, + 0x080c, 0xa8eb, 0x0804, 0xa186, 0xa486, 0x0400, 0x1130, 0x2019, + 0x0002, 0x080c, 0xa89d, 0x0804, 0xa186, 0xa486, 0x0200, 0x1110, + 0x080c, 0xa882, 0xa486, 0x1000, 0x1110, 0x080c, 0xa8d0, 0x0804, + 0xa186, 0x2069, 0xb048, 0x6a00, 0xd284, 0x0904, 0xa1d5, 0xa284, + 0x0300, 0x1904, 0xa1cf, 0x6804, 0xa005, 0x0904, 0xa1c0, 0x2d78, + 0x6003, 0x0007, 0x080c, 0x15c0, 0x0904, 0xa18d, 0x7800, 0xd08c, + 0x1118, 0x7804, 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, 0x0000, + 0x6837, 0x0116, 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, 0x684a, + 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, 0x7928, + 0x698a, 0x792c, 0x698e, 0x7930, 0x6992, 0x7934, 0x6996, 0x6853, + 0x003d, 0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118, 0x684f, + 0x0040, 0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080, 0x0010, + 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0xb290, 0xad90, 0x0015, + 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0xa178, 0x200c, + 0x6982, 0x8000, 0x200c, 0x697e, 0x080c, 0x510c, 0x002e, 0x004e, + 0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x6013, 0x0100, 0x6003, + 0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c70, + 0x2069, 0xb292, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x11a8, + 0x2069, 0xb280, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110, 0xa18c, + 0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, + 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0888, 0x6013, 0x0200, 0x6003, + 0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0830, + 0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, + 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0804, 0xa186, 0x6013, + 0x0500, 0x0c98, 0x6013, 0x0600, 0x0818, 0x6013, 0x0200, 0x0800, + 0xa186, 0x0013, 0x1170, 0x6004, 0xa08a, 0x0040, 0x0a0c, 0x14f6, + 0xa08a, 0x0053, 0x1a0c, 0x14f6, 0xa082, 0x0040, 0x2008, 0x0804, + 0xa252, 0xa186, 0x0051, 0x0138, 0xa186, 0x0047, 0x11d8, 0x6004, + 0xa086, 0x0041, 0x0518, 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0, + 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699, + 0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0xa086, 0x0002, 0x1170, + 0x0804, 0xa295, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, + 0x14f6, 0x6004, 0xa082, 0x0040, 0x2008, 0x001a, 0x080c, 0x80be, + 0x0005, 0xa22c, 0xa22e, 0xa22e, 0xa22c, 0xa22c, 0xa22c, 0xa22c, + 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, + 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0x080c, 0x14f6, 0x080c, 0x6b73, + 0x080c, 0x6c50, 0x0036, 0x00d6, 0x6010, 0xa06d, 0x01c0, 0xad84, + 0xf000, 0x01a8, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc, 0x1178, + 0x2019, 0x0004, 0x080c, 0xa91f, 0x6013, 0x0000, 0x6014, 0xa005, + 0x1120, 0x2001, 0xafa4, 0x2004, 0x6016, 0x6003, 0x0007, 0x00de, + 0x003e, 0x0005, 0x0002, 0xa266, 0xa283, 0xa26f, 0xa28f, 0xa266, + 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, + 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0x080c, 0x14f6, + 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x080c, + 0x6b73, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003, + 0x0007, 0x2009, 0x0043, 0x080c, 0x80a7, 0x0010, 0x6003, 0x0002, + 0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73, 0x080c, 0xab55, 0x1120, + 0x080c, 0x6618, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c, + 0x6b73, 0x2009, 0x0041, 0x0804, 0xa3de, 0xa182, 0x0040, 0x0002, + 0xa2ab, 0xa2ad, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ae, + 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, + 0xa2ab, 0xa2b9, 0xa2ab, 0x080c, 0x14f6, 0x0005, 0x6003, 0x0004, + 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, + 0x0005, 0x00d6, 0x080c, 0x6618, 0x00de, 0x080c, 0xabb4, 0x080c, + 0x8078, 0x0005, 0xa182, 0x0040, 0x0002, 0xa2d8, 0xa2d8, 0xa2d8, + 0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa2da, 0xa2d8, 0xa2dd, 0xa316, + 0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa316, 0xa2d8, 0xa2d8, 0xa2d8, + 0x080c, 0x14f6, 0x080c, 0x80be, 0x0005, 0x2001, 0xad71, 0x2004, + 0xd0e4, 0x0158, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x0228, + 0x2001, 0x011f, 0x2004, 0x6036, 0x0010, 0x6037, 0x0000, 0x080c, + 0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x684c, 0xd0fc, + 0x0150, 0xa08c, 0x0003, 0xa18e, 0x0002, 0x0168, 0x2009, 0x0041, + 0x00de, 0x0804, 0xa3de, 0x6003, 0x0007, 0x6017, 0x0000, 0x080c, + 0x6618, 0x00de, 0x0005, 0x080c, 0xab55, 0x0110, 0x00de, 0x0005, + 0x080c, 0x6618, 0x080c, 0x8078, 0x00de, 0x0ca0, 0x0036, 0x080c, + 0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x6018, 0x2004, + 0xd0bc, 0x0188, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0140, + 0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a, + 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xa91f, 0x6014, + 0xa005, 0x1128, 0x2001, 0xafa4, 0x2004, 0x8003, 0x6016, 0x6013, + 0x0000, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0xa186, 0x0013, + 0x1150, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x080c, 0x6b73, + 0x080c, 0x6c50, 0x0005, 0xa186, 0x0027, 0x0118, 0xa186, 0x0014, + 0x1180, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x2001, 0x0007, + 0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, + 0x0005, 0xa182, 0x0040, 0x0002, 0xa37f, 0xa37f, 0xa37f, 0xa37f, + 0xa37f, 0xa37f, 0xa37f, 0xa381, 0xa38d, 0xa37f, 0xa37f, 0xa37f, + 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0x080c, + 0x14f6, 0x0036, 0x0046, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, + 0x080c, 0x1824, 0x004e, 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068, + 0x6810, 0x6a14, 0x0006, 0x0046, 0x0056, 0x6c7c, 0xa422, 0x6d80, + 0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a, + 0x005e, 0x004e, 0x000e, 0xa20d, 0x1178, 0x684c, 0xd0fc, 0x0120, + 0x2009, 0x0041, 0x00de, 0x0490, 0x6003, 0x0007, 0x6017, 0x0000, + 0x080c, 0x6618, 0x00de, 0x0005, 0x0006, 0x00f6, 0x2c78, 0x080c, + 0x5029, 0x00fe, 0x000e, 0x0120, 0x6003, 0x0002, 0x00de, 0x0005, + 0x2009, 0xad0d, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, + 0x6003, 0x0006, 0x0021, 0x080c, 0x661a, 0x00de, 0x0005, 0xd2fc, + 0x0140, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009, + 0x0010, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040, + 0x0208, 0x0062, 0xa186, 0x0013, 0x0120, 0xa186, 0x0014, 0x190c, + 0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005, 0xa401, 0xa408, + 0xa414, 0xa420, 0xa401, 0xa401, 0xa401, 0xa42f, 0xa401, 0xa403, + 0xa403, 0xa401, 0xa401, 0xa401, 0xa401, 0xa403, 0xa401, 0xa403, + 0xa401, 0x080c, 0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005, + 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6c50, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, + 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, + 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x0126, 0x2091, + 0x8000, 0x080c, 0x680b, 0x080c, 0x6d0d, 0x012e, 0x0005, 0xa016, + 0x080c, 0x1824, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x00d6, + 0xa182, 0x0040, 0x0023, 0x00de, 0x003e, 0x012e, 0x0005, 0xa44f, + 0xa451, 0xa463, 0xa47e, 0xa44f, 0xa44f, 0xa44f, 0xa493, 0xa44f, + 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0x080c, + 0x14f6, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x01f8, 0xa09c, 0x0003, + 0xa39e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, + 0x080c, 0x6c50, 0x0498, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0168, + 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, + 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0408, 0x6013, 0x0000, 0x6017, + 0x0000, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00c0, 0x6010, 0x2068, + 0x684c, 0xd0fc, 0x0d90, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0d68, + 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b, + 0x080c, 0x6d0d, 0x0018, 0xa016, 0x080c, 0x1824, 0x0005, 0x080c, + 0x6b73, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa, + 0x0036, 0x2019, 0x0029, 0x080c, 0xa91f, 0x003e, 0x00de, 0x080c, + 0x974e, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6c05, 0x6110, 0x81ff, + 0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa, 0x0036, 0x2019, 0x0029, + 0x080c, 0xa91f, 0x003e, 0x00de, 0x080c, 0x974e, 0x080c, 0x6d0d, + 0x0005, 0xa182, 0x0085, 0x0002, 0xa4cd, 0xa4cb, 0xa4cb, 0xa4d9, + 0xa4cb, 0xa4cb, 0xa4cb, 0x080c, 0x14f6, 0x6003, 0x000b, 0x6106, + 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, + 0x0005, 0x0026, 0x00e6, 0x080c, 0xab4e, 0x0118, 0x080c, 0x8078, + 0x00c8, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0xa7ce, + 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0xa296, + 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x67a8, + 0x080c, 0x6c50, 0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160, + 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c, + 0x14f6, 0xa082, 0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186, + 0x0014, 0x0118, 0x080c, 0x80be, 0x0050, 0x2001, 0x0007, 0x080c, + 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, + 0xa527, 0xa529, 0xa529, 0xa527, 0xa527, 0xa527, 0xa527, 0x080c, + 0x14f6, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, + 0xa182, 0x0085, 0x0a0c, 0x14f6, 0xa182, 0x008c, 0x1a0c, 0x14f6, + 0xa182, 0x0085, 0x0002, 0xa542, 0xa542, 0xa542, 0xa544, 0xa542, + 0xa542, 0xa542, 0x080c, 0x14f6, 0x0005, 0xa186, 0x0013, 0x0148, + 0xa186, 0x0014, 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x80be, + 0x0030, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, + 0x0036, 0x080c, 0xabb4, 0x603f, 0x0000, 0x2019, 0x000b, 0x0031, + 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, + 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x2049, 0x0000, 0x080c, + 0x7b9a, 0x009e, 0x008e, 0x1578, 0x0076, 0x2c38, 0x080c, 0x7c34, + 0x007e, 0x1548, 0x6000, 0xa086, 0x0000, 0x0528, 0x601c, 0xa086, + 0x0007, 0x0508, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1150, 0x080c, + 0xabb4, 0x601f, 0x0007, 0x2001, 0xafa3, 0x2004, 0x6016, 0x080c, + 0x190b, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f, + 0x00de, 0x6013, 0x0000, 0x080c, 0xabb4, 0x601f, 0x0007, 0x2001, + 0xafa3, 0x2004, 0x6016, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, + 0x0036, 0x0156, 0x2079, 0xb280, 0x7938, 0x783c, 0x080c, 0x2676, + 0x1904, 0xa5f1, 0x0016, 0x00c6, 0x080c, 0x4cdc, 0x15c0, 0x2011, + 0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1578, + 0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x7cf4, + 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x007e, + 0x001e, 0x0076, 0x2039, 0x0000, 0x080c, 0xa712, 0x007e, 0x080c, + 0x4ecf, 0x0026, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, + 0x0118, 0xa286, 0x0004, 0x1118, 0x62a0, 0x080c, 0x2b87, 0x002e, + 0x001e, 0x080c, 0x493a, 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce, + 0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, + 0x00e6, 0x0016, 0x2009, 0xad20, 0x2104, 0xa086, 0x0074, 0x1904, + 0xa64b, 0x2069, 0xb28e, 0x690c, 0xa182, 0x0100, 0x06c0, 0x6908, + 0xa184, 0x8000, 0x05e8, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x1160, + 0x6018, 0x2070, 0x7010, 0xa084, 0x00ff, 0x0118, 0x7000, 0xd0f4, + 0x0118, 0xa184, 0x0800, 0x0560, 0x6910, 0xa18a, 0x0001, 0x0610, + 0x6914, 0x2069, 0xb2ae, 0x6904, 0x81ff, 0x1198, 0x690c, 0xa182, + 0x0100, 0x02a8, 0x6908, 0x81ff, 0x1178, 0x6910, 0xa18a, 0x0001, + 0x0288, 0x6918, 0xa18a, 0x0001, 0x0298, 0x00d0, 0x6013, 0x0100, + 0x00a0, 0x6013, 0x0300, 0x0088, 0x6013, 0x0500, 0x0070, 0x6013, + 0x0700, 0x0058, 0x6013, 0x0900, 0x0040, 0x6013, 0x0b00, 0x0028, + 0x6013, 0x0f00, 0x0010, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0008, + 0xa006, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, + 0x0026, 0x0036, 0x0156, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, + 0xa286, 0x0006, 0x0190, 0xa286, 0x0004, 0x0178, 0xa394, 0xff00, + 0x8217, 0xa286, 0x0006, 0x0148, 0xa286, 0x0004, 0x0130, 0x00c6, + 0x2d60, 0x080c, 0x4ceb, 0x00ce, 0x04c0, 0x2011, 0xb296, 0xad98, + 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1580, 0x2011, 0xb29a, + 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1538, 0x0046, + 0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xad52, + 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6800, + 0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039, + 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x2001, + 0x0007, 0x080c, 0x4c5d, 0x001e, 0x004e, 0xa006, 0x015e, 0x003e, + 0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069, 0xb28e, 0x6800, + 0xa086, 0x0800, 0x0118, 0x6013, 0x0000, 0x0008, 0xa006, 0x00de, + 0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, + 0xb28c, 0x7930, 0x7834, 0x080c, 0x2676, 0x11a0, 0x080c, 0x4cdc, + 0x1188, 0x2011, 0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, + 0x8a7c, 0x1140, 0x2011, 0xb294, 0xac98, 0x0006, 0x20a9, 0x0004, + 0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce, + 0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, + 0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x11a0, 0x080c, + 0x4cdc, 0x1188, 0x2011, 0xb296, 0xac98, 0x000a, 0x20a9, 0x0004, + 0x080c, 0x8a7c, 0x1140, 0x2011, 0xb29a, 0xac98, 0x0006, 0x20a9, + 0x0004, 0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, + 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, + 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0xafd0, + 0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400, 0x2071, 0xad00, + 0x7644, 0x7064, 0x81ff, 0x0128, 0x8001, 0xa602, 0x1a04, 0xa78e, + 0x0018, 0xa606, 0x0904, 0xa78e, 0x2100, 0xac06, 0x0904, 0xa785, + 0x080c, 0xa990, 0x0904, 0xa785, 0x671c, 0xa786, 0x0001, 0x0904, + 0xa7a5, 0xa786, 0x0004, 0x0904, 0xa7a5, 0xa786, 0x0007, 0x05e8, + 0x2500, 0xac06, 0x05d0, 0x2400, 0xac06, 0x05b8, 0x080c, 0xa9a0, + 0x15a0, 0x88ff, 0x0118, 0x6050, 0xa906, 0x1578, 0x00d6, 0x6000, + 0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x190b, 0x001e, 0xa786, + 0x0008, 0x1148, 0x080c, 0x9789, 0x1130, 0x080c, 0x85f3, 0x00de, + 0x080c, 0x974e, 0x00d0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0190, + 0xa786, 0x0003, 0x1528, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, + 0x080c, 0xabfa, 0x0016, 0x080c, 0x97fd, 0x080c, 0x510c, 0x001e, + 0x080c, 0x9742, 0x00de, 0x080c, 0x974e, 0xace0, 0x0018, 0x2001, + 0xad16, 0x2004, 0xac02, 0x1210, 0x0804, 0xa726, 0x012e, 0x002e, + 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, + 0xa786, 0x0006, 0x19c0, 0xa386, 0x0005, 0x0128, 0x080c, 0xabfa, + 0x080c, 0xa91f, 0x08f8, 0x00de, 0x0c00, 0x080c, 0xa9a0, 0x19e8, + 0x81ff, 0x09d8, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x0130, + 0xa180, 0x0001, 0x2004, 0xa086, 0x002d, 0x1978, 0x6000, 0xa086, + 0x0002, 0x1958, 0x080c, 0x9778, 0x0130, 0x080c, 0x9789, 0x1928, + 0x080c, 0x85f3, 0x0038, 0x080c, 0x2aff, 0x080c, 0x9789, 0x1110, + 0x080c, 0x85f3, 0x080c, 0x974e, 0x0804, 0xa785, 0x00c6, 0x00e6, + 0x0016, 0x2c08, 0x2170, 0x080c, 0xa940, 0x001e, 0x0120, 0x601c, + 0xa084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xa7e6, 0xa7e6, + 0xa7e6, 0xa7e6, 0xa7e6, 0xa7e6, 0xa7e8, 0xa7e6, 0xa006, 0x0005, + 0x0046, 0x0016, 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, + 0x8427, 0x2c00, 0x2009, 0x0020, 0x080c, 0xa96c, 0x001e, 0x004e, + 0x0036, 0x2019, 0x0002, 0x080c, 0xa566, 0x003e, 0xa085, 0x0001, + 0x0005, 0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026, + 0x0036, 0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c, + 0x8a7c, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6, + 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0026, 0x0126, 0x2091, + 0x8000, 0x2740, 0x2061, 0xb400, 0x2079, 0x0001, 0x8fff, 0x0904, + 0xa875, 0x2071, 0xad00, 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04, + 0xa875, 0x88ff, 0x0128, 0x2800, 0xac06, 0x15b0, 0x2079, 0x0000, + 0x080c, 0xa990, 0x0588, 0x2400, 0xac06, 0x0570, 0x671c, 0xa786, + 0x0006, 0x1550, 0xa786, 0x0007, 0x0538, 0x88ff, 0x1140, 0x6018, + 0xa206, 0x1510, 0x85ff, 0x0118, 0x6050, 0xa106, 0x11e8, 0x00d6, + 0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xabb4, 0x601f, 0x0007, + 0x2001, 0xafa3, 0x2004, 0x6016, 0x080c, 0x190b, 0x6010, 0x2068, + 0x080c, 0x9596, 0x0120, 0x0046, 0x080c, 0xa91f, 0x004e, 0x00de, + 0x080c, 0x974e, 0x88ff, 0x1198, 0xace0, 0x0018, 0x2001, 0xad16, + 0x2004, 0xac02, 0x1210, 0x0804, 0xa826, 0xa006, 0x012e, 0x002e, + 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5, + 0x0001, 0x0ca0, 0x0076, 0x0056, 0x0086, 0x2041, 0x0000, 0x2029, + 0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x0096, 0x2049, 0x0000, + 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x7c34, + 0x080c, 0xa817, 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056, + 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, + 0x0000, 0x0016, 0x0036, 0x080c, 0x4cdc, 0x11b0, 0x2c10, 0x0056, + 0x0086, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x0096, 0x2049, + 0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, + 0x7c34, 0x080c, 0xa817, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, + 0xa8a9, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, + 0x0076, 0x0056, 0x6218, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001, + 0x2019, 0x0048, 0x0096, 0x2049, 0x0000, 0x080c, 0x7b9a, 0x009e, + 0x008e, 0x2039, 0x0000, 0x080c, 0x7c34, 0x2c20, 0x080c, 0xa817, + 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6, + 0x0156, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036, + 0x080c, 0x4cdc, 0x11c0, 0x2c10, 0x0086, 0x2041, 0x0000, 0x2828, + 0x0046, 0x2021, 0x0001, 0x080c, 0xab96, 0x004e, 0x0096, 0x2049, + 0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, + 0x7c34, 0x080c, 0xa817, 0x003e, 0x001e, 0x8108, 0x1f04, 0xa8f6, + 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016, + 0x00f6, 0x3800, 0xd08c, 0x0130, 0xad82, 0x1000, 0x02b0, 0xad82, + 0xad00, 0x0230, 0xad82, 0xe400, 0x0280, 0xad82, 0xffff, 0x1268, + 0x6800, 0xa07d, 0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x510c, + 0x2f68, 0x0cb0, 0x6b52, 0x080c, 0x510c, 0x00fe, 0x001e, 0x0005, + 0x00e6, 0x0046, 0x0036, 0x2061, 0xb400, 0x2071, 0xad00, 0x7444, + 0x7064, 0x8001, 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000, + 0xa086, 0x0000, 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0, + 0x0006, 0x2424, 0xa406, 0x0140, 0xace0, 0x0018, 0x2001, 0xad16, + 0x2004, 0xac02, 0x1220, 0x0c08, 0xa085, 0x0001, 0x0008, 0xa006, + 0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x15d9, + 0x000e, 0x090c, 0x14f6, 0x6837, 0x010d, 0x685e, 0x0026, 0x2010, + 0x080c, 0x9586, 0x2001, 0x0000, 0x0120, 0x2200, 0xa080, 0x0014, + 0x2004, 0x002e, 0x684a, 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006, + 0x68b2, 0x6802, 0x683a, 0x685a, 0x080c, 0x510c, 0x00de, 0x0005, + 0x6700, 0xa786, 0x0000, 0x0158, 0xa786, 0x0001, 0x0140, 0xa786, + 0x000a, 0x0128, 0xa786, 0x0009, 0x0110, 0xa085, 0x0001, 0x0005, + 0x00e6, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005, 0x0016, + 0x6004, 0xa08e, 0x001e, 0x11a0, 0x8007, 0x6130, 0xa18c, 0x00ff, + 0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005, + 0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c, 0x6c50, + 0x001e, 0x0005, 0xe000, 0xe000, 0x0005, 0x6020, 0xd0e4, 0x0158, + 0xd0cc, 0x0118, 0x080c, 0x9866, 0x0030, 0x080c, 0xabb4, 0x080c, + 0x6618, 0x080c, 0x8078, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084, + 0x000f, 0x0002, 0xa9e3, 0xa9e3, 0xa9e3, 0xa9e8, 0xa9e3, 0xa9e5, + 0xa9e5, 0xa9e3, 0xa9e5, 0xa006, 0x0005, 0x00c6, 0x2260, 0x00ce, + 0xa085, 0x0001, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f, + 0x0002, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xaa05, + 0xa9fa, 0xa9fa, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00, + 0x6003, 0x0001, 0x080c, 0x67a8, 0x0005, 0x00c6, 0x2260, 0x080c, + 0xabb4, 0x603f, 0x0000, 0x6020, 0xc0f4, 0xc0cc, 0x6022, 0x6037, + 0x0000, 0x00ce, 0x00d6, 0x2268, 0xa186, 0x0007, 0x1904, 0xaa60, + 0x6810, 0xa005, 0x0138, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x1110, + 0x00de, 0x08c0, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x67a8, + 0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002, 0x1904, + 0xaae7, 0x6010, 0xa005, 0x1138, 0x6000, 0xa086, 0x0007, 0x190c, + 0x14f6, 0x0804, 0xaae7, 0xa08c, 0xf000, 0x1130, 0x0028, 0x2068, + 0x6800, 0xa005, 0x1de0, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084, + 0x0003, 0xa086, 0x0002, 0x1180, 0x6010, 0x2068, 0x684c, 0xc0dc, + 0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043, + 0x080c, 0xa3de, 0x0804, 0xaae7, 0x2009, 0x0041, 0x0804, 0xaae1, + 0xa186, 0x0005, 0x15f0, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc, + 0x1118, 0x00de, 0x0804, 0xa9fa, 0xd0b4, 0x0128, 0xd0fc, 0x090c, + 0x14f6, 0x0804, 0xaa18, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, + 0x67a8, 0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002, + 0x0120, 0xa186, 0x0004, 0x1904, 0xaae7, 0x2071, 0xaffd, 0x7000, + 0xa086, 0x0003, 0x1128, 0x7004, 0xac06, 0x1110, 0x7003, 0x0000, + 0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000, + 0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0804, + 0xaae1, 0x0036, 0x00d6, 0x00d6, 0x080c, 0x15d9, 0x003e, 0x090c, + 0x14f6, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b, + 0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872, + 0x2360, 0x6020, 0xc0dd, 0x6022, 0x6018, 0xa080, 0x0028, 0x2004, + 0xa084, 0x00ff, 0x8007, 0x6350, 0x6b4a, 0x6846, 0x684f, 0x0000, + 0x6d6a, 0x6e66, 0x686f, 0x0001, 0x080c, 0x510c, 0x2019, 0x0045, + 0x6008, 0x2068, 0x080c, 0xa566, 0x2d00, 0x600a, 0x601f, 0x0006, + 0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x00de, 0x003e, + 0x0038, 0x603f, 0x0000, 0x6003, 0x0007, 0x080c, 0xa3de, 0x00ce, + 0x00de, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, + 0x2008, 0x00c2, 0xa186, 0x0027, 0x1178, 0x080c, 0x6b73, 0x0036, + 0x00d6, 0x6010, 0x2068, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00de, + 0x003e, 0x080c, 0x6c50, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c, + 0x80be, 0x0005, 0xab13, 0xab11, 0xab11, 0xab11, 0xab11, 0xab11, + 0xab13, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x6003, 0x000c, 0x080c, + 0x6c50, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208, + 0x001a, 0x080c, 0x80be, 0x0005, 0xab2b, 0xab2b, 0xab2b, 0xab2b, + 0xab2d, 0xab4b, 0xab2b, 0x080c, 0x14f6, 0x00d6, 0x2c68, 0x080c, + 0x8022, 0x01a0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xb28e, + 0x210c, 0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x600b, 0xffff, + 0x6918, 0x611a, 0x601f, 0x0004, 0x080c, 0x67a8, 0x2d60, 0x080c, + 0x8078, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005, 0x00e6, 0x6018, + 0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x6010, 0xa080, 0x0013, + 0x200c, 0xd1ec, 0x05d0, 0x2001, 0xad71, 0x2004, 0xd0ec, 0x05a8, + 0x6003, 0x0002, 0x6020, 0xc0e5, 0x6022, 0xd1ac, 0x0180, 0x00f6, + 0x2c78, 0x080c, 0x5025, 0x00fe, 0x0150, 0x2001, 0xafa5, 0x2004, + 0x603e, 0x2009, 0xad71, 0x210c, 0xd1f4, 0x11e8, 0x0080, 0x2009, + 0xad71, 0x210c, 0xd1f4, 0x0128, 0x6020, 0xc0e4, 0x6022, 0xa006, + 0x00a0, 0x2001, 0xafa5, 0x200c, 0x8103, 0xa100, 0x603e, 0x6018, + 0xa088, 0x002b, 0x2104, 0xa005, 0x0118, 0xa088, 0x0003, 0x0cd0, + 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, 0x0005, 0x0016, 0x00c6, + 0x00e6, 0x6150, 0xa2f0, 0x002b, 0x2e04, 0x2060, 0x8cff, 0x0180, + 0x84ff, 0x1118, 0x6050, 0xa106, 0x1138, 0x600c, 0x2072, 0x080c, + 0x6618, 0x080c, 0x8078, 0x0010, 0xacf0, 0x0003, 0x2e64, 0x0c70, + 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x6018, 0xa0e8, 0x002b, + 0x2d04, 0xa005, 0x0140, 0xac06, 0x0120, 0x2d04, 0xa0e8, 0x0003, + 0x0cb8, 0x600c, 0x206a, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, + 0x2011, 0xad27, 0x2204, 0xa084, 0x00ff, 0x2019, 0xb28e, 0x2334, + 0xa636, 0x11d8, 0x8318, 0x2334, 0x2204, 0xa084, 0xff00, 0xa636, + 0x11a0, 0x2011, 0xb290, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, + 0x080c, 0x8a7c, 0x1150, 0x2011, 0xb294, 0x6018, 0xa098, 0x0006, + 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1100, 0x015e, 0x003e, 0x002e, + 0x0005, 0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x080c, 0x28fa, + 0x00ee, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0108, + 0x0011, 0x00ee, 0x0005, 0x6850, 0xc0e5, 0x6852, 0x0005, 0x00e6, + 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, + 0x2091, 0x8000, 0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424, + 0x2061, 0xb400, 0x2071, 0xad00, 0x7644, 0x7064, 0xa606, 0x0578, + 0x671c, 0xa786, 0x0001, 0x0118, 0xa786, 0x0008, 0x1500, 0x2500, + 0xac06, 0x01e8, 0x2400, 0xac06, 0x01d0, 0x080c, 0xa990, 0x01b8, + 0x080c, 0xa9a0, 0x11a0, 0x6000, 0xa086, 0x0004, 0x1120, 0x0016, + 0x080c, 0x190b, 0x001e, 0x080c, 0x9778, 0x1110, 0x080c, 0x2aff, + 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x080c, 0x974e, 0xace0, + 0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1208, 0x0858, 0x012e, + 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee, + 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xad40, + 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030, + 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a, 0x0451, 0x00ee, + 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, + 0x2071, 0xad40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, + 0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a, + 0x0081, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, + 0x2091, 0x8000, 0x2071, 0xad42, 0x0021, 0x00ee, 0x000e, 0x012e, + 0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, + 0x2072, 0x0005, 0x00e6, 0x2071, 0xad40, 0x0c99, 0x00ee, 0x0005, + 0x00e6, 0x2071, 0xad44, 0x0c69, 0x00ee, 0x0005, 0x0001, 0x0002, + 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, + 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x8529 +}; + diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index c7e78dcf0..1fd5fc6d0 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -1018,7 +1017,7 @@ static inline void cmd_frob(struct Command_Entry *cmd, struct scsi_cmnd *Cmnd, if (Cmnd->device->tagged_supported) { if (qpti->cmd_count[Cmnd->device->id] == 0) qpti->tag_ages[Cmnd->device->id] = jiffies; - if (time_after(jiffies, qpti->tag_ages[Cmnd->device->id] + (5*HZ))) { + if ((jiffies - qpti->tag_ages[Cmnd->device->id]) > (5*HZ)) { cmd->control_flags = CFLAG_ORDERED_TAG; qpti->tag_ages[Cmnd->device->id] = jiffies; } else diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index f16f92a6e..b00af0884 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -37,7 +37,7 @@ #include #define DRV_NAME "sata_mv" -#define DRV_VERSION "0.7" +#define DRV_VERSION "0.5" enum { /* BAR's are enumerated in terms of pci_resource_start() terms */ @@ -50,12 +50,6 @@ enum { MV_PCI_REG_BASE = 0, MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */ - MV_IRQ_COAL_CAUSE = (MV_IRQ_COAL_REG_BASE + 0x08), - MV_IRQ_COAL_CAUSE_LO = (MV_IRQ_COAL_REG_BASE + 0x88), - MV_IRQ_COAL_CAUSE_HI = (MV_IRQ_COAL_REG_BASE + 0x8c), - MV_IRQ_COAL_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xcc), - MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0), - MV_SATAHC0_REG_BASE = 0x20000, MV_FLASH_CTL = 0x1046c, MV_GPIO_PORT_CTL = 0x104f0, @@ -234,9 +228,7 @@ enum { MV_HP_ERRATA_50XXB2 = (1 << 2), MV_HP_ERRATA_60X1B2 = (1 << 3), MV_HP_ERRATA_60X1C0 = (1 << 4), - MV_HP_ERRATA_XX42A0 = (1 << 5), - MV_HP_50XX = (1 << 6), - MV_HP_GEN_IIE = (1 << 7), + MV_HP_50XX = (1 << 5), /* Port private flags (pp_flags) */ MV_PP_FLAG_EDMA_EN = (1 << 0), @@ -245,9 +237,6 @@ enum { #define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX) #define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0) -#define IS_GEN_I(hpriv) IS_50XX(hpriv) -#define IS_GEN_II(hpriv) IS_60XX(hpriv) -#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) enum { /* Our DMA boundary is determined by an ePRD being unable to handle @@ -266,8 +255,6 @@ enum chip_type { chip_5080, chip_604x, chip_608x, - chip_6042, - chip_7042, }; /* Command ReQuest Block: 32B */ @@ -278,14 +265,6 @@ struct mv_crqb { u16 ata_cmd[11]; }; -struct mv_crqb_iie { - u32 addr; - u32 addr_hi; - u32 flags; - u32 len; - u32 ata_cmd[4]; -}; - /* Command ResPonse Block: 8B */ struct mv_crpb { u16 id; @@ -308,6 +287,9 @@ struct mv_port_priv { dma_addr_t crpb_dma; struct mv_sg *sg_tbl; dma_addr_t sg_tbl_dma; + + unsigned req_producer; /* cp of req_in_ptr */ + unsigned rsp_consumer; /* cp of rsp_out_ptr */ u32 pp_flags; }; @@ -346,8 +328,7 @@ static void mv_host_stop(struct ata_host_set *host_set); static int mv_port_start(struct ata_port *ap); static void mv_port_stop(struct ata_port *ap); static void mv_qc_prep(struct ata_queued_cmd *qc); -static void mv_qc_prep_iie(struct ata_queued_cmd *qc); -static unsigned int mv_qc_issue(struct ata_queued_cmd *qc); +static int mv_qc_issue(struct ata_queued_cmd *qc); static irqreturn_t mv_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void mv_eng_timeout(struct ata_port *ap); @@ -381,9 +362,11 @@ static struct scsi_host_template mv_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = MV_USE_Q_DEPTH, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = MV_MAX_SG_CT / 2, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -447,33 +430,6 @@ static const struct ata_port_operations mv6_ops = { .host_stop = mv_host_stop, }; -static const struct ata_port_operations mv_iie_ops = { - .port_disable = ata_port_disable, - - .tf_load = ata_tf_load, - .tf_read = ata_tf_read, - .check_status = ata_check_status, - .exec_command = ata_exec_command, - .dev_select = ata_std_dev_select, - - .phy_reset = mv_phy_reset, - - .qc_prep = mv_qc_prep_iie, - .qc_issue = mv_qc_issue, - - .eng_timeout = mv_eng_timeout, - - .irq_handler = mv_interrupt, - .irq_clear = mv_irq_clear, - - .scr_read = mv_scr_read, - .scr_write = mv_scr_write, - - .port_start = mv_port_start, - .port_stop = mv_port_stop, - .host_stop = mv_host_stop, -}; - static const struct ata_port_info mv_port_info[] = { { /* chip_504x */ .sht = &mv_sht, @@ -511,21 +467,6 @@ static const struct ata_port_info mv_port_info[] = { .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &mv6_ops, }, - { /* chip_6042 */ - .sht = &mv_sht, - .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), - .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &mv_iie_ops, - }, - { /* chip_7042 */ - .sht = &mv_sht, - .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | - MV_FLAG_DUAL_HC), - .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &mv_iie_ops, - }, }; static const struct pci_device_id mv_pci_tbl[] = { @@ -536,7 +477,6 @@ static const struct pci_device_id mv_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x}, - {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6042), 0, 0, chip_6042}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x}, @@ -632,8 +572,8 @@ static void mv_irq_clear(struct ata_port *ap) * @base: port base address * @pp: port private data * - * Verify the local cache of the eDMA state is accurate with a - * WARN_ON. + * Verify the local cache of the eDMA state is accurate with an + * assert. * * LOCKING: * Inherited from caller. @@ -644,15 +584,15 @@ static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp) writelfl(EDMA_EN, base + EDMA_CMD_OFS); pp->pp_flags |= MV_PP_FLAG_EDMA_EN; } - WARN_ON(!(EDMA_EN & readl(base + EDMA_CMD_OFS))); + assert(EDMA_EN & readl(base + EDMA_CMD_OFS)); } /** * mv_stop_dma - Disable eDMA engine * @ap: ATA channel to manipulate * - * Verify the local cache of the eDMA state is accurate with a - * WARN_ON. + * Verify the local cache of the eDMA state is accurate with an + * assert. * * LOCKING: * Inherited from caller. @@ -670,7 +610,7 @@ static void mv_stop_dma(struct ata_port *ap) writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; } else { - WARN_ON(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)); + assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS))); } /* now properly wait for the eDMA to stop */ @@ -750,7 +690,7 @@ static void mv_dump_all_regs(void __iomem *mmio_base, int port, mv_dump_mem(mmio_base+0xf00, 0x4); mv_dump_mem(mmio_base+0x1d00, 0x6c); for (hc = start_hc; hc < start_hc + num_hcs; hc++) { - hc_base = mv_hc_base(mmio_base, hc); + hc_base = mv_hc_base(mmio_base, port >> MV_PORT_HC_SHIFT); DPRINTK("HC regs (HC %i):\n", hc); mv_dump_mem(hc_base, 0x1c); } @@ -833,33 +773,6 @@ static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev) dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma); } -static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio) -{ - u32 cfg = readl(port_mmio + EDMA_CFG_OFS); - - /* set up non-NCQ EDMA configuration */ - cfg &= ~0x1f; /* clear queue depth */ - cfg &= ~EDMA_CFG_NCQ; /* clear NCQ mode */ - cfg &= ~(1 << 9); /* disable equeue */ - - if (IS_GEN_I(hpriv)) - cfg |= (1 << 8); /* enab config burst size mask */ - - else if (IS_GEN_II(hpriv)) - cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN; - - else if (IS_GEN_IIE(hpriv)) { - cfg |= (1 << 23); /* dis RX PM port mask */ - cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */ - cfg &= ~(1 << 19); /* dis 128-entry queue (for now?) */ - cfg |= (1 << 18); /* enab early completion */ - cfg |= (1 << 17); /* enab host q cache */ - cfg |= (1 << 22); /* enab cutthrough */ - } - - writelfl(cfg, port_mmio + EDMA_CFG_OFS); -} - /** * mv_port_start - Port specific init/start routine. * @ap: ATA channel to manipulate @@ -873,7 +786,6 @@ static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio) static int mv_port_start(struct ata_port *ap) { struct device *dev = ap->host_set->dev; - struct mv_host_priv *hpriv = ap->host_set->private_data; struct mv_port_priv *pp; void __iomem *port_mmio = mv_ap_base(ap); void *mem; @@ -917,29 +829,22 @@ static int mv_port_start(struct ata_port *ap) pp->sg_tbl = mem; pp->sg_tbl_dma = mem_dma; - mv_edma_cfg(hpriv, port_mmio); + writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT | + EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS); writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK, port_mmio + EDMA_REQ_Q_IN_PTR_OFS); - if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0) - writelfl(pp->crqb_dma & 0xffffffff, - port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); - else - writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); + writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); + writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); - - if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0) - writelfl(pp->crpb_dma & 0xffffffff, - port_mmio + EDMA_RSP_Q_IN_PTR_OFS); - else - writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); - writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); + pp->req_producer = pp->rsp_consumer = 0; + /* Don't turn on EDMA here...do it before DMA commands only. Else * we'll be unable to send non-data, PIO, etc due to restricted access * to shadow regs. @@ -1010,7 +915,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); - pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff); + pp->sg_tbl[i].flags_size = cpu_to_le32(len); sg_len -= len; addr += len; @@ -1023,16 +928,16 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) } } -static inline unsigned mv_inc_q_index(unsigned index) +static inline unsigned mv_inc_q_index(unsigned *index) { - return (index + 1) & MV_MAX_Q_DEPTH_MASK; + *index = (*index + 1) & MV_MAX_Q_DEPTH_MASK; + return *index; } static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last) { - u16 tmp = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS | + *cmdw = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS | (last ? CRQB_CMD_LAST : 0); - *cmdw = cpu_to_le16(tmp); } /** @@ -1054,29 +959,31 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) u16 *cw; struct ata_taskfile *tf; u16 flags = 0; - unsigned in_index; - if (ATA_PROT_DMA != qc->tf.protocol) + if (ATA_PROT_DMA != qc->tf.protocol) { return; + } + + /* the req producer index should be the same as we remember it */ + assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> + EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + pp->req_producer); /* Fill in command request block */ - if (!(qc->tf.flags & ATA_TFLAG_WRITE)) + if (!(qc->tf.flags & ATA_TFLAG_WRITE)) { flags |= CRQB_FLAG_READ; - WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); + } + assert(MV_MAX_Q_DEPTH > qc->tag); flags |= qc->tag << CRQB_TAG_SHIFT; - /* get current queue index from hardware */ - in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) - >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; - - pp->crqb[in_index].sg_addr = + pp->crqb[pp->req_producer].sg_addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); - pp->crqb[in_index].sg_addr_hi = + pp->crqb[pp->req_producer].sg_addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); - pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags); + pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags); - cw = &pp->crqb[in_index].ata_cmd[0]; + cw = &pp->crqb[pp->req_producer].ata_cmd[0]; tf = &qc->tf; /* Sadly, the CRQB cannot accomodate all registers--there are @@ -1122,76 +1029,9 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) mv_crqb_pack_cmd(cw++, tf->device, ATA_REG_DEVICE, 0); mv_crqb_pack_cmd(cw++, tf->command, ATA_REG_CMD, 1); /* last */ - if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; - mv_fill_sg(qc); -} - -/** - * mv_qc_prep_iie - Host specific command preparation. - * @qc: queued command to prepare - * - * This routine simply redirects to the general purpose routine - * if command is not DMA. Else, it handles prep of the CRQB - * (command request block), does some sanity checking, and calls - * the SG load routine. - * - * LOCKING: - * Inherited from caller. - */ -static void mv_qc_prep_iie(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct mv_port_priv *pp = ap->private_data; - struct mv_crqb_iie *crqb; - struct ata_taskfile *tf; - unsigned in_index; - u32 flags = 0; - - if (ATA_PROT_DMA != qc->tf.protocol) - return; - - /* Fill in Gen IIE command request block - */ - if (!(qc->tf.flags & ATA_TFLAG_WRITE)) - flags |= CRQB_FLAG_READ; - - WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); - flags |= qc->tag << CRQB_TAG_SHIFT; - - /* get current queue index from hardware */ - in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) - >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; - - crqb = (struct mv_crqb_iie *) &pp->crqb[in_index]; - crqb->addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); - crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); - crqb->flags = cpu_to_le32(flags); - - tf = &qc->tf; - crqb->ata_cmd[0] = cpu_to_le32( - (tf->command << 16) | - (tf->feature << 24) - ); - crqb->ata_cmd[1] = cpu_to_le32( - (tf->lbal << 0) | - (tf->lbam << 8) | - (tf->lbah << 16) | - (tf->device << 24) - ); - crqb->ata_cmd[2] = cpu_to_le32( - (tf->hob_lbal << 0) | - (tf->hob_lbam << 8) | - (tf->hob_lbah << 16) | - (tf->hob_feature << 24) - ); - crqb->ata_cmd[3] = cpu_to_le32( - (tf->nsect << 0) | - (tf->hob_nsect << 8) - ); - - if (!(qc->flags & ATA_QCFLAG_DMAMAP)) + if (!(qc->flags & ATA_QCFLAG_DMAMAP)) { return; + } mv_fill_sg(qc); } @@ -1207,11 +1047,10 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) * LOCKING: * Inherited from caller. */ -static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) +static int mv_qc_issue(struct ata_queued_cmd *qc) { void __iomem *port_mmio = mv_ap_base(qc->ap); struct mv_port_priv *pp = qc->ap->private_data; - unsigned in_index; u32 in_ptr; if (ATA_PROT_DMA != qc->tf.protocol) { @@ -1223,20 +1062,23 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) return ata_qc_issue_prot(qc); } - in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS); - in_index = (in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; + in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS); + /* the req producer index should be the same as we remember it */ + assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + pp->req_producer); /* until we do queuing, the queue should be empty at this point */ - WARN_ON(in_index != ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) - >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); + assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >> + EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); - in_index = mv_inc_q_index(in_index); /* now incr producer index */ + mv_inc_q_index(&pp->req_producer); /* now incr producer index */ mv_start_dma(port_mmio, pp); /* and write the request in pointer to kick the EDMA to life */ in_ptr &= EDMA_REQ_Q_BASE_LO_MASK; - in_ptr |= in_index << EDMA_REQ_Q_PTR_SHIFT; + in_ptr |= pp->req_producer << EDMA_REQ_Q_PTR_SHIFT; writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS); return 0; @@ -1248,7 +1090,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) * * This routine is for use when the port is in DMA mode, when it * will be using the CRPB (command response block) method of - * returning command completion information. We check indices + * returning command completion information. We assert indices * are good, grab status, and bump the response consumer index to * prove that we're up to date. * @@ -1259,26 +1101,28 @@ static u8 mv_get_crpb_status(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; - unsigned out_index; u32 out_ptr; u8 ata_status; - out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); - out_index = (out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; + out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); - ata_status = le16_to_cpu(pp->crpb[out_index].flags) - >> CRPB_FLAG_STATUS_SHIFT; + /* the response consumer index should be the same as we remember it */ + assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + pp->rsp_consumer); + + ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT; /* increment our consumer index... */ - out_index = mv_inc_q_index(out_index); + pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); /* and, until we do NCQ, there should only be 1 CRPB waiting */ - WARN_ON(out_index != ((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) - >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); + assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> + EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + pp->rsp_consumer); /* write out our inc'd consumer index so EDMA knows we're caught up */ out_ptr &= EDMA_RSP_Q_BASE_LO_MASK; - out_ptr |= out_index << EDMA_RSP_Q_PTR_SHIFT; + out_ptr |= pp->rsp_consumer << EDMA_RSP_Q_PTR_SHIFT; writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); /* Return ATA status register for completed CRPB */ @@ -1288,7 +1132,6 @@ static u8 mv_get_crpb_status(struct ata_port *ap) /** * mv_err_intr - Handle error interrupts on the port * @ap: ATA channel to manipulate - * @reset_allowed: bool: 0 == don't trigger from reset here * * In most cases, just clear the interrupt and move on. However, * some cases require an eDMA reset, which is done right before @@ -1299,7 +1142,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap) * LOCKING: * Inherited from caller. */ -static void mv_err_intr(struct ata_port *ap, int reset_allowed) +static void mv_err_intr(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); u32 edma_err_cause, serr = 0; @@ -1321,8 +1164,9 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed) writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); /* check for fatal here and recover if needed */ - if (reset_allowed && (EDMA_ERR_FATAL & edma_err_cause)) + if (EDMA_ERR_FATAL & edma_err_cause) { mv_stop_and_reset(ap); + } } /** @@ -1346,6 +1190,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, { void __iomem *mmio = host_set->mmio_base; void __iomem *hc_mmio = mv_hc_base(mmio, hc); + struct ata_port *ap; struct ata_queued_cmd *qc; u32 hc_irq_cause; int shift, port, port0, hard_port, handled; @@ -1368,37 +1213,25 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { u8 ata_status = 0; - struct ata_port *ap = host_set->ports[port]; - struct mv_port_priv *pp = ap->private_data; - - hard_port = mv_hardport_from_port(port); /* range 0..3 */ + ap = host_set->ports[port]; + hard_port = port & MV_PORT_MASK; /* range 0-3 */ handled = 0; /* ensure ata_status is set if handled++ */ - /* Note that DEV_IRQ might happen spuriously during EDMA, - * and should be ignored in such cases. - * The cause of this is still under investigation. - */ - if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { - /* EDMA: check for response queue interrupt */ - if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { - ata_status = mv_get_crpb_status(ap); - handled = 1; - } - } else { - /* PIO: check for device (drive) interrupt */ - if ((DEV_IRQ << hard_port) & hc_irq_cause) { - ata_status = readb((void __iomem *) + if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { + /* new CRPB on the queue; just one at a time until NCQ + */ + ata_status = mv_get_crpb_status(ap); + handled++; + } else if ((DEV_IRQ << hard_port) & hc_irq_cause) { + /* received ATA IRQ; read the status reg to clear INTRQ + */ + ata_status = readb((void __iomem *) ap->ioaddr.status_addr); - handled = 1; - /* ignore spurious intr if drive still BUSY */ - if (ata_status & ATA_BUSY) { - ata_status = 0; - handled = 0; - } - } + handled++; } - if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)) + if (ap && + (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) continue; err_mask = ac_err_mask(ata_status); @@ -1408,14 +1241,14 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, shift++; /* skip bit 8 in the HC Main IRQ reg */ } if ((PORT0_ERR << shift) & relevant) { - mv_err_intr(ap, 1); + mv_err_intr(ap); err_mask |= AC_ERR_OTHER; - handled = 1; + handled++; } - if (handled) { + if (handled && ap) { qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) { + if (NULL != qc) { VPRINTK("port %u IRQ found for qc, " "ata_status 0x%x\n", port,ata_status); /* mark qc status appropriately */ @@ -1450,7 +1283,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, struct ata_host_set *host_set = dev_instance; unsigned int hc, handled = 0, n_hcs; void __iomem *mmio = host_set->mmio_base; - struct mv_host_priv *hpriv; u32 irq_stat; irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS); @@ -1472,17 +1304,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, handled++; } } - - hpriv = host_set->private_data; - if (IS_60XX(hpriv)) { - /* deal with the interrupt coalescing bits */ - if (irq_stat & (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE)) { - writelfl(0, mmio + MV_IRQ_COAL_CAUSE_LO); - writelfl(0, mmio + MV_IRQ_COAL_CAUSE_HI); - writelfl(0, mmio + MV_IRQ_COAL_CAUSE); - } - } - if (PCI_ERR & irq_stat) { printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n", readl(mmio + PCI_IRQ_CAUSE_OFS)); @@ -1863,12 +1684,6 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, m2 |= hpriv->signal[port].pre; m2 &= ~(1 << 16); - /* according to mvSata 3.6.1, some IIE values are fixed */ - if (IS_GEN_IIE(hpriv)) { - m2 &= ~0xC30FF01F; - m2 |= 0x0000900F; - } - writel(m2, port_mmio + PHY_MODE2); } @@ -1881,8 +1696,7 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, if (IS_60XX(hpriv)) { u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); - ifctl |= (1 << 7); /* enable gen2i speed */ - ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */ + ifctl |= (1 << 12) | (1 << 7); writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); } @@ -2047,15 +1861,24 @@ static void mv_eng_timeout(struct ata_port *ap) ap->host_set->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd); - spin_lock_irqsave(&ap->host_set->lock, flags); - mv_err_intr(ap, 0); + mv_err_intr(ap); mv_stop_and_reset(ap); - spin_unlock_irqrestore(&ap->host_set->lock, flags); - WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); - if (qc->flags & ATA_QCFLAG_ACTIVE) { - qc->err_mask |= AC_ERR_TIMEOUT; - ata_eh_qc_complete(qc); + if (!qc) { + printk(KERN_ERR "ata%u: BUG: timeout without command\n", + ap->id); + } else { + /* hack alert! We cannot use the supplied completion + * function from inside the ->eh_strategy_handler() thread. + * libata is the only user of ->eh_strategy_handler() in + * any kernel, so the default scsi_done() assumes it is + * not being called from the SCSI EH. + */ + spin_lock_irqsave(&ap->host_set->lock, flags); + qc->scsidone = scsi_finish_command; + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); + spin_unlock_irqrestore(&ap->host_set->lock, flags); } } @@ -2175,27 +1998,6 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, } break; - case chip_7042: - case chip_6042: - hpriv->ops = &mv6xxx_ops; - - hp_flags |= MV_HP_GEN_IIE; - - switch (rev_id) { - case 0x0: - hp_flags |= MV_HP_ERRATA_XX42A0; - break; - case 0x1: - hp_flags |= MV_HP_ERRATA_60X1C0; - break; - default: - dev_printk(KERN_WARNING, &pdev->dev, - "Applying 60X1C0 workarounds to unknown rev\n"); - hp_flags |= MV_HP_ERRATA_60X1C0; - break; - } - break; - default: printk(KERN_ERR DRV_NAME ": BUG: invalid board index %u\n", board_idx); return 1; @@ -2250,8 +2052,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, void __iomem *port_mmio = mv_port_base(mmio, port); u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); - ifctl |= (1 << 7); /* enable gen2i speed */ - ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */ + ifctl |= (1 << 12); writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); } @@ -2352,7 +2153,6 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) { return rc; } - pci_set_master(pdev); rc = pci_request_regions(pdev, DRV_NAME); if (rc) { diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index 9f553081b..7a3d63d29 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c @@ -29,6 +29,34 @@ * NV-specific details such as register offsets, SATA phy location, * hotplug info, etc. * + * 0.10 + * - Fixed spurious interrupts issue seen with the Maxtor 6H500F0 500GB + * drive. Also made the check_hotplug() callbacks return whether there + * was a hotplug interrupt or not. This was not the source of the + * spurious interrupts, but is the right thing to do anyway. + * + * 0.09 + * - Fixed bug introduced by 0.08's MCP51 and MCP55 support. + * + * 0.08 + * - Added support for MCP51 and MCP55. + * + * 0.07 + * - Added support for RAID class code. + * + * 0.06 + * - Added generic SATA support by using a pci_device_id that filters on + * the IDE storage class code. + * + * 0.03 + * - Fixed a bug where the hotplug handlers for non-CK804/MCP04 were using + * mmio_base, which is only set for the CK804/MCP04 case. + * + * 0.02 + * - Added support for CK804 SATA controller. + * + * 0.01 + * - Initial revision. */ #include @@ -46,55 +74,53 @@ #define DRV_NAME "sata_nv" #define DRV_VERSION "0.8" -enum { - NV_PORTS = 2, - NV_PIO_MASK = 0x1f, - NV_MWDMA_MASK = 0x07, - NV_UDMA_MASK = 0x7f, - NV_PORT0_SCR_REG_OFFSET = 0x00, - NV_PORT1_SCR_REG_OFFSET = 0x40, - - NV_INT_STATUS = 0x10, - NV_INT_STATUS_CK804 = 0x440, - NV_INT_STATUS_PDEV_INT = 0x01, - NV_INT_STATUS_PDEV_PM = 0x02, - NV_INT_STATUS_PDEV_ADDED = 0x04, - NV_INT_STATUS_PDEV_REMOVED = 0x08, - NV_INT_STATUS_SDEV_INT = 0x10, - NV_INT_STATUS_SDEV_PM = 0x20, - NV_INT_STATUS_SDEV_ADDED = 0x40, - NV_INT_STATUS_SDEV_REMOVED = 0x80, - NV_INT_STATUS_PDEV_HOTPLUG = (NV_INT_STATUS_PDEV_ADDED | - NV_INT_STATUS_PDEV_REMOVED), - NV_INT_STATUS_SDEV_HOTPLUG = (NV_INT_STATUS_SDEV_ADDED | - NV_INT_STATUS_SDEV_REMOVED), - NV_INT_STATUS_HOTPLUG = (NV_INT_STATUS_PDEV_HOTPLUG | - NV_INT_STATUS_SDEV_HOTPLUG), - - NV_INT_ENABLE = 0x11, - NV_INT_ENABLE_CK804 = 0x441, - NV_INT_ENABLE_PDEV_MASK = 0x01, - NV_INT_ENABLE_PDEV_PM = 0x02, - NV_INT_ENABLE_PDEV_ADDED = 0x04, - NV_INT_ENABLE_PDEV_REMOVED = 0x08, - NV_INT_ENABLE_SDEV_MASK = 0x10, - NV_INT_ENABLE_SDEV_PM = 0x20, - NV_INT_ENABLE_SDEV_ADDED = 0x40, - NV_INT_ENABLE_SDEV_REMOVED = 0x80, - NV_INT_ENABLE_PDEV_HOTPLUG = (NV_INT_ENABLE_PDEV_ADDED | - NV_INT_ENABLE_PDEV_REMOVED), - NV_INT_ENABLE_SDEV_HOTPLUG = (NV_INT_ENABLE_SDEV_ADDED | - NV_INT_ENABLE_SDEV_REMOVED), - NV_INT_ENABLE_HOTPLUG = (NV_INT_ENABLE_PDEV_HOTPLUG | - NV_INT_ENABLE_SDEV_HOTPLUG), - - NV_INT_CONFIG = 0x12, - NV_INT_CONFIG_METHD = 0x01, // 0 = INT, 1 = SMI - - // For PCI config register 20 - NV_MCP_SATA_CFG_20 = 0x50, - NV_MCP_SATA_CFG_20_SATA_SPACE_EN = 0x04, -}; +#define NV_PORTS 2 +#define NV_PIO_MASK 0x1f +#define NV_MWDMA_MASK 0x07 +#define NV_UDMA_MASK 0x7f +#define NV_PORT0_SCR_REG_OFFSET 0x00 +#define NV_PORT1_SCR_REG_OFFSET 0x40 + +#define NV_INT_STATUS 0x10 +#define NV_INT_STATUS_CK804 0x440 +#define NV_INT_STATUS_PDEV_INT 0x01 +#define NV_INT_STATUS_PDEV_PM 0x02 +#define NV_INT_STATUS_PDEV_ADDED 0x04 +#define NV_INT_STATUS_PDEV_REMOVED 0x08 +#define NV_INT_STATUS_SDEV_INT 0x10 +#define NV_INT_STATUS_SDEV_PM 0x20 +#define NV_INT_STATUS_SDEV_ADDED 0x40 +#define NV_INT_STATUS_SDEV_REMOVED 0x80 +#define NV_INT_STATUS_PDEV_HOTPLUG (NV_INT_STATUS_PDEV_ADDED | \ + NV_INT_STATUS_PDEV_REMOVED) +#define NV_INT_STATUS_SDEV_HOTPLUG (NV_INT_STATUS_SDEV_ADDED | \ + NV_INT_STATUS_SDEV_REMOVED) +#define NV_INT_STATUS_HOTPLUG (NV_INT_STATUS_PDEV_HOTPLUG | \ + NV_INT_STATUS_SDEV_HOTPLUG) + +#define NV_INT_ENABLE 0x11 +#define NV_INT_ENABLE_CK804 0x441 +#define NV_INT_ENABLE_PDEV_MASK 0x01 +#define NV_INT_ENABLE_PDEV_PM 0x02 +#define NV_INT_ENABLE_PDEV_ADDED 0x04 +#define NV_INT_ENABLE_PDEV_REMOVED 0x08 +#define NV_INT_ENABLE_SDEV_MASK 0x10 +#define NV_INT_ENABLE_SDEV_PM 0x20 +#define NV_INT_ENABLE_SDEV_ADDED 0x40 +#define NV_INT_ENABLE_SDEV_REMOVED 0x80 +#define NV_INT_ENABLE_PDEV_HOTPLUG (NV_INT_ENABLE_PDEV_ADDED | \ + NV_INT_ENABLE_PDEV_REMOVED) +#define NV_INT_ENABLE_SDEV_HOTPLUG (NV_INT_ENABLE_SDEV_ADDED | \ + NV_INT_ENABLE_SDEV_REMOVED) +#define NV_INT_ENABLE_HOTPLUG (NV_INT_ENABLE_PDEV_HOTPLUG | \ + NV_INT_ENABLE_SDEV_HOTPLUG) + +#define NV_INT_CONFIG 0x12 +#define NV_INT_CONFIG_METHD 0x01 // 0 = INT, 1 = SMI + +// For PCI config register 20 +#define NV_MCP_SATA_CFG_20 0x50 +#define NV_MCP_SATA_CFG_20_SATA_SPACE_EN 0x04 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static irqreturn_t nv_interrupt (int irq, void *dev_instance, @@ -140,6 +166,16 @@ static const struct pci_device_id nv_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, + { PCI_VENDOR_ID_NVIDIA, 0x045c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, + { PCI_VENDOR_ID_NVIDIA, 0x045d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, + { PCI_VENDOR_ID_NVIDIA, 0x045e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, + { PCI_VENDOR_ID_NVIDIA, 0x045f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, @@ -149,6 +185,8 @@ static const struct pci_device_id nv_pci_tbl[] = { { 0, } /* terminate list */ }; +#define NV_HOST_FLAGS_SCR_MMIO 0x00000001 + struct nv_host_desc { enum nv_host_type host_type; @@ -201,9 +239,11 @@ static struct scsi_host_template nv_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -303,23 +343,36 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance, static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) { + struct ata_host_set *host_set = ap->host_set; + struct nv_host *host = host_set->private_data; + if (sc_reg > SCR_CONTROL) return 0xffffffffU; - return ioread32((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4)); + if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) + return readl((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4)); + else + return inl(ap->ioaddr.scr_addr + (sc_reg * 4)); } static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { + struct ata_host_set *host_set = ap->host_set; + struct nv_host *host = host_set->private_data; + if (sc_reg > SCR_CONTROL) return; - iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4)); + if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) + writel(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4)); + else + outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)); } static void nv_host_stop (struct ata_host_set *host_set) { struct nv_host *host = host_set->private_data; + struct pci_dev *pdev = to_pci_dev(host_set->dev); // Disable hotplug event interrupts. if (host->host_desc->disable_hotplug) @@ -327,7 +380,8 @@ static void nv_host_stop (struct ata_host_set *host_set) kfree(host); - ata_pci_host_stop(host_set); + if (host_set->mmio_base) + pci_iounmap(pdev, host_set->mmio_base); } static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) @@ -339,7 +393,6 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) int pci_dev_busy = 0; int rc; u32 bar; - unsigned long base; // Make sure this is a SATA controller by counting the number of bars // (NVIDIA SATA controllers will always have six bars). Otherwise, @@ -384,16 +437,31 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->private_data = host; - probe_ent->mmio_base = pci_iomap(pdev, 5, 0); - if (!probe_ent->mmio_base) { - rc = -EIO; - goto err_out_free_host; - } + if (pci_resource_flags(pdev, 5) & IORESOURCE_MEM) + host->host_flags |= NV_HOST_FLAGS_SCR_MMIO; - base = (unsigned long)probe_ent->mmio_base; + if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) { + unsigned long base; - probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET; - probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET; + probe_ent->mmio_base = pci_iomap(pdev, 5, 0); + if (probe_ent->mmio_base == NULL) { + rc = -EIO; + goto err_out_free_host; + } + + base = (unsigned long)probe_ent->mmio_base; + + probe_ent->port[0].scr_addr = + base + NV_PORT0_SCR_REG_OFFSET; + probe_ent->port[1].scr_addr = + base + NV_PORT1_SCR_REG_OFFSET; + } else { + + probe_ent->port[0].scr_addr = + pci_resource_start(pdev, 5) | NV_PORT0_SCR_REG_OFFSET; + probe_ent->port[1].scr_addr = + pci_resource_start(pdev, 5) | NV_PORT1_SCR_REG_OFFSET; + } pci_set_master(pdev); @@ -410,7 +478,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return 0; err_out_iounmap: - pci_iounmap(pdev, probe_ent->mmio_base); + if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) + pci_iounmap(pdev, probe_ent->mmio_base); err_out_free_host: kfree(host); err_out_free_ent: diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index df5776210..07172fc3b 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -46,7 +46,7 @@ #include "sata_promise.h" #define DRV_NAME "sata_promise" -#define DRV_VERSION "1.04" +#define DRV_VERSION "1.03" enum { @@ -58,7 +58,6 @@ enum { PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */ PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ - PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ PDC_SLEW_CTL = 0x470, /* slew rate control reg */ PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) | @@ -68,10 +67,8 @@ enum { board_20319 = 1, /* FastTrak S150 TX4 */ board_20619 = 2, /* FastTrak TX4000 */ board_20771 = 3, /* FastTrak TX2300 */ - board_2057x = 4, /* SATAII150 Tx2plus */ - board_40518 = 5, /* SATAII150 Tx4 */ - PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ + PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */ PDC_RESET = (1 << 11), /* HDMA reset */ @@ -85,10 +82,6 @@ struct pdc_port_priv { dma_addr_t pkt_dma; }; -struct pdc_host_priv { - int hotplug_offset; -}; - static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); @@ -102,8 +95,7 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static void pdc_irq_clear(struct ata_port *ap); -static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); -static void pdc_host_stop(struct ata_host_set *host_set); +static int pdc_qc_issue_prot(struct ata_queued_cmd *qc); static struct scsi_host_template pdc_ata_sht = { @@ -111,9 +103,11 @@ static struct scsi_host_template pdc_ata_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -143,7 +137,7 @@ static const struct ata_port_operations pdc_sata_ops = { .scr_write = pdc_sata_scr_write, .port_start = pdc_port_start, .port_stop = pdc_port_stop, - .host_stop = pdc_host_stop, + .host_stop = ata_pci_host_stop, }; static const struct ata_port_operations pdc_pata_ops = { @@ -164,14 +158,14 @@ static const struct ata_port_operations pdc_pata_ops = { .port_start = pdc_port_start, .port_stop = pdc_port_stop, - .host_stop = pdc_host_stop, + .host_stop = ata_pci_host_stop, }; static const struct ata_port_info pdc_port_info[] = { /* board_2037x */ { .sht = &pdc_ata_sht, - .host_flags = PDC_COMMON_FLAGS /* | ATA_FLAG_SATA */, /* pata fix */ + .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -207,26 +201,6 @@ static const struct ata_port_info pdc_port_info[] = { .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &pdc_sata_ops, }, - - /* board_2057x */ - { - .sht = &pdc_ata_sht, - .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ - .port_ops = &pdc_sata_ops, - }, - - /* board_40518 */ - { - .sht = &pdc_ata_sht, - .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ - .port_ops = &pdc_sata_ops, - }, }; static const struct pci_device_id pdc_ata_pci_tbl[] = { @@ -243,9 +217,9 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_2057x }, + board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_2057x }, + board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, @@ -260,7 +234,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20319 }, { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_40518 }, + board_20319 }, { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20619 }, @@ -289,11 +263,12 @@ static int pdc_port_start(struct ata_port *ap) if (rc) return rc; - pp = kzalloc(sizeof(*pp), GFP_KERNEL); + pp = kmalloc(sizeof(*pp), GFP_KERNEL); if (!pp) { rc = -ENOMEM; goto err_out; } + memset(pp, 0, sizeof(*pp)); pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL); if (!pp->pkt) { @@ -325,16 +300,6 @@ static void pdc_port_stop(struct ata_port *ap) } -static void pdc_host_stop(struct ata_host_set *host_set) -{ - struct pdc_host_priv *hp = host_set->private_data; - - ata_pci_host_stop(host_set); - - kfree(hp); -} - - static void pdc_reset_port(struct ata_port *ap) { void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT; @@ -359,34 +324,15 @@ static void pdc_reset_port(struct ata_port *ap) static void pdc_sata_phy_reset(struct ata_port *ap) { -/* pdc_reset_port(ap); */ /* pata fix */ -/* sata_phy_reset(ap); */ /* pata fix */ - /* if no sata flag, test for pata drive */ /* pata fix */ - if (ap->flags & ATA_FLAG_SATA) /* pata fix */ - { /* pata fix */ - pdc_reset_port(ap); /* pata fix */ - sata_phy_reset(ap); /* pata fix */ - } /* pata fix */ - else /* pata fix */ - pdc_pata_phy_reset(ap); /* pata fix */ + pdc_reset_port(ap); + sata_phy_reset(ap); } static void pdc_pata_phy_reset(struct ata_port *ap) { /* FIXME: add cable detect. Don't assume 40-pin cable */ -/* ap->cbl = ATA_CBL_PATA40; */ /* pata fix */ -/* ap->udma_mask &= ATA_UDMA_MASK_40C; */ /* pata fix */ - /* add cable detection code for pata drives */ /* pata fix */ - u8 tmp; /* pata fix */ - void *mmio = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; /* pata fix */ - tmp = readb(mmio); /* pata fix */ - if (tmp & 0x01) /* pata fix */ - { /* pata fix */ - ap->cbl = ATA_CBL_PATA40; /* pata fix */ - ap->udma_mask &= ATA_UDMA_MASK_40C; /* pata fix */ - } /* pata fix */ - else /* pata fix */ - ap->cbl = ATA_CBL_PATA80; /* pata fix */ + ap->cbl = ATA_CBL_PATA40; + ap->udma_mask &= ATA_UDMA_MASK_40C; pdc_reset_port(ap); ata_port_probe(ap); @@ -450,6 +396,19 @@ static void pdc_eng_timeout(struct ata_port *ap) spin_lock_irqsave(&host_set->lock, flags); qc = ata_qc_from_tag(ap, ap->active_tag); + if (!qc) { + printk(KERN_ERR "ata%u: BUG: timeout without command\n", + ap->id); + goto out; + } + + /* hack alert! We cannot use the supplied completion + * function from inside the ->eh_strategy_handler() thread. + * libata is the only user of ->eh_strategy_handler() in + * any kernel, so the default scsi_done() assumes it is + * not being called from the SCSI EH. + */ + qc->scsidone = scsi_finish_command; switch (qc->tf.protocol) { case ATA_PROT_DMA: @@ -457,6 +416,7 @@ static void pdc_eng_timeout(struct ata_port *ap) printk(KERN_ERR "ata%u: command timeout\n", ap->id); drv_stat = ata_wait_idle(ap); qc->err_mask |= __ac_err_mask(drv_stat); + ata_qc_complete(qc); break; default: @@ -466,11 +426,12 @@ static void pdc_eng_timeout(struct ata_port *ap) ap->id, qc->tf.command, drv_stat); qc->err_mask |= ac_err_mask(drv_stat); + ata_qc_complete(qc); break; } +out: spin_unlock_irqrestore(&host_set->lock, flags); - ata_eh_qc_complete(qc); DPRINTK("EXIT\n"); } @@ -536,15 +497,14 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r VPRINTK("QUICK EXIT 2\n"); return IRQ_NONE; } - - spin_lock(&host_set->lock); - mask &= 0xffff; /* only 16 tags possible */ if (!mask) { VPRINTK("QUICK EXIT 3\n"); - goto done_irq; + return IRQ_NONE; } + spin_lock(&host_set->lock); + writel(mask, mmio_base + PDC_INT_SEQMASK); for (i = 0; i < host_set->n_ports; i++) { @@ -561,10 +521,10 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r } } + spin_unlock(&host_set->lock); + VPRINTK("EXIT\n"); -done_irq: - spin_unlock(&host_set->lock); return IRQ_RETVAL(handled); } @@ -586,7 +546,7 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc) readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */ } -static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc) +static int pdc_qc_issue_prot(struct ata_queued_cmd *qc) { switch (qc->tf.protocol) { case ATA_PROT_DMA: @@ -642,8 +602,6 @@ static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base) static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) { void __iomem *mmio = pe->mmio_base; - struct pdc_host_priv *hp = pe->private_data; - int hotplug_offset = hp->hotplug_offset; u32 tmp; /* @@ -658,12 +616,12 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) writel(tmp, mmio + PDC_FLASH_CTL); /* clear plug/unplug flags for all ports */ - tmp = readl(mmio + hotplug_offset); - writel(tmp | 0xff, mmio + hotplug_offset); + tmp = readl(mmio + PDC_SATA_PLUG_CSR); + writel(tmp | 0xff, mmio + PDC_SATA_PLUG_CSR); /* mask plug/unplug ints */ - tmp = readl(mmio + hotplug_offset); - writel(tmp | 0xff0000, mmio + hotplug_offset); + tmp = readl(mmio + PDC_SATA_PLUG_CSR); + writel(tmp | 0xff0000, mmio + PDC_SATA_PLUG_CSR); /* reduce TBG clock to 133 Mhz. */ tmp = readl(mmio + PDC_TBG_MODE); @@ -685,13 +643,11 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e { static int printed_version; struct ata_probe_ent *probe_ent = NULL; - struct pdc_host_priv *hp; unsigned long base; void __iomem *mmio_base; unsigned int board_idx = (unsigned int) ent->driver_data; int pci_dev_busy = 0; int rc; - u8 tmp; /* pata fix */ if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); @@ -717,12 +673,13 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e if (rc) goto err_out_regions; - probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); if (probe_ent == NULL) { rc = -ENOMEM; goto err_out_regions; } + memset(probe_ent, 0, sizeof(*probe_ent)); probe_ent->dev = pci_dev_to_dev(pdev); INIT_LIST_HEAD(&probe_ent->node); @@ -733,16 +690,6 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e } base = (unsigned long) mmio_base; - hp = kzalloc(sizeof(*hp), GFP_KERNEL); - if (hp == NULL) { - rc = -ENOMEM; - goto err_out_free_ent; - } - - /* Set default hotplug offset */ - hp->hotplug_offset = PDC_SATA_PLUG_CSR; - probe_ent->private_data = hp; - probe_ent->sht = pdc_port_info[board_idx].sht; probe_ent->host_flags = pdc_port_info[board_idx].host_flags; probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask; @@ -760,15 +707,8 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e probe_ent->port[0].scr_addr = base + 0x400; probe_ent->port[1].scr_addr = base + 0x500; - probe_ent->port_flags[0] = ATA_FLAG_SATA; /* pata fix */ - probe_ent->port_flags[1] = ATA_FLAG_SATA; /* pata fix */ - /* notice 4-port boards */ switch (board_idx) { - case board_40518: - /* Override hotplug offset for SATAII150 */ - hp->hotplug_offset = PDC2_SATA_PLUG_CSR; - /* Fall through */ case board_20319: probe_ent->n_ports = 4; @@ -777,27 +717,9 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e probe_ent->port[2].scr_addr = base + 0x600; probe_ent->port[3].scr_addr = base + 0x700; - - probe_ent->port_flags[2] = ATA_FLAG_SATA; /* pata fix */ - probe_ent->port_flags[3] = ATA_FLAG_SATA; /* pata fix */ break; - case board_2057x: - /* Override hotplug offset for SATAII150 */ - hp->hotplug_offset = PDC2_SATA_PLUG_CSR; - /* Fall through */ case board_2037x: -/* probe_ent->n_ports = 2; */ /* pata fix */ - /* Some boards have also PATA port */ /* pata fix */ - tmp = readb(mmio_base + PDC_FLASH_CTL+1); /* pata fix */ - if (!(tmp & 0x80)) /* pata fix */ - { /* pata fix */ - probe_ent->n_ports = 3; /* pata fix */ - pdc_ata_setup_port(&probe_ent->port[2], base + 0x300); /* pata fix */ - probe_ent->port_flags[2] = ATA_FLAG_SLAVE_POSS; /* pata fix */ - printk(KERN_INFO DRV_NAME " PATA port found\n"); /* pata fix */ - } /* pata fix */ - else /* pata fix */ - probe_ent->n_ports = 2; /* pata fix */ + probe_ent->n_ports = 2; break; case board_20771: probe_ent->n_ports = 2; @@ -810,9 +732,6 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e probe_ent->port[2].scr_addr = base + 0x600; probe_ent->port[3].scr_addr = base + 0x700; - - probe_ent->port_flags[2] = ATA_FLAG_SATA; /* pata fix */ - probe_ent->port_flags[3] = ATA_FLAG_SATA; /* pata fix */ break; default: BUG(); @@ -824,10 +743,8 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e /* initialize adapter */ pdc_host_init(board_idx, probe_ent); - /* FIXME: Need any other frees than hp? */ - if (!ata_device_add(probe_ent)) - kfree(hp); - + /* FIXME: check ata_device_add return value */ + ata_device_add(probe_ent); kfree(probe_ent); return 0; diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 886f3447d..80480f0fb 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c @@ -120,7 +120,7 @@ static void qs_host_stop(struct ata_host_set *host_set); static void qs_port_stop(struct ata_port *ap); static void qs_phy_reset(struct ata_port *ap); static void qs_qc_prep(struct ata_queued_cmd *qc); -static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); +static int qs_qc_issue(struct ata_queued_cmd *qc); static int qs_check_atapi_dma(struct ata_queued_cmd *qc); static void qs_bmdma_stop(struct ata_queued_cmd *qc); static u8 qs_bmdma_status(struct ata_port *ap); @@ -132,9 +132,11 @@ static struct scsi_host_template qs_ata_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = QS_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, //FIXME .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -274,8 +276,8 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) unsigned int nelem; u8 *prd = pp->pkt + QS_CPB_BYTES; - WARN_ON(qc->__sg == NULL); - WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); + assert(qc->__sg != NULL); + assert(qc->n_elem > 0 || qc->pad_len > 0); nelem = 0; ata_for_each_sg(sg, qc) { @@ -350,7 +352,7 @@ static inline void qs_packet_start(struct ata_queued_cmd *qc) readl(chan + QS_CCT_CFF); /* flush */ } -static unsigned int qs_qc_issue(struct ata_queued_cmd *qc) +static int qs_qc_issue(struct ata_queued_cmd *qc) { struct qs_port_priv *pp = qc->ap->private_data; diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 106627299..9face3c6a 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -49,30 +49,24 @@ #define DRV_VERSION "0.9" enum { - /* - * host flags - */ SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), SIL_FLAG_MOD15WRITE = (1 << 30), - SIL_DFL_HOST_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO, - /* - * Controller IDs - */ sil_3112 = 0, - sil_3512 = 1, - sil_3114 = 2, + sil_3112_m15w = 1, + sil_3512 = 2, + sil_3114 = 3, + + SIL_FIFO_R0 = 0x40, + SIL_FIFO_W0 = 0x41, + SIL_FIFO_R1 = 0x44, + SIL_FIFO_W1 = 0x45, + SIL_FIFO_R2 = 0x240, + SIL_FIFO_W2 = 0x241, + SIL_FIFO_R3 = 0x244, + SIL_FIFO_W3 = 0x245, - /* - * Register offsets - */ SIL_SYSCFG = 0x48, - - /* - * Register bits - */ - /* SYSCFG */ SIL_MASK_IDE0_INT = (1 << 22), SIL_MASK_IDE1_INT = (1 << 23), SIL_MASK_IDE2_INT = (1 << 24), @@ -81,12 +75,9 @@ enum { SIL_MASK_4PORT = SIL_MASK_2PORT | SIL_MASK_IDE2_INT | SIL_MASK_IDE3_INT, - /* BMDMA/BMDMA2 */ - SIL_INTR_STEERING = (1 << 1), + SIL_IDE2_BMDMA = 0x200, - /* - * Others - */ + SIL_INTR_STEERING = (1 << 1), SIL_QUIRK_MOD15WRITE = (1 << 0), SIL_QUIRK_UDMA5MAX = (1 << 1), }; @@ -99,13 +90,13 @@ static void sil_post_set_mode (struct ata_port *ap); static const struct pci_device_id sil_pci_tbl[] = { - { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, - { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, + { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, + { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, - { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, - { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, - { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, + { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, + { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, + { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, { } /* terminate list */ }; @@ -146,9 +137,11 @@ static struct scsi_host_template sil_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -166,7 +159,7 @@ static const struct ata_port_operations sil_ops = { .check_status = ata_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, - .probe_reset = ata_std_probe_reset, + .phy_reset = sata_phy_reset, .post_set_mode = sil_post_set_mode, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -188,7 +181,19 @@ static const struct ata_port_info sil_port_info[] = { /* sil_3112 */ { .sht = &sil_sht, - .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_MOD15WRITE, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_SRST | ATA_FLAG_MMIO, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = 0x3f, /* udma0-5 */ + .port_ops = &sil_ops, + }, + /* sil_3112_15w - keep it sync'd w/ sil_3112 */ + { + .sht = &sil_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_SRST | ATA_FLAG_MMIO | + SIL_FLAG_MOD15WRITE, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -197,7 +202,9 @@ static const struct ata_port_info sil_port_info[] = { /* sil_3512 */ { .sht = &sil_sht, - .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_SRST | ATA_FLAG_MMIO | + SIL_FLAG_RERR_ON_DMA_ACT, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -206,7 +213,9 @@ static const struct ata_port_info sil_port_info[] = { /* sil_3114 */ { .sht = &sil_sht, - .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_SRST | ATA_FLAG_MMIO | + SIL_FLAG_RERR_ON_DMA_ACT, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -220,17 +229,16 @@ static const struct { unsigned long tf; /* ATA taskfile register block */ unsigned long ctl; /* ATA control/altstatus register block */ unsigned long bmdma; /* DMA register block */ - unsigned long fifo_cfg; /* FIFO Valid Byte Count and Control */ unsigned long scr; /* SATA control register block */ unsigned long sien; /* SATA Interrupt Enable register */ unsigned long xfer_mode;/* data transfer mode register */ unsigned long sfis_cfg; /* SATA FIS reception config register */ } sil_port[] = { /* port 0 ... */ - { 0x80, 0x8A, 0x00, 0x40, 0x100, 0x148, 0xb4, 0x14c }, - { 0xC0, 0xCA, 0x08, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc }, - { 0x280, 0x28A, 0x200, 0x240, 0x300, 0x348, 0x2b4, 0x34c }, - { 0x2C0, 0x2CA, 0x208, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc }, + { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4, 0x14c }, + { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4, 0x1cc }, + { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4, 0x34c }, + { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4, 0x3cc }, /* ... port 3 */ }; @@ -346,12 +354,22 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) { unsigned int n, quirks = 0; - unsigned char model_num[41]; + unsigned char model_num[40]; + const char *s; + unsigned int len; - ata_id_c_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num)); + ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, + sizeof(model_num)); + s = &model_num[0]; + len = strnlen(s, sizeof(model_num)); + + /* ATAPI specifies that empty space is blank-filled; remove blanks */ + while ((len > 0) && (s[len - 1] == ' ')) + len--; for (n = 0; sil_blacklist[n].product; n++) - if (!strcmp(sil_blacklist[n].product, model_num)) { + if (!memcmp(sil_blacklist[n].product, s, + strlen(sil_blacklist[n].product))) { quirks = sil_blacklist[n].quirk; break; } @@ -362,15 +380,17 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) (quirks & SIL_QUIRK_MOD15WRITE))) { printk(KERN_INFO "ata%u(%u): applying Seagate errata fix (mod15write workaround)\n", ap->id, dev->devno); - dev->max_sectors = 15; + ap->host->max_sectors = 15; + ap->host->hostt->max_sectors = 15; + dev->flags |= ATA_DFLAG_LOCK_SECTORS; return; } /* limit to udma5 */ if (quirks & SIL_QUIRK_UDMA5MAX) { printk(KERN_INFO "ata%u(%u): applying Maxtor errata fix %s\n", - ap->id, dev->devno, model_num); - dev->udma_mask &= ATA_UDMA5; + ap->id, dev->devno, s); + ap->udma_mask &= ATA_UDMA5; return; } } @@ -411,12 +431,13 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) goto err_out_regions; - probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); if (probe_ent == NULL) { rc = -ENOMEM; goto err_out_regions; } + memset(probe_ent, 0, sizeof(*probe_ent)); INIT_LIST_HEAD(&probe_ent->node); probe_ent->dev = pci_dev_to_dev(pdev); probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops; @@ -453,12 +474,19 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (cls) { cls >>= 3; cls++; /* cls = (line_size/8)+1 */ - for (i = 0; i < probe_ent->n_ports; i++) - writew(cls << 8 | cls, - mmio_base + sil_port[i].fifo_cfg); + writeb(cls, mmio_base + SIL_FIFO_R0); + writeb(cls, mmio_base + SIL_FIFO_W0); + writeb(cls, mmio_base + SIL_FIFO_R1); + writeb(cls, mmio_base + SIL_FIFO_W1); + if (ent->driver_data == sil_3114) { + writeb(cls, mmio_base + SIL_FIFO_R2); + writeb(cls, mmio_base + SIL_FIFO_W2); + writeb(cls, mmio_base + SIL_FIFO_R3); + writeb(cls, mmio_base + SIL_FIFO_W3); + } } else dev_printk(KERN_WARNING, &pdev->dev, - "cache line size not set. Driver may not function\n"); + "cache line size not set. Driver may not function\n"); /* Apply R_ERR on DMA activate FIS errata workaround */ if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) { @@ -481,10 +509,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) irq_mask = SIL_MASK_4PORT; /* flip the magic "make 4 ports work" bit */ - tmp = readl(mmio_base + sil_port[2].bmdma); + tmp = readl(mmio_base + SIL_IDE2_BMDMA); if ((tmp & SIL_INTR_STEERING) == 0) writel(tmp | SIL_INTR_STEERING, - mmio_base + sil_port[2].bmdma); + mmio_base + SIL_IDE2_BMDMA); } else { irq_mask = SIL_MASK_2PORT; diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index cb9082fd7..e256bbbf9 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -249,9 +249,9 @@ static u8 sil24_check_status(struct ata_port *ap); static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); -static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes); +static void sil24_phy_reset(struct ata_port *ap); static void sil24_qc_prep(struct ata_queued_cmd *qc); -static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); +static int sil24_qc_issue(struct ata_queued_cmd *qc); static void sil24_irq_clear(struct ata_port *ap); static void sil24_eng_timeout(struct ata_port *ap); static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs); @@ -281,9 +281,11 @@ static struct scsi_host_template sil24_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -304,7 +306,7 @@ static const struct ata_port_operations sil24_ops = { .tf_read = sil24_tf_read, - .probe_reset = sil24_probe_reset, + .phy_reset = sil24_phy_reset, .qc_prep = sil24_qc_prep, .qc_issue = sil24_qc_issue, @@ -334,19 +336,19 @@ static struct ata_port_info sil24_port_info[] = { { .sht = &sil24_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - SIL24_NPORTS2FLAG(4), + ATA_FLAG_SRST | ATA_FLAG_MMIO | + ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil24_ops, }, - /* sil_3132 */ + /* sil_3132 */ { .sht = &sil24_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - SIL24_NPORTS2FLAG(2), + ATA_FLAG_SRST | ATA_FLAG_MMIO | + ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -356,8 +358,8 @@ static struct ata_port_info sil24_port_info[] = { { .sht = &sil24_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - SIL24_NPORTS2FLAG(1), + ATA_FLAG_SRST | ATA_FLAG_MMIO | + ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -369,7 +371,7 @@ static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev) { void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; - if (dev->cdb_len == 16) + if (ap->cdb_len == 16) writel(PORT_CS_CDB16, port + PORT_CTRL_STAT); else writel(PORT_CS_CDB16, port + PORT_CTRL_CLR); @@ -426,23 +428,14 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) *tf = pp->tf; } -static int sil24_softreset(struct ata_port *ap, int verbose, - unsigned int *class) +static int sil24_issue_SRST(struct ata_port *ap) { void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; struct sil24_port_priv *pp = ap->private_data; struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; dma_addr_t paddr = pp->cmd_block_dma; - unsigned long timeout = jiffies + ATA_TMOUT_BOOT * HZ; u32 irq_enable, irq_stat; - - DPRINTK("ENTER\n"); - - if (!sata_dev_present(ap)) { - DPRINTK("PHY reports no device\n"); - *class = ATA_DEV_NONE; - goto out; - } + int cnt; /* temporarily turn off IRQs during SRST */ irq_enable = readl(port + PORT_IRQ_ENABLE_SET); @@ -454,12 +447,12 @@ static int sil24_softreset(struct ata_port *ap, int verbose, */ msleep(10); - prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); + prb->ctrl = PRB_CTRL_SRST; prb->fis[1] = 0; /* no PM yet */ writel((u32)paddr, port + PORT_CMD_ACTIVATE); - do { + for (cnt = 0; cnt < 100; cnt++) { irq_stat = readl(port + PORT_IRQ_STAT); writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ @@ -467,42 +460,36 @@ static int sil24_softreset(struct ata_port *ap, int verbose, if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR)) break; - msleep(100); - } while (time_before(jiffies, timeout)); + msleep(1); + } /* restore IRQs */ writel(irq_enable, port + PORT_IRQ_ENABLE_SET); - if (!(irq_stat & PORT_IRQ_COMPLETE)) { - DPRINTK("EXIT, srst failed\n"); - return -EIO; - } + if (!(irq_stat & PORT_IRQ_COMPLETE)) + return -1; + /* update TF */ sil24_update_tf(ap); - *class = ata_dev_classify(&pp->tf); - - if (*class == ATA_DEV_UNKNOWN) - *class = ATA_DEV_NONE; - - out: - DPRINTK("EXIT, class=%u\n", *class); return 0; } -static int sil24_hardreset(struct ata_port *ap, int verbose, - unsigned int *class) +static void sil24_phy_reset(struct ata_port *ap) { - unsigned int dummy_class; + struct sil24_port_priv *pp = ap->private_data; - /* sil24 doesn't report device signature after hard reset */ - return sata_std_hardreset(ap, verbose, &dummy_class); -} + __sata_phy_reset(ap); + if (ap->flags & ATA_FLAG_PORT_DISABLED) + return; -static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes) -{ - return ata_drive_probe_reset(ap, ata_std_probeinit, - sil24_softreset, sil24_hardreset, - ata_std_postreset, classes); + if (sil24_issue_SRST(ap) < 0) { + printk(KERN_ERR DRV_NAME + " ata%u: SRST failed, disabling port\n", ap->id); + ap->ops->port_disable(ap); + return; + } + + ap->device->class = ata_dev_classify(&pp->tf); } static inline void sil24_fill_sg(struct ata_queued_cmd *qc, @@ -547,13 +534,13 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) prb = &cb->atapi.prb; sge = cb->atapi.sge; memset(cb->atapi.cdb, 0, 32); - memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len); + memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len); if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) { if (qc->tf.flags & ATA_TFLAG_WRITE) - prb->ctrl = cpu_to_le16(PRB_CTRL_PACKET_WRITE); + prb->ctrl = PRB_CTRL_PACKET_WRITE; else - prb->ctrl = cpu_to_le16(PRB_CTRL_PACKET_READ); + prb->ctrl = PRB_CTRL_PACKET_READ; } else prb->ctrl = 0; @@ -571,7 +558,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) sil24_fill_sg(qc, sge); } -static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc) +static int sil24_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; @@ -652,10 +639,23 @@ static void sil24_eng_timeout(struct ata_port *ap) struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); + if (!qc) { + printk(KERN_ERR "ata%u: BUG: timeout without command\n", + ap->id); + return; + } + /* + * hack alert! We cannot use the supplied completion + * function from inside the ->eh_strategy_handler() thread. + * libata is the only user of ->eh_strategy_handler() in + * any kernel, so the default scsi_done() assumes it is + * not being called from the SCSI EH. + */ printk(KERN_ERR "ata%u: command timeout\n", ap->id); - qc->err_mask |= AC_ERR_TIMEOUT; - ata_eh_qc_complete(qc); + qc->scsidone = scsi_finish_command; + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); sil24_reset_controller(ap); } @@ -841,10 +841,9 @@ static void sil24_port_stop(struct ata_port *ap) static void sil24_host_stop(struct ata_host_set *host_set) { struct sil24_host_priv *hpriv = host_set->private_data; - struct pci_dev *pdev = to_pci_dev(host_set->dev); - pci_iounmap(pdev, hpriv->host_base); - pci_iounmap(pdev, hpriv->port_base); + iounmap(hpriv->host_base); + iounmap(hpriv->port_base); kfree(hpriv); } @@ -871,30 +870,32 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_disable; rc = -ENOMEM; - /* map mmio registers */ - host_base = pci_iomap(pdev, 0, 0); + /* ioremap mmio registers */ + host_base = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); if (!host_base) goto out_free; - port_base = pci_iomap(pdev, 2, 0); + port_base = ioremap(pci_resource_start(pdev, 2), + pci_resource_len(pdev, 2)); if (!port_base) goto out_free; /* allocate & init probe_ent and hpriv */ - probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); if (!probe_ent) goto out_free; - hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL); + hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL); if (!hpriv) goto out_free; + memset(probe_ent, 0, sizeof(*probe_ent)); probe_ent->dev = pci_dev_to_dev(pdev); INIT_LIST_HEAD(&probe_ent->node); probe_ent->sht = pinfo->sht; probe_ent->host_flags = pinfo->host_flags; probe_ent->pio_mask = pinfo->pio_mask; - probe_ent->mwdma_mask = pinfo->mwdma_mask; probe_ent->udma_mask = pinfo->udma_mask; probe_ent->port_ops = pinfo->port_ops; probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->host_flags); @@ -904,6 +905,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->mmio_base = port_base; probe_ent->private_data = hpriv; + memset(hpriv, 0, sizeof(*hpriv)); hpriv->host_base = host_base; hpriv->port_base = port_base; @@ -1007,9 +1009,9 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) out_free: if (host_base) - pci_iounmap(pdev, host_base); + iounmap(host_base); if (port_base) - pci_iounmap(pdev, port_base); + iounmap(port_base); kfree(probe_ent); kfree(hpriv); pci_release_regions(pdev); diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index 728530df2..2df8c5632 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c @@ -87,9 +87,11 @@ static struct scsi_host_template sis_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = ATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 53b0d5c0a..d8472563f 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c @@ -56,35 +56,33 @@ #define DRV_NAME "sata_svw" #define DRV_VERSION "1.07" -enum { - /* Taskfile registers offsets */ - K2_SATA_TF_CMD_OFFSET = 0x00, - K2_SATA_TF_DATA_OFFSET = 0x00, - K2_SATA_TF_ERROR_OFFSET = 0x04, - K2_SATA_TF_NSECT_OFFSET = 0x08, - K2_SATA_TF_LBAL_OFFSET = 0x0c, - K2_SATA_TF_LBAM_OFFSET = 0x10, - K2_SATA_TF_LBAH_OFFSET = 0x14, - K2_SATA_TF_DEVICE_OFFSET = 0x18, - K2_SATA_TF_CMDSTAT_OFFSET = 0x1c, - K2_SATA_TF_CTL_OFFSET = 0x20, - - /* DMA base */ - K2_SATA_DMA_CMD_OFFSET = 0x30, - - /* SCRs base */ - K2_SATA_SCR_STATUS_OFFSET = 0x40, - K2_SATA_SCR_ERROR_OFFSET = 0x44, - K2_SATA_SCR_CONTROL_OFFSET = 0x48, - - /* Others */ - K2_SATA_SICR1_OFFSET = 0x80, - K2_SATA_SICR2_OFFSET = 0x84, - K2_SATA_SIM_OFFSET = 0x88, - - /* Port stride */ - K2_SATA_PORT_OFFSET = 0x100, -}; +/* Taskfile registers offsets */ +#define K2_SATA_TF_CMD_OFFSET 0x00 +#define K2_SATA_TF_DATA_OFFSET 0x00 +#define K2_SATA_TF_ERROR_OFFSET 0x04 +#define K2_SATA_TF_NSECT_OFFSET 0x08 +#define K2_SATA_TF_LBAL_OFFSET 0x0c +#define K2_SATA_TF_LBAM_OFFSET 0x10 +#define K2_SATA_TF_LBAH_OFFSET 0x14 +#define K2_SATA_TF_DEVICE_OFFSET 0x18 +#define K2_SATA_TF_CMDSTAT_OFFSET 0x1c +#define K2_SATA_TF_CTL_OFFSET 0x20 + +/* DMA base */ +#define K2_SATA_DMA_CMD_OFFSET 0x30 + +/* SCRs base */ +#define K2_SATA_SCR_STATUS_OFFSET 0x40 +#define K2_SATA_SCR_ERROR_OFFSET 0x44 +#define K2_SATA_SCR_CONTROL_OFFSET 0x48 + +/* Others */ +#define K2_SATA_SICR1_OFFSET 0x80 +#define K2_SATA_SICR2_OFFSET 0x84 +#define K2_SATA_SIM_OFFSET 0x88 + +/* Port stride */ +#define K2_SATA_PORT_OFFSET 0x100 static u8 k2_stat_check_status(struct ata_port *ap); @@ -290,9 +288,11 @@ static struct scsi_host_template k2_sata_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 4139ad4b1..bc87c16c8 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c @@ -174,7 +174,7 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, u32 offset, u32 size); static void pdc20621_irq_clear(struct ata_port *ap); -static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); +static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); static struct scsi_host_template pdc_sata_sht = { @@ -182,9 +182,11 @@ static struct scsi_host_template pdc_sata_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -458,7 +460,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) unsigned int i, idx, total_len = 0, sgt_len; u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; - WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); + assert(qc->flags & ATA_QCFLAG_DMAMAP); VPRINTK("ata%u: ENTER\n", ap->id); @@ -676,7 +678,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc) } } -static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc) +static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc) { switch (qc->tf.protocol) { case ATA_PROT_DMA: @@ -864,12 +866,26 @@ static void pdc_eng_timeout(struct ata_port *ap) spin_lock_irqsave(&host_set->lock, flags); qc = ata_qc_from_tag(ap, ap->active_tag); + if (!qc) { + printk(KERN_ERR "ata%u: BUG: timeout without command\n", + ap->id); + goto out; + } + + /* hack alert! We cannot use the supplied completion + * function from inside the ->eh_strategy_handler() thread. + * libata is the only user of ->eh_strategy_handler() in + * any kernel, so the default scsi_done() assumes it is + * not being called from the SCSI EH. + */ + qc->scsidone = scsi_finish_command; switch (qc->tf.protocol) { case ATA_PROT_DMA: case ATA_PROT_NODATA: printk(KERN_ERR "ata%u: command timeout\n", ap->id); qc->err_mask |= __ac_err_mask(ata_wait_idle(ap)); + ata_qc_complete(qc); break; default: @@ -879,11 +895,12 @@ static void pdc_eng_timeout(struct ata_port *ap) ap->id, qc->tf.command, drv_stat); qc->err_mask |= ac_err_mask(drv_stat); + ata_qc_complete(qc); break; } +out: spin_unlock_irqrestore(&host_set->lock, flags); - ata_eh_qc_complete(qc); DPRINTK("EXIT\n"); } diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index 38b52bd3f..9635ca700 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c @@ -44,8 +44,6 @@ enum { uli_5287 = 1, uli_5281 = 2, - uli_max_ports = 4, - /* PCI configuration registers */ ULI5287_BASE = 0x90, /* sata0 phy SCR registers */ ULI5287_OFFS = 0x10, /* offset from sata0->sata1 phy regs */ @@ -53,10 +51,6 @@ enum { ULI5281_OFFS = 0x60, /* offset from sata0->sata1 phy regs */ }; -struct uli_priv { - unsigned int scr_cfg_addr[uli_max_ports]; -}; - static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg); static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); @@ -81,9 +75,11 @@ static struct scsi_host_template uli_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -142,8 +138,7 @@ MODULE_VERSION(DRV_VERSION); static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg) { - struct uli_priv *hpriv = ap->host_set->private_data; - return hpriv->scr_cfg_addr[ap->port_no] + (4 * sc_reg); + return ap->ioaddr.scr_addr + (4 * sc_reg); } static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) @@ -188,7 +183,6 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) int rc; unsigned int board_idx = (unsigned int) ent->driver_data; int pci_dev_busy = 0; - struct uli_priv *hpriv; if (!printed_version++) dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); @@ -217,18 +211,10 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_regions; } - hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL); - if (!hpriv) { - rc = -ENOMEM; - goto err_out_probe_ent; - } - - probe_ent->private_data = hpriv; - switch (board_idx) { case uli_5287: - hpriv->scr_cfg_addr[0] = ULI5287_BASE; - hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS; + probe_ent->port[0].scr_addr = ULI5287_BASE; + probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS; probe_ent->n_ports = 4; probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8; @@ -236,27 +222,27 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->port[2].ctl_addr = (pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4; probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16; - hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4; + probe_ent->port[2].scr_addr = ULI5287_BASE + ULI5287_OFFS*4; probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8; probe_ent->port[3].altstatus_addr = probe_ent->port[3].ctl_addr = (pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4; probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24; - hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5; + probe_ent->port[3].scr_addr = ULI5287_BASE + ULI5287_OFFS*5; ata_std_ports(&probe_ent->port[2]); ata_std_ports(&probe_ent->port[3]); break; case uli_5289: - hpriv->scr_cfg_addr[0] = ULI5287_BASE; - hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS; + probe_ent->port[0].scr_addr = ULI5287_BASE; + probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS; break; case uli_5281: - hpriv->scr_cfg_addr[0] = ULI5281_BASE; - hpriv->scr_cfg_addr[1] = ULI5281_BASE + ULI5281_OFFS; + probe_ent->port[0].scr_addr = ULI5281_BASE; + probe_ent->port[1].scr_addr = ULI5281_BASE + ULI5281_OFFS; break; default: @@ -273,10 +259,9 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return 0; -err_out_probe_ent: - kfree(probe_ent); err_out_regions: pci_release_regions(pdev); + err_out: if (!pci_dev_busy) pci_disable_device(pdev); diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index 9e7ae4e0d..6d5b0a794 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c @@ -94,9 +94,11 @@ static struct scsi_host_template svia_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 8a29ce340..e484e8db6 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c @@ -47,58 +47,52 @@ #include #define DRV_NAME "sata_vsc" -#define DRV_VERSION "1.2" - -enum { - /* Interrupt register offsets (from chip base address) */ - VSC_SATA_INT_STAT_OFFSET = 0x00, - VSC_SATA_INT_MASK_OFFSET = 0x04, - - /* Taskfile registers offsets */ - VSC_SATA_TF_CMD_OFFSET = 0x00, - VSC_SATA_TF_DATA_OFFSET = 0x00, - VSC_SATA_TF_ERROR_OFFSET = 0x04, - VSC_SATA_TF_FEATURE_OFFSET = 0x06, - VSC_SATA_TF_NSECT_OFFSET = 0x08, - VSC_SATA_TF_LBAL_OFFSET = 0x0c, - VSC_SATA_TF_LBAM_OFFSET = 0x10, - VSC_SATA_TF_LBAH_OFFSET = 0x14, - VSC_SATA_TF_DEVICE_OFFSET = 0x18, - VSC_SATA_TF_STATUS_OFFSET = 0x1c, - VSC_SATA_TF_COMMAND_OFFSET = 0x1d, - VSC_SATA_TF_ALTSTATUS_OFFSET = 0x28, - VSC_SATA_TF_CTL_OFFSET = 0x29, - - /* DMA base */ - VSC_SATA_UP_DESCRIPTOR_OFFSET = 0x64, - VSC_SATA_UP_DATA_BUFFER_OFFSET = 0x6C, - VSC_SATA_DMA_CMD_OFFSET = 0x70, - - /* SCRs base */ - VSC_SATA_SCR_STATUS_OFFSET = 0x100, - VSC_SATA_SCR_ERROR_OFFSET = 0x104, - VSC_SATA_SCR_CONTROL_OFFSET = 0x108, - - /* Port stride */ - VSC_SATA_PORT_OFFSET = 0x200, - - /* Error interrupt status bit offsets */ - VSC_SATA_INT_ERROR_CRC = 0x40, - VSC_SATA_INT_ERROR_T = 0x20, - VSC_SATA_INT_ERROR_P = 0x10, - VSC_SATA_INT_ERROR_R = 0x8, - VSC_SATA_INT_ERROR_E = 0x4, - VSC_SATA_INT_ERROR_M = 0x2, - VSC_SATA_INT_PHY_CHANGE = 0x1, - VSC_SATA_INT_ERROR = (VSC_SATA_INT_ERROR_CRC | VSC_SATA_INT_ERROR_T | \ - VSC_SATA_INT_ERROR_P | VSC_SATA_INT_ERROR_R | \ - VSC_SATA_INT_ERROR_E | VSC_SATA_INT_ERROR_M | \ - VSC_SATA_INT_PHY_CHANGE), -}; - - +#define DRV_VERSION "1.1" + +/* Interrupt register offsets (from chip base address) */ +#define VSC_SATA_INT_STAT_OFFSET 0x00 +#define VSC_SATA_INT_MASK_OFFSET 0x04 + +/* Taskfile registers offsets */ +#define VSC_SATA_TF_CMD_OFFSET 0x00 +#define VSC_SATA_TF_DATA_OFFSET 0x00 +#define VSC_SATA_TF_ERROR_OFFSET 0x04 +#define VSC_SATA_TF_FEATURE_OFFSET 0x06 +#define VSC_SATA_TF_NSECT_OFFSET 0x08 +#define VSC_SATA_TF_LBAL_OFFSET 0x0c +#define VSC_SATA_TF_LBAM_OFFSET 0x10 +#define VSC_SATA_TF_LBAH_OFFSET 0x14 +#define VSC_SATA_TF_DEVICE_OFFSET 0x18 +#define VSC_SATA_TF_STATUS_OFFSET 0x1c +#define VSC_SATA_TF_COMMAND_OFFSET 0x1d +#define VSC_SATA_TF_ALTSTATUS_OFFSET 0x28 +#define VSC_SATA_TF_CTL_OFFSET 0x29 + +/* DMA base */ +#define VSC_SATA_UP_DESCRIPTOR_OFFSET 0x64 +#define VSC_SATA_UP_DATA_BUFFER_OFFSET 0x6C +#define VSC_SATA_DMA_CMD_OFFSET 0x70 + +/* SCRs base */ +#define VSC_SATA_SCR_STATUS_OFFSET 0x100 +#define VSC_SATA_SCR_ERROR_OFFSET 0x104 +#define VSC_SATA_SCR_CONTROL_OFFSET 0x108 + +/* Port stride */ +#define VSC_SATA_PORT_OFFSET 0x200 + +/* Error interrupt status bit offsets */ +#define VSC_SATA_INT_ERROR_E_OFFSET 2 +#define VSC_SATA_INT_ERROR_P_OFFSET 4 +#define VSC_SATA_INT_ERROR_T_OFFSET 5 +#define VSC_SATA_INT_ERROR_M_OFFSET 1 #define is_vsc_sata_int_err(port_idx, int_status) \ - (int_status & (VSC_SATA_INT_ERROR << (8 * port_idx))) + (int_status & ((1 << (VSC_SATA_INT_ERROR_E_OFFSET + (8 * port_idx))) | \ + (1 << (VSC_SATA_INT_ERROR_P_OFFSET + (8 * port_idx))) | \ + (1 << (VSC_SATA_INT_ERROR_T_OFFSET + (8 * port_idx))) | \ + (1 << (VSC_SATA_INT_ERROR_M_OFFSET + (8 * port_idx))) \ + )\ + ) static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) @@ -221,6 +215,14 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, ap = host_set->ports[i]; + if (is_vsc_sata_int_err(i, int_status)) { + u32 err_status; + printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); + err_status = ap ? vsc_sata_scr_read(ap, SCR_ERROR) : 0; + vsc_sata_scr_write(ap, SCR_ERROR, err_status); + handled++; + } + if (ap && !(ap->flags & (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; @@ -228,26 +230,12 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.ctl & ATA_NIEN))) { handled += ata_host_intr(ap, qc); - } else if (is_vsc_sata_int_err(i, int_status)) { - /* - * On some chips (i.e. Intel 31244), an error - * interrupt will sneak in at initialization - * time (phy state changes). Clearing the SCR - * error register is not required, but it prevents - * the phy state change interrupts from recurring - * later. - */ - u32 err_status; - err_status = vsc_sata_scr_read(ap, SCR_ERROR); - printk(KERN_DEBUG "%s: clearing interrupt, " - "status %x; sata err status %x\n", - __FUNCTION__, - int_status, err_status); - vsc_sata_scr_write(ap, SCR_ERROR, err_status); - /* Clear interrupt status */ + } else { + printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); ata_chk_status(ap); handled++; } + } } } @@ -263,9 +251,11 @@ static struct scsi_host_template vsc_sata_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 73994e2ac..c551bb84d 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -135,8 +136,9 @@ struct scsi_request *scsi_allocate_request(struct scsi_device *sdev, const int size = offset + sizeof(struct request); struct scsi_request *sreq; - sreq = kzalloc(size, gfp_mask); + sreq = kmalloc(size, gfp_mask); if (likely(sreq != NULL)) { + memset(sreq, 0, size); sreq->sr_request = (struct request *)(((char *)sreq) + offset); sreq->sr_device = sdev; sreq->sr_host = sdev->host; @@ -565,8 +567,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) /* * If SCSI-2 or lower, store the LUN value in cmnd. */ - if (cmd->device->scsi_level <= SCSI_2 && - cmd->device->scsi_level != SCSI_UNKNOWN) { + if (cmd->device->scsi_level <= SCSI_2) { cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) | (cmd->device->lun << 5 & 0xe0); } @@ -1244,9 +1245,10 @@ static int __init init_scsi(void) if (error) goto cleanup_sysctl; - for_each_possible_cpu(i) + for_each_cpu(i) INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); + devfs_mk_dir("scsi"); printk(KERN_NOTICE "SCSI subsystem initialized\n"); return 0; @@ -1271,6 +1273,7 @@ static void __exit exit_scsi(void) scsi_exit_sysctl(); scsi_exit_hosts(); scsi_exit_devinfo(); + devfs_remove("scsi"); scsi_exit_procfs(); scsi_exit_queue(); } diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 5a5d2af8e..0e529f817 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1061,12 +1061,13 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) } } if (NULL == open_devip) { /* try and make a new one */ - open_devip = kzalloc(sizeof(*open_devip),GFP_KERNEL); + open_devip = kmalloc(sizeof(*open_devip),GFP_KERNEL); if (NULL == open_devip) { printk(KERN_ERR "%s: out of memory at line %d\n", __FUNCTION__, __LINE__); return NULL; } + memset(open_devip, 0, sizeof(*open_devip)); open_devip->sdbg_host = sdbg_host; list_add_tail(&open_devip->dev_list, &sdbg_host->dev_info_list); @@ -1813,7 +1814,7 @@ static int sdebug_add_adapter(void) struct sdebug_dev_info *sdbg_devinfo; struct list_head *lh, *lh_sf; - sdbg_host = kzalloc(sizeof(*sdbg_host), GFP_KERNEL); + sdbg_host = kmalloc(sizeof(*sdbg_host),GFP_KERNEL); if (NULL == sdbg_host) { printk(KERN_ERR "%s: out of memory at line %d\n", @@ -1821,17 +1822,19 @@ static int sdebug_add_adapter(void) return -ENOMEM; } + memset(sdbg_host, 0, sizeof(*sdbg_host)); INIT_LIST_HEAD(&sdbg_host->dev_info_list); devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; for (k = 0; k < devs_per_host; k++) { - sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo), GFP_KERNEL); + sdbg_devinfo = kmalloc(sizeof(*sdbg_devinfo),GFP_KERNEL); if (NULL == sdbg_devinfo) { printk(KERN_ERR "%s: out of memory at line %d\n", __FUNCTION__, __LINE__); error = -ENOMEM; goto clean; } + memset(sdbg_devinfo, 0, sizeof(*sdbg_devinfo)); sdbg_devinfo->sdbg_host = sdbg_host; list_add_tail(&sdbg_devinfo->dev_list, &sdbg_host->dev_info_list); diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 62f8cb7b3..84c3937ae 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -56,8 +56,6 @@ static struct { {"DENON", "DRD-25X", "V", BLIST_NOLUN}, /* locks up */ {"HITACHI", "DK312C", "CM81", BLIST_NOLUN}, /* responds to all lun */ {"HITACHI", "DK314C", "CR21", BLIST_NOLUN}, /* responds to all lun */ - {"IBM", "2104-DU3", NULL, BLIST_NOLUN}, /* locks up */ - {"IBM", "2104-TU3", NULL, BLIST_NOLUN}, /* locks up */ {"IMS", "CDD521/10", "2.06", BLIST_NOLUN}, /* locks up */ {"MAXTOR", "XT-3280", "PR02", BLIST_NOLUN}, /* locks up */ {"MAXTOR", "XT-4380S", "B3C", BLIST_NOLUN}, /* locks up */ @@ -134,9 +132,7 @@ static struct { {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */ {"CNSI", "G7324", NULL, BLIST_SPARSELUN}, /* Chaparral G7324 RAID */ {"CNSi", "G8324", NULL, BLIST_SPARSELUN}, /* Chaparral G8324 RAID */ - {"COMPAQ", "ARRAY CONTROLLER", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | - BLIST_MAX_512 | BLIST_REPORTLUN2}, /* Compaq RA4x00 */ - {"COMPAQ", "LOGICAL VOLUME", NULL, BLIST_FORCELUN | BLIST_MAX_512}, /* Compaq RA4x00 */ + {"COMPAQ", "LOGICAL VOLUME", NULL, BLIST_FORCELUN}, {"COMPAQ", "CR3500", NULL, BLIST_FORCELUN}, {"COMPAQ", "MSA1000", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, {"COMPAQ", "MSA1000 VOLUME", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, @@ -165,7 +161,6 @@ static struct { {"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, {"HP", "C1557A", NULL, BLIST_FORCELUN}, {"HP", "C3323-300", "4269", BLIST_NOTQ}, - {"HP", "C5713A", NULL, BLIST_NOREPORTLUN}, {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN}, {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 1c75646f9..ff82ccfbb 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -164,12 +163,16 @@ void scsi_times_out(struct scsi_cmnd *scmd) { scsi_log_completion(scmd, TIMEOUT_ERROR); - if (scmd->device->host->transportt->eh_timed_out) - switch (scmd->device->host->transportt->eh_timed_out(scmd)) { + if (scmd->device->host->hostt->eh_timed_out) + switch (scmd->device->host->hostt->eh_timed_out(scmd)) { case EH_HANDLED: __scsi_done(scmd); return; case EH_RESET_TIMER: + /* This allows a single retry even of a command + * with allowed == 0 */ + if (scmd->retries++ > scmd->allowed) + break; scsi_add_timer(scmd, scmd->timeout_per_command, scsi_times_out); return; @@ -581,7 +584,8 @@ static int scsi_request_sense(struct scsi_cmnd *scmd) * keep a list of pending commands for final completion, and once we * are ready to leave error handling we handle completion for real. **/ -void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q) +static void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, + struct list_head *done_q) { scmd->device->host->host_failed--; scmd->eh_eflags = 0; @@ -593,7 +597,6 @@ void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q) scsi_setup_cmd_retry(scmd); list_move_tail(&scmd->eh_entry, done_q); } -EXPORT_SYMBOL(scsi_eh_finish_cmd); /** * scsi_eh_get_sense - Get device sense data. @@ -1422,7 +1425,7 @@ static void scsi_eh_ready_devs(struct Scsi_Host *shost, * @done_q: list_head of processed commands. * **/ -void scsi_eh_flush_done_q(struct list_head *done_q) +static void scsi_eh_flush_done_q(struct list_head *done_q) { struct scsi_cmnd *scmd, *next; @@ -1451,7 +1454,6 @@ void scsi_eh_flush_done_q(struct list_head *done_q) } } } -EXPORT_SYMBOL(scsi_eh_flush_done_q); /** * scsi_unjam_host - Attempt to fix a host which has a cmd that failed. @@ -1537,8 +1539,8 @@ int scsi_error_handler(void *data) * what we need to do to get it up and online again (if we can). * If we fail, we end up taking the thing offline. */ - if (shost->transportt->eh_strategy_handler) - shost->transportt->eh_strategy_handler(shost); + if (shost->hostt->eh_strategy_handler) + shost->hostt->eh_strategy_handler(shost); else scsi_unjam_host(shost); diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 46ababf31..0bba7d8ee 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -110,8 +110,11 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, sshdr.asc, sshdr.ascq); break; case NOT_READY: /* This happens if there is no disc in drive */ - if (sdev->removable) + if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) { + printk(KERN_INFO "Device not ready. Make sure" + " there is a disc in the drive.\n"); break; + } case UNIT_ATTENTION: if (sdev->removable) { sdev->changed = 1; @@ -154,6 +157,181 @@ int scsi_set_medium_removal(struct scsi_device *sdev, char state) } EXPORT_SYMBOL(scsi_set_medium_removal); +/* + * This interface is deprecated - users should use the scsi generic (sg) + * interface instead, as this is a more flexible approach to performing + * generic SCSI commands on a device. + * + * The structure that we are passed should look like: + * + * struct sdata { + * unsigned int inlen; [i] Length of data to be written to device + * unsigned int outlen; [i] Length of data to be read from device + * unsigned char cmd[x]; [i] SCSI command (6 <= x <= 12). + * [o] Data read from device starts here. + * [o] On error, sense buffer starts here. + * unsigned char wdata[y]; [i] Data written to device starts here. + * }; + * Notes: + * - The SCSI command length is determined by examining the 1st byte + * of the given command. There is no way to override this. + * - Data transfers are limited to PAGE_SIZE (4K on i386, 8K on alpha). + * - The length (x + y) must be at least OMAX_SB_LEN bytes long to + * accommodate the sense buffer when an error occurs. + * The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that + * old code will not be surprised. + * - If a Unix error occurs (e.g. ENOMEM) then the user will receive + * a negative return and the Unix error code in 'errno'. + * If the SCSI command succeeds then 0 is returned. + * Positive numbers returned are the compacted SCSI error codes (4 + * bytes in one int) where the lowest byte is the SCSI status. + * See the drivers/scsi/scsi.h file for more information on this. + * + */ +#define OMAX_SB_LEN 16 /* Old sense buffer length */ + +int scsi_ioctl_send_command(struct scsi_device *sdev, + struct scsi_ioctl_command __user *sic) +{ + char *buf; + unsigned char cmd[MAX_COMMAND_SIZE]; + unsigned char sense[SCSI_SENSE_BUFFERSIZE]; + char __user *cmd_in; + unsigned char opcode; + unsigned int inlen, outlen, cmdlen; + unsigned int needed, buf_needed; + int timeout, retries, result; + int data_direction; + gfp_t gfp_mask = GFP_KERNEL; + + if (!sic) + return -EINVAL; + + if (sdev->host->unchecked_isa_dma) + gfp_mask |= GFP_DMA; + + /* + * Verify that we can read at least this much. + */ + if (!access_ok(VERIFY_READ, sic, sizeof(Scsi_Ioctl_Command))) + return -EFAULT; + + if(__get_user(inlen, &sic->inlen)) + return -EFAULT; + + if(__get_user(outlen, &sic->outlen)) + return -EFAULT; + + /* + * We do not transfer more than MAX_BUF with this interface. + * If the user needs to transfer more data than this, they + * should use scsi_generics (sg) instead. + */ + if (inlen > MAX_BUF) + return -EINVAL; + if (outlen > MAX_BUF) + return -EINVAL; + + cmd_in = sic->data; + if(get_user(opcode, cmd_in)) + return -EFAULT; + + needed = buf_needed = (inlen > outlen ? inlen : outlen); + if (buf_needed) { + buf_needed = (buf_needed + 511) & ~511; + if (buf_needed > MAX_BUF) + buf_needed = MAX_BUF; + buf = kmalloc(buf_needed, gfp_mask); + if (!buf) + return -ENOMEM; + memset(buf, 0, buf_needed); + if (inlen == 0) { + data_direction = DMA_FROM_DEVICE; + } else if (outlen == 0 ) { + data_direction = DMA_TO_DEVICE; + } else { + /* + * Can this ever happen? + */ + data_direction = DMA_BIDIRECTIONAL; + } + + } else { + buf = NULL; + data_direction = DMA_NONE; + } + + /* + * Obtain the command from the user's address space. + */ + cmdlen = COMMAND_SIZE(opcode); + + result = -EFAULT; + + if (!access_ok(VERIFY_READ, cmd_in, cmdlen + inlen)) + goto error; + + if(__copy_from_user(cmd, cmd_in, cmdlen)) + goto error; + + /* + * Obtain the data to be sent to the device (if any). + */ + + if(inlen && copy_from_user(buf, cmd_in + cmdlen, inlen)) + goto error; + + switch (opcode) { + case SEND_DIAGNOSTIC: + case FORMAT_UNIT: + timeout = FORMAT_UNIT_TIMEOUT; + retries = 1; + break; + case START_STOP: + timeout = START_STOP_TIMEOUT; + retries = NORMAL_RETRIES; + break; + case MOVE_MEDIUM: + timeout = MOVE_MEDIUM_TIMEOUT; + retries = NORMAL_RETRIES; + break; + case READ_ELEMENT_STATUS: + timeout = READ_ELEMENT_STATUS_TIMEOUT; + retries = NORMAL_RETRIES; + break; + case READ_DEFECT_DATA: + timeout = READ_DEFECT_DATA_TIMEOUT; + retries = 1; + break; + default: + timeout = IOCTL_NORMAL_TIMEOUT; + retries = NORMAL_RETRIES; + break; + } + + result = scsi_execute(sdev, cmd, data_direction, buf, needed, + sense, timeout, retries, 0); + + /* + * If there was an error condition, pass the info back to the user. + */ + if (result) { + int sb_len = sizeof(*sense); + + sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len; + if (copy_to_user(cmd_in, sense, sb_len)) + result = -EFAULT; + } else { + if (outlen && copy_to_user(cmd_in, buf, outlen)) + result = -EFAULT; + } + +error: + kfree(buf); + return result; +} +EXPORT_SYMBOL(scsi_ioctl_send_command); + /* * The scsi_ioctl_get_pci() function places into arg the value * pci_dev::slot_name (8 characters) for the PCI device (if any). @@ -232,7 +410,7 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) case SCSI_IOCTL_SEND_COMMAND: if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; - return sg_scsi_ioctl(NULL, sdev->request_queue, NULL, arg); + return scsi_ioctl_send_command(sdev, arg); case SCSI_IOCTL_DOORLOCK: return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT); case SCSI_IOCTL_DOORUNLOCK: diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index faee4757c..e29f943a8 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -286,12 +286,13 @@ int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, int result; if (sshdr) { - sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); + sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); if (!sense) return DRIVER_ERROR << 24; + memset(sense, 0, SCSI_SENSE_BUFFERSIZE); } result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen, - sense, timeout, retries, 0); + sense, timeout, retries, 0); if (sshdr) scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr); @@ -474,6 +475,7 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, goto free_req; req->cmd_len = cmd_len; + memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ memcpy(req->cmd, cmd, req->cmd_len); req->sense = sioc->sense; req->sense_len = 0; @@ -1067,29 +1069,16 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, break; case NOT_READY: /* - * If the device is in the process of becoming - * ready, or has a temporary blockage, retry. + * If the device is in the process of becoming ready, + * retry. */ - if (sshdr.asc == 0x04) { - switch (sshdr.ascq) { - case 0x01: /* becoming ready */ - case 0x04: /* format in progress */ - case 0x05: /* rebuild in progress */ - case 0x06: /* recalculation in progress */ - case 0x07: /* operation in progress */ - case 0x08: /* Long write in progress */ - case 0x09: /* self test in progress */ - scsi_requeue_command(q, cmd); - return; - default: - break; - } + if (sshdr.asc == 0x04 && sshdr.ascq == 0x01) { + scsi_requeue_command(q, cmd); + return; } - if (!(req->flags & REQ_QUIET)) { + if (!(req->flags & REQ_QUIET)) scmd_printk(KERN_INFO, cmd, - "Device not ready: "); - scsi_print_sense_hdr("", &sshdr); - } + "Device not ready.\n"); scsi_end_request(cmd, 0, this_count, 1); return; case VOLUME_OVERFLOW: @@ -1492,8 +1481,6 @@ static inline int scsi_host_queue_ready(struct request_queue *q, static void scsi_kill_request(struct request *req, request_queue_t *q) { struct scsi_cmnd *cmd = req->special; - struct scsi_device *sdev = cmd->device; - struct Scsi_Host *shost = sdev->host; blkdev_dequeue_request(req); @@ -1506,19 +1493,6 @@ static void scsi_kill_request(struct request *req, request_queue_t *q) scsi_init_cmd_errh(cmd); cmd->result = DID_NO_CONNECT << 16; atomic_inc(&cmd->device->iorequest_cnt); - - /* - * SCSI request completion path will do scsi_device_unbusy(), - * bump busy counts. To bump the counters, we need to dance - * with the locks as normal issue path does. - */ - sdev->device_busy++; - spin_unlock(sdev->request_queue->queue_lock); - spin_lock(shost->host_lock); - shost->host_busy++; - spin_unlock(shost->host_lock); - spin_lock(sdev->request_queue->queue_lock); - __scsi_done(cmd); } @@ -1815,8 +1789,9 @@ int __init scsi_init_queue(void) sgp->name); } - sgp->pool = mempool_create_slab_pool(SG_MEMPOOL_SIZE, - sgp->slab); + sgp->pool = mempool_create(SG_MEMPOOL_SIZE, + mempool_alloc_slab, mempool_free_slab, + sgp->slab); if (!sgp->pool) { printk(KERN_ERR "SCSI: can't init sg mempool %s\n", sgp->name); @@ -1838,84 +1813,6 @@ void scsi_exit_queue(void) kmem_cache_destroy(sgp->slab); } } - -/** - * scsi_mode_select - issue a mode select - * @sdev: SCSI device to be queried - * @pf: Page format bit (1 == standard, 0 == vendor specific) - * @sp: Save page bit (0 == don't save, 1 == save) - * @modepage: mode page being requested - * @buffer: request buffer (may not be smaller than eight bytes) - * @len: length of request buffer. - * @timeout: command timeout - * @retries: number of retries before failing - * @data: returns a structure abstracting the mode header data - * @sense: place to put sense data (or NULL if no sense to be collected). - * must be SCSI_SENSE_BUFFERSIZE big. - * - * Returns zero if successful; negative error number or scsi - * status on error - * - */ -int -scsi_mode_select(struct scsi_device *sdev, int pf, int sp, int modepage, - unsigned char *buffer, int len, int timeout, int retries, - struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) -{ - unsigned char cmd[10]; - unsigned char *real_buffer; - int ret; - - memset(cmd, 0, sizeof(cmd)); - cmd[1] = (pf ? 0x10 : 0) | (sp ? 0x01 : 0); - - if (sdev->use_10_for_ms) { - if (len > 65535) - return -EINVAL; - real_buffer = kmalloc(8 + len, GFP_KERNEL); - if (!real_buffer) - return -ENOMEM; - memcpy(real_buffer + 8, buffer, len); - len += 8; - real_buffer[0] = 0; - real_buffer[1] = 0; - real_buffer[2] = data->medium_type; - real_buffer[3] = data->device_specific; - real_buffer[4] = data->longlba ? 0x01 : 0; - real_buffer[5] = 0; - real_buffer[6] = data->block_descriptor_length >> 8; - real_buffer[7] = data->block_descriptor_length; - - cmd[0] = MODE_SELECT_10; - cmd[7] = len >> 8; - cmd[8] = len; - } else { - if (len > 255 || data->block_descriptor_length > 255 || - data->longlba) - return -EINVAL; - - real_buffer = kmalloc(4 + len, GFP_KERNEL); - if (!real_buffer) - return -ENOMEM; - memcpy(real_buffer + 4, buffer, len); - len += 4; - real_buffer[0] = 0; - real_buffer[1] = data->medium_type; - real_buffer[2] = data->device_specific; - real_buffer[3] = data->block_descriptor_length; - - - cmd[0] = MODE_SELECT; - cmd[4] = len; - } - - ret = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, real_buffer, len, - sshdr, timeout, retries); - kfree(real_buffer); - return ret; -} -EXPORT_SYMBOL_GPL(scsi_mode_select); - /** * scsi_mode_sense - issue a mode sense, falling back from 10 to * six bytes if necessary. @@ -1937,8 +1834,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select); int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, unsigned char *buffer, int len, int timeout, int retries, - struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) -{ + struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) { unsigned char cmd[12]; int use_10_for_ms; int header_length; @@ -1998,16 +1894,8 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, } if(scsi_status_is_good(result)) { - if (unlikely(buffer[0] == 0x86 && buffer[1] == 0x0b && - (modepage == 6 || modepage == 8))) { - /* Initio breakage? */ - header_length = 0; - data->length = 13; - data->medium_type = 0; - data->device_specific = 0; - data->longlba = 0; - data->block_descriptor_length = 0; - } else if(use_10_for_ms) { + data->header_length = header_length; + if(use_10_for_ms) { data->length = buffer[0]*256 + buffer[1] + 2; data->medium_type = buffer[2]; data->device_specific = buffer[3]; @@ -2020,7 +1908,6 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, data->device_specific = buffer[2]; data->block_descriptor_length = buffer[3]; } - data->header_length = header_length; } return result; @@ -2363,3 +2250,61 @@ scsi_target_unblock(struct device *dev) device_for_each_child(dev, NULL, target_unblock); } EXPORT_SYMBOL_GPL(scsi_target_unblock); + + +struct work_queue_work { + struct work_struct work; + void (*fn)(void *); + void *data; +}; + +static void execute_in_process_context_work(void *data) +{ + void (*fn)(void *data); + struct work_queue_work *wqw = data; + + fn = wqw->fn; + data = wqw->data; + + kfree(wqw); + + fn(data); +} + +/** + * scsi_execute_in_process_context - reliably execute the routine with user context + * @fn: the function to execute + * @data: data to pass to the function + * + * Executes the function immediately if process context is available, + * otherwise schedules the function for delayed execution. + * + * Returns: 0 - function was executed + * 1 - function was scheduled for execution + * <0 - error + */ +int scsi_execute_in_process_context(void (*fn)(void *data), void *data) +{ + struct work_queue_work *wqw; + + if (!in_interrupt()) { + fn(data); + return 0; + } + + wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC); + + if (unlikely(!wqw)) { + printk(KERN_ERR "Failed to allocate memory\n"); + WARN_ON(1); + return -ENOMEM; + } + + INIT_WORK(&wqw->work, execute_in_process_context_work, wqw); + wqw->fn = fn; + wqw->data = data; + schedule_work(&wqw->work); + + return 1; +} +EXPORT_SYMBOL_GPL(scsi_execute_in_process_context); diff --git a/drivers/scsi/scsi_sas_internal.h b/drivers/scsi/scsi_sas_internal.h deleted file mode 100644 index d76e6e3d8..000000000 --- a/drivers/scsi/scsi_sas_internal.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _SCSI_SAS_INTERNAL_H -#define _SCSI_SAS_INTERNAL_H - -#define SAS_HOST_ATTRS 0 -#define SAS_PORT_ATTRS 17 -#define SAS_RPORT_ATTRS 7 -#define SAS_END_DEV_ATTRS 3 -#define SAS_EXPANDER_ATTRS 7 - -struct sas_internal { - struct scsi_transport_template t; - struct sas_function_template *f; - struct sas_domain_function_template *dft; - - struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; - struct class_device_attribute private_phy_attrs[SAS_PORT_ATTRS]; - struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; - struct class_device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS]; - struct class_device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS]; - - struct transport_container phy_attr_cont; - struct transport_container rphy_attr_cont; - struct transport_container end_dev_attr_cont; - struct transport_container expander_attr_cont; - - /* - * The array of null terminated pointers to attributes - * needed by scsi_sysfs.c - */ - struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; - struct class_device_attribute *phy_attrs[SAS_PORT_ATTRS + 1]; - struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; - struct class_device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1]; - struct class_device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1]; -}; -#define to_sas_internal(tmpl) container_of(tmpl, struct sas_internal, t) - -#endif diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 1a5474bd1..f9ecc3dea 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -205,11 +205,12 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, int display_failure_msg = 1, ret; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size, + sdev = kmalloc(sizeof(*sdev) + shost->transportt->device_size, GFP_ATOMIC); if (!sdev) goto out; + memset(sdev, 0, sizeof(*sdev)); sdev->vendor = scsi_null_device_strs; sdev->model = scsi_null_device_strs; sdev->rev = scsi_null_device_strs; @@ -251,7 +252,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, /* release fn is set up in scsi_sysfs_device_initialise, so * have to free and put manually here */ put_device(&starget->dev); - kfree(sdev); goto out; } @@ -288,7 +288,10 @@ static void scsi_target_dev_release(struct device *dev) { struct device *parent = dev->parent; struct scsi_target *starget = to_scsi_target(dev); + struct Scsi_Host *shost = dev_to_shost(parent); + if (shost->hostt->target_destroy) + shost->hostt->target_destroy(starget); kfree(starget); put_device(parent); } @@ -330,13 +333,13 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, + shost->transportt->target_size; struct scsi_target *starget; struct scsi_target *found_target; - int error; - starget = kzalloc(size, GFP_KERNEL); + starget = kmalloc(size, GFP_KERNEL); if (!starget) { printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); return NULL; } + memset(starget, 0, size); dev = &starget->dev; device_initialize(dev); starget->reap_ref = 1; @@ -348,8 +351,6 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, starget->channel = channel; INIT_LIST_HEAD(&starget->siblings); INIT_LIST_HEAD(&starget->devices); - starget->state = STARGET_RUNNING; - retry: spin_lock_irqsave(shost->host_lock, flags); found_target = __scsi_find_target(parent, channel, id); @@ -360,20 +361,10 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, spin_unlock_irqrestore(shost->host_lock, flags); /* allocate and add */ transport_setup_device(dev); - error = device_add(dev); - if (error) { - dev_err(dev, "target device_add failed, error %d\n", error); - spin_lock_irqsave(shost->host_lock, flags); - list_del_init(&starget->siblings); - spin_unlock_irqrestore(shost->host_lock, flags); - transport_destroy_device(dev); - put_device(parent); - kfree(starget); - return NULL; - } + device_add(dev); transport_add_device(dev); if (shost->hostt->target_alloc) { - error = shost->hostt->target_alloc(starget); + int error = shost->hostt->target_alloc(starget); if(error) { dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error); @@ -392,15 +383,8 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, found_target->reap_ref++; spin_unlock_irqrestore(shost->host_lock, flags); put_device(parent); - if (found_target->state != STARGET_DEL) { - kfree(starget); - return found_target; - } - /* Unfortunately, we found a dying target; need to - * wait until it's dead before we can get a new one */ - put_device(&found_target->dev); - flush_scheduled_work(); - goto retry; + kfree(starget); + return found_target; } static void scsi_target_reap_usercontext(void *data) @@ -409,15 +393,21 @@ static void scsi_target_reap_usercontext(void *data) struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); unsigned long flags; - transport_remove_device(&starget->dev); - device_del(&starget->dev); - transport_destroy_device(&starget->dev); spin_lock_irqsave(shost->host_lock, flags); - if (shost->hostt->target_destroy) - shost->hostt->target_destroy(starget); - list_del_init(&starget->siblings); + + if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { + list_del_init(&starget->siblings); + spin_unlock_irqrestore(shost->host_lock, flags); + transport_remove_device(&starget->dev); + device_del(&starget->dev); + transport_destroy_device(&starget->dev); + put_device(&starget->dev); + return; + + } spin_unlock_irqrestore(shost->host_lock, flags); - put_device(&starget->dev); + + return; } /** @@ -431,23 +421,7 @@ static void scsi_target_reap_usercontext(void *data) */ void scsi_target_reap(struct scsi_target *starget) { - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - unsigned long flags; - - spin_lock_irqsave(shost->host_lock, flags); - - if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { - BUG_ON(starget->state == STARGET_DEL); - starget->state = STARGET_DEL; - spin_unlock_irqrestore(shost->host_lock, flags); - execute_in_process_context(scsi_target_reap_usercontext, - starget, &starget->ew); - return; - - } - spin_unlock_irqrestore(shost->host_lock, flags); - - return; + scsi_execute_in_process_context(scsi_target_reap_usercontext, starget); } /** @@ -673,7 +647,6 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) case TYPE_MEDIUM_CHANGER: case TYPE_ENCLOSURE: case TYPE_COMM: - case TYPE_RAID: case TYPE_RBC: sdev->writeable = 1; break; @@ -716,8 +689,12 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) if (inq_result[7] & 0x10) sdev->sdtr = 1; + sprintf(sdev->devfs_name, "scsi/host%d/bus%d/target%d/lun%d", + sdev->host->host_no, sdev->channel, + sdev->id, sdev->lun); + /* - * End sysfs code. + * End driverfs/devfs code. */ if ((sdev->scsi_level >= SCSI_2) && (inq_result[7] & 2) && @@ -738,13 +715,6 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) if (*bflags & BLIST_SELECT_NO_ATN) sdev->select_no_atn = 1; - /* - * Maximum 512 sector transfer length - * broken RA4x00 Compaq Disk Array - */ - if (*bflags & BLIST_MAX_512) - blk_queue_max_sectors(sdev->request_queue, 512); - /* * Some devices may not want to have a start command automatically * issued when a device is added. @@ -901,19 +871,6 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, goto out_free_result; } - /* - * Non-standard SCSI targets may set the PDT to 0x1f (unknown or - * no device type) instead of using the Peripheral Qualifier to - * indicate that no LUN is present. For example, USB UFI does this. - */ - if (starget->pdt_1f_for_no_lun && (result[0] & 0x1f) == 0x1f) { - SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO - "scsi scan: peripheral device type" - " of 31, no device added\n")); - res = SCSI_SCAN_TARGET_PRESENT; - goto out_free_result; - } - res = scsi_add_lun(sdev, result, &bflags); if (res == SCSI_SCAN_LUN_PRESENT) { if (bflags & BLIST_KEY) { @@ -1131,13 +1088,10 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does * support more than 8 LUNs. */ - if (bflags & BLIST_NOREPORTLUN) - return 1; - if (starget->scsi_level < SCSI_2 && - starget->scsi_level != SCSI_UNKNOWN) - return 1; - if (starget->scsi_level < SCSI_3 && - (!(bflags & BLIST_REPORTLUN2) || shost->max_lun <= 8)) + if ((bflags & BLIST_NOREPORTLUN) || + starget->scsi_level < SCSI_2 || + (starget->scsi_level < SCSI_3 && + (!(bflags & BLIST_REPORTLUN2) || shost->max_lun <= 8)) ) return 1; if (bflags & BLIST_NOLUN) return 0; @@ -1307,8 +1261,9 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, uint id, uint lun, void *hostdata) { - struct scsi_device *sdev = ERR_PTR(-ENODEV); + struct scsi_device *sdev; struct device *parent = &shost->shost_gendev; + int res; struct scsi_target *starget; starget = scsi_alloc_target(parent, channel, id); @@ -1317,8 +1272,12 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, get_device(&starget->dev); mutex_lock(&shost->scan_mutex); - if (scsi_host_scan_allowed(shost)) - scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); + if (scsi_host_scan_allowed(shost)) { + res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, + hostdata); + if (res != SCSI_SCAN_LUN_PRESENT) + sdev = ERR_PTR(-ENODEV); + } mutex_unlock(&shost->scan_mutex); scsi_target_reap(starget); put_device(&starget->dev); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index a6fde5294..902a5def8 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -256,9 +256,7 @@ static void scsi_device_dev_release_usercontext(void *data) static void scsi_device_dev_release(struct device *dev) { - struct scsi_device *sdp = to_scsi_device(dev); - execute_in_process_context(scsi_device_dev_release_usercontext, dev, - &sdp->ew); + scsi_execute_in_process_context(scsi_device_dev_release_usercontext, dev); } static struct class sdev_class = { @@ -286,7 +284,7 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state) return err; if (sht->suspend) - err = sht->suspend(sdev, state); + err = sht->suspend(sdev); return err; } diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 95c5478dc..13ea64119 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -31,11 +31,8 @@ #include #include #include -#include #include "scsi_priv.h" -static int fc_queue_work(struct Scsi_Host *, struct work_struct *); - /* * Redefine so that we can have same named attributes in the * sdev/starget/host objects. @@ -215,8 +212,10 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names) #define FC_MGMTSRVR_PORTID 0x00000a +static void fc_shost_remove_rports(void *data); static void fc_timeout_deleted_rport(void *data); static void fc_scsi_scan_rport(void *data); +static void fc_rport_terminate(struct fc_rport *rport); /* * Attribute counts pre object type... @@ -288,58 +287,42 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev, struct class_device *cdev) { struct Scsi_Host *shost = dev_to_shost(dev); - struct fc_host_attrs *fc_host = shost_to_fc_host(shost); /* * Set default values easily detected by the midlayer as * failure cases. The scsi lldd is responsible for initializing * all transport attributes to valid values per host. */ - fc_host->node_name = -1; - fc_host->port_name = -1; - fc_host->permanent_port_name = -1; - fc_host->supported_classes = FC_COS_UNSPECIFIED; - memset(fc_host->supported_fc4s, 0, - sizeof(fc_host->supported_fc4s)); - memset(fc_host->symbolic_name, 0, - sizeof(fc_host->symbolic_name)); - fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN; - fc_host->maxframe_size = -1; - memset(fc_host->serial_number, 0, - sizeof(fc_host->serial_number)); - - fc_host->port_id = -1; - fc_host->port_type = FC_PORTTYPE_UNKNOWN; - fc_host->port_state = FC_PORTSTATE_UNKNOWN; - memset(fc_host->active_fc4s, 0, - sizeof(fc_host->active_fc4s)); - fc_host->speed = FC_PORTSPEED_UNKNOWN; - fc_host->fabric_name = -1; - - fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN; - - INIT_LIST_HEAD(&fc_host->rports); - INIT_LIST_HEAD(&fc_host->rport_bindings); - fc_host->next_rport_number = 0; - fc_host->next_target_id = 0; - - snprintf(fc_host->work_q_name, KOBJ_NAME_LEN, "fc_wq_%d", - shost->host_no); - fc_host->work_q = create_singlethread_workqueue( - fc_host->work_q_name); - if (!fc_host->work_q) - return -ENOMEM; - - snprintf(fc_host->devloss_work_q_name, KOBJ_NAME_LEN, "fc_dl_%d", - shost->host_no); - fc_host->devloss_work_q = create_singlethread_workqueue( - fc_host->devloss_work_q_name); - if (!fc_host->devloss_work_q) { - destroy_workqueue(fc_host->work_q); - fc_host->work_q = NULL; - return -ENOMEM; - } - + fc_host_node_name(shost) = -1; + fc_host_port_name(shost) = -1; + fc_host_permanent_port_name(shost) = -1; + fc_host_supported_classes(shost) = FC_COS_UNSPECIFIED; + memset(fc_host_supported_fc4s(shost), 0, + sizeof(fc_host_supported_fc4s(shost))); + memset(fc_host_symbolic_name(shost), 0, + sizeof(fc_host_symbolic_name(shost))); + fc_host_supported_speeds(shost) = FC_PORTSPEED_UNKNOWN; + fc_host_maxframe_size(shost) = -1; + memset(fc_host_serial_number(shost), 0, + sizeof(fc_host_serial_number(shost))); + + fc_host_port_id(shost) = -1; + fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; + fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; + memset(fc_host_active_fc4s(shost), 0, + sizeof(fc_host_active_fc4s(shost))); + fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; + fc_host_fabric_name(shost) = -1; + + fc_host_tgtid_bind_type(shost) = FC_TGTID_BIND_BY_WWPN; + + INIT_LIST_HEAD(&fc_host_rports(shost)); + INIT_LIST_HEAD(&fc_host_rport_bindings(shost)); + fc_host_next_rport_number(shost) = 0; + fc_host_next_target_id(shost) = 0; + + fc_host_flags(shost) = 0; + INIT_WORK(&fc_host_rport_del_work(shost), fc_shost_remove_rports, shost); return 0; } @@ -895,9 +878,9 @@ store_fc_private_host_tgtid_bind_type(struct class_device *cdev, while (!list_empty(&fc_host_rport_bindings(shost))) { get_list_head_entry(rport, &fc_host_rport_bindings(shost), peers); - list_del(&rport->peers); - rport->port_state = FC_PORTSTATE_DELETED; - fc_queue_work(shost, &rport->rport_delete_work); + spin_unlock_irqrestore(shost->host_lock, flags); + fc_rport_terminate(rport); + spin_lock_irqsave(shost->host_lock, flags); } spin_unlock_irqrestore(shost->host_lock, flags); } @@ -1107,40 +1090,6 @@ static int fc_rport_match(struct attribute_container *cont, } -/** - * fc_timed_out - FC Transport I/O timeout intercept handler - * - * @scmd: The SCSI command which timed out - * - * This routine protects against error handlers getting invoked while a - * rport is in a blocked state, typically due to a temporarily loss of - * connectivity. If the error handlers are allowed to proceed, requests - * to abort i/o, reset the target, etc will likely fail as there is no way - * to communicate with the device to perform the requested function. These - * failures may result in the midlayer taking the device offline, requiring - * manual intervention to restore operation. - * - * This routine, called whenever an i/o times out, validates the state of - * the underlying rport. If the rport is blocked, it returns - * EH_RESET_TIMER, which will continue to reschedule the timeout. - * Eventually, either the device will return, or devloss_tmo will fire, - * and when the timeout then fires, it will be handled normally. - * If the rport is not blocked, normal error handling continues. - * - * Notes: - * This routine assumes no locks are held on entry. - **/ -static enum scsi_eh_timer_return -fc_timed_out(struct scsi_cmnd *scmd) -{ - struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device)); - - if (rport->port_state == FC_PORTSTATE_BLOCKED) - return EH_RESET_TIMER; - - return EH_NOT_HANDLED; -} - /* * Must be called with shost->host_lock held */ @@ -1166,13 +1115,15 @@ static int fc_user_scan(struct Scsi_Host *shost, uint channel, struct scsi_transport_template * fc_attach_transport(struct fc_function_template *ft) { - int count; - struct fc_internal *i = kzalloc(sizeof(struct fc_internal), + struct fc_internal *i = kmalloc(sizeof(struct fc_internal), GFP_KERNEL); + int count; if (unlikely(!i)) return NULL; + memset(i, 0, sizeof(struct fc_internal)); + i->t.target_attrs.ac.attrs = &i->starget_attrs[0]; i->t.target_attrs.ac.class = &fc_transport_class.class; i->t.target_attrs.ac.match = fc_target_match; @@ -1197,8 +1148,6 @@ fc_attach_transport(struct fc_function_template *ft) /* Transport uses the shost workq for scsi scanning */ i->t.create_work_queue = 1; - i->t.eh_timed_out = fc_timed_out; - i->t.user_scan = fc_user_scan; /* @@ -1278,90 +1227,6 @@ void fc_release_transport(struct scsi_transport_template *t) } EXPORT_SYMBOL(fc_release_transport); -/** - * fc_queue_work - Queue work to the fc_host workqueue. - * @shost: Pointer to Scsi_Host bound to fc_host. - * @work: Work to queue for execution. - * - * Return value: - * 0 on success / != 0 for error - **/ -static int -fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) -{ - if (unlikely(!fc_host_work_q(shost))) { - printk(KERN_ERR - "ERROR: FC host '%s' attempted to queue work, " - "when no workqueue created.\n", shost->hostt->name); - dump_stack(); - - return -EINVAL; - } - - return queue_work(fc_host_work_q(shost), work); -} - -/** - * fc_flush_work - Flush a fc_host's workqueue. - * @shost: Pointer to Scsi_Host bound to fc_host. - **/ -static void -fc_flush_work(struct Scsi_Host *shost) -{ - if (!fc_host_work_q(shost)) { - printk(KERN_ERR - "ERROR: FC host '%s' attempted to flush work, " - "when no workqueue created.\n", shost->hostt->name); - dump_stack(); - return; - } - - flush_workqueue(fc_host_work_q(shost)); -} - -/** - * fc_queue_devloss_work - Schedule work for the fc_host devloss workqueue. - * @shost: Pointer to Scsi_Host bound to fc_host. - * @work: Work to queue for execution. - * @delay: jiffies to delay the work queuing - * - * Return value: - * 0 on success / != 0 for error - **/ -static int -fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work, - unsigned long delay) -{ - if (unlikely(!fc_host_devloss_work_q(shost))) { - printk(KERN_ERR - "ERROR: FC host '%s' attempted to queue work, " - "when no workqueue created.\n", shost->hostt->name); - dump_stack(); - - return -EINVAL; - } - - return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay); -} - -/** - * fc_flush_devloss - Flush a fc_host's devloss workqueue. - * @shost: Pointer to Scsi_Host bound to fc_host. - **/ -static void -fc_flush_devloss(struct Scsi_Host *shost) -{ - if (!fc_host_devloss_work_q(shost)) { - printk(KERN_ERR - "ERROR: FC host '%s' attempted to flush work, " - "when no workqueue created.\n", shost->hostt->name); - dump_stack(); - return; - } - - flush_workqueue(fc_host_devloss_work_q(shost)); -} - /** * fc_remove_host - called to terminate any fc_transport-related elements @@ -1383,103 +1248,36 @@ void fc_remove_host(struct Scsi_Host *shost) { struct fc_rport *rport, *next_rport; - struct workqueue_struct *work_q; - struct fc_host_attrs *fc_host = shost_to_fc_host(shost); /* Remove any remote ports */ list_for_each_entry_safe(rport, next_rport, - &fc_host->rports, peers) { - list_del(&rport->peers); - rport->port_state = FC_PORTSTATE_DELETED; - fc_queue_work(shost, &rport->rport_delete_work); - } - + &fc_host_rports(shost), peers) + fc_rport_terminate(rport); list_for_each_entry_safe(rport, next_rport, - &fc_host->rport_bindings, peers) { - list_del(&rport->peers); - rport->port_state = FC_PORTSTATE_DELETED; - fc_queue_work(shost, &rport->rport_delete_work); - } - - /* flush all scan work items */ - scsi_flush_work(shost); - - /* flush all stgt delete, and rport delete work items, then kill it */ - if (fc_host->work_q) { - work_q = fc_host->work_q; - fc_host->work_q = NULL; - destroy_workqueue(work_q); - } - - /* flush all devloss work items, then kill it */ - if (fc_host->devloss_work_q) { - work_q = fc_host->devloss_work_q; - fc_host->devloss_work_q = NULL; - destroy_workqueue(work_q); - } + &fc_host_rport_bindings(shost), peers) + fc_rport_terminate(rport); } EXPORT_SYMBOL(fc_remove_host); - -/** - * fc_starget_delete - called to delete the scsi decendents of an rport - * (target and all sdevs) - * - * @data: remote port to be operated on. - **/ +/* + * fc_rport_tgt_remove - Removes the scsi target on the remote port + * @rport: The remote port to be operated on + */ static void -fc_starget_delete(void *data) +fc_rport_tgt_remove(struct fc_rport *rport) { - struct fc_rport *rport = (struct fc_rport *)data; struct Scsi_Host *shost = rport_to_shost(rport); - unsigned long flags; scsi_target_unblock(&rport->dev); - spin_lock_irqsave(shost->host_lock, flags); - if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { - spin_unlock_irqrestore(shost->host_lock, flags); - if (!cancel_delayed_work(&rport->dev_loss_work)) - fc_flush_devloss(shost); - spin_lock_irqsave(shost->host_lock, flags); - rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; - } - spin_unlock_irqrestore(shost->host_lock, flags); + /* Stop anything on the workq */ + if (!cancel_delayed_work(&rport->dev_loss_work)) + flush_scheduled_work(); + scsi_flush_work(shost); scsi_remove_target(&rport->dev); } - -/** - * fc_rport_final_delete - finish rport termination and delete it. - * - * @data: remote port to be deleted. - **/ -static void -fc_rport_final_delete(void *data) -{ - struct fc_rport *rport = (struct fc_rport *)data; - struct device *dev = &rport->dev; - struct Scsi_Host *shost = rport_to_shost(rport); - - /* Delete SCSI target and sdevs */ - if (rport->scsi_target_id != -1) - fc_starget_delete(data); - - /* - * if a scan is pending, flush the SCSI Host work_q so that - * that we can reclaim the rport scan work element. - */ - if (rport->flags & FC_RPORT_SCAN_PENDING) - scsi_flush_work(shost); - - transport_remove_device(dev); - device_del(dev); - transport_destroy_device(dev); - put_device(&shost->shost_gendev); -} - - /** * fc_rport_create - allocates and creates a remote FC port. * @shost: scsi host the remote port is connected to. @@ -1497,7 +1295,8 @@ struct fc_rport * fc_rport_create(struct Scsi_Host *shost, int channel, struct fc_rport_identifiers *ids) { - struct fc_host_attrs *fc_host = shost_to_fc_host(shost); + struct fc_host_attrs *fc_host = + (struct fc_host_attrs *)shost->shost_data; struct fc_internal *fci = to_fc_internal(shost->transportt); struct fc_rport *rport; struct device *dev; @@ -1506,11 +1305,12 @@ fc_rport_create(struct Scsi_Host *shost, int channel, size_t size; size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size); - rport = kzalloc(size, GFP_KERNEL); + rport = kmalloc(size, GFP_KERNEL); if (unlikely(!rport)) { printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); return NULL; } + memset(rport, 0, size); rport->maxframe_size = -1; rport->supported_classes = FC_COS_UNSPECIFIED; @@ -1526,8 +1326,6 @@ fc_rport_create(struct Scsi_Host *shost, int channel, INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport); INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); - INIT_WORK(&rport->stgt_delete_work, fc_starget_delete, rport); - INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete, rport); spin_lock_irqsave(shost->host_lock, flags); @@ -1536,7 +1334,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel, rport->scsi_target_id = fc_host->next_target_id++; else rport->scsi_target_id = -1; - list_add_tail(&rport->peers, &fc_host->rports); + list_add_tail(&rport->peers, &fc_host_rports(shost)); get_device(&shost->shost_gendev); spin_unlock_irqrestore(shost->host_lock, flags); @@ -1557,11 +1355,9 @@ fc_rport_create(struct Scsi_Host *shost, int channel, transport_add_device(dev); transport_configure_device(dev); - if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) { + if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) /* initiate a scan of the target */ - rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); - } return rport; @@ -1621,14 +1417,10 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, struct fc_rport_identifiers *ids) { struct fc_internal *fci = to_fc_internal(shost->transportt); - struct fc_host_attrs *fc_host = shost_to_fc_host(shost); struct fc_rport *rport; unsigned long flags; int match = 0; - /* ensure any stgt delete functions are done */ - fc_flush_work(shost); - /* * Search the list of "active" rports, for an rport that has been * deleted, but we've held off the real delete while the target @@ -1636,12 +1428,12 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, */ spin_lock_irqsave(shost->host_lock, flags); - list_for_each_entry(rport, &fc_host->rports, peers) { + list_for_each_entry(rport, &fc_host_rports(shost), peers) { if ((rport->port_state == FC_PORTSTATE_BLOCKED) && (rport->channel == channel)) { - switch (fc_host->tgtid_bind_type) { + switch (fc_host_tgtid_bind_type(shost)) { case FC_TGTID_BIND_BY_WWPN: case FC_TGTID_BIND_NONE: if (rport->port_name == ids->port_name) @@ -1695,34 +1487,27 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, * transaction. */ if (!cancel_delayed_work(work)) - fc_flush_devloss(shost); - - spin_lock_irqsave(shost->host_lock, flags); - - rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; + flush_scheduled_work(); /* initiate a scan of the target */ - rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); - spin_unlock_irqrestore(shost->host_lock, flags); - return rport; } } } /* Search the bindings array */ - if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) { + if (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE) { /* search for a matching consistent binding */ - list_for_each_entry(rport, &fc_host->rport_bindings, + list_for_each_entry(rport, &fc_host_rport_bindings(shost), peers) { if (rport->channel != channel) continue; - switch (fc_host->tgtid_bind_type) { + switch (fc_host_tgtid_bind_type(shost)) { case FC_TGTID_BIND_BY_WWPN: if (rport->port_name == ids->port_name) match = 1; @@ -1740,7 +1525,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, } if (match) { - list_move_tail(&rport->peers, &fc_host->rports); + list_move_tail(&rport->peers, + &fc_host_rports(shost)); break; } } @@ -1754,17 +1540,15 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, rport->roles = ids->roles; rport->port_state = FC_PORTSTATE_ONLINE; + spin_unlock_irqrestore(shost->host_lock, flags); + if (fci->f->dd_fcrport_size) memset(rport->dd_data, 0, fci->f->dd_fcrport_size); - if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) { + if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) /* initiate a scan of the target */ - rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); - } - - spin_unlock_irqrestore(shost->host_lock, flags); return rport; } @@ -1779,6 +1563,30 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, } EXPORT_SYMBOL(fc_remote_port_add); +/* + * fc_rport_terminate - this routine tears down and deallocates a remote port. + * @rport: The remote port to be terminated + * + * Notes: + * This routine assumes no locks are held on entry. + */ +static void +fc_rport_terminate(struct fc_rport *rport) +{ + struct Scsi_Host *shost = rport_to_shost(rport); + struct device *dev = &rport->dev; + unsigned long flags; + + fc_rport_tgt_remove(rport); + + transport_remove_device(dev); + device_del(dev); + transport_destroy_device(dev); + spin_lock_irqsave(shost->host_lock, flags); + list_del(&rport->peers); + spin_unlock_irqrestore(shost->host_lock, flags); + put_device(&shost->shost_gendev); +} /** * fc_remote_port_delete - notifies the fc transport that a remote @@ -1833,39 +1641,20 @@ EXPORT_SYMBOL(fc_remote_port_add); void fc_remote_port_delete(struct fc_rport *rport) { - struct Scsi_Host *shost = rport_to_shost(rport); int timeout = rport->dev_loss_tmo; - unsigned long flags; - - /* - * No need to flush the fc_host work_q's, as all adds are synchronous. - * - * We do need to reclaim the rport scan work element, so eventually - * (in fc_rport_final_delete()) we'll flush the scsi host work_q if - * there's still a scan pending. - */ - - spin_lock_irqsave(shost->host_lock, flags); /* If no scsi target id mapping, delete it */ if (rport->scsi_target_id == -1) { - list_del(&rport->peers); - rport->port_state = FC_PORTSTATE_DELETED; - fc_queue_work(shost, &rport->rport_delete_work); - spin_unlock_irqrestore(shost->host_lock, flags); + fc_rport_terminate(rport); return; } - rport->port_state = FC_PORTSTATE_BLOCKED; - - rport->flags |= FC_RPORT_DEVLOSS_PENDING; - - spin_unlock_irqrestore(shost->host_lock, flags); - scsi_target_block(&rport->dev); /* cap the length the devices can be blocked until they are deleted */ - fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ); + schedule_delayed_work(&rport->dev_loss_work, timeout * HZ); + + rport->port_state = FC_PORTSTATE_BLOCKED; } EXPORT_SYMBOL(fc_remote_port_delete); @@ -1893,7 +1682,8 @@ void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) { struct Scsi_Host *shost = rport_to_shost(rport); - struct fc_host_attrs *fc_host = shost_to_fc_host(shost); + struct fc_host_attrs *fc_host = + (struct fc_host_attrs *)shost->shost_data; unsigned long flags; int create = 0; @@ -1905,11 +1695,10 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) create = 1; } + spin_unlock_irqrestore(shost->host_lock, flags); rport->roles = roles; - spin_unlock_irqrestore(shost->host_lock, flags); - if (create) { /* * There may have been a delete timer running on the @@ -1924,20 +1713,10 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) * transaction. */ if (!cancel_delayed_work(&rport->dev_loss_work)) - fc_flush_devloss(shost); - - spin_lock_irqsave(shost->host_lock, flags); - rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; - spin_unlock_irqrestore(shost->host_lock, flags); - - /* ensure any stgt delete functions are done */ - fc_flush_work(shost); + flush_scheduled_work(); /* initiate a scan of the target */ - spin_lock_irqsave(shost->host_lock, flags); - rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); - spin_unlock_irqrestore(shost->host_lock, flags); } } EXPORT_SYMBOL(fc_remote_port_rolechg); @@ -1954,24 +1733,22 @@ fc_timeout_deleted_rport(void *data) { struct fc_rport *rport = (struct fc_rport *)data; struct Scsi_Host *shost = rport_to_shost(rport); - struct fc_host_attrs *fc_host = shost_to_fc_host(shost); unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); - rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; - /* - * If the port is ONLINE, then it came back. Validate it's still an - * FCP target. If not, tear down the scsi_target on it. + * If the port is ONLINE, then it came back, but was no longer an + * FCP target. Thus we need to tear down the scsi_target on it. */ - if ((rport->port_state == FC_PORTSTATE_ONLINE) && - !(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { - dev_printk(KERN_ERR, &rport->dev, - "blocked FC remote port time out: no longer" - " a FCP target, removing starget\n"); - fc_queue_work(shost, &rport->stgt_delete_work); + if (rport->port_state == FC_PORTSTATE_ONLINE) { spin_unlock_irqrestore(shost->host_lock, flags); + + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: removing target\n"); + + fc_rport_tgt_remove(rport); + return; } @@ -1982,13 +1759,11 @@ fc_timeout_deleted_rport(void *data) return; } - if (fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) { - list_del(&rport->peers); - rport->port_state = FC_PORTSTATE_DELETED; + if (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE) { + spin_unlock_irqrestore(shost->host_lock, flags); dev_printk(KERN_ERR, &rport->dev, "blocked FC remote port time out: removing target\n"); - fc_queue_work(shost, &rport->rport_delete_work); - spin_unlock_irqrestore(shost->host_lock, flags); + fc_rport_terminate(rport); return; } @@ -1996,7 +1771,7 @@ fc_timeout_deleted_rport(void *data) "blocked FC remote port time out: removing target and " "saving binding\n"); - list_move_tail(&rport->peers, &fc_host->rport_bindings); + list_move_tail(&rport->peers, &fc_host_rport_bindings(shost)); /* * Note: We do not remove or clear the hostdata area. This allows @@ -2010,10 +1785,10 @@ fc_timeout_deleted_rport(void *data) rport->maxframe_size = -1; rport->supported_classes = FC_COS_UNSPECIFIED; rport->roles = FC_RPORT_ROLE_UNKNOWN; - rport->port_state = FC_PORTSTATE_NOTPRESENT; + rport->port_state = FC_PORTSTATE_DELETED; /* remove the identifiers that aren't used in the consisting binding */ - switch (fc_host->tgtid_bind_type) { + switch (fc_host_tgtid_bind_type(shost)) { case FC_TGTID_BIND_BY_WWPN: rport->node_name = -1; rport->port_id = -1; @@ -2034,8 +1809,17 @@ fc_timeout_deleted_rport(void *data) * As this only occurs if the remote port (scsi target) * went away and didn't come back - we'll remove * all attached scsi devices. + * + * We'll schedule the shost work item to perform the actual removal + * to avoid recursion in the different flush calls if we perform + * the removal in each target - and there are lots of targets + * whose timeouts fire at the same time. */ - fc_queue_work(shost, &rport->stgt_delete_work); + + if ( !(fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED)) { + fc_host_flags(shost) |= FC_SHOST_RPORT_DEL_SCHEDULED; + scsi_queue_work(shost, &fc_host_rport_del_work(shost)); + } spin_unlock_irqrestore(shost->host_lock, flags); } @@ -2052,18 +1836,44 @@ static void fc_scsi_scan_rport(void *data) { struct fc_rport *rport = (struct fc_rport *)data; - struct Scsi_Host *shost = rport_to_shost(rport); - unsigned long flags; - if ((rport->port_state == FC_PORTSTATE_ONLINE) && - (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { - scsi_target_unblock(&rport->dev); - scsi_scan_target(&rport->dev, rport->channel, - rport->scsi_target_id, SCAN_WILD_CARD, 1); - } + scsi_target_unblock(&rport->dev); + scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id, + SCAN_WILD_CARD, 1); +} + + +/** + * fc_shost_remove_rports - called to remove all rports that are marked + * as in a deleted (not connected) state. + * + * @data: shost whose rports are to be looked at + **/ +static void +fc_shost_remove_rports(void *data) +{ + struct Scsi_Host *shost = (struct Scsi_Host *)data; + struct fc_rport *rport, *next_rport; + unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); - rport->flags &= ~FC_RPORT_SCAN_PENDING; + while (fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED) { + + fc_host_flags(shost) &= ~FC_SHOST_RPORT_DEL_SCHEDULED; + +restart_search: + list_for_each_entry_safe(rport, next_rport, + &fc_host_rport_bindings(shost), peers) { + if (rport->port_state == FC_PORTSTATE_DELETED) { + rport->port_state = FC_PORTSTATE_NOTPRESENT; + spin_unlock_irqrestore(shost->host_lock, flags); + fc_rport_tgt_remove(rport); + spin_lock_irqsave(shost->host_lock, flags); + goto restart_search; + } + } + + } spin_unlock_irqrestore(shost->host_lock, flags); } diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 2730d507e..71e54a64a 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1117,9 +1117,10 @@ iscsi_register_transport(struct iscsi_transport *tt) if (priv) return NULL; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return NULL; + memset(priv, 0, sizeof(*priv)); INIT_LIST_HEAD(&priv->list); priv->iscsi_transport = tt; diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index f3b160663..210dab587 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2006 Dell Inc. + * Copyright (C) 2005 Dell Inc. * Released under GPL v2. * * Serial Attached SCSI (SAS) transport class. @@ -35,12 +35,36 @@ #include #include -#include "scsi_sas_internal.h" + +#define SAS_HOST_ATTRS 0 +#define SAS_PORT_ATTRS 17 +#define SAS_RPORT_ATTRS 5 + +struct sas_internal { + struct scsi_transport_template t; + struct sas_function_template *f; + + struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; + struct class_device_attribute private_phy_attrs[SAS_PORT_ATTRS]; + struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; + + struct transport_container phy_attr_cont; + struct transport_container rphy_attr_cont; + + /* + * The array of null terminated pointers to attributes + * needed by scsi_sysfs.c + */ + struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; + struct class_device_attribute *phy_attrs[SAS_PORT_ATTRS + 1]; + struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; +}; +#define to_sas_internal(tmpl) container_of(tmpl, struct sas_internal, t) + struct sas_host_attrs { struct list_head rphy_list; struct mutex lock; u32 next_target_id; - u32 next_expander_id; }; #define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) @@ -127,7 +151,6 @@ static struct { { SAS_SATA_SPINUP_HOLD, "Spin-up hold" }, { SAS_LINK_RATE_1_5_GBPS, "1.5 Gbit" }, { SAS_LINK_RATE_3_0_GBPS, "3.0 Gbit" }, - { SAS_LINK_RATE_6_0_GBPS, "6.0 Gbit" }, }; sas_bitfield_name_search(linkspeed, sas_linkspeed_names) @@ -145,7 +168,6 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, INIT_LIST_HEAD(&sas_host->rphy_list); mutex_init(&sas_host->lock); sas_host->next_target_id = 0; - sas_host->next_expander_id = 0; return 0; } @@ -250,7 +272,7 @@ show_sas_phy_##field(struct class_device *cdev, char *buf) \ if (!phy->local_attached) \ return -EINVAL; \ \ - error = i->f->get_linkerrors ? i->f->get_linkerrors(phy) : 0; \ + error = i->f->get_linkerrors(phy); \ if (error) \ return error; \ return snprintf(buf, 20, "%u\n", phy->field); \ @@ -369,21 +391,19 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number) struct Scsi_Host *shost = dev_to_shost(parent); struct sas_phy *phy; - phy = kzalloc(sizeof(*phy), GFP_KERNEL); + phy = kmalloc(sizeof(*phy), GFP_KERNEL); if (!phy) return NULL; + memset(phy, 0, sizeof(*phy)); + + get_device(parent); phy->number = number; device_initialize(&phy->dev); phy->dev.parent = get_device(parent); phy->dev.release = sas_phy_release; - if (scsi_is_sas_expander_device(parent)) { - struct sas_rphy *rphy = dev_to_rphy(parent); - sprintf(phy->dev.bus_id, "phy-%d-%d:%d", shost->host_no, - rphy->scsi_target_id, number); - } else - sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); + sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); transport_setup_device(&phy->dev); @@ -424,7 +444,10 @@ EXPORT_SYMBOL(sas_phy_add); void sas_phy_free(struct sas_phy *phy) { transport_destroy_device(&phy->dev); - put_device(&phy->dev); + put_device(phy->dev.parent); + put_device(phy->dev.parent); + put_device(phy->dev.parent); + kfree(phy); } EXPORT_SYMBOL(sas_phy_free); @@ -446,7 +469,7 @@ sas_phy_delete(struct sas_phy *phy) transport_remove_device(dev); device_del(dev); transport_destroy_device(dev); - put_device(dev); + put_device(dev->parent); } EXPORT_SYMBOL(sas_phy_delete); @@ -511,53 +534,6 @@ show_sas_rphy_device_type(struct class_device *cdev, char *buf) static SAS_CLASS_DEVICE_ATTR(rphy, device_type, S_IRUGO, show_sas_rphy_device_type, NULL); -static ssize_t -show_sas_rphy_enclosure_identifier(struct class_device *cdev, char *buf) -{ - struct sas_rphy *rphy = transport_class_to_rphy(cdev); - struct sas_phy *phy = dev_to_phy(rphy->dev.parent); - struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); - struct sas_internal *i = to_sas_internal(shost->transportt); - u64 identifier; - int error; - - /* - * Only devices behind an expander are supported, because the - * enclosure identifier is a SMP feature. - */ - if (phy->local_attached) - return -EINVAL; - - error = i->f->get_enclosure_identifier(rphy, &identifier); - if (error) - return error; - return sprintf(buf, "0x%llx\n", (unsigned long long)identifier); -} - -static SAS_CLASS_DEVICE_ATTR(rphy, enclosure_identifier, S_IRUGO, - show_sas_rphy_enclosure_identifier, NULL); - -static ssize_t -show_sas_rphy_bay_identifier(struct class_device *cdev, char *buf) -{ - struct sas_rphy *rphy = transport_class_to_rphy(cdev); - struct sas_phy *phy = dev_to_phy(rphy->dev.parent); - struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); - struct sas_internal *i = to_sas_internal(shost->transportt); - int val; - - if (phy->local_attached) - return -EINVAL; - - val = i->f->get_bay_identifier(rphy); - if (val < 0) - return val; - return sprintf(buf, "%d\n", val); -} - -static SAS_CLASS_DEVICE_ATTR(rphy, bay_identifier, S_IRUGO, - show_sas_rphy_bay_identifier, NULL); - sas_rphy_protocol_attr(identify.initiator_port_protocols, initiator_port_protocols); sas_rphy_protocol_attr(identify.target_port_protocols, target_port_protocols); @@ -565,103 +541,8 @@ sas_rphy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", unsigned long long); sas_rphy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); -/* only need 8 bytes of data plus header (4 or 8) */ -#define BUF_SIZE 64 - -int sas_read_port_mode_page(struct scsi_device *sdev) -{ - char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata; - struct sas_rphy *rphy = target_to_rphy(sdev->sdev_target); - struct sas_end_device *rdev; - struct scsi_mode_data mode_data; - int res, error; - - BUG_ON(rphy->identify.device_type != SAS_END_DEVICE); - - rdev = rphy_to_end_device(rphy); - - if (!buffer) - return -ENOMEM; - - res = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3, - &mode_data, NULL); - - error = -EINVAL; - if (!scsi_status_is_good(res)) - goto out; - - msdata = buffer + mode_data.header_length + - mode_data.block_descriptor_length; - - if (msdata - buffer > BUF_SIZE - 8) - goto out; - - error = 0; - - rdev->ready_led_meaning = msdata[2] & 0x10 ? 1 : 0; - rdev->I_T_nexus_loss_timeout = (msdata[4] << 8) + msdata[5]; - rdev->initiator_response_timeout = (msdata[6] << 8) + msdata[7]; - - out: - kfree(buffer); - return error; -} -EXPORT_SYMBOL(sas_read_port_mode_page); - -static DECLARE_TRANSPORT_CLASS(sas_end_dev_class, - "sas_end_device", NULL, NULL, NULL); - -#define sas_end_dev_show_simple(field, name, format_string, cast) \ -static ssize_t \ -show_sas_end_dev_##name(struct class_device *cdev, char *buf) \ -{ \ - struct sas_rphy *rphy = transport_class_to_rphy(cdev); \ - struct sas_end_device *rdev = rphy_to_end_device(rphy); \ - \ - return snprintf(buf, 20, format_string, cast rdev->field); \ -} - -#define sas_end_dev_simple_attr(field, name, format_string, type) \ - sas_end_dev_show_simple(field, name, format_string, (type)) \ -static SAS_CLASS_DEVICE_ATTR(end_dev, name, S_IRUGO, \ - show_sas_end_dev_##name, NULL) - -sas_end_dev_simple_attr(ready_led_meaning, ready_led_meaning, "%d\n", int); -sas_end_dev_simple_attr(I_T_nexus_loss_timeout, I_T_nexus_loss_timeout, - "%d\n", int); -sas_end_dev_simple_attr(initiator_response_timeout, initiator_response_timeout, - "%d\n", int); - -static DECLARE_TRANSPORT_CLASS(sas_expander_class, - "sas_expander", NULL, NULL, NULL); - -#define sas_expander_show_simple(field, name, format_string, cast) \ -static ssize_t \ -show_sas_expander_##name(struct class_device *cdev, char *buf) \ -{ \ - struct sas_rphy *rphy = transport_class_to_rphy(cdev); \ - struct sas_expander_device *edev = rphy_to_expander_device(rphy); \ - \ - return snprintf(buf, 20, format_string, cast edev->field); \ -} - -#define sas_expander_simple_attr(field, name, format_string, type) \ - sas_expander_show_simple(field, name, format_string, (type)) \ -static SAS_CLASS_DEVICE_ATTR(expander, name, S_IRUGO, \ - show_sas_expander_##name, NULL) - -sas_expander_simple_attr(vendor_id, vendor_id, "%s\n", char *); -sas_expander_simple_attr(product_id, product_id, "%s\n", char *); -sas_expander_simple_attr(product_rev, product_rev, "%s\n", char *); -sas_expander_simple_attr(component_vendor_id, component_vendor_id, - "%s\n", char *); -sas_expander_simple_attr(component_id, component_id, "%u\n", unsigned int); -sas_expander_simple_attr(component_revision_id, component_revision_id, "%u\n", - unsigned int); -sas_expander_simple_attr(level, level, "%d\n", int); - static DECLARE_TRANSPORT_CLASS(sas_rphy_class, - "sas_device", NULL, NULL, NULL); + "sas_rphy", NULL, NULL, NULL); static int sas_rphy_match(struct attribute_container *cont, struct device *dev) { @@ -682,138 +563,45 @@ static int sas_rphy_match(struct attribute_container *cont, struct device *dev) return &i->rphy_attr_cont.ac == cont; } -static int sas_end_dev_match(struct attribute_container *cont, - struct device *dev) -{ - struct Scsi_Host *shost; - struct sas_internal *i; - struct sas_rphy *rphy; - - if (!scsi_is_sas_rphy(dev)) - return 0; - shost = dev_to_shost(dev->parent->parent); - rphy = dev_to_rphy(dev); - - if (!shost->transportt) - return 0; - if (shost->transportt->host_attrs.ac.class != - &sas_host_class.class) - return 0; - - i = to_sas_internal(shost->transportt); - return &i->end_dev_attr_cont.ac == cont && - rphy->identify.device_type == SAS_END_DEVICE; -} - -static int sas_expander_match(struct attribute_container *cont, - struct device *dev) -{ - struct Scsi_Host *shost; - struct sas_internal *i; - struct sas_rphy *rphy; - - if (!scsi_is_sas_rphy(dev)) - return 0; - shost = dev_to_shost(dev->parent->parent); - rphy = dev_to_rphy(dev); - - if (!shost->transportt) - return 0; - if (shost->transportt->host_attrs.ac.class != - &sas_host_class.class) - return 0; - - i = to_sas_internal(shost->transportt); - return &i->expander_attr_cont.ac == cont && - (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE || - rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE); -} - -static void sas_expander_release(struct device *dev) +static void sas_rphy_release(struct device *dev) { struct sas_rphy *rphy = dev_to_rphy(dev); - struct sas_expander_device *edev = rphy_to_expander_device(rphy); put_device(dev->parent); - kfree(edev); -} - -static void sas_end_device_release(struct device *dev) -{ - struct sas_rphy *rphy = dev_to_rphy(dev); - struct sas_end_device *edev = rphy_to_end_device(rphy); - - put_device(dev->parent); - kfree(edev); + kfree(rphy); } /** - * sas_end_device_alloc - allocate an rphy for an end device + * sas_rphy_alloc -- allocates and initialize a SAS remote PHY structure + * @parent: SAS PHY this remote PHY is conneted to * * Allocates an SAS remote PHY structure, connected to @parent. * * Returns: * SAS PHY allocated or %NULL if the allocation failed. */ -struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent) +struct sas_rphy *sas_rphy_alloc(struct sas_phy *parent) { struct Scsi_Host *shost = dev_to_shost(&parent->dev); - struct sas_end_device *rdev; + struct sas_rphy *rphy; - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); - if (!rdev) { + rphy = kmalloc(sizeof(*rphy), GFP_KERNEL); + if (!rphy) { + put_device(&parent->dev); return NULL; } + memset(rphy, 0, sizeof(*rphy)); - device_initialize(&rdev->rphy.dev); - rdev->rphy.dev.parent = get_device(&parent->dev); - rdev->rphy.dev.release = sas_end_device_release; - sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d-%d", + device_initialize(&rphy->dev); + rphy->dev.parent = get_device(&parent->dev); + rphy->dev.release = sas_rphy_release; + sprintf(rphy->dev.bus_id, "rphy-%d:%d-%d", shost->host_no, parent->port_identifier, parent->number); - rdev->rphy.identify.device_type = SAS_END_DEVICE; - transport_setup_device(&rdev->rphy.dev); + transport_setup_device(&rphy->dev); - return &rdev->rphy; + return rphy; } -EXPORT_SYMBOL(sas_end_device_alloc); - -/** - * sas_expander_alloc - allocate an rphy for an end device - * - * Allocates an SAS remote PHY structure, connected to @parent. - * - * Returns: - * SAS PHY allocated or %NULL if the allocation failed. - */ -struct sas_rphy *sas_expander_alloc(struct sas_phy *parent, - enum sas_device_type type) -{ - struct Scsi_Host *shost = dev_to_shost(&parent->dev); - struct sas_expander_device *rdev; - struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); - - BUG_ON(type != SAS_EDGE_EXPANDER_DEVICE && - type != SAS_FANOUT_EXPANDER_DEVICE); - - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); - if (!rdev) { - return NULL; - } - - device_initialize(&rdev->rphy.dev); - rdev->rphy.dev.parent = get_device(&parent->dev); - rdev->rphy.dev.release = sas_expander_release; - mutex_lock(&sas_host->lock); - rdev->rphy.scsi_target_id = sas_host->next_expander_id++; - mutex_unlock(&sas_host->lock); - sprintf(rdev->rphy.dev.bus_id, "expander-%d:%d", - shost->host_no, rdev->rphy.scsi_target_id); - rdev->rphy.identify.device_type = type; - transport_setup_device(&rdev->rphy.dev); - - return &rdev->rphy; -} -EXPORT_SYMBOL(sas_expander_alloc); +EXPORT_SYMBOL(sas_rphy_alloc); /** * sas_rphy_add -- add a SAS remote PHY to the device hierachy @@ -845,12 +633,11 @@ int sas_rphy_add(struct sas_rphy *rphy) (identify->target_port_protocols & (SAS_PROTOCOL_SSP|SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA))) rphy->scsi_target_id = sas_host->next_target_id++; - else if (identify->device_type == SAS_END_DEVICE) + else rphy->scsi_target_id = -1; mutex_unlock(&sas_host->lock); - if (identify->device_type == SAS_END_DEVICE && - rphy->scsi_target_id != -1) { + if (rphy->scsi_target_id != -1) { scsi_scan_target(&rphy->dev, parent->port_identifier, rphy->scsi_target_id, ~0, 0); } @@ -872,7 +659,6 @@ EXPORT_SYMBOL(sas_rphy_add); */ void sas_rphy_free(struct sas_rphy *rphy) { - struct device *dev = &rphy->dev; struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); @@ -880,9 +666,11 @@ void sas_rphy_free(struct sas_rphy *rphy) list_del(&rphy->list); mutex_unlock(&sas_host->lock); - transport_destroy_device(dev); - - put_device(dev); + transport_destroy_device(&rphy->dev); + put_device(rphy->dev.parent); + put_device(rphy->dev.parent); + put_device(rphy->dev.parent); + kfree(rphy); } EXPORT_SYMBOL(sas_rphy_free); @@ -922,7 +710,7 @@ sas_rphy_delete(struct sas_rphy *rphy) parent->rphy = NULL; - put_device(dev); + put_device(&parent->dev); } EXPORT_SYMBOL(sas_rphy_delete); @@ -935,8 +723,7 @@ EXPORT_SYMBOL(sas_rphy_delete); */ int scsi_is_sas_rphy(const struct device *dev) { - return dev->release == sas_end_device_release || - dev->release == sas_expander_release; + return dev->release == sas_rphy_release; } EXPORT_SYMBOL(scsi_is_sas_rphy); @@ -955,8 +742,7 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, list_for_each_entry(rphy, &sas_host->rphy_list, list) { struct sas_phy *parent = dev_to_phy(rphy->dev.parent); - if (rphy->identify.device_type != SAS_END_DEVICE || - rphy->scsi_target_id == -1) + if (rphy->scsi_target_id == -1) continue; if ((channel == SCAN_WILD_CARD || channel == parent->port_identifier) && @@ -975,37 +761,27 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, * Setup / Teardown code */ -#define SETUP_TEMPLATE(attrb, field, perm, test) \ - i->private_##attrb[count] = class_device_attr_##field; \ - i->private_##attrb[count].attr.mode = perm; \ - i->attrb[count] = &i->private_##attrb[count]; \ - if (test) \ - count++ - - -#define SETUP_RPORT_ATTRIBUTE(field) \ - SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, 1) - -#define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \ - SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func) +#define SETUP_RPORT_ATTRIBUTE(field) \ + i->private_rphy_attrs[count] = class_device_attr_##field; \ + i->private_rphy_attrs[count].attr.mode = S_IRUGO; \ + i->private_rphy_attrs[count].store = NULL; \ + i->rphy_attrs[count] = &i->private_rphy_attrs[count]; \ + count++ #define SETUP_PORT_ATTRIBUTE(field) \ - SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1) - -#define SETUP_OPTIONAL_PORT_ATTRIBUTE(field, func) \ - SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) + i->private_phy_attrs[count] = class_device_attr_##field; \ + i->private_phy_attrs[count].attr.mode = S_IRUGO; \ + i->private_phy_attrs[count].store = NULL; \ + i->phy_attrs[count] = &i->private_phy_attrs[count]; \ + count++ #define SETUP_PORT_ATTRIBUTE_WRONLY(field) \ - SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1) - -#define SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(field, func) \ - SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func) - -#define SETUP_END_DEV_ATTRIBUTE(field) \ - SETUP_TEMPLATE(end_dev_attrs, field, S_IRUGO, 1) + i->private_phy_attrs[count] = class_device_attr_##field; \ + i->private_phy_attrs[count].attr.mode = S_IWUGO; \ + i->private_phy_attrs[count].show = NULL; \ + i->phy_attrs[count] = &i->private_phy_attrs[count]; \ + count++ -#define SETUP_EXPANDER_ATTRIBUTE(field) \ - SETUP_TEMPLATE(expander_attrs, expander_##field, S_IRUGO, 1) /** * sas_attach_transport -- instantiate SAS transport template @@ -1017,9 +793,10 @@ sas_attach_transport(struct sas_function_template *ft) struct sas_internal *i; int count; - i = kzalloc(sizeof(struct sas_internal), GFP_KERNEL); + i = kmalloc(sizeof(struct sas_internal), GFP_KERNEL); if (!i) return NULL; + memset(i, 0, sizeof(struct sas_internal)); i->t.user_scan = sas_user_scan; @@ -1039,16 +816,6 @@ sas_attach_transport(struct sas_function_template *ft) i->rphy_attr_cont.ac.match = sas_rphy_match; transport_container_register(&i->rphy_attr_cont); - i->end_dev_attr_cont.ac.class = &sas_end_dev_class.class; - i->end_dev_attr_cont.ac.attrs = &i->end_dev_attrs[0]; - i->end_dev_attr_cont.ac.match = sas_end_dev_match; - transport_container_register(&i->end_dev_attr_cont); - - i->expander_attr_cont.ac.class = &sas_expander_class.class; - i->expander_attr_cont.ac.attrs = &i->expander_attrs[0]; - i->expander_attr_cont.ac.match = sas_expander_match; - transport_container_register(&i->expander_attr_cont); - i->f = ft; count = 0; @@ -1071,8 +838,8 @@ sas_attach_transport(struct sas_function_template *ft) SETUP_PORT_ATTRIBUTE(running_disparity_error_count); SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); - SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(link_reset, phy_reset); - SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(hard_reset, phy_reset); + SETUP_PORT_ATTRIBUTE_WRONLY(link_reset); + SETUP_PORT_ATTRIBUTE_WRONLY(hard_reset); i->phy_attrs[count] = NULL; count = 0; @@ -1081,28 +848,8 @@ sas_attach_transport(struct sas_function_template *ft) SETUP_RPORT_ATTRIBUTE(rphy_device_type); SETUP_RPORT_ATTRIBUTE(rphy_sas_address); SETUP_RPORT_ATTRIBUTE(rphy_phy_identifier); - SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_enclosure_identifier, - get_enclosure_identifier); - SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_bay_identifier, - get_bay_identifier); i->rphy_attrs[count] = NULL; - count = 0; - SETUP_END_DEV_ATTRIBUTE(end_dev_ready_led_meaning); - SETUP_END_DEV_ATTRIBUTE(end_dev_I_T_nexus_loss_timeout); - SETUP_END_DEV_ATTRIBUTE(end_dev_initiator_response_timeout); - i->end_dev_attrs[count] = NULL; - - count = 0; - SETUP_EXPANDER_ATTRIBUTE(vendor_id); - SETUP_EXPANDER_ATTRIBUTE(product_id); - SETUP_EXPANDER_ATTRIBUTE(product_rev); - SETUP_EXPANDER_ATTRIBUTE(component_vendor_id); - SETUP_EXPANDER_ATTRIBUTE(component_id); - SETUP_EXPANDER_ATTRIBUTE(component_revision_id); - SETUP_EXPANDER_ATTRIBUTE(level); - i->expander_attrs[count] = NULL; - return &i->t; } EXPORT_SYMBOL(sas_attach_transport); @@ -1118,8 +865,6 @@ void sas_release_transport(struct scsi_transport_template *t) transport_container_unregister(&i->t.host_attrs); transport_container_unregister(&i->phy_attr_cont); transport_container_unregister(&i->rphy_attr_cont); - transport_container_unregister(&i->end_dev_attr_cont); - transport_container_unregister(&i->expander_attr_cont); kfree(i); } @@ -1138,19 +883,9 @@ static __init int sas_transport_init(void) error = transport_class_register(&sas_rphy_class); if (error) goto out_unregister_phy; - error = transport_class_register(&sas_end_dev_class); - if (error) - goto out_unregister_rphy; - error = transport_class_register(&sas_expander_class); - if (error) - goto out_unregister_end_dev; return 0; - out_unregister_end_dev: - transport_class_unregister(&sas_end_dev_class); - out_unregister_rphy: - transport_class_unregister(&sas_rphy_class); out_unregister_phy: transport_class_unregister(&sas_phy_class); out_unregister_transport: @@ -1165,8 +900,6 @@ static void __exit sas_transport_exit(void) transport_class_unregister(&sas_host_class); transport_class_unregister(&sas_phy_class); transport_class_unregister(&sas_rphy_class); - transport_class_unregister(&sas_end_dev_class); - transport_class_unregister(&sas_expander_class); } MODULE_AUTHOR("Christoph Hellwig"); diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 780aaedcb..7ee95eb83 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -401,7 +401,8 @@ static int period_to_str(char *buf, int period) } static ssize_t -show_spi_transport_period_helper(char *buf, int period) +show_spi_transport_period_helper(struct class_device *cdev, char *buf, + int period) { int len = period_to_str(buf, period); buf[len++] = '\n'; @@ -458,7 +459,7 @@ show_spi_transport_period(struct class_device *cdev, char *buf) if (i->f->get_period) i->f->get_period(starget); - return show_spi_transport_period_helper(buf, tp->period); + return show_spi_transport_period_helper(cdev, buf, tp->period); } static ssize_t @@ -493,7 +494,7 @@ show_spi_transport_min_period(struct class_device *cdev, char *buf) struct spi_transport_attrs *tp = (struct spi_transport_attrs *)&starget->starget_data; - return show_spi_transport_period_helper(buf, tp->min_period); + return show_spi_transport_period_helper(cdev, buf, tp->min_period); } static ssize_t @@ -899,11 +900,13 @@ spi_dv_device(struct scsi_device *sdev) if (unlikely(scsi_device_get(sdev))) return; - buffer = kzalloc(len, GFP_KERNEL); + buffer = kmalloc(len, GFP_KERNEL); if (unlikely(!buffer)) goto out_put; + memset(buffer, 0, len); + /* We need to verify that the actual device will quiesce; the * later target quiesce is just a nice to have */ if (unlikely(scsi_device_quiesce(sdev))) @@ -1051,63 +1054,25 @@ void spi_display_xfer_agreement(struct scsi_target *starget) } EXPORT_SYMBOL(spi_display_xfer_agreement); -int spi_populate_width_msg(unsigned char *msg, int width) -{ - msg[0] = EXTENDED_MESSAGE; - msg[1] = 2; - msg[2] = EXTENDED_WDTR; - msg[3] = width; - return 4; -} -EXPORT_SYMBOL_GPL(spi_populate_width_msg); - -int spi_populate_sync_msg(unsigned char *msg, int period, int offset) -{ - msg[0] = EXTENDED_MESSAGE; - msg[1] = 3; - msg[2] = EXTENDED_SDTR; - msg[3] = period; - msg[4] = offset; - return 5; -} -EXPORT_SYMBOL_GPL(spi_populate_sync_msg); - -int spi_populate_ppr_msg(unsigned char *msg, int period, int offset, - int width, int options) -{ - msg[0] = EXTENDED_MESSAGE; - msg[1] = 6; - msg[2] = EXTENDED_PPR; - msg[3] = period; - msg[4] = 0; - msg[5] = offset; - msg[6] = width; - msg[7] = options; - return 8; -} -EXPORT_SYMBOL_GPL(spi_populate_ppr_msg); - #ifdef CONFIG_SCSI_CONSTANTS static const char * const one_byte_msgs[] = { -/* 0x00 */ "Task Complete", NULL /* Extended Message */, "Save Pointers", +/* 0x00 */ "Command Complete", NULL, "Save Pointers", /* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", -/* 0x06 */ "Abort Task Set", "Message Reject", "Nop", "Message Parity Error", +/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error", /* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag", -/* 0x0c */ "Target Reset", "Abort Task", "Clear Task Set", -/* 0x0f */ "Initiate Recovery", "Release Recovery", -/* 0x11 */ "Terminate Process", "Continue Task", "Target Transfer Disable", -/* 0x14 */ NULL, NULL, "Clear ACA", "LUN Reset" +/* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", +/* 0x0f */ "Initiate Recovery", "Release Recovery" }; static const char * const two_byte_msgs[] = { /* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag", -/* 0x23 */ "Ignore Wide Residue", "ACA" +/* 0x23 */ "Ignore Wide Residue" }; static const char * const extended_msgs[] = { /* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request", /* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request", -/* 0x04 */ "Parallel Protocol Request", "Modify Bidirectional Data Pointer" +/* 0x04 */ "Parallel Protocol Request" }; static void print_nego(const unsigned char *msg, int per, int off, int width) @@ -1124,20 +1089,11 @@ static void print_nego(const unsigned char *msg, int per, int off, int width) printk("width = %d ", 8 << msg[width]); } -static void print_ptr(const unsigned char *msg, int msb, const char *desc) -{ - int ptr = (msg[msb] << 24) | (msg[msb+1] << 16) | (msg[msb+2] << 8) | - msg[msb+3]; - printk("%s = %d ", desc, ptr); -} - int spi_print_msg(const unsigned char *msg) { - int len = 1, i; + int len = 0, i; if (msg[0] == EXTENDED_MESSAGE) { - len = 2 + msg[1]; - if (len == 2) - len += 256; + len = 3 + msg[1]; if (msg[2] < ARRAY_SIZE(extended_msgs)) printk ("%s ", extended_msgs[msg[2]]); else @@ -1145,7 +1101,8 @@ int spi_print_msg(const unsigned char *msg) (int) msg[2]); switch (msg[2]) { case EXTENDED_MODIFY_DATA_POINTER: - print_ptr(msg, 3, "pointer"); + printk("pointer = %d", (int) (msg[3] << 24) | + (msg[4] << 16) | (msg[5] << 8) | msg[6]); break; case EXTENDED_SDTR: print_nego(msg, 3, 4, 0); @@ -1156,10 +1113,6 @@ int spi_print_msg(const unsigned char *msg) case EXTENDED_PPR: print_nego(msg, 3, 5, 6); break; - case EXTENDED_MODIFY_BIDI_DATA_PTR: - print_ptr(msg, 3, "out"); - print_ptr(msg, 7, "in"); - break; default: for (i = 2; i < len; ++i) printk("%02x ", msg[i]); @@ -1170,14 +1123,14 @@ int spi_print_msg(const unsigned char *msg) (msg[0] & 0x40) ? "" : "not ", (msg[0] & 0x20) ? "target routine" : "lun", msg[0] & 0x7); + len = 1; /* Normal One byte */ } else if (msg[0] < 0x1f) { - if (msg[0] < ARRAY_SIZE(one_byte_msgs) && one_byte_msgs[msg[0]]) - printk("%s ", one_byte_msgs[msg[0]]); + if (msg[0] < ARRAY_SIZE(one_byte_msgs)) + printk(one_byte_msgs[msg[0]]); else printk("reserved (%02x) ", msg[0]); - } else if (msg[0] == 0x55) { - printk("QAS Request "); + len = 1; /* Two byte */ } else if (msg[0] <= 0x2f) { if ((msg[0] - 0x20) < ARRAY_SIZE(two_byte_msgs)) @@ -1188,7 +1141,7 @@ int spi_print_msg(const unsigned char *msg) msg[0], msg[1]); len = 2; } else - printk("reserved "); + printk("reserved"); return len; } EXPORT_SYMBOL(spi_print_msg); @@ -1197,20 +1150,20 @@ EXPORT_SYMBOL(spi_print_msg); int spi_print_msg(const unsigned char *msg) { - int len = 1, i; + int len = 0, i; if (msg[0] == EXTENDED_MESSAGE) { - len = 2 + msg[1]; - if (len == 2) - len += 256; + len = 3 + msg[1]; for (i = 0; i < len; ++i) printk("%02x ", msg[i]); /* Identify */ } else if (msg[0] & 0x80) { printk("%02x ", msg[0]); + len = 1; /* Normal One byte */ - } else if ((msg[0] < 0x1f) || (msg[0] == 0x55)) { + } else if (msg[0] < 0x1f) { printk("%02x ", msg[0]); + len = 1; /* Two byte */ } else if (msg[0] <= 0x2f) { printk("%02x %02x", msg[0], msg[1]); @@ -1312,13 +1265,15 @@ static DECLARE_ANON_TRANSPORT_CLASS(spi_device_class, struct scsi_transport_template * spi_attach_transport(struct spi_function_template *ft) { - int count = 0; - struct spi_internal *i = kzalloc(sizeof(struct spi_internal), + struct spi_internal *i = kmalloc(sizeof(struct spi_internal), GFP_KERNEL); - + int count = 0; if (unlikely(!i)) return NULL; + memset(i, 0, sizeof(struct spi_internal)); + + i->t.target_attrs.ac.class = &spi_transport_class.class; i->t.target_attrs.ac.attrs = &i->attrs[0]; i->t.target_attrs.ac.match = spi_target_match; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c647d85d9..9d9872347 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -70,27 +71,6 @@ */ #define SD_MAJORS 16 -MODULE_AUTHOR("Eric Youngdale"); -MODULE_DESCRIPTION("SCSI disk (sd) driver"); -MODULE_LICENSE("GPL"); - -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK0_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK1_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK2_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK3_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK4_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK5_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK6_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK7_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK8_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK9_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK10_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK11_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK12_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR); - /* * This is limited by the naming scheme enforced in sd_probe, * add another character to it if you really need more disks. @@ -114,10 +94,12 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR); */ #define SD_BUF_SIZE 512 +static void scsi_disk_release(struct kref *kref); + struct scsi_disk { struct scsi_driver *driver; /* always &sd_template */ struct scsi_device *device; - struct class_device cdev; + struct kref kref; struct gendisk *disk; unsigned int openers; /* protected by BKL for now, yuck */ sector_t capacity; /* size in 512-byte sectors */ @@ -128,7 +110,6 @@ struct scsi_disk { unsigned RCD : 1; /* state of disk RCD bit, unused */ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ }; -#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) static DEFINE_IDR(sd_index_idr); static DEFINE_SPINLOCK(sd_index_lock); @@ -150,92 +131,6 @@ static int sd_issue_flush(struct device *, sector_t *); static void sd_prepare_flush(request_queue_t *, struct request *); static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname, unsigned char *buffer); -static void scsi_disk_release(struct class_device *cdev); - -static const char *sd_cache_types[] = { - "write through", "none", "write back", - "write back, no read (daft)" -}; - -static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, - size_t count) -{ - int i, ct = -1, rcd, wce, sp; - struct scsi_disk *sdkp = to_scsi_disk(cdev); - struct scsi_device *sdp = sdkp->device; - char buffer[64]; - char *buffer_data; - struct scsi_mode_data data; - struct scsi_sense_hdr sshdr; - int len; - - if (sdp->type != TYPE_DISK) - /* no cache control on RBC devices; theoretically they - * can do it, but there's probably so many exceptions - * it's not worth the risk */ - return -EINVAL; - - for (i = 0; i < sizeof(sd_cache_types)/sizeof(sd_cache_types[0]); i++) { - const int len = strlen(sd_cache_types[i]); - if (strncmp(sd_cache_types[i], buf, len) == 0 && - buf[len] == '\n') { - ct = i; - break; - } - } - if (ct < 0) - return -EINVAL; - rcd = ct & 0x01 ? 1 : 0; - wce = ct & 0x02 ? 1 : 0; - if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, - SD_MAX_RETRIES, &data, NULL)) - return -EINVAL; - len = min_t(size_t, sizeof(buffer), data.length - data.header_length - - data.block_descriptor_length); - buffer_data = buffer + data.header_length + - data.block_descriptor_length; - buffer_data[2] &= ~0x05; - buffer_data[2] |= wce << 2 | rcd; - sp = buffer_data[0] & 0x80 ? 1 : 0; - - if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT, - SD_MAX_RETRIES, &data, &sshdr)) { - if (scsi_sense_valid(&sshdr)) - scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr); - return -EINVAL; - } - sd_revalidate_disk(sdkp->disk); - return count; -} - -static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(cdev); - int ct = sdkp->RCD + 2*sdkp->WCE; - - return snprintf(buf, 40, "%s\n", sd_cache_types[ct]); -} - -static ssize_t sd_show_fua(struct class_device *cdev, char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(cdev); - - return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); -} - -static struct class_device_attribute sd_disk_attrs[] = { - __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, - sd_store_cache_type), - __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), - __ATTR_NULL, -}; - -static struct class sd_disk_class = { - .name = "scsi_disk", - .owner = THIS_MODULE, - .release = scsi_disk_release, - .class_dev_attrs = sd_disk_attrs, -}; static struct scsi_driver sd_template = { .owner = THIS_MODULE, @@ -279,6 +174,8 @@ static int sd_major(int major_idx) } } +#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,kref) + static inline struct scsi_disk *scsi_disk(struct gendisk *disk) { return container_of(disk->private_data, struct scsi_disk, driver); @@ -291,7 +188,7 @@ static struct scsi_disk *__scsi_disk_get(struct gendisk *disk) if (disk->private_data) { sdkp = scsi_disk(disk); if (scsi_device_get(sdkp->device) == 0) - class_device_get(&sdkp->cdev); + kref_get(&sdkp->kref); else sdkp = NULL; } @@ -325,7 +222,7 @@ static void scsi_disk_put(struct scsi_disk *sdkp) struct scsi_device *sdev = sdkp->device; mutex_lock(&sd_ref_mutex); - class_device_put(&sdkp->cdev); + kref_put(&sdkp->kref, scsi_disk_release); scsi_device_put(sdev); mutex_unlock(&sd_ref_mutex); } @@ -1436,12 +1333,6 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, if (!scsi_status_is_good(res)) goto bad_sense; - if (!data.header_length) { - modepage = 6; - printk(KERN_ERR "%s: missing header in MODE_SENSE response\n", - diskname); - } - /* that went OK, now ask for the proper length */ len = data.length; @@ -1463,6 +1354,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); if (scsi_status_is_good(res)) { + const char *types[] = { + "write through", "none", "write back", + "write back, no read (daft)" + }; int ct = 0; int offset = data.header_length + data.block_descriptor_length; @@ -1495,7 +1390,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ct = sdkp->RCD + 2*sdkp->WCE; printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n", - diskname, sd_cache_types[ct], + diskname, types[ct], sdkp->DPOFUA ? " w/ FUA" : ""); return; @@ -1622,10 +1517,13 @@ static int sd_probe(struct device *dev) "sd_attach\n")); error = -ENOMEM; - sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL); + sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL); if (!sdkp) goto out; + memset (sdkp, 0, sizeof(*sdkp)); + kref_init(&sdkp->kref); + gd = alloc_disk(16); if (!gd) goto out_free; @@ -1642,16 +1540,7 @@ static int sd_probe(struct device *dev) if (error) goto out_put; - class_device_initialize(&sdkp->cdev); - sdkp->cdev.dev = &sdp->sdev_gendev; - sdkp->cdev.class = &sd_disk_class; - strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); - - if (class_device_add(&sdkp->cdev)) - goto out_put; - get_device(&sdp->sdev_gendev); - sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd; @@ -1683,6 +1572,8 @@ static int sd_probe(struct device *dev) 'a' + m1, 'a' + m2, 'a' + m3); } + strcpy(gd->devfs_name, sdp->devfs_name); + gd->private_data = &sdkp->driver; gd->queue = sdkp->device->request_queue; @@ -1701,11 +1592,11 @@ static int sd_probe(struct device *dev) return 0; - out_put: +out_put: put_disk(gd); - out_free: +out_free: kfree(sdkp); - out: +out: return error; } @@ -1724,13 +1615,12 @@ static int sd_remove(struct device *dev) { struct scsi_disk *sdkp = dev_get_drvdata(dev); - class_device_del(&sdkp->cdev); del_gendisk(sdkp->disk); sd_shutdown(dev); mutex_lock(&sd_ref_mutex); dev_set_drvdata(dev, NULL); - class_device_put(&sdkp->cdev); + kref_put(&sdkp->kref, scsi_disk_release); mutex_unlock(&sd_ref_mutex); return 0; @@ -1738,16 +1628,16 @@ static int sd_remove(struct device *dev) /** * scsi_disk_release - Called to free the scsi_disk structure - * @cdev: pointer to embedded class device + * @kref: pointer to embedded kref * * sd_ref_mutex must be held entering this routine. Because it is * called on last put, you should always use the scsi_disk_get() * scsi_disk_put() helpers which manipulate the semaphore directly - * and never do a direct class_device_put(). + * and never do a direct kref_put(). **/ -static void scsi_disk_release(struct class_device *cdev) +static void scsi_disk_release(struct kref *kref) { - struct scsi_disk *sdkp = to_scsi_disk(cdev); + struct scsi_disk *sdkp = to_scsi_disk(kref); struct gendisk *disk = sdkp->disk; spin_lock(&sd_index_lock); @@ -1801,8 +1691,6 @@ static int __init init_sd(void) if (!majors) return -ENODEV; - class_register(&sd_disk_class); - return scsi_register_driver(&sd_template.gendrv); } @@ -1820,9 +1708,11 @@ static void __exit exit_sd(void) scsi_unregister_driver(&sd_template.gendrv); for (i = 0; i < SD_MAJORS; i++) unregister_blkdev(sd_major(i), "sd"); - - class_unregister(&sd_disk_class); } +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Eric Youngdale"); +MODULE_DESCRIPTION("SCSI disk (sd) driver"); + module_init(init_sd); module_exit(exit_sd); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index b09894244..5a0a19322 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -44,6 +44,7 @@ static int sg_version_num = 30533; /* 2 digits for each component */ #include #include #include +#include #include #include #include @@ -748,7 +749,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, /* * most likely out of mem, but could also be a bad map */ - sg_finish_rem_req(srp); return -ENOMEM; } else return 0; @@ -1045,7 +1045,7 @@ sg_ioctl(struct inode *inode, struct file *filp, if (!sg_allow_access(opcode, sdp->device->type)) return -EPERM; } - return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); + return scsi_ioctl_send_command(sdp->device, p); case SG_SET_DEBUG: result = get_user(val, ip); if (result) @@ -1140,6 +1140,32 @@ sg_fasync(int fd, struct file *filp, int mode) return (retval < 0) ? retval : 0; } +/* When startFinish==1 increments page counts for pages other than the + first of scatter gather elements obtained from alloc_pages(). + When startFinish==0 decrements ... */ +static void +sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish) +{ + struct scatterlist *sg = rsv_schp->buffer; + struct page *page; + int k, m; + + SCSI_LOG_TIMEOUT(3, printk("sg_rb_correct4mmap: startFinish=%d, scatg=%d\n", + startFinish, rsv_schp->k_use_sg)); + /* N.B. correction _not_ applied to base page of each allocation */ + for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) { + for (m = PAGE_SIZE; m < sg->length; m += PAGE_SIZE) { + page = sg->page; + if (startFinish) + get_page(page); + else { + if (page_count(page) > 0) + __put_page(page); + } + } + } +} + static struct page * sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type) { @@ -1211,7 +1237,10 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma) sa += len; } - sfp->mmap_called = 1; + if (0 == sfp->mmap_called) { + sg_rb_correct4mmap(rsv_schp, 1); /* do only once per fd lifetime */ + sfp->mmap_called = 1; + } vma->vm_flags |= VM_RESERVED; vma->vm_private_data = sfp; vma->vm_ops = &sg_mmap_vm_ops; @@ -1332,7 +1361,7 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) void *old_sg_dev_arr = NULL; int k, error; - sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL); + sdp = kmalloc(sizeof(Sg_device), GFP_KERNEL); if (!sdp) { printk(KERN_WARNING "kmalloc Sg_device failure\n"); return -ENOMEM; @@ -1344,11 +1373,12 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP; write_unlock_irqrestore(&sg_dev_arr_lock, iflags); - tmp_da = kzalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL); + tmp_da = kmalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL); if (unlikely(!tmp_da)) goto expand_failed; write_lock_irqsave(&sg_dev_arr_lock, iflags); + memset(tmp_da, 0, tmp_dev_max * sizeof(Sg_device *)); memcpy(tmp_da, sg_dev_arr, sg_dev_max * sizeof(Sg_device *)); old_sg_dev_arr = sg_dev_arr; sg_dev_arr = tmp_da; @@ -1361,6 +1391,7 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) if (unlikely(k >= SG_MAX_DEVS)) goto overflow; + memset(sdp, 0, sizeof(*sdp)); SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k)); sprintf(disk->disk_name, "sg%d", k); disk->first_minor = k; @@ -1427,10 +1458,14 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) k = error; sdp = sg_dev_arr[k]; + devfs_mk_cdev(MKDEV(SCSI_GENERIC_MAJOR, k), + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, + "%s/generic", scsidp->devfs_name); error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); - if (error) + if (error) { + devfs_remove("%s/generic", scsidp->devfs_name); goto out; - + } sdp->cdev = cdev; if (sg_sysfs_valid) { struct class_device * sg_class_member; @@ -1520,6 +1555,7 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k)); cdev_del(sdp->cdev); sdp->cdev = NULL; + devfs_remove("%s/generic", scsidp->devfs_name); put_disk(sdp->disk); sdp->disk = NULL; if (NULL == sdp->headfp) @@ -1541,7 +1577,6 @@ MODULE_AUTHOR("Douglas Gilbert"); MODULE_DESCRIPTION("SCSI generic (sg) driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(SG_VERSION_STR); -MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR); MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd"); MODULE_PARM_DESC(allow_dio, "allow direct I/O (default: 0 (disallow))"); @@ -1799,10 +1834,8 @@ sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len) res = st_map_user_pages(schp->buffer, mx_sc_elems, (unsigned long)hp->dxferp, dxfer_len, (SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0); - if (res <= 0) { - sg_remove_scat(schp); + if (res <= 0) return 1; - } schp->k_use_sg = res; schp->dio_in_use = 1; hp->info |= SG_INFO_DIRECT_IO; @@ -2362,6 +2395,8 @@ __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp: bufflen=%d, k_use_sg=%d\n", (int) sfp->reserve.bufflen, (int) sfp->reserve.k_use_sg)); + if (sfp->mmap_called) + sg_rb_correct4mmap(&sfp->reserve, 0); /* undo correction */ sg_remove_scat(&sfp->reserve); } sfp->parentdp = NULL; @@ -2443,9 +2478,9 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp) return resp; if (lowDma) - page_mask = GFP_ATOMIC | GFP_DMA | __GFP_COMP | __GFP_NOWARN; + page_mask = GFP_ATOMIC | GFP_DMA | __GFP_NOWARN; else - page_mask = GFP_ATOMIC | __GFP_COMP | __GFP_NOWARN; + page_mask = GFP_ATOMIC | __GFP_NOWARN; for (order = 0, a_size = PAGE_SIZE; a_size < rqSz; order++, a_size <<= 1) ; @@ -2939,3 +2974,4 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v) module_init(init_sg); module_exit(exit_sg); +MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR); diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index 7cd366fcc..bf2ceb543 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -265,7 +265,7 @@ out_unregister: return NULL; } -static int __init sgiwd93_detect(struct scsi_host_template *SGIblows) +int __init sgiwd93_detect(struct scsi_host_template *SGIblows) { int found = 0; @@ -288,7 +288,7 @@ static int __init sgiwd93_detect(struct scsi_host_template *SGIblows) return found; } -static int sgiwd93_release(struct Scsi_Host *instance) +int sgiwd93_release(struct Scsi_Host *instance) { struct ip22_hostdata *hdata = HDATA(instance); int irq = 0; diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 255886a9a..917178834 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -75,7 +75,7 @@ param_setup(char *str) else if(!strncmp(pos, "id:", 3)) { if(slot == -1) { printk(KERN_WARNING "sim710: Must specify slot for id parameter\n"); - } else if(slot >= MAX_SLOTS) { + } else if(slot > MAX_SLOTS) { printk(KERN_WARNING "sim710: Illegal slot %d for id %d\n", slot, val); } else { id_array[slot] = val; @@ -146,7 +146,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, out_put_host: scsi_host_put(host); out_release: - release_region(base_addr, 64); + release_region(host->base, 64); out_free: kfree(hostdata); out: diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 7c80711e1..997f8e305 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -60,10 +60,6 @@ #include "sr.h" -MODULE_DESCRIPTION("SCSI cdrom (sr) driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR); - #define SR_DISKS 256 #define MAX_RETRIES 3 @@ -71,7 +67,7 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR); #define SR_CAPABILITIES \ (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \ CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \ - CDC_PLAY_AUDIO|CDC_RESET|CDC_DRIVE_STATUS| \ + CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \ CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \ CDC_MRW|CDC_MRW_W|CDC_RAM) @@ -118,6 +114,7 @@ static struct cdrom_device_ops sr_dops = { .get_mcn = sr_get_mcn, .reset = sr_reset, .audio_ioctl = sr_audio_ioctl, + .dev_ioctl = sr_dev_ioctl, .capability = SR_CAPABILITIES, .generic_packet = sr_packet, }; @@ -455,33 +452,17 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, { struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk); struct scsi_device *sdev = cd->device; - void __user *argp = (void __user *)arg; - int ret; - /* - * Send SCSI addressing ioctls directly to mid level, send other - * ioctls to cdrom/block level. - */ - switch (cmd) { - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: - return scsi_ioctl(sdev, cmd, argp); + /* + * Send SCSI addressing ioctls directly to mid level, send other + * ioctls to cdrom/block level. + */ + switch (cmd) { + case SCSI_IOCTL_GET_IDLUN: + case SCSI_IOCTL_GET_BUS_NUMBER: + return scsi_ioctl(sdev, cmd, (void __user *)arg); } - - ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg); - if (ret != ENOSYS) - return ret; - - /* - * ENODEV means that we didn't recognise the ioctl, or that we - * cannot execute it in the current device state. In either - * case fall through to scsi_ioctl, which will return ENDOEV again - * if it doesn't recognise the ioctl - */ - ret = scsi_nonblockable_ioctl(sdev, cmd, argp, NULL); - if (ret != -ENODEV) - return ret; - return scsi_ioctl(sdev, cmd, argp); + return cdrom_ioctl(file, &cd->cdi, inode, cmd, arg); } static int sr_block_media_changed(struct gendisk *disk) @@ -544,9 +525,10 @@ static int sr_probe(struct device *dev) goto fail; error = -ENOMEM; - cd = kzalloc(sizeof(*cd), GFP_KERNEL); + cd = kmalloc(sizeof(*cd), GFP_KERNEL); if (!cd) goto fail; + memset(cd, 0, sizeof(*cd)); kref_init(&cd->kref); @@ -592,6 +574,8 @@ static int sr_probe(struct device *dev) get_capabilities(cd); sr_vendor_init(cd); + snprintf(disk->devfs_name, sizeof(disk->devfs_name), + "%s/cd", sdev->devfs_name); disk->driverfs_dev = &sdev->sdev_gendev; set_capacity(disk, cd->capacity); disk->private_data = &cd->driver; diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h index d65de9621..d2bcd99c2 100644 --- a/drivers/scsi/sr.h +++ b/drivers/scsi/sr.h @@ -55,6 +55,7 @@ int sr_get_mcn(struct cdrom_device_info *, struct cdrom_mcn *); int sr_reset(struct cdrom_device_info *); int sr_select_speed(struct cdrom_device_info *cdi, int speed); int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); +int sr_dev_ioctl(struct cdrom_device_info *, unsigned int, unsigned long); int sr_is_xa(Scsi_CD *); diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index d1268cb46..b65462f76 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -562,3 +562,22 @@ int sr_is_xa(Scsi_CD *cd) #endif return is_xa; } + +int sr_dev_ioctl(struct cdrom_device_info *cdi, + unsigned int cmd, unsigned long arg) +{ + Scsi_CD *cd = cdi->handle; + int ret; + + ret = scsi_nonblockable_ioctl(cd->device, cmd, + (void __user *)arg, NULL); + /* + * ENODEV means that we didn't recognise the ioctl, or that we + * cannot execute it in the current device state. In either + * case fall through to scsi_ioctl, which will return ENDOEV again + * if it doesn't recognise the ioctl + */ + if (ret != -ENODEV) + return ret; + return scsi_ioctl(cd->device, cmd, (void __user *)arg); +} diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 56cb49006..7f96f33c1 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -35,6 +35,7 @@ static const char *verstr = "20050830"; #include #include #include +#include #include #include #include @@ -86,9 +87,8 @@ static int st_nr_dev; static struct class *st_sysfs_class; MODULE_AUTHOR("Kai Makisara"); -MODULE_DESCRIPTION("SCSI tape (st) driver"); +MODULE_DESCRIPTION("SCSI Tape Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR); /* Set 'perm' (4th argument) to 0 to disable module_param's definition * of sysfs parameters (which module_param doesn't yet support). @@ -3590,11 +3590,12 @@ static struct st_buffer * i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) + max_sg * sizeof(struct st_buf_fragment); - tb = kzalloc(i, priority); + tb = kmalloc(i, priority); if (!tb) { printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n"); return NULL; } + memset(tb, 0, i); tb->frp_segs = tb->orig_frp_segs = 0; tb->use_sg = max_sg; tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); @@ -3923,13 +3924,14 @@ static int st_probe(struct device *dev) goto out_put_disk; } - tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC); + tmp_da = kmalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC); if (tmp_da == NULL) { write_unlock(&st_dev_arr_lock); printk(KERN_ERR "st: Can't extend device array.\n"); goto out_put_disk; } + memset(tmp_da, 0, tmp_dev_max * sizeof(struct scsi_tape *)); if (scsi_tapes != NULL) { memcpy(tmp_da, scsi_tapes, st_dev_max * sizeof(struct scsi_tape *)); @@ -3946,12 +3948,13 @@ static int st_probe(struct device *dev) if (i >= st_dev_max) panic("scsi_devices corrupt (st)"); - tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC); + tpnt = kmalloc(sizeof(struct scsi_tape), GFP_ATOMIC); if (tpnt == NULL) { write_unlock(&st_dev_arr_lock); printk(KERN_ERR "st: Can't allocate device descriptor.\n"); goto out_put_disk; } + memset(tpnt, 0, sizeof(struct scsi_tape)); kref_init(&tpnt->kref); tpnt->disk = disk; sprintf(disk->disk_name, "st%d", i); @@ -4053,8 +4056,23 @@ static int st_probe(struct device *dev) do_create_class_files(tpnt, dev_num, mode); } + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + /* Make sure that the minor numbers corresponding to the four + first modes always get the same names */ + i = mode << (4 - ST_NBR_MODE_BITS); + /* Rewind entry */ + devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 0)), + S_IFCHR | S_IRUGO | S_IWUGO, + "%s/mt%s", SDp->devfs_name, st_formats[i]); + /* No-rewind entry */ + devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 1)), + S_IFCHR | S_IRUGO | S_IWUGO, + "%s/mt%sn", SDp->devfs_name, st_formats[i]); + } + disk->number = devfs_register_tape(SDp->devfs_name); + sdev_printk(KERN_WARNING, SDp, - "Attached scsi tape %s\n", tape_name(tpnt)); + "Attached scsi tape %s", tape_name(tpnt)); printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n", tape_name(tpnt), tpnt->try_dio ? "yes" : "no", queue_dma_alignment(SDp->request_queue) + 1); @@ -4106,9 +4124,13 @@ static int st_remove(struct device *dev) scsi_tapes[i] = NULL; st_nr_dev--; write_unlock(&st_dev_arr_lock); + devfs_unregister_tape(tpnt->disk->number); sysfs_remove_link(&tpnt->device->sdev_gendev.kobj, "tape"); for (mode = 0; mode < ST_NBR_MODES; ++mode) { + j = mode << (4 - ST_NBR_MODE_BITS); + devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]); + devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]); for (j=0; j < 2; j++) { class_device_destroy(st_sysfs_class, MKDEV(SCSI_TAPE_MAJOR, diff --git a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h index defccc477..3659dd7b9 100644 --- a/drivers/scsi/sym53c8xx_2/sym_defs.h +++ b/drivers/scsi/sym53c8xx_2/sym_defs.h @@ -40,7 +40,7 @@ #ifndef SYM_DEFS_H #define SYM_DEFS_H -#define SYM_VERSION "2.2.3" +#define SYM_VERSION "2.2.2" #define SYM_DRIVER_NAME "sym-" SYM_VERSION /* diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 9c83b4d39..1fffd2b3c 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -134,17 +134,66 @@ static void sym2_setup_params(void) } } +/* + * We used to try to deal with 64-bit BARs here, but don't any more. + * There are many parts of this driver which would need to be modified + * to handle a 64-bit base address, including scripts. I'm uncomfortable + * with making those changes when I have no way of testing it, so I'm + * just going to disable it. + * + * Note that some machines (eg HP rx8620 and Superdome) have bus addresses + * below 4GB and physical addresses above 4GB. These will continue to work. + */ +static int __devinit +pci_get_base_address(struct pci_dev *pdev, int index, unsigned long *basep) +{ + u32 tmp; + unsigned long base; +#define PCI_BAR_OFFSET(index) (PCI_BASE_ADDRESS_0 + (index<<2)) + + pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp); + base = tmp; + if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) { + pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp); + if (tmp > 0) { + dev_err(&pdev->dev, + "BAR %d is 64-bit, disabling\n", index - 1); + base = 0; + } + } + + if ((base & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { + base &= PCI_BASE_ADDRESS_IO_MASK; + } else { + base &= PCI_BASE_ADDRESS_MEM_MASK; + } + + *basep = base; + return index; +#undef PCI_BAR_OFFSET +} + static struct scsi_transport_template *sym2_transport_template = NULL; +/* + * Used by the eh thread to wait for command completion. + * It is allocated on the eh thread stack. + */ +struct sym_eh_wait { + struct completion done; + struct timer_list timer; + void (*old_done)(struct scsi_cmnd *); + int to_do; + int timed_out; +}; + /* * Driver private area in the SCSI command structure. */ struct sym_ucmd { /* Override the SCSI pointer structure */ - dma_addr_t data_mapping; - unsigned char data_mapped; - unsigned char to_do; /* For error handling */ - void (*old_done)(struct scsi_cmnd *); /* For error handling */ - struct completion *eh_done; /* For error handling */ + dma_addr_t data_mapping; + u_char data_mapped; + struct sym_eh_wait *eh_wait; }; #define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp)) @@ -465,6 +514,8 @@ static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struc */ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) { + struct sym_tcb *tp = &np->target[cp->target]; + struct sym_lcb *lp = sym_lp(tp, cp->lun); u32 lastp, goalp; int dir; @@ -545,7 +596,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s /* * activate this job. */ - sym_put_start_queue(np, cp); + sym_start_next_ccbs(np, lp, 2); return 0; out_abort: @@ -700,22 +751,44 @@ static void sym53c8xx_timer(unsigned long npref) * What we will do regarding the involved SCSI command. */ #define SYM_EH_DO_IGNORE 0 +#define SYM_EH_DO_COMPLETE 1 #define SYM_EH_DO_WAIT 2 /* - * scsi_done() alias when error recovery is in progress. + * Our general completion handler. */ -static void sym_eh_done(struct scsi_cmnd *cmd) +static void __sym_eh_done(struct scsi_cmnd *cmd, int timed_out) { - struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); - BUILD_BUG_ON(sizeof(struct scsi_pointer) < sizeof(struct sym_ucmd)); + struct sym_eh_wait *ep = SYM_UCMD_PTR(cmd)->eh_wait; + if (!ep) + return; + + /* Try to avoid a race here (not 100% safe) */ + if (!timed_out) { + ep->timed_out = 0; + if (ep->to_do == SYM_EH_DO_WAIT && !del_timer(&ep->timer)) + return; + } - cmd->scsi_done = ucmd->old_done; + /* Revert everything */ + SYM_UCMD_PTR(cmd)->eh_wait = NULL; + cmd->scsi_done = ep->old_done; - if (ucmd->to_do == SYM_EH_DO_WAIT) - complete(ucmd->eh_done); + /* Wake up the eh thread if it wants to sleep */ + if (ep->to_do == SYM_EH_DO_WAIT) + complete(&ep->done); } +/* + * scsi_done() alias when error recovery is in progress. + */ +static void sym_eh_done(struct scsi_cmnd *cmd) { __sym_eh_done(cmd, 0); } + +/* + * Some timeout handler to avoid waiting too long. + */ +static void sym_eh_timeout(u_long p) { __sym_eh_done((struct scsi_cmnd *)p, 1); } + /* * Generic method for our eh processing. * The 'op' argument tells what we have to do. @@ -723,31 +796,35 @@ static void sym_eh_done(struct scsi_cmnd *cmd) static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) { struct sym_hcb *np = SYM_SOFTC_PTR(cmd); - struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); - struct Scsi_Host *host = cmd->device->host; SYM_QUEHEAD *qp; int to_do = SYM_EH_DO_IGNORE; int sts = -1; - struct completion eh_done; + struct sym_eh_wait eh, *ep = &eh; dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname); - spin_lock_irq(host->host_lock); /* This one is queued in some place -> to wait for completion */ FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); if (cp->cmd == cmd) { to_do = SYM_EH_DO_WAIT; - break; + goto prepare; } } - if (to_do == SYM_EH_DO_WAIT) { - init_completion(&eh_done); - ucmd->old_done = cmd->scsi_done; - ucmd->eh_done = &eh_done; - wmb(); +prepare: + /* Prepare stuff to either ignore, complete or wait for completion */ + switch(to_do) { + default: + case SYM_EH_DO_IGNORE: + break; + case SYM_EH_DO_WAIT: + init_completion(&ep->done); + /* fall through */ + case SYM_EH_DO_COMPLETE: + ep->old_done = cmd->scsi_done; cmd->scsi_done = sym_eh_done; + SYM_UCMD_PTR(cmd)->eh_wait = ep; } /* Try to proceed the operation we have been asked for */ @@ -774,19 +851,29 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) /* On error, restore everything and cross fingers :) */ if (sts) { - cmd->scsi_done = ucmd->old_done; + SYM_UCMD_PTR(cmd)->eh_wait = NULL; + cmd->scsi_done = ep->old_done; to_do = SYM_EH_DO_IGNORE; } - ucmd->to_do = to_do; - spin_unlock_irq(host->host_lock); + ep->to_do = to_do; + /* Complete the command with locks held as required by the driver */ + if (to_do == SYM_EH_DO_COMPLETE) + sym_xpt_done2(np, cmd, DID_ABORT); + /* Wait for completion with locks released, as required by kernel */ if (to_do == SYM_EH_DO_WAIT) { - if (!wait_for_completion_timeout(&eh_done, 5*HZ)) { - ucmd->to_do = SYM_EH_DO_IGNORE; - wmb(); + init_timer(&ep->timer); + ep->timer.expires = jiffies + (5*HZ); + ep->timer.function = sym_eh_timeout; + ep->timer.data = (u_long)cmd; + ep->timed_out = 1; /* Be pessimistic for once :) */ + add_timer(&ep->timer); + spin_unlock_irq(np->s.host->host_lock); + wait_for_completion(&ep->done); + spin_lock_irq(np->s.host->host_lock); + if (ep->timed_out) sts = -2; - } } dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname, sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed"); @@ -799,22 +886,46 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) */ static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd) { - return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd); + int rc; + + spin_lock_irq(cmd->device->host->host_lock); + rc = sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd); + spin_unlock_irq(cmd->device->host->host_lock); + + return rc; } static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd) { - return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd); + int rc; + + spin_lock_irq(cmd->device->host->host_lock); + rc = sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd); + spin_unlock_irq(cmd->device->host->host_lock); + + return rc; } static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd) { - return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd); + int rc; + + spin_lock_irq(cmd->device->host->host_lock); + rc = sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd); + spin_unlock_irq(cmd->device->host->host_lock); + + return rc; } static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd) { - return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); + int rc; + + spin_lock_irq(cmd->device->host->host_lock); + rc = sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); + spin_unlock_irq(cmd->device->host->host_lock); + + return rc; } /* @@ -833,12 +944,15 @@ static void sym_tune_dev_queuing(struct sym_tcb *tp, int lun, u_short reqtags) if (reqtags > lp->s.scdev_depth) reqtags = lp->s.scdev_depth; + lp->started_limit = reqtags ? reqtags : 2; + lp->started_max = 1; lp->s.reqtags = reqtags; if (reqtags != oldtags) { dev_info(&tp->starget->dev, "tagged command queuing %s, command queue depth %d.\n", - lp->s.reqtags ? "enabled" : "disabled", reqtags); + lp->s.reqtags ? "enabled" : "disabled", + lp->started_limit); } } @@ -1752,25 +1866,15 @@ static int __devinit sym_set_workarounds(struct sym_device *device) static void __devinit sym_init_device(struct pci_dev *pdev, struct sym_device *device) { - int i = 2; - struct pci_bus_region bus_addr; + int i; device->host_id = SYM_SETUP_HOST_ID; device->pdev = pdev; - pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); - device->mmio_base = bus_addr.start; - - /* - * If the BAR is 64-bit, resource 2 will be occupied by the - * upper 32 bits - */ - if (!pdev->resource[i].flags) - i++; - pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); - device->ram_base = bus_addr.start; + i = pci_get_base_address(pdev, 1, &device->mmio_base); + pci_get_base_address(pdev, i, &device->ram_base); -#ifdef CONFIG_SCSI_SYM53C8XX_MMIO +#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED if (device->mmio_base) device->s.ioaddr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1)); @@ -1874,8 +1978,7 @@ static struct scsi_host_template sym2_template = { .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler, .eh_host_reset_handler = sym53c8xx_eh_host_reset_handler, .this_id = 7, - .use_clustering = ENABLE_CLUSTERING, - .max_sectors = 0xFFFF, + .use_clustering = DISABLE_CLUSTERING, #ifdef SYM_LINUX_PROC_INFO_SUPPORT .proc_info = sym53c8xx_proc_info, .proc_name = NAME53C8XX, diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h index a446cda3f..cc92d0c70 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.h +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h @@ -68,7 +68,7 @@ */ #define SYM_CONF_TIMER_INTERVAL ((HZ+1)/2) -#undef SYM_OPT_HANDLE_DEVICE_QUEUEING +#define SYM_OPT_HANDLE_DEVICE_QUEUEING #define SYM_OPT_LIMIT_COMMAND_REORDERING /* diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index a671bdc07..2627000ca 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -40,6 +40,7 @@ #include #include /* for timeouts in units of HZ */ +#include #include "sym_glue.h" #include "sym_nvram.h" @@ -72,10 +73,7 @@ static void sym_printl_hex(u_char *p, int n) static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg) { - if (label) - sym_print_addr(cp->cmd, "%s: ", label); - else - sym_print_addr(cp->cmd, ""); + sym_print_addr(cp->cmd, "%s: ", label); spi_print_msg(msg); printf("\n"); @@ -475,7 +473,7 @@ static int sym_getpciclock (struct sym_hcb *np) * calculations more simple. */ #define _5M 5000000 -static const u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M}; +static u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M}; /* * Get clock factor and sync divisor for a given @@ -647,37 +645,6 @@ static void sym_save_initial_setting (struct sym_hcb *np) np->sv_ctest5 = INB(np, nc_ctest5) & 0x24; } -/* - * Set SCSI BUS mode. - * - LVD capable chips (895/895A/896/1010) report the current BUS mode - * through the STEST4 IO register. - * - For previous generation chips (825/825A/875), the user has to tell us - * how to check against HVD, since a 100% safe algorithm is not possible. - */ -static void sym_set_bus_mode(struct sym_hcb *np, struct sym_nvram *nvram) -{ - if (np->scsi_mode) - return; - - np->scsi_mode = SMODE_SE; - if (np->features & (FE_ULTRA2|FE_ULTRA3)) - np->scsi_mode = (np->sv_stest4 & SMODE); - else if (np->features & FE_DIFF) { - if (SYM_SETUP_SCSI_DIFF == 1) { - if (np->sv_scntl3) { - if (np->sv_stest2 & 0x20) - np->scsi_mode = SMODE_HVD; - } else if (nvram->type == SYM_SYMBIOS_NVRAM) { - if (!(INB(np, nc_gpreg) & 0x08)) - np->scsi_mode = SMODE_HVD; - } - } else if (SYM_SETUP_SCSI_DIFF == 2) - np->scsi_mode = SMODE_HVD; - } - if (np->scsi_mode == SMODE_HVD) - np->rv_stest2 |= 0x20; -} - /* * Prepare io register values used by sym_start_up() * according to selected and supported features. @@ -688,7 +655,10 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru u32 period; int i; - np->maxwide = (np->features & FE_WIDE) ? 1 : 0; + /* + * Wide ? + */ + np->maxwide = (np->features & FE_WIDE)? 1 : 0; /* * Guess the frequency of the chip's clock. @@ -869,7 +839,6 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru * Get parity checking, host ID and verbose mode from NVRAM */ np->myaddr = 255; - np->scsi_mode = 0; sym_nvram_setup_host(shost, np, nvram); /* @@ -886,7 +855,33 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru */ sym_init_burst(np, burst_max); - sym_set_bus_mode(np, nvram); + /* + * Set SCSI BUS mode. + * - LVD capable chips (895/895A/896/1010) report the + * current BUS mode through the STEST4 IO register. + * - For previous generation chips (825/825A/875), + * user has to tell us how to check against HVD, + * since a 100% safe algorithm is not possible. + */ + np->scsi_mode = SMODE_SE; + if (np->features & (FE_ULTRA2|FE_ULTRA3)) + np->scsi_mode = (np->sv_stest4 & SMODE); + else if (np->features & FE_DIFF) { + if (SYM_SETUP_SCSI_DIFF == 1) { + if (np->sv_scntl3) { + if (np->sv_stest2 & 0x20) + np->scsi_mode = SMODE_HVD; + } + else if (nvram->type == SYM_SYMBIOS_NVRAM) { + if (!(INB(np, nc_gpreg) & 0x08)) + np->scsi_mode = SMODE_HVD; + } + } + else if (SYM_SETUP_SCSI_DIFF == 2) + np->scsi_mode = SMODE_HVD; + } + if (np->scsi_mode == SMODE_HVD) + np->rv_stest2 |= 0x20; /* * Set LED support from SCRIPTS. @@ -979,8 +974,8 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru * * Has to be called with interrupts disabled. */ -#ifdef CONFIG_SCSI_SYM53C8XX_MMIO -static int sym_regtest(struct sym_hcb *np) +#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED +static int sym_regtest (struct sym_hcb *np) { register volatile u32 data; /* @@ -998,25 +993,20 @@ static int sym_regtest(struct sym_hcb *np) #endif printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n", (unsigned) data); - return 0x10; + return (0x10); } - return 0; -} -#else -static inline int sym_regtest(struct sym_hcb *np) -{ - return 0; + return (0); } #endif -static int sym_snooptest(struct sym_hcb *np) +static int sym_snooptest (struct sym_hcb *np) { - u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat; - int i, err; - - err = sym_regtest(np); - if (err) - return err; + u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat; + int i, err=0; +#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED + err |= sym_regtest (np); + if (err) return (err); +#endif restart_test: /* * Enable Master Parity Checking as we intend @@ -1105,7 +1095,7 @@ restart_test: err |= 4; } - return err; + return (err); } /* @@ -1442,18 +1432,29 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp switch (nego) { case NS_SYNC: - msglen += spi_populate_sync_msg(msgptr + msglen, goal->period, - goal->offset); + msgptr[msglen++] = M_EXTENDED; + msgptr[msglen++] = 3; + msgptr[msglen++] = M_X_SYNC_REQ; + msgptr[msglen++] = goal->period; + msgptr[msglen++] = goal->offset; break; case NS_WIDE: - msglen += spi_populate_width_msg(msgptr + msglen, goal->width); + msgptr[msglen++] = M_EXTENDED; + msgptr[msglen++] = 2; + msgptr[msglen++] = M_X_WIDE_REQ; + msgptr[msglen++] = goal->width; break; case NS_PPR: - msglen += spi_populate_ppr_msg(msgptr + msglen, goal->period, - goal->offset, goal->width, - (goal->iu ? PPR_OPT_IU : 0) | + msgptr[msglen++] = M_EXTENDED; + msgptr[msglen++] = 6; + msgptr[msglen++] = M_X_PPR_REQ; + msgptr[msglen++] = goal->period; + msgptr[msglen++] = 0; + msgptr[msglen++] = goal->offset; + msgptr[msglen++] = goal->width; + msgptr[msglen++] = (goal->iu ? PPR_OPT_IU : 0) | (goal->dt ? PPR_OPT_DT : 0) | - (goal->qas ? PPR_OPT_QAS : 0)); + (goal->qas ? PPR_OPT_QAS : 0); break; } @@ -1475,7 +1476,7 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp /* * Insert a job into the start queue. */ -void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp) +static void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp) { u_short qidx; @@ -3949,7 +3950,11 @@ sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp) /* * It was a request. Prepare an answer message. */ - spi_populate_sync_msg(np->msgout, per, ofs); + np->msgout[0] = M_EXTENDED; + np->msgout[1] = 3; + np->msgout[2] = M_X_SYNC_REQ; + np->msgout[3] = per; + np->msgout[4] = ofs; if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, target, "sync msgout", np->msgout); @@ -4075,7 +4080,14 @@ sym_ppr_nego_check(struct sym_hcb *np, int req, int target) /* * It was a request. Prepare an answer message. */ - spi_populate_ppr_msg(np->msgout, per, ofs, wide, opts); + np->msgout[0] = M_EXTENDED; + np->msgout[1] = 6; + np->msgout[2] = M_X_PPR_REQ; + np->msgout[3] = per; + np->msgout[4] = 0; + np->msgout[5] = ofs; + np->msgout[6] = wide; + np->msgout[7] = opts; if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, target, "ppr msgout", np->msgout); @@ -4187,7 +4199,10 @@ sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp) /* * It was a request. Prepare an answer message. */ - spi_populate_width_msg(np->msgout, wide); + np->msgout[0] = M_EXTENDED; + np->msgout[1] = 2; + np->msgout[2] = M_X_WIDE_REQ; + np->msgout[3] = wide; np->msgin [0] = M_NOOP; @@ -4232,8 +4247,11 @@ static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb * a single SCSI command (Suggested by Justin Gibbs). */ if (tp->tgoal.offset) { - spi_populate_sync_msg(np->msgout, tp->tgoal.period, - tp->tgoal.offset); + np->msgout[0] = M_EXTENDED; + np->msgout[1] = 3; + np->msgout[2] = M_X_SYNC_REQ; + np->msgout[3] = tp->tgoal.period; + np->msgout[4] = tp->tgoal.offset; if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, cp->target, @@ -4492,7 +4510,7 @@ static void sym_int_sir (struct sym_hcb *np) switch (np->msgin [2]) { case M_X_MODIFY_DP: if (DEBUG_FLAGS & DEBUG_POINTER) - sym_print_msg(cp, NULL, np->msgin); + sym_print_msg(cp,"modify DP",np->msgin); tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) + (np->msgin[5]<<8) + (np->msgin[6]); sym_modify_dp(np, tp, cp, tmp); @@ -4519,7 +4537,7 @@ static void sym_int_sir (struct sym_hcb *np) */ case M_IGN_RESIDUE: if (DEBUG_FLAGS & DEBUG_POINTER) - sym_print_msg(cp, NULL, np->msgin); + sym_print_msg(cp,"ign wide residue", np->msgin); if (cp->host_flags & HF_SENSE) OUTL_DSP(np, SCRIPTA_BA(np, clrack)); else @@ -4608,8 +4626,7 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t * Debugging purpose. */ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING - if (lp->busy_itl != 0) - goto out_free; + assert(lp->busy_itl == 0); #endif /* * Allocate resources for tags if not yet. @@ -4654,8 +4671,7 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t * Debugging purpose. */ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING - if (lp->busy_itl != 0 || lp->busy_itlq != 0) - goto out_free; + assert(lp->busy_itl == 0 && lp->busy_itlq == 0); #endif /* * Count this nexus for this LUN. diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h index 79ab6a177..2456090bb 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.h +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h @@ -1049,8 +1049,6 @@ int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int); struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision); #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn); -#else -void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); #endif void sym_start_up(struct sym_hcb *np, int reason); void sym_interrupt(struct sym_hcb *np); diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index d8a72609a..fb53eeaee 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -78,8 +78,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c index a6cfbb3b3..b131432c6 100644 --- a/drivers/scsi/zalon.c +++ b/drivers/scsi/zalon.c @@ -88,7 +88,7 @@ zalon_probe(struct parisc_device *dev) struct gsc_irq gsc_irq; u32 zalon_vers; int error = -ENODEV; - void __iomem *zalon = ioremap_nocache(dev->hpa.start, 4096); + void __iomem *zalon = ioremap(dev->hpa.start, 4096); void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET; static int unit = 0; struct Scsi_Host *host; diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 7572665a8..8c5c276c5 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c @@ -375,18 +375,23 @@ static void serial21285_setup_ports(void) } #ifdef CONFIG_SERIAL_21285_CONSOLE -static void serial21285_console_putchar(struct uart_port *port, int ch) -{ - while (*CSR_UARTFLG & 0x20) - barrier(); - *CSR_UARTDR = ch; -} static void serial21285_console_write(struct console *co, const char *s, unsigned int count) { - uart_console_write(&serial21285_port, s, count, serial21285_console_putchar); + int i; + + for (i = 0; i < count; i++) { + while (*CSR_UARTFLG & 0x20) + barrier(); + *CSR_UARTDR = s[i]; + if (s[i] == '\n') { + while (*CSR_UARTFLG & 0x20) + barrier(); + *CSR_UARTDR = '\r'; + } + } } static void __init diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index b88a7c115..7f0f35a05 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c @@ -101,6 +101,8 @@ struct tty_driver *serial_driver; #define RS_ISR_PASS_LIMIT 256 +#define _INLINE_ inline + static void change_speed(struct m68k_serial *info); /* @@ -260,7 +262,7 @@ static void batten_down_hatches(void) /* Drop into the debugger */ } -static void status_handle(struct m68k_serial *info, unsigned short status) +static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short status) { #if 0 if(status & DCD) { @@ -287,8 +289,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status) return; } -static void receive_chars(struct m68k_serial *info, struct pt_regs *regs, - unsigned short rx) +static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *regs, unsigned short rx) { struct tty_struct *tty = info->tty; m68328_uart *uart = &uart_addr[info->line]; @@ -358,7 +359,7 @@ clear_and_exit: return; } -static void transmit_chars(struct m68k_serial *info) +static _INLINE_ void transmit_chars(struct m68k_serial *info) { m68328_uart *uart = &uart_addr[info->line]; diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 968597781..7aca22c99 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -7,9 +7,6 @@ * * Copyright (C) 2001 Russell King. * - * 2005/09/16: Enabled higher baud rates for 16C95x. - * (Mathias Adam ) - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -365,40 +362,6 @@ serial_out(struct uart_8250_port *up, int offset, int value) #define serial_inp(up, offset) serial_in(up, offset) #define serial_outp(up, offset, value) serial_out(up, offset, value) -/* Uart divisor latch read */ -static inline int _serial_dl_read(struct uart_8250_port *up) -{ - return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8; -} - -/* Uart divisor latch write */ -static inline void _serial_dl_write(struct uart_8250_port *up, int value) -{ - serial_outp(up, UART_DLL, value & 0xff); - serial_outp(up, UART_DLM, value >> 8 & 0xff); -} - -#ifdef CONFIG_SERIAL_8250_AU1X00 -/* Au1x00 haven't got a standard divisor latch */ -static int serial_dl_read(struct uart_8250_port *up) -{ - if (up->port.iotype == UPIO_AU) - return __raw_readl(up->port.membase + 0x28); - else - return _serial_dl_read(up); -} - -static void serial_dl_write(struct uart_8250_port *up, int value) -{ - if (up->port.iotype == UPIO_AU) - __raw_writel(value, up->port.membase + 0x28); - else - _serial_dl_write(up, value); -} -#else -#define serial_dl_read(up) _serial_dl_read(up) -#define serial_dl_write(up, value) _serial_dl_write(up, value) -#endif /* * For the 16C950 @@ -531,8 +494,7 @@ static void disable_rsa(struct uart_8250_port *up) */ static int size_fifo(struct uart_8250_port *up) { - unsigned char old_fcr, old_mcr, old_lcr; - unsigned short old_dl; + unsigned char old_fcr, old_mcr, old_dll, old_dlm, old_lcr; int count; old_lcr = serial_inp(up, UART_LCR); @@ -543,8 +505,10 @@ static int size_fifo(struct uart_8250_port *up) UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); serial_outp(up, UART_MCR, UART_MCR_LOOP); serial_outp(up, UART_LCR, UART_LCR_DLAB); - old_dl = serial_dl_read(up); - serial_dl_write(up, 0x0001); + old_dll = serial_inp(up, UART_DLL); + old_dlm = serial_inp(up, UART_DLM); + serial_outp(up, UART_DLL, 0x01); + serial_outp(up, UART_DLM, 0x00); serial_outp(up, UART_LCR, 0x03); for (count = 0; count < 256; count++) serial_outp(up, UART_TX, count); @@ -555,7 +519,8 @@ static int size_fifo(struct uart_8250_port *up) serial_outp(up, UART_FCR, old_fcr); serial_outp(up, UART_MCR, old_mcr); serial_outp(up, UART_LCR, UART_LCR_DLAB); - serial_dl_write(up, old_dl); + serial_outp(up, UART_DLL, old_dll); + serial_outp(up, UART_DLM, old_dlm); serial_outp(up, UART_LCR, old_lcr); return count; @@ -785,7 +750,8 @@ static void autoconfig_16550a(struct uart_8250_port *up) serial_outp(up, UART_LCR, 0xE0); - quot = serial_dl_read(up); + quot = serial_inp(up, UART_DLM) << 8; + quot += serial_inp(up, UART_DLL); quot <<= 3; status1 = serial_in(up, 0x04); /* EXCR1 */ @@ -793,7 +759,8 @@ static void autoconfig_16550a(struct uart_8250_port *up) status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ serial_outp(up, 0x04, status1); - serial_dl_write(up, quot); + serial_outp(up, UART_DLL, quot & 0xff); + serial_outp(up, UART_DLM, quot >> 8); serial_outp(up, UART_LCR, 0); @@ -1561,7 +1528,7 @@ static int serial8250_startup(struct uart_port *port) /* * Clear the FIFO buffers and disable them. - * (they will be reenabled in set_termios()) + * (they will be reeanbled in set_termios()) */ serial8250_clear_fifos(up); @@ -1748,14 +1715,6 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int else if ((port->flags & UPF_MAGIC_MULTIPLIER) && baud == (port->uartclk/8)) quot = 0x8002; - /* - * For 16C950s UART_TCR is used in combination with divisor==1 - * to achieve baud rates up to baud_base*4. - */ - else if ((port->type == PORT_16C950) && - baud > (port->uartclk/16)) - quot = 1; - else quot = uart_get_divisor(port, baud); @@ -1769,7 +1728,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned char cval, fcr = 0; unsigned long flags; - unsigned int baud, quot, max_baud; + unsigned int baud, quot; switch (termios->c_cflag & CSIZE) { case CS5: @@ -1801,8 +1760,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, /* * Ask the core to calculate the divisor for us. */ - max_baud = (up->port.type == PORT_16C950 ? port->uartclk/4 : port->uartclk/16); - baud = uart_get_baud_rate(port, termios, old, 0, max_baud); + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = serial8250_get_divisor(port, baud); /* @@ -1838,19 +1796,6 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, */ spin_lock_irqsave(&up->port.lock, flags); - /* - * 16C950 supports additional prescaler ratios between 1:16 and 1:4 - * thus increasing max baud rate to uartclk/4. - */ - if (up->port.type == PORT_16C950) { - if (baud == port->uartclk/4) - serial_icr_write(up, UART_TCR, 0x4); - else if (baud == port->uartclk/8) - serial_icr_write(up, UART_TCR, 0x8); - else - serial_icr_write(up, UART_TCR, 0); - } - /* * Update the per-port timeout. */ @@ -1917,7 +1862,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ } - serial_dl_write(up, quot); + serial_outp(up, UART_DLL, quot & 0xff); /* LS of divisor */ + serial_outp(up, UART_DLM, quot >> 8); /* MS of divisor */ /* * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR @@ -1960,9 +1906,6 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) int ret = 0; switch (up->port.iotype) { - case UPIO_AU: - size = 0x100000; - /* fall thru */ case UPIO_MEM: if (!up->port.mapbase) break; @@ -1995,9 +1938,6 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) unsigned int size = 8 << up->port.regshift; switch (up->port.iotype) { - case UPIO_AU: - size = 0x100000; - /* fall thru */ case UPIO_MEM: if (!up->port.mapbase) break; @@ -2236,22 +2176,12 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) /* Wait up to 1s for flow control if necessary */ if (up->port.flags & UPF_CONS_FLOW) { tmout = 1000000; - while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) { + while (--tmout && + ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) udelay(1); - if ((tmout % 1000) == 0) - touch_nmi_watchdog(); - } } } -static void serial8250_console_putchar(struct uart_port *port, int ch) -{ - struct uart_8250_port *up = (struct uart_8250_port *)port; - - wait_for_xmitr(up, UART_LSR_THRE); - serial_out(up, UART_TX, ch); -} - /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -2262,21 +2192,11 @@ static void serial8250_console_write(struct console *co, const char *s, unsigned int count) { struct uart_8250_port *up = &serial8250_ports[co->index]; - unsigned long flags; unsigned int ier; - int locked = 1; + int i; touch_nmi_watchdog(); - local_irq_save(flags); - if (up->port.sysrq) { - /* serial8250_handle_port() already took the lock */ - locked = 0; - } else if (oops_in_progress) { - locked = spin_trylock(&up->port.lock); - } else - spin_lock(&up->port.lock); - /* * First save the IER then disable the interrupts */ @@ -2287,18 +2207,30 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) else serial_out(up, UART_IER, 0); - uart_console_write(&up->port, s, count, serial8250_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(up, UART_LSR_THRE); + + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_out(up, UART_TX, *s); + if (*s == 10) { + wait_for_xmitr(up, UART_LSR_THRE); + serial_out(up, UART_TX, 13); + } + } /* * Finally, wait for transmitter to become empty * and restore the IER */ wait_for_xmitr(up, BOTH_EMPTY); - serial_out(up, UART_IER, ier); - - if (locked) - spin_unlock(&up->port.lock); - local_irq_restore(flags); + up->ier |= UART_IER_THRI; + serial_out(up, UART_IER, ier | UART_IER_THRI); } static int serial8250_console_setup(struct console *co, char *options) diff --git a/drivers/serial/8250_acpi.c b/drivers/serial/8250_acpi.c new file mode 100644 index 000000000..809f89ab9 --- /dev/null +++ b/drivers/serial/8250_acpi.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2002-2003 Matthew Wilcox for Hewlett-Packard + * Copyright (C) 2004 Hewlett-Packard Co + * Bjorn Helgaas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 +#include +#include +#include + +#include + +#include + +#include "8250.h" + +struct serial_private { + int line; +}; + +static acpi_status acpi_serial_mmio(struct uart_port *port, + struct acpi_resource_address64 *addr) +{ + port->mapbase = addr->minimum; + port->iotype = UPIO_MEM; + port->flags |= UPF_IOREMAP; + return AE_OK; +} + +static acpi_status acpi_serial_port(struct uart_port *port, + struct acpi_resource_io *io) +{ + if (io->address_length) { + port->iobase = io->minimum; + port->iotype = UPIO_PORT; + } else + printk(KERN_ERR "%s: zero-length IO port range?\n", __FUNCTION__); + return AE_OK; +} + +static acpi_status acpi_serial_ext_irq(struct uart_port *port, + struct acpi_resource_extended_irq *ext_irq) +{ + int rc; + + if (ext_irq->interrupt_count > 0) { + rc = acpi_register_gsi(ext_irq->interrupts[0], + ext_irq->triggering, ext_irq->polarity); + if (rc < 0) + return AE_ERROR; + port->irq = rc; + } + return AE_OK; +} + +static acpi_status acpi_serial_irq(struct uart_port *port, + struct acpi_resource_irq *irq) +{ + int rc; + + if (irq->interrupt_count > 0) { + rc = acpi_register_gsi(irq->interrupts[0], + irq->triggering, irq->polarity); + if (rc < 0) + return AE_ERROR; + port->irq = rc; + } + return AE_OK; +} + +static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data) +{ + struct uart_port *port = (struct uart_port *) data; + struct acpi_resource_address64 addr; + acpi_status status; + + status = acpi_resource_to_address64(res, &addr); + if (ACPI_SUCCESS(status)) + return acpi_serial_mmio(port, &addr); + else if (res->type == ACPI_RESOURCE_TYPE_IO) + return acpi_serial_port(port, &res->data.io); + else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) + return acpi_serial_ext_irq(port, &res->data.extended_irq); + else if (res->type == ACPI_RESOURCE_TYPE_IRQ) + return acpi_serial_irq(port, &res->data.irq); + return AE_OK; +} + +static int acpi_serial_add(struct acpi_device *device) +{ + struct serial_private *priv; + acpi_status status; + struct uart_port port; + int result; + + memset(&port, 0, sizeof(struct uart_port)); + + port.uartclk = 1843200; + port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; + + priv = kmalloc(sizeof(struct serial_private), GFP_KERNEL); + if (!priv) { + result = -ENOMEM; + goto fail; + } + memset(priv, 0, sizeof(*priv)); + + status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, + acpi_serial_resource, &port); + if (ACPI_FAILURE(status)) { + result = -ENODEV; + goto fail; + } + + if (!port.mapbase && !port.iobase) { + printk(KERN_ERR "%s: no iomem or port address in %s _CRS\n", + __FUNCTION__, device->pnp.bus_id); + result = -ENODEV; + goto fail; + } + + priv->line = serial8250_register_port(&port); + if (priv->line < 0) { + printk(KERN_WARNING "Couldn't register serial port %s: %d\n", + device->pnp.bus_id, priv->line); + result = -ENODEV; + goto fail; + } + + acpi_driver_data(device) = priv; + return 0; + +fail: + kfree(priv); + + return result; +} + +static int acpi_serial_remove(struct acpi_device *device, int type) +{ + struct serial_private *priv; + + if (!device || !acpi_driver_data(device)) + return -EINVAL; + + priv = acpi_driver_data(device); + serial8250_unregister_port(priv->line); + kfree(priv); + + return 0; +} + +static struct acpi_driver acpi_serial_driver = { + .name = "serial", + .class = "", + .ids = "PNP0501", + .ops = { + .add = acpi_serial_add, + .remove = acpi_serial_remove, + }, +}; + +static int __init acpi_serial_init(void) +{ + return acpi_bus_register_driver(&acpi_serial_driver); +} + +static void __exit acpi_serial_exit(void) +{ + acpi_bus_unregister_driver(&acpi_serial_driver); +} + +module_init(acpi_serial_init); +module_exit(acpi_serial_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic 8250/16x50 ACPI serial driver"); diff --git a/drivers/serial/8250_au1x00.c b/drivers/serial/8250_au1x00.c index 58015fd14..8d8d7a70d 100644 --- a/drivers/serial/8250_au1x00.c +++ b/drivers/serial/8250_au1x00.c @@ -30,12 +30,13 @@ { \ .iobase = _base, \ .membase = (void __iomem *)_base,\ - .mapbase = CPHYSADDR(_base), \ + .mapbase = _base, \ .irq = _irq, \ .uartclk = 0, /* filled */ \ .regshift = 2, \ .iotype = UPIO_AU, \ - .flags = UPF_SKIP_TEST \ + .flags = UPF_SKIP_TEST | \ + UPF_IOREMAP, \ } static struct plat_serial8250_port au1x00_data[] = { @@ -50,7 +51,7 @@ static struct plat_serial8250_port au1x00_data[] = { #elif defined(CONFIG_SOC_AU1100) PORT(UART0_ADDR, AU1100_UART0_INT), PORT(UART1_ADDR, AU1100_UART1_INT), - /* The internal UART2 does not exist on the AU1100 processor. */ + PORT(UART2_ADDR, AU1100_UART2_INT), PORT(UART3_ADDR, AU1100_UART3_INT), #elif defined(CONFIG_SOC_AU1550) PORT(UART0_ADDR, AU1550_UART0_INT), diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c index 7e511199b..59ba5d993 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/serial/8250_early.c @@ -74,7 +74,7 @@ static void __init wait_for_xmitr(struct uart_port *port) } } -static void __init putc(struct uart_port *port, int c) +static void __init putc(struct uart_port *port, unsigned char c) { wait_for_xmitr(port); serial_out(port, UART_TX, c); @@ -89,7 +89,12 @@ static void __init early_uart_write(struct console *console, const char *s, unsi ier = serial_in(port, UART_IER); serial_out(port, UART_IER, 0); - uart_console_write(port, s, count, putc); + while (*s && count-- > 0) { + putc(port, *s); + if (*s == '\n') + putc(port, '\r'); + s++; + } /* Wait for transmitter to become empty and restore the IER */ wait_for_xmitr(port); diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index 913c71cc0..8b4947933 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c @@ -52,14 +52,13 @@ serial_init_chip(struct parisc_device *dev) address += 0x800; } - memset(&port, 0, sizeof(port)); - port.iotype = UPIO_MEM; - port.uartclk = LASI_BASE_BAUD * 16; - port.mapbase = address; - port.membase = ioremap_nocache(address, 16); - port.irq = dev->irq; - port.flags = UPF_BOOT_AUTOCONF; - port.dev = &dev->dev; + memset(&port, 0, sizeof(struct uart_port)); + port.mapbase = address; + port.irq = dev->irq; + port.iotype = UPIO_MEM; + port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; + port.uartclk = LASI_BASE_BAUD * 16; + port.dev = &dev->dev; err = serial8250_register_port(&port); if (err < 0) { diff --git a/drivers/serial/8250_hp300.c b/drivers/serial/8250_hp300.c index 53e81a44c..4315afe9c 100644 --- a/drivers/serial/8250_hp300.c +++ b/drivers/serial/8250_hp300.c @@ -55,8 +55,6 @@ static struct dio_driver hpdca_driver = { #endif -static unsigned int num_ports; - extern int hp300_uart_scode; /* Offset to UART registers from base of DCA */ @@ -201,8 +199,6 @@ static int __devinit hpdca_init_one(struct dio_dev *d, out_8(d->resource.start + DIO_VIRADDRBASE + DCA_ID, 0xff); udelay(100); - num_ports++; - return 0; } #endif @@ -210,6 +206,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d, static int __init hp300_8250_init(void) { static int called = 0; + int num_ports; #ifdef CONFIG_HPAPCI int line; unsigned long base; @@ -224,8 +221,11 @@ static int __init hp300_8250_init(void) if (!MACH_IS_HP300) return -ENODEV; + num_ports = 0; + #ifdef CONFIG_HPDCA - dio_register_driver(&hpdca_driver); + if (dio_module_init(&hpdca_driver) == 0) + num_ports++; #endif #ifdef CONFIG_HPAPCI if (hp300_model < HP_400) { diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index d2716173d..74efa366e 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -11,7 +11,6 @@ menu "Serial drivers" config SERIAL_8250 tristate "8250/16550 and compatible serial support" depends on (BROKEN || !SPARC) - depends on !XEN_DISABLE_SERIAL select SERIAL_CORE ---help--- This selects whether you want to include the driver for the standard @@ -64,33 +63,6 @@ config SERIAL_8250_CONSOLE If unsure, say N. -config SERIAL_8250_GSC - tristate - depends on SERIAL_8250 && GSC - default SERIAL_8250 - -config SERIAL_8250_PCI - tristate "8250/16550 PCI device support" if EMBEDDED - depends on SERIAL_8250 && PCI - default SERIAL_8250 - help - This builds standard PCI serial support. You may be able to - disable this feature if you only need legacy serial support. - Saves about 9K. - -config SERIAL_8250_PNP - tristate "8250/16550 PNP device support" if EMBEDDED - depends on SERIAL_8250 && PNP - default SERIAL_8250 - help - This builds standard PNP serial support. You may be able to - disable this feature if you only need legacy serial support. - -config SERIAL_8250_HP300 - tristate - depends on SERIAL_8250 && HP300 - default SERIAL_8250 - config SERIAL_8250_CS tristate "8250/16550 PCMCIA device support" depends on PCMCIA && SERIAL_8250 @@ -105,6 +77,14 @@ config SERIAL_8250_CS If unsure, say N. +config SERIAL_8250_ACPI + bool "8250/16550 device discovery via ACPI namespace" + default y if IA64 + depends on ACPI && SERIAL_8250 + ---help--- + If you wish to enable serial port discovery via the ACPI + namespace, say Y here. If unsure, say N. + config SERIAL_8250_NR_UARTS int "Maximum number of 8250/16550 serial ports" depends on SERIAL_8250 @@ -602,13 +582,6 @@ config SERIAL_SUNSAB_CONSOLE on your Sparc system as the console, you can do so by answering Y to this option. -config SERIAL_SUNHV - bool "Sun4v Hypervisor Console support" - depends on SPARC64 - help - This driver supports the console device found on SUN4V Sparc - systems. Say Y if you want to be able to use this device. - config SERIAL_IP22_ZILOG tristate "IP22 Zilog8530 serial support" depends on SGI_IP22 @@ -648,6 +621,22 @@ config SERIAL_SH_SCI_CONSOLE depends on SERIAL_SH_SCI=y select SERIAL_CORE_CONSOLE +config SERIAL_AU1X00 + bool "Enable Au1x00 UART Support" + depends on MIPS && SOC_AU1X00 + select SERIAL_CORE + help + If you have an Alchemy AU1X00 processor (MIPS based) and you want + to use serial ports, say Y. Otherwise, say N. + +config SERIAL_AU1X00_CONSOLE + bool "Enable Au1x00 serial console" + depends on SERIAL_AU1X00 + select SERIAL_CORE_CONSOLE + help + If you have an Alchemy AU1X00 processor (MIPS based) and you want + to use a console on a serial port, say Y. Otherwise, say N. + config SERIAL_CORE tristate @@ -804,7 +793,6 @@ config SERIAL_MPC52xx tristate "Freescale MPC52xx family PSC serial support" depends on PPC_MPC52xx select SERIAL_CORE - select FW_LOADER help This drivers support the MPC52xx PSC serial ports. If you would like to use them, you must answer Y or M to this option. Not that @@ -872,7 +860,7 @@ config SERIAL_M32R_PLDSIO config SERIAL_TXX9 bool "TMPTX39XX/49XX SIO support" - depends HAS_TXX9_SERIAL + depends HAS_TXX9_SERIAL && BROKEN select SERIAL_CORE default y diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 0a71bf68a..eaf8e01db 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -4,13 +4,16 @@ # $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $ # +serial-8250-y := +serial-8250-$(CONFIG_SERIAL_8250_ACPI) += 8250_acpi.o +serial-8250-$(CONFIG_PNP) += 8250_pnp.o +serial-8250-$(CONFIG_GSC) += 8250_gsc.o +serial-8250-$(CONFIG_PCI) += 8250_pci.o +serial-8250-$(CONFIG_HP300) += 8250_hp300.o + obj-$(CONFIG_SERIAL_CORE) += serial_core.o obj-$(CONFIG_SERIAL_21285) += 21285.o -obj-$(CONFIG_SERIAL_8250) += 8250.o -obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o -obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o -obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o -obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o +obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y) obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o @@ -27,7 +30,6 @@ obj-$(CONFIG_SERIAL_PXA) += pxa.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o -obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o @@ -39,6 +41,7 @@ obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o obj-$(CONFIG_V850E_UART) += v850e_uart.o obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o +obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o obj-$(CONFIG_SERIAL_DZ) += dz.o obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += sn_console.o diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 163141400..321a3b3a5 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -51,6 +51,8 @@ #include #include +#include +#include #define UART_NR 2 @@ -60,19 +62,47 @@ #define AMBA_ISR_PASS_LIMIT 256 +/* + * Access macros for the AMBA UARTs + */ +#define UART_GET_INT_STATUS(p) readb((p)->membase + UART010_IIR) +#define UART_PUT_ICR(p, c) writel((c), (p)->membase + UART010_ICR) +#define UART_GET_FR(p) readb((p)->membase + UART01x_FR) +#define UART_GET_CHAR(p) readb((p)->membase + UART01x_DR) +#define UART_PUT_CHAR(p, c) writel((c), (p)->membase + UART01x_DR) +#define UART_GET_RSR(p) readb((p)->membase + UART01x_RSR) +#define UART_GET_CR(p) readb((p)->membase + UART010_CR) +#define UART_PUT_CR(p,c) writel((c), (p)->membase + UART010_CR) +#define UART_GET_LCRL(p) readb((p)->membase + UART010_LCRL) +#define UART_PUT_LCRL(p,c) writel((c), (p)->membase + UART010_LCRL) +#define UART_GET_LCRM(p) readb((p)->membase + UART010_LCRM) +#define UART_PUT_LCRM(p,c) writel((c), (p)->membase + UART010_LCRM) +#define UART_GET_LCRH(p) readb((p)->membase + UART010_LCRH) +#define UART_PUT_LCRH(p,c) writel((c), (p)->membase + UART010_LCRH) #define UART_RX_DATA(s) (((s) & UART01x_FR_RXFE) == 0) #define UART_TX_READY(s) (((s) & UART01x_FR_TXFF) == 0) +#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART01x_FR_TMSK) == 0) -#define UART_DUMMY_RSR_RX 256 +#define UART_DUMMY_RSR_RX /*256*/0 #define UART_PORT_SIZE 64 +/* + * On the Integrator platform, the port RTS and DTR are provided by + * bits in the following SC_CTRLS register bits: + * RTS DTR + * UART0 7 6 + * UART1 5 4 + */ +#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET) +#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET) + /* * We wrap our port structure around the generic uart_port. */ struct uart_amba_port { struct uart_port port; - struct amba_device *dev; - struct amba_pl010_data *data; + unsigned int dtr_mask; + unsigned int rts_mask; unsigned int old_status; }; @@ -80,36 +110,36 @@ static void pl010_stop_tx(struct uart_port *port) { unsigned int cr; - cr = readb(port->membase + UART010_CR); + cr = UART_GET_CR(port); cr &= ~UART010_CR_TIE; - writel(cr, port->membase + UART010_CR); + UART_PUT_CR(port, cr); } static void pl010_start_tx(struct uart_port *port) { unsigned int cr; - cr = readb(port->membase + UART010_CR); + cr = UART_GET_CR(port); cr |= UART010_CR_TIE; - writel(cr, port->membase + UART010_CR); + UART_PUT_CR(port, cr); } static void pl010_stop_rx(struct uart_port *port) { unsigned int cr; - cr = readb(port->membase + UART010_CR); + cr = UART_GET_CR(port); cr &= ~(UART010_CR_RIE | UART010_CR_RTIE); - writel(cr, port->membase + UART010_CR); + UART_PUT_CR(port, cr); } static void pl010_enable_ms(struct uart_port *port) { unsigned int cr; - cr = readb(port->membase + UART010_CR); + cr = UART_GET_CR(port); cr |= UART010_CR_MSIE; - writel(cr, port->membase + UART010_CR); + UART_PUT_CR(port, cr); } static void @@ -122,9 +152,9 @@ pl010_rx_chars(struct uart_port *port) struct tty_struct *tty = port->info->tty; unsigned int status, ch, flag, rsr, max_count = 256; - status = readb(port->membase + UART01x_FR); + status = UART_GET_FR(port); while (UART_RX_DATA(status) && max_count--) { - ch = readb(port->membase + UART01x_DR); + ch = UART_GET_CHAR(port); flag = TTY_NORMAL; port->icount.rx++; @@ -133,7 +163,7 @@ pl010_rx_chars(struct uart_port *port) * Note that the error handling code is * out of the main execution path */ - rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX; + rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX; if (unlikely(rsr & UART01x_RSR_ANY)) { if (rsr & UART01x_RSR_BE) { rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); @@ -163,7 +193,7 @@ pl010_rx_chars(struct uart_port *port) uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag); ignore_char: - status = readb(port->membase + UART01x_FR); + status = UART_GET_FR(port); } tty_flip_buffer_push(tty); return; @@ -175,7 +205,7 @@ static void pl010_tx_chars(struct uart_port *port) int count; if (port->x_char) { - writel(port->x_char, port->membase + UART01x_DR); + UART_PUT_CHAR(port, port->x_char); port->icount.tx++; port->x_char = 0; return; @@ -187,7 +217,7 @@ static void pl010_tx_chars(struct uart_port *port) count = port->fifosize >> 1; do { - writel(xmit->buf[xmit->tail], port->membase + UART01x_DR); + UART_PUT_CHAR(port, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; if (uart_circ_empty(xmit)) @@ -206,9 +236,9 @@ static void pl010_modem_status(struct uart_port *port) struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int status, delta; - writel(0, uap->port.membase + UART010_ICR); + UART_PUT_ICR(&uap->port, 0); - status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + status = UART_GET_FR(&uap->port) & UART01x_FR_MODEM_ANY; delta = status ^ uap->old_status; uap->old_status = status; @@ -236,7 +266,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs) spin_lock(&port->lock); - status = readb(port->membase + UART010_IIR); + status = UART_GET_INT_STATUS(port); if (status) { do { if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) @@ -253,7 +283,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs) if (pass_counter-- == 0) break; - status = readb(port->membase + UART010_IIR); + status = UART_GET_INT_STATUS(port); } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS | UART010_IIR_TIS)); handled = 1; @@ -266,7 +296,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs) static unsigned int pl010_tx_empty(struct uart_port *port) { - return readb(port->membase + UART01x_FR) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; + return UART_GET_FR(port) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; } static unsigned int pl010_get_mctrl(struct uart_port *port) @@ -274,7 +304,7 @@ static unsigned int pl010_get_mctrl(struct uart_port *port) unsigned int result = 0; unsigned int status; - status = readb(port->membase + UART01x_FR); + status = UART_GET_FR(port); if (status & UART01x_FR_DCD) result |= TIOCM_CAR; if (status & UART01x_FR_DSR) @@ -288,9 +318,20 @@ static unsigned int pl010_get_mctrl(struct uart_port *port) static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int ctrls = 0, ctrlc = 0; + + if (mctrl & TIOCM_RTS) + ctrlc |= uap->rts_mask; + else + ctrls |= uap->rts_mask; - if (uap->data) - uap->data->set_mctrl(uap->dev, uap->port.membase, mctrl); + if (mctrl & TIOCM_DTR) + ctrlc |= uap->dtr_mask; + else + ctrls |= uap->dtr_mask; + + __raw_writel(ctrls, SC_CTRLS); + __raw_writel(ctrlc, SC_CTRLC); } static void pl010_break_ctl(struct uart_port *port, int break_state) @@ -299,12 +340,12 @@ static void pl010_break_ctl(struct uart_port *port, int break_state) unsigned int lcr_h; spin_lock_irqsave(&port->lock, flags); - lcr_h = readb(port->membase + UART010_LCRH); + lcr_h = UART_GET_LCRH(port); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; - writel(lcr_h, port->membase + UART010_LCRH); + UART_PUT_LCRH(port, lcr_h); spin_unlock_irqrestore(&port->lock, flags); } @@ -323,13 +364,13 @@ static int pl010_startup(struct uart_port *port) /* * initialise the old status of the modem signals */ - uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + uap->old_status = UART_GET_FR(port) & UART01x_FR_MODEM_ANY; /* * Finally, enable interrupts */ - writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE, - port->membase + UART010_CR); + UART_PUT_CR(port, UART01x_CR_UARTEN | UART010_CR_RIE | + UART010_CR_RTIE); return 0; } @@ -344,12 +385,11 @@ static void pl010_shutdown(struct uart_port *port) /* * disable all interrupts, disable the port */ - writel(0, port->membase + UART010_CR); + UART_PUT_CR(port, 0); /* disable break condition and fifos */ - writel(readb(port->membase + UART010_LCRH) & - ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN), - port->membase + UART010_LCRH); + UART_PUT_LCRH(port, UART_GET_LCRH(port) & + ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN)); } static void @@ -426,25 +466,25 @@ pl010_set_termios(struct uart_port *port, struct termios *termios, port->ignore_status_mask |= UART_DUMMY_RSR_RX; /* first, disable everything */ - old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE; + old_cr = UART_GET_CR(port) & ~UART010_CR_MSIE; if (UART_ENABLE_MS(port, termios->c_cflag)) old_cr |= UART010_CR_MSIE; - writel(0, port->membase + UART010_CR); + UART_PUT_CR(port, 0); /* Set baud rate */ quot -= 1; - writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM); - writel(quot & 0xff, port->membase + UART010_LCRL); + UART_PUT_LCRM(port, ((quot & 0xf00) >> 8)); + UART_PUT_LCRL(port, (quot & 0xff)); /* * ----------v----------v----------v----------v----- * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L * ----------^----------^----------^----------^----- */ - writel(lcr_h, port->membase + UART010_LCRH); - writel(old_cr, port->membase + UART010_CR); + UART_PUT_LCRH(port, lcr_h); + UART_PUT_CR(port, old_cr); spin_unlock_irqrestore(&port->lock, flags); } @@ -516,53 +556,87 @@ static struct uart_ops amba_pl010_pops = { .verify_port = pl010_verify_port, }; -static struct uart_amba_port *amba_ports[UART_NR]; +static struct uart_amba_port amba_ports[UART_NR] = { + { + .port = { + .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), + .mapbase = INTEGRATOR_UART0_BASE, + .iotype = UPIO_MEM, + .irq = IRQ_UARTINT0, + .uartclk = 14745600, + .fifosize = 16, + .ops = &amba_pl010_pops, + .flags = UPF_BOOT_AUTOCONF, + .line = 0, + }, + .dtr_mask = 1 << 5, + .rts_mask = 1 << 4, + }, + { + .port = { + .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), + .mapbase = INTEGRATOR_UART1_BASE, + .iotype = UPIO_MEM, + .irq = IRQ_UARTINT1, + .uartclk = 14745600, + .fifosize = 16, + .ops = &amba_pl010_pops, + .flags = UPF_BOOT_AUTOCONF, + .line = 1, + }, + .dtr_mask = 1 << 7, + .rts_mask = 1 << 6, + } +}; #ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE -static void pl010_console_putchar(struct uart_port *port, int ch) -{ - unsigned int status; - - do { - status = readb(port->membase + UART01x_FR); - barrier(); - } while (!UART_TX_READY(status)); - writel(ch, port->membase + UART01x_DR); -} - static void pl010_console_write(struct console *co, const char *s, unsigned int count) { - struct uart_port *port = &amba_ports[co->index]->port; + struct uart_port *port = &amba_ports[co->index].port; unsigned int status, old_cr; + int i; /* * First save the CR then disable the interrupts */ - old_cr = readb(port->membase + UART010_CR); - writel(UART01x_CR_UARTEN, port->membase + UART010_CR); + old_cr = UART_GET_CR(port); + UART_PUT_CR(port, UART01x_CR_UARTEN); - uart_console_write(port, s, count, pl010_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + do { + status = UART_GET_FR(port); + } while (!UART_TX_READY(status)); + UART_PUT_CHAR(port, s[i]); + if (s[i] == '\n') { + do { + status = UART_GET_FR(port); + } while (!UART_TX_READY(status)); + UART_PUT_CHAR(port, '\r'); + } + } /* * Finally, wait for transmitter to become empty * and restore the TCR */ do { - status = readb(port->membase + UART01x_FR); - barrier(); + status = UART_GET_FR(port); } while (status & UART01x_FR_BUSY); - writel(old_cr, port->membase + UART010_CR); + UART_PUT_CR(port, old_cr); } static void __init pl010_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits) { - if (readb(port->membase + UART010_CR) & UART01x_CR_UARTEN) { + if (UART_GET_CR(port) & UART01x_CR_UARTEN) { unsigned int lcr_h, quot; - lcr_h = readb(port->membase + UART010_LCRH); + lcr_h = UART_GET_LCRH(port); *parity = 'n'; if (lcr_h & UART01x_LCRH_PEN) { @@ -577,7 +651,7 @@ pl010_console_get_options(struct uart_port *port, int *baud, else *bits = 8; - quot = readb(port->membase + UART010_LCRL) | readb(port->membase + UART010_LCRM) << 8; + quot = UART_GET_LCRL(port) | UART_GET_LCRM(port) << 8; *baud = port->uartclk / (16 * (quot + 1)); } } @@ -597,7 +671,7 @@ static int __init pl010_console_setup(struct console *co, char *options) */ if (co->index >= UART_NR) co->index = 0; - port = &amba_ports[co->index]->port; + port = &amba_ports[co->index].port; if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); @@ -618,6 +692,24 @@ static struct console amba_console = { .data = &amba_reg, }; +static int __init amba_console_init(void) +{ + /* + * All port initializations are done statically + */ + register_console(&amba_console); + return 0; +} +console_initcall(amba_console_init); + +static int __init amba_late_console_init(void) +{ + if (!(amba_console.flags & CON_ENABLED)) + register_console(&amba_console); + return 0; +} +late_initcall(amba_late_console_init); + #define AMBA_CONSOLE &amba_console #else #define AMBA_CONSOLE NULL @@ -635,75 +727,29 @@ static struct uart_driver amba_reg = { static int pl010_probe(struct amba_device *dev, void *id) { - struct uart_amba_port *port; - void __iomem *base; - int i, ret; - - for (i = 0; i < ARRAY_SIZE(amba_ports); i++) - if (amba_ports[i] == NULL) - break; - - if (i == ARRAY_SIZE(amba_ports)) { - ret = -EBUSY; - goto out; - } - - port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); - if (!port) { - ret = -ENOMEM; - goto out; - } + int i; - base = ioremap(dev->res.start, PAGE_SIZE); - if (!base) { - ret = -ENOMEM; - goto free; - } + for (i = 0; i < UART_NR; i++) { + if (amba_ports[i].port.mapbase != dev->res.start) + continue; - port->port.dev = &dev->dev; - port->port.mapbase = dev->res.start; - port->port.membase = base; - port->port.iotype = UPIO_MEM; - port->port.irq = dev->irq[0]; - port->port.uartclk = 14745600; - port->port.fifosize = 16; - port->port.ops = &amba_pl010_pops; - port->port.flags = UPF_BOOT_AUTOCONF; - port->port.line = i; - port->dev = dev; - port->data = dev->dev.platform_data; - - amba_ports[i] = port; - - amba_set_drvdata(dev, port); - ret = uart_add_one_port(&amba_reg, &port->port); - if (ret) { - amba_set_drvdata(dev, NULL); - amba_ports[i] = NULL; - iounmap(base); - free: - kfree(port); + amba_ports[i].port.dev = &dev->dev; + uart_add_one_port(&amba_reg, &amba_ports[i].port); + amba_set_drvdata(dev, &amba_ports[i]); + break; } - out: - return ret; + return 0; } static int pl010_remove(struct amba_device *dev) { - struct uart_amba_port *port = amba_get_drvdata(dev); - int i; - - amba_set_drvdata(dev, NULL); - - uart_remove_one_port(&amba_reg, &port->port); + struct uart_amba_port *uap = amba_get_drvdata(dev); - for (i = 0; i < ARRAY_SIZE(amba_ports); i++) - if (amba_ports[i] == port) - amba_ports[i] = NULL; + if (uap) + uart_remove_one_port(&amba_reg, &uap->port); - iounmap(port->port.membase); - kfree(port); + amba_set_drvdata(dev, NULL); return 0; } diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 3d966cfc9..034a029e3 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -587,12 +587,14 @@ static struct uart_amba_port *amba_ports[UART_NR]; #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE -static void pl011_console_putchar(struct uart_port *port, int ch) +static inline void +pl011_console_write_char(struct uart_amba_port *uap, char ch) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int status; - while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) - barrier(); + do { + status = readw(uap->port.membase + UART01x_FR); + } while (status & UART01x_FR_TXFF); writew(ch, uap->port.membase + UART01x_DR); } @@ -601,6 +603,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) { struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr, new_cr; + int i; clk_enable(uap->clk); @@ -612,7 +615,14 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; writew(new_cr, uap->port.membase + UART011_CR); - uart_console_write(&uap->port, s, count, pl011_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + pl011_console_write_char(uap, s[i]); + if (s[i] == '\n') + pl011_console_write_char(uap, '\r'); + } /* * Finally, wait for transmitter to become empty diff --git a/drivers/serial/at91_serial.c b/drivers/serial/at91_serial.c index 6547fe0ce..2113feb75 100644 --- a/drivers/serial/at91_serial.c +++ b/drivers/serial/at91_serial.c @@ -711,12 +711,6 @@ void __init at91_register_uart(int idx, int port) } #ifdef CONFIG_SERIAL_AT91_CONSOLE -static void at91_console_putchar(struct uart_port *port, int ch) -{ - while (!(UART_GET_CSR(port) & AT91_US_TXRDY)) - barrier(); - UART_PUT_CHAR(port, ch); -} /* * Interrupts are disabled on entering @@ -724,7 +718,7 @@ static void at91_console_putchar(struct uart_port *port, int ch) static void at91_console_write(struct console *co, const char *s, u_int count) { struct uart_port *port = at91_ports + co->index; - unsigned int status, imr; + unsigned int status, i, imr; /* * First, save IMR and then disable interrupts @@ -732,7 +726,21 @@ static void at91_console_write(struct console *co, const char *s, u_int count) imr = UART_GET_IMR(port); /* get interrupt mask */ UART_PUT_IDR(port, AT91_US_RXRDY | AT91_US_TXRDY); - uart_console_write(port, s, count, at91_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + do { + status = UART_GET_CSR(port); + } while (!(status & AT91_US_TXRDY)); + UART_PUT_CHAR(port, s[i]); + if (s[i] == '\n') { + do { + status = UART_GET_CSR(port); + } while (!(status & AT91_US_TXRDY)); + UART_PUT_CHAR(port, '\r'); + } + } /* * Finally, wait for transmitter to become empty diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c new file mode 100644 index 000000000..344022fe5 --- /dev/null +++ b/drivers/serial/au1x00_uart.c @@ -0,0 +1,1296 @@ +/* + * Driver for 8250/16550-type serial ports + * + * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + * + * Copyright (C) 2001 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A note about mapbase / membase + * + * mapbase is the physical address of the IO port. Currently, we don't + * support this very well, and it may well be dropped from this driver + * in future. As such, mapbase should be NULL. + * + * membase is an 'ioremapped' cookie. This is compatible with the old + * serial.c driver, and is currently the preferred form. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(CONFIG_SERIAL_AU1X00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include +#include "8250.h" + +/* + * Debugging. + */ +#if 0 +#define DEBUG_AUTOCONF(fmt...) printk(fmt) +#else +#define DEBUG_AUTOCONF(fmt...) do { } while (0) +#endif + +#if 0 +#define DEBUG_INTR(fmt...) printk(fmt) +#else +#define DEBUG_INTR(fmt...) do { } while (0) +#endif + +#define PASS_LIMIT 256 + +/* + * We default to IRQ0 for the "no irq" hack. Some + * machine types want others as well - they're free + * to redefine this in their header file. + */ +#define is_real_interrupt(irq) ((irq) != 0) + +static struct old_serial_port old_serial_port[] = { + { .baud_base = 0, + .iomem_base = (u8 *)UART0_ADDR, + .irq = AU1000_UART0_INT, + .flags = STD_COM_FLAGS, + .iomem_reg_shift = 2, + }, { + .baud_base = 0, + .iomem_base = (u8 *)UART1_ADDR, + .irq = AU1000_UART1_INT, + .flags = STD_COM_FLAGS, + .iomem_reg_shift = 2 + }, { + .baud_base = 0, + .iomem_base = (u8 *)UART2_ADDR, + .irq = AU1000_UART2_INT, + .flags = STD_COM_FLAGS, + .iomem_reg_shift = 2 + }, { + .baud_base = 0, + .iomem_base = (u8 *)UART3_ADDR, + .irq = AU1000_UART3_INT, + .flags = STD_COM_FLAGS, + .iomem_reg_shift = 2 + } +}; + +#define UART_NR ARRAY_SIZE(old_serial_port) + +struct uart_8250_port { + struct uart_port port; + struct timer_list timer; /* "no irq" timer */ + struct list_head list; /* ports on this IRQ */ + unsigned short rev; + unsigned char acr; + unsigned char ier; + unsigned char lcr; + unsigned char mcr_mask; /* mask of user bits */ + unsigned char mcr_force; /* mask of forced bits */ + unsigned char lsr_break_flag; + + /* + * We provide a per-port pm hook. + */ + void (*pm)(struct uart_port *port, + unsigned int state, unsigned int old); +}; + +struct irq_info { + spinlock_t lock; + struct list_head *head; +}; + +static struct irq_info irq_lists[NR_IRQS]; + +/* + * Here we define the default xmit fifo size used for each type of UART. + */ +static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = { + { "unknown", 1, 0 }, + { "8250", 1, 0 }, + { "16450", 1, 0 }, + { "16550", 1, 0 }, + /* PORT_16550A */ + { "AU1X00_UART",16, UART_CLEAR_FIFO | UART_USE_FIFO }, +}; + +static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) +{ + return au_readl((unsigned long)up->port.membase + offset); +} + +static _INLINE_ void +serial_out(struct uart_8250_port *up, int offset, int value) +{ + au_writel(value, (unsigned long)up->port.membase + offset); +} + +#define serial_inp(up, offset) serial_in(up, offset) +#define serial_outp(up, offset, value) serial_out(up, offset, value) + +/* + * This routine is called by rs_init() to initialize a specific serial + * port. It determines what type of UART chip this serial port is + * using: 8250, 16450, 16550, 16550A. The important question is + * whether or not this UART is a 16550A or not, since this will + * determine whether or not we can use its FIFO features or not. + */ +static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) +{ + unsigned char save_lcr, save_mcr; + unsigned long flags; + + if (!up->port.iobase && !up->port.mapbase && !up->port.membase) + return; + + DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%08lx): ", + up->port.line, up->port.iobase, up->port.membase); + + /* + * We really do need global IRQs disabled here - we're going to + * be frobbing the chips IRQ enable register to see if it exists. + */ + spin_lock_irqsave(&up->port.lock, flags); +// save_flags(flags); cli(); + + save_mcr = serial_in(up, UART_MCR); + save_lcr = serial_in(up, UART_LCR); + + up->port.type = PORT_16550A; + serial_outp(up, UART_LCR, save_lcr); + + up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size; + + if (up->port.type == PORT_UNKNOWN) + goto out; + + /* + * Reset the UART. + */ + serial_outp(up, UART_MCR, save_mcr); + serial_outp(up, UART_FCR, (UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT)); + serial_outp(up, UART_FCR, 0); + (void)serial_in(up, UART_RX); + serial_outp(up, UART_IER, 0); + + out: + spin_unlock_irqrestore(&up->port.lock, flags); +// restore_flags(flags); + DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); +} + +static void serial8250_stop_tx(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + + if (up->ier & UART_IER_THRI) { + up->ier &= ~UART_IER_THRI; + serial_out(up, UART_IER, up->ier); + } +} + +static void serial8250_start_tx(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + + if (!(up->ier & UART_IER_THRI)) { + up->ier |= UART_IER_THRI; + serial_out(up, UART_IER, up->ier); + } +} + +static void serial8250_stop_rx(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + + up->ier &= ~UART_IER_RLSI; + up->port.read_status_mask &= ~UART_LSR_DR; + serial_out(up, UART_IER, up->ier); +} + +static void serial8250_enable_ms(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + + up->ier |= UART_IER_MSI; + serial_out(up, UART_IER, up->ier); +} + +static _INLINE_ void +receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) +{ + struct tty_struct *tty = up->port.info->tty; + unsigned char ch, flag; + int max_count = 256; + + do { + ch = serial_inp(up, UART_RX); + flag = TTY_NORMAL; + up->port.icount.rx++; + + if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | + UART_LSR_FE | UART_LSR_OE))) { + /* + * For statistics only + */ + if (*status & UART_LSR_BI) { + *status &= ~(UART_LSR_FE | UART_LSR_PE); + up->port.icount.brk++; + /* + * We do the SysRQ and SAK checking + * here because otherwise the break + * may get masked by ignore_status_mask + * or read_status_mask. + */ + if (uart_handle_break(&up->port)) + goto ignore_char; + } else if (*status & UART_LSR_PE) + up->port.icount.parity++; + else if (*status & UART_LSR_FE) + up->port.icount.frame++; + if (*status & UART_LSR_OE) + up->port.icount.overrun++; + + /* + * Mask off conditions which should be ingored. + */ + *status &= up->port.read_status_mask; + +#ifdef CONFIG_SERIAL_AU1X00_CONSOLE + if (up->port.line == up->port.cons->index) { + /* Recover the break flag from console xmit */ + *status |= up->lsr_break_flag; + up->lsr_break_flag = 0; + } +#endif + if (*status & UART_LSR_BI) { + DEBUG_INTR("handling break...."); + flag = TTY_BREAK; + } else if (*status & UART_LSR_PE) + flag = TTY_PARITY; + else if (*status & UART_LSR_FE) + flag = TTY_FRAME; + } + if (uart_handle_sysrq_char(&up->port, ch, regs)) + goto ignore_char; + if ((*status & up->port.ignore_status_mask) == 0) + tty_insert_flip_char(tty, ch, flag); + if (*status & UART_LSR_OE) + /* + * Overrun is special, since it's reported + * immediately, and doesn't affect the current + * character. + */ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + ignore_char: + *status = serial_inp(up, UART_LSR); + } while ((*status & UART_LSR_DR) && (max_count-- > 0)); + spin_unlock(&up->port.lock); + tty_flip_buffer_push(tty); + spin_lock(&up->port.lock); +} + +static _INLINE_ void transmit_chars(struct uart_8250_port *up) +{ + struct circ_buf *xmit = &up->port.info->xmit; + int count; + + if (up->port.x_char) { + serial_outp(up, UART_TX, up->port.x_char); + up->port.icount.tx++; + up->port.x_char = 0; + return; + } + if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { + serial8250_stop_tx(&up->port); + return; + } + + count = up->port.fifosize; + do { + serial_out(up, UART_TX, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + up->port.icount.tx++; + if (uart_circ_empty(xmit)) + break; + } while (--count > 0); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&up->port); + + DEBUG_INTR("THRE..."); + + if (uart_circ_empty(xmit)) + serial8250_stop_tx(&up->port); +} + +static _INLINE_ void check_modem_status(struct uart_8250_port *up) +{ + int status; + + status = serial_in(up, UART_MSR); + + if ((status & UART_MSR_ANY_DELTA) == 0) + return; + + if (status & UART_MSR_TERI) + up->port.icount.rng++; + if (status & UART_MSR_DDSR) + up->port.icount.dsr++; + if (status & UART_MSR_DDCD) + uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); + if (status & UART_MSR_DCTS) + uart_handle_cts_change(&up->port, status & UART_MSR_CTS); + + wake_up_interruptible(&up->port.info->delta_msr_wait); +} + +/* + * This handles the interrupt from one port. + */ +static inline void +serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs) +{ + unsigned int status = serial_inp(up, UART_LSR); + + DEBUG_INTR("status = %x...", status); + + if (status & UART_LSR_DR) + receive_chars(up, &status, regs); + check_modem_status(up); + if (status & UART_LSR_THRE) + transmit_chars(up); +} + +/* + * This is the serial driver's interrupt routine. + * + * Arjan thinks the old way was overly complex, so it got simplified. + * Alan disagrees, saying that need the complexity to handle the weird + * nature of ISA shared interrupts. (This is a special exception.) + * + * In order to handle ISA shared interrupts properly, we need to check + * that all ports have been serviced, and therefore the ISA interrupt + * line has been de-asserted. + * + * This means we need to loop through all ports. checking that they + * don't have an interrupt pending. + */ +static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct irq_info *i = dev_id; + struct list_head *l, *end = NULL; + int pass_counter = 0; + + DEBUG_INTR("serial8250_interrupt(%d)...", irq); + + spin_lock(&i->lock); + + l = i->head; + do { + struct uart_8250_port *up; + unsigned int iir; + + up = list_entry(l, struct uart_8250_port, list); + + iir = serial_in(up, UART_IIR); + if (!(iir & UART_IIR_NO_INT)) { + spin_lock(&up->port.lock); + serial8250_handle_port(up, regs); + spin_unlock(&up->port.lock); + + end = NULL; + } else if (end == NULL) + end = l; + + l = l->next; + + if (l == i->head && pass_counter++ > PASS_LIMIT) { + /* If we hit this, we're dead. */ + printk(KERN_ERR "serial8250: too much work for " + "irq%d\n", irq); + break; + } + } while (l != end); + + spin_unlock(&i->lock); + + DEBUG_INTR("end.\n"); + /* FIXME! Was it really ours? */ + return IRQ_HANDLED; +} + +/* + * To support ISA shared interrupts, we need to have one interrupt + * handler that ensures that the IRQ line has been deasserted + * before returning. Failing to do this will result in the IRQ + * line being stuck active, and, since ISA irqs are edge triggered, + * no more IRQs will be seen. + */ +static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up) +{ + spin_lock_irq(&i->lock); + + if (!list_empty(i->head)) { + if (i->head == &up->list) + i->head = i->head->next; + list_del(&up->list); + } else { + BUG_ON(i->head != &up->list); + i->head = NULL; + } + + spin_unlock_irq(&i->lock); +} + +static int serial_link_irq_chain(struct uart_8250_port *up) +{ + struct irq_info *i = irq_lists + up->port.irq; + int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? SA_SHIRQ : 0; + + spin_lock_irq(&i->lock); + + if (i->head) { + list_add(&up->list, i->head); + spin_unlock_irq(&i->lock); + + ret = 0; + } else { + INIT_LIST_HEAD(&up->list); + i->head = &up->list; + spin_unlock_irq(&i->lock); + + ret = request_irq(up->port.irq, serial8250_interrupt, + irq_flags, "serial", i); + if (ret < 0) + serial_do_unlink(i, up); + } + + return ret; +} + +static void serial_unlink_irq_chain(struct uart_8250_port *up) +{ + struct irq_info *i = irq_lists + up->port.irq; + + BUG_ON(i->head == NULL); + + if (list_empty(i->head)) + free_irq(up->port.irq, i); + + serial_do_unlink(i, up); +} + +/* + * This function is used to handle ports that do not have an + * interrupt. This doesn't work very well for 16450's, but gives + * barely passable results for a 16550A. (Although at the expense + * of much CPU overhead). + */ +static void serial8250_timeout(unsigned long data) +{ + struct uart_8250_port *up = (struct uart_8250_port *)data; + unsigned int timeout; + unsigned int iir; + + iir = serial_in(up, UART_IIR); + if (!(iir & UART_IIR_NO_INT)) { + spin_lock(&up->port.lock); + serial8250_handle_port(up, NULL); + spin_unlock(&up->port.lock); + } + + timeout = up->port.timeout; + timeout = timeout > 6 ? (timeout / 2 - 2) : 1; + mod_timer(&up->timer, jiffies + timeout); +} + +static unsigned int serial8250_tx_empty(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned long flags; + unsigned int ret; + + spin_lock_irqsave(&up->port.lock, flags); + ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; + spin_unlock_irqrestore(&up->port.lock, flags); + + return ret; +} + +static unsigned int serial8250_get_mctrl(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned char status; + unsigned int ret; + + status = serial_in(up, UART_MSR); + + ret = 0; + if (status & UART_MSR_DCD) + ret |= TIOCM_CAR; + if (status & UART_MSR_RI) + ret |= TIOCM_RNG; + if (status & UART_MSR_DSR) + ret |= TIOCM_DSR; + if (status & UART_MSR_CTS) + ret |= TIOCM_CTS; + return ret; +} + +static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned char mcr = 0; + + if (mctrl & TIOCM_RTS) + mcr |= UART_MCR_RTS; + if (mctrl & TIOCM_DTR) + mcr |= UART_MCR_DTR; + if (mctrl & TIOCM_OUT1) + mcr |= UART_MCR_OUT1; + if (mctrl & TIOCM_OUT2) + mcr |= UART_MCR_OUT2; + if (mctrl & TIOCM_LOOP) + mcr |= UART_MCR_LOOP; + + mcr = (mcr & up->mcr_mask) | up->mcr_force; + + serial_out(up, UART_MCR, mcr); +} + +static void serial8250_break_ctl(struct uart_port *port, int break_state) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned long flags; + + spin_lock_irqsave(&up->port.lock, flags); + if (break_state == -1) + up->lcr |= UART_LCR_SBC; + else + up->lcr &= ~UART_LCR_SBC; + serial_out(up, UART_LCR, up->lcr); + spin_unlock_irqrestore(&up->port.lock, flags); +} + +static int serial8250_startup(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned long flags; + int retval; + + /* + * Clear the FIFO buffers and disable them. + * (they will be reeanbled in set_termios()) + */ + if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) { + serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); + serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + serial_outp(up, UART_FCR, 0); + } + + /* + * Clear the interrupt registers. + */ + (void) serial_inp(up, UART_LSR); + (void) serial_inp(up, UART_RX); + (void) serial_inp(up, UART_IIR); + (void) serial_inp(up, UART_MSR); + + /* + * At this point, there's no way the LSR could still be 0xff; + * if it is, then bail out, because there's likely no UART + * here. + */ + if (!(up->port.flags & UPF_BUGGY_UART) && + (serial_inp(up, UART_LSR) == 0xff)) { + printk("ttyS%d: LSR safety check engaged!\n", up->port.line); + return -ENODEV; + } + + retval = serial_link_irq_chain(up); + if (retval) + return retval; + + /* + * Now, initialize the UART + */ + serial_outp(up, UART_LCR, UART_LCR_WLEN8); + + spin_lock_irqsave(&up->port.lock, flags); + if (up->port.flags & UPF_FOURPORT) { + if (!is_real_interrupt(up->port.irq)) + up->port.mctrl |= TIOCM_OUT1; + } else + /* + * Most PC uarts need OUT2 raised to enable interrupts. + */ + if (is_real_interrupt(up->port.irq)) + up->port.mctrl |= TIOCM_OUT2; + + serial8250_set_mctrl(&up->port, up->port.mctrl); + spin_unlock_irqrestore(&up->port.lock, flags); + + /* + * Finally, enable interrupts. Note: Modem status interrupts + * are set via set_termios(), which will be occurring imminently + * anyway, so we don't enable them here. + */ + up->ier = UART_IER_RLSI | UART_IER_RDI; + serial_outp(up, UART_IER, up->ier); + + if (up->port.flags & UPF_FOURPORT) { + unsigned int icp; + /* + * Enable interrupts on the AST Fourport board + */ + icp = (up->port.iobase & 0xfe0) | 0x01f; + outb_p(0x80, icp); + (void) inb_p(icp); + } + + /* + * And clear the interrupt registers again for luck. + */ + (void) serial_inp(up, UART_LSR); + (void) serial_inp(up, UART_RX); + (void) serial_inp(up, UART_IIR); + (void) serial_inp(up, UART_MSR); + + return 0; +} + +static void serial8250_shutdown(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned long flags; + + /* + * Disable interrupts from this port + */ + up->ier = 0; + serial_outp(up, UART_IER, 0); + + spin_lock_irqsave(&up->port.lock, flags); + if (up->port.flags & UPF_FOURPORT) { + /* reset interrupts on the AST Fourport board */ + inb((up->port.iobase & 0xfe0) | 0x1f); + up->port.mctrl |= TIOCM_OUT1; + } else + up->port.mctrl &= ~TIOCM_OUT2; + + serial8250_set_mctrl(&up->port, up->port.mctrl); + spin_unlock_irqrestore(&up->port.lock, flags); + + /* + * Disable break condition and FIFOs + */ + serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC); + serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT); + serial_outp(up, UART_FCR, 0); + + /* + * Read data port to reset things, and then unlink from + * the IRQ chain. + */ + (void) serial_in(up, UART_RX); + + if (!is_real_interrupt(up->port.irq)) + del_timer_sync(&up->timer); + else + serial_unlink_irq_chain(up); +} + +static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) +{ + unsigned int quot; + + /* + * Handle magic divisors for baud rates above baud_base on + * SMSC SuperIO chips. + */ + if ((port->flags & UPF_MAGIC_MULTIPLIER) && + baud == (port->uartclk/4)) + quot = 0x8001; + else if ((port->flags & UPF_MAGIC_MULTIPLIER) && + baud == (port->uartclk/8)) + quot = 0x8002; + else + quot = uart_get_divisor(port, baud); + + return quot; +} + +static void +serial8250_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned char cval, fcr = 0; + unsigned long flags; + unsigned int baud, quot; + + switch (termios->c_cflag & CSIZE) { + case CS5: + cval = UART_LCR_WLEN5; + break; + case CS6: + cval = UART_LCR_WLEN6; + break; + case CS7: + cval = UART_LCR_WLEN7; + break; + default: + case CS8: + cval = UART_LCR_WLEN8; + break; + } + + if (termios->c_cflag & CSTOPB) + cval |= UART_LCR_STOP; + if (termios->c_cflag & PARENB) + cval |= UART_LCR_PARITY; + if (!(termios->c_cflag & PARODD)) + cval |= UART_LCR_EPAR; +#ifdef CMSPAR + if (termios->c_cflag & CMSPAR) + cval |= UART_LCR_SPAR; +#endif + + /* + * Ask the core to calculate the divisor for us. + */ + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + quot = serial8250_get_divisor(port, baud); + quot = 0x35; /* FIXME */ + + /* + * Work around a bug in the Oxford Semiconductor 952 rev B + * chip which causes it to seriously miscalculate baud rates + * when DLL is 0. + */ + if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 && + up->rev == 0x5201) + quot ++; + + if (uart_config[up->port.type].flags & UART_USE_FIFO) { + if (baud < 2400) + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_1; + else + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8; + } + + /* + * Ok, we're now changing the port state. Do it with + * interrupts disabled. + */ + spin_lock_irqsave(&up->port.lock, flags); + + /* + * Update the per-port timeout. + */ + uart_update_timeout(port, termios->c_cflag, baud); + + up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; + if (termios->c_iflag & INPCK) + up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; + if (termios->c_iflag & (BRKINT | PARMRK)) + up->port.read_status_mask |= UART_LSR_BI; + + /* + * Characteres to ignore + */ + up->port.ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; + if (termios->c_iflag & IGNBRK) { + up->port.ignore_status_mask |= UART_LSR_BI; + /* + * If we're ignoring parity and break indicators, + * ignore overruns too (for real raw support). + */ + if (termios->c_iflag & IGNPAR) + up->port.ignore_status_mask |= UART_LSR_OE; + } + + /* + * ignore all characters if CREAD is not set + */ + if ((termios->c_cflag & CREAD) == 0) + up->port.ignore_status_mask |= UART_LSR_DR; + + /* + * CTS flow control flag and modem status interrupts + */ + up->ier &= ~UART_IER_MSI; + if (UART_ENABLE_MS(&up->port, termios->c_cflag)) + up->ier |= UART_IER_MSI; + + serial_out(up, UART_IER, up->ier); + serial_outp(up, 0x28, quot & 0xffff); + up->lcr = cval; /* Save LCR */ + if (up->port.type != PORT_16750) { + if (fcr & UART_FCR_ENABLE_FIFO) { + /* emulated UARTs (Lucent Venus 167x) need two steps */ + serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); + } + serial_outp(up, UART_FCR, fcr); /* set fcr */ + } + spin_unlock_irqrestore(&up->port.lock, flags); +} + +static void +serial8250_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + if (state) { + /* sleep */ + if (up->pm) + up->pm(port, state, oldstate); + } else { + /* wake */ + if (up->pm) + up->pm(port, state, oldstate); + } +} + +/* + * Resource handling. This is complicated by the fact that resources + * depend on the port type. Maybe we should be claiming the standard + * 8250 ports, and then trying to get other resources as necessary? + */ +static int +serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res) +{ + unsigned int size = 8 << up->port.regshift; + int ret = 0; + + switch (up->port.iotype) { + case UPIO_MEM: + if (up->port.mapbase) { + *res = request_mem_region(up->port.mapbase, size, "serial"); + if (!*res) + ret = -EBUSY; + } + break; + + case UPIO_HUB6: + case UPIO_PORT: + *res = request_region(up->port.iobase, size, "serial"); + if (!*res) + ret = -EBUSY; + break; + } + return ret; +} + + +static void serial8250_release_port(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned long start, offset = 0, size = 0; + + size <<= up->port.regshift; + + switch (up->port.iotype) { + case UPIO_MEM: + if (up->port.mapbase) { + /* + * Unmap the area. + */ + iounmap(up->port.membase); + up->port.membase = NULL; + + start = up->port.mapbase; + + if (size) + release_mem_region(start + offset, size); + release_mem_region(start, 8 << up->port.regshift); + } + break; + + case UPIO_HUB6: + case UPIO_PORT: + start = up->port.iobase; + + if (size) + release_region(start + offset, size); + release_region(start + offset, 8 << up->port.regshift); + break; + + default: + break; + } +} + +static int serial8250_request_port(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + struct resource *res = NULL, *res_rsa = NULL; + int ret = 0; + + ret = serial8250_request_std_resource(up, &res); + + /* + * If we have a mapbase, then request that as well. + */ + if (ret == 0 && up->port.flags & UPF_IOREMAP) { + int size = res->end - res->start + 1; + + up->port.membase = ioremap(up->port.mapbase, size); + if (!up->port.membase) + ret = -ENOMEM; + } + + if (ret < 0) { + if (res_rsa) + release_resource(res_rsa); + if (res) + release_resource(res); + } + return ret; +} + +static void serial8250_config_port(struct uart_port *port, int flags) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + struct resource *res_std = NULL, *res_rsa = NULL; + int probeflags = PROBE_ANY; + + probeflags &= ~PROBE_RSA; + + if (flags & UART_CONFIG_TYPE) + autoconfig(up, probeflags); + + /* + * If the port wasn't an RSA port, release the resource. + */ + if (up->port.type != PORT_RSA && res_rsa) + release_resource(res_rsa); + + if (up->port.type == PORT_UNKNOWN && res_std) + release_resource(res_std); +} + +static int +serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + if (ser->irq >= NR_IRQS || ser->irq < 0 || + ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || + ser->type > PORT_MAX_8250 || ser->type == PORT_CIRRUS || + ser->type == PORT_STARTECH) + return -EINVAL; + return 0; +} + +static const char * +serial8250_type(struct uart_port *port) +{ + int type = port->type; + + if (type >= ARRAY_SIZE(uart_config)) + type = 0; + return uart_config[type].name; +} + +static struct uart_ops serial8250_pops = { + .tx_empty = serial8250_tx_empty, + .set_mctrl = serial8250_set_mctrl, + .get_mctrl = serial8250_get_mctrl, + .stop_tx = serial8250_stop_tx, + .start_tx = serial8250_start_tx, + .stop_rx = serial8250_stop_rx, + .enable_ms = serial8250_enable_ms, + .break_ctl = serial8250_break_ctl, + .startup = serial8250_startup, + .shutdown = serial8250_shutdown, + .set_termios = serial8250_set_termios, + .pm = serial8250_pm, + .type = serial8250_type, + .release_port = serial8250_release_port, + .request_port = serial8250_request_port, + .config_port = serial8250_config_port, + .verify_port = serial8250_verify_port, +}; + +static struct uart_8250_port serial8250_ports[UART_NR]; + +static void __init serial8250_isa_init_ports(void) +{ + struct uart_8250_port *up; + static int first = 1; + int i; + + if (!first) + return; + first = 0; + + for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port); + i++, up++) { + up->port.iobase = old_serial_port[i].port; + up->port.irq = old_serial_port[i].irq; + up->port.uartclk = get_au1x00_uart_baud_base(); + up->port.flags = old_serial_port[i].flags; + up->port.hub6 = old_serial_port[i].hub6; + up->port.membase = old_serial_port[i].iomem_base; + up->port.iotype = old_serial_port[i].io_type; + up->port.regshift = old_serial_port[i].iomem_reg_shift; + up->port.ops = &serial8250_pops; + } +} + +static void __init serial8250_register_ports(struct uart_driver *drv) +{ + int i; + + serial8250_isa_init_ports(); + + for (i = 0; i < UART_NR; i++) { + struct uart_8250_port *up = &serial8250_ports[i]; + + up->port.line = i; + up->port.ops = &serial8250_pops; + init_timer(&up->timer); + up->timer.function = serial8250_timeout; + + /* + * ALPHA_KLUDGE_MCR needs to be killed. + */ + up->mcr_mask = ~ALPHA_KLUDGE_MCR; + up->mcr_force = ALPHA_KLUDGE_MCR; + + uart_add_one_port(drv, &up->port); + } +} + +#ifdef CONFIG_SERIAL_AU1X00_CONSOLE + +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + +/* + * Wait for transmitter & holding register to empty + */ +static inline void wait_for_xmitr(struct uart_8250_port *up) +{ + unsigned int status, tmout = 10000; + + /* Wait up to 10ms for the character(s) to be sent. */ + do { + status = serial_in(up, UART_LSR); + + if (status & UART_LSR_BI) + up->lsr_break_flag = UART_LSR_BI; + + if (--tmout == 0) + break; + udelay(1); + } while ((status & BOTH_EMPTY) != BOTH_EMPTY); + + /* Wait up to 1s for flow control if necessary */ + if (up->port.flags & UPF_CONS_FLOW) { + tmout = 1000000; + while (--tmout && + ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) + udelay(1); + } +} + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * The console_lock must be held when we get here. + */ +static void +serial8250_console_write(struct console *co, const char *s, unsigned int count) +{ + struct uart_8250_port *up = &serial8250_ports[co->index]; + unsigned int ier; + int i; + + /* + * First save the UER then disable the interrupts + */ + ier = serial_in(up, UART_IER); + serial_out(up, UART_IER, 0); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(up); + + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_out(up, UART_TX, *s); + if (*s == 10) { + wait_for_xmitr(up); + serial_out(up, UART_TX, 13); + } + } + + /* + * Finally, wait for transmitter to become empty + * and restore the IER + */ + wait_for_xmitr(up); + serial_out(up, UART_IER, ier); +} + +static int __init serial8250_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + /* + * Check whether an invalid uart number has been specified, and + * if so, search for the first available port that does have + * console support. + */ + if (co->index >= UART_NR) + co->index = 0; + port = &serial8250_ports[co->index].port; + + /* + * Temporary fix. + */ + spin_lock_init(&port->lock); + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +extern struct uart_driver serial8250_reg; +static struct console serial8250_console = { + .name = "ttyS", + .write = serial8250_console_write, + .device = uart_console_device, + .setup = serial8250_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &serial8250_reg, +}; + +static int __init serial8250_console_init(void) +{ + serial8250_isa_init_ports(); + register_console(&serial8250_console); + return 0; +} +console_initcall(serial8250_console_init); + +#define SERIAL8250_CONSOLE &serial8250_console +#else +#define SERIAL8250_CONSOLE NULL +#endif + +static struct uart_driver serial8250_reg = { + .owner = THIS_MODULE, + .driver_name = "serial", + .devfs_name = "tts/", + .dev_name = "ttyS", + .major = TTY_MAJOR, + .minor = 64, + .nr = UART_NR, + .cons = SERIAL8250_CONSOLE, +}; + +int __init early_serial_setup(struct uart_port *port) +{ + serial8250_isa_init_ports(); + serial8250_ports[port->line].port = *port; + serial8250_ports[port->line].port.ops = &serial8250_pops; + return 0; +} + +/** + * serial8250_suspend_port - suspend one serial port + * @line: serial line number + * @level: the level of port suspension, as per uart_suspend_port + * + * Suspend one serial port. + */ +void serial8250_suspend_port(int line) +{ + uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port); +} + +/** + * serial8250_resume_port - resume one serial port + * @line: serial line number + * @level: the level of port resumption, as per uart_resume_port + * + * Resume one serial port. + */ +void serial8250_resume_port(int line) +{ + uart_resume_port(&serial8250_reg, &serial8250_ports[line].port); +} + +static int __init serial8250_init(void) +{ + int ret, i; + + printk(KERN_INFO "Serial: Au1x00 driver\n"); + + for (i = 0; i < NR_IRQS; i++) + spin_lock_init(&irq_lists[i].lock); + + ret = uart_register_driver(&serial8250_reg); + if (ret >= 0) + serial8250_register_ports(&serial8250_reg); + + return ret; +} + +static void __exit serial8250_exit(void) +{ + int i; + + for (i = 0; i < UART_NR; i++) + uart_remove_one_port(&serial8250_reg, &serial8250_ports[i].port); + + uart_unregister_driver(&serial8250_reg); +} + +module_init(serial8250_init); +module_exit(serial8250_exit); + +EXPORT_SYMBOL(serial8250_suspend_port); +EXPORT_SYMBOL(serial8250_resume_port); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Au1x00 serial driver\n"); diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index 2691112c8..ce7b2e4ec 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c @@ -424,13 +424,6 @@ static struct uart_port clps711x_ports[UART_NR] = { }; #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE -static void clps711xuart_console_putchar(struct uart_port *port, int ch) -{ - while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF) - barrier(); - clps_writel(ch, UARTDR(port)); -} - /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -445,6 +438,7 @@ clps711xuart_console_write(struct console *co, const char *s, { struct uart_port *port = clps711x_ports + co->index; unsigned int status, syscon; + int i; /* * Ensure that the port is enabled. @@ -452,7 +446,21 @@ clps711xuart_console_write(struct console *co, const char *s, syscon = clps_readl(SYSCON(port)); clps_writel(syscon | SYSCON_UARTEN, SYSCON(port)); - uart_console_write(port, s, count, clps711xuart_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + do { + status = clps_readl(SYSFLG(port)); + } while (status & SYSFLG_UTXFF); + clps_writel(s[i], UARTDR(port)); + if (s[i] == '\n') { + do { + status = clps_readl(SYSFLG(port)); + } while (status & SYSFLG_UTXFF); + clps_writel('\r', UARTDR(port)); + } + } /* * Finally, wait for transmitter to become empty diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 3b35cb779..73c8a088c 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h @@ -5,20 +5,11 @@ * * Copyright (C) 2004 Freescale Semiconductor, Inc. * - * 2006 (c) MontaVista Software, Inc. - * Vitaly Bordug - * - * 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. - * */ #ifndef CPM_UART_H #define CPM_UART_H #include -#include -#include #if defined(CONFIG_CPM2) #include "cpm_uart_cpm2.h" @@ -35,14 +26,14 @@ #define FLAG_SMC 0x00000002 #define FLAG_CONSOLE 0x00000001 -#define UART_SMC1 fsid_smc1_uart -#define UART_SMC2 fsid_smc2_uart -#define UART_SCC1 fsid_scc1_uart -#define UART_SCC2 fsid_scc2_uart -#define UART_SCC3 fsid_scc3_uart -#define UART_SCC4 fsid_scc4_uart +#define UART_SMC1 0 +#define UART_SMC2 1 +#define UART_SCC1 2 +#define UART_SCC2 3 +#define UART_SCC3 4 +#define UART_SCC4 5 -#define UART_NR fs_uart_nr +#define UART_NR 6 #define RX_NUM_FIFO 4 #define RX_BUF_SIZE 32 @@ -73,7 +64,6 @@ struct uart_cpm_port { uint dp_addr; void *mem_addr; dma_addr_t dma_addr; - u32 mem_size; /* helpers */ int baud; int bits; @@ -100,38 +90,4 @@ void scc2_lineif(struct uart_cpm_port *pinfo); void scc3_lineif(struct uart_cpm_port *pinfo); void scc4_lineif(struct uart_cpm_port *pinfo); -/* - virtual to phys transtalion -*/ -static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo) -{ - int offset; - u32 val = (u32)addr; - /* sane check */ - if (likely((val >= (u32)pinfo->mem_addr)) && - (val<((u32)pinfo->mem_addr + pinfo->mem_size))) { - offset = val - (u32)pinfo->mem_addr; - return pinfo->dma_addr+offset; - } - /* something nasty happened */ - BUG(); - return 0; -} - -static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo) -{ - int offset; - u32 val = addr; - /* sane check */ - if (likely((val >= pinfo->dma_addr) && - (val<(pinfo->dma_addr + pinfo->mem_size)))) { - offset = val - (u32)pinfo->dma_addr; - return (void*)(pinfo->mem_addr+offset); - } - /* something nasty happened */ - BUG(); - return 0; -} - - #endif /* CPM_UART_H */ diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 5cba59ad7..b7bf4c698 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -12,8 +12,7 @@ * * Copyright (C) 2004 Freescale Semiconductor, Inc. * (C) 2004 Intracom, S.A. - * (C) 2005-2006 MontaVista Software, Inc. - * Vitaly Bordug + * (C) 2005 MontaVista Software, Inc. by Vitaly Bordug * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,7 +41,6 @@ #include #include #include -#include #include #include @@ -62,7 +60,7 @@ /* Track which ports are configured as uarts */ int cpm_uart_port_map[UART_NR]; /* How many ports did we config as uarts */ -int cpm_uart_nr = 0; +int cpm_uart_nr; /**************************************************************/ @@ -73,51 +71,18 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); /**************************************************************/ - -/* Place-holder for board-specific stuff */ -struct platform_device* __attribute__ ((weak)) __init -early_uart_get_pdev(int index) -{ - return NULL; -} - - -static void cpm_uart_count(void) +static inline unsigned long cpu2cpm_addr(void *addr) { - cpm_uart_nr = 0; -#ifdef CONFIG_SERIAL_CPM_SMC1 - cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; -#endif -#ifdef CONFIG_SERIAL_CPM_SMC2 - cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; -#endif -#ifdef CONFIG_SERIAL_CPM_SCC1 - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; -#endif -#ifdef CONFIG_SERIAL_CPM_SCC2 - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; -#endif -#ifdef CONFIG_SERIAL_CPM_SCC3 - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; -#endif -#ifdef CONFIG_SERIAL_CPM_SCC4 - cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; -#endif + if ((unsigned long)addr >= CPM_ADDR) + return (unsigned long)addr; + return virt_to_bus(addr); } -/* Get UART number by its id */ -static int cpm_uart_id2nr(int id) +static inline void *cpm2cpu_addr(unsigned long addr) { - int i; - if (id < UART_NR) { - for (i=0; i= CPM_ADDR) + return (void *)addr; + return bus_to_virt(addr); } /* @@ -293,7 +258,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) } /* get pointer */ - cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + cp = cpm2cpu_addr(bdp->cbd_bufaddr); /* loop through the buffer */ while (i-- > 0) { @@ -473,11 +438,7 @@ static void cpm_uart_shutdown(struct uart_port *port) } /* Shut them really down and reinit buffer descriptors */ - if (IS_SMC(pinfo)) - cpm_line_cr_cmd(line, CPM_CR_STOP_TX); - else - cpm_line_cr_cmd(line, CPM_CR_GRA_STOP_TX); - + cpm_line_cr_cmd(line, CPM_CR_STOP_TX); cpm_uart_initbd(pinfo); } } @@ -640,7 +601,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) /* Pick next descriptor and fill from buffer */ bdp = pinfo->tx_cur; - p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + p = cpm2cpu_addr(bdp->cbd_bufaddr); *p++ = port->x_char; bdp->cbd_datlen = 1; @@ -667,7 +628,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { count = 0; - p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + p = cpm2cpu_addr(bdp->cbd_bufaddr); while (count < pinfo->tx_fifosize) { *p++ = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); @@ -716,12 +677,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) mem_addr = pinfo->mem_addr; bdp = pinfo->rx_cur = pinfo->rx_bd_base; for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { - bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); + bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; mem_addr += pinfo->rx_fifosize; } - bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); + bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; /* Set the physical address of the host memory @@ -731,12 +692,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); bdp = pinfo->tx_cur = pinfo->tx_bd_base; for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { - bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); + bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); bdp->cbd_sc = BD_SC_INTRPT; mem_addr += pinfo->tx_fifosize; } - bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); + bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; } @@ -868,6 +829,14 @@ static int cpm_uart_request_port(struct uart_port *port) if (pinfo->flags & FLAG_CONSOLE) return 0; + /* + * Setup any port IO, connect any baud rate generators, + * etc. This is expected to be handled by board + * dependant code + */ + if (pinfo->set_lineif) + pinfo->set_lineif(pinfo); + if (IS_SMC(pinfo)) { pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); @@ -1019,58 +988,6 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { }, }; -int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) -{ - struct resource *r; - struct fs_uart_platform_info *pdata = pdev->dev.platform_data; - int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */ - struct uart_cpm_port *pinfo; - int line; - u32 mem, pram; - - line = cpm_uart_id2nr(idx); - if(line < 0) { - printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx); - return -1; - } - - pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx]; - - pinfo->brg = pdata->brg; - - if (!is_con) { - pinfo->port.line = line; - pinfo->port.flags = UPF_BOOT_AUTOCONF; - } - - if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"))) - return -EINVAL; - mem = r->start; - - if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"))) - return -EINVAL; - pram = r->start; - - if(idx > fsid_smc2_uart) { - pinfo->sccp = (scc_t *)mem; - pinfo->sccup = (scc_uart_t *)pram; - } else { - pinfo->smcp = (smc_t *)mem; - pinfo->smcup = (smc_uart_t *)pram; - } - pinfo->tx_nrfifos = pdata->tx_num_fifo; - pinfo->tx_fifosize = pdata->tx_buf_size; - - pinfo->rx_nrfifos = pdata->rx_num_fifo; - pinfo->rx_fifosize = pdata->rx_buf_size; - - pinfo->port.uartclk = pdata->uart_clk; - pinfo->port.mapbase = (unsigned long)mem; - pinfo->port.irq = platform_get_irq(pdev, 0); - - return 0; -} - #ifdef CONFIG_SERIAL_CPM_CONSOLE /* * Print a string to the serial port trying not to disturb @@ -1110,7 +1027,7 @@ static void cpm_uart_console_write(struct console *co, const char *s, * If the buffer address is in the CPM DPRAM, don't * convert it. */ - cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + cp = cpm2cpu_addr(bdp->cbd_bufaddr); *cp = *s; @@ -1127,7 +1044,7 @@ static void cpm_uart_console_write(struct console *co, const char *s, while ((bdp->cbd_sc & BD_SC_READY) != 0) ; - cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + cp = cpm2cpu_addr(bdp->cbd_bufaddr); *cp = 13; bdp->cbd_datlen = 1; @@ -1150,7 +1067,9 @@ static void cpm_uart_console_write(struct console *co, const char *s, pinfo->tx_cur = (volatile cbd_t *) bdp; } - +/* + * Setup console. Be careful is called early ! + */ static int __init cpm_uart_console_setup(struct console *co, char *options) { struct uart_port *port; @@ -1161,29 +1080,9 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) int flow = 'n'; int ret; - struct fs_uart_platform_info *pdata; - struct platform_device* pdev = early_uart_get_pdev(co->index); - - if (!pdev) { - pr_info("cpm_uart: console: compat mode\n"); - /* compatibility - will be cleaned up */ - cpm_uart_init_portdesc(); - } - port = (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; pinfo = (struct uart_cpm_port *)port; - if (!pdev) { - if (pinfo->set_lineif) - pinfo->set_lineif(pinfo); - } else { - pdata = pdev->dev.platform_data; - if (pdata) - if (pdata->init_ioports) - pdata->init_ioports(); - - cpm_uart_drv_get_platform_data(pdev, 1); - } pinfo->flags |= FLAG_CONSOLE; @@ -1198,6 +1097,14 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) baud = 9600; } + /* + * Setup any port IO, connect any baud rate generators, + * etc. This is expected to be handled by board + * dependant code + */ + if (pinfo->set_lineif) + pinfo->set_lineif(pinfo); + if (IS_SMC(pinfo)) { pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); @@ -1236,8 +1143,11 @@ static struct console cpm_scc_uart_console = { int __init cpm_uart_console_init(void) { - register_console(&cpm_scc_uart_console); - return 0; + int ret = cpm_uart_init_portdesc(); + + if (!ret) + register_console(&cpm_scc_uart_console); + return ret; } console_initcall(cpm_uart_console_init); @@ -1255,129 +1165,44 @@ static struct uart_driver cpm_reg = { .minor = SERIAL_CPM_MINOR, .cons = CPM_UART_CONSOLE, }; -static int cpm_uart_drv_probe(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fs_uart_platform_info *pdata; - int ret = -ENODEV; - - if(!pdev) { - printk(KERN_ERR"CPM UART: platform data missing!\n"); - return ret; - } - - pdata = pdev->dev.platform_data; - pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no)); - - if ((ret = cpm_uart_drv_get_platform_data(pdev, 0))) - return ret; - - if (pdata->init_ioports) - pdata->init_ioports(); - - ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); - - return ret; -} - -static int cpm_uart_drv_remove(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fs_uart_platform_info *pdata = pdev->dev.platform_data; - - pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n", - cpm_uart_id2nr(pdata->fs_no)); - - uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); - return 0; -} - -static struct device_driver cpm_smc_uart_driver = { - .name = "fsl-cpm-smc:uart", - .bus = &platform_bus_type, - .probe = cpm_uart_drv_probe, - .remove = cpm_uart_drv_remove, -}; - -static struct device_driver cpm_scc_uart_driver = { - .name = "fsl-cpm-scc:uart", - .bus = &platform_bus_type, - .probe = cpm_uart_drv_probe, - .remove = cpm_uart_drv_remove, -}; -/* - This is supposed to match uart devices on platform bus, - */ -static int match_is_uart (struct device* dev, void* data) +static int __init cpm_uart_init(void) { - struct platform_device* pdev = container_of(dev, struct platform_device, dev); - int ret = 0; - /* this was setfunc as uart */ - if(strstr(pdev->name,":uart")) { - ret = 1; - } - return ret; -} - + int ret, i; -static int cpm_uart_init(void) { + printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n"); - int ret; - int i; - struct device *dev; - printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n"); - - /* lookup the bus for uart devices */ - dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart); - - /* There are devices on the bus - all should be OK */ - if (dev) { - cpm_uart_count(); - cpm_reg.nr = cpm_uart_nr; - - if (!(ret = uart_register_driver(&cpm_reg))) { - if ((ret = driver_register(&cpm_smc_uart_driver))) { - uart_unregister_driver(&cpm_reg); - return ret; - } - if ((ret = driver_register(&cpm_scc_uart_driver))) { - driver_unregister(&cpm_scc_uart_driver); - uart_unregister_driver(&cpm_reg); - } - } - } else { - /* No capable platform devices found - falling back to legacy mode */ - pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n"); - pr_info( - "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n"); #ifndef CONFIG_SERIAL_CPM_CONSOLE - ret = cpm_uart_init_portdesc(); - if (ret) - return ret; + ret = cpm_uart_init_portdesc(); + if (ret) + return ret; #endif - cpm_reg.nr = cpm_uart_nr; - ret = uart_register_driver(&cpm_reg); + cpm_reg.nr = cpm_uart_nr; + ret = uart_register_driver(&cpm_reg); - if (ret) - return ret; - - for (i = 0; i < cpm_uart_nr; i++) { - int con = cpm_uart_port_map[i]; - cpm_uart_ports[con].port.line = i; - cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; - uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); - } + if (ret) + return ret; + for (i = 0; i < cpm_uart_nr; i++) { + int con = cpm_uart_port_map[i]; + cpm_uart_ports[con].port.line = i; + cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; + uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); } + return ret; } static void __exit cpm_uart_exit(void) { - driver_unregister(&cpm_scc_uart_driver); - driver_unregister(&cpm_smc_uart_driver); + int i; + + for (i = 0; i < cpm_uart_nr; i++) { + int con = cpm_uart_port_map[i]; + uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port); + } + uart_unregister_driver(&cpm_reg); } diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 17406a05c..d789ee55c 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -8,8 +8,6 @@ * * Copyright (C) 2004 Freescale Semiconductor, Inc. * (C) 2004 Intracom, S.A. - * (C) 2006 MontaVista Software, Inc. - * Vitaly Bordug * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -83,11 +81,58 @@ void cpm_line_cr_cmd(int line, int cmd) void smc1_lineif(struct uart_cpm_port *pinfo) { + volatile cpm8xx_t *cp = cpmp; + + (void)cp; /* fix warning */ +#if defined (CONFIG_MPC885ADS) + /* Enable SMC1 transceivers */ + { + cp->cp_pepar |= 0x000000c0; + cp->cp_pedir &= ~0x000000c0; + cp->cp_peso &= ~0x00000040; + cp->cp_peso |= 0x00000080; + } +#elif defined (CONFIG_MPC86XADS) + unsigned int iobits = 0x000000c0; + + if (!pinfo->is_portb) { + cp->cp_pbpar |= iobits; + cp->cp_pbdir &= ~iobits; + cp->cp_pbodr &= ~iobits; + } else { + ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits; + ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits; + ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; + } +#endif pinfo->brg = 1; } void smc2_lineif(struct uart_cpm_port *pinfo) { + volatile cpm8xx_t *cp = cpmp; + + (void)cp; /* fix warning */ +#if defined (CONFIG_MPC885ADS) + cp->cp_pepar |= 0x00000c00; + cp->cp_pedir &= ~0x00000c00; + cp->cp_peso &= ~0x00000400; + cp->cp_peso |= 0x00000800; +#elif defined (CONFIG_MPC86XADS) + unsigned int iobits = 0x00000c00; + + if (!pinfo->is_portb) { + cp->cp_pbpar |= iobits; + cp->cp_pbdir &= ~iobits; + cp->cp_pbodr &= ~iobits; + } else { + ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits; + ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits; + ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; + } + +#endif + pinfo->brg = 2; } @@ -146,7 +191,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) /* was hostalloc but changed cause it blows away the */ /* large tlb mapping when pinning the kernel area */ mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); - dma_addr = (u32)mem_addr; + dma_addr = 0; } else mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, GFP_KERNEL); @@ -159,9 +204,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) } pinfo->dp_addr = dp_offset; - pinfo->mem_addr = mem_addr; /* virtual address*/ - pinfo->dma_addr = dma_addr; /* physical address*/ - pinfo->mem_size = memsz; + pinfo->mem_addr = mem_addr; + pinfo->dma_addr = dma_addr; pinfo->rx_buf = mem_addr; pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index cdba12825..fd9e53ed3 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -8,8 +8,6 @@ * * Copyright (C) 2004 Freescale Semiconductor, Inc. * (C) 2004 Intracom, S.A. - * (C) 2006 MontaVista Software, Inc. - * Vitaly Bordug * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -144,12 +142,21 @@ void scc2_lineif(struct uart_cpm_port *pinfo) * be supported in a sane fashion. */ #ifndef CONFIG_STX_GP3 +#ifdef CONFIG_MPC8560_ADS + volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + io->iop_ppard |= 0x00000018; + io->iop_psord &= ~0x00000008; /* Rx */ + io->iop_psord &= ~0x00000010; /* Tx */ + io->iop_pdird &= ~0x00000008; /* Rx */ + io->iop_pdird |= 0x00000010; /* Tx */ +#else volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; io->iop_pparb |= 0x008b0000; io->iop_pdirb |= 0x00880000; io->iop_psorb |= 0x00880000; io->iop_pdirb &= ~0x00030000; io->iop_psorb &= ~0x00030000; +#endif #endif cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff; cpm2_immr->im_cpmux.cmx_scr |= 0x00090000; @@ -211,10 +218,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); - if (is_con) { + if (is_con) mem_addr = alloc_bootmem(memsz); - dma_addr = virt_to_bus(mem_addr); - } else mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, GFP_KERNEL); @@ -229,7 +234,6 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) pinfo->dp_addr = dp_offset; pinfo->mem_addr = mem_addr; pinfo->dma_addr = dma_addr; - pinfo->mem_size = memsz; pinfo->rx_buf = mem_addr; pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 89700141f..be12623d8 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c @@ -481,6 +481,8 @@ static char *serial_version = "$Revision: 1.25 $"; #include "serial_compat.h" #endif +#define _INLINE_ inline + struct tty_driver *serial_driver; /* serial subtype definitions */ @@ -589,6 +591,8 @@ static void rs_throttle(struct tty_struct * tty); static void rs_wait_until_sent(struct tty_struct *tty, int timeout); static int rs_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count); +extern _INLINE_ int rs_raw_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count); #ifdef CONFIG_ETRAX_RS485 static int e100_write_rs485(struct tty_struct * tty, int from_user, const unsigned char *buf, int count); @@ -1534,7 +1538,8 @@ e100_enable_rxdma_irq(struct e100_serial *info) /* the tx DMA uses only dma_descr interrupt */ -static void e100_disable_txdma_irq(struct e100_serial *info) +static _INLINE_ void +e100_disable_txdma_irq(struct e100_serial *info) { #ifdef SERIAL_DEBUG_INTR printk("txdma_irq(%d): 0\n",info->line); @@ -1543,7 +1548,8 @@ static void e100_disable_txdma_irq(struct e100_serial *info) *R_IRQ_MASK2_CLR = info->irq; } -static void e100_enable_txdma_irq(struct e100_serial *info) +static _INLINE_ void +e100_enable_txdma_irq(struct e100_serial *info) { #ifdef SERIAL_DEBUG_INTR printk("txdma_irq(%d): 1\n",info->line); @@ -1552,7 +1558,8 @@ static void e100_enable_txdma_irq(struct e100_serial *info) *R_IRQ_MASK2_SET = info->irq; } -static void e100_disable_txdma_channel(struct e100_serial *info) +static _INLINE_ void +e100_disable_txdma_channel(struct e100_serial *info) { unsigned long flags; @@ -1592,7 +1599,8 @@ static void e100_disable_txdma_channel(struct e100_serial *info) } -static void e100_enable_txdma_channel(struct e100_serial *info) +static _INLINE_ void +e100_enable_txdma_channel(struct e100_serial *info) { unsigned long flags; @@ -1617,7 +1625,8 @@ static void e100_enable_txdma_channel(struct e100_serial *info) restore_flags(flags); } -static void e100_disable_rxdma_channel(struct e100_serial *info) +static _INLINE_ void +e100_disable_rxdma_channel(struct e100_serial *info) { unsigned long flags; @@ -1656,7 +1665,8 @@ static void e100_disable_rxdma_channel(struct e100_serial *info) } -static void e100_enable_rxdma_channel(struct e100_serial *info) +static _INLINE_ void +e100_enable_rxdma_channel(struct e100_serial *info) { unsigned long flags; @@ -1903,7 +1913,9 @@ rs_start(struct tty_struct *tty) * This routine is used by the interrupt handler to schedule * processing in the software interrupt portion of the driver. */ -static void rs_sched_event(struct e100_serial *info, int event) +static _INLINE_ void +rs_sched_event(struct e100_serial *info, + int event) { if (info->event & (1 << event)) return; @@ -2143,9 +2155,8 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl return 1; } -static unsigned int handle_descr_data(struct e100_serial *info, - struct etrax_dma_descr *descr, - unsigned int recvl) +extern _INLINE_ unsigned int +handle_descr_data(struct e100_serial *info, struct etrax_dma_descr *descr, unsigned int recvl) { struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer; @@ -2171,7 +2182,8 @@ static unsigned int handle_descr_data(struct e100_serial *info, return recvl; } -static unsigned int handle_all_descr_data(struct e100_serial *info) +static _INLINE_ unsigned int +handle_all_descr_data(struct e100_serial *info) { struct etrax_dma_descr *descr; unsigned int recvl; @@ -2218,7 +2230,8 @@ static unsigned int handle_all_descr_data(struct e100_serial *info) return ret; } -static void receive_chars_dma(struct e100_serial *info) +static _INLINE_ void +receive_chars_dma(struct e100_serial *info) { struct tty_struct *tty; unsigned char rstat; @@ -2279,7 +2292,8 @@ static void receive_chars_dma(struct e100_serial *info) *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); } -static int start_recv_dma(struct e100_serial *info) +static _INLINE_ int +start_recv_dma(struct e100_serial *info) { struct etrax_dma_descr *descr = info->rec_descr; struct etrax_recv_buffer *buffer; @@ -2334,6 +2348,11 @@ start_receive(struct e100_serial *info) } +static _INLINE_ void +status_handle(struct e100_serial *info, unsigned short status) +{ +} + /* the bits in the MASK2 register are laid out like this: DMAI_EOP DMAI_DESCR DMAO_EOP DMAO_DESCR where I is the input channel and O is the output channel for the port. @@ -2435,7 +2454,8 @@ rec_interrupt(int irq, void *dev_id, struct pt_regs * regs) return IRQ_RETVAL(handled); } /* rec_interrupt */ -static int force_eop_if_needed(struct e100_serial *info) +static _INLINE_ int +force_eop_if_needed(struct e100_serial *info) { /* We check data_avail bit to determine if data has * arrived since last time @@ -2479,7 +2499,8 @@ static int force_eop_if_needed(struct e100_serial *info) return 1; } -static void flush_to_flip_buffer(struct e100_serial *info) +extern _INLINE_ void +flush_to_flip_buffer(struct e100_serial *info) { struct tty_struct *tty; struct etrax_recv_buffer *buffer; @@ -2590,7 +2611,8 @@ static void flush_to_flip_buffer(struct e100_serial *info) tty_flip_buffer_push(tty); } -static void check_flush_timeout(struct e100_serial *info) +static _INLINE_ void +check_flush_timeout(struct e100_serial *info) { /* Flip what we've got (if we can) */ flush_to_flip_buffer(info); @@ -2719,7 +2741,7 @@ TODO: The break will be delayed until an F or V character is received. */ -static +extern _INLINE_ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) { unsigned long data_read; @@ -2853,7 +2875,8 @@ more_data: return info; } -static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) +extern _INLINE_ +struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) { unsigned char rstat; @@ -2972,7 +2995,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) return info; } /* handle_ser_rx_interrupt */ -static void handle_ser_tx_interrupt(struct e100_serial *info) +extern _INLINE_ void handle_ser_tx_interrupt(struct e100_serial *info) { unsigned long flags; @@ -3598,8 +3621,9 @@ rs_flush_chars(struct tty_struct *tty) restore_flags(flags); } -static int rs_raw_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) +extern _INLINE_ int +rs_raw_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) { int c, ret = 0; struct e100_serial *info = (struct e100_serial *)tty->driver_data; @@ -4686,7 +4710,7 @@ rs_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static int line_info(char *buf, struct e100_serial *info) +extern _INLINE_ int line_info(char *buf, struct e100_serial *info) { char stat_buf[30]; int ret; diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index bf71bad5c..ba5541de6 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c @@ -674,12 +674,11 @@ static void dz_reset(struct dz_port *dport) } #ifdef CONFIG_SERIAL_DZ_CONSOLE -static void dz_console_putchar(struct uart_port *port, int ch) +static void dz_console_put_char(struct dz_port *dport, unsigned char ch) { - struct dz_port *dport = (struct dz_port *)uport; unsigned long flags; int loops = 2500; - unsigned short tmp = (unsigned char)ch; + unsigned short tmp = ch; /* this code sends stuff out to serial device - spinning its wheels and waiting. */ @@ -695,7 +694,6 @@ static void dz_console_putchar(struct uart_port *port, int ch) spin_unlock_irqrestore(&dport->port.lock, flags); } - /* * ------------------------------------------------------------------- * dz_console_print () @@ -712,7 +710,11 @@ static void dz_console_print(struct console *cons, #ifdef DEBUG_DZ prom_printf((char *) str); #endif - uart_console_write(&dport->port, str, count, dz_console_putchar); + while (count--) { + if (*str == '\n') + dz_console_put_char(dport, '\r'); + dz_console_put_char(dport, *str++); + } } static int __init dz_console_setup(struct console *co, char *options) diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index d202eb4f3..4d53fb5ca 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -45,7 +45,6 @@ #include #include #include -#include /* We've been assigned a range on the "Low-density serial ports" major */ #define SERIAL_IMX_MAJOR 204 @@ -74,8 +73,7 @@ struct imx_port { struct uart_port port; struct timer_list timer; unsigned int old_status; - int txirq,rxirq,rtsirq; - int have_rtscts:1; + int txirq,rxirq,rtsirq; }; /* @@ -493,12 +491,8 @@ imx_set_termios(struct uart_port *port, struct termios *termios, ucr2 = UCR2_SRST | UCR2_IRTS; if (termios->c_cflag & CRTSCTS) { - if( sport->have_rtscts ) { - ucr2 &= ~UCR2_IRTS; - ucr2 |= UCR2_CTSC; - } else { - termios->c_cflag &= ~CRTSCTS; - } + ucr2 &= ~UCR2_IRTS; + ucr2 |= UCR2_CTSC; } if (termios->c_cflag & CSTOPB) @@ -725,16 +719,30 @@ static void __init imx_init_ports(void) imx_ports[i].timer.function = imx_timeout; imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; } + + imx_gpio_mode(PC9_PF_UART1_CTS); + imx_gpio_mode(PC10_PF_UART1_RTS); + imx_gpio_mode(PC11_PF_UART1_TXD); + imx_gpio_mode(PC12_PF_UART1_RXD); + imx_gpio_mode(PB28_PF_UART2_CTS); + imx_gpio_mode(PB29_PF_UART2_RTS); + + imx_gpio_mode(PB30_PF_UART2_TXD); + imx_gpio_mode(PB31_PF_UART2_RXD); + +#if 0 /* We don't need these, on the mx1 the _modem_ side of the uart + * is implemented. + */ + imx_gpio_mode(PD7_AF_UART2_DTR); + imx_gpio_mode(PD8_AF_UART2_DCD); + imx_gpio_mode(PD9_AF_UART2_RI); + imx_gpio_mode(PD10_AF_UART2_DSR); +#endif + + } #ifdef CONFIG_SERIAL_IMX_CONSOLE -static void imx_console_putchar(struct uart_port *port, int ch) -{ - struct imx_port *sport = (struct imx_port *)port; - while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) - barrier(); - URTX0((u32)sport->port.membase) = ch; -} /* * Interrupts are disabled on entering @@ -743,7 +751,7 @@ static void imx_console_write(struct console *co, const char *s, unsigned int count) { struct imx_port *sport = &imx_ports[co->index]; - unsigned int old_ucr1, old_ucr2; + unsigned int old_ucr1, old_ucr2, i; /* * First, save UCR1/2 and then disable interrupts @@ -756,7 +764,22 @@ imx_console_write(struct console *co, const char *s, unsigned int count) & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; - uart_console_write(&sport->port, s, count, imx_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + + while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) + barrier(); + + URTX0((u32)sport->port.membase) = s[i]; + + if (s[i] == '\n') { + while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) + barrier(); + URTX0((u32)sport->port.membase) = '\r'; + } + } /* * Finally, wait for transmitter to become empty @@ -917,14 +940,7 @@ static int serial_imx_resume(struct platform_device *dev) static int serial_imx_probe(struct platform_device *dev) { - struct imxuart_platform_data *pdata; - imx_ports[dev->id].port.dev = &dev->dev; - - pdata = (struct imxuart_platform_data *)dev->dev.platform_data; - if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) - imx_ports[dev->id].have_rtscts = 1; - uart_add_one_port(&imx_reg, &imx_ports[dev->id].port); platform_set_drvdata(dev, &imx_ports[dev->id]); return 0; diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index c620209d7..a37579ce6 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 2003-2005 Silicon Graphics, Inc. All Rights Reserved. */ @@ -323,12 +323,9 @@ static unsigned int Num_of_ioc4_cards; #define IOC4_FIFO_CHARS 255 /* Device name we're using */ -#define DEVICE_NAME_RS232 "ttyIOC" -#define DEVICE_NAME_RS422 "ttyAIOC" -#define DEVICE_MAJOR 204 -#define DEVICE_MINOR_RS232 50 -#define DEVICE_MINOR_RS422 84 - +#define DEVICE_NAME "ttyIOC" +#define DEVICE_MAJOR 204 +#define DEVICE_MINOR 50 /* register offsets */ #define IOC4_SERIAL_OFFSET 0x300 @@ -344,8 +341,10 @@ static unsigned int Num_of_ioc4_cards; #define MAX_BAUD_SUPPORTED 115200 /* protocol types supported */ -#define PROTO_RS232 3 -#define PROTO_RS422 7 +enum sio_proto { + PROTO_RS232, + PROTO_RS422 +}; /* Notification types */ #define N_DATA_READY 0x01 @@ -396,17 +395,11 @@ static unsigned int Num_of_ioc4_cards; /* * This is the entry saved by the driver - one per card */ - -#define UART_PORT_MIN 0 -#define UART_PORT_RS232 UART_PORT_MIN -#define UART_PORT_RS422 1 -#define UART_PORT_COUNT 2 /* one for each mode */ - struct ioc4_control { int ic_irq; struct { - /* uart ports are allocated here - 1 for rs232, 1 for rs422 */ - struct uart_port icp_uart_port[UART_PORT_COUNT]; + /* uart ports are allocated here */ + struct uart_port icp_uart_port; /* Handy reference material */ struct ioc4_port *icp_port; } ic_port[IOC4_NUM_SERIAL_PORTS]; @@ -450,9 +443,7 @@ struct ioc4_soft { /* Local port info for each IOC4 serial ports */ struct ioc4_port { - struct uart_port *ip_port; /* current active port ptr */ - /* Ptrs for all ports */ - struct uart_port *ip_all_ports[UART_PORT_COUNT]; + struct uart_port *ip_port; /* Back ptrs for this port */ struct ioc4_control *ip_control; struct pci_dev *ip_pdev; @@ -511,9 +502,6 @@ struct ioc4_port { #define DCD_ON 0x02 #define LOWAT_WRITTEN 0x04 #define READ_ABORTED 0x08 -#define PORT_ACTIVE 0x10 -#define PORT_INACTIVE 0 /* This is the value when "off" */ - /* Since each port has different register offsets and bitmasks * for everything, we'll store those that we need in tables so we @@ -635,23 +623,6 @@ struct ring_buffer { static void receive_chars(struct uart_port *); static void handle_intr(void *arg, uint32_t sio_ir); -/* - * port_is_active - determines if this port is currently active - * @port: ptr to soft struct for this port - * @uart_port: uart port to test for - */ -static inline int port_is_active(struct ioc4_port *port, - struct uart_port *uart_port) -{ - if (port) { - if ((port->ip_flags & PORT_ACTIVE) - && (port->ip_port == uart_port)) - return 1; - } - return 0; -} - - /** * write_ireg - write the interrupt regs * @ioc4_soft: ptr to soft struct for this port @@ -737,33 +708,19 @@ static int set_baud(struct ioc4_port *port, int baud) /** * get_ioc4_port - given a uart port, return the control structure * @port: uart port - * @set: set this port as current */ -static struct ioc4_port *get_ioc4_port(struct uart_port *the_port, int set) +static struct ioc4_port *get_ioc4_port(struct uart_port *the_port) { struct ioc4_driver_data *idd = dev_get_drvdata(the_port->dev); struct ioc4_control *control = idd->idd_serial_data; - struct ioc4_port *port; - int port_num, port_type; + int ii; if (control) { - for ( port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS; - port_num++ ) { - port = control->ic_port[port_num].icp_port; - if (!port) + for ( ii = 0; ii < IOC4_NUM_SERIAL_PORTS; ii++ ) { + if (!control->ic_port[ii].icp_port) continue; - for (port_type = UART_PORT_MIN; - port_type < UART_PORT_COUNT; - port_type++) { - if (the_port == port->ip_all_ports - [port_type]) { - /* set local copy */ - if (set) { - port->ip_port = the_port; - } - return port; - } - } + if (the_port == control->ic_port[ii].icp_port->ip_port) + return control->ic_port[ii].icp_port; } } return NULL; @@ -989,7 +946,6 @@ intr_connect(struct ioc4_soft *soft, int type, * @arg: handler arg * @regs: registers */ - static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) { struct ioc4_soft *soft; @@ -997,7 +953,7 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) int xx, num_intrs = 0; int intr_type; int handled = 0; - struct ioc4_intr_info *intr_info; + struct ioc4_intr_info *ii; soft = arg; for (intr_type = 0; intr_type < IOC4_NUM_INTR_TYPES; intr_type++) { @@ -1010,13 +966,13 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) * which interrupt bits are set. */ for (xx = 0; xx < num_intrs; xx++) { - intr_info = &soft->is_intr_type[intr_type].is_intr_info[xx]; - if ((this_mir = this_ir & intr_info->sd_bits)) { + ii = &soft->is_intr_type[intr_type].is_intr_info[xx]; + if ((this_mir = this_ir & ii->sd_bits)) { /* Disable owned interrupts, call handler */ handled++; - write_ireg(soft, intr_info->sd_bits, IOC4_W_IEC, + write_ireg(soft, ii->sd_bits, IOC4_W_IEC, intr_type); - intr_info->sd_intr(intr_info->sd_info, this_mir); + ii->sd_intr(ii->sd_info, this_mir); this_ir &= ~this_mir; } } @@ -1024,6 +980,7 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) #ifdef DEBUG_INTERRUPTS { struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr; + spinlock_t *lp = &soft->is_ir_lock; unsigned long flag; spin_lock_irqsave(&soft->is_ir_lock, flag); @@ -1220,7 +1177,7 @@ static inline int local_open(struct ioc4_port *port) { int spiniter = 0; - port->ip_flags = PORT_ACTIVE; + port->ip_flags = 0; /* Pause the DMA interface if necessary */ if (port->ip_sscr & IOC4_SSCR_DMA_EN) { @@ -1230,7 +1187,6 @@ static inline int local_open(struct ioc4_port *port) & IOC4_SSCR_PAUSE_STATE) == 0) { spiniter++; if (spiniter > MAXITER) { - port->ip_flags = PORT_INACTIVE; return -1; } } @@ -1550,13 +1506,14 @@ static int set_notification(struct ioc4_port *port, int mask, int set_on) /** * set_mcr - set the master control reg * @the_port: port to use + * @set: set ? * @mask1: mcr mask * @mask2: shadow mask */ -static inline int set_mcr(struct uart_port *the_port, +static inline int set_mcr(struct uart_port *the_port, int set, int mask1, int mask2) { - struct ioc4_port *port = get_ioc4_port(the_port, 0); + struct ioc4_port *port = get_ioc4_port(the_port); uint32_t shadow; int spiniter = 0; char mcr; @@ -1579,9 +1536,13 @@ static inline int set_mcr(struct uart_port *the_port, mcr = (shadow & 0xff000000) >> 24; /* Set new value */ - mcr |= mask1; - shadow |= mask2; - + if (set) { + mcr |= mask1; + shadow |= mask2; + } else { + mcr &= ~mask1; + shadow &= ~mask2; + } writeb(mcr, &port->ip_uart_regs->i4u_mcr); writel(shadow, &port->ip_serial_regs->shadow); @@ -1597,7 +1558,7 @@ static inline int set_mcr(struct uart_port *the_port, * @port: port to use * @proto: protocol to use */ -static int ioc4_set_proto(struct ioc4_port *port, int proto) +static int ioc4_set_proto(struct ioc4_port *port, enum sio_proto proto) { struct hooks *hooks = port->ip_hooks; @@ -1628,7 +1589,7 @@ static void transmit_chars(struct uart_port *the_port) int result; char *start; struct tty_struct *tty; - struct ioc4_port *port = get_ioc4_port(the_port, 0); + struct ioc4_port *port = get_ioc4_port(the_port); struct uart_info *info; if (!the_port) @@ -1684,7 +1645,7 @@ static void ioc4_change_speed(struct uart_port *the_port, struct termios *new_termios, struct termios *old_termios) { - struct ioc4_port *port = get_ioc4_port(the_port, 0); + struct ioc4_port *port = get_ioc4_port(the_port); int baud, bits; unsigned cflag; int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; @@ -1791,7 +1752,7 @@ static inline int ic4_startup_local(struct uart_port *the_port) if (!the_port) return -1; - port = get_ioc4_port(the_port, 0); + port = get_ioc4_port(the_port); if (!port) return -1; @@ -1799,9 +1760,6 @@ static inline int ic4_startup_local(struct uart_port *the_port) local_open(port); - /* set the protocol - mapbase has the port type */ - ioc4_set_proto(port, the_port->mapbase); - /* set the speed of the serial port */ ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0); @@ -1810,17 +1768,17 @@ static inline int ic4_startup_local(struct uart_port *the_port) /* * ioc4_cb_output_lowat - called when the output low water mark is hit - * @the_port: port to output + * @port: port to output */ -static void ioc4_cb_output_lowat(struct uart_port *the_port) +static void ioc4_cb_output_lowat(struct ioc4_port *port) { unsigned long pflags; /* ip_lock is set on the call here */ - if (the_port) { - spin_lock_irqsave(&the_port->lock, pflags); - transmit_chars(the_port); - spin_unlock_irqrestore(&the_port->lock, pflags); + if (port->ip_port) { + spin_lock_irqsave(&port->ip_port->lock, pflags); + transmit_chars(port->ip_port); + spin_unlock_irqrestore(&port->ip_port->lock, pflags); } } @@ -1965,7 +1923,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) &port->ip_mem->sio_ir.raw); if (port->ip_notify & N_OUTPUT_LOWAT) - ioc4_cb_output_lowat(port->ip_port); + ioc4_cb_output_lowat(port); } /* Handle tx_mt. Must come after tx_explicit. */ @@ -1978,7 +1936,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) * So send the notification now. */ if (port->ip_notify & N_OUTPUT_LOWAT) { - ioc4_cb_output_lowat(port->ip_port); + ioc4_cb_output_lowat(port); /* We need to reload the sio_ir since the lowat * call may have caused another write to occur, @@ -2065,7 +2023,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf, int len) { int prod_ptr, cons_ptr, total; - struct ioc4_port *port = get_ioc4_port(the_port, 0); + struct ioc4_port *port = get_ioc4_port(the_port); struct ring *inring; struct ring_entry *entry; struct hooks *hooks = port->ip_hooks; @@ -2377,27 +2335,17 @@ static void receive_chars(struct uart_port *the_port) */ static const char *ic4_type(struct uart_port *the_port) { - if (the_port->mapbase == PROTO_RS232) - return "SGI IOC4 Serial [rs232]"; - else - return "SGI IOC4 Serial [rs422]"; + return "SGI IOC4 Serial"; } /** - * ic4_tx_empty - Is the transmitter empty? - * @port: Port to operate on + * ic4_tx_empty - Is the transmitter empty? We pretend we're always empty + * @port: Port to operate on (we ignore since we always return 1) * */ static unsigned int ic4_tx_empty(struct uart_port *the_port) { - struct ioc4_port *port = get_ioc4_port(the_port, 0); - unsigned int ret = 0; - - if (port_is_active(port, the_port)) { - if (readl(&port->ip_serial_regs->shadow) & IOC4_SHADOW_TEMT) - ret = TIOCSER_TEMT; - } - return ret; + return 1; } /** @@ -2407,10 +2355,6 @@ static unsigned int ic4_tx_empty(struct uart_port *the_port) */ static void ic4_stop_tx(struct uart_port *the_port) { - struct ioc4_port *port = get_ioc4_port(the_port, 0); - - if (port_is_active(port, the_port)) - set_notification(port, N_OUTPUT_LOWAT, 0); } /** @@ -2433,12 +2377,11 @@ static void ic4_shutdown(struct uart_port *the_port) struct ioc4_port *port; struct uart_info *info; - port = get_ioc4_port(the_port, 0); + port = get_ioc4_port(the_port); if (!port) return; info = the_port->info; - port->ip_port = NULL; wake_up_interruptible(&info->delta_msr_wait); @@ -2447,7 +2390,6 @@ static void ic4_shutdown(struct uart_port *the_port) spin_lock_irqsave(&the_port->lock, port_flags); set_notification(port, N_ALL, 0); - port->ip_flags = PORT_INACTIVE; spin_unlock_irqrestore(&the_port->lock, port_flags); } @@ -2460,11 +2402,6 @@ static void ic4_shutdown(struct uart_port *the_port) static void ic4_set_mctrl(struct uart_port *the_port, unsigned int mctrl) { unsigned char mcr = 0; - struct ioc4_port *port; - - port = get_ioc4_port(the_port, 0); - if (!port_is_active(port, the_port)) - return; if (mctrl & TIOCM_RTS) mcr |= UART_MCR_RTS; @@ -2477,7 +2414,7 @@ static void ic4_set_mctrl(struct uart_port *the_port, unsigned int mctrl) if (mctrl & TIOCM_LOOP) mcr |= UART_MCR_LOOP; - set_mcr(the_port, mcr, IOC4_SHADOW_DTR); + set_mcr(the_port, 1, mcr, IOC4_SHADOW_DTR); } /** @@ -2487,11 +2424,11 @@ static void ic4_set_mctrl(struct uart_port *the_port, unsigned int mctrl) */ static unsigned int ic4_get_mctrl(struct uart_port *the_port) { - struct ioc4_port *port = get_ioc4_port(the_port, 0); + struct ioc4_port *port = get_ioc4_port(the_port); uint32_t shadow; unsigned int ret = 0; - if (!port_is_active(port, the_port)) + if (!port) return 0; shadow = readl(&port->ip_serial_regs->shadow); @@ -2511,9 +2448,9 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port) */ static void ic4_start_tx(struct uart_port *the_port) { - struct ioc4_port *port = get_ioc4_port(the_port, 0); + struct ioc4_port *port = get_ioc4_port(the_port); - if (port_is_active(port, the_port)) { + if (port) { set_notification(port, N_OUTPUT_LOWAT, 1); enable_intrs(port, port->ip_hooks->intr_tx_mt); } @@ -2530,7 +2467,7 @@ static void ic4_break_ctl(struct uart_port *the_port, int break_state) } /** - * ic4_startup - Start up the serial port + * ic4_startup - Start up the serial port - always return 0 (We're always on) * @port: Port to operate on * */ @@ -2542,16 +2479,17 @@ static int ic4_startup(struct uart_port *the_port) struct uart_info *info; unsigned long port_flags; - if (!the_port) + if (!the_port) { return -ENODEV; - port = get_ioc4_port(the_port, 1); - if (!port) + } + port = get_ioc4_port(the_port); + if (!port) { return -ENODEV; + } info = the_port->info; control = port->ip_control; if (!control) { - port->ip_port = NULL; return -ENODEV; } @@ -2613,104 +2551,28 @@ static struct uart_ops ioc4_ops = { * Boot-time initialization code */ -static struct uart_driver ioc4_uart_rs232 = { +static struct uart_driver ioc4_uart = { .owner = THIS_MODULE, - .driver_name = "ioc4_serial_rs232", - .dev_name = DEVICE_NAME_RS232, + .driver_name = "ioc4_serial", + .dev_name = DEVICE_NAME, .major = DEVICE_MAJOR, - .minor = DEVICE_MINOR_RS232, + .minor = DEVICE_MINOR, .nr = IOC4_NUM_CARDS * IOC4_NUM_SERIAL_PORTS, }; -static struct uart_driver ioc4_uart_rs422 = { - .owner = THIS_MODULE, - .driver_name = "ioc4_serial_rs422", - .dev_name = DEVICE_NAME_RS422, - .major = DEVICE_MAJOR, - .minor = DEVICE_MINOR_RS422, - .nr = IOC4_NUM_CARDS * IOC4_NUM_SERIAL_PORTS, -}; - - /** - * ioc4_serial_remove_one - detach function - * - * @idd: IOC4 master module data for this IOC4 - */ - -static int ioc4_serial_remove_one(struct ioc4_driver_data *idd) -{ - int port_num, port_type; - struct ioc4_control *control; - struct uart_port *the_port; - struct ioc4_port *port; - struct ioc4_soft *soft; - - control = idd->idd_serial_data; - - for (port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS; port_num++) { - for (port_type = UART_PORT_MIN; - port_type < UART_PORT_COUNT; - port_type++) { - the_port = &control->ic_port[port_num].icp_uart_port - [port_type]; - if (the_port) { - switch (port_type) { - case UART_PORT_RS422: - uart_remove_one_port(&ioc4_uart_rs422, - the_port); - break; - default: - case UART_PORT_RS232: - uart_remove_one_port(&ioc4_uart_rs232, - the_port); - break; - } - } - } - port = control->ic_port[port_num].icp_port; - /* we allocate in pairs */ - if (!(port_num & 1) && port) { - pci_free_consistent(port->ip_pdev, - TOTAL_RING_BUF_SIZE, - port->ip_cpu_ringbuf, - port->ip_dma_ringbuf); - kfree(port); - } - } - soft = control->ic_soft; - if (soft) { - free_irq(control->ic_irq, soft); - if (soft->is_ioc4_serial_addr) { - release_region((unsigned long) - soft->is_ioc4_serial_addr, - sizeof(struct ioc4_serial)); - } - kfree(soft); - } - kfree(control); - idd->idd_serial_data = NULL; - - return 0; -} - - -/** - * ioc4_serial_core_attach_rs232 - register with serial core + * ioc4_serial_core_attach - register with serial core * This is done during pci probing * @pdev: handle for this card */ static inline int -ioc4_serial_core_attach(struct pci_dev *pdev, int port_type) +ioc4_serial_core_attach(struct pci_dev *pdev) { struct ioc4_port *port; struct uart_port *the_port; struct ioc4_driver_data *idd = pci_get_drvdata(pdev); struct ioc4_control *control = idd->idd_serial_data; - int port_num; - int port_type_idx; - struct uart_driver *u_driver; - + int ii; DPRINT_CONFIG(("%s: attach pdev 0x%p - control 0x%p\n", __FUNCTION__, pdev, (void *)control)); @@ -2718,36 +2580,28 @@ ioc4_serial_core_attach(struct pci_dev *pdev, int port_type) if (!control) return -ENODEV; - port_type_idx = (port_type == PROTO_RS232) ? UART_PORT_RS232 - : UART_PORT_RS422; - - u_driver = (port_type == PROTO_RS232) ? &ioc4_uart_rs232 - : &ioc4_uart_rs422; - /* once around for each port on this card */ - for (port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS; port_num++) { - the_port = &control->ic_port[port_num].icp_uart_port - [port_type_idx]; - port = control->ic_port[port_num].icp_port; - port->ip_all_ports[port_type_idx] = the_port; + for (ii = 0; ii < IOC4_NUM_SERIAL_PORTS; ii++) { + the_port = &control->ic_port[ii].icp_uart_port; + port = control->ic_port[ii].icp_port; + port->ip_port = the_port; - DPRINT_CONFIG(("%s: attach the_port 0x%p / port 0x%p : type %s\n", + DPRINT_CONFIG(("%s: attach the_port 0x%p / port 0x%p\n", __FUNCTION__, (void *)the_port, - (void *)port, - port_type == PROTO_RS232 ? "rs232" : "rs422")); + (void *)port)); /* membase, iobase and mapbase just need to be non-0 */ the_port->membase = (unsigned char __iomem *)1; - the_port->iobase = (pdev->bus->number << 16) | port_num; - the_port->line = (Num_of_ioc4_cards << 2) | port_num; - the_port->mapbase = port_type; + the_port->iobase = (pdev->bus->number << 16) | ii; + the_port->line = (Num_of_ioc4_cards << 2) | ii; + the_port->mapbase = 1; the_port->type = PORT_16550A; the_port->fifosize = IOC4_FIFO_CHARS; the_port->ops = &ioc4_ops; the_port->irq = control->ic_irq; the_port->dev = &pdev->dev; spin_lock_init(&the_port->lock); - if (uart_add_one_port(u_driver, the_port) < 0) { + if (uart_add_one_port(&ioc4_uart, the_port) < 0) { printk(KERN_WARNING "%s: unable to add port %d bus %d\n", __FUNCTION__, the_port->line, pdev->bus->number); @@ -2756,6 +2610,8 @@ ioc4_serial_core_attach(struct pci_dev *pdev, int port_type) ("IOC4 serial port %d irq = %d, bus %d\n", the_port->line, the_port->irq, pdev->bus->number)); } + /* all ports are rs232 for now */ + ioc4_set_proto(port, PROTO_RS232); } return 0; } @@ -2775,8 +2631,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) int ret = 0; - DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev, - idd->idd_pci_id)); + DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev, idd->idd_pci_id)); /* request serial registers */ tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET; @@ -2798,11 +2653,11 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) goto out2; } DPRINT_CONFIG(("%s : mem 0x%p, serial 0x%p\n", - __FUNCTION__, (void *)idd->idd_misc_regs, - (void *)serial)); + __FUNCTION__, (void *)idd->idd_misc_regs, (void *)serial)); /* Get memory for the new card */ - control = kmalloc(sizeof(struct ioc4_control), GFP_KERNEL); + control = kmalloc(sizeof(struct ioc4_control) * IOC4_NUM_SERIAL_PORTS, + GFP_KERNEL); if (!control) { printk(KERN_WARNING "ioc4_attach_one" @@ -2847,7 +2702,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) /* Hook up interrupt handler */ if (!request_irq(idd->idd_pdev->irq, ioc4_intr, SA_SHIRQ, - "sgi-ioc4serial", soft)) { + "sgi-ioc4serial", (void *)soft)) { control->ic_irq = idd->idd_pdev->irq; } else { printk(KERN_WARNING @@ -2858,21 +2713,16 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) if (ret) goto out4; - /* register port with the serial core - 1 rs232, 1 rs422 */ + /* register port with the serial core */ - if ((ret = ioc4_serial_core_attach(idd->idd_pdev, PROTO_RS232))) + if ((ret = ioc4_serial_core_attach(idd->idd_pdev))) goto out4; - if ((ret = ioc4_serial_core_attach(idd->idd_pdev, PROTO_RS422))) - goto out5; - Num_of_ioc4_cards++; return ret; /* error exits that give back resources */ -out5: - ioc4_serial_remove_one(idd); out4: kfree(soft); out3: @@ -2885,6 +2735,52 @@ out1: } +/** + * ioc4_serial_remove_one - detach function + * + * @idd: IOC4 master module data for this IOC4 + */ + +int ioc4_serial_remove_one(struct ioc4_driver_data *idd) +{ + int ii; + struct ioc4_control *control; + struct uart_port *the_port; + struct ioc4_port *port; + struct ioc4_soft *soft; + + control = idd->idd_serial_data; + + for (ii = 0; ii < IOC4_NUM_SERIAL_PORTS; ii++) { + the_port = &control->ic_port[ii].icp_uart_port; + if (the_port) { + uart_remove_one_port(&ioc4_uart, the_port); + } + port = control->ic_port[ii].icp_port; + if (!(ii & 1) && port) { + pci_free_consistent(port->ip_pdev, + TOTAL_RING_BUF_SIZE, + (void *)port->ip_cpu_ringbuf, + port->ip_dma_ringbuf); + kfree(port); + } + } + soft = control->ic_soft; + if (soft) { + free_irq(control->ic_irq, (void *)soft); + if (soft->is_ioc4_serial_addr) { + release_region((unsigned long) + soft->is_ioc4_serial_addr, + sizeof(struct ioc4_serial)); + } + kfree(soft); + } + kfree(control); + idd->idd_serial_data = NULL; + + return 0; +} + static struct ioc4_submodule ioc4_serial_submodule = { .is_name = "IOC4_serial", .is_owner = THIS_MODULE, @@ -2900,15 +2796,9 @@ int ioc4_serial_init(void) int ret; /* register with serial core */ - if ((ret = uart_register_driver(&ioc4_uart_rs232)) < 0) { - printk(KERN_WARNING - "%s: Couldn't register rs232 IOC4 serial driver\n", - __FUNCTION__); - return ret; - } - if ((ret = uart_register_driver(&ioc4_uart_rs422)) < 0) { + if ((ret = uart_register_driver(&ioc4_uart)) < 0) { printk(KERN_WARNING - "%s: Couldn't register rs422 IOC4 serial driver\n", + "%s: Couldn't register IOC4 serial driver\n", __FUNCTION__); return ret; } @@ -2920,8 +2810,7 @@ int ioc4_serial_init(void) static void __devexit ioc4_serial_exit(void) { ioc4_unregister_submodule(&ioc4_serial_submodule); - uart_unregister_driver(&ioc4_uart_rs232); - uart_unregister_driver(&ioc4_uart_rs422); + uart_unregister_driver(&ioc4_uart); } module_init(ioc4_serial_init); diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 651772474..193722d68 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c @@ -967,9 +967,8 @@ static struct zilog_layout * __init get_zs(int chip) #define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */ #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE -static void ip22zilog_put_char(struct uart_port *port, int ch) +static void ip22zilog_put_char(struct zilog_channel *channel, unsigned char ch) { - struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); int loops = ZS_PUT_CHAR_MAX_DELAY; /* This is a timed polling loop so do not switch the explicit @@ -993,10 +992,16 @@ static void ip22zilog_console_write(struct console *con, const char *s, unsigned int count) { struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index]; + struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port); unsigned long flags; + int i; spin_lock_irqsave(&up->port.lock, flags); - uart_console_write(&up->port, s, count, ip22zilog_put_char); + for (i = 0; i < count; i++, s++) { + ip22zilog_put_char(channel, *s); + if (*s == 10) + ip22zilog_put_char(channel, 13); + } udelay(2); spin_unlock_irqrestore(&up->port.lock, flags); } diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h index 777829fa3..dfc1e86d3 100644 --- a/drivers/serial/jsm/jsm.h +++ b/drivers/serial/jsm/jsm.h @@ -28,7 +28,6 @@ #define __JSM_DRIVER_H #include -#include #include /* To pick up the varions Linux types */ #include #include @@ -90,7 +89,7 @@ enum { #define WRITEBUFLEN ((4096) + 4) #define MYFLIPLEN N_TTY_BUF_SIZE -#define JSM_VERSION "jsm: 1.1-1-INKERNEL" +#define JSM_VERSION "jsm: 1.2-1-INKERNEL" #define JSM_PARTNUM "40002438_A-INKERNEL" struct jsm_board; @@ -381,7 +380,6 @@ struct neo_uart_struct { extern struct uart_driver jsm_uart_driver; extern struct board_ops jsm_neo_ops; extern int jsm_debug; -extern int jsm_rawreadok; /************************************************************************* * diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index b3e1f71be..b1b66e71d 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c @@ -20,7 +20,7 @@ * * Contact Information: * Scott H Kilau - * Wendy Xiong + * Wendy Xiong * * ***********************************************************************/ diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c index 3a11a69fe..87e4e2cf8 100644 --- a/drivers/serial/jsm/jsm_neo.c +++ b/drivers/serial/jsm/jsm_neo.c @@ -48,8 +48,9 @@ static inline void neo_pci_posting_flush(struct jsm_board *bd) static void neo_set_cts_flow_control(struct jsm_channel *ch) { - u8 ier = readb(&ch->ch_neo_uart->ier); - u8 efr = readb(&ch->ch_neo_uart->efr); + u8 ier, efr; + ier = readb(&ch->ch_neo_uart->ier); + efr = readb(&ch->ch_neo_uart->efr); jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting CTSFLOW\n"); @@ -78,8 +79,9 @@ static void neo_set_cts_flow_control(struct jsm_channel *ch) static void neo_set_rts_flow_control(struct jsm_channel *ch) { - u8 ier = readb(&ch->ch_neo_uart->ier); - u8 efr = readb(&ch->ch_neo_uart->efr); + u8 ier, efr; + ier = readb(&ch->ch_neo_uart->ier); + efr = readb(&ch->ch_neo_uart->efr); jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting RTSFLOW\n"); @@ -117,8 +119,9 @@ static void neo_set_rts_flow_control(struct jsm_channel *ch) static void neo_set_ixon_flow_control(struct jsm_channel *ch) { - u8 ier = readb(&ch->ch_neo_uart->ier); - u8 efr = readb(&ch->ch_neo_uart->efr); + u8 ier, efr; + ier = readb(&ch->ch_neo_uart->ier); + efr = readb(&ch->ch_neo_uart->efr); jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXON FLOW\n"); @@ -153,8 +156,9 @@ static void neo_set_ixon_flow_control(struct jsm_channel *ch) static void neo_set_ixoff_flow_control(struct jsm_channel *ch) { - u8 ier = readb(&ch->ch_neo_uart->ier); - u8 efr = readb(&ch->ch_neo_uart->efr); + u8 ier, efr; + ier = readb(&ch->ch_neo_uart->ier); + efr = readb(&ch->ch_neo_uart->efr); jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXOFF FLOW\n"); @@ -190,8 +194,9 @@ static void neo_set_ixoff_flow_control(struct jsm_channel *ch) static void neo_set_no_input_flow_control(struct jsm_channel *ch) { - u8 ier = readb(&ch->ch_neo_uart->ier); - u8 efr = readb(&ch->ch_neo_uart->efr); + u8 ier, efr; + ier = readb(&ch->ch_neo_uart->ier); + efr = readb(&ch->ch_neo_uart->efr); jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Input FLOW\n"); @@ -228,8 +233,9 @@ static void neo_set_no_input_flow_control(struct jsm_channel *ch) static void neo_set_no_output_flow_control(struct jsm_channel *ch) { - u8 ier = readb(&ch->ch_neo_uart->ier); - u8 efr = readb(&ch->ch_neo_uart->efr); + u8 ier, efr; + ier = readb(&ch->ch_neo_uart->ier); + efr = readb(&ch->ch_neo_uart->efr); jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Output FLOW\n"); @@ -959,56 +965,47 @@ static void neo_param(struct jsm_channel *ch) baud = ch->ch_custom_speed; if (ch->ch_flags & CH_BAUD0) ch->ch_flags &= ~(CH_BAUD0); - } else { - int iindex = 0; - int jindex = 0; - - const u64 bauds[4][16] = { - { - 0, 50, 75, 110, - 134, 150, 200, 300, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { - 0, 57600, 76800, 115200, - 131657, 153600, 230400, 460800, - 921600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 } - }; - - baud = C_BAUD(ch->uart_port.info->tty) & 0xff; - - if (ch->ch_c_cflag & CBAUDEX) - iindex = 1; - - jindex = baud; - - if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16)) - baud = bauds[iindex][jindex]; - else { - jsm_printk(IOCTL, DEBUG, &ch->ch_bd->pci_dev, - "baud indices were out of range (%d)(%d)", - iindex, jindex); - baud = 0; + } else { + int i; + unsigned int cflag; + static struct { + unsigned int rate; + unsigned int cflag; + } baud_rates[] = { + { 921600, B921600 }, + { 460800, B460800 }, + { 230400, B230400 }, + { 115200, B115200 }, + { 57600, B57600 }, + { 38400, B38400 }, + { 19200, B19200 }, + { 9600, B9600 }, + { 4800, B4800 }, + { 2400, B2400 }, + { 1200, B1200 }, + { 600, B600 }, + { 300, B300 }, + { 200, B200 }, + { 150, B150 }, + { 134, B134 }, + { 110, B110 }, + { 75, B75 }, + { 50, B50 }, + }; + + cflag = C_BAUD(ch->uart_port.info->tty); + baud = 9600; + for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { + if (baud_rates[i].cflag == cflag) { + baud = baud_rates[i].rate; + break; } - - if (baud == 0) - baud = 9600; - - if (ch->ch_flags & CH_BAUD0) - ch->ch_flags &= ~(CH_BAUD0); } + if (ch->ch_flags & CH_BAUD0) + ch->ch_flags &= ~(CH_BAUD0); + } + if (ch->ch_c_cflag & PARENB) lcr |= UART_LCR_PARITY; diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 7d8237051..4d48b625c 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c @@ -142,14 +142,12 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) { unsigned long lock_flags; struct jsm_channel *channel = (struct jsm_channel *)port; - struct termios *termios; spin_lock_irqsave(&port->lock, lock_flags); - termios = port->info->tty->termios; - if (ch == termios->c_cc[VSTART]) + if (ch == port->info->tty->termios->c_cc[VSTART]) channel->ch_bd->bd_ops->send_start_character(channel); - if (ch == termios->c_cc[VSTOP]) + if (ch == port->info->tty->termios->c_cc[VSTOP]) channel->ch_bd->bd_ops->send_stop_character(channel); spin_unlock_irqrestore(&port->lock, lock_flags); } @@ -180,7 +178,6 @@ 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 termios *termios; /* Get board pointer from our array of majors we have allocated */ brd = channel->ch_bd; @@ -242,13 +239,12 @@ static int jsm_tty_open(struct uart_port *port) channel->ch_cached_lsr = 0; channel->ch_stops_sent = 0; - termios = port->info->tty->termios; - channel->ch_c_cflag = termios->c_cflag; - channel->ch_c_iflag = termios->c_iflag; - channel->ch_c_oflag = termios->c_oflag; - channel->ch_c_lflag = termios->c_lflag; - channel->ch_startc = termios->c_cc[VSTART]; - channel->ch_stopc = termios->c_cc[VSTOP]; + channel->ch_c_cflag = port->info->tty->termios->c_cflag; + channel->ch_c_iflag = port->info->tty->termios->c_iflag; + channel->ch_c_oflag = port->info->tty->termios->c_oflag; + channel->ch_c_lflag = port->info->tty->termios->c_lflag; + channel->ch_startc = port->info->tty->termios->c_cc[VSTART]; + channel->ch_stopc = port->info->tty->termios->c_cc[VSTOP]; /* Tell UART to init itself */ brd->bd_ops->uart_init(channel); @@ -788,7 +784,6 @@ 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; /* Store how much space we have left in the queue */ @@ -814,7 +809,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* HWFLOW */ if (ch->ch_c_cflag & CRTSCTS) { if(!(ch->ch_flags & CH_RECEIVER_OFF)) { - bd_ops->disable_receiver(ch); + ch->ch_bd->bd_ops->disable_receiver(ch); ch->ch_flags |= (CH_RECEIVER_OFF); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n", @@ -824,7 +819,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* SWFLOW */ else if (ch->ch_c_iflag & IXOFF) { if (ch->ch_stops_sent <= MAX_STOPS_SENT) { - bd_ops->send_stop_character(ch); + ch->ch_bd->bd_ops->send_stop_character(ch); ch->ch_stops_sent++; jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending stop char! Times sent: %x\n", ch->ch_stops_sent); @@ -851,7 +846,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* HWFLOW */ if (ch->ch_c_cflag & CRTSCTS) { if (ch->ch_flags & CH_RECEIVER_OFF) { - bd_ops->enable_receiver(ch); + ch->ch_bd->bd_ops->enable_receiver(ch); ch->ch_flags &= ~(CH_RECEIVER_OFF); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n", @@ -861,7 +856,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* SWFLOW */ else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) { ch->ch_stops_sent = 0; - bd_ops->send_start_character(ch); + ch->ch_bd->bd_ops->send_start_character(ch); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n"); } } diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 321a40f33..242a04104 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c @@ -248,17 +248,17 @@ static void sio_error(int *status) #endif /* CONFIG_SERIAL_M32R_PLDSIO */ -static unsigned int sio_in(struct uart_sio_port *up, int offset) +static _INLINE_ unsigned int sio_in(struct uart_sio_port *up, int offset) { return __sio_in(up->port.iobase + offset); } -static void sio_out(struct uart_sio_port *up, int offset, int value) +static _INLINE_ void sio_out(struct uart_sio_port *up, int offset, int value) { __sio_out(value, up->port.iobase + offset); } -static unsigned int serial_in(struct uart_sio_port *up, int offset) +static _INLINE_ unsigned int serial_in(struct uart_sio_port *up, int offset) { if (!offset) return 0; @@ -266,7 +266,8 @@ static unsigned int serial_in(struct uart_sio_port *up, int offset) return __sio_in(offset); } -static void serial_out(struct uart_sio_port *up, int offset, int value) +static _INLINE_ void +serial_out(struct uart_sio_port *up, int offset, int value) { if (!offset) return; @@ -325,8 +326,8 @@ static void m32r_sio_enable_ms(struct uart_port *port) serial_out(up, UART_IER, up->ier); } -static void receive_chars(struct uart_sio_port *up, int *status, - struct pt_regs *regs) +static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status, + struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; unsigned char ch; @@ -399,7 +400,7 @@ static void receive_chars(struct uart_sio_port *up, int *status, tty_flip_buffer_push(tty); } -static void transmit_chars(struct uart_sio_port *up) +static _INLINE_ void transmit_chars(struct uart_sio_port *up) { struct circ_buf *xmit = &up->port.info->xmit; int count; @@ -1038,14 +1039,6 @@ static inline void wait_for_xmitr(struct uart_sio_port *up) } } -static void m32r_sio_console_putchar(struct uart_port *port, int ch) -{ - struct uart_sio_port *up = (struct uart_sio_port *)port; - - wait_for_xmitr(up); - sio_out(up, SIOTXB, ch); -} - /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -1057,6 +1050,7 @@ static void m32r_sio_console_write(struct console *co, const char *s, { struct uart_sio_port *up = &m32r_sio_ports[co->index]; unsigned int ier; + int i; /* * First save the UER then disable the interrupts @@ -1064,7 +1058,23 @@ static void m32r_sio_console_write(struct console *co, const char *s, ier = sio_in(up, SIOTRCR); sio_out(up, SIOTRCR, 0); - uart_console_write(&up->port, s, count, m32r_sio_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(up); + + /* + * Send the character out. + * If a LF, also do CR... + */ + sio_out(up, SIOTXB, *s); + + if (*s == 10) { + wait_for_xmitr(up); + sio_out(up, SIOTXB, 13); + } + } /* * Finally, wait for transmitter to become empty diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 6459edc7f..61dd17d7b 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -40,7 +40,7 @@ * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly * fpr the console code : without this 1:1 mapping, at early boot time, when we - * are parsing the kernel args console=ttyPSC?, we wouldn't know which PSC it + * are parsing the kernel args console=ttyPSC?, we wouldn't know wich PSC it * will be mapped to. */ @@ -603,14 +603,15 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count) udelay(1); /* Write all the chars */ - for (i = 0; i < count; i++, s++) { - /* Line return handling */ - if (*s == '\n') - out_8(&psc->mpc52xx_psc_buffer_8, '\r'); - + for ( i=0 ; impc52xx_psc_buffer_8, *s); + /* Line return handling */ + if ( *s++ == '\n' ) + out_8(&psc->mpc52xx_psc_buffer_8, '\r'); + /* Wait the TX buffer to be empty */ j = 20000; /* Maximum wait */ while (!(in_be16(&psc->mpc52xx_psc_status) & diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index 94681922e..0ca83ac31 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -1,4 +1,6 @@ /* + * drivers/serial/mpsc.c + * * Generic driver for the MPSC (UART mode) on Marvell parts (e.g., GT64240, * GT64260, MV64340, MV64360, GT96100, ... ). * @@ -50,263 +52,9 @@ * 4) AFAICT, hardware flow control isn't supported by the controller --MAG. */ -#include - -#if defined(CONFIG_SERIAL_MPSC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include - -#if defined(CONFIG_SERIAL_MPSC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#define MPSC_NUM_CTLRS 2 - -/* - * Descriptors and buffers must be cache line aligned. - * Buffers lengths must be multiple of cache line size. - * Number of Tx & Rx descriptors must be powers of 2. - */ -#define MPSC_RXR_ENTRIES 32 -#define MPSC_RXRE_SIZE dma_get_cache_alignment() -#define MPSC_RXR_SIZE (MPSC_RXR_ENTRIES * MPSC_RXRE_SIZE) -#define MPSC_RXBE_SIZE dma_get_cache_alignment() -#define MPSC_RXB_SIZE (MPSC_RXR_ENTRIES * MPSC_RXBE_SIZE) - -#define MPSC_TXR_ENTRIES 32 -#define MPSC_TXRE_SIZE dma_get_cache_alignment() -#define MPSC_TXR_SIZE (MPSC_TXR_ENTRIES * MPSC_TXRE_SIZE) -#define MPSC_TXBE_SIZE dma_get_cache_alignment() -#define MPSC_TXB_SIZE (MPSC_TXR_ENTRIES * MPSC_TXBE_SIZE) - -#define MPSC_DMA_ALLOC_SIZE (MPSC_RXR_SIZE + MPSC_RXB_SIZE + \ - MPSC_TXR_SIZE + MPSC_TXB_SIZE + \ - dma_get_cache_alignment() /* for alignment */) - -/* Rx and Tx Ring entry descriptors -- assume entry size is <= cacheline size */ -struct mpsc_rx_desc { - u16 bufsize; - u16 bytecnt; - u32 cmdstat; - u32 link; - u32 buf_ptr; -} __attribute((packed)); - -struct mpsc_tx_desc { - u16 bytecnt; - u16 shadow; - u32 cmdstat; - u32 link; - u32 buf_ptr; -} __attribute((packed)); - -/* - * Some regs that have the erratum that you can't read them are are shared - * between the two MPSC controllers. This struct contains those shared regs. - */ -struct mpsc_shared_regs { - phys_addr_t mpsc_routing_base_p; - phys_addr_t sdma_intr_base_p; - - void __iomem *mpsc_routing_base; - void __iomem *sdma_intr_base; - - u32 MPSC_MRR_m; - u32 MPSC_RCRR_m; - u32 MPSC_TCRR_m; - u32 SDMA_INTR_CAUSE_m; - u32 SDMA_INTR_MASK_m; -}; - -/* The main driver data structure */ -struct mpsc_port_info { - struct uart_port port; /* Overlay uart_port structure */ - - /* Internal driver state for this ctlr */ - u8 ready; - u8 rcv_data; - tcflag_t c_iflag; /* save termios->c_iflag */ - tcflag_t c_cflag; /* save termios->c_cflag */ - - /* Info passed in from platform */ - u8 mirror_regs; /* Need to mirror regs? */ - u8 cache_mgmt; /* Need manual cache mgmt? */ - u8 brg_can_tune; /* BRG has baud tuning? */ - u32 brg_clk_src; - u16 mpsc_max_idle; - int default_baud; - int default_bits; - int default_parity; - int default_flow; - - /* Physical addresses of various blocks of registers (from platform) */ - phys_addr_t mpsc_base_p; - phys_addr_t sdma_base_p; - phys_addr_t brg_base_p; - - /* Virtual addresses of various blocks of registers (from platform) */ - void __iomem *mpsc_base; - void __iomem *sdma_base; - void __iomem *brg_base; - - /* Descriptor ring and buffer allocations */ - void *dma_region; - dma_addr_t dma_region_p; - - dma_addr_t rxr; /* Rx descriptor ring */ - dma_addr_t rxr_p; /* Phys addr of rxr */ - u8 *rxb; /* Rx Ring I/O buf */ - u8 *rxb_p; /* Phys addr of rxb */ - u32 rxr_posn; /* First desc w/ Rx data */ - - dma_addr_t txr; /* Tx descriptor ring */ - dma_addr_t txr_p; /* Phys addr of txr */ - u8 *txb; /* Tx Ring I/O buf */ - u8 *txb_p; /* Phys addr of txb */ - int txr_head; /* Where new data goes */ - int txr_tail; /* Where sent data comes off */ - - /* Mirrored values of regs we can't read (if 'mirror_regs' set) */ - u32 MPSC_MPCR_m; - u32 MPSC_CHR_1_m; - u32 MPSC_CHR_2_m; - u32 MPSC_CHR_10_m; - u32 BRG_BCR_m; - struct mpsc_shared_regs *shared_regs; -}; - -/* Hooks to platform-specific code */ -int mpsc_platform_register_driver(void); -void mpsc_platform_unregister_driver(void); - -/* Hooks back in to mpsc common to be called by platform-specific code */ -struct mpsc_port_info *mpsc_device_probe(int index); -struct mpsc_port_info *mpsc_device_remove(int index); - -/* Main MPSC Configuration Register Offsets */ -#define MPSC_MMCRL 0x0000 -#define MPSC_MMCRH 0x0004 -#define MPSC_MPCR 0x0008 -#define MPSC_CHR_1 0x000c -#define MPSC_CHR_2 0x0010 -#define MPSC_CHR_3 0x0014 -#define MPSC_CHR_4 0x0018 -#define MPSC_CHR_5 0x001c -#define MPSC_CHR_6 0x0020 -#define MPSC_CHR_7 0x0024 -#define MPSC_CHR_8 0x0028 -#define MPSC_CHR_9 0x002c -#define MPSC_CHR_10 0x0030 -#define MPSC_CHR_11 0x0034 - -#define MPSC_MPCR_FRZ (1 << 9) -#define MPSC_MPCR_CL_5 0 -#define MPSC_MPCR_CL_6 1 -#define MPSC_MPCR_CL_7 2 -#define MPSC_MPCR_CL_8 3 -#define MPSC_MPCR_SBL_1 0 -#define MPSC_MPCR_SBL_2 1 - -#define MPSC_CHR_2_TEV (1<<1) -#define MPSC_CHR_2_TA (1<<7) -#define MPSC_CHR_2_TTCS (1<<9) -#define MPSC_CHR_2_REV (1<<17) -#define MPSC_CHR_2_RA (1<<23) -#define MPSC_CHR_2_CRD (1<<25) -#define MPSC_CHR_2_EH (1<<31) -#define MPSC_CHR_2_PAR_ODD 0 -#define MPSC_CHR_2_PAR_SPACE 1 -#define MPSC_CHR_2_PAR_EVEN 2 -#define MPSC_CHR_2_PAR_MARK 3 - -/* MPSC Signal Routing */ -#define MPSC_MRR 0x0000 -#define MPSC_RCRR 0x0004 -#define MPSC_TCRR 0x0008 - -/* Serial DMA Controller Interface Registers */ -#define SDMA_SDC 0x0000 -#define SDMA_SDCM 0x0008 -#define SDMA_RX_DESC 0x0800 -#define SDMA_RX_BUF_PTR 0x0808 -#define SDMA_SCRDP 0x0810 -#define SDMA_TX_DESC 0x0c00 -#define SDMA_SCTDP 0x0c10 -#define SDMA_SFTDP 0x0c14 - -#define SDMA_DESC_CMDSTAT_PE (1<<0) -#define SDMA_DESC_CMDSTAT_CDL (1<<1) -#define SDMA_DESC_CMDSTAT_FR (1<<3) -#define SDMA_DESC_CMDSTAT_OR (1<<6) -#define SDMA_DESC_CMDSTAT_BR (1<<9) -#define SDMA_DESC_CMDSTAT_MI (1<<10) -#define SDMA_DESC_CMDSTAT_A (1<<11) -#define SDMA_DESC_CMDSTAT_AM (1<<12) -#define SDMA_DESC_CMDSTAT_CT (1<<13) -#define SDMA_DESC_CMDSTAT_C (1<<14) -#define SDMA_DESC_CMDSTAT_ES (1<<15) -#define SDMA_DESC_CMDSTAT_L (1<<16) -#define SDMA_DESC_CMDSTAT_F (1<<17) -#define SDMA_DESC_CMDSTAT_P (1<<18) -#define SDMA_DESC_CMDSTAT_EI (1<<23) -#define SDMA_DESC_CMDSTAT_O (1<<31) - -#define SDMA_DESC_DFLT (SDMA_DESC_CMDSTAT_O | \ - SDMA_DESC_CMDSTAT_EI) - -#define SDMA_SDC_RFT (1<<0) -#define SDMA_SDC_SFM (1<<1) -#define SDMA_SDC_BLMR (1<<6) -#define SDMA_SDC_BLMT (1<<7) -#define SDMA_SDC_POVR (1<<8) -#define SDMA_SDC_RIFB (1<<9) - -#define SDMA_SDCM_ERD (1<<7) -#define SDMA_SDCM_AR (1<<15) -#define SDMA_SDCM_STD (1<<16) -#define SDMA_SDCM_TXD (1<<23) -#define SDMA_SDCM_AT (1<<31) - -#define SDMA_0_CAUSE_RXBUF (1<<0) -#define SDMA_0_CAUSE_RXERR (1<<1) -#define SDMA_0_CAUSE_TXBUF (1<<2) -#define SDMA_0_CAUSE_TXEND (1<<3) -#define SDMA_1_CAUSE_RXBUF (1<<8) -#define SDMA_1_CAUSE_RXERR (1<<9) -#define SDMA_1_CAUSE_TXBUF (1<<10) -#define SDMA_1_CAUSE_TXEND (1<<11) - -#define SDMA_CAUSE_RX_MASK (SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \ - SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR) -#define SDMA_CAUSE_TX_MASK (SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \ - SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND) - -/* SDMA Interrupt registers */ -#define SDMA_INTR_CAUSE 0x0000 -#define SDMA_INTR_MASK 0x0080 - -/* Baud Rate Generator Interface Registers */ -#define BRG_BCR 0x0000 -#define BRG_BTR 0x0004 +#include "mpsc.h" /* * Define how this driver is known to the outside (we've been assigned a @@ -1417,7 +1165,7 @@ mpsc_startup(struct uart_port *port) flag = SA_SHIRQ; if (request_irq(pi->port.irq, mpsc_sdma_intr, flag, - "mpsc-sdma", pi)) + "mpsc/sdma", pi)) printk(KERN_ERR "MPSC: Can't get SDMA IRQ %d\n", pi->port.irq); diff --git a/drivers/serial/mpsc.h b/drivers/serial/mpsc.h new file mode 100644 index 000000000..678dbcf06 --- /dev/null +++ b/drivers/serial/mpsc.h @@ -0,0 +1,289 @@ +/* + * drivers/serial/mpsc.h + * + * Author: Mark A. Greer + * + * 2004 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#ifndef __MPSC_H__ +#define __MPSC_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(CONFIG_SERIAL_MPSC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#define MPSC_NUM_CTLRS 2 + +/* + * Descriptors and buffers must be cache line aligned. + * Buffers lengths must be multiple of cache line size. + * Number of Tx & Rx descriptors must be powers of 2. + */ +#define MPSC_RXR_ENTRIES 32 +#define MPSC_RXRE_SIZE dma_get_cache_alignment() +#define MPSC_RXR_SIZE (MPSC_RXR_ENTRIES * MPSC_RXRE_SIZE) +#define MPSC_RXBE_SIZE dma_get_cache_alignment() +#define MPSC_RXB_SIZE (MPSC_RXR_ENTRIES * MPSC_RXBE_SIZE) + +#define MPSC_TXR_ENTRIES 32 +#define MPSC_TXRE_SIZE dma_get_cache_alignment() +#define MPSC_TXR_SIZE (MPSC_TXR_ENTRIES * MPSC_TXRE_SIZE) +#define MPSC_TXBE_SIZE dma_get_cache_alignment() +#define MPSC_TXB_SIZE (MPSC_TXR_ENTRIES * MPSC_TXBE_SIZE) + +#define MPSC_DMA_ALLOC_SIZE (MPSC_RXR_SIZE + MPSC_RXB_SIZE + \ + MPSC_TXR_SIZE + MPSC_TXB_SIZE + \ + dma_get_cache_alignment() /* for alignment */) + +/* Rx and Tx Ring entry descriptors -- assume entry size is <= cacheline size */ +struct mpsc_rx_desc { + u16 bufsize; + u16 bytecnt; + u32 cmdstat; + u32 link; + u32 buf_ptr; +} __attribute((packed)); + +struct mpsc_tx_desc { + u16 bytecnt; + u16 shadow; + u32 cmdstat; + u32 link; + u32 buf_ptr; +} __attribute((packed)); + +/* + * Some regs that have the erratum that you can't read them are are shared + * between the two MPSC controllers. This struct contains those shared regs. + */ +struct mpsc_shared_regs { + phys_addr_t mpsc_routing_base_p; + phys_addr_t sdma_intr_base_p; + + void __iomem *mpsc_routing_base; + void __iomem *sdma_intr_base; + + u32 MPSC_MRR_m; + u32 MPSC_RCRR_m; + u32 MPSC_TCRR_m; + u32 SDMA_INTR_CAUSE_m; + u32 SDMA_INTR_MASK_m; +}; + +/* The main driver data structure */ +struct mpsc_port_info { + struct uart_port port; /* Overlay uart_port structure */ + + /* Internal driver state for this ctlr */ + u8 ready; + u8 rcv_data; + tcflag_t c_iflag; /* save termios->c_iflag */ + tcflag_t c_cflag; /* save termios->c_cflag */ + + /* Info passed in from platform */ + u8 mirror_regs; /* Need to mirror regs? */ + u8 cache_mgmt; /* Need manual cache mgmt? */ + u8 brg_can_tune; /* BRG has baud tuning? */ + u32 brg_clk_src; + u16 mpsc_max_idle; + int default_baud; + int default_bits; + int default_parity; + int default_flow; + + /* Physical addresses of various blocks of registers (from platform) */ + phys_addr_t mpsc_base_p; + phys_addr_t sdma_base_p; + phys_addr_t brg_base_p; + + /* Virtual addresses of various blocks of registers (from platform) */ + void __iomem *mpsc_base; + void __iomem *sdma_base; + void __iomem *brg_base; + + /* Descriptor ring and buffer allocations */ + void *dma_region; + dma_addr_t dma_region_p; + + dma_addr_t rxr; /* Rx descriptor ring */ + dma_addr_t rxr_p; /* Phys addr of rxr */ + u8 *rxb; /* Rx Ring I/O buf */ + u8 *rxb_p; /* Phys addr of rxb */ + u32 rxr_posn; /* First desc w/ Rx data */ + + dma_addr_t txr; /* Tx descriptor ring */ + dma_addr_t txr_p; /* Phys addr of txr */ + u8 *txb; /* Tx Ring I/O buf */ + u8 *txb_p; /* Phys addr of txb */ + int txr_head; /* Where new data goes */ + int txr_tail; /* Where sent data comes off */ + + /* Mirrored values of regs we can't read (if 'mirror_regs' set) */ + u32 MPSC_MPCR_m; + u32 MPSC_CHR_1_m; + u32 MPSC_CHR_2_m; + u32 MPSC_CHR_10_m; + u32 BRG_BCR_m; + struct mpsc_shared_regs *shared_regs; +}; + +/* Hooks to platform-specific code */ +int mpsc_platform_register_driver(void); +void mpsc_platform_unregister_driver(void); + +/* Hooks back in to mpsc common to be called by platform-specific code */ +struct mpsc_port_info *mpsc_device_probe(int index); +struct mpsc_port_info *mpsc_device_remove(int index); + +/* + ***************************************************************************** + * + * Multi-Protocol Serial Controller Interface Registers + * + ***************************************************************************** + */ + +/* Main Configuratino Register Offsets */ +#define MPSC_MMCRL 0x0000 +#define MPSC_MMCRH 0x0004 +#define MPSC_MPCR 0x0008 +#define MPSC_CHR_1 0x000c +#define MPSC_CHR_2 0x0010 +#define MPSC_CHR_3 0x0014 +#define MPSC_CHR_4 0x0018 +#define MPSC_CHR_5 0x001c +#define MPSC_CHR_6 0x0020 +#define MPSC_CHR_7 0x0024 +#define MPSC_CHR_8 0x0028 +#define MPSC_CHR_9 0x002c +#define MPSC_CHR_10 0x0030 +#define MPSC_CHR_11 0x0034 + +#define MPSC_MPCR_FRZ (1 << 9) +#define MPSC_MPCR_CL_5 0 +#define MPSC_MPCR_CL_6 1 +#define MPSC_MPCR_CL_7 2 +#define MPSC_MPCR_CL_8 3 +#define MPSC_MPCR_SBL_1 0 +#define MPSC_MPCR_SBL_2 1 + +#define MPSC_CHR_2_TEV (1<<1) +#define MPSC_CHR_2_TA (1<<7) +#define MPSC_CHR_2_TTCS (1<<9) +#define MPSC_CHR_2_REV (1<<17) +#define MPSC_CHR_2_RA (1<<23) +#define MPSC_CHR_2_CRD (1<<25) +#define MPSC_CHR_2_EH (1<<31) +#define MPSC_CHR_2_PAR_ODD 0 +#define MPSC_CHR_2_PAR_SPACE 1 +#define MPSC_CHR_2_PAR_EVEN 2 +#define MPSC_CHR_2_PAR_MARK 3 + +/* MPSC Signal Routing */ +#define MPSC_MRR 0x0000 +#define MPSC_RCRR 0x0004 +#define MPSC_TCRR 0x0008 + +/* + ***************************************************************************** + * + * Serial DMA Controller Interface Registers + * + ***************************************************************************** + */ + +#define SDMA_SDC 0x0000 +#define SDMA_SDCM 0x0008 +#define SDMA_RX_DESC 0x0800 +#define SDMA_RX_BUF_PTR 0x0808 +#define SDMA_SCRDP 0x0810 +#define SDMA_TX_DESC 0x0c00 +#define SDMA_SCTDP 0x0c10 +#define SDMA_SFTDP 0x0c14 + +#define SDMA_DESC_CMDSTAT_PE (1<<0) +#define SDMA_DESC_CMDSTAT_CDL (1<<1) +#define SDMA_DESC_CMDSTAT_FR (1<<3) +#define SDMA_DESC_CMDSTAT_OR (1<<6) +#define SDMA_DESC_CMDSTAT_BR (1<<9) +#define SDMA_DESC_CMDSTAT_MI (1<<10) +#define SDMA_DESC_CMDSTAT_A (1<<11) +#define SDMA_DESC_CMDSTAT_AM (1<<12) +#define SDMA_DESC_CMDSTAT_CT (1<<13) +#define SDMA_DESC_CMDSTAT_C (1<<14) +#define SDMA_DESC_CMDSTAT_ES (1<<15) +#define SDMA_DESC_CMDSTAT_L (1<<16) +#define SDMA_DESC_CMDSTAT_F (1<<17) +#define SDMA_DESC_CMDSTAT_P (1<<18) +#define SDMA_DESC_CMDSTAT_EI (1<<23) +#define SDMA_DESC_CMDSTAT_O (1<<31) + +#define SDMA_DESC_DFLT (SDMA_DESC_CMDSTAT_O | \ + SDMA_DESC_CMDSTAT_EI) + +#define SDMA_SDC_RFT (1<<0) +#define SDMA_SDC_SFM (1<<1) +#define SDMA_SDC_BLMR (1<<6) +#define SDMA_SDC_BLMT (1<<7) +#define SDMA_SDC_POVR (1<<8) +#define SDMA_SDC_RIFB (1<<9) + +#define SDMA_SDCM_ERD (1<<7) +#define SDMA_SDCM_AR (1<<15) +#define SDMA_SDCM_STD (1<<16) +#define SDMA_SDCM_TXD (1<<23) +#define SDMA_SDCM_AT (1<<31) + +#define SDMA_0_CAUSE_RXBUF (1<<0) +#define SDMA_0_CAUSE_RXERR (1<<1) +#define SDMA_0_CAUSE_TXBUF (1<<2) +#define SDMA_0_CAUSE_TXEND (1<<3) +#define SDMA_1_CAUSE_RXBUF (1<<8) +#define SDMA_1_CAUSE_RXERR (1<<9) +#define SDMA_1_CAUSE_TXBUF (1<<10) +#define SDMA_1_CAUSE_TXEND (1<<11) + +#define SDMA_CAUSE_RX_MASK (SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \ + SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR) +#define SDMA_CAUSE_TX_MASK (SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \ + SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND) + +/* SDMA Interrupt registers */ +#define SDMA_INTR_CAUSE 0x0000 +#define SDMA_INTR_MASK 0x0080 + +/* + ***************************************************************************** + * + * Baud Rate Generator Interface Registers + * + ***************************************************************************** + */ + +#define BRG_BCR 0x0000 +#define BRG_BTR 0x0004 + +#endif /* __MPSC_H__ */ diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 64c0e8912..868eaf4a1 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -51,7 +51,7 @@ #define MUX_BREAK(status) ((status & 0xF000) == 0x2000) #define MUX_NR 256 -static unsigned int port_cnt __read_mostly; +static unsigned int port_cnt = 0; static struct uart_port mux_ports[MUX_NR]; static struct uart_driver mux_driver = { @@ -461,7 +461,7 @@ static int __init mux_probe(struct parisc_device *dev) port->iobase = 0; port->mapbase = dev->hpa.start + MUX_OFFSET + (i * MUX_LINE_OFFSET); - port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET); + port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); port->iotype = UPIO_MEM; port->type = PORT_MUX; port->irq = NO_IRQ; diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 513ff8597..9b7ed58cb 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -1916,16 +1916,6 @@ static void __exit exit_pmz(void) #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE -static void pmz_console_putchar(struct uart_port *port, int ch) -{ - struct uart_pmac_port *uap = (struct uart_pmac_port *)port; - - /* Wait for the transmit buffer to empty. */ - while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0) - udelay(5); - write_zsdata(uap, ch); -} - /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -1934,6 +1924,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c { struct uart_pmac_port *uap = &pmz_ports[con->index]; unsigned long flags; + int i; if (ZS_IS_ASLEEP(uap)) return; @@ -1943,7 +1934,17 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB); write_zsreg(uap, R5, uap->curregs[5] | TxENABLE | RTS | DTR); - uart_console_write(&uap->port, s, count, pmz_console_putchar); + for (i = 0; i < count; i++) { + /* Wait for the transmit buffer to empty. */ + while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0) + udelay(5); + write_zsdata(uap, s[i]); + if (s[i] == 10) { + while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0) + udelay(5); + write_zsdata(uap, R13); + } + } /* Restore the values in the registers. */ write_zsreg(uap, R1, uap->curregs[1]); diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 77d4568cc..10535f003 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -619,14 +619,6 @@ static inline void wait_for_xmitr(struct uart_pxa_port *up) } } -static void serial_pxa_console_putchar(struct uart_port *port, int ch) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - wait_for_xmitr(up); - serial_out(up, UART_TX, ch); -} - /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -638,6 +630,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) { struct uart_pxa_port *up = &serial_pxa_ports[co->index]; unsigned int ier; + int i; /* * First save the IER then disable the interrupts @@ -645,7 +638,22 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) ier = serial_in(up, UART_IER); serial_out(up, UART_IER, UART_IER_UUE); - uart_console_write(&up->port, s, count, serial_pxa_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(up); + + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_out(up, UART_TX, *s); + if (*s == 10) { + wait_for_xmitr(up); + serial_out(up, UART_TX, 13); + } + } /* * Finally, wait for transmitter to become empty diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index f5aac92fb..7410e093a 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -1066,8 +1066,6 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, port->mapbase = res->start; port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART); port->irq = platform_get_irq(platdev, 0); - if (port->irq < 0) - port->irq = 0; ourport->clk = clk_get(&platdev->dev, "uart"); @@ -1585,20 +1583,26 @@ s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0; } -static void -s3c24xx_serial_console_putchar(struct uart_port *port, int ch) -{ - unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); - while (!s3c24xx_serial_console_txrdy(port, ufcon)) - barrier(); - wr_regb(cons_uart, S3C2410_UTXH, ch); -} - static void s3c24xx_serial_console_write(struct console *co, const char *s, unsigned int count) { - uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); + int i; + unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); + + for (i = 0; i < count; i++) { + while (!s3c24xx_serial_console_txrdy(cons_uart, ufcon)) + barrier(); + + wr_regb(cons_uart, S3C2410_UTXH, s[i]); + + if (s[i] == '\n') { + while (!s3c24xx_serial_console_txrdy(cons_uart, ufcon)) + barrier(); + + wr_regb(cons_uart, S3C2410_UTXH, '\r'); + } + } } static void __init diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index c2d9068b4..2c00b8625 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -689,14 +689,6 @@ void __init sa1100_register_uart(int idx, int port) #ifdef CONFIG_SERIAL_SA1100_CONSOLE -static void sa1100_console_putchar(struct uart_port *port, int ch) -{ - struct sa1100_port *sport = (struct sa1100_port *)port; - - while (!(UART_GET_UTSR1(sport) & UTSR1_TNF)) - barrier(); - UART_PUT_CHAR(sport, ch); -} /* * Interrupts are disabled on entering @@ -705,7 +697,7 @@ static void sa1100_console_write(struct console *co, const char *s, unsigned int count) { struct sa1100_port *sport = &sa1100_ports[co->index]; - unsigned int old_utcr3, status; + unsigned int old_utcr3, status, i; /* * First, save UTCR3 and then disable interrupts @@ -714,7 +706,21 @@ sa1100_console_write(struct console *co, const char *s, unsigned int count) UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) | UTCR3_TXE); - uart_console_write(&sport->port, s, count, sa1100_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + do { + status = UART_GET_UTSR1(sport); + } while (!(status & UTSR1_TNF)); + UART_PUT_CHAR(sport, s[i]); + if (s[i] == '\n') { + do { + status = UART_GET_UTSR1(sport); + } while (!(status & UTSR1_TNF)); + UART_PUT_CHAR(sport, '\r'); + } + } /* * Finally, wait for transmitter to become empty diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 17839e753..cc1faa31d 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1500,18 +1500,20 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) static struct uart_state *uart_get(struct uart_driver *drv, int line) { struct uart_state *state; - int ret = 0; + mutex_lock(&port_mutex); state = drv->state + line; if (mutex_lock_interruptible(&state->mutex)) { - ret = -ERESTARTSYS; - goto err; + state = ERR_PTR(-ERESTARTSYS); + goto out; } state->count++; - if (!state->port || state->port->flags & UPF_DEAD) { - ret = -ENXIO; - goto err_unlock; + if (!state->port) { + state->count--; + mutex_unlock(&state->mutex); + state = ERR_PTR(-ENXIO); + goto out; } if (!state->info) { @@ -1529,17 +1531,15 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line) tasklet_init(&state->info->tlet, uart_tasklet_action, (unsigned long)state); } else { - ret = -ENOMEM; - goto err_unlock; + state->count--; + mutex_unlock(&state->mutex); + state = ERR_PTR(-ENOMEM); } } - return state; - err_unlock: - state->count--; - mutex_unlock(&state->mutex); - err: - return ERR_PTR(ret); + out: + mutex_unlock(&port_mutex); + return state; } /* @@ -1754,27 +1754,6 @@ static int uart_read_proc(char *page, char **start, off_t off, #endif #ifdef CONFIG_SERIAL_CORE_CONSOLE -/* - * uart_console_write - write a console message to a serial port - * @port: the port to write the message - * @s: array of characters - * @count: number of characters in string to write - * @write: function to write character to port - */ -void uart_console_write(struct uart_port *port, const char *s, - unsigned int count, - void (*putchar)(struct uart_port *, int)) -{ - unsigned int i; - - for (i = 0; i < count; i++, s++) { - if (*s == '\n') - putchar(port, '\r'); - putchar(port, *s); - } -} -EXPORT_SYMBOL_GPL(uart_console_write); - /* * Check whether an invalid uart number has been specified, and * if so, search for the first available port that does have @@ -1907,12 +1886,9 @@ uart_set_options(struct uart_port *port, struct console *co, static void uart_change_pm(struct uart_state *state, int pm_state) { struct uart_port *port = state->port; - - if (state->pm_state != pm_state) { - if (port->ops->pm) - port->ops->pm(port, pm_state, state->pm_state); - state->pm_state = pm_state; - } + if (port->ops->pm) + port->ops->pm(port, pm_state, state->pm_state); + state->pm_state = pm_state; } int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) @@ -2088,6 +2064,45 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, } } +/* + * This reverses the effects of uart_configure_port, hanging up the + * port before removal. + */ +static void +uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state) +{ + struct uart_port *port = state->port; + struct uart_info *info = state->info; + + if (info && info->tty) + tty_vhangup(info->tty); + + mutex_lock(&state->mutex); + + state->info = NULL; + + /* + * Free the port IO and memory resources, if any. + */ + if (port->type != PORT_UNKNOWN) + port->ops->release_port(port); + + /* + * Indicate that there isn't a port here anymore. + */ + port->type = PORT_UNKNOWN; + + /* + * Kill the tasklet, and free resources. + */ + if (info) { + tasklet_kill(&info->tlet); + kfree(info); + } + + mutex_unlock(&state->mutex); +} + static struct tty_operations uart_ops = { .open = uart_open, .close = uart_close, @@ -2234,7 +2249,6 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) state = drv->state + port->line; mutex_lock(&port_mutex); - mutex_lock(&state->mutex); if (state->port) { ret = -EINVAL; goto out; @@ -2269,13 +2283,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) port->cons && !(port->cons->flags & CON_ENABLED)) register_console(port->cons); - /* - * Ensure UPF_DEAD is not set. - */ - port->flags &= ~UPF_DEAD; - out: - mutex_unlock(&state->mutex); mutex_unlock(&port_mutex); return ret; @@ -2293,7 +2301,6 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) { struct uart_state *state = drv->state + port->line; - struct uart_info *info; BUG_ON(in_interrupt()); @@ -2303,49 +2310,12 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) mutex_lock(&port_mutex); - /* - * Mark the port "dead" - this prevents any opens from - * succeeding while we shut down the port. - */ - mutex_lock(&state->mutex); - port->flags |= UPF_DEAD; - mutex_unlock(&state->mutex); - /* * Remove the devices from devfs */ tty_unregister_device(drv->tty_driver, port->line); - info = state->info; - if (info && info->tty) - tty_vhangup(info->tty); - - /* - * All users of this port should now be disconnected from - * this driver, and the port shut down. We should be the - * only thread fiddling with this port from now on. - */ - state->info = NULL; - - /* - * Free the port IO and memory resources, if any. - */ - if (port->type != PORT_UNKNOWN) - port->ops->release_port(port); - - /* - * Indicate that there isn't a port here anymore. - */ - port->type = PORT_UNKNOWN; - - /* - * Kill the tasklet, and free resources. - */ - if (info) { - tasklet_kill(&info->tlet); - kfree(info); - } - + uart_unconfigure_port(drv, state); state->port = NULL; mutex_unlock(&port_mutex); diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 2c7077354..c30333694 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -98,13 +97,11 @@ static const struct multi_id multi_id[] = { #define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id)) struct serial_info { - struct pcmcia_device *p_dev; + dev_link_t link; int ndev; int multi; int slave; int manfid; - int prodid; - int c950ctrl; dev_node_t node[4]; int line[4]; }; @@ -116,36 +113,9 @@ struct serial_cfg_mem { }; -static int serial_config(struct pcmcia_device * link); +static void serial_config(dev_link_t * link); -static void wakeup_card(struct serial_info *info) -{ - int ctrl = info->c950ctrl; - - if (info->manfid == MANFID_OXSEMI) { - outb(12, ctrl + 1); - } else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) { - /* request_region? oxsemi branch does no request_region too... */ - /* This sequence is needed to properly initialize MC45 attached to OXCF950. - * I tried decreasing these msleep()s, but it worked properly (survived - * 1000 stop/start operations) with these timeouts (or bigger). */ - outb(0xA, ctrl + 1); - msleep(100); - outb(0xE, ctrl + 1); - msleep(300); - outb(0xC, ctrl + 1); - msleep(100); - outb(0xE, ctrl + 1); - msleep(200); - outb(0xF, ctrl + 1); - msleep(100); - outb(0xE, ctrl + 1); - msleep(100); - outb(0xC, ctrl + 1); - } -} - /*====================================================================== After a card is removed, serial_remove() will unregister @@ -153,45 +123,67 @@ static void wakeup_card(struct serial_info *info) ======================================================================*/ -static void serial_remove(struct pcmcia_device *link) +static void serial_remove(dev_link_t *link) { struct serial_info *info = link->priv; int i; + link->state &= ~DEV_PRESENT; + DEBUG(0, "serial_release(0x%p)\n", link); /* * Recheck to see if the device is still configured. */ - for (i = 0; i < info->ndev; i++) - serial8250_unregister_port(info->line[i]); + if (info->link.state & DEV_CONFIG) { + for (i = 0; i < info->ndev; i++) + serial8250_unregister_port(info->line[i]); - info->p_dev->dev_node = NULL; + info->link.dev = NULL; - if (!info->slave) - pcmcia_disable_device(link); + if (!info->slave) { + pcmcia_release_configuration(info->link.handle); + pcmcia_release_io(info->link.handle, &info->link.io); + pcmcia_release_irq(info->link.handle, &info->link.irq); + } + + info->link.state &= ~DEV_CONFIG; + } } -static int serial_suspend(struct pcmcia_device *link) +static int serial_suspend(struct pcmcia_device *dev) { - struct serial_info *info = link->priv; - int i; + dev_link_t *link = dev_to_instance(dev); + link->state |= DEV_SUSPEND; + + if (link->state & DEV_CONFIG) { + struct serial_info *info = link->priv; + int i; + + for (i = 0; i < info->ndev; i++) + serial8250_suspend_port(info->line[i]); - for (i = 0; i < info->ndev; i++) - serial8250_suspend_port(info->line[i]); + if (!info->slave) + pcmcia_release_configuration(link->handle); + } return 0; } -static int serial_resume(struct pcmcia_device *link) +static int serial_resume(struct pcmcia_device *dev) { - if (pcmcia_dev_present(link)) { + dev_link_t *link = dev_to_instance(dev); + link->state &= ~DEV_SUSPEND; + + if (DEV_OK(link)) { struct serial_info *info = link->priv; int i; + if (!info->slave) + pcmcia_request_configuration(link->handle, &link->conf); + for (i = 0; i < info->ndev; i++) serial8250_resume_port(info->line[i]); - wakeup_card(info); } return 0; @@ -205,9 +197,10 @@ static int serial_resume(struct pcmcia_device *link) ======================================================================*/ -static int serial_probe(struct pcmcia_device *link) +static int serial_probe(struct pcmcia_device *p_dev) { struct serial_info *info; + dev_link_t *link; DEBUG(0, "serial_attach()\n"); @@ -216,7 +209,7 @@ static int serial_probe(struct pcmcia_device *link) if (!info) return -ENOMEM; memset(info, 0, sizeof (*info)); - info->p_dev = link; + link = &info->link; link->priv = info; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; @@ -230,7 +223,12 @@ static int serial_probe(struct pcmcia_device *link) } link->conf.IntType = INT_MEMORY_AND_IO; - return serial_config(link); + link->handle = p_dev; + p_dev->instance = link; + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + serial_config(link); + + return 0; } /*====================================================================== @@ -242,8 +240,9 @@ static int serial_probe(struct pcmcia_device *link) ======================================================================*/ -static void serial_detach(struct pcmcia_device *link) +static void serial_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct serial_info *info = link->priv; DEBUG(0, "serial_detach(0x%p)\n", link); @@ -264,7 +263,7 @@ static void serial_detach(struct pcmcia_device *link) /*====================================================================*/ -static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, +static int setup_serial(client_handle_t handle, struct serial_info * info, kio_addr_t iobase, int irq) { struct uart_port port; @@ -299,7 +298,7 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, /*====================================================================*/ static int -first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) +first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) { int i; i = pcmcia_get_first_tuple(handle, tuple); @@ -312,7 +311,7 @@ first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) } static int -next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) +next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) { int i; i = pcmcia_get_next_tuple(handle, tuple); @@ -326,10 +325,11 @@ next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) /*====================================================================*/ -static int simple_config(struct pcmcia_device *link) +static int simple_config(dev_link_t *link) { static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; static const int size_table[2] = { 8, 16 }; + client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; @@ -350,7 +350,7 @@ static int simple_config(struct pcmcia_device *link) buf = cfg_mem->buf; /* If the card is already configured, look up the port and irq */ - i = pcmcia_get_configuration_info(link, &config); + i = pcmcia_get_configuration_info(handle, &config); if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { kio_addr_t port = 0; if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { @@ -363,9 +363,10 @@ static int simple_config(struct pcmcia_device *link) } if (info->slave) { kfree(cfg_mem); - return setup_serial(link, info, port, config.AssignedIRQ); + return setup_serial(handle, info, port, config.AssignedIRQ); } } + link->conf.Vcc = config.Vcc; /* First pass: look for a config entry that looks normal. */ tuple->TupleData = (cisdata_t *) buf; @@ -376,12 +377,12 @@ static int simple_config(struct pcmcia_device *link) /* Two tries: without IO aliases, then with aliases */ for (s = 0; s < 2; s++) { for (try = 0; try < 2; try++) { - i = first_tuple(link, tuple, parse); + i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) && (cf->io.win[0].base != 0)) { @@ -389,19 +390,19 @@ static int simple_config(struct pcmcia_device *link) link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: - i = next_tuple(link, tuple, parse); + i = next_tuple(handle, tuple, parse); } } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - i = first_tuple(link, tuple, parse); + i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { @@ -409,48 +410,50 @@ next_entry: for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } } - i = next_tuple(link, tuple, parse); + i = next_tuple(handle, tuple, parse); } found_port: if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); kfree(cfg_mem); return -1; } - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { - cs_error(link, RequestIRQ, i); + cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } if (info->multi && (info->manfid == MANFID_3COM)) link->conf.ConfigIndex &= ~(0x08); - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { - cs_error(link, RequestConfiguration, i); + cs_error(link->handle, RequestConfiguration, i); kfree(cfg_mem); return -1; } kfree(cfg_mem); - return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); + return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); } -static int multi_config(struct pcmcia_device * link) +static int multi_config(dev_link_t * link) { + client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; + config_info_t config; int i, rc, base2 = 0; cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); @@ -461,6 +464,14 @@ static int multi_config(struct pcmcia_device * link) cf = &parse->cftable_entry; buf = cfg_mem->buf; + i = pcmcia_get_configuration_info(handle, &config); + if (i != CS_SUCCESS) { + cs_error(handle, GetConfigurationInfo, i); + rc = -1; + goto free_cfg_mem; + } + link->conf.Vcc = config.Vcc; + tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; @@ -469,7 +480,7 @@ static int multi_config(struct pcmcia_device * link) /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; - i = first_tuple(link, tuple, parse); + i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ @@ -479,19 +490,19 @@ static int multi_config(struct pcmcia_device * link) link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); base2 = link->io.BasePort1 + 8; if (i == CS_SUCCESS) break; } - i = next_tuple(link, tuple, parse); + i = next_tuple(handle, tuple, parse); } /* If that didn't work, look for two windows */ if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; - i = first_tuple(link, tuple, parse); + i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { link->conf.ConfigIndex = cf->index; @@ -499,26 +510,26 @@ static int multi_config(struct pcmcia_device * link) link->io.BasePort2 = cf->io.win[1].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); base2 = link->io.BasePort2; if (i == CS_SUCCESS) break; } - i = next_tuple(link, tuple, parse); + i = next_tuple(handle, tuple, parse); } } if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + cs_error(link->handle, RequestIO, i); rc = -1; goto free_cfg_mem; } - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); - cs_error(link, RequestIRQ, i); + cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } /* Socket Dual IO: this enables irq's for second port */ @@ -526,43 +537,35 @@ static int multi_config(struct pcmcia_device * link) link->conf.Present |= PRESENT_EXT_STATUS; link->conf.ExtStatus = ESR_REQ_ATTN_ENA; } - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { - cs_error(link, RequestConfiguration, i); + cs_error(link->handle, RequestConfiguration, i); rc = -1; goto free_cfg_mem; } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: - * 8 registers are for the UART, the others are extra registers. - * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too. - */ - if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO && - info->prodid == PRODID_POSSIO_GCC)) { - int err; - + 8 registers are for the UART, the others are extra registers */ + if (info->manfid == MANFID_OXSEMI) { if (cf->index == 1 || cf->index == 3) { - err = setup_serial(link, info, base2, - link->irq.AssignedIRQ); - base2 = link->io.BasePort1; + setup_serial(handle, info, base2, link->irq.AssignedIRQ); + outb(12, link->io.BasePort1 + 1); } else { - err = setup_serial(link, info, link->io.BasePort1, - link->irq.AssignedIRQ); + setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); + outb(12, base2 + 1); } - info->c950ctrl = base2; - wakeup_card(info); rc = 0; goto free_cfg_mem; } - setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); + setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); /* The Nokia cards are not really multiport cards */ if (info->manfid == MANFID_NOKIA) { rc = 0; goto free_cfg_mem; } for (i = 0; i < info->multi - 1; i++) - setup_serial(link, info, base2 + (8 * i), + setup_serial(handle, info, base2 + (8 * i), link->irq.AssignedIRQ); rc = 0; free_cfg_mem: @@ -578,8 +581,9 @@ free_cfg_mem: ======================================================================*/ -static int serial_config(struct pcmcia_device * link) +void serial_config(dev_link_t * link) { + client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; @@ -605,7 +609,7 @@ static int serial_config(struct pcmcia_device * link) tuple->Attributes = 0; /* Get configuration register information */ tuple->DesiredTuple = CISTPL_CONFIG; - last_ret = first_tuple(link, tuple, parse); + last_ret = first_tuple(handle, tuple, parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; @@ -613,16 +617,18 @@ static int serial_config(struct pcmcia_device * link) link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + /* Is this a compliant multifunction card? */ tuple->DesiredTuple = CISTPL_LONGLINK_MFC; tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; - info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS); + info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS); /* Is this a multiport card? */ tuple->DesiredTuple = CISTPL_MANFID; - if (first_tuple(link, tuple, parse) == CS_SUCCESS) { + if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { info->manfid = parse->manfid.manf; - info->prodid = le16_to_cpu(buf[1]); for (i = 0; i < MULTI_COUNT; i++) if ((info->manfid == multi_id[i].manfid) && (parse->manfid.card == multi_id[i].prodid)) @@ -635,11 +641,11 @@ static int serial_config(struct pcmcia_device * link) multifunction cards that ask for appropriate IO port ranges */ tuple->DesiredTuple = CISTPL_FUNCID; if ((info->multi == 0) && - ((first_tuple(link, tuple, parse) != CS_SUCCESS) || + ((first_tuple(handle, tuple, parse) != CS_SUCCESS) || (parse->funcid.func == CISTPL_FUNCID_MULTI) || (parse->funcid.func == CISTPL_FUNCID_SERIAL))) { tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - if (first_tuple(link, tuple, parse) == CS_SUCCESS) { + if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) info->multi = cf->io.win[0].len >> 3; if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && @@ -658,30 +664,31 @@ static int serial_config(struct pcmcia_device * link) if (info->manfid == MANFID_IBM) { conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; - last_ret = pcmcia_access_configuration_register(link, ®); + last_ret = pcmcia_access_configuration_register(link->handle, ®); if (last_ret) { last_fn = AccessConfigurationRegister; goto cs_failed; } reg.Action = CS_WRITE; reg.Value = reg.Value | 1; - last_ret = pcmcia_access_configuration_register(link, ®); + last_ret = pcmcia_access_configuration_register(link->handle, ®); if (last_ret) { last_fn = AccessConfigurationRegister; goto cs_failed; } } - link->dev_node = &info->node[0]; + link->dev = &info->node[0]; + link->state &= ~DEV_CONFIG_PENDING; kfree(cfg_mem); - return 0; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: serial_remove(link); + link->state &= ~DEV_CONFIG_PENDING; kfree(cfg_mem); - return -ENODEV; } static struct pcmcia_device_id serial_ids[] = { @@ -732,7 +739,6 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77), PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302), PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301), - PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276), PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), @@ -751,7 +757,6 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef), PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0), - PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e), PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a), PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02), PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa), diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index aa521b8e0..04186eaae 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c @@ -543,12 +543,6 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { #else # define LH7A40X_CONSOLE &lh7a40x_console -static void lh7a40xuart_console_putchar(struct uart_port *port, int ch) -{ - while (UR(port, UART_R_STATUS) & nTxRdy) - ; - UR(port, UART_R_DATA) = ch; -} static void lh7a40xuart_console_write (struct console* co, const char* s, @@ -562,7 +556,16 @@ static void lh7a40xuart_console_write (struct console* co, UR (port, UART_R_INTEN) = 0; /* Disable all interrupts */ BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */ - uart_console_write(port, s, count, lh7a40xuart_console_putchar); + for (; count-- > 0; ++s) { + while (UR (port, UART_R_STATUS) & nTxRdy) + ; + UR (port, UART_R_DATA) = *s; + if (*s == '\n') { + while ((UR (port, UART_R_STATUS) & TxBusy)) + ; + UR (port, UART_R_DATA) = '\r'; + } + } /* Wait until all characters are sent */ while (UR (port, UART_R_STATUS) & TxBusy) diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 3bdee64d1..ee98a867b 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -33,10 +33,6 @@ * 1.02 Cleanup. (import 8250.c changes) * 1.03 Fix low-latency mode. (import 8250.c changes) * 1.04 Remove usage of deprecated functions, cleanup. - * 1.05 More strict check in verify_port. Cleanup. - * 1.06 Do not insert a char caused previous overrun. - * Fix some spin_locks. - * Do not call uart_add_one_port for absent ports. */ #include @@ -61,7 +57,7 @@ #include #include -static char *serial_version = "1.06"; +static char *serial_version = "1.04"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -98,8 +94,6 @@ static char *serial_name = "TX39/49 Serial driver"; #define UART_NR 4 #endif -#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) - struct uart_txx9_port { struct uart_port port; @@ -216,7 +210,7 @@ static inline unsigned int sio_in(struct uart_txx9_port *up, int offset) { switch (up->port.iotype) { default: - return __raw_readl(up->port.membase + offset); + return *(volatile u32 *)(up->port.membase + offset); case UPIO_PORT: return inl(up->port.iobase + offset); } @@ -227,7 +221,7 @@ sio_out(struct uart_txx9_port *up, int offset, int value) { switch (up->port.iotype) { default: - __raw_writel(value, up->port.membase + offset); + *(volatile u32 *)(up->port.membase + offset) = value; break; case UPIO_PORT: outl(value, up->port.iobase + offset); @@ -265,19 +259,34 @@ sio_quot_set(struct uart_txx9_port *up, int quot) static void serial_txx9_stop_tx(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; + unsigned long flags; + + spin_lock_irqsave(&up->port.lock, flags); sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); + spin_unlock_irqrestore(&up->port.lock, flags); } static void serial_txx9_start_tx(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; + unsigned long flags; + + spin_lock_irqsave(&up->port.lock, flags); sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); + spin_unlock_irqrestore(&up->port.lock, flags); } static void serial_txx9_stop_rx(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; + unsigned long flags; + + spin_lock_irqsave(&up->port.lock, flags); up->port.read_status_mask &= ~TXX9_SIDISR_RDIS; +#if 0 + sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_RIE); +#endif + spin_unlock_irqrestore(&up->port.lock, flags); } static void serial_txx9_enable_ms(struct uart_port *port) @@ -293,16 +302,12 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r unsigned int disr = *status; int max_count = 256; char flag; - unsigned int next_ignore_status_mask; do { ch = sio_in(up, TXX9_SIRFIFO); flag = TTY_NORMAL; up->port.icount.rx++; - /* mask out RFDN_MASK bit added by previous overrun */ - next_ignore_status_mask = - up->port.ignore_status_mask & ~TXX9_SIDISR_RFDN_MASK; if (unlikely(disr & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER | TXX9_SIDISR_UFER | TXX9_SIDISR_UOER))) { /* @@ -323,17 +328,8 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r up->port.icount.parity++; else if (disr & TXX9_SIDISR_UFER) up->port.icount.frame++; - if (disr & TXX9_SIDISR_UOER) { + if (disr & TXX9_SIDISR_UOER) up->port.icount.overrun++; - /* - * The receiver read buffer still hold - * a char which caused overrun. - * Ignore next char by adding RFDN_MASK - * to ignore_status_mask temporarily. - */ - next_ignore_status_mask |= - TXX9_SIDISR_RFDN_MASK; - } /* * Mask off conditions which should be ingored. @@ -353,7 +349,6 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag); ignore_char: - up->port.ignore_status_mask = next_ignore_status_mask; disr = sio_in(up, TXX9_SIDISR); } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); spin_unlock(&up->port.lock); @@ -455,11 +450,14 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port) static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; + unsigned long flags; + spin_lock_irqsave(&up->port.lock, flags); if (mctrl & TIOCM_RTS) sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); else sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); + spin_unlock_irqrestore(&up->port.lock, flags); } static void serial_txx9_break_ctl(struct uart_port *port, int break_state) @@ -483,7 +481,7 @@ static int serial_txx9_startup(struct uart_port *port) /* * Clear the FIFO buffers and disable them. - * (they will be reenabled in set_termios()) + * (they will be reeanbled in set_termios()) */ sio_set(up, TXX9_SIFCR, TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); @@ -786,14 +784,8 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags) static int serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser) { - unsigned long new_port = ser->port; - if (HIGH_BITS_OFFSET) - new_port += (unsigned long)ser->port_high << HIGH_BITS_OFFSET; - if (ser->type != port->type || - ser->irq != port->irq || - ser->io_type != port->iotype || - new_port != port->iobase || - (unsigned long)ser->iomem_base != port->mapbase) + if (ser->irq < 0 || + ser->baud_base < 9600 || ser->type != PORT_TXX9) return -EINVAL; return 0; } @@ -835,8 +827,7 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv) up->port.line = i; up->port.ops = &serial_txx9_pops; - if (up->port.iobase || up->port.mapbase) - uart_add_one_port(drv, &up->port); + uart_add_one_port(drv, &up->port); } } @@ -863,14 +854,6 @@ static inline void wait_for_xmitr(struct uart_txx9_port *up) } } -static void serial_txx9_console_putchar(struct uart_port *port, int ch) -{ - struct uart_txx9_port *up = (struct uart_txx9_port *)port; - - wait_for_xmitr(up); - sio_out(up, TXX9_SITFIFO, ch); -} - /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -882,6 +865,7 @@ serial_txx9_console_write(struct console *co, const char *s, unsigned int count) { struct uart_txx9_port *up = &serial_txx9_ports[co->index]; unsigned int ier, flcr; + int i; /* * First save the UER then disable the interrupts @@ -895,7 +879,22 @@ serial_txx9_console_write(struct console *co, const char *s, unsigned int count) if (!(up->port.flags & UPF_CONS_FLOW) && (flcr & TXX9_SIFLCR_TES)) sio_out(up, TXX9_SIFLCR, flcr & ~TXX9_SIFLCR_TES); - uart_console_write(&up->port, s, count, serial_txx9_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(up); + + /* + * Send the character out. + * If a LF, also do CR... + */ + sio_out(up, TXX9_SITFIFO, *s); + if (*s == 10) { + wait_for_xmitr(up); + sio_out(up, TXX9_SITFIFO, 13); + } + } /* * Finally, wait for transmitter to become empty @@ -927,6 +926,11 @@ static int serial_txx9_console_setup(struct console *co, char *options) if (!port->ops) return -ENODEV; + /* + * Temporary fix. + */ + spin_lock_init(&port->lock); + /* * Disable UART interrupts, set DTR and RTS high * and set speed. @@ -1037,10 +1041,11 @@ static int __devinit serial_txx9_register_port(struct uart_port *port) mutex_lock(&serial_txx9_mutex); for (i = 0; i < UART_NR; i++) { uart = &serial_txx9_ports[i]; - if (!(uart->port.iobase || uart->port.mapbase)) + if (uart->port.type == PORT_UNKNOWN) break; } if (i < UART_NR) { + uart_remove_one_port(&serial_txx9_reg, &uart->port); uart->port.iobase = port->iobase; uart->port.membase = port->membase; uart->port.irq = port->irq; @@ -1075,8 +1080,9 @@ static void __devexit serial_txx9_unregister_port(int line) uart->port.type = PORT_UNKNOWN; uart->port.iobase = 0; uart->port.mapbase = 0; - uart->port.membase = NULL; + uart->port.membase = 0; uart->port.dev = NULL; + uart_add_one_port(&serial_txx9_reg, &uart->port); mutex_unlock(&serial_txx9_mutex); } @@ -1192,11 +1198,8 @@ static void __exit serial_txx9_exit(void) #ifdef ENABLE_SERIAL_TXX9_PCI pci_unregister_driver(&serial_txx9_pci_driver); #endif - for (i = 0; i < UART_NR; i++) { - struct uart_txx9_port *up = &serial_txx9_ports[i]; - if (up->port.iobase || up->port.mapbase) - uart_remove_one_port(&serial_txx9_reg, &up->port); - } + for (i = 0; i < UART_NR; i++) + uart_remove_one_port(&serial_txx9_reg, &serial_txx9_ports[i].port); uart_unregister_driver(&serial_txx9_reg); } diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c deleted file mode 100644 index f137804b3..000000000 --- a/drivers/serial/sunhv.c +++ /dev/null @@ -1,550 +0,0 @@ -/* sunhv.c: Serial driver for SUN4V hypervisor console. - * - * Copyright (C) 2006 David S. Miller (davem@davemloft.net) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#if defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include - -#include "suncore.h" - -#define CON_BREAK ((long)-1) -#define CON_HUP ((long)-2) - -static inline long hypervisor_con_getchar(long *status) -{ - register unsigned long func asm("%o5"); - register unsigned long arg0 asm("%o0"); - register unsigned long arg1 asm("%o1"); - - func = HV_FAST_CONS_GETCHAR; - arg0 = 0; - arg1 = 0; - __asm__ __volatile__("ta %6" - : "=&r" (func), "=&r" (arg0), "=&r" (arg1) - : "0" (func), "1" (arg0), "2" (arg1), - "i" (HV_FAST_TRAP)); - - *status = arg0; - - return (long) arg1; -} - -static inline long hypervisor_con_putchar(long ch) -{ - register unsigned long func asm("%o5"); - register unsigned long arg0 asm("%o0"); - - func = HV_FAST_CONS_PUTCHAR; - arg0 = ch; - __asm__ __volatile__("ta %4" - : "=&r" (func), "=&r" (arg0) - : "0" (func), "1" (arg0), "i" (HV_FAST_TRAP)); - - return (long) arg0; -} - -#define IGNORE_BREAK 0x1 -#define IGNORE_ALL 0x2 - -static int hung_up = 0; - -static struct tty_struct *receive_chars(struct uart_port *port, struct pt_regs *regs) -{ - struct tty_struct *tty = NULL; - int saw_console_brk = 0; - int limit = 10000; - - if (port->info != NULL) /* Unopened serial console */ - tty = port->info->tty; - - while (limit-- > 0) { - long status; - long c = hypervisor_con_getchar(&status); - unsigned char flag; - - if (status == HV_EWOULDBLOCK) - break; - - if (c == CON_BREAK) { - if (uart_handle_break(port)) - continue; - saw_console_brk = 1; - c = 0; - } - - if (c == CON_HUP) { - hung_up = 1; - uart_handle_dcd_change(port, 0); - } else if (hung_up) { - hung_up = 0; - uart_handle_dcd_change(port, 1); - } - - if (tty == NULL) { - uart_handle_sysrq_char(port, c, regs); - continue; - } - - flag = TTY_NORMAL; - port->icount.rx++; - if (c == CON_BREAK) { - port->icount.brk++; - if (uart_handle_break(port)) - continue; - flag = TTY_BREAK; - } - - if (uart_handle_sysrq_char(port, c, regs)) - continue; - - if ((port->ignore_status_mask & IGNORE_ALL) || - ((port->ignore_status_mask & IGNORE_BREAK) && - (c == CON_BREAK))) - continue; - - tty_insert_flip_char(tty, c, flag); - } - - if (saw_console_brk) - sun_do_break(); - - return tty; -} - -static void transmit_chars(struct uart_port *port) -{ - struct circ_buf *xmit; - - if (!port->info) - return; - - xmit = &port->info->xmit; - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - return; - - while (!uart_circ_empty(xmit)) { - long status = hypervisor_con_putchar(xmit->buf[xmit->tail]); - - if (status != HV_EOK) - break; - - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); -} - -static irqreturn_t sunhv_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct uart_port *port = dev_id; - struct tty_struct *tty; - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - tty = receive_chars(port, regs); - transmit_chars(port); - spin_unlock_irqrestore(&port->lock, flags); - - if (tty) - tty_flip_buffer_push(tty); - - return IRQ_HANDLED; -} - -/* port->lock is not held. */ -static unsigned int sunhv_tx_empty(struct uart_port *port) -{ - /* Transmitter is always empty for us. If the circ buffer - * is non-empty or there is an x_char pending, our caller - * will do the right thing and ignore what we return here. - */ - return TIOCSER_TEMT; -} - -/* port->lock held by caller. */ -static void sunhv_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - return; -} - -/* port->lock is held by caller and interrupts are disabled. */ -static unsigned int sunhv_get_mctrl(struct uart_port *port) -{ - return TIOCM_DSR | TIOCM_CAR | TIOCM_CTS; -} - -/* port->lock held by caller. */ -static void sunhv_stop_tx(struct uart_port *port) -{ - return; -} - -/* port->lock held by caller. */ -static void sunhv_start_tx(struct uart_port *port) -{ - struct circ_buf *xmit = &port->info->xmit; - - while (!uart_circ_empty(xmit)) { - long status = hypervisor_con_putchar(xmit->buf[xmit->tail]); - - if (status != HV_EOK) - break; - - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } -} - -/* port->lock is not held. */ -static void sunhv_send_xchar(struct uart_port *port, char ch) -{ - unsigned long flags; - int limit = 10000; - - spin_lock_irqsave(&port->lock, flags); - - while (limit-- > 0) { - long status = hypervisor_con_putchar(ch); - if (status == HV_EOK) - break; - } - - spin_unlock_irqrestore(&port->lock, flags); -} - -/* port->lock held by caller. */ -static void sunhv_stop_rx(struct uart_port *port) -{ -} - -/* port->lock held by caller. */ -static void sunhv_enable_ms(struct uart_port *port) -{ -} - -/* port->lock is not held. */ -static void sunhv_break_ctl(struct uart_port *port, int break_state) -{ - if (break_state) { - unsigned long flags; - int limit = 1000000; - - spin_lock_irqsave(&port->lock, flags); - - while (limit-- > 0) { - long status = hypervisor_con_putchar(CON_BREAK); - if (status == HV_EOK) - break; - udelay(2); - } - - spin_unlock_irqrestore(&port->lock, flags); - } -} - -/* port->lock is not held. */ -static int sunhv_startup(struct uart_port *port) -{ - return 0; -} - -/* port->lock is not held. */ -static void sunhv_shutdown(struct uart_port *port) -{ -} - -/* port->lock is not held. */ -static void sunhv_set_termios(struct uart_port *port, struct termios *termios, - struct termios *old) -{ - unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); - unsigned int quot = uart_get_divisor(port, baud); - unsigned int iflag, cflag; - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - - iflag = termios->c_iflag; - cflag = termios->c_cflag; - - port->ignore_status_mask = 0; - if (iflag & IGNBRK) - port->ignore_status_mask |= IGNORE_BREAK; - if ((cflag & CREAD) == 0) - port->ignore_status_mask |= IGNORE_ALL; - - /* XXX */ - uart_update_timeout(port, cflag, - (port->uartclk / (16 * quot))); - - spin_unlock_irqrestore(&port->lock, flags); -} - -static const char *sunhv_type(struct uart_port *port) -{ - return "SUN4V HCONS"; -} - -static void sunhv_release_port(struct uart_port *port) -{ -} - -static int sunhv_request_port(struct uart_port *port) -{ - return 0; -} - -static void sunhv_config_port(struct uart_port *port, int flags) -{ -} - -static int sunhv_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - return -EINVAL; -} - -static struct uart_ops sunhv_pops = { - .tx_empty = sunhv_tx_empty, - .set_mctrl = sunhv_set_mctrl, - .get_mctrl = sunhv_get_mctrl, - .stop_tx = sunhv_stop_tx, - .start_tx = sunhv_start_tx, - .send_xchar = sunhv_send_xchar, - .stop_rx = sunhv_stop_rx, - .enable_ms = sunhv_enable_ms, - .break_ctl = sunhv_break_ctl, - .startup = sunhv_startup, - .shutdown = sunhv_shutdown, - .set_termios = sunhv_set_termios, - .type = sunhv_type, - .release_port = sunhv_release_port, - .request_port = sunhv_request_port, - .config_port = sunhv_config_port, - .verify_port = sunhv_verify_port, -}; - -static struct uart_driver sunhv_reg = { - .owner = THIS_MODULE, - .driver_name = "serial", - .devfs_name = "tts/", - .dev_name = "ttyS", - .major = TTY_MAJOR, -}; - -static struct uart_port *sunhv_port; - -static inline void sunhv_console_putchar(struct uart_port *port, char c) -{ - unsigned long flags; - int limit = 1000000; - - spin_lock_irqsave(&port->lock, flags); - - while (limit-- > 0) { - long status = hypervisor_con_putchar(c); - if (status == HV_EOK) - break; - udelay(2); - } - - spin_unlock_irqrestore(&port->lock, flags); -} - -static void sunhv_console_write(struct console *con, const char *s, unsigned n) -{ - struct uart_port *port = sunhv_port; - int i; - - for (i = 0; i < n; i++) { - if (*s == '\n') - sunhv_console_putchar(port, '\r'); - sunhv_console_putchar(port, *s++); - } -} - -static struct console sunhv_console = { - .name = "ttyHV", - .write = sunhv_console_write, - .device = uart_console_device, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &sunhv_reg, -}; - -static inline struct console *SUNHV_CONSOLE(void) -{ - if (con_is_present()) - return NULL; - - sunhv_console.index = 0; - - return &sunhv_console; -} - -static int __init hv_console_compatible(char *buf, int len) -{ - while (len) { - int this_len; - - if (!strcmp(buf, "qcn")) - return 1; - - this_len = strlen(buf) + 1; - - buf += this_len; - len -= this_len; - } - - return 0; -} - -static unsigned int __init get_interrupt(void) -{ - const char *cons_str = "console"; - const char *compat_str = "compatible"; - int node = prom_getchild(sun4v_vdev_root); - char buf[64]; - int err, len; - - node = prom_searchsiblings(node, cons_str); - if (!node) - return 0; - - len = prom_getproplen(node, compat_str); - if (len == 0 || len == -1) - return 0; - - err = prom_getproperty(node, compat_str, buf, 64); - if (err == -1) - return 0; - - if (!hv_console_compatible(buf, len)) - return 0; - - /* Ok, the this is the OBP node for the sun4v hypervisor - * console device. Decode the interrupt. - */ - return sun4v_vdev_device_interrupt(node); -} - -static int __init sunhv_init(void) -{ - struct uart_port *port; - int ret; - - if (tlb_type != hypervisor) - return -ENODEV; - - port = kmalloc(sizeof(struct uart_port), GFP_KERNEL); - if (unlikely(!port)) - return -ENOMEM; - - memset(port, 0, sizeof(struct uart_port)); - - port->line = 0; - port->ops = &sunhv_pops; - port->type = PORT_SUNHV; - port->uartclk = ( 29491200 / 16 ); /* arbitrary */ - - /* Set this just to make uart_configure_port() happy. */ - port->membase = (unsigned char __iomem *) __pa(port); - - port->irq = get_interrupt(); - if (!port->irq) { - kfree(port); - return -ENODEV; - } - - sunhv_reg.minor = sunserial_current_minor; - sunhv_reg.nr = 1; - - ret = uart_register_driver(&sunhv_reg); - if (ret < 0) { - printk(KERN_ERR "SUNHV: uart_register_driver() failed %d\n", - ret); - kfree(port); - - return ret; - } - - sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64; - sunserial_current_minor += 1; - - sunhv_reg.cons = SUNHV_CONSOLE(); - - sunhv_port = port; - - ret = uart_add_one_port(&sunhv_reg, port); - if (ret < 0) { - printk(KERN_ERR "SUNHV: uart_add_one_port() failed %d\n", ret); - sunserial_current_minor -= 1; - uart_unregister_driver(&sunhv_reg); - kfree(port); - sunhv_port = NULL; - return -ENODEV; - } - - if (request_irq(port->irq, sunhv_interrupt, - SA_SHIRQ, "serial(sunhv)", port)) { - printk(KERN_ERR "sunhv: Cannot register IRQ\n"); - uart_remove_one_port(&sunhv_reg, port); - sunserial_current_minor -= 1; - uart_unregister_driver(&sunhv_reg); - kfree(port); - sunhv_port = NULL; - return -ENODEV; - } - - return 0; -} - -static void __exit sunhv_exit(void) -{ - struct uart_port *port = sunhv_port; - - BUG_ON(!port); - - free_irq(port->irq, port); - - uart_remove_one_port(&sunhv_reg, port); - sunserial_current_minor -= 1; - - uart_unregister_driver(&sunhv_reg); - - kfree(sunhv_port); - sunhv_port = NULL; -} - -module_init(sunhv_init); -module_exit(sunhv_exit); - -MODULE_AUTHOR("David S. Miller"); -MODULE_DESCRIPTION("SUN4V Hypervisor console driver") -MODULE_LICENSE("GPL"); diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index bfbe9dc90..85664228a 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -861,9 +861,8 @@ static int num_channels; #ifdef CONFIG_SERIAL_SUNSAB_CONSOLE -static void sunsab_console_putchar(struct uart_port *port, int c) +static __inline__ void sunsab_console_putchar(struct uart_sunsab_port *up, char c) { - struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; unsigned long flags; spin_lock_irqsave(&up->port.lock, flags); @@ -877,8 +876,13 @@ static void sunsab_console_putchar(struct uart_port *port, int c) static void sunsab_console_write(struct console *con, const char *s, unsigned n) { struct uart_sunsab_port *up = &sunsab_ports[con->index]; + int i; - uart_console_write(&up->port, s, n, sunsab_console_putchar); + for (i = 0; i < n; i++) { + if (*s == '\n') + sunsab_console_putchar(up, '\r'); + sunsab_console_putchar(up, *s++); + } sunsab_tec_wait(up); } @@ -951,13 +955,14 @@ static struct console sunsab_console = { .index = -1, .data = &sunsab_reg, }; +#define SUNSAB_CONSOLE (&sunsab_console) -static inline struct console *SUNSAB_CONSOLE(void) +static void __init sunsab_console_init(void) { int i; if (con_is_present()) - return NULL; + return; for (i = 0; i < num_channels; i++) { int this_minor = sunsab_reg.minor + i; @@ -966,14 +971,13 @@ static inline struct console *SUNSAB_CONSOLE(void) break; } if (i == num_channels) - return NULL; + return; sunsab_console.index = i; - - return &sunsab_console; + register_console(&sunsab_console); } #else -#define SUNSAB_CONSOLE() (NULL) +#define SUNSAB_CONSOLE (NULL) #define sunsab_console_init() do { } while (0) #endif @@ -1120,6 +1124,7 @@ static int __init sunsab_init(void) sunsab_reg.minor = sunserial_current_minor; sunsab_reg.nr = num_channels; + sunsab_reg.cons = SUNSAB_CONSOLE; ret = uart_register_driver(&sunsab_reg); if (ret < 0) { @@ -1138,12 +1143,10 @@ static int __init sunsab_init(void) return ret; } - sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64; - - sunsab_reg.cons = SUNSAB_CONSOLE(); - sunserial_current_minor += num_channels; + sunsab_console_init(); + for (i = 0; i < num_channels; i++) { struct uart_sunsab_port *up = &sunsab_ports[i]; diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 2b4f96541..4e453fa96 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -102,7 +102,9 @@ struct uart_sunsu_port { #endif }; -static unsigned int serial_in(struct uart_sunsu_port *up, int offset) +#define _INLINE_ + +static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset) { offset <<= up->port.regshift; @@ -119,7 +121,8 @@ static unsigned int serial_in(struct uart_sunsu_port *up, int offset) } } -static void serial_out(struct uart_sunsu_port *up, int offset, int value) +static _INLINE_ void +serial_out(struct uart_sunsu_port *up, int offset, int value) { #ifndef CONFIG_SPARC64 /* @@ -313,7 +316,7 @@ static void sunsu_enable_ms(struct uart_port *port) spin_unlock_irqrestore(&up->port.lock, flags); } -static struct tty_struct * +static _INLINE_ struct tty_struct * receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; @@ -392,7 +395,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs return tty; } -static void transmit_chars(struct uart_sunsu_port *up) +static _INLINE_ void transmit_chars(struct uart_sunsu_port *up) { struct circ_buf *xmit = &up->port.info->xmit; int count; @@ -428,7 +431,7 @@ static void transmit_chars(struct uart_sunsu_port *up) __stop_tx(up); } -static void check_modem_status(struct uart_sunsu_port *up) +static _INLINE_ void check_modem_status(struct uart_sunsu_port *up) { int status; @@ -641,7 +644,7 @@ static int sunsu_startup(struct uart_port *port) /* * Clear the FIFO buffers and disable them. - * (they will be reenabled in set_termios()) + * (they will be reeanbled in set_termios()) */ if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) { serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); @@ -1277,7 +1280,6 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel) struct serio *serio; #endif - spin_lock_init(&up->port.lock); up->port.line = channel; up->port.type = PORT_UNKNOWN; up->port.uartclk = (SU_BASE_BAUD * 16); @@ -1374,14 +1376,6 @@ static __inline__ void wait_for_xmitr(struct uart_sunsu_port *up) } } -static void sunsu_console_putchar(struct uart_port *port, int ch) -{ - struct uart_sunsu_port *up = (struct uart_sunsu_port *)port; - - wait_for_xmitr(up); - serial_out(up, UART_TX, ch); -} - /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -1391,6 +1385,7 @@ static void sunsu_console_write(struct console *co, const char *s, { struct uart_sunsu_port *up = &sunsu_ports[co->index]; unsigned int ier; + int i; /* * First save the UER then disable the interrupts @@ -1398,7 +1393,22 @@ static void sunsu_console_write(struct console *co, const char *s, ier = serial_in(up, UART_IER); serial_out(up, UART_IER, 0); - uart_console_write(&up->port, s, count, sunsu_console_putchar); + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(up); + + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_out(up, UART_TX, *s); + if (*s == 10) { + wait_for_xmitr(up); + serial_out(up, UART_TX, 13); + } + } /* * Finally, wait for transmitter to become empty @@ -1454,17 +1464,18 @@ static struct console sunsu_cons = { .index = -1, .data = &sunsu_reg, }; +#define SUNSU_CONSOLE (&sunsu_cons) /* * Register console. */ -static inline struct console *SUNSU_CONSOLE(void) +static int __init sunsu_serial_console_init(void) { int i; if (con_is_present()) - return NULL; + return 0; for (i = 0; i < UART_NR; i++) { int this_minor = sunsu_reg.minor + i; @@ -1473,16 +1484,16 @@ static inline struct console *SUNSU_CONSOLE(void) break; } if (i == UART_NR) - return NULL; + return 0; if (sunsu_ports[i].port_node == 0) - return NULL; + return 0; sunsu_cons.index = i; - - return &sunsu_cons; + register_console(&sunsu_cons); + return 0; } #else -#define SUNSU_CONSOLE() (NULL) +#define SUNSU_CONSOLE (NULL) #define sunsu_serial_console_init() do { } while (0) #endif @@ -1499,7 +1510,6 @@ static int __init sunsu_serial_init(void) up->su_type == SU_PORT_KBD) continue; - spin_lock_init(&up->port.lock); up->port.flags |= UPF_BOOT_AUTOCONF; up->port.type = PORT_UNKNOWN; up->port.uartclk = (SU_BASE_BAUD * 16); @@ -1513,19 +1523,16 @@ static int __init sunsu_serial_init(void) } sunsu_reg.minor = sunserial_current_minor; + sunserial_current_minor += instance; sunsu_reg.nr = instance; + sunsu_reg.cons = SUNSU_CONSOLE; ret = uart_register_driver(&sunsu_reg); if (ret < 0) return ret; - sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64; - - sunserial_current_minor += instance; - - sunsu_reg.cons = SUNSU_CONSOLE(); - + sunsu_serial_console_init(); for (i = 0; i < UART_NR; i++) { struct uart_sunsu_port *up = &sunsu_ports[i]; @@ -1730,4 +1737,3 @@ static void __exit sunsu_exit(void) module_init(sunsu_probe); module_exit(sunsu_exit); -MODULE_LICENSE("GPL"); diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index cd49ebbf4..5cc4d4c29 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1252,9 +1252,8 @@ static struct zilog_layout __iomem * __init get_zs(int chip, int node) #define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */ -static void sunzilog_putchar(struct uart_port *port, int ch) +static void sunzilog_put_char(struct zilog_channel __iomem *channel, unsigned char ch) { - struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); int loops = ZS_PUT_CHAR_MAX_DELAY; /* This is a timed polling loop so do not switch the explicit @@ -1285,7 +1284,7 @@ static int sunzilog_serio_write(struct serio *serio, unsigned char ch) spin_lock_irqsave(&sunzilog_serio_lock, flags); - sunzilog_putchar(&up->port, ch); + sunzilog_put_char(ZILOG_CHANNEL_FROM_PORT(&up->port), ch); spin_unlock_irqrestore(&sunzilog_serio_lock, flags); @@ -1326,10 +1325,16 @@ static void sunzilog_console_write(struct console *con, const char *s, unsigned int count) { struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; + struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port); unsigned long flags; + int i; spin_lock_irqsave(&up->port.lock, flags); - uart_console_write(&up->port, s, count, sunzilog_putchar); + for (i = 0; i < count; i++, s++) { + sunzilog_put_char(channel, *s); + if (*s == 10) + sunzilog_put_char(channel, 13); + } udelay(2); spin_unlock_irqrestore(&up->port.lock, flags); } @@ -1385,6 +1390,7 @@ static struct console sunzilog_console = { .index = -1, .data = &sunzilog_reg, }; +#define SUNZILOG_CONSOLE (&sunzilog_console) static int __init sunzilog_console_init(void) { @@ -1407,31 +1413,8 @@ static int __init sunzilog_console_init(void) register_console(&sunzilog_console); return 0; } - -static inline struct console *SUNZILOG_CONSOLE(void) -{ - int i; - - if (con_is_present()) - return NULL; - - for (i = 0; i < NUM_CHANNELS; i++) { - int this_minor = sunzilog_reg.minor + i; - - if ((this_minor - 64) == (serial_console - 1)) - break; - } - if (i == NUM_CHANNELS) - return NULL; - - sunzilog_console.index = i; - sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS; - - return &sunzilog_console; -} - #else -#define SUNZILOG_CONSOLE() (NULL) +#define SUNZILOG_CONSOLE (NULL) #define sunzilog_console_init() do { } while (0) #endif @@ -1683,15 +1666,14 @@ static int __init sunzilog_ports_init(void) } sunzilog_reg.nr = uart_count; + sunzilog_reg.cons = SUNZILOG_CONSOLE; + sunzilog_reg.minor = sunserial_current_minor; + sunserial_current_minor += uart_count; ret = uart_register_driver(&sunzilog_reg); if (ret == 0) { - sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; - sunzilog_reg.cons = SUNZILOG_CONSOLE(); - - sunserial_current_minor += uart_count; - + sunzilog_console_init(); for (i = 0; i < NUM_CHANNELS; i++) { struct uart_sunzilog_port *up = &sunzilog_port_table[i]; diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index df5e8713f..d61494d18 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c @@ -821,23 +821,25 @@ static void wait_for_xmitr(struct uart_port *port) } } -static void siu_console_putchar(struct uart_port *port, int ch) -{ - wait_for_xmitr(port); - siu_write(port, UART_TX, ch); -} - static void siu_console_write(struct console *con, const char *s, unsigned count) { struct uart_port *port; uint8_t ier; + unsigned i; port = &siu_uart_ports[con->index]; ier = siu_read(port, UART_IER); siu_write(port, UART_IER, 0); - uart_console_write(port, s, count, siu_console_putchar); + for (i = 0; i < count && *s != '\0'; i++, s++) { + wait_for_xmitr(port); + siu_write(port, UART_TX, *s); + if (*s == '\n') { + wait_for_xmitr(port); + siu_write(port, UART_TX, '\r'); + } + } wait_for_xmitr(port); siu_write(port, UART_IER, ier); @@ -917,7 +919,7 @@ static struct uart_driver siu_uart_driver = { .cons = SERIAL_VR41XX_CONSOLE, }; -static int __devinit siu_probe(struct platform_device *dev) +static int siu_probe(struct platform_device *dev) { struct uart_port *port; int num, i, retval; @@ -951,7 +953,7 @@ static int __devinit siu_probe(struct platform_device *dev) return 0; } -static int __devexit siu_remove(struct platform_device *dev) +static int siu_remove(struct platform_device *dev) { struct uart_port *port; int i; @@ -1004,28 +1006,21 @@ static struct platform_device *siu_platform_device; static struct platform_driver siu_device_driver = { .probe = siu_probe, - .remove = __devexit_p(siu_remove), + .remove = siu_remove, .suspend = siu_suspend, .resume = siu_resume, .driver = { .name = "SIU", - .owner = THIS_MODULE, }, }; -static int __init vr41xx_siu_init(void) +static int __devinit vr41xx_siu_init(void) { int retval; - siu_platform_device = platform_device_alloc("SIU", -1); - if (!siu_platform_device) - return -ENOMEM; - - retval = platform_device_add(siu_platform_device); - if (retval < 0) { - platform_device_put(siu_platform_device); - return retval; - } + siu_platform_device = platform_device_register_simple("SIU", -1, NULL, 0); + if (IS_ERR(siu_platform_device)) + return PTR_ERR(siu_platform_device); retval = platform_driver_register(&siu_device_driver); if (retval < 0) @@ -1034,9 +1029,10 @@ static int __init vr41xx_siu_init(void) return retval; } -static void __exit vr41xx_siu_exit(void) +static void __devexit vr41xx_siu_exit(void) { platform_driver_unregister(&siu_device_driver); + platform_device_unregister(siu_platform_device); } diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index 501316b19..4bd05a007 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -620,9 +619,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, 0xffffffffffffffffULL); if (!ret) { - ret = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); + ret = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); if (ret < 0) { printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA " "for consistent allocations\n", diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index cdeff9094..771e86810 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -54,10 +54,11 @@ * Submodule management * ************************/ -static DEFINE_MUTEX(ioc4_mutex); - static LIST_HEAD(ioc4_devices); +static DECLARE_RWSEM(ioc4_devices_rwsem); + static LIST_HEAD(ioc4_submodules); +static DECLARE_RWSEM(ioc4_submodules_rwsem); /* Register an IOC4 submodule */ int @@ -65,13 +66,15 @@ ioc4_register_submodule(struct ioc4_submodule *is) { struct ioc4_driver_data *idd; - mutex_lock(&ioc4_mutex); + down_write(&ioc4_submodules_rwsem); list_add(&is->is_list, &ioc4_submodules); + up_write(&ioc4_submodules_rwsem); /* Initialize submodule for each IOC4 */ if (!is->is_probe) - goto out; + return 0; + down_read(&ioc4_devices_rwsem); list_for_each_entry(idd, &ioc4_devices, idd_list) { if (is->is_probe(idd)) { printk(KERN_WARNING @@ -81,8 +84,8 @@ ioc4_register_submodule(struct ioc4_submodule *is) pci_name(idd->idd_pdev)); } } - out: - mutex_unlock(&ioc4_mutex); + up_read(&ioc4_devices_rwsem); + return 0; } @@ -92,13 +95,15 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) { struct ioc4_driver_data *idd; - mutex_lock(&ioc4_mutex); + down_write(&ioc4_submodules_rwsem); list_del(&is->is_list); + up_write(&ioc4_submodules_rwsem); /* Remove submodule for each IOC4 */ if (!is->is_remove) - goto out; + return; + down_read(&ioc4_devices_rwsem); list_for_each_entry(idd, &ioc4_devices, idd_list) { if (is->is_remove(idd)) { printk(KERN_WARNING @@ -108,8 +113,7 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) pci_name(idd->idd_pdev)); } } - out: - mutex_unlock(&ioc4_mutex); + up_read(&ioc4_devices_rwsem); } /********************* @@ -308,11 +312,12 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) /* Track PCI-device specific data */ idd->idd_serial_data = NULL; pci_set_drvdata(idd->idd_pdev, idd); - - mutex_lock(&ioc4_mutex); + down_write(&ioc4_devices_rwsem); list_add_tail(&idd->idd_list, &ioc4_devices); + up_write(&ioc4_devices_rwsem); /* Add this IOC4 to all submodules */ + down_read(&ioc4_submodules_rwsem); list_for_each_entry(is, &ioc4_submodules, is_list) { if (is->is_probe && is->is_probe(idd)) { printk(KERN_WARNING @@ -322,7 +327,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) pci_name(idd->idd_pdev)); } } - mutex_unlock(&ioc4_mutex); + up_read(&ioc4_submodules_rwsem); return 0; @@ -346,7 +351,7 @@ ioc4_remove(struct pci_dev *pdev) idd = pci_get_drvdata(pdev); /* Remove this IOC4 from all submodules */ - mutex_lock(&ioc4_mutex); + down_read(&ioc4_submodules_rwsem); list_for_each_entry(is, &ioc4_submodules, is_list) { if (is->is_remove && is->is_remove(idd)) { printk(KERN_WARNING @@ -356,7 +361,7 @@ ioc4_remove(struct pci_dev *pdev) pci_name(idd->idd_pdev)); } } - mutex_unlock(&ioc4_mutex); + up_read(&ioc4_submodules_rwsem); /* Release resources */ iounmap(idd->idd_misc_regs); @@ -372,9 +377,9 @@ ioc4_remove(struct pci_dev *pdev) pci_disable_device(pdev); /* Remove and free driver data */ - mutex_lock(&ioc4_mutex); + down_write(&ioc4_devices_rwsem); list_del(&idd->idd_list); - mutex_unlock(&ioc4_mutex); + up_write(&ioc4_devices_rwsem); kfree(idd); } diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 23334c8bc..7a75faeb0 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -75,45 +75,11 @@ config SPI_BUTTERFLY inexpensive battery powered microcontroller evaluation board. This same cable can be used to flash new firmware. -config SPI_MPC83xx - tristate "Freescale MPC83xx SPI controller" - depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL - select SPI_BITBANG - help - This enables using the Freescale MPC83xx SPI controller in master - mode. - - Note, this driver uniquely supports the SPI controller on the MPC83xx - family of PowerPC processors. The MPC83xx uses a simple set of shift - registers for data (opposed to the CPM based descriptor model). - -config SPI_PXA2XX - tristate "PXA2xx SSP SPI master" - depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL - help - This enables using a PXA2xx SSP port as a SPI master controller. - The driver can be configured to use any SSP port and additional - documentation can be found a Documentation/spi/pxa2xx. - -config SPI_S3C24XX_GPIO - tristate "Samsung S3C24XX series SPI by GPIO" - depends on SPI_MASTER && ARCH_S3C2410 && SPI_BITBANG && EXPERIMENTAL - help - SPI driver for Samsung S3C24XX series ARM SoCs using - GPIO lines to provide the SPI bus. This can be used where - the inbuilt hardware cannot provide the transfer mode, or - where the board is using non hardware connected pins. # # Add new SPI master controllers in alphabetical order above this line # -config SPI_S3C24XX - tristate "Samsung S3C24XX series SPI" - depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL - help - SPI driver for Samsung S3C24XX series ARM SoCs - # # There are lots of SPI device types, with sensors and memory # being probably the most widely used ones. diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 8f4cb6799..c2c87e845 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -13,10 +13,6 @@ obj-$(CONFIG_SPI_MASTER) += spi.o # SPI master controller drivers (bus) obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o -obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o -obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o -obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o -obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o # ... add above this line ... # SPI protocol drivers (device/link on bus) diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c deleted file mode 100644 index 29aec77f9..000000000 --- a/drivers/spi/pxa2xx_spi.c +++ /dev/null @@ -1,1486 +0,0 @@ -/* - * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -MODULE_AUTHOR("Stephen Street"); -MODULE_DESCRIPTION("PXA2xx SSP SPI Contoller"); -MODULE_LICENSE("GPL"); - -#define MAX_BUSES 3 - -#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) -#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) -#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) - -#define DEFINE_SSP_REG(reg, off) \ -static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \ -static inline void write_##reg(u32 v, void *p) { __raw_writel(v, p + (off)); } - -DEFINE_SSP_REG(SSCR0, 0x00) -DEFINE_SSP_REG(SSCR1, 0x04) -DEFINE_SSP_REG(SSSR, 0x08) -DEFINE_SSP_REG(SSITR, 0x0c) -DEFINE_SSP_REG(SSDR, 0x10) -DEFINE_SSP_REG(SSTO, 0x28) -DEFINE_SSP_REG(SSPSP, 0x2c) - -#define START_STATE ((void*)0) -#define RUNNING_STATE ((void*)1) -#define DONE_STATE ((void*)2) -#define ERROR_STATE ((void*)-1) - -#define QUEUE_RUNNING 0 -#define QUEUE_STOPPED 1 - -struct driver_data { - /* Driver model hookup */ - struct platform_device *pdev; - - /* SPI framework hookup */ - enum pxa_ssp_type ssp_type; - struct spi_master *master; - - /* PXA hookup */ - struct pxa2xx_spi_master *master_info; - - /* DMA setup stuff */ - int rx_channel; - int tx_channel; - u32 *null_dma_buf; - - /* SSP register addresses */ - void *ioaddr; - u32 ssdr_physical; - - /* SSP masks*/ - u32 dma_cr1; - u32 int_cr1; - u32 clear_sr; - u32 mask_sr; - - /* Driver message queue */ - struct workqueue_struct *workqueue; - struct work_struct pump_messages; - spinlock_t lock; - struct list_head queue; - int busy; - int run; - - /* Message Transfer pump */ - struct tasklet_struct pump_transfers; - - /* Current message transfer state info */ - struct spi_message* cur_msg; - struct spi_transfer* cur_transfer; - struct chip_data *cur_chip; - size_t len; - void *tx; - void *tx_end; - void *rx; - void *rx_end; - int dma_mapped; - dma_addr_t rx_dma; - dma_addr_t tx_dma; - size_t rx_map_len; - size_t tx_map_len; - u8 n_bytes; - u32 dma_width; - int cs_change; - void (*write)(struct driver_data *drv_data); - void (*read)(struct driver_data *drv_data); - irqreturn_t (*transfer_handler)(struct driver_data *drv_data); - void (*cs_control)(u32 command); -}; - -struct chip_data { - u32 cr0; - u32 cr1; - u32 to; - u32 psp; - u32 timeout; - u8 n_bytes; - u32 dma_width; - u32 dma_burst_size; - u32 threshold; - u32 dma_threshold; - u8 enable_dma; - u8 bits_per_word; - u32 speed_hz; - void (*write)(struct driver_data *drv_data); - void (*read)(struct driver_data *drv_data); - void (*cs_control)(u32 command); -}; - -static void pump_messages(void *data); - -static int flush(struct driver_data *drv_data) -{ - unsigned long limit = loops_per_jiffy << 1; - - void *reg = drv_data->ioaddr; - - do { - while (read_SSSR(reg) & SSSR_RNE) { - read_SSDR(reg); - } - } while ((read_SSSR(reg) & SSSR_BSY) && limit--); - write_SSSR(SSSR_ROR, reg); - - return limit; -} - -static void restore_state(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - /* Clear status and disable clock */ - write_SSSR(drv_data->clear_sr, reg); - write_SSCR0(drv_data->cur_chip->cr0 & ~SSCR0_SSE, reg); - - /* Load the registers */ - write_SSCR1(drv_data->cur_chip->cr1, reg); - write_SSCR0(drv_data->cur_chip->cr0, reg); - if (drv_data->ssp_type != PXA25x_SSP) { - write_SSTO(0, reg); - write_SSPSP(drv_data->cur_chip->psp, reg); - } -} - -static void null_cs_control(u32 command) -{ -} - -static void null_writer(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - u8 n_bytes = drv_data->n_bytes; - - while ((read_SSSR(reg) & SSSR_TNF) - && (drv_data->tx < drv_data->tx_end)) { - write_SSDR(0, reg); - drv_data->tx += n_bytes; - } -} - -static void null_reader(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - u8 n_bytes = drv_data->n_bytes; - - while ((read_SSSR(reg) & SSSR_RNE) - && (drv_data->rx < drv_data->rx_end)) { - read_SSDR(reg); - drv_data->rx += n_bytes; - } -} - -static void u8_writer(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_TNF) - && (drv_data->tx < drv_data->tx_end)) { - write_SSDR(*(u8 *)(drv_data->tx), reg); - ++drv_data->tx; - } -} - -static void u8_reader(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_RNE) - && (drv_data->rx < drv_data->rx_end)) { - *(u8 *)(drv_data->rx) = read_SSDR(reg); - ++drv_data->rx; - } -} - -static void u16_writer(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_TNF) - && (drv_data->tx < drv_data->tx_end)) { - write_SSDR(*(u16 *)(drv_data->tx), reg); - drv_data->tx += 2; - } -} - -static void u16_reader(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_RNE) - && (drv_data->rx < drv_data->rx_end)) { - *(u16 *)(drv_data->rx) = read_SSDR(reg); - drv_data->rx += 2; - } -} -static void u32_writer(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_TNF) - && (drv_data->tx < drv_data->tx_end)) { - write_SSDR(*(u32 *)(drv_data->tx), reg); - drv_data->tx += 4; - } -} - -static void u32_reader(struct driver_data *drv_data) -{ - void *reg = drv_data->ioaddr; - - while ((read_SSSR(reg) & SSSR_RNE) - && (drv_data->rx < drv_data->rx_end)) { - *(u32 *)(drv_data->rx) = read_SSDR(reg); - drv_data->rx += 4; - } -} - -static void *next_transfer(struct driver_data *drv_data) -{ - struct spi_message *msg = drv_data->cur_msg; - struct spi_transfer *trans = drv_data->cur_transfer; - - /* Move to next transfer */ - if (trans->transfer_list.next != &msg->transfers) { - drv_data->cur_transfer = - list_entry(trans->transfer_list.next, - struct spi_transfer, - transfer_list); - return RUNNING_STATE; - } else - return DONE_STATE; -} - -static int map_dma_buffers(struct driver_data *drv_data) -{ - struct spi_message *msg = drv_data->cur_msg; - struct device *dev = &msg->spi->dev; - - if (!drv_data->cur_chip->enable_dma) - return 0; - - if (msg->is_dma_mapped) - return drv_data->rx_dma && drv_data->tx_dma; - - if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx)) - return 0; - - /* Modify setup if rx buffer is null */ - if (drv_data->rx == NULL) { - *drv_data->null_dma_buf = 0; - drv_data->rx = drv_data->null_dma_buf; - drv_data->rx_map_len = 4; - } else - drv_data->rx_map_len = drv_data->len; - - - /* Modify setup if tx buffer is null */ - if (drv_data->tx == NULL) { - *drv_data->null_dma_buf = 0; - drv_data->tx = drv_data->null_dma_buf; - drv_data->tx_map_len = 4; - } else - drv_data->tx_map_len = drv_data->len; - - /* Stream map the rx buffer */ - drv_data->rx_dma = dma_map_single(dev, drv_data->rx, - drv_data->rx_map_len, - DMA_FROM_DEVICE); - if (dma_mapping_error(drv_data->rx_dma)) - return 0; - - /* Stream map the tx buffer */ - drv_data->tx_dma = dma_map_single(dev, drv_data->tx, - drv_data->tx_map_len, - DMA_TO_DEVICE); - - if (dma_mapping_error(drv_data->tx_dma)) { - dma_unmap_single(dev, drv_data->rx_dma, - drv_data->rx_map_len, DMA_FROM_DEVICE); - return 0; - } - - return 1; -} - -static void unmap_dma_buffers(struct driver_data *drv_data) -{ - struct device *dev; - - if (!drv_data->dma_mapped) - return; - - if (!drv_data->cur_msg->is_dma_mapped) { - dev = &drv_data->cur_msg->spi->dev; - dma_unmap_single(dev, drv_data->rx_dma, - drv_data->rx_map_len, DMA_FROM_DEVICE); - dma_unmap_single(dev, drv_data->tx_dma, - drv_data->tx_map_len, DMA_TO_DEVICE); - } - - drv_data->dma_mapped = 0; -} - -/* caller already set message->status; dma and pio irqs are blocked */ -static void giveback(struct driver_data *drv_data) -{ - struct spi_transfer* last_transfer; - unsigned long flags; - struct spi_message *msg; - - spin_lock_irqsave(&drv_data->lock, flags); - 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); - - last_transfer = list_entry(msg->transfers.prev, - struct spi_transfer, - transfer_list); - - if (!last_transfer->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); - - msg->state = NULL; - if (msg->complete) - msg->complete(msg->context); -} - -static int wait_ssp_rx_stall(void *ioaddr) -{ - unsigned long limit = loops_per_jiffy << 1; - - while ((read_SSSR(ioaddr) & SSSR_BSY) && limit--) - cpu_relax(); - - return limit; -} - -static int wait_dma_channel_stop(int channel) -{ - unsigned long limit = loops_per_jiffy << 1; - - while (!(DCSR(channel) & DCSR_STOPSTATE) && limit--) - cpu_relax(); - - return limit; -} - -static void dma_handler(int channel, void *data, struct pt_regs *regs) -{ - struct driver_data *drv_data = data; - struct spi_message *msg = drv_data->cur_msg; - void *reg = drv_data->ioaddr; - u32 irq_status = DCSR(channel) & DMA_INT_MASK; - u32 trailing_sssr = 0; - - if (irq_status & DCSR_BUSERR) { - - /* Disable interrupts, clear status and reset DMA */ - write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); - write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - - if (flush(drv_data) == 0) - dev_err(&drv_data->pdev->dev, - "dma_handler: flush fail\n"); - - unmap_dma_buffers(drv_data); - - if (channel == drv_data->tx_channel) - dev_err(&drv_data->pdev->dev, - "dma_handler: bad bus address on " - "tx channel %d, source %x target = %x\n", - channel, DSADR(channel), DTADR(channel)); - else - dev_err(&drv_data->pdev->dev, - "dma_handler: bad bus address on " - "rx channel %d, source %x target = %x\n", - channel, DSADR(channel), DTADR(channel)); - - msg->state = ERROR_STATE; - tasklet_schedule(&drv_data->pump_transfers); - } - - /* PXA255x_SSP has no timeout interrupt, wait for tailing bytes */ - if ((drv_data->ssp_type == PXA25x_SSP) - && (channel == drv_data->tx_channel) - && (irq_status & DCSR_ENDINTR)) { - - /* Wait for rx to stall */ - if (wait_ssp_rx_stall(drv_data->ioaddr) == 0) - dev_err(&drv_data->pdev->dev, - "dma_handler: ssp rx stall failed\n"); - - /* Clear and disable interrupts on SSP and DMA channels*/ - write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - if (wait_dma_channel_stop(drv_data->rx_channel) == 0) - dev_err(&drv_data->pdev->dev, - "dma_handler: dma rx channel stop failed\n"); - - unmap_dma_buffers(drv_data); - - /* Read trailing bytes */ - /* Calculate number of trailing bytes, read them */ - trailing_sssr = read_SSSR(reg); - if ((trailing_sssr & 0xf008) != 0xf000) { - drv_data->rx = drv_data->rx_end - - (((trailing_sssr >> 12) & 0x0f) + 1); - drv_data->read(drv_data); - } - msg->actual_length += drv_data->len; - - /* Release chip select if requested, transfer delays are - * handled in pump_transfers */ - if (drv_data->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); - - /* Move to next transfer */ - msg->state = next_transfer(drv_data); - - /* Schedule transfer tasklet */ - tasklet_schedule(&drv_data->pump_transfers); - } -} - -static irqreturn_t dma_transfer(struct driver_data *drv_data) -{ - u32 irq_status; - u32 trailing_sssr = 0; - struct spi_message *msg = drv_data->cur_msg; - void *reg = drv_data->ioaddr; - - irq_status = read_SSSR(reg) & drv_data->mask_sr; - if (irq_status & SSSR_ROR) { - /* Clear and disable interrupts on SSP and DMA channels*/ - write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); - write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - unmap_dma_buffers(drv_data); - - if (flush(drv_data) == 0) - dev_err(&drv_data->pdev->dev, - "dma_transfer: flush fail\n"); - - dev_warn(&drv_data->pdev->dev, "dma_transfer: fifo overun\n"); - - drv_data->cur_msg->state = ERROR_STATE; - tasklet_schedule(&drv_data->pump_transfers); - - return IRQ_HANDLED; - } - - /* Check for false positive timeout */ - if ((irq_status & SSSR_TINT) && DCSR(drv_data->tx_channel) & DCSR_RUN) { - write_SSSR(SSSR_TINT, reg); - return IRQ_HANDLED; - } - - if (irq_status & SSSR_TINT || drv_data->rx == drv_data->rx_end) { - - /* Clear and disable interrupts on SSP and DMA channels*/ - write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - - if (wait_dma_channel_stop(drv_data->rx_channel) == 0) - dev_err(&drv_data->pdev->dev, - "dma_transfer: dma rx channel stop failed\n"); - - if (wait_ssp_rx_stall(drv_data->ioaddr) == 0) - dev_err(&drv_data->pdev->dev, - "dma_transfer: ssp rx stall failed\n"); - - unmap_dma_buffers(drv_data); - - /* Calculate number of trailing bytes, read them */ - trailing_sssr = read_SSSR(reg); - if ((trailing_sssr & 0xf008) != 0xf000) { - drv_data->rx = drv_data->rx_end - - (((trailing_sssr >> 12) & 0x0f) + 1); - drv_data->read(drv_data); - } - msg->actual_length += drv_data->len; - - /* Release chip select if requested, transfer delays are - * handled in pump_transfers */ - if (drv_data->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); - - /* Move to next transfer */ - msg->state = next_transfer(drv_data); - - /* Schedule transfer tasklet */ - tasklet_schedule(&drv_data->pump_transfers); - - return IRQ_HANDLED; - } - - /* Opps problem detected */ - return IRQ_NONE; -} - -static irqreturn_t interrupt_transfer(struct driver_data *drv_data) -{ - struct spi_message *msg = drv_data->cur_msg; - void *reg = drv_data->ioaddr; - unsigned long limit = loops_per_jiffy << 1; - u32 irq_status; - u32 irq_mask = (read_SSCR1(reg) & SSCR1_TIE) ? - drv_data->mask_sr : drv_data->mask_sr & ~SSSR_TFS; - - while ((irq_status = read_SSSR(reg) & irq_mask)) { - - if (irq_status & SSSR_ROR) { - - /* Clear and disable interrupts */ - write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); - write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - - if (flush(drv_data) == 0) - dev_err(&drv_data->pdev->dev, - "interrupt_transfer: flush fail\n"); - - /* Stop the SSP */ - - dev_warn(&drv_data->pdev->dev, - "interrupt_transfer: fifo overun\n"); - - msg->state = ERROR_STATE; - tasklet_schedule(&drv_data->pump_transfers); - - return IRQ_HANDLED; - } - - /* Look for false positive timeout */ - if ((irq_status & SSSR_TINT) - && (drv_data->rx < drv_data->rx_end)) - write_SSSR(SSSR_TINT, reg); - - /* Pump data */ - drv_data->read(drv_data); - drv_data->write(drv_data); - - if (drv_data->tx == drv_data->tx_end) { - /* Disable tx interrupt */ - write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg); - irq_mask = drv_data->mask_sr & ~SSSR_TFS; - - /* PXA25x_SSP has no timeout, read trailing bytes */ - if (drv_data->ssp_type == PXA25x_SSP) { - while ((read_SSSR(reg) & SSSR_BSY) && limit--) - drv_data->read(drv_data); - - if (limit == 0) - dev_err(&drv_data->pdev->dev, - "interrupt_transfer: " - "trailing byte read failed\n"); - } - } - - if ((irq_status & SSSR_TINT) - || (drv_data->rx == drv_data->rx_end)) { - - /* Clear timeout */ - write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - - /* Update total byte transfered */ - msg->actual_length += drv_data->len; - - /* Release chip select if requested, transfer delays are - * handled in pump_transfers */ - if (drv_data->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); - - /* Move to next transfer */ - msg->state = next_transfer(drv_data); - - /* Schedule transfer tasklet */ - tasklet_schedule(&drv_data->pump_transfers); - } - } - - /* We did something */ - return IRQ_HANDLED; -} - -static irqreturn_t ssp_int(int irq, void *dev_id, struct pt_regs *regs) -{ - struct driver_data *drv_data = (struct driver_data *)dev_id; - void *reg = drv_data->ioaddr; - - if (!drv_data->cur_msg) { - - write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); - write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, reg); - write_SSSR(drv_data->clear_sr, reg); - - dev_err(&drv_data->pdev->dev, "bad message state " - "in interrupt handler"); - - /* Never fail */ - return IRQ_HANDLED; - } - - return drv_data->transfer_handler(drv_data); -} - -static void pump_transfers(unsigned long data) -{ - struct driver_data *drv_data = (struct driver_data *)data; - struct spi_message *message = NULL; - struct spi_transfer *transfer = NULL; - struct spi_transfer *previous = NULL; - struct chip_data *chip = NULL; - void *reg = drv_data->ioaddr; - u32 clk_div = 0; - u8 bits = 0; - u32 speed = 0; - u32 cr0; - - /* Get current state information */ - message = drv_data->cur_msg; - transfer = drv_data->cur_transfer; - chip = drv_data->cur_chip; - - /* Handle for abort */ - if (message->state == ERROR_STATE) { - message->status = -EIO; - giveback(drv_data); - return; - } - - /* Handle end of message */ - if (message->state == DONE_STATE) { - message->status = 0; - giveback(drv_data); - return; - } - - /* Delay if requested at end of transfer*/ - if (message->state == RUNNING_STATE) { - previous = list_entry(transfer->transfer_list.prev, - struct spi_transfer, - transfer_list); - if (previous->delay_usecs) - udelay(previous->delay_usecs); - } - - /* Setup the transfer state based on the type of transfer */ - if (flush(drv_data) == 0) { - dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n"); - message->status = -EIO; - giveback(drv_data); - return; - } - 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; - drv_data->rx_end = drv_data->rx + transfer->len; - drv_data->rx_dma = transfer->rx_dma; - drv_data->tx_dma = transfer->tx_dma; - drv_data->len = transfer->len; - drv_data->write = drv_data->tx ? chip->write : null_writer; - drv_data->read = drv_data->rx ? chip->read : null_reader; - drv_data->cs_change = transfer->cs_change; - - /* Change speed and bit per word on a per transfer */ - if (transfer->speed_hz || transfer->bits_per_word) { - - /* Disable clock */ - write_SSCR0(chip->cr0 & ~SSCR0_SSE, reg); - cr0 = chip->cr0; - bits = chip->bits_per_word; - speed = chip->speed_hz; - - if (transfer->speed_hz) - speed = transfer->speed_hz; - - if (transfer->bits_per_word) - bits = transfer->bits_per_word; - - if (reg == SSP1_VIRT) - clk_div = SSP1_SerClkDiv(speed); - else if (reg == SSP2_VIRT) - clk_div = SSP2_SerClkDiv(speed); - else if (reg == SSP3_VIRT) - clk_div = SSP3_SerClkDiv(speed); - - if (bits <= 8) { - drv_data->n_bytes = 1; - drv_data->dma_width = DCMD_WIDTH1; - drv_data->read = drv_data->read != null_reader ? - u8_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u8_writer : null_writer; - } else if (bits <= 16) { - drv_data->n_bytes = 2; - drv_data->dma_width = DCMD_WIDTH2; - drv_data->read = drv_data->read != null_reader ? - u16_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u16_writer : null_writer; - } else if (bits <= 32) { - drv_data->n_bytes = 4; - drv_data->dma_width = DCMD_WIDTH4; - drv_data->read = drv_data->read != null_reader ? - u32_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u32_writer : null_writer; - } - - cr0 = clk_div - | SSCR0_Motorola - | SSCR0_DataSize(bits > 16 ? bits - 16 : bits) - | SSCR0_SSE - | (bits > 16 ? SSCR0_EDSS : 0); - - /* Start it back up */ - write_SSCR0(cr0, reg); - } - - message->state = RUNNING_STATE; - - /* Try to map dma buffer and do a dma transfer if successful */ - if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) { - - /* Ensure we have the correct interrupt handler */ - drv_data->transfer_handler = dma_transfer; - - /* Setup rx DMA Channel */ - DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; - DSADR(drv_data->rx_channel) = drv_data->ssdr_physical; - DTADR(drv_data->rx_channel) = drv_data->rx_dma; - if (drv_data->rx == drv_data->null_dma_buf) - /* No target address increment */ - DCMD(drv_data->rx_channel) = DCMD_FLOWSRC - | drv_data->dma_width - | chip->dma_burst_size - | drv_data->len; - else - DCMD(drv_data->rx_channel) = DCMD_INCTRGADDR - | DCMD_FLOWSRC - | drv_data->dma_width - | chip->dma_burst_size - | drv_data->len; - - /* Setup tx DMA Channel */ - DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; - DSADR(drv_data->tx_channel) = drv_data->tx_dma; - DTADR(drv_data->tx_channel) = drv_data->ssdr_physical; - if (drv_data->tx == drv_data->null_dma_buf) - /* No source address increment */ - DCMD(drv_data->tx_channel) = DCMD_FLOWTRG - | drv_data->dma_width - | chip->dma_burst_size - | drv_data->len; - else - DCMD(drv_data->tx_channel) = DCMD_INCSRCADDR - | DCMD_FLOWTRG - | drv_data->dma_width - | chip->dma_burst_size - | drv_data->len; - - /* Enable dma end irqs on SSP to detect end of transfer */ - if (drv_data->ssp_type == PXA25x_SSP) - DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN; - - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - - /* Go baby, go */ - write_SSSR(drv_data->clear_sr, reg); - DCSR(drv_data->rx_channel) |= DCSR_RUN; - DCSR(drv_data->tx_channel) |= DCSR_RUN; - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(chip->timeout, reg); - write_SSCR1(chip->cr1 - | chip->dma_threshold - | drv_data->dma_cr1, - reg); - } else { - /* Ensure we have the correct interrupt handler */ - drv_data->transfer_handler = interrupt_transfer; - - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - - /* Go baby, go */ - write_SSSR(drv_data->clear_sr, reg); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(chip->timeout, reg); - write_SSCR1(chip->cr1 - | chip->threshold - | drv_data->int_cr1, - reg); - } -} - -static void pump_messages(void *data) -{ - struct driver_data *drv_data = data; - unsigned long flags; - - /* Lock queue and check for queue work */ - spin_lock_irqsave(&drv_data->lock, flags); - if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) { - drv_data->busy = 0; - spin_unlock_irqrestore(&drv_data->lock, flags); - return; - } - - /* Make sure we are not already running a message */ - if (drv_data->cur_msg) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return; - } - - /* Extract head of queue */ - drv_data->cur_msg = list_entry(drv_data->queue.next, - struct spi_message, queue); - list_del_init(&drv_data->cur_msg->queue); - - /* Initial message state*/ - drv_data->cur_msg->state = START_STATE; - drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, - struct spi_transfer, - transfer_list); - - /* Setup the SSP using the per chip configuration */ - drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); - restore_state(drv_data); - - /* Mark as busy and launch transfers */ - tasklet_schedule(&drv_data->pump_transfers); - - drv_data->busy = 1; - spin_unlock_irqrestore(&drv_data->lock, flags); -} - -static int transfer(struct spi_device *spi, struct spi_message *msg) -{ - struct driver_data *drv_data = spi_master_get_devdata(spi->master); - unsigned long flags; - - spin_lock_irqsave(&drv_data->lock, flags); - - if (drv_data->run == QUEUE_STOPPED) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return -ESHUTDOWN; - } - - msg->actual_length = 0; - msg->status = -EINPROGRESS; - msg->state = START_STATE; - - list_add_tail(&msg->queue, &drv_data->queue); - - if (drv_data->run == QUEUE_RUNNING && !drv_data->busy) - queue_work(drv_data->workqueue, &drv_data->pump_messages); - - spin_unlock_irqrestore(&drv_data->lock, flags); - - return 0; -} - -static int setup(struct spi_device *spi) -{ - struct pxa2xx_spi_chip *chip_info = NULL; - struct chip_data *chip; - struct driver_data *drv_data = spi_master_get_devdata(spi->master); - unsigned int clk_div; - - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - if (drv_data->ssp_type != PXA25x_SSP - && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) - return -EINVAL; - else if (spi->bits_per_word < 4 || spi->bits_per_word > 16) - return -EINVAL; - - /* Only alloc (or use chip_info) on first setup */ - chip = spi_get_ctldata(spi); - if (chip == NULL) { - chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->cs_control = null_cs_control; - chip->enable_dma = 0; - chip->timeout = SSP_TIMEOUT(1000); - chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1); - chip->dma_burst_size = drv_data->master_info->enable_dma ? - DCMD_BURST8 : 0; - - chip_info = spi->controller_data; - } - - /* chip_info isn't always needed */ - if (chip_info) { - if (chip_info->cs_control) - chip->cs_control = chip_info->cs_control; - - chip->timeout = SSP_TIMEOUT(chip_info->timeout_microsecs); - - chip->threshold = SSCR1_RxTresh(chip_info->rx_threshold) - | SSCR1_TxTresh(chip_info->tx_threshold); - - chip->enable_dma = chip_info->dma_burst_size != 0 - && drv_data->master_info->enable_dma; - chip->dma_threshold = 0; - - if (chip->enable_dma) { - if (chip_info->dma_burst_size <= 8) { - chip->dma_threshold = SSCR1_RxTresh(8) - | SSCR1_TxTresh(8); - chip->dma_burst_size = DCMD_BURST8; - } else if (chip_info->dma_burst_size <= 16) { - chip->dma_threshold = SSCR1_RxTresh(16) - | SSCR1_TxTresh(16); - chip->dma_burst_size = DCMD_BURST16; - } else { - chip->dma_threshold = SSCR1_RxTresh(32) - | SSCR1_TxTresh(32); - chip->dma_burst_size = DCMD_BURST32; - } - } - - - if (chip_info->enable_loopback) - chip->cr1 = SSCR1_LBM; - } - - if (drv_data->ioaddr == SSP1_VIRT) - clk_div = SSP1_SerClkDiv(spi->max_speed_hz); - else if (drv_data->ioaddr == SSP2_VIRT) - clk_div = SSP2_SerClkDiv(spi->max_speed_hz); - else if (drv_data->ioaddr == SSP3_VIRT) - clk_div = SSP3_SerClkDiv(spi->max_speed_hz); - else - return -ENODEV; - chip->speed_hz = spi->max_speed_hz; - - chip->cr0 = clk_div - | SSCR0_Motorola - | SSCR0_DataSize(spi->bits_per_word > 16 ? - spi->bits_per_word - 16 : spi->bits_per_word) - | SSCR0_SSE - | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0); - chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4) - | (((spi->mode & SPI_CPOL) != 0) << 3); - - /* NOTE: PXA25x_SSP _could_ use external clocking ... */ - if (drv_data->ssp_type != PXA25x_SSP) - dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n", - spi->bits_per_word, - (CLOCK_SPEED_HZ) - / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - spi->mode & 0x3); - else - dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n", - spi->bits_per_word, - (CLOCK_SPEED_HZ/2) - / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - spi->mode & 0x3); - - if (spi->bits_per_word <= 8) { - chip->n_bytes = 1; - chip->dma_width = DCMD_WIDTH1; - chip->read = u8_reader; - chip->write = u8_writer; - } else if (spi->bits_per_word <= 16) { - chip->n_bytes = 2; - chip->dma_width = DCMD_WIDTH2; - chip->read = u16_reader; - chip->write = u16_writer; - } else if (spi->bits_per_word <= 32) { - chip->cr0 |= SSCR0_EDSS; - chip->n_bytes = 4; - chip->dma_width = DCMD_WIDTH4; - chip->read = u32_reader; - chip->write = u32_writer; - } else { - dev_err(&spi->dev, "invalid wordsize\n"); - kfree(chip); - return -ENODEV; - } - chip->bits_per_word = spi->bits_per_word; - - spi_set_ctldata(spi, chip); - - return 0; -} - -static void cleanup(const struct spi_device *spi) -{ - struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi); - - kfree(chip); -} - -static int init_queue(struct driver_data *drv_data) -{ - INIT_LIST_HEAD(&drv_data->queue); - spin_lock_init(&drv_data->lock); - - drv_data->run = QUEUE_STOPPED; - drv_data->busy = 0; - - tasklet_init(&drv_data->pump_transfers, - pump_transfers, (unsigned long)drv_data); - - INIT_WORK(&drv_data->pump_messages, pump_messages, drv_data); - drv_data->workqueue = create_singlethread_workqueue( - drv_data->master->cdev.dev->bus_id); - if (drv_data->workqueue == NULL) - return -EBUSY; - - return 0; -} - -static int start_queue(struct driver_data *drv_data) -{ - unsigned long flags; - - spin_lock_irqsave(&drv_data->lock, flags); - - if (drv_data->run == QUEUE_RUNNING || drv_data->busy) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return -EBUSY; - } - - drv_data->run = QUEUE_RUNNING; - drv_data->cur_msg = NULL; - drv_data->cur_transfer = NULL; - drv_data->cur_chip = NULL; - spin_unlock_irqrestore(&drv_data->lock, flags); - - queue_work(drv_data->workqueue, &drv_data->pump_messages); - - return 0; -} - -static int stop_queue(struct driver_data *drv_data) -{ - unsigned long flags; - unsigned limit = 500; - int status = 0; - - spin_lock_irqsave(&drv_data->lock, flags); - - /* This is a bit lame, but is optimized for the common execution path. - * A wait_queue on the drv_data->busy could be used, but then the common - * execution path (pump_messages) would be required to call wake_up or - * friends on every SPI message. Do this instead */ - drv_data->run = QUEUE_STOPPED; - while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { - spin_unlock_irqrestore(&drv_data->lock, flags); - msleep(10); - spin_lock_irqsave(&drv_data->lock, flags); - } - - if (!list_empty(&drv_data->queue) || drv_data->busy) - status = -EBUSY; - - spin_unlock_irqrestore(&drv_data->lock, flags); - - return status; -} - -static int destroy_queue(struct driver_data *drv_data) -{ - int status; - - status = stop_queue(drv_data); - if (status != 0) - return status; - - destroy_workqueue(drv_data->workqueue); - - return 0; -} - -static int pxa2xx_spi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct pxa2xx_spi_master *platform_info; - struct spi_master *master; - struct driver_data *drv_data = 0; - struct resource *memory_resource; - int irq; - int status = 0; - - platform_info = dev->platform_data; - - if (platform_info->ssp_type == SSP_UNDEFINED) { - dev_err(&pdev->dev, "undefined SSP\n"); - return -ENODEV; - } - - /* Allocate master with space for drv_data and null dma buffer */ - master = spi_alloc_master(dev, sizeof(struct driver_data) + 16); - if (!master) { - dev_err(&pdev->dev, "can not alloc spi_master\n"); - return -ENOMEM; - } - drv_data = spi_master_get_devdata(master); - drv_data->master = master; - drv_data->master_info = platform_info; - drv_data->pdev = pdev; - - master->bus_num = pdev->id; - master->num_chipselect = platform_info->num_chipselect; - master->cleanup = cleanup; - master->setup = setup; - master->transfer = transfer; - - drv_data->ssp_type = platform_info->ssp_type; - drv_data->null_dma_buf = (u32 *)ALIGN((u32)(drv_data + - sizeof(struct driver_data)), 8); - - /* Setup register addresses */ - memory_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!memory_resource) { - dev_err(&pdev->dev, "memory resources not defined\n"); - status = -ENODEV; - goto out_error_master_alloc; - } - - drv_data->ioaddr = (void *)io_p2v((unsigned long)(memory_resource->start)); - drv_data->ssdr_physical = memory_resource->start + 0x00000010; - if (platform_info->ssp_type == PXA25x_SSP) { - drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; - drv_data->dma_cr1 = 0; - drv_data->clear_sr = SSSR_ROR; - drv_data->mask_sr = SSSR_RFS | SSSR_TFS | SSSR_ROR; - } else { - drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE; - drv_data->dma_cr1 = SSCR1_TSRE | SSCR1_RSRE | SSCR1_TINTE; - drv_data->clear_sr = SSSR_ROR | SSSR_TINT; - drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR; - } - - /* Attach to IRQ */ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "irq resource not defined\n"); - status = -ENODEV; - goto out_error_master_alloc; - } - - status = request_irq(irq, ssp_int, 0, dev->bus_id, drv_data); - if (status < 0) { - dev_err(&pdev->dev, "can not get IRQ\n"); - goto out_error_master_alloc; - } - - /* Setup DMA if requested */ - drv_data->tx_channel = -1; - drv_data->rx_channel = -1; - if (platform_info->enable_dma) { - - /* Get two DMA channels (rx and tx) */ - drv_data->rx_channel = pxa_request_dma("pxa2xx_spi_ssp_rx", - DMA_PRIO_HIGH, - dma_handler, - drv_data); - if (drv_data->rx_channel < 0) { - dev_err(dev, "problem (%d) requesting rx channel\n", - drv_data->rx_channel); - status = -ENODEV; - goto out_error_irq_alloc; - } - drv_data->tx_channel = pxa_request_dma("pxa2xx_spi_ssp_tx", - DMA_PRIO_MEDIUM, - dma_handler, - drv_data); - if (drv_data->tx_channel < 0) { - dev_err(dev, "problem (%d) requesting tx channel\n", - drv_data->tx_channel); - status = -ENODEV; - goto out_error_dma_alloc; - } - - if (drv_data->ioaddr == SSP1_VIRT) { - DRCMRRXSSDR = DRCMR_MAPVLD - | drv_data->rx_channel; - DRCMRTXSSDR = DRCMR_MAPVLD - | drv_data->tx_channel; - } else if (drv_data->ioaddr == SSP2_VIRT) { - DRCMRRXSS2DR = DRCMR_MAPVLD - | drv_data->rx_channel; - DRCMRTXSS2DR = DRCMR_MAPVLD - | drv_data->tx_channel; - } else if (drv_data->ioaddr == SSP3_VIRT) { - DRCMRRXSS3DR = DRCMR_MAPVLD - | drv_data->rx_channel; - DRCMRTXSS3DR = DRCMR_MAPVLD - | drv_data->tx_channel; - } else { - dev_err(dev, "bad SSP type\n"); - goto out_error_dma_alloc; - } - } - - /* Enable SOC clock */ - pxa_set_cken(platform_info->clock_enable, 1); - - /* Load default SSP configuration */ - write_SSCR0(0, drv_data->ioaddr); - write_SSCR1(SSCR1_RxTresh(4) | SSCR1_TxTresh(12), drv_data->ioaddr); - write_SSCR0(SSCR0_SerClkDiv(2) - | SSCR0_Motorola - | SSCR0_DataSize(8), - drv_data->ioaddr); - if (drv_data->ssp_type != PXA25x_SSP) - write_SSTO(0, drv_data->ioaddr); - write_SSPSP(0, drv_data->ioaddr); - - /* Initial and start queue */ - status = init_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem initializing queue\n"); - goto out_error_clock_enabled; - } - status = start_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem starting queue\n"); - goto out_error_clock_enabled; - } - - /* Register with the SPI framework */ - platform_set_drvdata(pdev, drv_data); - status = spi_register_master(master); - if (status != 0) { - dev_err(&pdev->dev, "problem registering spi master\n"); - goto out_error_queue_alloc; - } - - return status; - -out_error_queue_alloc: - destroy_queue(drv_data); - -out_error_clock_enabled: - pxa_set_cken(platform_info->clock_enable, 0); - -out_error_dma_alloc: - if (drv_data->tx_channel != -1) - pxa_free_dma(drv_data->tx_channel); - if (drv_data->rx_channel != -1) - pxa_free_dma(drv_data->rx_channel); - -out_error_irq_alloc: - free_irq(irq, drv_data); - -out_error_master_alloc: - spi_master_put(master); - return status; -} - -static int pxa2xx_spi_remove(struct platform_device *pdev) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int irq; - int status = 0; - - if (!drv_data) - return 0; - - /* Remove the queue */ - status = destroy_queue(drv_data); - if (status != 0) - return status; - - /* Disable the SSP at the peripheral and SOC level */ - write_SSCR0(0, drv_data->ioaddr); - pxa_set_cken(drv_data->master_info->clock_enable, 0); - - /* Release DMA */ - if (drv_data->master_info->enable_dma) { - if (drv_data->ioaddr == SSP1_VIRT) { - DRCMRRXSSDR = 0; - DRCMRTXSSDR = 0; - } else if (drv_data->ioaddr == SSP2_VIRT) { - DRCMRRXSS2DR = 0; - DRCMRTXSS2DR = 0; - } else if (drv_data->ioaddr == SSP3_VIRT) { - DRCMRRXSS3DR = 0; - DRCMRTXSS3DR = 0; - } - pxa_free_dma(drv_data->tx_channel); - pxa_free_dma(drv_data->rx_channel); - } - - /* Release IRQ */ - irq = platform_get_irq(pdev, 0); - if (irq >= 0) - free_irq(irq, drv_data); - - /* Disconnect from the SPI framework */ - spi_unregister_master(drv_data->master); - - /* Prevent double remove */ - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static void pxa2xx_spi_shutdown(struct platform_device *pdev) -{ - int status = 0; - - if ((status = pxa2xx_spi_remove(pdev)) != 0) - dev_err(&pdev->dev, "shutdown failed with %d\n", status); -} - -#ifdef CONFIG_PM -static int suspend_devices(struct device *dev, void *pm_message) -{ - pm_message_t *state = pm_message; - - if (dev->power.power_state.event != state->event) { - dev_warn(dev, "pm state does not match request\n"); - return -1; - } - - return 0; -} - -static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int status = 0; - - /* Check all childern for current power state */ - if (device_for_each_child(&pdev->dev, &state, suspend_devices) != 0) { - dev_warn(&pdev->dev, "suspend aborted\n"); - return -1; - } - - status = stop_queue(drv_data); - if (status != 0) - return status; - write_SSCR0(0, drv_data->ioaddr); - pxa_set_cken(drv_data->master_info->clock_enable, 0); - - return 0; -} - -static int pxa2xx_spi_resume(struct platform_device *pdev) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int status = 0; - - /* Enable the SSP clock */ - pxa_set_cken(drv_data->master_info->clock_enable, 1); - - /* Start the queue running */ - status = start_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem starting queue (%d)\n", status); - return status; - } - - return 0; -} -#else -#define pxa2xx_spi_suspend NULL -#define pxa2xx_spi_resume NULL -#endif /* CONFIG_PM */ - -static struct platform_driver driver = { - .driver = { - .name = "pxa2xx-spi", - .bus = &platform_bus_type, - .owner = THIS_MODULE, - }, - .probe = pxa2xx_spi_probe, - .remove = __devexit_p(pxa2xx_spi_remove), - .shutdown = pxa2xx_spi_shutdown, - .suspend = pxa2xx_spi_suspend, - .resume = pxa2xx_spi_resume, -}; - -static int __init pxa2xx_spi_init(void) -{ - platform_driver_register(&driver); - - return 0; -} -module_init(pxa2xx_spi_init); - -static void __exit pxa2xx_spi_exit(void) -{ - platform_driver_unregister(&driver); -} -module_exit(pxa2xx_spi_exit); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 1cea4a679..94f5e8ed8 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -338,18 +338,18 @@ static struct class spi_master_class = { * spi_alloc_master - allocate SPI master controller * @dev: the controller, possibly using the platform_bus * @size: how much driver-private data to preallocate; the pointer to this - * memory is in the class_data field of the returned class_device, + * memory is in the class_data field of the returned class_device, * accessible with spi_master_get_devdata(). * * This call is used only by SPI master controller drivers, which are the * only ones directly touching chip registers. It's how they allocate - * an spi_master structure, prior to calling spi_register_master(). + * an spi_master structure, prior to calling spi_add_master(). * * This must be called from context that can sleep. It returns the SPI * master structure on success, else NULL. * * The caller is responsible for assigning the bus number and initializing - * the master's methods before calling spi_register_master(); and (after errors + * the master's methods before calling spi_add_master(); and (after errors * adding the device) calling spi_master_put() to prevent a memory leak. */ struct spi_master * __init_or_module @@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master); int __init_or_module spi_register_master(struct spi_master *master) { - static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1); + static atomic_t dyn_bus_id = ATOMIC_INIT(0); struct device *dev = master->cdev.dev; int status = -ENODEV; int dynamic = 0; @@ -404,7 +404,7 @@ spi_register_master(struct spi_master *master) return -ENODEV; /* convention: dynamically assigned bus IDs count down from the max */ - if (master->bus_num < 0) { + if (master->bus_num == 0) { master->bus_num = atomic_dec_return(&dyn_bus_id); dynamic = 1; } @@ -522,8 +522,7 @@ int spi_sync(struct spi_device *spi, struct spi_message *message) } EXPORT_SYMBOL_GPL(spi_sync); -/* portable code must never pass more than 32 bytes */ -#define SPI_BUFSIZ max(32,SMP_CACHE_BYTES) +#define SPI_BUFSIZ (SMP_CACHE_BYTES) static u8 *buf; diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index dd2f950b2..f037e5593 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -138,45 +138,6 @@ static unsigned bitbang_txrx_32( return t->len - count; } -int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t) -{ - struct spi_bitbang_cs *cs = spi->controller_state; - u8 bits_per_word; - u32 hz; - - if (t) { - bits_per_word = t->bits_per_word; - hz = t->speed_hz; - } else { - bits_per_word = 0; - hz = 0; - } - - /* spi_transfer level calls that work per-word */ - if (!bits_per_word) - bits_per_word = spi->bits_per_word; - if (bits_per_word <= 8) - cs->txrx_bufs = bitbang_txrx_8; - else if (bits_per_word <= 16) - cs->txrx_bufs = bitbang_txrx_16; - else if (bits_per_word <= 32) - cs->txrx_bufs = bitbang_txrx_32; - else - return -EINVAL; - - /* nsecs = (clock period)/2 */ - if (!hz) - hz = spi->max_speed_hz; - if (hz) { - cs->nsecs = (1000000000/2) / hz; - if (cs->nsecs > (MAX_UDELAY_MS * 1000 * 1000)) - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL_GPL(spi_bitbang_setup_transfer); - /** * spi_bitbang_setup - default setup for per-word I/O loops */ @@ -184,16 +145,8 @@ int spi_bitbang_setup(struct spi_device *spi) { struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; - int retval; - bitbang = spi_master_get_devdata(spi->master); - - /* REVISIT: some systems will want to support devices using lsb-first - * bit encodings on the wire. In pure software that would be trivial, - * just bitbang_txrx_le_cphaX() routines shifting the other way, and - * some hardware controllers also have this support. - */ - if ((spi->mode & SPI_LSB_FIRST) != 0) + if (!spi->max_speed_hz) return -EINVAL; if (!cs) { @@ -202,20 +155,32 @@ int spi_bitbang_setup(struct spi_device *spi) return -ENOMEM; spi->controller_state = cs; } + bitbang = spi_master_get_devdata(spi->master); if (!spi->bits_per_word) spi->bits_per_word = 8; + /* spi_transfer level calls that work per-word */ + if (spi->bits_per_word <= 8) + cs->txrx_bufs = bitbang_txrx_8; + else if (spi->bits_per_word <= 16) + cs->txrx_bufs = bitbang_txrx_16; + else if (spi->bits_per_word <= 32) + cs->txrx_bufs = bitbang_txrx_32; + else + return -EINVAL; + /* per-word shift register access, in hardware or bitbanging */ cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; if (!cs->txrx_word) return -EINVAL; - retval = spi_bitbang_setup_transfer(spi, NULL); - if (retval < 0) - return retval; + /* nsecs = (clock period)/2 */ + cs->nsecs = (1000000000/2) / (spi->max_speed_hz); + if (cs->nsecs > MAX_UDELAY_MS * 1000) + return -EINVAL; - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n", + dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), spi->bits_per_word, 2 * cs->nsecs); @@ -281,8 +246,6 @@ static void bitbang_work(void *_bitbang) unsigned tmp; unsigned cs_change; int status; - int (*setup_transfer)(struct spi_device *, - struct spi_transfer *); m = container_of(bitbang->queue.next, struct spi_message, queue); @@ -299,7 +262,6 @@ static void bitbang_work(void *_bitbang) tmp = 0; cs_change = 1; status = 0; - setup_transfer = NULL; list_for_each_entry (t, &m->transfers, transfer_list) { if (bitbang->shutdown) { @@ -307,20 +269,6 @@ static void bitbang_work(void *_bitbang) break; } - /* override or restore speed and wordsize */ - if (t->speed_hz || t->bits_per_word) { - setup_transfer = bitbang->setup_transfer; - if (!setup_transfer) { - status = -ENOPROTOOPT; - break; - } - } - if (setup_transfer) { - status = setup_transfer(spi, t); - if (status < 0) - break; - } - /* set up default clock polarity, and activate chip; * this implicitly updates clock and spi modes as * previously recorded for this device via setup(). @@ -377,10 +325,6 @@ static void bitbang_work(void *_bitbang) m->status = status; m->complete(m->context); - /* restore speed and wordsize */ - if (setup_transfer) - setup_transfer(spi, NULL); - /* normally deactivate chipselect ... unless no error and * cs_change has hinted that the next message will probably * be for this chip too. @@ -404,7 +348,6 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) { struct spi_bitbang *bitbang; unsigned long flags; - int status = 0; m->actual_length = 0; m->status = -EINPROGRESS; @@ -414,15 +357,11 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) return -ESHUTDOWN; spin_lock_irqsave(&bitbang->lock, flags); - if (!spi->max_speed_hz) - status = -ENETDOWN; - else { - list_add_tail(&m->queue, &bitbang->queue); - queue_work(bitbang->workqueue, &bitbang->work); - } + list_add_tail(&m->queue, &bitbang->queue); + queue_work(bitbang->workqueue, &bitbang->work); spin_unlock_irqrestore(&bitbang->lock, flags); - return status; + return 0; } EXPORT_SYMBOL_GPL(spi_bitbang_transfer); @@ -467,9 +406,6 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) bitbang->use_dma = 0; bitbang->txrx_bufs = spi_bitbang_bufs; if (!bitbang->master->setup) { - if (!bitbang->setup_transfer) - bitbang->setup_transfer = - spi_bitbang_setup_transfer; bitbang->master->setup = spi_bitbang_setup; bitbang->master->cleanup = spi_bitbang_cleanup; } diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index a006a1ee2..ff9e5faa4 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c @@ -321,7 +321,6 @@ static void butterfly_attach(struct parport *p) * (firmware resets at45, acts as spi slave) or neither (we ignore * both, AVR uses AT45). Here we expect firmware for the first option. */ - pp->info[0].max_speed_hz = 15 * 1000 * 1000; strcpy(pp->info[0].modalias, "mtd_dataflash"); pp->info[0].platform_data = &flash; diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c deleted file mode 100644 index 5d92a7e5c..000000000 --- a/drivers/spi/spi_mpc83xx.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * MPC83xx SPI controller driver. - * - * Maintainer: Kumar Gala - * - * Copyright (C) 2006 Polycom, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* SPI Controller registers */ -struct mpc83xx_spi_reg { - u8 res1[0x20]; - __be32 mode; - __be32 event; - __be32 mask; - __be32 command; - __be32 transmit; - __be32 receive; -}; - -/* SPI Controller mode register definitions */ -#define SPMODE_CI_INACTIVEHIGH (1 << 29) -#define SPMODE_CP_BEGIN_EDGECLK (1 << 28) -#define SPMODE_DIV16 (1 << 27) -#define SPMODE_REV (1 << 26) -#define SPMODE_MS (1 << 25) -#define SPMODE_ENABLE (1 << 24) -#define SPMODE_LEN(x) ((x) << 20) -#define SPMODE_PM(x) ((x) << 16) - -/* - * Default for SPI Mode: - * SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk - */ -#define SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \ - SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf)) - -/* SPIE register values */ -#define SPIE_NE 0x00000200 /* Not empty */ -#define SPIE_NF 0x00000100 /* Not full */ - -/* SPIM register values */ -#define SPIM_NE 0x00000200 /* Not empty */ -#define SPIM_NF 0x00000100 /* Not full */ - -/* SPI Controller driver's private data. */ -struct mpc83xx_spi { - /* bitbang has to be first */ - struct spi_bitbang bitbang; - struct completion done; - - struct mpc83xx_spi_reg __iomem *base; - - /* rx & tx bufs from the spi_transfer */ - const void *tx; - void *rx; - - /* functions to deal with different sized buffers */ - void (*get_rx) (u32 rx_data, struct mpc83xx_spi *); - u32(*get_tx) (struct mpc83xx_spi *); - - unsigned int count; - u32 irq; - - unsigned nsecs; /* (clock cycle time)/2 */ - - u32 sysclk; - void (*activate_cs) (u8 cs, u8 polarity); - void (*deactivate_cs) (u8 cs, u8 polarity); -}; - -static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val) -{ - out_be32(reg, val); -} - -static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg) -{ - return in_be32(reg); -} - -#define MPC83XX_SPI_RX_BUF(type) \ -void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ -{ \ - type * rx = mpc83xx_spi->rx; \ - *rx++ = (type)data; \ - mpc83xx_spi->rx = rx; \ -} - -#define MPC83XX_SPI_TX_BUF(type) \ -u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \ -{ \ - u32 data; \ - const type * tx = mpc83xx_spi->tx; \ - data = *tx++; \ - mpc83xx_spi->tx = tx; \ - return data; \ -} - -MPC83XX_SPI_RX_BUF(u8) -MPC83XX_SPI_RX_BUF(u16) -MPC83XX_SPI_RX_BUF(u32) -MPC83XX_SPI_TX_BUF(u8) -MPC83XX_SPI_TX_BUF(u16) -MPC83XX_SPI_TX_BUF(u32) - -static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) -{ - struct mpc83xx_spi *mpc83xx_spi; - u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0; - - mpc83xx_spi = spi_master_get_devdata(spi->master); - - if (value == BITBANG_CS_INACTIVE) { - if (mpc83xx_spi->deactivate_cs) - mpc83xx_spi->deactivate_cs(spi->chip_select, pol); - } - - if (value == BITBANG_CS_ACTIVE) { - u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); - u32 len = spi->bits_per_word; - if (len == 32) - len = 0; - else - len = len - 1; - - /* mask out bits we are going to set */ - regval &= ~0x38ff0000; - - if (spi->mode & SPI_CPHA) - regval |= SPMODE_CP_BEGIN_EDGECLK; - if (spi->mode & SPI_CPOL) - regval |= SPMODE_CI_INACTIVEHIGH; - - regval |= SPMODE_LEN(len); - - if ((mpc83xx_spi->sysclk / spi->max_speed_hz) >= 64) { - u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 64); - regval |= SPMODE_PM(pm) | SPMODE_DIV16; - } else { - u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 4); - regval |= SPMODE_PM(pm); - } - - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); - if (mpc83xx_spi->activate_cs) - mpc83xx_spi->activate_cs(spi->chip_select, pol); - } -} - -static -int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) -{ - struct mpc83xx_spi *mpc83xx_spi; - u32 regval; - u8 bits_per_word; - u32 hz; - - mpc83xx_spi = spi_master_get_devdata(spi->master); - - if (t) { - bits_per_word = t->bits_per_word; - hz = t->speed_hz; - } else { - bits_per_word = 0; - hz = 0; - } - - /* spi_transfer level calls that work per-word */ - if (!bits_per_word) - bits_per_word = spi->bits_per_word; - - /* Make sure its a bit width we support [4..16, 32] */ - if ((bits_per_word < 4) - || ((bits_per_word > 16) && (bits_per_word != 32))) - return -EINVAL; - - if (bits_per_word <= 8) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; - } else if (bits_per_word <= 16) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16; - } else if (bits_per_word <= 32) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32; - } else - return -EINVAL; - - /* nsecs = (clock period)/2 */ - if (!hz) - hz = spi->max_speed_hz; - mpc83xx_spi->nsecs = (1000000000 / 2) / hz; - if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000) - return -EINVAL; - - if (bits_per_word == 32) - bits_per_word = 0; - else - bits_per_word = bits_per_word - 1; - - regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); - - /* Mask out bits_per_wordgth */ - regval &= 0xff0fffff; - regval |= SPMODE_LEN(bits_per_word); - - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); - - return 0; -} - -static int mpc83xx_spi_setup(struct spi_device *spi) -{ - struct spi_bitbang *bitbang; - struct mpc83xx_spi *mpc83xx_spi; - int retval; - - if (!spi->max_speed_hz) - return -EINVAL; - - bitbang = spi_master_get_devdata(spi->master); - mpc83xx_spi = spi_master_get_devdata(spi->master); - - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - retval = mpc83xx_spi_setup_transfer(spi, NULL); - if (retval < 0) - return retval; - - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", - __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), - spi->bits_per_word, 2 * mpc83xx_spi->nsecs); - - /* NOTE we _need_ to call chipselect() early, ideally with adapter - * setup, unless the hardware defaults cooperate to avoid confusion - * between normal (active low) and inverted chipselects. - */ - - /* deselect chip (low or high) */ - spin_lock(&bitbang->lock); - if (!bitbang->busy) { - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(mpc83xx_spi->nsecs); - } - spin_unlock(&bitbang->lock); - - return 0; -} - -static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) -{ - struct mpc83xx_spi *mpc83xx_spi; - u32 word; - - mpc83xx_spi = spi_master_get_devdata(spi->master); - - mpc83xx_spi->tx = t->tx_buf; - mpc83xx_spi->rx = t->rx_buf; - mpc83xx_spi->count = t->len; - INIT_COMPLETION(mpc83xx_spi->done); - - /* enable rx ints */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE); - - /* transmit word */ - word = mpc83xx_spi->get_tx(mpc83xx_spi); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); - - wait_for_completion(&mpc83xx_spi->done); - - /* disable rx ints */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); - - return t->len - mpc83xx_spi->count; -} - -irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data, - struct pt_regs * ptregs) -{ - struct mpc83xx_spi *mpc83xx_spi = context_data; - u32 event; - irqreturn_t ret = IRQ_NONE; - - /* Get interrupt events(tx/rx) */ - event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event); - - /* We need handle RX first */ - if (event & SPIE_NE) { - u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive); - - if (mpc83xx_spi->rx) - mpc83xx_spi->get_rx(rx_data, mpc83xx_spi); - - ret = IRQ_HANDLED; - } - - if ((event & SPIE_NF) == 0) - /* spin until TX is done */ - while (((event = - mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) & - SPIE_NF) == 0) - cpu_relax(); - - mpc83xx_spi->count -= 1; - if (mpc83xx_spi->count) { - if (mpc83xx_spi->tx) { - u32 word = mpc83xx_spi->get_tx(mpc83xx_spi); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, - word); - } - } else { - complete(&mpc83xx_spi->done); - } - - /* Clear the events */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event); - - return ret; -} - -static int __init mpc83xx_spi_probe(struct platform_device *dev) -{ - struct spi_master *master; - struct mpc83xx_spi *mpc83xx_spi; - struct fsl_spi_platform_data *pdata; - struct resource *r; - u32 regval; - int ret = 0; - - /* Get resources(memory, IRQ) associated with the device */ - master = spi_alloc_master(&dev->dev, sizeof(struct mpc83xx_spi)); - - if (master == NULL) { - ret = -ENOMEM; - goto err; - } - - platform_set_drvdata(dev, master); - pdata = dev->dev.platform_data; - - if (pdata == NULL) { - ret = -ENODEV; - goto free_master; - } - - r = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (r == NULL) { - ret = -ENODEV; - goto free_master; - } - - mpc83xx_spi = spi_master_get_devdata(master); - mpc83xx_spi->bitbang.master = spi_master_get(master); - mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect; - mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer; - mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs; - mpc83xx_spi->sysclk = pdata->sysclk; - mpc83xx_spi->activate_cs = pdata->activate_cs; - mpc83xx_spi->deactivate_cs = pdata->deactivate_cs; - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; - - mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup; - init_completion(&mpc83xx_spi->done); - - mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1); - if (mpc83xx_spi->base == NULL) { - ret = -ENOMEM; - goto put_master; - } - - mpc83xx_spi->irq = platform_get_irq(dev, 0); - - if (mpc83xx_spi->irq < 0) { - ret = -ENXIO; - goto unmap_io; - } - - /* Register for SPI Interrupt */ - ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq, - 0, "mpc83xx_spi", mpc83xx_spi); - - if (ret != 0) - goto unmap_io; - - master->bus_num = pdata->bus_num; - master->num_chipselect = pdata->max_chipselect; - - /* SPI controller initializations */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff); - - /* Enable SPI interface */ - regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); - - ret = spi_bitbang_start(&mpc83xx_spi->bitbang); - - if (ret != 0) - goto free_irq; - - printk(KERN_INFO - "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n", - dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq); - - return ret; - -free_irq: - free_irq(mpc83xx_spi->irq, mpc83xx_spi); -unmap_io: - iounmap(mpc83xx_spi->base); -put_master: - spi_master_put(master); -free_master: - kfree(master); -err: - return ret; -} - -static int __devexit mpc83xx_spi_remove(struct platform_device *dev) -{ - struct mpc83xx_spi *mpc83xx_spi; - struct spi_master *master; - - master = platform_get_drvdata(dev); - mpc83xx_spi = spi_master_get_devdata(master); - - spi_bitbang_stop(&mpc83xx_spi->bitbang); - free_irq(mpc83xx_spi->irq, mpc83xx_spi); - iounmap(mpc83xx_spi->base); - spi_master_put(mpc83xx_spi->bitbang.master); - - return 0; -} - -static struct platform_driver mpc83xx_spi_driver = { - .probe = mpc83xx_spi_probe, - .remove = __devexit_p(mpc83xx_spi_remove), - .driver = { - .name = "mpc83xx_spi", - }, -}; - -static int __init mpc83xx_spi_init(void) -{ - return platform_driver_register(&mpc83xx_spi_driver); -} - -static void __exit mpc83xx_spi_exit(void) -{ - platform_driver_unregister(&mpc83xx_spi_driver); -} - -module_init(mpc83xx_spi_init); -module_exit(mpc83xx_spi_exit); - -MODULE_AUTHOR("Kumar Gala"); -MODULE_DESCRIPTION("Simple MPC83xx SPI Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c deleted file mode 100644 index 5fc14563e..000000000 --- a/drivers/spi/spi_s3c24xx.c +++ /dev/null @@ -1,453 +0,0 @@ -/* linux/drivers/spi/spi_s3c24xx.c - * - * Copyright (c) 2006 Ben Dooks - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * 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. - * -*/ - - -//#define DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -struct s3c24xx_spi { - /* bitbang has to be first */ - struct spi_bitbang bitbang; - struct completion done; - - void __iomem *regs; - int irq; - int len; - int count; - - /* data buffers */ - const unsigned char *tx; - unsigned char *rx; - - struct clk *clk; - struct resource *ioarea; - struct spi_master *master; - struct spi_device *curdev; - struct device *dev; - struct s3c2410_spi_info *pdata; -}; - -#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT) -#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) - -static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) -{ - return spi_master_get_devdata(sdev->master); -} - -static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) -{ - struct s3c24xx_spi *hw = to_hw(spi); - unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; - unsigned int spcon; - - switch (value) { - case BITBANG_CS_INACTIVE: - if (hw->pdata->set_cs) - hw->pdata->set_cs(hw->pdata, value, cspol); - else - s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1); - break; - - case BITBANG_CS_ACTIVE: - spcon = readb(hw->regs + S3C2410_SPCON); - - if (spi->mode & SPI_CPHA) - spcon |= S3C2410_SPCON_CPHA_FMTB; - else - spcon &= ~S3C2410_SPCON_CPHA_FMTB; - - if (spi->mode & SPI_CPOL) - spcon |= S3C2410_SPCON_CPOL_HIGH; - else - spcon &= ~S3C2410_SPCON_CPOL_HIGH; - - spcon |= S3C2410_SPCON_ENSCK; - - /* write new configration */ - - writeb(spcon, hw->regs + S3C2410_SPCON); - - if (hw->pdata->set_cs) - hw->pdata->set_cs(hw->pdata, value, cspol); - else - s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol); - - break; - - } -} - -static int s3c24xx_spi_setupxfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct s3c24xx_spi *hw = to_hw(spi); - unsigned int bpw; - unsigned int hz; - unsigned int div; - - bpw = t ? t->bits_per_word : spi->bits_per_word; - hz = t ? t->speed_hz : spi->max_speed_hz; - - if (bpw != 8) { - dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); - return -EINVAL; - } - - div = clk_get_rate(hw->clk) / hz; - - /* is clk = pclk / (2 * (pre+1)), or is it - * clk = (pclk * 2) / ( pre + 1) */ - - div = (div / 2) - 1; - - if (div < 0) - div = 1; - - if (div > 255) - div = 255; - - dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", div, hz); - writeb(div, hw->regs + S3C2410_SPPRE); - - spin_lock(&hw->bitbang.lock); - if (!hw->bitbang.busy) { - hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); - /* need to ndelay for 0.5 clocktick ? */ - } - spin_unlock(&hw->bitbang.lock); - - return 0; -} - -static int s3c24xx_spi_setup(struct spi_device *spi) -{ - int ret; - - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - if ((spi->mode & SPI_LSB_FIRST) != 0) - return -EINVAL; - - ret = s3c24xx_spi_setupxfer(spi, NULL); - if (ret < 0) { - dev_err(&spi->dev, "setupxfer returned %d\n", ret); - return ret; - } - - dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", - __FUNCTION__, spi->mode, spi->bits_per_word, - spi->max_speed_hz); - - return 0; -} - -static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count) -{ - return hw->tx ? hw->tx[count] : 0xff; -} - -static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) -{ - struct s3c24xx_spi *hw = to_hw(spi); - - dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", - t->tx_buf, t->rx_buf, t->len); - - hw->tx = t->tx_buf; - hw->rx = t->rx_buf; - hw->len = t->len; - hw->count = 0; - - /* send the first byte */ - writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT); - wait_for_completion(&hw->done); - - return hw->count; -} - -static irqreturn_t s3c24xx_spi_irq(int irq, void *dev, struct pt_regs *regs) -{ - struct s3c24xx_spi *hw = dev; - unsigned int spsta = readb(hw->regs + S3C2410_SPSTA); - unsigned int count = hw->count; - - if (spsta & S3C2410_SPSTA_DCOL) { - dev_dbg(hw->dev, "data-collision\n"); - complete(&hw->done); - goto irq_done; - } - - if (!(spsta & S3C2410_SPSTA_READY)) { - dev_dbg(hw->dev, "spi not ready for tx?\n"); - complete(&hw->done); - goto irq_done; - } - - hw->count++; - - if (hw->rx) - hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); - - count++; - - if (count < hw->len) - writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); - else - complete(&hw->done); - - irq_done: - return IRQ_HANDLED; -} - -static int s3c24xx_spi_probe(struct platform_device *pdev) -{ - struct s3c24xx_spi *hw; - struct spi_master *master; - struct spi_board_info *bi; - struct resource *res; - int err = 0; - int i; - - master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); - if (master == NULL) { - dev_err(&pdev->dev, "No memory for spi_master\n"); - err = -ENOMEM; - goto err_nomem; - } - - hw = spi_master_get_devdata(master); - memset(hw, 0, sizeof(struct s3c24xx_spi)); - - hw->master = spi_master_get(master); - hw->pdata = pdev->dev.platform_data; - hw->dev = &pdev->dev; - - if (hw->pdata == NULL) { - dev_err(&pdev->dev, "No platform data supplied\n"); - err = -ENOENT; - goto err_no_pdata; - } - - platform_set_drvdata(pdev, hw); - init_completion(&hw->done); - - /* setup the state for the bitbang driver */ - - hw->bitbang.master = hw->master; - hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer; - hw->bitbang.chipselect = s3c24xx_spi_chipsel; - hw->bitbang.txrx_bufs = s3c24xx_spi_txrx; - hw->bitbang.master->setup = s3c24xx_spi_setup; - - dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); - - /* find and map our resources */ - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); - err = -ENOENT; - goto err_no_iores; - } - - hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1, - pdev->name); - - if (hw->ioarea == NULL) { - dev_err(&pdev->dev, "Cannot reserve region\n"); - err = -ENXIO; - goto err_no_iores; - } - - hw->regs = ioremap(res->start, (res->end - res->start)+1); - if (hw->regs == NULL) { - dev_err(&pdev->dev, "Cannot map IO\n"); - err = -ENXIO; - goto err_no_iomap; - } - - hw->irq = platform_get_irq(pdev, 0); - if (hw->irq < 0) { - dev_err(&pdev->dev, "No IRQ specified\n"); - err = -ENOENT; - goto err_no_irq; - } - - err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); - if (err) { - dev_err(&pdev->dev, "Cannot claim IRQ\n"); - goto err_no_irq; - } - - hw->clk = clk_get(&pdev->dev, "spi"); - if (IS_ERR(hw->clk)) { - dev_err(&pdev->dev, "No clock for device\n"); - err = PTR_ERR(hw->clk); - goto err_no_clk; - } - - /* for the moment, permanently enable the clock */ - - clk_enable(hw->clk); - - /* program defaults into the registers */ - - writeb(0xff, hw->regs + S3C2410_SPPRE); - writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); - writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); - - /* setup any gpio we can */ - - if (!hw->pdata->set_cs) { - s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); - s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); - } - - /* register our spi controller */ - - err = spi_bitbang_start(&hw->bitbang); - if (err) { - dev_err(&pdev->dev, "Failed to register SPI master\n"); - goto err_register; - } - - dev_dbg(hw->dev, "shutdown=%d\n", hw->bitbang.shutdown); - - /* register all the devices associated */ - - bi = &hw->pdata->board_info[0]; - for (i = 0; i < hw->pdata->board_size; i++, bi++) { - dev_info(hw->dev, "registering %s\n", bi->modalias); - - bi->controller_data = hw; - spi_new_device(master, bi); - } - - return 0; - - err_register: - clk_disable(hw->clk); - clk_put(hw->clk); - - err_no_clk: - free_irq(hw->irq, hw); - - err_no_irq: - iounmap(hw->regs); - - err_no_iomap: - release_resource(hw->ioarea); - kfree(hw->ioarea); - - err_no_iores: - err_no_pdata: - spi_master_put(hw->master);; - - err_nomem: - return err; -} - -static int s3c24xx_spi_remove(struct platform_device *dev) -{ - struct s3c24xx_spi *hw = platform_get_drvdata(dev); - - platform_set_drvdata(dev, NULL); - - spi_unregister_master(hw->master); - - clk_disable(hw->clk); - clk_put(hw->clk); - - free_irq(hw->irq, hw); - iounmap(hw->regs); - - release_resource(hw->ioarea); - kfree(hw->ioarea); - - spi_master_put(hw->master); - return 0; -} - - -#ifdef CONFIG_PM - -static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg) -{ - struct s3c24xx_spi *hw = platform_get_drvdata(pdev); - - clk_disable(hw->clk); - return 0; -} - -static int s3c24xx_spi_resume(struct platform_device *pdev) -{ - struct s3c24xx_spi *hw = platform_get_drvdata(pdev); - - clk_enable(hw->clk); - return 0; -} - -#else -#define s3c24xx_spi_suspend NULL -#define s3c24xx_spi_resume NULL -#endif - -static struct platform_driver s3c24xx_spidrv = { - .probe = s3c24xx_spi_probe, - .remove = s3c24xx_spi_remove, - .suspend = s3c24xx_spi_suspend, - .resume = s3c24xx_spi_resume, - .driver = { - .name = "s3c2410-spi", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c24xx_spi_init(void) -{ - return platform_driver_register(&s3c24xx_spidrv); -} - -static void __exit s3c24xx_spi_exit(void) -{ - platform_driver_unregister(&s3c24xx_spidrv); -} - -module_init(s3c24xx_spi_init); -module_exit(s3c24xx_spi_exit); - -MODULE_DESCRIPTION("S3C24XX SPI Driver"); -MODULE_AUTHOR("Ben Dooks, "); -MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi_s3c24xx_gpio.c b/drivers/spi/spi_s3c24xx_gpio.c deleted file mode 100644 index aacdceb8f..000000000 --- a/drivers/spi/spi_s3c24xx_gpio.c +++ /dev/null @@ -1,188 +0,0 @@ -/* linux/drivers/spi/spi_s3c24xx_gpio.c - * - * Copyright (c) 2006 Ben Dooks - * Copyright (c) 2006 Simtec Electronics - * - * S3C24XX GPIO based SPI driver - * - * 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 -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -struct s3c2410_spigpio { - struct spi_bitbang bitbang; - - struct s3c2410_spigpio_info *info; - struct platform_device *dev; -}; - -static inline struct s3c2410_spigpio *spidev_to_sg(struct spi_device *spi) -{ - return spi->controller_data; -} - -static inline void setsck(struct spi_device *dev, int on) -{ - struct s3c2410_spigpio *sg = spidev_to_sg(dev); - s3c2410_gpio_setpin(sg->info->pin_clk, on ? 1 : 0); -} - -static inline void setmosi(struct spi_device *dev, int on) -{ - struct s3c2410_spigpio *sg = spidev_to_sg(dev); - s3c2410_gpio_setpin(sg->info->pin_mosi, on ? 1 : 0); -} - -static inline u32 getmiso(struct spi_device *dev) -{ - struct s3c2410_spigpio *sg = spidev_to_sg(dev); - return s3c2410_gpio_getpin(sg->info->pin_miso) ? 1 : 0; -} - -#define spidelay(x) ndelay(x) - -#define EXPAND_BITBANG_TXRX -#include - - -static u32 s3c2410_spigpio_txrx_mode0(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits) -{ - return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); -} - -static u32 s3c2410_spigpio_txrx_mode1(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits) -{ - return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits); -} - -static void s3c2410_spigpio_chipselect(struct spi_device *dev, int value) -{ - struct s3c2410_spigpio *sg = spidev_to_sg(dev); - - if (sg->info && sg->info->chip_select) - (sg->info->chip_select)(sg->info, value); -} - -static int s3c2410_spigpio_probe(struct platform_device *dev) -{ - struct spi_master *master; - struct s3c2410_spigpio *sp; - int ret; - int i; - - master = spi_alloc_master(&dev->dev, sizeof(struct s3c2410_spigpio)); - if (master == NULL) { - dev_err(&dev->dev, "failed to allocate spi master\n"); - ret = -ENOMEM; - goto err; - } - - sp = spi_master_get_devdata(master); - - platform_set_drvdata(dev, sp); - - /* copy in the plkatform data */ - sp->info = dev->dev.platform_data; - - /* setup spi bitbang adaptor */ - sp->bitbang.master = spi_master_get(master); - sp->bitbang.chipselect = s3c2410_spigpio_chipselect; - - sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0; - sp->bitbang.txrx_word[SPI_MODE_1] = s3c2410_spigpio_txrx_mode1; - - /* set state of spi pins */ - s3c2410_gpio_setpin(sp->info->pin_clk, 0); - s3c2410_gpio_setpin(sp->info->pin_mosi, 0); - - s3c2410_gpio_cfgpin(sp->info->pin_clk, S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(sp->info->pin_mosi, S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(sp->info->pin_miso, S3C2410_GPIO_INPUT); - - ret = spi_bitbang_start(&sp->bitbang); - if (ret) - goto err_no_bitbang; - - /* register the chips to go with the board */ - - for (i = 0; i < sp->info->board_size; i++) { - dev_info(&dev->dev, "registering %p: %s\n", - &sp->info->board_info[i], - sp->info->board_info[i].modalias); - - sp->info->board_info[i].controller_data = sp; - spi_new_device(master, sp->info->board_info + i); - } - - return 0; - - err_no_bitbang: - spi_master_put(sp->bitbang.master); - err: - return ret; - -} - -static int s3c2410_spigpio_remove(struct platform_device *dev) -{ - struct s3c2410_spigpio *sp = platform_get_drvdata(dev); - - spi_bitbang_stop(&sp->bitbang); - spi_master_put(sp->bitbang.master); - - return 0; -} - -/* all gpio should be held over suspend/resume, so we should - * not need to deal with this -*/ - -#define s3c2410_spigpio_suspend NULL -#define s3c2410_spigpio_resume NULL - - -static struct platform_driver s3c2410_spigpio_drv = { - .probe = s3c2410_spigpio_probe, - .remove = s3c2410_spigpio_remove, - .suspend = s3c2410_spigpio_suspend, - .resume = s3c2410_spigpio_resume, - .driver = { - .name = "s3c24xx-spi-gpio", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c2410_spigpio_init(void) -{ - return platform_driver_register(&s3c2410_spigpio_drv); -} - -static void __exit s3c2410_spigpio_exit(void) -{ - platform_driver_unregister(&s3c2410_spigpio_drv); -} - -module_init(s3c2410_spigpio_init); -module_exit(s3c2410_spigpio_exit); - -MODULE_DESCRIPTION("S3C24XX SPI Driver"); -MODULE_AUTHOR("Ben Dooks, "); -MODULE_LICENSE("GPL"); diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index 2dffa8e30..6756d0fab 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c @@ -186,6 +186,8 @@ static struct tty_driver *serial_driver; #define RS_STROBE_TIME 10 #define RS_ISR_PASS_LIMIT 256 +#define _INLINE_ inline + static void probe_sccs(void); static void change_speed(struct dec_serial *info); static void rs_wait_until_sent(struct tty_struct *tty, int timeout); @@ -342,13 +344,14 @@ static inline void rs_recv_clear(struct dec_zschannel *zsc) * This routine is used by the interrupt handler to schedule * processing in the software interrupt portion of the driver. */ -static void rs_sched_event(struct dec_serial *info, int event) +static _INLINE_ void rs_sched_event(struct dec_serial *info, int event) { info->event |= 1 << event; tasklet_schedule(&info->tlet); } -static void receive_chars(struct dec_serial *info, struct pt_regs *regs) +static _INLINE_ void receive_chars(struct dec_serial *info, + struct pt_regs *regs) { struct tty_struct *tty = info->tty; unsigned char ch, stat, flag; @@ -438,7 +441,7 @@ static void transmit_chars(struct dec_serial *info) rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); } -static void status_handle(struct dec_serial *info) +static _INLINE_ void status_handle(struct dec_serial *info) { unsigned char stat; diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h index fbea4541c..8d69bcdc2 100644 --- a/drivers/telephony/ixj.h +++ b/drivers/telephony/ixj.h @@ -1295,7 +1295,7 @@ typedef struct { Proc_Info_Type Info_write; unsigned short frame_count; unsigned int filter_hist[4]; - unsigned char filter_en[4]; + unsigned char filter_en[6]; unsigned short proc_load; unsigned long framesread; unsigned long frameswritten; diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index dda0ca45d..d3a7b0c3d 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c @@ -35,52 +35,73 @@ typedef struct ixj_info_t { } ixj_info_t; static void ixj_detach(struct pcmcia_device *p_dev); -static int ixj_config(struct pcmcia_device * link); -static void ixj_cs_release(struct pcmcia_device * link); +static void ixj_config(dev_link_t * link); +static void ixj_cs_release(dev_link_t * link); -static int ixj_probe(struct pcmcia_device *p_dev) +static int ixj_attach(struct pcmcia_device *p_dev) { + dev_link_t *link; + DEBUG(0, "ixj_attach()\n"); /* Create new ixj device */ - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = 3; - p_dev->conf.IntType = INT_MEMORY_AND_IO; - p_dev->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL); - if (!p_dev->priv) { + link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); + if (!link) + return -ENOMEM; + memset(link, 0, sizeof(struct dev_link_t)); + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = 3; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL); + if (!link->priv) { + kfree(link); return -ENOMEM; } - memset(p_dev->priv, 0, sizeof(struct ixj_info_t)); + memset(link->priv, 0, sizeof(struct ixj_info_t)); + + link->handle = p_dev; + p_dev->instance = link; - return ixj_config(p_dev); + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + ixj_config(link); + + return 0; } -static void ixj_detach(struct pcmcia_device *link) +static void ixj_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + DEBUG(0, "ixj_detach(0x%p)\n", link); - ixj_cs_release(link); + link->state &= ~DEV_RELEASE_PENDING; + if (link->state & DEV_CONFIG) + ixj_cs_release(link); kfree(link->priv); + kfree(link); } #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) +static void ixj_get_serial(dev_link_t * link, IXJ * j) { + client_handle_t handle; tuple_t tuple; u_short buf[128]; char *str; int last_ret, last_fn, i, place; + handle = link->handle; DEBUG(0, "ixj_get_serial(0x%p)\n", link); tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 80; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_VERS_1; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); str = (char *) buf; printk("PCMCIA Version %d.%d\n", str[0], str[1]); str += 2; @@ -128,19 +149,22 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) return; } -static int ixj_config(struct pcmcia_device * link) +static void ixj_config(dev_link_t * link) { IXJ *j; + client_handle_t handle; ixj_info_t *info; tuple_t tuple; u_short buf[128]; cisparse_t parse; + config_info_t conf; cistpl_cftable_entry_t *cfg = &parse.cftable_entry; cistpl_cftable_entry_t dflt = { 0 }; int last_ret, last_fn; + handle = link->handle; info = link->priv; DEBUG(0, "ixj_config(0x%p)\n", link); tuple.TupleData = (cisdata_t *) buf; @@ -148,17 +172,19 @@ static int ixj_config(struct pcmcia_device * link) tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + link->state |= DEV_CONFIG; + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 || + pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; @@ -169,7 +195,7 @@ static int ixj_config(struct pcmcia_device * link) link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; } - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; /* If we've got this far, we're done */ break; @@ -177,10 +203,10 @@ static int ixj_config(struct pcmcia_device * link) next_entry: if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); } - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); /* * Register the card with the core. @@ -189,21 +215,46 @@ static int ixj_config(struct pcmcia_device * link) info->ndev = 1; info->node.major = PHONE_MAJOR; - link->dev_node = &info->node; + link->dev = &info->node; ixj_get_serial(link, j); - return 0; + link->state &= ~DEV_CONFIG_PENDING; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); ixj_cs_release(link); - return -ENODEV; } -static void ixj_cs_release(struct pcmcia_device *link) +static void ixj_cs_release(dev_link_t *link) { ixj_info_t *info = link->priv; DEBUG(0, "ixj_cs_release(0x%p)\n", link); info->ndev = 0; - pcmcia_disable_device(link); + link->dev = NULL; + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + link->state &= ~DEV_CONFIG; +} + +static int ixj_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int ixj_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (DEV_OK(link)) + pcmcia_request_configuration(link->handle, &link->conf); + + return 0; } static struct pcmcia_device_id ixj_ids[] = { @@ -217,9 +268,11 @@ static struct pcmcia_driver ixj_driver = { .drv = { .name = "ixj_cs", }, - .probe = ixj_probe, + .probe = ixj_attach, .remove = ixj_detach, .id_table = ixj_ids, + .suspend = ixj_suspend, + .resume = ixj_resume, }; static int __init ixj_pcmcia_init(void) diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index e166fffea..3c987f49f 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c @@ -29,7 +29,6 @@ #include #include #include -#include #define PHONE_NUM_DEVICES 256 @@ -38,7 +37,7 @@ */ static struct phone_device *phone_device[PHONE_NUM_DEVICES]; -static DEFINE_MUTEX(phone_lock); +static DECLARE_MUTEX(phone_lock); /* * Open a phone device. @@ -49,19 +48,19 @@ static int phone_open(struct inode *inode, struct file *file) unsigned int minor = iminor(inode); int err = 0; struct phone_device *p; - const struct file_operations *old_fops, *new_fops = NULL; + struct file_operations *old_fops, *new_fops = NULL; if (minor >= PHONE_NUM_DEVICES) return -ENODEV; - mutex_lock(&phone_lock); + down(&phone_lock); p = phone_device[minor]; if (p) new_fops = fops_get(p->f_op); if (!new_fops) { - mutex_unlock(&phone_lock); + up(&phone_lock); request_module("char-major-%d-%d", PHONE_MAJOR, minor); - mutex_lock(&phone_lock); + down(&phone_lock); p = phone_device[minor]; if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL) { @@ -79,7 +78,7 @@ static int phone_open(struct inode *inode, struct file *file) } fops_put(old_fops); end: - mutex_unlock(&phone_lock); + up(&phone_lock); return err; } @@ -101,18 +100,18 @@ int phone_register_device(struct phone_device *p, int unit) end = unit + 1; /* enter the loop at least one time */ } - mutex_lock(&phone_lock); + down(&phone_lock); for (i = base; i < end; i++) { if (phone_device[i] == NULL) { phone_device[i] = p; p->minor = i; devfs_mk_cdev(MKDEV(PHONE_MAJOR,i), S_IFCHR|S_IRUSR|S_IWUSR, "phone/%d", i); - mutex_unlock(&phone_lock); + up(&phone_lock); return 0; } } - mutex_unlock(&phone_lock); + up(&phone_lock); return -ENFILE; } @@ -122,12 +121,12 @@ int phone_register_device(struct phone_device *p, int unit) void phone_unregister_device(struct phone_device *pfd) { - mutex_lock(&phone_lock); + down(&phone_lock); if (phone_device[pfd->minor] != pfd) panic("phone: bad unregister"); devfs_remove("phone/%d", pfd->minor); phone_device[pfd->minor] = NULL; - mutex_unlock(&phone_lock); + up(&phone_lock); } diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7fdbc5dad..85dacc925 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -10,7 +10,6 @@ menu "USB support" config USB_ARCH_HAS_HCD boolean default y if USB_ARCH_HAS_OHCI - default y if USB_ARCH_HAS_EHCI default y if ARM # SL-811 default PCI @@ -23,7 +22,6 @@ config USB_ARCH_HAS_OHCI default y if ARCH_LH7A404 default y if ARCH_S3C2410 default y if PXA27x - default y if ARCH_AT91RM9200 # PPC: default y if STB03xxx default y if PPC_MPC52xx @@ -32,13 +30,6 @@ config USB_ARCH_HAS_OHCI # more: default PCI -# some non-PCI hcds implement EHCI -config USB_ARCH_HAS_EHCI - boolean - default y if PPC_83xx - default y if SOC_AU1200 - default PCI - # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. config USB tristate "Support for Host-side USB" @@ -87,6 +78,8 @@ source "drivers/usb/input/Kconfig" source "drivers/usb/image/Kconfig" +source "drivers/usb/media/Kconfig" + source "drivers/usb/net/Kconfig" source "drivers/usb/mon/Kconfig" diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 9b7d9769f..36e476dd9 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -15,9 +15,10 @@ obj-$(CONFIG_USB_OHCI_HCD) += host/ obj-$(CONFIG_USB_UHCI_HCD) += host/ obj-$(CONFIG_USB_SL811_HCD) += host/ obj-$(CONFIG_ETRAX_USB_HOST) += host/ -obj-$(CONFIG_USB_OHCI_AT91) += host/ obj-$(CONFIG_USB_ACM) += class/ +obj-$(CONFIG_USB_AUDIO) += class/ +obj-$(CONFIG_USB_MIDI) += class/ obj-$(CONFIG_USB_PRINTER) += class/ obj-$(CONFIG_USB_STORAGE) += storage/ @@ -35,6 +36,19 @@ obj-$(CONFIG_USB_WACOM) += input/ obj-$(CONFIG_USB_ACECAD) += input/ obj-$(CONFIG_USB_XPAD) += input/ +obj-$(CONFIG_USB_DABUSB) += media/ +obj-$(CONFIG_USB_DSBR) += media/ +obj-$(CONFIG_USB_ET61X251) += media/ +obj-$(CONFIG_USB_IBMCAM) += media/ +obj-$(CONFIG_USB_KONICAWC) += media/ +obj-$(CONFIG_USB_OV511) += media/ +obj-$(CONFIG_USB_PWC) += media/ +obj-$(CONFIG_USB_SE401) += media/ +obj-$(CONFIG_USB_SN9C102) += media/ +obj-$(CONFIG_USB_STV680) += media/ +obj-$(CONFIG_USB_VICAM) += media/ +obj-$(CONFIG_USB_W9968CF) += media/ + obj-$(CONFIG_USB_CATC) += net/ obj-$(CONFIG_USB_KAWETH) += net/ obj-$(CONFIG_USB_PEGASUS) += net/ diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 2a1697bfd..7860c8a58 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -5,6 +5,8 @@ * Copyright (C) 2003, Duncan Sands * Copyright (C) 2004, David Woodhouse * + * Based on "modem_run.c", copyright (C) 2001, Benoit Papillault + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) @@ -21,467 +23,206 @@ * ******************************************************************************/ -#include -#include +#include +#include +#include +#include #include +#include #include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "usb_atm.h" +#include +#include +#include +#include +#include -#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) -# define USE_FW_LOADER -#endif +#include "usbatm.h" #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands " -#define DRIVER_VERSION "1.8" +#define DRIVER_VERSION "1.10" #define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION static const char speedtch_driver_name[] = "speedtch"; -#define SPEEDTOUCH_VENDORID 0x06b9 -#define SPEEDTOUCH_PRODUCTID 0x4061 - -/* Timeout in jiffies */ -#define CTRL_TIMEOUT 2000 -#define DATA_TIMEOUT 2000 - -#define OFFSET_7 0 /* size 1 */ -#define OFFSET_b 1 /* size 8 */ -#define OFFSET_d 9 /* size 4 */ -#define OFFSET_e 13 /* size 1 */ -#define OFFSET_f 14 /* size 1 */ -#define TOTAL 15 - -#define SIZE_7 1 -#define SIZE_b 8 -#define SIZE_d 4 -#define SIZE_e 1 -#define SIZE_f 1 +#define CTRL_TIMEOUT 2000 /* milliseconds */ +#define DATA_TIMEOUT 2000 /* milliseconds */ + +#define OFFSET_7 0 /* size 1 */ +#define OFFSET_b 1 /* size 8 */ +#define OFFSET_d 9 /* size 4 */ +#define OFFSET_e 13 /* size 1 */ +#define OFFSET_f 14 /* size 1 */ +#define TOTAL 15 + +#define SIZE_7 1 +#define SIZE_b 8 +#define SIZE_d 4 +#define SIZE_e 1 +#define SIZE_f 1 + +#define MIN_POLL_DELAY 5000 /* milliseconds */ +#define MAX_POLL_DELAY 60000 /* milliseconds */ + +#define RESUBMIT_DELAY 1000 /* milliseconds */ + +#define DEFAULT_BULK_ALTSETTING 1 +#define DEFAULT_ISOC_ALTSETTING 2 +#define DEFAULT_DL_512_FIRST 0 +#define DEFAULT_ENABLE_ISOC 0 +#define DEFAULT_SW_BUFFERING 0 + +static unsigned int altsetting = 0; /* zero means: use the default */ +static int dl_512_first = DEFAULT_DL_512_FIRST; +static int enable_isoc = DEFAULT_ENABLE_ISOC; +static int sw_buffering = DEFAULT_SW_BUFFERING; + +module_param(altsetting, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(altsetting, + "Alternative setting for data interface (bulk_default: " + __MODULE_STRING(DEFAULT_BULK_ALTSETTING) "; isoc_default: " + __MODULE_STRING(DEFAULT_ISOC_ALTSETTING) ")"); + +module_param(dl_512_first, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(dl_512_first, + "Read 512 bytes before sending firmware (default: " + __MODULE_STRING(DEFAULT_DL_512_FIRST) ")"); + +module_param(enable_isoc, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(enable_isoc, + "Use isochronous transfers if available (default: " + __MODULE_STRING(DEFAULT_ENABLE_ISOC) ")"); + +module_param(sw_buffering, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(sw_buffering, + "Enable software buffering (default: " + __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); + +#define INTERFACE_DATA 1 +#define ENDPOINT_INT 0x81 +#define ENDPOINT_BULK_DATA 0x07 +#define ENDPOINT_ISOC_DATA 0x07 +#define ENDPOINT_FIRMWARE 0x05 -static int dl_512_first = 0; -static int sw_buffering = 0; - -module_param(dl_512_first, bool, 0444); -MODULE_PARM_DESC(dl_512_first, "Read 512 bytes before sending firmware"); - -module_param(sw_buffering, uint, 0444); -MODULE_PARM_DESC(sw_buffering, "Enable software buffering"); - -#define UDSL_IOCTL_LINE_UP 1 -#define UDSL_IOCTL_LINE_DOWN 2 +#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) -#define SPEEDTCH_ENDPOINT_INT 0x81 -#define SPEEDTCH_ENDPOINT_DATA 0x07 -#define SPEEDTCH_ENDPOINT_FIRMWARE 0x05 +struct speedtch_instance_data { + struct usbatm_data *usbatm; -#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) + unsigned int altsetting; -static struct usb_device_id speedtch_usb_ids[] = { - {USB_DEVICE(SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID)}, - {} -}; + struct work_struct status_checker; -MODULE_DEVICE_TABLE(usb, speedtch_usb_ids); + unsigned char last_status; -struct speedtch_instance_data { - struct udsl_instance_data u; + int poll_delay; /* milliseconds */ - /* Status */ + struct timer_list resubmit_timer; struct urb *int_urb; unsigned char int_data[16]; - struct work_struct poll_work; - struct timer_list poll_timer; -}; -/* USB */ -static int speedtch_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id); -static void speedtch_usb_disconnect(struct usb_interface *intf); -static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code, - void *user_data); -static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs); -static void speedtch_poll_status(struct speedtch_instance_data *instance); - -static struct usb_driver speedtch_usb_driver = { - .owner = THIS_MODULE, - .name = speedtch_driver_name, - .probe = speedtch_usb_probe, - .disconnect = speedtch_usb_disconnect, - .ioctl = speedtch_usb_ioctl, - .id_table = speedtch_usb_ids, + unsigned char scratch_buffer[TOTAL]; }; /*************** ** firmware ** ***************/ -static void speedtch_got_firmware(struct speedtch_instance_data *instance, - int got_it) +static void speedtch_set_swbuff(struct speedtch_instance_data *instance, int state) { - int err; - struct usb_interface *intf; - - down(&instance->u.serialize); /* vs self, speedtch_firmware_start */ - if (instance->u.status == UDSL_LOADED_FIRMWARE) - goto out; - if (!got_it) { - instance->u.status = UDSL_NO_FIRMWARE; - goto out; - } - if ((err = usb_set_interface(instance->u.usb_dev, 1, 1)) < 0) { - dbg("speedtch_got_firmware: usb_set_interface returned %d!", err); - instance->u.status = UDSL_NO_FIRMWARE; - goto out; - } - - /* Set up interrupt endpoint */ - intf = usb_ifnum_to_if(instance->u.usb_dev, 0); - if (intf && !usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) { - - instance->int_urb = usb_alloc_urb(0, GFP_KERNEL); - if (instance->int_urb) { - - usb_fill_int_urb(instance->int_urb, instance->u.usb_dev, - usb_rcvintpipe(instance->u.usb_dev, SPEEDTCH_ENDPOINT_INT), - instance->int_data, - sizeof(instance->int_data), - speedtch_handle_int, instance, 50); - err = usb_submit_urb(instance->int_urb, GFP_KERNEL); - if (err) { - /* Doesn't matter; we'll poll anyway */ - dbg("speedtch_got_firmware: Submission of interrupt URB failed %d", err); - usb_free_urb(instance->int_urb); - instance->int_urb = NULL; - usb_driver_release_interface(&speedtch_usb_driver, intf); - } - } - } - /* Start status polling */ - mod_timer(&instance->poll_timer, jiffies + (1 * HZ)); - - instance->u.status = UDSL_LOADED_FIRMWARE; - tasklet_schedule(&instance->u.receive_tasklet); - out: - up(&instance->u.serialize); - wake_up_interruptible(&instance->u.firmware_waiters); -} - -static int speedtch_set_swbuff(struct speedtch_instance_data *instance, - int state) -{ - struct usb_device *dev = instance->u.usb_dev; + struct usbatm_data *usbatm = instance->usbatm; + struct usb_device *usb_dev = usbatm->usb_dev; int ret; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x32, 0x40, state ? 0x01 : 0x00, - 0x00, NULL, 0, 100); - if (ret < 0) { - printk("Warning: %sabling SW buffering: usb_control_msg returned %d\n", - state ? "En" : "Dis", ret); - return ret; - } - - dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis"); - return 0; + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), + 0x32, 0x40, state ? 0x01 : 0x00, 0x00, NULL, 0, CTRL_TIMEOUT); + if (ret < 0) + usb_warn(usbatm, + "%sabling SW buffering: usb_control_msg returned %d\n", + state ? "En" : "Dis", ret); + else + dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis"); } static void speedtch_test_sequence(struct speedtch_instance_data *instance) { - struct usb_device *dev = instance->u.usb_dev; - unsigned char buf[10]; + struct usbatm_data *usbatm = instance->usbatm; + struct usb_device *usb_dev = usbatm->usb_dev; + unsigned char *buf = instance->scratch_buffer; int ret; /* URB 147 */ buf[0] = 0x1c; buf[1] = 0x50; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x01, 0x40, 0x0b, 0x00, buf, 2, 100); + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), + 0x01, 0x40, 0x0b, 0x00, buf, 2, CTRL_TIMEOUT); if (ret < 0) - printk(KERN_WARNING "%s failed on URB147: %d\n", __func__, ret); + usb_warn(usbatm, "%s failed on URB147: %d\n", __func__, ret); /* URB 148 */ buf[0] = 0x32; buf[1] = 0x00; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x01, 0x40, 0x02, 0x00, buf, 2, 100); + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), + 0x01, 0x40, 0x02, 0x00, buf, 2, CTRL_TIMEOUT); if (ret < 0) - printk(KERN_WARNING "%s failed on URB148: %d\n", __func__, ret); + usb_warn(usbatm, "%s failed on URB148: %d\n", __func__, ret); /* URB 149 */ buf[0] = 0x01; buf[1] = 0x00; buf[2] = 0x01; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x01, 0x40, 0x03, 0x00, buf, 3, 100); + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), + 0x01, 0x40, 0x03, 0x00, buf, 3, CTRL_TIMEOUT); if (ret < 0) - printk(KERN_WARNING "%s failed on URB149: %d\n", __func__, ret); + usb_warn(usbatm, "%s failed on URB149: %d\n", __func__, ret); /* URB 150 */ buf[0] = 0x01; buf[1] = 0x00; buf[2] = 0x01; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x01, 0x40, 0x04, 0x00, buf, 3, 100); + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), + 0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT); if (ret < 0) - printk(KERN_WARNING "%s failed on URB150: %d\n", __func__, ret); -} - -static int speedtch_start_synchro(struct speedtch_instance_data *instance) -{ - struct usb_device *dev = instance->u.usb_dev; - unsigned char buf[2]; - int ret; - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x12, 0xc0, 0x04, 0x00, - buf, sizeof(buf), CTRL_TIMEOUT); - if (ret < 0) { - printk(KERN_WARNING "SpeedTouch: Failed to start ADSL synchronisation: %d\n", ret); - return ret; - } - - dbg("speedtch_start_synchro: modem prodded. %d Bytes returned: %02x %02x", ret, buf[0], buf[1]); - return 0; -} - -static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs) -{ - struct speedtch_instance_data *instance = urb->context; - unsigned int count = urb->actual_length; - int ret; - - /* The magic interrupt for "up state" */ - const static unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; - /* The magic interrupt for "down state" */ - const static unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - 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; - } - - if (count < 6) { - dbg("%s - int packet too short", __func__); - goto exit; - } - - if (!memcmp(up_int, instance->int_data, 6)) { - del_timer(&instance->poll_timer); - printk(KERN_NOTICE "DSL line goes up\n"); - } else if (!memcmp(down_int, instance->int_data, 6)) { - printk(KERN_NOTICE "DSL line goes down\n"); - } else { - int i; - - printk(KERN_DEBUG "Unknown interrupt packet of %d bytes:", count); - for (i = 0; i < count; i++) - printk(" %02x", instance->int_data[i]); - printk("\n"); - } - schedule_work(&instance->poll_work); - - exit: - rmb(); - if (!instance->int_urb) - return; - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) - err("%s - usb_submit_urb failed with result %d", __func__, ret); -} - -static int speedtch_get_status(struct speedtch_instance_data *instance, - unsigned char *buf) -{ - struct usb_device *dev = instance->u.usb_dev; - int ret; - - memset(buf, 0, TOTAL); - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, - CTRL_TIMEOUT); - if (ret < 0) { - dbg("MSG 7 failed"); - return ret; - } - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x12, 0xc0, 0x0b, 0x00, buf + OFFSET_b, SIZE_b, - CTRL_TIMEOUT); - if (ret < 0) { - dbg("MSG B failed"); - return ret; - } - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x12, 0xc0, 0x0d, 0x00, buf + OFFSET_d, SIZE_d, - CTRL_TIMEOUT); - if (ret < 0) { - dbg("MSG D failed"); - return ret; - } - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x01, 0xc0, 0x0e, 0x00, buf + OFFSET_e, SIZE_e, - CTRL_TIMEOUT); - if (ret < 0) { - dbg("MSG E failed"); - return ret; - } - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x01, 0xc0, 0x0f, 0x00, buf + OFFSET_f, SIZE_f, - CTRL_TIMEOUT); - if (ret < 0) { - dbg("MSG F failed"); - return ret; - } - - return 0; + usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret); } -static void speedtch_poll_status(struct speedtch_instance_data *instance) -{ - unsigned char buf[TOTAL]; - int ret; - - ret = speedtch_get_status(instance, buf); - if (ret) { - printk(KERN_WARNING - "SpeedTouch: Error %d fetching device status\n", ret); - return; - } - - dbg("Line state %02x", buf[OFFSET_7]); - - switch (buf[OFFSET_7]) { - case 0: - if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) { - instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; - printk(KERN_NOTICE "ADSL line is down\n"); - /* It'll never resync again unless we ask it to... */ - speedtch_start_synchro(instance); - } - break; - - case 0x08: - if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) { - instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN; - printk(KERN_NOTICE "ADSL line is blocked?\n"); - } - break; - - case 0x10: - if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) { - instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; - printk(KERN_NOTICE "ADSL line is synchronising\n"); - } - break; - - case 0x20: - if (instance->u.atm_dev->signal != ATM_PHY_SIG_FOUND) { - int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8) - | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24); - int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8) - | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24); - - if (!(down_speed & 0x0000ffff) && - !(up_speed & 0x0000ffff)) { - down_speed >>= 16; - up_speed >>= 16; - } - instance->u.atm_dev->link_rate = down_speed * 1000 / 424; - instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND; - - printk(KERN_NOTICE - "ADSL line is up (%d Kib/s down | %d Kib/s up)\n", - down_speed, up_speed); - } - break; - - default: - if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) { - instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN; - printk(KERN_NOTICE "Unknown line state %02x\n", buf[OFFSET_7]); - } - break; - } -} - -static void speedtch_timer_poll(unsigned long data) -{ - struct speedtch_instance_data *instance = (void *)data; - - schedule_work(&instance->poll_work); - mod_timer(&instance->poll_timer, jiffies + (5 * HZ)); -} - -#ifdef USE_FW_LOADER -static void speedtch_upload_firmware(struct speedtch_instance_data *instance, +static int speedtch_upload_firmware(struct speedtch_instance_data *instance, const struct firmware *fw1, const struct firmware *fw2) { unsigned char *buffer; - struct usb_device *usb_dev = instance->u.usb_dev; + struct usbatm_data *usbatm = instance->usbatm; struct usb_interface *intf; - int actual_length, ret; + struct usb_device *usb_dev = usbatm->usb_dev; + int actual_length; + int ret = 0; int offset; - dbg("speedtch_upload_firmware"); - - if (!(intf = usb_ifnum_to_if(usb_dev, 2))) { - dbg("speedtch_upload_firmware: interface not found!"); - goto fail; - } + usb_dbg(usbatm, "%s entered\n", __func__); if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) { - dbg("speedtch_upload_firmware: no memory for buffer!"); - goto fail; + ret = -ENOMEM; + usb_dbg(usbatm, "%s: no memory for buffer!\n", __func__); + goto out; } - /* A user-space firmware loader may already have claimed interface #2 */ - if ((ret = - usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) < 0) { - dbg("speedtch_upload_firmware: interface in use (%d)!", ret); - goto fail_free; + if (!(intf = usb_ifnum_to_if(usb_dev, 2))) { + ret = -ENODEV; + usb_dbg(usbatm, "%s: interface not found!\n", __func__); + goto out_free; } /* URB 7 */ if (dl_512_first) { /* some modems need a read before writing the firmware */ - ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), + ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, 0x200, &actual_length, 2000); if (ret < 0 && ret != -ETIMEDOUT) - dbg("speedtch_upload_firmware: read BLOCK0 from modem failed (%d)!", ret); + usb_warn(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret); else - dbg("speedtch_upload_firmware: BLOCK0 downloaded (%d bytes)", ret); + usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret); } /* URB 8 : both leds are static green */ @@ -489,60 +230,65 @@ static void speedtch_upload_firmware(struct speedtch_instance_data *instance, int thislen = min_t(int, PAGE_SIZE, fw1->size - offset); memcpy(buffer, fw1->data + offset, thislen); - ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), + ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, thislen, &actual_length, DATA_TIMEOUT); if (ret < 0) { - dbg("speedtch_upload_firmware: write BLOCK1 to modem failed (%d)!", ret); - goto fail_release; + usb_err(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret); + goto out_free; } - dbg("speedtch_upload_firmware: BLOCK1 uploaded (%zu bytes)", fw1->size); + usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size); } /* USB led blinking green, ADSL led off */ /* URB 11 */ - ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), + ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, 0x200, &actual_length, DATA_TIMEOUT); if (ret < 0) { - dbg("speedtch_upload_firmware: read BLOCK2 from modem failed (%d)!", ret); - goto fail_release; + usb_err(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret); + goto out_free; } - dbg("speedtch_upload_firmware: BLOCK2 downloaded (%d bytes)", actual_length); + usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length); /* URBs 12 to 139 - USB led blinking green, ADSL led off */ for (offset = 0; offset < fw2->size; offset += PAGE_SIZE) { int thislen = min_t(int, PAGE_SIZE, fw2->size - offset); memcpy(buffer, fw2->data + offset, thislen); - ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), + ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, thislen, &actual_length, DATA_TIMEOUT); if (ret < 0) { - dbg("speedtch_upload_firmware: write BLOCK3 to modem failed (%d)!", ret); - goto fail_release; + usb_err(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret); + goto out_free; } } - dbg("speedtch_upload_firmware: BLOCK3 uploaded (%zu bytes)", fw2->size); + usb_dbg(usbatm, "%s: BLOCK3 uploaded (%zu bytes)\n", __func__, fw2->size); /* USB led static green, ADSL led static red */ /* URB 142 */ - ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), + ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, 0x200, &actual_length, DATA_TIMEOUT); if (ret < 0) { - dbg("speedtch_upload_firmware: read BLOCK4 from modem failed (%d)!", ret); - goto fail_release; + usb_err(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret); + goto out_free; } /* success */ - dbg("speedtch_upload_firmware: BLOCK4 downloaded (%d bytes)", actual_length); + usb_dbg(usbatm, "%s: BLOCK4 downloaded (%d bytes)\n", __func__, actual_length); /* Delay to allow firmware to start up. We can do this here because we're in our own kernel thread anyway. */ - msleep(1000); + msleep_interruptible(1000); + + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { + usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret); + goto out_free; + } /* Enable software buffering, if requested */ if (sw_buffering) @@ -551,291 +297,595 @@ static void speedtch_upload_firmware(struct speedtch_instance_data *instance, /* Magic spell; don't ask us what this does */ speedtch_test_sequence(instance); - /* Start modem synchronisation */ - if (speedtch_start_synchro(instance)) - dbg("speedtch_start_synchro: failed"); - - speedtch_got_firmware(instance, 1); + ret = 0; +out_free: free_page((unsigned long)buffer); - return; - - fail_release: - /* Only release interface #2 if uploading failed; we don't release it - we succeeded. This prevents the userspace tools from trying to load - the firmware themselves */ - usb_driver_release_interface(&speedtch_usb_driver, intf); - fail_free: - free_page((unsigned long)buffer); - fail: - speedtch_got_firmware(instance, 0); +out: + return ret; } -static int speedtch_find_firmware(struct speedtch_instance_data - *instance, int phase, - const struct firmware **fw_p) +static int speedtch_find_firmware(struct usbatm_data *usbatm, struct usb_interface *intf, + int phase, const struct firmware **fw_p) { - char buf[24]; - const u16 bcdDevice = le16_to_cpu(instance->u.usb_dev->descriptor.bcdDevice); + struct device *dev = &intf->dev; + const u16 bcdDevice = le16_to_cpu(interface_to_usbdev(intf)->descriptor.bcdDevice); const u8 major_revision = bcdDevice >> 8; const u8 minor_revision = bcdDevice & 0xff; + char buf[24]; sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision); - dbg("speedtch_find_firmware: looking for %s", buf); + usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); - if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { + if (request_firmware(fw_p, buf, dev)) { sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision); - dbg("speedtch_find_firmware: looking for %s", buf); + usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); - if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { + if (request_firmware(fw_p, buf, dev)) { sprintf(buf, "speedtch-%d.bin", phase); - dbg("speedtch_find_firmware: looking for %s", buf); + usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); - if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { - dev_warn(&instance->u.usb_dev->dev, "no stage %d firmware found!", phase); + if (request_firmware(fw_p, buf, dev)) { + usb_err(usbatm, "%s: no stage %d firmware found!\n", __func__, phase); return -ENOENT; } } } - dev_info(&instance->u.usb_dev->dev, "found stage %d firmware %s\n", phase, buf); + usb_info(usbatm, "found stage %d firmware %s\n", phase, buf); return 0; } -static int speedtch_load_firmware(void *arg) +static int speedtch_heavy_init(struct usbatm_data *usbatm, struct usb_interface *intf) { const struct firmware *fw1, *fw2; - struct speedtch_instance_data *instance = arg; - - BUG_ON(!instance); + struct speedtch_instance_data *instance = usbatm->driver_data; + int ret; - daemonize("firmware/speedtch"); + if ((ret = speedtch_find_firmware(usbatm, intf, 1, &fw1)) < 0) + return ret; - if (!speedtch_find_firmware(instance, 1, &fw1)) { - if (!speedtch_find_firmware(instance, 2, &fw2)) { - speedtch_upload_firmware(instance, fw1, fw2); - release_firmware(fw2); - } + if ((ret = speedtch_find_firmware(usbatm, intf, 2, &fw2)) < 0) { release_firmware(fw1); + return ret; } - /* In case we failed, set state back to NO_FIRMWARE so that - another later attempt may work. Otherwise, we never actually - manage to recover if, for example, the firmware is on /usr and - we look for it too early. */ - speedtch_got_firmware(instance, 0); + if ((ret = speedtch_upload_firmware(instance, fw1, fw2)) < 0) + usb_err(usbatm, "%s: firmware upload failed (%d)!\n", __func__, ret); - module_put(THIS_MODULE); - udsl_put_instance(&instance->u); - return 0; + release_firmware(fw2); + release_firmware(fw1); + + return ret; } -#endif /* USE_FW_LOADER */ -static void speedtch_firmware_start(struct speedtch_instance_data *instance) + +/********** +** ATM ** +**********/ + +static int speedtch_read_status(struct speedtch_instance_data *instance) { -#ifdef USE_FW_LOADER + struct usbatm_data *usbatm = instance->usbatm; + struct usb_device *usb_dev = usbatm->usb_dev; + unsigned char *buf = instance->scratch_buffer; int ret; -#endif - dbg("speedtch_firmware_start"); + memset(buf, 0, TOTAL); - down(&instance->u.serialize); /* vs self, speedtch_got_firmware */ + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), + 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, + CTRL_TIMEOUT); + if (ret < 0) { + atm_dbg(usbatm, "%s: MSG 7 failed\n", __func__); + return ret; + } - if (instance->u.status >= UDSL_LOADING_FIRMWARE) { - up(&instance->u.serialize); - return; + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), + 0x12, 0xc0, 0x0b, 0x00, buf + OFFSET_b, SIZE_b, + CTRL_TIMEOUT); + if (ret < 0) { + atm_dbg(usbatm, "%s: MSG B failed\n", __func__); + return ret; + } + + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), + 0x12, 0xc0, 0x0d, 0x00, buf + OFFSET_d, SIZE_d, + CTRL_TIMEOUT); + if (ret < 0) { + atm_dbg(usbatm, "%s: MSG D failed\n", __func__); + return ret; + } + + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), + 0x01, 0xc0, 0x0e, 0x00, buf + OFFSET_e, SIZE_e, + CTRL_TIMEOUT); + if (ret < 0) { + atm_dbg(usbatm, "%s: MSG E failed\n", __func__); + return ret; + } + + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), + 0x01, 0xc0, 0x0f, 0x00, buf + OFFSET_f, SIZE_f, + CTRL_TIMEOUT); + if (ret < 0) { + atm_dbg(usbatm, "%s: MSG F failed\n", __func__); + return ret; } - instance->u.status = UDSL_LOADING_FIRMWARE; - up(&instance->u.serialize); + return 0; +} -#ifdef USE_FW_LOADER - udsl_get_instance(&instance->u); - try_module_get(THIS_MODULE); +static int speedtch_start_synchro(struct speedtch_instance_data *instance) +{ + struct usbatm_data *usbatm = instance->usbatm; + struct usb_device *usb_dev = usbatm->usb_dev; + unsigned char *buf = instance->scratch_buffer; + int ret; - ret = kernel_thread(speedtch_load_firmware, instance, - CLONE_FS | CLONE_FILES); + atm_dbg(usbatm, "%s entered\n", __func__); - if (ret >= 0) - return; /* OK */ + memset(buf, 0, 2); - dbg("speedtch_firmware_start: kernel_thread failed (%d)!", ret); + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), + 0x12, 0xc0, 0x04, 0x00, + buf, 2, CTRL_TIMEOUT); - module_put(THIS_MODULE); - udsl_put_instance(&instance->u); - /* Just pretend it never happened... hope modem_run happens */ -#endif /* USE_FW_LOADER */ + if (ret < 0) + atm_warn(usbatm, "failed to start ADSL synchronisation: %d\n", ret); + else + atm_dbg(usbatm, "%s: modem prodded. %d bytes returned: %02x %02x\n", + __func__, ret, buf[0], buf[1]); - speedtch_got_firmware(instance, 0); + return ret; } -static int speedtch_firmware_wait(struct udsl_instance_data *instance) +static void speedtch_check_status(struct speedtch_instance_data *instance) { - speedtch_firmware_start((void *)instance); + struct usbatm_data *usbatm = instance->usbatm; + struct atm_dev *atm_dev = usbatm->atm_dev; + unsigned char *buf = instance->scratch_buffer; + int down_speed, up_speed, ret; + unsigned char status; + +#ifdef VERBOSE_DEBUG + atm_dbg(usbatm, "%s entered\n", __func__); +#endif - if (wait_event_interruptible(instance->firmware_waiters, instance->status != UDSL_LOADING_FIRMWARE) < 0) - return -ERESTARTSYS; + ret = speedtch_read_status(instance); + if (ret < 0) { + atm_warn(usbatm, "error %d fetching device status\n", ret); + instance->poll_delay = min(2 * instance->poll_delay, MAX_POLL_DELAY); + return; + } - return (instance->status == UDSL_LOADED_FIRMWARE) ? 0 : -EAGAIN; -} + instance->poll_delay = max(instance->poll_delay / 2, MIN_POLL_DELAY); -/********** -** USB ** -**********/ + status = buf[OFFSET_7]; -static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code, - void *user_data) -{ - struct speedtch_instance_data *instance = usb_get_intfdata(intf); + if ((status != instance->last_status) || !status) { + atm_dbg(usbatm, "%s: line state 0x%02x\n", __func__, status); - dbg("speedtch_usb_ioctl entered"); + switch (status) { + case 0: + atm_dev->signal = ATM_PHY_SIG_LOST; + if (instance->last_status) + atm_info(usbatm, "ADSL line is down\n"); + /* It may never resync again unless we ask it to... */ + ret = speedtch_start_synchro(instance); + break; - if (!instance) { - dbg("speedtch_usb_ioctl: NULL instance!"); - return -ENODEV; - } + case 0x08: + atm_dev->signal = ATM_PHY_SIG_UNKNOWN; + atm_info(usbatm, "ADSL line is blocked?\n"); + break; - switch (code) { - case UDSL_IOCTL_LINE_UP: - instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND; - speedtch_got_firmware(instance, 1); - return (instance->u.status == UDSL_LOADED_FIRMWARE) ? 0 : -EIO; - case UDSL_IOCTL_LINE_DOWN: - instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; - return 0; - default: - return -ENOTTY; + case 0x10: + atm_dev->signal = ATM_PHY_SIG_LOST; + atm_info(usbatm, "ADSL line is synchronising\n"); + break; + + case 0x20: + down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8) + | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24); + up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8) + | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24); + + if (!(down_speed & 0x0000ffff) && !(up_speed & 0x0000ffff)) { + down_speed >>= 16; + up_speed >>= 16; + } + + atm_dev->link_rate = down_speed * 1000 / 424; + atm_dev->signal = ATM_PHY_SIG_FOUND; + + atm_info(usbatm, + "ADSL line is up (%d kb/s down | %d kb/s up)\n", + down_speed, up_speed); + break; + + default: + atm_dev->signal = ATM_PHY_SIG_UNKNOWN; + atm_info(usbatm, "unknown line state %02x\n", status); + break; + } + + instance->last_status = status; } } -static int speedtch_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) +static void speedtch_status_poll(unsigned long data) { - struct usb_device *dev = interface_to_usbdev(intf); - int ifnum = intf->altsetting->desc.bInterfaceNumber; - struct speedtch_instance_data *instance; - unsigned char mac_str[13]; - int ret, i; - char buf7[SIZE_7]; + struct speedtch_instance_data *instance = (void *)data; - dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct), ifnum); + schedule_work(&instance->status_checker); - if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || - (ifnum != 1)) - return -ENODEV; + /* The following check is racy, but the race is harmless */ + if (instance->poll_delay < MAX_POLL_DELAY) + mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(instance->poll_delay)); + else + atm_warn(instance->usbatm, "Too many failures - disabling line status polling\n"); +} - dbg("speedtch_usb_probe: device accepted"); +static void speedtch_resubmit_int(unsigned long data) +{ + struct speedtch_instance_data *instance = (void *)data; + struct urb *int_urb = instance->int_urb; + int ret; - /* instance init */ - instance = kmalloc(sizeof(*instance), GFP_KERNEL); - if (!instance) { - dbg("speedtch_usb_probe: no memory for instance data!"); - return -ENOMEM; + atm_dbg(instance->usbatm, "%s entered\n", __func__); + + if (int_urb) { + ret = usb_submit_urb(int_urb, GFP_ATOMIC); + if (!ret) + schedule_work(&instance->status_checker); + else { + atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); + mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); + } } +} - memset(instance, 0, sizeof(struct speedtch_instance_data)); +static void speedtch_handle_int(struct urb *int_urb, struct pt_regs *regs) +{ + struct speedtch_instance_data *instance = int_urb->context; + struct usbatm_data *usbatm = instance->usbatm; + unsigned int count = int_urb->actual_length; + int ret = int_urb->status; - if ((ret = usb_set_interface(dev, 0, 0)) < 0) - goto fail; + /* The magic interrupt for "up state" */ + static const unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; + /* The magic interrupt for "down state" */ + static const unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + atm_dbg(usbatm, "%s entered\n", __func__); - if ((ret = usb_set_interface(dev, 2, 0)) < 0) + if (ret < 0) { + atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, ret); goto fail; + } - instance->u.data_endpoint = SPEEDTCH_ENDPOINT_DATA; - instance->u.firmware_wait = speedtch_firmware_wait; - instance->u.driver_name = speedtch_driver_name; + if ((count == 6) && !memcmp(up_int, instance->int_data, 6)) { + del_timer(&instance->status_checker.timer); + atm_info(usbatm, "DSL line goes up\n"); + } else if ((count == 6) && !memcmp(down_int, instance->int_data, 6)) { + atm_info(usbatm, "DSL line goes down\n"); + } else { + int i; - ret = udsl_instance_setup(dev, &instance->u); - if (ret) + atm_dbg(usbatm, "%s: unknown interrupt packet of length %d:", __func__, count); + for (i = 0; i < count; i++) + printk(" %02x", instance->int_data[i]); + printk("\n"); goto fail; + } - init_timer(&instance->poll_timer); - instance->poll_timer.function = speedtch_timer_poll; - instance->poll_timer.data = (unsigned long)instance; + if ((int_urb = instance->int_urb)) { + ret = usb_submit_urb(int_urb, GFP_ATOMIC); + schedule_work(&instance->status_checker); + if (ret < 0) { + atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); + goto fail; + } + } - INIT_WORK(&instance->poll_work, (void *)speedtch_poll_status, instance); + return; + +fail: + if ((int_urb = instance->int_urb)) + mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); +} + +static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_dev) +{ + struct usb_device *usb_dev = usbatm->usb_dev; + struct speedtch_instance_data *instance = usbatm->driver_data; + int i, ret; + unsigned char mac_str[13]; - /* set MAC address, it is stored in the serial number */ - memset(instance->u.atm_dev->esi, 0, sizeof(instance->u.atm_dev->esi)); - if (usb_string(dev, dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { + atm_dbg(usbatm, "%s entered\n", __func__); + + /* Set MAC address, it is stored in the serial number */ + memset(atm_dev->esi, 0, sizeof(atm_dev->esi)); + if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { for (i = 0; i < 6; i++) - instance->u.atm_dev->esi[i] = - (hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1])); + atm_dev->esi[i] = (hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1])); } - /* First check whether the modem already seems to be alive */ - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x12, 0xc0, 0x07, 0x00, buf7, SIZE_7, 500); + /* Start modem synchronisation */ + ret = speedtch_start_synchro(instance); - if (ret == SIZE_7) { - dbg("firmware appears to be already loaded"); - speedtch_got_firmware(instance, 1); - speedtch_poll_status(instance); - } else { - speedtch_firmware_start(instance); + /* Set up interrupt endpoint */ + if (instance->int_urb) { + ret = usb_submit_urb(instance->int_urb, GFP_KERNEL); + if (ret < 0) { + /* Doesn't matter; we'll poll anyway */ + atm_dbg(usbatm, "%s: submission of interrupt URB failed (%d)!\n", __func__, ret); + usb_free_urb(instance->int_urb); + instance->int_urb = NULL; + } } - usb_set_intfdata(intf, instance); + /* Start status polling */ + mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(1000)); return 0; +} - fail: - kfree(instance); +static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_dev) +{ + struct speedtch_instance_data *instance = usbatm->driver_data; + struct urb *int_urb = instance->int_urb; + + atm_dbg(usbatm, "%s entered\n", __func__); + + del_timer_sync(&instance->status_checker.timer); + + /* + * Since resubmit_timer and int_urb can schedule themselves and + * each other, shutting them down correctly takes some care + */ + instance->int_urb = NULL; /* signal shutdown */ + mb(); + usb_kill_urb(int_urb); + del_timer_sync(&instance->resubmit_timer); + /* + * At this point, speedtch_handle_int and speedtch_resubmit_int + * can run or be running, but instance->int_urb == NULL means that + * they will not reschedule + */ + usb_kill_urb(int_urb); + del_timer_sync(&instance->resubmit_timer); + usb_free_urb(int_urb); - return -ENOMEM; + flush_scheduled_work(); } -static void speedtch_usb_disconnect(struct usb_interface *intf) + +/********** +** USB ** +**********/ + +static struct usb_device_id speedtch_usb_ids[] = { + {USB_DEVICE(0x06b9, 0x4061)}, + {} +}; + +MODULE_DEVICE_TABLE(usb, speedtch_usb_ids); + +static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *); + +static struct usb_driver speedtch_usb_driver = { + .name = speedtch_driver_name, + .probe = speedtch_usb_probe, + .disconnect = usbatm_usb_disconnect, + .id_table = speedtch_usb_ids +}; + +static void speedtch_release_interfaces(struct usb_device *usb_dev, int num_interfaces) { + struct usb_interface *cur_intf; + int i; + + for(i = 0; i < num_interfaces; i++) + if ((cur_intf = usb_ifnum_to_if(usb_dev, i))) { + usb_set_intfdata(cur_intf, NULL); + usb_driver_release_interface(&speedtch_usb_driver, cur_intf); + } +} + +static int speedtch_bind(struct usbatm_data *usbatm, + struct usb_interface *intf, + const struct usb_device_id *id) { - struct speedtch_instance_data *instance = usb_get_intfdata(intf); + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct usb_interface *cur_intf, *data_intf; + struct speedtch_instance_data *instance; + int ifnum = intf->altsetting->desc.bInterfaceNumber; + int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; + int i, ret; + int use_isoc; + + usb_dbg(usbatm, "%s entered\n", __func__); + + /* sanity checks */ + + if (usb_dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { + usb_err(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass); + return -ENODEV; + } + + if (!(data_intf = usb_ifnum_to_if(usb_dev, INTERFACE_DATA))) { + usb_err(usbatm, "%s: data interface not found!\n", __func__); + return -ENODEV; + } + + /* claim all interfaces */ + + for (i=0; i < num_interfaces; i++) { + cur_intf = usb_ifnum_to_if(usb_dev, i); + + if ((i != ifnum) && cur_intf) { + ret = usb_driver_claim_interface(&speedtch_usb_driver, cur_intf, usbatm); + + if (ret < 0) { + usb_err(usbatm, "%s: failed to claim interface %2d (%d)!\n", __func__, i, ret); + speedtch_release_interfaces(usb_dev, i); + return ret; + } + } + } - dbg("speedtch_usb_disconnect entered"); + instance = kzalloc(sizeof(*instance), GFP_KERNEL); if (!instance) { - dbg("speedtch_usb_disconnect: NULL instance!"); - return; + usb_err(usbatm, "%s: no memory for instance data!\n", __func__); + ret = -ENOMEM; + goto fail_release; } -/*QQ need to handle disconnects on interface #2 while uploading firmware */ -/*QQ and what about interface #1? */ + instance->usbatm = usbatm; - if (instance->int_urb) { - struct urb *int_urb = instance->int_urb; - instance->int_urb = NULL; - wmb(); - usb_unlink_urb(int_urb); - usb_free_urb(int_urb); + /* altsetting and enable_isoc may change at any moment, so take a snapshot */ + instance->altsetting = altsetting; + use_isoc = enable_isoc; + + if (instance->altsetting) + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { + usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->altsetting, ret); + instance->altsetting = 0; /* fall back to default */ + } + + if (!instance->altsetting && use_isoc) + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) { + usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret); + use_isoc = 0; /* fall back to bulk */ + } + + if (use_isoc) { + const struct usb_host_interface *desc = data_intf->cur_altsetting; + const __u8 target_address = USB_DIR_IN | usbatm->driver->isoc_in; + int i; + + use_isoc = 0; /* fall back to bulk if endpoint not found */ + + for (i=0; idesc.bNumEndpoints; i++) { + const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc; + + if ((endpoint_desc->bEndpointAddress == target_address)) { + use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC; + break; + } + } + + if (!use_isoc) + usb_info(usbatm, "isochronous transfer not supported - using bulk\n"); } - instance->int_data[0] = 1; - del_timer_sync(&instance->poll_timer); - wmb(); - flush_scheduled_work(); + if (!use_isoc && !instance->altsetting) + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) { + usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret); + goto fail_free; + } + + if (!instance->altsetting) + instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; + + usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); + + INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); + + instance->status_checker.timer.function = speedtch_status_poll; + instance->status_checker.timer.data = (unsigned long)instance; + instance->last_status = 0xff; + instance->poll_delay = MIN_POLL_DELAY; - udsl_instance_disconnect(&instance->u); + init_timer(&instance->resubmit_timer); + instance->resubmit_timer.function = speedtch_resubmit_int; + instance->resubmit_timer.data = (unsigned long)instance; - /* clean up */ - usb_set_intfdata(intf, NULL); - udsl_put_instance(&instance->u); + instance->int_urb = usb_alloc_urb(0, GFP_KERNEL); + + if (instance->int_urb) + usb_fill_int_urb(instance->int_urb, usb_dev, + usb_rcvintpipe(usb_dev, ENDPOINT_INT), + instance->int_data, sizeof(instance->int_data), + speedtch_handle_int, instance, 50); + else + usb_dbg(usbatm, "%s: no memory for interrupt urb!\n", __func__); + + /* check whether the modem already seems to be alive */ + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), + 0x12, 0xc0, 0x07, 0x00, + instance->scratch_buffer + OFFSET_7, SIZE_7, 500); + + usbatm->flags |= (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0); + + usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not"); + + if (!(usbatm->flags & UDSL_SKIP_HEAVY_INIT)) + if ((ret = usb_reset_device(usb_dev)) < 0) { + usb_err(usbatm, "%s: device reset failed (%d)!\n", __func__, ret); + goto fail_free; + } + + usbatm->driver_data = instance; + + return 0; + +fail_free: + usb_free_urb(instance->int_urb); + kfree(instance); +fail_release: + speedtch_release_interfaces(usb_dev, num_interfaces); + return ret; } +static void speedtch_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) +{ + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct speedtch_instance_data *instance = usbatm->driver_data; + + usb_dbg(usbatm, "%s entered\n", __func__); + + speedtch_release_interfaces(usb_dev, usb_dev->actconfig->desc.bNumInterfaces); + usb_free_urb(instance->int_urb); + kfree(instance); +} + + /*********** ** init ** ***********/ +static struct usbatm_driver speedtch_usbatm_driver = { + .driver_name = speedtch_driver_name, + .bind = speedtch_bind, + .heavy_init = speedtch_heavy_init, + .unbind = speedtch_unbind, + .atm_start = speedtch_atm_start, + .atm_stop = speedtch_atm_stop, + .bulk_in = ENDPOINT_BULK_DATA, + .bulk_out = ENDPOINT_BULK_DATA, + .isoc_in = ENDPOINT_ISOC_DATA +}; + +static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + return usbatm_usb_probe(intf, id, &speedtch_usbatm_driver); +} + static int __init speedtch_usb_init(void) { - dbg("speedtch_usb_init: driver version " DRIVER_VERSION); + dbg("%s: driver version %s", __func__, DRIVER_VERSION); return usb_register(&speedtch_usb_driver); } static void __exit speedtch_usb_cleanup(void) { - dbg("speedtch_usb_cleanup entered"); + dbg("%s", __func__); usb_deregister(&speedtch_usb_driver); } diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index b38990adf..830d2c982 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -68,7 +68,7 @@ #include "usbatm.h" -#define EAGLEUSBVERSION "ueagle 1.3" +#define EAGLEUSBVERSION "ueagle 1.2" /* @@ -243,7 +243,7 @@ enum { #define BULK_TIMEOUT 300 #define CTRL_TIMEOUT 1000 -#define ACK_TIMEOUT msecs_to_jiffies(3000) +#define ACK_TIMEOUT msecs_to_jiffies(1500) #define UEA_INTR_IFACE_NO 0 #define UEA_US_IFACE_NO 1 @@ -314,10 +314,6 @@ struct cmv { ((d) & 0xff) << 16 | \ ((a) & 0xff) << 8 | \ ((b) & 0xff)) -#define GETSA1(a) ((a >> 8) & 0xff) -#define GETSA2(a) (a & 0xff) -#define GETSA3(a) ((a >> 24) & 0xff) -#define GETSA4(a) ((a >> 16) & 0xff) #define SA_CNTL MAKESA('C', 'N', 'T', 'L') #define SA_DIAG MAKESA('D', 'I', 'A', 'G') @@ -732,12 +728,11 @@ bad2: uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i); return; bad1: - uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); + uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno); } static inline void wake_up_cmv_ack(struct uea_softc *sc) { - BUG_ON(sc->cmv_ack); sc->cmv_ack = 1; wake_up(&sc->cmv_ack_wait); } @@ -748,9 +743,6 @@ static inline int wait_cmv_ack(struct uea_softc *sc) sc->cmv_ack, ACK_TIMEOUT); sc->cmv_ack = 0; - uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", - jiffies_to_msecs(ret)); - if (ret < 0) return ret; @@ -799,12 +791,6 @@ static int uea_cmv(struct uea_softc *sc, struct cmv cmv; int ret; - uea_enters(INS_TO_USBDEV(sc)); - uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " - "offset : 0x%04x, data : 0x%08x\n", - FUNCTION_TYPE(function), FUNCTION_SUBTYPE(function), - GETSA1(address), GETSA2(address), GETSA3(address), - GETSA4(address), offset, data); /* we send a request, but we expect a reply */ sc->cmv_function = function | 0x2; sc->cmv_idx++; @@ -822,9 +808,7 @@ static int uea_cmv(struct uea_softc *sc, ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); if (ret < 0) return ret; - ret = wait_cmv_ack(sc); - uea_leaves(INS_TO_USBDEV(sc)); - return ret; + return wait_cmv_ack(sc); } static inline int uea_read_cmv(struct uea_softc *sc, @@ -938,7 +922,7 @@ static int uea_stat(struct uea_softc *sc) * we check the status again in order to detect the failure earlier */ if (sc->stats.phy.flags) { - uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n", + uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n", sc->stats.phy.flags); return 0; } @@ -1079,13 +1063,7 @@ static int uea_start_reset(struct uea_softc *sc) uea_enters(INS_TO_USBDEV(sc)); uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); - /* mask interrupt */ sc->booting = 1; - /* We need to set this here because, a ack timeout could have occured, - * but before we start the reboot, the ack occurs and set this to 1. - * So we will failed to wait Ready CMV. - */ - sc->cmv_ack = 0; UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST); /* reset statistics */ @@ -1111,7 +1089,6 @@ static int uea_start_reset(struct uea_softc *sc) msleep(1000); sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); - /* demask interrupt */ sc->booting = 0; /* start loading DSP */ @@ -1124,8 +1101,6 @@ static int uea_start_reset(struct uea_softc *sc) if (ret < 0) return ret; - uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); - /* Enter in R-IDLE (cmv) until instructed otherwise */ ret = uea_write_cmv(sc, SA_CNTL, 0, 1); if (ret < 0) @@ -1146,7 +1121,6 @@ static int uea_start_reset(struct uea_softc *sc) } /* Enter in R-ACT-REQ */ ret = uea_write_cmv(sc, SA_CNTL, 0, 2); - uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); out: release_firmware(cmvs_fw); sc->reset = 0; @@ -1261,7 +1235,6 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { wake_up_cmv_ack(sc); - uea_leaves(INS_TO_USBDEV(sc)); return; } @@ -1276,7 +1249,6 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) sc->data = sc->data << 16 | sc->data >> 16; wake_up_cmv_ack(sc); - uea_leaves(INS_TO_USBDEV(sc)); return; bad2: @@ -1284,14 +1256,12 @@ bad2: "Function : %d, Subfunction : %d\n", FUNCTION_TYPE(cmv->bFunction), FUNCTION_SUBTYPE(cmv->bFunction)); - uea_leaves(INS_TO_USBDEV(sc)); return; bad1: uea_err(INS_TO_USBDEV(sc), "invalid cmv received, " "wPreamble %d, bDirection %d\n", le16_to_cpu(cmv->wPreamble), cmv->bDirection); - uea_leaves(INS_TO_USBDEV(sc)); } /* @@ -1376,7 +1346,7 @@ static int uea_boot(struct uea_softc *sc) if (ret < 0) { uea_err(INS_TO_USBDEV(sc), "urb submition failed with error %d\n", ret); - goto err; + goto err1; } sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); @@ -1390,10 +1360,10 @@ static int uea_boot(struct uea_softc *sc) err2: usb_kill_urb(sc->urb_int); +err1: + kfree(intr); err: usb_free_urb(sc->urb_int); - sc->urb_int = NULL; - kfree(intr); uea_leaves(INS_TO_USBDEV(sc)); return -ENOMEM; } @@ -1538,7 +1508,7 @@ static ssize_t read_##name(struct device *dev, \ int ret = -ENODEV; \ struct uea_softc *sc; \ \ - mutex_lock(&uea_mutex); \ + mutex_lock(&uea_mutex); \ sc = dev_to_uea(dev); \ if (!sc) \ goto out; \ @@ -1546,7 +1516,7 @@ static ssize_t read_##name(struct device *dev, \ if (reset) \ sc->stats.phy.name = 0; \ out: \ - mutex_unlock(&uea_mutex); \ + mutex_unlock(&uea_mutex); \ return ret; \ } \ \ @@ -1673,7 +1643,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); if (!sc) { - uea_err(usb, "uea_init: not enough memory !\n"); + uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n"); return -ENOMEM; } diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 546249843..c1211fc03 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -99,11 +99,11 @@ static const char usbatm_driver_name[] = "usbatm"; #define UDSL_MAX_RCV_URBS 16 #define UDSL_MAX_SND_URBS 16 -#define UDSL_MAX_BUF_SIZE 65536 +#define UDSL_MAX_BUF_SIZE 64 * 1024 /* bytes */ #define UDSL_DEFAULT_RCV_URBS 4 #define UDSL_DEFAULT_SND_URBS 4 -#define UDSL_DEFAULT_RCV_BUF_SIZE 3392 /* 64 * ATM_CELL_SIZE */ -#define UDSL_DEFAULT_SND_BUF_SIZE 3392 /* 64 * ATM_CELL_SIZE */ +#define UDSL_DEFAULT_RCV_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ +#define UDSL_DEFAULT_SND_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ #define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD) @@ -135,7 +135,7 @@ MODULE_PARM_DESC(rcv_buf_bytes, module_param(snd_buf_bytes, uint, S_IRUGO); MODULE_PARM_DESC(snd_buf_bytes, "Size of the buffers used for transmission, in bytes (range: 1-" - __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: " + __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: " __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")"); diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 3a9102d25..ef105a92a 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig @@ -4,6 +4,53 @@ comment "USB Device Class drivers" depends on USB +config OBSOLETE_OSS_USB_DRIVER + bool "Obsolete OSS USB drivers" + depends on USB && SOUND + help + This option enables support for the obsolete USB Audio and Midi + drivers that are scheduled for removal in the near future since + there are ALSA drivers for the same hardware. + + Please contact Adrian Bunk if you had to + say Y here because of missing support in the ALSA drivers. + + If unsure, say N. + +config USB_AUDIO + tristate "USB Audio support" + depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER + help + Say Y here if you want to connect USB audio equipment such as + speakers to your computer's USB port. You only need this if you use + the OSS sound driver; ALSA has its own option for usb audio support. + + To compile this driver as a module, choose M here: the + module will be called audio. + +config USB_MIDI + tristate "USB MIDI support" + depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER + ---help--- + Say Y here if you want to connect a USB MIDI device to your + computer's USB port. You only need this if you use the OSS + sound system; USB MIDI devices are supported by ALSA's USB + audio driver. This driver is for devices that comply with + 'Universal Serial Bus Device Class Definition for MIDI Device'. + + The following devices are known to work: + * Steinberg USB2MIDI + * Roland MPU64 + * Roland PC-300 + * Roland SC8850 + * Roland UM-1 + * Roland UM-2 + * Roland UA-100 + * Yamaha MU1000 + + To compile this driver as a module, choose M here: the + module will be called usb-midi. + config USB_ACM tristate "USB Modem (CDC ACM) support" depends on USB diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile index cc391e6c2..229471247 100644 --- a/drivers/usb/class/Makefile +++ b/drivers/usb/class/Makefile @@ -4,4 +4,6 @@ # obj-$(CONFIG_USB_ACM) += cdc-acm.o +obj-$(CONFIG_USB_AUDIO) += audio.o +obj-$(CONFIG_USB_MIDI) += usb-midi.o obj-$(CONFIG_USB_PRINTER) += usblp.o diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c new file mode 100644 index 000000000..3ad9ee8b8 --- /dev/null +++ b/drivers/usb/class/audio.c @@ -0,0 +1,3869 @@ +/*****************************************************************************/ + +/* + * audio.c -- USB Audio Class driver + * + * Copyright (C) 1999, 2000, 2001, 2003, 2004 + * Alan Cox (alan@lxorguk.ukuu.org.uk) + * Thomas Sailer (sailer@ife.ee.ethz.ch) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Debugging: + * Use the 'lsusb' utility to dump the descriptors. + * + * 1999-09-07: Alan Cox + * Parsing Audio descriptor patch + * 1999-09-08: Thomas Sailer + * Added OSS compatible data io functions; both parts of the + * driver remain to be glued together + * 1999-09-10: Thomas Sailer + * Beautified the driver. Added sample format conversions. + * Still not properly glued with the parsing code. + * The parsing code seems to have its problems btw, + * Since it parses all available configs but doesn't + * store which iface/altsetting belongs to which config. + * 1999-09-20: Thomas Sailer + * Threw out Alan's parsing code and implemented my own one. + * You cannot reasonnably linearly parse audio descriptors, + * especially the AudioClass descriptors have to be considered + * pointer lists. Mixer parsing untested, due to lack of device. + * First stab at synch pipe implementation, the Dallas USB DAC + * wants to use an Asynch out pipe. usb_audio_state now basically + * only contains lists of mixer and wave devices. We can therefore + * now have multiple mixer/wave devices per USB device. + * 1999-10-28: Thomas Sailer + * Converted to URB API. Fixed a taskstate/wakeup semantics mistake + * that made the driver consume all available CPU cycles. + * Now runs stable on UHCI-Acher/Fliegl/Sailer. + * 1999-10-31: Thomas Sailer + * Audio can now be unloaded if it is not in use by any mixer + * or dsp client (formerly you had to disconnect the audio devices + * from the USB port) + * Finally, about three months after ordering, my "Maxxtro SPK222" + * speakers arrived, isn't disdata a great mail order company 8-) + * Parse class specific endpoint descriptor of the audiostreaming + * interfaces and take the endpoint attributes from there. + * Unbelievably, the Philips USB DAC has a sampling rate range + * of over a decade, yet does not support the sampling rate control! + * No wonder it sounds so bad, has very audible sampling rate + * conversion distortion. Don't try to listen to it using + * decent headphones! + * "Let's make things better" -> but please Philips start with your + * own stuff!!!! + * 1999-11-02: Thomas Sailer + * It takes the Philips boxes several seconds to acquire synchronisation + * that means they won't play short sounds. Should probably maintain + * the ISO datastream even if there's nothing to play. + * Fix counting the total_bytes counter, RealPlayer G2 depends on it. + * 1999-12-20: Thomas Sailer + * Fix bad bug in conversion to per interface probing. + * disconnect was called multiple times for the audio device, + * leading to a premature freeing of the audio structures + * 2000-05-13: Thomas Sailer + * I don't remember who changed the find_format routine, + * but the change was completely broken for the Dallas + * chip. Anyway taking sampling rate into account in find_format + * is bad and should not be done unless there are devices with + * completely broken audio descriptors. Unless someone shows + * me such a descriptor, I will not allow find_format to + * take the sampling rate into account. + * Also, the former find_format made: + * - mpg123 play mono instead of stereo + * - sox completely fail for wav's with sample rates < 44.1kHz + * for the Dallas chip. + * Also fix a rather long standing problem with applications that + * use "small" writes producing no sound at all. + * 2000-05-15: Thomas Sailer + * My fears came true, the Philips camera indeed has pretty stupid + * audio descriptors. + * 2000-05-17: Thomas Sailer + * Nemsoft spotted my stupid last minute change, thanks + * 2000-05-19: Thomas Sailer + * Fixed FEATURE_UNIT thinkos found thanks to the KC Technology + * Xtend device. Basically the driver treated FEATURE_UNIT's sourced + * by mono terminals as stereo. + * 2000-05-20: Thomas Sailer + * SELECTOR support (and thus selecting record channels from the mixer). + * Somewhat peculiar due to OSS interface limitations. Only works + * for channels where a "slider" is already in front of it (i.e. + * a MIXER unit or a FEATURE unit with volume capability). + * 2000-11-26: Thomas Sailer + * Workaround for Dallas DS4201. The DS4201 uses PCM8 as format tag for + * its 8 bit modes, but expects signed data (and should therefore have used PCM). + * 2001-03-10: Thomas Sailer + * provide abs function, prevent picking up a bogus kernel macro + * for abs. Bug report by Andrew Morton + * 2001-06-16: Bryce Nesbitt + * Fix SNDCTL_DSP_STEREO API violation + * 2003-04-08: Oliver Neukum (oliver@neukum.name): + * Setting a configuration is done by usbcore and must not be overridden + * 2004-02-27: Workaround for broken synch descriptors + * 2004-03-07: Alan Stern + * Add usb_ifnum_to_if() and usb_altnum_to_altsetting() support. + * Use the in-memory descriptors instead of reading them from the device. + * + */ + +/* + * Strategy: + * + * Alan Cox and Thomas Sailer are starting to dig at opposite ends and + * are hoping to meet in the middle, just like tunnel diggers :) + * Alan tackles the descriptor parsing, Thomas the actual data IO and the + * OSS compatible interface. + * + * Data IO implementation issues + * + * A mmap'able ring buffer per direction is implemented, because + * almost every OSS app expects it. It is however impractical to + * transmit/receive USB data directly into and out of the ring buffer, + * due to alignment and synchronisation issues. Instead, the ring buffer + * feeds a constant time delay line that handles the USB issues. + * + * Now we first try to find an alternate setting that exactly matches + * the sample format requested by the user. If we find one, we do not + * need to perform any sample rate conversions. If there is no matching + * altsetting, we choose the closest one and perform sample format + * conversions. We never do sample rate conversion; these are too + * expensive to be performed in the kernel. + * + * Current status: no known HCD-specific issues. + * + * Generally: Due to the brokenness of the Audio Class spec + * it seems generally impossible to write a generic Audio Class driver, + * so a reasonable driver should implement the features that are actually + * used. + * + * Parsing implementation issues + * + * One cannot reasonably parse the AudioClass descriptors linearly. + * Therefore the current implementation features routines to look + * for a specific descriptor in the descriptor list. + * + * How does the parsing work? First, all interfaces are searched + * for an AudioControl class interface. If found, the config descriptor + * that belongs to the current configuration is searched and + * the HEADER descriptor is found. It contains a list of + * all AudioStreaming and MIDIStreaming devices. This list is then walked, + * and all AudioStreaming interfaces are classified into input and output + * interfaces (according to the endpoint0 direction in altsetting1) (MIDIStreaming + * is currently not supported). The input & output list is then used + * to group inputs and outputs together and issued pairwise to the + * AudioStreaming class parser. Finally, all OUTPUT_TERMINAL descriptors + * are walked and issued to the mixer construction routine. + * + * The AudioStreaming parser simply enumerates all altsettings belonging + * to the specified interface. It looks for AS_GENERAL and FORMAT_TYPE + * class specific descriptors to extract the sample format/sample rate + * data. Only sample format types PCM and PCM8 are supported right now, and + * only FORMAT_TYPE_I is handled. The isochronous data endpoint needs to + * be the first endpoint of the interface, and the optional synchronisation + * isochronous endpoint the second one. + * + * Mixer construction works as follows: The various TERMINAL and UNIT + * descriptors span a tree from the root (OUTPUT_TERMINAL) through the + * intermediate nodes (UNITs) to the leaves (INPUT_TERMINAL). We walk + * that tree in a depth first manner. FEATURE_UNITs may contribute volume, + * bass and treble sliders to the mixer, MIXER_UNITs volume sliders. + * The terminal type encoded in the INPUT_TERMINALs feeds a heuristic + * to determine "meaningful" OSS slider numbers, however we will see + * how well this works in practice. Other features are not used at the + * moment, they seem less often used. Also, it seems difficult at least + * to construct recording source switches from SELECTOR_UNITs, but + * since there are not many USB ADC's available, we leave that for later. + */ + +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "audio.h" + +/* + * Version Information + */ +#define DRIVER_VERSION "v1.0.0" +#define DRIVER_AUTHOR "Alan Cox , Thomas Sailer (sailer@ife.ee.ethz.ch)" +#define DRIVER_DESC "USB Audio Class driver" + +#define AUDIO_DEBUG 1 + +#define SND_DEV_DSP16 5 + +#define dprintk(x) + +/* --------------------------------------------------------------------- */ + +/* + * Linked list of all audio devices... + */ +static struct list_head audiodevs = LIST_HEAD_INIT(audiodevs); +static DECLARE_MUTEX(open_sem); + +/* + * wait queue for processes wanting to open an USB audio device + */ +static DECLARE_WAIT_QUEUE_HEAD(open_wait); + + +#define MAXFORMATS MAX_ALT +#define DMABUFSHIFT 17 /* 128k worth of DMA buffer */ +#define NRSGBUF (1U<<(DMABUFSHIFT-PAGE_SHIFT)) + +/* + * This influences: + * - Latency + * - Interrupt rate + * - Synchronisation behaviour + * Don't touch this if you don't understand all of the above. + */ +#define DESCFRAMES 5 +#define SYNCFRAMES DESCFRAMES + +#define MIXFLG_STEREOIN 1 +#define MIXFLG_STEREOOUT 2 + +struct mixerchannel { + __u16 value; + __u16 osschannel; /* number of the OSS channel */ + __s16 minval, maxval; + __u16 slctunitid; + __u8 unitid; + __u8 selector; + __u8 chnum; + __u8 flags; +}; + +struct audioformat { + unsigned int format; + unsigned int sratelo; + unsigned int sratehi; + unsigned char altsetting; + unsigned char attributes; +}; + +struct dmabuf { + /* buffer data format */ + unsigned int format; + unsigned int srate; + /* physical buffer */ + unsigned char *sgbuf[NRSGBUF]; + unsigned bufsize; + unsigned numfrag; + unsigned fragshift; + unsigned wrptr, rdptr; + unsigned total_bytes; + int count; + unsigned error; /* over/underrun */ + wait_queue_head_t wait; + /* redundant, but makes calculations easier */ + unsigned fragsize; + unsigned dmasize; + /* OSS stuff */ + unsigned mapped:1; + unsigned ready:1; + unsigned ossfragshift; + int ossmaxfrags; + unsigned subdivision; +}; + +struct usb_audio_state; + +#define FLG_URB0RUNNING 1 +#define FLG_URB1RUNNING 2 +#define FLG_SYNC0RUNNING 4 +#define FLG_SYNC1RUNNING 8 +#define FLG_RUNNING 16 +#define FLG_CONNECTED 32 + +struct my_data_urb { + struct urb *urb; +}; + +struct my_sync_urb { + struct urb *urb; +}; + + +struct usb_audiodev { + struct list_head list; + struct usb_audio_state *state; + + /* soundcore stuff */ + int dev_audio; + + /* wave stuff */ + mode_t open_mode; + spinlock_t lock; /* DMA buffer access spinlock */ + + struct usbin { + int interface; /* Interface number, -1 means not used */ + unsigned int format; /* USB data format */ + unsigned int datapipe; /* the data input pipe */ + unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but adaptive IN mode */ + unsigned int syncinterval; /* P for adaptive IN mode, 0 otherwise */ + unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */ + unsigned int freqmax; /* maximum sampling rate, used for buffer management */ + unsigned int phase; /* phase accumulator */ + unsigned int flags; /* see FLG_ defines */ + + struct my_data_urb durb[2]; /* ISO descriptors for the data endpoint */ + struct my_sync_urb surb[2]; /* ISO sync pipe descriptor if needed */ + + struct dmabuf dma; + } usbin; + + struct usbout { + int interface; /* Interface number, -1 means not used */ + unsigned int format; /* USB data format */ + unsigned int datapipe; /* the data input pipe */ + unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but asynchronous OUT mode */ + unsigned int syncinterval; /* P for asynchronous OUT mode, 0 otherwise */ + unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */ + unsigned int freqm; /* momentary sampling rate in USB format, i.e. fs/1000 in Q10.14 */ + unsigned int freqmax; /* maximum sampling rate, used for buffer management */ + unsigned int phase; /* phase accumulator */ + unsigned int flags; /* see FLG_ defines */ + + struct my_data_urb durb[2]; /* ISO descriptors for the data endpoint */ + struct my_sync_urb surb[2]; /* ISO sync pipe descriptor if needed */ + + struct dmabuf dma; + } usbout; + + + unsigned int numfmtin, numfmtout; + struct audioformat fmtin[MAXFORMATS]; + struct audioformat fmtout[MAXFORMATS]; +}; + +struct usb_mixerdev { + struct list_head list; + struct usb_audio_state *state; + + /* soundcore stuff */ + int dev_mixer; + + unsigned char iface; /* interface number of the AudioControl interface */ + + /* USB format descriptions */ + unsigned int numch, modcnt; + + /* mixch is last and gets allocated dynamically */ + struct mixerchannel ch[0]; +}; + +struct usb_audio_state { + struct list_head audiodev; + + /* USB device */ + struct usb_device *usbdev; + + struct list_head audiolist; + struct list_head mixerlist; + + unsigned count; /* usage counter; NOTE: the usb stack is also considered a user */ +}; + +/* private audio format extensions */ +#define AFMT_STEREO 0x80000000 +#define AFMT_ISSTEREO(x) ((x) & AFMT_STEREO) +#define AFMT_IS16BIT(x) ((x) & (AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE)) +#define AFMT_ISUNSIGNED(x) ((x) & (AFMT_U8|AFMT_U16_LE|AFMT_U16_BE)) +#define AFMT_BYTESSHIFT(x) ((AFMT_ISSTEREO(x) ? 1 : 0) + (AFMT_IS16BIT(x) ? 1 : 0)) +#define AFMT_BYTES(x) (1<= 0x10000) { + x >>= 16; + r += 16; + } + if (x >= 0x100) { + x >>= 8; + r += 8; + } + if (x >= 0x10) { + x >>= 4; + r += 4; + } + if (x >= 4) { + x >>= 2; + r += 2; + } + if (x >= 2) + r++; + return r; +} + +/* --------------------------------------------------------------------- */ + +/* + * OSS compatible ring buffer management. The ring buffer may be mmap'ed into + * an application address space. + * + * I first used the rvmalloc stuff copied from bttv. Alan Cox did not like it, so + * we now use an array of pointers to a single page each. This saves us the + * kernel page table manipulations, but we have to do a page table alike mechanism + * (though only one indirection) in software. + */ + +static void dmabuf_release(struct dmabuf *db) +{ + unsigned int nr; + void *p; + + for(nr = 0; nr < NRSGBUF; nr++) { + if (!(p = db->sgbuf[nr])) + continue; + ClearPageReserved(virt_to_page(p)); + free_page((unsigned long)p); + db->sgbuf[nr] = NULL; + } + db->mapped = db->ready = 0; +} + +static int dmabuf_init(struct dmabuf *db) +{ + unsigned int nr, bytepersec, bufs; + void *p; + + /* initialize some fields */ + db->rdptr = db->wrptr = db->total_bytes = db->count = db->error = 0; + /* calculate required buffer size */ + bytepersec = db->srate << AFMT_BYTESSHIFT(db->format); + bufs = 1U << DMABUFSHIFT; + if (db->ossfragshift) { + if ((1000 << db->ossfragshift) < bytepersec) + db->fragshift = ld2(bytepersec/1000); + else + db->fragshift = db->ossfragshift; + } else { + db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); + if (db->fragshift < 3) + db->fragshift = 3; + } + db->numfrag = bufs >> db->fragshift; + while (db->numfrag < 4 && db->fragshift > 3) { + db->fragshift--; + db->numfrag = bufs >> db->fragshift; + } + db->fragsize = 1 << db->fragshift; + if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) + db->numfrag = db->ossmaxfrags; + db->dmasize = db->numfrag << db->fragshift; + for(nr = 0; nr < NRSGBUF; nr++) { + if (!db->sgbuf[nr]) { + p = (void *)get_zeroed_page(GFP_KERNEL); + if (!p) + return -ENOMEM; + db->sgbuf[nr] = p; + SetPageReserved(virt_to_page(p)); + } + memset(db->sgbuf[nr], AFMT_ISUNSIGNED(db->format) ? 0x80 : 0, PAGE_SIZE); + if ((nr << PAGE_SHIFT) >= db->dmasize) + break; + } + db->bufsize = nr << PAGE_SHIFT; + db->ready = 1; + dprintk((KERN_DEBUG "usbaudio: dmabuf_init bytepersec %d bufs %d ossfragshift %d ossmaxfrags %d " + "fragshift %d fragsize %d numfrag %d dmasize %d bufsize %d fmt 0x%x srate %d\n", + bytepersec, bufs, db->ossfragshift, db->ossmaxfrags, db->fragshift, db->fragsize, + db->numfrag, db->dmasize, db->bufsize, db->format, db->srate)); + return 0; +} + +static int dmabuf_mmap(struct vm_area_struct *vma, struct dmabuf *db, unsigned long start, unsigned long size, pgprot_t prot) +{ + unsigned int nr; + + if (!db->ready || db->mapped || (start | size) & (PAGE_SIZE-1) || size > db->bufsize) + return -EINVAL; + size >>= PAGE_SHIFT; + for(nr = 0; nr < size; nr++) + if (!db->sgbuf[nr]) + return -EINVAL; + db->mapped = 1; + for(nr = 0; nr < size; nr++) { + unsigned long pfn; + + pfn = virt_to_phys(db->sgbuf[nr]) >> PAGE_SHIFT; + if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, prot)) + return -EAGAIN; + start += PAGE_SIZE; + } + return 0; +} + +static void dmabuf_copyin(struct dmabuf *db, const void *buffer, unsigned int size) +{ + unsigned int pgrem, rem; + + db->total_bytes += size; + for (;;) { + if (size <= 0) + return; + pgrem = ((~db->wrptr) & (PAGE_SIZE-1)) + 1; + if (pgrem > size) + pgrem = size; + rem = db->dmasize - db->wrptr; + if (pgrem > rem) + pgrem = rem; + memcpy((db->sgbuf[db->wrptr >> PAGE_SHIFT]) + (db->wrptr & (PAGE_SIZE-1)), buffer, pgrem); + size -= pgrem; + buffer += pgrem; + db->wrptr += pgrem; + if (db->wrptr >= db->dmasize) + db->wrptr = 0; + } +} + +static void dmabuf_copyout(struct dmabuf *db, void *buffer, unsigned int size) +{ + unsigned int pgrem, rem; + + db->total_bytes += size; + for (;;) { + if (size <= 0) + return; + pgrem = ((~db->rdptr) & (PAGE_SIZE-1)) + 1; + if (pgrem > size) + pgrem = size; + rem = db->dmasize - db->rdptr; + if (pgrem > rem) + pgrem = rem; + memcpy(buffer, (db->sgbuf[db->rdptr >> PAGE_SHIFT]) + (db->rdptr & (PAGE_SIZE-1)), pgrem); + size -= pgrem; + buffer += pgrem; + db->rdptr += pgrem; + if (db->rdptr >= db->dmasize) + db->rdptr = 0; + } +} + +static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void __user *buffer, unsigned int size) +{ + unsigned int pgrem, rem; + + if (!db->ready || db->mapped) + return -EINVAL; + for (;;) { + if (size <= 0) + return 0; + pgrem = ((~ptr) & (PAGE_SIZE-1)) + 1; + if (pgrem > size) + pgrem = size; + rem = db->dmasize - ptr; + if (pgrem > rem) + pgrem = rem; + if (copy_from_user((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem)) + return -EFAULT; + size -= pgrem; + buffer += pgrem; + ptr += pgrem; + if (ptr >= db->dmasize) + ptr = 0; + } +} + +static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void __user *buffer, unsigned int size) +{ + unsigned int pgrem, rem; + + if (!db->ready || db->mapped) + return -EINVAL; + for (;;) { + if (size <= 0) + return 0; + pgrem = ((~ptr) & (PAGE_SIZE-1)) + 1; + if (pgrem > size) + pgrem = size; + rem = db->dmasize - ptr; + if (pgrem > rem) + pgrem = rem; + if (copy_to_user(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem)) + return -EFAULT; + size -= pgrem; + buffer += pgrem; + ptr += pgrem; + if (ptr >= db->dmasize) + ptr = 0; + } +} + +/* --------------------------------------------------------------------- */ +/* + * USB I/O code. We do sample format conversion if necessary + */ + +static void usbin_stop(struct usb_audiodev *as) +{ + struct usbin *u = &as->usbin; + unsigned long flags; + unsigned int i, notkilled = 1; + + spin_lock_irqsave(&as->lock, flags); + u->flags &= ~FLG_RUNNING; + i = u->flags; + spin_unlock_irqrestore(&as->lock, flags); + while (i & (FLG_URB0RUNNING|FLG_URB1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) { + if (notkilled) + schedule_timeout_interruptible(1); + else + schedule_timeout_uninterruptible(1); + spin_lock_irqsave(&as->lock, flags); + i = u->flags; + spin_unlock_irqrestore(&as->lock, flags); + if (notkilled && signal_pending(current)) { + if (i & FLG_URB0RUNNING) + usb_kill_urb(u->durb[0].urb); + if (i & FLG_URB1RUNNING) + usb_kill_urb(u->durb[1].urb); + if (i & FLG_SYNC0RUNNING) + usb_kill_urb(u->surb[0].urb); + if (i & FLG_SYNC1RUNNING) + usb_kill_urb(u->surb[1].urb); + notkilled = 0; + } + } + set_current_state(TASK_RUNNING); + kfree(u->durb[0].urb->transfer_buffer); + kfree(u->durb[1].urb->transfer_buffer); + kfree(u->surb[0].urb->transfer_buffer); + kfree(u->surb[1].urb->transfer_buffer); + u->durb[0].urb->transfer_buffer = u->durb[1].urb->transfer_buffer = + u->surb[0].urb->transfer_buffer = u->surb[1].urb->transfer_buffer = NULL; +} + +static inline void usbin_release(struct usb_audiodev *as) +{ + usbin_stop(as); +} + +static void usbin_disc(struct usb_audiodev *as) +{ + struct usbin *u = &as->usbin; + + unsigned long flags; + + spin_lock_irqsave(&as->lock, flags); + u->flags &= ~(FLG_RUNNING | FLG_CONNECTED); + spin_unlock_irqrestore(&as->lock, flags); + usbin_stop(as); +} + +static void conversion(const void *ibuf, unsigned int ifmt, void *obuf, unsigned int ofmt, void *tmp, unsigned int scnt) +{ + unsigned int cnt, i; + __s16 *sp, *sp2, s; + unsigned char *bp; + + cnt = scnt; + if (AFMT_ISSTEREO(ifmt)) + cnt <<= 1; + sp = ((__s16 *)tmp) + cnt; + switch (ifmt & ~AFMT_STEREO) { + case AFMT_U8: + for (bp = ((unsigned char *)ibuf)+cnt, i = 0; i < cnt; i++) { + bp--; + sp--; + *sp = (*bp ^ 0x80) << 8; + } + break; + + case AFMT_S8: + for (bp = ((unsigned char *)ibuf)+cnt, i = 0; i < cnt; i++) { + bp--; + sp--; + *sp = *bp << 8; + } + break; + + case AFMT_U16_LE: + for (bp = ((unsigned char *)ibuf)+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = (bp[0] | (bp[1] << 8)) ^ 0x8000; + } + break; + + case AFMT_U16_BE: + for (bp = ((unsigned char *)ibuf)+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = (bp[1] | (bp[0] << 8)) ^ 0x8000; + } + break; + + case AFMT_S16_LE: + for (bp = ((unsigned char *)ibuf)+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = bp[0] | (bp[1] << 8); + } + break; + + case AFMT_S16_BE: + for (bp = ((unsigned char *)ibuf)+2*cnt, i = 0; i < cnt; i++) { + bp -= 2; + sp--; + *sp = bp[1] | (bp[0] << 8); + } + break; + } + if (!AFMT_ISSTEREO(ifmt) && AFMT_ISSTEREO(ofmt)) { + /* expand from mono to stereo */ + for (sp = ((__s16 *)tmp)+scnt, sp2 = ((__s16 *)tmp)+2*scnt, i = 0; i < scnt; i++) { + sp--; + sp2 -= 2; + sp2[0] = sp2[1] = sp[0]; + } + } + if (AFMT_ISSTEREO(ifmt) && !AFMT_ISSTEREO(ofmt)) { + /* contract from stereo to mono */ + for (sp = sp2 = ((__s16 *)tmp), i = 0; i < scnt; i++, sp++, sp2 += 2) + sp[0] = (sp2[0] + sp2[1]) >> 1; + } + cnt = scnt; + if (AFMT_ISSTEREO(ofmt)) + cnt <<= 1; + sp = ((__s16 *)tmp); + bp = ((unsigned char *)obuf); + switch (ofmt & ~AFMT_STEREO) { + case AFMT_U8: + for (i = 0; i < cnt; i++, sp++, bp++) + *bp = (*sp >> 8) ^ 0x80; + break; + + case AFMT_S8: + for (i = 0; i < cnt; i++, sp++, bp++) + *bp = *sp >> 8; + break; + + case AFMT_U16_LE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[0] = s; + bp[1] = (s >> 8) ^ 0x80; + } + break; + + case AFMT_U16_BE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[1] = s; + bp[0] = (s >> 8) ^ 0x80; + } + break; + + case AFMT_S16_LE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[0] = s; + bp[1] = s >> 8; + } + break; + + case AFMT_S16_BE: + for (i = 0; i < cnt; i++, sp++, bp += 2) { + s = *sp; + bp[1] = s; + bp[0] = s >> 8; + } + break; + } + +} + +static void usbin_convert(struct usbin *u, unsigned char *buffer, unsigned int samples) +{ + union { + __s16 s[64]; + unsigned char b[0]; + } tmp; + unsigned int scnt, maxs, ufmtsh, dfmtsh; + + ufmtsh = AFMT_BYTESSHIFT(u->format); + dfmtsh = AFMT_BYTESSHIFT(u->dma.format); + maxs = (AFMT_ISSTEREO(u->dma.format | u->format)) ? 32 : 64; + while (samples > 0) { + scnt = samples; + if (scnt > maxs) + scnt = maxs; + conversion(buffer, u->format, tmp.b, u->dma.format, tmp.b, scnt); + dmabuf_copyin(&u->dma, tmp.b, scnt << dfmtsh); + buffer += scnt << ufmtsh; + samples -= scnt; + } +} + +static int usbin_prepare_desc(struct usbin *u, struct urb *urb) +{ + unsigned int i, maxsize, offs; + + maxsize = (u->freqmax + 0x3fff) >> (14 - AFMT_BYTESSHIFT(u->format)); + //printk(KERN_DEBUG "usbin_prepare_desc: maxsize %d freq 0x%x format 0x%x\n", maxsize, u->freqn, u->format); + for (i = offs = 0; i < DESCFRAMES; i++, offs += maxsize) { + urb->iso_frame_desc[i].length = maxsize; + urb->iso_frame_desc[i].offset = offs; + } + urb->interval = 1; + return 0; +} + +/* + * return value: 0 if descriptor should be restarted, -1 otherwise + * convert sample format on the fly if necessary + */ +static int usbin_retire_desc(struct usbin *u, struct urb *urb) +{ + unsigned int i, ufmtsh, dfmtsh, err = 0, cnt, scnt, dmafree; + unsigned char *cp; + + ufmtsh = AFMT_BYTESSHIFT(u->format); + dfmtsh = AFMT_BYTESSHIFT(u->dma.format); + for (i = 0; i < DESCFRAMES; i++) { + cp = ((unsigned char *)urb->transfer_buffer) + urb->iso_frame_desc[i].offset; + if (urb->iso_frame_desc[i].status) { + dprintk((KERN_DEBUG "usbin_retire_desc: frame %u status %d\n", i, urb->iso_frame_desc[i].status)); + continue; + } + scnt = urb->iso_frame_desc[i].actual_length >> ufmtsh; + if (!scnt) + continue; + cnt = scnt << dfmtsh; + if (!u->dma.mapped) { + dmafree = u->dma.dmasize - u->dma.count; + if (cnt > dmafree) { + scnt = dmafree >> dfmtsh; + cnt = scnt << dfmtsh; + err++; + } + } + u->dma.count += cnt; + if (u->format == u->dma.format) { + /* we do not need format conversion */ + dprintk((KERN_DEBUG "usbaudio: no sample format conversion\n")); + dmabuf_copyin(&u->dma, cp, cnt); + } else { + /* we need sampling format conversion */ + dprintk((KERN_DEBUG "usbaudio: sample format conversion %x != %x\n", u->format, u->dma.format)); + usbin_convert(u, cp, scnt); + } + } + if (err) + u->dma.error++; + if (u->dma.count >= (signed)u->dma.fragsize) + wake_up(&u->dma.wait); + return err ? -1 : 0; +} + +static void usbin_completed(struct urb *urb, struct pt_regs *regs) +{ + struct usb_audiodev *as = (struct usb_audiodev *)urb->context; + struct usbin *u = &as->usbin; + unsigned long flags; + unsigned int mask; + int suret = 0; + +#if 0 + printk(KERN_DEBUG "usbin_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); +#endif + if (urb == u->durb[0].urb) + mask = FLG_URB0RUNNING; + else if (urb == u->durb[1].urb) + mask = FLG_URB1RUNNING; + else { + mask = 0; + printk(KERN_ERR "usbin_completed: panic: unknown URB\n"); + } + urb->dev = as->state->usbdev; + spin_lock_irqsave(&as->lock, flags); + if (!usbin_retire_desc(u, urb) && + u->flags & FLG_RUNNING && + !usbin_prepare_desc(u, urb) && + (suret = usb_submit_urb(urb, GFP_ATOMIC)) == 0) { + u->flags |= mask; + } else { + u->flags &= ~(mask | FLG_RUNNING); + wake_up(&u->dma.wait); + printk(KERN_DEBUG "usbin_completed: descriptor not restarted (usb_submit_urb: %d)\n", suret); + } + spin_unlock_irqrestore(&as->lock, flags); +} + +/* + * we output sync data + */ +static int usbin_sync_prepare_desc(struct usbin *u, struct urb *urb) +{ + unsigned char *cp = urb->transfer_buffer; + unsigned int i, offs; + + for (i = offs = 0; i < SYNCFRAMES; i++, offs += 3, cp += 3) { + urb->iso_frame_desc[i].length = 3; + urb->iso_frame_desc[i].offset = offs; + cp[0] = u->freqn; + cp[1] = u->freqn >> 8; + cp[2] = u->freqn >> 16; + } + urb->interval = 1; + return 0; +} + +/* + * return value: 0 if descriptor should be restarted, -1 otherwise + */ +static int usbin_sync_retire_desc(struct usbin *u, struct urb *urb) +{ + unsigned int i; + + for (i = 0; i < SYNCFRAMES; i++) + if (urb->iso_frame_desc[0].status) + dprintk((KERN_DEBUG "usbin_sync_retire_desc: frame %u status %d\n", i, urb->iso_frame_desc[i].status)); + return 0; +} + +static void usbin_sync_completed(struct urb *urb, struct pt_regs *regs) +{ + struct usb_audiodev *as = (struct usb_audiodev *)urb->context; + struct usbin *u = &as->usbin; + unsigned long flags; + unsigned int mask; + int suret = 0; + +#if 0 + printk(KERN_DEBUG "usbin_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); +#endif + if (urb == u->surb[0].urb) + mask = FLG_SYNC0RUNNING; + else if (urb == u->surb[1].urb) + mask = FLG_SYNC1RUNNING; + else { + mask = 0; + printk(KERN_ERR "usbin_sync_completed: panic: unknown URB\n"); + } + urb->dev = as->state->usbdev; + spin_lock_irqsave(&as->lock, flags); + if (!usbin_sync_retire_desc(u, urb) && + u->flags & FLG_RUNNING && + !usbin_sync_prepare_desc(u, urb) && + (suret = usb_submit_urb(urb, GFP_ATOMIC)) == 0) { + u->flags |= mask; + } else { + u->flags &= ~(mask | FLG_RUNNING); + wake_up(&u->dma.wait); + dprintk((KERN_DEBUG "usbin_sync_completed: descriptor not restarted (usb_submit_urb: %d)\n", suret)); + } + spin_unlock_irqrestore(&as->lock, flags); +} + +static int usbin_start(struct usb_audiodev *as) +{ + struct usb_device *dev = as->state->usbdev; + struct usbin *u = &as->usbin; + struct urb *urb; + unsigned long flags; + unsigned int maxsze, bufsz; + +#if 0 + printk(KERN_DEBUG "usbin_start: device %d ufmt 0x%08x dfmt 0x%08x srate %d\n", + dev->devnum, u->format, u->dma.format, u->dma.srate); +#endif + /* allocate USB storage if not already done */ + spin_lock_irqsave(&as->lock, flags); + if (!(u->flags & FLG_CONNECTED)) { + spin_unlock_irqrestore(&as->lock, flags); + return -EIO; + } + if (!(u->flags & FLG_RUNNING)) { + spin_unlock_irqrestore(&as->lock, flags); + u->freqn = ((u->dma.srate << 11) + 62) / 125; /* this will overflow at approx 2MSPS */ + u->freqmax = u->freqn + (u->freqn >> 2); + u->phase = 0; + maxsze = (u->freqmax + 0x3fff) >> (14 - AFMT_BYTESSHIFT(u->format)); + bufsz = DESCFRAMES * maxsze; + kfree(u->durb[0].urb->transfer_buffer); + u->durb[0].urb->transfer_buffer = kmalloc(bufsz, GFP_KERNEL); + u->durb[0].urb->transfer_buffer_length = bufsz; + kfree(u->durb[1].urb->transfer_buffer); + u->durb[1].urb->transfer_buffer = kmalloc(bufsz, GFP_KERNEL); + u->durb[1].urb->transfer_buffer_length = bufsz; + if (u->syncpipe) { + kfree(u->surb[0].urb->transfer_buffer); + u->surb[0].urb->transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL); + u->surb[0].urb->transfer_buffer_length = 3*SYNCFRAMES; + kfree(u->surb[1].urb->transfer_buffer); + u->surb[1].urb->transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL); + u->surb[1].urb->transfer_buffer_length = 3*SYNCFRAMES; + } + if (!u->durb[0].urb->transfer_buffer || !u->durb[1].urb->transfer_buffer || + (u->syncpipe && (!u->surb[0].urb->transfer_buffer || !u->surb[1].urb->transfer_buffer))) { + printk(KERN_ERR "usbaudio: cannot start playback device %d\n", dev->devnum); + return 0; + } + spin_lock_irqsave(&as->lock, flags); + } + if (u->dma.count >= u->dma.dmasize && !u->dma.mapped) { + spin_unlock_irqrestore(&as->lock, flags); + return 0; + } + u->flags |= FLG_RUNNING; + if (!(u->flags & FLG_URB0RUNNING)) { + urb = u->durb[0].urb; + urb->dev = dev; + urb->pipe = u->datapipe; + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = DESCFRAMES; + urb->context = as; + urb->complete = usbin_completed; + if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) + u->flags |= FLG_URB0RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + if (u->flags & FLG_RUNNING && !(u->flags & FLG_URB1RUNNING)) { + urb = u->durb[1].urb; + urb->dev = dev; + urb->pipe = u->datapipe; + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = DESCFRAMES; + urb->context = as; + urb->complete = usbin_completed; + if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) + u->flags |= FLG_URB1RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + if (u->syncpipe) { + if (u->flags & FLG_RUNNING && !(u->flags & FLG_SYNC0RUNNING)) { + urb = u->surb[0].urb; + urb->dev = dev; + urb->pipe = u->syncpipe; + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = SYNCFRAMES; + urb->context = as; + urb->complete = usbin_sync_completed; + /* stride: u->syncinterval */ + if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) + u->flags |= FLG_SYNC0RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + if (u->flags & FLG_RUNNING && !(u->flags & FLG_SYNC1RUNNING)) { + urb = u->surb[1].urb; + urb->dev = dev; + urb->pipe = u->syncpipe; + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = SYNCFRAMES; + urb->context = as; + urb->complete = usbin_sync_completed; + /* stride: u->syncinterval */ + if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) + u->flags |= FLG_SYNC1RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + } + spin_unlock_irqrestore(&as->lock, flags); + return 0; +} + +static void usbout_stop(struct usb_audiodev *as) +{ + struct usbout *u = &as->usbout; + unsigned long flags; + unsigned int i, notkilled = 1; + + spin_lock_irqsave(&as->lock, flags); + u->flags &= ~FLG_RUNNING; + i = u->flags; + spin_unlock_irqrestore(&as->lock, flags); + while (i & (FLG_URB0RUNNING|FLG_URB1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) { + if (notkilled) + schedule_timeout_interruptible(1); + else + schedule_timeout_uninterruptible(1); + spin_lock_irqsave(&as->lock, flags); + i = u->flags; + spin_unlock_irqrestore(&as->lock, flags); + if (notkilled && signal_pending(current)) { + if (i & FLG_URB0RUNNING) + usb_kill_urb(u->durb[0].urb); + if (i & FLG_URB1RUNNING) + usb_kill_urb(u->durb[1].urb); + if (i & FLG_SYNC0RUNNING) + usb_kill_urb(u->surb[0].urb); + if (i & FLG_SYNC1RUNNING) + usb_kill_urb(u->surb[1].urb); + notkilled = 0; + } + } + set_current_state(TASK_RUNNING); + kfree(u->durb[0].urb->transfer_buffer); + kfree(u->durb[1].urb->transfer_buffer); + kfree(u->surb[0].urb->transfer_buffer); + kfree(u->surb[1].urb->transfer_buffer); + u->durb[0].urb->transfer_buffer = u->durb[1].urb->transfer_buffer = + u->surb[0].urb->transfer_buffer = u->surb[1].urb->transfer_buffer = NULL; +} + +static inline void usbout_release(struct usb_audiodev *as) +{ + usbout_stop(as); +} + +static void usbout_disc(struct usb_audiodev *as) +{ + struct usbout *u = &as->usbout; + unsigned long flags; + + spin_lock_irqsave(&as->lock, flags); + u->flags &= ~(FLG_RUNNING | FLG_CONNECTED); + spin_unlock_irqrestore(&as->lock, flags); + usbout_stop(as); +} + +static void usbout_convert(struct usbout *u, unsigned char *buffer, unsigned int samples) +{ + union { + __s16 s[64]; + unsigned char b[0]; + } tmp; + unsigned int scnt, maxs, ufmtsh, dfmtsh; + + ufmtsh = AFMT_BYTESSHIFT(u->format); + dfmtsh = AFMT_BYTESSHIFT(u->dma.format); + maxs = (AFMT_ISSTEREO(u->dma.format | u->format)) ? 32 : 64; + while (samples > 0) { + scnt = samples; + if (scnt > maxs) + scnt = maxs; + dmabuf_copyout(&u->dma, tmp.b, scnt << dfmtsh); + conversion(tmp.b, u->dma.format, buffer, u->format, tmp.b, scnt); + buffer += scnt << ufmtsh; + samples -= scnt; + } +} + +static int usbout_prepare_desc(struct usbout *u, struct urb *urb) +{ + unsigned int i, ufmtsh, dfmtsh, err = 0, cnt, scnt, offs; + unsigned char *cp = urb->transfer_buffer; + + ufmtsh = AFMT_BYTESSHIFT(u->format); + dfmtsh = AFMT_BYTESSHIFT(u->dma.format); + for (i = offs = 0; i < DESCFRAMES; i++) { + urb->iso_frame_desc[i].offset = offs; + u->phase = (u->phase & 0x3fff) + u->freqm; + scnt = u->phase >> 14; + if (!scnt) { + urb->iso_frame_desc[i].length = 0; + continue; + } + cnt = scnt << dfmtsh; + if (!u->dma.mapped) { + if (cnt > u->dma.count) { + scnt = u->dma.count >> dfmtsh; + cnt = scnt << dfmtsh; + err++; + } + u->dma.count -= cnt; + } else + u->dma.count += cnt; + if (u->format == u->dma.format) { + /* we do not need format conversion */ + dmabuf_copyout(&u->dma, cp, cnt); + } else { + /* we need sampling format conversion */ + usbout_convert(u, cp, scnt); + } + cnt = scnt << ufmtsh; + urb->iso_frame_desc[i].length = cnt; + offs += cnt; + cp += cnt; + } + urb->interval = 1; + if (err) + u->dma.error++; + if (u->dma.mapped) { + if (u->dma.count >= (signed)u->dma.fragsize) + wake_up(&u->dma.wait); + } else { + if ((signed)u->dma.dmasize >= u->dma.count + (signed)u->dma.fragsize) + wake_up(&u->dma.wait); + } + return err ? -1 : 0; +} + +/* + * return value: 0 if descriptor should be restarted, -1 otherwise + */ +static int usbout_retire_desc(struct usbout *u, struct urb *urb) +{ + unsigned int i; + + for (i = 0; i < DESCFRAMES; i++) { + if (urb->iso_frame_desc[i].status) { + dprintk((KERN_DEBUG "usbout_retire_desc: frame %u status %d\n", i, urb->iso_frame_desc[i].status)); + continue; + } + } + return 0; +} + +static void usbout_completed(struct urb *urb, struct pt_regs *regs) +{ + struct usb_audiodev *as = (struct usb_audiodev *)urb->context; + struct usbout *u = &as->usbout; + unsigned long flags; + unsigned int mask; + int suret = 0; + +#if 0 + printk(KERN_DEBUG "usbout_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); +#endif + if (urb == u->durb[0].urb) + mask = FLG_URB0RUNNING; + else if (urb == u->durb[1].urb) + mask = FLG_URB1RUNNING; + else { + mask = 0; + printk(KERN_ERR "usbout_completed: panic: unknown URB\n"); + } + urb->dev = as->state->usbdev; + spin_lock_irqsave(&as->lock, flags); + if (!usbout_retire_desc(u, urb) && + u->flags & FLG_RUNNING && + !usbout_prepare_desc(u, urb) && + (suret = usb_submit_urb(urb, GFP_ATOMIC)) == 0) { + u->flags |= mask; + } else { + u->flags &= ~(mask | FLG_RUNNING); + wake_up(&u->dma.wait); + dprintk((KERN_DEBUG "usbout_completed: descriptor not restarted (usb_submit_urb: %d)\n", suret)); + } + spin_unlock_irqrestore(&as->lock, flags); +} + +static int usbout_sync_prepare_desc(struct usbout *u, struct urb *urb) +{ + unsigned int i, offs; + + for (i = offs = 0; i < SYNCFRAMES; i++, offs += 3) { + urb->iso_frame_desc[i].length = 3; + urb->iso_frame_desc[i].offset = offs; + } + urb->interval = 1; + return 0; +} + +/* + * return value: 0 if descriptor should be restarted, -1 otherwise + */ +static int usbout_sync_retire_desc(struct usbout *u, struct urb *urb) +{ + unsigned char *cp = urb->transfer_buffer; + unsigned int f, i; + + for (i = 0; i < SYNCFRAMES; i++, cp += 3) { + if (urb->iso_frame_desc[i].status) { + dprintk((KERN_DEBUG "usbout_sync_retire_desc: frame %u status %d\n", i, urb->iso_frame_desc[i].status)); + continue; + } + if (urb->iso_frame_desc[i].actual_length < 3) { + dprintk((KERN_DEBUG "usbout_sync_retire_desc: frame %u length %d\n", i, urb->iso_frame_desc[i].actual_length)); + continue; + } + f = cp[0] | (cp[1] << 8) | (cp[2] << 16); + if (abs(f - u->freqn) > (u->freqn >> 3) || f > u->freqmax) { + printk(KERN_WARNING "usbout_sync_retire_desc: requested frequency %u (nominal %u) out of range!\n", f, u->freqn); + continue; + } + u->freqm = f; + } + return 0; +} + +static void usbout_sync_completed(struct urb *urb, struct pt_regs *regs) +{ + struct usb_audiodev *as = (struct usb_audiodev *)urb->context; + struct usbout *u = &as->usbout; + unsigned long flags; + unsigned int mask; + int suret = 0; + +#if 0 + printk(KERN_DEBUG "usbout_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); +#endif + if (urb == u->surb[0].urb) + mask = FLG_SYNC0RUNNING; + else if (urb == u->surb[1].urb) + mask = FLG_SYNC1RUNNING; + else { + mask = 0; + printk(KERN_ERR "usbout_sync_completed: panic: unknown URB\n"); + } + urb->dev = as->state->usbdev; + spin_lock_irqsave(&as->lock, flags); + if (!usbout_sync_retire_desc(u, urb) && + u->flags & FLG_RUNNING && + !usbout_sync_prepare_desc(u, urb) && + (suret = usb_submit_urb(urb, GFP_ATOMIC)) == 0) { + u->flags |= mask; + } else { + u->flags &= ~(mask | FLG_RUNNING); + wake_up(&u->dma.wait); + dprintk((KERN_DEBUG "usbout_sync_completed: descriptor not restarted (usb_submit_urb: %d)\n", suret)); + } + spin_unlock_irqrestore(&as->lock, flags); +} + +static int usbout_start(struct usb_audiodev *as) +{ + struct usb_device *dev = as->state->usbdev; + struct usbout *u = &as->usbout; + struct urb *urb; + unsigned long flags; + unsigned int maxsze, bufsz; + +#if 0 + printk(KERN_DEBUG "usbout_start: device %d ufmt 0x%08x dfmt 0x%08x srate %d\n", + dev->devnum, u->format, u->dma.format, u->dma.srate); +#endif + /* allocate USB storage if not already done */ + spin_lock_irqsave(&as->lock, flags); + if (!(u->flags & FLG_CONNECTED)) { + spin_unlock_irqrestore(&as->lock, flags); + return -EIO; + } + if (!(u->flags & FLG_RUNNING)) { + spin_unlock_irqrestore(&as->lock, flags); + u->freqn = u->freqm = ((u->dma.srate << 11) + 62) / 125; /* this will overflow at approx 2MSPS */ + u->freqmax = u->freqn + (u->freqn >> 2); + u->phase = 0; + maxsze = (u->freqmax + 0x3fff) >> (14 - AFMT_BYTESSHIFT(u->format)); + bufsz = DESCFRAMES * maxsze; + kfree(u->durb[0].urb->transfer_buffer); + u->durb[0].urb->transfer_buffer = kmalloc(bufsz, GFP_KERNEL); + u->durb[0].urb->transfer_buffer_length = bufsz; + kfree(u->durb[1].urb->transfer_buffer); + u->durb[1].urb->transfer_buffer = kmalloc(bufsz, GFP_KERNEL); + u->durb[1].urb->transfer_buffer_length = bufsz; + if (u->syncpipe) { + kfree(u->surb[0].urb->transfer_buffer); + u->surb[0].urb->transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL); + u->surb[0].urb->transfer_buffer_length = 3*SYNCFRAMES; + kfree(u->surb[1].urb->transfer_buffer); + u->surb[1].urb->transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL); + u->surb[1].urb->transfer_buffer_length = 3*SYNCFRAMES; + } + if (!u->durb[0].urb->transfer_buffer || !u->durb[1].urb->transfer_buffer || + (u->syncpipe && (!u->surb[0].urb->transfer_buffer || !u->surb[1].urb->transfer_buffer))) { + printk(KERN_ERR "usbaudio: cannot start playback device %d\n", dev->devnum); + return 0; + } + spin_lock_irqsave(&as->lock, flags); + } + if (u->dma.count <= 0 && !u->dma.mapped) { + spin_unlock_irqrestore(&as->lock, flags); + return 0; + } + u->flags |= FLG_RUNNING; + if (!(u->flags & FLG_URB0RUNNING)) { + urb = u->durb[0].urb; + urb->dev = dev; + urb->pipe = u->datapipe; + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = DESCFRAMES; + urb->context = as; + urb->complete = usbout_completed; + if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC)) + u->flags |= FLG_URB0RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + if (u->flags & FLG_RUNNING && !(u->flags & FLG_URB1RUNNING)) { + urb = u->durb[1].urb; + urb->dev = dev; + urb->pipe = u->datapipe; + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = DESCFRAMES; + urb->context = as; + urb->complete = usbout_completed; + if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC)) + u->flags |= FLG_URB1RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + if (u->syncpipe) { + if (u->flags & FLG_RUNNING && !(u->flags & FLG_SYNC0RUNNING)) { + urb = u->surb[0].urb; + urb->dev = dev; + urb->pipe = u->syncpipe; + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = SYNCFRAMES; + urb->context = as; + urb->complete = usbout_sync_completed; + /* stride: u->syncinterval */ + if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC)) + u->flags |= FLG_SYNC0RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + if (u->flags & FLG_RUNNING && !(u->flags & FLG_SYNC1RUNNING)) { + urb = u->surb[1].urb; + urb->dev = dev; + urb->pipe = u->syncpipe; + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = SYNCFRAMES; + urb->context = as; + urb->complete = usbout_sync_completed; + /* stride: u->syncinterval */ + if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC)) + u->flags |= FLG_SYNC1RUNNING; + else + u->flags &= ~FLG_RUNNING; + } + } + spin_unlock_irqrestore(&as->lock, flags); + return 0; +} + +/* --------------------------------------------------------------------- */ + +static unsigned int format_goodness(struct audioformat *afp, unsigned int fmt, unsigned int srate) +{ + unsigned int g = 0; + + if (srate < afp->sratelo) + g += afp->sratelo - srate; + if (srate > afp->sratehi) + g += srate - afp->sratehi; + if (AFMT_ISSTEREO(afp->format) && !AFMT_ISSTEREO(fmt)) + g += 0x100000; + if (!AFMT_ISSTEREO(afp->format) && AFMT_ISSTEREO(fmt)) + g += 0x400000; + if (AFMT_IS16BIT(afp->format) && !AFMT_IS16BIT(fmt)) + g += 0x100000; + if (!AFMT_IS16BIT(afp->format) && AFMT_IS16BIT(fmt)) + g += 0x400000; + return g; +} + +static int find_format(struct audioformat *afp, unsigned int nr, unsigned int fmt, unsigned int srate) +{ + unsigned int i, g, gb = ~0; + int j = -1; /* default to failure */ + + /* find "best" format (according to format_goodness) */ + for (i = 0; i < nr; i++) { + g = format_goodness(&afp[i], fmt, srate); + if (g >= gb) + continue; + j = i; + gb = g; + } + return j; +} + +static int set_format_in(struct usb_audiodev *as) +{ + struct usb_device *dev = as->state->usbdev; + struct usb_host_interface *alts; + struct usb_interface *iface; + struct usbin *u = &as->usbin; + struct dmabuf *d = &u->dma; + struct audioformat *fmt; + unsigned int ep; + unsigned char data[3]; + int fmtnr, ret; + + iface = usb_ifnum_to_if(dev, u->interface); + if (!iface) + return 0; + + fmtnr = find_format(as->fmtin, as->numfmtin, d->format, d->srate); + if (fmtnr < 0) { + printk(KERN_ERR "usbaudio: set_format_in(): failed to find desired format/speed combination.\n"); + return -1; + } + + fmt = as->fmtin + fmtnr; + alts = usb_altnum_to_altsetting(iface, fmt->altsetting); + u->format = fmt->format; + u->datapipe = usb_rcvisocpipe(dev, alts->endpoint[0].desc.bEndpointAddress & 0xf); + u->syncpipe = u->syncinterval = 0; + if ((alts->endpoint[0].desc.bmAttributes & 0x0c) == 0x08) { + if (alts->desc.bNumEndpoints < 2 || + alts->endpoint[1].desc.bmAttributes != 0x01 || + alts->endpoint[1].desc.bSynchAddress != 0 || + alts->endpoint[1].desc.bEndpointAddress != (alts->endpoint[0].desc.bSynchAddress & 0x7f)) { + printk(KERN_WARNING "usbaudio: device %d interface %d altsetting %d claims adaptive in " + "but has invalid synch pipe; treating as asynchronous in\n", + dev->devnum, u->interface, fmt->altsetting); + } else { + u->syncpipe = usb_sndisocpipe(dev, alts->endpoint[1].desc.bEndpointAddress & 0xf); + u->syncinterval = alts->endpoint[1].desc.bRefresh; + } + } + if (d->srate < fmt->sratelo) + d->srate = fmt->sratelo; + if (d->srate > fmt->sratehi) + d->srate = fmt->sratehi; + dprintk((KERN_DEBUG "usbaudio: set_format_in: usb_set_interface %u %u\n", + u->interface, fmt->altsetting)); + if (usb_set_interface(dev, alts->desc.bInterfaceNumber, fmt->altsetting) < 0) { + printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n", + dev->devnum, u->interface, fmt->altsetting); + return -1; + } + if (fmt->sratelo == fmt->sratehi) + return 0; + ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN); + /* if endpoint has pitch control, enable it */ + if (fmt->attributes & 0x02) { + data[0] = 1; + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n", + ret, dev->devnum, u->interface, ep, d->srate); + return -1; + } + } + /* if endpoint has sampling rate control, set it */ + if (fmt->attributes & 0x01) { + data[0] = d->srate; + data[1] = d->srate >> 8; + data[2] = d->srate >> 16; + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to set input sampling frequency device %d interface %u endpoint 0x%x to %u\n", + ret, dev->devnum, u->interface, ep, d->srate); + return -1; + } + if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to get input sampling frequency device %d interface %u endpoint 0x%x\n", + ret, dev->devnum, u->interface, ep); + return -1; + } + dprintk((KERN_DEBUG "usbaudio: set_format_in: device %d interface %d altsetting %d srate req: %u real %u\n", + dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16))); + d->srate = data[0] | (data[1] << 8) | (data[2] << 16); + } + dprintk((KERN_DEBUG "usbaudio: set_format_in: USB format 0x%x, DMA format 0x%x srate %u\n", u->format, d->format, d->srate)); + return 0; +} + +static int set_format_out(struct usb_audiodev *as) +{ + struct usb_device *dev = as->state->usbdev; + struct usb_host_interface *alts; + struct usb_interface *iface; + struct usbout *u = &as->usbout; + struct dmabuf *d = &u->dma; + struct audioformat *fmt; + unsigned int ep; + unsigned char data[3]; + int fmtnr, ret; + + iface = usb_ifnum_to_if(dev, u->interface); + if (!iface) + return 0; + + fmtnr = find_format(as->fmtout, as->numfmtout, d->format, d->srate); + if (fmtnr < 0) { + printk(KERN_ERR "usbaudio: set_format_out(): failed to find desired format/speed combination.\n"); + return -1; + } + + fmt = as->fmtout + fmtnr; + u->format = fmt->format; + alts = usb_altnum_to_altsetting(iface, fmt->altsetting); + u->datapipe = usb_sndisocpipe(dev, alts->endpoint[0].desc.bEndpointAddress & 0xf); + u->syncpipe = u->syncinterval = 0; + if ((alts->endpoint[0].desc.bmAttributes & 0x0c) == 0x04) { +#if 0 + printk(KERN_DEBUG "bNumEndpoints 0x%02x endpoint[1].bmAttributes 0x%02x\n" + KERN_DEBUG "endpoint[1].bSynchAddress 0x%02x endpoint[1].bEndpointAddress 0x%02x\n" + KERN_DEBUG "endpoint[0].bSynchAddress 0x%02x\n", alts->bNumEndpoints, + alts->endpoint[1].bmAttributes, alts->endpoint[1].bSynchAddress, + alts->endpoint[1].bEndpointAddress, alts->endpoint[0].bSynchAddress); +#endif + if (alts->desc.bNumEndpoints < 2 || + alts->endpoint[1].desc.bmAttributes != 0x01 || + alts->endpoint[1].desc.bSynchAddress != 0 || + alts->endpoint[1].desc.bEndpointAddress != (alts->endpoint[0].desc.bSynchAddress | 0x80)) { + printk(KERN_WARNING "usbaudio: device %d interface %d altsetting %d claims asynch out " + "but has invalid synch pipe; treating as adaptive out\n", + dev->devnum, u->interface, fmt->altsetting); + } else { + u->syncpipe = usb_rcvisocpipe(dev, alts->endpoint[1].desc.bEndpointAddress & 0xf); + u->syncinterval = alts->endpoint[1].desc.bRefresh; + } + } + if (d->srate < fmt->sratelo) + d->srate = fmt->sratelo; + if (d->srate > fmt->sratehi) + d->srate = fmt->sratehi; + dprintk((KERN_DEBUG "usbaudio: set_format_out: usb_set_interface %u %u\n", + u->interface, fmt->altsetting)); + if (usb_set_interface(dev, u->interface, fmt->altsetting) < 0) { + printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n", + dev->devnum, u->interface, fmt->altsetting); + return -1; + } + if (fmt->sratelo == fmt->sratehi) + return 0; + ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN); + /* if endpoint has pitch control, enable it */ + if (fmt->attributes & 0x02) { + data[0] = 1; + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n", + ret, dev->devnum, u->interface, ep, d->srate); + return -1; + } + } + /* if endpoint has sampling rate control, set it */ + if (fmt->attributes & 0x01) { + data[0] = d->srate; + data[1] = d->srate >> 8; + data[2] = d->srate >> 16; + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to set output sampling frequency device %d interface %u endpoint 0x%x to %u\n", + ret, dev->devnum, u->interface, ep, d->srate); + return -1; + } + if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to get output sampling frequency device %d interface %u endpoint 0x%x\n", + ret, dev->devnum, u->interface, ep); + return -1; + } + dprintk((KERN_DEBUG "usbaudio: set_format_out: device %d interface %d altsetting %d srate req: %u real %u\n", + dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16))); + d->srate = data[0] | (data[1] << 8) | (data[2] << 16); + } + dprintk((KERN_DEBUG "usbaudio: set_format_out: USB format 0x%x, DMA format 0x%x srate %u\n", u->format, d->format, d->srate)); + return 0; +} + +static int set_format(struct usb_audiodev *s, unsigned int fmode, unsigned int fmt, unsigned int srate) +{ + int ret1 = 0, ret2 = 0; + + if (!(fmode & (FMODE_READ|FMODE_WRITE))) + return -EINVAL; + if (fmode & FMODE_READ) { + usbin_stop(s); + s->usbin.dma.ready = 0; + if (fmt == AFMT_QUERY) + fmt = s->usbin.dma.format; + else + s->usbin.dma.format = fmt; + if (!srate) + srate = s->usbin.dma.srate; + else + s->usbin.dma.srate = srate; + } + if (fmode & FMODE_WRITE) { + usbout_stop(s); + s->usbout.dma.ready = 0; + if (fmt == AFMT_QUERY) + fmt = s->usbout.dma.format; + else + s->usbout.dma.format = fmt; + if (!srate) + srate = s->usbout.dma.srate; + else + s->usbout.dma.srate = srate; + } + if (fmode & FMODE_READ) + ret1 = set_format_in(s); + if (fmode & FMODE_WRITE) + ret2 = set_format_out(s); + return ret1 ? ret1 : ret2; +} + +/* --------------------------------------------------------------------- */ + +static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value) +{ + struct usb_device *dev = ms->state->usbdev; + unsigned char data[2]; + struct mixerchannel *ch; + int v1, v2, v3; + + if (mixch >= ms->numch) + return -1; + ch = &ms->ch[mixch]; + v3 = ch->maxval - ch->minval; + v1 = value & 0xff; + v2 = (value >> 8) & 0xff; + if (v1 > 100) + v1 = 100; + if (v2 > 100) + v2 = 100; + if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) + v2 = v1; + ch->value = v1 | (v2 << 8); + v1 = (v1 * v3) / 100 + ch->minval; + v2 = (v2 * v3) / 100 + ch->minval; + switch (ch->selector) { + case 0: /* mixer unit request */ + data[0] = v1; + data[1] = v1 >> 8; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->chnum << 8) | 1, ms->iface | (ch->unitid << 8), data, 2, 1000) < 0) + goto err; + if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) + return 0; + data[0] = v2; + data[1] = v2 >> 8; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)), + ms->iface | (ch->unitid << 8), data, 2, 1000) < 0) + goto err; + return 0; + + /* various feature unit controls */ + case VOLUME_CONTROL: + data[0] = v1; + data[1] = v1 >> 8; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 2, 1000) < 0) + goto err; + if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) + return 0; + data[0] = v2; + data[1] = v2 >> 8; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 2, 1000) < 0) + goto err; + return 0; + + case BASS_CONTROL: + case MID_CONTROL: + case TREBLE_CONTROL: + data[0] = v1 >> 8; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 1, 1000) < 0) + goto err; + if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) + return 0; + data[0] = v2 >> 8; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 1, 1000) < 0) + goto err; + return 0; + + default: + return -1; + } + return 0; + + err: + printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n", + dev->devnum, ms->iface, ch->unitid, ch->chnum, ch->selector); + return -1; +} + +static int get_rec_src(struct usb_mixerdev *ms) +{ + struct usb_device *dev = ms->state->usbdev; + unsigned int mask = 0, retmask = 0; + unsigned int i, j; + unsigned char buf; + int err = 0; + + for (i = 0; i < ms->numch; i++) { + if (!ms->ch[i].slctunitid || (mask & (1 << i))) + continue; + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + 0, ms->iface | (ms->ch[i].slctunitid << 8), &buf, 1, 1000) < 0) { + err = -EIO; + printk(KERN_ERR "usbaudio: selector read request device %u if %u unit %u failed\n", + dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff); + continue; + } + for (j = i; j < ms->numch; j++) { + if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff) + continue; + mask |= 1 << j; + if (buf == (ms->ch[j].slctunitid >> 8)) + retmask |= 1 << ms->ch[j].osschannel; + } + } + if (err) + return -EIO; + return retmask; +} + +static int set_rec_src(struct usb_mixerdev *ms, int srcmask) +{ + struct usb_device *dev = ms->state->usbdev; + unsigned int mask = 0, smask, bmask; + unsigned int i, j; + unsigned char buf; + int err = 0; + + for (i = 0; i < ms->numch; i++) { + if (!ms->ch[i].slctunitid || (mask & (1 << i))) + continue; + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + 0, ms->iface | (ms->ch[i].slctunitid << 8), &buf, 1, 1000) < 0) { + err = -EIO; + printk(KERN_ERR "usbaudio: selector read request device %u if %u unit %u failed\n", + dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff); + continue; + } + /* first generate smask */ + smask = bmask = 0; + for (j = i; j < ms->numch; j++) { + if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff) + continue; + smask |= 1 << ms->ch[j].osschannel; + if (buf == (ms->ch[j].slctunitid >> 8)) + bmask |= 1 << ms->ch[j].osschannel; + mask |= 1 << j; + } + /* check for multiple set sources */ + j = hweight32(srcmask & smask); + if (j == 0) + continue; + if (j > 1) + srcmask &= ~bmask; + for (j = i; j < ms->numch; j++) { + if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff) + continue; + if (!(srcmask & (1 << ms->ch[j].osschannel))) + continue; + buf = ms->ch[j].slctunitid >> 8; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + 0, ms->iface | (ms->ch[j].slctunitid << 8), &buf, 1, 1000) < 0) { + err = -EIO; + printk(KERN_ERR "usbaudio: selector write request device %u if %u unit %u failed\n", + dev->devnum, ms->iface, ms->ch[j].slctunitid & 0xff); + continue; + } + } + } + return err ? -EIO : 0; +} + +/* --------------------------------------------------------------------- */ + +/* + * should be called with open_sem hold, so that no new processes + * look at the audio device to be destroyed + */ + +static void release(struct usb_audio_state *s) +{ + struct usb_audiodev *as; + struct usb_mixerdev *ms; + + s->count--; + if (s->count) { + up(&open_sem); + return; + } + up(&open_sem); + wake_up(&open_wait); + while (!list_empty(&s->audiolist)) { + as = list_entry(s->audiolist.next, struct usb_audiodev, list); + list_del(&as->list); + usbin_release(as); + usbout_release(as); + dmabuf_release(&as->usbin.dma); + dmabuf_release(&as->usbout.dma); + usb_free_urb(as->usbin.durb[0].urb); + usb_free_urb(as->usbin.durb[1].urb); + usb_free_urb(as->usbin.surb[0].urb); + usb_free_urb(as->usbin.surb[1].urb); + usb_free_urb(as->usbout.durb[0].urb); + usb_free_urb(as->usbout.durb[1].urb); + usb_free_urb(as->usbout.surb[0].urb); + usb_free_urb(as->usbout.surb[1].urb); + kfree(as); + } + while (!list_empty(&s->mixerlist)) { + ms = list_entry(s->mixerlist.next, struct usb_mixerdev, list); + list_del(&ms->list); + kfree(ms); + } + kfree(s); +} + +static inline int prog_dmabuf_in(struct usb_audiodev *as) +{ + usbin_stop(as); + return dmabuf_init(&as->usbin.dma); +} + +static inline int prog_dmabuf_out(struct usb_audiodev *as) +{ + usbout_stop(as); + return dmabuf_init(&as->usbout.dma); +} + +/* --------------------------------------------------------------------- */ + +static int usb_audio_open_mixdev(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct usb_mixerdev *ms; + struct usb_audio_state *s; + + down(&open_sem); + list_for_each_entry(s, &audiodevs, audiodev) { + list_for_each_entry(ms, &s->mixerlist, list) { + if (ms->dev_mixer == minor) + goto mixer_found; + } + } + up(&open_sem); + return -ENODEV; + + mixer_found: + if (!s->usbdev) { + up(&open_sem); + return -EIO; + } + file->private_data = ms; + s->count++; + + up(&open_sem); + return nonseekable_open(inode, file); +} + +static int usb_audio_release_mixdev(struct inode *inode, struct file *file) +{ + struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data; + struct usb_audio_state *s; + + lock_kernel(); + s = ms->state; + down(&open_sem); + release(s); + unlock_kernel(); + return 0; +} + +static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data; + int i, j, val; + int __user *user_arg = (int __user *)arg; + + if (!ms->state->usbdev) + return -ENODEV; + + if (cmd == SOUND_MIXER_INFO) { + mixer_info info; + + memset(&info, 0, sizeof(info)); + strncpy(info.id, "USB_AUDIO", sizeof(info.id)); + strncpy(info.name, "USB Audio Class Driver", sizeof(info.name)); + info.modify_counter = ms->modcnt; + if (copy_to_user((void __user *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == SOUND_OLD_MIXER_INFO) { + _old_mixer_info info; + + memset(&info, 0, sizeof(info)); + strncpy(info.id, "USB_AUDIO", sizeof(info.id)); + strncpy(info.name, "USB Audio Class Driver", sizeof(info.name)); + if (copy_to_user((void __user *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == OSS_GETVERSION) + return put_user(SOUND_VERSION, user_arg); + if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int)) + return -EINVAL; + if (_IOC_DIR(cmd) == _IOC_READ) { + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + val = get_rec_src(ms); + if (val < 0) + return val; + return put_user(val, user_arg); + + case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ + for (val = i = 0; i < ms->numch; i++) + val |= 1 << ms->ch[i].osschannel; + return put_user(val, user_arg); + + case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ + for (val = i = 0; i < ms->numch; i++) + if (ms->ch[i].slctunitid) + val |= 1 << ms->ch[i].osschannel; + return put_user(val, user_arg); + + case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ + for (val = i = 0; i < ms->numch; i++) + if (ms->ch[i].flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) + val |= 1 << ms->ch[i].osschannel; + return put_user(val, user_arg); + + case SOUND_MIXER_CAPS: + return put_user(SOUND_CAP_EXCL_INPUT, user_arg); + + default: + i = _IOC_NR(cmd); + if (i >= SOUND_MIXER_NRDEVICES) + return -EINVAL; + for (j = 0; j < ms->numch; j++) { + if (ms->ch[j].osschannel == i) { + return put_user(ms->ch[j].value, user_arg); + } + } + return -EINVAL; + } + } + if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) + return -EINVAL; + ms->modcnt++; + switch (_IOC_NR(cmd)) { + case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ + if (get_user(val, user_arg)) + return -EFAULT; + return set_rec_src(ms, val); + + default: + i = _IOC_NR(cmd); + if (i >= SOUND_MIXER_NRDEVICES) + return -EINVAL; + for (j = 0; j < ms->numch && ms->ch[j].osschannel != i; j++); + if (j >= ms->numch) + return -EINVAL; + if (get_user(val, user_arg)) + return -EFAULT; + if (wrmixer(ms, j, val)) + return -EIO; + return put_user(ms->ch[j].value, user_arg); + } +} + +static /*const*/ struct file_operations usb_mixer_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = usb_audio_ioctl_mixdev, + .open = usb_audio_open_mixdev, + .release = usb_audio_release_mixdev, +}; + +/* --------------------------------------------------------------------- */ + +static int drain_out(struct usb_audiodev *as, int nonblock) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int count, tmo; + + if (as->usbout.dma.mapped || !as->usbout.dma.ready) + return 0; + usbout_start(as); + add_wait_queue(&as->usbout.dma.wait, &wait); + for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); + spin_lock_irqsave(&as->lock, flags); + count = as->usbout.dma.count; + spin_unlock_irqrestore(&as->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (nonblock) { + remove_wait_queue(&as->usbout.dma.wait, &wait); + set_current_state(TASK_RUNNING); + return -EBUSY; + } + tmo = 3 * HZ * count / as->usbout.dma.srate; + tmo >>= AFMT_BYTESSHIFT(as->usbout.dma.format); + if (!schedule_timeout(tmo + 1)) { + printk(KERN_DEBUG "usbaudio: dma timed out??\n"); + break; + } + } + remove_wait_queue(&as->usbout.dma.wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +/* --------------------------------------------------------------------- */ + +static ssize_t usb_audio_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret = 0; + unsigned long flags; + unsigned int ptr; + int cnt, err; + + if (as->usbin.dma.mapped) + return -ENXIO; + if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as))) + return ret; + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + add_wait_queue(&as->usbin.dma.wait, &wait); + while (count > 0) { + spin_lock_irqsave(&as->lock, flags); + ptr = as->usbin.dma.rdptr; + cnt = as->usbin.dma.count; + /* set task state early to avoid wakeup races */ + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&as->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (usbin_start(as)) { + if (!ret) + ret = -ENODEV; + break; + } + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if ((err = dmabuf_copyout_user(&as->usbin.dma, ptr, buffer, cnt))) { + if (!ret) + ret = err; + break; + } + ptr += cnt; + if (ptr >= as->usbin.dma.dmasize) + ptr -= as->usbin.dma.dmasize; + spin_lock_irqsave(&as->lock, flags); + as->usbin.dma.rdptr = ptr; + as->usbin.dma.count -= cnt; + spin_unlock_irqrestore(&as->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&as->usbin.dma.wait, &wait); + return ret; +} + +static ssize_t usb_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret = 0; + unsigned long flags; + unsigned int ptr; + unsigned int start_thr; + int cnt, err; + + if (as->usbout.dma.mapped) + return -ENXIO; + if (!as->usbout.dma.ready && (ret = prog_dmabuf_out(as))) + return ret; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + start_thr = (as->usbout.dma.srate << AFMT_BYTESSHIFT(as->usbout.dma.format)) / (1000 / (3 * DESCFRAMES)); + add_wait_queue(&as->usbout.dma.wait, &wait); + while (count > 0) { +#if 0 + printk(KERN_DEBUG "usb_audio_write: count %u dma: count %u rdptr %u wrptr %u dmasize %u fragsize %u flags 0x%02x taskst 0x%lx\n", + count, as->usbout.dma.count, as->usbout.dma.rdptr, as->usbout.dma.wrptr, as->usbout.dma.dmasize, as->usbout.dma.fragsize, + as->usbout.flags, current->state); +#endif + spin_lock_irqsave(&as->lock, flags); + if (as->usbout.dma.count < 0) { + as->usbout.dma.count = 0; + as->usbout.dma.rdptr = as->usbout.dma.wrptr; + } + ptr = as->usbout.dma.wrptr; + cnt = as->usbout.dma.dmasize - as->usbout.dma.count; + /* set task state early to avoid wakeup races */ + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&as->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (usbout_start(as)) { + if (!ret) + ret = -ENODEV; + break; + } + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if ((err = dmabuf_copyin_user(&as->usbout.dma, ptr, buffer, cnt))) { + if (!ret) + ret = err; + break; + } + ptr += cnt; + if (ptr >= as->usbout.dma.dmasize) + ptr -= as->usbout.dma.dmasize; + spin_lock_irqsave(&as->lock, flags); + as->usbout.dma.wrptr = ptr; + as->usbout.dma.count += cnt; + spin_unlock_irqrestore(&as->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + if (as->usbout.dma.count >= start_thr && usbout_start(as)) { + if (!ret) + ret = -ENODEV; + break; + } + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&as->usbout.dma.wait, &wait); + return ret; +} + +/* Called without the kernel lock - fine */ +static unsigned int usb_audio_poll(struct file *file, struct poll_table_struct *wait) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + if (file->f_mode & FMODE_WRITE) { + if (!as->usbout.dma.ready) + prog_dmabuf_out(as); + poll_wait(file, &as->usbout.dma.wait, wait); + } + if (file->f_mode & FMODE_READ) { + if (!as->usbin.dma.ready) + prog_dmabuf_in(as); + poll_wait(file, &as->usbin.dma.wait, wait); + } + spin_lock_irqsave(&as->lock, flags); + if (file->f_mode & FMODE_READ) { + if (as->usbin.dma.count >= (signed)as->usbin.dma.fragsize) + mask |= POLLIN | POLLRDNORM; + } + if (file->f_mode & FMODE_WRITE) { + if (as->usbout.dma.mapped) { + if (as->usbout.dma.count >= (signed)as->usbout.dma.fragsize) + mask |= POLLOUT | POLLWRNORM; + } else { + if ((signed)as->usbout.dma.dmasize >= as->usbout.dma.count + (signed)as->usbout.dma.fragsize) + mask |= POLLOUT | POLLWRNORM; + } + } + spin_unlock_irqrestore(&as->lock, flags); + return mask; +} + +static int usb_audio_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + struct dmabuf *db; + int ret = -EINVAL; + + lock_kernel(); + if (vma->vm_flags & VM_WRITE) { + if ((ret = prog_dmabuf_out(as)) != 0) + goto out; + db = &as->usbout.dma; + } else if (vma->vm_flags & VM_READ) { + if ((ret = prog_dmabuf_in(as)) != 0) + goto out; + db = &as->usbin.dma; + } else + goto out; + + ret = -EINVAL; + if (vma->vm_pgoff != 0) + goto out; + + ret = dmabuf_mmap(vma, db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot); +out: + unlock_kernel(); + return ret; +} + +static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + struct usb_audio_state *s = as->state; + int __user *user_arg = (int __user *)arg; + unsigned long flags; + audio_buf_info abinfo; + count_info cinfo; + int val = 0; + int val2, mapped, ret; + + if (!s->usbdev) + return -EIO; + mapped = ((file->f_mode & FMODE_WRITE) && as->usbout.dma.mapped) || + ((file->f_mode & FMODE_READ) && as->usbin.dma.mapped); +#if 0 + if (arg) + get_user(val, (int *)arg); + printk(KERN_DEBUG "usbaudio: usb_audio_ioctl cmd=%x arg=%lx *arg=%d\n", cmd, arg, val) +#endif + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, user_arg); + + case SNDCTL_DSP_SYNC: + if (file->f_mode & FMODE_WRITE) + return drain_out(as, 0/*file->f_flags & O_NONBLOCK*/); + return 0; + + case SNDCTL_DSP_SETDUPLEX: + return 0; + + case SNDCTL_DSP_GETCAPS: + return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | + DSP_CAP_MMAP | DSP_CAP_BATCH, user_arg); + + case SNDCTL_DSP_RESET: + if (file->f_mode & FMODE_WRITE) { + usbout_stop(as); + as->usbout.dma.rdptr = as->usbout.dma.wrptr = as->usbout.dma.count = as->usbout.dma.total_bytes = 0; + } + if (file->f_mode & FMODE_READ) { + usbin_stop(as); + as->usbin.dma.rdptr = as->usbin.dma.wrptr = as->usbin.dma.count = as->usbin.dma.total_bytes = 0; + } + return 0; + + case SNDCTL_DSP_SPEED: + if (get_user(val, user_arg)) + return -EFAULT; + if (val >= 0) { + if (val < 4000) + val = 4000; + if (val > 100000) + val = 100000; + if (set_format(as, file->f_mode, AFMT_QUERY, val)) + return -EIO; + } + return put_user((file->f_mode & FMODE_READ) ? + as->usbin.dma.srate : as->usbout.dma.srate, + user_arg); + + case SNDCTL_DSP_STEREO: + if (get_user(val, user_arg)) + return -EFAULT; + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + if (val) + val2 |= AFMT_STEREO; + else + val2 &= ~AFMT_STEREO; + if (set_format(as, file->f_mode, val2, 0)) + return -EIO; + return 0; + + case SNDCTL_DSP_CHANNELS: + if (get_user(val, user_arg)) + return -EFAULT; + if (val != 0) { + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + if (val == 1) + val2 &= ~AFMT_STEREO; + else + val2 |= AFMT_STEREO; + if (set_format(as, file->f_mode, val2, 0)) + return -EIO; + } + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg); + + case SNDCTL_DSP_GETFMTS: /* Returns a mask */ + return put_user(AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE | + AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, user_arg); + + case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ + if (get_user(val, user_arg)) + return -EFAULT; + if (val != AFMT_QUERY) { + if (hweight32(val) != 1) + return -EINVAL; + if (!(val & (AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE | + AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE))) + return -EINVAL; + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + val |= val2 & AFMT_STEREO; + if (set_format(as, file->f_mode, val, 0)) + return -EIO; + } + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + return put_user(val2 & ~AFMT_STEREO, user_arg); + + case SNDCTL_DSP_POST: + return 0; + + case SNDCTL_DSP_GETTRIGGER: + val = 0; + if (file->f_mode & FMODE_READ && as->usbin.flags & FLG_RUNNING) + val |= PCM_ENABLE_INPUT; + if (file->f_mode & FMODE_WRITE && as->usbout.flags & FLG_RUNNING) + val |= PCM_ENABLE_OUTPUT; + return put_user(val, user_arg); + + case SNDCTL_DSP_SETTRIGGER: + if (get_user(val, user_arg)) + return -EFAULT; + if (file->f_mode & FMODE_READ) { + if (val & PCM_ENABLE_INPUT) { + if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as))) + return ret; + if (usbin_start(as)) + return -ENODEV; + } else + usbin_stop(as); + } + if (file->f_mode & FMODE_WRITE) { + if (val & PCM_ENABLE_OUTPUT) { + if (!as->usbout.dma.ready && (ret = prog_dmabuf_out(as))) + return ret; + if (usbout_start(as)) + return -ENODEV; + } else + usbout_stop(as); + } + return 0; + + case SNDCTL_DSP_GETOSPACE: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!(as->usbout.flags & FLG_RUNNING) && (val = prog_dmabuf_out(as)) != 0) + return val; + spin_lock_irqsave(&as->lock, flags); + abinfo.fragsize = as->usbout.dma.fragsize; + abinfo.bytes = as->usbout.dma.dmasize - as->usbout.dma.count; + abinfo.fragstotal = as->usbout.dma.numfrag; + abinfo.fragments = abinfo.bytes >> as->usbout.dma.fragshift; + spin_unlock_irqrestore(&as->lock, flags); + return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_GETISPACE: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + if (!(as->usbin.flags & FLG_RUNNING) && (val = prog_dmabuf_in(as)) != 0) + return val; + spin_lock_irqsave(&as->lock, flags); + abinfo.fragsize = as->usbin.dma.fragsize; + abinfo.bytes = as->usbin.dma.count; + abinfo.fragstotal = as->usbin.dma.numfrag; + abinfo.fragments = abinfo.bytes >> as->usbin.dma.fragshift; + spin_unlock_irqrestore(&as->lock, flags); + return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_NONBLOCK: + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_GETODELAY: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&as->lock, flags); + val = as->usbout.dma.count; + spin_unlock_irqrestore(&as->lock, flags); + return put_user(val, user_arg); + + case SNDCTL_DSP_GETIPTR: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + spin_lock_irqsave(&as->lock, flags); + cinfo.bytes = as->usbin.dma.total_bytes; + cinfo.blocks = as->usbin.dma.count >> as->usbin.dma.fragshift; + cinfo.ptr = as->usbin.dma.wrptr; + if (as->usbin.dma.mapped) + as->usbin.dma.count &= as->usbin.dma.fragsize-1; + spin_unlock_irqrestore(&as->lock, flags); + if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo))) + return -EFAULT; + return 0; + + case SNDCTL_DSP_GETOPTR: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + spin_lock_irqsave(&as->lock, flags); + cinfo.bytes = as->usbout.dma.total_bytes; + cinfo.blocks = as->usbout.dma.count >> as->usbout.dma.fragshift; + cinfo.ptr = as->usbout.dma.rdptr; + if (as->usbout.dma.mapped) + as->usbout.dma.count &= as->usbout.dma.fragsize-1; + spin_unlock_irqrestore(&as->lock, flags); + if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo))) + return -EFAULT; + return 0; + + case SNDCTL_DSP_GETBLKSIZE: + if (file->f_mode & FMODE_WRITE) { + if ((val = prog_dmabuf_out(as))) + return val; + return put_user(as->usbout.dma.fragsize, user_arg); + } + if ((val = prog_dmabuf_in(as))) + return val; + return put_user(as->usbin.dma.fragsize, user_arg); + + case SNDCTL_DSP_SETFRAGMENT: + if (get_user(val, user_arg)) + return -EFAULT; + if (file->f_mode & FMODE_READ) { + as->usbin.dma.ossfragshift = val & 0xffff; + as->usbin.dma.ossmaxfrags = (val >> 16) & 0xffff; + if (as->usbin.dma.ossfragshift < 4) + as->usbin.dma.ossfragshift = 4; + if (as->usbin.dma.ossfragshift > 15) + as->usbin.dma.ossfragshift = 15; + if (as->usbin.dma.ossmaxfrags < 4) + as->usbin.dma.ossmaxfrags = 4; + } + if (file->f_mode & FMODE_WRITE) { + as->usbout.dma.ossfragshift = val & 0xffff; + as->usbout.dma.ossmaxfrags = (val >> 16) & 0xffff; + if (as->usbout.dma.ossfragshift < 4) + as->usbout.dma.ossfragshift = 4; + if (as->usbout.dma.ossfragshift > 15) + as->usbout.dma.ossfragshift = 15; + if (as->usbout.dma.ossmaxfrags < 4) + as->usbout.dma.ossmaxfrags = 4; + } + return 0; + + case SNDCTL_DSP_SUBDIVIDE: + if ((file->f_mode & FMODE_READ && as->usbin.dma.subdivision) || + (file->f_mode & FMODE_WRITE && as->usbout.dma.subdivision)) + return -EINVAL; + if (get_user(val, user_arg)) + return -EFAULT; + if (val != 1 && val != 2 && val != 4) + return -EINVAL; + if (file->f_mode & FMODE_READ) + as->usbin.dma.subdivision = val; + if (file->f_mode & FMODE_WRITE) + as->usbout.dma.subdivision = val; + return 0; + + case SOUND_PCM_READ_RATE: + return put_user((file->f_mode & FMODE_READ) ? + as->usbin.dma.srate : as->usbout.dma.srate, + user_arg); + + case SOUND_PCM_READ_CHANNELS: + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg); + + case SOUND_PCM_READ_BITS: + val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format; + return put_user(AFMT_IS16BIT(val2) ? 16 : 8, user_arg); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: + case SOUND_PCM_READ_FILTER: + return -EINVAL; + } + dprintk((KERN_DEBUG "usbaudio: usb_audio_ioctl - no command found\n")); + return -ENOIOCTLCMD; +} + +static int usb_audio_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + DECLARE_WAITQUEUE(wait, current); + struct usb_audiodev *as; + struct usb_audio_state *s; + + for (;;) { + down(&open_sem); + list_for_each_entry(s, &audiodevs, audiodev) { + list_for_each_entry(as, &s->audiolist, list) { + if (!((as->dev_audio ^ minor) & ~0xf)) + goto device_found; + } + } + up(&open_sem); + return -ENODEV; + + device_found: + if (!s->usbdev) { + up(&open_sem); + return -EIO; + } + /* wait for device to become free */ + if (!(as->open_mode & file->f_mode)) + break; + if (file->f_flags & O_NONBLOCK) { + up(&open_sem); + return -EBUSY; + } + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&open_wait, &wait); + up(&open_sem); + schedule(); + __set_current_state(TASK_RUNNING); + remove_wait_queue(&open_wait, &wait); + if (signal_pending(current)) + return -ERESTARTSYS; + } + if (file->f_mode & FMODE_READ) + as->usbin.dma.ossfragshift = as->usbin.dma.ossmaxfrags = as->usbin.dma.subdivision = 0; + if (file->f_mode & FMODE_WRITE) + as->usbout.dma.ossfragshift = as->usbout.dma.ossmaxfrags = as->usbout.dma.subdivision = 0; + if (set_format(as, file->f_mode, ((minor & 0xf) == SND_DEV_DSP16) ? AFMT_S16_LE : AFMT_U8 /* AFMT_ULAW */, 8000)) { + up(&open_sem); + return -EIO; + } + file->private_data = as; + as->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); + s->count++; + up(&open_sem); + return nonseekable_open(inode, file); +} + +static int usb_audio_release(struct inode *inode, struct file *file) +{ + struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; + struct usb_audio_state *s; + struct usb_device *dev; + + lock_kernel(); + s = as->state; + dev = s->usbdev; + if (file->f_mode & FMODE_WRITE) + drain_out(as, file->f_flags & O_NONBLOCK); + down(&open_sem); + if (file->f_mode & FMODE_WRITE) { + usbout_stop(as); + if (dev && as->usbout.interface >= 0) + usb_set_interface(dev, as->usbout.interface, 0); + dmabuf_release(&as->usbout.dma); + usbout_release(as); + } + if (file->f_mode & FMODE_READ) { + usbin_stop(as); + if (dev && as->usbin.interface >= 0) + usb_set_interface(dev, as->usbin.interface, 0); + dmabuf_release(&as->usbin.dma); + usbin_release(as); + } + as->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); + release(s); + wake_up(&open_wait); + unlock_kernel(); + return 0; +} + +static /*const*/ struct file_operations usb_audio_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = usb_audio_read, + .write = usb_audio_write, + .poll = usb_audio_poll, + .ioctl = usb_audio_ioctl, + .mmap = usb_audio_mmap, + .open = usb_audio_open, + .release = usb_audio_release, +}; + +/* --------------------------------------------------------------------- */ + +static int usb_audio_probe(struct usb_interface *iface, + const struct usb_device_id *id); +static void usb_audio_disconnect(struct usb_interface *iface); + +static struct usb_device_id usb_audio_ids [] = { + { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), + .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = 1}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, usb_audio_ids); + +static struct usb_driver usb_audio_driver = { + .name = "audio", + .probe = usb_audio_probe, + .disconnect = usb_audio_disconnect, + .id_table = usb_audio_ids, +}; + +static void *find_descriptor(void *descstart, unsigned int desclen, void *after, + u8 dtype, int iface, int altsetting) +{ + u8 *p, *end, *next; + int ifc = -1, as = -1; + + p = descstart; + end = p + desclen; + for (; p < end;) { + if (p[0] < 2) + return NULL; + next = p + p[0]; + if (next > end) + return NULL; + if (p[1] == USB_DT_INTERFACE) { + /* minimum length of interface descriptor */ + if (p[0] < 9) + return NULL; + ifc = p[2]; + as = p[3]; + } + if (p[1] == dtype && (!after || (void *)p > after) && + (iface == -1 || iface == ifc) && (altsetting == -1 || altsetting == as)) { + return p; + } + p = next; + } + return NULL; +} + +static void *find_csinterface_descriptor(void *descstart, unsigned int desclen, void *after, u8 dsubtype, int iface, int altsetting) +{ + unsigned char *p; + + p = find_descriptor(descstart, desclen, after, USB_DT_CS_INTERFACE, iface, altsetting); + while (p) { + if (p[0] >= 3 && p[2] == dsubtype) + return p; + p = find_descriptor(descstart, desclen, p, USB_DT_CS_INTERFACE, iface, altsetting); + } + return NULL; +} + +static void *find_audiocontrol_unit(void *descstart, unsigned int desclen, void *after, u8 unit, int iface) +{ + unsigned char *p; + + p = find_descriptor(descstart, desclen, after, USB_DT_CS_INTERFACE, iface, -1); + while (p) { + if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit) + return p; + p = find_descriptor(descstart, desclen, p, USB_DT_CS_INTERFACE, iface, -1); + } + return NULL; +} + +static void usb_audio_parsestreaming(struct usb_audio_state *s, unsigned char *buffer, unsigned int buflen, int asifin, int asifout) +{ + struct usb_device *dev = s->usbdev; + struct usb_audiodev *as; + struct usb_host_interface *alts; + struct usb_interface *iface; + struct audioformat *fp; + unsigned char *fmt, *csep; + unsigned int i, j, k, format, idx; + + if (!(as = kmalloc(sizeof(struct usb_audiodev), GFP_KERNEL))) + return; + memset(as, 0, sizeof(struct usb_audiodev)); + init_waitqueue_head(&as->usbin.dma.wait); + init_waitqueue_head(&as->usbout.dma.wait); + spin_lock_init(&as->lock); + as->usbin.durb[0].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL); + as->usbin.durb[1].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL); + as->usbin.surb[0].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL); + as->usbin.surb[1].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL); + as->usbout.durb[0].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL); + as->usbout.durb[1].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL); + as->usbout.surb[0].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL); + as->usbout.surb[1].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL); + if ((!as->usbin.durb[0].urb) || + (!as->usbin.durb[1].urb) || + (!as->usbin.surb[0].urb) || + (!as->usbin.surb[1].urb) || + (!as->usbout.durb[0].urb) || + (!as->usbout.durb[1].urb) || + (!as->usbout.surb[0].urb) || + (!as->usbout.surb[1].urb)) { + usb_free_urb(as->usbin.durb[0].urb); + usb_free_urb(as->usbin.durb[1].urb); + usb_free_urb(as->usbin.surb[0].urb); + usb_free_urb(as->usbin.surb[1].urb); + usb_free_urb(as->usbout.durb[0].urb); + usb_free_urb(as->usbout.durb[1].urb); + usb_free_urb(as->usbout.surb[0].urb); + usb_free_urb(as->usbout.surb[1].urb); + kfree(as); + return; + } + as->state = s; + as->usbin.interface = asifin; + as->usbout.interface = asifout; + /* search for input formats */ + if (asifin >= 0) { + as->usbin.flags = FLG_CONNECTED; + iface = usb_ifnum_to_if(dev, asifin); + for (idx = 0; idx < iface->num_altsetting; idx++) { + alts = &iface->altsetting[idx]; + i = alts->desc.bAlternateSetting; + if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO || alts->desc.bInterfaceSubClass != 2) + continue; + if (alts->desc.bNumEndpoints < 1) { + if (i != 0) { /* altsetting 0 has no endpoints (Section B.3.4.1) */ + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n", + dev->devnum, asifin, i); + } + continue; + } + if ((alts->endpoint[0].desc.bmAttributes & 0x03) != 0x01 || + !(alts->endpoint[0].desc.bEndpointAddress & 0x80)) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous in\n", + dev->devnum, asifin, i); + continue; + } + fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifin, i); + if (!fmt) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + dev->devnum, asifin, i); + continue; + } + if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u format not supported\n", + dev->devnum, asifin, i); + continue; + } + format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8); + fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifin, i); + if (!fmt) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + dev->devnum, asifin, i); + continue; + } + if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n", + dev->devnum, asifin, i); + continue; + } + if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n", + dev->devnum, asifin, i, fmt[4], fmt[5]); + continue; + } + csep = find_descriptor(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, asifin, i); + if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u no or invalid class specific endpoint descriptor\n", + dev->devnum, asifin, i); + continue; + } + if (as->numfmtin >= MAXFORMATS) + continue; + fp = &as->fmtin[as->numfmtin++]; + if (fmt[5] == 2) + format &= (AFMT_U16_LE | AFMT_S16_LE); + else + format &= (AFMT_U8 | AFMT_S8); + if (fmt[4] == 2) + format |= AFMT_STEREO; + fp->format = format; + fp->altsetting = i; + fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16); + printk(KERN_INFO "usbaudio: valid input sample rate %u\n", fp->sratelo); + for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) { + k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16); + printk(KERN_INFO "usbaudio: valid input sample rate %u\n", k); + if (k > fp->sratehi) + fp->sratehi = k; + if (k < fp->sratelo) + fp->sratelo = k; + } + fp->attributes = csep[3]; + printk(KERN_INFO "usbaudio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u attributes 0x%02x\n", + dev->devnum, asifin, i, fp->format, fp->sratelo, fp->sratehi, fp->attributes); + } + } + /* search for output formats */ + if (asifout >= 0) { + as->usbout.flags = FLG_CONNECTED; + iface = usb_ifnum_to_if(dev, asifout); + for (idx = 0; idx < iface->num_altsetting; idx++) { + alts = &iface->altsetting[idx]; + i = alts->desc.bAlternateSetting; + if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO || alts->desc.bInterfaceSubClass != 2) + continue; + if (alts->desc.bNumEndpoints < 1) { + /* altsetting 0 should never have iso EPs */ + if (i != 0) + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n", + dev->devnum, asifout, i); + continue; + } + if ((alts->endpoint[0].desc.bmAttributes & 0x03) != 0x01 || + (alts->endpoint[0].desc.bEndpointAddress & 0x80)) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous out\n", + dev->devnum, asifout, i); + continue; + } + /* See USB audio formats manual, section 2 */ + fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifout, i); + if (!fmt) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + dev->devnum, asifout, i); + continue; + } + if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u format not supported\n", + dev->devnum, asifout, i); + continue; + } + format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8); + /* Dallas DS4201 workaround */ + if (le16_to_cpu(dev->descriptor.idVendor) == 0x04fa && + le16_to_cpu(dev->descriptor.idProduct) == 0x4201) + format = (AFMT_S16_LE | AFMT_S8); + fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifout, i); + if (!fmt) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + dev->devnum, asifout, i); + continue; + } + if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n", + dev->devnum, asifout, i); + continue; + } + if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n", + dev->devnum, asifout, i, fmt[4], fmt[5]); + continue; + } + csep = find_descriptor(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, asifout, i); + if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u no or invalid class specific endpoint descriptor\n", + dev->devnum, asifout, i); + continue; + } + if (as->numfmtout >= MAXFORMATS) + continue; + fp = &as->fmtout[as->numfmtout++]; + if (fmt[5] == 2) + format &= (AFMT_U16_LE | AFMT_S16_LE); + else + format &= (AFMT_U8 | AFMT_S8); + if (fmt[4] == 2) + format |= AFMT_STEREO; + fp->format = format; + fp->altsetting = i; + fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16); + printk(KERN_INFO "usbaudio: valid output sample rate %u\n", fp->sratelo); + for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) { + k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16); + printk(KERN_INFO "usbaudio: valid output sample rate %u\n", k); + if (k > fp->sratehi) + fp->sratehi = k; + if (k < fp->sratelo) + fp->sratelo = k; + } + fp->attributes = csep[3]; + printk(KERN_INFO "usbaudio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u attributes 0x%02x\n", + dev->devnum, asifout, i, fp->format, fp->sratelo, fp->sratehi, fp->attributes); + } + } + if (as->numfmtin == 0 && as->numfmtout == 0) { + usb_free_urb(as->usbin.durb[0].urb); + usb_free_urb(as->usbin.durb[1].urb); + usb_free_urb(as->usbin.surb[0].urb); + usb_free_urb(as->usbin.surb[1].urb); + usb_free_urb(as->usbout.durb[0].urb); + usb_free_urb(as->usbout.durb[1].urb); + usb_free_urb(as->usbout.surb[0].urb); + usb_free_urb(as->usbout.surb[1].urb); + kfree(as); + return; + } + if ((as->dev_audio = register_sound_dsp(&usb_audio_fops, -1)) < 0) { + printk(KERN_ERR "usbaudio: cannot register dsp\n"); + usb_free_urb(as->usbin.durb[0].urb); + usb_free_urb(as->usbin.durb[1].urb); + usb_free_urb(as->usbin.surb[0].urb); + usb_free_urb(as->usbin.surb[1].urb); + usb_free_urb(as->usbout.durb[0].urb); + usb_free_urb(as->usbout.durb[1].urb); + usb_free_urb(as->usbout.surb[0].urb); + usb_free_urb(as->usbout.surb[1].urb); + kfree(as); + return; + } + printk(KERN_INFO "usbaudio: registered dsp 14,%d\n", as->dev_audio); + /* everything successful */ + list_add_tail(&as->list, &s->audiolist); +} + +struct consmixstate { + struct usb_audio_state *s; + unsigned char *buffer; + unsigned int buflen; + unsigned int ctrlif; + struct mixerchannel mixch[SOUND_MIXER_NRDEVICES]; + unsigned int nrmixch; + unsigned int mixchmask; + unsigned long unitbitmap[32/sizeof(unsigned long)]; + /* return values */ + unsigned int nrchannels; + unsigned int termtype; + unsigned int chconfig; +}; + +static struct mixerchannel *getmixchannel(struct consmixstate *state, unsigned int nr) +{ + struct mixerchannel *c; + + if (nr >= SOUND_MIXER_NRDEVICES) { + printk(KERN_ERR "usbaudio: invalid OSS mixer channel %u\n", nr); + return NULL; + } + if (!(state->mixchmask & (1 << nr))) { + printk(KERN_WARNING "usbaudio: OSS mixer channel %u already in use\n", nr); + return NULL; + } + c = &state->mixch[state->nrmixch++]; + c->osschannel = nr; + state->mixchmask &= ~(1 << nr); + return c; +} + +static unsigned int getvolchannel(struct consmixstate *state) +{ + unsigned int u; + + if ((state->termtype & 0xff00) == 0x0000 && (state->mixchmask & SOUND_MASK_VOLUME)) + return SOUND_MIXER_VOLUME; + if ((state->termtype & 0xff00) == 0x0100) { + if (state->mixchmask & SOUND_MASK_PCM) + return SOUND_MIXER_PCM; + if (state->mixchmask & SOUND_MASK_ALTPCM) + return SOUND_MIXER_ALTPCM; + } + if ((state->termtype & 0xff00) == 0x0200 && (state->mixchmask & SOUND_MASK_MIC)) + return SOUND_MIXER_MIC; + if ((state->termtype & 0xff00) == 0x0300 && (state->mixchmask & SOUND_MASK_SPEAKER)) + return SOUND_MIXER_SPEAKER; + if ((state->termtype & 0xff00) == 0x0500) { + if (state->mixchmask & SOUND_MASK_PHONEIN) + return SOUND_MIXER_PHONEIN; + if (state->mixchmask & SOUND_MASK_PHONEOUT) + return SOUND_MIXER_PHONEOUT; + } + if (state->termtype >= 0x710 && state->termtype <= 0x711 && (state->mixchmask & SOUND_MASK_RADIO)) + return SOUND_MIXER_RADIO; + if (state->termtype >= 0x709 && state->termtype <= 0x70f && (state->mixchmask & SOUND_MASK_VIDEO)) + return SOUND_MIXER_VIDEO; + u = ffs(state->mixchmask & (SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | SOUND_MASK_LINE3 | + SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | SOUND_MASK_DIGITAL3)); + return u-1; +} + +static void prepmixch(struct consmixstate *state) +{ + struct usb_device *dev = state->s->usbdev; + struct mixerchannel *ch; + unsigned char *buf; + __s16 v1; + unsigned int v2, v3; + + if (!state->nrmixch || state->nrmixch > SOUND_MIXER_NRDEVICES) + return; + buf = kmalloc(sizeof(*buf) * 2, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "prepmixch: out of memory\n") ; + return; + } + + ch = &state->mixch[state->nrmixch-1]; + switch (ch->selector) { + case 0: /* mixer unit request */ + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0) + goto err; + ch->minval = buf[0] | (buf[1] << 8); + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0) + goto err; + ch->maxval = buf[0] | (buf[1] << 8); + v2 = ch->maxval - ch->minval; + if (!v2) + v2 = 1; + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0) + goto err; + v1 = buf[0] | (buf[1] << 8); + v3 = v1 - ch->minval; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + ch->value = v3; + if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) { + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)), + state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0) + goto err; + v1 = buf[0] | (buf[1] << 8); + v3 = v1 - ch->minval; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + } + ch->value |= v3 << 8; + break; + + /* various feature unit controls */ + case VOLUME_CONTROL: + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0) + goto err; + ch->minval = buf[0] | (buf[1] << 8); + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0) + goto err; + ch->maxval = buf[0] | (buf[1] << 8); + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0) + goto err; + v1 = buf[0] | (buf[1] << 8); + v2 = ch->maxval - ch->minval; + v3 = v1 - ch->minval; + if (!v2) + v2 = 1; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + ch->value = v3; + if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) { + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0) + goto err; + v1 = buf[0] | (buf[1] << 8); + v3 = v1 - ch->minval; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + } + ch->value |= v3 << 8; + break; + + case BASS_CONTROL: + case MID_CONTROL: + case TREBLE_CONTROL: + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, 1000) < 0) + goto err; + ch->minval = buf[0] << 8; + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, 1000) < 0) + goto err; + ch->maxval = buf[0] << 8; + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, 1000) < 0) + goto err; + v1 = buf[0] << 8; + v2 = ch->maxval - ch->minval; + v3 = v1 - ch->minval; + if (!v2) + v2 = 1; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + ch->value = v3; + if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) { + if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 1, 1000) < 0) + goto err; + v1 = buf[0] << 8; + v3 = v1 - ch->minval; + v3 = 100 * v3 / v2; + if (v3 > 100) + v3 = 100; + } + ch->value |= v3 << 8; + break; + + default: + goto err; + } + + freebuf: + kfree(buf); + return; + err: + printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n", + dev->devnum, state->ctrlif, ch->unitid, ch->chnum, ch->selector); + if (state->nrmixch) + state->nrmixch--; + goto freebuf; +} + + +static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid); + +static inline int checkmixbmap(unsigned char *bmap, unsigned char flg, unsigned int inidx, unsigned int numoch) +{ + unsigned int idx; + + idx = inidx*numoch; + if (!(bmap[-(idx >> 3)] & (0x80 >> (idx & 7)))) + return 0; + if (!(flg & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) + return 1; + idx = (inidx+!!(flg & MIXFLG_STEREOIN))*numoch+!!(flg & MIXFLG_STEREOOUT); + if (!(bmap[-(idx >> 3)] & (0x80 >> (idx & 7)))) + return 0; + return 1; +} + +static void usb_audio_mixerunit(struct consmixstate *state, unsigned char *mixer) +{ + unsigned int nroutch = mixer[5+mixer[4]]; + unsigned int chidx[SOUND_MIXER_NRDEVICES+1]; + unsigned int termt[SOUND_MIXER_NRDEVICES]; + unsigned char flg = (nroutch >= 2) ? MIXFLG_STEREOOUT : 0; + unsigned char *bmap = &mixer[9+mixer[4]]; + unsigned int bmapsize; + struct mixerchannel *ch; + unsigned int i; + + if (!mixer[4]) { + printk(KERN_ERR "usbaudio: unit %u invalid MIXER_UNIT descriptor\n", mixer[3]); + return; + } + if (mixer[4] > SOUND_MIXER_NRDEVICES) { + printk(KERN_ERR "usbaudio: mixer unit %u: too many input pins\n", mixer[3]); + return; + } + chidx[0] = 0; + for (i = 0; i < mixer[4]; i++) { + usb_audio_recurseunit(state, mixer[5+i]); + chidx[i+1] = chidx[i] + state->nrchannels; + termt[i] = state->termtype; + } + state->termtype = 0; + state->chconfig = mixer[6+mixer[4]] | (mixer[7+mixer[4]] << 8); + bmapsize = (nroutch * chidx[mixer[4]] + 7) >> 3; + bmap += bmapsize - 1; + if (mixer[0] < 10+mixer[4]+bmapsize) { + printk(KERN_ERR "usbaudio: unit %u invalid MIXER_UNIT descriptor (bitmap too small)\n", mixer[3]); + return; + } + for (i = 0; i < mixer[4]; i++) { + state->termtype = termt[i]; + if (chidx[i+1]-chidx[i] >= 2) { + flg |= MIXFLG_STEREOIN; + if (checkmixbmap(bmap, flg, chidx[i], nroutch)) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = mixer[3]; + ch->selector = 0; + ch->chnum = chidx[i]+1; + ch->flags = flg; + prepmixch(state); + } + continue; + } + } + flg &= ~MIXFLG_STEREOIN; + if (checkmixbmap(bmap, flg, chidx[i], nroutch)) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = mixer[3]; + ch->selector = 0; + ch->chnum = chidx[i]+1; + ch->flags = flg; + prepmixch(state); + } + } + } + state->termtype = 0; +} + +static struct mixerchannel *slctsrc_findunit(struct consmixstate *state, __u8 unitid) +{ + unsigned int i; + + for (i = 0; i < state->nrmixch; i++) + if (state->mixch[i].unitid == unitid) + return &state->mixch[i]; + return NULL; +} + +static void usb_audio_selectorunit(struct consmixstate *state, unsigned char *selector) +{ + unsigned int chnum, i, mixch; + struct mixerchannel *mch; + + if (!selector[4]) { + printk(KERN_ERR "usbaudio: unit %u invalid SELECTOR_UNIT descriptor\n", selector[3]); + return; + } + mixch = state->nrmixch; + usb_audio_recurseunit(state, selector[5]); + if (state->nrmixch != mixch) { + mch = &state->mixch[state->nrmixch-1]; + mch->slctunitid = selector[3] | (1 << 8); + } else if ((mch = slctsrc_findunit(state, selector[5]))) { + mch->slctunitid = selector[3] | (1 << 8); + } else { + printk(KERN_INFO "usbaudio: selector unit %u: ignoring channel 1\n", selector[3]); + } + chnum = state->nrchannels; + for (i = 1; i < selector[4]; i++) { + mixch = state->nrmixch; + usb_audio_recurseunit(state, selector[5+i]); + if (chnum != state->nrchannels) { + printk(KERN_ERR "usbaudio: selector unit %u: input pins with varying channel numbers\n", selector[3]); + state->termtype = 0; + state->chconfig = 0; + state->nrchannels = 0; + return; + } + if (state->nrmixch != mixch) { + mch = &state->mixch[state->nrmixch-1]; + mch->slctunitid = selector[3] | ((i + 1) << 8); + } else if ((mch = slctsrc_findunit(state, selector[5+i]))) { + mch->slctunitid = selector[3] | ((i + 1) << 8); + } else { + printk(KERN_INFO "usbaudio: selector unit %u: ignoring channel %u\n", selector[3], i+1); + } + } + state->termtype = 0; + state->chconfig = 0; +} + +/* in the future we might try to handle 3D etc. effect units */ + +static void usb_audio_processingunit(struct consmixstate *state, unsigned char *proc) +{ + unsigned int i; + + for (i = 0; i < proc[6]; i++) + usb_audio_recurseunit(state, proc[7+i]); + state->nrchannels = proc[7+proc[6]]; + state->termtype = 0; + state->chconfig = proc[8+proc[6]] | (proc[9+proc[6]] << 8); +} + + +/* See Audio Class Spec, section 4.3.2.5 */ +static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr) +{ + struct mixerchannel *ch; + unsigned short chftr, mchftr; +#if 0 + struct usb_device *dev = state->s->usbdev; + unsigned char data[1]; +#endif + unsigned char nr_logical_channels, i; + + usb_audio_recurseunit(state, ftr[4]); + + if (ftr[5] == 0 ) { + printk(KERN_ERR "usbaudio: wrong controls size in feature unit %u\n",ftr[3]); + return; + } + + if (state->nrchannels == 0) { + printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]); + return; + } + if (state->nrchannels > 2) + printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]); + + nr_logical_channels=(ftr[0]-7)/ftr[5]-1; + + if (nr_logical_channels != state->nrchannels) { + printk(KERN_WARNING "usbaudio: warning: found %d of %d logical channels.\n", state->nrchannels,nr_logical_channels); + + if (state->nrchannels == 1 && nr_logical_channels==0) { + printk(KERN_INFO "usbaudio: assuming the channel found is the master channel (got a Philips camera?). Should be fine.\n"); + } else if (state->nrchannels == 1 && nr_logical_channels==2) { + printk(KERN_INFO "usbaudio: assuming that a stereo channel connected directly to a mixer is missing in search (got Labtec headset?). Should be fine.\n"); + state->nrchannels=nr_logical_channels; + } else { + printk(KERN_WARNING "usbaudio: no idea what's going on..., contact linux-usb-devel@lists.sourceforge.net\n"); + } + } + + /* There is always a master channel */ + mchftr = ftr[6]; + /* Binary AND over logical channels if they exist */ + if (nr_logical_channels) { + chftr = ftr[6+ftr[5]]; + for (i = 2; i <= nr_logical_channels; i++) + chftr &= ftr[6+i*ftr[5]]; + } else { + chftr = 0; + } + + /* volume control */ + if (chftr & 2) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = VOLUME_CONTROL; + ch->chnum = 1; + ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0; + prepmixch(state); + } + } else if (mchftr & 2) { + ch = getmixchannel(state, getvolchannel(state)); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = VOLUME_CONTROL; + ch->chnum = 0; + ch->flags = 0; + prepmixch(state); + } + } + /* bass control */ + if (chftr & 4) { + ch = getmixchannel(state, SOUND_MIXER_BASS); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = BASS_CONTROL; + ch->chnum = 1; + ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0; + prepmixch(state); + } + } else if (mchftr & 4) { + ch = getmixchannel(state, SOUND_MIXER_BASS); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = BASS_CONTROL; + ch->chnum = 0; + ch->flags = 0; + prepmixch(state); + } + } + /* treble control */ + if (chftr & 16) { + ch = getmixchannel(state, SOUND_MIXER_TREBLE); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = TREBLE_CONTROL; + ch->chnum = 1; + ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0; + prepmixch(state); + } + } else if (mchftr & 16) { + ch = getmixchannel(state, SOUND_MIXER_TREBLE); + if (ch) { + ch->unitid = ftr[3]; + ch->selector = TREBLE_CONTROL; + ch->chnum = 0; + ch->flags = 0; + prepmixch(state); + } + } +#if 0 + /* if there are mute controls, unmute them */ + /* does not seem to be necessary, and the Dallas chip does not seem to support the "all" channel (255) */ + if ((chftr & 1) || (mchftr & 1)) { + printk(KERN_DEBUG "usbaudio: unmuting feature unit %u interface %u\n", ftr[3], state->ctrlif); + data[0] = 0; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (MUTE_CONTROL << 8) | 0xff, state->ctrlif | (ftr[3] << 8), data, 1, 1000) < 0) + printk(KERN_WARNING "usbaudio: failure to unmute feature unit %u interface %u\n", ftr[3], state->ctrlif); + } +#endif +} + +static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid) +{ + unsigned char *p1; + unsigned int i, j; + + if (test_and_set_bit(unitid, state->unitbitmap)) { + printk(KERN_INFO "usbaudio: mixer path revisits unit %d\n", unitid); + return; + } + p1 = find_audiocontrol_unit(state->buffer, state->buflen, NULL, unitid, state->ctrlif); + if (!p1) { + printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid); + return; + } + state->nrchannels = 0; + state->termtype = 0; + state->chconfig = 0; + switch (p1[2]) { + case INPUT_TERMINAL: + if (p1[0] < 12) { + printk(KERN_ERR "usbaudio: unit %u: invalid INPUT_TERMINAL descriptor\n", unitid); + return; + } + state->nrchannels = p1[7]; + state->termtype = p1[4] | (p1[5] << 8); + state->chconfig = p1[8] | (p1[9] << 8); + return; + + case MIXER_UNIT: + if (p1[0] < 10 || p1[0] < 10+p1[4]) { + printk(KERN_ERR "usbaudio: unit %u: invalid MIXER_UNIT descriptor\n", unitid); + return; + } + usb_audio_mixerunit(state, p1); + return; + + case SELECTOR_UNIT: + if (p1[0] < 6 || p1[0] < 6+p1[4]) { + printk(KERN_ERR "usbaudio: unit %u: invalid SELECTOR_UNIT descriptor\n", unitid); + return; + } + usb_audio_selectorunit(state, p1); + return; + + case FEATURE_UNIT: /* See USB Audio Class Spec 4.3.2.5 */ + if (p1[0] < 7 || p1[0] < 7+p1[5]) { + printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid); + return; + } + usb_audio_featureunit(state, p1); + return; + + case PROCESSING_UNIT: + if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]]) { + printk(KERN_ERR "usbaudio: unit %u: invalid PROCESSING_UNIT descriptor\n", unitid); + return; + } + usb_audio_processingunit(state, p1); + return; + + case EXTENSION_UNIT: + if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]]) { + printk(KERN_ERR "usbaudio: unit %u: invalid EXTENSION_UNIT descriptor\n", unitid); + return; + } + for (j = i = 0; i < p1[6]; i++) { + usb_audio_recurseunit(state, p1[7+i]); + if (!i) + j = state->termtype; + else if (j != state->termtype) + j = 0; + } + state->nrchannels = p1[7+p1[6]]; + state->chconfig = p1[8+p1[6]] | (p1[9+p1[6]] << 8); + state->termtype = j; + return; + + default: + printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); + return; + } +} + +static void usb_audio_constructmixer(struct usb_audio_state *s, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif, unsigned char *oterm) +{ + struct usb_mixerdev *ms; + struct consmixstate state; + + memset(&state, 0, sizeof(state)); + state.s = s; + state.nrmixch = 0; + state.mixchmask = ~0; + state.buffer = buffer; + state.buflen = buflen; + state.ctrlif = ctrlif; + set_bit(oterm[3], state.unitbitmap); /* mark terminal ID as visited */ + printk(KERN_DEBUG "usbaudio: constructing mixer for Terminal %u type 0x%04x\n", + oterm[3], oterm[4] | (oterm[5] << 8)); + usb_audio_recurseunit(&state, oterm[7]); + if (!state.nrmixch) { + printk(KERN_INFO "usbaudio: no mixer controls found for Terminal %u\n", oterm[3]); + return; + } + if (!(ms = kmalloc(sizeof(struct usb_mixerdev)+state.nrmixch*sizeof(struct mixerchannel), GFP_KERNEL))) + return; + memset(ms, 0, sizeof(struct usb_mixerdev)); + memcpy(&ms->ch, &state.mixch, state.nrmixch*sizeof(struct mixerchannel)); + ms->state = s; + ms->iface = ctrlif; + ms->numch = state.nrmixch; + if ((ms->dev_mixer = register_sound_mixer(&usb_mixer_fops, -1)) < 0) { + printk(KERN_ERR "usbaudio: cannot register mixer\n"); + kfree(ms); + return; + } + printk(KERN_INFO "usbaudio: registered mixer 14,%d\n", ms->dev_mixer); + list_add_tail(&ms->list, &s->mixerlist); +} + +/* arbitrary limit, we won't check more interfaces than this */ +#define USB_MAXINTERFACES 32 + +static struct usb_audio_state *usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif) +{ + struct usb_audio_state *s; + struct usb_interface *iface; + struct usb_host_interface *alt; + unsigned char ifin[USB_MAXINTERFACES], ifout[USB_MAXINTERFACES]; + unsigned char *p1; + unsigned int i, j, k, numifin = 0, numifout = 0; + + if (!(s = kmalloc(sizeof(struct usb_audio_state), GFP_KERNEL))) + return NULL; + memset(s, 0, sizeof(struct usb_audio_state)); + INIT_LIST_HEAD(&s->audiolist); + INIT_LIST_HEAD(&s->mixerlist); + s->usbdev = dev; + s->count = 1; + + /* find audiocontrol interface */ + if (!(p1 = find_csinterface_descriptor(buffer, buflen, NULL, HEADER, ctrlif, -1))) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u no HEADER found\n", + dev->devnum, ctrlif); + goto ret; + } + if (p1[0] < 8 + p1[7]) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u HEADER error\n", + dev->devnum, ctrlif); + goto ret; + } + if (!p1[7]) + printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u has no AudioStreaming and MidiStreaming interfaces\n", + dev->devnum, ctrlif); + for (i = 0; i < p1[7]; i++) { + j = p1[8+i]; + iface = usb_ifnum_to_if(dev, j); + if (!iface) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u does not exist\n", + dev->devnum, ctrlif, j); + continue; + } + if (iface->num_altsetting == 1) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u has only 1 altsetting.\n", dev->devnum, ctrlif); + continue; + } + alt = usb_altnum_to_altsetting(iface, 0); + if (!alt) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no altsetting 0\n", + dev->devnum, ctrlif, j); + continue; + } + if (alt->desc.bInterfaceClass != USB_CLASS_AUDIO) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u is not an AudioClass interface\n", + dev->devnum, ctrlif, j); + continue; + } + if (alt->desc.bInterfaceSubClass == 3) { + printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u interface %u MIDIStreaming not supported\n", + dev->devnum, ctrlif, j); + continue; + } + if (alt->desc.bInterfaceSubClass != 2) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u invalid AudioClass subtype\n", + dev->devnum, ctrlif, j); + continue; + } + if (alt->desc.bNumEndpoints > 0) { + /* Check all endpoints; should they all have a bandwidth of 0 ? */ + for (k = 0; k < alt->desc.bNumEndpoints; k++) { + if (le16_to_cpu(alt->endpoint[k].desc.wMaxPacketSize) > 0) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u endpoint %d does not have 0 bandwidth at alt[0]\n", dev->devnum, ctrlif, k); + break; + } + } + if (k < alt->desc.bNumEndpoints) + continue; + } + + alt = usb_altnum_to_altsetting(iface, 1); + if (!alt) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no altsetting 1\n", + dev->devnum, ctrlif, j); + continue; + } + if (alt->desc.bNumEndpoints < 1) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no endpoint\n", + dev->devnum, ctrlif, j); + continue; + } + /* note: this requires the data endpoint to be ep0 and the optional sync + ep to be ep1, which seems to be the case */ + if (alt->endpoint[0].desc.bEndpointAddress & USB_DIR_IN) { + if (numifin < USB_MAXINTERFACES) { + ifin[numifin++] = j; + usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1); + } + } else { + if (numifout < USB_MAXINTERFACES) { + ifout[numifout++] = j; + usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1); + } + } + } + printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u has %u input and %u output AudioStreaming interfaces\n", + dev->devnum, ctrlif, numifin, numifout); + for (i = 0; i < numifin && i < numifout; i++) + usb_audio_parsestreaming(s, buffer, buflen, ifin[i], ifout[i]); + for (j = i; j < numifin; j++) + usb_audio_parsestreaming(s, buffer, buflen, ifin[i], -1); + for (j = i; j < numifout; j++) + usb_audio_parsestreaming(s, buffer, buflen, -1, ifout[i]); + /* now walk through all OUTPUT_TERMINAL descriptors to search for mixers */ + p1 = find_csinterface_descriptor(buffer, buflen, NULL, OUTPUT_TERMINAL, ctrlif, -1); + while (p1) { + if (p1[0] >= 9) + usb_audio_constructmixer(s, buffer, buflen, ctrlif, p1); + p1 = find_csinterface_descriptor(buffer, buflen, p1, OUTPUT_TERMINAL, ctrlif, -1); + } + +ret: + if (list_empty(&s->audiolist) && list_empty(&s->mixerlist)) { + kfree(s); + return NULL; + } + /* everything successful */ + down(&open_sem); + list_add_tail(&s->audiodev, &audiodevs); + up(&open_sem); + printk(KERN_DEBUG "usb_audio_parsecontrol: usb_audio_state at %p\n", s); + return s; +} + +/* we only care for the currently active configuration */ + +static int usb_audio_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev (intf); + struct usb_audio_state *s; + unsigned char *buffer; + unsigned int buflen; + +#if 0 + printk(KERN_DEBUG "usbaudio: Probing if %i: IC %x, ISC %x\n", ifnum, + config->interface[ifnum].altsetting[0].desc.bInterfaceClass, + config->interface[ifnum].altsetting[0].desc.bInterfaceSubClass); +#endif + + /* + * audiocontrol interface found + * find which configuration number is active + */ + buffer = dev->rawdescriptors[dev->actconfig - dev->config]; + buflen = le16_to_cpu(dev->actconfig->desc.wTotalLength); + s = usb_audio_parsecontrol(dev, buffer, buflen, intf->altsetting->desc.bInterfaceNumber); + if (s) { + usb_set_intfdata (intf, s); + return 0; + } + return -ENODEV; +} + + +/* a revoke facility would make things simpler */ + +static void usb_audio_disconnect(struct usb_interface *intf) +{ + struct usb_audio_state *s = usb_get_intfdata (intf); + struct usb_audiodev *as; + struct usb_mixerdev *ms; + + if (!s) + return; + + /* we get called with -1 for every audiostreaming interface registered */ + if (s == (struct usb_audio_state *)-1) { + dprintk((KERN_DEBUG "usbaudio: note, usb_audio_disconnect called with -1\n")); + return; + } + if (!s->usbdev) { + dprintk((KERN_DEBUG "usbaudio: error, usb_audio_disconnect already called for %p!\n", s)); + return; + } + down(&open_sem); + list_del_init(&s->audiodev); + s->usbdev = NULL; + usb_set_intfdata (intf, NULL); + + /* deregister all audio and mixer devices, so no new processes can open this device */ + list_for_each_entry(as, &s->audiolist, list) { + usbin_disc(as); + usbout_disc(as); + wake_up(&as->usbin.dma.wait); + wake_up(&as->usbout.dma.wait); + if (as->dev_audio >= 0) { + unregister_sound_dsp(as->dev_audio); + printk(KERN_INFO "usbaudio: unregister dsp 14,%d\n", as->dev_audio); + } + as->dev_audio = -1; + } + list_for_each_entry(ms, &s->mixerlist, list) { + if (ms->dev_mixer >= 0) { + unregister_sound_mixer(ms->dev_mixer); + printk(KERN_INFO "usbaudio: unregister mixer 14,%d\n", ms->dev_mixer); + } + ms->dev_mixer = -1; + } + release(s); + wake_up(&open_wait); +} + +static int __init usb_audio_init(void) +{ + int result = usb_register(&usb_audio_driver); + if (result == 0) + info(DRIVER_VERSION ":" DRIVER_DESC); + return result; +} + + +static void __exit usb_audio_cleanup(void) +{ + usb_deregister(&usb_audio_driver); +} + +module_init(usb_audio_init); +module_exit(usb_audio_cleanup); + +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_LICENSE("GPL"); + diff --git a/drivers/usb/class/audio.h b/drivers/usb/class/audio.h new file mode 100644 index 000000000..45916eb12 --- /dev/null +++ b/drivers/usb/class/audio.h @@ -0,0 +1,110 @@ +#define CS_AUDIO_UNDEFINED 0x20 +#define CS_AUDIO_DEVICE 0x21 +#define CS_AUDIO_CONFIGURATION 0x22 +#define CS_AUDIO_STRING 0x23 +#define CS_AUDIO_INTERFACE 0x24 +#define CS_AUDIO_ENDPOINT 0x25 + +#define HEADER 0x01 +#define INPUT_TERMINAL 0x02 +#define OUTPUT_TERMINAL 0x03 +#define MIXER_UNIT 0x04 +#define SELECTOR_UNIT 0x05 +#define FEATURE_UNIT 0x06 +#define PROCESSING_UNIT 0x07 +#define EXTENSION_UNIT 0x08 + +#define AS_GENERAL 0x01 +#define FORMAT_TYPE 0x02 +#define FORMAT_SPECIFIC 0x03 + +#define EP_GENERAL 0x01 + +#define MAX_CHAN 9 +#define MAX_FREQ 16 +#define MAX_IFACE 8 +#define MAX_FORMAT 8 +#define MAX_ALT 32 /* Sorry, we need quite a few for the Philips webcams */ + +struct usb_audio_terminal +{ + u8 flags; + u8 assoc; + u16 type; /* Mic etc */ + u8 channels; + u8 source; + u16 chancfg; +}; + +struct usb_audio_format +{ + u8 type; + u8 channels; + u8 num_freq; + u8 sfz; + u8 bits; + u16 freq[MAX_FREQ]; +}; + +struct usb_audio_interface +{ + u8 terminal; + u8 delay; + u16 num_formats; + u16 format_type; + u8 flags; + u8 idleconf; /* Idle config */ +#define AU_IFACE_FOUND 1 + struct usb_audio_format format[MAX_FORMAT]; +}; + +struct usb_audio_device +{ + struct list_head list; + u8 mixer; + u8 selector; + void *irq_handle; + u8 num_channels; + u8 num_dsp_iface; + u8 channel_map[MAX_CHAN]; + struct usb_audio_terminal terminal[MAX_CHAN]; + struct usb_audio_interface interface[MAX_IFACE][MAX_ALT]; +}; + + + +/* Audio Class specific Request Codes */ + +#define SET_CUR 0x01 +#define GET_CUR 0x81 +#define SET_MIN 0x02 +#define GET_MIN 0x82 +#define SET_MAX 0x03 +#define GET_MAX 0x83 +#define SET_RES 0x04 +#define GET_RES 0x84 +#define SET_MEM 0x05 +#define GET_MEM 0x85 +#define GET_STAT 0xff + +/* Terminal Control Selectors */ + +#define COPY_PROTECT_CONTROL 0x01 + +/* Feature Unit Control Selectors */ + +#define MUTE_CONTROL 0x01 +#define VOLUME_CONTROL 0x02 +#define BASS_CONTROL 0x03 +#define MID_CONTROL 0x04 +#define TREBLE_CONTROL 0x05 +#define GRAPHIC_EQUALIZER_CONTROL 0x06 +#define AUTOMATIC_GAIN_CONTROL 0x07 +#define DELAY_CONTROL 0x08 +#define BASS_BOOST_CONTROL 0x09 +#define LOUDNESS_CONTROL 0x0a + +/* Endpoint Control Selectors */ + +#define SAMPLING_FREQ_CONTROL 0x01 +#define PITCH_CONTROL 0x02 diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6dd339f4c..97bdeb1c2 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -81,7 +80,7 @@ static struct usb_driver acm_driver; static struct tty_driver *acm_tty_driver; static struct acm *acm_table[ACM_TTY_MINORS]; -static DEFINE_MUTEX(open_mutex); +static DECLARE_MUTEX(open_sem); #define ACM_READY(acm) (acm && acm->dev && acm->used) @@ -432,8 +431,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) int rv = -EINVAL; int i; dbg("Entering acm_tty_open.\n"); - - mutex_lock(&open_mutex); + + down(&open_sem); acm = acm_table[tty->index]; if (!acm || !acm->dev) @@ -475,14 +474,14 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) done: err_out: - mutex_unlock(&open_mutex); + up(&open_sem); return rv; full_bailout: usb_kill_urb(acm->ctrlurb); bail_out: acm->used--; - mutex_unlock(&open_mutex); + up(&open_sem); return -EIO; } @@ -508,7 +507,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) if (!acm || !acm->used) return; - mutex_lock(&open_mutex); + down(&open_sem); if (!--acm->used) { if (acm->dev) { acm_set_control(acm, acm->ctrlout = 0); @@ -519,7 +518,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) } else acm_tty_unregister(acm); } - mutex_unlock(&open_mutex); + up(&open_sem); } static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) @@ -1014,9 +1013,9 @@ static void acm_disconnect(struct usb_interface *intf) return; } - mutex_lock(&open_mutex); + down(&open_sem); if (!usb_get_intfdata(intf)) { - mutex_unlock(&open_mutex); + up(&open_sem); return; } acm->dev = NULL; @@ -1046,11 +1045,11 @@ static void acm_disconnect(struct usb_interface *intf) if (!acm->used) { acm_tty_unregister(acm); - mutex_unlock(&open_mutex); + up(&open_sem); return; } - mutex_unlock(&open_mutex); + up(&open_sem); if (acm->tty) tty_hangup(acm->tty); diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c new file mode 100644 index 000000000..f13f004d3 --- /dev/null +++ b/drivers/usb/class/usb-midi.c @@ -0,0 +1,2153 @@ +/* + usb-midi.c -- USB-MIDI driver + + Copyright (C) 2001 + NAGANO Daisuke + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This driver is based on: + - 'Universal Serial Bus Device Class Definition for MIDI Device' + - linux/drivers/sound/es1371.c, linux/drivers/usb/audio.c + - alsa/lowlevel/pci/cs64xx.c + - umidi.c for NetBSD + */ + +/* ------------------------------------------------------------------------- */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "usb-midi.h" + +/* ------------------------------------------------------------------------- */ + +/* More verbose on syslog */ +#undef MIDI_DEBUG + +#define MIDI_IN_BUFSIZ 1024 + +#define HAVE_SUPPORT_USB_MIDI_CLASS + +#undef HAVE_SUPPORT_ALSA + +/* ------------------------------------------------------------------------- */ + +static int singlebyte = 0; +module_param(singlebyte, int, 0); +MODULE_PARM_DESC(singlebyte,"Enable sending MIDI messages with single message packet"); + +static int maxdevices = 4; +module_param(maxdevices, int, 0); +MODULE_PARM_DESC(maxdevices,"Max number of allocatable MIDI device"); + +static int uvendor = -1; +module_param(uvendor, int, 0); +MODULE_PARM_DESC(uvendor, "The USB Vendor ID of a semi-compliant interface"); + +static int uproduct = -1; +module_param(uproduct, int, 0); +MODULE_PARM_DESC(uproduct, "The USB Product ID of a semi-compliant interface"); + +static int uinterface = -1; +module_param(uinterface, int, 0); +MODULE_PARM_DESC(uinterface, "The Interface number of a semi-compliant interface"); + +static int ualt = -1; +module_param(ualt, int, 0); +MODULE_PARM_DESC(ualt, "The optional alternative setting of a semi-compliant interface"); + +static int umin = -1; +module_param(umin, int, 0); +MODULE_PARM_DESC(umin, "The input endpoint of a semi-compliant interface"); + +static int umout = -1; +module_param(umout, int, 0); +MODULE_PARM_DESC(umout, "The output endpoint of a semi-compliant interface"); + +static int ucable = -1; +module_param(ucable, int, 0); +MODULE_PARM_DESC(ucable, "The cable number used for a semi-compliant interface"); + +/** Note -- the usb_string() returns only Latin-1 characters. + * (unicode chars <= 255). To support Japanese, a unicode16LE-to-EUC or + * unicode16LE-to-JIS routine is needed to wrap around usb_get_string(). + **/ +static unsigned short ulangid = 0x0409; /** 0x0411 for Japanese **/ +module_param(ulangid, ushort, 0); +MODULE_PARM_DESC(ulangid, "The optional preferred USB Language ID for all devices"); + +MODULE_AUTHOR("NAGANO Daisuke "); +MODULE_DESCRIPTION("USB-MIDI driver"); +MODULE_LICENSE("GPL"); + +/* ------------------------------------------------------------------------- */ + +/** MIDIStreaming Class-Specific Interface Descriptor Subtypes **/ + +#define MS_DESCRIPTOR_UNDEFINED 0 +#define MS_HEADER 1 +#define MIDI_IN_JACK 2 +#define MIDI_OUT_JACK 3 +/* Spec reads: ELEMENT */ +#define ELEMENT_DESCRIPTOR 4 + +#define MS_HEADER_LENGTH 7 + +/** MIDIStreaming Class-Specific Endpoint Descriptor Subtypes **/ + +#define DESCRIPTOR_UNDEFINED 0 +/* Spec reads: MS_GENERAL */ +#define MS_GENERAL_ENDPOINT 1 + +/** MIDIStreaming MIDI IN and OUT Jack Types **/ + +#define JACK_TYPE_UNDEFINED 0 +/* Spec reads: EMBEDDED */ +#define EMBEDDED_JACK 1 +/* Spec reads: EXTERNAL */ +#define EXTERNAL_JACK 2 + + +/* structure summary + + usb_midi_state usb_device + | | + *| *| per ep + in_ep out_ep + | | + *| *| per cable + min mout + | | (cable to device pairing magic) + | | + usb_midi_dev dev_id (major,minor) == file->private_data + +*/ + +/* usb_midi_state: corresponds to a USB-MIDI module */ +struct usb_midi_state { + struct list_head mididev; + + struct usb_device *usbdev; + + struct list_head midiDevList; + struct list_head inEndpointList; + struct list_head outEndpointList; + + spinlock_t lock; + + unsigned int count; /* usage counter */ +}; + +/* midi_out_endpoint: corresponds to an output endpoint */ +struct midi_out_endpoint { + struct list_head list; + + struct usb_device *usbdev; + int endpoint; + spinlock_t lock; + wait_queue_head_t wait; + + unsigned char *buf; + int bufWrPtr; + int bufSize; + + struct urb *urb; +}; + +/* midi_in_endpoint: corresponds to an input endpoint */ +struct midi_in_endpoint { + struct list_head list; + + struct usb_device *usbdev; + int endpoint; + spinlock_t lock; + wait_queue_head_t wait; + + struct usb_mididev *cables[16]; // cables open for read + int readers; // number of cables open for read + + struct urb *urb; + unsigned char *recvBuf; + int recvBufSize; + int urbSubmitted; //FIXME: == readers > 0 +}; + +/* usb_mididev: corresponds to a logical device */ +struct usb_mididev { + struct list_head list; + + struct usb_midi_state *midi; + int dev_midi; + mode_t open_mode; + + struct { + struct midi_in_endpoint *ep; + int cableId; + +// as we are pushing data from usb_bulk_read to usb_midi_read, +// we need a larger, cyclic buffer here. + unsigned char buf[MIDI_IN_BUFSIZ]; + int bufRdPtr; + int bufWrPtr; + int bufRemains; + } min; + + struct { + struct midi_out_endpoint *ep; + int cableId; + + unsigned char buf[3]; + int bufPtr; + int bufRemains; + + int isInExclusive; + unsigned char lastEvent; + } mout; + + int singlebyte; +}; + +/** Map the high nybble of MIDI voice messages to number of Message bytes. + * High nyble ranges from 0x8 to 0xe + */ + +static int remains_80e0[] = { + 3, /** 0x8X Note Off **/ + 3, /** 0x9X Note On **/ + 3, /** 0xAX Poly-key pressure **/ + 3, /** 0xBX Control Change **/ + 2, /** 0xCX Program Change **/ + 2, /** 0xDX Channel pressure **/ + 3 /** 0xEX PitchBend Change **/ +}; + +/** Map the messages to a number of Message bytes. + * + **/ +static int remains_f0f6[] = { + 0, /** 0xF0 **/ + 2, /** 0XF1 **/ + 3, /** 0XF2 **/ + 2, /** 0XF3 **/ + 2, /** 0XF4 (Undefined by MIDI Spec, and subject to change) **/ + 2, /** 0XF5 (Undefined by MIDI Spec, and subject to change) **/ + 1 /** 0XF6 **/ +}; + +/** Map the messages to a CIN (Code Index Number). + * + **/ +static int cin_f0ff[] = { + 4, /** 0xF0 System Exclusive Message Start (special cases may be 6 or 7) */ + 2, /** 0xF1 **/ + 3, /** 0xF2 **/ + 2, /** 0xF3 **/ + 2, /** 0xF4 **/ + 2, /** 0xF5 **/ + 5, /** 0xF6 **/ + 5, /** 0xF7 End of System Exclusive Message (May be 6 or 7) **/ + 5, /** 0xF8 **/ + 5, /** 0xF9 **/ + 5, /** 0xFA **/ + 5, /** 0xFB **/ + 5, /** 0xFC **/ + 5, /** 0xFD **/ + 5, /** 0xFE **/ + 5 /** 0xFF **/ +}; + +/** Map MIDIStreaming Event packet Code Index Number (low nybble of byte 0) + * to the number of bytes of valid MIDI data. + * + * CIN of 0 and 1 are NOT USED in MIDIStreaming 1.0. + * + **/ +static int cin_to_len[] = { + 0, 0, 2, 3, + 3, 1, 2, 3, + 3, 3, 3, 3, + 2, 2, 3, 1 +}; + + +/* ------------------------------------------------------------------------- */ + +static struct list_head mididevs = LIST_HEAD_INIT(mididevs); + +static DECLARE_MUTEX(open_sem); +static DECLARE_WAIT_QUEUE_HEAD(open_wait); + + +/* ------------------------------------------------------------------------- */ + +static void usb_write_callback(struct urb *urb, struct pt_regs *regs) +{ + struct midi_out_endpoint *ep = (struct midi_out_endpoint *)urb->context; + + if ( waitqueue_active( &ep->wait ) ) + wake_up_interruptible( &ep->wait ); +} + + +static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len ) +{ + struct usb_device *d; + int pipe; + int ret = 0; + int status; + int maxretry = 50; + + DECLARE_WAITQUEUE(wait,current); + init_waitqueue_head(&ep->wait); + + d = ep->usbdev; + pipe = usb_sndbulkpipe(d, ep->endpoint); + usb_fill_bulk_urb( ep->urb, d, pipe, (unsigned char*)buf, len, + usb_write_callback, ep ); + + status = usb_submit_urb(ep->urb, GFP_KERNEL); + + if (status) { + printk(KERN_ERR "usbmidi: Cannot submit urb (%d)\n",status); + ret = -EIO; + goto error; + } + + add_wait_queue( &ep->wait, &wait ); + set_current_state( TASK_INTERRUPTIBLE ); + + while( ep->urb->status == -EINPROGRESS ) { + if ( maxretry-- < 0 ) { + printk(KERN_ERR "usbmidi: usb_bulk_msg timed out\n"); + ret = -ETIME; + break; + } + interruptible_sleep_on_timeout( &ep->wait, 10 ); + } + set_current_state( TASK_RUNNING ); + remove_wait_queue( &ep->wait, &wait ); + +error: + return ret; +} + + +/** Copy data from URB to In endpoint buf. + * Discard if CIN == 0 or CIN = 1. + * + * + **/ + +static void usb_bulk_read(struct urb *urb, struct pt_regs *regs) +{ + struct midi_in_endpoint *ep = (struct midi_in_endpoint *)(urb->context); + unsigned char *data = urb->transfer_buffer; + int i, j, wake; + + if ( !ep->urbSubmitted ) { + return; + } + + if ( (urb->status == 0) && (urb->actual_length > 0) ) { + wake = 0; + spin_lock( &ep->lock ); + + for(j = 0; j < urb->actual_length; j += 4) { + int cin = (data[j]>>0)&0xf; + int cab = (data[j]>>4)&0xf; + struct usb_mididev *cable = ep->cables[cab]; + if ( cable ) { + int len = cin_to_len[cin]; /** length of MIDI data **/ + for (i = 0; i < len; i++) { + cable->min.buf[cable->min.bufWrPtr] = data[1+i+j]; + cable->min.bufWrPtr = (cable->min.bufWrPtr+1)%MIDI_IN_BUFSIZ; + if (cable->min.bufRemains < MIDI_IN_BUFSIZ) + cable->min.bufRemains += 1; + else /** need to drop data **/ + cable->min.bufRdPtr += (cable->min.bufRdPtr+1)%MIDI_IN_BUFSIZ; + wake = 1; + } + } + } + + spin_unlock ( &ep->lock ); + if ( wake ) { + wake_up( &ep->wait ); + } + } + + /* urb->dev must be reinitialized on 2.4.x kernels */ + urb->dev = ep->usbdev; + + urb->actual_length = 0; + usb_submit_urb(urb, GFP_ATOMIC); +} + + + +/* ------------------------------------------------------------------------- */ + +/* This routine must be called with spin_lock */ + +/** Wrapper around usb_write(). + * This routine must be called with spin_lock held on ep. + * Called by midiWrite(), putOneMidiEvent(), and usb_midi_write(); + **/ +static int flush_midi_buffer( struct midi_out_endpoint *ep ) +{ + int ret=0; + + if ( ep->bufWrPtr > 0 ) { + ret = usb_write( ep, ep->buf, ep->bufWrPtr ); + ep->bufWrPtr = 0; + } + + return ret; +} + + +/* ------------------------------------------------------------------------- */ + + +/** Given a MIDI Event, determine size of data to be attached to + * USB-MIDI packet. + * Returns 1, 2 or 3. + * Called by midiWrite(); + * Uses remains_80e0 and remains_f0f6; + **/ +static int get_remains(int event) +{ + int ret; + + if ( event < 0x80 ) { + ret = 1; + } else if ( event < 0xf0 ) { + ret = remains_80e0[((event-0x80)>>4)&0x0f]; + } else if ( event < 0xf7 ) { + ret = remains_f0f6[event-0xf0]; + } else { + ret = 1; + } + + return ret; +} + +/** Given the output MIDI data in the output buffer, computes a reasonable + * CIN. + * Called by putOneMidiEvent(). + **/ +static int get_CIN( struct usb_mididev *m ) +{ + int cin; + + if ( m->mout.buf[0] == 0xf7 ) { + cin = 5; + } + else if ( m->mout.buf[1] == 0xf7 ) { + cin = 6; + } + else if ( m->mout.buf[2] == 0xf7 ) { + cin = 7; + } + else { + if ( m->mout.isInExclusive == 1 ) { + cin = 4; + } else if ( m->mout.buf[0] < 0x80 ) { + /** One byte that we know nothing about. **/ + cin = 0xF; + } else if ( m->mout.buf[0] < 0xf0 ) { + /** MIDI Voice messages 0x8X to 0xEX map to cin 0x8 to 0xE. **/ + cin = (m->mout.buf[0]>>4)&0x0f; + } + else { + /** Special lookup table exists for real-time events. **/ + cin = cin_f0ff[m->mout.buf[0]-0xf0]; + } + } + + return cin; +} + + +/* ------------------------------------------------------------------------- */ + + + +/** Move data to USB endpoint buffer. + * + **/ +static int put_one_midi_event(struct usb_mididev *m) +{ + int cin; + unsigned long flags; + struct midi_out_endpoint *ep = m->mout.ep; + int ret=0; + + cin = get_CIN( m ); + if ( cin > 0x0f || cin < 0 ) { + return -EINVAL; + } + + spin_lock_irqsave( &ep->lock, flags ); + ep->buf[ep->bufWrPtr++] = (m->mout.cableId<<4) | cin; + ep->buf[ep->bufWrPtr++] = m->mout.buf[0]; + ep->buf[ep->bufWrPtr++] = m->mout.buf[1]; + ep->buf[ep->bufWrPtr++] = m->mout.buf[2]; + if ( ep->bufWrPtr >= ep->bufSize ) { + ret = flush_midi_buffer( ep ); + } + spin_unlock_irqrestore( &ep->lock, flags); + + m->mout.buf[0] = m->mout.buf[1] = m->mout.buf[2] = 0; + m->mout.bufPtr = 0; + + return ret; +} + +/** Write the MIDI message v on the midi device. + * Called by usb_midi_write(); + * Responsible for packaging a MIDI data stream into USB-MIDI packets. + **/ + +static int midi_write( struct usb_mididev *m, int v ) +{ + unsigned long flags; + struct midi_out_endpoint *ep = m->mout.ep; + int ret=0; + unsigned char c = (unsigned char)v; + unsigned char sysrt_buf[4]; + + if ( m->singlebyte != 0 ) { + /** Simple code to handle the single-byte USB-MIDI protocol. */ + spin_lock_irqsave( &ep->lock, flags ); + if ( ep->bufWrPtr+4 > ep->bufSize ) { + ret = flush_midi_buffer( ep ); + if ( !ret ) { + spin_unlock_irqrestore( &ep->lock, flags ); + return ret; + } + } + ep->buf[ep->bufWrPtr++] = (m->mout.cableId<<4) | 0x0f; /* single byte */ + ep->buf[ep->bufWrPtr++] = c; + ep->buf[ep->bufWrPtr++] = 0; + ep->buf[ep->bufWrPtr++] = 0; + if ( ep->bufWrPtr >= ep->bufSize ) { + ret = flush_midi_buffer( ep ); + } + spin_unlock_irqrestore( &ep->lock, flags ); + + return ret; + } + /** Normal USB-MIDI protocol begins here. */ + + if ( c > 0xf7 ) { /* system: Realtime messages */ + /** Realtime messages are written IMMEDIATELY. */ + sysrt_buf[0] = (m->mout.cableId<<4) | 0x0f; + sysrt_buf[1] = c; + sysrt_buf[2] = 0; + sysrt_buf[3] = 0; + spin_lock_irqsave( &ep->lock, flags ); + ret = usb_write( ep, sysrt_buf, 4 ); + spin_unlock_irqrestore( &ep->lock, flags ); + /* m->mout.lastEvent = 0; */ + + return ret; + } + + if ( c >= 0x80 ) { + if ( c < 0xf0 ) { + m->mout.lastEvent = c; + m->mout.isInExclusive = 0; + m->mout.bufRemains = get_remains(c); + } else if ( c == 0xf0 ) { + /* m->mout.lastEvent = 0; */ + m->mout.isInExclusive = 1; + m->mout.bufRemains = get_remains(c); + } else if ( c == 0xf7 && m->mout.isInExclusive == 1 ) { + /* m->mout.lastEvent = 0; */ + m->mout.isInExclusive = 0; + m->mout.bufRemains = 1; + } else if ( c > 0xf0 ) { + /* m->mout.lastEvent = 0; */ + m->mout.isInExclusive = 0; + m->mout.bufRemains = get_remains(c); + } + + } else if ( m->mout.bufRemains == 0 && m->mout.isInExclusive == 0 ) { + if ( m->mout.lastEvent == 0 ) { + return 0; /* discard, waiting for the first event */ + } + /** track status **/ + m->mout.buf[0] = m->mout.lastEvent; + m->mout.bufPtr = 1; + m->mout.bufRemains = get_remains(m->mout.lastEvent)-1; + } + + m->mout.buf[m->mout.bufPtr++] = c; + m->mout.bufRemains--; + if ( m->mout.bufRemains == 0 || m->mout.bufPtr >= 3) { + ret = put_one_midi_event(m); + } + + return ret; +} + + +/* ------------------------------------------------------------------------- */ + +/** Basic operation on /dev/midiXX as registered through struct file_operations. + * + * Basic contract: Used to change the current read/write position in a file. + * On success, the non-negative position is reported. + * On failure, the negative of an error code is reported. + * + * Because a MIDIStream is not a file, all seek operations are doomed to fail. + * + **/ +static loff_t usb_midi_llseek(struct file *file, loff_t offset, int origin) +{ + /** Tell user you cannot seek on a PIPE-like device. **/ + return -ESPIPE; +} + + +/** Basic operation on /dev/midiXX as registered through struct file_operations. + * + * Basic contract: Block until count bytes have been read or an error occurs. + * + **/ + +static ssize_t usb_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) +{ + struct usb_mididev *m = (struct usb_mididev *)file->private_data; + struct midi_in_endpoint *ep = m->min.ep; + ssize_t ret; + DECLARE_WAITQUEUE(wait, current); + + if ( !access_ok(VERIFY_READ, buffer, count) ) { + return -EFAULT; + } + if ( count == 0 ) { + return 0; + } + + add_wait_queue( &ep->wait, &wait ); + ret = 0; + while( count > 0 ) { + int cnt; + int d = (int)count; + + cnt = m->min.bufRemains; + if ( cnt > d ) { + cnt = d; + } + + if ( cnt <= 0 ) { + if ( file->f_flags & O_NONBLOCK ) { + if (!ret) + ret = -EAGAIN; + break; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (signal_pending(current)) { + if(!ret) + ret=-ERESTARTSYS; + break; + } + continue; + } + + { + int i; + unsigned long flags; /* used to synchronize access to the endpoint */ + spin_lock_irqsave( &ep->lock, flags ); + for (i = 0; i < cnt; i++) { + if ( copy_to_user( buffer+i, m->min.buf+m->min.bufRdPtr, 1 ) ) { + if ( !ret ) + ret = -EFAULT; + break; + } + m->min.bufRdPtr = (m->min.bufRdPtr+1)%MIDI_IN_BUFSIZ; + m->min.bufRemains -= 1; + } + spin_unlock_irqrestore( &ep->lock, flags ); + } + + count-=cnt; + buffer+=cnt; + ret+=cnt; + + break; + } + + remove_wait_queue( &ep->wait, &wait ); + set_current_state(TASK_RUNNING); + + return ret; +} + + +/** Basic operation on /dev/midiXX as registered through struct file_operations. + * + * Basic Contract: Take MIDI data byte-by-byte and pass it to + * writeMidi() which packages MIDI data into USB-MIDI stream. + * Then flushMidiData() is called to ensure all bytes have been written + * in a timely fashion. + * + **/ + +static ssize_t usb_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + struct usb_mididev *m = (struct usb_mididev *)file->private_data; + ssize_t ret; + unsigned long int flags; + + if ( !access_ok(VERIFY_READ, buffer, count) ) { + return -EFAULT; + } + if ( count == 0 ) { + return 0; + } + + ret = 0; + while( count > 0 ) { + unsigned char c; + + if (copy_from_user((unsigned char *)&c, buffer, 1)) { + if ( ret == 0 ) + ret = -EFAULT; + break; + } + if( midi_write(m, (int)c) ) { + if ( ret == 0 ) + ret = -EFAULT; + break; + } + count--; + buffer++; + ret++; + } + + spin_lock_irqsave( &m->mout.ep->lock, flags ); + if ( flush_midi_buffer(m->mout.ep) < 0 ) { + ret = -EFAULT; + } + spin_unlock_irqrestore( &m->mout.ep->lock, flags ); + + return ret; +} + +/** Basic operation on /dev/midiXX as registered through struct file_operations. + * + * Basic contract: Wait (spin) until ready to read or write on the file. + * + **/ +static unsigned int usb_midi_poll(struct file *file, struct poll_table_struct *wait) +{ + struct usb_mididev *m = (struct usb_mididev *)file->private_data; + struct midi_in_endpoint *iep = m->min.ep; + struct midi_out_endpoint *oep = m->mout.ep; + unsigned long flags; + unsigned int mask = 0; + + if ( file->f_mode & FMODE_READ ) { + poll_wait( file, &iep->wait, wait ); + spin_lock_irqsave( &iep->lock, flags ); + if ( m->min.bufRemains > 0 ) + mask |= POLLIN | POLLRDNORM; + spin_unlock_irqrestore( &iep->lock, flags ); + } + + if ( file->f_mode & FMODE_WRITE ) { + poll_wait( file, &oep->wait, wait ); + spin_lock_irqsave( &oep->lock, flags ); + if ( oep->bufWrPtr < oep->bufSize ) + mask |= POLLOUT | POLLWRNORM; + spin_unlock_irqrestore( &oep->lock, flags ); + } + + return mask; +} + + +/** Basic operation on /dev/midiXX as registered through struct file_operations. + * + * Basic contract: This is always the first operation performed on the + * device node. If no method is defined, the open succeeds without any + * notification given to the module. + * + **/ + +static int usb_midi_open(struct inode *inode, struct file *file) +{ + int minor = iminor(inode); + DECLARE_WAITQUEUE(wait, current); + struct usb_midi_state *s; + struct usb_mididev *m; + unsigned long flags; + int succeed = 0; + +#if 0 + printk(KERN_INFO "usb-midi: Open minor= %d.\n", minor); +#endif + + for(;;) { + down(&open_sem); + list_for_each_entry(s, &mididevs, mididev) { + list_for_each_entry(m, &s->midiDevList, list) { + if ( !((m->dev_midi ^ minor) & ~0xf) ) + goto device_found; + } + } + up(&open_sem); + return -ENODEV; + + device_found: + if ( !s->usbdev ) { + up(&open_sem); + return -EIO; + } + if ( !(m->open_mode & file->f_mode) ) { + break; + } + if ( file->f_flags & O_NONBLOCK ) { + up(&open_sem); + return -EBUSY; + } + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue( &open_wait, &wait ); + up(&open_sem); + schedule(); + remove_wait_queue( &open_wait, &wait ); + if ( signal_pending(current) ) { + return -ERESTARTSYS; + } + } + + file->private_data = m; + spin_lock_irqsave( &s->lock, flags ); + + if ( !(m->open_mode & (FMODE_READ | FMODE_WRITE)) ) { + //FIXME: intented semantics unclear here + m->min.bufRdPtr = 0; + m->min.bufWrPtr = 0; + m->min.bufRemains = 0; + spin_lock_init(&m->min.ep->lock); + + m->mout.bufPtr = 0; + m->mout.bufRemains = 0; + m->mout.isInExclusive = 0; + m->mout.lastEvent = 0; + spin_lock_init(&m->mout.ep->lock); + } + + if ( (file->f_mode & FMODE_READ) && m->min.ep != NULL ) { + unsigned long int flagsep; + spin_lock_irqsave( &m->min.ep->lock, flagsep ); + m->min.ep->cables[m->min.cableId] = m; + m->min.ep->readers += 1; + m->min.bufRdPtr = 0; + m->min.bufWrPtr = 0; + m->min.bufRemains = 0; + spin_unlock_irqrestore( &m->min.ep->lock, flagsep ); + + if ( !(m->min.ep->urbSubmitted)) { + + /* urb->dev must be reinitialized on 2.4.x kernels */ + m->min.ep->urb->dev = m->min.ep->usbdev; + + if ( usb_submit_urb(m->min.ep->urb, GFP_ATOMIC) ) { + printk(KERN_ERR "usbmidi: Cannot submit urb for MIDI-IN\n"); + } + m->min.ep->urbSubmitted = 1; + } + m->open_mode |= FMODE_READ; + succeed = 1; + } + + if ( (file->f_mode & FMODE_WRITE) && m->mout.ep != NULL ) { + m->mout.bufPtr = 0; + m->mout.bufRemains = 0; + m->mout.isInExclusive = 0; + m->mout.lastEvent = 0; + m->open_mode |= FMODE_WRITE; + succeed = 1; + } + + spin_unlock_irqrestore( &s->lock, flags ); + + s->count++; + up(&open_sem); + + /** Changed to prevent extra increments to USE_COUNT. **/ + if (!succeed) { + return -EBUSY; + } + +#if 0 + printk(KERN_INFO "usb-midi: Open Succeeded. minor= %d.\n", minor); +#endif + + return nonseekable_open(inode, file); /** Success. **/ +} + + +/** Basic operation on /dev/midiXX as registered through struct file_operations. + * + * Basic contract: Close an opened file and deallocate anything we allocated. + * Like open(), this can be missing. If open set file->private_data, + * release() must clear it. + * + **/ + +static int usb_midi_release(struct inode *inode, struct file *file) +{ + struct usb_mididev *m = (struct usb_mididev *)file->private_data; + struct usb_midi_state *s = (struct usb_midi_state *)m->midi; + +#if 0 + printk(KERN_INFO "usb-midi: Close.\n"); +#endif + + down(&open_sem); + + if ( m->open_mode & FMODE_WRITE ) { + m->open_mode &= ~FMODE_WRITE; + usb_kill_urb( m->mout.ep->urb ); + } + + if ( m->open_mode & FMODE_READ ) { + unsigned long int flagsep; + spin_lock_irqsave( &m->min.ep->lock, flagsep ); + m->min.ep->cables[m->min.cableId] = NULL; // discard cable + m->min.ep->readers -= 1; + m->open_mode &= ~FMODE_READ; + if ( m->min.ep->readers == 0 && + m->min.ep->urbSubmitted ) { + m->min.ep->urbSubmitted = 0; + usb_kill_urb(m->min.ep->urb); + } + spin_unlock_irqrestore( &m->min.ep->lock, flagsep ); + } + + s->count--; + + up(&open_sem); + wake_up(&open_wait); + + file->private_data = NULL; + return 0; +} + +static struct file_operations usb_midi_fops = { + .owner = THIS_MODULE, + .llseek = usb_midi_llseek, + .read = usb_midi_read, + .write = usb_midi_write, + .poll = usb_midi_poll, + .open = usb_midi_open, + .release = usb_midi_release, +}; + +/* ------------------------------------------------------------------------- */ + +/** Returns filled midi_in_endpoint structure or null on failure. + * + * Parameters: + * d - a usb_device + * endPoint - An usb endpoint in the range 0 to 15. + * Called by allocUsbMidiDev(); + * + **/ + +static struct midi_in_endpoint *alloc_midi_in_endpoint( struct usb_device *d, int endPoint ) +{ + struct midi_in_endpoint *ep; + int bufSize; + int pipe; + + endPoint &= 0x0f; /* Silently force endPoint to lie in range 0 to 15. */ + + pipe = usb_rcvbulkpipe( d, endPoint ); + bufSize = usb_maxpacket( d, pipe, 0 ); + /* usb_pipein() = ! usb_pipeout() = true for an in Endpoint */ + + ep = (struct midi_in_endpoint *)kmalloc(sizeof(struct midi_in_endpoint), GFP_KERNEL); + if ( !ep ) { + printk(KERN_ERR "usbmidi: no memory for midi in-endpoint\n"); + return NULL; + } + memset( ep, 0, sizeof(struct midi_in_endpoint) ); +// this sets cables[] and readers to 0, too. +// for (i=0; i<16; i++) ep->cables[i] = 0; // discard cable +// ep->readers = 0; + + ep->endpoint = endPoint; + + ep->recvBuf = (unsigned char *)kmalloc(sizeof(unsigned char)*(bufSize), GFP_KERNEL); + if ( !ep->recvBuf ) { + printk(KERN_ERR "usbmidi: no memory for midi in-endpoint buffer\n"); + kfree(ep); + return NULL; + } + + ep->urb = usb_alloc_urb(0, GFP_KERNEL); /* no ISO */ + if ( !ep->urb ) { + printk(KERN_ERR "usbmidi: no memory for midi in-endpoint urb\n"); + kfree(ep->recvBuf); + kfree(ep); + return NULL; + } + usb_fill_bulk_urb( ep->urb, d, + usb_rcvbulkpipe(d, endPoint), + (unsigned char *)ep->recvBuf, bufSize, + usb_bulk_read, ep ); + + /* ep->bufRdPtr = 0; */ + /* ep->bufWrPtr = 0; */ + /* ep->bufRemains = 0; */ + /* ep->urbSubmitted = 0; */ + ep->recvBufSize = bufSize; + + init_waitqueue_head(&ep->wait); + + return ep; +} + +static int remove_midi_in_endpoint( struct midi_in_endpoint *min ) +{ + usb_kill_urb( min->urb ); + usb_free_urb( min->urb ); + kfree( min->recvBuf ); + kfree( min ); + + return 0; +} + +/** Returns filled midi_out_endpoint structure or null on failure. + * + * Parameters: + * d - a usb_device + * endPoint - An usb endpoint in the range 0 to 15. + * Called by allocUsbMidiDev(); + * + **/ +static struct midi_out_endpoint *alloc_midi_out_endpoint( struct usb_device *d, int endPoint ) +{ + struct midi_out_endpoint *ep = NULL; + int pipe; + int bufSize; + + endPoint &= 0x0f; + pipe = usb_sndbulkpipe( d, endPoint ); + bufSize = usb_maxpacket( d, pipe, 1 ); + + ep = (struct midi_out_endpoint *)kmalloc(sizeof(struct midi_out_endpoint), GFP_KERNEL); + if ( !ep ) { + printk(KERN_ERR "usbmidi: no memory for midi out-endpoint\n"); + return NULL; + } + memset( ep, 0, sizeof(struct midi_out_endpoint) ); + + ep->endpoint = endPoint; + ep->buf = (unsigned char *)kmalloc(sizeof(unsigned char)*bufSize, GFP_KERNEL); + if ( !ep->buf ) { + printk(KERN_ERR "usbmidi: no memory for midi out-endpoint buffer\n"); + kfree(ep); + return NULL; + } + + ep->urb = usb_alloc_urb(0, GFP_KERNEL); /* no ISO */ + if ( !ep->urb ) { + printk(KERN_ERR "usbmidi: no memory for midi out-endpoint urb\n"); + kfree(ep->buf); + kfree(ep); + return NULL; + } + + ep->bufSize = bufSize; + /* ep->bufWrPtr = 0; */ + + init_waitqueue_head(&ep->wait); + + return ep; +} + + +static int remove_midi_out_endpoint( struct midi_out_endpoint *mout ) +{ + usb_kill_urb( mout->urb ); + usb_free_urb( mout->urb ); + kfree( mout->buf ); + kfree( mout ); + + return 0; +} + + +/** Returns a filled usb_mididev structure, registered as a Linux MIDI device. + * + * Returns null if memory is not available or the device cannot be registered. + * Called by allocUsbMidiDev(); + * + **/ +static struct usb_mididev *allocMidiDev( + struct usb_midi_state *s, + struct midi_in_endpoint *min, + struct midi_out_endpoint *mout, + int inCableId, + int outCableId ) +{ + struct usb_mididev *m; + + m = (struct usb_mididev *)kmalloc(sizeof(struct usb_mididev), GFP_KERNEL); + if (!m) { + printk(KERN_ERR "usbmidi: no memory for midi device\n"); + return NULL; + } + + memset(m, 0, sizeof(struct usb_mididev)); + + if ((m->dev_midi = register_sound_midi(&usb_midi_fops, -1)) < 0) { + printk(KERN_ERR "usbmidi: cannot register midi device\n"); + kfree(m); + return NULL; + } + + m->midi = s; + /* m->open_mode = 0; */ + + if ( min ) { + m->min.ep = min; + m->min.ep->usbdev = s->usbdev; + m->min.cableId = inCableId; + } + /* m->min.bufPtr = 0; */ + /* m->min.bufRemains = 0; */ + + if ( mout ) { + m->mout.ep = mout; + m->mout.ep->usbdev = s->usbdev; + m->mout.cableId = outCableId; + } + /* m->mout.bufPtr = 0; */ + /* m->mout.bufRemains = 0; */ + /* m->mout.isInExclusive = 0; */ + /* m->mout.lastEvent = 0; */ + + m->singlebyte = singlebyte; + + return m; +} + + +static void release_midi_device( struct usb_midi_state *s ) +{ + struct usb_mididev *m; + struct midi_in_endpoint *min; + struct midi_out_endpoint *mout; + + if ( s->count > 0 ) { + up(&open_sem); + return; + } + up( &open_sem ); + wake_up( &open_wait ); + + while(!list_empty(&s->inEndpointList)) { + min = list_entry(s->inEndpointList.next, struct midi_in_endpoint, list); + list_del(&min->list); + remove_midi_in_endpoint(min); + } + + while(!list_empty(&s->outEndpointList)) { + mout = list_entry(s->outEndpointList.next, struct midi_out_endpoint, list); + list_del(&mout->list); + remove_midi_out_endpoint(mout); + } + + while(!list_empty(&s->midiDevList)) { + m = list_entry(s->midiDevList.next, struct usb_mididev, list); + list_del(&m->list); + kfree(m); + } + + kfree(s); + + return; +} + + +/* ------------------------------------------------------------------------- */ + +/** Utility routine to find a descriptor in a dump of many descriptors. + * Returns start of descriptor or NULL if not found. + * descStart pointer to list of interfaces. + * descLength length (in bytes) of dump + * after (ignored if NULL) this routine returns only descriptors after "after" + * dtype (mandatory) The descriptor type. + * iface (ignored if -1) returns descriptor at/following given interface + * altSetting (ignored if -1) returns descriptor at/following given altSetting + * + * + * Called by parseDescriptor(), find_csinterface_descriptor(); + * + */ +static void *find_descriptor( void *descStart, unsigned int descLength, void *after, unsigned char dtype, int iface, int altSetting ) +{ + unsigned char *p, *end, *next; + int interfaceNumber = -1, altSet = -1; + + p = descStart; + end = p + descLength; + for( ; p < end; ) { + if ( p[0] < 2 ) + return NULL; + next = p + p[0]; + if ( next > end ) + return NULL; + if ( p[1] == USB_DT_INTERFACE ) { + if ( p[0] < USB_DT_INTERFACE_SIZE ) + return NULL; + interfaceNumber = p[2]; + altSet = p[3]; + } + if ( p[1] == dtype && + ( !after || ( p > (unsigned char *)after) ) && + ( ( iface == -1) || (iface == interfaceNumber) ) && + ( (altSetting == -1) || (altSetting == altSet) )) { + return p; + } + p = next; + } + return NULL; +} + +/** Utility to find a class-specific interface descriptor. + * dsubtype is a descriptor subtype + * Called by parseDescriptor(); + **/ +static void *find_csinterface_descriptor(void *descStart, unsigned int descLength, void *after, u8 dsubtype, int iface, int altSetting) +{ + unsigned char *p; + + p = find_descriptor( descStart, descLength, after, USB_DT_CS_INTERFACE, iface, altSetting ); + while ( p ) { + if ( p[0] >= 3 && p[2] == dsubtype ) + return p; + p = find_descriptor( descStart, descLength, p, USB_DT_CS_INTERFACE, + iface, altSetting ); + } + return NULL; +} + + +/** The magic of making a new usb_midi_device from config happens here. + * + * The caller is responsible for free-ing this return value (if not NULL). + * + **/ +static struct usb_midi_device *parse_descriptor( struct usb_device *d, unsigned char *buffer, int bufSize, unsigned int ifnum , unsigned int altSetting, int quirks) +{ + struct usb_midi_device *u; + unsigned char *p1; + unsigned char *p2; + unsigned char *next; + int iep, oep; + int length; + unsigned long longBits; + int pins, nbytes, offset, shift, jack; +#ifdef HAVE_JACK_STRINGS + /** Jacks can have associated names. **/ + unsigned char jack2string[256]; +#endif + + u = NULL; + /* find audiocontrol interface */ + p1 = find_csinterface_descriptor( buffer, bufSize, NULL, + MS_HEADER, ifnum, altSetting); + + if ( !p1 ) { + goto error_end; + } + + if ( p1[0] < MS_HEADER_LENGTH ) { + goto error_end; + } + + /* Assume success. Since the device corresponds to USB-MIDI spec, we assume + that the rest of the USB 2.0 spec is obeyed. */ + + u = (struct usb_midi_device *)kmalloc( sizeof(struct usb_midi_device), GFP_KERNEL ); + if ( !u ) { + return NULL; + } + u->deviceName = NULL; + u->idVendor = le16_to_cpu(d->descriptor.idVendor); + u->idProduct = le16_to_cpu(d->descriptor.idProduct); + u->interface = ifnum; + u->altSetting = altSetting; + u->in[0].endpoint = -1; + u->in[0].cableId = -1; + u->out[0].endpoint = -1; + u->out[0].cableId = -1; + + + printk(KERN_INFO "usb-midi: Found MIDIStreaming device corresponding to Release %d.%02d of spec.\n", + (p1[4] >> 4) * 10 + (p1[4] & 0x0f ), + (p1[3] >> 4) * 10 + (p1[3] & 0x0f ) + ); + + length = p1[5] | (p1[6] << 8); + +#ifdef HAVE_JACK_STRINGS + memset(jack2string, 0, sizeof(unsigned char) * 256); +#endif + + length -= p1[0]; + for (p2 = p1 + p1[0]; length > 0; p2 = next) { + next = p2 + p2[0]; + length -= p2[0]; + + if (p2[0] < 2 ) + break; + if (p2[1] != USB_DT_CS_INTERFACE) + break; + if (p2[2] == MIDI_IN_JACK && p2[0] >= 6 ) { + jack = p2[4]; +#ifdef HAVE_JACK_STRINGS + jack2string[jack] = p2[5]; +#endif + printk(KERN_INFO "usb-midi: Found IN Jack 0x%02x %s\n", + jack, (p2[3] == EMBEDDED_JACK)?"EMBEDDED":"EXTERNAL" ); + } else if ( p2[2] == MIDI_OUT_JACK && p2[0] >= 6) { + pins = p2[5]; + if ( p2[0] < (6 + 2 * pins) ) + continue; + jack = p2[4]; +#ifdef HAVE_JACK_STRINGS + jack2string[jack] = p2[5 + 2 * pins]; +#endif + printk(KERN_INFO "usb-midi: Found OUT Jack 0x%02x %s, %d pins\n", + jack, (p2[3] == EMBEDDED_JACK)?"EMBEDDED":"EXTERNAL", pins ); + } else if ( p2[2] == ELEMENT_DESCRIPTOR && p2[0] >= 10) { + pins = p2[4]; + if ( p2[0] < (9 + 2 * pins ) ) + continue; + nbytes = p2[8 + 2 * pins ]; + if ( p2[0] < (10 + 2 * pins + nbytes) ) + continue; + longBits = 0L; + for ( offset = 0, shift = 0; offset < nbytes && offset < 8; offset ++, shift += 8) { + longBits |= ((long)(p2[9 + 2 * pins + offset])) << shift; + } + jack = p2[3]; +#ifdef HAVE_JACK_STRINGS + jack2string[jack] = p2[9 + 2 * pins + nbytes]; +#endif + printk(KERN_INFO "usb-midi: Found ELEMENT 0x%02x, %d/%d pins in/out, bits: 0x%016lx\n", + jack, pins, (int)(p2[5 + 2 * pins]), (long)longBits ); + } else { + } + } + + iep=0; + oep=0; + + if (quirks==0) { + /* MIDISTREAM */ + p2 = NULL; + for (p1 = find_descriptor(buffer, bufSize, NULL, USB_DT_ENDPOINT, + ifnum, altSetting ); p1; p1 = next ) { + next = find_descriptor(buffer, bufSize, p1, USB_DT_ENDPOINT, + ifnum, altSetting ); + p2 = find_descriptor(buffer, bufSize, p1, USB_DT_CS_ENDPOINT, + ifnum, altSetting ); + + if ( p2 && next && ( p2 > next ) ) + p2 = NULL; + + if ( p1[0] < 9 || !p2 || p2[0] < 4 ) + continue; + + if ( (p1[2] & 0x80) == 0x80 ) { + if ( iep < 15 ) { + pins = p2[3]; /* not pins -- actually "cables" */ + if ( pins > 16 ) + pins = 16; + u->in[iep].endpoint = p1[2]; + u->in[iep].cableId = ( 1 << pins ) - 1; + if ( u->in[iep].cableId ) + iep ++; + if ( iep < 15 ) { + u->in[iep].endpoint = -1; + u->in[iep].cableId = -1; + } + } + } else { + if ( oep < 15 ) { + pins = p2[3]; /* not pins -- actually "cables" */ + if ( pins > 16 ) + pins = 16; + u->out[oep].endpoint = p1[2]; + u->out[oep].cableId = ( 1 << pins ) - 1; + if ( u->out[oep].cableId ) + oep ++; + if ( oep < 15 ) { + u->out[oep].endpoint = -1; + u->out[oep].cableId = -1; + } + } + } + + } + } else if (quirks==1) { + /* YAMAHA quirks */ + for (p1 = find_descriptor(buffer, bufSize, NULL, USB_DT_ENDPOINT, + ifnum, altSetting ); p1; p1 = next ) { + next = find_descriptor(buffer, bufSize, p1, USB_DT_ENDPOINT, + ifnum, altSetting ); + + if ( p1[0] < 7 ) + continue; + + if ( (p1[2] & 0x80) == 0x80 ) { + if ( iep < 15 ) { + pins = iep+1; + if ( pins > 16 ) + pins = 16; + u->in[iep].endpoint = p1[2]; + u->in[iep].cableId = ( 1 << pins ) - 1; + if ( u->in[iep].cableId ) + iep ++; + if ( iep < 15 ) { + u->in[iep].endpoint = -1; + u->in[iep].cableId = -1; + } + } + } else { + if ( oep < 15 ) { + pins = oep+1; + u->out[oep].endpoint = p1[2]; + u->out[oep].cableId = ( 1 << pins ) - 1; + if ( u->out[oep].cableId ) + oep ++; + if ( oep < 15 ) { + u->out[oep].endpoint = -1; + u->out[oep].cableId = -1; + } + } + } + + } + } + + if ( !iep && ! oep ) { + goto error_end; + } + + return u; + +error_end: + kfree(u); + return NULL; +} + +/* ------------------------------------------------------------------------- */ + +/** Returns number between 0 and 16. + * + **/ +static int on_bits( unsigned short v ) +{ + int i; + int ret=0; + + for ( i=0 ; i<16 ; i++ ) { + if ( v & (1<num_altsetting; + + for ( alt=0 ; altaltsetting[alt]; + epin = -1; + epout = -1; + + for ( i=0 ; idesc.bNumEndpoints ; i++ ) { + ep = &interface->endpoint[i].desc; + if ( (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ) { + continue; + } + if ( (ep->bEndpointAddress & USB_DIR_IN) && epin < 0 ) { + epin = i; + } else if ( epout < 0 ) { + epout = i; + } + if ( epin >= 0 && epout >= 0 ) { + return interface->desc.bAlternateSetting; + } + } + } + + return -ENODEV; +} + + +/* ------------------------------------------------------------------------- */ + + +/** Returns 0 if successful in allocating and registering internal structures. + * Returns negative on failure. + * Calls allocMidiDev which additionally registers /dev/midiXX devices. + * Writes messages on success to indicate which /dev/midiXX is which physical + * endpoint. + * + **/ +static int alloc_usb_midi_device( struct usb_device *d, struct usb_midi_state *s, struct usb_midi_device *u ) +{ + struct usb_mididev **mdevs=NULL; + struct midi_in_endpoint *mins[15], *min; + struct midi_out_endpoint *mouts[15], *mout; + int inDevs=0, outDevs=0; + int inEndpoints=0, outEndpoints=0; + int inEndpoint, outEndpoint; + int inCableId, outCableId; + int i; + int devices = 0; + int alt = 0; + + /* Obtain altSetting or die.. */ + alt = u->altSetting; + if ( alt < 0 ) { + alt = get_alt_setting( d, u->interface ); + } + if ( alt < 0 ) + return -ENXIO; + + /* Configure interface */ + if ( usb_set_interface( d, u->interface, alt ) < 0 ) { + return -ENXIO; + } + + for ( i = 0 ; i < 15 ; i++ ) { + mins[i] = NULL; + mouts[i] = NULL; + } + + /* Begin Allocation */ + while( inEndpoints < 15 + && inDevs < maxdevices + && u->in[inEndpoints].cableId >= 0 ) { + inDevs += on_bits((unsigned short)u->in[inEndpoints].cableId); + mins[inEndpoints] = alloc_midi_in_endpoint( d, u->in[inEndpoints].endpoint ); + if ( mins[inEndpoints] == NULL ) + goto error_end; + inEndpoints++; + } + + while( outEndpoints < 15 + && outDevs < maxdevices + && u->out[outEndpoints].cableId >= 0 ) { + outDevs += on_bits((unsigned short)u->out[outEndpoints].cableId); + mouts[outEndpoints] = alloc_midi_out_endpoint( d, u->out[outEndpoints].endpoint ); + if ( mouts[outEndpoints] == NULL ) + goto error_end; + outEndpoints++; + } + + devices = inDevs > outDevs ? inDevs : outDevs; + devices = maxdevices > devices ? devices : maxdevices; + + /* obtain space for device name (iProduct) if not known. */ + if ( ! u->deviceName ) { + mdevs = (struct usb_mididev **) + kmalloc(sizeof(struct usb_mididevs *)*devices + + sizeof(char) * 256, GFP_KERNEL); + } else { + mdevs = (struct usb_mididev **) + kmalloc(sizeof(struct usb_mididevs *)*devices, GFP_KERNEL); + } + + if ( !mdevs ) { + /* devices = 0; */ + /* mdevs = NULL; */ + goto error_end; + } + for ( i=0 ; ideviceName ) { + u->deviceName = (char *) (mdevs + devices); + if ( ! d->have_langid && d->descriptor.iProduct) { + alt = usb_get_string(d, 0, 0, u->deviceName, 250); + if (alt < 0) { + printk(KERN_INFO "error getting string descriptor 0 (error=%d)\n", alt); + } else if (u->deviceName[0] < 4) { + printk(KERN_INFO "string descriptor 0 too short (length = %d)\n", alt); + } else { + printk(KERN_INFO "string descriptor 0 found (length = %d)\n", alt); + for(; alt >= 4; alt -= 2) { + i = u->deviceName[alt-2] | (u->deviceName[alt-1]<< 8); + printk(KERN_INFO "usb-midi: langid(%d) 0x%04x\n", + (alt-4) >> 1, i); + if ( ( ( i ^ ulangid ) & 0xff ) == 0 ) { + d->have_langid = 1; + d->string_langid = i; + printk(KERN_INFO "usb-midi: langid(match) 0x%04x\n", i); + if ( i == ulangid ) + break; + } + } + } + } + u->deviceName[0] = (char) 0; + if (d->descriptor.iProduct) { + printk(KERN_INFO "usb-midi: fetchString(%d)\n", d->descriptor.iProduct); + alt = usb_string(d, d->descriptor.iProduct, u->deviceName, 255); + if( alt < 0 ) { + u->deviceName[0] = (char) 0; + } + printk(KERN_INFO "usb-midi: fetchString = %d\n", alt); + } + /* Failsafe */ + if ( !u->deviceName[0] ) { + if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_ROLAND ) { + strcpy(u->deviceName, "Unknown Roland"); + } else if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_STEINBERG ) { + strcpy(u->deviceName, "Unknown Steinberg"); + } else if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_YAMAHA ) { + strcpy(u->deviceName, "Unknown Yamaha"); + } else { + strcpy(u->deviceName, "Unknown"); + } + } + } + + inEndpoint = 0; inCableId = -1; + outEndpoint = 0; outCableId = -1; + + for ( i=0 ; iin[inEndpoint].cableId & (1<= 16 ) { + inEndpoint ++; + inCableId = 0; + } + } + min = mins[inEndpoint]; + for ( outCableId ++ ; + outEndpoint <15 + && mouts[outEndpoint] + && !(u->out[outEndpoint].cableId & (1<= 16 ) { + outEndpoint ++; + outCableId = 0; + } + } + mout = mouts[outEndpoint]; + + mdevs[i] = allocMidiDev( s, min, mout, inCableId, outCableId ); + if ( mdevs[i] == NULL ) + goto error_end; + + } + + /* Success! */ + for ( i=0 ; ilist, &s->midiDevList ); + } + for ( i=0 ; ilist, &s->inEndpointList ); + } + for ( i=0 ; ilist, &s->outEndpointList ); + } + + printk(KERN_INFO "usbmidi: found [ %s ] (0x%04x:0x%04x), attached:\n", u->deviceName, u->idVendor, u->idProduct ); + for ( i=0 ; idev_midi-2)>>4; + if ( mdevs[i]->mout.ep != NULL && mdevs[i]->min.ep != NULL ) { + printk(KERN_INFO "usbmidi: /dev/midi%02d: in (ep:%02x cid:%2d bufsiz:%2d) out (ep:%02x cid:%2d bufsiz:%2d)\n", + dm, + mdevs[i]->min.ep->endpoint|USB_DIR_IN, mdevs[i]->min.cableId, mdevs[i]->min.ep->recvBufSize, + mdevs[i]->mout.ep->endpoint, mdevs[i]->mout.cableId, mdevs[i]->mout.ep->bufSize); + } else if ( mdevs[i]->min.ep != NULL ) { + printk(KERN_INFO "usbmidi: /dev/midi%02d: in (ep:%02x cid:%2d bufsiz:%02d)\n", + dm, + mdevs[i]->min.ep->endpoint|USB_DIR_IN, mdevs[i]->min.cableId, mdevs[i]->min.ep->recvBufSize); + } else if ( mdevs[i]->mout.ep != NULL ) { + printk(KERN_INFO "usbmidi: /dev/midi%02d: out (ep:%02x cid:%2d bufsiz:%02d)\n", + dm, + mdevs[i]->mout.ep->endpoint, mdevs[i]->mout.cableId, mdevs[i]->mout.ep->bufSize); + } + } + + kfree(mdevs); + return 0; + + error_end: + if ( mdevs != NULL ) { + for ( i=0 ; idev_midi ); + kfree(mdevs[i]); + } + } + kfree(mdevs); + } + + for ( i=0 ; i<15 ; i++ ) { + if ( mins[i] != NULL ) { + remove_midi_in_endpoint( mins[i] ); + } + if ( mouts[i] != NULL ) { + remove_midi_out_endpoint( mouts[i] ); + } + } + + return -ENOMEM; +} + +/* ------------------------------------------------------------------------- */ + +/** Attempt to scan YAMAHA's device descriptor and detect correct values of + * them. + * Return 0 on succes, negative on failure. + * Called by usb_midi_probe(); + **/ + +static int detect_yamaha_device( struct usb_device *d, + struct usb_interface *iface, unsigned int ifnum, + struct usb_midi_state *s) +{ + struct usb_host_interface *interface; + struct usb_midi_device *u; + unsigned char *buffer; + int bufSize; + int i; + int alts=-1; + int ret; + + if (le16_to_cpu(d->descriptor.idVendor) != USB_VENDOR_ID_YAMAHA) { + return -EINVAL; + } + + for ( i=0 ; i < iface->num_altsetting; i++ ) { + interface = iface->altsetting + i; + + if ( interface->desc.bInterfaceClass != 255 || + interface->desc.bInterfaceSubClass != 0 ) + continue; + alts = interface->desc.bAlternateSetting; + } + if ( alts == -1 ) { + return -EINVAL; + } + + printk(KERN_INFO "usb-midi: Found YAMAHA USB-MIDI device on dev %04x:%04x, iface %d\n", + le16_to_cpu(d->descriptor.idVendor), + le16_to_cpu(d->descriptor.idProduct), ifnum); + + i = d->actconfig - d->config; + buffer = d->rawdescriptors[i]; + bufSize = le16_to_cpu(d->actconfig->desc.wTotalLength); + + u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 1); + if ( u == NULL ) { + return -EINVAL; + } + + ret = alloc_usb_midi_device( d, s, u ); + + kfree(u); + + return ret; +} + + +/** Scan table of known devices which are only partially compliant with + * the MIDIStreaming specification. + * Called by usb_midi_probe(); + * + **/ + +static int detect_vendor_specific_device( struct usb_device *d, unsigned int ifnum, struct usb_midi_state *s ) +{ + struct usb_midi_device *u; + int i; + int ret = -ENXIO; + + for ( i=0; idescriptor.idVendor) != u->idVendor || + le16_to_cpu(d->descriptor.idProduct) != u->idProduct || + ifnum != u->interface ) + continue; + + ret = alloc_usb_midi_device( d, s, u ); + break; + } + + return ret; +} + + +/** Attempt to match any config of an interface to a MIDISTREAMING interface. + * Returns 0 on success, negative on failure. + * Called by usb_midi_probe(); + **/ +static int detect_midi_subclass(struct usb_device *d, + struct usb_interface *iface, unsigned int ifnum, + struct usb_midi_state *s) +{ + struct usb_host_interface *interface; + struct usb_midi_device *u; + unsigned char *buffer; + int bufSize; + int i; + int alts=-1; + int ret; + + for ( i=0 ; i < iface->num_altsetting; i++ ) { + interface = iface->altsetting + i; + + if ( interface->desc.bInterfaceClass != USB_CLASS_AUDIO || + interface->desc.bInterfaceSubClass != USB_SUBCLASS_MIDISTREAMING ) + continue; + alts = interface->desc.bAlternateSetting; + } + if ( alts == -1 ) { + return -EINVAL; + } + + printk(KERN_INFO "usb-midi: Found MIDISTREAMING on dev %04x:%04x, iface %d\n", + le16_to_cpu(d->descriptor.idVendor), + le16_to_cpu(d->descriptor.idProduct), ifnum); + + + /* From USB Spec v2.0, Section 9.5. + If the class or vendor specific descriptors use the same format + as standard descriptors (e.g., start with a length byte and + followed by a type byte), they must be returned interleaved with + standard descriptors in the configuration information returned by + a GetDescriptor(Configuration) request. In this case, the class + or vendor-specific descriptors must follow a related standard + descriptor they modify or extend. + */ + + i = d->actconfig - d->config; + buffer = d->rawdescriptors[i]; + bufSize = le16_to_cpu(d->actconfig->desc.wTotalLength); + + u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 0); + if ( u == NULL ) { + return -EINVAL; + } + + ret = alloc_usb_midi_device( d, s, u ); + + kfree(u); + + return ret; +} + + +/** When user has requested a specific device, match it exactly. + * + * Uses uvendor, uproduct, uinterface, ualt, umin, umout and ucable. + * Called by usb_midi_probe(); + * + **/ +static int detect_by_hand(struct usb_device *d, unsigned int ifnum, struct usb_midi_state *s) +{ + struct usb_midi_device u; + + if ( le16_to_cpu(d->descriptor.idVendor) != uvendor || + le16_to_cpu(d->descriptor.idProduct) != uproduct || + ifnum != uinterface ) { + return -EINVAL; + } + + if ( ualt < 0 ) + ualt = -1; + + if ( umin < 0 || umin > 15 ) + umin = 0x01 | USB_DIR_IN; + if ( umout < 0 || umout > 15 ) + umout = 0x01; + if ( ucable < 0 || ucable > 15 ) + ucable = 0; + + u.deviceName = NULL; /* A flag for alloc_usb_midi_device to get device + name from device. */ + u.idVendor = uvendor; + u.idProduct = uproduct; + u.interface = uinterface; + u.altSetting = ualt; + + u.in[0].endpoint = umin; + u.in[0].cableId = (1<cur_altsetting->desc.bInterfaceNumber; + + s = (struct usb_midi_state *)kmalloc(sizeof(struct usb_midi_state), GFP_KERNEL); + if ( !s ) + return -ENOMEM; + + memset( s, 0, sizeof(struct usb_midi_state) ); + INIT_LIST_HEAD(&s->midiDevList); + INIT_LIST_HEAD(&s->inEndpointList); + INIT_LIST_HEAD(&s->outEndpointList); + s->usbdev = dev; + s->count = 0; + spin_lock_init(&s->lock); + + if ( + detect_by_hand( dev, ifnum, s ) && + detect_midi_subclass( dev, intf, ifnum, s ) && + detect_vendor_specific_device( dev, ifnum, s ) && + detect_yamaha_device( dev, intf, ifnum, s) ) { + kfree(s); + return -EIO; + } + + down(&open_sem); + list_add_tail(&s->mididev, &mididevs); + up(&open_sem); + + usb_set_intfdata (intf, s); + return 0; +} + + +static void usb_midi_disconnect(struct usb_interface *intf) +{ + struct usb_midi_state *s = usb_get_intfdata (intf); + struct usb_mididev *m; + + if ( !s ) + return; + + if ( s == (struct usb_midi_state *)-1 ) { + return; + } + if ( !s->usbdev ) { + return; + } + down(&open_sem); + list_del(&s->mididev); + INIT_LIST_HEAD(&s->mididev); + s->usbdev = NULL; + usb_set_intfdata (intf, NULL); + + list_for_each_entry(m, &s->midiDevList, list) { + wake_up(&(m->min.ep->wait)); + wake_up(&(m->mout.ep->wait)); + if ( m->dev_midi >= 0 ) { + unregister_sound_midi(m->dev_midi); + } + m->dev_midi = -1; + } + release_midi_device(s); + wake_up(&open_wait); +} + +/* we want to look at all devices by hand */ +static struct usb_device_id id_table[] = { + {.driver_info = 42}, + {} +}; + +static struct usb_driver usb_midi_driver = { + .name = "midi", + .probe = usb_midi_probe, + .disconnect = usb_midi_disconnect, + .id_table = id_table, +}; + +/* ------------------------------------------------------------------------- */ + +static int __init usb_midi_init(void) +{ + return usb_register(&usb_midi_driver); +} + +static void __exit usb_midi_exit(void) +{ + usb_deregister(&usb_midi_driver); +} + +module_init(usb_midi_init) ; +module_exit(usb_midi_exit) ; + +#ifdef HAVE_ALSA_SUPPORT +#define SNDRV_MAIN_OBJECT_FILE +#include "../../include/driver.h" +#include "../../include/control.h" +#include "../../include/info.h" +#include "../../include/cs46xx.h" + +/* ------------------------------------------------------------------------- */ + +static int snd_usbmidi_input_close(snd_rawmidi_substream_t * substream) +{ + return 0; +} + +static int snd_usbmidi_input_open(snd_rawmidi_substream_t * substream ) +{ + return 0; +} + +static void snd_usbmidi_input_trigger(snd_rawmidi_substream_t * substream, int up) +{ + return 0; +} + + +/* ------------------------------------------------------------------------- */ + +static int snd_usbmidi_output_close(snd_rawmidi_substream_t * substream) +{ + return 0; +} + +static int snd_usbmidi_output_open(snd_rawmidi_substream_t * substream) +{ + return 0; +} + +static void snd_usb_midi_output_trigger(snd_rawmidi_substream_t * substream, + int up) +{ + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static snd_rawmidi_ops_t snd_usbmidi_output = +{ + .open = snd_usbmidi_output_open, + .close = snd_usbmidi_output_close, + .trigger = snd_usbmidi_output_trigger, +}; +static snd_rawmidi_ops_t snd_usbmidi_input = +{ + .open = snd_usbmidi_input_open, + .close = snd_usbmidi_input_close, + .trigger = snd_usbmidi_input_trigger, +}; + +int snd_usbmidi_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rrawmidi) +{ + snd_rawmidi_t *rmidi; + int err; + + if (rrawmidi) + *rrawmidi = NULL; + if ((err = snd_rawmidi_new(chip->card, "USB-MIDI", device, 1, 1, &rmidi)) < 0) + return err; + strcpy(rmidi->name, "USB-MIDI"); + + snd_rawmidi_set_ops( rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output ); + snd_rawmidi_set_ops( rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_usbmidi_input ); + + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; + + rmidi->private_data = chip; + chip->rmidi = rmidi; + if (rrawmidi) + *rrawmidi = NULL; + + return 0; +} + +int snd_usbmidi_create( snd_card_t * card, + struct pci_dev * pci, + usbmidi_t ** rchip ) +{ + usbmidi_t *chip; + int err, idx; + snd_region_t *region; + static snd_device_opt_t ops = { + .dev_free = snd_usbmidi_dev_free, + }; + + *rchip = NULL; + chip = snd_magic_kcalloc( usbmidi_t, 0, GFP_KERNEL ); + if ( chip == NULL ) + return -ENOMEM; +} + +EXPORT_SYMBOL(snd_usbmidi_create); +EXPORT_SYMBOL(snd_usbmidi_midi); +#endif /* HAVE_ALSA_SUPPORT */ + diff --git a/drivers/usb/class/usb-midi.h b/drivers/usb/class/usb-midi.h new file mode 100644 index 000000000..358cdef84 --- /dev/null +++ b/drivers/usb/class/usb-midi.h @@ -0,0 +1,164 @@ +/* + usb-midi.h -- USB-MIDI driver + + Copyright (C) 2001 + NAGANO Daisuke + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ------------------------------------------------------------------------- */ + +#ifndef _USB_MIDI_H_ +#define _USB_MIDI_H_ + +#ifndef USB_SUBCLASS_MIDISTREAMING +#define USB_SUBCLASS_MIDISTREAMING 3 +#endif + +/* ------------------------------------------------------------------------- */ +/* Roland MIDI Devices */ + +#define USB_VENDOR_ID_ROLAND 0x0582 +#define USBMIDI_ROLAND_UA100G 0x0000 +#define USBMIDI_ROLAND_MPU64 0x0002 +#define USBMIDI_ROLAND_SC8850 0x0003 +#define USBMIDI_ROLAND_SC8820 0x0007 +#define USBMIDI_ROLAND_UM2 0x0005 +#define USBMIDI_ROLAND_UM1 0x0009 +#define USBMIDI_ROLAND_PC300 0x0008 + +/* YAMAHA MIDI Devices */ +#define USB_VENDOR_ID_YAMAHA 0x0499 +#define USBMIDI_YAMAHA_MU1000 0x1001 + +/* Steinberg MIDI Devices */ +#define USB_VENDOR_ID_STEINBERG 0x0763 +#define USBMIDI_STEINBERG_USB2MIDI 0x1001 + +/* Mark of the Unicorn MIDI Devices */ +#define USB_VENDOR_ID_MOTU 0x07fd +#define USBMIDI_MOTU_FASTLANE 0x0001 + +/* ------------------------------------------------------------------------- */ +/* Supported devices */ + +struct usb_midi_endpoint { + int endpoint; + int cableId; /* if bit-n == 1 then cableId-n is enabled (n: 0 - 15) */ +}; + +struct usb_midi_device { + char *deviceName; + + u16 idVendor; + u16 idProduct; + int interface; + int altSetting; /* -1: auto detect */ + + struct usb_midi_endpoint in[15]; + struct usb_midi_endpoint out[15]; +}; + +static struct usb_midi_device usb_midi_devices[] = { + { /* Roland UM-1 */ + "Roland UM-1", + USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM1, 2, -1, + { { 0x81, 1 }, {-1, -1} }, + { { 0x01, 1,}, {-1, -1} }, + }, + + { /* Roland UM-2 */ + "Roland UM-2" , + USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM2, 2, -1, + { { 0x81, 3 }, {-1, -1} }, + { { 0x01, 3,}, {-1, -1} }, + }, + +/** Next entry courtesy research by Michael Minn **/ + { /* Roland UA-100 */ + "Roland UA-100", + USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UA100G, 2, -1, + { { 0x82, 7 }, {-1, -1} }, /** cables 0,1 and 2 for SYSEX **/ + { { 0x02, 7 }, {-1, -1} }, + }, + +/** Next entry courtesy research by Michael Minn **/ + { /* Roland SC8850 */ + "Roland SC8850", + USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8850, 2, -1, + { { 0x81, 0x3f }, {-1, -1} }, + { { 0x01, 0x3f }, {-1, -1} }, + }, + + { /* Roland SC8820 */ + "Roland SC8820", + USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8820, 2, -1, + { { 0x81, 0x13 }, {-1, -1} }, + { { 0x01, 0x13 }, {-1, -1} }, + }, + + { /* Roland SC8820 */ + "Roland SC8820", + USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8820, 2, -1, + { { 0x81, 17 }, {-1, -1} }, + { { 0x01, 17 }, {-1, -1} }, + }, + + { /* YAMAHA MU1000 */ + "YAMAHA MU1000", + USB_VENDOR_ID_YAMAHA, USBMIDI_YAMAHA_MU1000, 0, -1, + { { 0x81, 1 }, {-1, -1} }, + { { 0x01, 15 }, {-1, -1} }, + }, + { /* Roland PC-300 */ + "Roland PC-300", + USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_PC300, 2, -1, + { { 0x81, 1 }, {-1, -1} }, + { { 0x01, 1 }, {-1, -1} }, + }, + { /* MOTU Fastlane USB */ + "MOTU Fastlane USB", + USB_VENDOR_ID_MOTU, USBMIDI_MOTU_FASTLANE, 1, 0, + { { 0x82, 3 }, {-1, -1} }, + { { 0x02, 3 }, {-1, -1} }, + } +}; + +#define VENDOR_SPECIFIC_USB_MIDI_DEVICES (sizeof(usb_midi_devices)/sizeof(struct usb_midi_device)) + +/* for Hot-Plugging */ + +static struct usb_device_id usb_midi_ids [] = { + { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), + .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING}, + { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM1 ) }, + { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM2 ) }, + { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UA100G ) }, + { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_PC300 ) }, + { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8850 ) }, + { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8820 ) }, + { USB_DEVICE( USB_VENDOR_ID_YAMAHA, USBMIDI_YAMAHA_MU1000 ) }, + { USB_DEVICE( USB_VENDOR_ID_MOTU, USBMIDI_MOTU_FASTLANE ) }, +/* { USB_DEVICE( USB_VENDOR_ID_STEINBERG, USBMIDI_STEINBERG_USB2MIDI ) },*/ + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, usb_midi_ids); + +/* ------------------------------------------------------------------------- */ +#endif /* _USB_MIDI_H_ */ + + diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 48dee4b8d..cc03f6875 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -55,7 +55,6 @@ #include #include #include -#include #undef DEBUG #include @@ -224,7 +223,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp); /* forward reference to make our lives easier */ static struct usb_driver usblp_driver; -static DEFINE_MUTEX(usblp_mutex); /* locks the existence of usblp's */ +static DECLARE_MUTEX(usblp_sem); /* locks the existence of usblp's */ /* * Functions for usblp control messages. @@ -352,7 +351,7 @@ static int usblp_open(struct inode *inode, struct file *file) if (minor < 0) return -ENODEV; - mutex_lock (&usblp_mutex); + down (&usblp_sem); retval = -ENODEV; intf = usb_find_interface(&usblp_driver, minor); @@ -400,7 +399,7 @@ static int usblp_open(struct inode *inode, struct file *file) } } out: - mutex_unlock (&usblp_mutex); + up (&usblp_sem); return retval; } @@ -426,13 +425,13 @@ static int usblp_release(struct inode *inode, struct file *file) { struct usblp *usblp = file->private_data; - mutex_lock (&usblp_mutex); + down (&usblp_sem); usblp->used = 0; if (usblp->present) { usblp_unlink_urbs(usblp); } else /* finish cleanup from disconnect */ usblp_cleanup (usblp); - mutex_unlock (&usblp_mutex); + up (&usblp_sem); return 0; } @@ -701,6 +700,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t usblp->wcomplete = 0; err = usb_submit_urb(usblp->writeurb, GFP_KERNEL); if (err) { + usblp->wcomplete = 1; if (err != -ENOMEM) count = -EIO; else @@ -1153,7 +1153,7 @@ static void usblp_disconnect(struct usb_interface *intf) device_remove_file(&intf->dev, &dev_attr_ieee1284_id); - mutex_lock (&usblp_mutex); + down (&usblp_sem); down (&usblp->sem); usblp->present = 0; usb_set_intfdata (intf, NULL); @@ -1167,7 +1167,7 @@ static void usblp_disconnect(struct usb_interface *intf) if (!usblp->used) usblp_cleanup (usblp); - mutex_unlock (&usblp_mutex); + up (&usblp_sem); } static struct usb_device_id usblp_ids [] = { diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index a08787e25..ff03184da 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -99,11 +99,4 @@ config USB_OTG_WHITELIST normal Linux-USB hosts do (other than the warning), and is convenient for many stages of product development. -config USB_OTG_BLACKLIST_HUB - bool "Disable external hubs" - depends on USB_OTG - help - If you say Y here, then Linux will refuse to enumerate - external hubs. OTG hosts are allowed to reduce hardware - and software costs by not supporting external hubs. diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index c0f37343a..2684e15b8 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -57,7 +57,6 @@ #include #include #include -#include #include #include "usb.h" @@ -571,7 +570,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte if (!access_ok(VERIFY_WRITE, buf, nbytes)) return -EFAULT; - mutex_lock(&usb_bus_list_lock); + down (&usb_bus_list_lock); /* print devices for all busses */ list_for_each_entry(bus, &usb_bus_list, bus_list) { /* recurse through all children of the root hub */ @@ -581,12 +580,12 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0); usb_unlock_device(bus->root_hub); if (ret < 0) { - mutex_unlock(&usb_bus_list_lock); + up(&usb_bus_list_lock); return ret; } total_written += ret; } - mutex_unlock(&usb_bus_list_lock); + up (&usb_bus_list_lock); return total_written; } diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 545da37af..2b68998fe 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -134,21 +134,26 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l } if (pos < sizeof(struct usb_device_descriptor)) { - struct usb_device_descriptor temp_desc ; /* 18 bytes - fits on the stack */ - - memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor)); - le16_to_cpus(&temp_desc.bcdUSB); - le16_to_cpus(&temp_desc.idVendor); - le16_to_cpus(&temp_desc.idProduct); - le16_to_cpus(&temp_desc.bcdDevice); + struct usb_device_descriptor *desc = kmalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) { + ret = -ENOMEM; + goto err; + } + memcpy(desc, &dev->descriptor, sizeof(dev->descriptor)); + le16_to_cpus(&desc->bcdUSB); + le16_to_cpus(&desc->idVendor); + le16_to_cpus(&desc->idProduct); + le16_to_cpus(&desc->bcdDevice); len = sizeof(struct usb_device_descriptor) - pos; if (len > nbytes) len = nbytes; - if (copy_to_user(buf, ((char *)&temp_desc) + pos, len)) { + if (copy_to_user(buf, ((char *)desc) + pos, len)) { + kfree(desc); ret = -EFAULT; goto err; } + kfree(desc); *ppos += len; buf += len; @@ -493,8 +498,7 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig { int ret = 0; - if (ps->dev->state != USB_STATE_ADDRESS - && ps->dev->state != USB_STATE_CONFIGURED) + if (ps->dev->state != USB_STATE_CONFIGURED) return -EHOSTUNREACH; if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) return 0; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c196f3845..dce9d987f 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -378,7 +378,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface, return NULL; } -EXPORT_SYMBOL_GPL_FUTURE(usb_match_id); +EXPORT_SYMBOL(usb_match_id); int usb_device_match(struct device *dev, struct device_driver *drv) { @@ -446,7 +446,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner) return retval; } -EXPORT_SYMBOL_GPL_FUTURE(usb_register_driver); +EXPORT_SYMBOL(usb_register_driver); /** * usb_deregister - unregister a USB driver @@ -469,4 +469,4 @@ void usb_deregister(struct usb_driver *driver) usbfs_update_special(); } -EXPORT_SYMBOL_GPL_FUTURE(usb_deregister); +EXPORT_SYMBOL(usb_deregister); diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index b263a54a1..37b13368c 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -24,15 +24,15 @@ #include "usb.h" #define MAX_USB_MINORS 256 -static const struct file_operations *usb_minors[MAX_USB_MINORS]; +static struct file_operations *usb_minors[MAX_USB_MINORS]; static DEFINE_SPINLOCK(minor_lock); static int usb_open(struct inode * inode, struct file * file) { int minor = iminor(inode); - const struct file_operations *c; + struct file_operations *c; int err = -ENODEV; - const struct file_operations *old_fops, *new_fops = NULL; + struct file_operations *old_fops, *new_fops = NULL; spin_lock (&minor_lock); c = usb_minors[minor]; diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 66b78404a..29b5b2a6e 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -213,9 +213,11 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) if (hcd->driver->suspend) { retval = hcd->driver->suspend(hcd, message); - suspend_report_result(hcd->driver->suspend, retval); - if (retval) + if (retval) { + dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n", + retval); goto done; + } } synchronize_irq(dev->irq); @@ -261,21 +263,15 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) * some device state (e.g. as part of clock reinit). */ retval = pci_set_power_state (dev, PCI_D3hot); - suspend_report_result(pci_set_power_state, retval); if (retval == 0) { - int wake = device_can_wakeup(&hcd->self.root_hub->dev); - - wake = wake && device_may_wakeup(hcd->self.controller); - - dev_dbg (hcd->self.controller, "--> PCI D3%s\n", - wake ? "/wakeup" : ""); + dev_dbg (hcd->self.controller, "--> PCI D3\n"); /* Ignore these return values. We rely on pci code to * reject requests the hardware can't implement, rather * than coding the same thing. */ - (void) pci_enable_wake (dev, PCI_D3hot, wake); - (void) pci_enable_wake (dev, PCI_D3cold, wake); + (void) pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); + (void) pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); } else { dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", retval); @@ -295,7 +291,7 @@ done: #ifdef CONFIG_PPC_PMAC /* Disable ASIC clocks for USB */ - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; of_node = pci_device_to_OF_node (dev); @@ -330,7 +326,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev) #ifdef CONFIG_PPC_PMAC /* Reenable ASIC clocks for USB */ - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; of_node = pci_device_to_OF_node (dev); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index e2e00ba4e..9e82afc33 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -94,7 +93,7 @@ struct usb_busmap { static struct usb_busmap busmap; /* used when updating list of hcds */ -DEFINE_MUTEX(usb_bus_list_lock); /* exported only for usbfs */ +DECLARE_MUTEX (usb_bus_list_lock); /* exported only for usbfs */ EXPORT_SYMBOL_GPL (usb_bus_list_lock); /* used for controlling access to virtual root hubs */ @@ -345,7 +344,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) struct usb_ctrlrequest *cmd; u16 typeReq, wValue, wIndex, wLength; u8 *ubuf = urb->transfer_buffer; - u8 tbuf [sizeof (struct usb_hub_descriptor)]; + u8 tbuf [sizeof (struct usb_hub_descriptor)] + __attribute__((aligned(4))); const u8 *bufp = tbuf; int len = 0; int patch_wakeup = 0; @@ -367,39 +367,21 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) /* DEVICE REQUESTS */ - /* The root hub's remote wakeup enable bit is implemented using - * driver model wakeup flags. If this system supports wakeup - * through USB, userspace may change the default "allow wakeup" - * policy through sysfs or these calls. - * - * Most root hubs support wakeup from downstream devices, for - * runtime power management (disabling USB clocks and reducing - * VBUS power usage). However, not all of them do so; silicon, - * board, and BIOS bugs here are not uncommon, so these can't - * be treated quite like external hubs. - * - * Likewise, not all root hubs will pass wakeup events upstream, - * to wake up the whole system. So don't assume root hub and - * controller capabilities are identical. - */ - case DeviceRequest | USB_REQ_GET_STATUS: - tbuf [0] = (device_may_wakeup(&hcd->self.root_hub->dev) - << USB_DEVICE_REMOTE_WAKEUP) + tbuf [0] = (hcd->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP) | (1 << USB_DEVICE_SELF_POWERED); tbuf [1] = 0; len = 2; break; case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: if (wValue == USB_DEVICE_REMOTE_WAKEUP) - device_set_wakeup_enable(&hcd->self.root_hub->dev, 0); + hcd->remote_wakeup = 0; else goto error; break; case DeviceOutRequest | USB_REQ_SET_FEATURE: - if (device_can_wakeup(&hcd->self.root_hub->dev) - && wValue == USB_DEVICE_REMOTE_WAKEUP) - device_set_wakeup_enable(&hcd->self.root_hub->dev, 1); + if (hcd->can_wakeup && wValue == USB_DEVICE_REMOTE_WAKEUP) + hcd->remote_wakeup = 1; else goto error; break; @@ -428,7 +410,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) bufp = fs_rh_config_descriptor; len = sizeof fs_rh_config_descriptor; } - if (device_can_wakeup(&hcd->self.root_hub->dev)) + if (hcd->can_wakeup) patch_wakeup = 1; break; case USB_DT_STRING << 8: @@ -780,14 +762,14 @@ static int usb_register_bus(struct usb_bus *bus) { int busnum; - mutex_lock(&usb_bus_list_lock); + down (&usb_bus_list_lock); busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); if (busnum < USB_MAXBUS) { set_bit (busnum, busmap.busmap); bus->busnum = busnum; } else { printk (KERN_ERR "%s: too many buses\n", usbcore_name); - mutex_unlock(&usb_bus_list_lock); + up(&usb_bus_list_lock); return -E2BIG; } @@ -795,7 +777,7 @@ static int usb_register_bus(struct usb_bus *bus) bus->controller, "usb_host%d", busnum); if (IS_ERR(bus->class_dev)) { clear_bit(busnum, busmap.busmap); - mutex_unlock(&usb_bus_list_lock); + up(&usb_bus_list_lock); return PTR_ERR(bus->class_dev); } @@ -803,7 +785,7 @@ static int usb_register_bus(struct usb_bus *bus) /* Add it to the local list of buses */ list_add (&bus->bus_list, &usb_bus_list); - mutex_unlock(&usb_bus_list_lock); + up (&usb_bus_list_lock); usb_notify_add_bus(bus); @@ -828,9 +810,9 @@ static void usb_deregister_bus (struct usb_bus *bus) * controller code, as well as having it call this when cleaning * itself up */ - mutex_lock(&usb_bus_list_lock); + down (&usb_bus_list_lock); list_del (&bus->bus_list); - mutex_unlock(&usb_bus_list_lock); + up (&usb_bus_list_lock); usb_notify_remove_bus(bus); @@ -841,17 +823,18 @@ static void usb_deregister_bus (struct usb_bus *bus) /** * register_root_hub - called by usb_add_hcd() to register a root hub + * @usb_dev: the usb root hub device to be registered. * @hcd: host controller for this root hub * * This function registers the root hub with the USB subsystem. It sets up - * the device properly in the device tree and then calls usb_new_device() - * to register the usb device. It also assigns the root hub's USB address - * (always 1). + * the device properly in the device tree and stores the root_hub pointer + * in the bus structure, then calls usb_new_device() to register the usb + * device. It also assigns the root hub's USB address (always 1). */ -static int register_root_hub(struct usb_hcd *hcd) +static int register_root_hub (struct usb_device *usb_dev, + struct usb_hcd *hcd) { struct device *parent_dev = hcd->self.controller; - struct usb_device *usb_dev = hcd->self.root_hub; const int devnum = 1; int retval; @@ -862,12 +845,14 @@ static int register_root_hub(struct usb_hcd *hcd) set_bit (devnum, usb_dev->bus->devmap.devicemap); usb_set_device_state(usb_dev, USB_STATE_ADDRESS); - mutex_lock(&usb_bus_list_lock); + down (&usb_bus_list_lock); + usb_dev->bus->root_hub = usb_dev; usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); if (retval != sizeof usb_dev->descriptor) { - mutex_unlock(&usb_bus_list_lock); + usb_dev->bus->root_hub = NULL; + up (&usb_bus_list_lock); dev_dbg (parent_dev, "can't read %s device descriptor %d\n", usb_dev->dev.bus_id, retval); return (retval < 0) ? retval : -EMSGSIZE; @@ -875,10 +860,11 @@ static int register_root_hub(struct usb_hcd *hcd) retval = usb_new_device (usb_dev); if (retval) { + usb_dev->bus->root_hub = NULL; dev_err (parent_dev, "can't register root hub for %s, %d\n", usb_dev->dev.bus_id, retval); } - mutex_unlock(&usb_bus_list_lock); + up (&usb_bus_list_lock); if (retval == 0) { spin_lock_irq (&hcd_root_hub_lock); @@ -1105,6 +1091,7 @@ static void urb_unlink (struct urb *urb) spin_lock_irqsave (&hcd_data_lock, flags); list_del_init (&urb->urb_list); spin_unlock_irqrestore (&hcd_data_lock, flags); + usb_put_dev (urb->dev); } @@ -1144,6 +1131,7 @@ static int hcd_submit_urb (struct urb *urb, gfp_t mem_flags) case HC_STATE_RUNNING: case HC_STATE_RESUMING: doit: + usb_get_dev (urb->dev); list_add_tail (&urb->urb_list, &ep->urb_list); status = 0; break; @@ -1784,10 +1772,12 @@ int usb_add_hcd(struct usb_hcd *hcd, set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - /* HC is in reset state, but accessible. Now do the one-time init, - * bottom up so that hcds can customize the root hubs before khubd - * starts talking to them. (Note, bus id is assigned early too.) - */ + /* till now HC has been in an indeterminate state ... */ + if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) { + dev_err(hcd->self.controller, "can't reset\n"); + return retval; + } + if ((retval = hcd_buffer_create(hcd)) != 0) { dev_dbg(hcd->self.controller, "pool alloc failed\n"); return retval; @@ -1796,35 +1786,6 @@ int usb_add_hcd(struct usb_hcd *hcd, if ((retval = usb_register_bus(&hcd->self)) < 0) goto err_register_bus; - if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) { - dev_err(hcd->self.controller, "unable to allocate root hub\n"); - retval = -ENOMEM; - goto err_allocate_root_hub; - } - rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : - USB_SPEED_FULL; - hcd->self.root_hub = rhdev; - - /* wakeup flag init defaults to "everything works" for root hubs, - * but drivers can override it in reset() if needed, along with - * recording the overall controller's system wakeup capability. - */ - device_init_wakeup(&rhdev->dev, 1); - - /* "reset" is misnamed; its role is now one-time init. the controller - * should already have been reset (and boot firmware kicked off etc). - */ - if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) { - dev_err(hcd->self.controller, "can't setup\n"); - goto err_hcd_driver_setup; - } - - /* NOTE: root hub and controller capabilities may not be the same */ - if (device_can_wakeup(hcd->self.controller) - && device_can_wakeup(&hcd->self.root_hub->dev)) - dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); - - /* enable irqs just before we start the controller */ if (hcd->driver->irq) { char buf[8], *bufp = buf; @@ -1856,32 +1817,56 @@ int usb_add_hcd(struct usb_hcd *hcd, (unsigned long long)hcd->rsrc_start); } + /* Allocate the root hub before calling hcd->driver->start(), + * but don't register it until afterward so that the hardware + * is running. + */ + if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) { + dev_err(hcd->self.controller, "unable to allocate root hub\n"); + retval = -ENOMEM; + goto err_allocate_root_hub; + } + + /* Although in principle hcd->driver->start() might need to use rhdev, + * none of the current drivers do. + */ if ((retval = hcd->driver->start(hcd)) < 0) { dev_err(hcd->self.controller, "startup error %d\n", retval); goto err_hcd_driver_start; } - /* starting here, usbcore will pay attention to this root hub */ + /* hcd->driver->start() reported can_wakeup, probably with + * assistance from board's boot firmware. + * NOTE: normal devices won't enable wakeup by default. + */ + if (hcd->can_wakeup) + dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); + hcd->remote_wakeup = hcd->can_wakeup; + + rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : + USB_SPEED_FULL; rhdev->bus_mA = min(500u, hcd->power_budget); - if ((retval = register_root_hub(hcd)) != 0) + if ((retval = register_root_hub(rhdev, hcd)) != 0) goto err_register_root_hub; if (hcd->uses_new_polling && hcd->poll_rh) usb_hcd_poll_rh_status(hcd); return retval; -err_register_root_hub: + err_register_root_hub: hcd->driver->stop(hcd); -err_hcd_driver_start: + + err_hcd_driver_start: + usb_put_dev(rhdev); + + err_allocate_root_hub: if (hcd->irq >= 0) free_irq(irqnum, hcd); -err_request_irq: -err_hcd_driver_setup: - hcd->self.root_hub = NULL; - usb_put_dev(rhdev); -err_allocate_root_hub: + + err_request_irq: usb_deregister_bus(&hcd->self); -err_register_bus: + + err_register_bus: hcd_buffer_destroy(hcd); return retval; } @@ -1907,9 +1892,9 @@ void usb_remove_hcd(struct usb_hcd *hcd) hcd->rh_registered = 0; spin_unlock_irq (&hcd_root_hub_lock); - mutex_lock(&usb_bus_list_lock); + down(&usb_bus_list_lock); usb_disconnect(&hcd->self.root_hub); - mutex_unlock(&usb_bus_list_lock); + up(&usb_bus_list_lock); hcd->poll_rh = 0; del_timer_sync(&hcd->rh_timer); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 7022aafb2..591b5aad1 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -78,6 +78,8 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */ #define HCD_FLAG_HW_ACCESSIBLE 0x00000001 #define HCD_FLAG_SAW_IRQ 0x00000002 + unsigned can_wakeup:1; /* hw supports wakeup? */ + unsigned remote_wakeup:1;/* sw should use wakeup? */ unsigned rh_registered:1;/* is root hub registered? */ /* The next flag is a stopgap, to be removed when all the HCDs @@ -362,7 +364,7 @@ extern void usb_set_device_state(struct usb_device *udev, /* exported only within usbcore */ extern struct list_head usb_bus_list; -extern struct mutex usb_bus_list_lock; +extern struct semaphore usb_bus_list_lock; extern wait_queue_head_t usb_kill_urb_queue; extern struct usb_bus *usb_bus_get (struct usb_bus *bus); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 90b8d43c6..650d5ee58 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -836,13 +835,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) desc = intf->cur_altsetting; hdev = interface_to_usbdev(intf); -#ifdef CONFIG_USB_OTG_BLACKLIST_HUB - if (hdev->parent) { - dev_warn(&intf->dev, "ignoring external hub\n"); - return -ENODEV; - } -#endif - /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ if ((desc->desc.bInterfaceSubClass != 0) && @@ -1013,22 +1005,17 @@ void usb_set_device_state(struct usb_device *udev, ; /* do nothing */ else if (new_state != USB_STATE_NOTATTACHED) { udev->state = new_state; - - /* root hub wakeup capabilities are managed out-of-band - * and may involve silicon errata ... ignore them here. - */ - if (udev->parent) { - if (new_state == USB_STATE_CONFIGURED) - device_init_wakeup(&udev->dev, - (udev->actconfig->desc.bmAttributes - & USB_CONFIG_ATT_WAKEUP)); - else if (new_state != USB_STATE_SUSPENDED) - device_init_wakeup(&udev->dev, 0); - } + if (new_state == USB_STATE_CONFIGURED) + device_init_wakeup(&udev->dev, + (udev->actconfig->desc.bmAttributes + & USB_CONFIG_ATT_WAKEUP)); + else if (new_state != USB_STATE_SUSPENDED) + device_init_wakeup(&udev->dev, 0); } else recursively_mark_NOTATTACHED(udev); spin_unlock_irqrestore(&device_state_lock, flags); } +EXPORT_SYMBOL(usb_set_device_state); #ifdef CONFIG_PM @@ -1168,18 +1155,25 @@ static inline const char *plural(int n) static int choose_configuration(struct usb_device *udev) { int i; + u16 devstatus; + int bus_powered; int num_configs; struct usb_host_config *c, *best; + /* If this fails, assume the device is bus-powered */ + devstatus = 0; + usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); + le16_to_cpus(&devstatus); + bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0); + dev_dbg(&udev->dev, "device is %s-powered\n", + bus_powered ? "bus" : "self"); + best = NULL; c = udev->config; num_configs = udev->descriptor.bNumConfigurations; for (i = 0; i < num_configs; (i++, c++)) { - struct usb_interface_descriptor *desc = NULL; - - /* It's possible that a config has no interfaces! */ - if (c->desc.bNumInterfaces > 0) - desc = &c->intf_cache[0]->altsetting->desc; + struct usb_interface_descriptor *desc = + &c->intf_cache[0]->altsetting->desc; /* * HP's USB bus-powered keyboard has only one configuration @@ -1187,19 +1181,6 @@ static int choose_configuration(struct usb_device *udev) * similar errors in their descriptors. If the next test * were allowed to execute, such configurations would always * be rejected and the devices would not work as expected. - * In the meantime, we run the risk of selecting a config - * that requires external power at a time when that power - * isn't available. It seems to be the lesser of two evils. - * - * Bugzilla #6448 reports a device that appears to crash - * when it receives a GET_DEVICE_STATUS request! We don't - * have any other way to tell whether a device is self-powered, - * but since we don't use that information anywhere but here, - * the call has been removed. - * - * Maybe the GET_DEVICE_STATUS call and the test below can - * be reinstated when device firmwares become more reliable. - * Don't hold your breath. */ #if 0 /* Rule out self-powered configs for a bus-powered device */ @@ -1227,8 +1208,7 @@ static int choose_configuration(struct usb_device *udev) /* If the first config's first interface is COMM/2/0xff * (MSFT RNDIS), rule it out unless Linux has host-side * RNDIS support. */ - if (i == 0 && desc - && desc->bInterfaceClass == USB_CLASS_COMM + if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM && desc->bInterfaceSubClass == 2 && desc->bInterfaceProtocol == 0xff) { #ifndef CONFIG_USB_NET_RNDIS @@ -1244,8 +1224,8 @@ static int choose_configuration(struct usb_device *udev) * than a vendor-specific driver. */ else if (udev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC && - (!desc || desc->bInterfaceClass != - USB_CLASS_VENDOR_SPEC)) { + desc->bInterfaceClass != + USB_CLASS_VENDOR_SPEC) { best = c; break; } @@ -1896,18 +1876,18 @@ int usb_resume_device(struct usb_device *udev) if (udev->state == USB_STATE_NOTATTACHED) return -ENODEV; +#ifdef CONFIG_USB_SUSPEND /* selective resume of one downstream hub-to-device port */ if (udev->parent) { -#ifdef CONFIG_USB_SUSPEND if (udev->state == USB_STATE_SUSPENDED) { // NOTE swsusp may bork us, device state being wrong... // NOTE this fails if parent is also suspended... status = hub_port_resume(hdev_to_hub(udev->parent), udev->portnum, udev); } else -#endif status = 0; } else +#endif status = finish_device_resume(udev); if (status < 0) dev_dbg(&udev->dev, "can't resume, status %d\n", @@ -2182,7 +2162,7 @@ static int hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, int retry_counter) { - static DEFINE_MUTEX(usb_address0_mutex); + static DECLARE_MUTEX(usb_address0_sem); struct usb_device *hdev = hub->hdev; int i, j, retval; @@ -2203,7 +2183,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, if (oldspeed == USB_SPEED_LOW) delay = HUB_LONG_RESET_TIME; - mutex_lock(&usb_address0_mutex); + down(&usb_address0_sem); /* Reset the device; full speed may morph to high speed */ retval = hub_port_reset(hub, port1, udev, delay); @@ -2401,7 +2381,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, fail: if (retval) hub_port_disable(hub, port1, 0); - mutex_unlock(&usb_address0_mutex); + up(&usb_address0_sem); return retval; } @@ -3037,7 +3017,7 @@ int usb_reset_device(struct usb_device *udev) parent_hub = hdev_to_hub(parent_hdev); /* If we're resetting an active hub, take some special actions */ - if (udev->actconfig && udev->actconfig->desc.bNumInterfaces > 0 && + if (udev->actconfig && udev->actconfig->interface[0]->dev.driver == &hub_driver.driver && (hub = hdev_to_hub(udev)) != NULL) { diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 08fb20f06..96cabeb7a 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -631,8 +631,8 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char * Returns the number of bytes received on success, or else the status code * returned by the underlying usb_control_msg() call. */ -static int usb_get_string(struct usb_device *dev, unsigned short langid, - unsigned char index, void *buf, int size) +int usb_get_string(struct usb_device *dev, unsigned short langid, + unsigned char index, void *buf, int size) { int i; int result; @@ -1490,6 +1490,7 @@ EXPORT_SYMBOL(usb_sg_wait); // synchronous control message convenience routines EXPORT_SYMBOL(usb_get_descriptor); EXPORT_SYMBOL(usb_get_status); +EXPORT_SYMBOL(usb_get_string); EXPORT_SYMBOL(usb_string); // synchronous calls that also maintain usbcore state diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c index fe0ed54fa..fbbebab52 100644 --- a/drivers/usb/core/notify.c +++ b/drivers/usb/core/notify.c @@ -13,10 +13,59 @@ #include #include #include -#include #include "usb.h" -static BLOCKING_NOTIFIER_HEAD(usb_notifier_list); + +static struct notifier_block *usb_notifier_list; +static DECLARE_MUTEX(usb_notifier_lock); + +static void usb_notifier_chain_register(struct notifier_block **list, + struct notifier_block *n) +{ + down(&usb_notifier_lock); + while (*list) { + if (n->priority > (*list)->priority) + break; + list = &((*list)->next); + } + n->next = *list; + *list = n; + up(&usb_notifier_lock); +} + +static void usb_notifier_chain_unregister(struct notifier_block **nl, + struct notifier_block *n) +{ + down(&usb_notifier_lock); + while ((*nl)!=NULL) { + if ((*nl)==n) { + *nl = n->next; + goto exit; + } + nl=&((*nl)->next); + } +exit: + up(&usb_notifier_lock); +} + +static int usb_notifier_call_chain(struct notifier_block **n, + unsigned long val, void *v) +{ + int ret=NOTIFY_DONE; + struct notifier_block *nb = *n; + + down(&usb_notifier_lock); + while (nb) { + ret = nb->notifier_call(nb,val,v); + if (ret&NOTIFY_STOP_MASK) { + goto exit; + } + nb = nb->next; + } +exit: + up(&usb_notifier_lock); + return ret; +} /** * usb_register_notify - register a notifier callback whenever a usb change happens @@ -26,7 +75,7 @@ static BLOCKING_NOTIFIER_HEAD(usb_notifier_list); */ void usb_register_notify(struct notifier_block *nb) { - blocking_notifier_chain_register(&usb_notifier_list, nb); + usb_notifier_chain_register(&usb_notifier_list, nb); } EXPORT_SYMBOL_GPL(usb_register_notify); @@ -39,28 +88,27 @@ EXPORT_SYMBOL_GPL(usb_register_notify); */ void usb_unregister_notify(struct notifier_block *nb) { - blocking_notifier_chain_unregister(&usb_notifier_list, nb); + usb_notifier_chain_unregister(&usb_notifier_list, nb); } EXPORT_SYMBOL_GPL(usb_unregister_notify); void usb_notify_add_device(struct usb_device *udev) { - blocking_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev); + usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev); } void usb_notify_remove_device(struct usb_device *udev) { - blocking_notifier_call_chain(&usb_notifier_list, - USB_DEVICE_REMOVE, udev); + usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev); } void usb_notify_add_bus(struct usb_bus *ubus) { - blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus); + usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus); } void usb_notify_remove_bus(struct usb_bus *ubus) { - blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); + usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index b7fdc1cd1..13d1d367f 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -640,7 +639,7 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id) struct usb_bus *bus; struct usb_device *dev = NULL; - mutex_lock(&usb_bus_list_lock); + down(&usb_bus_list_lock); for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) { @@ -654,7 +653,7 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id) goto exit; } exit: - mutex_unlock(&usb_bus_list_lock); + up(&usb_bus_list_lock); return dev; } @@ -1194,6 +1193,7 @@ EXPORT_SYMBOL(usb_disabled); EXPORT_SYMBOL_GPL(usb_get_intf); EXPORT_SYMBOL_GPL(usb_put_intf); +EXPORT_SYMBOL(usb_alloc_dev); EXPORT_SYMBOL(usb_put_dev); EXPORT_SYMBOL(usb_get_dev); EXPORT_SYMBOL(usb_hub_tt_clear_buffer); @@ -1207,6 +1207,7 @@ EXPORT_SYMBOL(usb_ifnum_to_if); EXPORT_SYMBOL(usb_altnum_to_altsetting); EXPORT_SYMBOL(usb_reset_device); +EXPORT_SYMBOL(usb_disconnect); EXPORT_SYMBOL(__usb_get_extra_descriptor); diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 363b2ad74..ff075a53c 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -69,11 +69,11 @@ choice often need board-specific hooks. config USB_GADGET_NET2280 - boolean "NetChip 228x" + boolean "NetChip 2280" depends on PCI select USB_GADGET_DUALSPEED help - NetChip 2280 / 2282 is a PCI based USB peripheral controller which + NetChip 2280 is a PCI based USB peripheral controller which supports both full and high speed USB 2.0 data transfers. It has six configurable endpoints, as well as endpoint zero @@ -187,23 +187,6 @@ config USB_OTG Select this only if your OMAP board has a Mini-AB connector. -config USB_GADGET_AT91 - boolean "AT91 USB Device Port" - depends on ARCH_AT91RM9200 - select USB_GADGET_SELECTED - help - Many Atmel AT91 processors (such as the AT91RM2000) have a - full speed USB Device Port with support for five configurable - endpoints (plus endpoint zero). - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "at91_udc" and force all - gadget drivers to also be dynamically linked. - -config USB_AT91 - tristate - depends on USB_GADGET_AT91 - default USB_GADGET config USB_GADGET_DUMMY_HCD boolean "Dummy HCD (DEVELOPMENT)" diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 5a28e6139..d5fd04d88 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o obj-$(CONFIG_USB_GOKU) += goku_udc.o obj-$(CONFIG_USB_OMAP) += omap_udc.o obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o -obj-$(CONFIG_USB_AT91) += at91_udc.o # # USB gadget drivers diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c deleted file mode 100644 index b8d0b7825..000000000 --- a/drivers/usb/gadget/at91_udc.c +++ /dev/null @@ -1,1773 +0,0 @@ -/* - * at91_udc -- driver for at91-series USB peripheral controller - * - * Copyright (C) 2004 by Thomas Rathbone - * Copyright (C) 2005 by HP Labs - * Copyright (C) 2005 by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#undef DEBUG -#undef VERBOSE -#undef PACKET_TRACE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "at91_udc.h" - - -/* - * This controller is simple and PIO-only. It's used in many AT91-series - * ARMv4T controllers, including the at91rm9200 (arm920T, with MMU), - * at91sam9261 (arm926ejs, with MMU), and several no-mmu versions. - * - * This driver expects the board has been wired with two GPIOs suppporting - * a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the - * testing hasn't covered such cases.) The pullup is most important; it - * provides software control over whether the host enumerates the device. - * The VBUS sensing helps during enumeration, and allows both USB clocks - * (and the transceiver) to stay gated off until they're necessary, saving - * power. During USB suspend, the 48 MHz clock is gated off. - */ - -#define DRIVER_VERSION "8 March 2005" - -static const char driver_name [] = "at91_udc"; -static const char ep0name[] = "ep0"; - -/*-------------------------------------------------------------------------*/ - -/* - * Read from a UDP register. - */ -static inline unsigned long at91_udp_read(unsigned int reg) -{ - void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP; - - return __raw_readl(udp_base + reg); -} - -/* - * Write to a UDP register. - */ -static inline void at91_udp_write(unsigned int reg, unsigned long value) -{ - void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP; - - __raw_writel(value, udp_base + reg); -} - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_USB_GADGET_DEBUG_FILES - -#include - -static const char debug_filename[] = "driver/udc"; - -#define FOURBITS "%s%s%s%s" -#define EIGHTBITS FOURBITS FOURBITS - -static void proc_ep_show(struct seq_file *s, struct at91_ep *ep) -{ - static char *types[] = { - "control", "out-iso", "out-bulk", "out-int", - "BOGUS", "in-iso", "in-bulk", "in-int"}; - - u32 csr; - struct at91_request *req; - unsigned long flags; - - local_irq_save(flags); - - csr = __raw_readl(ep->creg); - - /* NOTE: not collecting per-endpoint irq statistics... */ - - seq_printf(s, "\n"); - seq_printf(s, "%s, maxpacket %d %s%s %s%s\n", - ep->ep.name, ep->ep.maxpacket, - ep->is_in ? "in" : "out", - ep->is_iso ? " iso" : "", - ep->is_pingpong - ? (ep->fifo_bank ? "pong" : "ping") - : "", - ep->stopped ? " stopped" : ""); - seq_printf(s, "csr %08x rxbytes=%d %s %s %s" EIGHTBITS "\n", - csr, - (csr & 0x07ff0000) >> 16, - (csr & (1 << 15)) ? "enabled" : "disabled", - (csr & (1 << 11)) ? "DATA1" : "DATA0", - types[(csr & 0x700) >> 8], - - /* iff type is control then print current direction */ - (!(csr & 0x700)) - ? ((csr & (1 << 7)) ? " IN" : " OUT") - : "", - (csr & (1 << 6)) ? " rxdatabk1" : "", - (csr & (1 << 5)) ? " forcestall" : "", - (csr & (1 << 4)) ? " txpktrdy" : "", - - (csr & (1 << 3)) ? " stallsent" : "", - (csr & (1 << 2)) ? " rxsetup" : "", - (csr & (1 << 1)) ? " rxdatabk0" : "", - (csr & (1 << 0)) ? " txcomp" : ""); - if (list_empty (&ep->queue)) - seq_printf(s, "\t(queue empty)\n"); - - else list_for_each_entry (req, &ep->queue, queue) { - unsigned length = req->req.actual; - - seq_printf(s, "\treq %p len %d/%d buf %p\n", - &req->req, length, - req->req.length, req->req.buf); - } - local_irq_restore(flags); -} - -static void proc_irq_show(struct seq_file *s, const char *label, u32 mask) -{ - int i; - - seq_printf(s, "%s %04x:%s%s" FOURBITS, label, mask, - (mask & (1 << 13)) ? " wakeup" : "", - (mask & (1 << 12)) ? " endbusres" : "", - - (mask & (1 << 11)) ? " sofint" : "", - (mask & (1 << 10)) ? " extrsm" : "", - (mask & (1 << 9)) ? " rxrsm" : "", - (mask & (1 << 8)) ? " rxsusp" : ""); - for (i = 0; i < 8; i++) { - if (mask & (1 << i)) - seq_printf(s, " ep%d", i); - } - seq_printf(s, "\n"); -} - -static int proc_udc_show(struct seq_file *s, void *unused) -{ - struct at91_udc *udc = s->private; - struct at91_ep *ep; - u32 tmp; - - seq_printf(s, "%s: version %s\n", driver_name, DRIVER_VERSION); - - seq_printf(s, "vbus %s, pullup %s, %s powered%s, gadget %s\n\n", - udc->vbus ? "present" : "off", - udc->enabled - ? (udc->vbus ? "active" : "enabled") - : "disabled", - udc->selfpowered ? "self" : "VBUS", - udc->suspended ? ", suspended" : "", - udc->driver ? udc->driver->driver.name : "(none)"); - - /* don't access registers when interface isn't clocked */ - if (!udc->clocked) { - seq_printf(s, "(not clocked)\n"); - return 0; - } - - tmp = at91_udp_read(AT91_UDP_FRM_NUM); - seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp, - (tmp & AT91_UDP_FRM_OK) ? " ok" : "", - (tmp & AT91_UDP_FRM_ERR) ? " err" : "", - (tmp & AT91_UDP_NUM)); - - tmp = at91_udp_read(AT91_UDP_GLB_STAT); - seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp, - (tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "", - (tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "", - (tmp & AT91_UDP_ESR) ? " esr" : "", - (tmp & AT91_UDP_CONFG) ? " confg" : "", - (tmp & AT91_UDP_FADDEN) ? " fadden" : ""); - - tmp = at91_udp_read(AT91_UDP_FADDR); - seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp, - (tmp & AT91_UDP_FEN) ? " fen" : "", - (tmp & AT91_UDP_FADD)); - - proc_irq_show(s, "imr ", at91_udp_read(AT91_UDP_IMR)); - proc_irq_show(s, "isr ", at91_udp_read(AT91_UDP_ISR)); - - if (udc->enabled && udc->vbus) { - proc_ep_show(s, &udc->ep[0]); - list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) { - if (ep->desc) - proc_ep_show(s, ep); - } - } - return 0; -} - -static int proc_udc_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_udc_show, PDE(inode)->data); -} - -static struct file_operations proc_ops = { - .open = proc_udc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void create_debug_file(struct at91_udc *udc) -{ - struct proc_dir_entry *pde; - - pde = create_proc_entry (debug_filename, 0, NULL); - udc->pde = pde; - if (pde == NULL) - return; - - pde->proc_fops = &proc_ops; - pde->data = udc; -} - -static void remove_debug_file(struct at91_udc *udc) -{ - if (udc->pde) - remove_proc_entry(debug_filename, NULL); -} - -#else - -static inline void create_debug_file(struct at91_udc *udc) {} -static inline void remove_debug_file(struct at91_udc *udc) {} - -#endif - - -/*-------------------------------------------------------------------------*/ - -static void done(struct at91_ep *ep, struct at91_request *req, int status) -{ - unsigned stopped = ep->stopped; - - list_del_init(&req->queue); - if (req->req.status == -EINPROGRESS) - req->req.status = status; - else - status = req->req.status; - if (status && status != -ESHUTDOWN) - VDBG("%s done %p, status %d\n", ep->ep.name, req, status); - - ep->stopped = 1; - req->req.complete(&ep->ep, &req->req); - ep->stopped = stopped; - - /* ep0 is always ready; other endpoints need a non-empty queue */ - if (list_empty(&ep->queue) && ep->int_mask != (1 << 0)) - at91_udp_write(AT91_UDP_IDR, ep->int_mask); -} - -/*-------------------------------------------------------------------------*/ - -/* bits indicating OUT fifo has data ready */ -#define RX_DATA_READY (AT91_UDP_RX_DATA_BK0 | AT91_UDP_RX_DATA_BK1) - -/* - * Endpoint FIFO CSR bits have a mix of bits, making it unsafe to just write - * back most of the value you just read (because of side effects, including - * bits that may change after reading and before writing). - * - * Except when changing a specific bit, always write values which: - * - clear SET_FX bits (setting them could change something) - * - set CLR_FX bits (clearing them could change something) - * - * There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE - * that shouldn't normally be changed. - */ -#define SET_FX (AT91_UDP_TXPKTRDY) -#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP) - -/* pull OUT packet data from the endpoint's fifo */ -static int read_fifo (struct at91_ep *ep, struct at91_request *req) -{ - u32 __iomem *creg = ep->creg; - u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0)); - u32 csr; - u8 *buf; - unsigned int count, bufferspace, is_done; - - buf = req->req.buf + req->req.actual; - bufferspace = req->req.length - req->req.actual; - - /* - * there might be nothing to read if ep_queue() calls us, - * or if we already emptied both pingpong buffers - */ -rescan: - csr = __raw_readl(creg); - if ((csr & RX_DATA_READY) == 0) - return 0; - - count = (csr & AT91_UDP_RXBYTECNT) >> 16; - if (count > ep->ep.maxpacket) - count = ep->ep.maxpacket; - if (count > bufferspace) { - DBG("%s buffer overflow\n", ep->ep.name); - req->req.status = -EOVERFLOW; - count = bufferspace; - } - __raw_readsb(dreg, buf, count); - - /* release and swap pingpong mem bank */ - csr |= CLR_FX; - if (ep->is_pingpong) { - if (ep->fifo_bank == 0) { - csr &= ~(SET_FX | AT91_UDP_RX_DATA_BK0); - ep->fifo_bank = 1; - } else { - csr &= ~(SET_FX | AT91_UDP_RX_DATA_BK1); - ep->fifo_bank = 0; - } - } else - csr &= ~(SET_FX | AT91_UDP_RX_DATA_BK0); - __raw_writel(csr, creg); - - req->req.actual += count; - is_done = (count < ep->ep.maxpacket); - if (count == bufferspace) - is_done = 1; - - PACKET("%s %p out/%d%s\n", ep->ep.name, &req->req, count, - is_done ? " (done)" : ""); - - /* - * avoid extra trips through IRQ logic for packets already in - * the fifo ... maybe preventing an extra (expensive) OUT-NAK - */ - if (is_done) - done(ep, req, 0); - else if (ep->is_pingpong) { - bufferspace -= count; - buf += count; - goto rescan; - } - - return is_done; -} - -/* load fifo for an IN packet */ -static int write_fifo(struct at91_ep *ep, struct at91_request *req) -{ - u32 __iomem *creg = ep->creg; - u32 csr = __raw_readl(creg); - u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0)); - unsigned total, count, is_last; - - /* - * TODO: allow for writing two packets to the fifo ... that'll - * reduce the amount of IN-NAKing, but probably won't affect - * throughput much. (Unlike preventing OUT-NAKing!) - */ - - /* - * If ep_queue() calls us, the queue is empty and possibly in - * odd states like TXCOMP not yet cleared (we do it, saving at - * least one IRQ) or the fifo not yet being free. Those aren't - * issues normally (IRQ handler fast path). - */ - if (unlikely(csr & (AT91_UDP_TXCOMP | AT91_UDP_TXPKTRDY))) { - if (csr & AT91_UDP_TXCOMP) { - csr |= CLR_FX; - csr &= ~(SET_FX | AT91_UDP_TXCOMP); - __raw_writel(csr, creg); - csr = __raw_readl(creg); - } - if (csr & AT91_UDP_TXPKTRDY) - return 0; - } - - total = req->req.length - req->req.actual; - if (ep->ep.maxpacket < total) { - count = ep->ep.maxpacket; - is_last = 0; - } else { - count = total; - is_last = (count < ep->ep.maxpacket) || !req->req.zero; - } - - /* - * Write the packet, maybe it's a ZLP. - * - * NOTE: incrementing req->actual before we receive the ACK means - * gadget driver IN bytecounts can be wrong in fault cases. That's - * fixable with PIO drivers like this one (save "count" here, and - * do the increment later on TX irq), but not for most DMA hardware. - * - * So all gadget drivers must accept that potential error. Some - * hardware supports precise fifo status reporting, letting them - * recover when the actual bytecount matters (e.g. for USB Test - * and Measurement Class devices). - */ - __raw_writesb(dreg, req->req.buf + req->req.actual, count); - csr &= ~SET_FX; - csr |= CLR_FX | AT91_UDP_TXPKTRDY; - __raw_writel(csr, creg); - req->req.actual += count; - - PACKET("%s %p in/%d%s\n", ep->ep.name, &req->req, count, - is_last ? " (done)" : ""); - if (is_last) - done(ep, req, 0); - return is_last; -} - -static void nuke(struct at91_ep *ep, int status) -{ - struct at91_request *req; - - // terminer chaque requete dans la queue - ep->stopped = 1; - if (list_empty(&ep->queue)) - return; - - VDBG("%s %s\n", __FUNCTION__, ep->ep.name); - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, struct at91_request, queue); - done(ep, req, status); - } -} - -/*-------------------------------------------------------------------------*/ - -static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) -{ - struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); - struct at91_udc *dev = ep->udc; - u16 maxpacket; - u32 tmp; - unsigned long flags; - - if (!_ep || !ep - || !desc || ep->desc - || _ep->name == ep0name - || desc->bDescriptorType != USB_DT_ENDPOINT - || (maxpacket = le16_to_cpu(desc->wMaxPacketSize)) == 0 - || maxpacket > ep->maxpacket) { - DBG("bad ep or descriptor\n"); - return -EINVAL; - } - - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { - DBG("bogus device state\n"); - return -ESHUTDOWN; - } - - tmp = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - switch (tmp) { - case USB_ENDPOINT_XFER_CONTROL: - DBG("only one control endpoint\n"); - return -EINVAL; - case USB_ENDPOINT_XFER_INT: - if (maxpacket > 64) - goto bogus_max; - break; - case USB_ENDPOINT_XFER_BULK: - switch (maxpacket) { - case 8: - case 16: - case 32: - case 64: - goto ok; - } -bogus_max: - DBG("bogus maxpacket %d\n", maxpacket); - return -EINVAL; - case USB_ENDPOINT_XFER_ISOC: - if (!ep->is_pingpong) { - DBG("iso requires double buffering\n"); - return -EINVAL; - } - break; - } - -ok: - local_irq_save(flags); - - /* initialize endpoint to match this descriptor */ - ep->is_in = (desc->bEndpointAddress & USB_DIR_IN) != 0; - ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC); - ep->stopped = 0; - if (ep->is_in) - tmp |= 0x04; - tmp <<= 8; - tmp |= AT91_UDP_EPEDS; - __raw_writel(tmp, ep->creg); - - ep->desc = desc; - ep->ep.maxpacket = maxpacket; - - /* - * reset/init endpoint fifo. NOTE: leaves fifo_bank alone, - * since endpoint resets don't reset hw pingpong state. - */ - at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); - at91_udp_write(AT91_UDP_RST_EP, 0); - - local_irq_restore(flags); - return 0; -} - -static int at91_ep_disable (struct usb_ep * _ep) -{ - struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); - unsigned long flags; - - if (ep == &ep->udc->ep[0]) - return -EINVAL; - - local_irq_save(flags); - - nuke(ep, -ESHUTDOWN); - - /* restore the endpoint's pristine config */ - ep->desc = NULL; - ep->ep.maxpacket = ep->maxpacket; - - /* reset fifos and endpoint */ - if (ep->udc->clocked) { - at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); - at91_udp_write(AT91_UDP_RST_EP, 0); - __raw_writel(0, ep->creg); - } - - local_irq_restore(flags); - return 0; -} - -/* - * this is a PIO-only driver, so there's nothing - * interesting for request or buffer allocation. - */ - -static struct usb_request *at91_ep_alloc_request (struct usb_ep *_ep, unsigned int gfp_flags) -{ - struct at91_request *req; - - req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL); - if (!req) - return NULL; - - INIT_LIST_HEAD(&req->queue); - return &req->req; -} - -static void at91_ep_free_request(struct usb_ep *_ep, struct usb_request *_req) -{ - struct at91_request *req; - - req = container_of(_req, struct at91_request, req); - BUG_ON(!list_empty(&req->queue)); - kfree(req); -} - -static void *at91_ep_alloc_buffer( - struct usb_ep *_ep, - unsigned bytes, - dma_addr_t *dma, - gfp_t gfp_flags) -{ - *dma = ~0; - return kmalloc(bytes, gfp_flags); -} - -static void at91_ep_free_buffer( - struct usb_ep *ep, - void *buf, - dma_addr_t dma, - unsigned bytes) -{ - kfree(buf); -} - -static int at91_ep_queue(struct usb_ep *_ep, - struct usb_request *_req, gfp_t gfp_flags) -{ - struct at91_request *req; - struct at91_ep *ep; - struct at91_udc *dev; - int status; - unsigned long flags; - - req = container_of(_req, struct at91_request, req); - ep = container_of(_ep, struct at91_ep, ep); - - if (!_req || !_req->complete - || !_req->buf || !list_empty(&req->queue)) { - DBG("invalid request\n"); - return -EINVAL; - } - - if (!_ep || (!ep->desc && ep->ep.name != ep0name)) { - DBG("invalid ep\n"); - return -EINVAL; - } - - dev = ep->udc; - - if (!dev || !dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { - DBG("invalid device\n"); - return -EINVAL; - } - - _req->status = -EINPROGRESS; - _req->actual = 0; - - local_irq_save(flags); - - /* try to kickstart any empty and idle queue */ - if (list_empty(&ep->queue) && !ep->stopped) { - int is_ep0; - - /* - * If this control request has a non-empty DATA stage, this - * will start that stage. It works just like a non-control - * request (until the status stage starts, maybe early). - * - * If the data stage is empty, then this starts a successful - * IN/STATUS stage. (Unsuccessful ones use set_halt.) - */ - is_ep0 = (ep->ep.name == ep0name); - if (is_ep0) { - u32 tmp; - - if (!dev->req_pending) { - status = -EINVAL; - goto done; - } - - /* - * defer changing CONFG until after the gadget driver - * reconfigures the endpoints. - */ - if (dev->wait_for_config_ack) { - tmp = at91_udp_read(AT91_UDP_GLB_STAT); - tmp ^= AT91_UDP_CONFG; - VDBG("toggle config\n"); - at91_udp_write(AT91_UDP_GLB_STAT, tmp); - } - if (req->req.length == 0) { -ep0_in_status: - PACKET("ep0 in/status\n"); - status = 0; - tmp = __raw_readl(ep->creg); - tmp &= ~SET_FX; - tmp |= CLR_FX | AT91_UDP_TXPKTRDY; - __raw_writel(tmp, ep->creg); - dev->req_pending = 0; - goto done; - } - } - - if (ep->is_in) - status = write_fifo(ep, req); - else { - status = read_fifo(ep, req); - - /* IN/STATUS stage is otherwise triggered by irq */ - if (status && is_ep0) - goto ep0_in_status; - } - } else - status = 0; - - if (req && !status) { - list_add_tail (&req->queue, &ep->queue); - at91_udp_write(AT91_UDP_IER, ep->int_mask); - } -done: - local_irq_restore(flags); - return (status < 0) ? status : 0; -} - -static int at91_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) -{ - struct at91_ep *ep; - struct at91_request *req; - - ep = container_of(_ep, struct at91_ep, ep); - if (!_ep || ep->ep.name == ep0name) - return -EINVAL; - - /* make sure it's actually queued on this endpoint */ - list_for_each_entry (req, &ep->queue, queue) { - if (&req->req == _req) - break; - } - if (&req->req != _req) - return -EINVAL; - - done(ep, req, -ECONNRESET); - return 0; -} - -static int at91_ep_set_halt(struct usb_ep *_ep, int value) -{ - struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); - u32 __iomem *creg; - u32 csr; - unsigned long flags; - int status = 0; - - if (!_ep || ep->is_iso || !ep->udc->clocked) - return -EINVAL; - - creg = ep->creg; - local_irq_save(flags); - - csr = __raw_readl(creg); - - /* - * fail with still-busy IN endpoints, ensuring correct sequencing - * of data tx then stall. note that the fifo rx bytecount isn't - * completely accurate as a tx bytecount. - */ - if (ep->is_in && (!list_empty(&ep->queue) || (csr >> 16) != 0)) - status = -EAGAIN; - else { - csr |= CLR_FX; - csr &= ~SET_FX; - if (value) { - csr |= AT91_UDP_FORCESTALL; - VDBG("halt %s\n", ep->ep.name); - } else { - at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); - at91_udp_write(AT91_UDP_RST_EP, 0); - csr &= ~AT91_UDP_FORCESTALL; - } - __raw_writel(csr, creg); - } - - local_irq_restore(flags); - return status; -} - -static struct usb_ep_ops at91_ep_ops = { - .enable = at91_ep_enable, - .disable = at91_ep_disable, - .alloc_request = at91_ep_alloc_request, - .free_request = at91_ep_free_request, - .alloc_buffer = at91_ep_alloc_buffer, - .free_buffer = at91_ep_free_buffer, - .queue = at91_ep_queue, - .dequeue = at91_ep_dequeue, - .set_halt = at91_ep_set_halt, - // there's only imprecise fifo status reporting -}; - -/*-------------------------------------------------------------------------*/ - -static int at91_get_frame(struct usb_gadget *gadget) -{ - if (!to_udc(gadget)->clocked) - return -EINVAL; - return at91_udp_read(AT91_UDP_FRM_NUM) & AT91_UDP_NUM; -} - -static int at91_wakeup(struct usb_gadget *gadget) -{ - struct at91_udc *udc = to_udc(gadget); - u32 glbstate; - int status = -EINVAL; - unsigned long flags; - - DBG("%s\n", __FUNCTION__ ); - local_irq_save(flags); - - if (!udc->clocked || !udc->suspended) - goto done; - - /* NOTE: some "early versions" handle ESR differently ... */ - - glbstate = at91_udp_read(AT91_UDP_GLB_STAT); - if (!(glbstate & AT91_UDP_ESR)) - goto done; - glbstate |= AT91_UDP_ESR; - at91_udp_write(AT91_UDP_GLB_STAT, glbstate); - -done: - local_irq_restore(flags); - return status; -} - -/* reinit == restore inital software state */ -static void udc_reinit(struct at91_udc *udc) -{ - u32 i; - - INIT_LIST_HEAD(&udc->gadget.ep_list); - INIT_LIST_HEAD(&udc->gadget.ep0->ep_list); - - for (i = 0; i < NUM_ENDPOINTS; i++) { - struct at91_ep *ep = &udc->ep[i]; - - if (i != 0) - list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); - ep->desc = NULL; - ep->stopped = 0; - ep->fifo_bank = 0; - ep->ep.maxpacket = ep->maxpacket; - // initialiser une queue par endpoint - INIT_LIST_HEAD(&ep->queue); - } -} - -static void stop_activity(struct at91_udc *udc) -{ - struct usb_gadget_driver *driver = udc->driver; - int i; - - if (udc->gadget.speed == USB_SPEED_UNKNOWN) - driver = NULL; - udc->gadget.speed = USB_SPEED_UNKNOWN; - - for (i = 0; i < NUM_ENDPOINTS; i++) { - struct at91_ep *ep = &udc->ep[i]; - ep->stopped = 1; - nuke(ep, -ESHUTDOWN); - } - if (driver) - driver->disconnect(&udc->gadget); - - udc_reinit(udc); -} - -static void clk_on(struct at91_udc *udc) -{ - if (udc->clocked) - return; - udc->clocked = 1; - clk_enable(udc->iclk); - clk_enable(udc->fclk); -} - -static void clk_off(struct at91_udc *udc) -{ - if (!udc->clocked) - return; - udc->clocked = 0; - udc->gadget.speed = USB_SPEED_UNKNOWN; - clk_disable(udc->iclk); - clk_disable(udc->fclk); -} - -/* - * activate/deactivate link with host; minimize power usage for - * inactive links by cutting clocks and transceiver power. - */ -static void pullup(struct at91_udc *udc, int is_on) -{ - if (!udc->enabled || !udc->vbus) - is_on = 0; - DBG("%sactive\n", is_on ? "" : "in"); - if (is_on) { - clk_on(udc); - at91_udp_write(AT91_UDP_TXVC, 0); - at91_set_gpio_value(udc->board.pullup_pin, 1); - } else { - stop_activity(udc); - at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); - at91_set_gpio_value(udc->board.pullup_pin, 0); - clk_off(udc); - - // REVISIT: with transceiver disabled, will D- float - // so that a host would falsely detect a device? - } -} - -/* vbus is here! turn everything on that's ready */ -static int at91_vbus_session(struct usb_gadget *gadget, int is_active) -{ - struct at91_udc *udc = to_udc(gadget); - unsigned long flags; - - // VDBG("vbus %s\n", is_active ? "on" : "off"); - local_irq_save(flags); - udc->vbus = (is_active != 0); - pullup(udc, is_active); - local_irq_restore(flags); - return 0; -} - -static int at91_pullup(struct usb_gadget *gadget, int is_on) -{ - struct at91_udc *udc = to_udc(gadget); - unsigned long flags; - - local_irq_save(flags); - udc->enabled = is_on = !!is_on; - pullup(udc, is_on); - local_irq_restore(flags); - return 0; -} - -static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on) -{ - struct at91_udc *udc = to_udc(gadget); - unsigned long flags; - - local_irq_save(flags); - udc->selfpowered = (is_on != 0); - local_irq_restore(flags); - return 0; -} - -static const struct usb_gadget_ops at91_udc_ops = { - .get_frame = at91_get_frame, - .wakeup = at91_wakeup, - .set_selfpowered = at91_set_selfpowered, - .vbus_session = at91_vbus_session, - .pullup = at91_pullup, - - /* - * VBUS-powered devices may also also want to support bigger - * power budgets after an appropriate SET_CONFIGURATION. - */ - // .vbus_power = at91_vbus_power, -}; - -/*-------------------------------------------------------------------------*/ - -static int handle_ep(struct at91_ep *ep) -{ - struct at91_request *req; - u32 __iomem *creg = ep->creg; - u32 csr = __raw_readl(creg); - - if (!list_empty(&ep->queue)) - req = list_entry(ep->queue.next, - struct at91_request, queue); - else - req = NULL; - - if (ep->is_in) { - if (csr & (AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)) { - csr |= CLR_FX; - csr &= ~(SET_FX | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP); - __raw_writel(csr, creg); - } - if (req) - return write_fifo(ep, req); - - } else { - if (csr & AT91_UDP_STALLSENT) { - /* STALLSENT bit == ISOERR */ - if (ep->is_iso && req) - req->req.status = -EILSEQ; - csr |= CLR_FX; - csr &= ~(SET_FX | AT91_UDP_STALLSENT); - __raw_writel(csr, creg); - csr = __raw_readl(creg); - } - if (req && (csr & RX_DATA_READY)) - return read_fifo(ep, req); - } - return 0; -} - -union setup { - u8 raw[8]; - struct usb_ctrlrequest r; -}; - -static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) -{ - u32 __iomem *creg = ep->creg; - u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0)); - unsigned rxcount, i = 0; - u32 tmp; - union setup pkt; - int status = 0; - - /* read and ack SETUP; hard-fail for bogus packets */ - rxcount = (csr & AT91_UDP_RXBYTECNT) >> 16; - if (likely(rxcount == 8)) { - while (rxcount--) - pkt.raw[i++] = __raw_readb(dreg); - if (pkt.r.bRequestType & USB_DIR_IN) { - csr |= AT91_UDP_DIR; - ep->is_in = 1; - } else { - csr &= ~AT91_UDP_DIR; - ep->is_in = 0; - } - } else { - // REVISIT this happens sometimes under load; why?? - ERR("SETUP len %d, csr %08x\n", rxcount, csr); - status = -EINVAL; - } - csr |= CLR_FX; - csr &= ~(SET_FX | AT91_UDP_RXSETUP); - __raw_writel(csr, creg); - udc->wait_for_addr_ack = 0; - udc->wait_for_config_ack = 0; - ep->stopped = 0; - if (unlikely(status != 0)) - goto stall; - -#define w_index le16_to_cpu(pkt.r.wIndex) -#define w_value le16_to_cpu(pkt.r.wValue) -#define w_length le16_to_cpu(pkt.r.wLength) - - VDBG("SETUP %02x.%02x v%04x i%04x l%04x\n", - pkt.r.bRequestType, pkt.r.bRequest, - w_value, w_index, w_length); - - /* - * A few standard requests get handled here, ones that touch - * hardware ... notably for device and endpoint features. - */ - udc->req_pending = 1; - csr = __raw_readl(creg); - csr |= CLR_FX; - csr &= ~SET_FX; - switch ((pkt.r.bRequestType << 8) | pkt.r.bRequest) { - - case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) - | USB_REQ_SET_ADDRESS: - __raw_writel(csr | AT91_UDP_TXPKTRDY, creg); - udc->addr = w_value; - udc->wait_for_addr_ack = 1; - udc->req_pending = 0; - /* FADDR is set later, when we ack host STATUS */ - return; - - case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) - | USB_REQ_SET_CONFIGURATION: - tmp = at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_CONFG; - if (pkt.r.wValue) - udc->wait_for_config_ack = (tmp == 0); - else - udc->wait_for_config_ack = (tmp != 0); - if (udc->wait_for_config_ack) - VDBG("wait for config\n"); - /* CONFG is toggled later, if gadget driver succeeds */ - break; - - /* - * Hosts may set or clear remote wakeup status, and - * devices may report they're VBUS powered. - */ - case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) - | USB_REQ_GET_STATUS: - tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED); - if (at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_ESR) - tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); - PACKET("get device status\n"); - __raw_writeb(tmp, dreg); - __raw_writeb(0, dreg); - goto write_in; - /* then STATUS starts later, automatically */ - case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) - | USB_REQ_SET_FEATURE: - if (w_value != USB_DEVICE_REMOTE_WAKEUP) - goto stall; - tmp = at91_udp_read(AT91_UDP_GLB_STAT); - tmp |= AT91_UDP_ESR; - at91_udp_write(AT91_UDP_GLB_STAT, tmp); - goto succeed; - case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) - | USB_REQ_CLEAR_FEATURE: - if (w_value != USB_DEVICE_REMOTE_WAKEUP) - goto stall; - tmp = at91_udp_read(AT91_UDP_GLB_STAT); - tmp &= ~AT91_UDP_ESR; - at91_udp_write(AT91_UDP_GLB_STAT, tmp); - goto succeed; - - /* - * Interfaces have no feature settings; this is pretty useless. - * we won't even insist the interface exists... - */ - case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8) - | USB_REQ_GET_STATUS: - PACKET("get interface status\n"); - __raw_writeb(0, dreg); - __raw_writeb(0, dreg); - goto write_in; - /* then STATUS starts later, automatically */ - case ((USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8) - | USB_REQ_SET_FEATURE: - case ((USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8) - | USB_REQ_CLEAR_FEATURE: - goto stall; - - /* - * Hosts may clear bulk/intr endpoint halt after the gadget - * driver sets it (not widely used); or set it (for testing) - */ - case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8) - | USB_REQ_GET_STATUS: - tmp = w_index & USB_ENDPOINT_NUMBER_MASK; - ep = &udc->ep[tmp]; - if (tmp > NUM_ENDPOINTS || (tmp && !ep->desc)) - goto stall; - - if (tmp) { - if ((w_index & USB_DIR_IN)) { - if (!ep->is_in) - goto stall; - } else if (ep->is_in) - goto stall; - } - PACKET("get %s status\n", ep->ep.name); - if (__raw_readl(ep->creg) & AT91_UDP_FORCESTALL) - tmp = (1 << USB_ENDPOINT_HALT); - else - tmp = 0; - __raw_writeb(tmp, dreg); - __raw_writeb(0, dreg); - goto write_in; - /* then STATUS starts later, automatically */ - case ((USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8) - | USB_REQ_SET_FEATURE: - tmp = w_index & USB_ENDPOINT_NUMBER_MASK; - ep = &udc->ep[tmp]; - if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS) - goto stall; - if (!ep->desc || ep->is_iso) - goto stall; - if ((w_index & USB_DIR_IN)) { - if (!ep->is_in) - goto stall; - } else if (ep->is_in) - goto stall; - - tmp = __raw_readl(ep->creg); - tmp &= ~SET_FX; - tmp |= CLR_FX | AT91_UDP_FORCESTALL; - __raw_writel(tmp, ep->creg); - goto succeed; - case ((USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8) - | USB_REQ_CLEAR_FEATURE: - tmp = w_index & USB_ENDPOINT_NUMBER_MASK; - ep = &udc->ep[tmp]; - if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS) - goto stall; - if (tmp == 0) - goto succeed; - if (!ep->desc || ep->is_iso) - goto stall; - if ((w_index & USB_DIR_IN)) { - if (!ep->is_in) - goto stall; - } else if (ep->is_in) - goto stall; - - at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); - at91_udp_write(AT91_UDP_RST_EP, 0); - tmp = __raw_readl(ep->creg); - tmp |= CLR_FX; - tmp &= ~(SET_FX | AT91_UDP_FORCESTALL); - __raw_writel(tmp, ep->creg); - if (!list_empty(&ep->queue)) - handle_ep(ep); - goto succeed; - } - -#undef w_value -#undef w_index -#undef w_length - - /* pass request up to the gadget driver */ - status = udc->driver->setup(&udc->gadget, &pkt.r); - if (status < 0) { -stall: - VDBG("req %02x.%02x protocol STALL; stat %d\n", - pkt.r.bRequestType, pkt.r.bRequest, status); - csr |= AT91_UDP_FORCESTALL; - __raw_writel(csr, creg); - udc->req_pending = 0; - } - return; - -succeed: - /* immediate successful (IN) STATUS after zero length DATA */ - PACKET("ep0 in/status\n"); -write_in: - csr |= AT91_UDP_TXPKTRDY; - __raw_writel(csr, creg); - udc->req_pending = 0; - return; -} - -static void handle_ep0(struct at91_udc *udc) -{ - struct at91_ep *ep0 = &udc->ep[0]; - u32 __iomem *creg = ep0->creg; - u32 csr = __raw_readl(creg); - struct at91_request *req; - - if (unlikely(csr & AT91_UDP_STALLSENT)) { - nuke(ep0, -EPROTO); - udc->req_pending = 0; - csr |= CLR_FX; - csr &= ~(SET_FX | AT91_UDP_STALLSENT | AT91_UDP_FORCESTALL); - __raw_writel(csr, creg); - VDBG("ep0 stalled\n"); - csr = __raw_readl(creg); - } - if (csr & AT91_UDP_RXSETUP) { - nuke(ep0, 0); - udc->req_pending = 0; - handle_setup(udc, ep0, csr); - return; - } - - if (list_empty(&ep0->queue)) - req = NULL; - else - req = list_entry(ep0->queue.next, struct at91_request, queue); - - /* host ACKed an IN packet that we sent */ - if (csr & AT91_UDP_TXCOMP) { - csr |= CLR_FX; - csr &= ~(SET_FX | AT91_UDP_TXCOMP); - - /* write more IN DATA? */ - if (req && ep0->is_in) { - if (handle_ep(ep0)) - udc->req_pending = 0; - - /* - * Ack after: - * - last IN DATA packet (including GET_STATUS) - * - IN/STATUS for OUT DATA - * - IN/STATUS for any zero-length DATA stage - * except for the IN DATA case, the host should send - * an OUT status later, which we'll ack. - */ - } else { - udc->req_pending = 0; - __raw_writel(csr, creg); - - /* - * SET_ADDRESS takes effect only after the STATUS - * (to the original address) gets acked. - */ - if (udc->wait_for_addr_ack) { - u32 tmp; - - at91_udp_write(AT91_UDP_FADDR, AT91_UDP_FEN | udc->addr); - tmp = at91_udp_read(AT91_UDP_GLB_STAT); - tmp &= ~AT91_UDP_FADDEN; - if (udc->addr) - tmp |= AT91_UDP_FADDEN; - at91_udp_write(AT91_UDP_GLB_STAT, tmp); - - udc->wait_for_addr_ack = 0; - VDBG("address %d\n", udc->addr); - } - } - } - - /* OUT packet arrived ... */ - else if (csr & AT91_UDP_RX_DATA_BK0) { - csr |= CLR_FX; - csr &= ~(SET_FX | AT91_UDP_RX_DATA_BK0); - - /* OUT DATA stage */ - if (!ep0->is_in) { - if (req) { - if (handle_ep(ep0)) { - /* send IN/STATUS */ - PACKET("ep0 in/status\n"); - csr = __raw_readl(creg); - csr &= ~SET_FX; - csr |= CLR_FX | AT91_UDP_TXPKTRDY; - __raw_writel(csr, creg); - udc->req_pending = 0; - } - } else if (udc->req_pending) { - /* - * AT91 hardware has a hard time with this - * "deferred response" mode for control-OUT - * transfers. (For control-IN it's fine.) - * - * The normal solution leaves OUT data in the - * fifo until the gadget driver is ready. - * We couldn't do that here without disabling - * the IRQ that tells about SETUP packets, - * e.g. when the host gets impatient... - * - * Working around it by copying into a buffer - * would almost be a non-deferred response, - * except that it wouldn't permit reliable - * stalling of the request. Instead, demand - * that gadget drivers not use this mode. - */ - DBG("no control-OUT deferred responses!\n"); - __raw_writel(csr | AT91_UDP_FORCESTALL, creg); - udc->req_pending = 0; - } - - /* STATUS stage for control-IN; ack. */ - } else { - PACKET("ep0 out/status ACK\n"); - __raw_writel(csr, creg); - - /* "early" status stage */ - if (req) - done(ep0, req, 0); - } - } -} - -static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r) -{ - struct at91_udc *udc = _udc; - u32 rescans = 5; - - while (rescans--) { - u32 status = at91_udp_read(AT91_UDP_ISR); - - status &= at91_udp_read(AT91_UDP_IMR); - if (!status) - break; - - /* USB reset irq: not maskable */ - if (status & AT91_UDP_ENDBUSRES) { - at91_udp_write(AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS); - at91_udp_write(AT91_UDP_IER, MINIMUS_INTERRUPTUS); - /* Atmel code clears this irq twice */ - at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES); - at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES); - VDBG("end bus reset\n"); - udc->addr = 0; - stop_activity(udc); - - /* enable ep0 */ - at91_udp_write(AT91_UDP_CSR(0), AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); - udc->gadget.speed = USB_SPEED_FULL; - udc->suspended = 0; - at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0)); - - /* - * NOTE: this driver keeps clocks off unless the - * USB host is present. That saves power, and also - * eliminates IRQs (reset, resume, suspend) that can - * otherwise flood from the controller. If your - * board doesn't support VBUS detection, suspend and - * resume irq logic may need more attention... - */ - - /* host initiated suspend (3+ms bus idle) */ - } else if (status & AT91_UDP_RXSUSP) { - at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXSUSP); - at91_udp_write(AT91_UDP_IER, AT91_UDP_RXRSM); - at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXSUSP); - // VDBG("bus suspend\n"); - if (udc->suspended) - continue; - udc->suspended = 1; - - /* - * NOTE: when suspending a VBUS-powered device, the - * gadget driver should switch into slow clock mode - * and then into standby to avoid drawing more than - * 500uA power (2500uA for some high-power configs). - */ - if (udc->driver && udc->driver->suspend) - udc->driver->suspend(&udc->gadget); - - /* host initiated resume */ - } else if (status & AT91_UDP_RXRSM) { - at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXRSM); - at91_udp_write(AT91_UDP_IER, AT91_UDP_RXSUSP); - at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXRSM); - // VDBG("bus resume\n"); - if (!udc->suspended) - continue; - udc->suspended = 0; - - /* - * NOTE: for a VBUS-powered device, the gadget driver - * would normally want to switch out of slow clock - * mode into normal mode. - */ - if (udc->driver && udc->driver->resume) - udc->driver->resume(&udc->gadget); - - /* endpoint IRQs are cleared by handling them */ - } else { - int i; - unsigned mask = 1; - struct at91_ep *ep = &udc->ep[1]; - - if (status & mask) - handle_ep0(udc); - for (i = 1; i < NUM_ENDPOINTS; i++) { - mask <<= 1; - if (status & mask) - handle_ep(ep); - ep++; - } - } - } - - return IRQ_HANDLED; -} - -/*-------------------------------------------------------------------------*/ - -static struct at91_udc controller = { - .gadget = { - .ops = &at91_udc_ops, - .ep0 = &controller.ep[0].ep, - .name = driver_name, - .dev = { - .bus_id = "gadget" - } - }, - .ep[0] = { - .ep = { - .name = ep0name, - .ops = &at91_ep_ops, - }, - .udc = &controller, - .maxpacket = 8, - .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(0)), - .int_mask = 1 << 0, - }, - .ep[1] = { - .ep = { - .name = "ep1", - .ops = &at91_ep_ops, - }, - .udc = &controller, - .is_pingpong = 1, - .maxpacket = 64, - .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(1)), - .int_mask = 1 << 1, - }, - .ep[2] = { - .ep = { - .name = "ep2", - .ops = &at91_ep_ops, - }, - .udc = &controller, - .is_pingpong = 1, - .maxpacket = 64, - .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(2)), - .int_mask = 1 << 2, - }, - .ep[3] = { - .ep = { - /* could actually do bulk too */ - .name = "ep3-int", - .ops = &at91_ep_ops, - }, - .udc = &controller, - .maxpacket = 8, - .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(3)), - .int_mask = 1 << 3, - }, - .ep[4] = { - .ep = { - .name = "ep4", - .ops = &at91_ep_ops, - }, - .udc = &controller, - .is_pingpong = 1, - .maxpacket = 256, - .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(4)), - .int_mask = 1 << 4, - }, - .ep[5] = { - .ep = { - .name = "ep5", - .ops = &at91_ep_ops, - }, - .udc = &controller, - .is_pingpong = 1, - .maxpacket = 256, - .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(5)), - .int_mask = 1 << 5, - }, - /* ep6 and ep7 are also reserved */ -}; - -static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r) -{ - struct at91_udc *udc = _udc; - unsigned value; - - /* vbus needs at least brief debouncing */ - udelay(10); - value = at91_get_gpio_value(udc->board.vbus_pin); - if (value != udc->vbus) - at91_vbus_session(&udc->gadget, value); - - return IRQ_HANDLED; -} - -int usb_gadget_register_driver (struct usb_gadget_driver *driver) -{ - struct at91_udc *udc = &controller; - int retval; - - if (!driver - || driver->speed != USB_SPEED_FULL - || !driver->bind - || !driver->unbind - || !driver->setup) { - DBG("bad parameter.\n"); - return -EINVAL; - } - - if (udc->driver) { - DBG("UDC already has a gadget driver\n"); - return -EBUSY; - } - - udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; - udc->gadget.dev.driver_data = &driver->driver; - udc->enabled = 1; - udc->selfpowered = 1; - - retval = driver->bind(&udc->gadget); - if (retval) { - DBG("driver->bind() returned %d\n", retval); - udc->driver = NULL; - return retval; - } - - local_irq_disable(); - pullup(udc, 1); - local_irq_enable(); - - DBG("bound to %s\n", driver->driver.name); - return 0; -} -EXPORT_SYMBOL (usb_gadget_register_driver); - -int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) -{ - struct at91_udc *udc = &controller; - - if (!driver || driver != udc->driver) - return -EINVAL; - - local_irq_disable(); - udc->enabled = 0; - pullup(udc, 0); - local_irq_enable(); - - driver->unbind(&udc->gadget); - udc->driver = NULL; - - DBG("unbound from %s\n", driver->driver.name); - return 0; -} -EXPORT_SYMBOL (usb_gadget_unregister_driver); - -/*-------------------------------------------------------------------------*/ - -static void at91udc_shutdown(struct platform_device *dev) -{ - /* force disconnect on reboot */ - pullup(platform_get_drvdata(dev), 0); -} - -static int __devinit at91udc_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct at91_udc *udc; - int retval; - - if (!dev->platform_data) { - /* small (so we copy it) but critical! */ - DBG("missing platform_data\n"); - return -ENODEV; - } - - if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) { - DBG("someone's using UDC memory\n"); - return -EBUSY; - } - - /* init software state */ - udc = &controller; - udc->gadget.dev.parent = dev; - udc->board = *(struct at91_udc_data *) dev->platform_data; - udc->pdev = pdev; - udc_reinit(udc); - udc->enabled = 0; - - /* get interface and function clocks */ - udc->iclk = clk_get(dev, "udc_clk"); - udc->fclk = clk_get(dev, "udpck"); - if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { - DBG("clocks missing\n"); - return -ENODEV; - } - - retval = device_register(&udc->gadget.dev); - if (retval < 0) - goto fail0; - - /* disable everything until there's a gadget driver and vbus */ - pullup(udc, 0); - - /* request UDC and maybe VBUS irqs */ - if (request_irq(AT91_ID_UDP, at91_udc_irq, SA_INTERRUPT, driver_name, udc)) { - DBG("request irq %d failed\n", AT91_ID_UDP); - retval = -EBUSY; - goto fail1; - } - if (udc->board.vbus_pin > 0) { - if (request_irq(udc->board.vbus_pin, at91_vbus_irq, SA_INTERRUPT, driver_name, udc)) { - DBG("request vbus irq %d failed\n", udc->board.vbus_pin); - free_irq(AT91_ID_UDP, udc); - retval = -EBUSY; - goto fail1; - } - } else { - DBG("no VBUS detection, assuming always-on\n"); - udc->vbus = 1; - } - dev_set_drvdata(dev, udc); - create_debug_file(udc); - - INFO("%s version %s\n", driver_name, DRIVER_VERSION); - return 0; - -fail1: - device_unregister(&udc->gadget.dev); -fail0: - release_mem_region(AT91_VA_BASE_UDP, SZ_16K); - DBG("%s probe failed, %d\n", driver_name, retval); - return retval; -} - -static int __devexit at91udc_remove(struct platform_device *dev) -{ - struct at91_udc *udc = platform_get_drvdata(dev); - - DBG("remove\n"); - - pullup(udc, 0); - - if (udc->driver != 0) - usb_gadget_unregister_driver(udc->driver); - - remove_debug_file(udc); - if (udc->board.vbus_pin > 0) - free_irq(udc->board.vbus_pin, udc); - free_irq(AT91_ID_UDP, udc); - device_unregister(&udc->gadget.dev); - release_mem_region(AT91_BASE_UDP, SZ_16K); - - clk_put(udc->iclk); - clk_put(udc->fclk); - - return 0; -} - -#ifdef CONFIG_PM -static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg) -{ - struct at91_udc *udc = platform_get_drvdata(dev); - - /* - * The "safe" suspend transitions are opportunistic ... e.g. when - * the USB link is suspended (48MHz clock autogated off), or when - * it's disconnected (programmatically gated off, elsewhere). - * Then we can suspend, and the chip can enter slow clock mode. - * - * The problem case is some component (user mode?) suspending this - * device while it's active, with the 48 MHz clock in use. There - * are two basic approaches: (a) veto suspend levels involving slow - * clock mode, (b) disconnect, so 48 MHz will no longer be in use - * and we can enter slow clock mode. This uses (b) for now, since - * it's simplest until AT91 PM exists and supports the other option. - */ - if (udc->vbus && !udc->suspended) - pullup(udc, 0); - return 0; -} - -static int at91udc_resume(struct platform_device *dev) -{ - struct at91_udc *udc = platform_get_drvdata(dev); - - /* maybe reconnect to host; if so, clocks on */ - pullup(udc, 1); - return 0; -} -#else -#define at91udc_suspend NULL -#define at91udc_resume NULL -#endif - -static struct platform_driver at91_udc = { - .probe = at91udc_probe, - .remove = __devexit_p(at91udc_remove), - .shutdown = at91udc_shutdown, - .suspend = at91udc_suspend, - .resume = at91udc_resume, - .driver = { - .name = (char *) driver_name, - .owner = THIS_MODULE, - }, -}; - -static int __devinit udc_init_module(void) -{ - return platform_driver_register(&at91_udc); -} -module_init(udc_init_module); - -static void __devexit udc_exit_module(void) -{ - platform_driver_unregister(&at91_udc); -} -module_exit(udc_exit_module); - -MODULE_DESCRIPTION("AT91RM9200 udc driver"); -MODULE_AUTHOR("Thomas Rathbone, David Brownell"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h deleted file mode 100644 index 5a4799ced..000000000 --- a/drivers/usb/gadget/at91_udc.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2004 by Thomas Rathbone, HP Labs - * Copyright (C) 2005 by Ivan Kokshaysky - * Copyright (C) 2006 by SAN People - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 AT91_UDC_H -#define AT91_UDC_H - -/* - * USB Device Port (UDP) registers. - * Based on AT91RM9200 datasheet revision E. - */ - -#define AT91_UDP_FRM_NUM 0x00 /* Frame Number Register */ -#define AT91_UDP_NUM (0x7ff << 0) /* Frame Number */ -#define AT91_UDP_FRM_ERR (1 << 16) /* Frame Error */ -#define AT91_UDP_FRM_OK (1 << 17) /* Frame OK */ - -#define AT91_UDP_GLB_STAT 0x04 /* Global State Register */ -#define AT91_UDP_FADDEN (1 << 0) /* Function Address Enable */ -#define AT91_UDP_CONFG (1 << 1) /* Configured */ -#define AT91_UDP_ESR (1 << 2) /* Enable Send Resume */ -#define AT91_UDP_RSMINPR (1 << 3) /* Resume has been sent */ -#define AT91_UDP_RMWUPE (1 << 4) /* Remote Wake Up Enable */ - -#define AT91_UDP_FADDR 0x08 /* Function Address Register */ -#define AT91_UDP_FADD (0x7f << 0) /* Function Address Value */ -#define AT91_UDP_FEN (1 << 8) /* Function Enable */ - -#define AT91_UDP_IER 0x10 /* Interrupt Enable Register */ -#define AT91_UDP_IDR 0x14 /* Interrupt Disable Register */ -#define AT91_UDP_IMR 0x18 /* Interrupt Mask Register */ - -#define AT91_UDP_ISR 0x1c /* Interrupt Status Register */ -#define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ -#define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ -#define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ -#define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status */ -#define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ -#define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ -#define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status */ - -#define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ -#define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ - -#define AT91_UDP_CSR(n) (0x30+((n)*4)) /* Endpoint Control/Status Registers 0-7 */ -#define AT91_UDP_TXCOMP (1 << 0) /* Generates IN packet with data previously written in DPR */ -#define AT91_UDP_RX_DATA_BK0 (1 << 1) /* Receive Data Bank 0 */ -#define AT91_UDP_RXSETUP (1 << 2) /* Send STALL to the host */ -#define AT91_UDP_STALLSENT (1 << 3) /* Stall Sent / Isochronous error (Isochronous endpoints) */ -#define AT91_UDP_TXPKTRDY (1 << 4) /* Transmit Packet Ready */ -#define AT91_UDP_FORCESTALL (1 << 5) /* Force Stall */ -#define AT91_UDP_RX_DATA_BK1 (1 << 6) /* Receive Data Bank 1 */ -#define AT91_UDP_DIR (1 << 7) /* Transfer Direction */ -#define AT91_UDP_EPTYPE (7 << 8) /* Endpoint Type */ -#define AT91_UDP_EPTYPE_CTRL (0 << 8) -#define AT91_UDP_EPTYPE_ISO_OUT (1 << 8) -#define AT91_UDP_EPTYPE_BULK_OUT (2 << 8) -#define AT91_UDP_EPTYPE_INT_OUT (3 << 8) -#define AT91_UDP_EPTYPE_ISO_IN (5 << 8) -#define AT91_UDP_EPTYPE_BULK_IN (6 << 8) -#define AT91_UDP_EPTYPE_INT_IN (7 << 8) -#define AT91_UDP_DTGLE (1 << 11) /* Data Toggle */ -#define AT91_UDP_EPEDS (1 << 15) /* Endpoint Enable/Disable */ -#define AT91_UDP_RXBYTECNT (0x7ff << 16) /* Number of bytes in FIFO */ - -#define AT91_UDP_FDR(n) (0x50+((n)*4)) /* Endpoint FIFO Data Registers 0-7 */ - -#define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ -#define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ - - -/*-------------------------------------------------------------------------*/ - -/* - * controller driver data structures - */ - -#define NUM_ENDPOINTS 6 - -/* - * hardware won't disable bus reset, or resume while the controller - * is suspended ... watching suspend helps keep the logic symmetric. - */ -#define MINIMUS_INTERRUPTUS \ - (AT91_UDP_ENDBUSRES | AT91_UDP_RXRSM | AT91_UDP_RXSUSP) - -struct at91_ep { - struct usb_ep ep; - struct list_head queue; - struct at91_udc *udc; - void __iomem *creg; - - unsigned maxpacket:16; - u8 int_mask; - unsigned is_pingpong:1; - - unsigned stopped:1; - unsigned is_in:1; - unsigned is_iso:1; - unsigned fifo_bank:1; - - const struct usb_endpoint_descriptor - *desc; -}; - -/* - * driver is non-SMP, and just blocks IRQs whenever it needs - * access protection for chip registers or driver state - */ -struct at91_udc { - struct usb_gadget gadget; - struct at91_ep ep[NUM_ENDPOINTS]; - struct usb_gadget_driver *driver; - unsigned vbus:1; - unsigned enabled:1; - unsigned clocked:1; - unsigned suspended:1; - unsigned req_pending:1; - unsigned wait_for_addr_ack:1; - unsigned wait_for_config_ack:1; - unsigned selfpowered:1; - u8 addr; - struct at91_udc_data board; - struct clk *iclk, *fclk; - struct platform_device *pdev; - struct proc_dir_entry *pde; -}; - -static inline struct at91_udc *to_udc(struct usb_gadget *g) -{ - return container_of(g, struct at91_udc, gadget); -} - -struct at91_request { - struct usb_request req; - struct list_head queue; -}; - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -#define DBG(stuff...) printk(KERN_DEBUG "udc: " stuff) -#else -#define DBG(stuff...) do{}while(0) -#endif - -#ifdef VERBOSE -# define VDBG DBG -#else -# define VDBG(stuff...) do{}while(0) -#endif - -#ifdef PACKET_TRACE -# define PACKET VDBG -#else -# define PACKET(stuff...) do{}while(0) -#endif - -#define ERR(stuff...) printk(KERN_ERR "udc: " stuff) -#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) -#define INFO(stuff...) printk(KERN_INFO "udc: " stuff) - -#endif - diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 42ce41d71..9734cb76d 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -478,9 +478,10 @@ dummy_alloc_request (struct usb_ep *_ep, gfp_t mem_flags) return NULL; ep = usb_ep_to_dummy_ep (_ep); - req = kzalloc(sizeof(*req), mem_flags); + req = kmalloc (sizeof *req, mem_flags); if (!req) return NULL; + memset (req, 0, sizeof *req); INIT_LIST_HEAD (&req->queue); return &req->req; } diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 9c4422ac9..afc84cfb6 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -182,37 +182,33 @@ struct eth_dev { * parameters are in UTF-8 (superset of ASCII's 7 bit characters). */ -static ushort idVendor; +static ushort __initdata idVendor; module_param(idVendor, ushort, S_IRUGO); MODULE_PARM_DESC(idVendor, "USB Vendor ID"); -static ushort idProduct; +static ushort __initdata idProduct; module_param(idProduct, ushort, S_IRUGO); MODULE_PARM_DESC(idProduct, "USB Product ID"); -static ushort bcdDevice; +static ushort __initdata bcdDevice; module_param(bcdDevice, ushort, S_IRUGO); MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); -static char *iManufacturer; +static char *__initdata iManufacturer; module_param(iManufacturer, charp, S_IRUGO); MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); -static char *iProduct; +static char *__initdata iProduct; module_param(iProduct, charp, S_IRUGO); MODULE_PARM_DESC(iProduct, "USB Product string"); -static char *iSerialNumber; -module_param(iSerialNumber, charp, S_IRUGO); -MODULE_PARM_DESC(iSerialNumber, "SerialNumber"); - /* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */ -static char *dev_addr; +static char *__initdata dev_addr; module_param(dev_addr, charp, S_IRUGO); MODULE_PARM_DESC(dev_addr, "Device Ethernet Address"); /* this address is invisible to ifconfig */ -static char *host_addr; +static char *__initdata host_addr; module_param(host_addr, charp, S_IRUGO); MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); @@ -257,14 +253,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_CDC #endif -#ifdef CONFIG_USB_GADGET_MUSBHSFC -#define DEV_CONFIG_CDC -#endif - -#ifdef CONFIG_USB_GADGET_MUSBHDRC -#define DEV_CONFIG_CDC -#endif - /* For CDC-incapable hardware, choose the simple cdc subset. * Anything that talks bulk (without notable bugs) can do this. @@ -407,7 +395,6 @@ static inline int BITRATE(struct usb_gadget *g) #define STRING_CDC 7 #define STRING_SUBSET 8 #define STRING_RNDIS 9 -#define STRING_SERIALNUMBER 10 /* holds our biggest descriptor (or RNDIS response) */ #define USB_BUFSIZ 256 @@ -875,7 +862,6 @@ static inline void __init hs_subset_descriptors(void) static char manufacturer [50]; static char product_desc [40] = DRIVER_DESC; -static char serial_number [20]; #ifdef DEV_CONFIG_CDC /* address that the host will use ... usually assigned at random */ @@ -886,7 +872,6 @@ static char ethaddr [2 * ETH_ALEN + 1]; static struct usb_string strings [] = { { STRING_MANUFACTURER, manufacturer, }, { STRING_PRODUCT, product_desc, }, - { STRING_SERIALNUMBER, serial_number, }, { STRING_DATA, "Ethernet Data", }, #ifdef DEV_CONFIG_CDC { STRING_CDC, "CDC Ethernet", }, @@ -1564,8 +1549,7 @@ static int eth_change_mtu (struct net_device *net, int new_mtu) { struct eth_dev *dev = netdev_priv(net); - if (dev->rndis) - return -EBUSY; + // FIXME if rndis, don't change while link's live if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN) return -ERANGE; @@ -2132,7 +2116,7 @@ eth_req_free (struct usb_ep *ep, struct usb_request *req) } -static void __exit +static void eth_unbind (struct usb_gadget *gadget) { struct eth_dev *dev = get_gadget_data (gadget); @@ -2169,7 +2153,7 @@ static u8 __init nibble (unsigned char c) return 0; } -static int __init get_ether_addr(const char *str, u8 *dev_addr) +static void __init get_ether_addr (const char *str, u8 *dev_addr) { if (str) { unsigned i; @@ -2184,10 +2168,9 @@ static int __init get_ether_addr(const char *str, u8 *dev_addr) dev_addr [i] = num; } if (is_valid_ether_addr (dev_addr)) - return 0; + return; } random_ether_addr(dev_addr); - return 1; } static int __init @@ -2285,10 +2268,6 @@ eth_bind (struct usb_gadget *gadget) strlcpy (manufacturer, iManufacturer, sizeof manufacturer); if (iProduct) strlcpy (product_desc, iProduct, sizeof product_desc); - if (iSerialNumber) { - device_desc.iSerialNumber = STRING_SERIALNUMBER, - strlcpy(serial_number, iSerialNumber, sizeof serial_number); - } /* all we really need is bulk IN/OUT */ usb_ep_autoconfig_reset (gadget); @@ -2338,9 +2317,6 @@ autoconf_fail: hs_subset_descriptors(); } - device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; - usb_gadget_set_selfpowered (gadget); - /* For now RNDIS is always a second config */ if (rndis) device_desc.bNumConfigurations = 2; @@ -2364,6 +2340,9 @@ autoconf_fail: #endif #endif /* DUALSPEED */ + device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; + usb_gadget_set_selfpowered (gadget); + if (gadget->is_otg) { otg_descriptor.bmAttributes |= USB_OTG_HNP, eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; @@ -2398,13 +2377,9 @@ autoconf_fail: * The host side address is used with CDC and RNDIS, and commonly * ends up in a persistent config database. */ - if (get_ether_addr(dev_addr, net->dev_addr)) - dev_warn(&gadget->dev, - "using random %s ethernet address\n", "self"); + get_ether_addr(dev_addr, net->dev_addr); if (cdc || rndis) { - if (get_ether_addr(host_addr, dev->host_mac)) - dev_warn(&gadget->dev, - "using random %s ethernet address\n", "host"); + get_ether_addr(host_addr, dev->host_mac); #ifdef DEV_CONFIG_CDC snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", dev->host_mac [0], dev->host_mac [1], @@ -2548,7 +2523,7 @@ static struct usb_gadget_driver eth_driver = { .function = (char *) driver_desc, .bind = eth_bind, - .unbind = __exit_p(eth_unbind), + .unbind = eth_unbind, .setup = eth_setup, .disconnect = eth_disconnect, diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 6f887478b..de59c5889 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -71,12 +71,6 @@ * requirement amounts to two 16K buffers, size configurable by a parameter. * Support is included for both full-speed and high-speed operation. * - * Note that the driver is slightly non-portable in that it assumes a - * single memory/DMA buffer will be useable for bulk-in, bulk-out, and - * interrupt-in endpoints. With most device controllers this isn't an - * issue, but there may be some with hardware restrictions that prevent - * a buffer from being used by more than one endpoint. - * * Module options: * * file=filename[,filename...] @@ -114,14 +108,6 @@ * setting are not allowed when the medium is loaded. * * This gadget driver is heavily based on "Gadget Zero" by David Brownell. - * The driver's SCSI command interface was based on the "Information - * technology - Small Computer System Interface - 2" document from - * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at - * . The single exception - * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the - * "Universal Serial Bus Mass Storage Class UFI Command Specification" - * document, Revision 1.0, December 14, 1998, available at - * . */ @@ -348,9 +334,11 @@ MODULE_LICENSE("Dual BSD/GPL"); #define MAX_LUNS 8 + /* Arggh! There should be a module_param_array_named macro! */ +static char *file[MAX_LUNS]; +static int ro[MAX_LUNS]; + static struct { - char *file[MAX_LUNS]; - int ro[MAX_LUNS]; int num_filenames; int num_ros; unsigned int nluns; @@ -382,11 +370,10 @@ static struct { }; -module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, - S_IRUGO); +module_param_array(file, charp, &mod_data.num_filenames, S_IRUGO); MODULE_PARM_DESC(file, "names of backing files or devices"); -module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); +module_param_array(ro, bool, &mod_data.num_ros, S_IRUGO); MODULE_PARM_DESC(ro, "true to force read-only"); module_param_named(luns, mod_data.nluns, uint, S_IRUGO); @@ -1808,7 +1795,6 @@ static int do_write(struct fsg_dev *fsg) * the bulk-out maxpacket size */ bh->outreq->length = bh->bulk_out_intended_length = amount; - bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); fsg->next_buffhd_to_fill = bh->next; @@ -2412,7 +2398,6 @@ static int throw_away_data(struct fsg_dev *fsg) * the bulk-out maxpacket size */ bh->outreq->length = bh->bulk_out_intended_length = amount; - bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); fsg->next_buffhd_to_fill = bh->next; @@ -3044,7 +3029,6 @@ static int get_next_command(struct fsg_dev *fsg) /* Queue a request to read a Bulk-only CBW */ set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); - bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); @@ -3694,7 +3678,7 @@ static void lun_release(struct device *dev) kref_put(&fsg->ref, fsg_release); } -static void __exit fsg_unbind(struct usb_gadget *gadget) +static void fsg_unbind(struct usb_gadget *gadget) { struct fsg_dev *fsg = get_gadget_data(gadget); int i; @@ -3875,7 +3859,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) for (i = 0; i < fsg->nluns; ++i) { curlun = &fsg->luns[i]; - curlun->ro = mod_data.ro[i]; + curlun->ro = ro[i]; curlun->dev.parent = &gadget->dev; curlun->dev.driver = &fsg_driver.driver; dev_set_drvdata(&curlun->dev, fsg); @@ -3892,9 +3876,8 @@ static int __init fsg_bind(struct usb_gadget *gadget) kref_get(&fsg->ref); } - if (mod_data.file[i] && *mod_data.file[i]) { - if ((rc = open_backing_file(curlun, - mod_data.file[i])) != 0) + if (file[i] && *file[i]) { + if ((rc = open_backing_file(curlun, file[i])) != 0) goto out; } else if (!mod_data.removable) { ERROR(fsg, "no file given for LUN%d\n", i); @@ -3970,9 +3953,6 @@ static int __init fsg_bind(struct usb_gadget *gadget) for (i = 0; i < NUM_BUFFERS; ++i) { struct fsg_buffhd *bh = &fsg->buffhds[i]; - /* Allocate for the bulk-in endpoint. We assume that - * the buffer will also work with the bulk-out (and - * interrupt-in) endpoint. */ bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen, &bh->dma, GFP_KERNEL); if (!bh->buf) @@ -4084,7 +4064,7 @@ static struct usb_gadget_driver fsg_driver = { #endif .function = (char *) longname, .bind = fsg_bind, - .unbind = __exit_p(fsg_unbind), + .unbind = fsg_unbind, .disconnect = fsg_disconnect, .setup = fsg_setup, .suspend = fsg_suspend, diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index aa80f0910..8cbae21d8 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -3,9 +3,9 @@ * gadget drivers or other code that needs to deal with them, and which * autoconfigures instead of using early binding to the hardware. * - * This SHOULD eventually work like the ARM mach_is_*() stuff, driven by + * This could eventually work like the ARM mach_is_*() stuff, driven by * some config file that gets updated as new hardware is supported. - * (And avoiding all runtime comparisons in typical one-choice configs!) + * (And avoiding the runtime comparisons in typical one-choice cases.) * * NOTE: some of these controller drivers may not be available yet. */ @@ -93,26 +93,6 @@ #define gadget_is_imx(g) 0 #endif -/* Mentor high speed function controller */ -#ifdef CONFIG_USB_GADGET_MUSBHSFC -#define gadget_is_musbhsfc(g) !strcmp("musbhsfc_udc", (g)->name) -#else -#define gadget_is_musbhsfc(g) 0 -#endif - -/* Mentor high speed "dual role" controller, in peripheral role */ -#ifdef CONFIG_USB_GADGET_MUSB_HDRC -#define gadget_is_musbhdrc(g) !strcmp("musb_hdrc", (g)->name) -#else -#define gadget_is_musbhdrc(g) 0 -#endif - -#ifdef CONFIG_USB_GADGET_MPC8272 -#define gadget_is_mpc8272(g) !strcmp("mpc8272_udc", (g)->name) -#else -#define gadget_is_mpc8272(g) 0 -#endif - // CONFIG_USB_GADGET_SX2 // CONFIG_USB_GADGET_AU1X00 // ... @@ -163,11 +143,5 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x13; else if (gadget_is_imx(gadget)) return 0x14; - else if (gadget_is_musbhsfc(gadget)) - return 0x15; - else if (gadget_is_musbhdrc(gadget)) - return 0x16; - else if (gadget_is_mpc8272(gadget)) - return 0x17; return -ENOENT; } diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 66b81bbf6..b0f3cd63e 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -275,10 +275,11 @@ goku_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) if (!_ep) return NULL; - req = kzalloc(sizeof *req, gfp_flags); + req = kmalloc(sizeof *req, gfp_flags); if (!req) return NULL; + memset(req, 0, sizeof *req); req->req.dma = DMA_ADDR_INVALID; INIT_LIST_HEAD(&req->queue); return &req->req; diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 0eb010a3f..0aab7d24c 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -170,9 +170,10 @@ static struct dev_data *dev_new (void) { struct dev_data *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc (sizeof *dev, GFP_KERNEL); if (!dev) return NULL; + memset (dev, 0, sizeof *dev); dev->state = STATE_DEV_DISABLED; atomic_set (&dev->count, 1); spin_lock_init (&dev->lock); @@ -810,7 +811,7 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (value == 0) data->state = STATE_EP_ENABLED; break; -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED case USB_SPEED_HIGH: /* fails if caller didn't provide that descriptor... */ value = usb_ep_enable (ep, &data->hs_desc); @@ -982,7 +983,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) /* assume that was SET_CONFIGURATION */ if (dev->current_config) { unsigned power; -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED if (dev->gadget->speed == USB_SPEED_HIGH) power = dev->hs_config->bMaxPower; else @@ -1262,7 +1263,7 @@ static struct file_operations ep0_io_operations = { * Unrecognized ep0 requests may be handled in user space. */ -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED static void make_qualifier (struct dev_data *dev) { struct usb_qualifier_descriptor qual; @@ -1291,7 +1292,7 @@ static int config_buf (struct dev_data *dev, u8 type, unsigned index) { int len; -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED int hs; #endif @@ -1299,7 +1300,7 @@ config_buf (struct dev_data *dev, u8 type, unsigned index) if (index > 0) return -EINVAL; -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED hs = (dev->gadget->speed == USB_SPEED_HIGH); if (type == USB_DT_OTHER_SPEED_CONFIG) hs = !hs; @@ -1335,12 +1336,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->state = STATE_CONNECTED; dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { ERROR (dev, "no high speed config??\n"); return -EINVAL; } -#endif /* CONFIG_USB_GADGET_DUALSPEED */ +#endif /* HIGHSPEED */ INFO (dev, "connected\n"); event = next_event (dev, GADGETFS_CONNECT); @@ -1352,11 +1353,11 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) /* ... down_trylock (&data->lock) ... */ if (data->state != STATE_EP_DEFER_ENABLE) continue; -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED if (gadget->speed == USB_SPEED_HIGH) value = usb_ep_enable (ep, &data->hs_desc); else -#endif /* CONFIG_USB_GADGET_DUALSPEED */ +#endif /* HIGHSPEED */ value = usb_ep_enable (ep, &data->desc); if (value) { ERROR (dev, "deferred %s enable --> %d\n", @@ -1391,7 +1392,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) value = min (w_length, (u16) sizeof *dev->dev); req->buf = dev->dev; break; -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED case USB_DT_DEVICE_QUALIFIER: if (!dev->hs_config) break; @@ -1428,7 +1429,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) // user mode expected to disable endpoints } else { u8 config, power; -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED if (gadget->speed == USB_SPEED_HIGH) { config = dev->hs_config->bConfigurationValue; power = dev->hs_config->bMaxPower; @@ -1581,7 +1582,7 @@ restart: static struct inode * gadgetfs_create_file (struct super_block *sb, char const *name, - void *data, const struct file_operations *fops, + void *data, struct file_operations *fops, struct dentry **dentry_p); static int activate_ep_files (struct dev_data *dev) @@ -1591,9 +1592,10 @@ static int activate_ep_files (struct dev_data *dev) gadget_for_each_ep (ep, dev->gadget) { struct ep_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc (sizeof *data, GFP_KERNEL); if (!data) goto enomem; + memset (data, 0, sizeof data); data->state = STATE_EP_DISABLED; init_MUTEX (&data->lock); init_waitqueue_head (&data->wait); @@ -1614,7 +1616,6 @@ static int activate_ep_files (struct dev_data *dev) data, &ep_config_operations, &data->dentry); if (!data->inode) { - usb_ep_free_request(ep, data->req); kfree (data); goto enomem; } @@ -1729,7 +1730,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) } static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED +#ifdef HIGHSPEED .speed = USB_SPEED_HIGH, #else .speed = USB_SPEED_FULL, @@ -1956,7 +1957,7 @@ module_param (default_perm, uint, 0644); static struct inode * gadgetfs_make_inode (struct super_block *sb, - void *data, const struct file_operations *fops, + void *data, struct file_operations *fops, int mode) { struct inode *inode = new_inode (sb); @@ -1980,7 +1981,7 @@ gadgetfs_make_inode (struct super_block *sb, */ static struct inode * gadgetfs_create_file (struct super_block *sb, char const *name, - void *data, const struct file_operations *fops, + void *data, struct file_operations *fops, struct dentry **dentry_p) { struct dentry *dentry; diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 0d3424eda..1a362c5e7 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c @@ -1114,10 +1114,11 @@ static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, DEBUG("%s, %p\n", __FUNCTION__, ep); - req = kzalloc(sizeof(*req), gfp_flags); + req = kmalloc(sizeof *req, gfp_flags); if (!req) return 0; + memset(req, 0, sizeof *req); INIT_LIST_HEAD(&req->queue); return &req->req; diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 0b9293493..67b13ab2f 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -26,8 +26,6 @@ * Copyright (C) 2003 David Brownell * Copyright (C) 2003-2005 PLX Technology, Inc. * - * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility with 2282 chip - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -73,8 +71,8 @@ #include -#define DRIVER_DESC "PLX NET228x USB Peripheral Controller" -#define DRIVER_VERSION "2005 Sept 27" +#define DRIVER_DESC "PLX NET2280 USB Peripheral Controller" +#define DRIVER_VERSION "2005 Feb 03" #define DMA_ADDR_INVALID (~(dma_addr_t)0) #define EP_DONTUSE 13 /* nonzero */ @@ -120,7 +118,7 @@ module_param (fifo_mode, ushort, 0644); /* enable_suspend -- When enabled, the driver will respond to * USB suspend requests by powering down the NET2280. Otherwise, * USB suspend requests will be ignored. This is acceptible for - * self-powered devices + * self-powered devices, and helps avoid some quirks. */ static int enable_suspend = 0; @@ -225,11 +223,6 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) ep->is_in = (tmp & USB_DIR_IN) != 0; if (!ep->is_in) writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); - else if (dev->pdev->device != 0x2280) { - /* Added for 2282, Don't use nak packets on an in endpoint, this was ignored on 2280 */ - writel ((1 << CLEAR_NAK_OUT_PACKETS) - | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); - } writel (tmp, &ep->regs->ep_cfg); @@ -239,9 +232,8 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) writel (tmp, &dev->regs->pciirqenb0); tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) - | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); - if (dev->pdev->device == 0x2280) - tmp |= readl (&ep->regs->ep_irqenb); + | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE) + | readl (&ep->regs->ep_irqenb); writel (tmp, &ep->regs->ep_irqenb); } else { /* dma, per-request */ tmp = (1 << (8 + ep->num)); /* completion */ @@ -322,18 +314,10 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) /* init to our chosen defaults, notably so that we NAK OUT * packets until the driver queues a read (+note erratum 0112) */ - if (!ep->is_in || ep->dev->pdev->device == 0x2280) { - tmp = (1 << SET_NAK_OUT_PACKETS_MODE) + tmp = (1 << SET_NAK_OUT_PACKETS_MODE) | (1 << SET_NAK_OUT_PACKETS) | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | (1 << CLEAR_INTERRUPT_MODE); - } else { - /* added for 2282 */ - tmp = (1 << CLEAR_NAK_OUT_PACKETS_MODE) - | (1 << CLEAR_NAK_OUT_PACKETS) - | (1 << CLEAR_EP_HIDE_STATUS_PHASE) - | (1 << CLEAR_INTERRUPT_MODE); - } if (ep->num != 0) { tmp |= (1 << CLEAR_ENDPOINT_TOGGLE) @@ -342,18 +326,14 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) writel (tmp, &ep->regs->ep_rsp); /* scrub most status bits, and flush any fifo state */ - if (ep->dev->pdev->device == 0x2280) - tmp = (1 << FIFO_OVERFLOW) - | (1 << FIFO_UNDERFLOW); - else - tmp = 0; - - writel (tmp | (1 << TIMEOUT) + writel ( (1 << TIMEOUT) | (1 << USB_STALL_SENT) | (1 << USB_IN_NAK_SENT) | (1 << USB_IN_ACK_RCVD) | (1 << USB_OUT_PING_NAK_SENT) | (1 << USB_OUT_ACK_SENT) + | (1 << FIFO_OVERFLOW) + | (1 << FIFO_UNDERFLOW) | (1 << FIFO_FLUSH) | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) @@ -406,10 +386,11 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) return NULL; ep = container_of (_ep, struct net2280_ep, ep); - req = kzalloc(sizeof(*req), gfp_flags); + req = kmalloc (sizeof *req, gfp_flags); if (!req) return NULL; + memset (req, 0, sizeof *req); req->req.dma = DMA_ADDR_INVALID; INIT_LIST_HEAD (&req->queue); @@ -738,7 +719,7 @@ fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid) */ if (ep->is_in) dmacount |= (1 << DMA_DIRECTION); - if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) || ep->dev->pdev->device != 0x2280) + else if ((dmacount % ep->ep.maxpacket) != 0) dmacount |= (1 << END_OF_CHAIN); req->valid = valid; @@ -780,12 +761,9 @@ static inline void stop_dma (struct net2280_dma_regs __iomem *dma) static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) { struct net2280_dma_regs __iomem *dma = ep->dma; - unsigned int tmp = (1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION); - - if (ep->dev->pdev->device != 0x2280) - tmp |= (1 << END_OF_CHAIN); - writel (tmp, &dma->dmacount); + writel ((1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION), + &dma->dmacount); writel (readl (&dma->dmastat), &dma->dmastat); writel (td_dma, &dma->dmadesc); @@ -2133,11 +2111,7 @@ static void handle_ep_small (struct net2280_ep *ep) VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n", ep->ep.name, t, req ? &req->req : 0); #endif - if (!ep->is_in || ep->dev->pdev->device == 0x2280) - writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); - else - /* Added for 2282 */ - writel (t, &ep->regs->ep_stat); + writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); /* for ep0, monitor token irqs to catch data stage length errors * and to synchronize on status. @@ -2166,7 +2140,7 @@ static void handle_ep_small (struct net2280_ep *ep) ep->stopped = 1; set_halt (ep); mode = 2; - } else if (!req && !ep->stopped) + } else if (!req && ep->stopped) write_fifo (ep, NULL); } } else { @@ -2241,8 +2215,7 @@ static void handle_ep_small (struct net2280_ep *ep) if (likely (req)) { req->td->dmacount = 0; t = readl (&ep->regs->ep_avail); - dma_done (ep, req, count, - (ep->out_overflow || t) ? -EOVERFLOW : 0); + dma_done (ep, req, count, t); } /* also flush to prevent erratum 0106 trouble */ @@ -2280,7 +2253,9 @@ static void handle_ep_small (struct net2280_ep *ep) /* if we wrote it all, we're usually done */ if (req->req.actual == req->req.length) { if (ep->num == 0) { - /* send zlps until the status stage */ + /* wait for control status */ + if (mode != 2) + req = NULL; } else if (!req->req.zero || len != ep->ep.maxpacket) mode = 2; } @@ -2363,7 +2338,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) u32 raw [2]; struct usb_ctrlrequest r; } u; - int tmp; + int tmp = 0; struct net2280_request *req; if (dev->gadget.speed == USB_SPEED_UNKNOWN) { @@ -2390,19 +2365,14 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) } ep->stopped = 0; dev->protocol_stall = 0; - - if (ep->dev->pdev->device == 0x2280) - tmp = (1 << FIFO_OVERFLOW) - | (1 << FIFO_UNDERFLOW); - else - tmp = 0; - - writel (tmp | (1 << TIMEOUT) + writel ( (1 << TIMEOUT) | (1 << USB_STALL_SENT) | (1 << USB_IN_NAK_SENT) | (1 << USB_IN_ACK_RCVD) | (1 << USB_OUT_PING_NAK_SENT) | (1 << USB_OUT_ACK_SENT) + | (1 << FIFO_OVERFLOW) + | (1 << FIFO_UNDERFLOW) | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | (1 << DATA_PACKET_RECEIVED_INTERRUPT) @@ -2416,8 +2386,6 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) cpu_to_le32s (&u.raw [0]); cpu_to_le32s (&u.raw [1]); - tmp = 0; - #define w_value le16_to_cpup (&u.r.wValue) #define w_index le16_to_cpup (&u.r.wIndex) #define w_length le16_to_cpup (&u.r.wLength) @@ -2627,17 +2595,10 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) writel (stat, &dev->regs->irqstat1); /* some status we can just ignore */ - if (dev->pdev->device == 0x2280) - stat &= ~((1 << CONTROL_STATUS_INTERRUPT) - | (1 << SUSPEND_REQUEST_INTERRUPT) - | (1 << RESUME_INTERRUPT) - | (1 << SOF_INTERRUPT)); - else - stat &= ~((1 << CONTROL_STATUS_INTERRUPT) - | (1 << RESUME_INTERRUPT) - | (1 << SOF_DOWN_INTERRUPT) - | (1 << SOF_INTERRUPT)); - + stat &= ~((1 << CONTROL_STATUS_INTERRUPT) + | (1 << SUSPEND_REQUEST_INTERRUPT) + | (1 << RESUME_INTERRUPT) + | (1 << SOF_INTERRUPT)); if (!stat) return; // DEBUG (dev, "irqstat1 %08x\n", stat); @@ -2742,10 +2703,6 @@ static irqreturn_t net2280_irq (int irq, void *_dev, struct pt_regs * r) { struct net2280 *dev = _dev; - /* shared interrupt, not ours */ - if (!(readl(&dev->regs->irqstat0) & (1 << INTA_ASSERTED))) - return IRQ_NONE; - spin_lock (&dev->lock); /* handle disconnect, dma, and more */ @@ -2833,13 +2790,13 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) } /* alloc, and start init */ - dev = kzalloc (sizeof *dev, SLAB_KERNEL); + dev = kmalloc (sizeof *dev, SLAB_KERNEL); if (dev == NULL){ retval = -ENOMEM; goto done; } - pci_set_drvdata (pdev, dev); + memset (dev, 0, sizeof *dev); spin_lock_init (&dev->lock); dev->pdev = pdev; dev->gadget.ops = &net2280_ops; @@ -2952,6 +2909,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) dev->chiprev = get_idx_reg (dev->regs, REG_CHIPREV) & 0xffff; /* done */ + pci_set_drvdata (pdev, dev); INFO (dev, "%s\n", driver_desc); INFO (dev, "irq %s, pci mem %p, chip rev %04x\n", bufp, base, dev->chiprev); @@ -2982,13 +2940,6 @@ static struct pci_device_id pci_ids [] = { { .device = 0x2280, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, -}, { - .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), - .class_mask = ~0, - .vendor = 0x17cc, - .device = 0x2282, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, }, { /* end: all zeroes */ } }; diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h index 957d6df34..fff4509cf 100644 --- a/drivers/usb/gadget/net2280.h +++ b/drivers/usb/gadget/net2280.h @@ -22,7 +22,420 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +/*-------------------------------------------------------------------------*/ + +/* NET2280 MEMORY MAPPED REGISTERS + * + * The register layout came from the chip documentation, and the bit + * number definitions were extracted from chip specification. + * + * Use the shift operator ('<<') to build bit masks, with readl/writel + * to access the registers through PCI. + */ + +/* main registers, BAR0 + 0x0000 */ +struct net2280_regs { + // offset 0x0000 + u32 devinit; +#define LOCAL_CLOCK_FREQUENCY 8 +#define FORCE_PCI_RESET 7 +#define PCI_ID 6 +#define PCI_ENABLE 5 +#define FIFO_SOFT_RESET 4 +#define CFG_SOFT_RESET 3 +#define PCI_SOFT_RESET 2 +#define USB_SOFT_RESET 1 +#define M8051_RESET 0 + u32 eectl; +#define EEPROM_ADDRESS_WIDTH 23 +#define EEPROM_CHIP_SELECT_ACTIVE 22 +#define EEPROM_PRESENT 21 +#define EEPROM_VALID 20 +#define EEPROM_BUSY 19 +#define EEPROM_CHIP_SELECT_ENABLE 18 +#define EEPROM_BYTE_READ_START 17 +#define EEPROM_BYTE_WRITE_START 16 +#define EEPROM_READ_DATA 8 +#define EEPROM_WRITE_DATA 0 + u32 eeclkfreq; + u32 _unused0; + // offset 0x0010 + + u32 pciirqenb0; /* interrupt PCI master ... */ +#define SETUP_PACKET_INTERRUPT_ENABLE 7 +#define ENDPOINT_F_INTERRUPT_ENABLE 6 +#define ENDPOINT_E_INTERRUPT_ENABLE 5 +#define ENDPOINT_D_INTERRUPT_ENABLE 4 +#define ENDPOINT_C_INTERRUPT_ENABLE 3 +#define ENDPOINT_B_INTERRUPT_ENABLE 2 +#define ENDPOINT_A_INTERRUPT_ENABLE 1 +#define ENDPOINT_0_INTERRUPT_ENABLE 0 + u32 pciirqenb1; +#define PCI_INTERRUPT_ENABLE 31 +#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 +#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 +#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 +#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 +#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 +#define PCI_TARGET_ABORT_ASSERTED_INTERRUPT_ENABLE 18 +#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 +#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 +#define GPIO_INTERRUPT_ENABLE 13 +#define DMA_D_INTERRUPT_ENABLE 12 +#define DMA_C_INTERRUPT_ENABLE 11 +#define DMA_B_INTERRUPT_ENABLE 10 +#define DMA_A_INTERRUPT_ENABLE 9 +#define EEPROM_DONE_INTERRUPT_ENABLE 8 +#define VBUS_INTERRUPT_ENABLE 7 +#define CONTROL_STATUS_INTERRUPT_ENABLE 6 +#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 +#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 +#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 +#define RESUME_INTERRUPT_ENABLE 1 +#define SOF_INTERRUPT_ENABLE 0 + u32 cpu_irqenb0; /* ... or onboard 8051 */ +#define SETUP_PACKET_INTERRUPT_ENABLE 7 +#define ENDPOINT_F_INTERRUPT_ENABLE 6 +#define ENDPOINT_E_INTERRUPT_ENABLE 5 +#define ENDPOINT_D_INTERRUPT_ENABLE 4 +#define ENDPOINT_C_INTERRUPT_ENABLE 3 +#define ENDPOINT_B_INTERRUPT_ENABLE 2 +#define ENDPOINT_A_INTERRUPT_ENABLE 1 +#define ENDPOINT_0_INTERRUPT_ENABLE 0 + u32 cpu_irqenb1; +#define CPU_INTERRUPT_ENABLE 31 +#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 +#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 +#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 +#define PCI_INTA_INTERRUPT_ENABLE 24 +#define PCI_PME_INTERRUPT_ENABLE 23 +#define PCI_SERR_INTERRUPT_ENABLE 22 +#define PCI_PERR_INTERRUPT_ENABLE 21 +#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 +#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 +#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 +#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 +#define GPIO_INTERRUPT_ENABLE 13 +#define DMA_D_INTERRUPT_ENABLE 12 +#define DMA_C_INTERRUPT_ENABLE 11 +#define DMA_B_INTERRUPT_ENABLE 10 +#define DMA_A_INTERRUPT_ENABLE 9 +#define EEPROM_DONE_INTERRUPT_ENABLE 8 +#define VBUS_INTERRUPT_ENABLE 7 +#define CONTROL_STATUS_INTERRUPT_ENABLE 6 +#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 +#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 +#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 +#define RESUME_INTERRUPT_ENABLE 1 +#define SOF_INTERRUPT_ENABLE 0 + + // offset 0x0020 + u32 _unused1; + u32 usbirqenb1; +#define USB_INTERRUPT_ENABLE 31 +#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 +#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 +#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 +#define PCI_INTA_INTERRUPT_ENABLE 24 +#define PCI_PME_INTERRUPT_ENABLE 23 +#define PCI_SERR_INTERRUPT_ENABLE 22 +#define PCI_PERR_INTERRUPT_ENABLE 21 +#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 +#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 +#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 +#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 +#define GPIO_INTERRUPT_ENABLE 13 +#define DMA_D_INTERRUPT_ENABLE 12 +#define DMA_C_INTERRUPT_ENABLE 11 +#define DMA_B_INTERRUPT_ENABLE 10 +#define DMA_A_INTERRUPT_ENABLE 9 +#define EEPROM_DONE_INTERRUPT_ENABLE 8 +#define VBUS_INTERRUPT_ENABLE 7 +#define CONTROL_STATUS_INTERRUPT_ENABLE 6 +#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 +#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 +#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 +#define RESUME_INTERRUPT_ENABLE 1 +#define SOF_INTERRUPT_ENABLE 0 + u32 irqstat0; +#define INTA_ASSERTED 12 +#define SETUP_PACKET_INTERRUPT 7 +#define ENDPOINT_F_INTERRUPT 6 +#define ENDPOINT_E_INTERRUPT 5 +#define ENDPOINT_D_INTERRUPT 4 +#define ENDPOINT_C_INTERRUPT 3 +#define ENDPOINT_B_INTERRUPT 2 +#define ENDPOINT_A_INTERRUPT 1 +#define ENDPOINT_0_INTERRUPT 0 + u32 irqstat1; +#define POWER_STATE_CHANGE_INTERRUPT 27 +#define PCI_ARBITER_TIMEOUT_INTERRUPT 26 +#define PCI_PARITY_ERROR_INTERRUPT 25 +#define PCI_INTA_INTERRUPT 24 +#define PCI_PME_INTERRUPT 23 +#define PCI_SERR_INTERRUPT 22 +#define PCI_PERR_INTERRUPT 21 +#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT 20 +#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19 +#define PCI_RETRY_ABORT_INTERRUPT 17 +#define PCI_MASTER_CYCLE_DONE_INTERRUPT 16 +#define GPIO_INTERRUPT 13 +#define DMA_D_INTERRUPT 12 +#define DMA_C_INTERRUPT 11 +#define DMA_B_INTERRUPT 10 +#define DMA_A_INTERRUPT 9 +#define EEPROM_DONE_INTERRUPT 8 +#define VBUS_INTERRUPT 7 +#define CONTROL_STATUS_INTERRUPT 6 +#define ROOT_PORT_RESET_INTERRUPT 4 +#define SUSPEND_REQUEST_INTERRUPT 3 +#define SUSPEND_REQUEST_CHANGE_INTERRUPT 2 +#define RESUME_INTERRUPT 1 +#define SOF_INTERRUPT 0 + // offset 0x0030 + u32 idxaddr; + u32 idxdata; + u32 fifoctl; +#define PCI_BASE2_RANGE 16 +#define IGNORE_FIFO_AVAILABILITY 3 +#define PCI_BASE2_SELECT 2 +#define FIFO_CONFIGURATION_SELECT 0 + u32 _unused2; + // offset 0x0040 + u32 memaddr; +#define START 28 +#define DIRECTION 27 +#define FIFO_DIAGNOSTIC_SELECT 24 +#define MEMORY_ADDRESS 0 + u32 memdata0; + u32 memdata1; + u32 _unused3; + // offset 0x0050 + u32 gpioctl; +#define GPIO3_LED_SELECT 12 +#define GPIO3_INTERRUPT_ENABLE 11 +#define GPIO2_INTERRUPT_ENABLE 10 +#define GPIO1_INTERRUPT_ENABLE 9 +#define GPIO0_INTERRUPT_ENABLE 8 +#define GPIO3_OUTPUT_ENABLE 7 +#define GPIO2_OUTPUT_ENABLE 6 +#define GPIO1_OUTPUT_ENABLE 5 +#define GPIO0_OUTPUT_ENABLE 4 +#define GPIO3_DATA 3 +#define GPIO2_DATA 2 +#define GPIO1_DATA 1 +#define GPIO0_DATA 0 + u32 gpiostat; +#define GPIO3_INTERRUPT 3 +#define GPIO2_INTERRUPT 2 +#define GPIO1_INTERRUPT 1 +#define GPIO0_INTERRUPT 0 +} __attribute__ ((packed)); + +/* usb control, BAR0 + 0x0080 */ +struct net2280_usb_regs { + // offset 0x0080 + u32 stdrsp; +#define STALL_UNSUPPORTED_REQUESTS 31 +#define SET_TEST_MODE 16 +#define GET_OTHER_SPEED_CONFIGURATION 15 +#define GET_DEVICE_QUALIFIER 14 +#define SET_ADDRESS 13 +#define ENDPOINT_SET_CLEAR_HALT 12 +#define DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP 11 +#define GET_STRING_DESCRIPTOR_2 10 +#define GET_STRING_DESCRIPTOR_1 9 +#define GET_STRING_DESCRIPTOR_0 8 +#define GET_SET_INTERFACE 6 +#define GET_SET_CONFIGURATION 5 +#define GET_CONFIGURATION_DESCRIPTOR 4 +#define GET_DEVICE_DESCRIPTOR 3 +#define GET_ENDPOINT_STATUS 2 +#define GET_INTERFACE_STATUS 1 +#define GET_DEVICE_STATUS 0 + u32 prodvendid; +#define PRODUCT_ID 16 +#define VENDOR_ID 0 + u32 relnum; + u32 usbctl; +#define SERIAL_NUMBER_INDEX 16 +#define PRODUCT_ID_STRING_ENABLE 13 +#define VENDOR_ID_STRING_ENABLE 12 +#define USB_ROOT_PORT_WAKEUP_ENABLE 11 +#define VBUS_PIN 10 +#define TIMED_DISCONNECT 9 +#define SUSPEND_IMMEDIATELY 7 +#define SELF_POWERED_USB_DEVICE 6 +#define REMOTE_WAKEUP_SUPPORT 5 +#define PME_POLARITY 4 +#define USB_DETECT_ENABLE 3 +#define PME_WAKEUP_ENABLE 2 +#define DEVICE_REMOTE_WAKEUP_ENABLE 1 +#define SELF_POWERED_STATUS 0 + // offset 0x0090 + u32 usbstat; +#define HIGH_SPEED 7 +#define FULL_SPEED 6 +#define GENERATE_RESUME 5 +#define GENERATE_DEVICE_REMOTE_WAKEUP 4 + u32 xcvrdiag; +#define FORCE_HIGH_SPEED_MODE 31 +#define FORCE_FULL_SPEED_MODE 30 +#define USB_TEST_MODE 24 +#define LINE_STATE 16 +#define TRANSCEIVER_OPERATION_MODE 2 +#define TRANSCEIVER_SELECT 1 +#define TERMINATION_SELECT 0 + u32 setup0123; + u32 setup4567; + // offset 0x0090 + u32 _unused0; + u32 ouraddr; +#define FORCE_IMMEDIATE 7 +#define OUR_USB_ADDRESS 0 + u32 ourconfig; +} __attribute__ ((packed)); + +/* pci control, BAR0 + 0x0100 */ +struct net2280_pci_regs { + // offset 0x0100 + u32 pcimstctl; +#define PCI_ARBITER_PARK_SELECT 13 +#define PCI_MULTI LEVEL_ARBITER 12 +#define PCI_RETRY_ABORT_ENABLE 11 +#define DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE 10 +#define DMA_READ_MULTIPLE_ENABLE 9 +#define DMA_READ_LINE_ENABLE 8 +#define PCI_MASTER_COMMAND_SELECT 6 +#define MEM_READ_OR_WRITE 0 +#define IO_READ_OR_WRITE 1 +#define CFG_READ_OR_WRITE 2 +#define PCI_MASTER_START 5 +#define PCI_MASTER_READ_WRITE 4 +#define PCI_MASTER_WRITE 0 +#define PCI_MASTER_READ 1 +#define PCI_MASTER_BYTE_WRITE_ENABLES 0 + u32 pcimstaddr; + u32 pcimstdata; + u32 pcimststat; +#define PCI_ARBITER_CLEAR 2 +#define PCI_EXTERNAL_ARBITER 1 +#define PCI_HOST_MODE 0 +} __attribute__ ((packed)); + +/* dma control, BAR0 + 0x0180 ... array of four structs like this, + * for channels 0..3. see also struct net2280_dma: descriptor + * that can be loaded into some of these registers. + */ +struct net2280_dma_regs { /* [11.7] */ + // offset 0x0180, 0x01a0, 0x01c0, 0x01e0, + u32 dmactl; +#define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25 +#define DMA_CLEAR_COUNT_ENABLE 21 +#define DESCRIPTOR_POLLING_RATE 19 +#define POLL_CONTINUOUS 0 +#define POLL_1_USEC 1 +#define POLL_100_USEC 2 +#define POLL_1_MSEC 3 +#define DMA_VALID_BIT_POLLING_ENABLE 18 +#define DMA_VALID_BIT_ENABLE 17 +#define DMA_SCATTER_GATHER_ENABLE 16 +#define DMA_OUT_AUTO_START_ENABLE 4 +#define DMA_PREEMPT_ENABLE 3 +#define DMA_FIFO_VALIDATE 2 +#define DMA_ENABLE 1 +#define DMA_ADDRESS_HOLD 0 + u32 dmastat; +#define DMA_SCATTER_GATHER_DONE_INTERRUPT 25 +#define DMA_TRANSACTION_DONE_INTERRUPT 24 +#define DMA_ABORT 1 +#define DMA_START 0 + u32 _unused0 [2]; + // offset 0x0190, 0x01b0, 0x01d0, 0x01f0, + u32 dmacount; +#define VALID_BIT 31 +#define DMA_DIRECTION 30 +#define DMA_DONE_INTERRUPT_ENABLE 29 +#define END_OF_CHAIN 28 +#define DMA_BYTE_COUNT_MASK ((1<<24)-1) +#define DMA_BYTE_COUNT 0 + u32 dmaaddr; + u32 dmadesc; + u32 _unused1; +} __attribute__ ((packed)); + +/* dedicated endpoint registers, BAR0 + 0x0200 */ + +struct net2280_dep_regs { /* [11.8] */ + // offset 0x0200, 0x0210, 0x220, 0x230, 0x240 + u32 dep_cfg; + // offset 0x0204, 0x0214, 0x224, 0x234, 0x244 + u32 dep_rsp; + u32 _unused [2]; +} __attribute__ ((packed)); + +/* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs + * like this, for ep0 then the configurable endpoints A..F + * ep0 reserved for control; E and F have only 64 bytes of fifo + */ +struct net2280_ep_regs { /* [11.9] */ + // offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0 + u32 ep_cfg; +#define ENDPOINT_BYTE_COUNT 16 +#define ENDPOINT_ENABLE 10 +#define ENDPOINT_TYPE 8 +#define ENDPOINT_DIRECTION 7 +#define ENDPOINT_NUMBER 0 + u32 ep_rsp; +#define SET_NAK_OUT_PACKETS 15 +#define SET_EP_HIDE_STATUS_PHASE 14 +#define SET_EP_FORCE_CRC_ERROR 13 +#define SET_INTERRUPT_MODE 12 +#define SET_CONTROL_STATUS_PHASE_HANDSHAKE 11 +#define SET_NAK_OUT_PACKETS_MODE 10 +#define SET_ENDPOINT_TOGGLE 9 +#define SET_ENDPOINT_HALT 8 +#define CLEAR_NAK_OUT_PACKETS 7 +#define CLEAR_EP_HIDE_STATUS_PHASE 6 +#define CLEAR_EP_FORCE_CRC_ERROR 5 +#define CLEAR_INTERRUPT_MODE 4 +#define CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE 3 +#define CLEAR_NAK_OUT_PACKETS_MODE 2 +#define CLEAR_ENDPOINT_TOGGLE 1 +#define CLEAR_ENDPOINT_HALT 0 + u32 ep_irqenb; +#define SHORT_PACKET_OUT_DONE_INTERRUPT_ENABLE 6 +#define SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE 5 +#define DATA_PACKET_RECEIVED_INTERRUPT_ENABLE 3 +#define DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE 2 +#define DATA_OUT_PING_TOKEN_INTERRUPT_ENABLE 1 +#define DATA_IN_TOKEN_INTERRUPT_ENABLE 0 + u32 ep_stat; +#define FIFO_VALID_COUNT 24 +#define HIGH_BANDWIDTH_OUT_TRANSACTION_PID 22 +#define TIMEOUT 21 +#define USB_STALL_SENT 20 +#define USB_IN_NAK_SENT 19 +#define USB_IN_ACK_RCVD 18 +#define USB_OUT_PING_NAK_SENT 17 +#define USB_OUT_ACK_SENT 16 +#define FIFO_OVERFLOW 13 +#define FIFO_UNDERFLOW 12 +#define FIFO_FULL 11 +#define FIFO_EMPTY 10 +#define FIFO_FLUSH 9 +#define SHORT_PACKET_OUT_DONE_INTERRUPT 6 +#define SHORT_PACKET_TRANSFERRED_INTERRUPT 5 +#define NAK_OUT_PACKETS 4 +#define DATA_PACKET_RECEIVED_INTERRUPT 3 +#define DATA_PACKET_TRANSMITTED_INTERRUPT 2 +#define DATA_OUT_PING_TOKEN_INTERRUPT 1 +#define DATA_IN_TOKEN_INTERRUPT 0 + // offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0 + u32 ep_avail; + u32 ep_data; + u32 _unused0 [2]; +} __attribute__ ((packed)); /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index fbea51448..a8972d7c9 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -273,8 +273,9 @@ omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) { struct omap_req *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kmalloc(sizeof *req, gfp_flags); if (req) { + memset (req, 0, sizeof *req); req->req.dma = DMA_ADDR_INVALID; INIT_LIST_HEAD (&req->queue); } @@ -2585,10 +2586,11 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) /* UDC_PULLUP_EN gates the chip clock */ // OTG_SYSCON_1_REG |= DEV_IDLE_EN; - udc = kzalloc(sizeof(*udc), SLAB_KERNEL); + udc = kmalloc (sizeof *udc, SLAB_KERNEL); if (!udc) return -ENOMEM; + memset(udc, 0, sizeof *udc); spin_lock_init (&udc->lock); udc->gadget.ops = &omap_gadget_ops; diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 680f7fc5b..bb028c5b8 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -335,10 +335,11 @@ pxa2xx_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) { struct pxa2xx_request *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kmalloc (sizeof *req, gfp_flags); if (!req) return NULL; + memset (req, 0, sizeof *req); INIT_LIST_HEAD (&req->queue); return &req->req; } diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index b992546c3..ba9acd531 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -369,7 +369,7 @@ static struct usb_gadget_driver gs_gadget_driver = { #endif /* CONFIG_USB_GADGET_DUALSPEED */ .function = GS_LONG_NAME, .bind = gs_bind, - .unbind = __exit_p(gs_unbind), + .unbind = gs_unbind, .setup = gs_setup, .disconnect = gs_disconnect, .driver = { @@ -1413,7 +1413,7 @@ requeue: * Called on module load. Allocates and initializes the device * structure and a control request. */ -static int __init gs_bind(struct usb_gadget *gadget) +static int gs_bind(struct usb_gadget *gadget) { int ret; struct usb_ep *ep; @@ -1538,7 +1538,7 @@ autoconf_fail: * Called on module unload. Frees the control request and device * structure. */ -static void __exit gs_unbind(struct usb_gadget *gadget) +static void gs_unbind(struct usb_gadget *gadget) { struct gs_dev *dev = get_gadget_data(gadget); @@ -2178,9 +2178,10 @@ static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags) return -EIO; for (i=0; iport_dev = dev; port->port_num = i; port->port_line_coding.dwDTERate = cpu_to_le32(GS_DEFAULT_DTE_RATE); diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 68e3d8f5d..ae7a1c0f5 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -572,10 +572,9 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) switch (status) { case 0: /* normal completion? */ - if (ep == dev->out_ep) { + if (ep == dev->out_ep) check_read_data (dev, ep, req); - memset (req->buf, 0x55, req->length); - } else + else reinit_write_data (dev, ep, req); break; @@ -627,8 +626,6 @@ source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) if (strcmp (ep->name, EP_IN_NAME) == 0) reinit_write_data (ep->driver_data, ep, req); - else - memset (req->buf, 0x55, req->length); status = usb_ep_queue (ep, req, gfp_flags); if (status) { @@ -1122,7 +1119,7 @@ zero_autoresume (unsigned long _dev) /*-------------------------------------------------------------------------*/ -static void __exit +static void zero_unbind (struct usb_gadget *gadget) { struct zero_dev *dev = get_gadget_data (gadget); @@ -1139,7 +1136,7 @@ zero_unbind (struct usb_gadget *gadget) set_gadget_data (gadget, NULL); } -static int __init +static int zero_bind (struct usb_gadget *gadget) { struct zero_dev *dev; @@ -1191,9 +1188,10 @@ autoconf_fail: /* ok, we made sense of the hardware ... */ - dev = kzalloc(sizeof(*dev), SLAB_KERNEL); + dev = kmalloc (sizeof *dev, SLAB_KERNEL); if (!dev) return -ENOMEM; + memset (dev, 0, sizeof *dev); spin_lock_init (&dev->lock); dev->gadget = gadget; set_gadget_data (gadget, dev); @@ -1226,6 +1224,12 @@ autoconf_fail: loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } + if (gadget->is_otg) { + otg_descriptor.bmAttributes |= USB_OTG_HNP, + source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } + usb_gadget_set_selfpowered (gadget); init_timer (&dev->resume); @@ -1290,7 +1294,7 @@ static struct usb_gadget_driver zero_driver = { #endif .function = (char *) longname, .bind = zero_bind, - .unbind = __exit_p(zero_unbind), + .unbind = zero_unbind, .setup = zero_setup, .disconnect = zero_disconnect, diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index e27b79a3c..be3fd9bce 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -6,7 +6,7 @@ comment "USB Host Controller Drivers" config USB_EHCI_HCD tristate "EHCI HCD (USB 2.0) support" - depends on USB && USB_ARCH_HAS_EHCI + depends on USB && PCI ---help--- The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c deleted file mode 100644 index 63eadeec1..000000000 --- a/drivers/usb/host/ehci-au1xxx.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * EHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 2000-2004 David Brownell - * - * Bus Glue for AMD Alchemy Au1xxx - * - * Based on "ohci-au1xxx.c" by Matt Porter - * - * Modified for AMD Alchemy Au1200 EHC - * by K.Boge - * - * This file is licenced under the GPL. - */ - -#include -#include - -#ifndef CONFIG_SOC_AU1200 -#error "this Alchemy chip doesn't have EHCI" -#else /* Au1200 */ - -#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) -#define USB_MCFG_PFEN (1<<31) -#define USB_MCFG_RDCOMB (1<<30) -#define USB_MCFG_SSDEN (1<<23) -#define USB_MCFG_PHYPLLEN (1<<19) -#define USB_MCFG_EHCCLKEN (1<<17) -#define USB_MCFG_UCAM (1<<7) -#define USB_MCFG_EBMEN (1<<3) -#define USB_MCFG_EMEMEN (1<<2) - -#define USBH_ENABLE_CE (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN) - -#ifdef CONFIG_DMA_COHERENT -#define USBH_ENABLE_INIT (USBH_ENABLE_CE \ - | USB_MCFG_PFEN | USB_MCFG_RDCOMB \ - | USB_MCFG_SSDEN | USB_MCFG_UCAM \ - | USB_MCFG_EBMEN | USB_MCFG_EMEMEN) -#else -#define USBH_ENABLE_INIT (USBH_ENABLE_CE \ - | USB_MCFG_PFEN | USB_MCFG_RDCOMB \ - | USB_MCFG_SSDEN \ - | USB_MCFG_EBMEN | USB_MCFG_EMEMEN) -#endif -#define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN) - -#endif /* Au1200 */ - -extern int usb_disabled(void); - -/*-------------------------------------------------------------------------*/ - -static void au1xxx_start_ehc(struct platform_device *dev) -{ - pr_debug(__FILE__ ": starting Au1xxx EHCI USB Controller\n"); - - /* write HW defaults again in case Yamon cleared them */ - if (au_readl(USB_HOST_CONFIG) == 0) { - au_writel(0x00d02000, USB_HOST_CONFIG); - au_readl(USB_HOST_CONFIG); - udelay(1000); - } - /* enable host controller */ - au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG); - au_readl(USB_HOST_CONFIG); - udelay(1000); - au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG), - USB_HOST_CONFIG); - au_readl(USB_HOST_CONFIG); - udelay(1000); - - pr_debug(__FILE__ ": Clock to USB host has been enabled\n"); -} - -static void au1xxx_stop_ehc(struct platform_device *dev) -{ - pr_debug(__FILE__ ": stopping Au1xxx EHCI USB Controller\n"); - - /* Disable mem */ - au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG); - udelay(1000); - /* Disable clock */ - au_writel(~USB_MCFG_EHCCLKEN & au_readl(USB_HOST_CONFIG), - USB_HOST_CONFIG); - au_readl(USB_HOST_CONFIG); -} - -/*-------------------------------------------------------------------------*/ - -/* configure so an HC device and id are always provided */ -/* always called with process context; sleeping is OK */ - -/** - * usb_ehci_au1xxx_probe - initialize Au1xxx-based HCDs - * Context: !in_interrupt() - * - * Allocates basic resources for this USB host controller, and - * then invokes the start() method for the HCD associated with it - * through the hotplug entry's driver_data. - * - */ -int usb_ehci_au1xxx_probe(const struct hc_driver *driver, - struct usb_hcd **hcd_out, struct platform_device *dev) -{ - int retval; - struct usb_hcd *hcd; - struct ehci_hcd *ehci; - -#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT) - - /* Au1200 AB USB does not support coherent memory */ - if (!(read_c0_prid() & 0xff)) { - pr_info("%s: this is chip revision AB!\n", dev->dev.name); - pr_info("%s: update your board or re-configure the kernel\n", - dev->dev.name); - return -ENODEV; - } -#endif - - au1xxx_start_ehc(dev); - - if (dev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ"); - retval = -ENOMEM; - } - hcd = usb_create_hcd(driver, &dev->dev, "Au1xxx"); - if (!hcd) - return -ENOMEM; - hcd->rsrc_start = dev->resource[0].start; - hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_debug("request_mem_region failed"); - retval = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - pr_debug("ioremap failed"); - retval = -ENOMEM; - goto err2; - } - - ehci = hcd_to_ehci(hcd); - ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); - /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = readl(&ehci->caps->hcs_params); - - /* ehci_hcd_init(hcd_to_ehci(hcd)); */ - - retval = - usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT | SA_SHIRQ); - if (retval == 0) - return retval; - - au1xxx_stop_ehc(dev); - iounmap(hcd->regs); -err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err1: - usb_put_hcd(hcd); - return retval; -} - -/* may be called without controller electrically present */ -/* may be called with controller, bus, and devices active */ - -/** - * usb_ehci_hcd_au1xxx_remove - shutdown processing for Au1xxx-based HCDs - * @dev: USB Host Controller being removed - * Context: !in_interrupt() - * - * Reverses the effect of usb_ehci_hcd_au1xxx_probe(), first invoking - * the HCD's stop() method. It is always called from a thread - * context, normally "rmmod", "apmd", or something similar. - * - */ -void usb_ehci_au1xxx_remove(struct usb_hcd *hcd, struct platform_device *dev) -{ - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - au1xxx_stop_ehc(dev); -} - -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ehci_au1xxx_hc_driver = { - .description = hcd_name, - .product_desc = "Au1xxx EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = ehci_init, - .start = ehci_run, - .stop = ehci_stop, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, -#ifdef CONFIG_PM - .hub_suspend = ehci_hub_suspend, - .hub_resume = ehci_hub_resume, -#endif -}; - -/*-------------------------------------------------------------------------*/ - -static int ehci_hcd_au1xxx_drv_probe(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct usb_hcd *hcd = NULL; - int ret; - - pr_debug("In ehci_hcd_au1xxx_drv_probe\n"); - - if (usb_disabled()) - return -ENODEV; - - ret = usb_ehci_au1xxx_probe(&ehci_au1xxx_hc_driver, &hcd, pdev); - return ret; -} - -static int ehci_hcd_au1xxx_drv_remove(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct usb_hcd *hcd = dev_get_drvdata(dev); - - usb_ehci_au1xxx_remove(hcd, pdev); - return 0; -} - - /*TBD*/ -/*static int ehci_hcd_au1xxx_drv_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct usb_hcd *hcd = dev_get_drvdata(dev); - - return 0; -} -static int ehci_hcd_au1xxx_drv_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct usb_hcd *hcd = dev_get_drvdata(dev); - - return 0; -} -*/ -static struct device_driver ehci_hcd_au1xxx_driver = { - .name = "au1xxx-ehci", - .bus = &platform_bus_type, - .probe = ehci_hcd_au1xxx_drv_probe, - .remove = ehci_hcd_au1xxx_drv_remove, - /*.suspend = ehci_hcd_au1xxx_drv_suspend, */ - /*.resume = ehci_hcd_au1xxx_drv_resume, */ -}; - -static int __init ehci_hcd_au1xxx_init(void) -{ - pr_debug(DRIVER_INFO " (Au1xxx)\n"); - - return driver_register(&ehci_hcd_au1xxx_driver); -} - -static void __exit ehci_hcd_au1xxx_cleanup(void) -{ - driver_unregister(&ehci_hcd_au1xxx_driver); -} - -module_init(ehci_hcd_au1xxx_init); -module_exit(ehci_hcd_au1xxx_cleanup); diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c deleted file mode 100644 index f985f121a..000000000 --- a/drivers/usb/host/ehci-fsl.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * (C) Copyright David Brownell 2000-2002 - * Copyright (c) 2005 MontaVista Software - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You 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. - * - * Ported to 834x by Randy Vinson using code provided - * by Hunter Wu. - */ - -#include -#include - -#include "ehci-fsl.h" - -/* FIXME: Power Managment is un-ported so temporarily disable it */ -#undef CONFIG_PM - -/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */ - -/* configure so an HC device and id are always provided */ -/* always called with process context; sleeping is OK */ - -/** - * usb_hcd_fsl_probe - initialize FSL-based HCDs - * @drvier: Driver to be used for this HCD - * @pdev: USB Host Controller being probed - * Context: !in_interrupt() - * - * Allocates basic resources for this USB host controller. - * - */ -int usb_hcd_fsl_probe(const struct hc_driver *driver, - struct platform_device *pdev) -{ - struct fsl_usb2_platform_data *pdata; - struct usb_hcd *hcd; - struct resource *res; - int irq; - int retval; - unsigned int temp; - - pr_debug("initializing FSL-SOC USB Controller\n"); - - /* Need platform data for setup */ - pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, - "No platform data for %s.\n", pdev->dev.bus_id); - return -ENODEV; - } - - /* - * This is a host mode driver, verify that we're supposed to be - * in host mode. - */ - if (!((pdata->operating_mode == FSL_USB2_DR_HOST) || - (pdata->operating_mode == FSL_USB2_MPH_HOST))) { - dev_err(&pdev->dev, - "Non Host Mode configured for %s. Wrong driver linked.\n", - pdev->dev.bus_id); - return -ENODEV; - } - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no IRQ. Check %s setup!\n", - pdev->dev.bus_id); - return -ENODEV; - } - irq = res->start; - - hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); - if (!hcd) { - retval = -ENOMEM; - goto err1; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - pdev->dev.bus_id); - retval = -ENODEV; - goto err2; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = res->end - res->start + 1; - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, - driver->description)) { - dev_dbg(&pdev->dev, "controller already in use\n"); - retval = -EBUSY; - goto err2; - } - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - - if (hcd->regs == NULL) { - dev_dbg(&pdev->dev, "error mapping memory\n"); - retval = -EFAULT; - goto err3; - } - - /* Enable USB controller */ - temp = in_be32(hcd->regs + 0x500); - out_be32(hcd->regs + 0x500, temp | 0x4); - - /* Set to Host mode */ - temp = in_le32(hcd->regs + 0x1a8); - out_le32(hcd->regs + 0x1a8, temp | 0x3); - - retval = usb_add_hcd(hcd, irq, SA_SHIRQ); - if (retval != 0) - goto err4; - return retval; - - err4: - iounmap(hcd->regs); - err3: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - err2: - usb_put_hcd(hcd); - err1: - dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval); - return retval; -} - -/* may be called without controller electrically present */ -/* may be called with controller, bus, and devices active */ - -/** - * usb_hcd_fsl_remove - shutdown processing for FSL-based HCDs - * @dev: USB Host Controller being removed - * Context: !in_interrupt() - * - * Reverses the effect of usb_hcd_fsl_probe(). - * - */ -void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev) -{ - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); -} - -static void mpc83xx_setup_phy(struct ehci_hcd *ehci, - enum fsl_usb2_phy_modes phy_mode, - unsigned int port_offset) -{ - u32 portsc = 0; - switch (phy_mode) { - case FSL_USB2_PHY_ULPI: - portsc |= PORT_PTS_ULPI; - break; - case FSL_USB2_PHY_SERIAL: - portsc |= PORT_PTS_SERIAL; - break; - case FSL_USB2_PHY_UTMI_WIDE: - portsc |= PORT_PTS_PTW; - /* fall through */ - case FSL_USB2_PHY_UTMI: - portsc |= PORT_PTS_UTMI; - break; - case FSL_USB2_PHY_NONE: - break; - } - writel(portsc, &ehci->regs->port_status[port_offset]); -} - -static void mpc83xx_usb_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct fsl_usb2_platform_data *pdata; - void __iomem *non_ehci = hcd->regs; - - pdata = - (struct fsl_usb2_platform_data *)hcd->self.controller-> - platform_data; - /* Enable PHY interface in the control reg. */ - out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004); - out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b); - - if (pdata->operating_mode == FSL_USB2_DR_HOST) - mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); - - if (pdata->operating_mode == FSL_USB2_MPH_HOST) { - unsigned int chip, rev, svr; - - svr = mfspr(SPRN_SVR); - chip = svr >> 16; - rev = (svr >> 4) & 0xf; - - /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */ - if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055)) - ehci->has_fsl_port_bug = 1; - - if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) - mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); - if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) - mpc83xx_setup_phy(ehci, pdata->phy_mode, 1); - } - - /* put controller in host mode. */ - writel(0x00000003, non_ehci + FSL_SOC_USB_USBMODE); - out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); - out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); - out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); -} - -/* called after powerup, by probe or system-pm "wakeup" */ -static int ehci_fsl_reinit(struct ehci_hcd *ehci) -{ - mpc83xx_usb_setup(ehci_to_hcd(ehci)); - ehci_port_power(ehci, 0); - - return 0; -} - -/* called during probe() after chip reset completes */ -static int ehci_fsl_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - /* EHCI registers start at offset 0x100 */ - ehci->caps = hcd->regs + 0x100; - ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(readl(&ehci->caps->hc_capbase)); - dbg_hcs_params(ehci, "reset"); - dbg_hcc_params(ehci, "reset"); - - /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = readl(&ehci->caps->hcs_params); - - retval = ehci_halt(ehci); - if (retval) - return retval; - - /* data structure init */ - retval = ehci_init(hcd); - if (retval) - return retval; - - ehci->is_tdi_rh_tt = 1; - - ehci->sbrn = 0x20; - - ehci_reset(ehci); - - retval = ehci_fsl_reinit(ehci); - return retval; -} - -static const struct hc_driver ehci_fsl_hc_driver = { - .description = hcd_name, - .product_desc = "Freescale On-Chip EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = ehci_fsl_setup, - .start = ehci_run, -#ifdef CONFIG_PM - .suspend = ehci_bus_suspend, - .resume = ehci_bus_resume, -#endif - .stop = ehci_stop, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -}; - -static int ehci_fsl_drv_probe(struct platform_device *pdev) -{ - if (usb_disabled()) - return -ENODEV; - - return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev); -} - -static int ehci_fsl_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_hcd_fsl_remove(hcd, pdev); - - return 0; -} - -static struct platform_driver ehci_fsl_dr_driver = { - .probe = ehci_fsl_drv_probe, - .remove = ehci_fsl_drv_remove, - .driver = { - .name = "fsl-usb2-dr", - }, -}; - -static struct platform_driver ehci_fsl_mph_driver = { - .probe = ehci_fsl_drv_probe, - .remove = ehci_fsl_drv_remove, - .driver = { - .name = "fsl-usb2-mph", - }, -}; - -static int __init ehci_fsl_init(void) -{ - int retval; - - pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", - hcd_name, - sizeof(struct ehci_qh), sizeof(struct ehci_qtd), - sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); - - retval = platform_driver_register(&ehci_fsl_dr_driver); - if (retval) - return retval; - - return platform_driver_register(&ehci_fsl_mph_driver); -} - -static void __exit ehci_fsl_cleanup(void) -{ - platform_driver_unregister(&ehci_fsl_mph_driver); - platform_driver_unregister(&ehci_fsl_dr_driver); -} - -module_init(ehci_fsl_init); -module_exit(ehci_fsl_cleanup); diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h deleted file mode 100644 index caac0d196..000000000 --- a/drivers/usb/host/ehci-fsl.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2005 freescale semiconductor - * Copyright (c) 2005 MontaVista Software - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You 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 _EHCI_FSL_H -#define _EHCI_FSL_H - -/* offsets for the non-ehci registers in the FSL SOC USB controller */ -#define FSL_SOC_USB_ULPIVP 0x170 -#define FSL_SOC_USB_PORTSC1 0x184 -#define PORT_PTS_MSK (3<<30) -#define PORT_PTS_UTMI (0<<30) -#define PORT_PTS_ULPI (2<<30) -#define PORT_PTS_SERIAL (3<<30) -#define PORT_PTS_PTW (1<<28) -#define FSL_SOC_USB_PORTSC2 0x188 -#define FSL_SOC_USB_USBMODE 0x1a8 -#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */ -#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */ -#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */ -#define FSL_SOC_USB_SICTRL 0x40c /* NOTE: big-endian */ -#define FSL_SOC_USB_PRICTRL 0x410 /* NOTE: big-endian */ -#define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */ -#endif /* _EHCI_FSL_H */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 79f2d8b9b..9dd3d14c6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -889,19 +889,8 @@ MODULE_LICENSE ("GPL"); #ifdef CONFIG_PCI #include "ehci-pci.c" -#define EHCI_BUS_GLUED #endif -#ifdef CONFIG_PPC_83xx -#include "ehci-fsl.c" -#define EHCI_BUS_GLUED -#endif - -#ifdef CONFIG_SOC_AU1X00 -#include "ehci-au1xxx.c" -#define EHCI_BUS_GLUED -#endif - -#ifndef EHCI_BUS_GLUED +#if !defined(CONFIG_PCI) #error "missing bus glue for ehci-hcd" #endif diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index d03e3cad5..69b0b9be7 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -359,8 +359,6 @@ static int ehci_hub_control ( case USB_PORT_FEAT_SUSPEND: if (temp & PORT_RESET) goto error; - if (ehci->no_selective_suspend) - break; if (temp & PORT_SUSPEND) { if ((temp & PORT_PE) == 0) goto error; @@ -516,8 +514,6 @@ static int ehci_hub_control ( temp &= ~PORT_RWC_BITS; switch (wValue) { case USB_PORT_FEAT_SUSPEND: - if (ehci->no_selective_suspend) - break; if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) goto error; diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 766061e02..91c2ab43c 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -75,6 +75,7 @@ static void qh_destroy (struct kref *kref) } if (qh->dummy) ehci_qtd_free (ehci, qh->dummy); + usb_put_dev (qh->dev); dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); } @@ -220,9 +221,13 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) ehci->periodic [i] = EHCI_LIST_END; /* software shadow of hardware table */ - ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags); - if (ehci->pshadow != NULL) - return 0; + ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags); + if (ehci->pshadow == NULL) { + goto fail; + } + memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *)); + + return 0; fail: ehci_dbg (ehci, "couldn't init memory\n"); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index a1bd2bea6..3a6687df5 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -106,11 +106,11 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_NVIDIA: - switch (pdev->device) { /* NVidia reports that certain chips don't handle * QH, ITD, or SITD addresses above 2GB. (But TD, * data buffer, and periodic schedule are normal.) */ + switch (pdev->device) { case 0x003c: /* MCP04 */ case 0x005b: /* CK804 */ case 0x00d8: /* CK8 */ @@ -120,14 +120,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ehci_warn(ehci, "can't enable NVidia " "workaround for >2GB RAM\n"); break; - /* Some NForce2 chips have problems with selective suspend; - * fixed in newer silicon. - */ - case 0x0068: - pci_read_config_dword(pdev, PCI_REVISION_ID, &temp); - if ((temp & 0xff) < 0xa4) - ehci->no_selective_suspend = 1; - break; } break; } @@ -171,21 +163,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) device_init_wakeup(&pdev->dev, 1); } -#ifdef CONFIG_USB_SUSPEND - /* REVISIT: the controller works fine for wakeup iff the root hub - * itself is "globally" suspended, but usbcore currently doesn't - * understand such things. - * - * System suspend currently expects to be able to suspend the entire - * device tree, device-at-a-time. If we failed selective suspend - * reports, system suspend would fail; so the root hub code must claim - * success. That's lying to usbcore, and it matters for for runtime - * PM scenarios with selective suspend and remote wakeup... - */ - if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev)) - ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); -#endif - retval = ehci_pci_reinit(ehci, pdev); done: return retval; @@ -350,7 +327,7 @@ static const struct hc_driver ehci_pci_hc_driver = { /* PCI driver selection metadata; PCI hotplugging uses this */ static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ - PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), + PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), .driver_data = (unsigned long) &ehci_pci_hc_driver, }, { /* end: all zeroes */ } diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index e469221e7..9b13bf2fa 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -702,7 +702,7 @@ qh_make ( } /* support for tt scheduling, and access to toggles */ - qh->dev = urb->dev; + qh->dev = usb_get_dev (urb->dev); /* using TT? */ switch (urb->dev->speed) { @@ -721,14 +721,7 @@ qh_make ( info1 |= maxp << 16; info2 |= (EHCI_TUNE_MULT_TT << 30); - - /* Some Freescale processors have an erratum in which the - * port number in the queue head was 0..N-1 instead of 1..N. - */ - if (ehci_has_fsl_portno_bug(ehci)) - info2 |= (urb->dev->ttport-1) << 23; - else - info2 |= urb->dev->ttport << 23; + info2 |= urb->dev->ttport << 23; /* set the address of the TT; for TDI's integrated * root hub tt, leave it zeroed. @@ -1022,14 +1015,12 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) /* stop async schedule right now? */ if (unlikely (qh == ehci->async)) { /* can't get here without STS_ASS set */ - if (ehci_to_hcd(ehci)->state != HC_STATE_HALT - && !ehci->reclaim) { - /* ... and CMD_IAAD clear */ + if (ehci_to_hcd(ehci)->state != HC_STATE_HALT) { writel (cmd & ~CMD_ASE, &ehci->regs->command); wmb (); // handshake later, if we need to - timer_action_done (ehci, TIMER_ASYNC_OFF); } + timer_action_done (ehci, TIMER_ASYNC_OFF); return; } diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 5871944e6..88419c682 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -864,8 +864,9 @@ iso_sched_alloc (unsigned packets, gfp_t mem_flags) int size = sizeof *iso_sched; size += packets * sizeof (struct ehci_iso_packet); - iso_sched = kzalloc(size, mem_flags); + iso_sched = kmalloc (size, mem_flags); if (likely (iso_sched != NULL)) { + memset(iso_sched, 0, size); INIT_LIST_HEAD (&iso_sched->td_list); } return iso_sched; @@ -1398,7 +1399,7 @@ itd_complete ( */ /* give urb back to the driver ... can be out-of-order */ - dev = urb->dev; + dev = usb_get_dev (urb->dev); ehci_urb_done (ehci, urb, regs); urb = NULL; @@ -1417,6 +1418,7 @@ itd_complete ( (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } iso_stream_put (ehci, stream); + usb_put_dev (dev); return 1; } @@ -1763,7 +1765,7 @@ sitd_complete ( */ /* give urb back to the driver */ - dev = urb->dev; + dev = usb_get_dev (urb->dev); ehci_urb_done (ehci, urb, regs); urb = NULL; @@ -1782,6 +1784,7 @@ sitd_complete ( (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } iso_stream_put (ehci, stream); + usb_put_dev (dev); return 1; } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 679c1cdcc..18e257c2b 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -88,12 +88,7 @@ struct ehci_hcd { /* one per controller */ unsigned long next_statechange; u32 command; - /* SILICON QUIRKS */ unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ - unsigned no_selective_suspend:1; - unsigned has_fsl_port_bug:1; /* FreeScale */ - - u8 sbrn; /* packed release number */ /* irq statistics */ #ifdef EHCI_STATS @@ -102,6 +97,7 @@ struct ehci_hcd { /* one per controller */ #else # define COUNT(x) do {} while (0) #endif + u8 sbrn; /* packed release number */ }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ @@ -640,18 +636,6 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) #define ehci_port_speed(ehci, portsc) (1<has_fsl_port_bug) -#else -#define ehci_has_fsl_portno_bug(e) (0) -#endif - - /*-------------------------------------------------------------------------*/ #ifndef DEBUG diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c index 2fe7fd194..641268d7e 100644 --- a/drivers/usb/host/hc_crisv10.c +++ b/drivers/usb/host/hc_crisv10.c @@ -2137,9 +2137,10 @@ static int etrax_usb_submit_bulk_urb(struct urb *urb) urb->status = -EINPROGRESS; /* Setup the hcpriv data. */ - urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); assert(urb_priv != NULL); /* This sets rx_offset to 0. */ + memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); urb_priv->urb_state = NOT_STARTED; urb->hcpriv = urb_priv; @@ -2474,9 +2475,10 @@ static int etrax_usb_submit_ctrl_urb(struct urb *urb) urb->status = -EINPROGRESS; /* Setup the hcpriv data. */ - urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); assert(urb_priv != NULL); /* This sets rx_offset to 0. */ + memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); urb_priv->urb_state = NOT_STARTED; urb->hcpriv = urb_priv; @@ -2765,8 +2767,9 @@ static void etrax_usb_add_to_intr_sb_list(struct urb *urb, int epid) maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); interval = urb->interval; - urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); assert(urb_priv != NULL); + memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); urb->hcpriv = urb_priv; first_ep = &TxIntrEPList[0]; @@ -2994,8 +2997,9 @@ static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid) prev_sb_desc = next_sb_desc = temp_sb_desc = NULL; - urb_priv = kzalloc(sizeof(etrax_urb_priv_t), GFP_ATOMIC); + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_ATOMIC); assert(urb_priv != NULL); + memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); urb->hcpriv = urb_priv; urb_priv->epid = epid; diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index e99210b79..972ce0488 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -724,7 +724,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, ep = hep->hcpriv; else { INIT_LIST_HEAD(&ep->schedule); - ep->udev = udev; + ep->udev = usb_get_dev(udev); ep->epnum = epnum; ep->maxpacket = usb_maxpacket(udev, urb->pipe, is_out); usb_settoggle(udev, epnum, is_out, 0); @@ -891,6 +891,7 @@ static void isp116x_endpoint_disable(struct usb_hcd *hcd, if (!list_empty(&hep->urb_list)) WARN("ep %p not empty?\n", ep); + usb_put_dev(ep->udev); kfree(ep); hep->hcpriv = NULL; } @@ -1552,7 +1553,7 @@ static struct hc_driver isp116x_hc_driver = { /*----------------------------------------------------------------*/ -static int isp116x_remove(struct platform_device *pdev) +static int __init_or_module isp116x_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct isp116x *isp116x; diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c deleted file mode 100644 index 6b7350b52..000000000 --- a/drivers/usb/host/ohci-at91.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * Copyright (C) 2004 SAN People (Pty) Ltd. - * Copyright (C) 2005 Thibaut VARENE - * - * AT91RM9200 Bus Glue - * - * Based on fragments of 2.4 driver by Rick Bronson. - * Based on ohci-omap.c - * - * This file is licenced under the GPL. - */ - -#include -#include - -#include -#include -#include - -#ifndef CONFIG_ARCH_AT91RM9200 -#error "CONFIG_ARCH_AT91RM9200 must be defined." -#endif - -/* interface and function clocks */ -static struct clk *iclk, *fclk; - -extern int usb_disabled(void); - -/*-------------------------------------------------------------------------*/ - -static void at91_start_hc(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct ohci_regs __iomem *regs = hcd->regs; - - dev_dbg(&pdev->dev, "starting AT91RM9200 OHCI USB Controller\n"); - - /* - * Start the USB clocks. - */ - clk_enable(iclk); - clk_enable(fclk); - - /* - * The USB host controller must remain in reset. - */ - writel(0, ®s->control); -} - -static void at91_stop_hc(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct ohci_regs __iomem *regs = hcd->regs; - - dev_dbg(&pdev->dev, "stopping AT91RM9200 OHCI USB Controller\n"); - - /* - * Put the USB host controller into reset. - */ - writel(0, ®s->control); - - /* - * Stop the USB clocks. - */ - clk_disable(fclk); - clk_disable(iclk); -} - - -/*-------------------------------------------------------------------------*/ - -static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); - -/* configure so an HC device and id are always provided */ -/* always called with process context; sleeping is OK */ - - -/** - * usb_hcd_at91_probe - initialize AT91RM9200-based HCDs - * Context: !in_interrupt() - * - * Allocates basic resources for this USB host controller, and - * then invokes the start() method for the HCD associated with it - * through the hotplug entry's driver_data. - */ -int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev) -{ - int retval; - struct usb_hcd *hcd = NULL; - - if (pdev->num_resources != 2) { - pr_debug("hcd probe: invalid num_resources"); - return -ENODEV; - } - - if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) { - pr_debug("hcd probe: invalid resource type\n"); - return -ENODEV; - } - - hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200"); - if (!hcd) - return -ENOMEM; - hcd->rsrc_start = pdev->resource[0].start; - hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_debug("request_mem_region failed\n"); - retval = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - pr_debug("ioremap failed\n"); - retval = -EIO; - goto err2; - } - - iclk = clk_get(&pdev->dev, "ohci_clk"); - fclk = clk_get(&pdev->dev, "uhpck"); - - at91_start_hc(pdev); - ohci_hcd_init(hcd_to_ohci(hcd)); - - retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT); - if (retval == 0) - return retval; - - /* Error handling */ - at91_stop_hc(pdev); - - clk_put(fclk); - clk_put(iclk); - - iounmap(hcd->regs); - - err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - - err1: - usb_put_hcd(hcd); - return retval; -} - - -/* may be called with controller, bus, and devices active */ - -/** - * usb_hcd_at91_remove - shutdown processing for AT91RM9200-based HCDs - * @dev: USB Host Controller being removed - * Context: !in_interrupt() - * - * Reverses the effect of usb_hcd_at91_probe(), first invoking - * the HCD's stop() method. It is always called from a thread - * context, normally "rmmod", "apmd", or something similar. - * - */ -static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pdev) -{ - usb_remove_hcd(hcd); - at91_stop_hc(pdev); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - - clk_put(fclk); - clk_put(iclk); - fclk = iclk = NULL; - - dev_set_drvdata(&pdev->dev, NULL); - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int __devinit -ohci_at91_start (struct usb_hcd *hcd) -{ -// struct at91_ohci_data *board = hcd->self.controller->platform_data; - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ret; - - if ((ret = ohci_init(ohci)) < 0) - return ret; - - if ((ret = ohci_run(ohci)) < 0) { - err("can't start %s", hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } -// hcd->self.root_hub->maxchild = board->ports; - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ohci_at91_hc_driver = { - .description = hcd_name, - .product_desc = "AT91RM9200 OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_at91_start, - .stop = ohci_stop, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, - -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -/*-------------------------------------------------------------------------*/ - -static int ohci_hcd_at91_drv_probe(struct platform_device *dev) -{ - return usb_hcd_at91_probe(&ohci_at91_hc_driver, dev); -} - -static int ohci_hcd_at91_drv_remove(struct platform_device *dev) -{ - return usb_hcd_at91_remove(platform_get_drvdata(dev), dev); -} - -#ifdef CONFIG_PM - -/* REVISIT suspend/resume look "too" simple here */ - -static int -ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg) -{ - clk_disable(fclk); - clk_disable(iclk); - - return 0; -} - -static int ohci_hcd_at91_drv_resume(struct platform_device *dev) -{ - clk_enable(iclk); - clk_enable(fclk); - - return 0; -} -#else -#define ohci_hcd_at91_drv_suspend NULL -#define ohci_hcd_at91_drv_resume NULL -#endif - -MODULE_ALIAS("at91rm9200-ohci"); - -static struct platform_driver ohci_hcd_at91_driver = { - .probe = ohci_hcd_at91_drv_probe, - .remove = ohci_hcd_at91_drv_remove, - .suspend = ohci_hcd_at91_drv_suspend, - .resume = ohci_hcd_at91_drv_resume, - .driver = { - .name = "at91rm9200-ohci", - .owner = THIS_MODULE, - }, -}; - -static int __init ohci_hcd_at91_init (void) -{ - if (usb_disabled()) - return -ENODEV; - - return platform_driver_register(&ohci_hcd_at91_driver); -} - -static void __exit ohci_hcd_at91_cleanup (void) -{ - platform_driver_unregister(&ohci_hcd_at91_driver); -} - -module_init (ohci_hcd_at91_init); -module_exit (ohci_hcd_at91_cleanup); diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index a1c8b3b2f..db280ca7b 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -23,8 +23,6 @@ #include -#ifndef CONFIG_SOC_AU1200 - #define USBH_ENABLE_BE (1<<0) #define USBH_ENABLE_C (1<<1) #define USBH_ENABLE_E (1<<2) @@ -39,68 +37,21 @@ #error not byte order defined #endif -#else /* Au1200 */ - -#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) -#define USB_MCFG_PFEN (1<<31) -#define USB_MCFG_RDCOMB (1<<30) -#define USB_MCFG_SSDEN (1<<23) -#define USB_MCFG_OHCCLKEN (1<<16) -#define USB_MCFG_UCAM (1<<7) -#define USB_MCFG_OBMEN (1<<1) -#define USB_MCFG_OMEMEN (1<<0) - -#define USBH_ENABLE_CE USB_MCFG_OHCCLKEN -#ifdef CONFIG_DMA_COHERENT -#define USBH_ENABLE_INIT (USB_MCFG_OHCCLKEN \ - | USB_MCFG_PFEN | USB_MCFG_RDCOMB \ - | USB_MCFG_SSDEN | USB_MCFG_UCAM \ - | USB_MCFG_OBMEN | USB_MCFG_OMEMEN) -#else -#define USBH_ENABLE_INIT (USB_MCFG_OHCCLKEN \ - | USB_MCFG_PFEN | USB_MCFG_RDCOMB \ - | USB_MCFG_SSDEN \ - | USB_MCFG_OBMEN | USB_MCFG_OMEMEN) -#endif -#define USBH_DISABLE (USB_MCFG_OBMEN | USB_MCFG_OMEMEN) - -#endif /* Au1200 */ - extern int usb_disabled(void); /*-------------------------------------------------------------------------*/ -static void au1xxx_start_ohc(struct platform_device *dev) +static void au1xxx_start_hc(struct platform_device *dev) { printk(KERN_DEBUG __FILE__ ": starting Au1xxx OHCI USB Controller\n"); /* enable host controller */ - -#ifndef CONFIG_SOC_AU1200 - au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG); udelay(1000); au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG); udelay(1000); -#else /* Au1200 */ - - /* write HW defaults again in case Yamon cleared them */ - if (au_readl(USB_HOST_CONFIG) == 0) { - au_writel(0x00d02000, USB_HOST_CONFIG); - au_readl(USB_HOST_CONFIG); - udelay(1000); - } - au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG); - au_readl(USB_HOST_CONFIG); - udelay(1000); - au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG); - au_readl(USB_HOST_CONFIG); - udelay(1000); - -#endif /* Au1200 */ - /* wait for reset complete (read register twice; see au1500 errata) */ while (au_readl(USB_HOST_CONFIG), !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) @@ -110,25 +61,13 @@ static void au1xxx_start_ohc(struct platform_device *dev) ": Clock to USB host has been enabled \n"); } -static void au1xxx_stop_ohc(struct platform_device *dev) +static void au1xxx_stop_hc(struct platform_device *dev) { printk(KERN_DEBUG __FILE__ ": stopping Au1xxx OHCI USB Controller\n"); -#ifndef CONFIG_SOC_AU1200 - /* Disable clock */ au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); - -#else /* Au1200 */ - - /* Disable mem */ - au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG); - udelay(1000); - /* Disable clock */ - au_writel(~USBH_ENABLE_CE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG); - au_readl(USB_HOST_CONFIG); -#endif /* Au1200 */ } @@ -139,7 +78,7 @@ static void au1xxx_stop_ohc(struct platform_device *dev) /** - * usb_ohci_au1xxx_probe - initialize Au1xxx-based HCDs + * usb_hcd_au1xxx_probe - initialize Au1xxx-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and @@ -147,25 +86,14 @@ static void au1xxx_stop_ohc(struct platform_device *dev) * through the hotplug entry's driver_data. * */ -static int usb_ohci_au1xxx_probe(const struct hc_driver *driver, +int usb_hcd_au1xxx_probe (const struct hc_driver *driver, struct platform_device *dev) { int retval; struct usb_hcd *hcd; -#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT) - /* Au1200 AB USB does not support coherent memory */ - if (!(read_c0_prid() & 0xff)) { - pr_info("%s: this is chip revision AB !!\n", - dev->dev.name); - pr_info("%s: update your board or re-configure the kernel\n", - dev->dev.name); - return -ENODEV; - } -#endif - - if (dev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ\n"); + if(dev->resource[1].flags != IORESOURCE_IRQ) { + pr_debug ("resource[1] is not IORESOURCE_IRQ"); return -ENOMEM; } @@ -176,26 +104,26 @@ static int usb_ohci_au1xxx_probe(const struct hc_driver *driver, hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_debug("request_mem_region failed\n"); + pr_debug("request_mem_region failed"); retval = -EBUSY; goto err1; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { - pr_debug("ioremap failed\n"); + pr_debug("ioremap failed"); retval = -ENOMEM; goto err2; } - au1xxx_start_ohc(dev); + au1xxx_start_hc(dev); ohci_hcd_init(hcd_to_ohci(hcd)); - retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT | SA_SHIRQ); + retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); if (retval == 0) return retval; - au1xxx_stop_ohc(dev); + au1xxx_stop_hc(dev); iounmap(hcd->regs); err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); @@ -218,10 +146,10 @@ static int usb_ohci_au1xxx_probe(const struct hc_driver *driver, * context, normally "rmmod", "apmd", or something similar. * */ -static void usb_ohci_au1xxx_remove(struct usb_hcd *hcd, struct platform_device *dev) +void usb_hcd_au1xxx_remove (struct usb_hcd *hcd, struct platform_device *dev) { usb_remove_hcd(hcd); - au1xxx_stop_ohc(dev); + au1xxx_stop_hc(dev); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); @@ -307,7 +235,7 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; - ret = usb_ohci_au1xxx_probe(&ohci_au1xxx_hc_driver, pdev); + ret = usb_hcd_au1xxx_probe(&ohci_au1xxx_hc_driver, pdev); return ret; } @@ -315,7 +243,7 @@ static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); - usb_ohci_au1xxx_remove(hcd, pdev); + usb_hcd_au1xxx_remove(hcd, pdev); return 0; } /*TBD*/ diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 73f5a379d..a4b12404a 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -443,16 +443,11 @@ ohci_reboot (struct notifier_block *block, unsigned long code, void *null) static int ohci_init (struct ohci_hcd *ohci) { int ret; - struct usb_hcd *hcd = ohci_to_hcd(ohci); disable (ohci); - ohci->regs = hcd->regs; + ohci->regs = ohci_to_hcd(ohci)->regs; ohci->next_statechange = jiffies; - /* REVISIT this BIOS handshake is now moved into PCI "quirks", and - * was never needed for most non-PCI systems ... remove the code? - */ - #ifndef IR_DISABLE /* SMM owns the HC? not for long! */ if (!no_handshake && ohci_readl (ohci, @@ -483,10 +478,8 @@ static int ohci_init (struct ohci_hcd *ohci) /* Disable HC interrupts */ ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); - - /* flush the writes, and save key bits like RWC */ - if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC) - ohci->hc_control |= OHCI_CTRL_RWC; + // flush the writes + (void) ohci_readl (ohci, &ohci->regs->control); /* Read the number of ports unless overridden */ if (ohci->num_ports == 0) @@ -495,19 +488,16 @@ static int ohci_init (struct ohci_hcd *ohci) if (ohci->hcca) return 0; - ohci->hcca = dma_alloc_coherent (hcd->self.controller, + ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller, sizeof *ohci->hcca, &ohci->hcca_dma, 0); if (!ohci->hcca) return -ENOMEM; if ((ret = ohci_mem_init (ohci)) < 0) - ohci_stop (hcd); - else { - register_reboot_notifier (&ohci->reboot_notifier); - create_debug_files (ohci); - } + ohci_stop (ohci_to_hcd(ohci)); return ret; + } /*-------------------------------------------------------------------------*/ @@ -520,7 +510,6 @@ static int ohci_run (struct ohci_hcd *ohci) { u32 mask, temp; int first = ohci->fminterval == 0; - struct usb_hcd *hcd = ohci_to_hcd(ohci); disable (ohci); @@ -536,17 +525,18 @@ static int ohci_run (struct ohci_hcd *ohci) /* also: power/overcurrent flags in roothub.a */ } - /* Reset USB nearly "by the book". RemoteWakeupConnected was - * saved if boot firmware (BIOS/SMM/...) told us it's connected, - * or if bus glue did the same (e.g. for PCI add-in cards with - * PCI PM support). + /* Reset USB nearly "by the book". RemoteWakeupConnected + * saved if boot firmware (BIOS/SMM/...) told us it's connected + * (for OHCI integrated on mainboard, it normally is) */ + ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n", hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), - ohci_readl (ohci, &ohci->regs->control)); - if ((ohci->hc_control & OHCI_CTRL_RWC) != 0 - && !device_may_wakeup(hcd->self.controller)) - device_init_wakeup(hcd->self.controller, 1); + ohci->hc_control); + + if (ohci->hc_control & OHCI_CTRL_RWC + && !(ohci->flags & OHCI_QUIRK_AMD756)) + ohci_to_hcd(ohci)->can_wakeup = 1; switch (ohci->hc_control & OHCI_CTRL_HCFS) { case OHCI_USB_OPER: @@ -642,7 +632,7 @@ retry: ohci->hc_control &= OHCI_CTRL_RWC; ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); - hcd->state = HC_STATE_RUNNING; + ohci_to_hcd(ohci)->state = HC_STATE_RUNNING; /* wake on ConnectStatusChange, matching external hubs */ ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); @@ -677,10 +667,15 @@ retry: // POTPGT delay is bits 24-31, in 2 ms units. mdelay ((temp >> 23) & 0x1fe); - hcd->state = HC_STATE_RUNNING; + ohci_to_hcd(ohci)->state = HC_STATE_RUNNING; ohci_dump (ohci, 1); + if (ohci_to_hcd(ohci)->self.root_hub == NULL) { + register_reboot_notifier (&ohci->reboot_notifier); + create_debug_files (ohci); + } + return 0; } @@ -863,7 +858,7 @@ static int ohci_restart (struct ohci_hcd *ohci) i = ohci->num_ports; while (i--) ohci_writel (ohci, RH_PS_PSS, - &ohci->regs->roothub.portstatus [i]); + &ohci->regs->roothub.portstatus [temp]); ohci_dbg (ohci, "restart complete\n"); } return 0; @@ -910,10 +905,6 @@ MODULE_LICENSE ("GPL"); #include "ohci-ppc-soc.c" #endif -#ifdef CONFIG_ARCH_AT91RM9200 -#include "ohci-at91.c" -#endif - #if !(defined(CONFIG_PCI) \ || defined(CONFIG_SA1111) \ || defined(CONFIG_ARCH_S3C2410) \ @@ -922,7 +913,6 @@ MODULE_LICENSE ("GPL"); || defined (CONFIG_PXA27x) \ || defined (CONFIG_SOC_AU1X00) \ || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ - || defined (CONFIG_ARCH_AT91RM9200) \ ) #error "missing bus glue for ohci-hcd" #endif diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 0bb972b58..4b2226d77 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -107,7 +107,7 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) &ohci->regs->intrstatus); /* maybe resume can wake root hub */ - if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev)) + if (hcd->remote_wakeup) ohci->hc_control |= OHCI_CTRL_RWE; else ohci->hc_control &= ~OHCI_CTRL_RWE; @@ -246,9 +246,9 @@ static int ohci_bus_resume (struct usb_hcd *hcd) (void) ohci_readl (ohci, &ohci->regs->control); msleep (3); - temp = ohci->hc_control; - temp &= OHCI_CTRL_RWC; - temp |= OHCI_CONTROL_INIT | OHCI_USB_OPER; + temp = OHCI_CONTROL_INIT | OHCI_USB_OPER; + if (hcd->can_wakeup) + temp |= OHCI_CTRL_RWC; ohci->hc_control = temp; ohci_writel (ohci, temp, &ohci->regs->control); (void) ohci_readl (ohci, &ohci->regs->control); @@ -302,7 +302,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int i, changed = 0, length = 1; - int can_suspend = device_may_wakeup(&hcd->self.root_hub->dev); + int can_suspend = hcd->can_wakeup; unsigned long flags; spin_lock_irqsave (&ohci->lock, flags); @@ -354,7 +354,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) */ if (!(status & RH_PS_CCS)) continue; - if ((status & RH_PS_PSS) && can_suspend) + if ((status & RH_PS_PSS) && hcd->remote_wakeup) continue; can_suspend = 0; } diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index ca19abe01..3785b3f7d 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -286,7 +286,7 @@ void usb_hcd_omap_remove (struct usb_hcd *, struct platform_device *); int usb_hcd_omap_probe (const struct hc_driver *driver, struct platform_device *pdev) { - int retval, irq; + int retval; struct usb_hcd *hcd = 0; struct ohci_hcd *ohci; @@ -329,12 +329,7 @@ int usb_hcd_omap_probe (const struct hc_driver *driver, if (retval < 0) goto err2; - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - retval = -ENXIO; - goto err2; - } - retval = usb_add_hcd(hcd, irq, SA_INTERRUPT); + retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), SA_INTERRUPT); if (retval == 0) return retval; diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index b268537e3..1b09dde06 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -35,10 +35,7 @@ ohci_pci_start (struct usb_hcd *hcd) struct ohci_hcd *ohci = hcd_to_ohci (hcd); int ret; - /* REVISIT this whole block should move to reset(), which handles - * all the other one-time init. - */ - if (hcd->self.controller) { + if(hcd->self.controller && hcd->self.controller->bus == &pci_bus_type) { struct pci_dev *pdev = to_pci_dev(hcd->self.controller); /* AMD 756, for most chips (early revs), corrupts register @@ -48,8 +45,7 @@ ohci_pci_start (struct usb_hcd *hcd) && pdev->device == 0x740c) { ohci->flags = OHCI_QUIRK_AMD756; ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); - /* also erratum 10 (suspend/resume issues) */ - device_init_wakeup(&hcd->self.root_hub->dev, 0); + // also somewhat erratum 10 (suspend/resume issues) } /* FIXME for some of the early AMD 760 southbridges, OHCI @@ -92,13 +88,6 @@ ohci_pci_start (struct usb_hcd *hcd) ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); } - - /* RWC may not be set for add-in PCI cards, since boot - * firmware probably ignored them. This transfers PCI - * PM wakeup capabilities (once the PCI layer is fixed). - */ - if (device_may_wakeup(&pdev->dev)) - ohci->hc_control |= OHCI_CTRL_RWC; } /* NOTE: there may have already been a first reset, to @@ -206,7 +195,7 @@ static const struct hc_driver ohci_pci_hc_driver = { static const struct pci_device_id pci_ids [] = { { /* handle any USB OHCI controller */ - PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0), + PCI_DEVICE_CLASS((PCI_CLASS_SERIAL_USB << 8) | 0x10, ~0), .driver_data = (unsigned long) &ohci_pci_hc_driver, }, { /* end: all zeroes */ } }; diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index fafe7c126..acde8868d 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -185,9 +185,6 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device /* Select Power Management Mode */ pxa27x_ohci_select_pmm(inf->port_mode); - if (inf->power_budget) - hcd->power_budget = inf->power_budget; - ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT); diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 1da5de573..372527a83 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -30,7 +30,6 @@ /* clock device associated with the hcd */ static struct clk *clk; -static struct clk *usb_clk; /* forward definitions */ @@ -38,7 +37,7 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc); /* conversion functions */ -static struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) +struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) { return hcd->self.controller->platform_data; } @@ -48,10 +47,6 @@ static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd) struct s3c2410_hcd_info *info = dev->dev.platform_data; dev_dbg(&dev->dev, "s3c2410_start_hc:\n"); - - clk_enable(usb_clk); - mdelay(2); /* let the bus clock stabilise */ - clk_enable(clk); if (info != NULL) { @@ -80,7 +75,6 @@ static void s3c2410_stop_hc(struct platform_device *dev) } clk_disable(clk); - clk_disable(usb_clk); } /* ohci_s3c2410_hub_status_data @@ -164,7 +158,7 @@ static int ohci_s3c2410_hub_control ( "s3c2410_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n", hcd, typeReq, wValue, wIndex, buf, wLength); - /* if we are only an humble host without any special capabilities + /* if we are only an humble host without any special capabilites * process the request straight away and exit */ if (info == NULL) { @@ -322,8 +316,7 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) * */ -static void -usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) +void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) { usb_remove_hcd(hcd); s3c2410_stop_hc(dev); @@ -341,8 +334,8 @@ usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) * through the hotplug entry's driver_data. * */ -static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, - struct platform_device *dev) +int usb_hcd_s3c2410_probe (const struct hc_driver *driver, + struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; @@ -360,21 +353,14 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_err(&dev->dev, "request_mem_region failed"); retval = -EBUSY; - goto err_put; + goto err0; } - clk = clk_get(&dev->dev, "usb-host"); + clk = clk_get(NULL, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = -ENOENT; - goto err_mem; - } - - usb_clk = clk_get(&dev->dev, "upll"); - if (IS_ERR(usb_clk)) { - dev_err(&dev->dev, "cannot get usb-host clock\n"); - retval = -ENOENT; - goto err_clk; + goto err1; } s3c2410_start_hc(dev, hcd); @@ -383,29 +369,26 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, if (!hcd->regs) { dev_err(&dev->dev, "ioremap failed\n"); retval = -ENOMEM; - goto err_ioremap; + goto err2; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); if (retval != 0) - goto err_ioremap; + goto err2; return 0; - err_ioremap: + err2: s3c2410_stop_hc(dev); iounmap(hcd->regs); - clk_put(usb_clk); - - err_clk: clk_put(clk); - err_mem: + err1: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - err_put: + err0: usb_put_hcd(hcd); return retval; } diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 1045f846f..9e81c2631 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -15,7 +15,6 @@ #include #include #include -#include "pci-quirks.h" #define UHCI_USBLEGSUP 0xc0 /* legacy support */ diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h deleted file mode 100644 index 1564edfff..000000000 --- a/drivers/usb/host/pci-quirks.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __LINUX_USB_PCI_QUIRKS_H -#define __LINUX_USB_PCI_QUIRKS_H - -void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); -int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); - -#endif /* __LINUX_USB_PCI_QUIRKS_H */ diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index a92343052..517360b77 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -853,7 +853,7 @@ static int sl811h_urb_enqueue( } else { INIT_LIST_HEAD(&ep->schedule); - ep->udev = udev; + ep->udev = usb_get_dev(udev); ep->epnum = epnum; ep->maxpacket = usb_maxpacket(udev, urb->pipe, is_out); ep->defctrl = SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENABLE; @@ -1052,6 +1052,7 @@ sl811h_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) if (!list_empty(&hep->urb_list)) WARN("ep %p not empty?\n", ep); + usb_put_dev(ep->udev); kfree(ep); hep->hcpriv = NULL; } diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 302aa1ec3..134d20001 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -67,11 +67,11 @@ module_param(pc_debug, int, 0644); static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; typedef struct local_info_t { - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; } local_info_t; -static void sl811_cs_release(struct pcmcia_device * link); +static void sl811_cs_release(dev_link_t * link); /*====================================================================*/ @@ -138,27 +138,41 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) /*====================================================================*/ -static void sl811_cs_detach(struct pcmcia_device *link) +static void sl811_cs_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); + DBG(0, "sl811_cs_detach(0x%p)\n", link); - sl811_cs_release(link); + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) + sl811_cs_release(link); /* This points to the parent local_info_t struct */ kfree(link->priv); } -static void sl811_cs_release(struct pcmcia_device * link) +static void sl811_cs_release(dev_link_t * link) { + DBG(0, "sl811_cs_release(0x%p)\n", link); - pcmcia_disable_device(link); + /* Unlink the device chain */ + link->dev = NULL; + platform_device_unregister(&platform_dev); + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; } -static int sl811_cs_config(struct pcmcia_device *link) +static void sl811_cs_config(dev_link_t *link) { - struct device *parent = &handle_to_dev(link); + client_handle_t handle = link->handle; + struct device *parent = &handle_to_dev(handle); local_info_t *dev = link->priv; tuple_t tuple; cisparse_t parse; @@ -174,23 +188,27 @@ static int sl811_cs_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Configure card */ + link->state |= DEV_CONFIG; + /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); + pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - if (pcmcia_get_tuple_data(link, &tuple) != 0 - || pcmcia_parse_tuple(link, &tuple, &parse) + if (pcmcia_get_tuple_data(handle, &tuple) != 0 + || pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; @@ -216,10 +234,10 @@ static int sl811_cs_config(struct pcmcia_device *link) } if (cfg->vpp1.present & (1<conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<conf.Vpp = + link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* we need an interrupt */ @@ -236,14 +254,15 @@ static int sl811_cs_config(struct pcmcia_device *link) link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; } break; next_entry: - pcmcia_disable_device(link); - last_ret = pcmcia_get_next_tuple(link, &tuple); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + last_ret = pcmcia_get_next_tuple(handle, &tuple); } /* require an IRQ and two registers */ @@ -251,46 +270,71 @@ next_entry: goto cs_failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, - pcmcia_request_irq(link, &link->irq)); + pcmcia_request_irq(link->handle, &link->irq)); else goto cs_failed; CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link, &link->conf)); + pcmcia_request_configuration(link->handle, &link->conf)); sprintf(dev->node.dev_name, driver_name); dev->node.major = dev->node.minor = 0; - link->dev_node = &dev->node; + link->dev = &dev->node; - printk(KERN_INFO "%s: index 0x%02x: ", - dev->node.dev_name, link->conf.ConfigIndex); - if (link->conf.Vpp) - printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", + dev->node.dev_name, link->conf.ConfigIndex, + link->conf.Vcc/10, link->conf.Vcc%10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); printk(", irq %d", link->irq.AssignedIRQ); printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); + link->state &= ~DEV_CONFIG_PENDING; + if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { cs_failed: printk("sl811_cs_config failed\n"); - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); sl811_cs_release(link); - return -ENODEV; + link->state &= ~DEV_CONFIG_PENDING; } +} + +static int sl811_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int sl811_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + return 0; } -static int sl811_cs_probe(struct pcmcia_device *link) +static int sl811_cs_attach(struct pcmcia_device *p_dev) { local_info_t *local; + dev_link_t *link; local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); - local->p_dev = link; + link = &local->link; link->priv = local; /* Initialize */ @@ -299,9 +343,16 @@ static int sl811_cs_probe(struct pcmcia_device *link) link->irq.Handler = NULL; link->conf.Attributes = 0; + link->conf.Vcc = 33; link->conf.IntType = INT_MEMORY_AND_IO; - return sl811_cs_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + sl811_cs_config(link); + + return 0; } static struct pcmcia_device_id sl811_ids[] = { @@ -315,9 +366,11 @@ static struct pcmcia_driver sl811_cs_driver = { .drv = { .name = (char *)driver_name, }, - .probe = sl811_cs_probe, + .probe = sl811_cs_attach, .remove = sl811_cs_detach, .id_table = sl811_ids, + .suspend = sl811_suspend, + .resume = sl811_resume, }; /*====================================================================*/ diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index e12393196..583295308 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -17,13 +17,10 @@ #include "uhci-hcd.h" -#define uhci_debug_operations (* (struct file_operations *) NULL) -static struct dentry *uhci_debugfs_root; - -#ifdef DEBUG +static struct dentry *uhci_debugfs_root = NULL; /* Handle REALLY large printks so we don't overflow buffers */ -static void lprintk(char *buf) +static inline void lprintk(char *buf) { char *p; @@ -93,59 +90,13 @@ static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space) return out - buf; } -static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) -{ - char *out = buf; - struct uhci_td *td; - int i, nactive, ninactive; - - if (len < 200) - return 0; - - out += sprintf(out, "urb_priv [%p] ", urbp); - out += sprintf(out, "urb [%p] ", urbp->urb); - out += sprintf(out, "qh [%p] ", urbp->qh); - out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe)); - out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe), - (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT")); - - switch (usb_pipetype(urbp->urb->pipe)) { - case PIPE_ISOCHRONOUS: out += sprintf(out, "ISO"); break; - case PIPE_INTERRUPT: out += sprintf(out, "INT"); break; - case PIPE_BULK: out += sprintf(out, "BLK"); break; - case PIPE_CONTROL: out += sprintf(out, "CTL"); break; - } - - out += sprintf(out, "%s", (urbp->fsbr ? " FSBR" : "")); - - if (urbp->urb->status != -EINPROGRESS) - out += sprintf(out, " Status=%d", urbp->urb->status); - out += sprintf(out, "\n"); - - i = nactive = ninactive = 0; - list_for_each_entry(td, &urbp->td_list, list) { - if (++i <= 10 || debug > 2) { - out += sprintf(out, "%*s%d: ", space + 2, "", i); - out += uhci_show_td(td, out, len - (out - buf), 0); - } else { - if (td_status(td) & TD_CTRL_ACTIVE) - ++nactive; - else - ++ninactive; - } - } - if (nactive + ninactive > 0) - out += sprintf(out, "%*s[skipped %d inactive and %d active " - "TDs]\n", - space, "", ninactive, nactive); - - return out - buf; -} - static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) { char *out = buf; - int i, nurbs; + struct urb_priv *urbp; + struct list_head *head, *tmp; + struct uhci_td *td; + int i = 0, checked = 0, prevactive = 0; __le32 element = qh_element(qh); /* Try to make sure there's enough memory */ @@ -167,40 +118,86 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) if (!(element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH))) out += sprintf(out, "%*s Element is NULL (bug?)\n", space, ""); - if (list_empty(&qh->queue)) { - out += sprintf(out, "%*s queue is empty\n", space, ""); - } else { - struct urb_priv *urbp = list_entry(qh->queue.next, - struct urb_priv, node); - struct uhci_td *td = list_entry(urbp->td_list.next, - struct uhci_td, list); - - if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS)) - out += sprintf(out, "%*s Element != First TD\n", - space, ""); - i = nurbs = 0; - list_for_each_entry(urbp, &qh->queue, node) { - if (++i <= 10) - out += uhci_show_urbp(urbp, out, - len - (out - buf), space + 2); - else - ++nurbs; + if (!qh->urbp) { + out += sprintf(out, "%*s urbp == NULL\n", space, ""); + goto out; + } + + urbp = qh->urbp; + + head = &urbp->td_list; + tmp = head->next; + + td = list_entry(tmp, struct uhci_td, list); + + if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS)) + out += sprintf(out, "%*s Element != First TD\n", space, ""); + + while (tmp != head) { + struct uhci_td *td = list_entry(tmp, struct uhci_td, list); + + tmp = tmp->next; + + out += sprintf(out, "%*s%d: ", space + 2, "", i++); + out += uhci_show_td(td, out, len - (out - buf), 0); + + if (i > 10 && !checked && prevactive && tmp != head && + debug <= 2) { + struct list_head *ntmp = tmp; + struct uhci_td *ntd = td; + int active = 1, ni = i; + + checked = 1; + + while (ntmp != head && ntmp->next != head && active) { + ntd = list_entry(ntmp, struct uhci_td, list); + + ntmp = ntmp->next; + + active = td_status(ntd) & TD_CTRL_ACTIVE; + + ni++; + } + + if (active && ni > i) { + out += sprintf(out, "%*s[skipped %d active TDs]\n", space, "", ni - i); + tmp = ntmp; + td = ntd; + i = ni; + } } - if (nurbs > 0) - out += sprintf(out, "%*s Skipped %d URBs\n", - space, "", nurbs); + + prevactive = td_status(td) & TD_CTRL_ACTIVE; } - if (qh->udev) { - out += sprintf(out, "%*s Dummy TD\n", space, ""); - out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); + if (list_empty(&urbp->queue_list) || urbp->queued) + goto out; + + out += sprintf(out, "%*sQueued QHs:\n", -space, "--"); + + head = &urbp->queue_list; + tmp = head->next; + + while (tmp != head) { + struct urb_priv *nurbp = list_entry(tmp, struct urb_priv, + queue_list); + tmp = tmp->next; + + out += uhci_show_qh(nurbp->qh, out, len - (out - buf), space); } +out: return out - buf; } +#define show_frame_num() \ + if (!shown) { \ + shown = 1; \ + out += sprintf(out, "- Frame %d\n", i); \ + } + +#ifdef CONFIG_PROC_FS static const char * const qh_names[] = { - "skel_unlink_qh", "skel_iso_qh", "skel_int128_qh", "skel_int64_qh", "skel_int32_qh", "skel_int16_qh", "skel_int8_qh", "skel_int4_qh", @@ -209,6 +206,12 @@ static const char * const qh_names[] = { "skel_bulk_qh", "skel_term_qh" }; +#define show_qh_name() \ + if (!shown) { \ + shown = 1; \ + out += sprintf(out, "- %s\n", qh_names[i]); \ + } + static int uhci_show_sc(int port, unsigned short status, char *buf, int len) { char *out = buf; @@ -318,29 +321,139 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) return out - buf; } +static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *buf, int len) +{ + struct list_head *tmp; + char *out = buf; + int count = 0; + + if (len < 200) + return 0; + + out += sprintf(out, "urb_priv [%p] ", urbp); + out += sprintf(out, "urb [%p] ", urbp->urb); + out += sprintf(out, "qh [%p] ", urbp->qh); + out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe)); + out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe), (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT")); + + switch (usb_pipetype(urbp->urb->pipe)) { + case PIPE_ISOCHRONOUS: out += sprintf(out, "ISO "); break; + case PIPE_INTERRUPT: out += sprintf(out, "INT "); break; + case PIPE_BULK: out += sprintf(out, "BLK "); break; + case PIPE_CONTROL: out += sprintf(out, "CTL "); break; + } + + out += sprintf(out, "%s", (urbp->fsbr ? "FSBR " : "")); + out += sprintf(out, "%s", (urbp->fsbr_timeout ? "FSBR_TO " : "")); + + if (urbp->urb->status != -EINPROGRESS) + out += sprintf(out, "Status=%d ", urbp->urb->status); + //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); + + count = 0; + list_for_each(tmp, &urbp->td_list) + count++; + out += sprintf(out, "TDs=%d ",count); + + if (urbp->queued) + out += sprintf(out, "queued\n"); + else { + count = 0; + list_for_each(tmp, &urbp->queue_list) + count++; + out += sprintf(out, "queued URBs=%d\n", count); + } + + return out - buf; +} + +static int uhci_show_lists(struct uhci_hcd *uhci, char *buf, int len) +{ + char *out = buf; + struct list_head *head, *tmp; + int count; + + out += sprintf(out, "Main list URBs:"); + if (list_empty(&uhci->urb_list)) + out += sprintf(out, " Empty\n"); + else { + out += sprintf(out, "\n"); + count = 0; + head = &uhci->urb_list; + tmp = head->next; + while (tmp != head) { + struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list); + + out += sprintf(out, " %d: ", ++count); + out += uhci_show_urbp(uhci, urbp, out, len - (out - buf)); + tmp = tmp->next; + } + } + + out += sprintf(out, "Remove list URBs:"); + if (list_empty(&uhci->urb_remove_list)) + out += sprintf(out, " Empty\n"); + else { + out += sprintf(out, "\n"); + count = 0; + head = &uhci->urb_remove_list; + tmp = head->next; + while (tmp != head) { + struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list); + + out += sprintf(out, " %d: ", ++count); + out += uhci_show_urbp(uhci, urbp, out, len - (out - buf)); + tmp = tmp->next; + } + } + + out += sprintf(out, "Complete list URBs:"); + if (list_empty(&uhci->complete_list)) + out += sprintf(out, " Empty\n"); + else { + out += sprintf(out, "\n"); + count = 0; + head = &uhci->complete_list; + tmp = head->next; + while (tmp != head) { + struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list); + + out += sprintf(out, " %d: ", ++count); + out += uhci_show_urbp(uhci, urbp, out, len - (out - buf)); + tmp = tmp->next; + } + } + + return out - buf; +} + static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) { + unsigned long flags; char *out = buf; int i, j; struct uhci_qh *qh; struct uhci_td *td; struct list_head *tmp, *head; + spin_lock_irqsave(&uhci->lock, flags); + out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); out += sprintf(out, "HC status\n"); out += uhci_show_status(uhci, out, len - (out - buf)); - if (debug <= 1) - return out - buf; out += sprintf(out, "Frame List\n"); for (i = 0; i < UHCI_NUMFRAMES; ++i) { + int shown = 0; td = uhci->frame_cpu[i]; if (!td) continue; - out += sprintf(out, "- Frame %d\n", i); \ - if (td->dma_handle != (dma_addr_t)uhci->frame[i]) + if (td->dma_handle != (dma_addr_t)uhci->frame[i]) { + show_frame_num(); out += sprintf(out, " frame list does not match td->dma_handle!\n"); + } + show_frame_num(); head = &td->fl_list; tmp = head; @@ -354,11 +467,14 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) out += sprintf(out, "Skeleton QHs\n"); for (i = 0; i < UHCI_NUM_SKELQH; ++i) { - int cnt = 0; + int shown = 0; qh = uhci->skelqh[i]; - out += sprintf(out, "- %s\n", qh_names[i]); \ - out += uhci_show_qh(qh, out, len - (out - buf), 4); + + if (debug > 1) { + show_qh_name(); + out += uhci_show_qh(qh, out, len - (out - buf), 4); + } /* Last QH is the Terminating QH, it's different */ if (i == UHCI_NUM_SKELQH - 1) { @@ -371,37 +487,53 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) continue; } - j = (i < 9) ? 9 : i+1; /* Next skeleton */ - head = &qh->node; + j = (i < 7) ? 7 : i+1; /* Next skeleton */ + if (list_empty(&qh->list)) { + if (i < UHCI_NUM_SKELQH - 1) { + if (qh->link != + (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH)) { + show_qh_name(); + out += sprintf(out, " skeleton QH not linked to next skeleton QH!\n"); + } + } + + continue; + } + + show_qh_name(); + + head = &qh->list; tmp = head->next; while (tmp != head) { - qh = list_entry(tmp, struct uhci_qh, node); + qh = list_entry(tmp, struct uhci_qh, list); + tmp = tmp->next; - if (++cnt <= 10) - out += uhci_show_qh(qh, out, - len - (out - buf), 4); + + out += uhci_show_qh(qh, out, len - (out - buf), 4); } - if ((cnt -= 10) > 0) - out += sprintf(out, " Skipped %d QHs\n", cnt); - if (i > 1 && i < UHCI_NUM_SKELQH - 1) { + if (i < UHCI_NUM_SKELQH - 1) { if (qh->link != (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH)) out += sprintf(out, " last QH not linked to next skeleton!\n"); } } + if (debug > 2) + out += uhci_show_lists(uhci, out, len - (out - buf)); + + spin_unlock_irqrestore(&uhci->lock, flags); + return out - buf; } -#ifdef CONFIG_DEBUG_FS - #define MAX_OUTPUT (64 * 1024) struct uhci_debug { int size; char *data; + struct uhci_hcd *uhci; }; static int uhci_debug_open(struct inode *inode, struct file *file) @@ -409,7 +541,6 @@ static int uhci_debug_open(struct inode *inode, struct file *file) struct uhci_hcd *uhci = inode->u.generic_ip; struct uhci_debug *up; int ret = -ENOMEM; - unsigned long flags; lock_kernel(); up = kmalloc(sizeof(*up), GFP_KERNEL); @@ -422,11 +553,7 @@ static int uhci_debug_open(struct inode *inode, struct file *file) goto out; } - up->size = 0; - spin_lock_irqsave(&uhci->lock, flags); - if (uhci->is_initialized) - up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT); - spin_unlock_irqrestore(&uhci->lock, flags); + up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT); file->private_data = up; @@ -477,32 +604,15 @@ static int uhci_debug_release(struct inode *inode, struct file *file) return 0; } -#undef uhci_debug_operations static struct file_operations uhci_debug_operations = { - .owner = THIS_MODULE, .open = uhci_debug_open, .llseek = uhci_debug_lseek, .read = uhci_debug_read, .release = uhci_debug_release, }; -#endif /* CONFIG_DEBUG_FS */ - -#else /* DEBUG */ - -static inline void lprintk(char *buf) -{} - -static inline int uhci_show_qh(struct uhci_qh *qh, char *buf, - int len, int space) -{ - return 0; -} +#else /* CONFIG_DEBUG_FS */ -static inline int uhci_sprint_schedule(struct uhci_hcd *uhci, - char *buf, int len) -{ - return 0; -} +#define uhci_debug_operations (* (struct file_operations *) NULL) #endif diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index d225e11f4..dfe121d35 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -50,12 +50,11 @@ #include "../core/hcd.h" #include "uhci-hcd.h" -#include "pci-quirks.h" /* * Version Information */ -#define DRIVER_VERSION "v3.0" +#define DRIVER_VERSION "v2.3" #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \ Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \ Alan Stern" @@ -69,16 +68,12 @@ Alan Stern" * debug = 3, show all TDs in URBs when dumping */ #ifdef DEBUG -#define DEBUG_CONFIGURED 1 static int debug = 1; -module_param(debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug level"); - #else -#define DEBUG_CONFIGURED 0 -#define debug 0 +static int debug = 0; #endif - +module_param(debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug level"); static char *errbuf; #define ERRBUF_LEN (32 * 1024) @@ -101,6 +96,9 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); #include "uhci-q.c" #include "uhci-hub.c" +extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); +extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); + /* * Finish up a host controller reset and update the recorded state. */ @@ -115,7 +113,8 @@ static void finish_reset(struct uhci_hcd *uhci) for (port = 0; port < uhci->rh_numports; ++port) outw(0, uhci->io_addr + USBPORTSC1 + (port * 2)); - uhci->port_c_suspend = uhci->resuming_ports = 0; + uhci->port_c_suspend = uhci->suspended_ports = + uhci->resuming_ports = 0; uhci->rh_state = UHCI_RH_RESET; uhci->is_stopped = UHCI_IS_STOPPED; uhci_to_hcd(uhci)->state = HC_STATE_HALT; @@ -339,12 +338,6 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) dev_err(uhci_dev(uhci), "host controller halted, " "very bad!\n"); - if (debug > 1 && errbuf) { - /* Print the schedule for debugging */ - uhci_sprint_schedule(uhci, - errbuf, ERRBUF_LEN); - lprintk(errbuf); - } hc_died(uhci); /* Force a callback in case there are @@ -383,14 +376,6 @@ static void release_uhci(struct uhci_hcd *uhci) { int i; - if (DEBUG_CONFIGURED) { - spin_lock_irq(&uhci->lock); - uhci->is_initialized = 0; - spin_unlock_irq(&uhci->lock); - - debugfs_remove(uhci->dentry); - } - for (i = 0; i < UHCI_NUM_SKELQH; i++) uhci_free_qh(uhci, uhci->skelqh[i]); @@ -405,6 +390,8 @@ static void release_uhci(struct uhci_hcd *uhci) dma_free_coherent(uhci_dev(uhci), UHCI_NUMFRAMES * sizeof(*uhci->frame), uhci->frame, uhci->frame_dma_handle); + + debugfs_remove(uhci->dentry); } static int uhci_reset(struct usb_hcd *hcd) @@ -487,28 +474,32 @@ static int uhci_start(struct usb_hcd *hcd) hcd->uses_new_polling = 1; + dentry = debugfs_create_file(hcd->self.bus_name, + S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, + &uhci_debug_operations); + if (!dentry) { + dev_err(uhci_dev(uhci), + "couldn't create uhci debugfs entry\n"); + retval = -ENOMEM; + goto err_create_debug_entry; + } + uhci->dentry = dentry; + uhci->fsbr = 0; uhci->fsbrtimeout = 0; spin_lock_init(&uhci->lock); + INIT_LIST_HEAD(&uhci->qh_remove_list); INIT_LIST_HEAD(&uhci->td_remove_list); - INIT_LIST_HEAD(&uhci->idle_qh_list); - init_waitqueue_head(&uhci->waitqh); + INIT_LIST_HEAD(&uhci->urb_remove_list); - if (DEBUG_CONFIGURED) { - dentry = debugfs_create_file(hcd->self.bus_name, - S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, - uhci, &uhci_debug_operations); - if (!dentry) { - dev_err(uhci_dev(uhci), "couldn't create uhci " - "debugfs entry\n"); - retval = -ENOMEM; - goto err_create_debug_entry; - } - uhci->dentry = dentry; - } + INIT_LIST_HEAD(&uhci->urb_list); + + INIT_LIST_HEAD(&uhci->complete_list); + + init_waitqueue_head(&uhci->waitqh); uhci->frame = dma_alloc_coherent(uhci_dev(uhci), UHCI_NUMFRAMES * sizeof(*uhci->frame), @@ -549,7 +540,7 @@ static int uhci_start(struct usb_hcd *hcd) } for (i = 0; i < UHCI_NUM_SKELQH; i++) { - uhci->skelqh[i] = uhci_alloc_qh(uhci, NULL, NULL); + uhci->skelqh[i] = uhci_alloc_qh(uhci); if (!uhci->skelqh[i]) { dev_err(uhci_dev(uhci), "unable to allocate QH\n"); goto err_alloc_skelqh; @@ -566,17 +557,13 @@ static int uhci_start(struct usb_hcd *hcd) uhci->skel_int16_qh->link = uhci->skel_int8_qh->link = uhci->skel_int4_qh->link = - uhci->skel_int2_qh->link = UHCI_PTR_QH | - cpu_to_le32(uhci->skel_int1_qh->dma_handle); - - uhci->skel_int1_qh->link = UHCI_PTR_QH | - cpu_to_le32(uhci->skel_ls_control_qh->dma_handle); - uhci->skel_ls_control_qh->link = UHCI_PTR_QH | - cpu_to_le32(uhci->skel_fs_control_qh->dma_handle); - uhci->skel_fs_control_qh->link = UHCI_PTR_QH | - cpu_to_le32(uhci->skel_bulk_qh->dma_handle); - uhci->skel_bulk_qh->link = UHCI_PTR_QH | - cpu_to_le32(uhci->skel_term_qh->dma_handle); + uhci->skel_int2_qh->link = + cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH; + uhci->skel_int1_qh->link = cpu_to_le32(uhci->skel_ls_control_qh->dma_handle) | UHCI_PTR_QH; + + uhci->skel_ls_control_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; + uhci->skel_fs_control_qh->link = cpu_to_le32(uhci->skel_bulk_qh->dma_handle) | UHCI_PTR_QH; + uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; /* This dummy TD is to work around a bug in Intel PIIX controllers */ uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | @@ -602,15 +589,15 @@ static int uhci_start(struct usb_hcd *hcd) /* * ffs (Find First bit Set) does exactly what we need: - * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], - * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. - * ffs >= 7 => not on any high-period queue, so use - * skel_int1_qh = skelqh[9]. + * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[6], + * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[5], etc. + * ffs > 6 => not on any high-period queue, so use + * skel_int1_qh = skelqh[7]. * Add UHCI_NUMFRAMES to insure at least one bit is set. */ - irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES); - if (irq <= 1) - irq = 9; + irq = 6 - (int) __ffs(i + UHCI_NUMFRAMES); + if (irq < 0) + irq = 7; /* Only place we don't use the frame list routines */ uhci->frame[i] = UHCI_PTR_QH | @@ -624,7 +611,6 @@ static int uhci_start(struct usb_hcd *hcd) mb(); configure_hc(uhci); - uhci->is_initialized = 1; start_rh(uhci); return 0; @@ -781,30 +767,13 @@ static int uhci_resume(struct usb_hcd *hcd) } #endif -/* Wait until a particular device/endpoint's QH is idle, and free it */ +/* Wait until all the URBs for a particular device/endpoint are gone */ static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd, - struct usb_host_endpoint *hep) + struct usb_host_endpoint *ep) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); - struct uhci_qh *qh; - - spin_lock_irq(&uhci->lock); - qh = (struct uhci_qh *) hep->hcpriv; - if (qh == NULL) - goto done; - - while (qh->state != QH_STATE_IDLE) { - ++uhci->num_waiting; - spin_unlock_irq(&uhci->lock); - wait_event_interruptible(uhci->waitqh, - qh->state == QH_STATE_IDLE); - spin_lock_irq(&uhci->lock); - --uhci->num_waiting; - } - uhci_free_qh(uhci, qh); -done: - spin_unlock_irq(&uhci->lock); + wait_event_interruptible(uhci->waitqh, list_empty(&ep->urb_list)); } static int uhci_hcd_get_frame_number(struct usb_hcd *hcd) @@ -858,7 +827,7 @@ static const struct hc_driver uhci_driver = { static const struct pci_device_id uhci_pci_ids[] = { { /* handle any USB UHCI controller */ - PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), + PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x00), ~0), .driver_data = (unsigned long) &uhci_driver, }, { /* end: all zeroes */ } }; @@ -888,15 +857,16 @@ static int __init uhci_hcd_init(void) if (usb_disabled()) return -ENODEV; - if (DEBUG_CONFIGURED) { + if (debug) { errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); if (!errbuf) goto errbuf_failed; - uhci_debugfs_root = debugfs_create_dir("uhci", NULL); - if (!uhci_debugfs_root) - goto debug_failed; } + uhci_debugfs_root = debugfs_create_dir("uhci", NULL); + if (!uhci_debugfs_root) + goto debug_failed; + uhci_up_cachep = kmem_cache_create("uhci_urb_priv", sizeof(struct urb_priv), 0, 0, NULL, NULL); if (!uhci_up_cachep) diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index d5c8f4d92..8b4b887a7 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -28,9 +28,8 @@ #define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */ #define USBSTS_ERROR 0x0002 /* Interrupt due to error */ #define USBSTS_RD 0x0004 /* Resume Detect */ -#define USBSTS_HSE 0x0008 /* Host System Error: PCI problems */ -#define USBSTS_HCPE 0x0010 /* Host Controller Process Error: - * the schedule is buggy */ +#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */ +#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */ #define USBSTS_HCH 0x0020 /* HC Halted */ /* Interrupt enable register */ @@ -48,8 +47,7 @@ /* USB port status and control registers */ #define USBPORTSC1 16 #define USBPORTSC2 18 -#define USBPORTSC_CCS 0x0001 /* Current Connect Status - * ("device present") */ +#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */ #define USBPORTSC_CSC 0x0002 /* Connect Status Change */ #define USBPORTSC_PE 0x0004 /* Port Enable */ #define USBPORTSC_PEC 0x0008 /* Port Enable Change */ @@ -73,16 +71,15 @@ #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ -#define UHCI_PTR_BITS __constant_cpu_to_le32(0x000F) -#define UHCI_PTR_TERM __constant_cpu_to_le32(0x0001) -#define UHCI_PTR_QH __constant_cpu_to_le32(0x0002) -#define UHCI_PTR_DEPTH __constant_cpu_to_le32(0x0004) -#define UHCI_PTR_BREADTH __constant_cpu_to_le32(0x0000) +#define UHCI_PTR_BITS cpu_to_le32(0x000F) +#define UHCI_PTR_TERM cpu_to_le32(0x0001) +#define UHCI_PTR_QH cpu_to_le32(0x0002) +#define UHCI_PTR_DEPTH cpu_to_le32(0x0004) +#define UHCI_PTR_BREADTH cpu_to_le32(0x0000) #define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ -#define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames - * can be scheduled */ +#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ /* @@ -90,59 +87,38 @@ */ /* - * One role of a QH is to hold a queue of TDs for some endpoint. One QH goes - * with each endpoint, and qh->element (updated by the HC) is either: - * - the next unprocessed TD in the endpoint's queue, or - * - UHCI_PTR_TERM (when there's no more traffic for this endpoint). + * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is + * used with one URB, and qh->element (updated by the HC) is either: + * - the next unprocessed TD for the URB, or + * - UHCI_PTR_TERM (when there's no more traffic for this endpoint), or + * - the QH for the next URB queued to the same endpoint. * * The other role of a QH is to serve as a "skeleton" framelist entry, so we * can easily splice a QH for some endpoint into the schedule at the right * place. Then qh->element is UHCI_PTR_TERM. * - * In the schedule, qh->link maintains a list of QHs seen by the HC: + * In the frame list, qh->link maintains a list of QHs seen by the HC: * skel1 --> ep1-qh --> ep2-qh --> ... --> skel2 --> ... - * - * qh->node is the software equivalent of qh->link. The differences - * are that the software list is doubly-linked and QHs in the UNLINKING - * state are on the software list but not the hardware schedule. - * - * For bookkeeping purposes we maintain QHs even for Isochronous endpoints, - * but they never get added to the hardware schedule. */ -#define QH_STATE_IDLE 1 /* QH is not being used */ -#define QH_STATE_UNLINKING 2 /* QH has been removed from the - * schedule but the hardware may - * still be using it */ -#define QH_STATE_ACTIVE 3 /* QH is on the schedule */ - struct uhci_qh { /* Hardware fields */ - __le32 link; /* Next QH in the schedule */ - __le32 element; /* Queue element (TD) pointer */ + __le32 link; /* Next queue */ + __le32 element; /* Queue element pointer */ /* Software fields */ dma_addr_t dma_handle; - struct list_head node; /* Node in the list of QHs */ - struct usb_host_endpoint *hep; /* Endpoint information */ - struct usb_device *udev; - struct list_head queue; /* Queue of urbps for this QH */ - struct uhci_qh *skel; /* Skeleton for this QH */ - struct uhci_td *dummy_td; /* Dummy TD to end the queue */ + struct urb_priv *urbp; - unsigned int unlink_frame; /* When the QH was unlinked */ - int state; /* QH_STATE_xxx; see above */ - - unsigned int initial_toggle:1; /* Endpoint's current toggle value */ - unsigned int needs_fixup:1; /* Must fix the TD toggle values */ - unsigned int is_stopped:1; /* Queue was stopped by an error */ + struct list_head list; + struct list_head remove_list; } __attribute__((aligned(16))); /* * We need a special accessor for the element pointer because it is * subject to asynchronous updates by the controller. */ -static inline __le32 qh_element(struct uhci_qh *qh) { +static __le32 inline qh_element(struct uhci_qh *qh) { __le32 element = qh->element; barrier(); @@ -173,13 +149,11 @@ static inline __le32 qh_element(struct uhci_qh *qh) { #define TD_CTRL_ACTLEN_MASK 0x7FF /* actual length, encoded as n - 1 */ #define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ - TD_CTRL_BABBLE | TD_CTRL_CRCTIME | \ - TD_CTRL_BITSTUFF) + TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF) #define uhci_maxerr(err) ((err) << TD_CTRL_C_ERR_SHIFT) #define uhci_status_bits(ctrl_sts) ((ctrl_sts) & 0xF60000) -#define uhci_actual_length(ctrl_sts) (((ctrl_sts) + 1) & \ - TD_CTRL_ACTLEN_MASK) /* 1-based */ +#define uhci_actual_length(ctrl_sts) (((ctrl_sts) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */ /* * for TD : (a.k.a. Token) @@ -189,7 +163,7 @@ static inline __le32 qh_element(struct uhci_qh *qh) { #define TD_TOKEN_TOGGLE_SHIFT 19 #define TD_TOKEN_TOGGLE (1 << 19) #define TD_TOKEN_EXPLEN_SHIFT 21 -#define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n-1 */ +#define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */ #define TD_TOKEN_PID_MASK 0xFF #define uhci_explen(len) ((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \ @@ -213,7 +187,7 @@ static inline __le32 qh_element(struct uhci_qh *qh) { * sw space after the TD entry. * * td->link points to either another TD (not necessarily for the same urb or - * even the same endpoint), or nothing (PTR_TERM), or a QH. + * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs). */ struct uhci_td { /* Hardware fields */ @@ -236,7 +210,7 @@ struct uhci_td { * We need a special accessor for the control/status word because it is * subject to asynchronous updates by the controller. */ -static inline u32 td_status(struct uhci_td *td) { +static u32 inline td_status(struct uhci_td *td) { __le32 status = td->status; barrier(); @@ -249,14 +223,17 @@ static inline u32 td_status(struct uhci_td *td) { */ /* - * The UHCI driver uses QHs with Interrupt, Control and Bulk URBs for - * automatic queuing. To make it easy to insert entries into the schedule, - * we have a skeleton of QHs for each predefined Interrupt latency, - * low-speed control, full-speed control, bulk, and terminating QH - * (see explanation for the terminating QH below). + * The UHCI driver places Interrupt, Control and Bulk into QHs both + * to group together TDs for one transfer, and also to facilitate queuing + * of URBs. To make it easy to insert entries into the schedule, we have + * a skeleton of QHs for each predefined Interrupt latency, low-speed + * control, full-speed control and terminating QH (see explanation for + * the terminating QH below). * * When we want to add a new QH, we add it to the end of the list for the - * skeleton QH. For instance, the schedule list can look like this: + * skeleton QH. + * + * For instance, the queue can look like this: * * skel int128 QH * dev 1 interrupt QH @@ -279,31 +256,26 @@ static inline u32 td_status(struct uhci_td *td) { * - To loop back to the full-speed control queue for full-speed bandwidth * reclamation. * - * There's a special skeleton QH for Isochronous QHs. It never appears - * on the schedule, and Isochronous TDs go on the schedule before the - * the skeleton QHs. The hardware accesses them directly rather than - * through their QH, which is used only for bookkeeping purposes. - * While the UHCI spec doesn't forbid the use of QHs for Isochronous, - * it doesn't use them either. And the spec says that queues never - * advance on an error completion status, which makes them totally - * unsuitable for Isochronous transfers. + * Isochronous transfers are stored before the start of the skeleton + * schedule and don't use QHs. While the UHCI spec doesn't forbid the + * use of QHs for Isochronous, it doesn't use them either. And the spec + * says that queues never advance on an error completion status, which + * makes them totally unsuitable for Isochronous transfers. */ -#define UHCI_NUM_SKELQH 14 -#define skel_unlink_qh skelqh[0] -#define skel_iso_qh skelqh[1] -#define skel_int128_qh skelqh[2] -#define skel_int64_qh skelqh[3] -#define skel_int32_qh skelqh[4] -#define skel_int16_qh skelqh[5] -#define skel_int8_qh skelqh[6] -#define skel_int4_qh skelqh[7] -#define skel_int2_qh skelqh[8] -#define skel_int1_qh skelqh[9] -#define skel_ls_control_qh skelqh[10] -#define skel_fs_control_qh skelqh[11] -#define skel_bulk_qh skelqh[12] -#define skel_term_qh skelqh[13] +#define UHCI_NUM_SKELQH 12 +#define skel_int128_qh skelqh[0] +#define skel_int64_qh skelqh[1] +#define skel_int32_qh skelqh[2] +#define skel_int16_qh skelqh[3] +#define skel_int8_qh skelqh[4] +#define skel_int4_qh skelqh[5] +#define skel_int2_qh skelqh[6] +#define skel_int1_qh skelqh[7] +#define skel_ls_control_qh skelqh[8] +#define skel_fs_control_qh skelqh[9] +#define skel_bulk_qh skelqh[10] +#define skel_term_qh skelqh[11] /* * Search tree for determining where fits in the skelqh[] @@ -321,21 +293,21 @@ static inline int __interval_to_skel(int interval) if (interval < 16) { if (interval < 4) { if (interval < 2) - return 9; /* int1 for 0-1 ms */ - return 8; /* int2 for 2-3 ms */ + return 7; /* int1 for 0-1 ms */ + return 6; /* int2 for 2-3 ms */ } if (interval < 8) - return 7; /* int4 for 4-7 ms */ - return 6; /* int8 for 8-15 ms */ + return 5; /* int4 for 4-7 ms */ + return 4; /* int8 for 8-15 ms */ } if (interval < 64) { if (interval < 32) - return 5; /* int16 for 16-31 ms */ - return 4; /* int32 for 32-63 ms */ + return 3; /* int16 for 16-31 ms */ + return 2; /* int32 for 32-63 ms */ } if (interval < 128) - return 3; /* int64 for 64-127 ms */ - return 2; /* int128 for 128-255 ms (Max.) */ + return 1; /* int64 for 64-127 ms */ + return 0; /* int128 for 128-255 ms (Max.) */ } @@ -388,16 +360,15 @@ struct uhci_hcd { struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QHs */ - struct uhci_qh *next_qh; /* Next QH to scan */ spinlock_t lock; - dma_addr_t frame_dma_handle; /* Hardware frame list */ + dma_addr_t frame_dma_handle; /* Hardware frame list */ __le32 *frame; - void **frame_cpu; /* CPU's frame list */ + void **frame_cpu; /* CPU's frame list */ - int fsbr; /* Full-speed bandwidth reclamation */ - unsigned long fsbrtimeout; /* FSBR delay */ + int fsbr; /* Full-speed bandwidth reclamation */ + unsigned long fsbrtimeout; /* FSBR delay */ enum uhci_rh_state rh_state; unsigned long auto_stop_time; /* When to AUTO_STOP */ @@ -411,23 +382,34 @@ struct uhci_hcd { unsigned int hc_inaccessible:1; /* HC is suspended or dead */ unsigned int working_RD:1; /* Suspended root hub doesn't need to be polled */ - unsigned int is_initialized:1; /* Data structure is usable */ /* Support for port suspend/resume/reset */ unsigned long port_c_suspend; /* Bit-arrays of ports */ + unsigned long suspended_ports; unsigned long resuming_ports; unsigned long ports_timeout; /* Time to stop signalling */ + /* Main list of URBs currently controlled by this HC */ + struct list_head urb_list; + + /* List of QHs that are done, but waiting to be unlinked (race) */ + struct list_head qh_remove_list; + unsigned int qh_remove_age; /* Age in frames */ + /* List of TDs that are done, but waiting to be freed (race) */ struct list_head td_remove_list; unsigned int td_remove_age; /* Age in frames */ - struct list_head idle_qh_list; /* Where the idle QHs live */ + /* List of asynchronously unlinked URBs */ + struct list_head urb_remove_list; + unsigned int urb_remove_age; /* Age in frames */ + + /* List of URBs awaiting completion callback */ + struct list_head complete_list; int rh_numports; /* Number of root-hub ports */ wait_queue_head_t waitqh; /* endpoint_disable waiters */ - int num_waiting; /* Number of waiters */ }; /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ @@ -447,7 +429,7 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci) * Private per-URB data */ struct urb_priv { - struct list_head node; /* Node in the QH's urbp list */ + struct list_head urb_list; struct urb *urb; @@ -455,8 +437,15 @@ struct urb_priv { struct list_head td_list; unsigned fsbr : 1; /* URB turned on FSBR */ - unsigned short_transfer : 1; /* URB got a short transfer, no - * need to rescan */ + unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ + unsigned queued : 1; /* QH was queued (not linked in) */ + unsigned short_control_packet : 1; /* If we get a short packet during */ + /* a control transfer, retrigger */ + /* the status phase */ + + unsigned long fsbrtime; /* In jiffies */ + + struct list_head queue_list; }; diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index c8451d957..152971d16 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -85,10 +85,11 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, { int status; - if (inw(port_addr) & (USBPORTSC_SUSP | USBPORTSC_RD)) { + if (test_bit(port, &uhci->suspended_ports)) { CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD); - if (test_bit(port, &uhci->resuming_ports)) - set_bit(port, &uhci->port_c_suspend); + clear_bit(port, &uhci->suspended_ports); + clear_bit(port, &uhci->resuming_ports); + set_bit(port, &uhci->port_c_suspend); /* The controller won't actually turn off the RD bit until * it has had a chance to send a low-speed EOP sequence, @@ -96,7 +97,6 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, * slightly longer for good luck. */ udelay(4); } - clear_bit(port, &uhci->resuming_ports); } /* Wait for the UHCI controller in HP's iLO2 server management chip. @@ -265,6 +265,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, wPortChange |= USB_PORT_STAT_C_SUSPEND; lstatus |= 1; } + if (test_bit(port, &uhci->suspended_ports)) + lstatus |= 2; if (test_bit(port, &uhci->resuming_ports)) lstatus |= 4; @@ -307,6 +309,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, switch (wValue) { case USB_PORT_FEAT_SUSPEND: + set_bit(port, &uhci->suspended_ports); SET_RH_PORTSTAT(USBPORTSC_SUSP); OK(0); case USB_PORT_FEAT_RESET: @@ -340,11 +343,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, CLR_RH_PORTSTAT(USBPORTSC_PEC); OK(0); case USB_PORT_FEAT_SUSPEND: - if (!(inw(port_addr) & USBPORTSC_SUSP)) { - - /* Make certain the port isn't suspended */ - uhci_finish_suspend(uhci, port, port_addr); - } else if (!test_and_set_bit(port, + if (test_bit(port, &uhci->suspended_ports) && + !test_and_set_bit(port, &uhci->resuming_ports)) { SET_RH_PORTSTAT(USBPORTSC_RD); diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 5f44354c4..782398045 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -13,9 +13,13 @@ * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) - * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu + * (C) Copyright 2004 Alan Stern, stern@rowland.harvard.edu */ +static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb); +static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb); +static void uhci_remove_pending_urbps(struct uhci_hcd *uhci); +static void uhci_free_pending_qhs(struct uhci_hcd *uhci); static void uhci_free_pending_tds(struct uhci_hcd *uhci); /* @@ -26,7 +30,7 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci); * games with the FSBR code to make sure we get the correct order in all * the cases. I don't think it's worth the effort */ -static void uhci_set_next_interrupt(struct uhci_hcd *uhci) +static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci) { if (uhci->is_stopped) mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); @@ -38,6 +42,12 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC); } +static inline void uhci_moveto_complete(struct uhci_hcd *uhci, + struct urb_priv *urbp) +{ + list_move_tail(&urbp->urb_list, &uhci->complete_list); +} + static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) { dma_addr_t dma_handle; @@ -48,6 +58,10 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) return NULL; td->dma_handle = dma_handle; + + td->link = UHCI_PTR_TERM; + td->buffer = 0; + td->frame = -1; INIT_LIST_HEAD(&td->list); @@ -57,18 +71,6 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) return td; } -static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) -{ - if (!list_empty(&td->list)) - dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); - if (!list_empty(&td->remove_list)) - dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td); - if (!list_empty(&td->fl_list)) - dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); - - dma_pool_free(uhci->td_pool, td, td->dma_handle); -} - static inline void uhci_fill_td(struct uhci_td *td, u32 status, u32 token, u32 buffer) { @@ -80,8 +82,7 @@ static inline void uhci_fill_td(struct uhci_td *td, u32 status, /* * We insert Isochronous URBs directly into the frame list at the beginning */ -static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, - struct uhci_td *td, unsigned framenum) +static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum) { framenum &= (UHCI_NUMFRAMES - 1); @@ -107,7 +108,7 @@ static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, } } -static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, +static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td) { /* If it's not inserted, don't remove it */ @@ -138,21 +139,48 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, td->frame = -1; } -/* - * Remove all the TDs for an Isochronous URB from the frame list - */ -static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) +static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) { struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; struct uhci_td *td; list_for_each_entry(td, &urbp->td_list, list) - uhci_remove_td_from_frame_list(uhci, td); + uhci_remove_td_frame_list(uhci, td); wmb(); } -static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, - struct usb_device *udev, struct usb_host_endpoint *hep) +/* + * Inserts a td list into qh. + */ +static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct urb *urb, __le32 breadth) +{ + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + struct uhci_td *td; + __le32 *plink; + + /* Ordering isn't important here yet since the QH hasn't been */ + /* inserted into the schedule yet */ + plink = &qh->element; + list_for_each_entry(td, &urbp->td_list, list) { + *plink = cpu_to_le32(td->dma_handle) | breadth; + plink = &td->link; + } + *plink = UHCI_PTR_TERM; +} + +static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) +{ + if (!list_empty(&td->list)) + dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); + if (!list_empty(&td->remove_list)) + dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td); + if (!list_empty(&td->fl_list)) + dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); + + dma_pool_free(uhci->td_pool, td, td->dma_handle); +} + +static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci) { dma_addr_t dma_handle; struct uhci_qh *qh; @@ -166,217 +194,256 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, qh->element = UHCI_PTR_TERM; qh->link = UHCI_PTR_TERM; - INIT_LIST_HEAD(&qh->queue); - INIT_LIST_HEAD(&qh->node); + qh->urbp = NULL; + + INIT_LIST_HEAD(&qh->list); + INIT_LIST_HEAD(&qh->remove_list); - if (udev) { /* Normal QH */ - qh->dummy_td = uhci_alloc_td(uhci); - if (!qh->dummy_td) { - dma_pool_free(uhci->qh_pool, qh, dma_handle); - return NULL; - } - qh->state = QH_STATE_IDLE; - qh->hep = hep; - qh->udev = udev; - hep->hcpriv = qh; - - } else { /* Skeleton QH */ - qh->state = QH_STATE_ACTIVE; - qh->udev = NULL; - } return qh; } static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) { - WARN_ON(qh->state != QH_STATE_IDLE && qh->udev); - if (!list_empty(&qh->queue)) + if (!list_empty(&qh->list)) dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh); + if (!list_empty(&qh->remove_list)) + dev_warn(uhci_dev(uhci), "qh %p still in remove_list!\n", qh); - list_del(&qh->node); - if (qh->udev) { - qh->hep->hcpriv = NULL; - uhci_free_td(uhci, qh->dummy_td); - } dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); } /* - * When the currently executing URB is dequeued, save its current toggle value + * Append this urb's qh after the last qh in skelqh->list + * + * Note that urb_priv.queue_list doesn't have a separate queue head; + * it's a ring with every element "live". */ -static void uhci_save_toggle(struct uhci_qh *qh, struct urb *urb) +static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct urb *urb) { - struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; - struct uhci_td *td; + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + struct urb_priv *turbp; + struct uhci_qh *lqh; - /* If the QH element pointer is UHCI_PTR_TERM then then currently - * executing URB has already been unlinked, so this one isn't it. */ - if (qh_element(qh) == UHCI_PTR_TERM || - qh->queue.next != &urbp->node) - return; - qh->element = UHCI_PTR_TERM; + /* Grab the last QH */ + lqh = list_entry(skelqh->list.prev, struct uhci_qh, list); - /* Only bulk and interrupt pipes have to worry about toggles */ - if (!(usb_pipetype(urb->pipe) == PIPE_BULK || - usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) - return; + /* Point to the next skelqh */ + urbp->qh->link = lqh->link; + wmb(); /* Ordering is important */ - /* Find the first active TD; that's the device's toggle state */ - list_for_each_entry(td, &urbp->td_list, list) { - if (td_status(td) & TD_CTRL_ACTIVE) { - qh->needs_fixup = 1; - qh->initial_toggle = uhci_toggle(td_token(td)); - return; - } + /* + * Patch QHs for previous endpoint's queued URBs? HC goes + * here next, not to the next skelqh it now points to. + * + * lqh --> td ... --> qh ... --> td --> qh ... --> td + * | | | + * v v v + * +<----------------+-----------------+ + * v + * newqh --> td ... --> td + * | + * v + * ... + * + * The HC could see (and use!) any of these as we write them. + */ + lqh->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH; + if (lqh->urbp) { + list_for_each_entry(turbp, &lqh->urbp->queue_list, queue_list) + turbp->qh->link = lqh->link; } - WARN_ON(1); + list_add_tail(&urbp->qh->list, &skelqh->list); } /* - * Fix up the data toggles for URBs in a queue, when one of them - * terminates early (short transfer, error, or dequeued). + * Start removal of QH from schedule; it finishes next frame. + * TDs should be unlinked before this is called. */ -static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) +static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) { - struct urb_priv *urbp = NULL; - struct uhci_td *td; - unsigned int toggle = qh->initial_toggle; - unsigned int pipe; - - /* Fixups for a short transfer start with the second URB in the - * queue (the short URB is the first). */ - if (skip_first) - urbp = list_entry(qh->queue.next, struct urb_priv, node); - - /* When starting with the first URB, if the QH element pointer is - * still valid then we know the URB's toggles are okay. */ - else if (qh_element(qh) != UHCI_PTR_TERM) - toggle = 2; - - /* Fix up the toggle for the URBs in the queue. Normally this - * loop won't run more than once: When an error or short transfer - * occurs, the queue usually gets emptied. */ - urbp = list_prepare_entry(urbp, &qh->queue, node); - list_for_each_entry_continue(urbp, &qh->queue, node) { - - /* If the first TD has the right toggle value, we don't - * need to change any toggles in this URB */ - td = list_entry(urbp->td_list.next, struct uhci_td, list); - if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) { - td = list_entry(urbp->td_list.prev, struct uhci_td, - list); - toggle = uhci_toggle(td_token(td)) ^ 1; - - /* Otherwise all the toggles in the URB have to be switched */ - } else { - list_for_each_entry(td, &urbp->td_list, list) { - td->token ^= __constant_cpu_to_le32( - TD_TOKEN_TOGGLE); - toggle ^= 1; - } + struct uhci_qh *pqh; + __le32 newlink; + + if (!qh) + return; + + /* + * Only go through the hoops if it's actually linked in + */ + if (!list_empty(&qh->list)) { + + /* If our queue is nonempty, make the next URB the head */ + if (!list_empty(&qh->urbp->queue_list)) { + struct urb_priv *nurbp; + + nurbp = list_entry(qh->urbp->queue_list.next, + struct urb_priv, queue_list); + nurbp->queued = 0; + list_add(&nurbp->qh->list, &qh->list); + newlink = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH; + } else + newlink = qh->link; + + /* Fix up the previous QH's queue to link to either + * the new head of this queue or the start of the + * next endpoint's queue. */ + pqh = list_entry(qh->list.prev, struct uhci_qh, list); + pqh->link = newlink; + if (pqh->urbp) { + struct urb_priv *turbp; + + list_for_each_entry(turbp, &pqh->urbp->queue_list, + queue_list) + turbp->qh->link = newlink; } + wmb(); + + /* Leave qh->link in case the HC is on the QH now, it will */ + /* continue the rest of the schedule */ + qh->element = UHCI_PTR_TERM; + + list_del_init(&qh->list); } - wmb(); - pipe = list_entry(qh->queue.next, struct urb_priv, node)->urb->pipe; - usb_settoggle(qh->udev, usb_pipeendpoint(pipe), - usb_pipeout(pipe), toggle); - qh->needs_fixup = 0; + list_del_init(&qh->urbp->queue_list); + qh->urbp = NULL; + + uhci_get_current_frame_number(uhci); + if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age) { + uhci_free_pending_qhs(uhci); + uhci->qh_remove_age = uhci->frame_number; + } + + /* Check to see if the remove list is empty. Set the IOC bit */ + /* to force an interrupt so we can remove the QH */ + if (list_empty(&uhci->qh_remove_list)) + uhci_set_next_interrupt(uhci); + + list_add(&qh->remove_list, &uhci->qh_remove_list); } -/* - * Put a QH on the schedule in both hardware and software - */ -static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) +static int uhci_fixup_toggle(struct urb *urb, unsigned int toggle) { - struct uhci_qh *pqh; - - WARN_ON(list_empty(&qh->queue)); + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + struct uhci_td *td; - /* Set the element pointer if it isn't set already. - * This isn't needed for Isochronous queues, but it doesn't hurt. */ - if (qh_element(qh) == UHCI_PTR_TERM) { - struct urb_priv *urbp = list_entry(qh->queue.next, - struct urb_priv, node); - struct uhci_td *td = list_entry(urbp->td_list.next, - struct uhci_td, list); + list_for_each_entry(td, &urbp->td_list, list) { + if (toggle) + td->token |= cpu_to_le32(TD_TOKEN_TOGGLE); + else + td->token &= ~cpu_to_le32(TD_TOKEN_TOGGLE); - qh->element = cpu_to_le32(td->dma_handle); + toggle ^= 1; } - if (qh->state == QH_STATE_ACTIVE) - return; - qh->state = QH_STATE_ACTIVE; - - /* Move the QH from its old list to the end of the appropriate - * skeleton's list */ - if (qh == uhci->next_qh) - uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, - node); - list_move_tail(&qh->node, &qh->skel->node); - - /* Link it into the schedule */ - pqh = list_entry(qh->node.prev, struct uhci_qh, node); - qh->link = pqh->link; - wmb(); - pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle); + return toggle; } -/* - * Take a QH off the hardware schedule - */ -static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) +/* This function will append one URB's QH to another URB's QH. This is for */ +/* queuing interrupt, control or bulk transfers */ +static void uhci_append_queued_urb(struct uhci_hcd *uhci, struct urb *eurb, struct urb *urb) { - struct uhci_qh *pqh; + struct urb_priv *eurbp, *urbp, *furbp, *lurbp; + struct uhci_td *lltd; - if (qh->state == QH_STATE_UNLINKING) - return; - WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev); - qh->state = QH_STATE_UNLINKING; + eurbp = eurb->hcpriv; + urbp = urb->hcpriv; - /* Unlink the QH from the schedule and record when we did it */ - pqh = list_entry(qh->node.prev, struct uhci_qh, node); - pqh->link = qh->link; - mb(); + /* Find the first URB in the queue */ + furbp = eurbp; + if (eurbp->queued) { + list_for_each_entry(furbp, &eurbp->queue_list, queue_list) + if (!furbp->queued) + break; + } - uhci_get_current_frame_number(uhci); - qh->unlink_frame = uhci->frame_number; + lurbp = list_entry(furbp->queue_list.prev, struct urb_priv, queue_list); - /* Force an interrupt so we know when the QH is fully unlinked */ - if (list_empty(&uhci->skel_unlink_qh->node)) - uhci_set_next_interrupt(uhci); + lltd = list_entry(lurbp->td_list.prev, struct uhci_td, list); + + /* Control transfers always start with toggle 0 */ + if (!usb_pipecontrol(urb->pipe)) + usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe), + uhci_fixup_toggle(urb, + uhci_toggle(td_token(lltd)) ^ 1)); - /* Move the QH from its old list to the end of the unlinking list */ - if (qh == uhci->next_qh) - uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, - node); - list_move_tail(&qh->node, &uhci->skel_unlink_qh->node); + /* All qhs in the queue need to link to the next queue */ + urbp->qh->link = eurbp->qh->link; + + wmb(); /* Make sure we flush everything */ + + lltd->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH; + + list_add_tail(&urbp->queue_list, &furbp->queue_list); + + urbp->queued = 1; } -/* - * When we and the controller are through with a QH, it becomes IDLE. - * This happens when a QH has been off the schedule (on the unlinking - * list) for more than one frame, or when an error occurs while adding - * the first URB onto a new QH. - */ -static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh) +static void uhci_delete_queued_urb(struct uhci_hcd *uhci, struct urb *urb) { - WARN_ON(qh->state == QH_STATE_ACTIVE); + struct urb_priv *urbp, *nurbp, *purbp, *turbp; + struct uhci_td *pltd; + unsigned int toggle; - if (qh == uhci->next_qh) - uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, - node); - list_move(&qh->node, &uhci->idle_qh_list); - qh->state = QH_STATE_IDLE; + urbp = urb->hcpriv; + + if (list_empty(&urbp->queue_list)) + return; - /* If anyone is waiting for a QH to become idle, wake them up */ - if (uhci->num_waiting) - wake_up_all(&uhci->waitqh); + nurbp = list_entry(urbp->queue_list.next, struct urb_priv, queue_list); + + /* + * Fix up the toggle for the following URBs in the queue. + * Only needed for bulk and interrupt: control and isochronous + * endpoints don't propagate toggles between messages. + */ + if (usb_pipebulk(urb->pipe) || usb_pipeint(urb->pipe)) { + if (!urbp->queued) + /* We just set the toggle in uhci_unlink_generic */ + toggle = usb_gettoggle(urb->dev, + usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe)); + else { + /* If we're in the middle of the queue, grab the */ + /* toggle from the TD previous to us */ + purbp = list_entry(urbp->queue_list.prev, + struct urb_priv, queue_list); + pltd = list_entry(purbp->td_list.prev, + struct uhci_td, list); + toggle = uhci_toggle(td_token(pltd)) ^ 1; + } + + list_for_each_entry(turbp, &urbp->queue_list, queue_list) { + if (!turbp->queued) + break; + toggle = uhci_fixup_toggle(turbp->urb, toggle); + } + + usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe), toggle); + } + + if (urbp->queued) { + /* We're somewhere in the middle (or end). The case where + * we're at the head is handled in uhci_remove_qh(). */ + purbp = list_entry(urbp->queue_list.prev, struct urb_priv, + queue_list); + + pltd = list_entry(purbp->td_list.prev, struct uhci_td, list); + if (nurbp->queued) + pltd->link = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH; + else + /* The next URB happens to be the beginning, so */ + /* we're the last, end the chain */ + pltd->link = UHCI_PTR_TERM; + } + + /* urbp->queue_list is handled in uhci_remove_qh() */ } -static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, - struct urb *urb) +static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *urb) { struct urb_priv *urbp; @@ -386,11 +453,16 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, memset((void *)urbp, 0, sizeof(*urbp)); + urbp->fsbrtime = jiffies; urbp->urb = urb; - urb->hcpriv = urbp; - INIT_LIST_HEAD(&urbp->node); INIT_LIST_HEAD(&urbp->td_list); + INIT_LIST_HEAD(&urbp->queue_list); + INIT_LIST_HEAD(&urbp->urb_list); + + list_add_tail(&urbp->urb_list, &uhci->urb_list); + + urb->hcpriv = urbp; return urbp; } @@ -410,14 +482,18 @@ static void uhci_remove_td_from_urb(struct uhci_td *td) list_del_init(&td->list); } -static void uhci_free_urb_priv(struct uhci_hcd *uhci, - struct urb_priv *urbp) +static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) { struct uhci_td *td, *tmp; + struct urb_priv *urbp; + + urbp = (struct urb_priv *)urb->hcpriv; + if (!urbp) + return; - if (!list_empty(&urbp->node)) - dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", - urbp->urb); + if (!list_empty(&urbp->urb_list)) + dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list " + "or uhci->remove_list!\n", urb); uhci_get_current_frame_number(uhci); if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) { @@ -426,7 +502,7 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, } /* Check to see if the remove list is empty. Set the IOC bit */ - /* to force an interrupt so we can remove the TDs. */ + /* to force an interrupt so we can remove the TDs*/ if (list_empty(&uhci->td_remove_list)) uhci_set_next_interrupt(uhci); @@ -435,7 +511,7 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, list_add(&td->remove_list, &uhci->td_remove_list); } - urbp->urb->hcpriv = NULL; + urb->hcpriv = NULL; kmem_cache_free(uhci_up_cachep, urbp); } @@ -494,33 +570,34 @@ static int uhci_map_status(int status, int dir_out) /* * Control transfers */ -static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, - struct uhci_qh *qh) +static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb) { + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; struct uhci_td *td; + struct uhci_qh *qh, *skelqh; unsigned long destination, status; - int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); + int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); int len = urb->transfer_buffer_length; dma_addr_t data = urb->transfer_dma; - __le32 *plink; /* The "pipe" thing contains the destination in bits 8--18 */ destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; - /* 3 errors, dummy TD remains inactive */ - status = uhci_maxerr(3); + /* 3 errors */ + status = TD_CTRL_ACTIVE | uhci_maxerr(3); if (urb->dev->speed == USB_SPEED_LOW) status |= TD_CTRL_LS; /* * Build the TD for the control request setup packet */ - td = qh->dummy_td; + td = uhci_alloc_td(uhci); + if (!td) + return -ENOMEM; + uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(8), - urb->setup_dma); - plink = &td->link; - status |= TD_CTRL_ACTIVE; + urb->setup_dma); /* * If direction is "send", change the packet ID from SETUP (0x2D) @@ -538,20 +615,21 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, * Build the DATA TDs */ while (len > 0) { - int pktsze = min(len, maxsze); + int pktsze = len; + + if (pktsze > maxsze) + pktsze = maxsze; td = uhci_alloc_td(uhci); if (!td) - goto nomem; - *plink = cpu_to_le32(td->dma_handle); + return -ENOMEM; /* Alternate Data0/1 (start with Data1) */ destination ^= TD_TOKEN_TOGGLE; uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(pktsze), - data); - plink = &td->link; + data); data += pktsze; len -= pktsze; @@ -562,8 +640,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, */ td = uhci_alloc_td(uhci); if (!td) - goto nomem; - *plink = cpu_to_le32(td->dma_handle); + return -ENOMEM; /* * It's IN if the pipe is an output pipe or we're not expecting @@ -581,21 +658,16 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status | TD_CTRL_IOC, - destination | uhci_explen(0), 0); - plink = &td->link; + destination | uhci_explen(0), 0); - /* - * Build the new dummy TD and activate the old one - */ - td = uhci_alloc_td(uhci); - if (!td) - goto nomem; - *plink = cpu_to_le32(td->dma_handle); + qh = uhci_alloc_qh(uhci); + if (!qh) + return -ENOMEM; - uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); - wmb(); - qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); - qh->dummy_td = td; + urbp->qh = qh; + qh->urbp = urbp; + + uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH); /* Low-speed transfers get a different queue, and won't hog the bus. * Also, some devices enumerate better without FSBR; the easiest way @@ -603,17 +675,18 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, * isn't in the CONFIGURED state. */ if (urb->dev->speed == USB_SPEED_LOW || urb->dev->state != USB_STATE_CONFIGURED) - qh->skel = uhci->skel_ls_control_qh; + skelqh = uhci->skel_ls_control_qh; else { - qh->skel = uhci->skel_fs_control_qh; + skelqh = uhci->skel_fs_control_qh; uhci_inc_fsbr(uhci, urb); } - return 0; -nomem: - /* Remove the dummy TD from the td_list so it doesn't get freed */ - uhci_remove_td_from_urb(qh->dummy_td); - return -ENOMEM; + if (eurb) + uhci_append_queued_urb(uhci, eurb, urb); + else + uhci_insert_qh(uhci, skelqh, urb); + + return -EINPROGRESS; } /* @@ -630,7 +703,7 @@ static int usb_control_retrigger_status(struct uhci_hcd *uhci, struct urb *urb) struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; struct uhci_td *td; - urbp->short_transfer = 1; + urbp->short_control_packet = 1; td = list_entry(urbp->td_list.prev, struct uhci_td, list); urbp->qh->element = cpu_to_le32(td->dma_handle); @@ -647,14 +720,16 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb) unsigned int status; int ret = 0; + if (list_empty(&urbp->td_list)) + return -EINVAL; + head = &urbp->td_list; - if (urbp->short_transfer) { + + if (urbp->short_control_packet) { tmp = head->prev; goto status_stage; } - urb->actual_length = 0; - tmp = head->next; td = list_entry(tmp, struct uhci_td, list); @@ -667,6 +742,8 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb) if (status) goto td_error; + urb->actual_length = 0; + /* The rest of the TDs (but the last) are data */ tmp = tmp->next; while (tmp != head && tmp->next != head) { @@ -693,7 +770,10 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb) goto err; } - return usb_control_retrigger_status(uhci, urb); + if (uhci_packetid(td_token(td)) == USB_PID_IN) + return usb_control_retrigger_status(uhci, urb); + else + return 0; } } @@ -734,40 +814,34 @@ err: if (errbuf) { /* Print the chain for debugging purposes */ uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0); + lprintk(errbuf); } } - /* Note that the queue has stopped */ - urbp->qh->element = UHCI_PTR_TERM; - urbp->qh->is_stopped = 1; return ret; } /* * Common submit for bulk and interrupt */ -static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, - struct uhci_qh *qh) +static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb, struct uhci_qh *skelqh) { struct uhci_td *td; + struct uhci_qh *qh; unsigned long destination, status; - int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); + int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); int len = urb->transfer_buffer_length; + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; dma_addr_t data = urb->transfer_dma; - __le32 *plink; - unsigned int toggle; if (len < 0) return -EINVAL; /* The "pipe" thing contains the destination in bits 8--18 */ destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); - toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe)); - /* 3 errors, dummy TD remains inactive */ - status = uhci_maxerr(3); + status = uhci_maxerr(3) | TD_CTRL_ACTIVE; if (urb->dev->speed == USB_SPEED_LOW) status |= TD_CTRL_LS; if (usb_pipein(urb->pipe)) @@ -776,34 +850,30 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, /* * Build the DATA TDs */ - plink = NULL; - td = qh->dummy_td; do { /* Allow zero length packets */ int pktsze = maxsze; - if (len <= pktsze) { /* The last packet */ + if (pktsze >= len) { pktsze = len; if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) status &= ~TD_CTRL_SPD; } - if (plink) { - td = uhci_alloc_td(uhci); - if (!td) - goto nomem; - *plink = cpu_to_le32(td->dma_handle); - } + td = uhci_alloc_td(uhci); + if (!td) + return -ENOMEM; + uhci_add_td_to_urb(urb, td); - uhci_fill_td(td, status, - destination | uhci_explen(pktsze) | - (toggle << TD_TOKEN_TOGGLE_SHIFT), - data); - plink = &td->link; - status |= TD_CTRL_ACTIVE; + uhci_fill_td(td, status, destination | uhci_explen(pktsze) | + (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), + data); data += pktsze; len -= maxsze; - toggle ^= 1; + + usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe)); } while (len > 0); /* @@ -813,22 +883,20 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, * however, if transfer_length == 0, the zero packet was already * prepared above. */ - if ((urb->transfer_flags & URB_ZERO_PACKET) && - usb_pipeout(urb->pipe) && len == 0 && - urb->transfer_buffer_length > 0) { + if (usb_pipeout(urb->pipe) && (urb->transfer_flags & URB_ZERO_PACKET) && + !len && urb->transfer_buffer_length) { td = uhci_alloc_td(uhci); if (!td) - goto nomem; - *plink = cpu_to_le32(td->dma_handle); + return -ENOMEM; uhci_add_td_to_urb(urb, td); - uhci_fill_td(td, status, - destination | uhci_explen(0) | - (toggle << TD_TOKEN_TOGGLE_SHIFT), - data); - plink = &td->link; + uhci_fill_td(td, status, destination | uhci_explen(0) | + (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), + data); - toggle ^= 1; + usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), + usb_pipeout(urb->pipe)); } /* Set the interrupt-on-completion flag on the last packet. @@ -837,29 +905,24 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, * fast side but not enough to justify delaying an interrupt * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT * flag setting. */ - td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); + td->status |= cpu_to_le32(TD_CTRL_IOC); - /* - * Build the new dummy TD and activate the old one - */ - td = uhci_alloc_td(uhci); - if (!td) - goto nomem; - *plink = cpu_to_le32(td->dma_handle); + qh = uhci_alloc_qh(uhci); + if (!qh) + return -ENOMEM; - uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); - wmb(); - qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); - qh->dummy_td = td; + urbp->qh = qh; + qh->urbp = urbp; - usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe), toggle); - return 0; + /* Always breadth first */ + uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH); + + if (eurb) + uhci_append_queued_urb(uhci, eurb, urb); + else + uhci_insert_qh(uhci, skelqh, urb); -nomem: - /* Remove the dummy TD from the td_list so it doesn't get freed */ - uhci_remove_td_from_urb(qh->dummy_td); - return -ENOMEM; + return -EINPROGRESS; } /* @@ -891,29 +954,8 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) if (urb->transfer_flags & URB_SHORT_NOT_OK) { ret = -EREMOTEIO; goto err; - } - - /* - * This URB stopped short of its end. We have to - * fix up the toggles of the following URBs on the - * queue and restart the queue. But only if this - * TD isn't the last one in the URB. - * - * Do this only the first time we encounter the - * short URB. - */ - if (!urbp->short_transfer && - &td->list != urbp->td_list.prev) { - urbp->short_transfer = 1; - urbp->qh->initial_toggle = - uhci_toggle(td_token(td)) ^ 1; - uhci_fixup_toggles(urbp->qh, 1); - - td = list_entry(urbp->td_list.prev, - struct uhci_td, list); - urbp->qh->element = td->link; - } - break; + } else + return 0; } } @@ -922,30 +964,31 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) td_error: ret = uhci_map_status(status, uhci_packetout(td_token(td))); +err: + /* + * Enable this chunk of code if you want to see some more debugging. + * But be careful, it has the tendancy to starve out khubd and prevent + * disconnects from happening successfully if you have a slow debug + * log interface (like a serial console. + */ +#if 0 if ((debug == 1 && ret != -EPIPE) || debug > 1) { /* Some debugging code */ dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n", __FUNCTION__, status); - if (debug > 1 && errbuf) { + if (errbuf) { /* Print the chain for debugging purposes */ uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0); + lprintk(errbuf); } } -err: - - /* Note that the queue has stopped and save the next toggle value */ - urbp->qh->element = UHCI_PTR_TERM; - urbp->qh->is_stopped = 1; - urbp->qh->needs_fixup = 1; - urbp->qh->initial_toggle = uhci_toggle(td_token(td)) ^ - (ret == -EREMOTEIO); +#endif return ret; } -static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, - struct uhci_qh *qh) +static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb) { int ret; @@ -953,60 +996,95 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, if (urb->dev->speed == USB_SPEED_LOW) return -EINVAL; - qh->skel = uhci->skel_bulk_qh; - ret = uhci_submit_common(uhci, urb, qh); - if (ret == 0) + ret = uhci_submit_common(uhci, urb, eurb, uhci->skel_bulk_qh); + if (ret == -EINPROGRESS) uhci_inc_fsbr(uhci, urb); + return ret; } -static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, - struct uhci_qh *qh) +static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb) { - /* USB 1.1 interrupt transfers only involve one packet per interval. - * Drivers can submit URBs of any length, but longer ones will need - * multiple intervals to complete. + /* USB 1.1 interrupt transfers only involve one packet per interval; + * that's the uhci_submit_common() "breadth first" policy. Drivers + * can submit urbs of any length, but longer ones might need many + * intervals to complete. */ - qh->skel = uhci->skelqh[__interval_to_skel(urb->interval)]; - return uhci_submit_common(uhci, urb, qh); + return uhci_submit_common(uhci, urb, eurb, uhci->skelqh[__interval_to_skel(urb->interval)]); } /* * Isochronous transfers */ -static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, - struct uhci_qh *qh) +static int isochronous_find_limits(struct uhci_hcd *uhci, struct urb *urb, unsigned int *start, unsigned int *end) { - struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */ - int i, frame; - unsigned long destination, status; - struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; + struct urb *last_urb = NULL; + struct urb_priv *up; + int ret = 0; + + list_for_each_entry(up, &uhci->urb_list, urb_list) { + struct urb *u = up->urb; + + /* look for pending URBs with identical pipe handle */ + if ((urb->pipe == u->pipe) && (urb->dev == u->dev) && + (u->status == -EINPROGRESS) && (u != urb)) { + if (!last_urb) + *start = u->start_frame; + last_urb = u; + } + } + + if (last_urb) { + *end = (last_urb->start_frame + last_urb->number_of_packets * + last_urb->interval) & (UHCI_NUMFRAMES-1); + ret = 0; + } else + ret = -1; /* no previous urb found */ + + return ret; +} + +static int isochronous_find_start(struct uhci_hcd *uhci, struct urb *urb) +{ + int limits; + unsigned int start = 0, end = 0; if (urb->number_of_packets > 900) /* 900? Why? */ return -EFBIG; - status = TD_CTRL_ACTIVE | TD_CTRL_IOS; - destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); + limits = isochronous_find_limits(uhci, urb, &start, &end); - /* Figure out the starting frame number */ if (urb->transfer_flags & URB_ISO_ASAP) { - if (list_empty(&qh->queue)) { + if (limits) { uhci_get_current_frame_number(uhci); - urb->start_frame = (uhci->frame_number + 10); - - } else { /* Go right after the last one */ - struct urb *last_urb; - - last_urb = list_entry(qh->queue.prev, - struct urb_priv, node)->urb; - urb->start_frame = (last_urb->start_frame + - last_urb->number_of_packets * - last_urb->interval); - } + urb->start_frame = (uhci->frame_number + 10) + & (UHCI_NUMFRAMES - 1); + } else + urb->start_frame = end; } else { + urb->start_frame &= (UHCI_NUMFRAMES - 1); /* FIXME: Sanity check */ } - urb->start_frame &= (UHCI_NUMFRAMES - 1); + + return 0; +} + +/* + * Isochronous transfers + */ +static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) +{ + struct uhci_td *td; + int i, ret, frame; + int status, destination; + struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; + + status = TD_CTRL_ACTIVE | TD_CTRL_IOS; + destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); + + ret = isochronous_find_start(uhci, urb); + if (ret) + return ret; for (i = 0; i < urb->number_of_packets; i++) { td = uhci_alloc_td(uhci); @@ -1014,25 +1092,20 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, return -ENOMEM; uhci_add_td_to_urb(urb, td); - uhci_fill_td(td, status, destination | - uhci_explen(urb->iso_frame_desc[i].length), - urb->transfer_dma + - urb->iso_frame_desc[i].offset); - } + uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length), + urb->transfer_dma + urb->iso_frame_desc[i].offset); - /* Set the interrupt-on-completion flag on the last packet. */ - td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); - - qh->skel = uhci->skel_iso_qh; + if (i + 1 >= urb->number_of_packets) + td->status |= cpu_to_le32(TD_CTRL_IOC); + } - /* Add the TDs to the frame list */ frame = urb->start_frame; list_for_each_entry(td, &urbp->td_list, list) { - uhci_insert_td_in_frame_list(uhci, td, frame); + uhci_insert_td_frame_list(uhci, td, frame); frame += urb->interval; } - return 0; + return -EINPROGRESS; } static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) @@ -1066,67 +1139,80 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) i++; } + unlink_isochronous_tds(uhci, urb); return ret; } +static struct urb *uhci_find_urb_ep(struct uhci_hcd *uhci, struct urb *urb) +{ + struct urb_priv *up; + + /* We don't match Isoc transfers since they are special */ + if (usb_pipeisoc(urb->pipe)) + return NULL; + + list_for_each_entry(up, &uhci->urb_list, urb_list) { + struct urb *u = up->urb; + + if (u->dev == urb->dev && u->status == -EINPROGRESS) { + /* For control, ignore the direction */ + if (usb_pipecontrol(urb->pipe) && + (u->pipe & ~USB_DIR_IN) == (urb->pipe & ~USB_DIR_IN)) + return u; + else if (u->pipe == urb->pipe) + return u; + } + } + + return NULL; +} + static int uhci_urb_enqueue(struct usb_hcd *hcd, - struct usb_host_endpoint *hep, + struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags) { int ret; struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned long flags; - struct urb_priv *urbp; - struct uhci_qh *qh; + struct urb *eurb; int bustime; spin_lock_irqsave(&uhci->lock, flags); ret = urb->status; if (ret != -EINPROGRESS) /* URB already unlinked! */ - goto done; + goto out; - ret = -ENOMEM; - urbp = uhci_alloc_urb_priv(uhci, urb); - if (!urbp) - goto done; + eurb = uhci_find_urb_ep(uhci, urb); - if (hep->hcpriv) - qh = (struct uhci_qh *) hep->hcpriv; - else { - qh = uhci_alloc_qh(uhci, urb->dev, hep); - if (!qh) - goto err_no_qh; + if (!uhci_alloc_urb_priv(uhci, urb)) { + ret = -ENOMEM; + goto out; } - urbp->qh = qh; switch (usb_pipetype(urb->pipe)) { case PIPE_CONTROL: - ret = uhci_submit_control(uhci, urb, qh); - break; - case PIPE_BULK: - ret = uhci_submit_bulk(uhci, urb, qh); + ret = uhci_submit_control(uhci, urb, eurb); break; case PIPE_INTERRUPT: - if (list_empty(&qh->queue)) { + if (!eurb) { bustime = usb_check_bandwidth(urb->dev, urb); if (bustime < 0) ret = bustime; else { - ret = uhci_submit_interrupt(uhci, urb, qh); - if (ret == 0) + ret = uhci_submit_interrupt(uhci, urb, eurb); + if (ret == -EINPROGRESS) usb_claim_bandwidth(urb->dev, urb, bustime, 0); } } else { /* inherit from parent */ - struct urb_priv *eurbp; - - eurbp = list_entry(qh->queue.prev, struct urb_priv, - node); - urb->bandwidth = eurbp->urb->bandwidth; - ret = uhci_submit_interrupt(uhci, urb, qh); + urb->bandwidth = eurb->bandwidth; + ret = uhci_submit_interrupt(uhci, urb, eurb); } break; + case PIPE_BULK: + ret = uhci_submit_bulk(uhci, urb, eurb); + break; case PIPE_ISOCHRONOUS: bustime = usb_check_bandwidth(urb->dev, urb); if (bustime < 0) { @@ -1134,208 +1220,221 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, break; } - ret = uhci_submit_isochronous(uhci, urb, qh); - if (ret == 0) + ret = uhci_submit_isochronous(uhci, urb); + if (ret == -EINPROGRESS) usb_claim_bandwidth(urb->dev, urb, bustime, 1); break; } - if (ret != 0) - goto err_submit_failed; - - /* Add this URB to the QH */ - urbp->qh = qh; - list_add_tail(&urbp->node, &qh->queue); - /* If the new URB is the first and only one on this QH then either - * the QH is new and idle or else it's unlinked and waiting to - * become idle, so we can activate it right away. */ - if (qh->queue.next == &urbp->node) - uhci_activate_qh(uhci, qh); - goto done; + if (ret != -EINPROGRESS) { + /* Submit failed, so delete it from the urb_list */ + struct urb_priv *urbp = urb->hcpriv; -err_submit_failed: - if (qh->state == QH_STATE_IDLE) - uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */ + list_del_init(&urbp->urb_list); + uhci_destroy_urb_priv(uhci, urb); + } else + ret = 0; -err_no_qh: - uhci_free_urb_priv(uhci, urbp); - -done: +out: spin_unlock_irqrestore(&uhci->lock, flags); return ret; } -static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) +/* + * Return the result of a transfer + */ +static void uhci_transfer_result(struct uhci_hcd *uhci, struct urb *urb) { - struct uhci_hcd *uhci = hcd_to_uhci(hcd); - unsigned long flags; + int ret = -EINPROGRESS; struct urb_priv *urbp; - spin_lock_irqsave(&uhci->lock, flags); - urbp = urb->hcpriv; - if (!urbp) /* URB was never linked! */ - goto done; - - /* Remove Isochronous TDs from the frame list ASAP */ - if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) - uhci_unlink_isochronous_tds(uhci, urb); - uhci_unlink_qh(uhci, urbp->qh); - -done: - spin_unlock_irqrestore(&uhci->lock, flags); - return 0; -} + spin_lock(&urb->lock); -/* - * Finish unlinking an URB and give it back - */ -static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct urb *urb, struct pt_regs *regs) -__releases(uhci->lock) -__acquires(uhci->lock) -{ - struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; + urbp = (struct urb_priv *)urb->hcpriv; - /* Isochronous TDs get unlinked directly from the frame list */ - if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) - uhci_unlink_isochronous_tds(uhci, urb); - - /* If the URB isn't first on its queue, adjust the link pointer - * of the last TD in the previous URB. */ - else if (qh->queue.next != &urbp->node) { - struct urb_priv *purbp; - struct uhci_td *ptd, *ltd; - - purbp = list_entry(urbp->node.prev, struct urb_priv, node); - ptd = list_entry(purbp->td_list.prev, struct uhci_td, - list); - ltd = list_entry(urbp->td_list.prev, struct uhci_td, - list); - ptd->link = ltd->link; - } + if (urb->status != -EINPROGRESS) /* URB already dequeued */ + goto out; - /* Take the URB off the QH's queue. If the queue is now empty, - * this is a perfect time for a toggle fixup. */ - list_del_init(&urbp->node); - if (list_empty(&qh->queue) && qh->needs_fixup) { - usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe), qh->initial_toggle); - qh->needs_fixup = 0; + switch (usb_pipetype(urb->pipe)) { + case PIPE_CONTROL: + ret = uhci_result_control(uhci, urb); + break; + case PIPE_BULK: + case PIPE_INTERRUPT: + ret = uhci_result_common(uhci, urb); + break; + case PIPE_ISOCHRONOUS: + ret = uhci_result_isochronous(uhci, urb); + break; } - uhci_dec_fsbr(uhci, urb); /* Safe since it checks */ - uhci_free_urb_priv(uhci, urbp); + if (ret == -EINPROGRESS) + goto out; + urb->status = ret; switch (usb_pipetype(urb->pipe)) { + case PIPE_CONTROL: + case PIPE_BULK: case PIPE_ISOCHRONOUS: /* Release bandwidth for Interrupt or Isoc. transfers */ if (urb->bandwidth) usb_release_bandwidth(urb->dev, urb, 1); + uhci_unlink_generic(uhci, urb); break; case PIPE_INTERRUPT: /* Release bandwidth for Interrupt or Isoc. transfers */ /* Make sure we don't release if we have a queued URB */ - if (list_empty(&qh->queue) && urb->bandwidth) + if (list_empty(&urbp->queue_list) && urb->bandwidth) usb_release_bandwidth(urb->dev, urb, 0); else /* bandwidth was passed on to queued URB, */ /* so don't let usb_unlink_urb() release it */ urb->bandwidth = 0; + uhci_unlink_generic(uhci, urb); break; + default: + dev_info(uhci_dev(uhci), "%s: unknown pipe type %d " + "for urb %p\n", + __FUNCTION__, usb_pipetype(urb->pipe), urb); } - spin_unlock(&uhci->lock); - usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, regs); - spin_lock(&uhci->lock); + /* Move it from uhci->urb_list to uhci->complete_list */ + uhci_moveto_complete(uhci, urbp); - /* If the queue is now empty, we can unlink the QH and give up its - * reserved bandwidth. */ - if (list_empty(&qh->queue)) { - uhci_unlink_qh(uhci, qh); +out: + spin_unlock(&urb->lock); +} + +static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb) +{ + struct list_head *head; + struct uhci_td *td; + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + int prevactive = 0; + + uhci_dec_fsbr(uhci, urb); /* Safe since it checks */ - /* Bandwidth stuff not yet implemented */ + /* + * Now we need to find out what the last successful toggle was + * so we can update the local data toggle for the next transfer + * + * There are 2 ways the last successful completed TD is found: + * + * 1) The TD is NOT active and the actual length < expected length + * 2) The TD is NOT active and it's the last TD in the chain + * + * and a third way the first uncompleted TD is found: + * + * 3) The TD is active and the previous TD is NOT active + * + * Control and Isochronous ignore the toggle, so this is safe + * for all types + * + * FIXME: The toggle fixups won't be 100% reliable until we + * change over to using a single queue for each endpoint and + * stop the queue before unlinking. + */ + head = &urbp->td_list; + list_for_each_entry(td, head, list) { + unsigned int ctrlstat = td_status(td); + + if (!(ctrlstat & TD_CTRL_ACTIVE) && + (uhci_actual_length(ctrlstat) < + uhci_expected_length(td_token(td)) || + td->list.next == head)) + usb_settoggle(urb->dev, uhci_endpoint(td_token(td)), + uhci_packetout(td_token(td)), + uhci_toggle(td_token(td)) ^ 1); + else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive) + usb_settoggle(urb->dev, uhci_endpoint(td_token(td)), + uhci_packetout(td_token(td)), + uhci_toggle(td_token(td))); + + prevactive = ctrlstat & TD_CTRL_ACTIVE; } -} -/* - * Scan the URBs in a QH's queue - */ -#define QH_FINISHED_UNLINKING(qh) \ - (qh->state == QH_STATE_UNLINKING && \ - uhci->frame_number + uhci->is_stopped != qh->unlink_frame) + uhci_delete_queued_urb(uhci, urb); + + /* The interrupt loop will reclaim the QHs */ + uhci_remove_qh(uhci, urbp->qh); + urbp->qh = NULL; +} -static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct pt_regs *regs) +static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) { + struct uhci_hcd *uhci = hcd_to_uhci(hcd); + unsigned long flags; struct urb_priv *urbp; - struct urb *urb; - int status; - while (!list_empty(&qh->queue)) { - urbp = list_entry(qh->queue.next, struct urb_priv, node); - urb = urbp->urb; + spin_lock_irqsave(&uhci->lock, flags); + urbp = urb->hcpriv; + if (!urbp) /* URB was never linked! */ + goto done; + list_del_init(&urbp->urb_list); + + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) + unlink_isochronous_tds(uhci, urb); + uhci_unlink_generic(uhci, urb); - switch (usb_pipetype(urb->pipe)) { - case PIPE_CONTROL: - status = uhci_result_control(uhci, urb); - break; - case PIPE_ISOCHRONOUS: - status = uhci_result_isochronous(uhci, urb); - break; - default: /* PIPE_BULK or PIPE_INTERRUPT */ - status = uhci_result_common(uhci, urb); - break; - } - if (status == -EINPROGRESS) - break; + uhci_get_current_frame_number(uhci); + if (uhci->frame_number + uhci->is_stopped != uhci->urb_remove_age) { + uhci_remove_pending_urbps(uhci); + uhci->urb_remove_age = uhci->frame_number; + } - spin_lock(&urb->lock); - if (urb->status == -EINPROGRESS) /* Not dequeued */ - urb->status = status; - else - status = -ECONNRESET; - spin_unlock(&urb->lock); + /* If we're the first, set the next interrupt bit */ + if (list_empty(&uhci->urb_remove_list)) + uhci_set_next_interrupt(uhci); + list_add_tail(&urbp->urb_list, &uhci->urb_remove_list); - /* Dequeued but completed URBs can't be given back unless - * the QH is stopped or has finished unlinking. */ - if (status == -ECONNRESET && - !(qh->is_stopped || QH_FINISHED_UNLINKING(qh))) - return; +done: + spin_unlock_irqrestore(&uhci->lock, flags); + return 0; +} - uhci_giveback_urb(uhci, qh, urb, regs); - if (qh->is_stopped) - break; - } +static int uhci_fsbr_timeout(struct uhci_hcd *uhci, struct urb *urb) +{ + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + struct list_head *head; + struct uhci_td *td; + int count = 0; - /* If the QH is neither stopped nor finished unlinking (normal case), - * our work here is done. */ - restart: - if (!(qh->is_stopped || QH_FINISHED_UNLINKING(qh))) - return; + uhci_dec_fsbr(uhci, urb); - /* Otherwise give back each of the dequeued URBs */ - list_for_each_entry(urbp, &qh->queue, node) { - urb = urbp->urb; - if (urb->status != -EINPROGRESS) { - uhci_save_toggle(qh, urb); - uhci_giveback_urb(uhci, qh, urb, regs); - goto restart; - } - } - qh->is_stopped = 0; - - /* There are no more dequeued URBs. If there are still URBs on the - * queue, the QH can now be re-activated. */ - if (!list_empty(&qh->queue)) { - if (qh->needs_fixup) - uhci_fixup_toggles(qh, 0); - uhci_activate_qh(uhci, qh); + urbp->fsbr_timeout = 1; + + /* + * Ideally we would want to fix qh->element as well, but it's + * read/write by the HC, so that can introduce a race. It's not + * really worth the hassle + */ + + head = &urbp->td_list; + list_for_each_entry(td, head, list) { + /* + * Make sure we don't do the last one (since it'll have the + * TERM bit set) as well as we skip every so many TDs to + * make sure it doesn't hog the bandwidth + */ + if (td->list.next != head && (count % DEPTH_INTERVAL) == + (DEPTH_INTERVAL - 1)) + td->link |= UHCI_PTR_DEPTH; + + count++; } - /* The queue is empty. The QH can become idle if it is fully - * unlinked. */ - else if (QH_FINISHED_UNLINKING(qh)) - uhci_make_qh_idle(uhci, qh); + return 0; +} + +static void uhci_free_pending_qhs(struct uhci_hcd *uhci) +{ + struct uhci_qh *qh, *tmp; + + list_for_each_entry_safe(qh, tmp, &uhci->qh_remove_list, remove_list) { + list_del_init(&qh->remove_list); + + uhci_free_qh(uhci, qh); + } } static void uhci_free_pending_tds(struct uhci_hcd *uhci) @@ -1349,13 +1448,43 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci) } } -/* - * Process events in the schedule, but only in one thread at a time - */ +static void +uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs) +__releases(uhci->lock) +__acquires(uhci->lock) +{ + struct uhci_hcd *uhci = hcd_to_uhci(hcd); + + uhci_destroy_urb_priv(uhci, urb); + + spin_unlock(&uhci->lock); + usb_hcd_giveback_urb(hcd, urb, regs); + spin_lock(&uhci->lock); +} + +static void uhci_finish_completion(struct uhci_hcd *uhci, struct pt_regs *regs) +{ + struct urb_priv *urbp, *tmp; + + list_for_each_entry_safe(urbp, tmp, &uhci->complete_list, urb_list) { + struct urb *urb = urbp->urb; + + list_del_init(&urbp->urb_list); + uhci_finish_urb(uhci_to_hcd(uhci), urb, regs); + } +} + +static void uhci_remove_pending_urbps(struct uhci_hcd *uhci) +{ + + /* Splice the urb_remove_list onto the end of the complete_list */ + list_splice_init(&uhci->urb_remove_list, uhci->complete_list.prev); +} + +/* Process events in the schedule, but only in one thread at a time */ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) { - int i; - struct uhci_qh *qh; + struct urb_priv *urbp, *tmp; /* Don't allow re-entrant calls */ if (uhci->scan_in_progress) { @@ -1369,39 +1498,60 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) uhci_clear_next_interrupt(uhci); uhci_get_current_frame_number(uhci); + if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age) + uhci_free_pending_qhs(uhci); if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) uhci_free_pending_tds(uhci); + if (uhci->frame_number + uhci->is_stopped != uhci->urb_remove_age) + uhci_remove_pending_urbps(uhci); - /* Go through all the QH queues and process the URBs in each one */ - for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) { - uhci->next_qh = list_entry(uhci->skelqh[i]->node.next, - struct uhci_qh, node); - while ((qh = uhci->next_qh) != uhci->skelqh[i]) { - uhci->next_qh = list_entry(qh->node.next, - struct uhci_qh, node); - uhci_scan_qh(uhci, qh, regs); - } + /* Walk the list of pending URBs to see which ones completed + * (must be _safe because uhci_transfer_result() dequeues URBs) */ + list_for_each_entry_safe(urbp, tmp, &uhci->urb_list, urb_list) { + struct urb *urb = urbp->urb; + + /* Checks the status and does all of the magic necessary */ + uhci_transfer_result(uhci, urb); + } + uhci_finish_completion(uhci, regs); + + /* If the controller is stopped, we can finish these off right now */ + if (uhci->is_stopped) { + uhci_free_pending_qhs(uhci); + uhci_free_pending_tds(uhci); + uhci_remove_pending_urbps(uhci); } if (uhci->need_rescan) goto rescan; uhci->scan_in_progress = 0; - /* If the controller is stopped, we can finish these off right now */ - if (uhci->is_stopped) - uhci_free_pending_tds(uhci); - - if (list_empty(&uhci->td_remove_list) && - list_empty(&uhci->skel_unlink_qh->node)) + if (list_empty(&uhci->urb_remove_list) && + list_empty(&uhci->td_remove_list) && + list_empty(&uhci->qh_remove_list)) uhci_clear_next_interrupt(uhci); else uhci_set_next_interrupt(uhci); + + /* Wake up anyone waiting for an URB to complete */ + wake_up_all(&uhci->waitqh); } static void check_fsbr(struct uhci_hcd *uhci) { - /* For now, don't scan URBs for FSBR timeouts. - * Add it back in later... */ + struct urb_priv *up; + + list_for_each_entry(up, &uhci->urb_list, urb_list) { + struct urb *u = up->urb; + + spin_lock(&u->lock); + + /* Check if the FSBR timed out */ + if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT)) + uhci_fsbr_timeout(uhci, u); + + spin_unlock(&u->lock); + } /* Really disable FSBR */ if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) { diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 08daf400f..049871145 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -96,7 +96,6 @@ #include #include #include -#include #include #include @@ -170,7 +169,7 @@ struct mdc800_data int out_count; // Bytes in the buffer int open; // Camera device open ? - struct mutex io_lock; // IO -lock + struct semaphore io_lock; // IO -lock char in [8]; // Command Input Buffer int in_count; @@ -498,7 +497,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, info ("Found Mustek MDC800 on USB."); - mutex_lock(&mdc800->io_lock); + down (&mdc800->io_lock); retval = usb_register_dev(intf, &mdc800_class); if (retval) { @@ -543,7 +542,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, mdc800->state=READY; - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); usb_set_intfdata(intf, mdc800); return 0; @@ -621,7 +620,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file) int retval=0; int errn=0; - mutex_lock(&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) { @@ -657,7 +656,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file) dbg ("Mustek MDC800 device opened."); error_out: - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return errn; } @@ -670,7 +669,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file) int retval=0; dbg ("Mustek MDC800 device closed."); - mutex_lock(&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->open && (mdc800->state != NOT_CONNECTED)) { usb_kill_urb(mdc800->irq_urb); @@ -683,7 +682,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file) retval=-EIO; } - mutex_unlock(&mdc800->io_lock); + up(&mdc800->io_lock); return retval; } @@ -696,21 +695,21 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l size_t left=len, sts=len; /* single transfer size */ char __user *ptr = buf; - mutex_lock(&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) { - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (mdc800->state == WORKING) { warn ("Illegal State \"working\" reached during read ?!"); - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (!mdc800->open) { - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } @@ -718,7 +717,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l { if (signal_pending (current)) { - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EINTR; } @@ -737,7 +736,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL)) { err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } wait_event_timeout(mdc800->download_wait, mdc800->downloaded, @@ -746,14 +745,14 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l if (mdc800->download_urb->status != 0) { err ("request download-bytes fails (status=%i)",mdc800->download_urb->status); - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } } else { /* No more bytes -> that's an error*/ - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } } @@ -762,7 +761,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l /* Copy Bytes */ if (copy_to_user(ptr, &mdc800->out [mdc800->out_ptr], sts)) { - mutex_unlock(&mdc800->io_lock); + up(&mdc800->io_lock); return -EFAULT; } ptr+=sts; @@ -771,7 +770,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l } } - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } @@ -786,15 +785,15 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s { size_t i=0; - mutex_lock(&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state != READY) { - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (!mdc800->open ) { - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } @@ -803,13 +802,13 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s unsigned char c; if (signal_pending (current)) { - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EINTR; } if(get_user(c, buf+i)) { - mutex_unlock(&mdc800->io_lock); + up(&mdc800->io_lock); return -EFAULT; } @@ -830,7 +829,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s } else { - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -842,7 +841,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s if (mdc800_usb_waitForIRQ (0,TO_GET_READY)) { err ("Camera didn't get ready.\n"); - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -854,7 +853,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL)) { err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } wait_event_timeout(mdc800->write_wait, mdc800->written, TO_WRITE_GET_READY*HZ/1000); @@ -862,7 +861,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s if (mdc800->state == WORKING) { usb_kill_urb(mdc800->write_urb); - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -874,7 +873,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s { err ("call 0x07 before 0x05,0x3e"); mdc800->state=READY; - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } mdc800->pic_len=-1; @@ -893,7 +892,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ)) { err ("requesting answer from irq fails"); - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -921,7 +920,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND)) { err ("Command Timeout."); - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } } @@ -931,7 +930,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s } i++; } - mutex_unlock(&mdc800->io_lock); + up (&mdc800->io_lock); return i; } @@ -979,13 +978,15 @@ static int __init usb_mdc800_init (void) { int retval = -ENODEV; /* Allocate Memory */ - mdc800=kzalloc (sizeof (struct mdc800_data), GFP_KERNEL); + mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL); if (!mdc800) goto cleanup_on_fail; + memset(mdc800, 0, sizeof(struct mdc800_data)); mdc800->dev = NULL; + mdc800->open=0; mdc800->state=NOT_CONNECTED; - mutex_init (&mdc800->io_lock); + init_MUTEX (&mdc800->io_lock); init_waitqueue_head (&mdc800->irq_wait); init_waitqueue_head (&mdc800->write_wait); diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 2a0e18a48..28538db9e 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -360,7 +360,7 @@ static int mts_scsi_host_reset (Scsi_Cmnd *srb) rc = usb_lock_device_for_reset(desc->usb_dev, desc->usb_intf); if (rc < 0) return FAILED; - result = usb_reset_device(desc->usb_dev); + result = usb_reset_device(desc->usb_dev);; if (rc) usb_unlock_device(desc->usb_dev); return result ? FAILED : SUCCESS; diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 650103bc9..5246b3530 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig @@ -200,41 +200,45 @@ config USB_POWERMATE To compile this driver as a module, choose M here: the module will be called powermate. -config USB_TOUCHSCREEN - tristate "USB Touchscreen Driver" +config USB_MTOUCH + tristate "MicroTouch USB Touchscreen Driver" depends on USB && INPUT ---help--- - USB Touchscreen driver for: - - eGalax Touchkit USB - - PanJit TouchSet USB - - 3M MicroTouch USB - - ITM + Say Y here if you want to use a MicroTouch (Now 3M) USB + Touchscreen controller. - Have a look at for - a usage description and the required user-space stuff. + See for additional information. To compile this driver as a module, choose M here: the - module will be called usbtouchscreen. + module will be called mtouchusb. -config USB_TOUCHSCREEN_EGALAX - default y - bool "eGalax device support" if EMBEDDED - depends on USB_TOUCHSCREEN +config USB_ITMTOUCH + tristate "ITM Touch USB Touchscreen Driver" + depends on USB && INPUT + ---help--- + Say Y here if you want to use a ITM Touch USB + Touchscreen controller. -config USB_TOUCHSCREEN_PANJIT - default y - bool "PanJit device support" if EMBEDDED - depends on USB_TOUCHSCREEN + This touchscreen is used in LG 1510SF monitors. -config USB_TOUCHSCREEN_3M - default y - bool "3M/Microtouch device support" if EMBEDDED - depends on USB_TOUCHSCREEN + To compile this driver as a module, choose M here: the + module will be called itmtouch. -config USB_TOUCHSCREEN_ITM - default y - bool "ITM device support" if EMBEDDED - depends on USB_TOUCHSCREEN +config USB_EGALAX + tristate "eGalax TouchKit USB Touchscreen Driver" + depends on USB && INPUT + ---help--- + Say Y here if you want to use a eGalax TouchKit USB + Touchscreen controller. + + The driver has been tested on a Xenarc 700TSV monitor + with eGalax touchscreen. + + Have a look at for + a usage description and the required user-space stuff. + + To compile this driver as a module, choose M here: the + module will be called touchkitusb. config USB_YEALINK tristate "Yealink usb-p1k voip phone" diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 764114529..d512d9f48 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile @@ -37,7 +37,6 @@ obj-$(CONFIG_USB_MOUSE) += usbmouse.o obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o obj-$(CONFIG_USB_EGALAX) += touchkitusb.o -obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o obj-$(CONFIG_USB_POWERMATE) += powermate.o obj-$(CONFIG_USB_WACOM) += wacom.o obj-$(CONFIG_USB_ACECAD) += acecad.o diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 99f986cb6..cea6d4bfa 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -159,6 +159,8 @@ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; */ #define FILTER_TIME (HZ / 20) +static DECLARE_MUTEX(disconnect_sem); + struct ati_remote { struct input_dev *idev; struct usb_device *udev; @@ -624,7 +626,7 @@ static void ati_remote_free_buffers(struct ati_remote *ati_remote) if (ati_remote->outbuf) usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, - ati_remote->inbuf, ati_remote->outbuf_dma); + ati_remote->outbuf, ati_remote->outbuf_dma); } static void ati_remote_input_init(struct ati_remote *ati_remote) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 435273e7c..1db813d3c 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -66,8 +66,9 @@ static struct hid_report *hid_register_report(struct hid_device *device, unsigne if (report_enum->report_id_hash[id]) return report_enum->report_id_hash[id]; - if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL))) + if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) return NULL; + memset(report, 0, sizeof(struct hid_report)); if (id != 0) report_enum->numbered = 1; @@ -96,9 +97,12 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned return NULL; } - if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) + if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) + values * sizeof(unsigned), GFP_KERNEL))) return NULL; + memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) + + values * sizeof(unsigned)); + field->index = report->maxfield++; report->field[field->index] = field; field->usage = (struct hid_usage *)(field + 1); @@ -647,14 +651,17 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) hid_parser_reserved }; - if (!(device = kzalloc(sizeof(struct hid_device), GFP_KERNEL))) + if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) return NULL; + memset(device, 0, sizeof(struct hid_device)); - if (!(device->collection = kzalloc(sizeof(struct hid_collection) * + if (!(device->collection = kmalloc(sizeof(struct hid_collection) * HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { kfree(device); return NULL; } + memset(device->collection, 0, sizeof(struct hid_collection) * + HID_DEFAULT_NUM_COLLECTIONS); device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; for (i = 0; i < HID_REPORT_TYPES; i++) @@ -668,12 +675,13 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) memcpy(device->rdesc, start, size); device->rsize = size; - if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) { + if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { kfree(device->rdesc); kfree(device->collection); kfree(device); return NULL; } + memset(parser, 0, sizeof(struct hid_parser)); parser->device = device; end = start + size; @@ -902,99 +910,6 @@ static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_ return 0; } -/* - * Input submission and I/O error handler. - */ - -static void hid_io_error(struct hid_device *hid); - -/* Start up the input URB */ -static int hid_start_in(struct hid_device *hid) -{ - unsigned long flags; - int rc = 0; - - spin_lock_irqsave(&hid->inlock, flags); - if (hid->open > 0 && !test_bit(HID_SUSPENDED, &hid->iofl) && - !test_and_set_bit(HID_IN_RUNNING, &hid->iofl)) { - rc = usb_submit_urb(hid->urbin, GFP_ATOMIC); - if (rc != 0) - clear_bit(HID_IN_RUNNING, &hid->iofl); - } - spin_unlock_irqrestore(&hid->inlock, flags); - return rc; -} - -/* I/O retry timer routine */ -static void hid_retry_timeout(unsigned long _hid) -{ - struct hid_device *hid = (struct hid_device *) _hid; - - dev_dbg(&hid->intf->dev, "retrying intr urb\n"); - if (hid_start_in(hid)) - hid_io_error(hid); -} - -/* Workqueue routine to reset the device */ -static void hid_reset(void *_hid) -{ - struct hid_device *hid = (struct hid_device *) _hid; - int rc_lock, rc; - - dev_dbg(&hid->intf->dev, "resetting device\n"); - rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); - if (rc_lock >= 0) { - rc = usb_reset_device(hid->dev); - if (rc_lock) - usb_unlock_device(hid->dev); - } - clear_bit(HID_RESET_PENDING, &hid->iofl); - - if (rc == 0) { - hid->retry_delay = 0; - if (hid_start_in(hid)) - hid_io_error(hid); - } else if (!(rc == -ENODEV || rc == -EHOSTUNREACH || rc == -EINTR)) - err("can't reset device, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, - hid->dev->devpath, - hid->ifnum, rc); -} - -/* Main I/O error handler */ -static void hid_io_error(struct hid_device *hid) -{ - unsigned long flags; - - spin_lock_irqsave(&hid->inlock, flags); - - /* Stop when disconnected */ - if (usb_get_intfdata(hid->intf) == NULL) - goto done; - - /* When an error occurs, retry at increasing intervals */ - if (hid->retry_delay == 0) { - hid->retry_delay = 13; /* Then 26, 52, 104, 104, ... */ - hid->stop_retry = jiffies + msecs_to_jiffies(1000); - } else if (hid->retry_delay < 100) - hid->retry_delay *= 2; - - if (time_after(jiffies, hid->stop_retry)) { - - /* Retries failed, so do a port reset */ - if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) { - if (schedule_work(&hid->reset_work)) - goto done; - clear_bit(HID_RESET_PENDING, &hid->iofl); - } - } - - mod_timer(&hid->io_retry, - jiffies + msecs_to_jiffies(hid->retry_delay)); -done: - spin_unlock_irqrestore(&hid->inlock, flags); -} - /* * Input interrupt completion handler. */ @@ -1006,35 +921,25 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs) switch (urb->status) { case 0: /* success */ - hid->retry_delay = 0; hid_input_report(HID_INPUT_REPORT, urb, 1, regs); break; case -ECONNRESET: /* unlink */ case -ENOENT: + case -EPERM: case -ESHUTDOWN: /* unplug */ - clear_bit(HID_IN_RUNNING, &hid->iofl); + case -EILSEQ: /* unplug timeout on uhci */ return; - case -EILSEQ: /* protocol error or unplug */ - case -EPROTO: /* protocol error or unplug */ case -ETIMEDOUT: /* NAK */ - clear_bit(HID_IN_RUNNING, &hid->iofl); - hid_io_error(hid); - return; + break; default: /* error */ warn("input irq status %d received", urb->status); } status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status) { - clear_bit(HID_IN_RUNNING, &hid->iofl); - if (status != -EPERM) { - err("can't resubmit intr, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, - hid->dev->devpath, - hid->ifnum, status); - hid_io_error(hid); - } - } + if (status) + err("can't resubmit intr, %s-%s/input%d, status %d", + hid->dev->bus->bus_name, hid->dev->devpath, + hid->ifnum, status); } /* @@ -1196,9 +1101,8 @@ static void hid_irq_out(struct urb *urb, struct pt_regs *regs) case 0: /* success */ break; case -ESHUTDOWN: /* unplug */ + case -EILSEQ: /* unplug timeout on uhci */ unplug = 1; - case -EILSEQ: /* protocol error or unplug */ - case -EPROTO: /* protocol error or unplug */ case -ECONNRESET: /* unlink */ case -ENOENT: break; @@ -1215,7 +1119,7 @@ static void hid_irq_out(struct urb *urb, struct pt_regs *regs) if (hid->outhead != hid->outtail) { if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &hid->iofl); + clear_bit(HID_OUT_RUNNING, &hid->iofl);; wake_up(&hid->wait); } spin_unlock_irqrestore(&hid->outlock, flags); @@ -1245,9 +1149,8 @@ static void hid_ctrl(struct urb *urb, struct pt_regs *regs) hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); break; case -ESHUTDOWN: /* unplug */ + case -EILSEQ: /* unplug timectrl on uhci */ unplug = 1; - case -EILSEQ: /* protocol error or unplug */ - case -EPROTO: /* protocol error or unplug */ case -ECONNRESET: /* unlink */ case -ENOENT: case -EPIPE: /* report not available */ @@ -1360,9 +1263,14 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, int hid_open(struct hid_device *hid) { - ++hid->open; - if (hid_start_in(hid)) - hid_io_error(hid); + if (hid->open++) + return 0; + + hid->urbin->dev = hid->dev; + + if (usb_submit_urb(hid->urbin, GFP_KERNEL)) + return -EIO; + return 0; } @@ -1372,11 +1280,6 @@ void hid_close(struct hid_device *hid) usb_kill_urb(hid->urbin); } -#define USB_VENDOR_ID_PANJIT 0x134c - -#define USB_VENDOR_ID_SILVERCREST 0x062a -#define USB_DEVICE_ID_SILVERCREST_KB 0x0201 - /* * Initialize all reports */ @@ -1557,11 +1460,8 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_HP 0x03f0 #define USB_DEVICE_ID_HP_USBHUB_KB 0x020c -#define USB_VENDOR_ID_IBM 0x04b3 -#define USB_DEVICE_ID_IBM_USBHUB_KB 0x3005 - -#define USB_VENDOR_ID_CREATIVELABS 0x062a -#define USB_DEVICE_ID_CREATIVELABS_SILVERCREST 0x0201 +#define USB_VENDOR_ID_YEALINK 0x6993 +#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 /* * Alphabetically sorted blacklist by quirk type. @@ -1592,6 +1492,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, @@ -1663,12 +1564,9 @@ static const struct hid_blacklist { { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 3, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 4, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 5, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF + 3, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, @@ -1682,12 +1580,9 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET}, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVELABS_SILVERCREST, HID_QUIRK_NOGET }, { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_USBHUB_KB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, @@ -1714,11 +1609,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, - { 0, 0 } }; @@ -1909,10 +1799,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) init_waitqueue_head(&hid->wait); - INIT_WORK(&hid->reset_work, hid_reset, hid); - setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid); - - spin_lock_init(&hid->inlock); spin_lock_init(&hid->outlock); spin_lock_init(&hid->ctrllock); @@ -1981,16 +1867,11 @@ static void hid_disconnect(struct usb_interface *intf) if (!hid) return; - spin_lock_irq(&hid->inlock); /* Sync with error handler */ usb_set_intfdata(intf, NULL); - spin_unlock_irq(&hid->inlock); usb_kill_urb(hid->urbin); usb_kill_urb(hid->urbout); usb_kill_urb(hid->urbctrl); - del_timer_sync(&hid->io_retry); - flush_scheduled_work(); - if (hid->claimed & HID_CLAIMED_INPUT) hidinput_disconnect(hid); if (hid->claimed & HID_CLAIMED_HIDDEV) @@ -2065,10 +1946,6 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) { struct hid_device *hid = usb_get_intfdata (intf); - spin_lock_irq(&hid->inlock); /* Sync with error handler */ - set_bit(HID_SUSPENDED, &hid->iofl); - spin_unlock_irq(&hid->inlock); - del_timer(&hid->io_retry); usb_kill_urb(hid->urbin); dev_dbg(&intf->dev, "suspend\n"); return 0; @@ -2079,8 +1956,10 @@ static int hid_resume(struct usb_interface *intf) struct hid_device *hid = usb_get_intfdata (intf); int status; - clear_bit(HID_SUSPENDED, &hid->iofl); - status = hid_start_in(hid); + if (hid->open) + status = usb_submit_urb(hid->urbin, GFP_NOIO); + else + status = 0; dev_dbg(&intf->dev, "resume status %d\n", status); return status; } diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c index d5c91ee67..72e698658 100644 --- a/drivers/usb/input/hid-ff.c +++ b/drivers/usb/input/hid-ff.c @@ -34,6 +34,12 @@ #include "hid.h" +/* Drivers' initializing functions */ +extern int hid_lgff_init(struct hid_device* hid); +extern int hid_lg3d_init(struct hid_device* hid); +extern int hid_pid_init(struct hid_device* hid); +extern int hid_tmff_init(struct hid_device* hid); + /* * This table contains pointers to initializers. To add support for new * devices, you need to add the USB vendor and product ids here. diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 25bc85f8c..cb0d80f49 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -510,7 +510,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x025: map_key_clear(KEY_TV); break; case 0x026: map_key_clear(KEY_MENU); break; case 0x031: map_key_clear(KEY_AUDIO); break; - case 0x032: map_key_clear(KEY_TEXT); break; + case 0x032: map_key_clear(KEY_SUBTITLE); break; case 0x033: map_key_clear(KEY_LAST); break; case 0x047: map_key_clear(KEY_MP3); break; case 0x048: map_key_clear(KEY_DVD); break; diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c index f07d44357..f82c9c9e5 100644 --- a/drivers/usb/input/hid-lgff.c +++ b/drivers/usb/input/hid-lgff.c @@ -154,9 +154,10 @@ int hid_lgff_init(struct hid_device* hid) return -1; } - private = kzalloc(sizeof(struct lgff_device), GFP_KERNEL); + private = kmalloc(sizeof(struct lgff_device), GFP_KERNEL); if (!private) return -1; + memset(private, 0, sizeof(struct lgff_device)); hid->ff_private = private; /* Input init */ @@ -227,12 +228,13 @@ static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report) } *ret->field[0] = *report->field[0]; - ret->field[0]->value = kzalloc(sizeof(s32[8]), GFP_KERNEL); + ret->field[0]->value = kmalloc(sizeof(s32[8]), GFP_KERNEL); if (!ret->field[0]->value) { kfree(ret->field[0]); kfree(ret); return NULL; } + memset(ret->field[0]->value, 0, sizeof(s32[8])); return ret; } diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c index 534425c69..023fd5ac3 100644 --- a/drivers/usb/input/hid-tmff.c +++ b/drivers/usb/input/hid-tmff.c @@ -113,10 +113,11 @@ int hid_tmff_init(struct hid_device *hid) struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); struct input_dev *input_dev = hidinput->input; - private = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); + private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL); if (!private) return -ENOMEM; + memset(private, 0, sizeof(struct tmff_device)); hid->ff_private = private; /* Find the report to use */ diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index 9c62837b5..8b0d4346c 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h @@ -31,8 +31,6 @@ #include #include #include -#include -#include /* * USB HID (Human Interface Device) interface class code @@ -372,9 +370,6 @@ struct hid_control_fifo { #define HID_CTRL_RUNNING 1 #define HID_OUT_RUNNING 2 -#define HID_IN_RUNNING 3 -#define HID_RESET_PENDING 4 -#define HID_SUSPENDED 5 struct hid_input { struct list_head list; @@ -398,17 +393,12 @@ struct hid_device { /* device report descriptor */ int ifnum; /* USB interface number */ 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 */ unsigned int bufsize; /* URB buffer size */ 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 */ @@ -533,8 +523,3 @@ static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input, return hid->ff_event(hid, input, type, code, value); return -ENOSYS; } - -int hid_lgff_init(struct hid_device* hid); -int hid_tmff_init(struct hid_device* hid); -int hid_pid_init(struct hid_device* hid); - diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index c4670e1d4..925f5aba0 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -257,8 +257,9 @@ static int hiddev_open(struct inode * inode, struct file * file) { if (i >= HIDDEV_MINORS || !hiddev_table[i]) return -ENODEV; - if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) + if (!(list = kmalloc(sizeof(struct hiddev_list), GFP_KERNEL))) return -ENOMEM; + memset(list, 0, sizeof(struct hiddev_list)); list->hiddev = hiddev_table[i]; list->next = hiddev_table[i]->list; @@ -317,7 +318,6 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun } schedule(); - set_current_state(TASK_INTERRUPTIBLE); } set_current_state(TASK_RUNNING); @@ -754,8 +754,9 @@ int hiddev_connect(struct hid_device *hid) if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0) return -1; - if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) + if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL))) return -1; + memset(hiddev, 0, sizeof(struct hiddev)); retval = usb_register_dev(hid->intf, &hiddev_class); if (retval) { diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index 3d911976f..b4a051b54 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c @@ -297,8 +297,6 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs) remote->data.bits_left -= 6; } else { err("%s - Error in message, invalid toggle.\n", __FUNCTION__); - remote->stage = 0; - return; } keyspan_load_tester(remote, 5); diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c deleted file mode 100644 index e9a07c1e9..000000000 --- a/drivers/usb/input/usbtouchscreen.c +++ /dev/null @@ -1,605 +0,0 @@ -/****************************************************************************** - * usbtouchscreen.c - * Driver for USB Touchscreens, supporting those devices: - * - eGalax Touchkit - * - 3M/Microtouch - * - ITM - * - PanJit TouchSet - * - * Copyright (C) 2004-2006 by Daniel Ritz - * Copyright (C) by Todd E. Johnson (mtouchusb.c) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You 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 is based on touchkitusb.c - * - ITM parts are from itmtouch.c - * - 3M parts are from mtouchusb.c - * - PanJit parts are from an unmerged driver by Lanslott Gish - * - *****************************************************************************/ - -//#define DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define DRIVER_VERSION "v0.3" -#define DRIVER_AUTHOR "Daniel Ritz " -#define DRIVER_DESC "USB Touchscreen Driver" - -static int swap_xy; -module_param(swap_xy, bool, 0644); -MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); - -/* device specifc data/functions */ -struct usbtouch_usb; -struct usbtouch_device_info { - int min_xc, max_xc; - int min_yc, max_yc; - int min_press, max_press; - int rept_size; - int flags; - - void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, unsigned char *pkt, int len); - int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); - int (*init) (struct usbtouch_usb *usbtouch); -}; - -#define USBTOUCH_FLG_BUFFER 0x01 - - -/* a usbtouch device */ -struct usbtouch_usb { - unsigned char *data; - dma_addr_t data_dma; - unsigned char *buffer; - int buf_len; - struct urb *irq; - struct usb_device *udev; - struct input_dev *input; - struct usbtouch_device_info *type; - char name[128]; - char phys[64]; -}; - -static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, - struct pt_regs *regs, unsigned char *pkt, int len); - -/* device types */ -enum { - DEVTPYE_DUMMY = -1, - DEVTYPE_EGALAX, - DEVTYPE_PANJIT, - DEVTYPE_3M, - DEVTYPE_ITM, -}; - -static struct usb_device_id usbtouch_devices[] = { -#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX - {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, - {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, - {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX}, - {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX}, -#endif - -#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT - {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT}, - {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT}, - {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT}, - {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT}, -#endif - -#ifdef CONFIG_USB_TOUCHSCREEN_3M - {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M}, -#endif - -#ifdef CONFIG_USB_TOUCHSCREEN_ITM - {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, -#endif - - {} -}; - - -/***************************************************************************** - * eGalax part - */ - -#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX - -#define EGALAX_PKT_TYPE_MASK 0xFE -#define EGALAX_PKT_TYPE_REPT 0x80 -#define EGALAX_PKT_TYPE_DIAG 0x0A - -static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) -{ - if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) - return 0; - - *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); - *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); - *touch = pkt[0] & 0x01; - - return 1; - -} - -static int egalax_get_pkt_len(unsigned char *buf) -{ - switch (buf[0] & EGALAX_PKT_TYPE_MASK) { - case EGALAX_PKT_TYPE_REPT: - return 5; - - case EGALAX_PKT_TYPE_DIAG: - return buf[1] + 2; - } - - return 0; -} - -static void egalax_process(struct usbtouch_usb *usbtouch, struct pt_regs *regs, - unsigned char *pkt, int len) -{ - unsigned char *buffer; - int pkt_len, buf_len, pos; - - /* if the buffer contains data, append */ - if (unlikely(usbtouch->buf_len)) { - int tmp; - - /* if only 1 byte in buffer, add another one to get length */ - if (usbtouch->buf_len == 1) - usbtouch->buffer[1] = pkt[0]; - - pkt_len = egalax_get_pkt_len(usbtouch->buffer); - - /* unknown packet: drop everything */ - if (!pkt_len) - return; - - /* append, process */ - tmp = pkt_len - usbtouch->buf_len; - memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp); - usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len); - - buffer = pkt + tmp; - buf_len = len - tmp; - } else { - buffer = pkt; - buf_len = len; - } - - /* only one byte left in buffer */ - if (unlikely(buf_len == 1)) { - usbtouch->buffer[0] = buffer[0]; - usbtouch->buf_len = 1; - return; - } - - /* loop over the buffer */ - pos = 0; - while (pos < buf_len) { - /* get packet len */ - pkt_len = egalax_get_pkt_len(buffer + pos); - - /* unknown packet: drop everything */ - if (unlikely(!pkt_len)) - return; - - /* full packet: process */ - if (likely(pkt_len <= buf_len)) { - usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len); - } else { - /* incomplete packet: save in buffer */ - memcpy(usbtouch->buffer, buffer + pos, buf_len - pos); - usbtouch->buf_len = buf_len - pos; - } - pos += pkt_len; - } -} -#endif - - -/***************************************************************************** - * PanJit Part - */ -#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT -static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) -{ - *x = ((pkt[2] & 0x0F) << 8) | pkt[1]; - *y = ((pkt[4] & 0x0F) << 8) | pkt[3]; - *touch = pkt[0] & 0x01; - - return 1; -} -#endif - - -/***************************************************************************** - * 3M/Microtouch Part - */ -#ifdef CONFIG_USB_TOUCHSCREEN_3M - -#define MTOUCHUSB_ASYNC_REPORT 1 -#define MTOUCHUSB_RESET 7 -#define MTOUCHUSB_REQ_CTRLLR_ID 10 - -static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) -{ - *x = (pkt[8] << 8) | pkt[7]; - *y = (pkt[10] << 8) | pkt[9]; - *touch = (pkt[2] & 0x40) ? 1 : 0; - - return 1; -} - -static int mtouch_init(struct usbtouch_usb *usbtouch) -{ - int ret; - - ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), - MTOUCHUSB_RESET, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", - __FUNCTION__, ret); - if (ret < 0) - return ret; - - ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), - MTOUCHUSB_ASYNC_REPORT, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); - dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", - __FUNCTION__, ret); - if (ret < 0) - return ret; - - return 0; -} -#endif - - -/***************************************************************************** - * ITM Part - */ -#ifdef CONFIG_USB_TOUCHSCREEN_ITM -static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) -{ - *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); - *x = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); - *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F); - *touch = ~pkt[7] & 0x20; - - return 1; -} -#endif - - -/***************************************************************************** - * the different device descriptors - */ -static struct usbtouch_device_info usbtouch_dev_info[] = { -#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX - [DEVTYPE_EGALAX] = { - .min_xc = 0x0, - .max_xc = 0x07ff, - .min_yc = 0x0, - .max_yc = 0x07ff, - .rept_size = 16, - .flags = USBTOUCH_FLG_BUFFER, - .process_pkt = egalax_process, - .read_data = egalax_read_data, - }, -#endif - -#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT - [DEVTYPE_PANJIT] = { - .min_xc = 0x0, - .max_xc = 0x0fff, - .min_yc = 0x0, - .max_yc = 0x0fff, - .rept_size = 8, - .read_data = panjit_read_data, - }, -#endif - -#ifdef CONFIG_USB_TOUCHSCREEN_3M - [DEVTYPE_3M] = { - .min_xc = 0x0, - .max_xc = 0x4000, - .min_yc = 0x0, - .max_yc = 0x4000, - .rept_size = 11, - .read_data = mtouch_read_data, - .init = mtouch_init, - }, -#endif - -#ifdef CONFIG_USB_TOUCHSCREEN_ITM - [DEVTYPE_ITM] = { - .min_xc = 0x0, - .max_xc = 0x0fff, - .min_yc = 0x0, - .max_yc = 0x0fff, - .max_press = 0xff, - .rept_size = 8, - .read_data = itm_read_data, - }, -#endif -}; - - -/***************************************************************************** - * Generic Part - */ -static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, - struct pt_regs *regs, unsigned char *pkt, int len) -{ - int x, y, touch, press; - struct usbtouch_device_info *type = usbtouch->type; - - if (!type->read_data(pkt, &x, &y, &touch, &press)) - return; - - input_regs(usbtouch->input, regs); - input_report_key(usbtouch->input, BTN_TOUCH, touch); - - if (swap_xy) { - input_report_abs(usbtouch->input, ABS_X, y); - input_report_abs(usbtouch->input, ABS_Y, x); - } else { - input_report_abs(usbtouch->input, ABS_X, x); - input_report_abs(usbtouch->input, ABS_Y, y); - } - if (type->max_press) - input_report_abs(usbtouch->input, ABS_PRESSURE, press); - input_sync(usbtouch->input); -} - - -static void usbtouch_irq(struct urb *urb, struct pt_regs *regs) -{ - struct usbtouch_usb *usbtouch = urb->context; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ETIMEDOUT: - /* this urb is timing out */ - dbg("%s - urb timed out - was the device unplugged?", - __FUNCTION__); - return; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __FUNCTION__, urb->status); - goto exit; - } - - usbtouch->type->process_pkt(usbtouch, regs, usbtouch->data, urb->actual_length); - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - err("%s - usb_submit_urb failed with result: %d", - __FUNCTION__, retval); -} - -static int usbtouch_open(struct input_dev *input) -{ - struct usbtouch_usb *usbtouch = input->private; - - usbtouch->irq->dev = usbtouch->udev; - - if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) - return -EIO; - - return 0; -} - -static void usbtouch_close(struct input_dev *input) -{ - struct usbtouch_usb *usbtouch = input->private; - - usb_kill_urb(usbtouch->irq); -} - - -static void usbtouch_free_buffers(struct usb_device *udev, - struct usbtouch_usb *usbtouch) -{ - if (usbtouch->data) - usb_buffer_free(udev, usbtouch->type->rept_size, - usbtouch->data, usbtouch->data_dma); - kfree(usbtouch->buffer); -} - - -static int usbtouch_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usbtouch_usb *usbtouch; - struct input_dev *input_dev; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - struct usb_device *udev = interface_to_usbdev(intf); - struct usbtouch_device_info *type; - int err; - - interface = intf->cur_altsetting; - endpoint = &interface->endpoint[0].desc; - - usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!usbtouch || !input_dev) - goto out_free; - - type = &usbtouch_dev_info[id->driver_info]; - usbtouch->type = type; - if (!type->process_pkt) - type->process_pkt = usbtouch_process_pkt; - - usbtouch->data = usb_buffer_alloc(udev, type->rept_size, - SLAB_KERNEL, &usbtouch->data_dma); - if (!usbtouch->data) - goto out_free; - - if (type->flags & USBTOUCH_FLG_BUFFER) { - usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL); - if (!usbtouch->buffer) - goto out_free_buffers; - } - - usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!usbtouch->irq) { - dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__); - goto out_free_buffers; - } - - usbtouch->udev = udev; - usbtouch->input = input_dev; - - if (udev->manufacturer) - strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name)); - - if (udev->product) { - if (udev->manufacturer) - strlcat(usbtouch->name, " ", sizeof(usbtouch->name)); - strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name)); - } - - if (!strlen(usbtouch->name)) - snprintf(usbtouch->name, sizeof(usbtouch->name), - "USB Touchscreen %04x:%04x", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys)); - strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys)); - - input_dev->name = usbtouch->name; - input_dev->phys = usbtouch->phys; - usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; - input_dev->private = usbtouch; - input_dev->open = usbtouch_open; - input_dev->close = usbtouch_close; - - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0); - input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0); - if (type->max_press) - input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, - type->max_press, 0, 0); - - usb_fill_int_urb(usbtouch->irq, usbtouch->udev, - usb_rcvintpipe(usbtouch->udev, 0x81), - usbtouch->data, type->rept_size, - usbtouch_irq, usbtouch, endpoint->bInterval); - - usbtouch->irq->transfer_dma = usbtouch->data_dma; - usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - /* device specific init */ - if (type->init) { - err = type->init(usbtouch); - if (err) { - dbg("%s - type->init() failed, err: %d", __FUNCTION__, err); - goto out_free_buffers; - } - } - - err = input_register_device(usbtouch->input); - if (err) { - dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err); - goto out_free_buffers; - } - - usb_set_intfdata(intf, usbtouch); - - return 0; - -out_free_buffers: - usbtouch_free_buffers(udev, usbtouch); -out_free: - input_free_device(input_dev); - kfree(usbtouch); - return -ENOMEM; -} - -static void usbtouch_disconnect(struct usb_interface *intf) -{ - struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); - - dbg("%s - called", __FUNCTION__); - - if (!usbtouch) - return; - - dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__); - usb_set_intfdata(intf, NULL); - usb_kill_urb(usbtouch->irq); - input_unregister_device(usbtouch->input); - usb_free_urb(usbtouch->irq); - usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); - kfree(usbtouch); -} - -MODULE_DEVICE_TABLE(usb, usbtouch_devices); - -static struct usb_driver usbtouch_driver = { - .name = "usbtouchscreen", - .probe = usbtouch_probe, - .disconnect = usbtouch_disconnect, - .id_table = usbtouch_devices, -}; - -static int __init usbtouch_init(void) -{ - return usb_register(&usbtouch_driver); -} - -static void __exit usbtouch_cleanup(void) -{ - usb_deregister(&usbtouch_driver); -} - -module_init(usbtouch_init); -module_exit(usbtouch_cleanup); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -MODULE_ALIAS("touchkitusb"); -MODULE_ALIAS("itmtouch"); -MODULE_ALIAS("mtouchusb"); diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index cf84c6096..d3e15df9e 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -9,7 +9,7 @@ * Copyright (c) 2000 Daniel Egger * Copyright (c) 2001 Frederic Lepied * Copyright (c) 2004 Panagiotis Issaris - * Copyright (c) 2002-2006 Ping Cheng + * Copyright (c) 2002-2005 Ping Cheng * * ChangeLog: * v0.1 (vp) - Initial release @@ -56,8 +56,6 @@ * - Merged wacom_intuos3_irq into wacom_intuos_irq * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. * - Report Device IDs - * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 - * - Minor data report fix */ /* @@ -80,7 +78,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.45" +#define DRIVER_VERSION "v1.44" #define DRIVER_AUTHOR "Vojtech Pavlik " #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" #define DRIVER_LICENSE "GPL" @@ -101,8 +99,6 @@ enum { PL, INTUOS, INTUOS3, - INTUOS312, - INTUOS319, CINTIQ, MAX_TYPE }; @@ -131,19 +127,7 @@ struct wacom { char phys[32]; }; -#define USB_REQ_GET_REPORT 0x01 #define USB_REQ_SET_REPORT 0x09 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - static int usb_set_report(struct usb_interface *intf, unsigned char type, unsigned char id, void *buf, int size) { @@ -222,8 +206,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) wacom->tool[1] = BTN_TOOL_PEN; id = STYLUS_DEVICE_ID; } - input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ - input_report_abs(dev, ABS_MISC, id); /* report tool id */ + input_report_key(dev, wacom->tool[1], id); /* report in proximity for tool */ input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); input_report_abs(dev, ABS_PRESSURE, pressure); @@ -256,7 +239,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) struct wacom *wacom = urb->context; unsigned char *data = wacom->data; struct input_dev *dev = wacom->dev; - int retval, id; + int retval; switch (urb->status) { case 0: @@ -280,15 +263,12 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) input_regs(dev, regs); if (data[1] & 0x04) { - input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); + input_report_key(dev, BTN_TOOL_RUBBER, (data[1] & 0x20) ? ERASER_DEVICE_ID : 0); input_report_key(dev, BTN_TOUCH, data[1] & 0x08); - id = ERASER_DEVICE_ID; } else { - input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); + input_report_key(dev, BTN_TOOL_PEN, (data[1] & 0x20) ? STYLUS_DEVICE_ID : 0); input_report_key(dev, BTN_TOUCH, data[1] & 0x01); - id = STYLUS_DEVICE_ID; } - input_report_abs(dev, ABS_MISC, id); /* report tool id */ input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4])); input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); @@ -332,8 +312,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) } input_regs(dev, regs); - input_report_key(dev, BTN_TOOL_PEN, 1); - input_report_abs(dev, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ + input_report_key(dev, BTN_TOOL_PEN, STYLUS_DEVICE_ID); input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); @@ -371,8 +350,6 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) goto exit; } - if (data[0] == 99) return; /* for Volito tablets */ - if (data[0] != 2) { dbg("wacom_graphire_irq: received unknown report #%d", data[0]); goto exit; @@ -397,10 +374,10 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) case 2: /* Mouse with wheel */ input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); if (wacom->features->type == WACOM_G4) { - rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); - input_report_rel(dev, REL_WHEEL, -rw); + rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); + input_report_rel(dev, REL_WHEEL, rw); } else - input_report_rel(dev, REL_WHEEL, -(signed char) data[6]); + input_report_rel(dev, REL_WHEEL, (signed char) data[6]); /* fall through */ case 3: /* Mouse without wheel */ @@ -429,27 +406,39 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) } } - if (data[1] & 0x10) - input_report_abs(dev, ABS_MISC, id); /* report tool id */ - else - input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ - input_report_key(dev, wacom->tool[0], data[1] & 0x10); + input_report_key(dev, wacom->tool[0], (data[1] & 0x10) ? id : 0); input_sync(dev); /* send pad data */ if (wacom->features->type == WACOM_G4) { - if ((wacom->serial[1] & 0xc0) != (data[7] & 0xf8)) { - wacom->id[1] = 1; - wacom->serial[1] = (data[7] & 0xf8); + /* fist time sending pad data */ + if (wacom->tool[1] != BTN_TOOL_FINGER) { + wacom->id[1] = 0; + wacom->serial[1] = (data[7] & 0x38) >> 2; + } + if (data[7] & 0xf8) { input_report_key(dev, BTN_0, (data[7] & 0x40)); input_report_key(dev, BTN_4, (data[7] & 0x80)); - rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); + if (((data[7] & 0x38) >> 2) == (wacom->serial[1] & 0x0e)) + /* alter REL_WHEEL value so X apps can get it */ + wacom->serial[1] += (wacom->serial[1] & 0x01) ? -1 : 1; + else + wacom->serial[1] = (data[7] & 0x38 ) >> 2; + + /* don't alter the value when there is no wheel event */ + if (wacom->serial[1] == 1) + wacom->serial[1] = 0; + rw = wacom->serial[1]; + rw = (rw & 0x08) ? -(rw & 0x07) : (rw & 0x07); input_report_rel(dev, REL_WHEEL, rw); - input_report_key(dev, BTN_TOOL_FINGER, 0xf0); + wacom->tool[1] = BTN_TOOL_FINGER; + wacom->id[1] = data[7] & 0xf8; + input_report_key(dev, wacom->tool[1], 0xf0); input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); } else if (wacom->id[1]) { wacom->id[1] = 0; - input_report_key(dev, BTN_TOOL_FINGER, 0); + wacom->serial[1] = 0; + input_report_key(dev, wacom->tool[1], 0); input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); } input_sync(dev); @@ -527,31 +516,21 @@ static int wacom_intuos_inout(struct urb *urb) default: /* Unknown tool */ wacom->tool[idx] = BTN_TOOL_PEN; } - if(!((wacom->tool[idx] == BTN_TOOL_LENS) && - ((wacom->features->type == INTUOS312) - || (wacom->features->type == INTUOS319)))) { - input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */ - input_report_key(dev, wacom->tool[idx], 1); - input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - input_sync(dev); - } + input_report_key(dev, wacom->tool[idx], wacom->id[idx]); + input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); + input_sync(dev); return 1; } /* Exit report */ if ((data[1] & 0xfe) == 0x80) { input_report_key(dev, wacom->tool[idx], 0); - input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev); return 1; } - if((wacom->tool[idx] == BTN_TOOL_LENS) && ((wacom->features->type == INTUOS312) - || (wacom->features->type == INTUOS319))) - return 1; - else - return 0; + return 0; } static void wacom_intuos_general(struct urb *urb) @@ -621,9 +600,10 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) /* pad packets. Works as a second tool and is always in prox */ if (data[0] == 12) { /* initiate the pad as a device */ - if (wacom->tool[1] != BTN_TOOL_FINGER) + if (wacom->tool[1] != BTN_TOOL_FINGER) { wacom->tool[1] = BTN_TOOL_FINGER; - + input_report_key(dev, wacom->tool[1], 1); + } input_report_key(dev, BTN_0, (data[5] & 0x01)); input_report_key(dev, BTN_1, (data[5] & 0x02)); input_report_key(dev, BTN_2, (data[5] & 0x04)); @@ -634,11 +614,6 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) input_report_key(dev, BTN_7, (data[6] & 0x08)); input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | data[2]) - input_report_key(dev, wacom->tool[1], 1); - else - input_report_key(dev, wacom->tool[1], 0); input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff); input_sync(dev); goto exit; @@ -701,8 +676,8 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) input_report_key(dev, BTN_LEFT, data[8] & 0x04); input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); input_report_key(dev, BTN_RIGHT, data[8] & 0x10); - input_report_rel(dev, REL_WHEEL, (data[8] & 0x01) - - ((data[8] & 0x02) >> 1)); + input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1) + - (data[8] & 0x01)); /* I3 2D mouse side buttons */ if (wacom->features->type == INTUOS3) { @@ -720,8 +695,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) } } - input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */ - input_report_key(dev, wacom->tool[idx], 1); + input_report_key(dev, wacom->tool[idx], wacom->id[idx]); input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev); @@ -759,8 +733,7 @@ static struct wacom_features wacom_features[] = { { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq }, { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_pl_irq }, { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq }, - { "Wacom DTU710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq }, - { "Wacom DTF521", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq }, + { "Wacom PL710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq }, { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_pl_irq }, { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq }, { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, @@ -771,8 +744,6 @@ static struct wacom_features wacom_features[] = { { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq }, { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq }, { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq }, - { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 15, INTUOS312, wacom_intuos_irq }, - { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 15, INTUOS319, wacom_intuos_irq }, { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_intuos_irq }, { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq }, { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, @@ -808,7 +779,6 @@ static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC3) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, @@ -818,8 +788,6 @@ static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, @@ -852,7 +820,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct input_dev *input_dev; - char rep_data[2], limit = 0; + char rep_data[2] = {0x02, 0x02}; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); input_dev = input_allocate_device(); @@ -889,7 +857,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i input_set_abs_params(input_dev, ABS_X, 0, wacom->features->x_max, 4, 0); input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); - input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); switch (wacom->features->type) { case WACOM_G4: @@ -908,8 +875,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i break; case INTUOS3: - case INTUOS312: - case INTUOS319: case CINTIQ: input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); @@ -951,13 +916,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i input_register_device(wacom->dev); - /* Ask the tablet to report tablet data. Repeat until it succeeds */ - do { - rep_data[0] = 2; - rep_data[1] = 2; - usb_set_report(intf, 3, 2, rep_data, 2); - usb_get_report(intf, 3, 2, rep_data, 2); - } while (rep_data[1] != 2 && limit++ < 5); + /* ask the tablet to report tablet data */ + usb_set_report(intf, 3, 2, rep_data, 2); + /* repeat once (not sure why the first call often fails) */ + usb_set_report(intf, 3, 2, rep_data, 2); usb_set_intfdata(intf, wacom); return 0; diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index 37d2f0ba0..b1d4fd662 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c @@ -813,12 +813,9 @@ static int usb_cleanup(struct yealink_dev *yld, int err) if (yld == NULL) return err; - if (yld->urb_irq) { - usb_kill_urb(yld->urb_irq); - usb_free_urb(yld->urb_irq); - } - if (yld->urb_ctl) - usb_free_urb(yld->urb_ctl); + usb_kill_urb(yld->urb_irq); /* parameter validation in core/urb */ + usb_kill_urb(yld->urb_ctl); /* parameter validation in core/urb */ + if (yld->idev) { if (err) input_free_device(yld->idev); @@ -834,6 +831,9 @@ static int usb_cleanup(struct yealink_dev *yld, int err) if (yld->irq_data) usb_buffer_free(yld->udev, USB_PKT_LEN, yld->irq_data, yld->irq_dma); + + usb_free_urb(yld->urb_irq); /* parameter validation in core/urb */ + usb_free_urb(yld->urb_ctl); /* parameter validation in core/urb */ kfree(yld); return err; } diff --git a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig new file mode 100644 index 000000000..0d3d2cc5d --- /dev/null +++ b/drivers/usb/media/Kconfig @@ -0,0 +1,226 @@ +# +# USB Multimedia device configuration +# +comment "USB Multimedia devices" + depends on USB + +config USB_DABUSB + tristate "DABUSB driver" + depends on USB + ---help--- + A Digital Audio Broadcasting (DAB) Receiver for USB and Linux + brought to you by the DAB-Team + . This driver can be taken + as an example for URB-based bulk, control, and isochronous + transactions. URB's are explained in + . + + To compile this driver as a module, choose M here: the + module will be called dabusb. + +comment "Video4Linux support is needed for USB Multimedia device support" + depends on USB && VIDEO_DEV=n + +config USB_VICAM + tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)" + depends on USB && VIDEO_DEV && EXPERIMENTAL + ---help--- + Say Y here if you have 3com homeconnect camera (vicam). + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" (under Multimedia Devices) to use this driver. + Information on this API and pointers to "v4l" programs may be found + at . + + To compile this driver as a module, choose M here: the + module will be called vicam. + +config USB_DSBR + tristate "D-Link USB FM radio support (EXPERIMENTAL)" + depends on USB && VIDEO_DEV && EXPERIMENTAL + ---help--- + Say Y here if you want to connect this type of radio to your + computer's USB port. Note that the audio is not digital, and + you must connect the line out connector to a sound card or a + set of speakers. + + This driver uses the Video For Linux API. You must enable + (Y or M in config) Video For Linux (under Character Devices) + to use this driver. Information on this API and pointers to + "v4l" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called dsbr100. + +config USB_ET61X251 + tristate "USB ET61X[12]51 PC Camera Controller support" + depends on USB && VIDEO_DEV + ---help--- + Say Y here if you want support for cameras based on Etoms ET61X151 + or ET61X251 PC Camera Controllers. + + See for more informations. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" to use this driver. + + To compile this driver as a module, choose M here: the + module will be called et61x251. + +config USB_IBMCAM + tristate "USB IBM (Xirlink) C-it Camera support" + depends on USB && VIDEO_DEV + ---help--- + Say Y here if you want to connect a IBM "C-It" camera, also known as + "Xirlink PC Camera" to your computer's USB port. For more + information, read . + + This driver uses the Video For Linux API. You must enable + (Y or M in config) Video For Linux (under Character Devices) + to use this driver. Information on this API and pointers to + "v4l" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called ibmcam. + + This camera has several configuration options which + can be specified when you load the module. Read + to learn more. + +config USB_KONICAWC + tristate "USB Konica Webcam support" + depends on USB && VIDEO_DEV + ---help--- + Say Y here if you want support for webcams based on a Konica + chipset. This is known to work with the Intel YC76 webcam. + + This driver uses the Video For Linux API. You must enable + (Y or M in config) Video For Linux (under Character Devices) + to use this driver. Information on this API and pointers to + "v4l" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called konicawc. + +config USB_OV511 + tristate "USB OV511 Camera support" + depends on USB && VIDEO_DEV + ---help--- + Say Y here if you want to connect this type of camera to your + computer's USB port. See for more + information and for a list of supported cameras. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" (under Character Devices) to use this driver. + Information on this API and pointers to "v4l" programs may be found + at . + + To compile this driver as a module, choose M here: the + module will be called ov511. + +config USB_SE401 + tristate "USB SE401 Camera support" + depends on USB && VIDEO_DEV + ---help--- + Say Y here if you want to connect this type of camera to your + computer's USB port. See for more + information and for a list of supported cameras. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" (under Multimedia Devices) to use this driver. + Information on this API and pointers to "v4l" programs may be found + at . + + To compile this driver as a module, choose M here: the + module will be called se401. + +config USB_SN9C102 + tristate "USB SN9C10x PC Camera Controller support" + depends on USB && VIDEO_DEV + ---help--- + Say Y here if you want support for cameras based on SONiX SN9C101, + SN9C102 or SN9C103 PC Camera Controllers. + + See for more informations. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" to use this driver. + + To compile this driver as a module, choose M here: the + module will be called sn9c102. + +config USB_STV680 + tristate "USB STV680 (Pencam) Camera support" + depends on USB && VIDEO_DEV + ---help--- + Say Y here if you want to connect this type of camera to your + computer's USB port. This includes the Pencam line of cameras. + See for more information and for + a list of supported cameras. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" (under Multimedia Devices) to use this driver. + Information on this API and pointers to "v4l" programs may be found + at . + + To compile this driver as a module, choose M here: the + module will be called stv680. + +config USB_W9968CF + tristate "USB W996[87]CF JPEG Dual Mode Camera support" + depends on USB && VIDEO_DEV && I2C && VIDEO_OVCAMCHIP + ---help--- + Say Y here if you want support for cameras based on OV681 or + Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. + + This driver has an optional plugin, which is distributed as a + separate module only (released under GPL). It allows to use higher + resolutions and framerates, but cannot be included in the official + Linux kernel for performance purposes. + + See for more informations. + + This driver uses the Video For Linux and the I2C APIs. It needs the + OmniVision Camera Chip support as well. You must say Y or M to + "Video For Linux", "I2C Support" and "OmniVision Camera Chip + support" to use this driver. + + To compile this driver as a module, choose M here: the + module will be called w9968cf. + +config USB_PWC + tristate "USB Philips Cameras" + depends on USB && VIDEO_DEV + ---help--- + Say Y or M here if you want to use one of these Philips & OEM + webcams: + * Philips PCA645, PCA646 + * Philips PCVC675, PCVC680, PCVC690 + * Philips PCVC720/40, PCVC730, PCVC740, PCVC750 + * Askey VC010 + * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro' + and 'Orbit'/'Sphere' + * Samsung MPC-C10, MPC-C30 + * Creative Webcam 5, Pro Ex + * SOTEC Afina Eye + * Visionite VCS-UC300, VCS-UM100 + + The PCA635, PCVC665 and PCVC720/20 are not supported by this driver + and never will be, but the 665 and 720/20 are supported by other + drivers. + + See for more information and + installation instructions. + + The built-in microphone is enabled by selecting USB Audio support. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" (under Character Devices) to use this driver. + Information on this API and pointers to "v4l" programs may be found + at . + + To compile this driver as a module, choose M here: the + module will be called pwc. diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile new file mode 100644 index 000000000..3957aa1be --- /dev/null +++ b/drivers/usb/media/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for USB Media drivers +# + +sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o +et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o + +obj-$(CONFIG_USB_DABUSB) += dabusb.o +obj-$(CONFIG_USB_DSBR) += dsbr100.o +obj-$(CONFIG_USB_ET61X251) += et61x251.o +obj-$(CONFIG_USB_IBMCAM) += ibmcam.o usbvideo.o ultracam.o +obj-$(CONFIG_USB_KONICAWC) += konicawc.o usbvideo.o +obj-$(CONFIG_USB_OV511) += ov511.o +obj-$(CONFIG_USB_SE401) += se401.o +obj-$(CONFIG_USB_SN9C102) += sn9c102.o +obj-$(CONFIG_USB_STV680) += stv680.o +obj-$(CONFIG_USB_VICAM) += vicam.o usbvideo.o +obj-$(CONFIG_USB_W9968CF) += w9968cf.o +obj-$(CONFIG_USB_PWC) += pwc/ diff --git a/drivers/media/video/dabfirmware.h b/drivers/usb/media/dabfirmware.h similarity index 100% rename from drivers/media/video/dabfirmware.h rename to drivers/usb/media/dabfirmware.h diff --git a/drivers/media/video/dabusb.c b/drivers/usb/media/dabusb.c similarity index 97% rename from drivers/media/video/dabusb.c rename to drivers/usb/media/dabusb.c index b9ba95f5e..18d8eaf40 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/usb/media/dabusb.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "dabusb.h" #include "dabfirmware.h" @@ -86,7 +85,7 @@ static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_ return ret; } /*-------------------------------------------------------------------*/ -#ifdef DEBUG +#ifdef DEBUG static void dump_urb (struct urb *urb) { dbg("urb :%p", urb); @@ -136,7 +135,7 @@ static int dabusb_free_queue (struct list_head *q) for (p = q->next; p != q;) { b = list_entry (p, buff_t, buff_list); -#ifdef DEBUG +#ifdef DEBUG dump_urb(b->purb); #endif kfree(b->purb->transfer_buffer); @@ -218,11 +217,12 @@ static int dabusb_alloc_buffers (pdabusb_t s) pipesize, packets, transfer_buffer_length); while (buffers < (s->total_buffer_size << 10)) { - b = (pbuff_t) kzalloc (sizeof (buff_t), GFP_KERNEL); + b = (pbuff_t) kmalloc (sizeof (buff_t), GFP_KERNEL); if (!b) { - err("kzalloc(sizeof(buff_t))==NULL"); + err("kmalloc(sizeof(buff_t))==NULL"); goto err; } + memset (b, 0, sizeof (buff_t)); b->s = s; b->purb = usb_alloc_urb(packets, GFP_KERNEL); if (!b->purb) { @@ -287,7 +287,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) } } - + if( ret == -EPIPE ) { warn("CLEAR_FEATURE request to remove STALL condition."); if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe))) @@ -328,7 +328,7 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname) PINTEL_HEX_RECORD ptr = firmware; dbg("Enter dabusb_loadmem (internal)"); - + ret = dabusb_8051_reset (s, 1); while (ptr->Type == 0) { @@ -449,7 +449,7 @@ static int dabusb_startrek (pdabusb_t s) if (!list_empty (&s->free_buff_list)) { pbuff_t end; int ret; - + while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) { dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list); @@ -506,7 +506,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l err("error: rec_buf_list is empty"); goto err; } - + b = list_entry (s->rec_buff_list.next, buff_t, buff_list); purb = b->purb; @@ -571,7 +571,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l s->readptr = 0; } } - err: //mutex_unlock(&s->mutex); + err: //up(&s->mutex); return ret; } @@ -586,10 +586,10 @@ static int dabusb_open (struct inode *inode, struct file *file) s = &dabusb[devnum - DABUSB_MINOR]; dbg("dabusb_open"); - mutex_lock(&s->mutex); + down (&s->mutex); while (!s->usbdev || s->opened) { - mutex_unlock(&s->mutex); + up (&s->mutex); if (file->f_flags & O_NONBLOCK) { return -EBUSY; @@ -599,15 +599,15 @@ static int dabusb_open (struct inode *inode, struct file *file) if (signal_pending (current)) { return -EAGAIN; } - mutex_lock(&s->mutex); + down (&s->mutex); } if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { - mutex_unlock(&s->mutex); + up(&s->mutex); err("set_interface failed"); return -EINVAL; } s->opened = 1; - mutex_unlock(&s->mutex); + up (&s->mutex); file->f_pos = 0; file->private_data = s; @@ -621,10 +621,10 @@ static int dabusb_release (struct inode *inode, struct file *file) dbg("dabusb_release"); - mutex_lock(&s->mutex); + down (&s->mutex); dabusb_stop (s); dabusb_free_buffers (s); - mutex_unlock(&s->mutex); + up (&s->mutex); if (!s->remove_pending) { if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) @@ -649,10 +649,10 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm if (s->remove_pending) return -EIO; - mutex_lock(&s->mutex); + down (&s->mutex); if (!s->usbdev) { - mutex_unlock(&s->mutex); + up (&s->mutex); return -EIO; } @@ -692,7 +692,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm ret = -ENOIOCTLCMD; break; } - mutex_unlock(&s->mutex); + up (&s->mutex); return ret; } @@ -738,7 +738,7 @@ static int dabusb_probe (struct usb_interface *intf, s = &dabusb[intf->minor]; - mutex_lock(&s->mutex); + down (&s->mutex); s->remove_pending = 0; s->usbdev = usbdev; s->devnum = intf->minor; @@ -761,7 +761,7 @@ static int dabusb_probe (struct usb_interface *intf, } dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber); usb_set_intfdata (intf, s); - mutex_unlock(&s->mutex); + up (&s->mutex); retval = usb_register_dev(intf, &dabusb_class); if (retval) { @@ -772,7 +772,7 @@ static int dabusb_probe (struct usb_interface *intf, return 0; reject: - mutex_unlock(&s->mutex); + up (&s->mutex); s->usbdev = NULL; return -ENODEV; } @@ -783,9 +783,9 @@ static void dabusb_disconnect (struct usb_interface *intf) pdabusb_t s = usb_get_intfdata (intf); dbg("dabusb_disconnect"); - + init_waitqueue_entry(&__wait, current); - + usb_set_intfdata (intf, NULL); if (s) { usb_deregister_dev (intf, &dabusb_class); @@ -797,7 +797,7 @@ static void dabusb_disconnect (struct usb_interface *intf) schedule(); current->state = TASK_RUNNING; remove_wait_queue(&s->remove_ok, &__wait); - + s->usbdev = NULL; s->overruns = 0; } @@ -829,7 +829,7 @@ static int __init dabusb_init (void) for (u = 0; u < NRDABUSB; u++) { pdabusb_t s = &dabusb[u]; memset (s, 0, sizeof (dabusb_t)); - mutex_init (&s->mutex); + init_MUTEX (&s->mutex); s->usbdev = NULL; s->total_buffer_size = buffers; init_waitqueue_head (&s->wait); diff --git a/drivers/media/video/dabusb.h b/drivers/usb/media/dabusb.h similarity index 94% rename from drivers/media/video/dabusb.h rename to drivers/usb/media/dabusb.h index 00eb34c86..10b666e43 100644 --- a/drivers/media/video/dabusb.h +++ b/drivers/usb/media/dabusb.h @@ -10,7 +10,7 @@ typedef struct #define DABUSB_VERSION 0x1000 #define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t) #define IOCTL_DAB_OVERRUNS _IOR('d', 0x15, int) -#define IOCTL_DAB_VERSION _IOR('d', 0x3f, int) +#define IOCTL_DAB_VERSION _IOR('d', 0x3f, int) #ifdef __KERNEL__ @@ -18,7 +18,7 @@ typedef enum { _stopped=0, _started } driver_state_t; typedef struct { - struct mutex mutex; + struct semaphore mutex; struct usb_device *usbdev; wait_queue_head_t wait; wait_queue_head_t remove_ok; @@ -36,7 +36,7 @@ typedef struct struct list_head rec_buff_list; } dabusb_t,*pdabusb_t; -typedef struct +typedef struct { pdabusb_t s; struct urb *purb; diff --git a/drivers/media/video/dsbr100.c b/drivers/usb/media/dsbr100.c similarity index 92% rename from drivers/media/video/dsbr100.c rename to drivers/usb/media/dsbr100.c index 3b4e9985c..25646804d 100644 --- a/drivers/media/video/dsbr100.c +++ b/drivers/usb/media/dsbr100.c @@ -37,28 +37,28 @@ Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing Version 0.30: - Markus: Updates for 2.5.x kernel and more ISO compliant source + Markus: Updates for 2.5.x kernel and more ISO compliant source Version 0.25: - PSL and Markus: Cleanup, radio now doesn't stop on device close + PSL and Markus: Cleanup, radio now doesn't stop on device close Version 0.24: - Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally + Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally right. Some minor cleanup, improved standalone compilation Version 0.23: - Markus: Sign extension bug fixed by declaring transfer_buffer unsigned + Markus: Sign extension bug fixed by declaring transfer_buffer unsigned Version 0.22: - Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns, + Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns, thanks to Mike Cox for pointing the problem out. Version 0.21: - Markus: Minor cleanup, warnings if something goes wrong, lame attempt + Markus: Minor cleanup, warnings if something goes wrong, lame attempt to adhere to Documentation/CodingStyle - Version 0.2: - Brad Hards : Fixes to make it work as non-module + Version 0.2: + Brad Hards : Fixes to make it work as non-module Markus: Copyright clarification Version 0.01: Markus: initial release @@ -163,11 +163,11 @@ static struct usb_driver usb_dsbr100_driver = { static int dsbr100_start(dsbr100_device *radio) { if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, + USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x00, 0xC7, radio->transfer_buffer, 8, 300)<0 || usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - DSB100_ONOFF, + DSB100_ONOFF, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x01, 0x00, radio->transfer_buffer, 8, 300)<0) return -1; @@ -179,11 +179,11 @@ static int dsbr100_start(dsbr100_device *radio) static int dsbr100_stop(dsbr100_device *radio) { if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, + USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x16, 0x1C, radio->transfer_buffer, 8, 300)<0 || usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - DSB100_ONOFF, + DSB100_ONOFF, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x00, 0x00, radio->transfer_buffer, 8, 300)<0) return -1; @@ -195,16 +195,16 @@ static int dsbr100_setfreq(dsbr100_device *radio, int freq) { freq = (freq/16*80)/1000+856; if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - DSB100_TUNE, + DSB100_TUNE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - (freq>>8)&0x00ff, freq&0xff, + (freq>>8)&0x00ff, freq&0xff, radio->transfer_buffer, 8, 300)<0 || usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, + USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x96, 0xB7, radio->transfer_buffer, 8, 300)<0 || usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, + USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x00, 0x24, radio->transfer_buffer, 8, 300)<0) { radio->stereo = -1; @@ -219,7 +219,7 @@ sees a stereo signal or not. Pity. */ static void dsbr100_getstat(dsbr100_device *radio) { if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, + USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x00 , 0x24, radio->transfer_buffer, 8, 300)<0) radio->stereo = -1; @@ -232,7 +232,7 @@ static void dsbr100_getstat(dsbr100_device *radio) /* check if the device is present and register with v4l and usb if it is */ -static int usb_dsbr100_probe(struct usb_interface *intf, +static int usb_dsbr100_probe(struct usb_interface *intf, const struct usb_device_id *id) { dsbr100_device *radio; @@ -243,7 +243,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf, kfree(radio); return -ENOMEM; } - memcpy(radio->videodev, &dsbr100_videodev_template, + memcpy(radio->videodev, &dsbr100_videodev_template, sizeof(dsbr100_videodev_template)); radio->removed = 0; radio->users = 0; @@ -310,7 +310,7 @@ static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file, struct video_tuner *v = arg; dsbr100_getstat(radio); - if(v->tuner) /* Only 1 tuner */ + if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow = FREQ_MIN*FREQ_MUL; v->rangehigh = FREQ_MAX*FREQ_MUL; @@ -355,12 +355,12 @@ static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file, v->volume = 1; v->step = 1; strcpy(v->name, "Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if (v->audio) + if (v->audio) return -EINVAL; if (v->flags&VIDEO_AUDIO_MUTE) { if (dsbr100_stop(radio)==-1) diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/usb/media/ibmcam.c similarity index 99% rename from drivers/media/video/usbvideo/ibmcam.c rename to drivers/usb/media/ibmcam.c index 76f771b6a..a42c22294 100644 --- a/drivers/media/video/usbvideo/ibmcam.c +++ b/drivers/usb/media/ibmcam.c @@ -1300,11 +1300,11 @@ static void ibmcam_model2_Packet1(struct uvd *uvd, unsigned short v1, unsigned s /* * ibmcam_model3_Packet1() * - * 00_0078_012d + * 00_0078_012d * 00_0097_012f - * 00_d141_0124 + * 00_d141_0124 * 00_0096_0127 - * 00_fea8_0124 + * 00_fea8_0124 */ static void ibmcam_model3_Packet1(struct uvd *uvd, unsigned short v1, unsigned short v2) { @@ -2687,7 +2687,7 @@ static void ibmcam_model4_setup_after_video_if(struct uvd *uvd) ibmcam_veio(uvd, 0, 0x0004, 0x0127); ibmcam_veio(uvd, 0, 0xfea8, 0x0124); ibmcam_veio(uvd, 0, 0x00c0, 0x010c); - break; + break; } usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp)); } @@ -3238,7 +3238,7 @@ static void ibmcam_model3_setup_after_video_if(struct uvd *uvd) {0, 0x0062, 0x0107}, {0, 0x0003, 0x0111}, }; -#define NUM_INIT_DATA +#define NUM_INIT_DATA unsigned short compression = 0; /* 0=none, 7=best frame rate */ int f_rate; /* 0=Fastest 7=slowest */ diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/usb/media/konicawc.c similarity index 97% rename from drivers/media/video/usbvideo/konicawc.c rename to drivers/usb/media/konicawc.c index c11f5d46b..e2ede5835 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/usb/media/konicawc.c @@ -36,7 +36,7 @@ enum ctrl_req { SetWhitebal = 0x01, SetBrightness = 0x02, - SetSharpness = 0x03, + SetSharpness = 0x03, SetContrast = 0x04, SetSaturation = 0x05, }; @@ -47,7 +47,7 @@ enum frame_sizes { SIZE_160X136 = 1, SIZE_176X144 = 2, SIZE_320X240 = 3, - + }; #define MAX_FRAME_SIZE SIZE_320X240 @@ -69,7 +69,7 @@ static const int debug = 0; /* Some default values for initial camera settings, can be set by modprobe */ -static int size; +static int size; static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */ static int brightness = MAX_BRIGHTNESS/2; static int contrast = MAX_CONTRAST/2; @@ -132,24 +132,24 @@ struct konicawc { static int konicawc_ctrl_msg(struct uvd *uvd, u8 dir, u8 request, u16 value, u16 index, void *buf, int len) { - int retval = usb_control_msg(uvd->dev, + int retval = usb_control_msg(uvd->dev, dir ? usb_rcvctrlpipe(uvd->dev, 0) : usb_sndctrlpipe(uvd->dev, 0), request, 0x40 | dir, value, index, buf, len, 1000); - return retval < 0 ? retval : 0; + return retval < 0 ? retval : 0; } static inline void konicawc_camera_on(struct uvd *uvd) { - DEBUG(0, "camera on"); - konicawc_set_misc(uvd, 0x2, 1, 0x0b); + DEBUG(0, "camera on"); + konicawc_set_misc(uvd, 0x2, 1, 0x0b); } static inline void konicawc_camera_off(struct uvd *uvd) { - DEBUG(0, "camera off"); - konicawc_set_misc(uvd, 0x2, 0, 0x0b); + DEBUG(0, "camera off"); + konicawc_set_misc(uvd, 0x2, 0, 0x0b); } @@ -317,7 +317,7 @@ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct ur button = !!(sts & 0x40); sts &= ~0x40; } - + /* work out the button status, but don't do anything with it for now */ @@ -331,7 +331,7 @@ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct ur discard++; continue; } - + if((sts > 0x01) && (sts < 0x80)) { info("unknown status %2.2x", sts); bad++; @@ -350,7 +350,7 @@ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct ur DEBUG(2, "found initial image"); cam->lastframe = -1; } - + marker[3] = sts & 0x7F; RingQueue_Enqueue(&uvd->dp, marker, 4); totlen += 4; @@ -367,16 +367,16 @@ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct ur static void resubmit_urb(struct uvd *uvd, struct urb *urb) { - int i, ret; - for (i = 0; i < FRAMES_PER_DESC; i++) { - urb->iso_frame_desc[i].status = 0; - } - urb->dev = uvd->dev; - urb->status = 0; + int i, ret; + for (i = 0; i < FRAMES_PER_DESC; i++) { + urb->iso_frame_desc[i].status = 0; + } + urb->dev = uvd->dev; + urb->status = 0; ret = usb_submit_urb(urb, GFP_ATOMIC); DEBUG(3, "submitting urb of length %d", urb->transfer_buffer_length); - if(ret) - err("usb_submit_urb error (%d)", ret); + if(ret) + err("usb_submit_urb error (%d)", ret); } @@ -490,7 +490,7 @@ static int konicawc_start_data(struct uvd *uvd) } cam->last_data_urb = NULL; - + /* Submit all URBs */ for (i=0; i < USBVIDEO_NUMSBUF; i++) { errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL); @@ -539,7 +539,7 @@ static void konicawc_stop_data(struct uvd *uvd) static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame) -{ +{ struct konicawc *cam = (struct konicawc *)uvd->user_data; int maxline = cam->maxline; int yplanesz = cam->yplanesz; @@ -583,13 +583,13 @@ static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame) if(frame->scanstate == ScanState_Scanning) return; - + /* Try to move data from queue into frame buffer * We get data in blocks of 384 bytes made up of: * 256 Y, 64 U, 64 V. * This needs to be written out as a Y plane, a U plane and a V plane. */ - + while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) { /* Y */ RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256); diff --git a/drivers/media/video/ov511.c b/drivers/usb/media/ov511.c similarity index 98% rename from drivers/media/video/ov511.c rename to drivers/usb/media/ov511.c index fdc8e3f13..51e9cc06f 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/usb/media/ov511.c @@ -15,7 +15,7 @@ * * Based on the Linux CPiA driver written by Peter Pregler, * Scott J. Bertin and Johannes Erdfelt. - * + * * Please see the file: Documentation/usb/ov511.txt * and the website at: http://alpha.dyndns.org/ov511 * for more info. @@ -365,14 +365,14 @@ reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) PDEBUG(5, "0x%02X:0x%02X", reg, value); - mutex_lock(&ov->cbuf_lock); + down(&ov->cbuf_lock); ov->cbuf[0] = value; rc = usb_control_msg(ov->dev, usb_sndctrlpipe(ov->dev, 0), (ov->bclass == BCL_OV518)?1:2 /* REG_IO */, USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, (__u16)reg, &ov->cbuf[0], 1, 1000); - mutex_unlock(&ov->cbuf_lock); + up(&ov->cbuf_lock); if (rc < 0) err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc)); @@ -387,7 +387,7 @@ reg_r(struct usb_ov511 *ov, unsigned char reg) { int rc; - mutex_lock(&ov->cbuf_lock); + down(&ov->cbuf_lock); rc = usb_control_msg(ov->dev, usb_rcvctrlpipe(ov->dev, 0), (ov->bclass == BCL_OV518)?1:3 /* REG_IO */, @@ -401,7 +401,7 @@ reg_r(struct usb_ov511 *ov, unsigned char reg) PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]); } - mutex_unlock(&ov->cbuf_lock); + up(&ov->cbuf_lock); return rc; } @@ -433,7 +433,7 @@ reg_w_mask(struct usb_ov511 *ov, return (reg_w(ov, reg, newval)); } -/* +/* * Writes multiple (n) byte value to a single register. Only valid with certain * registers (0x30 and 0xc4 - 0xce). */ @@ -444,7 +444,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n) PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n); - mutex_lock(&ov->cbuf_lock); + down(&ov->cbuf_lock); *((__le32 *)ov->cbuf) = __cpu_to_le32(val); @@ -453,7 +453,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n) 1 /* REG_IO */, USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, (__u16)reg, ov->cbuf, n, 1000); - mutex_unlock(&ov->cbuf_lock); + up(&ov->cbuf_lock); if (rc < 0) err("reg write multiple: error %d: %s", rc, @@ -629,7 +629,7 @@ ov511_i2c_write_internal(struct usb_ov511 *ov, /* Retry until idle */ do rc = reg_r(ov, R511_I2C_CTL); - while (rc > 0 && ((rc&1) == 0)); + while (rc > 0 && ((rc&1) == 0)); if (rc < 0) break; @@ -768,14 +768,14 @@ i2c_r(struct usb_ov511 *ov, unsigned char reg) { int rc; - mutex_lock(&ov->i2c_lock); + down(&ov->i2c_lock); if (ov->bclass == BCL_OV518) rc = ov518_i2c_read_internal(ov, reg); else rc = ov511_i2c_read_internal(ov, reg); - mutex_unlock(&ov->i2c_lock); + up(&ov->i2c_lock); return rc; } @@ -785,14 +785,14 @@ i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) { int rc; - mutex_lock(&ov->i2c_lock); + down(&ov->i2c_lock); if (ov->bclass == BCL_OV518) rc = ov518_i2c_write_internal(ov, reg, value); else rc = ov511_i2c_write_internal(ov, reg, value); - mutex_unlock(&ov->i2c_lock); + up(&ov->i2c_lock); return rc; } @@ -842,9 +842,9 @@ i2c_w_mask(struct usb_ov511 *ov, { int rc; - mutex_lock(&ov->i2c_lock); + down(&ov->i2c_lock); rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask); - mutex_unlock(&ov->i2c_lock); + up(&ov->i2c_lock); return rc; } @@ -880,7 +880,7 @@ i2c_w_slave(struct usb_ov511 *ov, { int rc = 0; - mutex_lock(&ov->i2c_lock); + down(&ov->i2c_lock); /* Set new slave IDs */ rc = i2c_set_slave_internal(ov, slave); @@ -894,7 +894,7 @@ out: if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) err("Couldn't restore primary I2C slave"); - mutex_unlock(&ov->i2c_lock); + up(&ov->i2c_lock); return rc; } @@ -906,7 +906,7 @@ i2c_r_slave(struct usb_ov511 *ov, { int rc; - mutex_lock(&ov->i2c_lock); + down(&ov->i2c_lock); /* Set new slave IDs */ rc = i2c_set_slave_internal(ov, slave); @@ -923,7 +923,7 @@ out: if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) err("Couldn't restore primary I2C slave"); - mutex_unlock(&ov->i2c_lock); + up(&ov->i2c_lock); return rc; } @@ -933,7 +933,7 @@ ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) { int rc; - mutex_lock(&ov->i2c_lock); + down(&ov->i2c_lock); rc = i2c_set_slave_internal(ov, sid); if (rc < 0) @@ -942,7 +942,7 @@ ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) // FIXME: Is this actually necessary? rc = ov51x_reset(ov, OV511_RESET_NOREGS); out: - mutex_unlock(&ov->i2c_lock); + up(&ov->i2c_lock); return rc; } @@ -1752,7 +1752,7 @@ sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p) ov->whiteness = p->whiteness; /* Don't return error if a setting is unsupported, or rest of settings - * will not be performed */ + * will not be performed */ rc = sensor_set_contrast(ov, p->contrast); if (FATAL_ERROR(rc)) @@ -1781,7 +1781,7 @@ sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p) PDEBUG(4, "sensor_get_picture"); /* Don't return error if a setting is unsupported, or rest of settings - * will not be performed */ + * will not be performed */ rc = sensor_get_contrast(ov, &(p->contrast)); if (FATAL_ERROR(rc)) @@ -2251,7 +2251,7 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height, /******** Clock programming ********/ - /* The OV6620 needs special handling. This prevents the + /* The OV6620 needs special handling. This prevents the * severe banding that normally occurs */ if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) { @@ -2326,7 +2326,7 @@ set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode, int sub_flag) { int ret; - int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize; + int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize; int hoffset, voffset, hwscale = 0, vwscale = 0; /* The different sensor ICs handle setting up of window differently. @@ -2575,7 +2575,7 @@ ov518_mode_init_regs(struct usb_ov511 *ov, /* OV518 needs U and V swapped */ i2c_w_mask(ov, 0x15, 0x00, 0x01); - if (mode == VIDEO_PALETTE_GREY) { + if (mode == VIDEO_PALETTE_GREY) { /* Set 16-bit input format (UV data are ignored) */ reg_w_mask(ov, 0x20, 0x00, 0x08); @@ -2894,7 +2894,7 @@ make_8x8(unsigned char *pIn, unsigned char *pOut, int w) * ... ... ... * 56 57 ... 63 120 121 ... 127 248 249 ... 255 * - */ + */ static void yuv400raw_to_yuv400p(struct ov511_frame *frame, unsigned char *pIn0, unsigned char *pOut0) @@ -2923,7 +2923,7 @@ yuv400raw_to_yuv400p(struct ov511_frame *frame, * * 0 1 ... 7 * 8 9 ... 15 - * ... + * ... * 56 57 ... 63 * * U and V are shipped at half resolution (1 U,V sample -> one 2x2 block). @@ -3034,7 +3034,7 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame, */ static void deinterlace(struct ov511_frame *frame, int rawformat, - unsigned char *pIn0, unsigned char *pOut0) + unsigned char *pIn0, unsigned char *pOut0) { const int fieldheight = frame->rawheight / 2; const int fieldpix = fieldheight * frame->rawwidth; @@ -3112,7 +3112,7 @@ ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame) frame->tempdata); deinterlace(frame, RAWFMT_YUV400, frame->tempdata, - frame->data); + frame->data); } else { if (frame->compressed) decompress(ov, frame, frame->rawdata, @@ -3136,7 +3136,7 @@ ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame) frame->tempdata); deinterlace(frame, RAWFMT_YUV420, frame->tempdata, - frame->data); + frame->data); } else { if (frame->compressed) decompress(ov, frame, frame->rawdata, frame->data); @@ -3226,7 +3226,7 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) frame->rawwidth = ((int)(in[9]) + 1) * 8; frame->rawheight = ((int)(in[10]) + 1) * 8; - PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d", + PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d", ov->curframe, pnum, frame->rawwidth, frame->rawheight, frame->bytes_recvd); @@ -3527,10 +3527,10 @@ ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs) return; } - if (urb->status == -ENOENT || urb->status == -ECONNRESET) { - PDEBUG(4, "URB unlinked"); - return; - } + if (urb->status == -ENOENT || urb->status == -ECONNRESET) { + PDEBUG(4, "URB unlinked"); + return; + } if (urb->status != -EINPROGRESS && urb->status != 0) { err("ERROR: urb->status=%d: %s", urb->status, @@ -3832,7 +3832,7 @@ ov51x_alloc(struct usb_ov511 *ov) const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h); PDEBUG(4, "entered"); - mutex_lock(&ov->buf_lock); + down(&ov->buf_lock); if (ov->buf_state == BUF_ALLOCATED) goto out; @@ -3879,12 +3879,12 @@ ov51x_alloc(struct usb_ov511 *ov) ov->buf_state = BUF_ALLOCATED; out: - mutex_unlock(&ov->buf_lock); + up(&ov->buf_lock); PDEBUG(4, "leaving"); return 0; error: ov51x_do_dealloc(ov); - mutex_unlock(&ov->buf_lock); + up(&ov->buf_lock); PDEBUG(4, "errored"); return -ENOMEM; } @@ -3893,9 +3893,9 @@ static void ov51x_dealloc(struct usb_ov511 *ov) { PDEBUG(4, "entered"); - mutex_lock(&ov->buf_lock); + down(&ov->buf_lock); ov51x_do_dealloc(ov); - mutex_unlock(&ov->buf_lock); + up(&ov->buf_lock); PDEBUG(4, "leaving"); } @@ -3914,7 +3914,7 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) PDEBUG(4, "opening"); - mutex_lock(&ov->lock); + down(&ov->lock); err = -EBUSY; if (ov->user) @@ -3958,7 +3958,7 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) ov51x_led_control(ov, 1); out: - mutex_unlock(&ov->lock); + up(&ov->lock); return err; } @@ -3970,7 +3970,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) PDEBUG(4, "ov511_close"); - mutex_lock(&ov->lock); + down(&ov->lock); ov->user--; ov51x_stop_isoc(ov); @@ -3981,15 +3981,15 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) if (ov->dev) ov51x_dealloc(ov); - mutex_unlock(&ov->lock); + up(&ov->lock); /* Device unplugged while open. Only a minimum of unregistration is done * here; the disconnect callback already did the rest. */ if (!ov->dev) { - mutex_lock(&ov->cbuf_lock); + down(&ov->cbuf_lock); kfree(ov->cbuf); ov->cbuf = NULL; - mutex_unlock(&ov->cbuf_lock); + up(&ov->cbuf_lock); ov51x_dealloc(ov); kfree(ov); @@ -4449,12 +4449,12 @@ ov51x_v4l1_ioctl(struct inode *inode, struct file *file, struct usb_ov511 *ov = video_get_drvdata(vdev); int rc; - if (mutex_lock_interruptible(&ov->lock)) + if (down_interruptible(&ov->lock)) return -EINTR; rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal); - mutex_unlock(&ov->lock); + up(&ov->lock); return rc; } @@ -4468,7 +4468,7 @@ ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos) int i, rc = 0, frmx = -1; struct ov511_frame *frame; - if (mutex_lock_interruptible(&ov->lock)) + if (down_interruptible(&ov->lock)) return -EINTR; PDEBUG(4, "%ld bytes, noblock=%d", count, noblock); @@ -4604,11 +4604,11 @@ restart: PDEBUG(4, "read finished, returning %ld (sweet)", count); - mutex_unlock(&ov->lock); + up(&ov->lock); return count; error: - mutex_unlock(&ov->lock); + up(&ov->lock); return rc; } @@ -4627,18 +4627,18 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) PDEBUG(4, "mmap: %ld (%lX) bytes", size, size); if (size > (((OV511_NUMFRAMES - * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight) - + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))) + * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight) + + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))) return -EINVAL; - if (mutex_lock_interruptible(&ov->lock)) + if (down_interruptible(&ov->lock)) return -EINTR; pos = (unsigned long)ov->fbuf; while (size > 0) { page = vmalloc_to_pfn((void *)pos); if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { - mutex_unlock(&ov->lock); + up(&ov->lock); return -EAGAIN; } start += PAGE_SIZE; @@ -4649,7 +4649,7 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) size = 0; } - mutex_unlock(&ov->lock); + up(&ov->lock); return 0; } @@ -5062,7 +5062,7 @@ ov6xx0_configure(struct usb_ov511 *ov) } /* This initializes the KS0127 and KS0127B video decoders. */ -static int +static int ks0127_configure(struct usb_ov511 *ov) { int rc; @@ -5193,7 +5193,7 @@ saa7111a_configure(struct usb_ov511 *ov) return -1; /* Detect version of decoder. This must be done after writing the - * initial regs or the decoder will lock up. */ + * initial regs or the decoder will lock up. */ rc = i2c_r(ov, 0x00); if (rc < 0) { @@ -5216,13 +5216,13 @@ saa7111a_configure(struct usb_ov511 *ov) } /* This initializes the OV511/OV511+ and the sensor */ -static int +static int ov511_configure(struct usb_ov511 *ov) { static struct ov511_regvals aRegvalsInit511[] = { { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, - { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, - { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, + { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, { OV511_REG_BUS, R51x_SYS_RESET, 0x3f }, { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, @@ -5269,7 +5269,7 @@ ov511_configure(struct usb_ov511 *ov) err("Please notify " EMAIL " of the name,"); err("manufacturer, model, and this number of your camera."); err("Also include the output of the detection process."); - } + } if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */ ov->pal = 1; @@ -5336,17 +5336,17 @@ ov511_configure(struct usb_ov511 *ov) if (i2c_w(ov, 0x10, 0x00) < 0) { err("Can't determine sensor slave IDs"); - goto error; + goto error; } else { if (ks0127_configure(ov) < 0) { err("Failed to configure KS0127"); - goto error; + goto error; } } } else { if (saa7111a_configure(ov) < 0) { err("Failed to configure SAA7111A"); - goto error; + goto error; } } } else { @@ -5356,13 +5356,13 @@ ov511_configure(struct usb_ov511 *ov) } else { if (ov6xx0_configure(ov) < 0) { err("Failed to configure OV6xx0"); - goto error; + goto error; } } } else { if (ov7xx0_configure(ov) < 0) { err("Failed to configure OV7xx0"); - goto error; + goto error; } } @@ -5381,12 +5381,12 @@ ov518_configure(struct usb_ov511 *ov) /* For 518 and 518+ */ static struct ov511_regvals aRegvalsInit518[] = { { OV511_REG_BUS, R51x_SYS_RESET, 0x40 }, - { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, - { OV511_REG_BUS, R51x_SYS_RESET, 0x3e }, + { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x3e }, { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, { OV511_REG_BUS, R51x_SYS_RESET, 0x00 }, { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, - { OV511_REG_BUS, 0x46, 0x00 }, + { OV511_REG_BUS, 0x46, 0x00 }, { OV511_REG_BUS, 0x5d, 0x03 }, { OV511_DONE_BUS, 0x0, 0x00}, }; @@ -5517,7 +5517,7 @@ ov518_configure(struct usb_ov511 *ov) if (init_ov_sensor(ov) < 0) { err("Can't determine sensor slave IDs"); - goto error; + goto error; } else { err("Detected unsupported OV8xx0 sensor"); goto error; @@ -5525,13 +5525,13 @@ ov518_configure(struct usb_ov511 *ov) } else { if (ov6xx0_configure(ov) < 0) { err("Failed to configure OV6xx0"); - goto error; + goto error; } } } else { if (ov7xx0_configure(ov) < 0) { err("Failed to configure OV7xx0"); - goto error; + goto error; } } @@ -5564,28 +5564,28 @@ static ssize_t show_custom_id(struct class_device *cd, char *buf) { struct usb_ov511 *ov = cd_to_ov(cd); return sprintf(buf, "%d\n", ov->customid); -} +} static CLASS_DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL); static ssize_t show_model(struct class_device *cd, char *buf) { struct usb_ov511 *ov = cd_to_ov(cd); return sprintf(buf, "%s\n", ov->desc); -} +} static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL); static ssize_t show_bridge(struct class_device *cd, char *buf) { struct usb_ov511 *ov = cd_to_ov(cd); return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge)); -} +} static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL); static ssize_t show_sensor(struct class_device *cd, char *buf) { struct usb_ov511 *ov = cd_to_ov(cd); return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor)); -} +} static CLASS_DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL); static ssize_t show_brightness(struct class_device *cd, char *buf) @@ -5597,7 +5597,7 @@ static ssize_t show_brightness(struct class_device *cd, char *buf) return -ENODEV; sensor_get_brightness(ov, &x); return sprintf(buf, "%d\n", x >> 8); -} +} static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); static ssize_t show_saturation(struct class_device *cd, char *buf) @@ -5609,7 +5609,7 @@ static ssize_t show_saturation(struct class_device *cd, char *buf) return -ENODEV; sensor_get_saturation(ov, &x); return sprintf(buf, "%d\n", x >> 8); -} +} static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); static ssize_t show_contrast(struct class_device *cd, char *buf) @@ -5621,7 +5621,7 @@ static ssize_t show_contrast(struct class_device *cd, char *buf) return -ENODEV; sensor_get_contrast(ov, &x); return sprintf(buf, "%d\n", x >> 8); -} +} static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); static ssize_t show_hue(struct class_device *cd, char *buf) @@ -5633,19 +5633,19 @@ static ssize_t show_hue(struct class_device *cd, char *buf) return -ENODEV; sensor_get_hue(ov, &x); return sprintf(buf, "%d\n", x >> 8); -} +} static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); static ssize_t show_exposure(struct class_device *cd, char *buf) { struct usb_ov511 *ov = cd_to_ov(cd); - unsigned char exp = 0; + unsigned char exp; if (!ov->dev) return -ENODEV; sensor_get_exposure(ov, &exp); return sprintf(buf, "%d\n", exp >> 8); -} +} static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL); static void ov_create_sysfs(struct video_device *vdev) @@ -5686,11 +5686,13 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) if (idesc->bInterfaceSubClass != 0x00) return -ENODEV; - if ((ov = kzalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { + if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { err("couldn't kmalloc ov struct"); goto error_out; } + memset(ov, 0, sizeof(*ov)); + ov->dev = dev; ov->iface = idesc->bInterfaceNumber; ov->led_policy = led; @@ -5736,10 +5738,11 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) init_waitqueue_head(&ov->wq); - mutex_init(&ov->lock); /* to 1 == available */ - mutex_init(&ov->buf_lock); - mutex_init(&ov->i2c_lock); - mutex_init(&ov->cbuf_lock); + init_MUTEX(&ov->lock); /* to 1 == available */ + init_MUTEX(&ov->buf_lock); + init_MUTEX(&ov->param_lock); + init_MUTEX(&ov->i2c_lock); + init_MUTEX(&ov->cbuf_lock); ov->buf_state = BUF_NOT_ALLOCATED; @@ -5830,10 +5833,10 @@ error: } if (ov->cbuf) { - mutex_lock(&ov->cbuf_lock); + down(&ov->cbuf_lock); kfree(ov->cbuf); ov->cbuf = NULL; - mutex_unlock(&ov->cbuf_lock); + up(&ov->cbuf_lock); } kfree(ov); @@ -5878,10 +5881,10 @@ ov51x_disconnect(struct usb_interface *intf) /* Free the memory */ if (ov && !ov->user) { - mutex_lock(&ov->cbuf_lock); + down(&ov->cbuf_lock); kfree(ov->cbuf); ov->cbuf = NULL; - mutex_unlock(&ov->cbuf_lock); + up(&ov->cbuf_lock); ov51x_dealloc(ov); kfree(ov); diff --git a/drivers/media/video/ov511.h b/drivers/usb/media/ov511.h similarity index 97% rename from drivers/media/video/ov511.h rename to drivers/usb/media/ov511.h index 12b3d51e1..086509a13 100644 --- a/drivers/media/video/ov511.h +++ b/drivers/usb/media/ov511.h @@ -5,7 +5,6 @@ #include #include #include -#include #define OV511_DEBUG /* Turn on debug messages */ @@ -130,7 +129,7 @@ #define R511_COMP_QVY 0x76 #define R511_COMP_QVUV 0x77 #define R511_COMP_EN 0x78 -#define R511_COMP_LUT_EN 0x79 +#define R511_COMP_LUT_EN 0x79 #define R511_COMP_LUT_BEGIN 0x80 /* --------------------------------- */ @@ -436,7 +435,7 @@ struct usb_ov511 { int led_policy; /* LED: off|on|auto; OV511+ only */ - struct mutex lock; /* Serializes user-accessible operations */ + struct semaphore lock; /* Serializes user-accessible operations */ int user; /* user count for exclusive use */ int streaming; /* Are we streaming Isochronous? */ @@ -459,14 +458,14 @@ struct usb_ov511 { int subh; /* Pix Array subcapture height */ int curframe; /* Current receiving sbuf */ - struct ov511_frame frame[OV511_NUMFRAMES]; + struct ov511_frame frame[OV511_NUMFRAMES]; struct ov511_sbuf sbuf[OV511_NUMSBUF]; wait_queue_head_t wq; /* Processes waiting */ int snap_enabled; /* Snapshot mode enabled */ - + int bridge; /* Type of bridge (BRG_*) */ int bclass; /* Class of bridge (BCL_*) */ int sensor; /* Type of image sensor chip (SEN_*) */ @@ -474,9 +473,11 @@ struct usb_ov511 { int packet_size; /* Frame size per isoc desc */ int packet_numbering; /* Is ISO frame numbering enabled? */ + struct semaphore param_lock; /* params lock for this camera */ + /* Framebuffer/sbuf management */ int buf_state; - struct mutex buf_lock; + struct semaphore buf_lock; struct ov51x_decomp_ops *decomp_ops; @@ -493,12 +494,12 @@ struct usb_ov511 { int pal; /* Device is designed for PAL resolution */ /* I2C interface */ - struct mutex i2c_lock; /* Protect I2C controller regs */ + struct semaphore i2c_lock; /* Protect I2C controller regs */ unsigned char primary_i2c_slave; /* I2C write id of sensor */ /* Control transaction stuff */ unsigned char *cbuf; /* Buffer for payload */ - struct mutex cbuf_lock; + struct semaphore cbuf_lock; }; /* Used to represent a list of values and their respective symbolic names */ @@ -512,7 +513,7 @@ struct symbolic_list { /* Returns the name of the matching element in the symbolic_list array. The * end of the list must be marked with an element that has a NULL name. */ -static inline char * +static inline char * symbolic(struct symbolic_list list[], int num) { int i; diff --git a/drivers/usb/media/pwc/Makefile b/drivers/usb/media/pwc/Makefile new file mode 100644 index 000000000..2d93a7750 --- /dev/null +++ b/drivers/usb/media/pwc/Makefile @@ -0,0 +1,20 @@ +ifneq ($(KERNELRELEASE),) + +pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o + +obj-$(CONFIG_USB_PWC) += pwc.o + +else + +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) + +default: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules + +endif + +clean: + rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c + rm -rf .tmp_versions + diff --git a/drivers/media/video/pwc/philips.txt b/drivers/usb/media/pwc/philips.txt similarity index 90% rename from drivers/media/video/pwc/philips.txt rename to drivers/usb/media/pwc/philips.txt index 11f751a6b..04a640d72 100644 --- a/drivers/media/video/pwc/philips.txt +++ b/drivers/usb/media/pwc/philips.txt @@ -47,17 +47,17 @@ don't know how to set it properly in the driver. The options are: size Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or 'vga', for an image size of resp. 128x96, 160x120, 176x144, - 320x240, 352x288 and 640x480 (of course, only for those cameras that + 320x240, 352x288 and 640x480 (of course, only for those cameras that support these resolutions). fps Specifies the desired framerate. Is an integer in the range of 4-30. fbufs - This paramter specifies the number of internal buffers to use for storing - frames from the cam. This will help if the process that reads images from - the cam is a bit slow or momentarely busy. However, on slow machines it - only introduces lag, so choose carefully. The default is 3, which is + This paramter specifies the number of internal buffers to use for storing + frames from the cam. This will help if the process that reads images from + the cam is a bit slow or momentarely busy. However, on slow machines it + only introduces lag, so choose carefully. The default is 3, which is reasonable. You can set it between 2 and 5. mbufs @@ -65,9 +65,9 @@ mbufs buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends. The default is 2, which is adequate for most applications (double buffering). - + Should you experience a lot of 'Dumping frame...' messages during - grabbing with a tool that uses mmap(), you might want to increase if. + grabbing with a tool that uses mmap(), you might want to increase if. However, it doesn't really buffer images, it just gives you a bit more slack when your program is behind. But you need a multi-threaded or forked program to really take advantage of these buffers. @@ -88,15 +88,15 @@ power_save compression (only useful with the plugin) With this option you can control the compression factor that the camera - uses to squeeze the image through the USB bus. You can set the + uses to squeeze the image through the USB bus. You can set the parameter between 0 and 3: 0 = prefer uncompressed images; if the requested mode is not available - in an uncompressed format, the driver will silently switch to low - compression. + in an uncompressed format, the driver will silently switch to low + compression. 1 = low compression. 2 = medium compression. 3 = high compression. - + High compression takes less bandwidth of course, but it could also introduce some unwanted artefacts. The default is 2, medium compression. See the FAQ on the website for an overview of which modes require @@ -112,7 +112,7 @@ leds this is let the LED blink while the camera is in use. This: leds=500,500 - + will blink the LED once every second. But with: leds=0,0 @@ -123,7 +123,7 @@ leds when the camera is not used anymore. This parameter works only with the ToUCam range of cameras (720, 730, 740, - 750) and OEMs. For other cameras this command is silently ignored, and + 750) and OEMs. For other cameras this command is silently ignored, and the LED cannot be controlled. Finally: this parameters does not take effect UNTIL the first time you @@ -144,35 +144,35 @@ dev_hint format: [type[.serialnumber]:]node - + The square brackets mean that both the type and the serialnumber are optional, but a serialnumber cannot be specified without a type (which would be rather pointless). The serialnumber is separated from the type by a '.'; the node number by a ':'. - + This somewhat cryptic syntax is best explained by a few examples: dev_hint=3,5 The first detected cam gets assigned - /dev/video3, the second /dev/video5. Any - other cameras will get the first free - available slot (see below). + /dev/video3, the second /dev/video5. Any + other cameras will get the first free + available slot (see below). dev_hint=645:1,680:2 The PCA645 camera will get /dev/video1, - and a PCVC680 /dev/video2. - - dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber - 0123 goes to /dev/video3, the same - camera model with the 4567 serial - gets /dev/video0. + and a PCVC680 /dev/video2. + + dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber + 0123 goes to /dev/video3, the same + camera model with the 4567 serial + gets /dev/video0. - dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the - next 3 Philips cams will use /dev/video4 - through /dev/video6. + dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the + next 3 Philips cams will use /dev/video4 + through /dev/video6. Some points worth knowing: - - Serialnumbers are case sensitive and must be written full, including + - Serialnumbers are case sensitive and must be written full, including leading zeroes (it's treated as a string). - - If a device node is already occupied, registration will fail and + - If a device node is already occupied, registration will fail and the webcam is not available. - You can have up to 64 video devices; be sure to make enough device nodes in /dev if you want to spread the numbers (this does not apply @@ -186,13 +186,13 @@ trace kernel log at debug level. The trace variable is a bitmask; each bit represents a certain feature. - If you want to trace something, look up the bit value(s) in the table + If you want to trace something, look up the bit value(s) in the table below, add the values together and supply that to the trace variable. Value Value Description Default (dec) (hex) 1 0x1 Module initialization; this will log messages On - while loading and unloading the module + while loading and unloading the module 2 0x2 probe() and disconnect() traces On @@ -203,7 +203,7 @@ trace 16 0x10 Memory allocation of buffers, etc. Off 32 0x20 Showing underflow, overflow and Dumping frame On - messages + messages 64 0x40 Show viewport and image sizes Off @@ -217,7 +217,7 @@ trace Example: - + # modprobe pwc size=cif fps=15 power_save=1 The fbufs, mbufs and trace parameters are global and apply to all connected diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c similarity index 91% rename from drivers/media/video/pwc/pwc-ctrl.c rename to drivers/usb/media/pwc/pwc-ctrl.c index 4ba549bfa..3ebb6e9cd 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c @@ -31,17 +31,18 @@ /* Changes - 2001/08/03 Alvarado Added methods for changing white balance and - red/green gains + 2001/08/03 Alvarado Added methods for changing white balance and + red/green gains */ /* Control functions for the cam; brightness, contrast, video mode, etc. */ #ifdef __KERNEL__ -#include +#include #endif #include - +#include + #include "pwc.h" #include "pwc-ioctl.h" #include "pwc-uncompress.h" @@ -116,13 +117,13 @@ static const char *size2name[PSZ_MAX] = "SIF", "CIF", "VGA", -}; +}; /********/ -/* Entries for the Nala (645/646) camera; the Nala doesn't have compression +/* Entries for the Nala (645/646) camera; the Nala doesn't have compression preferences, so you either get compressed or non-compressed streams. - + An alternate value of 0 means this mode is not available at all. */ @@ -205,13 +206,13 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra { /* closest match of framerate */ 0, 0, 0, 0, 4, /* 0-4 */ 5, 5, 7, 7, 10, /* 5-9 */ - 10, 10, 12, 12, 15, /* 10-14 */ - 15, 15, 15, 20, 20, /* 15-19 */ - 20, 20, 20, 24, 24, /* 20-24 */ - 24, 24, 24, 24, 24, /* 25-29 */ - 24 /* 30 */ + 10, 10, 12, 12, 15, /* 10-14 */ + 15, 15, 15, 20, 20, /* 15-19 */ + 20, 20, 20, 24, 24, /* 20-24 */ + 24, 24, 24, 24, 24, /* 25-29 */ + 24 /* 30 */ }; - int frames2table[31] = + int frames2table[31] = { 0, 0, 0, 0, 0, /* 0-4 */ 1, 1, 1, 2, 2, /* 5-9 */ 3, 3, 4, 4, 4, /* 10-14 */ @@ -220,7 +221,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra 7, 7, 7, 7, 7, /* 25-29 */ 7 /* 30 */ }; - + if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25) return -EINVAL; frames = frames2frames[frames]; @@ -232,7 +233,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra if (pEntry->compressed) return -ENOENT; /* Not supported. */ - memcpy(buf, pEntry->mode, 3); + memcpy(buf, pEntry->mode, 3); ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3); if (ret < 0) { Debug("Failed to send video command... %d\n", ret); @@ -257,7 +258,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra break; } } - + pdev->cmd_len = 3; memcpy(pdev->cmd_buf, buf, 3); @@ -352,13 +353,13 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ if (size == PSZ_VGA && frames == 5 && snapshot) { - /* Only available in case the raw palette is selected or - we have the decompressor available. This mode is - only available in compressed form + /* Only available in case the raw palette is selected or + we have the decompressor available. This mode is + only available in compressed form */ if (pdev->vpalette == VIDEO_PALETTE_RAW) { - Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette); + Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette); pChoose = &RawEntry; } else @@ -368,9 +369,9 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr } else { - /* Find a supported framerate with progressively higher compression ratios + /* Find a supported framerate with progressively higher compression ratios if the preferred ratio is not available. - Skip this step when using RAW modes. + Skip this step when using RAW modes. */ while (compression <= 3) { pChoose = &Kiara_table[size][fps][compression]; @@ -383,7 +384,7 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr return -ENOENT; /* Not supported. */ Debug("Using alternate setting %d.\n", pChoose->alternate); - + /* usb_control_msg won't take staticly allocated arrays as argument?? */ memcpy(buf, pChoose->mode, 12); if (snapshot) @@ -463,9 +464,9 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev) */ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot) { - int ret, size; + int ret, size; - Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); + Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); size = pwc_decode_size(pdev, width, height); if (size < 0) { Debug("Could not find suitable size.\n"); @@ -473,7 +474,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame } Debug("decode_size = %d.\n", size); - ret = -EINVAL; + ret = -EINVAL; switch(pdev->type) { case 645: case 646: @@ -485,7 +486,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame case 690: ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot); break; - + case 720: case 730: case 740: @@ -517,7 +518,7 @@ int pwc_get_brightness(struct pwc_device *pdev) char buf; int ret; - ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); + ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); if (ret < 0) return ret; return buf << 9; @@ -566,7 +567,7 @@ int pwc_get_gamma(struct pwc_device *pdev) { char buf; int ret; - + ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); if (ret < 0) return ret; @@ -622,14 +623,14 @@ static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value) { char buf; int ret; - + if (mode) buf = 0x0; /* auto */ else buf = 0xff; /* fixed */ ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1); - + if (!mode && ret >= 0) { if (value < 0) value = 0; @@ -647,7 +648,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1); if (ret < 0) return ret; @@ -658,7 +659,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value) return ret; if (buf > 0x3F) buf = 0x3F; - *value = (buf << 10); + *value = (buf << 10); } else { /* auto */ ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1); @@ -683,7 +684,7 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v buf[0] = 0x0; /* auto */ else buf[0] = 0xff; /* fixed */ - + ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1); if (!mode && ret >= 0) { @@ -713,7 +714,7 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); } return ret; -} +} /* POWER */ @@ -765,22 +766,22 @@ static inline int pwc_restore_factory(struct pwc_device *pdev) * 02: fluorescent lighting * 03: manual * 04: auto - */ + */ static inline int pwc_set_awb(struct pwc_device *pdev, int mode) { char buf; int ret; - + if (mode < 0) mode = 0; - + if (mode > 4) mode = 4; - + buf = mode & 0x07; /* just the lowest three bits */ - + ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1); - + if (ret < 0) return ret; return 0; @@ -790,17 +791,17 @@ static inline int pwc_get_awb(struct pwc_device *pdev) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1); - if (ret < 0) + if (ret < 0) return ret; return buf; } static inline int pwc_set_red_gain(struct pwc_device *pdev, int value) { - unsigned char buf; + unsigned char buf; if (value < 0) value = 0; @@ -815,7 +816,7 @@ static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); if (ret < 0) return ret; @@ -841,7 +842,7 @@ static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); if (ret < 0) return ret; @@ -851,14 +852,14 @@ static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) /* The following two functions are different, since they only read the - internal red/blue gains, which may be different from the manual + internal red/blue gains, which may be different from the manual gains set or read above. - */ + */ static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1); if (ret < 0) return ret; @@ -870,7 +871,7 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1); if (ret < 0) return ret; @@ -882,7 +883,7 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed) { unsigned char buf; - + /* useful range is 0x01..0x20 */ buf = speed / 0x7f0; return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); @@ -892,7 +893,7 @@ static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); if (ret < 0) return ret; @@ -904,7 +905,7 @@ static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay) { unsigned char buf; - + /* useful range is 0x01..0x3F */ buf = (delay >> 10); return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); @@ -914,7 +915,7 @@ static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); if (ret < 0) return ret; @@ -950,7 +951,7 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) { unsigned char buf[2]; int ret; - + if (pdev->type < 730) { *on_value = -1; *off_value = -1; @@ -969,7 +970,7 @@ static inline int pwc_set_contour(struct pwc_device *pdev, int contour) { unsigned char buf; int ret; - + if (contour < 0) buf = 0xff; /* auto contour on */ else @@ -977,16 +978,16 @@ static inline int pwc_set_contour(struct pwc_device *pdev, int contour) ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1); if (ret < 0) return ret; - + if (contour < 0) return 0; if (contour > 0xffff) contour = 0xffff; - + buf = (contour >> 10); /* contour preset is [0..3f] */ ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1); - if (ret < 0) - return ret; + if (ret < 0) + return ret; return 0; } @@ -994,7 +995,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) { unsigned char buf; int ret; - + ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1); if (ret < 0) return ret; @@ -1002,7 +1003,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) if (buf == 0) { /* auto mode off, query current preset value */ ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1); - if (ret < 0) + if (ret < 0) return ret; *contour = buf << 10; } @@ -1015,7 +1016,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight) { unsigned char buf; - + if (backlight) buf = 0xff; else @@ -1027,7 +1028,7 @@ static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) { int ret; unsigned char buf; - + ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); if (ret < 0) return ret; @@ -1039,7 +1040,7 @@ static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker) { unsigned char buf; - + if (flicker) buf = 0xff; else @@ -1051,7 +1052,7 @@ static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker) { int ret; unsigned char buf; - + ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); if (ret < 0) return ret; @@ -1076,7 +1077,7 @@ static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) { int ret; unsigned char buf; - + ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); if (ret < 0) return ret; @@ -1087,7 +1088,7 @@ static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) static int pwc_mpt_reset(struct pwc_device *pdev, int flags) { unsigned char buf; - + buf = flags & 0x03; // only lower two bits are currently used return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); } @@ -1095,7 +1096,7 @@ static int pwc_mpt_reset(struct pwc_device *pdev, int flags) static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) { unsigned char buf[4]; - + /* set new relative angle; angles are expressed in degrees * 100, but cam as .5 degree resolution, hence divide by 200. Also the angle must be multiplied by 64 before it's send to @@ -1114,7 +1115,7 @@ static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_sta { int ret; unsigned char buf[5]; - + ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5); if (ret < 0) return ret; @@ -1129,14 +1130,14 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) { unsigned char buf; int ret = -1, request; - + if (pdev->type < 675) request = SENSOR_TYPE_FORMATTER1; else if (pdev->type < 730) return -1; /* The Vesta series doesn't have this call */ else request = SENSOR_TYPE_FORMATTER2; - + ret = RecvControlMsg(GET_STATUS_CTL, request, 1); if (ret < 0) return ret; @@ -1163,23 +1164,23 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) ret = -EINVAL; break; } - + case VIDIOCPWCSUSER: { if (pwc_save_user(pdev)) ret = -EINVAL; break; } - + case VIDIOCPWCFACTORY: { if (pwc_restore_factory(pdev)) ret = -EINVAL; break; } - + case VIDIOCPWCSCQUAL: - { + { int *qual = arg; if (*qual < 0 || *qual > 3) @@ -1190,14 +1191,14 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) pdev->vcompression = *qual; break; } - + case VIDIOCPWCGCQUAL: { int *qual = arg; *qual = pdev->vcompression; break; } - + case VIDIOCPWCPROBE: { struct pwc_probe *probe = arg; @@ -1220,27 +1221,27 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) ret = -EINVAL; break; } - + case VIDIOCPWCGAGC: { int *agc = arg; - + if (pwc_get_agc(pdev, agc)) ret = -EINVAL; break; } - + case VIDIOCPWCSSHUTTER: { int *shutter_speed = arg; ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed); break; } - - case VIDIOCPWCSAWB: + + case VIDIOCPWCSAWB: { struct pwc_whitebalance *wb = arg; - + ret = pwc_set_awb(pdev, wb->mode); if (ret >= 0 && wb->mode == PWC_WB_MANUAL) { pwc_set_red_gain(pdev, wb->manual_red); @@ -1270,18 +1271,18 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) ret = pwc_read_red_gain(pdev, &wb->read_red); if (ret < 0) break; - ret = pwc_read_blue_gain(pdev, &wb->read_blue); - if (ret < 0) - break; + ret = pwc_read_blue_gain(pdev, &wb->read_blue); + if (ret < 0) + break; } } break; } - + case VIDIOCPWCSAWBSPEED: { struct pwc_wb_speed *wbs = arg; - + if (wbs->control_speed > 0) { ret = pwc_set_wb_speed(pdev, wbs->control_speed); } @@ -1290,11 +1291,11 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) } break; } - + case VIDIOCPWCGAWBSPEED: { struct pwc_wb_speed *wbs = arg; - + ret = pwc_get_wb_speed(pdev, &wbs->control_speed); if (ret < 0) break; @@ -1304,7 +1305,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) break; } - case VIDIOCPWCSLED: + case VIDIOCPWCSLED: { struct pwc_leds *leds = arg; ret = pwc_set_leds(pdev, leds->led_on, leds->led_off); @@ -1325,14 +1326,14 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) ret = pwc_set_contour(pdev, *contour); break; } - + case VIDIOCPWCGCONTOUR: { int *contour = arg; ret = pwc_get_contour(pdev, contour); break; } - + case VIDIOCPWCSBACKLIGHT: { int *backlight = arg; @@ -1346,7 +1347,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) ret = pwc_get_backlight(pdev, backlight); break; } - + case VIDIOCPWCSFLICKER: { int *flicker = arg; @@ -1360,14 +1361,14 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) ret = pwc_get_flicker(pdev, flicker); break; } - + case VIDIOCPWCSDYNNOISE: { int *dynnoise = arg; ret = pwc_set_dynamic_noise(pdev, *dynnoise); break; } - + case VIDIOCPWCGDYNNOISE: { int *dynnoise = arg; @@ -1381,61 +1382,61 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) size->width = pdev->image.x; size->height = pdev->image.y; break; - } - - case VIDIOCPWCMPTRESET: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - int *flags = arg; + } + + case VIDIOCPWCMPTRESET: + { + if (pdev->features & FEATURE_MOTOR_PANTILT) + { + int *flags = arg; ret = pwc_mpt_reset(pdev, *flags); - if (ret >= 0) - { - pdev->pan_angle = 0; - pdev->tilt_angle = 0; - } - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTGRANGE: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - struct pwc_mpt_range *range = arg; - *range = pdev->angle_range; - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTSANGLE: - { - int new_pan, new_tilt; - - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - struct pwc_mpt_angles *angles = arg; + if (ret >= 0) + { + pdev->pan_angle = 0; + pdev->tilt_angle = 0; + } + } + else + { + ret = -ENXIO; + } + break; + } + + case VIDIOCPWCMPTGRANGE: + { + if (pdev->features & FEATURE_MOTOR_PANTILT) + { + struct pwc_mpt_range *range = arg; + *range = pdev->angle_range; + } + else + { + ret = -ENXIO; + } + break; + } + + case VIDIOCPWCMPTSANGLE: + { + int new_pan, new_tilt; + + if (pdev->features & FEATURE_MOTOR_PANTILT) + { + struct pwc_mpt_angles *angles = arg; /* The camera can only set relative angles, so do some calculations when getting an absolute angle . */ if (angles->absolute) { - new_pan = angles->pan; - new_tilt = angles->tilt; - } - else - { - new_pan = pdev->pan_angle + angles->pan; - new_tilt = pdev->tilt_angle + angles->tilt; + new_pan = angles->pan; + new_tilt = angles->tilt; + } + else + { + new_pan = pdev->pan_angle + angles->pan; + new_tilt = pdev->tilt_angle + angles->tilt; } /* check absolute ranges */ if (new_pan < pdev->angle_range.pan_min || @@ -1463,53 +1464,53 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) pdev->tilt_angle += new_tilt; } if (ret == -EPIPE) /* stall -> out of range */ - ret = -ERANGE; + ret = -ERANGE; } - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTGANGLE: - { - - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - struct pwc_mpt_angles *angles = arg; - - angles->absolute = 1; - angles->pan = pdev->pan_angle; - angles->tilt = pdev->tilt_angle; - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTSTATUS: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - struct pwc_mpt_status *status = arg; - ret = pwc_mpt_get_status(pdev, status); - } - else - { - ret = -ENXIO; - } - break; + } + else + { + ret = -ENXIO; + } + break; + } + + case VIDIOCPWCMPTGANGLE: + { + + if (pdev->features & FEATURE_MOTOR_PANTILT) + { + struct pwc_mpt_angles *angles = arg; + + angles->absolute = 1; + angles->pan = pdev->pan_angle; + angles->tilt = pdev->tilt_angle; + } + else + { + ret = -ENXIO; + } + break; + } + + case VIDIOCPWCMPTSTATUS: + { + if (pdev->features & FEATURE_MOTOR_PANTILT) + { + struct pwc_mpt_status *status = arg; + ret = pwc_mpt_get_status(pdev, status); + } + else + { + ret = -ENXIO; + } + break; } case VIDIOCPWCGVIDCMD: { struct pwc_video_command *cmd = arg; - - cmd->type = pdev->type; + + cmd->type = pdev->type; cmd->release = pdev->release; cmd->command_len = pdev->cmd_len; memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len); @@ -1531,7 +1532,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) ret = -ENOIOCTLCMD; break; } - + if (ret > 0) return 0; return ret; diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c similarity index 93% rename from drivers/media/video/pwc/pwc-if.c rename to drivers/usb/media/pwc/pwc-if.c index 41418294a..4f9b0dc6f 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c @@ -25,18 +25,18 @@ */ -/* +/* This code forms the interface between the USB layers and the Philips specific stuff. Some adanved stuff of the driver falls under an NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and - is thus not distributed in source form. The binary pwcx.o module + is thus not distributed in source form. The binary pwcx.o module contains the code that falls under the NDA. - - In case you're wondering: 'pwc' stands for "Philips WebCam", but + + In case you're wondering: 'pwc' stands for "Philips WebCam", but I really didn't want to type 'philips_web_cam' every time (I'm lazy as any Linux kernel hacker, but I don't like uncomprehensible abbreviations without explanation). - + Oh yes, convention: to disctinguish between all the various pointers to device-structures, I use these names for the pointer variables: udev: struct usb_device * @@ -62,6 +62,7 @@ #include #include #include +#include #include #include "pwc.h" @@ -170,14 +171,14 @@ static struct video_device pwc_template = { /* Okay, this is some magic that I worked out and the reasoning behind it... - The biggest problem with any USB device is of course: "what to do + The biggest problem with any USB device is of course: "what to do when the user unplugs the device while it is in use by an application?" We have several options: 1) Curse them with the 7 plagues when they do (requires divine intervention) 2) Tell them not to (won't work: they'll do it anyway) 3) Oops the kernel (this will have a negative effect on a user's uptime) 4) Do something sensible. - + Of course, we go for option 4. It happens that this device will be linked to two times, once from @@ -185,15 +186,15 @@ static struct video_device pwc_template = { pointers. This is done when the device is probed() and all initialization succeeded. The pwc_device struct links back to both structures. - When a device is unplugged while in use it will be removed from the - list of known USB devices; I also de-register it as a V4L device, but + When a device is unplugged while in use it will be removed from the + list of known USB devices; I also de-register it as a V4L device, but unfortunately I can't free the memory since the struct is still in use by the file descriptor. This free-ing is then deferend until the first opportunity. Crude, but it works. - + A small 'advantage' is that if a user unplugs the cam and plugs it back in, it should get assigned the same video device minor, but unfortunately - it's non-trivial to re-link the cam back to the video device... (that + it's non-trivial to re-link the cam back to the video device... (that would surely be magic! :)) */ @@ -203,14 +204,14 @@ static struct video_device pwc_template = { /* Here we want the physical address of the memory. * This is used when initializing the contents of the area. */ -static inline unsigned long kvirt_to_pa(unsigned long adr) +static inline unsigned long kvirt_to_pa(unsigned long adr) { - unsigned long kva, ret; + unsigned long kva, ret; kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); kva |= adr & (PAGE_SIZE-1); /* restore the offset */ ret = __pa(kva); - return ret; + return ret; } static void * rvmalloc(unsigned long size) @@ -219,13 +220,13 @@ static void * rvmalloc(unsigned long size) unsigned long adr; size=PAGE_ALIGN(size); - mem=vmalloc_32(size); - if (mem) + mem=vmalloc_32(size); + if (mem) { memset(mem, 0, size); /* Clear the ram out, no junk to the user */ - adr=(unsigned long) mem; - while (size > 0) - { + adr=(unsigned long) mem; + while (size > 0) + { SetPageReserved(vmalloc_to_page((void *)adr)); adr+=PAGE_SIZE; size-=PAGE_SIZE; @@ -236,13 +237,13 @@ static void * rvmalloc(unsigned long size) static void rvfree(void * mem, unsigned long size) { - unsigned long adr; + unsigned long adr; - if (mem) + if (mem) { - adr=(unsigned long) mem; - while ((long) size > 0) - { + adr=(unsigned long) mem; + while ((long) size > 0) + { ClearPageReserved(vmalloc_to_page((void *)adr)); adr+=PAGE_SIZE; size-=PAGE_SIZE; @@ -263,13 +264,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) if (pdev == NULL) return -ENXIO; - + #ifdef PWC_MAGIC if (pdev->magic != PWC_MAGIC) { Err("allocate_buffers(): magic failed.\n"); return -ENXIO; } -#endif +#endif /* Allocate Isochronous pipe buffers */ for (i = 0; i < MAX_ISO_BUFS; i++) { if (pdev->sbuf[i].data == NULL) { @@ -308,7 +309,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) memset(kbuf, 128, PWC_FRAME_SIZE); } } - + /* Allocate decompressor table space */ kbuf = NULL; switch (pdev->type) @@ -320,7 +321,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) case 730: case 740: case 750: -#if 0 +#if 0 Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private)); kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */ break; @@ -329,11 +330,11 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) /* TODO & FIXME */ kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); break; -#endif +#endif ; } pdev->decompress_data = kbuf; - + /* Allocate image buffer; double buffer for mmap() */ kbuf = rvmalloc(default_mbufs * pdev->len_per_image); if (kbuf == NULL) { @@ -348,7 +349,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) pdev->image_ptr[i] = NULL; kbuf = NULL; - + Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n"); return 0; } @@ -366,7 +367,7 @@ static void pwc_free_buffers(struct pwc_device *pdev) Err("free_buffers(): magic failed.\n"); return; } -#endif +#endif /* Release Iso-pipe buffers */ for (i = 0; i < MAX_ISO_BUFS; i++) @@ -403,17 +404,17 @@ static void pwc_free_buffers(struct pwc_device *pdev) rvfree(pdev->image_data, default_mbufs * pdev->len_per_image); } pdev->image_data = NULL; - + Trace(TRACE_MEMORY, "Leaving free_buffers().\n"); } -/* The frame & image buffer mess. +/* The frame & image buffer mess. Yes, this is a mess. Well, it used to be simple, but alas... In this module, 3 buffers schemes are used to get the data from the USB bus to the user program. The first scheme involves the ISO buffers (called thus since they transport ISO data from the USB controller), and not really - interesting. Suffices to say the data from this buffer is quickly + interesting. Suffices to say the data from this buffer is quickly gathered in an interrupt handler (pwc_isoc_handler) and placed into the frame buffer. @@ -443,8 +444,8 @@ static void pwc_free_buffers(struct pwc_device *pdev) and a 'full' frame list: * Initially, all frame buffers but one are on the 'empty' list; the one remaining buffer is our initial fill frame. - * If a frame is needed for filling, we try to take it from the 'empty' - list, unless that list is empty, in which case we take the buffer at + * If a frame is needed for filling, we try to take it from the 'empty' + list, unless that list is empty, in which case we take the buffer at the head of the 'full' list. * When our fill buffer has been filled, it is appended to the 'full' list. @@ -646,7 +647,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break; } Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); - /* Give up after a number of contiguous errors on the USB bus. + /* Give up after a number of contiguous errors on the USB bus. Appearantly something is wrong so we simulate an unplug event. */ if (++pdev->visoc_errors > MAX_ISOC_ERRORS) @@ -673,8 +674,8 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) pdev->visoc_errors = 0; /* vsync: 0 = don't copy data - 1 = sync-hunt - 2 = synched + 1 = sync-hunt + 2 = synched */ /* Compact data */ for (i = 0; i < urb->number_of_packets; i++) { @@ -701,18 +702,18 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) } /* ..flen > 0 */ if (flen < pdev->vlast_packet_size) { - /* Shorter packet... We probably have the end of an image-frame; + /* Shorter packet... We probably have the end of an image-frame; wake up read() process and let select()/poll() do something. Decompression is done in user time over there. */ if (pdev->vsync == 2) { - /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus - frames on the USB wire after an exposure change. This conditition is + /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus + frames on the USB wire after an exposure change. This conditition is however detected in the cam and a bit is set in the header. */ if (pdev->type == 730) { unsigned char *ptr = (unsigned char *)fbuf->data; - + if (ptr[1] == 1 && ptr[0] & 0x10) { #if PWC_DEBUG Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence); @@ -733,13 +734,13 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) Info("Image is normal.\n"); } pdev->vmirror = ptr[0] & 0x03; - /* Sometimes the trailer of the 730 is still sent as a 4 byte packet + /* Sometimes the trailer of the 730 is still sent as a 4 byte packet after a short frame; this condition is filtered out specifically. A 4 byte frame doesn't make sense anyway. - So we get either this sequence: - drop_bit set -> 4 byte frame -> short frame -> good frame + So we get either this sequence: + drop_bit set -> 4 byte frame -> short frame -> good frame Or this one: - drop_bit set -> short frame -> good frame + drop_bit set -> short frame -> good frame So we drop either 3 or 2 frames in all! */ if (fbuf->filled == 4) @@ -826,11 +827,14 @@ static int pwc_isoc_init(struct pwc_device *pdev) /* Get the current alternate interface, adjust packet size */ if (!udev->actconfig) return -EFAULT; - +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) + idesc = &udev->actconfig->interface[0]->altsetting[pdev->valternate]; +#else intf = usb_ifnum_to_if(udev, 0); if (intf) idesc = usb_altnum_to_altsetting(intf, pdev->valternate); - +#endif + if (!idesc) return -EFAULT; @@ -841,7 +845,7 @@ static int pwc_isoc_init(struct pwc_device *pdev) pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); break; } - + if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { Err("Failed to find packet size for video endpoint in current alternate setting.\n"); return -ENFILE; /* Odd error, that should be noticeable */ @@ -875,18 +879,18 @@ static int pwc_isoc_init(struct pwc_device *pdev) return ret; } - /* init URB structure */ + /* init URB structure */ for (i = 0; i < MAX_ISO_BUFS; i++) { urb = pdev->sbuf[i].urb; urb->interval = 1; // devik urb->dev = udev; - urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint); + urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint); urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = pdev->sbuf[i].data; - urb->transfer_buffer_length = ISO_BUFFER_SIZE; - urb->complete = pwc_isoc_handler; - urb->context = pdev; + urb->transfer_buffer = pdev->sbuf[i].data; + urb->transfer_buffer_length = ISO_BUFFER_SIZE; + urb->complete = pwc_isoc_handler; + urb->context = pdev; urb->start_frame = 0; urb->number_of_packets = ISO_FRAMES_PER_DESC; for (j = 0; j < ISO_FRAMES_PER_DESC; j++) { @@ -935,7 +939,7 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev) } /* Stop camera, but only if we are sure the camera is still there (unplug - is signalled by EPIPE) + is signalled by EPIPE) */ if (pdev->error_status && pdev->error_status != EPIPE) { Trace(TRACE_OPEN, "Setting alternate interface 0.\n"); @@ -956,12 +960,12 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f pwc_reset_buffers(pdev); /* Try to set video mode... */ start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); - if (ret) { - Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n"); + if (ret) { + Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n"); /* That failed... restore old mode (we know that worked) */ start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); if (start) { - Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n"); + Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n"); } } if (start == 0) @@ -987,18 +991,18 @@ static int pwc_video_open(struct inode *inode, struct file *file) struct pwc_device *pdev; Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev); - + pdev = (struct pwc_device *)vdev->priv; if (pdev == NULL) BUG(); if (pdev->vopen) return -EBUSY; - + down(&pdev->modlock); if (!pdev->usb_init) { Trace(TRACE_OPEN, "Doing first time initialization.\n"); pdev->usb_init = 1; - + if (pwc_trace & TRACE_OPEN) { /* Query sensor type */ @@ -1036,7 +1040,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) /* Set LED on/off time */ if (pwc_set_leds(pdev, led_on, led_off) < 0) Info("Failed to set LED on/off time.\n"); - + pwc_construct(pdev); /* set min/max sizes correct */ /* So far, so good. Allocate memory. */ @@ -1046,7 +1050,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) up(&pdev->modlock); return i; } - + /* Reset buffers & parameters */ pwc_reset_buffers(pdev); for (i = 0; i < default_mbufs; i++) @@ -1081,7 +1085,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) up(&pdev->modlock); return i; } - + i = pwc_isoc_init(pdev); if (i) { Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i); @@ -1155,13 +1159,13 @@ static int pwc_video_close(struct inode *inode, struct file *file) /* * FIXME: what about two parallel reads ???? * ANSWER: Not supported. You can't open the device more than once, - despite what the V4L1 interface says. First, I don't see - the need, second there's no mechanism of alerting the - 2nd/3rd/... process of events like changing image size. - And I don't see the point of blocking that for the - 2nd/3rd/... process. - In multi-threaded environments reading parallel from any - device is tricky anyhow. + despite what the V4L1 interface says. First, I don't see + the need, second there's no mechanism of alerting the + 2nd/3rd/... process of events like changing image size. + And I don't see the point of blocking that for the + 2nd/3rd/... process. + In multi-threaded environments reading parallel from any + device is tricky anyhow. */ static ssize_t pwc_video_read(struct file *file, char __user * buf, @@ -1171,7 +1175,7 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf, struct pwc_device *pdev; int noblock = file->f_flags & O_NONBLOCK; DECLARE_WAITQUEUE(wait, current); - int bytes_to_read; + int bytes_to_read; Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count); if (vdev == NULL) @@ -1193,22 +1197,22 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf, set_current_state(TASK_RUNNING); return -pdev->error_status ; } - if (noblock) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -EWOULDBLOCK; - } - if (signal_pending(current)) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -ERESTARTSYS; - } - schedule(); - set_current_state(TASK_INTERRUPTIBLE); + if (noblock) { + remove_wait_queue(&pdev->frameq, &wait); + set_current_state(TASK_RUNNING); + return -EWOULDBLOCK; + } + if (signal_pending(current)) { + remove_wait_queue(&pdev->frameq, &wait); + set_current_state(TASK_RUNNING); + return -ERESTARTSYS; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); } remove_wait_queue(&pdev->frameq, &wait); set_current_state(TASK_RUNNING); - + /* Decompress and release frame */ if (pwc_handle_frame(pdev)) return -EFAULT; @@ -1218,7 +1222,7 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf, if (pdev->vpalette == VIDEO_PALETTE_RAW) bytes_to_read = pdev->frame_size; else - bytes_to_read = pdev->view.size; + bytes_to_read = pdev->view.size; /* copy bytes to user space; we allow for partial reads */ if (count + pdev->image_read_pos > bytes_to_read) @@ -1348,11 +1352,11 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, struct video_picture *p = arg; /* * FIXME: Suppose we are mid read - ANSWER: No problem: the firmware of the camera - can handle brightness/contrast/etc - changes at _any_ time, and the palette - is used exactly once in the uncompress - routine. + ANSWER: No problem: the firmware of the camera + can handle brightness/contrast/etc + changes at _any_ time, and the palette + is used exactly once in the uncompress + routine. */ pwc_set_brightness(pdev, p->brightness); pwc_set_contrast(pdev, p->contrast); @@ -1373,21 +1377,21 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, break; } - /* Window/size parameters */ + /* Window/size parameters */ case VIDIOCGWIN: { struct video_window *vw = arg; - + vw->x = 0; vw->y = 0; vw->width = pdev->view.x; vw->height = pdev->view.y; vw->chromakey = 0; - vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | - (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); + vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | + (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); break; } - + case VIDIOCSWIN: { struct video_window *vw = arg; @@ -1402,9 +1406,9 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot); if (ret) return ret; - break; + break; } - + /* We don't have overlay support (yet) */ case VIDIOCGFBUF: { @@ -1471,8 +1475,8 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, return -EBUSY; /* buffer wasn't available. Bummer */ pdev->image_used[vm->frame] = 1; - /* Okay, we're done here. In the SYNC call we wait until a - frame comes available, then expand image into the given + /* Okay, we're done here. In the SYNC call we wait until a + frame comes available, then expand image into the given buffer. In contrast to the CPiA cam the Philips cams deliver a constant stream, almost like a grabber card. Also, @@ -1487,16 +1491,16 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, { /* The doc says: "Whenever a buffer is used it should call VIDIOCSYNC to free this frame up and continue." - - The only odd thing about this whole procedure is + + The only odd thing about this whole procedure is that MCAPTURE flags the buffer as "in use", and - SYNC immediately unmarks it, while it isn't + SYNC immediately unmarks it, while it isn't after SYNC that you know that the buffer actually got filled! So you better not start a CAPTURE in - the same frame immediately (use double buffering). - This is not a problem for this cam, since it has - extra intermediate buffers, but a hardware - grabber card will then overwrite the buffer + the same frame immediately (use double buffering). + This is not a problem for this cam, since it has + extra intermediate buffers, but a hardware + grabber card will then overwrite the buffer you're working on. */ int *mbuf = arg; @@ -1512,10 +1516,10 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; /* Add ourselves to the frame wait-queue. - + FIXME: needs auditing for safety. QUESTION: In what respect? I think that using the - frameq is safe now. + frameq is safe now. */ add_wait_queue(&pdev->frameq, &wait); while (pdev->full_frames == NULL) { @@ -1524,21 +1528,21 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, set_current_state(TASK_RUNNING); return -pdev->error_status; } - - if (signal_pending(current)) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -ERESTARTSYS; - } - schedule(); - set_current_state(TASK_INTERRUPTIBLE); + + if (signal_pending(current)) { + remove_wait_queue(&pdev->frameq, &wait); + set_current_state(TASK_RUNNING); + return -ERESTARTSYS; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); } remove_wait_queue(&pdev->frameq, &wait); set_current_state(TASK_RUNNING); - - /* The frame is ready. Expand in the image buffer - requested by the user. I don't care if you - mmap() 5 buffers and request data in this order: + + /* The frame is ready. Expand in the image buffer + requested by the user. I don't care if you + mmap() 5 buffers and request data in this order: buffer 4 2 3 0 1 2 3 0 4 3 1 . . . Grabber hardware may not be so forgiving. */ @@ -1551,11 +1555,11 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, return -EFAULT; break; } - + case VIDIOCGAUDIO: { struct video_audio *v = arg; - + strcpy(v->name, "Microphone"); v->audio = -1; /* unknown audio minor */ v->flags = 0; @@ -1565,19 +1569,19 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, v->treble = 0; v->balance = 0x8000; v->step = 1; - break; + break; } - + case VIDIOCSAUDIO: { /* Dummy: nothing can be set */ break; } - + case VIDIOCGUNIT: { struct video_unit *vu = arg; - + vu->video = pdev->vdev->minor & 0x3F; vu->audio = -1; /* not known yet */ vu->vbi = -1; @@ -1589,7 +1593,7 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file, return pwc_ioctl(pdev, cmd, arg); } /* ..switch */ return 0; -} +} static int pwc_video_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -1605,10 +1609,10 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) unsigned long start = vma->vm_start; unsigned long size = vma->vm_end-vma->vm_start; unsigned long page, pos; - + Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size); pdev = vdev->priv; - + vma->vm_flags |= VM_IO; pos = (unsigned long)pdev->image_data; @@ -1646,7 +1650,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id char serial_number[30], *name; /* Check if we can handle this device */ - Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", + Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), intf->altsetting->desc.bInterfaceNumber); @@ -1770,11 +1774,11 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id name = "Logitech QuickCam (res.)"; type_id = 730; /* Assuming CMOS */ break; - default: + default: return -ENODEV; - break; - } - } + break; + } + } else if (vendor_id == 0x055d) { /* I don't know the difference between the C10 and the C30; I suppose the difference is the sensor, but both cameras @@ -1837,7 +1841,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id return -ENODEV; break; } - + } else if (vendor_id == 0x0d81) { switch(product_id) { @@ -1856,7 +1860,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id break; } } - else + else return -ENODEV; /* Not any of the know types; but the list keeps growing. */ memset(serial_number, 0, 30); @@ -1867,11 +1871,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id Info("Warning: more than 1 configuration available.\n"); /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ - pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); + pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL); if (pdev == NULL) { Err("Oops, could not allocate memory for pwc_device.\n"); return -ENOMEM; } + memset(pdev, 0, sizeof(struct pwc_device)); pdev->type = type_id; pdev->vsize = default_size; pdev->vframes = default_fps; @@ -1880,9 +1885,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id if (vendor_id == 0x046D && product_id == 0x08B5) { /* Logitech QuickCam Orbit - The ranges have been determined experimentally; they may differ from cam to cam. - Also, the exact ranges left-right and up-down are different for my cam - */ + The ranges have been determined experimentally; they may differ from cam to cam. + Also, the exact ranges left-right and up-down are different for my cam + */ pdev->angle_range.pan_min = -7000; pdev->angle_range.pan_max = 7000; pdev->angle_range.tilt_min = -3000; @@ -1939,7 +1944,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id } /* occupy slot */ - if (hint < MAX_DEV_HINTS) + if (hint < MAX_DEV_HINTS) device_hint[hint].pdev = pdev; Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev); @@ -1968,13 +1973,13 @@ static void usb_pwc_disconnect(struct usb_interface *intf) Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); goto disconnect_out; } -#ifdef PWC_MAGIC +#ifdef PWC_MAGIC if (pdev->magic != PWC_MAGIC) { Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n"); goto disconnect_out; } #endif - + /* We got unplugged; this is signalled by an EPIPE error code */ if (pdev->vopen) { Info("Disconnected while webcam is in use!\n"); @@ -2017,8 +2022,8 @@ static int pwc_atoi(const char *s) } -/* - * Initialization code & module stuff +/* + * Initialization code & module stuff */ static char size[10]; @@ -2168,7 +2173,7 @@ static int __init usb_pwc_init(void) if (*dot != '\0') { /* There's a serial number as well */ int k; - + dot++; k = 0; while (*dot != ':' && k < 29) { @@ -2178,18 +2183,18 @@ static int __init usb_pwc_init(void) device_hint[i].serial_number[k] = '\0'; } } -#if PWC_DEBUG +#if PWC_DEBUG Debug("device_hint[%d]:\n", i); Debug(" type : %d\n", device_hint[i].type); Debug(" serial# : %s\n", device_hint[i].serial_number); Debug(" node : %d\n", device_hint[i].device_node); -#endif +#endif } else device_hint[i].type = 0; /* not filled */ } /* ..for MAX_DEV_HINTS */ - Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver); + Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver); return usb_register(&pwc_driver); } diff --git a/drivers/media/video/pwc/pwc-ioctl.h b/drivers/usb/media/pwc/pwc-ioctl.h similarity index 94% rename from drivers/media/video/pwc/pwc-ioctl.h rename to drivers/usb/media/pwc/pwc-ioctl.h index 784bc7252..5f9cb08bc 100644 --- a/drivers/media/video/pwc/pwc-ioctl.h +++ b/drivers/usb/media/pwc/pwc-ioctl.h @@ -33,10 +33,10 @@ /* Changes 2001/08/03 Alvarado Added ioctl constants to access methods for - changing white balance and red/blue gains + changing white balance and red/blue gains 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE 2003/12/13 Nemosft Unv. Some modifications to make interfacing to - PWCX easier + PWCX easier */ /* These are private ioctl() commands, specific for the Philips webcams. @@ -45,10 +45,10 @@ The #define names are built up like follows: VIDIOC VIDeo IOCtl prefix - PWC Philps WebCam - G optional: Get - S optional: Set - ... the function + PWC Philps WebCam + G optional: Get + S optional: Set + ... the function */ @@ -94,7 +94,7 @@ struct pwc_serial { char serial[30]; /* String with serial number. Contains terminating 0 */ }; - + /* pwc_whitebalance.mode values */ #define PWC_WB_INDOOR 0 #define PWC_WB_OUTDOOR 1 @@ -102,14 +102,14 @@ struct pwc_serial #define PWC_WB_MANUAL 3 #define PWC_WB_AUTO 4 -/* Used with VIDIOCPWC[SG]AWB (Auto White Balance). +/* Used with VIDIOCPWC[SG]AWB (Auto White Balance). Set mode to one of the PWC_WB_* values above. - *red and *blue are the respective gains of these colour components inside + *red and *blue are the respective gains of these colour components inside the camera; range 0..65535 - When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; + When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; otherwise undefined. 'read_red' and 'read_blue' are read-only. -*/ +*/ struct pwc_whitebalance { int mode; @@ -117,9 +117,9 @@ struct pwc_whitebalance int read_red, read_blue; /* R/O */ }; -/* +/* 'control_speed' and 'control_delay' are used in automatic whitebalance mode, - and tell the camera how fast it should react to changes in lighting, and + and tell the camera how fast it should react to changes in lighting, and with how much delay. Valid values are 0..65535. */ struct pwc_wb_speed @@ -148,11 +148,11 @@ struct pwc_imagesize #define PWC_MPT_TILT 0x02 #define PWC_MPT_TIMEOUT 0x04 /* for status */ -/* Set angles; when absolute != 0, the angle is absolute and the +/* Set angles; when absolute != 0, the angle is absolute and the driver calculates the relative offset for you. This can only be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns absolute angles. - */ + */ struct pwc_mpt_angles { int absolute; /* write-only */ @@ -179,14 +179,14 @@ struct pwc_mpt_status /* This is used for out-of-kernel decompression. With it, you can get all the necessary information to initialize and use the decompressor routines in standalone applications. - */ + */ struct pwc_video_command { int type; /* camera type (645, 675, 730, etc.) */ int release; /* release number */ - int size; /* one of PSZ_* */ - int alternate; + int size; /* one of PSZ_* */ + int alternate; int command_len; /* length of USB video command */ unsigned char command_buf[13]; /* Actual USB video command */ int bandlength; /* >0 = compressed */ @@ -264,7 +264,7 @@ struct pwc_video_command /* Flickerless mode; = 0 off, otherwise on */ #define VIDIOCPWCSFLICKER _IOW('v', 208, int) -#define VIDIOCPWCGFLICKER _IOR('v', 208, int) +#define VIDIOCPWCGFLICKER _IOR('v', 208, int) /* Dynamic noise reduction; 0 off, 3 = high noise reduction */ #define VIDIOCPWCSDYNNOISE _IOW('v', 209, int) @@ -273,7 +273,7 @@ struct pwc_video_command /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */ #define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize) - /* Motorized pan & tilt functions */ + /* Motorized pan & tilt functions */ #define VIDIOCPWCMPTRESET _IOW('v', 211, int) #define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range) #define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles) diff --git a/drivers/usb/media/pwc/pwc-kiara.c b/drivers/usb/media/pwc/pwc-kiara.c new file mode 100644 index 000000000..c498c68ba --- /dev/null +++ b/drivers/usb/media/pwc/pwc-kiara.c @@ -0,0 +1,318 @@ +/* Linux driver for Philips webcam + (C) 2004 Luc Saillard (luc@saillard.org) + + NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx + driver and thus may have bugs that are not present in the original version. + Please send bug reports and support requests to . + The decompression routines have been implemented by reverse-engineering the + Nemosoft binary pwcx module. Caveat emptor. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +/* This tables contains entries for the 730/740/750 (Kiara) camera, with + 4 different qualities (no compression, low, medium, high). + It lists the bandwidth requirements for said mode by its alternate interface + number. An alternate of 0 means that the mode is unavailable. + + There are 6 * 4 * 4 entries: + 6 different resolutions subqcif, qsif, qcif, sif, cif, vga + 6 framerates: 5, 10, 15, 20, 25, 30 + 4 compression modi: none, low, medium, high + + When an uncompressed mode is not available, the next available compressed mode + will be chosen (unless the decompressor is absent). Sometimes there are only + 1 or 2 compressed modes available; in that case entries are duplicated. +*/ + + +#include "pwc-kiara.h" +#include "pwc-uncompress.h" + +const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] = +{ + /* SQCIF */ + { + /* 5 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 10 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 15 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 20 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 25 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 30 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + }, + /* QSIF */ + { + /* 5 fps */ + { + {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, + {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, + {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, + {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, + }, + /* 10 fps */ + { + {2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}}, + {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, + {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, + {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, + }, + /* 15 fps */ + { + {3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}}, + {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}}, + {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}}, + {1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}}, + }, + /* 20 fps */ + { + {4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}}, + {3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}}, + {2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}}, + {1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}}, + }, + /* 25 fps */ + { + {5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}}, + {3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}}, + {2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}}, + {1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}}, + }, + /* 30 fps */ + { + {8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}}, + {5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}}, + {3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}}, + {2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}}, + }, + }, + /* QCIF */ + { + /* 5 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 10 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 15 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 20 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 25 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 30 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + }, + /* SIF */ + { + /* 5 fps */ + { + {4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}}, + {3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}}, + {2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}}, + {1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}}, + }, + /* 10 fps */ + { + {0, }, + {6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}}, + {3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}}, + {2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}}, + }, + /* 15 fps */ + { + {0, }, + {9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}}, + {4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}}, + {3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}}, + }, + /* 20 fps */ + { + {0, }, + {9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}}, + {5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}}, + {3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}}, + }, + /* 25 fps */ + { + {0, }, + {9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}}, + {6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}}, + {4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}}, + }, + /* 30 fps */ + { + {0, }, + {9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}}, + {6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}}, + {4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}}, + }, + }, + /* CIF */ + { + /* 5 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 10 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 15 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 20 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 25 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 30 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + }, + /* VGA */ + { + /* 5 fps */ + { + {0, }, + {6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}}, + {4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}}, + {3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}}, + }, + /* 10 fps */ + { + {0, }, + {9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}}, + {6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}}, + {4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}}, + }, + /* 15 fps */ + { + {0, }, + {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}}, + {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}}, + {8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}}, + }, + /* 20 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 25 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 30 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + }, +}; + diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/usb/media/pwc/pwc-kiara.h similarity index 100% rename from drivers/media/video/pwc/pwc-kiara.h rename to drivers/usb/media/pwc/pwc-kiara.h diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/usb/media/pwc/pwc-misc.c similarity index 87% rename from drivers/media/video/pwc/pwc-misc.c rename to drivers/usb/media/pwc/pwc-misc.c index 58fe79747..b7a4bd352 100644 --- a/drivers/media/video/pwc/pwc-misc.c +++ b/drivers/usb/media/pwc/pwc-misc.c @@ -1,4 +1,4 @@ -/* Linux driver for Philips webcam +/* Linux driver for Philips webcam Various miscellaneous functions and tables. (C) 1999-2003 Nemosoft Unv. (C) 2004 Luc Saillard (luc@saillard.org) @@ -44,17 +44,17 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) int i, find; /* Make sure we don't go beyond our max size. - NB: we have different limits for RAW and normal modes. In case - you don't have the decompressor loaded or use RAW mode, - the maximum viewable size is smaller. - */ + NB: we have different limits for RAW and normal modes. In case + you don't have the decompressor loaded or use RAW mode, + the maximum viewable size is smaller. + */ if (pdev->vpalette == VIDEO_PALETTE_RAW) { if (width > pdev->abs_max.x || height > pdev->abs_max.y) { Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); - return -1; - } + return -1; + } } else { @@ -88,8 +88,8 @@ void pwc_construct(struct pwc_device *pdev) pdev->view_min.y = 96; pdev->view_max.x = 352; pdev->view_max.y = 288; - pdev->abs_max.x = 352; - pdev->abs_max.y = 288; + pdev->abs_max.x = 352; + pdev->abs_max.y = 288; pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF; pdev->vcinterface = 2; pdev->vendpoint = 4; @@ -105,8 +105,8 @@ void pwc_construct(struct pwc_device *pdev) pdev->view_max.x = 640; pdev->view_max.y = 480; pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA; - pdev->abs_max.x = 640; - pdev->abs_max.y = 480; + pdev->abs_max.x = 640; + pdev->abs_max.y = 480; pdev->vcinterface = 3; pdev->vendpoint = 4; pdev->frame_header_size = 0; @@ -121,8 +121,8 @@ void pwc_construct(struct pwc_device *pdev) pdev->view_max.x = 640; pdev->view_max.y = 480; pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; - pdev->abs_max.x = 640; - pdev->abs_max.y = 480; + pdev->abs_max.x = 640; + pdev->abs_max.y = 480; pdev->vcinterface = 3; pdev->vendpoint = 5; pdev->frame_header_size = TOUCAM_HEADER_SIZE; diff --git a/drivers/media/video/pwc/pwc-nala.h b/drivers/usb/media/pwc/pwc-nala.h similarity index 99% rename from drivers/media/video/pwc/pwc-nala.h rename to drivers/usb/media/pwc/pwc-nala.h index 168c73ef7..e6c5cb69d 100644 --- a/drivers/media/video/pwc/pwc-nala.h +++ b/drivers/usb/media/pwc/pwc-nala.h @@ -54,7 +54,7 @@ {0}, }, /* VGA */ - { + { {0}, {0}, {0}, diff --git a/drivers/usb/media/pwc/pwc-timon.c b/drivers/usb/media/pwc/pwc-timon.c new file mode 100644 index 000000000..dee967173 --- /dev/null +++ b/drivers/usb/media/pwc/pwc-timon.c @@ -0,0 +1,316 @@ +/* Linux driver for Philips webcam + (C) 2004 Luc Saillard (luc@saillard.org) + + NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx + driver and thus may have bugs that are not present in the original version. + Please send bug reports and support requests to . + The decompression routines have been implemented by reverse-engineering the + Nemosoft binary pwcx module. Caveat emptor. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +/* This tables contains entries for the 675/680/690 (Timon) camera, with + 4 different qualities (no compression, low, medium, high). + It lists the bandwidth requirements for said mode by its alternate interface + number. An alternate of 0 means that the mode is unavailable. + + There are 6 * 4 * 4 entries: + 6 different resolutions subqcif, qsif, qcif, sif, cif, vga + 6 framerates: 5, 10, 15, 20, 25, 30 + 4 compression modi: none, low, medium, high + + When an uncompressed mode is not available, the next available compressed mode + will be chosen (unless the decompressor is absent). Sometimes there are only + 1 or 2 compressed modes available; in that case entries are duplicated. +*/ + +#include "pwc-timon.h" + +const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = +{ + /* SQCIF */ + { + /* 5 fps */ + { + {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, + {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, + {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, + {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, + }, + /* 10 fps */ + { + {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, + {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, + {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, + {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, + }, + /* 15 fps */ + { + {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, + {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, + {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, + {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, + }, + /* 20 fps */ + { + {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, + {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, + {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, + {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, + }, + /* 25 fps */ + { + {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, + {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, + {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, + {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, + }, + /* 30 fps */ + { + {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, + {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, + {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, + {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, + }, + }, + /* QSIF */ + { + /* 5 fps */ + { + {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, + {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, + {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, + {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, + }, + /* 10 fps */ + { + {2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}}, + {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, + {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, + {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, + }, + /* 15 fps */ + { + {3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}}, + {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, + {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, + {1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, + }, + /* 20 fps */ + { + {4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}}, + {3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, + {2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, + {1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}}, + }, + /* 25 fps */ + { + {5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}}, + {3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, + {2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, + {1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}}, + }, + /* 30 fps */ + { + {8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}}, + {5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}}, + {3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}}, + {2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}}, + }, + }, + /* QCIF */ + { + /* 5 fps */ + { + {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, + {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, + {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, + {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, + }, + /* 10 fps */ + { + {3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}}, + {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, + {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, + {1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}}, + }, + /* 15 fps */ + { + {4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}}, + {3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}}, + {2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}}, + {1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}}, + }, + /* 20 fps */ + { + {6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}}, + {4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}}, + {3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, + {2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}}, + }, + /* 25 fps */ + { + {9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}}, + {5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}}, + {3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, + {2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, + }, + /* 30 fps */ + { + {0, }, + {9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}}, + {4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}}, + {2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}}, + }, + }, + /* SIF */ + { + /* 5 fps */ + { + {4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}}, + {3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}}, + {2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}}, + {1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}}, + }, + /* 10 fps */ + { + {0, }, + {6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}}, + {3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}}, + {2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}}, + }, + /* 15 fps */ + { + {0, }, + {9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}}, + {4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}}, + {3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}}, + }, + /* 20 fps */ + { + {0, }, + {9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}}, + {5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}}, + {3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}}, + }, + /* 25 fps */ + { + {0, }, + {9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}}, + {6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}}, + {4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}}, + }, + /* 30 fps */ + { + {0, }, + {9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}}, + {6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}}, + {4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}}, + }, + }, + /* CIF */ + { + /* 5 fps */ + { + {6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}}, + {4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}}, + {2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}}, + {1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}}, + }, + /* 10 fps */ + { + {0, }, + {9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}}, + {4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}}, + {2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}}, + }, + /* 15 fps */ + { + {0, }, + {9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}}, + {5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}}, + {3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}}, + }, + /* 20 fps */ + { + {0, }, + {9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}}, + {6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}}, + {4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}}, + }, + /* 25 fps */ + { + {0, }, + {9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}}, + {7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}}, + {5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}}, + }, + /* 30 fps */ + { + {0, }, + {9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}}, + {7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}}, + {6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}}, + }, + }, + /* VGA */ + { + /* 5 fps */ + { + {0, }, + {6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}}, + {4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}}, + {3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}}, + }, + /* 10 fps */ + { + {0, }, + {9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}}, + {6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}}, + {4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}}, + }, + /* 15 fps */ + { + {0, }, + {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}}, + {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}}, + {8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}}, + }, + /* 20 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 25 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + /* 30 fps */ + { + {0, }, + {0, }, + {0, }, + {0, }, + }, + }, +}; + diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/usb/media/pwc/pwc-timon.h similarity index 100% rename from drivers/media/video/pwc/pwc-timon.h rename to drivers/usb/media/pwc/pwc-timon.h diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c similarity index 96% rename from drivers/media/video/pwc/pwc-uncompress.c rename to drivers/usb/media/pwc/pwc-uncompress.c index b37a89a16..ef4204eab 100644 --- a/drivers/media/video/pwc/pwc-uncompress.c +++ b/drivers/usb/media/pwc/pwc-uncompress.c @@ -109,9 +109,9 @@ int pwc_decompress(struct pwc_device *pdev) in planar format immediately. */ int flags; - - flags = PWCX_FLAG_PLANAR; - if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) + + flags = PWCX_FLAG_PLANAR; + if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) { printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n"); flags |= PWCX_FLAG_BAYER; diff --git a/drivers/media/video/pwc/pwc-uncompress.h b/drivers/usb/media/pwc/pwc-uncompress.h similarity index 96% rename from drivers/media/video/pwc/pwc-uncompress.h rename to drivers/usb/media/pwc/pwc-uncompress.h index f75e1b6cb..d3b9250e4 100644 --- a/drivers/media/video/pwc/pwc-uncompress.h +++ b/drivers/usb/media/pwc/pwc-uncompress.h @@ -24,7 +24,7 @@ /* This file is the bridge between the kernel module and the plugin; it describes the structures and datatypes used in both modules. Any - significant change should be reflected by increasing the + significant change should be reflected by increasing the pwc_decompressor_version major number. */ #ifndef PWC_UNCOMPRESS_H diff --git a/drivers/media/video/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h similarity index 99% rename from drivers/media/video/pwc/pwc.h rename to drivers/usb/media/pwc/pwc.h index 1b0ee0ced..6dd76bb3d 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/usb/media/pwc/pwc.h @@ -123,7 +123,7 @@ struct pwc_device #endif /* Pointer to our usb_device */ struct usb_device *udev; - + int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ int release; /* release number */ int features; /* feature bits */ @@ -149,7 +149,7 @@ struct pwc_device char vsnapshot; /* snapshot mode */ char vsync; /* used by isoc handler */ char vmirror; /* for ToUCaM series */ - + int cmd_len; unsigned char cmd_buf[13]; diff --git a/drivers/media/video/se401.c b/drivers/usb/media/se401.c similarity index 88% rename from drivers/media/video/se401.c rename to drivers/usb/media/se401.c index a846ebc78..2ba562285 100644 --- a/drivers/media/video/se401.c +++ b/drivers/usb/media/se401.c @@ -4,7 +4,7 @@ * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org) * * Still somewhat based on the Linux ov511 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 @@ -114,16 +114,16 @@ static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req, unsigned short value, unsigned char *cp, int size) { return usb_control_msg ( - se401->dev, - set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), - req, - (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, - 0, - cp, - size, - 1000 - ); + se401->dev, + set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), + req, + (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, + 0, + cp, + size, + 1000 + ); } static int se401_set_feature(struct usb_se401 *se401, unsigned short selector, @@ -140,30 +140,30 @@ static int se401_set_feature(struct usb_se401 *se401, unsigned short selector, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, param, selector, - NULL, - 0, - 1000 - ); + NULL, + 0, + 1000 + ); } -static unsigned short se401_get_feature(struct usb_se401 *se401, - unsigned short selector) +static unsigned short se401_get_feature(struct usb_se401 *se401, + unsigned short selector) { /* For 'set' the selecetor should be in index, not sure if the spec is wrong here to.... */ unsigned char cp[2]; - usb_control_msg ( - se401->dev, - usb_rcvctrlpipe(se401->dev, 0), - SE401_REQ_GET_EXT_FEATURE, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, - selector, - cp, - 2, - 1000 - ); + usb_control_msg ( + se401->dev, + usb_rcvctrlpipe(se401->dev, 0), + SE401_REQ_GET_EXT_FEATURE, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, + selector, + cp, + 2, + 1000 + ); return cp[0]+cp[1]*256; } @@ -183,14 +183,14 @@ static int se401_send_pict(struct usb_se401 *se401) se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */ se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */ se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */ - + return 0; } static void se401_set_exposure(struct usb_se401 *se401, int brightness) { int integration=brightness<<5; - + if (flickerless==50) { integration=integration-integration%106667; } @@ -255,11 +255,11 @@ static void se401_auto_resetlevel(struct usb_se401 *se401) /* For some reason this normally read-only register doesn't get reset to zero after reading them just once... */ - se401_get_feature(se401, HV7131_REG_HIREFNOH); + se401_get_feature(se401, HV7131_REG_HIREFNOH); se401_get_feature(se401, HV7131_REG_HIREFNOL); se401_get_feature(se401, HV7131_REG_LOREFNOH); se401_get_feature(se401, HV7131_REG_LOREFNOL); - ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + + ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + se401_get_feature(se401, HV7131_REG_HIREFNOL); alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) + se401_get_feature(se401, HV7131_REG_LOREFNOL); @@ -287,12 +287,12 @@ static void se401_button_irq(struct urb *urb, struct pt_regs *regs) { struct usb_se401 *se401 = urb->context; int status; - + if (!se401->dev) { info("ohoh: device vapourished"); return; } - + switch (urb->status) { case 0: /* success */ @@ -368,7 +368,7 @@ static void se401_video_irq(struct urb *urb, struct pt_regs *regs) if (se401->nullpackets > SE401_MAX_NULLPACKETS) { if (waitqueue_active(&se401->wq)) { wake_up_interruptible(&se401->wq); - } + } } } @@ -433,8 +433,8 @@ static int se401_start_stream(struct usb_se401 *se401) int err=0, i; se401->streaming=1; - se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); - se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); + se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); + se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); /* Set picture settings */ se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */ @@ -571,7 +571,7 @@ static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data) } /* First three are absolute, all others relative. - * Format is rgb from right to left (mirrorred image), + * Format is rgb from right to left (mirrorred image), * we flip it to get bgr from left to right. */ if (frame->curlinepix < 3) { *(frame->curline-frame->curlinepix)=1+data*4; @@ -703,7 +703,7 @@ static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch * int width=se401->cwidth; int blineoffset=0, bline; int linelength=width*3, i; - + if (frame->curpix==0) { if (frame->grabstate==FRAME_READY) { @@ -831,7 +831,7 @@ static int se401_newframe(struct usb_se401 *se401, int framenr) se401->nullpackets=0; info("to many null length packets, restarting capture"); se401_stop_stream(se401); - se401_start_stream(se401); + se401_start_stream(se401); } else { if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) { se401->frame[framenr].grabstate=FRAME_ERROR; @@ -866,7 +866,7 @@ static void usb_se401_remove_disconnected (struct usb_se401 *se401) { int i; - se401->dev = NULL; + se401->dev = NULL; for (i=0; iurb[i]) { @@ -882,9 +882,9 @@ static void usb_se401_remove_disconnected (struct usb_se401 *se401) usb_kill_urb(se401->inturb); usb_free_urb(se401->inturb); } - info("%s disconnected", se401->camera_name); + info("%s disconnected", se401->camera_name); - /* Free the memory */ + /* Free the memory */ kfree(se401->width); kfree(se401->height); kfree(se401); @@ -910,7 +910,7 @@ static int se401_open(struct inode *inode, struct file *file) se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES); if (se401->fbuf) file->private_data = dev; - else + else err = -ENOMEM; se401->user = !err; @@ -920,11 +920,11 @@ static int se401_open(struct inode *inode, struct file *file) static int se401_close(struct inode *inode, struct file *file) { struct video_device *dev = file->private_data; - struct usb_se401 *se401 = (struct usb_se401 *)dev; + struct usb_se401 *se401 = (struct usb_se401 *)dev; int i; rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES); - if (se401->removed) { + if (se401->removed) { usb_se401_remove_disconnected(se401); info("device unregistered"); } else { @@ -942,12 +942,12 @@ static int se401_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = file->private_data; - struct usb_se401 *se401 = (struct usb_se401 *)vdev; + struct usb_se401 *se401 = (struct usb_se401 *)vdev; - if (!se401->dev) - return -EIO; + if (!se401->dev) + return -EIO; - switch (cmd) { + switch (cmd) { case VIDIOCGCAP: { struct video_capability *b = arg; @@ -981,8 +981,8 @@ static int se401_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; return 0; } - case VIDIOCGPICT: - { + case VIDIOCGPICT: + { struct video_picture *p = arg; se401_get_pict(se401, p); @@ -1007,7 +1007,7 @@ static int se401_do_ioctl(struct inode *inode, struct file *file, if (se401_set_size(se401, vw->width, vw->height)) return -EINVAL; return 0; - } + } case VIDIOCGWIN: { struct video_window *vw = arg; @@ -1095,11 +1095,11 @@ static int se401_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGAUDIO: case VIDIOCSAUDIO: return -EINVAL; - default: - return -ENOIOCTLCMD; - } /* end switch */ + default: + return -ENOIOCTLCMD; + } /* end switch */ - return 0; + return 0; } static int se401_ioctl(struct inode *inode, struct file *file, @@ -1142,7 +1142,7 @@ static ssize_t se401_read(struct file *file, char __user *buf, se401->frame[0].grabstate=FRAME_UNUSED; if (ret) - return ret; + return ret; if (copy_to_user(buf, se401->frame[0].data, realcount)) return -EFAULT; @@ -1157,21 +1157,21 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) unsigned long size = vma->vm_end-vma->vm_start; unsigned long page, pos; - mutex_lock(&se401->lock); + down(&se401->lock); if (se401->dev == NULL) { - mutex_unlock(&se401->lock); + up(&se401->lock); return -EIO; } if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) { - mutex_unlock(&se401->lock); + up(&se401->lock); return -EINVAL; } pos = (unsigned long)se401->fbuf; while (size > 0) { page = vmalloc_to_pfn((void *)pos); if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { - mutex_unlock(&se401->lock); + up(&se401->lock); return -EAGAIN; } start += PAGE_SIZE; @@ -1181,26 +1181,26 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) else size = 0; } - mutex_unlock(&se401->lock); + up(&se401->lock); - return 0; + return 0; } static struct file_operations se401_fops = { .owner = THIS_MODULE, - .open = se401_open, - .release = se401_close, - .read = se401_read, - .mmap = se401_mmap, + .open = se401_open, + .release = se401_close, + .read = se401_read, + .mmap = se401_mmap, .ioctl = se401_ioctl, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static struct video_device se401_template = { .owner = THIS_MODULE, - .name = "se401 USB camera", - .type = VID_TYPE_CAPTURE, - .hardware = VID_HARDWARE_SE401, + .name = "se401 USB camera", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_SE401, .fops = &se401_fops, }; @@ -1209,12 +1209,12 @@ static struct video_device se401_template = { /***************************/ static int se401_init(struct usb_se401 *se401, int button) { - int i=0, rc; - unsigned char cp[0x40]; + int i=0, rc; + unsigned char cp[0x40]; char temp[200]; /* led on */ - se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); + se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); /* get camera descriptor */ rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp)); @@ -1254,7 +1254,7 @@ static int se401_init(struct usb_se401 *se401, int button) return 1; } /* set output mode (BAYER) */ - se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0); + se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0); rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp)); se401->brightness=cp[0]+cp[1]*256; @@ -1292,71 +1292,73 @@ static int se401_init(struct usb_se401 *se401, int button) } else se401->inturb=NULL; - /* Flash the led */ - se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); - se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); - se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); + /* Flash the led */ + se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); + se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); + se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); - return 0; + return 0; } static int se401_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); - struct usb_interface_descriptor *interface; - struct usb_se401 *se401; - char *camera_name=NULL; + struct usb_interface_descriptor *interface; + struct usb_se401 *se401; + char *camera_name=NULL; int button=1; - /* We don't handle multi-config cameras */ - if (dev->descriptor.bNumConfigurations != 1) - return -ENODEV; + /* We don't handle multi-config cameras */ + if (dev->descriptor.bNumConfigurations != 1) + return -ENODEV; - interface = &intf->cur_altsetting->desc; + interface = &intf->cur_altsetting->desc; - /* Is it an se401? */ - if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && - le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { - camera_name="Endpoints/Aox SE401"; - } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && - le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { - camera_name="Philips PCVC665K"; - } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && + /* Is it an se401? */ + if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && + le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { + camera_name="Endpoints/Aox SE401"; + } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && + le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { + camera_name="Philips PCVC665K"; + } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && le16_to_cpu(dev->descriptor.idProduct) == 0x5001) { camera_name="Kensington VideoCAM 67014"; - } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && + } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && le16_to_cpu(dev->descriptor.idProduct) == 0x5002) { camera_name="Kensington VideoCAM 6701(5/7)"; - } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && + } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && le16_to_cpu(dev->descriptor.idProduct) == 0x5003) { camera_name="Kensington VideoCAM 67016"; button=0; } else return -ENODEV; - /* Checking vendor/product should be enough, but what the hell */ - if (interface->bInterfaceClass != 0x00) + /* Checking vendor/product should be enough, but what the hell */ + if (interface->bInterfaceClass != 0x00) return -ENODEV; - if (interface->bInterfaceSubClass != 0x00) + if (interface->bInterfaceSubClass != 0x00) return -ENODEV; - /* We found one */ - info("SE401 camera found: %s", camera_name); + /* We found one */ + info("SE401 camera found: %s", camera_name); - if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { - err("couldn't kmalloc se401 struct"); + if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { + err("couldn't kmalloc se401 struct"); return -ENOMEM; - } + } + + memset(se401, 0, sizeof(*se401)); - se401->dev = dev; - se401->iface = interface->bInterfaceNumber; - se401->camera_name = camera_name; + se401->dev = dev; + se401->iface = interface->bInterfaceNumber; + se401->camera_name = camera_name; info("firmware version: %02x", le16_to_cpu(dev->descriptor.bcdDevice) & 255); - if (se401_init(se401, button)) { + if (se401_init(se401, button)) { kfree(se401); return -EIO; } @@ -1364,7 +1366,7 @@ static int se401_probe(struct usb_interface *intf, memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name)); init_waitqueue_head(&se401->wq); - mutex_init(&se401->lock); + init_MUTEX(&se401->lock); wmb(); if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { @@ -1375,7 +1377,7 @@ static int se401_probe(struct usb_interface *intf, info("registered new video device: video%d", se401->vdev.minor); usb_set_intfdata (intf, se401); - return 0; + return 0; } static void se401_disconnect(struct usb_interface *intf) @@ -1400,10 +1402,10 @@ static void se401_disconnect(struct usb_interface *intf) } static struct usb_driver se401_driver = { - .name = "se401", - .id_table = device_table, + .name = "se401", + .id_table = device_table, .probe = se401_probe, - .disconnect = se401_disconnect, + .disconnect = se401_disconnect, }; diff --git a/drivers/media/video/se401.h b/drivers/usb/media/se401.h similarity index 98% rename from drivers/media/video/se401.h rename to drivers/usb/media/se401.h index a7a216bd4..2e5846f1e 100644 --- a/drivers/media/video/se401.h +++ b/drivers/usb/media/se401.h @@ -5,7 +5,6 @@ #include #include #include -#include #define se401_DEBUG /* Turn on debug messages */ @@ -177,7 +176,7 @@ struct usb_se401 { int expose_m; int expose_l; int resetlevel; - + int enhance; int format; @@ -190,7 +189,7 @@ struct usb_se401 { int maxframesize; int cframesize; /* current framesize */ - struct mutex lock; + struct semaphore lock; int user; /* user count for exclusive use */ int removed; /* device disconnected */ @@ -200,12 +199,12 @@ struct usb_se401 { struct urb *urb[SE401_NUMSBUF]; struct urb *inturb; - + int button; int buttonpressed; int curframe; /* Current receiving frame */ - struct se401_frame frame[SE401_NUMFRAMES]; + struct se401_frame frame[SE401_NUMFRAMES]; int readcount; int framecount; int error; diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/usb/media/sn9c102.h similarity index 89% rename from drivers/media/video/sn9c102/sn9c102.h rename to drivers/usb/media/sn9c102.h index 2c6ff396d..17d60c1ee 100644 --- a/drivers/media/video/sn9c102/sn9c102.h +++ b/drivers/usb/media/sn9c102.h @@ -33,9 +33,7 @@ #include #include #include -#include -#include -#include +#include #include "sn9c102_sensor.h" @@ -52,7 +50,6 @@ #define SN9C102_ALTERNATE_SETTING 8 #define SN9C102_URB_TIMEOUT msecs_to_jiffies(2 * SN9C102_ISO_PACKETS) #define SN9C102_CTRL_TIMEOUT 300 -#define SN9C102_FRAME_TIMEOUT 2 /*****************************************************************************/ @@ -110,17 +107,16 @@ struct sn9c102_sysfs_attr { struct sn9c102_module_param { u8 force_munmap; - u16 frame_timeout; }; -static DEFINE_MUTEX(sn9c102_sysfs_lock); +static DECLARE_MUTEX(sn9c102_sysfs_lock); static DECLARE_RWSEM(sn9c102_disconnect); struct sn9c102_device { struct video_device* v4ldev; enum sn9c102_bridge bridge; - struct sn9c102_sensor sensor; + struct sn9c102_sensor* sensor; struct usb_device* usbdev; struct urb* urb[SN9C102_URBS]; @@ -145,28 +141,19 @@ struct sn9c102_device { enum sn9c102_dev_state state; u8 users; - struct mutex dev_mutex, fileop_mutex; + struct semaphore dev_sem, fileop_sem; spinlock_t queue_lock; wait_queue_head_t open, wait_frame, wait_stream; }; /*****************************************************************************/ -struct sn9c102_device* -sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id) -{ - if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id)) - return cam; - - return NULL; -} - - void sn9c102_attach_sensor(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor) + struct sn9c102_sensor* sensor) { - memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor)); + cam->sensor = sensor; + cam->sensor->usbdev = cam->usbdev; } /*****************************************************************************/ @@ -183,7 +170,7 @@ do { \ dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) >= 3) \ dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args); \ + __FUNCTION__, __LINE__ , ## args); \ } \ } while (0) # define V4LDBG(level, name, cmd) \ @@ -198,7 +185,7 @@ do { \ pr_info("sn9c102: " fmt "\n", ## args); \ else if ((level) == 3) \ pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \ - __LINE__ , ## args); \ + __LINE__ , ## args); \ } \ } while (0) #else @@ -209,8 +196,7 @@ do { \ #undef PDBG #define PDBG(fmt, args...) \ -dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args) +dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args) #undef PDBGG #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c similarity index 84% rename from drivers/media/video/sn9c102/sn9c102_core.c rename to drivers/usb/media/sn9c102_core.c index ea4394dc9..c81397e47 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c @@ -25,9 +25,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -47,8 +49,8 @@ #define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" #define SN9C102_AUTHOR_EMAIL "" #define SN9C102_MODULE_LICENSE "GPL" -#define SN9C102_MODULE_VERSION "1:1.27" -#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 27) +#define SN9C102_MODULE_VERSION "1:1.26" +#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 26) /*****************************************************************************/ @@ -62,53 +64,44 @@ MODULE_LICENSE(SN9C102_MODULE_LICENSE); static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1}; module_param_array(video_nr, short, NULL, 0444); MODULE_PARM_DESC(video_nr, - "\n<-1|n[,...]> Specify V4L2 minor mode number." - "\n -1 = use next available (default)" - "\n n = use minor number n (integer >= 0)" - "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES) - " cameras this way." - "\nFor example:" - "\nvideo_nr=-1,2,-1 would assign minor number 2 to" - "\nthe second camera and use auto for the first" - "\none and for every other camera." - "\n"); - -static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] = - SN9C102_FORCE_MUNMAP}; + "\n<-1|n[,...]> Specify V4L2 minor mode number." + "\n -1 = use next available (default)" + "\n n = use minor number n (integer >= 0)" + "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES) + " cameras this way." + "\nFor example:" + "\nvideo_nr=-1,2,-1 would assign minor number 2 to" + "\nthe second camera and use auto for the first" + "\none and for every other camera." + "\n"); + +static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] = + SN9C102_FORCE_MUNMAP}; module_param_array(force_munmap, bool, NULL, 0444); MODULE_PARM_DESC(force_munmap, - "\n<0|1[,...]> Force the application to unmap previously" - "\nmapped buffer memory before calling any VIDIOC_S_CROP or" - "\nVIDIOC_S_FMT ioctl's. Not all the applications support" - "\nthis feature. This parameter is specific for each" - "\ndetected camera." - "\n 0 = do not force memory unmapping" - "\n 1 = force memory unmapping (save memory)" - "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." - "\n"); - -static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] = - SN9C102_FRAME_TIMEOUT}; -module_param_array(frame_timeout, uint, NULL, 0644); -MODULE_PARM_DESC(frame_timeout, - "\n Timeout for a video frame in seconds." - "\nThis parameter is specific for each detected camera." - "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"." - "\n"); + "\n<0|1[,...]> Force the application to unmap previously" + "\nmapped buffer memory before calling any VIDIOC_S_CROP or" + "\nVIDIOC_S_FMT ioctl's. Not all the applications support" + "\nthis feature. This parameter is specific for each" + "\ndetected camera." + "\n 0 = do not force memory unmapping" + "\n 1 = force memory unmapping (save memory)" + "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." + "\n"); #ifdef SN9C102_DEBUG static unsigned short debug = SN9C102_DEBUG_LEVEL; module_param(debug, ushort, 0644); MODULE_PARM_DESC(debug, - "\n Debugging information level, from 0 to 3:" - "\n0 = none (use carefully)" - "\n1 = critical errors" - "\n2 = significant informations" - "\n3 = more verbose messages" - "\nLevel 3 is useful for testing only, when only " - "one device is used." - "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"." - "\n"); + "\n Debugging information level, from 0 to 3:" + "\n0 = none (use carefully)" + "\n1 = critical errors" + "\n2 = significant informations" + "\n3 = more verbose messages" + "\nLevel 3 is useful for testing only, when only " + "one device is used." + "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"." + "\n"); #endif /*****************************************************************************/ @@ -131,16 +124,16 @@ static sn9c102_eof_header_t sn9c102_eof_header[] = { /*****************************************************************************/ -static u32 -sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, - enum sn9c102_io_method io) +static u32 +sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, + enum sn9c102_io_method io) { - struct v4l2_pix_format* p = &(cam->sensor.pix_format); - struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); + struct v4l2_pix_format* p = &(cam->sensor->pix_format); + struct v4l2_rect* r = &(cam->sensor->cropcap.bounds); const size_t imagesize = cam->module_param.force_munmap || - io == IO_READ ? - (p->width * p->height * p->priv) / 8 : - (r->width * r->height * p->priv) / 8; + io == IO_READ ? + (p->width * p->height * p->priv) / 8 : + (r->width * r->height * p->priv) / 8; void* buff = NULL; u32 i; @@ -232,8 +225,8 @@ int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index) return -1; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, - index, 0, buff, sizeof(buff), - SN9C102_CTRL_TIMEOUT*sizeof(buff)); + index, 0, buff, sizeof(buff), + SN9C102_CTRL_TIMEOUT*sizeof(buff)); if (res < 0) { DBG(3, "Failed to write registers (index 0x%02X, error %d)", index, res); @@ -259,7 +252,7 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index) *buff = value; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, - index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); + index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); if (res < 0) { DBG(3, "Failed to write a register (value 0x%02X, index " "0x%02X, error %d)", value, index, res); @@ -280,7 +273,7 @@ static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index) int res; res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1, - index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); + index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); if (res < 0) DBG(3, "Failed to read a register (index 0x%02X, error %d)", index, res); @@ -319,8 +312,8 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor) static int -sn9c102_i2c_detect_read_error(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor) +sn9c102_i2c_detect_read_error(struct sn9c102_device* cam, + struct sn9c102_sensor* sensor) { int r; r = sn9c102_read_reg(cam, 0x08); @@ -329,8 +322,8 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam, static int -sn9c102_i2c_detect_write_error(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor) +sn9c102_i2c_detect_write_error(struct sn9c102_device* cam, + struct sn9c102_sensor* sensor) { int r; r = sn9c102_read_reg(cam, 0x08); @@ -338,10 +331,10 @@ sn9c102_i2c_detect_write_error(struct sn9c102_device* cam, } -int +int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 data0, u8 data1, - u8 n, u8 buffer[]) + struct sn9c102_sensor* sensor, u8 data0, u8 data1, + u8 n, u8 buffer[]) { struct usb_device* udev = cam->usbdev; u8* data = cam->control_buffer; @@ -349,12 +342,12 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, /* Write cycle */ data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) | - ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10; + ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10; data[1] = data0; /* I2C slave id */ data[2] = data1; /* address */ data[7] = 0x10; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, - 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT); + 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT); if (res < 0) err += res; @@ -362,12 +355,12 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, /* Read cycle - n bytes */ data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) | - ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | - (n << 4) | 0x02; + ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | + (n << 4) | 0x02; data[1] = data0; data[7] = 0x10; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, - 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT); + 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT); if (res < 0) err += res; @@ -375,7 +368,7 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, /* The first read byte will be placed in data[4] */ res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1, - 0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT); + 0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT); if (res < 0) err += res; @@ -396,10 +389,10 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, } -int +int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 n, u8 data0, - u8 data1, u8 data2, u8 data3, u8 data4, u8 data5) + struct sn9c102_sensor* sensor, u8 n, u8 data0, + u8 data1, u8 data2, u8 data3, u8 data4, u8 data5) { struct usb_device* udev = cam->usbdev; u8* data = cam->control_buffer; @@ -407,8 +400,8 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, /* Write cycle. It usually is address + value */ data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) | - ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) - | ((n - 1) << 4); + ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) + | ((n - 1) << 4); data[1] = data0; data[2] = data1; data[3] = data2; @@ -417,7 +410,7 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, data[6] = data5; data[7] = 0x14; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, - 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT); + 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT); if (res < 0) err += res; @@ -437,32 +430,38 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, int sn9c102_i2c_try_read(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 address) + struct sn9c102_sensor* sensor, u8 address) { return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id, - address, 1, NULL); + address, 1, NULL); } int sn9c102_i2c_try_write(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 address, u8 value) + struct sn9c102_sensor* sensor, u8 address, u8 value) { - return sn9c102_i2c_try_raw_write(cam, sensor, 3, - sensor->i2c_slave_id, address, - value, 0, 0, 0); + return sn9c102_i2c_try_raw_write(cam, sensor, 3, + sensor->i2c_slave_id, address, + value, 0, 0, 0); } int sn9c102_i2c_read(struct sn9c102_device* cam, u8 address) { - return sn9c102_i2c_try_read(cam, &cam->sensor, address); + if (!cam->sensor) + return -1; + + return sn9c102_i2c_try_read(cam, cam->sensor, address); } int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value) { - return sn9c102_i2c_try_write(cam, &cam->sensor, address, value); + if (!cam->sensor) + return -1; + + return sn9c102_i2c_try_write(cam, cam->sensor, address, value); } /*****************************************************************************/ @@ -484,7 +483,7 @@ sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) n = sizeof(sn9c103_sof_header) / soflen; } - for (i = 0; (len >= soflen) && (i <= len - soflen); i++) + for (i = 0; (len >= soflen) && (i <= len - soflen); i++) for (j = 0; j < n; j++) /* The invariable part of the header is 6 bytes long */ if ((cam->bridge != BRIDGE_SN9C103 && @@ -506,7 +505,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) size_t eoflen = sizeof(sn9c102_eof_header_t), i; unsigned j, n = sizeof(sn9c102_eof_header) / eoflen; - if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) + if (cam->sensor->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) return NULL; /* EOF header does not exist in compressed data */ for (i = 0; (len >= eoflen) && (i <= len - eoflen); i++) @@ -536,7 +535,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs) if ((*f)) (*f)->state = F_QUEUED; DBG(3, "Stream interrupted"); - wake_up(&cam->wait_stream); + wake_up_interruptible(&cam->wait_stream); } if (cam->state & DEV_DISCONNECTED) @@ -552,15 +551,15 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs) if (!(*f)) (*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t, - frame); + frame); - imagesize = (cam->sensor.pix_format.width * - cam->sensor.pix_format.height * - cam->sensor.pix_format.priv) / 8; + imagesize = (cam->sensor->pix_format.width * + cam->sensor->pix_format.height * + cam->sensor->pix_format.priv) / 8; soflen = (cam->bridge) == BRIDGE_SN9C103 ? - sizeof(sn9c103_sof_header_t) : - sizeof(sn9c102_sof_header_t); + sizeof(sn9c103_sof_header_t) : + sizeof(sn9c102_sof_header_t); for (i = 0; i < urb->number_of_packets; i++) { unsigned int img, len, status; @@ -580,7 +579,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs) redo: sof = sn9c102_find_sof_header(cam, pos, len); - if (likely(!sof)) { + if (!sof) { eof = sn9c102_find_eof_header(cam, pos, len); if ((*f)->state == F_GRABBING) { end_of_frame: @@ -590,9 +589,8 @@ end_of_frame: img = (eof > pos) ? eof - pos - 1 : 0; if ((*f)->buf.bytesused+img > imagesize) { - u32 b; - b = (*f)->buf.bytesused + img - - imagesize; + u32 b = (*f)->buf.bytesused + img - + imagesize; img = imagesize - (*f)->buf.bytesused; DBG(3, "Expected EOF not found: " "video frame cut"); @@ -610,20 +608,19 @@ end_of_frame: (*f)->buf.bytesused += img; if ((*f)->buf.bytesused == imagesize || - (cam->sensor.pix_format.pixelformat == - V4L2_PIX_FMT_SN9C10X && eof)) { - u32 b; - b = (*f)->buf.bytesused; + (cam->sensor->pix_format.pixelformat == + V4L2_PIX_FMT_SN9C10X && eof)) { + u32 b = (*f)->buf.bytesused; (*f)->state = F_DONE; (*f)->buf.sequence= ++cam->frame_count; spin_lock(&cam->queue_lock); list_move_tail(&(*f)->frame, - &cam->outqueue); + &cam->outqueue); if (!list_empty(&cam->inqueue)) (*f) = list_entry( - cam->inqueue.next, - struct sn9c102_frame_t, - frame ); + cam->inqueue.next, + struct sn9c102_frame_t, + frame ); else (*f) = NULL; spin_unlock(&cam->queue_lock); @@ -638,7 +635,7 @@ end_of_frame: } else if (eof) { (*f)->state = F_ERROR; DBG(3, "Not expected EOF after %lu " - "bytes of image data", + "bytes of image data", (unsigned long) ((*f)->buf.bytesused)); } @@ -670,13 +667,13 @@ start_of_frame: if (eof && eof < sof) goto end_of_frame; /* (1) */ else { - if (cam->sensor.pix_format.pixelformat == + if (cam->sensor->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) { eof = sof - soflen; goto end_of_frame; } else { DBG(3, "SOF before expected EOF after " - "%lu bytes of image data", + "%lu bytes of image data", (unsigned long) ((*f)->buf.bytesused)); goto start_of_frame; @@ -702,18 +699,18 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) struct usb_device *udev = cam->usbdev; struct urb* urb; const unsigned int sn9c102_wMaxPacketSize[] = {0, 128, 256, 384, 512, - 680, 800, 900, 1023}; + 680, 800, 900, 1023}; const unsigned int sn9c103_wMaxPacketSize[] = {0, 128, 256, 384, 512, - 680, 800, 900, 1003}; + 680, 800, 900, 1003}; const unsigned int psz = (cam->bridge == BRIDGE_SN9C103) ? - sn9c103_wMaxPacketSize[SN9C102_ALTERNATE_SETTING] : - sn9c102_wMaxPacketSize[SN9C102_ALTERNATE_SETTING]; + sn9c103_wMaxPacketSize[SN9C102_ALTERNATE_SETTING] : + sn9c102_wMaxPacketSize[SN9C102_ALTERNATE_SETTING]; s8 i, j; int err = 0; for (i = 0; i < SN9C102_URBS; i++) { cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz, - GFP_KERNEL); + GFP_KERNEL); if (!cam->transfer_buffer[i]) { err = -ENOMEM; DBG(1, "Not enough memory"); @@ -811,21 +808,20 @@ static int sn9c102_stop_transfer(struct sn9c102_device* cam) static int sn9c102_stream_interrupt(struct sn9c102_device* cam) { - long timeout; + int err = 0; cam->stream = STREAM_INTERRUPT; - timeout = wait_event_timeout(cam->wait_stream, - (cam->stream == STREAM_OFF) || - (cam->state & DEV_DISCONNECTED), - SN9C102_URB_TIMEOUT); + err = wait_event_timeout(cam->wait_stream, + (cam->stream == STREAM_OFF) || + (cam->state & DEV_DISCONNECTED), + SN9C102_URB_TIMEOUT); if (cam->state & DEV_DISCONNECTED) return -ENODEV; - else if (cam->stream != STREAM_OFF) { + else if (err) { cam->state |= DEV_MISCONFIGURED; - DBG(1, "URB timeout reached. The camera is misconfigured. " - "To use it, close and open /dev/video%d again.", - cam->v4ldev->minor); - return -EIO; + DBG(1, "The camera is misconfigured. To use it, close and " + "open /dev/video%d again.", cam->v4ldev->minor); + return err; } return 0; @@ -861,7 +857,7 @@ static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count) /* NOTE 1: being inside one of the following methods implies that the v4l - device exists for sure (see kobjects and reference counters) + device exists for sure (see kobjects and reference counters) NOTE 2: buffers are PAGE_SIZE long */ @@ -870,42 +866,42 @@ static ssize_t sn9c102_show_reg(struct class_device* cd, char* buf) struct sn9c102_device* cam; ssize_t count; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } count = sprintf(buf, "%u\n", cam->sysfs.reg); - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return count; -} +} -static ssize_t +static ssize_t sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len) { struct sn9c102_device* cam; u8 index; ssize_t count; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } index = sn9c102_strtou8(buf, len, &count); if (index > 0x1f || !count) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -EINVAL; } @@ -914,7 +910,7 @@ sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len) DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg); DBG(3, "Written bytes: %zd", count); - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return count; } @@ -926,17 +922,17 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf) ssize_t count; int val; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -EIO; } @@ -944,10 +940,10 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf) DBG(3, "Read bytes: %zd", count); - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return count; -} +} static ssize_t @@ -958,24 +954,24 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len) ssize_t count; int err; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } value = sn9c102_strtou8(buf, len, &count); if (!count) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -EINVAL; } err = sn9c102_write_reg(cam, value, cam->sysfs.reg); if (err) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -EIO; } @@ -983,7 +979,7 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len) cam->sysfs.reg, value); DBG(3, "Written bytes: %zd", count); - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return count; } @@ -994,12 +990,12 @@ static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf) struct sn9c102_device* cam; ssize_t count; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } @@ -1007,31 +1003,31 @@ static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf) DBG(3, "Read bytes: %zd", count); - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return count; } -static ssize_t +static ssize_t sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len) { struct sn9c102_device* cam; u8 index; ssize_t count; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } index = sn9c102_strtou8(buf, len, &count); if (!count) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -EINVAL; } @@ -1040,7 +1036,7 @@ sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len) DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg); DBG(3, "Written bytes: %zd", count); - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return count; } @@ -1052,22 +1048,22 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf) ssize_t count; int val; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } - if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) { - mutex_unlock(&sn9c102_sysfs_lock); + if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) { + up(&sn9c102_sysfs_lock); return -ENOSYS; } if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -EIO; } @@ -1075,10 +1071,10 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf) DBG(3, "Read bytes: %zd", count); - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return count; -} +} static ssize_t @@ -1089,29 +1085,29 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len) ssize_t count; int err; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } - if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) { - mutex_unlock(&sn9c102_sysfs_lock); + if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) { + up(&sn9c102_sysfs_lock); return -ENOSYS; } value = sn9c102_strtou8(buf, len, &count); if (!count) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -EINVAL; } err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value); if (err) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -EIO; } @@ -1119,7 +1115,7 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len) cam->sysfs.i2c_reg, value); DBG(3, "Written bytes: %zd", count); - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return count; } @@ -1134,18 +1130,18 @@ sn9c102_store_green(struct class_device* cd, const char* buf, size_t len) u8 value; ssize_t count; - if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) + if (down_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(to_video_device(cd)); if (!cam) { - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); return -ENODEV; } bridge = cam->bridge; - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); value = sn9c102_strtou8(buf, len, &count); if (!count) @@ -1222,22 +1218,22 @@ static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf) DBG(3, "Frame header, read bytes: %zd", count); return count; -} +} static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, - sn9c102_show_reg, sn9c102_store_reg); + sn9c102_show_reg, sn9c102_store_reg); static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR, - sn9c102_show_val, sn9c102_store_val); + sn9c102_show_val, sn9c102_store_val); static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR, - sn9c102_show_i2c_reg, sn9c102_store_i2c_reg); + sn9c102_show_i2c_reg, sn9c102_store_i2c_reg); static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, - sn9c102_show_i2c_val, sn9c102_store_i2c_val); + sn9c102_show_i2c_val, sn9c102_store_i2c_val); static CLASS_DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green); static CLASS_DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue); static CLASS_DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red); static CLASS_DEVICE_ATTR(frame_header, S_IRUGO, - sn9c102_show_frame_header, NULL); + sn9c102_show_frame_header, NULL); static void sn9c102_create_sysfs(struct sn9c102_device* cam) @@ -1253,7 +1249,7 @@ static void sn9c102_create_sysfs(struct sn9c102_device* cam) video_device_create_file(v4ldev, &class_device_attr_blue); video_device_create_file(v4ldev, &class_device_attr_red); } - if (cam->sensor.sysfs_ops) { + if (cam->sensor && cam->sensor->sysfs_ops) { video_device_create_file(v4ldev, &class_device_attr_i2c_reg); video_device_create_file(v4ldev, &class_device_attr_i2c_val); } @@ -1278,7 +1274,7 @@ sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix) static int sn9c102_set_compression(struct sn9c102_device* cam, - struct v4l2_jpegcompression* compression) + struct v4l2_jpegcompression* compression) { int err = 0; @@ -1316,7 +1312,7 @@ static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale) static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect) { - struct sn9c102_sensor* s = &cam->sensor; + struct sn9c102_sensor* s = cam->sensor; u8 h_start = (u8)(rect->left - s->cropcap.bounds.left), v_start = (u8)(rect->top - s->cropcap.bounds.top), h_size = (u8)(rect->width / 16), @@ -1339,7 +1335,7 @@ static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect) static int sn9c102_init(struct sn9c102_device* cam) { - struct sn9c102_sensor* s = &cam->sensor; + struct sn9c102_sensor* s = cam->sensor; struct v4l2_control ctrl; struct v4l2_queryctrl *qctrl; struct v4l2_rect* rect; @@ -1408,7 +1404,7 @@ static int sn9c102_init(struct sn9c102_device* cam) } if (!(cam->state & DEV_INITIALIZED)) { - mutex_init(&cam->fileop_mutex); + init_MUTEX(&cam->fileop_sem); spin_lock_init(&cam->queue_lock); init_waitqueue_head(&cam->wait_frame); init_waitqueue_head(&cam->wait_stream); @@ -1426,15 +1422,13 @@ static int sn9c102_init(struct sn9c102_device* cam) static void sn9c102_release_resources(struct sn9c102_device* cam) { - mutex_lock(&sn9c102_sysfs_lock); + down(&sn9c102_sysfs_lock); DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); - usb_put_dev(cam->usbdev); - - mutex_unlock(&sn9c102_sysfs_lock); + up(&sn9c102_sysfs_lock); kfree(cam->control_buffer); } @@ -1455,7 +1449,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp) cam = video_get_drvdata(video_devdata(filp)); - if (mutex_lock_interruptible(&cam->dev_mutex)) { + if (down_interruptible(&cam->dev_sem)) { up_read(&sn9c102_disconnect); return -ERESTARTSYS; } @@ -1467,10 +1461,10 @@ static int sn9c102_open(struct inode* inode, struct file* filp) err = -EWOULDBLOCK; goto out; } - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); err = wait_event_interruptible_exclusive(cam->open, - cam->state & DEV_DISCONNECTED - || !cam->users); + cam->state & DEV_DISCONNECTED + || !cam->users); if (err) { up_read(&sn9c102_disconnect); return err; @@ -1479,7 +1473,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp) up_read(&sn9c102_disconnect); return -ENODEV; } - mutex_lock(&cam->dev_mutex); + down(&cam->dev_sem); } @@ -1507,7 +1501,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp) DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); out: - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); up_read(&sn9c102_disconnect); return err; } @@ -1517,7 +1511,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp) { struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); - mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ + down(&cam->dev_sem); /* prevent disconnect() to be called */ sn9c102_stop_transfer(cam); @@ -1525,7 +1519,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp) if (cam->state & DEV_DISCONNECTED) { sn9c102_release_resources(cam); - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); kfree(cam); return 0; } @@ -1535,7 +1529,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp) DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); return 0; } @@ -1547,36 +1541,35 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); struct sn9c102_frame_t* f, * i; unsigned long lock_flags; - long timeout; int err = 0; - if (mutex_lock_interruptible(&cam->fileop_mutex)) + if (down_interruptible(&cam->fileop_sem)) return -ERESTARTSYS; if (cam->state & DEV_DISCONNECTED) { DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -ENODEV; } if (cam->state & DEV_MISCONFIGURED) { DBG(1, "The camera is misconfigured. Close and open it " "again."); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EIO; } if (cam->io == IO_MMAP) { DBG(3, "Close and open the device again to choose " "the read method"); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EINVAL; } if (cam->io == IO_NONE) { if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) { DBG(1, "read() failed, not enough memory"); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -ENOMEM; } cam->io = IO_READ; @@ -1590,32 +1583,30 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) } if (!count) { - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return 0; } if (list_empty(&cam->outqueue)) { if (filp->f_flags & O_NONBLOCK) { - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EAGAIN; } - timeout = wait_event_interruptible_timeout - ( cam->wait_frame, - (!list_empty(&cam->outqueue)) || - (cam->state & DEV_DISCONNECTED) || - (cam->state & DEV_MISCONFIGURED), - cam->module_param.frame_timeout * - 1000 * msecs_to_jiffies(1) ); - if (timeout < 0) { - mutex_unlock(&cam->fileop_mutex); - return timeout; + err = wait_event_interruptible + ( cam->wait_frame, + (!list_empty(&cam->outqueue)) || + (cam->state & DEV_DISCONNECTED) || + (cam->state & DEV_MISCONFIGURED) ); + if (err) { + up(&cam->fileop_sem); + return err; } if (cam->state & DEV_DISCONNECTED) { - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -ENODEV; } - if (!timeout || (cam->state & DEV_MISCONFIGURED)) { - mutex_unlock(&cam->fileop_mutex); + if (cam->state & DEV_MISCONFIGURED) { + up(&cam->fileop_sem); return -EIO; } } @@ -1643,7 +1634,7 @@ exit: PDBGG("Frame #%lu, bytes read: %zu", (unsigned long)f->buf.index, count); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return count; } @@ -1656,7 +1647,7 @@ static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) unsigned long lock_flags; unsigned int mask = 0; - if (mutex_lock_interruptible(&cam->fileop_mutex)) + if (down_interruptible(&cam->fileop_sem)) return POLLERR; if (cam->state & DEV_DISCONNECTED) { @@ -1672,7 +1663,7 @@ static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) if (cam->io == IO_NONE) { if (!sn9c102_request_buffers(cam, cam->nreadbuffers, - IO_READ)) { + IO_READ)) { DBG(1, "poll() failed, not enough memory"); goto error; } @@ -1694,12 +1685,12 @@ static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) if (!list_empty(&cam->outqueue)) mask |= POLLIN | POLLRDNORM; - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return mask; error: - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return POLLERR; } @@ -1729,29 +1720,29 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) { struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start; + start = vma->vm_start; void *pos; u32 i; - if (mutex_lock_interruptible(&cam->fileop_mutex)) + if (down_interruptible(&cam->fileop_sem)) return -ERESTARTSYS; if (cam->state & DEV_DISCONNECTED) { DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -ENODEV; } if (cam->state & DEV_MISCONFIGURED) { DBG(1, "The camera is misconfigured. Close and open it " "again."); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EIO; } if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || size != PAGE_ALIGN(cam->frame[0].buf.length)) { - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EINVAL; } @@ -1760,7 +1751,7 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) break; } if (i == cam->nbuffers) { - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EINVAL; } @@ -1770,7 +1761,7 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) pos = cam->frame[i].bufmem; while (size > 0) { /* size is page-aligned */ if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EAGAIN; } start += PAGE_SIZE; @@ -1783,7 +1774,7 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) sn9c102_vm_open(vma); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return 0; } @@ -1797,13 +1788,13 @@ sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg) .driver = "sn9c102", .version = SN9C102_MODULE_VERSION_CODE, .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING, + V4L2_CAP_STREAMING, }; strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, - sizeof(cap.bus_info)); + sizeof(cap.bus_info)); if (copy_to_user(arg, &cap, sizeof(cap))) return -EFAULT; @@ -1825,7 +1816,6 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) memset(&i, 0, sizeof(i)); strcpy(i.name, "Camera"); - i.type = V4L2_INPUT_TYPE_CAMERA; if (copy_to_user(arg, &i, sizeof(i))) return -EFAULT; @@ -1835,19 +1825,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) static int -sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg) -{ - int index = 0; - - if (copy_to_user(arg, &index, sizeof(index))) - return -EFAULT; - - return 0; -} - - -static int -sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg) +sn9c102_vidioc_gs_input(struct sn9c102_device* cam, void __user * arg) { int index; @@ -1864,7 +1842,7 @@ sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg) static int sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg) { - struct sn9c102_sensor* s = &cam->sensor; + struct sn9c102_sensor* s = cam->sensor; struct v4l2_queryctrl qc; u8 i; @@ -1886,7 +1864,7 @@ sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg) static int sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg) { - struct sn9c102_sensor* s = &cam->sensor; + struct sn9c102_sensor* s = cam->sensor; struct v4l2_control ctrl; int err = 0; u8 i; @@ -1918,7 +1896,7 @@ exit: static int sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg) { - struct sn9c102_sensor* s = &cam->sensor; + struct sn9c102_sensor* s = cam->sensor; struct v4l2_control ctrl; u8 i; int err = 0; @@ -1931,8 +1909,6 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg) for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) if (ctrl.id == s->qctrl[i].id) { - if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) - return -EINVAL; if (ctrl.value < s->qctrl[i].minimum || ctrl.value > s->qctrl[i].maximum) return -ERANGE; @@ -1955,7 +1931,7 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg) static int sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg) { - struct v4l2_cropcap* cc = &(cam->sensor.cropcap); + struct v4l2_cropcap* cc = &(cam->sensor->cropcap); cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; cc->pixelaspect.numerator = 1; @@ -1971,7 +1947,7 @@ sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg) static int sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg) { - struct sn9c102_sensor* s = &cam->sensor; + struct sn9c102_sensor* s = cam->sensor; struct v4l2_crop crop = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, }; @@ -1988,7 +1964,7 @@ sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg) static int sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) { - struct sn9c102_sensor* s = &cam->sensor; + struct sn9c102_sensor* s = cam->sensor; struct v4l2_crop crop; struct v4l2_rect* rect; struct v4l2_rect* bounds = &(s->cropcap.bounds); @@ -2129,7 +2105,7 @@ static int sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) { struct v4l2_format format; - struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); + struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); if (copy_from_user(&format, arg, sizeof(format))) return -EFAULT; @@ -2138,7 +2114,7 @@ sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) return -EINVAL; pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X) - ? 0 : (pfmt->width * pfmt->priv) / 8; + ? 0 : (pfmt->width * pfmt->priv) / 8; pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); pfmt->field = V4L2_FIELD_NONE; memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt)); @@ -2152,9 +2128,9 @@ sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) static int sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, - void __user * arg) + void __user * arg) { - struct sn9c102_sensor* s = &cam->sensor; + struct sn9c102_sensor* s = cam->sensor; struct v4l2_format format; struct v4l2_pix_format* pix; struct v4l2_pix_format* pfmt = &(s->pix_format); @@ -2214,7 +2190,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, pix->priv = pfmt->priv; /* bpp */ pix->colorspace = pfmt->colorspace; pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) - ? 0 : (pix->width * pix->priv) / 8; + ? 0 : (pix->width * pix->priv) / 8; pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8); pix->field = V4L2_FIELD_NONE; @@ -2287,7 +2263,7 @@ static int sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg) { if (copy_to_user(arg, &cam->compression, - sizeof(cam->compression))) + sizeof(cam->compression))) return -EFAULT; return 0; @@ -2436,12 +2412,12 @@ sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg) static int sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp, - void __user * arg) + void __user * arg) { struct v4l2_buffer b; struct sn9c102_frame_t *f; unsigned long lock_flags; - long timeout; + int err = 0; if (copy_from_user(&b, arg, sizeof(b))) return -EFAULT; @@ -2454,18 +2430,16 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp, return -EINVAL; if (filp->f_flags & O_NONBLOCK) return -EAGAIN; - timeout = wait_event_interruptible_timeout - ( cam->wait_frame, - (!list_empty(&cam->outqueue)) || - (cam->state & DEV_DISCONNECTED) || - (cam->state & DEV_MISCONFIGURED), - cam->module_param.frame_timeout * - 1000 * msecs_to_jiffies(1) ); - if (timeout < 0) - return timeout; + err = wait_event_interruptible + ( cam->wait_frame, + (!list_empty(&cam->outqueue)) || + (cam->state & DEV_DISCONNECTED) || + (cam->state & DEV_MISCONFIGURED) ); + if (err) + return err; if (cam->state & DEV_DISCONNECTED) return -ENODEV; - if (!timeout || (cam->state & DEV_MISCONFIGURED)) + if (cam->state & DEV_MISCONFIGURED) return -EIO; } @@ -2584,7 +2558,7 @@ sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg) static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, - unsigned int cmd, void __user * arg) + unsigned int cmd, void __user * arg) { struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); @@ -2597,10 +2571,8 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, return sn9c102_vidioc_enuminput(cam, arg); case VIDIOC_G_INPUT: - return sn9c102_vidioc_g_input(cam, arg); - case VIDIOC_S_INPUT: - return sn9c102_vidioc_s_input(cam, arg); + return sn9c102_vidioc_gs_input(cam, arg); case VIDIOC_QUERYCTRL: return sn9c102_vidioc_query_ctrl(cam, arg); @@ -2678,24 +2650,24 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, static int sn9c102_ioctl(struct inode* inode, struct file* filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); int err = 0; - if (mutex_lock_interruptible(&cam->fileop_mutex)) + if (down_interruptible(&cam->fileop_sem)) return -ERESTARTSYS; if (cam->state & DEV_DISCONNECTED) { DBG(1, "Device not present"); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -ENODEV; } if (cam->state & DEV_MISCONFIGURED) { DBG(1, "The camera is misconfigured. Close and open it " "again."); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EIO; } @@ -2703,7 +2675,7 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return err; } @@ -2750,7 +2722,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) goto fail; } - mutex_init(&cam->dev_mutex); + init_MUTEX(&cam->dev_sem); r = sn9c102_read_reg(cam, 0x00); if (r < 0 || r != 0x10) { @@ -2761,7 +2733,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } cam->bridge = (id->idProduct & 0xffc0) == 0x6080 ? - BRIDGE_SN9C103 : BRIDGE_SN9C102; + BRIDGE_SN9C103 : BRIDGE_SN9C102; switch (cam->bridge) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: @@ -2780,10 +2752,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) break; } - if (!err) { - DBG(2, "%s image sensor detected", cam->sensor.name); + if (!err && cam->sensor) { + DBG(2, "%s image sensor detected", cam->sensor->name); DBG(3, "Support for %s maintained by %s", - cam->sensor.name, cam->sensor.maintainer); + cam->sensor->name, cam->sensor->maintainer); } else { DBG(1, "No supported image sensor detected"); err = -ENODEV; @@ -2804,24 +2776,23 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) cam->v4ldev->release = video_device_release; video_set_drvdata(cam->v4ldev, cam); - mutex_lock(&cam->dev_mutex); + down(&cam->dev_sem); err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, - video_nr[dev_nr]); + video_nr[dev_nr]); if (err) { DBG(1, "V4L2 device registration failed"); if (err == -ENFILE && video_nr[dev_nr] == -1) DBG(1, "Free /dev/videoX node not found"); video_nr[dev_nr] = -1; dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); goto fail; } DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); cam->module_param.force_munmap = force_munmap[dev_nr]; - cam->module_param.frame_timeout = frame_timeout[dev_nr]; dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; @@ -2832,7 +2803,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) usb_set_intfdata(intf, cam); - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); return 0; @@ -2856,7 +2827,7 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf) down_write(&sn9c102_disconnect); - mutex_lock(&cam->dev_mutex); + down(&cam->dev_sem); DBG(2, "Disconnecting %s...", cam->v4ldev->name); @@ -2870,14 +2841,13 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf) sn9c102_stop_transfer(cam); cam->state |= DEV_DISCONNECTED; wake_up_interruptible(&cam->wait_frame); - wake_up(&cam->wait_stream); - usb_get_dev(cam->usbdev); + wake_up_interruptible(&cam->wait_stream); } else { cam->state |= DEV_DISCONNECTED; sn9c102_release_resources(cam); } - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); if (!cam->users) kfree(cam); diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c similarity index 93% rename from drivers/media/video/sn9c102/sn9c102_hv7131d.c rename to drivers/usb/media/sn9c102_hv7131d.c index c4117bf64..46c12ec3c 100644 --- a/drivers/media/video/sn9c102/sn9c102_hv7131d.c +++ b/drivers/usb/media/sn9c102_hv7131d.c @@ -44,8 +44,8 @@ static int hv7131d_init(struct sn9c102_device* cam) } -static int hv7131d_get_ctrl(struct sn9c102_device* cam, - struct v4l2_control* ctrl) +static int hv7131d_get_ctrl(struct sn9c102_device* cam, + struct v4l2_control* ctrl) { switch (ctrl->id) { case V4L2_CID_EXPOSURE: @@ -88,8 +88,8 @@ static int hv7131d_get_ctrl(struct sn9c102_device* cam, } -static int hv7131d_set_ctrl(struct sn9c102_device* cam, - const struct v4l2_control* ctrl) +static int hv7131d_set_ctrl(struct sn9c102_device* cam, + const struct v4l2_control* ctrl) { int err = 0; @@ -121,8 +121,8 @@ static int hv7131d_set_ctrl(struct sn9c102_device* cam, } -static int hv7131d_set_crop(struct sn9c102_device* cam, - const struct v4l2_rect* rect) +static int hv7131d_set_crop(struct sn9c102_device* cam, + const struct v4l2_rect* rect) { struct sn9c102_sensor* s = &hv7131d; int err = 0; @@ -136,8 +136,8 @@ static int hv7131d_set_crop(struct sn9c102_device* cam, } -static int hv7131d_set_pix_format(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix) +static int hv7131d_set_pix_format(struct sn9c102_device* cam, + const struct v4l2_pix_format* pix) { int err = 0; diff --git a/drivers/media/video/sn9c102/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c similarity index 73% rename from drivers/media/video/sn9c102/sn9c102_mi0343.c rename to drivers/usb/media/sn9c102_mi0343.c index 4169ea4a2..d9aa7a610 100644 --- a/drivers/media/video/sn9c102/sn9c102_mi0343.c +++ b/drivers/usb/media/sn9c102_mi0343.c @@ -39,64 +39,64 @@ static int mi0343_init(struct sn9c102_device* cam) err += sn9c102_write_reg(cam, 0xa0, 0x19); err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, - 0x0d, 0x00, 0x01, 0, 0); + 0x0d, 0x00, 0x01, 0, 0); err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, - 0x0d, 0x00, 0x00, 0, 0); + 0x0d, 0x00, 0x00, 0, 0); err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, - 0x03, 0x01, 0xe1, 0, 0); + 0x03, 0x01, 0xe1, 0, 0); err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, - 0x04, 0x02, 0x81, 0, 0); + 0x04, 0x02, 0x81, 0, 0); err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, - 0x05, 0x00, 0x17, 0, 0); + 0x05, 0x00, 0x17, 0, 0); err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, - 0x06, 0x00, 0x11, 0, 0); + 0x06, 0x00, 0x11, 0, 0); err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, - 0x62, 0x04, 0x9a, 0, 0); + 0x62, 0x04, 0x9a, 0, 0); return err; } -static int mi0343_get_ctrl(struct sn9c102_device* cam, - struct v4l2_control* ctrl) +static int mi0343_get_ctrl(struct sn9c102_device* cam, + struct v4l2_control* ctrl) { switch (ctrl->id) { case V4L2_CID_EXPOSURE: if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, - 0x09, 2+1, mi0343_i2c_data) < 0) + 0x09, 2+1, mi0343_i2c_data) < 0) return -EIO; ctrl->value = mi0343_i2c_data[2]; return 0; case V4L2_CID_GAIN: if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, - 0x35, 2+1, mi0343_i2c_data) < 0) + 0x35, 2+1, mi0343_i2c_data) < 0) return -EIO; break; case V4L2_CID_HFLIP: if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, - 0x20, 2+1, mi0343_i2c_data) < 0) + 0x20, 2+1, mi0343_i2c_data) < 0) return -EIO; ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0; return 0; case V4L2_CID_VFLIP: if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, - 0x20, 2+1, mi0343_i2c_data) < 0) + 0x20, 2+1, mi0343_i2c_data) < 0) return -EIO; ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0; return 0; case V4L2_CID_RED_BALANCE: if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, - 0x2d, 2+1, mi0343_i2c_data) < 0) + 0x2d, 2+1, mi0343_i2c_data) < 0) return -EIO; break; case V4L2_CID_BLUE_BALANCE: if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, - 0x2c, 2+1, mi0343_i2c_data) < 0) + 0x2c, 2+1, mi0343_i2c_data) < 0) return -EIO; break; case SN9C102_V4L2_CID_GREEN_BALANCE: if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, - 0x2e, 2+1, mi0343_i2c_data) < 0) + 0x2e, 2+1, mi0343_i2c_data) < 0) return -EIO; break; default: @@ -121,8 +121,8 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam, } -static int mi0343_set_ctrl(struct sn9c102_device* cam, - const struct v4l2_control* ctrl) +static int mi0343_set_ctrl(struct sn9c102_device* cam, + const struct v4l2_control* ctrl) { u16 reg = 0; int err = 0; @@ -144,51 +144,51 @@ static int mi0343_set_ctrl(struct sn9c102_device* cam, switch (ctrl->id) { case V4L2_CID_EXPOSURE: err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x09, ctrl->value, 0x00, - 0, 0); + mi0343.i2c_slave_id, + 0x09, ctrl->value, 0x00, + 0, 0); break; case V4L2_CID_GAIN: err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x35, reg >> 8, reg & 0xff, - 0, 0); + mi0343.i2c_slave_id, + 0x35, reg >> 8, reg & 0xff, + 0, 0); break; case V4L2_CID_HFLIP: err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x20, ctrl->value ? 0x40:0x00, - ctrl->value ? 0x20:0x00, - 0, 0); + mi0343.i2c_slave_id, + 0x20, ctrl->value ? 0x40:0x00, + ctrl->value ? 0x20:0x00, + 0, 0); break; case V4L2_CID_VFLIP: err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x20, ctrl->value ? 0x80:0x00, - ctrl->value ? 0x80:0x00, - 0, 0); + mi0343.i2c_slave_id, + 0x20, ctrl->value ? 0x80:0x00, + ctrl->value ? 0x80:0x00, + 0, 0); break; case V4L2_CID_RED_BALANCE: err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x2d, reg >> 8, reg & 0xff, - 0, 0); + mi0343.i2c_slave_id, + 0x2d, reg >> 8, reg & 0xff, + 0, 0); break; case V4L2_CID_BLUE_BALANCE: err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x2c, reg >> 8, reg & 0xff, - 0, 0); + mi0343.i2c_slave_id, + 0x2c, reg >> 8, reg & 0xff, + 0, 0); break; case SN9C102_V4L2_CID_GREEN_BALANCE: err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x2b, reg >> 8, reg & 0xff, - 0, 0); + mi0343.i2c_slave_id, + 0x2b, reg >> 8, reg & 0xff, + 0, 0); err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x2e, reg >> 8, reg & 0xff, - 0, 0); + mi0343.i2c_slave_id, + 0x2e, reg >> 8, reg & 0xff, + 0, 0); break; default: return -EINVAL; @@ -198,8 +198,8 @@ static int mi0343_set_ctrl(struct sn9c102_device* cam, } -static int mi0343_set_crop(struct sn9c102_device* cam, - const struct v4l2_rect* rect) +static int mi0343_set_crop(struct sn9c102_device* cam, + const struct v4l2_rect* rect) { struct sn9c102_sensor* s = &mi0343; int err = 0; @@ -213,20 +213,20 @@ static int mi0343_set_crop(struct sn9c102_device* cam, } -static int mi0343_set_pix_format(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix) +static int mi0343_set_pix_format(struct sn9c102_device* cam, + const struct v4l2_pix_format* pix) { int err = 0; if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x0a, 0x00, 0x03, 0, 0); + mi0343.i2c_slave_id, + 0x0a, 0x00, 0x03, 0, 0); err += sn9c102_write_reg(cam, 0x20, 0x19); } else { err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, - mi0343.i2c_slave_id, - 0x0a, 0x00, 0x05, 0, 0); + mi0343.i2c_slave_id, + 0x0a, 0x00, 0x05, 0, 0); err += sn9c102_write_reg(cam, 0xa0, 0x19); } @@ -351,7 +351,7 @@ int sn9c102_probe_mi0343(struct sn9c102_device* cam) return -EIO; if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00, - 2, mi0343_i2c_data) < 0) + 2, mi0343_i2c_data) < 0) return -EIO; if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3) diff --git a/drivers/media/video/sn9c102/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c similarity index 94% rename from drivers/media/video/sn9c102/sn9c102_pas106b.c rename to drivers/usb/media/sn9c102_pas106b.c index 991594423..b1dee78ab 100644 --- a/drivers/media/video/sn9c102/sn9c102_pas106b.c +++ b/drivers/usb/media/sn9c102_pas106b.c @@ -53,8 +53,8 @@ static int pas106b_init(struct sn9c102_device* cam) } -static int pas106b_get_ctrl(struct sn9c102_device* cam, - struct v4l2_control* ctrl) +static int pas106b_get_ctrl(struct sn9c102_device* cam, + struct v4l2_control* ctrl) { switch (ctrl->id) { case V4L2_CID_EXPOSURE: @@ -102,8 +102,8 @@ static int pas106b_get_ctrl(struct sn9c102_device* cam, } -static int pas106b_set_ctrl(struct sn9c102_device* cam, - const struct v4l2_control* ctrl) +static int pas106b_set_ctrl(struct sn9c102_device* cam, + const struct v4l2_control* ctrl) { int err = 0; @@ -140,8 +140,8 @@ static int pas106b_set_ctrl(struct sn9c102_device* cam, } -static int pas106b_set_crop(struct sn9c102_device* cam, - const struct v4l2_rect* rect) +static int pas106b_set_crop(struct sn9c102_device* cam, + const struct v4l2_rect* rect) { struct sn9c102_sensor* s = &pas106b; int err = 0; @@ -155,8 +155,8 @@ static int pas106b_set_crop(struct sn9c102_device* cam, } -static int pas106b_set_pix_format(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix) +static int pas106b_set_pix_format(struct sn9c102_device* cam, + const struct v4l2_pix_format* pix) { int err = 0; diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/usb/media/sn9c102_pas202bcb.c similarity index 93% rename from drivers/media/video/sn9c102/sn9c102_pas202bcb.c rename to drivers/usb/media/sn9c102_pas202bcb.c index e3c1178e3..5ca54c7da 100644 --- a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c +++ b/drivers/usb/media/sn9c102_pas202bcb.c @@ -58,8 +58,8 @@ static int pas202bcb_init(struct sn9c102_device* cam) } -static int pas202bcb_get_ctrl(struct sn9c102_device* cam, - struct v4l2_control* ctrl) +static int pas202bcb_get_ctrl(struct sn9c102_device* cam, + struct v4l2_control* ctrl) { switch (ctrl->id) { case V4L2_CID_EXPOSURE: @@ -101,8 +101,8 @@ static int pas202bcb_get_ctrl(struct sn9c102_device* cam, } -static int pas202bcb_set_pix_format(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix) +static int pas202bcb_set_pix_format(struct sn9c102_device* cam, + const struct v4l2_pix_format* pix) { int err = 0; @@ -115,8 +115,8 @@ static int pas202bcb_set_pix_format(struct sn9c102_device* cam, } -static int pas202bcb_set_ctrl(struct sn9c102_device* cam, - const struct v4l2_control* ctrl) +static int pas202bcb_set_ctrl(struct sn9c102_device* cam, + const struct v4l2_control* ctrl) { int err = 0; @@ -149,8 +149,8 @@ static int pas202bcb_set_ctrl(struct sn9c102_device* cam, } -static int pas202bcb_set_crop(struct sn9c102_device* cam, - const struct v4l2_rect* rect) +static int pas202bcb_set_crop(struct sn9c102_device* cam, + const struct v4l2_rect* rect) { struct sn9c102_sensor* s = &pas202bcb; int err = 0; @@ -167,7 +167,7 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam, static struct sn9c102_sensor pas202bcb = { .name = "PAS202BCB", .maintainer = "Carlos Eduardo Medaglia Dyonisio " - "", + "", .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, .interface = SN9C102_I2C_2WIRES, @@ -263,7 +263,7 @@ static struct sn9c102_sensor pas202bcb = { int sn9c102_probe_pas202bcb(struct sn9c102_device* cam) -{ +{ int r0 = 0, r1 = 0, err = 0; unsigned int pid = 0; diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h similarity index 90% rename from drivers/media/video/sn9c102/sn9c102_sensor.h rename to drivers/usb/media/sn9c102_sensor.h index 2a874ee6f..7d953b24f 100644 --- a/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/drivers/usb/media/sn9c102_sensor.h @@ -58,7 +58,7 @@ struct sn9c102_sensor; Probing functions: on success, you must attach the sensor to the camera by calling sn9c102_attach_sensor() provided below. To enable the I2C communication, you might need to perform a really basic - initialization of the SN9C10X chip by using the write function declared + initialization of the SN9C10X chip by using the write function declared ahead. Functions must return 0 on success, the appropriate error otherwise. */ @@ -66,14 +66,13 @@ extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); extern int sn9c102_probe_ov7630(struct sn9c102_device* cam); extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); -extern int sn9c102_probe_pas202bca(struct sn9c102_device* cam); extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam); /* Add the above entries to this table. Be sure to add the entry in the right - place, since, on failure, the next probing routine is called according to + place, since, on failure, the next probing routine is called according to the order of the list below, from top to bottom. */ #define SN9C102_SENSOR_TABLE \ @@ -82,21 +81,16 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { \ &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \ &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \ &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \ - &sn9c102_probe_pas202bca, /* detection mostly based on USB pid/vid */ \ &sn9c102_probe_ov7630, /* detection mostly based on USB pid/vid */ \ &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \ &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \ NULL, \ }; -/* Device identification */ -extern struct sn9c102_device* -sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id); - /* Attach a probed sensor to the camera. */ -extern void +extern void sn9c102_attach_sensor(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor); + struct sn9c102_sensor* sensor); /* Each SN9C10x camera has proper PID/VID identifiers. @@ -105,7 +99,7 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, */ #define SN9C102_USB_DEVICE(vend, prod, intclass) \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ - USB_DEVICE_ID_MATCH_INT_CLASS, \ + USB_DEVICE_ID_MATCH_INT_CLASS, \ .idVendor = (vend), \ .idProduct = (prod), \ .bInterfaceClass = (intclass) @@ -114,7 +108,6 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, static const struct usb_device_id sn9c102_id_table[] = { \ { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \ { USB_DEVICE(0x0c45, 0x6005), }, /* TAS5110C1B */ \ - { USB_DEVICE(0x0c45, 0x6007), }, \ { USB_DEVICE(0x0c45, 0x6009), }, /* PAS106B */ \ { USB_DEVICE(0x0c45, 0x600d), }, /* PAS106B */ \ { USB_DEVICE(0x0c45, 0x6024), }, \ @@ -133,7 +126,7 @@ static const struct usb_device_id sn9c102_id_table[] = { \ { SN9C102_USB_DEVICE(0x0c45, 0x6088, 0xff), }, \ { SN9C102_USB_DEVICE(0x0c45, 0x608a, 0xff), }, \ { SN9C102_USB_DEVICE(0x0c45, 0x608b, 0xff), }, \ - { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131/R */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131x */ \ { SN9C102_USB_DEVICE(0x0c45, 0x608e, 0xff), }, /* CIS-VF10 */ \ { SN9C102_USB_DEVICE(0x0c45, 0x608f, 0xff), }, /* OV7630 */ \ { SN9C102_USB_DEVICE(0x0c45, 0x60a0, 0xff), }, \ @@ -162,19 +155,19 @@ static const struct usb_device_id sn9c102_id_table[] = { \ Read/write routines: they always return -1 on error, 0 or the read value otherwise. NOTE that a real read operation is not supported by the SN9C10X chip for some of its registers. To work around this problem, a pseudo-read - call is provided instead: it returns the last successfully written value + call is provided instead: it returns the last successfully written value on the register (0 if it has never been written), the usual -1 on error. */ /* The "try" I2C I/O versions are used when probing the sensor */ extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*, - u8 address, u8 value); + u8 address, u8 value); extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*, - u8 address); + u8 address); /* These must be used if and only if the sensor doesn't implement the standard - I2C protocol. There are a number of good reasons why you must use the + I2C protocol. There are a number of good reasons why you must use the single-byte versions of these functions: do not abuse. The first function writes n bytes, from data0 to datan, to registers 0x09 - 0x09+n of SN9C10X chip. The second one programs the registers 0x09 and 0x10 with data0 and @@ -184,12 +177,12 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*, byte. */ extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 n, - u8 data0, u8 data1, u8 data2, u8 data3, - u8 data4, u8 data5); + struct sn9c102_sensor* sensor, u8 n, + u8 data0, u8 data1, u8 data2, u8 data3, + u8 data4, u8 data5); extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 data0, - u8 data1, u8 n, u8 buffer[]); + struct sn9c102_sensor* sensor, u8 data0, + u8 data1, u8 n, u8 buffer[]); /* To be used after the sensor struct has been attached to the camera struct */ extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value); @@ -252,17 +245,17 @@ struct sn9c102_sensor { /* NOTE: Where not noted,most of the functions below are not mandatory. - Set to null if you do not implement them. If implemented, - they must return 0 on success, the proper error otherwise. + Set to null if you do not implement them. If implemented, + they must return 0 on success, the proper error otherwise. */ int (*init)(struct sn9c102_device* cam); /* - This function will be called after the sensor has been attached. + This function will be called after the sensor has been attached. It should be used to initialize the sensor only, but may also configure part of the SN9C10X chip if necessary. You don't need to setup picture settings like brightness, contrast, etc.. here, if - the corrisponding controls are implemented (see below), since + the corrisponding controls are implemented (see below), since they are adjusted in the core driver by calling the set_ctrl() method after init(), where the arguments are the default values specified in the v4l2_queryctrl list of supported controls; @@ -273,13 +266,13 @@ struct sn9c102_sensor { struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS]; /* - Optional list of default controls, defined as indicated in the + Optional list of default controls, defined as indicated in the V4L2 API. Menu type controls are not handled by this interface. */ int (*get_ctrl)(struct sn9c102_device* cam, struct v4l2_control* ctrl); int (*set_ctrl)(struct sn9c102_device* cam, - const struct v4l2_control* ctrl); + const struct v4l2_control* ctrl); /* You must implement at least the set_ctrl method if you have defined the list above. The returned value must follow the V4L2 @@ -306,7 +299,7 @@ struct sn9c102_sensor { specified in the cropcap substructures 'bounds' and 'defrect'. By default, the source rectangle should cover the largest possible area. Again, it is not always true that the largest source rectangle - can cover the entire active window, although it is a rare case for + can cover the entire active window, although it is a rare case for the hardware we have. The bounds of the source rectangle _must_ be multiple of 16 and must use the same coordinate system as indicated before; their centers shall align initially. @@ -317,13 +310,13 @@ struct sn9c102_sensor { defined the correct default bounds in the structures. See the V4L2 API for further details. NOTE: once you have defined the bounds of the active window - (struct cropcap.bounds) you must not change them.anymore. + (struct cropcap.bounds) you must not change them.anymore. Only 'bounds' and 'defrect' fields are mandatory, other fields will be ignored. */ int (*set_crop)(struct sn9c102_device* cam, - const struct v4l2_rect* rect); + const struct v4l2_rect* rect); /* To be called on VIDIOC_C_SETCROP. The core module always calls a default routine which configures the appropriate SN9C10X regs (also @@ -332,12 +325,12 @@ struct sn9c102_sensor { case you override the default function, you always have to program the chip to match those values; on error return the corresponding error code without rolling back. - NOTE: in case, you must program the SN9C10X chip to get rid of - blank pixels or blank lines at the _start_ of each line or - frame after each HSYNC or VSYNC, so that the image starts with - real RGB data (see regs 0x12, 0x13) (having set H_SIZE and, - V_SIZE you don't have to care about blank pixels or blank - lines at the end of each line or frame). + NOTE: in case, you must program the SN9C10X chip to get rid of + blank pixels or blank lines at the _start_ of each line or + frame after each HSYNC or VSYNC, so that the image starts with + real RGB data (see regs 0x12, 0x13) (having set H_SIZE and, + V_SIZE you don't have to care about blank pixels or blank + lines at the end of each line or frame). */ struct v4l2_pix_format pix_format; @@ -349,23 +342,29 @@ struct sn9c102_sensor { number of bits per pixel for uncompressed video, 8 or 9 (despite the current value of 'pixelformat'). NOTE 1: both 'width' and 'height' _must_ be either 1/1 or 1/2 or 1/4 - of cropcap.defrect.width and cropcap.defrect.height. I - suggest 1/1. + of cropcap.defrect.width and cropcap.defrect.height. I + suggest 1/1. NOTE 2: The initial compression quality is defined by the first bit - of reg 0x17 during the initialization of the image sensor. + of reg 0x17 during the initialization of the image sensor. NOTE 3: as said above, you have to program the SN9C10X chip to get - rid of any blank pixels, so that the output of the sensor - matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR). + rid of any blank pixels, so that the output of the sensor + matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR). */ int (*set_pix_format)(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix); + const struct v4l2_pix_format* pix); /* To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to SN9C10X pixel format or viceversa. On error return the corresponding error code without rolling back. */ + const struct usb_device* usbdev; + /* + Points to the usb_device struct after the sensor is attached. + Do not touch unless you know what you are doing. + */ + /* Do NOT write to the data below, it's READ ONLY. It is used by the core module to store successfully updated values of the above diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c similarity index 87% rename from drivers/media/video/sn9c102/sn9c102_tas5110c1b.c rename to drivers/usb/media/sn9c102_tas5110c1b.c index 294eb02fb..32ddf236c 100644 --- a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c +++ b/drivers/usb/media/sn9c102_tas5110c1b.c @@ -44,8 +44,8 @@ static int tas5110c1b_init(struct sn9c102_device* cam) } -static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, - const struct v4l2_control* ctrl) +static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, + const struct v4l2_control* ctrl) { int err = 0; @@ -61,8 +61,8 @@ static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, } -static int tas5110c1b_set_crop(struct sn9c102_device* cam, - const struct v4l2_rect* rect) +static int tas5110c1b_set_crop(struct sn9c102_device* cam, + const struct v4l2_rect* rect) { struct sn9c102_sensor* s = &tas5110c1b; int err = 0; @@ -81,8 +81,8 @@ static int tas5110c1b_set_crop(struct sn9c102_device* cam, } -static int tas5110c1b_set_pix_format(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix) +static int tas5110c1b_set_pix_format(struct sn9c102_device* cam, + const struct v4l2_pix_format* pix) { int err = 0; @@ -142,18 +142,14 @@ static struct sn9c102_sensor tas5110c1b = { int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam) { - const struct usb_device_id tas5110c1b_id_table[] = { - { USB_DEVICE(0x0c45, 0x6001), }, - { USB_DEVICE(0x0c45, 0x6005), }, - { USB_DEVICE(0x0c45, 0x60ab), }, - { } - }; + /* This sensor has no identifiers, so let's attach it anyway */ + sn9c102_attach_sensor(cam, &tas5110c1b); /* Sensor detection is based on USB pid/vid */ - if (!sn9c102_match_id(cam, tas5110c1b_id_table)) + if (le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6001 && + le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6005 && + le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x60ab) return -ENODEV; - sn9c102_attach_sensor(cam, &tas5110c1b); - return 0; } diff --git a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c similarity index 89% rename from drivers/media/video/sn9c102/sn9c102_tas5130d1b.c rename to drivers/usb/media/sn9c102_tas5130d1b.c index 9ecb09032..a0728f0ae 100644 --- a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c +++ b/drivers/usb/media/sn9c102_tas5130d1b.c @@ -42,8 +42,8 @@ static int tas5130d1b_init(struct sn9c102_device* cam) } -static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, - const struct v4l2_control* ctrl) +static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, + const struct v4l2_control* ctrl) { int err = 0; @@ -62,8 +62,8 @@ static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, } -static int tas5130d1b_set_crop(struct sn9c102_device* cam, - const struct v4l2_rect* rect) +static int tas5130d1b_set_crop(struct sn9c102_device* cam, + const struct v4l2_rect* rect) { struct sn9c102_sensor* s = &tas5130d1b; u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 104, @@ -82,8 +82,8 @@ static int tas5130d1b_set_crop(struct sn9c102_device* cam, } -static int tas5130d1b_set_pix_format(struct sn9c102_device* cam, - const struct v4l2_pix_format* pix) +static int tas5130d1b_set_pix_format(struct sn9c102_device* cam, + const struct v4l2_pix_format* pix) { int err = 0; @@ -153,17 +153,13 @@ static struct sn9c102_sensor tas5130d1b = { int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam) { - const struct usb_device_id tas5130d1b_id_table[] = { - { USB_DEVICE(0x0c45, 0x6025), }, - { USB_DEVICE(0x0c45, 0x60aa), }, - { } - }; + /* This sensor has no identifiers, so let's attach it anyway */ + sn9c102_attach_sensor(cam, &tas5130d1b); /* Sensor detection is based on USB pid/vid */ - if (!sn9c102_match_id(cam, tas5130d1b_id_table)) + if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6025 && + le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x60aa) return -ENODEV; - sn9c102_attach_sensor(cam, &tas5130d1b); - return 0; } diff --git a/drivers/media/video/stv680.c b/drivers/usb/media/stv680.c similarity index 98% rename from drivers/media/video/stv680.c rename to drivers/usb/media/stv680.c index b38bda83a..b497a6a0a 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/usb/media/stv680.c @@ -1,16 +1,16 @@ /* * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net) - * - * Thanks to STMicroelectronics for information on the usb commands, and - * to Steve Miller at STM for his help and encouragement while I was + * + * Thanks to STMicroelectronics for information on the usb commands, and + * to Steve Miller at STM for his help and encouragement while I was * writing this driver. * - * This driver is based heavily on the + * This driver is based heavily on the * Endpoints (formerly known as AOX) se401 USB Camera Driver * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org) * * Still somewhat based on the Linux ov511 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 @@ -25,18 +25,18 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * History: - * ver 0.1 October, 2001. Initial attempt. + * History: + * ver 0.1 October, 2001. Initial attempt. * * ver 0.2 November, 2001. Fixed asbility to resize, added brightness * function, made more stable (?) * - * ver 0.21 Nov, 2001. Added gamma correction and white balance, - * due to Alexander Schwartz. Still trying to + * ver 0.21 Nov, 2001. Added gamma correction and white balance, + * due to Alexander Schwartz. Still trying to * improve stablility. Moved stuff into stv680.h * - * ver 0.22 Nov, 2001. Added sharpen function (by Michael Sweet, - * mike@easysw.com) from GIMP, also used in pencam. + * ver 0.22 Nov, 2001. Added sharpen function (by Michael Sweet, + * mike@easysw.com) from GIMP, also used in pencam. * Simple, fast, good integer math routine. * * ver 0.23 Dec, 2001 (gkh) @@ -44,11 +44,11 @@ * Lindent, and did other minor tweaks to get * things to work properly with 2.5.1 * - * ver 0.24 Jan, 2002 (kjs) + * ver 0.24 Jan, 2002 (kjs) * Fixed the problem with webcam crashing after - * two pictures. Changed the way pic is halved to - * improve quality. Got rid of green line around - * frame. Fix brightness reset when changing size + * two pictures. Changed the way pic is halved to + * improve quality. Got rid of green line around + * frame. Fix brightness reset when changing size * bug. Adjusted gamma filters slightly. * * ver 0.25 Jan, 2002 (kjs) @@ -67,7 +67,6 @@ #include #include #include -#include #include "stv680.h" @@ -318,11 +317,12 @@ static int stv_init (struct usb_stv *stv680) unsigned char *buffer; unsigned long int bufsize; - buffer = kzalloc (40, GFP_KERNEL); + buffer = kmalloc (40, GFP_KERNEL); if (buffer == NULL) { PDEBUG (0, "STV(e): Out of (small buf) memory"); return -1; } + memset (buffer, 0, 40); udelay (100); /* set config 1, interface 0, alternate 0 */ @@ -484,7 +484,7 @@ exit: PDEBUG (1, "STV(i): swapRGB is (forced) ON"); else if (swapRGB_on == -1) PDEBUG (1, "STV(i): swapRGB is (forced) OFF"); - + if (stv_set_video_mode (stv680) < 0) { PDEBUG (0, "STV(e): Could not set video mode in stv_init"); return -1; @@ -570,7 +570,7 @@ static int stv680_set_pict (struct usb_stv *stv680, struct video_picture *p) if (stv680->brightness != p->brightness) { stv680->chgbright = 1; stv680->brightness = p->brightness; - } + } stv680->whiteness = p->whiteness; /* greyscale */ stv680->colour = p->colour; @@ -612,7 +612,7 @@ static void stv680_video_irq (struct urb *urb, struct pt_regs *regs) case BUFFER_UNUSED: memcpy (stv680->scratch[stv680->scratch_next].data, - (unsigned char *) urb->transfer_buffer, length); + (unsigned char *) urb->transfer_buffer, length); stv680->scratch[stv680->scratch_next].state = BUFFER_READY; stv680->scratch[stv680->scratch_next].length = length; if (waitqueue_active (&stv680->wq)) { @@ -752,7 +752,7 @@ static int stv680_set_size (struct usb_stv *stv680, int width, int height) PDEBUG (1, "STV(e): request for non-supported size: request: v.width = %i, v.height = %i actual: stv.width = %i, stv.height = %i", width, height, stv680->vwidth, stv680->vheight); return 1; } - + /* Stop a current stream and start it again at the new size */ if (wasstreaming) stv680_stop_stream (stv680); @@ -773,7 +773,7 @@ static int stv680_set_size (struct usb_stv *stv680, int width, int height) /* * STV0680 Vision Camera Chipset Driver - * Copyright (C) 2000 Adam Harrison + * Copyright (C) 2000 Adam Harrison */ #define RED 0 @@ -842,7 +842,7 @@ static void bayer_unshuffle (struct usb_stv *stv680, struct stv680_scratch *buff colour = 2; break; } - i = (y * vw + x) * 3; + i = (y * vw + x) * 3; *(output + i + colour) = (unsigned char) p; } /* for x */ @@ -850,9 +850,9 @@ static void bayer_unshuffle (struct usb_stv *stv680, struct stv680_scratch *buff /****** gamma correction plus hardcoded white balance */ /* Thanks to Alexander Schwartx for this code. - Correction values red[], green[], blue[], are generated by - (pow(i/256.0, GAMMA)*255.0)*white balanceRGB where GAMMA=0.55, 1vm_end-vma->vm_start; unsigned long page, pos; - mutex_lock(&stv680->lock); + down (&stv680->lock); if (stv680->udev == NULL) { - mutex_unlock(&stv680->lock); + up (&stv680->lock); return -EIO; } if (size > (((STV680_NUMFRAMES * stv680->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) { - mutex_unlock(&stv680->lock); + up (&stv680->lock); return -EINVAL; } pos = (unsigned long) stv680->fbuf; while (size > 0) { page = vmalloc_to_pfn((void *)pos); if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { - mutex_unlock(&stv680->lock); + up (&stv680->lock); return -EAGAIN; } start += PAGE_SIZE; @@ -1283,7 +1283,7 @@ static int stv680_mmap (struct file *file, struct vm_area_struct *vma) else size = 0; } - mutex_unlock(&stv680->lock); + up (&stv680->lock); return 0; } @@ -1387,12 +1387,14 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id goto error; } /* We found one */ - if ((stv680 = kzalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) { + if ((stv680 = kmalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) { PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct."); retval = -ENOMEM; goto error; } + memset (stv680, 0, sizeof (*stv680)); + stv680->udev = dev; stv680->camera_name = camera_name; @@ -1407,7 +1409,7 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name)); init_waitqueue_head (&stv680->wq); - mutex_init (&stv680->lock); + init_MUTEX (&stv680->lock); wmb (); if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { diff --git a/drivers/media/video/stv680.h b/drivers/usb/media/stv680.h similarity index 54% rename from drivers/media/video/stv680.h rename to drivers/usb/media/stv680.h index a08f1b08a..b0551cdb2 100644 --- a/drivers/media/video/stv680.h +++ b/drivers/usb/media/stv680.h @@ -9,12 +9,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You 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. @@ -118,7 +118,7 @@ struct usb_stv { int origGain; int origMode; /* original camera mode */ - struct mutex lock; /* to lock the structure */ + struct semaphore lock; /* to lock the structure */ int user; /* user count for exclusive use */ int removed; /* device disconnected */ int streaming; /* Are we streaming video? */ @@ -152,76 +152,76 @@ struct usb_stv { static const unsigned char red[256] = { - 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, - 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, - 71, 71, 73, 75, 77, 78, 80, 81, 82, 84, 85, 87, - 88, 89, 90, 91, 93, 94, 95, 97, 98, 98, 99, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, - 134, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143, - 143, 143, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, - 152, 152, 152, 153, 154, 154, 155, 156, 157, 157, 158, 159, - 159, 160, 161, 161, 161, 162, 163, 163, 164, 165, 165, 166, - 167, 167, 168, 168, 169, 170, 170, 170, 171, 171, 172, 173, - 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 179, 179, - 180, 180, 181, 181, 182, 183, 183, 184, 184, 185, 185, 186, - 187, 187, 188, 188, 188, 188, 189, 190, 190, 191, 191, 192, - 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 197, 197, - 198, 198, 199, 199, 200, 201, 201, 202, 202, 203, 203, 204, - 204, 205, 205, 206, 206, 206, 206, 207, 207, 208, 208, 209, - 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, - 215, 215, 215, 216, 216, 217, 217, 218, 218, 218, 219, 219, - 220, 220, 221, 221 -}; + 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, + 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, + 71, 71, 73, 75, 77, 78, 80, 81, 82, 84, 85, 87, + 88, 89, 90, 91, 93, 94, 95, 97, 98, 98, 99, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, + 134, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143, + 143, 143, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, + 152, 152, 152, 153, 154, 154, 155, 156, 157, 157, 158, 159, + 159, 160, 161, 161, 161, 162, 163, 163, 164, 165, 165, 166, + 167, 167, 168, 168, 169, 170, 170, 170, 171, 171, 172, 173, + 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 179, 179, + 180, 180, 181, 181, 182, 183, 183, 184, 184, 185, 185, 186, + 187, 187, 188, 188, 188, 188, 189, 190, 190, 191, 191, 192, + 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 197, 197, + 198, 198, 199, 199, 200, 201, 201, 202, 202, 203, 203, 204, + 204, 205, 205, 206, 206, 206, 206, 207, 207, 208, 208, 209, + 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, + 215, 215, 215, 216, 216, 217, 217, 218, 218, 218, 219, 219, + 220, 220, 221, 221 +}; static const unsigned char green[256] = { - 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, - 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, - 79, 80, 82, 84, 86, 87, 89, 91, 92, 94, 95, 97, - 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 111, 113, - 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, - 150, 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, - 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168, - 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, - 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, - 186, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, - 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200, - 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207, - 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, - 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220, - 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, - 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, - 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, - 239, 240, 240, 241, 241, 242, 242, 243, 243, 243, 244, 244, - 245, 245, 246, 246 -}; + 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, + 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, + 79, 80, 82, 84, 86, 87, 89, 91, 92, 94, 95, 97, + 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 111, 113, + 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, + 150, 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, + 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168, + 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, + 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, + 186, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, + 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200, + 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207, + 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, + 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220, + 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, + 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, + 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, + 239, 240, 240, 241, 241, 242, 242, 243, 243, 243, 244, 244, + 245, 245, 246, 246 +}; static const unsigned char blue[256] = { - 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, - 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, - 86, 88, 90, 92, 94, 95, 97, 100, 101, 103, 104, 106, - 107, 110, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, - 125, 126, 127, 128, 129, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163, - 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, - 176, 176, 177, 178, 179, 180, 180, 181, 182, 183, 183, 184, - 185, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194, - 194, 195, 196, 196, 198, 199, 200, 200, 201, 202, 202, 203, - 204, 204, 205, 205, 206, 207, 207, 209, 210, 210, 211, 212, - 212, 213, 213, 214, 215, 215, 216, 217, 217, 218, 218, 220, - 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, - 228, 228, 229, 229, 231, 231, 232, 233, 233, 234, 234, 235, - 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 242, 242, - 243, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249, - 249, 250, 250, 251, 251, 253, 253, 254, 254, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255 -}; + 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, + 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, + 86, 88, 90, 92, 94, 95, 97, 100, 101, 103, 104, 106, + 107, 110, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, + 125, 126, 127, 128, 129, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163, + 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, + 176, 176, 177, 178, 179, 180, 180, 181, 182, 183, 183, 184, + 185, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194, + 194, 195, 196, 196, 198, 199, 200, 200, 201, 202, 202, 203, + 204, 204, 205, 205, 206, 207, 207, 209, 210, 210, 211, 212, + 212, 213, 213, 214, 215, 215, 216, 217, 217, 218, 218, 220, + 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, + 228, 228, 229, 229, 231, 231, 232, 233, 233, 234, 234, 235, + 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 242, 242, + 243, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249, + 249, 250, 250, 251, 251, 253, 253, 254, 254, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255 +}; diff --git a/drivers/media/video/usbvideo/ultracam.c b/drivers/usb/media/ultracam.c similarity index 99% rename from drivers/media/video/usbvideo/ultracam.c rename to drivers/usb/media/ultracam.c index 10c58b4a2..75ff75522 100644 --- a/drivers/media/video/usbvideo/ultracam.c +++ b/drivers/usb/media/ultracam.c @@ -23,7 +23,7 @@ typedef struct { int initialized; /* Had we already sent init sequence? */ int camera_model; /* What type of IBM camera we got? */ - int has_hdr; + int has_hdr; } ultracam_t; #define ULTRACAM_T(uvd) ((ultracam_t *)((uvd)->user_data)) diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/usb/media/usbvideo.c similarity index 98% rename from drivers/media/video/usbvideo/usbvideo.c rename to drivers/usb/media/usbvideo.c index 13b37c8c0..63a72e550 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/usb/media/usbvideo.c @@ -574,7 +574,7 @@ void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode) } else { /* Just the blue screen */ } - + *f++ = cb; *f++ = cg; *f++ = cr; @@ -690,13 +690,14 @@ int usbvideo_register( } base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo); - cams = (struct usbvideo *) kzalloc(base_size, GFP_KERNEL); + cams = (struct usbvideo *) kmalloc(base_size, GFP_KERNEL); if (cams == NULL) { err("Failed to allocate %d. bytes for usbvideo struct", base_size); return -ENOMEM; } dbg("%s: Allocated $%p (%d. bytes) for %d. cameras", __FUNCTION__, cams, base_size, num_cams); + memset(cams, 0, base_size); /* Copy callbacks, apply defaults for those that are not set */ memmove(&cams->cb, cbTbl, sizeof(cams->cb)); @@ -714,7 +715,7 @@ int usbvideo_register( cams->md_module = md; if (cams->md_module == NULL) warn("%s: module == NULL!", __FUNCTION__); - mutex_init(&cams->lock); /* to 1 == available */ + init_MUTEX(&cams->lock); /* to 1 == available */ for (i = 0; i < num_cams; i++) { struct uvd *up = &cams->cam[i]; @@ -862,7 +863,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) if (uvd->debug > 0) info("%s(%p.)", __FUNCTION__, intf); - mutex_lock(&uvd->lock); + down(&uvd->lock); uvd->remove_pending = 1; /* Now all ISO data will be ignored */ /* At this time we ask to cancel outstanding URBs */ @@ -882,7 +883,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) info("%s: In use, disconnect pending.", __FUNCTION__); else usbvideo_CameraRelease(uvd); - mutex_unlock(&uvd->lock); + up(&uvd->lock); info("USB camera disconnected."); usbvideo_ClientDecModCount(uvd); @@ -929,19 +930,19 @@ static int usbvideo_find_struct(struct usbvideo *cams) err("No usbvideo handle?"); return -1; } - mutex_lock(&cams->lock); + down(&cams->lock); for (u = 0; u < cams->num_cameras; u++) { struct uvd *uvd = &cams->cam[u]; if (!uvd->uvd_used) /* This one is free */ { uvd->uvd_used = 1; /* In use now */ - mutex_init(&uvd->lock); /* to 1 == available */ + init_MUTEX(&uvd->lock); /* to 1 == available */ uvd->dev = NULL; rv = u; break; } } - mutex_unlock(&cams->lock); + up(&cams->lock); return rv; } @@ -983,7 +984,7 @@ struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams) /* Not relying upon caller we increase module counter ourselves */ usbvideo_ClientIncModCount(uvd); - mutex_lock(&uvd->lock); + down(&uvd->lock); for (i=0; i < USBVIDEO_NUMSBUF; i++) { uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); if (uvd->sbuf[i].urb == NULL) { @@ -1006,7 +1007,7 @@ struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams) * return control to the client's probe function right now. */ allocate_done: - mutex_unlock(&uvd->lock); + up (&uvd->lock); usbvideo_ClientDecModCount(uvd); return uvd; } @@ -1120,7 +1121,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) info("%s($%p)", __FUNCTION__, dev); usbvideo_ClientIncModCount(uvd); - mutex_lock(&uvd->lock); + down(&uvd->lock); if (uvd->user) { err("%s: Someone tried to open an already opened device!", __FUNCTION__); @@ -1201,7 +1202,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) } } } - mutex_unlock(&uvd->lock); + up(&uvd->lock); if (errCode != 0) usbvideo_ClientDecModCount(uvd); if (uvd->debug > 0) @@ -1230,7 +1231,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) if (uvd->debug > 1) info("%s($%p)", __FUNCTION__, dev); - mutex_lock(&uvd->lock); + down(&uvd->lock); GET_CALLBACK(uvd, stopDataPump)(uvd); usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size); uvd->fbuf = NULL; @@ -1243,7 +1244,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) #if USBVIDEO_REPORT_STATS usbvideo_ReportStatistics(uvd); -#endif +#endif uvd->user--; if (uvd->remove_pending) { @@ -1251,7 +1252,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) info("usbvideo_v4l_close: Final disconnect."); usbvideo_CameraRelease(uvd); } - mutex_unlock(&uvd->lock); + up(&uvd->lock); usbvideo_ClientDecModCount(uvd); if (uvd->debug > 1) @@ -1290,7 +1291,7 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOCSCHAN: - { + { struct video_channel *v = arg; if (v->channel != 0) return -EINVAL; @@ -1347,7 +1348,7 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, vw->chromakey = 0; if (VALID_CALLBACK(uvd, getFPS)) vw->flags = GET_CALLBACK(uvd, getFPS)(uvd); - else + else vw->flags = 10; /* FIXME: do better! */ return 0; } @@ -1359,7 +1360,7 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, memset(vm, 0, sizeof(*vm)); vm->size = uvd->max_frame_size * USBVIDEO_NUMFRAMES; vm->frames = USBVIDEO_NUMFRAMES; - for(i = 0; i < USBVIDEO_NUMFRAMES; i++) + for(i = 0; i < USBVIDEO_NUMFRAMES; i++) vm->offsets[i] = i * uvd->max_frame_size; return 0; @@ -1425,7 +1426,7 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, if (*frameNum < 0 || *frameNum >= USBVIDEO_NUMFRAMES) return -EINVAL; - + if (uvd->debug >= 1) info("VIDIOCSYNC: syncing to frame %d.", *frameNum); if (uvd->flags & FLAGS_NO_DECODING) @@ -1454,8 +1455,8 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, struct video_buffer *vb = arg; memset(vb, 0, sizeof(*vb)); - return 0; - } + return 0; + } case VIDIOCKEY: return 0; @@ -1511,7 +1512,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, if (uvd->debug >= 1) info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock); - mutex_lock(&uvd->lock); + down(&uvd->lock); /* See if a frame is completed, then use it. */ for(i = 0; i < USBVIDEO_NUMFRAMES; i++) { @@ -1643,7 +1644,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, } } read_done: - mutex_unlock(&uvd->lock); + up(&uvd->lock); return count; } @@ -1704,7 +1705,7 @@ static void usbvideo_IsocIrq(struct urb *urb, struct pt_regs *regs) info("Not streaming, but interrupt!"); return; } - + uvd->stats.urb_count++; if (urb->actual_length <= 0) goto urb_done_with; @@ -1763,7 +1764,7 @@ static int usbvideo_StartDataPump(struct uvd *uvd) } if (VALID_CALLBACK(uvd, videoStart)) GET_CALLBACK(uvd, videoStart)(uvd); - else + else err("%s: videoStart not set", __FUNCTION__); /* We double buffer the Iso lists */ @@ -1830,7 +1831,7 @@ static void usbvideo_StopDataPump(struct uvd *uvd) /* Invoke minidriver's magic to stop the camera */ if (VALID_CALLBACK(uvd, videoStop)) GET_CALLBACK(uvd, videoStop)(uvd); - else + else err("%s: videoStop not set", __FUNCTION__); /* Set packet size to 0 */ @@ -1963,14 +1964,14 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) info("%s($%p,%d.)", __FUNCTION__, uvd, frameNum); switch (frame->frameState) { - case FrameState_Unused: + case FrameState_Unused: if (uvd->debug >= 2) info("%s: FrameState_Unused", __FUNCTION__); return -EINVAL; - case FrameState_Ready: - case FrameState_Grabbing: - case FrameState_Error: - { + case FrameState_Ready: + case FrameState_Grabbing: + case FrameState_Error: + { int ntries, signalPending; redo: if (!CAMERA_IS_OPERATIONAL(uvd)) { @@ -1978,7 +1979,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) info("%s: Camera is not operational (1)", __FUNCTION__); return -EIO; } - ntries = 0; + ntries = 0; do { RingQueue_InterruptibleSleepOn(&uvd->dp); signalPending = signal_pending(current); @@ -2010,7 +2011,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) usbvideo_CollectRawData(uvd, frame); else if (VALID_CALLBACK(uvd, processData)) GET_CALLBACK(uvd, processData)(uvd, frame); - else + else err("%s: processData not set", __FUNCTION__); } } while (frame->frameState == FrameState_Grabbing); @@ -2027,8 +2028,8 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) goto redo; } /* Note that we fall through to meet our destiny below */ - } - case FrameState_Done: + } + case FrameState_Done: /* * Do all necessary postprocessing of data prepared in * "interrupt" code and the collecting code above. The @@ -2157,7 +2158,7 @@ EXPORT_SYMBOL(usbvideo_DeinterlaceFrame); * History: * 09-Feb-2001 Created. */ -static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd, +static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd, struct usbvideo_frame *frame) { int i, j, v4l_linesize; diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/usb/media/usbvideo.h similarity index 96% rename from drivers/media/video/usbvideo/usbvideo.h rename to drivers/usb/media/usbvideo.h index 3cbf4fc49..6c390a1f9 100644 --- a/drivers/media/video/usbvideo/usbvideo.h +++ b/drivers/usb/media/usbvideo.h @@ -19,7 +19,6 @@ #include #include #include -#include /* Most helpful debugging aid */ #define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__)))) @@ -189,11 +188,11 @@ struct usbvideo_frame { /* Statistics that can be overlaid on screen */ struct usbvideo_statistics { - unsigned long frame_num; /* Sequential number of the frame */ - unsigned long urb_count; /* How many URBs we received so far */ - unsigned long urb_length; /* Length of last URB */ - unsigned long data_count; /* How many bytes we received */ - unsigned long header_count; /* How many frame headers we found */ + unsigned long frame_num; /* Sequential number of the frame */ + unsigned long urb_count; /* How many URBs we received so far */ + unsigned long urb_length; /* Length of last URB */ + unsigned long data_count; /* How many bytes we received */ + unsigned long header_count; /* How many frame headers we found */ unsigned long iso_skip_count; /* How many empty ISO packets received */ unsigned long iso_err_count; /* How many bad ISO packets received */ }; @@ -214,7 +213,7 @@ struct uvd { unsigned long flags; /* FLAGS_USBVIDEO_xxx */ unsigned long paletteBits; /* Which palettes we accept? */ unsigned short defaultPalette; /* What palette to use for read() */ - struct mutex lock; + struct semaphore lock; int user; /* user count for exclusive use */ videosize_t videosize; /* Current setting */ @@ -273,7 +272,7 @@ struct usbvideo { int num_cameras; /* As allocated */ struct usb_driver usbdrv; /* Interface to the USB stack */ char drvName[80]; /* Driver name */ - struct mutex lock; /* Mutex protecting camera structures */ + struct semaphore lock; /* Mutex protecting camera structures */ struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */ struct video_device vdt; /* Video device template */ struct uvd *cam; /* Array of camera structures */ diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/usb/media/vicam.c similarity index 98% rename from drivers/media/video/usbvideo/vicam.c rename to drivers/usb/media/vicam.c index 90d48e851..5df144073 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/usb/media/vicam.c @@ -42,7 +42,6 @@ #include #include #include -#include #include "usbvideo.h" // #define VICAM_DEBUG @@ -69,10 +68,10 @@ #define VICAM_HEADER_SIZE 64 #define clamp( x, l, h ) max_t( __typeof__( x ), \ - ( l ), \ - min_t( __typeof__( x ), \ - ( h ), \ - ( x ) ) ) + ( l ), \ + min_t( __typeof__( x ), \ + ( h ), \ + ( x ) ) ) /* Not sure what all the bytes in these char * arrays do, but they're necessary to make @@ -357,7 +356,7 @@ static unsigned char setup5[] = { * Not sure why these are not yet non-statics which I can reference through * usbvideo.h the same as it is in 2.4.20. I bet this will get fixed sometime * in the future. - * + * */ static void *rvmalloc(unsigned long size) { @@ -408,7 +407,7 @@ struct vicam_camera { struct usb_device *udev; // usb device /* guard against simultaneous accesses to the camera */ - struct mutex cam_lock; + struct semaphore cam_lock; int is_initialized; u8 open_count; @@ -462,12 +461,12 @@ static int send_control_msg(struct vicam_camera *cam, u16 size) { int status = -ENODEV; - mutex_lock(&cam->cam_lock); + down(&cam->cam_lock); if (cam->udev) { status = __send_control_msg(cam, request, value, index, cp, size); } - mutex_unlock(&cam->cam_lock); + up(&cam->cam_lock); return status; } static int @@ -603,12 +602,12 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign case VIDIOCSPICT: { struct video_picture vp; - + if (copy_from_user(&vp, user_arg, sizeof(vp))) { retval = -EFAULT; break; } - + DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth, vp.palette); @@ -655,7 +654,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign } DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height); - + if ( vw.width != 320 || vw.height != 240 ) retval = -EFAULT; @@ -764,7 +763,6 @@ vicam_open(struct inode *inode, struct file *file) if (!cam) { printk(KERN_ERR "vicam video_device improperly initialized"); - return -EINVAL; } /* the videodev_lock held above us protects us from @@ -809,12 +807,12 @@ vicam_open(struct inode *inode, struct file *file) cam->needsDummyRead = 1; cam->open_count++; - file->private_data = cam; - + file->private_data = cam; + return 0; } -static int +static int vicam_close(struct inode *inode, struct file *file) { struct vicam_camera *cam = file->private_data; @@ -833,13 +831,13 @@ vicam_close(struct inode *inode, struct file *file) rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); kfree(cam->cntrlbuf); - mutex_lock(&cam->cam_lock); + down(&cam->cam_lock); cam->open_count--; open_count = cam->open_count; udev = cam->udev; - mutex_unlock(&cam->cam_lock); + up(&cam->cam_lock); if (!open_count && !udev) { kfree(cam); @@ -962,7 +960,7 @@ read_frame(struct vicam_camera *cam, int framenum) request[8] = 0; // bytes 9-15 do not seem to affect exposure or image quality - mutex_lock(&cam->cam_lock); + down(&cam->cam_lock); if (!cam->udev) { goto done; @@ -987,7 +985,7 @@ read_frame(struct vicam_camera *cam, int framenum) } done: - mutex_unlock(&cam->cam_lock); + up(&cam->cam_lock); } static ssize_t @@ -1187,7 +1185,7 @@ vicam_create_proc_entry(struct vicam_camera *cam) if ( !cam->proc_dir ) return; // FIXME: We should probably return an error here - + ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR, cam->proc_dir); if (ent) { @@ -1282,7 +1280,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) const struct usb_host_interface *interface; const struct usb_endpoint_descriptor *endpoint; struct vicam_camera *cam; - + printk(KERN_INFO "ViCam based webcam connected\n"); interface = intf->cur_altsetting; @@ -1311,7 +1309,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) cam->shutter_speed = 15; - mutex_init(&cam->cam_lock); + init_MUTEX(&cam->cam_lock); memcpy(&cam->vdev, &vicam_template, sizeof (vicam_template)); @@ -1331,7 +1329,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor); usb_set_intfdata (intf, cam); - + return 0; } @@ -1353,7 +1351,7 @@ vicam_disconnect(struct usb_interface *intf) /* stop the camera from being used */ - mutex_lock(&cam->cam_lock); + down(&cam->cam_lock); /* mark the camera as gone */ @@ -1370,7 +1368,7 @@ vicam_disconnect(struct usb_interface *intf) open_count = cam->open_count; - mutex_unlock(&cam->cam_lock); + up(&cam->cam_lock); if (!open_count) { kfree(cam); diff --git a/drivers/media/video/w9968cf.c b/drivers/usb/media/w9968cf.c similarity index 79% rename from drivers/media/video/w9968cf.c rename to drivers/usb/media/w9968cf.c index 20f211b55..9937fc64c 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/usb/media/w9968cf.c @@ -47,13 +47,6 @@ #include "w9968cf.h" #include "w9968cf_decoder.h" -static struct w9968cf_vpp_t* w9968cf_vpp; -static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait); - -static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */ -static DEFINE_MUTEX(w9968cf_devlist_mutex); /* semaphore for list traversal */ - -static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */ /**************************************************************************** @@ -71,39 +64,39 @@ MODULE_SUPPORTED_DEVICE("Video"); static int ovmod_load = W9968CF_OVMOD_LOAD; static unsigned short simcams = W9968CF_SIMCAMS; static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/ -static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_PACKET_SIZE}; -static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_BUFFERS}; -static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_DOUBLE_BUFFER}; +static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_PACKET_SIZE}; +static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_BUFFERS}; +static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_DOUBLE_BUFFER}; static int clamping[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLAMPING}; -static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_FILTER_TYPE}; +static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_FILTER_TYPE}; static int largeview[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LARGEVIEW}; -static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_DECOMPRESSION}; +static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_DECOMPRESSION}; static int upscaling[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_UPSCALING}; static unsigned short force_palette[] = {[0 ... W9968CF_MAX_DEVICES-1] = 0}; static int force_rgb[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_FORCE_RGB}; static int autobright[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOBRIGHT}; static int autoexp[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOEXP}; -static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_LIGHTFREQ}; +static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_LIGHTFREQ}; static int bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]= - W9968CF_BANDINGFILTER}; + W9968CF_BANDINGFILTER}; static short clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV}; static int backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT}; static int mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR}; static int monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME}; -static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_BRIGHTNESS}; +static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_BRIGHTNESS}; static unsigned int hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE}; static unsigned int colour[]={[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR}; -static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_CONTRAST}; -static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] = - W9968CF_WHITENESS}; +static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_CONTRAST}; +static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] = + W9968CF_WHITENESS}; #ifdef W9968CF_DEBUG static unsigned short debug = W9968CF_DEBUG_LEVEL; static int specific_debug = W9968CF_SPECIFIC_DEBUG; @@ -145,251 +138,251 @@ module_param(specific_debug, bool, 0644); #endif #ifdef CONFIG_KMOD -MODULE_PARM_DESC(ovmod_load, - "\n<0|1> Automatic 'ovcamchip' module loading." - "\n0 disabled, 1 enabled." - "\nIf enabled,'insmod' searches for the required 'ovcamchip'" - "\nmodule in the system, according to its configuration, and" - "\nattempts to load that module automatically. This action is" - "\nperformed once as soon as the 'w9968cf' module is loaded" - "\ninto memory." - "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"." - "\n"); +MODULE_PARM_DESC(ovmod_load, + "\n<0|1> Automatic 'ovcamchip' module loading." + "\n0 disabled, 1 enabled." + "\nIf enabled,'insmod' searches for the required 'ovcamchip'" + "\nmodule in the system, according to its configuration, and" + "\nattempts to load that module automatically. This action is" + "\nperformed once as soon as the 'w9968cf' module is loaded" + "\ninto memory." + "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"." + "\n"); #endif -MODULE_PARM_DESC(simcams, - "\n Number of cameras allowed to stream simultaneously." - "\nn may vary from 0 to " - __MODULE_STRING(W9968CF_MAX_DEVICES)"." - "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"." - "\n"); +MODULE_PARM_DESC(simcams, + "\n Number of cameras allowed to stream simultaneously." + "\nn may vary from 0 to " + __MODULE_STRING(W9968CF_MAX_DEVICES)"." + "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"." + "\n"); MODULE_PARM_DESC(video_nr, - "\n<-1|n[,...]> Specify V4L minor mode number." - "\n -1 = use next available (default)" - "\n n = use minor number n (integer >= 0)" - "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES) - " cameras this way." - "\nFor example:" - "\nvideo_nr=-1,2,-1 would assign minor number 2 to" - "\nthe second camera and use auto for the first" - "\none and for every other camera." - "\n"); + "\n<-1|n[,...]> Specify V4L minor mode number." + "\n -1 = use next available (default)" + "\n n = use minor number n (integer >= 0)" + "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES) + " cameras this way." + "\nFor example:" + "\nvideo_nr=-1,2,-1 would assign minor number 2 to" + "\nthe second camera and use auto for the first" + "\none and for every other camera." + "\n"); MODULE_PARM_DESC(packet_size, - "\n Specify the maximum data payload" - "\nsize in bytes for alternate settings, for each device." - "\nn is scaled between 63 and 1023 " - "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")." - "\n"); + "\n Specify the maximum data payload" + "\nsize in bytes for alternate settings, for each device." + "\nn is scaled between 63 and 1023 " + "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")." + "\n"); MODULE_PARM_DESC(max_buffers, - "\n For advanced users." - "\nSpecify the maximum number of video frame buffers" - "\nto allocate for each device, from 2 to " - __MODULE_STRING(W9968CF_MAX_BUFFERS) - ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")." - "\n"); -MODULE_PARM_DESC(double_buffer, - "\n<0|1[,...]> " - "Hardware double buffering: 0 disabled, 1 enabled." - "\nIt should be enabled if you want smooth video output: if" - "\nyou obtain out of sync. video, disable it, or try to" - "\ndecrease the 'clockdiv' module parameter value." - "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER) - " for every device." - "\n"); -MODULE_PARM_DESC(clamping, - "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled." - "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING) - " for every device." - "\n"); -MODULE_PARM_DESC(filter_type, - "\n<0|1|2[,...]> Video filter type." - "\n0 none, 1 (1-2-1) 3-tap filter, " - "2 (2-3-6-3-2) 5-tap filter." - "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE) - " for every device." - "\nThe filter is used to reduce noise and aliasing artifacts" - "\nproduced by the CCD or CMOS image sensor, and the scaling" - " process." - "\n"); -MODULE_PARM_DESC(largeview, - "\n<0|1[,...]> Large view: 0 disabled, 1 enabled." - "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW) - " for every device." - "\n"); -MODULE_PARM_DESC(upscaling, - "\n<0|1[,...]> Software scaling (for non-compressed video):" - "\n0 disabled, 1 enabled." - "\nDisable it if you have a slow CPU or you don't have" - " enough memory." - "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING) - " for every device." - "\nIf 'w9968cf-vpp' is not present, this parameter is" - " set to 0." - "\n"); + "\n For advanced users." + "\nSpecify the maximum number of video frame buffers" + "\nto allocate for each device, from 2 to " + __MODULE_STRING(W9968CF_MAX_BUFFERS) + ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")." + "\n"); +MODULE_PARM_DESC(double_buffer, + "\n<0|1[,...]> " + "Hardware double buffering: 0 disabled, 1 enabled." + "\nIt should be enabled if you want smooth video output: if" + "\nyou obtain out of sync. video, disable it, or try to" + "\ndecrease the 'clockdiv' module parameter value." + "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER) + " for every device." + "\n"); +MODULE_PARM_DESC(clamping, + "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled." + "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING) + " for every device." + "\n"); +MODULE_PARM_DESC(filter_type, + "\n<0|1|2[,...]> Video filter type." + "\n0 none, 1 (1-2-1) 3-tap filter, " + "2 (2-3-6-3-2) 5-tap filter." + "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE) + " for every device." + "\nThe filter is used to reduce noise and aliasing artifacts" + "\nproduced by the CCD or CMOS image sensor, and the scaling" + " process." + "\n"); +MODULE_PARM_DESC(largeview, + "\n<0|1[,...]> Large view: 0 disabled, 1 enabled." + "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW) + " for every device." + "\n"); +MODULE_PARM_DESC(upscaling, + "\n<0|1[,...]> Software scaling (for non-compressed video):" + "\n0 disabled, 1 enabled." + "\nDisable it if you have a slow CPU or you don't have" + " enough memory." + "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING) + " for every device." + "\nIf 'w9968cf-vpp' is not present, this parameter is" + " set to 0." + "\n"); MODULE_PARM_DESC(decompression, - "\n<0|1|2[,...]> Software video decompression:" - "\n- 0 disables decompression (doesn't allow formats needing" - " decompression)" - "\n- 1 forces decompression (allows formats needing" - " decompression only);" - "\n- 2 allows any permitted formats." - "\nFormats supporting compressed video are YUV422P and" - " YUV420P/YUV420 " - "\nin any resolutions where both width and height are " - "a multiple of 16." - "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION) - " for every device." - "\nIf 'w9968cf-vpp' is not present, forcing decompression is " - "\nnot allowed; in this case this parameter is set to 2." - "\n"); + "\n<0|1|2[,...]> Software video decompression:" + "\n- 0 disables decompression (doesn't allow formats needing" + " decompression)" + "\n- 1 forces decompression (allows formats needing" + " decompression only);" + "\n- 2 allows any permitted formats." + "\nFormats supporting compressed video are YUV422P and" + " YUV420P/YUV420 " + "\nin any resolutions where both width and height are " + "a multiple of 16." + "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION) + " for every device." + "\nIf 'w9968cf-vpp' is not present, forcing decompression is " + "\nnot allowed; in this case this parameter is set to 2." + "\n"); MODULE_PARM_DESC(force_palette, - "\n<0" - "|" __MODULE_STRING(VIDEO_PALETTE_UYVY) - "|" __MODULE_STRING(VIDEO_PALETTE_YUV420) - "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P) - "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P) - "|" __MODULE_STRING(VIDEO_PALETTE_YUYV) - "|" __MODULE_STRING(VIDEO_PALETTE_YUV422) - "|" __MODULE_STRING(VIDEO_PALETTE_GREY) - "|" __MODULE_STRING(VIDEO_PALETTE_RGB555) - "|" __MODULE_STRING(VIDEO_PALETTE_RGB565) - "|" __MODULE_STRING(VIDEO_PALETTE_RGB24) - "|" __MODULE_STRING(VIDEO_PALETTE_RGB32) - "[,...]>" - " Force picture palette." - "\nIn order:" - "\n- 0 allows any of the following formats:" - "\n- UYVY 16 bpp - Original video, compression disabled" - "\n- YUV420 12 bpp - Original video, compression enabled" - "\n- YUV422P 16 bpp - Original video, compression enabled" - "\n- YUV420P 12 bpp - Original video, compression enabled" - "\n- YUVY 16 bpp - Software conversion from UYVY" - "\n- YUV422 16 bpp - Software conversion from UYVY" - "\n- GREY 8 bpp - Software conversion from UYVY" - "\n- RGB555 16 bpp - Software conversion from UYVY" - "\n- RGB565 16 bpp - Software conversion from UYVY" - "\n- RGB24 24 bpp - Software conversion from UYVY" - "\n- RGB32 32 bpp - Software conversion from UYVY" - "\nWhen not 0, this parameter will override 'decompression'." - "\nDefault value is 0 for every device." - "\nInitial palette is " - __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"." - "\nIf 'w9968cf-vpp' is not present, this parameter is" - " set to 9 (UYVY)." - "\n"); -MODULE_PARM_DESC(force_rgb, - "\n<0|1[,...]> Read RGB video data instead of BGR:" - "\n 1 = use RGB component ordering." - "\n 0 = use BGR component ordering." - "\nThis parameter has effect when using RGBX palettes only." - "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB) - " for every device." - "\n"); + "\n<0" + "|" __MODULE_STRING(VIDEO_PALETTE_UYVY) + "|" __MODULE_STRING(VIDEO_PALETTE_YUV420) + "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P) + "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P) + "|" __MODULE_STRING(VIDEO_PALETTE_YUYV) + "|" __MODULE_STRING(VIDEO_PALETTE_YUV422) + "|" __MODULE_STRING(VIDEO_PALETTE_GREY) + "|" __MODULE_STRING(VIDEO_PALETTE_RGB555) + "|" __MODULE_STRING(VIDEO_PALETTE_RGB565) + "|" __MODULE_STRING(VIDEO_PALETTE_RGB24) + "|" __MODULE_STRING(VIDEO_PALETTE_RGB32) + "[,...]>" + " Force picture palette." + "\nIn order:" + "\n- 0 allows any of the following formats:" + "\n- UYVY 16 bpp - Original video, compression disabled" + "\n- YUV420 12 bpp - Original video, compression enabled" + "\n- YUV422P 16 bpp - Original video, compression enabled" + "\n- YUV420P 12 bpp - Original video, compression enabled" + "\n- YUVY 16 bpp - Software conversion from UYVY" + "\n- YUV422 16 bpp - Software conversion from UYVY" + "\n- GREY 8 bpp - Software conversion from UYVY" + "\n- RGB555 16 bpp - Software conversion from UYVY" + "\n- RGB565 16 bpp - Software conversion from UYVY" + "\n- RGB24 24 bpp - Software conversion from UYVY" + "\n- RGB32 32 bpp - Software conversion from UYVY" + "\nWhen not 0, this parameter will override 'decompression'." + "\nDefault value is 0 for every device." + "\nInitial palette is " + __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"." + "\nIf 'w9968cf-vpp' is not present, this parameter is" + " set to 9 (UYVY)." + "\n"); +MODULE_PARM_DESC(force_rgb, + "\n<0|1[,...]> Read RGB video data instead of BGR:" + "\n 1 = use RGB component ordering." + "\n 0 = use BGR component ordering." + "\nThis parameter has effect when using RGBX palettes only." + "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB) + " for every device." + "\n"); MODULE_PARM_DESC(autobright, - "\n<0|1[,...]> Image sensor automatically changes brightness:" - "\n 0 = no, 1 = yes" - "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT) - " for every device." - "\n"); + "\n<0|1[,...]> Image sensor automatically changes brightness:" + "\n 0 = no, 1 = yes" + "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT) + " for every device." + "\n"); MODULE_PARM_DESC(autoexp, - "\n<0|1[,...]> Image sensor automatically changes exposure:" - "\n 0 = no, 1 = yes" - "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP) - " for every device." - "\n"); + "\n<0|1[,...]> Image sensor automatically changes exposure:" + "\n 0 = no, 1 = yes" + "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP) + " for every device." + "\n"); MODULE_PARM_DESC(lightfreq, - "\n<50|60[,...]> Light frequency in Hz:" - "\n 50 for European and Asian lighting," - " 60 for American lighting." - "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ) - " for every device." - "\n"); + "\n<50|60[,...]> Light frequency in Hz:" + "\n 50 for European and Asian lighting," + " 60 for American lighting." + "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ) + " for every device." + "\n"); MODULE_PARM_DESC(bandingfilter, - "\n<0|1[,...]> Banding filter to reduce effects of" - " fluorescent lighting:" - "\n 0 disabled, 1 enabled." - "\nThis filter tries to reduce the pattern of horizontal" - "\nlight/dark bands caused by some (usually fluorescent)" - " lighting." - "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER) - " for every device." - "\n"); + "\n<0|1[,...]> Banding filter to reduce effects of" + " fluorescent lighting:" + "\n 0 disabled, 1 enabled." + "\nThis filter tries to reduce the pattern of horizontal" + "\nlight/dark bands caused by some (usually fluorescent)" + " lighting." + "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER) + " for every device." + "\n"); MODULE_PARM_DESC(clockdiv, - "\n<-1|n[,...]> " - "Force pixel clock divisor to a specific value (for experts):" - "\n n may vary from 0 to 127." - "\n -1 for automatic value." - "\nSee also the 'double_buffer' module parameter." - "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV) - " for every device." - "\n"); + "\n<-1|n[,...]> " + "Force pixel clock divisor to a specific value (for experts):" + "\n n may vary from 0 to 127." + "\n -1 for automatic value." + "\nSee also the 'double_buffer' module parameter." + "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV) + " for every device." + "\n"); MODULE_PARM_DESC(backlight, - "\n<0|1[,...]> Objects are lit from behind:" - "\n 0 = no, 1 = yes" - "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT) - " for every device." - "\n"); + "\n<0|1[,...]> Objects are lit from behind:" + "\n 0 = no, 1 = yes" + "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT) + " for every device." + "\n"); MODULE_PARM_DESC(mirror, - "\n<0|1[,...]> Reverse image horizontally:" - "\n 0 = no, 1 = yes" - "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR) - " for every device." - "\n"); + "\n<0|1[,...]> Reverse image horizontally:" + "\n 0 = no, 1 = yes" + "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR) + " for every device." + "\n"); MODULE_PARM_DESC(monochrome, - "\n<0|1[,...]> Use image sensor as monochrome sensor:" - "\n 0 = no, 1 = yes" - "\nNot all the sensors support monochrome color." - "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME) - " for every device." - "\n"); -MODULE_PARM_DESC(brightness, - "\n Set picture brightness (0-65535)." - "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS) - " for every device." - "\nThis parameter has no effect if 'autobright' is enabled." - "\n"); -MODULE_PARM_DESC(hue, - "\n Set picture hue (0-65535)." - "\nDefault value is "__MODULE_STRING(W9968CF_HUE) - " for every device." - "\n"); -MODULE_PARM_DESC(colour, - "\n Set picture saturation (0-65535)." - "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR) - " for every device." - "\n"); -MODULE_PARM_DESC(contrast, - "\n Set picture contrast (0-65535)." - "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST) - " for every device." - "\n"); -MODULE_PARM_DESC(whiteness, - "\n Set picture whiteness (0-65535)." - "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS) - " for every device." - "\n"); + "\n<0|1[,...]> Use image sensor as monochrome sensor:" + "\n 0 = no, 1 = yes" + "\nNot all the sensors support monochrome color." + "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME) + " for every device." + "\n"); +MODULE_PARM_DESC(brightness, + "\n Set picture brightness (0-65535)." + "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS) + " for every device." + "\nThis parameter has no effect if 'autobright' is enabled." + "\n"); +MODULE_PARM_DESC(hue, + "\n Set picture hue (0-65535)." + "\nDefault value is "__MODULE_STRING(W9968CF_HUE) + " for every device." + "\n"); +MODULE_PARM_DESC(colour, + "\n Set picture saturation (0-65535)." + "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR) + " for every device." + "\n"); +MODULE_PARM_DESC(contrast, + "\n Set picture contrast (0-65535)." + "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST) + " for every device." + "\n"); +MODULE_PARM_DESC(whiteness, + "\n Set picture whiteness (0-65535)." + "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS) + " for every device." + "\n"); #ifdef W9968CF_DEBUG MODULE_PARM_DESC(debug, - "\n Debugging information level, from 0 to 6:" - "\n0 = none (use carefully)" - "\n1 = critical errors" - "\n2 = significant informations" - "\n3 = configuration or general messages" - "\n4 = warnings" - "\n5 = called functions" - "\n6 = function internals" - "\nLevel 5 and 6 are useful for testing only, when only " - "one device is used." - "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"." - "\n"); + "\n Debugging information level, from 0 to 6:" + "\n0 = none (use carefully)" + "\n1 = critical errors" + "\n2 = significant informations" + "\n3 = configuration or general messages" + "\n4 = warnings" + "\n5 = called functions" + "\n6 = function internals" + "\nLevel 5 and 6 are useful for testing only, when only " + "one device is used." + "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"." + "\n"); MODULE_PARM_DESC(specific_debug, - "\n<0|1> Enable or disable specific debugging messages:" - "\n0 = print messages concerning every level" - " <= 'debug' level." - "\n1 = print messages concerning the level" - " indicated by 'debug'." - "\nDefault value is " - __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"." - "\n"); + "\n<0|1> Enable or disable specific debugging messages:" + "\n0 = print messages concerning every level" + " <= 'debug' level." + "\n1 = print messages concerning the level" + " indicated by 'debug'." + "\nDefault value is " + __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"." + "\n"); #endif /* W9968CF_DEBUG */ @@ -406,7 +399,7 @@ static int w9968cf_mmap(struct file*, struct vm_area_struct*); static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long); static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*); static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, - void __user *); + void __user *); /* USB-specific */ static int w9968cf_start_transfer(struct w9968cf_device*); @@ -428,25 +421,25 @@ static int w9968cf_smbus_write_ack(struct w9968cf_device*); static int w9968cf_smbus_read_ack(struct w9968cf_device*); static int w9968cf_smbus_refresh_bus(struct w9968cf_device*); static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam, - u16 address, u8* value); -static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address, - u8 subaddress, u8* value); + u16 address, u8* value); +static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address, + u8 subaddress, u8* value); static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*, - u16 address, u8 subaddress); + u16 address, u8 subaddress); static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*, - u16 address, u8 subaddress, - u8 value); + u16 address, u8 subaddress, + u8 value); /* I2C interface to kernel */ static int w9968cf_i2c_init(struct w9968cf_device*); -static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr, - unsigned short flags, char read_write, - u8 command, int size, union i2c_smbus_data*); +static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data*); static u32 w9968cf_i2c_func(struct i2c_adapter*); static int w9968cf_i2c_attach_inform(struct i2c_client*); static int w9968cf_i2c_detach_inform(struct i2c_client*); static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd, - unsigned long arg); + unsigned long arg); /* Memory management */ static void* rvmalloc(unsigned long size); @@ -458,17 +451,17 @@ static int w9968cf_allocate_memory(struct w9968cf_device*); static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val); static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val); static int w9968cf_sensor_cmd(struct w9968cf_device*, - unsigned int cmd, void *arg); + unsigned int cmd, void *arg); static int w9968cf_sensor_init(struct w9968cf_device*); static int w9968cf_sensor_update_settings(struct w9968cf_device*); static int w9968cf_sensor_get_picture(struct w9968cf_device*); -static int w9968cf_sensor_update_picture(struct w9968cf_device*, - struct video_picture pict); +static int w9968cf_sensor_update_picture(struct w9968cf_device*, + struct video_picture pict); /* Other helper functions */ static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*, - enum w9968cf_model_id, - const unsigned short dev_nr); + enum w9968cf_model_id, + const unsigned short dev_nr); static void w9968cf_adjust_configuration(struct w9968cf_device*); static int w9968cf_turn_on_led(struct w9968cf_device*); static int w9968cf_init_chip(struct w9968cf_device*); @@ -477,8 +470,8 @@ static inline u16 w9968cf_valid_depth(u16 palette); static inline u8 w9968cf_need_decompression(u16 palette); static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture); static int w9968cf_set_window(struct w9968cf_device*, struct video_window); -static int w9968cf_postprocess_frame(struct w9968cf_device*, - struct w9968cf_frame_t*); +static int w9968cf_postprocess_frame(struct w9968cf_device*, + struct w9968cf_frame_t*); static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h); static void w9968cf_init_framelist(struct w9968cf_device*); static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num); @@ -497,11 +490,11 @@ struct w9968cf_symbolic_list { const char *name; }; -/*-------------------------------------------------------------------------- +/*-------------------------------------------------------------------------- Returns the name of the matching element in the symbolic_list array. The end of the list must be marked with an element that has a NULL name. --------------------------------------------------------------------------*/ -static inline const char * +static inline const char * symbolic(struct w9968cf_symbolic_list list[], const int num) { int i; @@ -568,7 +561,7 @@ static struct w9968cf_symbolic_list v4l1_plist[] = { static struct w9968cf_symbolic_list decoder_errlist[] = { { W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" }, { W9968CF_DEC_ERR_BUF_OVERFLOW, "Buffer overflow" }, - { W9968CF_DEC_ERR_NO_SOI, "SOI marker not found" }, + { W9968CF_DEC_ERR_NO_SOI, "SOI marker not found" }, { W9968CF_DEC_ERR_NO_SOF0, "SOF0 marker not found" }, { W9968CF_DEC_ERR_NO_SOS, "SOS marker not found" }, { W9968CF_DEC_ERR_NO_EOI, "EOI marker not found" }, @@ -695,19 +688,20 @@ static int w9968cf_allocate_memory(struct w9968cf_device* cam) bpp = (w9968cf_vpp) ? 4 : 2; if (cam->upscaling) vpp_bufsize = max(W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp, - cam->maxwidth*cam->maxheight*bpp); + cam->maxwidth*cam->maxheight*bpp); else vpp_bufsize = cam->maxwidth*cam->maxheight*bpp; /* Allocate memory for the isochronous transfer buffers */ for (i = 0; i < W9968CF_URBS; i++) { if (!(cam->transfer_buffer[i] = - kzalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) { + kmalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) { DBG(1, "Couldn't allocate memory for the isochronous " - "transfer buffers (%u bytes)", + "transfer buffers (%u bytes)", p_size * W9968CF_ISO_PACKETS) return -ENOMEM; } + memset(cam->transfer_buffer[i], 0, W9968CF_ISO_PACKETS*p_size); } /* Allocate memory for the temporary frame buffer */ @@ -780,7 +774,7 @@ static int w9968cf_allocate_memory(struct w9968cf_device* cam) of the next video frame; if an error is encountered in a packet, the entire video frame is discarded and grabbed again. If there are no requested frames in the FIFO list, packets are collected into - a temporary buffer. + a temporary buffer. --------------------------------------------------------------------------*/ static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs) { @@ -799,7 +793,7 @@ static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs) /* "(*f)" will be used instead of "cam->frame_current" */ f = &cam->frame_current; - /* If a frame has been requested and we are grabbing into + /* If a frame has been requested and we are grabbing into the temporary frame, we'll switch to that requested frame */ if ((*f) == &cam->frame_tmp && *cam->requested_frame) { if (cam->frame_tmp.status == F_GRABBING) { @@ -808,7 +802,7 @@ static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs) (*f)->length = cam->frame_tmp.length; memcpy((*f)->buffer, cam->frame_tmp.buffer, (*f)->length); - DBG(6, "Switched from temp. frame to frame #%d", + DBG(6, "Switched from temp. frame to frame #%d", (*f)->number) } } @@ -850,7 +844,7 @@ static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs) if (cam->vpp_flag & VPP_DECOMPRESSION) { err = w9968cf_vpp->check_headers((*f)->buffer, - (*f)->length); + (*f)->length); if (err) { DBG(4, "Skip corrupted frame: %s", symbolic(decoder_errlist, err)) @@ -975,7 +969,7 @@ static int w9968cf_start_transfer(struct w9968cf_device* cam) cam->frame_current = &cam->frame_tmp; if (!(cam->vpp_flag & VPP_DECOMPRESSION)) - DBG(5, "Isochronous transfer size: %lu bytes/frame", + DBG(5, "Isochronous transfer size: %lu bytes/frame", (unsigned long)t_size*2) DBG(5, "Starting the isochronous transfer...") @@ -992,7 +986,7 @@ static int w9968cf_start_transfer(struct w9968cf_device* cam) usb_free_urb(cam->urb[j]); } DBG(1, "Couldn't send a transfer request to the " - "USB core (error #%d, %s)", err, + "USB core (error #%d, %s)", err, symbolic(urb_errlist, err)) return err; } @@ -1016,7 +1010,7 @@ static int w9968cf_stop_transfer(struct w9968cf_device* cam) if (!cam->streaming) return 0; - /* This avoids race conditions with usb_submit_urb() + /* This avoids race conditions with usb_submit_urb() in the URB completition handler */ spin_lock_irqsave(&cam->urb_lock, lock_flags); cam->streaming = 0; @@ -1050,7 +1044,7 @@ exit: /*-------------------------------------------------------------------------- - Write a W9968CF register. + Write a W9968CF register. Return 0 on success, -1 otherwise. --------------------------------------------------------------------------*/ static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index) @@ -1059,8 +1053,8 @@ static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index) int res; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0, - USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT); + USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, + value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT); if (res < 0) DBG(4, "Failed to write a register " @@ -1072,7 +1066,7 @@ static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index) /*-------------------------------------------------------------------------- - Read a W9968CF register. + Read a W9968CF register. Return the register value on success, -1 otherwise. --------------------------------------------------------------------------*/ static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index) @@ -1082,8 +1076,8 @@ static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index) int res; res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT); + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT); if (res < 0) DBG(4, "Failed to read a register " @@ -1107,8 +1101,8 @@ static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data) value = *data++; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0, - USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT); + USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, + value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT); if (res < 0) DBG(4, "Failed to write the FSB registers " @@ -1287,9 +1281,9 @@ static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam) /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ -static int -w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam, - u16 address, u8 subaddress,u8 value) +static int +w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam, + u16 address, u8 subaddress,u8 value) { u16* data = cam->data_buffer; int err = 0; @@ -1348,7 +1342,7 @@ w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam, "value 0x%02X", address, subaddress, value) else DBG(5, "I2C write byte data failed, addr.0x%04X, " - "subaddr.0x%02X, value 0x%02X", + "subaddr.0x%02X, value 0x%02X", address, subaddress, value) return err; @@ -1356,10 +1350,10 @@ w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam, /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ -static int -w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam, - u16 address, u8 subaddress, - u8* value) +static int +w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam, + u16 address, u8 subaddress, + u8* value) { int err = 0; @@ -1384,7 +1378,7 @@ w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam, if (!err) DBG(5, "I2C read byte data done, addr.0x%04X, " - "subaddr.0x%02X, value 0x%02X", + "subaddr.0x%02X, value 0x%02X", address, subaddress, *value) else DBG(5, "I2C read byte data failed, addr.0x%04X, " @@ -1396,9 +1390,9 @@ w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam, /* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */ -static int +static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam, - u16 address, u8* value) + u16 address, u8* value) { int err = 0; @@ -1411,7 +1405,7 @@ w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam, err += w9968cf_smbus_read_byte(cam, value); err += w9968cf_smbus_write_ack(cam); err += w9968cf_smbus_stop(cam); - + /* Serial data disable */ err += w9968cf_write_sb(cam, 0x0000); @@ -1427,9 +1421,9 @@ w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam, /* SMBus protocol: S Addr Wr [A] Value [A] P */ -static int +static int w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam, - u16 address, u8 value) + u16 address, u8 value) { DBG(4, "i2c_write_byte() is an unsupported transfer mode") return -EINVAL; @@ -1442,13 +1436,13 @@ w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam, ****************************************************************************/ static int -w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char read_write, u8 command, - int size, union i2c_smbus_data *data) +w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data) { struct w9968cf_device* cam = i2c_get_adapdata(adapter); u8 i; - int err = 0; + int err = 0; switch (addr) { case OV6xx0_SID: @@ -1464,20 +1458,20 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, addr <<= 1; if (read_write == I2C_SMBUS_WRITE) - err = w9968cf_i2c_adap_write_byte(cam, addr, command); - else if (read_write == I2C_SMBUS_READ) + err = w9968cf_i2c_adap_write_byte(cam, addr, command); + else if (read_write == I2C_SMBUS_READ) err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte); } else if (size == I2C_SMBUS_BYTE_DATA) { addr <<= 1; if (read_write == I2C_SMBUS_WRITE) - err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr, - command, data->byte); + err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr, + command, data->byte); else if (read_write == I2C_SMBUS_READ) { for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) { err = w9968cf_i2c_adap_read_byte_data(cam,addr, - command, &data->byte); + command, &data->byte); if (err) { if (w9968cf_smbus_refresh_bus(cam)) { err = -EIO; @@ -1520,7 +1514,7 @@ static int w9968cf_i2c_attach_inform(struct i2c_client* client) return err; } } else { - DBG(4, "Rejected client [%s] with driver [%s]", + DBG(4, "Rejected client [%s] with driver [%s]", client->name, client->driver->driver.name) return -EINVAL; } @@ -1545,9 +1539,9 @@ static int w9968cf_i2c_detach_inform(struct i2c_client* client) } -static int +static int w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd, - unsigned long arg) + unsigned long arg) { return 0; } @@ -1625,12 +1619,12 @@ static int w9968cf_turn_on_led(struct w9968cf_device* cam) static int w9968cf_init_chip(struct w9968cf_device* cam) { unsigned long hw_bufsize = cam->maxwidth*cam->maxheight*2, - y0 = 0x0000, - u0 = y0 + hw_bufsize/2, - v0 = u0 + hw_bufsize/4, - y1 = v0 + hw_bufsize/4, - u1 = y1 + hw_bufsize/2, - v1 = u1 + hw_bufsize/4; + y0 = 0x0000, + u0 = y0 + hw_bufsize/2, + v0 = u0 + hw_bufsize/4, + y1 = v0 + hw_bufsize/4, + u1 = y1 + hw_bufsize/2, + v1 = u1 + hw_bufsize/4; int err = 0; err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */ @@ -1762,7 +1756,7 @@ w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict) cam->vpp_flag = VPP_SWAP_YUV_BYTES; hw_palette = VIDEO_PALETTE_UYVY; break; - /* Original video is used instead of RGBX palettes. + /* Original video is used instead of RGBX palettes. Software conversion later. */ case VIDEO_PALETTE_GREY: case VIDEO_PALETTE_RGB555: @@ -1777,7 +1771,7 @@ w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict) } /* NOTE: due to memory issues, it is better to disable the hardware - double buffering during compression */ + double buffering during compression */ if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION)) reg_v |= 0x0080; @@ -1832,8 +1826,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) #define __UNSC(x) ((x) >> 10) /* Make sure we are using a supported resolution */ - if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, - (u16*)&win.height))) + if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, + (u16*)&win.height))) goto error; /* Scaling factors */ @@ -1962,7 +1956,7 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) /* Settings changed, so we clear the frame buffers */ memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size); - DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)", + DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)", win.width, win.height, win.x, win.y) PDBGG("x=%u ,y=%u, w=%u, h=%u, ax=%u, ay=%u, s_win.x=%u, s_win.y=%u, " @@ -1978,11 +1972,11 @@ error: } -/*-------------------------------------------------------------------------- +/*-------------------------------------------------------------------------- Adjust the asked values for window width and height. Return 0 on success, -1 otherwise. --------------------------------------------------------------------------*/ -static int +static int w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height) { u16 maxw, maxh; @@ -1992,10 +1986,10 @@ w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height) maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) - : cam->maxwidth; + : cam->maxwidth; maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight) - : cam->maxheight; + : cam->maxheight; if (*width > maxw) *width = maxw; @@ -2054,7 +2048,7 @@ static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num) Read, store and remove the first pointer in the FIFO list of requested frames. This function is called in interrupt context. --------------------------------------------------------------------------*/ -static void +static void w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep) { u8 i; @@ -2078,9 +2072,9 @@ w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep) High-level video post-processing routine on grabbed frames. Return 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ -static int -w9968cf_postprocess_frame(struct w9968cf_device* cam, - struct w9968cf_frame_t* fr) +static int +w9968cf_postprocess_frame(struct w9968cf_device* cam, + struct w9968cf_frame_t* fr) { void *pIn = fr->buffer, *pOut = cam->frame_vpp.buffer, *tmp; u16 w = cam->window.width, @@ -2127,7 +2121,7 @@ w9968cf_postprocess_frame(struct w9968cf_device* cam, w9968cf_vpp->uyvy_to_rgbx(pIn, fr->length, pOut, fmt, rgb); fr->length = (w*h*d)/8; _PSWAP(pIn, pOut) - DBG(6, "UYVY-16bit to %s conversion done", + DBG(6, "UYVY-16bit to %s conversion done", symbolic(v4l1_plist, fmt)) } @@ -2143,7 +2137,7 @@ w9968cf_postprocess_frame(struct w9968cf_device* cam, * Image sensor control routines * ****************************************************************************/ -static int +static int w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val) { struct ovcamchip_control ctl; @@ -2158,7 +2152,7 @@ w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val) } -static int +static int w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val) { struct ovcamchip_control ctl; @@ -2198,38 +2192,38 @@ static int w9968cf_sensor_update_settings(struct w9968cf_device* cam) int err = 0; /* Auto brightness */ - err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT, - cam->auto_brt); + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT, + cam->auto_brt); if (err) return err; /* Auto exposure */ - err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP, - cam->auto_exp); + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP, + cam->auto_exp); if (err) return err; /* Banding filter */ - err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT, - cam->bandfilt); + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT, + cam->bandfilt); if (err) return err; /* Light frequency */ err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ, - cam->lightfreq); + cam->lightfreq); if (err) return err; /* Back light */ err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT, - cam->backlight); + cam->backlight); if (err) return err; /* Mirror */ err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR, - cam->mirror); + cam->mirror); if (err) return err; @@ -2281,15 +2275,15 @@ static int w9968cf_sensor_get_picture(struct w9968cf_device* cam) Returns: 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ static int -w9968cf_sensor_update_picture(struct w9968cf_device* cam, - struct video_picture pict) +w9968cf_sensor_update_picture(struct w9968cf_device* cam, + struct video_picture pict) { int err = 0; if ((!cam->sensor_initialized) || pict.contrast != cam->picture.contrast) { err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT, - pict.contrast); + pict.contrast); if (err) goto fail; DBG(4, "Contrast changed from %u to %u", @@ -2297,10 +2291,10 @@ w9968cf_sensor_update_picture(struct w9968cf_device* cam, cam->picture.contrast = pict.contrast; } - if (((!cam->sensor_initialized) || + if (((!cam->sensor_initialized) || pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) { - err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT, - pict.brightness); + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT, + pict.brightness); if (err) goto fail; DBG(4, "Brightness changed from %u to %u", @@ -2309,8 +2303,8 @@ w9968cf_sensor_update_picture(struct w9968cf_device* cam, } if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) { - err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT, - pict.colour); + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT, + pict.colour); if (err) goto fail; DBG(4, "Colour changed from %u to %u", @@ -2319,8 +2313,8 @@ w9968cf_sensor_update_picture(struct w9968cf_device* cam, } if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) { - err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE, - pict.hue); + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE, + pict.hue); if (err) goto fail; DBG(4, "Hue changed from %u to %u", @@ -2349,12 +2343,12 @@ static int w9968cf_sensor_init(struct w9968cf_device* cam) { int err = 0; - if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE, - &cam->monochrome))) + if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE, + &cam->monochrome))) goto error; - if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE, - &cam->sensor))) + if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE, + &cam->sensor))) goto error; /* NOTE: Make sure width and height are a multiple of 16 */ @@ -2416,16 +2410,16 @@ error: /*-------------------------------------------------------------------------- Fill some basic fields in the main device data structure. - This function is called once on w9968cf_usb_probe() for each recognized + This function is called once on w9968cf_usb_probe() for each recognized camera. --------------------------------------------------------------------------*/ static void w9968cf_configure_camera(struct w9968cf_device* cam, - struct usb_device* udev, - enum w9968cf_model_id mod_id, - const unsigned short dev_nr) + struct usb_device* udev, + enum w9968cf_model_id mod_id, + const unsigned short dev_nr) { - mutex_init(&cam->fileop_mutex); + init_MUTEX(&cam->fileop_sem); init_waitqueue_head(&cam->open); spin_lock_init(&cam->urb_lock); spin_lock_init(&cam->flist_lock); @@ -2444,60 +2438,60 @@ w9968cf_configure_camera(struct w9968cf_device* cam, packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1]; cam->altsetting++); - cam->max_buffers = (max_buffers[dev_nr] < 2 || - max_buffers[dev_nr] > W9968CF_MAX_BUFFERS) - ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr]; + cam->max_buffers = (max_buffers[dev_nr] < 2 || + max_buffers[dev_nr] > W9968CF_MAX_BUFFERS) + ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr]; - cam->double_buffer = (double_buffer[dev_nr] == 0 || - double_buffer[dev_nr] == 1) - ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER; + cam->double_buffer = (double_buffer[dev_nr] == 0 || + double_buffer[dev_nr] == 1) + ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER; cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1) - ? (u8)clamping[dev_nr] : W9968CF_CLAMPING; - + ? (u8)clamping[dev_nr] : W9968CF_CLAMPING; + cam->filter_type = (filter_type[dev_nr] == 0 || - filter_type[dev_nr] == 1 || - filter_type[dev_nr] == 2) - ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE; + filter_type[dev_nr] == 1 || + filter_type[dev_nr] == 2) + ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE; cam->capture = 1; cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1) - ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW; + ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW; - cam->decompression = (decompression[dev_nr] == 0 || - decompression[dev_nr] == 1 || - decompression[dev_nr] == 2) - ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION; + cam->decompression = (decompression[dev_nr] == 0 || + decompression[dev_nr] == 1 || + decompression[dev_nr] == 2) + ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION; - cam->upscaling = (upscaling[dev_nr] == 0 || - upscaling[dev_nr] == 1) - ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING; + cam->upscaling = (upscaling[dev_nr] == 0 || + upscaling[dev_nr] == 1) + ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING; cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1) - ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT; + ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT; cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1) - ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP; + ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP; cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60) - ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ; + ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ; - cam->bandfilt = (bandingfilter[dev_nr] == 0 || - bandingfilter[dev_nr] == 1) - ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER; + cam->bandfilt = (bandingfilter[dev_nr] == 0 || + bandingfilter[dev_nr] == 1) + ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER; cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1) - ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT; + ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT; cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0) - ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV; + ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV; cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1) - ? (u8)mirror[dev_nr] : W9968CF_MIRROR; + ? (u8)mirror[dev_nr] : W9968CF_MIRROR; cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1) - ? monochrome[dev_nr] : W9968CF_MONOCHROME; + ? monochrome[dev_nr] : W9968CF_MONOCHROME; cam->picture.brightness = (u16)brightness[dev_nr]; cam->picture.hue = (u16)hue[dev_nr]; @@ -2519,7 +2513,7 @@ w9968cf_configure_camera(struct w9968cf_device* cam, cam->picture.depth = w9968cf_valid_depth(cam->picture.palette); cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1) - ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB; + ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB; cam->window.x = 0; cam->window.y = 0; @@ -2531,16 +2525,16 @@ w9968cf_configure_camera(struct w9968cf_device* cam, DBG(3, "%s configured with settings #%u:", symbolic(camlist, cam->id), dev_nr) - + DBG(3, "- Data packet size for USB isochrnous transfer: %u bytes", wMaxPacketSize[cam->altsetting-1]) - + DBG(3, "- Number of requested video frame buffers: %u", cam->max_buffers) if (cam->double_buffer) DBG(3, "- Hardware double buffering enabled") - else + else DBG(3, "- Hardware double buffering disabled") if (cam->filter_type == 0) @@ -2648,12 +2642,12 @@ static void w9968cf_adjust_configuration(struct w9968cf_device* cam) /*-------------------------------------------------------------------------- Release the resources used by the driver. - This function is called on disconnect + This function is called on disconnect (or on close if deallocation has been deferred) --------------------------------------------------------------------------*/ static void w9968cf_release_resources(struct w9968cf_device* cam) { - mutex_lock(&w9968cf_devlist_mutex); + down(&w9968cf_devlist_sem); DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor) @@ -2664,7 +2658,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam) kfree(cam->control_buffer); kfree(cam->data_buffer); - mutex_unlock(&w9968cf_devlist_mutex); + up(&w9968cf_devlist_sem); } @@ -2684,14 +2678,14 @@ static int w9968cf_open(struct inode* inode, struct file* filp) cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); - mutex_lock(&cam->dev_mutex); + down(&cam->dev_sem); if (cam->sensor == CC_UNKNOWN) { DBG(2, "No supported image sensor has been detected by the " "'ovcamchip' module for the %s (/dev/video%d). Make " "sure it is loaded *before* (re)connecting the camera.", symbolic(camlist, cam->id), cam->v4ldev->minor) - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); up_read(&w9968cf_disconnect); return -ENODEV; } @@ -2700,14 +2694,14 @@ static int w9968cf_open(struct inode* inode, struct file* filp) DBG(2, "%s (/dev/video%d) has been already occupied by '%s'", symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command) if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) { - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); up_read(&w9968cf_disconnect); return -EWOULDBLOCK; } - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); err = wait_event_interruptible_exclusive(cam->open, - cam->disconnected || - !cam->users); + cam->disconnected || + !cam->users); if (err) { up_read(&w9968cf_disconnect); return err; @@ -2716,7 +2710,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp) up_read(&w9968cf_disconnect); return -ENODEV; } - mutex_lock(&cam->dev_mutex); + down(&cam->dev_sem); } DBG(5, "Opening '%s', /dev/video%d ...", @@ -2745,7 +2739,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp) DBG(5, "Video device is open") - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); up_read(&w9968cf_disconnect); return 0; @@ -2753,7 +2747,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp) deallocate_memory: w9968cf_deallocate_memory(cam); DBG(2, "Failed to open the video device") - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); up_read(&w9968cf_disconnect); return err; } @@ -2765,13 +2759,13 @@ static int w9968cf_release(struct inode* inode, struct file* filp) cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); - mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ + down(&cam->dev_sem); /* prevent disconnect() to be called */ w9968cf_stop_transfer(cam); if (cam->disconnected) { w9968cf_release_resources(cam); - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); kfree(cam); return 0; } @@ -2781,7 +2775,7 @@ static int w9968cf_release(struct inode* inode, struct file* filp) wake_up_interruptible_nr(&cam->open, 1); DBG(5, "Video device closed") - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); return 0; } @@ -2798,18 +2792,18 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) if (filp->f_flags & O_NONBLOCK) return -EWOULDBLOCK; - if (mutex_lock_interruptible(&cam->fileop_mutex)) + if (down_interruptible(&cam->fileop_sem)) return -ERESTARTSYS; if (cam->disconnected) { DBG(2, "Device not present") - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -ENODEV; } if (cam->misconfigured) { DBG(2, "The camera is misconfigured. Close and open it again.") - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EIO; } @@ -2820,15 +2814,15 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) w9968cf_push_frame(cam, 1); err = wait_event_interruptible(cam->wait_queue, - cam->frame[0].status == F_READY || - cam->frame[1].status == F_READY || - cam->disconnected); + cam->frame[0].status == F_READY || + cam->frame[1].status == F_READY || + cam->disconnected); if (err) { - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return err; } if (cam->disconnected) { - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -ENODEV; } @@ -2842,7 +2836,7 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) if (copy_to_user(buf, fr->buffer, count)) { fr->status = F_UNUSED; - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EFAULT; } *f_pos += count; @@ -2851,7 +2845,7 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) DBG(5, "%zu bytes read", count) - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return count; } @@ -2859,12 +2853,12 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma) { struct w9968cf_device* cam = (struct w9968cf_device*) - video_get_drvdata(video_devdata(filp)); + video_get_drvdata(video_devdata(filp)); unsigned long vsize = vma->vm_end - vma->vm_start, - psize = cam->nbuffers * cam->frame[0].size, - start = vma->vm_start, - pos = (unsigned long)cam->frame[0].buffer, - page; + psize = cam->nbuffers * cam->frame[0].size, + start = vma->vm_start, + pos = (unsigned long)cam->frame[0].buffer, + page; if (cam->disconnected) { DBG(2, "Device not present") @@ -2898,51 +2892,51 @@ static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma) static int w9968cf_ioctl(struct inode* inode, struct file* filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { struct w9968cf_device* cam; int err; cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); - if (mutex_lock_interruptible(&cam->fileop_mutex)) + if (down_interruptible(&cam->fileop_sem)) return -ERESTARTSYS; if (cam->disconnected) { DBG(2, "Device not present") - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -ENODEV; } if (cam->misconfigured) { DBG(2, "The camera is misconfigured. Close and open it again.") - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return -EIO; } err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg); - mutex_unlock(&cam->fileop_mutex); + up(&cam->fileop_sem); return err; } static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, - unsigned int cmd, void __user * arg) + unsigned int cmd, void __user * arg) { struct w9968cf_device* cam; const char* v4l1_ioctls[] = { - "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", + "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE", - "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE", - "GVBIFMT", "SVBIFMT" + "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE", + "GVBIFMT", "SVBIFMT" }; #define V4L1_IOCTL(cmd) \ - ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \ - v4l1_ioctls[_IOC_NR((cmd))] : "?") + ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \ + v4l1_ioctls[_IOC_NR((cmd))] : "?") cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); @@ -2957,14 +2951,14 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, .minwidth = cam->minwidth, .minheight = cam->minheight, }; - sprintf(cap.name, "W996[87]CF USB Camera #%d", - cam->v4ldev->minor); + sprintf(cap.name, "W996[87]CF USB Camera #%d", + cam->v4ldev->minor); cap.maxwidth = (cam->upscaling && w9968cf_vpp) - ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) - : cam->maxwidth; + ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) + : cam->maxwidth; cap.maxheight = (cam->upscaling && w9968cf_vpp) - ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight) - : cam->maxheight; + ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight) + : cam->maxheight; if (copy_to_user(arg, &cap, sizeof(cap))) return -EFAULT; @@ -3029,7 +3023,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, if (copy_from_user(&pict, arg, sizeof(pict))) return -EFAULT; - if ( (cam->force_palette || !w9968cf_vpp) + if ( (cam->force_palette || !w9968cf_vpp) && pict.palette != cam->picture.palette ) { DBG(4, "Palette %s rejected: only %s is allowed", symbolic(v4l1_plist, pict.palette), @@ -3046,24 +3040,24 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, if (!cam->force_palette) { if (cam->decompression == 0) { if (w9968cf_need_decompression(pict.palette)) { - DBG(4, "Decompression disabled: palette %s is not " - "allowed. VIDIOCSPICT failed", - symbolic(v4l1_plist, pict.palette)) - return -EINVAL; + DBG(4, "Decompression disabled: palette %s is not " + "allowed. VIDIOCSPICT failed", + symbolic(v4l1_plist, pict.palette)) + return -EINVAL; } } else if (cam->decompression == 1) { if (!w9968cf_need_decompression(pict.palette)) { - DBG(4, "Decompression forced: palette %s is not " - "allowed. VIDIOCSPICT failed", - symbolic(v4l1_plist, pict.palette)) - return -EINVAL; + DBG(4, "Decompression forced: palette %s is not " + "allowed. VIDIOCSPICT failed", + symbolic(v4l1_plist, pict.palette)) + return -EINVAL; } } } if (pict.depth != w9968cf_valid_depth(pict.palette)) { DBG(4, "Requested depth %u bpp is not valid for %s " - "palette: ignored and changed to %u bpp", + "palette: ignored and changed to %u bpp", pict.depth, symbolic(v4l1_plist, pict.palette), w9968cf_valid_depth(pict.palette)) pict.depth = w9968cf_valid_depth(pict.palette); @@ -3074,9 +3068,9 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, || cam->frame_current->queued) { err = wait_event_interruptible ( cam->wait_queue, - cam->disconnected || - (!*cam->requested_frame && - !cam->frame_current->queued) ); + cam->disconnected || + (!*cam->requested_frame && + !cam->frame_current->queued) ); if (err) return err; if (cam->disconnected) @@ -3116,7 +3110,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, return -EINVAL; if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, - (u16*)&win.height))) { + (u16*)&win.height))) { DBG(4, "Resolution not supported (%ux%u). " "VIDIOCSWIN failed", win.width, win.height) return err; @@ -3130,9 +3124,9 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, || cam->frame_current->queued) { err = wait_event_interruptible ( cam->wait_queue, - cam->disconnected || - (!*cam->requested_frame && - !cam->frame_current->queued) ); + cam->disconnected || + (!*cam->requested_frame && + !cam->frame_current->queued) ); if (err) return err; if (cam->disconnected) @@ -3175,7 +3169,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, mbuf.frames = cam->nbuffers; for (i = 0; i < cam->nbuffers; i++) mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer - - (unsigned long)cam->frame[0].buffer; + (unsigned long)cam->frame[0].buffer; if (copy_to_user(arg, &mbuf, sizeof(mbuf))) return -EFAULT; @@ -3194,7 +3188,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, return -EFAULT; DBG(6, "VIDIOCMCAPTURE called: frame #%u, format=%s, %dx%d", - mmap.frame, symbolic(v4l1_plist, mmap.format), + mmap.frame, symbolic(v4l1_plist, mmap.format), mmap.width, mmap.height) if (mmap.frame >= cam->nbuffers) { @@ -3203,7 +3197,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, return -EINVAL; } - if (mmap.format!=cam->picture.palette && + if (mmap.format!=cam->picture.palette && (cam->force_palette || !w9968cf_vpp)) { DBG(4, "Palette %s rejected: only %s is allowed", symbolic(v4l1_plist, mmap.format), @@ -3213,7 +3207,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, if (!w9968cf_valid_palette(mmap.format)) { DBG(4, "Palette %s not supported. " - "VIDIOCMCAPTURE failed", + "VIDIOCMCAPTURE failed", symbolic(v4l1_plist, mmap.format)) return -EINVAL; } @@ -3221,23 +3215,23 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, if (!cam->force_palette) { if (cam->decompression == 0) { if (w9968cf_need_decompression(mmap.format)) { - DBG(4, "Decompression disabled: palette %s is not " - "allowed. VIDIOCSPICT failed", - symbolic(v4l1_plist, mmap.format)) - return -EINVAL; + DBG(4, "Decompression disabled: palette %s is not " + "allowed. VIDIOCSPICT failed", + symbolic(v4l1_plist, mmap.format)) + return -EINVAL; } } else if (cam->decompression == 1) { if (!w9968cf_need_decompression(mmap.format)) { - DBG(4, "Decompression forced: palette %s is not " - "allowed. VIDIOCSPICT failed", - symbolic(v4l1_plist, mmap.format)) - return -EINVAL; + DBG(4, "Decompression forced: palette %s is not " + "allowed. VIDIOCSPICT failed", + symbolic(v4l1_plist, mmap.format)) + return -EINVAL; } } } - if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width, - (u16*)&mmap.height))) { + if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width, + (u16*)&mmap.height))) { DBG(4, "Resolution not supported (%dx%d). " "VIDIOCMCAPTURE failed", mmap.width, mmap.height) @@ -3258,12 +3252,12 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, DBG(6, "VIDIOCMCAPTURE. Change settings for " "frame #%u: %dx%d, format %s. Wait...", mmap.frame, mmap.width, mmap.height, - symbolic(v4l1_plist, mmap.format)) + symbolic(v4l1_plist, mmap.format)) err = wait_event_interruptible ( cam->wait_queue, - cam->disconnected || - (!*cam->requested_frame && - !cam->frame_current->queued) ); + cam->disconnected || + (!*cam->requested_frame && + !cam->frame_current->queued) ); if (err) return err; if (cam->disconnected) @@ -3280,7 +3274,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, goto ioctl_fail; /* This before set_window */ - if (w9968cf_set_picture(cam, pict)) + if (w9968cf_set_picture(cam, pict)) goto ioctl_fail; if (w9968cf_set_window(cam, win)) @@ -3292,10 +3286,10 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, } else if (fr->queued) { DBG(6, "Wait until frame #%u is free", mmap.frame) - - err = wait_event_interruptible(cam->wait_queue, - cam->disconnected || - (!fr->queued)); + + err = wait_event_interruptible(cam->wait_queue, + cam->disconnected || + (!fr->queued)); if (err) return err; if (cam->disconnected) @@ -3335,9 +3329,9 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, } case F_ERROR: case F_GRABBING: - err = wait_event_interruptible(cam->wait_queue, - (fr->status == F_READY) - || cam->disconnected); + err = wait_event_interruptible(cam->wait_queue, + (fr->status == F_READY) + || cam->disconnected); if (err) return err; if (cam->disconnected) @@ -3439,7 +3433,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s " "(type 0x%01X, " "n. 0x%01X, " - "dir. 0x%01X, " + "dir. 0x%01X, " "size 0x%02X)", V4L1_IOCTL(cmd), _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd)) @@ -3499,18 +3493,20 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct) mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */ else if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[1].idVendor && - le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct) + le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct) mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */ else return -ENODEV; cam = (struct w9968cf_device*) - kzalloc(sizeof(struct w9968cf_device), GFP_KERNEL); + kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL); if (!cam) return -ENOMEM; - mutex_init(&cam->dev_mutex); - mutex_lock(&cam->dev_mutex); + memset(cam, 0, sizeof(*cam)); + + init_MUTEX(&cam->dev_sem); + down(&cam->dev_sem); cam->usbdev = udev; /* NOTE: a local copy is used to avoid possible race conditions */ @@ -3522,10 +3518,10 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) simcams = W9968CF_SIMCAMS; /* How many cameras are connected ? */ - mutex_lock(&w9968cf_devlist_mutex); + down(&w9968cf_devlist_sem); list_for_each(ptr, &w9968cf_dev_list) sc++; - mutex_unlock(&w9968cf_devlist_mutex); + up(&w9968cf_devlist_sem); if (sc >= simcams) { DBG(2, "Device rejected: too many connected cameras " @@ -3536,19 +3532,21 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) /* Allocate 2 bytes of memory for camera control USB transfers */ - if (!(cam->control_buffer = kzalloc(2, GFP_KERNEL))) { + if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) { DBG(1,"Couldn't allocate memory for camera control transfers") err = -ENOMEM; goto fail; } + memset(cam->control_buffer, 0, 2); /* Allocate 8 bytes of memory for USB data transfers to the FSB */ - if (!(cam->data_buffer = kzalloc(8, GFP_KERNEL))) { + if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) { DBG(1, "Couldn't allocate memory for data " "transfers to the FSB") err = -ENOMEM; goto fail; } + memset(cam->data_buffer, 0, 8); /* Register the V4L device */ cam->v4ldev = video_device_alloc(); @@ -3569,7 +3567,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) cam->v4ldev->dev = &cam->dev; err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, - video_nr[dev_nr]); + video_nr[dev_nr]); if (err) { DBG(1, "V4L device registration failed") if (err == -ENFILE && video_nr[dev_nr] == -1) @@ -3585,9 +3583,9 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) w9968cf_configure_camera(cam, udev, mod_id, dev_nr); /* Add a new entry into the list of V4L registered devices */ - mutex_lock(&w9968cf_devlist_mutex); + down(&w9968cf_devlist_sem); list_add(&cam->v4llist, &w9968cf_dev_list); - mutex_unlock(&w9968cf_devlist_mutex); + up(&w9968cf_devlist_sem); dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0; w9968cf_turn_on_led(cam); @@ -3595,7 +3593,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) w9968cf_i2c_init(cam); usb_set_intfdata(intf, cam); - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); return 0; fail: /* Free unused memory */ @@ -3603,7 +3601,7 @@ fail: /* Free unused memory */ kfree(cam->data_buffer); if (cam->v4ldev) video_device_release(cam->v4ldev); - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); kfree(cam); return err; } @@ -3611,14 +3609,14 @@ fail: /* Free unused memory */ static void w9968cf_usb_disconnect(struct usb_interface* intf) { - struct w9968cf_device* cam = + struct w9968cf_device* cam = (struct w9968cf_device*)usb_get_intfdata(intf); down_write(&w9968cf_disconnect); if (cam) { /* Prevent concurrent accesses to data */ - mutex_lock(&cam->dev_mutex); + down(&cam->dev_sem); cam->disconnected = 1; @@ -3637,7 +3635,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) } else w9968cf_release_resources(cam); - mutex_unlock(&cam->dev_mutex); + up(&cam->dev_sem); if (!cam->users) kfree(cam); diff --git a/drivers/media/video/w9968cf.h b/drivers/usb/media/w9968cf.h similarity index 94% rename from drivers/media/video/w9968cf.h rename to drivers/usb/media/w9968cf.h index 2836b45ec..47a6ff794 100644 --- a/drivers/media/video/w9968cf.h +++ b/drivers/usb/media/w9968cf.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include @@ -61,7 +61,7 @@ /* Maximum data payload sizes in bytes for alternate settings */ static const u16 wMaxPacketSize[] = {1023, 959, 895, 831, 767, 703, 639, 575, - 511, 447, 383, 319, 255, 191, 127, 63}; + 511, 447, 383, 319, 255, 191, 127, 63}; #define W9968CF_PACKET_SIZE 1023 /* according to wMaxPacketSizes[] */ #define W9968CF_MIN_PACKET_SIZE 63 /* minimum value */ #define W9968CF_ISO_PACKETS 5 /* n.of packets for isochronous transfers */ @@ -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" + "Dual Mode Camera Chip" #define W9968CF_MODULE_VERSION "1:1.33-basic" #define W9968CF_MODULE_AUTHOR "(C) 2002-2004 Luca Risolia" #define W9968CF_AUTHOR_EMAIL "" @@ -194,6 +194,14 @@ enum w9968cf_vpp_flag { VPP_UYVY_TO_RGBX = 0x08, }; +static struct w9968cf_vpp_t* w9968cf_vpp; +static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait); + +static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */ +static DECLARE_MUTEX(w9968cf_devlist_sem); /* semaphore for list traversal */ + +static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */ + /* Main device driver structure */ struct w9968cf_device { struct device dev; /* device structure */ @@ -269,10 +277,10 @@ struct w9968cf_device { struct i2c_client* sensor_client; /* Locks */ - struct mutex dev_mutex, /* for probe, disconnect,open and close */ - fileop_mutex; /* for read and ioctl */ + struct semaphore dev_sem, /* for probe, disconnect,open and close */ + fileop_sem; /* for read and ioctl */ spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */ - flist_lock; /* for requested frame list accesses */ + flist_lock; /* for requested frame list accesses */ wait_queue_head_t open, wait_queue; char command[16]; /* name of the program holding the device */ @@ -299,7 +307,7 @@ struct w9968cf_device { dev_warn(&cam->dev, fmt "\n", ## args); \ else if ((level) >= 5) \ dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args); \ + __FUNCTION__, __LINE__ , ## args); \ } \ } /* For generic kernel (not device specific) messages */ @@ -311,7 +319,7 @@ struct w9968cf_device { pr_info("w9968cf: " fmt "\n", ## args); \ else if ((level) >= 5) \ pr_debug("w9968cf: [%s:%d] " fmt "\n", __FUNCTION__, \ - __LINE__ , ## args); \ + __LINE__ , ## args); \ } \ } #else diff --git a/drivers/media/video/w9968cf_decoder.h b/drivers/usb/media/w9968cf_decoder.h similarity index 94% rename from drivers/media/video/w9968cf_decoder.h rename to drivers/usb/media/w9968cf_decoder.h index 59decbfc5..31faccbe8 100644 --- a/drivers/media/video/w9968cf_decoder.h +++ b/drivers/usb/media/w9968cf_decoder.h @@ -78,9 +78,9 @@ static const unsigned char UV_QUANTABLE[64] = { #define W9968CF_DEC_ERR_NO_EOI -6 extern void w9968cf_init_decoder(void); -extern int w9968cf_check_headers(const unsigned char* Pin, - const unsigned long BUF_SIZE); -extern int w9968cf_decode(const char* Pin, const unsigned long BUF_SIZE, - const unsigned W, const unsigned H, char* Pout); +extern int w9968cf_check_headers(const unsigned char* Pin, + const unsigned long BUF_SIZE); +extern int w9968cf_decode(const char* Pin, const unsigned long BUF_SIZE, + const unsigned W, const unsigned H, char* Pout); #endif /* _W9968CF_DECODER_H_ */ diff --git a/drivers/media/video/w9968cf_vpp.h b/drivers/usb/media/w9968cf_vpp.h similarity index 98% rename from drivers/media/video/w9968cf_vpp.h rename to drivers/usb/media/w9968cf_vpp.h index 88c9b6c0c..f3b91b782 100644 --- a/drivers/media/video/w9968cf_vpp.h +++ b/drivers/usb/media/w9968cf_vpp.h @@ -29,7 +29,7 @@ struct w9968cf_vpp_t { struct module* owner; int (*check_headers)(const unsigned char*, const unsigned long); int (*decode)(const char*, const unsigned long, const unsigned, - const unsigned, char*); + const unsigned, char*); void (*swap_yuvbytes)(void*, unsigned long); void (*uyvy_to_rgbx)(u8*, unsigned long, u8*, u16, u8); void (*scale_up)(u8*, u8*, u16, u16, u16, u16, u16); diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 1fef36e71..ad2f4cccd 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -570,9 +570,10 @@ static int auerchain_setup (pauerchain_t acp, unsigned int numElements) /* fill the list of free elements */ for (;numElements; numElements--) { - acep = kzalloc(sizeof(auerchainelement_t), GFP_KERNEL); + acep = (pauerchainelement_t) kmalloc (sizeof (auerchainelement_t), GFP_KERNEL); if (!acep) goto ac_fail; + memset (acep, 0, sizeof (auerchainelement_t)); INIT_LIST_HEAD (&acep->list); list_add_tail (&acep->list, &acp->free_list); } @@ -760,9 +761,10 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned /* fill the list of free elements */ for (;numElements; numElements--) { - bep = kzalloc(sizeof(auerbuf_t), GFP_KERNEL); + bep = (pauerbuf_t) kmalloc (sizeof (auerbuf_t), GFP_KERNEL); if (!bep) goto bl_fail; + memset (bep, 0, sizeof (auerbuf_t)); bep->list = bcp; INIT_LIST_HEAD (&bep->buff_list); bep->bufp = kmalloc (bufsize, GFP_KERNEL); diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index a04204292..6671317b4 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -351,11 +351,12 @@ static int cytherm_probe(struct usb_interface *interface, struct usb_cytherm *dev = NULL; int retval = -ENOMEM; - dev = kzalloc (sizeof(struct usb_cytherm), GFP_KERNEL); + dev = kmalloc (sizeof(struct usb_cytherm), GFP_KERNEL); if (dev == NULL) { dev_err (&interface->dev, "Out of memory\n"); goto error; } + memset (dev, 0x00, sizeof (*dev)); dev->udev = usb_get_dev(udev); diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 1fd9cb85f..3824df330 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -15,7 +15,6 @@ #include #include #include -#include #define MAX_INTEL_HEX_RECORD_LENGTH 16 typedef struct _INTEL_HEX_RECORD @@ -115,7 +114,6 @@ static int emi26_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); - msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with @@ -152,7 +150,6 @@ static int emi26_load_firmware (struct usb_device *dev) goto wraperr; } } - msleep(250); /* let device settle */ /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); @@ -195,7 +192,6 @@ static int emi26_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } - msleep(250); /* let device settle */ /* return 1 to fail the driver inialization * and give real driver change to load */ diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index fe351371f..52fea2e08 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c @@ -15,7 +15,6 @@ #include #include #include -#include #define MAX_INTEL_HEX_RECORD_LENGTH 16 typedef struct _INTEL_HEX_RECORD @@ -124,7 +123,6 @@ static int emi62_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi62_set_reset(dev,0); - msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with @@ -168,7 +166,6 @@ static int emi62_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } - msleep(250); /* let device settle */ /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ @@ -231,7 +228,6 @@ static int emi62_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } - msleep(250); /* let device settle */ kfree(buf); diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index d0b167256..d8cde1017 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -122,7 +121,7 @@ static struct usb_driver idmouse_driver = { }; /* prevent races between open() and disconnect() */ -static DEFINE_MUTEX(disconnect_mutex); +static DECLARE_MUTEX(disconnect_sem); static int idmouse_create_image(struct usb_idmouse *dev) { @@ -214,18 +213,18 @@ static int idmouse_open(struct inode *inode, struct file *file) int result = 0; /* prevent disconnects */ - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); /* get the interface from minor number and driver information */ interface = usb_find_interface (&idmouse_driver, iminor (inode)); if (!interface) { - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return -ENODEV; } /* get the device information block from the interface */ dev = usb_get_intfdata(interface); if (!dev) { - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return -ENODEV; } @@ -259,7 +258,7 @@ error: up(&dev->sem); /* unlock the disconnect semaphore */ - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return result; } @@ -268,12 +267,12 @@ static int idmouse_release(struct inode *inode, struct file *file) struct usb_idmouse *dev; /* prevent a race condition with open() */ - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); dev = (struct usb_idmouse *) file->private_data; if (dev == NULL) { - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return -ENODEV; } @@ -283,7 +282,7 @@ static int idmouse_release(struct inode *inode, struct file *file) /* are we really open? */ if (dev->open <= 0) { up(&dev->sem); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return -ENODEV; } @@ -293,12 +292,12 @@ static int idmouse_release(struct inode *inode, struct file *file) /* the device was unplugged before the file was released */ up(&dev->sem); idmouse_delete(dev); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return 0; } up(&dev->sem); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return 0; } @@ -341,9 +340,10 @@ static int idmouse_probe(struct usb_interface *interface, return -ENODEV; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) return -ENOMEM; + memset(dev, 0x00, sizeof(*dev)); init_MUTEX(&dev->sem); dev->udev = udev; @@ -400,7 +400,7 @@ static void idmouse_disconnect(struct usb_interface *interface) struct usb_idmouse *dev; /* prevent races with open() */ - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); /* get device structure */ dev = usb_get_intfdata(interface); @@ -422,7 +422,7 @@ static void idmouse_disconnect(struct usb_interface *interface) if (!dev->open) idmouse_delete(dev); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); info("%s disconnected", DRIVER_DESC); } diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 966acb474..e2d119862 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -173,7 +172,7 @@ struct ld_usb { }; /* prevent races between open() and disconnect() */ -static DEFINE_MUTEX(disconnect_mutex); +static DECLARE_MUTEX(disconnect_sem); static struct usb_driver ld_usb_driver; @@ -294,7 +293,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) nonseekable_open(inode, file); subminor = iminor(inode); - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); interface = usb_find_interface(&ld_usb_driver, subminor); @@ -356,7 +355,7 @@ unlock_exit: up(&dev->sem); unlock_disconnect_exit: - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return retval; } @@ -627,11 +626,12 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * /* allocate memory for our device state and intialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { dev_err(&intf->dev, "Out of memory\n"); goto exit; } + memset(dev, 0x00, sizeof(*dev)); init_MUTEX(&dev->sem); dev->intf = intf; init_waitqueue_head(&dev->read_wait); @@ -741,7 +741,7 @@ static void ld_usb_disconnect(struct usb_interface *intf) struct ld_usb *dev; int minor; - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); @@ -762,7 +762,7 @@ static void ld_usb_disconnect(struct usb_interface *intf) up(&dev->sem); } - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", (minor - USB_LD_MINOR_BASE)); diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 779bcf037..1336745b8 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -83,7 +83,6 @@ #include #include #include -#include #include #include #include @@ -257,7 +256,7 @@ static void tower_disconnect (struct usb_interface *interface); /* prevent races between open() and disconnect */ -static DEFINE_MUTEX (disconnect_mutex); +static DECLARE_MUTEX (disconnect_sem); /* file operations needed when we register this driver */ static struct file_operations tower_fops = { @@ -350,7 +349,7 @@ static int tower_open (struct inode *inode, struct file *file) nonseekable_open(inode, file); subminor = iminor(inode); - mutex_lock (&disconnect_mutex); + down (&disconnect_sem); interface = usb_find_interface (&tower_driver, subminor); @@ -428,7 +427,7 @@ unlock_exit: up (&dev->sem); unlock_disconnect_exit: - mutex_unlock (&disconnect_mutex); + up (&disconnect_sem); dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval); @@ -1006,7 +1005,7 @@ static void tower_disconnect (struct usb_interface *interface) dbg(2, "%s: enter", __FUNCTION__); - mutex_lock (&disconnect_mutex); + down (&disconnect_sem); dev = usb_get_intfdata (interface); usb_set_intfdata (interface, NULL); @@ -1028,7 +1027,7 @@ static void tower_disconnect (struct usb_interface *interface) up (&dev->sem); } - mutex_unlock (&disconnect_mutex); + up (&disconnect_sem); info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE)); diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 997db5d8e..605a3c87e 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c @@ -88,7 +88,7 @@ static int change_outputs(struct phidget_interfacekit *kit, int output_num, int int retval; int n; - buffer = kzalloc(4, GFP_KERNEL); + buffer = kmalloc(4, GFP_KERNEL); if (!buffer) { dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); @@ -96,6 +96,7 @@ static int change_outputs(struct phidget_interfacekit *kit, int output_num, int } kit->outputs[output_num] = enable; + memset(buffer, 0, 4); for (n=0; n<8; n++) { if (kit->outputs[n]) { buffer[0] |= 1 << n; @@ -191,7 +192,7 @@ static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, unsigned char *buffer; int retval = -ENOMEM; - buffer = kzalloc(8, GFP_KERNEL); + buffer = kmalloc(8, GFP_KERNEL); if (!buffer) { dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); goto exit; @@ -201,6 +202,7 @@ static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, retval = -EINVAL; goto exit; } + memset(buffer, 0x00, 8); if (enabled) buffer[0] = 0x01; buffer[7] = 0x11; @@ -404,11 +406,12 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - kit = kzalloc(sizeof(*kit), GFP_KERNEL); + kit = kmalloc(sizeof(*kit), GFP_KERNEL); if (kit == NULL) { dev_err(&intf->dev, "%s - out of memory\n", __FUNCTION__); return -ENOMEM; } + memset(kit, 0, sizeof(*kit)); kit->ifkit = ifkit; kit->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kit->data_dma); diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index 5a040c205..b3418d2bc 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c @@ -252,11 +252,12 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id) struct usb_device *udev = interface_to_usbdev(interface); struct phidget_servo *dev; - dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL); + dev = kmalloc(sizeof (struct phidget_servo), GFP_KERNEL); if (dev == NULL) { dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); return -ENOMEM; } + memset(dev, 0x00, sizeof (*dev)); dev->udev = usb_get_dev(udev); dev->type = id->driver_info; diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 196c8794a..3260d5954 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3188,7 +3188,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, break; default: - retval = -ENOTTY; + retval = -EINVAL; break; } @@ -3251,11 +3251,12 @@ static int sisusb_probe(struct usb_interface *intf, dev->devnum); /* Allocate memory for our private */ - if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) { + if (!(sisusb = kmalloc(sizeof(*sisusb), GFP_KERNEL))) { printk(KERN_ERR "sisusb: Failed to allocate memory for private data\n"); return -ENOMEM; } + memset(sisusb, 0, sizeof(*sisusb)); kref_init(&sisusb->kref); init_MUTEX(&(sisusb->lock)); diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h index a716825d1..1d7a77cc7 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.h +++ b/drivers/usb/misc/sisusbvga/sisusb.h @@ -37,16 +37,24 @@ #ifndef _SISUSB_H_ #define _SISUSB_H_ +#include #ifdef CONFIG_COMPAT +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) +#include +#define SISUSB_OLD_CONFIG_COMPAT +#else #define SISUSB_NEW_CONFIG_COMPAT #endif +#endif /* For older kernels, support for text consoles is by default * off. To ensable text console support, change the following: */ #if 0 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) #define CONFIG_USB_SISUSBVGA_CON #endif +#endif /* Version Information */ diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index c82c40228..cc3dae3f3 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -270,11 +270,12 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { err("Out of memory"); goto error; } + memset(dev, 0x00, sizeof(*dev)); kref_init(&dev->kref); dev->udev = usb_get_dev(interface_to_usbdev(interface)); diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index f44196413..877b081a3 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c @@ -106,11 +106,12 @@ static int led_probe(struct usb_interface *interface, const struct usb_device_id struct usb_led *dev = NULL; int retval = -ENOMEM; - dev = kzalloc(sizeof(struct usb_led), GFP_KERNEL); + dev = kmalloc(sizeof(struct usb_led), GFP_KERNEL); if (dev == NULL) { dev_err(&interface->dev, "Out of memory\n"); goto error; } + memset (dev, 0x00, sizeof (*dev)); dev->udev = usb_get_dev(udev); diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index ccc5e8238..84fa1728f 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -381,27 +381,17 @@ alloc_sglist (int nents, int max, int vary) for (i = 0; i < nents; i++) { char *buf; - unsigned j; - buf = kzalloc (size, SLAB_KERNEL); + buf = kmalloc (size, SLAB_KERNEL); if (!buf) { free_sglist (sg, i); return NULL; } + memset (buf, 0, size); /* kmalloc pages are always physically contiguous! */ sg_init_one(&sg[i], buf, size); - switch (pattern) { - case 0: - /* already zeroed */ - break; - case 1: - for (j = 0; j < size; j++) - *buf++ = (u8) (j % 63); - break; - } - if (vary) { size += vary; size %= max; @@ -436,8 +426,6 @@ static int perform_sglist ( usb_sg_wait (req); retval = req->status; - /* FIXME check resulting data pattern */ - /* FIXME if endpoint halted, clear halt (and log) */ } @@ -854,9 +842,10 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) * as with bulk/intr sglists, sglen is the queue depth; it also * controls which subtests run (more tests than sglen) or rerun. */ - urb = kcalloc(param->sglen, sizeof(struct urb *), SLAB_KERNEL); + urb = kmalloc (param->sglen * sizeof (struct urb *), SLAB_KERNEL); if (!urb) return -ENOMEM; + memset (urb, 0, param->sglen * sizeof (struct urb *)); for (i = 0; i < param->sglen; i++) { int pipe = usb_rcvctrlpipe (udev, 0); unsigned len; @@ -1876,9 +1865,10 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) } #endif - dev = kzalloc(sizeof(*dev), SLAB_KERNEL); + dev = kmalloc (sizeof *dev, SLAB_KERNEL); if (!dev) return -ENOMEM; + memset (dev, 0, sizeof *dev); info = (struct usbtest_info *) id->driver_info; dev->info = info; init_MUTEX (&dev->sem); diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 6ecc27302..c34944c75 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "usb_mon.h" #include "../core/hcd.h" @@ -24,7 +23,7 @@ static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); static void mon_bus_drop(struct kref *r); static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus); -DEFINE_MUTEX(mon_lock); +DECLARE_MUTEX(mon_lock); static struct dentry *mon_dir; /* /dbg/usbmon */ static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ @@ -197,14 +196,14 @@ static void mon_bus_remove(struct usb_bus *ubus) { struct mon_bus *mbus = ubus->mon_bus; - mutex_lock(&mon_lock); + down(&mon_lock); list_del(&mbus->bus_link); debugfs_remove(mbus->dent_t); debugfs_remove(mbus->dent_s); mon_dissolve(mbus, ubus); kref_put(&mbus->ref, mon_bus_drop); - mutex_unlock(&mon_lock); + up(&mon_lock); } static int mon_notify(struct notifier_block *self, unsigned long action, @@ -277,8 +276,9 @@ static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) char name[NAMESZ]; int rc; - if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) + if ((mbus = kmalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) goto err_alloc; + memset(mbus, 0, sizeof(struct mon_bus)); kref_init(&mbus->ref); spin_lock_init(&mbus->lock); INIT_LIST_HEAD(&mbus->r_list); @@ -307,9 +307,9 @@ static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) goto err_create_s; mbus->dent_s = d; - mutex_lock(&mon_lock); + down(&mon_lock); list_add_tail(&mbus->bus_link, &mon_buses); - mutex_unlock(&mon_lock); + up(&mon_lock); return; err_create_s: @@ -347,11 +347,11 @@ static int __init mon_init(void) usb_register_notify(&mon_nb); - mutex_lock(&usb_bus_list_lock); + down(&usb_bus_list_lock); list_for_each_entry (ubus, &usb_bus_list, bus_list) { mon_bus_init(mondir, ubus); } - mutex_unlock(&usb_bus_list_lock); + up(&usb_bus_list_lock); return 0; } @@ -363,7 +363,7 @@ static void __exit mon_exit(void) usb_unregister_notify(&mon_nb); usb_mon_deregister(); - mutex_lock(&mon_lock); + down(&mon_lock); while (!list_empty(&mon_buses)) { p = mon_buses.next; mbus = list_entry(p, struct mon_bus, bus_link); @@ -387,7 +387,7 @@ static void __exit mon_exit(void) mon_dissolve(mbus, mbus->u_bus); kref_put(&mbus->ref, mon_bus_drop); } - mutex_unlock(&mon_lock); + up(&mon_lock); debugfs_remove(mon_dir); } diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index ac043ec2b..611612146 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include "usb_mon.h" @@ -55,7 +54,7 @@ struct mon_reader_text { wait_queue_head_t wait; int printf_size; char *printf_buf; - struct mutex printf_lock; + struct semaphore printf_lock; char slab_name[SLAB_NAME_SZ]; }; @@ -209,18 +208,19 @@ static int mon_text_open(struct inode *inode, struct file *file) struct mon_reader_text *rp; int rc; - mutex_lock(&mon_lock); + down(&mon_lock); mbus = inode->u.generic_ip; ubus = mbus->u_bus; - rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL); + rp = kmalloc(sizeof(struct mon_reader_text), GFP_KERNEL); if (rp == NULL) { rc = -ENOMEM; goto err_alloc; } + memset(rp, 0, sizeof(struct mon_reader_text)); INIT_LIST_HEAD(&rp->e_list); init_waitqueue_head(&rp->wait); - mutex_init(&rp->printf_lock); + init_MUTEX(&rp->printf_lock); rp->printf_size = PRINTF_DFL; rp->printf_buf = kmalloc(rp->printf_size, GFP_KERNEL); @@ -247,7 +247,7 @@ static int mon_text_open(struct inode *inode, struct file *file) mon_reader_add(mbus, &rp->r); file->private_data = rp; - mutex_unlock(&mon_lock); + up(&mon_lock); return 0; // err_busy: @@ -257,7 +257,7 @@ err_slab: err_alloc_pr: kfree(rp); err_alloc: - mutex_unlock(&mon_lock); + up(&mon_lock); return rc; } @@ -301,7 +301,7 @@ static ssize_t mon_text_read(struct file *file, char __user *buf, set_current_state(TASK_RUNNING); remove_wait_queue(&rp->wait, &waita); - mutex_lock(&rp->printf_lock); + down(&rp->printf_lock); cnt = 0; pbuf = rp->printf_buf; limit = rp->printf_size; @@ -358,7 +358,7 @@ static ssize_t mon_text_read(struct file *file, char __user *buf, if (copy_to_user(buf, rp->printf_buf, cnt)) cnt = -EFAULT; - mutex_unlock(&rp->printf_lock); + up(&rp->printf_lock); kmem_cache_free(rp->e_slab, ep); return cnt; } @@ -371,12 +371,12 @@ static int mon_text_release(struct inode *inode, struct file *file) struct list_head *p; struct mon_event_text *ep; - mutex_lock(&mon_lock); + down(&mon_lock); mbus = inode->u.generic_ip; if (mbus->nreaders <= 0) { printk(KERN_ERR TAG ": consistency error on close\n"); - mutex_unlock(&mon_lock); + up(&mon_lock); return 0; } mon_reader_del(mbus, &rp->r); @@ -402,7 +402,7 @@ static int mon_text_release(struct inode *inode, struct file *file) kfree(rp->printf_buf); kfree(rp); - mutex_unlock(&mon_lock); + up(&mon_lock); return 0; } diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index 8e0613c35..4be0f9346 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h @@ -49,7 +49,7 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); */ extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len); -extern struct mutex mon_lock; +extern struct semaphore mon_lock; extern struct file_operations mon_fops_text; extern struct file_operations mon_fops_stat; diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig index efd6ca7e4..6c94f59db 100644 --- a/drivers/usb/net/Kconfig +++ b/drivers/usb/net/Kconfig @@ -84,6 +84,7 @@ config USB_PEGASUS config USB_RTL8150 tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)" depends on EXPERIMENTAL + select MII help Say Y here if you have RTL8150 based usb-ethernet adapter. Send me any comments you may have. diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 12b599a0b..309497061 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c @@ -37,6 +37,7 @@ #include "usbnet.h" + /* ASIX AX8817X based USB 2.0 Ethernet Devices */ #define AX_CMD_SET_SW_MII 0x06 @@ -108,7 +109,7 @@ #define AX_EEPROM_MAGIC 0xdeadbeef /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ -struct asix_data { +struct ax8817x_data { u8 multi_filter[AX_MCAST_FILTER_SIZE]; }; @@ -120,7 +121,7 @@ struct ax88172_int_data { u16 res3; } __attribute__ ((packed)); -static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, +static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { return usb_control_msg( @@ -135,7 +136,7 @@ static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, USB_CTRL_GET_TIMEOUT); } -static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, +static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { return usb_control_msg( @@ -150,80 +151,19 @@ static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, USB_CTRL_SET_TIMEOUT); } -static void asix_async_cmd_callback(struct urb *urb, struct pt_regs *regs) +static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs) { struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; if (urb->status < 0) - printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d", + printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d", urb->status); kfree(req); usb_free_urb(urb); } -static inline int asix_set_sw_mii(struct usbnet *dev) -{ - int ret; - ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); - if (ret < 0) - devdbg(dev, "Failed to enable software MII access"); - return ret; -} - -static inline int asix_set_hw_mii(struct usbnet *dev) -{ - int ret; - ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); - if (ret < 0) - devdbg(dev, "Failed to enable hardware MII access"); - return ret; -} - -static inline int asix_get_phyid(struct usbnet *dev) -{ - int ret = 0; - void *buf; - - buf = kmalloc(2, GFP_KERNEL); - if (!buf) - goto out1; - - if ((ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, - 0, 0, 2, buf)) < 2) { - devdbg(dev, "Error reading PHYID register: %02x", ret); - goto out2; - } - ret = *((u8 *)buf + 1); -out2: - kfree(buf); -out1: - return ret; -} - -static int asix_sw_reset(struct usbnet *dev, u8 flags) -{ - int ret; - - ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); - if (ret < 0) - devdbg(dev,"Failed to send software reset: %02x", ret); - - return ret; -} - -static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) -{ - int ret; - - ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); - if (ret < 0) - devdbg(dev, "Failed to write RX_CTL mode: %02x", ret); - - return ret; -} - -static void asix_status(struct usbnet *dev, struct urb *urb) +static void ax8817x_status(struct usbnet *dev, struct urb *urb) { struct ax88172_int_data *event; int link; @@ -239,12 +179,12 @@ static void asix_status(struct usbnet *dev, struct urb *urb) usbnet_defer_kevent (dev, EVENT_LINK_RESET ); } else netif_carrier_off(dev->net); - devdbg(dev, "Link Status is: %d", link); + devdbg(dev, "ax8817x - Link Status is: %d", link); } } static void -asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, +ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { struct usb_ctrlrequest *req; @@ -271,7 +211,7 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), (void *)req, data, size, - asix_async_cmd_callback, req); + ax8817x_async_cmd_callback, req); if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { deverr(dev, "Error submitting the control message: status=%d", @@ -281,10 +221,10 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, } } -static void asix_set_multicast(struct net_device *net) +static void ax8817x_set_multicast(struct net_device *net) { struct usbnet *dev = netdev_priv(net); - struct asix_data *data = (struct asix_data *)&dev->data; + struct ax8817x_data *data = (struct ax8817x_data *)&dev->data; u8 rx_ctl = 0x8c; if (net->flags & IFF_PROMISC) { @@ -315,51 +255,53 @@ static void asix_set_multicast(struct net_device *net) mc_list = mc_list->next; } - asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, + ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, AX_MCAST_FILTER_SIZE, data->multi_filter); rx_ctl |= 0x10; } - asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); + ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); } -static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) +static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc) { struct usbnet *dev = netdev_priv(netdev); u16 res; + u8 buf[1]; - asix_set_sw_mii(dev); - asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, + ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); + ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res); - asix_set_hw_mii(dev); + ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); return res & 0xffff; } /* same as above, but converts resulting value to cpu byte order */ -static int asix_mdio_read_le(struct net_device *netdev, int phy_id, int loc) +static int ax8817x_mdio_read_le(struct net_device *netdev, int phy_id, int loc) { - return le16_to_cpu(asix_mdio_read(netdev,phy_id, loc)); + return le16_to_cpu(ax8817x_mdio_read(netdev,phy_id, loc)); } static void -asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) +ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) { struct usbnet *dev = netdev_priv(netdev); u16 res = val; + u8 buf[1]; - asix_set_sw_mii(dev); - asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, + ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); + ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res); - asix_set_hw_mii(dev); + ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); } /* same as above, but converts new value to le16 byte order before writing */ static void -asix_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val) +ax8817x_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val) { - asix_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) ); + ax8817x_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) ); } static int ax88172_link_reset(struct usbnet *dev) @@ -370,23 +312,23 @@ static int ax88172_link_reset(struct usbnet *dev) u8 mode; mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN; - lpa = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); - adv = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); + lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); + adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); res = mii_nway_result(lpa|adv); if (res & LPA_DUPLEX) mode |= AX_MEDIUM_FULL_DUPLEX; - asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); + ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); return 0; } static void -asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) +ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); u8 opt; - if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { + if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { wolinfo->supported = 0; wolinfo->wolopts = 0; return; @@ -402,7 +344,7 @@ asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) } static int -asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) +ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); u8 opt = 0; @@ -415,19 +357,19 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) if (opt != 0) opt |= AX_MONITOR_MODE; - if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, + if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, opt, 0, 0, &buf) < 0) return -EINVAL; return 0; } -static int asix_get_eeprom_len(struct net_device *net) +static int ax8817x_get_eeprom_len(struct net_device *net) { return AX_EEPROM_LEN; } -static int asix_get_eeprom(struct net_device *net, +static int ax8817x_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, u8 *data) { struct usbnet *dev = netdev_priv(net); @@ -444,14 +386,14 @@ static int asix_get_eeprom(struct net_device *net, /* ax8817x returns 2 bytes from eeprom on read */ for (i=0; i < eeprom->len / 2; i++) { - if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, + if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM, eeprom->offset + i, 0, 2, &ebuf[i]) < 0) return -EINVAL; } return 0; } -static void asix_get_drvinfo (struct net_device *net, +static void ax8817x_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { /* Inherit standard device info */ @@ -459,14 +401,14 @@ static void asix_get_drvinfo (struct net_device *net, info->eedump_len = 0x3e; } -static int asix_get_settings(struct net_device *net, struct ethtool_cmd *cmd) +static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd) { struct usbnet *dev = netdev_priv(net); return mii_ethtool_gset(&dev->mii,cmd); } -static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd) +static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd) { struct usbnet *dev = netdev_priv(net); @@ -476,27 +418,27 @@ static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd) /* We need to override some ethtool_ops so we require our own structure so we don't interfere with other usbnet devices that may be connected at the same time. */ -static struct ethtool_ops ax88172_ethtool_ops = { - .get_drvinfo = asix_get_drvinfo, +static struct ethtool_ops ax8817x_ethtool_ops = { + .get_drvinfo = ax8817x_get_drvinfo, .get_link = ethtool_op_get_link, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, - .get_wol = asix_get_wol, - .set_wol = asix_set_wol, - .get_eeprom_len = asix_get_eeprom_len, - .get_eeprom = asix_get_eeprom, - .get_settings = asix_get_settings, - .set_settings = asix_set_settings, + .get_wol = ax8817x_get_wol, + .set_wol = ax8817x_set_wol, + .get_eeprom_len = ax8817x_get_eeprom_len, + .get_eeprom = ax8817x_get_eeprom, + .get_settings = ax8817x_get_settings, + .set_settings = ax8817x_set_settings, }; -static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) +static int ax8817x_ioctl (struct net_device *net, struct ifreq *rq, int cmd) { struct usbnet *dev = netdev_priv(net); return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); } -static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) +static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf) { int ret = 0; void *buf; @@ -513,39 +455,55 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) /* Toggle the GPIOs in a manufacturer/model specific way */ for (i = 2; i >= 0; i--) { - if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, (gpio_bits >> (i * 8)) & 0xff, 0, 0, buf)) < 0) goto out2; msleep(5); } - if ((ret = asix_write_rx_ctl(dev,0x80)) < 0) + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, + 0x80, 0, 0, buf)) < 0) { + dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret); goto out2; + } /* Get the MAC address */ memset(buf, 0, ETH_ALEN); - if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, + if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, 6, buf)) < 0) { dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); goto out2; } memcpy(dev->net->dev_addr, buf, ETH_ALEN); + /* Get the PHY id */ + if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, + 0, 0, 2, buf)) < 0) { + dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret); + goto out2; + } else if (ret < 2) { + /* this should always return 2 bytes */ + dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", + ret); + ret = -EIO; + goto out2; + } + /* Initialize MII structure */ dev->mii.dev = dev->net; - dev->mii.mdio_read = asix_mdio_read; - dev->mii.mdio_write = asix_mdio_write; + dev->mii.mdio_read = ax8817x_mdio_read; + dev->mii.mdio_write = ax8817x_mdio_write; dev->mii.phy_id_mask = 0x3f; dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = asix_get_phyid(dev); - dev->net->do_ioctl = asix_ioctl; + dev->mii.phy_id = *((u8 *)buf + 1); + dev->net->do_ioctl = ax8817x_ioctl; - dev->net->set_multicast_list = asix_set_multicast; - dev->net->ethtool_ops = &ax88172_ethtool_ops; + dev->net->set_multicast_list = ax8817x_set_multicast; + dev->net->ethtool_ops = &ax8817x_ethtool_ops; - asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); - asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, + ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); mii_nway_restart(&dev->mii); @@ -557,16 +515,16 @@ out1: } static struct ethtool_ops ax88772_ethtool_ops = { - .get_drvinfo = asix_get_drvinfo, + .get_drvinfo = ax8817x_get_drvinfo, .get_link = ethtool_op_get_link, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, - .get_wol = asix_get_wol, - .set_wol = asix_set_wol, - .get_eeprom_len = asix_get_eeprom_len, - .get_eeprom = asix_get_eeprom, - .get_settings = asix_get_settings, - .set_settings = asix_set_settings, + .get_wol = ax8817x_get_wol, + .set_wol = ax8817x_set_wol, + .get_eeprom_len = ax8817x_get_eeprom_len, + .get_eeprom = ax8817x_get_eeprom, + .get_settings = ax8817x_get_settings, + .set_settings = ax8817x_set_settings, }; static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) @@ -583,45 +541,62 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) goto out1; } - if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, 0x00B0, 0, 0, buf)) < 0) goto out2; msleep(5); - if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0x0001, 0, 0, buf)) < 0) { dbg("Select PHY #1 failed: %d", ret); goto out2; } - if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD)) < 0) + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD, + 0, 0, buf)) < 0) { + dbg("Failed to power down internal PHY: %d", ret); goto out2; + } msleep(150); - if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0) + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR, + 0, 0, buf)) < 0) { + dbg("Failed to perform software reset: %d", ret); goto out2; + } msleep(150); - if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, + AX_SWRESET_IPRL | AX_SWRESET_PRL, + 0, 0, buf)) < 0) { + dbg("Failed to set Internal/External PHY reset control: %d", + ret); goto out2; + } msleep(150); - if ((ret = asix_write_rx_ctl(dev, 0x00)) < 0) + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, + 0x0000, 0, 0, buf)) < 0) { + dbg("Failed to reset RX_CTL: %d", ret); goto out2; + } /* Get the MAC address */ memset(buf, 0, ETH_ALEN); - if ((ret = asix_read_cmd(dev, AX88772_CMD_READ_NODE_ID, + if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) { dbg("Failed to read MAC address: %d", ret); goto out2; } memcpy(dev->net->dev_addr, buf, ETH_ALEN); - if ((ret = asix_set_sw_mii(dev)) < 0) + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, + 0, 0, 0, buf)) < 0) { + dbg("Enabling software MII failed: %d", ret); goto out2; + } - if (((ret = asix_read_cmd(dev, AX_CMD_READ_MII_REG, + if (((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, 0x0010, 2, 2, buf)) < 0) || (*((u16 *)buf) != 0x003b)) { dbg("Read PHY register 2 must be 0x3b00: %d", ret); @@ -630,49 +605,74 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) /* Initialize MII structure */ dev->mii.dev = dev->net; - dev->mii.mdio_read = asix_mdio_read; - dev->mii.mdio_write = asix_mdio_write; + dev->mii.mdio_read = ax8817x_mdio_read; + dev->mii.mdio_write = ax8817x_mdio_write; dev->mii.phy_id_mask = 0xff; dev->mii.reg_num_mask = 0xff; - dev->net->do_ioctl = asix_ioctl; - dev->mii.phy_id = asix_get_phyid(dev); + dev->net->do_ioctl = ax8817x_ioctl; - if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0) + /* Get the PHY id */ + if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, + 0, 0, 2, buf)) < 0) { + dbg("Error reading PHY ID: %02x", ret); goto out2; + } else if (ret < 2) { + /* this should always return 2 bytes */ + dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", + ret); + ret = -EIO; + goto out2; + } + dev->mii.phy_id = *((u8 *)buf + 1); + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, + 0, 0, buf)) < 0) { + dbg("Set external PHY reset pin level: %d", ret); + goto out2; + } msleep(150); - - if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, + AX_SWRESET_IPRL | AX_SWRESET_PRL, + 0, 0, buf)) < 0) { + dbg("Set Internal/External PHY reset control: %d", ret); goto out2; - + } msleep(150); - dev->net->set_multicast_list = asix_set_multicast; + + dev->net->set_multicast_list = ax8817x_set_multicast; dev->net->ethtool_ops = &ax88772_ethtool_ops; - asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); - asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, + ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA); mii_nway_restart(&dev->mii); - if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) { dbg("Write medium mode register: %d", ret); goto out2; } - if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, AX88772_IPG2_DEFAULT, 0, buf)) < 0) { dbg("Write IPG,IPG1,IPG2 failed: %d", ret); goto out2; } - if ((ret = asix_set_hw_mii(dev)) < 0) + if ((ret = + ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) { + dbg("Failed to set hardware MII: %02x", ret); goto out2; + } /* Set RX_CTL to default values with 2k buffer, and enable cactus */ - if ((ret = asix_write_rx_ctl(dev, 0x0088)) < 0) + if ((ret = + ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0, + buf)) < 0) { + dbg("Reset RX_CTL failed: %d", ret); goto out2; + } kfree(buf); @@ -794,23 +794,23 @@ static int ax88772_link_reset(struct usbnet *dev) u16 mode; mode = AX88772_MEDIUM_DEFAULT; - lpa = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); - adv = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); + lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); + adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); res = mii_nway_result(lpa|adv); if ((res & LPA_DUPLEX) == 0) mode &= ~AX88772_MEDIUM_FULL_DUPLEX; if ((res & LPA_100) == 0) mode &= ~AX88772_MEDIUM_100MB; - asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); + ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); return 0; } static const struct driver_info ax8817x_info = { .description = "ASIX AX8817x USB 2.0 Ethernet", - .bind = ax88172_bind, - .status = asix_status, + .bind = ax8817x_bind, + .status = ax8817x_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, .flags = FLAG_ETHER, @@ -819,8 +819,8 @@ static const struct driver_info ax8817x_info = { static const struct driver_info dlink_dub_e100_info = { .description = "DLink DUB-E100 USB Ethernet", - .bind = ax88172_bind, - .status = asix_status, + .bind = ax8817x_bind, + .status = ax8817x_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, .flags = FLAG_ETHER, @@ -829,8 +829,8 @@ static const struct driver_info dlink_dub_e100_info = { static const struct driver_info netgear_fa120_info = { .description = "Netgear FA-120 USB Ethernet", - .bind = ax88172_bind, - .status = asix_status, + .bind = ax8817x_bind, + .status = ax8817x_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, .flags = FLAG_ETHER, @@ -839,8 +839,8 @@ static const struct driver_info netgear_fa120_info = { static const struct driver_info hawking_uf200_info = { .description = "Hawking UF200 USB Ethernet", - .bind = ax88172_bind, - .status = asix_status, + .bind = ax8817x_bind, + .status = ax8817x_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, .flags = FLAG_ETHER, @@ -850,12 +850,13 @@ static const struct driver_info hawking_uf200_info = { static const struct driver_info ax88772_info = { .description = "ASIX AX88772 USB 2.0 Ethernet", .bind = ax88772_bind, - .status = asix_status, + .status = ax8817x_status, .link_reset = ax88772_link_reset, .reset = ax88772_link_reset, .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88772_rx_fixup, .tx_fixup = ax88772_tx_fixup, + .data = 0x00130103, }; static const struct usb_device_id products [] = { diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 7683926a1..156a2f1cb 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -262,7 +262,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), (char *) &pegasus->dr, - tmp, 1, ctrl_callback, pegasus); + &tmp, 1, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -318,8 +318,6 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) set_register(pegasus, PhyCtrl, (indx | PHY_READ)); for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, PhyCtrl, 1, data); - if (ret == -ESHUTDOWN) - goto fail; if (data[0] & PHY_DONE) break; } @@ -328,7 +326,6 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) *regd = le16_to_cpu(regdi); return ret; } -fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); @@ -357,15 +354,12 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, PhyCtrl, 1, data); - if (ret == -ESHUTDOWN) - goto fail; if (data[0] & PHY_DONE) break; } if (i < REG_TIMEOUT) return ret; -fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -393,8 +387,6 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) ret = get_registers(pegasus, EpromCtrl, 1, &tmp); if (tmp & EPROM_DONE) break; - if (ret == -ESHUTDOWN) - goto fail; } if (i < REG_TIMEOUT) { ret = get_registers(pegasus, EpromData, 2, &retdatai); @@ -402,7 +394,6 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) return ret; } -fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -442,15 +433,12 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, EpromCtrl, 1, &tmp); - if (ret == -ESHUTDOWN) - goto fail; if (tmp & EPROM_DONE) break; } disable_eprom_write(pegasus); if (i < REG_TIMEOUT) return ret; -fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -536,7 +524,6 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) ret = set_registers(pegasus, EthCtrl0, 3, data); if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || - usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 || usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { u16 auxmode; read_mii_word(pegasus, 0, 0x1b, &auxmode); @@ -1390,8 +1377,9 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message) struct pegasus *pegasus = usb_get_intfdata(intf); netif_device_detach (pegasus->net); - cancel_delayed_work(&pegasus->carrier_check); if (netif_running(pegasus->net)) { + cancel_delayed_work(&pegasus->carrier_check); + usb_kill_urb(pegasus->rx_urb); usb_kill_urb(pegasus->intr_urb); } @@ -1411,9 +1399,10 @@ static int pegasus_resume (struct usb_interface *intf) pegasus->intr_urb->status = 0; pegasus->intr_urb->actual_length = 0; intr_callback(pegasus->intr_urb, NULL); + + queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, + CARRIER_CHECK_DELAY); } - queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, - CARRIER_CHECK_DELAY); return 0; } diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h index a54752ce1..9fbd59b55 100644 --- a/drivers/usb/net/pegasus.h +++ b/drivers/usb/net/pegasus.h @@ -25,6 +25,7 @@ #define PHY_READ 0x40 #define PHY_WRITE 0x20 #define DEFAULT_GPIO_RESET 0x24 +#define LINKSYS_GPIO_RESET 0x24 #define DEFAULT_GPIO_SET 0x26 #define PEGASUS_PRESENT 0x00000001 @@ -139,7 +140,6 @@ struct usb_eth_dev { #define VENDOR_KINGSTON 0x0951 #define VENDOR_LANEED 0x056e #define VENDOR_LINKSYS 0x066b -#define VENDOR_LINKSYS2 0x077b #define VENDOR_MELCO 0x0411 #define VENDOR_MICROSOFT 0x045e #define VENDOR_MOBILITY 0x1342 @@ -218,15 +218,15 @@ PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004, PEGASUS_DEV( "Corega FEter USB-TXS", VENDOR_COREGA, 0x000d, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001, - DEFAULT_GPIO_RESET ) + LINKSYS_GPIO_RESET ) PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4002, - DEFAULT_GPIO_RESET ) + LINKSYS_GPIO_RESET ) PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4102, - DEFAULT_GPIO_RESET | PEGASUS_II ) + LINKSYS_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x400b, - DEFAULT_GPIO_RESET | PEGASUS_II ) + LINKSYS_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x200c, - DEFAULT_GPIO_RESET | PEGASUS_II ) + LINKSYS_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003, DEFAULT_GPIO_RESET | HAS_HOME_PNA ) PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1, @@ -260,19 +260,17 @@ PEGASUS_DEV( "LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1, PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x2202, - DEFAULT_GPIO_RESET ) + LINKSYS_GPIO_RESET ) PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2203, - DEFAULT_GPIO_RESET ) + LINKSYS_GPIO_RESET ) PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204, - DEFAULT_GPIO_RESET | HAS_HOME_PNA ) + LINKSYS_GPIO_RESET | HAS_HOME_PNA ) PEGASUS_DEV( "Linksys USB10T Ethernet Adapter", VENDOR_LINKSYS, 0x2206, - DEFAULT_GPIO_RESET | PEGASUS_II) -PEGASUS_DEV( "Linksys USBVPN1", VENDOR_LINKSYS2, 0x08b4, - DEFAULT_GPIO_RESET ) + LINKSYS_GPIO_RESET | PEGASUS_II) PEGASUS_DEV( "Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b, - DEFAULT_GPIO_RESET | PEGASUS_II ) + LINKSYS_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x200c, - DEFAULT_GPIO_RESET | PEGASUS_II ) + LINKSYS_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005, diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index 94ddfe16f..49991ac1b 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c @@ -39,20 +39,6 @@ * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of * course ACM was intended for modems, not Ethernet links! USB's standard * for Ethernet links is "CDC Ethernet", which is significantly simpler. - * - * NOTE that Microsoft's "RNDIS 1.0" specification is incomplete. Issues - * include: - * - Power management in particular relies on information that's scattered - * through other documentation, and which is incomplete or incorrect even - * there. - * - There are various undocumented protocol requirements, such as the - * need to send unused garbage in control-OUT messages. - * - In some cases, MS-Windows will emit undocumented requests; this - * matters more to peripheral implementations than host ones. - * - * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in - * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and - * currently rare) "Ethernet Emulation Model" (EEM). */ /* @@ -86,17 +72,17 @@ struct rndis_msg_hdr { */ #define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */ #define RNDIS_MSG_INIT ccpu2(0x00000002) -#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) #define RNDIS_MSG_HALT ccpu2(0x00000003) #define RNDIS_MSG_QUERY ccpu2(0x00000004) -#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) #define RNDIS_MSG_SET ccpu2(0x00000005) -#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) #define RNDIS_MSG_RESET ccpu2(0x00000006) -#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) #define RNDIS_MSG_INDICATE ccpu2(0x00000007) #define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008) -#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) /* codes for "status" field of completion messages */ #define RNDIS_STATUS_SUCCESS ccpu2(0x00000000) @@ -610,13 +596,13 @@ static struct usb_driver rndis_driver = { static int __init rndis_init(void) { - return usb_register(&rndis_driver); + return usb_register(&rndis_driver); } module_init(rndis_init); static void __exit rndis_exit(void) { - usb_deregister(&rndis_driver); + usb_deregister(&rndis_driver); } module_exit(rndis_exit); diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 1bbbae283..8ca52be23 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -880,6 +880,7 @@ static int rtl8150_probe(struct usb_interface *intf, } fill_skb_pool(dev); set_ethernet_addr(dev); + info("%s: rtl8150 is detected", netdev->name); usb_set_intfdata(intf, dev); SET_NETDEV_DEV(netdev, &intf->dev); @@ -887,9 +888,6 @@ static int rtl8150_probe(struct usb_interface *intf, err("couldn't register the device"); goto out2; } - - info("%s: rtl8150 is detected", netdev->name); - return 0; out2: diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c index f7ac9d6b9..9c5ab2513 100644 --- a/drivers/usb/net/zaurus.c +++ b/drivers/usb/net/zaurus.c @@ -217,7 +217,7 @@ static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf) * with devices that use it and those that don't. */ if ((detail->bDetailData[1] & ~0x02) != 0x01) { - /* bmDataCapabilities == 0 would be fine too, + /* bmDataCapabilites == 0 would be fine too, * but framing is minidriver-coupled for now. */ bad_detail: diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c index 9b1e4ed1d..f3a8e2807 100644 --- a/drivers/usb/net/zd1201.c +++ b/drivers/usb/net/zd1201.c @@ -621,9 +621,10 @@ static int zd1201_drvr_start(struct zd1201 *zd) __le16 zdmax; unsigned char *buffer; - buffer = kzalloc(ZD1201_RXSIZE, GFP_KERNEL); + buffer = kmalloc(ZD1201_RXSIZE, GFP_KERNEL); if (!buffer) return -ENOMEM; + memset(buffer, 0, ZD1201_RXSIZE); usb_fill_bulk_urb(zd->rx_urb, zd->usb, usb_rcvbulkpipe(zd->usb, zd->endp_in), buffer, ZD1201_RXSIZE, @@ -1736,7 +1737,6 @@ static const struct iw_handler_def zd1201_iw_handlers = { .standard = (iw_handler *)zd1201_iw_handler, .private = (iw_handler *)zd1201_private_handler, .private_args = (struct iw_priv_args *) zd1201_private_args, - .get_wireless_stats = zd1201_get_wireless_stats, }; static int zd1201_probe(struct usb_interface *interface, @@ -1750,9 +1750,11 @@ static int zd1201_probe(struct usb_interface *interface, usb = interface_to_usbdev(interface); - zd = kzalloc(sizeof(struct zd1201), GFP_KERNEL); - if (!zd) + zd = kmalloc(sizeof(struct zd1201), GFP_KERNEL); + if (!zd) { return -ENOMEM; + } + memset(zd, 0, sizeof(struct zd1201)); zd->ap = ap; zd->usb = usb; zd->removed = 0; @@ -1797,6 +1799,7 @@ static int zd1201_probe(struct usb_interface *interface, zd->dev->open = zd1201_net_open; zd->dev->stop = zd1201_net_stop; zd->dev->get_stats = zd1201_get_stats; + zd->dev->get_wireless_stats = zd1201_get_wireless_stats; zd->dev->wireless_handlers = (struct iw_handler_def *)&zd1201_iw_handlers; zd->dev->hard_start_xmit = zd1201_hard_start_xmit; diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 5c60be521..be5dc8083 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -71,16 +71,6 @@ config USB_SERIAL_ANYDATA To compile this driver as a module, choose M here: the module will be called anydata. -config USB_SERIAL_ARK3116 - tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL - help - Say Y here if you want to use a ARK Micro 3116 USB to Serial - device. - - To compile this driver as a module, choose M here: the - module will be called ark3116 - config USB_SERIAL_BELKIN tristate "USB Belkin and Peracom Single Port Serial Driver" depends on USB_SERIAL @@ -168,15 +158,6 @@ config USB_SERIAL_FTDI_SIO To compile this driver as a module, choose M here: the module will be called ftdi_sio. -config USB_SERIAL_FUNSOFT - tristate "USB Fundamental Software Dongle Driver" - depends on USB_SERIAL - ---help--- - Say Y here if you want to use the Fundamental Software dongle. - - To compile this driver as a module, choose M here: the - module will be called funsoft. - config USB_SERIAL_VISOR tristate "USB Handspring Visor / Palm m50x / Sony Clie Driver" depends on USB_SERIAL @@ -422,13 +403,6 @@ config USB_SERIAL_MCT_U232 To compile this driver as a module, choose M here: the module will be called mct_u232. -config USB_SERIAL_NAVMAN - tristate "USB Navman GPS device" - depends on USB_SERIAL - help - To compile this driver as a module, choose M here: the - module will be called navman. - config USB_SERIAL_PL2303 tristate "USB Prolific 2303 Single Port Serial Driver" depends on USB_SERIAL diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 5a0960fc9..f0b04420c 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -13,7 +13,6 @@ usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o -obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o @@ -23,7 +22,6 @@ obj-$(CONFIG_USB_SERIAL_EDGEPORT) += io_edgeport.o obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o obj-$(CONFIG_USB_SERIAL_EMPEG) += empeg.o obj-$(CONFIG_USB_SERIAL_FTDI_SIO) += ftdi_sio.o -obj-$(CONFIG_USB_SERIAL_FUNSOFT) += funsoft.o obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o @@ -34,7 +32,6 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o -obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o obj-$(CONFIG_USB_SERIAL_OPTION) += option.o obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 694b205f9..dbf1f0630 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -18,7 +18,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0xf3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */ { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ - { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c deleted file mode 100644 index 8dec79622..000000000 --- a/drivers/usb/serial/ark3116.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * ark3116 - * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547, - * productid=0x0232) (used in a datacable called KQ-U8A) - * - * - based on code by krisfx -> thanks !! - * (see http://www.linuxquestions.org/questions/showthread.php?p=2184457#post2184457) - * - * - based on logs created by usbsnoopy - * - * Author : Simon Schulz [ark3116_driverauctionant.de] - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include "usb-serial.h" - - -static int debug; - -static struct usb_device_id id_table [] = { - { USB_DEVICE(0x6547, 0x0232) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -struct ark3116_private { - spinlock_t lock; - u8 termios_initialized; -}; - -static inline void ARK3116_SND(struct usb_serial *serial, int seq, - __u8 request, __u8 requesttype, - __u16 value, __u16 index) -{ - int result; - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev,0), - request, requesttype, value, index, - NULL,0x00, 1000); - dbg("%03d > ok",seq); -} - -static inline void ARK3116_RCV(struct usb_serial *serial, int seq, - __u8 request, __u8 requesttype, - __u16 value, __u16 index, __u8 expected, - char *buf) -{ - int result; - result = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev,0), - request, requesttype, value, index, - buf, 0x0000001, 1000); - if (result) - dbg("%03d < %d bytes [0x%02X]",seq, result, buf[0]); - else - dbg("%03d < 0 bytes", seq); -} - - -static inline void ARK3116_RCV_QUIET(struct usb_serial *serial, - __u8 request, __u8 requesttype, - __u16 value, __u16 index, char *buf) -{ - usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev,0), - request, requesttype, value, index, - buf, 0x0000001, 1000); -} - - -static int ark3116_attach(struct usb_serial *serial) -{ - char *buf; - struct ark3116_private *priv; - int i; - - for (i = 0; i < serial->num_ports; ++i) { - priv = kmalloc (sizeof (struct ark3116_private), GFP_KERNEL); - if (!priv) - goto cleanup; - memset (priv, 0x00, sizeof (struct ark3116_private)); - spin_lock_init(&priv->lock); - - usb_set_serial_port_data(serial->port[i], priv); - } - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) { - dbg("error kmalloc -> out of mem ?"); - goto cleanup; - } - - /* 3 */ - ARK3116_SND(serial, 3,0xFE,0x40,0x0008,0x0002); - ARK3116_SND(serial, 4,0xFE,0x40,0x0008,0x0001); - ARK3116_SND(serial, 5,0xFE,0x40,0x0000,0x0008); - ARK3116_SND(serial, 6,0xFE,0x40,0x0000,0x000B); - - /* <-- seq7 */ - ARK3116_RCV(serial, 7,0xFE,0xC0,0x0000,0x0003, 0x00, buf); - ARK3116_SND(serial, 8,0xFE,0x40,0x0080,0x0003); - ARK3116_SND(serial, 9,0xFE,0x40,0x001A,0x0000); - ARK3116_SND(serial,10,0xFE,0x40,0x0000,0x0001); - ARK3116_SND(serial,11,0xFE,0x40,0x0000,0x0003); - - /* <-- seq12 */ - ARK3116_RCV(serial,12,0xFE,0xC0,0x0000,0x0004, 0x00, buf); - ARK3116_SND(serial,13,0xFE,0x40,0x0000,0x0004); - - /* 14 */ - ARK3116_RCV(serial,14,0xFE,0xC0,0x0000,0x0004, 0x00, buf); - ARK3116_SND(serial,15,0xFE,0x40,0x0000,0x0004); - - /* 16 */ - ARK3116_RCV(serial,16,0xFE,0xC0,0x0000,0x0004, 0x00, buf); - /* --> seq17 */ - ARK3116_SND(serial,17,0xFE,0x40,0x0001,0x0004); - - /* <-- seq18 */ - ARK3116_RCV(serial,18,0xFE,0xC0,0x0000,0x0004, 0x01, buf); - - /* --> seq19 */ - ARK3116_SND(serial,19,0xFE,0x40,0x0003,0x0004); - - - /* <-- seq20 */ - /* seems like serial port status info (RTS, CTS,...) */ - /* returns modem control line status ?! */ - ARK3116_RCV(serial,20,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); - - /* set 9600 baud & do some init ?! */ - ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); - ARK3116_SND(serial,148,0xFE,0x40,0x0038,0x0000); - ARK3116_SND(serial,149,0xFE,0x40,0x0001,0x0001); - ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); - ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); - ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); - ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); - ARK3116_SND(serial,154,0xFE,0x40,0x0003,0x0003); - - kfree(buf); - return(0); - -cleanup: - for (--i; i>=0; --i) - usb_set_serial_port_data(serial->port[i], NULL); - return -ENOMEM; -} - -static void ark3116_set_termios(struct usb_serial_port *port, - struct termios *old_termios) -{ - struct usb_serial *serial = port->serial; - struct ark3116_private *priv = usb_get_serial_port_data(port); - unsigned int cflag = port->tty->termios->c_cflag; - unsigned long flags; - int baud; - int ark3116_baud; - char *buf; - char config; - - config = 0; - - dbg("%s - port %d", __FUNCTION__, port->number); - - if ((!port->tty) || (!port->tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - if (!priv->termios_initialized) { - *(port->tty->termios) = tty_std_termios; - port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - priv->termios_initialized = 1; - } - spin_unlock_irqrestore(&priv->lock, flags); - - cflag = port->tty->termios->c_cflag; - - /* check that they really want us to change something: */ - if (old_termios) { - if ((cflag == old_termios->c_cflag) && - (RELEVANT_IFLAG(port->tty->termios->c_iflag) == - RELEVANT_IFLAG(old_termios->c_iflag))) { - dbg("%s - nothing to change...", __FUNCTION__); - return; - } - } - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) { - dbg("error kmalloc"); - return; - } - - /* set data bit count (8/7/6/5) */ - if (cflag & CSIZE){ - switch (cflag & CSIZE){ - case CS5: - config |= 0x00; - dbg("setting CS5"); - break; - case CS6: - config |= 0x01; - dbg("setting CS6"); - break; - case CS7: - config |= 0x02; - dbg("setting CS7"); - break; - default: - err ("CSIZE was set but not CS5-CS8, using CS8!"); - case CS8: - config |= 0x03; - dbg("setting CS8"); - break; - } - } - - /* set parity (NONE,EVEN,ODD) */ - if (cflag & PARENB){ - if (cflag & PARODD) { - config |= 0x08; - dbg("setting parity to ODD"); - } else { - config |= 0x18; - dbg("setting parity to EVEN"); - } - } else { - dbg("setting parity to NONE"); - } - - /* SET STOPBIT (1/2) */ - if (cflag & CSTOPB) { - config |= 0x04; - dbg ("setting 2 stop bits"); - } else { - dbg ("setting 1 stop bit"); - } - - - /* set baudrate: */ - baud = 0; - switch (cflag & CBAUD){ - case B0: - err("can't set 0baud, using 9600 instead"); - break; - case B75: baud = 75; break; - case B150: baud = 150; break; - case B300: baud = 300; break; - case B600: baud = 600; break; - case B1200: baud = 1200; break; - case B1800: baud = 1800; break; - case B2400: baud = 2400; break; - case B4800: baud = 4800; break; - case B9600: baud = 9600; break; - case B19200: baud = 19200; break; - case B38400: baud = 38400; break; - case B57600: baud = 57600; break; - case B115200: baud = 115200; break; - case B230400: baud = 230400; break; - case B460800: baud = 460800; break; - default: - dbg("does not support the baudrate requested (fix it)"); - break; - } - - /* set 9600 as default (if given baudrate is invalid for example) */ - if (baud == 0) - baud = 9600; - - /* - * found by try'n'error, be careful, maybe there are other options - * for multiplicator etc! - */ - if (baud == 460800) - /* strange, for 460800 the formula is wrong - * (dont use round(), then 9600baud is wrong) */ - ark3116_baud = 7; - else - ark3116_baud = 3000000 / baud; - - /* ? */ - ARK3116_RCV(serial,0,0xFE,0xC0,0x0000,0x0003, 0x03, buf); - /* offset = buf[0]; */ - /* offset = 0x03; */ - /* dbg("using 0x%04X as target for 0x0003:",0x0080+offset); */ - - - /* set baudrate */ - dbg("setting baudrate to %d (->reg=%d)",baud,ark3116_baud); - ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); - ARK3116_SND(serial,148,0xFE,0x40,(ark3116_baud & 0x00FF) ,0x0000); - ARK3116_SND(serial,149,0xFE,0x40,(ark3116_baud & 0xFF00)>>8,0x0001); - ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); - - /* ? */ - ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); - ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); - - /* set data bit count, stop bit count & parity: */ - dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config); - ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); - ARK3116_SND(serial,154,0xFE,0x40,config,0x0003); - - if (cflag & CRTSCTS) - dbg("CRTSCTS not supported by chipset ?!"); - - /* TEST ARK3116_SND(154,0xFE,0x40,0xFFFF, 0x0006); */ - - kfree(buf); - return; -} - -static int ark3116_open(struct usb_serial_port *port, struct file *filp) -{ - struct termios tmp_termios; - struct usb_serial *serial = port->serial; - char *buf; - int result = 0; - - dbg("%s - port %d", __FUNCTION__, port->number); - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) { - dbg("error kmalloc -> out of mem ?"); - return -ENOMEM; - } - - result = usb_serial_generic_open(port, filp); - if (result) - return result; - - /* open */ - ARK3116_RCV(serial,111,0xFE,0xC0,0x0000,0x0003, 0x02, buf); - - ARK3116_SND(serial,112,0xFE,0x40,0x0082,0x0003); - ARK3116_SND(serial,113,0xFE,0x40,0x001A,0x0000); - ARK3116_SND(serial,114,0xFE,0x40,0x0000,0x0001); - ARK3116_SND(serial,115,0xFE,0x40,0x0002,0x0003); - - ARK3116_RCV(serial,116,0xFE,0xC0,0x0000,0x0004, 0x03, buf); - ARK3116_SND(serial,117,0xFE,0x40,0x0002,0x0004); - - ARK3116_RCV(serial,118,0xFE,0xC0,0x0000,0x0004, 0x02, buf); - ARK3116_SND(serial,119,0xFE,0x40,0x0000,0x0004); - - ARK3116_RCV(serial,120,0xFE,0xC0,0x0000,0x0004, 0x00, buf); - - ARK3116_SND(serial,121,0xFE,0x40,0x0001,0x0004); - - ARK3116_RCV(serial,122,0xFE,0xC0,0x0000,0x0004, 0x01, buf); - - ARK3116_SND(serial,123,0xFE,0x40,0x0003,0x0004); - - /* returns different values (control lines ?!) */ - ARK3116_RCV(serial,124,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); - - /* initialise termios: */ - if (port->tty) - ark3116_set_termios(port, &tmp_termios); - - kfree(buf); - - return result; - -} - -static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg) -{ - dbg("ioctl not supported yet..."); - return -ENOIOCTLCMD; -} - -static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file) -{ - struct usb_serial *serial = port->serial; - char *buf; - char temp; - - /* seems like serial port status info (RTS, CTS,...) is stored - * in reg(?) 0x0006 - * pcb connection point 11 = GND -> sets bit4 of response - * pcb connection point 7 = GND -> sets bit6 of response - */ - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) { - dbg("error kmalloc"); - return -ENOMEM; - } - - /* read register: */ - ARK3116_RCV_QUIET(serial,0xFE,0xC0,0x0000,0x0006,buf); - temp = buf[0]; - kfree(buf); - - /* i do not really know if bit4=CTS and bit6=DSR... was just a - * quick guess !! - */ - return (temp & (1<<4) ? TIOCM_CTS : 0) | - (temp & (1<<6) ? TIOCM_DSR : 0); -} - -static struct usb_driver ark3116_driver = { - .name = "ark3116", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver ark3116_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ark3116", - }, - .id_table = id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, - .num_ports = 1, - .attach = ark3116_attach, - .set_termios = ark3116_set_termios, - .ioctl = ark3116_ioctl, - .tiocmget = ark3116_tiocmget, - .open = ark3116_open, -}; - -static int __init ark3116_init(void) -{ - int retval; - - retval = usb_serial_register(&ark3116_device); - if (retval) - return retval; - retval = usb_register(&ark3116_driver); - if (retval) - usb_serial_deregister(&ark3116_device); - return retval; -} - -static void __exit ark3116_exit(void) -{ - usb_deregister(&ark3116_driver); - usb_serial_deregister(&ark3116_device); -} - -module_init(ark3116_init); -module_exit(ark3116_exit); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index e0c2acdb3..dc7a06950 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -32,7 +32,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.07" +#define DRIVER_VERSION "v0.06" #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" /* @@ -58,7 +58,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ - { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ @@ -170,7 +169,9 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request, /* Number of integers required to contain the array */ length = (((size - 1) | 3) + 1)/4; - buf = kcalloc(length, sizeof(u32), GFP_KERNEL); + buf = kmalloc (length * sizeof(u32), GFP_KERNEL); + memset(buf, 0, length * sizeof(u32)); + if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); return -ENOMEM; diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 7212fbe3b..68067fe11 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -98,16 +98,10 @@ static struct usb_device_id id_table_cyphidcomrs232 [] = { { } /* Terminating entry */ }; -static struct usb_device_id id_table_nokiaca42v2 [] = { - { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, - { } /* Terminating entry */ -}; - static struct usb_device_id id_table_combined [] = { { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, - { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, { } /* Terminating entry */ }; @@ -155,7 +149,6 @@ struct cypress_buf { /* function prototypes for the Cypress USB to serial device */ static int cypress_earthmate_startup (struct usb_serial *serial); static int cypress_hidcom_startup (struct usb_serial *serial); -static int cypress_ca42v2_startup (struct usb_serial *serial); static void cypress_shutdown (struct usb_serial *serial); static int cypress_open (struct usb_serial_port *port, struct file *filp); static void cypress_close (struct usb_serial_port *port, struct file *filp); @@ -242,34 +235,6 @@ static struct usb_serial_driver cypress_hidcom_device = { .write_int_callback = cypress_write_int_callback, }; -static struct usb_serial_driver cypress_ca42v2_device = { - .driver = { - .owner = THIS_MODULE, - .name = "nokiaca42v2", - }, - .description = "Nokia CA-42 V2 Adapter", - .id_table = id_table_nokiaca42v2, - .num_interrupt_in = 1, - .num_interrupt_out = 1, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, - .num_ports = 1, - .attach = cypress_ca42v2_startup, - .shutdown = cypress_shutdown, - .open = cypress_open, - .close = cypress_close, - .write = cypress_write, - .write_room = cypress_write_room, - .ioctl = cypress_ioctl, - .set_termios = cypress_set_termios, - .tiocmget = cypress_tiocmget, - .tiocmset = cypress_tiocmset, - .chars_in_buffer = cypress_chars_in_buffer, - .throttle = cypress_throttle, - .unthrottle = cypress_unthrottle, - .read_int_callback = cypress_read_int_callback, - .write_int_callback = cypress_write_int_callback, -}; /***************************************************************************** * Cypress serial helper functions @@ -321,12 +286,6 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m __FUNCTION__); new_baudrate = priv->baud_rate; } - } else if (priv->chiptype == CT_CA42V2) { - if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { - err("%s - failed setting baud rate, unsupported speed", - __FUNCTION__); - new_baudrate = priv->baud_rate; - } } else if (priv->chiptype == CT_GENERIC) { if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { err("%s - failed setting baud rate, unsupported speed", @@ -476,10 +435,11 @@ static int generic_startup (struct usb_serial *serial) dbg("%s - port %d", __FUNCTION__, serial->port[0]->number); - priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL); + priv = kmalloc(sizeof (struct cypress_private), GFP_KERNEL); if (!priv) return -ENOMEM; + memset(priv, 0x00, sizeof (struct cypress_private)); spin_lock_init(&priv->lock); priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE); if (priv->buf == NULL) { @@ -540,25 +500,6 @@ static int cypress_hidcom_startup (struct usb_serial *serial) } /* cypress_hidcom_startup */ -static int cypress_ca42v2_startup (struct usb_serial *serial) -{ - struct cypress_private *priv; - - dbg("%s", __FUNCTION__); - - if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __FUNCTION__, - serial->port[0]->number); - return 1; - } - - priv = usb_get_serial_port_data(serial->port[0]); - priv->chiptype = CT_CA42V2; - - return 0; -} /* cypress_ca42v2_startup */ - - static void cypress_shutdown (struct usb_serial *serial) { struct cypress_private *priv; @@ -1003,10 +944,6 @@ static void cypress_set_termios (struct usb_serial_port *port, *(tty->termios) = tty_std_termios; tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - } else if (priv->chiptype == CT_CA42V2) { - *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | - CLOCAL; } priv->termios_initialized = 1; } @@ -1605,9 +1542,6 @@ static int __init cypress_init(void) retval = usb_serial_register(&cypress_hidcom_device); if (retval) goto failed_hidcom_register; - retval = usb_serial_register(&cypress_ca42v2_device); - if (retval) - goto failed_ca42v2_register; retval = usb_register(&cypress_driver); if (retval) goto failed_usb_register; @@ -1616,8 +1550,6 @@ static int __init cypress_init(void) return 0; failed_usb_register: usb_deregister(&cypress_driver); -failed_ca42v2_register: - usb_serial_deregister(&cypress_ca42v2_device); failed_hidcom_register: usb_serial_deregister(&cypress_hidcom_device); failed_em_register: @@ -1634,7 +1566,6 @@ static void __exit cypress_exit (void) usb_deregister (&cypress_driver); usb_serial_deregister (&cypress_earthmate_device); usb_serial_deregister (&cypress_hidcom_device); - usb_serial_deregister (&cypress_ca42v2_device); } diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h index e1c7c27e1..1fa119efe 100644 --- a/drivers/usb/serial/cypress_m8.h +++ b/drivers/usb/serial/cypress_m8.h @@ -18,10 +18,6 @@ /* Cypress HID->COM RS232 Adapter */ #define VENDOR_ID_CYPRESS 0x04b4 #define PRODUCT_ID_CYPHIDCOM 0x5500 - -/* Nokia CA-42 USB to serial cable */ -#define VENDOR_ID_DAZZLE 0x07d0 -#define PRODUCT_ID_CA42 0x4101 /* End of device listing */ /* Used for setting / requesting serial line settings */ @@ -38,7 +34,6 @@ #define CT_EARTHMATE 0x01 #define CT_CYPHIDCOM 0x02 -#define CT_CA42V2 0x03 #define CT_GENERIC 0x0F /* End of chiptype definitions */ diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ad9ddecf1..b64b9d354 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -307,9 +307,7 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { static struct usb_device_id id_table_combined [] = { - { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, @@ -491,15 +489,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_ECLO_COM_1WIRE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, - { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -1156,11 +1148,12 @@ static int ftdi_sio_attach (struct usb_serial *serial) dbg("%s",__FUNCTION__); - priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); + priv = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL); if (!priv){ err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct ftdi_private)); return -ENOMEM; } + memset(priv, 0, sizeof(*priv)); spin_lock_init(&priv->rx_lock); spin_lock_init(&priv->tx_lock); diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index d69a917e7..bdef3b8c7 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -32,10 +32,6 @@ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ -/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ -#define FTDI_ACTZWAVE_PID 0xF2D0 - - /* www.irtrans.de device */ #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ @@ -43,9 +39,6 @@ /* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ #define FTDI_TTUSB_PID 0xFF20 /* Product Id */ -/* iPlus device */ -#define FTDI_IPLUS_PID 0xD070 /* Product Id */ - /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ /* they use the ftdi chipset for the USB interface and the vendor id is the same */ #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ @@ -152,18 +145,6 @@ #define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ #define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ -/* - * Icom ID-1 digital transceiver - */ - -#define ICOM_ID1_VID 0x0C26 -#define ICOM_ID1_PID 0x0004 - -/* - * ASK.fr devices - */ -#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ - /* * DSS-20 Sync Station for Sony Ericsson P800 */ @@ -411,31 +392,6 @@ #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ -/* - * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) - */ -#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ - -/* - * Eclo (http://www.eclo.pt/) product IDs. - * PID 0xEA90 submitted by Martin Grill. - */ -#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ - -/* - * Papouch products (http://www.papouch.com/) - * Submitted by Folkert van Heusden - */ - -#define PAPOUCH_VID 0x5050 /* Vendor ID */ -#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ - -/* - * ACG Identification Technologies GmbH products (http://www.acg.de/). - * Submitted by anton -at- goto10 -dot- org. - */ -#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ - /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c deleted file mode 100644 index 803721b97..000000000 --- a/drivers/usb/serial/funsoft.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Funsoft Serial USB driver - * - * Copyright (C) 2006 Greg Kroah-Hartman - * - * 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 -#include -#include -#include -#include -#include "usb-serial.h" - -static struct usb_device_id id_table [] = { - { USB_DEVICE(0x1404, 0xcddc) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver funsoft_driver = { - .name = "funsoft", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .no_dynamic_id = 1, -}; - -static struct usb_serial_driver funsoft_device = { - .driver = { - .owner = THIS_MODULE, - .name = "funsoft", - }, - .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, - .num_ports = 1, -}; - -static int __init funsoft_init(void) -{ - int retval; - - retval = usb_serial_register(&funsoft_device); - if (retval) - return retval; - retval = usb_register(&funsoft_driver); - if (retval) - usb_serial_deregister(&funsoft_device); - return retval; -} - -static void __exit funsoft_exit(void) -{ - usb_deregister(&funsoft_driver); - usb_serial_deregister(&funsoft_device); -} - -module_init(funsoft_init); -module_exit(funsoft_exit); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 5ec9bf5ba..d6f55e9dc 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1422,11 +1422,12 @@ static int garmin_attach (struct usb_serial *serial) dbg("%s", __FUNCTION__); - garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); + garmin_data_p = kmalloc (sizeof(struct garmin_data), GFP_KERNEL); if (garmin_data_p == NULL) { dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__); return -ENOMEM; } + memset (garmin_data_p, 0, sizeof(struct garmin_data)); init_timer(&garmin_data_p->timer); spin_lock_init(&garmin_data_p->lock); INIT_LIST_HEAD(&garmin_data_p->pktlist); diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index c62cc2876..476cda107 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -138,7 +138,6 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) return result; } -EXPORT_SYMBOL_GPL(usb_serial_generic_open); static void generic_cleanup (struct usb_serial_port *port) { diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index b606c5968..3f29e6b0f 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2725,11 +2725,12 @@ static int edge_startup (struct usb_serial *serial) dev = serial->dev; /* create our private serial structure */ - edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); + edge_serial = kmalloc (sizeof(struct edgeport_serial), GFP_KERNEL); if (edge_serial == NULL) { dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); return -ENOMEM; } + memset (edge_serial, 0, sizeof(struct edgeport_serial)); spin_lock_init(&edge_serial->es_lock); edge_serial->serial = serial; usb_set_serial_data(serial, edge_serial); diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 8e1e22537..afc0f34b3 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2727,11 +2727,12 @@ static int edge_startup (struct usb_serial *serial) dev = serial->dev; /* create our private serial structure */ - edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); + edge_serial = kmalloc (sizeof(struct edgeport_serial), GFP_KERNEL); if (edge_serial == NULL) { dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); return -ENOMEM; } + memset (edge_serial, 0, sizeof(struct edgeport_serial)); sema_init(&edge_serial->es_sem, 1); edge_serial->serial = serial; usb_set_serial_data(serial, edge_serial); @@ -2744,11 +2745,12 @@ static int edge_startup (struct usb_serial *serial) /* set up our port private structures */ for (i = 0; i < serial->num_ports; ++i) { - edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); + edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL); if (edge_port == NULL) { dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); goto cleanup; } + memset (edge_port, 0, sizeof(struct edgeport_port)); spin_lock_init(&edge_port->ep_lock); edge_port->ep_out_buf = edge_buf_alloc(EDGE_OUT_BUF_SIZE); if (edge_port->ep_out_buf == NULL) { diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 426182ddc..a59010421 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -184,9 +184,10 @@ static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, struct irda_class_desc *desc; int ret; - desc = kzalloc(sizeof (struct irda_class_desc), GFP_KERNEL); + desc = kmalloc(sizeof (struct irda_class_desc), GFP_KERNEL); if (desc == NULL) return NULL; + memset(desc, 0, sizeof(struct irda_class_desc)); ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0), IU_REQ_GET_CLASS_DESC, diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 052b735c4..3b958e60f 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -2250,11 +2250,12 @@ static int keyspan_startup (struct usb_serial *serial) } /* Setup private data for serial driver */ - s_priv = kzalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL); + s_priv = kmalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL); if (!s_priv) { dbg("%s - kmalloc for keyspan_serial_private failed.", __FUNCTION__); return -ENOMEM; } + memset(s_priv, 0, sizeof(struct keyspan_serial_private)); s_priv->device_details = d_details; usb_set_serial_data(serial, s_priv); @@ -2262,11 +2263,12 @@ static int keyspan_startup (struct usb_serial *serial) /* Now setup per port private data */ for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; - p_priv = kzalloc(sizeof(struct keyspan_port_private), GFP_KERNEL); + p_priv = kmalloc(sizeof(struct keyspan_port_private), GFP_KERNEL); if (!p_priv) { dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __FUNCTION__, i); return (1); } + memset(p_priv, 0, sizeof(struct keyspan_port_private)); p_priv->device_details = d_details; usb_set_serial_port_data(port, p_priv); } diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 87dfcd89f..b8b213185 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -255,9 +255,11 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) } // allocate memory for transfer buffer - transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); + transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL); if (! transfer_buffer) { return -ENOMEM; + } else { + memset(transfer_buffer, 0, transfer_buffer_length); } // allocate write_urb @@ -381,10 +383,11 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) // BEGIN DEBUG /* - dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); + dbg_data = (unsigned char *) kmalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); if (! dbg_data) { return; } + memset(dbg_data, 0, (3 * purb->actual_length + 10)); for (i = 0; i < purb->actual_length; i++) { sprintf(dbg_data +3*i, "%02X ", data[i]); } @@ -515,10 +518,11 @@ static int kobil_tiocmget(struct usb_serial_port *port, struct file *file) } // allocate memory for transfer buffer - transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); + transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL); if (!transfer_buffer) { return -ENOMEM; } + memset(transfer_buffer, 0, transfer_buffer_length); result = usb_control_msg( port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0 ), @@ -560,10 +564,11 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, } // allocate memory for transfer buffer - transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); + transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL); if (! transfer_buffer) { return -ENOMEM; } + memset(transfer_buffer, 0, transfer_buffer_length); if (set & TIOCM_RTS) rts = 1; @@ -650,10 +655,11 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, (struct termios __user *)arg)) return -EFAULT; - settings = kzalloc(50, GFP_KERNEL); + settings = (unsigned char *) kmalloc(50, GFP_KERNEL); if (! settings) { return -ENOBUFS; } + memset(settings, 0, 50); switch (priv->internal_termios.c_cflag & CBAUD) { case B1200: diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 35bd29b6c..b6d6cab9c 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -348,9 +348,10 @@ static int mct_u232_startup (struct usb_serial *serial) struct mct_u232_private *priv; struct usb_serial_port *port, *rport; - priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); + priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL); if (!priv) return -ENOMEM; + memset(priv, 0, sizeof(struct mct_u232_private)); spin_lock_init(&priv->lock); usb_set_serial_port_data(serial->port[0], priv); diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c deleted file mode 100644 index 7f5440810..000000000 --- a/drivers/usb/serial/navman.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Navman Serial USB driver - * - * Copyright (C) 2006 Greg Kroah-Hartman - * - * 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 -#include -#include -#include -#include -#include -#include "usb-serial.h" - -static int debug; - -static struct usb_device_id id_table [] = { - { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver navman_driver = { - .name = "navman", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .no_dynamic_id = 1, -}; - -static void navman_read_int_callback(struct urb *urb, struct pt_regs *regs) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - struct tty_struct *tty; - int result; - - 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", - __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __FUNCTION__, urb->status); - goto exit; - } - - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, - urb->actual_length, data); - - tty = port->tty; - if (tty && urb->actual_length) { - tty_buffer_request_room(tty, urb->actual_length); - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - -exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - Error %d submitting interrupt urb\n", - __FUNCTION__, result); -} - -static int navman_open(struct usb_serial_port *port, struct file *filp) -{ - int result = 0; - - dbg("%s - port %d", __FUNCTION__, port->number); - - if (port->interrupt_in_urb) { - dbg("%s - adding interrupt input for treo", __FUNCTION__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result) - dev_err(&port->dev, - "%s - failed submitting interrupt urb, error %d\n", - __FUNCTION__, result); - } - return result; -} - -static void navman_close(struct usb_serial_port *port, struct file *filp) -{ - dbg("%s - port %d", __FUNCTION__, port->number); - - if (port->interrupt_in_urb) - usb_kill_urb(port->interrupt_in_urb); -} - -static int navman_write(struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - dbg("%s - port %d", __FUNCTION__, port->number); - - /* - * This device can't write any data, only read from the device - * so we just silently eat all data sent to us and say it was - * successfully sent. - * Evil, I know, but do you have a better idea? - */ - - return count; -} - -static struct usb_serial_driver navman_device = { - .driver = { - .owner = THIS_MODULE, - .name = "navman", - }, - .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, - .num_ports = 1, - .open = navman_open, - .close = navman_close, - .write = navman_write, - .read_int_callback = navman_read_int_callback, -}; - -static int __init navman_init(void) -{ - int retval; - - retval = usb_serial_register(&navman_device); - if (retval) - return retval; - retval = usb_register(&navman_driver); - if (retval) - usb_serial_deregister(&navman_device); - return retval; -} - -static void __exit navman_exit(void) -{ - usb_deregister(&navman_driver); - usb_serial_deregister(&navman_device); -} - -module_init(navman_init); -module_exit(navman_exit); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 238033a87..762d8ff9a 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -204,7 +204,7 @@ static void omninet_read_bulk_callback (struct urb *urb, struct pt_regs *regs) int i; int result; - dbg("%s - port %d", __FUNCTION__, port->number); +// dbg("omninet_read_bulk_callback"); if (urb->status) { dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); @@ -250,21 +250,21 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf int result; - dbg("%s - port %d", __FUNCTION__, port->number); +// dbg("omninet_write port %d", port->number); if (count == 0) { dbg("%s - write request of 0 bytes", __FUNCTION__); return (0); } - spin_lock(&wport->lock); - if (wport->write_urb_busy) { - spin_unlock(&wport->lock); + spin_lock(&port->lock); + if (port->write_urb_busy) { + spin_unlock(&port->lock); dbg("%s - already writing", __FUNCTION__); return 0; } - wport->write_urb_busy = 1; - spin_unlock(&wport->lock); + port->write_urb_busy = 1; + spin_unlock(&port->lock); count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; @@ -283,7 +283,7 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf wport->write_urb->dev = serial->dev; result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); if (result) { - wport->write_urb_busy = 0; + port->write_urb_busy = 0; err("%s - failed submitting write urb, error %d", __FUNCTION__, result); } else result = count; @@ -302,7 +302,7 @@ static int omninet_write_room (struct usb_serial_port *port) if (wport->write_urb_busy) room = wport->bulk_out_size - OMNINET_HEADERLEN; - dbg("%s - returns %d", __FUNCTION__, room); +// dbg("omninet_write_room returns %d", room); return (room); } @@ -312,7 +312,7 @@ static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs) /* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */ struct usb_serial_port *port = (struct usb_serial_port *) urb->context; - dbg("%s - port %0x\n", __FUNCTION__, port->number); +// dbg("omninet_write_bulk_callback, port %0x\n", port); port->write_urb_busy = 0; if (urb->status) { @@ -321,6 +321,8 @@ static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs) } schedule_work(&port->work); + +// dbg("omninet_write_bulk_callback, tty %0x\n", tty); } diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5cf2b80ad..fd8a50e08 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -28,7 +28,6 @@ 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes wants to send >2000 bytes. - 2006-04-10 v0.4.2 fixed two array overrun errors :-/ Work sponsored by: Sigos GmbH, Germany @@ -103,7 +102,7 @@ static struct usb_driver option_driver = { .no_dynamic_id = 1, }; -/* The card has three separate interfaces, which the serial driver +/* The card has three separate interfaces, wich the serial driver * recognizes separately, thus num_port=1. */ static struct usb_serial_driver option_3port_device = { @@ -632,12 +631,13 @@ static int option_startup(struct usb_serial *serial) /* Now setup per port private data */ for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); + portdata = kmalloc(sizeof(*portdata), GFP_KERNEL); if (!portdata) { dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i); return (1); } + memset(portdata, 0, sizeof(struct option_port_private)); usb_set_serial_port_data(port, portdata); diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index c96714bb1..37c81c08f 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -61,7 +61,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) }, { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) }, - { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, @@ -78,8 +77,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) }, - { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, - { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) }, { } /* Terminating entry */ }; @@ -221,9 +218,10 @@ static int pl2303_startup (struct usb_serial *serial) dbg("device type: %d", type); for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL); + priv = kmalloc (sizeof (struct pl2303_private), GFP_KERNEL); if (!priv) goto cleanup; + memset (priv, 0x00, sizeof (struct pl2303_private)); spin_lock_init(&priv->lock); priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE); if (priv->buf == NULL) { @@ -385,11 +383,12 @@ static void pl2303_set_termios (struct usb_serial_port *port, struct termios *ol } } - buf = kzalloc (7, GFP_KERNEL); + buf = kmalloc (7, GFP_KERNEL); if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); return; } + memset (buf, 0x00, 0x07); i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0), GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE, @@ -829,7 +828,6 @@ static void pl2303_update_line_status(struct usb_serial_port *port, spin_lock_irqsave(&priv->lock, flags); priv->line_status = data[status_idx]; spin_unlock_irqrestore(&priv->lock, flags); - wake_up_interruptible (&priv->delta_msr_wait); exit: return; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 7f29e81d3..9bc475516 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -26,7 +26,6 @@ #define ITEGNO_VENDOR_ID 0x0eba #define ITEGNO_PRODUCT_ID 0x1080 -#define ITEGNO_PRODUCT_ID_2080 0x2080 #define MA620_VENDOR_ID 0x0df7 #define MA620_PRODUCT_ID 0x0620 @@ -76,11 +75,3 @@ /* Leadtek GPS 9531 (ID 0413:2101) */ #define LEADTEK_VENDOR_ID 0x0413 #define LEADTEK_9531_PRODUCT_ID 0x2101 - -/* USB GSM cable from Speed Dragon Multimedia, Ltd */ -#define SPEEDDRAGON_VENDOR_ID 0x0e55 -#define SPEEDDRAGON_PRODUCT_ID 0x110b - -/* Ours Technology Inc DKU-5 clone, chipset: Prolific Technology Inc */ -#define OTI_VENDOR_ID 0x0ea0 -#define OTI_PRODUCT_ID 0x6858 diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index c3a2071b8..c18db3257 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -416,11 +416,12 @@ static int ti_startup(struct usb_serial *serial) dev->actconfig->desc.bConfigurationValue); /* create device structure */ - tdev = kzalloc(sizeof(struct ti_device), GFP_KERNEL); + tdev = kmalloc(sizeof(struct ti_device), GFP_KERNEL); if (tdev == NULL) { dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); return -ENOMEM; } + memset(tdev, 0, sizeof(struct ti_device)); sema_init(&tdev->td_open_close_sem, 1); tdev->td_serial = serial; usb_set_serial_data(serial, tdev); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 9c36f0ece..b5c96e74a 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -27,10 +27,10 @@ #include #include #include -#include #include #include #include +#include #include #include "usb-serial.h" #include "pl2303.h" @@ -189,15 +189,11 @@ static int serial_open (struct tty_struct *tty, struct file * filp) portNumber = tty->index - serial->minor; port = serial->port[portNumber]; - if (!port) { - retval = -ENODEV; - goto bailout_kref_put; - } + if (!port) + return -ENODEV; - if (mutex_lock_interruptible(&port->mutex)) { - retval = -ERESTARTSYS; - goto bailout_kref_put; - } + if (down_interruptible(&port->sem)) + return -ERESTARTSYS; ++port->open_count; @@ -213,7 +209,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) * safe because we are called with BKL held */ if (!try_module_get(serial->type->driver.owner)) { retval = -ENODEV; - goto bailout_mutex_unlock; + goto bailout_kref_put; } /* only call the device specific open if this @@ -223,16 +219,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp) goto bailout_module_put; } - mutex_unlock(&port->mutex); + up(&port->sem); return 0; bailout_module_put: module_put(serial->type->driver.owner); -bailout_mutex_unlock: - port->open_count = 0; - mutex_unlock(&port->mutex); bailout_kref_put: kref_put(&serial->kref, destroy_serial); + port->open_count = 0; + up(&port->sem); return retval; } @@ -245,10 +240,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) dbg("%s - port %d", __FUNCTION__, port->number); - mutex_lock(&port->mutex); + down(&port->sem); if (port->open_count == 0) { - mutex_unlock(&port->mutex); + up(&port->sem); return; } @@ -267,7 +262,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) module_put(port->serial->type->driver.owner); } - mutex_unlock(&port->mutex); + up(&port->sem); kref_put(&port->serial->kref, destroy_serial); } @@ -569,11 +564,12 @@ static struct usb_serial * create_serial (struct usb_device *dev, { struct usb_serial *serial; - serial = kzalloc(sizeof(*serial), GFP_KERNEL); + serial = kmalloc (sizeof (*serial), GFP_KERNEL); if (!serial) { dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); return NULL; } + memset (serial, 0, sizeof(*serial)); serial->dev = usb_get_dev(dev); serial->type = driver; serial->interface = interface; @@ -782,13 +778,14 @@ int usb_serial_probe(struct usb_interface *interface, serial->num_port_pointers = max_endpoints; dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); for (i = 0; i < max_endpoints; ++i) { - port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); + port = kmalloc(sizeof(struct usb_serial_port), GFP_KERNEL); if (!port) goto probe_error; + memset(port, 0x00, sizeof(struct usb_serial_port)); port->number = i + serial->minor; port->serial = serial; spin_lock_init(&port->lock); - mutex_init(&port->mutex); + sema_init(&port->sem, 1); INIT_WORK(&port->work, usb_serial_port_softint, port); serial->port[i] = port; } diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index dc89d8710..d7d27c338 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -16,7 +16,7 @@ #include #include -#include +#include #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ @@ -31,7 +31,7 @@ * @serial: pointer back to the struct usb_serial owner of this port. * @tty: pointer to the corresponding tty for this port. * @lock: spinlock to grab when updating portions of this structure. - * @mutex: mutex used to synchronize serial_open() and serial_close() + * @sem: semaphore used to synchronize serial_open() and serial_close() * access for this port. * @number: the number of the port (the minor number). * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. @@ -63,7 +63,7 @@ struct usb_serial_port { struct usb_serial * serial; struct tty_struct * tty; spinlock_t lock; - struct mutex mutex; + struct semaphore sem; unsigned char number; unsigned char * interrupt_in_buffer; diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index f5c3841d4..11a48d874 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -763,9 +763,10 @@ static int generic_startup(struct usb_serial *serial) int i; for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc (sizeof(*priv), GFP_KERNEL); + priv = kmalloc (sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + memset (priv, 0x00, sizeof(*priv)); spin_lock_init(&priv->lock); usb_set_serial_port_data(serial->port[i], priv); } diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 3ced09ca1..f494b67a8 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -508,7 +508,6 @@ no_firmware: err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description); err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description); err("%s: please contact support@connecttech.com\n", serial->type->description); - kfree(result); return -ENODEV; no_command_private: diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 01d8971ad..54e3e6c7e 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -512,12 +512,13 @@ int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) }; if (!us->extra) { - us->extra = kzalloc(sizeof(struct datafab_info), GFP_NOIO); + us->extra = kmalloc(sizeof(struct datafab_info), GFP_NOIO); if (!us->extra) { US_DEBUGP("datafab_transport: Gah! " "Can't allocate storage for Datafab info struct!\n"); return USB_STOR_TRANSPORT_ERROR; } + memset(us->extra, 0, sizeof(struct datafab_info)); us->extra_destructor = datafab_info_destructor; ((struct datafab_info *)us->extra)->lun = -1; } diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 6831dca93..ecb328aa9 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -1361,19 +1361,21 @@ static int isd200_init_info(struct us_data *us) struct isd200_info *info; info = (struct isd200_info *) - kzalloc(sizeof(struct isd200_info), GFP_KERNEL); + kmalloc(sizeof(struct isd200_info), GFP_KERNEL); if (!info) retStatus = ISD200_ERROR; else { + memset(info, 0, sizeof(struct isd200_info)); info->id = (struct hd_driveid *) - kzalloc(sizeof(struct hd_driveid), GFP_KERNEL); + kmalloc(sizeof(struct hd_driveid), GFP_KERNEL); info->RegsBuf = (unsigned char *) kmalloc(sizeof(info->ATARegs), GFP_KERNEL); if (!info->id || !info->RegsBuf) { isd200_free_info_ptrs(info); kfree(info); retStatus = ISD200_ERROR; - } + } else + memset(info->id, 0, sizeof(struct hd_driveid)); } if (retStatus == ISD200_GOOD) { @@ -1382,7 +1384,7 @@ static int isd200_init_info(struct us_data *us) } else US_DEBUGP("ERROR - kmalloc failure\n"); - return retStatus; + return(retStatus); } /************************************************************************** diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 5031aa98f..aff9d51c3 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -441,11 +441,12 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) }; if (!us->extra) { - us->extra = kzalloc(sizeof(struct jumpshot_info), GFP_NOIO); + us->extra = kmalloc(sizeof(struct jumpshot_info), GFP_NOIO); if (!us->extra) { US_DEBUGP("jumpshot_transport: Gah! Can't allocate storage for jumpshot info struct!\n"); return USB_STOR_TRANSPORT_ERROR; } + memset(us->extra, 0, sizeof(struct jumpshot_info)); us->extra_destructor = jumpshot_info_destructor; } diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 5f11e19ea..4ef552702 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -47,7 +47,6 @@ #include #include -#include #include #include @@ -272,9 +271,9 @@ static int device_reset(struct scsi_cmnd *srb) US_DEBUGP("%s called\n", __FUNCTION__); /* lock the device pointers and do the reset */ - mutex_lock(&(us->dev_mutex)); + down(&(us->dev_semaphore)); result = us->transport_reset(us); - mutex_unlock(&us->dev_mutex); + up(&(us->dev_semaphore)); return result < 0 ? FAILED : SUCCESS; } @@ -287,9 +286,9 @@ static int bus_reset(struct scsi_cmnd *srb) US_DEBUGP("%s called\n", __FUNCTION__); - mutex_lock(&(us->dev_mutex)); + down(&(us->dev_semaphore)); result = usb_stor_port_reset(us); - mutex_unlock(&us->dev_mutex); + up(&(us->dev_semaphore)); return result < 0 ? FAILED : SUCCESS; } diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 0b1b5b59c..8451779f4 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -751,10 +751,11 @@ int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) struct sddr55_card_info *info; if (!us->extra) { - us->extra = kzalloc( + us->extra = kmalloc( sizeof(struct sddr55_card_info), GFP_NOIO); if (!us->extra) return USB_STOR_TRANSPORT_ERROR; + memset(us->extra, 0, sizeof(struct sddr55_card_info)); us->extra_destructor = sddr55_card_info_destructor; } diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index f2bc5c9e2..fea176d7e 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1318,11 +1318,12 @@ int init_usbat(struct us_data *us) unsigned char subcountL = USBAT_ATA_LBA_ME; unsigned char *status = us->iobuf; - us->extra = kzalloc(sizeof(struct usbat_info), GFP_NOIO); + us->extra = kmalloc(sizeof(struct usbat_info), GFP_NOIO); if (!us->extra) { US_DEBUGP("init_usbat: Gah! Can't allocate storage for usbat info struct!\n"); return 1; } + memset(us->extra, 0, sizeof(struct usbat_info)); info = (struct usbat_info *) (us->extra); /* Enable peripheral control signals */ diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a1a83029c..31ca92056 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -62,13 +62,6 @@ UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN ), -/* Reported by Rodolfo Quesada */ -UNUSUAL_DEV( 0x03ee, 0x6906, 0x0003, 0x0003, - "VIA Technologies Inc.", - "Mitsumi multi cardreader", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE ), - UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, "HP", "CD-Writer+", @@ -113,12 +106,6 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), -/* Reported by Orgad Shaneh */ -UNUSUAL_DEV( 0x0419, 0xaace, 0x0100, 0x0100, - "Samsung", "MP3 Player", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE), - /* Reported by Christian Leber */ UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100, "TrekStor", @@ -133,12 +120,6 @@ UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), -/* Reported by Pete Zaitcev , bz#176584 */ -UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, - "GENERIC", "MP3 PLAYER", /* MyMusix PD-205 on the outside. */ - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE ), - /* Reported by Olaf Hering from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", @@ -417,7 +398,7 @@ UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133, UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100, "Iomega", "USB Clik! 40", - US_SC_8070, US_PR_DEVICE, NULL, + US_SC_8070, US_PR_BULK, NULL, US_FL_FIX_INQUIRY ), /* Yakumo Mega Image 37 @@ -779,26 +760,12 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), -/* Reported by Olivier Blondeau */ -UNUSUAL_DEV( 0x0727, 0x0306, 0x0100, 0x0100, - "ATMEL", - "SND1 Storage", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE), - -/* Submitted by Roman Hodek */ -UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, +UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk", "ImageMate SDDR-05a", US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN ), -UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009, - "SanDisk Corporation", - "ImageMate CompactFlash USB", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - #ifdef CONFIG_USB_STORAGE_USBAT UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, "Sandisk", @@ -1106,16 +1073,6 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, 0), #endif -/* - * Pete Zaitcev , bz#164688. - * The device blatantly ignores LUN and returns 1 in GetMaxLUN. - */ -UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100, - "Unknown", - "Unknown", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_SINGLE_LUN ), - /* Submitted by Joris Struyve */ UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, "Medion", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 0142fe82f..dbcf23980 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include @@ -189,7 +188,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) struct us_data *us = usb_get_intfdata(iface); /* Wait until no command is running */ - mutex_lock(&us->dev_mutex); + down(&us->dev_semaphore); US_DEBUGP("%s\n", __FUNCTION__); if (us->suspend_resume_hook) @@ -199,7 +198,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) /* When runtime PM is working, we'll set a flag to indicate * whether we should autoresume when a SCSI request arrives. */ - mutex_unlock(&us->dev_mutex); + up(&us->dev_semaphore); return 0; } @@ -207,14 +206,14 @@ static int storage_resume(struct usb_interface *iface) { struct us_data *us = usb_get_intfdata(iface); - mutex_lock(&us->dev_mutex); + down(&us->dev_semaphore); US_DEBUGP("%s\n", __FUNCTION__); if (us->suspend_resume_hook) (us->suspend_resume_hook)(us, US_RESUME); iface->dev.power.power_state.event = PM_EVENT_ON; - mutex_unlock(&us->dev_mutex); + up(&us->dev_semaphore); return 0; } @@ -277,12 +276,12 @@ static int usb_stor_control_thread(void * __us) US_DEBUGP("*** thread awakened.\n"); /* lock the device pointers */ - mutex_lock(&(us->dev_mutex)); + down(&(us->dev_semaphore)); /* if the device has disconnected, we are free to exit */ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { US_DEBUGP("-- exiting\n"); - mutex_unlock(&us->dev_mutex); + up(&(us->dev_semaphore)); break; } @@ -371,7 +370,7 @@ SkipForAbort: scsi_unlock(host); /* unlock the device pointers */ - mutex_unlock(&us->dev_mutex); + up(&(us->dev_semaphore)); } /* for (;;) */ scsi_host_put(host); @@ -593,15 +592,6 @@ static int get_transport(struct us_data *us) break; #endif -#ifdef CONFIG_USB_STORAGE_ALAUDA - case US_PR_ALAUDA: - us->transport_name = "Alauda Control/Bulk"; - us->transport = alauda_transport; - us->transport_reset = usb_stor_Bulk_reset; - us->max_lun = 1; - break; -#endif - default: return -EIO; } @@ -657,6 +647,15 @@ static int get_protocol(struct us_data *us) break; #endif +#ifdef CONFIG_USB_STORAGE_ALAUDA + case US_PR_ALAUDA: + us->transport_name = "Alauda Control/Bulk"; + us->transport = alauda_transport; + us->transport_reset = usb_stor_Bulk_reset; + us->max_lun = 1; + break; +#endif + default: return -EIO; } @@ -816,8 +815,8 @@ static void quiesce_and_remove_host(struct us_data *us) * The thread will exit when it sees the DISCONNECTING flag. */ /* Wait for the current command to finish, then remove the host */ - mutex_lock(&us->dev_mutex); - mutex_unlock(&us->dev_mutex); + down(&us->dev_semaphore); + up(&us->dev_semaphore); /* queuecommand won't accept any new commands and the control * thread won't execute a previously-queued command. If there @@ -871,9 +870,9 @@ retry: /* For bulk-only devices, determine the max LUN value */ if (us->protocol == US_PR_BULK && !(us->flags & US_FL_SINGLE_LUN)) { - mutex_lock(&us->dev_mutex); + down(&us->dev_semaphore); us->max_lun = usb_stor_Bulk_max_lun(us); - mutex_unlock(&us->dev_mutex); + up(&us->dev_semaphore); } scsi_scan_host(us_to_host(us)); printk(KERN_DEBUG "usb-storage: device scan complete\n"); @@ -913,7 +912,7 @@ static int storage_probe(struct usb_interface *intf, us = host_to_us(host); memset(us, 0, sizeof(struct us_data)); - mutex_init(&(us->dev_mutex)); + init_MUTEX(&(us->dev_semaphore)); init_MUTEX_LOCKED(&(us->sema)); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 009fb0953..7259fd1f6 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -49,7 +49,6 @@ #include #include #include -#include #include struct us_data; @@ -104,9 +103,9 @@ typedef void (*pm_hook)(struct us_data *, int); /* power management hook */ struct us_data { /* The device we're working with * It's important to note: - * (o) you must hold dev_mutex to change pusb_dev + * (o) you must hold dev_semaphore to change pusb_dev */ - struct mutex dev_mutex; /* protect pusb_dev */ + struct semaphore dev_semaphore; /* protect pusb_dev */ struct usb_device *pusb_dev; /* this usb_device */ struct usb_interface *pusb_intf; /* this interface */ struct us_unusual_dev *unusual_dev; /* device-filter entry */ diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2fd9ab7f4..f5079c78b 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -70,22 +70,6 @@ config FB_MACMODES depends on FB default n -config FB_FIRMWARE_EDID - bool "Enable firmware EDID" - depends on FB - default y - ---help--- - This enables access to the EDID transferred from the firmware. - On the i386, this is from the Video BIOS. Enable this if DDC/I2C - transfers do not work for your driver and if you are using - nvidiafb, i810fb or savagefb. - - In general, choosing Y for this option is safe. If you - experience extremely long delays while booting before you get - something on your display, try setting this to N. Matrox cards in - combination with certain motherboards and monitors are known to - suffer from this problem. - config FB_MODE_HELPERS bool "Enable Video Mode Handling Helpers" depends on FB @@ -400,8 +384,6 @@ config FB_ASILIANT select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Asiliant 69030 chipset config FB_IMSTT bool "IMS Twin Turbo display support" @@ -513,7 +495,7 @@ config FB_HGA_ACCEL config VIDEO_SELECT bool - depends on (FB = y) && X86 && !XEN + depends on (FB = y) && X86 default y config FB_SGIVW @@ -906,6 +888,20 @@ config FB_MATROX_MULTIHEAD There is no need for enabling 'Matrox multihead support' if you have only one Matrox card in the box. +config FB_RADEON_OLD + tristate "ATI Radeon display support (Old driver)" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC + help + Choose this option if you want to use an ATI Radeon graphics card as + a framebuffer device. There are both PCI and AGP versions. You + don't need to choose this to run the Radeon in plain VGA mode. + There is a product page at + . + config FB_RADEON tristate "ATI Radeon display support" depends on FB && PCI @@ -963,7 +959,7 @@ config FB_ATY128 config FB_ATY tristate "ATI Mach64 display support" if PCI || ATARI - depends on FB && !SPARC32 + depends on FB select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -1208,17 +1204,6 @@ config FB_AU1100 bool "Au1100 LCD Driver" depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y -config FB_AU1200 - bool "Au1200 LCD Driver" - depends on FB && MIPS && SOC_AU1200 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer driver for the AMD Au1200 SOC. It can drive - various panels and CRTs by passing in kernel cmd line option - au1200fb:panel=. - source "drivers/video/geode/Kconfig" config FB_FFB diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 23de3b2c7..aa434e725 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_FB_KYRO) += kyro/ obj-$(CONFIG_FB_SAVAGE) += savage/ obj-$(CONFIG_FB_GEODE) += geode/ obj-$(CONFIG_FB_I810) += vgastate.o +obj-$(CONFIG_FB_RADEON_OLD) += radeonfb.o obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o obj-$(CONFIG_FB_VIRGE) += virgefb.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o @@ -85,7 +86,6 @@ obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o obj-$(CONFIG_FB_PXA) += pxafb.o obj-$(CONFIG_FB_W100) += w100fb.o obj-$(CONFIG_FB_AU1100) += au1100fb.o -obj-$(CONFIG_FB_AU1200) += au1200fb.o obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 98baecccb..b05827352 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -1269,7 +1269,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end) */ page = virt_to_page(virtual_start); ClearPageReserved(page); - init_page_count(page); + set_page_count(page, 1); free_page(virtual_start); virtual_start += PAGE_SIZE; @@ -1308,7 +1308,7 @@ static int __init acornfb_probe(struct platform_device *dev) /* * Try to select a suitable default mode */ - for (i = 0; i < ARRAY_SIZE(modedb); i++) { + for (i = 0; i < sizeof(modedb) / sizeof(*modedb); i++) { unsigned long hs; hs = modedb[i].refresh * @@ -1380,7 +1380,7 @@ static int __init acornfb_probe(struct platform_device *dev) */ free_unused_pages(PAGE_OFFSET + size, PAGE_OFFSET + MAX_SIZE); #endif - + fb_info.fix.smem_len = size; current_par.palette_size = VIDC_PALETTE_SIZE; @@ -1391,7 +1391,7 @@ static int __init acornfb_probe(struct platform_device *dev) */ do { rc = fb_find_mode(&fb_info.var, &fb_info, NULL, modedb, - ARRAY_SIZE(modedb), + sizeof(modedb) / sizeof(*modedb), &acornfb_default_mode, DEFAULT_BPP); /* * If we found an exact match, all ok. @@ -1408,7 +1408,7 @@ static int __init acornfb_probe(struct platform_device *dev) break; rc = fb_find_mode(&fb_info.var, &fb_info, NULL, modedb, - ARRAY_SIZE(modedb), + sizeof(modedb) / sizeof(*modedb), &acornfb_default_mode, DEFAULT_BPP); if (rc) break; diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index 29f9f0dfe..c924d81f7 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c @@ -353,6 +353,8 @@ struct chips_init_reg { unsigned char data; }; +#define N_ELTS(x) (sizeof(x) / sizeof(x[0])) + static struct chips_init_reg chips_init_sr[] = { {0x00, 0x03}, /* Reset register */ @@ -458,22 +460,22 @@ static void __devinit chips_hw_init(struct fb_info *p) { int i; - for (i = 0; i < ARRAY_SIZE(chips_init_xr); ++i) + for (i = 0; i < N_ELTS(chips_init_xr); ++i) write_xr(chips_init_xr[i].addr, chips_init_xr[i].data); write_xr(0x81, 0x12); write_xr(0x82, 0x08); write_xr(0x20, 0x00); - for (i = 0; i < ARRAY_SIZE(chips_init_sr); ++i) + for (i = 0; i < N_ELTS(chips_init_sr); ++i) write_sr(chips_init_sr[i].addr, chips_init_sr[i].data); - for (i = 0; i < ARRAY_SIZE(chips_init_gr); ++i) + for (i = 0; i < N_ELTS(chips_init_gr); ++i) write_gr(chips_init_gr[i].addr, chips_init_gr[i].data); - for (i = 0; i < ARRAY_SIZE(chips_init_ar); ++i) + for (i = 0; i < N_ELTS(chips_init_ar); ++i) write_ar(chips_init_ar[i].addr, chips_init_ar[i].data); /* Enable video output in attribute index register */ writeb(0x20, mmio_base + 0x780); - for (i = 0; i < ARRAY_SIZE(chips_init_cr); ++i) + for (i = 0; i < N_ELTS(chips_init_cr); ++i) write_cr(chips_init_cr[i].addr, chips_init_cr[i].data); - for (i = 0; i < ARRAY_SIZE(chips_init_fr); ++i) + for (i = 0; i < N_ELTS(chips_init_fr); ++i) write_fr(chips_init_fr[i].addr, chips_init_fr[i].data); } diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index f7bbff4dd..620c9a934 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -67,7 +67,6 @@ #include #ifdef CONFIG_PPC_PMAC -#include #include #include #include @@ -1726,9 +1725,9 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id * strcpy(video_card, "Rage128 XX "); video_card[8] = ent->device >> 8; video_card[9] = ent->device & 0xFF; - + /* range check to make sure */ - if (ent->driver_data < ARRAY_SIZE(r128_family)) + if (ent->driver_data < (sizeof(r128_family)/sizeof(char *))) strncat(video_card, r128_family[ent->driver_data], sizeof(video_card)); printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev); @@ -1749,7 +1748,7 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id * var = default_var; #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { /* Indicate sleep capability */ if (par->chip_gen == rage_M3) { pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1); @@ -2012,7 +2011,7 @@ static int aty128fb_blank(int blank, struct fb_info *fb) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank) + if ((_machine == _MACH_Pmac) && blank) set_backlight_enable(0); #endif /* CONFIG_PMAC_BACKLIGHT */ @@ -2030,7 +2029,7 @@ static int aty128fb_blank(int blank, struct fb_info *fb) aty128_set_lcd_enable(par, par->lcd_on && !blank); } #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && !blank) + if ((_machine == _MACH_Pmac) && !blank) set_backlight_enable(1); #endif /* CONFIG_PMAC_BACKLIGHT */ return 0; diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index d9d7d3c4c..485be386a 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -75,7 +75,6 @@ #include "ati_ids.h" #ifdef __powerpc__ -#include #include #include "../macmodes.h" #endif @@ -435,7 +434,7 @@ static int __devinit correct_chipset(struct atyfb_par *par) const char *name; int i; - for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) + for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--) if (par->pci_id == aty_chips[i].pci_id) break; @@ -2169,10 +2168,10 @@ static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk) if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { refresh_tbl = ragexl_tbl; - size = ARRAY_SIZE(ragexl_tbl); + size = sizeof(ragexl_tbl)/sizeof(int); } else { refresh_tbl = ragepro_tbl; - size = ARRAY_SIZE(ragepro_tbl); + size = sizeof(ragepro_tbl)/sizeof(int); } for (i=0; i < size; i++) { @@ -2299,10 +2298,6 @@ static int __init aty_init(struct fb_info *info, const char *name) case CLK_ATI18818_1: par->pll_ops = &aty_pll_ati18818_1; break; - case CLK_IBMRGB514: - par->pll_ops = &aty_pll_ibm514; - break; -#if 0 /* dead code */ case CLK_STG1703: par->pll_ops = &aty_pll_stg1703; break; @@ -2312,7 +2307,9 @@ static int __init aty_init(struct fb_info *info, const char *name) case CLK_ATT20C408: par->pll_ops = &aty_pll_att20c408; break; -#endif + case CLK_IBMRGB514: + par->pll_ops = &aty_pll_ibm514; + break; default: PRINTKI("aty_init: CLK type not implemented yet!"); par->pll_ops = &aty_pll_unsupported; @@ -2519,7 +2516,7 @@ static int __init aty_init(struct fb_info *info, const char *name) memset(&var, 0, sizeof(var)); #ifdef CONFIG_PPC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { /* * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it * applies to all Mac video cards @@ -2674,7 +2671,7 @@ static int atyfb_blank(int blank, struct fb_info *info) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank > FB_BLANK_NORMAL) + if ((_machine == _MACH_Pmac) && blank > FB_BLANK_NORMAL) set_backlight_enable(0); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) if (par->lcd_table && blank > FB_BLANK_NORMAL && @@ -2706,7 +2703,7 @@ static int atyfb_blank(int blank, struct fb_info *info) aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) + if ((_machine == _MACH_Pmac) && blank <= FB_BLANK_NORMAL) set_backlight_enable(1); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) if (par->lcd_table && blank <= FB_BLANK_NORMAL && @@ -3400,7 +3397,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi struct atyfb_par *par; int i, rc = -ENOMEM; - for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) + for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--) if (pdev->device == aty_chips[i].pci_id) break; diff --git a/drivers/video/aty/mach64_gx.c b/drivers/video/aty/mach64_gx.c index 2045639cb..01fdff794 100644 --- a/drivers/video/aty/mach64_gx.c +++ b/drivers/video/aty/mach64_gx.c @@ -149,7 +149,8 @@ static int aty_var_to_pll_514(const struct fb_info *info, u32 vclk_per, }; int i; - for (i = 0; i < ARRAY_SIZE(RGB514_clocks); i++) + for (i = 0; i < sizeof(RGB514_clocks) / sizeof(*RGB514_clocks); + i++) if (vclk_per <= RGB514_clocks[i].limit) { pll->ibm514.m = RGB514_clocks[i].m; pll->ibm514.n = RGB514_clocks[i].n; diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 085cf8022..c9f0c5a07 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -272,9 +272,6 @@ static int force_measure_pll = 0; #ifdef CONFIG_MTRR static int nomtrr = 0; #endif -#if defined(CONFIG_PM) && defined(CONFIG_X86) -int radeon_force_sleep = 0; -#endif /* * prototypes @@ -1070,7 +1067,7 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, if (regno > 255) - return -EINVAL; + return 1; red >>= 8; green >>= 8; @@ -1089,9 +1086,9 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, pindex = regno * 8; if (rinfo->depth == 16 && regno > 63) - return -EINVAL; + return 1; if (rinfo->depth == 15 && regno > 31) - return -EINVAL; + return 1; /* For 565, the green component is mixed one order * below @@ -2268,7 +2265,7 @@ static struct bin_attribute edid2_attr = { }; -static int __devinit radeonfb_pci_register (struct pci_dev *pdev, +static int radeonfb_pci_register (struct pci_dev *pdev, const struct pci_device_id *ent) { struct fb_info *info; @@ -2618,10 +2615,6 @@ static int __init radeonfb_setup (char *options) force_measure_pll = 1; } else if (!strncmp(this_opt, "ignore_edid", 11)) { ignore_edid = 1; -#if defined(CONFIG_PM) && defined(CONFIG_X86) - } else if (!strncmp(this_opt, "force_sleep", 11)) { - radeon_force_sleep = 1; -#endif } else mode_option = this_opt; } @@ -2677,7 +2670,3 @@ module_param(panel_yres, int, 0); MODULE_PARM_DESC(panel_yres, "int: set panel yres"); module_param(mode_option, charp, 0); MODULE_PARM_DESC(mode_option, "Specify resolution as \"x[-][@]\" "); -#if defined(CONFIG_PM) && defined(CONFIG_X86) -module_param(radeon_force_sleep, int, 0); -MODULE_PARM_DESC(radeon_force_sleep, "bool: force ACPI sleep mode on untested machines"); -#endif diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 459fda622..1f8d805c6 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c @@ -20,31 +20,13 @@ #include #ifdef CONFIG_PPC_PMAC -#include +#include #include #include #endif -/* For detecting supported PC laptops */ -#ifdef CONFIG_X86 -#include -#endif - #include "ati_ids.h" -#ifdef CONFIG_X86 -/* This array holds a list of supported PC laptops. - * Currently only few IBM models are tested. - * If you want to experiment, use dmidecode to find out - * vendor and product codes for Your laptop. - */ -static struct dmi_system_id __devinitdata radeonfb_dmi_table[] = { -#include "radeon_pm_whitelist.h" -}; - -extern int radeon_force_sleep; -#endif - static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo) { u32 tmp; @@ -870,14 +852,7 @@ static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo) /* because both INPLL and OUTPLL take the same lock, that's why. */ tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND; OUTPLL( pllMCLK_MISC, tmp); - - /* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset - * and radeon chip dependent. Thus we only enable it on Mac for - * now (until we get more info on how to compute the correct - * value for various X86 bridges). - */ - -#ifdef CONFIG_PPC_PMAC + /* AGP PLL control */ if (rinfo->family <= CHIP_FAMILY_RV280) { OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID); @@ -889,7 +864,6 @@ static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo) OUTREG(BUS_CNTL1, INREG(BUS_CNTL1)); OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000); } -#endif OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN)); @@ -2106,7 +2080,7 @@ static void radeon_reinitialize_M9P(struct radeonfb_info *rinfo) OUTREG(0x2ec, 0x6332a3f0); mdelay(17); - OUTPLL(pllPPLL_REF_DIV, rinfo->pll.ref_div); + OUTPLL(pllPPLL_REF_DIV, rinfo->pll.ref_div);; OUTPLL(pllPPLL_DIV_0, rinfo->save_regs[92]); mdelay(40); @@ -2771,7 +2745,7 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) rinfo->pm_mode |= radeon_pm_off; } #if defined(CONFIG_PPC_PMAC) - if (machine_is(powermac) && rinfo->of_node) { + if (_machine == _MACH_Pmac && rinfo->of_node) { if (rinfo->is_mobility && rinfo->pm_reg && rinfo->family <= CHIP_FAMILY_RV250) rinfo->pm_mode |= radeon_pm_d2; @@ -2816,29 +2790,6 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) } #endif /* defined(CONFIG_PPC_PMAC) */ #endif /* defined(CONFIG_PM) */ - -/* The PM code also works on some PC laptops. - * Only a few models are actually tested so Your mileage may vary. - * We can do D2 on at least M7 and M9 on some IBM ThinkPad T41 models. - */ -#if defined(CONFIG_PM) && defined(CONFIG_X86) - if (radeon_force_sleep || dmi_check_system(radeonfb_dmi_table)) { - if (radeon_force_sleep) - printk("radeonfb: forcefully enabling sleep mode\n"); - else - printk("radeonfb: enabling sleep mode\n"); - - if (rinfo->is_mobility && rinfo->pm_reg && - rinfo->family <= CHIP_FAMILY_RV250) - rinfo->pm_mode |= radeon_pm_d2; - - /* Power down TV DAC, that saves a significant amount of power, - * we'll have something better once we actually have some TVOut - * support - */ - OUTREG(TV_DAC_CNTL, INREG(TV_DAC_CNTL) | 0x07000000); - } -#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */ } void radeonfb_pm_exit(struct radeonfb_info *rinfo) diff --git a/drivers/video/aty/radeon_pm_whitelist.h b/drivers/video/aty/radeon_pm_whitelist.h deleted file mode 100644 index c484ee7f8..000000000 --- a/drivers/video/aty/radeon_pm_whitelist.h +++ /dev/null @@ -1,78 +0,0 @@ -#define E(_vendor, _product, _ident, _reporter) \ -{ /* _reporter */ \ - .ident = _ident, \ - .matches = { \ - DMI_MATCH(DMI_SYS_VENDOR, _vendor), \ - DMI_MATCH(DMI_PRODUCT_NAME, _product), \ - }, \ -} -E("IBM", "18297RG", "IBM ThinkPad R50", "Borschuk Oleg "), -E("IBM", "18299MG", "IBM ThinkPad R51", "Georges Herber "), -E("IBM", "1829EHG", "IBM ThinkPad R51", "Wouter Cloetens "), -E("IBM", "1829R6G", "IBM ThinkPad R51", "Sten Heinze"), -E("IBM", "1836Q6U", "IBM ThinkPad R51", "Eugene Pavlovsky"), -E("IBM", "236696G", "IBM ThinkPad T30", "Jakob Schiotz "), -E("IBM", "236697G", "IBM ThinkPad T30", "Stephan Groß "), -E("IBM", "2366JBG", "IBM ThinkPad T30", "Thomas M Steenholdt "), -E("IBM", "2366MU9", "IBM ThinkPad T30", "Phillip Jones "), -E("IBM", "2366QU5", "IBM ThinkPad T30", "ChazeFroy "), -/* brads's 2366QU8 works, but dmidecode shows bogus data */ -E("IBM", "2366QU8", "IBM ThinkPad T30", "Brad Smith "), -E("IBM", "23729CU", "IBM ThinkPad T40", "George Avrunin "), -E("IBM", "237314U", "IBM ThinkPad T40", "Dmitriy Zavin "), -E("IBM", "23731FG", "IBM ThinkPad T41", "Aivo Prykk "), -E("IBM", "237322G", "IBM ThinkPad T40", "Michele Lamarca "), -E("IBM", "237325G", "IBM ThinkPad T40", "Klaus Kurzmann "), -E("IBM", "23732FG", "IBM ThinkPad T41", "Antti Andreimann "), -E("IBM", "23733HM", "IBM ThinkPad T41", "Grahame Bowland "), -E("IBM", "23734G2", "IBM ThinkPad T40", "Antti P Miettinen "), -E("IBM", "23737JU", "IBM ThinkPad T41", "Matthew Saltzman "), -E("IBM", "23738CG", "IBM ThinkPad T40", "Pete Toscano "), -E("IBM", "237392G", "IBM ThinkPad T40", "Pete Toscano "), -E("IBM", "237394G", "IBM ThinkPad T40", "Manuel Carro "), -E("IBM", "237394U", "IBM ThinkPad T40", "Pete Toscano "), -E("IBM", "23739FU", "IBM ThinkPad T41", "Peter Jones "), -E("IBM", "23739HG", "IBM ThinkPad T41", "Chris Vanden Berghe "), -E("IBM", "23739HU", "IBM ThinkPad T41", "Ajay Ramaswamy "), -E("IBM", "2373BU7", "IBM ThinkPad T40", "Peter Jones "), -E("IBM", "2373F2G", "IBM ThinkPad T42", "Isaac Wilcox"), -E("IBM", "2373FWG", "IBM ThinkPad T42", "Jerome Poggi and Pete Toscano "), -E("IBM", "2373G1G", "IBM ThinkPad T40p", "Juerg Billeter "), -E("IBM", "2373G1U", "IBM ThinkPad T40p", "Bill Nottingham "), -E("IBM", "2373G3G", "IBM ThinkPad T40p", "Hartwig, Thomas "), -E("IBM", "2373GEU", "IBM ThinkPad T41p", "Eric Benson "), -E("IBM", "2373HU6", "IBM ThinkPad T41", "David Zeuthen "), -E("IBM", "2373JTU", "IBM ThinkPad T42", "Dwight Barkley "), -E("IBM", "2373MU4", "IBM ThinkPad T40", "Vernon Mauery "), -E("IBM", "2373RU1", "IBM ThinkPad T40", "Adam Glasgall "), -E("IBM", "2373TG5", "IBM ThinkPad T41", "Paul Ionescu "), -E("IBM", "2373XNX", "IBM ThinkPad T41", "Ajay Ramaswamy "), -E("IBM", "23746VU", "IBM ThinkPad T42", "Tim Hull "), -E("IBM", "2374CTO", "IBM ThinkPad T42", "Johannes Hansen"), -E("IBM", "2374ZEP", "IBM ThinkPad T42", "Johannes Hansen"), -E("IBM", "2378DEU", "IBM ThinkPad T41", "obi "), -E("IBM", "2378DLU", "IBM ThinkPad T41", "Paul Stanisci "), -E("IBM", "2378DUU", "IBM ThinkPad T42", "Austin Clements "), -E("IBM", "2378R2U", "IBM ThinkPad T42", "Ulrich Drepper "), -E("IBM", "2378RBF", "IBM ThinkPad T42", "Nicolas Dufresne "), -E("IBM", "2378RBU", "IBM ThinkPad T42", "Nicolas Dufresne "), -E("IBM", "2378XXE", "IBM ThinkPad T42", "Tom Marshall"), -E("IBM", "2379D6U", "IBM ThinkPad T41", "anonymous"), -E("IBM", "2379DJU", "IBM ThinkPad T41", "Volker Braun "), -E("IBM", "2658BQG", "IBM ThinkPad R32", "Frank Otto "), -E("IBM", "26725KU", "IBM ThinkPad X31", "Chris Lee "), -E("IBM", "2672A9U", "IBM ThinkPad X31", "Jeremy Katz "), -E("IBM", "2672JHG", "IBM ThinkPad X31", "Daniel P. Berrange "), -E("IBM", "2672RU3", "IBM ThinkPad X31", "Chris Blizzard "), - /* IBM ThinkPad X31 2672-XXH -> works, but doesn't fix the LCD - backlight on during S3 issue. */ -E("IBM", "2672XXH", "IBM ThinkPad X31", "Henrik Brix Andersen "), -E("IBM", "27223GG", "IBM ThinkPad R40", "Frank Schmitt "), -E("IBM", "27225MG", "IBM ThinkPad R40", "Nils Trebing "), -E("IBM", "27226YU", "IBM ThinkPad R40", "Rushi Bhatt"), -E("IBM", "2722B3G", "IBM ThinkPad R40", "Pete Toscano "), -E("IBM", "2722CDG", "IBM ThinkPad R40", "Meik Hellmund "), -{ }, -/* Negative reports: */ -/* E("IBM", "2373KUU", "IBM ThinkPad T42p", "Dax Kelson "), */ -#undef E diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 789450bb0..3d04b2def 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -214,13 +214,10 @@ int au1100fb_setmode(struct au1100fb_device *fbdev) */ int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi) { - struct au1100fb_device *fbdev; - u32 *palette; + struct au1100fb_device *fbdev = to_au1100fb_device(fbi); + u32 *palette = fbdev->regs->lcd_pallettebase; u32 value; - fbdev = to_au1100fb_device(fbi); - palette = fbdev->regs->lcd_pallettebase; - if (regno > (AU1100_LCD_NBR_PALETTE_ENTRIES - 1)) return -EINVAL; @@ -319,11 +316,9 @@ int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) */ int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) { - struct au1100fb_device *fbdev; + struct au1100fb_device *fbdev = to_au1100fb_device(fbi); int dy; - fbdev = to_au1100fb_device(fbi); - print_dbg("fb_pan_display %p %p", var, fbi); if (!var || !fbdev) { @@ -387,12 +382,10 @@ void au1100fb_fb_rotate(struct fb_info *fbi, int angle) */ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) { - struct au1100fb_device *fbdev; + struct au1100fb_device *fbdev = to_au1100fb_device(fbi); unsigned int len; unsigned long start=0, off; - fbdev = to_au1100fb_device(fbi); - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { return -EINVAL; } @@ -474,7 +467,7 @@ int au1100fb_drv_probe(struct device *dev) if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len, DRIVER_NAME)) { - print_err("fail to lock memory region at 0x%08lx", + print_err("fail to lock memory region at 0x%08x", au1100fb_fix.mmio_start); return -EBUSY; } @@ -602,13 +595,13 @@ int au1100fb_drv_remove(struct device *dev) return 0; } -int au1100fb_drv_suspend(struct device *dev, pm_message_t state) +int au1100fb_drv_suspend(struct device *dev, u32 state, u32 level) { /* TODO */ return 0; } -int au1100fb_drv_resume(struct device *dev) +int au1100fb_drv_resume(struct device *dev, u32 level) { /* TODO */ return 0; diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c deleted file mode 100644 index 600d3e0e0..000000000 --- a/drivers/video/au1200fb.c +++ /dev/null @@ -1,1922 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Au1200 LCD Driver. - * - * Copyright 2004-2005 AMD - * Author: AMD - * - * Based on: - * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device - * Created 28 Dec 1997 by Geert Uytterhoeven - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "au1200fb.h" - -#ifdef CONFIG_PM -#include -#endif - -#ifndef CONFIG_FB_AU1200_DEVS -#define CONFIG_FB_AU1200_DEVS 4 -#endif - -#define DRIVER_NAME "au1200fb" -#define DRIVER_DESC "LCD controller driver for AU1200 processors" - -#define DEBUG 1 - -#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg) -#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg) -#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg) - -#if DEBUG -#define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg) -#else -#define print_dbg(f, arg...) do {} while (0) -#endif - - -#define AU1200_LCD_FB_IOCTL 0x46FF - -#define AU1200_LCD_SET_SCREEN 1 -#define AU1200_LCD_GET_SCREEN 2 -#define AU1200_LCD_SET_WINDOW 3 -#define AU1200_LCD_GET_WINDOW 4 -#define AU1200_LCD_SET_PANEL 5 -#define AU1200_LCD_GET_PANEL 6 - -#define SCREEN_SIZE (1<< 1) -#define SCREEN_BACKCOLOR (1<< 2) -#define SCREEN_BRIGHTNESS (1<< 3) -#define SCREEN_COLORKEY (1<< 4) -#define SCREEN_MASK (1<< 5) - -struct au1200_lcd_global_regs_t { - unsigned int flags; - unsigned int xsize; - unsigned int ysize; - unsigned int backcolor; - unsigned int brightness; - unsigned int colorkey; - unsigned int mask; - unsigned int panel_choice; - char panel_desc[80]; - -}; - -#define WIN_POSITION (1<< 0) -#define WIN_ALPHA_COLOR (1<< 1) -#define WIN_ALPHA_MODE (1<< 2) -#define WIN_PRIORITY (1<< 3) -#define WIN_CHANNEL (1<< 4) -#define WIN_BUFFER_FORMAT (1<< 5) -#define WIN_COLOR_ORDER (1<< 6) -#define WIN_PIXEL_ORDER (1<< 7) -#define WIN_SIZE (1<< 8) -#define WIN_COLORKEY_MODE (1<< 9) -#define WIN_DOUBLE_BUFFER_MODE (1<< 10) -#define WIN_RAM_ARRAY_MODE (1<< 11) -#define WIN_BUFFER_SCALE (1<< 12) -#define WIN_ENABLE (1<< 13) - -struct au1200_lcd_window_regs_t { - unsigned int flags; - unsigned int xpos; - unsigned int ypos; - unsigned int alpha_color; - unsigned int alpha_mode; - unsigned int priority; - unsigned int channel; - unsigned int buffer_format; - unsigned int color_order; - unsigned int pixel_order; - unsigned int xsize; - unsigned int ysize; - unsigned int colorkey_mode; - unsigned int double_buffer_mode; - unsigned int ram_array_mode; - unsigned int xscale; - unsigned int yscale; - unsigned int enable; -}; - - -struct au1200_lcd_iodata_t { - unsigned int subcmd; - struct au1200_lcd_global_regs_t global; - struct au1200_lcd_window_regs_t window; -}; - -#if defined(__BIG_ENDIAN) -#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11 -#else -#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00 -#endif -#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565 - -/* Private, per-framebuffer management information (independent of the panel itself) */ -struct au1200fb_device { - struct fb_info fb_info; /* FB driver info record */ - - int plane; - unsigned char* fb_mem; /* FrameBuffer memory map */ - unsigned int fb_len; - dma_addr_t fb_phys; -}; - -static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS]; -/********************************************************************/ - -/* LCD controller restrictions */ -#define AU1200_LCD_MAX_XRES 1280 -#define AU1200_LCD_MAX_YRES 1024 -#define AU1200_LCD_MAX_BPP 32 -#define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */ -#define AU1200_LCD_NBR_PALETTE_ENTRIES 256 - -/* Default number of visible screen buffer to allocate */ -#define AU1200FB_NBR_VIDEO_BUFFERS 1 - -/********************************************************************/ - -static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR; -static int window_index = 2; /* default is zero */ -static int panel_index = 2; /* default is zero */ -static struct window_settings *win; -static struct panel_settings *panel; -static int noblanking = 1; -static int nohwcursor = 0; - -struct window_settings { - unsigned char name[64]; - uint32 mode_backcolor; - uint32 mode_colorkey; - uint32 mode_colorkeymsk; - struct { - int xres; - int yres; - int xpos; - int ypos; - uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */ - uint32 mode_winenable; - } w[4]; -}; - -#if defined(__BIG_ENDIAN) -#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00 -#else -#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01 -#endif - -extern int board_au1200fb_panel_init (void); -extern int board_au1200fb_panel_shutdown (void); - -#ifdef CONFIG_PM -int au1200fb_pm_callback(au1xxx_power_dev_t *dev, - au1xxx_request_t request, void *data); -au1xxx_power_dev_t *LCD_pm_dev; -#endif - -/* - * Default window configurations - */ -static struct window_settings windows[] = { - { /* Index 0 */ - "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", - /* mode_backcolor */ 0x006600ff, - /* mode_colorkey,msk*/ 0, 0, - { - { - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP, - /* mode_winenable*/ LCD_WINENABLE_WEN0, - }, - { - /* xres, yres, xpos, ypos */ 100, 100, 100, 100, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP | - LCD_WINCTRL1_PIPE, - /* mode_winenable*/ LCD_WINENABLE_WEN1, - }, - { - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP, - /* mode_winenable*/ 0, - }, - { - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP | - LCD_WINCTRL1_PIPE, - /* mode_winenable*/ 0, - }, - }, - }, - - { /* Index 1 */ - "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", - /* mode_backcolor */ 0x006600ff, - /* mode_colorkey,msk*/ 0, 0, - { - { - /* xres, yres, xpos, ypos */ 320, 240, 5, 5, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP | - LCD_WINCTRL1_PO_00, - /* mode_winenable*/ LCD_WINENABLE_WEN0, - }, - { - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 - | LCD_WINCTRL1_PO_16BPP, - /* mode_winenable*/ 0, - }, - { - /* xres, yres, xpos, ypos */ 100, 100, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP | - LCD_WINCTRL1_PIPE, - /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/, - }, - { - /* xres, yres, xpos, ypos */ 200, 25, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP | - LCD_WINCTRL1_PIPE, - /* mode_winenable*/ 0, - }, - }, - }, - { /* Index 2 */ - "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", - /* mode_backcolor */ 0x006600ff, - /* mode_colorkey,msk*/ 0, 0, - { - { - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP, - /* mode_winenable*/ LCD_WINENABLE_WEN0, - }, - { - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP, - /* mode_winenable*/ 0, - }, - { - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP | - LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE, - /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/, - }, - { - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | - LCD_WINCTRL1_PO_16BPP | - LCD_WINCTRL1_PIPE, - /* mode_winenable*/ 0, - }, - }, - }, - /* Need VGA 640 @ 24bpp, @ 32bpp */ - /* Need VGA 800 @ 24bpp, @ 32bpp */ - /* Need VGA 1024 @ 24bpp, @ 32bpp */ -}; - -/* - * Controller configurations for various panels. - */ - -struct panel_settings -{ - const char name[25]; /* Full name _ */ - - struct fb_monspecs monspecs; /* FB monitor specs */ - - /* panel timings */ - uint32 mode_screen; - uint32 mode_horztiming; - uint32 mode_verttiming; - uint32 mode_clkcontrol; - uint32 mode_pwmdiv; - uint32 mode_pwmhi; - uint32 mode_outmask; - uint32 mode_fifoctrl; - uint32 mode_toyclksrc; - uint32 mode_backlight; - uint32 mode_auxpll; - int (*device_init)(void); - int (*device_shutdown)(void); -#define Xres min_xres -#define Yres min_yres - u32 min_xres; /* Minimum horizontal resolution */ - u32 max_xres; /* Maximum horizontal resolution */ - u32 min_yres; /* Minimum vertical resolution */ - u32 max_yres; /* Maximum vertical resolution */ -}; - -/********************************************************************/ -/* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */ - -/* List of panels known to work with the AU1200 LCD controller. - * To add a new panel, enter the same specifications as the - * Generic_TFT one, and MAKE SURE that it doesn't conflicts - * with the controller restrictions. Restrictions are: - * - * STN color panels: max_bpp <= 12 - * STN mono panels: max_bpp <= 4 - * TFT panels: max_bpp <= 16 - * max_xres <= 800 - * max_yres <= 600 - */ -static struct panel_settings known_lcd_panels[] = -{ - [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */ - .name = "QVGA_320x240", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 30000, - .hfmax = 70000, - .vfmin = 60, - .vfmax = 60, - .dclkmin = 6000000, - .dclkmax = 28000000, - .input = FB_DISP_RGB, - }, - .mode_screen = LCD_SCREEN_SX_N(320) | - LCD_SCREEN_SY_N(240), - .mode_horztiming = 0x00c4623b, - .mode_verttiming = 0x00502814, - .mode_clkcontrol = 0x00020002, /* /4=24Mhz */ - .mode_pwmdiv = 0x00000000, - .mode_pwmhi = 0x00000000, - .mode_outmask = 0x00FFFFFF, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ - .device_init = NULL, - .device_shutdown = NULL, - 320, 320, - 240, 240, - }, - - [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */ - .name = "VGA_640x480", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 30000, - .hfmax = 70000, - .vfmin = 60, - .vfmax = 60, - .dclkmin = 6000000, - .dclkmax = 28000000, - .input = FB_DISP_RGB, - }, - .mode_screen = 0x13f9df80, - .mode_horztiming = 0x003c5859, - .mode_verttiming = 0x00741201, - .mode_clkcontrol = 0x00020001, /* /4=24Mhz */ - .mode_pwmdiv = 0x00000000, - .mode_pwmhi = 0x00000000, - .mode_outmask = 0x00FFFFFF, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ - .device_init = NULL, - .device_shutdown = NULL, - 640, 480, - 640, 480, - }, - - [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */ - .name = "SVGA_800x600", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 30000, - .hfmax = 70000, - .vfmin = 60, - .vfmax = 60, - .dclkmin = 6000000, - .dclkmax = 28000000, - .input = FB_DISP_RGB, - }, - .mode_screen = 0x18fa5780, - .mode_horztiming = 0x00dc7e77, - .mode_verttiming = 0x00584805, - .mode_clkcontrol = 0x00020000, /* /2=48Mhz */ - .mode_pwmdiv = 0x00000000, - .mode_pwmhi = 0x00000000, - .mode_outmask = 0x00FFFFFF, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ - .device_init = NULL, - .device_shutdown = NULL, - 800, 800, - 600, 600, - }, - - [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */ - .name = "XVGA_1024x768", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 30000, - .hfmax = 70000, - .vfmin = 60, - .vfmax = 60, - .dclkmin = 6000000, - .dclkmax = 28000000, - .input = FB_DISP_RGB, - }, - .mode_screen = 0x1ffaff80, - .mode_horztiming = 0x007d0e57, - .mode_verttiming = 0x00740a01, - .mode_clkcontrol = 0x000A0000, /* /1 */ - .mode_pwmdiv = 0x00000000, - .mode_pwmhi = 0x00000000, - .mode_outmask = 0x00FFFFFF, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 6, /* 72MHz AUXPLL */ - .device_init = NULL, - .device_shutdown = NULL, - 1024, 1024, - 768, 768, - }, - - [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */ - .name = "XVGA_1280x1024", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 30000, - .hfmax = 70000, - .vfmin = 60, - .vfmax = 60, - .dclkmin = 6000000, - .dclkmax = 28000000, - .input = FB_DISP_RGB, - }, - .mode_screen = 0x27fbff80, - .mode_horztiming = 0x00cdb2c7, - .mode_verttiming = 0x00600002, - .mode_clkcontrol = 0x000A0000, /* /1 */ - .mode_pwmdiv = 0x00000000, - .mode_pwmhi = 0x00000000, - .mode_outmask = 0x00FFFFFF, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 10, /* 120MHz AUXPLL */ - .device_init = NULL, - .device_shutdown = NULL, - 1280, 1280, - 1024, 1024, - }, - - [5] = { /* Samsung 1024x768 TFT */ - .name = "Samsung_1024x768_TFT", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 30000, - .hfmax = 70000, - .vfmin = 60, - .vfmax = 60, - .dclkmin = 6000000, - .dclkmax = 28000000, - .input = FB_DISP_RGB, - }, - .mode_screen = 0x1ffaff80, - .mode_horztiming = 0x018cc677, - .mode_verttiming = 0x00241217, - .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */ - .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */ - .mode_pwmhi = 0x03400000, /* SCB 0x0 */ - .mode_outmask = 0x00FFFFFF, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ - .device_init = board_au1200fb_panel_init, - .device_shutdown = board_au1200fb_panel_shutdown, - 1024, 1024, - 768, 768, - }, - - [6] = { /* Toshiba 640x480 TFT */ - .name = "Toshiba_640x480_TFT", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 30000, - .hfmax = 70000, - .vfmin = 60, - .vfmax = 60, - .dclkmin = 6000000, - .dclkmax = 28000000, - .input = FB_DISP_RGB, - }, - .mode_screen = LCD_SCREEN_SX_N(640) | - LCD_SCREEN_SY_N(480), - .mode_horztiming = LCD_HORZTIMING_HPW_N(96) | - LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51), - .mode_verttiming = LCD_VERTTIMING_VPW_N(2) | - LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32), - .mode_clkcontrol = 0x00000000, /* /4=24Mhz */ - .mode_pwmdiv = 0x8000063f, - .mode_pwmhi = 0x03400000, - .mode_outmask = 0x00fcfcfc, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ - .device_init = board_au1200fb_panel_init, - .device_shutdown = board_au1200fb_panel_shutdown, - 640, 480, - 640, 480, - }, - - [7] = { /* Sharp 320x240 TFT */ - .name = "Sharp_320x240_TFT", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 12500, - .hfmax = 20000, - .vfmin = 38, - .vfmax = 81, - .dclkmin = 4500000, - .dclkmax = 6800000, - .input = FB_DISP_RGB, - }, - .mode_screen = LCD_SCREEN_SX_N(320) | - LCD_SCREEN_SY_N(240), - .mode_horztiming = LCD_HORZTIMING_HPW_N(60) | - LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2), - .mode_verttiming = LCD_VERTTIMING_VPW_N(2) | - LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5), - .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/ - .mode_pwmdiv = 0x8000063f, - .mode_pwmhi = 0x03400000, - .mode_outmask = 0x00fcfcfc, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ - .device_init = board_au1200fb_panel_init, - .device_shutdown = board_au1200fb_panel_shutdown, - 320, 320, - 240, 240, - }, - - [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */ - .name = "Toppoly_TD070WGCB2", - .monspecs = { - .modedb = NULL, - .modedb_len = 0, - .hfmin = 30000, - .hfmax = 70000, - .vfmin = 60, - .vfmax = 60, - .dclkmin = 6000000, - .dclkmax = 28000000, - .input = FB_DISP_RGB, - }, - .mode_screen = LCD_SCREEN_SX_N(856) | - LCD_SCREEN_SY_N(480), - .mode_horztiming = LCD_HORZTIMING_HND2_N(43) | - LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114), - .mode_verttiming = LCD_VERTTIMING_VND2_N(20) | - LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4), - .mode_clkcontrol = 0x00020001, /* /4=24Mhz */ - .mode_pwmdiv = 0x8000063f, - .mode_pwmhi = 0x03400000, - .mode_outmask = 0x00fcfcfc, - .mode_fifoctrl = 0x2f2f2f2f, - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ - .mode_backlight = 0x00000000, - .mode_auxpll = 8, /* 96MHz AUXPLL */ - .device_init = board_au1200fb_panel_init, - .device_shutdown = board_au1200fb_panel_shutdown, - 856, 856, - 480, 480, - }, -}; - -#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels)) - -/********************************************************************/ - -#ifdef CONFIG_PM -static int set_brightness(unsigned int brightness) -{ - unsigned int hi1, divider; - - /* limit brightness pwm duty to >= 30/1600 */ - if (brightness < 30) { - brightness = 30; - } - divider = (lcd->pwmdiv & 0x3FFFF) + 1; - hi1 = (lcd->pwmhi >> 16) + 1; - hi1 = (((brightness & 0xFF) + 1) * divider >> 8); - lcd->pwmhi &= 0xFFFF; - lcd->pwmhi |= (hi1 << 16); - - return brightness; -} -#endif /* CONFIG_PM */ - -static int winbpp (unsigned int winctrl1) -{ - int bits = 0; - - /* how many bits are needed for each pixel format */ - switch (winctrl1 & LCD_WINCTRL1_FRM) { - case LCD_WINCTRL1_FRM_1BPP: - bits = 1; - break; - case LCD_WINCTRL1_FRM_2BPP: - bits = 2; - break; - case LCD_WINCTRL1_FRM_4BPP: - bits = 4; - break; - case LCD_WINCTRL1_FRM_8BPP: - bits = 8; - break; - case LCD_WINCTRL1_FRM_12BPP: - case LCD_WINCTRL1_FRM_16BPP655: - case LCD_WINCTRL1_FRM_16BPP565: - case LCD_WINCTRL1_FRM_16BPP556: - case LCD_WINCTRL1_FRM_16BPPI1555: - case LCD_WINCTRL1_FRM_16BPPI5551: - case LCD_WINCTRL1_FRM_16BPPA1555: - case LCD_WINCTRL1_FRM_16BPPA5551: - bits = 16; - break; - case LCD_WINCTRL1_FRM_24BPP: - case LCD_WINCTRL1_FRM_32BPP: - bits = 32; - break; - } - - return bits; -} - -static int fbinfo2index (struct fb_info *fb_info) -{ - int i; - - for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) { - if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info)) - return i; - } - printk("au1200fb: ERROR: fbinfo2index failed!\n"); - return -1; -} - -static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, - int xpos, int ypos) -{ - uint32 winctrl0, winctrl1, winenable, fb_offset = 0; - int xsz, ysz; - - /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */ - - winctrl0 = lcd->window[plane].winctrl0; - winctrl1 = lcd->window[plane].winctrl1; - winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN); - winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY); - - /* Check for off-screen adjustments */ - xsz = win->w[plane].xres; - ysz = win->w[plane].yres; - if ((xpos + win->w[plane].xres) > panel->Xres) { - /* Off-screen to the right */ - xsz = panel->Xres - xpos; /* off by 1 ??? */ - /*printk("off screen right\n");*/ - } - - if ((ypos + win->w[plane].yres) > panel->Yres) { - /* Off-screen to the bottom */ - ysz = panel->Yres - ypos; /* off by 1 ??? */ - /*printk("off screen bottom\n");*/ - } - - if (xpos < 0) { - /* Off-screen to the left */ - xsz = win->w[plane].xres + xpos; - fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8); - xpos = 0; - /*printk("off screen left\n");*/ - } - - if (ypos < 0) { - /* Off-screen to the top */ - ysz = win->w[plane].yres + ypos; - /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */ - ypos = 0; - /*printk("off screen top\n");*/ - } - - /* record settings */ - win->w[plane].xpos = xpos; - win->w[plane].ypos = ypos; - - xsz -= 1; - ysz -= 1; - winctrl0 |= (xpos << 21); - winctrl0 |= (ypos << 10); - winctrl1 |= (xsz << 11); - winctrl1 |= (ysz << 0); - - /* Disable the window while making changes, then restore WINEN */ - winenable = lcd->winenable & (1 << plane); - au_sync(); - lcd->winenable &= ~(1 << plane); - lcd->window[plane].winctrl0 = winctrl0; - lcd->window[plane].winctrl1 = winctrl1; - lcd->window[plane].winbuf0 = - lcd->window[plane].winbuf1 = fbdev->fb_phys; - lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ - lcd->winenable |= winenable; - au_sync(); - - return 0; -} - -static void au1200_setpanel (struct panel_settings *newpanel) -{ - /* - * Perform global setup/init of LCD controller - */ - uint32 winenable; - - /* Make sure all windows disabled */ - winenable = lcd->winenable; - lcd->winenable = 0; - au_sync(); - /* - * Ensure everything is disabled before reconfiguring - */ - if (lcd->screen & LCD_SCREEN_SEN) { - /* Wait for vertical sync period */ - lcd->intstatus = LCD_INT_SS; - while ((lcd->intstatus & LCD_INT_SS) == 0) { - au_sync(); - } - - lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ - - do { - lcd->intstatus = lcd->intstatus; /*clear interrupts*/ - au_sync(); - /*wait for controller to shut down*/ - } while ((lcd->intstatus & LCD_INT_SD) == 0); - - /* Call shutdown of current panel (if up) */ - /* this must occur last, because if an external clock is driving - the controller, the clock cannot be turned off before first - shutting down the controller. - */ - if (panel->device_shutdown != NULL) - panel->device_shutdown(); - } - - /* Newpanel == NULL indicates a shutdown operation only */ - if (newpanel == NULL) - return; - - panel = newpanel; - - printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres); - - /* - * Setup clocking if internal LCD clock source (assumes sys_auxpll valid) - */ - if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) - { - uint32 sys_clksrc; - au_writel(panel->mode_auxpll, SYS_AUXPLL); - sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f; - sys_clksrc |= panel->mode_toyclksrc; - au_writel(sys_clksrc, SYS_CLKSRC); - } - - /* - * Configure panel timings - */ - lcd->screen = panel->mode_screen; - lcd->horztiming = panel->mode_horztiming; - lcd->verttiming = panel->mode_verttiming; - lcd->clkcontrol = panel->mode_clkcontrol; - lcd->pwmdiv = panel->mode_pwmdiv; - lcd->pwmhi = panel->mode_pwmhi; - lcd->outmask = panel->mode_outmask; - lcd->fifoctrl = panel->mode_fifoctrl; - au_sync(); - - /* fixme: Check window settings to make sure still valid - * for new geometry */ -#if 0 - au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos); - au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos); - au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos); - au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos); -#endif - lcd->winenable = winenable; - - /* - * Re-enable screen now that it is configured - */ - lcd->screen |= LCD_SCREEN_SEN; - au_sync(); - - /* Call init of panel */ - if (panel->device_init != NULL) panel->device_init(); - - /* FIX!!!! not appropriate on panel change!!! Global setup/init */ - lcd->intenable = 0; - lcd->intstatus = ~0; - lcd->backcolor = win->mode_backcolor; - - /* Setup Color Key - FIX!!! */ - lcd->colorkey = win->mode_colorkey; - lcd->colorkeymsk = win->mode_colorkeymsk; - - /* Setup HWCursor - FIX!!! Need to support this eventually */ - lcd->hwc.cursorctrl = 0; - lcd->hwc.cursorpos = 0; - lcd->hwc.cursorcolor0 = 0; - lcd->hwc.cursorcolor1 = 0; - lcd->hwc.cursorcolor2 = 0; - lcd->hwc.cursorcolor3 = 0; - - -#if 0 -#define D(X) printk("%25s: %08X\n", #X, X) - D(lcd->screen); - D(lcd->horztiming); - D(lcd->verttiming); - D(lcd->clkcontrol); - D(lcd->pwmdiv); - D(lcd->pwmhi); - D(lcd->outmask); - D(lcd->fifoctrl); - D(lcd->window[0].winctrl0); - D(lcd->window[0].winctrl1); - D(lcd->window[0].winctrl2); - D(lcd->window[0].winbuf0); - D(lcd->window[0].winbuf1); - D(lcd->window[0].winbufctrl); - D(lcd->window[1].winctrl0); - D(lcd->window[1].winctrl1); - D(lcd->window[1].winctrl2); - D(lcd->window[1].winbuf0); - D(lcd->window[1].winbuf1); - D(lcd->window[1].winbufctrl); - D(lcd->window[2].winctrl0); - D(lcd->window[2].winctrl1); - D(lcd->window[2].winctrl2); - D(lcd->window[2].winbuf0); - D(lcd->window[2].winbuf1); - D(lcd->window[2].winbufctrl); - D(lcd->window[3].winctrl0); - D(lcd->window[3].winctrl1); - D(lcd->window[3].winctrl2); - D(lcd->window[3].winbuf0); - D(lcd->window[3].winbuf1); - D(lcd->window[3].winbufctrl); - D(lcd->winenable); - D(lcd->intenable); - D(lcd->intstatus); - D(lcd->backcolor); - D(lcd->winenable); - D(lcd->colorkey); - D(lcd->colorkeymsk); - D(lcd->hwc.cursorctrl); - D(lcd->hwc.cursorpos); - D(lcd->hwc.cursorcolor0); - D(lcd->hwc.cursorcolor1); - D(lcd->hwc.cursorcolor2); - D(lcd->hwc.cursorcolor3); -#endif -} - -static void au1200_setmode(struct au1200fb_device *fbdev) -{ - int plane = fbdev->plane; - /* Window/plane setup */ - lcd->window[plane].winctrl1 = ( 0 - | LCD_WINCTRL1_PRI_N(plane) - | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */ - ) ; - - au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos); - - lcd->window[plane].winctrl2 = ( 0 - | LCD_WINCTRL2_CKMODE_00 - | LCD_WINCTRL2_DBM - | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length) - | LCD_WINCTRL2_SCX_1 - | LCD_WINCTRL2_SCY_1 - ) ; - lcd->winenable |= win->w[plane].mode_winenable; - au_sync(); -} - - -/* Inline helpers */ - -/*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/ -/*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/ - -#define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN) - -/* Bitfields format supported by the controller. */ -static struct fb_bitfield rgb_bitfields[][4] = { - /* Red, Green, Blue, Transp */ - [LCD_WINCTRL1_FRM_16BPP655 >> 25] = - { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, - - [LCD_WINCTRL1_FRM_16BPP565 >> 25] = - { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, - - [LCD_WINCTRL1_FRM_16BPP556 >> 25] = - { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } }, - - [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] = - { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, - - [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] = - { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } }, - - [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] = - { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } }, - - [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] = - { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } }, - - [LCD_WINCTRL1_FRM_24BPP >> 25] = - { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } }, - - [LCD_WINCTRL1_FRM_32BPP >> 25] = - { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } }, -}; - -/*-------------------------------------------------------------------------*/ - -/* Helpers */ - -static void au1200fb_update_fbinfo(struct fb_info *fbi) -{ - /* FIX!!!! This also needs to take the window pixel format into account!!! */ - - /* Update var-dependent FB info */ - if (panel_is_color(panel)) { - if (fbi->var.bits_per_pixel <= 8) { - /* palettized */ - fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR; - fbi->fix.line_length = fbi->var.xres_virtual / - (8/fbi->var.bits_per_pixel); - } else { - /* non-palettized */ - fbi->fix.visual = FB_VISUAL_TRUECOLOR; - fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8); - } - } else { - /* mono FIX!!! mono 8 and 4 bits */ - fbi->fix.visual = FB_VISUAL_MONO10; - fbi->fix.line_length = fbi->var.xres_virtual / 8; - } - - fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual; - print_dbg("line length: %d\n", fbi->fix.line_length); - print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel); -} - -/*-------------------------------------------------------------------------*/ - -/* AU1200 framebuffer driver */ - -/* fb_check_var - * Validate var settings with hardware restrictions and modify it if necessary - */ -static int au1200fb_fb_check_var(struct fb_var_screeninfo *var, - struct fb_info *fbi) -{ - struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi; - u32 pixclock; - int screen_size, plane; - - plane = fbdev->plane; - - /* Make sure that the mode respect all LCD controller and - * panel restrictions. */ - var->xres = win->w[plane].xres; - var->yres = win->w[plane].yres; - - /* No need for virtual resolution support */ - var->xres_virtual = var->xres; - var->yres_virtual = var->yres; - - var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1); - - screen_size = var->xres_virtual * var->yres_virtual; - if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8); - else screen_size /= (8/var->bits_per_pixel); - - if (fbdev->fb_len < screen_size) - return -EINVAL; /* Virtual screen is to big, abort */ - - /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */ - /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel - * clock can only be obtain by dividing this value by an even integer. - * Fallback to a slower pixel clock if necessary. */ - pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin); - pixclock = min(pixclock, min(fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2)); - - if (AU1200_LCD_MAX_CLK % pixclock) { - int diff = AU1200_LCD_MAX_CLK % pixclock; - pixclock -= diff; - } - - var->pixclock = KHZ2PICOS(pixclock/1000); -#if 0 - if (!panel_is_active(panel)) { - int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1; - - if (!panel_is_color(panel) - && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) { - /* STN 8bit mono panel support is up to 6MHz pixclock */ - var->pixclock = KHZ2PICOS(6000); - } else if (!pcd) { - /* Other STN panel support is up to 12MHz */ - var->pixclock = KHZ2PICOS(12000); - } - } -#endif - /* Set bitfield accordingly */ - switch (var->bits_per_pixel) { - case 16: - { - /* 16bpp True color. - * These must be set to MATCH WINCTRL[FORM] */ - int idx; - idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25; - var->red = rgb_bitfields[idx][0]; - var->green = rgb_bitfields[idx][1]; - var->blue = rgb_bitfields[idx][2]; - var->transp = rgb_bitfields[idx][3]; - break; - } - - case 32: - { - /* 32bpp True color. - * These must be set to MATCH WINCTRL[FORM] */ - int idx; - idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25; - var->red = rgb_bitfields[idx][0]; - var->green = rgb_bitfields[idx][1]; - var->blue = rgb_bitfields[idx][2]; - var->transp = rgb_bitfields[idx][3]; - break; - } - default: - print_dbg("Unsupported depth %dbpp", var->bits_per_pixel); - return -EINVAL; - } - - return 0; -} - -/* fb_set_par - * Set hardware with var settings. This will enable the controller with a - * specific mode, normally validated with the fb_check_var method - */ -static int au1200fb_fb_set_par(struct fb_info *fbi) -{ - struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi; - - au1200fb_update_fbinfo(fbi); - au1200_setmode(fbdev); - - return 0; -} - -/* fb_setcolreg - * Set color in LCD palette. - */ -static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, struct fb_info *fbi) -{ - volatile u32 *palette = lcd->palette; - u32 value; - - if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1)) - return -EINVAL; - - if (fbi->var.grayscale) { - /* Convert color to grayscale */ - red = green = blue = - (19595 * red + 38470 * green + 7471 * blue) >> 16; - } - - if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) { - /* Place color in the pseudopalette */ - if (regno > 16) - return -EINVAL; - - palette = (u32*) fbi->pseudo_palette; - - red >>= (16 - fbi->var.red.length); - green >>= (16 - fbi->var.green.length); - blue >>= (16 - fbi->var.blue.length); - - value = (red << fbi->var.red.offset) | - (green << fbi->var.green.offset)| - (blue << fbi->var.blue.offset); - value &= 0xFFFF; - - } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) { - /* COLOR TFT PALLETTIZED (use RGB 565) */ - value = (red & 0xF800)|((green >> 5) & - 0x07E0)|((blue >> 11) & 0x001F); - value &= 0xFFFF; - - } else if (0 /*panel_is_color(fbdev->panel)*/) { - /* COLOR STN MODE */ - value = 0x1234; - value &= 0xFFF; - } else { - /* MONOCHROME MODE */ - value = (green >> 12) & 0x000F; - value &= 0xF; - } - - palette[regno] = value; - - return 0; -} - -/* fb_blank - * Blank the screen. Depending on the mode, the screen will be - * activated with the backlight color, or desactivated - */ -static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi) -{ - /* Short-circuit screen blanking */ - if (noblanking) - return 0; - - switch (blank_mode) { - - case FB_BLANK_UNBLANK: - case FB_BLANK_NORMAL: - /* printk("turn on panel\n"); */ - au1200_setpanel(panel); - break; - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_POWERDOWN: - /* printk("turn off panel\n"); */ - au1200_setpanel(NULL); - break; - default: - break; - - } - - /* FB_BLANK_NORMAL is a soft blank */ - return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0; -} - -/* fb_mmap - * Map video memory in user space. We don't use the generic fb_mmap - * method mainly to allow the use of the TLB streaming flag (CCA=6) - */ -static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) - -{ - unsigned int len; - unsigned long start=0, off; - struct au1200fb_device *fbdev = (struct au1200fb_device *) info; - -#ifdef CONFIG_PM - au1xxx_pm_access(LCD_pm_dev); -#endif - - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { - return -EINVAL; - } - - start = fbdev->fb_phys & PAGE_MASK; - len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); - - off = vma->vm_pgoff << PAGE_SHIFT; - - if ((vma->vm_end - vma->vm_start + off) > len) { - return -EINVAL; - } - - off += start; - vma->vm_pgoff = off >> PAGE_SHIFT; - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ - - vma->vm_flags |= VM_IO; - - return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); - - return 0; -} - -static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) -{ - - unsigned int hi1, divider; - - /* SCREEN_SIZE: user cannot reset size, must switch panel choice */ - - if (pdata->flags & SCREEN_BACKCOLOR) - lcd->backcolor = pdata->backcolor; - - if (pdata->flags & SCREEN_BRIGHTNESS) { - - // limit brightness pwm duty to >= 30/1600 - if (pdata->brightness < 30) { - pdata->brightness = 30; - } - divider = (lcd->pwmdiv & 0x3FFFF) + 1; - hi1 = (lcd->pwmhi >> 16) + 1; - hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8); - lcd->pwmhi &= 0xFFFF; - lcd->pwmhi |= (hi1 << 16); - } - - if (pdata->flags & SCREEN_COLORKEY) - lcd->colorkey = pdata->colorkey; - - if (pdata->flags & SCREEN_MASK) - lcd->colorkeymsk = pdata->mask; - au_sync(); -} - -static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) -{ - unsigned int hi1, divider; - - pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1; - pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1; - - pdata->backcolor = lcd->backcolor; - pdata->colorkey = lcd->colorkey; - pdata->mask = lcd->colorkeymsk; - - // brightness - hi1 = (lcd->pwmhi >> 16) + 1; - divider = (lcd->pwmdiv & 0x3FFFF) + 1; - pdata->brightness = ((hi1 << 8) / divider) - 1; - au_sync(); -} - -static void set_window(unsigned int plane, - struct au1200_lcd_window_regs_t *pdata) -{ - unsigned int val, bpp; - - /* Window control register 0 */ - if (pdata->flags & WIN_POSITION) { - val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX | - LCD_WINCTRL0_OY); - val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX); - val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY); - lcd->window[plane].winctrl0 = val; - } - if (pdata->flags & WIN_ALPHA_COLOR) { - val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A); - val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A); - lcd->window[plane].winctrl0 = val; - } - if (pdata->flags & WIN_ALPHA_MODE) { - val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN); - val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN); - lcd->window[plane].winctrl0 = val; - } - - /* Window control register 1 */ - if (pdata->flags & WIN_PRIORITY) { - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI); - val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI); - lcd->window[plane].winctrl1 = val; - } - if (pdata->flags & WIN_CHANNEL) { - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE); - val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE); - lcd->window[plane].winctrl1 = val; - } - if (pdata->flags & WIN_BUFFER_FORMAT) { - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM); - val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM); - lcd->window[plane].winctrl1 = val; - } - if (pdata->flags & WIN_COLOR_ORDER) { - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO); - val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO); - lcd->window[plane].winctrl1 = val; - } - if (pdata->flags & WIN_PIXEL_ORDER) { - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO); - val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO); - lcd->window[plane].winctrl1 = val; - } - if (pdata->flags & WIN_SIZE) { - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX | - LCD_WINCTRL1_SZY); - val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX); - val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY); - lcd->window[plane].winctrl1 = val; - /* program buffer line width */ - bpp = winbpp(val) / 8; - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX); - val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX); - lcd->window[plane].winctrl2 = val; - } - - /* Window control register 2 */ - if (pdata->flags & WIN_COLORKEY_MODE) { - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE); - val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE); - lcd->window[plane].winctrl2 = val; - } - if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) { - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM); - val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM); - lcd->window[plane].winctrl2 = val; - } - if (pdata->flags & WIN_RAM_ARRAY_MODE) { - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM); - val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM); - lcd->window[plane].winctrl2 = val; - } - - /* Buffer line width programmed with WIN_SIZE */ - - if (pdata->flags & WIN_BUFFER_SCALE) { - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX | - LCD_WINCTRL2_SCY); - val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX); - val |= ((pdata->ysize) & LCD_WINCTRL2_SCY); - lcd->window[plane].winctrl2 = val; - } - - if (pdata->flags & WIN_ENABLE) { - val = lcd->winenable; - val &= ~(1<enable & 1) << plane; - lcd->winenable = val; - } - au_sync(); -} - -static void get_window(unsigned int plane, - struct au1200_lcd_window_regs_t *pdata) -{ - /* Window control register 0 */ - pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21; - pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10; - pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2; - pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1; - - /* Window control register 1 */ - pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30; - pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29; - pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25; - pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24; - pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22; - pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1; - pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1; - - /* Window control register 2 */ - pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24; - pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23; - pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; - - pdata->enable = (lcd->winenable >> plane) & 1; - au_sync(); -} - -static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) -{ - int plane; - int val; - -#ifdef CONFIG_PM - au1xxx_pm_access(LCD_pm_dev); -#endif - - plane = fbinfo2index(info); - print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane); - - if (cmd == AU1200_LCD_FB_IOCTL) { - struct au1200_lcd_iodata_t iodata; - - if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata))) - return -EFAULT; - - print_dbg("FB IOCTL called\n"); - - switch (iodata.subcmd) { - case AU1200_LCD_SET_SCREEN: - print_dbg("AU1200_LCD_SET_SCREEN\n"); - set_global(cmd, &iodata.global); - break; - - case AU1200_LCD_GET_SCREEN: - print_dbg("AU1200_LCD_GET_SCREEN\n"); - get_global(cmd, &iodata.global); - break; - - case AU1200_LCD_SET_WINDOW: - print_dbg("AU1200_LCD_SET_WINDOW\n"); - set_window(plane, &iodata.window); - break; - - case AU1200_LCD_GET_WINDOW: - print_dbg("AU1200_LCD_GET_WINDOW\n"); - get_window(plane, &iodata.window); - break; - - case AU1200_LCD_SET_PANEL: - print_dbg("AU1200_LCD_SET_PANEL\n"); - if ((iodata.global.panel_choice >= 0) && - (iodata.global.panel_choice < - NUM_PANELS)) - { - struct panel_settings *newpanel; - panel_index = iodata.global.panel_choice; - newpanel = &known_lcd_panels[panel_index]; - au1200_setpanel(newpanel); - } - break; - - case AU1200_LCD_GET_PANEL: - print_dbg("AU1200_LCD_GET_PANEL\n"); - iodata.global.panel_choice = panel_index; - break; - - default: - return -EINVAL; - } - - val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata)); - if (val) { - print_dbg("error: could not copy %d bytes\n", val); - return -EFAULT; - } - } - - return 0; -} - - -static struct fb_ops au1200fb_fb_ops = { - .owner = THIS_MODULE, - .fb_check_var = au1200fb_fb_check_var, - .fb_set_par = au1200fb_fb_set_par, - .fb_setcolreg = au1200fb_fb_setcolreg, - .fb_blank = au1200fb_fb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_sync = NULL, - .fb_ioctl = au1200fb_ioctl, - .fb_mmap = au1200fb_fb_mmap, -}; - -/*-------------------------------------------------------------------------*/ - -static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs) -{ - /* Nothing to do for now, just clear any pending interrupt */ - lcd->intstatus = lcd->intstatus; - au_sync(); - - return IRQ_HANDLED; -} - -/*-------------------------------------------------------------------------*/ - -/* AU1200 LCD device probe helpers */ - -static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) -{ - struct fb_info *fbi = &fbdev->fb_info; - int bpp; - - memset(fbi, 0, sizeof(struct fb_info)); - fbi->fbops = &au1200fb_fb_ops; - - bpp = winbpp(win->w[fbdev->plane].mode_winctrl1); - - /* Copy monitor specs from panel data */ - /* fixme: we're setting up LCD controller windows, so these dont give a - damn as to what the monitor specs are (the panel itself does, but that - isnt done here...so maybe need a generic catchall monitor setting??? */ - memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs)); - - /* We first try the user mode passed in argument. If that failed, - * or if no one has been specified, we default to the first mode of the - * panel list. Note that after this call, var data will be set */ - if (!fb_find_mode(&fbi->var, - fbi, - NULL, /* drv_info.opt_mode, */ - fbi->monspecs.modedb, - fbi->monspecs.modedb_len, - fbi->monspecs.modedb, - bpp)) { - - print_err("Cannot find valid mode for panel %s", panel->name); - return -EFAULT; - } - - fbi->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); - if (!fbi->pseudo_palette) { - return -ENOMEM; - } - memset(fbi->pseudo_palette, 0, sizeof(u32) * 16); - - if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { - print_err("Fail to allocate colormap (%d entries)", - AU1200_LCD_NBR_PALETTE_ENTRIES); - kfree(fbi->pseudo_palette); - return -EFAULT; - } - - strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id)); - fbi->fix.smem_start = fbdev->fb_phys; - fbi->fix.smem_len = fbdev->fb_len; - fbi->fix.type = FB_TYPE_PACKED_PIXELS; - fbi->fix.xpanstep = 0; - fbi->fix.ypanstep = 0; - fbi->fix.mmio_start = 0; - fbi->fix.mmio_len = 0; - fbi->fix.accel = FB_ACCEL_NONE; - - fbi->screen_base = (char __iomem *) fbdev->fb_mem; - - au1200fb_update_fbinfo(fbi); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* AU1200 LCD controller device driver */ - -static int au1200fb_drv_probe(struct device *dev) -{ - struct au1200fb_device *fbdev; - unsigned long page; - int bpp, plane, ret; - - if (!dev) - return -EINVAL; - - for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) { - bpp = winbpp(win->w[plane].mode_winctrl1); - if (win->w[plane].xres == 0) - win->w[plane].xres = panel->Xres; - if (win->w[plane].yres == 0) - win->w[plane].yres = panel->Yres; - - fbdev = &_au1200fb_devices[plane]; - memset(fbdev, 0, sizeof(struct au1200fb_device)); - fbdev->plane = plane; - - /* Allocate the framebuffer to the maximum screen size */ - fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; - - fbdev->fb_mem = dma_alloc_noncoherent(dev, - PAGE_ALIGN(fbdev->fb_len), - &fbdev->fb_phys, GFP_KERNEL); - if (!fbdev->fb_mem) { - print_err("fail to allocate frambuffer (size: %dK))", - fbdev->fb_len / 1024); - return -ENOMEM; - } - - /* - * Set page reserved so that mmap will work. This is necessary - * since we'll be remapping normal memory. - */ - for (page = (unsigned long)fbdev->fb_phys; - page < PAGE_ALIGN((unsigned long)fbdev->fb_phys + - fbdev->fb_len); - page += PAGE_SIZE) { - SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */ - } - print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); - print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); - - /* Init FB data */ - if ((ret = au1200fb_init_fbinfo(fbdev)) < 0) - goto failed; - - /* Register new framebuffer */ - if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) { - print_err("cannot register new framebuffer"); - goto failed; - } - - au1200fb_fb_set_par(&fbdev->fb_info); - -#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) - if (plane == 0) - if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) { - /* Start display and show logo on boot */ - fb_set_cmap(&fbdev->fb_info.cmap, - &fbdev->fb_info); - - fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR); - } -#endif - } - - /* Now hook interrupt too */ - if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq, - SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) { - print_err("fail to request interrupt line %d (err: %d)", - AU1200_LCD_INT, ret); - goto failed; - } - - return 0; - -failed: - /* NOTE: This only does the current plane/window that failed; others are still active */ - if (fbdev->fb_mem) - dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), - fbdev->fb_mem, fbdev->fb_phys); - if (fbdev->fb_info.cmap.len != 0) - fb_dealloc_cmap(&fbdev->fb_info.cmap); - if (fbdev->fb_info.pseudo_palette) - kfree(fbdev->fb_info.pseudo_palette); - if (plane == 0) - free_irq(AU1200_LCD_INT, (void*)dev); - return ret; -} - -static int au1200fb_drv_remove(struct device *dev) -{ - struct au1200fb_device *fbdev; - int plane; - - if (!dev) - return -ENODEV; - - /* Turn off the panel */ - au1200_setpanel(NULL); - - for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) - { - fbdev = &_au1200fb_devices[plane]; - - /* Clean up all probe data */ - unregister_framebuffer(&fbdev->fb_info); - if (fbdev->fb_mem) - dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), - fbdev->fb_mem, fbdev->fb_phys); - if (fbdev->fb_info.cmap.len != 0) - fb_dealloc_cmap(&fbdev->fb_info.cmap); - if (fbdev->fb_info.pseudo_palette) - kfree(fbdev->fb_info.pseudo_palette); - } - - free_irq(AU1200_LCD_INT, (void *)dev); - - return 0; -} - -#ifdef CONFIG_PM -static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level) -{ - /* TODO */ - return 0; -} - -static int au1200fb_drv_resume(struct device *dev, u32 level) -{ - /* TODO */ - return 0; -} -#endif /* CONFIG_PM */ - -static struct device_driver au1200fb_driver = { - .name = "au1200-lcd", - .bus = &platform_bus_type, - .probe = au1200fb_drv_probe, - .remove = au1200fb_drv_remove, -#ifdef CONFIG_PM - .suspend = au1200fb_drv_suspend, - .resume = au1200fb_drv_resume, -#endif -}; - -/*-------------------------------------------------------------------------*/ - -/* Kernel driver */ - -static void au1200fb_setup(void) -{ - char* options = NULL; - char* this_opt; - int num_panels = ARRAY_SIZE(known_lcd_panels); - int panel_idx = -1; - - fb_get_options(DRIVER_NAME, &options); - - if (options) { - while ((this_opt = strsep(&options,",")) != NULL) { - /* Panel option - can be panel name, - * "bs" for board-switch, or number/index */ - if (!strncmp(this_opt, "panel:", 6)) { - int i; - long int li; - char *endptr; - this_opt += 6; - /* First check for index, which allows - * to short circuit this mess */ - li = simple_strtol(this_opt, &endptr, 0); - if (*endptr == '\0') { - panel_idx = (int)li; - } - else if (strcmp(this_opt, "bs") == 0) { - extern int board_au1200fb_panel(void); - panel_idx = board_au1200fb_panel(); - } - - else - for (i = 0; i < num_panels; i++) { - if (!strcmp(this_opt, known_lcd_panels[i].name)) { - panel_idx = i; - break; - } - } - - if ((panel_idx < 0) || (panel_idx >= num_panels)) { - print_warn("Panel %s not supported!", this_opt); - } - else - panel_index = panel_idx; - } - - else if (strncmp(this_opt, "nohwcursor", 10) == 0) { - nohwcursor = 1; - } - - /* Unsupported option */ - else { - print_warn("Unsupported option \"%s\"", this_opt); - } - } - } -} - -#ifdef CONFIG_PM -static int au1200fb_pm_callback(au1xxx_power_dev_t *dev, - au1xxx_request_t request, void *data) { - int retval = -1; - unsigned int d = 0; - unsigned int brightness = 0; - - if (request == AU1XXX_PM_SLEEP) { - board_au1200fb_panel_shutdown(); - } - else if (request == AU1XXX_PM_WAKEUP) { - if(dev->prev_state == SLEEP_STATE) - { - int plane; - au1200_setpanel(panel); - for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) { - struct au1200fb_device *fbdev; - fbdev = &_au1200fb_devices[plane]; - au1200fb_fb_set_par(&fbdev->fb_info); - } - } - - d = *((unsigned int*)data); - if(d <=10) brightness = 26; - else if(d<=20) brightness = 51; - else if(d<=30) brightness = 77; - else if(d<=40) brightness = 102; - else if(d<=50) brightness = 128; - else if(d<=60) brightness = 153; - else if(d<=70) brightness = 179; - else if(d<=80) brightness = 204; - else if(d<=90) brightness = 230; - else brightness = 255; - set_brightness(brightness); - } else if (request == AU1XXX_PM_GETSTATUS) { - return dev->cur_state; - } else if (request == AU1XXX_PM_ACCESS) { - if (dev->cur_state != SLEEP_STATE) - return retval; - else { - au1200_setpanel(panel); - } - } else if (request == AU1XXX_PM_IDLE) { - } else if (request == AU1XXX_PM_CLEANUP) { - } - - return retval; -} -#endif - -static int __init au1200fb_init(void) -{ - print_info("" DRIVER_DESC ""); - - /* Setup driver with options */ - au1200fb_setup(); - - /* Point to the panel selected */ - panel = &known_lcd_panels[panel_index]; - win = &windows[window_index]; - - printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name); - printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name); - - /* Kickstart the panel, the framebuffers/windows come soon enough */ - au1200_setpanel(panel); - - #ifdef CONFIG_PM - LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL); - if ( LCD_pm_dev == NULL) - printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n"); - else - printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n"); - #endif - - return driver_register(&au1200fb_driver); -} - -static void __exit au1200fb_cleanup(void) -{ - driver_unregister(&au1200fb_driver); -} - -module_init(au1200fb_init); -module_exit(au1200fb_cleanup); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/au1200fb.h b/drivers/video/au1200fb.h deleted file mode 100644 index e2672714d..000000000 --- a/drivers/video/au1200fb.h +++ /dev/null @@ -1,572 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Hardware definitions for the Au1200 LCD controller - * - * Copyright 2004 AMD - * Author: AMD - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _AU1200LCD_H -#define _AU1200LCD_H - -/********************************************************************/ -#define AU1200_LCD_ADDR 0xB5000000 - -#define uint8 unsigned char -#define uint32 unsigned int - -struct au1200_lcd { - volatile uint32 reserved0; - volatile uint32 screen; - volatile uint32 backcolor; - volatile uint32 horztiming; - volatile uint32 verttiming; - volatile uint32 clkcontrol; - volatile uint32 pwmdiv; - volatile uint32 pwmhi; - volatile uint32 reserved1; - volatile uint32 winenable; - volatile uint32 colorkey; - volatile uint32 colorkeymsk; - struct - { - volatile uint32 cursorctrl; - volatile uint32 cursorpos; - volatile uint32 cursorcolor0; - volatile uint32 cursorcolor1; - volatile uint32 cursorcolor2; - uint32 cursorcolor3; - } hwc; - volatile uint32 intstatus; - volatile uint32 intenable; - volatile uint32 outmask; - volatile uint32 fifoctrl; - uint32 reserved2[(0x0100-0x0058)/4]; - struct - { - volatile uint32 winctrl0; - volatile uint32 winctrl1; - volatile uint32 winctrl2; - volatile uint32 winbuf0; - volatile uint32 winbuf1; - volatile uint32 winbufctrl; - uint32 winreserved0; - uint32 winreserved1; - } window[4]; - - uint32 reserved3[(0x0400-0x0180)/4]; - - volatile uint32 palette[(0x0800-0x0400)/4]; - - volatile uint8 cursorpattern[256]; -}; - -/* lcd_screen */ -#define LCD_SCREEN_SEN (1<<31) -#define LCD_SCREEN_SX (0x07FF<<19) -#define LCD_SCREEN_SY (0x07FF<< 8) -#define LCD_SCREEN_SWP (1<<7) -#define LCD_SCREEN_SWD (1<<6) -#define LCD_SCREEN_PT (7<<0) -#define LCD_SCREEN_PT_TFT (0<<0) -#define LCD_SCREEN_SX_N(WIDTH) ((WIDTH-1)<<19) -#define LCD_SCREEN_SY_N(HEIGHT) ((HEIGHT-1)<<8) -#define LCD_SCREEN_PT_CSTN (1<<0) -#define LCD_SCREEN_PT_CDSTN (2<<0) -#define LCD_SCREEN_PT_M8STN (3<<0) -#define LCD_SCREEN_PT_M4STN (4<<0) - -/* lcd_backcolor */ -#define LCD_BACKCOLOR_SBGR (0xFF<<16) -#define LCD_BACKCOLOR_SBGG (0xFF<<8) -#define LCD_BACKCOLOR_SBGB (0xFF<<0) -#define LCD_BACKCOLOR_SBGR_N(N) ((N)<<16) -#define LCD_BACKCOLOR_SBGG_N(N) ((N)<<8) -#define LCD_BACKCOLOR_SBGB_N(N) ((N)<<0) - -/* lcd_winenable */ -#define LCD_WINENABLE_WEN3 (1<<3) -#define LCD_WINENABLE_WEN2 (1<<2) -#define LCD_WINENABLE_WEN1 (1<<1) -#define LCD_WINENABLE_WEN0 (1<<0) - -/* lcd_colorkey */ -#define LCD_COLORKEY_CKR (0xFF<<16) -#define LCD_COLORKEY_CKG (0xFF<<8) -#define LCD_COLORKEY_CKB (0xFF<<0) -#define LCD_COLORKEY_CKR_N(N) ((N)<<16) -#define LCD_COLORKEY_CKG_N(N) ((N)<<8) -#define LCD_COLORKEY_CKB_N(N) ((N)<<0) - -/* lcd_colorkeymsk */ -#define LCD_COLORKEYMSK_CKMR (0xFF<<16) -#define LCD_COLORKEYMSK_CKMG (0xFF<<8) -#define LCD_COLORKEYMSK_CKMB (0xFF<<0) -#define LCD_COLORKEYMSK_CKMR_N(N) ((N)<<16) -#define LCD_COLORKEYMSK_CKMG_N(N) ((N)<<8) -#define LCD_COLORKEYMSK_CKMB_N(N) ((N)<<0) - -/* lcd windows control 0 */ -#define LCD_WINCTRL0_OX (0x07FF<<21) -#define LCD_WINCTRL0_OY (0x07FF<<10) -#define LCD_WINCTRL0_A (0x00FF<<2) -#define LCD_WINCTRL0_AEN (1<<1) -#define LCD_WINCTRL0_OX_N(N) ((N)<<21) -#define LCD_WINCTRL0_OY_N(N) ((N)<<10) -#define LCD_WINCTRL0_A_N(N) ((N)<<2) - -/* lcd windows control 1 */ -#define LCD_WINCTRL1_PRI (3<<30) -#define LCD_WINCTRL1_PIPE (1<<29) -#define LCD_WINCTRL1_FRM (0xF<<25) -#define LCD_WINCTRL1_CCO (1<<24) -#define LCD_WINCTRL1_PO (3<<22) -#define LCD_WINCTRL1_SZX (0x07FF<<11) -#define LCD_WINCTRL1_SZY (0x07FF<<0) -#define LCD_WINCTRL1_FRM_1BPP (0<<25) -#define LCD_WINCTRL1_FRM_2BPP (1<<25) -#define LCD_WINCTRL1_FRM_4BPP (2<<25) -#define LCD_WINCTRL1_FRM_8BPP (3<<25) -#define LCD_WINCTRL1_FRM_12BPP (4<<25) -#define LCD_WINCTRL1_FRM_16BPP655 (5<<25) -#define LCD_WINCTRL1_FRM_16BPP565 (6<<25) -#define LCD_WINCTRL1_FRM_16BPP556 (7<<25) -#define LCD_WINCTRL1_FRM_16BPPI1555 (8<<25) -#define LCD_WINCTRL1_FRM_16BPPI5551 (9<<25) -#define LCD_WINCTRL1_FRM_16BPPA1555 (10<<25) -#define LCD_WINCTRL1_FRM_16BPPA5551 (11<<25) -#define LCD_WINCTRL1_FRM_24BPP (12<<25) -#define LCD_WINCTRL1_FRM_32BPP (13<<25) -#define LCD_WINCTRL1_PRI_N(N) ((N)<<30) -#define LCD_WINCTRL1_PO_00 (0<<22) -#define LCD_WINCTRL1_PO_01 (1<<22) -#define LCD_WINCTRL1_PO_10 (2<<22) -#define LCD_WINCTRL1_PO_11 (3<<22) -#define LCD_WINCTRL1_SZX_N(N) ((N-1)<<11) -#define LCD_WINCTRL1_SZY_N(N) ((N-1)<<0) - -/* lcd windows control 2 */ -#define LCD_WINCTRL2_CKMODE (3<<24) -#define LCD_WINCTRL2_DBM (1<<23) -#define LCD_WINCTRL2_RAM (3<<21) -#define LCD_WINCTRL2_BX (0x1FFF<<8) -#define LCD_WINCTRL2_SCX (0xF<<4) -#define LCD_WINCTRL2_SCY (0xF<<0) -#define LCD_WINCTRL2_CKMODE_00 (0<<24) -#define LCD_WINCTRL2_CKMODE_01 (1<<24) -#define LCD_WINCTRL2_CKMODE_10 (2<<24) -#define LCD_WINCTRL2_CKMODE_11 (3<<24) -#define LCD_WINCTRL2_RAM_NONE (0<<21) -#define LCD_WINCTRL2_RAM_PALETTE (1<<21) -#define LCD_WINCTRL2_RAM_GAMMA (2<<21) -#define LCD_WINCTRL2_RAM_BUFFER (3<<21) -#define LCD_WINCTRL2_BX_N(N) ((N)<<8) -#define LCD_WINCTRL2_SCX_1 (0<<4) -#define LCD_WINCTRL2_SCX_2 (1<<4) -#define LCD_WINCTRL2_SCX_4 (2<<4) -#define LCD_WINCTRL2_SCY_1 (0<<0) -#define LCD_WINCTRL2_SCY_2 (1<<0) -#define LCD_WINCTRL2_SCY_4 (2<<0) - -/* lcd windows buffer control */ -#define LCD_WINBUFCTRL_DB (1<<1) -#define LCD_WINBUFCTRL_DBN (1<<0) - -/* lcd_intstatus, lcd_intenable */ -#define LCD_INT_IFO (0xF<<14) -#define LCD_INT_IFU (0xF<<10) -#define LCD_INT_OFO (1<<9) -#define LCD_INT_OFU (1<<8) -#define LCD_INT_WAIT (1<<3) -#define LCD_INT_SD (1<<2) -#define LCD_INT_SA (1<<1) -#define LCD_INT_SS (1<<0) - -/* lcd_horztiming */ -#define LCD_HORZTIMING_HND2 (0x1FF<<18) -#define LCD_HORZTIMING_HND1 (0x1FF<<9) -#define LCD_HORZTIMING_HPW (0x1FF<<0) -#define LCD_HORZTIMING_HND2_N(N)(((N)-1)<<18) -#define LCD_HORZTIMING_HND1_N(N)(((N)-1)<<9) -#define LCD_HORZTIMING_HPW_N(N) (((N)-1)<<0) - -/* lcd_verttiming */ -#define LCD_VERTTIMING_VND2 (0x1FF<<18) -#define LCD_VERTTIMING_VND1 (0x1FF<<9) -#define LCD_VERTTIMING_VPW (0x1FF<<0) -#define LCD_VERTTIMING_VND2_N(N)(((N)-1)<<18) -#define LCD_VERTTIMING_VND1_N(N)(((N)-1)<<9) -#define LCD_VERTTIMING_VPW_N(N) (((N)-1)<<0) - -/* lcd_clkcontrol */ -#define LCD_CLKCONTROL_EXT (1<<22) -#define LCD_CLKCONTROL_DELAY (3<<20) -#define LCD_CLKCONTROL_CDD (1<<19) -#define LCD_CLKCONTROL_IB (1<<18) -#define LCD_CLKCONTROL_IC (1<<17) -#define LCD_CLKCONTROL_IH (1<<16) -#define LCD_CLKCONTROL_IV (1<<15) -#define LCD_CLKCONTROL_BF (0x1F<<10) -#define LCD_CLKCONTROL_PCD (0x3FF<<0) -#define LCD_CLKCONTROL_BF_N(N) (((N)-1)<<10) -#define LCD_CLKCONTROL_PCD_N(N) ((N)<<0) - -/* lcd_pwmdiv */ -#define LCD_PWMDIV_EN (1<<31) -#define LCD_PWMDIV_PWMDIV (0x1FFFF<<0) -#define LCD_PWMDIV_PWMDIV_N(N) ((N)<<0) - -/* lcd_pwmhi */ -#define LCD_PWMHI_PWMHI1 (0xFFFF<<16) -#define LCD_PWMHI_PWMHI0 (0xFFFF<<0) -#define LCD_PWMHI_PWMHI1_N(N) ((N)<<16) -#define LCD_PWMHI_PWMHI0_N(N) ((N)<<0) - -/* lcd_hwccon */ -#define LCD_HWCCON_EN (1<<0) - -/* lcd_cursorpos */ -#define LCD_CURSORPOS_HWCXOFF (0x1F<<27) -#define LCD_CURSORPOS_HWCXPOS (0x07FF<<16) -#define LCD_CURSORPOS_HWCYOFF (0x1F<<11) -#define LCD_CURSORPOS_HWCYPOS (0x07FF<<0) -#define LCD_CURSORPOS_HWCXOFF_N(N) ((N)<<27) -#define LCD_CURSORPOS_HWCXPOS_N(N) ((N)<<16) -#define LCD_CURSORPOS_HWCYOFF_N(N) ((N)<<11) -#define LCD_CURSORPOS_HWCYPOS_N(N) ((N)<<0) - -/* lcd_cursorcolor */ -#define LCD_CURSORCOLOR_HWCA (0xFF<<24) -#define LCD_CURSORCOLOR_HWCR (0xFF<<16) -#define LCD_CURSORCOLOR_HWCG (0xFF<<8) -#define LCD_CURSORCOLOR_HWCB (0xFF<<0) -#define LCD_CURSORCOLOR_HWCA_N(N) ((N)<<24) -#define LCD_CURSORCOLOR_HWCR_N(N) ((N)<<16) -#define LCD_CURSORCOLOR_HWCG_N(N) ((N)<<8) -#define LCD_CURSORCOLOR_HWCB_N(N) ((N)<<0) - -/* lcd_fifoctrl */ -#define LCD_FIFOCTRL_F3IF (1<<29) -#define LCD_FIFOCTRL_F3REQ (0x1F<<24) -#define LCD_FIFOCTRL_F2IF (1<<29) -#define LCD_FIFOCTRL_F2REQ (0x1F<<16) -#define LCD_FIFOCTRL_F1IF (1<<29) -#define LCD_FIFOCTRL_F1REQ (0x1F<<8) -#define LCD_FIFOCTRL_F0IF (1<<29) -#define LCD_FIFOCTRL_F0REQ (0x1F<<0) -#define LCD_FIFOCTRL_F3REQ_N(N) ((N-1)<<24) -#define LCD_FIFOCTRL_F2REQ_N(N) ((N-1)<<16) -#define LCD_FIFOCTRL_F1REQ_N(N) ((N-1)<<8) -#define LCD_FIFOCTRL_F0REQ_N(N) ((N-1)<<0) - -/* lcd_outmask */ -#define LCD_OUTMASK_MASK (0x00FFFFFF) - -/********************************************************************/ -#endif /* _AU1200LCD_H */ -/* - * BRIEF MODULE DESCRIPTION - * Hardware definitions for the Au1200 LCD controller - * - * Copyright 2004 AMD - * Author: AMD - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _AU1200LCD_H -#define _AU1200LCD_H - -/********************************************************************/ -#define AU1200_LCD_ADDR 0xB5000000 - -#define uint8 unsigned char -#define uint32 unsigned int - -struct au1200_lcd { - volatile uint32 reserved0; - volatile uint32 screen; - volatile uint32 backcolor; - volatile uint32 horztiming; - volatile uint32 verttiming; - volatile uint32 clkcontrol; - volatile uint32 pwmdiv; - volatile uint32 pwmhi; - volatile uint32 reserved1; - volatile uint32 winenable; - volatile uint32 colorkey; - volatile uint32 colorkeymsk; - struct - { - volatile uint32 cursorctrl; - volatile uint32 cursorpos; - volatile uint32 cursorcolor0; - volatile uint32 cursorcolor1; - volatile uint32 cursorcolor2; - uint32 cursorcolor3; - } hwc; - volatile uint32 intstatus; - volatile uint32 intenable; - volatile uint32 outmask; - volatile uint32 fifoctrl; - uint32 reserved2[(0x0100-0x0058)/4]; - struct - { - volatile uint32 winctrl0; - volatile uint32 winctrl1; - volatile uint32 winctrl2; - volatile uint32 winbuf0; - volatile uint32 winbuf1; - volatile uint32 winbufctrl; - uint32 winreserved0; - uint32 winreserved1; - } window[4]; - - uint32 reserved3[(0x0400-0x0180)/4]; - - volatile uint32 palette[(0x0800-0x0400)/4]; - - volatile uint8 cursorpattern[256]; -}; - -/* lcd_screen */ -#define LCD_SCREEN_SEN (1<<31) -#define LCD_SCREEN_SX (0x07FF<<19) -#define LCD_SCREEN_SY (0x07FF<< 8) -#define LCD_SCREEN_SWP (1<<7) -#define LCD_SCREEN_SWD (1<<6) -#define LCD_SCREEN_PT (7<<0) -#define LCD_SCREEN_PT_TFT (0<<0) -#define LCD_SCREEN_SX_N(WIDTH) ((WIDTH-1)<<19) -#define LCD_SCREEN_SY_N(HEIGHT) ((HEIGHT-1)<<8) -#define LCD_SCREEN_PT_CSTN (1<<0) -#define LCD_SCREEN_PT_CDSTN (2<<0) -#define LCD_SCREEN_PT_M8STN (3<<0) -#define LCD_SCREEN_PT_M4STN (4<<0) - -/* lcd_backcolor */ -#define LCD_BACKCOLOR_SBGR (0xFF<<16) -#define LCD_BACKCOLOR_SBGG (0xFF<<8) -#define LCD_BACKCOLOR_SBGB (0xFF<<0) -#define LCD_BACKCOLOR_SBGR_N(N) ((N)<<16) -#define LCD_BACKCOLOR_SBGG_N(N) ((N)<<8) -#define LCD_BACKCOLOR_SBGB_N(N) ((N)<<0) - -/* lcd_winenable */ -#define LCD_WINENABLE_WEN3 (1<<3) -#define LCD_WINENABLE_WEN2 (1<<2) -#define LCD_WINENABLE_WEN1 (1<<1) -#define LCD_WINENABLE_WEN0 (1<<0) - -/* lcd_colorkey */ -#define LCD_COLORKEY_CKR (0xFF<<16) -#define LCD_COLORKEY_CKG (0xFF<<8) -#define LCD_COLORKEY_CKB (0xFF<<0) -#define LCD_COLORKEY_CKR_N(N) ((N)<<16) -#define LCD_COLORKEY_CKG_N(N) ((N)<<8) -#define LCD_COLORKEY_CKB_N(N) ((N)<<0) - -/* lcd_colorkeymsk */ -#define LCD_COLORKEYMSK_CKMR (0xFF<<16) -#define LCD_COLORKEYMSK_CKMG (0xFF<<8) -#define LCD_COLORKEYMSK_CKMB (0xFF<<0) -#define LCD_COLORKEYMSK_CKMR_N(N) ((N)<<16) -#define LCD_COLORKEYMSK_CKMG_N(N) ((N)<<8) -#define LCD_COLORKEYMSK_CKMB_N(N) ((N)<<0) - -/* lcd windows control 0 */ -#define LCD_WINCTRL0_OX (0x07FF<<21) -#define LCD_WINCTRL0_OY (0x07FF<<10) -#define LCD_WINCTRL0_A (0x00FF<<2) -#define LCD_WINCTRL0_AEN (1<<1) -#define LCD_WINCTRL0_OX_N(N) ((N)<<21) -#define LCD_WINCTRL0_OY_N(N) ((N)<<10) -#define LCD_WINCTRL0_A_N(N) ((N)<<2) - -/* lcd windows control 1 */ -#define LCD_WINCTRL1_PRI (3<<30) -#define LCD_WINCTRL1_PIPE (1<<29) -#define LCD_WINCTRL1_FRM (0xF<<25) -#define LCD_WINCTRL1_CCO (1<<24) -#define LCD_WINCTRL1_PO (3<<22) -#define LCD_WINCTRL1_SZX (0x07FF<<11) -#define LCD_WINCTRL1_SZY (0x07FF<<0) -#define LCD_WINCTRL1_FRM_1BPP (0<<25) -#define LCD_WINCTRL1_FRM_2BPP (1<<25) -#define LCD_WINCTRL1_FRM_4BPP (2<<25) -#define LCD_WINCTRL1_FRM_8BPP (3<<25) -#define LCD_WINCTRL1_FRM_12BPP (4<<25) -#define LCD_WINCTRL1_FRM_16BPP655 (5<<25) -#define LCD_WINCTRL1_FRM_16BPP565 (6<<25) -#define LCD_WINCTRL1_FRM_16BPP556 (7<<25) -#define LCD_WINCTRL1_FRM_16BPPI1555 (8<<25) -#define LCD_WINCTRL1_FRM_16BPPI5551 (9<<25) -#define LCD_WINCTRL1_FRM_16BPPA1555 (10<<25) -#define LCD_WINCTRL1_FRM_16BPPA5551 (11<<25) -#define LCD_WINCTRL1_FRM_24BPP (12<<25) -#define LCD_WINCTRL1_FRM_32BPP (13<<25) -#define LCD_WINCTRL1_PRI_N(N) ((N)<<30) -#define LCD_WINCTRL1_PO_00 (0<<22) -#define LCD_WINCTRL1_PO_01 (1<<22) -#define LCD_WINCTRL1_PO_10 (2<<22) -#define LCD_WINCTRL1_PO_11 (3<<22) -#define LCD_WINCTRL1_SZX_N(N) ((N-1)<<11) -#define LCD_WINCTRL1_SZY_N(N) ((N-1)<<0) - -/* lcd windows control 2 */ -#define LCD_WINCTRL2_CKMODE (3<<24) -#define LCD_WINCTRL2_DBM (1<<23) -#define LCD_WINCTRL2_RAM (3<<21) -#define LCD_WINCTRL2_BX (0x1FFF<<8) -#define LCD_WINCTRL2_SCX (0xF<<4) -#define LCD_WINCTRL2_SCY (0xF<<0) -#define LCD_WINCTRL2_CKMODE_00 (0<<24) -#define LCD_WINCTRL2_CKMODE_01 (1<<24) -#define LCD_WINCTRL2_CKMODE_10 (2<<24) -#define LCD_WINCTRL2_CKMODE_11 (3<<24) -#define LCD_WINCTRL2_RAM_NONE (0<<21) -#define LCD_WINCTRL2_RAM_PALETTE (1<<21) -#define LCD_WINCTRL2_RAM_GAMMA (2<<21) -#define LCD_WINCTRL2_RAM_BUFFER (3<<21) -#define LCD_WINCTRL2_BX_N(N) ((N)<<8) -#define LCD_WINCTRL2_SCX_1 (0<<4) -#define LCD_WINCTRL2_SCX_2 (1<<4) -#define LCD_WINCTRL2_SCX_4 (2<<4) -#define LCD_WINCTRL2_SCY_1 (0<<0) -#define LCD_WINCTRL2_SCY_2 (1<<0) -#define LCD_WINCTRL2_SCY_4 (2<<0) - -/* lcd windows buffer control */ -#define LCD_WINBUFCTRL_DB (1<<1) -#define LCD_WINBUFCTRL_DBN (1<<0) - -/* lcd_intstatus, lcd_intenable */ -#define LCD_INT_IFO (0xF<<14) -#define LCD_INT_IFU (0xF<<10) -#define LCD_INT_OFO (1<<9) -#define LCD_INT_OFU (1<<8) -#define LCD_INT_WAIT (1<<3) -#define LCD_INT_SD (1<<2) -#define LCD_INT_SA (1<<1) -#define LCD_INT_SS (1<<0) - -/* lcd_horztiming */ -#define LCD_HORZTIMING_HND2 (0x1FF<<18) -#define LCD_HORZTIMING_HND1 (0x1FF<<9) -#define LCD_HORZTIMING_HPW (0x1FF<<0) -#define LCD_HORZTIMING_HND2_N(N)(((N)-1)<<18) -#define LCD_HORZTIMING_HND1_N(N)(((N)-1)<<9) -#define LCD_HORZTIMING_HPW_N(N) (((N)-1)<<0) - -/* lcd_verttiming */ -#define LCD_VERTTIMING_VND2 (0x1FF<<18) -#define LCD_VERTTIMING_VND1 (0x1FF<<9) -#define LCD_VERTTIMING_VPW (0x1FF<<0) -#define LCD_VERTTIMING_VND2_N(N)(((N)-1)<<18) -#define LCD_VERTTIMING_VND1_N(N)(((N)-1)<<9) -#define LCD_VERTTIMING_VPW_N(N) (((N)-1)<<0) - -/* lcd_clkcontrol */ -#define LCD_CLKCONTROL_EXT (1<<22) -#define LCD_CLKCONTROL_DELAY (3<<20) -#define LCD_CLKCONTROL_CDD (1<<19) -#define LCD_CLKCONTROL_IB (1<<18) -#define LCD_CLKCONTROL_IC (1<<17) -#define LCD_CLKCONTROL_IH (1<<16) -#define LCD_CLKCONTROL_IV (1<<15) -#define LCD_CLKCONTROL_BF (0x1F<<10) -#define LCD_CLKCONTROL_PCD (0x3FF<<0) -#define LCD_CLKCONTROL_BF_N(N) (((N)-1)<<10) -#define LCD_CLKCONTROL_PCD_N(N) ((N)<<0) - -/* lcd_pwmdiv */ -#define LCD_PWMDIV_EN (1<<31) -#define LCD_PWMDIV_PWMDIV (0x1FFFF<<0) -#define LCD_PWMDIV_PWMDIV_N(N) ((N)<<0) - -/* lcd_pwmhi */ -#define LCD_PWMHI_PWMHI1 (0xFFFF<<16) -#define LCD_PWMHI_PWMHI0 (0xFFFF<<0) -#define LCD_PWMHI_PWMHI1_N(N) ((N)<<16) -#define LCD_PWMHI_PWMHI0_N(N) ((N)<<0) - -/* lcd_hwccon */ -#define LCD_HWCCON_EN (1<<0) - -/* lcd_cursorpos */ -#define LCD_CURSORPOS_HWCXOFF (0x1F<<27) -#define LCD_CURSORPOS_HWCXPOS (0x07FF<<16) -#define LCD_CURSORPOS_HWCYOFF (0x1F<<11) -#define LCD_CURSORPOS_HWCYPOS (0x07FF<<0) -#define LCD_CURSORPOS_HWCXOFF_N(N) ((N)<<27) -#define LCD_CURSORPOS_HWCXPOS_N(N) ((N)<<16) -#define LCD_CURSORPOS_HWCYOFF_N(N) ((N)<<11) -#define LCD_CURSORPOS_HWCYPOS_N(N) ((N)<<0) - -/* lcd_cursorcolor */ -#define LCD_CURSORCOLOR_HWCA (0xFF<<24) -#define LCD_CURSORCOLOR_HWCR (0xFF<<16) -#define LCD_CURSORCOLOR_HWCG (0xFF<<8) -#define LCD_CURSORCOLOR_HWCB (0xFF<<0) -#define LCD_CURSORCOLOR_HWCA_N(N) ((N)<<24) -#define LCD_CURSORCOLOR_HWCR_N(N) ((N)<<16) -#define LCD_CURSORCOLOR_HWCG_N(N) ((N)<<8) -#define LCD_CURSORCOLOR_HWCB_N(N) ((N)<<0) - -/* lcd_fifoctrl */ -#define LCD_FIFOCTRL_F3IF (1<<29) -#define LCD_FIFOCTRL_F3REQ (0x1F<<24) -#define LCD_FIFOCTRL_F2IF (1<<29) -#define LCD_FIFOCTRL_F2REQ (0x1F<<16) -#define LCD_FIFOCTRL_F1IF (1<<29) -#define LCD_FIFOCTRL_F1REQ (0x1F<<8) -#define LCD_FIFOCTRL_F0IF (1<<29) -#define LCD_FIFOCTRL_F0REQ (0x1F<<0) -#define LCD_FIFOCTRL_F3REQ_N(N) ((N-1)<<24) -#define LCD_FIFOCTRL_F2REQ_N(N) ((N-1)<<16) -#define LCD_FIFOCTRL_F1REQ_N(N) ((N-1)<<8) -#define LCD_FIFOCTRL_F0REQ_N(N) ((N-1)<<0) - -/* lcd_outmask */ -#define LCD_OUTMASK_MASK (0x00FFFFFF) - -/********************************************************************/ -#endif /* _AU1200LCD_H */ diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index b895eaaa7..9d996f2c1 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -43,11 +43,11 @@ config LCD_DEVICE default y config BACKLIGHT_CORGI - tristate "Sharp Corgi Backlight Driver (SL Series)" + tristate "Sharp Corgi Backlight Driver (SL-C7xx Series)" depends on BACKLIGHT_DEVICE && PXA_SHARPSL default y help - If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the + If you have a Sharp Zaurus SL-C7xx, say y to enable the backlight driver. config BACKLIGHT_HP680 diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index acc81cb01..151fda8dd 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -5,7 +5,6 @@ * */ -#include #include #include #include @@ -14,7 +13,6 @@ #include #include #include -#include static ssize_t backlight_show_power(struct class_device *cdev, char *buf) { @@ -174,7 +172,7 @@ struct backlight_device *backlight_device_register(const char *name, void *devda new_bd = kmalloc(sizeof(struct backlight_device), GFP_KERNEL); if (unlikely(!new_bd)) - return ERR_PTR(ENOMEM); + return ERR_PTR(-ENOMEM); init_MUTEX(&new_bd->sem); new_bd->props = bp; diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 353cb3f73..d0aaf450e 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c @@ -14,22 +14,23 @@ #include #include #include -#include +#include #include #include #include -#include -#include +#include +#include -#define CORGI_MAX_INTENSITY 0x3e #define CORGI_DEFAULT_INTENSITY 0x1f -#define CORGI_LIMIT_MASK 0x0b +#define CORGI_LIMIT_MASK 0x0b static int corgibl_powermode = FB_BLANK_UNBLANK; static int current_intensity = 0; static int corgibl_limit = 0; +static void (*corgibl_mach_set_intensity)(int intensity); static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; +static struct backlight_properties corgibl_data; static void corgibl_send_intensity(int intensity) { @@ -43,19 +44,17 @@ static void corgibl_send_intensity(int intensity) intensity &= CORGI_LIMIT_MASK; } - /* Skip 0x20 as it will blank the display */ - if (intensity >= 0x20) - intensity++; - spin_lock_irqsave(&bl_lock, flags); - /* Bits 0-4 are accessed via the SSP interface */ - corgi_ssp_blduty_set(intensity & 0x1f); - /* Bit 5 is via SCOOP */ - if (intensity & 0x0020) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); + + corgibl_mach_set_intensity(intensity); + spin_unlock_irqrestore(&bl_lock, flags); + + corgi_kick_batt = symbol_get(sharpsl_battery_kick); + if (corgi_kick_batt) { + corgi_kick_batt(); + symbol_put(sharpsl_battery_kick); + } } static void corgibl_blank(int blank) @@ -81,17 +80,15 @@ static void corgibl_blank(int blank) } #ifdef CONFIG_PM -static int corgibl_suspend(struct device *dev, pm_message_t state, u32 level) +static int corgibl_suspend(struct platform_device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) - corgibl_blank(FB_BLANK_POWERDOWN); + corgibl_blank(FB_BLANK_POWERDOWN); return 0; } -static int corgibl_resume(struct device *dev, u32 level) +static int corgibl_resume(struct platform_device *dev) { - if (level == RESUME_POWER_ON) - corgibl_blank(FB_BLANK_UNBLANK); + corgibl_blank(FB_BLANK_UNBLANK); return 0; } #else @@ -113,8 +110,8 @@ static int corgibl_get_power(struct backlight_device *bd) static int corgibl_set_intensity(struct backlight_device *bd, int intensity) { - if (intensity > CORGI_MAX_INTENSITY) - intensity = CORGI_MAX_INTENSITY; + if (intensity > corgibl_data.max_brightness) + intensity = corgibl_data.max_brightness; corgibl_send_intensity(intensity); current_intensity=intensity; return 0; @@ -141,27 +138,32 @@ static struct backlight_properties corgibl_data = { .owner = THIS_MODULE, .get_power = corgibl_get_power, .set_power = corgibl_set_power, - .max_brightness = CORGI_MAX_INTENSITY, .get_brightness = corgibl_get_intensity, .set_brightness = corgibl_set_intensity, }; static struct backlight_device *corgi_backlight_device; -static int __init corgibl_probe(struct device *dev) +static int __init corgibl_probe(struct platform_device *pdev) { + struct corgibl_machinfo *machinfo = pdev->dev.platform_data; + + corgibl_data.max_brightness = machinfo->max_intensity; + corgibl_mach_set_intensity = machinfo->set_bl_intensity; + corgi_backlight_device = backlight_device_register ("corgi-bl", NULL, &corgibl_data); if (IS_ERR (corgi_backlight_device)) return PTR_ERR (corgi_backlight_device); corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY); + corgibl_limit_intensity(0); printk("Corgi Backlight Driver Initialized.\n"); return 0; } -static int corgibl_remove(struct device *dev) +static int corgibl_remove(struct platform_device *dev) { backlight_device_unregister(corgi_backlight_device); @@ -171,23 +173,24 @@ static int corgibl_remove(struct device *dev) return 0; } -static struct device_driver corgibl_driver = { - .name = "corgi-bl", - .bus = &platform_bus_type, +static struct platform_driver corgibl_driver = { .probe = corgibl_probe, .remove = corgibl_remove, .suspend = corgibl_suspend, .resume = corgibl_resume, + .driver = { + .name = "corgi-bl", + }, }; static int __init corgibl_init(void) { - return driver_register(&corgibl_driver); + return platform_driver_register(&corgibl_driver); } static void __exit corgibl_exit(void) { - driver_unregister(&corgibl_driver); + platform_driver_unregister(&corgibl_driver); } module_init(corgibl_init); diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index a71e984c9..95da4c9ed 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -25,58 +25,66 @@ #define HP680_MAX_INTENSITY 255 #define HP680_DEFAULT_INTENSITY 10 -static int hp680bl_suspended; +static int hp680bl_powermode = FB_BLANK_UNBLANK; static int current_intensity = 0; static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; -static struct backlight_device *hp680_backlight_device; -static void hp680bl_send_intensity(struct backlight_device *bd) +static void hp680bl_send_intensity(int intensity) { unsigned long flags; - u16 v; - int intensity = bd->props->brightness; - if (bd->props->power != FB_BLANK_UNBLANK) - intensity = 0; - if (bd->props->fb_blank != FB_BLANK_UNBLANK) - intensity = 0; - if (hp680bl_suspended) + if (hp680bl_powermode != FB_BLANK_UNBLANK) intensity = 0; spin_lock_irqsave(&bl_lock, flags); - if (intensity && current_intensity == 0) { - sh_dac_enable(DAC_LCD_BRIGHTNESS); - v = inw(HD64461_GPBDR); - v &= ~HD64461_GPBDR_LCDOFF; - outw(v, HD64461_GPBDR); - sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); - } else if (intensity == 0 && current_intensity != 0) { - sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); - sh_dac_disable(DAC_LCD_BRIGHTNESS); - v = inw(HD64461_GPBDR); - v |= HD64461_GPBDR_LCDOFF; - outw(v, HD64461_GPBDR); - } else if (intensity) { - sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); - } + sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); spin_unlock_irqrestore(&bl_lock, flags); - - current_intensity = intensity; } +static void hp680bl_blank(int blank) +{ + u16 v; + + switch(blank) { + + case FB_BLANK_NORMAL: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_POWERDOWN: + if (hp680bl_powermode == FB_BLANK_UNBLANK) { + hp680bl_send_intensity(0); + hp680bl_powermode = blank; + sh_dac_disable(DAC_LCD_BRIGHTNESS); + v = inw(HD64461_GPBDR); + v |= HD64461_GPBDR_LCDOFF; + outw(v, HD64461_GPBDR); + } + break; + case FB_BLANK_UNBLANK: + if (hp680bl_powermode != FB_BLANK_UNBLANK) { + sh_dac_enable(DAC_LCD_BRIGHTNESS); + v = inw(HD64461_GPBDR); + v &= ~HD64461_GPBDR_LCDOFF; + outw(v, HD64461_GPBDR); + hp680bl_powermode = blank; + hp680bl_send_intensity(current_intensity); + } + break; + } +} #ifdef CONFIG_PM -static int hp680bl_suspend(struct platform_device *dev, pm_message_t state) +static int hp680bl_suspend(struct device *dev, pm_message_t state, u32 level) { - hp680bl_suspended = 1; - hp680bl_send_intensity(hp680_backlight_device); + if (level == SUSPEND_POWER_DOWN) + hp680bl_blank(FB_BLANK_POWERDOWN); return 0; } -static int hp680bl_resume(struct platform_device *dev) +static int hp680bl_resume(struct device *dev, u32 level) { - hp680bl_suspended = 0; - hp680bl_send_intensity(hp680_backlight_device); + if (level == RESUME_POWER_ON) + hp680bl_blank(FB_BLANK_UNBLANK); return 0; } #else @@ -84,9 +92,24 @@ static int hp680bl_resume(struct platform_device *dev) #define hp680bl_resume NULL #endif -static int hp680bl_set_intensity(struct backlight_device *bd) + +static int hp680bl_set_power(struct backlight_device *bd, int state) { - hp680bl_send_intensity(bd); + hp680bl_blank(state); + return 0; +} + +static int hp680bl_get_power(struct backlight_device *bd) +{ + return hp680bl_powermode; +} + +static int hp680bl_set_intensity(struct backlight_device *bd, int intensity) +{ + if (intensity > HP680_MAX_INTENSITY) + intensity = HP680_MAX_INTENSITY; + hp680bl_send_intensity(intensity); + current_intensity = intensity; return 0; } @@ -97,67 +120,65 @@ static int hp680bl_get_intensity(struct backlight_device *bd) static struct backlight_properties hp680bl_data = { .owner = THIS_MODULE, + .get_power = hp680bl_get_power, + .set_power = hp680bl_set_power, .max_brightness = HP680_MAX_INTENSITY, .get_brightness = hp680bl_get_intensity, - .update_status = hp680bl_set_intensity, + .set_brightness = hp680bl_set_intensity, }; -static int __init hp680bl_probe(struct platform_device *dev) +static struct backlight_device *hp680_backlight_device; + +static int __init hp680bl_probe(struct device *dev) { hp680_backlight_device = backlight_device_register ("hp680-bl", NULL, &hp680bl_data); if (IS_ERR (hp680_backlight_device)) return PTR_ERR (hp680_backlight_device); - hp680_backlight_device->props->brightness = HP680_DEFAULT_INTENSITY; - hp680bl_send_intensity(hp680_backlight_device); + hp680bl_set_intensity(NULL, HP680_DEFAULT_INTENSITY); return 0; } -static int hp680bl_remove(struct platform_device *dev) +static int hp680bl_remove(struct device *dev) { backlight_device_unregister(hp680_backlight_device); return 0; } -static struct platform_driver hp680bl_driver = { +static struct device_driver hp680bl_driver = { + .name = "hp680-bl", + .bus = &platform_bus_type, .probe = hp680bl_probe, .remove = hp680bl_remove, .suspend = hp680bl_suspend, .resume = hp680bl_resume, - .driver = { - .name = "hp680-bl", - }, }; -static struct platform_device *hp680bl_device; +static struct platform_device hp680bl_device = { + .name = "hp680-bl", + .id = -1, +}; static int __init hp680bl_init(void) { int ret; - ret = platform_driver_register(&hp680bl_driver); + ret=driver_register(&hp680bl_driver); if (!ret) { - hp680bl_device = platform_device_alloc("hp680-bl", -1); - if (!hp680bl_device) - return -ENOMEM; - - ret = platform_device_add(hp680bl_device); - - if (ret) { - platform_device_put(hp680bl_device); - platform_driver_unregister(&hp680bl_driver); - } + ret = platform_device_register(&hp680bl_device); + if (ret) + driver_unregister(&hp680bl_driver); } return ret; } static void __exit hp680bl_exit(void) { - platform_device_unregister(hp680bl_device); - platform_driver_unregister(&hp680bl_driver); + platform_device_unregister(&hp680bl_device); + driver_unregister(&hp680bl_driver); } module_init(hp680bl_init); diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 470e6f0ee..86908a60c 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -5,7 +5,6 @@ * */ -#include #include #include #include @@ -14,7 +13,6 @@ #include #include #include -#include static ssize_t lcd_show_power(struct class_device *cdev, char *buf) { @@ -173,7 +171,7 @@ struct lcd_device *lcd_device_register(const char *name, void *devdata, new_ld = kmalloc(sizeof(struct lcd_device), GFP_KERNEL); if (unlikely(!new_ld)) - return ERR_PTR(ENOMEM); + return ERR_PTR(-ENOMEM); init_MUTEX(&new_ld->sem); new_ld->props = lp; diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 60831bb23..ada6e75eb 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -20,10 +20,14 @@ #include #include -#include -#include -#include "../../../arch/arm/mach-sa1100/generic.h" +#ifdef CONFIG_SA1100_COLLIE +#include +#else +#include +#endif + +extern void (*sa1100fb_lcd_power)(int on); static struct locomo_dev *locomolcd_dev; @@ -78,7 +82,7 @@ static void locomolcd_off(int comadj) void locomolcd_power(int on) { - int comadj = sharpsl_param.comadj; + int comadj = 118; unsigned long flags; local_irq_save(flags); @@ -89,12 +93,11 @@ void locomolcd_power(int on) } /* read comadj */ - if (comadj == -1) { - if (machine_is_poodle()) - comadj = 118; - if (machine_is_collie()) - comadj = 128; - } +#ifdef CONFIG_MACH_POODLE + comadj = 118; +#else + comadj = 128; +#endif if (on) locomolcd_on(comadj); diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 6577fdfdf..c029db464 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -327,7 +327,8 @@ static void bw2_init_one(struct sbus_dev *sdev) } else #else { - BUG_ON(!sdev); + if (!sdev) + BUG(); all->par.physbase = sdev->reg_addrs[0].phys_addr; resp = &sdev->resource[0]; sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1); diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index 72ff6bf75..bc061d4ec 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c @@ -178,6 +178,8 @@ struct chips_init_reg { unsigned char data; }; +#define N_ELTS(x) (sizeof(x) / sizeof(x[0])) + static struct chips_init_reg chips_init_sr[] = { { 0x00, 0x03 }, { 0x01, 0x01 }, @@ -285,18 +287,18 @@ static void __init chips_hw_init(void) { int i; - for (i = 0; i < ARRAY_SIZE(chips_init_xr); ++i) + for (i = 0; i < N_ELTS(chips_init_xr); ++i) write_xr(chips_init_xr[i].addr, chips_init_xr[i].data); outb(0x29, 0x3c2); /* set misc output reg */ - for (i = 0; i < ARRAY_SIZE(chips_init_sr); ++i) + for (i = 0; i < N_ELTS(chips_init_sr); ++i) write_sr(chips_init_sr[i].addr, chips_init_sr[i].data); - for (i = 0; i < ARRAY_SIZE(chips_init_gr); ++i) + for (i = 0; i < N_ELTS(chips_init_gr); ++i) write_gr(chips_init_gr[i].addr, chips_init_gr[i].data); - for (i = 0; i < ARRAY_SIZE(chips_init_ar); ++i) + for (i = 0; i < N_ELTS(chips_init_ar); ++i) write_ar(chips_init_ar[i].addr, chips_init_ar[i].data); - for (i = 0; i < ARRAY_SIZE(chips_init_cr); ++i) + for (i = 0; i < N_ELTS(chips_init_cr); ++i) write_cr(chips_init_cr[i].addr, chips_init_cr[i].data); - for (i = 0; i < ARRAY_SIZE(chips_init_fr); ++i) + for (i = 0; i < N_ELTS(chips_init_fr); ++i) write_fr(chips_init_fr[i].addr, chips_init_fr[i].data); } diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 1103010af..e0dbdfc0c 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -60,8 +60,8 @@ #include #endif #ifdef CONFIG_PPC_PREP -#include -#define isPReP (machine_is(prep)) +#include +#define isPReP (_machine == _MACH_prep) #else #define isPReP 0 #endif @@ -2622,7 +2622,7 @@ static int __init cirrusfb_init(void) #endif #ifdef CONFIG_ZORRO - error |= zorro_register_driver(&cirrusfb_zorro_driver); + error |= zorro_module_init(&cirrusfb_zorro_driver); #endif #ifdef CONFIG_PCI error |= pci_register_driver(&cirrusfb_pci_driver); diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 4444bef68..6ee449858 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -26,30 +26,6 @@ config VGA_CONSOLE # fi # fi -config VGACON_SOFT_SCROLLBACK - bool "Enable Scrollback Buffer in System RAM" - depends on VGA_CONSOLE - default n - help - The scrollback buffer of the standard VGA console is located in - the VGA RAM. The size of this RAM is fixed and is quite small. - If you require a larger scrollback buffer, this can be placed in - System RAM which is dynamically allocated during intialization. - Placing the scrollback buffer in System RAM will slightly slow - down the console. - - If you want this feature, say 'Y' here and enter the amount of - RAM to allocate for this buffer. If unsure, say 'N'. - -config VGACON_SOFT_SCROLLBACK_SIZE - int "Scrollback Buffer Size (in KB)" - depends on VGACON_SOFT_SCROLLBACK - default "64" - help - Enter the amount of System RAM to allocate for the scrollback - buffer. Each 64KB will give you approximately 16 80x25 - screenfuls of scrollback buffer - config VIDEO_SELECT bool "Video mode selection support" depends on X86 && VGA_CONSOLE diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 47ba1a79a..041d06987 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -466,7 +466,7 @@ static int __init fb_console_setup(char *this_opt) int i, j; if (!this_opt || !*this_opt) - return 1; + return 0; while ((options = strsep(&this_opt, ",")) != NULL) { if (!strncmp(options, "font:", 5)) @@ -481,10 +481,10 @@ static int __init fb_console_setup(char *this_opt) options++; } if (*options != ',') - return 1; + return 0; options++; } else - return 1; + return 0; } if (!strncmp(options, "map:", 4)) { @@ -496,7 +496,7 @@ static int __init fb_console_setup(char *this_opt) con2fb_map_boot[i] = (options[j++]-'0') % FB_MAX; } - return 1; + return 0; } if (!strncmp(options, "vc:", 3)) { @@ -518,7 +518,7 @@ static int __init fb_console_setup(char *this_opt) rotate = 0; } } - return 1; + return 0; } __setup("fbcon=", fb_console_setup); @@ -1142,7 +1142,6 @@ static void fbcon_init(struct vc_data *vc, int init) set_blitting_type(vc, info); } - ops->p = &fb_display[fg_console]; } static void fbcon_deinit(struct vc_data *vc) @@ -1745,7 +1744,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, fbcon_redraw_move(vc, p, 0, t, count); ypan_up_redraw(vc, t, count); if (vc->vc_rows - b > 0) - fbcon_redraw_move(vc, p, b, + fbcon_redraw_move(vc, p, b - count, vc->vc_rows - b, b); } else fbcon_redraw_move(vc, p, t + count, b - t - count, t); @@ -2631,7 +2630,7 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) scr_memcpyw((u16 *) q, (u16 *) p, vc->vc_size_row); } - softback_in = softback_curr = p; + softback_in = p; update_region(vc, vc->vc_origin, logo_lines * vc->vc_cols); } diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c index 0cc1bfda7..4fd07d9ec 100644 --- a/drivers/video/console/fonts.c +++ b/drivers/video/console/fonts.c @@ -66,7 +66,7 @@ static const struct font_desc *fonts[] = { #endif }; -#define num_fonts ARRAY_SIZE(fonts) +#define num_fonts (sizeof(fonts)/sizeof(*fonts)) #ifdef NO_FONTS #error No fonts configured. diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index e99fe30e5..762c7a593 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -149,7 +149,7 @@ static inline void newport_clear_lines(int ystart, int yend, int ci) newport_clear_screen(0, ystart, 1280 + 63, yend, ci); } -static void newport_reset(void) +void newport_reset(void) { unsigned short treg; int i; @@ -193,7 +193,7 @@ static void newport_reset(void) * calculate the actual screen size by reading * the video timing out of the VC2 */ -static void newport_get_screensize(void) +void newport_get_screensize(void) { int i, cols; unsigned short ventry, treg; diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 2ade75291..3957fc752 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c @@ -25,9 +25,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) unsigned int buf_align = info->pixmap.buf_align - 1; unsigned int i, size, dsize, s_pitch, d_pitch; struct fb_image *image; - u8 *dst; - static u8 *src=NULL; - static int allocsize = 0; + u8 *dst, *src; if (info->state != FBINFO_STATE_RUNNING) return 0; @@ -35,17 +33,9 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) s_pitch = (cursor->image.width + 7) >> 3; dsize = s_pitch * cursor->image.height; - if (dsize + sizeof(struct fb_image) != allocsize) { - if (src != NULL) - kfree(src); - allocsize = dsize + sizeof(struct fb_image); - - src = kmalloc(allocsize, GFP_ATOMIC); - if (!src) { - allocsize = 0; - return -ENOMEM; - } - } + src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC); + if (!src) + return -ENOMEM; image = (struct fb_image *) (src + dsize); *image = cursor->image; @@ -73,6 +63,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); image->data = dst; info->fbops->fb_imageblit(info, image); + kfree(src); return 0; } diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 74ac2acaf..0339f5640 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -275,7 +275,7 @@ static int __init sti_setup(char *str) if (str) strlcpy (default_sti_path, str, sizeof (default_sti_path)); - return 1; + return 0; } /* Assuming the machine has multiple STI consoles (=graphic cards) which @@ -321,7 +321,7 @@ static int __init sti_font_setup(char *str) i++; } - return 1; + return 0; } /* The optional linux kernel parameter "sti_font" defines which font @@ -373,7 +373,7 @@ sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request) glob_cfg->save_addr)); /* dump extended cfg */ - cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr); + cfg = PTR_STI(glob_cfg->ext_ptr); DPRINTK(( KERN_INFO "monitor %d\n" "in friendly mode: %d\n" @@ -453,11 +453,25 @@ sti_init_glob_cfg(struct sti_struct *sti, sti->regions_phys[i] = REGION_OFFSET_TO_PHYS(sti->regions[i], newhpa); + /* remap virtually */ + /* FIXME: add BTLB support if btlb==1 */ len = sti->regions[i].region_desc.length * 4096; + +/* XXX: Enabling IOREMAP debugging causes a crash, so we must be passing + * a virtual address to something expecting a physical address that doesn't + * go through a readX macro */ +#if 0 + if (len) + glob_cfg->region_ptrs[i] = (unsigned long) ( + sti->regions[i].region_desc.cache ? + ioremap(sti->regions_phys[i], len) : + ioremap_nocache(sti->regions_phys[i], len) ); +#else if (len) glob_cfg->region_ptrs[i] = sti->regions_phys[i]; +#endif - DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, " + DPRINTK(("region #%d: phys %08lx, virt %08x, len=%lukB, " "btlb=%d, sysonly=%d, cache=%d, last=%d\n", i, sti->regions_phys[i], glob_cfg->region_ptrs[i], len/1024, diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index d5a04b68c..5a8697853 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -93,6 +93,7 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); static unsigned long vgacon_uni_pagedir[2]; + /* Description of the hardware situation */ static unsigned long vga_vram_base; /* Base of video memory */ static unsigned long vga_vram_end; /* End of video memory */ @@ -160,201 +161,6 @@ static inline void write_vga(unsigned char reg, unsigned int val) spin_unlock_irqrestore(&vga_lock, flags); } -static inline void vga_set_mem_top(struct vc_data *c) -{ - write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2); -} - -#ifdef CONFIG_VGACON_SOFT_SCROLLBACK -#include -/* software scrollback */ -static void *vgacon_scrollback; -static int vgacon_scrollback_tail; -static int vgacon_scrollback_size; -static int vgacon_scrollback_rows; -static int vgacon_scrollback_cnt; -static int vgacon_scrollback_cur; -static int vgacon_scrollback_save; -static int vgacon_scrollback_restore; - -static void vgacon_scrollback_init(int pitch) -{ - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - - if (vgacon_scrollback) { - vgacon_scrollback_cnt = 0; - vgacon_scrollback_tail = 0; - vgacon_scrollback_cur = 0; - vgacon_scrollback_rows = rows - 1; - vgacon_scrollback_size = rows * pitch; - } -} - -static void __init vgacon_scrollback_startup(void) -{ - vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE - * 1024); - vgacon_scrollback_init(vga_video_num_columns * 2); -} - -static void vgacon_scrollback_update(struct vc_data *c, int t, int count) -{ - void *p; - - if (!vgacon_scrollback_size || c->vc_num != fg_console) - return; - - p = (void *) (c->vc_origin + t * c->vc_size_row); - - while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, - p, c->vc_size_row); - vgacon_scrollback_cnt++; - p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; - - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; - - if (vgacon_scrollback_cnt > vgacon_scrollback_rows) - vgacon_scrollback_cnt = vgacon_scrollback_rows; - - vgacon_scrollback_cur = vgacon_scrollback_cnt; - } -} - -static void vgacon_restore_screen(struct vc_data *c) -{ - vgacon_scrollback_save = 0; - - if (!vga_is_gfx && !vgacon_scrollback_restore) { - scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, - c->vc_screenbuf_size > vga_vram_size ? - vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback_restore = 1; - vgacon_scrollback_cur = vgacon_scrollback_cnt; - } -} - -static int vgacon_scrolldelta(struct vc_data *c, int lines) -{ - int start, end, count, soff, diff; - void *d, *s; - - if (!lines) { - c->vc_visible_origin = c->vc_origin; - vga_set_mem_top(c); - return 1; - } - - if (!vgacon_scrollback) - return 1; - - if (!vgacon_scrollback_save) { - vgacon_cursor(c, CM_ERASE); - vgacon_save_screen(c); - vgacon_scrollback_save = 1; - } - - vgacon_scrollback_restore = 0; - start = vgacon_scrollback_cur + lines; - end = start + abs(lines); - - if (start < 0) - start = 0; - - if (start > vgacon_scrollback_cnt) - start = vgacon_scrollback_cnt; - - if (end < 0) - end = 0; - - if (end > vgacon_scrollback_cnt) - end = vgacon_scrollback_cnt; - - vgacon_scrollback_cur = start; - count = end - start; - soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * - c->vc_size_row); - soff -= count * c->vc_size_row; - - if (soff < 0) - soff += vgacon_scrollback_size; - - count = vgacon_scrollback_cnt - start; - - if (count > c->vc_rows) - count = c->vc_rows; - - diff = c->vc_rows - count; - - d = (void *) c->vc_origin; - s = (void *) c->vc_screenbuf; - - while (count--) { - scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row); - d += c->vc_size_row; - soff += c->vc_size_row; - - if (soff >= vgacon_scrollback_size) - soff = 0; - } - - if (diff == c->vc_rows) { - vgacon_cursor(c, CM_MOVE); - } else { - while (diff--) { - scr_memcpyw(d, s, c->vc_size_row); - d += c->vc_size_row; - s += c->vc_size_row; - } - } - - return 1; -} -#else -#define vgacon_scrollback_startup(...) do { } while (0) -#define vgacon_scrollback_init(...) do { } while (0) -#define vgacon_scrollback_update(...) do { } while (0) - -static void vgacon_restore_screen(struct vc_data *c) -{ - if (c->vc_origin != c->vc_visible_origin) - vgacon_scrolldelta(c, 0); -} - -static int vgacon_scrolldelta(struct vc_data *c, int lines) -{ - if (!lines) /* Turn scrollback off */ - c->vc_visible_origin = c->vc_origin; - else { - int margin = c->vc_size_row * 4; - int ul, we, p, st; - - if (vga_rolled_over > - (c->vc_scr_end - vga_vram_base) + margin) { - ul = c->vc_scr_end - vga_vram_base; - we = vga_rolled_over + c->vc_size_row; - } else { - ul = 0; - we = vga_vram_size; - } - p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + - lines * c->vc_size_row; - st = (c->vc_origin - vga_vram_base - ul + we) % we; - if (st < 2 * margin) - margin = 0; - if (p < margin) - p = 0; - if (p > st - margin) - p = st; - c->vc_visible_origin = vga_vram_base + (p + ul) % we; - } - vga_set_mem_top(c); - return 1; -} -#endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ - static const char __init *vgacon_startup(void) { const char *display_desc = NULL; @@ -524,7 +330,7 @@ static const char __init *vgacon_startup(void) vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; vgacon_yres = vga_scan_lines; - vgacon_scrollback_startup(); + return display_desc; } @@ -551,6 +357,11 @@ static void vgacon_init(struct vc_data *c, int init) con_set_default_unimap(c); } +static inline void vga_set_mem_top(struct vc_data *c) +{ + write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2); +} + static void vgacon_deinit(struct vc_data *c) { /* When closing the last console, reset video origin */ @@ -622,37 +433,29 @@ static void vgacon_set_cursor_size(int xpos, int from, int to) cursor_size_lastto = to; spin_lock_irqsave(&vga_lock, flags); - if (vga_video_type >= VIDEO_TYPE_VGAC) { - outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg); - curs = inb_p(vga_video_port_val); - outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg); - cure = inb_p(vga_video_port_val); - } else { - curs = 0; - cure = 0; - } + outb_p(0x0a, vga_video_port_reg); /* Cursor start */ + curs = inb_p(vga_video_port_val); + outb_p(0x0b, vga_video_port_reg); /* Cursor end */ + cure = inb_p(vga_video_port_val); curs = (curs & 0xc0) | from; cure = (cure & 0xe0) | to; - outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg); + outb_p(0x0a, vga_video_port_reg); /* Cursor start */ outb_p(curs, vga_video_port_val); - outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg); + outb_p(0x0b, vga_video_port_reg); /* Cursor end */ outb_p(cure, vga_video_port_val); spin_unlock_irqrestore(&vga_lock, flags); } static void vgacon_cursor(struct vc_data *c, int mode) { - vgacon_restore_screen(c); - + if (c->vc_origin != c->vc_visible_origin) + vgacon_scrolldelta(c, 0); switch (mode) { case CM_ERASE: write_vga(14, (c->vc_pos - vga_vram_base) / 2); - if (vga_video_type >= VIDEO_TYPE_VGAC) - vgacon_set_cursor_size(c->vc_x, 31, 30); - else - vgacon_set_cursor_size(c->vc_x, 31, 31); + vgacon_set_cursor_size(c->vc_x, 31, 30); break; case CM_MOVE: @@ -690,10 +493,7 @@ static void vgacon_cursor(struct vc_data *c, int mode) 10 ? 1 : 2)); break; case CUR_NONE: - if (vga_video_type >= VIDEO_TYPE_VGAC) - vgacon_set_cursor_size(c->vc_x, 31, 30); - else - vgacon_set_cursor_size(c->vc_x, 31, 31); + vgacon_set_cursor_size(c->vc_x, 31, 30); break; default: vgacon_set_cursor_size(c->vc_x, 1, @@ -795,7 +595,6 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - vgacon_scrollback_init(c->vc_size_row); return 0; /* Redrawing not needed */ } @@ -1263,6 +1062,37 @@ static int vgacon_resize(struct vc_data *c, unsigned int width, return 0; } +static int vgacon_scrolldelta(struct vc_data *c, int lines) +{ + if (!lines) /* Turn scrollback off */ + c->vc_visible_origin = c->vc_origin; + else { + int margin = c->vc_size_row * 4; + int ul, we, p, st; + + if (vga_rolled_over > + (c->vc_scr_end - vga_vram_base) + margin) { + ul = c->vc_scr_end - vga_vram_base; + we = vga_rolled_over + c->vc_size_row; + } else { + ul = 0; + we = vga_vram_size; + } + p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + + lines * c->vc_size_row; + st = (c->vc_origin - vga_vram_base - ul + we) % we; + if (st < 2 * margin) + margin = 0; + if (p < margin) + p = 0; + if (p > st - margin) + p = st; + c->vc_visible_origin = vga_vram_base + (p + ul) % we; + } + vga_set_mem_top(c); + return 1; +} + static int vgacon_set_origin(struct vc_data *c) { if (vga_is_gfx || /* We don't play origin tricks in graphic modes */ @@ -1305,14 +1135,15 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, if (t || b != c->vc_rows || vga_is_gfx) return 0; + if (c->vc_origin != c->vc_visible_origin) + vgacon_scrolldelta(c, 0); + if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2) return 0; - vgacon_restore_screen(c); oldo = c->vc_origin; delta = lines * c->vc_size_row; if (dir == SM_UP) { - vgacon_scrollback_update(c, t, lines); if (c->vc_scr_end + delta >= vga_vram_end) { scr_memcpyw((u16 *) vga_vram_base, (u16 *) (oldo + delta), diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 082759447..3b0e71383 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c @@ -607,7 +607,6 @@ static void clearfb16(struct fb_info *info) static void epson1355fb_platform_release(struct device *device) { - dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n"); } static int epson1355fb_remove(struct platform_device *dev) diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index 1f98392a4..c32a2a50b 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c @@ -85,7 +85,7 @@ static struct fb_cmap default_16_colors = { * Allocates memory for a colormap @cmap. @len is the * number of entries in the palette. * - * Returns negative errno on error, or zero on success. + * Returns -1 errno on error, or zero on success. * */ @@ -116,7 +116,7 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) fail: fb_dealloc_cmap(cmap); - return -ENOMEM; + return -1; } /** diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 372aa1776..b1b4d1342 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -55,7 +55,7 @@ #define FBPIXMAPSIZE (1024 * 8) -static BLOCKING_NOTIFIER_HEAD(fb_notifier_list); +static struct notifier_block *fb_notifier_list; struct fb_info *registered_fb[FB_MAX]; int num_registered_fb; @@ -435,11 +435,6 @@ int fb_prepare_logo(struct fb_info *info, int rotate) depth = info->var.green.length; } - if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { - /* assume console colormap */ - depth = 4; - } - if (depth >= 8) { switch (info->fix.visual) { case FB_VISUAL_TRUECOLOR: @@ -559,7 +554,8 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset, int clen; clen = 0; - for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && len < 4000; fi++) + for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && clen < 4000; + fi++) if (*fi) clen += sprintf(buf + clen, "%d %s\n", (*fi)->node, @@ -795,7 +791,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) event.info = info; event.data = &mode1; - ret = blocking_notifier_call_chain(&fb_notifier_list, + ret = notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_DELETE, &event); } @@ -841,8 +837,8 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) info->flags &= ~FBINFO_MISC_USEREVENT; event.info = info; - blocking_notifier_call_chain(&fb_notifier_list, - evnt, &event); + notifier_call_chain(&fb_notifier_list, evnt, + &event); } } } @@ -865,8 +861,7 @@ fb_blank(struct fb_info *info, int blank) event.info = info; event.data = ␣ - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_BLANK, &event); + notifier_call_chain(&fb_notifier_list, FB_EVENT_BLANK, &event); } return ret; @@ -937,7 +932,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, con2fb.framebuffer = -1; event.info = info; event.data = &con2fb; - blocking_notifier_call_chain(&fb_notifier_list, + notifier_call_chain(&fb_notifier_list, FB_EVENT_GET_CONSOLE_MAP, &event); return copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; @@ -956,7 +951,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -EINVAL; event.info = info; event.data = &con2fb; - return blocking_notifier_call_chain(&fb_notifier_list, + return notifier_call_chain(&fb_notifier_list, FB_EVENT_SET_CONSOLE_MAP, &event); case FBIOBLANK: @@ -1181,6 +1176,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) vma->vm_pgoff = off >> PAGE_SHIFT; /* This is an IO map - tell maydump to skip this VMA */ vma->vm_flags |= VM_IO | VM_RESERVED; +#if defined(__sparc_v9__) + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; +#else #if defined(__mc68000__) #if defined(CONFIG_SUN3) pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE; @@ -1202,7 +1202,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) #elif defined(__i386__) || defined(__x86_64__) if (boot_cpu_data.x86 > 3) pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; -#elif defined(__mips__) || defined(__sparc_v9__) +#elif defined(__mips__) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); #elif defined(__hppa__) pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; @@ -1219,6 +1219,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; +#endif /* !__sparc_v9__ */ return 0; #endif /* !sparc32 */ } @@ -1336,7 +1337,7 @@ register_framebuffer(struct fb_info *fb_info) devfs_mk_cdev(MKDEV(FB_MAJOR, i), S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i); event.info = fb_info; - blocking_notifier_call_chain(&fb_notifier_list, + notifier_call_chain(&fb_notifier_list, FB_EVENT_FB_REGISTERED, &event); return 0; } @@ -1378,7 +1379,7 @@ unregister_framebuffer(struct fb_info *fb_info) */ int fb_register_client(struct notifier_block *nb) { - return blocking_notifier_chain_register(&fb_notifier_list, nb); + return notifier_chain_register(&fb_notifier_list, nb); } /** @@ -1387,7 +1388,7 @@ int fb_register_client(struct notifier_block *nb) */ int fb_unregister_client(struct notifier_block *nb) { - return blocking_notifier_chain_unregister(&fb_notifier_list, nb); + return notifier_chain_unregister(&fb_notifier_list, nb); } /** @@ -1405,13 +1406,11 @@ void fb_set_suspend(struct fb_info *info, int state) event.info = info; if (state) { - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_SUSPEND, &event); + notifier_call_chain(&fb_notifier_list, FB_EVENT_SUSPEND, &event); info->state = FBINFO_STATE_SUSPENDED; } else { info->state = FBINFO_STATE_RUNNING; - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_RESUME, &event); + notifier_call_chain(&fb_notifier_list, FB_EVENT_RESUME, &event); } } @@ -1483,7 +1482,7 @@ int fb_new_modelist(struct fb_info *info) if (!list_empty(&info->modelist)) { event.info = info; - err = blocking_notifier_call_chain(&fb_notifier_list, + err = notifier_call_chain(&fb_notifier_list, FB_EVENT_NEW_MODELIST, &event); } @@ -1509,7 +1508,7 @@ int fb_con_duit(struct fb_info *info, int event, void *data) evnt.info = info; evnt.data = data; - return blocking_notifier_call_chain(&fb_notifier_list, event, &evnt); + return notifier_call_chain(&fb_notifier_list, event, &evnt); } EXPORT_SYMBOL(fb_con_duit); @@ -1599,7 +1598,7 @@ static int __init video_setup(char *options) } } - return 1; + return 0; } __setup("video=", video_setup); #endif diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 53beeb4a9..7c74e7325 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -1281,7 +1281,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) -EINVAL : 0; } -#if defined(CONFIG_FB_FIRMWARE_EDID) && defined(__i386__) +#if defined(__i386__) #include /* @@ -1311,11 +1311,11 @@ const unsigned char *fb_firmware_edid(struct device *device) { return NULL; } -#endif -EXPORT_SYMBOL(fb_firmware_edid); +#endif /* _i386_ */ EXPORT_SYMBOL(fb_parse_edid); EXPORT_SYMBOL(fb_edid_to_monspecs); +EXPORT_SYMBOL(fb_firmware_edid); EXPORT_SYMBOL(fb_get_mode); EXPORT_SYMBOL(fb_validate_mode); EXPORT_SYMBOL(fb_destroy_modedb); diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 34e073997..6d2605733 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -305,6 +305,94 @@ static ssize_t show_stride(struct class_device *class_device, char *buf) return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length); } +/* Format for cmap is "%02x%c%4x%4x%4x\n" */ +/* %02x entry %c transp %4x red %4x blue %4x green \n */ +/* 256 rows at 16 chars equals 4096, the normal page size */ +/* the code will automatically adjust for different page sizes */ +static ssize_t store_cmap(struct class_device *class_device, const char *buf, + size_t count) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + int rc, i, start, length, transp = 0; + + if ((count > PAGE_SIZE) || ((count % 16) != 0)) + return -EINVAL; + + if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap) + return -EINVAL; + + sscanf(buf, "%02x", &start); + length = count / 16; + + for (i = 0; i < length; i++) + if (buf[i * 16 + 2] != ' ') + transp = 1; + + /* If we can batch, do it */ + if (fb_info->fbops->fb_setcmap && length > 1) { + struct fb_cmap umap; + + memset(&umap, 0, sizeof(umap)); + if ((rc = fb_alloc_cmap(&umap, length, transp))) + return rc; + + umap.start = start; + for (i = 0; i < length; i++) { + sscanf(&buf[i * 16 + 3], "%4hx", &umap.red[i]); + sscanf(&buf[i * 16 + 7], "%4hx", &umap.blue[i]); + sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]); + if (transp) + umap.transp[i] = (buf[i * 16 + 2] != ' '); + } + rc = fb_info->fbops->fb_setcmap(&umap, fb_info); + fb_copy_cmap(&umap, &fb_info->cmap); + fb_dealloc_cmap(&umap); + + return rc; + } + for (i = 0; i < length; i++) { + u16 red, blue, green, tsp; + + sscanf(&buf[i * 16 + 3], "%4hx", &red); + sscanf(&buf[i * 16 + 7], "%4hx", &blue); + sscanf(&buf[i * 16 + 11], "%4hx", &green); + tsp = (buf[i * 16 + 2] != ' '); + if ((rc = fb_info->fbops->fb_setcolreg(start++, + red, green, blue, tsp, fb_info))) + return rc; + + fb_info->cmap.red[i] = red; + fb_info->cmap.blue[i] = blue; + fb_info->cmap.green[i] = green; + if (transp) + fb_info->cmap.transp[i] = tsp; + } + return 0; +} + +static ssize_t show_cmap(struct class_device *class_device, char *buf) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + unsigned int i; + + if (!fb_info->cmap.red || !fb_info->cmap.blue || + !fb_info->cmap.green) + return -EINVAL; + + if (fb_info->cmap.len > PAGE_SIZE / 16) + return -EINVAL; + + /* don't mess with the format, the buffer is PAGE_SIZE */ + /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */ + for (i = 0; i < fb_info->cmap.len; i++) { + snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, + ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '), + fb_info->cmap.red[i], fb_info->cmap.blue[i], + fb_info->cmap.green[i]); + } + return 16 * fb_info->cmap.len; +} + static ssize_t store_blank(struct class_device *class_device, const char * buf, size_t count) { @@ -414,12 +502,10 @@ static ssize_t show_fbstate(struct class_device *class_device, char *buf) return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); } -/* When cmap is added back in it should be a binary attribute - * not a text one. Consideration should also be given to converting - * fbdev to use configfs instead of sysfs */ static struct class_device_attribute class_device_attrs[] = { __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), + __ATTR(color_map, S_IRUGO|S_IWUSR, show_cmap, store_cmap), __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console), __ATTR(cursor, S_IRUGO|S_IWUSR, show_cursor, store_cursor), __ATTR(mode, S_IRUGO|S_IWUSR, show_mode, store_mode), diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 7633e41ad..9c9b21d46 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -466,7 +466,8 @@ static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) unsigned long flags; u32 fg; - BUG_ON(rect->rop != ROP_COPY && rect->rop != ROP_XOR); + if (rect->rop != ROP_COPY && rect->rop != ROP_XOR) + BUG(); fg = ((u32 *)info->pseudo_palette)[rect->color]; diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig index b075fd02d..42fb9a89a 100644 --- a/drivers/video/geode/Kconfig +++ b/drivers/video/geode/Kconfig @@ -3,27 +3,22 @@ # config FB_GEODE bool "AMD Geode family framebuffer support (EXPERIMENTAL)" - default n - depends on FB && EXPERIMENTAL && X86 + depends on FB && PCI && EXPERIMENTAL && X86 ---help--- Say 'Y' here to allow you to select framebuffer drivers for the AMD Geode family of processors. config FB_GEODE_GX1 tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)" - default n depends on FB_GEODE && EXPERIMENTAL select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- Framebuffer driver for the display controller integrated into the AMD Geode GX1 processor. - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called gx1fb. If you want to compile it as a module, - say M here and read . + To compile this driver as a module, choose M here: the module will be + called gx1fb. If unsure, say N. diff --git a/drivers/video/geode/display_gx.c b/drivers/video/geode/display_gx.c deleted file mode 100644 index 825c3405f..000000000 --- a/drivers/video/geode/display_gx.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Geode GX display controller. - * - * Copyright (C) 2005 Arcom Control Systems Ltd. - * - * Portions from AMD's original 2.4 driver: - * Copyright (C) 2004 Advanced Micro 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. - */ -#include -#include -#include -#include -#include -#include - -#include "geodefb.h" -#include "display_gx.h" - -int gx_frame_buffer_size(void) -{ - /* Assuming 16 MiB. */ - return 16*1024*1024; -} - -int gx_line_delta(int xres, int bpp) -{ - /* Must be a multiple of 8 bytes. */ - return (xres * (bpp >> 3) + 7) & ~0x7; -} - -static void gx_set_mode(struct fb_info *info) -{ - struct geodefb_par *par = info->par; - u32 gcfg, dcfg; - int hactive, hblankstart, hsyncstart, hsyncend, hblankend, htotal; - int vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal; - - /* Unlock the display controller registers. */ - readl(par->dc_regs + DC_UNLOCK); - writel(DC_UNLOCK_CODE, par->dc_regs + DC_UNLOCK); - - gcfg = readl(par->dc_regs + DC_GENERAL_CFG); - dcfg = readl(par->dc_regs + DC_DISPLAY_CFG); - - /* Disable the timing generator. */ - dcfg &= ~(DC_DCFG_TGEN); - writel(dcfg, par->dc_regs + DC_DISPLAY_CFG); - - /* Wait for pending memory requests before disabling the FIFO load. */ - udelay(100); - - /* Disable FIFO load and compression. */ - gcfg &= ~(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); - writel(gcfg, par->dc_regs + DC_GENERAL_CFG); - - /* Setup DCLK and its divisor. */ - par->vid_ops->set_dclk(info); - - /* - * Setup new mode. - */ - - /* Clear all unused feature bits. */ - gcfg &= DC_GCFG_YUVM | DC_GCFG_VDSE; - dcfg = 0; - - /* Set FIFO priority (default 6/5) and enable. */ - /* FIXME: increase fifo priority for 1280x1024 and higher modes? */ - gcfg |= (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | DC_GCFG_DFLE; - - /* Framebuffer start offset. */ - writel(0, par->dc_regs + DC_FB_ST_OFFSET); - - /* Line delta and line buffer length. */ - writel(info->fix.line_length >> 3, par->dc_regs + DC_GFX_PITCH); - writel(((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2, - par->dc_regs + DC_LINE_SIZE); - - /* Enable graphics and video data and unmask address lines. */ - dcfg |= DC_DCFG_GDEN | DC_DCFG_VDEN | DC_DCFG_A20M | DC_DCFG_A18M; - - /* Set pixel format. */ - switch (info->var.bits_per_pixel) { - case 8: - dcfg |= DC_DCFG_DISP_MODE_8BPP; - break; - case 16: - dcfg |= DC_DCFG_DISP_MODE_16BPP; - dcfg |= DC_DCFG_16BPP_MODE_565; - break; - case 32: - dcfg |= DC_DCFG_DISP_MODE_24BPP; - dcfg |= DC_DCFG_PALB; - break; - } - - /* Enable timing generator. */ - dcfg |= DC_DCFG_TGEN; - - /* Horizontal and vertical timings. */ - hactive = info->var.xres; - hblankstart = hactive; - hsyncstart = hblankstart + info->var.right_margin; - hsyncend = hsyncstart + info->var.hsync_len; - hblankend = hsyncend + info->var.left_margin; - htotal = hblankend; - - vactive = info->var.yres; - vblankstart = vactive; - vsyncstart = vblankstart + info->var.lower_margin; - vsyncend = vsyncstart + info->var.vsync_len; - vblankend = vsyncend + info->var.upper_margin; - vtotal = vblankend; - - writel((hactive - 1) | ((htotal - 1) << 16), par->dc_regs + DC_H_ACTIVE_TIMING); - writel((hblankstart - 1) | ((hblankend - 1) << 16), par->dc_regs + DC_H_BLANK_TIMING); - writel((hsyncstart - 1) | ((hsyncend - 1) << 16), par->dc_regs + DC_H_SYNC_TIMING); - - writel((vactive - 1) | ((vtotal - 1) << 16), par->dc_regs + DC_V_ACTIVE_TIMING); - writel((vblankstart - 1) | ((vblankend - 1) << 16), par->dc_regs + DC_V_BLANK_TIMING); - writel((vsyncstart - 1) | ((vsyncend - 1) << 16), par->dc_regs + DC_V_SYNC_TIMING); - - /* Write final register values. */ - writel(dcfg, par->dc_regs + DC_DISPLAY_CFG); - writel(gcfg, par->dc_regs + DC_GENERAL_CFG); - - par->vid_ops->configure_display(info); - - /* Relock display controller registers */ - writel(0, par->dc_regs + DC_UNLOCK); -} - -static void gx_set_hw_palette_reg(struct fb_info *info, unsigned regno, - unsigned red, unsigned green, unsigned blue) -{ - struct geodefb_par *par = info->par; - int val; - - /* Hardware palette is in RGB 8-8-8 format. */ - val = (red << 8) & 0xff0000; - val |= (green) & 0x00ff00; - val |= (blue >> 8) & 0x0000ff; - - writel(regno, par->dc_regs + DC_PAL_ADDRESS); - writel(val, par->dc_regs + DC_PAL_DATA); -} - -struct geode_dc_ops gx_dc_ops = { - .set_mode = gx_set_mode, - .set_palette_reg = gx_set_hw_palette_reg, -}; diff --git a/drivers/video/geode/display_gx.h b/drivers/video/geode/display_gx.h deleted file mode 100644 index 86c623361..000000000 --- a/drivers/video/geode/display_gx.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Geode GX display controller - * - * Copyright (C) 2006 Arcom Control Systems Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the 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 __DISPLAY_GX_H__ -#define __DISPLAY_GX_H__ - -int gx_frame_buffer_size(void); -int gx_line_delta(int xres, int bpp); - -extern struct geode_dc_ops gx_dc_ops; - -/* Display controller registers */ - -#define DC_UNLOCK 0x00 -# define DC_UNLOCK_CODE 0x00004758 - -#define DC_GENERAL_CFG 0x04 -# define DC_GCFG_DFLE 0x00000001 -# define DC_GCFG_CURE 0x00000002 -# define DC_GCFG_ICNE 0x00000004 -# define DC_GCFG_VIDE 0x00000008 -# define DC_GCFG_CMPE 0x00000020 -# define DC_GCFG_DECE 0x00000040 -# define DC_GCFG_VGAE 0x00000080 -# define DC_GCFG_DFHPSL_MASK 0x00000F00 -# define DC_GCFG_DFHPSL_POS 8 -# define DC_GCFG_DFHPEL_MASK 0x0000F000 -# define DC_GCFG_DFHPEL_POS 12 -# define DC_GCFG_STFM 0x00010000 -# define DC_GCFG_FDTY 0x00020000 -# define DC_GCFG_VGAFT 0x00040000 -# define DC_GCFG_VDSE 0x00080000 -# define DC_GCFG_YUVM 0x00100000 -# define DC_GCFG_VFSL 0x00800000 -# define DC_GCFG_SIGE 0x01000000 -# define DC_GCFG_SGRE 0x02000000 -# define DC_GCFG_SGFR 0x04000000 -# define DC_GCFG_CRC_MODE 0x08000000 -# define DC_GCFG_DIAG 0x10000000 -# define DC_GCFG_CFRW 0x20000000 - -#define DC_DISPLAY_CFG 0x08 -# define DC_DCFG_TGEN 0x00000001 -# define DC_DCFG_GDEN 0x00000008 -# define DC_DCFG_VDEN 0x00000010 -# define DC_DCFG_TRUP 0x00000040 -# define DC_DCFG_DISP_MODE_MASK 0x00000300 -# define DC_DCFG_DISP_MODE_8BPP 0x00000000 -# define DC_DCFG_DISP_MODE_16BPP 0x00000100 -# define DC_DCFG_DISP_MODE_24BPP 0x00000200 -# define DC_DCFG_16BPP_MODE_MASK 0x00000c00 -# define DC_DCFG_16BPP_MODE_565 0x00000000 -# define DC_DCFG_16BPP_MODE_555 0x00000100 -# define DC_DCFG_16BPP_MODE_444 0x00000200 -# define DC_DCFG_DCEN 0x00080000 -# define DC_DCFG_PALB 0x02000000 -# define DC_DCFG_FRLK 0x04000000 -# define DC_DCFG_VISL 0x08000000 -# define DC_DCFG_FRSL 0x20000000 -# define DC_DCFG_A18M 0x40000000 -# define DC_DCFG_A20M 0x80000000 - -#define DC_FB_ST_OFFSET 0x10 - -#define DC_LINE_SIZE 0x30 -# define DC_LINE_SIZE_FB_LINE_SIZE_MASK 0x000007ff -# define DC_LINE_SIZE_FB_LINE_SIZE_POS 0 -# define DC_LINE_SIZE_CB_LINE_SIZE_MASK 0x007f0000 -# define DC_LINE_SIZE_CB_LINE_SIZE_POS 16 -# define DC_LINE_SIZE_VID_LINE_SIZE_MASK 0xff000000 -# define DC_LINE_SIZE_VID_LINE_SIZE_POS 24 - -#define DC_GFX_PITCH 0x34 -# define DC_GFX_PITCH_FB_PITCH_MASK 0x0000ffff -# define DC_GFX_PITCH_FB_PITCH_POS 0 -# define DC_GFX_PITCH_CB_PITCH_MASK 0xffff0000 -# define DC_GFX_PITCH_CB_PITCH_POS 16 - -#define DC_H_ACTIVE_TIMING 0x40 -#define DC_H_BLANK_TIMING 0x44 -#define DC_H_SYNC_TIMING 0x48 -#define DC_V_ACTIVE_TIMING 0x50 -#define DC_V_BLANK_TIMING 0x54 -#define DC_V_SYNC_TIMING 0x58 - -#define DC_PAL_ADDRESS 0x70 -#define DC_PAL_DATA 0x74 - -#endif /* !__DISPLAY_GX1_H__ */ diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c deleted file mode 100644 index 89c34b15f..000000000 --- a/drivers/video/geode/gxfb_core.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Geode GX framebuffer driver. - * - * Copyright (C) 2006 Arcom Control Systems Ltd. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - * This driver assumes that the BIOS has created a virtual PCI device header - * for the video device. The PCI header is assumed to contain the following - * BARs: - * - * BAR0 - framebuffer memory - * BAR1 - graphics processor registers - * BAR2 - display controller registers - * BAR3 - video processor and flat panel control registers. - * - * 16 MiB of framebuffer memory is assumed to be available. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "geodefb.h" -#include "display_gx.h" -#include "video_gx.h" - -static char mode_option[32] = "640x480-16@60"; - -/* Modes relevant to the GX (taken from modedb.c) */ -static const struct fb_videomode __initdata gx_modedb[] = { - /* 640x480-60 VESA */ - { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 640x480-75 VESA */ - { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 640x480-85 VESA */ - { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 800x600-60 VESA */ - { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 800x600-75 VESA */ - { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 800x600-85 VESA */ - { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1024x768-60 VESA */ - { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1024x768-75 VESA */ - { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1024x768-85 VESA */ - { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1280x960-60 VESA */ - { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1280x960-85 VESA */ - { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1280x1024-60 VESA */ - { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1280x1024-75 VESA */ - { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1280x1024-85 VESA */ - { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1600x1200-60 VESA */ - { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1600x1200-75 VESA */ - { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1600x1200-85 VESA */ - { NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, -}; - -static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - if (var->xres > 1600 || var->yres > 1200) - return -EINVAL; - if ((var->xres > 1280 || var->yres > 1024) && var->bits_per_pixel > 16) - return -EINVAL; - - if (var->bits_per_pixel == 32) { - var->red.offset = 16; var->red.length = 8; - var->green.offset = 8; var->green.length = 8; - var->blue.offset = 0; var->blue.length = 8; - } else if (var->bits_per_pixel == 16) { - var->red.offset = 11; var->red.length = 5; - var->green.offset = 5; var->green.length = 6; - var->blue.offset = 0; var->blue.length = 5; - } else if (var->bits_per_pixel == 8) { - var->red.offset = 0; var->red.length = 8; - var->green.offset = 0; var->green.length = 8; - var->blue.offset = 0; var->blue.length = 8; - } else - return -EINVAL; - var->transp.offset = 0; var->transp.length = 0; - - /* Enough video memory? */ - if (gx_line_delta(var->xres, var->bits_per_pixel) * var->yres > info->fix.smem_len) - return -EINVAL; - - /* FIXME: Check timing parameters here? */ - - return 0; -} - -static int gxfb_set_par(struct fb_info *info) -{ - struct geodefb_par *par = info->par; - - if (info->var.bits_per_pixel > 8) { - info->fix.visual = FB_VISUAL_TRUECOLOR; - fb_dealloc_cmap(&info->cmap); - } else { - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - fb_alloc_cmap(&info->cmap, 1<var.bits_per_pixel, 0); - } - - info->fix.line_length = gx_line_delta(info->var.xres, info->var.bits_per_pixel); - - par->dc_ops->set_mode(info); - - return 0; -} - -static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) -{ - chan &= 0xffff; - chan >>= 16 - bf->length; - return chan << bf->offset; -} - -static int gxfb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) -{ - struct geodefb_par *par = info->par; - - if (info->var.grayscale) { - /* grayscale = 0.30*R + 0.59*G + 0.11*B */ - red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; - } - - /* Truecolor has hardware independent palette */ - if (info->fix.visual == FB_VISUAL_TRUECOLOR) { - u32 *pal = info->pseudo_palette; - u32 v; - - if (regno >= 16) - return -EINVAL; - - v = chan_to_field(red, &info->var.red); - v |= chan_to_field(green, &info->var.green); - v |= chan_to_field(blue, &info->var.blue); - - pal[regno] = v; - } else { - if (regno >= 256) - return -EINVAL; - - par->dc_ops->set_palette_reg(info, regno, red, green, blue); - } - - return 0; -} - -static int gxfb_blank(int blank_mode, struct fb_info *info) -{ - struct geodefb_par *par = info->par; - - return par->vid_ops->blank_display(info, blank_mode); -} - -static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev) -{ - struct geodefb_par *par = info->par; - int fb_len; - int ret; - - ret = pci_enable_device(dev); - if (ret < 0) - return ret; - - ret = pci_request_region(dev, 3, "gxfb (video processor)"); - if (ret < 0) - return ret; - par->vid_regs = ioremap(pci_resource_start(dev, 3), - pci_resource_len(dev, 3)); - if (!par->vid_regs) - return -ENOMEM; - - ret = pci_request_region(dev, 2, "gxfb (display controller)"); - if (ret < 0) - return ret; - par->dc_regs = ioremap(pci_resource_start(dev, 2), pci_resource_len(dev, 2)); - if (!par->dc_regs) - return -ENOMEM; - - ret = pci_request_region(dev, 0, "gxfb (framebuffer)"); - if (ret < 0) - return ret; - if ((fb_len = gx_frame_buffer_size()) < 0) - return -ENOMEM; - info->fix.smem_start = pci_resource_start(dev, 0); - info->fix.smem_len = fb_len; - info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); - if (!info->screen_base) - return -ENOMEM; - - dev_info(&dev->dev, "%d Kibyte of video memory at 0x%lx\n", - info->fix.smem_len / 1024, info->fix.smem_start); - - return 0; -} - -static struct fb_ops gxfb_ops = { - .owner = THIS_MODULE, - .fb_check_var = gxfb_check_var, - .fb_set_par = gxfb_set_par, - .fb_setcolreg = gxfb_setcolreg, - .fb_blank = gxfb_blank, - /* No HW acceleration for now. */ - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - -static struct fb_info * __init gxfb_init_fbinfo(struct device *dev) -{ - struct geodefb_par *par; - struct fb_info *info; - - /* Alloc enough space for the pseudo palette. */ - info = framebuffer_alloc(sizeof(struct geodefb_par) + sizeof(u32) * 16, dev); - if (!info) - return NULL; - - par = info->par; - - strcpy(info->fix.id, "Geode GX"); - - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.type_aux = 0; - info->fix.xpanstep = 0; - info->fix.ypanstep = 0; - info->fix.ywrapstep = 0; - info->fix.accel = FB_ACCEL_NONE; - - info->var.nonstd = 0; - info->var.activate = FB_ACTIVATE_NOW; - info->var.height = -1; - info->var.width = -1; - info->var.accel_flags = 0; - info->var.vmode = FB_VMODE_NONINTERLACED; - - info->fbops = &gxfb_ops; - info->flags = FBINFO_DEFAULT; - info->node = -1; - - info->pseudo_palette = (void *)par + sizeof(struct geodefb_par); - - info->var.grayscale = 0; - - return info; -} - -static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - struct geodefb_par *par; - struct fb_info *info; - int ret; - - info = gxfb_init_fbinfo(&pdev->dev); - if (!info) - return -ENOMEM; - par = info->par; - - /* GX display controller and GX video device. */ - par->dc_ops = &gx_dc_ops; - par->vid_ops = &gx_vid_ops; - - if ((ret = gxfb_map_video_memory(info, pdev)) < 0) { - dev_err(&pdev->dev, "failed to map frame buffer or controller registers\n"); - goto err; - } - - ret = fb_find_mode(&info->var, info, mode_option, - gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16); - if (ret == 0 || ret == 4) { - dev_err(&pdev->dev, "could not find valid video mode\n"); - ret = -EINVAL; - goto err; - } - - /* Clear the frame buffer of garbage. */ - memset_io(info->screen_base, 0, info->fix.smem_len); - - gxfb_check_var(&info->var, info); - gxfb_set_par(info); - - if (register_framebuffer(info) < 0) { - ret = -EINVAL; - goto err; - } - pci_set_drvdata(pdev, info); - printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); - return 0; - - err: - if (info->screen_base) { - iounmap(info->screen_base); - pci_release_region(pdev, 0); - } - if (par->vid_regs) { - iounmap(par->vid_regs); - pci_release_region(pdev, 3); - } - if (par->dc_regs) { - iounmap(par->dc_regs); - pci_release_region(pdev, 2); - } - - pci_disable_device(pdev); - - if (info) - framebuffer_release(info); - return ret; -} - -static void gxfb_remove(struct pci_dev *pdev) -{ - struct fb_info *info = pci_get_drvdata(pdev); - struct geodefb_par *par = info->par; - - unregister_framebuffer(info); - - iounmap((void __iomem *)info->screen_base); - pci_release_region(pdev, 0); - - iounmap(par->vid_regs); - pci_release_region(pdev, 3); - - iounmap(par->dc_regs); - pci_release_region(pdev, 2); - - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - - framebuffer_release(info); -} - -static struct pci_device_id gxfb_id_table[] = { - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_VIDEO, - PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, - 0xff0000, 0 }, - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, gxfb_id_table); - -static struct pci_driver gxfb_driver = { - .name = "gxfb", - .id_table = gxfb_id_table, - .probe = gxfb_probe, - .remove = gxfb_remove, -}; - -static int __init gxfb_init(void) -{ -#ifndef MODULE - if (fb_get_options("gxfb", NULL)) - return -ENODEV; -#endif - return pci_register_driver(&gxfb_driver); -} - -static void __exit gxfb_cleanup(void) -{ - pci_unregister_driver(&gxfb_driver); -} - -module_init(gxfb_init); -module_exit(gxfb_cleanup); - -module_param_string(mode, mode_option, sizeof(mode_option), 0444); -MODULE_PARM_DESC(mode, "video mode (x[-][@])"); - -MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode GX"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c deleted file mode 100644 index 2b2a7880e..000000000 --- a/drivers/video/geode/video_gx.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Geode GX video processor device. - * - * Copyright (C) 2006 Arcom Control Systems Ltd. - * - * Portions from AMD's original 2.4 driver: - * Copyright (C) 2004 Advanced Micro 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. - */ -#include -#include -#include -#include -#include - -#include "geodefb.h" -#include "video_gx.h" - - -/* - * Tables of register settings for various DOTCLKs. - */ -struct gx_pll_entry { - long pixclock; /* ps */ - u32 sys_rstpll_bits; - u32 dotpll_value; -}; - -#define POSTDIV3 ((u32)MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3) -#define PREMULT2 ((u32)MSR_GLCP_SYS_RSTPLL_DOTPREMULT2) -#define PREDIV2 ((u32)MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3) - -static const struct gx_pll_entry gx_pll_table_48MHz[] = { - { 40123, POSTDIV3, 0x00000BF2 }, /* 24.9230 */ - { 39721, 0, 0x00000037 }, /* 25.1750 */ - { 35308, POSTDIV3|PREMULT2, 0x00000B1A }, /* 28.3220 */ - { 31746, POSTDIV3, 0x000002D2 }, /* 31.5000 */ - { 27777, POSTDIV3|PREMULT2, 0x00000FE2 }, /* 36.0000 */ - { 26666, POSTDIV3, 0x0000057A }, /* 37.5000 */ - { 25000, POSTDIV3, 0x0000030A }, /* 40.0000 */ - { 22271, 0, 0x00000063 }, /* 44.9000 */ - { 20202, 0, 0x0000054B }, /* 49.5000 */ - { 20000, 0, 0x0000026E }, /* 50.0000 */ - { 19860, PREMULT2, 0x00000037 }, /* 50.3500 */ - { 18518, POSTDIV3|PREMULT2, 0x00000B0D }, /* 54.0000 */ - { 17777, 0, 0x00000577 }, /* 56.2500 */ - { 17733, 0, 0x000007F7 }, /* 56.3916 */ - { 17653, 0, 0x0000057B }, /* 56.6444 */ - { 16949, PREMULT2, 0x00000707 }, /* 59.0000 */ - { 15873, POSTDIV3|PREMULT2, 0x00000B39 }, /* 63.0000 */ - { 15384, POSTDIV3|PREMULT2, 0x00000B45 }, /* 65.0000 */ - { 14814, POSTDIV3|PREMULT2, 0x00000FC1 }, /* 67.5000 */ - { 14124, POSTDIV3, 0x00000561 }, /* 70.8000 */ - { 13888, POSTDIV3, 0x000007E1 }, /* 72.0000 */ - { 13426, PREMULT2, 0x00000F4A }, /* 74.4810 */ - { 13333, 0, 0x00000052 }, /* 75.0000 */ - { 12698, 0, 0x00000056 }, /* 78.7500 */ - { 12500, POSTDIV3|PREMULT2, 0x00000709 }, /* 80.0000 */ - { 11135, PREMULT2, 0x00000262 }, /* 89.8000 */ - { 10582, 0, 0x000002D2 }, /* 94.5000 */ - { 10101, PREMULT2, 0x00000B4A }, /* 99.0000 */ - { 10000, PREMULT2, 0x00000036 }, /* 100.0000 */ - { 9259, 0, 0x000007E2 }, /* 108.0000 */ - { 8888, 0, 0x000007F6 }, /* 112.5000 */ - { 7692, POSTDIV3|PREMULT2, 0x00000FB0 }, /* 130.0000 */ - { 7407, POSTDIV3|PREMULT2, 0x00000B50 }, /* 135.0000 */ - { 6349, 0, 0x00000055 }, /* 157.5000 */ - { 6172, 0, 0x000009C1 }, /* 162.0000 */ - { 5787, PREMULT2, 0x0000002D }, /* 172.798 */ - { 5698, 0, 0x000002C1 }, /* 175.5000 */ - { 5291, 0, 0x000002D1 }, /* 189.0000 */ - { 4938, 0, 0x00000551 }, /* 202.5000 */ - { 4357, 0, 0x0000057D }, /* 229.5000 */ -}; - -static const struct gx_pll_entry gx_pll_table_14MHz[] = { - { 39721, 0, 0x00000037 }, /* 25.1750 */ - { 35308, 0, 0x00000B7B }, /* 28.3220 */ - { 31746, 0, 0x000004D3 }, /* 31.5000 */ - { 27777, 0, 0x00000BE3 }, /* 36.0000 */ - { 26666, 0, 0x0000074F }, /* 37.5000 */ - { 25000, 0, 0x0000050B }, /* 40.0000 */ - { 22271, 0, 0x00000063 }, /* 44.9000 */ - { 20202, 0, 0x0000054B }, /* 49.5000 */ - { 20000, 0, 0x0000026E }, /* 50.0000 */ - { 19860, 0, 0x000007C3 }, /* 50.3500 */ - { 18518, 0, 0x000007E3 }, /* 54.0000 */ - { 17777, 0, 0x00000577 }, /* 56.2500 */ - { 17733, 0, 0x000002FB }, /* 56.3916 */ - { 17653, 0, 0x0000057B }, /* 56.6444 */ - { 16949, 0, 0x0000058B }, /* 59.0000 */ - { 15873, 0, 0x0000095E }, /* 63.0000 */ - { 15384, 0, 0x0000096A }, /* 65.0000 */ - { 14814, 0, 0x00000BC2 }, /* 67.5000 */ - { 14124, 0, 0x0000098A }, /* 70.8000 */ - { 13888, 0, 0x00000BE2 }, /* 72.0000 */ - { 13333, 0, 0x00000052 }, /* 75.0000 */ - { 12698, 0, 0x00000056 }, /* 78.7500 */ - { 12500, 0, 0x0000050A }, /* 80.0000 */ - { 11135, 0, 0x0000078E }, /* 89.8000 */ - { 10582, 0, 0x000002D2 }, /* 94.5000 */ - { 10101, 0, 0x000011F6 }, /* 99.0000 */ - { 10000, 0, 0x0000054E }, /* 100.0000 */ - { 9259, 0, 0x000007E2 }, /* 108.0000 */ - { 8888, 0, 0x000002FA }, /* 112.5000 */ - { 7692, 0, 0x00000BB1 }, /* 130.0000 */ - { 7407, 0, 0x00000975 }, /* 135.0000 */ - { 6349, 0, 0x00000055 }, /* 157.5000 */ - { 6172, 0, 0x000009C1 }, /* 162.0000 */ - { 5698, 0, 0x000002C1 }, /* 175.5000 */ - { 5291, 0, 0x00000539 }, /* 189.0000 */ - { 4938, 0, 0x00000551 }, /* 202.5000 */ - { 4357, 0, 0x0000057D }, /* 229.5000 */ -}; - -static void gx_set_dclk_frequency(struct fb_info *info) -{ - const struct gx_pll_entry *pll_table; - int pll_table_len; - int i, best_i; - long min, diff; - u64 dotpll, sys_rstpll; - int timeout = 1000; - - /* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */ - if (cpu_data->x86_mask == 1) { - pll_table = gx_pll_table_14MHz; - pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz); - } else { - pll_table = gx_pll_table_48MHz; - pll_table_len = ARRAY_SIZE(gx_pll_table_48MHz); - } - - /* Search the table for the closest pixclock. */ - best_i = 0; - min = abs(pll_table[0].pixclock - info->var.pixclock); - for (i = 1; i < pll_table_len; i++) { - diff = abs(pll_table[i].pixclock - info->var.pixclock); - if (diff < min) { - min = diff; - best_i = i; - } - } - - rdmsrl(MSR_GLCP_SYS_RSTPLL, sys_rstpll); - rdmsrl(MSR_GLCP_DOTPLL, dotpll); - - /* Program new M, N and P. */ - dotpll &= 0x00000000ffffffffull; - dotpll |= (u64)pll_table[best_i].dotpll_value << 32; - dotpll |= MSR_GLCP_DOTPLL_DOTRESET; - dotpll &= ~MSR_GLCP_DOTPLL_BYPASS; - - wrmsrl(MSR_GLCP_DOTPLL, dotpll); - - /* Program dividers. */ - sys_rstpll &= ~( MSR_GLCP_SYS_RSTPLL_DOTPREDIV2 - | MSR_GLCP_SYS_RSTPLL_DOTPREMULT2 - | MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3 ); - sys_rstpll |= pll_table[best_i].sys_rstpll_bits; - - wrmsrl(MSR_GLCP_SYS_RSTPLL, sys_rstpll); - - /* Clear reset bit to start PLL. */ - dotpll &= ~(MSR_GLCP_DOTPLL_DOTRESET); - wrmsrl(MSR_GLCP_DOTPLL, dotpll); - - /* Wait for LOCK bit. */ - do { - rdmsrl(MSR_GLCP_DOTPLL, dotpll); - } while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK)); -} - -static void gx_configure_display(struct fb_info *info) -{ - struct geodefb_par *par = info->par; - u32 dcfg, fp_pm; - - dcfg = readl(par->vid_regs + GX_DCFG); - - /* Clear bits from existing mode. */ - dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK - | GX_DCFG_CRT_HSYNC_POL | GX_DCFG_CRT_VSYNC_POL - | GX_DCFG_VSYNC_EN | GX_DCFG_HSYNC_EN); - - /* Set default sync skew. */ - dcfg |= GX_DCFG_CRT_SYNC_SKW_DFLT; - - /* Enable hsync and vsync. */ - dcfg |= GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN; - - /* Sync polarities. */ - if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) - dcfg |= GX_DCFG_CRT_HSYNC_POL; - if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) - dcfg |= GX_DCFG_CRT_VSYNC_POL; - - writel(dcfg, par->vid_regs + GX_DCFG); - - /* Power on flat panel. */ - fp_pm = readl(par->vid_regs + GX_FP_PM); - fp_pm |= GX_FP_PM_P; - writel(fp_pm, par->vid_regs + GX_FP_PM); -} - -static int gx_blank_display(struct fb_info *info, int blank_mode) -{ - struct geodefb_par *par = info->par; - u32 dcfg, fp_pm; - int blank, hsync, vsync; - - /* CRT power saving modes. */ - switch (blank_mode) { - case FB_BLANK_UNBLANK: - blank = 0; hsync = 1; vsync = 1; - break; - case FB_BLANK_NORMAL: - blank = 1; hsync = 1; vsync = 1; - break; - case FB_BLANK_VSYNC_SUSPEND: - blank = 1; hsync = 1; vsync = 0; - break; - case FB_BLANK_HSYNC_SUSPEND: - blank = 1; hsync = 0; vsync = 1; - break; - case FB_BLANK_POWERDOWN: - blank = 1; hsync = 0; vsync = 0; - break; - default: - return -EINVAL; - } - dcfg = readl(par->vid_regs + GX_DCFG); - dcfg &= ~(GX_DCFG_DAC_BL_EN - | GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN); - if (!blank) - dcfg |= GX_DCFG_DAC_BL_EN; - if (hsync) - dcfg |= GX_DCFG_HSYNC_EN; - if (vsync) - dcfg |= GX_DCFG_VSYNC_EN; - writel(dcfg, par->vid_regs + GX_DCFG); - - /* Power on/off flat panel. */ - fp_pm = readl(par->vid_regs + GX_FP_PM); - if (blank_mode == FB_BLANK_POWERDOWN) - fp_pm &= ~GX_FP_PM_P; - else - fp_pm |= GX_FP_PM_P; - writel(fp_pm, par->vid_regs + GX_FP_PM); - - return 0; -} - -struct geode_vid_ops gx_vid_ops = { - .set_dclk = gx_set_dclk_frequency, - .configure_display = gx_configure_display, - .blank_display = gx_blank_display, -}; diff --git a/drivers/video/geode/video_gx.h b/drivers/video/geode/video_gx.h deleted file mode 100644 index 2d9211f3e..000000000 --- a/drivers/video/geode/video_gx.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Geode GX video device - * - * Copyright (C) 2006 Arcom Control Systems Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the 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 __VIDEO_GX_H__ -#define __VIDEO_GX_H__ - -extern struct geode_vid_ops gx_vid_ops; - -/* Geode GX video processor registers */ - -#define GX_DCFG 0x0008 -# define GX_DCFG_CRT_EN 0x00000001 -# define GX_DCFG_HSYNC_EN 0x00000002 -# define GX_DCFG_VSYNC_EN 0x00000004 -# define GX_DCFG_DAC_BL_EN 0x00000008 -# define GX_DCFG_CRT_HSYNC_POL 0x00000100 -# define GX_DCFG_CRT_VSYNC_POL 0x00000200 -# define GX_DCFG_CRT_SYNC_SKW_MASK 0x0001C000 -# define GX_DCFG_CRT_SYNC_SKW_DFLT 0x00010000 -# define GX_DCFG_VG_CK 0x00100000 -# define GX_DCFG_GV_GAM 0x00200000 -# define GX_DCFG_DAC_VREF 0x04000000 - -/* Geode GX flat panel display control registers */ -#define GX_FP_PM 0x410 -# define GX_FP_PM_P 0x01000000 - -/* Geode GX clock control MSRs */ - -#define MSR_GLCP_SYS_RSTPLL 0x4c000014 -# define MSR_GLCP_SYS_RSTPLL_DOTPREDIV2 (0x0000000000000002ull) -# define MSR_GLCP_SYS_RSTPLL_DOTPREMULT2 (0x0000000000000004ull) -# define MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3 (0x0000000000000008ull) - -#define MSR_GLCP_DOTPLL 0x4c000015 -# define MSR_GLCP_DOTPLL_DOTRESET (0x0000000000000001ull) -# define MSR_GLCP_DOTPLL_BYPASS (0x0000000000008000ull) -# define MSR_GLCP_DOTPLL_LOCK (0x0000000002000000ull) - -#endif /* !__VIDEO_GX_H__ */ diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c index abd920a66..bebdac59d 100644 --- a/drivers/video/hpfb.c +++ b/drivers/video/hpfb.c @@ -386,9 +386,7 @@ int __init hpfb_init(void) if (fb_get_options("hpfb", NULL)) return -ENODEV; - err = dio_register_driver(&hpfb_driver); - if (err) - return err; + dio_module_init(&hpfb_driver); fs = get_fs(); set_fs(KERNEL_DS); diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c index 3fe3ae1af..e3c8b5f1c 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/i810/i810-i2c.c @@ -210,7 +210,8 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn) } } - *out_edid = edid; + if (out_edid) + *out_edid = edid; return (edid) ? 0 : 1; } diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 44aa2ffff..788297e9d 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -76,8 +76,8 @@ * * Experiment with v_offset to find out which works best for you. */ -static u32 v_offset_default __devinitdata; /* For 32 MiB Aper size, 8 should be the default */ -static u32 voffset __devinitdata; +static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */ +static u32 voffset __initdata = 0; static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor); static int __devinit i810fb_init_pci (struct pci_dev *dev, diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index f73c642b5..7db42542e 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -440,9 +440,9 @@ getclkMHz(struct imstt_par *par) static void setclkMHz(struct imstt_par *par, __u32 MHz) { - __u32 clk_m, clk_n, x, stage, spilled; + __u32 clk_m, clk_n, clk_p, x, stage, spilled; - clk_m = clk_n = 0; + clk_m = clk_n = clk_p = 0; stage = spilled = 0; for (;;) { switch (stage) { @@ -453,7 +453,7 @@ setclkMHz(struct imstt_par *par, __u32 MHz) clk_n++; break; } - x = 20 * (clk_m + 1) / (clk_n + 1); + x = 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1)); if (x == MHz) break; if (x > MHz) { @@ -466,7 +466,7 @@ setclkMHz(struct imstt_par *par, __u32 MHz) par->init.pclk_m = clk_m; par->init.pclk_n = clk_n; - par->init.pclk_p = 0; + par->init.pclk_p = clk_p; } static struct imstt_regvals * @@ -1372,24 +1372,18 @@ init_imstt(struct fb_info *info) write_reg_le32(par->dc_regs, STGCTL, tmp & ~0x1); write_reg_le32(par->dc_regs, SSR, 0); - /* set default values for DAC registers */ + /* set default values for DAC registers */ if (par->ramdac == IBM) { - par->cmap_regs[PPMASK] = 0xff; - eieio(); - par->cmap_regs[PIDXHI] = 0; - eieio(); - for (i = 0; i < ARRAY_SIZE(ibm_initregs); i++) { - par->cmap_regs[PIDXLO] = ibm_initregs[i].addr; - eieio(); - par->cmap_regs[PIDXDATA] = ibm_initregs[i].value; - eieio(); + par->cmap_regs[PPMASK] = 0xff; eieio(); + par->cmap_regs[PIDXHI] = 0; eieio(); + for (i = 0; i < sizeof(ibm_initregs) / sizeof(*ibm_initregs); i++) { + par->cmap_regs[PIDXLO] = ibm_initregs[i].addr; eieio(); + par->cmap_regs[PIDXDATA] = ibm_initregs[i].value; eieio(); } } else { - for (i = 0; i < ARRAY_SIZE(tvp_initregs); i++) { - par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr; - eieio(); - par->cmap_regs[TVPIDATA] = tvp_initregs[i].value; - eieio(); + for (i = 0; i < sizeof(tvp_initregs) / sizeof(*tvp_initregs); i++) { + par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr; eieio(); + par->cmap_regs[TVPIDATA] = tvp_initregs[i].value; eieio(); } } diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile index b985dfad6..4ef5cd196 100644 --- a/drivers/video/logo/Makefile +++ b/drivers/video/logo/Makefile @@ -34,7 +34,7 @@ extra-y += $(call logo-cfiles,_clut224,ppm) extra-y += $(call logo-cfiles,_gray256,pgm) # Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..." -quiet_cmd_logo = LOGO $@ +quiet_cmd_logo = LOGO $@ cmd_logo = scripts/pnmtologo \ -t $(patsubst $*_%,%,$(notdir $(basename $<))) \ -n $(notdir $(basename $<)) -o $@ $< diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c index c0385c6f7..2fc71081f 100644 --- a/drivers/video/macmodes.c +++ b/drivers/video/macmodes.c @@ -380,7 +380,7 @@ int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info, if (mode_option && !strncmp(mode_option, "mac", 3)) { mode_option += 3; db = mac_modedb; - dbsize = ARRAY_SIZE(mac_modedb); + dbsize = sizeof(mac_modedb)/sizeof(*mac_modedb); } return fb_find_mode(var, info, mode_option, db, dbsize, &mac_modedb[DEFAULT_MODEDB_INDEX], default_bpp); diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c index 440272ad1..8073a73f6 100644 --- a/drivers/video/matrox/g450_pll.c +++ b/drivers/video/matrox/g450_pll.c @@ -316,24 +316,14 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, case M_PIXEL_PLL_B: case M_PIXEL_PLL_C: { - u_int8_t tmp, xpwrctrl; + u_int8_t tmp; unsigned long flags; matroxfb_DAC_lock_irqsave(flags); - - xpwrctrl = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL); - matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN); - mga_outb(M_SEQ_INDEX, M_SEQ1); - mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF); tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL); - tmp |= M1064_XPIXCLKCTRL_DIS; if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) { - tmp |= M1064_XPIXCLKCTRL_PLL_UP; + matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp | M1064_XPIXCLKCTRL_PLL_UP); } - matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); - matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0); - matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl); - matroxfb_DAC_unlock_irqrestore(flags); } { @@ -428,15 +418,6 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, frequency to higher - with <= lowest wins, while with < highest one wins */ if (delta <= deltaarray[idx-1]) { - /* all else being equal except VCO, - * choose VCO not near (within 1/16th or so) VCOmin - * (freqs near VCOmin aren't as stable) - */ - if (delta == deltaarray[idx-1] - && vco != g450_mnp2vco(PMINFO mnparray[idx-1]) - && vco < (pi->vcomin * 17 / 16)) { - break; - } mnparray[idx] = mnparray[idx-1]; deltaarray[idx] = deltaarray[idx-1]; } else { diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c index a456e67a5..0fbd9b514 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.c +++ b/drivers/video/matrox/matroxfb_DAC1064.c @@ -12,6 +12,7 @@ * */ +/* make checkconfig does not walk through include tree :-( */ #include #include "matroxfb_DAC1064.h" diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h index 56513a5d2..a6a470127 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.h +++ b/drivers/video/matrox/matroxfb_DAC1064.h @@ -1,6 +1,7 @@ #ifndef __MATROXFB_DAC1064_H__ #define __MATROXFB_DAC1064_H__ +/* make checkconfig does not walk through include tree */ #include #include "matroxfb_base.h" @@ -40,7 +41,6 @@ void DAC1064_global_restore(WPMINFO2); #define M1064_XCURCOL1RED 0x0C #define M1064_XCURCOL1GREEN 0x0D #define M1064_XCURCOL1BLUE 0x0E -#define M1064_XDVICLKCTRL 0x0F #define M1064_XCURCOL2RED 0x10 #define M1064_XCURCOL2GREEN 0x11 #define M1064_XCURCOL2BLUE 0x12 @@ -145,7 +145,6 @@ void DAC1064_global_restore(WPMINFO2); #define M1064_XVIDPLLN 0x8F #define M1064_XPWRCTRL 0xA0 -#define M1064_XPWRCTRL_PANELPDN 0x04 #define M1064_XPANMODE 0xA2 diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c index 23ebad0a1..537ade5d8 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.c +++ b/drivers/video/matrox/matroxfb_Ti3026.c @@ -78,6 +78,7 @@ * */ +/* make checkconfig does not verify included files... */ #include #include "matroxfb_Ti3026.h" diff --git a/drivers/video/matrox/matroxfb_Ti3026.h b/drivers/video/matrox/matroxfb_Ti3026.h index 536e5f69d..541933d7e 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.h +++ b/drivers/video/matrox/matroxfb_Ti3026.h @@ -1,6 +1,7 @@ #ifndef __MATROXFB_TI3026_H__ #define __MATROXFB_TI3026_H__ +/* make checkconfig does not walk through whole include tree */ #include #include "matroxfb_base.h" diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 23c1827b2..4055ff6f5 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -99,6 +99,7 @@ * */ +/* make checkconfig does not check included files... */ #include #include @@ -115,7 +116,6 @@ #include #ifdef CONFIG_PPC_PMAC -#include unsigned char nvram_read_byte(int); static int default_vmode = VMODE_NVRAM; static int default_cmode = CMODE_NVRAM; @@ -1834,7 +1834,7 @@ static int initMatrox2(WPMINFO struct board* b){ /* FIXME: Where to move this?! */ #if defined(CONFIG_PPC_PMAC) #ifndef MODULE - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct fb_var_screeninfo var; if (default_vmode <= 0 || default_vmode > VMODE_MAX) default_vmode = VMODE_640_480_60; diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index b71737178..3a3e1804c 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -672,8 +672,6 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv); #define M_SEQ_INDEX 0x1FC4 #define M_SEQ_DATA 0x1FC5 -#define M_SEQ1 0x01 -#define M_SEQ1_SCROFF 0x20 #define M_MISC_REG_READ 0x1FCC diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c index 4d610b405..c122d8743 100644 --- a/drivers/video/matrox/matroxfb_g450.c +++ b/drivers/video/matrox/matroxfb_g450.c @@ -59,7 +59,7 @@ static const struct mctl g450_controls[] = }, offsetof(struct matrox_fb_info, altout.tvo_params.testout) }, }; -#define G450CTRLS ARRAY_SIZE(g450_controls) +#define G450CTRLS (sizeof(g450_controls)/sizeof(g450_controls[0])) /* Return: positive number: id found -EINVAL: id not found, return failure diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index 5d29a26b8..6019710dc 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c @@ -89,12 +89,12 @@ static const struct mctl maven_controls[] = }, offsetof(struct matrox_fb_info, altout.tvo_params.hue) }, { { V4L2_CID_GAMMA, V4L2_CTRL_TYPE_INTEGER, "gamma", - 0, ARRAY_SIZE(maven_gamma) - 1, 1, 3, + 0, sizeof(maven_gamma)/sizeof(maven_gamma[0])-1, 1, 3, 0, }, offsetof(struct matrox_fb_info, altout.tvo_params.gamma) }, { { MATROXFB_CID_TESTOUT, V4L2_CTRL_TYPE_BOOLEAN, "test output", - 0, 1, 1, 0, + 0, 1, 1, 0, 0, }, offsetof(struct matrox_fb_info, altout.tvo_params.testout) }, { { MATROXFB_CID_DEFLICKER, V4L2_CTRL_TYPE_INTEGER, @@ -105,7 +105,7 @@ static const struct mctl maven_controls[] = }; -#define MAVCTRLS ARRAY_SIZE(maven_controls) +#define MAVCTRLS (sizeof(maven_controls)/sizeof(maven_controls[0])) /* Return: positive number: id found -EINVAL: id not found, return failure @@ -129,7 +129,7 @@ static int get_ctrl_id(__u32 v4l2_id) { struct maven_data { struct matrox_fb_info* primary_head; - struct i2c_client client; + struct i2c_client* client; int version; }; @@ -970,7 +970,7 @@ static inline int maven_compute_timming(struct maven_data* md, static int maven_program_timming(struct maven_data* md, const struct mavenregs* m) { - struct i2c_client* c = &md->client; + struct i2c_client* c = md->client; if (m->mode == MATROXFB_OUTPUT_MODE_MONITOR) { LR(0x80); @@ -1007,7 +1007,7 @@ static int maven_program_timming(struct maven_data* md, } static inline int maven_resync(struct maven_data* md) { - struct i2c_client* c = &md->client; + struct i2c_client* c = md->client; maven_set_reg(c, 0x95, 0x20); /* start whole thing */ return 0; } @@ -1065,48 +1065,48 @@ static int maven_set_control (struct maven_data* md, maven_compute_bwlevel(md, &blacklevel, &whitelevel); blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8); whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8); - maven_set_reg_pair(&md->client, 0x0e, blacklevel); - maven_set_reg_pair(&md->client, 0x1e, whitelevel); + maven_set_reg_pair(md->client, 0x0e, blacklevel); + maven_set_reg_pair(md->client, 0x1e, whitelevel); } break; case V4L2_CID_SATURATION: { - maven_set_reg(&md->client, 0x20, p->value); - maven_set_reg(&md->client, 0x22, p->value); + maven_set_reg(md->client, 0x20, p->value); + maven_set_reg(md->client, 0x22, p->value); } break; case V4L2_CID_HUE: { - maven_set_reg(&md->client, 0x25, p->value); + maven_set_reg(md->client, 0x25, p->value); } break; case V4L2_CID_GAMMA: { const struct maven_gamma* g; g = maven_compute_gamma(md); - maven_set_reg(&md->client, 0x83, g->reg83); - maven_set_reg(&md->client, 0x84, g->reg84); - maven_set_reg(&md->client, 0x85, g->reg85); - maven_set_reg(&md->client, 0x86, g->reg86); - maven_set_reg(&md->client, 0x87, g->reg87); - maven_set_reg(&md->client, 0x88, g->reg88); - maven_set_reg(&md->client, 0x89, g->reg89); - maven_set_reg(&md->client, 0x8a, g->reg8a); - maven_set_reg(&md->client, 0x8b, g->reg8b); + maven_set_reg(md->client, 0x83, g->reg83); + maven_set_reg(md->client, 0x84, g->reg84); + maven_set_reg(md->client, 0x85, g->reg85); + maven_set_reg(md->client, 0x86, g->reg86); + maven_set_reg(md->client, 0x87, g->reg87); + maven_set_reg(md->client, 0x88, g->reg88); + maven_set_reg(md->client, 0x89, g->reg89); + maven_set_reg(md->client, 0x8a, g->reg8a); + maven_set_reg(md->client, 0x8b, g->reg8b); } break; case MATROXFB_CID_TESTOUT: { unsigned char val - = maven_get_reg(&md->client,0x8d); + = maven_get_reg (md->client,0x8d); if (p->value) val |= 0x10; else val &= ~0x10; - maven_set_reg(&md->client, 0x8d, val); + maven_set_reg (md->client, 0x8d, val); } break; case MATROXFB_CID_DEFLICKER: { - maven_set_reg(&md->client, 0x93, maven_compute_deflicker(md)); + maven_set_reg(md->client, 0x93, maven_compute_deflicker(md)); } break; } @@ -1185,6 +1185,7 @@ static int maven_init_client(struct i2c_client* clnt) { MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo); md->primary_head = MINFO; + md->client = clnt; down_write(&ACCESS_FBINFO(altout.lock)); ACCESS_FBINFO(outputs[1]).output = &maven_altout; ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; @@ -1242,17 +1243,19 @@ static int maven_detect_client(struct i2c_adapter* adapter, int address, int kin I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_PROTOCOL_MANGLING)) goto ERROR0; - if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { + if (!(new_client = (struct i2c_client*)kmalloc(sizeof(*new_client) + sizeof(*data), + GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } - new_client = &data->client; + memset(new_client, 0, sizeof(*new_client) + sizeof(*data)); + data = (struct maven_data*)(new_client + 1); i2c_set_clientdata(new_client, data); new_client->addr = address; new_client->adapter = adapter; new_client->driver = &maven_driver; new_client->flags = 0; - strlcpy(new_client->name, "maven", I2C_NAME_SIZE); + strcpy(new_client->name, "maven client"); if ((err = i2c_attach_client(new_client))) goto ERROR3; err = maven_init_client(new_client); @@ -1276,10 +1279,12 @@ static int maven_attach_adapter(struct i2c_adapter* adapter) { static int maven_detach_client(struct i2c_client* client) { int err; - if ((err = i2c_detach_client(client))) + if ((err = i2c_detach_client(client))) { + printk(KERN_ERR "maven: Cannot deregister client\n"); return err; + } maven_shutdown_client(client); - kfree(i2c_get_clientdata(client)); + kfree(client); return 0; } @@ -1292,13 +1297,20 @@ static struct i2c_driver maven_driver={ .detach_client = maven_detach_client, }; -static int __init matroxfb_maven_init(void) -{ - return i2c_add_driver(&maven_driver); +/* ************************** */ + +static int matroxfb_maven_init(void) { + int err; + + err = i2c_add_driver(&maven_driver); + if (err) { + printk(KERN_ERR "maven: Maven driver failed to register (%d).\n", err); + return err; + } + return 0; } -static void __exit matroxfb_maven_exit(void) -{ +static void matroxfb_maven_exit(void) { i2c_del_driver(&maven_driver); } diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index 263d801ef..455a46ce8 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c @@ -84,6 +84,7 @@ * */ +/* make checkconfig does not check includes for this... */ #include #include "matroxfb_misc.h" diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c index f85421bf7..743e7ad26 100644 --- a/drivers/video/maxinefb.c +++ b/drivers/video/maxinefb.c @@ -55,7 +55,7 @@ static struct fb_var_screeninfo maxinefb_defined = { }; static struct fb_fix_screeninfo maxinefb_fix = { - .id = "Maxine", + .id = "Maxine onboard graphics 1024x768x8", .smem_len = (1024*768), .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, @@ -107,6 +107,8 @@ static int maxinefb_setcolreg(unsigned regno, unsigned red, unsigned green, static struct fb_ops maxinefb_ops = { .owner = THIS_MODULE, + .fb_get_fix = gen_get_fix, + .fb_get_var = gen_get_var, .fb_setcolreg = maxinefb_setcolreg, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 26a1c618a..244a21adc 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c @@ -500,7 +500,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, /* Set up defaults */ if (!db) { db = modedb; - dbsize = ARRAY_SIZE(modedb); + dbsize = sizeof(modedb)/sizeof(*modedb); } if (!default_mode) default_mode = &modedb[DEFAULT_MODEDB_INDEX]; diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 24b12f71d..b961d5601 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -165,20 +165,20 @@ static int neoFindMode(int xres, int yres, int depth) switch (depth) { case 8: - size = ARRAY_SIZE(bios8); + size = sizeof(bios8) / sizeof(biosMode); mode = bios8; break; case 16: - size = ARRAY_SIZE(bios16); + size = sizeof(bios16) / sizeof(biosMode); mode = bios16; break; case 24: - size = ARRAY_SIZE(bios24); + size = sizeof(bios24) / sizeof(biosMode); mode = bios24; break; #ifdef NO_32BIT_SUPPORT_YET case 32: - size = ARRAY_SIZE(bios32); + size = sizeof(bios32) / sizeof(biosMode); mode = bios32; break; #endif diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index 99c3a8e6a..ea426115c 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c @@ -145,12 +145,18 @@ static void nvGetClocks(struct nvidia_par *par, unsigned int *MClk, if (par->Architecture >= NV_ARCH_40) { pll = NV_RD32(par->PMC, 0x4020); - P = (pll >> 16) & 0x03; + P = (pll >> 16) & 0x07; pll = NV_RD32(par->PMC, 0x4024); M = pll & 0xFF; N = (pll >> 8) & 0xFF; - MB = (pll >> 16) & 0xFF; - NB = (pll >> 24) & 0xFF; + if (((par->Chipset & 0xfff0) == 0x0290) || + ((par->Chipset & 0xfff0) == 0x0390)) { + MB = 1; + NB = 1; + } else { + MB = (pll >> 16) & 0xFF; + NB = (pll >> 24) & 0xFF; + } *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P; pll = NV_RD32(par->PMC, 0x4000); @@ -886,7 +892,10 @@ void NVCalcStateExt(struct nvidia_par *par, case NV_ARCH_20: case NV_ARCH_30: default: - if (((par->Chipset & 0xffff) == 0x01A0) || + if ((par->Chipset & 0xfff0) == 0x0240) { + state->arbitration0 = 256; + state->arbitration1 = 0x0480; + } else if (((par->Chipset & 0xffff) == 0x01A0) || ((par->Chipset & 0xffff) == 0x01f0)) { nForceUpdateArbitrationSettings(VClk, pixelDepth * 8, @@ -1235,6 +1244,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) break; case 0x0160: case 0x01D0: + case 0x0240: NV_WR32(par->PMC, 0x1700, NV_RD32(par->PFB, 0x020C)); NV_WR32(par->PMC, 0x1704, 0); @@ -1359,7 +1369,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) if(((par->Chipset & 0xfff0) != 0x0160) && ((par->Chipset & 0xfff0) - != 0x0220)) + != 0x0220) && + ((par->Chipset & 0xfff0) + != 0x240)) NV_WR32(par->PGRAPH, 0x6900 + i*4, NV_RD32(par->PFB, diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index 1edb1c432..bd9eca05e 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c @@ -218,7 +218,8 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) } } - *out_edid = edid; + if (out_edid) + *out_edid = edid; return (edid) ? 0 : 1; } diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index a18a9aebf..eab3e282a 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c @@ -262,7 +262,7 @@ static void nv10GetConfig(struct nvidia_par *par) #endif dev = pci_find_slot(0, 1); - if ((par->Chipset && 0xffff) == 0x01a0) { + if ((par->Chipset & 0xffff) == 0x01a0) { int amt = 0; pci_read_config_dword(dev, 0x7c, &amt); @@ -359,6 +359,7 @@ int NVCommonSetup(struct fb_info *info) case 0x0186: case 0x0187: case 0x018D: + case 0x0228: case 0x0286: case 0x028C: case 0x0316: @@ -382,6 +383,10 @@ int NVCommonSetup(struct fb_info *info) case 0x034C: case 0x0160: case 0x0166: + case 0x0169: + case 0x016B: + case 0x016C: + case 0x016D: case 0x00C8: case 0x00CC: case 0x0144: @@ -639,12 +644,23 @@ int NVCommonSetup(struct fb_info *info) par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; - printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight); + printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight); } if (monA) info->monspecs = *monA; + if (!par->FlatPanel || !par->twoHeads) + par->FPDither = 0; + + par->LVDS = 0; + if (par->FlatPanel && par->twoHeads) { + NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); + if (par->PRAMDAC0[0x08b4] & 1) + par->LVDS = 1; + printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); + } + kfree(edidA); kfree(edidB); done: diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h index acdc26693..0cc431e5c 100644 --- a/drivers/video/nvidia/nv_type.h +++ b/drivers/video/nvidia/nv_type.h @@ -129,7 +129,7 @@ struct nvidia_par { int fpHeight; int PanelTweak; int paneltweak; - int pm_state; + int LVDS; u32 crtcSync_read; u32 fpSyncs; u32 dmaPut; diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 093ab9977..d6e996cdf 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -21,7 +21,6 @@ #include #include #include -#include #ifdef CONFIG_MTRR #include #endif @@ -30,9 +29,11 @@ #include #endif #ifdef CONFIG_PMAC_BACKLIGHT -#include #include #endif +#ifdef CONFIG_BOOTX_TEXT +#include +#endif #include "nv_local.h" #include "nv_type.h" @@ -619,30 +620,6 @@ static int nvidia_panel_tweak(struct nvidia_par *par, return tweak; } -static void nvidia_vga_protect(struct nvidia_par *par, int on) -{ - unsigned char tmp; - - if (on) { - /* - * Turn off screen and disable sequencer. - */ - tmp = NVReadSeq(par, 0x01); - - NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */ - NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */ - } else { - /* - * Reenable sequencer, then turn on screen. - */ - - tmp = NVReadSeq(par, 0x01); - - NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */ - NVWriteSeq(par, 0x00, 0x03); /* End Reset */ - } -} - static void nvidia_save_vga(struct nvidia_par *par, struct _riva_hw_state *state) { @@ -671,9 +648,9 @@ static void nvidia_save_vga(struct nvidia_par *par, #undef DUMP_REG -static void nvidia_write_regs(struct nvidia_par *par, - struct _riva_hw_state *state) +static void nvidia_write_regs(struct nvidia_par *par) { + struct _riva_hw_state *state = &par->ModeReg; int i; NVTRACE_ENTER(); @@ -722,6 +699,32 @@ static void nvidia_write_regs(struct nvidia_par *par, NVTRACE_LEAVE(); } +static void nvidia_vga_protect(struct nvidia_par *par, int on) +{ + unsigned char tmp; + + if (on) { + /* + * Turn off screen and disable sequencer. + */ + tmp = NVReadSeq(par, 0x01); + + NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */ + NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */ + } else { + /* + * Reenable sequencer, then turn on screen. + */ + + tmp = NVReadSeq(par, 0x01); + + NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */ + NVWriteSeq(par, 0x00, 0x03); /* End Reset */ + } +} + + + static int nvidia_calc_regs(struct fb_info *info) { struct nvidia_par *par = info->par; @@ -1070,8 +1073,7 @@ static int nvidiafb_set_par(struct fb_info *info) nvidia_vga_protect(par, 1); - nvidia_write_regs(par, &par->ModeReg); - NVSetStartAddress(par, 0); + nvidia_write_regs(par); #if defined (__BIG_ENDIAN) /* turn on LFB swapping */ @@ -1108,6 +1110,13 @@ static int nvidiafb_set_par(struct fb_info *info) nvidia_vga_protect(par, 0); +#ifdef CONFIG_BOOTX_TEXT + /* Update debug text engine */ + btext_update_display(info->fix.smem_start, + info->var.xres, info->var.yres, + info->var.bits_per_pixel, info->fix.line_length); +#endif + NVTRACE_LEAVE(); return 0; } @@ -1356,7 +1365,7 @@ static int nvidiafb_blank(int blank, struct fb_info *info) NVWriteCrtc(par, 0x1a, vesa); #ifdef CONFIG_PMAC_BACKLIGHT - if (par->FlatPanel && machine_is(powermac)) { + if (par->FlatPanel && _machine == _MACH_Pmac) { set_backlight_enable(!blank); } #endif @@ -1380,57 +1389,6 @@ static struct fb_ops nvidia_fb_ops = { .fb_sync = nvidiafb_sync, }; -#ifdef CONFIG_PM -static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t state) -{ - struct fb_info *info = pci_get_drvdata(dev); - struct nvidia_par *par = info->par; - - acquire_console_sem(); - par->pm_state = state.event; - - if (state.event == PM_EVENT_FREEZE) { - dev->dev.power.power_state = state; - } else { - fb_set_suspend(info, 1); - nvidiafb_blank(FB_BLANK_POWERDOWN, info); - nvidia_write_regs(par, &par->SavedReg); - pci_save_state(dev); - pci_disable_device(dev); - pci_set_power_state(dev, pci_choose_state(dev, state)); - } - - release_console_sem(); - return 0; -} - -static int nvidiafb_resume(struct pci_dev *dev) -{ - struct fb_info *info = pci_get_drvdata(dev); - struct nvidia_par *par = info->par; - - acquire_console_sem(); - pci_set_power_state(dev, PCI_D0); - - if (par->pm_state != PM_EVENT_FREEZE) { - pci_restore_state(dev); - pci_enable_device(dev); - pci_set_master(dev); - } - - par->pm_state = PM_EVENT_ON; - nvidiafb_set_par(info); - fb_set_suspend (info, 0); - nvidiafb_blank(FB_BLANK_UNBLANK, info); - - release_console_sem(); - return 0; -} -#else -#define nvidiafb_suspend NULL -#define nvidiafb_resume NULL -#endif - static int __devinit nvidia_set_fbinfo(struct fb_info *info) { struct fb_monspecs *specs = &info->monspecs; @@ -1576,19 +1534,20 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info) case 0x0340: /* GeForceFX 5700 */ arch = NV_ARCH_30; break; - case 0x0040: - case 0x00C0: - case 0x0120: + case 0x0040: /* GeForce 6800 */ + case 0x00C0: /* GeForce 6800 */ + case 0x0120: /* GeForce 6800 */ case 0x0130: - case 0x0140: - case 0x0160: - case 0x01D0: - case 0x0090: - case 0x0210: - case 0x0220: + case 0x0140: /* GeForce 6600 */ + case 0x0160: /* GeForce 6200 */ + case 0x01D0: /* GeForce 7200, 7300, 7400 */ + case 0x0090: /* GeForce 7800 */ + case 0x0210: /* GeForce 6800 */ + case 0x0220: /* GeForce 6200 */ case 0x0230: - case 0x0290: - case 0x0390: + case 0x0240: /* GeForce 6100 */ + case 0x0290: /* GeForce 7900 */ + case 0x0390: /* GeForce 7600 */ arch = NV_ARCH_40; break; case 0x0020: /* TNT, TNT2 */ @@ -1742,7 +1701,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, info->fix.id, par->FbMapSize / (1024 * 1024), info->fix.smem_start); #ifdef CONFIG_PMAC_BACKLIGHT - if (par->FlatPanel && machine_is(powermac)) + if (par->FlatPanel && _machine == _MACH_Pmac) register_backlight_controller(&nvidia_backlight_controller, par, "mnca"); #endif @@ -1774,6 +1733,8 @@ static void __exit nvidiafb_remove(struct pci_dev *pd) struct nvidia_par *par = info->par; NVTRACE_ENTER(); + if (!info) + return; unregister_framebuffer(info); #ifdef CONFIG_MTRR @@ -1850,10 +1811,8 @@ static int __devinit nvidiafb_setup(char *options) static struct pci_driver nvidiafb_driver = { .name = "nvidiafb", .id_table = nvidiafb_pci_tbl, - .probe = nvidiafb_probe, - .suspend = nvidiafb_suspend, - .resume = nvidiafb_resume, - .remove = __exit_p(nvidiafb_remove), + .probe = nvidiafb_probe, + .remove = __exit_p(nvidiafb_remove), }; /* ------------------------------------------------------------------------- * diff --git a/drivers/video/offb.c b/drivers/video/offb.c index a57455ee0..ad1434e3f 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -321,9 +321,8 @@ static void __init offb_init_nodriver(struct device_node *dp) int *pp, i; unsigned int len; int width = 640, height = 480, depth = 8, pitch; - unsigned flags, rsize, *up, addr_prop = 0; - unsigned long max_size = 0; - u64 rstart, address = OF_BAD_ADDR; + unsigned int flags, rsize, *up; + u64 address = OF_BAD_ADDR; u32 *addrp; u64 asize; @@ -344,57 +343,69 @@ static void __init offb_init_nodriver(struct device_node *dp) } else pitch = width; - rsize = (unsigned long)pitch * (unsigned long)height * - (unsigned long)(depth / 8); - - /* Ok, now we try to figure out the address of the framebuffer. - * - * Unfortunately, Open Firmware doesn't provide a standard way to do - * so. All we can do is a dodgy heuristic that happens to work in - * practice. On most machines, the "address" property contains what - * we need, though not on Matrox cards found in IBM machines. What I've - * found that appears to give good results is to go through the PCI - * ranges and pick one that is both big enough and if possible encloses - * the "address" property. If none match, we pick the biggest - */ - up = (unsigned int *) get_property(dp, "address", &len); - if (up && len == sizeof(unsigned int)) - addr_prop = *up; - - for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) - != NULL; i++) { - int match_addrp = 0; - - if (!(flags & IORESOURCE_MEM)) - continue; - if (asize < rsize) - continue; - rstart = of_translate_address(dp, addrp); - if (rstart == OF_BAD_ADDR) - continue; - if (addr_prop && (rstart <= addr_prop) && - ((rstart + rsize) > addr_prop)) - match_addrp = 1; - if (match_addrp) { - address = addr_prop; - break; + rsize = (unsigned long)pitch * (unsigned long)height * + (unsigned long)(depth / 8); + + /* Try to match device to a PCI device in order to get a properly + * translated address rather then trying to decode the open firmware + * stuff in various incorrect ways + */ +#ifdef CONFIG_PCI + /* First try to locate the PCI device if any */ + { + struct pci_dev *pdev = NULL; + + for_each_pci_dev(pdev) { + if (dp == pci_device_to_OF_node(pdev)) + break; + } + if (pdev) { + for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) { + if ((pci_resource_flags(pdev, i) & + IORESOURCE_MEM) && + (pci_resource_len(pdev, i) >= rsize)) + address = pci_resource_start(pdev, i); + } + pci_dev_put(pdev); + } + } +#endif /* CONFIG_PCI */ + + /* This one is dodgy, we may drop it ... */ + if (address == OF_BAD_ADDR && + (up = (unsigned *) get_property(dp, "address", &len)) != NULL && + len == sizeof(unsigned int)) + address = (u64) * up; + + if (address == OF_BAD_ADDR) { + for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) + != NULL; i++) { + if (!(flags & IORESOURCE_MEM)) + continue; + if (asize >= pitch * height * depth / 8) + break; + } + if (addrp == NULL) { + printk(KERN_ERR + "no framebuffer address found for %s\n", + dp->full_name); + return; } - if (rsize > max_size) { - max_size = rsize; - address = OF_BAD_ADDR; + address = of_translate_address(dp, addrp); + if (address == OF_BAD_ADDR) { + printk(KERN_ERR + "can't translate framebuffer address for %s\n", + dp->full_name); + return; } - if (address == OF_BAD_ADDR) - address = rstart; - } - if (address == OF_BAD_ADDR && addr_prop) - address = (u_long)addr_prop; - if (address != OF_BAD_ADDR) { + /* kludge for valkyrie */ if (strcmp(dp->name, "valkyrie") == 0) address += 0x1000; - offb_init_fb(dp->name, dp->full_name, width, height, depth, - pitch, address, dp); } + offb_init_fb(dp->name, dp->full_name, width, height, depth, + pitch, address, dp); + } static void __init offb_init_fb(const char *name, const char *full_name, diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 4e963930b..5fe197943 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c @@ -73,8 +73,8 @@ static char *mode __devinitdata = NULL; * these flags allow the user to specify that requests for +ve sync * should be silently turned in -ve sync. */ -static int lowhsync; -static int lowvsync; +static int lowhsync __devinitdata = 0; +static int lowvsync __devinitdata = 0; /* * The hardware state of the graphics card that isn't part of the diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index 52c18a35f..0e78ddc81 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c @@ -3532,26 +3532,26 @@ int __init pm3fb_init(void) MODULE_AUTHOR("Romain Dolbeau"); MODULE_DESCRIPTION("Permedia3 framebuffer device driver"); static char *mode[PM3_MAX_BOARD]; -module_param_array(mode, charp, NULL, 0); +MODULE_PARM(mode,PM3_MAX_BOARD_MODULE_ARRAY_STRING); MODULE_PARM_DESC(mode,"video mode"); -module_param_array(disable, short, NULL, 0); +MODULE_PARM(disable,PM3_MAX_BOARD_MODULE_ARRAY_SHORT); MODULE_PARM_DESC(disable,"disable board"); static short off[PM3_MAX_BOARD]; -module_param_array(off, short, NULL, 0); +MODULE_PARM(off,PM3_MAX_BOARD_MODULE_ARRAY_SHORT); MODULE_PARM_DESC(off,"disable board"); static char *pciid[PM3_MAX_BOARD]; -module_param_array(pciid, charp, NULL, 0); +MODULE_PARM(pciid,PM3_MAX_BOARD_MODULE_ARRAY_STRING); MODULE_PARM_DESC(pciid,"board PCI Id"); -module_param_array(noaccel, short, NULL, 0); +MODULE_PARM(noaccel,PM3_MAX_BOARD_MODULE_ARRAY_SHORT); MODULE_PARM_DESC(noaccel,"disable accel"); static char *font[PM3_MAX_BOARD]; -module_param_array(font, charp, NULL, 0); +MODULE_PARM(font,PM3_MAX_BOARD_MODULE_ARRAY_STRING); MODULE_PARM_DESC(font,"choose font"); -module_param(depth, short, NULL, 0); +MODULE_PARM(depth,PM3_MAX_BOARD_MODULE_ARRAY_SHORT); MODULE_PARM_DESC(depth,"boot-time depth"); -module_param(printtimings, short, NULL, 0); +MODULE_PARM(printtimings, "h"); MODULE_PARM_DESC(printtimings, "print the memory timings of the card(s)"); -module_param(forcesize, short, NULL, 0); +MODULE_PARM(forcesize, PM3_MAX_BOARD_MODULE_ARRAY_SHORT); MODULE_PARM_DESC(forcesize, "force specified memory size"); /* MODULE_SUPPORTED_DEVICE("Permedia3 PCI boards") diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 73e2d7d16..eeeac924b 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c @@ -228,7 +228,7 @@ static void __init pmagbbfb_osc_setup(struct fb_info *info) freq1 = (par->osc0 * count1 + count0 / 2) / count0; par->osc1 = freq1; - for (i = 0; i < ARRAY_SIZE(pmagbbfb_freqs); i++) + for (i = 0; i < sizeof(pmagbbfb_freqs) / sizeof(*pmagbbfb_freqs); i++) if (freq1 >= pmagbbfb_freqs[i] - (pmagbbfb_freqs[i] + 128) / 256 && freq1 <= pmagbbfb_freqs[i] + diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 809fc5eef..53ad61f10 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -232,9 +232,9 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) if (var->yres < MIN_YRES) var->yres = MIN_YRES; if (var->xres > fbi->max_xres) - return -EINVAL; + var->xres = fbi->max_xres; if (var->yres > fbi->max_yres) - return -EINVAL; + var->yres = fbi->max_yres; var->xres_virtual = max(var->xres_virtual, var->xres); var->yres_virtual = @@ -781,7 +781,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */ - schedule_timeout(200 * HZ / 1000); + schedule_timeout(20 * HZ / 1000); remove_wait_queue(&fbi->ctrlr_wait, &wait); /* disable LCD controller clock */ @@ -1274,7 +1274,7 @@ int __init pxafb_probe(struct platform_device *dev) struct pxafb_mach_info *inf; int ret; - dev_dbg(&dev->dev, "pxafb_probe\n"); + dev_dbg(dev, "pxafb_probe\n"); inf = dev->dev.platform_data; ret = -ENOMEM; diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c new file mode 100644 index 000000000..db9fb9074 --- /dev/null +++ b/drivers/video/radeonfb.c @@ -0,0 +1,3167 @@ +/* + * drivers/video/radeonfb.c + * framebuffer driver for ATI Radeon chipset video boards + * + * Copyright 2000 Ani Joshi + * + * + * ChangeLog: + * 2000-08-03 initial version 0.0.1 + * 2000-09-10 more bug fixes, public release 0.0.5 + * 2001-02-19 mode bug fixes, 0.0.7 + * 2001-07-05 fixed scrolling issues, engine initialization, + * and minor mode tweaking, 0.0.9 + * 2001-09-07 Radeon VE support, Nick Kurshev + * blanking, pan_display, and cmap fixes, 0.1.0 + * 2001-10-10 Radeon 7500 and 8500 support, and experimental + * flat panel support, 0.1.1 + * 2001-11-17 Radeon M6 (ppc) support, Daniel Berlin, 0.1.2 + * 2001-11-18 DFP fixes, Kevin Hendricks, 0.1.3 + * 2001-11-29 more cmap, backlight fixes, Benjamin Herrenschmidt + * 2002-01-18 DFP panel detection via BIOS, Michael Clark, 0.1.4 + * 2002-06-02 console switching, mode set fixes, accel fixes + * 2002-06-03 MTRR support, Peter Horton, 0.1.5 + * 2002-09-21 rv250, r300, m9 initial support, + * added mirror option, 0.1.6 + * + * Special thanks to ATI DevRel team for their hardware donations. + * + */ + + +#define RADEON_VERSION "0.1.6" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#if defined(__powerpc__) +#include +#include +#include "macmodes.h" + +#ifdef CONFIG_NVRAM +#include +#endif + +#ifdef CONFIG_PMAC_BACKLIGHT +#include +#endif + +#ifdef CONFIG_BOOTX_TEXT +#include +#endif + +#ifdef CONFIG_ADB_PMU +#include +#include +#endif + +#endif /* __powerpc__ */ + +#ifdef CONFIG_MTRR +#include +#endif + +#include
Powered by Linux/TUX 3.0
\n" - -static void http_dirlist_tail (tux_req_t *req, int cachemiss) -{ - __send_async_message(req, DIRLIST_TAIL, 200, sizeof(DIRLIST_TAIL)-1, 1); -} - -static void http_dirlist (tux_req_t *req, int cachemiss) -{ - int head = (req->method == METHOD_HEAD); - - req->lookup_dir = 3; - clear_keepalive(req); - if (!head) { - add_tux_atom(req, http_dirlist_tail); - add_tux_atom(req, list_directory); - add_tux_atom(req, http_dirlist_head); - } - http_pre_header(req, head); - add_req_to_workqueue(req); -} - -static char *host_path_hash(tux_req_t *req, char *tmp) -{ - if (req->host_len < 2) - return NULL; - - switch (mass_hosting_hash) { - default: - case 0: - return req->host; - case 1: - - // www.ABCDEFG.com => A/ABCDEFG.com - - tmp[0] = req->host[0]; - tmp[1] = '/'; - memcpy(tmp + 2, req->host, req->host_len); - tmp[req->host_len + 2] = 0; - - return tmp; - case 2: - // www.ABCDEFG.com => A/AB/ABCDEFG.com - - tmp[0] = req->host[0]; - tmp[1] = '/'; - tmp[2] = req->host[0]; - tmp[3] = req->host[1]; - tmp[4] = '/'; - memcpy(tmp + 5, req->host, req->host_len); - tmp[req->host_len + 5] = 0; - - return tmp; - case 3: - // www.ABCDEFG.com => A/AB/ABC/ABCDEFG.com - - tmp[0] = req->host[0]; - tmp[1] = '/'; - tmp[2] = req->host[0]; - tmp[3] = req->host[1]; - tmp[4] = '/'; - tmp[5] = req->host[0]; - tmp[6] = req->host[1]; - tmp[7] = req->host[2]; - tmp[8] = '/'; - memcpy(tmp + 9, req->host, req->host_len); - tmp[req->host_len + 9] = 0; - - return tmp; - } -} - -static struct dentry * vhost_lookup (tux_req_t *req, struct nameidata* base, struct vfsmount **mnt) -{ - struct dentry *dentry = NULL; - // 255.255.255.255 - char ip [3+1+3+1+3+1+3 + 2]; - - if (req->virtual >= TUX_VHOST_IP) { - sprintf(ip, "%d.%d.%d.%d", - NIPQUAD(inet_sk(req->sock->sk)->rcv_saddr)); - dentry = __tux_lookup (req, ip, base, mnt); - if (!dentry || IS_ERR(dentry)) { - if (PTR_ERR(dentry) == -EWOULDBLOCKIO) - return dentry; - base->dentry = dget(req->proto->main_docroot.dentry); - base->mnt = mntget(req->proto->main_docroot.mnt); - goto lookup_default; - } - if (req->virtual == TUX_VHOST_IP) - goto done; - - // fall through in mixed mode: - } - - if (!req->host_len) { -lookup_default: - *mnt = NULL; - dentry = __tux_lookup (req, tux_default_vhost, base, mnt); - } else { - char tmp [MAX_HOST_LEN*2]; - char *host_path; - - host_path = host_path_hash(req, tmp); - Dprintk("host path hash returned: {%s}\n", host_path); - - dentry = NULL; - if (host_path) { - *mnt = NULL; - dentry = __tux_lookup (req, host_path, base, mnt); - } - if (!dentry || IS_ERR(dentry)) { - if (PTR_ERR(dentry) == -EWOULDBLOCKIO) - return dentry; - base->dentry = dget(req->proto->main_docroot.dentry); - base->mnt = mntget(req->proto->main_docroot.mnt); - if (req->virtual >= TUX_VHOST_IP) { - *mnt = NULL; - dentry = __tux_lookup (req, ip, base, mnt); - if (!dentry || IS_ERR(dentry)) { - if (PTR_ERR(dentry) == -EWOULDBLOCKIO) - return dentry; - base->dentry = dget(req->proto->main_docroot.dentry); - base->mnt = mntget(req->proto->main_docroot.mnt); - } - } - goto lookup_default; - } - } -done: - return dentry; -} - -static void http_lookup_vhost (tux_req_t *req, int cachemiss) -{ - struct dentry *dentry; - struct nameidata base = { }; - struct vfsmount *mnt = NULL; - unsigned int flag = cachemiss ? 0 : LOOKUP_ATOMIC; - - Dprintk("http_lookup_vhost(%p, %d, virtual: %d, host: %s (%d).)\n", req, flag, req->virtual, req->host, req->host_len); - - base.flags = LOOKUP_FOLLOW|flag; - base.last_type = LAST_ROOT; - base.dentry = dget(req->proto->main_docroot.dentry); - base.mnt = mntget(req->proto->main_docroot.mnt); - - dentry = vhost_lookup(req, &base, &mnt); - - Dprintk("looked up dentry %p.\n", dentry); - - if (dentry && !IS_ERR(dentry) && !dentry->d_inode) - TUX_BUG(); - - if (!dentry || IS_ERR(dentry)) { - if (PTR_ERR(dentry) == -EWOULDBLOCKIO) { - add_tux_atom(req, http_lookup_vhost); - queue_cachemiss(req); - return; - } - goto abort; - } - - req->docroot_dentry = dentry; - req->docroot_mnt = mnt; - - add_tux_atom(req, http_process_message); - add_req_to_workqueue(req); - return; -abort: - if (dentry) { - if (!IS_ERR(dentry)) - dput(dentry); - dentry = NULL; - } - if (mnt) { - if (!IS_ERR(mnt)) - mntput(mnt); - mnt = NULL; - } - req_err(req); - add_req_to_workqueue(req); -} - -static void http_process_message (tux_req_t *req, int cachemiss) -{ - tux_attribute_t *attr; - int missed; - unsigned int lookup_flag = cachemiss ? 0 : LOOKUP_ATOMIC; - - Dprintk("handling req %p, cachemiss: %d.\n", req, cachemiss); - - /* - * URL redirection support - redirect all valid requests - * to the first userspace module. - */ - if (tux_all_userspace) { - tcapi_template_t *tcapi = get_first_usermodule(); - if (tcapi) { - req->usermode = 1; - req->usermodule_idx = tcapi->userspace_id; - goto usermode; - } - } - missed = lookup_url(req, lookup_flag); - if (missed == 2) { - if (req->query_str) { - req->error = TUX_ERROR_REDIRECT; - goto error; - } - send_ret_redirect(req, cachemiss); - return; - } - if (req->error) - goto error; - if (missed) { -cachemiss: - if (cachemiss) - TUX_BUG(); - Dprintk("uncached request.\n"); - INC_STAT(static_lookup_cachemisses); - if (req->dentry) - TUX_BUG(); - add_tux_atom(req, http_process_message); - queue_cachemiss(req); - return; - } - /* - * HTML directory indexing. - */ - if (S_ISDIR(req->dentry->d_inode->i_mode)) - return http_dirlist(req, cachemiss); - if (!S_ISREG(req->dentry->d_inode->i_mode)) - TUX_BUG(); - - - attr = req->dentry->d_extra_attributes; - if (!attr) { - attr = lookup_tux_attribute(req); - if (!attr) - TUX_BUG(); - req->dentry->d_extra_attributes = attr; - } - if (attr->mime) - Dprintk("using MIME type %s:%s, %d.\n", attr->mime->type, attr->mime->ext, attr->mime->special); - if (attr->tcapi) { - req->usermode = 1; - req->usermodule_idx = attr->tcapi->userspace_id; - if (req->module_dentry) - TUX_BUG(); - req->module_dentry = dget(req->dentry); - release_req_dentry(req); - goto usermode; - } - - switch (attr->mime->special) { - case MIME_TYPE_MODULE: - req->usermode = 1; - goto usermode; - - case MIME_TYPE_REDIRECT: - req->error = TUX_ERROR_REDIRECT; - goto error; - - case MIME_TYPE_CGI: -#ifdef CONFIG_TUX_EXTCGI - Dprintk("CGI request %p.\n", req); - query_extcgi(req); - return; -#endif - - default: - if (req->query_str) { - req->error = TUX_ERROR_REDIRECT; - goto error; - } - } - req->attr = attr; - switch (req->method) { - case METHOD_GET: - case METHOD_HEAD: - break; - default: - req->error = TUX_ERROR_REDIRECT; - goto error; - } - if (req->usermode) - TUX_BUG(); - - req->output_len = req->total_file_len; - /* - * Do range calculations. - */ - if (req->offset_end || req->offset_start) - handle_range(req); - - if (req->may_send_gzip && !req->offset_start && !req->offset_end) { - if (handle_gzip_req(req, lookup_flag)) - goto cachemiss; - if ((tux_compression >= 2) && !req->content_gzipped) - req->content_gzipped = 2; - } - if (req->parsed_len) - trunc_headers(req); - - if (req->error) - goto error; - - add_tux_atom(req, http_send_body); - add_tux_atom(req, http_post_header); - - http_pre_header(req, req->method == METHOD_HEAD); - - add_req_to_workqueue(req); - return; - -error: - if (req->error) - zap_request(req, cachemiss); - return; - -usermode: - add_req_to_workqueue(req); -} - -static void http_post_header (tux_req_t *req, int cachemiss) -{ -#ifdef CONFIG_TUX_DEBUG - req->bytes_expected = req->output_len; -#endif - req->bytes_sent = 0; // data comes now. - - add_req_to_workqueue(req); -} - -static void http_send_body (tux_req_t *req, int cachemiss) -{ - int ret; - - Dprintk("SEND req %p <%p> (sock %p, sk %p) (keepalive: %d, status: %d)\n", req, __builtin_return_address(0), req->sock, req->sock->sk, req->keep_alive, req->status); - - SET_TIMESTAMP(req->output_timestamp); - - if (req->error) { -#ifdef CONFIG_TUX_DEBUG - req->bytes_expected = 0; -#endif - req->in_file->f_pos = 0; - /* - * We are in the middle of a file transfer, - * zap it immediately: - */ - TDprintk("req->error = TUX_ERROR_CONN_CLOSE.\n"); - req->error = TUX_ERROR_CONN_CLOSE; - zap_request(req, cachemiss); - return; - } - -repeat: - ret = 0; - if (!req->status) - req->status = 200; - if (req->method != METHOD_HEAD) { - ret = generic_send_file(req, req->sock, cachemiss); - Dprintk("body send-file returned: %d.\n", ret); - } else { -#ifdef CONFIG_TUX_DEBUG - req->bytes_expected = 0; -#endif - } - - switch (ret) { - case -5: - add_tux_atom(req, http_send_body); - output_timeout(req); - break; - case -4: - add_tux_atom(req, http_send_body); - if (add_output_space_event(req, req->sock)) { - del_tux_atom(req); - goto repeat; - } - break; - case -3: - INC_STAT(static_sendfile_cachemisses); - add_tux_atom(req, http_send_body); - queue_cachemiss(req); - break; - case -1: - break; - default: - req->in_file->f_pos = 0; - add_req_to_workqueue(req); - break; - } -} - -#define DEFAULT_DATE "Wed, 01 Jan 1970 00:00:01 GMT" - -char tux_date [DATE_LEN] = DEFAULT_DATE; - -/* - * HTTP header - */ - -#define HEADER_PART1A \ - "HTTP/1.1 200 OK\r\n" \ - "Content-Type: " - -#define HEADER_PART1B \ - "HTTP/1.1 200 OK" - -#define HEADER_PART1AP \ - "HTTP/1.1 206 Partial Content\r\n" \ - "Content-Type: " - -#define HEADER_PART1BP \ - "HTTP/1.1 206 Partial Content" - -#define HEADER_PART1C \ - "HTTP/1.1 404 Page Not Found\r\n" \ - "Content-Type: " - -#define HEADER_PART1D \ - "HTTP/1.1 200 OK\r\n" \ - "Content-Type: text/html\r\n" \ - "Connection: close\r\n" - -#define HEADER_PART2_keepalive "\r\nConnection: Keep-Alive\r\nDate: " - -#define HEADER_PART2_close "\r\nConnection: close\r\nDate: " - -#define HEADER_PART2_none "\r\nDate: " - -// date "%s" - -#define HEADER_PART3A "\r\nContent-Encoding: gzip" -#define HEADER_PART3BX "\r\nContent-Length: " - -/* - * Please acknowledge our hard work by not changing this define, or - * at least please acknowledge us by leaving "TUX/2.0 (Linux)" in - * the ID string. Thanks! :-) - */ -#define HEADER_PART3BY "\r\nServer: TUX/2.0 (Linux)\r\nContent-Length: " -#define HEADER_PART3C "\r\nETag: \"" -#define HEADER_PART3ACC "\r\nAccept-Ranges: bytes" -#define HEADER_PART3L "\r\nLast-Modified: " -#define HEADER_PART3P "\r\nContent-Range: bytes " -#define HEADER_PART3CA "\r\nCache-Control: max-age=" -#define HEADER_PART4 "\r\n\r\n" - -#define MAX_OUT_HEADER_LEN (sizeof(HEADER_PART1AP) + MAX_MIMETYPE_LEN + \ - sizeof(HEADER_PART2_keepalive) + DATE_LEN + \ - sizeof(HEADER_PART3A) + sizeof(HEADER_PART3BY) + \ - 12 + sizeof(HEADER_PART3C) + 21 + sizeof(HEADER_PART3L) + \ - sizeof(HEADER_PART3P) + 32 + \ - DATE_LEN + sizeof(HEADER_PART4) + sizeof(tux_extra_html_header) \ - + sizeof(HEADER_PART3CA) + MAX_CACHE_CONTROL_AGE_LEN) - -static void http_pre_header (tux_req_t *req, int head) -{ - int partial = req->offset_start | req->offset_end; - unsigned long flags; - char *buf, *curr; - mimetype_t *mime = NULL; - int size; - - - if (MAX_OUT_HEADER_LEN > PAGE_SIZE) - TUX_BUG(); - if ((req->attr && req->attr->tcapi) || req->usermode) - TUX_BUG(); - -#define COPY_STATIC_PART(nr,curr) \ - do { \ - memcpy(curr, HEADER_PART##nr, sizeof(HEADER_PART##nr)-1); \ - curr += sizeof(HEADER_PART##nr)-1; \ - } while (0) - - buf = curr = get_abuf(req, MAX_OUT_HEADER_LEN); - - if (req->lookup_dir) { - COPY_STATIC_PART(1D, curr); - goto dir_next; - } - mime = req->attr->mime; - if (!mime) - TUX_BUG(); - - if (req->status == 404) { - COPY_STATIC_PART(1C, curr); - memcpy(curr, mime->type, mime->type_len); - curr += mime->type_len; - } else { - if (tux_noid && (mime == &default_mimetype)) { - if (partial) - COPY_STATIC_PART(1BP, curr); - else - COPY_STATIC_PART(1B, curr); - } else { - if (partial) - COPY_STATIC_PART(1AP, curr); - else - COPY_STATIC_PART(1A, curr); - memcpy(curr, mime->type, mime->type_len); - curr += mime->type_len; - } - } - - if (tux_generate_cache_control && mime->expire_str_len) { - COPY_STATIC_PART(3CA, curr); - memcpy(curr, mime->expire_str, mime->expire_str_len); - curr += mime->expire_str_len; - } - - if (req->keep_alive /* && (req->version == HTTP_1_0) */) - COPY_STATIC_PART(2_keepalive, curr); - else if (!req->keep_alive && (req->version == HTTP_1_1)) - COPY_STATIC_PART(2_close, curr); - else - // HTTP/1.0 default means close - COPY_STATIC_PART(2_none, curr); - -dir_next: - memcpy(curr, tux_date, DATE_LEN-1); - curr += DATE_LEN-1; - - if (req->content_gzipped) - COPY_STATIC_PART(3A, curr); - - /* - * Content-Length: - */ - if (!req->lookup_dir) { - if (tux_noid) - COPY_STATIC_PART(3BX, curr); - else - COPY_STATIC_PART(3BY, curr); - - if (partial) - curr += sprintf(curr, "%Ld", req->output_len); - else { - if (req->content_gzipped) - curr += sprintf(curr, "%Ld", - req->total_file_len); - else { - memcpy(curr, &req->etag, req->lendigits); - curr += req->lendigits; - } - } - if (tux_generate_etags && (req->status != 404)) { - COPY_STATIC_PART(3C, curr); - memcpy(curr, &req->etag, req->etaglen); - curr += req->etaglen; - curr[0] = '"'; - curr++; - } - if (tux_generate_last_mod || tux_generate_etags) - COPY_STATIC_PART(3ACC, curr); - } - if (tux_generate_last_mod && (req->status != 404)) { - COPY_STATIC_PART(3L, curr); - last_mod_time(curr, req->mtime); - curr += DATE_LEN-1; - } - if (partial) { - COPY_STATIC_PART(3P, curr); - curr += sprintf(curr, "%Ld-%Ld/%Ld", req->offset_start, - req->offset_end-1, req->total_file_len); - } - COPY_STATIC_PART(4, curr); - /* - * Possibly add an extra HTML header: - */ - if (tux_extra_html_header_size && mime && !strcmp(mime->type, "text/html")) { - unsigned int len = tux_extra_html_header_size; - - memcpy(curr, tux_extra_html_header, len); - curr += len; - } - - size = curr-buf; - -#ifdef CONFIG_TUX_DEBUG - *curr = 0; - Dprintk("{%s} [%d/%d]\n", buf, size, strlen(buf)); -#endif - - flags = MSG_DONTWAIT; - if (!head) - flags |= MSG_MORE; - send_abuf(req, size, flags); -} - -void http_illegal_request (tux_req_t *req, int cachemiss) -{ - if (req->status == 304) - send_ret_notmodified(req); - else { - if (req->status == 403) - send_async_err_forbidden(req); - else - send_async_err_not_found(req); - } -} - -static int http_check_req_err (tux_req_t *req, int cachemiss) -{ - if ((req->sock->sk->sk_state <= TCP_SYN_RECV) && - !tcp_sk(req->sock->sk)->urg_data) - return 0; - Dprintk("http_check_req_err(%p,%d): 1 (state: %d, urg: %d)\n", - req, cachemiss, req->sock->sk->sk_state, - tcp_sk(req->sock->sk)->urg_data); -#ifdef CONFIG_TUX_DEBUG - req->bytes_expected = 0; -#endif - req->in_file->f_pos = 0; - req->error = TUX_ERROR_CONN_CLOSE; - zap_request(req, cachemiss); - - return 1; -} - -#define COPY_STR(str) \ - do { memcpy(tmp, str, sizeof(str)-1); \ - tmp += sizeof(str)-1; } while (0) - -static char * http_print_dir_line (tux_req_t *req, char *tmp, char *d_name, int d_len, int d_type, struct dentry *dentry, struct inode *inode) -{ - int len, spaces; - loff_t size; - - switch (d_type) { - case DT_DIR: - COPY_STR("\"[DIR]\""); - break; - case DT_REG: - if ((d_len >= 3) && - (d_name[d_len-3] == '.') && - (d_name[d_len-2] == 'g') && - (d_name[d_len-1] == 'z')) - COPY_STR("\"["); - else - if ((d_len >= 4) && - (d_name[d_len-4] == '.') && - (d_name[d_len-3] == 't') && - (d_name[d_len-2] == 'g') && - (d_name[d_len-1] == 'z')) - COPY_STR("\"["); - else - if ((d_len >= 4) && - (d_name[d_len-4] == '.') && - (d_name[d_len-3] == 't') && - (d_name[d_len-2] == 'x') && - (d_name[d_len-1] == 't')) - COPY_STR("\"["); - else - if ((d_len >= 4) && - (d_name[d_len-4] == '.') && - (d_name[d_len-3] == 'b') && - (d_name[d_len-2] == 'z') && - (d_name[d_len-1] == '2')) - COPY_STR("\"["); - else - if ((d_len >= 4) && - (d_name[d_len-4] == '.') && - (d_name[d_len-3] == 'z') && - (d_name[d_len-2] == 'i') && - (d_name[d_len-1] == 'p')) - COPY_STR("\"["); - else - COPY_STR("\"["); - break; - case DT_LNK: - COPY_STR("\"[LNK]\""); - break; - default: - if (tux_hide_unreadable) - goto out_dput; - COPY_STR("\"["); - break; - } - -#define LIST_1 " " -#define LIST_2_DIR "/\">" -#define LIST_3 " " - - COPY_STR(LIST_1); - memcpy(tmp, d_name, d_len); - tmp += d_len; - if (d_type == DT_DIR) - COPY_STR(LIST_2_DIR); - else - COPY_STR(LIST_2); - spaces = 0; - len = d_len; - - if (len > 25) - len = 25; - memcpy(tmp, d_name, len); - tmp += len; - if (len != d_len) { - *tmp++ = '.'; - *tmp++ = '.'; - } else { - if (d_type == DT_DIR) - *tmp++ = '/'; - else - spaces++; - spaces++; - } - COPY_STR(LIST_3); - while (spaces) { - *tmp++ = ' '; - spaces--; - } -#define FILL 25 - if (d_len < FILL) { - memset(tmp, ' ', FILL-d_len); - tmp += FILL-d_len; - } - - tmp += time_unix2ls(inode->i_mtime.tv_sec, tmp); - *tmp++ = ' '; - - if (d_type != DT_REG) { - COPY_STR(" - "); - goto out_size; - } - size = inode->i_size >> 10; - if (size < 1024) { - tmp += sprintf(tmp, "%8Lik ", size); - goto out_size; - } - size >>= 10; - if (size < 1024) { - tmp += sprintf(tmp, "%8LiM ", size); - goto out_size; - } - size >>= 10; - if (size < 1024) { - tmp += sprintf(tmp, "%8LiG ", size); - goto out_size; - } - size >>= 10; - if (size < 1024) { - tmp += sprintf(tmp, "%8LiT ", size); - goto out_size; - } - size >>= 10; - tmp += sprintf(tmp, "%8LiT ", size); - -out_size: - *tmp++ = '\n'; - *tmp = 0; - - return tmp; -out_dput: - return NULL; -} - -tux_proto_t tux_proto_http = { - defer_accept: 1, - can_redirect: 1, - got_request: http_got_request, - parse_message: parse_http_message, - illegal_request: http_illegal_request, - check_req_err: http_check_req_err, - print_dir_line: http_print_dir_line, - name: "http", -}; - diff --git a/net/tux/redirect.c b/net/tux/redirect.c deleted file mode 100644 index b55c322b0..000000000 --- a/net/tux/redirect.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * TUX - Integrated Application Protocols Layer and Object Cache - * - * Copyright (C) 2000, 2001, Ingo Molnar - * - * redirect.c: redirect requests to other server sockets (such as Apache). - */ - -#include -#include -#include - -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -static void nop_destructor(struct request_sock *req) -{ -} - -static struct request_sock_ops tux_req = -{ - .destructor = &nop_destructor, -}; - -static int redirect_sock (tux_req_t *req, const int port) -{ - struct socket *sock = req->sock; - struct request_sock *tcpreq; - struct sock *sk, *oldsk; - int err = -1; - - /* - * Look up (optional) listening user-space socket. - */ - local_bh_disable(); - sk = inet_lookup_listener(&tcp_hashinfo, INADDR_ANY, port, 0); - /* - * Look up localhost listeners as well. - */ - if (!sk) { - u32 daddr; - ((unsigned char *)&daddr)[0] = 127; - ((unsigned char *)&daddr)[1] = 0; - ((unsigned char *)&daddr)[2] = 0; - ((unsigned char *)&daddr)[3] = 1; - sk = inet_lookup_listener(&tcp_hashinfo, daddr, port, 0); - } - local_bh_enable(); - - /* No secondary server found */ - if (!sk) - goto out; - if (sk->sk_family != AF_INET) { - sock_put(sk); - goto out; - } - - /* - * Requeue the 'old' socket as an accept-socket of - * the listening socket. This way we can shuffle - * a socket around. Since we've read the input data - * via the non-destructive MSG_PEEK, the secondary - * server can be used transparently. - */ - oldsk = sock->sk; - lock_sock(sk); - - if (sk->sk_state != TCP_LISTEN) - goto out_unlock; - - tcpreq = reqsk_alloc(&tux_req); - if (!tcpreq) - goto out_unlock; - - unlink_tux_socket(req); - - sock->sk = NULL; - sock->state = SS_UNCONNECTED; - - write_lock_irq(&oldsk->sk_callback_lock); - oldsk->sk_socket = NULL; - oldsk->sk_sleep = NULL; - write_unlock_irq(&oldsk->sk_callback_lock); - - tcp_sk(oldsk)->nonagle = 0; - - inet_csk_reqsk_queue_add(sk, tcpreq, oldsk); - - sk->sk_data_ready(sk, 0); - - /* - * It's now completely up to the secondary - * server to handle this request. - */ - if (req->fd != -1) { - tux_close(req->fd); - req->fd = -1; - } else - sock_release(req->sock); - req->sock = NULL; - req->parsed_len = 0; - err = 0; - Dprintk("req %p redirected to secondary server!\n", req); - -out_unlock: - release_sock(sk); - sock_put(sk); -out: - if (err) - Dprintk("NO secondary server for req %p!\n", req); - return err; -} - -void redirect_request (tux_req_t *req, int cachemiss) -{ - if (tux_TDprintk && (req->status != 304)) { - TDprintk("trying to redirect req %p, req->error: %d, req->status: %d.\n", req, req->error, req->status); - print_req(req); - } - - if (cachemiss) - TUX_BUG(); - if (req->error == TUX_ERROR_CONN_CLOSE) - goto out_flush; - if (!req->sock) - TUX_BUG(); - - if (!req->status) - req->status = -1; - if (!req->proto->can_redirect || (req->status == 304) || redirect_sock(req, tux_clientport)) { - if (req->parsed_len) - trunc_headers(req); - req->proto->illegal_request(req, cachemiss); - return; - } else { - if (req->data_sock) - BUG(); - } -out_flush: - clear_keepalive(req); - if (!tux_redirect_logging) - req->status = 0; - flush_request(req, cachemiss); -} - -int init_tux_request_slabs(void) -{ - tux_req.slab = kmem_cache_create("tux-request", - sizeof(struct request_sock), 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - - return tux_req.slab == NULL; -} - -void free_tux_request_slabs(void) -{ - kmem_cache_destroy(tux_req.slab); -} diff --git a/net/tux/times.c b/net/tux/times.c deleted file mode 100644 index 284dffa11..000000000 --- a/net/tux/times.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * TUX - Integrated Application Protocols Layer and Object Cache - * - * Copyright (C) 2000, 2001, Ingo Molnar - * - * times.c: time conversion routines. - * - * Original time convserion code Copyright (C) 1999 by Arjan van de Ven - */ - -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -#include -#include -#include -#include - - -#include "times.h" - -char *dayName[7] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -static char *monthName[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -char itoa_h[60]={'0','0','0','0','0','0','0','0','0','0', - '1','1','1','1','1','1','1','1','1','1', - '2','2','2','2','2','2','2','2','2','2', - '3','3','3','3','3','3','3','3','3','3', - '4','4','4','4','4','4','4','4','4','4', - '5','5','5','5','5','5','5','5','5','5'}; - -char itoa_l[60]={'0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9'}; - -int time_unix2ls(time_t zulu, char *buf) -{ - int Y=0,M=0,D=0; - int H=0,Min=0,S=0,WD=0; - int I,I2; - time_t rest, delta; - - if (zulu > xtime.tv_sec) - zulu = xtime.tv_sec; - - I=0; - while (Izulu) - break; - I++; - } - - Y=--I; - if (I<0) { - Y=0; - goto BuildYear; - } - I2=0; - while (I2<=12) { - if (TimeDays[I][I2]>zulu) - break; - I2++; - } - - M=I2-1; - - rest=zulu - TimeDays[Y][M]; - WD=WeekDays[Y][M]; - D=rest/86400; - rest=rest%86400; - WD+=D; - WD=WD%7; - H=rest/3600; - rest=rest%3600; - Min=rest/60; - rest=rest%60; - S=rest; - -BuildYear: - Y+=TUX_YEAROFFSET; - - - /* Format: Day, 01 Mon 1999 01:01:01 GMT */ - - delta = xtime.tv_sec - zulu; - if (delta > 6*30*24*60) - // "May 23 2000" - return sprintf( buf, "%s %02i %04i", monthName[M], D+1, Y); - else - // "May 23 10:14" - return sprintf( buf, "%s %02i %02i:%02i", - monthName[M], D+1, H, Min); -} - -static int MonthHash[32] = - {0,0,7,0,0,0,0,0,0,0,0,3,0,0,0,2,6,0,5,0,9,8,4,0,0,11,1,10,0,0,0,0}; - -#define is_digit(c) ((c) >= '0' && (c) <= '9') - -static inline int skip_atoi(char **s) -{ - int i=0; - - while (is_digit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - -time_t mimetime_to_unixtime(char *Q) -{ - int Y,M,D,H,Min,S; - unsigned int Hash; - time_t Temp; - char *s,**s2; - - s=Q; - s2=&s; - - if (strlen(s)<30) return 0; - if (s[3]!=',') return 0; - if (s[19]!=':') return 0; - - s+=5; /* Skip day of week */ - D = skip_atoi(s2); /* Day of month */ - s++; - Hash = (char)s[0]+(char)s[2]; - Hash = (Hash<<1) + (char)s[1]; - Hash = (Hash&63)>>1; - M = MonthHash[Hash]; - s+=4; - Y = skip_atoi(s2); /* Year */ - s++; - H = skip_atoi(s2); /* Hour */ - s++; - Min = skip_atoi(s2); /* Minutes */ - s++; - S = skip_atoi(s2); /* Seconds */ - s++; - if ((s[0]!='G')||(s[1]!='M')||(s[2]!='T')) - { - return 0; /* No GMT */ - } - - if (YTUX_YEAROFFSET+9) Y = TUX_YEAROFFSET+9; - - Temp = TimeDays[Y-TUX_YEAROFFSET][M]; - Temp += D*86400+H*3600+Min*60+S; - - return Temp; -} - -// writes the full http date, corresponding to time_t received - -void last_mod_time(char * curr, const time_t t) -{ - int day, tod, year, wday, mon, hour, min, sec; - - tod = t % 86400; - day = t / 86400; - if (tod < 0) { - tod += 86400; - --day; - } - - hour = tod / 3600; - tod %= 3600; - min = tod / 60; - sec = tod % 60; - - wday = (day + 4) % 7; - if (wday < 0) - wday += 7; - - day -= 11017; - /* day 0 is march 1, 2000 */ - year = 5 + day / 146097; - day = day % 146097; - if (day < 0) { - day += 146097; - --year; - } - /* from now on, day is nonnegative */ - year *= 4; - if (day == 146096) { - year += 3; - day = 36524; - } else { - year += day / 36524; - day %= 36524; - } - year *= 25; - year += day / 1461; - day %= 1461; - year *= 4; - if (day == 1460) { - year += 3; - day = 365; - } else { - year += day / 365; - day %= 365; - } - - day *= 10; - mon = (day + 5) / 306; - day = day + 5 - 306 * mon; - day /= 10; - if (mon >= 10) { - ++year; - mon -= 10; - } else - mon += 2; - - sprintf(curr, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", dayName[wday], - day+1, monthName[mon], year, hour, min, sec); -} - -// writes the full date in ISO8601 format, -// corresponding to time_t received -// example: 20011126224910 - -int mdtm_time(char * curr, const time_t t) -{ - int day, tod, year, wday, mon, hour, min, sec; - - tod = t % 86400; - day = t / 86400; - if (tod < 0) { - tod += 86400; - --day; - } - - hour = tod / 3600; - tod %= 3600; - min = tod / 60; - sec = tod % 60; - - wday = (day + 4) % 7; - if (wday < 0) - wday += 7; - - day -= 11017; - /* day 0 is march 1, 2000 */ - year = 5 + day / 146097; - day = day % 146097; - if (day < 0) { - day += 146097; - --year; - } - /* from now on, day is nonnegative */ - year *= 4; - if (day == 146096) { - year += 3; - day = 36524; - } else { - year += day / 36524; - day %= 36524; - } - year *= 25; - year += day / 1461; - day %= 1461; - year *= 4; - if (day == 1460) { - year += 3; - day = 365; - } else { - year += day / 365; - day %= 365; - } - - day *= 10; - mon = (day + 5) / 306; - day = day + 5 - 306 * mon; - day /= 10; - if (mon >= 10) { - ++year; - mon -= 10; - } else - mon += 2; - - return sprintf(curr, "213 %.4d%.2d%.2d%.2d%.2d%.2d\r\n", - year, mon+1, day+1, hour, min, sec); -} - -static inline int make_num(const char *s) -{ - if (*s >= '0' && *s <= '9') - return 10 * (*s - '0') + *(s + 1) - '0'; - else - return *(s + 1) - '0'; -} - -static inline int make_month(const char *s) -{ - int i; - - for (i = 0; i < 12; i++) - if (!strncmp(monthName[i], s, 3)) - return i+1; - return 0; -} - -time_t parse_time(const char *str, const int str_len) -{ - int hour; - int min; - int sec; - int mday; - int mon; - int year; - - if (str[3] == ',') { - /* Thu, 09 Jan 1993 01:29:59 GMT */ - - if (str_len < 29) - return -1; - - mday = make_num(str+5); - mon = make_month(str + 8); - year = 100 * make_num(str + 12) + make_num(str + 14); - hour = make_num(str + 17); - min = make_num(str + 20); - sec = make_num(str + 23); - } - else { - const char *s; - s = strchr(str, ','); - if (!s || (str_len - (s - str) < 24)) { - /* Wed Jun 9 01:29:59 1993 */ - - if (str_len < 24) - return -1; - - mon = make_month(str+4); - mday = make_num(str+8); - hour = make_num(str+11); - min = make_num(str+14); - sec = make_num(str+17); - year = make_num(str+20)*100 + make_num(str+22); - } - else { - /* Thursday, 10-Jun-93 01:29:59 GMT */ - - mday = make_num(s + 2); - mon = make_month(s + 5); - year = make_num(s + 9) + 1900; - if (year < 1970) - year += 100; - hour = make_num(s + 12); - min = make_num(s + 15); - sec = make_num(s + 18); - } - } - - if (sec < 0 || sec > 59) - return -1; - if (min < 0 || min > 59) - return -1; - if (hour < 0 || hour > 23) - return -1; - if (mday < 1 || mday > 31) - return -1; - if (mon < 1 || mon > 12) - return -1; - if (year < 1970 || year > 2020) - return -1; - - return mktime(year, mon, mday, hour, min, sec); -} diff --git a/net/tux/times.h b/net/tux/times.h deleted file mode 100644 index d7a3661b6..000000000 --- a/net/tux/times.h +++ /dev/null @@ -1,26 +0,0 @@ -static time_t TimeDays[10][13] = { - { 852073200, 854751600, 857170800, 859849200, 862441200, 865119600, 867711600, 870390000, 873068400, 875660400, 878338800, 880930800, 883609200 } , - { 883609200, 886287600, 888706800, 891385200, 893977200, 896655600, 899247600, 901926000, 904604400, 907196400, 909874800, 912466800, 915145200 } , - { 915145200, 917823600, 920242800, 922921200, 925513200, 928191600, 930783600, 933462000, 936140400, 938732400, 941410800, 944002800, 946681200 } , - { 946681200, 949359600, 951865200, 954543600, 957135600, 959814000, 962406000, 965084400, 967762800, 970354800, 973033200, 975625200, 978303600 } , - { 978303600, 980982000, 983401200, 986079600, 988671600, 991350000, 993942000, 996620400, 999298800, 1001890800, 1004569200, 1007161200, 1009839600 } , - { 1009839600, 1012518000, 1014937200, 1017615600, 1020207600, 1022886000, 1025478000, 1028156400, 1030834800, 1033426800, 1036105200, 1038697200, 1041375600 } , - { 1041375600, 1044054000, 1046473200, 1049151600, 1051743600, 1054422000, 1057014000, 1059692400, 1062370800, 1064962800, 1067641200, 1070233200, 1072911600 } , - { 1072911600, 1075590000, 1078095600, 1080774000, 1083366000, 1086044400, 1088636400, 1091314800, 1093993200, 1096585200, 1099263600, 1101855600, 1104534000 } , - { 1104534000, 1107212400, 1109631600, 1112310000, 1114902000, 1117580400, 1120172400, 1122850800, 1125529200, 1128121200, 1130799600, 1133391600, 1136070000 } , - { 1136070000, 1138748400, 1141167600, 1143846000, 1146438000, 1149116400, 1151708400, 1154386800, 1157065200, 1159657200, 1162335600, 1164927600, 1167606000 } -}; -static int WeekDays[10][13] = { - { 3, 6, 6, 2, 4, 0, 2, 5, 1, 3, 6, 1, 4 } , - { 4, 0, 0, 3, 5, 1, 3, 6, 2, 4, 0, 2, 5 } , - { 5, 1, 1, 4, 6, 2, 4, 0, 3, 5, 1, 3, 6 } , - { 6, 2, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5, 1 } , - { 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6, 2 } , - { 2, 5, 5, 1, 3, 6, 1, 4, 0, 2, 5, 0, 3 } , - { 3, 6, 6, 2, 4, 0, 2, 5, 1, 3, 6, 1, 4 } , - { 4, 0, 1, 4, 6, 2, 4, 0, 3, 5, 1, 3, 6 } , - { 6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4, 0 } , - { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5, 1 } -}; -#define TUX_YEAROFFSET 1997 -#define TUX_NUMYEARS 10 diff --git a/net/tux/userspace.c b/net/tux/userspace.c deleted file mode 100644 index effd45d3a..000000000 --- a/net/tux/userspace.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * TUX - Integrated Application Protocols Layer and Object Cache - * - * Copyright (C) 2000, 2001, Ingo Molnar - * - * userspace.c: handle userspace-module requests - */ - -#include - -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index d2bdd0116..7020c57c5 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -571,7 +571,7 @@ static struct sock * unix_create1(struct socket *sock) u->mnt = NULL; spin_lock_init(&u->lock); atomic_set(&u->inflight, sock ? 0 : -1); - mutex_init(&u->readlock); /* single task reading lock */ + init_MUTEX(&u->readsem); /* single task reading lock */ init_waitqueue_head(&u->peer_wait); unix_insert_socket(unix_sockets_unbound, sk); out: @@ -628,7 +628,7 @@ static int unix_autobind(struct socket *sock) struct unix_address * addr; int err; - mutex_lock(&u->readlock); + down(&u->readsem); err = 0; if (u->addr) @@ -666,7 +666,7 @@ retry: spin_unlock(&unix_table_lock); err = 0; -out: mutex_unlock(&u->readlock); +out: up(&u->readsem); return err; } @@ -749,7 +749,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) goto out; addr_len = err; - mutex_lock(&u->readlock); + down(&u->readsem); err = -EINVAL; if (u->addr) @@ -821,7 +821,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) out_unlock: spin_unlock(&unix_table_lock); out_up: - mutex_unlock(&u->readlock); + up(&u->readsem); out: return err; @@ -1432,15 +1432,15 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, while(sent < len) { /* - * Optimisation for the fact that under 0.01% of X - * messages typically need breaking up. + * Optimisation for the fact that under 0.01% of X messages typically + * need breaking up. */ - size = len-sent; + size=len-sent; /* Keep two messages in the pipe so it schedules better */ - if (size > ((sk->sk_sndbuf >> 1) - 64)) - size = (sk->sk_sndbuf >> 1) - 64; + if (size > sk->sk_sndbuf / 2 - 64) + size = sk->sk_sndbuf / 2 - 64; if (size > SKB_MAX_ALLOC) size = SKB_MAX_ALLOC; @@ -1550,7 +1550,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, msg->msg_namelen = 0; - mutex_lock(&u->readlock); + down(&u->readsem); skb = skb_recv_datagram(sk, flags, noblock, &err); if (!skb) @@ -1605,7 +1605,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, out_free: skb_free_datagram(sk,skb); out_unlock: - mutex_unlock(&u->readlock); + up(&u->readsem); out: return err; } @@ -1681,7 +1681,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, memset(&tmp_scm, 0, sizeof(tmp_scm)); } - mutex_lock(&u->readlock); + down(&u->readsem); do { @@ -1705,7 +1705,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, err = -EAGAIN; if (!timeo) break; - mutex_unlock(&u->readlock); + up(&u->readsem); timeo = unix_stream_data_wait(sk, timeo); @@ -1713,7 +1713,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, err = sock_intr_errno(timeo); goto out; } - mutex_lock(&u->readlock); + down(&u->readsem); continue; } @@ -1779,7 +1779,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, } } while (size); - mutex_unlock(&u->readlock); + up(&u->readsem); scm_recv(sock, msg, siocb->scm, flags); out: return copied ? : err; @@ -1883,8 +1883,6 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl mask |= POLLERR; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; - if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; /* readable? */ if (!skb_queue_empty(&sk->sk_receive_queue) || diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 746c2f4a5..411802bd4 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -76,7 +76,6 @@ #include #include #include -#include #include #include @@ -170,7 +169,7 @@ static void maybe_unmark_and_push(struct sock *x) void unix_gc(void) { - static DEFINE_MUTEX(unix_gc_sem); + static DECLARE_MUTEX(unix_gc_sem); int i; struct sock *s; struct sk_buff_head hitlist; @@ -180,7 +179,7 @@ void unix_gc(void) * Avoid a recursive GC. */ - if (!mutex_trylock(&unix_gc_sem)) + if (down_trylock(&unix_gc_sem)) return; spin_lock(&unix_table_lock); @@ -309,5 +308,5 @@ void unix_gc(void) */ __skb_queue_purge(&hitlist); - mutex_unlock(&unix_gc_sem); + up(&unix_gc_sem); } diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c index b1265187b..8b9bf4a76 100644 --- a/net/wanrouter/af_wanpipe.c +++ b/net/wanrouter/af_wanpipe.c @@ -55,10 +55,12 @@ #include #include #include +#include #include #include #include #include +#include #ifdef CONFIG_INET #include diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index f404f67be..3da1bd997 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -54,10 +54,7 @@ #include /* For TIOCINQ/OUTQ */ #include #include -#include - #include -#include int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20; int sysctl_x25_call_request_timeout = X25_DEFAULT_T21; @@ -72,14 +69,6 @@ static const struct proto_ops x25_proto_ops; static struct x25_address null_x25_address = {" "}; -#ifdef CONFIG_COMPAT -struct compat_x25_subscrip_struct { - char device[200-sizeof(compat_ulong_t)]; - compat_ulong_t global_facil_mask; - compat_uint_t extended; -}; -#endif - int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, struct x25_address *calling_addr) { @@ -528,13 +517,6 @@ static int x25_create(struct socket *sock, int protocol) x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; x25->facilities.throughput = X25_DEFAULT_THROUGHPUT; x25->facilities.reverse = X25_DEFAULT_REVERSE; - x25->dte_facilities.calling_len = 0; - x25->dte_facilities.called_len = 0; - memset(x25->dte_facilities.called_ae, '\0', - sizeof(x25->dte_facilities.called_ae)); - memset(x25->dte_facilities.calling_ae, '\0', - sizeof(x25->dte_facilities.calling_ae)); - rc = 0; out: return rc; @@ -571,7 +553,6 @@ static struct sock *x25_make_new(struct sock *osk) x25->t2 = ox25->t2; x25->facilities = ox25->facilities; x25->qbitincl = ox25->qbitincl; - x25->dte_facilities = ox25->dte_facilities; x25->cudmatchlength = ox25->cudmatchlength; x25->accptapprv = ox25->accptapprv; @@ -755,7 +736,7 @@ out: return rc; } -static int x25_wait_for_data(struct sock *sk, long timeout) +static int x25_wait_for_data(struct sock *sk, int timeout) { DECLARE_WAITQUEUE(wait, current); int rc = 0; @@ -851,7 +832,6 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, struct x25_sock *makex25; struct x25_address source_addr, dest_addr; struct x25_facilities facilities; - struct x25_dte_facilities dte_facilities; int len, rc; /* @@ -888,8 +868,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, /* * Try to reach a compromise on the requested facilities. */ - len = x25_negotiate_facilities(skb, sk, &facilities, &dte_facilities); - if (len == -1) + if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1) goto out_sock_put; /* @@ -920,12 +899,9 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, makex25->source_addr = source_addr; makex25->neighbour = nb; makex25->facilities = facilities; - makex25->dte_facilities= dte_facilities; makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask; /* ensure no reverse facil on accept */ makex25->vc_facil_mask &= ~X25_MASK_REVERSE; - /* ensure no calling address extension on accept */ - makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE; makex25->cudmatchlength = x25_sk(sk)->cudmatchlength; /* Normally all calls are accepted immediatly */ @@ -1332,36 +1308,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; } - case SIOCX25GDTEFACILITIES: { - rc = copy_to_user(argp, &x25->dte_facilities, - sizeof(x25->dte_facilities)); - if (rc) - rc = -EFAULT; - break; - } - - case SIOCX25SDTEFACILITIES: { - struct x25_dte_facilities dtefacs; - rc = -EFAULT; - if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) - break; - rc = -EINVAL; - if (sk->sk_state != TCP_LISTEN && - sk->sk_state != TCP_CLOSE) - break; - if (dtefacs.calling_len > X25_MAX_AE_LEN) - break; - if (dtefacs.calling_ae == NULL) - break; - if (dtefacs.called_len > X25_MAX_AE_LEN) - break; - if (dtefacs.called_ae == NULL) - break; - x25->dte_facilities = dtefacs; - rc = 0; - break; - } - case SIOCX25GCALLUSERDATA: { struct x25_calluserdata cud = x25->calluserdata; rc = copy_to_user(argp, &cud, @@ -1444,118 +1390,6 @@ static struct net_proto_family x25_family_ops = { .owner = THIS_MODULE, }; -#ifdef CONFIG_COMPAT -static int compat_x25_subscr_ioctl(unsigned int cmd, - struct compat_x25_subscrip_struct __user *x25_subscr32) -{ - struct compat_x25_subscrip_struct x25_subscr; - struct x25_neigh *nb; - struct net_device *dev; - int rc = -EINVAL; - - rc = -EFAULT; - if (copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32))) - goto out; - - rc = -EINVAL; - dev = x25_dev_get(x25_subscr.device); - if (dev == NULL) - goto out; - - nb = x25_get_neigh(dev); - if (nb == NULL) - goto out_dev_put; - - dev_put(dev); - - if (cmd == SIOCX25GSUBSCRIP) { - x25_subscr.extended = nb->extended; - x25_subscr.global_facil_mask = nb->global_facil_mask; - rc = copy_to_user(x25_subscr32, &x25_subscr, - sizeof(*x25_subscr32)) ? -EFAULT : 0; - } else { - rc = -EINVAL; - if (x25_subscr.extended == 0 || x25_subscr.extended == 1) { - rc = 0; - nb->extended = x25_subscr.extended; - nb->global_facil_mask = x25_subscr.global_facil_mask; - } - } - x25_neigh_put(nb); -out: - return rc; -out_dev_put: - dev_put(dev); - goto out; -} - -static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = compat_ptr(arg); - struct sock *sk = sock->sk; - - int rc = -ENOIOCTLCMD; - - switch(cmd) { - case TIOCOUTQ: - case TIOCINQ: - rc = x25_ioctl(sock, cmd, (unsigned long)argp); - break; - case SIOCGSTAMP: - rc = -EINVAL; - if (sk) - rc = compat_sock_get_timestamp(sk, - (struct timeval __user*)argp); - break; - case SIOCGIFADDR: - case SIOCSIFADDR: - case SIOCGIFDSTADDR: - case SIOCSIFDSTADDR: - case SIOCGIFBRDADDR: - case SIOCSIFBRDADDR: - case SIOCGIFNETMASK: - case SIOCSIFNETMASK: - case SIOCGIFMETRIC: - case SIOCSIFMETRIC: - rc = -EINVAL; - break; - case SIOCADDRT: - case SIOCDELRT: - rc = -EPERM; - if (!capable(CAP_NET_ADMIN)) - break; - rc = x25_route_ioctl(cmd, argp); - break; - case SIOCX25GSUBSCRIP: - rc = compat_x25_subscr_ioctl(cmd, argp); - break; - case SIOCX25SSUBSCRIP: - rc = -EPERM; - if (!capable(CAP_NET_ADMIN)) - break; - rc = compat_x25_subscr_ioctl(cmd, argp); - break; - case SIOCX25GFACILITIES: - case SIOCX25SFACILITIES: - case SIOCX25GDTEFACILITIES: - case SIOCX25SDTEFACILITIES: - case SIOCX25GCALLUSERDATA: - case SIOCX25SCALLUSERDATA: - case SIOCX25GCAUSEDIAG: - case SIOCX25SCUDMATCHLEN: - case SIOCX25CALLACCPTAPPRV: - case SIOCX25SENDCALLACCPT: - rc = x25_ioctl(sock, cmd, (unsigned long)argp); - break; - default: - rc = -ENOIOCTLCMD; - break; - } - return rc; -} -#endif - static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { .family = AF_X25, .owner = THIS_MODULE, @@ -1567,9 +1401,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { .getname = x25_getname, .poll = datagram_poll, .ioctl = x25_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = compat_x25_ioctl, -#endif .listen = x25_listen, .shutdown = sock_no_shutdown, .setsockopt = x25_setsockopt, diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 9f42b9c9d..54278b962 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c @@ -28,28 +28,18 @@ #include /* - * Parse a set of facilities into the facilities structures. Unrecognised + * Parse a set of facilities into the facilities structure. Unrecognised * facilities are written to the debug log file. */ -int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, - struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) +int x25_parse_facilities(struct sk_buff *skb, + struct x25_facilities *facilities, + unsigned long *vc_fac_mask) { unsigned char *p = skb->data; unsigned int len = *p++; *vc_fac_mask = 0; - /* - * The kernel knows which facilities were set on an incoming call but - * currently this information is not available to userspace. Here we - * give userspace who read incoming call facilities 0 length to indicate - * it wasn't set. - */ - dte_facs->calling_len = 0; - dte_facs->called_len = 0; - memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); - memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); - while (len > 0) { switch (*p & X25_FAC_CLASS_MASK) { case X25_FAC_CLASS_A: @@ -84,8 +74,6 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, facilities->throughput = p[1]; *vc_fac_mask |= X25_MASK_THROUGHPUT; break; - case X25_MARKER: - break; default: printk(KERN_DEBUG "X.25: unknown facility " "%02X, value %02X\n", @@ -124,30 +112,11 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, len -= 4; break; case X25_FAC_CLASS_D: - switch (*p) { - case X25_FAC_CALLING_AE: - if (p[1] > X25_MAX_DTE_FACIL_LEN) - break; - dte_facs->calling_len = p[2]; - memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); - *vc_fac_mask |= X25_MASK_CALLING_AE; - break; - case X25_FAC_CALLED_AE: - if (p[1] > X25_MAX_DTE_FACIL_LEN) - break; - dte_facs->called_len = p[2]; - memcpy(dte_facs->called_ae, &p[3], p[1] - 1); - *vc_fac_mask |= X25_MASK_CALLED_AE; - break; - default: - printk(KERN_DEBUG "X.25: unknown facility %02X," - "length %d, values %02X, %02X, " - "%02X, %02X\n", - p[0], p[1], p[2], p[3], p[4], p[5]); - break; - } + printk(KERN_DEBUG "X.25: unknown facility %02X, " + "length %d, values %02X, %02X, %02X, %02X\n", + p[0], p[1], p[2], p[3], p[4], p[5]); len -= p[1] + 2; - p += p[1] + 2; + p += p[1] + 2; break; } } @@ -159,8 +128,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, * Create a set of facilities. */ int x25_create_facilities(unsigned char *buffer, - struct x25_facilities *facilities, - struct x25_dte_facilities *dte_facs, unsigned long facil_mask) + struct x25_facilities *facilities, + unsigned long facil_mask) { unsigned char *p = buffer + 1; int len; @@ -199,33 +168,6 @@ int x25_create_facilities(unsigned char *buffer, *p++ = facilities->winsize_out ? : facilities->winsize_in; } - if (facil_mask & (X25_MASK_CALLING_AE|X25_MASK_CALLED_AE)) { - *p++ = X25_MARKER; - *p++ = X25_DTE_SERVICES; - } - - if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) { - unsigned bytecount = (dte_facs->calling_len % 2) ? - dte_facs->calling_len / 2 + 1 : - dte_facs->calling_len / 2; - *p++ = X25_FAC_CALLING_AE; - *p++ = 1 + bytecount; - *p++ = dte_facs->calling_len; - memcpy(p, dte_facs->calling_ae, bytecount); - p += bytecount; - } - - if (dte_facs->called_len && (facil_mask & X25_MASK_CALLED_AE)) { - unsigned bytecount = (dte_facs->called_len % 2) ? - dte_facs->called_len / 2 + 1 : - dte_facs->called_len / 2; - *p++ = X25_FAC_CALLED_AE; - *p++ = 1 + bytecount; - *p++ = dte_facs->called_len; - memcpy(p, dte_facs->called_ae, bytecount); - p+=bytecount; - } - len = p - buffer; buffer[0] = len - 1; @@ -238,7 +180,7 @@ int x25_create_facilities(unsigned char *buffer, * The only real problem is with reverse charging. */ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, - struct x25_facilities *new, struct x25_dte_facilities *dte) + struct x25_facilities *new) { struct x25_sock *x25 = x25_sk(sk); struct x25_facilities *ours = &x25->facilities; @@ -248,7 +190,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, memset(&theirs, 0, sizeof(theirs)); memcpy(new, ours, sizeof(*new)); - len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask); + len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask); /* * They want reverse charging, we won't accept it. diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index eed50e10f..26146874b 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c @@ -106,8 +106,7 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); skb_pull(skb, x25_parse_facilities(skb, &x25->facilities, - &x25->dte_facilities, - &x25->vc_facil_mask)); + &x25->vc_facil_mask)); /* * Copy any Call User Data. */ diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c index 8d6220aa5..8be9b8fbc 100644 --- a/net/x25/x25_subr.c +++ b/net/x25/x25_subr.c @@ -190,9 +190,8 @@ void x25_write_internal(struct sock *sk, int frametype) dptr = skb_put(skb, len); memcpy(dptr, addresses, len); len = x25_create_facilities(facilities, - &x25->facilities, - &x25->dte_facilities, - x25->neighbour->global_facil_mask); + &x25->facilities, + x25->neighbour->global_facil_mask); dptr = skb_put(skb, len); memcpy(dptr, facilities, len); dptr = skb_put(skb, x25->calluserdata.cudlength); @@ -207,7 +206,6 @@ void x25_write_internal(struct sock *sk, int frametype) *dptr++ = 0x00; /* Address lengths */ len = x25_create_facilities(facilities, &x25->facilities, - &x25->dte_facilities, x25->vc_facil_mask); dptr = skb_put(skb, len); memcpy(dptr, facilities, len); diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c index 71ff3088f..0a92e1da3 100644 --- a/net/x25/x25_timer.c +++ b/net/x25/x25_timer.c @@ -114,9 +114,8 @@ static void x25_heartbeat_expiry(unsigned long param) if (sock_flag(sk, SOCK_DESTROY) || (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { - bh_unlock_sock(sk); x25_destroy_socket(sk); - return; + goto unlock; } break; @@ -129,6 +128,7 @@ static void x25_heartbeat_expiry(unsigned long param) } restart_heartbeat: x25_start_heartbeat(sk); +unlock: bh_unlock_sock(sk); } diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 891a6090c..2407a7072 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -18,7 +18,7 @@ void __secpath_destroy(struct sec_path *sp) { int i; for (i = 0; i < sp->len; i++) - xfrm_state_put(sp->xvec[i]); + xfrm_state_put(sp->x[i].xvec); kmem_cache_free(secpath_cachep, sp); } EXPORT_SYMBOL(__secpath_destroy); @@ -37,7 +37,7 @@ struct sec_path *secpath_dup(struct sec_path *src) memcpy(sp, src, sizeof(*sp)); for (i = 0; i < sp->len; i++) - xfrm_state_hold(sp->xvec[i]); + xfrm_state_hold(sp->x[i].xvec); } atomic_set(&sp->refcnt, 1); return sp; @@ -62,7 +62,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) case IPPROTO_COMP: if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr))) return -EINVAL; - *spi = htonl(ntohs(*(u16*)(skb->h.raw + 2))); + *spi = ntohl(ntohs(*(u16*)(skb->h.raw + 2))); *seq = 0; return 0; default: diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index b469c8b54..ae62054a9 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -26,8 +26,8 @@ #include #include -DEFINE_MUTEX(xfrm_cfg_mutex); -EXPORT_SYMBOL(xfrm_cfg_mutex); +DECLARE_MUTEX(xfrm_cfg_sem); +EXPORT_SYMBOL(xfrm_cfg_sem); static DEFINE_RWLOCK(xfrm_policy_lock); @@ -57,12 +57,12 @@ int xfrm_register_type(struct xfrm_type *type, unsigned short family) return -EAFNOSUPPORT; typemap = afinfo->type_map; - write_lock_bh(&typemap->lock); + write_lock(&typemap->lock); if (likely(typemap->map[type->proto] == NULL)) typemap->map[type->proto] = type; else err = -EEXIST; - write_unlock_bh(&typemap->lock); + write_unlock(&typemap->lock); xfrm_policy_put_afinfo(afinfo); return err; } @@ -78,12 +78,12 @@ int xfrm_unregister_type(struct xfrm_type *type, unsigned short family) return -EAFNOSUPPORT; typemap = afinfo->type_map; - write_lock_bh(&typemap->lock); + write_lock(&typemap->lock); if (unlikely(typemap->map[type->proto] != type)) err = -ENOENT; else typemap->map[type->proto] = NULL; - write_unlock_bh(&typemap->lock); + write_unlock(&typemap->lock); xfrm_policy_put_afinfo(afinfo); return err; } @@ -203,7 +203,7 @@ static void xfrm_policy_timer(unsigned long data) } if (warn) - km_policy_expired(xp, dir, 0, 0); + km_policy_expired(xp, dir, 0); if (next != LONG_MAX && !mod_timer(&xp->timer, jiffies + make_jiffies(next))) xfrm_pol_hold(xp); @@ -216,7 +216,7 @@ out: expired: read_unlock(&xp->lock); if (!xfrm_policy_delete(xp, dir)) - km_policy_expired(xp, dir, 1, 0); + km_policy_expired(xp, dir, 1); xfrm_pol_put(xp); } @@ -621,7 +621,6 @@ int xfrm_policy_delete(struct xfrm_policy *pol, int dir) } return -ENOENT; } -EXPORT_SYMBOL(xfrm_policy_delete); int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) { @@ -943,9 +942,9 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start, } else start = -1; for (; idx < sp->len; idx++) { - if (xfrm_state_ok(tmpl, sp->xvec[idx], family)) + if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family)) return ++idx; - if (sp->xvec[idx]->props.mode) + if (sp->x[idx].xvec->props.mode) break; } return start; @@ -968,7 +967,7 @@ EXPORT_SYMBOL(xfrm_decode_session); static inline int secpath_has_tunnel(struct sec_path *sp, int k) { for (; k < sp->len; k++) { - if (sp->xvec[k]->props.mode) + if (sp->x[k].xvec->props.mode) return 1; } @@ -994,8 +993,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, int i; for (i=skb->sp->len-1; i>=0; i--) { - struct xfrm_state *x = skb->sp->xvec[i]; - if (!xfrm_selector_match(&x->sel, &fl, family)) + struct sec_decap_state *xvec = &(skb->sp->x[i]); + if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) return 0; } } @@ -1251,7 +1250,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) return -EINVAL; if (unlikely(afinfo->family >= NPROTO)) return -EAFNOSUPPORT; - write_lock_bh(&xfrm_policy_afinfo_lock); + write_lock(&xfrm_policy_afinfo_lock); if (unlikely(xfrm_policy_afinfo[afinfo->family] != NULL)) err = -ENOBUFS; else { @@ -1268,7 +1267,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) afinfo->garbage_collect = __xfrm_garbage_collect; xfrm_policy_afinfo[afinfo->family] = afinfo; } - write_unlock_bh(&xfrm_policy_afinfo_lock); + write_unlock(&xfrm_policy_afinfo_lock); return err; } EXPORT_SYMBOL(xfrm_policy_register_afinfo); @@ -1280,7 +1279,7 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) return -EINVAL; if (unlikely(afinfo->family >= NPROTO)) return -EAFNOSUPPORT; - write_lock_bh(&xfrm_policy_afinfo_lock); + write_lock(&xfrm_policy_afinfo_lock); if (likely(xfrm_policy_afinfo[afinfo->family] != NULL)) { if (unlikely(xfrm_policy_afinfo[afinfo->family] != afinfo)) err = -EINVAL; @@ -1294,7 +1293,7 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) afinfo->garbage_collect = NULL; } } - write_unlock_bh(&xfrm_policy_afinfo_lock); + write_unlock(&xfrm_policy_afinfo_lock); return err; } EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 93a2f36ad..c656cbaf3 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -20,15 +20,6 @@ #include #include -struct sock *xfrm_nl; -EXPORT_SYMBOL(xfrm_nl); - -u32 sysctl_xfrm_aevent_etime = XFRM_AE_ETIME; -EXPORT_SYMBOL(sysctl_xfrm_aevent_etime); - -u32 sysctl_xfrm_aevent_rseqth = XFRM_AE_SEQT_SIZE; -EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth); - /* Each xfrm_state may be linked to two tables: 1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl) @@ -59,20 +50,18 @@ static DEFINE_SPINLOCK(xfrm_state_gc_lock); static int xfrm_state_gc_flush_bundles; -int __xfrm_state_delete(struct xfrm_state *x); +static int __xfrm_state_delete(struct xfrm_state *x); static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); -int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); -void km_state_expired(struct xfrm_state *x, int hard, u32 pid); +static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); +static void km_state_expired(struct xfrm_state *x, int hard); static void xfrm_state_gc_destroy(struct xfrm_state *x) { if (del_timer(&x->timer)) BUG(); - if (del_timer(&x->rtimer)) - BUG(); kfree(x->aalg); kfree(x->ealg); kfree(x->calg); @@ -164,7 +153,7 @@ static void xfrm_timer_handler(unsigned long data) x->km.dying = warn; if (warn) - km_state_expired(x, 0, 0); + km_state_expired(x, 0); resched: if (next != LONG_MAX && !mod_timer(&x->timer, jiffies + make_jiffies(next))) @@ -179,15 +168,13 @@ expired: goto resched; } if (!__xfrm_state_delete(x) && x->id.spi) - km_state_expired(x, 1, 0); + km_state_expired(x, 1); out: spin_unlock(&x->lock); xfrm_state_put(x); } -static void xfrm_replay_timer_handler(unsigned long data); - struct xfrm_state *xfrm_state_alloc(void) { struct xfrm_state *x; @@ -203,16 +190,11 @@ struct xfrm_state *xfrm_state_alloc(void) init_timer(&x->timer); x->timer.function = xfrm_timer_handler; x->timer.data = (unsigned long)x; - init_timer(&x->rtimer); - x->rtimer.function = xfrm_replay_timer_handler; - x->rtimer.data = (unsigned long)x; x->curlft.add_time = (unsigned long)xtime.tv_sec; x->lft.soft_byte_limit = XFRM_INF; x->lft.soft_packet_limit = XFRM_INF; x->lft.hard_byte_limit = XFRM_INF; x->lft.hard_packet_limit = XFRM_INF; - x->replay_maxage = 0; - x->replay_maxdiff = 0; spin_lock_init(&x->lock); } return x; @@ -230,7 +212,7 @@ void __xfrm_state_destroy(struct xfrm_state *x) } EXPORT_SYMBOL(__xfrm_state_destroy); -int __xfrm_state_delete(struct xfrm_state *x) +static int __xfrm_state_delete(struct xfrm_state *x) { int err = -ESRCH; @@ -246,8 +228,6 @@ int __xfrm_state_delete(struct xfrm_state *x) spin_unlock(&xfrm_state_lock); if (del_timer(&x->timer)) __xfrm_state_put(x); - if (del_timer(&x->rtimer)) - __xfrm_state_put(x); /* The number two in this test is the reference * mentioned in the comment below plus the reference @@ -269,7 +249,6 @@ int __xfrm_state_delete(struct xfrm_state *x) return err; } -EXPORT_SYMBOL(__xfrm_state_delete); int xfrm_state_delete(struct xfrm_state *x) { @@ -447,10 +426,6 @@ static void __xfrm_state_insert(struct xfrm_state *x) if (!mod_timer(&x->timer, jiffies + HZ)) xfrm_state_hold(x); - if (x->replay_maxage && - !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) - xfrm_state_hold(x); - wake_up(&km_waitq); } @@ -605,7 +580,7 @@ int xfrm_state_check_expire(struct xfrm_state *x) (x->curlft.bytes >= x->lft.soft_byte_limit || x->curlft.packets >= x->lft.soft_packet_limit)) { x->km.dying = 1; - km_state_expired(x, 0, 0); + km_state_expired(x, 0); } return 0; } @@ -787,74 +762,6 @@ out: } EXPORT_SYMBOL(xfrm_state_walk); - -void xfrm_replay_notify(struct xfrm_state *x, int event) -{ - struct km_event c; - /* we send notify messages in case - * 1. we updated on of the sequence numbers, and the seqno difference - * is at least x->replay_maxdiff, in this case we also update the - * timeout of our timer function - * 2. if x->replay_maxage has elapsed since last update, - * and there were changes - * - * The state structure must be locked! - */ - - switch (event) { - case XFRM_REPLAY_UPDATE: - if (x->replay_maxdiff && - (x->replay.seq - x->preplay.seq < x->replay_maxdiff) && - (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff)) { - if (x->xflags & XFRM_TIME_DEFER) - event = XFRM_REPLAY_TIMEOUT; - else - return; - } - - break; - - case XFRM_REPLAY_TIMEOUT: - if ((x->replay.seq == x->preplay.seq) && - (x->replay.bitmap == x->preplay.bitmap) && - (x->replay.oseq == x->preplay.oseq)) { - x->xflags |= XFRM_TIME_DEFER; - return; - } - - break; - } - - memcpy(&x->preplay, &x->replay, sizeof(struct xfrm_replay_state)); - c.event = XFRM_MSG_NEWAE; - c.data.aevent = event; - km_state_notify(x, &c); - - if (x->replay_maxage && - !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) { - xfrm_state_hold(x); - x->xflags &= ~XFRM_TIME_DEFER; - } -} -EXPORT_SYMBOL(xfrm_replay_notify); - -static void xfrm_replay_timer_handler(unsigned long data) -{ - struct xfrm_state *x = (struct xfrm_state*)data; - - spin_lock(&x->lock); - - if (x->km.state == XFRM_STATE_VALID) { - if (xfrm_aevent_is_on()) - xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT); - else - x->xflags |= XFRM_TIME_DEFER; - } - - spin_unlock(&x->lock); - xfrm_state_put(x); -} - int xfrm_replay_check(struct xfrm_state *x, u32 seq) { u32 diff; @@ -898,9 +805,6 @@ void xfrm_replay_advance(struct xfrm_state *x, u32 seq) diff = x->replay.seq - seq; x->replay.bitmap |= (1U << diff); } - - if (xfrm_aevent_is_on()) - xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); } EXPORT_SYMBOL(xfrm_replay_advance); @@ -931,12 +835,11 @@ void km_state_notify(struct xfrm_state *x, struct km_event *c) EXPORT_SYMBOL(km_policy_notify); EXPORT_SYMBOL(km_state_notify); -void km_state_expired(struct xfrm_state *x, int hard, u32 pid) +static void km_state_expired(struct xfrm_state *x, int hard) { struct km_event c; c.data.hard = hard; - c.pid = pid; c.event = XFRM_MSG_EXPIRE; km_state_notify(x, &c); @@ -944,12 +847,11 @@ void km_state_expired(struct xfrm_state *x, int hard, u32 pid) wake_up(&km_waitq); } -EXPORT_SYMBOL(km_state_expired); /* * We send to all registered managers regardless of failure * We are happy with one success */ -int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol) +static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol) { int err = -EINVAL, acqret; struct xfrm_mgr *km; @@ -963,7 +865,6 @@ int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol) read_unlock(&xfrm_km_lock); return err; } -EXPORT_SYMBOL(km_query); int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) { @@ -982,19 +883,17 @@ int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) } EXPORT_SYMBOL(km_new_mapping); -void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid) +void km_policy_expired(struct xfrm_policy *pol, int dir, int hard) { struct km_event c; c.data.hard = hard; - c.pid = pid; c.event = XFRM_MSG_POLEXPIRE; km_policy_notify(pol, dir, &c); if (hard) wake_up(&km_waitq); } -EXPORT_SYMBOL(km_policy_expired); int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen) { @@ -1061,7 +960,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo) return -EINVAL; if (unlikely(afinfo->family >= NPROTO)) return -EAFNOSUPPORT; - write_lock_bh(&xfrm_state_afinfo_lock); + write_lock(&xfrm_state_afinfo_lock); if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL)) err = -ENOBUFS; else { @@ -1069,7 +968,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo) afinfo->state_byspi = xfrm_state_byspi; xfrm_state_afinfo[afinfo->family] = afinfo; } - write_unlock_bh(&xfrm_state_afinfo_lock); + write_unlock(&xfrm_state_afinfo_lock); return err; } EXPORT_SYMBOL(xfrm_state_register_afinfo); @@ -1081,7 +980,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo) return -EINVAL; if (unlikely(afinfo->family >= NPROTO)) return -EAFNOSUPPORT; - write_lock_bh(&xfrm_state_afinfo_lock); + write_lock(&xfrm_state_afinfo_lock); if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) { if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo)) err = -EINVAL; @@ -1091,7 +990,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo) afinfo->state_bydst = NULL; } } - write_unlock_bh(&xfrm_state_afinfo_lock); + write_unlock(&xfrm_state_afinfo_lock); return err; } EXPORT_SYMBOL(xfrm_state_unregister_afinfo); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 81d100583..7de175592 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -28,6 +28,8 @@ #include #include +static struct sock *xfrm_nl; + static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type) { struct rtattr *rt = xfrma[type - 1]; @@ -101,6 +103,9 @@ static inline int verify_sec_ctx_len(struct rtattr **xfrma) uctx = RTA_DATA(rt); + if (uctx->ctx_len > PAGE_SIZE) + return -EINVAL; + len += sizeof(struct xfrm_user_sec_ctx); len += uctx->ctx_len; @@ -271,56 +276,6 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * x->props.flags = p->flags; } -/* - * someday when pfkey also has support, we could have the code - * somehow made shareable and move it to xfrm_state.c - JHS - * -*/ -static int xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma) -{ - int err = - EINVAL; - struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1]; - struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1]; - struct rtattr *et = xfrma[XFRMA_ETIMER_THRESH-1]; - struct rtattr *rt = xfrma[XFRMA_REPLAY_THRESH-1]; - - if (rp) { - struct xfrm_replay_state *replay; - if (RTA_PAYLOAD(rp) < sizeof(*replay)) - goto error; - replay = RTA_DATA(rp); - memcpy(&x->replay, replay, sizeof(*replay)); - memcpy(&x->preplay, replay, sizeof(*replay)); - } - - if (lt) { - struct xfrm_lifetime_cur *ltime; - if (RTA_PAYLOAD(lt) < sizeof(*ltime)) - goto error; - ltime = RTA_DATA(lt); - x->curlft.bytes = ltime->bytes; - x->curlft.packets = ltime->packets; - x->curlft.add_time = ltime->add_time; - x->curlft.use_time = ltime->use_time; - } - - if (et) { - if (RTA_PAYLOAD(et) < sizeof(u32)) - goto error; - x->replay_maxage = *(u32*)RTA_DATA(et); - } - - if (rt) { - if (RTA_PAYLOAD(rt) < sizeof(u32)) - goto error; - x->replay_maxdiff = *(u32*)RTA_DATA(rt); - } - - return 0; -error: - return err; -} - static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, struct rtattr **xfrma, int *errp) @@ -356,18 +311,6 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, goto error; x->km.seq = p->seq; - x->replay_maxdiff = sysctl_xfrm_aevent_rseqth; - /* sysctl_xfrm_aevent_etime is in 100ms units */ - x->replay_maxage = (sysctl_xfrm_aevent_etime*HZ)/XFRM_AE_ETH_M; - x->preplay.bitmap = 0; - x->preplay.seq = x->replay.seq+x->replay_maxdiff; - x->preplay.oseq = x->replay.oseq +x->replay_maxdiff; - - /* override default values from above */ - - err = xfrm_update_ae_params(x, (struct rtattr **)xfrma); - if (err < 0) - goto error; return x; @@ -1082,142 +1025,9 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma return 0; } - -static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c) -{ - struct xfrm_aevent_id *id; - struct nlmsghdr *nlh; - struct xfrm_lifetime_cur ltime; - unsigned char *b = skb->tail; - - nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id)); - id = NLMSG_DATA(nlh); - nlh->nlmsg_flags = 0; - - id->sa_id.daddr = x->id.daddr; - id->sa_id.spi = x->id.spi; - id->sa_id.family = x->props.family; - id->sa_id.proto = x->id.proto; - id->flags = c->data.aevent; - - RTA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay); - - ltime.bytes = x->curlft.bytes; - ltime.packets = x->curlft.packets; - ltime.add_time = x->curlft.add_time; - ltime.use_time = x->curlft.use_time; - - RTA_PUT(skb, XFRMA_LTIME_VAL, sizeof(struct xfrm_lifetime_cur), <ime); - - if (id->flags&XFRM_AE_RTHR) { - RTA_PUT(skb,XFRMA_REPLAY_THRESH,sizeof(u32),&x->replay_maxdiff); - } - - if (id->flags&XFRM_AE_ETHR) { - u32 etimer = x->replay_maxage*10/HZ; - RTA_PUT(skb,XFRMA_ETIMER_THRESH,sizeof(u32),&etimer); - } - - nlh->nlmsg_len = skb->tail - b; - return skb->len; - -rtattr_failure: -nlmsg_failure: - skb_trim(skb, b - skb->data); - return -1; -} - -static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) -{ - struct xfrm_state *x; - struct sk_buff *r_skb; - int err; - struct km_event c; - struct xfrm_aevent_id *p = NLMSG_DATA(nlh); - int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id)); - struct xfrm_usersa_id *id = &p->sa_id; - - len += RTA_SPACE(sizeof(struct xfrm_replay_state)); - len += RTA_SPACE(sizeof(struct xfrm_lifetime_cur)); - - if (p->flags&XFRM_AE_RTHR) - len+=RTA_SPACE(sizeof(u32)); - - if (p->flags&XFRM_AE_ETHR) - len+=RTA_SPACE(sizeof(u32)); - - r_skb = alloc_skb(len, GFP_ATOMIC); - if (r_skb == NULL) - return -ENOMEM; - - x = xfrm_state_lookup(&id->daddr, id->spi, id->proto, id->family); - if (x == NULL) { - kfree(r_skb); - return -ESRCH; - } - - /* - * XXX: is this lock really needed - none of the other - * gets lock (the concern is things getting updated - * while we are still reading) - jhs - */ - spin_lock_bh(&x->lock); - c.data.aevent = p->flags; - c.seq = nlh->nlmsg_seq; - c.pid = nlh->nlmsg_pid; - - if (build_aevent(r_skb, x, &c) < 0) - BUG(); - err = netlink_unicast(xfrm_nl, r_skb, - NETLINK_CB(skb).pid, MSG_DONTWAIT); - spin_unlock_bh(&x->lock); - xfrm_state_put(x); - return err; -} - -static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) -{ - struct xfrm_state *x; - struct km_event c; - int err = - EINVAL; - struct xfrm_aevent_id *p = NLMSG_DATA(nlh); - struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1]; - struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1]; - - if (!lt && !rp) - return err; - - /* pedantic mode - thou shalt sayeth replaceth */ - if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) - return err; - - x = xfrm_state_lookup(&p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); - if (x == NULL) - return -ESRCH; - - if (x->km.state != XFRM_STATE_VALID) - goto out; - - spin_lock_bh(&x->lock); - err = xfrm_update_ae_params(x,(struct rtattr **)xfrma); - spin_unlock_bh(&x->lock); - if (err < 0) - goto out; - - c.event = nlh->nlmsg_type; - c.seq = nlh->nlmsg_seq; - c.pid = nlh->nlmsg_pid; - c.data.aevent = XFRM_AE_CU; - km_state_notify(x, &c); - err = 0; -out: - xfrm_state_put(x); - return err; -} - static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) { -struct km_event c; + struct km_event c; xfrm_policy_flush(); c.event = nlh->nlmsg_type; @@ -1227,139 +1037,6 @@ struct km_event c; return 0; } -static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) -{ - struct xfrm_policy *xp; - struct xfrm_user_polexpire *up = NLMSG_DATA(nlh); - struct xfrm_userpolicy_info *p = &up->pol; - int err = -ENOENT; - - if (p->index) - xp = xfrm_policy_byid(p->dir, p->index, 0); - else { - struct rtattr **rtattrs = (struct rtattr **)xfrma; - struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; - struct xfrm_policy tmp; - - err = verify_sec_ctx_len(rtattrs); - if (err) - return err; - - memset(&tmp, 0, sizeof(struct xfrm_policy)); - if (rt) { - struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt); - - if ((err = security_xfrm_policy_alloc(&tmp, uctx))) - return err; - } - xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, 0); - security_xfrm_policy_free(&tmp); - } - - if (xp == NULL) - return err; - read_lock(&xp->lock); - if (xp->dead) { - read_unlock(&xp->lock); - goto out; - } - - read_unlock(&xp->lock); - err = 0; - if (up->hard) { - xfrm_policy_delete(xp, p->dir); - } else { - // reset the timers here? - printk("Dont know what to do with soft policy expire\n"); - } - km_policy_expired(xp, p->dir, up->hard, current->pid); - -out: - xfrm_pol_put(xp); - return err; -} - -static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) -{ - struct xfrm_state *x; - int err; - struct xfrm_user_expire *ue = NLMSG_DATA(nlh); - struct xfrm_usersa_info *p = &ue->state; - - x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family); - err = -ENOENT; - - if (x == NULL) - return err; - - err = -EINVAL; - - spin_lock_bh(&x->lock); - if (x->km.state != XFRM_STATE_VALID) - goto out; - km_state_expired(x, ue->hard, current->pid); - - if (ue->hard) - __xfrm_state_delete(x); -out: - spin_unlock_bh(&x->lock); - xfrm_state_put(x); - return err; -} - -static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) -{ - struct xfrm_policy *xp; - struct xfrm_user_tmpl *ut; - int i; - struct rtattr *rt = xfrma[XFRMA_TMPL-1]; - - struct xfrm_user_acquire *ua = NLMSG_DATA(nlh); - struct xfrm_state *x = xfrm_state_alloc(); - int err = -ENOMEM; - - if (!x) - return err; - - err = verify_newpolicy_info(&ua->policy); - if (err) { - printk("BAD policy passed\n"); - kfree(x); - return err; - } - - /* build an XP */ - xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) xfrma, &err); if (!xp) { - kfree(x); - return err; - } - - memcpy(&x->id, &ua->id, sizeof(ua->id)); - memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr)); - memcpy(&x->sel, &ua->sel, sizeof(ua->sel)); - - ut = RTA_DATA(rt); - /* extract the templates and for each call km_key */ - for (i = 0; i < xp->xfrm_nr; i++, ut++) { - struct xfrm_tmpl *t = &xp->xfrm_vec[i]; - memcpy(&x->id, &t->id, sizeof(x->id)); - x->props.mode = t->mode; - x->props.reqid = t->reqid; - x->props.family = ut->family; - t->aalgos = ua->aalgos; - t->ealgos = ua->ealgos; - t->calgos = ua->calgos; - err = km_query(x, t, xp); - - } - - kfree(x); - kfree(xp); - - return 0; -} - - #define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { @@ -1377,8 +1054,6 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire), [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0), - [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id), - [XFRM_MSG_GETAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id), }; #undef XMSGSIZE @@ -1396,15 +1071,10 @@ static struct xfrm_link { [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, .dump = xfrm_dump_policy }, [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, - [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire }, - [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_sa_expire }, [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, - [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_pol_expire}, [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, - [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = { .doit = xfrm_new_ae }, - [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae }, }; static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) @@ -1486,26 +1156,26 @@ static void xfrm_netlink_rcv(struct sock *sk, int len) unsigned int qlen = 0; do { - mutex_lock(&xfrm_cfg_mutex); + down(&xfrm_cfg_sem); netlink_run_queue(sk, &qlen, &xfrm_user_rcv_msg); - mutex_unlock(&xfrm_cfg_mutex); + up(&xfrm_cfg_sem); } while (qlen); } -static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c) +static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) { struct xfrm_user_expire *ue; struct nlmsghdr *nlh; unsigned char *b = skb->tail; - nlh = NLMSG_PUT(skb, c->pid, 0, XFRM_MSG_EXPIRE, + nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_EXPIRE, sizeof(*ue)); ue = NLMSG_DATA(nlh); nlh->nlmsg_flags = 0; copy_to_user_state(x, &ue->state); - ue->hard = (c->data.hard != 0) ? 1 : 0; + ue->hard = (hard != 0) ? 1 : 0; nlh->nlmsg_len = skb->tail - b; return skb->len; @@ -1524,31 +1194,13 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) if (skb == NULL) return -ENOMEM; - if (build_expire(skb, x, c) < 0) + if (build_expire(skb, x, c->data.hard) < 0) BUG(); NETLINK_CB(skb).dst_group = XFRMNLGRP_EXPIRE; return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); } -static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c) -{ - struct sk_buff *skb; - int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id)); - - len += RTA_SPACE(sizeof(struct xfrm_replay_state)); - len += RTA_SPACE(sizeof(struct xfrm_lifetime_cur)); - skb = alloc_skb(len, GFP_ATOMIC); - if (skb == NULL) - return -ENOMEM; - - if (build_aevent(skb, x, c) < 0) - BUG(); - - NETLINK_CB(skb).dst_group = XFRMNLGRP_AEVENTS; - return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC); -} - static int xfrm_notify_sa_flush(struct km_event *c) { struct xfrm_usersa_flush *p; @@ -1661,8 +1313,6 @@ static int xfrm_send_state_notify(struct xfrm_state *x, struct km_event *c) switch (c->event) { case XFRM_MSG_EXPIRE: return xfrm_exp_state_notify(x, c); - case XFRM_MSG_NEWAE: - return xfrm_aevent_state_notify(x, c); case XFRM_MSG_DELSA: case XFRM_MSG_UPDSA: case XFRM_MSG_NEWSA: @@ -1793,14 +1443,13 @@ static struct xfrm_policy *xfrm_compile_policy(u16 family, int opt, } static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, - int dir, struct km_event *c) + int dir, int hard) { struct xfrm_user_polexpire *upe; struct nlmsghdr *nlh; - int hard = c->data.hard; unsigned char *b = skb->tail; - nlh = NLMSG_PUT(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe)); + nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe)); upe = NLMSG_DATA(nlh); nlh->nlmsg_flags = 0; @@ -1831,7 +1480,7 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve if (skb == NULL) return -ENOMEM; - if (build_polexpire(skb, xp, dir, c) < 0) + if (build_polexpire(skb, xp, dir, c->data.hard) < 0) BUG(); NETLINK_CB(skb).dst_group = XFRMNLGRP_EXPIRE; @@ -1947,15 +1596,12 @@ static struct xfrm_mgr netlink_mgr = { static int __init xfrm_user_init(void) { - struct sock *nlsk; - printk(KERN_INFO "Initializing IPsec netlink socket\n"); - nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX, - xfrm_netlink_rcv, THIS_MODULE); - if (nlsk == NULL) + xfrm_nl = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX, + xfrm_netlink_rcv, THIS_MODULE); + if (xfrm_nl == NULL) return -ENOMEM; - rcu_assign_pointer(xfrm_nl, nlsk); xfrm_register_km(&netlink_mgr); @@ -1964,16 +1610,11 @@ static int __init xfrm_user_init(void) static void __exit xfrm_user_exit(void) { - struct sock *nlsk = xfrm_nl; - xfrm_unregister_km(&netlink_mgr); - rcu_assign_pointer(xfrm_nl, NULL); - synchronize_rcu(); - sock_release(nlsk->sk_socket); + sock_release(xfrm_nl->sk_socket); } module_init(xfrm_user_init); module_exit(xfrm_user_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_XFRM); - diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index b0d067be7..0168d6c37 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -44,56 +44,15 @@ define filechk fi endef -###### -# gcc support functions -# See documentation in Documentation/kbuild/makefiles.txt - -# as-option -# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,) - -as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \ - -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \ - else echo "$(2)"; fi ;) - -# cc-option -# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) - -cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ - > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) - -# cc-option-yn -# Usage: flag := $(call cc-option-yn, -march=winchip-c6) -cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ - > /dev/null 2>&1; then echo "y"; else echo "n"; fi;) - -# cc-option-align -# Prefix align with either -falign or -malign -cc-option-align = $(subst -functions=0,,\ - $(call cc-option,-falign-functions=0,-malign-functions=0)) - -# cc-version -# Usage gcc-ver := $(call cc-version, $(CC)) -cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \ - $(if $(1), $(1), $(CC))) - -# cc-ifversion -# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) -cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \ - echo $(3); fi;) - ### # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= # Usage: # $(Q)$(MAKE) $(build)=dir build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj -# Prefix -I with $(srctree) if it is not an absolute path -addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1) -# Find all -I options and call addtree -flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) - # If quiet is set, only print short version of command -cmd = @$(echo-cmd) $(cmd_$(1)) +cmd = @$(if $($(quiet)cmd_$(1)),\ + echo ' $(call escsq,$($(quiet)cmd_$(1)))' &&) $(cmd_$(1)) # Add $(obj)/ for paths that is not absolute objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) @@ -116,33 +75,30 @@ endif echo-cmd = $(if $($(quiet)cmd_$(1)), \ echo ' $(call escsq,$($(quiet)cmd_$(1)))';) -make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))) - # function to only execute the passed command if necessary # >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file # note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars -# -if_changed = $(if $(strip $(filter-out $(PHONY),$?) \ - $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ +# +if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ @set -e; \ - $(echo-cmd) $(cmd_$(1)); \ - echo 'cmd_$@ := $(make-cmd)' > $(@D)/.$(@F).cmd) + $(echo-cmd) \ + $(cmd_$(1)); \ + echo 'cmd_$@ := $(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).cmd) # execute the command and also postprocess generated .d dependencies # file -if_changed_dep = $(if $(strip $(filter-out $(PHONY),$?) \ - $(filter-out FORCE $(wildcard $^),$^) \ - $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ +if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\ + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ @set -e; \ - $(echo-cmd) $(cmd_$(1)); \ - scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(@D)/.$(@F).tmp; \ + $(echo-cmd) \ + $(cmd_$(1)); \ + scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \ rm -f $(depfile); \ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) # Usage: $(call if_changed_rule,foo) # will check if $(cmd_foo) changed, or any of the prequisites changed, # and if so will execute $(rule_foo) -if_changed_rule = $(if $(strip $(filter-out $(PHONY),$?) \ - $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ +if_changed_rule = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ @set -e; \ $(rule_$(1))) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e48e60da3..c33e62bde 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -4,18 +4,17 @@ src := $(obj) -PHONY := __build +.PHONY: __build __build: # Read .config if it exist, otherwise ignore -include .config -include scripts/Kbuild.include - # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) +include scripts/Kbuild.include include scripts/Makefile.lib ifdef host-progs @@ -129,7 +128,7 @@ $(multi-objs-y:.o=.s) : modname = $(modname-multi) $(multi-objs-y:.o=.lst) : modname = $(modname-multi) quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ -cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $< +cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< %.s: %.c FORCE $(call if_changed_dep,cc_s_c) @@ -166,7 +165,7 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< cmd_modversions = \ if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ $(CPP) -D__GENKSYMS__ $(c_flags) $< \ - | $(GENKSYMS) -a $(ARCH) \ + | $(GENKSYMS) \ > $(@D)/.tmp_$(@F:.o=.ver); \ \ $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ @@ -178,10 +177,12 @@ cmd_modversions = \ endif define rule_cc_o_c - $(call echo-cmd,checksrc) $(cmd_checksrc) \ - $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ + $(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \ + $(cmd_checksrc) \ + $(if $($(quiet)cmd_cc_o_c),echo ' $(call escsq,$($(quiet)cmd_cc_o_c))';) \ + $(cmd_cc_o_c); \ $(cmd_modversions) \ - scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > $(@D)/.$(@F).tmp; \ + scripts/basic/fixdep $(depfile) $@ '$(call escsq,$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp; \ rm -f $(depfile); \ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd endef @@ -308,14 +309,14 @@ targets += $(multi-used-y) $(multi-used-m) # Descending # --------------------------------------------------------------------------- -PHONY += $(subdir-ym) +.PHONY: $(subdir-ym) $(subdir-ym): $(Q)$(MAKE) $(build)=$@ # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- -PHONY += FORCE +.PHONY: FORCE FORCE: @@ -330,9 +331,3 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) include $(cmd_files) endif - - -# 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. - -.PHONY: $(PHONY) diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index cff33498f..8974ea5fc 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -4,7 +4,7 @@ src := $(obj) -PHONY := __clean +.PHONY: __clean __clean: # Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir @@ -87,16 +87,10 @@ endif # Descending # --------------------------------------------------------------------------- -PHONY += $(subdir-ymn) +.PHONY: $(subdir-ymn) $(subdir-ymn): $(Q)$(MAKE) $(clean)=$@ # If quiet is set, only print short version of command cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1)) - - -# 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. - -.PHONY: $(PHONY) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2cb4935e8..550798f57 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -99,6 +99,11 @@ __a_flags = $(_a_flags) __cpp_flags = $(_cpp_flags) else +# Prefix -I with $(srctree) if it is not an absolute path +addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1) +# Find all -I options and call addtree +flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) + # -I$(obj) locates generated .h files # $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files # and locates generated .h files diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 2686dd5dc..23fd1bdc2 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -2,7 +2,7 @@ # Installing modules # ========================================================================== -PHONY := __modinst +.PHONY: __modinst __modinst: include scripts/Kbuild.include @@ -12,7 +12,7 @@ include scripts/Kbuild.include __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) -PHONY += $(modules) +.PHONY: $(modules) __modinst: $(modules) @: @@ -27,9 +27,3 @@ modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) $(modules): $(call cmd,modules_install,$(MODLIB)/$(modinst_dir)) - - -# 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. - -.PHONY: $(PHONY) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 0e056cfff..bf96a61d4 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -4,7 +4,7 @@ # # Stage one of module building created the following: # a) The individual .o files used for the module -# b) A .o file which is the .o files above linked together +# b) A .o file wich is the .o files above linked together # c) A .mod file in $(MODVERDIR)/, listing the name of the # the preliminary .o file, plus all .o files @@ -32,15 +32,14 @@ # Step 4 is solely used to allow module versioning in external modules, # where the CRC of each module is retrieved from the Module.symers file. -PHONY := _modpost +.PHONY: _modpost _modpost: __modpost include .config include scripts/Kbuild.include include scripts/Makefile.lib -kernelsymfile := $(objtree)/Module.symvers -modulesymfile := $(KBUILD_EXTMOD)/Modules.symvers +symverfile := $(objtree)/Module.symvers # Step 1), find all modules listed in $(MODVERDIR)/ __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) @@ -55,12 +54,10 @@ quiet_cmd_modpost = MODPOST cmd_modpost = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ - $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ - $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ - $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ + $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \ $(filter-out FORCE,$^) -PHONY += __modpost +.PHONY: __modpost __modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE $(call cmd,modpost) @@ -97,7 +94,7 @@ targets += $(modules) # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- -PHONY += FORCE +.PHONY: FORCE FORCE: @@ -112,9 +109,3 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) include $(cmd_files) endif - - -# 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. - -.PHONY: $(PHONY) diff --git a/scripts/Makefile.xen b/scripts/Makefile.xen deleted file mode 100644 index 831f68b79..000000000 --- a/scripts/Makefile.xen +++ /dev/null @@ -1,14 +0,0 @@ - -# cherrypickxen($1 = allobj) -cherrypickxen = $(foreach var, $(1), \ - $(shell o=$(var); \ - c=$${o%.o}-xen.c; \ - s=$${o%.o}-xen.S; \ - oxen=$${o%.o}-xen.o; \ - [ -f $(srctree)/$(src)/$${c} ] || \ - [ -f $(srctree)/$(src)/$${s} ] \ - && echo $$oxen \ - || echo $(var) ) \ - ) -# filterxen($1 = allobj, $2 = noobjs) -filterxen = $(filter-out $(2), $(1)) diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 668a11a8b..679124b11 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -132,10 +132,20 @@ void usage(void) /* * Print out the commandline prefixed with cmd_ := - */ + * If commandline contains '#' escape with '\' so make to not see + * the '#' as a start-of-comment symbol + **/ void print_cmdline(void) { - printf("cmd_%s := %s\n\n", target, cmdline); + char *p = cmdline; + + printf("cmd_%s := ", target); + for (; *p; p++) { + if (*p == '#') + printf("\\"); + printf("%c", *p); + } + printf("\n\n"); } char * str_config = NULL; diff --git a/scripts/checkconfig.pl b/scripts/checkconfig.pl new file mode 100755 index 000000000..ca1f231b1 --- /dev/null +++ b/scripts/checkconfig.pl @@ -0,0 +1,65 @@ +#! /usr/bin/perl +# +# checkconfig: find uses of CONFIG_* names without matching definitions. +# Copyright abandoned, 1998, Michael Elizabeth Chastain . + +use integer; + +$| = 1; + +foreach $file (@ARGV) +{ + # Open this file. + open(FILE, $file) || die "Can't open $file: $!\n"; + + # Initialize variables. + my $fInComment = 0; + my $fInString = 0; + my $fUseConfig = 0; + my $iLinuxConfig = 0; + my %configList = (); + + LINE: while ( ) + { + # Strip comments. + $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); + m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); + + # Pick up definitions. + if ( m/^\s*#/o ) + { + $iLinuxConfig = $. if m/^\s*#\s*include\s*"linux\/config\.h"/o; + $configList{uc $1} = 1 if m/^\s*#\s*include\s*"config\/(\S*)\.h"/o; + } + + # Strip strings. + $fInString && (s+^.*?"+ +o ? ($fInString = 0) : next); + m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1))); + + # Pick up definitions. + if ( m/^\s*#/o ) + { + $iLinuxConfig = $. if m/^\s*#\s*include\s*/o; + $configList{uc $1} = 1 if m/^\s*#\s*include\s*/o; + $configList{$1} = 1 if m/^\s*#\s*define\s+CONFIG_(\w*)/o; + $configList{$1} = 1 if m/^\s*#\s*undef\s+CONFIG_(\w*)/o; + } + + # Look for usages. + next unless m/CONFIG_/o; + WORD: while ( m/\bCONFIG_(\w+)/og ) + { + $fUseConfig = 1; + last LINE if $iLinuxConfig; + next WORD if exists $configList{$1}; + print "$file: $.: need CONFIG_$1.\n"; + $configList{$1} = 0; + } + } + + # Report superfluous includes. + if ( $iLinuxConfig && ! $fUseConfig ) + { print "$file: $iLinuxConfig: linux/config.h not needed.\n"; } + + close(FILE); +} diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index 8187e6f0d..d9f9f34b2 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig @@ -4,7 +4,6 @@ # $arg1 is [b]zImage filename binoffset="./scripts/binoffset" -test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1 IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54" IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44" @@ -21,7 +20,7 @@ function dump_config { let start="$start + 8" let size="$end - $start" - dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat + head --bytes="$end" "$file" | tail --bytes="$size" | zcat clean_up exit 0 @@ -46,7 +45,7 @@ then exit 1 fi -TMPFILE=`mktemp -t ikconfig-XXXXXX` || exit 1 +TMPFILE="/tmp/ikconfig-$$" image="$1" # vmlinux: Attempt to dump the configuration from the file directly diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 331c079f0..6d411169b 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -1,55 +1,22 @@ #!/bin/bash # Copyright (C) Martin Schlemmer -# Copyright (c) 2006 Sam Ravnborg -# # Released under the terms of the GNU GPL # -# Generate a cpio packed initramfs. It uses gen_init_cpio to generate -# the cpio archive, and gzip to pack it. -# The script may also be used to generate the inputfile used for gen_init_cpio -# This script assumes that gen_init_cpio is located in usr/ directory - -# error out on errors -set -e - -usage() { -cat << EOF -Usage: -$0 [-o ] [-u ] [-g ] {-d | } ... - -o Create gzipped initramfs file named using - gen_init_cpio and gzip - -u User ID to map to user ID 0 (root). - is only meaningful if - is a directory. - -g Group ID to map to group ID 0 (root). - is only meaningful if - is a directory. - File list or directory for cpio archive. - If is a .cpio file it will be used - as direct input to initramfs. - -d Output the default cpio list. - -All options except -o and -l may be repeated and are interpreted -sequentially and immediately. -u and -g states are preserved across - options so an explicit "-u 0 -g 0" is required -to reset the root/group mapping. -EOF -} - -list_default_initramfs() { - # echo usr/kinit/kinit - : -} +# Generate a newline separated list of entries from the file/directory +# supplied as an argument. +# +# If a file/directory is not supplied then generate a small dummy file. +# +# The output is suitable for gen_init_cpio built from usr/gen_init_cpio.c. +# default_initramfs() { - cat <<-EOF >> ${output} + cat <<-EOF # This is a very simple, default initramfs dir /dev 0755 0 0 nod /dev/console 0600 0 0 c 5 1 dir /root 0700 0 0 - # file /kinit usr/kinit/kinit 0755 0 0 - # slink /init kinit 0755 0 0 EOF } @@ -75,28 +42,18 @@ filetype() { return 0 } -list_print_mtime() { - : -} - print_mtime() { + local argv1="$1" local my_mtime="0" - if [ -e "$1" ]; then - my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1) + if [ -e "${argv1}" ]; then + my_mtime=$(find "${argv1}" -printf "%T@\n" | sort -r | head -n 1) fi - - echo "# Last modified: ${my_mtime}" >> ${output} - echo "" >> ${output} -} - -list_parse() { - echo "$1 \\" + + echo "# Last modified: ${my_mtime}" + echo } -# for each file print a line in following format -# -# for links, devices etc the format differs. See gen_init_cpio for details parse() { local location="$1" local name="${location/${srcdir}//}" @@ -142,116 +99,80 @@ parse() { ;; esac - echo "${str}" >> ${output} + echo "${str}" return 0 } -unknown_option() { - printf "ERROR: unknown option \"$arg\"\n" >&2 - printf "If the filename validly begins with '-', " >&2 - printf "then it must be prefixed\n" >&2 - printf "by './' so that it won't be interpreted as an option." >&2 - printf "\n" >&2 - usage >&2 - exit 1 -} - -list_header() { - echo "deps_initramfs := \\" -} - -header() { - printf "\n#####################\n# $1\n" >> ${output} -} - -# process one directory (incl sub-directories) -dir_filelist() { - ${dep_list}header "$1" - - srcdir=$(echo "$1" | sed -e 's://*:/:g') - dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null) - - # If $dirlist is only one line, then the directory is empty - if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then - ${dep_list}print_mtime "$1" - - echo "${dirlist}" | \ - while read x; do - ${dep_list}parse ${x} - done - fi +usage() { + printf "Usage:\n" + printf "$0 [ [-u ] [-g ] [-d | ] ] . . .\n" + printf "\n" + printf -- "-u User ID to map to user ID 0 (root).\n" + printf " is only meaningful if \n" + printf " is a directory.\n" + printf -- "-g Group ID to map to group ID 0 (root).\n" + printf " is only meaningful if \n" + printf " is a directory.\n" + printf " File list or directory for cpio archive.\n" + printf " If is not provided then a\n" + printf " a default list will be output.\n" + printf -- "-d Output the default cpio list. If no \n" + printf " is given then the default cpio list will be output.\n" + printf "\n" + printf "All options may be repeated and are interpreted sequentially\n" + printf "and immediately. -u and -g states are preserved across\n" + printf " options so an explicit \"-u 0 -g 0\" is required\n" + printf "to reset the root/group mapping.\n" } -# if only one file is specified and it is .cpio file then use it direct as fs -# if a directory is specified then add all files in given direcotry to fs -# if a regular file is specified assume it is in gen_initramfs format -input_file() { - source="$1" - if [ -f "$1" ]; then - ${dep_list}header "$1" - is_cpio="$(echo "$1" | sed 's/^.*\.cpio/cpio/')" - if [ $2 -eq 0 -a ${is_cpio} == "cpio" ]; then - cpio_file=$1 - [ ! -z ${dep_list} ] && echo "$1" - return 0 - fi - if [ -z ${dep_list} ]; then - print_mtime "$1" >> ${output} - cat "$1" >> ${output} - else - cat "$1" | while read type dir file perm ; do - if [ "$type" == "file" ]; then - echo "$file \\"; - fi +build_list() { + printf "\n#####################\n# $cpio_source\n" + + if [ -f "$cpio_source" ]; then + print_mtime "$cpio_source" + cat "$cpio_source" + elif [ -d "$cpio_source" ]; then + srcdir=$(echo "$cpio_source" | sed -e 's://*:/:g') + dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null) + + # If $dirlist is only one line, then the directory is empty + if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then + print_mtime "$cpio_source" + + echo "${dirlist}" | \ + while read x; do + parse ${x} done + else + # Failsafe in case directory is empty + default_initramfs fi - elif [ -d "$1" ]; then - dir_filelist "$1" else - echo " ${prog}: Cannot open '$1'" >&2 + echo " $0: Cannot open '$cpio_source'" >&2 exit 1 fi } -prog=$0 + root_uid=0 root_gid=0 -dep_list= -cpio_file= -cpio_list= -output="/dev/stdout" -output_file="" -arg="$1" -case "$arg" in - "-l") # files included in initramfs - used by kbuild - dep_list="list_" - shift - ;; - "-o") # generate gzipped cpio image named $1 - shift - output_file="$1" - cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)" - output=${cpio_list} - shift - ;; -esac while [ $# -gt 0 ]; do arg="$1" shift case "$arg" in - "-u") # map $1 to uid=0 (root) + "-u") root_uid="$1" shift ;; - "-g") # map $1 to gid=0 (root) + "-g") root_gid="$1" shift ;; - "-d") # display default initramfs list + "-d") default_list="$arg" - ${dep_list}default_initramfs + default_initramfs ;; "-h") usage @@ -260,27 +181,23 @@ while [ $# -gt 0 ]; do *) case "$arg" in "-"*) - unknown_option + printf "ERROR: unknown option \"$arg\"\n" >&2 + printf "If the filename validly begins with '-', then it must be prefixed\n" >&2 + printf "by './' so that it won't be interpreted as an option." >&2 + printf "\n" >&2 + usage >&2 + exit 1 ;; - *) # input file/dir - process it - input_file "$arg" "$#" + *) + cpio_source="$arg" + build_list ;; esac ;; esac done -# If output_file is set we will generate cpio archive and gzip it -# we are carefull to delete tmp files -if [ ! -z ${output_file} ]; then - if [ -z ${cpio_file} ]; then - cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)" - usr/gen_init_cpio ${cpio_list} > ${cpio_tfile} - else - cpio_tfile=${cpio_file} - fi - rm ${cpio_list} - cat ${cpio_tfile} | gzip -f -9 - > ${output_file} - [ -z ${cpio_file} ] && rm ${cpio_tfile} -fi +# spit out the default cpio list if a source hasn't been specified +[ -z "$cpio_source" -a -z "$default_list" ] && default_initramfs + exit 0 diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 5b0344e20..416a694b0 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -29,421 +29,481 @@ #include #ifdef __GNU_LIBRARY__ #include -#endif /* __GNU_LIBRARY__ */ +#endif /* __GNU_LIBRARY__ */ #include "genksyms.h" + /*----------------------------------------------------------------------*/ #define HASH_BUCKETS 4096 static struct symbol *symtab[HASH_BUCKETS]; -static FILE *debugfile; +FILE *debugfile; int cur_line = 1; -char *cur_filename; +char *cur_filename, *output_directory; -static int flag_debug, flag_dump_defs, flag_warnings; -static const char *arch = ""; -static const char *mod_prefix = ""; +int flag_debug, flag_dump_defs, flag_warnings; static int errors; static int nsyms; static struct symbol *expansion_trail; -static const char *const symbol_type_name[] = { - "normal", "typedef", "enum", "struct", "union" +static const char * const symbol_type_name[] = { + "normal", "typedef", "enum", "struct", "union" }; -static int equal_list(struct string_list *a, struct string_list *b); -static void print_list(FILE * f, struct string_list *list); - /*----------------------------------------------------------------------*/ -static const unsigned int crctab32[] = { - 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, - 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, - 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, - 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, - 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, - 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, - 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, - 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, - 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, - 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, - 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, - 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, - 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, - 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, - 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, - 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, - 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, - 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, - 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, - 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, - 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, - 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, - 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, - 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, - 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, - 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, - 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, - 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, - 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, - 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, - 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, - 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, - 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, - 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, - 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, - 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, - 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, - 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, - 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, - 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, - 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, - 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, - 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, - 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, - 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, - 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, - 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, - 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, - 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, - 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, - 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, - 0x2d02ef8dU +static const unsigned int crctab32[] = +{ + 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, + 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, + 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, + 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, + 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, + 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, + 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, + 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, + 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, + 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, + 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, + 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, + 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, + 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, + 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, + 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, + 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, + 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, + 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, + 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, + 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, + 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, + 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, + 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, + 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, + 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, + 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, + 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, + 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, + 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, + 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, + 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, + 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, + 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, + 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, + 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, + 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, + 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, + 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, + 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, + 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, + 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, + 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, + 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, + 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, + 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, + 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, + 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, + 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, + 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, + 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, + 0x2d02ef8dU }; -static unsigned long partial_crc32_one(unsigned char c, unsigned long crc) +static inline unsigned long +partial_crc32_one(unsigned char c, unsigned long crc) { - return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); + return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); } -static unsigned long partial_crc32(const char *s, unsigned long crc) +static inline unsigned long +partial_crc32(const char *s, unsigned long crc) { - while (*s) - crc = partial_crc32_one(*s++, crc); - return crc; + while (*s) + crc = partial_crc32_one(*s++, crc); + return crc; } -static unsigned long crc32(const char *s) +static inline unsigned long +crc32(const char *s) { - return partial_crc32(s, 0xffffffff) ^ 0xffffffff; + return partial_crc32(s, 0xffffffff) ^ 0xffffffff; } + /*----------------------------------------------------------------------*/ -static enum symbol_type map_to_ns(enum symbol_type t) +static inline enum symbol_type +map_to_ns(enum symbol_type t) { - if (t == SYM_TYPEDEF) - t = SYM_NORMAL; - else if (t == SYM_UNION) - t = SYM_STRUCT; - return t; + if (t == SYM_TYPEDEF) + t = SYM_NORMAL; + else if (t == SYM_UNION) + t = SYM_STRUCT; + return t; } -struct symbol *find_symbol(const char *name, enum symbol_type ns) +struct symbol * +find_symbol(const char *name, enum symbol_type ns) { - unsigned long h = crc32(name) % HASH_BUCKETS; - struct symbol *sym; + unsigned long h = crc32(name) % HASH_BUCKETS; + struct symbol *sym; - for (sym = symtab[h]; sym; sym = sym->hash_next) - if (map_to_ns(sym->type) == map_to_ns(ns) && - strcmp(name, sym->name) == 0) - break; + for (sym = symtab[h]; sym ; sym = sym->hash_next) + if (map_to_ns(sym->type) == map_to_ns(ns) && strcmp(name, sym->name) == 0) + break; - return sym; + return sym; } -struct symbol *add_symbol(const char *name, enum symbol_type type, - struct string_list *defn, int is_extern) +struct symbol * +add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern) { - unsigned long h = crc32(name) % HASH_BUCKETS; - struct symbol *sym; - - for (sym = symtab[h]; sym; sym = sym->hash_next) { - if (map_to_ns(sym->type) == map_to_ns(type) - && strcmp(name, sym->name) == 0) { - if (!equal_list(sym->defn, defn)) - error_with_pos("redefinition of %s", name); - return sym; - } - } - - sym = xmalloc(sizeof(*sym)); - sym->name = name; - sym->type = type; - sym->defn = defn; - sym->expansion_trail = NULL; - sym->is_extern = is_extern; - - sym->hash_next = symtab[h]; - symtab[h] = sym; - - if (flag_debug) { - fprintf(debugfile, "Defn for %s %s == <", - symbol_type_name[type], name); - if (is_extern) - fputs("extern ", debugfile); - print_list(debugfile, defn); - fputs(">\n", debugfile); - } - - ++nsyms; + unsigned long h = crc32(name) % HASH_BUCKETS; + struct symbol *sym; + + for (sym = symtab[h]; sym ; sym = sym->hash_next) + if (map_to_ns(sym->type) == map_to_ns(type) + && strcmp(name, sym->name) == 0) + { + if (!equal_list(sym->defn, defn)) + error_with_pos("redefinition of %s", name); return sym; + } + + sym = xmalloc(sizeof(*sym)); + sym->name = name; + sym->type = type; + sym->defn = defn; + sym->expansion_trail = NULL; + sym->is_extern = is_extern; + + sym->hash_next = symtab[h]; + symtab[h] = sym; + + if (flag_debug) + { + fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type], name); + if (is_extern) + fputs("extern ", debugfile); + print_list(debugfile, defn); + fputs(">\n", debugfile); + } + + ++nsyms; + return sym; } + /*----------------------------------------------------------------------*/ -void free_node(struct string_list *node) +inline void +free_node(struct string_list *node) { - free(node->string); - free(node); + free(node->string); + free(node); } -void free_list(struct string_list *s, struct string_list *e) +void +free_list(struct string_list *s, struct string_list *e) { - while (s != e) { - struct string_list *next = s->next; - free_node(s); - s = next; - } + while (s != e) + { + struct string_list *next = s->next; + free_node(s); + s = next; + } } -struct string_list *copy_node(struct string_list *node) +inline struct string_list * +copy_node(struct string_list *node) { - struct string_list *newnode; + struct string_list *newnode; - newnode = xmalloc(sizeof(*newnode)); - newnode->string = xstrdup(node->string); - newnode->tag = node->tag; + newnode = xmalloc(sizeof(*newnode)); + newnode->string = xstrdup(node->string); + newnode->tag = node->tag; - return newnode; + return newnode; } -static int equal_list(struct string_list *a, struct string_list *b) +struct string_list * +copy_list(struct string_list *s, struct string_list *e) { - while (a && b) { - if (a->tag != b->tag || strcmp(a->string, b->string)) - return 0; - a = a->next; - b = b->next; - } + struct string_list *h, *p; + + if (s == e) + return NULL; + + p = h = copy_node(s); + while ((s = s->next) != e) + p = p->next = copy_node(s); + p->next = NULL; - return !a && !b; + return h; } -static void print_node(FILE * f, struct string_list *list) +int +equal_list(struct string_list *a, struct string_list *b) { - switch (list->tag) { - case SYM_STRUCT: - putc('s', f); - goto printit; - case SYM_UNION: - putc('u', f); - goto printit; - case SYM_ENUM: - putc('e', f); - goto printit; - case SYM_TYPEDEF: - putc('t', f); - goto printit; + while (a && b) + { + if (a->tag != b->tag || strcmp(a->string, b->string)) + return 0; + a = a->next; + b = b->next; + } + + return !a && !b; +} - printit: - putc('#', f); - case SYM_NORMAL: - fputs(list->string, f); - break; - } +static inline void +print_node(FILE *f, struct string_list *list) +{ + switch (list->tag) + { + case SYM_STRUCT: + putc('s', f); + goto printit; + case SYM_UNION: + putc('u', f); + goto printit; + case SYM_ENUM: + putc('e', f); + goto printit; + case SYM_TYPEDEF: + putc('t', f); + goto printit; + + printit: + putc('#', f); + case SYM_NORMAL: + fputs(list->string, f); + break; + } } -static void print_list(FILE * f, struct string_list *list) +void +print_list(FILE *f, struct string_list *list) { - struct string_list **e, **b; - struct string_list *tmp, **tmp2; - int elem = 1; + struct string_list **e, **b; + struct string_list *tmp, **tmp2; + int elem = 1; + + if (list == NULL) + { + fputs("(nil)", f); + return; + } + + tmp = list; + while((tmp = tmp->next) != NULL) + elem++; + + b = alloca(elem * sizeof(*e)); + e = b + elem; + tmp2 = e - 1; + + (*tmp2--) = list; + while((list = list->next) != NULL) + *(tmp2--) = list; + + while (b != e) + { + print_node(f, *b++); + putc(' ', f); + } +} - if (list == NULL) { - fputs("(nil)", f); - return; - } +static unsigned long +expand_and_crc_list(struct string_list *list, unsigned long crc) +{ + struct string_list **e, **b; + struct string_list *tmp, **tmp2; + int elem = 1; - tmp = list; - while ((tmp = tmp->next) != NULL) - elem++; + if (!list) + return crc; - b = alloca(elem * sizeof(*e)); - e = b + elem; - tmp2 = e - 1; + tmp = list; + while((tmp = tmp->next) != NULL) + elem++; - (*tmp2--) = list; - while ((list = list->next) != NULL) - *(tmp2--) = list; + b = alloca(elem * sizeof(*e)); + e = b + elem; + tmp2 = e - 1; - while (b != e) { - print_node(f, *b++); - putc(' ', f); - } -} + *(tmp2--) = list; + while ((list = list->next) != NULL) + *(tmp2--) = list; -static unsigned long expand_and_crc_list(struct string_list *list, - unsigned long crc) -{ - struct string_list **e, **b; - struct string_list *tmp, **tmp2; - int elem = 1; - - if (!list) - return crc; - - tmp = list; - while ((tmp = tmp->next) != NULL) - elem++; - - b = alloca(elem * sizeof(*e)); - e = b + elem; - tmp2 = e - 1; - - *(tmp2--) = list; - while ((list = list->next) != NULL) - *(tmp2--) = list; - - while (b != e) { - struct string_list *cur; - struct symbol *subsym; - - cur = *(b++); - switch (cur->tag) { - case SYM_NORMAL: - if (flag_dump_defs) - fprintf(debugfile, "%s ", cur->string); - crc = partial_crc32(cur->string, crc); - crc = partial_crc32_one(' ', crc); - break; - - case SYM_TYPEDEF: - subsym = find_symbol(cur->string, cur->tag); - if (subsym->expansion_trail) { - if (flag_dump_defs) - fprintf(debugfile, "%s ", cur->string); - crc = partial_crc32(cur->string, crc); - crc = partial_crc32_one(' ', crc); - } else { - subsym->expansion_trail = expansion_trail; - expansion_trail = subsym; - crc = expand_and_crc_list(subsym->defn, crc); - } - break; - - case SYM_STRUCT: - case SYM_UNION: - case SYM_ENUM: - subsym = find_symbol(cur->string, cur->tag); - if (!subsym) { - struct string_list *n, *t = NULL; - - error_with_pos("expand undefined %s %s", - symbol_type_name[cur->tag], - cur->string); - - n = xmalloc(sizeof(*n)); - n->string = xstrdup(symbol_type_name[cur->tag]); - n->tag = SYM_NORMAL; - n->next = t; - t = n; - - n = xmalloc(sizeof(*n)); - n->string = xstrdup(cur->string); - n->tag = SYM_NORMAL; - n->next = t; - t = n; - - n = xmalloc(sizeof(*n)); - n->string = xstrdup("{ UNKNOWN }"); - n->tag = SYM_NORMAL; - n->next = t; - - subsym = - add_symbol(cur->string, cur->tag, n, 0); - } - if (subsym->expansion_trail) { - if (flag_dump_defs) { - fprintf(debugfile, "%s %s ", - symbol_type_name[cur->tag], - cur->string); - } - - crc = partial_crc32(symbol_type_name[cur->tag], - crc); - crc = partial_crc32_one(' ', crc); - crc = partial_crc32(cur->string, crc); - crc = partial_crc32_one(' ', crc); - } else { - subsym->expansion_trail = expansion_trail; - expansion_trail = subsym; - crc = expand_and_crc_list(subsym->defn, crc); - } - break; + while (b != e) + { + struct string_list *cur; + struct symbol *subsym; + + cur = *(b++); + switch (cur->tag) + { + case SYM_NORMAL: + if (flag_dump_defs) + fprintf(debugfile, "%s ", cur->string); + crc = partial_crc32(cur->string, crc); + crc = partial_crc32_one(' ', crc); + break; + + case SYM_TYPEDEF: + subsym = find_symbol(cur->string, cur->tag); + if (subsym->expansion_trail) + { + if (flag_dump_defs) + fprintf(debugfile, "%s ", cur->string); + crc = partial_crc32(cur->string, crc); + crc = partial_crc32_one(' ', crc); + } + else + { + subsym->expansion_trail = expansion_trail; + expansion_trail = subsym; + crc = expand_and_crc_list(subsym->defn, crc); + } + break; + + case SYM_STRUCT: + case SYM_UNION: + case SYM_ENUM: + subsym = find_symbol(cur->string, cur->tag); + if (!subsym) + { + struct string_list *n, *t = NULL; + + error_with_pos("expand undefined %s %s", + symbol_type_name[cur->tag], cur->string); + + n = xmalloc(sizeof(*n)); + n->string = xstrdup(symbol_type_name[cur->tag]); + n->tag = SYM_NORMAL; + n->next = t; + t = n; + + n = xmalloc(sizeof(*n)); + n->string = xstrdup(cur->string); + n->tag = SYM_NORMAL; + n->next = t; + t = n; + + n = xmalloc(sizeof(*n)); + n->string = xstrdup("{ UNKNOWN }"); + n->tag = SYM_NORMAL; + n->next = t; + + subsym = add_symbol(cur->string, cur->tag, n, 0); + } + if (subsym->expansion_trail) + { + if (flag_dump_defs) + { + fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag], + cur->string); } + + crc = partial_crc32(symbol_type_name[cur->tag], crc); + crc = partial_crc32_one(' ', crc); + crc = partial_crc32(cur->string, crc); + crc = partial_crc32_one(' ', crc); + } + else + { + subsym->expansion_trail = expansion_trail; + expansion_trail = subsym; + crc = expand_and_crc_list(subsym->defn, crc); + } + break; } + } - return crc; + return crc; } -void export_symbol(const char *name) +void +export_symbol(const char *name) { - struct symbol *sym; + struct symbol *sym; - sym = find_symbol(name, SYM_NORMAL); - if (!sym) - error_with_pos("export undefined symbol %s", name); - else { - unsigned long crc; + sym = find_symbol(name, SYM_NORMAL); + if (!sym) + error_with_pos("export undefined symbol %s", name); + else + { + unsigned long crc; - if (flag_dump_defs) - fprintf(debugfile, "Export %s == <", name); + if (flag_dump_defs) + fprintf(debugfile, "Export %s == <", name); - expansion_trail = (struct symbol *)-1L; + expansion_trail = (struct symbol *)-1L; - crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; + crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; - sym = expansion_trail; - while (sym != (struct symbol *)-1L) { - struct symbol *n = sym->expansion_trail; - sym->expansion_trail = 0; - sym = n; - } + sym = expansion_trail; + while (sym != (struct symbol *)-1L) + { + struct symbol *n = sym->expansion_trail; + sym->expansion_trail = 0; + sym = n; + } - if (flag_dump_defs) - fputs(">\n", debugfile); + if (flag_dump_defs) + fputs(">\n", debugfile); - /* Used as a linker script. */ - printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); - } + /* Used as a linker script. */ + printf("__crc_%s = 0x%08lx ;\n", name, crc); + } } /*----------------------------------------------------------------------*/ -void error_with_pos(const char *fmt, ...) + +void +error(const char *fmt, ...) +{ + va_list args; + + if (flag_warnings) + { + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + putc('\n', stderr); + + errors++; + } +} + +void +error_with_pos(const char *fmt, ...) { - va_list args; + va_list args; - if (flag_warnings) { - fprintf(stderr, "%s:%d: ", cur_filename ? : "", - cur_line); + if (flag_warnings) + { + fprintf(stderr, "%s:%d: ", cur_filename ? : "", cur_line); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - putc('\n', stderr); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + putc('\n', stderr); - errors++; - } + errors++; + } } -static void genksyms_usage(void) + +void genksyms_usage(void) { - fputs("Usage:\n" "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" "\n" + fputs("Usage:\n" + "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" + "\n" #ifdef __GNU_LIBRARY__ " -d, --debug Increment the debug level (repeatable)\n" " -D, --dump Dump expanded symbol defs (for debugging only)\n" @@ -451,84 +511,81 @@ static void genksyms_usage(void) " -q, --quiet Disable warnings (default)\n" " -h, --help Print this message\n" " -V, --version Print the release version\n" -#else /* __GNU_LIBRARY__ */ - " -d Increment the debug level (repeatable)\n" - " -D Dump expanded symbol defs (for debugging only)\n" - " -w Enable warnings\n" - " -q Disable warnings (default)\n" - " -h Print this message\n" - " -V Print the release version\n" -#endif /* __GNU_LIBRARY__ */ +#else /* __GNU_LIBRARY__ */ + " -d Increment the debug level (repeatable)\n" + " -D Dump expanded symbol defs (for debugging only)\n" + " -w Enable warnings\n" + " -q Disable warnings (default)\n" + " -h Print this message\n" + " -V Print the release version\n" +#endif /* __GNU_LIBRARY__ */ , stderr); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { - int o; + int o; #ifdef __GNU_LIBRARY__ - struct option long_opts[] = { - {"arch", 1, 0, 'a'}, - {"debug", 0, 0, 'd'}, - {"warnings", 0, 0, 'w'}, - {"quiet", 0, 0, 'q'}, - {"dump", 0, 0, 'D'}, - {"version", 0, 0, 'V'}, - {"help", 0, 0, 'h'}, - {0, 0, 0, 0} - }; - - while ((o = getopt_long(argc, argv, "a:dwqVDk:p:", - &long_opts[0], NULL)) != EOF) -#else /* __GNU_LIBRARY__ */ - while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF) -#endif /* __GNU_LIBRARY__ */ - switch (o) { - case 'a': - arch = optarg; - break; - case 'd': - flag_debug++; - break; - case 'w': - flag_warnings = 1; - break; - case 'q': - flag_warnings = 0; - break; - case 'V': - fputs("genksyms version 2.5.60\n", stderr); - break; - case 'D': - flag_dump_defs = 1; - break; - case 'h': - genksyms_usage(); - return 0; - default: - genksyms_usage(); - return 1; - } - if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0)) - mod_prefix = "_"; - { - extern int yydebug; - extern int yy_flex_debug; - - yydebug = (flag_debug > 1); - yy_flex_debug = (flag_debug > 2); - - debugfile = stderr; - /* setlinebuf(debugfile); */ - } - - yyparse(); - - if (flag_debug) { - fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", - nsyms, HASH_BUCKETS, - (double)nsyms / (double)HASH_BUCKETS); - } - - return errors != 0; + struct option long_opts[] = { + {"debug", 0, 0, 'd'}, + {"warnings", 0, 0, 'w'}, + {"quiet", 0, 0, 'q'}, + {"dump", 0, 0, 'D'}, + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + + while ((o = getopt_long(argc, argv, "dwqVDk:p:", + &long_opts[0], NULL)) != EOF) +#else /* __GNU_LIBRARY__ */ + while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF) +#endif /* __GNU_LIBRARY__ */ + switch (o) + { + case 'd': + flag_debug++; + break; + case 'w': + flag_warnings = 1; + break; + case 'q': + flag_warnings = 0; + break; + case 'V': + fputs("genksyms version 2.5.60\n", stderr); + break; + case 'D': + flag_dump_defs = 1; + break; + case 'h': + genksyms_usage(); + return 0; + default: + genksyms_usage(); + return 1; + } + + { + extern int yydebug; + extern int yy_flex_debug; + + yydebug = (flag_debug > 1); + yy_flex_debug = (flag_debug > 2); + + debugfile = stderr; + /* setlinebuf(debugfile); */ + } + + yyparse(); + + if (flag_debug) + { + fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", + nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS); + } + + return errors != 0; } diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h index ab6f34f38..f09af47ab 100644 --- a/scripts/genksyms/genksyms.h +++ b/scripts/genksyms/genksyms.h @@ -20,51 +20,74 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #ifndef MODUTILS_GENKSYMS_H #define MODUTILS_GENKSYMS_H 1 #include -enum symbol_type { - SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION + +enum symbol_type +{ + SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION }; -struct string_list { - struct string_list *next; - enum symbol_type tag; - char *string; +struct string_list +{ + struct string_list *next; + enum symbol_type tag; + char *string; }; -struct symbol { - struct symbol *hash_next; - const char *name; - enum symbol_type type; - struct string_list *defn; - struct symbol *expansion_trail; - int is_extern; +struct symbol +{ + struct symbol *hash_next; + const char *name; + enum symbol_type type; + struct string_list *defn; + struct symbol *expansion_trail; + int is_extern; }; typedef struct string_list **yystype; #define YYSTYPE yystype +extern FILE *outfile, *debugfile; + extern int cur_line; -extern char *cur_filename; +extern char *cur_filename, *output_directory; + +extern int flag_debug, flag_dump_defs, flag_warnings; +extern int checksum_version, kernel_version; + +extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents; +extern struct string_list *current_list, *next_list; + struct symbol *find_symbol(const char *name, enum symbol_type ns); struct symbol *add_symbol(const char *name, enum symbol_type type, - struct string_list *defn, int is_extern); + struct string_list *defn, int is_extern); void export_symbol(const char *); -void free_node(struct string_list *list); +struct string_list *reset_list(void); void free_list(struct string_list *s, struct string_list *e); +void free_node(struct string_list *list); struct string_list *copy_node(struct string_list *); +struct string_list *copy_list(struct string_list *s, struct string_list *e); +int equal_list(struct string_list *a, struct string_list *b); +void print_list(FILE *, struct string_list *list); int yylex(void); int yyparse(void); void error_with_pos(const char *, ...); +#define version(a,b,c) ((a << 16) | (b << 8) | (c)) + /*----------------------------------------------------------------------*/ + +#define MODUTILS_VERSION "" + #define xmalloc(size) ({ void *__ptr = malloc(size); \ if(!__ptr && size != 0) { \ fprintf(stderr, "out of memory\n"); \ @@ -78,4 +101,4 @@ void error_with_pos(const char *, ...); } \ __str; }) -#endif /* genksyms.h */ +#endif /* genksyms.h */ diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped index d8153f572..ee4647805 100644 --- a/scripts/genksyms/keywords.c_shipped +++ b/scripts/genksyms/keywords.c_shipped @@ -52,9 +52,9 @@ is_reserved_hash (register const char *str, register unsigned int len) 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 0, - 71, 71, 71, 71, 71, 71, 35, 71, 71, 71, - 5, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 15, + 71, 71, 71, 71, 71, 71, 15, 71, 71, 71, + 10, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 0, 71, 0, 71, 5, 5, 0, 10, 20, 71, 25, 71, 71, 20, 0, 20, 30, 25, 71, 10, 5, 0, 20, 15, 71, @@ -84,9 +84,9 @@ is_reserved_word (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 42, + TOTAL_KEYWORDS = 41, MIN_WORD_LENGTH = 3, - MAX_WORD_LENGTH = 24, + MAX_WORD_LENGTH = 17, MIN_HASH_VALUE = 3, MAX_HASH_VALUE = 70 }; @@ -94,105 +94,104 @@ is_reserved_word (register const char *str, register unsigned int len) static const struct resword wordlist[] = { {""}, {""}, {""}, -#line 25 "scripts/genksyms/keywords.gperf" +#line 24 "scripts/genksyms/keywords.gperf" {"asm", ASM_KEYW}, {""}, -#line 8 "scripts/genksyms/keywords.gperf" +#line 7 "scripts/genksyms/keywords.gperf" {"__asm", ASM_KEYW}, {""}, -#line 9 "scripts/genksyms/keywords.gperf" +#line 8 "scripts/genksyms/keywords.gperf" {"__asm__", ASM_KEYW}, {""}, -#line 22 "scripts/genksyms/keywords.gperf" +#line 21 "scripts/genksyms/keywords.gperf" {"_restrict", RESTRICT_KEYW}, -#line 51 "scripts/genksyms/keywords.gperf" +#line 50 "scripts/genksyms/keywords.gperf" {"__typeof__", TYPEOF_KEYW}, -#line 10 "scripts/genksyms/keywords.gperf" +#line 9 "scripts/genksyms/keywords.gperf" {"__attribute", ATTRIBUTE_KEYW}, -#line 12 "scripts/genksyms/keywords.gperf" - {"__const", CONST_KEYW}, #line 11 "scripts/genksyms/keywords.gperf" + {"__const", CONST_KEYW}, +#line 10 "scripts/genksyms/keywords.gperf" {"__attribute__", ATTRIBUTE_KEYW}, -#line 13 "scripts/genksyms/keywords.gperf" +#line 12 "scripts/genksyms/keywords.gperf" {"__const__", CONST_KEYW}, -#line 17 "scripts/genksyms/keywords.gperf" +#line 16 "scripts/genksyms/keywords.gperf" {"__signed__", SIGNED_KEYW}, -#line 43 "scripts/genksyms/keywords.gperf" +#line 42 "scripts/genksyms/keywords.gperf" {"static", STATIC_KEYW}, {""}, -#line 16 "scripts/genksyms/keywords.gperf" +#line 15 "scripts/genksyms/keywords.gperf" {"__signed", SIGNED_KEYW}, -#line 31 "scripts/genksyms/keywords.gperf" +#line 30 "scripts/genksyms/keywords.gperf" {"char", CHAR_KEYW}, {""}, -#line 44 "scripts/genksyms/keywords.gperf" +#line 43 "scripts/genksyms/keywords.gperf" {"struct", STRUCT_KEYW}, -#line 23 "scripts/genksyms/keywords.gperf" +#line 22 "scripts/genksyms/keywords.gperf" {"__restrict__", RESTRICT_KEYW}, -#line 24 "scripts/genksyms/keywords.gperf" +#line 23 "scripts/genksyms/keywords.gperf" {"restrict", RESTRICT_KEYW}, -#line 34 "scripts/genksyms/keywords.gperf" +#line 33 "scripts/genksyms/keywords.gperf" {"enum", ENUM_KEYW}, -#line 18 "scripts/genksyms/keywords.gperf" +#line 17 "scripts/genksyms/keywords.gperf" {"__volatile", VOLATILE_KEYW}, -#line 35 "scripts/genksyms/keywords.gperf" +#line 34 "scripts/genksyms/keywords.gperf" {"extern", EXTERN_KEYW}, -#line 19 "scripts/genksyms/keywords.gperf" +#line 18 "scripts/genksyms/keywords.gperf" {"__volatile__", VOLATILE_KEYW}, -#line 38 "scripts/genksyms/keywords.gperf" +#line 37 "scripts/genksyms/keywords.gperf" {"int", INT_KEYW}, -#line 7 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, -#line 32 "scripts/genksyms/keywords.gperf" + {""}, +#line 31 "scripts/genksyms/keywords.gperf" {"const", CONST_KEYW}, -#line 33 "scripts/genksyms/keywords.gperf" +#line 32 "scripts/genksyms/keywords.gperf" {"double", DOUBLE_KEYW}, {""}, -#line 14 "scripts/genksyms/keywords.gperf" +#line 13 "scripts/genksyms/keywords.gperf" {"__inline", INLINE_KEYW}, -#line 30 "scripts/genksyms/keywords.gperf" +#line 29 "scripts/genksyms/keywords.gperf" {"auto", AUTO_KEYW}, -#line 15 "scripts/genksyms/keywords.gperf" +#line 14 "scripts/genksyms/keywords.gperf" {"__inline__", INLINE_KEYW}, -#line 42 "scripts/genksyms/keywords.gperf" +#line 41 "scripts/genksyms/keywords.gperf" {"signed", SIGNED_KEYW}, {""}, -#line 47 "scripts/genksyms/keywords.gperf" +#line 46 "scripts/genksyms/keywords.gperf" {"unsigned", UNSIGNED_KEYW}, {""}, -#line 41 "scripts/genksyms/keywords.gperf" +#line 40 "scripts/genksyms/keywords.gperf" {"short", SHORT_KEYW}, -#line 50 "scripts/genksyms/keywords.gperf" +#line 49 "scripts/genksyms/keywords.gperf" {"typeof", TYPEOF_KEYW}, -#line 45 "scripts/genksyms/keywords.gperf" +#line 44 "scripts/genksyms/keywords.gperf" {"typedef", TYPEDEF_KEYW}, -#line 49 "scripts/genksyms/keywords.gperf" +#line 48 "scripts/genksyms/keywords.gperf" {"volatile", VOLATILE_KEYW}, {""}, -#line 36 "scripts/genksyms/keywords.gperf" +#line 35 "scripts/genksyms/keywords.gperf" {"float", FLOAT_KEYW}, {""}, {""}, -#line 40 "scripts/genksyms/keywords.gperf" +#line 39 "scripts/genksyms/keywords.gperf" {"register", REGISTER_KEYW}, -#line 48 "scripts/genksyms/keywords.gperf" +#line 47 "scripts/genksyms/keywords.gperf" {"void", VOID_KEYW}, {""}, -#line 37 "scripts/genksyms/keywords.gperf" +#line 36 "scripts/genksyms/keywords.gperf" {"inline", INLINE_KEYW}, {""}, #line 5 "scripts/genksyms/keywords.gperf" {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, {""}, -#line 21 "scripts/genksyms/keywords.gperf" +#line 20 "scripts/genksyms/keywords.gperf" {"_Bool", BOOL_KEYW}, {""}, #line 6 "scripts/genksyms/keywords.gperf" {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 39 "scripts/genksyms/keywords.gperf" +#line 38 "scripts/genksyms/keywords.gperf" {"long", LONG_KEYW}, {""}, {""}, {""}, {""}, {""}, -#line 46 "scripts/genksyms/keywords.gperf" +#line 45 "scripts/genksyms/keywords.gperf" {"union", UNION_KEYW} }; diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf index c75e0c8d8..b6bec7659 100644 --- a/scripts/genksyms/keywords.gperf +++ b/scripts/genksyms/keywords.gperf @@ -4,7 +4,6 @@ struct resword { const char *name; int token; } %% EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW -EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW __asm, ASM_KEYW __asm__, ASM_KEYW __attribute, ATTRIBUTE_KEYW diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 22d281c6e..d591578bd 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -124,11 +124,6 @@ static int read_symbol(FILE *in, struct sym_entry *s) * compressed together */ s->len = strlen(str) + 1; s->sym = malloc(s->len + 1); - if (!s->sym) { - fprintf(stderr, "kallsyms failure: " - "unable to allocate required amount of memory\n"); - exit(EXIT_FAILURE); - } strcpy((char *)s->sym + 1, str); s->sym[0] = stype; @@ -277,12 +272,7 @@ static void write_src(void) /* table of offset markers, that give the offset in the compressed stream * every 256 symbols */ - markers = malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256)); - if (!markers) { - fprintf(stderr, "kallsyms failure: " - "unable to allocate required memory\n"); - exit(EXIT_FAILURE); - } + markers = (unsigned int *) malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256)); output_label("kallsyms_names"); off = 0; diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 56fa8fef2..5760e057e 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -2,7 +2,7 @@ # Kernel configuration targets # These targets are used from top-level makefile -PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config +.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config xconfig: $(obj)/qconf $< arch/$(ARCH)/Kconfig @@ -23,9 +23,6 @@ oldconfig: $(obj)/conf silentoldconfig: $(obj)/conf $< -s arch/$(ARCH)/Kconfig -nonint_oldconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -b arch/$(ARCH)/Kconfig - update-po-config: $(obj)/kxgettext xgettext --default-domain=linux \ --add-comments --keyword=_ --keyword=N_ \ @@ -45,7 +42,7 @@ update-po-config: $(obj)/kxgettext $(Q)rm -f arch/um/Kconfig_arch $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot -PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig +.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig randconfig: $(obj)/conf $< -r arch/$(ARCH)/Kconfig @@ -81,7 +78,7 @@ help: @echo ' defconfig - New config with default answer to all options' @echo ' allmodconfig - New config selecting modules when possible' @echo ' allyesconfig - New config where all options are accepted with yes' - @echo ' allnoconfig - New config where all options are answered with no' + @echo ' allnoconfig - New minimal config' # =========================================================================== # Shared Makefile for the various kconfig executables: diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 52159cfca..10eeae53d 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -21,7 +20,6 @@ enum { ask_all, ask_new, ask_silent, - dont_ask, set_default, set_yes, set_mod, @@ -38,8 +36,6 @@ static struct menu *rootEntry; static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); -static int return_value = 0; - static void strip(char *str) { char *p = str; @@ -67,6 +63,20 @@ static void check_stdin(void) } } +static char *fgets_check_stream(char *s, int size, FILE *stream) +{ + char *ret = fgets(s, size, stream); + + if (ret == NULL && feof(stream)) { + printf(_("aborted!\n\n")); + printf(_("Console input is closed. ")); + printf(_("Run 'make oldconfig' to update configuration.\n\n")); + exit(1); + } + + return ret; +} + static void conf_askvalue(struct symbol *sym, const char *def) { enum symbol_type type = sym_get_type(sym); @@ -104,13 +114,7 @@ static void conf_askvalue(struct symbol *sym, const char *def) check_stdin(); case ask_all: fflush(stdout); - fgets(line, 128, stdin); - return; - case dont_ask: - if (!sym_has_value(sym)) { - fprintf(stderr,"CONFIG_%s\n",sym->name); - return_value++; - } + fgets_check_stream(line, 128, stdin); return; case set_default: printf("%s\n", def); @@ -324,7 +328,8 @@ static int conf_choice(struct menu *menu) printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); def_sym = sym_get_choice_value(sym); cnt = def = 0; - line[0] = 0; + line[0] = '0'; + line[1] = 0; for (child = menu->list; child; child = child->next) { if (!menu_is_visible(child)) continue; @@ -355,10 +360,6 @@ static int conf_choice(struct menu *menu) printf("?"); printf("]: "); switch (input_mode) { - case dont_ask: - cnt = def; - printf("%d\n", cnt); - break; case ask_new: case ask_silent: if (!is_new) { @@ -369,7 +370,7 @@ static int conf_choice(struct menu *menu) check_stdin(); case ask_all: fflush(stdout); - fgets(line, 128, stdin); + fgets_check_stream(line, 128, stdin); strip(line); if (line[0] == '?') { printf("\n%s\n", menu->sym->help ? @@ -495,10 +496,7 @@ static void check_conf(struct menu *menu) if (!conf_cnt++) printf(_("*\n* Restart config...\n*\n")); rootEntry = menu_get_parent_menu(menu); - if (input_mode == dont_ask) - fprintf(stderr,"CONFIG_%s\n",sym->name); - else - conf(rootEntry); + conf(rootEntry); } } @@ -517,9 +515,6 @@ int main(int ac, char **av) case 'o': input_mode = ask_new; break; - case 'b': - input_mode = dont_ask; - break; case 's': input_mode = ask_silent; valid_stdin = isatty(0) && isatty(1) && isatty(2); @@ -551,7 +546,7 @@ int main(int ac, char **av) break; case 'h': case '?': - fprintf(stderr, "See README for usage info\n"); + printf("%s [-o|-s] config\n", av[0]); exit(0); } } @@ -584,7 +579,6 @@ int main(int ac, char **av) } case ask_all: case ask_new: - case dont_ask: conf_read(NULL); break; case set_no: @@ -623,10 +617,10 @@ int main(int ac, char **av) do { conf_cnt = 0; check_conf(&rootmenu); - } while ((conf_cnt) && (input_mode != dont_ask)); + } while (conf_cnt); if (conf_write(NULL)) { fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); return 1; } - return return_value; + return 0; } diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c1702d82b..b0cbbe2e4 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -153,6 +153,7 @@ int conf_read_simple(const char *name) break; } else if (!(sym->flags & SYMBOL_NEW)) { conf_warning("trying to reassign symbol %s", sym->name); + break; } switch (sym->type) { case S_BOOLEAN: @@ -182,6 +183,7 @@ int conf_read_simple(const char *name) break; } else if (!(sym->flags & SYMBOL_NEW)) { conf_warning("trying to reassign symbol %s", sym->name); + break; } switch (sym->type) { case S_TRISTATE: @@ -254,7 +256,7 @@ int conf_read_simple(const char *name) cs->flags |= SYMBOL_NEW; } else cs->user.val = sym; - //break; + break; } cs->user.tri = E_OR(cs->user.tri, sym->user.tri); } @@ -323,7 +325,7 @@ int conf_read(const char *name) sym->flags |= e->right.sym->flags & SYMBOL_NEW; } - sym_change_count = conf_warnings || conf_unsaved; + sym_change_count = conf_warnings && conf_unsaved; return 0; } @@ -372,7 +374,6 @@ int conf_write(const char *name) out_h = fopen(".tmpconfig.h", "w"); if (!out_h) return 1; - file_write_dep(NULL); } sym = sym_lookup("KERNELVERSION", 0); sym_calc_value(sym); @@ -511,6 +512,7 @@ int conf_write(const char *name) if (out_h) { fclose(out_h); rename(".tmpconfig.h", "include/linux/autoconf.h"); + file_write_dep(NULL); } if (!name || basename != conf_def_filename) { if (!name) diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile index a8b026326..bbf4887cf 100644 --- a/scripts/kconfig/lxdialog/Makefile +++ b/scripts/kconfig/lxdialog/Makefile @@ -7,10 +7,10 @@ check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh # we really need to do so. (Do not call gcc as part of make mrproper) HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) + +HOST_EXTRACFLAGS += -DLOCALE -HOST_EXTRACFLAGS += -DLOCALE - -PHONY += dochecklxdialog +.PHONY: dochecklxdialog $(obj)/dochecklxdialog: $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index be0200e9c..db07ae73e 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -196,8 +196,8 @@ int dialog_checklist(const char *title, const char *prompt, int height, print_buttons(dialog, height, width, 0); - wnoutrefresh(dialog); wnoutrefresh(list); + wnoutrefresh(dialog); doupdate(); while (key != ESC) { @@ -225,11 +225,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, } scroll--; print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE); + wnoutrefresh(list); + print_arrows(dialog, choice, item_no, scroll, box_y, box_x + check_x + 5, list_height); - wnoutrefresh(dialog); - wrefresh(list); + wrefresh(dialog); continue; /* wait for another key press */ } else @@ -251,12 +252,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, scroll++; print_item(list, items[(scroll + max_choice - 1) * 3 + 1], status[scroll + max_choice - 1], max_choice - 1, TRUE); + wnoutrefresh(list); print_arrows(dialog, choice, item_no, scroll, box_y, box_x + check_x + 5, list_height); - wnoutrefresh(dialog); - wrefresh(list); + wrefresh(dialog); continue; /* wait for another key press */ } else @@ -270,8 +271,8 @@ int dialog_checklist(const char *title, const char *prompt, int height, choice = i; print_item(list, items[(scroll + choice) * 3 + 1], status[scroll + choice], choice, TRUE); - wnoutrefresh(dialog); - wrefresh(list); + wnoutrefresh(list); + wrefresh(dialog); } continue; /* wait for another key press */ } @@ -305,8 +306,8 @@ int dialog_checklist(const char *title, const char *prompt, int height, print_item(list, items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice); } - wnoutrefresh(dialog); - wrefresh(list); + wnoutrefresh(list); + wrefresh(dialog); for (i = 0; i < item_no; i++) if (status[i]) diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index bf8052f4f..09512b544 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -58,7 +58,8 @@ #include "dialog.h" -static int menu_width, item_x; +#define ITEM_IDENT 1 /* Indent of menu entries. Fixed for all menus */ +static int menu_width; /* * Print menu item @@ -69,7 +70,7 @@ static void do_print_item(WINDOW * win, const char *item, int choice, int j; char *menu_item = malloc(menu_width + 1); - strncpy(menu_item, item, menu_width - item_x); + strncpy(menu_item, item, menu_width - ITEM_IDENT); menu_item[menu_width] = 0; j = first_alpha(menu_item, "YyNnMmHh"); @@ -86,13 +87,13 @@ static void do_print_item(WINDOW * win, const char *item, int choice, wclrtoeol(win); #endif wattrset(win, selected ? item_selected_attr : item_attr); - mvwaddstr(win, choice, item_x, menu_item); + mvwaddstr(win, choice, ITEM_IDENT, menu_item); if (hotkey) { wattrset(win, selected ? tag_key_selected_attr : tag_key_attr); - mvwaddch(win, choice, item_x + j, menu_item[j]); + mvwaddch(win, choice, ITEM_IDENT + j, menu_item[j]); } if (selected) { - wmove(win, choice, item_x + 1); + wmove(win, choice, ITEM_IDENT + 1); } free(menu_item); wrefresh(win); @@ -226,8 +227,6 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, menubox_border_attr, menubox_attr); - item_x = (menu_width - 70) / 2; - /* Set choice to default item */ for (i = 0; i < item_no; i++) if (strcmp(current, items[i * 2]) == 0) @@ -264,10 +263,10 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, wnoutrefresh(menu); print_arrows(dialog, item_no, scroll, - box_y, box_x + item_x + 1, menu_height); + box_y, box_x + ITEM_IDENT + 1, menu_height); print_buttons(dialog, height, width, 0); - wmove(menu, choice, item_x + 1); + wmove(menu, choice, ITEM_IDENT + 1); wrefresh(menu); while (key != ESC) { @@ -350,7 +349,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, print_item(scroll + choice, choice, TRUE); print_arrows(dialog, item_no, scroll, - box_y, box_x + item_x + 1, menu_height); + box_y, box_x + ITEM_IDENT + 1, menu_height); wnoutrefresh(dialog); wrefresh(menu); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 37f67c23e..c164b230a 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -34,7 +34,7 @@ typedef uint16_t __u16; typedef unsigned char __u8; /* Big exception to the "don't include kernel headers into userspace, which - * even potentially has different endianness and word sizes, since + * even potentially has different endianness and word sizes, since * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" #include "../../include/linux/input.h" @@ -153,8 +153,8 @@ static void do_usb_table(void *symval, unsigned long size, const unsigned long id_size = sizeof(struct usb_device_id); if (size % id_size || size < id_size) { - warn("%s ids %lu bad size " - "(each on %lu)\n", mod->name, size, id_size); + fprintf(stderr, "*** Warning: %s ids %lu bad size " + "(each on %lu)\n", mod->name, size, id_size); } /* Leave last one: it's the terminator. */ size -= id_size; @@ -217,8 +217,9 @@ static int do_pci_entry(const char *filename, if ((baseclass_mask != 0 && baseclass_mask != 0xFF) || (subclass_mask != 0 && subclass_mask != 0xFF) || (interface_mask != 0 && interface_mask != 0xFF)) { - warn("Can't handle masks in %s:%04X\n", - filename, id->class_mask); + fprintf(stderr, + "*** Warning: Can't handle masks in %s:%04X\n", + filename, id->class_mask); return 0; } @@ -228,7 +229,7 @@ static int do_pci_entry(const char *filename, return 1; } -/* looks like: "ccw:tNmNdtNdmN" */ +/* looks like: "ccw:tNmNdtNdmN" */ static int do_ccw_entry(const char *filename, struct ccw_device_id *id, char *alias) { @@ -374,10 +375,10 @@ static void do_input(char *alias, kernel_ulong_t *arr, unsigned int min, unsigned int max) { unsigned int i; - - for (i = min; i < max; i++) - if (arr[i / BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) - sprintf(alias + strlen(alias), "%X,*", i); + for (i = min; i < max; i++) { + if (arr[i/BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) + sprintf(alias+strlen(alias), "%X,*", i); + } } /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ @@ -386,37 +387,39 @@ static int do_input_entry(const char *filename, struct input_device_id *id, { sprintf(alias, "input:"); - ADD(alias, "b", id->flags & INPUT_DEVICE_ID_MATCH_BUS, id->bustype); - ADD(alias, "v", id->flags & INPUT_DEVICE_ID_MATCH_VENDOR, id->vendor); - ADD(alias, "p", id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT, id->product); - ADD(alias, "e", id->flags & INPUT_DEVICE_ID_MATCH_VERSION, id->version); + ADD(alias, "b", id->flags&INPUT_DEVICE_ID_MATCH_BUS, id->id.bustype); + ADD(alias, "v", id->flags&INPUT_DEVICE_ID_MATCH_VENDOR, id->id.vendor); + ADD(alias, "p", id->flags&INPUT_DEVICE_ID_MATCH_PRODUCT, + id->id.product); + ADD(alias, "e", id->flags&INPUT_DEVICE_ID_MATCH_VERSION, + id->id.version); sprintf(alias + strlen(alias), "-e*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_EVBIT) do_input(alias, id->evbit, 0, EV_MAX); sprintf(alias + strlen(alias), "k*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_KEYBIT) do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX); sprintf(alias + strlen(alias), "r*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_RELBIT) do_input(alias, id->relbit, 0, REL_MAX); sprintf(alias + strlen(alias), "a*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_ABSBIT) do_input(alias, id->absbit, 0, ABS_MAX); sprintf(alias + strlen(alias), "m*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_MSCIT) do_input(alias, id->mscbit, 0, MSC_MAX); sprintf(alias + strlen(alias), "l*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_LEDBIT) do_input(alias, id->ledbit, 0, LED_MAX); sprintf(alias + strlen(alias), "s*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_SNDBIT) do_input(alias, id->sndbit, 0, SND_MAX); sprintf(alias + strlen(alias), "f*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_FFBIT) do_input(alias, id->ffbit, 0, FF_MAX); sprintf(alias + strlen(alias), "w*"); - if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT) + if (id->flags&INPUT_DEVICE_ID_MATCH_SWBIT) do_input(alias, id->swbit, 0, SW_MAX); return 1; } @@ -442,8 +445,8 @@ static void do_table(void *symval, unsigned long size, int (*do_entry)(const char *, void *entry, char *alias) = function; if (size % id_size || size < id_size) { - warn("%s ids %lu bad size " - "(each on %lu)\n", mod->name, size, id_size); + fprintf(stderr, "*** Warning: %s ids %lu bad size " + "(each on %lu)\n", mod->name, size, id_size); } /* Leave last one: it's the terminator. */ size -= id_size; diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index 3c92c8373..de2aabf89 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -6,7 +6,7 @@ int main(int argc, char **argv) { - unsigned char ei[EI_NIDENT]; + unsigned char ei[EI_NIDENT]; union { short s; char c[2]; } endian_test; if (argc != 2) { @@ -57,7 +57,7 @@ main(int argc, char **argv) if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); - else + else printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); return 0; diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d0f86ed43..b8b2a560b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2,7 +2,7 @@ * * Copyright 2003 Kai Germaschewski * Copyright 2002-2004 Rusty Russell, IBM Corporation - * Copyright 2006 Sam Ravnborg + * * Based in part on module-init-tools/depmod.c,file2alias * * This software may be used and distributed according to the terms @@ -20,10 +20,9 @@ int modversions = 0; int have_vmlinux = 0; /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ static int all_versions = 0; -/* If we are modposting external module set to 1 */ -static int external_module = 0; -void fatal(const char *fmt, ...) +void +fatal(const char *fmt, ...) { va_list arglist; @@ -36,7 +35,8 @@ void fatal(const char *fmt, ...) exit(1); } -void warn(const char *fmt, ...) +void +warn(const char *fmt, ...) { va_list arglist; @@ -47,18 +47,6 @@ void warn(const char *fmt, ...) va_end(arglist); } -static int is_vmlinux(const char *modname) -{ - const char *myname; - - if ((myname = strrchr(modname, '/'))) - myname++; - else - myname = modname; - - return strcmp(myname, "vmlinux") == 0; -} - void *do_nofail(void *ptr, const char *expr) { if (!ptr) { @@ -71,7 +59,8 @@ void *do_nofail(void *ptr, const char *expr) static struct module *modules; -static struct module *find_module(char *modname) +struct module * +find_module(char *modname) { struct module *mod; @@ -81,11 +70,12 @@ static struct module *find_module(char *modname) return mod; } -static struct module *new_module(char *modname) +struct module * +new_module(char *modname) { struct module *mod; char *p, *s; - + mod = NOFAIL(malloc(sizeof(*mod))); memset(mod, 0, sizeof(*mod)); p = NOFAIL(strdup(modname)); @@ -114,10 +104,6 @@ struct symbol { unsigned int crc; int crc_valid; unsigned int weak:1; - unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ - unsigned int kernel:1; /* 1 if symbol is from kernel - * (only for external modules) **/ - unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ char name[0]; }; @@ -136,12 +122,11 @@ static inline unsigned int tdb_hash(const char *name) return (1103515243 * value + 12345); } -/** - * Allocate a new symbols for use in the hash of exported symbols or - * the list of unresolved symbols per module - **/ -static struct symbol *alloc_symbol(const char *name, unsigned int weak, - struct symbol *next) +/* Allocate a new symbols for use in the hash of exported symbols or + * the list of unresolved symbols per module */ + +struct symbol * +alloc_symbol(const char *name, unsigned int weak, struct symbol *next) { struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); @@ -153,7 +138,9 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak, } /* For the hash of exported symbols */ -static struct symbol *new_symbol(const char *name, struct module *module) + +void +new_symbol(const char *name, struct module *module, unsigned int *crc) { unsigned int hash; struct symbol *new; @@ -161,10 +148,14 @@ static struct symbol *new_symbol(const char *name, struct module *module) hash = tdb_hash(name) % SYMBOL_HASH_SIZE; new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); new->module = module; - return new; + if (crc) { + new->crc = *crc; + new->crc_valid = 1; + } } -static struct symbol *find_symbol(const char *name) +struct symbol * +find_symbol(const char *name) { struct symbol *s; @@ -179,42 +170,25 @@ static struct symbol *find_symbol(const char *name) return NULL; } -/** - * Add an exported symbol - it may have already been added without a - * CRC, in this case just update the CRC - **/ -static struct symbol *sym_add_exported(const char *name, struct module *mod) +/* Add an exported symbol - it may have already been added without a + * CRC, in this case just update the CRC */ +void +add_exported_symbol(const char *name, struct module *module, unsigned int *crc) { struct symbol *s = find_symbol(name); if (!s) { - s = new_symbol(name, mod); - } else { - if (!s->preloaded) { - warn("%s: '%s' exported twice. Previous export " - "was in %s%s\n", mod->name, name, - s->module->name, - is_vmlinux(s->module->name) ?"":".ko"); - } + new_symbol(name, module, crc); + return; + } + if (crc) { + s->crc = *crc; + s->crc_valid = 1; } - s->preloaded = 0; - s->vmlinux = is_vmlinux(mod->name); - s->kernel = 0; - return s; -} - -static void sym_update_crc(const char *name, struct module *mod, - unsigned int crc) -{ - struct symbol *s = find_symbol(name); - - if (!s) - s = new_symbol(name, mod); - s->crc = crc; - s->crc_valid = 1; } -void *grab_file(const char *filename, unsigned long *size) +void * +grab_file(const char *filename, unsigned long *size) { struct stat st; void *map; @@ -233,12 +207,13 @@ void *grab_file(const char *filename, unsigned long *size) return map; } -/** - * Return a copy of the next line in a mmap'ed file. - * spaces in the beginning of the line is trimmed away. - * Return a pointer to a static buffer. - **/ -char* get_next_line(unsigned long *pos, void *file, unsigned long size) +/* + Return a copy of the next line in a mmap'ed file. + spaces in the beginning of the line is trimmed away. + Return a pointer to a static buffer. +*/ +char* +get_next_line(unsigned long *pos, void *file, unsigned long size) { static char line[4096]; int skip = 1; @@ -268,12 +243,14 @@ char* get_next_line(unsigned long *pos, void *file, unsigned long size) return NULL; } -void release_file(void *file, unsigned long size) +void +release_file(void *file, unsigned long size) { munmap(file, size); } -static void parse_elf(struct elf_info *info, const char *filename) +void +parse_elf(struct elf_info *info, const char *filename) { unsigned int i; Elf_Ehdr *hdr = info->hdr; @@ -320,13 +297,14 @@ static void parse_elf(struct elf_info *info, const char *filename) continue; info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; - info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset + info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset + sechdrs[i].sh_size; - info->strtab = (void *)hdr + + info->strtab = (void *)hdr + sechdrs[sechdrs[i].sh_link].sh_offset; } if (!info->symtab_start) { - fatal("%s has no symtab?\n", filename); + fprintf(stderr, "modpost: %s no symtab?\n", filename); + abort(); } /* Fix endianness in symbols */ for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { @@ -338,31 +316,36 @@ static void parse_elf(struct elf_info *info, const char *filename) return; truncated: - fatal("%s is truncated.\n", filename); + fprintf(stderr, "modpost: %s is truncated.\n", filename); + abort(); } -static void parse_elf_finish(struct elf_info *info) +void +parse_elf_finish(struct elf_info *info) { release_file(info->hdr, info->size); } -#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" -#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" +#define CRC_PFX "__crc_" +#define KSYMTAB_PFX "__ksymtab_" -static void handle_modversions(struct module *mod, struct elf_info *info, - Elf_Sym *sym, const char *symname) +void +handle_modversions(struct module *mod, struct elf_info *info, + Elf_Sym *sym, const char *symname) { unsigned int crc; switch (sym->st_shndx) { case SHN_COMMON: - warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); + fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n", + symname, mod->name); break; case SHN_ABS: /* CRC'd symbol */ if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { crc = (unsigned int) sym->st_value; - sym_update_crc(symname + strlen(CRC_PFX), mod, crc); + add_exported_symbol(symname + strlen(CRC_PFX), + mod, &crc); } break; case SHN_UNDEF: @@ -387,15 +370,15 @@ static void handle_modversions(struct module *mod, struct elf_info *info, /* Ignore register directives. */ if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) break; - if (symname[0] == '.') { - char *munged = strdup(symname); - munged[0] = '_'; - munged[1] = toupper(munged[1]); - symname = munged; - } + if (symname[0] == '.') { + char *munged = strdup(symname); + munged[0] = '_'; + munged[1] = toupper(munged[1]); + symname = munged; + } } #endif - + if (memcmp(symname, MODULE_SYMBOL_PREFIX, strlen(MODULE_SYMBOL_PREFIX)) == 0) mod->unres = alloc_symbol(symname + @@ -406,7 +389,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, default: /* All exported symbols */ if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { - sym_add_exported(symname + strlen(KSYMTAB_PFX), mod); + add_exported_symbol(symname + strlen(KSYMTAB_PFX), + mod, NULL); } if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) mod->has_init = 1; @@ -416,9 +400,20 @@ static void handle_modversions(struct module *mod, struct elf_info *info, } } -/** - * Parse tag=value strings from .modinfo section - **/ +int +is_vmlinux(const char *modname) +{ + const char *myname; + + if ((myname = strrchr(modname, '/'))) + myname++; + else + myname = modname; + + return strcmp(myname, "vmlinux") == 0; +} + +/* Parse tag=value strings from .modinfo section */ static char *next_string(char *string, unsigned long *secsize) { /* Skip non-zero chars */ @@ -451,473 +446,8 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, return NULL; } -/** - * Test if string s ends in string sub - * return 0 if match - **/ -static int strrcmp(const char *s, const char *sub) -{ - int slen, sublen; - - if (!s || !sub) - return 1; - - slen = strlen(s); - sublen = strlen(sub); - - if ((slen == 0) || (sublen == 0)) - return 1; - - if (sublen > slen) - return 1; - - return memcmp(s + slen - sublen, sub, sublen); -} - -/** - * Whitelist to allow certain references to pass with no warning. - * Pattern 1: - * If a module parameter is declared __initdata and permissions=0 - * then this is legal despite the warning generated. - * We cannot see value of permissions here, so just ignore - * this pattern. - * The pattern is identified by: - * tosec = .init.data - * fromsec = .data* - * atsym =__param* - * - * Pattern 2: - * Many drivers utilise a *driver container with references to - * add, remove, probe functions etc. - * These functions may often be marked __init and we do not want to - * warn here. - * the pattern is identified by: - * tosec = .init.text | .exit.text | .init.data - * fromsec = .data - * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one - **/ -static int secref_whitelist(const char *tosec, const char *fromsec, - const char *atsym) -{ - int f1 = 1, f2 = 1; - const char **s; - const char *pat2sym[] = { - "driver", - "_template", /* scsi uses *_template a lot */ - "_sht", /* scsi also used *_sht to some extent */ - "_ops", - "_probe", - "_probe_one", - NULL - }; - - /* Check for pattern 1 */ - if (strcmp(tosec, ".init.data") != 0) - f1 = 0; - if (strncmp(fromsec, ".data", strlen(".data")) != 0) - f1 = 0; - if (strncmp(atsym, "__param", strlen("__param")) != 0) - f1 = 0; - - if (f1) - return f1; - - /* Check for pattern 2 */ - if ((strcmp(tosec, ".init.text") != 0) && - (strcmp(tosec, ".exit.text") != 0) && - (strcmp(tosec, ".init.data") != 0)) - f2 = 0; - if (strcmp(fromsec, ".data") != 0) - f2 = 0; - - for (s = pat2sym; *s; s++) - if (strrcmp(atsym, *s) == 0) - f1 = 1; - - return f1 && f2; -} - -/** - * Find symbol based on relocation record info. - * In some cases the symbol supplied is a valid symbol so - * return refsym. If st_name != 0 we assume this is a valid symbol. - * In other cases the symbol needs to be looked up in the symbol table - * based on section and address. - * **/ -static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, - Elf_Sym *relsym) -{ - Elf_Sym *sym; - - if (relsym->st_name != 0) - return relsym; - for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { - if (sym->st_shndx != relsym->st_shndx) - continue; - if (sym->st_value == addr) - return sym; - } - return NULL; -} - -/* - * Find symbols before or equal addr and after addr - in the section sec. - * If we find two symbols with equal offset prefer one with a valid name. - * The ELF format may have a better way to detect what type of symbol - * it is, but this works for now. - **/ -static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, - const char *sec, - Elf_Sym **before, Elf_Sym **after) -{ - Elf_Sym *sym; - Elf_Ehdr *hdr = elf->hdr; - Elf_Addr beforediff = ~0; - Elf_Addr afterdiff = ~0; - const char *secstrings = (void *)hdr + - elf->sechdrs[hdr->e_shstrndx].sh_offset; - - *before = NULL; - *after = NULL; - - for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { - const char *symsec; - - if (sym->st_shndx >= SHN_LORESERVE) - continue; - symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name; - if (strcmp(symsec, sec) != 0) - continue; - if (sym->st_value <= addr) { - if ((addr - sym->st_value) < beforediff) { - beforediff = addr - sym->st_value; - *before = sym; - } - else if ((addr - sym->st_value) == beforediff) { - /* equal offset, valid name? */ - const char *name = elf->strtab + sym->st_name; - if (name && strlen(name)) - *before = sym; - } - } - else - { - if ((sym->st_value - addr) < afterdiff) { - afterdiff = sym->st_value - addr; - *after = sym; - } - else if ((sym->st_value - addr) == afterdiff) { - /* equal offset, valid name? */ - const char *name = elf->strtab + sym->st_name; - if (name && strlen(name)) - *after = sym; - } - } - } -} - -/** - * Print a warning about a section mismatch. - * Try to find symbols near it so user can find it. - * Check whitelist before warning - it may be a false positive. - **/ -static void warn_sec_mismatch(const char *modname, const char *fromsec, - struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) -{ - const char *refsymname = ""; - Elf_Sym *before, *after; - Elf_Sym *refsym; - Elf_Ehdr *hdr = elf->hdr; - Elf_Shdr *sechdrs = elf->sechdrs; - const char *secstrings = (void *)hdr + - sechdrs[hdr->e_shstrndx].sh_offset; - const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name; - - find_symbols_between(elf, r.r_offset, fromsec, &before, &after); - - refsym = find_elf_symbol(elf, r.r_addend, sym); - if (refsym && strlen(elf->strtab + refsym->st_name)) - refsymname = elf->strtab + refsym->st_name; - - /* check whitelist - we may ignore it */ - if (before && - secref_whitelist(secname, fromsec, elf->strtab + before->st_name)) - return; - - if (before && after) { - warn("%s - Section mismatch: reference to %s:%s from %s " - "between '%s' (at offset 0x%llx) and '%s'\n", - modname, secname, refsymname, fromsec, - elf->strtab + before->st_name, - (long long)r.r_offset, - elf->strtab + after->st_name); - } else if (before) { - warn("%s - Section mismatch: reference to %s:%s from %s " - "after '%s' (at offset 0x%llx)\n", - modname, secname, refsymname, fromsec, - elf->strtab + before->st_name, - (long long)r.r_offset); - } else if (after) { - warn("%s - Section mismatch: reference to %s:%s from %s " - "before '%s' (at offset -0x%llx)\n", - modname, secname, refsymname, fromsec, - elf->strtab + after->st_name, - (long long)r.r_offset); - } else { - warn("%s - Section mismatch: reference to %s:%s from %s " - "(offset 0x%llx)\n", - modname, secname, fromsec, refsymname, - (long long)r.r_offset); - } -} - -/** - * A module includes a number of sections that are discarded - * either when loaded or when used as built-in. - * For loaded modules all functions marked __init and all data - * marked __initdata will be discarded when the module has been intialized. - * Likewise for modules used built-in the sections marked __exit - * are discarded because __exit marked function are supposed to be called - * only when a moduel is unloaded which never happes for built-in modules. - * The check_sec_ref() function traverses all relocation records - * to find all references to a section that reference a section that will - * be discarded and warns about it. - **/ -static void check_sec_ref(struct module *mod, const char *modname, - struct elf_info *elf, - int section(const char*), - int section_ref_ok(const char *)) -{ - int i; - Elf_Sym *sym; - Elf_Ehdr *hdr = elf->hdr; - Elf_Shdr *sechdrs = elf->sechdrs; - const char *secstrings = (void *)hdr + - sechdrs[hdr->e_shstrndx].sh_offset; - - /* Walk through all sections */ - for (i = 0; i < hdr->e_shnum; i++) { - const char *name = secstrings + sechdrs[i].sh_name; - const char *secname; - Elf_Rela r; - unsigned int r_sym; - /* We want to process only relocation sections and not .init */ - if (sechdrs[i].sh_type == SHT_RELA) { - Elf_Rela *rela; - Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; - Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; - name += strlen(".rela"); - if (section_ref_ok(name)) - continue; - - for (rela = start; rela < stop; rela++) { - r.r_offset = TO_NATIVE(rela->r_offset); -#if KERNEL_ELFCLASS == ELFCLASS64 - if (hdr->e_machine == EM_MIPS) { - r_sym = ELF64_MIPS_R_SYM(rela->r_info); - r_sym = TO_NATIVE(r_sym); - } else { - r.r_info = TO_NATIVE(rela->r_info); - r_sym = ELF_R_SYM(r.r_info); - } -#else - r.r_info = TO_NATIVE(rela->r_info); - r_sym = ELF_R_SYM(r.r_info); -#endif - r.r_addend = TO_NATIVE(rela->r_addend); - sym = elf->symtab_start + r_sym; - /* Skip special sections */ - if (sym->st_shndx >= SHN_LORESERVE) - continue; - - secname = secstrings + - sechdrs[sym->st_shndx].sh_name; - if (section(secname)) - warn_sec_mismatch(modname, name, - elf, sym, r); - } - } else if (sechdrs[i].sh_type == SHT_REL) { - Elf_Rel *rel; - Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset; - Elf_Rel *stop = (void*)start + sechdrs[i].sh_size; - name += strlen(".rel"); - if (section_ref_ok(name)) - continue; - - for (rel = start; rel < stop; rel++) { - r.r_offset = TO_NATIVE(rel->r_offset); -#if KERNEL_ELFCLASS == ELFCLASS64 - if (hdr->e_machine == EM_MIPS) { - r_sym = ELF64_MIPS_R_SYM(rel->r_info); - r_sym = TO_NATIVE(r_sym); - } else { - r.r_info = TO_NATIVE(rel->r_info); - r_sym = ELF_R_SYM(r.r_info); - } -#else - r.r_info = TO_NATIVE(rel->r_info); - r_sym = ELF_R_SYM(r.r_info); -#endif - r.r_addend = 0; - sym = elf->symtab_start + r_sym; - /* Skip special sections */ - if (sym->st_shndx >= SHN_LORESERVE) - continue; - - secname = secstrings + - sechdrs[sym->st_shndx].sh_name; - if (section(secname)) - warn_sec_mismatch(modname, name, - elf, sym, r); - } - } - } -} - -/** - * Functions used only during module init is marked __init and is stored in - * a .init.text section. Likewise data is marked __initdata and stored in - * a .init.data section. - * If this section is one of these sections return 1 - * See include/linux/init.h for the details - **/ -static int init_section(const char *name) -{ - if (strcmp(name, ".init") == 0) - return 1; - if (strncmp(name, ".init.", strlen(".init.")) == 0) - return 1; - return 0; -} - -/** - * Identify sections from which references to a .init section is OK. - * - * Unfortunately references to read only data that referenced .init - * sections had to be excluded. Almost all of these are false - * positives, they are created by gcc. The downside of excluding rodata - * is that there really are some user references from rodata to - * init code, e.g. drivers/video/vgacon.c: - * - * const struct consw vga_con = { - * con_startup: vgacon_startup, - * - * where vgacon_startup is __init. If you want to wade through the false - * positives, take out the check for rodata. - **/ -static int init_section_ref_ok(const char *name) -{ - const char **s; - /* Absolute section names */ - const char *namelist1[] = { - ".init", - ".opd", /* see comment [OPD] at exit_section_ref_ok() */ - ".toc1", /* used by ppc64 */ - ".stab", - ".rodata", - ".text.lock", - "__bug_table", /* used by powerpc for BUG() */ - ".pci_fixup_header", - ".pci_fixup_final", - ".pdr", - "__param", - NULL - }; - /* Start of section names */ - const char *namelist2[] = { - ".init.", - ".altinstructions", - ".eh_frame", - ".debug", - NULL - }; - /* part of section name */ - const char *namelist3 [] = { - ".unwind", /* sample: IA_64.unwind.init.text */ - NULL - }; - - for (s = namelist1; *s; s++) - if (strcmp(*s, name) == 0) - return 1; - for (s = namelist2; *s; s++) - if (strncmp(*s, name, strlen(*s)) == 0) - return 1; - for (s = namelist3; *s; s++) - if (strstr(name, *s) != NULL) - return 1; - return 0; -} - -/* - * Functions used only during module exit is marked __exit and is stored in - * a .exit.text section. Likewise data is marked __exitdata and stored in - * a .exit.data section. - * If this section is one of these sections return 1 - * See include/linux/init.h for the details - **/ -static int exit_section(const char *name) -{ - if (strcmp(name, ".exit.text") == 0) - return 1; - if (strcmp(name, ".exit.data") == 0) - return 1; - return 0; - -} - -/* - * Identify sections from which references to a .exit section is OK. - * - * [OPD] Keith Ownes commented: - * For our future {in}sanity, add a comment that this is the ppc .opd - * section, not the ia64 .opd section. - * ia64 .opd should not point to discarded sections. - * [.rodata] like for .init.text we ignore .rodata references -same reason - **/ -static int exit_section_ref_ok(const char *name) -{ - const char **s; - /* Absolute section names */ - const char *namelist1[] = { - ".exit.text", - ".exit.data", - ".init.text", - ".rodata", - ".opd", /* See comment [OPD] */ - ".toc1", /* used by ppc64 */ - ".altinstructions", - ".pdr", - "__bug_table", /* used by powerpc for BUG() */ - ".exitcall.exit", - ".eh_frame", - ".stab", - NULL - }; - /* Start of section names */ - const char *namelist2[] = { - ".debug", - NULL - }; - /* part of section name */ - const char *namelist3 [] = { - ".unwind", /* Sample: IA_64.unwind.exit.text */ - NULL - }; - - for (s = namelist1; *s; s++) - if (strcmp(*s, name) == 0) - return 1; - for (s = namelist2; *s; s++) - if (strncmp(*s, name, strlen(*s)) == 0) - return 1; - for (s = namelist3; *s; s++) - if (strstr(name, *s) != NULL) - return 1; - return 0; -} - -static void read_symbols(char *modname) +void +read_symbols(char *modname) { const char *symname; char *version; @@ -932,7 +462,9 @@ static void read_symbols(char *modname) /* When there's no vmlinux, don't print warnings about * unresolved symbols (since there'll be too many ;) */ if (is_vmlinux(modname)) { + unsigned int fake_crc = 0; have_vmlinux = 1; + add_exported_symbol("struct_module", mod, &fake_crc); mod->skip = 1; } @@ -942,8 +474,6 @@ static void read_symbols(char *modname) handle_modversions(mod, &info, sym, symname); handle_moddevtable(mod, &info, sym, symname); } - check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); - check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); version = get_modinfo(info.modinfo, info.modinfo_len, "version"); if (version) @@ -969,20 +499,21 @@ static void read_symbols(char *modname) * following helper, then compare to the file on disk and * only update the later if anything changed */ -void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, - const char *fmt, ...) +void __attribute__((format(printf, 2, 3))) +buf_printf(struct buffer *buf, const char *fmt, ...) { char tmp[SZ]; int len; va_list ap; - + va_start(ap, fmt); len = vsnprintf(tmp, SZ, fmt, ap); buf_write(buf, tmp, len); va_end(ap); } -void buf_write(struct buffer *buf, const char *s, int len) +void +buf_write(struct buffer *buf, const char *s, int len) { if (buf->size - buf->pos < len) { buf->size += len + SZ; @@ -992,10 +523,10 @@ void buf_write(struct buffer *buf, const char *s, int len) buf->pos += len; } -/** - * Header for the generated file - **/ -static void add_header(struct buffer *b, struct module *mod) +/* Header for the generated file */ + +void +add_header(struct buffer *b, struct module *mod) { buf_printf(b, "#include \n"); buf_printf(b, "#include \n"); @@ -1015,10 +546,10 @@ static void add_header(struct buffer *b, struct module *mod) buf_printf(b, "};\n"); } -/** - * Record CRCs for unresolved symbols - **/ -static void add_versions(struct buffer *b, struct module *mod) +/* Record CRCs for unresolved symbols */ + +void +add_versions(struct buffer *b, struct module *mod) { struct symbol *s, *exp; @@ -1026,8 +557,8 @@ static void add_versions(struct buffer *b, struct module *mod) exp = find_symbol(s->name); if (!exp || exp->module == mod) { if (have_vmlinux && !s->weak) - warn("\"%s\" [%s.ko] undefined!\n", - s->name, mod->name); + fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " + "undefined!\n", s->name, mod->name); continue; } s->module = exp->module; @@ -1048,7 +579,8 @@ static void add_versions(struct buffer *b, struct module *mod) continue; } if (!s->crc_valid) { - warn("\"%s\" [%s.ko] has no CRC!\n", + fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " + "has no CRC!\n", s->name, mod->name); continue; } @@ -1058,8 +590,8 @@ static void add_versions(struct buffer *b, struct module *mod) buf_printf(b, "};\n"); } -static void add_depends(struct buffer *b, struct module *mod, - struct module *modules) +void +add_depends(struct buffer *b, struct module *mod, struct module *modules) { struct symbol *s; struct module *m; @@ -1089,7 +621,8 @@ static void add_depends(struct buffer *b, struct module *mod, buf_printf(b, "\";\n"); } -static void add_srcversion(struct buffer *b, struct module *mod) +void +add_srcversion(struct buffer *b, struct module *mod) { if (mod->srcversion[0]) { buf_printf(b, "\n"); @@ -1098,7 +631,8 @@ static void add_srcversion(struct buffer *b, struct module *mod) } } -static void write_if_changed(struct buffer *b, const char *fname) +void +write_if_changed(struct buffer *b, const char *fname) { char *tmp; FILE *file; @@ -1142,7 +676,8 @@ static void write_if_changed(struct buffer *b, const char *fname) fclose(file); } -static void read_dump(const char *fname, unsigned int kernel) +void +read_dump(const char *fname) { unsigned long size, pos = 0; void *file = grab_file(fname, &size); @@ -1156,7 +691,6 @@ static void read_dump(const char *fname, unsigned int kernel) char *symname, *modname, *d; unsigned int crc; struct module *mod; - struct symbol *s; if (!(symname = strchr(line, '\t'))) goto fail; @@ -1177,30 +711,15 @@ static void read_dump(const char *fname, unsigned int kernel) mod = new_module(NOFAIL(strdup(modname))); mod->skip = 1; } - s = sym_add_exported(symname, mod); - s->kernel = kernel; - s->preloaded = 1; - sym_update_crc(symname, mod, crc); + add_exported_symbol(symname, mod, &crc); } return; fail: fatal("parse error in symbol dump file\n"); } -/* For normal builds always dump all symbols. - * For external modules only dump symbols - * that are not read from kernel Module.symvers. - **/ -static int dump_sym(struct symbol *sym) -{ - if (!external_module) - return 1; - if (sym->vmlinux || sym->kernel) - return 0; - return 1; -} - -static void write_dump(const char *fname) +void +write_dump(const char *fname) { struct buffer buf = { }; struct symbol *symbol; @@ -1209,33 +728,34 @@ static void write_dump(const char *fname) for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { symbol = symbolhash[n]; while (symbol) { - if (dump_sym(symbol)) - buf_printf(&buf, "0x%08x\t%s\t%s\n", - symbol->crc, symbol->name, - symbol->module->name); + symbol = symbol->next; + } + } + + for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { + symbol = symbolhash[n]; + while (symbol) { + buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc, + symbol->name, symbol->module->name); symbol = symbol->next; } } write_if_changed(&buf, fname); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct module *mod; struct buffer buf = { }; char fname[SZ]; - char *kernel_read = NULL, *module_read = NULL; - char *dump_write = NULL; + char *dump_read = NULL, *dump_write = NULL; int opt; - while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) { + while ((opt = getopt(argc, argv, "i:mo:a")) != -1) { switch(opt) { case 'i': - kernel_read = optarg; - break; - case 'I': - module_read = optarg; - external_module = 1; + dump_read = optarg; break; case 'm': modversions = 1; @@ -1251,10 +771,8 @@ int main(int argc, char **argv) } } - if (kernel_read) - read_dump(kernel_read, 1); - if (module_read) - read_dump(module_read, 0); + if (dump_read) + read_dump(dump_read); while (optind < argc) { read_symbols(argv[optind++]); @@ -1281,3 +799,4 @@ int main(int argc, char **argv) return 0; } + diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 861d866fc..7334d8391 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -13,53 +13,22 @@ #if KERNEL_ELFCLASS == ELFCLASS32 -#define Elf_Ehdr Elf32_Ehdr -#define Elf_Shdr Elf32_Shdr +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym -#define Elf_Addr Elf32_Addr -#define Elf_Section Elf32_Section #define ELF_ST_BIND ELF32_ST_BIND #define ELF_ST_TYPE ELF32_ST_TYPE -#define Elf_Rel Elf32_Rel -#define Elf_Rela Elf32_Rela -#define ELF_R_SYM ELF32_R_SYM -#define ELF_R_TYPE ELF32_R_TYPE #else -#define Elf_Ehdr Elf64_Ehdr -#define Elf_Shdr Elf64_Shdr +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym -#define Elf_Addr Elf64_Addr -#define Elf_Section Elf64_Section #define ELF_ST_BIND ELF64_ST_BIND #define ELF_ST_TYPE ELF64_ST_TYPE -#define Elf_Rel Elf64_Rel -#define Elf_Rela Elf64_Rela -#define ELF_R_SYM ELF64_R_SYM -#define ELF_R_TYPE ELF64_R_TYPE #endif -/* The 64-bit MIPS ELF ABI uses an unusual reloc format. */ -typedef struct -{ - Elf32_Word r_sym; /* Symbol index */ - unsigned char r_ssym; /* Special symbol for 2nd relocation */ - unsigned char r_type3; /* 3rd relocation type */ - unsigned char r_type2; /* 2nd relocation type */ - unsigned char r_type1; /* 1st relocation type */ -} _Elf64_Mips_R_Info; - -typedef union -{ - Elf64_Xword r_info_number; - _Elf64_Mips_R_Info r_info_fields; -} _Elf64_Mips_R_Info_union; - -#define ELF64_MIPS_R_SYM(i) \ - ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) - #if KERNEL_ELFDATA != HOST_ELFDATA static inline void __endian(const void *src, void *dest, unsigned int size) @@ -69,6 +38,8 @@ static inline void __endian(const void *src, void *dest, unsigned int size) ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1]; } + + #define TO_NATIVE(x) \ ({ \ typeof(x) __x; \ @@ -120,22 +91,17 @@ struct elf_info { unsigned int modinfo_len; }; -/* file2alias.c */ void handle_moddevtable(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname); + void add_moddevtable(struct buffer *buf, struct module *mod); -/* sumversion.c */ void maybe_frob_rcs_version(const char *modfilename, char *version, void *modinfo, unsigned long modinfo_offset); void get_src_version(const char *modname, char sum[], unsigned sumlen); -/* from modpost.c */ void *grab_file(const char *filename, unsigned long *size); char* get_next_line(unsigned long *pos, void *file, unsigned long size); void release_file(void *file, unsigned long size); - -void fatal(const char *fmt, ...); -void warn(const char *fmt, ...); diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 111234724..43271a1ca 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -252,9 +252,9 @@ static int parse_comment(const char *file, unsigned long len) } /* FIXME: Handle .s files differently (eg. # starts comments) --RR */ -static int parse_file(const signed char *fname, struct md4_ctx *md) +static int parse_file(const char *fname, struct md4_ctx *md) { - signed char *file; + char *file; unsigned long i, len; file = grab_file(fname, &len); @@ -332,7 +332,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) Sum all files in the same dir or subdirs. */ while ((line = get_next_line(&pos, file, flen)) != NULL) { - signed char* p = line; + char* p = line; if (strncmp(line, "deps_", sizeof("deps_")-1) == 0) { check_files = 1; continue; @@ -458,7 +458,7 @@ out: close(fd); } -static int strip_rcs_crap(signed char *version) +static int strip_rcs_crap(char *version) { unsigned int len, full_len; diff --git a/scripts/modsign/Makefile b/scripts/modsign/Makefile deleted file mode 100644 index 947f5f92f..000000000 --- a/scripts/modsign/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# Set the following to `true' to make a debuggable build. -# Leave this set to `false' for production use. -DEBUG = true - - -ROOT = mod-extract -VERSION = 0.1 -INSTALL_DIR = /usr/local/bin -RELEASE_NAME = $(ROOT)-$(VERSION) - -CC = gcc - -INCLUDES = -CFLAGS = -g -O -Wall - -OBJS = mod-extract.o - -all: $(ROOT) - -$(ROOT): $(OBJS) - $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) -lbfd -liberty $(LIB_OBJS) $(ARCH_LIB_OBJS) - -.c.o: - $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@ - -clean: - -rm $(OBJS) $(ROOT) diff --git a/scripts/modsign/mod-extract.c b/scripts/modsign/mod-extract.c deleted file mode 100644 index f8502e71e..000000000 --- a/scripts/modsign/mod-extract.c +++ /dev/null @@ -1,109 +0,0 @@ - - - -#include -#include -#include -#include -#include -#include -#include - -/* This should be set in a Makefile somehow */ -#define TARGET "i686-pc-linux-gnu" - -static FILE *out; - -static void dump_data(bfd *abfd) -{ - asection *section; - bfd_byte *data = 0; - bfd_size_type size; - bfd_size_type addr_offset; - bfd_size_type stop_offset; - unsigned int opb = bfd_octets_per_byte(abfd); - unsigned int cksum; - - for (section = abfd->sections; section != NULL; section = section->next) { - if (section->flags & SEC_HAS_CONTENTS) { - if (bfd_section_size(abfd, section) == 0) - continue; - - /* We only care about sections with "text" or "data" in their names */ - if ((strstr(section->name, "text") == NULL) && - (strstr(section->name, "data") == NULL)) - continue; - - cksum = 0; - - size = bfd_section_size(abfd, section) / opb; - - printf("Contents of section %s size %lu", section->name, size); - - data = (bfd_byte *) malloc(size); - - bfd_get_section_contents(abfd, section, (PTR) data, 0, size); - - stop_offset = size; - - printf(" idata %02x%02x%02x%02x", data[0], data[1], data[2], data[3]); - - for (addr_offset = 0; addr_offset < stop_offset; ++addr_offset) { - cksum += (unsigned int) data[addr_offset]; - fputc(data[addr_offset], out); - } - free (data); - - printf(" checksum %08x\n", cksum); - } - } -} - -void set_default_bfd_target(void) -{ - const char *target = TARGET; - - if (!bfd_set_default_target(target)) - fprintf(stderr, "can't set BFD default target to `%s': %s", target, bfd_errmsg (bfd_get_error ())); -} - -int main (int argc, char *argv[]) -{ - char *in_file; - char *out_file; - bfd *file; - char **matching; - - if (argc != 3) { - fprintf(stderr, "%s [infile] [outfile]\n", argv[0]); - exit(1); - } - - in_file = argv[1]; - out_file = argv[2]; - - bfd_init(); - set_default_bfd_target(); - - -// file = bfd_openr(in_file, "elf32-i386"); - file = bfd_openr(in_file, NULL); - if (file == NULL) { - fprintf(stderr, "error \"%s\" trying to open %s\n", strerror(errno), in_file); - exit(1); - } - - out = fopen(out_file, "w"); - if (out == NULL) { - fprintf(stderr, "error \"%s\" trying to create %s\n", strerror(errno), out_file); - exit(1); - } - - if (bfd_check_format_matches(file, bfd_object, &matching)) { - dump_data (file); - } - - fclose(out); - - return 0; -} diff --git a/scripts/modsign/modsign.sh b/scripts/modsign/modsign.sh deleted file mode 100644 index 4d3eaa233..000000000 --- a/scripts/modsign/modsign.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - - -if [ $# = "0" ] ; then - echo -# echo "usage: $0 " - echo "usage: $0 " - echo - exit 1 -fi - -module=$1 -#key=$2 - -# strip out only the sections that we care about -sh scripts/modsign/mod-extract.sh $module $module.out - -# sign the sections -#gpg --no-greeting --default-key $key -b $module.out -gpg --no-greeting --no-default-keyring --secret-keyring ../kernel.sec --keyring ../kernel.pub -b $module.out - -# check the signature -#gpg --verify rxrpc.ko.out.sig rxrpc.ko.out - -## sha1 the sections -#sha1sum $module.out | awk "{print \$1}" > $module.sha1 -# -## encrypt the sections -#gpg --no-greeting -e -o - -r $key $module.sha1 > $module.crypt - -# add the encrypted data to the module -#objcopy --add-section module_sig=$module.crypt $module $module.signed -objcopy --add-section module_sig=$module.out.sig $module $module.signed -objcopy --set-section-flags module_sig=alloc $module.signed -rm -f $module.out* diff --git a/scripts/namespace.pl b/scripts/namespace.pl index f34373853..88e30e82f 100644 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -66,8 +66,8 @@ require 5; # at least perl 5 use strict; use File::Find; -my $nm = ($ENV{'NM'} || "nm") . " -p"; -my $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment"; +my $nm = "/usr/bin/nm -p"; +my $objdump = "/usr/bin/objdump -s -j .comment"; my $srctree = ""; my $objtree = ""; $srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'})); diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 3b1f2eff2..c201ef001 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -59,7 +59,7 @@ $(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@ binrpm-pkg: $(objtree)/binkernel.spec - $(MAKE) + $(MAKE) KBUILD_SRC= set -e; \ $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version set -e; \ @@ -74,16 +74,30 @@ clean-files += $(objtree)/binkernel.spec # .PHONY: deb-pkg deb-pkg: - $(MAKE) + $(MAKE) KBUILD_SRC= $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb clean-dirs += $(objtree)/debian/ +# tarball targets +# --------------------------------------------------------------------------- +.PHONY: tar%pkg +tar%pkg: + $(MAKE) KBUILD_SRC= + $(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ + +clean-dirs += $(objtree)/tar-install/ + + # Help text displayed when executing 'make help' # --------------------------------------------------------------------------- help: - @echo ' rpm-pkg - Build the kernel as an RPM package' - @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel & modules' - @echo ' deb-pkg - Build the kernel as an deb package' + @echo ' rpm-pkg - Build the kernel as an RPM package' + @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel' + @echo ' and modules' + @echo ' deb-pkg - Build the kernel as an deb package' + @echo ' tar-pkg - Build the kernel as an uncompressed tarball' + @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' + @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl deleted file mode 100644 index cb4260ebd..000000000 --- a/scripts/profile2linkerlist.pl +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/perl - -# -# Takes a (sorted) output of readprofile and turns it into a list suitable for -# linker scripts -# -# usage: -# readprofile | sort -rn | perl profile2linkerlist.pl > functionlist -# - -while (<>) { - my $line = $_; - - $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/; - - if ( ($line =~ /unknown/) || ($line =~ /total/)) { - - } else { - print "*(.text.$1)\n"; - } -} diff --git a/scripts/reference_discarded.pl b/scripts/reference_discarded.pl new file mode 100644 index 000000000..4ee6ab213 --- /dev/null +++ b/scripts/reference_discarded.pl @@ -0,0 +1,112 @@ +#!/usr/bin/perl -w +# +# reference_discarded.pl (C) Keith Owens 2001 +# +# Released under GPL V2. +# +# List dangling references to vmlinux discarded sections. + +use strict; +die($0 . " takes no arguments\n") if($#ARGV >= 0); + +my %object; +my $object; +my $line; +my $ignore; +my $errorcount; + +$| = 1; + +# printf("Finding objects, "); +open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed"; +while (defined($line = )) { + chomp($line); + if ($line =~ /:\s+file format/) { + ($object = $line) =~ s/:.*//; + $object{$object}->{'module'} = 0; + $object{$object}->{'size'} = 0; + $object{$object}->{'off'} = 0; + } + if ($line =~ /^\s*\d+\s+\.modinfo\s+/) { + $object{$object}->{'module'} = 1; + } + if ($line =~ /^\s*\d+\s+\.comment\s+/) { + ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5]; + } +} +close(OBJDUMP_LIST); +# printf("%d objects, ", scalar keys(%object)); +$ignore = 0; +foreach $object (keys(%object)) { + if ($object{$object}->{'module'}) { + ++$ignore; + delete($object{$object}); + } +} +# printf("ignoring %d module(s)\n", $ignore); + +# Ignore conglomerate objects, they have been built from multiple objects and we +# only care about the individual objects. If an object has more than one GCC: +# string in the comment section then it is conglomerate. This does not filter +# out conglomerates that consist of exactly one object, can't be helped. + +# printf("Finding conglomerates, "); +$ignore = 0; +foreach $object (keys(%object)) { + if (exists($object{$object}->{'off'})) { + my ($off, $size, $comment, $l); + $off = hex($object{$object}->{'off'}); + $size = hex($object{$object}->{'size'}); + open(OBJECT, "<$object") || die "cannot read $object"; + seek(OBJECT, $off, 0) || die "seek to $off in $object failed"; + $l = read(OBJECT, $comment, $size); + die "read $size bytes from $object .comment failed" if ($l != $size); + close(OBJECT); + if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) { + ++$ignore; + delete($object{$object}); + } + } +} +# printf("ignoring %d conglomerate(s)\n", $ignore); + +# printf("Scanning objects\n"); + +# Keith Ownes commented: +# For our future {in}sanity, add a comment that this is the ppc .opd +# section, not the ia64 .opd section. +# ia64 .opd should not point to discarded sections. +$errorcount = 0; +foreach $object (keys(%object)) { + my $from; + open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object"; + while (defined($line = )) { + chomp($line); + if ($line =~ /RELOCATION RECORDS FOR /) { + ($from = $line) =~ s/.*\[([^]]*).*/$1/; + } + if (($line =~ /\.text\.exit$/ || + $line =~ /\.exit\.text$/ || + $line =~ /\.data\.exit$/ || + $line =~ /\.exit\.data$/ || + $line =~ /\.exitcall\.exit$/) && + ($from !~ /\.text\.exit$/ && + $from !~ /\.exit\.text$/ && + $from !~ /\.data\.exit$/ && + $from !~ /\.opd$/ && + $from !~ /\.exit\.data$/ && + $from !~ /\.altinstructions$/ && + $from !~ /\.pdr$/ && + $from !~ /\.debug_.*$/ && + $from !~ /\.exitcall\.exit$/ && + $from !~ /\.eh_frame$/ && + $from !~ /\.stab$/)) { + printf("Error: %s %s refers to %s\n", $object, $from, $line); + $errorcount = $errorcount + 1; + } + } + close(OBJDUMP); +} +# printf("Done\n"); + +exit(0); diff --git a/scripts/reference_init.pl b/scripts/reference_init.pl new file mode 100644 index 000000000..7f6960b17 --- /dev/null +++ b/scripts/reference_init.pl @@ -0,0 +1,108 @@ +#!/usr/bin/perl -w +# +# reference_init.pl (C) Keith Owens 2002 +# +# List references to vmlinux init sections from non-init sections. + +# Unfortunately I had to exclude references from read only data to .init +# sections, almost all of these are false positives, they are created by +# gcc. The downside of excluding rodata is that there really are some +# user references from rodata to init code, e.g. drivers/video/vgacon.c +# +# const struct consw vga_con = { +# con_startup: vgacon_startup, +# +# where vgacon_startup is __init. If you want to wade through the false +# positives, take out the check for rodata. + +use strict; +die($0 . " takes no arguments\n") if($#ARGV >= 0); + +my %object; +my $object; +my $line; +my $ignore; + +$| = 1; + +printf("Finding objects, "); +open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed"; +while (defined($line = )) { + chomp($line); + if ($line =~ /:\s+file format/) { + ($object = $line) =~ s/:.*//; + $object{$object}->{'module'} = 0; + $object{$object}->{'size'} = 0; + $object{$object}->{'off'} = 0; + } + if ($line =~ /^\s*\d+\s+\.modinfo\s+/) { + $object{$object}->{'module'} = 1; + } + if ($line =~ /^\s*\d+\s+\.comment\s+/) { + ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5]; + } +} +close(OBJDUMP_LIST); +printf("%d objects, ", scalar keys(%object)); +$ignore = 0; +foreach $object (keys(%object)) { + if ($object{$object}->{'module'}) { + ++$ignore; + delete($object{$object}); + } +} +printf("ignoring %d module(s)\n", $ignore); + +# Ignore conglomerate objects, they have been built from multiple objects and we +# only care about the individual objects. If an object has more than one GCC: +# string in the comment section then it is conglomerate. This does not filter +# out conglomerates that consist of exactly one object, can't be helped. + +printf("Finding conglomerates, "); +$ignore = 0; +foreach $object (keys(%object)) { + if (exists($object{$object}->{'off'})) { + my ($off, $size, $comment, $l); + $off = hex($object{$object}->{'off'}); + $size = hex($object{$object}->{'size'}); + open(OBJECT, "<$object") || die "cannot read $object"; + seek(OBJECT, $off, 0) || die "seek to $off in $object failed"; + $l = read(OBJECT, $comment, $size); + die "read $size bytes from $object .comment failed" if ($l != $size); + close(OBJECT); + if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) { + ++$ignore; + delete($object{$object}); + } + } +} +printf("ignoring %d conglomerate(s)\n", $ignore); + +printf("Scanning objects\n"); +foreach $object (sort(keys(%object))) { + my $from; + open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object"; + while (defined($line = )) { + chomp($line); + if ($line =~ /RELOCATION RECORDS FOR /) { + ($from = $line) =~ s/.*\[([^]]*).*/$1/; + } + if (($line =~ /\.init$/ || $line =~ /\.init\./) && + ($from !~ /\.init$/ && + $from !~ /\.init\./ && + $from !~ /\.stab$/ && + $from !~ /\.rodata$/ && + $from !~ /\.text\.lock$/ && + $from !~ /\.pci_fixup_header$/ && + $from !~ /\.pci_fixup_final$/ && + $from !~ /\.pdr$/ && + $from !~ /\__param$/ && + $from !~ /\.altinstructions/ && + $from !~ /\.eh_frame/ && + $from !~ /\.debug_/)) { + printf("Error: %s %s refers to %s\n", $object, $from, $line); + } + } + close(OBJDUMP); +} +printf("Done\n"); diff --git a/scripts/ver_linux b/scripts/ver_linux index 84999f697..beb43ef7f 100755 --- a/scripts/ver_linux +++ b/scripts/ver_linux @@ -39,10 +39,10 @@ tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' | awk \ fsck.jfs -V 2>&1 | grep version | sed 's/,//' | awk \ 'NR==1 {print "jfsutils ", $3}' -reiserfsck -V 2>&1 | grep ^reiserfsck | awk \ +reiserfsck -V 2>&1 | grep reiserfsck | awk \ 'NR==1{print "reiserfsprogs ", $2}' -fsck.reiser4 -V 2>&1 | grep ^fsck.reiser4 | awk \ +fsck.reiser4 -V 2>&1 | grep fsck.reiser4 | awk \ 'NR==1{print "reiser4progs ", $2}' xfs_db -V 2>&1 | grep version | awk \ diff --git a/security/commoncap.c b/security/commoncap.c index eceae9e53..cc05a3fd4 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -61,8 +61,8 @@ int cap_settime(struct timespec *ts, struct timezone *tz) int cap_ptrace (struct task_struct *parent, struct task_struct *child) { /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */ - if (!cap_issubset(child->cap_permitted, parent->cap_permitted) && - !__capable(parent, CAP_SYS_PTRACE)) + if (!cap_issubset (child->cap_permitted, current->cap_permitted) && + !capable(CAP_SYS_PTRACE)) return -EPERM; return 0; } diff --git a/security/dummy.c b/security/dummy.c index 8ccccccc1..f1a5bd98b 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -378,7 +378,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name) return 0; } -static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) +static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) { return -EOPNOTSUPP; } @@ -393,11 +393,6 @@ static int dummy_inode_listsecurity(struct inode *inode, char *buffer, size_t bu return 0; } -static const char *dummy_inode_xattr_getsuffix(void) -{ - return NULL; -} - static int dummy_file_permission (struct file *file, int mask) { return 0; @@ -768,14 +763,8 @@ static int dummy_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb) return 0; } -static int dummy_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) -{ - return -ENOPROTOOPT; -} - -static int dummy_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, - u32 *seclen) +static int dummy_socket_getpeersec(struct socket *sock, char __user *optval, + int __user *optlen, unsigned len) { return -ENOPROTOOPT; } @@ -936,7 +925,6 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, inode_getxattr); set_to_dummy_if_null(ops, inode_listxattr); set_to_dummy_if_null(ops, inode_removexattr); - set_to_dummy_if_null(ops, inode_xattr_getsuffix); set_to_dummy_if_null(ops, inode_getsecurity); set_to_dummy_if_null(ops, inode_setsecurity); set_to_dummy_if_null(ops, inode_listsecurity); @@ -1014,8 +1002,7 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, socket_getsockopt); set_to_dummy_if_null(ops, socket_shutdown); set_to_dummy_if_null(ops, socket_sock_rcv_skb); - set_to_dummy_if_null(ops, socket_getpeersec_stream); - set_to_dummy_if_null(ops, socket_getpeersec_dgram); + set_to_dummy_if_null(ops, socket_getpeersec); set_to_dummy_if_null(ops, sk_alloc_security); set_to_dummy_if_null(ops, sk_free_security); set_to_dummy_if_null(ops, sk_getsid); diff --git a/security/keys/key.c b/security/keys/key.c index b6061fa29..0e2584e11 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -1,6 +1,6 @@ /* key.c: basic authentication token and access key management * - * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or @@ -271,7 +271,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, * its description */ if (!not_in_quota) { spin_lock(&user->lock); - if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS || + if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS && user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES ) goto no_quota; @@ -799,16 +799,12 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, goto error_3; } - /* if it's possible to update this type of key, search for an existing - * key of the same type and description in the destination keyring and - * update that instead if possible + /* search for an existing key of the same type and description in the + * destination keyring */ - if (ktype->update) { - key_ref = __keyring_search_one(keyring_ref, ktype, description, - 0); - if (!IS_ERR(key_ref)) - goto found_matching_key; - } + key_ref = __keyring_search_one(keyring_ref, ktype, description, 0); + if (!IS_ERR(key_ref)) + goto found_matching_key; /* decide on the permissions we want */ perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index ed71d86d2..0c62798ac 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -17,33 +17,10 @@ #include #include #include -#include #include #include #include "internal.h" -static int key_get_type_from_user(char *type, - const char __user *_type, - unsigned len) -{ - int ret; - - ret = strncpy_from_user(type, _type, len); - - if (ret < 0) - return -EFAULT; - - if (ret == 0 || ret >= len) - return -EINVAL; - - if (type[0] == '.') - return -EPERM; - - type[len - 1] = '\0'; - - return 0; -} - /*****************************************************************************/ /* * extract the description of a new key from userspace and either add it as a @@ -61,22 +38,40 @@ asmlinkage long sys_add_key(const char __user *_type, key_ref_t keyring_ref, key_ref; char type[32], *description; void *payload; - long ret; + long dlen, ret; ret = -EINVAL; if (plen > 32767) goto error; /* draw all the data into kernel space */ - ret = key_get_type_from_user(type, _type, sizeof(type)); + ret = strncpy_from_user(type, _type, sizeof(type) - 1); if (ret < 0) goto error; + type[31] = '\0'; - description = strndup_user(_description, PAGE_SIZE); - if (IS_ERR(description)) { - ret = PTR_ERR(description); + ret = -EPERM; + if (type[0] == '.') + goto error; + + ret = -EFAULT; + dlen = strnlen_user(_description, PAGE_SIZE - 1); + if (dlen <= 0) goto error; - } + + ret = -EINVAL; + if (dlen > PAGE_SIZE - 1) + goto error; + + ret = -ENOMEM; + description = kmalloc(dlen + 1, GFP_KERNEL); + if (!description) + goto error; + description[dlen] = '\0'; + + ret = -EFAULT; + if (copy_from_user(description, _description, dlen) != 0) + goto error2; /* pull the payload in if one was supplied */ payload = NULL; @@ -141,28 +136,59 @@ asmlinkage long sys_request_key(const char __user *_type, struct key *key; key_ref_t dest_ref; char type[32], *description, *callout_info; - long ret; + long dlen, ret; /* pull the type into kernel space */ - ret = key_get_type_from_user(type, _type, sizeof(type)); + ret = strncpy_from_user(type, _type, sizeof(type) - 1); if (ret < 0) goto error; + type[31] = '\0'; + + ret = -EPERM; + if (type[0] == '.') + goto error; /* pull the description into kernel space */ - description = strndup_user(_description, PAGE_SIZE); - if (IS_ERR(description)) { - ret = PTR_ERR(description); + ret = -EFAULT; + dlen = strnlen_user(_description, PAGE_SIZE - 1); + if (dlen <= 0) goto error; - } + + ret = -EINVAL; + if (dlen > PAGE_SIZE - 1) + goto error; + + ret = -ENOMEM; + description = kmalloc(dlen + 1, GFP_KERNEL); + if (!description) + goto error; + description[dlen] = '\0'; + + ret = -EFAULT; + if (copy_from_user(description, _description, dlen) != 0) + goto error2; /* pull the callout info into kernel space */ callout_info = NULL; if (_callout_info) { - callout_info = strndup_user(_callout_info, PAGE_SIZE); - if (IS_ERR(callout_info)) { - ret = PTR_ERR(callout_info); + ret = -EFAULT; + dlen = strnlen_user(_callout_info, PAGE_SIZE - 1); + if (dlen <= 0) goto error2; - } + + ret = -EINVAL; + if (dlen > PAGE_SIZE - 1) + goto error2; + + ret = -ENOMEM; + callout_info = kmalloc(dlen + 1, GFP_KERNEL); + if (!callout_info) + goto error2; + callout_info[dlen] = '\0'; + + ret = -EFAULT; + if (copy_from_user(callout_info, _callout_info, dlen) != 0) + goto error3; } /* get the destination keyring if specified */ @@ -238,21 +264,36 @@ long keyctl_get_keyring_ID(key_serial_t id, int create) long keyctl_join_session_keyring(const char __user *_name) { char *name; - long ret; + long nlen, ret; /* fetch the name from userspace */ name = NULL; if (_name) { - name = strndup_user(_name, PAGE_SIZE); - if (IS_ERR(name)) { - ret = PTR_ERR(name); + ret = -EFAULT; + nlen = strnlen_user(_name, PAGE_SIZE - 1); + if (nlen <= 0) goto error; - } + + ret = -EINVAL; + if (nlen > PAGE_SIZE - 1) + goto error; + + ret = -ENOMEM; + name = kmalloc(nlen + 1, GFP_KERNEL); + if (!name) + goto error; + name[nlen] = '\0'; + + ret = -EFAULT; + if (copy_from_user(name, _name, nlen) != 0) + goto error2; } /* join the session */ ret = join_session_keyring(name); + error2: + kfree(name); error: return ret; @@ -525,18 +566,32 @@ long keyctl_keyring_search(key_serial_t ringid, struct key_type *ktype; key_ref_t keyring_ref, key_ref, dest_ref; char type[32], *description; - long ret; + long dlen, ret; /* pull the type and description into kernel space */ - ret = key_get_type_from_user(type, _type, sizeof(type)); + ret = strncpy_from_user(type, _type, sizeof(type) - 1); if (ret < 0) goto error; + type[31] = '\0'; - description = strndup_user(_description, PAGE_SIZE); - if (IS_ERR(description)) { - ret = PTR_ERR(description); + ret = -EFAULT; + dlen = strnlen_user(_description, PAGE_SIZE - 1); + if (dlen <= 0) goto error; - } + + ret = -EINVAL; + if (dlen > PAGE_SIZE - 1) + goto error; + + ret = -ENOMEM; + description = kmalloc(dlen + 1, GFP_KERNEL); + if (!description) + goto error; + description[dlen] = '\0'; + + ret = -EFAULT; + if (copy_from_user(description, _description, dlen) != 0) + goto error2; /* get the keyring at which to begin the search */ keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH); diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 217a0bef3..74cb79eb9 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -16,12 +16,11 @@ #include #include #include -#include #include #include "internal.h" /* session keyring create vs join semaphore */ -static DEFINE_MUTEX(key_session_mutex); +static DECLARE_MUTEX(key_session_sem); /* the root user's tracking struct */ struct key_user root_key_user = { @@ -168,12 +167,11 @@ error: */ int install_process_keyring(struct task_struct *tsk) { + unsigned long flags; struct key *keyring; char buf[20]; int ret; - might_sleep(); - if (!tsk->signal->process_keyring) { sprintf(buf, "_pid.%u", tsk->tgid); @@ -184,12 +182,12 @@ int install_process_keyring(struct task_struct *tsk) } /* attach keyring */ - spin_lock_irq(&tsk->sighand->siglock); + spin_lock_irqsave(&tsk->sighand->siglock, flags); if (!tsk->signal->process_keyring) { tsk->signal->process_keyring = keyring; keyring = NULL; } - spin_unlock_irq(&tsk->sighand->siglock); + spin_unlock_irqrestore(&tsk->sighand->siglock, flags); key_put(keyring); } @@ -208,37 +206,38 @@ error: static int install_session_keyring(struct task_struct *tsk, struct key *keyring) { + unsigned long flags; struct key *old; char buf[20]; - - might_sleep(); + int ret; /* create an empty session keyring */ if (!keyring) { sprintf(buf, "_ses.%u", tsk->tgid); keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); - if (IS_ERR(keyring)) - return PTR_ERR(keyring); + if (IS_ERR(keyring)) { + ret = PTR_ERR(keyring); + goto error; + } } else { atomic_inc(&keyring->usage); } /* install the keyring */ - spin_lock_irq(&tsk->sighand->siglock); - old = tsk->signal->session_keyring; + spin_lock_irqsave(&tsk->sighand->siglock, flags); + old = rcu_dereference(tsk->signal->session_keyring); rcu_assign_pointer(tsk->signal->session_keyring, keyring); - spin_unlock_irq(&tsk->sighand->siglock); + spin_unlock_irqrestore(&tsk->sighand->siglock, flags); - /* we're using RCU on the pointer, but there's no point synchronising - * on it if it didn't previously point to anything */ - if (old) { - synchronize_rcu(); - key_put(old); - } + ret = 0; - return 0; + /* we're using RCU on the pointer */ + synchronize_rcu(); + key_put(old); +error: + return ret; } /* end install_session_keyring() */ @@ -311,6 +310,7 @@ void exit_keys(struct task_struct *tsk) */ int exec_keys(struct task_struct *tsk) { + unsigned long flags; struct key *old; /* newly exec'd tasks don't get a thread keyring */ @@ -322,10 +322,10 @@ int exec_keys(struct task_struct *tsk) key_put(old); /* discard the process keyring from a newly exec'd task */ - spin_lock_irq(&tsk->sighand->siglock); + spin_lock_irqsave(&tsk->sighand->siglock, flags); old = tsk->signal->process_keyring; tsk->signal->process_keyring = NULL; - spin_unlock_irq(&tsk->sighand->siglock); + spin_unlock_irqrestore(&tsk->sighand->siglock, flags); key_put(old); @@ -711,7 +711,7 @@ long join_session_keyring(const char *name) } /* allow the user to join or create a named keyring */ - mutex_lock(&key_session_mutex); + down(&key_session_sem); /* look for an existing keyring of this name */ keyring = find_keyring_by_name(name, 0); @@ -737,7 +737,7 @@ long join_session_keyring(const char *name) key_put(keyring); error2: - mutex_unlock(&key_session_mutex); + up(&key_session_sem); error: return ret; diff --git a/security/seclvl.c b/security/seclvl.c index 441beaf1b..8ebe647b5 100644 --- a/security/seclvl.c +++ b/security/seclvl.c @@ -8,7 +8,6 @@ * Copyright (c) 2001 WireX Communications, Inc * Copyright (c) 2001 Greg Kroah-Hartman * Copyright (c) 2002 International Business Machines - * Copyright (c) 2006 Davi E. M. Arnaut * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +31,6 @@ #include #include #include -#include #include #include @@ -196,27 +194,35 @@ static unsigned char hashedPassword[SHA1_DIGEST_SIZE]; * people... */ static int -plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len) +plaintext_to_sha1(unsigned char *hash, const char *plaintext, int len) { + char *pgVirtAddr; struct crypto_tfm *tfm; - struct scatterlist sg; + struct scatterlist sg[1]; if (len > PAGE_SIZE) { seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d " "characters). Largest possible is %lu " "bytes.\n", len, PAGE_SIZE); - return -EINVAL; + return -ENOMEM; } tfm = crypto_alloc_tfm("sha1", CRYPTO_TFM_REQ_MAY_SLEEP); if (tfm == NULL) { seclvl_printk(0, KERN_ERR, "Failed to load transform for SHA1\n"); - return -EINVAL; + return -ENOSYS; } - sg_init_one(&sg, (u8 *)plaintext, len); + // Just get a new page; don't play around with page boundaries + // and scatterlists. + pgVirtAddr = (char *)__get_free_page(GFP_KERNEL); + sg[0].page = virt_to_page(pgVirtAddr); + sg[0].offset = 0; + sg[0].length = len; + strncpy(pgVirtAddr, plaintext, len); crypto_digest_init(tfm); - crypto_digest_update(tfm, &sg, 1); + crypto_digest_update(tfm, sg, 1); crypto_digest_final(tfm, hash); crypto_free_tfm(tfm); + free_page((unsigned long)pgVirtAddr); return 0; } @@ -228,9 +234,11 @@ static ssize_t passwd_write_file(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { - char *p; - int len; + int i; unsigned char tmp[SHA1_DIGEST_SIZE]; + char *page; + int rc; + int len; if (!*passwd && !*sha1_passwd) { seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the " @@ -243,39 +251,38 @@ passwd_write_file(struct file * file, const char __user * buf, return -EINVAL; } - if (count >= PAGE_SIZE) + if (count < 0 || count >= PAGE_SIZE) return -EINVAL; if (*ppos != 0) return -EINVAL; - p = kmalloc(count, GFP_KERNEL); - if (!p) + page = (char *)get_zeroed_page(GFP_KERNEL); + if (!page) return -ENOMEM; len = -EFAULT; - if (copy_from_user(p, buf, count)) + if (copy_from_user(page, buf, count)) goto out; - len = count; + len = strlen(page); /* ``echo "secret" > seclvl/passwd'' includes a newline */ - if (p[len - 1] == '\n') + if (page[len - 1] == '\n') len--; /* Hash the password, then compare the hashed values */ - if ((len = plaintext_to_sha1(tmp, p, len))) { + if ((rc = plaintext_to_sha1(tmp, page, len))) { seclvl_printk(0, KERN_ERR, "Error hashing password: rc = " - "[%d]\n", len); - goto out; + "[%d]\n", rc); + return rc; + } + for (i = 0; i < SHA1_DIGEST_SIZE; i++) { + if (hashedPassword[i] != tmp[i]) + return -EPERM; } - - len = -EPERM; - if (memcmp(hashedPassword, tmp, SHA1_DIGEST_SIZE)) - goto out; - seclvl_printk(0, KERN_INFO, "Password accepted; seclvl reduced to 0.\n"); seclvl = 0; len = count; out: - kfree (p); + free_page((unsigned long)page); return len; } @@ -288,11 +295,13 @@ static struct file_operations passwd_file_ops = { */ static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child) { - if (seclvl >= 0 && child->pid == 1) { - seclvl_printk(1, KERN_WARNING, "Attempt to ptrace " - "the init process dissallowed in " - "secure level %d\n", seclvl); - return -EPERM; + if (seclvl >= 0) { + if (child->pid == 1) { + seclvl_printk(1, KERN_WARNING, "Attempt to ptrace " + "the init process dissallowed in " + "secure level %d\n", seclvl); + return -EPERM; + } } return 0; } @@ -303,54 +312,55 @@ static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child) */ static int seclvl_capable(struct task_struct *tsk, int cap) { - int rc = 0; - /* init can do anything it wants */ if (tsk->pid == 1) return 0; - if (seclvl > 0) { - rc = -EPERM; - - if (cap == CAP_LINUX_IMMUTABLE) + switch (seclvl) { + case 2: + /* fall through */ + case 1: + if (cap == CAP_LINUX_IMMUTABLE) { seclvl_printk(1, KERN_WARNING, "Attempt to modify " "the IMMUTABLE and/or APPEND extended " "attribute on a file with the IMMUTABLE " "and/or APPEND extended attribute set " "denied in seclvl [%d]\n", seclvl); - else if (cap == CAP_SYS_RAWIO) + return -EPERM; + } else if (cap == CAP_SYS_RAWIO) { // Somewhat broad... seclvl_printk(1, KERN_WARNING, "Attempt to perform " "raw I/O while in secure level [%d] " "denied\n", seclvl); - else if (cap == CAP_NET_ADMIN) + return -EPERM; + } else if (cap == CAP_NET_ADMIN) { seclvl_printk(1, KERN_WARNING, "Attempt to perform " "network administrative task while " "in secure level [%d] denied\n", seclvl); - else if (cap == CAP_SETUID) + return -EPERM; + } else if (cap == CAP_SETUID) { seclvl_printk(1, KERN_WARNING, "Attempt to setuid " "while in secure level [%d] denied\n", seclvl); - else if (cap == CAP_SETGID) + return -EPERM; + } else if (cap == CAP_SETGID) { seclvl_printk(1, KERN_WARNING, "Attempt to setgid " "while in secure level [%d] denied\n", seclvl); - else if (cap == CAP_SYS_MODULE) + } else if (cap == CAP_SYS_MODULE) { seclvl_printk(1, KERN_WARNING, "Attempt to perform " "a module operation while in secure " "level [%d] denied\n", seclvl); - else - rc = 0; - } - - if (!rc) { - if (!(cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0)) - rc = -EPERM; + return -EPERM; + } + break; + default: + break; } - - if (rc) - seclvl_printk(1, KERN_WARNING, "Capability denied\n"); - - return rc; + /* from dummy.c */ + if (cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0) + return 0; /* capability granted */ + seclvl_printk(1, KERN_WARNING, "Capability denied\n"); + return -EPERM; /* capability denied */ } /** @@ -371,6 +381,8 @@ static int seclvl_settime(struct timespec *tv, struct timezone *tz) current->group_leader->pid); return -EPERM; } /* if attempt to decrement time */ + if (tv->tv_sec > 1924988400) /* disallow dates after 2030) */ + return -EPERM; /* CVE-2005-4352 */ } /* if seclvl > 1 */ return 0; } @@ -456,9 +468,12 @@ static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr) static void seclvl_file_free_security(struct file *filp) { struct dentry *dentry = filp->f_dentry; + struct inode *inode = NULL; - if (dentry) - seclvl_bd_release(dentry->d_inode); + if (dentry) { + inode = dentry->d_inode; + seclvl_bd_release(inode); + } } /** @@ -466,7 +481,9 @@ static void seclvl_file_free_security(struct file *filp) */ static int seclvl_umount(struct vfsmount *mnt, int flags) { - if (current->pid != 1 && seclvl == 2) { + if (current->pid == 1) + return 0; + if (seclvl == 2) { seclvl_printk(1, KERN_WARNING, "Attempt to unmount in secure " "level %d\n", seclvl); return -EPERM; @@ -490,9 +507,8 @@ static struct security_operations seclvl_ops = { static int processPassword(void) { int rc = 0; + hashedPassword[0] = '\0'; if (*passwd) { - char *p; - if (*sha1_passwd) { seclvl_printk(0, KERN_ERR, "Error: Both " "passwd and sha1_passwd " @@ -500,16 +516,12 @@ static int processPassword(void) "exclusive.\n"); return -EINVAL; } - - p = kstrdup(passwd, GFP_KERNEL); - if (p == NULL) - return -ENOMEM; - - if ((rc = plaintext_to_sha1(hashedPassword, p, strlen(p)))) + if ((rc = plaintext_to_sha1(hashedPassword, passwd, + strlen(passwd)))) { seclvl_printk(0, KERN_ERR, "Error: SHA1 support not " "in kernel\n"); - - kfree (p); + return rc; + } /* All static data goes to the BSS, which zero's the * plaintext password out for us. */ } else if (*sha1_passwd) { // Base 16 @@ -532,7 +544,7 @@ static int processPassword(void) sha1_passwd[i + 2] = tmp; } } - return rc; + return 0; } /** @@ -542,46 +554,28 @@ struct dentry *dir_ino, *seclvl_ino, *passwd_ino; static int seclvlfs_register(void) { - int rc = 0; - dir_ino = securityfs_create_dir("seclvl", NULL); - - if (IS_ERR(dir_ino)) - return PTR_ERR(dir_ino); + if (!dir_ino) + return -EFAULT; seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR, dir_ino, &seclvl, &seclvl_file_ops); - if (IS_ERR(seclvl_ino)) { - rc = PTR_ERR(seclvl_ino); + if (!seclvl_ino) goto out_deldir; - } if (*passwd || *sha1_passwd) { passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR, dir_ino, NULL, &passwd_file_ops); - if (IS_ERR(passwd_ino)) { - rc = PTR_ERR(passwd_ino); + if (!passwd_ino) goto out_delf; - } } - return rc; - -out_delf: - securityfs_remove(seclvl_ino); + return 0; out_deldir: securityfs_remove(dir_ino); - - return rc; -} - -static void seclvlfs_unregister(void) -{ +out_delf: securityfs_remove(seclvl_ino); - if (*passwd || *sha1_passwd) - securityfs_remove(passwd_ino); - - securityfs_remove(dir_ino); + return -EFAULT; } /** @@ -590,8 +584,6 @@ static void seclvlfs_unregister(void) static int __init seclvl_init(void) { int rc = 0; - static char once; - if (verbosity < 0 || verbosity > 1) { printk(KERN_ERR "Error: bad verbosity [%d]; only 0 or 1 " "are valid values\n", verbosity); @@ -610,11 +602,6 @@ static int __init seclvl_init(void) "module parameter(s): rc = [%d]\n", rc); goto exit; } - - if ((rc = seclvlfs_register())) { - seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n"); - goto exit; - } /* register ourselves with the security framework */ if (register_security(&seclvl_ops)) { seclvl_printk(0, KERN_ERR, @@ -626,24 +613,20 @@ static int __init seclvl_init(void) seclvl_printk(0, KERN_ERR, "seclvl: Failure " "registering with primary security " "module.\n"); - seclvlfs_unregister(); goto exit; } /* if primary module registered */ secondary = 1; } /* if we registered ourselves with the security framework */ - - seclvl_printk(0, KERN_INFO, "seclvl: Successfully initialized.\n"); - - if (once) { - once = 1; - seclvl_printk(0, KERN_INFO, "seclvl is going away. It has been " - "buggy for ages. Also, be warned that " - "Securelevels are useless."); + if ((rc = seclvlfs_register())) { + seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n"); + goto exit; } + seclvl_printk(0, KERN_INFO, "seclvl: Successfully initialized.\n"); exit: - if (rc) + if (rc) { printk(KERN_ERR "seclvl: Error during initialization: rc = " "[%d]\n", rc); + } return rc; } @@ -652,14 +635,17 @@ static int __init seclvl_init(void) */ static void __exit seclvl_exit(void) { - seclvlfs_unregister(); - - if (secondary) + securityfs_remove(seclvl_ino); + if (*passwd || *sha1_passwd) + securityfs_remove(passwd_ino); + securityfs_remove(dir_ino); + if (secondary == 1) { mod_unreg_security(MY_NAME, &seclvl_ops); - else if (unregister_security(&seclvl_ops)) + } else if (unregister_security(&seclvl_ops)) { seclvl_printk(0, KERN_INFO, "seclvl: Failure unregistering with the " "kernel\n"); + } } module_init(seclvl_init); diff --git a/security/security.c b/security/security.c index 51ef50971..c5c5793b1 100644 --- a/security/security.c +++ b/security/security.c @@ -174,8 +174,34 @@ int mod_unreg_security(const char *name, struct security_operations *ops) return security_ops->unregister_security(name, ops); } +/** + * capable - calls the currently loaded security module's capable() function with the specified capability + * @cap: the requested capability level. + * + * This function calls the currently loaded security module's capable() + * function with a pointer to the current task and the specified @cap value. + * + * This allows the security module to implement the capable function call + * however it chooses to. + */ +int capable(int cap) +{ + if (vx_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap)) + return 0; + if (security_ops->capable(current, cap)) { + /* capability denied */ + return 0; + } + + /* capability granted */ + current->flags |= PF_SUPERPRIV; + return 1; +} + + EXPORT_SYMBOL_GPL(register_security); EXPORT_SYMBOL_GPL(unregister_security); EXPORT_SYMBOL_GPL(mod_reg_security); EXPORT_SYMBOL_GPL(mod_unreg_security); +EXPORT_SYMBOL(capable); EXPORT_SYMBOL(security_ops); diff --git a/security/selinux/Makefile b/security/selinux/Makefile index faf2e02e4..688c0a267 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ -selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o exports.o +selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o diff --git a/security/selinux/avc.c b/security/selinux/avc.c index a300702da..ac5d69bb3 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -800,7 +800,7 @@ out: int avc_ss_reset(u32 seqno) { struct avc_callback_node *c; - int i, rc = 0, tmprc; + int i, rc = 0; unsigned long flag; struct avc_node *node; @@ -813,16 +813,15 @@ int avc_ss_reset(u32 seqno) for (c = avc_callbacks; c; c = c->next) { if (c->events & AVC_CALLBACK_RESET) { - tmprc = c->callback(AVC_CALLBACK_RESET, - 0, 0, 0, 0, NULL); - /* save the first error encountered for the return - value and continue processing the callbacks */ - if (!rc) - rc = tmprc; + rc = c->callback(AVC_CALLBACK_RESET, + 0, 0, 0, 0, NULL); + if (rc) + goto out; } } avc_latest_notif_update(seqno, 0); +out: return rc; } diff --git a/security/selinux/exports.c b/security/selinux/exports.c deleted file mode 100644 index ae4c73eb3..000000000 --- a/security/selinux/exports.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SELinux services exported to the rest of the kernel. - * - * Author: James Morris - * - * Copyright (C) 2005 Red Hat, Inc., James Morris - * Copyright (C) 2006 Trusted Computer Solutions, Inc. - * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez - * - * 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 -#include -#include -#include -#include -#include - -#include "security.h" -#include "objsec.h" - -void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid) -{ - struct task_security_struct *tsec = tsk->security; - if (selinux_enabled) - *ctxid = tsec->sid; - else - *ctxid = 0; -} - -int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen) -{ - if (selinux_enabled) - return security_sid_to_context(ctxid, ctx, ctxlen); - else { - *ctx = NULL; - *ctxlen = 0; - } - - return 0; -} - -void selinux_get_inode_sid(const struct inode *inode, u32 *sid) -{ - if (selinux_enabled) { - struct inode_security_struct *isec = inode->i_security; - *sid = isec->sid; - return; - } - *sid = 0; -} - -void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) -{ - if (selinux_enabled) { - struct ipc_security_struct *isec = ipcp->security; - *sid = isec->sid; - return; - } - *sid = 0; -} - -void selinux_get_task_sid(struct task_struct *tsk, u32 *sid) -{ - if (selinux_enabled) { - struct task_security_struct *tsec = tsk->security; - *sid = tsec->sid; - return; - } - *sid = 0; -} - diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 9fcb30dab..b65c201e9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -101,8 +101,6 @@ static int __init selinux_enabled_setup(char *str) return 1; } __setup("selinux=", selinux_enabled_setup); -#else -int selinux_enabled = 1; #endif /* Original (dummy) security module. */ @@ -119,34 +117,6 @@ static struct security_operations *secondary_ops = NULL; static LIST_HEAD(superblock_security_head); static DEFINE_SPINLOCK(sb_security_lock); -static kmem_cache_t *sel_inode_cache; - -/* Return security context for a given sid or just the context - length if the buffer is null or length is 0 */ -static int selinux_getsecurity(u32 sid, void *buffer, size_t size) -{ - char *context; - unsigned len; - int rc; - - rc = security_sid_to_context(sid, &context, &len); - if (rc) - return rc; - - if (!buffer || !size) - goto getsecurity_exit; - - if (size < len) { - len = -ERANGE; - goto getsecurity_exit; - } - memcpy(buffer, context, len); - -getsecurity_exit: - kfree(context); - return len; -} - /* Allocate and free functions for each kind of security blob. */ static int task_alloc_security(struct task_struct *task) @@ -176,11 +146,10 @@ static int inode_alloc_security(struct inode *inode) struct task_security_struct *tsec = current->security; struct inode_security_struct *isec; - isec = kmem_cache_alloc(sel_inode_cache, SLAB_KERNEL); + isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL); if (!isec) return -ENOMEM; - memset(isec, 0, sizeof(*isec)); init_MUTEX(&isec->sem); INIT_LIST_HEAD(&isec->list); isec->inode = inode; @@ -203,7 +172,7 @@ static void inode_free_security(struct inode *inode) spin_unlock(&sbsec->isec_lock); inode->i_security = NULL; - kmem_cache_free(sel_inode_cache, isec); + kfree(isec); } static int file_alloc_security(struct file *file) @@ -1960,6 +1929,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, struct task_security_struct *tsec; struct inode_security_struct *dsec; struct superblock_security_struct *sbsec; + struct inode_security_struct *isec; u32 newsid, clen; int rc; char *namep = NULL, *context; @@ -1967,6 +1937,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, tsec = current->security; dsec = dir->i_security; sbsec = dir->i_sb->s_security; + isec = inode->i_security; if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { newsid = tsec->create_sid; @@ -1986,7 +1957,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, inode_security_set_sid(inode, newsid); - if (!ss_initialized || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) + if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) return -EOPNOTSUPP; if (name) { @@ -2238,11 +2209,6 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name) return -EACCES; } -static const char *selinux_inode_xattr_getsuffix(void) -{ - return XATTR_SELINUX_SUFFIX; -} - /* * Copy the in-core inode security context value to the user. If the * getxattr() prior to this succeeded, check to see if we need to @@ -2250,14 +2216,47 @@ static const char *selinux_inode_xattr_getsuffix(void) * * Permission check is handled by selinux_inode_getxattr hook. */ -static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) +static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) { struct inode_security_struct *isec = inode->i_security; + char *context; + unsigned len; + int rc; - if (strcmp(name, XATTR_SELINUX_SUFFIX)) - return -EOPNOTSUPP; + if (strcmp(name, XATTR_SELINUX_SUFFIX)) { + rc = -EOPNOTSUPP; + goto out; + } - return selinux_getsecurity(isec->sid, buffer, size); + rc = security_sid_to_context(isec->sid, &context, &len); + if (rc) + goto out; + + /* Probe for required buffer size */ + if (!buffer || !size) { + rc = len; + goto out_free; + } + + if (size < len) { + rc = -ERANGE; + goto out_free; + } + + if (err > 0) { + if ((len == err) && !(memcmp(context, buffer, len))) { + /* Don't need to canonicalize value */ + rc = err; + goto out_free; + } + memset(buffer, 0, size); + } + memcpy(buffer, context, len); + rc = len; +out_free: + kfree(context); +out: + return rc; } static int selinux_inode_setsecurity(struct inode *inode, const char *name, @@ -2366,6 +2365,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, static int file_map_prot_check(struct file *file, unsigned long prot, int shared) { +#ifndef CONFIG_PPC32 if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { /* * We are making executable an anonymous mapping or a @@ -2376,6 +2376,7 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared if (rc) return rc; } +#endif if (file) { /* read access is always possible with a mapping */ @@ -2422,6 +2423,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, if (selinux_checkreqprot) prot = reqprot; +#ifndef CONFIG_PPC32 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { rc = 0; if (vma->vm_start >= vma->vm_mm->start_brk && @@ -2446,6 +2448,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, if (rc) return rc; } +#endif return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); } @@ -3227,7 +3230,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) goto out; /* Handle mapped IPv4 packets arriving via IPv6 sockets */ - if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) + if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) family = PF_INET; read_lock_bh(&sk->sk_callback_lock); @@ -3315,38 +3318,24 @@ out: return err; } -static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) +static int selinux_socket_getpeersec(struct socket *sock, char __user *optval, + int __user *optlen, unsigned len) { int err = 0; char *scontext; u32 scontext_len; struct sk_security_struct *ssec; struct inode_security_struct *isec; - u32 peer_sid = 0; isec = SOCK_INODE(sock)->i_security; - - /* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */ - if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) { - ssec = sock->sk->sk_security; - peer_sid = ssec->peer_sid; - } - else if (isec->sclass == SECCLASS_TCP_SOCKET) { - peer_sid = selinux_socket_getpeer_stream(sock->sk); - - if (peer_sid == SECSID_NULL) { - err = -ENOPROTOOPT; - goto out; - } - } - else { + if (isec->sclass != SECCLASS_UNIX_STREAM_SOCKET) { err = -ENOPROTOOPT; goto out; } - err = security_sid_to_context(peer_sid, &scontext, &scontext_len); - + ssec = sock->sk->sk_security; + + err = security_sid_to_context(ssec->peer_sid, &scontext, &scontext_len); if (err) goto out; @@ -3367,23 +3356,6 @@ out: return err; } -static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen) -{ - int err = 0; - u32 peer_sid = selinux_socket_getpeer_dgram(skb); - - if (peer_sid == SECSID_NULL) - return -EINVAL; - - err = security_sid_to_context(peer_sid, secdata, seclen); - if (err) - return err; - - return 0; -} - - - static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) { return sk_alloc_security(sk, family, priority); @@ -4091,7 +4063,8 @@ static int selinux_getprocattr(struct task_struct *p, char *name, void *value, size_t size) { struct task_security_struct *tsec; - u32 sid; + u32 sid, len; + char *context; int error; if (current != p) { @@ -4100,6 +4073,9 @@ static int selinux_getprocattr(struct task_struct *p, return error; } + if (!size) + return -ERANGE; + tsec = p->security; if (!strcmp(name, "current")) @@ -4116,7 +4092,16 @@ static int selinux_getprocattr(struct task_struct *p, if (!sid) return 0; - return selinux_getsecurity(sid, value, size); + error = security_sid_to_context(sid, &context, &len); + if (error) + return error; + if (len > size) { + kfree(context); + return -ERANGE; + } + memcpy(value, context, len); + kfree(context); + return len; } static int selinux_setprocattr(struct task_struct *p, @@ -4274,7 +4259,6 @@ static struct security_operations selinux_ops = { .inode_getxattr = selinux_inode_getxattr, .inode_listxattr = selinux_inode_listxattr, .inode_removexattr = selinux_inode_removexattr, - .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix, .inode_getsecurity = selinux_inode_getsecurity, .inode_setsecurity = selinux_inode_setsecurity, .inode_listsecurity = selinux_inode_listsecurity, @@ -4360,8 +4344,7 @@ static struct security_operations selinux_ops = { .socket_setsockopt = selinux_socket_setsockopt, .socket_shutdown = selinux_socket_shutdown, .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb, - .socket_getpeersec_stream = selinux_socket_getpeersec_stream, - .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram, + .socket_getpeersec = selinux_socket_getpeersec, .sk_alloc_security = selinux_sk_alloc_security, .sk_free_security = selinux_sk_free_security, .sk_getsid = selinux_sk_getsid_security, @@ -4393,9 +4376,6 @@ static __init int selinux_init(void) tsec = current->security; tsec->osid = tsec->sid = SECINITSID_KERNEL; - sel_inode_cache = kmem_cache_create("selinux_inode_security", - sizeof(struct inode_security_struct), - 0, SLAB_PANIC, NULL, NULL); avc_init(); original_ops = secondary_ops = security_ops; @@ -4418,7 +4398,6 @@ void selinux_complete_init(void) /* Set up any superblocks initialized prior to the policy load. */ printk(KERN_INFO "SELinux: Setting up existing superblocks.\n"); - spin_lock(&sb_lock); spin_lock(&sb_security_lock); next_sb: if (!list_empty(&superblock_security_head)) { @@ -4427,20 +4406,19 @@ next_sb: struct superblock_security_struct, list); struct super_block *sb = sbsec->sb; + spin_lock(&sb_lock); sb->s_count++; - spin_unlock(&sb_security_lock); spin_unlock(&sb_lock); + spin_unlock(&sb_security_lock); down_read(&sb->s_umount); if (sb->s_root) superblock_doinit(sb, NULL); drop_super(sb); - spin_lock(&sb_lock); spin_lock(&sb_security_lock); list_del_init(&sbsec->list); goto next_sb; } spin_unlock(&sb_security_lock); - spin_unlock(&sb_lock); } /* SELinux requires early initialization in order to label @@ -4535,7 +4513,6 @@ int selinux_disable(void) printk(KERN_INFO "SELinux: Disabled at runtime.\n"); selinux_disabled = 1; - selinux_enabled = 0; /* Reset security_ops to the secondary module, dummy or capability. */ security_ops = secondary_ops; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 063af47bb..5f016c980 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -29,7 +29,12 @@ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB +#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM extern int selinux_enabled; +#else +#define selinux_enabled 1 +#endif + extern int selinux_mls_enabled; int security_load_policy(void * data, size_t len); diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index c10f1fc41..8e87996c6 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h @@ -39,8 +39,6 @@ static inline u32 selinux_no_sk_sid(struct flowi *fl) #ifdef CONFIG_SECURITY_NETWORK_XFRM int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb); int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb); -u32 selinux_socket_getpeer_stream(struct sock *sk); -u32 selinux_socket_getpeer_dgram(struct sk_buff *skb); #else static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) { @@ -51,16 +49,6 @@ static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb) { return NF_ACCEPT; } - -static inline int selinux_socket_getpeer_stream(struct sock *sk) -{ - return SECSID_NULL; -} - -static inline int selinux_socket_getpeer_dgram(struct sk_buff *skb) -{ - return SECSID_NULL; -} #endif #endif /* _SELINUX_XFRM_H_ */ diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index d4f8abf52..69b9329b2 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -88,15 +88,8 @@ static struct nlmsg_perm nlmsg_xfrm_perms[] = { XFRM_MSG_DELPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, { XFRM_MSG_GETPOLICY, NETLINK_XFRM_SOCKET__NLMSG_READ }, { XFRM_MSG_ALLOCSPI, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, - { XFRM_MSG_ACQUIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, - { XFRM_MSG_EXPIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, { XFRM_MSG_UPDPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, { XFRM_MSG_UPDSA, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, - { XFRM_MSG_POLEXPIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, - { XFRM_MSG_FLUSHSA, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, - { XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, - { XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, - { XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ }, }; static struct nlmsg_perm nlmsg_audit_perms[] = @@ -106,14 +99,8 @@ static struct nlmsg_perm nlmsg_audit_perms[] = { AUDIT_LIST, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV }, { AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, { AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, - { AUDIT_LIST_RULES, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV }, - { AUDIT_ADD_RULE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, - { AUDIT_DEL_RULE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY }, { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ }, - { AUDIT_WATCH_INS, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, - { AUDIT_WATCH_REM, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, - { AUDIT_WATCH_LIST, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV }, }; @@ -158,10 +145,8 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) break; case SECCLASS_NETLINK_AUDIT_SOCKET: - if ((nlmsg_type >= AUDIT_FIRST_USER_MSG && - nlmsg_type <= AUDIT_LAST_USER_MSG) || - (nlmsg_type >= AUDIT_FIRST_USER_MSG2 && - nlmsg_type <= AUDIT_LAST_USER_MSG2)) { + if (nlmsg_type >= AUDIT_FIRST_USER_MSG && + nlmsg_type <= AUDIT_LAST_USER_MSG) { *perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY; } else { err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms, diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index a4efc966f..b5fa02d17 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -15,14 +15,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include @@ -46,7 +44,7 @@ static int __init checkreqprot_setup(char *str) __setup("checkreqprot=", checkreqprot_setup); -static DEFINE_MUTEX(sel_mutex); +static DECLARE_MUTEX(sel_sem); /* global data for booleans */ static struct dentry *bool_dir = NULL; @@ -128,10 +126,6 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf, length = task_has_security(current, SECURITY__SETENFORCE); if (length) goto out; - audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, - "enforcing=%d old_enforcing=%d auid=%u", new_value, - selinux_enforcing, - audit_get_loginuid(current->audit_context)); selinux_enforcing = new_value; if (selinux_enforcing) avc_ss_reset(0); @@ -182,9 +176,6 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf, length = selinux_disable(); if (length < 0) goto out; - audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, - "selinux=0 auid=%u", - audit_get_loginuid(current->audit_context)); } length = count; @@ -239,7 +230,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf, ssize_t length; void *data = NULL; - mutex_lock(&sel_mutex); + down(&sel_sem); length = task_has_security(current, SECURITY__LOAD_POLICY); if (length) @@ -270,11 +261,8 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf, length = ret; else length = count; - audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, - "policy loaded auid=%u", - audit_get_loginuid(current->audit_context)); out: - mutex_unlock(&sel_mutex); + up(&sel_sem); vfree(data); return length; } @@ -721,11 +709,12 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, { char *page = NULL; ssize_t length; + ssize_t end; ssize_t ret; int cur_enforcing; struct inode *inode; - mutex_lock(&sel_mutex); + down(&sel_sem); ret = -EFAULT; @@ -751,9 +740,26 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]); - ret = simple_read_from_buffer(buf, count, ppos, page, length); + if (length < 0) { + ret = length; + goto out; + } + + if (*ppos >= length) { + ret = 0; + goto out; + } + if (count + *ppos > length) + count = length - *ppos; + end = count + *ppos; + if (copy_to_user(buf, (char *) page + *ppos, count)) { + ret = -EFAULT; + goto out; + } + *ppos = end; + ret = count; out: - mutex_unlock(&sel_mutex); + up(&sel_sem); if (page) free_page((unsigned long)page); return ret; @@ -767,7 +773,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, int new_value; struct inode *inode; - mutex_lock(&sel_mutex); + down(&sel_sem); length = task_has_security(current, SECURITY__SETBOOL); if (length) @@ -806,7 +812,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, length = count; out: - mutex_unlock(&sel_mutex); + up(&sel_sem); if (page) free_page((unsigned long) page); return length; @@ -825,7 +831,7 @@ static ssize_t sel_commit_bools_write(struct file *filep, ssize_t length = -EFAULT; int new_value; - mutex_lock(&sel_mutex); + down(&sel_sem); length = task_has_security(current, SECURITY__SETBOOL); if (length) @@ -863,7 +869,7 @@ static ssize_t sel_commit_bools_write(struct file *filep, length = count; out: - mutex_unlock(&sel_mutex); + up(&sel_sem); if (page) free_page((unsigned long) page); return length; @@ -981,7 +987,7 @@ out: return ret; err: kfree(values); - sel_remove_bools(dir); + d_genocide(dir); ret = -ENOMEM; goto out; } @@ -1162,38 +1168,37 @@ static int sel_make_avc_files(struct dentry *dir) dentry = d_alloc_name(dir, files[i].name); if (!dentry) { ret = -ENOMEM; - goto out; + goto err; } inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); if (!inode) { ret = -ENOMEM; - goto out; + goto err; } inode->i_fop = files[i].ops; d_add(dentry, inode); } out: return ret; +err: + d_genocide(dir); + goto out; } -static int sel_make_dir(struct inode *dir, struct dentry *dentry) +static int sel_make_dir(struct super_block *sb, struct dentry *dentry) { int ret = 0; struct inode *inode; - inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); + inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); if (!inode) { ret = -ENOMEM; goto out; } inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; - /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; d_add(dentry, inode); - /* bump link count on parent directory, too */ - dir->i_nlink++; out: return ret; } @@ -1202,7 +1207,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) { int ret; struct dentry *dentry; - struct inode *inode, *root_inode; + struct inode *inode; struct inode_security_struct *isec; static struct tree_descr selinux_files[] = { @@ -1223,33 +1228,30 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) }; ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); if (ret) - goto err; - - root_inode = sb->s_root->d_inode; + return ret; dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); - if (!dentry) { - ret = -ENOMEM; - goto err; - } - - ret = sel_make_dir(root_inode, dentry); - if (ret) - goto err; + if (!dentry) + return -ENOMEM; + inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); + if (!inode) + goto out; + inode->i_op = &simple_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + d_add(dentry, inode); bool_dir = dentry; + ret = sel_make_bools(); + if (ret) + goto out; dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); - if (!dentry) { - ret = -ENOMEM; - goto err; - } + if (!dentry) + return -ENOMEM; inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); - if (!inode) { - ret = -ENOMEM; - goto err; - } + if (!inode) + goto out; isec = (struct inode_security_struct*)inode->i_security; isec->sid = SECINITSID_DEVNULL; isec->sclass = SECCLASS_CHR_FILE; @@ -1260,23 +1262,22 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) selinux_null = dentry; dentry = d_alloc_name(sb->s_root, "avc"); - if (!dentry) { - ret = -ENOMEM; - goto err; - } + if (!dentry) + return -ENOMEM; - ret = sel_make_dir(root_inode, dentry); + ret = sel_make_dir(sb, dentry); if (ret) - goto err; + goto out; ret = sel_make_avc_files(dentry); if (ret) - goto err; + goto out; + + return 0; out: - return ret; -err: + dput(dentry); printk(KERN_ERR "%s: failed while creating inodes\n", __FUNCTION__); - goto out; + return -ENOMEM; } static struct super_block *sel_get_sb(struct file_system_type *fs_type, diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 7bc5b6440..84047f69f 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -8,7 +8,7 @@ * * Support for enhanced MLS infrastructure. * - * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. */ #include @@ -384,34 +384,6 @@ out: return rc; } -/* - * Set the MLS fields in the security context structure - * `context' based on the string representation in - * the string `str'. This function will allocate temporary memory with the - * given constraints of gfp_mask. - */ -int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) -{ - char *tmpstr, *freestr; - int rc; - - if (!selinux_mls_enabled) - return -EINVAL; - - /* we need freestr because mls_context_to_sid will change - the value of tmpstr */ - tmpstr = freestr = kstrdup(str, gfp_mask); - if (!tmpstr) { - rc = -ENOMEM; - } else { - rc = mls_context_to_sid(':', &tmpstr, context, - NULL, SECSID_NULL); - kfree(freestr); - } - - return rc; -} - /* * Copies the effective MLS range from `src' into `dst'. */ diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index fbb42f07d..03de697c8 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -8,7 +8,7 @@ * * Support for enhanced MLS infrastructure. * - * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. */ #ifndef _SS_MLS_H_ @@ -27,8 +27,6 @@ int mls_context_to_sid(char oldc, struct sidtab *s, u32 def_sid); -int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); - int mls_convert_context(struct policydb *oldp, struct policydb *newp, struct context *context); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index c284dbb8b..6375dd578 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -7,13 +7,12 @@ * Updated: Trusted Computer Solutions, Inc. * * Support for enhanced MLS infrastructure. - * Support for context based audit filters. * * Updated: Frank Mayer and Karl MacMillan * * Added conditional policy language extensions * - * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2004 Tresys Technology, LLC * Copyright (C) 2003 Red Hat, Inc., James Morris * This program is free software; you can redistribute it and/or modify @@ -28,8 +27,7 @@ #include #include #include -#include - +#include #include "flask.h" #include "avc.h" #include "avc_ss.h" @@ -50,9 +48,9 @@ static DEFINE_RWLOCK(policy_rwlock); #define POLICY_RDUNLOCK read_unlock(&policy_rwlock) #define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock) -static DEFINE_MUTEX(load_mutex); -#define LOAD_LOCK mutex_lock(&load_mutex) -#define LOAD_UNLOCK mutex_unlock(&load_mutex) +static DECLARE_MUTEX(load_sem); +#define LOAD_LOCK down(&load_sem) +#define LOAD_UNLOCK up(&load_sem) static struct sidtab sidtab; struct policydb policydb; @@ -1764,22 +1762,19 @@ int security_set_bools(int len, int *values) goto out; } + printk(KERN_INFO "security: committed booleans { "); for (i = 0; i < len; i++) { - if (!!values[i] != policydb.bool_val_to_struct[i]->state) { - audit_log(current->audit_context, GFP_ATOMIC, - AUDIT_MAC_CONFIG_CHANGE, - "bool=%s val=%d old_val=%d auid=%u", - policydb.p_bool_val_to_name[i], - !!values[i], - policydb.bool_val_to_struct[i]->state, - audit_get_loginuid(current->audit_context)); - } if (values[i]) { policydb.bool_val_to_struct[i]->state = 1; } else { policydb.bool_val_to_struct[i]->state = 0; } + if (i != 0) + printk(", "); + printk("%s:%d", policydb.p_bool_val_to_name[i], + policydb.bool_val_to_struct[i]->state); } + printk(" }\n"); for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { rc = evaluate_cond_node(&policydb, cur); @@ -1816,235 +1811,3 @@ out: POLICY_RDUNLOCK; return rc; } - -struct selinux_audit_rule { - u32 au_seqno; - struct context au_ctxt; -}; - -void selinux_audit_rule_free(struct selinux_audit_rule *rule) -{ - if (rule) { - context_destroy(&rule->au_ctxt); - kfree(rule); - } -} - -int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, - struct selinux_audit_rule **rule) -{ - struct selinux_audit_rule *tmprule; - struct role_datum *roledatum; - struct type_datum *typedatum; - struct user_datum *userdatum; - int rc = 0; - - *rule = NULL; - - if (!ss_initialized) - return -ENOTSUPP; - - switch (field) { - case AUDIT_SE_USER: - case AUDIT_SE_ROLE: - case AUDIT_SE_TYPE: - /* only 'equals' and 'not equals' fit user, role, and type */ - if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL) - return -EINVAL; - break; - case AUDIT_SE_SEN: - case AUDIT_SE_CLR: - /* we do not allow a range, indicated by the presense of '-' */ - if (strchr(rulestr, '-')) - return -EINVAL; - break; - default: - /* only the above fields are valid */ - return -EINVAL; - } - - tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); - if (!tmprule) - return -ENOMEM; - - context_init(&tmprule->au_ctxt); - - POLICY_RDLOCK; - - tmprule->au_seqno = latest_granting; - - switch (field) { - case AUDIT_SE_USER: - userdatum = hashtab_search(policydb.p_users.table, rulestr); - if (!userdatum) - rc = -EINVAL; - else - tmprule->au_ctxt.user = userdatum->value; - break; - case AUDIT_SE_ROLE: - roledatum = hashtab_search(policydb.p_roles.table, rulestr); - if (!roledatum) - rc = -EINVAL; - else - tmprule->au_ctxt.role = roledatum->value; - break; - case AUDIT_SE_TYPE: - typedatum = hashtab_search(policydb.p_types.table, rulestr); - if (!typedatum) - rc = -EINVAL; - else - tmprule->au_ctxt.type = typedatum->value; - break; - case AUDIT_SE_SEN: - case AUDIT_SE_CLR: - rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); - break; - } - - POLICY_RDUNLOCK; - - if (rc) { - selinux_audit_rule_free(tmprule); - tmprule = NULL; - } - - *rule = tmprule; - - return rc; -} - -int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op, - struct selinux_audit_rule *rule, - struct audit_context *actx) -{ - struct context *ctxt; - struct mls_level *level; - int match = 0; - - if (!rule) { - audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: missing rule\n"); - return -ENOENT; - } - - POLICY_RDLOCK; - - if (rule->au_seqno < latest_granting) { - audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: stale rule\n"); - match = -ESTALE; - goto out; - } - - ctxt = sidtab_search(&sidtab, ctxid); - if (!ctxt) { - audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: unrecognized SID %d\n", - ctxid); - match = -ENOENT; - goto out; - } - - /* a field/op pair that is not caught here will simply fall through - without a match */ - switch (field) { - case AUDIT_SE_USER: - switch (op) { - case AUDIT_EQUAL: - match = (ctxt->user == rule->au_ctxt.user); - break; - case AUDIT_NOT_EQUAL: - match = (ctxt->user != rule->au_ctxt.user); - break; - } - break; - case AUDIT_SE_ROLE: - switch (op) { - case AUDIT_EQUAL: - match = (ctxt->role == rule->au_ctxt.role); - break; - case AUDIT_NOT_EQUAL: - match = (ctxt->role != rule->au_ctxt.role); - break; - } - break; - case AUDIT_SE_TYPE: - switch (op) { - case AUDIT_EQUAL: - match = (ctxt->type == rule->au_ctxt.type); - break; - case AUDIT_NOT_EQUAL: - match = (ctxt->type != rule->au_ctxt.type); - break; - } - break; - case AUDIT_SE_SEN: - case AUDIT_SE_CLR: - level = (op == AUDIT_SE_SEN ? - &ctxt->range.level[0] : &ctxt->range.level[1]); - switch (op) { - case AUDIT_EQUAL: - match = mls_level_eq(&rule->au_ctxt.range.level[0], - level); - break; - case AUDIT_NOT_EQUAL: - match = !mls_level_eq(&rule->au_ctxt.range.level[0], - level); - break; - case AUDIT_LESS_THAN: - match = (mls_level_dom(&rule->au_ctxt.range.level[0], - level) && - !mls_level_eq(&rule->au_ctxt.range.level[0], - level)); - break; - case AUDIT_LESS_THAN_OR_EQUAL: - match = mls_level_dom(&rule->au_ctxt.range.level[0], - level); - break; - case AUDIT_GREATER_THAN: - match = (mls_level_dom(level, - &rule->au_ctxt.range.level[0]) && - !mls_level_eq(level, - &rule->au_ctxt.range.level[0])); - break; - case AUDIT_GREATER_THAN_OR_EQUAL: - match = mls_level_dom(level, - &rule->au_ctxt.range.level[0]); - break; - } - } - -out: - POLICY_RDUNLOCK; - return match; -} - -static int (*aurule_callback)(void) = NULL; - -static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, - u16 class, u32 perms, u32 *retained) -{ - int err = 0; - - if (event == AVC_CALLBACK_RESET && aurule_callback) - err = aurule_callback(); - return err; -} - -static int __init aurule_init(void) -{ - int err; - - err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, - SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); - if (err) - panic("avc_add_callback() failed, error %d\n", err); - - return err; -} -__initcall(aurule_init); - -void selinux_audit_set_callback(int (*callback)(void)) -{ - aurule_callback = callback; -} diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index abe99d881..b2af7ca49 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -224,74 +224,6 @@ void selinux_xfrm_state_free(struct xfrm_state *x) kfree(ctx); } -/* - * SELinux internal function to retrieve the context of a connected - * (sk->sk_state == TCP_ESTABLISHED) TCP socket based on its security - * association used to connect to the remote socket. - * - * Retrieve via getsockopt SO_PEERSEC. - */ -u32 selinux_socket_getpeer_stream(struct sock *sk) -{ - struct dst_entry *dst, *dst_test; - u32 peer_sid = SECSID_NULL; - - if (sk->sk_state != TCP_ESTABLISHED) - goto out; - - dst = sk_dst_get(sk); - if (!dst) - goto out; - - for (dst_test = dst; dst_test != 0; - dst_test = dst_test->child) { - struct xfrm_state *x = dst_test->xfrm; - - if (x && selinux_authorizable_xfrm(x)) { - struct xfrm_sec_ctx *ctx = x->security; - peer_sid = ctx->ctx_sid; - break; - } - } - dst_release(dst); - -out: - return peer_sid; -} - -/* - * SELinux internal function to retrieve the context of a UDP packet - * based on its security association used to connect to the remote socket. - * - * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message - * type SCM_SECURITY. - */ -u32 selinux_socket_getpeer_dgram(struct sk_buff *skb) -{ - struct sec_path *sp; - - if (skb == NULL) - return SECSID_NULL; - - if (skb->sk->sk_protocol != IPPROTO_UDP) - return SECSID_NULL; - - sp = skb->sp; - if (sp) { - int i; - - for (i = sp->len-1; i >= 0; i--) { - struct xfrm_state *x = sp->xvec[i]; - if (selinux_authorizable_xfrm(x)) { - struct xfrm_sec_ctx *ctx = x->security; - return ctx->ctx_sid; - } - } - } - - return SECSID_NULL; -} - /* * LSM hook that controls access to unlabelled packets. If * a xfrm_state is authorizable (defined by macro) then it was @@ -314,7 +246,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) * Only need to verify the existence of an authorizable sp. */ for (i = 0; i < sp->len; i++) { - struct xfrm_state *x = sp->xvec[i]; + struct xfrm_state *x = sp->x[i].xvec; if (x && selinux_authorizable_xfrm(x)) goto accept; diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 5f22d70fe..149feb410 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -73,7 +73,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned if (ac97->num >= 4) return; - mutex_lock(&aaci->ac97_sem); + down(&aaci->ac97_sem); aaci_ac97_select_codec(aaci, ac97); @@ -91,7 +91,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned v = readl(aaci->base + AACI_SLFR); } while (v & (SLFR_1TXB|SLFR_2TXB)); - mutex_unlock(&aaci->ac97_sem); + up(&aaci->ac97_sem); } /* @@ -105,7 +105,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) if (ac97->num >= 4) return ~0; - mutex_lock(&aaci->ac97_sem); + down(&aaci->ac97_sem); aaci_ac97_select_codec(aaci, ac97); @@ -145,7 +145,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) v = ~0; } - mutex_unlock(&aaci->ac97_sem); + up(&aaci->ac97_sem); return v; } @@ -783,7 +783,7 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) card->shortname, dev->res.start, dev->irq[0]); aaci = card->private_data; - mutex_init(&aaci->ac97_sem); + init_MUTEX(&aaci->ac97_sem); spin_lock_init(&aaci->lock); aaci->card = card; aaci->dev = dev; diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h index 062951906..83f73c250 100644 --- a/sound/arm/aaci.h +++ b/sound/arm/aaci.h @@ -227,7 +227,7 @@ struct aaci { unsigned int fifosize; /* AC'97 */ - struct mutex ac97_sem; + struct semaphore ac97_sem; ac97_bus_t *ac97_bus; u32 maincr; diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 599aff829..3acbc6023 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -33,7 +33,7 @@ #include "pxa2xx-pcm.h" -static DEFINE_MUTEX(car_mutex); +static DECLARE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; @@ -52,7 +52,7 @@ static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg unsigned short val = -1; volatile u32 *reg_addr; - mutex_lock(&car_mutex); + down(&car_mutex); /* set up primary or secondary codec space */ reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; @@ -79,7 +79,7 @@ static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg /* but we've just started another cycle... */ wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); -out: mutex_unlock(&car_mutex); +out: up(&car_mutex); return val; } @@ -87,7 +87,7 @@ static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigne { volatile u32 *reg_addr; - mutex_lock(&car_mutex); + down(&car_mutex); /* set up primary or secondary codec space */ reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; @@ -101,7 +101,7 @@ static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigne printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", __FUNCTION__, reg, GSR | gsr_bits); - mutex_unlock(&car_mutex); + up(&car_mutex); } static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 4262a1c87..f79755f77 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -73,15 +73,6 @@ config SND_PCM_OSS To compile this driver as a module, choose M here: the module will be called snd-pcm-oss. -config SND_PCM_OSS_PLUGINS - bool "OSS PCM (digital audio) API - Include plugin system" - depends on SND_PCM_OSS - default y - help - If you disable this option, the ALSA's OSS PCM API will not - support conversion of channels, formats and rates. It will - behave like most of new OSS/Free drivers in 2.4/2.6 kernels. - config SND_SEQUENCER_OSS bool "OSS Sequencer API" depends on SND && SND_SEQUENCER @@ -92,9 +83,8 @@ config SND_SEQUENCER_OSS Many programs still use the OSS API, so say Y. - If you choose M in "Sequencer support" (SND_SEQUENCER), - this will be compiled as a module. The module will be called - snd-seq-oss. + To compile this driver as a module, choose M here: the module + will be called snd-seq-oss. config SND_RTCTIMER tristate "RTC Timer support" @@ -140,15 +130,6 @@ config SND_SUPPORT_OLD_API Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3 or older). -config SND_VERBOSE_PROCFS - bool "Verbose procfs contents" - depends on SND && PROC_FS - default y - help - Say Y here to include code for verbose procfs contents (provides - usefull information to developers when a problem occurs). On the - other side, it makes the ALSA subsystem larger. - config SND_VERBOSE_PRINTK bool "Verbose printk" depends on SND @@ -171,13 +152,3 @@ config SND_DEBUG_DETECT help Say Y here to enable extra-verbose log messages printed when detecting devices. - -config SND_PCM_XRUN_DEBUG - bool "Enable PCM ring buffer overrun/underrun debugging" - default n - depends on SND_DEBUG && SND_VERBOSE_PROCFS - help - Say Y to enable the PCM ring buffer overrun/underrun debugging. - It is usually not required, but if you have trouble with - sound clicking when system is loaded, it may help to determine - the process or driver which causes the scheduling gaps. diff --git a/sound/core/control.c b/sound/core/control.c index 22565c9b9..ebf68f126 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -309,29 +309,28 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) { struct snd_ctl_elem_id id; unsigned int idx; - int err = -EINVAL; + snd_assert(card != NULL, return -EINVAL); if (! kcontrol) - return err; - snd_assert(card != NULL, goto error); - snd_assert(kcontrol->info != NULL, goto error); + return -EINVAL; + snd_assert(kcontrol->info != NULL, return -EINVAL); id = kcontrol->id; down_write(&card->controls_rwsem); if (snd_ctl_find_id(card, &id)) { up_write(&card->controls_rwsem); + snd_ctl_free_one(kcontrol); snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", id.iface, id.device, id.subdevice, id.name, id.index); - err = -EBUSY; - goto error; + return -EBUSY; } if (snd_ctl_find_hole(card, kcontrol->count) < 0) { up_write(&card->controls_rwsem); - err = -ENOMEM; - goto error; + snd_ctl_free_one(kcontrol); + return -ENOMEM; } list_add_tail(&kcontrol->list, &card->controls); card->controls_count += kcontrol->count; @@ -341,10 +340,6 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); return 0; - - error: - snd_ctl_free_one(kcontrol); - return err; } /** @@ -663,11 +658,7 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl, if (copy_from_user(&info, _info, sizeof(info))) return -EFAULT; - snd_power_lock(ctl->card); - result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_info(ctl, &info); - snd_power_unlock(ctl->card); + result = snd_ctl_elem_info(ctl, &info); if (result >= 0) if (copy_to_user(_info, &info, sizeof(info))) return -EFAULT; @@ -717,11 +708,7 @@ static int snd_ctl_elem_read_user(struct snd_card *card, kfree(control); return -EFAULT; } - snd_power_lock(card); - result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_read(card, control); - snd_power_unlock(card); + result = snd_ctl_elem_read(card, control); if (result >= 0) if (copy_to_user(_control, control, sizeof(*control))) result = -EFAULT; @@ -771,7 +758,6 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, struct snd_ctl_elem_value __user *_control) { struct snd_ctl_elem_value *control; - struct snd_card *card; int result; control = kmalloc(sizeof(*control), GFP_KERNEL); @@ -781,12 +767,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, kfree(control); return -EFAULT; } - card = file->card; - snd_power_lock(card); - result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_write(card, file, control); - snd_power_unlock(card); + result = snd_ctl_elem_write(file->card, file, control); if (result >= 0) if (copy_to_user(_control, control, sizeof(*control))) result = -EFAULT; @@ -973,6 +954,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, if (ue == NULL) return -ENOMEM; ue->info = *info; + ue->info.access = 0; ue->elem_data = (char *)ue + sizeof(*ue); ue->elem_data_size = private_size; kctl.private_free = snd_ctl_elem_user_free; diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 7fdabea4b..a529b6297 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -22,7 +22,7 @@ #include -struct sndrv_ctl_elem_list32 { +struct snd_ctl_elem_list32 { u32 offset; u32 space; u32 used; @@ -31,9 +31,10 @@ struct sndrv_ctl_elem_list32 { unsigned char reserved[50]; } /* don't set packed attribute here */; -static int snd_ctl_elem_list_compat(snd_card_t *card, struct sndrv_ctl_elem_list32 __user *data32) +static int snd_ctl_elem_list_compat(struct snd_card *card, + struct snd_ctl_elem_list32 __user *data32) { - struct sndrv_ctl_elem_list __user *data; + struct snd_ctl_elem_list __user *data; compat_caddr_t ptr; int err; @@ -60,8 +61,8 @@ static int snd_ctl_elem_list_compat(snd_card_t *card, struct sndrv_ctl_elem_list * it uses union, so the things are not easy.. */ -struct sndrv_ctl_elem_info32 { - struct sndrv_ctl_elem_id id; // the size of struct is same +struct snd_ctl_elem_info32 { + struct snd_ctl_elem_id id; // the size of struct is same s32 type; u32 access; u32 count; @@ -87,12 +88,13 @@ struct sndrv_ctl_elem_info32 { unsigned char reserved[64]; } __attribute__((packed)); -static int snd_ctl_elem_info_compat(snd_ctl_file_t *ctl, struct sndrv_ctl_elem_info32 __user *data32) +static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, + struct snd_ctl_elem_info32 __user *data32) { - struct sndrv_ctl_elem_info *data; + struct snd_ctl_elem_info *data; int err; - data = kcalloc(1, sizeof(*data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (! data) return -ENOMEM; @@ -146,8 +148,8 @@ static int snd_ctl_elem_info_compat(snd_ctl_file_t *ctl, struct sndrv_ctl_elem_i } /* read / write */ -struct sndrv_ctl_elem_value32 { - struct sndrv_ctl_elem_id id; +struct snd_ctl_elem_value32 { + struct snd_ctl_elem_id id; unsigned int indirect; /* bit-field causes misalignment */ union { s32 integer[128]; @@ -161,10 +163,11 @@ struct sndrv_ctl_elem_value32 { /* get the value type and count of the control */ -static int get_ctl_type(snd_card_t *card, snd_ctl_elem_id_t *id, int *countp) +static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, + int *countp) { - snd_kcontrol_t *kctl; - snd_ctl_elem_info_t info; + struct snd_kcontrol *kctl; + struct snd_ctl_elem_info *info; int err; down_read(&card->controls_rwsem); @@ -173,13 +176,19 @@ static int get_ctl_type(snd_card_t *card, snd_ctl_elem_id_t *id, int *countp) up_read(&card->controls_rwsem); return -ENXIO; } - info.id = *id; - err = kctl->info(kctl, &info); + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (info == NULL) { + up_read(&card->controls_rwsem); + return -ENOMEM; + } + info->id = *id; + err = kctl->info(kctl, info); up_read(&card->controls_rwsem); if (err >= 0) { - err = info.type; - *countp = info.count; + err = info->type; + *countp = info->count; } + kfree(info); return err; } @@ -193,15 +202,15 @@ static int get_elem_size(int type, int count) case SNDRV_CTL_ELEM_TYPE_BYTES: return 512; case SNDRV_CTL_ELEM_TYPE_IEC958: - return sizeof(struct sndrv_aes_iec958); + return sizeof(struct snd_aes_iec958); default: return -1; } } -static int copy_ctl_value_from_user(snd_card_t *card, - struct sndrv_ctl_elem_value *data, - struct sndrv_ctl_elem_value32 __user *data32, +static int copy_ctl_value_from_user(struct snd_card *card, + struct snd_ctl_elem_value *data, + struct snd_ctl_elem_value32 __user *data32, int *typep, int *countp) { int i, type, count, size; @@ -242,8 +251,8 @@ static int copy_ctl_value_from_user(snd_card_t *card, } /* restore the value to 32bit */ -static int copy_ctl_value_to_user(struct sndrv_ctl_elem_value32 __user *data32, - struct sndrv_ctl_elem_value *data, +static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32, + struct snd_ctl_elem_value *data, int type, int count) { int i, size; @@ -265,13 +274,13 @@ static int copy_ctl_value_to_user(struct sndrv_ctl_elem_value32 __user *data32, return 0; } -static int snd_ctl_elem_read_user_compat(snd_card_t *card, - struct sndrv_ctl_elem_value32 __user *data32) +static int snd_ctl_elem_read_user_compat(struct snd_card *card, + struct snd_ctl_elem_value32 __user *data32) { - struct sndrv_ctl_elem_value *data; + struct snd_ctl_elem_value *data; int err, type, count; - data = kcalloc(1, sizeof(*data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -285,13 +294,13 @@ static int snd_ctl_elem_read_user_compat(snd_card_t *card, return err; } -static int snd_ctl_elem_write_user_compat(snd_ctl_file_t *file, - struct sndrv_ctl_elem_value32 __user *data32) +static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file, + struct snd_ctl_elem_value32 __user *data32) { - struct sndrv_ctl_elem_value *data; + struct snd_ctl_elem_value *data; int err, type, count; - data = kcalloc(1, sizeof(*data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -306,14 +315,14 @@ static int snd_ctl_elem_write_user_compat(snd_ctl_file_t *file, } /* add or replace a user control */ -static int snd_ctl_elem_add_compat(snd_ctl_file_t *file, - struct sndrv_ctl_elem_info32 __user *data32, +static int snd_ctl_elem_add_compat(struct snd_ctl_file *file, + struct snd_ctl_elem_info32 __user *data32, int replace) { - struct sndrv_ctl_elem_info *data; + struct snd_ctl_elem_info *data; int err; - data = kcalloc(1, sizeof(*data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (! data) return -ENOMEM; @@ -355,17 +364,17 @@ static int snd_ctl_elem_add_compat(snd_ctl_file_t *file, } enum { - SNDRV_CTL_IOCTL_ELEM_LIST32 = _IOWR('U', 0x10, struct sndrv_ctl_elem_list32), - SNDRV_CTL_IOCTL_ELEM_INFO32 = _IOWR('U', 0x11, struct sndrv_ctl_elem_info32), - SNDRV_CTL_IOCTL_ELEM_READ32 = _IOWR('U', 0x12, struct sndrv_ctl_elem_value32), - SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct sndrv_ctl_elem_value32), - SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct sndrv_ctl_elem_info32), - SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct sndrv_ctl_elem_info32), + SNDRV_CTL_IOCTL_ELEM_LIST32 = _IOWR('U', 0x10, struct snd_ctl_elem_list32), + SNDRV_CTL_IOCTL_ELEM_INFO32 = _IOWR('U', 0x11, struct snd_ctl_elem_info32), + SNDRV_CTL_IOCTL_ELEM_READ32 = _IOWR('U', 0x12, struct snd_ctl_elem_value32), + SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32), + SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32), + SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32), }; static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) { - snd_ctl_file_t *ctl; + struct snd_ctl_file *ctl; struct list_head *list; void __user *argp = compat_ptr(arg); int err; @@ -398,7 +407,7 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns down_read(&snd_ioctl_rwsem); list_for_each(list, &snd_control_compat_ioctls) { - snd_kctl_ioctl_t *p = list_entry(list, snd_kctl_ioctl_t, list); + struct snd_kctl_ioctl *p = list_entry(list, struct snd_kctl_ioctl, list); if (p->fioctl) { err = p->fioctl(ctl->card, ctl, cmd, arg); if (err != -ENOIOCTLCMD) { diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 2524e66ec..618c43be0 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -37,7 +36,7 @@ MODULE_DESCRIPTION("Hardware dependent layer"); MODULE_LICENSE("GPL"); static LIST_HEAD(snd_hwdep_devices); -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); static int snd_hwdep_free(struct snd_hwdep *hwdep); static int snd_hwdep_dev_free(struct snd_device *device); @@ -112,7 +111,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) init_waitqueue_entry(&wait, current); add_wait_queue(&hw->open_wait, &wait); - mutex_lock(&hw->open_mutex); + down(&hw->open_mutex); while (1) { if (hw->exclusive && hw->used > 0) { err = -EBUSY; @@ -129,9 +128,9 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) } else break; set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&hw->open_mutex); + up(&hw->open_mutex); schedule(); - mutex_lock(&hw->open_mutex); + down(&hw->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -148,7 +147,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) hw->ops.release(hw, file); } } - mutex_unlock(&hw->open_mutex); + up(&hw->open_mutex); if (err < 0) module_put(hw->card->module); return err; @@ -158,7 +157,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) { int err = -ENXIO; struct snd_hwdep *hw = file->private_data; - mutex_lock(&hw->open_mutex); + down(&hw->open_mutex); if (hw->ops.release) { err = hw->ops.release(hw, file); wake_up(&hw->open_wait); @@ -166,7 +165,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) if (hw->used > 0) hw->used--; snd_card_file_remove(hw->card, file); - mutex_unlock(&hw->open_mutex); + up(&hw->open_mutex); module_put(hw->card->module); return err; } @@ -273,7 +272,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)arg)) return -EFAULT; - mutex_lock(®ister_mutex); + down(®ister_mutex); device = device < 0 ? 0 : device + 1; while (device < SNDRV_MINOR_HWDEPS) { if (snd_hwdep_search(card, device)) @@ -282,7 +281,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, } if (device >= SNDRV_MINOR_HWDEPS) device = -1; - mutex_unlock(®ister_mutex); + up(®ister_mutex); if (put_user(device, (int __user *)arg)) return -EFAULT; return 0; @@ -295,13 +294,13 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, if (get_user(device, &info->device)) return -EFAULT; - mutex_lock(®ister_mutex); + down(®ister_mutex); hwdep = snd_hwdep_search(card, device); if (hwdep) err = snd_hwdep_info(hwdep, info); else err = -ENXIO; - mutex_unlock(®ister_mutex); + up(®ister_mutex); return err; } } @@ -376,7 +375,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, return err; } init_waitqueue_head(&hwdep->open_wait); - mutex_init(&hwdep->open_mutex); + init_MUTEX(&hwdep->open_mutex); *rhwdep = hwdep; return 0; } @@ -402,9 +401,9 @@ static int snd_hwdep_dev_register(struct snd_device *device) int err; char name[32]; - mutex_lock(®ister_mutex); + down(®ister_mutex); if (snd_hwdep_search(hwdep->card, hwdep->device)) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -EBUSY; } list_add_tail(&hwdep->list, &snd_hwdep_devices); @@ -415,7 +414,7 @@ static int snd_hwdep_dev_register(struct snd_device *device) snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n", hwdep->card->number, hwdep->device); list_del(&hwdep->list); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return err; } #ifdef CONFIG_SND_OSSEMUL @@ -435,7 +434,7 @@ static int snd_hwdep_dev_register(struct snd_device *device) } } #endif - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } @@ -444,9 +443,9 @@ static int snd_hwdep_dev_unregister(struct snd_device *device) struct snd_hwdep *hwdep = device->device_data; snd_assert(hwdep != NULL, return -ENXIO); - mutex_lock(®ister_mutex); + down(®ister_mutex); if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -EINVAL; } #ifdef CONFIG_SND_OSSEMUL @@ -455,7 +454,7 @@ static int snd_hwdep_dev_unregister(struct snd_device *device) #endif snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); list_del(&hwdep->list); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return snd_hwdep_free(hwdep); } @@ -470,13 +469,13 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry, struct list_head *p; struct snd_hwdep *hwdep; - mutex_lock(®ister_mutex); + down(®ister_mutex); list_for_each(p, &snd_hwdep_devices) { hwdep = list_entry(p, struct snd_hwdep, list); snd_iprintf(buffer, "%02i-%02i: %s\n", hwdep->card->number, hwdep->device, hwdep->name); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); } static struct snd_info_entry *snd_hwdep_proc_entry; diff --git a/sound/core/info.c b/sound/core/info.c index 2582b74d3..af123e3bd 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -31,7 +31,6 @@ #include #include #include -#include #include /* @@ -69,7 +68,7 @@ int snd_info_check_reserved_words(const char *str) return 1; } -static DEFINE_MUTEX(info_mutex); +static DECLARE_MUTEX(info_mutex); struct snd_info_private_data { struct snd_info_buffer *rbuffer; @@ -266,11 +265,11 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) struct proc_dir_entry *p; int mode, err; - mutex_lock(&info_mutex); + down(&info_mutex); p = PDE(inode); entry = p == NULL ? NULL : (struct snd_info_entry *)p->data; if (entry == NULL || entry->disconnected) { - mutex_unlock(&info_mutex); + up(&info_mutex); return -ENODEV; } if (!try_module_get(entry->module)) { @@ -362,13 +361,13 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) break; } file->private_data = data; - mutex_unlock(&info_mutex); + up(&info_mutex); if (entry->content == SNDRV_INFO_CONTENT_TEXT && (mode == O_RDONLY || mode == O_RDWR)) { if (entry->c.text.read) { - mutex_lock(&entry->access); + down(&entry->access); entry->c.text.read(entry, data->rbuffer); - mutex_unlock(&entry->access); + up(&entry->access); } } return 0; @@ -376,7 +375,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) __error: module_put(entry->module); __error1: - mutex_unlock(&info_mutex); + up(&info_mutex); return err; } @@ -748,7 +747,7 @@ static struct snd_info_entry *snd_info_create_entry(const char *name) } entry->mode = S_IFREG | S_IRUGO; entry->content = SNDRV_INFO_CONTENT_TEXT; - mutex_init(&entry->access); + init_MUTEX(&entry->access); return entry; } @@ -897,10 +896,10 @@ int snd_info_register(struct snd_info_entry * entry) snd_assert(entry != NULL, return -ENXIO); root = entry->parent == NULL ? snd_proc_root : entry->parent->p; - mutex_lock(&info_mutex); + down(&info_mutex); p = snd_create_proc_entry(entry->name, entry->mode, root); if (!p) { - mutex_unlock(&info_mutex); + up(&info_mutex); return -ENOMEM; } p->owner = entry->module; @@ -909,7 +908,7 @@ int snd_info_register(struct snd_info_entry * entry) p->size = entry->size; p->data = entry; entry->p = p; - mutex_unlock(&info_mutex); + up(&info_mutex); return 0; } @@ -930,9 +929,9 @@ int snd_info_unregister(struct snd_info_entry * entry) snd_assert(entry->p != NULL, return -ENXIO); root = entry->parent == NULL ? snd_proc_root : entry->parent->p; snd_assert(root, return -ENXIO); - mutex_lock(&info_mutex); + down(&info_mutex); snd_remove_proc_entry(root, entry->p); - mutex_unlock(&info_mutex); + up(&info_mutex); snd_info_free_entry(entry); return 0; } diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c index f9ce854b3..820f4772e 100644 --- a/sound/core/info_oss.c +++ b/sound/core/info_oss.c @@ -28,7 +28,6 @@ #include #include #include -#include #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) @@ -36,7 +35,7 @@ * OSS compatible part */ -static DEFINE_MUTEX(strings); +static DECLARE_MUTEX(strings); static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT]; static struct snd_info_entry *snd_sndstat_proc_entry; @@ -46,7 +45,7 @@ int snd_oss_info_register(int dev, int num, char *string) snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO); snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO); - mutex_lock(&strings); + down(&strings); if (string == NULL) { if ((x = snd_sndstat_strings[num][dev]) != NULL) { kfree(x); @@ -55,12 +54,12 @@ int snd_oss_info_register(int dev, int num, char *string) } else { x = kstrdup(string, GFP_KERNEL); if (x == NULL) { - mutex_unlock(&strings); + up(&strings); return -ENOMEM; } } snd_sndstat_strings[num][dev] = x; - mutex_unlock(&strings); + up(&strings); return 0; } @@ -72,7 +71,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d char *str; snd_iprintf(buf, "\n%s:", id); - mutex_lock(&strings); + down(&strings); for (idx = 0; idx < SNDRV_CARDS; idx++) { str = snd_sndstat_strings[idx][dev]; if (str) { @@ -83,7 +82,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d snd_iprintf(buf, "%i: %s\n", idx, str); } } - mutex_unlock(&strings); + up(&strings); if (ok < 0) snd_iprintf(buf, " NOT ENABLED IN CONFIG\n"); return ok; diff --git a/sound/core/init.c b/sound/core/init.c index 39ed2e5bb..758166886 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -145,7 +145,7 @@ struct snd_card *snd_card_new(int idx, const char *xid, init_waitqueue_head(&card->shutdown_sleep); INIT_WORK(&card->free_workq, snd_card_free_thread, card); #ifdef CONFIG_PM - mutex_init(&card->power_lock); + init_MUTEX(&card->power_lock); init_waitqueue_head(&card->power_sleep); #endif /* the control interface cannot be accessed from the user space until */ @@ -169,44 +169,11 @@ struct snd_card *snd_card_new(int idx, const char *xid, return NULL; } -static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) -{ - return -ENODEV; -} - -static ssize_t snd_disconnect_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return -ENODEV; -} - -static ssize_t snd_disconnect_write(struct file *file, const char __user *buf, - size_t count, loff_t *offset) -{ - return -ENODEV; -} - static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) { return POLLERR | POLLNVAL; } -static long snd_disconnect_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - return -ENODEV; -} - -static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma) -{ - return -ENODEV; -} - -static int snd_disconnect_fasync(int fd, struct file *file, int on) -{ - return -ENODEV; -} - /** * snd_card_disconnect - disconnect all APIs from the file-operations (user space) * @card: soundcard structure @@ -223,8 +190,7 @@ int snd_card_disconnect(struct snd_card *card) struct snd_monitor_file *mfile; struct file *file; struct snd_shutdown_f_ops *s_f_ops; - struct file_operations *f_ops; - const struct file_operations *old_f_ops; + struct file_operations *f_ops, *old_f_ops; int err; spin_lock(&card->files_lock); @@ -258,16 +224,7 @@ int snd_card_disconnect(struct snd_card *card) memset(f_ops, 0, sizeof(*f_ops)); f_ops->owner = file->f_op->owner; f_ops->release = file->f_op->release; - f_ops->llseek = snd_disconnect_llseek; - f_ops->read = snd_disconnect_read; - f_ops->write = snd_disconnect_write; f_ops->poll = snd_disconnect_poll; - f_ops->unlocked_ioctl = snd_disconnect_ioctl; -#ifdef CONFIG_COMPAT - f_ops->compat_ioctl = snd_disconnect_ioctl; -#endif - f_ops->mmap = snd_disconnect_mmap; - f_ops->fasync = snd_disconnect_fasync; s_f_ops->next = card->s_f_ops; card->s_f_ops = s_f_ops; @@ -722,12 +679,13 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) * snd_power_wait - wait until the power-state is changed. * @card: soundcard structure * @power_state: expected power state + * @file: file structure for the O_NONBLOCK check (optional) * * Waits until the power-state is changed. * * Note: the power lock must be active before call. */ -int snd_power_wait(struct snd_card *card, unsigned int power_state) +int snd_power_wait(struct snd_card *card, unsigned int power_state, struct file *file) { wait_queue_t wait; int result = 0; @@ -744,6 +702,12 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state) } if (snd_power_get_state(card) == power_state) break; +#if 0 /* block all devices */ + if (file && (file->f_flags & O_NONBLOCK)) { + result = -EAGAIN; + break; + } +#endif set_current_state(TASK_UNINTERRUPTIBLE); snd_power_unlock(card); schedule_timeout(30 * HZ); diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 3fc6f9707..19b3dcbb0 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_SBUS #include @@ -54,7 +54,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab); /* */ -static DEFINE_MUTEX(list_mutex); +static DECLARE_MUTEX(list_mutex); static LIST_HEAD(mem_list_head); /* buffer preservation list */ @@ -83,7 +83,7 @@ struct snd_mem_list { * Hacks */ -#if defined(__i386__) +#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__) /* * A hack to allocate large buffers via dma_alloc_coherent() * @@ -141,6 +141,10 @@ static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size, #endif /* arch */ +#if ! defined(__arm__) +#define NEED_RESERVE_PAGES +#endif + /* * * Generic memory allocators @@ -159,6 +163,20 @@ static inline void dec_snd_pages(int order) snd_allocated_pages -= 1 << order; } +static void mark_pages(struct page *page, int order) +{ + struct page *last_page = page + (1 << order); + while (page < last_page) + SetPageReserved(page++); +} + +static void unmark_pages(struct page *page, int order) +{ + struct page *last_page = page + (1 << order); + while (page < last_page) + ClearPageReserved(page++); +} + /** * snd_malloc_pages - allocate pages with the given size * @size: the size to allocate in bytes @@ -177,8 +195,10 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags) snd_assert(gfp_flags != 0, return NULL); gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */ pg = get_order(size); - if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) + if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) { + mark_pages(virt_to_page(res), pg); inc_snd_pages(pg); + } return res; } @@ -197,6 +217,7 @@ void snd_free_pages(void *ptr, size_t size) return; pg = get_order(size); dec_snd_pages(pg); + unmark_pages(virt_to_page(ptr), pg); free_pages((unsigned long) ptr, pg); } @@ -221,8 +242,12 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d | __GFP_NORETRY /* don't trigger OOM-killer */ | __GFP_NOWARN; /* no stack trace print - this call is non-critical */ res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags); - if (res != NULL) + if (res != NULL) { +#ifdef NEED_RESERVE_PAGES + mark_pages(virt_to_page(res), pg); /* should be dma_to_page() */ +#endif inc_snd_pages(pg); + } return res; } @@ -237,6 +262,9 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr, return; pg = get_order(size); dec_snd_pages(pg); +#ifdef NEED_RESERVE_PAGES + unmark_pages(virt_to_page(ptr), pg); /* should be dma_to_page() */ +#endif dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma); } @@ -412,7 +440,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) snd_assert(dmab, return 0); - mutex_lock(&list_mutex); + down(&list_mutex); list_for_each(p, &mem_list_head) { mem = list_entry(p, struct snd_mem_list, list); if (mem->id == id && @@ -424,11 +452,11 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) if (dmab->dev.dev == NULL) dmab->dev.dev = dev; kfree(mem); - mutex_unlock(&list_mutex); + up(&list_mutex); return dmab->bytes; } } - mutex_unlock(&list_mutex); + up(&list_mutex); return 0; } @@ -449,11 +477,11 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id) mem = kmalloc(sizeof(*mem), GFP_KERNEL); if (! mem) return -ENOMEM; - mutex_lock(&list_mutex); + down(&list_mutex); mem->buffer = *dmab; mem->id = id; list_add_tail(&mem->list, &mem_list_head); - mutex_unlock(&list_mutex); + up(&list_mutex); return 0; } @@ -465,7 +493,7 @@ static void free_all_reserved_pages(void) struct list_head *p; struct snd_mem_list *mem; - mutex_lock(&list_mutex); + down(&list_mutex); while (! list_empty(&mem_list_head)) { p = mem_list_head.next; mem = list_entry(p, struct snd_mem_list, list); @@ -473,7 +501,7 @@ static void free_all_reserved_pages(void) snd_dma_free_pages(&mem->buffer); kfree(mem); } - mutex_unlock(&list_mutex); + up(&list_mutex); } @@ -494,7 +522,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, int devno; static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; - mutex_lock(&list_mutex); + down(&list_mutex); len += snprintf(page + len, count - len, "pages : %li bytes (%li pages per %likB)\n", pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); @@ -509,7 +537,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, " addr = 0x%lx, size = %d bytes\n", (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes); } - mutex_unlock(&list_mutex); + up(&list_mutex); return len; } diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c index 6658facc5..d6a04c2d5 100644 --- a/sound/core/oss/copy.c +++ b/sound/core/oss/copy.c @@ -20,9 +20,6 @@ */ #include - -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - #include #include #include @@ -88,5 +85,3 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } - -#endif diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c index b6e7ce30e..322702e05 100644 --- a/sound/core/oss/io.c +++ b/sound/core/oss/io.c @@ -20,9 +20,6 @@ */ #include - -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - #include #include #include @@ -135,5 +132,3 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } - -#endif diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c index 5b1bcdc64..8cbfa415c 100644 --- a/sound/core/oss/linear.c +++ b/sound/core/oss/linear.c @@ -21,9 +21,6 @@ */ #include - -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - #include #include #include @@ -106,7 +103,7 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin, return frames; } -static int conv_index(int src_format, int dst_format) +int conv_index(int src_format, int dst_format) { int src_endian, dst_endian, sign, src_width, dst_width; @@ -159,5 +156,3 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } - -#endif diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 9c68bc3f9..f08e65a2b 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -1095,7 +1095,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry, struct snd_mixer_oss *mixer = entry->private_data; int i; - mutex_lock(&mixer->reg_mutex); + down(&mixer->reg_mutex); for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) { struct slot *p; @@ -1110,7 +1110,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry, else snd_iprintf(buffer, "\"\" 0\n"); } - mutex_unlock(&mixer->reg_mutex); + up(&mixer->reg_mutex); } static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, @@ -1134,9 +1134,9 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, cptr = snd_info_get_str(str, cptr, sizeof(str)); if (! *str) { /* remove the entry */ - mutex_lock(&mixer->reg_mutex); + down(&mixer->reg_mutex); mixer_slot_clear(&mixer->slots[ch]); - mutex_unlock(&mixer->reg_mutex); + up(&mixer->reg_mutex); continue; } snd_info_get_str(idxstr, cptr, sizeof(idxstr)); @@ -1145,7 +1145,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx); continue; } - mutex_lock(&mixer->reg_mutex); + down(&mixer->reg_mutex); slot = (struct slot *)mixer->slots[ch].private_data; if (slot && slot->assigned && slot->assigned->index == idx && ! strcmp(slot->assigned->name, str)) @@ -1168,7 +1168,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, kfree(tbl); } __unlock: - mutex_unlock(&mixer->reg_mutex); + up(&mixer->reg_mutex); } } @@ -1288,7 +1288,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd) mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL); if (mixer == NULL) return -ENOMEM; - mutex_init(&mixer->reg_mutex); + init_MUTEX(&mixer->reg_mutex); sprintf(name, "mixer%i%i", card->number, 0); if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, card, 0, diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c index 2eb18807e..14f5578ec 100644 --- a/sound/core/oss/mulaw.c +++ b/sound/core/oss/mulaw.c @@ -22,9 +22,6 @@ */ #include - -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - #include #include #include @@ -265,25 +262,6 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin, return frames; } -static int getput_index(int format) -{ - int sign, width, endian; - sign = !snd_pcm_format_signed(format); - width = snd_pcm_format_width(format) / 8 - 1; - if (width < 0 || width > 3) { - snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format); - width = 0; - } -#ifdef SNDRV_LITTLE_ENDIAN - endian = snd_pcm_format_big_endian(format); -#else - endian = snd_pcm_format_little_endian(format); -#endif - if (endian < 0) - endian = 0; - return width * 4 + endian * 2 + sign; -} - int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, struct snd_pcm_plugin_format *src_format, struct snd_pcm_plugin_format *dst_format, @@ -328,5 +306,3 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } - -#endif diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 0691aca51..7fd072392 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -78,7 +78,6 @@ static inline void snd_leave_user(mm_segment_t fs) set_fs(fs); } -#ifdef CONFIG_SND_PCM_OSS_PLUGINS static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -123,7 +122,6 @@ int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin) } return 0; } -#endif /* CONFIG_SND_PCM_OSS_PLUGINS */ static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames) { @@ -208,8 +206,9 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, oss_buffer_size = runtime->oss.mmap_bytes; } - if (substream->oss.setup.period_size > 16) - oss_period_size = substream->oss.setup.period_size; + if (substream->oss.setup && + substream->oss.setup->period_size > 16) + oss_period_size = substream->oss.setup->period_size; else if (runtime->oss.fragshift) { oss_period_size = 1 << runtime->oss.fragshift; if (oss_period_size > oss_buffer_size / 2) @@ -251,8 +250,10 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, oss_periods = oss_buffer_size / oss_period_size; - if (substream->oss.setup.periods > 1) - oss_periods = substream->oss.setup.periods; + if (substream->oss.setup) { + if (substream->oss.setup->periods > 1) + oss_periods = substream->oss.setup->periods; + } s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL); if (runtime->oss.maxfrags && s > runtime->oss.maxfrags) @@ -338,10 +339,12 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) goto failure; } - if (atomic_read(&runtime->mmap_count)) + if (atomic_read(&runtime->mmap_count)) { direct = 1; - else - direct = substream->oss.setup.direct; + } else { + struct snd_pcm_oss_setup *setup = substream->oss.setup; + direct = (setup != NULL && setup->direct); + } _snd_pcm_hw_params_any(sparams); _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS); @@ -409,7 +412,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) oss_frame_size = snd_pcm_format_physical_width(params_format(params)) * params_channels(params) / 8; -#ifdef CONFIG_SND_PCM_OSS_PLUGINS snd_pcm_oss_plugin_clear(substream); if (!direct) { /* add necessary plugins */ @@ -439,7 +441,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) } } } -#endif err = snd_pcm_oss_period_size(substream, params, sparams); if (err < 0) @@ -477,7 +478,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) 1 : runtime->period_size; sw_params->xfer_align = 1; if (atomic_read(&runtime->mmap_count) || - substream->oss.setup.nosilence) { + (substream->oss.setup && substream->oss.setup->nosilence)) { sw_params->silence_threshold = 0; sw_params->silence_size = 0; } else { @@ -497,13 +498,11 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) runtime->oss.periods = params_periods(sparams); oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams)); snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure); -#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first) { err = snd_pcm_plug_alloc(substream, oss_period_size); if (err < 0) goto failure; } -#endif oss_period_size *= oss_frame_size; oss_buffer_size = oss_period_size * runtime->oss.periods; @@ -785,7 +784,6 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_sframes_t frames, frames1; -#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first) { struct snd_pcm_plugin_channel *channels; size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; @@ -802,9 +800,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha if (frames1 <= 0) return frames1; bytes = frames1 * oss_frame_bytes; - } else -#endif - { + } else { frames = bytes_to_frames(runtime, bytes); frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel); if (frames1 <= 0) @@ -838,7 +834,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha buf += tmp; bytes -= tmp; xfer += tmp; - if (substream->oss.setup.partialfrag || + if ((substream->oss.setup != NULL && substream->oss.setup->partialfrag) || runtime->oss.buffer_used == runtime->oss.period_bytes) { tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr, runtime->oss.buffer_used - runtime->oss.period_ptr, 1); @@ -875,7 +871,6 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_sframes_t frames, frames1; -#ifdef CONFIG_SND_PCM_OSS_PLUGINS char __user *final_dst = (char __user *)buf; if (runtime->oss.plugin_first) { struct snd_pcm_plugin_channel *channels; @@ -892,9 +887,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, bytes = frames1 * oss_frame_bytes; if (!in_kernel && copy_to_user(final_dst, buf, bytes)) return -EFAULT; - } else -#endif - { + } else { frames = bytes_to_frames(runtime, bytes); frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel); if (frames1 <= 0) @@ -954,12 +947,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file) substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; if (substream != NULL) { - snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); substream->runtime->oss.prepare = 1; } substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; if (substream != NULL) { - snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + snd_pcm_kernel_capture_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); substream->runtime->oss.prepare = 1; } return 0; @@ -974,7 +967,7 @@ static int snd_pcm_oss_post(struct snd_pcm_oss_file *pcm_oss_file) if (substream != NULL) { if ((err = snd_pcm_oss_make_ready(substream)) < 0) return err; - snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL); + snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL); } /* note: all errors from the start action are ignored */ /* OSS apps do not know, how to handle them */ @@ -1103,7 +1096,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) __direct: saved_f_flags = substream->ffile->f_flags; substream->ffile->f_flags &= ~O_NONBLOCK; - err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); + err = snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); substream->ffile->f_flags = saved_f_flags; if (err < 0) return err; @@ -1115,7 +1108,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) if ((err = snd_pcm_oss_make_ready(substream)) < 0) return err; runtime = substream->runtime; - err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + err = snd_pcm_kernel_capture_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); if (err < 0) return err; runtime->oss.buffer_used = 0; @@ -1209,10 +1202,12 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) return err; - if (atomic_read(&substream->runtime->mmap_count)) + if (atomic_read(&substream->runtime->mmap_count)) { direct = 1; - else - direct = substream->oss.setup.direct; + } else { + struct snd_pcm_oss_setup *setup = substream->oss.setup; + direct = (setup != NULL && setup->direct); + } if (!direct) return AFMT_MU_LAW | AFMT_U8 | AFMT_S16_LE | AFMT_S16_BE | @@ -1242,8 +1237,6 @@ static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int for if (format != AFMT_QUERY) { formats = snd_pcm_oss_get_formats(pcm_oss_file); - if (formats < 0) - return formats; if (!(formats & format)) format = AFMT_U8; for (idx = 1; idx >= 0; --idx) { @@ -1432,7 +1425,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr cmd = SNDRV_PCM_IOCTL_DROP; runtime->oss.prepare = 1; } - err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL); + err = snd_pcm_kernel_playback_ioctl(psubstream, cmd, NULL); if (err < 0) return err; } @@ -1453,7 +1446,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr cmd = SNDRV_PCM_IOCTL_DROP; runtime->oss.prepare = 1; } - err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL); + err = snd_pcm_kernel_capture_ioctl(csubstream, cmd, NULL); if (err < 0) return err; } @@ -1490,7 +1483,7 @@ static int snd_pcm_oss_get_odelay(struct snd_pcm_oss_file *pcm_oss_file) runtime = substream->runtime; if (runtime->oss.params || runtime->oss.prepare) return 0; - err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay); + err = snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay); if (err == -EPIPE) delay = 0; /* hack for broken OSS applications */ else if (err < 0) @@ -1550,7 +1543,8 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream } else { delay = snd_pcm_oss_bytes(substream, delay); if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (substream->oss.setup.buggyptr) + struct snd_pcm_oss_setup *setup = substream->oss.setup; + if (setup && setup->buggyptr) info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes; else info.blocks = (delay + fixup) / runtime->oss.period_bytes; @@ -1632,46 +1626,37 @@ static int snd_pcm_oss_get_mapbuf(struct snd_pcm_oss_file *pcm_oss_file, int str return -EINVAL; } -static const char *strip_task_path(const char *path) +static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream, const char *task_name) { - const char *ptr, *ptrl = NULL; - for (ptr = path; *ptr; ptr++) { + const char *ptr, *ptrl; + struct snd_pcm_oss_setup *setup; + + down(&pcm->streams[stream].oss.setup_mutex); + for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { + if (!strcmp(setup->task_name, task_name)) { + up(&pcm->streams[stream].oss.setup_mutex); + return setup; + } + } + ptr = ptrl = task_name; + while (*ptr) { if (*ptr == '/') ptrl = ptr + 1; + ptr++; } - return ptrl; -} - -static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream, - const char *task_name, - struct snd_pcm_oss_setup *rsetup) -{ - struct snd_pcm_oss_setup *setup; - - mutex_lock(&pcm->streams[stream].oss.setup_mutex); - do { - for (setup = pcm->streams[stream].oss.setup_list; setup; - setup = setup->next) { - if (!strcmp(setup->task_name, task_name)) - goto out; + if (ptrl == task_name) { + goto __not_found; + return NULL; + } + for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { + if (!strcmp(setup->task_name, ptrl)) { + up(&pcm->streams[stream].oss.setup_mutex); + return setup; } - } while ((task_name = strip_task_path(task_name)) != NULL); - out: - if (setup) - *rsetup = *setup; - mutex_unlock(&pcm->streams[stream].oss.setup_mutex); -} - -static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime; - runtime = substream->runtime; - vfree(runtime->oss.buffer); - runtime->oss.buffer = NULL; -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - snd_pcm_oss_plugin_clear(substream); -#endif - substream->oss.oss = 0; + } + __not_found: + up(&pcm->streams[stream].oss.setup_mutex); + return NULL; } static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, @@ -1681,11 +1666,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime; substream->oss.oss = 1; - substream->oss.setup = *setup; - if (setup->nonblock) - substream->ffile->f_flags |= O_NONBLOCK; - else if (setup->block) - substream->ffile->f_flags &= ~O_NONBLOCK; + substream->oss.setup = setup; runtime = substream->runtime; runtime->oss.params = 1; runtime->oss.trigger = 1; @@ -1704,7 +1685,16 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, runtime->oss.fragshift = 0; runtime->oss.maxfrags = 0; runtime->oss.subdivision = 0; - substream->pcm_release = snd_pcm_oss_release_substream; +} + +static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime; + runtime = substream->runtime; + vfree(runtime->oss.buffer); + snd_pcm_oss_plugin_clear(substream); + substream->oss.file = NULL; + substream->oss.oss = 0; } static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) @@ -1713,8 +1703,23 @@ static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) snd_assert(pcm_oss_file != NULL, return -ENXIO); for (cidx = 0; cidx < 2; ++cidx) { struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx]; - if (substream) - snd_pcm_release_substream(substream); + struct snd_pcm_runtime *runtime; + if (substream == NULL) + continue; + runtime = substream->runtime; + + snd_pcm_stream_lock_irq(substream); + if (snd_pcm_running(substream)) + snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); + snd_pcm_stream_unlock_irq(substream); + if (substream->ffile != NULL) { + if (substream->ops->hw_free != NULL) + substream->ops->hw_free(substream); + substream->ops->close(substream); + substream->ffile = NULL; + } + snd_pcm_oss_release_substream(substream); + snd_pcm_release_substream(substream); } kfree(pcm_oss_file); return 0; @@ -1724,11 +1729,12 @@ static int snd_pcm_oss_open_file(struct file *file, struct snd_pcm *pcm, struct snd_pcm_oss_file **rpcm_oss_file, int minor, - struct snd_pcm_oss_setup *setup) + struct snd_pcm_oss_setup *psetup, + struct snd_pcm_oss_setup *csetup) { - int idx, err; + int err = 0; struct snd_pcm_oss_file *pcm_oss_file; - struct snd_pcm_substream *substream; + struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL; unsigned int f_mode = file->f_mode; snd_assert(rpcm_oss_file != NULL, return -EINVAL); @@ -1741,34 +1747,73 @@ static int snd_pcm_oss_open_file(struct file *file, if ((f_mode & (FMODE_WRITE|FMODE_READ)) == (FMODE_WRITE|FMODE_READ) && (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) f_mode = FMODE_WRITE; - - for (idx = 0; idx < 2; idx++) { - if (setup[idx].disable) - continue; - if (! pcm->streams[idx].substream_count) - continue; /* no matching substream */ - if (idx == SNDRV_PCM_STREAM_PLAYBACK) { - if (! (f_mode & FMODE_WRITE)) - continue; - } else { - if (! (f_mode & FMODE_READ)) - continue; - } - err = snd_pcm_open_substream(pcm, idx, file, &substream); - if (err < 0) { + if ((f_mode & FMODE_WRITE) && !(psetup && psetup->disable)) { + if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &psubstream)) < 0) { snd_pcm_oss_release_file(pcm_oss_file); return err; } - - pcm_oss_file->streams[idx] = substream; - substream->file = pcm_oss_file; - snd_pcm_oss_init_substream(substream, &setup[idx], minor); + pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK] = psubstream; + } + if ((f_mode & FMODE_READ) && !(csetup && csetup->disable)) { + if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_CAPTURE, + &csubstream)) < 0) { + if (!(f_mode & FMODE_WRITE) || err != -ENODEV) { + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } else { + csubstream = NULL; + } + } + pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE] = csubstream; } - if (!pcm_oss_file->streams[0] && !pcm_oss_file->streams[1]) { + if (psubstream == NULL && csubstream == NULL) { snd_pcm_oss_release_file(pcm_oss_file); return -EINVAL; } + if (psubstream != NULL) { + psubstream->oss.file = pcm_oss_file; + err = snd_pcm_hw_constraints_init(psubstream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraint_init failed\n"); + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + if ((err = psubstream->ops->open(psubstream)) < 0) { + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + psubstream->ffile = file; + err = snd_pcm_hw_constraints_complete(psubstream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraint_complete failed\n"); + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + snd_pcm_oss_init_substream(psubstream, psetup, minor); + } + if (csubstream != NULL) { + csubstream->oss.file = pcm_oss_file; + err = snd_pcm_hw_constraints_init(csubstream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraint_init failed\n"); + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + if ((err = csubstream->ops->open(csubstream)) < 0) { + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + csubstream->ffile = file; + err = snd_pcm_hw_constraints_complete(csubstream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraint_complete failed\n"); + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + snd_pcm_oss_init_substream(csubstream, csetup, minor); + } file->private_data = pcm_oss_file; *rpcm_oss_file = pcm_oss_file; @@ -1793,16 +1838,9 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) char task_name[32]; struct snd_pcm *pcm; struct snd_pcm_oss_file *pcm_oss_file; - struct snd_pcm_oss_setup setup[2]; + struct snd_pcm_oss_setup *psetup = NULL, *csetup = NULL; int nonblock; wait_queue_t wait; - static char printed_comm[16]; - - if (strncmp(printed_comm, current->comm, 16)) { - printk(KERN_DEBUG "application %s uses obsolete OSS audio interface\n", - current->comm); - memcpy(printed_comm, current->comm, 16); - } pcm = snd_lookup_oss_minor_data(iminor(inode), SNDRV_OSS_DEVICE_TYPE_PCM); @@ -1821,24 +1859,32 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) err = -EFAULT; goto __error; } - memset(setup, 0, sizeof(setup)); if (file->f_mode & FMODE_WRITE) - snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK, - task_name, &setup[0]); + psetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK, task_name); if (file->f_mode & FMODE_READ) - snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE, - task_name, &setup[1]); + csetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE, task_name); nonblock = !!(file->f_flags & O_NONBLOCK); + if (psetup && !psetup->disable) { + if (psetup->nonblock) + nonblock = 1; + else if (psetup->block) + nonblock = 0; + } else if (csetup && !csetup->disable) { + if (csetup->nonblock) + nonblock = 1; + else if (csetup->block) + nonblock = 0; + } if (!nonblock) nonblock = nonblock_open; init_waitqueue_entry(&wait, current); add_wait_queue(&pcm->open_wait, &wait); - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); while (1) { err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, - iminor(inode), setup); + iminor(inode), psetup, csetup); if (err >= 0) break; if (err == -EAGAIN) { @@ -1849,16 +1895,16 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) } else break; set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); schedule(); - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; } } remove_wait_queue(&pcm->open_wait, &wait); - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); if (err < 0) goto __error; return err; @@ -1884,9 +1930,9 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file) snd_assert(substream != NULL, return -ENXIO); pcm = substream->pcm; snd_pcm_oss_sync(pcm_oss_file); - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); snd_pcm_oss_release_file(pcm_oss_file); - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); wake_up(&pcm->open_wait); module_put(pcm->card->module); snd_card_file_remove(pcm->card, file); @@ -2200,10 +2246,8 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) if ((err = snd_pcm_oss_change_params(substream)) < 0) return err; } -#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first != NULL) return -EIO; -#endif if (area->vm_pgoff != 0) return -EINVAL; @@ -2223,7 +2267,7 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) return 0; } -#ifdef CONFIG_SND_VERBOSE_PROCFS +#ifdef CONFIG_PROC_FS /* * /proc interface */ @@ -2233,7 +2277,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, { struct snd_pcm_str *pstr = entry->private_data; struct snd_pcm_oss_setup *setup = pstr->oss.setup_list; - mutex_lock(&pstr->oss.setup_mutex); + down(&pstr->oss.setup_mutex); while (setup) { snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n", setup->task_name, @@ -2247,13 +2291,18 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, setup->nosilence ? " no-silence" : ""); setup = setup->next; } - mutex_unlock(&pstr->oss.setup_mutex); + up(&pstr->oss.setup_mutex); } static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr) { + unsigned int idx; + struct snd_pcm_substream *substream; struct snd_pcm_oss_setup *setup, *setupn; + for (idx = 0, substream = pstr->substream; + idx < pstr->substream_count; idx++, substream = substream->next) + substream->oss.setup = NULL; for (setup = pstr->oss.setup_list, pstr->oss.setup_list = NULL; setup; setup = setupn) { setupn = setup->next; @@ -2272,12 +2321,12 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, struct snd_pcm_oss_setup *setup, *setup1, template; while (!snd_info_get_line(buffer, line, sizeof(line))) { - mutex_lock(&pstr->oss.setup_mutex); + down(&pstr->oss.setup_mutex); memset(&template, 0, sizeof(template)); ptr = snd_info_get_str(task_name, line, sizeof(task_name)); if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) { snd_pcm_oss_proc_free_setup_list(pstr); - mutex_unlock(&pstr->oss.setup_mutex); + up(&pstr->oss.setup_mutex); continue; } for (setup = pstr->oss.setup_list; setup; setup = setup->next) { @@ -2314,29 +2363,22 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, } } while (*str); if (setup == NULL) { - setup = kmalloc(sizeof(*setup), GFP_KERNEL); - if (! setup) { - buffer->error = -ENOMEM; - mutex_lock(&pstr->oss.setup_mutex); - return; - } - if (pstr->oss.setup_list == NULL) - pstr->oss.setup_list = setup; - else { - for (setup1 = pstr->oss.setup_list; - setup1->next; setup1 = setup1->next); - setup1->next = setup; - } - template.task_name = kstrdup(task_name, GFP_KERNEL); - if (! template.task_name) { - kfree(setup); + setup = kmalloc(sizeof(struct snd_pcm_oss_setup), GFP_KERNEL); + if (setup) { + if (pstr->oss.setup_list == NULL) { + pstr->oss.setup_list = setup; + } else { + for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next); + setup1->next = setup; + } + template.task_name = kstrdup(task_name, GFP_KERNEL); + } else { buffer->error = -ENOMEM; - mutex_lock(&pstr->oss.setup_mutex); - return; } } - *setup = template; - mutex_unlock(&pstr->oss.setup_mutex); + if (setup) + *setup = template; + up(&pstr->oss.setup_mutex); } } @@ -2377,10 +2419,10 @@ static void snd_pcm_oss_proc_done(struct snd_pcm *pcm) } } } -#else /* !CONFIG_SND_VERBOSE_PROCFS */ +#else /* !CONFIG_PROC_FS */ #define snd_pcm_oss_proc_init(pcm) #define snd_pcm_oss_proc_done(pcm) -#endif /* CONFIG_SND_VERBOSE_PROCFS */ +#endif /* CONFIG_PROC_FS */ /* * ENTRY functions diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 0e67dd280..7e8676880 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c @@ -25,9 +25,6 @@ #endif #include - -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - #include #include #include @@ -39,6 +36,26 @@ #define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first) #define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last) +static int snd_pcm_plugin_src_channels_mask(struct snd_pcm_plugin *plugin, + unsigned long *dst_vmask, + unsigned long **src_vmask) +{ + unsigned long *vmask = plugin->src_vmask; + bitmap_copy(vmask, dst_vmask, plugin->src_format.channels); + *src_vmask = vmask; + return 0; +} + +static int snd_pcm_plugin_dst_channels_mask(struct snd_pcm_plugin *plugin, + unsigned long *src_vmask, + unsigned long **dst_vmask) +{ + unsigned long *vmask = plugin->dst_vmask; + bitmap_copy(vmask, src_vmask, plugin->dst_format.channels); + *dst_vmask = vmask; + return 0; +} + /* * because some cards might have rates "very close", we ignore * all "resampling" requests within +-5% @@ -176,7 +193,19 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug, snd_pcm_plugin_free(plugin); return -ENOMEM; } + plugin->src_vmask = bitmap_alloc(src_format->channels); + if (plugin->src_vmask == NULL) { + snd_pcm_plugin_free(plugin); + return -ENOMEM; + } + plugin->dst_vmask = bitmap_alloc(dst_format->channels); + if (plugin->dst_vmask == NULL) { + snd_pcm_plugin_free(plugin); + return -ENOMEM; + } plugin->client_channels = snd_pcm_plugin_client_channels; + plugin->src_channels_mask = snd_pcm_plugin_src_channels_mask; + plugin->dst_channels_mask = snd_pcm_plugin_dst_channels_mask; *ret = plugin; return 0; } @@ -189,6 +218,8 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin) plugin->private_free(plugin); kfree(plugin->buf_channels); vfree(plugin->buf); + kfree(plugin->src_vmask); + kfree(plugin->dst_vmask); kfree(plugin); return 0; } @@ -398,14 +429,24 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, dstformat.channels); /* Format change (linearization) */ - if (! rate_match(srcformat.rate, dstformat.rate) && - ! snd_pcm_format_linear(srcformat.format)) { - if (srcformat.format != SNDRV_PCM_FORMAT_MU_LAW) + if ((srcformat.format != dstformat.format || + !rate_match(srcformat.rate, dstformat.rate) || + srcformat.channels != dstformat.channels) && + !snd_pcm_format_linear(srcformat.format)) { + if (snd_pcm_format_linear(dstformat.format)) + tmpformat.format = dstformat.format; + else + tmpformat.format = SNDRV_PCM_FORMAT_S16; + switch (srcformat.format) { + case SNDRV_PCM_FORMAT_MU_LAW: + err = snd_pcm_plugin_build_mulaw(plug, + &srcformat, &tmpformat, + &plugin); + break; + default: return -EINVAL; - tmpformat.format = SNDRV_PCM_FORMAT_S16; - err = snd_pcm_plugin_build_mulaw(plug, - &srcformat, &tmpformat, - &plugin); + } + pdprintf("format change: src=%i, dst=%i returns %i\n", srcformat.format, tmpformat.format, err); if (err < 0) return err; err = snd_pcm_plugin_append(plugin); @@ -419,11 +460,35 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, /* channels reduction */ if (srcformat.channels > dstformat.channels) { + int sv = srcformat.channels; + int dv = dstformat.channels; + int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL); + if (ttable == NULL) + return -ENOMEM; +#if 1 + if (sv == 2 && dv == 1) { + ttable[0] = HALF; + ttable[1] = HALF; + } else +#endif + { + int v; + for (v = 0; v < dv; ++v) + ttable[v * sv + v] = FULL; + } tmpformat.channels = dstformat.channels; - err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin); + if (rate_match(srcformat.rate, dstformat.rate) && + snd_pcm_format_linear(dstformat.format)) + tmpformat.format = dstformat.format; + err = snd_pcm_plugin_build_route(plug, + &srcformat, &tmpformat, + ttable, &plugin); + kfree(ttable); pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); - if (err < 0) + if (err < 0) { + snd_pcm_plugin_free(plugin); return err; + } err = snd_pcm_plugin_append(plugin); if (err < 0) { snd_pcm_plugin_free(plugin); @@ -435,29 +500,18 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, /* rate resampling */ if (!rate_match(srcformat.rate, dstformat.rate)) { - if (srcformat.format != SNDRV_PCM_FORMAT_S16) { - /* convert to S16 for resampling */ - tmpformat.format = SNDRV_PCM_FORMAT_S16; - err = snd_pcm_plugin_build_linear(plug, - &srcformat, &tmpformat, - &plugin); - if (err < 0) - return err; - err = snd_pcm_plugin_append(plugin); - if (err < 0) { - snd_pcm_plugin_free(plugin); - return err; - } - srcformat = tmpformat; - src_access = dst_access; - } tmpformat.rate = dstformat.rate; + if (srcformat.channels == dstformat.channels && + snd_pcm_format_linear(dstformat.format)) + tmpformat.format = dstformat.format; err = snd_pcm_plugin_build_rate(plug, &srcformat, &tmpformat, &plugin); pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err); - if (err < 0) + if (err < 0) { + snd_pcm_plugin_free(plugin); return err; + } err = snd_pcm_plugin_append(plugin); if (err < 0) { snd_pcm_plugin_free(plugin); @@ -467,11 +521,56 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, src_access = dst_access; } + /* channels extension */ + if (srcformat.channels < dstformat.channels) { + int sv = srcformat.channels; + int dv = dstformat.channels; + int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL); + if (ttable == NULL) + return -ENOMEM; +#if 0 + { + int v; + for (v = 0; v < sv; ++v) + ttable[v * sv + v] = FULL; + } +#else + { + /* Playback is spreaded on all channels */ + int vd, vs; + for (vd = 0, vs = 0; vd < dv; ++vd) { + ttable[vd * sv + vs] = FULL; + vs++; + if (vs == sv) + vs = 0; + } + } +#endif + tmpformat.channels = dstformat.channels; + if (snd_pcm_format_linear(dstformat.format)) + tmpformat.format = dstformat.format; + err = snd_pcm_plugin_build_route(plug, + &srcformat, &tmpformat, + ttable, &plugin); + kfree(ttable); + pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); + if (err < 0) { + snd_pcm_plugin_free(plugin); + return err; + } + err = snd_pcm_plugin_append(plugin); + if (err < 0) { + snd_pcm_plugin_free(plugin); + return err; + } + srcformat = tmpformat; + src_access = dst_access; + } + /* format change */ if (srcformat.format != dstformat.format) { tmpformat.format = dstformat.format; - if (srcformat.format == SNDRV_PCM_FORMAT_MU_LAW || - tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) { + if (tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) { err = snd_pcm_plugin_build_mulaw(plug, &srcformat, &tmpformat, &plugin); @@ -496,22 +595,6 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, src_access = dst_access; } - /* channels extension */ - if (srcformat.channels < dstformat.channels) { - tmpformat.channels = dstformat.channels; - err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin); - pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); - if (err < 0) - return err; - err = snd_pcm_plugin_append(plugin); - if (err < 0) { - snd_pcm_plugin_free(plugin); - return err; - } - srcformat = tmpformat; - src_access = dst_access; - } - /* de-interleave */ if (src_access != dst_access) { err = snd_pcm_plugin_build_copy(plug, @@ -567,6 +650,92 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu return count; } +static int snd_pcm_plug_playback_channels_mask(struct snd_pcm_substream *plug, + unsigned long *client_vmask) +{ + struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug); + if (plugin == NULL) { + return 0; + } else { + int schannels = plugin->dst_format.channels; + DECLARE_BITMAP(bs, schannels); + unsigned long *srcmask; + unsigned long *dstmask = bs; + int err; + bitmap_fill(dstmask, schannels); + + while (1) { + err = plugin->src_channels_mask(plugin, dstmask, &srcmask); + if (err < 0) + return err; + dstmask = srcmask; + if (plugin->prev == NULL) + break; + plugin = plugin->prev; + } + bitmap_and(client_vmask, client_vmask, dstmask, plugin->src_format.channels); + return 0; + } +} + +static int snd_pcm_plug_playback_disable_useless_channels(struct snd_pcm_substream *plug, + struct snd_pcm_plugin_channel *src_channels) +{ + struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug); + unsigned int nchannels = plugin->src_format.channels; + DECLARE_BITMAP(bs, nchannels); + unsigned long *srcmask = bs; + int err; + unsigned int channel; + for (channel = 0; channel < nchannels; channel++) { + if (src_channels[channel].enabled) + set_bit(channel, srcmask); + else + clear_bit(channel, srcmask); + } + err = snd_pcm_plug_playback_channels_mask(plug, srcmask); + if (err < 0) + return err; + for (channel = 0; channel < nchannels; channel++) { + if (!test_bit(channel, srcmask)) + src_channels[channel].enabled = 0; + } + return 0; +} + +static int snd_pcm_plug_capture_disable_useless_channels(struct snd_pcm_substream *plug, + struct snd_pcm_plugin_channel *src_channels, + struct snd_pcm_plugin_channel *client_channels) +{ + struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug); + unsigned int nchannels = plugin->dst_format.channels; + DECLARE_BITMAP(bs, nchannels); + unsigned long *dstmask = bs; + unsigned long *srcmask; + int err; + unsigned int channel; + for (channel = 0; channel < nchannels; channel++) { + if (client_channels[channel].enabled) + set_bit(channel, dstmask); + else + clear_bit(channel, dstmask); + } + while (plugin) { + err = plugin->src_channels_mask(plugin, dstmask, &srcmask); + if (err < 0) + return err; + dstmask = srcmask; + plugin = plugin->prev; + } + plugin = snd_pcm_plug_first(plug); + nchannels = plugin->src_format.channels; + for (channel = 0; channel < nchannels; channel++) { + if (!test_bit(channel, dstmask)) + src_channels[channel].enabled = 0; + } + return 0; +} + snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size) { struct snd_pcm_plugin *plugin, *next; @@ -574,6 +743,9 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st int err; snd_pcm_sframes_t frames = size; + if ((err = snd_pcm_plug_playback_disable_useless_channels(plug, src_channels)) < 0) + return err; + plugin = snd_pcm_plug_first(plug); while (plugin && frames > 0) { if ((next = plugin->next) != NULL) { @@ -618,6 +790,10 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str return err; } frames = err; + if (!plugin->prev) { + if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0) + return err; + } } else { dst_channels = dst_channels_final; } @@ -740,5 +916,3 @@ int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_of } return 0; } - -#endif diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h index 3be91b3d5..29198da61 100644 --- a/sound/core/oss/pcm_plugin.h +++ b/sound/core/oss/pcm_plugin.h @@ -22,7 +22,12 @@ * */ -#ifdef CONFIG_SND_PCM_OSS_PLUGINS +#include + +static inline unsigned long *bitmap_alloc(unsigned int nbits) +{ + return kmalloc(BITS_TO_LONGS(nbits), GFP_KERNEL); +} #define snd_pcm_plug_stream(plug) ((plug)->stream) @@ -64,6 +69,12 @@ struct snd_pcm_plugin { snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames, struct snd_pcm_plugin_channel **channels); + int (*src_channels_mask)(struct snd_pcm_plugin *plugin, + unsigned long *dst_vmask, + unsigned long **src_vmask); + int (*dst_channels_mask)(struct snd_pcm_plugin *plugin, + unsigned long *src_vmask, + unsigned long **dst_vmask); snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin, const struct snd_pcm_plugin_channel *src_channels, struct snd_pcm_plugin_channel *dst_channels, @@ -79,6 +90,8 @@ struct snd_pcm_plugin { char *buf; snd_pcm_uframes_t buf_frames; struct snd_pcm_plugin_channel *buf_channels; + unsigned long *src_vmask; + unsigned long *dst_vmask; char extra_data[0]; }; @@ -115,6 +128,7 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle, int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle, struct snd_pcm_plugin_format *src_format, struct snd_pcm_plugin_format *dst_format, + int *ttable, struct snd_pcm_plugin **r_plugin); int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle, struct snd_pcm_plugin_format *src_format, @@ -167,13 +181,15 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel); -#else +#define ROUTE_PLUGIN_RESOLUTION 16 -static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; } -static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; } -static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; } +int getput_index(int format); +int copy_index(int format); +int conv_index(int src_format, int dst_format); -#endif +void zero_channel(struct snd_pcm_plugin *plugin, + const struct snd_pcm_plugin_channel *dst_channel, + size_t samples); #ifdef PLUGIN_DEBUG #define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args) diff --git a/sound/core/oss/plugin_ops.h b/sound/core/oss/plugin_ops.h index 1f5bde463..0607e9566 100644 --- a/sound/core/oss/plugin_ops.h +++ b/sound/core/oss/plugin_ops.h @@ -362,6 +362,172 @@ put_s16_xx12_0029: as_u32(dst) = (u_int32_t)swab16(sample) ^ 0x80; goto PUT_S16_ } #endif +#if 0 +#ifdef GET32_LABELS +/* src_wid src_endswap unsigned */ +static void *get32_labels[4 * 2 * 2] = { + &&get32_xxx1_1000, /* 8h -> 32h */ + &&get32_xxx1_9000, /* 8h ^> 32h */ + &&get32_xxx1_1000, /* 8s -> 32h */ + &&get32_xxx1_9000, /* 8s ^> 32h */ + &&get32_xx12_1200, /* 16h -> 32h */ + &&get32_xx12_9200, /* 16h ^> 32h */ + &&get32_xx12_2100, /* 16s -> 32h */ + &&get32_xx12_A100, /* 16s ^> 32h */ + &&get32_x123_1230, /* 24h -> 32h */ + &&get32_x123_9230, /* 24h ^> 32h */ + &&get32_123x_3210, /* 24s -> 32h */ + &&get32_123x_B210, /* 24s ^> 32h */ + &&get32_1234_1234, /* 32h -> 32h */ + &&get32_1234_9234, /* 32h ^> 32h */ + &&get32_1234_4321, /* 32s -> 32h */ + &&get32_1234_C321, /* 32s ^> 32h */ +}; +#endif + +#ifdef GET32_END +while (0) { +get32_xxx1_1000: sample = (u_int32_t)as_u8(src) << 24; goto GET32_END; +get32_xxx1_9000: sample = (u_int32_t)(as_u8(src) ^ 0x80) << 24; goto GET32_END; +get32_xx12_1200: sample = (u_int32_t)as_u16(src) << 16; goto GET32_END; +get32_xx12_9200: sample = (u_int32_t)(as_u16(src) ^ 0x8000) << 16; goto GET32_END; +get32_xx12_2100: sample = (u_int32_t)swab16(as_u16(src)) << 16; goto GET32_END; +get32_xx12_A100: sample = (u_int32_t)swab16(as_u16(src) ^ 0x80) << 16; goto GET32_END; +get32_x123_1230: sample = as_u32(src) << 8; goto GET32_END; +get32_x123_9230: sample = (as_u32(src) << 8) ^ 0x80000000; goto GET32_END; +get32_123x_3210: sample = swab32(as_u32(src) >> 8); goto GET32_END; +get32_123x_B210: sample = swab32((as_u32(src) >> 8) ^ 0x80); goto GET32_END; +get32_1234_1234: sample = as_u32(src); goto GET32_END; +get32_1234_9234: sample = as_u32(src) ^ 0x80000000; goto GET32_END; +get32_1234_4321: sample = swab32(as_u32(src)); goto GET32_END; +get32_1234_C321: sample = swab32(as_u32(src) ^ 0x80); goto GET32_END; +} +#endif +#endif + +#ifdef PUT_U32_LABELS +/* dst_wid dst_endswap unsigned */ +static void *put_u32_labels[4 * 2 * 2] = { + &&put_u32_1234_xxx9, /* u32h -> s8h */ + &&put_u32_1234_xxx1, /* u32h -> u8h */ + &&put_u32_1234_xxx9, /* u32h -> s8s */ + &&put_u32_1234_xxx1, /* u32h -> u8s */ + &&put_u32_1234_xx92, /* u32h -> s16h */ + &&put_u32_1234_xx12, /* u32h -> u16h */ + &&put_u32_1234_xx29, /* u32h -> s16s */ + &&put_u32_1234_xx21, /* u32h -> u16s */ + &&put_u32_1234_x923, /* u32h -> s24h */ + &&put_u32_1234_x123, /* u32h -> u24h */ + &&put_u32_1234_329x, /* u32h -> s24s */ + &&put_u32_1234_321x, /* u32h -> u24s */ + &&put_u32_1234_9234, /* u32h -> s32h */ + &&put_u32_1234_1234, /* u32h -> u32h */ + &&put_u32_1234_4329, /* u32h -> s32s */ + &&put_u32_1234_4321, /* u32h -> u32s */ +}; +#endif + +#ifdef PUT_U32_END +while (0) { +put_u32_1234_xxx1: as_u8(dst) = sample >> 24; goto PUT_U32_END; +put_u32_1234_xxx9: as_u8(dst) = (sample >> 24) ^ 0x80; goto PUT_U32_END; +put_u32_1234_xx12: as_u16(dst) = sample >> 16; goto PUT_U32_END; +put_u32_1234_xx92: as_u16(dst) = (sample >> 16) ^ 0x8000; goto PUT_U32_END; +put_u32_1234_xx21: as_u16(dst) = swab16(sample >> 16); goto PUT_U32_END; +put_u32_1234_xx29: as_u16(dst) = swab16(sample >> 16) ^ 0x80; goto PUT_U32_END; +put_u32_1234_x123: as_u32(dst) = sample >> 8; goto PUT_U32_END; +put_u32_1234_x923: as_u32(dst) = (sample >> 8) ^ 0x800000; goto PUT_U32_END; +put_u32_1234_321x: as_u32(dst) = swab32(sample) << 8; goto PUT_U32_END; +put_u32_1234_329x: as_u32(dst) = (swab32(sample) ^ 0x80) << 8; goto PUT_U32_END; +put_u32_1234_1234: as_u32(dst) = sample; goto PUT_U32_END; +put_u32_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT_U32_END; +put_u32_1234_4321: as_u32(dst) = swab32(sample); goto PUT_U32_END; +put_u32_1234_4329: as_u32(dst) = swab32(sample) ^ 0x80; goto PUT_U32_END; +} +#endif + +#ifdef GET_U_LABELS +/* width endswap unsigned*/ +static void *get_u_labels[4 * 2 * 2] = { + &&get_u_s8, /* s8 -> u8 */ + &&get_u_u8, /* u8 -> u8 */ + &&get_u_s8, /* s8 -> u8 */ + &&get_u_u8, /* u8 -> u8 */ + &&get_u_s16h, /* s16h -> u16h */ + &&get_u_u16h, /* u16h -> u16h */ + &&get_u_s16s, /* s16s -> u16h */ + &&get_u_u16s, /* u16s -> u16h */ + &&get_u_s24h, /* s24h -> u32h */ + &&get_u_u24h, /* u24h -> u32h */ + &&get_u_s24s, /* s24s -> u32h */ + &&get_u_u24s, /* u24s -> u32h */ + &&get_u_s32h, /* s32h -> u32h */ + &&get_u_u32h, /* u32h -> u32h */ + &&get_u_s32s, /* s32s -> u32h */ + &&get_u_u32s, /* u32s -> u32h */ +}; +#endif + +#ifdef GET_U_END +while (0) { +get_u_s8: sample = as_u8(src) ^ 0x80; goto GET_U_END; +get_u_u8: sample = as_u8(src); goto GET_U_END; +get_u_s16h: sample = as_u16(src) ^ 0x8000; goto GET_U_END; +get_u_u16h: sample = as_u16(src); goto GET_U_END; +get_u_s16s: sample = swab16(as_u16(src) ^ 0x80); goto GET_U_END; +get_u_u16s: sample = swab16(as_u16(src)); goto GET_U_END; +get_u_s24h: sample = (as_u32(src) ^ 0x800000); goto GET_U_END; +get_u_u24h: sample = as_u32(src); goto GET_U_END; +get_u_s24s: sample = swab32(as_u32(src) ^ 0x800000); goto GET_U_END; +get_u_u24s: sample = swab32(as_u32(src)); goto GET_U_END; +get_u_s32h: sample = as_u32(src) ^ 0x80000000; goto GET_U_END; +get_u_u32h: sample = as_u32(src); goto GET_U_END; +get_u_s32s: sample = swab32(as_u32(src) ^ 0x80); goto GET_U_END; +get_u_u32s: sample = swab32(as_u32(src)); goto GET_U_END; +} +#endif + +#if 0 +#ifdef PUT_LABELS +/* width endswap unsigned */ +static void *put_labels[4 * 2 * 2] = { + &&put_s8, /* s8 -> s8 */ + &&put_u8, /* u8 -> s8 */ + &&put_s8, /* s8 -> s8 */ + &&put_u8, /* u8 -> s8 */ + &&put_s16h, /* s16h -> s16h */ + &&put_u16h, /* u16h -> s16h */ + &&put_s16s, /* s16s -> s16h */ + &&put_u16s, /* u16s -> s16h */ + &&put_s24h, /* s24h -> s32h */ + &&put_u24h, /* u24h -> s32h */ + &&put_s24s, /* s24s -> s32h */ + &&put_u24s, /* u24s -> s32h */ + &&put_s32h, /* s32h -> s32h */ + &&put_u32h, /* u32h -> s32h */ + &&put_s32s, /* s32s -> s32h */ + &&put_u32s, /* u32s -> s32h */ +}; +#endif + +#ifdef PUT_END +put_s8: as_s8(dst) = sample; goto PUT_END; +put_u8: as_u8(dst) = sample ^ 0x80; goto PUT_END; +put_s16h: as_s16(dst) = sample; goto PUT_END; +put_u16h: as_u16(dst) = sample ^ 0x8000; goto PUT_END; +put_s16s: as_s16(dst) = swab16(sample); goto PUT_END; +put_u16s: as_u16(dst) = swab16(sample ^ 0x80); goto PUT_END; +put_s24h: as_s24(dst) = sample & 0xffffff; goto PUT_END; +put_u24h: as_u24(dst) = sample ^ 0x80000000; goto PUT_END; +put_s24s: as_s24(dst) = swab32(sample & 0xffffff); goto PUT_END; +put_u24s: as_u24(dst) = swab32(sample ^ 0x80); goto PUT_END; +put_s32h: as_s32(dst) = sample; goto PUT_END; +put_u32h: as_u32(dst) = sample ^ 0x80000000; goto PUT_END; +put_s32s: as_s32(dst) = swab32(sample); goto PUT_END; +put_u32s: as_u32(dst) = swab32(sample ^ 0x80); goto PUT_END; +#endif +#endif + #undef as_u8 #undef as_u16 #undef as_u32 diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index 18d8a0f4e..4854cef6f 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c @@ -20,9 +20,6 @@ */ #include - -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - #include #include #include @@ -50,6 +47,7 @@ struct rate_priv { unsigned int pitch; unsigned int pos; rate_f func; + int get, put; snd_pcm_sframes_t old_src_frames, old_dst_frames; struct rate_channel channels[0]; }; @@ -73,12 +71,21 @@ static void resample_expand(struct snd_pcm_plugin *plugin, unsigned int pos = 0; signed int val; signed short S1, S2; - signed short *src, *dst; + char *src, *dst; unsigned int channel; int src_step, dst_step; int src_frames1, dst_frames1; struct rate_priv *data = (struct rate_priv *)plugin->extra_data; struct rate_channel *rchannels = data->channels; + +#define GET_S16_LABELS +#define PUT_S16_LABELS +#include "plugin_ops.h" +#undef GET_S16_LABELS +#undef PUT_S16_LABELS + void *get = get_s16_labels[data->get]; + void *put = put_s16_labels[data->put]; + signed short sample = 0; for (channel = 0; channel < plugin->src_format.channels; channel++) { pos = data->pos; @@ -91,12 +98,10 @@ static void resample_expand(struct snd_pcm_plugin *plugin, continue; } dst_channels[channel].enabled = 1; - src = (signed short *)src_channels[channel].area.addr + - src_channels[channel].area.first / 8 / 2; - dst = (signed short *)dst_channels[channel].area.addr + - dst_channels[channel].area.first / 8 / 2; - src_step = src_channels[channel].area.step / 8 / 2; - dst_step = dst_channels[channel].area.step / 8 / 2; + src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; + dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; + src_step = src_channels[channel].area.step / 8; + dst_step = dst_channels[channel].area.step / 8; src_frames1 = src_frames; dst_frames1 = dst_frames; while (dst_frames1-- > 0) { @@ -104,7 +109,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin, pos &= R_MASK; S1 = S2; if (src_frames1-- > 0) { - S2 = *src; + goto *get; +#define GET_S16_END after_get +#include "plugin_ops.h" +#undef GET_S16_END + after_get: + S2 = sample; src += src_step; } } @@ -113,7 +123,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin, val = -32768; else if (val > 32767) val = 32767; - *dst = val; + sample = val; + goto *put; +#define PUT_S16_END after_put +#include "plugin_ops.h" +#undef PUT_S16_END + after_put: dst += dst_step; pos += data->pitch; } @@ -132,12 +147,21 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, unsigned int pos = 0; signed int val; signed short S1, S2; - signed short *src, *dst; + char *src, *dst; unsigned int channel; int src_step, dst_step; int src_frames1, dst_frames1; struct rate_priv *data = (struct rate_priv *)plugin->extra_data; struct rate_channel *rchannels = data->channels; + +#define GET_S16_LABELS +#define PUT_S16_LABELS +#include "plugin_ops.h" +#undef GET_S16_LABELS +#undef PUT_S16_LABELS + void *get = get_s16_labels[data->get]; + void *put = put_s16_labels[data->put]; + signed short sample = 0; for (channel = 0; channel < plugin->src_format.channels; ++channel) { pos = data->pos; @@ -150,18 +174,21 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, continue; } dst_channels[channel].enabled = 1; - src = (signed short *)src_channels[channel].area.addr + - src_channels[channel].area.first / 8 / 2; - dst = (signed short *)dst_channels[channel].area.addr + - dst_channels[channel].area.first / 8 / 2; - src_step = src_channels[channel].area.step / 8 / 2; - dst_step = dst_channels[channel].area.step / 8 / 2; + src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; + dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; + src_step = src_channels[channel].area.step / 8; + dst_step = dst_channels[channel].area.step / 8; src_frames1 = src_frames; dst_frames1 = dst_frames; while (dst_frames1 > 0) { S1 = S2; if (src_frames1-- > 0) { - S1 = *src; + goto *get; +#define GET_S16_END after_get +#include "plugin_ops.h" +#undef GET_S16_END + after_get: + S2 = sample; src += src_step; } if (pos & ~R_MASK) { @@ -171,7 +198,12 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, val = -32768; else if (val > 32767) val = 32767; - *dst = val; + sample = val; + goto *put; +#define PUT_S16_END after_put +#include "plugin_ops.h" +#undef PUT_S16_END + after_put: dst += dst_step; dst_frames1--; } @@ -311,8 +343,8 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, snd_assert(src_format->channels == dst_format->channels, return -ENXIO); snd_assert(src_format->channels > 0, return -ENXIO); - snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); - snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); + snd_assert(snd_pcm_format_linear(src_format->format) != 0, return -ENXIO); + snd_assert(snd_pcm_format_linear(dst_format->format) != 0, return -ENXIO); snd_assert(src_format->rate != dst_format->rate, return -ENXIO); err = snd_pcm_plugin_build(plug, "rate conversion", @@ -323,6 +355,11 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, if (err < 0) return err; data = (struct rate_priv *)plugin->extra_data; + data->get = getput_index(src_format->format); + snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); + data->put = getput_index(dst_format->format); + snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL); + if (src_format->rate < dst_format->rate) { data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate; data->func = resample_expand; @@ -340,5 +377,3 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } - -#endif diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c index 46917dc01..726c5caa3 100644 --- a/sound/core/oss/route.c +++ b/sound/core/oss/route.c @@ -1,5 +1,5 @@ /* - * Route Plug-In + * Attenuated route Plug-In * Copyright (c) 2000 by Abramo Bagnara * * @@ -20,93 +20,502 @@ */ #include - -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - #include #include #include #include #include "pcm_plugin.h" -static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts, - snd_pcm_uframes_t frames, int format) +/* The best possible hack to support missing optimization in gcc 2.7.2.3 */ +#if ROUTE_PLUGIN_RESOLUTION & (ROUTE_PLUGIN_RESOLUTION - 1) != 0 +#define div(a) a /= ROUTE_PLUGIN_RESOLUTION +#elif ROUTE_PLUGIN_RESOLUTION == 16 +#define div(a) a >>= 4 +#else +#error "Add some code here" +#endif + +struct ttable_dst; + +typedef void (*route_channel_f)(struct snd_pcm_plugin *plugin, + const struct snd_pcm_plugin_channel *src_channels, + struct snd_pcm_plugin_channel *dst_channel, + struct ttable_dst *ttable, snd_pcm_uframes_t frames); + +struct ttable_src { + int channel; + int as_int; +}; + +struct ttable_dst { + int att; /* Attenuated */ + unsigned int nsrcs; + struct ttable_src *srcs; + route_channel_f func; +}; + +struct route_priv { + enum {R_UINT32=0, R_UINT64=1} sum_type; + int get, put; + int conv; + int src_sample_size; + struct ttable_dst ttable[0]; +}; + +union sum { + u_int32_t as_uint32; + u_int64_t as_uint64; +}; + + +static void route_to_channel_from_zero(struct snd_pcm_plugin *plugin, + const struct snd_pcm_plugin_channel *src_channels, + struct snd_pcm_plugin_channel *dst_channel, + struct ttable_dst *ttable, + snd_pcm_uframes_t frames) { - int dst = 0; - for (; dst < ndsts; ++dst) { - if (dvp->wanted) - snd_pcm_area_silence(&dvp->area, 0, frames, format); - dvp->enabled = 0; - dvp++; + if (dst_channel->wanted) + snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format); + dst_channel->enabled = 0; +} + +static void route_to_channel_from_one(struct snd_pcm_plugin *plugin, + const struct snd_pcm_plugin_channel *src_channels, + struct snd_pcm_plugin_channel *dst_channel, + struct ttable_dst *ttable, + snd_pcm_uframes_t frames) +{ +#define CONV_LABELS +#include "plugin_ops.h" +#undef CONV_LABELS + struct route_priv *data = (struct route_priv *)plugin->extra_data; + void *conv; + const struct snd_pcm_plugin_channel *src_channel = NULL; + unsigned int srcidx; + char *src, *dst; + int src_step, dst_step; + for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) { + src_channel = &src_channels[ttable->srcs[srcidx].channel]; + if (src_channel->area.addr != NULL) + break; + } + if (srcidx == ttable->nsrcs) { + route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames); + return; + } + + dst_channel->enabled = 1; + conv = conv_labels[data->conv]; + src = src_channel->area.addr + src_channel->area.first / 8; + src_step = src_channel->area.step / 8; + dst = dst_channel->area.addr + dst_channel->area.first / 8; + dst_step = dst_channel->area.step / 8; + while (frames-- > 0) { + goto *conv; +#define CONV_END after +#include "plugin_ops.h" +#undef CONV_END + after: + src += src_step; + dst += dst_step; } } -static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel, +static void route_to_channel(struct snd_pcm_plugin *plugin, + const struct snd_pcm_plugin_channel *src_channels, struct snd_pcm_plugin_channel *dst_channel, - snd_pcm_uframes_t frames, int format) + struct ttable_dst *ttable, snd_pcm_uframes_t frames) { +#define GET_U_LABELS +#define PUT_U32_LABELS +#include "plugin_ops.h" +#undef GET_U_LABELS +#undef PUT_U32_LABELS + static void *zero_labels[2] = { &&zero_int32, &&zero_int64 }; + /* sum_type att */ + static void *add_labels[2 * 2] = { &&add_int32_noatt, &&add_int32_att, + &&add_int64_noatt, &&add_int64_att, + }; + /* sum_type att shift */ + static void *norm_labels[2 * 2 * 4] = { NULL, + &&norm_int32_8_noatt, + &&norm_int32_16_noatt, + &&norm_int32_24_noatt, + NULL, + &&norm_int32_8_att, + &&norm_int32_16_att, + &&norm_int32_24_att, + &&norm_int64_0_noatt, + &&norm_int64_8_noatt, + &&norm_int64_16_noatt, + &&norm_int64_24_noatt, + &&norm_int64_0_att, + &&norm_int64_8_att, + &&norm_int64_16_att, + &&norm_int64_24_att, + }; + struct route_priv *data = (struct route_priv *)plugin->extra_data; + void *zero, *get, *add, *norm, *put_u32; + int nsrcs = ttable->nsrcs; + char *dst; + int dst_step; + char *srcs[nsrcs]; + int src_steps[nsrcs]; + struct ttable_src src_tt[nsrcs]; + u_int32_t sample = 0; + int srcidx, srcidx1 = 0; + for (srcidx = 0; srcidx < nsrcs; ++srcidx) { + const struct snd_pcm_plugin_channel *src_channel = &src_channels[ttable->srcs[srcidx].channel]; + if (!src_channel->enabled) + continue; + srcs[srcidx1] = src_channel->area.addr + src_channel->area.first / 8; + src_steps[srcidx1] = src_channel->area.step / 8; + src_tt[srcidx1] = ttable->srcs[srcidx]; + srcidx1++; + } + nsrcs = srcidx1; + if (nsrcs == 0) { + route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames); + return; + } else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) { + route_to_channel_from_one(plugin, src_channels, dst_channel, ttable, frames); + return; + } + dst_channel->enabled = 1; - snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format); + zero = zero_labels[data->sum_type]; + get = get_u_labels[data->get]; + add = add_labels[data->sum_type * 2 + ttable->att]; + norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size]; + put_u32 = put_u32_labels[data->put]; + dst = dst_channel->area.addr + dst_channel->area.first / 8; + dst_step = dst_channel->area.step / 8; + + while (frames-- > 0) { + struct ttable_src *ttp = src_tt; + union sum sum; + + /* Zero sum */ + goto *zero; + zero_int32: + sum.as_uint32 = 0; + goto zero_end; + zero_int64: + sum.as_uint64 = 0; + goto zero_end; + zero_end: + for (srcidx = 0; srcidx < nsrcs; ++srcidx) { + char *src = srcs[srcidx]; + + /* Get sample */ + goto *get; +#define GET_U_END after_get +#include "plugin_ops.h" +#undef GET_U_END + after_get: + + /* Sum */ + goto *add; + add_int32_att: + sum.as_uint32 += sample * ttp->as_int; + goto after_sum; + add_int32_noatt: + if (ttp->as_int) + sum.as_uint32 += sample; + goto after_sum; + add_int64_att: + sum.as_uint64 += (u_int64_t) sample * ttp->as_int; + goto after_sum; + add_int64_noatt: + if (ttp->as_int) + sum.as_uint64 += sample; + goto after_sum; + after_sum: + srcs[srcidx] += src_steps[srcidx]; + ttp++; + } + + /* Normalization */ + goto *norm; + norm_int32_8_att: + sum.as_uint64 = sum.as_uint32; + norm_int64_8_att: + sum.as_uint64 <<= 8; + norm_int64_0_att: + div(sum.as_uint64); + goto norm_int; + + norm_int32_16_att: + sum.as_uint64 = sum.as_uint32; + norm_int64_16_att: + sum.as_uint64 <<= 16; + div(sum.as_uint64); + goto norm_int; + + norm_int32_24_att: + sum.as_uint64 = sum.as_uint32; + norm_int64_24_att: + sum.as_uint64 <<= 24; + div(sum.as_uint64); + goto norm_int; + + norm_int32_8_noatt: + sum.as_uint64 = sum.as_uint32; + norm_int64_8_noatt: + sum.as_uint64 <<= 8; + goto norm_int; + + norm_int32_16_noatt: + sum.as_uint64 = sum.as_uint32; + norm_int64_16_noatt: + sum.as_uint64 <<= 16; + goto norm_int; + + norm_int32_24_noatt: + sum.as_uint64 = sum.as_uint32; + norm_int64_24_noatt: + sum.as_uint64 <<= 24; + goto norm_int; + + norm_int64_0_noatt: + norm_int: + if (sum.as_uint64 > (u_int32_t)0xffffffff) + sample = (u_int32_t)0xffffffff; + else + sample = sum.as_uint64; + goto after_norm; + + after_norm: + + /* Put sample */ + goto *put_u32; +#define PUT_U32_END after_put_u32 +#include "plugin_ops.h" +#undef PUT_U32_END + after_put_u32: + + dst += dst_step; + } +} + +static int route_src_channels_mask(struct snd_pcm_plugin *plugin, + unsigned long *dst_vmask, + unsigned long **src_vmask) +{ + struct route_priv *data = (struct route_priv *)plugin->extra_data; + int schannels = plugin->src_format.channels; + int dchannels = plugin->dst_format.channels; + unsigned long *vmask = plugin->src_vmask; + int channel; + struct ttable_dst *dp = data->ttable; + bitmap_zero(vmask, schannels); + for (channel = 0; channel < dchannels; channel++, dp++) { + unsigned int src; + struct ttable_src *sp; + if (!test_bit(channel, dst_vmask)) + continue; + sp = dp->srcs; + for (src = 0; src < dp->nsrcs; src++, sp++) + set_bit(sp->channel, vmask); + } + *src_vmask = vmask; + return 0; +} + +static int route_dst_channels_mask(struct snd_pcm_plugin *plugin, + unsigned long *src_vmask, + unsigned long **dst_vmask) +{ + struct route_priv *data = (struct route_priv *)plugin->extra_data; + int dchannels = plugin->dst_format.channels; + unsigned long *vmask = plugin->dst_vmask; + int channel; + struct ttable_dst *dp = data->ttable; + bitmap_zero(vmask, dchannels); + for (channel = 0; channel < dchannels; channel++, dp++) { + unsigned int src; + struct ttable_src *sp; + sp = dp->srcs; + for (src = 0; src < dp->nsrcs; src++, sp++) { + if (test_bit(sp->channel, src_vmask)) { + set_bit(channel, vmask); + break; + } + } + } + *dst_vmask = vmask; + return 0; +} + +static void route_free(struct snd_pcm_plugin *plugin) +{ + struct route_priv *data = (struct route_priv *)plugin->extra_data; + unsigned int dst_channel; + for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) { + kfree(data->ttable[dst_channel].srcs); + } +} + +static int route_load_ttable(struct snd_pcm_plugin *plugin, + const int *src_ttable) +{ + struct route_priv *data; + unsigned int src_channel, dst_channel; + const int *sptr; + struct ttable_dst *dptr; + if (src_ttable == NULL) + return 0; + data = (struct route_priv *)plugin->extra_data; + dptr = data->ttable; + sptr = src_ttable; + plugin->private_free = route_free; + for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) { + int t = 0; + int att = 0; + int nsrcs = 0; + struct ttable_src srcs[plugin->src_format.channels]; + for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) { + snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO); + if (*sptr != 0) { + srcs[nsrcs].channel = src_channel; + srcs[nsrcs].as_int = *sptr; + if (*sptr != FULL) + att = 1; + t += *sptr; + nsrcs++; + } + sptr++; + } + dptr->att = att; + dptr->nsrcs = nsrcs; + if (nsrcs == 0) + dptr->func = route_to_channel_from_zero; + else if (nsrcs == 1 && !att) + dptr->func = route_to_channel_from_one; + else + dptr->func = route_to_channel; + if (nsrcs > 0) { + int srcidx; + dptr->srcs = kcalloc(nsrcs, sizeof(*srcs), GFP_KERNEL); + for(srcidx = 0; srcidx < nsrcs; srcidx++) + dptr->srcs[srcidx] = srcs[srcidx]; + } else + dptr->srcs = NULL; + dptr++; + } + return 0; } static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin, - const struct snd_pcm_plugin_channel *src_channels, - struct snd_pcm_plugin_channel *dst_channels, - snd_pcm_uframes_t frames) + const struct snd_pcm_plugin_channel *src_channels, + struct snd_pcm_plugin_channel *dst_channels, + snd_pcm_uframes_t frames) { - int nsrcs, ndsts, dst; + struct route_priv *data; + int src_nchannels, dst_nchannels; + int dst_channel; + struct ttable_dst *ttp; struct snd_pcm_plugin_channel *dvp; - int format; snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); if (frames == 0) return 0; + data = (struct route_priv *)plugin->extra_data; - nsrcs = plugin->src_format.channels; - ndsts = plugin->dst_format.channels; + src_nchannels = plugin->src_format.channels; + dst_nchannels = plugin->dst_format.channels; - format = plugin->dst_format.format; - dvp = dst_channels; - if (nsrcs <= 1) { - /* expand to all channels */ - for (dst = 0; dst < ndsts; ++dst) { - copy_area(src_channels, dvp, frames, format); - dvp++; +#ifdef CONFIG_SND_DEBUG + { + int src_channel; + for (src_channel = 0; src_channel < src_nchannels; ++src_channel) { + snd_assert(src_channels[src_channel].area.first % 8 == 0 || + src_channels[src_channel].area.step % 8 == 0, + return -ENXIO); + } + for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) { + snd_assert(dst_channels[dst_channel].area.first % 8 == 0 || + dst_channels[dst_channel].area.step % 8 == 0, + return -ENXIO); } - return frames; } +#endif - for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) { - copy_area(src_channels, dvp, frames, format); + ttp = data->ttable; + dvp = dst_channels; + for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) { + ttp->func(plugin, src_channels, dvp, ttp, frames); dvp++; - src_channels++; + ttp++; } - if (dst < ndsts) - zero_areas(dvp, ndsts - dst, frames, format); return frames; } +int getput_index(int format) +{ + int sign, width, endian; + sign = !snd_pcm_format_signed(format); + width = snd_pcm_format_width(format) / 8 - 1; + if (width < 0 || width > 3) { + snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format); + width = 0; + } +#ifdef SNDRV_LITTLE_ENDIAN + endian = snd_pcm_format_big_endian(format); +#else + endian = snd_pcm_format_little_endian(format); +#endif + if (endian < 0) + endian = 0; + return width * 4 + endian * 2 + sign; +} + int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug, struct snd_pcm_plugin_format *src_format, struct snd_pcm_plugin_format *dst_format, + int *ttable, struct snd_pcm_plugin **r_plugin) { + struct route_priv *data; struct snd_pcm_plugin *plugin; int err; snd_assert(r_plugin != NULL, return -ENXIO); *r_plugin = NULL; snd_assert(src_format->rate == dst_format->rate, return -ENXIO); - snd_assert(src_format->format == dst_format->format, return -ENXIO); + snd_assert(snd_pcm_format_linear(src_format->format) != 0 && + snd_pcm_format_linear(dst_format->format) != 0, + return -ENXIO); - err = snd_pcm_plugin_build(plug, "route conversion", - src_format, dst_format, 0, &plugin); + err = snd_pcm_plugin_build(plug, "attenuated route conversion", + src_format, dst_format, + sizeof(struct route_priv) + + sizeof(data->ttable[0]) * dst_format->channels, + &plugin); if (err < 0) return err; + data = (struct route_priv *)plugin->extra_data; + + data->get = getput_index(src_format->format); + snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); + data->put = getput_index(dst_format->format); + snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); + data->conv = conv_index(src_format->format, dst_format->format); + + if (snd_pcm_format_width(src_format->format) == 32) + data->sum_type = R_UINT64; + else + data->sum_type = R_UINT32; + data->src_sample_size = snd_pcm_format_width(src_format->format) / 8; + + if ((err = route_load_ttable(plugin, ttable)) < 0) { + snd_pcm_plugin_free(plugin); + return err; + } plugin->transfer = route_transfer; + plugin->src_channels_mask = route_src_channels_mask; + plugin->dst_channels_mask = route_dst_channels_mask; *r_plugin = plugin; return 0; } - -#endif diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 84b000382..28ca61eb0 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -36,7 +35,7 @@ MODULE_LICENSE("GPL"); static LIST_HEAD(snd_pcm_devices); static LIST_HEAD(snd_pcm_notify_list); -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); static int snd_pcm_free(struct snd_pcm *pcm); static int snd_pcm_dev_free(struct snd_device *device); @@ -68,7 +67,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)arg)) return -EFAULT; - mutex_lock(®ister_mutex); + down(®ister_mutex); device = device < 0 ? 0 : device + 1; while (device < SNDRV_PCM_DEVICES) { if (snd_pcm_search(card, device)) @@ -77,7 +76,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, } if (device == SNDRV_PCM_DEVICES) device = -1; - mutex_unlock(®ister_mutex); + up(®ister_mutex); if (put_user(device, (int __user *)arg)) return -EFAULT; return 0; @@ -101,7 +100,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, return -EINVAL; if (get_user(subdevice, &info->subdevice)) return -EFAULT; - mutex_lock(®ister_mutex); + down(®ister_mutex); pcm = snd_pcm_search(card, device); if (pcm == NULL) { err = -ENXIO; @@ -126,7 +125,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, } err = snd_pcm_info_user(substream, info); _error: - mutex_unlock(®ister_mutex); + up(®ister_mutex); return err; } case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: @@ -141,9 +140,6 @@ static int snd_pcm_control_ioctl(struct snd_card *card, } return -ENOIOCTLCMD; } - -#ifdef CONFIG_SND_VERBOSE_PROCFS - #define STATE(v) [SNDRV_PCM_STATE_##v] = #v #define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v #define READY(v) [SNDRV_PCM_READY_##v] = #v @@ -196,11 +192,12 @@ static char *snd_pcm_format_names[] = { FORMAT(U18_3BE), }; -static const char *snd_pcm_format_name(snd_pcm_format_t format) +const char *snd_pcm_format_name(snd_pcm_format_t format) { return snd_pcm_format_names[format]; } +#ifdef CONFIG_PROC_FS static char *snd_pcm_stream_names[] = { STREAM(PLAYBACK), STREAM(CAPTURE), @@ -263,7 +260,6 @@ static const char *snd_pcm_state_name(snd_pcm_state_t state) #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) #include - static const char *snd_pcm_oss_format_name(int format) { switch (format) { @@ -436,7 +432,7 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr); } -#ifdef CONFIG_SND_PCM_XRUN_DEBUG +#ifdef CONFIG_SND_DEBUG static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { @@ -480,7 +476,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) } pstr->proc_info_entry = entry; -#ifdef CONFIG_SND_PCM_XRUN_DEBUG +#ifdef CONFIG_SND_DEBUG if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", pstr->proc_root)) != NULL) { entry->c.text.read_size = 64; @@ -501,7 +497,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { -#ifdef CONFIG_SND_PCM_XRUN_DEBUG +#ifdef CONFIG_SND_DEBUG if (pstr->proc_xrun_debug_entry) { snd_info_unregister(pstr->proc_xrun_debug_entry); pstr->proc_xrun_debug_entry = NULL; @@ -599,12 +595,12 @@ static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) } return 0; } -#else /* !CONFIG_SND_VERBOSE_PROCFS */ +#else /* !CONFIG_PROC_FS */ static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; } static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; } static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; } static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; } -#endif /* CONFIG_SND_VERBOSE_PROCFS */ +#endif /* CONFIG_PROC_FS */ /** * snd_pcm_new_stream - create a new PCM stream @@ -626,7 +622,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) struct snd_pcm_substream *substream, *prev; #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) - mutex_init(&pstr->oss.setup_mutex); + init_MUTEX(&pstr->oss.setup_mutex); #endif pstr->stream = stream; pstr->pcm = pcm; @@ -720,7 +716,7 @@ int snd_pcm_new(struct snd_card *card, char *id, int device, snd_pcm_free(pcm); return err; } - mutex_init(&pcm->open_mutex); + init_MUTEX(&pcm->open_mutex); init_waitqueue_head(&pcm->open_wait); if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { snd_pcm_free(pcm); @@ -777,9 +773,8 @@ static void snd_pcm_tick_timer_func(unsigned long data) snd_pcm_tick_elapsed(substream); } -int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, - struct file *file, - struct snd_pcm_substream **rsubstream) +int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, + struct snd_pcm_substream **rsubstream) { struct snd_pcm_str * pstr; struct snd_pcm_substream *substream; @@ -794,7 +789,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, *rsubstream = NULL; snd_assert(pcm != NULL, return -ENXIO); pstr = &pcm->streams[stream]; - if (pstr->substream == NULL || pstr->substream_count == 0) + if (pstr->substream == NULL) return -ENODEV; card = pcm->card; @@ -808,6 +803,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, } up_read(&card->controls_rwsem); + if (pstr->substream_count == 0) + return -ENODEV; switch (stream) { case SNDRV_PCM_STREAM_PLAYBACK: if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) { @@ -873,13 +870,12 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, substream->runtime = runtime; substream->private_data = pcm->private_data; - substream->ffile = file; pstr->substream_opened++; *rsubstream = substream; return 0; } -void snd_pcm_detach_substream(struct snd_pcm_substream *substream) +void snd_pcm_release_substream(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; substream->file = NULL; @@ -906,9 +902,9 @@ static int snd_pcm_dev_register(struct snd_device *device) struct snd_pcm *pcm = device->device_data; snd_assert(pcm != NULL && device != NULL, return -ENXIO); - mutex_lock(®ister_mutex); + down(®ister_mutex); if (snd_pcm_search(pcm->card, pcm->device)) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -EBUSY; } list_add_tail(&pcm->list, &snd_pcm_devices); @@ -932,7 +928,7 @@ static int snd_pcm_dev_register(struct snd_device *device) pcm, str)) < 0) { list_del(&pcm->list); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return err; } for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) @@ -943,7 +939,7 @@ static int snd_pcm_dev_register(struct snd_device *device) notify = list_entry(list, struct snd_pcm_notify, list); notify->n_register(pcm); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } @@ -954,7 +950,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) struct snd_pcm_substream *substream; int cidx; - mutex_lock(®ister_mutex); + down(®ister_mutex); list_del_init(&pcm->list); for (cidx = 0; cidx < 2; cidx++) for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) @@ -965,7 +961,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) notify = list_entry(list, struct snd_pcm_notify, list); notify->n_disconnect(pcm); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } @@ -977,7 +973,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device) struct snd_pcm *pcm = device->device_data; snd_assert(pcm != NULL, return -ENXIO); - mutex_lock(®ister_mutex); + down(®ister_mutex); list_del(&pcm->list); for (cidx = 0; cidx < 2; cidx++) { devtype = -1; @@ -998,7 +994,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device) notify = list_entry(list, struct snd_pcm_notify, list); notify->n_unregister(pcm); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); return snd_pcm_free(pcm); } @@ -1007,7 +1003,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) struct list_head *p; snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); - mutex_lock(®ister_mutex); + down(®ister_mutex); if (nfree) { list_del(¬ify->list); list_for_each(p, &snd_pcm_devices) @@ -1018,7 +1014,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) list_for_each(p, &snd_pcm_devices) notify->n_register(list_entry(p, struct snd_pcm, list)); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } @@ -1033,7 +1029,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, struct list_head *p; struct snd_pcm *pcm; - mutex_lock(®ister_mutex); + down(®ister_mutex); list_for_each(p, &snd_pcm_devices) { pcm = list_entry(p, struct snd_pcm, list); snd_iprintf(buffer, "%02i-%02i: %s : %s", @@ -1046,7 +1042,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count); snd_iprintf(buffer, "\n"); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); } static struct snd_info_entry *snd_pcm_proc_entry = NULL; @@ -1105,12 +1101,15 @@ EXPORT_SYMBOL(snd_pcm_new_stream); EXPORT_SYMBOL(snd_pcm_notify); EXPORT_SYMBOL(snd_pcm_open_substream); EXPORT_SYMBOL(snd_pcm_release_substream); +EXPORT_SYMBOL(snd_pcm_format_name); /* pcm_native.c */ EXPORT_SYMBOL(snd_pcm_link_rwlock); #ifdef CONFIG_PM EXPORT_SYMBOL(snd_pcm_suspend); EXPORT_SYMBOL(snd_pcm_suspend_all); #endif +EXPORT_SYMBOL(snd_pcm_kernel_playback_ioctl); +EXPORT_SYMBOL(snd_pcm_kernel_capture_ioctl); EXPORT_SYMBOL(snd_pcm_kernel_ioctl); EXPORT_SYMBOL(snd_pcm_mmap_data); #if SNDRV_PCM_INFO_MMAP_IOMEM diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index eedc6cb03..eeba2f060 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -130,7 +130,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram static void xrun(struct snd_pcm_substream *substream) { snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); -#ifdef CONFIG_SND_PCM_XRUN_DEBUG +#ifdef CONFIG_SND_DEBUG if (substream->pstr->xrun_debug) { snd_printd(KERN_DEBUG "XRUN: pcmC%dD%d%c\n", substream->pcm->card->number, @@ -204,7 +204,7 @@ static inline int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *subs delta = hw_ptr_interrupt - new_hw_ptr; if (delta > 0) { if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { -#ifdef CONFIG_SND_PCM_XRUN_DEBUG +#ifdef CONFIG_SND_DEBUG if (runtime->periods > 1 && substream->pstr->xrun_debug) { snd_printd(KERN_ERR "Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); if (substream->pstr->xrun_debug > 1) @@ -249,7 +249,7 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) delta = old_hw_ptr - new_hw_ptr; if (delta > 0) { if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { -#ifdef CONFIG_SND_PCM_XRUN_DEBUG +#ifdef CONFIG_SND_DEBUG if (runtime->periods > 2 && substream->pstr->xrun_debug) { snd_printd(KERN_ERR "Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); if (substream->pstr->xrun_debug > 1) @@ -2299,7 +2299,19 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; + snd_assert(substream->ffile != NULL, return -ENXIO); nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); +#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) + if (substream->oss.oss) { + struct snd_pcm_oss_setup *setup = substream->oss.setup; + if (setup != NULL) { + if (setup->nonblock) + nonblock = 1; + else if (setup->block) + nonblock = 0; + } + } +#endif if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && runtime->channels > 1) @@ -2362,7 +2374,19 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; + snd_assert(substream->ffile != NULL, return -ENXIO); nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); +#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) + if (substream->oss.oss) { + struct snd_pcm_oss_setup *setup = substream->oss.setup; + if (setup != NULL) { + if (setup->nonblock) + nonblock = 1; + else if (setup->block) + nonblock = 0; + } + } +#endif if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) return -EINVAL; @@ -2572,7 +2596,19 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; + snd_assert(substream->ffile != NULL, return -ENXIO); nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); +#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) + if (substream->oss.oss) { + struct snd_pcm_oss_setup *setup = substream->oss.setup; + if (setup != NULL) { + if (setup->nonblock) + nonblock = 1; + else if (setup->block) + nonblock = 0; + } + } +#endif if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) return -EINVAL; return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); @@ -2629,7 +2665,20 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; + snd_assert(substream->ffile != NULL, return -ENXIO); nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); +#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) + if (substream->oss.oss) { + struct snd_pcm_oss_setup *setup = substream->oss.setup; + if (setup != NULL) { + if (setup->nonblock) + nonblock = 1; + else if (setup->block) + nonblock = 0; + } + } +#endif + if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) return -EINVAL; return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 428f8c169..a0119ae67 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -100,10 +100,8 @@ static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream) { snd_pcm_lib_preallocate_dma_free(substream); -#ifdef CONFIG_SND_VERBOSE_PROCFS snd_info_unregister(substream->proc_prealloc_entry); substream->proc_prealloc_entry = NULL; -#endif return 0; } @@ -126,7 +124,7 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm) return 0; } -#ifdef CONFIG_SND_VERBOSE_PROCFS +#ifdef CONFIG_PROC_FS /* * read callback for prealloc proc file * @@ -205,9 +203,9 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream) substream->proc_prealloc_entry = entry; } -#else /* !CONFIG_SND_VERBOSE_PROCFS */ +#else /* !CONFIG_PROC_FS */ #define preallocate_info_init(s) -#endif /* CONFIG_SND_VERBOSE_PROCFS */ +#endif /* * pre-allocate the buffer and create a proc file for the substream diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 0860c5a84..f3d5de7b5 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1170,7 +1170,7 @@ static int snd_pcm_resume(struct snd_pcm_substream *substream) int res; snd_power_lock(card); - if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) + if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile)) >= 0) res = snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0); snd_power_unlock(card); return res; @@ -1198,7 +1198,7 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream) snd_power_lock(card); if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { - result = snd_power_wait(card, SNDRV_CTL_POWER_D0); + result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); if (result < 0) goto _unlock; } @@ -1313,13 +1313,13 @@ static struct action_ops snd_pcm_action_prepare = { * * Prepare the PCM substream to be triggerable. */ -static int snd_pcm_prepare(struct snd_pcm_substream *substream) +int snd_pcm_prepare(struct snd_pcm_substream *substream) { int res; struct snd_card *card = substream->pcm->card; snd_power_lock(card); - if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) + if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile)) >= 0) res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0); snd_power_unlock(card); return res; @@ -1410,7 +1410,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) snd_power_lock(card); if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { - result = snd_power_wait(card, SNDRV_CTL_POWER_D0); + result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); if (result < 0) { snd_power_unlock(card); return result; @@ -1533,7 +1533,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) snd_power_lock(card); if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { - result = snd_power_wait(card, SNDRV_CTL_POWER_D0); + result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); if (result < 0) goto _unlock; } @@ -1995,65 +1995,28 @@ static void snd_pcm_remove_file(struct snd_pcm_str *str, } } -static void pcm_release_private(struct snd_pcm_substream *substream) +static int snd_pcm_release_file(struct snd_pcm_file * pcm_file) { - struct snd_pcm_file *pcm_file = substream->file; + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + struct snd_pcm_str * str; + snd_assert(pcm_file != NULL, return -ENXIO); + substream = pcm_file->substream; + snd_assert(substream != NULL, return -ENXIO); + runtime = substream->runtime; + str = substream->pstr; snd_pcm_unlink(substream); - snd_pcm_remove_file(substream->pstr, pcm_file); - kfree(pcm_file); -} - -void snd_pcm_release_substream(struct snd_pcm_substream *substream) -{ - snd_pcm_drop(substream); - if (substream->hw_opened) { + if (substream->ffile != NULL) { if (substream->ops->hw_free != NULL) substream->ops->hw_free(substream); substream->ops->close(substream); - substream->hw_opened = 0; - } - if (substream->pcm_release) { - substream->pcm_release(substream); - substream->pcm_release = NULL; - } - snd_pcm_detach_substream(substream); -} - -int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, - struct file *file, - struct snd_pcm_substream **rsubstream) -{ - struct snd_pcm_substream *substream; - int err; - - err = snd_pcm_attach_substream(pcm, stream, file, &substream); - if (err < 0) - return err; - substream->no_mmap_ctrl = 0; - err = snd_pcm_hw_constraints_init(substream); - if (err < 0) { - snd_printd("snd_pcm_hw_constraints_init failed\n"); - goto error; + substream->ffile = NULL; } - - if ((err = substream->ops->open(substream)) < 0) - goto error; - - substream->hw_opened = 1; - - err = snd_pcm_hw_constraints_complete(substream); - if (err < 0) { - snd_printd("snd_pcm_hw_constraints_complete failed\n"); - goto error; - } - - *rsubstream = substream; - return 0; - - error: + snd_pcm_remove_file(str, pcm_file); snd_pcm_release_substream(substream); - return err; + kfree(pcm_file); + return 0; } static int snd_pcm_open_file(struct file *file, @@ -2061,29 +2024,52 @@ static int snd_pcm_open_file(struct file *file, int stream, struct snd_pcm_file **rpcm_file) { + int err = 0; struct snd_pcm_file *pcm_file; struct snd_pcm_substream *substream; struct snd_pcm_str *str; - int err; snd_assert(rpcm_file != NULL, return -EINVAL); *rpcm_file = NULL; - err = snd_pcm_open_substream(pcm, stream, file, &substream); - if (err < 0) - return err; - pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); if (pcm_file == NULL) { - snd_pcm_release_substream(substream); return -ENOMEM; } + + if ((err = snd_pcm_open_substream(pcm, stream, &substream)) < 0) { + kfree(pcm_file); + return err; + } + str = substream->pstr; substream->file = pcm_file; - substream->pcm_release = pcm_release_private; + substream->no_mmap_ctrl = 0; + pcm_file->substream = substream; + snd_pcm_add_file(str, pcm_file); + err = snd_pcm_hw_constraints_init(substream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraints_init failed\n"); + snd_pcm_release_file(pcm_file); + return err; + } + + if ((err = substream->ops->open(substream)) < 0) { + snd_pcm_release_file(pcm_file); + return err; + } + substream->ffile = file; + + err = snd_pcm_hw_constraints_complete(substream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraints_complete failed\n"); + snd_pcm_release_file(pcm_file); + return err; + } + file->private_data = pcm_file; *rpcm_file = pcm_file; return 0; @@ -2126,7 +2112,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) } init_waitqueue_entry(&wait, current); add_wait_queue(&pcm->open_wait, &wait); - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); while (1) { err = snd_pcm_open_file(file, pcm, stream, &pcm_file); if (err >= 0) @@ -2139,16 +2125,16 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) } else break; set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); schedule(); - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; } } remove_wait_queue(&pcm->open_wait, &wait); - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); if (err < 0) goto __error; return err; @@ -2172,10 +2158,11 @@ static int snd_pcm_release(struct inode *inode, struct file *file) snd_assert(substream != NULL, return -ENXIO); snd_assert(!atomic_read(&substream->runtime->mmap_count), ); pcm = substream->pcm; + snd_pcm_drop(substream); fasync_helper(-1, file, 0, &substream->runtime->fasync); - mutex_lock(&pcm->open_mutex); - snd_pcm_release_substream(substream); - mutex_unlock(&pcm->open_mutex); + down(&pcm->open_mutex); + snd_pcm_release_file(pcm_file); + up(&pcm->open_mutex); wake_up(&pcm->open_wait); module_put(pcm->card->module); snd_card_file_remove(pcm->card, file); @@ -2493,6 +2480,11 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, return 0; } +static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, + unsigned int cmd, void __user *arg); +static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream, + unsigned int cmd, void __user *arg); + static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { @@ -2547,14 +2539,6 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, return snd_pcm_drain(substream); case SNDRV_PCM_IOCTL_DROP: return snd_pcm_drop(substream); - case SNDRV_PCM_IOCTL_PAUSE: - { - int res; - snd_pcm_stream_lock_irq(substream); - res = snd_pcm_pause(substream, (int)(unsigned long)arg); - snd_pcm_stream_unlock_irq(substream); - return res; - } } snd_printd("unknown ioctl = 0x%x\n", cmd); return -ENOTTY; @@ -2635,6 +2619,14 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, __put_user(result, _frames); return result < 0 ? result : 0; } + case SNDRV_PCM_IOCTL_PAUSE: + { + int res; + snd_pcm_stream_lock_irq(substream); + res = snd_pcm_pause(substream, (int)(unsigned long)arg); + snd_pcm_stream_unlock_irq(substream); + return res; + } } return snd_pcm_common_ioctl1(substream, cmd, arg); } @@ -2744,28 +2736,41 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg); } -int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) +int snd_pcm_kernel_playback_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + mm_segment_t fs; + int result; + + fs = snd_enter_user(); + result = snd_pcm_playback_ioctl1(substream, cmd, (void __user *)arg); + snd_leave_user(fs); + return result; +} + +int snd_pcm_kernel_capture_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) { mm_segment_t fs; int result; fs = snd_enter_user(); + result = snd_pcm_capture_ioctl1(substream, cmd, (void __user *)arg); + snd_leave_user(fs); + return result; +} + +int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ switch (substream->stream) { case SNDRV_PCM_STREAM_PLAYBACK: - result = snd_pcm_playback_ioctl1(substream, - cmd, (void __user *)arg); - break; + return snd_pcm_kernel_playback_ioctl(substream, cmd, arg); case SNDRV_PCM_STREAM_CAPTURE: - result = snd_pcm_capture_ioctl1(substream, - cmd, (void __user *)arg); - break; + return snd_pcm_kernel_capture_ioctl(substream, cmd, arg); default: - result = -EINVAL; - break; + return -EINVAL; } - snd_leave_user(fs); - return result; } static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 87b47c956..d4d124e21 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -58,7 +57,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device); static int snd_rawmidi_dev_unregister(struct snd_device *device); static LIST_HEAD(snd_rawmidi_devices); -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) { @@ -238,9 +237,9 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, if (rfile) rfile->input = rfile->output = NULL; - mutex_lock(®ister_mutex); + down(®ister_mutex); rmidi = snd_rawmidi_search(card, device); - mutex_unlock(®ister_mutex); + up(®ister_mutex); if (rmidi == NULL) { err = -ENODEV; goto __error1; @@ -250,7 +249,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, goto __error1; } if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - mutex_lock(&rmidi->open_mutex); + down(&rmidi->open_mutex); if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) { err = -ENXIO; @@ -360,7 +359,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, soutput = NULL; } if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - mutex_unlock(&rmidi->open_mutex); + up(&rmidi->open_mutex); if (rfile) { rfile->rmidi = rmidi; rfile->input = sinput; @@ -375,7 +374,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, snd_rawmidi_runtime_free(soutput); module_put(rmidi->card->module); if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - mutex_unlock(&rmidi->open_mutex); + up(&rmidi->open_mutex); __error1: return err; } @@ -423,7 +422,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) } init_waitqueue_entry(&wait, current); add_wait_queue(&rmidi->open_wait, &wait); - mutex_lock(&rmidi->open_mutex); + down(&rmidi->open_mutex); while (1) { subdevice = -1; down_read(&card->controls_rwsem); @@ -447,9 +446,9 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) } else break; set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&rmidi->open_mutex); + up(&rmidi->open_mutex); schedule(); - mutex_lock(&rmidi->open_mutex); + down(&rmidi->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -468,7 +467,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) snd_card_file_remove(card, file); kfree(rawmidi_file); } - mutex_unlock(&rmidi->open_mutex); + up(&rmidi->open_mutex); return err; } @@ -481,7 +480,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) snd_assert(rfile != NULL, return -ENXIO); snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); rmidi = rfile->rmidi; - mutex_lock(&rmidi->open_mutex); + down(&rmidi->open_mutex); if (rfile->input != NULL) { substream = rfile->input; rfile->input = NULL; @@ -515,7 +514,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) } rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--; } - mutex_unlock(&rmidi->open_mutex); + up(&rmidi->open_mutex); module_put(rmidi->card->module); return 0; } @@ -577,9 +576,9 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info struct snd_rawmidi_substream *substream; struct list_head *list; - mutex_lock(®ister_mutex); + down(®ister_mutex); rmidi = snd_rawmidi_search(card, info->device); - mutex_unlock(®ister_mutex); + up(®ister_mutex); if (!rmidi) return -ENXIO; if (info->stream < 0 || info->stream > 1) @@ -631,8 +630,7 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, return -EINVAL; } if (params->buffer_size != runtime->buffer_size) { - newbuf = kmalloc(params->buffer_size, GFP_KERNEL); - if (!newbuf) + if ((newbuf = (char *) kmalloc(params->buffer_size, GFP_KERNEL)) == NULL) return -ENOMEM; kfree(runtime->buffer); runtime->buffer = newbuf; @@ -658,8 +656,7 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, return -EINVAL; } if (params->buffer_size != runtime->buffer_size) { - newbuf = kmalloc(params->buffer_size, GFP_KERNEL); - if (!newbuf) + if ((newbuf = (char *) kmalloc(params->buffer_size, GFP_KERNEL)) == NULL) return -ENOMEM; kfree(runtime->buffer); runtime->buffer = newbuf; @@ -821,7 +818,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)argp)) return -EFAULT; - mutex_lock(®ister_mutex); + down(®ister_mutex); device = device < 0 ? 0 : device + 1; while (device < SNDRV_RAWMIDI_DEVICES) { if (snd_rawmidi_search(card, device)) @@ -830,7 +827,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, } if (device == SNDRV_RAWMIDI_DEVICES) device = -1; - mutex_unlock(®ister_mutex); + up(®ister_mutex); if (put_user(device, (int __user *)argp)) return -EFAULT; return 0; @@ -1317,7 +1314,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, rmidi = entry->private_data; snd_iprintf(buffer, "%s\n\n", rmidi->name); - mutex_lock(&rmidi->open_mutex); + down(&rmidi->open_mutex); if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { substream = list_entry(list, struct snd_rawmidi_substream, list); @@ -1358,7 +1355,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, } } } - mutex_unlock(&rmidi->open_mutex); + up(&rmidi->open_mutex); } /* @@ -1439,7 +1436,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, } rmidi->card = card; rmidi->device = device; - mutex_init(&rmidi->open_mutex); + init_MUTEX(&rmidi->open_mutex); init_waitqueue_head(&rmidi->open_wait); if (id != NULL) strlcpy(rmidi->id, id, sizeof(rmidi->id)); @@ -1510,9 +1507,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device) if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) return -ENOMEM; - mutex_lock(®ister_mutex); + down(®ister_mutex); if (snd_rawmidi_search(rmidi->card, rmidi->device)) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -EBUSY; } list_add_tail(&rmidi->list, &snd_rawmidi_devices); @@ -1522,14 +1519,14 @@ static int snd_rawmidi_dev_register(struct snd_device *device) &snd_rawmidi_f_ops, rmidi, name)) < 0) { snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); list_del(&rmidi->list); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return err; } if (rmidi->ops && rmidi->ops->dev_register && (err = rmidi->ops->dev_register(rmidi)) < 0) { snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); list_del(&rmidi->list); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return err; } #ifdef CONFIG_SND_OSSEMUL @@ -1556,7 +1553,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device) } } #endif /* CONFIG_SND_OSSEMUL */ - mutex_unlock(®ister_mutex); + up(®ister_mutex); sprintf(name, "midi%d", rmidi->device); entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); if (entry) { @@ -1586,9 +1583,9 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) { struct snd_rawmidi *rmidi = device->device_data; - mutex_lock(®ister_mutex); + down(®ister_mutex); list_del_init(&rmidi->list); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } @@ -1597,7 +1594,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device) struct snd_rawmidi *rmidi = device->device_data; snd_assert(rmidi != NULL, return -ENXIO); - mutex_lock(®ister_mutex); + down(®ister_mutex); list_del(&rmidi->list); if (rmidi->proc_entry) { snd_info_unregister(rmidi->proc_entry); @@ -1619,7 +1616,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device) if (rmidi->ops && rmidi->ops->dev_unregister) rmidi->ops->dev_unregister(rmidi); snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); - mutex_unlock(®ister_mutex); + up(®ister_mutex); #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) if (rmidi->seq_dev) { snd_device_free(rmidi->card, rmidi->seq_dev); diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c index 84704ccb1..15b6c8a3f 100644 --- a/sound/core/rtctimer.c +++ b/sound/core/rtctimer.c @@ -50,7 +50,9 @@ static int rtctimer_stop(struct snd_timer *t); * The hardware dependent description for this timer. */ static struct snd_timer_hardware rtc_hw = { - .flags = SNDRV_TIMER_HW_FIRST|SNDRV_TIMER_HW_AUTO, + .flags = SNDRV_TIMER_HW_AUTO | + SNDRV_TIMER_HW_FIRST | + SNDRV_TIMER_HW_TASKLET, .ticks = 100000000L, /* FIXME: XXX */ .open = rtctimer_open, .close = rtctimer_close, @@ -60,6 +62,7 @@ static struct snd_timer_hardware rtc_hw = { static int rtctimer_freq = RTC_FREQ; /* frequency */ static struct snd_timer *rtctimer; +static struct tasklet_struct rtc_tasklet; static rtc_task_t rtc_task; @@ -81,6 +84,7 @@ rtctimer_close(struct snd_timer *t) rtc_task_t *rtc = t->private_data; if (rtc) { rtc_unregister(rtc); + tasklet_kill(&rtc_tasklet); t->private_data = NULL; } return 0; @@ -105,12 +109,17 @@ rtctimer_stop(struct snd_timer *timer) return 0; } +static void rtctimer_tasklet(unsigned long data) +{ + snd_timer_interrupt((struct snd_timer *)data, 1); +} + /* * interrupt */ static void rtctimer_interrupt(void *private_data) { - snd_timer_interrupt(private_data, 1); + tasklet_hi_schedule(private_data); } @@ -139,9 +148,11 @@ static int __init rtctimer_init(void) timer->hw = rtc_hw; timer->hw.resolution = NANO_SEC / rtctimer_freq; + tasklet_init(&rtc_tasklet, rtctimer_tasklet, (unsigned long)timer); + /* set up RTC callback */ rtc_task.func = rtctimer_interrupt; - rtc_task.private_data = timer; + rtc_task.private_data = &rtc_tasklet; err = snd_timer_global_register(timer); if (err < 0) { diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index b99197851..c98f0ba13 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -125,7 +124,7 @@ module_exit(alsa_seq_oss_exit) * ALSA minor device interface */ -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); static int odev_open(struct inode *inode, struct file *file) @@ -137,9 +136,9 @@ odev_open(struct inode *inode, struct file *file) else level = SNDRV_SEQ_OSS_MODE_SYNTH; - mutex_lock(®ister_mutex); + down(®ister_mutex); rc = snd_seq_oss_open(file, level); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return rc; } @@ -154,9 +153,9 @@ odev_release(struct inode *inode, struct file *file) snd_seq_oss_drain_write(dp); - mutex_lock(®ister_mutex); + down(®ister_mutex); snd_seq_oss_release(dp); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } @@ -225,13 +224,13 @@ register_device(void) { int rc; - mutex_lock(®ister_mutex); + down(®ister_mutex); if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0, &seq_oss_f_ops, NULL, SNDRV_SEQ_OSS_DEVNAME)) < 0) { snd_printk(KERN_ERR "can't register device seq\n"); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return rc; } if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, @@ -240,24 +239,24 @@ register_device(void) SNDRV_SEQ_OSS_DEVNAME)) < 0) { snd_printk(KERN_ERR "can't register device music\n"); snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return rc; } debug_printk(("device registered\n")); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } static void unregister_device(void) { - mutex_lock(®ister_mutex); + down(®ister_mutex); debug_printk(("device unregistered\n")); if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0) snd_printk(KERN_ERR "error unregister device music\n"); if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0) snd_printk(KERN_ERR "error unregister device seq\n"); - mutex_unlock(®ister_mutex); + up(®ister_mutex); } /* @@ -271,12 +270,12 @@ static struct snd_info_entry *info_entry; static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) { - mutex_lock(®ister_mutex); + down(®ister_mutex); snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR); snd_seq_oss_system_info_read(buf); snd_seq_oss_synth_info_read(buf); snd_seq_oss_midi_info_read(buf); - mutex_unlock(®ister_mutex); + up(®ister_mutex); } diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index bb15d9ee8..fd2032eae 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -67,7 +67,7 @@ #define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT) static DEFINE_SPINLOCK(clients_lock); -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); /* * client table @@ -237,7 +237,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) client->type = NO_CLIENT; snd_use_lock_init(&client->use_lock); rwlock_init(&client->ports_lock); - mutex_init(&client->ports_mutex); + init_MUTEX(&client->ports_mutex); INIT_LIST_HEAD(&client->ports_list_head); /* find free slot in the client table */ @@ -290,7 +290,7 @@ static int seq_free_client1(struct snd_seq_client *client) static void seq_free_client(struct snd_seq_client * client) { - mutex_lock(®ister_mutex); + down(®ister_mutex); switch (client->type) { case NO_CLIENT: snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n", @@ -306,7 +306,7 @@ static void seq_free_client(struct snd_seq_client * client) snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n", client->number, client->type); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); snd_seq_system_client_ev_client_exit(client->number); } @@ -322,11 +322,11 @@ static int snd_seq_open(struct inode *inode, struct file *file) struct snd_seq_client *client; struct snd_seq_user_client *user; - if (mutex_lock_interruptible(®ister_mutex)) + if (down_interruptible(®ister_mutex)) return -ERESTARTSYS; client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS); if (client == NULL) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -ENOMEM; /* failure code */ } @@ -346,14 +346,14 @@ static int snd_seq_open(struct inode *inode, struct file *file) if (user->fifo == NULL) { seq_free_client1(client); kfree(client); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -ENOMEM; } } usage_alloc(&client_usage, 1); client->type = USER_CLIENT; - mutex_unlock(®ister_mutex); + up(®ister_mutex); c = client->number; file->private_data = client; @@ -1743,7 +1743,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, if (queue == NULL) return -EINVAL; - if (mutex_lock_interruptible(&queue->timer_mutex)) { + if (down_interruptible(&queue->timer_mutex)) { queuefree(queue); return -ERESTARTSYS; } @@ -1756,7 +1756,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, timer.u.alsa.id = tmr->alsa_id; timer.u.alsa.resolution = tmr->preferred_resolution; } - mutex_unlock(&queue->timer_mutex); + up(&queue->timer_mutex); queuefree(queue); if (copy_to_user(arg, &timer, sizeof(timer))) @@ -1785,7 +1785,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, q = queueptr(timer.queue); if (q == NULL) return -ENXIO; - if (mutex_lock_interruptible(&q->timer_mutex)) { + if (down_interruptible(&q->timer_mutex)) { queuefree(q); return -ERESTARTSYS; } @@ -1797,7 +1797,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, tmr->preferred_resolution = timer.u.alsa.resolution; } result = snd_seq_queue_timer_open(timer.queue); - mutex_unlock(&q->timer_mutex); + up(&q->timer_mutex); queuefree(q); } else { return -EPERM; @@ -1866,7 +1866,8 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, info.output_pool = cptr->pool->size; info.output_room = cptr->pool->room; info.output_free = info.output_pool; - info.output_free = snd_seq_unused_cells(cptr->pool); + if (cptr->pool) + info.output_free = snd_seq_unused_cells(cptr->pool); if (cptr->type == USER_CLIENT) { info.input_pool = cptr->data.user.fifo_pool_size; info.input_free = info.input_pool; @@ -2229,7 +2230,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS) return -EINVAL; - if (mutex_lock_interruptible(®ister_mutex)) + if (down_interruptible(®ister_mutex)) return -ERESTARTSYS; if (card) { @@ -2242,7 +2243,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, /* empty write queue as default */ client = seq_create_client1(client_index, 0); if (client == NULL) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -EBUSY; /* failure code */ } usage_alloc(&client_usage, 1); @@ -2255,7 +2256,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, va_end(args); client->type = KERNEL_CLIENT; - mutex_unlock(®ister_mutex); + up(®ister_mutex); /* make others aware this new client */ snd_seq_system_client_ev_client_start(client->number); @@ -2463,7 +2464,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, { struct list_head *l; - mutex_lock(&client->ports_mutex); + down(&client->ports_mutex); list_for_each(l, &client->ports_list_head) { struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n", @@ -2475,7 +2476,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: "); snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: "); } - mutex_unlock(&client->ports_mutex); + up(&client->ports_mutex); } @@ -2549,16 +2550,16 @@ int __init snd_sequencer_device_init(void) { int err; - if (mutex_lock_interruptible(®ister_mutex)) + if (down_interruptible(®ister_mutex)) return -ERESTARTSYS; if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, &snd_seq_f_ops, NULL, "seq")) < 0) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return err; } - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h index 5e04e20e2..450091ca1 100644 --- a/sound/core/seq/seq_clientmgr.h +++ b/sound/core/seq/seq_clientmgr.h @@ -58,7 +58,7 @@ struct snd_seq_client { int num_ports; /* number of ports */ struct list_head ports_list_head; rwlock_t ports_lock; - struct mutex ports_mutex; + struct semaphore ports_mutex; int convert32; /* convert 32->64bit */ /* output pool */ diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index d9a3e5a18..9ece443fb 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -45,7 +45,6 @@ #include #include #include -#include MODULE_AUTHOR("Takashi Iwai "); MODULE_DESCRIPTION("ALSA sequencer device management"); @@ -70,7 +69,7 @@ struct ops_list { struct list_head dev_list; /* list of devices */ int num_devices; /* number of associated devices */ int num_init_devices; /* number of initialized devices */ - struct mutex reg_mutex; + struct semaphore reg_mutex; struct list_head list; /* next driver */ }; @@ -78,7 +77,7 @@ struct ops_list { static LIST_HEAD(opslist); static int num_ops; -static DEFINE_MUTEX(ops_mutex); +static DECLARE_MUTEX(ops_mutex); #ifdef CONFIG_PROC_FS static struct snd_info_entry *info_entry = NULL; #endif @@ -109,7 +108,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, { struct list_head *head; - mutex_lock(&ops_mutex); + down(&ops_mutex); list_for_each(head, &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); snd_iprintf(buffer, "snd-%s%s%s%s,%d\n", @@ -119,7 +118,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, ops->driver & DRIVER_LOCKED ? ",locked" : "", ops->num_devices); } - mutex_unlock(&ops_mutex); + up(&ops_mutex); } #endif @@ -155,20 +154,20 @@ void snd_seq_device_load_drivers(void) if (! current->fs->root) return; - mutex_lock(&ops_mutex); + down(&ops_mutex); list_for_each(head, &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); if (! (ops->driver & DRIVER_LOADED) && ! (ops->driver & DRIVER_REQUESTED)) { ops->used++; - mutex_unlock(&ops_mutex); + up(&ops_mutex); ops->driver |= DRIVER_REQUESTED; request_module("snd-%s", ops->id); - mutex_lock(&ops_mutex); + down(&ops_mutex); ops->used--; } } - mutex_unlock(&ops_mutex); + up(&ops_mutex); #endif } @@ -215,10 +214,10 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, dev->status = SNDRV_SEQ_DEVICE_FREE; /* add this device to the list */ - mutex_lock(&ops->reg_mutex); + down(&ops->reg_mutex); list_add_tail(&dev->list, &ops->dev_list); ops->num_devices++; - mutex_unlock(&ops->reg_mutex); + up(&ops->reg_mutex); unlock_driver(ops); @@ -247,10 +246,10 @@ static int snd_seq_device_free(struct snd_seq_device *dev) return -ENXIO; /* remove the device from the list */ - mutex_lock(&ops->reg_mutex); + down(&ops->reg_mutex); list_del(&dev->list); ops->num_devices--; - mutex_unlock(&ops->reg_mutex); + up(&ops->reg_mutex); free_device(dev, ops); if (dev->private_free) @@ -345,7 +344,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, return -EBUSY; } - mutex_lock(&ops->reg_mutex); + down(&ops->reg_mutex); /* copy driver operators */ ops->ops = *entry; ops->driver |= DRIVER_LOADED; @@ -356,7 +355,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); init_device(dev, ops); } - mutex_unlock(&ops->reg_mutex); + up(&ops->reg_mutex); unlock_driver(ops); snd_seq_autoload_unlock(); @@ -379,17 +378,17 @@ static struct ops_list * create_driver(char *id) /* set up driver entry */ strlcpy(ops->id, id, sizeof(ops->id)); - mutex_init(&ops->reg_mutex); + init_MUTEX(&ops->reg_mutex); ops->driver = DRIVER_EMPTY; INIT_LIST_HEAD(&ops->dev_list); /* lock this instance */ ops->used = 1; /* register driver entry */ - mutex_lock(&ops_mutex); + down(&ops_mutex); list_add_tail(&ops->list, &opslist); num_ops++; - mutex_unlock(&ops_mutex); + up(&ops_mutex); return ops; } @@ -415,7 +414,7 @@ int snd_seq_device_unregister_driver(char *id) } /* close and release all devices associated with this driver */ - mutex_lock(&ops->reg_mutex); + down(&ops->reg_mutex); ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */ list_for_each(head, &ops->dev_list) { struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); @@ -426,7 +425,7 @@ int snd_seq_device_unregister_driver(char *id) if (ops->num_init_devices > 0) snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n", ops->num_init_devices); - mutex_unlock(&ops->reg_mutex); + up(&ops->reg_mutex); unlock_driver(ops); @@ -444,7 +443,7 @@ static void remove_drivers(void) { struct list_head *head; - mutex_lock(&ops_mutex); + down(&ops_mutex); head = opslist.next; while (head != &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); @@ -457,7 +456,7 @@ static void remove_drivers(void) } else head = head->next; } - mutex_unlock(&ops_mutex); + up(&ops_mutex); } /* @@ -520,16 +519,16 @@ static struct ops_list * find_driver(char *id, int create_if_empty) { struct list_head *head; - mutex_lock(&ops_mutex); + down(&ops_mutex); list_for_each(head, &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); if (strcmp(ops->id, id) == 0) { ops->used++; - mutex_unlock(&ops_mutex); + up(&ops_mutex); return ops; } } - mutex_unlock(&ops_mutex); + up(&ops_mutex); if (create_if_empty) return create_driver(id); return NULL; @@ -537,9 +536,9 @@ static struct ops_list * find_driver(char *id, int create_if_empty) static void unlock_driver(struct ops_list *ops) { - mutex_lock(&ops_mutex); + down(&ops_mutex); ops->used--; - mutex_unlock(&ops_mutex); + up(&ops_mutex); } diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c index f30d171b6..487452063 100644 --- a/sound/core/seq/seq_instr.c +++ b/sound/core/seq/seq_instr.c @@ -36,7 +36,7 @@ static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list) if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { spin_lock_irqsave(&list->ops_lock, list->ops_flags); } else { - mutex_lock(&list->ops_mutex); + down(&list->ops_mutex); } } @@ -45,7 +45,7 @@ static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list) if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { spin_unlock_irqrestore(&list->ops_lock, list->ops_flags); } else { - mutex_unlock(&list->ops_mutex); + up(&list->ops_mutex); } } @@ -82,7 +82,7 @@ struct snd_seq_kinstr_list *snd_seq_instr_list_new(void) return NULL; spin_lock_init(&list->lock); spin_lock_init(&list->ops_lock); - mutex_init(&list->ops_mutex); + init_MUTEX(&list->ops_mutex); list->owner = -1; return list; } diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 9caa1372b..ce0df8615 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c @@ -32,7 +32,7 @@ Possible options for midisynth module: #include #include #include -#include +#include #include #include #include @@ -70,7 +70,7 @@ struct seq_midisynth_client { }; static struct seq_midisynth_client *synths[SNDRV_CARDS]; -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); /* handle rawmidi input event (MIDI v1.0 stream) */ static void snd_midi_input_event(struct snd_rawmidi_substream *substream) @@ -308,13 +308,13 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) if (ports > (256 / SNDRV_RAWMIDI_DEVICES)) ports = 256 / SNDRV_RAWMIDI_DEVICES; - mutex_lock(®ister_mutex); + down(®ister_mutex); client = synths[card->number]; if (client == NULL) { newclient = 1; client = kzalloc(sizeof(*client), GFP_KERNEL); if (client == NULL) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); kfree(info); return -ENOMEM; } @@ -324,7 +324,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) (const char *)info->name : "External MIDI"); if (client->seq_client < 0) { kfree(client); - mutex_unlock(®ister_mutex); + up(®ister_mutex); kfree(info); return -ENOMEM; } @@ -397,7 +397,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) client->num_ports++; if (newclient) synths[card->number] = client; - mutex_unlock(®ister_mutex); + up(®ister_mutex); kfree(info); kfree(port); return 0; /* success */ @@ -414,7 +414,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) } kfree(info); kfree(port); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -ENOMEM; } @@ -427,10 +427,10 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) struct snd_card *card = dev->card; int device = dev->device, p, ports; - mutex_lock(®ister_mutex); + down(®ister_mutex); client = synths[card->number]; if (client == NULL || client->ports[device] == NULL) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -ENODEV; } ports = client->ports_per_device[device]; @@ -446,7 +446,7 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) synths[card->number] = NULL; kfree(client); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 2ef8fb52e..2b384fd79 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -159,7 +159,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, port_subs_info_init(&new_port->c_dest); num = port >= 0 ? port : 0; - mutex_lock(&client->ports_mutex); + down(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); list_for_each(l, &client->ports_list_head) { struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); @@ -173,7 +173,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, client->num_ports++; new_port->addr.port = num; /* store the port number in the port */ write_unlock_irqrestore(&client->ports_lock, flags); - mutex_unlock(&client->ports_mutex); + up(&client->ports_mutex); sprintf(new_port->name, "port-%d", num); return new_port; @@ -292,7 +292,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port) struct list_head *l; struct snd_seq_client_port *found = NULL; - mutex_lock(&client->ports_mutex); + down(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); list_for_each(l, &client->ports_list_head) { struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); @@ -305,7 +305,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port) } } write_unlock_irqrestore(&client->ports_lock, flags); - mutex_unlock(&client->ports_mutex); + up(&client->ports_mutex); if (found) return port_delete(client, found); else @@ -321,11 +321,13 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) /* move the port list to deleted_list, and * clear the port list in the client data. */ - mutex_lock(&client->ports_mutex); + down(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); if (! list_empty(&client->ports_list_head)) { - list_add(&deleted_list, &client->ports_list_head); - list_del_init(&client->ports_list_head); + __list_add(&deleted_list, + client->ports_list_head.prev, + client->ports_list_head.next); + INIT_LIST_HEAD(&client->ports_list_head); } else { INIT_LIST_HEAD(&deleted_list); } @@ -339,7 +341,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); port_delete(client, port); } - mutex_unlock(&client->ports_mutex); + up(&client->ports_mutex); return 0; } diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 9b87bb0c7..9cf20f045 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -119,7 +119,7 @@ static struct snd_seq_queue *queue_new(int owner, int locked) spin_lock_init(&q->owner_lock); spin_lock_init(&q->check_lock); - mutex_init(&q->timer_mutex); + init_MUTEX(&q->timer_mutex); snd_use_lock_init(&q->use_lock); q->queue = -1; @@ -516,7 +516,7 @@ int snd_seq_queue_use(int queueid, int client, int use) queue = queueptr(queueid); if (queue == NULL) return -EINVAL; - mutex_lock(&queue->timer_mutex); + down(&queue->timer_mutex); if (use) { if (!test_and_set_bit(client, queue->clients_bitmap)) queue->clients++; @@ -531,7 +531,7 @@ int snd_seq_queue_use(int queueid, int client, int use) } else { snd_seq_timer_close(queue); } - mutex_unlock(&queue->timer_mutex); + up(&queue->timer_mutex); queuefree(queue); return 0; } diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h index 30c811147..888438599 100644 --- a/sound/core/seq/seq_queue.h +++ b/sound/core/seq/seq_queue.h @@ -54,7 +54,7 @@ struct snd_seq_queue { /* clients which uses this queue (bitmap) */ DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS); unsigned int clients; /* users of this queue */ - struct mutex timer_mutex; + struct semaphore timer_mutex; snd_use_lock_t use_lock; }; diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index f4edec603..14fd1a608 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -167,7 +167,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, return; /* ignored */ } if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { - if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) + if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) return; vmidi->event.type = SNDRV_SEQ_EVENT_NONE; } @@ -186,7 +186,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, pbuf += res; count -= res; if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { - if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) + if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) return; vmidi->event.type = SNDRV_SEQ_EVENT_NONE; } diff --git a/sound/core/sound.c b/sound/core/sound.c index 108e430b5..5ac097605 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -33,7 +33,6 @@ #include #include #include -#include #define SNDRV_OS_MINORS 256 @@ -62,7 +61,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); int snd_ecards_limit; static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; -static DEFINE_MUTEX(sound_mutex); +static DECLARE_MUTEX(sound_mutex); extern struct class *sound_class; @@ -123,13 +122,13 @@ void *snd_lookup_minor_data(unsigned int minor, int type) if (minor >= ARRAY_SIZE(snd_minors)) return NULL; - mutex_lock(&sound_mutex); + down(&sound_mutex); mreg = snd_minors[minor]; if (mreg && mreg->type == type) private_data = mreg->private_data; else private_data = NULL; - mutex_unlock(&sound_mutex); + up(&sound_mutex); return private_data; } @@ -137,7 +136,7 @@ static int snd_open(struct inode *inode, struct file *file) { unsigned int minor = iminor(inode); struct snd_minor *mptr = NULL; - const struct file_operations *old_fops; + struct file_operations *old_fops; int err = 0; if (minor >= ARRAY_SIZE(snd_minors)) @@ -240,7 +239,7 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev) * Retrurns zero if successful, or a negative error code on failure. */ int snd_register_device(int type, struct snd_card *card, int dev, - const struct file_operations *f_ops, void *private_data, + struct file_operations *f_ops, void *private_data, const char *name) { int minor; @@ -257,7 +256,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, preg->f_ops = f_ops; preg->private_data = private_data; strcpy(preg->name, name); - mutex_lock(&sound_mutex); + down(&sound_mutex); #ifdef CONFIG_SND_DYNAMIC_MINORS minor = snd_find_free_minor(); #else @@ -266,7 +265,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, minor = -EBUSY; #endif if (minor < 0) { - mutex_unlock(&sound_mutex); + up(&sound_mutex); kfree(preg); return minor; } @@ -277,7 +276,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, device = card->dev; class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name); - mutex_unlock(&sound_mutex); + up(&sound_mutex); return 0; } @@ -298,7 +297,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) struct snd_minor *mptr; cardnum = card ? card->number : -1; - mutex_lock(&sound_mutex); + down(&sound_mutex); for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) if ((mptr = snd_minors[minor]) != NULL && mptr->type == type && @@ -306,7 +305,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) mptr->device == dev) break; if (minor == ARRAY_SIZE(snd_minors)) { - mutex_unlock(&sound_mutex); + up(&sound_mutex); return -EINVAL; } @@ -316,7 +315,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) class_device_destroy(sound_class, MKDEV(major, minor)); snd_minors[minor] = NULL; - mutex_unlock(&sound_mutex); + up(&sound_mutex); kfree(mptr); return 0; } @@ -355,7 +354,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu int minor; struct snd_minor *mptr; - mutex_lock(&sound_mutex); + down(&sound_mutex); for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { if (!(mptr = snd_minors[minor])) continue; @@ -372,7 +371,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu snd_iprintf(buffer, "%3i: : %s\n", minor, snd_device_type_name(mptr->type)); } - mutex_unlock(&sound_mutex); + up(&sound_mutex); } int __init snd_minor_info_init(void) diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index 9055c6de9..79752205c 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c @@ -34,12 +34,11 @@ #include #include #include -#include #define SNDRV_OSS_MINORS 128 static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; -static DEFINE_MUTEX(sound_oss_mutex); +static DECLARE_MUTEX(sound_oss_mutex); void *snd_lookup_oss_minor_data(unsigned int minor, int type) { @@ -48,13 +47,13 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) if (minor >= ARRAY_SIZE(snd_oss_minors)) return NULL; - mutex_lock(&sound_oss_mutex); + down(&sound_oss_mutex); mreg = snd_oss_minors[minor]; if (mreg && mreg->type == type) private_data = mreg->private_data; else private_data = NULL; - mutex_unlock(&sound_oss_mutex); + up(&sound_oss_mutex); return private_data; } @@ -95,7 +94,7 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) } int snd_register_oss_device(int type, struct snd_card *card, int dev, - const struct file_operations *f_ops, void *private_data, + struct file_operations *f_ops, void *private_data, const char *name) { int minor = snd_oss_kernel_minor(type, card, dev); @@ -118,7 +117,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; - mutex_lock(&sound_oss_mutex); + down(&sound_oss_mutex); snd_oss_minors[minor] = preg; minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); switch (minor_unit) { @@ -144,7 +143,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, goto __end; snd_oss_minors[track2] = preg; } - mutex_unlock(&sound_oss_mutex); + up(&sound_oss_mutex); return 0; __end: @@ -153,7 +152,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, if (register1 >= 0) unregister_sound_special(register1); snd_oss_minors[minor] = NULL; - mutex_unlock(&sound_oss_mutex); + up(&sound_oss_mutex); kfree(preg); return -EBUSY; } @@ -169,10 +168,10 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) return 0; if (minor < 0) return minor; - mutex_lock(&sound_oss_mutex); + down(&sound_oss_mutex); mptr = snd_oss_minors[minor]; if (mptr == NULL) { - mutex_unlock(&sound_oss_mutex); + up(&sound_oss_mutex); return -ENOENT; } unregister_sound_special(minor); @@ -192,7 +191,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) snd_oss_minors[track2] = NULL; } snd_oss_minors[minor] = NULL; - mutex_unlock(&sound_oss_mutex); + up(&sound_oss_mutex); kfree(mptr); return 0; } @@ -230,7 +229,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry, int minor; struct snd_minor *mptr; - mutex_lock(&sound_oss_mutex); + down(&sound_oss_mutex); for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) { if (!(mptr = snd_oss_minors[minor])) continue; @@ -242,7 +241,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry, snd_iprintf(buffer, "%3i: : %s\n", minor, snd_oss_device_type_name(mptr->type)); } - mutex_unlock(&sound_oss_mutex); + up(&sound_oss_mutex); } diff --git a/sound/core/timer.c b/sound/core/timer.c index 4585600ba..c7670f5c4 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -71,7 +70,7 @@ struct snd_timer_user { struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; - struct mutex tread_sem; + struct semaphore tread_sem; }; /* list of timers */ @@ -83,7 +82,7 @@ static LIST_HEAD(snd_timer_slave_list); /* lock for slave active lists */ static DEFINE_SPINLOCK(slave_active_lock); -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); static int snd_timer_free(struct snd_timer *timer); static int snd_timer_dev_free(struct snd_device *device); @@ -253,10 +252,10 @@ int snd_timer_open(struct snd_timer_instance **ti, snd_printd("invalid slave class %i\n", tid->dev_sclass); return -EINVAL; } - mutex_lock(®ister_mutex); + down(®ister_mutex); timeri = snd_timer_instance_new(owner, NULL); if (!timeri) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -ENOMEM; } timeri->slave_class = tid->dev_sclass; @@ -264,37 +263,37 @@ int snd_timer_open(struct snd_timer_instance **ti, timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; list_add_tail(&timeri->open_list, &snd_timer_slave_list); snd_timer_check_slave(timeri); - mutex_unlock(®ister_mutex); + up(®ister_mutex); *ti = timeri; return 0; } /* open a master instance */ - mutex_lock(®ister_mutex); + down(®ister_mutex); timer = snd_timer_find(tid); #ifdef CONFIG_KMOD if (timer == NULL) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); snd_timer_request(tid); - mutex_lock(®ister_mutex); + down(®ister_mutex); timer = snd_timer_find(tid); } #endif if (!timer) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -ENODEV; } if (!list_empty(&timer->open_list_head)) { timeri = list_entry(timer->open_list_head.next, struct snd_timer_instance, open_list); if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -EBUSY; } } timeri = snd_timer_instance_new(owner, timer); if (!timeri) { - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -ENOMEM; } timeri->slave_class = tid->dev_sclass; @@ -303,7 +302,7 @@ int snd_timer_open(struct snd_timer_instance **ti, timer->hw.open(timer); list_add_tail(&timeri->open_list, &timer->open_list_head); snd_timer_check_master(timeri); - mutex_unlock(®ister_mutex); + up(®ister_mutex); *ti = timeri; return 0; } @@ -334,9 +333,9 @@ int snd_timer_close(struct snd_timer_instance *timeri) spin_lock_irq(&slave_active_lock); } spin_unlock_irq(&slave_active_lock); - mutex_lock(®ister_mutex); + down(®ister_mutex); list_del(&timeri->open_list); - mutex_unlock(®ister_mutex); + up(®ister_mutex); } else { timer = timeri->timer; /* wait, until the active callback is finished */ @@ -347,7 +346,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) spin_lock_irq(&timer->lock); } spin_unlock_irq(&timer->lock); - mutex_lock(®ister_mutex); + down(®ister_mutex); list_del(&timeri->open_list); if (timer && list_empty(&timer->open_list_head) && timer->hw.close) @@ -363,7 +362,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) slave->timer = NULL; spin_unlock_irq(&slave_active_lock); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); } if (timeri->private_free) timeri->private_free(timeri); @@ -837,7 +836,7 @@ static int snd_timer_dev_register(struct snd_device *dev) !timer->hw.resolution && timer->hw.c_resolution == NULL) return -EINVAL; - mutex_lock(®ister_mutex); + down(®ister_mutex); list_for_each(p, &snd_timer_list) { timer1 = list_entry(p, struct snd_timer, device_list); if (timer1->tmr_class > timer->tmr_class) @@ -859,11 +858,11 @@ static int snd_timer_dev_register(struct snd_device *dev) if (timer1->tmr_subdevice < timer->tmr_subdevice) continue; /* conflicts.. */ - mutex_unlock(®ister_mutex); + up(®ister_mutex); return -EBUSY; } list_add_tail(&timer->device_list, p); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return 0; } @@ -873,7 +872,7 @@ static int snd_timer_unregister(struct snd_timer *timer) struct snd_timer_instance *ti; snd_assert(timer != NULL, return -ENXIO); - mutex_lock(®ister_mutex); + down(®ister_mutex); if (! list_empty(&timer->open_list_head)) { snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); list_for_each_safe(p, n, &timer->open_list_head) { @@ -883,7 +882,7 @@ static int snd_timer_unregister(struct snd_timer *timer) } } list_del(&timer->device_list); - mutex_unlock(®ister_mutex); + up(®ister_mutex); return snd_timer_free(timer); } @@ -1067,7 +1066,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, struct snd_timer_instance *ti; struct list_head *p, *q; - mutex_lock(®ister_mutex); + down(®ister_mutex); list_for_each(p, &snd_timer_list) { timer = list_entry(p, struct snd_timer, device_list); switch (timer->tmr_class) { @@ -1107,7 +1106,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, } spin_unlock_irqrestore(&timer->lock, flags); } - mutex_unlock(®ister_mutex); + up(®ister_mutex); } static struct snd_info_entry *snd_timer_proc_entry = NULL; @@ -1271,7 +1270,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); - mutex_init(&tu->tread_sem); + init_MUTEX(&tu->tread_sem); tu->ticks = 1; tu->queue_size = 128; tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), @@ -1327,7 +1326,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid) if (copy_from_user(&id, _tid, sizeof(id))) return -EFAULT; - mutex_lock(®ister_mutex); + down(®ister_mutex); if (id.dev_class < 0) { /* first item */ if (list_empty(&snd_timer_list)) snd_timer_user_zero_id(&id); @@ -1409,7 +1408,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid) snd_timer_user_zero_id(&id); } } - mutex_unlock(®ister_mutex); + up(®ister_mutex); if (copy_to_user(_tid, &id, sizeof(*_tid))) return -EFAULT; return 0; @@ -1434,7 +1433,7 @@ static int snd_timer_user_ginfo(struct file *file, tid = ginfo->tid; memset(ginfo, 0, sizeof(*ginfo)); ginfo->tid = tid; - mutex_lock(®ister_mutex); + down(®ister_mutex); t = snd_timer_find(&tid); if (t != NULL) { ginfo->card = t->card ? t->card->number : -1; @@ -1453,7 +1452,7 @@ static int snd_timer_user_ginfo(struct file *file, } else { err = -ENODEV; } - mutex_unlock(®ister_mutex); + up(®ister_mutex); if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo))) err = -EFAULT; kfree(ginfo); @@ -1469,7 +1468,7 @@ static int snd_timer_user_gparams(struct file *file, if (copy_from_user(&gparams, _gparams, sizeof(gparams))) return -EFAULT; - mutex_lock(®ister_mutex); + down(®ister_mutex); t = snd_timer_find(&gparams.tid); if (!t) { err = -ENODEV; @@ -1485,7 +1484,7 @@ static int snd_timer_user_gparams(struct file *file, } err = t->hw.set_period(t, gparams.period_num, gparams.period_den); _error: - mutex_unlock(®ister_mutex); + up(®ister_mutex); return err; } @@ -1502,7 +1501,7 @@ static int snd_timer_user_gstatus(struct file *file, tid = gstatus.tid; memset(&gstatus, 0, sizeof(gstatus)); gstatus.tid = tid; - mutex_lock(®ister_mutex); + down(®ister_mutex); t = snd_timer_find(&tid); if (t != NULL) { if (t->hw.c_resolution) @@ -1519,7 +1518,7 @@ static int snd_timer_user_gstatus(struct file *file, } else { err = -ENODEV; } - mutex_unlock(®ister_mutex); + up(®ister_mutex); if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus))) err = -EFAULT; return err; @@ -1534,7 +1533,7 @@ static int snd_timer_user_tselect(struct file *file, int err = 0; tu = file->private_data; - mutex_lock(&tu->tread_sem); + down(&tu->tread_sem); if (tu->timeri) { snd_timer_close(tu->timeri); tu->timeri = NULL; @@ -1578,7 +1577,7 @@ static int snd_timer_user_tselect(struct file *file, } __err: - mutex_unlock(&tu->tread_sem); + up(&tu->tread_sem); return err; } @@ -1799,17 +1798,17 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, { int xarg; - mutex_lock(&tu->tread_sem); + down(&tu->tread_sem); if (tu->timeri) { /* too late */ - mutex_unlock(&tu->tread_sem); + up(&tu->tread_sem); return -EBUSY; } if (get_user(xarg, p)) { - mutex_unlock(&tu->tread_sem); + up(&tu->tread_sem); return -EFAULT; } tu->tread = xarg ? 1 : 0; - mutex_unlock(&tu->tread_sem); + up(&tu->tread_sem); return 0; } case SNDRV_TIMER_IOCTL_GINFO: diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index ae0df549f..14e1a671b 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -669,14 +669,14 @@ static int __init alsa_card_dummy_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(SND_DUMMY_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; + } devices[i] = device; cards++; } @@ -684,10 +684,14 @@ static int __init alsa_card_dummy_init(void) #ifdef MODULE printk(KERN_ERR "Dummy soundcard not found or device busy\n"); #endif - snd_dummy_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_dummy_unregister_all(); + return err; } static void __exit alsa_card_dummy_exit(void) diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 77b060097..915589a40 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c @@ -59,8 +59,7 @@ module_param_array(irq, int, NULL, 0444); MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); static struct platform_device *platform_devices[SNDRV_CARDS]; -static int pnp_registered; -static unsigned int snd_mpu401_devices; +static int pnp_registered = 0; static int snd_mpu401_create(int dev, struct snd_card **rcard) { @@ -151,7 +150,7 @@ static struct pnp_device_id snd_mpu401_pnpids[] = { MODULE_DEVICE_TABLE(pnp, snd_mpu401_pnpids); -static int __devinit snd_mpu401_pnp(int dev, struct pnp_dev *device, +static int __init snd_mpu401_pnp(int dev, struct pnp_dev *device, const struct pnp_device_id *id) { if (!pnp_port_valid(device, 0) || @@ -198,7 +197,6 @@ static int __devinit snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev, } snd_card_set_dev(card, &pnp_dev->dev); pnp_set_drvdata(pnp_dev, card); - snd_mpu401_devices++; ++dev; return 0; } @@ -236,38 +234,44 @@ static void __init_or_module snd_mpu401_unregister_all(void) static int __init alsa_card_mpu401_init(void) { - int i, err; + int i, err, devices; if ((err = platform_driver_register(&snd_mpu401_driver)) < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { + devices = 0; + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; #ifdef CONFIG_PNP if (pnp[i]) continue; #endif device = platform_device_register_simple(SND_MPU401_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; + } platform_devices[i] = device; - snd_mpu401_devices++; + devices++; } - err = pnp_register_driver(&snd_mpu401_pnp_driver); - if (!err) + if ((err = pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) { pnp_registered = 1; + devices += err; + } - if (!snd_mpu401_devices) { + if (!devices) { #ifdef MODULE printk(KERN_ERR "MPU-401 device not found or device busy\n"); #endif - snd_mpu401_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_mpu401_unregister_all(); + return err; } static void __exit alsa_card_mpu401_exit(void) diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index b49a45cbf..8687ae3c6 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c @@ -183,8 +183,7 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input) */ -static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, - int ack) +static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int ack) { unsigned long flags; int timeout, ok; @@ -219,11 +218,9 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, ok = 1; } spin_unlock_irqrestore(&mpu->input_lock, flags); - if (!ok) { + if (! ok) snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); - return 1; - } - return 0; + // snd_printk("cmd: 0x%x at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); } /* @@ -238,19 +235,12 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream) if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) return err; if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { - if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) - goto error_out; - if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) - goto error_out; + snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); + snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); } mpu->substream_input = substream; set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); return 0; - -error_out: - if (mpu->open_input && mpu->close_input) - mpu->close_input(mpu); - return -EIO; } static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) @@ -262,52 +252,39 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) return err; if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { - if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) - goto error_out; - if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) - goto error_out; + snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); + snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); } mpu->substream_output = substream; set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); return 0; - -error_out: - if (mpu->open_output && mpu->close_output) - mpu->close_output(mpu); - return -EIO; } static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream) { struct snd_mpu401 *mpu; - int err = 0; mpu = substream->rmidi->private_data; clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); mpu->substream_input = NULL; if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) - err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); + snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); if (mpu->close_input) mpu->close_input(mpu); - if (err) - return -EIO; return 0; } static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream) { struct snd_mpu401 *mpu; - int err = 0; mpu = substream->rmidi->private_data; clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); mpu->substream_output = NULL; if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) - err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); + snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); if (mpu->close_output) mpu->close_output(mpu); - if (err) - return -EIO; return 0; } @@ -339,7 +316,6 @@ static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substrea snd_mpu401_uart_remove_timer(mpu, 1); clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); } - } /* diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c index 4f8556976..1e0c76b9a 100644 --- a/sound/drivers/opl3/opl3_lib.c +++ b/sound/drivers/opl3/opl3_lib.c @@ -358,7 +358,7 @@ int snd_opl3_new(struct snd_card *card, opl3->hardware = hardware; spin_lock_init(&opl3->reg_lock); spin_lock_init(&opl3->timer_lock); - mutex_init(&opl3->access_mutex); + init_MUTEX(&opl3->access_mutex); if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) { snd_opl3_free(opl3); diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c index 57becf34f..56b1d1a96 100644 --- a/sound/drivers/opl3/opl3_seq.c +++ b/sound/drivers/opl3/opl3_seq.c @@ -52,13 +52,13 @@ int snd_opl3_synth_setup(struct snd_opl3 * opl3) { int idx; - mutex_lock(&opl3->access_mutex); + down(&opl3->access_mutex); if (opl3->used) { - mutex_unlock(&opl3->access_mutex); + up(&opl3->access_mutex); return -EBUSY; } opl3->used++; - mutex_unlock(&opl3->access_mutex); + up(&opl3->access_mutex); snd_opl3_reset(opl3); @@ -91,9 +91,9 @@ void snd_opl3_synth_cleanup(struct snd_opl3 * opl3) spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); snd_opl3_reset(opl3); - mutex_lock(&opl3->access_mutex); + down(&opl3->access_mutex); opl3->used--; - mutex_unlock(&opl3->access_mutex); + up(&opl3->access_mutex); } static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info) diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c index 6db503f02..3534a0e33 100644 --- a/sound/drivers/opl3/opl3_synth.c +++ b/sound/drivers/opl3/opl3_synth.c @@ -76,13 +76,13 @@ int snd_opl3_open(struct snd_hwdep * hw, struct file *file) { struct snd_opl3 *opl3 = hw->private_data; - mutex_lock(&opl3->access_mutex); + down(&opl3->access_mutex); if (opl3->used) { - mutex_unlock(&opl3->access_mutex); + up(&opl3->access_mutex); return -EAGAIN; } opl3->used++; - mutex_unlock(&opl3->access_mutex); + up(&opl3->access_mutex); return 0; } @@ -179,9 +179,9 @@ int snd_opl3_release(struct snd_hwdep * hw, struct file *file) struct snd_opl3 *opl3 = hw->private_data; snd_opl3_reset(opl3); - mutex_lock(&opl3->access_mutex); + down(&opl3->access_mutex); opl3->used--; - mutex_unlock(&opl3->access_mutex); + up(&opl3->access_mutex); return 0; } diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c index 4bc860ae0..ddfc10d04 100644 --- a/sound/drivers/opl4/opl4_lib.c +++ b/sound/drivers/opl4/opl4_lib.c @@ -214,7 +214,7 @@ int snd_opl4_create(struct snd_card *card, opl4->fm_port = fm_port; opl4->pcm_port = pcm_port; spin_lock_init(&opl4->reg_lock); - mutex_init(&opl4->access_mutex); + init_MUTEX(&opl4->access_mutex); err = snd_opl4_detect(opl4); if (err < 0) { diff --git a/sound/drivers/opl4/opl4_local.h b/sound/drivers/opl4/opl4_local.h index 470e5a758..7e088a4a2 100644 --- a/sound/drivers/opl4/opl4_local.h +++ b/sound/drivers/opl4/opl4_local.h @@ -182,7 +182,7 @@ struct snd_opl4 { struct snd_info_entry *proc_entry; int memory_access; #endif - struct mutex access_mutex; + struct semaphore access_mutex; #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) int used; diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c index e552ec341..f4b4e74fc 100644 --- a/sound/drivers/opl4/opl4_proc.c +++ b/sound/drivers/opl4/opl4_proc.c @@ -28,13 +28,13 @@ static int snd_opl4_mem_proc_open(struct snd_info_entry *entry, { struct snd_opl4 *opl4 = entry->private_data; - mutex_lock(&opl4->access_mutex); + down(&opl4->access_mutex); if (opl4->memory_access) { - mutex_unlock(&opl4->access_mutex); + up(&opl4->access_mutex); return -EBUSY; } opl4->memory_access++; - mutex_unlock(&opl4->access_mutex); + up(&opl4->access_mutex); return 0; } @@ -43,9 +43,9 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry, { struct snd_opl4 *opl4 = entry->private_data; - mutex_lock(&opl4->access_mutex); + down(&opl4->access_mutex); opl4->memory_access--; - mutex_unlock(&opl4->access_mutex); + up(&opl4->access_mutex); return 0; } diff --git a/sound/drivers/opl4/opl4_seq.c b/sound/drivers/opl4/opl4_seq.c index dc0dcdc6c..e3480326e 100644 --- a/sound/drivers/opl4/opl4_seq.c +++ b/sound/drivers/opl4/opl4_seq.c @@ -62,10 +62,10 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i struct snd_opl4 *opl4 = private_data; int err; - mutex_lock(&opl4->access_mutex); + down(&opl4->access_mutex); if (opl4->used) { - mutex_unlock(&opl4->access_mutex); + up(&opl4->access_mutex); return -EBUSY; } opl4->used++; @@ -73,12 +73,12 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) { err = snd_opl4_seq_use_inc(opl4); if (err < 0) { - mutex_unlock(&opl4->access_mutex); + up(&opl4->access_mutex); return err; } } - mutex_unlock(&opl4->access_mutex); + up(&opl4->access_mutex); snd_opl4_synth_reset(opl4); return 0; @@ -90,9 +90,9 @@ static int snd_opl4_seq_unuse(void *private_data, struct snd_seq_port_subscribe snd_opl4_synth_shutdown(opl4); - mutex_lock(&opl4->access_mutex); + down(&opl4->access_mutex); opl4->used--; - mutex_unlock(&opl4->access_mutex); + up(&opl4->access_mutex); if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) snd_opl4_seq_use_dec(opl4); diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index c01b4c511..112ddf705 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c @@ -789,7 +789,6 @@ static int __init snd_uart16550_create(struct snd_card *card, if ((err = snd_uart16550_detect(uart)) <= 0) { printk(KERN_ERR "no UART detected at 0x%lx\n", iobase); - snd_uart16550_free(uart); return -ENODEV; } @@ -990,14 +989,14 @@ static int __init alsa_card_serial_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(SND_SERIAL_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; + } devices[i] = device; cards++; } @@ -1005,10 +1004,14 @@ static int __init alsa_card_serial_init(void) #ifdef MODULE printk(KERN_ERR "serial midi soundcard not found or device busy\n"); #endif - snd_serial_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_serial_unregister_all(); + return err; } static void __exit alsa_card_serial_exit(void) diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c index 26eb2499d..4258723de 100644 --- a/sound/drivers/virmidi.c +++ b/sound/drivers/virmidi.c @@ -163,14 +163,14 @@ static int __init alsa_card_virmidi_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(SND_VIRMIDI_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; + } devices[i] = device; cards++; } @@ -178,10 +178,14 @@ static int __init alsa_card_virmidi_init(void) #ifdef MODULE printk(KERN_ERR "Card-VirMIDI soundcard not found or device busy\n"); #endif - snd_virmidi_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_virmidi_unregister_all(); + return err; } static void __exit alsa_card_virmidi_exit(void) diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index fa4a2b5c2..43f615d7a 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c @@ -778,7 +778,7 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw, chip->type = hw->type; chip->ops = ops; tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip); - mutex_init(&chip->mixer_mutex); + init_MUTEX(&chip->mixer_mutex); chip->card = card; card->private_data = chip; diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c index c1d7fcdd1..8ec2c605d 100644 --- a/sound/drivers/vx/vx_mixer.c +++ b/sound/drivers/vx/vx_mixer.c @@ -427,10 +427,10 @@ static int vx_output_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele { struct vx_core *chip = snd_kcontrol_chip(kcontrol); int codec = kcontrol->id.index; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); ucontrol->value.integer.value[0] = chip->output_level[codec][0]; ucontrol->value.integer.value[1] = chip->output_level[codec][1]; - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -438,7 +438,7 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele { struct vx_core *chip = snd_kcontrol_chip(kcontrol); int codec = kcontrol->id.index; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); if (ucontrol->value.integer.value[0] != chip->output_level[codec][0] || ucontrol->value.integer.value[1] != chip->output_level[codec][1]) { vx_set_analog_output_level(chip, codec, @@ -446,10 +446,10 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele ucontrol->value.integer.value[1]); chip->output_level[codec][0] = ucontrol->value.integer.value[0]; chip->output_level[codec][1] = ucontrol->value.integer.value[1]; - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 1; } - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -502,14 +502,14 @@ static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct vx_core *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) { chip->audio_source_target = ucontrol->value.enumerated.item[0]; vx_sync_audio_source(chip); - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 1; } - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -550,14 +550,14 @@ static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct vx_core *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); if (chip->clock_mode != ucontrol->value.enumerated.item[0]) { chip->clock_mode = ucontrol->value.enumerated.item[0]; vx_set_clock(chip, chip->freq); - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 1; } - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -587,10 +587,10 @@ static int vx_audio_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ int audio = kcontrol->private_value & 0xff; int capture = (kcontrol->private_value >> 8) & 1; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio]; ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1]; - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -600,15 +600,15 @@ static int vx_audio_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ int audio = kcontrol->private_value & 0xff; int capture = (kcontrol->private_value >> 8) & 1; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); if (ucontrol->value.integer.value[0] != chip->audio_gain[capture][audio] || ucontrol->value.integer.value[1] != chip->audio_gain[capture][audio+1]) { vx_set_audio_gain(chip, audio, capture, ucontrol->value.integer.value[0]); vx_set_audio_gain(chip, audio+1, capture, ucontrol->value.integer.value[1]); - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 1; } - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -617,10 +617,10 @@ static int vx_audio_monitor_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el struct vx_core *chip = snd_kcontrol_chip(kcontrol); int audio = kcontrol->private_value & 0xff; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); ucontrol->value.integer.value[0] = chip->audio_monitor[audio]; ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1]; - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -629,17 +629,17 @@ static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el struct vx_core *chip = snd_kcontrol_chip(kcontrol); int audio = kcontrol->private_value & 0xff; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); if (ucontrol->value.integer.value[0] != chip->audio_monitor[audio] || ucontrol->value.integer.value[1] != chip->audio_monitor[audio+1]) { vx_set_monitor_level(chip, audio, ucontrol->value.integer.value[0], chip->audio_monitor_active[audio]); vx_set_monitor_level(chip, audio+1, ucontrol->value.integer.value[1], chip->audio_monitor_active[audio+1]); - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 1; } - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -657,10 +657,10 @@ static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va struct vx_core *chip = snd_kcontrol_chip(kcontrol); int audio = kcontrol->private_value & 0xff; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); ucontrol->value.integer.value[0] = chip->audio_active[audio]; ucontrol->value.integer.value[1] = chip->audio_active[audio+1]; - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -669,15 +669,15 @@ static int vx_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va struct vx_core *chip = snd_kcontrol_chip(kcontrol); int audio = kcontrol->private_value & 0xff; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); if (ucontrol->value.integer.value[0] != chip->audio_active[audio] || ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) { vx_set_audio_switch(chip, audio, ucontrol->value.integer.value[0]); vx_set_audio_switch(chip, audio+1, ucontrol->value.integer.value[1]); - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 1; } - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -686,10 +686,10 @@ static int vx_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ struct vx_core *chip = snd_kcontrol_chip(kcontrol); int audio = kcontrol->private_value & 0xff; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio]; ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1]; - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -698,17 +698,17 @@ static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ struct vx_core *chip = snd_kcontrol_chip(kcontrol); int audio = kcontrol->private_value & 0xff; - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] || ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) { vx_set_monitor_level(chip, audio, chip->audio_monitor[audio], ucontrol->value.integer.value[0]); vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1], ucontrol->value.integer.value[1]); - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 1; } - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -756,12 +756,12 @@ static int vx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu { struct vx_core *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff; ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff; ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff; ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff; - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } @@ -783,14 +783,14 @@ static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu (ucontrol->value.iec958.status[1] << 8) | (ucontrol->value.iec958.status[2] << 16) | (ucontrol->value.iec958.status[3] << 24); - mutex_lock(&chip->mixer_mutex); + down(&chip->mixer_mutex); if (chip->uer_bits != val) { chip->uer_bits = val; vx_set_iec958_status(chip, val); - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 1; } - mutex_unlock(&chip->mixer_mutex); + up(&chip->mixer_mutex); return 0; } diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index c4af84995..464109e42 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c @@ -98,9 +98,10 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) { struct snd_pcm_runtime *runtime = subs->runtime; - - vfree(runtime->dma_area); - runtime->dma_area = NULL; + if (runtime->dma_area) { + vfree(runtime->dma_area); + runtime->dma_area = NULL; + } return 0; } @@ -1253,13 +1254,9 @@ static int vx_init_audio_io(struct vx_core *chip) /* allocate pipes */ chip->playback_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_outs, GFP_KERNEL); - if (!chip->playback_pipes) - return -ENOMEM; chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL); - if (!chip->capture_pipes) { - kfree(chip->playback_pipes); + if (! chip->playback_pipes || ! chip->capture_pipes) return -ENOMEM; - } memset(chip->playback_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_outs); memset(chip->capture_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_ins); diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c index cb89f7eb9..9deba80a5 100644 --- a/sound/i2c/cs8427.c +++ b/sound/i2c/cs8427.c @@ -291,13 +291,11 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427) { struct cs8427 *chip; unsigned long end_time; - int data, aes3input = 0; + int data; snd_assert(cs8427, return); chip = cs8427->private_data; snd_i2c_lock(cs8427->bus); - if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) == CS8427_RXDAES3INPUT) /* AES3 bit is set */ - aes3input = 1; chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK); snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, chip->regmap[CS8427_REG_CLOCKSOURCE]); @@ -318,8 +316,7 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427) } snd_i2c_lock(cs8427->bus); chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK; - if (aes3input) - chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT; + chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT; snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, chip->regmap[CS8427_REG_CLOCKSOURCE]); snd_i2c_unlock(cs8427->bus); diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c index edfe76fb0..c4e1f2c23 100644 --- a/sound/i2c/i2c.c +++ b/sound/i2c/i2c.c @@ -88,7 +88,7 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name, bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (bus == NULL) return -ENOMEM; - mutex_init(&bus->lock_mutex); + init_MUTEX(&bus->lock_mutex); INIT_LIST_HEAD(&bus->devices); INIT_LIST_HEAD(&bus->buses); bus->card = card; diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 557c4de22..ff8fef932 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -11,15 +11,6 @@ config SND_CS4231_LIB tristate select SND_PCM -config SND_ADLIB - tristate "AdLib FM card" - select SND_OPL3_LIB - help - Say Y here to include support for AdLib FM cards. - - To compile this driver as a module, choose M here: the module - will be called snd-adlib. - config SND_AD1816A tristate "Analog Devices SoundPort AD1816A" depends on SND && PNP && ISA @@ -301,20 +292,6 @@ config SND_OPTI93X To compile this driver as a module, choose M here: the module will be called snd-opti93x. -config SND_MIRO - tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" - depends on SND - select SND_OPL4_LIB - select SND_CS4231_LIB - select SND_MPU401_UART - select SND_PCM - help - Say 'Y' or 'M' to include support for Miro miroSOUND PCM1 pro, - miroSOUND PCM12 and miroSOUND PCM20 Radio soundcards. - - To compile this driver as a module, choose M here: the module - will be called snd-miro. - config SND_SB8 tristate "Sound Blaster 1.0/2.0/Pro (8-bit)" depends on SND diff --git a/sound/isa/Makefile b/sound/isa/Makefile index bb317ccc1..05724eb7b 100644 --- a/sound/isa/Makefile +++ b/sound/isa/Makefile @@ -3,7 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -snd-adlib-objs := adlib.o snd-als100-objs := als100.o snd-azt2320-objs := azt2320.o snd-cmi8330-objs := cmi8330.o @@ -14,7 +13,6 @@ snd-sgalaxy-objs := sgalaxy.o snd-sscape-objs := sscape.o # Toplevel Module Dependency -obj-$(CONFIG_SND_ADLIB) += snd-adlib.o obj-$(CONFIG_SND_ALS100) += snd-als100.o obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 31f299aed..7051f7798 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c @@ -262,8 +262,6 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard return 0; } -static unsigned int __devinitdata ad1816a_devices; - static int __devinit snd_ad1816a_pnp_detect(struct pnp_card_link *card, const struct pnp_card_device_id *id) { @@ -277,7 +275,6 @@ static int __devinit snd_ad1816a_pnp_detect(struct pnp_card_link *card, if (res < 0) return res; dev++; - ad1816a_devices++; return 0; } return -ENODEV; @@ -300,13 +297,10 @@ static struct pnp_card_driver ad1816a_pnpc_driver = { static int __init alsa_card_ad1816a_init(void) { - int err; - - err = pnp_register_card_driver(&ad1816a_pnpc_driver); - if (err) - return err; + int cards; - if (!ad1816a_devices) { + cards = pnp_register_card_driver(&ad1816a_pnpc_driver); + if (cards <= 0) { pnp_unregister_card_driver(&ad1816a_pnpc_driver); #ifdef MODULE printk(KERN_ERR "no AD1816A based soundcards found.\n"); diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index fd8fe16c0..ac0d808ff 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c @@ -1,3 +1,4 @@ + /* ad1816a.c - lowlevel code for Analog Devices AD1816A chip. Copyright (C) 1999-2000 by Massimo Piccioni @@ -174,7 +175,7 @@ static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode) static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what, - int channel, int cmd, int iscapture) + int channel, int cmd) { int error = 0; @@ -183,14 +184,10 @@ static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what, case SNDRV_PCM_TRIGGER_STOP: spin_lock(&chip->lock); cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00; - /* if (what & AD1816A_PLAYBACK_ENABLE) */ - /* That is not valid, because playback and capture enable - * are the same bit pattern, just to different addresses - */ - if (! iscapture) + if (what & AD1816A_PLAYBACK_ENABLE) snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG, AD1816A_PLAYBACK_ENABLE, cmd); - else + if (what & AD1816A_CAPTURE_ENABLE) snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG, AD1816A_CAPTURE_ENABLE, cmd); spin_unlock(&chip->lock); @@ -207,14 +204,14 @@ static int snd_ad1816a_playback_trigger(struct snd_pcm_substream *substream, int { struct snd_ad1816a *chip = snd_pcm_substream_chip(substream); return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE, - SNDRV_PCM_STREAM_PLAYBACK, cmd, 0); + SNDRV_PCM_STREAM_PLAYBACK, cmd); } static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_ad1816a *chip = snd_pcm_substream_chip(substream); return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE, - SNDRV_PCM_STREAM_CAPTURE, cmd, 1); + SNDRV_PCM_STREAM_CAPTURE, cmd); } static int snd_ad1816a_hw_params(struct snd_pcm_substream *substream, diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 99908e441..e091bbeff 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -187,17 +187,13 @@ static int __init alsa_card_ad1848_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(SND_AD1848_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } devices[i] = device; cards++; @@ -206,10 +202,14 @@ static int __init alsa_card_ad1848_init(void) #ifdef MODULE printk(KERN_ERR "AD1848 soundcard not found or device busy\n"); #endif - snd_ad1848_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_ad1848_unregister_all(); + return err; } static void __exit alsa_card_ad1848_exit(void) diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index e0f8baa84..ed7cdb028 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -387,9 +387,9 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode) { unsigned long flags; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); if (chip->mode & AD1848_MODE_OPEN) { - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return -EAGAIN; } snd_ad1848_mce_down(chip); @@ -432,7 +432,7 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode) spin_unlock_irqrestore(&chip->reg_lock, flags); chip->mode = mode; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return 0; } @@ -441,9 +441,9 @@ static void snd_ad1848_close(struct snd_ad1848 *chip) { unsigned long flags; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); if (!chip->mode) { - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return; } /* disable IRQ */ @@ -471,7 +471,7 @@ static void snd_ad1848_close(struct snd_ad1848 *chip) spin_unlock_irqrestore(&chip->reg_lock, flags); chip->mode = 0; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); } /* @@ -889,7 +889,7 @@ int snd_ad1848_create(struct snd_card *card, if (chip == NULL) return -ENOMEM; spin_lock_init(&chip->reg_lock); - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->open_mutex); chip->card = card; chip->port = port; chip->irq = -1; diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c deleted file mode 100644 index 1124344ed..000000000 --- a/sound/isa/adlib.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * AdLib FM card driver. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define CRD_NAME "AdLib FM" -#define DRV_NAME "snd_adlib" - -MODULE_DESCRIPTION(CRD_NAME); -MODULE_AUTHOR("Rene Herman"); -MODULE_LICENSE("GPL"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; -static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); -module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); - -static struct platform_device *devices[SNDRV_CARDS]; - -static void snd_adlib_free(struct snd_card *card) -{ - release_and_free_resource(card->private_data); -} - -static int __devinit snd_adlib_probe(struct platform_device *device) -{ - struct snd_card *card; - struct snd_opl3 *opl3; - - int error, i = device->id; - - if (port[i] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR DRV_NAME ": please specify port\n"); - error = -EINVAL; - goto out0; - } - - card = snd_card_new(index[i], id[i], THIS_MODULE, 0); - if (!card) { - snd_printk(KERN_ERR DRV_NAME ": could not create card\n"); - error = -EINVAL; - goto out0; - } - - card->private_data = request_region(port[i], 4, CRD_NAME); - if (!card->private_data) { - snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n"); - error = -EBUSY; - goto out1; - } - card->private_free = snd_adlib_free; - - error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3); - if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n"); - goto out1; - } - - error = snd_opl3_hwdep_new(opl3, 0, 0, NULL); - if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not create FM\n"); - goto out1; - } - - strcpy(card->driver, DRV_NAME); - strcpy(card->shortname, CRD_NAME); - sprintf(card->longname, CRD_NAME " at %#lx", port[i]); - - snd_card_set_dev(card, &device->dev); - - error = snd_card_register(card); - if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not register card\n"); - goto out1; - } - - platform_set_drvdata(device, card); - return 0; - -out1: snd_card_free(card); -out0: return error; -} - -static int __devexit snd_adlib_remove(struct platform_device *device) -{ - snd_card_free(platform_get_drvdata(device)); - platform_set_drvdata(device, NULL); - return 0; -} - -static struct platform_driver snd_adlib_driver = { - .probe = snd_adlib_probe, - .remove = __devexit_p(snd_adlib_remove), - - .driver = { - .name = DRV_NAME - } -}; - -static int __init alsa_card_adlib_init(void) -{ - int i, cards; - - if (platform_driver_register(&snd_adlib_driver) < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not register driver\n"); - return -ENODEV; - } - - for (cards = 0, i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - - if (!enable[i]) - continue; - - device = platform_device_register_simple(DRV_NAME, i, NULL, 0); - if (IS_ERR(device)) - continue; - - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - - devices[i] = device; - cards++; - } - - if (!cards) { -#ifdef MODULE - printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n"); -#endif - platform_driver_unregister(&snd_adlib_driver); - return -ENODEV; - } - return 0; -} - -static void __exit alsa_card_adlib_exit(void) -{ - int i; - - for (i = 0; i < SNDRV_CARDS; i++) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_adlib_driver); -} - -module_init(alsa_card_adlib_init); -module_exit(alsa_card_adlib_exit); diff --git a/sound/isa/als100.c b/sound/isa/als100.c index a52bd8a14..9b77c17b3 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c @@ -199,7 +199,7 @@ static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard, return 0; } -static int __devinit snd_card_als100_probe(int dev, +static int __init snd_card_als100_probe(int dev, struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -281,8 +281,6 @@ static int __devinit snd_card_als100_probe(int dev, return 0; } -static unsigned int __devinitdata als100_devices; - static int __devinit snd_als100_pnp_detect(struct pnp_card_link *card, const struct pnp_card_device_id *id) { @@ -296,7 +294,6 @@ static int __devinit snd_als100_pnp_detect(struct pnp_card_link *card, if (res < 0) return res; dev++; - als100_devices++; return 0; } return -ENODEV; @@ -348,13 +345,10 @@ static struct pnp_card_driver als100_pnpc_driver = { static int __init alsa_card_als100_init(void) { - int err; - - err = pnp_register_card_driver(&als100_pnpc_driver); - if (err) - return err; + int cards; - if (!als100_devices) { + cards = pnp_register_card_driver(&als100_pnpc_driver); + if (cards <= 0) { pnp_unregister_card_driver(&als100_pnpc_driver); #ifdef MODULE snd_printk(KERN_ERR "no ALS100 based soundcards found\n"); diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index 15e59283a..a530691bf 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c @@ -310,8 +310,6 @@ static int __devinit snd_card_azt2320_probe(int dev, return 0; } -static unsigned int __devinitdata azt2320_devices; - static int __devinit snd_azt2320_pnp_detect(struct pnp_card_link *card, const struct pnp_card_device_id *id) { @@ -325,7 +323,6 @@ static int __devinit snd_azt2320_pnp_detect(struct pnp_card_link *card, if (res < 0) return res; dev++; - azt2320_devices++; return 0; } return -ENODEV; @@ -375,13 +372,10 @@ static struct pnp_card_driver azt2320_pnpc_driver = { static int __init alsa_card_azt2320_init(void) { - int err; - - err = pnp_register_card_driver(&azt2320_pnpc_driver); - if (err) - return err; + int cards; - if (!azt2320_devices) { + cards = pnp_register_card_driver(&azt2320_pnpc_driver); + if (cards <= 0) { pnp_unregister_card_driver(&azt2320_pnpc_driver); #ifdef MODULE snd_printk(KERN_ERR "no AZT2320 based soundcards found\n"); diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index 3c1e9fd56..fd9bb2575 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -175,7 +175,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_cmi8330_pnpids); #endif -static struct ad1848_mix_elem snd_cmi8330_controls[] __devinitdata = { +static struct ad1848_mix_elem snd_cmi8330_controls[] __initdata = { AD1848_DOUBLE("Master Playback Volume", 0, CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0), AD1848_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1), AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), @@ -204,7 +204,7 @@ AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",PLAYBACK,SWITCH), 0, CMI8330_MUTEMU }; #ifdef ENABLE_SB_MIXER -static struct sbmix_elem cmi8330_sb_mixers[] __devinitdata = { +static struct sbmix_elem cmi8330_sb_mixers[] __initdata = { SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31), SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15), SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15), @@ -222,7 +222,7 @@ SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6 SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1), }; -static unsigned char cmi8330_sb_init_values[][2] __devinitdata = { +static unsigned char cmi8330_sb_init_values[][2] __initdata = { { SB_DSP4_MASTER_DEV + 0, 0 }, { SB_DSP4_MASTER_DEV + 1, 0 }, { SB_DSP4_PCM_DEV + 0, 0 }, @@ -545,7 +545,7 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev) +static int __init snd_cmi8330_nonpnp_probe(struct platform_device *pdev) { struct snd_card *card; int err; @@ -607,8 +607,6 @@ static struct platform_driver snd_cmi8330_driver = { #ifdef CONFIG_PNP -static unsigned int __devinitdata cmi8330_pnp_devices; - static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -638,7 +636,6 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - cmi8330_pnp_devices++; return 0; } @@ -693,17 +690,15 @@ static int __init alsa_card_cmi8330_init(void) if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) + if (is_isapnp_selected(i)) continue; device = platform_device_register_simple(CMI8330_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } platform_devices[i] = device; cards++; @@ -711,9 +706,9 @@ static int __init alsa_card_cmi8330_init(void) #ifdef CONFIG_PNP err = pnp_register_card_driver(&cmi8330_pnpc_driver); - if (!err) { + if (err >= 0) { pnp_registered = 1; - cards += cmi8330_pnp_devices; + cards += err; } #endif @@ -721,10 +716,14 @@ static int __init alsa_card_cmi8330_init(void) #ifdef MODULE snd_printk(KERN_ERR "CMI8330 not found or device busy\n"); #endif - snd_cmi8330_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_cmi8330_unregister_all(); + return err; } static void __exit alsa_card_cmi8330_exit(void) diff --git a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile index 2fb4f7409..d2afaea30 100644 --- a/sound/isa/cs423x/Makefile +++ b/sound/isa/cs423x/Makefile @@ -11,7 +11,6 @@ snd-cs4236-objs := cs4236.o # Toplevel Module Dependency obj-$(CONFIG_SND_AZT2320) += snd-cs4231-lib.o -obj-$(CONFIG_SND_MIRO) += snd-cs4231-lib.o obj-$(CONFIG_SND_OPL3SA2) += snd-cs4231-lib.o obj-$(CONFIG_SND_CS4231) += snd-cs4231.o snd-cs4231-lib.o obj-$(CONFIG_SND_CS4232) += snd-cs4232.o snd-cs4231-lib.o diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index 397310f35..ab67b5c25 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c @@ -203,17 +203,13 @@ static int __init alsa_card_cs4231_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(SND_CS4231_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } devices[i] = device; cards++; @@ -222,10 +218,14 @@ static int __init alsa_card_cs4231_init(void) #ifdef MODULE printk(KERN_ERR "CS4231 soundcard not found or device busy\n"); #endif - snd_cs4231_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_cs4231_unregister_all(); + return err; } static void __exit alsa_card_cs4231_exit(void) diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c index 823db8246..eab7eb59b 100644 --- a/sound/isa/cs423x/cs4231_lib.c +++ b/sound/isa/cs423x/cs4231_lib.c @@ -531,7 +531,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, unsigned long flags; int full_calib = 1; - mutex_lock(&chip->mce_mutex); + down(&chip->mce_mutex); snd_cs4231_calibrate_mute(chip, 1); if (chip->hardware == CS4231_HW_CS4231A || (chip->hardware & CS4231_HW_CS4232_MASK)) { @@ -560,7 +560,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, snd_cs4231_mce_down(chip); } snd_cs4231_calibrate_mute(chip, 0); - mutex_unlock(&chip->mce_mutex); + up(&chip->mce_mutex); } static void snd_cs4231_capture_format(struct snd_cs4231 *chip, @@ -570,7 +570,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, unsigned long flags; int full_calib = 1; - mutex_lock(&chip->mce_mutex); + down(&chip->mce_mutex); snd_cs4231_calibrate_mute(chip, 1); if (chip->hardware == CS4231_HW_CS4231A || (chip->hardware & CS4231_HW_CS4232_MASK)) { @@ -603,7 +603,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, snd_cs4231_mce_down(chip); } snd_cs4231_calibrate_mute(chip, 0); - mutex_unlock(&chip->mce_mutex); + up(&chip->mce_mutex); } /* @@ -709,15 +709,15 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) { unsigned long flags; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); if ((chip->mode & mode) || ((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) { - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return -EAGAIN; } if (chip->mode & CS4231_MODE_OPEN) { chip->mode |= mode; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return 0; } /* ok. now enable and ack CODEC IRQ */ @@ -737,7 +737,7 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) spin_unlock_irqrestore(&chip->reg_lock, flags); chip->mode = mode; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return 0; } @@ -745,10 +745,10 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) { unsigned long flags; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); chip->mode &= ~mode; if (chip->mode & CS4231_MODE_OPEN) { - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return; } snd_cs4231_calibrate_mute(chip, 1); @@ -785,7 +785,7 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) snd_cs4231_calibrate_mute(chip, 0); chip->mode = 0; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); } /* @@ -1408,8 +1408,8 @@ static int snd_cs4231_new(struct snd_card *card, chip->hwshare = hwshare; spin_lock_init(&chip->reg_lock); - mutex_init(&chip->mce_mutex); - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->mce_mutex); + init_MUTEX(&chip->open_mutex); chip->card = card; chip->rate_constraint = snd_cs4231_xrate; chip->set_playback_format = snd_cs4231_playback_format; @@ -1538,8 +1538,8 @@ int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm) return err; spin_lock_init(&chip->reg_lock); - mutex_init(&chip->mce_mutex); - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->mce_mutex); + init_MUTEX(&chip->open_mutex); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops); diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index f7fa77934..99a42138b 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -133,7 +133,6 @@ static int pnpc_registered; static int pnp_registered; #endif #endif /* CONFIG_PNP */ -static unsigned int snd_cs423x_devices; struct snd_card_cs4236 { struct snd_cs4231 *chip; @@ -565,7 +564,7 @@ static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev) snd_card_free(card); return err; } - + platform_set_drvdata(pdev, card); return 0; } @@ -651,7 +650,6 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, } pnp_set_drvdata(pdev, card); dev++; - snd_cs423x_devices++; return 0; } @@ -715,7 +713,6 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - snd_cs423x_devices++; return 0; } @@ -724,7 +721,7 @@ static void __devexit snd_cs423x_pnpc_remove(struct pnp_card_link * pcard) snd_card_free(pnp_get_card_drvdata(pcard)); pnp_set_card_drvdata(pcard, NULL); } - + #ifdef CONFIG_PM static int snd_cs423x_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state) { @@ -769,45 +766,51 @@ static void __init_or_module snd_cs423x_unregister_all(void) static int __init alsa_card_cs423x_init(void) { - int i, err; + int i, err, cards = 0; if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) + if (is_isapnp_selected(i)) continue; device = platform_device_register_simple(CS423X_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } platform_devices[i] = device; - snd_cs423x_devices++; + cards++; } #ifdef CONFIG_PNP #ifdef CS4232 - err = pnp_register_driver(&cs4232_pnp_driver); - if (!err) + i = pnp_register_driver(&cs4232_pnp_driver); + if (i >= 0) { pnp_registered = 1; + cards += i; + } #endif - err = pnp_register_card_driver(&cs423x_pnpc_driver); - if (!err) + i = pnp_register_card_driver(&cs423x_pnpc_driver); + if (i >= 0) { pnpc_registered = 1; + cards += i; + } #endif /* CONFIG_PNP */ - if (!snd_cs423x_devices) { + if (!cards) { #ifdef MODULE printk(KERN_ERR IDENT " soundcard not found or device busy\n"); #endif - snd_cs423x_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_cs423x_unregister_all(); + return err; } static void __exit alsa_card_cs423x_exit(void) diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c index 7a5a6c71f..e36981d64 100644 --- a/sound/isa/cs423x/cs4236_lib.c +++ b/sound/isa/cs423x/cs4236_lib.c @@ -644,7 +644,7 @@ static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct s val2 = (chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & ~0x7f) | val2; change = val1 != chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] || val2 != chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)]; snd_cs4236_ext_out(chip, CS4236_LEFT_MASTER, val1); - snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val2); + snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val1); spin_unlock_irqrestore(&chip->reg_lock, flags); return change; } @@ -841,7 +841,7 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn enable = ucontrol->value.integer.value[0] & 1; - mutex_lock(&chip->mce_mutex); + down(&chip->mce_mutex); snd_cs4231_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1); @@ -854,7 +854,7 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn snd_cs4236_ctrl_out(chip, 4, val); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_cs4231_mce_down(chip); - mutex_unlock(&chip->mce_mutex); + up(&chip->mce_mutex); #if 0 printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c index 0acb4e5da..50e7bc5ef 100644 --- a/sound/isa/dt019x.c +++ b/sound/isa/dt019x.c @@ -272,8 +272,6 @@ static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, return 0; } -static unsigned int __devinitdata dt019x_devices; - static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device_id *pid) { @@ -287,7 +285,6 @@ static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card, if (res < 0) return res; dev++; - dt019x_devices++; return 0; } return -ENODEV; @@ -339,13 +336,10 @@ static struct pnp_card_driver dt019x_pnpc_driver = { static int __init alsa_card_dt019x_init(void) { - int err; - - err = pnp_register_card_driver(&dt019x_pnpc_driver); - if (err) - return err; + int cards = 0; - if (!dt019x_devices) { + cards = pnp_register_card_driver(&dt019x_pnpc_driver); + if (cards <= 0) { pnp_unregister_card_driver(&dt019x_pnpc_driver); #ifdef MODULE snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n"); diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index e90689ee1..50d23cf3d 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -207,17 +207,13 @@ static int __init alsa_card_es1688_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(ES1688_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } devices[i] = device; cards++; @@ -226,10 +222,14 @@ static int __init alsa_card_es1688_init(void) #ifdef MODULE printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n"); #endif - snd_es1688_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_es1688_unregister_all(); + return err; } static void __exit alsa_card_es1688_exit(void) diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index e6945db8e..7a12848a7 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -49,10 +49,6 @@ * - contrarily to some pages in DS_1869.PDF the rates can be set * independently. * - * - Zoom Video is implemented by sharing the FM DAC, thus the user can - * have either FM playback or Video playback but not both simultaneously. - * The Video Playback Switch mixer control toggles this choice. - * * BUGS: * * - There is a major trouble I noted: @@ -67,16 +63,7 @@ * */ -/* - * ES1879 NOTES: - * - When Zoom Video is enabled (reg 0x71 bit 6 toggled on) the PCM playback - * seems to be effected (speaker_test plays a lower frequency). Can't find - * anything in the datasheet to account for this, so a Video Playback Switch - * control has been included to allow ZV to be enabled only when necessary. - * Then again on at least one test system the 0x71 bit 6 enable bit is not - * needed for ZV, so maybe the datasheet is entirely wrong here. - */ - + #include #include #include @@ -85,8 +72,6 @@ #include #include #include -#include - #include #include #include @@ -163,7 +148,7 @@ struct snd_audiodrive { #define ES18XX_DUPLEX_SAME 0x0010 /* Playback and record must share the same rate */ #define ES18XX_NEW_RATE 0x0020 /* More precise rate setting */ #define ES18XX_AUXB 0x0040 /* AuxB mixer control */ -#define ES18XX_HWV 0x0080 /* Has seperate hardware volume mixer controls*/ +#define ES18XX_HWV 0x0080 /* Has hardware volume */ #define ES18XX_MONO 0x0100 /* Mono_in mixer control */ #define ES18XX_I2S 0x0200 /* I2S mixer control */ #define ES18XX_MUTEREC 0x0400 /* Record source can be muted */ @@ -803,12 +788,9 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id, struct pt_regs *r /* Hardware volume */ if (status & HWV_IRQ) { - int split = 0; - if (chip->caps & ES18XX_HWV) { - split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id); - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id); - } + int split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; + snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id); + snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id); if (!split) { snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id); snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id); @@ -957,118 +939,37 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream) * MIXER part */ -/* Record source mux routines: - * Depending on the chipset this mux switches between 4, 5, or 8 possible inputs. - * bit table for the 4/5 source mux: - * reg 1C: - * b2 b1 b0 muxSource - * x 0 x microphone - * 0 1 x CD - * 1 1 0 line - * 1 1 1 mixer - * if it's "mixer" and it's a 5 source mux chipset then reg 7A bit 3 determines - * either the play mixer or the capture mixer. - * - * "map4Source" translates from source number to reg bit pattern - * "invMap4Source" translates from reg bit pattern to source number - */ - static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts4Source[4] = { - "Mic", "CD", "Line", "Master" - }; - static char *texts5Source[5] = { - "Mic", "CD", "Line", "Master", "Mix" - }; - static char *texts8Source[8] = { + static char *texts[8] = { "Mic", "Mic Master", "CD", "AOUT", "Mic1", "Mix", "Line", "Master" }; - struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; - switch (chip->version) { - case 0x1868: - case 0x1878: - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]); - break; - case 0x1887: - case 0x1888: - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item > 4) - uinfo->value.enumerated.item = 4; - strcpy(uinfo->value.enumerated.name, texts5Source[uinfo->value.enumerated.item]); - break; - case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */ - case 0x1879: - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item > 7) - uinfo->value.enumerated.item = 7; - strcpy(uinfo->value.enumerated.name, texts8Source[uinfo->value.enumerated.item]); - break; - default: - return -EINVAL; - } + uinfo->value.enumerated.items = 8; + if (uinfo->value.enumerated.item > 7) + uinfo->value.enumerated.item = 7; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0; } static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - static unsigned char invMap4Source[8] = {0, 0, 1, 1, 0, 0, 2, 3}; struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); - int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07; - if (!(chip->version == 0x1869 || chip->version == 0x1879)) { - muxSource = invMap4Source[muxSource]; - if (muxSource==3 && - (chip->version == 0x1887 || chip->version == 0x1888) && - (snd_es18xx_mixer_read(chip, 0x7a) & 0x08) - ) - muxSource = 4; - } - ucontrol->value.enumerated.item[0] = muxSource; + ucontrol->value.enumerated.item[0] = snd_es18xx_mixer_read(chip, 0x1c) & 0x07; return 0; } static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - static unsigned char map4Source[4] = {0, 2, 6, 7}; struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); unsigned char val = ucontrol->value.enumerated.item[0]; - unsigned char retVal = 0; - - switch (chip->version) { - /* 5 source chips */ - case 0x1887: - case 0x1888: - if (val > 4) - return -EINVAL; - if (val == 4) { - retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08; - val = 3; - } else - retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00; - /* 4 source chips */ - case 0x1868: - case 0x1878: - if (val > 3) - return -EINVAL; - val = map4Source[val]; - break; - /* 8 source chips */ - case 0x1869: - case 0x1879: - if (val > 7) - return -EINVAL; - break; - default: + + if (val > 7) return -EINVAL; - } - return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal; + return snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val; } static int snd_es18xx_info_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -1290,22 +1191,19 @@ static int snd_es18xx_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } -/* Mixer controls - * These arrays contain setup data for mixer controls. - * - * The controls that are universal to all chipsets are fully initialized - * here. - */ static struct snd_kcontrol_new snd_es18xx_base_controls[] = { ES18XX_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0), ES18XX_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1), ES18XX_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0), ES18XX_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0), ES18XX_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0), +ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), ES18XX_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0), ES18XX_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0), +ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0), ES18XX_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0), ES18XX_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0), +ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", @@ -1315,37 +1213,19 @@ ES18XX_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0), } }; +static struct snd_kcontrol_new snd_es18xx_mono_in_control = +ES18XX_DOUBLE("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0); + static struct snd_kcontrol_new snd_es18xx_recmix_controls[] = { ES18XX_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0), ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0), ES18XX_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0), ES18XX_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0), +ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0), ES18XX_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0), ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0) }; -/* - * The chipset specific mixer controls - */ -static struct snd_kcontrol_new snd_es18xx_opt_speaker = - ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0); - -static struct snd_kcontrol_new snd_es18xx_opt_1869[] = { -ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), -ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0), -ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), -ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0) -}; - -static struct snd_kcontrol_new snd_es18xx_opt_1878 = - ES18XX_DOUBLE("Video Playback Volume", 0, 0x68, 0x68, 4, 0, 15, 0); - -static struct snd_kcontrol_new snd_es18xx_opt_1879[] = { -ES18XX_SINGLE("Video Playback Switch", 0, 0x71, 6, 1, 0), -ES18XX_DOUBLE("Video Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), -ES18XX_DOUBLE("Video Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0) -}; - static struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = { ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0), }; @@ -1390,6 +1270,7 @@ static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = { ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0), }; +#if 0 static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) { int data; @@ -1400,6 +1281,7 @@ static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned ch spin_unlock_irqrestore(&chip->ctrl_lock, flags); return data; } +#endif static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip, unsigned char reg, unsigned char data) @@ -1545,17 +1427,6 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip) snd_es18xx_mixer_write(chip, 0x58, 0x94); snd_es18xx_mixer_write(chip, 0x5a, 0x80); } - /* Flip the "enable I2S" bits for those chipsets that need it */ - switch (chip->version) { - case 0x1879: - //Leaving I2S enabled on the 1879 screws up the PCM playback (rate effected somehow) - //so a Switch control has been added to toggle this 0x71 bit on/off: - //snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40); - /* Note: we fall through on purpose here. */ - case 0x1878: - snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40); - break; - } /* Mute input source */ if (chip->caps & ES18XX_MUTEREC) mask = 0x10; @@ -1605,14 +1476,11 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip) } outb(0x40, chip->port + 0x04); - udelay(10); hi = inb(chip->port + 0x05); - udelay(10); lo = inb(chip->port + 0x05); if (hi != lo) { chip->version = hi << 8 | lo; chip->ctrl_port = inb(chip->port + 0x05) << 8; - udelay(10); chip->ctrl_port += inb(chip->port + 0x05); if ((chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL")) == NULL) { @@ -1651,22 +1519,22 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip) switch (chip->version) { case 0x1868: - chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL; + chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_HWV; break; case 0x1869: chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV; break; case 0x1878: - chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; + chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; break; case 0x1879: chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; break; case 0x1887: - chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; + chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV; break; case 0x1888: - chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; + chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV; break; default: snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n", @@ -1910,6 +1778,10 @@ static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip) } } + if (chip->caps & ES18XX_MONO) { + if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_mono_in_control, chip))) < 0) + return err; + } if (chip->caps & ES18XX_RECMIX) { for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) { if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0) @@ -1947,36 +1819,6 @@ static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip) } } - /* finish initializing other chipset specific controls - */ - if (chip->version != 0x1868) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_speaker, - chip)); - if (err < 0) - return err; - } - if (chip->version == 0x1869) { - for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1869); idx++) { - err = snd_ctl_add(card, - snd_ctl_new1(&snd_es18xx_opt_1869[idx], - chip)); - if (err < 0) - return err; - } - } else if (chip->version == 0x1878) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_1878, - chip)); - if (err < 0) - return err; - } else if (chip->version == 0x1879) { - for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1879); idx++) { - err = snd_ctl_add(card, - snd_ctl_new1(&snd_es18xx_opt_1879[idx], - chip)); - if (err < 0) - return err; - } - } return 0; } @@ -2206,7 +2048,7 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __init snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr) { struct snd_card *card; int err; @@ -2223,7 +2065,7 @@ static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *d return 0; } -static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) +static int __init snd_es18xx_nonpnp_probe(struct platform_device *pdev) { int dev = pdev->id; int err; @@ -2299,8 +2141,6 @@ static struct platform_driver snd_es18xx_nonpnp_driver = { #ifdef CONFIG_PNP -static unsigned int __devinitdata es18xx_pnp_devices; - static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -2331,7 +2171,6 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard, pnp_set_card_drvdata(pcard, card); dev++; - es18xx_pnp_devices++; return 0; } @@ -2387,27 +2226,25 @@ static int __init alsa_card_es18xx_init(void) if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) + if (is_isapnp_selected(i)) continue; device = platform_device_register_simple(ES18XX_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } platform_devices[i] = device; cards++; } #ifdef CONFIG_PNP - err = pnp_register_card_driver(&es18xx_pnpc_driver); - if (!err) { + i = pnp_register_card_driver(&es18xx_pnpc_driver); + if (i >= 0) { pnp_registered = 1; - cards += es18xx_pnp_devices; + cards += i; } #endif @@ -2415,10 +2252,14 @@ static int __init alsa_card_es18xx_init(void) #ifdef MODULE snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n"); #endif - snd_es18xx_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_es18xx_unregister_all(); + return err; } static void __exit alsa_card_es18xx_exit(void) diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c index 44ee5d367..930f4bc56 100644 --- a/sound/isa/gus/gus_dma.c +++ b/sound/isa/gus/gus_dma.c @@ -149,10 +149,10 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus) int snd_gf1_dma_init(struct snd_gus_card * gus) { - mutex_lock(&gus->dma_mutex); + down(&gus->dma_mutex); gus->gf1.dma_shared++; if (gus->gf1.dma_shared > 1) { - mutex_unlock(&gus->dma_mutex); + up(&gus->dma_mutex); return 0; } gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt; @@ -160,7 +160,7 @@ int snd_gf1_dma_init(struct snd_gus_card * gus) gus->gf1.dma_data_pcm_last = gus->gf1.dma_data_synth = gus->gf1.dma_data_synth_last = NULL; - mutex_unlock(&gus->dma_mutex); + up(&gus->dma_mutex); return 0; } @@ -168,7 +168,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus) { struct snd_gf1_dma_block *block; - mutex_lock(&gus->dma_mutex); + down(&gus->dma_mutex); gus->gf1.dma_shared--; if (!gus->gf1.dma_shared) { snd_dma_disable(gus->gf1.dma1); @@ -185,7 +185,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus) gus->gf1.dma_data_pcm_last = gus->gf1.dma_data_synth_last = NULL; } - mutex_unlock(&gus->dma_mutex); + up(&gus->dma_mutex); return 0; } diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index 53eeaf370..6d15b3d18 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c @@ -225,7 +225,7 @@ int snd_gus_create(struct snd_card *card, spin_lock_init(&gus->dma_lock); spin_lock_init(&gus->pcm_volume_level_lock); spin_lock_init(&gus->uart_cmd_lock); - mutex_init(&gus->dma_mutex); + init_MUTEX(&gus->dma_mutex); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) { snd_gus_free(gus); return err; diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c index 3c0d27aa0..e8bdb860a 100644 --- a/sound/isa/gus/gus_mem.c +++ b/sound/isa/gus/gus_mem.c @@ -34,9 +34,9 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry, void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup) { if (!xup) { - mutex_lock(&alloc->memory_mutex); + down(&alloc->memory_mutex); } else { - mutex_unlock(&alloc->memory_mutex); + up(&alloc->memory_mutex); } } @@ -59,7 +59,7 @@ static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc, alloc->first = nblock; else nblock->prev->next = nblock; - mutex_unlock(&alloc->memory_mutex); + up(&alloc->memory_mutex); return NULL; } pblock = pblock->next; @@ -80,7 +80,7 @@ int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * blo { if (block->share) { /* ok.. shared block */ block->share--; - mutex_unlock(&alloc->memory_mutex); + up(&alloc->memory_mutex); return 0; } if (alloc->first == block) { @@ -244,7 +244,7 @@ int snd_gf1_mem_init(struct snd_gus_card * gus) #endif alloc = &gus->gf1.mem_alloc; - mutex_init(&alloc->memory_mutex); + init_MUTEX(&alloc->memory_mutex); alloc->first = alloc->last = NULL; if (!gus->gf1.memory) return 0; @@ -299,7 +299,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry, gus = entry->private_data; alloc = &gus->gf1.mem_alloc; - mutex_lock(&alloc->memory_mutex); + down(&alloc->memory_mutex); snd_iprintf(buffer, "8-bit banks : \n "); for (i = 0; i < 4; i++) snd_iprintf(buffer, "0x%06x (%04ik)%s", alloc->banks_8[i].address, alloc->banks_8[i].size >> 10, i + 1 < 4 ? "," : ""); @@ -343,7 +343,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry, } snd_iprintf(buffer, " Total: memory = %i, used = %i, free = %i\n", total, used, total - used); - mutex_unlock(&alloc->memory_mutex); + up(&alloc->memory_mutex); #if 0 ultra_iprintf(buffer, " Verify: free = %i, max 8-bit block = %i, max 16-bit block = %i\n", ultra_memory_free_size(card, &card->gf1.mem_alloc), diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index c7f95e7aa..d0829393e 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c @@ -114,6 +114,8 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream) unsigned char pan; unsigned int voice; + if (substream == NULL) + return; spin_lock_irqsave(&pcmp->lock, flags); if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) { spin_unlock_irqrestore(&pcmp->lock, flags); diff --git a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c index 2767cc187..85a1b051f 100644 --- a/sound/isa/gus/gus_synth.c +++ b/sound/isa/gus/gus_synth.c @@ -55,9 +55,9 @@ static int snd_gus_synth_use(void *private_data, struct snd_seq_port_subscribe * if (info->voices > 32) return -EINVAL; - mutex_lock(&gus->register_mutex); + down(&gus->register_mutex); if (!snd_gus_use_inc(gus)) { - mutex_unlock(&gus->register_mutex); + up(&gus->register_mutex); return -EFAULT; } for (idx = 0; idx < info->voices; idx++) { @@ -65,12 +65,12 @@ static int snd_gus_synth_use(void *private_data, struct snd_seq_port_subscribe * if (voice == NULL) { snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port); snd_gus_use_dec(gus); - mutex_unlock(&gus->register_mutex); + up(&gus->register_mutex); return -EBUSY; } voice->index = idx; } - mutex_unlock(&gus->register_mutex); + up(&gus->register_mutex); return 0; } @@ -79,10 +79,10 @@ static int snd_gus_synth_unuse(void *private_data, struct snd_seq_port_subscribe struct snd_gus_port * port = private_data; struct snd_gus_card * gus = port->gus; - mutex_lock(&gus->register_mutex); + down(&gus->register_mutex); snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port); snd_gus_use_dec(gus); - mutex_unlock(&gus->register_mutex); + up(&gus->register_mutex); return 0; } @@ -223,7 +223,7 @@ static int snd_gus_synth_new_device(struct snd_seq_device *dev) if (gus == NULL) return -EINVAL; - mutex_init(&gus->register_mutex); + init_MUTEX(&gus->register_mutex); gus->gf1.seq_client = -1; /* allocate new client */ diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 37057a37d..91c219116 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c @@ -247,17 +247,13 @@ static int __init alsa_card_gusclassic_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(GUSCLASSIC_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } devices[i] = device; cards++; @@ -266,10 +262,14 @@ static int __init alsa_card_gusclassic_init(void) #ifdef MODULE printk(KERN_ERR "GUS Classic soundcard not found or device busy\n"); #endif - snd_gusclassic_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_gusclassic_unregister_all(); + return err; } static void __exit alsa_card_gusclassic_exit(void) diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 05852fcc6..239f16e6b 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -357,17 +357,13 @@ static int __init alsa_card_gusextreme_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(GUSEXTREME_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } devices[i] = device; cards++; @@ -376,10 +372,14 @@ static int __init alsa_card_gusextreme_init(void) #ifdef MODULE printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n"); #endif - snd_gusextreme_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_gusextreme_unregister_all(); + return err; } static void __exit alsa_card_gusextreme_exit(void) diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index fcf2c8fe6..d4d2b2a51 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -384,17 +384,13 @@ static int __init alsa_card_gusmax_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(GUSMAX_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } devices[i] = device; cards++; @@ -403,10 +399,14 @@ static int __init alsa_card_gusmax_init(void) #ifdef MODULE printk(KERN_ERR "GUS MAX soundcard not found or device busy\n"); #endif - snd_gusmax_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_gusmax_unregister_all(); + return err; } static void __exit alsa_card_gusmax_exit(void) diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 4298d339e..9838d992b 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -791,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) return 0; } -static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __init snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr) { struct snd_card *card; int err; @@ -809,7 +809,7 @@ static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device return 0; } -static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) +static int __init snd_interwave_nonpnp_probe(struct platform_device *pdev) { int dev = pdev->id; int err; @@ -867,7 +867,6 @@ static struct platform_driver snd_interwave_driver = { }; #ifdef CONFIG_PNP -static unsigned int __devinitdata interwave_pnp_devices; static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) @@ -898,7 +897,6 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - interwave_pnp_devices++; return 0; } @@ -937,41 +935,41 @@ static int __init alsa_card_interwave_init(void) if ((err = platform_driver_register(&snd_interwave_driver)) < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; #ifdef CONFIG_PNP if (isapnp[i]) continue; #endif device = platform_device_register_simple(INTERWAVE_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } platform_devices[i] = device; cards++; } /* ISA PnP cards */ - err = pnp_register_card_driver(&interwave_pnpc_driver); - if (!err) { + i = pnp_register_card_driver(&interwave_pnpc_driver); + if (i >= 0) { pnp_registered = 1; - cards += interwave_pnp_devices;; + cards += i; } if (!cards) { #ifdef MODULE printk(KERN_ERR "InterWave soundcard not found or device busy\n"); #endif - snd_interwave_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_interwave_unregister_all(); + return err; } static void __exit alsa_card_interwave_exit(void) diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 6d889052c..9d8431978 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -95,7 +95,6 @@ static struct platform_device *platform_devices[SNDRV_CARDS]; static int pnp_registered; static int pnpc_registered; #endif -static unsigned int snd_opl3sa2_devices; /* control ports */ #define OPL3SA2_PM_CTRL 0x01 @@ -761,7 +760,6 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, } pnp_set_drvdata(pdev, card); dev++; - snd_opl3sa2_devices++; return 0; } @@ -828,7 +826,6 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - snd_opl3sa2_devices++; return 0; } @@ -947,48 +944,52 @@ static void __init_or_module snd_opl3sa2_unregister_all(void) static int __init alsa_card_opl3sa2_init(void) { - int i, err; + int i, err, cards = 0; if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; #ifdef CONFIG_PNP if (isapnp[i]) continue; #endif device = platform_device_register_simple(OPL3SA2_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } platform_devices[i] = device; - snd_opl3sa2_devices++; + cards++; } #ifdef CONFIG_PNP err = pnp_register_driver(&opl3sa2_pnp_driver); - if (!err) + if (err >= 0) { pnp_registered = 1; + cards += err; + } err = pnp_register_card_driver(&opl3sa2_pnpc_driver); - if (!err) + if (err >= 0) { pnpc_registered = 1; + cards += err; + } #endif - if (!snd_opl3sa2_devices) { + if (!cards) { #ifdef MODULE snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); #endif - snd_opl3sa2_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_opl3sa2_unregister_all(); + return err; } static void __exit alsa_card_opl3sa2_exit(void) diff --git a/sound/isa/opti9xx/Makefile b/sound/isa/opti9xx/Makefile index 0e41bfd5a..28c64070c 100644 --- a/sound/isa/opti9xx/Makefile +++ b/sound/isa/opti9xx/Makefile @@ -6,10 +6,8 @@ snd-opti92x-ad1848-objs := opti92x-ad1848.o snd-opti92x-cs4231-objs := opti92x-cs4231.o snd-opti93x-objs := opti93x.o -snd-miro-objs := miro.o # Toplevel Module Dependency obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opti92x-ad1848.o obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opti92x-cs4231.o obj-$(CONFIG_SND_OPTI93X) += snd-opti93x.o -obj-$(CONFIG_SND_MIRO) += snd-miro.o diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c deleted file mode 100644 index e6bfcf74c..000000000 --- a/sound/isa/opti9xx/miro.c +++ /dev/null @@ -1,1455 +0,0 @@ -/* - * ALSA soundcard driver for Miro miroSOUND PCM1 pro - * miroSOUND PCM12 - * miroSOUND PCM20 Radio - * - * Copyright (C) 2004-2005 Martin Langer - * - * Based on OSS ACI and ALSA OPTi9xx drivers - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define SNDRV_LEGACY_FIND_FREE_IRQ -#define SNDRV_LEGACY_FIND_FREE_DMA -#include -#include "miro.h" - -MODULE_AUTHOR("Martin Langer "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Miro miroSOUND PCM1 pro, PCM12, PCM20 Radio"); -MODULE_SUPPORTED_DEVICE("{{Miro,miroSOUND PCM1 pro}, " - "{Miro,miroSOUND PCM12}, " - "{Miro,miroSOUND PCM20 Radio}}"); - -static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ -static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ -static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */ -static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */ -static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */ -static int irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10,11 */ -static int mpu_irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10 */ -static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */ -static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */ -static int wss; -static int ide; - -module_param(index, int, 0444); -MODULE_PARM_DESC(index, "Index value for miro soundcard."); -module_param(id, charp, 0444); -MODULE_PARM_DESC(id, "ID string for miro soundcard."); -module_param(port, long, 0444); -MODULE_PARM_DESC(port, "WSS port # for miro driver."); -module_param(mpu_port, long, 0444); -MODULE_PARM_DESC(mpu_port, "MPU-401 port # for miro driver."); -module_param(fm_port, long, 0444); -MODULE_PARM_DESC(fm_port, "FM Port # for miro driver."); -module_param(irq, int, 0444); -MODULE_PARM_DESC(irq, "WSS irq # for miro driver."); -module_param(mpu_irq, int, 0444); -MODULE_PARM_DESC(mpu_irq, "MPU-401 irq # for miro driver."); -module_param(dma1, int, 0444); -MODULE_PARM_DESC(dma1, "1st dma # for miro driver."); -module_param(dma2, int, 0444); -MODULE_PARM_DESC(dma2, "2nd dma # for miro driver."); -module_param(wss, int, 0444); -MODULE_PARM_DESC(wss, "wss mode"); -module_param(ide, int, 0444); -MODULE_PARM_DESC(ide, "enable ide port"); - -#define OPTi9XX_HW_DETECT 0 -#define OPTi9XX_HW_82C928 1 -#define OPTi9XX_HW_82C929 2 -#define OPTi9XX_HW_82C924 3 -#define OPTi9XX_HW_82C925 4 -#define OPTi9XX_HW_82C930 5 -#define OPTi9XX_HW_82C931 6 -#define OPTi9XX_HW_82C933 7 -#define OPTi9XX_HW_LAST OPTi9XX_HW_82C933 - -#define OPTi9XX_MC_REG(n) n - - -struct snd_miro { - unsigned short hardware; - unsigned char password; - char name[7]; - - struct resource *res_mc_base; - struct resource *res_aci_port; - - unsigned long mc_base; - unsigned long mc_base_size; - unsigned long pwd_reg; - - spinlock_t lock; - struct snd_card *card; - struct snd_pcm *pcm; - - long wss_base; - int irq; - int dma1; - int dma2; - - long fm_port; - - long mpu_port; - int mpu_irq; - - unsigned long aci_port; - int aci_vendor; - int aci_product; - int aci_version; - int aci_amp; - int aci_preamp; - int aci_solomode; - - struct mutex aci_mutex; -}; - -static void snd_miro_proc_init(struct snd_miro * miro); - -#define DRIVER_NAME "snd-miro" - -static struct platform_device *device; - -static char * snd_opti9xx_names[] = { - "unkown", - "82C928", "82C929", - "82C924", "82C925", - "82C930", "82C931", "82C933" -}; - -/* - * ACI control - */ - -static int aci_busy_wait(struct snd_miro * miro) -{ - long timeout; - unsigned char byte; - - for (timeout = 1; timeout <= ACI_MINTIME+30; timeout++) { - if (((byte=inb(miro->aci_port + ACI_REG_BUSY)) & 1) == 0) { - if (timeout >= ACI_MINTIME) - snd_printd("aci ready in round %ld.\n", - timeout-ACI_MINTIME); - return byte; - } - if (timeout >= ACI_MINTIME) { - long out=10*HZ; - switch (timeout-ACI_MINTIME) { - case 0 ... 9: - out /= 10; - case 10 ... 19: - out /= 10; - case 20 ... 30: - out /= 10; - default: - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(out); - break; - } - } - } - snd_printk(KERN_ERR "aci_busy_wait() time out\n"); - return -EBUSY; -} - -static inline int aci_write(struct snd_miro * miro, unsigned char byte) -{ - if (aci_busy_wait(miro) >= 0) { - outb(byte, miro->aci_port + ACI_REG_COMMAND); - return 0; - } else { - snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte); - return -EBUSY; - } -} - -static inline int aci_read(struct snd_miro * miro) -{ - unsigned char byte; - - if (aci_busy_wait(miro) >= 0) { - byte=inb(miro->aci_port + ACI_REG_STATUS); - return byte; - } else { - snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n"); - return -EBUSY; - } -} - -static int aci_cmd(struct snd_miro * miro, int write1, int write2, int write3) -{ - int write[] = {write1, write2, write3}; - int value, i; - - if (mutex_lock_interruptible(&miro->aci_mutex)) - return -EINTR; - - for (i=0; i<3; i++) { - if (write[i]< 0 || write[i] > 255) - break; - else { - value = aci_write(miro, write[i]); - if (value < 0) - goto out; - } - } - - value = aci_read(miro); - -out: mutex_unlock(&miro->aci_mutex); - return value; -} - -static int aci_getvalue(struct snd_miro * miro, unsigned char index) -{ - return aci_cmd(miro, ACI_STATUS, index, -1); -} - -static int aci_setvalue(struct snd_miro * miro, unsigned char index, int value) -{ - return aci_cmd(miro, index, value, -1); -} - -/* - * MIXER part - */ - -static int snd_miro_info_capture(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - - return 0; -} - -static int snd_miro_get_capture(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_miro *miro = snd_kcontrol_chip(kcontrol); - int value; - - if ((value = aci_getvalue(miro, ACI_S_GENERAL)) < 0) { - snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n", value); - return value; - } - - ucontrol->value.integer.value[0] = value & 0x20; - - return 0; -} - -static int snd_miro_put_capture(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_miro *miro = snd_kcontrol_chip(kcontrol); - int change, value, error; - - value = !(ucontrol->value.integer.value[0]); - - if ((error = aci_setvalue(miro, ACI_SET_SOLOMODE, value)) < 0) { - snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n", error); - return error; - } - - change = (value != miro->aci_solomode); - miro->aci_solomode = value; - - return change; -} - -static int snd_miro_info_preamp(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 3; - - return 0; -} - -static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_miro *miro = snd_kcontrol_chip(kcontrol); - int value; - - if (miro->aci_version <= 176) { - - /* - OSS says it's not readable with versions < 176. - But it doesn't work on my card, - which is a PCM12 with aci_version = 176. - */ - - ucontrol->value.integer.value[0] = miro->aci_preamp; - return 0; - } - - if ((value = aci_getvalue(miro, ACI_GET_PREAMP)) < 0) { - snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n", value); - return value; - } - - ucontrol->value.integer.value[0] = value; - - return 0; -} - -static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_miro *miro = snd_kcontrol_chip(kcontrol); - int error, value, change; - - value = ucontrol->value.integer.value[0]; - - if ((error = aci_setvalue(miro, ACI_SET_PREAMP, value)) < 0) { - snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n", error); - return error; - } - - change = (value != miro->aci_preamp); - miro->aci_preamp = value; - - return change; -} - -static int snd_miro_info_amp(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - - return 0; -} - -static int snd_miro_get_amp(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_miro *miro = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = miro->aci_amp; - - return 0; -} - -static int snd_miro_put_amp(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_miro *miro = snd_kcontrol_chip(kcontrol); - int error, value, change; - - value = ucontrol->value.integer.value[0]; - - if ((error = aci_setvalue(miro, ACI_SET_POWERAMP, value)) < 0) { - snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error); - return error; - } - - change = (value != miro->aci_amp); - miro->aci_amp = value; - - return change; -} - -#define MIRO_DOUBLE(ctl_name, ctl_index, get_right_reg, set_right_reg) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = ctl_name, \ - .index = ctl_index, \ - .info = snd_miro_info_double, \ - .get = snd_miro_get_double, \ - .put = snd_miro_put_double, \ - .private_value = get_right_reg | (set_right_reg << 8) \ -} - -static int snd_miro_info_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - int reg = kcontrol->private_value & 0xff; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - - if ((reg >= ACI_GET_EQ1) && (reg <= ACI_GET_EQ7)) { - - /* equalizer elements */ - - uinfo->value.integer.min = - 0x7f; - uinfo->value.integer.max = 0x7f; - } else { - - /* non-equalizer elements */ - - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 0x20; - } - - return 0; -} - -static int snd_miro_get_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *uinfo) -{ - struct snd_miro *miro = snd_kcontrol_chip(kcontrol); - int left_val, right_val; - - int right_reg = kcontrol->private_value & 0xff; - int left_reg = right_reg + 1; - - if ((right_val = aci_getvalue(miro, right_reg)) < 0) { - snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val); - return right_val; - } - - if ((left_val = aci_getvalue(miro, left_reg)) < 0) { - snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val); - return left_val; - } - - if ((right_reg >= ACI_GET_EQ1) && (right_reg <= ACI_GET_EQ7)) { - - /* equalizer elements */ - - if (left_val < 0x80) { - uinfo->value.integer.value[0] = left_val; - } else { - uinfo->value.integer.value[0] = 0x80 - left_val; - } - - if (right_val < 0x80) { - uinfo->value.integer.value[1] = right_val; - } else { - uinfo->value.integer.value[1] = 0x80 - right_val; - } - - } else { - - /* non-equalizer elements */ - - uinfo->value.integer.value[0] = 0x20 - left_val; - uinfo->value.integer.value[1] = 0x20 - right_val; - } - - return 0; -} - -static int snd_miro_put_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_miro *miro = snd_kcontrol_chip(kcontrol); - int left, right, left_old, right_old; - int setreg_left, setreg_right, getreg_left, getreg_right; - int change, error; - - left = ucontrol->value.integer.value[0]; - right = ucontrol->value.integer.value[1]; - - setreg_right = (kcontrol->private_value >> 8) & 0xff; - if (setreg_right == ACI_SET_MASTER) { - setreg_left = setreg_right + 1; - } else { - setreg_left = setreg_right + 8; - } - - getreg_right = kcontrol->private_value & 0xff; - getreg_left = getreg_right + 1; - - if ((left_old = aci_getvalue(miro, getreg_left)) < 0) { - snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old); - return left_old; - } - - if ((right_old = aci_getvalue(miro, getreg_right)) < 0) { - snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old); - return right_old; - } - - if ((getreg_right >= ACI_GET_EQ1) && (getreg_right <= ACI_GET_EQ7)) { - - /* equalizer elements */ - - if (left_old > 0x80) - left_old = 0x80 - left_old; - if (right_old > 0x80) - right_old = 0x80 - right_old; - - if (left >= 0) { - if ((error = aci_setvalue(miro, setreg_left, left)) < 0) { - snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", - left, error); - return error; - } - } else { - if ((error = aci_setvalue(miro, setreg_left, 0x80 - left)) < 0) { - snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", - 0x80 - left, error); - return error; - } - } - - if (right >= 0) { - if ((error = aci_setvalue(miro, setreg_right, right)) < 0) { - snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", - right, error); - return error; - } - } else { - if ((error = aci_setvalue(miro, setreg_right, 0x80 - right)) < 0) { - snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", - 0x80 - right, error); - return error; - } - } - - } else { - - /* non-equalizer elements */ - - left_old = 0x20 - left_old; - right_old = 0x20 - right_old; - - if ((error = aci_setvalue(miro, setreg_left, 0x20 - left)) < 0) { - snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", - 0x20 - left, error); - return error; - } - if ((error = aci_setvalue(miro, setreg_right, 0x20 - right)) < 0) { - snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", - 0x20 - right, error); - return error; - } - } - - change = (left != left_old) || (right != right_old); - - return change; -} - -static struct snd_kcontrol_new snd_miro_controls[] = { -MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER), -MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC), -MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE), -MIRO_DOUBLE("CD Playback Volume", 0, ACI_GET_CD, ACI_SET_CD), -MIRO_DOUBLE("Synth Playback Volume", 0, ACI_GET_SYNTH, ACI_SET_SYNTH), -MIRO_DOUBLE("PCM Playback Volume", 1, ACI_GET_PCM, ACI_SET_PCM), -MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2), -}; - -/* Equalizer with seven bands (only PCM20) - from -12dB up to +12dB on each band */ -static struct snd_kcontrol_new snd_miro_eq_controls[] = { -MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1), -MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2), -MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3), -MIRO_DOUBLE("Tone Control - 1 kHz", 0, ACI_GET_EQ4, ACI_SET_EQ4), -MIRO_DOUBLE("Tone Control - 2.5 kHz", 0, ACI_GET_EQ5, ACI_SET_EQ5), -MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6), -MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7), -}; - -static struct snd_kcontrol_new snd_miro_radio_control[] = { -MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1), -}; - -static struct snd_kcontrol_new snd_miro_line_control[] = { -MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1), -}; - -static struct snd_kcontrol_new snd_miro_preamp_control[] = { -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Boost", - .index = 1, - .info = snd_miro_info_preamp, - .get = snd_miro_get_preamp, - .put = snd_miro_put_preamp, -}}; - -static struct snd_kcontrol_new snd_miro_amp_control[] = { -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Line Boost", - .index = 0, - .info = snd_miro_info_amp, - .get = snd_miro_get_amp, - .put = snd_miro_put_amp, -}}; - -static struct snd_kcontrol_new snd_miro_capture_control[] = { -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Capture Switch", - .index = 0, - .info = snd_miro_info_capture, - .get = snd_miro_get_capture, - .put = snd_miro_put_capture, -}}; - -static unsigned char aci_init_values[][2] __initdata = { - { ACI_SET_MUTE, 0x00 }, - { ACI_SET_POWERAMP, 0x00 }, - { ACI_SET_PREAMP, 0x00 }, - { ACI_SET_SOLOMODE, 0x00 }, - { ACI_SET_MIC + 0, 0x20 }, - { ACI_SET_MIC + 8, 0x20 }, - { ACI_SET_LINE + 0, 0x20 }, - { ACI_SET_LINE + 8, 0x20 }, - { ACI_SET_CD + 0, 0x20 }, - { ACI_SET_CD + 8, 0x20 }, - { ACI_SET_PCM + 0, 0x20 }, - { ACI_SET_PCM + 8, 0x20 }, - { ACI_SET_LINE1 + 0, 0x20 }, - { ACI_SET_LINE1 + 8, 0x20 }, - { ACI_SET_LINE2 + 0, 0x20 }, - { ACI_SET_LINE2 + 8, 0x20 }, - { ACI_SET_SYNTH + 0, 0x20 }, - { ACI_SET_SYNTH + 8, 0x20 }, - { ACI_SET_MASTER + 0, 0x20 }, - { ACI_SET_MASTER + 1, 0x20 }, -}; - -static int __init snd_set_aci_init_values(struct snd_miro *miro) -{ - int idx, error; - - /* enable WSS on PCM1 */ - - if ((miro->aci_product == 'A') && wss) { - if ((error = aci_setvalue(miro, ACI_SET_WSS, wss)) < 0) { - snd_printk(KERN_ERR "enabling WSS mode failed\n"); - return error; - } - } - - /* enable IDE port */ - - if (ide) { - if ((error = aci_setvalue(miro, ACI_SET_IDE, ide)) < 0) { - snd_printk(KERN_ERR "enabling IDE port failed\n"); - return error; - } - } - - /* set common aci values */ - - for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) - if ((error = aci_setvalue(miro, aci_init_values[idx][0], - aci_init_values[idx][1])) < 0) { - snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", - aci_init_values[idx][0], error); - return error; - } - - miro->aci_amp = 0; - miro->aci_preamp = 0; - miro->aci_solomode = 1; - - return 0; -} - -static int snd_miro_mixer(struct snd_miro *miro) -{ - struct snd_card *card; - unsigned int idx; - int err; - - snd_assert(miro != NULL && miro->card != NULL, return -EINVAL); - - card = miro->card; - - switch (miro->hardware) { - case OPTi9XX_HW_82C924: - strcpy(card->mixername, "ACI & OPTi924"); - break; - case OPTi9XX_HW_82C929: - strcpy(card->mixername, "ACI & OPTi929"); - break; - default: - snd_BUG(); - break; - } - - for (idx = 0; idx < ARRAY_SIZE(snd_miro_controls); idx++) { - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_controls[idx], miro))) < 0) - return err; - } - - if ((miro->aci_product == 'A') || (miro->aci_product == 'B')) { - /* PCM1/PCM12 with power-amp and Line 2 */ - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0) - return err; - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_amp_control[0], miro))) < 0) - return err; - } - - if ((miro->aci_product == 'B') || (miro->aci_product == 'C')) { - /* PCM12/PCM20 with mic-preamp */ - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0) - return err; - if (miro->aci_version >= 176) - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0) - return err; - } - - if (miro->aci_product == 'C') { - /* PCM20 with radio and 7 band equalizer */ - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0) - return err; - for (idx = 0; idx < ARRAY_SIZE(snd_miro_eq_controls); idx++) { - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_eq_controls[idx], miro))) < 0) - return err; - } - } - - return 0; -} - -static long snd_legacy_find_free_ioport(long *port_table, long size) -{ - while (*port_table != -1) { - struct resource *res; - if ((res = request_region(*port_table, size, - "ALSA test")) != NULL) { - release_and_free_resource(res); - return *port_table; - } - port_table++; - } - return -1; -} - -static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware) -{ - static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; - - chip->hardware = hardware; - strcpy(chip->name, snd_opti9xx_names[hardware]); - - chip->mc_base_size = opti9xx_mc_size[hardware]; - - spin_lock_init(&chip->lock); - - chip->wss_base = -1; - chip->irq = -1; - chip->dma1 = -1; - chip->dma2 = -1; - chip->fm_port = -1; - chip->mpu_port = -1; - chip->mpu_irq = -1; - - switch (hardware) { - case OPTi9XX_HW_82C929: - chip->mc_base = 0xf8c; - chip->password = 0xe3; - chip->pwd_reg = 3; - break; - - case OPTi9XX_HW_82C924: - chip->mc_base = 0xf8c; - chip->password = 0xe5; - chip->pwd_reg = 3; - break; - - default: - snd_printk(KERN_ERR "sorry, no support for %d\n", hardware); - return -ENODEV; - } - - return 0; -} - -static unsigned char snd_miro_read(struct snd_miro *chip, - unsigned char reg) -{ - unsigned long flags; - unsigned char retval = 0xff; - - spin_lock_irqsave(&chip->lock, flags); - outb(chip->password, chip->mc_base + chip->pwd_reg); - - switch (chip->hardware) { - case OPTi9XX_HW_82C924: - if (reg > 7) { - outb(reg, chip->mc_base + 8); - outb(chip->password, chip->mc_base + chip->pwd_reg); - retval = inb(chip->mc_base + 9); - break; - } - - case OPTi9XX_HW_82C929: - retval = inb(chip->mc_base + reg); - break; - - default: - snd_printk(KERN_ERR "sorry, no support for %d\n", chip->hardware); - } - - spin_unlock_irqrestore(&chip->lock, flags); - return retval; -} - -static void snd_miro_write(struct snd_miro *chip, unsigned char reg, - unsigned char value) -{ - unsigned long flags; - - spin_lock_irqsave(&chip->lock, flags); - outb(chip->password, chip->mc_base + chip->pwd_reg); - - switch (chip->hardware) { - case OPTi9XX_HW_82C924: - if (reg > 7) { - outb(reg, chip->mc_base + 8); - outb(chip->password, chip->mc_base + chip->pwd_reg); - outb(value, chip->mc_base + 9); - break; - } - - case OPTi9XX_HW_82C929: - outb(value, chip->mc_base + reg); - break; - - default: - snd_printk(KERN_ERR "sorry, no support for %d\n", chip->hardware); - } - - spin_unlock_irqrestore(&chip->lock, flags); -} - - -#define snd_miro_write_mask(chip, reg, value, mask) \ - snd_miro_write(chip, reg, \ - (snd_miro_read(chip, reg) & ~(mask)) | ((value) & (mask))) - -/* - * Proc Interface - */ - -static void snd_miro_proc_read(struct snd_info_entry * entry, - struct snd_info_buffer *buffer) -{ - struct snd_miro *miro = (struct snd_miro *) entry->private_data; - char* model = "unknown"; - - /* miroSOUND PCM1 pro, early PCM12 */ - - if ((miro->hardware == OPTi9XX_HW_82C929) && - (miro->aci_vendor == 'm') && - (miro->aci_product == 'A')) { - switch(miro->aci_version) { - case 3: - model = "miroSOUND PCM1 pro"; - break; - default: - model = "miroSOUND PCM1 pro / (early) PCM12"; - break; - } - } - - /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */ - - if ((miro->hardware == OPTi9XX_HW_82C924) && - (miro->aci_vendor == 'm') && - (miro->aci_product == 'B')) { - switch(miro->aci_version) { - case 4: - model = "miroSOUND PCM12"; - break; - case 176: - model = "miroSOUND PCM12 (Rev. E)"; - break; - default: - model = "miroSOUND PCM12 / PCM12 pnp"; - break; - } - } - - /* miroSOUND PCM20 radio */ - - if ((miro->hardware == OPTi9XX_HW_82C924) && - (miro->aci_vendor == 'm') && - (miro->aci_product == 'C')) { - switch(miro->aci_version) { - case 7: - model = "miroSOUND PCM20 radio (Rev. E)"; - break; - default: - model = "miroSOUND PCM20 radio"; - break; - } - } - - snd_iprintf(buffer, "\nGeneral information:\n"); - snd_iprintf(buffer, " model : %s\n", model); - snd_iprintf(buffer, " opti : %s\n", miro->name); - snd_iprintf(buffer, " codec : %s\n", miro->pcm->name); - snd_iprintf(buffer, " port : 0x%lx\n", miro->wss_base); - snd_iprintf(buffer, " irq : %d\n", miro->irq); - snd_iprintf(buffer, " dma : %d,%d\n\n", miro->dma1, miro->dma2); - - snd_iprintf(buffer, "MPU-401:\n"); - snd_iprintf(buffer, " port : 0x%lx\n", miro->mpu_port); - snd_iprintf(buffer, " irq : %d\n\n", miro->mpu_irq); - - snd_iprintf(buffer, "ACI information:\n"); - snd_iprintf(buffer, " vendor : "); - switch(miro->aci_vendor) { - case 'm': - snd_iprintf(buffer, "Miro\n"); - break; - default: - snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_vendor); - break; - } - - snd_iprintf(buffer, " product : "); - switch(miro->aci_product) { - case 'A': - snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n"); - break; - case 'B': - snd_iprintf(buffer, "miroSOUND PCM12\n"); - break; - case 'C': - snd_iprintf(buffer, "miroSOUND PCM20 radio\n"); - break; - default: - snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_product); - break; - } - - snd_iprintf(buffer, " firmware: %d (0x%x)\n", - miro->aci_version, miro->aci_version); - snd_iprintf(buffer, " port : 0x%lx-0x%lx\n", - miro->aci_port, miro->aci_port+2); - snd_iprintf(buffer, " wss : 0x%x\n", wss); - snd_iprintf(buffer, " ide : 0x%x\n", ide); - snd_iprintf(buffer, " solomode: 0x%x\n", miro->aci_solomode); - snd_iprintf(buffer, " amp : 0x%x\n", miro->aci_amp); - snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp); -} - -static void __init snd_miro_proc_init(struct snd_miro * miro) -{ - struct snd_info_entry *entry; - - if (! snd_card_proc_new(miro->card, "miro", &entry)) - snd_info_set_text_ops(entry, miro, 1024, snd_miro_proc_read); -} - -/* - * Init - */ - -static int __init snd_miro_configure(struct snd_miro *chip) -{ - unsigned char wss_base_bits; - unsigned char irq_bits; - unsigned char dma_bits; - unsigned char mpu_port_bits = 0; - unsigned char mpu_irq_bits; - unsigned long flags; - - switch (chip->hardware) { - case OPTi9XX_HW_82C924: - snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); - snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); - snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */ - snd_miro_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); - snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); - break; - case OPTi9XX_HW_82C929: - /* untested init commands for OPTi929 */ - snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); - snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */ - snd_miro_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c); - snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); - break; - default: - snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); - return -EINVAL; - } - - switch (chip->wss_base) { - case 0x530: - wss_base_bits = 0x00; - break; - case 0x604: - wss_base_bits = 0x03; - break; - case 0xe80: - wss_base_bits = 0x01; - break; - case 0xf40: - wss_base_bits = 0x02; - break; - default: - snd_printk(KERN_ERR "WSS port 0x%lx not valid\n", chip->wss_base); - goto __skip_base; - } - snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); - -__skip_base: - switch (chip->irq) { - case 5: - irq_bits = 0x05; - break; - case 7: - irq_bits = 0x01; - break; - case 9: - irq_bits = 0x02; - break; - case 10: - irq_bits = 0x03; - break; - case 11: - irq_bits = 0x04; - break; - default: - snd_printk(KERN_ERR "WSS irq # %d not valid\n", chip->irq); - goto __skip_resources; - } - - switch (chip->dma1) { - case 0: - dma_bits = 0x01; - break; - case 1: - dma_bits = 0x02; - break; - case 3: - dma_bits = 0x03; - break; - default: - snd_printk(KERN_ERR "WSS dma1 # %d not valid\n", chip->dma1); - goto __skip_resources; - } - - if (chip->dma1 == chip->dma2) { - snd_printk(KERN_ERR "don't want to share dmas\n"); - return -EBUSY; - } - - switch (chip->dma2) { - case 0: - case 1: - break; - default: - snd_printk(KERN_ERR "WSS dma2 # %d not valid\n", chip->dma2); - goto __skip_resources; - } - dma_bits |= 0x04; - - spin_lock_irqsave(&chip->lock, flags); - outb(irq_bits << 3 | dma_bits, chip->wss_base); - spin_unlock_irqrestore(&chip->lock, flags); - -__skip_resources: - if (chip->hardware > OPTi9XX_HW_82C928) { - switch (chip->mpu_port) { - case 0: - case -1: - break; - case 0x300: - mpu_port_bits = 0x03; - break; - case 0x310: - mpu_port_bits = 0x02; - break; - case 0x320: - mpu_port_bits = 0x01; - break; - case 0x330: - mpu_port_bits = 0x00; - break; - default: - snd_printk(KERN_ERR "MPU-401 port 0x%lx not valid\n", - chip->mpu_port); - goto __skip_mpu; - } - - switch (chip->mpu_irq) { - case 5: - mpu_irq_bits = 0x02; - break; - case 7: - mpu_irq_bits = 0x03; - break; - case 9: - mpu_irq_bits = 0x00; - break; - case 10: - mpu_irq_bits = 0x01; - break; - default: - snd_printk(KERN_ERR "MPU-401 irq # %d not valid\n", - chip->mpu_irq); - goto __skip_mpu; - } - - snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), - (chip->mpu_port <= 0) ? 0x00 : - 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3, - 0xf8); - } -__skip_mpu: - - return 0; -} - -static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip) -{ - int i, err; - unsigned char value; - - for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) { - - if ((err = snd_miro_init(chip, i)) < 0) - return err; - - if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) - continue; - - value = snd_miro_read(chip, OPTi9XX_MC_REG(1)); - if ((value != 0xff) && (value != inb(chip->mc_base + 1))) - if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1))) - return 1; - - release_and_free_resource(chip->res_mc_base); - chip->res_mc_base = NULL; - - } - - return -ENODEV; -} - -static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro) -{ - unsigned char regval; - int i; - - mutex_init(&miro->aci_mutex); - - /* get ACI port from OPTi9xx MC 4 */ - - miro->mc_base = 0xf8c; - regval=inb(miro->mc_base + 4); - miro->aci_port = (regval & 0x10) ? 0x344: 0x354; - - if ((miro->res_aci_port = request_region(miro->aci_port, 3, "miro aci")) == NULL) { - snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n", - miro->aci_port, miro->aci_port+2); - return -ENOMEM; - } - - /* force ACI into a known state */ - for (i = 0; i < 3; i++) - if (aci_cmd(miro, ACI_ERROR_OP, -1, -1) < 0) { - snd_printk(KERN_ERR "can't force aci into known state.\n"); - return -ENXIO; - } - - if ((miro->aci_vendor=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0 || - (miro->aci_product=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0) { - snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n", miro->aci_port); - return -ENXIO; - } - - if ((miro->aci_version=aci_cmd(miro, ACI_READ_VERSION, -1, -1)) < 0) { - snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n", - miro->aci_port); - return -ENXIO; - } - - if (aci_cmd(miro, ACI_INIT, -1, -1) < 0 || - aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 || - aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) { - snd_printk(KERN_ERR "can't initialize aci.\n"); - return -ENXIO; - } - - return 0; -} - -static void snd_card_miro_free(struct snd_card *card) -{ - struct snd_miro *miro = card->private_data; - - release_and_free_resource(miro->res_aci_port); - release_and_free_resource(miro->res_mc_base); -} - -static int __init snd_miro_probe(struct platform_device *devptr) -{ - static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; - static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1}; - static int possible_irqs[] = {11, 9, 10, 7, -1}; - static int possible_mpu_irqs[] = {10, 5, 9, 7, -1}; - static int possible_dma1s[] = {3, 1, 0, -1}; - static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}}; - - int error; - struct snd_miro *miro; - struct snd_cs4231 *codec; - struct snd_timer *timer; - struct snd_card *card; - struct snd_pcm *pcm; - struct snd_rawmidi *rmidi; - - if (!(card = snd_card_new(index, id, THIS_MODULE, - sizeof(struct snd_miro)))) - return -ENOMEM; - - card->private_free = snd_card_miro_free; - miro = card->private_data; - miro->card = card; - - if ((error = snd_card_miro_aci_detect(card, miro)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR "unable to detect aci chip\n"); - return -ENODEV; - } - - /* init proc interface */ - snd_miro_proc_init(miro); - - if ((error = snd_card_miro_detect(card, miro)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n"); - return -ENODEV; - } - - if (! miro->res_mc_base && - (miro->res_mc_base = request_region(miro->mc_base, miro->mc_base_size, - "miro (OPTi9xx MC)")) == NULL) { - snd_card_free(card); - snd_printk(KERN_ERR "request for OPTI9xx MC failed\n"); - return -ENOMEM; - } - - miro->wss_base = port; - miro->fm_port = fm_port; - miro->mpu_port = mpu_port; - miro->irq = irq; - miro->mpu_irq = mpu_irq; - miro->dma1 = dma1; - miro->dma2 = dma2; - - if (miro->wss_base == SNDRV_AUTO_PORT) { - if ((miro->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR "unable to find a free WSS port\n"); - return -EBUSY; - } - } - - if (miro->mpu_port == SNDRV_AUTO_PORT) { - if ((miro->mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR "unable to find a free MPU401 port\n"); - return -EBUSY; - } - } - if (miro->irq == SNDRV_AUTO_IRQ) { - if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR "unable to find a free IRQ\n"); - return -EBUSY; - } - } - if (miro->mpu_irq == SNDRV_AUTO_IRQ) { - if ((miro->mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n"); - return -EBUSY; - } - } - if (miro->dma1 == SNDRV_AUTO_DMA) { - if ((miro->dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR "unable to find a free DMA1\n"); - return -EBUSY; - } - } - if (miro->dma2 == SNDRV_AUTO_DMA) { - if ((miro->dma2 = snd_legacy_find_free_dma(possible_dma2s[miro->dma1 % 4])) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR "unable to find a free DMA2\n"); - return -EBUSY; - } - } - - if ((error = snd_miro_configure(miro))) { - snd_card_free(card); - return error; - } - - if ((error = snd_cs4231_create(card, miro->wss_base + 4, -1, - miro->irq, miro->dma1, miro->dma2, - CS4231_HW_AD1845, - 0, - &codec)) < 0) { - snd_card_free(card); - return error; - } - - if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) { - snd_card_free(card); - return error; - } - if ((error = snd_cs4231_mixer(codec)) < 0) { - snd_card_free(card); - return error; - } - if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) { - snd_card_free(card); - return error; - } - - miro->pcm = pcm; - - if ((error = snd_miro_mixer(miro)) < 0) { - snd_card_free(card); - return error; - } - - if (miro->aci_vendor == 'm') { - /* It looks like a miro sound card. */ - switch (miro->aci_product) { - case 'A': - sprintf(card->shortname, - "miroSOUND PCM1 pro / PCM12"); - break; - case 'B': - sprintf(card->shortname, - "miroSOUND PCM12"); - break; - case 'C': - sprintf(card->shortname, - "miroSOUND PCM20 radio"); - break; - default: - sprintf(card->shortname, - "unknown miro"); - snd_printk(KERN_INFO "unknown miro aci id\n"); - break; - } - } else { - snd_printk(KERN_INFO "found unsupported aci card\n"); - sprintf(card->shortname, "unknown Cardinal Technologies"); - } - - strcpy(card->driver, "miro"); - sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d", - card->shortname, miro->name, pcm->name, miro->wss_base + 4, - miro->irq, miro->dma1, miro->dma2); - - if (miro->mpu_port <= 0 || miro->mpu_port == SNDRV_AUTO_PORT) - rmidi = NULL; - else - if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, - miro->mpu_port, 0, miro->mpu_irq, SA_INTERRUPT, - &rmidi))) - snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", miro->mpu_port); - - if (miro->fm_port > 0 && miro->fm_port != SNDRV_AUTO_PORT) { - struct snd_opl3 *opl3 = NULL; - struct snd_opl4 *opl4; - if (snd_opl4_create(card, miro->fm_port, miro->fm_port - 8, - 2, &opl3, &opl4) < 0) - snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n", miro->fm_port); - } - - if ((error = snd_set_aci_init_values(miro)) < 0) { - snd_card_free(card); - return error; - } - - snd_card_set_dev(card, &devptr->dev); - - if ((error = snd_card_register(card))) { - snd_card_free(card); - return error; - } - - platform_set_drvdata(devptr, card); - return 0; -} - -static int __devexit snd_miro_remove(struct platform_device *devptr) -{ - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); - return 0; -} - -static struct platform_driver snd_miro_driver = { - .probe = snd_miro_probe, - .remove = __devexit_p(snd_miro_remove), - /* FIXME: suspend/resume */ - .driver = { - .name = DRIVER_NAME - }, -}; - -static int __init alsa_card_miro_init(void) -{ - int error; - - if ((error = platform_driver_register(&snd_miro_driver)) < 0) - return error; - device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); - if (! IS_ERR(device)) { - if (platform_get_drvdata(device)) - return 0; - platform_device_unregister(device); - } -#ifdef MODULE - printk(KERN_ERR "no miro soundcard found\n"); -#endif - platform_driver_unregister(&snd_miro_driver); - return PTR_ERR(device); -} - -static void __exit alsa_card_miro_exit(void) -{ - platform_device_unregister(device); - platform_driver_unregister(&snd_miro_driver); -} - -module_init(alsa_card_miro_init) -module_exit(alsa_card_miro_exit) diff --git a/sound/isa/opti9xx/miro.h b/sound/isa/opti9xx/miro.h deleted file mode 100644 index 6e1385b8e..000000000 --- a/sound/isa/opti9xx/miro.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _MIRO_H_ -#define _MIRO_H_ - -#define ACI_REG_COMMAND 0 /* write register offset */ -#define ACI_REG_STATUS 1 /* read register offset */ -#define ACI_REG_BUSY 2 /* busy register offset */ -#define ACI_REG_RDS 2 /* PCM20: RDS register offset */ -#define ACI_MINTIME 500 /* ACI time out limit */ - -#define ACI_SET_MUTE 0x0d -#define ACI_SET_POWERAMP 0x0f -#define ACI_SET_TUNERMUTE 0xa3 -#define ACI_SET_TUNERMONO 0xa4 -#define ACI_SET_IDE 0xd0 -#define ACI_SET_WSS 0xd1 -#define ACI_SET_SOLOMODE 0xd2 -#define ACI_SET_PREAMP 0x03 -#define ACI_GET_PREAMP 0x21 -#define ACI_WRITE_TUNE 0xa7 -#define ACI_READ_TUNERSTEREO 0xa8 -#define ACI_READ_TUNERSTATION 0xa9 -#define ACI_READ_VERSION 0xf1 -#define ACI_READ_IDCODE 0xf2 -#define ACI_INIT 0xff -#define ACI_STATUS 0xf0 -#define ACI_S_GENERAL 0x00 -#define ACI_ERROR_OP 0xdf - -/* ACI Mixer */ - -/* These are the values for the right channel GET registers. - Add an offset of 0x01 for the left channel register. - (left=right+0x01) */ - -#define ACI_GET_MASTER 0x03 -#define ACI_GET_MIC 0x05 -#define ACI_GET_LINE 0x07 -#define ACI_GET_CD 0x09 -#define ACI_GET_SYNTH 0x0b -#define ACI_GET_PCM 0x0d -#define ACI_GET_LINE1 0x10 /* Radio on PCM20 */ -#define ACI_GET_LINE2 0x12 - -#define ACI_GET_EQ1 0x22 /* from Bass ... */ -#define ACI_GET_EQ2 0x24 -#define ACI_GET_EQ3 0x26 -#define ACI_GET_EQ4 0x28 -#define ACI_GET_EQ5 0x2a -#define ACI_GET_EQ6 0x2c -#define ACI_GET_EQ7 0x2e /* ... to Treble */ - -/* And these are the values for the right channel SET registers. - For left channel access you have to add an offset of 0x08. - MASTER is an exception, which needs an offset of 0x01 */ - -#define ACI_SET_MASTER 0x00 -#define ACI_SET_MIC 0x30 -#define ACI_SET_LINE 0x31 -#define ACI_SET_CD 0x34 -#define ACI_SET_SYNTH 0x33 -#define ACI_SET_PCM 0x32 -#define ACI_SET_LINE1 0x35 /* Radio on PCM20 */ -#define ACI_SET_LINE2 0x36 - -#define ACI_SET_EQ1 0x40 /* from Bass ... */ -#define ACI_SET_EQ2 0x41 -#define ACI_SET_EQ3 0x42 -#define ACI_SET_EQ4 0x43 -#define ACI_SET_EQ5 0x44 -#define ACI_SET_EQ6 0x45 -#define ACI_SET_EQ7 0x46 /* ... to Treble */ - -#endif /* _MIRO_H_ */ diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 8ee0d7053..65b28cbc0 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -2099,11 +2099,8 @@ static int __init alsa_card_opti9xx_init(void) return error; device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); if (!IS_ERR(device)) { - if (platform_get_drvdata(device)) { - snd_opti9xx_platform_device = device; - return 0; - } - platform_device_unregister(device); + snd_opti9xx_platform_device = device; + return 0; } platform_driver_unregister(&snd_opti9xx_driver); } diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c index d4d65b842..9da80bfa3 100644 --- a/sound/isa/sb/es968.c +++ b/sound/isa/sb/es968.c @@ -124,7 +124,7 @@ static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard, return 0; } -static int __devinit snd_card_es968_probe(int dev, +static int __init snd_card_es968_probe(int dev, struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -182,8 +182,6 @@ static int __devinit snd_card_es968_probe(int dev, return 0; } -static unsigned int __devinitdata es968_devices; - static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card, const struct pnp_card_device_id *id) { @@ -197,7 +195,6 @@ static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card, if (res < 0) return res; dev++; - es968_devices++; return 0; } return -ENODEV; @@ -249,11 +246,8 @@ static struct pnp_card_driver es968_pnpc_driver = { static int __init alsa_card_es968_init(void) { - int err = pnp_register_card_driver(&es968_pnpc_driver); - if (err) - return err; - - if (!es968_devices) { + int cards = pnp_register_card_driver(&es968_pnpc_driver); + if (cards <= 0) { pnp_unregister_card_driver(&es968_pnpc_driver); #ifdef MODULE snd_printk(KERN_ERR "no ES968 based soundcards found\n"); diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 6333f900e..0667bd14a 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -369,7 +369,7 @@ static struct snd_card *snd_sb16_card_new(int dev) return card; } -static int __devinit snd_sb16_probe(struct snd_card *card, int dev) +static int __init snd_sb16_probe(struct snd_card *card, int dev) { int xirq, xdma8, xdma16; struct snd_sb *chip; @@ -518,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card) } #endif -static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __init snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr) { struct snd_card_sb16 *acard; struct snd_card *card; @@ -548,7 +548,7 @@ static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *dev } -static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) +static int __init snd_sb16_nonpnp_probe(struct platform_device *pdev) { int dev = pdev->id; int err; @@ -629,7 +629,6 @@ static struct platform_driver snd_sb16_nonpnp_driver = { #ifdef CONFIG_PNP -static unsigned int __devinitdata sb16_pnp_devices; static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) @@ -652,7 +651,6 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - sb16_pnp_devices++; return 0; } @@ -714,27 +712,25 @@ static int __init alsa_card_sb16_init(void) if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) + if (is_isapnp_selected(i)) continue; device = platform_device_register_simple(SND_SB16_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } platform_devices[i] = device; cards++; } #ifdef CONFIG_PNP /* PnP cards at last */ - err = pnp_register_card_driver(&sb16_pnpc_driver); - if (!err) { + i = pnp_register_card_driver(&sb16_pnpc_driver); + if (i >= 0) { pnp_registered = 1; - cards += sb16_pnp_devices; + cards += i; } #endif @@ -747,10 +743,14 @@ static int __init alsa_card_sb16_init(void) snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n"); #endif #endif - snd_sb16_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_sb16_unregister_all(); + return err; } static void __exit alsa_card_sb16_exit(void) diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 9703c68e4..9c2b5efba 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -138,7 +138,7 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) p->ops.csp_stop = snd_sb_csp_stop; p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer; - mutex_init(&p->access_mutex); + init_MUTEX(&p->access_mutex); sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f)); hw->iface = SNDRV_HWDEP_IFACE_SB16CSP; hw->private_data = p; @@ -265,13 +265,13 @@ static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file) */ static int snd_sb_csp_use(struct snd_sb_csp * p) { - mutex_lock(&p->access_mutex); + down(&p->access_mutex); if (p->used) { - mutex_unlock(&p->access_mutex); + up(&p->access_mutex); return -EAGAIN; } p->used++; - mutex_unlock(&p->access_mutex); + up(&p->access_mutex); return 0; @@ -282,9 +282,9 @@ static int snd_sb_csp_use(struct snd_sb_csp * p) */ static int snd_sb_csp_unuse(struct snd_sb_csp * p) { - mutex_lock(&p->access_mutex); + down(&p->access_mutex); p->used--; - mutex_unlock(&p->access_mutex); + up(&p->access_mutex); return 0; } diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index 141400c01..60ee79cd1 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -258,17 +258,13 @@ static int __init alsa_card_sb8_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(SND_SB8_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } devices[i] = device; cards++; @@ -277,10 +273,14 @@ static int __init alsa_card_sb8_init(void) #ifdef MODULE snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n"); #endif - snd_sb8_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_sb8_unregister_all(); + return err; } static void __exit alsa_card_sb8_exit(void) diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 09c8e8c6b..0dbbb35b2 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -360,17 +360,13 @@ static int __init alsa_card_sgalaxy_init(void) return err; cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; device = platform_device_register_simple(SND_SGALAXY_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } devices[i] = device; cards++; @@ -379,10 +375,14 @@ static int __init alsa_card_sgalaxy_init(void) #ifdef MODULE snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n"); #endif - snd_sgalaxy_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_sgalaxy_unregister_all(); + return err; } static void __exit alsa_card_sgalaxy_exit(void) diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index d2a856f0f..29bba8cc3 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -1255,7 +1255,7 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) } -static int __devinit snd_sscape_probe(struct platform_device *pdev) +static int __init snd_sscape_probe(struct platform_device *pdev) { int dev = pdev->id; struct snd_card *card; @@ -1427,8 +1427,8 @@ static int __init sscape_manual_probe(void) dma[i] == SNDRV_AUTO_DMA) { printk(KERN_INFO "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); - sscape_unregister_all(); - return -ENXIO; + ret = -ENXIO; + goto errout; } /* @@ -1436,15 +1436,17 @@ static int __init sscape_manual_probe(void) */ device = platform_device_register_simple(SSCAPE_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + ret = PTR_ERR(device); + goto errout; } platform_devices[i] = device; } return 0; + + errout: + sscape_unregister_all(); + return ret; } static void sscape_exit(void) @@ -1467,7 +1469,7 @@ static int __init sscape_init(void) if (ret < 0) return ret; #ifdef CONFIG_PNP - if (pnp_register_card_driver(&sscape_pnpc_driver) == 0) + if (pnp_register_card_driver(&sscape_pnpc_driver) >= 0) pnp_registered = 1; #endif return 0; diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 7ae86f82c..fa3ab960d 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -589,7 +589,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev) +static int __init snd_wavefront_nonpnp_probe(struct platform_device *pdev) { int dev = pdev->id; struct snd_card *card; @@ -637,7 +637,6 @@ static struct platform_driver snd_wavefront_driver = { #ifdef CONFIG_PNP -static unsigned int __devinitdata wavefront_pnp_devices; static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) @@ -671,7 +670,6 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, pnp_set_card_drvdata(pcard, card); dev++; - wavefront_pnp_devices++; return 0; } @@ -712,31 +710,27 @@ static int __init alsa_card_wavefront_init(void) if ((err = platform_driver_register(&snd_wavefront_driver)) < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { + for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { struct platform_device *device; - if (! enable[i]) - continue; #ifdef CONFIG_PNP if (isapnp[i]) continue; #endif device = platform_device_register_simple(WAVEFRONT_DRIVER, i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; + if (IS_ERR(device)) { + err = PTR_ERR(device); + goto errout; } platform_devices[i] = device; cards++; } #ifdef CONFIG_PNP - err = pnp_register_card_driver(&wavefront_pnpc_driver); - if (!err) { + i = pnp_register_card_driver(&wavefront_pnpc_driver); + if (i >= 0) { pnp_registered = 1; - cards += wavefront_pnp_devices; + cards += i; } #endif @@ -744,10 +738,14 @@ static int __init alsa_card_wavefront_init(void) #ifdef MODULE printk (KERN_ERR "No WaveFront cards found or devices busy\n"); #endif - snd_wavefront_unregister_all(); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_wavefront_unregister_all(); + return err; } static void __exit alsa_card_wavefront_exit(void) diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index cf476fe1a..6d8f8b3ea 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -154,7 +153,6 @@ au1000_setup_dma_link(struct audio_stream *stream, unsigned int period_bytes, { struct snd_pcm_substream *substream = stream->substream; struct snd_pcm_runtime *runtime = substream->runtime; - struct au1000_period *pointer; unsigned long dma_start; int i; @@ -561,13 +559,12 @@ snd_au1000_ac97_new(struct snd_au1000 *au1000) .read = snd_au1000_ac97_read, }; - if ((au1000->ac97_res_port = request_mem_region(CPHYSADDR(AC97C_CONFIG), - 0x100000, "Au1x00 AC97")) == NULL) { + if ((au1000->ac97_res_port = request_region(AC97C_CONFIG, + sizeof(struct au1000_ac97_reg), "Au1x00 AC97")) == NULL) { snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n"); return -EBUSY; } - au1000->ac97_ioport = (struct au1000_ac97_reg *) - KSEG1ADDR(au1000->ac97_res_port->start); + au1000->ac97_ioport = (struct au1000_ac97_reg *) au1000->ac97_res_port->start; spin_lock_init(&au1000->ac97_lock); @@ -613,17 +610,14 @@ snd_au1000_free(struct snd_card *card) release_and_free_resource(au1000->ac97_res_port); } - if (au1000->stream[PLAYBACK]) { - if (au1000->stream[PLAYBACK]->dma >= 0) - free_au1000_dma(au1000->stream[PLAYBACK]->dma); - kfree(au1000->stream[PLAYBACK]); - } + if (au1000->stream[PLAYBACK]->dma >= 0) + free_au1000_dma(au1000->stream[PLAYBACK]->dma); - if (au1000->stream[CAPTURE]) { - if (au1000->stream[CAPTURE]->dma >= 0) - free_au1000_dma(au1000->stream[CAPTURE]->dma); - kfree(au1000->stream[CAPTURE]); - } + if (au1000->stream[CAPTURE]->dma >= 0) + free_au1000_dma(au1000->stream[CAPTURE]->dma); + + kfree(au1000->stream[PLAYBACK]); + kfree(au1000->stream[CAPTURE]); } @@ -642,19 +636,15 @@ au1000_init(void) card->private_free = snd_au1000_free; au1000 = card->private_data; - au1000->card = card; - - au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); - au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); /* so that snd_au1000_free will work as intended */ + au1000->card = card; + au1000->stream[PLAYBACK]->dma = -1; + au1000->stream[CAPTURE]->dma = -1; au1000->ac97_res_port = NULL; - if (au1000->stream[PLAYBACK]) - au1000->stream[PLAYBACK]->dma = -1; - if (au1000->stream[CAPTURE ]) - au1000->stream[CAPTURE ]->dma = -1; - + au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); + au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); if (au1000->stream[PLAYBACK] == NULL || - au1000->stream[CAPTURE ] == NULL) { + au1000->stream[CAPTURE] == NULL) { snd_card_free(card); return -ENOMEM; } diff --git a/sound/oss/.gitignore b/sound/oss/.gitignore deleted file mode 100644 index 7efb12b45..000000000 --- a/sound/oss/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -#Ignore generated files -maui_boot.h -pss_boot.h -trix_boot.h diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 558c6ed44..f69c6d5e3 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig @@ -5,9 +5,18 @@ # # Prompt user for primary drivers. +config OBSOLETE_OSS_DRIVER + bool "Obsolete OSS drivers" + depends on SOUND_PRIME + help + This option enables support for obsolete OSS drivers that + have been removed in kernel 2.6.17. + + If unsure, say N. + config SOUND_BT878 tristate "BT878 audio dma" - depends on SOUND_PRIME && PCI + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER ---help--- Audio DMA support for bt878 based grabber boards. As you might have already noticed, bt878 is listed with two functions in /proc/pci. @@ -21,9 +30,48 @@ config SOUND_BT878 To compile this driver as a module, choose M here: the module will be called btaudio. +config SOUND_CMPCI + tristate "C-Media PCI (CMI8338/8738)" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + help + Say Y or M if you have a PCI sound card using the CMI8338 + or the CMI8738 chipset. Data on these chips are available at + . + + A userspace utility to control some internal registers of these + chips is available at + . + +config SOUND_CMPCI_FM + bool "Enable legacy FM" + depends on SOUND_CMPCI && X86 + help + Say Y here to enable the legacy FM (frequency-modulation) synthesizer + support on a card using the CMI8338 or CMI8378 chipset. Even it is + enabled, you need to set fmio as proper value to enable it. + Say N here if you don't need this. + +config SOUND_CMPCI_MIDI + bool "Enable legacy MPU-401" + depends on SOUND_CMPCI && X86 + help + Say Y here to enable the legacy MPU401 MIDI synthesizer support on a + card using the CMI8338 or CMI8378 chipset. Even it is enabled, + you need to set mpuio as proper value to enable it. + Say N here if you don't need this. + +config SOUND_CMPCI_JOYSTICK + bool "Enable joystick" + depends on SOUND_CMPCI && X86 && (GAMEPORT=y || SOUND_CMPCI=GAMEPORT) + help + Say Y here in order to enable the joystick port on a sound card using + the CMI8338 or the CMI8738 chipset. You need to config the + gameport support and set joystick parameter as 1 to use it. + Say N here if you don't need this. + config SOUND_EMU10K1 tristate "Creative SBLive! (EMU10K1)" - depends on SOUND_PRIME && PCI + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER ---help--- Say Y or M if you have a PCI sound card using the EMU10K1 chipset, such as the Creative SBLive!, SB PCI512 or Emu-APS. @@ -55,6 +103,13 @@ config SOUND_FUSION series) when wired as native sound drivers with AC97 codecs. If this driver does not work try the CS4232 driver. +config SOUND_CS4281 + tristate "Crystal Sound CS4281" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + help + Picture and feature list at + . + config SOUND_BCM_CS4297A tristate "Crystal Sound CS4297a (for Swarm)" depends on SOUND_PRIME && SIBYTE_SWARM @@ -65,9 +120,22 @@ config SOUND_BCM_CS4297A note that CONFIG_KGDB should not be enabled at the same time, since it also attempts to use this UART port. +config SOUND_ES1370 + tristate "Ensoniq AudioPCI (ES1370)" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + help + Say Y or M if you have a PCI sound card utilizing the Ensoniq + ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find + out if your sound card uses an ES1370 without removing your + computer's cover, use lspci -n and look for the PCI ID + 1274:5000. Since Ensoniq was bought by Creative Labs, + Sound Blaster 64/PCI models are either ES1370 or ES1371 based. + This driver differs slightly from OSS/Free, so PLEASE READ + . + config SOUND_ES1371 tristate "Creative Ensoniq AudioPCI 97 (ES1371)" - depends on SOUND_PRIME && PCI + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER help Say Y or M if you have a PCI sound card utilizing the Ensoniq ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if @@ -78,6 +146,33 @@ config SOUND_ES1371 slightly from OSS/Free, so PLEASE READ . +config SOUND_ESSSOLO1 + tristate "ESS Technology Solo1" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + help + Say Y or M if you have a PCI sound card utilizing the ESS Technology + Solo1 chip. To find out if your sound card uses a + Solo1 chip without removing your computer's cover, use + lspci -n and look for the PCI ID 125D:1969. This driver + differs slightly from OSS/Free, so PLEASE READ + . + +config SOUND_MAESTRO + tristate "ESS Maestro, Maestro2, Maestro2E driver" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + help + Say Y or M if you have a sound system driven by ESS's Maestro line + of PCI sound chips. These include the Maestro 1, Maestro 2, and + Maestro 2E. See for more + details. + +config SOUND_MAESTRO3 + tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)" + depends on SOUND_PRIME && PCI && EXPERIMENTAL && OBSOLETE_OSS_DRIVER + help + Say Y or M if you have a sound system driven by ESS's Maestro 3 + PCI sound chip. + config SOUND_ICH tristate "Intel ICH (i8xx) audio support" depends on SOUND_PRIME && PCI @@ -85,6 +180,24 @@ config SOUND_ICH Support for integral audio in Intel's I/O Controller Hub (ICH) chipset, as used on the 810/820/840 motherboards. +config SOUND_HARMONY + tristate "PA Harmony audio driver" + depends on GSC_LASI && SOUND_PRIME && OBSOLETE_OSS_DRIVER + help + Say 'Y' or 'M' to include support for Harmony soundchip + on HP 712, 715/new and many other GSC based machines. + +config SOUND_SONICVIBES + tristate "S3 SonicVibes" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + help + Say Y or M if you have a PCI sound card utilizing the S3 + SonicVibes chipset. To find out if your sound card uses a + SonicVibes chip without removing your computer's cover, use + lspci -n and look for the PCI ID 5333:CA00. This driver + differs slightly from OSS/Free, so PLEASE READ + . + config SOUND_VWSND tristate "SGI Visual Workstation Sound" depends on SOUND_PRIME && X86_VISWS @@ -113,6 +226,10 @@ config SOUND_VRC5477 integrated, multi-function controller chip for MIPS CPUs. Works with the AC97 codec. +config SOUND_AU1000 + tristate "Au1000 Sound" + depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && OBSOLETE_OSS_DRIVER + config SOUND_AU1550_AC97 tristate "Au1550 AC97 Sound" depends on SOUND_PRIME && SOC_AU1550 @@ -385,7 +502,7 @@ config MSND_FIFOSIZE config SOUND_VIA82CXXX tristate "VIA 82C686 Audio Codec" - depends on SOUND_PRIME && PCI + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER help Say Y here to include support for the audio codec found on VIA 82Cxxx-based chips. Typically these are built into a motherboard. @@ -454,6 +571,18 @@ config SOUND_AD1889 Say M here if you have a sound card based on the Analog Devices AD1889 chip. +config SOUND_SGALAXY + tristate "Aztech Sound Galaxy (non-PnP) cards" + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER + help + This module initializes the older non Plug and Play sound galaxy + cards from Aztech. It supports the Waverider Pro 32 - 3D and the + Galaxy Washington 16. + + If you compile the driver into the kernel, you have to add + "sgalaxy=,,,," to the kernel command + line. + config SOUND_ADLIB tristate "Adlib Cards" depends on SOUND_OSS @@ -480,7 +609,7 @@ config SOUND_ACI_MIXER config SOUND_CS4232 tristate "Crystal CS4232 based (PnP) cards" - depends on SOUND_OSS + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER help Say Y here if you have a card based on the Crystal CS4232 chip set, which uses its own Plug and Play protocol. @@ -492,6 +621,42 @@ config SOUND_CS4232 See for more information on configuring this card. +config SOUND_SSCAPE + tristate "Ensoniq SoundScape support" + depends on SOUND_OSS + help + Answer Y if you have a sound card based on the Ensoniq SoundScape + chipset. Such cards are being manufactured at least by Ensoniq, Spea + and Reveal (Reveal makes also other cards). + + If you compile the driver into the kernel, you have to add + "sscape=,,,," to the kernel command + line. + +config SOUND_GUS + tristate "Gravis Ultrasound support" + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER + help + Say Y here for any type of Gravis Ultrasound card, including the GUS + or GUS MAX. See also for more + information on configuring this card with modules. + + If you compile the driver into the kernel, you have to add + "gus=,,," to the kernel command line. + +config SOUND_GUS16 + bool "16 bit sampling option of GUS (_NOT_ GUS MAX)" + depends on SOUND_GUS + help + Support for Gravis Ulstrasound (GUS) cards (other than the GUS), + sampling at 16-bit width. + +config SOUND_GUSMAX + bool "GUS MAX support" + depends on SOUND_GUS + help + Support for Gravis Ulstrasound MAX. + config SOUND_VMIDI tristate "Loopback MIDI device support" depends on SOUND_OSS @@ -572,7 +737,7 @@ config SOUND_MPU401 config SOUND_NM256 tristate "NM256AV/NM256ZX audio support" - depends on SOUND_OSS + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER help Say M here to include audio support for the NeoMagic 256AV/256ZX chipsets. These are the audio chipsets found in the Sony @@ -582,6 +747,35 @@ config SOUND_NM256 See for further information. +config SOUND_MAD16 + tristate "OPTi MAD16 and/or Mozart based cards" + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER + ---help--- + Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi + 82C928 or 82C929 or 82C931) audio interface chip. These chips are + quite common so it's possible that many no-name cards have one of + them. In addition the MAD16 chip is used in some cards made by known + manufacturers such as Turtle Beach (Tropez), Reveal (some models) + and Diamond (latest ones). Note however that the Tropez sound cards + have their own driver; if you have one of those, say N here and Y or + M to "Full support for Turtle Beach WaveFront", below. + + If you compile the driver into the kernel, you have to add + "mad16=,,,,," to the + kernel command line. + + See also and + for more information on setting + these cards up as modules. + +config MAD16_OLDCARD + bool "Support MIDI in older MAD16 based cards (requires SB)" + depends on SOUND_MAD16 + help + Answer Y (or M) if you have an older card based on the C928 or + Mozart chipset and you want to have MIDI support. If you enable this + option you also need to enable support for Sound Blaster. + config SOUND_PAS tristate "ProAudioSpectrum 16 support" depends on SOUND_OSS @@ -674,9 +868,53 @@ config SOUND_SB You can say M here to compile this driver as a module; the module is called sb. +config SOUND_AWE32_SYNTH + tristate "AWE32 synth" + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER + help + Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or + similar sound card. See , + and the Soundblaster-AWE + mini-HOWTO, available from + for more info. + +config SOUND_WAVEFRONT + tristate "Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards" + depends on SOUND_OSS && m && OBSOLETE_OSS_DRIVER + help + Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card + and read the files and + . + +config SOUND_MAUI + tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers" + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER + help + Say Y here if you have a Turtle Beach Wave Front, Maui, or Tropez + sound card. + + If you compile the driver into the kernel, you have to add + "maui=," to the kernel command line. + +config MAUI_HAVE_BOOT + bool "Have OSWF.MOT firmware file" + depends on SOUND_MAUI=y && !STANDALONE + help + Turtle Beach Maui and Tropez sound cards have a microcontroller + which needs to be initialized prior to use. OSWF.MOT is a file + distributed with the card's DOS/Windows drivers. Answer Y if you + have this file. + +config MAUI_BOOT_FILE + string "Full pathname of OSWF.MOT firmware file" + depends on MAUI_HAVE_BOOT + default "/etc/sound/oswf.mot" + help + Enter the full pathname of your OSWF.MOT file, starting from /. + config SOUND_YM3812 tristate "Yamaha FM synthesizer (YM3812/OPL-3) support" - depends on SOUND_OSS + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER ---help--- Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). Answering Y is usually a safe and recommended choice, however some @@ -690,6 +928,18 @@ config SOUND_YM3812 If unsure, say Y. +config SOUND_OPL3SA1 + tristate "Yamaha OPL3-SA1 audio controller" + depends on SOUND_OSS && OBSOLETE_OSS_DRIVER + help + Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is + usually built into motherboards. Read + for details. + + If you compile the driver into the kernel, you have to add + "opl3sa=,,,,," to the kernel + command line. + config SOUND_OPL3SA2 tristate "Yamaha OPL3-SA2 and SA3 based PnP cards" depends on SOUND_OSS @@ -704,6 +954,19 @@ config SOUND_OPL3SA2 "opl3sa2=,,,,," to the kernel command line. +config SOUND_YMFPCI + tristate "Yamaha YMF7xx PCI audio (native mode)" + depends on SOUND_OSS && PCI && OBSOLETE_OSS_DRIVER + help + Support for Yamaha cards including the YMF711, YMF715, YMF718, + YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital. + +config SOUND_YMFPCI_LEGACY + bool "Yamaha PCI legacy ports support" + depends on SOUND_YMFPCI + help + Support for YMF7xx PCI cards emulating an MP401. + config SOUND_UART6850 tristate "6850 UART support" depends on SOUND_OSS @@ -833,6 +1096,30 @@ config SOUND_KAHLUA tristate "XpressAudio Sound Blaster emulation" depends on SOUND_SB +config SOUND_ALI5455 + tristate "ALi5455 audio support" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + +config SOUND_FORTE + tristate "ForteMedia FM801 driver" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + help + Say Y or M if you want driver support for the ForteMedia FM801 PCI + audio controller (Abit AU10, Genius Sound Maker, HP Workstation + zx2000, and others). + +config SOUND_RME96XX + tristate "RME Hammerfall (RME96XX) support" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER + help + Say Y or M if you have a Hammerfall or Hammerfall light + multichannel card from RME. If you want to access advanced + features of the card, read . + +config SOUND_AD1980 + tristate "AD1980 front/back switch plugin" + depends on SOUND_PRIME && OBSOLETE_OSS_DRIVER + config SOUND_SH_DAC_AUDIO tristate "SuperH DAC audio support" depends on SOUND_PRIME && CPU_SH3 diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c index 972327c97..fd25aca25 100644 --- a/sound/oss/ac97_codec.c +++ b/sound/oss/ac97_codec.c @@ -55,7 +55,7 @@ #include #include #include -#include +#include #define CODEC_ID_BUFSZ 14 @@ -304,7 +304,7 @@ static const unsigned int ac97_oss_rm[] = { static LIST_HEAD(codecs); static LIST_HEAD(codec_drivers); -static DEFINE_MUTEX(codec_mutex); +static DECLARE_MUTEX(codec_sem); /* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows about that given mixer, and should be holding a spinlock for the card */ @@ -769,9 +769,9 @@ void ac97_release_codec(struct ac97_codec *codec) { /* Remove from the list first, we don't want to be "rediscovered" */ - mutex_lock(&codec_mutex); + down(&codec_sem); list_del(&codec->list); - mutex_unlock(&codec_mutex); + up(&codec_sem); /* * The driver needs to deal with internal * locking to avoid accidents here. @@ -889,7 +889,7 @@ int ac97_probe_codec(struct ac97_codec *codec) * callbacks. */ - mutex_lock(&codec_mutex); + down(&codec_sem); list_add(&codec->list, &codecs); list_for_each(l, &codec_drivers) { @@ -903,7 +903,7 @@ int ac97_probe_codec(struct ac97_codec *codec) } } - mutex_unlock(&codec_mutex); + up(&codec_sem); return 1; } @@ -1439,7 +1439,7 @@ int ac97_register_driver(struct ac97_driver *driver) struct list_head *l; struct ac97_codec *c; - mutex_lock(&codec_mutex); + down(&codec_sem); INIT_LIST_HEAD(&driver->list); list_add(&driver->list, &codec_drivers); @@ -1452,7 +1452,7 @@ int ac97_register_driver(struct ac97_driver *driver) continue; c->driver = driver; } - mutex_unlock(&codec_mutex); + up(&codec_sem); return 0; } @@ -1471,7 +1471,7 @@ void ac97_unregister_driver(struct ac97_driver *driver) struct list_head *l; struct ac97_codec *c; - mutex_lock(&codec_mutex); + down(&codec_sem); list_del_init(&driver->list); list_for_each(l, &codecs) @@ -1483,7 +1483,7 @@ void ac97_unregister_driver(struct ac97_driver *driver) } } - mutex_unlock(&codec_mutex); + up(&codec_sem); } EXPORT_SYMBOL_GPL(ac97_unregister_driver); @@ -1494,14 +1494,14 @@ static int swap_headphone(int remove_master) struct ac97_codec *c; if (remove_master) { - mutex_lock(&codec_mutex); + down(&codec_sem); list_for_each(l, &codecs) { c = list_entry(l, struct ac97_codec, list); if (supported_mixer(c, SOUND_MIXER_PHONEOUT)) c->supported_mixers &= ~SOUND_MASK_PHONEOUT; } - mutex_unlock(&codec_mutex); + up(&codec_sem); } else ac97_hw[SOUND_MIXER_PHONEOUT].offset = AC97_MASTER_VOL_STEREO; diff --git a/sound/oss/aci.c b/sound/oss/aci.c index 3bfac375d..3928c2802 100644 --- a/sound/oss/aci.c +++ b/sound/oss/aci.c @@ -56,8 +56,7 @@ #include #include #include -#include - +#include #include #include #include "sound_config.h" @@ -80,7 +79,7 @@ static int aci_micpreamp=3; /* microphone preamp-level that can't be * * checked with ACI versions prior to 0xb0 */ static int mixer_device; -static struct mutex aci_mutex; +static struct semaphore aci_sem; #ifdef MODULE static int reset; @@ -213,7 +212,7 @@ int aci_rw_cmd(int write1, int write2, int write3) int write[] = {write1, write2, write3}; int read = -EINTR, i; - if (mutex_lock_interruptible(&aci_mutex)) + if (down_interruptible(&aci_sem)) goto out; for (i=0; i<3; i++) { @@ -228,7 +227,7 @@ int aci_rw_cmd(int write1, int write2, int write3) } read = aci_rawread(); -out_up: mutex_unlock(&aci_mutex); +out_up: up(&aci_sem); out: return read; } @@ -604,7 +603,7 @@ static int __init attach_aci(void) char *boardname; int i, rc = -EBUSY; - mutex_init(&aci_mutex); + init_MUTEX(&aci_sem); outb(0xE3, 0xf8f); /* Write MAD16 password */ aci_port = (inb(0xf90) & 0x10) ? diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c index e04fa49b0..49796be95 100644 --- a/sound/oss/ad1848.c +++ b/sound/oss/ad1848.c @@ -2026,8 +2026,7 @@ int ad1848_init (char *name, struct resource *ports, int irq, int dma_playback, if (irq > 0) { devc->dev_no = my_dev; - if (request_irq(devc->irq, adintr, 0, devc->name, - (void *)(long)my_dev) < 0) + if (request_irq(devc->irq, adintr, 0, devc->name, (void *)my_dev) < 0) { printk(KERN_WARNING "ad1848: Unable to allocate IRQ\n"); /* Don't free it either then.. */ @@ -2176,7 +2175,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int if (!share_dma) { if (devc->irq > 0) /* There is no point in freeing irq, if it wasn't allocated */ - free_irq(devc->irq, (void *)(long)devc->dev_no); + free_irq(devc->irq, (void *)devc->dev_no); sound_free_dma(dma_playback); @@ -2205,7 +2204,7 @@ irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy) unsigned char c930_stat = 0; int cnt = 0; - dev = (long)dev_id; + dev = (int)dev_id; devc = (ad1848_info *) audio_devs[dev]->devc; interrupt_again: /* Jump back here if int status doesn't reset */ @@ -2901,8 +2900,7 @@ static struct pnp_dev *activate_dev(char *devname, char *resname, struct pnp_dev return(dev); } -static struct pnp_dev __init *ad1848_init_generic(struct pnp_card *bus, - struct address_info *hw_config, int slot) +static struct pnp_dev *ad1848_init_generic(struct pnp_card *bus, struct address_info *hw_config, int slot) { /* Configure Audio device */ diff --git a/sound/oss/ad1889.c b/sound/oss/ad1889.c index a4ca7569e..a0d73f343 100644 --- a/sound/oss/ad1889.c +++ b/sound/oss/ad1889.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -75,7 +74,7 @@ static inline void ad1889_set_wav_rate(ad1889_dev_t *dev, int rate) DBG("Setting WAV rate to %d\n", rate); dev->state[AD_WAV_STATE].dmabuf.rate = rate; - AD1889_WRITEW(dev, AD_DS_WAS, rate); + AD1889_WRITEW(dev, AD_DSWAS, rate); /* Cycle the DAC to enable the new rate */ ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0200); @@ -89,14 +88,14 @@ static inline void ad1889_set_wav_fmt(ad1889_dev_t *dev, int fmt) DBG("Setting WAV format to 0x%x\n", fmt); - tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); + tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); if (fmt & AFMT_S16_LE) { //tmp |= 0x0100; /* set WA16 */ tmp |= 0x0300; /* set WA16 stereo */ } else if (fmt & AFMT_U8) { tmp &= ~0x0100; /* clear WA16 */ } - AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); + AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); } static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt) @@ -105,13 +104,13 @@ static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt) DBG("Setting ADC format to 0x%x\n", fmt); - tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC); + tmp = AD1889_READW(ad1889_dev, AD_DSRAMC); if (fmt & AFMT_S16_LE) { tmp |= 0x0100; /* set WA16 */ } else if (fmt & AFMT_U8) { tmp &= ~0x0100; /* clear WA16 */ } - AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp); + AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp); } static void ad1889_start_wav(ad1889_state_t *state) @@ -145,21 +144,21 @@ static void ad1889_start_wav(ad1889_state_t *state) dmabuf->rd_ptr, dmabuf->dma_len); /* load up the current register set */ - AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCC, cnt); - AD1889_WRITEL(ad1889_dev, AD_DMA_WAVICC, cnt); - AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCA, dmabuf->dma_handle); + AD1889_WRITEL(ad1889_dev, AD_DMAWAVCC, cnt); + AD1889_WRITEL(ad1889_dev, AD_DMAWAVICC, cnt); + AD1889_WRITEL(ad1889_dev, AD_DMAWAVCA, dmabuf->dma_handle); /* TODO: for now we load the base registers with the same thing */ - AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBC, cnt); - AD1889_WRITEL(ad1889_dev, AD_DMA_WAVIBC, cnt); - AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBA, dmabuf->dma_handle); + AD1889_WRITEL(ad1889_dev, AD_DMAWAVBC, cnt); + AD1889_WRITEL(ad1889_dev, AD_DMAWAVIBC, cnt); + AD1889_WRITEL(ad1889_dev, AD_DMAWAVBA, dmabuf->dma_handle); /* and we're off to the races... */ - AD1889_WRITEL(ad1889_dev, AD_DMA_CHSS, 0x8); - tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); + AD1889_WRITEL(ad1889_dev, AD_DMACHSS, 0x8); + tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); tmp |= 0x0400; /* set WAEN */ - AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); - (void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */ + AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); + (void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */ dmabuf->enable |= DAC_RUNNING; @@ -179,10 +178,10 @@ static void ad1889_stop_wav(ad1889_state_t *state) u16 tmp; unsigned long cnt = dmabuf->dma_len; - tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); + tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); tmp &= ~0x0400; /* clear WAEN */ - AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); - (void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */ + AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); + (void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */ pci_unmap_single(ad1889_dev->pci, dmabuf->dma_handle, cnt, PCI_DMA_TODEVICE); @@ -211,7 +210,7 @@ static void ad1889_startstop_adc(ad1889_state_t *state, int start) spin_lock_irqsave(&state->card->lock, flags); - tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC); + tmp = AD1889_READW(ad1889_dev, AD_DSRAMC); if (start) { state->dmabuf.enable |= ADC_RUNNING; tmp |= 0x0004; /* set ADEN */ @@ -219,7 +218,7 @@ static void ad1889_startstop_adc(ad1889_state_t *state, int start) state->dmabuf.enable &= ~ADC_RUNNING; tmp &= ~0x0004; /* clear ADEN */ } - AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp); + AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp); spin_unlock_irqrestore(&state->card->lock, flags); } @@ -239,7 +238,7 @@ static ad1889_dev_t *ad1889_alloc_dev(struct pci_dev *pci) for (i = 0; i < AD_MAX_STATES; i++) { dev->state[i].card = dev; - mutex_init(&dev->state[i].mutex); + init_MUTEX(&dev->state[i].sem); init_waitqueue_head(&dev->state[i].dmabuf.wait); } @@ -301,53 +300,53 @@ static int ad1889_read_proc (char *page, char **start, off_t off, int len, i; ad1889_dev_t *dev = data; ad1889_reg_t regs[] = { - { "WSMC", AD_DS_WSMC, 16 }, - { "RAMC", AD_DS_RAMC, 16 }, - { "WADA", AD_DS_WADA, 16 }, - { "SYDA", AD_DS_SYDA, 16 }, - { "WAS", AD_DS_WAS, 16 }, - { "RES", AD_DS_RES, 16 }, - { "CCS", AD_DS_CCS, 16 }, - { "ADCBA", AD_DMA_ADCBA, 32 }, - { "ADCCA", AD_DMA_ADCCA, 32 }, - { "ADCBC", AD_DMA_ADCBC, 32 }, - { "ADCCC", AD_DMA_ADCCC, 32 }, - { "ADCIBC", AD_DMA_ADCIBC, 32 }, - { "ADCICC", AD_DMA_ADCICC, 32 }, - { "ADCCTRL", AD_DMA_ADCCTRL, 16 }, - { "WAVBA", AD_DMA_WAVBA, 32 }, - { "WAVCA", AD_DMA_WAVCA, 32 }, - { "WAVBC", AD_DMA_WAVBC, 32 }, - { "WAVCC", AD_DMA_WAVCC, 32 }, - { "WAVIBC", AD_DMA_WAVIBC, 32 }, - { "WAVICC", AD_DMA_WAVICC, 32 }, - { "WAVCTRL", AD_DMA_WAVCTRL, 16 }, - { "DISR", AD_DMA_DISR, 32 }, - { "CHSS", AD_DMA_CHSS, 32 }, - { "IPC", AD_GPIO_IPC, 16 }, - { "OP", AD_GPIO_OP, 16 }, - { "IP", AD_GPIO_IP, 16 }, - { "ACIC", AD_AC97_ACIC, 16 }, - { "AC97_RESET", AD_AC97_BASE + AC97_RESET, 16 }, - { "AC97_MASTER_VOL_STEREO", AD_AC97_BASE + AC97_MASTER_VOL_STEREO, 16 }, - { "AC97_HEADPHONE_VOL", AD_AC97_BASE + AC97_HEADPHONE_VOL, 16 }, - { "AC97_MASTER_VOL_MONO", AD_AC97_BASE + AC97_MASTER_VOL_MONO, 16 }, - { "AC97_MASTER_TONE", AD_AC97_BASE + AC97_MASTER_TONE, 16 }, - { "AC97_PCBEEP_VOL", AD_AC97_BASE + AC97_PCBEEP_VOL, 16 }, - { "AC97_PHONE_VOL", AD_AC97_BASE + AC97_PHONE_VOL, 16 }, - { "AC97_MIC_VOL", AD_AC97_BASE + AC97_MIC_VOL, 16 }, - { "AC97_LINEIN_VOL", AD_AC97_BASE + AC97_LINEIN_VOL, 16 }, - { "AC97_CD_VOL", AD_AC97_BASE + AC97_CD_VOL, 16 }, - { "AC97_VIDEO_VOL", AD_AC97_BASE + AC97_VIDEO_VOL, 16 }, - { "AC97_AUX_VOL", AD_AC97_BASE + AC97_AUX_VOL, 16 }, - { "AC97_PCMOUT_VOL", AD_AC97_BASE + AC97_PCMOUT_VOL, 16 }, - { "AC97_RECORD_SELECT", AD_AC97_BASE + AC97_RECORD_SELECT, 16 }, - { "AC97_RECORD_GAIN", AD_AC97_BASE + AC97_RECORD_GAIN, 16 }, - { "AC97_RECORD_GAIN_MIC", AD_AC97_BASE + AC97_RECORD_GAIN_MIC, 16 }, - { "AC97_GENERAL_PURPOSE", AD_AC97_BASE + AC97_GENERAL_PURPOSE, 16 }, - { "AC97_3D_CONTROL", AD_AC97_BASE + AC97_3D_CONTROL, 16 }, - { "AC97_MODEM_RATE", AD_AC97_BASE + AC97_MODEM_RATE, 16 }, - { "AC97_POWER_CONTROL", AD_AC97_BASE + AC97_POWER_CONTROL, 16 }, + { "WSMC", AD_DSWSMC, 16 }, + { "RAMC", AD_DSRAMC, 16 }, + { "WADA", AD_DSWADA, 16 }, + { "SYDA", AD_DSSYDA, 16 }, + { "WAS", AD_DSWAS, 16 }, + { "RES", AD_DSRES, 16 }, + { "CCS", AD_DSCCS, 16 }, + { "ADCBA", AD_DMAADCBA, 32 }, + { "ADCCA", AD_DMAADCCA, 32 }, + { "ADCBC", AD_DMAADCBC, 32 }, + { "ADCCC", AD_DMAADCCC, 32 }, + { "ADCIBC", AD_DMAADCIBC, 32 }, + { "ADCICC", AD_DMAADCICC, 32 }, + { "ADCCTRL", AD_DMAADCCTRL, 16 }, + { "WAVBA", AD_DMAWAVBA, 32 }, + { "WAVCA", AD_DMAWAVCA, 32 }, + { "WAVBC", AD_DMAWAVBC, 32 }, + { "WAVCC", AD_DMAWAVCC, 32 }, + { "WAVIBC", AD_DMAWAVIBC, 32 }, + { "WAVICC", AD_DMAWAVICC, 32 }, + { "WAVCTRL", AD_DMAWAVCTRL, 16 }, + { "DISR", AD_DMADISR, 32 }, + { "CHSS", AD_DMACHSS, 32 }, + { "IPC", AD_GPIOIPC, 16 }, + { "OP", AD_GPIOOP, 16 }, + { "IP", AD_GPIOIP, 16 }, + { "ACIC", AD_ACIC, 16 }, + { "AC97_RESET", 0x100 + AC97_RESET, 16 }, + { "AC97_MASTER_VOL_STEREO", 0x100 + AC97_MASTER_VOL_STEREO, 16 }, + { "AC97_HEADPHONE_VOL", 0x100 + AC97_HEADPHONE_VOL, 16 }, + { "AC97_MASTER_VOL_MONO", 0x100 + AC97_MASTER_VOL_MONO, 16 }, + { "AC97_MASTER_TONE", 0x100 + AC97_MASTER_TONE, 16 }, + { "AC97_PCBEEP_VOL", 0x100 + AC97_PCBEEP_VOL, 16 }, + { "AC97_PHONE_VOL", 0x100 + AC97_PHONE_VOL, 16 }, + { "AC97_MIC_VOL", 0x100 + AC97_MIC_VOL, 16 }, + { "AC97_LINEIN_VOL", 0x100 + AC97_LINEIN_VOL, 16 }, + { "AC97_CD_VOL", 0x100 + AC97_CD_VOL, 16 }, + { "AC97_VIDEO_VOL", 0x100 + AC97_VIDEO_VOL, 16 }, + { "AC97_AUX_VOL", 0x100 + AC97_AUX_VOL, 16 }, + { "AC97_PCMOUT_VOL", 0x100 + AC97_PCMOUT_VOL, 16 }, + { "AC97_RECORD_SELECT", 0x100 + AC97_RECORD_SELECT, 16 }, + { "AC97_RECORD_GAIN", 0x100 + AC97_RECORD_GAIN, 16 }, + { "AC97_RECORD_GAIN_MIC", 0x100 + AC97_RECORD_GAIN_MIC, 16 }, + { "AC97_GENERAL_PURPOSE", 0x100 + AC97_GENERAL_PURPOSE, 16 }, + { "AC97_3D_CONTROL", 0x100 + AC97_3D_CONTROL, 16 }, + { "AC97_MODEM_RATE", 0x100 + AC97_MODEM_RATE, 16 }, + { "AC97_POWER_CONTROL", 0x100 + AC97_POWER_CONTROL, 16 }, { NULL } }; @@ -400,9 +399,9 @@ static inline unsigned long ad1889_get_dma_addr(ad1889_state_t *state) } if (dmabuf->enable & DAC_RUNNING) - offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_WAVBA)); + offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAWAVBA)); else - offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_ADCBA)); + offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAADCBA)); return (unsigned long)bus_to_virt((unsigned long)offset) - (unsigned long)dmabuf->rawbuf; } @@ -462,7 +461,7 @@ static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t ssize_t ret = 0; DECLARE_WAITQUEUE(wait, current); - mutex_lock(&state->mutex); + down(&state->sem); #if 0 if (dmabuf->mapped) { ret = -ENXIO; @@ -547,7 +546,7 @@ static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t err2: remove_wait_queue(&state->dmabuf.wait, &wait); err1: - mutex_unlock(&state->mutex); + up(&state->sem); return ret; } @@ -639,9 +638,9 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd if (val > 5400 && val < 48000) { if (file->f_mode & FMODE_WRITE) - AD1889_WRITEW(ad1889_dev, AD_DS_WAS, val); + AD1889_WRITEW(ad1889_dev, AD_DSWAS, val); if (file->f_mode & FMODE_READ) - AD1889_WRITEW(ad1889_dev, AD_DS_RES, val); + AD1889_WRITEW(ad1889_dev, AD_DSRES, val); } return 0; @@ -649,22 +648,22 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd if (get_user(val, p)) return -EFAULT; if (file->f_mode & FMODE_READ) { - val = AD1889_READW(ad1889_dev, AD_DS_WSMC); + val = AD1889_READW(ad1889_dev, AD_DSWSMC); if (val) { val |= 0x0200; /* set WAST */ } else { val &= ~0x0200; /* clear WAST */ } - AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, val); + AD1889_WRITEW(ad1889_dev, AD_DSWSMC, val); } if (file->f_mode & FMODE_WRITE) { - val = AD1889_READW(ad1889_dev, AD_DS_RAMC); + val = AD1889_READW(ad1889_dev, AD_DSRAMC); if (val) { val |= 0x0002; /* set ADST */ } else { val &= ~0x0002; /* clear ADST */ } - AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, val); + AD1889_WRITEW(ad1889_dev, AD_DSRAMC, val); } return 0; @@ -739,7 +738,7 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; case SOUND_PCM_READ_RATE: - return put_user(AD1889_READW(ad1889_dev, AD_DS_WAS), p); + return put_user(AD1889_READW(ad1889_dev, AD_DSWAS), p); case SOUND_PCM_READ_CHANNELS: case SOUND_PCM_READ_BITS: @@ -769,7 +768,7 @@ static int ad1889_open(struct inode *inode, struct file *file) ad1889_set_wav_rate(ad1889_dev, 48000); ad1889_set_wav_fmt(ad1889_dev, AFMT_S16_LE); - AD1889_WRITEW(ad1889_dev, AD_DS_WADA, 0x0404); /* attenuation */ + AD1889_WRITEW(ad1889_dev, AD_DSWADA, 0x0404); /* attenuation */ return nonseekable_open(inode, file); } @@ -826,15 +825,15 @@ static void ad1889_codec_write(struct ac97_codec *ac97, u8 reg, u16 val) { ad1889_dev_t *dev = ac97->private_data; - //DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + AD_AC97_BASE + reg); - AD1889_WRITEW(dev, AD_AC97_BASE + reg, val); + //DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + 0x100 + reg); + AD1889_WRITEW(dev, 0x100 + reg, val); } static u16 ad1889_codec_read(struct ac97_codec *ac97, u8 reg) { ad1889_dev_t *dev = ac97->private_data; - //DBG("Reading from 0x%lx\n", dev->regbase + AD_AC97_BASE + reg); - return AD1889_READW(dev, AD_AC97_BASE + reg); + //DBG("Reading from 0x%lx\n", dev->regbase + 0x100 + reg); + return AD1889_READW(dev, 0x100 + reg); } static int ad1889_ac97_init(ad1889_dev_t *dev, int id) @@ -883,24 +882,24 @@ static int ad1889_aclink_reset(struct pci_dev * pcidev) int retry = 200; ad1889_dev_t *dev = pci_get_drvdata(pcidev); - AD1889_WRITEW(dev, AD_DS_CCS, 0x8000); /* turn on clock */ - AD1889_READW(dev, AD_DS_CCS); + AD1889_WRITEW(dev, AD_DSCCS, 0x8000); /* turn on clock */ + AD1889_READW(dev, AD_DSCCS); WAIT_10MS(); - stat = AD1889_READW(dev, AD_AC97_ACIC); + stat = AD1889_READW(dev, AD_ACIC); stat |= 0x0002; /* Reset Disable */ - AD1889_WRITEW(dev, AD_AC97_ACIC, stat); - (void) AD1889_READW(dev, AD_AC97_ACIC); /* flush posted write */ + AD1889_WRITEW(dev, AD_ACIC, stat); + (void) AD1889_READW(dev, AD_ACIC); /* flush posted write */ udelay(10); - stat = AD1889_READW(dev, AD_AC97_ACIC); + stat = AD1889_READW(dev, AD_ACIC); stat |= 0x0001; /* Interface Enable */ - AD1889_WRITEW(dev, AD_AC97_ACIC, stat); + AD1889_WRITEW(dev, AD_ACIC, stat); do { - if (AD1889_READW(dev, AD_AC97_ACIC) & 0x8000) /* Ready */ + if (AD1889_READW(dev, AD_ACIC) & 0x8000) /* Ready */ break; WAIT_10MS(); retry--; @@ -908,16 +907,16 @@ static int ad1889_aclink_reset(struct pci_dev * pcidev) if (!retry) { printk(KERN_ERR "ad1889_aclink_reset: codec is not ready [0x%x]\n", - AD1889_READW(dev, AD_AC97_ACIC)); + AD1889_READW(dev, AD_ACIC)); return -EBUSY; } /* TODO reset AC97 codec */ /* TODO set wave/adc pci ctrl status */ - stat = AD1889_READW(dev, AD_AC97_ACIC); + stat = AD1889_READW(dev, AD_ACIC); stat |= 0x0004; /* Audio Stream Output Enable */ - AD1889_WRITEW(dev, AD_AC97_ACIC, stat); + AD1889_WRITEW(dev, AD_ACIC, stat); return 0; } @@ -935,10 +934,10 @@ static irqreturn_t ad1889_interrupt(int irq, void *dev_id, struct pt_regs *regs) u32 stat; ad1889_dev_t *dev = (ad1889_dev_t *)dev_id; - stat = AD1889_READL(dev, AD_DMA_DISR); + stat = AD1889_READL(dev, AD_DMADISR); /* clear ISR */ - AD1889_WRITEL(dev, AD_DMA_DISR, stat); + AD1889_WRITEL(dev, AD_DMADISR, stat); if (stat & 0x8) { /* WAVI */ DBG("WAV interrupt\n"); @@ -964,15 +963,15 @@ static void ad1889_initcfg(ad1889_dev_t *dev) u32 tmp32; /* make sure the interrupt bits are setup the way we want */ - tmp32 = AD1889_READL(dev, AD_DMA_WAVCTRL); + tmp32 = AD1889_READL(dev, AD_DMAWAVCTRL); tmp32 &= ~0xff; /* flat dma, no sg, mask out the intr bits */ tmp32 |= 0x6; /* intr on count, loop */ - AD1889_WRITEL(dev, AD_DMA_WAVCTRL, tmp32); + AD1889_WRITEL(dev, AD_DMAWAVCTRL, tmp32); /* unmute... */ - tmp16 = AD1889_READW(dev, AD_DS_WADA); + tmp16 = AD1889_READW(dev, AD_DSWADA); tmp16 &= ~0x8080; - AD1889_WRITEW(dev, AD_DS_WADA, tmp16); + AD1889_WRITEW(dev, AD_DSWADA, tmp16); } static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) @@ -1005,7 +1004,7 @@ static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_devic goto out1; } - dev->regbase = ioremap_nocache(bar, AD_DS_IOMEMSIZE); + dev->regbase = ioremap_nocache(bar, AD_DSIOMEMSIZE); if (!dev->regbase) { printk(KERN_ERR DEVNAME ": unable to remap iomem\n"); goto out2; diff --git a/sound/oss/ad1889.h b/sound/oss/ad1889.h index 099137659..e04affce1 100644 --- a/sound/oss/ad1889.h +++ b/sound/oss/ad1889.h @@ -1,58 +1,57 @@ #ifndef _AD1889_H_ #define _AD1889_H_ -#define AD_DS_WSMC 0x00 /* DMA input wave/syn mixer control */ -#define AD_DS_RAMC 0x02 /* DMA output resamp/ADC mixer control */ -#define AD_DS_WADA 0x04 /* DMA input wave attenuation */ -#define AD_DS_SYDA 0x06 /* DMA input syn attentuation */ -#define AD_DS_WAS 0x08 /* wave input sample rate */ -#define AD_DS_RES 0x0a /* resampler output sample rate */ -#define AD_DS_CCS 0x0c /* chip control/status */ - -#define AD_DMA_RESBA 0x40 /* RES base addr */ -#define AD_DMA_RESCA 0x44 /* RES current addr */ -#define AD_DMA_RESBC 0x48 /* RES base cnt */ -#define AD_DMA_RESCC 0x4c /* RES current count */ -#define AD_DMA_ADCBA 0x50 /* ADC */ -#define AD_DMA_ADCCA 0x54 -#define AD_DMA_ADCBC 0x58 -#define AD_DMA_ADCCC 0x5c -#define AD_DMA_SYNBA 0x60 /* SYN */ -#define AD_DMA_SYNCA 0x64 -#define AD_DMA_SYNBC 0x68 -#define AD_DMA_SYNCC 0x6c -#define AD_DMA_WAVBA 0x70 /* WAV */ -#define AD_DMA_WAVCA 0x74 -#define AD_DMA_WAVBC 0x78 -#define AD_DMA_WAVCC 0x7c -#define AD_DMA_RESICC 0x80 /* RES interrupt current count */ -#define AD_DMA_RESIBC 0x84 /* RES interrupt base count */ -#define AD_DMA_ADCICC 0x88 /* ADC interrupt current count */ -#define AD_DMA_ADCIBC 0x8c /* ADC interrupt base count */ -#define AD_DMA_SYNICC 0x90 /* SYN interrupt current count */ -#define AD_DMA_SYNIBC 0x94 /* SYN interrupt base count */ -#define AD_DMA_WAVICC 0x98 /* WAV interrupt current count */ -#define AD_DMA_WAVIBC 0x9c /* WAV interrupt base count */ -#define AD_DMA_RESCTRL 0xa0 /* RES PCI control/status */ -#define AD_DMA_ADCCTRL 0xa8 /* ADC PCI control/status */ -#define AD_DMA_SYNCTRL 0xb0 /* SYN PCI control/status */ -#define AD_DMA_WAVCTRL 0xb8 /* WAV PCI control/status */ -#define AD_DMA_DISR 0xc0 /* PCI DMA intr status */ -#define AD_DMA_CHSS 0xc4 /* PCI DMA channel stop status */ - -#define AD_GPIO_IPC 0xc8 /* IO port ctrl */ -#define AD_GPIO_OP 0xca /* IO output status */ -#define AD_GPIO_IP 0xcc /* IO input status */ +#define AD_DSWSMC 0x00 /* DMA input wave/syn mixer control */ +#define AD_DSRAMC 0x02 /* DMA output resamp/ADC mixer control */ +#define AD_DSWADA 0x04 /* DMA input wave attenuation */ +#define AD_DSSYDA 0x06 /* DMA input syn attentuation */ +#define AD_DSWAS 0x08 /* wave input sample rate */ +#define AD_DSRES 0x0a /* resampler output sample rate */ +#define AD_DSCCS 0x0c /* chip control/status */ + +#define AD_DMARESBA 0x40 /* RES base addr */ +#define AD_DMARESCA 0x44 /* RES current addr */ +#define AD_DMARESBC 0x48 /* RES base cnt */ +#define AD_DMARESCC 0x4c /* RES current count */ +#define AD_DMAADCBA 0x50 /* ADC */ +#define AD_DMAADCCA 0x54 +#define AD_DMAADCBC 0x58 +#define AD_DMAADCCC 0x5c +#define AD_DMASYNBA 0x60 /* SYN */ +#define AD_DMASYNCA 0x64 +#define AD_DMASYNBC 0x68 +#define AD_DMASYNCC 0x6c +#define AD_DMAWAVBA 0x70 /* WAV */ +#define AD_DMAWAVCA 0x74 +#define AD_DMAWAVBC 0x78 +#define AD_DMAWAVCC 0x7c +#define AD_DMARESICC 0x80 /* RES interrupt current count */ +#define AD_DMARESIBC 0x84 /* RES interrupt base count */ +#define AD_DMAADCICC 0x88 /* ADC interrupt current count */ +#define AD_DMAADCIBC 0x8c /* ADC interrupt base count */ +#define AD_DMASYNICC 0x90 /* SYN interrupt current count */ +#define AD_DMASYNIBC 0x94 /* SYN interrupt base count */ +#define AD_DMAWAVICC 0x98 /* WAV interrupt current count */ +#define AD_DMAWAVIBC 0x9c /* WAV interrupt base count */ +#define AD_DMARESCTRL 0xa0 /* RES PCI control/status */ +#define AD_DMAADCCTRL 0xa8 /* ADC PCI control/status */ +#define AD_DMASYNCTRL 0xb0 /* SYN PCI control/status */ +#define AD_DMAWAVCTRL 0xb8 /* WAV PCI control/status */ +#define AD_DMADISR 0xc0 /* PCI DMA intr status */ +#define AD_DMACHSS 0xc4 /* PCI DMA channel stop status */ + +#define AD_GPIOIPC 0xc8 /* IO port ctrl */ +#define AD_GPIOOP 0xca /* IO output status */ +#define AD_GPIOIP 0xcc /* IO input status */ /* AC97 registers, 0x100 - 0x17f; see ac97.h */ -#define AD_AC97_BASE 0x100 /* ac97 base register */ -#define AD_AC97_ACIC 0x180 /* AC Link interface ctrl */ +#define AD_ACIC 0x180 /* AC Link interface ctrl */ /* OPL3; BAR1 */ -#define AD_OPL_M0AS 0x00 /* Music0 address/status */ -#define AD_OPL_M0DATA 0x01 /* Music0 data */ -#define AD_OPL_M1A 0x02 /* Music1 address */ -#define AD_OPL_M1DATA 0x03 /* Music1 data */ +#define AD_OPLM0AS 0x00 /* Music0 address/status */ +#define AD_OPLM0DATA 0x01 /* Music0 data */ +#define AD_OPLM1A 0x02 /* Music1 address */ +#define AD_OPLM1DATA 0x03 /* Music1 data */ /* 0x04-0x0f reserved */ /* MIDI; BAR2 */ @@ -60,9 +59,9 @@ #define AD_MISC 0x01 /* MIDI status/cmd */ /* 0x02-0xff reserved */ -#define AD_DS_IOMEMSIZE 512 -#define AD_OPL_MEMSIZE 16 -#define AD_MIDI_MEMSIZE 16 +#define AD_DSIOMEMSIZE 512 +#define AD_OPLMEMSIZE 16 +#define AD_MIDIMEMSIZE 16 #define AD_WAV_STATE 0 #define AD_ADC_STATE 1 @@ -101,7 +100,7 @@ typedef struct ad1889_state { unsigned int subdivision; } dmabuf; - struct mutex mutex; + struct semaphore sem; } ad1889_state_t; typedef struct ad1889_dev { diff --git a/sound/oss/ali5455.c b/sound/oss/ali5455.c index 62bb936b1..9c9e6c041 100644 --- a/sound/oss/ali5455.c +++ b/sound/oss/ali5455.c @@ -64,8 +64,6 @@ #include #include #include -#include - #include #ifndef PCI_DEVICE_ID_ALI_5455 @@ -236,7 +234,7 @@ struct ali_state { struct ali_card *card; /* Card info */ /* single open lock mechanism, only used for recording */ - struct mutex open_mutex; + struct semaphore open_sem; wait_queue_head_t open_wait; /* file mode */ @@ -2809,7 +2807,7 @@ found_virt: state->card = card; state->magic = ALI5455_STATE_MAGIC; init_waitqueue_head(&dmabuf->wait); - mutex_init(&state->open_mutex); + init_MUTEX(&state->open_sem); file->private_data = state; dmabuf->trigger = 0; /* allocate hardware channels */ @@ -3361,7 +3359,7 @@ static void __devinit ali_configure_clocking(void) state->card = card; state->magic = ALI5455_STATE_MAGIC; init_waitqueue_head(&dmabuf->wait); - mutex_init(&state->open_mutex); + init_MUTEX(&state->open_sem); dmabuf->fmt = ALI5455_FMT_STEREO | ALI5455_FMT_16BIT; dmabuf->trigger = PCM_ENABLE_OUTPUT; ali_set_dac_rate(state, 48000); diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c index eacb0aef2..c407de86c 100644 --- a/sound/oss/au1000.c +++ b/sound/oss/au1000.c @@ -68,8 +68,6 @@ #include #include #include -#include - #include #include #include @@ -100,7 +98,7 @@ /* Boot options */ static int vra = 0; // 0 = no VRA, 1 = use VRA if codec supports it -module_param(vra, bool, 0); +MODULE_PARM(vra, "i"); MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it"); @@ -122,8 +120,8 @@ struct au1000_state { int no_vra; // do not use VRA spinlock_t lock; - struct mutex open_mutex; - struct mutex sem; + struct semaphore open_sem; + struct semaphore sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -1108,7 +1106,7 @@ static ssize_t au1000_read(struct file *file, char *buffer, count *= db->cnt_factor; - mutex_lock(&s->sem); + down(&s->sem); add_wait_queue(&db->wait, &wait); while (count > 0) { @@ -1127,14 +1125,14 @@ static ssize_t au1000_read(struct file *file, char *buffer, ret = -EAGAIN; goto out; } - mutex_unlock(&s->sem); + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out2; } - mutex_lock(&s->sem); + down(&s->sem); } } while (avail <= 0); @@ -1161,7 +1159,7 @@ static ssize_t au1000_read(struct file *file, char *buffer, } // while (count > 0) out: - mutex_unlock(&s->sem); + up(&s->sem); out2: remove_wait_queue(&db->wait, &wait); set_current_state(TASK_RUNNING); @@ -1189,7 +1187,7 @@ static ssize_t au1000_write(struct file *file, const char *buffer, count *= db->cnt_factor; - mutex_lock(&s->sem); + down(&s->sem); add_wait_queue(&db->wait, &wait); while (count > 0) { @@ -1206,14 +1204,14 @@ static ssize_t au1000_write(struct file *file, const char *buffer, ret = -EAGAIN; goto out; } - mutex_unlock(&s->sem); + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out2; } - mutex_lock(&s->sem); + down(&s->sem); } } while (avail <= 0); @@ -1242,7 +1240,7 @@ static ssize_t au1000_write(struct file *file, const char *buffer, } // while (count > 0) out: - mutex_unlock(&s->sem); + up(&s->sem); out2: remove_wait_queue(&db->wait, &wait); set_current_state(TASK_RUNNING); @@ -1300,7 +1298,7 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma) dbg("%s", __FUNCTION__); lock_kernel(); - mutex_lock(&s->sem); + down(&s->sem); if (vma->vm_flags & VM_WRITE) db = &s->dma_dac; else if (vma->vm_flags & VM_READ) @@ -1326,7 +1324,7 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags &= ~VM_IO; db->mapped = 1; out: - mutex_unlock(&s->sem); + up(&s->sem); unlock_kernel(); return ret; } @@ -1831,21 +1829,21 @@ static int au1000_open(struct inode *inode, struct file *file) file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } stop_dac(s); @@ -1881,8 +1879,8 @@ static int au1000_open(struct inode *inode, struct file *file) } s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); - mutex_init(&s->sem); + up(&s->open_sem); + init_MUTEX(&s->sem); return nonseekable_open(inode, file); } @@ -1898,7 +1896,7 @@ static int au1000_release(struct inode *inode, struct file *file) lock_kernel(); } - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); dealloc_dmabuf(s, &s->dma_dac); @@ -1908,7 +1906,7 @@ static int au1000_release(struct inode *inode, struct file *file) dealloc_dmabuf(s, &s->dma_adc); } s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE)); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -1998,7 +1996,7 @@ static int __devinit au1000_probe(void) init_waitqueue_head(&s->dma_adc.wait); init_waitqueue_head(&s->dma_dac.wait); init_waitqueue_head(&s->open_wait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->codec.private_data = s; s->codec.id = 0; diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index c1168fae6..bdee0502f 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -52,8 +52,6 @@ #include #include #include -#include - #include #include #include @@ -79,7 +77,7 @@ * 0 = no VRA, 1 = use VRA if codec supports it */ static int vra = 1; -module_param(vra, bool, 0); +MODULE_PARM(vra, "i"); MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it"); static struct au1550_state { @@ -92,8 +90,8 @@ static struct au1550_state { int no_vra; /* do not use VRA */ spinlock_t lock; - struct mutex open_mutex; - struct mutex sem; + struct semaphore open_sem; + struct semaphore sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -1046,7 +1044,7 @@ au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos) count *= db->cnt_factor; - mutex_lock(&s->sem); + down(&s->sem); add_wait_queue(&db->wait, &wait); while (count > 0) { @@ -1066,14 +1064,14 @@ au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos) ret = -EAGAIN; goto out; } - mutex_unlock(&s->sem); + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out2; } - mutex_lock(&s->sem); + down(&s->sem); } } while (avail <= 0); @@ -1101,7 +1099,7 @@ au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos) } /* while (count > 0) */ out: - mutex_unlock(&s->sem); + up(&s->sem); out2: remove_wait_queue(&db->wait, &wait); set_current_state(TASK_RUNNING); @@ -1127,7 +1125,7 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) count *= db->cnt_factor; - mutex_lock(&s->sem); + down(&s->sem); add_wait_queue(&db->wait, &wait); while (count > 0) { @@ -1145,14 +1143,14 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) ret = -EAGAIN; goto out; } - mutex_unlock(&s->sem); + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out2; } - mutex_lock(&s->sem); + down(&s->sem); } } while (avail <= 0); @@ -1198,7 +1196,7 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) } /* while (count > 0) */ out: - mutex_unlock(&s->sem); + up(&s->sem); out2: remove_wait_queue(&db->wait, &wait); set_current_state(TASK_RUNNING); @@ -1255,7 +1253,7 @@ au1550_mmap(struct file *file, struct vm_area_struct *vma) int ret = 0; lock_kernel(); - mutex_lock(&s->sem); + down(&s->sem); if (vma->vm_flags & VM_WRITE) db = &s->dma_dac; else if (vma->vm_flags & VM_READ) @@ -1281,7 +1279,7 @@ au1550_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags &= ~VM_IO; db->mapped = 1; out: - mutex_unlock(&s->sem); + up(&s->sem); unlock_kernel(); return ret; } @@ -1792,21 +1790,21 @@ au1550_open(struct inode *inode, struct file *file) file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } stop_dac(s); @@ -1842,8 +1840,8 @@ au1550_open(struct inode *inode, struct file *file) } s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); - mutex_init(&s->sem); + up(&s->open_sem); + init_MUTEX(&s->sem); return 0; } @@ -1860,7 +1858,7 @@ au1550_release(struct inode *inode, struct file *file) lock_kernel(); } - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); kfree(s->dma_dac.rawbuf); @@ -1872,7 +1870,7 @@ au1550_release(struct inode *inode, struct file *file) s->dma_adc.rawbuf = NULL; } s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE)); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -1904,7 +1902,7 @@ au1550_probe(void) init_waitqueue_head(&s->dma_adc.wait); init_waitqueue_head(&s->dma_dac.wait); init_waitqueue_head(&s->open_wait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->codec = ac97_alloc_codec(); diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c index d1a0eb294..b3ea719d3 100644 --- a/sound/oss/awe_wave.c +++ b/sound/oss/awe_wave.c @@ -2944,7 +2944,7 @@ alloc_new_info(void) { awe_voice_list *newlist; - newlist = kmalloc(sizeof(*newlist), GFP_KERNEL); + newlist = (awe_voice_list *)kmalloc(sizeof(*newlist), GFP_KERNEL); if (newlist == NULL) { printk(KERN_ERR "AWE32: can't alloc info table\n"); return NULL; @@ -3547,10 +3547,8 @@ awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag) smp->checksum_flag = 0; smp->checksum = 0; - if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0) { - kfree(vrec); + if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0) return rc; - } sf->mem_ptr += rc; add_sf_sample(sf, smprec); diff --git a/sound/oss/btaudio.c b/sound/oss/btaudio.c index bfe3b534e..4007a5680 100644 --- a/sound/oss/btaudio.c +++ b/sound/oss/btaudio.c @@ -32,8 +32,6 @@ #include #include #include -#include - #include #include @@ -110,7 +108,7 @@ struct btaudio { /* locking */ int users; - struct mutex lock; + struct semaphore lock; /* risc instructions */ unsigned int risc_size; @@ -442,7 +440,7 @@ static struct file_operations btaudio_mixer_fops = { static int btaudio_dsp_open(struct inode *inode, struct file *file, struct btaudio *bta, int analog) { - mutex_lock(&bta->lock); + down(&bta->lock); if (bta->users) goto busy; bta->users++; @@ -454,11 +452,11 @@ static int btaudio_dsp_open(struct inode *inode, struct file *file, bta->read_count = 0; bta->sampleshift = 0; - mutex_unlock(&bta->lock); + up(&bta->lock); return 0; busy: - mutex_unlock(&bta->lock); + up(&bta->lock); return -EBUSY; } @@ -498,11 +496,11 @@ static int btaudio_dsp_release(struct inode *inode, struct file *file) { struct btaudio *bta = file->private_data; - mutex_lock(&bta->lock); + down(&bta->lock); if (bta->recording) stop_recording(bta); bta->users--; - mutex_unlock(&bta->lock); + up(&bta->lock); return 0; } @@ -515,7 +513,7 @@ static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer, DECLARE_WAITQUEUE(wait, current); add_wait_queue(&bta->readq, &wait); - mutex_lock(&bta->lock); + down(&bta->lock); while (swcount > 0) { if (0 == bta->read_count) { if (!bta->recording) { @@ -530,10 +528,10 @@ static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer, ret = -EAGAIN; break; } - mutex_unlock(&bta->lock); + up(&bta->lock); current->state = TASK_INTERRUPTIBLE; schedule(); - mutex_lock(&bta->lock); + down(&bta->lock); if(signal_pending(current)) { if (0 == ret) ret = -EINTR; @@ -606,7 +604,7 @@ static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer, if (bta->read_offset == bta->buf_size) bta->read_offset = 0; } - mutex_unlock(&bta->lock); + up(&bta->lock); remove_wait_queue(&bta->readq, &wait); current->state = TASK_RUNNING; return ret; @@ -653,10 +651,10 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file, bta->decimation = 0; } if (bta->recording) { - mutex_lock(&bta->lock); + down(&bta->lock); stop_recording(bta); start_recording(bta); - mutex_unlock(&bta->lock); + up(&bta->lock); } /* fall through */ case SOUND_PCM_READ_RATE: @@ -718,10 +716,10 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file, else bta->bits = 16; if (bta->recording) { - mutex_lock(&bta->lock); + down(&bta->lock); stop_recording(bta); start_recording(bta); - mutex_unlock(&bta->lock); + up(&bta->lock); } } if (debug) @@ -738,9 +736,9 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file, case SNDCTL_DSP_RESET: if (bta->recording) { - mutex_lock(&bta->lock); + down(&bta->lock); stop_recording(bta); - mutex_unlock(&bta->lock); + up(&bta->lock); } return 0; case SNDCTL_DSP_GETBLKSIZE: @@ -943,7 +941,7 @@ static int __devinit btaudio_probe(struct pci_dev *pci_dev, if (rate) bta->rate = rate; - mutex_init(&bta->lock); + init_MUTEX(&bta->lock); init_waitqueue_head(&bta->readq); if (-1 != latency) { diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c index de60a059f..7cfbb08db 100644 --- a/sound/oss/cmpci.c +++ b/sound/oss/cmpci.c @@ -138,8 +138,6 @@ #endif #ifdef CONFIG_SOUND_CMPCI_JOYSTICK #include -#include - #endif /* --------------------------------------------------------------------- */ @@ -394,7 +392,7 @@ struct cm_state { unsigned char fmt, enable; spinlock_t lock; - struct mutex open_mutex; + struct semaphore open_sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -1713,7 +1711,7 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg) case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ if (get_user(val, p)) return -EFAULT; - i = hweight32(val); + i = generic_hweight32(val); for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) { if (!(val & (1 << i))) continue; @@ -2827,21 +2825,21 @@ static int cm_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } if (file->f_mode & FMODE_READ) { s->status &= ~DO_BIGENDIAN_R; @@ -2869,7 +2867,7 @@ static int cm_open(struct inode *inode, struct file *file) } set_fmt(s, fmtm, fmts); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -2881,7 +2879,7 @@ static int cm_release(struct inode *inode, struct file *file) lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); @@ -2905,7 +2903,7 @@ static int cm_release(struct inode *inode, struct file *file) s->status &= ~DO_BIGENDIAN_R; } s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -3082,7 +3080,7 @@ static int __devinit cm_probe(struct pci_dev *pcidev, const struct pci_device_id init_waitqueue_head(&s->dma_adc.wait); init_waitqueue_head(&s->dma_dac.wait); init_waitqueue_head(&s->open_wait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->magic = CM_MAGIC; s->dev = pcidev; diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c index c7f86f09c..7c59e2d40 100644 --- a/sound/oss/cs4232.c +++ b/sound/oss/cs4232.c @@ -360,8 +360,6 @@ static int __initdata synthio = -1; static int __initdata synthirq = -1; static int __initdata isapnp = 1; -static unsigned int cs4232_devices; - MODULE_DESCRIPTION("CS4232 based soundcard driver"); MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis"); MODULE_LICENSE("GPL"); @@ -423,7 +421,6 @@ static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev return -ENODEV; } pnp_set_drvdata(dev,isapnpcfg); - cs4232_devices++; return 0; } @@ -458,11 +455,10 @@ static int __init init_cs4232(void) #endif cfg.irq = -1; - if (isapnp) { - pnp_register_driver(&cs4232_driver); - if (cs4232_devices) - return 0; - } + if (isapnp && + (pnp_register_driver(&cs4232_driver) > 0) + ) + return 0; if(io==-1||irq==-1||dma==-1) { @@ -507,8 +503,7 @@ static int __init setup_cs4232(char *str) int ints[7]; /* If we have isapnp cards, no need for options */ - pnp_register_driver(&cs4232_driver); - if (cs4232_devices) + if (pnp_register_driver(&cs4232_driver) > 0) return 1; str = get_options(str, ARRAY_SIZE(ints), ints); diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c index 0004442f9..0720365f6 100644 --- a/sound/oss/cs4281/cs4281m.c +++ b/sound/oss/cs4281/cs4281m.c @@ -245,9 +245,9 @@ struct cs4281_state { void *tmpbuff; // tmp buffer for sample conversions unsigned ena; spinlock_t lock; - struct mutex open_sem; - struct mutex open_sem_adc; - struct mutex open_sem_dac; + struct semaphore open_sem; + struct semaphore open_sem_adc; + struct semaphore open_sem_dac; mode_t open_mode; wait_queue_head_t open_wait; wait_queue_head_t open_wait_adc; @@ -3598,20 +3598,20 @@ static int cs4281_release(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) { drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_sem_dac); + down(&s->open_sem_dac); stop_dac(s); dealloc_dmabuf(s, &s->dma_dac); s->open_mode &= ~FMODE_WRITE; - mutex_unlock(&s->open_sem_dac); + up(&s->open_sem_dac); wake_up(&s->open_wait_dac); } if (file->f_mode & FMODE_READ) { drain_adc(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_sem_adc); + down(&s->open_sem_adc); stop_adc(s); dealloc_dmabuf(s, &s->dma_adc); s->open_mode &= ~FMODE_READ; - mutex_unlock(&s->open_sem_adc); + up(&s->open_sem_adc); wake_up(&s->open_wait_adc); } return 0; @@ -3651,33 +3651,33 @@ static int cs4281_open(struct inode *inode, struct file *file) return -ENODEV; } if (file->f_mode & FMODE_WRITE) { - mutex_lock(&s->open_sem_dac); + down(&s->open_sem_dac); while (s->open_mode & FMODE_WRITE) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_sem_dac); + up(&s->open_sem_dac); return -EBUSY; } - mutex_unlock(&s->open_sem_dac); + up(&s->open_sem_dac); interruptible_sleep_on(&s->open_wait_dac); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_sem_dac); + down(&s->open_sem_dac); } } if (file->f_mode & FMODE_READ) { - mutex_lock(&s->open_sem_adc); + down(&s->open_sem_adc); while (s->open_mode & FMODE_READ) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_sem_adc); + up(&s->open_sem_adc); return -EBUSY; } - mutex_unlock(&s->open_sem_adc); + up(&s->open_sem_adc); interruptible_sleep_on(&s->open_wait_adc); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_sem_adc); + down(&s->open_sem_adc); } } s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); @@ -3691,7 +3691,7 @@ static int cs4281_open(struct inode *inode, struct file *file) s->ena &= ~FMODE_READ; s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; - mutex_unlock(&s->open_sem_adc); + up(&s->open_sem_adc); if (prog_dmabuf_adc(s)) { CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR @@ -3711,7 +3711,7 @@ static int cs4281_open(struct inode *inode, struct file *file) s->ena &= ~FMODE_WRITE; s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; - mutex_unlock(&s->open_sem_dac); + up(&s->open_sem_dac); if (prog_dmabuf_dac(s)) { CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR @@ -3978,17 +3978,17 @@ static int cs4281_midi_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; // wait for device to become free - mutex_lock(&s->open_sem); + down(&s->open_sem); while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_sem); + up(&s->open_sem); return -EBUSY; } - mutex_unlock(&s->open_sem); + up(&s->open_sem); interruptible_sleep_on(&s->open_wait); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_sem); + down(&s->open_sem); } spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -4018,7 +4018,7 @@ static int cs4281_midi_open(struct inode *inode, struct file *file) (file-> f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); - mutex_unlock(&s->open_sem); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -4057,7 +4057,7 @@ static int cs4281_midi_release(struct inode *inode, struct file *file) remove_wait_queue(&s->midi.owait, &wait); current->state = TASK_RUNNING; } - mutex_lock(&s->open_sem); + down(&s->open_sem); s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); @@ -4067,7 +4067,7 @@ static int cs4281_midi_release(struct inode *inode, struct file *file) del_timer(&s->midi.timer); } spin_unlock_irqrestore(&s->lock, flags); - mutex_unlock(&s->open_sem); + up(&s->open_sem); wake_up(&s->open_wait); return 0; } @@ -4300,9 +4300,9 @@ static int __devinit cs4281_probe(struct pci_dev *pcidev, init_waitqueue_head(&s->open_wait_dac); init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); - mutex_init(&s->open_sem); - mutex_init(&s->open_sem_adc); - mutex_init(&s->open_sem_dac); + init_MUTEX(&s->open_sem); + init_MUTEX(&s->open_sem_adc); + init_MUTEX(&s->open_sem_dac); spin_lock_init(&s->lock); s->pBA0phys = pci_resource_start(pcidev, 0); s->pBA1phys = pci_resource_start(pcidev, 1); diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c index 53881bc91..58e25c82e 100644 --- a/sound/oss/cs46xx.c +++ b/sound/oss/cs46xx.c @@ -90,7 +90,6 @@ #include #include #include -#include #include #include @@ -239,7 +238,7 @@ struct cs_state { struct cs_card *card; /* Card info */ /* single open lock mechanism, only used for recording */ - struct mutex open_mutex; + struct semaphore open_sem; wait_queue_head_t open_wait; /* file mode */ @@ -298,7 +297,7 @@ struct cs_state { unsigned subdivision; } dmabuf; /* Guard against mmap/write/read races */ - struct mutex sem; + struct semaphore sem; }; struct cs_card { @@ -376,7 +375,7 @@ struct cs_card { unsigned char ibuf[CS_MIDIINBUF]; unsigned char obuf[CS_MIDIOUTBUF]; mode_t open_mode; - struct mutex open_mutex; + struct semaphore open_sem; } midi; struct cs46xx_pm pm; }; @@ -1429,9 +1428,9 @@ static int prog_dmabuf(struct cs_state *state) { int ret; - mutex_lock(&state->sem); + down(&state->sem); ret = __prog_dmabuf(state); - mutex_unlock(&state->sem); + up(&state->sem); return ret; } @@ -1832,17 +1831,17 @@ static int cs_midi_open(struct inode *inode, struct file *file) file->private_data = card; /* wait for device to become free */ - mutex_lock(&card->midi.open_mutex); + down(&card->midi.open_sem); while (card->midi.open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&card->midi.open_mutex); + up(&card->midi.open_sem); return -EBUSY; } - mutex_unlock(&card->midi.open_mutex); + up(&card->midi.open_sem); interruptible_sleep_on(&card->midi.open_wait); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&card->midi.open_mutex); + down(&card->midi.open_sem); } spin_lock_irqsave(&card->midi.lock, flags); if (!(card->midi.open_mode & (FMODE_READ | FMODE_WRITE))) { @@ -1860,7 +1859,7 @@ static int cs_midi_open(struct inode *inode, struct file *file) } spin_unlock_irqrestore(&card->midi.lock, flags); card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE)); - mutex_unlock(&card->midi.open_mutex); + up(&card->midi.open_sem); return 0; } @@ -1892,9 +1891,9 @@ static int cs_midi_release(struct inode *inode, struct file *file) remove_wait_queue(&card->midi.owait, &wait); current->state = TASK_RUNNING; } - mutex_lock(&card->midi.open_mutex); + down(&card->midi.open_sem); card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE))); - mutex_unlock(&card->midi.open_mutex); + up(&card->midi.open_sem); wake_up(&card->midi.open_wait); return 0; } @@ -2082,7 +2081,7 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; - mutex_lock(&state->sem); + down(&state->sem); if (!dmabuf->ready && (ret = __prog_dmabuf(state))) goto out2; @@ -2115,13 +2114,13 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof if (!ret) ret = -EAGAIN; goto out; } - mutex_unlock(&state->sem); + up(&state->sem); schedule(); if (signal_pending(current)) { if(!ret) ret = -ERESTARTSYS; goto out; } - mutex_lock(&state->sem); + down(&state->sem); if (dmabuf->mapped) { if(!ret) @@ -2156,7 +2155,7 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof out: remove_wait_queue(&state->dmabuf.wait, &wait); out2: - mutex_unlock(&state->sem); + up(&state->sem); set_current_state(TASK_RUNNING); CS_DBGOUT(CS_WAVE_READ | CS_FUNCTION, 4, printk("cs46xx: cs_read()- %zd\n",ret) ); @@ -2185,7 +2184,7 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou return -EFAULT; dmabuf = &state->dmabuf; - mutex_lock(&state->sem); + down(&state->sem); if (dmabuf->mapped) { ret = -ENXIO; @@ -2241,13 +2240,13 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou if (!ret) ret = -EAGAIN; goto out; } - mutex_unlock(&state->sem); + up(&state->sem); schedule(); if (signal_pending(current)) { if(!ret) ret = -ERESTARTSYS; goto out; } - mutex_lock(&state->sem); + down(&state->sem); if (dmabuf->mapped) { if(!ret) @@ -2279,7 +2278,7 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou start_dac(state); } out: - mutex_unlock(&state->sem); + up(&state->sem); remove_wait_queue(&state->dmabuf.wait, &wait); set_current_state(TASK_RUNNING); @@ -2412,7 +2411,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma) goto out; } - mutex_lock(&state->sem); + down(&state->sem); dmabuf = &state->dmabuf; if (cs4x_pgoff(vma) != 0) { @@ -2439,7 +2438,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma) CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mmap()-\n") ); out: - mutex_unlock(&state->sem); + up(&state->sem); return ret; } @@ -3201,7 +3200,7 @@ static int cs_open(struct inode *inode, struct file *file) if (state == NULL) return -ENOMEM; memset(state, 0, sizeof(struct cs_state)); - mutex_init(&state->sem); + init_MUTEX(&state->sem); dmabuf = &state->dmabuf; dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if(dmabuf->pbuf==NULL) @@ -3242,10 +3241,10 @@ static int cs_open(struct inode *inode, struct file *file) state->virt = 0; state->magic = CS_STATE_MAGIC; init_waitqueue_head(&dmabuf->wait); - mutex_init(&state->open_mutex); + init_MUTEX(&state->open_sem); file->private_data = card; - mutex_lock(&state->open_mutex); + down(&state->open_sem); /* set default sample format. According to OSS Programmer's Guide /dev/dsp should be default to unsigned 8-bits, mono, with sample rate 8kHz and @@ -3261,7 +3260,7 @@ static int cs_open(struct inode *inode, struct file *file) cs_set_divisor(dmabuf); state->open_mode |= FMODE_READ; - mutex_unlock(&state->open_mutex); + up(&state->open_sem); } if(file->f_mode & FMODE_WRITE) { @@ -3272,7 +3271,7 @@ static int cs_open(struct inode *inode, struct file *file) if (state == NULL) return -ENOMEM; memset(state, 0, sizeof(struct cs_state)); - mutex_init(&state->sem); + init_MUTEX(&state->sem); dmabuf = &state->dmabuf; dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if(dmabuf->pbuf==NULL) @@ -3313,10 +3312,10 @@ static int cs_open(struct inode *inode, struct file *file) state->virt = 1; state->magic = CS_STATE_MAGIC; init_waitqueue_head(&dmabuf->wait); - mutex_init(&state->open_mutex); + init_MUTEX(&state->open_sem); file->private_data = card; - mutex_lock(&state->open_mutex); + down(&state->open_sem); /* set default sample format. According to OSS Programmer's Guide /dev/dsp should be default to unsigned 8-bits, mono, with sample rate 8kHz and @@ -3332,7 +3331,7 @@ static int cs_open(struct inode *inode, struct file *file) cs_set_divisor(dmabuf); state->open_mode |= FMODE_WRITE; - mutex_unlock(&state->open_mutex); + up(&state->open_sem); if((ret = prog_dmabuf(state))) return ret; } @@ -3364,14 +3363,14 @@ static int cs_release(struct inode *inode, struct file *file) cs_clear_tail(state); drain_dac(state, file->f_flags & O_NONBLOCK); /* stop DMA state machine and free DMA buffers/channels */ - mutex_lock(&state->open_mutex); + down(&state->open_sem); stop_dac(state); dealloc_dmabuf(state); state->card->free_pcm_channel(state->card, dmabuf->channel->num); free_page((unsigned long)state->dmabuf.pbuf); - /* we're covered by the open_mutex */ - mutex_unlock(&state->open_mutex); + /* we're covered by the open_sem */ + up(&state->open_sem); state->card->states[state->virt] = NULL; state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); @@ -3396,14 +3395,14 @@ static int cs_release(struct inode *inode, struct file *file) { CS_DBGOUT(CS_RELEASE, 2, printk("cs46xx: cs_release() FMODE_READ\n") ); dmabuf = &state->dmabuf; - mutex_lock(&state->open_mutex); + down(&state->open_sem); stop_adc(state); dealloc_dmabuf(state); state->card->free_pcm_channel(state->card, dmabuf->channel->num); free_page((unsigned long)state->dmabuf.pbuf); - /* we're covered by the open_mutex */ - mutex_unlock(&state->open_mutex); + /* we're covered by the open_sem */ + up(&state->open_sem); state->card->states[state->virt] = NULL; state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); @@ -5508,7 +5507,7 @@ static int __devinit cs46xx_probe(struct pci_dev *pci_dev, } init_waitqueue_head(&card->midi.open_wait); - mutex_init(&card->midi.open_mutex); + init_MUTEX(&card->midi.open_sem); init_waitqueue_head(&card->midi.iwait); init_waitqueue_head(&card->midi.owait); cs461x_pokeBA0(card, BA0_MIDCR, MIDCR_MRST); diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c index c8e210326..74f975676 100644 --- a/sound/oss/dmasound/dmasound_awacs.c +++ b/sound/oss/dmasound/dmasound_awacs.c @@ -80,7 +80,7 @@ #include #include #include -#include +#include #ifdef CONFIG_ADB_CUDA #include #endif @@ -88,6 +88,8 @@ #include #endif +#include + #include #include #include @@ -128,7 +130,7 @@ static struct resource awacs_rsrc[3]; static char awacs_name[64]; static int awacs_revision; static int awacs_sleeping; -static DEFINE_MUTEX(dmasound_mutex); +static DECLARE_MUTEX(dmasound_sem); static int sound_device_id; /* exists after iMac revA */ static int hw_can_byteswap = 1 ; /* most pmac sound h/w can */ @@ -310,11 +312,11 @@ extern int daca_enter_sleep(void); extern int daca_leave_sleep(void); #define TRY_LOCK() \ - if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0) \ + if ((rc = down_interruptible(&dmasound_sem)) != 0) \ return rc; -#define LOCK() mutex_lock(&dmasound_mutex); +#define LOCK() down(&dmasound_sem); -#define UNLOCK() mutex_unlock(&dmasound_mutex); +#define UNLOCK() up(&dmasound_sem); /* We use different versions that the ones provided in dmasound.h * @@ -2798,7 +2800,7 @@ __init setup_beep(void) DBDMA_ALIGN(beep_dbdma_cmd_space); /* set up emergency dbdma cmd */ emergency_dbdma_cmd = beep_dbdma_cmd+1 ; - beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); + beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); if (beep_buf == NULL) { printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n"); kfree(beep_dbdma_cmd_space) ; @@ -2814,7 +2816,7 @@ int __init dmasound_awacs_init(void) struct device_node *io = NULL, *info = NULL; int vol, res; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return -ENODEV; awacs_subframe = 0; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 87bd3100a..c9302a1e5 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -195,18 +195,18 @@ */ int dmasound_catchRadius = 0; -module_param(dmasound_catchRadius, int, 0); +MODULE_PARM(dmasound_catchRadius, "i"); static unsigned int numWriteBufs = DEFAULT_N_BUFFERS; -module_param(numWriteBufs, int, 0); +MODULE_PARM(numWriteBufs, "i"); static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */ -module_param(writeBufSize, int, 0); +MODULE_PARM(writeBufSize, "i"); #ifdef HAS_RECORD static unsigned int numReadBufs = DEFAULT_N_BUFFERS; -module_param(numReadBufs, int, 0); +MODULE_PARM(numReadBufs, "i"); static unsigned int readBufSize = DEFAULT_BUFF_SIZE; /* in bytes */ -module_param(readBufSize, int, 0); +MODULE_PARM(readBufSize, "i"); #endif MODULE_LICENSE("GPL"); diff --git a/sound/oss/emu10k1/hwaccess.h b/sound/oss/emu10k1/hwaccess.h index 85e27bda6..104223a19 100644 --- a/sound/oss/emu10k1/hwaccess.h +++ b/sound/oss/emu10k1/hwaccess.h @@ -181,7 +181,7 @@ struct emu10k1_card struct emu10k1_mpuout *mpuout; struct emu10k1_mpuin *mpuin; - struct mutex open_sem; + struct semaphore open_sem; mode_t open_mode; wait_queue_head_t open_wait; diff --git a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c index 3721c5857..23241cbdd 100644 --- a/sound/oss/emu10k1/main.c +++ b/sound/oss/emu10k1/main.c @@ -94,7 +94,6 @@ #include #include #include -#include #include "hwaccess.h" #include "8010.h" @@ -120,7 +119,7 @@ /* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */ -#define EMU10K1_DMA_MASK DMA_29BIT_MASK /* DMA buffer mask for pci_alloc_consist */ +#define EMU10K1_DMA_MASK 0x1fffffff /* DMA buffer mask for pci_alloc_consist */ #ifndef PCI_VENDOR_ID_CREATIVE #define PCI_VENDOR_ID_CREATIVE 0x1102 @@ -1321,7 +1320,7 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev card->is_aps = (subsysvid == EMU_APS_SUBID); spin_lock_init(&card->lock); - mutex_init(&card->open_sem); + init_MUTEX(&card->open_sem); card->open_mode = 0; init_waitqueue_head(&card->open_wait); diff --git a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c index 25ae8e4a4..b40b5f97a 100644 --- a/sound/oss/emu10k1/midi.c +++ b/sound/oss/emu10k1/midi.c @@ -65,8 +65,7 @@ static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hd init_midi_hdr(midihdr); - midihdr->data = kmalloc(MIDIIN_BUFLEN, GFP_KERNEL); - if (!midihdr->data) { + if ((midihdr->data = (u8 *) kmalloc(MIDIIN_BUFLEN, GFP_KERNEL)) == NULL) { ERROR(); kfree(midihdr); return -1; @@ -111,21 +110,21 @@ match: #endif /* Wait for device to become free */ - mutex_lock(&card->open_sem); + down(&card->open_sem); while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&card->open_sem); + up(&card->open_sem); return -EBUSY; } - mutex_unlock(&card->open_sem); + up(&card->open_sem); interruptible_sleep_on(&card->open_wait); if (signal_pending(current)) { return -ERESTARTSYS; } - mutex_lock(&card->open_sem); + down(&card->open_sem); } if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) @@ -184,7 +183,7 @@ match: card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); - mutex_unlock(&card->open_sem); + up(&card->open_sem); return nonseekable_open(inode, file); } @@ -235,9 +234,9 @@ static int emu10k1_midi_release(struct inode *inode, struct file *file) kfree(midi_dev); - mutex_lock(&card->open_sem); + down(&card->open_sem); card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE)); - mutex_unlock(&card->open_sem); + up(&card->open_sem); wake_up_interruptible(&card->open_wait); unlock_kernel(); @@ -335,8 +334,7 @@ static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, midihdr->bytesrecorded = 0; midihdr->flags = 0; - midihdr->data = kmalloc(count, GFP_KERNEL); - if (!midihdr->data) { + if ((midihdr->data = (u8 *) kmalloc(count, GFP_KERNEL)) == NULL) { ERROR(); kfree(midihdr); return -EINVAL; @@ -547,8 +545,7 @@ int emu10k1_seq_midi_out(int dev, unsigned char midi_byte) midihdr->bytesrecorded = 0; midihdr->flags = 0; - midihdr->data = kmalloc(1, GFP_KERNEL); - if (!midihdr->data) { + if ((midihdr->data = (u8 *) kmalloc(1, GFP_KERNEL)) == NULL) { ERROR(); kfree(midihdr); return -EINVAL; diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c index 094f569cc..ae55c5366 100644 --- a/sound/oss/es1370.c +++ b/sound/oss/es1370.c @@ -157,7 +157,6 @@ #include #include #include -#include #include #include @@ -347,7 +346,7 @@ struct es1370_state { unsigned sctrl; spinlock_t lock; - struct mutex open_mutex; + struct semaphore open_sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -394,7 +393,7 @@ struct es1370_state { struct gameport *gameport; #endif - struct mutex mutex; + struct semaphore sem; }; /* --------------------------------------------------------------------- */ @@ -1160,7 +1159,7 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, return -ENXIO; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; - mutex_lock(&s->mutex); + down(&s->sem); if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) goto out; @@ -1184,14 +1183,14 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, ret = -EAGAIN; goto out; } - mutex_unlock(&s->mutex); + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out; } - mutex_lock(&s->mutex); + down(&s->sem); if (s->dma_adc.mapped) { ret = -ENXIO; @@ -1216,7 +1215,7 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, start_adc(s); } out: - mutex_unlock(&s->mutex); + up(&s->sem); remove_wait_queue(&s->dma_adc.wait, &wait); set_current_state(TASK_RUNNING); return ret; @@ -1236,7 +1235,7 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t return -ENXIO; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; - mutex_lock(&s->mutex); + down(&s->sem); if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) goto out; ret = 0; @@ -1264,14 +1263,14 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t ret = -EAGAIN; goto out; } - mutex_unlock(&s->mutex); + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out; } - mutex_lock(&s->mutex); + down(&s->sem); if (s->dma_dac2.mapped) { ret = -ENXIO; @@ -1297,7 +1296,7 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t start_dac2(s); } out: - mutex_unlock(&s->mutex); + up(&s->sem); remove_wait_queue(&s->dma_dac2.wait, &wait); set_current_state(TASK_RUNNING); return ret; @@ -1349,7 +1348,7 @@ static int es1370_mmap(struct file *file, struct vm_area_struct *vma) VALIDATE_STATE(s); lock_kernel(); - mutex_lock(&s->mutex); + down(&s->sem); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf_dac2(s)) != 0) { goto out; @@ -1381,7 +1380,7 @@ static int es1370_mmap(struct file *file, struct vm_area_struct *vma) } db->mapped = 1; out: - mutex_unlock(&s->mutex); + up(&s->sem); unlock_kernel(); return ret; } @@ -1753,21 +1752,21 @@ static int es1370_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_READ|FMODE_WRITE))) @@ -1794,8 +1793,8 @@ static int es1370_open(struct inode *inode, struct file *file) outl(s->ctrl, s->io+ES1370_REG_CONTROL); spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); - mutex_init(&s->mutex); + up(&s->open_sem); + init_MUTEX(&s->sem); return nonseekable_open(inode, file); } @@ -1807,7 +1806,7 @@ static int es1370_release(struct inode *inode, struct file *file) lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac2(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac2(s); synchronize_irq(s->irq); @@ -1819,7 +1818,7 @@ static int es1370_release(struct inode *inode, struct file *file) } s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -2199,21 +2198,21 @@ static int es1370_open_dac(struct inode *inode, struct file *file) return -EINVAL; file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & FMODE_DAC) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; s->dma_dac1.enabled = 1; @@ -2228,7 +2227,7 @@ static int es1370_open_dac(struct inode *inode, struct file *file) outl(s->ctrl, s->io+ES1370_REG_CONTROL); spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= FMODE_DAC; - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -2239,12 +2238,12 @@ static int es1370_release_dac(struct inode *inode, struct file *file) VALIDATE_STATE(s); lock_kernel(); drain_dac1(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); stop_dac1(s); dealloc_dmabuf(s, &s->dma_dac1); s->open_mode &= ~FMODE_DAC; wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -2431,21 +2430,21 @@ static int es1370_midi_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -2466,7 +2465,7 @@ static int es1370_midi_open(struct inode *inode, struct file *file) es1370_handle_midi(s); spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -2500,7 +2499,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file) remove_wait_queue(&s->midi.owait, &wait); set_current_state(TASK_RUNNING); } - mutex_lock(&s->open_mutex); + down(&s->open_sem); s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -2509,7 +2508,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file) } spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -2639,7 +2638,7 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic init_waitqueue_head(&s->open_wait); init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->magic = ES1370_MAGIC; s->dev = pcidev; diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c index 4400c8538..5c697f162 100644 --- a/sound/oss/es1371.c +++ b/sound/oss/es1371.c @@ -129,7 +129,6 @@ #include #include #include -#include #include #include @@ -420,7 +419,7 @@ struct es1371_state { unsigned dac1rate, dac2rate, adcrate; spinlock_t lock; - struct mutex open_mutex; + struct semaphore open_sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -463,7 +462,7 @@ struct es1371_state { struct gameport *gameport; #endif - struct mutex sem; + struct semaphore sem; }; /* --------------------------------------------------------------------- */ @@ -1347,7 +1346,7 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, return -ENXIO; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; - mutex_lock(&s->sem); + down(&s->sem); if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) goto out2; @@ -1371,14 +1370,14 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, ret = -EAGAIN; goto out; } - mutex_unlock(&s->sem); + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out2; } - mutex_lock(&s->sem); + down(&s->sem); if (s->dma_adc.mapped) { ret = -ENXIO; @@ -1403,7 +1402,7 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, start_adc(s); } out: - mutex_unlock(&s->sem); + up(&s->sem); out2: remove_wait_queue(&s->dma_adc.wait, &wait); set_current_state(TASK_RUNNING); @@ -1424,7 +1423,7 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t return -ENXIO; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; - mutex_lock(&s->sem); + down(&s->sem); if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) goto out3; ret = 0; @@ -1452,14 +1451,14 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t ret = -EAGAIN; goto out; } - mutex_unlock(&s->sem); + up(&s->sem); schedule(); if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto out2; } - mutex_lock(&s->sem); + down(&s->sem); if (s->dma_dac2.mapped) { ret = -ENXIO; @@ -1485,7 +1484,7 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t start_dac2(s); } out: - mutex_unlock(&s->sem); + up(&s->sem); out2: remove_wait_queue(&s->dma_dac2.wait, &wait); out3: @@ -1539,7 +1538,7 @@ static int es1371_mmap(struct file *file, struct vm_area_struct *vma) VALIDATE_STATE(s); lock_kernel(); - mutex_lock(&s->sem); + down(&s->sem); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf_dac2(s)) != 0) { @@ -1572,7 +1571,7 @@ static int es1371_mmap(struct file *file, struct vm_area_struct *vma) } db->mapped = 1; out: - mutex_unlock(&s->sem); + up(&s->sem); unlock_kernel(); return ret; } @@ -1939,21 +1938,21 @@ static int es1371_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } if (file->f_mode & FMODE_READ) { s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; @@ -1983,8 +1982,8 @@ static int es1371_open(struct inode *inode, struct file *file) outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); - mutex_init(&s->sem); + up(&s->open_sem); + init_MUTEX(&s->sem); return nonseekable_open(inode, file); } @@ -1996,7 +1995,7 @@ static int es1371_release(struct inode *inode, struct file *file) lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac2(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac2(s); dealloc_dmabuf(s, &s->dma_dac2); @@ -2006,7 +2005,7 @@ static int es1371_release(struct inode *inode, struct file *file) dealloc_dmabuf(s, &s->dma_adc); } s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -2378,21 +2377,21 @@ static int es1371_open_dac(struct inode *inode, struct file *file) return -EINVAL; file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & FMODE_DAC) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; s->dma_dac1.enabled = 1; @@ -2406,7 +2405,7 @@ static int es1371_open_dac(struct inode *inode, struct file *file) outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= FMODE_DAC; - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -2417,11 +2416,11 @@ static int es1371_release_dac(struct inode *inode, struct file *file) VALIDATE_STATE(s); lock_kernel(); drain_dac1(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); stop_dac1(s); dealloc_dmabuf(s, &s->dma_dac1); s->open_mode &= ~FMODE_DAC; - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -2609,21 +2608,21 @@ static int es1371_midi_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -2644,7 +2643,7 @@ static int es1371_midi_open(struct inode *inode, struct file *file) es1371_handle_midi(s); spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -2677,7 +2676,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file) remove_wait_queue(&s->midi.owait, &wait); set_current_state(TASK_RUNNING); } - mutex_lock(&s->open_mutex); + down(&s->open_sem); s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -2685,7 +2684,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file) outl(s->ctrl, s->io+ES1371_REG_CONTROL); } spin_unlock_irqrestore(&s->lock, flags); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -2885,7 +2884,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic init_waitqueue_head(&s->open_wait); init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->magic = ES1371_MAGIC; s->dev = pcidev; diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c index 6861563d7..849b59f67 100644 --- a/sound/oss/esssolo1.c +++ b/sound/oss/esssolo1.c @@ -105,8 +105,6 @@ #include #include #include -#include - #include #include @@ -193,7 +191,7 @@ struct solo1_state { unsigned ena; spinlock_t lock; - struct mutex open_mutex; + struct semaphore open_sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -1583,7 +1581,7 @@ static int solo1_release(struct inode *inode, struct file *file) lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); outb(0, s->iobase+6); /* disable DMA */ @@ -1597,7 +1595,7 @@ static int solo1_release(struct inode *inode, struct file *file) } s->open_mode &= ~(FMODE_READ | FMODE_WRITE); wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -1626,21 +1624,21 @@ static int solo1_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & (FMODE_READ | FMODE_WRITE)) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } s->fmt = AFMT_U8; s->channels = 1; @@ -1652,7 +1650,7 @@ static int solo1_open(struct inode *inode, struct file *file) s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; s->dma_dac.enabled = 1; s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); prog_codec(s); return nonseekable_open(inode, file); } @@ -1913,21 +1911,21 @@ static int solo1_midi_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -1953,7 +1951,7 @@ static int solo1_midi_open(struct inode *inode, struct file *file) } spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -1987,7 +1985,7 @@ static int solo1_midi_release(struct inode *inode, struct file *file) remove_wait_queue(&s->midi.owait, &wait); set_current_state(TASK_RUNNING); } - mutex_lock(&s->open_mutex); + down(&s->open_sem); s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -1996,7 +1994,7 @@ static int solo1_midi_release(struct inode *inode, struct file *file) } spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -2134,24 +2132,24 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & FMODE_DMFM) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n"); return -EBUSY; } @@ -2163,7 +2161,7 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file) outb(5, s->sbbase+2); outb(1, s->sbbase+3); /* enable OPL3 */ s->open_mode |= FMODE_DMFM; - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -2174,7 +2172,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file) VALIDATE_STATE(s); lock_kernel(); - mutex_lock(&s->open_mutex); + down(&s->open_sem); s->open_mode &= ~FMODE_DMFM; for (regb = 0xb0; regb < 0xb9; regb++) { outb(regb, s->sbbase); @@ -2184,7 +2182,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file) } release_region(s->sbbase, FMSYNTH_EXTENT); wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -2348,7 +2346,7 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device /* Recording requires 24-bit DMA, so attempt to set dma mask * to 24 bits first, then 32 bits (playback only) if that fails. */ - if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK) && + if (pci_set_dma_mask(pcidev, 0x00ffffff) && pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) { printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n"); return -ENODEV; @@ -2364,7 +2362,7 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device init_waitqueue_head(&s->open_wait); init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->magic = SOLO1_MAGIC; s->dev = pcidev; diff --git a/sound/oss/forte.c b/sound/oss/forte.c index 0294eec8a..8406bc90c 100644 --- a/sound/oss/forte.c +++ b/sound/oss/forte.c @@ -43,7 +43,6 @@ #include #include -#include #include #include @@ -186,7 +185,7 @@ struct forte_chip { unsigned long iobase; int irq; - struct mutex open_mutex; /* Device access */ + struct semaphore open_sem; /* Device access */ spinlock_t lock; /* State */ spinlock_t ac97_lock; @@ -1243,13 +1242,13 @@ forte_dsp_open (struct inode *inode, struct file *file) struct forte_chip *chip = forte; /* FIXME: HACK FROM HELL! */ if (file->f_flags & O_NONBLOCK) { - if (!mutex_trylock(&chip->open_mutex)) { + if (down_trylock (&chip->open_sem)) { DPRINTK ("%s: returning -EAGAIN\n", __FUNCTION__); return -EAGAIN; } } else { - if (mutex_lock_interruptible(&chip->open_mutex)) { + if (down_interruptible (&chip->open_sem)) { DPRINTK ("%s: returning -ERESTARTSYS\n", __FUNCTION__); return -ERESTARTSYS; } @@ -1303,7 +1302,7 @@ forte_dsp_release (struct inode *inode, struct file *file) spin_unlock_irq (&chip->lock); } - mutex_unlock(&chip->open_mutex); + up (&chip->open_sem); return ret; } @@ -2012,7 +2011,7 @@ forte_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id) memset (chip, 0, sizeof (struct forte_chip)); chip->pci_dev = pci_dev; - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->open_sem); spin_lock_init (&chip->lock); spin_lock_init (&chip->ac97_lock); diff --git a/sound/oss/hal2.c b/sound/oss/hal2.c index dd4f59d30..afe97c4ce 100644 --- a/sound/oss/hal2.c +++ b/sound/oss/hal2.c @@ -32,8 +32,6 @@ #include #include #include -#include - #include #include @@ -94,7 +92,7 @@ struct hal2_codec { wait_queue_head_t dma_wait; spinlock_t lock; - struct mutex sem; + struct semaphore sem; int usecount; /* recording and playback are * independent */ @@ -1180,7 +1178,7 @@ static ssize_t hal2_read(struct file *file, char *buffer, if (!count) return 0; - if (mutex_lock_interruptible(&adc->sem)) + if (down_interruptible(&adc->sem)) return -EINTR; if (file->f_flags & O_NONBLOCK) { err = hal2_get_buffer(hal2, buffer, count); @@ -1219,7 +1217,7 @@ static ssize_t hal2_read(struct file *file, char *buffer, } } while (count > 0 && err >= 0); } - mutex_unlock(&adc->sem); + up(&adc->sem); return err; } @@ -1234,7 +1232,7 @@ static ssize_t hal2_write(struct file *file, const char *buffer, if (!count) return 0; - if (mutex_lock_interruptible(&dac->sem)) + if (down_interruptible(&dac->sem)) return -EINTR; if (file->f_flags & O_NONBLOCK) { err = hal2_add_buffer(hal2, buf, count); @@ -1273,7 +1271,7 @@ static ssize_t hal2_write(struct file *file, const char *buffer, } } while (count > 0 && err >= 0); } - mutex_unlock(&dac->sem); + up(&dac->sem); return err; } @@ -1358,20 +1356,20 @@ static int hal2_release(struct inode *inode, struct file *file) if (file->f_mode & FMODE_READ) { struct hal2_codec *adc = &hal2->adc; - mutex_lock(&adc->sem); + down(&adc->sem); hal2_stop_adc(hal2); hal2_free_adc_dmabuf(adc); adc->usecount--; - mutex_unlock(&adc->sem); + up(&adc->sem); } if (file->f_mode & FMODE_WRITE) { struct hal2_codec *dac = &hal2->dac; - mutex_lock(&dac->sem); + down(&dac->sem); hal2_sync_dac(hal2); hal2_free_dac_dmabuf(dac); dac->usecount--; - mutex_unlock(&dac->sem); + up(&dac->sem); } return 0; @@ -1402,7 +1400,7 @@ static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3, codec->pbus.pbusnr = index; codec->pbus.pbus = &hpc3->pbdma[index]; init_waitqueue_head(&codec->dma_wait); - mutex_init(&codec->sem); + init_MUTEX(&codec->sem); spin_lock_init(&codec->lock); } diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c index dd2b871cd..abc242abd 100644 --- a/sound/oss/i810_audio.c +++ b/sound/oss/i810_audio.c @@ -100,8 +100,6 @@ #include #include #include -#include - #include #define DRIVER_VERSION "1.01" @@ -333,7 +331,7 @@ struct i810_state { struct i810_card *card; /* Card info */ /* single open lock mechanism, only used for recording */ - struct mutex open_mutex; + struct semaphore open_sem; wait_queue_head_t open_wait; /* file mode */ @@ -2599,7 +2597,7 @@ found_virt: state->card = card; state->magic = I810_STATE_MAGIC; init_waitqueue_head(&dmabuf->wait); - mutex_init(&state->open_mutex); + init_MUTEX(&state->open_sem); file->private_data = state; dmabuf->trigger = 0; @@ -3215,7 +3213,7 @@ static void __devinit i810_configure_clocking (void) state->card = card; state->magic = I810_STATE_MAGIC; init_waitqueue_head(&dmabuf->wait); - mutex_init(&state->open_mutex); + init_MUTEX(&state->open_sem); dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT; dmabuf->trigger = PCM_ENABLE_OUTPUT; i810_set_spdif_output(state, -1, 0); diff --git a/sound/oss/ite8172.c b/sound/oss/ite8172.c index 00ac1c95a..8fd2f9a9e 100644 --- a/sound/oss/ite8172.c +++ b/sound/oss/ite8172.c @@ -71,8 +71,6 @@ #include #include #include -#include - #include #include #include @@ -306,7 +304,7 @@ struct it8172_state { unsigned dacrate, adcrate; spinlock_t lock; - struct mutex open_mutex; + struct semaphore open_sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -1803,21 +1801,21 @@ static int it8172_open(struct inode *inode, struct file *file) } file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } spin_lock_irqsave(&s->lock, flags); @@ -1852,7 +1850,7 @@ static int it8172_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE)); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -1866,7 +1864,7 @@ static int it8172_release(struct inode *inode, struct file *file) lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); dealloc_dmabuf(s, &s->dma_dac); @@ -1876,7 +1874,7 @@ static int it8172_release(struct inode *inode, struct file *file) dealloc_dmabuf(s, &s->dma_adc); } s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE)); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -1968,9 +1966,9 @@ static int i2s_fmt[NR_DEVICE]; static unsigned int devindex; -module_param_array(spdif, int, NULL, 0); +MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i"); MODULE_PARM_DESC(spdif, "if 1 the S/PDIF digital output is enabled"); -module_param_array(i2s_fmt, int, NULL, 0); +MODULE_PARM(i2s_fmt, "1-" __MODULE_STRING(NR_DEVICE) "i"); MODULE_PARM_DESC(i2s_fmt, "the format of I2S"); MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com"); @@ -1999,7 +1997,7 @@ static int __devinit it8172_probe(struct pci_dev *pcidev, init_waitqueue_head(&s->dma_adc.wait); init_waitqueue_head(&s->dma_dac.wait); init_waitqueue_head(&s->open_wait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->dev = pcidev; s->io = pci_resource_start(pcidev, 0); diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c index e647f2f86..d4b569acf 100644 --- a/sound/oss/maestro.c +++ b/sound/oss/maestro.c @@ -223,8 +223,6 @@ #include #include #include -#include - #include #include @@ -399,7 +397,7 @@ struct ess_state { /* this locks around the oss state in the driver */ spinlock_t lock; /* only let 1 be opening at a time */ - struct mutex open_mutex; + struct semaphore open_sem; wait_queue_head_t open_wait; mode_t open_mode; @@ -3022,26 +3020,26 @@ ess_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EWOULDBLOCK; } - mutex_unlock(&s->open_mutex); + up(&s->open_sem); interruptible_sleep_on(&s->open_wait); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } /* under semaphore.. */ if ((s->card->dmapages==NULL) && allocate_buffers(s)) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -ENOMEM; } - /* we're covered by the open_mutex */ + /* we're covered by the open_sem */ if( ! s->card->dsps_open ) { maestro_power(s->card,ACPI_D0); start_bob(s); @@ -3078,7 +3076,7 @@ ess_open(struct inode *inode, struct file *file) set_fmt(s, fmtm, fmts); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -3091,7 +3089,7 @@ ess_release(struct inode *inode, struct file *file) lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); } @@ -3100,7 +3098,7 @@ ess_release(struct inode *inode, struct file *file) } s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); - /* we're covered by the open_mutex */ + /* we're covered by the open_sem */ M_printk("maestro: %d dsps now alive\n",s->card->dsps_open-1); if( --s->card->dsps_open <= 0) { s->card->dsps_open = 0; @@ -3108,7 +3106,7 @@ ess_release(struct inode *inode, struct file *file) free_buffers(s); maestro_power(s->card,ACPI_D2); } - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -3468,7 +3466,7 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid) init_waitqueue_head(&s->dma_dac.wait); init_waitqueue_head(&s->open_wait); spin_lock_init(&s->lock); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); s->magic = ESS_STATE_MAGIC; s->apu[0] = 6*i; diff --git a/sound/oss/maestro3.c b/sound/oss/maestro3.c index 4a5e4237a..f3dec70fc 100644 --- a/sound/oss/maestro3.c +++ b/sound/oss/maestro3.c @@ -144,8 +144,6 @@ #include #include #include -#include - #include #include @@ -207,7 +205,7 @@ struct m3_state { when irqhandler uses s->lock and m3_assp_read uses card->lock ? */ - struct mutex open_mutex; + struct semaphore open_sem; wait_queue_head_t open_wait; mode_t open_mode; @@ -2015,17 +2013,17 @@ static int m3_open(struct inode *inode, struct file *file) file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EWOULDBLOCK; } - mutex_unlock(&s->open_mutex); + up(&s->open_sem); interruptible_sleep_on(&s->open_wait); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } spin_lock_irqsave(&c->lock, flags); @@ -2049,7 +2047,7 @@ static int m3_open(struct inode *inode, struct file *file) set_fmt(s, fmtm, fmts); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); spin_unlock_irqrestore(&c->lock, flags); return nonseekable_open(inode, file); } @@ -2064,7 +2062,7 @@ static int m3_release(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); spin_lock_irqsave(&card->lock, flags); if (file->f_mode & FMODE_WRITE) { @@ -2085,7 +2083,7 @@ static int m3_release(struct inode *inode, struct file *file) s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); spin_unlock_irqrestore(&card->lock, flags); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); return 0; @@ -2582,9 +2580,15 @@ static int alloc_dsp_suspendmem(struct m3_card *card) return 0; } +static void free_dsp_suspendmem(struct m3_card *card) +{ + if(card->suspend_mem) + vfree(card->suspend_mem); +} #else #define alloc_dsp_suspendmem(args...) 0 +#define free_dsp_suspendmem(args...) #endif /* @@ -2675,7 +2679,7 @@ static int __devinit m3_probe(struct pci_dev *pci_dev, const struct pci_device_i init_waitqueue_head(&s->dma_adc.wait); init_waitqueue_head(&s->dma_dac.wait); init_waitqueue_head(&s->open_wait); - mutex_init(&(s->open_mutex)); + init_MUTEX(&(s->open_sem)); s->magic = M3_STATE_MAGIC; m3_assp_client_init(s); @@ -2711,7 +2715,7 @@ out: if(ret) { if(card->iobase) release_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); - vfree(card->suspend_mem); + free_dsp_suspendmem(card); if(card->ac97) { unregister_sound_mixer(card->ac97->dev_mixer); kfree(card->ac97); @@ -2754,7 +2758,7 @@ static void m3_remove(struct pci_dev *pci_dev) } release_region(card->iobase, 256); - vfree(card->suspend_mem); + free_dsp_suspendmem(card); kfree(card); } devs = NULL; diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c index 5dbfc0f9c..a7ad2b0a2 100644 --- a/sound/oss/msnd.c +++ b/sound/oss/msnd.c @@ -95,8 +95,10 @@ void msnd_fifo_init(msnd_fifo *f) void msnd_fifo_free(msnd_fifo *f) { - vfree(f->data); - f->data = NULL; + if (f->data) { + vfree(f->data); + f->data = NULL; + } } int msnd_fifo_alloc(msnd_fifo *f, size_t n) diff --git a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c index 21c1954d9..fbb9170e8 100644 --- a/sound/oss/nec_vrc5477.c +++ b/sound/oss/nec_vrc5477.c @@ -78,8 +78,6 @@ #include #include #include -#include - #include #include #include @@ -200,7 +198,7 @@ struct vrc5477_ac97_state { unsigned short extended_status; spinlock_t lock; - struct mutex open_mutex; + struct semaphore open_sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -1619,22 +1617,22 @@ static int vrc5477_ac97_open(struct inode *inode, struct file *file) file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } spin_lock_irqsave(&s->lock, flags); @@ -1661,7 +1659,7 @@ static int vrc5477_ac97_open(struct inode *inode, struct file *file) bailout: spin_unlock_irqrestore(&s->lock, flags); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return ret; } @@ -1673,7 +1671,7 @@ static int vrc5477_ac97_release(struct inode *inode, struct file *file) lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); dealloc_dmabuf(s, &s->dma_dac); @@ -1683,7 +1681,7 @@ static int vrc5477_ac97_release(struct inode *inode, struct file *file) dealloc_dmabuf(s, &s->dma_adc); } s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); wake_up(&s->open_wait); unlock_kernel(); return 0; @@ -1869,7 +1867,7 @@ static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev, init_waitqueue_head(&s->dma_adc.wait); init_waitqueue_head(&s->dma_dac.wait); init_waitqueue_head(&s->open_wait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->dev = pcidev; diff --git a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c index 6e662ac00..7de079b20 100644 --- a/sound/oss/nm256_audio.c +++ b/sound/oss/nm256_audio.c @@ -960,7 +960,7 @@ static struct ac97_mixer_value_list mixer_defaults[] = { /* Installs the AC97 mixer into CARD. */ -static int __devinit +static int __init nm256_install_mixer (struct nm256_info *card) { int mixer; @@ -995,7 +995,7 @@ nm256_install_mixer (struct nm256_info *card) * RAM. */ -static void __devinit +static void __init nm256_peek_for_sig (struct nm256_info *card) { u32 port1offset @@ -1056,7 +1056,7 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) card->playing = 0; card->recording = 0; card->rev = rev; - spin_lock_init(&card->lock); + spin_lock_init(&card->lock); /* Init the memory port info. */ for (x = 0; x < 2; x++) { diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c index a1ec9d131..faa0b7919 100644 --- a/sound/oss/rme96xx.c +++ b/sound/oss/rme96xx.c @@ -58,7 +58,6 @@ TODO: #include #include #include -#include #include #include @@ -327,7 +326,7 @@ typedef struct _rme96xx_info { /* waiting and locking */ wait_queue_head_t wait; - struct mutex open_mutex; + struct semaphore open_sem; wait_queue_head_t open_wait; } dma[RME96xx_MAX_DEVS]; @@ -843,7 +842,7 @@ static void busmaster_free(void* ptr,int size) { static int rme96xx_dmabuf_init(rme96xx_info * s,struct dmabuf* dma,int ioffset,int ooffset) { - mutex_init(&dma->open_mutex); + init_MUTEX(&dma->open_sem); init_waitqueue_head(&dma->open_wait); init_waitqueue_head(&dma->wait); dma->s = s; @@ -1470,21 +1469,21 @@ static int rme96xx_open(struct inode *in, struct file *f) dma = &s->dma[devnum]; f->private_data = dma; /* wait for device to become free */ - mutex_lock(&dma->open_mutex); + down(&dma->open_sem); while (dma->open_mode & f->f_mode) { if (f->f_flags & O_NONBLOCK) { - mutex_unlock(&dma->open_mutex); + up(&dma->open_sem); return -EBUSY; } add_wait_queue(&dma->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&dma->open_mutex); + up(&dma->open_sem); schedule(); remove_wait_queue(&dma->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&dma->open_mutex); + down(&dma->open_sem); } COMM ("hardware open") @@ -1493,7 +1492,7 @@ static int rme96xx_open(struct inode *in, struct file *f) dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE)); dma->opened = 1; - mutex_unlock(&dma->open_mutex); + up(&dma->open_sem); DBG(printk("device num %d open finished\n",devnum)); return 0; @@ -1525,7 +1524,7 @@ static int rme96xx_release(struct inode *in, struct file *file) } wake_up(&dma->open_wait); - mutex_unlock(&dma->open_mutex); + up(&dma->open_sem); return 0; } diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c index 4708cbdc3..680b82e15 100644 --- a/sound/oss/sb_card.c +++ b/sound/oss/sb_card.c @@ -52,7 +52,6 @@ static int __initdata sm_games = 0; /* Logitech soundman games? */ static struct sb_card_config *legacy = NULL; #ifdef CONFIG_PNP -static int pnp_registered; static int __initdata pnp = 1; /* static int __initdata uart401 = 0; @@ -134,7 +133,7 @@ static void sb_unload(struct sb_card_config *scc) } /* Register legacy card with OSS subsystem */ -static int __init sb_init_legacy(void) +static int sb_init_legacy(void) { struct sb_module_options sbmo = {0}; @@ -235,8 +234,6 @@ static void sb_dev2cfg(struct pnp_dev *dev, struct sb_card_config *scc) } } -static unsigned int sb_pnp_devices; - /* Probe callback function for the PnP API */ static int sb_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device_id *card_id) { @@ -267,7 +264,6 @@ static int sb_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device scc->conf.dma, scc->conf.dma2); pnp_set_card_drvdata(card, scc); - sb_pnp_devices++; return sb_register_oss(scc, &sbmo); } @@ -293,14 +289,6 @@ static struct pnp_card_driver sb_pnp_driver = { MODULE_DEVICE_TABLE(pnp_card, sb_pnp_card_table); #endif /* CONFIG_PNP */ -static void __init_or_module sb_unregister_all(void) -{ -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&sb_pnp_driver); -#endif -} - static int __init sb_init(void) { int lres = 0; @@ -319,18 +307,17 @@ static int __init sb_init(void) #ifdef CONFIG_PNP if(pnp) { - int err = pnp_register_card_driver(&sb_pnp_driver); - if (!err) - pnp_registered = 1; - pres = sb_pnp_devices; + pres = pnp_register_card_driver(&sb_pnp_driver); } #endif printk(KERN_INFO "sb: Init: Done\n"); /* If either PnP or Legacy registered a card then return * success */ - if (pres == 0 && lres <= 0) { - sb_unregister_all(); + if (pres <= 0 && lres <= 0) { +#ifdef CONFIG_PNP + pnp_unregister_card_driver(&sb_pnp_driver); +#endif return -ENODEV; } return 0; @@ -346,10 +333,14 @@ static void __exit sb_exit(void) sb_unload(legacy); } - sb_unregister_all(); +#ifdef CONFIG_PNP + pnp_unregister_card_driver(&sb_pnp_driver); +#endif - vfree(smw_free); - smw_free = NULL; + if (smw_free) { + vfree(smw_free); + smw_free = NULL; + } } module_init(sb_init); diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c index ccb21d48d..f56898c39 100644 --- a/sound/oss/sb_mixer.c +++ b/sound/oss/sb_mixer.c @@ -273,14 +273,14 @@ int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right) int regoffs; unsigned char val; - if ((dev < 0) || (dev >= devc->iomap_sz)) - return -EINVAL; - regoffs = (*devc->iomap)[dev][LEFT_CHN].regno; if (regoffs == 0) return -EINVAL; + if ((dev < 0) || (dev >= devc->iomap_sz)) + return -EINVAL; + val = sb_getmixer(devc, regoffs); change_bits(devc, &val, dev, LEFT_CHN, left); diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c index 6815c30e0..698614226 100644 --- a/sound/oss/sequencer.c +++ b/sound/oss/sequencer.c @@ -709,11 +709,11 @@ static void seq_local_event(unsigned char *event_rec) static void seq_sysex_message(unsigned char *event_rec) { - unsigned int dev = event_rec[1]; + int dev = event_rec[1]; int i, l = 0; unsigned char *buf = &event_rec[2]; - if (dev > max_synthdev) + if ((int) dev > max_synthdev) return; if (!(synth_open_mask & (1 << dev))) return; @@ -1671,7 +1671,14 @@ void sequencer_init(void) void sequencer_unload(void) { - vfree(queue); - vfree(iqueue); - queue = iqueue = NULL; + if(queue) + { + vfree(queue); + queue=NULL; + } + if(iqueue) + { + vfree(iqueue); + iqueue=NULL; + } } diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c index 3f7427cd1..8a9917c91 100644 --- a/sound/oss/sh_dac_audio.c +++ b/sound/oss/sh_dac_audio.c @@ -289,7 +289,7 @@ static int __init dac_audio_init(void) in_use = 0; - data_buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL); + data_buffer = (char *)kmalloc(BUFFER_SIZE, GFP_KERNEL); if (data_buffer == NULL) return -ENOMEM; diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c index 42bd276cf..71b05e2f6 100644 --- a/sound/oss/sonicvibes.c +++ b/sound/oss/sonicvibes.c @@ -116,9 +116,6 @@ #include #include #include -#include -#include - #include #include @@ -331,7 +328,7 @@ struct sv_state { unsigned char fmt, enable; spinlock_t lock; - struct mutex open_mutex; + struct semaphore open_sem; mode_t open_mode; wait_queue_head_t open_wait; @@ -408,6 +405,24 @@ static inline unsigned ld2(unsigned int x) return r; } +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#ifdef hweight32 +#undef hweight32 +#endif + +static inline unsigned int hweight32(unsigned int w) +{ + unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); + res = (res & 0x33333333) + ((res >> 2) & 0x33333333); + res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); + res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); + return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); +} + /* --------------------------------------------------------------------- */ /* @@ -1907,21 +1922,21 @@ static int sv_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } if (file->f_mode & FMODE_READ) { fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT); @@ -1941,7 +1956,7 @@ static int sv_open(struct inode *inode, struct file *file) } set_fmt(s, fmtm, fmts); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -1953,7 +1968,7 @@ static int sv_release(struct inode *inode, struct file *file) lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_mutex); + down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(s); dealloc_dmabuf(s, &s->dma_dac); @@ -1964,7 +1979,7 @@ static int sv_release(struct inode *inode, struct file *file) } s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -2152,21 +2167,21 @@ static int sv_midi_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -2195,7 +2210,7 @@ static int sv_midi_open(struct inode *inode, struct file *file) } spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -2233,7 +2248,7 @@ static int sv_midi_release(struct inode *inode, struct file *file) remove_wait_queue(&s->midi.owait, &wait); set_current_state(TASK_RUNNING); } - mutex_lock(&s->open_mutex); + down(&s->open_sem); s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); spin_lock_irqsave(&s->lock, flags); if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { @@ -2242,7 +2257,7 @@ static int sv_midi_release(struct inode *inode, struct file *file) } spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -2373,21 +2388,21 @@ static int sv_dmfm_open(struct inode *inode, struct file *file) VALIDATE_STATE(s); file->private_data = s; /* wait for device to become free */ - mutex_lock(&s->open_mutex); + down(&s->open_sem); while (s->open_mode & FMODE_DMFM) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return -EBUSY; } add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - mutex_lock(&s->open_mutex); + down(&s->open_sem); } /* init the stuff */ outb(1, s->iosynth); @@ -2397,7 +2412,7 @@ static int sv_dmfm_open(struct inode *inode, struct file *file) outb(5, s->iosynth+2); outb(1, s->iosynth+3); /* enable OPL3 */ s->open_mode |= FMODE_DMFM; - mutex_unlock(&s->open_mutex); + up(&s->open_sem); return nonseekable_open(inode, file); } @@ -2408,7 +2423,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file) VALIDATE_STATE(s); lock_kernel(); - mutex_lock(&s->open_mutex); + down(&s->open_sem); s->open_mode &= ~FMODE_DMFM; for (regb = 0xb0; regb < 0xb9; regb++) { outb(regb, s->iosynth); @@ -2417,7 +2432,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file) outb(0, s->iosynth+3); } wake_up(&s->open_wait); - mutex_unlock(&s->open_mutex); + up(&s->open_sem); unlock_kernel(); return 0; } @@ -2536,7 +2551,7 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id return -ENODEV; if (pcidev->irq == 0) return -ENODEV; - if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK)) { + if (pci_set_dma_mask(pcidev, 0x00ffffff)) { printk(KERN_WARNING "sonicvibes: architecture does not support 24bit PCI busmaster DMA\n"); return -ENODEV; } @@ -2567,7 +2582,7 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id init_waitqueue_head(&s->open_wait); init_waitqueue_head(&s->midi.iwait); init_waitqueue_head(&s->midi.owait); - mutex_init(&s->open_mutex); + init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->magic = SV_MAGIC; s->dev = pcidev; diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index eb5ea32fd..a1de9dcfb 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -76,7 +76,6 @@ #include #include #include -#include #include #include @@ -154,8 +153,8 @@ static void start_adc(struct cs4297a_state *s); #if CSDEBUG static unsigned long cs_debuglevel = 4; // levels range from 1-9 static unsigned long cs_debugmask = CS_INIT /*| CS_IOCTL*/; -module_param(cs_debuglevel, int, 0); -module_param(cs_debugmask, int, 0); +MODULE_PARM(cs_debuglevel, "i"); +MODULE_PARM(cs_debugmask, "i"); #endif #define CS_TRUE 1 #define CS_FALSE 0 @@ -292,9 +291,9 @@ struct cs4297a_state { unsigned conversion:1; // conversion from 16 to 8 bit in progress unsigned ena; spinlock_t lock; - struct mutex open_mutex; - struct mutex open_sem_adc; - struct mutex open_sem_dac; + struct semaphore open_sem; + struct semaphore open_sem_adc; + struct semaphore open_sem_dac; mode_t open_mode; wait_queue_head_t open_wait; wait_queue_head_t open_wait_adc; @@ -725,7 +724,7 @@ static int serdma_reg_access(struct cs4297a_state *s, u64 data) serdma_t *d = &s->dma_dac; u64 *data_p; unsigned swptr; - int flags; + unsigned long flags; serdma_descr_t *descr; if (s->reg_request) { @@ -2353,20 +2352,20 @@ static int cs4297a_release(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) { drain_dac(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_sem_dac); + down(&s->open_sem_dac); stop_dac(s); dealloc_dmabuf(s, &s->dma_dac); s->open_mode &= ~FMODE_WRITE; - mutex_unlock(&s->open_sem_dac); + up(&s->open_sem_dac); wake_up(&s->open_wait_dac); } if (file->f_mode & FMODE_READ) { drain_adc(s, file->f_flags & O_NONBLOCK); - mutex_lock(&s->open_sem_adc); + down(&s->open_sem_adc); stop_adc(s); dealloc_dmabuf(s, &s->dma_adc); s->open_mode &= ~FMODE_READ; - mutex_unlock(&s->open_sem_adc); + up(&s->open_sem_adc); wake_up(&s->open_wait_adc); } return 0; @@ -2414,37 +2413,37 @@ static int cs4297a_open(struct inode *inode, struct file *file) ; } - mutex_lock(&s->open_sem_dac); + down(&s->open_sem_dac); while (s->open_mode & FMODE_WRITE) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_sem_dac); + up(&s->open_sem_dac); return -EBUSY; } - mutex_unlock(&s->open_sem_dac); + up(&s->open_sem_dac); interruptible_sleep_on(&s->open_wait_dac); if (signal_pending(current)) { printk("open - sig pending\n"); return -ERESTARTSYS; } - mutex_lock(&s->open_sem_dac); + down(&s->open_sem_dac); } } if (file->f_mode & FMODE_READ) { - mutex_lock(&s->open_sem_adc); + down(&s->open_sem_adc); while (s->open_mode & FMODE_READ) { if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_sem_adc); + up(&s->open_sem_adc); return -EBUSY; } - mutex_unlock(&s->open_sem_adc); + up(&s->open_sem_adc); interruptible_sleep_on(&s->open_wait_adc); if (signal_pending(current)) { printk("open - sig pending\n"); return -ERESTARTSYS; } - mutex_lock(&s->open_sem_adc); + down(&s->open_sem_adc); } } s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); @@ -2457,7 +2456,7 @@ static int cs4297a_open(struct inode *inode, struct file *file) s->ena &= ~FMODE_READ; s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; - mutex_unlock(&s->open_sem_adc); + up(&s->open_sem_adc); if (prog_dmabuf_adc(s)) { CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR @@ -2475,7 +2474,7 @@ static int cs4297a_open(struct inode *inode, struct file *file) s->ena &= ~FMODE_WRITE; s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; - mutex_unlock(&s->open_sem_dac); + up(&s->open_sem_dac); if (prog_dmabuf_dac(s)) { CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR @@ -2632,8 +2631,8 @@ static int __init cs4297a_init(void) init_waitqueue_head(&s->open_wait); init_waitqueue_head(&s->open_wait_adc); init_waitqueue_head(&s->open_wait_dac); - mutex_init(&s->open_sem_adc); - mutex_init(&s->open_sem_dac); + init_MUTEX(&s->open_sem_adc); + init_MUTEX(&s->open_sem_dac); spin_lock_init(&s->lock); s->irq = K_INT_SER_1; diff --git a/sound/oss/trident.c b/sound/oss/trident.c index e61a454a8..a21c663e7 100644 --- a/sound/oss/trident.c +++ b/sound/oss/trident.c @@ -190,7 +190,7 @@ * * Lock order (high->low) * lock - hardware lock - * open_mutex - guard opens + * open_sem - guard opens * sem - guard dmabuf, write re-entry etc */ @@ -216,8 +216,6 @@ #include #include #include -#include - #include #include #include @@ -351,7 +349,7 @@ struct trident_state { unsigned chans_num; unsigned long fmt_flag; /* Guard against mmap/write/read races */ - struct mutex sem; + struct semaphore sem; }; @@ -404,7 +402,7 @@ struct trident_card { struct trident_card *next; /* single open lock mechanism, only used for recording */ - struct mutex open_mutex; + struct semaphore open_sem; /* The trident has a certain amount of cross channel interaction so we use a single per card lock */ @@ -1883,7 +1881,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; - mutex_lock(&state->sem); + down(&state->sem); if (!dmabuf->ready && (ret = prog_dmabuf_record(state))) goto out; @@ -1915,7 +1913,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos goto out; } - mutex_unlock(&state->sem); + up(&state->sem); /* No matter how much space left in the buffer, */ /* we have to wait until CSO == ESO/2 or CSO == ESO */ /* when address engine interrupts */ @@ -1942,7 +1940,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos ret = -ERESTARTSYS; goto out; } - mutex_lock(&state->sem); + down(&state->sem); if (dmabuf->mapped) { if (!ret) ret = -ENXIO; @@ -1970,7 +1968,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos start_adc(state); } out: - mutex_unlock(&state->sem); + up(&state->sem); return ret; } @@ -1998,7 +1996,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t * Guard against an mmap or ioctl while writing */ - mutex_lock(&state->sem); + down(&state->sem); if (dmabuf->mapped) { ret = -ENXIO; @@ -2047,7 +2045,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2); tmo >>= sample_shift[dmabuf->fmt]; unlock_set_fmt(state); - mutex_unlock(&state->sem); + up(&state->sem); /* There are two situations when sleep_on_timeout */ /* returns, one is when the interrupt is serviced */ @@ -2075,7 +2073,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t ret = -ERESTARTSYS; goto out_nolock; } - mutex_lock(&state->sem); + down(&state->sem); if (dmabuf->mapped) { if (!ret) ret = -ENXIO; @@ -2133,7 +2131,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t start_dac(state); } out: - mutex_unlock(&state->sem); + up(&state->sem); out_nolock: return ret; } @@ -2154,24 +2152,24 @@ trident_poll(struct file *file, struct poll_table_struct *wait) * prog_dmabuf events */ - mutex_lock(&state->sem); + down(&state->sem); if (file->f_mode & FMODE_WRITE) { if (!dmabuf->ready && prog_dmabuf_playback(state)) { - mutex_unlock(&state->sem); + up(&state->sem); return 0; } poll_wait(file, &dmabuf->wait, wait); } if (file->f_mode & FMODE_READ) { if (!dmabuf->ready && prog_dmabuf_record(state)) { - mutex_unlock(&state->sem); + up(&state->sem); return 0; } poll_wait(file, &dmabuf->wait, wait); } - mutex_unlock(&state->sem); + up(&state->sem); spin_lock_irqsave(&state->card->lock, flags); trident_update_ptr(state); @@ -2209,7 +2207,7 @@ trident_mmap(struct file *file, struct vm_area_struct *vma) * a read or write against an mmap. */ - mutex_lock(&state->sem); + down(&state->sem); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf_playback(state)) != 0) @@ -2234,7 +2232,7 @@ trident_mmap(struct file *file, struct vm_area_struct *vma) dmabuf->mapped = 1; ret = 0; out: - mutex_unlock(&state->sem); + up(&state->sem); return ret; } @@ -2431,15 +2429,15 @@ trident_ioctl(struct inode *inode, struct file *file, unlock_set_fmt(state); break; } - mutex_lock(&state->card->open_mutex); + down(&state->card->open_sem); ret = ali_allocate_other_states_resources(state, 6); if (ret < 0) { - mutex_unlock(&state->card->open_mutex); + up(&state->card->open_sem); unlock_set_fmt(state); break; } state->card->multi_channel_use_count++; - mutex_unlock(&state->card->open_mutex); + up(&state->card->open_sem); } else val = 2; /*yield to 2-channels */ } else @@ -2729,11 +2727,11 @@ trident_open(struct inode *inode, struct file *file) /* find an available virtual channel (instance of /dev/dsp) */ while (card != NULL) { - mutex_lock(&card->open_mutex); + down(&card->open_sem); if (file->f_mode & FMODE_READ) { /* Skip opens on cards that are in 6 channel mode */ if (card->multi_channel_use_count > 0) { - mutex_unlock(&card->open_mutex); + up(&card->open_sem); card = card->next; continue; } @@ -2742,16 +2740,16 @@ trident_open(struct inode *inode, struct file *file) if (card->states[i] == NULL) { state = card->states[i] = kmalloc(sizeof(*state), GFP_KERNEL); if (state == NULL) { - mutex_unlock(&card->open_mutex); + up(&card->open_sem); return -ENOMEM; } memset(state, 0, sizeof(*state)); - mutex_init(&state->sem); + init_MUTEX(&state->sem); dmabuf = &state->dmabuf; goto found_virt; } } - mutex_unlock(&card->open_mutex); + up(&card->open_sem); card = card->next; } /* no more virtual channel avaiable */ @@ -2818,7 +2816,7 @@ trident_open(struct inode *inode, struct file *file) } state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&card->open_mutex); + up(&card->open_sem); pr_debug("trident: open virtual channel %d, hard channel %d\n", state->virt, dmabuf->channel->num); @@ -2847,7 +2845,7 @@ trident_release(struct inode *inode, struct file *file) state->virt, dmabuf->channel->num); /* stop DMA state machine and free DMA buffers/channels */ - mutex_lock(&card->open_mutex); + down(&card->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac(state); @@ -2880,8 +2878,8 @@ trident_release(struct inode *inode, struct file *file) card->states[state->virt] = NULL; kfree(state); - /* we're covered by the open_mutex */ - mutex_unlock(&card->open_mutex); + /* we're covered by the open_sem */ + up(&card->open_sem); return 0; } @@ -4407,7 +4405,7 @@ trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) card->banks[BANK_B].addresses = &bank_b_addrs; card->banks[BANK_B].bitmap = 0UL; - mutex_init(&card->open_mutex); + init_MUTEX(&card->open_sem); spin_lock_init(&card->lock); init_timer(&card->timer); diff --git a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c index 1a921ee71..83edda93f 100644 --- a/sound/oss/via82cxxx_audio.c +++ b/sound/oss/via82cxxx_audio.c @@ -38,8 +38,7 @@ #include #include #include -#include - +#include #include "sound_config.h" #include "dev_table.h" #include "mpu401.h" @@ -312,8 +311,8 @@ struct via_info { int mixer_vol; /* 8233/35 volume - not yet implemented */ - struct mutex syscall_mutex; - struct mutex open_mutex; + struct semaphore syscall_sem; + struct semaphore open_sem; /* The 8233/8235 have 4 DX audio channels, two record and one six channel out. We bind ch_in to DX 1, ch_out to multichannel @@ -506,10 +505,10 @@ static inline int via_syscall_down (struct via_info *card, int nonblock) nonblock = 0; if (nonblock) { - if (!mutex_trylock(&card->syscall_mutex)) + if (down_trylock (&card->syscall_sem)) return -EAGAIN; } else { - if (mutex_lock_interruptible(&card->syscall_mutex)) + if (down_interruptible (&card->syscall_sem)) return -ERESTARTSYS; } @@ -1610,7 +1609,7 @@ static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int #endif rc = codec->mixer_ioctl(codec, cmd, arg); - mutex_unlock(&card->syscall_mutex); + up (&card->syscall_sem); out: DPRINTK ("EXIT, returning %d\n", rc); @@ -2229,7 +2228,7 @@ static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma) if (wr) card->ch_out.is_mapped = 1; - mutex_unlock(&card->syscall_mutex); + up (&card->syscall_sem); rc = 0; out: @@ -2257,7 +2256,7 @@ handle_one_block: /* Thomas Sailer: * But also to ourselves, release semaphore if we do so */ if (need_resched()) { - mutex_unlock(&card->syscall_mutex); + up(&card->syscall_sem); schedule (); ret = via_syscall_down (card, nonblock); if (ret) @@ -2287,7 +2286,7 @@ handle_one_block: break; } - mutex_unlock(&card->syscall_mutex); + up(&card->syscall_sem); DPRINTK ("Sleeping on block %d\n", n); schedule(); @@ -2403,7 +2402,7 @@ static ssize_t via_dsp_read(struct file *file, char __user *buffer, size_t count rc = via_dsp_do_read (card, buffer, count, nonblock); out_up: - mutex_unlock(&card->syscall_mutex); + up (&card->syscall_sem); out: DPRINTK ("EXIT, returning %ld\n",(long) rc); return rc; @@ -2427,7 +2426,7 @@ handle_one_block: /* Thomas Sailer: * But also to ourselves, release semaphore if we do so */ if (need_resched()) { - mutex_unlock(&card->syscall_mutex); + up(&card->syscall_sem); schedule (); ret = via_syscall_down (card, nonblock); if (ret) @@ -2457,7 +2456,7 @@ handle_one_block: break; } - mutex_unlock(&card->syscall_mutex); + up(&card->syscall_sem); DPRINTK ("Sleeping on page %d, tmp==%d, ir==%d\n", n, tmp, chan->is_record); schedule(); @@ -2586,7 +2585,7 @@ static ssize_t via_dsp_write(struct file *file, const char __user *buffer, size_ rc = via_dsp_do_write (card, buffer, count, nonblock); out_up: - mutex_unlock(&card->syscall_mutex); + up (&card->syscall_sem); out: DPRINTK ("EXIT, returning %ld\n",(long) rc); return rc; @@ -2635,7 +2634,7 @@ static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wa * Sleeps until all playback has been flushed to the audio * hardware. * - * Locking: inside card->syscall_mutex + * Locking: inside card->syscall_sem */ static int via_dsp_drain_playback (struct via_info *card, @@ -2693,7 +2692,7 @@ static int via_dsp_drain_playback (struct via_info *card, printk (KERN_ERR "sleeping but not active\n"); #endif - mutex_unlock(&card->syscall_mutex); + up(&card->syscall_sem); DPRINTK ("sleeping, nbufs=%d\n", atomic_read (&chan->n_frags)); schedule(); @@ -2749,7 +2748,7 @@ out: * * Handles SNDCTL_DSP_GETISPACE and SNDCTL_DSP_GETOSPACE. * - * Locking: inside card->syscall_mutex + * Locking: inside card->syscall_sem */ static int via_dsp_ioctl_space (struct via_info *card, @@ -2794,7 +2793,7 @@ static int via_dsp_ioctl_space (struct via_info *card, * * Handles SNDCTL_DSP_GETIPTR and SNDCTL_DSP_GETOPTR. * - * Locking: inside card->syscall_mutex + * Locking: inside card->syscall_sem */ static int via_dsp_ioctl_ptr (struct via_info *card, @@ -3222,7 +3221,7 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file, break; } - mutex_unlock(&card->syscall_mutex); + up (&card->syscall_sem); DPRINTK ("EXIT, returning %d\n", rc); return rc; } @@ -3265,12 +3264,12 @@ static int via_dsp_open (struct inode *inode, struct file *file) match: if (nonblock) { - if (!mutex_trylock(&card->open_mutex)) { + if (down_trylock (&card->open_sem)) { DPRINTK ("EXIT, returning -EAGAIN\n"); return -EAGAIN; } } else { - if (mutex_lock_interruptible(&card->open_mutex)) { + if (down_interruptible (&card->open_sem)) { DPRINTK ("EXIT, returning -ERESTARTSYS\n"); return -ERESTARTSYS; } @@ -3356,8 +3355,8 @@ static int via_dsp_release(struct inode *inode, struct file *file) via_chan_buffer_free (card, &card->ch_in); } - mutex_unlock(&card->syscall_mutex); - mutex_unlock(&card->open_mutex); + up (&card->syscall_sem); + up (&card->open_sem); DPRINTK ("EXIT, returning 0\n"); return 0; @@ -3415,8 +3414,8 @@ static int __devinit via_init_one (struct pci_dev *pdev, const struct pci_device card->card_num = via_num_cards++; spin_lock_init (&card->lock); spin_lock_init (&card->ac97_lock); - mutex_init(&card->syscall_mutex); - mutex_init(&card->open_mutex); + init_MUTEX (&card->syscall_sem); + init_MUTEX (&card->open_sem); /* we must init these now, in case the intr handler needs them */ via_chan_init_defaults (card, &card->ch_out); diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c index 5f140c758..265423054 100644 --- a/sound/oss/vwsnd.c +++ b/sound/oss/vwsnd.c @@ -94,7 +94,7 @@ * Open will block until the previous client has closed the * device, unless O_NONBLOCK is specified. * - * The semaphore devc->io_mutex serializes PCM I/O syscalls. This + * The semaphore devc->io_sema serializes PCM I/O syscalls. This * is unnecessary in Linux 2.2, because the kernel lock * serializes read, write, and ioctl globally, but it's there, * ready for the brave, new post-kernel-lock world. @@ -105,7 +105,7 @@ * area it owns and update its pointers. See pcm_output() and * pcm_input() for most of the gory stuff. * - * devc->mix_mutex serializes all mixer ioctls. This is also + * devc->mix_sema serializes all mixer ioctls. This is also * redundant because of the kernel lock. * * The lowest level lock is lith->lithium_lock. It is a @@ -148,8 +148,7 @@ #include #include #include -#include - +#include #include #include "sound_config.h" @@ -247,6 +246,27 @@ typedef struct lithium { spinlock_t lock; /* protects codec and UST/MSC access */ } lithium_t; +/* + * li_create initializes the lithium_t structure and sets up vm mappings + * to access the registers. + * Returns 0 on success, -errno on failure. + */ + +static int __init li_create(lithium_t *lith, unsigned long baseaddr) +{ + static void li_destroy(lithium_t *); + + spin_lock_init(&lith->lock); + lith->page0 = ioremap_nocache(baseaddr + LI_PAGE0_OFFSET, PAGE_SIZE); + lith->page1 = ioremap_nocache(baseaddr + LI_PAGE1_OFFSET, PAGE_SIZE); + lith->page2 = ioremap_nocache(baseaddr + LI_PAGE2_OFFSET, PAGE_SIZE); + if (!lith->page0 || !lith->page1 || !lith->page2) { + li_destroy(lith); + return -ENOMEM; + } + return 0; +} + /* * li_destroy destroys the lithium_t structure and vm mappings. */ @@ -267,25 +287,6 @@ static void li_destroy(lithium_t *lith) } } -/* - * li_create initializes the lithium_t structure and sets up vm mappings - * to access the registers. - * Returns 0 on success, -errno on failure. - */ - -static int __init li_create(lithium_t *lith, unsigned long baseaddr) -{ - spin_lock_init(&lith->lock); - lith->page0 = ioremap_nocache(baseaddr + LI_PAGE0_OFFSET, PAGE_SIZE); - lith->page1 = ioremap_nocache(baseaddr + LI_PAGE1_OFFSET, PAGE_SIZE); - lith->page2 = ioremap_nocache(baseaddr + LI_PAGE2_OFFSET, PAGE_SIZE); - if (!lith->page0 || !lith->page1 || !lith->page2) { - li_destroy(lith); - return -ENOMEM; - } - return 0; -} - /* * basic register accessors - read/write long/byte */ @@ -1446,11 +1447,11 @@ typedef enum vwsnd_port_flags { * * port->lock protects: hwstate, flags, swb_[iu]_avail. * - * devc->io_mutex protects: swstate, sw_*, swb_[iu]_idx. + * devc->io_sema protects: swstate, sw_*, swb_[iu]_idx. * * everything else is only written by open/release or * pcm_{setup,shutdown}(), which are serialized by a - * combination of devc->open_mutex and devc->io_mutex. + * combination of devc->open_sema and devc->io_sema. */ typedef struct vwsnd_port { @@ -1506,9 +1507,9 @@ typedef struct vwsnd_dev { int audio_minor; /* minor number of audio device */ int mixer_minor; /* minor number of mixer device */ - struct mutex open_mutex; - struct mutex io_mutex; - struct mutex mix_mutex; + struct semaphore open_sema; + struct semaphore io_sema; + struct semaphore mix_sema; mode_t open_mode; wait_queue_head_t open_wait; @@ -1632,7 +1633,7 @@ static __inline__ unsigned int swb_inc_i(vwsnd_port_t *port, int inc) * mode-setting ioctls have been done, but before the first I/O is * done. * - * Locking: called with devc->io_mutex held. + * Locking: called with devc->io_sema held. * * Returns 0 on success, -errno on failure. */ @@ -2318,9 +2319,9 @@ static ssize_t vwsnd_audio_read(struct file *file, vwsnd_dev_t *devc = file->private_data; ssize_t ret; - mutex_lock(&devc->io_mutex); + down(&devc->io_sema); ret = vwsnd_audio_do_read(file, buffer, count, ppos); - mutex_unlock(&devc->io_mutex); + up(&devc->io_sema); return ret; } @@ -2393,9 +2394,9 @@ static ssize_t vwsnd_audio_write(struct file *file, vwsnd_dev_t *devc = file->private_data; ssize_t ret; - mutex_lock(&devc->io_mutex); + down(&devc->io_sema); ret = vwsnd_audio_do_write(file, buffer, count, ppos); - mutex_unlock(&devc->io_mutex); + up(&devc->io_sema); return ret; } @@ -2890,9 +2891,9 @@ static int vwsnd_audio_ioctl(struct inode *inode, vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; int ret; - mutex_lock(&devc->io_mutex); + down(&devc->io_sema); ret = vwsnd_audio_do_ioctl(inode, file, cmd, arg); - mutex_unlock(&devc->io_mutex); + up(&devc->io_sema); return ret; } @@ -2928,9 +2929,9 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) return -ENODEV; } - mutex_lock(&devc->open_mutex); + down(&devc->open_sema); while (devc->open_mode & file->f_mode) { - mutex_unlock(&devc->open_mutex); + up(&devc->open_sema); if (file->f_flags & O_NONBLOCK) { DEC_USE_COUNT; return -EBUSY; @@ -2940,10 +2941,10 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) DEC_USE_COUNT; return -ERESTARTSYS; } - mutex_lock(&devc->open_mutex); + down(&devc->open_sema); } devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&devc->open_mutex); + up(&devc->open_sema); /* get default sample format from minor number. */ @@ -2959,7 +2960,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) /* Initialize vwsnd_ports. */ - mutex_lock(&devc->io_mutex); + down(&devc->io_sema); { if (file->f_mode & FMODE_READ) { devc->rport.swstate = SW_INITIAL; @@ -2986,7 +2987,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) devc->wport.frag_count = 0; } } - mutex_unlock(&devc->io_mutex); + up(&devc->io_sema); file->private_data = devc; DBGRV(); @@ -3004,7 +3005,7 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file) int err = 0; lock_kernel(); - mutex_lock(&devc->io_mutex); + down(&devc->io_sema); { DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); @@ -3021,13 +3022,13 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file) if (wport) wport->swstate = SW_OFF; } - mutex_unlock(&devc->io_mutex); + up(&devc->io_sema); - mutex_lock(&devc->open_mutex); + down(&devc->open_sema); { devc->open_mode &= ~file->f_mode; } - mutex_unlock(&devc->open_mutex); + up(&devc->open_sema); wake_up(&devc->open_wait); DEC_USE_COUNT; DBGR(); @@ -3212,7 +3213,7 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl, DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg); - mutex_lock(&devc->mix_mutex); + down(&devc->mix_sema); { if ((cmd & ~nrmask) == MIXER_READ(0)) retval = mixer_read_ioctl(devc, nr, (void __user *) arg); @@ -3221,7 +3222,7 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl, else retval = -EINVAL; } - mutex_unlock(&devc->mix_mutex); + up(&devc->mix_sema); return retval; } @@ -3375,9 +3376,9 @@ static int __init attach_vwsnd(struct address_info *hw_config) /* Initialize as much of *devc as possible */ - mutex_init(&devc->open_mutex); - mutex_init(&devc->io_mutex); - mutex_init(&devc->mix_mutex); + init_MUTEX(&devc->open_sema); + init_MUTEX(&devc->io_sema); + init_MUTEX(&devc->mix_sema); devc->open_mode = 0; spin_lock_init(&devc->rport.lock); init_waitqueue_head(&devc->rport.queue); diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c index afcb524a4..99d04ad3c 100644 --- a/sound/oss/waveartist.c +++ b/sound/oss/waveartist.c @@ -2028,8 +2028,8 @@ __setup("waveartist=", setup_waveartist); #endif MODULE_DESCRIPTION("Rockwell WaveArtist RWA-010 sound driver"); -module_param(io, int, 0); /* IO base */ -module_param(irq, int, 0); /* IRQ */ -module_param(dma, int, 0); /* DMA */ -module_param(dma2, int, 0); /* DMA2 */ +MODULE_PARM(io, "i"); /* IO base */ +MODULE_PARM(irq, "i"); /* IRQ */ +MODULE_PARM(dma, "i"); /* DMA */ +MODULE_PARM(dma2, "i"); /* DMA2 */ MODULE_LICENSE("GPL"); diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c index bf90c124a..f8bd72e46 100644 --- a/sound/oss/ymfpci.c +++ b/sound/oss/ymfpci.c @@ -1918,10 +1918,10 @@ static int ymf_open(struct inode *inode, struct file *file) if (unit == NULL) return -ENODEV; - mutex_lock(&unit->open_mutex); + down(&unit->open_sem); if ((state = ymf_state_alloc(unit)) == NULL) { - mutex_unlock(&unit->open_mutex); + up(&unit->open_sem); return -ENOMEM; } list_add_tail(&state->chain, &unit->states); @@ -1956,7 +1956,7 @@ static int ymf_open(struct inode *inode, struct file *file) ymfpci_writeb(unit, YDSXGR_TIMERCTRL, (YDSXGR_TIMERCTRL_TEN|YDSXGR_TIMERCTRL_TIEN)); #endif - mutex_unlock(&unit->open_mutex); + up(&unit->open_sem); return nonseekable_open(inode, file); @@ -1974,7 +1974,7 @@ out_nodma: list_del(&state->chain); kfree(state); - mutex_unlock(&unit->open_mutex); + up(&unit->open_sem); return err; } @@ -1987,7 +1987,7 @@ static int ymf_release(struct inode *inode, struct file *file) ymfpci_writeb(unit, YDSXGR_TIMERCTRL, 0); #endif - mutex_lock(&unit->open_mutex); + down(&unit->open_sem); /* * XXX Solve the case of O_NONBLOCK close - don't deallocate here. @@ -2004,7 +2004,7 @@ static int ymf_release(struct inode *inode, struct file *file) file->private_data = NULL; /* Can you tell I programmed Solaris */ kfree(state); - mutex_unlock(&unit->open_mutex); + up(&unit->open_sem); return 0; } @@ -2532,7 +2532,7 @@ static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_devi spin_lock_init(&codec->reg_lock); spin_lock_init(&codec->voice_lock); spin_lock_init(&codec->ac97_lock); - mutex_init(&codec->open_mutex); + init_MUTEX(&codec->open_sem); INIT_LIST_HEAD(&codec->states); codec->pci = pcidev; diff --git a/sound/oss/ymfpci.h b/sound/oss/ymfpci.h index ac1785f2b..f810a100c 100644 --- a/sound/oss/ymfpci.h +++ b/sound/oss/ymfpci.h @@ -22,7 +22,6 @@ * */ #include -#include /* * Direct registers @@ -280,7 +279,7 @@ struct ymf_unit { /* soundcore stuff */ int dev_audio; - struct mutex open_mutex; + struct semaphore open_sem; struct list_head ymf_devs; struct list_head states; /* List of states for this unit */ diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 8f34986dd..9243318c8 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -15,18 +15,6 @@ config SND_AD1889 To compile this as a module, choose M here: the module will be called snd-ad1889. -config SND_ALS300 - tristate "Avance Logic ALS300/ALS300+" - depends on SND - select SND_PCM - select SND_AC97_CODEC - select SND_OPL3_LIB - help - Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+ - - To compile this driver as a module, choose M here: the module - will be called snd-als300 - config SND_ALS4000 tristate "Avance Logic ALS4000" depends on SND && ISA_DMA_API @@ -207,9 +195,8 @@ config SND_CS46XX will be called snd-cs46xx. config SND_CS46XX_NEW_DSP - bool "Cirrus Logic (Sound Fusion) New DSP support" - depends on SND_CS46XX - default y + bool "Cirrus Logic (Sound Fusion) New DSP support (EXPERIMENTAL)" + depends on SND_CS46XX && EXPERIMENTAL help Say Y here to use a new DSP image for SPDIF and dual codecs. @@ -228,6 +215,143 @@ config SND_CS5535AUDIO To compile this driver as a module, choose M here: the module will be called snd-cs5535audio. +config SND_DARLA20 + tristate "(Echoaudio) Darla20" + depends on SND + depends on FW_LOADER + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Darla. + + To compile this driver as a module, choose M here: the module + will be called snd-darla20 + +config SND_GINA20 + tristate "(Echoaudio) Gina20" + depends on SND + depends on FW_LOADER + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Gina. + + To compile this driver as a module, choose M here: the module + will be called snd-gina20 + +config SND_LAYLA20 + tristate "(Echoaudio) Layla20" + depends on SND + depends on FW_LOADER + select SND_RAWMIDI + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Layla. + + To compile this driver as a module, choose M here: the module + will be called snd-layla20 + +config SND_DARLA24 + tristate "(Echoaudio) Darla24" + depends on SND + depends on FW_LOADER + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Darla24. + + To compile this driver as a module, choose M here: the module + will be called snd-darla24 + +config SND_GINA24 + tristate "(Echoaudio) Gina24" + depends on SND + depends on FW_LOADER + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Gina24. + + To compile this driver as a module, choose M here: the module + will be called snd-gina24 + +config SND_LAYLA24 + tristate "(Echoaudio) Layla24" + depends on SND + depends on FW_LOADER + select SND_RAWMIDI + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Layla24. + + To compile this driver as a module, choose M here: the module + will be called snd-layla24 + +config SND_MONA + tristate "(Echoaudio) Mona" + depends on SND + depends on FW_LOADER + select SND_RAWMIDI + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Mona. + + To compile this driver as a module, choose M here: the module + will be called snd-mona + +config SND_MIA + tristate "(Echoaudio) Mia" + depends on SND + depends on FW_LOADER + select SND_RAWMIDI + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Mia and Mia-midi. + + To compile this driver as a module, choose M here: the module + will be called snd-mia + +config SND_ECHO3G + tristate "(Echoaudio) 3G cards" + depends on SND + depends on FW_LOADER + select SND_RAWMIDI + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Gina3G and Layla3G. + + To compile this driver as a module, choose M here: the module + will be called snd-echo3g + +config SND_INDIGO + tristate "(Echoaudio) Indigo" + depends on SND + depends on FW_LOADER + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Indigo. + + To compile this driver as a module, choose M here: the module + will be called snd-indigo + +config SND_INDIGOIO + tristate "(Echoaudio) Indigo IO" + depends on SND + depends on FW_LOADER + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Indigo IO. + + To compile this driver as a module, choose M here: the module + will be called snd-indigoio + +config SND_INDIGODJ + tristate "(Echoaudio) Indigo DJ" + depends on SND + depends on FW_LOADER + select SND_PCM + help + Say 'Y' or 'M' to include support for Echoaudio Indigo DJ. + + To compile this driver as a module, choose M here: the module + will be called snd-indigodj + config SND_EMU10K1 tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" depends on SND @@ -327,10 +451,10 @@ config SND_FM801_TEA575X_BOOL Forte SF256-PCS-02) into the snd-fm801 driver. config SND_FM801_TEA575X - tristate - depends on SND_FM801_TEA575X_BOOL - default SND_FM801 - select VIDEO_DEV + tristate + depends on SND_FM801_TEA575X_BOOL + default SND_FM801 + select VIDEO_DEV config SND_HDA_INTEL tristate "Intel HD Audio" @@ -481,19 +605,6 @@ config SND_PCXHR To compile this driver as a module, choose M here: the module will be called snd-pcxhr. -config SND_RIPTIDE - tristate "Conexant Riptide" - depends on SND - depends on FW_LOADER - select SND_OPL3_LIB - select SND_MPU401_UART - select SND_AC97_CODEC - help - Say 'Y' or 'M' to include support for Conexant Riptide chip. - - To compile this driver as a module, choose M here: the module - will be called snd-riptide - config SND_RME32 tristate "RME Digi32, 32/8, 32 PRO" depends on SND diff --git a/sound/pci/Makefile b/sound/pci/Makefile index cba5105aa..63d325763 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile @@ -4,7 +4,6 @@ # snd-ad1889-objs := ad1889.o -snd-als300-objs := als300.o snd-als4000-objs := als4000.o snd-atiixp-objs := atiixp.o snd-atiixp-modem-objs := atiixp_modem.o @@ -28,7 +27,6 @@ snd-via82xx-modem-objs := via82xx_modem.o # Toplevel Module Dependency obj-$(CONFIG_SND_AD1889) += snd-ad1889.o -obj-$(CONFIG_SND_ALS300) += snd-als300.o obj-$(CONFIG_SND_ALS4000) += snd-als4000.o obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o @@ -57,6 +55,7 @@ obj-$(CONFIG_SND) += \ ca0106/ \ cs46xx/ \ cs5535audio/ \ + echoaudio/ \ emu10k1/ \ hda/ \ ice1712/ \ @@ -64,7 +63,6 @@ obj-$(CONFIG_SND) += \ mixart/ \ nm256/ \ pcxhr/ \ - riptide/ \ rme9652/ \ trident/ \ ymfpci/ \ diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index fcb00c2a2..3020ca2b6 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -150,7 +149,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL }, { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL }, -{ 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix +{ 0x4e534350, 0xffffffff, "LM4550", NULL, NULL }, { 0x50534304, 0xffffffff, "UCB1400", NULL, NULL }, { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, @@ -160,7 +159,6 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF -{ 0x56494182, 0xffffffff, "VIA1618", NULL, NULL }, { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, @@ -193,6 +191,9 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) { + if (ac97->limited_regs && ! test_bit(reg, ac97->reg_accessed)) + return 0; + /* filter some registers for buggy codecs */ switch (ac97->id) { case AC97_ID_AK4540: @@ -295,11 +296,11 @@ void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned sh { if (!snd_ac97_valid_reg(ac97, reg)) return; - mutex_lock(&ac97->reg_mutex); + down(&ac97->reg_mutex); ac97->regs[reg] = value; ac97->bus->ops->write(ac97, reg, value); set_bit(reg, ac97->reg_accessed); - mutex_unlock(&ac97->reg_mutex); + up(&ac97->reg_mutex); } /** @@ -320,14 +321,14 @@ int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short va if (!snd_ac97_valid_reg(ac97, reg)) return -EINVAL; - mutex_lock(&ac97->reg_mutex); + down(&ac97->reg_mutex); change = ac97->regs[reg] != value; if (change) { ac97->regs[reg] = value; ac97->bus->ops->write(ac97, reg, value); } set_bit(reg, ac97->reg_accessed); - mutex_unlock(&ac97->reg_mutex); + up(&ac97->reg_mutex); return change; } @@ -350,9 +351,9 @@ int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned sho if (!snd_ac97_valid_reg(ac97, reg)) return -EINVAL; - mutex_lock(&ac97->reg_mutex); + down(&ac97->reg_mutex); change = snd_ac97_update_bits_nolock(ac97, reg, mask, value); - mutex_unlock(&ac97->reg_mutex); + up(&ac97->reg_mutex); return change; } @@ -379,12 +380,12 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns int change; unsigned short old, new, cfg; - mutex_lock(&ac97->page_mutex); + down(&ac97->page_mutex); old = ac97->spec.ad18xx.pcmreg[codec]; new = (old & ~mask) | value; change = old != new; if (change) { - mutex_lock(&ac97->reg_mutex); + down(&ac97->reg_mutex); cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG); ac97->spec.ad18xx.pcmreg[codec] = new; /* select single codec */ @@ -396,9 +397,9 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns /* select all codecs */ ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG, cfg | 0x7000); - mutex_unlock(&ac97->reg_mutex); + up(&ac97->reg_mutex); } - mutex_unlock(&ac97->page_mutex); + up(&ac97->page_mutex); return change; } @@ -466,7 +467,7 @@ static int snd_ac97_page_save(struct snd_ac97 *ac97, int reg, struct snd_kcontro (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 && (reg >= 0x60 && reg < 0x70)) { unsigned short page = (kcontrol->private_value >> 26) & 0x0f; - mutex_lock(&ac97->page_mutex); /* lock paging */ + down(&ac97->page_mutex); /* lock paging */ page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); } @@ -477,7 +478,7 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save) { if (page_save >= 0) { snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); - mutex_unlock(&ac97->page_mutex); /* unlock paging */ + up(&ac97->page_mutex); /* unlock paging */ } } @@ -673,12 +674,12 @@ static int snd_ac97_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - mutex_lock(&ac97->reg_mutex); + down(&ac97->reg_mutex); ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff; ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff; ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff; ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff; - mutex_unlock(&ac97->reg_mutex); + up(&ac97->reg_mutex); return 0; } @@ -717,7 +718,7 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ } } - mutex_lock(&ac97->reg_mutex); + down(&ac97->reg_mutex); change = ac97->spdif_status != new; ac97->spdif_status = new; @@ -745,7 +746,7 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ } } - mutex_unlock(&ac97->reg_mutex); + up(&ac97->reg_mutex); return change; } @@ -762,7 +763,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ value = (ucontrol->value.integer.value[0] & mask); - mutex_lock(&ac97->reg_mutex); + down(&ac97->reg_mutex); mask <<= shift; value <<= shift; old = snd_ac97_read_cache(ac97, reg); @@ -776,7 +777,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ if (extst & AC97_EA_SPDIF) snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ } - mutex_unlock(&ac97->reg_mutex); + up(&ac97->reg_mutex); return change; } @@ -887,10 +888,10 @@ static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int codec = kcontrol->private_value & 3; - mutex_lock(&ac97->page_mutex); + down(&ac97->page_mutex); ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); - mutex_unlock(&ac97->page_mutex); + up(&ac97->page_mutex); return 0; } @@ -1006,6 +1007,9 @@ static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg) break; } + if (ac97->limited_regs && test_bit(reg, ac97->reg_accessed)) + return 1; /* allow without check */ + val = snd_ac97_read(ac97, reg); if (!(val & mask)) { /* nothing seems to be here - mute flag is not set */ @@ -1025,18 +1029,6 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha unsigned char max[3] = { 63, 31, 15 }; int i; - /* first look up the static resolution table */ - if (ac97->res_table) { - const struct snd_ac97_res_table *tbl; - for (tbl = ac97->res_table; tbl->reg; tbl++) { - if (tbl->reg == reg) { - *lo_max = tbl->bits & 0xff; - *hi_max = (tbl->bits >> 8) & 0xff; - return; - } - } - } - *lo_max = *hi_max = 0; for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { unsigned short val; @@ -1204,20 +1196,6 @@ static int snd_ac97_cmix_new_stereo(struct snd_card *card, const char *pfx, int static unsigned int snd_ac97_determine_spdif_rates(struct snd_ac97 *ac97); -static void snd_ctl_elem_remove(struct snd_card *card, - struct snd_kcontrol *kcontrol) -{ - struct snd_kcontrol *kct; - struct snd_ctl_elem_id id = kcontrol->id; - - down_write(&card->controls_rwsem); - - if ((kct = snd_ctl_find_id(card, &id))) - snd_ctl_remove(card, kct); - - up_write(&card->controls_rwsem); -} - static int snd_ac97_mixer_build(struct snd_ac97 * ac97) { struct snd_card *card = ac97->bus->card; @@ -1361,35 +1339,23 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97) init_val = 0x9f9f; else init_val = 0x9f1f; - for (idx = 0; idx < 2; idx++) { - struct snd_kcontrol *kctrl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_pcm[idx], ac97); - snd_ctl_elem_remove(card, kctrl); - if ((err = snd_ctl_add(card, kctrl)) < 0) + for (idx = 0; idx < 2; idx++) + if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_pcm[idx], ac97))) < 0) return err; - } ac97->spec.ad18xx.pcmreg[0] = init_val; if (ac97->scaps & AC97_SCAP_SURROUND_DAC) { - for (idx = 0; idx < 2; idx++) { - struct snd_kcontrol *kctrl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_surround[idx], ac97); - snd_ctl_elem_remove(card, kctrl); - if ((err = snd_ctl_add(card, kctrl)) < 0) + for (idx = 0; idx < 2; idx++) + if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_surround[idx], ac97))) < 0) return err; - } ac97->spec.ad18xx.pcmreg[1] = init_val; } if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) { - for (idx = 0; idx < 2; idx++) { - struct snd_kcontrol *kctrl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_center[idx], ac97); - snd_ctl_elem_remove(card, kctrl); - if ((err = snd_ctl_add(card, kctrl)) < 0) + for (idx = 0; idx < 2; idx++) + if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_center[idx], ac97))) < 0) return err; - } - for (idx = 0; idx < 2; idx++) { - struct snd_kcontrol *kctrl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_lfe[idx], ac97); - snd_ctl_elem_remove(card, kctrl); - if ((err = snd_ctl_add(card, kctrl)) < 0) + for (idx = 0; idx < 2; idx++) + if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_lfe[idx], ac97))) < 0) return err; - } ac97->spec.ad18xx.pcmreg[2] = init_val; } snd_ac97_write_cache(ac97, AC97_PCM, init_val); @@ -1887,10 +1853,11 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, ac97->num = template->num; ac97->addr = template->addr; ac97->scaps = template->scaps; - ac97->res_table = template->res_table; + ac97->limited_regs = template->limited_regs; + memcpy(ac97->reg_accessed, template->reg_accessed, sizeof(ac97->reg_accessed)); bus->codec[ac97->num] = ac97; - mutex_init(&ac97->reg_mutex); - mutex_init(&ac97->page_mutex); + init_MUTEX(&ac97->reg_mutex); + init_MUTEX(&ac97->page_mutex); #ifdef CONFIG_PCI if (ac97->pci) { diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 4d9cf3730..a444a78c7 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -27,8 +27,6 @@ #include #include #include -#include - #include #include #include @@ -57,12 +55,12 @@ static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsi unsigned short page_save; int ret; - mutex_lock(&ac97->page_mutex); + down(&ac97->page_mutex); page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); ret = snd_ac97_update_bits(ac97, reg, mask, value); snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); - mutex_unlock(&ac97->page_mutex); /* unlock paging */ + up(&ac97->page_mutex); /* unlock paging */ return ret; } @@ -899,12 +897,12 @@ static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_ struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int err; - mutex_lock(&ac97->page_mutex); + down(&ac97->page_mutex); snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba); err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010, (ucontrol->value.integer.value[0] & 1) << 4); snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0); - mutex_unlock(&ac97->page_mutex); + up(&ac97->page_mutex); return err; } @@ -2825,33 +2823,3 @@ int mpatch_si3036(struct snd_ac97 * ac97) snd_ac97_write_cache(ac97, 0x68, 0); return 0; } - -/* - * LM 4550 Codec - * - * We use a static resolution table since LM4550 codec cannot be - * properly autoprobed to determine the resolution via - * check_volume_resolution(). - */ - -static struct snd_ac97_res_table lm4550_restbl[] = { - { AC97_MASTER, 0x1f1f }, - { AC97_HEADPHONE, 0x1f1f }, - { AC97_MASTER_MONO, 0x001f }, - { AC97_PC_BEEP, 0x001f }, /* LSB is ignored */ - { AC97_PHONE, 0x001f }, - { AC97_MIC, 0x001f }, - { AC97_LINE, 0x1f1f }, - { AC97_CD, 0x1f1f }, - { AC97_VIDEO, 0x1f1f }, - { AC97_AUX, 0x1f1f }, - { AC97_PCM, 0x1f1f }, - { AC97_REC_GAIN, 0x0f0f }, - { } /* terminator */ -}; - -int patch_lm4550(struct snd_ac97 *ac97) -{ - ac97->res_table = lm4550_restbl; - return 0; -} diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index adcaa0458..5060cb6f2 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h @@ -59,4 +59,3 @@ int patch_vt1616(struct snd_ac97 * ac97); int patch_vt1617a(struct snd_ac97 * ac97); int patch_it2646(struct snd_ac97 * ac97); int mpatch_si3036(struct snd_ac97 * ac97); -int patch_lm4550(struct snd_ac97 * ac97); diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index 512a3583b..c3e590bf7 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c @@ -27,8 +27,6 @@ #include #include #include -#include - #include #include #include @@ -208,7 +206,7 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) mask = AC97_SC_SPSR_MASK; } - mutex_lock(&ac97->reg_mutex); + down(&ac97->reg_mutex); old = snd_ac97_read(ac97, reg) & mask; if (old != bits) { snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); @@ -233,7 +231,7 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) ac97->spdif_status = sbits; } snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); - mutex_unlock(&ac97->reg_mutex); + up(&ac97->reg_mutex); return 0; } diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c index 4d523df79..7134b3f55 100644 --- a/sound/pci/ac97/ac97_proc.c +++ b/sound/pci/ac97/ac97_proc.c @@ -24,8 +24,6 @@ #include #include -#include - #include #include #include @@ -340,7 +338,7 @@ static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buf { struct snd_ac97 *ac97 = entry->private_data; - mutex_lock(&ac97->page_mutex); + down(&ac97->page_mutex); if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 int idx; for (idx = 0; idx < 3; idx++) @@ -366,7 +364,7 @@ static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buf } else { snd_ac97_proc_read_main(ac97, buffer, 0); } - mutex_unlock(&ac97->page_mutex); + up(&ac97->page_mutex); } #ifdef CONFIG_SND_DEBUG @@ -376,7 +374,7 @@ static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_in struct snd_ac97 *ac97 = entry->private_data; char line[64]; unsigned int reg, val; - mutex_lock(&ac97->page_mutex); + down(&ac97->page_mutex); while (!snd_info_get_line(buffer, line, sizeof(line))) { if (sscanf(line, "%x %x", ®, &val) != 2) continue; @@ -384,7 +382,7 @@ static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_in if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff) snd_ac97_write_cache(ac97, reg, val); } - mutex_unlock(&ac97->page_mutex); + up(&ac97->page_mutex); } #endif @@ -403,7 +401,7 @@ static void snd_ac97_proc_regs_read(struct snd_info_entry *entry, { struct snd_ac97 *ac97 = entry->private_data; - mutex_lock(&ac97->page_mutex); + down(&ac97->page_mutex); if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 int idx; @@ -419,7 +417,7 @@ static void snd_ac97_proc_regs_read(struct snd_info_entry *entry, } else { snd_ac97_proc_regs_read_main(ac97, buffer, 0); } - mutex_unlock(&ac97->page_mutex); + up(&ac97->page_mutex); } void snd_ac97_proc_init(struct snd_ac97 * ac97) diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c index 0fb7b3407..dcfb5036f 100644 --- a/sound/pci/ac97/ak4531_codec.c +++ b/sound/pci/ac97/ak4531_codec.c @@ -23,8 +23,6 @@ #include #include #include -#include - #include #include @@ -84,9 +82,9 @@ static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e int invert = (kcontrol->private_value >> 22) & 1; int val; - mutex_lock(&ak4531->reg_mutex); + down(&ak4531->reg_mutex); val = (ak4531->regs[reg] >> shift) & mask; - mutex_unlock(&ak4531->reg_mutex); + up(&ak4531->reg_mutex); if (invert) { val = mask - val; } @@ -109,11 +107,11 @@ static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e val = mask - val; } val <<= shift; - mutex_lock(&ak4531->reg_mutex); + down(&ak4531->reg_mutex); val = (ak4531->regs[reg] & ~(mask << shift)) | val; change = val != ak4531->regs[reg]; ak4531->write(ak4531, reg, ak4531->regs[reg] = val); - mutex_unlock(&ak4531->reg_mutex); + up(&ak4531->reg_mutex); return change; } @@ -145,10 +143,10 @@ static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e int invert = (kcontrol->private_value >> 22) & 1; int left, right; - mutex_lock(&ak4531->reg_mutex); + down(&ak4531->reg_mutex); left = (ak4531->regs[left_reg] >> left_shift) & mask; right = (ak4531->regs[right_reg] >> right_shift) & mask; - mutex_unlock(&ak4531->reg_mutex); + up(&ak4531->reg_mutex); if (invert) { left = mask - left; right = mask - right; @@ -178,7 +176,7 @@ static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e } left <<= left_shift; right <<= right_shift; - mutex_lock(&ak4531->reg_mutex); + down(&ak4531->reg_mutex); if (left_reg == right_reg) { left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right; change = left != ak4531->regs[left_reg]; @@ -190,7 +188,7 @@ static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right); } - mutex_unlock(&ak4531->reg_mutex); + up(&ak4531->reg_mutex); return change; } @@ -217,12 +215,12 @@ static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl int left_shift = (kcontrol->private_value >> 16) & 0x0f; int right_shift = (kcontrol->private_value >> 24) & 0x0f; - mutex_lock(&ak4531->reg_mutex); + down(&ak4531->reg_mutex); ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1; ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1; ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1; ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1; - mutex_unlock(&ak4531->reg_mutex); + up(&ak4531->reg_mutex); return 0; } @@ -236,7 +234,7 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl int change; int val1, val2; - mutex_lock(&ak4531->reg_mutex); + down(&ak4531->reg_mutex); val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift)); val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift)); val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift; @@ -246,7 +244,7 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2]; ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1); ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2); - mutex_unlock(&ak4531->reg_mutex); + up(&ak4531->reg_mutex); return change; } @@ -368,7 +366,7 @@ int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, if (ak4531 == NULL) return -ENOMEM; *ak4531 = *_ak4531; - mutex_init(&ak4531->reg_mutex); + init_MUTEX(&ak4531->reg_mutex); if ((err = snd_component_add(card, "AK4531")) < 0) { snd_ak4531_free(ak4531); return err; diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index eece1c7e5..a208075cd 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include @@ -910,10 +909,10 @@ snd_ad1889_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) 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, 0xffffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0xffffffff) < 0) { printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n"); pci_disable_device(pci); return -ENXIO; @@ -1051,7 +1050,7 @@ snd_ad1889_remove(struct pci_dev *pci) pci_set_drvdata(pci, NULL); } -static struct pci_device_id snd_ad1889_ids[] __devinitdata = { +static struct pci_device_id snd_ad1889_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) }, { 0, }, }; diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index e2dbc2118..e264136e8 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -279,7 +278,7 @@ struct snd_ali { #endif }; -static struct pci_device_id snd_ali_ids[] __devinitdata = { +static struct pci_device_id snd_ali_ids[] = { {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0}, {0, } }; @@ -2221,8 +2220,8 @@ static int __devinit snd_ali_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 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, 0x7fffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) { snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/als300.c b/sound/pci/als300.c deleted file mode 100644 index 901b08ae9..000000000 --- a/sound/pci/als300.c +++ /dev/null @@ -1,867 +0,0 @@ -/* - * als300.c - driver for Avance Logic ALS300/ALS300+ soundcards. - * Copyright (C) 2005 by Ash Willis - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 - * - * TODO - * 4 channel playback for ALS300+ - * gameport - * mpu401 - * opl3 - * - * NOTES - * The BLOCK_COUNTER registers for the ALS300(+) return a figure related to - * the position in the current period, NOT the whole buffer. It is important - * to know which period we are in so we can calculate the correct pointer. - * This is why we always use 2 periods. We can then use a flip-flop variable - * to keep track of what period we are in. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -/* snd_als300_set_irq_flag */ -#define IRQ_DISABLE 0 -#define IRQ_ENABLE 1 - -/* I/O port layout */ -#define AC97_ACCESS 0x00 -#define AC97_READ 0x04 -#define AC97_STATUS 0x06 -#define AC97_DATA_AVAIL (1<<6) -#define AC97_BUSY (1<<7) -#define ALS300_IRQ_STATUS 0x07 /* ALS300 Only */ -#define IRQ_PLAYBACK (1<<3) -#define IRQ_CAPTURE (1<<2) -#define GCR_DATA 0x08 -#define GCR_INDEX 0x0C -#define ALS300P_DRAM_IRQ_STATUS 0x0D /* ALS300+ Only */ -#define MPU_IRQ_STATUS 0x0E /* ALS300 Rev. E+, ALS300+ */ -#define ALS300P_IRQ_STATUS 0x0F /* ALS300+ Only */ - -/* General Control Registers */ -#define PLAYBACK_START 0x80 -#define PLAYBACK_END 0x81 -#define PLAYBACK_CONTROL 0x82 -#define TRANSFER_START (1<<16) -#define FIFO_PAUSE (1<<17) -#define RECORD_START 0x83 -#define RECORD_END 0x84 -#define RECORD_CONTROL 0x85 -#define DRAM_WRITE_CONTROL 0x8B -#define WRITE_TRANS_START (1<<16) -#define DRAM_MODE_2 (1<<17) -#define MISC_CONTROL 0x8C -#define IRQ_SET_BIT (1<<15) -#define VMUTE_NORMAL (1<<20) -#define MMUTE_NORMAL (1<<21) -#define MUS_VOC_VOL 0x8E -#define PLAYBACK_BLOCK_COUNTER 0x9A -#define RECORD_BLOCK_COUNTER 0x9B - -#define DEBUG_CALLS 1 -#define DEBUG_PLAY_REC 1 - -#if DEBUG_CALLS -#define snd_als300_dbgcalls(format, args...) printk(format, ##args) -#define snd_als300_dbgcallenter() printk(KERN_ERR "--> %s\n", __FUNCTION__) -#define snd_als300_dbgcallleave() printk(KERN_ERR "<-- %s\n", __FUNCTION__) -#else -#define snd_als300_dbgcalls(format, args...) -#define snd_als300_dbgcallenter() -#define snd_als300_dbgcallleave() -#endif - -#if DEBUG_PLAY_REC -#define snd_als300_dbgplay(format, args...) printk(KERN_ERR format, ##args) -#else -#define snd_als300_dbgplay(format, args...) -#endif - -enum {DEVICE_ALS300, DEVICE_ALS300_PLUS}; - -MODULE_AUTHOR("Ash Willis "); -MODULE_DESCRIPTION("Avance Logic ALS300"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS300},{Avance Logic,ALS300+}}"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; - -struct snd_als300 { - unsigned long port; - spinlock_t reg_lock; - struct snd_card *card; - struct pci_dev *pci; - - struct snd_pcm *pcm; - struct snd_pcm_substream *playback_substream; - struct snd_pcm_substream *capture_substream; - - struct snd_ac97 *ac97; - struct snd_opl3 *opl3; - - struct resource *res_port; - - int irq; - - int chip_type; /* ALS300 or ALS300+ */ - - char revision; -}; - -struct snd_als300_substream_data { - int period_flipflop; - int control_register; - int block_counter_register; -}; - -static struct pci_device_id snd_als300_ids[] __devinitdata = { - { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 }, - { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS }, - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, snd_als300_ids); - -static inline u32 snd_als300_gcr_read(unsigned long port, unsigned short reg) -{ - outb(reg, port+GCR_INDEX); - return inl(port+GCR_DATA); -} - -static inline void snd_als300_gcr_write(unsigned long port, - unsigned short reg, u32 val) -{ - outb(reg, port+GCR_INDEX); - outl(val, port+GCR_DATA); -} - -/* Enable/Disable Interrupts */ -static void snd_als300_set_irq_flag(struct snd_als300 *chip, int cmd) -{ - u32 tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL); - snd_als300_dbgcallenter(); - - /* boolean XOR check, since old vs. new hardware have - directly reversed bit setting for ENABLE and DISABLE. - ALS300+ acts like newer versions of ALS300 */ - if (((chip->revision > 5 || chip->chip_type == DEVICE_ALS300_PLUS) ^ - (cmd == IRQ_ENABLE)) == 0) - tmp |= IRQ_SET_BIT; - else - tmp &= ~IRQ_SET_BIT; - snd_als300_gcr_write(chip->port, MISC_CONTROL, tmp); - snd_als300_dbgcallleave(); -} - -static int snd_als300_free(struct snd_als300 *chip) -{ - snd_als300_dbgcallenter(); - snd_als300_set_irq_flag(chip, IRQ_DISABLE); - if (chip->irq >= 0) - free_irq(chip->irq, (void *)chip); - pci_release_regions(chip->pci); - pci_disable_device(chip->pci); - kfree(chip); - snd_als300_dbgcallleave(); - return 0; -} - -static int snd_als300_dev_free(struct snd_device *device) -{ - struct snd_als300 *chip = device->device_data; - return snd_als300_free(chip); -} - -static irqreturn_t snd_als300_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - u8 status; - struct snd_als300 *chip = dev_id; - struct snd_als300_substream_data *data; - - status = inb(chip->port+ALS300_IRQ_STATUS); - if (!status) /* shared IRQ, for different device?? Exit ASAP! */ - return IRQ_NONE; - - /* ACK everything ASAP */ - outb(status, chip->port+ALS300_IRQ_STATUS); - if (status & IRQ_PLAYBACK) { - if (chip->pcm && chip->playback_substream) { - data = chip->playback_substream->runtime->private_data; - data->period_flipflop ^= 1; - snd_pcm_period_elapsed(chip->playback_substream); - snd_als300_dbgplay("IRQ_PLAYBACK\n"); - } - } - if (status & IRQ_CAPTURE) { - if (chip->pcm && chip->capture_substream) { - data = chip->capture_substream->runtime->private_data; - data->period_flipflop ^= 1; - snd_pcm_period_elapsed(chip->capture_substream); - snd_als300_dbgplay("IRQ_CAPTURE\n"); - } - } - return IRQ_HANDLED; -} - -static irqreturn_t snd_als300plus_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - u8 general, mpu, dram; - struct snd_als300 *chip = dev_id; - struct snd_als300_substream_data *data; - - general = inb(chip->port+ALS300P_IRQ_STATUS); - mpu = inb(chip->port+MPU_IRQ_STATUS); - dram = inb(chip->port+ALS300P_DRAM_IRQ_STATUS); - - /* shared IRQ, for different device?? Exit ASAP! */ - if ((general == 0) && ((mpu & 0x80) == 0) && ((dram & 0x01) == 0)) - return IRQ_NONE; - - if (general & IRQ_PLAYBACK) { - if (chip->pcm && chip->playback_substream) { - outb(IRQ_PLAYBACK, chip->port+ALS300P_IRQ_STATUS); - data = chip->playback_substream->runtime->private_data; - data->period_flipflop ^= 1; - snd_pcm_period_elapsed(chip->playback_substream); - snd_als300_dbgplay("IRQ_PLAYBACK\n"); - } - } - if (general & IRQ_CAPTURE) { - if (chip->pcm && chip->capture_substream) { - outb(IRQ_CAPTURE, chip->port+ALS300P_IRQ_STATUS); - data = chip->capture_substream->runtime->private_data; - data->period_flipflop ^= 1; - snd_pcm_period_elapsed(chip->capture_substream); - snd_als300_dbgplay("IRQ_CAPTURE\n"); - } - } - /* FIXME: Ack other interrupt types. Not important right now as - * those other devices aren't enabled. */ - return IRQ_HANDLED; -} - -static void __devexit snd_als300_remove(struct pci_dev *pci) -{ - snd_als300_dbgcallenter(); - snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); - snd_als300_dbgcallleave(); -} - -static unsigned short snd_als300_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - int i; - struct snd_als300 *chip = ac97->private_data; - - for (i = 0; i < 1000; i++) { - if ((inb(chip->port+AC97_STATUS) & (AC97_BUSY)) == 0) - break; - udelay(10); - } - outl((reg << 24) | (1 << 31), chip->port+AC97_ACCESS); - - for (i = 0; i < 1000; i++) { - if ((inb(chip->port+AC97_STATUS) & (AC97_DATA_AVAIL)) != 0) - break; - udelay(10); - } - return inw(chip->port+AC97_READ); -} - -static void snd_als300_ac97_write(struct snd_ac97 *ac97, - unsigned short reg, unsigned short val) -{ - int i; - struct snd_als300 *chip = ac97->private_data; - - for (i = 0; i < 1000; i++) { - if ((inb(chip->port+AC97_STATUS) & (AC97_BUSY)) == 0) - break; - udelay(10); - } - outl((reg << 24) | val, chip->port+AC97_ACCESS); -} - -static int snd_als300_ac97(struct snd_als300 *chip) -{ - struct snd_ac97_bus *bus; - struct snd_ac97_template ac97; - int err; - static struct snd_ac97_bus_ops ops = { - .write = snd_als300_ac97_write, - .read = snd_als300_ac97_read, - }; - - snd_als300_dbgcallenter(); - if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus)) < 0) - return err; - - memset(&ac97, 0, sizeof(ac97)); - ac97.private_data = chip; - - snd_als300_dbgcallleave(); - return snd_ac97_mixer(bus, &ac97, &chip->ac97); -} - -/* hardware definition - * - * In AC97 mode, we always use 48k/16bit/stereo. - * Any request to change data type is ignored by - * the card when it is running outside of legacy - * mode. - */ -static struct snd_pcm_hardware snd_als300_playback_hw = -{ - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_S16, - .rates = SNDRV_PCM_RATE_48000, - .rate_min = 48000, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = 64 * 1024, - .period_bytes_min = 64, - .period_bytes_max = 32 * 1024, - .periods_min = 2, - .periods_max = 2, -}; - -static struct snd_pcm_hardware snd_als300_capture_hw = -{ - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_S16, - .rates = SNDRV_PCM_RATE_48000, - .rate_min = 48000, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = 64 * 1024, - .period_bytes_min = 64, - .period_bytes_max = 32 * 1024, - .periods_min = 2, - .periods_max = 2, -}; - -static int snd_als300_playback_open(struct snd_pcm_substream *substream) -{ - struct snd_als300 *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_als300_substream_data *data = kzalloc(sizeof(*data), - GFP_KERNEL); - - snd_als300_dbgcallenter(); - chip->playback_substream = substream; - runtime->hw = snd_als300_playback_hw; - runtime->private_data = data; - data->control_register = PLAYBACK_CONTROL; - data->block_counter_register = PLAYBACK_BLOCK_COUNTER; - snd_als300_dbgcallleave(); - return 0; -} - -static int snd_als300_playback_close(struct snd_pcm_substream *substream) -{ - struct snd_als300 *chip = snd_pcm_substream_chip(substream); - struct snd_als300_substream_data *data; - - data = substream->runtime->private_data; - snd_als300_dbgcallenter(); - kfree(data); - chip->playback_substream = NULL; - snd_pcm_lib_free_pages(substream); - snd_als300_dbgcallleave(); - return 0; -} - -static int snd_als300_capture_open(struct snd_pcm_substream *substream) -{ - struct snd_als300 *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_als300_substream_data *data = kzalloc(sizeof(*data), - GFP_KERNEL); - - snd_als300_dbgcallenter(); - chip->capture_substream = substream; - runtime->hw = snd_als300_capture_hw; - runtime->private_data = data; - data->control_register = RECORD_CONTROL; - data->block_counter_register = RECORD_BLOCK_COUNTER; - snd_als300_dbgcallleave(); - return 0; -} - -static int snd_als300_capture_close(struct snd_pcm_substream *substream) -{ - struct snd_als300 *chip = snd_pcm_substream_chip(substream); - struct snd_als300_substream_data *data; - - data = substream->runtime->private_data; - snd_als300_dbgcallenter(); - kfree(data); - chip->capture_substream = NULL; - snd_pcm_lib_free_pages(substream); - snd_als300_dbgcallleave(); - return 0; -} - -static int snd_als300_pcm_hw_params(struct snd_pcm_substream *substream, - snd_pcm_hw_params_t * hw_params) -{ - return snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); -} - -static int snd_als300_pcm_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int snd_als300_playback_prepare(struct snd_pcm_substream *substream) -{ - u32 tmp; - struct snd_als300 *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned short period_bytes = snd_pcm_lib_period_bytes(substream); - unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream); - - snd_als300_dbgcallenter(); - spin_lock_irq(&chip->reg_lock); - tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL); - tmp &= ~TRANSFER_START; - - snd_als300_dbgplay("Period bytes: %d Buffer bytes %d\n", - period_bytes, buffer_bytes); - - /* set block size */ - tmp &= 0xffff0000; - tmp |= period_bytes - 1; - snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL, tmp); - - /* set dma area */ - snd_als300_gcr_write(chip->port, PLAYBACK_START, - runtime->dma_addr); - snd_als300_gcr_write(chip->port, PLAYBACK_END, - runtime->dma_addr + buffer_bytes - 1); - spin_unlock_irq(&chip->reg_lock); - snd_als300_dbgcallleave(); - return 0; -} - -static int snd_als300_capture_prepare(struct snd_pcm_substream *substream) -{ - u32 tmp; - struct snd_als300 *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned short period_bytes = snd_pcm_lib_period_bytes(substream); - unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream); - - snd_als300_dbgcallenter(); - spin_lock_irq(&chip->reg_lock); - tmp = snd_als300_gcr_read(chip->port, RECORD_CONTROL); - tmp &= ~TRANSFER_START; - - snd_als300_dbgplay("Period bytes: %d Buffer bytes %d\n", period_bytes, - buffer_bytes); - - /* set block size */ - tmp &= 0xffff0000; - tmp |= period_bytes - 1; - - /* set dma area */ - snd_als300_gcr_write(chip->port, RECORD_CONTROL, tmp); - snd_als300_gcr_write(chip->port, RECORD_START, - runtime->dma_addr); - snd_als300_gcr_write(chip->port, RECORD_END, - runtime->dma_addr + buffer_bytes - 1); - spin_unlock_irq(&chip->reg_lock); - snd_als300_dbgcallleave(); - return 0; -} - -static int snd_als300_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_als300 *chip = snd_pcm_substream_chip(substream); - u32 tmp; - struct snd_als300_substream_data *data; - unsigned short reg; - int ret = 0; - - data = substream->runtime->private_data; - reg = data->control_register; - - snd_als300_dbgcallenter(); - spin_lock(&chip->reg_lock); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - tmp = snd_als300_gcr_read(chip->port, reg); - data->period_flipflop = 1; - snd_als300_gcr_write(chip->port, reg, tmp | TRANSFER_START); - snd_als300_dbgplay("TRIGGER START\n"); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - tmp = snd_als300_gcr_read(chip->port, reg); - snd_als300_gcr_write(chip->port, reg, tmp & ~TRANSFER_START); - snd_als300_dbgplay("TRIGGER STOP\n"); - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - tmp = snd_als300_gcr_read(chip->port, reg); - snd_als300_gcr_write(chip->port, reg, tmp | FIFO_PAUSE); - snd_als300_dbgplay("TRIGGER PAUSE\n"); - break; - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - tmp = snd_als300_gcr_read(chip->port, reg); - snd_als300_gcr_write(chip->port, reg, tmp & ~FIFO_PAUSE); - snd_als300_dbgplay("TRIGGER RELEASE\n"); - break; - default: - snd_als300_dbgplay("TRIGGER INVALID\n"); - ret = -EINVAL; - } - spin_unlock(&chip->reg_lock); - snd_als300_dbgcallleave(); - return ret; -} - -static snd_pcm_uframes_t snd_als300_pointer(struct snd_pcm_substream *substream) -{ - u16 current_ptr; - struct snd_als300 *chip = snd_pcm_substream_chip(substream); - struct snd_als300_substream_data *data; - unsigned short period_bytes; - - data = substream->runtime->private_data; - period_bytes = snd_pcm_lib_period_bytes(substream); - - snd_als300_dbgcallenter(); - spin_lock(&chip->reg_lock); - current_ptr = (u16) snd_als300_gcr_read(chip->port, - data->block_counter_register) + 4; - spin_unlock(&chip->reg_lock); - if (current_ptr > period_bytes) - current_ptr = 0; - else - current_ptr = period_bytes - current_ptr; - - if (data->period_flipflop == 0) - current_ptr += period_bytes; - snd_als300_dbgplay("Pointer (bytes): %d\n", current_ptr); - snd_als300_dbgcallleave(); - return bytes_to_frames(substream->runtime, current_ptr); -} - -static struct snd_pcm_ops snd_als300_playback_ops = { - .open = snd_als300_playback_open, - .close = snd_als300_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_als300_pcm_hw_params, - .hw_free = snd_als300_pcm_hw_free, - .prepare = snd_als300_playback_prepare, - .trigger = snd_als300_trigger, - .pointer = snd_als300_pointer, -}; - -static struct snd_pcm_ops snd_als300_capture_ops = { - .open = snd_als300_capture_open, - .close = snd_als300_capture_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_als300_pcm_hw_params, - .hw_free = snd_als300_pcm_hw_free, - .prepare = snd_als300_capture_prepare, - .trigger = snd_als300_trigger, - .pointer = snd_als300_pointer, -}; - -static int __devinit snd_als300_new_pcm(struct snd_als300 *chip) -{ - struct snd_pcm *pcm; - int err; - - snd_als300_dbgcallenter(); - err = snd_pcm_new(chip->card, "ALS300", 0, 1, 1, &pcm); - if (err < 0) - return err; - pcm->private_data = chip; - strcpy(pcm->name, "ALS300"); - chip->pcm = pcm; - - /* set operators */ - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_als300_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &snd_als300_capture_ops); - - /* pre-allocation of buffers */ - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), 64*1024, 64*1024); - snd_als300_dbgcallleave(); - return 0; -} - -static void snd_als300_init(struct snd_als300 *chip) -{ - unsigned long flags; - u32 tmp; - - snd_als300_dbgcallenter(); - spin_lock_irqsave(&chip->reg_lock, flags); - chip->revision = (snd_als300_gcr_read(chip->port, MISC_CONTROL) >> 16) - & 0x0000000F; - /* Setup DRAM */ - tmp = snd_als300_gcr_read(chip->port, DRAM_WRITE_CONTROL); - snd_als300_gcr_write(chip->port, DRAM_WRITE_CONTROL, - (tmp | DRAM_MODE_2) - & ~WRITE_TRANS_START); - - /* Enable IRQ output */ - snd_als300_set_irq_flag(chip, IRQ_ENABLE); - - /* Unmute hardware devices so their outputs get routed to - * the onboard mixer */ - tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL); - snd_als300_gcr_write(chip->port, MISC_CONTROL, - tmp | VMUTE_NORMAL | MMUTE_NORMAL); - - /* Reset volumes */ - snd_als300_gcr_write(chip->port, MUS_VOC_VOL, 0); - - /* Make sure playback transfer is stopped */ - tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL); - snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL, - tmp & ~TRANSFER_START); - spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_als300_dbgcallleave(); -} - -static int __devinit snd_als300_create(snd_card_t *card, - struct pci_dev *pci, int chip_type, - struct snd_als300 **rchip) -{ - struct snd_als300 *chip; - void *irq_handler; - int err; - - static snd_device_ops_t ops = { - .dev_free = snd_als300_dev_free, - }; - *rchip = NULL; - - snd_als300_dbgcallenter(); - 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) { - printk(KERN_ERR "error setting 28bit DMA mask\n"); - pci_disable_device(pci); - return -ENXIO; - } - pci_set_master(pci); - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } - - chip->card = card; - chip->pci = pci; - chip->irq = -1; - chip->chip_type = chip_type; - spin_lock_init(&chip->reg_lock); - - if ((err = pci_request_regions(pci, "ALS300")) < 0) { - kfree(chip); - pci_disable_device(pci); - return err; - } - chip->port = pci_resource_start(pci, 0); - - if (chip->chip_type == DEVICE_ALS300_PLUS) - irq_handler = snd_als300plus_interrupt; - else - irq_handler = snd_als300_interrupt; - - if (request_irq(pci->irq, irq_handler, SA_INTERRUPT|SA_SHIRQ, - card->shortname, (void *)chip)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); - snd_als300_free(chip); - return -EBUSY; - } - chip->irq = pci->irq; - - - snd_als300_init(chip); - - if (snd_als300_ac97(chip) < 0) { - snd_printk(KERN_WARNING "Could not create ac97\n"); - snd_als300_free(chip); - return err; - } - - if ((err = snd_als300_new_pcm(chip)) < 0) { - snd_printk(KERN_WARNING "Could not create PCM\n"); - snd_als300_free(chip); - return err; - } - - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, - chip, &ops)) < 0) { - snd_als300_free(chip); - return err; - } - - snd_card_set_dev(card, &pci->dev); - - *rchip = chip; - snd_als300_dbgcallleave(); - return 0; -} - -#ifdef CONFIG_PM -static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state) -{ - struct snd_card *card = pci_get_drvdata(pci); - struct snd_als300 *chip = card->private_data; - - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); - snd_ac97_suspend(chip->ac97); - - pci_set_power_state(pci, PCI_D3hot); - pci_disable_device(pci); - pci_save_state(pci); - return 0; -} - -static int snd_als300_resume(struct pci_dev *pci) -{ - struct snd_card *card = pci_get_drvdata(pci); - struct snd_als300 *chip = card->private_data; - - pci_restore_state(pci); - pci_enable_device(pci); - pci_set_power_state(pci, PCI_D0); - pci_set_master(pci); - - snd_als300_init(chip); - snd_ac97_resume(chip->ac97); - - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - return 0; -} -#endif - -static int __devinit snd_als300_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - static int dev; - struct snd_card *card; - struct snd_als300 *chip; - int err, chip_type; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - - if (card == NULL) - return -ENOMEM; - - chip_type = pci_id->driver_data; - - if ((err = snd_als300_create(card, pci, chip_type, &chip)) < 0) { - snd_card_free(card); - return err; - } - card->private_data = chip; - - strcpy(card->driver, "ALS300"); - if (chip->chip_type == DEVICE_ALS300_PLUS) - /* don't know much about ALS300+ yet - * print revision number for now */ - sprintf(card->shortname, "ALS300+ (Rev. %d)", chip->revision); - else - sprintf(card->shortname, "ALS300 (Rev. %c)", 'A' + - chip->revision - 1); - sprintf(card->longname, "%s at 0x%lx irq %i", - card->shortname, chip->port, chip->irq); - - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } - pci_set_drvdata(pci, card); - dev++; - return 0; -} - -static struct pci_driver driver = { - .name = "ALS300", - .id_table = snd_als300_ids, - .probe = snd_als300_probe, - .remove = __devexit_p(snd_als300_remove), -#ifdef CONFIG_PM - .suspend = snd_als300_suspend, - .resume = snd_als300_resume, -#endif -}; - -static int __init alsa_card_als300_init(void) -{ - return pci_register_driver(&driver); -} - -static void __exit alsa_card_als300_exit(void) -{ - pci_unregister_driver(&driver); -} - -module_init(alsa_card_als300_init) -module_exit(alsa_card_als300_exit) diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 60423b1c6..7b2ff5f46 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -70,7 +70,6 @@ #include #include #include -#include #include #include #include @@ -116,7 +115,7 @@ struct snd_card_als4000 { #endif }; -static struct pci_device_id snd_als4000_ids[] __devinitdata = { +static struct pci_device_id snd_als4000_ids[] = { { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */ { 0, } }; @@ -689,8 +688,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, 0x00ffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x00ffffff) < 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/atiixp.c b/sound/pci/atiixp.c index d0f759d86..b7217adaf 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -278,13 +277,13 @@ struct atiixp { unsigned int codec_not_ready_bits; /* for codec detection */ int spdif_over_aclink; /* passed from the module option */ - struct mutex open_mutex; /* playback open mutex */ + struct semaphore open_mutex; /* playback open mutex */ }; /* */ -static struct pci_device_id snd_atiixp_ids[] __devinitdata = { +static struct pci_device_id snd_atiixp_ids[] = { { 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ { 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */ { 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */ @@ -1052,9 +1051,9 @@ static int snd_atiixp_playback_open(struct snd_pcm_substream *substream) struct atiixp *chip = snd_pcm_substream_chip(substream); int err; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0); - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); if (err < 0) return err; substream->runtime->hw.channels_max = chip->max_channels; @@ -1069,9 +1068,9 @@ static int snd_atiixp_playback_close(struct snd_pcm_substream *substream) { struct atiixp *chip = snd_pcm_substream_chip(substream); int err; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return err; } @@ -1091,12 +1090,12 @@ static int snd_atiixp_spdif_open(struct snd_pcm_substream *substream) { struct atiixp *chip = snd_pcm_substream_chip(substream); int err; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); if (chip->spdif_over_aclink) /* share DMA_PLAYBACK */ err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2); else err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1); - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return err; } @@ -1104,12 +1103,12 @@ static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream) { struct atiixp *chip = snd_pcm_substream_chip(substream); int err; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); if (chip->spdif_over_aclink) err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); else err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]); - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return err; } @@ -1561,7 +1560,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card, } spin_lock_init(&chip->reg_lock); - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->open_mutex); chip->card = card; chip->pci = pci; chip->irq = -1; diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 12a34c39c..8d8fd5a4e 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -256,13 +255,13 @@ struct atiixp_modem { unsigned int codec_not_ready_bits; /* for codec detection */ int spdif_over_aclink; /* passed from the module option */ - struct mutex open_mutex; /* playback open mutex */ + struct semaphore open_mutex; /* playback open mutex */ }; /* */ -static struct pci_device_id snd_atiixp_ids[] __devinitdata = { +static struct pci_device_id snd_atiixp_ids[] = { { 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ { 0x1002, 0x4378, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */ { 0, } @@ -912,9 +911,9 @@ static int snd_atiixp_playback_open(struct snd_pcm_substream *substream) struct atiixp_modem *chip = snd_pcm_substream_chip(substream); int err; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0); - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); if (err < 0) return err; return 0; @@ -924,9 +923,9 @@ static int snd_atiixp_playback_close(struct snd_pcm_substream *substream) { struct atiixp_modem *chip = snd_pcm_substream_chip(substream); int err; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return err; } @@ -1234,7 +1233,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card, } spin_lock_init(&chip->reg_lock); - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->open_mutex); chip->card = card; chip->pci = pci; chip->irq = -1; diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c index bd3352998..fce22c7af 100644 --- a/sound/pci/au88x0/au8810.c +++ b/sound/pci/au88x0/au8810.c @@ -1,6 +1,6 @@ #include "au8810.h" #include "au88x0.h" -static struct pci_device_id snd_vortex_ids[] __devinitdata = { +static struct pci_device_id snd_vortex_ids[] = { {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1,}, {0,} diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c index 7e3fd8372..d1fbcce07 100644 --- a/sound/pci/au88x0/au8820.c +++ b/sound/pci/au88x0/au8820.c @@ -1,6 +1,6 @@ #include "au8820.h" #include "au88x0.h" -static struct pci_device_id snd_vortex_ids[] __devinitdata = { +static struct pci_device_id snd_vortex_ids[] = { {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, {0,} diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c index b840f6608..d4f2717c1 100644 --- a/sound/pci/au88x0/au8830.c +++ b/sound/pci/au88x0/au8830.c @@ -1,6 +1,6 @@ #include "au8830.h" #include "au88x0.h" -static struct pci_device_id snd_vortex_ids[] __devinitdata = { +static struct pci_device_id snd_vortex_ids[] = { {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, {0,} diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 126870ec0..7d9184f73 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -151,18 +151,14 @@ 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_32BIT_MASK)) { printk(KERN_ERR "error to set DMA mask\n"); - pci_disable_device(pci); return -ENXIO; } chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - pci_disable_device(pci); + if (chip == NULL) return -ENOMEM; - } chip->card = card; @@ -212,8 +208,6 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) goto alloc_out; } - snd_card_set_dev(card, &pci->dev); - *rchip = chip; return 0; diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index f078b716d..c2ad2674b 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h @@ -19,6 +19,7 @@ #ifdef __KERNEL__ #include +#include #include #include #include @@ -38,8 +39,8 @@ #include "au88x0_wt.h" #endif -#define hwread(x,y) readl((x)+(y)) -#define hwwrite(x,y,z) writel((z),(x)+(y)) +#define hwread(x,y) readl((x)+((y)>>2)) +#define hwwrite(x,y,z) writel((z),(x)+((y)>>2)) /* Vortex MPU401 defines. */ #define MIDI_CLOCK_DIV 0x61 @@ -112,7 +113,7 @@ typedef struct { //int this_08; /* Still unknown */ int fifo_enabled; /* this_24 */ int fifo_status; /* this_1c */ - u32 dma_ctrl; /* this_78 (ADB), this_7c (WT) */ + int dma_ctrl; /* this_78 (ADB), this_7c (WT) */ int dma_unknown; /* this_74 (ADB), this_78 (WT). WDM: +8 */ int cfg0; int cfg1; @@ -177,7 +178,7 @@ struct snd_vortex { /* PCI hardware resources */ unsigned long io; - void __iomem *mmio; + unsigned long __iomem *mmio; unsigned int irq; spinlock_t lock; @@ -200,14 +201,14 @@ static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, int count); static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir, int fmt, int d, - u32 offset); + unsigned long offset); static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb); #ifndef CHIP_AU8810 static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, struct snd_sg_buf * sgbuf, int size, int count); static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */ - u32 offset); + unsigned long offset); static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb); #endif @@ -276,14 +277,14 @@ static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en); #endif /* Driver stuff. */ -static int vortex_gameport_register(vortex_t * card); +static int __devinit vortex_gameport_register(vortex_t * card); static void vortex_gameport_unregister(vortex_t * card); #ifndef CHIP_AU8820 -static int vortex_eq_init(vortex_t * vortex); -static int vortex_eq_free(vortex_t * vortex); +static int __devinit vortex_eq_init(vortex_t * vortex); +static int __devexit vortex_eq_free(vortex_t * vortex); #endif /* ALSA stuff. */ -static int snd_vortex_new_pcm(vortex_t * vortex, int idx, int nr); -static int snd_vortex_mixer(vortex_t * vortex); -static int snd_vortex_midi(vortex_t * vortex); +static int __devinit snd_vortex_new_pcm(vortex_t * vortex, int idx, int nr); +static int __devinit snd_vortex_mixer(vortex_t * vortex); +static int __devinit snd_vortex_midi(vortex_t * vortex); #endif diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 4347e6abc..e3394fe63 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -376,7 +376,7 @@ vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch) static void vortex_mixer_init(vortex_t * vortex) { - u32 addr; + unsigned long addr; int x; // FIXME: get rid of this crap. @@ -639,7 +639,7 @@ static void vortex_src_setupchannel(vortex_t * card, unsigned char src, static void vortex_srcblock_init(vortex_t * vortex) { - u32 addr; + unsigned long addr; int x; hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff); /* @@ -1035,7 +1035,7 @@ vortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority, static void vortex_fifo_init(vortex_t * vortex) { int x; - u32 addr; + unsigned long addr; /* ADB DMA channels fifos. */ addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4); @@ -1054,7 +1054,7 @@ static void vortex_fifo_init(vortex_t * vortex) hwwrite(vortex->mmio, addr, FIFO_U0); if (hwread(vortex->mmio, addr) != FIFO_U0) printk(KERN_ERR - "bad wt fifo reset (0x%08x, 0x%08x)!\n", + "bad wt fifo reset (0x%08lx, 0x%08x)!\n", addr, hwread(vortex->mmio, addr)); vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE); addr -= 4; @@ -1152,7 +1152,7 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir, - int fmt, int d, u32 offset) + int fmt, int d, unsigned long offset) { stream_t *dma = &vortex->dma_adb[adbdma]; @@ -1411,7 +1411,7 @@ vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, - /*int e, */ u32 offset) + /*int e, */ unsigned long offset) { stream_t *dma = &vortex->dma_wt[wtdma]; @@ -2658,7 +2658,7 @@ static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode) /* Initialization */ -static int __devinit vortex_core_init(vortex_t * vortex) +static int vortex_core_init(vortex_t * vortex) { printk(KERN_INFO "Vortex: init.... "); diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c index 0c86a31c4..c8280f82e 100644 --- a/sound/pci/au88x0/au88x0_eq.c +++ b/sound/pci/au88x0/au88x0_eq.c @@ -377,23 +377,23 @@ static void vortex_EqHw_GetLevels(vortex_t * vortex, u16 a[]) #endif /* Global Control */ -static void vortex_EqHw_SetControlReg(vortex_t * vortex, u32 reg) +static void vortex_EqHw_SetControlReg(vortex_t * vortex, unsigned long reg) { hwwrite(vortex->mmio, 0x2b440, reg); } -static void vortex_EqHw_SetSampleRate(vortex_t * vortex, u32 sr) +static void vortex_EqHw_SetSampleRate(vortex_t * vortex, int sr) { hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800); } #if 0 -static void vortex_EqHw_GetControlReg(vortex_t * vortex, u32 *reg) +static void vortex_EqHw_GetControlReg(vortex_t * vortex, unsigned long *reg) { *reg = hwread(vortex->mmio, 0x2b440); } -static void vortex_EqHw_GetSampleRate(vortex_t * vortex, u32 *sr) +static void vortex_EqHw_GetSampleRate(vortex_t * vortex, int *sr) { *sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f; } @@ -554,7 +554,7 @@ static void vortex_Eqlzr_SetRightGain(vortex_t * vortex, u16 index, u16 gain) #if 0 static int -vortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, s32 *cnt) +vortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, unsigned long *cnt) { eqlzr_t *eq = &(vortex->eq); int si = 0; @@ -586,7 +586,7 @@ static int vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex_t * vortex) } static int -vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], s32 count) +vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], unsigned long count) { eqlzr_t *eq = &(vortex->eq); int i; @@ -604,10 +604,11 @@ vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], s32 count) } static void -vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, u32 a, u32 b) +vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, unsigned long a, + unsigned long b) { eqlzr_t *eq = &(vortex->eq); - u32 eax, ebx; + int eax, ebx; eq->this58 = a; eq->this5c = b; @@ -623,7 +624,7 @@ vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, u32 a, u32 b) static void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex) { eqlzr_t *eq = &(vortex->eq); - u32 eax, ebx; + int eax, ebx; if (eq->this54) eax = eq->this0e; @@ -640,7 +641,7 @@ static void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex) vortex_EqHw_ZeroA3DIO(vortex); } -static void vortex_Eqlzr_SetBypass(vortex_t * vortex, u32 bp) +static void vortex_Eqlzr_SetBypass(vortex_t * vortex, long bp) { eqlzr_t *eq = &(vortex->eq); @@ -650,8 +651,8 @@ static void vortex_Eqlzr_SetBypass(vortex_t * vortex, u32 bp) vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08); } else { /* EQ disabled. */ - vortex_EqHw_SetLeftGainsTarget(vortex, eq->this14_array); - vortex_EqHw_SetRightGainsTarget(vortex, eq->this14_array); + vortex_EqHw_SetLeftGainsTarget(vortex, (u16 *) (eq->this14)); + vortex_EqHw_SetRightGainsTarget(vortex, (u16 *) (eq->this14)); vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c); } vortex_Eqlzr_ProgramA3dBypassGain(vortex); @@ -705,7 +706,7 @@ static void vortex_Eqlzr_init(vortex_t * vortex) eq->this5c = 0xffff; /* Set gains. */ - memset(eq->this14_array, 0, sizeof(eq->this14_array)); + memset(eq->this14, 0, 2 * 10); /* Actual init. */ vortex_EqHw_ZeroState(vortex); @@ -791,7 +792,7 @@ snd_vortex_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucon { vortex_t *vortex = snd_kcontrol_chip(kcontrol); int i = kcontrol->private_value; - u16 gainL = 0, gainR = 0; + u16 gainL, gainR; vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); vortex_Eqlzr_GetRightGain(vortex, i, &gainR); @@ -805,7 +806,7 @@ snd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucon { vortex_t *vortex = snd_kcontrol_chip(kcontrol); int changed = 0, i = kcontrol->private_value; - u16 gainL = 0, gainR = 0; + u16 gainL, gainR; vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); vortex_Eqlzr_GetRightGain(vortex, i, &gainR); @@ -885,7 +886,7 @@ static char *EqBandLabels[10] __devinitdata = { }; /* ALSA driver entry points. Init and exit. */ -static int __devinit vortex_eq_init(vortex_t * vortex) +static int vortex_eq_init(vortex_t * vortex) { struct snd_kcontrol *kcontrol; int err, i; diff --git a/sound/pci/au88x0/au88x0_eq.h b/sound/pci/au88x0/au88x0_eq.h index 474cd0046..e49bc625c 100644 --- a/sound/pci/au88x0/au88x0_eq.h +++ b/sound/pci/au88x0/au88x0_eq.h @@ -13,28 +13,31 @@ typedef struct { u16 LeftCoefs[50]; //0x4 u16 RightCoefs[50]; // 0x68 - u16 LeftGains[10]; //0xd0 - u16 RightGains[10]; //0xe4 + u16 LeftGains[20]; //0xd0 + u16 RightGains[20]; //0xe4 } auxxEqCoeffSet_t; typedef struct { - s32 this04; /* How many filters for each side (default = 10) */ - s32 this08; /* inited to cero. Stereo flag? */ + unsigned int *this00; /*CAsp4HwIO */ + long this04; /* How many filters for each side (default = 10) */ + long this08; /* inited to cero. Stereo flag? */ } eqhw_t; typedef struct { + unsigned int *this00; /*CAsp4Core */ eqhw_t this04; /* CHwEq */ - u16 this08; /* Bad codec flag ? SetBypassGain: bypass gain */ - u16 this0a; - u16 this0c; /* SetBypassGain: bypass gain when this28 is not set. */ - u16 this0e; + short this08; /* Bad codec flag ? SetBypassGain: bypass gain */ + short this0a; + short this0c; /* SetBypassGain: bypass gain when this28 is not set. */ + short this0e; - s32 this10; /* How many gains are used for each side (right or left). */ - u16 this14_array[10]; /* SetLeftGainsTarget: Left (and right?) EQ gains */ - s32 this28; /* flag related to EQ enabled or not. Gang flag ? */ - s32 this54; /* SetBypass */ - s32 this58; - s32 this5c; + long this10; /* How many gains are used for each side (right or left). */ + u16 this14[32]; /* SetLeftGainsTarget: Left (and right?) EQ gains */ + long this24; + long this28; /* flag related to EQ enabled or not. Gang flag ? */ + long this54; /* SetBypass */ + long this58; + long this5c; /*0x60 */ auxxEqCoeffSet_t coefset; /* 50 u16 word each channel. */ u16 this130[20]; /* Left and Right gains */ diff --git a/sound/pci/au88x0/au88x0_eqdata.c b/sound/pci/au88x0/au88x0_eqdata.c index ce8dca8ce..abf8d6ac4 100644 --- a/sound/pci/au88x0/au88x0_eqdata.c +++ b/sound/pci/au88x0/au88x0_eqdata.c @@ -104,11 +104,7 @@ static u16 asEqOutStateZeros[48] = { }; /*_rodataba0:*/ -static u16 eq_levels[64] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +static long eq_levels[32] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c index 118dcc71e..82aec9112 100644 --- a/sound/pci/au88x0/au88x0_mpu401.c +++ b/sound/pci/au88x0/au88x0_mpu401.c @@ -95,7 +95,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex) return temp; } #else - port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA); + port = (unsigned long)(vortex->mmio + (VORTEX_MIDI_DATA >> 2)); if ((temp = snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port, 1, 0, 0, &rmidi)) != 0) { @@ -105,7 +105,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex) return temp; } mpu = rmidi->private_data; - mpu->cport = (unsigned long)(vortex->mmio + VORTEX_MIDI_CMD); + mpu->cport = (unsigned long)(vortex->mmio + (VORTEX_MIDI_CMD >> 2)); #endif vortex->rmidi = rmidi; return 0; diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 7b5baa173..6a13ca1d5 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -506,7 +506,7 @@ static int __devinit snd_vortex_new_pcm(vortex_t * chip, int idx, int nr) int i; int err, nr_capt; - if ((chip == 0) || (idx < 0) || (idx >= VORTEX_PCM_LAST)) + if ((chip == 0) || (idx < 0) || (idx > VORTEX_PCM_LAST)) return -ENODEV; /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c index d3e662a12..65f375bad 100644 --- a/sound/pci/au88x0/au88x0_synth.c +++ b/sound/pci/au88x0/au88x0_synth.c @@ -32,7 +32,7 @@ static void vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mix, int a); static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j); static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, - u32 val); + unsigned long val); /* WT */ @@ -166,7 +166,7 @@ static int vortex_wt_GetReg(vortex_t * vortex, char reg, int wt) /* WT hardware abstraction layer generic register interface. */ static int vortex_wt_SetReg2(vortex_t * vortex, unsigned char reg, int wt, - u16 val) + unsigned short val) { /* int eax, edx; @@ -190,7 +190,7 @@ vortex_wt_SetReg2(vortex_t * vortex, unsigned char reg, int wt, #endif static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, - u32 val) + unsigned long val) { int ecx; @@ -279,7 +279,7 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, static void vortex_wt_init(vortex_t * vortex) { - u32 var4, var8, varc, var10 = 0, edi; + int var4, var8, varc, var10 = 0, edi; var10 &= 0xFFFFFFE3; var10 |= 0x22; @@ -353,7 +353,7 @@ static void vortex_wt_SetVolume(vortex_t * vortex, int wt, int vol[]) static void vortex_wt_SetFrequency(vortex_t * vortex, int wt, unsigned int sr) { wt_voice_t *voice = &(vortex->wt_voice[wt]); - u32 eax, edx; + long int eax, edx; //FIXME: 64 bit operation. eax = ((sr << 0xf) * 0x57619F1) & 0xffffffff; diff --git a/sound/pci/au88x0/au88x0_wt.h b/sound/pci/au88x0/au88x0_wt.h index 38d98f88a..d536c88b4 100644 --- a/sound/pci/au88x0/au88x0_wt.h +++ b/sound/pci/au88x0/au88x0_wt.h @@ -53,11 +53,11 @@ enum { #endif typedef struct { - u32 parm0; /* this_1E4 */ - u32 parm1; /* this_1E8 */ - u32 parm2; /* this_1EC */ - u32 parm3; /* this_1F0 */ - u32 this_1D0; + unsigned int parm0; /* this_1E4 */ + unsigned int parm1; /* this_1E8 */ + unsigned int parm2; /* this_1EC */ + unsigned int parm3; /* this_1F0 */ + unsigned int this_1D0; } wt_voice_t; #endif /* _AU88X0_WT_H */ diff --git a/sound/pci/au88x0/au88x0_xtalk.c b/sound/pci/au88x0/au88x0_xtalk.c index 4534e1882..df915fa3f 100644 --- a/sound/pci/au88x0/au88x0_xtalk.c +++ b/sound/pci/au88x0/au88x0_xtalk.c @@ -562,7 +562,7 @@ static void vortex_XtalkHw_SetDelay(vortex_t * vortex, unsigned short right, unsigned short left) { - u32 esp0 = 0; + int esp0 = 0; esp0 &= 0x1FFFFFFF; esp0 |= 0xA0000000; @@ -632,18 +632,18 @@ static void vortex_XtalkHw_GetRightDline(vortex_t * vortex, xtalk_dline_t dline) /* Control/Global stuff */ #if 0 -static void vortex_XtalkHw_SetControlReg(vortex_t * vortex, u32 ctrl) +static void vortex_XtalkHw_SetControlReg(vortex_t * vortex, unsigned long ctrl) { hwwrite(vortex->mmio, 0x24660, ctrl); } -static void vortex_XtalkHw_GetControlReg(vortex_t * vortex, u32 *ctrl) +static void vortex_XtalkHw_GetControlReg(vortex_t * vortex, unsigned long *ctrl) { *ctrl = hwread(vortex->mmio, 0x24660); } #endif -static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, u32 sr) +static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, int sr) { - u32 temp; + int temp; temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; temp = (temp & 0xffffff07) | ((sr & 0x1f) << 3); @@ -651,7 +651,7 @@ static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, u32 sr) } #if 0 -static void vortex_XtalkHw_GetSampleRate(vortex_t * vortex, u32 *sr) +static void vortex_XtalkHw_GetSampleRate(vortex_t * vortex, int *sr) { *sr = (hwread(vortex->mmio, 0x24660) >> 3) & 0x1f; } @@ -659,7 +659,7 @@ static void vortex_XtalkHw_GetSampleRate(vortex_t * vortex, u32 *sr) #endif static void vortex_XtalkHw_Enable(vortex_t * vortex) { - u32 temp; + int temp; temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; temp |= 1; @@ -669,7 +669,7 @@ static void vortex_XtalkHw_Enable(vortex_t * vortex) static void vortex_XtalkHw_Disable(vortex_t * vortex) { - u32 temp; + int temp; temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; temp &= 0xfffffffe; diff --git a/sound/pci/au88x0/au88x0_xtalk.h b/sound/pci/au88x0/au88x0_xtalk.h index 7f4534b94..0b8d7b640 100644 --- a/sound/pci/au88x0/au88x0_xtalk.h +++ b/sound/pci/au88x0/au88x0_xtalk.h @@ -39,16 +39,16 @@ #define XT_SPEAKER1 3 #define XT_DIAMOND 4 -typedef u32 xtalk_dline_t[XTDLINE_SZ]; -typedef u16 xtalk_gains_t[XTGAINS_SZ]; -typedef u16 xtalk_instate_t[XTINST_SZ]; -typedef u16 xtalk_coefs_t[5][5]; -typedef u16 xtalk_state_t[5][4]; +typedef long xtalk_dline_t[XTDLINE_SZ]; +typedef short xtalk_gains_t[XTGAINS_SZ]; +typedef short xtalk_instate_t[XTINST_SZ]; +typedef short xtalk_coefs_t[5][5]; +typedef short xtalk_state_t[5][4]; static void vortex_XtalkHw_SetGains(vortex_t * vortex, xtalk_gains_t const gains); static void vortex_XtalkHw_SetGainsAllChan(vortex_t * vortex); -static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, u32 sr); +static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, int sr); static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex); static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex); static void vortex_XtalkHw_ProgramXtalkWide(vortex_t * vortex); diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 52a364524..e077eb3fb 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -104,7 +104,6 @@ #include #include #include -#include #include #include #include @@ -216,7 +215,7 @@ struct snd_azf3328 { int irq; }; -static const struct pci_device_id snd_azf3328_ids[] __devinitdata = { +static const struct pci_device_id snd_azf3328_ids[] = { { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */ { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */ { 0, } @@ -1670,8 +1669,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, 0x00ffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) { snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); err = -ENXIO; goto out_err; diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 9ee07d4aa..c840a4c08 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -774,7 +774,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card, .driver_data = rate } /* driver_data is the default digital_rate value for that device */ -static struct pci_device_id snd_bt87x_ids[] __devinitdata = { +static struct pci_device_id snd_bt87x_ids[] = { /* Hauppauge WinTV series */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */ @@ -783,8 +783,6 @@ static struct pci_device_id snd_bt87x_ids[] __devinitdata = { BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), /* AVerMedia Studio No. 103, 203, ...? */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000), - /* Leadtek Winfast tv 2000xp delux */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), { } }; MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); @@ -795,15 +793,12 @@ static struct { unsigned short subvendor, subdevice; } blacklist[] __devinitdata = { {0x0071, 0x0101}, /* Nebula Electronics DigiTV */ - {0x11bd, 0x001c}, /* Pinnacle PCTV Sat */ {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */ {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */ {0x1461, 0x0771}, /* AVermedia DVB-T 771 */ {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */ - {0x18ac, 0xd500}, /* DVICO FusionHDTV 5 Lite */ {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */ {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */ - {0x7063, 0x2000}, /* pcHDTV HD-2000 TV */ }; static struct pci_driver driver; @@ -821,13 +816,13 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) for (i = 0; i < ARRAY_SIZE(blacklist); ++i) if (blacklist[i].subvendor == pci->subsystem_vendor && blacklist[i].subdevice == pci->subsystem_device) { - snd_printdd(KERN_INFO "card %#04x-%#04x:%#04x has no audio\n", - pci->device, pci->subsystem_vendor, pci->subsystem_device); + snd_printdd(KERN_INFO "card %#04x:%#04x has no audio\n", + pci->subsystem_vendor, pci->subsystem_device); return -EBUSY; } - snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x, using default rate 32000\n", - pci->device, pci->subsystem_vendor, pci->subsystem_device); + snd_printk(KERN_INFO "unknown card %#04x:%#04x, using default rate 32000\n", + pci->subsystem_vendor, pci->subsystem_device); snd_printk(KERN_DEBUG "please mail id, board name, and, " "if it works, the correct digital_rate option to " "\n"); @@ -911,7 +906,7 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci) /* default entries for all Bt87x cards - it's not exported */ /* driver_data is set to 0 to call detection */ -static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { +static struct pci_device_id snd_bt87x_default_ids[] = { BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0), BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0), { } diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index fd8bfebfb..9477838a9 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -1561,7 +1561,7 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci) } // PCI IDs -static struct pci_device_id snd_ca0106_ids[] __devinitdata = { +static struct pci_device_id snd_ca0106_ids[] = { { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */ { 0, } }; diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index e5ce2dabd..c03b0a0a3 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -440,7 +439,7 @@ struct cmipci { struct snd_pcm_hardware *hw_info[3]; /* for playbacks */ int opened[2]; /* open mode */ - struct mutex open_mutex; + struct semaphore open_mutex; unsigned int mixer_insensitive: 1; struct snd_kcontrol *mixer_res_ctl[CM_SAVED_MIXERS]; @@ -642,14 +641,14 @@ static int snd_cmipci_playback2_hw_params(struct snd_pcm_substream *substream, { struct cmipci *cm = snd_pcm_substream_chip(substream); if (params_channels(hw_params) > 2) { - mutex_lock(&cm->open_mutex); + down(&cm->open_mutex); if (cm->opened[CM_CH_PLAY]) { - mutex_unlock(&cm->open_mutex); + up(&cm->open_mutex); return -EBUSY; } /* reserve the channel A */ cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI; - mutex_unlock(&cm->open_mutex); + up(&cm->open_mutex); } return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } @@ -1462,9 +1461,9 @@ static int open_device_check(struct cmipci *cm, int mode, struct snd_pcm_substre * pcm framework doesn't pass file pointer before actually opened, * we can't know whether blocking mode or not in open callback.. */ - mutex_lock(&cm->open_mutex); + down(&cm->open_mutex); if (cm->opened[ch]) { - mutex_unlock(&cm->open_mutex); + up(&cm->open_mutex); return -EBUSY; } cm->opened[ch] = mode; @@ -1476,7 +1475,7 @@ static int open_device_check(struct cmipci *cm, int mode, struct snd_pcm_substre snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC); spin_unlock_irq(&cm->reg_lock); } - mutex_unlock(&cm->open_mutex); + up(&cm->open_mutex); return 0; } @@ -1484,7 +1483,7 @@ static void close_device_check(struct cmipci *cm, int mode) { int ch = mode & CM_OPEN_CH_MASK; - mutex_lock(&cm->open_mutex); + down(&cm->open_mutex); if (cm->opened[ch] == mode) { if (cm->channel[ch].substream) { snd_cmipci_ch_reset(cm, ch); @@ -1500,7 +1499,7 @@ static void close_device_check(struct cmipci *cm, int mode) spin_unlock_irq(&cm->reg_lock); } } - mutex_unlock(&cm->open_mutex); + up(&cm->open_mutex); } /* @@ -1547,7 +1546,7 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */ return err; runtime->hw = snd_cmipci_playback2; - mutex_lock(&cm->open_mutex); + down(&cm->open_mutex); if (! cm->opened[CM_CH_PLAY]) { if (cm->can_multi_ch) { runtime->hw.channels_max = cm->max_channels; @@ -1560,7 +1559,7 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); } - mutex_unlock(&cm->open_mutex); + up(&cm->open_mutex); return 0; } @@ -2609,7 +2608,7 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {} #endif -static struct pci_device_id snd_cmipci_ids[] __devinitdata = { +static struct pci_device_id snd_cmipci_ids[] = { {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -2845,7 +2844,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc } spin_lock_init(&cm->reg_lock); - mutex_init(&cm->open_mutex); + init_MUTEX(&cm->open_mutex); cm->device = pci->device; cm->card = card; cm->pci = pci; diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index b3c94d834..4f65ec56b 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -494,7 +494,7 @@ struct cs4281 { static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct pci_device_id snd_cs4281_ids[] __devinitdata = { +static struct pci_device_id snd_cs4281_ids[] = { { 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4281 */ { 0, } }; @@ -1046,7 +1046,7 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol, snd_cs4281_pokeBA0(chip, regL, volL); change = 1; } - if (ucontrol->value.integer.value[1] != volR) { + if (ucontrol->value.integer.value[0] != volL) { volR = CS_VOL_MASK - (ucontrol->value.integer.value[1] & CS_VOL_MASK); snd_cs4281_pokeBA0(chip, regR, volR); change = 1; @@ -1416,7 +1416,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card, static int snd_cs4281_chip_init(struct cs4281 *chip) { unsigned int tmp; - unsigned long end_time; + int timeout; int retry_count = 2; /* Having EPPMC.FPDN=1 prevent proper chip initialisation */ @@ -1496,7 +1496,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) /* * Wait for the DLL ready signal from the clock logic. */ - end_time = jiffies + HZ; + timeout = 100; do { /* * Read the AC97 status register to see if we've seen a CODEC @@ -1504,8 +1504,8 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) */ if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY) goto __ok0; - schedule_timeout_uninterruptible(1); - } while (time_after_eq(end_time, jiffies)); + msleep(1); + } while (timeout-- > 0); snd_printk(KERN_ERR "DLLRDY not seen\n"); return -EIO; @@ -1522,7 +1522,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) /* * Wait for the codec ready signal from the AC97 codec. */ - end_time = jiffies + HZ; + timeout = 100; do { /* * Read the AC97 status register to see if we've seen a CODEC @@ -1530,20 +1530,20 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) */ if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY) goto __ok1; - schedule_timeout_uninterruptible(1); - } while (time_after_eq(end_time, jiffies)); + msleep(1); + } while (timeout-- > 0); snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS)); return -EIO; __ok1: if (chip->dual_codec) { - end_time = jiffies + HZ; + timeout = 100; do { if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY) goto __codec2_ok; - schedule_timeout_uninterruptible(1); - } while (time_after_eq(end_time, jiffies)); + msleep(1); + } while (timeout-- > 0); snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n"); chip->dual_codec = 0; __codec2_ok: ; @@ -1561,7 +1561,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) * the codec is pumping ADC data across the AC-link. */ - end_time = jiffies + HZ; + timeout = 100; do { /* * Read the input slot valid register and see if input slots 3 @@ -1569,8 +1569,8 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) */ if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) goto __ok2; - schedule_timeout_uninterruptible(1); - } while (time_after_eq(end_time, jiffies)); + msleep(1); + } while (timeout-- > 0); if (--retry_count > 0) goto __retry; diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index 848d772ae..c590602e2 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c @@ -65,7 +65,7 @@ MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control."); module_param_array(mmap_valid, bool, NULL, 0444); MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); -static struct pci_device_id snd_cs46xx_ids[] __devinitdata = { +static struct pci_device_id snd_cs46xx_ids[] = { { 0x1013, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4280 */ { 0x1013, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4612 */ { 0x1013, 0x6004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4615 */ diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 69dbf542a..8fb275d6e 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -53,8 +53,6 @@ #include #include #include -#include - #include #include @@ -911,22 +909,22 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, #ifdef CONFIG_SND_CS46XX_NEW_DSP snd_assert (sample_rate != 0, return -ENXIO); - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) { - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return -ENXIO; } snd_assert (cpcm->pcm_channel != NULL); if (!cpcm->pcm_channel) { - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return -ENXIO; } if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return -EINVAL; } @@ -967,7 +965,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, } if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) { #ifdef CONFIG_SND_CS46XX_NEW_DSP - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); #endif return err; } @@ -991,7 +989,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, } #ifdef CONFIG_SND_CS46XX_NEW_DSP - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); #endif return 0; @@ -1321,7 +1319,7 @@ static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,in cpcm->substream = substream; #ifdef CONFIG_SND_CS46XX_NEW_DSP - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); cpcm->pcm_channel = NULL; cpcm->pcm_channel_id = pcm_channel_id; @@ -1330,7 +1328,7 @@ static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,in SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_sizes); - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); #else chip->playback_pcm = cpcm; /* HACK */ #endif @@ -1369,9 +1367,9 @@ static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream) snd_printdd("open raw iec958 channel\n"); - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); cs46xx_iec958_pre_open (chip); - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL); } @@ -1387,9 +1385,9 @@ static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream) err = snd_cs46xx_playback_close(substream); - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); cs46xx_iec958_post_close (chip); - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return err; } @@ -1430,12 +1428,12 @@ static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream) if (!cpcm) return -ENXIO; #ifdef CONFIG_SND_CS46XX_NEW_DSP - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); if (cpcm->pcm_channel) { cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); cpcm->pcm_channel = NULL; } - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); #else chip->playback_pcm = NULL; #endif @@ -1850,7 +1848,7 @@ static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, switch (kcontrol->private_value) { case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT: - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); if (ucontrol->value.integer.value[0] && !change) cs46xx_dsp_enable_spdif_out(chip); @@ -1858,7 +1856,7 @@ static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, cs46xx_dsp_disable_spdif_out(chip); res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); break; case CS46XX_MIXER_SPDIF_INPUT_ELEMENT: change = chip->dsp_spos_instance->spdif_status_in; @@ -1999,12 +1997,12 @@ static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); struct dsp_spos_instance * ins = chip->dsp_spos_instance; - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); ucontrol->value.iec958.status[2] = 0; ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return 0; } @@ -2017,7 +2015,7 @@ static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol, unsigned int val; int change; - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | @@ -2031,7 +2029,7 @@ static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol, if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return change; } @@ -2052,12 +2050,12 @@ static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); struct dsp_spos_instance * ins = chip->dsp_spos_instance; - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); ucontrol->value.iec958.status[2] = 0; ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return 0; } @@ -2070,7 +2068,7 @@ static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol, unsigned int val; int change; - mutex_lock(&chip->spos_mutex); + down (&chip->spos_mutex); val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | @@ -2084,7 +2082,7 @@ static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol, if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); - mutex_unlock(&chip->spos_mutex); + up (&chip->spos_mutex); return change; } @@ -3757,7 +3755,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card, } spin_lock_init(&chip->reg_lock); #ifdef CONFIG_SND_CS46XX_NEW_DSP - mutex_init(&chip->spos_mutex); + init_MUTEX(&chip->spos_mutex); #endif chip->card = card; chip->pci = pci; diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index f407d2a5c..81bcae073 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c @@ -28,8 +28,6 @@ #include #include #include -#include - #include #include #include @@ -293,7 +291,7 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) snd_assert(ins != NULL, return); - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); for (i = 0; i < ins->nscb; ++i) { if (ins->scbs[i].deleted) continue; @@ -304,7 +302,7 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) vfree(ins->symbol_table.symbols); kfree(ins->modules); kfree(ins); - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); } int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) @@ -503,7 +501,7 @@ static void cs46xx_dsp_proc_modules_read (struct snd_info_entry *entry, struct dsp_spos_instance * ins = chip->dsp_spos_instance; int i,j; - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); snd_iprintf(buffer, "MODULES:\n"); for ( i = 0; i < ins->nmodules; ++i ) { snd_iprintf(buffer, "\n%s:\n", ins->modules[i].module_name); @@ -516,7 +514,7 @@ static void cs46xx_dsp_proc_modules_read (struct snd_info_entry *entry, desc->segment_type,desc->offset, desc->size); } } - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); } static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry, @@ -527,7 +525,7 @@ static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry, int i, j, col; void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET; - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); snd_iprintf(buffer, "TASK TREES:\n"); for ( i = 0; i < ins->ntask; ++i) { snd_iprintf(buffer,"\n%04x %s:\n",ins->tasks[i].address,ins->tasks[i].task_name); @@ -544,7 +542,7 @@ static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry, } snd_iprintf(buffer,"\n"); - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); } static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry, @@ -554,7 +552,7 @@ static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry, struct dsp_spos_instance * ins = chip->dsp_spos_instance; int i; - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); snd_iprintf(buffer, "SCB's:\n"); for ( i = 0; i < ins->nscb; ++i) { if (ins->scbs[i].deleted) @@ -577,7 +575,7 @@ static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry, } snd_iprintf(buffer,"\n"); - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); } static void cs46xx_dsp_proc_parameter_dump_read (struct snd_info_entry *entry, @@ -858,14 +856,14 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip) } ins->proc_scb_info_entry = entry; - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); /* register/update SCB's entries on proc */ for (i = 0; i < ins->nscb; ++i) { if (ins->scbs[i].deleted) continue; cs46xx_dsp_proc_register_scb_desc (chip, (ins->scbs + i)); } - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } @@ -905,12 +903,12 @@ int cs46xx_dsp_proc_done (struct snd_cs46xx *chip) ins->proc_task_info_entry = NULL; } - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); for (i = 0; i < ins->nscb; ++i) { if (ins->scbs[i].deleted) continue; cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); } - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); if (ins->proc_dsp_dir) { snd_info_unregister (ins->proc_dsp_dir); @@ -1700,7 +1698,7 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip) snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL); snd_assert (ins->spdif_in_src != NULL,return -EINVAL); - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED) ) { /* time countdown enable */ @@ -1744,7 +1742,7 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip) /* monitor state */ ins->spdif_status_in = 1; - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } @@ -1756,7 +1754,7 @@ int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip) snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL); snd_assert (ins->spdif_in_src != NULL,return -EINVAL); - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); /* Remove the asynchronous receiver SCB */ cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb); @@ -1766,7 +1764,7 @@ int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip) /* monitor state */ ins->spdif_status_in = 0; - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); /* restore amplifier */ chip->active_ctrl(chip, -1); @@ -1782,10 +1780,10 @@ int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip) snd_assert (ins->pcm_input == NULL,return -EINVAL); snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL); - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR, "PCMSerialInput_Wave"); - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } @@ -1796,10 +1794,10 @@ int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip) snd_assert (ins->pcm_input != NULL,return -EINVAL); - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); cs46xx_dsp_remove_scb (chip,ins->pcm_input); ins->pcm_input = NULL; - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } @@ -1811,10 +1809,10 @@ int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip) snd_assert (ins->adc_input == NULL,return -EINVAL); snd_assert (ins->codec_in_scb != NULL,return -EINVAL); - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR, "PCMSerialInput_ADC"); - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } @@ -1825,10 +1823,10 @@ int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip) snd_assert (ins->adc_input != NULL,return -EINVAL); - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); cs46xx_dsp_remove_scb (chip,ins->adc_input); ins->adc_input = NULL; - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } @@ -1875,7 +1873,7 @@ int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right) struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_scb_descriptor * scb; - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); /* main output */ scb = ins->master_mix_scb->sub_list_ptr; @@ -1894,7 +1892,7 @@ int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right) ins->dac_volume_left = left; ins->dac_volume_right = right; - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } @@ -1903,7 +1901,7 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); if (ins->asynch_rx_scb != NULL) cs46xx_dsp_scb_set_volume (chip,ins->asynch_rx_scb, @@ -1912,7 +1910,7 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) ins->spdif_input_volume_left = left; ins->spdif_input_volume_right = right; - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index 2c4ee45fe..d4e0fb39b 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -28,8 +28,6 @@ #include #include #include -#include - #include #include #include @@ -79,7 +77,7 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry, ins = chip->dsp_spos_instance; - mutex_lock(&chip->spos_mutex); + down(&chip->spos_mutex); snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name); for (col = 0,j = 0;j < 0x10; j++,col++) { @@ -107,7 +105,7 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry, scb->task_entry->address); snd_iprintf(buffer,"index [%d] ref_count [%d]\n",scb->index,scb->ref_count); - mutex_unlock(&chip->spos_mutex); + up(&chip->spos_mutex); } #endif diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index 2c1213a35..02e372103 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c @@ -45,7 +45,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; -static struct pci_device_id snd_cs5535audio_ids[] __devinitdata = { +static struct pci_device_id snd_cs5535audio_ids[] = { { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO, @@ -62,7 +62,7 @@ static void wait_till_cmd_acked(struct cs5535audio *cs5535au, unsigned long time tmp = cs_readl(cs5535au, ACC_CODEC_CNTL); if (!(tmp & CMD_NEW)) break; - udelay(1); + msleep(10); } while (--timeout); if (!timeout) snd_printk(KERN_ERR "Failure writing to cs5535 codec\n"); @@ -80,14 +80,14 @@ static unsigned short snd_cs5535audio_codec_read(struct cs5535audio *cs5535au, regdata |= CMD_NEW; cs_writel(cs5535au, ACC_CODEC_CNTL, regdata); - wait_till_cmd_acked(cs5535au, 50); + wait_till_cmd_acked(cs5535au, 500); timeout = 50; do { val = cs_readl(cs5535au, ACC_CODEC_STATUS); if ((val & STS_NEW) && reg == (val >> 24)) break; - udelay(1); + msleep(10); } while (--timeout); if (!timeout) snd_printk(KERN_ERR "Failure reading cs5535 codec\n"); diff --git a/sound/pci/echoaudio/Makefile b/sound/pci/echoaudio/Makefile new file mode 100644 index 000000000..7b576aeb3 --- /dev/null +++ b/sound/pci/echoaudio/Makefile @@ -0,0 +1,30 @@ +# +# Makefile for ALSA Echoaudio soundcard drivers +# Copyright (c) 2003 by Giuliano Pochini +# + +snd-darla20-objs := darla20.o +snd-gina20-objs := gina20.o +snd-layla20-objs := layla20.o +snd-darla24-objs := darla24.o +snd-gina24-objs := gina24.o +snd-layla24-objs := layla24.o +snd-mona-objs := mona.o +snd-mia-objs := mia.o +snd-echo3g-objs := echo3g.o +snd-indigo-objs := indigo.o +snd-indigoio-objs := indigoio.o +snd-indigodj-objs := indigodj.o + +obj-$(CONFIG_SND_DARLA20) += snd-darla20.o +obj-$(CONFIG_SND_GINA20) += snd-gina20.o +obj-$(CONFIG_SND_LAYLA20) += snd-layla20.o +obj-$(CONFIG_SND_DARLA24) += snd-darla24.o +obj-$(CONFIG_SND_GINA24) += snd-gina24.o +obj-$(CONFIG_SND_LAYLA24) += snd-layla24.o +obj-$(CONFIG_SND_MONA) += snd-mona.o +obj-$(CONFIG_SND_MIA) += snd-mia.o +obj-$(CONFIG_SND_ECHO3G) += snd-echo3g.o +obj-$(CONFIG_SND_INDIGO) += snd-indigo.o +obj-$(CONFIG_SND_INDIGOIO) += snd-indigoio.o +obj-$(CONFIG_SND_INDIGODJ) += snd-indigodj.o diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c new file mode 100644 index 000000000..b7108e29a --- /dev/null +++ b/sound/pci/echoaudio/darla20.c @@ -0,0 +1,99 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHOGALS_FAMILY +#define ECHOCARD_DARLA20 +#define ECHOCARD_NAME "Darla20" +#define ECHOCARD_HAS_MONITOR + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 0 */ +#define PX_ANALOG_IN 8 /* 2 */ +#define PX_DIGITAL_IN 10 /* 0 */ +#define PX_NUM 10 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 8 */ +#define BX_DIGITAL_OUT 8 /* 0 */ +#define BX_ANALOG_IN 8 /* 2 */ +#define BX_DIGITAL_IN 10 /* 0 */ +#define BX_NUM 10 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_DARLA20_DSP 0 + +static const struct firmware card_fw[] = { + {0, "darla20_dsp.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .rate_min = 44100, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, + /* One page (4k) contains 512 instructions. I don't know if the hw + supports lists longer than this. In this case periods_max=220 is a + safe limit to make sure the list never exceeds 512 instructions. */ +}; + + +#include "darla20_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio.c" diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c new file mode 100644 index 000000000..4159e3bc1 --- /dev/null +++ b/sound/pci/echoaudio/darla20_dsp.c @@ -0,0 +1,125 @@ +/*************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Darla20\n")); + snd_assert((subdevice_id & 0xfff0) == DARLA20, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP]; + chip->spdif_status = GD_SPDIF_STATUS_UNDEF; + chip->clock_state = GD_CLOCK_UNDEF; + /* Since this card has no ASIC, mark it as loaded so everything + works OK */ + chip->asic_loaded = TRUE; + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + DE_INIT(("init_hw done\n")); + return err; +} + + + +/* The Darla20 has no external clock sources */ +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + return ECHO_CLOCK_BIT_INTERNAL; +} + + + +/* The Darla20 has no ASIC. Just do nothing */ +static int load_asic(struct echoaudio *chip) +{ + return 0; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u8 clock_state, spdif_status; + + if (wait_handshake(chip)) + return -EIO; + + switch (rate) { + case 44100: + clock_state = GD_CLOCK_44; + spdif_status = GD_SPDIF_STATUS_44; + break; + case 48000: + clock_state = GD_CLOCK_48; + spdif_status = GD_SPDIF_STATUS_48; + break; + default: + clock_state = GD_CLOCK_NOCHANGE; + spdif_status = GD_SPDIF_STATUS_NOCHANGE; + break; + } + + if (chip->clock_state == clock_state) + clock_state = GD_CLOCK_NOCHANGE; + if (spdif_status == chip->spdif_status) + spdif_status = GD_SPDIF_STATUS_NOCHANGE; + + chip->comm_page->sample_rate = cpu_to_le32(rate); + chip->comm_page->gd_clock_state = clock_state; + chip->comm_page->gd_spdif_status = spdif_status; + chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ + + /* Save the new audio state if it changed */ + if (clock_state != GD_CLOCK_NOCHANGE) + chip->clock_state = clock_state; + if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) + chip->spdif_status = spdif_status; + chip->sample_rate = rate; + + clear_handshake(chip); + return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); +} diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c new file mode 100644 index 000000000..e59a982ee --- /dev/null +++ b/sound/pci/echoaudio/darla24.c @@ -0,0 +1,106 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHOGALS_FAMILY +#define ECHOCARD_DARLA24 +#define ECHOCARD_NAME "Darla24" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_EXTERNAL_CLOCK +#define ECHOCARD_HAS_SUPER_INTERLEAVE + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 0 */ +#define PX_ANALOG_IN 8 /* 2 */ +#define PX_DIGITAL_IN 10 /* 0 */ +#define PX_NUM 10 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 8 */ +#define BX_DIGITAL_OUT 8 /* 0 */ +#define BX_ANALOG_IN 8 /* 2 */ +#define BX_DIGITAL_IN 10 /* 0 */ +#define BX_NUM 10 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_DARLA24_DSP 0 + +static const struct firmware card_fw[] = { + {0, "darla24_dsp.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */ + {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_8000_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 8000, + .rate_max = 96000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, + /* One page (4k) contains 512 instructions. I don't know if the hw + supports lists longer than this. In this case periods_max=220 is a + safe limit to make sure the list never exceeds 512 instructions. */ +}; + + +#include "darla24_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio.c" diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c new file mode 100644 index 000000000..79938eed7 --- /dev/null +++ b/sound/pci/echoaudio/darla24_dsp.c @@ -0,0 +1,156 @@ +/*************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Darla24\n")); + snd_assert((subdevice_id & 0xfff0) == DARLA24, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP]; + /* Since this card has no ASIC, mark it as loaded so everything + works OK */ + chip->asic_loaded = TRUE; + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | + ECHO_CLOCK_BIT_ESYNC; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + u32 clocks_from_dsp, clock_bits; + + /* Map the DSP clock detect bits to the generic driver clock + detect bits */ + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + clock_bits = ECHO_CLOCK_BIT_INTERNAL; + + if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_ESYNC) + clock_bits |= ECHO_CLOCK_BIT_ESYNC; + + return clock_bits; +} + + + +/* The Darla24 has no ASIC. Just do nothing */ +static int load_asic(struct echoaudio *chip) +{ + return 0; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u8 clock; + + switch (rate) { + case 96000: + clock = GD24_96000; + break; + case 88200: + clock = GD24_88200; + break; + case 48000: + clock = GD24_48000; + break; + case 44100: + clock = GD24_44100; + break; + case 32000: + clock = GD24_32000; + break; + case 22050: + clock = GD24_22050; + break; + case 16000: + clock = GD24_16000; + break; + case 11025: + clock = GD24_11025; + break; + case 8000: + clock = GD24_8000; + break; + default: + DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n", + rate)); + return -EINVAL; + } + + if (wait_handshake(chip)) + return -EIO; + + DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); + chip->sample_rate = rate; + + /* Override the sample rate if this card is set to Echo sync. */ + if (chip->input_clock == ECHO_CLOCK_ESYNC) + clock = GD24_EXT_SYNC; + + chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ + chip->comm_page->gd_clock_state = clock; + clear_handshake(chip); + return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); +} + + + +static int set_input_clock(struct echoaudio *chip, u16 clock) +{ + snd_assert(clock == ECHO_CLOCK_INTERNAL || + clock == ECHO_CLOCK_ESYNC, return -EINVAL); + chip->input_clock = clock; + return set_sample_rate(chip, chip->sample_rate); +} + diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c new file mode 100644 index 000000000..12099fe15 --- /dev/null +++ b/sound/pci/echoaudio/echo3g.c @@ -0,0 +1,118 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHO3G_FAMILY +#define ECHOCARD_ECHO3G +#define ECHOCARD_NAME "Echo3G" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_ASIC +#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_DIGITAL_IO +#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH +#define ECHOCARD_HAS_ADAT 6 +#define ECHOCARD_HAS_EXTERNAL_CLOCK +#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 +#define ECHOCARD_HAS_MIDI +#define ECHOCARD_HAS_PHANTOM_POWER + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 +#define PX_DIGITAL_OUT chip->px_digital_out +#define PX_ANALOG_IN chip->px_analog_in +#define PX_DIGITAL_IN chip->px_digital_in +#define PX_NUM chip->px_num + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 +#define BX_DIGITAL_OUT chip->bx_digital_out +#define BX_ANALOG_IN chip->bx_analog_in +#define BX_DIGITAL_IN chip->bx_digital_in +#define BX_NUM chip->bx_num + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_361_LOADER 0 +#define FW_ECHO3G_DSP 1 +#define FW_3G_ASIC 2 + +static const struct firmware card_fw[] = { + {0, "loader_dsp.fw"}, + {0, "echo3g_dsp.fw"}, + {0, "3g_asic.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 32000, + .rate_max = 100000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, +}; + +#include "echo3g_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio_3g.c" +#include "echoaudio.c" +#include "midi.c" diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c new file mode 100644 index 000000000..d26a1d1f3 --- /dev/null +++ b/sound/pci/echoaudio/echo3g_dsp.c @@ -0,0 +1,131 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + +static int load_asic(struct echoaudio *chip); +static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode); +static int set_digital_mode(struct echoaudio *chip, u8 mode); +static int check_asic_status(struct echoaudio *chip); +static int set_sample_rate(struct echoaudio *chip, u32 rate); +static int set_input_clock(struct echoaudio *chip, u16 clock); +static int set_professional_spdif(struct echoaudio *chip, char prof); +static int set_phantom_power(struct echoaudio *chip, char on); +static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, + char force); + +#include + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + local_irq_enable(); + DE_INIT(("init_hw() - Echo3G\n")); + snd_assert((subdevice_id & 0xfff0) == ECHO3G, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->comm_page->e3g_frq_register = + __constant_cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2); + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->has_midi = TRUE; + chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP]; + + /* Load the DSP code and the ASIC on the PCI card and get + what type of external box is attached */ + err = load_firmware(chip); + + if (err < 0) { + return err; + } else if (err == E3G_GINA3G_BOX_TYPE) { + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | + ECHO_CLOCK_BIT_SPDIF | + ECHO_CLOCK_BIT_ADAT; + chip->card_name = "Gina3G"; + chip->px_digital_out = chip->bx_digital_out = 6; + chip->px_analog_in = chip->bx_analog_in = 14; + chip->px_digital_in = chip->bx_digital_in = 16; + chip->px_num = chip->bx_num = 24; + chip->has_phantom_power = TRUE; + chip->hasnt_input_nominal_level = TRUE; + } else if (err == E3G_LAYLA3G_BOX_TYPE) { + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | + ECHO_CLOCK_BIT_SPDIF | + ECHO_CLOCK_BIT_ADAT | + ECHO_CLOCK_BIT_WORD; + chip->card_name = "Layla3G"; + chip->px_digital_out = chip->bx_digital_out = 8; + chip->px_analog_in = chip->bx_analog_in = 16; + chip->px_digital_in = chip->bx_digital_in = 24; + chip->px_num = chip->bx_num = 32; + } else { + return -ENODEV; + } + + chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | + ECHOCAPS_HAS_DIGITAL_MODE_ADAT; + chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; + chip->professional_spdif = FALSE; + chip->non_audio_spdif = FALSE; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); + snd_assert(err >= 0, return err); + err = set_phantom_power(chip, 0); + snd_assert(err >= 0, return err); + err = set_professional_spdif(chip, TRUE); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static int set_phantom_power(struct echoaudio *chip, char on) +{ + u32 control_reg = le32_to_cpu(chip->comm_page->control_register); + + if (on) + control_reg |= E3G_PHANTOM_POWER; + else + control_reg &= ~E3G_PHANTOM_POWER; + + chip->phantom_power = on; + return write_control_reg(chip, control_reg, + le32_to_cpu(chip->comm_page->e3g_frq_register), + 0); +} diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c new file mode 100644 index 000000000..43b408ada --- /dev/null +++ b/sound/pci/echoaudio/echoaudio.c @@ -0,0 +1,2196 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +MODULE_AUTHOR("Giuliano Pochini "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver"); +MODULE_SUPPORTED_DEVICE("{{Echoaudio," ECHOCARD_NAME "}}"); +MODULE_DEVICE_TABLE(pci, snd_echo_ids); + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard."); +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for " ECHOCARD_NAME " soundcard."); +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); + +static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; + +static int get_firmware(const struct firmware **fw_entry, + const struct firmware *frm, struct echoaudio *chip) +{ + int err; + char name[30]; + DE_ACT(("firmware requested: %s\n", frm->data)); + snprintf(name, sizeof(name), "ea/%s", frm->data); + if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) + snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); + return err; +} + +static void free_firmware(const struct firmware *fw_entry) +{ + release_firmware(fw_entry); + DE_ACT(("firmware released\n")); +} + + + +/****************************************************************************** + PCM interface +******************************************************************************/ + +static void audiopipe_free(struct snd_pcm_runtime *runtime) +{ + struct audiopipe *pipe = runtime->private_data; + + if (pipe->sgpage.area) + snd_dma_free_pages(&pipe->sgpage); + kfree(pipe); +} + + + +static int hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct snd_interval *c = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + struct snd_mask fmt; + + snd_mask_any(&fmt); + +#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + /* >=2 channels cannot be S32_BE */ + if (c->min == 2) { + fmt.bits[0] &= ~SNDRV_PCM_FMTBIT_S32_BE; + return snd_mask_refine(f, &fmt); + } +#endif + /* > 2 channels cannot be U8 and S32_BE */ + if (c->min > 2) { + fmt.bits[0] &= ~(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_BE); + return snd_mask_refine(f, &fmt); + } + /* Mono is ok with any format */ + return 0; +} + + + +static int hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct snd_interval *c = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + struct snd_interval ch; + + snd_interval_any(&ch); + + /* S32_BE is mono (and stereo) only */ + if (f->bits[0] == SNDRV_PCM_FMTBIT_S32_BE) { + ch.min = 1; +#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + ch.max = 2; +#else + ch.max = 1; +#endif + ch.integer = 1; + return snd_interval_refine(c, &ch); + } + /* U8 can be only mono or stereo */ + if (f->bits[0] == SNDRV_PCM_FMTBIT_U8) { + ch.min = 1; + ch.max = 2; + ch.integer = 1; + return snd_interval_refine(c, &ch); + } + /* S16_LE, S24_3LE and S32_LE support any number of channels. */ + return 0; +} + + + +static int hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct snd_interval *c = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + struct snd_mask fmt; + u64 fmask; + snd_mask_any(&fmt); + + fmask = fmt.bits[0] + ((u64)fmt.bits[1] << 32); + + /* >2 channels must be S16_LE, S24_3LE or S32_LE */ + if (c->min > 2) { + fmask &= SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE; + /* 1 channel must be S32_BE or S32_LE */ + } else if (c->max == 1) + fmask &= SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE; +#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + /* 2 channels cannot be S32_BE */ + else if (c->min == 2 && c->max == 2) + fmask &= ~SNDRV_PCM_FMTBIT_S32_BE; +#endif + else + return 0; + + fmt.bits[0] &= (u32)fmask; + fmt.bits[1] &= (u32)(fmask >> 32); + return snd_mask_refine(f, &fmt); +} + + + +static int hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct snd_interval *c = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + struct snd_interval ch; + u64 fmask; + + snd_interval_any(&ch); + ch.integer = 1; + fmask = f->bits[0] + ((u64)f->bits[1] << 32); + + /* S32_BE is mono (and stereo) only */ + if (fmask == SNDRV_PCM_FMTBIT_S32_BE) { + ch.min = 1; +#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + ch.max = 2; +#else + ch.max = 1; +#endif + /* U8 is stereo only */ + } else if (fmask == SNDRV_PCM_FMTBIT_U8) + ch.min = ch.max = 2; + /* S16_LE and S24_3LE must be at least stereo */ + else if (!(fmask & ~(SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE))) + ch.min = 2; + else + return 0; + + return snd_interval_refine(c, &ch); +} + + + +/* Since the sample rate is a global setting, do allow the user to change the +sample rate only if there is only one pcm device open. */ +static int hw_rule_sample_rate(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct echoaudio *chip = rule->private; + struct snd_interval fixed; + + if (!chip->can_set_rate) { + snd_interval_any(&fixed); + fixed.min = fixed.max = chip->sample_rate; + return snd_interval_refine(rate, &fixed); + } + return 0; +} + + +static int pcm_open(struct snd_pcm_substream *substream, + signed char max_channels) +{ + struct echoaudio *chip; + struct snd_pcm_runtime *runtime; + struct audiopipe *pipe; + int err, i; + + if (max_channels <= 0) + return -EAGAIN; + + chip = snd_pcm_substream_chip(substream); + runtime = substream->runtime; + + if (!(pipe = kmalloc(sizeof(struct audiopipe), GFP_KERNEL))) + return -ENOMEM; + memset(pipe, 0, sizeof(struct audiopipe)); + pipe->index = -1; /* Not configured yet */ + + /* Set up hw capabilities and contraints */ + memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware)); + DE_HWP(("max_channels=%d\n", max_channels)); + pipe->constr.list = channels_list; + pipe->constr.mask = 0; + for (i = 0; channels_list[i] <= max_channels; i++); + pipe->constr.count = i; + if (pipe->hw.channels_max > max_channels) + pipe->hw.channels_max = max_channels; + if (chip->digital_mode == DIGITAL_MODE_ADAT) { + pipe->hw.rate_max = 48000; + pipe->hw.rates &= SNDRV_PCM_RATE_8000_48000; + } + + runtime->hw = pipe->hw; + runtime->private_data = pipe; + runtime->private_free = audiopipe_free; + snd_pcm_set_sync(substream); + + /* Only mono and any even number of channels are allowed */ + if ((err = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &pipe->constr)) < 0) + return err; + + /* All periods should have the same size */ + if ((err = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS)) < 0) + return err; + + /* The hw accesses memory in chunks 32 frames long and they should be + 32-bytes-aligned. It's not a requirement, but it seems that IRQs are + generated with a resolution of 32 frames. Thus we need the following */ + if ((err = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, + 32)) < 0) + return err; + if ((err = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, + 32)) < 0) + return err; + + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + hw_rule_sample_rate, chip, + SNDRV_PCM_HW_PARAM_RATE, -1)) < 0) + return err; + + /* Finally allocate a page for the scatter-gather list */ + if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + PAGE_SIZE, &pipe->sgpage)) < 0) { + DE_HWP(("s-g list allocation failed\n")); + return err; + } + + return 0; +} + + + +static int pcm_analog_in_open(struct snd_pcm_substream *substream) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + int err; + + DE_ACT(("pcm_analog_in_open\n")); + if ((err = pcm_open(substream, num_analog_busses_in(chip) - + substream->number)) < 0) + return err; + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + hw_rule_capture_channels_by_format, NULL, + SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) + return err; + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_FORMAT, + hw_rule_capture_format_by_channels, NULL, + SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) + return err; + atomic_inc(&chip->opencount); + if (atomic_read(&chip->opencount) > 1 && chip->rate_set) + chip->can_set_rate=0; + DE_HWP(("pcm_analog_in_open cs=%d oc=%d r=%d\n", + chip->can_set_rate, atomic_read(&chip->opencount), + chip->sample_rate)); + return 0; +} + + + +static int pcm_analog_out_open(struct snd_pcm_substream *substream) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + int max_channels, err; + +#ifdef ECHOCARD_HAS_VMIXER + max_channels = num_pipes_out(chip); +#else + max_channels = num_analog_busses_out(chip); +#endif + DE_ACT(("pcm_analog_out_open\n")); + if ((err = pcm_open(substream, max_channels - substream->number)) < 0) + return err; + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + hw_rule_playback_channels_by_format, + NULL, + SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) + return err; + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_FORMAT, + hw_rule_playback_format_by_channels, + NULL, + SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) + return err; + atomic_inc(&chip->opencount); + if (atomic_read(&chip->opencount) > 1 && chip->rate_set) + chip->can_set_rate=0; + DE_HWP(("pcm_analog_out_open cs=%d oc=%d r=%d\n", + chip->can_set_rate, atomic_read(&chip->opencount), + chip->sample_rate)); + return 0; +} + + + +#ifdef ECHOCARD_HAS_DIGITAL_IO + +static int pcm_digital_in_open(struct snd_pcm_substream *substream) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + int err, max_channels; + + DE_ACT(("pcm_digital_in_open\n")); + max_channels = num_digital_busses_in(chip) - substream->number; + down(&chip->mode_mutex); + if (chip->digital_mode == DIGITAL_MODE_ADAT) + err = pcm_open(substream, max_channels); + else /* If the card has ADAT, subtract the 6 channels + * that S/PDIF doesn't have + */ + err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); + + if (err < 0) + goto din_exit; + + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + hw_rule_capture_channels_by_format, NULL, + SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) + goto din_exit; + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_FORMAT, + hw_rule_capture_format_by_channels, NULL, + SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) + goto din_exit; + + atomic_inc(&chip->opencount); + if (atomic_read(&chip->opencount) > 1 && chip->rate_set) + chip->can_set_rate=0; + +din_exit: + up(&chip->mode_mutex); + return err; +} + + + +#ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ + +static int pcm_digital_out_open(struct snd_pcm_substream *substream) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + int err, max_channels; + + DE_ACT(("pcm_digital_out_open\n")); + max_channels = num_digital_busses_out(chip) - substream->number; + down(&chip->mode_mutex); + if (chip->digital_mode == DIGITAL_MODE_ADAT) + err = pcm_open(substream, max_channels); + else /* If the card has ADAT, subtract the 6 channels + * that S/PDIF doesn't have + */ + err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); + + if (err < 0) + goto dout_exit; + + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + hw_rule_playback_channels_by_format, + NULL, SNDRV_PCM_HW_PARAM_FORMAT, + -1)) < 0) + goto dout_exit; + if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_FORMAT, + hw_rule_playback_format_by_channels, + NULL, SNDRV_PCM_HW_PARAM_CHANNELS, + -1)) < 0) + goto dout_exit; + atomic_inc(&chip->opencount); + if (atomic_read(&chip->opencount) > 1 && chip->rate_set) + chip->can_set_rate=0; +dout_exit: + up(&chip->mode_mutex); + return err; +} + +#endif /* !ECHOCARD_HAS_VMIXER */ + +#endif /* ECHOCARD_HAS_DIGITAL_IO */ + + + +static int pcm_close(struct snd_pcm_substream *substream) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + int oc; + + /* Nothing to do here. Audio is already off and pipe will be + * freed by its callback + */ + DE_ACT(("pcm_close\n")); + + atomic_dec(&chip->opencount); + oc = atomic_read(&chip->opencount); + DE_ACT(("pcm_close oc=%d cs=%d rs=%d\n", oc, + chip->can_set_rate, chip->rate_set)); + if (oc < 2) + chip->can_set_rate = 1; + if (oc == 0) + chip->rate_set = 0; + DE_ACT(("pcm_close2 oc=%d cs=%d rs=%d\n", oc, + chip->can_set_rate,chip->rate_set)); + + return 0; +} + + + +/* Channel allocation and scatter-gather list setup */ +static int init_engine(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params, + int pipe_index, int interleave) +{ + struct echoaudio *chip; + int err, per, rest, page, edge, offs; + struct snd_sg_buf *sgbuf; + struct audiopipe *pipe; + + chip = snd_pcm_substream_chip(substream); + pipe = (struct audiopipe *) substream->runtime->private_data; + + /* Sets up che hardware. If it's already initialized, reset and + * redo with the new parameters + */ + spin_lock_irq(&chip->lock); + if (pipe->index >= 0) { + DE_HWP(("hwp_ie free(%d)\n", pipe->index)); + err = free_pipes(chip, pipe); + snd_assert(!err); + chip->substream[pipe->index] = NULL; + } + + err = allocate_pipes(chip, pipe, pipe_index, interleave); + if (err < 0) { + spin_unlock_irq(&chip->lock); + DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n", + pipe_index, err)); + return err; + } + spin_unlock_irq(&chip->lock); + DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index)); + + DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", + params_buffer_bytes(hw_params), params_periods(hw_params), + params_period_bytes(hw_params))); + err = snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); + if (err < 0) { + snd_printk(KERN_ERR "malloc_pages err=%d\n", err); + spin_lock_irq(&chip->lock); + free_pipes(chip, pipe); + spin_unlock_irq(&chip->lock); + pipe->index = -1; + return err; + } + + sgbuf = snd_pcm_substream_sgbuf(substream); + + DE_HWP(("pcm_hw_params table size=%d pages=%d\n", + sgbuf->size, sgbuf->pages)); + sglist_init(chip, pipe); + edge = PAGE_SIZE; + for (offs = page = per = 0; offs < params_buffer_bytes(hw_params); + per++) { + rest = params_period_bytes(hw_params); + if (offs + rest > params_buffer_bytes(hw_params)) + rest = params_buffer_bytes(hw_params) - offs; + while (rest) { + if (rest <= edge - offs) { + sglist_add_mapping(chip, pipe, + snd_sgbuf_get_addr(sgbuf, offs), + rest); + sglist_add_irq(chip, pipe); + offs += rest; + rest = 0; + } else { + sglist_add_mapping(chip, pipe, + snd_sgbuf_get_addr(sgbuf, offs), + edge - offs); + rest -= edge - offs; + offs = edge; + } + if (offs == edge) { + edge += PAGE_SIZE; + page++; + } + } + } + + /* Close the ring buffer */ + sglist_wrap(chip, pipe); + + /* This stuff is used by the irq handler, so it must be + * initialized before chip->substream + */ + chip->last_period[pipe_index] = 0; + pipe->last_counter = 0; + pipe->position = 0; + smp_wmb(); + chip->substream[pipe_index] = substream; + chip->rate_set = 1; + spin_lock_irq(&chip->lock); + set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den); + spin_unlock_irq(&chip->lock); + DE_HWP(("pcm_hw_params ok\n")); + return 0; +} + + + +static int pcm_analog_in_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + + return init_engine(substream, hw_params, px_analog_in(chip) + + substream->number, params_channels(hw_params)); +} + + + +static int pcm_analog_out_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + return init_engine(substream, hw_params, substream->number, + params_channels(hw_params)); +} + + + +#ifdef ECHOCARD_HAS_DIGITAL_IO + +static int pcm_digital_in_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + + return init_engine(substream, hw_params, px_digital_in(chip) + + substream->number, params_channels(hw_params)); +} + + + +#ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ +static int pcm_digital_out_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + + return init_engine(substream, hw_params, px_digital_out(chip) + + substream->number, params_channels(hw_params)); +} +#endif /* !ECHOCARD_HAS_VMIXER */ + +#endif /* ECHOCARD_HAS_DIGITAL_IO */ + + + +static int pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct echoaudio *chip; + struct audiopipe *pipe; + + chip = snd_pcm_substream_chip(substream); + pipe = (struct audiopipe *) substream->runtime->private_data; + + spin_lock_irq(&chip->lock); + if (pipe->index >= 0) { + DE_HWP(("pcm_hw_free(%d)\n", pipe->index)); + free_pipes(chip, pipe); + chip->substream[pipe->index] = NULL; + pipe->index = -1; + } + spin_unlock_irq(&chip->lock); + + DE_HWP(("pcm_hw_freed\n")); + snd_pcm_lib_free_pages(substream); + return 0; +} + + + +static int pcm_prepare(struct snd_pcm_substream *substream) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct audioformat format; + int pipe_index = ((struct audiopipe *)runtime->private_data)->index; + + DE_HWP(("Prepare rate=%d format=%d channels=%d\n", + runtime->rate, runtime->format, runtime->channels)); + format.interleave = runtime->channels; + format.data_are_bigendian = 0; + format.mono_to_stereo = 0; + switch (runtime->format) { + case SNDRV_PCM_FORMAT_U8: + format.bits_per_sample = 8; + break; + case SNDRV_PCM_FORMAT_S16_LE: + format.bits_per_sample = 16; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + format.bits_per_sample = 24; + break; + case SNDRV_PCM_FORMAT_S32_BE: + format.data_are_bigendian = 1; + case SNDRV_PCM_FORMAT_S32_LE: + format.bits_per_sample = 32; + break; + default: + DE_HWP(("Prepare error: unsupported format %d\n", + runtime->format)); + return -EINVAL; + } + + snd_assert(pipe_index < px_num(chip), return -EINVAL); + snd_assert(is_pipe_allocated(chip, pipe_index), return -EINVAL); + set_audio_format(chip, pipe_index, &format); + return 0; +} + + + +static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct echoaudio *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct audiopipe *pipe = runtime->private_data; + int i, err; + u32 channelmask = 0; + struct list_head *pos; + struct snd_pcm_substream *s; + + snd_pcm_group_for_each(pos, substream) { + s = snd_pcm_group_substream_entry(pos); + for (i = 0; i < DSP_MAXPIPES; i++) { + if (s == chip->substream[i]) { + channelmask |= 1 << i; + snd_pcm_trigger_done(s, substream); + } + } + } + + spin_lock(&chip->lock); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + DE_ACT(("pcm_trigger start\n")); + for (i = 0; i < DSP_MAXPIPES; i++) { + if (channelmask & (1 << i)) { + pipe = chip->substream[i]->runtime->private_data; + switch (pipe->state) { + case PIPE_STATE_STOPPED: + chip->last_period[i] = 0; + pipe->last_counter = 0; + pipe->position = 0; + *pipe->dma_counter = 0; + case PIPE_STATE_PAUSED: + pipe->state = PIPE_STATE_STARTED; + break; + case PIPE_STATE_STARTED: + break; + } + } + } + err = start_transport(chip, channelmask, + chip->pipe_cyclic_mask); + break; + case SNDRV_PCM_TRIGGER_STOP: + DE_ACT(("pcm_trigger stop\n")); + for (i = 0; i < DSP_MAXPIPES; i++) { + if (channelmask & (1 << i)) { + pipe = chip->substream[i]->runtime->private_data; + pipe->state = PIPE_STATE_STOPPED; + } + } + err = stop_transport(chip, channelmask); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + DE_ACT(("pcm_trigger pause\n")); + for (i = 0; i < DSP_MAXPIPES; i++) { + if (channelmask & (1 << i)) { + pipe = chip->substream[i]->runtime->private_data; + pipe->state = PIPE_STATE_PAUSED; + } + } + err = pause_transport(chip, channelmask); + break; + default: + err = -EINVAL; + } + spin_unlock(&chip->lock); + return err; +} + + + +static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct audiopipe *pipe = runtime->private_data; + size_t cnt, bufsize, pos; + + cnt = le32_to_cpu(*pipe->dma_counter); + pipe->position += cnt - pipe->last_counter; + pipe->last_counter = cnt; + bufsize = substream->runtime->buffer_size; + pos = bytes_to_frames(substream->runtime, pipe->position); + + while (pos >= bufsize) { + pipe->position -= frames_to_bytes(substream->runtime, bufsize); + pos -= bufsize; + } + return pos; +} + + + +/* pcm *_ops structures */ +static struct snd_pcm_ops analog_playback_ops = { + .open = pcm_analog_out_open, + .close = pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = pcm_analog_out_hw_params, + .hw_free = pcm_hw_free, + .prepare = pcm_prepare, + .trigger = pcm_trigger, + .pointer = pcm_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; +static struct snd_pcm_ops analog_capture_ops = { + .open = pcm_analog_in_open, + .close = pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = pcm_analog_in_hw_params, + .hw_free = pcm_hw_free, + .prepare = pcm_prepare, + .trigger = pcm_trigger, + .pointer = pcm_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; +#ifdef ECHOCARD_HAS_DIGITAL_IO +#ifndef ECHOCARD_HAS_VMIXER +static struct snd_pcm_ops digital_playback_ops = { + .open = pcm_digital_out_open, + .close = pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = pcm_digital_out_hw_params, + .hw_free = pcm_hw_free, + .prepare = pcm_prepare, + .trigger = pcm_trigger, + .pointer = pcm_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; +#endif /* !ECHOCARD_HAS_VMIXER */ +static struct snd_pcm_ops digital_capture_ops = { + .open = pcm_digital_in_open, + .close = pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = pcm_digital_in_hw_params, + .hw_free = pcm_hw_free, + .prepare = pcm_prepare, + .trigger = pcm_trigger, + .pointer = pcm_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; +#endif /* ECHOCARD_HAS_DIGITAL_IO */ + + + +/* Preallocate memory only for the first substream because it's the most + * used one + */ +static int snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev) +{ + struct snd_pcm_substream *ss; + int stream, err; + + for (stream = 0; stream < 2; stream++) + for (ss = pcm->streams[stream].substream; ss; ss = ss->next) { + err = snd_pcm_lib_preallocate_pages(ss, SNDRV_DMA_TYPE_DEV_SG, + dev, + ss->number ? 0 : 128<<10, + 256<<10); + if (err < 0) + return err; + } + return 0; +} + + + +/*<--snd_echo_probe() */ +static int __devinit snd_echo_new_pcm(struct echoaudio *chip) +{ + struct snd_pcm *pcm; + int err; + +#ifdef ECHOCARD_HAS_VMIXER + /* This card has a Vmixer, that is there is no direct mapping from PCM + streams to physical outputs. The user can mix the streams as he wishes + via control interface and it's possible to send any stream to any + output, thus it makes no sense to keep analog and digital outputs + separated */ + + /* PCM#0 Virtual outputs and analog inputs */ + if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip), + num_analog_busses_in(chip), &pcm)) < 0) + return err; + pcm->private_data = chip; + chip->analog_pcm = pcm; + strcpy(pcm->name, chip->card->shortname); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); + if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) + return err; + DE_INIT(("Analog PCM ok\n")); + +#ifdef ECHOCARD_HAS_DIGITAL_IO + /* PCM#1 Digital inputs, no outputs */ + if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0, + num_digital_busses_in(chip), &pcm)) < 0) + return err; + pcm->private_data = chip; + chip->digital_pcm = pcm; + strcpy(pcm->name, chip->card->shortname); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); + if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) + return err; + DE_INIT(("Digital PCM ok\n")); +#endif /* ECHOCARD_HAS_DIGITAL_IO */ + +#else /* ECHOCARD_HAS_VMIXER */ + + /* The card can manage substreams formed by analog and digital channels + at the same time, but I prefer to keep analog and digital channels + separated, because that mixed thing is confusing and useless. So we + register two PCM devices: */ + + /* PCM#0 Analog i/o */ + if ((err = snd_pcm_new(chip->card, "Analog PCM", 0, + num_analog_busses_out(chip), + num_analog_busses_in(chip), &pcm)) < 0) + return err; + pcm->private_data = chip; + chip->analog_pcm = pcm; + strcpy(pcm->name, chip->card->shortname); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); + if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) + return err; + DE_INIT(("Analog PCM ok\n")); + +#ifdef ECHOCARD_HAS_DIGITAL_IO + /* PCM#1 Digital i/o */ + if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, + num_digital_busses_out(chip), + num_digital_busses_in(chip), &pcm)) < 0) + return err; + pcm->private_data = chip; + chip->digital_pcm = pcm; + strcpy(pcm->name, chip->card->shortname); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); + if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) + return err; + DE_INIT(("Digital PCM ok\n")); +#endif /* ECHOCARD_HAS_DIGITAL_IO */ + +#endif /* ECHOCARD_HAS_VMIXER */ + + return 0; +} + + + + +/****************************************************************************** + Control interface +******************************************************************************/ + +/******************* PCM output volume *******************/ +static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = num_busses_out(chip); + uinfo->value.integer.min = ECHOGAIN_MINOUT; + uinfo->value.integer.max = ECHOGAIN_MAXOUT; + return 0; +} + +static int snd_echo_output_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int c; + + chip = snd_kcontrol_chip(kcontrol); + for (c = 0; c < num_busses_out(chip); c++) + ucontrol->value.integer.value[c] = chip->output_gain[c]; + return 0; +} + +static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int c, changed, gain; + + changed = 0; + chip = snd_kcontrol_chip(kcontrol); + spin_lock_irq(&chip->lock); + for (c = 0; c < num_busses_out(chip); c++) { + gain = ucontrol->value.integer.value[c]; + /* Ignore out of range values */ + if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) + continue; + if (chip->output_gain[c] != gain) { + set_output_gain(chip, c, gain); + changed = 1; + } + } + if (changed) + update_output_line_level(chip); + spin_unlock_irq(&chip->lock); + return changed; +} + +#ifdef ECHOCARD_HAS_VMIXER +/* On Vmixer cards this one controls the line-out volume */ +static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { + .name = "Line Playback Volume", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_echo_output_gain_info, + .get = snd_echo_output_gain_get, + .put = snd_echo_output_gain_put, +}; +#else +static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { + .name = "PCM Playback Volume", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_echo_output_gain_info, + .get = snd_echo_output_gain_get, + .put = snd_echo_output_gain_put, +}; +#endif + + + +#ifdef ECHOCARD_HAS_INPUT_GAIN + +/******************* Analog input volume *******************/ +static int snd_echo_input_gain_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = num_analog_busses_in(chip); + uinfo->value.integer.min = ECHOGAIN_MININP; + uinfo->value.integer.max = ECHOGAIN_MAXINP; + return 0; +} + +static int snd_echo_input_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int c; + + chip = snd_kcontrol_chip(kcontrol); + for (c = 0; c < num_analog_busses_in(chip); c++) + ucontrol->value.integer.value[c] = chip->input_gain[c]; + return 0; +} + +static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int c, gain, changed; + + changed = 0; + chip = snd_kcontrol_chip(kcontrol); + spin_lock_irq(&chip->lock); + for (c = 0; c < num_analog_busses_in(chip); c++) { + gain = ucontrol->value.integer.value[c]; + /* Ignore out of range values */ + if (gain < ECHOGAIN_MININP || gain > ECHOGAIN_MAXINP) + continue; + if (chip->input_gain[c] != gain) { + set_input_gain(chip, c, gain); + changed = 1; + } + } + if (changed) + update_input_line_level(chip); + spin_unlock_irq(&chip->lock); + return changed; +} + +static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = { + .name = "Line Capture Volume", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_echo_input_gain_info, + .get = snd_echo_input_gain_get, + .put = snd_echo_input_gain_put, +}; + +#endif /* ECHOCARD_HAS_INPUT_GAIN */ + + + +#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL + +/************ Analog output nominal level (+4dBu / -10dBV) ***************/ +static int snd_echo_output_nominal_info (struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = num_analog_busses_out(chip); + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_echo_output_nominal_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int c; + + chip = snd_kcontrol_chip(kcontrol); + for (c = 0; c < num_analog_busses_out(chip); c++) + ucontrol->value.integer.value[c] = chip->nominal_level[c]; + return 0; +} + +static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int c, changed; + + changed = 0; + chip = snd_kcontrol_chip(kcontrol); + spin_lock_irq(&chip->lock); + for (c = 0; c < num_analog_busses_out(chip); c++) { + if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) { + set_nominal_level(chip, c, + ucontrol->value.integer.value[c]); + changed = 1; + } + } + if (changed) + update_output_line_level(chip); + spin_unlock_irq(&chip->lock); + return changed; +} + +static struct snd_kcontrol_new snd_echo_output_nominal_level __devinitdata = { + .name = "Line Playback Switch (-10dBV)", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_echo_output_nominal_info, + .get = snd_echo_output_nominal_get, + .put = snd_echo_output_nominal_put, +}; + +#endif /* ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL */ + + + +#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL + +/*************** Analog input nominal level (+4dBu / -10dBV) ***************/ +static int snd_echo_input_nominal_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = num_analog_busses_in(chip); + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_echo_input_nominal_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int c; + + chip = snd_kcontrol_chip(kcontrol); + for (c = 0; c < num_analog_busses_in(chip); c++) + ucontrol->value.integer.value[c] = + chip->nominal_level[bx_analog_in(chip) + c]; + return 0; +} + +static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int c, changed; + + changed = 0; + chip = snd_kcontrol_chip(kcontrol); + spin_lock_irq(&chip->lock); + for (c = 0; c < num_analog_busses_in(chip); c++) { + if (chip->nominal_level[bx_analog_in(chip) + c] != + ucontrol->value.integer.value[c]) { + set_nominal_level(chip, bx_analog_in(chip) + c, + ucontrol->value.integer.value[c]); + changed = 1; + } + } + if (changed) + update_output_line_level(chip); /* "Output" is not a mistake + * here. + */ + spin_unlock_irq(&chip->lock); + return changed; +} + +static struct snd_kcontrol_new snd_echo_intput_nominal_level __devinitdata = { + .name = "Line Capture Switch (-10dBV)", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_echo_input_nominal_info, + .get = snd_echo_input_nominal_get, + .put = snd_echo_input_nominal_put, +}; + +#endif /* ECHOCARD_HAS_INPUT_NOMINAL_LEVEL */ + + + +#ifdef ECHOCARD_HAS_MONITOR + +/******************* Monitor mixer *******************/ +static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = ECHOGAIN_MINOUT; + uinfo->value.integer.max = ECHOGAIN_MAXOUT; + uinfo->dimen.d[0] = num_busses_out(chip); + uinfo->dimen.d[1] = num_busses_in(chip); + return 0; +} + +static int snd_echo_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = + chip->monitor_gain[ucontrol->id.index / num_busses_in(chip)] + [ucontrol->id.index % num_busses_in(chip)]; + return 0; +} + +static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int changed, gain; + short out, in; + + changed = 0; + chip = snd_kcontrol_chip(kcontrol); + out = ucontrol->id.index / num_busses_in(chip); + in = ucontrol->id.index % num_busses_in(chip); + gain = ucontrol->value.integer.value[0]; + if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) + return -EINVAL; + if (chip->monitor_gain[out][in] != gain) { + spin_lock_irq(&chip->lock); + set_monitor_gain(chip, out, in, gain); + update_output_line_level(chip); + spin_unlock_irq(&chip->lock); + changed = 1; + } + return changed; +} + +static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = { + .name = "Monitor Mixer Volume", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_echo_mixer_info, + .get = snd_echo_mixer_get, + .put = snd_echo_mixer_put, +}; + +#endif /* ECHOCARD_HAS_MONITOR */ + + + +#ifdef ECHOCARD_HAS_VMIXER + +/******************* Vmixer *******************/ +static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = ECHOGAIN_MINOUT; + uinfo->value.integer.max = ECHOGAIN_MAXOUT; + uinfo->dimen.d[0] = num_busses_out(chip); + uinfo->dimen.d[1] = num_pipes_out(chip); + return 0; +} + +static int snd_echo_vmixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = + chip->vmixer_gain[ucontrol->id.index / num_pipes_out(chip)] + [ucontrol->id.index % num_pipes_out(chip)]; + return 0; +} + +static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int gain, changed; + short vch, out; + + changed = 0; + chip = snd_kcontrol_chip(kcontrol); + out = ucontrol->id.index / num_pipes_out(chip); + vch = ucontrol->id.index % num_pipes_out(chip); + gain = ucontrol->value.integer.value[0]; + if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) + return -EINVAL; + if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) { + spin_lock_irq(&chip->lock); + set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]); + update_vmixer_level(chip); + spin_unlock_irq(&chip->lock); + changed = 1; + } + return changed; +} + +static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = { + .name = "VMixer Volume", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_echo_vmixer_info, + .get = snd_echo_vmixer_get, + .put = snd_echo_vmixer_put, +}; + +#endif /* ECHOCARD_HAS_VMIXER */ + + + +#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH + +/******************* Digital mode switch *******************/ +static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *names[4] = { + "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical", + "S/PDIF Cdrom" + }; + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->value.enumerated.items = chip->num_digital_modes; + uinfo->count = 1; + if (uinfo->value.enumerated.item >= chip->num_digital_modes) + uinfo->value.enumerated.item = chip->num_digital_modes - 1; + strcpy(uinfo->value.enumerated.name, names[ + chip->digital_mode_list[uinfo->value.enumerated.item]]); + return 0; +} + +static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int i, mode; + + chip = snd_kcontrol_chip(kcontrol); + mode = chip->digital_mode; + for (i = chip->num_digital_modes - 1; i >= 0; i--) + if (mode == chip->digital_mode_list[i]) { + ucontrol->value.enumerated.item[0] = i; + break; + } + return 0; +} + +static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int changed; + unsigned short emode, dmode; + + changed = 0; + chip = snd_kcontrol_chip(kcontrol); + + emode = ucontrol->value.enumerated.item[0]; + if (emode >= chip->num_digital_modes) + return -EINVAL; + dmode = chip->digital_mode_list[emode]; + + if (dmode != chip->digital_mode) { + /* mode_mutex is required to make this operation atomic wrt + pcm_digital_*_open() and set_input_clock() functions. */ + down(&chip->mode_mutex); + + /* Do not allow the user to change the digital mode when a pcm + device is open because it also changes the number of channels + and the allowed sample rates */ + if (atomic_read(&chip->opencount)) { + changed = -EAGAIN; + } else { + changed = set_digital_mode(chip, dmode); + /* If we had to change the clock source, report it */ + if (changed > 0 && chip->clock_src_ctl) { + snd_ctl_notify(chip->card, + SNDRV_CTL_EVENT_MASK_VALUE, + &chip->clock_src_ctl->id); + DE_ACT(("SDM() =%d\n", changed)); + } + if (changed >= 0) + changed = 1; /* No errors */ + } + up(&chip->mode_mutex); + } + return changed; +} + +static struct snd_kcontrol_new snd_echo_digital_mode_switch __devinitdata = { + .name = "Digital mode Switch", + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .info = snd_echo_digital_mode_info, + .get = snd_echo_digital_mode_get, + .put = snd_echo_digital_mode_put, +}; + +#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ + + + +#ifdef ECHOCARD_HAS_DIGITAL_IO + +/******************* S/PDIF mode switch *******************/ +static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *names[2] = {"Consumer", "Professional"}; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->value.enumerated.items = 2; + uinfo->count = 1; + if (uinfo->value.enumerated.item) + uinfo->value.enumerated.item = 1; + strcpy(uinfo->value.enumerated.name, + names[uinfo->value.enumerated.item]); + return 0; +} + +static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + ucontrol->value.enumerated.item[0] = !!chip->professional_spdif; + return 0; +} + +static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int mode; + + chip = snd_kcontrol_chip(kcontrol); + mode = !!ucontrol->value.enumerated.item[0]; + if (mode != chip->professional_spdif) { + spin_lock_irq(&chip->lock); + set_professional_spdif(chip, mode); + spin_unlock_irq(&chip->lock); + return 1; + } + return 0; +} + +static struct snd_kcontrol_new snd_echo_spdif_mode_switch __devinitdata = { + .name = "S/PDIF mode Switch", + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .info = snd_echo_spdif_mode_info, + .get = snd_echo_spdif_mode_get, + .put = snd_echo_spdif_mode_put, +}; + +#endif /* ECHOCARD_HAS_DIGITAL_IO */ + + + +#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK + +/******************* Select input clock source *******************/ +static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *names[8] = { + "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync", + "ESync96", "MTC" + }; + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->value.enumerated.items = chip->num_clock_sources; + uinfo->count = 1; + if (uinfo->value.enumerated.item >= chip->num_clock_sources) + uinfo->value.enumerated.item = chip->num_clock_sources - 1; + strcpy(uinfo->value.enumerated.name, names[ + chip->clock_source_list[uinfo->value.enumerated.item]]); + return 0; +} + +static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int i, clock; + + chip = snd_kcontrol_chip(kcontrol); + clock = chip->input_clock; + + for (i = 0; i < chip->num_clock_sources; i++) + if (clock == chip->clock_source_list[i]) + ucontrol->value.enumerated.item[0] = i; + + return 0; +} + +static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int changed; + unsigned int eclock, dclock; + + changed = 0; + chip = snd_kcontrol_chip(kcontrol); + eclock = ucontrol->value.enumerated.item[0]; + if (eclock >= chip->input_clock_types) + return -EINVAL; + dclock = chip->clock_source_list[eclock]; + if (chip->input_clock != dclock) { + down(&chip->mode_mutex); + spin_lock_irq(&chip->lock); + if ((changed = set_input_clock(chip, dclock)) == 0) + changed = 1; /* no errors */ + spin_unlock_irq(&chip->lock); + up(&chip->mode_mutex); + } + + if (changed < 0) + DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed)); + + return changed; +} + +static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = { + .name = "Sample Clock Source", + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .info = snd_echo_clock_source_info, + .get = snd_echo_clock_source_get, + .put = snd_echo_clock_source_put, +}; + +#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ + + + +#ifdef ECHOCARD_HAS_PHANTOM_POWER + +/******************* Phantom power switch *******************/ +static int snd_echo_phantom_power_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = chip->phantom_power; + return 0; +} + +static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip = snd_kcontrol_chip(kcontrol); + int power, changed = 0; + + power = !!ucontrol->value.integer.value[0]; + if (chip->phantom_power != power) { + spin_lock_irq(&chip->lock); + changed = set_phantom_power(chip, power); + spin_unlock_irq(&chip->lock); + if (changed == 0) + changed = 1; /* no errors */ + } + return changed; +} + +static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = { + .name = "Phantom power Switch", + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .info = snd_echo_phantom_power_info, + .get = snd_echo_phantom_power_get, + .put = snd_echo_phantom_power_put, +}; + +#endif /* ECHOCARD_HAS_PHANTOM_POWER */ + + + +#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE + +/******************* Digital input automute switch *******************/ +static int snd_echo_automute_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_echo_automute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = chip->digital_in_automute; + return 0; +} + +static int snd_echo_automute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip = snd_kcontrol_chip(kcontrol); + int automute, changed = 0; + + automute = !!ucontrol->value.integer.value[0]; + if (chip->digital_in_automute != automute) { + spin_lock_irq(&chip->lock); + changed = set_input_auto_mute(chip, automute); + spin_unlock_irq(&chip->lock); + if (changed == 0) + changed = 1; /* no errors */ + } + return changed; +} + +static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = { + .name = "Digital Capture Switch (automute)", + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .info = snd_echo_automute_info, + .get = snd_echo_automute_get, + .put = snd_echo_automute_put, +}; + +#endif /* ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE */ + + + +/******************* VU-meters switch *******************/ +static int snd_echo_vumeters_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + spin_lock_irq(&chip->lock); + set_meters_on(chip, ucontrol->value.integer.value[0]); + spin_unlock_irq(&chip->lock); + return 1; +} + +static struct snd_kcontrol_new snd_echo_vumeters_switch __devinitdata = { + .name = "VU-meters Switch", + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .access = SNDRV_CTL_ELEM_ACCESS_WRITE, + .info = snd_echo_vumeters_switch_info, + .put = snd_echo_vumeters_switch_put, +}; + + + +/***** Read VU-meters (input, output, analog and digital together) *****/ +static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 96; + uinfo->value.integer.min = ECHOGAIN_MINOUT; + uinfo->value.integer.max = 0; +#ifdef ECHOCARD_HAS_VMIXER + uinfo->dimen.d[0] = 3; /* Out, In, Virt */ +#else + uinfo->dimen.d[0] = 2; /* Out, In */ +#endif + uinfo->dimen.d[1] = 16; /* 16 channels */ + uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */ + return 0; +} + +static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + get_audio_meters(chip, ucontrol->value.integer.value); + return 0; +} + +static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = { + .name = "VU-meters", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_echo_vumeters_info, + .get = snd_echo_vumeters_get, +}; + + + +/*** Channels info - it exports informations about the number of channels ***/ +static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct echoaudio *chip; + + chip = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 6; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1 << ECHO_CLOCK_NUMBER; + return 0; +} + +static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct echoaudio *chip; + int detected, clocks, bit, src; + + chip = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = num_busses_in(chip); + ucontrol->value.integer.value[1] = num_analog_busses_in(chip); + ucontrol->value.integer.value[2] = num_busses_out(chip); + ucontrol->value.integer.value[3] = num_analog_busses_out(chip); + ucontrol->value.integer.value[4] = num_pipes_out(chip); + + /* Compute the bitmask of the currently valid input clocks */ + detected = detect_input_clocks(chip); + clocks = 0; + src = chip->num_clock_sources - 1; + for (bit = ECHO_CLOCK_NUMBER - 1; bit >= 0; bit--) + if (detected & (1 << bit)) + for (; src >= 0; src--) + if (bit == chip->clock_source_list[src]) { + clocks |= 1 << src; + break; + } + ucontrol->value.integer.value[5] = clocks; + + return 0; +} + +static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = { + .name = "Channels info", + .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_echo_channels_info_info, + .get = snd_echo_channels_info_get, +}; + + + + +/****************************************************************************** + IRQ Handler +******************************************************************************/ + +static irqreturn_t snd_echo_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + struct echoaudio *chip = dev_id; + struct snd_pcm_substream *substream; + int period, ss, st; + + spin_lock(&chip->lock); + st = service_irq(chip); + if (st < 0) { + spin_unlock(&chip->lock); + return IRQ_NONE; + } + /* The hardware doesn't tell us which substream caused the irq, + thus we have to check all running substreams. */ + for (ss = 0; ss < DSP_MAXPIPES; ss++) { + if ((substream = chip->substream[ss])) { + period = pcm_pointer(substream) / + substream->runtime->period_size; + if (period != chip->last_period[ss]) { + chip->last_period[ss] = period; + spin_unlock(&chip->lock); + snd_pcm_period_elapsed(substream); + spin_lock(&chip->lock); + } + } + } + spin_unlock(&chip->lock); + +#ifdef ECHOCARD_HAS_MIDI + if (st > 0 && chip->midi_in) { + snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st); + DE_MID(("rawmidi_iread=%d\n", st)); + } +#endif + return IRQ_HANDLED; +} + + + + +/****************************************************************************** + Module construction / destruction +******************************************************************************/ + +static int snd_echo_free(struct echoaudio *chip) +{ + DE_INIT(("Stop DSP...\n")); + if (chip->comm_page) { + rest_in_peace(chip); + snd_dma_free_pages(&chip->commpage_dma_buf); + } + DE_INIT(("Stopped.\n")); + + if (chip->irq >= 0) + free_irq(chip->irq, (void *)chip); + + if (chip->dsp_registers) + iounmap(chip->dsp_registers); + + if (chip->iores) + release_and_free_resource(chip->iores); + + DE_INIT(("MMIO freed.\n")); + + pci_disable_device(chip->pci); + + /* release chip data */ + kfree(chip); + DE_INIT(("Chip freed.\n")); + return 0; +} + + + +static int snd_echo_dev_free(struct snd_device *device) +{ + struct echoaudio *chip = device->device_data; + + DE_INIT(("snd_echo_dev_free()...\n")); + return snd_echo_free(chip); +} + + + +/* <--snd_echo_probe() */ +static __devinit int snd_echo_create(struct snd_card *card, + struct pci_dev *pci, + struct echoaudio **rchip) +{ + struct echoaudio *chip; + int err; + size_t sz; + static struct snd_device_ops ops = { + .dev_free = snd_echo_dev_free, + }; + + *rchip = NULL; + + pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0); + + if ((err = pci_enable_device(pci)) < 0) + return err; + pci_set_master(pci); + + /* allocate a chip-specific data */ + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (!chip) { + pci_disable_device(pci); + return -ENOMEM; + } + DE_INIT(("chip=%p\n", chip)); + + spin_lock_init(&chip->lock); + chip->card = card; + chip->pci = pci; + chip->irq = -1; + + /* PCI resource allocation */ + chip->dsp_registers_phys = pci_resource_start(pci, 0); + sz = pci_resource_len(pci, 0); + if (sz > PAGE_SIZE) + sz = PAGE_SIZE; /* We map only the required part */ + + if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz, + ECHOCARD_NAME)) == NULL) { + snd_echo_free(chip); + snd_printk(KERN_ERR "cannot get memory region\n"); + return -EBUSY; + } + chip->dsp_registers = (volatile u32 __iomem *) + ioremap_nocache(chip->dsp_registers_phys, sz); + + if (request_irq(pci->irq, snd_echo_interrupt, SA_INTERRUPT | SA_SHIRQ, + ECHOCARD_NAME, (void *)chip)) { + snd_echo_free(chip); + snd_printk(KERN_ERR "cannot grab irq\n"); + return -EBUSY; + } + chip->irq = pci->irq; + DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n", + chip->pci, chip->irq, chip->pci->subsystem_device)); + + /* Create the DSP comm page - this is the area of memory used for most + of the communication with the DSP, which accesses it via bus mastering */ + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), + sizeof(struct comm_page), + &chip->commpage_dma_buf) < 0) { + snd_echo_free(chip); + snd_printk(KERN_ERR "cannot allocate the comm page\n"); + return -ENOMEM; + } + chip->comm_page_phys = chip->commpage_dma_buf.addr; + chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; + + err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); + if (err) { + DE_INIT(("init_hw err=%d\n", err)); + snd_echo_free(chip); + return err; + } + DE_INIT(("Card init OK\n")); + + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { + snd_echo_free(chip); + return err; + } + atomic_set(&chip->opencount, 0); + init_MUTEX(&chip->mode_mutex); + chip->can_set_rate = 1; + *rchip = chip; + /* Init done ! */ + return 0; +} + + + +/* constructor */ +static int __devinit snd_echo_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + static int dev; + struct snd_card *card; + struct echoaudio *chip; + char *dsp; + int i, err; + + if (dev >= SNDRV_CARDS) + return -ENODEV; + if (!enable[dev]) { + dev++; + return -ENOENT; + } + + DE_INIT(("Echoaudio driver starting...\n")); + i = 0; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; + + if ((err = snd_echo_create(card, pci, &chip)) < 0) { + snd_card_free(card); + return err; + } + + strcpy(card->driver, "Echo_" ECHOCARD_NAME); + strcpy(card->shortname, chip->card_name); + + dsp = "56301"; + if (pci_id->device == 0x3410) + dsp = "56361"; + + sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i", + card->shortname, pci_id->subdevice & 0x000f, dsp, + chip->dsp_registers_phys, chip->irq); + + if ((err = snd_echo_new_pcm(chip)) < 0) { + snd_printk(KERN_ERR "new pcm error %d\n", err); + snd_card_free(card); + return err; + } + +#ifdef ECHOCARD_HAS_MIDI + if (chip->has_midi) { /* Some Mia's do not have midi */ + if ((err = snd_echo_midi_create(card, chip)) < 0) { + snd_printk(KERN_ERR "new midi error %d\n", err); + snd_card_free(card); + return err; + } + } +#endif + +#ifdef ECHOCARD_HAS_VMIXER + snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_output_gain, chip))) < 0) + goto ctl_error; + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) + goto ctl_error; +#else + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0) + goto ctl_error; +#endif + +#ifdef ECHOCARD_HAS_INPUT_GAIN + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0) + goto ctl_error; +#endif + +#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL + if (!chip->hasnt_input_nominal_level) + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0) + goto ctl_error; +#endif + +#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0) + goto ctl_error; +#endif + + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0) + goto ctl_error; + + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0) + goto ctl_error; + +#ifdef ECHOCARD_HAS_MONITOR + snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip); + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0) + goto ctl_error; +#endif + +#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0) + goto ctl_error; +#endif + + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0) + goto ctl_error; + +#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH + /* Creates a list of available digital modes */ + chip->num_digital_modes = 0; + for (i = 0; i < 6; i++) + if (chip->digital_modes & (1 << i)) + chip->digital_mode_list[chip->num_digital_modes++] = i; + + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0) + goto ctl_error; +#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ + +#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK + /* Creates a list of available clock sources */ + chip->num_clock_sources = 0; + for (i = 0; i < 10; i++) + if (chip->input_clock_types & (1 << i)) + chip->clock_source_list[chip->num_clock_sources++] = i; + + if (chip->num_clock_sources > 1) { + chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip); + if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0) + goto ctl_error; + } +#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ + +#ifdef ECHOCARD_HAS_DIGITAL_IO + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0) + goto ctl_error; +#endif + +#ifdef ECHOCARD_HAS_PHANTOM_POWER + if (chip->has_phantom_power) + if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0) + goto ctl_error; +#endif + + if ((err = snd_card_register(card)) < 0) { + snd_card_free(card); + goto ctl_error; + } + snd_printk(KERN_INFO "Card registered: %s\n", card->longname); + + pci_set_drvdata(pci, chip); + dev++; + return 0; + +ctl_error: + snd_printk(KERN_ERR "new control error %d\n", err); + snd_card_free(card); + return err; +} + + + +static void __devexit snd_echo_remove(struct pci_dev *pci) +{ + struct echoaudio *chip; + + chip = pci_get_drvdata(pci); + if (chip) + snd_card_free(chip->card); + pci_set_drvdata(pci, NULL); +} + + + +/****************************************************************************** + Everything starts and ends here +******************************************************************************/ + +/* pci_driver definition */ +static struct pci_driver driver = { + .name = "Echoaudio " ECHOCARD_NAME, + .id_table = snd_echo_ids, + .probe = snd_echo_probe, + .remove = __devexit_p(snd_echo_remove), +}; + + + +/* initialization of the module */ +static int __init alsa_card_echo_init(void) +{ + return pci_register_driver(&driver); +} + + + +/* clean up the module */ +static void __exit alsa_card_echo_exit(void) +{ + pci_unregister_driver(&driver); +} + + +module_init(alsa_card_echo_init) +module_exit(alsa_card_echo_exit) diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h new file mode 100644 index 000000000..7e88c968e --- /dev/null +++ b/sound/pci/echoaudio/echoaudio.h @@ -0,0 +1,590 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + **************************************************************************** + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + + **************************************************************************** + + + Here's a block diagram of how most of the cards work: + + +-----------+ + record | |<-------------------- Inputs + <-------| | | + PCI | Transport | | + bus | engine | \|/ + ------->| | +-------+ + play | |--->|monitor|-------> Outputs + +-----------+ | mixer | + +-------+ + + The lines going to and from the PCI bus represent "pipes". A pipe performs + audio transport - moving audio data to and from buffers on the host via + bus mastering. + + The inputs and outputs on the right represent input and output "busses." + A bus is a physical, real connection to the outside world. An example + of a bus would be the 1/4" analog connectors on the back of Layla or + an RCA S/PDIF connector. + + For most cards, there is a one-to-one correspondence between outputs + and busses; that is, each individual pipe is hard-wired to a single bus. + + Cards that work this way are Darla20, Gina20, Layla20, Darla24, Gina24, + Layla24, Mona, and Indigo. + + + Mia has a feature called "virtual outputs." + + + +-----------+ + record | |<----------------------------- Inputs + <-------| | | + PCI | Transport | | + bus | engine | \|/ + ------->| | +------+ +-------+ + play | |-->|vmixer|-->|monitor|-------> Outputs + +-----------+ +------+ | mixer | + +-------+ + + + Obviously, the difference here is the box labeled "vmixer." Vmixer is + short for "virtual output mixer." For Mia, pipes are *not* hard-wired + to a single bus; the vmixer lets you mix any pipe to any bus in any + combination. + + Note, however, that the left-hand side of the diagram is unchanged. + Transport works exactly the same way - the difference is in the mixer stage. + + + Pipes and busses are numbered starting at zero. + + + + Pipe index + ========== + + A number of calls in CEchoGals refer to a "pipe index". A pipe index is + a unique number for a pipe that unambiguously refers to a playback or record + pipe. Pipe indices are numbered starting with analog outputs, followed by + digital outputs, then analog inputs, then digital inputs. + + Take Gina24 as an example: + + Pipe index + + 0-7 Analog outputs (0 .. FirstDigitalBusOut-1) + 8-15 Digital outputs (FirstDigitalBusOut .. NumBussesOut-1) + 16-17 Analog inputs + 18-25 Digital inputs + + + You get the pipe index by calling CEchoGals::OpenAudio; the other transport + functions take the pipe index as a parameter. If you need a pipe index for + some other reason, use the handy Makepipe_index method. + + + Some calls take a CChannelMask parameter; CChannelMask is a handy way to + group pipe indices. + + + + Digital mode switch + =================== + + Some cards (right now, Gina24, Layla24, and Mona) have a Digital Mode Switch + or DMS. Cards with a DMS can be set to one of three mutually exclusive + digital modes: S/PDIF RCA, S/PDIF optical, or ADAT optical. + + This may create some confusion since ADAT optical is 8 channels wide and + S/PDIF is only two channels wide. Gina24, Layla24, and Mona handle this + by acting as if they always have 8 digital outs and ins. If you are in + either S/PDIF mode, the last 6 channels don't do anything - data sent + out these channels is thrown away and you will always record zeros. + + Note that with Gina24, Layla24, and Mona, sample rates above 50 kHz are + only available if you have the card configured for S/PDIF optical or S/PDIF + RCA. + + + + Double speed mode + ================= + + Some of the cards support 88.2 kHz and 96 kHz sampling (Darla24, Gina24, + Layla24, Mona, Mia, and Indigo). For these cards, the driver sometimes has + to worry about "double speed mode"; double speed mode applies whenever the + sampling rate is above 50 kHz. + + For instance, Mona and Layla24 support word clock sync. However, they + actually support two different word clock modes - single speed (below + 50 kHz) and double speed (above 50 kHz). The hardware detects if a single + or double speed word clock signal is present; the generic code uses that + information to determine which mode to use. + + The generic code takes care of all this for you. +*/ + + +#ifndef _ECHOAUDIO_H_ +#define _ECHOAUDIO_H_ + + +#define TRUE 1 +#define FALSE 0 + +#include "echoaudio_dsp.h" + + + +/*********************************************************************** + + PCI configuration space + +***********************************************************************/ + +/* + * PCI vendor ID and device IDs for the hardware + */ +#define VENDOR_ID 0x1057 +#define DEVICE_ID_56301 0x1801 +#define DEVICE_ID_56361 0x3410 +#define SUBVENDOR_ID 0xECC0 + + +/* + * Valid Echo PCI subsystem card IDs + */ +#define DARLA20 0x0010 +#define GINA20 0x0020 +#define LAYLA20 0x0030 +#define DARLA24 0x0040 +#define GINA24 0x0050 +#define LAYLA24 0x0060 +#define MONA 0x0070 +#define MIA 0x0080 +#define INDIGO 0x0090 +#define INDIGO_IO 0x00a0 +#define INDIGO_DJ 0x00b0 +#define ECHO3G 0x0100 + + +/************************************************************************ + + Array sizes and so forth + +***********************************************************************/ + +/* + * Sizes + */ +#define ECHO_MAXAUDIOINPUTS 32 /* Max audio input channels */ +#define ECHO_MAXAUDIOOUTPUTS 32 /* Max audio output channels */ +#define ECHO_MAXAUDIOPIPES 32 /* Max number of input and output + * pipes */ +#define E3G_MAX_OUTPUTS 16 +#define ECHO_MAXMIDIJACKS 1 /* Max MIDI ports */ +#define ECHO_MIDI_QUEUE_SZ 512 /* Max MIDI input queue entries */ +#define ECHO_MTC_QUEUE_SZ 32 /* Max MIDI time code input queue + * entries */ + +/* + * MIDI activity indicator timeout + */ +#define MIDI_ACTIVITY_TIMEOUT_USEC 200000 + + +/**************************************************************************** + + Clocks + +*****************************************************************************/ + +/* + * Clock numbers + */ +#define ECHO_CLOCK_INTERNAL 0 +#define ECHO_CLOCK_WORD 1 +#define ECHO_CLOCK_SUPER 2 +#define ECHO_CLOCK_SPDIF 3 +#define ECHO_CLOCK_ADAT 4 +#define ECHO_CLOCK_ESYNC 5 +#define ECHO_CLOCK_ESYNC96 6 +#define ECHO_CLOCK_MTC 7 +#define ECHO_CLOCK_NUMBER 8 +#define ECHO_CLOCKS 0xffff + +/* + * Clock bit numbers - used to report capabilities and whatever clocks + * are being detected dynamically. + */ +#define ECHO_CLOCK_BIT_INTERNAL (1 << ECHO_CLOCK_INTERNAL) +#define ECHO_CLOCK_BIT_WORD (1 << ECHO_CLOCK_WORD) +#define ECHO_CLOCK_BIT_SUPER (1 << ECHO_CLOCK_SUPER) +#define ECHO_CLOCK_BIT_SPDIF (1 << ECHO_CLOCK_SPDIF) +#define ECHO_CLOCK_BIT_ADAT (1 << ECHO_CLOCK_ADAT) +#define ECHO_CLOCK_BIT_ESYNC (1 << ECHO_CLOCK_ESYNC) +#define ECHO_CLOCK_BIT_ESYNC96 (1 << ECHO_CLOCK_ESYNC96) +#define ECHO_CLOCK_BIT_MTC (1<comm_page->handshake = 0; +} + +static inline u32 get_dsp_register(struct echoaudio *chip, u32 index) +{ + return readl(&chip->dsp_registers[index]); +} + +static inline void set_dsp_register(struct echoaudio *chip, u32 index, + u32 value) +{ + writel(value, &chip->dsp_registers[index]); +} + + +/* Pipe and bus indexes. PX_* and BX_* are defined as chip->px_* and chip->bx_* +for 3G cards because they depend on the external box. They are integer +constants for all other cards. +Never use those defines directly, use the following functions instead. */ + +static inline int px_digital_out(const struct echoaudio *chip) +{ + return PX_DIGITAL_OUT; +} + +static inline int px_analog_in(const struct echoaudio *chip) +{ + return PX_ANALOG_IN; +} + +static inline int px_digital_in(const struct echoaudio *chip) +{ + return PX_DIGITAL_IN; +} + +static inline int px_num(const struct echoaudio *chip) +{ + return PX_NUM; +} + +static inline int bx_digital_out(const struct echoaudio *chip) +{ + return BX_DIGITAL_OUT; +} + +static inline int bx_analog_in(const struct echoaudio *chip) +{ + return BX_ANALOG_IN; +} + +static inline int bx_digital_in(const struct echoaudio *chip) +{ + return BX_DIGITAL_IN; +} + +static inline int bx_num(const struct echoaudio *chip) +{ + return BX_NUM; +} + +static inline int num_pipes_out(const struct echoaudio *chip) +{ + return px_analog_in(chip); +} + +static inline int num_pipes_in(const struct echoaudio *chip) +{ + return px_num(chip) - px_analog_in(chip); +} + +static inline int num_busses_out(const struct echoaudio *chip) +{ + return bx_analog_in(chip); +} + +static inline int num_busses_in(const struct echoaudio *chip) +{ + return bx_num(chip) - bx_analog_in(chip); +} + +static inline int num_analog_busses_out(const struct echoaudio *chip) +{ + return bx_digital_out(chip); +} + +static inline int num_analog_busses_in(const struct echoaudio *chip) +{ + return bx_digital_in(chip) - bx_analog_in(chip); +} + +static inline int num_digital_busses_out(const struct echoaudio *chip) +{ + return num_busses_out(chip) - num_analog_busses_out(chip); +} + +static inline int num_digital_busses_in(const struct echoaudio *chip) +{ + return num_busses_in(chip) - num_analog_busses_in(chip); +} + +/* The monitor array is a one-dimensional array; compute the offset + * into the array */ +static inline int monitor_index(const struct echoaudio *chip, int out, int in) +{ + return out * num_busses_in(chip) + in; +} + + +#ifndef pci_device +#define pci_device(chip) (&chip->pci->dev) +#endif + + +#endif /* _ECHOAUDIO_H_ */ diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c new file mode 100644 index 000000000..9f439ea45 --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_3g.c @@ -0,0 +1,431 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + + +/* These functions are common for all "3G" cards */ + + +static int check_asic_status(struct echoaudio *chip) +{ + u32 box_status; + + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->ext_box_status = + __constant_cpu_to_le32(E3G_ASIC_NOT_LOADED); + chip->asic_loaded = FALSE; + clear_handshake(chip); + send_vector(chip, DSP_VC_TEST_ASIC); + + if (wait_handshake(chip)) { + chip->dsp_code = NULL; + return -EIO; + } + + box_status = le32_to_cpu(chip->comm_page->ext_box_status); + DE_INIT(("box_status=%x\n", box_status)); + if (box_status == E3G_ASIC_NOT_LOADED) + return -ENODEV; + + chip->asic_loaded = TRUE; + return box_status & E3G_BOX_TYPE_MASK; +} + + + +static inline u32 get_frq_reg(struct echoaudio *chip) +{ + return le32_to_cpu(chip->comm_page->e3g_frq_register); +} + + + +/* Most configuration of 3G cards is accomplished by writing the control +register. write_control_reg sends the new control register value to the DSP. */ +static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, + char force) +{ + if (wait_handshake(chip)) + return -EIO; + + DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq)); + + ctl = cpu_to_le32(ctl); + frq = cpu_to_le32(frq); + + if (ctl != chip->comm_page->control_register || + frq != chip->comm_page->e3g_frq_register || force) { + chip->comm_page->e3g_frq_register = frq; + chip->comm_page->control_register = ctl; + clear_handshake(chip); + return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); + } + + DE_ACT(("WriteControlReg: not written, no change\n")); + return 0; +} + + + +/* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */ +static int set_digital_mode(struct echoaudio *chip, u8 mode) +{ + u8 previous_mode; + int err, i, o; + + /* All audio channels must be closed before changing the digital mode */ + snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); + + snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); + + previous_mode = chip->digital_mode; + err = dsp_set_digital_mode(chip, mode); + + /* If we successfully changed the digital mode from or to ADAT, + * then make sure all output, input and monitor levels are + * updated by the DSP comm object. */ + if (err >= 0 && previous_mode != mode && + (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { + spin_lock_irq(&chip->lock); + for (o = 0; o < num_busses_out(chip); o++) + for (i = 0; i < num_busses_in(chip); i++) + set_monitor_gain(chip, o, i, + chip->monitor_gain[o][i]); + +#ifdef ECHOCARD_HAS_INPUT_GAIN + for (i = 0; i < num_busses_in(chip); i++) + set_input_gain(chip, i, chip->input_gain[i]); + update_input_line_level(chip); +#endif + + for (o = 0; o < num_busses_out(chip); o++) + set_output_gain(chip, o, chip->output_gain[o]); + update_output_line_level(chip); + spin_unlock_irq(&chip->lock); + } + + return err; +} + + + +static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate) +{ + control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK; + + switch (rate) { + case 32000 : + control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1; + break; + case 44100 : + if (chip->professional_spdif) + control_reg |= E3G_SPDIF_SAMPLE_RATE0; + break; + case 48000 : + control_reg |= E3G_SPDIF_SAMPLE_RATE1; + break; + } + + if (chip->professional_spdif) + control_reg |= E3G_SPDIF_PRO_MODE; + + if (chip->non_audio_spdif) + control_reg |= E3G_SPDIF_NOT_AUDIO; + + control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL | + E3G_SPDIF_COPY_PERMIT; + + return control_reg; +} + + + +/* Set the S/PDIF output format */ +static int set_professional_spdif(struct echoaudio *chip, char prof) +{ + u32 control_reg; + + control_reg = le32_to_cpu(chip->comm_page->control_register); + chip->professional_spdif = prof; + control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate); + return write_control_reg(chip, control_reg, get_frq_reg(chip), 0); +} + + + +/* detect_input_clocks() returns a bitmask consisting of all the input clocks +currently connected to the hardware; this changes as the user connects and +disconnects clock inputs. You should use this information to determine which +clocks the user is allowed to select. */ +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + u32 clocks_from_dsp, clock_bits; + + /* Map the DSP clock detect bits to the generic driver clock + * detect bits */ + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + clock_bits = ECHO_CLOCK_BIT_INTERNAL; + + if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD) + clock_bits |= ECHO_CLOCK_BIT_WORD; + + switch(chip->digital_mode) { + case DIGITAL_MODE_SPDIF_RCA: + case DIGITAL_MODE_SPDIF_OPTICAL: + if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF) + clock_bits |= ECHO_CLOCK_BIT_SPDIF; + break; + case DIGITAL_MODE_ADAT: + if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT) + clock_bits |= ECHO_CLOCK_BIT_ADAT; + break; + } + + return clock_bits; +} + + + +static int load_asic(struct echoaudio *chip) +{ + int box_type, err; + + if (chip->asic_loaded) + return 0; + + /* Give the DSP a few milliseconds to settle down */ + mdelay(2); + + err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, + &card_fw[FW_3G_ASIC]); + if (err < 0) + return err; + + chip->asic_code = &card_fw[FW_3G_ASIC]; + + /* Now give the new ASIC a little time to set up */ + mdelay(2); + /* See if it worked */ + box_type = check_asic_status(chip); + + /* Set up the control register if the load succeeded - + * 48 kHz, internal clock, S/PDIF RCA mode */ + if (box_type >= 0) { + err = write_control_reg(chip, E3G_48KHZ, + E3G_FREQ_REG_DEFAULT, TRUE); + if (err < 0) + return err; + } + + return box_type; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u32 control_reg, clock, base_rate, frq_reg; + + /* Only set the clock for internal mode. */ + if (chip->input_clock != ECHO_CLOCK_INTERNAL) { + DE_ACT(("set_sample_rate: Cannot set sample rate - " + "clock not set to CLK_CLOCKININTERNAL\n")); + /* Save the rate anyhow */ + chip->comm_page->sample_rate = cpu_to_le32(rate); + chip->sample_rate = rate; + set_input_clock(chip, chip->input_clock); + return 0; + } + + snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, + return -EINVAL); + + clock = 0; + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= E3G_CLOCK_CLEAR_MASK; + + switch (rate) { + case 96000: + clock = E3G_96KHZ; + break; + case 88200: + clock = E3G_88KHZ; + break; + case 48000: + clock = E3G_48KHZ; + break; + case 44100: + clock = E3G_44KHZ; + break; + case 32000: + clock = E3G_32KHZ; + break; + default: + clock = E3G_CONTINUOUS_CLOCK; + if (rate > 50000) + clock |= E3G_DOUBLE_SPEED_MODE; + break; + } + + control_reg |= clock; + control_reg = set_spdif_bits(chip, control_reg, rate); + + base_rate = rate; + if (base_rate > 50000) + base_rate /= 2; + if (base_rate < 32000) + base_rate = 32000; + + frq_reg = E3G_MAGIC_NUMBER / base_rate - 2; + if (frq_reg > E3G_FREQ_REG_MAX) + frq_reg = E3G_FREQ_REG_MAX; + + chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ + chip->sample_rate = rate; + DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg)); + + /* Tell the DSP about it - DSP reads both control reg & freq reg */ + return write_control_reg(chip, control_reg, frq_reg, 0); +} + + + +/* Set the sample clock source to internal, S/PDIF, ADAT */ +static int set_input_clock(struct echoaudio *chip, u16 clock) +{ + u32 control_reg, clocks_from_dsp; + + DE_ACT(("set_input_clock:\n")); + + /* Mask off the clock select bits */ + control_reg = le32_to_cpu(chip->comm_page->control_register) & + E3G_CLOCK_CLEAR_MASK; + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + switch (clock) { + case ECHO_CLOCK_INTERNAL: + DE_ACT(("Set Echo3G clock to INTERNAL\n")); + chip->input_clock = ECHO_CLOCK_INTERNAL; + return set_sample_rate(chip, chip->sample_rate); + case ECHO_CLOCK_SPDIF: + if (chip->digital_mode == DIGITAL_MODE_ADAT) + return -EAGAIN; + DE_ACT(("Set Echo3G clock to SPDIF\n")); + control_reg |= E3G_SPDIF_CLOCK; + if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96) + control_reg |= E3G_DOUBLE_SPEED_MODE; + else + control_reg &= ~E3G_DOUBLE_SPEED_MODE; + break; + case ECHO_CLOCK_ADAT: + if (chip->digital_mode != DIGITAL_MODE_ADAT) + return -EAGAIN; + DE_ACT(("Set Echo3G clock to ADAT\n")); + control_reg |= E3G_ADAT_CLOCK; + control_reg &= ~E3G_DOUBLE_SPEED_MODE; + break; + case ECHO_CLOCK_WORD: + DE_ACT(("Set Echo3G clock to WORD\n")); + control_reg |= E3G_WORD_CLOCK; + if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96) + control_reg |= E3G_DOUBLE_SPEED_MODE; + else + control_reg &= ~E3G_DOUBLE_SPEED_MODE; + break; + default: + DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock)); + return -EINVAL; + } + + chip->input_clock = clock; + return write_control_reg(chip, control_reg, get_frq_reg(chip), 1); +} + + + +static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) +{ + u32 control_reg; + int err, incompatible_clock; + + /* Set clock to "internal" if it's not compatible with the new mode */ + incompatible_clock = FALSE; + switch (mode) { + case DIGITAL_MODE_SPDIF_OPTICAL: + case DIGITAL_MODE_SPDIF_RCA: + if (chip->input_clock == ECHO_CLOCK_ADAT) + incompatible_clock = TRUE; + break; + case DIGITAL_MODE_ADAT: + if (chip->input_clock == ECHO_CLOCK_SPDIF) + incompatible_clock = TRUE; + break; + default: + DE_ACT(("Digital mode not supported: %d\n", mode)); + return -EINVAL; + } + + spin_lock_irq(&chip->lock); + + if (incompatible_clock) { + chip->sample_rate = 48000; + set_input_clock(chip, ECHO_CLOCK_INTERNAL); + } + + /* Clear the current digital mode */ + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK; + + /* Tweak the control reg */ + switch (mode) { + case DIGITAL_MODE_SPDIF_OPTICAL: + control_reg |= E3G_SPDIF_OPTICAL_MODE; + break; + case DIGITAL_MODE_SPDIF_RCA: + /* E3G_SPDIF_OPTICAL_MODE bit cleared */ + break; + case DIGITAL_MODE_ADAT: + control_reg |= E3G_ADAT_MODE; + control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */ + break; + } + + err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1); + spin_unlock_irq(&chip->lock); + if (err < 0) + return err; + chip->digital_mode = mode; + + DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode)); + return incompatible_clock; +} diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c new file mode 100644 index 000000000..42afa837d --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -0,0 +1,1125 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + +#if PAGE_SIZE < 4096 +#error PAGE_SIZE is < 4k +#endif + +static int restore_dsp_rettings(struct echoaudio *chip); + + +/* Some vector commands involve the DSP reading or writing data to and from the +comm page; if you send one of these commands to the DSP, it will complete the +command and then write a non-zero value to the Handshake field in the +comm page. This function waits for the handshake to show up. */ +static int wait_handshake(struct echoaudio *chip) +{ + int i; + + /* Wait up to 10ms for the handshake from the DSP */ + for (i = 0; i < HANDSHAKE_TIMEOUT; i++) { + /* Look for the handshake value */ + if (chip->comm_page->handshake) { + /*if (i) DE_ACT(("Handshake time: %d\n", i));*/ + return 0; + } + udelay(1); + } + + snd_printk(KERN_ERR "wait_handshake(): Timeout waiting for DSP\n"); + return -EBUSY; +} + + + +/* Much of the interaction between the DSP and the driver is done via vector +commands; send_vector writes a vector command to the DSP. Typically, this +causes the DSP to read or write fields in the comm page. +PCI posting is not required thanks to the handshake logic. */ +static int send_vector(struct echoaudio *chip, u32 command) +{ + int i; + + wmb(); /* Flush all pending writes before sending the command */ + + /* Wait up to 100ms for the "vector busy" bit to be off */ + for (i = 0; i < VECTOR_BUSY_TIMEOUT; i++) { + if (!(get_dsp_register(chip, CHI32_VECTOR_REG) & + CHI32_VECTOR_BUSY)) { + set_dsp_register(chip, CHI32_VECTOR_REG, command); + /*if (i) DE_ACT(("send_vector time: %d\n", i));*/ + return 0; + } + udelay(1); + } + + DE_ACT((KERN_ERR "timeout on send_vector\n")); + return -EBUSY; +} + + + +/* write_dsp writes a 32-bit value to the DSP; this is used almost +exclusively for loading the DSP. */ +static int write_dsp(struct echoaudio *chip, u32 data) +{ + u32 status, i; + + for (i = 0; i < 10000000; i++) { /* timeout = 10s */ + status = get_dsp_register(chip, CHI32_STATUS_REG); + if ((status & CHI32_STATUS_HOST_WRITE_EMPTY) != 0) { + set_dsp_register(chip, CHI32_DATA_REG, data); + wmb(); /* write it immediately */ + return 0; + } + udelay(1); + cond_resched(); + } + + chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ + DE_ACT((KERN_ERR "write_dsp: Set bad_board to TRUE\n")); + return -EIO; +} + + + +/* read_dsp reads a 32-bit value from the DSP; this is used almost +exclusively for loading the DSP and checking the status of the ASIC. */ +static int read_dsp(struct echoaudio *chip, u32 *data) +{ + u32 status, i; + + for (i = 0; i < READ_DSP_TIMEOUT; i++) { + status = get_dsp_register(chip, CHI32_STATUS_REG); + if ((status & CHI32_STATUS_HOST_READ_FULL) != 0) { + *data = get_dsp_register(chip, CHI32_DATA_REG); + return 0; + } + udelay(1); + cond_resched(); + } + + chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ + DE_INIT((KERN_ERR "read_dsp: Set bad_board to TRUE\n")); + return -EIO; +} + + + +/**************************************************************************** + Firmware loading functions + ****************************************************************************/ + +/* This function is used to read back the serial number from the DSP; +this is triggered by the SET_COMMPAGE_ADDR command. +Only some early Echogals products have serial numbers in the ROM; +the serial number is not used, but you still need to do this as +part of the DSP load process. */ +static int read_sn(struct echoaudio *chip) +{ + int i; + u32 sn[6]; + + for (i = 0; i < 5; i++) { + if (read_dsp(chip, &sn[i])) { + snd_printk(KERN_ERR "Failed to read serial number\n"); + return -EIO; + } + } + DE_INIT(("Read serial number %08x %08x %08x %08x %08x\n", + sn[0], sn[1], sn[2], sn[3], sn[4])); + return 0; +} + + + +#ifndef ECHOCARD_HAS_ASIC +/* This card has no ASIC, just return ok */ +static inline int check_asic_status(struct echoaudio *chip) +{ + chip->asic_loaded = TRUE; + return 0; +} + +#endif /* !ECHOCARD_HAS_ASIC */ + + + +#ifdef ECHOCARD_HAS_ASIC + +/* Load ASIC code - done after the DSP is loaded */ +static int load_asic_generic(struct echoaudio *chip, u32 cmd, + const struct firmware *asic) +{ + const struct firmware *fw; + int err; + u32 i, size; + u8 *code; + + if ((err = get_firmware(&fw, asic, chip)) < 0) { + snd_printk(KERN_WARNING "Firmware not found !\n"); + return err; + } + + code = (u8 *)fw->data; + size = fw->size; + + /* Send the "Here comes the ASIC" command */ + if (write_dsp(chip, cmd) < 0) + goto la_error; + + /* Write length of ASIC file in bytes */ + if (write_dsp(chip, size) < 0) + goto la_error; + + for (i = 0; i < size; i++) { + if (write_dsp(chip, code[i]) < 0) + goto la_error; + } + + DE_INIT(("ASIC loaded\n")); + free_firmware(fw); + return 0; + +la_error: + DE_INIT(("failed on write_dsp\n")); + free_firmware(fw); + return -EIO; +} + +#endif /* ECHOCARD_HAS_ASIC */ + + + +#ifdef DSP_56361 + +/* Install the resident loader for 56361 DSPs; The resident loader is on +the EPROM on the board for 56301 DSP. The resident loader is a tiny little +program that is used to load the real DSP code. */ +static int install_resident_loader(struct echoaudio *chip) +{ + u32 address; + int index, words, i; + u16 *code; + u32 status; + const struct firmware *fw; + + /* 56361 cards only! This check is required by the old 56301-based + Mona and Gina24 */ + if (chip->device_id != DEVICE_ID_56361) + return 0; + + /* Look to see if the resident loader is present. If the resident + loader is already installed, host flag 5 will be on. */ + status = get_dsp_register(chip, CHI32_STATUS_REG); + if (status & CHI32_STATUS_REG_HF5) { + DE_INIT(("Resident loader already installed; status is 0x%x\n", + status)); + return 0; + } + + if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) { + snd_printk(KERN_WARNING "Firmware not found !\n"); + return i; + } + + /* The DSP code is an array of 16 bit words. The array is divided up + into sections. The first word of each section is the size in words, + followed by the section type. + Since DSP addresses and data are 24 bits wide, they each take up two + 16 bit words in the array. + This is a lot like the other loader loop, but it's not a loop, you + don't write the memory type, and you don't write a zero at the end. */ + + /* Set DSP format bits for 24 bit mode */ + set_dsp_register(chip, CHI32_CONTROL_REG, + get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900); + + code = (u16 *)fw->data; + + /* Skip the header section; the first word in the array is the size + of the first section, so the first real section of code is pointed + to by Code[0]. */ + index = code[0]; + + /* Skip the section size, LRS block type, and DSP memory type */ + index += 3; + + /* Get the number of DSP words to write */ + words = code[index++]; + + /* Get the DSP address for this block; 24 bits, so build from two words */ + address = ((u32)code[index] << 16) + code[index + 1]; + index += 2; + + /* Write the count to the DSP */ + if (write_dsp(chip, words)) { + DE_INIT(("install_resident_loader: Failed to write word count!\n")); + goto irl_error; + } + /* Write the DSP address */ + if (write_dsp(chip, address)) { + DE_INIT(("install_resident_loader: Failed to write DSP address!\n")); + goto irl_error; + } + /* Write out this block of code to the DSP */ + for (i = 0; i < words; i++) { + u32 data; + + data = ((u32)code[index] << 16) + code[index + 1]; + if (write_dsp(chip, data)) { + DE_INIT(("install_resident_loader: Failed to write DSP code\n")); + goto irl_error; + } + index += 2; + } + + /* Wait for flag 5 to come up */ + for (i = 0; i < 200; i++) { /* Timeout is 50us * 200 = 10ms */ + udelay(50); + status = get_dsp_register(chip, CHI32_STATUS_REG); + if (status & CHI32_STATUS_REG_HF5) + break; + } + + if (i == 200) { + DE_INIT(("Resident loader failed to set HF5\n")); + goto irl_error; + } + + DE_INIT(("Resident loader successfully installed\n")); + free_firmware(fw); + return 0; + +irl_error: + free_firmware(fw); + return -EIO; +} + +#endif /* DSP_56361 */ + + +static int load_dsp(struct echoaudio *chip, u16 *code) +{ + u32 address, data; + int index, words, i; + + if (chip->dsp_code == code) { + DE_INIT(("DSP is already loaded!\n")); + return 0; + } + chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ + chip->dsp_code = NULL; /* Current DSP code not loaded */ + chip->asic_loaded = FALSE; /* Loading the DSP code will reset the ASIC */ + + DE_INIT(("load_dsp: Set bad_board to TRUE\n")); + + /* If this board requires a resident loader, install it. */ +#ifdef DSP_56361 + if ((i = install_resident_loader(chip)) < 0) + return i; +#endif + + /* Send software reset command */ + if (send_vector(chip, DSP_VC_RESET) < 0) { + DE_INIT(("LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n")); + return -EIO; + } + /* Delay 10us */ + udelay(10); + + /* Wait 10ms for HF3 to indicate that software reset is complete */ + for (i = 0; i < 1000; i++) { /* Timeout is 10us * 1000 = 10ms */ + if (get_dsp_register(chip, CHI32_STATUS_REG) & + CHI32_STATUS_REG_HF3) + break; + udelay(10); + } + + if (i == 1000) { + DE_INIT(("load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n")); + return -EIO; + } + + /* Set DSP format bits for 24 bit mode now that soft reset is done */ + set_dsp_register(chip, CHI32_CONTROL_REG, + get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900); + + /* Main loader loop */ + + index = code[0]; + for (;;) { + int block_type, mem_type; + + /* Total Block Size */ + index++; + + /* Block Type */ + block_type = code[index]; + if (block_type == 4) /* We're finished */ + break; + + index++; + + /* Memory Type P=0,X=1,Y=2 */ + mem_type = code[index++]; + + /* Block Code Size */ + words = code[index++]; + if (words == 0) /* We're finished */ + break; + + /* Start Address */ + address = ((u32)code[index] << 16) + code[index + 1]; + index += 2; + + if (write_dsp(chip, words) < 0) { + DE_INIT(("load_dsp: failed to write number of DSP words\n")); + return -EIO; + } + if (write_dsp(chip, address) < 0) { + DE_INIT(("load_dsp: failed to write DSP address\n")); + return -EIO; + } + if (write_dsp(chip, mem_type) < 0) { + DE_INIT(("load_dsp: failed to write DSP memory type\n")); + return -EIO; + } + /* Code */ + for (i = 0; i < words; i++, index+=2) { + data = ((u32)code[index] << 16) + code[index + 1]; + if (write_dsp(chip, data) < 0) { + DE_INIT(("load_dsp: failed to write DSP data\n")); + return -EIO; + } + } + } + + if (write_dsp(chip, 0) < 0) { /* We're done!!! */ + DE_INIT(("load_dsp: Failed to write final zero\n")); + return -EIO; + } + udelay(10); + + for (i = 0; i < 5000; i++) { /* Timeout is 100us * 5000 = 500ms */ + /* Wait for flag 4 - indicates that the DSP loaded OK */ + if (get_dsp_register(chip, CHI32_STATUS_REG) & + CHI32_STATUS_REG_HF4) { + set_dsp_register(chip, CHI32_CONTROL_REG, + get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00); + + if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) { + DE_INIT(("load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n")); + return -EIO; + } + + if (write_dsp(chip, chip->comm_page_phys) < 0) { + DE_INIT(("load_dsp: Failed to write comm page address\n")); + return -EIO; + } + + /* Get the serial number via slave mode. + This is triggered by the SET_COMMPAGE_ADDR command. + We don't actually use the serial number but we have to + get it as part of the DSP init voodoo. */ + if (read_sn(chip) < 0) { + DE_INIT(("load_dsp: Failed to read serial number\n")); + return -EIO; + } + + chip->dsp_code = code; /* Show which DSP code loaded */ + chip->bad_board = FALSE; /* DSP OK */ + DE_INIT(("load_dsp: OK!\n")); + return 0; + } + udelay(100); + } + + DE_INIT(("load_dsp: DSP load timed out waiting for HF4\n")); + return -EIO; +} + + + +/* load_firmware takes care of loading the DSP and any ASIC code. */ +static int load_firmware(struct echoaudio *chip) +{ + const struct firmware *fw; + int box_type, err; + + snd_assert(chip->dsp_code_to_load && chip->comm_page, return -EPERM); + + /* See if the ASIC is present and working - only if the DSP is already loaded */ + if (chip->dsp_code) { + if ((box_type = check_asic_status(chip)) >= 0) + return box_type; + /* ASIC check failed; force the DSP to reload */ + chip->dsp_code = NULL; + } + + if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0) + return err; + err = load_dsp(chip, (u16 *)fw->data); + free_firmware(fw); + if (err < 0) + return err; + + if ((box_type = load_asic(chip)) < 0) + return box_type; /* error */ + + if ((err = restore_dsp_rettings(chip)) < 0) + return err; + + return box_type; +} + + + +/**************************************************************************** + Mixer functions + ****************************************************************************/ + +#if defined(ECHOCARD_HAS_INPUT_NOMINAL_LEVEL) || \ + defined(ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL) + +/* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */ +static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer) +{ + snd_assert(index < num_busses_out(chip) + num_busses_in(chip), + return -EINVAL); + + /* Wait for the handshake (OK even if ASIC is not loaded) */ + if (wait_handshake(chip)) + return -EIO; + + chip->nominal_level[index] = consumer; + + if (consumer) + chip->comm_page->nominal_level_mask |= cpu_to_le32(1 << index); + else + chip->comm_page->nominal_level_mask &= ~cpu_to_le32(1 << index); + + return 0; +} + +#endif /* ECHOCARD_HAS_*_NOMINAL_LEVEL */ + + + +/* Set the gain for a single physical output channel (dB). */ +static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain) +{ + snd_assert(channel < num_busses_out(chip), return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + /* Save the new value */ + chip->output_gain[channel] = gain; + chip->comm_page->line_out_level[channel] = gain; + return 0; +} + + + +#ifdef ECHOCARD_HAS_MONITOR +/* Set the monitor level from an input bus to an output bus. */ +static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input, + s8 gain) +{ + snd_assert(output < num_busses_out(chip) && + input < num_busses_in(chip), return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + chip->monitor_gain[output][input] = gain; + chip->comm_page->monitors[monitor_index(chip, output, input)] = gain; + return 0; +} +#endif /* ECHOCARD_HAS_MONITOR */ + + +/* Tell the DSP to read and update output, nominal & monitor levels in comm page. */ +static int update_output_line_level(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_OUTVOL); +} + + + +/* Tell the DSP to read and update input levels in comm page */ +static int update_input_line_level(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_INGAIN); +} + + + +/* set_meters_on turns the meters on or off. If meters are turned on, the DSP +will write the meter and clock detect values to the comm page at about 30Hz */ +static void set_meters_on(struct echoaudio *chip, char on) +{ + if (on && !chip->meters_enabled) { + send_vector(chip, DSP_VC_METERS_ON); + chip->meters_enabled = 1; + } else if (!on && chip->meters_enabled) { + send_vector(chip, DSP_VC_METERS_OFF); + chip->meters_enabled = 0; + memset((s8 *)chip->comm_page->vu_meter, ECHOGAIN_MUTED, + DSP_MAXPIPES); + memset((s8 *)chip->comm_page->peak_meter, ECHOGAIN_MUTED, + DSP_MAXPIPES); + } +} + + + +/* Fill out an the given array using the current values in the comm page. +Meters are written in the comm page by the DSP in this order: + Output busses + Input busses + Output pipes (vmixer cards only) + +This function assumes there are no more than 16 in/out busses or pipes +Meters is an array [3][16][2] of long. */ +static void get_audio_meters(struct echoaudio *chip, long *meters) +{ + int i, m, n; + + m = 0; + n = 0; + for (i = 0; i < num_busses_out(chip); i++, m++) { + meters[n++] = chip->comm_page->vu_meter[m]; + meters[n++] = chip->comm_page->peak_meter[m]; + } + for (; n < 32; n++) + meters[n] = 0; + +#ifdef ECHOCARD_ECHO3G + m = E3G_MAX_OUTPUTS; /* Skip unused meters */ +#endif + + for (i = 0; i < num_busses_in(chip); i++, m++) { + meters[n++] = chip->comm_page->vu_meter[m]; + meters[n++] = chip->comm_page->peak_meter[m]; + } + for (; n < 64; n++) + meters[n] = 0; + +#ifdef ECHOCARD_HAS_VMIXER + for (i = 0; i < num_pipes_out(chip); i++, m++) { + meters[n++] = chip->comm_page->vu_meter[m]; + meters[n++] = chip->comm_page->peak_meter[m]; + } +#endif + for (; n < 96; n++) + meters[n] = 0; +} + + + +static int restore_dsp_rettings(struct echoaudio *chip) +{ + int err; + DE_INIT(("restore_dsp_settings\n")); + + if ((err = check_asic_status(chip)) < 0) + return err; + + /* @ Gina20/Darla20 only. Should be harmless for other cards. */ + chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; + chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; + chip->comm_page->handshake = 0xffffffff; + + if ((err = set_sample_rate(chip, chip->sample_rate)) < 0) + return err; + + if (chip->meters_enabled) + if (send_vector(chip, DSP_VC_METERS_ON) < 0) + return -EIO; + +#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK + if (set_input_clock(chip, chip->input_clock) < 0) + return -EIO; +#endif + +#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH + if (set_output_clock(chip, chip->output_clock) < 0) + return -EIO; +#endif + + if (update_output_line_level(chip) < 0) + return -EIO; + + if (update_input_line_level(chip) < 0) + return -EIO; + +#ifdef ECHOCARD_HAS_VMIXER + if (update_vmixer_level(chip) < 0) + return -EIO; +#endif + + if (wait_handshake(chip) < 0) + return -EIO; + clear_handshake(chip); + + DE_INIT(("restore_dsp_rettings done\n")); + return send_vector(chip, DSP_VC_UPDATE_FLAGS); +} + + + +/**************************************************************************** + Transport functions + ****************************************************************************/ + +/* set_audio_format() sets the format of the audio data in host memory for +this pipe. Note that _MS_ (mono-to-stereo) playback modes are not used by ALSA +but they are here because they are just mono while capturing */ +static void set_audio_format(struct echoaudio *chip, u16 pipe_index, + const struct audioformat *format) +{ + u16 dsp_format; + + dsp_format = DSP_AUDIOFORM_SS_16LE; + + /* Look for super-interleave (no big-endian and 8 bits) */ + if (format->interleave > 2) { + switch (format->bits_per_sample) { + case 16: + dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE; + break; + case 24: + dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE; + break; + case 32: + dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE; + break; + } + dsp_format |= format->interleave; + } else if (format->data_are_bigendian) { + /* For big-endian data, only 32 bit samples are supported */ + switch (format->interleave) { + case 1: + dsp_format = DSP_AUDIOFORM_MM_32BE; + break; +#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + case 2: + dsp_format = DSP_AUDIOFORM_SS_32BE; + break; +#endif + } + } else if (format->interleave == 1 && + format->bits_per_sample == 32 && !format->mono_to_stereo) { + /* 32 bit little-endian mono->mono case */ + dsp_format = DSP_AUDIOFORM_MM_32LE; + } else { + /* Handle the other little-endian formats */ + switch (format->bits_per_sample) { + case 8: + if (format->interleave == 2) + dsp_format = DSP_AUDIOFORM_SS_8; + else + dsp_format = DSP_AUDIOFORM_MS_8; + break; + default: + case 16: + if (format->interleave == 2) + dsp_format = DSP_AUDIOFORM_SS_16LE; + else + dsp_format = DSP_AUDIOFORM_MS_16LE; + break; + case 24: + if (format->interleave == 2) + dsp_format = DSP_AUDIOFORM_SS_24LE; + else + dsp_format = DSP_AUDIOFORM_MS_24LE; + break; + case 32: + if (format->interleave == 2) + dsp_format = DSP_AUDIOFORM_SS_32LE; + else + dsp_format = DSP_AUDIOFORM_MS_32LE; + break; + } + } + DE_ACT(("set_audio_format[%d] = %x\n", pipe_index, dsp_format)); + chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format); +} + + + +/* start_transport starts transport for a set of pipes. +The bits 1 in channel_mask specify what pipes to start. Only the bit of the +first channel must be set, regardless its interleave. +Same thing for pause_ and stop_ -trasport below. */ +static int start_transport(struct echoaudio *chip, u32 channel_mask, + u32 cyclic_mask) +{ + DE_ACT(("start_transport %x\n", channel_mask)); + + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->cmd_start |= cpu_to_le32(channel_mask); + + if (chip->comm_page->cmd_start) { + clear_handshake(chip); + send_vector(chip, DSP_VC_START_TRANSFER); + if (wait_handshake(chip)) + return -EIO; + /* Keep track of which pipes are transporting */ + chip->active_mask |= channel_mask; + chip->comm_page->cmd_start = 0; + return 0; + } + + DE_ACT(("start_transport: No pipes to start!\n")); + return -EINVAL; +} + + + +static int pause_transport(struct echoaudio *chip, u32 channel_mask) +{ + DE_ACT(("pause_transport %x\n", channel_mask)); + + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); + chip->comm_page->cmd_reset = 0; + if (chip->comm_page->cmd_stop) { + clear_handshake(chip); + send_vector(chip, DSP_VC_STOP_TRANSFER); + if (wait_handshake(chip)) + return -EIO; + /* Keep track of which pipes are transporting */ + chip->active_mask &= ~channel_mask; + chip->comm_page->cmd_stop = 0; + chip->comm_page->cmd_reset = 0; + return 0; + } + + DE_ACT(("pause_transport: No pipes to stop!\n")); + return 0; +} + + + +static int stop_transport(struct echoaudio *chip, u32 channel_mask) +{ + DE_ACT(("stop_transport %x\n", channel_mask)); + + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); + chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask); + if (chip->comm_page->cmd_reset) { + clear_handshake(chip); + send_vector(chip, DSP_VC_STOP_TRANSFER); + if (wait_handshake(chip)) + return -EIO; + /* Keep track of which pipes are transporting */ + chip->active_mask &= ~channel_mask; + chip->comm_page->cmd_stop = 0; + chip->comm_page->cmd_reset = 0; + return 0; + } + + DE_ACT(("stop_transport: No pipes to stop!\n")); + return 0; +} + + + +static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index) +{ + return (chip->pipe_alloc_mask & (1 << pipe_index)); +} + + + +/* Stops everything and turns off the DSP. All pipes should be already +stopped and unallocated. */ +static int rest_in_peace(struct echoaudio *chip) +{ + DE_ACT(("rest_in_peace() open=%x\n", chip->pipe_alloc_mask)); + + /* Stops all active pipes (just to be sure) */ + stop_transport(chip, chip->active_mask); + + set_meters_on(chip, FALSE); + +#ifdef ECHOCARD_HAS_MIDI + enable_midi_input(chip, FALSE); +#endif + + /* Go to sleep */ + if (chip->dsp_code) { + /* Make load_firmware do a complete reload */ + chip->dsp_code = NULL; + /* Put the DSP to sleep */ + return send_vector(chip, DSP_VC_GO_COMATOSE); + } + return 0; +} + + + +/* Fills the comm page with default values */ +static int init_dsp_comm_page(struct echoaudio *chip) +{ + /* Check if the compiler added extra padding inside the structure */ + if (offsetof(struct comm_page, midi_output) != 0xbe0) { + DE_INIT(("init_dsp_comm_page() - Invalid struct comm_page structure\n")); + return -EPERM; + } + + /* Init all the basic stuff */ + chip->card_name = ECHOCARD_NAME; + chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ + chip->dsp_code = NULL; /* Current DSP code not loaded */ + chip->digital_mode = DIGITAL_MODE_NONE; + chip->input_clock = ECHO_CLOCK_INTERNAL; + chip->output_clock = ECHO_CLOCK_WORD; + chip->asic_loaded = FALSE; + memset(chip->comm_page, 0, sizeof(struct comm_page)); + + /* Init the comm page */ + chip->comm_page->comm_size = + __constant_cpu_to_le32(sizeof(struct comm_page)); + chip->comm_page->handshake = 0xffffffff; + chip->comm_page->midi_out_free_count = + __constant_cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); + chip->comm_page->sample_rate = __constant_cpu_to_le32(44100); + chip->sample_rate = 44100; + + /* Set line levels so we don't blast any inputs on startup */ + memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); + memset(chip->comm_page->vmixer, ECHOGAIN_MUTED, VMIXER_ARRAY_SIZE); + + return 0; +} + + + +/* This function initializes the several volume controls for busses and pipes. +This MUST be called after the DSP is up and running ! */ +static int init_line_levels(struct echoaudio *chip) +{ + int st, i, o; + + DE_INIT(("init_line_levels\n")); + + /* Mute output busses */ + for (i = 0; i < num_busses_out(chip); i++) + if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED))) + return st; + if ((st = update_output_line_level(chip))) + return st; + +#ifdef ECHOCARD_HAS_VMIXER + /* Mute the Vmixer */ + for (i = 0; i < num_pipes_out(chip); i++) + for (o = 0; o < num_busses_out(chip); o++) + if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED))) + return st; + if ((st = update_vmixer_level(chip))) + return st; +#endif /* ECHOCARD_HAS_VMIXER */ + +#ifdef ECHOCARD_HAS_MONITOR + /* Mute the monitor mixer */ + for (o = 0; o < num_busses_out(chip); o++) + for (i = 0; i < num_busses_in(chip); i++) + if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED))) + return st; + if ((st = update_output_line_level(chip))) + return st; +#endif /* ECHOCARD_HAS_MONITOR */ + +#ifdef ECHOCARD_HAS_INPUT_GAIN + for (i = 0; i < num_busses_in(chip); i++) + if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED))) + return st; + if ((st = update_input_line_level(chip))) + return st; +#endif /* ECHOCARD_HAS_INPUT_GAIN */ + + return 0; +} + + + +/* This is low level part of the interrupt handler. +It returns -1 if the IRQ is not ours, or N>=0 if it is, where N is the number +of midi data in the input queue. */ +static int service_irq(struct echoaudio *chip) +{ + int st; + + /* Read the DSP status register and see if this DSP generated this interrupt */ + if (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_IRQ) { + st = 0; +#ifdef ECHOCARD_HAS_MIDI + /* Get and parse midi data if present */ + if (chip->comm_page->midi_input[0]) /* The count is at index 0 */ + st = midi_service_irq(chip); /* Returns how many midi bytes we received */ +#endif + /* Clear the hardware interrupt */ + chip->comm_page->midi_input[0] = 0; + send_vector(chip, DSP_VC_ACK_INT); + return st; + } + return -1; +} + + + + +/****************************************************************************** + Functions for opening and closing pipes + ******************************************************************************/ + +/* allocate_pipes is used to reserve audio pipes for your exclusive use. +The call will fail if some pipes are already allocated. */ +static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, + int pipe_index, int interleave) +{ + int i; + u32 channel_mask; + char is_cyclic; + + DE_ACT(("allocate_pipes: ch=%d int=%d\n", pipe_index, interleave)); + + if (chip->bad_board) + return -EIO; + + is_cyclic = 1; /* This driver uses cyclic buffers only */ + + for (channel_mask = i = 0; i < interleave; i++) + channel_mask |= 1 << (pipe_index + i); + if (chip->pipe_alloc_mask & channel_mask) { + DE_ACT(("allocate_pipes: channel already open\n")); + return -EAGAIN; + } + + chip->comm_page->position[pipe_index] = 0; + chip->pipe_alloc_mask |= channel_mask; + if (is_cyclic) + chip->pipe_cyclic_mask |= channel_mask; + pipe->index = pipe_index; + pipe->interleave = interleave; + pipe->state = PIPE_STATE_STOPPED; + + /* The counter register is where the DSP writes the 32 bit DMA + position for a pipe. The DSP is constantly updating this value as + it moves data. The DMA counter is in units of bytes, not samples. */ + pipe->dma_counter = &chip->comm_page->position[pipe_index]; + *pipe->dma_counter = 0; + DE_ACT(("allocate_pipes: ok\n")); + return pipe_index; +} + + + +static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe) +{ + u32 channel_mask; + int i; + + DE_ACT(("free_pipes: Pipe %d\n", pipe->index)); + snd_assert(is_pipe_allocated(chip, pipe->index), return -EINVAL); + snd_assert(pipe->state == PIPE_STATE_STOPPED, return -EINVAL); + + for (channel_mask = i = 0; i < pipe->interleave; i++) + channel_mask |= 1 << (pipe->index + i); + + chip->pipe_alloc_mask &= ~channel_mask; + chip->pipe_cyclic_mask &= ~channel_mask; + return 0; +} + + + +/****************************************************************************** + Functions for managing the scatter-gather list +******************************************************************************/ + +static int sglist_init(struct echoaudio *chip, struct audiopipe *pipe) +{ + pipe->sglist_head = 0; + memset(pipe->sgpage.area, 0, PAGE_SIZE); + chip->comm_page->sglist_addr[pipe->index].addr = + cpu_to_le32(pipe->sgpage.addr); + return 0; +} + + + +static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe, + dma_addr_t address, size_t length) +{ + int head = pipe->sglist_head; + struct sg_entry *list = (struct sg_entry *)pipe->sgpage.area; + + if (head < MAX_SGLIST_ENTRIES - 1) { + list[head].addr = cpu_to_le32(address); + list[head].size = cpu_to_le32(length); + pipe->sglist_head++; + } else { + DE_ACT(("SGlist: too many fragments\n")); + return -ENOMEM; + } + return 0; +} + + + +static inline int sglist_add_irq(struct echoaudio *chip, struct audiopipe *pipe) +{ + return sglist_add_mapping(chip, pipe, 0, 0); +} + + + +static inline int sglist_wrap(struct echoaudio *chip, struct audiopipe *pipe) +{ + return sglist_add_mapping(chip, pipe, pipe->sgpage.addr, 0); +} diff --git a/sound/pci/echoaudio/echoaudio_dsp.h b/sound/pci/echoaudio/echoaudio_dsp.h new file mode 100644 index 000000000..e55ee0099 --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_dsp.h @@ -0,0 +1,694 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + +#ifndef _ECHO_DSP_ +#define _ECHO_DSP_ + + +/**** Echogals: Darla20, Gina20, Layla20, and Darla24 ****/ +#if defined(ECHOGALS_FAMILY) + +#define NUM_ASIC_TESTS 5 +#define READ_DSP_TIMEOUT 1000000L /* one second */ + +/**** Echo24: Gina24, Layla24, Mona, Mia, Mia-midi ****/ +#elif defined(ECHO24_FAMILY) + +#define DSP_56361 /* Some Echo24 cards use the 56361 DSP */ +#define READ_DSP_TIMEOUT 100000L /* .1 second */ + +/**** 3G: Gina3G, Layla3G ****/ +#elif defined(ECHO3G_FAMILY) + +#define DSP_56361 +#define READ_DSP_TIMEOUT 100000L /* .1 second */ +#define MIN_MTC_1X_RATE 32000 + +/**** Indigo: Indigo, Indigo IO, Indigo DJ ****/ +#elif defined(INDIGO_FAMILY) + +#define DSP_56361 +#define READ_DSP_TIMEOUT 100000L /* .1 second */ + +#else + +#error No family is defined + +#endif + + + +/* + * + * Max inputs and outputs + * + */ + +#define DSP_MAXAUDIOINPUTS 16 /* Max audio input channels */ +#define DSP_MAXAUDIOOUTPUTS 16 /* Max audio output channels */ +#define DSP_MAXPIPES 32 /* Max total pipes (input + output) */ + + +/* + * + * These are the offsets for the memory-mapped DSP registers; the DSP base + * address is treated as the start of a u32 array. + */ + +#define CHI32_CONTROL_REG 4 +#define CHI32_STATUS_REG 5 +#define CHI32_VECTOR_REG 6 +#define CHI32_DATA_REG 7 + + +/* + * + * Interesting bits within the DSP registers + * + */ + +#define CHI32_VECTOR_BUSY 0x00000001 +#define CHI32_STATUS_REG_HF3 0x00000008 +#define CHI32_STATUS_REG_HF4 0x00000010 +#define CHI32_STATUS_REG_HF5 0x00000020 +#define CHI32_STATUS_HOST_READ_FULL 0x00000004 +#define CHI32_STATUS_HOST_WRITE_EMPTY 0x00000002 +#define CHI32_STATUS_IRQ 0x00000040 + + +/* + * + * DSP commands sent via slave mode; these are sent to the DSP by write_dsp() + * + */ + +#define DSP_FNC_SET_COMMPAGE_ADDR 0x02 +#define DSP_FNC_LOAD_LAYLA_ASIC 0xa0 +#define DSP_FNC_LOAD_GINA24_ASIC 0xa0 +#define DSP_FNC_LOAD_MONA_PCI_CARD_ASIC 0xa0 +#define DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC 0xa0 +#define DSP_FNC_LOAD_MONA_EXTERNAL_ASIC 0xa1 +#define DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC 0xa1 +#define DSP_FNC_LOAD_3G_ASIC 0xa0 + + +/* + * + * Defines to handle the MIDI input state engine; these are used to properly + * extract MIDI time code bytes and their timestamps from the MIDI input stream. + * + */ + +#define MIDI_IN_STATE_NORMAL 0 +#define MIDI_IN_STATE_TS_HIGH 1 +#define MIDI_IN_STATE_TS_LOW 2 +#define MIDI_IN_STATE_F1_DATA 3 +#define MIDI_IN_SKIP_DATA (-1) + + +/*---------------------------------------------------------------------------- + +Setting the sample rates on Layla24 is somewhat schizophrenic. + +For standard rates, it works exactly like Mona and Gina24. That is, for +8, 11.025, 16, 22.05, 32, 44.1, 48, 88.2, and 96 kHz, you just set the +appropriate bits in the control register and write the control register. + +In order to support MIDI time code sync (and possibly SMPTE LTC sync in +the future), Layla24 also has "continuous sample rate mode". In this mode, +Layla24 can generate any sample rate between 25 and 50 kHz inclusive, or +50 to 100 kHz inclusive for double speed mode. + +To use continuous mode: + +-Set the clock select bits in the control register to 0xe (see the #define + below) + +-Set double-speed mode if you want to use sample rates above 50 kHz + +-Write the control register as you would normally + +-Now, you need to set the frequency register. First, you need to determine the + value for the frequency register. This is given by the following formula: + +frequency_reg = (LAYLA24_MAGIC_NUMBER / sample_rate) - 2 + +Note the #define below for the magic number + +-Wait for the DSP handshake +-Write the frequency_reg value to the .SampleRate field of the comm page +-Send the vector command SET_LAYLA24_FREQUENCY_REG (see vmonkey.h) + +Once you have set the control register up for continuous mode, you can just +write the frequency register to change the sample rate. This could be +used for MIDI time code sync. For MTC sync, the control register is set for +continuous mode. The driver then just keeps writing the +SET_LAYLA24_FREQUENCY_REG command. + +-----------------------------------------------------------------------------*/ + +#define LAYLA24_MAGIC_NUMBER 677376000 +#define LAYLA24_CONTINUOUS_CLOCK 0x000e + + +/* + * + * DSP vector commands + * + */ + +#define DSP_VC_RESET 0x80ff + +#ifndef DSP_56361 + +#define DSP_VC_ACK_INT 0x8073 +#define DSP_VC_SET_VMIXER_GAIN 0x0000 /* Not used, only for compile */ +#define DSP_VC_START_TRANSFER 0x0075 /* Handshke rqd. */ +#define DSP_VC_METERS_ON 0x0079 +#define DSP_VC_METERS_OFF 0x007b +#define DSP_VC_UPDATE_OUTVOL 0x007d /* Handshke rqd. */ +#define DSP_VC_UPDATE_INGAIN 0x007f /* Handshke rqd. */ +#define DSP_VC_ADD_AUDIO_BUFFER 0x0081 /* Handshke rqd. */ +#define DSP_VC_TEST_ASIC 0x00eb +#define DSP_VC_UPDATE_CLOCKS 0x00ef /* Handshke rqd. */ +#define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00f1 /* Handshke rqd. */ +#define DSP_VC_SET_GD_AUDIO_STATE 0x00f1 /* Handshke rqd. */ +#define DSP_VC_WRITE_CONTROL_REG 0x00f1 /* Handshke rqd. */ +#define DSP_VC_MIDI_WRITE 0x00f5 /* Handshke rqd. */ +#define DSP_VC_STOP_TRANSFER 0x00f7 /* Handshke rqd. */ +#define DSP_VC_UPDATE_FLAGS 0x00fd /* Handshke rqd. */ +#define DSP_VC_GO_COMATOSE 0x00f9 + +#else /* !DSP_56361 */ + +/* Vector commands for families that use either the 56301 or 56361 */ +#define DSP_VC_ACK_INT 0x80F5 +#define DSP_VC_SET_VMIXER_GAIN 0x00DB /* Handshke rqd. */ +#define DSP_VC_START_TRANSFER 0x00DD /* Handshke rqd. */ +#define DSP_VC_METERS_ON 0x00EF +#define DSP_VC_METERS_OFF 0x00F1 +#define DSP_VC_UPDATE_OUTVOL 0x00E3 /* Handshke rqd. */ +#define DSP_VC_UPDATE_INGAIN 0x00E5 /* Handshke rqd. */ +#define DSP_VC_ADD_AUDIO_BUFFER 0x00E1 /* Handshke rqd. */ +#define DSP_VC_TEST_ASIC 0x00ED +#define DSP_VC_UPDATE_CLOCKS 0x00E9 /* Handshke rqd. */ +#define DSP_VC_SET_LAYLA24_FREQUENCY_REG 0x00E9 /* Handshke rqd. */ +#define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00EB /* Handshke rqd. */ +#define DSP_VC_SET_GD_AUDIO_STATE 0x00EB /* Handshke rqd. */ +#define DSP_VC_WRITE_CONTROL_REG 0x00EB /* Handshke rqd. */ +#define DSP_VC_MIDI_WRITE 0x00E7 /* Handshke rqd. */ +#define DSP_VC_STOP_TRANSFER 0x00DF /* Handshke rqd. */ +#define DSP_VC_UPDATE_FLAGS 0x00FB /* Handshke rqd. */ +#define DSP_VC_GO_COMATOSE 0x00d9 + +#endif /* !DSP_56361 */ + + +/* + * + * Timeouts + * + */ + +#define HANDSHAKE_TIMEOUT 20000 /* send_vector command timeout (20ms) */ +#define VECTOR_BUSY_TIMEOUT 100000 /* 100ms */ +#define MIDI_OUT_DELAY_USEC 2000 /* How long to wait after MIDI fills up */ + + +/* + * + * Flags for .Flags field in the comm page + * + */ + +#define DSP_FLAG_MIDI_INPUT 0x0001 /* Enable MIDI input */ +#define DSP_FLAG_SPDIF_NONAUDIO 0x0002 /* Sets the "non-audio" bit + * in the S/PDIF out status + * bits. Clear this flag for + * audio data; + * set it for AC3 or WMA or + * some such */ +#define DSP_FLAG_PROFESSIONAL_SPDIF 0x0008 /* 1 Professional, 0 Consumer */ + + +/* + * + * Clock detect bits reported by the DSP for Gina20, Layla20, Darla24, and Mia + * + */ + +#define GLDM_CLOCK_DETECT_BIT_WORD 0x0002 +#define GLDM_CLOCK_DETECT_BIT_SUPER 0x0004 +#define GLDM_CLOCK_DETECT_BIT_SPDIF 0x0008 +#define GLDM_CLOCK_DETECT_BIT_ESYNC 0x0010 + + +/* + * + * Clock detect bits reported by the DSP for Gina24, Mona, and Layla24 + * + */ + +#define GML_CLOCK_DETECT_BIT_WORD96 0x0002 +#define GML_CLOCK_DETECT_BIT_WORD48 0x0004 +#define GML_CLOCK_DETECT_BIT_SPDIF48 0x0008 +#define GML_CLOCK_DETECT_BIT_SPDIF96 0x0010 +#define GML_CLOCK_DETECT_BIT_WORD (GML_CLOCK_DETECT_BIT_WORD96 | GML_CLOCK_DETECT_BIT_WORD48) +#define GML_CLOCK_DETECT_BIT_SPDIF (GML_CLOCK_DETECT_BIT_SPDIF48 | GML_CLOCK_DETECT_BIT_SPDIF96) +#define GML_CLOCK_DETECT_BIT_ESYNC 0x0020 +#define GML_CLOCK_DETECT_BIT_ADAT 0x0040 + + +/* + * + * Layla clock numbers to send to DSP + * + */ + +#define LAYLA20_CLOCK_INTERNAL 0 +#define LAYLA20_CLOCK_SPDIF 1 +#define LAYLA20_CLOCK_WORD 2 +#define LAYLA20_CLOCK_SUPER 3 + + +/* + * + * Gina/Darla clock states + * + */ + +#define GD_CLOCK_NOCHANGE 0 +#define GD_CLOCK_44 1 +#define GD_CLOCK_48 2 +#define GD_CLOCK_SPDIFIN 3 +#define GD_CLOCK_UNDEF 0xff + + +/* + * + * Gina/Darla S/PDIF status bits + * + */ + +#define GD_SPDIF_STATUS_NOCHANGE 0 +#define GD_SPDIF_STATUS_44 1 +#define GD_SPDIF_STATUS_48 2 +#define GD_SPDIF_STATUS_UNDEF 0xff + + +/* + * + * Layla20 output clocks + * + */ + +#define LAYLA20_OUTPUT_CLOCK_SUPER 0 +#define LAYLA20_OUTPUT_CLOCK_WORD 1 + + +/**************************************************************************** + + Magic constants for the Darla24 hardware + + ****************************************************************************/ + +#define GD24_96000 0x0 +#define GD24_48000 0x1 +#define GD24_44100 0x2 +#define GD24_32000 0x3 +#define GD24_22050 0x4 +#define GD24_16000 0x5 +#define GD24_11025 0x6 +#define GD24_8000 0x7 +#define GD24_88200 0x8 +#define GD24_EXT_SYNC 0x9 + + +/* + * + * Return values from the DSP when ASIC is loaded + * + */ + +#define ASIC_ALREADY_LOADED 0x1 +#define ASIC_NOT_LOADED 0x0 + + +/* + * + * DSP Audio formats + * + * These are the audio formats that the DSP can transfer + * via input and output pipes. LE means little-endian, + * BE means big-endian. + * + * DSP_AUDIOFORM_MS_8 + * + * 8-bit mono unsigned samples. For playback, + * mono data is duplicated out the left and right channels + * of the output bus. The "MS" part of the name + * means mono->stereo. + * + * DSP_AUDIOFORM_MS_16LE + * + * 16-bit signed little-endian mono samples. Playback works + * like the previous code. + * + * DSP_AUDIOFORM_MS_24LE + * + * 24-bit signed little-endian mono samples. Data is packed + * three bytes per sample; if you had two samples 0x112233 and 0x445566 + * they would be stored in memory like this: 33 22 11 66 55 44. + * + * DSP_AUDIOFORM_MS_32LE + * + * 24-bit signed little-endian mono samples in a 32-bit + * container. In other words, each sample is a 32-bit signed + * integer, where the actual audio data is left-justified + * in the 32 bits and only the 24 most significant bits are valid. + * + * DSP_AUDIOFORM_SS_8 + * DSP_AUDIOFORM_SS_16LE + * DSP_AUDIOFORM_SS_24LE + * DSP_AUDIOFORM_SS_32LE + * + * Like the previous ones, except now with stereo interleaved + * data. "SS" means stereo->stereo. + * + * DSP_AUDIOFORM_MM_32LE + * + * Similar to DSP_AUDIOFORM_MS_32LE, except that the mono + * data is not duplicated out both the left and right outputs. + * This mode is used by the ASIO driver. Here, "MM" means + * mono->mono. + * + * DSP_AUDIOFORM_MM_32BE + * + * Just like DSP_AUDIOFORM_MM_32LE, but now the data is + * in big-endian format. + * + */ + +#define DSP_AUDIOFORM_MS_8 0 /* 8 bit mono */ +#define DSP_AUDIOFORM_MS_16LE 1 /* 16 bit mono */ +#define DSP_AUDIOFORM_MS_24LE 2 /* 24 bit mono */ +#define DSP_AUDIOFORM_MS_32LE 3 /* 32 bit mono */ +#define DSP_AUDIOFORM_SS_8 4 /* 8 bit stereo */ +#define DSP_AUDIOFORM_SS_16LE 5 /* 16 bit stereo */ +#define DSP_AUDIOFORM_SS_24LE 6 /* 24 bit stereo */ +#define DSP_AUDIOFORM_SS_32LE 7 /* 32 bit stereo */ +#define DSP_AUDIOFORM_MM_32LE 8 /* 32 bit mono->mono little-endian */ +#define DSP_AUDIOFORM_MM_32BE 9 /* 32 bit mono->mono big-endian */ +#define DSP_AUDIOFORM_SS_32BE 10 /* 32 bit stereo big endian */ +#define DSP_AUDIOFORM_INVALID 0xFF /* Invalid audio format */ + + +/* + * + * Super-interleave is defined as interleaving by 4 or more. Darla20 and Gina20 + * do not support super interleave. + * + * 16 bit, 24 bit, and 32 bit little endian samples are supported for super + * interleave. The interleave factor must be even. 16 - way interleave is the + * current maximum, so you can interleave by 4, 6, 8, 10, 12, 14, and 16. + * + * The actual format code is derived by taking the define below and or-ing with + * the interleave factor. So, 32 bit interleave by 6 is 0x86 and + * 16 bit interleave by 16 is (0x40 | 0x10) = 0x50. + * + */ + +#define DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE 0x40 +#define DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE 0xc0 +#define DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE 0x80 + + +/* + * + * Gina24, Mona, and Layla24 control register defines + * + */ + +#define GML_CONVERTER_ENABLE 0x0010 +#define GML_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1, + consumer == 0 */ +#define GML_SPDIF_SAMPLE_RATE0 0x0040 +#define GML_SPDIF_SAMPLE_RATE1 0x0080 +#define GML_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels, + 0 == one channel */ +#define GML_SPDIF_NOT_AUDIO 0x0200 +#define GML_SPDIF_COPY_PERMIT 0x0400 +#define GML_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */ +#define GML_ADAT_MODE 0x1000 /* 1 == ADAT mode, 0 == S/PDIF mode */ +#define GML_SPDIF_OPTICAL_MODE 0x2000 /* 1 == optical mode, 0 == RCA mode */ +#define GML_SPDIF_CDROM_MODE 0x3000 /* 1 == CDROM mode, + * 0 == RCA or optical mode */ +#define GML_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed, + 0 == single speed */ + +#define GML_DIGITAL_IN_AUTO_MUTE 0x800000 + +#define GML_96KHZ (0x0 | GML_DOUBLE_SPEED_MODE) +#define GML_88KHZ (0x1 | GML_DOUBLE_SPEED_MODE) +#define GML_48KHZ 0x2 +#define GML_44KHZ 0x3 +#define GML_32KHZ 0x4 +#define GML_22KHZ 0x5 +#define GML_16KHZ 0x6 +#define GML_11KHZ 0x7 +#define GML_8KHZ 0x8 +#define GML_SPDIF_CLOCK 0x9 +#define GML_ADAT_CLOCK 0xA +#define GML_WORD_CLOCK 0xB +#define GML_ESYNC_CLOCK 0xC +#define GML_ESYNCx2_CLOCK 0xD + +#define GML_CLOCK_CLEAR_MASK 0xffffbff0 +#define GML_SPDIF_RATE_CLEAR_MASK (~(GML_SPDIF_SAMPLE_RATE0|GML_SPDIF_SAMPLE_RATE1)) +#define GML_DIGITAL_MODE_CLEAR_MASK 0xffffcfff +#define GML_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f + + +/* + * + * Mia sample rate and clock setting constants + * + */ + +#define MIA_32000 0x0040 +#define MIA_44100 0x0042 +#define MIA_48000 0x0041 +#define MIA_88200 0x0142 +#define MIA_96000 0x0141 + +#define MIA_SPDIF 0x00000044 +#define MIA_SPDIF96 0x00000144 + +#define MIA_MIDI_REV 1 /* Must be Mia rev 1 for MIDI support */ + + +/* + * + * 3G register bits + * + */ + +#define E3G_CONVERTER_ENABLE 0x0010 +#define E3G_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1, + consumer == 0 */ +#define E3G_SPDIF_SAMPLE_RATE0 0x0040 +#define E3G_SPDIF_SAMPLE_RATE1 0x0080 +#define E3G_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels, + 0 == one channel */ +#define E3G_SPDIF_NOT_AUDIO 0x0200 +#define E3G_SPDIF_COPY_PERMIT 0x0400 +#define E3G_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */ +#define E3G_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed, + 0 == single speed */ +#define E3G_PHANTOM_POWER 0x8000 /* 1 == phantom power on, + 0 == phantom power off */ + +#define E3G_96KHZ (0x0 | E3G_DOUBLE_SPEED_MODE) +#define E3G_88KHZ (0x1 | E3G_DOUBLE_SPEED_MODE) +#define E3G_48KHZ 0x2 +#define E3G_44KHZ 0x3 +#define E3G_32KHZ 0x4 +#define E3G_22KHZ 0x5 +#define E3G_16KHZ 0x6 +#define E3G_11KHZ 0x7 +#define E3G_8KHZ 0x8 +#define E3G_SPDIF_CLOCK 0x9 +#define E3G_ADAT_CLOCK 0xA +#define E3G_WORD_CLOCK 0xB +#define E3G_CONTINUOUS_CLOCK 0xE + +#define E3G_ADAT_MODE 0x1000 +#define E3G_SPDIF_OPTICAL_MODE 0x2000 + +#define E3G_CLOCK_CLEAR_MASK 0xbfffbff0 +#define E3G_DIGITAL_MODE_CLEAR_MASK 0xffffcfff +#define E3G_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f + +/* Clock detect bits reported by the DSP */ +#define E3G_CLOCK_DETECT_BIT_WORD96 0x0001 +#define E3G_CLOCK_DETECT_BIT_WORD48 0x0002 +#define E3G_CLOCK_DETECT_BIT_SPDIF48 0x0004 +#define E3G_CLOCK_DETECT_BIT_ADAT 0x0004 +#define E3G_CLOCK_DETECT_BIT_SPDIF96 0x0008 +#define E3G_CLOCK_DETECT_BIT_WORD (E3G_CLOCK_DETECT_BIT_WORD96|E3G_CLOCK_DETECT_BIT_WORD48) +#define E3G_CLOCK_DETECT_BIT_SPDIF (E3G_CLOCK_DETECT_BIT_SPDIF48|E3G_CLOCK_DETECT_BIT_SPDIF96) + +/* Frequency control register */ +#define E3G_MAGIC_NUMBER 677376000 +#define E3G_FREQ_REG_DEFAULT (E3G_MAGIC_NUMBER / 48000 - 2) +#define E3G_FREQ_REG_MAX 0xffff + +/* 3G external box types */ +#define E3G_GINA3G_BOX_TYPE 0x00 +#define E3G_LAYLA3G_BOX_TYPE 0x10 +#define E3G_ASIC_NOT_LOADED 0xffff +#define E3G_BOX_TYPE_MASK 0xf0 + +#define EXT_3GBOX_NC 0x01 +#define EXT_3GBOX_NOT_SET 0x02 + + +/* + * + * Gina20 & Layla20 have input gain controls for the analog inputs; + * this is the magic number for the hardware that gives you 0 dB at -10. + * + */ + +#define GL20_INPUT_GAIN_MAGIC_NUMBER 0xC8 + + +/* + * + * Defines how much time must pass between DSP load attempts + * + */ + +#define DSP_LOAD_ATTEMPT_PERIOD 1000000L /* One second */ + + +/* + * + * Size of arrays for the comm page. MAX_PLAY_TAPS and MAX_REC_TAPS are + * no longer used, but the sizes must still be right for the DSP to see + * the comm page correctly. + * + */ + +#define MONITOR_ARRAY_SIZE 0x180 +#define VMIXER_ARRAY_SIZE 0x40 +#define MIDI_OUT_BUFFER_SIZE 32 +#define MIDI_IN_BUFFER_SIZE 256 +#define MAX_PLAY_TAPS 168 +#define MAX_REC_TAPS 192 +#define DSP_MIDI_OUT_FIFO_SIZE 64 + + +/* sg_entry is a single entry for the scatter-gather list. The array of struct +sg_entry struct is read by the DSP, so all values must be little-endian. */ + +#define MAX_SGLIST_ENTRIES 512 + +struct sg_entry { + u32 addr; + u32 size; +}; + + +/**************************************************************************** + + The comm page. This structure is read and written by the DSP; the + DSP code is a firm believer in the byte offsets written in the comments + at the end of each line. This structure should not be changed. + + Any reads from or writes to this structure should be in little-endian format. + + ****************************************************************************/ + +struct comm_page { /* Base Length*/ + u32 comm_size; /* size of this object 0x000 4 */ + u32 flags; /* See Appendix A below 0x004 4 */ + u32 unused; /* Unused entry 0x008 4 */ + u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */ + volatile u32 handshake; /* DSP command handshake 0x010 4 */ + u32 cmd_start; /* Chs. to start mask 0x014 4 */ + u32 cmd_stop; /* Chs. to stop mask 0x018 4 */ + u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */ + u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */ + struct sg_entry sglist_addr[DSP_MAXPIPES]; + /* Chs. Physical sglist addrs 0x060 32*8 */ + volatile u32 position[DSP_MAXPIPES]; + /* Positions for ea. ch. 0x160 32*4 */ + volatile s8 vu_meter[DSP_MAXPIPES]; + /* VU meters 0x1e0 32*1 */ + volatile s8 peak_meter[DSP_MAXPIPES]; + /* Peak meters 0x200 32*1 */ + s8 line_out_level[DSP_MAXAUDIOOUTPUTS]; + /* Output gain 0x220 16*1 */ + s8 line_in_level[DSP_MAXAUDIOINPUTS]; + /* Input gain 0x230 16*1 */ + s8 monitors[MONITOR_ARRAY_SIZE]; + /* Monitor map 0x240 0x180 */ + u32 play_coeff[MAX_PLAY_TAPS]; + /* Gina/Darla play filters - obsolete 0x3c0 168*4 */ + u32 rec_coeff[MAX_REC_TAPS]; + /* Gina/Darla record filters - obsolete 0x660 192*4 */ + volatile u16 midi_input[MIDI_IN_BUFFER_SIZE]; + /* MIDI input data transfer buffer 0x960 256*2 */ + u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */ + u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */ + u8 gd_resampler_state; /* Should always be 3 0xb62 1 */ + u8 filler2; /* 0xb63 1 */ + u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */ + u16 input_clock; /* Chg. Input clock state 0xb68 2 */ + u16 output_clock; /* Chg. Output clock state 0xb6a 2 */ + volatile u32 status_clocks; + /* Current Input clock state 0xb6c 4 */ + u32 ext_box_status; /* External box status 0xb70 4 */ + u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */ + volatile u32 midi_out_free_count; + /* # of bytes free in MIDI output FIFO 0xb78 4 */ + u32 unused2; /* Cyclic pipes 0xb7c 4 */ + u32 control_register; + /* Mona, Gina24, Layla24, 3G ctrl reg 0xb80 4 */ + u32 e3g_frq_register; /* 3G frequency register 0xb84 4 */ + u8 filler[24]; /* filler 0xb88 24*1 */ + s8 vmixer[VMIXER_ARRAY_SIZE]; + /* Vmixer levels 0xba0 64*1 */ + u8 midi_output[MIDI_OUT_BUFFER_SIZE]; + /* MIDI output data 0xbe0 32*1 */ +}; + +#endif /* _ECHO_DSP_ */ diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c new file mode 100644 index 000000000..3aa37e76e --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_gml.c @@ -0,0 +1,198 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +/* These functions are common for Gina24, Layla24 and Mona cards */ + + +/* ASIC status check - some cards have one or two ASICs that need to be +loaded. Once that load is complete, this function is called to see if +the load was successful. +If this load fails, it does not necessarily mean that the hardware is +defective - the external box may be disconnected or turned off. */ +static int check_asic_status(struct echoaudio *chip) +{ + u32 asic_status; + + send_vector(chip, DSP_VC_TEST_ASIC); + + /* The DSP will return a value to indicate whether or not the + ASIC is currently loaded */ + if (read_dsp(chip, &asic_status) < 0) { + DE_INIT(("check_asic_status: failed on read_dsp\n")); + chip->asic_loaded = FALSE; + return -EIO; + } + + chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED); + return chip->asic_loaded ? 0 : -EIO; +} + + + +/* Most configuration of Gina24, Layla24, or Mona is accomplished by writing +the control register. write_control_reg sends the new control register +value to the DSP. */ +static int write_control_reg(struct echoaudio *chip, u32 value, char force) +{ + /* Handle the digital input auto-mute */ + if (chip->digital_in_automute) + value |= GML_DIGITAL_IN_AUTO_MUTE; + else + value &= ~GML_DIGITAL_IN_AUTO_MUTE; + + DE_ACT(("write_control_reg: 0x%x\n", value)); + + /* Write the control register */ + value = cpu_to_le32(value); + if (value != chip->comm_page->control_register || force) { + if (wait_handshake(chip)) + return -EIO; + chip->comm_page->control_register = value; + clear_handshake(chip); + return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); + } + return 0; +} + + + +/* Gina24, Layla24, and Mona support digital input auto-mute. If the digital +input auto-mute is enabled, the DSP will only enable the digital inputs if +the card is syncing to a valid clock on the ADAT or S/PDIF inputs. +If the auto-mute is disabled, the digital inputs are enabled regardless of +what the input clock is set or what is connected. */ +static int set_input_auto_mute(struct echoaudio *chip, int automute) +{ + DE_ACT(("set_input_auto_mute %d\n", automute)); + + chip->digital_in_automute = automute; + + /* Re-set the input clock to the current value - indirectly causes + the auto-mute flag to be sent to the DSP */ + return set_input_clock(chip, chip->input_clock); +} + + + +/* S/PDIF coax / S/PDIF optical / ADAT - switch */ +static int set_digital_mode(struct echoaudio *chip, u8 mode) +{ + u8 previous_mode; + int err, i, o; + + if (chip->bad_board) + return -EIO; + + /* All audio channels must be closed before changing the digital mode */ + snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); + + snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); + + previous_mode = chip->digital_mode; + err = dsp_set_digital_mode(chip, mode); + + /* If we successfully changed the digital mode from or to ADAT, + then make sure all output, input and monitor levels are + updated by the DSP comm object. */ + if (err >= 0 && previous_mode != mode && + (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { + spin_lock_irq(&chip->lock); + for (o = 0; o < num_busses_out(chip); o++) + for (i = 0; i < num_busses_in(chip); i++) + set_monitor_gain(chip, o, i, + chip->monitor_gain[o][i]); + +#ifdef ECHOCARD_HAS_INPUT_GAIN + for (i = 0; i < num_busses_in(chip); i++) + set_input_gain(chip, i, chip->input_gain[i]); + update_input_line_level(chip); +#endif + + for (o = 0; o < num_busses_out(chip); o++) + set_output_gain(chip, o, chip->output_gain[o]); + update_output_line_level(chip); + spin_unlock_irq(&chip->lock); + } + + return err; +} + + + +/* Set the S/PDIF output format */ +static int set_professional_spdif(struct echoaudio *chip, char prof) +{ + u32 control_reg; + int err; + + /* Clear the current S/PDIF flags */ + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK; + + /* Set the new S/PDIF flags depending on the mode */ + control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT | + GML_SPDIF_COPY_PERMIT; + if (prof) { + /* Professional mode */ + control_reg |= GML_SPDIF_PRO_MODE; + + switch (chip->sample_rate) { + case 32000: + control_reg |= GML_SPDIF_SAMPLE_RATE0 | + GML_SPDIF_SAMPLE_RATE1; + break; + case 44100: + control_reg |= GML_SPDIF_SAMPLE_RATE0; + break; + case 48000: + control_reg |= GML_SPDIF_SAMPLE_RATE1; + break; + } + } else { + /* Consumer mode */ + switch (chip->sample_rate) { + case 32000: + control_reg |= GML_SPDIF_SAMPLE_RATE0 | + GML_SPDIF_SAMPLE_RATE1; + break; + case 48000: + control_reg |= GML_SPDIF_SAMPLE_RATE1; + break; + } + } + + if ((err = write_control_reg(chip, control_reg, FALSE))) + return err; + chip->professional_spdif = prof; + DE_ACT(("set_professional_spdif to %s\n", + prof ? "Professional" : "Consumer")); + return 0; +} diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c new file mode 100644 index 000000000..29d6d12f8 --- /dev/null +++ b/sound/pci/echoaudio/gina20.c @@ -0,0 +1,103 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHOGALS_FAMILY +#define ECHOCARD_GINA20 +#define ECHOCARD_NAME "Gina20" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_INPUT_GAIN +#define ECHOCARD_HAS_DIGITAL_IO +#define ECHOCARD_HAS_EXTERNAL_CLOCK +#define ECHOCARD_HAS_ADAT FALSE + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 2 */ +#define PX_ANALOG_IN 10 /* 2 */ +#define PX_DIGITAL_IN 12 /* 2 */ +#define PX_NUM 14 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 8 */ +#define BX_DIGITAL_OUT 8 /* 2 */ +#define BX_ANALOG_IN 10 /* 2 */ +#define BX_DIGITAL_IN 12 /* 2 */ +#define BX_NUM 14 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_GINA20_DSP 0 + +static const struct firmware card_fw[] = { + {0, "gina20_dsp.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .rate_min = 44100, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, + /* One page (4k) contains 512 instructions. I don't know if the hw + supports lists longer than this. In this case periods_max=220 is a + safe limit to make sure the list never exceeds 512 instructions. */ +}; + + +#include "gina20_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio.c" diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c new file mode 100644 index 000000000..2757c8960 --- /dev/null +++ b/sound/pci/echoaudio/gina20_dsp.c @@ -0,0 +1,215 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int set_professional_spdif(struct echoaudio *chip, char prof); +static int update_flags(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Gina20\n")); + snd_assert((subdevice_id & 0xfff0) == GINA20, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP]; + chip->spdif_status = GD_SPDIF_STATUS_UNDEF; + chip->clock_state = GD_CLOCK_UNDEF; + /* Since this card has no ASIC, mark it as loaded so everything + works OK */ + chip->asic_loaded = TRUE; + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | + ECHO_CLOCK_BIT_SPDIF; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + err = set_professional_spdif(chip, TRUE); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + u32 clocks_from_dsp, clock_bits; + + /* Map the DSP clock detect bits to the generic driver clock + detect bits */ + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + clock_bits = ECHO_CLOCK_BIT_INTERNAL; + + if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) + clock_bits |= ECHO_CLOCK_BIT_SPDIF; + + return clock_bits; +} + + + +/* The Gina20 has no ASIC. Just do nothing */ +static int load_asic(struct echoaudio *chip) +{ + return 0; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u8 clock_state, spdif_status; + + if (wait_handshake(chip)) + return -EIO; + + switch (rate) { + case 44100: + clock_state = GD_CLOCK_44; + spdif_status = GD_SPDIF_STATUS_44; + break; + case 48000: + clock_state = GD_CLOCK_48; + spdif_status = GD_SPDIF_STATUS_48; + break; + default: + clock_state = GD_CLOCK_NOCHANGE; + spdif_status = GD_SPDIF_STATUS_NOCHANGE; + break; + } + + if (chip->clock_state == clock_state) + clock_state = GD_CLOCK_NOCHANGE; + if (spdif_status == chip->spdif_status) + spdif_status = GD_SPDIF_STATUS_NOCHANGE; + + chip->comm_page->sample_rate = cpu_to_le32(rate); + chip->comm_page->gd_clock_state = clock_state; + chip->comm_page->gd_spdif_status = spdif_status; + chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ + + /* Save the new audio state if it changed */ + if (clock_state != GD_CLOCK_NOCHANGE) + chip->clock_state = clock_state; + if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) + chip->spdif_status = spdif_status; + chip->sample_rate = rate; + + clear_handshake(chip); + return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); +} + + + +static int set_input_clock(struct echoaudio *chip, u16 clock) +{ + DE_ACT(("set_input_clock:\n")); + + switch (clock) { + case ECHO_CLOCK_INTERNAL: + /* Reset the audio state to unknown (just in case) */ + chip->clock_state = GD_CLOCK_UNDEF; + chip->spdif_status = GD_SPDIF_STATUS_UNDEF; + set_sample_rate(chip, chip->sample_rate); + chip->input_clock = clock; + DE_ACT(("Set Gina clock to INTERNAL\n")); + break; + case ECHO_CLOCK_SPDIF: + chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN; + chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE; + clear_handshake(chip); + send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); + chip->clock_state = GD_CLOCK_SPDIFIN; + DE_ACT(("Set Gina20 clock to SPDIF\n")); + chip->input_clock = clock; + break; + default: + return -EINVAL; + } + + return 0; +} + + + +/* Set input bus gain (one unit is 0.5dB !) */ +static int set_input_gain(struct echoaudio *chip, u16 input, int gain) +{ + snd_assert(input < num_busses_in(chip), return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + chip->input_gain[input] = gain; + gain += GL20_INPUT_GAIN_MAGIC_NUMBER; + chip->comm_page->line_in_level[input] = gain; + return 0; +} + + + +/* Tell the DSP to reread the flags from the comm page */ +static int update_flags(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_FLAGS); +} + + + +static int set_professional_spdif(struct echoaudio *chip, char prof) +{ + DE_ACT(("set_professional_spdif %d\n", prof)); + if (prof) + chip->comm_page->flags |= + __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + else + chip->comm_page->flags &= + ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + chip->professional_spdif = prof; + return update_flags(chip); +} diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c new file mode 100644 index 000000000..e464d720d --- /dev/null +++ b/sound/pci/echoaudio/gina24.c @@ -0,0 +1,123 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHO24_FAMILY +#define ECHOCARD_GINA24 +#define ECHOCARD_NAME "Gina24" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_ASIC +#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_DIGITAL_IO +#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE +#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH +#define ECHOCARD_HAS_EXTERNAL_CLOCK +#define ECHOCARD_HAS_ADAT 6 +#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 8 */ +#define PX_ANALOG_IN 16 /* 2 */ +#define PX_DIGITAL_IN 18 /* 8 */ +#define PX_NUM 26 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 8 */ +#define BX_DIGITAL_OUT 8 /* 8 */ +#define BX_ANALOG_IN 16 /* 2 */ +#define BX_DIGITAL_IN 18 /* 8 */ +#define BX_NUM 26 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_361_LOADER 0 +#define FW_GINA24_301_DSP 1 +#define FW_GINA24_361_DSP 2 +#define FW_GINA24_301_ASIC 3 +#define FW_GINA24_361_ASIC 4 + +static const struct firmware card_fw[] = { + {0, "loader_dsp.fw"}, + {0, "gina24_301_dsp.fw"}, + {0, "gina24_361_dsp.fw"}, + {0, "gina24_301_asic.fw"}, + {0, "gina24_361_asic.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */ + {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */ + {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */ + {0x1057, 0x3410, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56361 Gina24 rev.1 */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_8000_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 8000, + .rate_max = 96000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, + /* One page (4k) contains 512 instructions. I don't know if the hw + supports lists longer than this. In this case periods_max=220 is a + safe limit to make sure the list never exceeds 512 instructions. + 220 ~= (512 - 1 - (BUFFER_BYTES_MAX / PAGE_SIZE)) / 2 */ +}; + +#include "gina24_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio_gml.c" +#include "echoaudio.c" diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c new file mode 100644 index 000000000..144fc567b --- /dev/null +++ b/sound/pci/echoaudio/gina24_dsp.c @@ -0,0 +1,346 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int write_control_reg(struct echoaudio *chip, u32 value, char force); +static int set_input_clock(struct echoaudio *chip, u16 clock); +static int set_professional_spdif(struct echoaudio *chip, char prof); +static int set_digital_mode(struct echoaudio *chip, u8 mode); +static int load_asic_generic(struct echoaudio *chip, u32 cmd, + const struct firmware *asic); +static int check_asic_status(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Gina24\n")); + snd_assert((subdevice_id & 0xfff0) == GINA24, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->input_clock_types = + ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | + ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | + ECHO_CLOCK_BIT_ADAT; + chip->professional_spdif = FALSE; + chip->digital_in_automute = TRUE; + chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; + + /* Gina24 comes in both '301 and '361 flavors */ + if (chip->device_id == DEVICE_ID_56361) { + chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP]; + chip->digital_modes = + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | + ECHOCAPS_HAS_DIGITAL_MODE_ADAT; + } else { + chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP]; + chip->digital_modes = + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | + ECHOCAPS_HAS_DIGITAL_MODE_ADAT | + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM; + } + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); + snd_assert(err >= 0, return err); + err = set_professional_spdif(chip, TRUE); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + u32 clocks_from_dsp, clock_bits; + + /* Map the DSP clock detect bits to the generic driver clock + detect bits */ + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + clock_bits = ECHO_CLOCK_BIT_INTERNAL; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) + clock_bits |= ECHO_CLOCK_BIT_SPDIF; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) + clock_bits |= ECHO_CLOCK_BIT_ADAT; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC) + clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96; + + return clock_bits; +} + + + +/* Gina24 has an ASIC on the PCI card which must be loaded for anything +interesting to happen. */ +static int load_asic(struct echoaudio *chip) +{ + u32 control_reg; + int err; + const struct firmware *fw; + + if (chip->asic_loaded) + return 1; + + /* Give the DSP a few milliseconds to settle down */ + mdelay(10); + + /* Pick the correct ASIC for '301 or '361 Gina24 */ + if (chip->device_id == DEVICE_ID_56361) + fw = &card_fw[FW_GINA24_361_ASIC]; + else + fw = &card_fw[FW_GINA24_301_ASIC]; + + if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0) + return err; + + chip->asic_code = fw; + + /* Now give the new ASIC a little time to set up */ + mdelay(10); + /* See if it worked */ + err = check_asic_status(chip); + + /* Set up the control register if the load succeeded - + 48 kHz, internal clock, S/PDIF RCA mode */ + if (!err) { + control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; + err = write_control_reg(chip, control_reg, TRUE); + } + DE_INIT(("load_asic() done\n")); + return err; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u32 control_reg, clock; + + snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, + return -EINVAL); + + /* Only set the clock for internal mode. */ + if (chip->input_clock != ECHO_CLOCK_INTERNAL) { + DE_ACT(("set_sample_rate: Cannot set sample rate - " + "clock not set to CLK_CLOCKININTERNAL\n")); + /* Save the rate anyhow */ + chip->comm_page->sample_rate = cpu_to_le32(rate); + chip->sample_rate = rate; + return 0; + } + + clock = 0; + + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK; + + switch (rate) { + case 96000: + clock = GML_96KHZ; + break; + case 88200: + clock = GML_88KHZ; + break; + case 48000: + clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; + break; + case 44100: + clock = GML_44KHZ; + /* Professional mode ? */ + if (control_reg & GML_SPDIF_PRO_MODE) + clock |= GML_SPDIF_SAMPLE_RATE0; + break; + case 32000: + clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | + GML_SPDIF_SAMPLE_RATE1; + break; + case 22050: + clock = GML_22KHZ; + break; + case 16000: + clock = GML_16KHZ; + break; + case 11025: + clock = GML_11KHZ; + break; + case 8000: + clock = GML_8KHZ; + break; + default: + DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + return -EINVAL; + } + + control_reg |= clock; + + chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ + chip->sample_rate = rate; + DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); + + return write_control_reg(chip, control_reg, FALSE); +} + + + +static int set_input_clock(struct echoaudio *chip, u16 clock) +{ + u32 control_reg, clocks_from_dsp; + + DE_ACT(("set_input_clock:\n")); + + /* Mask off the clock select bits */ + control_reg = le32_to_cpu(chip->comm_page->control_register) & + GML_CLOCK_CLEAR_MASK; + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + switch (clock) { + case ECHO_CLOCK_INTERNAL: + DE_ACT(("Set Gina24 clock to INTERNAL\n")); + chip->input_clock = ECHO_CLOCK_INTERNAL; + return set_sample_rate(chip, chip->sample_rate); + case ECHO_CLOCK_SPDIF: + if (chip->digital_mode == DIGITAL_MODE_ADAT) + return -EAGAIN; + DE_ACT(("Set Gina24 clock to SPDIF\n")); + control_reg |= GML_SPDIF_CLOCK; + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) + control_reg |= GML_DOUBLE_SPEED_MODE; + else + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + case ECHO_CLOCK_ADAT: + if (chip->digital_mode != DIGITAL_MODE_ADAT) + return -EAGAIN; + DE_ACT(("Set Gina24 clock to ADAT\n")); + control_reg |= GML_ADAT_CLOCK; + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + case ECHO_CLOCK_ESYNC: + DE_ACT(("Set Gina24 clock to ESYNC\n")); + control_reg |= GML_ESYNC_CLOCK; + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + case ECHO_CLOCK_ESYNC96: + DE_ACT(("Set Gina24 clock to ESYNC96\n")); + control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE; + break; + default: + DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock)); + return -EINVAL; + } + + chip->input_clock = clock; + return write_control_reg(chip, control_reg, TRUE); +} + + + +static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) +{ + u32 control_reg; + int err, incompatible_clock; + + /* Set clock to "internal" if it's not compatible with the new mode */ + incompatible_clock = FALSE; + switch (mode) { + case DIGITAL_MODE_SPDIF_OPTICAL: + case DIGITAL_MODE_SPDIF_CDROM: + case DIGITAL_MODE_SPDIF_RCA: + if (chip->input_clock == ECHO_CLOCK_ADAT) + incompatible_clock = TRUE; + break; + case DIGITAL_MODE_ADAT: + if (chip->input_clock == ECHO_CLOCK_SPDIF) + incompatible_clock = TRUE; + break; + default: + DE_ACT(("Digital mode not supported: %d\n", mode)); + return -EINVAL; + } + + spin_lock_irq(&chip->lock); + + if (incompatible_clock) { /* Switch to 48KHz, internal */ + chip->sample_rate = 48000; + set_input_clock(chip, ECHO_CLOCK_INTERNAL); + } + + /* Clear the current digital mode */ + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; + + /* Tweak the control reg */ + switch (mode) { + case DIGITAL_MODE_SPDIF_OPTICAL: + control_reg |= GML_SPDIF_OPTICAL_MODE; + break; + case DIGITAL_MODE_SPDIF_CDROM: + /* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */ + if (chip->device_id == DEVICE_ID_56301) + control_reg |= GML_SPDIF_CDROM_MODE; + break; + case DIGITAL_MODE_SPDIF_RCA: + /* GML_SPDIF_OPTICAL_MODE bit cleared */ + break; + case DIGITAL_MODE_ADAT: + control_reg |= GML_ADAT_MODE; + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + } + + err = write_control_reg(chip, control_reg, TRUE); + spin_unlock_irq(&chip->lock); + if (err < 0) + return err; + chip->digital_mode = mode; + + DE_ACT(("set_digital_mode to %d\n", chip->digital_mode)); + return incompatible_clock; +} diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c new file mode 100644 index 000000000..bfd246709 --- /dev/null +++ b/sound/pci/echoaudio/indigo.c @@ -0,0 +1,104 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define INDIGO_FAMILY +#define ECHOCARD_INDIGO +#define ECHOCARD_NAME "Indigo" +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_VMIXER +#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 0 */ +#define PX_ANALOG_IN 8 /* 0 */ +#define PX_DIGITAL_IN 8 /* 0 */ +#define PX_NUM 8 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 2 */ +#define BX_DIGITAL_OUT 2 /* 0 */ +#define BX_ANALOG_IN 2 /* 0 */ +#define BX_DIGITAL_IN 2 /* 0 */ +#define BX_NUM 2 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_361_LOADER 0 +#define FW_INDIGO_DSP 1 + +static const struct firmware card_fw[] = { + {0, "loader_dsp.fw"}, + {0, "indigo_dsp.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 32000, + .rate_max = 96000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, +}; + +#include "indigo_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio.c" + diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c new file mode 100644 index 000000000..d6ac77346 --- /dev/null +++ b/sound/pci/echoaudio/indigo_dsp.c @@ -0,0 +1,170 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, + int gain); +static int update_vmixer_level(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Indigo\n")); + snd_assert((subdevice_id & 0xfff0) == INDIGO, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP]; + /* Since this card has no ASIC, mark it as loaded so everything + works OK */ + chip->asic_loaded = TRUE; + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + /* Default routing of the virtual channels: all vchannels are routed + to the stereo output */ + set_vmixer_gain(chip, 0, 0, 0); + set_vmixer_gain(chip, 1, 1, 0); + set_vmixer_gain(chip, 0, 2, 0); + set_vmixer_gain(chip, 1, 3, 0); + set_vmixer_gain(chip, 0, 4, 0); + set_vmixer_gain(chip, 1, 5, 0); + set_vmixer_gain(chip, 0, 6, 0); + set_vmixer_gain(chip, 1, 7, 0); + err = update_vmixer_level(chip); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + return ECHO_CLOCK_BIT_INTERNAL; +} + + + +/* The Indigo has no ASIC. Just do nothing */ +static int load_asic(struct echoaudio *chip) +{ + return 0; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u32 control_reg; + + switch (rate) { + case 96000: + control_reg = MIA_96000; + break; + case 88200: + control_reg = MIA_88200; + break; + case 48000: + control_reg = MIA_48000; + break; + case 44100: + control_reg = MIA_44100; + break; + case 32000: + control_reg = MIA_32000; + break; + default: + DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + return -EINVAL; + } + + /* Set the control register if it has changed */ + if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ + chip->comm_page->control_register = cpu_to_le32(control_reg); + chip->sample_rate = rate; + + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_CLOCKS); + } + return 0; +} + + + +/* This function routes the sound from a virtual channel to a real output */ +static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, + int gain) +{ + int index; + + snd_assert(pipe < num_pipes_out(chip) && + output < num_busses_out(chip), return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + chip->vmixer_gain[output][pipe] = gain; + index = output * num_pipes_out(chip) + pipe; + chip->comm_page->vmixer[index] = gain; + + DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + return 0; +} + + + +/* Tell the DSP to read and update virtual mixer levels in comm page. */ +static int update_vmixer_level(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); +} + diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c new file mode 100644 index 000000000..8ed7ff1fd --- /dev/null +++ b/sound/pci/echoaudio/indigodj.c @@ -0,0 +1,104 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define INDIGO_FAMILY +#define ECHOCARD_INDIGO_DJ +#define ECHOCARD_NAME "Indigo DJ" +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_VMIXER +#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 0 */ +#define PX_ANALOG_IN 8 /* 0 */ +#define PX_DIGITAL_IN 8 /* 0 */ +#define PX_NUM 8 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 4 */ +#define BX_DIGITAL_OUT 4 /* 0 */ +#define BX_ANALOG_IN 4 /* 0 */ +#define BX_DIGITAL_IN 4 /* 0 */ +#define BX_NUM 4 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_361_LOADER 0 +#define FW_INDIGO_DJ_DSP 1 + +static const struct firmware card_fw[] = { + {0, "loader_dsp.fw"}, + {0, "indigo_dj_dsp.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 32000, + .rate_max = 96000, + .channels_min = 1, + .channels_max = 4, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, +}; + +#include "indigodj_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio.c" + diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c new file mode 100644 index 000000000..500e150b4 --- /dev/null +++ b/sound/pci/echoaudio/indigodj_dsp.c @@ -0,0 +1,170 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, + int gain); +static int update_vmixer_level(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Indigo DJ\n")); + snd_assert((subdevice_id & 0xfff0) == INDIGO_DJ, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP]; + /* Since this card has no ASIC, mark it as loaded so everything + works OK */ + chip->asic_loaded = TRUE; + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + /* Default routing of the virtual channels: vchannels 0-3 and + vchannels 4-7 are routed to real channels 0-4 */ + set_vmixer_gain(chip, 0, 0, 0); + set_vmixer_gain(chip, 1, 1, 0); + set_vmixer_gain(chip, 2, 2, 0); + set_vmixer_gain(chip, 3, 3, 0); + set_vmixer_gain(chip, 0, 4, 0); + set_vmixer_gain(chip, 1, 5, 0); + set_vmixer_gain(chip, 2, 6, 0); + set_vmixer_gain(chip, 3, 7, 0); + err = update_vmixer_level(chip); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + return ECHO_CLOCK_BIT_INTERNAL; +} + + + +/* The IndigoDJ has no ASIC. Just do nothing */ +static int load_asic(struct echoaudio *chip) +{ + return 0; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u32 control_reg; + + switch (rate) { + case 96000: + control_reg = MIA_96000; + break; + case 88200: + control_reg = MIA_88200; + break; + case 48000: + control_reg = MIA_48000; + break; + case 44100: + control_reg = MIA_44100; + break; + case 32000: + control_reg = MIA_32000; + break; + default: + DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + return -EINVAL; + } + + /* Set the control register if it has changed */ + if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ + chip->comm_page->control_register = cpu_to_le32(control_reg); + chip->sample_rate = rate; + + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_CLOCKS); + } + return 0; +} + + + +/* This function routes the sound from a virtual channel to a real output */ +static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, + int gain) +{ + int index; + + snd_assert(pipe < num_pipes_out(chip) && + output < num_busses_out(chip), return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + chip->vmixer_gain[output][pipe] = gain; + index = output * num_pipes_out(chip) + pipe; + chip->comm_page->vmixer[index] = gain; + + DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + return 0; +} + + + +/* Tell the DSP to read and update virtual mixer levels in comm page. */ +static int update_vmixer_level(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); +} + diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c new file mode 100644 index 000000000..a8788e959 --- /dev/null +++ b/sound/pci/echoaudio/indigoio.c @@ -0,0 +1,105 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define INDIGO_FAMILY +#define ECHOCARD_INDIGO_IO +#define ECHOCARD_NAME "Indigo IO" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_VMIXER +#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 0 */ +#define PX_ANALOG_IN 8 /* 2 */ +#define PX_DIGITAL_IN 10 /* 0 */ +#define PX_NUM 10 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 2 */ +#define BX_DIGITAL_OUT 2 /* 0 */ +#define BX_ANALOG_IN 2 /* 2 */ +#define BX_DIGITAL_IN 4 /* 0 */ +#define BX_NUM 4 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_361_LOADER 0 +#define FW_INDIGO_IO_DSP 1 + +static const struct firmware card_fw[] = { + {0, "loader_dsp.fw"}, + {0, "indigo_io_dsp.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 32000, + .rate_max = 96000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, +}; + +#include "indigoio_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio.c" + diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c new file mode 100644 index 000000000..f3ad13d06 --- /dev/null +++ b/sound/pci/echoaudio/indigoio_dsp.c @@ -0,0 +1,141 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, + int gain); +static int update_vmixer_level(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Indigo IO\n")); + snd_assert((subdevice_id & 0xfff0) == INDIGO_IO, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP]; + /* Since this card has no ASIC, mark it as loaded so everything + works OK */ + chip->asic_loaded = TRUE; + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + /* Default routing of the virtual channels: all vchannels are routed + to the stereo output */ + set_vmixer_gain(chip, 0, 0, 0); + set_vmixer_gain(chip, 1, 1, 0); + set_vmixer_gain(chip, 0, 2, 0); + set_vmixer_gain(chip, 1, 3, 0); + set_vmixer_gain(chip, 0, 4, 0); + set_vmixer_gain(chip, 1, 5, 0); + set_vmixer_gain(chip, 0, 6, 0); + set_vmixer_gain(chip, 1, 7, 0); + err = update_vmixer_level(chip); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + return ECHO_CLOCK_BIT_INTERNAL; +} + + + +/* The IndigoIO has no ASIC. Just do nothing */ +static int load_asic(struct echoaudio *chip) +{ + return 0; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + if (wait_handshake(chip)) + return -EIO; + + chip->sample_rate = rate; + chip->comm_page->sample_rate = cpu_to_le32(rate); + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_CLOCKS); +} + + + +/* This function routes the sound from a virtual channel to a real output */ +static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, + int gain) +{ + int index; + + snd_assert(pipe < num_pipes_out(chip) && + output < num_busses_out(chip), return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + chip->vmixer_gain[output][pipe] = gain; + index = output * num_pipes_out(chip) + pipe; + chip->comm_page->vmixer[index] = gain; + + DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + return 0; +} + + + +/* Tell the DSP to read and update virtual mixer levels in comm page. */ +static int update_vmixer_level(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); +} + diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c new file mode 100644 index 000000000..e503d74b3 --- /dev/null +++ b/sound/pci/echoaudio/layla20.c @@ -0,0 +1,112 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHOGALS_FAMILY +#define ECHOCARD_LAYLA20 +#define ECHOCARD_NAME "Layla20" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_ASIC +#define ECHOCARD_HAS_INPUT_GAIN +#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_DIGITAL_IO +#define ECHOCARD_HAS_EXTERNAL_CLOCK +#define ECHOCARD_HAS_ADAT FALSE +#define ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH +#define ECHOCARD_HAS_MIDI + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 10 */ +#define PX_DIGITAL_OUT 10 /* 2 */ +#define PX_ANALOG_IN 12 /* 8 */ +#define PX_DIGITAL_IN 20 /* 2 */ +#define PX_NUM 22 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 10 */ +#define BX_DIGITAL_OUT 10 /* 2 */ +#define BX_ANALOG_IN 12 /* 8 */ +#define BX_DIGITAL_IN 20 /* 2 */ +#define BX_NUM 22 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_LAYLA20_DSP 0 +#define FW_LAYLA20_ASIC 1 + +static const struct firmware card_fw[] = { + {0, "layla20_dsp.fw"}, + {0, "layla20_asic.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */ + {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 8000, + .rate_max = 50000, + .channels_min = 1, + .channels_max = 10, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, + /* One page (4k) contains 512 instructions. I don't know if the hw + supports lists longer than this. In this case periods_max=220 is a + safe limit to make sure the list never exceeds 512 instructions. */ +}; + +#include "layla20_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio.c" +#include "midi.c" diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c new file mode 100644 index 000000000..990c9a60a --- /dev/null +++ b/sound/pci/echoaudio/layla20_dsp.c @@ -0,0 +1,290 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int read_dsp(struct echoaudio *chip, u32 *data); +static int set_professional_spdif(struct echoaudio *chip, char prof); +static int load_asic_generic(struct echoaudio *chip, u32 cmd, + const struct firmware *asic); +static int check_asic_status(struct echoaudio *chip); +static int update_flags(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Layla20\n")); + snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->has_midi = TRUE; + chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP]; + chip->input_clock_types = + ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | + ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; + chip->output_clock_types = + ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + err = set_professional_spdif(chip, TRUE); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + u32 clocks_from_dsp, clock_bits; + + /* Map the DSP clock detect bits to the generic driver clock detect bits */ + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + clock_bits = ECHO_CLOCK_BIT_INTERNAL; + + if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) + clock_bits |= ECHO_CLOCK_BIT_SPDIF; + + if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) { + if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER) + clock_bits |= ECHO_CLOCK_BIT_SUPER; + else + clock_bits |= ECHO_CLOCK_BIT_WORD; + } + + return clock_bits; +} + + + +/* ASIC status check - some cards have one or two ASICs that need to be +loaded. Once that load is complete, this function is called to see if +the load was successful. +If this load fails, it does not necessarily mean that the hardware is +defective - the external box may be disconnected or turned off. +This routine sometimes fails for Layla20; for Layla20, the loop runs +5 times and succeeds if it wins on three of the loops. */ +static int check_asic_status(struct echoaudio *chip) +{ + u32 asic_status; + int goodcnt, i; + + chip->asic_loaded = FALSE; + for (i = goodcnt = 0; i < 5; i++) { + send_vector(chip, DSP_VC_TEST_ASIC); + + /* The DSP will return a value to indicate whether or not + the ASIC is currently loaded */ + if (read_dsp(chip, &asic_status) < 0) { + DE_ACT(("check_asic_status: failed on read_dsp\n")); + return -EIO; + } + + if (asic_status == ASIC_ALREADY_LOADED) { + if (++goodcnt == 3) { + chip->asic_loaded = TRUE; + return 0; + } + } + } + return -EIO; +} + + + +/* Layla20 has an ASIC in the external box */ +static int load_asic(struct echoaudio *chip) +{ + int err; + + if (chip->asic_loaded) + return 0; + + err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, + &card_fw[FW_LAYLA20_ASIC]); + if (err < 0) + return err; + + /* Check if ASIC is alive and well. */ + return check_asic_status(chip); +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL); + + /* Only set the clock for internal mode. Do not return failure, + simply treat it as a non-event. */ + if (chip->input_clock != ECHO_CLOCK_INTERNAL) { + DE_ACT(("set_sample_rate: Cannot set sample rate - " + "clock not set to CLK_CLOCKININTERNAL\n")); + chip->comm_page->sample_rate = cpu_to_le32(rate); + chip->sample_rate = rate; + return 0; + } + + if (wait_handshake(chip)) + return -EIO; + + DE_ACT(("set_sample_rate(%d)\n", rate)); + chip->sample_rate = rate; + chip->comm_page->sample_rate = cpu_to_le32(rate); + clear_handshake(chip); + return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE); +} + + + +static int set_input_clock(struct echoaudio *chip, u16 clock_source) +{ + u16 clock; + u32 rate; + + DE_ACT(("set_input_clock:\n")); + rate = 0; + switch (clock_source) { + case ECHO_CLOCK_INTERNAL: + DE_ACT(("Set Layla20 clock to INTERNAL\n")); + rate = chip->sample_rate; + clock = LAYLA20_CLOCK_INTERNAL; + break; + case ECHO_CLOCK_SPDIF: + DE_ACT(("Set Layla20 clock to SPDIF\n")); + clock = LAYLA20_CLOCK_SPDIF; + break; + case ECHO_CLOCK_WORD: + DE_ACT(("Set Layla20 clock to WORD\n")); + clock = LAYLA20_CLOCK_WORD; + break; + case ECHO_CLOCK_SUPER: + DE_ACT(("Set Layla20 clock to SUPER\n")); + clock = LAYLA20_CLOCK_SUPER; + break; + default: + DE_ACT(("Input clock 0x%x not supported for Layla24\n", + clock_source)); + return -EINVAL; + } + chip->input_clock = clock_source; + + chip->comm_page->input_clock = cpu_to_le16(clock); + clear_handshake(chip); + send_vector(chip, DSP_VC_UPDATE_CLOCKS); + + if (rate) + set_sample_rate(chip, rate); + + return 0; +} + + + +static int set_output_clock(struct echoaudio *chip, u16 clock) +{ + DE_ACT(("set_output_clock: %d\n", clock)); + switch (clock) { + case ECHO_CLOCK_SUPER: + clock = LAYLA20_OUTPUT_CLOCK_SUPER; + break; + case ECHO_CLOCK_WORD: + clock = LAYLA20_OUTPUT_CLOCK_WORD; + break; + default: + DE_ACT(("set_output_clock wrong clock\n")); + return -EINVAL; + } + + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->output_clock = cpu_to_le16(clock); + chip->output_clock = clock; + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_CLOCKS); +} + + + +/* Set input bus gain (one unit is 0.5dB !) */ +static int set_input_gain(struct echoaudio *chip, u16 input, int gain) +{ + snd_assert(input < num_busses_in(chip), return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + chip->input_gain[input] = gain; + gain += GL20_INPUT_GAIN_MAGIC_NUMBER; + chip->comm_page->line_in_level[input] = gain; + return 0; +} + + + +/* Tell the DSP to reread the flags from the comm page */ +static int update_flags(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_FLAGS); +} + + + +static int set_professional_spdif(struct echoaudio *chip, char prof) +{ + DE_ACT(("set_professional_spdif %d\n", prof)); + if (prof) + chip->comm_page->flags |= + __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + else + chip->comm_page->flags &= + ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + chip->professional_spdif = prof; + return update_flags(chip); +} diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c new file mode 100644 index 000000000..d4581fdc8 --- /dev/null +++ b/sound/pci/echoaudio/layla24.c @@ -0,0 +1,121 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHO24_FAMILY +#define ECHOCARD_LAYLA24 +#define ECHOCARD_NAME "Layla24" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_ASIC +#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_DIGITAL_IO +#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE +#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH +#define ECHOCARD_HAS_EXTERNAL_CLOCK +#define ECHOCARD_HAS_ADAT 6 +#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 +#define ECHOCARD_HAS_MIDI + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 8 */ +#define PX_ANALOG_IN 16 /* 8 */ +#define PX_DIGITAL_IN 24 /* 8 */ +#define PX_NUM 32 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 8 */ +#define BX_DIGITAL_OUT 8 /* 8 */ +#define BX_ANALOG_IN 16 /* 8 */ +#define BX_DIGITAL_IN 24 /* 8 */ +#define BX_NUM 32 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_361_LOADER 0 +#define FW_LAYLA24_DSP 1 +#define FW_LAYLA24_1_ASIC 2 +#define FW_LAYLA24_2A_ASIC 3 +#define FW_LAYLA24_2S_ASIC 4 + +static const struct firmware card_fw[] = { + {0, "loader_dsp.fw"}, + {0, "layla24_dsp.fw"}, + {0, "layla24_1_asic.fw"}, + {0, "layla24_2A_asic.fw"}, + {0, "layla24_2S_asic.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_8000_96000, + .rate_min = 8000, + .rate_max = 100000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, + /* One page (4k) contains 512 instructions. I don't know if the hw + supports lists longer than this. In this case periods_max=220 is a + safe limit to make sure the list never exceeds 512 instructions. */ +}; + + +#include "layla24_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio_gml.c" +#include "echoaudio.c" +#include "midi.c" diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c new file mode 100644 index 000000000..7ec5b63d0 --- /dev/null +++ b/sound/pci/echoaudio/layla24_dsp.c @@ -0,0 +1,394 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int write_control_reg(struct echoaudio *chip, u32 value, char force); +static int set_input_clock(struct echoaudio *chip, u16 clock); +static int set_professional_spdif(struct echoaudio *chip, char prof); +static int set_digital_mode(struct echoaudio *chip, u8 mode); +static int load_asic_generic(struct echoaudio *chip, u32 cmd, + const struct firmware *asic); +static int check_asic_status(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Layla24\n")); + snd_assert((subdevice_id & 0xfff0) == LAYLA24, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->has_midi = TRUE; + chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP]; + chip->input_clock_types = + ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | + ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; + chip->digital_modes = + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | + ECHOCAPS_HAS_DIGITAL_MODE_ADAT; + chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; + chip->professional_spdif = FALSE; + chip->digital_in_automute = TRUE; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); + snd_assert(err >= 0, return err); + err = set_professional_spdif(chip, TRUE); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + u32 clocks_from_dsp, clock_bits; + + /* Map the DSP clock detect bits to the generic driver clock detect bits */ + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + clock_bits = ECHO_CLOCK_BIT_INTERNAL; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) + clock_bits |= ECHO_CLOCK_BIT_SPDIF; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) + clock_bits |= ECHO_CLOCK_BIT_ADAT; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD) + clock_bits |= ECHO_CLOCK_BIT_WORD; + + return clock_bits; +} + + + +/* Layla24 has an ASIC on the PCI card and another ASIC in the external box; +both need to be loaded. */ +static int load_asic(struct echoaudio *chip) +{ + int err; + + if (chip->asic_loaded) + return 1; + + DE_INIT(("load_asic\n")); + + /* Give the DSP a few milliseconds to settle down */ + mdelay(10); + + /* Load the ASIC for the PCI card */ + err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, + &card_fw[FW_LAYLA24_1_ASIC]); + if (err < 0) + return err; + + chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC]; + + /* Now give the new ASIC a little time to set up */ + mdelay(10); + + /* Do the external one */ + err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, + &card_fw[FW_LAYLA24_2S_ASIC]); + if (err < 0) + return FALSE; + + /* Now give the external ASIC a little time to set up */ + mdelay(10); + + /* See if it worked */ + err = check_asic_status(chip); + + /* Set up the control register if the load succeeded - + 48 kHz, internal clock, S/PDIF RCA mode */ + if (!err) + err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ, + TRUE); + + DE_INIT(("load_asic() done\n")); + return err; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u32 control_reg, clock, base_rate; + + snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, + return -EINVAL); + + /* Only set the clock for internal mode. */ + if (chip->input_clock != ECHO_CLOCK_INTERNAL) { + DE_ACT(("set_sample_rate: Cannot set sample rate - " + "clock not set to CLK_CLOCKININTERNAL\n")); + /* Save the rate anyhow */ + chip->comm_page->sample_rate = cpu_to_le32(rate); + chip->sample_rate = rate; + return 0; + } + + /* Get the control register & clear the appropriate bits */ + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK; + + clock = 0; + + switch (rate) { + case 96000: + clock = GML_96KHZ; + break; + case 88200: + clock = GML_88KHZ; + break; + case 48000: + clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; + break; + case 44100: + clock = GML_44KHZ; + /* Professional mode */ + if (control_reg & GML_SPDIF_PRO_MODE) + clock |= GML_SPDIF_SAMPLE_RATE0; + break; + case 32000: + clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | + GML_SPDIF_SAMPLE_RATE1; + break; + case 22050: + clock = GML_22KHZ; + break; + case 16000: + clock = GML_16KHZ; + break; + case 11025: + clock = GML_11KHZ; + break; + case 8000: + clock = GML_8KHZ; + break; + default: + /* If this is a non-standard rate, then the driver needs to + use Layla24's special "continuous frequency" mode */ + clock = LAYLA24_CONTINUOUS_CLOCK; + if (rate > 50000) { + base_rate = rate >> 1; + control_reg |= GML_DOUBLE_SPEED_MODE; + } else { + base_rate = rate; + } + + if (base_rate < 25000) + base_rate = 25000; + + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->sample_rate = + cpu_to_le32(LAYLA24_MAGIC_NUMBER / base_rate - 2); + + clear_handshake(chip); + send_vector(chip, DSP_VC_SET_LAYLA24_FREQUENCY_REG); + } + + control_reg |= clock; + + chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ + chip->sample_rate = rate; + DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg)); + + return write_control_reg(chip, control_reg, FALSE); +} + + + +static int set_input_clock(struct echoaudio *chip, u16 clock) +{ + u32 control_reg, clocks_from_dsp; + + /* Mask off the clock select bits */ + control_reg = le32_to_cpu(chip->comm_page->control_register) & + GML_CLOCK_CLEAR_MASK; + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + /* Pick the new clock */ + switch (clock) { + case ECHO_CLOCK_INTERNAL: + DE_ACT(("Set Layla24 clock to INTERNAL\n")); + chip->input_clock = ECHO_CLOCK_INTERNAL; + return set_sample_rate(chip, chip->sample_rate); + case ECHO_CLOCK_SPDIF: + if (chip->digital_mode == DIGITAL_MODE_ADAT) + return -EAGAIN; + control_reg |= GML_SPDIF_CLOCK; + /* Layla24 doesn't support 96KHz S/PDIF */ + control_reg &= ~GML_DOUBLE_SPEED_MODE; + DE_ACT(("Set Layla24 clock to SPDIF\n")); + break; + case ECHO_CLOCK_WORD: + control_reg |= GML_WORD_CLOCK; + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) + control_reg |= GML_DOUBLE_SPEED_MODE; + else + control_reg &= ~GML_DOUBLE_SPEED_MODE; + DE_ACT(("Set Layla24 clock to WORD\n")); + break; + case ECHO_CLOCK_ADAT: + if (chip->digital_mode != DIGITAL_MODE_ADAT) + return -EAGAIN; + control_reg |= GML_ADAT_CLOCK; + control_reg &= ~GML_DOUBLE_SPEED_MODE; + DE_ACT(("Set Layla24 clock to ADAT\n")); + break; + default: + DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock)); + return -EINVAL; + } + + chip->input_clock = clock; + return write_control_reg(chip, control_reg, TRUE); +} + + + +/* Depending on what digital mode you want, Layla24 needs different ASICs +loaded. This function checks the ASIC needed for the new mode and sees +if it matches the one already loaded. */ +static int switch_asic(struct echoaudio *chip, const struct firmware *asic) +{ + s8 *monitors; + + /* Check to see if this is already loaded */ + if (asic != chip->asic_code) { + monitors = kmalloc(MONITOR_ARRAY_SIZE, GFP_KERNEL); + if (! monitors) + return -ENOMEM; + + memcpy(monitors, chip->comm_page->monitors, MONITOR_ARRAY_SIZE); + memset(chip->comm_page->monitors, ECHOGAIN_MUTED, + MONITOR_ARRAY_SIZE); + + /* Load the desired ASIC */ + if (load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, + asic) < 0) { + memcpy(chip->comm_page->monitors, monitors, + MONITOR_ARRAY_SIZE); + kfree(monitors); + return -EIO; + } + chip->asic_code = asic; + memcpy(chip->comm_page->monitors, monitors, MONITOR_ARRAY_SIZE); + kfree(monitors); + } + + return 0; +} + + + +static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) +{ + u32 control_reg; + int err, incompatible_clock; + const struct firmware *asic; + + /* Set clock to "internal" if it's not compatible with the new mode */ + incompatible_clock = FALSE; + switch (mode) { + case DIGITAL_MODE_SPDIF_OPTICAL: + case DIGITAL_MODE_SPDIF_RCA: + if (chip->input_clock == ECHO_CLOCK_ADAT) + incompatible_clock = TRUE; + asic = &card_fw[FW_LAYLA24_2S_ASIC]; + break; + case DIGITAL_MODE_ADAT: + if (chip->input_clock == ECHO_CLOCK_SPDIF) + incompatible_clock = TRUE; + asic = &card_fw[FW_LAYLA24_2A_ASIC]; + break; + default: + DE_ACT(("Digital mode not supported: %d\n", mode)); + return -EINVAL; + } + + if (incompatible_clock) { /* Switch to 48KHz, internal */ + chip->sample_rate = 48000; + spin_lock_irq(&chip->lock); + set_input_clock(chip, ECHO_CLOCK_INTERNAL); + spin_unlock_irq(&chip->lock); + } + + /* switch_asic() can sleep */ + if (switch_asic(chip, asic) < 0) + return -EIO; + + spin_lock_irq(&chip->lock); + + /* Tweak the control register */ + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; + + switch (mode) { + case DIGITAL_MODE_SPDIF_OPTICAL: + control_reg |= GML_SPDIF_OPTICAL_MODE; + break; + case DIGITAL_MODE_SPDIF_RCA: + /* GML_SPDIF_OPTICAL_MODE bit cleared */ + break; + case DIGITAL_MODE_ADAT: + control_reg |= GML_ADAT_MODE; + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + } + + err = write_control_reg(chip, control_reg, TRUE); + spin_unlock_irq(&chip->lock); + if (err < 0) + return err; + chip->digital_mode = mode; + + DE_ACT(("set_digital_mode to %d\n", mode)); + return incompatible_clock; +} diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c new file mode 100644 index 000000000..be40c6426 --- /dev/null +++ b/sound/pci/echoaudio/mia.c @@ -0,0 +1,117 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHO24_FAMILY +#define ECHOCARD_MIA +#define ECHOCARD_NAME "Mia" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_VMIXER +#define ECHOCARD_HAS_DIGITAL_IO +#define ECHOCARD_HAS_EXTERNAL_CLOCK +#define ECHOCARD_HAS_ADAT FALSE +#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 +#define ECHOCARD_HAS_MIDI + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 8 */ +#define PX_DIGITAL_OUT 8 /* 0 */ +#define PX_ANALOG_IN 8 /* 2 */ +#define PX_DIGITAL_IN 10 /* 2 */ +#define PX_NUM 12 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 2 */ +#define BX_DIGITAL_OUT 2 /* 2 */ +#define BX_ANALOG_IN 4 /* 2 */ +#define BX_DIGITAL_IN 6 /* 2 */ +#define BX_NUM 8 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_361_LOADER 0 +#define FW_MIA_DSP 1 + +static const struct firmware card_fw[] = { + {0, "loader_dsp.fw"}, + {0, "mia_dsp.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */ + {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 8000, + .rate_max = 96000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, + /* One page (4k) contains 512 instructions. I don't know if the hw + supports lists longer than this. In this case periods_max=220 is a + safe limit to make sure the list never exceeds 512 instructions. */ +}; + + +#include "mia_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio.c" +#include "midi.c" diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c new file mode 100644 index 000000000..891c70519 --- /dev/null +++ b/sound/pci/echoaudio/mia_dsp.c @@ -0,0 +1,229 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int set_input_clock(struct echoaudio *chip, u16 clock); +static int set_professional_spdif(struct echoaudio *chip, char prof); +static int update_flags(struct echoaudio *chip); +static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, + int gain); +static int update_vmixer_level(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Mia\n")); + snd_assert((subdevice_id & 0xfff0) == MIA, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->dsp_code_to_load = &card_fw[FW_MIA_DSP]; + /* Since this card has no ASIC, mark it as loaded so everything + works OK */ + chip->asic_loaded = TRUE; + if ((subdevice_id & 0x0000f) == MIA_MIDI_REV) + chip->has_midi = TRUE; + chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | + ECHO_CLOCK_BIT_SPDIF; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip))) + return err; + + /* Default routing of the virtual channels: vchannels 0-3 go to analog + outputs and vchannels 4-7 go to S/PDIF outputs */ + set_vmixer_gain(chip, 0, 0, 0); + set_vmixer_gain(chip, 1, 1, 0); + set_vmixer_gain(chip, 0, 2, 0); + set_vmixer_gain(chip, 1, 3, 0); + set_vmixer_gain(chip, 2, 4, 0); + set_vmixer_gain(chip, 3, 5, 0); + set_vmixer_gain(chip, 2, 6, 0); + set_vmixer_gain(chip, 3, 7, 0); + err = update_vmixer_level(chip); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + u32 clocks_from_dsp, clock_bits; + + /* Map the DSP clock detect bits to the generic driver clock + detect bits */ + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + clock_bits = ECHO_CLOCK_BIT_INTERNAL; + + if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) + clock_bits |= ECHO_CLOCK_BIT_SPDIF; + + return clock_bits; +} + + + +/* The Mia has no ASIC. Just do nothing */ +static int load_asic(struct echoaudio *chip) +{ + return 0; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u32 control_reg; + + switch (rate) { + case 96000: + control_reg = MIA_96000; + break; + case 88200: + control_reg = MIA_88200; + break; + case 48000: + control_reg = MIA_48000; + break; + case 44100: + control_reg = MIA_44100; + break; + case 32000: + control_reg = MIA_32000; + break; + default: + DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + return -EINVAL; + } + + /* Override the clock setting if this Mia is set to S/PDIF clock */ + if (chip->input_clock == ECHO_CLOCK_SPDIF) + control_reg |= MIA_SPDIF; + + /* Set the control register if it has changed */ + if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { + if (wait_handshake(chip)) + return -EIO; + + chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ + chip->comm_page->control_register = cpu_to_le32(control_reg); + chip->sample_rate = rate; + + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_CLOCKS); + } + return 0; +} + + + +static int set_input_clock(struct echoaudio *chip, u16 clock) +{ + DE_ACT(("set_input_clock(%d)\n", clock)); + snd_assert(clock == ECHO_CLOCK_INTERNAL || clock == ECHO_CLOCK_SPDIF, + return -EINVAL); + + chip->input_clock = clock; + return set_sample_rate(chip, chip->sample_rate); +} + + + +/* This function routes the sound from a virtual channel to a real output */ +static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, + int gain) +{ + int index; + + snd_assert(pipe < num_pipes_out(chip) && + output < num_busses_out(chip), return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + chip->vmixer_gain[output][pipe] = gain; + index = output * num_pipes_out(chip) + pipe; + chip->comm_page->vmixer[index] = gain; + + DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + return 0; +} + + + +/* Tell the DSP to read and update virtual mixer levels in comm page. */ +static int update_vmixer_level(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); +} + + + +/* Tell the DSP to reread the flags from the comm page */ +static int update_flags(struct echoaudio *chip) +{ + if (wait_handshake(chip)) + return -EIO; + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_FLAGS); +} + + + +static int set_professional_spdif(struct echoaudio *chip, char prof) +{ + DE_ACT(("set_professional_spdif %d\n", prof)); + if (prof) + chip->comm_page->flags |= + __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + else + chip->comm_page->flags &= + ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); + chip->professional_spdif = prof; + return update_flags(chip); +} + diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c new file mode 100644 index 000000000..e31f0f11e --- /dev/null +++ b/sound/pci/echoaudio/midi.c @@ -0,0 +1,327 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +/****************************************************************************** + MIDI lowlevel code +******************************************************************************/ + +/* Start and stop Midi input */ +static int enable_midi_input(struct echoaudio *chip, char enable) +{ + DE_MID(("enable_midi_input(%d)\n", enable)); + + if (wait_handshake(chip)) + return -EIO; + + if (enable) { + chip->mtc_state = MIDI_IN_STATE_NORMAL; + chip->comm_page->flags |= + __constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT); + } else + chip->comm_page->flags &= + ~__constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT); + + clear_handshake(chip); + return send_vector(chip, DSP_VC_UPDATE_FLAGS); +} + + + +/* Send a buffer full of MIDI data to the DSP +Returns how many actually written or < 0 on error */ +static int write_midi(struct echoaudio *chip, u8 *data, int bytes) +{ + snd_assert(bytes > 0 && bytes < MIDI_OUT_BUFFER_SIZE, return -EINVAL); + + if (wait_handshake(chip)) + return -EIO; + + /* HF4 indicates that it is safe to write MIDI output data */ + if (! (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_REG_HF4)) + return 0; + + chip->comm_page->midi_output[0] = bytes; + memcpy(&chip->comm_page->midi_output[1], data, bytes); + chip->comm_page->midi_out_free_count = 0; + clear_handshake(chip); + send_vector(chip, DSP_VC_MIDI_WRITE); + DE_MID(("write_midi: %d\n", bytes)); + return bytes; +} + + + +/* Run the state machine for MIDI input data +MIDI time code sync isn't supported by this code right now, but you still need +this state machine to parse the incoming MIDI data stream. Every time the DSP +sees a 0xF1 byte come in, it adds the DSP sample position to the MIDI data +stream. The DSP sample position is represented as a 32 bit unsigned value, +with the high 16 bits first, followed by the low 16 bits. Since these aren't +real MIDI bytes, the following logic is needed to skip them. */ +static inline int mtc_process_data(struct echoaudio *chip, short midi_byte) +{ + switch (chip->mtc_state) { + case MIDI_IN_STATE_NORMAL: + if (midi_byte == 0xF1) + chip->mtc_state = MIDI_IN_STATE_TS_HIGH; + break; + case MIDI_IN_STATE_TS_HIGH: + chip->mtc_state = MIDI_IN_STATE_TS_LOW; + return MIDI_IN_SKIP_DATA; + break; + case MIDI_IN_STATE_TS_LOW: + chip->mtc_state = MIDI_IN_STATE_F1_DATA; + return MIDI_IN_SKIP_DATA; + break; + case MIDI_IN_STATE_F1_DATA: + chip->mtc_state = MIDI_IN_STATE_NORMAL; + break; + } + return 0; +} + + + +/* This function is called from the IRQ handler and it reads the midi data +from the DSP's buffer. It returns the number of bytes received. */ +static int midi_service_irq(struct echoaudio *chip) +{ + short int count, midi_byte, i, received; + + /* The count is at index 0, followed by actual data */ + count = le16_to_cpu(chip->comm_page->midi_input[0]); + + snd_assert(count < MIDI_IN_BUFFER_SIZE, return 0); + + /* Get the MIDI data from the comm page */ + i = 1; + received = 0; + for (i = 1; i <= count; i++) { + /* Get the MIDI byte */ + midi_byte = le16_to_cpu(chip->comm_page->midi_input[i]); + + /* Parse the incoming MIDI stream. The incoming MIDI data + consists of MIDI bytes and timestamps for the MIDI time code + 0xF1 bytes. mtc_process_data() is a little state machine that + parses the stream. If you get MIDI_IN_SKIP_DATA back, then + this is a timestamp byte, not a MIDI byte, so don't store it + in the MIDI input buffer. */ + if (mtc_process_data(chip, midi_byte) == MIDI_IN_SKIP_DATA) + continue; + + chip->midi_buffer[received++] = (u8)midi_byte; + } + + return received; +} + + + + +/****************************************************************************** + MIDI interface +******************************************************************************/ + +static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream) +{ + struct echoaudio *chip = substream->rmidi->private_data; + + chip->midi_in = substream; + DE_MID(("rawmidi_iopen\n")); + return 0; +} + + + +static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream, + int up) +{ + struct echoaudio *chip = substream->rmidi->private_data; + + if (up != chip->midi_input_enabled) { + spin_lock_irq(&chip->lock); + enable_midi_input(chip, up); + spin_unlock_irq(&chip->lock); + chip->midi_input_enabled = up; + } +} + + + +static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream) +{ + struct echoaudio *chip = substream->rmidi->private_data; + + chip->midi_in = NULL; + DE_MID(("rawmidi_iclose\n")); + return 0; +} + + + +static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream) +{ + struct echoaudio *chip = substream->rmidi->private_data; + + chip->tinuse = 0; + chip->midi_full = 0; + chip->midi_out = substream; + DE_MID(("rawmidi_oopen\n")); + return 0; +} + + + +static void snd_echo_midi_output_write(unsigned long data) +{ + struct echoaudio *chip = (struct echoaudio *)data; + unsigned long flags; + int bytes, sent, time; + unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1]; + + DE_MID(("snd_echo_midi_output_write\n")); + /* No interrupts are involved: we have to check at regular intervals + if the card's output buffer has room for new data. */ + sent = bytes = 0; + spin_lock_irqsave(&chip->lock, flags); + chip->midi_full = 0; + if (chip->midi_out && !snd_rawmidi_transmit_empty(chip->midi_out)) { + bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf, + MIDI_OUT_BUFFER_SIZE - 1); + DE_MID(("Try to send %d bytes...\n", bytes)); + sent = write_midi(chip, buf, bytes); + if (sent < 0) { + snd_printk(KERN_ERR "write_midi() error %d\n", sent); + /* retry later */ + sent = 9000; + chip->midi_full = 1; + } else if (sent > 0) { + DE_MID(("%d bytes sent\n", sent)); + snd_rawmidi_transmit_ack(chip->midi_out, sent); + } else { + /* Buffer is full. DSP's internal buffer is 64 (128 ?) + bytes long. Let's wait until half of them are sent */ + DE_MID(("Full\n")); + sent = 32; + chip->midi_full = 1; + } + } + + /* We restart the timer only if there is some data left to send */ + if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) { + /* The timer will expire slightly after the data has been + sent */ + time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */ + mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000); + DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000))); + } + spin_unlock_irqrestore(&chip->lock, flags); +} + + + +static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream, + int up) +{ + struct echoaudio *chip = substream->rmidi->private_data; + + DE_MID(("snd_echo_midi_output_trigger(%d)\n", up)); + spin_lock_irq(&chip->lock); + if (up) { + if (!chip->tinuse) { + init_timer(&chip->timer); + chip->timer.function = snd_echo_midi_output_write; + chip->timer.data = (unsigned long)chip; + chip->tinuse = 1; + } + } else { + if (chip->tinuse) { + del_timer(&chip->timer); + chip->tinuse = 0; + DE_MID(("Timer removed\n")); + } + } + spin_unlock_irq(&chip->lock); + + if (up && !chip->midi_full) + snd_echo_midi_output_write((unsigned long)chip); +} + + + +static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream) +{ + struct echoaudio *chip = substream->rmidi->private_data; + + chip->midi_out = NULL; + DE_MID(("rawmidi_oclose\n")); + return 0; +} + + + +static struct snd_rawmidi_ops snd_echo_midi_input = { + .open = snd_echo_midi_input_open, + .close = snd_echo_midi_input_close, + .trigger = snd_echo_midi_input_trigger, +}; + +static struct snd_rawmidi_ops snd_echo_midi_output = { + .open = snd_echo_midi_output_open, + .close = snd_echo_midi_output_close, + .trigger = snd_echo_midi_output_trigger, +}; + + + +/* <--snd_echo_probe() */ +static int __devinit snd_echo_midi_create(struct snd_card *card, + struct echoaudio *chip) +{ + int err; + + if ((err = snd_rawmidi_new(card, card->shortname, 0, 1, 1, + &chip->rmidi)) < 0) + return err; + + strcpy(chip->rmidi->name, card->shortname); + chip->rmidi->private_data = chip; + + snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &snd_echo_midi_input); + snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &snd_echo_midi_output); + + chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | + SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; + DE_INIT(("MIDI ok\n")); + return 0; +} diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c new file mode 100644 index 000000000..5dc512add --- /dev/null +++ b/sound/pci/echoaudio/mona.c @@ -0,0 +1,129 @@ +/* + * ALSA driver for Echoaudio soundcards. + * Copyright (C) 2003-2004 Giuliano Pochini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define ECHO24_FAMILY +#define ECHOCARD_MONA +#define ECHOCARD_NAME "Mona" +#define ECHOCARD_HAS_MONITOR +#define ECHOCARD_HAS_ASIC +#define ECHOCARD_HAS_SUPER_INTERLEAVE +#define ECHOCARD_HAS_DIGITAL_IO +#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE +#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH +#define ECHOCARD_HAS_EXTERNAL_CLOCK +#define ECHOCARD_HAS_ADAT 6 +#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 + +/* Pipe indexes */ +#define PX_ANALOG_OUT 0 /* 6 */ +#define PX_DIGITAL_OUT 6 /* 8 */ +#define PX_ANALOG_IN 14 /* 4 */ +#define PX_DIGITAL_IN 18 /* 8 */ +#define PX_NUM 26 + +/* Bus indexes */ +#define BX_ANALOG_OUT 0 /* 6 */ +#define BX_DIGITAL_OUT 6 /* 8 */ +#define BX_ANALOG_IN 14 /* 4 */ +#define BX_DIGITAL_IN 18 /* 8 */ +#define BX_NUM 26 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "echoaudio.h" + +#define FW_361_LOADER 0 +#define FW_MONA_301_DSP 1 +#define FW_MONA_361_DSP 2 +#define FW_MONA_301_1_ASIC48 3 +#define FW_MONA_301_1_ASIC96 4 +#define FW_MONA_361_1_ASIC48 5 +#define FW_MONA_361_1_ASIC96 6 +#define FW_MONA_2_ASIC 7 + +static const struct firmware card_fw[] = { + {0, "loader_dsp.fw"}, + {0, "mona_301_dsp.fw"}, + {0, "mona_361_dsp.fw"}, + {0, "mona_301_1_asic_48.fw"}, + {0, "mona_301_1_asic_96.fw"}, + {0, "mona_361_1_asic_48.fw"}, + {0, "mona_361_1_asic_96.fw"}, + {0, "mona_2_asic.fw"} +}; + +static struct pci_device_id snd_echo_ids[] = { + {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */ + {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */ + {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */ + {0x1057, 0x3410, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56361 Mona rev.0 */ + {0x1057, 0x3410, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56361 Mona rev.1 */ + {0x1057, 0x3410, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56361 Mona rev.2 */ + {0,} +}; + +static struct snd_pcm_hardware pcm_hardware_skel = { + .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_U8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_S32_BE, + .rates = SNDRV_PCM_RATE_8000_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000, + .rate_min = 8000, + .rate_max = 96000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 262144, + .period_bytes_min = 32, + .period_bytes_max = 131072, + .periods_min = 2, + .periods_max = 220, + /* One page (4k) contains 512 instructions. I don't know if the hw + supports lists longer than this. In this case periods_max=220 is a + safe limit to make sure the list never exceeds 512 instructions. */ +}; + + +#include "mona_dsp.c" +#include "echoaudio_dsp.c" +#include "echoaudio_gml.c" +#include "echoaudio.c" diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c new file mode 100644 index 000000000..c0b4bf0be --- /dev/null +++ b/sound/pci/echoaudio/mona_dsp.c @@ -0,0 +1,428 @@ +/**************************************************************************** + + Copyright Echo Digital Audio Corporation (c) 1998 - 2004 + All rights reserved + www.echoaudio.com + + This file is part of Echo Digital Audio's generic driver library. + + Echo Digital Audio's generic driver library is free software; + 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 will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + ************************************************************************* + + Translation from C++ and adaptation for use in ALSA-Driver + were made by Giuliano Pochini + +****************************************************************************/ + + +static int write_control_reg(struct echoaudio *chip, u32 value, char force); +static int set_input_clock(struct echoaudio *chip, u16 clock); +static int set_professional_spdif(struct echoaudio *chip, char prof); +static int set_digital_mode(struct echoaudio *chip, u8 mode); +static int load_asic_generic(struct echoaudio *chip, u32 cmd, + const struct firmware *asic); +static int check_asic_status(struct echoaudio *chip); + + +static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) +{ + int err; + + DE_INIT(("init_hw() - Mona\n")); + snd_assert((subdevice_id & 0xfff0) == MONA, return -ENODEV); + + if ((err = init_dsp_comm_page(chip))) { + DE_INIT(("init_hw - could not initialize DSP comm page\n")); + return err; + } + + chip->device_id = device_id; + chip->subdevice_id = subdevice_id; + chip->bad_board = TRUE; + chip->input_clock_types = + ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | + ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; + chip->digital_modes = + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | + ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | + ECHOCAPS_HAS_DIGITAL_MODE_ADAT; + + /* Mona comes in both '301 and '361 flavors */ + if (chip->device_id == DEVICE_ID_56361) + chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP]; + else + chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP]; + + chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; + chip->professional_spdif = FALSE; + chip->digital_in_automute = TRUE; + + if ((err = load_firmware(chip)) < 0) + return err; + chip->bad_board = FALSE; + + if ((err = init_line_levels(chip)) < 0) + return err; + + err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); + snd_assert(err >= 0, return err); + err = set_professional_spdif(chip, TRUE); + + DE_INIT(("init_hw done\n")); + return err; +} + + + +static u32 detect_input_clocks(const struct echoaudio *chip) +{ + u32 clocks_from_dsp, clock_bits; + + /* Map the DSP clock detect bits to the generic driver clock + detect bits */ + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + clock_bits = ECHO_CLOCK_BIT_INTERNAL; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) + clock_bits |= ECHO_CLOCK_BIT_SPDIF; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) + clock_bits |= ECHO_CLOCK_BIT_ADAT; + + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD) + clock_bits |= ECHO_CLOCK_BIT_WORD; + + return clock_bits; +} + + + +/* Mona has an ASIC on the PCI card and another ASIC in the external box; +both need to be loaded. */ +static int load_asic(struct echoaudio *chip) +{ + u32 control_reg; + int err; + const struct firmware *asic; + + if (chip->asic_loaded) + return 0; + + mdelay(10); + + if (chip->device_id == DEVICE_ID_56361) + asic = &card_fw[FW_MONA_361_1_ASIC48]; + else + asic = &card_fw[FW_MONA_301_1_ASIC48]; + + err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); + if (err < 0) + return err; + + chip->asic_code = asic; + mdelay(10); + + /* Do the external one */ + err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, + &card_fw[FW_MONA_2_ASIC]); + if (err < 0) + return err; + + mdelay(10); + err = check_asic_status(chip); + + /* Set up the control register if the load succeeded - + 48 kHz, internal clock, S/PDIF RCA mode */ + if (!err) { + control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; + err = write_control_reg(chip, control_reg, TRUE); + } + + return err; +} + + + +/* Depending on what digital mode you want, Mona needs different ASICs +loaded. This function checks the ASIC needed for the new mode and sees +if it matches the one already loaded. */ +static int switch_asic(struct echoaudio *chip, char double_speed) +{ + const struct firmware *asic; + int err; + + /* Check the clock detect bits to see if this is + a single-speed clock or a double-speed clock; load + a new ASIC if necessary. */ + if (chip->device_id == DEVICE_ID_56361) { + if (double_speed) + asic = &card_fw[FW_MONA_361_1_ASIC96]; + else + asic = &card_fw[FW_MONA_361_1_ASIC48]; + } else { + if (double_speed) + asic = &card_fw[FW_MONA_301_1_ASIC96]; + else + asic = &card_fw[FW_MONA_301_1_ASIC48]; + } + + if (asic != chip->asic_code) { + /* Load the desired ASIC */ + err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, + asic); + if (err < 0) + return err; + chip->asic_code = asic; + } + + return 0; +} + + + +static int set_sample_rate(struct echoaudio *chip, u32 rate) +{ + u32 control_reg, clock; + const struct firmware *asic; + char force_write; + + /* Only set the clock for internal mode. */ + if (chip->input_clock != ECHO_CLOCK_INTERNAL) { + DE_ACT(("set_sample_rate: Cannot set sample rate - " + "clock not set to CLK_CLOCKININTERNAL\n")); + /* Save the rate anyhow */ + chip->comm_page->sample_rate = cpu_to_le32(rate); + chip->sample_rate = rate; + return 0; + } + + /* Now, check to see if the required ASIC is loaded */ + if (rate >= 88200) { + if (chip->digital_mode == DIGITAL_MODE_ADAT) + return -EINVAL; + if (chip->device_id == DEVICE_ID_56361) + asic = &card_fw[FW_MONA_361_1_ASIC96]; + else + asic = &card_fw[FW_MONA_301_1_ASIC96]; + } else { + if (chip->device_id == DEVICE_ID_56361) + asic = &card_fw[FW_MONA_361_1_ASIC48]; + else + asic = &card_fw[FW_MONA_301_1_ASIC48]; + } + + force_write = 0; + if (asic != chip->asic_code) { + int err; + /* Load the desired ASIC (load_asic_generic() can sleep) */ + spin_unlock_irq(&chip->lock); + err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, + asic); + spin_lock_irq(&chip->lock); + + if (err < 0) + return err; + chip->asic_code = asic; + force_write = 1; + } + + /* Compute the new control register value */ + clock = 0; + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= GML_CLOCK_CLEAR_MASK; + control_reg &= GML_SPDIF_RATE_CLEAR_MASK; + + switch (rate) { + case 96000: + clock = GML_96KHZ; + break; + case 88200: + clock = GML_88KHZ; + break; + case 48000: + clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; + break; + case 44100: + clock = GML_44KHZ; + /* Professional mode */ + if (control_reg & GML_SPDIF_PRO_MODE) + clock |= GML_SPDIF_SAMPLE_RATE0; + break; + case 32000: + clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | + GML_SPDIF_SAMPLE_RATE1; + break; + case 22050: + clock = GML_22KHZ; + break; + case 16000: + clock = GML_16KHZ; + break; + case 11025: + clock = GML_11KHZ; + break; + case 8000: + clock = GML_8KHZ; + break; + default: + DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + return -EINVAL; + } + + control_reg |= clock; + + chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ + chip->sample_rate = rate; + DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); + + return write_control_reg(chip, control_reg, force_write); +} + + + +static int set_input_clock(struct echoaudio *chip, u16 clock) +{ + u32 control_reg, clocks_from_dsp; + int err; + + DE_ACT(("set_input_clock:\n")); + + /* Prevent two simultaneous calls to switch_asic() */ + if (atomic_read(&chip->opencount)) + return -EAGAIN; + + /* Mask off the clock select bits */ + control_reg = le32_to_cpu(chip->comm_page->control_register) & + GML_CLOCK_CLEAR_MASK; + clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); + + switch (clock) { + case ECHO_CLOCK_INTERNAL: + DE_ACT(("Set Mona clock to INTERNAL\n")); + chip->input_clock = ECHO_CLOCK_INTERNAL; + return set_sample_rate(chip, chip->sample_rate); + case ECHO_CLOCK_SPDIF: + if (chip->digital_mode == DIGITAL_MODE_ADAT) + return -EAGAIN; + spin_unlock_irq(&chip->lock); + err = switch_asic(chip, clocks_from_dsp & + GML_CLOCK_DETECT_BIT_SPDIF96); + spin_lock_irq(&chip->lock); + if (err < 0) + return err; + DE_ACT(("Set Mona clock to SPDIF\n")); + control_reg |= GML_SPDIF_CLOCK; + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) + control_reg |= GML_DOUBLE_SPEED_MODE; + else + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + case ECHO_CLOCK_WORD: + DE_ACT(("Set Mona clock to WORD\n")); + spin_unlock_irq(&chip->lock); + err = switch_asic(chip, clocks_from_dsp & + GML_CLOCK_DETECT_BIT_WORD96); + spin_lock_irq(&chip->lock); + if (err < 0) + return err; + control_reg |= GML_WORD_CLOCK; + if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) + control_reg |= GML_DOUBLE_SPEED_MODE; + else + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + case ECHO_CLOCK_ADAT: + DE_ACT(("Set Mona clock to ADAT\n")); + if (chip->digital_mode != DIGITAL_MODE_ADAT) + return -EAGAIN; + control_reg |= GML_ADAT_CLOCK; + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + default: + DE_ACT(("Input clock 0x%x not supported for Mona\n", clock)); + return -EINVAL; + } + + chip->input_clock = clock; + return write_control_reg(chip, control_reg, TRUE); +} + + + +static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) +{ + u32 control_reg; + int err, incompatible_clock; + + /* Set clock to "internal" if it's not compatible with the new mode */ + incompatible_clock = FALSE; + switch (mode) { + case DIGITAL_MODE_SPDIF_OPTICAL: + case DIGITAL_MODE_SPDIF_RCA: + if (chip->input_clock == ECHO_CLOCK_ADAT) + incompatible_clock = TRUE; + break; + case DIGITAL_MODE_ADAT: + if (chip->input_clock == ECHO_CLOCK_SPDIF) + incompatible_clock = TRUE; + break; + default: + DE_ACT(("Digital mode not supported: %d\n", mode)); + return -EINVAL; + } + + spin_lock_irq(&chip->lock); + + if (incompatible_clock) { /* Switch to 48KHz, internal */ + chip->sample_rate = 48000; + set_input_clock(chip, ECHO_CLOCK_INTERNAL); + } + + /* Clear the current digital mode */ + control_reg = le32_to_cpu(chip->comm_page->control_register); + control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; + + /* Tweak the control reg */ + switch (mode) { + case DIGITAL_MODE_SPDIF_OPTICAL: + control_reg |= GML_SPDIF_OPTICAL_MODE; + break; + case DIGITAL_MODE_SPDIF_RCA: + /* GML_SPDIF_OPTICAL_MODE bit cleared */ + break; + case DIGITAL_MODE_ADAT: + /* If the current ASIC is the 96KHz ASIC, switch the ASIC + and set to 48 KHz */ + if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] || + chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) { + set_sample_rate(chip, 48000); + } + control_reg |= GML_ADAT_MODE; + control_reg &= ~GML_DOUBLE_SPEED_MODE; + break; + } + + err = write_control_reg(chip, control_reg, FALSE); + spin_unlock_irq(&chip->lock); + if (err < 0) + return err; + chip->digital_mode = mode; + + DE_ACT(("set_digital_mode to %d\n", mode)); + return incompatible_clock; +} diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 42b11ba1d..2dfa932f7 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c @@ -77,7 +77,7 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model."); /* * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 */ -static struct pci_device_id snd_emu10k1_ids[] __devinitdata = { +static struct pci_device_id snd_emu10k1_ids[] = { { 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* EMU10K1 */ { 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy */ { 0x1102, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy 2 Value SB0400 */ diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 6bfa08436..4faea3768 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -36,8 +36,6 @@ #include #include #include -#include - #include #include @@ -777,14 +775,6 @@ static int snd_emu10k1_dev_free(struct snd_device *device) static struct snd_emu_chip_details emu_chip_details[] = { /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ - /* Audigy4 SB0400 */ - {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102, - .driver = "Audigy2", .name = "Audigy 4 [SB0400]", - .id = "Audigy2", - .emu10k2_chip = 1, - .ca0108_chip = 1, - .spk71 = 1, - .ac97_chip = 1} , /* Tested by James@superbug.co.uk 3rd July 2005 */ /* DSP: CA0108-IAT * DAC: CS4382-KQ @@ -843,11 +833,8 @@ static struct snd_emu_chip_details emu_chip_details[] = { .spdif_bug = 1, .ac97_chip = 1} , /* Tested by shane-alsa@cm.nu 5th Nov 2005 */ - /* The 0x20061102 does have SB0350 written on it - * Just like 0x20021102 - */ {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102, - .driver = "Audigy2", .name = "Audigy 2 [SB0350b]", + .driver = "Audigy2", .name = "Audigy 2 [2006]", .id = "Audigy2", .emu10k2_chip = 1, .ca0102_chip = 1, @@ -1110,7 +1097,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card, spin_lock_init(&emu->voice_lock); spin_lock_init(&emu->synth_lock); spin_lock_init(&emu->memblk_lock); - mutex_init(&emu->fx8010.lock); + init_MUTEX(&emu->ptb_lock); + init_MUTEX(&emu->fx8010.lock); INIT_LIST_HEAD(&emu->mapped_link_head); INIT_LIST_HEAD(&emu->mapped_order_link_head); emu->pci = pci; @@ -1407,8 +1395,8 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu) /* resore for spdif */ if (emu->audigy) - outl(emu->port + A_IOCFG, emu->saved_a_iocfg); - outl(emu->port + HCFG, emu->saved_hcfg); + outl(emu->saved_a_iocfg, emu->port + A_IOCFG); + outl(emu->saved_hcfg, emu->port + HCFG); val = emu->saved_ptr; for (reg = saved_regs; *reg != 0xff; reg++) diff --git a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c index 204995a1d..1fa393f22 100644 --- a/sound/pci/emu10k1/emu10k1_synth.c +++ b/sound/pci/emu10k1/emu10k1_synth.c @@ -62,6 +62,7 @@ static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev) if (snd_emux_register(emu, dev->card, arg->index, "Emu10k1") < 0) { snd_emux_free(emu); + emu->hw = NULL; return -ENOMEM; } diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index d51290c18..1107c8ec7 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -894,24 +893,24 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card, static struct snd_device_ops ops = { .dev_free = snd_emu10k1x_dev_free, }; - + *rchip = NULL; - + 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, 0x0fffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { snd_printk(KERN_ERR "error to set 28bit mask DMA\n"); pci_disable_device(pci); return -ENXIO; } - + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; } - + chip->card = card; chip->pci = pci; chip->irq = -1; @@ -1595,7 +1594,7 @@ static void __devexit snd_emu10k1x_remove(struct pci_dev *pci) } // PCI IDs -static struct pci_device_id snd_emu10k1x_ids[] __devinitdata = { +static struct pci_device_id snd_emu10k1x_ids[] = { { 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dell OEM version (EMU10K1) */ { 0, } }; diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index dfba00230..509837252 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -32,8 +32,6 @@ #include #include #include -#include - #include #include @@ -876,7 +874,7 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, { int err = 0; - mutex_lock(&emu->fx8010.lock); + down(&emu->fx8010.lock); if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0) goto __error; strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name)); @@ -899,7 +897,7 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, else snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg); __error: - mutex_unlock(&emu->fx8010.lock); + up(&emu->fx8010.lock); return err; } @@ -908,7 +906,7 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, { int err; - mutex_lock(&emu->fx8010.lock); + down(&emu->fx8010.lock); strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name)); /* ok, do the main job */ err = snd_emu10k1_gpr_peek(emu, icode); @@ -918,7 +916,7 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, err = snd_emu10k1_code_peek(emu, icode); if (err >= 0) err = snd_emu10k1_list_controls(emu, icode); - mutex_unlock(&emu->fx8010.lock); + up(&emu->fx8010.lock); return err; } @@ -934,7 +932,7 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu, if (ipcm->channels > 32) return -EINVAL; pcm = &emu->fx8010.pcm[ipcm->substream]; - mutex_lock(&emu->fx8010.lock); + down(&emu->fx8010.lock); spin_lock_irq(&emu->reg_lock); if (pcm->opened) { err = -EBUSY; @@ -964,7 +962,7 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu, } __error: spin_unlock_irq(&emu->reg_lock); - mutex_unlock(&emu->fx8010.lock); + up(&emu->fx8010.lock); return err; } @@ -978,7 +976,7 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu, if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) return -EINVAL; pcm = &emu->fx8010.pcm[ipcm->substream]; - mutex_lock(&emu->fx8010.lock); + down(&emu->fx8010.lock); spin_lock_irq(&emu->reg_lock); ipcm->channels = pcm->channels; ipcm->tram_start = pcm->tram_start; @@ -994,7 +992,7 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu, ipcm->res1 = ipcm->res2 = 0; ipcm->pad = 0; spin_unlock_irq(&emu->reg_lock); - mutex_unlock(&emu->fx8010.lock); + up(&emu->fx8010.lock); return err; } @@ -2310,9 +2308,9 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un return -EPERM; if (get_user(addr, (unsigned int __user *)argp)) return -EFAULT; - mutex_lock(&emu->fx8010.lock); + down(&emu->fx8010.lock); res = snd_emu10k1_fx8010_tram_setup(emu, addr); - mutex_unlock(&emu->fx8010.lock); + up(&emu->fx8010.lock); return res; case SNDRV_EMU10K1_IOCTL_STOP: if (!capable(CAP_SYS_ADMIN)) diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index e7ec98649..68c795c03 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -24,8 +24,6 @@ #include #include #include -#include - #include #include @@ -304,10 +302,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst hdr = emu->memhdr; snd_assert(hdr, return NULL); - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); blk = search_empty(emu, runtime->dma_bytes); if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } /* fill buffer addresses but pointers are not stored so that @@ -320,14 +318,14 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst if (idx >= sgbuf->pages) { printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n", blk->first_page, blk->last_page, sgbuf->pages); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } #endif addr = sgbuf->table[idx].addr; if (! is_valid_page(emu, addr)) { printk(KERN_ERR "emu: failure page = %d\n", idx); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } emu->page_addr_table[page] = addr; @@ -339,10 +337,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst err = snd_emu10k1_memblk_map(emu, blk); if (err < 0) { __snd_util_mem_free(hdr, (struct snd_util_memblk *)blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return (struct snd_util_memblk *)blk; } @@ -371,19 +369,19 @@ snd_emu10k1_synth_alloc(struct snd_emu10k1 *hw, unsigned int size) struct snd_emu10k1_memblk *blk; struct snd_util_memhdr *hdr = hw->memhdr; - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); blk = (struct snd_emu10k1_memblk *)__snd_util_mem_alloc(hdr, size); if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } if (synth_alloc_pages(hw, blk)) { __snd_util_mem_free(hdr, (struct snd_util_memblk *)blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } snd_emu10k1_memblk_map(hw, blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return (struct snd_util_memblk *)blk; } @@ -398,14 +396,14 @@ snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *memblk) struct snd_emu10k1_memblk *blk = (struct snd_emu10k1_memblk *)memblk; unsigned long flags; - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); spin_lock_irqsave(&emu->memblk_lock, flags); if (blk->mapped_page >= 0) unmap_memblk(emu, blk); spin_unlock_irqrestore(&emu->memblk_lock, flags); synth_free_pages(emu, blk); __snd_util_mem_free(hdr, memblk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return 0; } diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index ca9e34e88..55aaf1103 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -35,8 +35,6 @@ #include #include #include -#include - #include #include #include @@ -381,7 +379,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force)."); struct ensoniq { spinlock_t reg_lock; - struct mutex src_mutex; + struct semaphore src_mutex; int irq; @@ -446,7 +444,7 @@ struct ensoniq { static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct pci_device_id snd_audiopci_ids[] __devinitdata = { +static struct pci_device_id snd_audiopci_ids[] = { #ifdef CHIP1370 { 0x1274, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1370 */ #endif @@ -611,7 +609,7 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, struct ensoniq *ensoniq = ac97->private_data; unsigned int t, x; - mutex_lock(&ensoniq->src_mutex); + down(&ensoniq->src_mutex); for (t = 0; t < POLL_COUNT; t++) { if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { /* save the current state for latter */ @@ -636,11 +634,11 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, /* restore SRC reg */ snd_es1371_wait_src_ready(ensoniq); outl(x, ES_REG(ensoniq, 1371_SMPRATE)); - mutex_unlock(&ensoniq->src_mutex); + up(&ensoniq->src_mutex); return; } } - mutex_unlock(&ensoniq->src_mutex); + up(&ensoniq->src_mutex); snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); } @@ -652,7 +650,7 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, unsigned int t, x, fail = 0; __again: - mutex_lock(&ensoniq->src_mutex); + down(&ensoniq->src_mutex); for (t = 0; t < POLL_COUNT; t++) { if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { /* save the current state for latter */ @@ -685,11 +683,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, /* now wait for the stinkin' data (RDY) */ for (t = 0; t < POLL_COUNT; t++) { if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { - mutex_unlock(&ensoniq->src_mutex); + up(&ensoniq->src_mutex); return ES_1371_CODEC_READ(x); } } - mutex_unlock(&ensoniq->src_mutex); + up(&ensoniq->src_mutex); if (++fail > 10) { snd_printk(KERN_ERR "codec read timeout (final) " "at 0x%lx, reg = 0x%x [0x%x]\n", @@ -700,7 +698,7 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, goto __again; } } - mutex_unlock(&ensoniq->src_mutex); + up(&ensoniq->src_mutex); snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); return 0; @@ -719,7 +717,7 @@ static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate) { unsigned int n, truncm, freq, result; - mutex_lock(&ensoniq->src_mutex); + down(&ensoniq->src_mutex); n = rate / 3000; if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) n--; @@ -744,14 +742,14 @@ static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate) snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff); snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8); snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8); - mutex_unlock(&ensoniq->src_mutex); + up(&ensoniq->src_mutex); } static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate) { unsigned int freq, r; - mutex_lock(&ensoniq->src_mutex); + down(&ensoniq->src_mutex); freq = ((rate << 15) + 1500) / 3000; r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | @@ -765,14 +763,14 @@ static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate) r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1)); outl(r, ES_REG(ensoniq, 1371_SMPRATE)); - mutex_unlock(&ensoniq->src_mutex); + up(&ensoniq->src_mutex); } static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate) { unsigned int freq, r; - mutex_lock(&ensoniq->src_mutex); + down(&ensoniq->src_mutex); freq = ((rate << 15) + 1500) / 3000; r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | @@ -787,7 +785,7 @@ static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate) r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1)); outl(r, ES_REG(ensoniq, 1371_SMPRATE)); - mutex_unlock(&ensoniq->src_mutex); + up(&ensoniq->src_mutex); } #endif /* CHIP1371 */ @@ -2063,13 +2061,6 @@ static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state) #ifdef CHIP1371 snd_ac97_suspend(ensoniq->u.es1371.ac97); #else - /* try to reset AK4531 */ - outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC)); - inw(ES_REG(ensoniq, 1370_CODEC)); - udelay(100); - outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x03), ES_REG(ensoniq, 1370_CODEC)); - inw(ES_REG(ensoniq, 1370_CODEC)); - udelay(100); snd_ak4531_suspend(ensoniq->u.es1370.ak4531); #endif pci_set_power_state(pci, PCI_D3hot); @@ -2125,7 +2116,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card, return -ENOMEM; } spin_lock_init(&ensoniq->reg_lock); - mutex_init(&ensoniq->src_mutex); + init_MUTEX(&ensoniq->src_mutex); ensoniq->card = card; ensoniq->pci = pci; ensoniq->irq = -1; diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 6f9094ca4..0d556b09a 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include @@ -242,7 +241,7 @@ struct es1938 { static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct pci_device_id snd_es1938_ids[] __devinitdata = { +static struct pci_device_id snd_es1938_ids[] = { { 0x125d, 0x1969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Solo-1 */ { 0, } }; @@ -1518,8 +1517,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, 0x00ffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x00ffffff) < 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 5ff4175c7..3747a436f 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -100,12 +100,9 @@ #include #include #include -#include #include #include #include -#include - #include #include #include @@ -572,7 +569,7 @@ struct es1968 { u16 maestro_map[32]; int bobclient; /* active timer instancs */ int bob_freq; /* timer frequency */ - struct mutex memory_mutex; /* memory lock */ + struct semaphore memory_mutex; /* memory lock */ /* APU states */ unsigned char apu[NR_APUS]; @@ -592,7 +589,7 @@ struct es1968 { static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct pci_device_id snd_es1968_ids[] __devinitdata = { +static struct pci_device_id snd_es1968_ids[] = { /* Maestro 1 */ { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO }, /* Maestro 2 */ @@ -1359,13 +1356,13 @@ static int calc_available_memory_size(struct es1968 *chip) struct list_head *p; int max_size = 0; - mutex_lock(&chip->memory_mutex); + down(&chip->memory_mutex); list_for_each(p, &chip->buf_list) { struct esm_memory *buf = list_entry(p, struct esm_memory, list); if (buf->empty && buf->buf.bytes > max_size) max_size = buf->buf.bytes; } - mutex_unlock(&chip->memory_mutex); + up(&chip->memory_mutex); if (max_size >= 128*1024) max_size = 127*1024; return max_size; @@ -1378,20 +1375,20 @@ static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size) struct list_head *p; size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN; - mutex_lock(&chip->memory_mutex); + down(&chip->memory_mutex); list_for_each(p, &chip->buf_list) { buf = list_entry(p, struct esm_memory, list); if (buf->empty && buf->buf.bytes >= size) goto __found; } - mutex_unlock(&chip->memory_mutex); + up(&chip->memory_mutex); return NULL; __found: if (buf->buf.bytes > size) { struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); if (chunk == NULL) { - mutex_unlock(&chip->memory_mutex); + up(&chip->memory_mutex); return NULL; } chunk->buf = buf->buf; @@ -1403,7 +1400,7 @@ __found: list_add(&chunk->list, &buf->list); } buf->empty = 0; - mutex_unlock(&chip->memory_mutex); + up(&chip->memory_mutex); return buf; } @@ -1412,7 +1409,7 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf) { struct esm_memory *chunk; - mutex_lock(&chip->memory_mutex); + down(&chip->memory_mutex); buf->empty = 1; if (buf->list.prev != &chip->buf_list) { chunk = list_entry(buf->list.prev, struct esm_memory, list); @@ -1431,7 +1428,7 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf) kfree(chunk); } } - mutex_unlock(&chip->memory_mutex); + up(&chip->memory_mutex); } static void snd_es1968_free_dmabuf(struct es1968 *chip) @@ -2562,8 +2559,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, 0x0fffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; @@ -2582,7 +2579,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, INIT_LIST_HEAD(&chip->buf_list); INIT_LIST_HEAD(&chip->substream_list); spin_lock_init(&chip->ac97_lock); - mutex_init(&chip->memory_mutex); + init_MUTEX(&chip->memory_mutex); tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip); chip->card = card; chip->pci = pci; diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 09a2885ca..712ba72c7 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -199,7 +199,7 @@ struct fm801 { #endif }; -static struct pci_device_id snd_fm801_ids[] __devinitdata = { +static struct pci_device_id snd_fm801_ids[] = { { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */ { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */ { 0, } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 5bee3b536..4a6dd97de 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include @@ -77,12 +76,12 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire unsigned int verb, unsigned int parm) { unsigned int res; - mutex_lock(&codec->bus->cmd_mutex); + down(&codec->bus->cmd_mutex); if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) res = codec->bus->ops.get_response(codec); else res = (unsigned int)-1; - mutex_unlock(&codec->bus->cmd_mutex); + up(&codec->bus->cmd_mutex); return res; } @@ -102,9 +101,9 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm) { int err; - mutex_lock(&codec->bus->cmd_mutex); + down(&codec->bus->cmd_mutex); err = codec->bus->ops.command(codec, nid, direct, verb, parm); - mutex_unlock(&codec->bus->cmd_mutex); + up(&codec->bus->cmd_mutex); return err; } @@ -295,7 +294,7 @@ static int init_unsol_queue(struct hda_bus *bus) snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); return -ENOMEM; } - unsol->workq = create_singlethread_workqueue("hda_codec"); + unsol->workq = create_workqueue("hda_codec"); if (! unsol->workq) { snd_printk(KERN_ERR "hda_codec: can't create workqueue\n"); kfree(unsol); @@ -372,7 +371,7 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, bus->modelname = temp->modelname; bus->ops = temp->ops; - mutex_init(&bus->cmd_mutex); + init_MUTEX(&bus->cmd_mutex); INIT_LIST_HEAD(&bus->codec_list); if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { @@ -524,19 +523,13 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, codec->bus = bus; codec->addr = codec_addr; - mutex_init(&codec->spdif_mutex); + init_MUTEX(&codec->spdif_mutex); init_amp_hash(codec); list_add_tail(&codec->list, &bus->codec_list); bus->caddr_tbl[codec_addr] = codec; codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); - if (codec->vendor_id == -1) - /* read again, hopefully the access method was corrected - * in the last read... - */ - codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, - AC_PAR_VENDOR_ID); codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); @@ -729,8 +722,7 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, /* * read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit. */ -int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, - int direction, int index) +static int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index) { struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); if (! info) @@ -741,8 +733,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, /* * update the AMP value, mask = bit mask to set, val = the value */ -int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, - int direction, int idx, int mask, int val) +static int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val) { struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); @@ -890,12 +881,12 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ unsigned long pval; int err; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + down(&codec->spdif_mutex); /* reuse spdif_mutex */ pval = kcontrol->private_value; kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); kcontrol->private_value = pval; - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return err; } @@ -905,7 +896,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ unsigned long pval; int i, indices, err = 0, change = 0; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + down(&codec->spdif_mutex); /* reuse spdif_mutex */ pval = kcontrol->private_value; indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; for (i = 0; i < indices; i++) { @@ -916,7 +907,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ change |= err; } kcontrol->private_value = pval; - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return err < 0 ? err : change; } @@ -1020,7 +1011,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c unsigned short val; int change; - mutex_lock(&codec->spdif_mutex); + down(&codec->spdif_mutex); codec->spdif_status = ucontrol->value.iec958.status[0] | ((unsigned int)ucontrol->value.iec958.status[1] << 8) | ((unsigned int)ucontrol->value.iec958.status[2] << 16) | @@ -1035,7 +1026,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); } - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return change; } @@ -1063,7 +1054,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn unsigned short val; int change; - mutex_lock(&codec->spdif_mutex); + down(&codec->spdif_mutex); val = codec->spdif_ctls & ~1; if (ucontrol->value.integer.value[0]) val |= 1; @@ -1075,7 +1066,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); } - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return change; } @@ -1159,13 +1150,13 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd unsigned int val = !!ucontrol->value.integer.value[0]; int change; - mutex_lock(&codec->spdif_mutex); + down(&codec->spdif_mutex); change = codec->spdif_in_enable != val; if (change || codec->in_resume) { codec->spdif_in_enable = val; snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); } - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return change; } @@ -1833,13 +1824,13 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i */ int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) { - mutex_lock(&codec->spdif_mutex); + down(&codec->spdif_mutex); if (mout->dig_out_used) { - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return -EBUSY; /* already being used */ } mout->dig_out_used = HDA_DIG_EXCLUSIVE; - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return 0; } @@ -1848,9 +1839,9 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mo */ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) { - mutex_lock(&codec->spdif_mutex); + down(&codec->spdif_mutex); mout->dig_out_used = 0; - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return 0; } @@ -1878,7 +1869,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o int chs = substream->runtime->channels; int i; - mutex_lock(&codec->spdif_mutex); + down(&codec->spdif_mutex); if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { if (chs == 2 && snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && @@ -1892,20 +1883,13 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); } } - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); /* front */ snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); if (mout->hp_nid) /* headphone out will just decode front left/right (stereo) */ snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); - /* extra outputs copied from front */ - for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) - if (mout->extra_out_nid[i]) - snd_hda_codec_setup_stream(codec, - mout->extra_out_nid[i], - stream_tag, 0, format); - /* surrounds */ for (i = 1; i < mout->num_dacs; i++) { if (chs >= (i + 1) * 2) /* independent out */ @@ -1930,17 +1914,12 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); if (mout->hp_nid) snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0); - for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) - if (mout->extra_out_nid[i]) - snd_hda_codec_setup_stream(codec, - mout->extra_out_nid[i], - 0, 0, 0); - mutex_lock(&codec->spdif_mutex); + down(&codec->spdif_mutex); if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) { snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); mout->dig_out_used = 0; } - mutex_unlock(&codec->spdif_mutex); + up(&codec->spdif_mutex); return 0; } @@ -1956,29 +1935,13 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) return 0; } -/* - * Parse all pin widgets and store the useful pin nids to cfg - * - * The number of line-outs or any primary output is stored in line_outs, - * and the corresponding output pins are assigned to line_out_pins[], - * in the order of front, rear, CLFE, side, ... - * - * If more extra outputs (speaker and headphone) are found, the pins are - * assisnged to hp_pin and speaker_pins[], respectively. If no line-out jack - * is detected, one of speaker of HP pins is assigned as the primary - * output, i.e. to line_out_pins[0]. So, line_outs is always positive - * if any analog output exists. - * - * The analog input pins are assigned to input_pins array. - * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, - * respectively. - */ +/* parse all pin widgets and store the useful pin nids to cfg */ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, hda_nid_t *ignore_nids) { hda_nid_t nid, nid_start; int i, j, nodes; - short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)]; + short seq, sequences[4], assoc_line_out; memset(cfg, 0, sizeof(*cfg)); @@ -2020,10 +1983,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c cfg->line_outs++; break; case AC_JACK_SPEAKER: - if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) - continue; - cfg->speaker_pins[cfg->speaker_outs] = nid; - cfg->speaker_outs++; + cfg->speaker_pin = nid; break; case AC_JACK_HP_OUT: cfg->hp_pin = nid; @@ -2088,46 +2048,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c break; } - /* - * debug prints of the parsed results - */ - snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", - cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], - cfg->line_out_pins[2], cfg->line_out_pins[3], - cfg->line_out_pins[4]); - snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", - cfg->speaker_outs, cfg->speaker_pins[0], - cfg->speaker_pins[1], cfg->speaker_pins[2], - cfg->speaker_pins[3], cfg->speaker_pins[4]); - snd_printd(" hp=0x%x, dig_out=0x%x, din_in=0x%x\n", - cfg->hp_pin, cfg->dig_out_pin, cfg->dig_in_pin); - snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," - " cd=0x%x, aux=0x%x\n", - cfg->input_pins[AUTO_PIN_MIC], - cfg->input_pins[AUTO_PIN_FRONT_MIC], - cfg->input_pins[AUTO_PIN_LINE], - cfg->input_pins[AUTO_PIN_FRONT_LINE], - cfg->input_pins[AUTO_PIN_CD], - cfg->input_pins[AUTO_PIN_AUX]); - - /* - * FIX-UP: if no line-outs are detected, try to use speaker or HP pin - * as a primary output - */ - if (! cfg->line_outs) { - if (cfg->speaker_outs) { - cfg->line_outs = cfg->speaker_outs; - memcpy(cfg->line_out_pins, cfg->speaker_pins, - sizeof(cfg->speaker_pins)); - cfg->speaker_outs = 0; - memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); - } else if (cfg->hp_pin) { - cfg->line_outs = 1; - cfg->line_out_pins[0] = cfg->hp_pin; - cfg->hp_pin = 0; - } - } - return 0; } diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c9e9dc9c7..63e26c7a2 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -75,7 +75,12 @@ enum { #define AC_VERB_GET_DIGI_CONVERT 0x0f0d #define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f /* f10-f1a: GPIO */ +#define AC_VERB_GET_GPIO_DATA 0x0f15 +#define AC_VERB_GET_GPIO_MASK 0x0f16 +#define AC_VERB_GET_GPIO_DIRECTION 0x0f17 #define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c +/* f20: AFG/MFG */ +#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20 /* * SET verbs @@ -93,10 +98,13 @@ enum { #define AC_VERB_SET_UNSOLICITED_ENABLE 0x708 #define AC_VERB_SET_PIN_SENSE 0x709 #define AC_VERB_SET_BEEP_CONTROL 0x70a -#define AC_VERB_SET_EAPD_BTLENALBE 0x70c +#define AC_VERB_SET_EAPD_BTLENABLE 0x70c #define AC_VERB_SET_DIGI_CONVERT_1 0x70d #define AC_VERB_SET_DIGI_CONVERT_2 0x70e #define AC_VERB_SET_VOLUME_KNOB_CONTROL 0x70f +#define AC_VERB_SET_GPIO_DATA 0x715 +#define AC_VERB_SET_GPIO_MASK 0x716 +#define AC_VERB_SET_GPIO_DIRECTION 0x717 #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e @@ -176,16 +184,15 @@ enum { #define AC_PINCAP_OUT (1<<4) /* output capable */ #define AC_PINCAP_IN (1<<5) /* input capable */ #define AC_PINCAP_BALANCE (1<<6) /* balanced I/O capable */ -#define AC_PINCAP_VREF (7<<8) +#define AC_PINCAP_VREF (0x37<<8) #define AC_PINCAP_VREF_SHIFT 8 #define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ -/* Vref status (used in pin cap and pin ctl) */ -#define AC_PIN_VREF_HIZ (1<<0) /* Hi-Z */ -#define AC_PIN_VREF_50 (1<<1) /* 50% */ -#define AC_PIN_VREF_GRD (1<<2) /* ground */ -#define AC_PIN_VREF_80 (1<<4) /* 80% */ -#define AC_PIN_VREF_100 (1<<5) /* 100% */ - +/* Vref status (used in pin cap) */ +#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */ +#define AC_PINCAP_VREF_50 (1<<1) /* 50% */ +#define AC_PINCAP_VREF_GRD (1<<2) /* ground */ +#define AC_PINCAP_VREF_80 (1<<4) /* 80% */ +#define AC_PINCAP_VREF_100 (1<<5) /* 100% */ /* Amplifier capabilities */ #define AC_AMPCAP_OFFSET (0x7f<<0) /* 0dB offset */ @@ -207,6 +214,12 @@ enum { #define AC_PWRST_D2SUP (1<<2) #define AC_PWRST_D3SUP (1<<3) +/* Power state values */ +#define AC_PWRST_D0 0x00 +#define AC_PWRST_D1 0x01 +#define AC_PWRST_D2 0x02 +#define AC_PWRST_D3 0x03 + /* Processing capabilies */ #define AC_PCAP_BENIGN (1<<0) #define AC_PCAP_NUM_COEF (0xff<<8) @@ -248,14 +261,24 @@ enum { /* Pin widget control - 8bit */ #define AC_PINCTL_VREFEN (0x7<<0) +#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ +#define AC_PINCTL_VREF_50 1 /* 50% */ +#define AC_PINCTL_VREF_GRD 2 /* ground */ +#define AC_PINCTL_VREF_80 4 /* 80% */ +#define AC_PINCTL_VREF_100 5 /* 100% */ #define AC_PINCTL_IN_EN (1<<5) #define AC_PINCTL_OUT_EN (1<<6) #define AC_PINCTL_HP_EN (1<<7) +/* Unsolicited response - 8bit */ +#define AC_USRSP_EN (1<<7) + /* configuration default - 32bit */ #define AC_DEFCFG_SEQUENCE (0xf<<0) #define AC_DEFCFG_DEF_ASSOC (0xf<<4) +#define AC_DEFCFG_ASSOC_SHIFT 4 #define AC_DEFCFG_MISC (0xf<<8) +#define AC_DEFCFG_MISC_SHIFT 8 #define AC_DEFCFG_COLOR (0xf<<12) #define AC_DEFCFG_COLOR_SHIFT 12 #define AC_DEFCFG_CONN_TYPE (0xf<<16) @@ -359,7 +382,7 @@ enum { }; /* max. connections to a widget */ -#define HDA_MAX_CONNECTIONS 16 +#define HDA_MAX_CONNECTIONS 32 /* max. codec address */ #define HDA_MAX_CODEC_ADDRESS 0x0f @@ -403,7 +426,7 @@ struct hda_bus_template { * A hda_bus contains several codecs in the list codec_list. */ struct hda_bus { - snd_card_t *card; + struct snd_card *card; /* copied from template */ void *private_data; @@ -413,14 +436,14 @@ struct hda_bus { /* codec linked list */ struct list_head codec_list; - struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS]; /* caddr -> codec */ + struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */ struct semaphore cmd_mutex; /* unsolicited event queue */ struct hda_bus_unsolicited *unsol; - snd_info_entry_t *proc; + struct snd_info_entry *proc; }; /* @@ -464,14 +487,14 @@ struct hda_amp_info { /* PCM callbacks */ struct hda_pcm_ops { int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec, - snd_pcm_substream_t *substream); + struct snd_pcm_substream *substream); int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec, - snd_pcm_substream_t *substream); + struct snd_pcm_substream *substream); int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec, unsigned int stream_tag, unsigned int format, - snd_pcm_substream_t *substream); + struct snd_pcm_substream *substream); int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, - snd_pcm_substream_t *substream); + struct snd_pcm_substream *substream); }; /* PCM information for each substream */ @@ -490,6 +513,7 @@ struct hda_pcm_stream { struct hda_pcm { char *name; struct hda_pcm_stream stream[2]; + unsigned int is_modem; /* modem codec? */ }; /* codec information */ @@ -499,6 +523,7 @@ struct hda_codec { struct list_head list; /* list point */ hda_nid_t afg; /* AFG node id */ + hda_nid_t mfg; /* MFG node id */ /* ids */ u32 vendor_id; @@ -523,10 +548,16 @@ struct hda_codec { /* codec specific info */ void *spec; + /* widget capabilities cache */ + unsigned int num_nodes; + hda_nid_t start_nid; + u32 *wcaps; + /* hash for amp access */ u16 amp_hash[32]; int num_amp_entries; - struct hda_amp_info amp_info[128]; /* big enough? */ + int amp_info_size; + struct hda_amp_info *amp_info; struct semaphore spdif_mutex; unsigned int spdif_status; /* IEC958 status bits */ @@ -543,7 +574,7 @@ enum { /* * constructors */ -int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp, +int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, struct hda_bus **busp); int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, struct hda_codec **codecp); diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 69f7b6c4c..39edfcfd3 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -32,7 +32,8 @@ struct hda_gnode { hda_nid_t nid; /* NID of this widget */ unsigned short nconns; /* number of input connections */ - hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; /* input connections */ + hda_nid_t *conn_list; + hda_nid_t slist[2]; /* temporay list */ unsigned int wid_caps; /* widget capabilities */ unsigned char type; /* widget type */ unsigned char pin_ctl; /* pin controls */ @@ -44,7 +45,7 @@ struct hda_gnode { struct list_head list; }; -/* pathc-specific record */ +/* patch-specific record */ struct hda_gspec { struct hda_gnode *dac_node; /* DAC node */ struct hda_gnode *out_pin_node; /* Output pin (Line-Out) node */ @@ -68,8 +69,8 @@ struct hda_gspec { /* * retrieve the default device type from the default config value */ -#define get_defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) -#define get_defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) +#define defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) +#define defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) /* * destructor @@ -84,6 +85,8 @@ static void snd_hda_generic_free(struct hda_codec *codec) /* free all widgets */ list_for_each_safe(p, n, &spec->nid_list) { struct hda_gnode *node = list_entry(p, struct hda_gnode, list); + if (node->conn_list != node->slist) + kfree(node->conn_list); kfree(node); } kfree(spec); @@ -97,18 +100,32 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid { struct hda_gnode *node; int nconns; + hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; - node = kcalloc(1, sizeof(*node), GFP_KERNEL); + node = kzalloc(sizeof(*node), GFP_KERNEL); if (node == NULL) return -ENOMEM; node->nid = nid; - nconns = snd_hda_get_connections(codec, nid, node->conn_list, HDA_MAX_CONNECTIONS); + nconns = snd_hda_get_connections(codec, nid, conn_list, + HDA_MAX_CONNECTIONS); if (nconns < 0) { kfree(node); return nconns; } + if (nconns <= ARRAY_SIZE(node->slist)) + node->conn_list = node->slist; + else { + node->conn_list = kmalloc(sizeof(hda_nid_t) * nconns, + GFP_KERNEL); + if (! node->conn_list) { + snd_printk(KERN_ERR "hda-generic: cannot malloc\n"); + kfree(node); + return -ENOMEM; + } + } + memcpy(node->conn_list, conn_list, nconns); node->nconns = nconns; - node->wid_caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); + node->wid_caps = get_wcaps(codec, nid); node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (node->type == AC_WID_PIN) { @@ -323,7 +340,7 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec, if (! (node->pin_caps & AC_PINCAP_OUT)) continue; if (jack_type >= 0) { - if (jack_type != get_defcfg_type(node)) + if (jack_type != defcfg_type(node)) continue; if (node->wid_caps & AC_WCAP_DIGITAL) continue; /* skip SPDIF */ @@ -389,14 +406,14 @@ static int parse_output(struct hda_codec *codec) */ /* control callbacks */ -static int capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) +static int capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_gspec *spec = codec->spec; return snd_hda_input_mux_info(&spec->input_mux, uinfo); } -static int capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +static int capture_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_gspec *spec = codec->spec; @@ -405,7 +422,7 @@ static int capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uc return 0; } -static int capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +static int capture_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_gspec *spec = codec->spec; @@ -418,15 +435,15 @@ static int capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uc */ static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl) { - unsigned int location = get_defcfg_location(node); - switch (get_defcfg_type(node)) { + unsigned int location = defcfg_location(node); + switch (defcfg_type(node)) { case AC_JACK_LINE_IN: if ((location & 0x0f) == AC_JACK_LOC_FRONT) return "Front Line"; return "Line"; case AC_JACK_CD: if (pinctl) - *pinctl |= AC_PIN_VREF_GRD; + *pinctl |= AC_PINCTL_VREF_GRD; return "CD"; case AC_JACK_AUX: if ((location & 0x0f) == AC_JACK_LOC_FRONT) @@ -617,7 +634,7 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node, char name[32]; int err; int created = 0; - snd_kcontrol_new_t knew; + struct snd_kcontrol_new knew; if (type) sprintf(name, "%s %s Switch", type, dir_sfx); @@ -625,14 +642,14 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node, sprintf(name, "%s Switch", dir_sfx); if ((node->wid_caps & AC_WCAP_IN_AMP) && (node->amp_in_caps & AC_AMPCAP_MUTE)) { - knew = (snd_kcontrol_new_t)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT); + knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT); snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) return err; created = 1; } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && (node->amp_out_caps & AC_AMPCAP_MUTE)) { - knew = (snd_kcontrol_new_t)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT); + knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT); snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) return err; @@ -645,14 +662,14 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node, sprintf(name, "%s Volume", dir_sfx); if ((node->wid_caps & AC_WCAP_IN_AMP) && (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) { - knew = (snd_kcontrol_new_t)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT); + knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT); snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) return err; created = 1; } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) { - knew = (snd_kcontrol_new_t)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT); + knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT); snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) return err; @@ -667,7 +684,7 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node, */ static int check_existing_control(struct hda_codec *codec, const char *type, const char *dir) { - snd_ctl_elem_id_t id; + struct snd_ctl_elem_id id; memset(&id, 0, sizeof(id)); sprintf(id.name, "%s %s Volume", type, dir); id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; @@ -710,7 +727,7 @@ static int build_input_controls(struct hda_codec *codec) /* create input MUX if multiple sources are available */ if (spec->input_mux.num_items > 1) { - static snd_kcontrol_new_t cap_sel = { + static struct snd_kcontrol_new cap_sel = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .info = capture_source_info, @@ -881,7 +898,10 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec) struct hda_gspec *spec; int err; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + if(!codec->afg) + return 0; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) { printk(KERN_ERR "hda_generic: can't allocate spec\n"); return -ENOMEM; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9dd541df6..0ff38cbe7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include "hda_codec.h" @@ -54,7 +53,6 @@ static char *id = SNDRV_DEFAULT_STR1; static char *model; static int position_fix; static int probe_mask = -1; -static int single_cmd; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); @@ -66,8 +64,6 @@ module_param(position_fix, int, 0444); MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); module_param(probe_mask, int, 0444); MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); -module_param(single_cmd, bool, 0444); -MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); /* just for backward compatibility */ @@ -81,7 +77,6 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{Intel, ESB2}," "{Intel, ICH8}," "{ATI, SB450}," - "{ATI, SB600}," "{VIA, VT8251}," "{VIA, VT8237A}," "{SiS, SIS966}," @@ -239,6 +234,12 @@ enum { #define NVIDIA_HDA_TRANSREG_ADDR 0x4e #define NVIDIA_HDA_ENABLE_COHBITS 0x0f +/* + * Use CORB/RIRB for communication from/to codecs. + * This is the way recommended by Intel (see below). + */ +#define USE_CORB_RIRB + /* */ @@ -251,6 +252,7 @@ struct azx_dev { unsigned int fragsize; /* size of each period in bytes */ unsigned int frags; /* number for period in the play buffer */ unsigned int fifo_size; /* FIFO size */ + unsigned int last_pos; /* last updated period position */ void __iomem *sd_addr; /* stream descriptor pointer */ @@ -261,11 +263,10 @@ struct azx_dev { unsigned int format_val; /* format value to be set in the controller and the codec */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ - /* for sanity check of position buffer */ - unsigned int period_intr; unsigned int opened: 1; unsigned int running: 1; + unsigned int period_updating: 1; }; /* CORB/RIRB */ @@ -299,7 +300,7 @@ struct azx { /* locks */ spinlock_t reg_lock; - struct mutex open_mutex; + struct semaphore open_mutex; /* streams (x num_streams) */ struct azx_dev *azx_dev; @@ -324,7 +325,6 @@ struct azx { /* flags */ int position_fix; unsigned int initialized: 1; - unsigned int single_cmd: 1; }; /* driver types */ @@ -388,6 +388,7 @@ static char *driver_short_names[] __devinitdata = { * Interface for HD codec */ +#ifdef USE_CORB_RIRB /* * CORB / RIRB interface */ @@ -435,7 +436,11 @@ static void azx_init_cmd_io(struct azx *chip) /* set N=1, get RIRB response interrupt for new entry */ azx_writew(chip, RINTCNT, 1); /* enable rirb dma and response irq */ +#ifdef USE_CORB_RIRB azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); +#else + azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN); +#endif chip->rirb.rp = chip->rirb.cmds = 0; } @@ -447,8 +452,8 @@ static void azx_free_cmd_io(struct azx *chip) } /* send a command */ -static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, - unsigned int verb, unsigned int para) +static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, + unsigned int verb, unsigned int para) { struct azx *chip = codec->bus->private_data; unsigned int wp; @@ -504,21 +509,18 @@ static void azx_update_rirb(struct azx *chip) } /* receive a response */ -static unsigned int azx_rirb_get_response(struct hda_codec *codec) +static unsigned int azx_get_response(struct hda_codec *codec) { struct azx *chip = codec->bus->private_data; int timeout = 50; while (chip->rirb.cmds) { if (! --timeout) { - snd_printk(KERN_ERR - "hda_intel: azx_get_response timeout, " - "switching to single_cmd mode...\n"); + if (printk_ratelimit()) + snd_printk(KERN_ERR + "azx_get_response timeout\n"); chip->rirb.rp = azx_readb(chip, RIRBWP); chip->rirb.cmds = 0; - /* switch to single_cmd mode */ - chip->single_cmd = 1; - azx_free_cmd_io(chip); return -1; } msleep(1); @@ -526,6 +528,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) return chip->rirb.res; /* the last value */ } +#else /* * Use the single immediate command instead of CORB/RIRB for simplicity * @@ -536,10 +539,13 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) * I left the codes, however, for debugging/testing purposes. */ +#define azx_alloc_cmd_io(chip) 0 +#define azx_init_cmd_io(chip) +#define azx_free_cmd_io(chip) + /* send a command */ -static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, - int direct, unsigned int verb, - unsigned int para) +static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, + unsigned int verb, unsigned int para) { struct azx *chip = codec->bus->private_data; u32 val; @@ -567,7 +573,7 @@ static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, } /* receive a response */ -static unsigned int azx_single_get_response(struct hda_codec *codec) +static unsigned int azx_get_response(struct hda_codec *codec) { struct azx *chip = codec->bus->private_data; int timeout = 50; @@ -582,35 +588,9 @@ static unsigned int azx_single_get_response(struct hda_codec *codec) return (unsigned int)-1; } -/* - * The below are the main callbacks from hda_codec. - * - * They are just the skeleton to call sub-callbacks according to the - * current setting of chip->single_cmd. - */ - -/* send a command */ -static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, - int direct, unsigned int verb, - unsigned int para) -{ - struct azx *chip = codec->bus->private_data; - if (chip->single_cmd) - return azx_single_send_cmd(codec, nid, direct, verb, para); - else - return azx_corb_send_cmd(codec, nid, direct, verb, para); -} - -/* get a response */ -static unsigned int azx_get_response(struct hda_codec *codec) -{ - struct azx *chip = codec->bus->private_data; - if (chip->single_cmd) - return azx_single_get_response(codec); - else - return azx_rirb_get_response(codec); -} +#define azx_update_rirb(chip) +#endif /* USE_CORB_RIRB */ /* reset codec link */ static int azx_reset(struct azx *chip) @@ -757,8 +737,7 @@ static void azx_init_chip(struct azx *chip) azx_int_enable(chip); /* initialize the codec command I/O */ - if (! chip->single_cmd) - azx_init_cmd_io(chip); + azx_init_cmd_io(chip); /* program the position buffer */ azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); @@ -805,10 +784,11 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) if (status & azx_dev->sd_int_sta_mask) { azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); if (azx_dev->substream && azx_dev->running) { - azx_dev->period_intr++; + azx_dev->period_updating = 1; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(azx_dev->substream); spin_lock(&chip->reg_lock); + azx_dev->period_updating = 0; } } } @@ -816,7 +796,7 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) /* clear rirb int */ status = azx_readb(chip, RIRBSTS); if (status & RIRB_INT_MASK) { - if (! chip->single_cmd && (status & RIRB_INT_RESPONSE)) + if (status & RIRB_INT_RESPONSE) azx_update_rirb(chip); azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); } @@ -1022,10 +1002,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) unsigned long flags; int err; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); azx_dev = azx_assign_device(chip, substream->stream); if (azx_dev == NULL) { - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return -EBUSY; } runtime->hw = azx_pcm_hw; @@ -1037,7 +1017,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { azx_release_device(azx_dev); - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return err; } spin_lock_irqsave(&chip->reg_lock, flags); @@ -1046,7 +1026,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) spin_unlock_irqrestore(&chip->reg_lock, flags); runtime->private_data = azx_dev; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return 0; } @@ -1058,14 +1038,14 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) struct azx_dev *azx_dev = get_azx_dev(substream); unsigned long flags; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); spin_lock_irqsave(&chip->reg_lock, flags); azx_dev->substream = NULL; azx_dev->running = 0; spin_unlock_irqrestore(&chip->reg_lock, flags); azx_release_device(azx_dev); hinfo->ops.close(hinfo, apcm->codec, substream); - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return 0; } @@ -1119,6 +1099,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; else azx_dev->fifo_size = 0; + azx_dev->last_pos = 0; return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, azx_dev->format_val, substream); @@ -1166,20 +1147,10 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) struct azx_dev *azx_dev = get_azx_dev(substream); unsigned int pos; - if (chip->position_fix == POS_FIX_POSBUF || - chip->position_fix == POS_FIX_AUTO) { + if (chip->position_fix == POS_FIX_POSBUF) { /* use the position buffer */ pos = *azx_dev->posbuf; - if (chip->position_fix == POS_FIX_AUTO && - azx_dev->period_intr == 1 && ! pos) { - printk(KERN_WARNING - "hda-intel: Invalid position buffer, " - "using LPIB read method instead.\n"); - chip->position_fix = POS_FIX_NONE; - goto read_lpib; - } } else { - read_lpib: /* read LPIB */ pos = azx_sd_readl(azx_dev, SD_LPIB); if (chip->position_fix == POS_FIX_FIFO) @@ -1444,14 +1415,13 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, } spin_lock_init(&chip->reg_lock); - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->open_mutex); chip->card = card; chip->pci = pci; chip->irq = -1; chip->driver_type = driver_type; - chip->position_fix = position_fix; - chip->single_cmd = single_cmd; + chip->position_fix = position_fix ? position_fix : POS_FIX_POSBUF; #if BITS_PER_LONG != 64 /* Fix up base address on ULI M5461 */ @@ -1522,9 +1492,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, goto errout; } /* allocate CORB/RIRB */ - if (! chip->single_cmd) - if ((err = azx_alloc_cmd_io(chip)) < 0) - goto errout; + if ((err = azx_alloc_cmd_io(chip)) < 0) + goto errout; /* initialize streams */ azx_init_stream(chip); @@ -1614,13 +1583,12 @@ static void __devexit azx_remove(struct pci_dev *pci) } /* PCI IDs */ -static struct pci_device_id azx_ids[] __devinitdata = { +static struct pci_device_id azx_ids[] = { { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH6 */ { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH7 */ { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */ { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */ { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ - { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 7c7b84987..c82d2a72d 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -27,37 +27,59 @@ * for mixer controls */ #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) +/* mono volume with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ .info = snd_hda_mixer_amp_volume_info, \ .get = snd_hda_mixer_amp_volume_get, \ .put = snd_hda_mixer_amp_volume_put, \ .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } +/* stereo volume with index */ #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) +/* mono volume */ #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction) +/* stereo volume */ #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) +/* mono mute switch with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ .info = snd_hda_mixer_amp_switch_info, \ .get = snd_hda_mixer_amp_switch_get, \ .put = snd_hda_mixer_amp_switch_put, \ .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } +/* stereo mute switch with index */ #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \ HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) +/* mono mute switch */ #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \ HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction) +/* stereo mute switch */ #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) -int snd_hda_mixer_amp_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo); -int snd_hda_mixer_amp_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); -int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); -int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo); -int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); -int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); +int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); +int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); +int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); + +/* mono switch binding multiple inputs */ +#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ + .info = snd_hda_mixer_amp_switch_info, \ + .get = snd_hda_mixer_bind_switch_get, \ + .put = snd_hda_mixer_bind_switch_put, \ + .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } + +/* stereo switch binding multiple inputs */ +#define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) + +int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); @@ -65,7 +87,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); /* * input MUX helper */ -#define HDA_MAX_NUM_INPUTS 8 +#define HDA_MAX_NUM_INPUTS 16 struct hda_input_mux_item { const char *label; unsigned int index; @@ -75,11 +97,28 @@ struct hda_input_mux { struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS]; }; -int snd_hda_input_mux_info(const struct hda_input_mux *imux, snd_ctl_elem_info_t *uinfo); +int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo); int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, - snd_ctl_elem_value_t *ucontrol, hda_nid_t nid, + struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, unsigned int *cur_val); +/* + * Channel mode helper + */ +struct hda_channel_mode { + int channels; + const struct hda_verb *sequence; +}; + +int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, + const struct hda_channel_mode *chmode, int num_chmodes); +int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, int num_chmodes, + int max_channels); +int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, int num_chmodes, + int *max_channelsp); + /* * Multi-channel / digital-out PCM helper */ @@ -99,11 +138,11 @@ struct hda_multi_out { int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, - snd_pcm_substream_t *substream); + struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, - snd_pcm_substream_t *substream); + struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout); /* @@ -126,18 +165,18 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } struct hda_board_config { const char *modelname; int config; - unsigned short pci_vendor; - unsigned short pci_device; + unsigned short pci_subvendor; + unsigned short pci_subdevice; }; -int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl); -int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew); +int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl); +int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); /* * power management */ #ifdef CONFIG_PM -int snd_hda_resume_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew); +int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); int snd_hda_resume_spdif_out(struct hda_codec *codec); int snd_hda_resume_spdif_in(struct hda_codec *codec); #endif @@ -158,4 +197,65 @@ struct hda_bus_unsolicited { struct work_struct work; }; +/* + * Helper for automatic ping configuration + */ + +enum { + AUTO_PIN_MIC, + AUTO_PIN_FRONT_MIC, + AUTO_PIN_LINE, + AUTO_PIN_FRONT_LINE, + AUTO_PIN_CD, + AUTO_PIN_AUX, + AUTO_PIN_LAST +}; + +extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; + +struct auto_pin_cfg { + int line_outs; + hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */ + hda_nid_t speaker_pin; + hda_nid_t hp_pin; + hda_nid_t input_pins[AUTO_PIN_LAST]; + hda_nid_t dig_out_pin; + hda_nid_t dig_in_pin; +}; + +#define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) +#define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) +#define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) +#define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) +#define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) + +int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, + hda_nid_t *ignore_nids); + +/* amp values */ +#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) +#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8)) +#define AMP_OUT_MUTE 0xb080 +#define AMP_OUT_UNMUTE 0xb000 +#define AMP_OUT_ZERO 0xb000 +/* pinctl values */ +#define PIN_IN 0x20 +#define PIN_VREF80 0x24 +#define PIN_VREF50 0x21 +#define PIN_OUT 0x40 +#define PIN_HP 0xc0 +#define PIN_HP_AMP 0x80 + +/* + * get widget capabilities + */ +static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid) +{ + if (nid < codec->start_nid || + nid >= codec->start_nid + codec->num_nodes) + return snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); + return codec->wcaps[nid - codec->start_nid]; +} + + #endif /* __SOUND_HDA_LOCAL_H */ diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index d7343dc82..edb7b1b19 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -23,8 +23,6 @@ #include #include #include -#include - #include #include "hda_codec.h" #include "hda_local.h" @@ -44,7 +42,6 @@ struct ad198x_spec { * dig_out_nid and hp_nid are optional */ unsigned int cur_eapd; - unsigned int need_dac_fix; /* capture */ unsigned int num_adc_nids; @@ -63,7 +60,7 @@ struct ad198x_spec { /* PCM information */ struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ - struct mutex amp_mutex; /* PCM volume/mute control mutex */ + struct semaphore amp_mutex; /* PCM volume/mute control mutex */ unsigned int spdif_route; /* dynamic controls, init_verbs and input_mux */ @@ -311,7 +308,7 @@ static int ad198x_resume(struct hda_codec *codec) struct ad198x_spec *spec = codec->spec; int i; - codec->patch_ops.init(codec); + ad198x_init(codec); for (i = 0; i < spec->num_mixers; i++) snd_hda_resume_ctls(codec, spec->mixers[i]); if (spec->multiout.dig_out_nid) @@ -333,61 +330,6 @@ static struct hda_codec_ops ad198x_patch_ops = { }; -/* - * EAPD control - * the private value = nid | (invert << 8) - */ -static int ad198x_eapd_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int ad198x_eapd_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *spec = codec->spec; - int invert = (kcontrol->private_value >> 8) & 1; - if (invert) - ucontrol->value.integer.value[0] = ! spec->cur_eapd; - else - ucontrol->value.integer.value[0] = spec->cur_eapd; - return 0; -} - -static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *spec = codec->spec; - int invert = (kcontrol->private_value >> 8) & 1; - hda_nid_t nid = kcontrol->private_value & 0xff; - unsigned int eapd; - eapd = ucontrol->value.integer.value[0]; - if (invert) - eapd = !eapd; - if (eapd == spec->cur_eapd && ! codec->in_resume) - return 0; - spec->cur_eapd = eapd; - snd_hda_codec_write(codec, nid, - 0, AC_VERB_SET_EAPD_BTLENABLE, - eapd ? 0x02 : 0x00); - return 1; -} - -static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); - - /* * AD1986A specific */ @@ -402,7 +344,6 @@ static hda_nid_t ad1986a_dac_nids[3] = { AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC }; static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; -static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; static struct hda_input_mux ad1986a_capture_source = { .num_items = 7, @@ -430,9 +371,9 @@ static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct ad198x_spec *ad = codec->spec; - mutex_lock(&ad->amp_mutex); + down(&ad->amp_mutex); snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); - mutex_unlock(&ad->amp_mutex); + up(&ad->amp_mutex); return 0; } @@ -442,13 +383,13 @@ static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl struct ad198x_spec *ad = codec->spec; int i, change = 0; - mutex_lock(&ad->amp_mutex); + down(&ad->amp_mutex); for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); } kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); - mutex_unlock(&ad->amp_mutex); + up(&ad->amp_mutex); return change; } @@ -459,9 +400,9 @@ static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct ad198x_spec *ad = codec->spec; - mutex_lock(&ad->amp_mutex); + down(&ad->amp_mutex); snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); - mutex_unlock(&ad->amp_mutex); + up(&ad->amp_mutex); return 0; } @@ -471,13 +412,13 @@ static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ struct ad198x_spec *ad = codec->spec; int i, change = 0; - mutex_lock(&ad->amp_mutex); + down(&ad->amp_mutex); for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); } kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); - mutex_unlock(&ad->amp_mutex); + up(&ad->amp_mutex); return change; } @@ -536,143 +477,6 @@ static struct snd_kcontrol_new ad1986a_mixers[] = { { } /* end */ }; -/* additional mixers for 3stack mode */ -static struct snd_kcontrol_new ad1986a_3st_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = ad198x_ch_mode_info, - .get = ad198x_ch_mode_get, - .put = ad198x_ch_mode_put, - }, - { } /* end */ -}; - -/* laptop model - 2ch only */ -static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; - -static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { - HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Master Playback Volume", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), */ - HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), - /* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ - HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - { } /* end */ -}; - -/* laptop-eapd model - 2ch only */ - -/* master controls both pins 0x1a and 0x1b */ -static int ad1986a_laptop_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - return change; -} - -static int ad1986a_laptop_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, - 0x80, valp[0] ? 0 : 0x80); - change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, - 0x80, valp[1] ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, valp[0] ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x80, valp[1] ? 0 : 0x80); - return change; -} - -static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { - .num_items = 3, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x4 }, - { "Mix", 0x5 }, - }, -}; - -static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = ad1986a_laptop_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = ad1986a_laptop_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), - }, - HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "External Amplifier", - .info = ad198x_eapd_info, - .get = ad198x_eapd_get, - .put = ad198x_eapd_put, - .private_value = 0x1b | (1 << 8), /* port-D, inversed */ - }, - { } /* end */ -}; - /* * initialization verbs */ @@ -731,97 +535,16 @@ static struct hda_verb ad1986a_init_verbs[] = { { } /* end */ }; -/* additional verbs for 3-stack model */ -static struct hda_verb ad1986a_3st_init_verbs[] = { - /* Mic and line-in selectors */ - {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, - {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, - { } /* end */ -}; - -static struct hda_verb ad1986a_ch2_init[] = { - /* Surround out -> Line In */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* CLFE -> Mic in */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - { } /* end */ -}; - -static struct hda_verb ad1986a_ch4_init[] = { - /* Surround out -> Surround */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - /* CLFE -> Mic in */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - { } /* end */ -}; - -static struct hda_verb ad1986a_ch6_init[] = { - /* Surround out -> Surround out */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - /* CLFE -> CLFE */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - { } /* end */ -}; - -static struct hda_channel_mode ad1986a_modes[3] = { - { 2, ad1986a_ch2_init }, - { 4, ad1986a_ch4_init }, - { 6, ad1986a_ch6_init }, -}; - -/* eapd initialization */ -static struct hda_verb ad1986a_eapd_init_verbs[] = { - {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, - {} -}; - -/* models */ -enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD }; - -static struct hda_board_config ad1986a_cfg_tbl[] = { - { .modelname = "6stack", .config = AD1986A_6STACK }, - { .modelname = "3stack", .config = AD1986A_3STACK }, - { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84, - .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */ - { .modelname = "laptop", .config = AD1986A_LAPTOP }, - { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, - .config = AD1986A_LAPTOP }, /* FSC V2060 */ - { .pci_subvendor = 0x17c0, .pci_subdevice = 0x2017, - .config = AD1986A_LAPTOP }, /* Samsung M50 */ - { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, - .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ - { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, - { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, - .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ - { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153, - .config = AD1986A_LAPTOP_EAPD }, /* ASUS M9 */ - { .pci_subvendor = 0x1043, .pci_subdevice = 0x1213, - .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */ - { .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7, - .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */ - { .pci_subvendor = 0x1043, .pci_subdevice = 0x1297, - .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */ - { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af, - .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */ - {} -}; static int patch_ad1986a(struct hda_codec *codec) { struct ad198x_spec *spec; - int board_config; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); + init_MUTEX(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 6; @@ -830,7 +553,7 @@ static int patch_ad1986a(struct hda_codec *codec) spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; spec->num_adc_nids = 1; spec->adc_nids = ad1986a_adc_nids; - spec->capsrc_nids = ad1986a_capsrc_nids; + spec->capsrc_nids = ad1986a_adc_nids; spec->input_mux = &ad1986a_capture_source; spec->num_mixers = 1; spec->mixers[0] = ad1986a_mixers; @@ -839,39 +562,6 @@ static int patch_ad1986a(struct hda_codec *codec) codec->patch_ops = ad198x_patch_ops; - /* override some parameters */ - board_config = snd_hda_check_board_config(codec, ad1986a_cfg_tbl); - switch (board_config) { - case AD1986A_3STACK: - spec->num_mixers = 2; - spec->mixers[1] = ad1986a_3st_mixers; - spec->num_init_verbs = 3; - spec->init_verbs[1] = ad1986a_3st_init_verbs; - spec->init_verbs[2] = ad1986a_ch2_init; - spec->channel_mode = ad1986a_modes; - spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); - spec->need_dac_fix = 1; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - break; - case AD1986A_LAPTOP: - spec->mixers[0] = ad1986a_laptop_mixers; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; - break; - case AD1986A_LAPTOP_EAPD: - spec->mixers[0] = ad1986a_laptop_eapd_mixers; - spec->num_init_verbs = 2; - spec->init_verbs[1] = ad1986a_eapd_init_verbs; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; - spec->multiout.dig_out_nid = 0; - spec->input_mux = &ad1986a_laptop_eapd_capture_source; - break; - } - return 0; } @@ -885,7 +575,6 @@ static int patch_ad1986a(struct hda_codec *codec) static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; -static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; static struct hda_input_mux ad1983_capture_source = { .num_items = 4, @@ -1019,7 +708,7 @@ static int patch_ad1983(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); + init_MUTEX(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 2; @@ -1028,7 +717,7 @@ static int patch_ad1983(struct hda_codec *codec) spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; spec->num_adc_nids = 1; spec->adc_nids = ad1983_adc_nids; - spec->capsrc_nids = ad1983_capsrc_nids; + spec->capsrc_nids = ad1983_adc_nids; spec->input_mux = &ad1983_capture_source; spec->num_mixers = 1; spec->mixers[0] = ad1983_mixers; @@ -1052,7 +741,6 @@ static int patch_ad1983(struct hda_codec *codec) static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; -static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ static struct hda_input_mux ad1981_capture_source = { @@ -1158,198 +846,15 @@ static struct hda_verb ad1981_init_verbs[] = { { } /* end */ }; -/* - * Patch for HP nx6320 - * - * nx6320 uses EAPD in the reserve way - EAPD-on means the internal - * speaker output enabled _and_ mute-LED off. - */ - -#define AD1981_HP_EVENT 0x37 -#define AD1981_MIC_EVENT 0x38 - -static struct hda_verb ad1981_hp_init_verbs[] = { - {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ - /* pin sensing on HP and Mic jacks */ - {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, - {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, - {} -}; - -/* turn on/off EAPD (+ mute HP) as a master switch */ -static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *spec = codec->spec; - - if (! ad198x_eapd_put(kcontrol, ucontrol)) - return 0; - - /* toggle HP mute appropriately */ - snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, - 0x80, spec->cur_eapd ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, - 0x80, spec->cur_eapd ? 0 : 0x80); - return 1; -} - -/* bind volumes of both NID 0x05 and 0x06 */ -static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - return change; -} - -/* mute internal speaker if HP is plugged */ -static void ad1981_hp_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x06, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); -} - -/* toggle input of built-in and mic jack appropriately */ -static void ad1981_hp_automic(struct hda_codec *codec) -{ - static struct hda_verb mic_jack_on[] = { - {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {} - }; - static struct hda_verb mic_jack_off[] = { - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {} - }; - unsigned int present; - - present = snd_hda_codec_read(codec, 0x08, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - if (present) - snd_hda_sequence_write(codec, mic_jack_on); - else - snd_hda_sequence_write(codec, mic_jack_off); -} - -/* unsolicited event for HP jack sensing */ -static void ad1981_hp_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - res >>= 26; - switch (res) { - case AD1981_HP_EVENT: - ad1981_hp_automute(codec); - break; - case AD1981_MIC_EVENT: - ad1981_hp_automic(codec); - break; - } -} - -static struct hda_input_mux ad1981_hp_capture_source = { - .num_items = 3, - .items = { - { "Mic", 0x0 }, - { "Docking-Station", 0x1 }, - { "Mix", 0x2 }, - }, -}; - -static struct snd_kcontrol_new ad1981_hp_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = ad1981_hp_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = ad198x_eapd_info, - .get = ad198x_eapd_get, - .put = ad1981_hp_master_sw_put, - .private_value = 0x05, - }, - HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), -#if 0 - /* FIXME: analog mic/line loopback doesn't work with my tests... - * (although recording is OK) - */ - HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), - /* FIXME: does this laptop have analog CD connection? */ - HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), -#endif - HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - { } /* end */ -}; - -/* initialize jack-sensing, too */ -static int ad1981_hp_init(struct hda_codec *codec) -{ - ad198x_init(codec); - ad1981_hp_automute(codec); - ad1981_hp_automic(codec); - return 0; -} - -/* models */ -enum { AD1981_BASIC, AD1981_HP }; - -static struct hda_board_config ad1981_cfg_tbl[] = { - { .modelname = "hp", .config = AD1981_HP }, - /* All HP models */ - { .pci_subvendor = 0x103c, .config = AD1981_HP }, - { .modelname = "basic", .config = AD1981_BASIC }, - {} -}; - static int patch_ad1981(struct hda_codec *codec) { struct ad198x_spec *spec; - int board_config; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); + init_MUTEX(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 2; @@ -1358,7 +863,7 @@ static int patch_ad1981(struct hda_codec *codec) spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; spec->num_adc_nids = 1; spec->adc_nids = ad1981_adc_nids; - spec->capsrc_nids = ad1981_capsrc_nids; + spec->capsrc_nids = ad1981_adc_nids; spec->input_mux = &ad1981_capture_source; spec->num_mixers = 1; spec->mixers[0] = ad1981_mixers; @@ -1368,21 +873,6 @@ static int patch_ad1981(struct hda_codec *codec) codec->patch_ops = ad198x_patch_ops; - /* override some parameters */ - board_config = snd_hda_check_board_config(codec, ad1981_cfg_tbl); - switch (board_config) { - case AD1981_HP: - spec->mixers[0] = ad1981_hp_mixers; - spec->num_init_verbs = 2; - spec->init_verbs[1] = ad1981_hp_init_verbs; - spec->multiout.dig_out_nid = 0; - spec->input_mux = &ad1981_hp_capture_source; - - codec->patch_ops.init = ad1981_hp_init; - codec->patch_ops.unsol_event = ad1981_hp_unsol_event; - break; - } - return 0; } @@ -1569,12 +1059,48 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct ad198x_spec *spec = codec->spec; - if (spec->need_dac_fix) - spec->multiout.num_dacs = spec->multiout.max_channels / 2; return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, spec->num_channel_mode, &spec->multiout.max_channels); } +/* + * EAPD control + */ +static int ad1988_eapd_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int ad1988_eapd_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct ad198x_spec *spec = codec->spec; + ucontrol->value.enumerated.item[0] = ! spec->cur_eapd; + return 0; +} + +static int ad1988_eapd_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct ad198x_spec *spec = codec->spec; + unsigned int eapd; + eapd = ! ucontrol->value.enumerated.item[0]; + if (eapd == spec->cur_eapd && ! codec->in_resume) + return 0; + spec->cur_eapd = eapd; + snd_hda_codec_write(codec, 0x12 /* port-D */, + 0, AC_VERB_SET_EAPD_BTLENABLE, + eapd ? 0x02 : 0x00); + return 0; +} + /* 6-stack mode */ static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), @@ -1701,10 +1227,9 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "External Amplifier", - .info = ad198x_eapd_info, - .get = ad198x_eapd_get, - .put = ad198x_eapd_put, - .private_value = 0x12 | (1 << 8), /* port-D, inversed */ + .info = ad1988_eapd_info, + .get = ad1988_eapd_get, + .put = ad1988_eapd_put, }, { } /* end */ @@ -2277,11 +1802,14 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, idx = ad1988_pin_idx(pin); nid = ad1988_idx_to_dac(codec, idx); - /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) + if (! spec->multiout.dac_nids[0]) { + /* use this as the primary output */ + spec->multiout.dac_nids[0] = nid; + if (! spec->multiout.num_dacs) + spec->multiout.num_dacs = 1; + } else + /* specify the DAC as the extra output */ spec->multiout.hp_nid = nid; - else - spec->multiout.extra_out_nid[0] = nid; /* control HP volume/switch on the output mixer amp */ sprintf(name, "%s Playback Volume", pfx); if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, @@ -2400,7 +1928,7 @@ static void ad1988_auto_init_extra_out(struct hda_codec *codec) struct ad198x_spec *spec = codec->spec; hda_nid_t pin; - pin = spec->autocfg.speaker_pins[0]; + pin = spec->autocfg.speaker_pin; if (pin) /* connect to front */ ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); pin = spec->autocfg.hp_pin; @@ -2449,13 +1977,13 @@ static int ad1988_parse_auto_config(struct hda_codec *codec) return err; if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) return err; - if (! spec->autocfg.line_outs) + if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && + ! spec->autocfg.hp_pin) return 0; /* can't find valid BIOS pin config */ if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = ad1988_auto_create_extra_out(codec, - spec->autocfg.speaker_pins[0], + (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin, "Speaker")) < 0 || - (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pin, + (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin, "Headphone")) < 0 || (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) return err; @@ -2511,7 +2039,7 @@ static int patch_ad1988(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); + init_MUTEX(&spec->amp_mutex); codec->spec = spec; if (is_rev2(codec)) @@ -2630,6 +2158,5 @@ struct hda_codec_preset snd_hda_preset_analog[] = { { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, - { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, {} /* terminator */ }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 94cf292d9..bc1932ee6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6,7 +6,6 @@ * Copyright (c) 2004 Kailang Yang * PeiSen Hou * Takashi Iwai - * Jonathan Woithe * * This driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,8 +50,6 @@ enum { ALC880_UNIWILL_DIG, ALC880_CLEVO, ALC880_TCL_S700, - ALC880_LG, - ALC880_LG_LW, #ifdef CONFIG_SND_DEBUG ALC880_TEST, #endif @@ -66,10 +63,6 @@ enum { ALC260_HP, ALC260_HP_3013, ALC260_FUJITSU_S702X, - ALC260_ACER, -#ifdef CONFIG_SND_DEBUG - ALC260_TEST, -#endif ALC260_AUTO, ALC260_MODEL_LAST /* last tag */ }; @@ -77,7 +70,6 @@ enum { /* ALC262 models */ enum { ALC262_BASIC, - ALC262_FUJITSU, ALC262_AUTO, ALC262_MODEL_LAST /* last tag */ }; @@ -132,7 +124,6 @@ struct alc_spec { hda_nid_t dig_in_nid; /* digital-in NID; optional */ /* capture source */ - unsigned int num_mux_defs; const struct hda_input_mux *input_mux; unsigned int cur_mux[3]; @@ -141,7 +132,7 @@ struct alc_spec { int num_channel_mode; /* PCM information */ - struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ + struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; @@ -149,14 +140,6 @@ struct alc_spec { struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_imux; hda_nid_t private_dac_nids[5]; - - /* hooks */ - void (*init_hook)(struct hda_codec *codec); - void (*unsol_event)(struct hda_codec *codec, unsigned int res); - - /* for pin sensing */ - unsigned int sense_updated: 1; - unsigned int jack_present: 1; }; /* @@ -174,10 +157,7 @@ struct alc_config_preset { hda_nid_t dig_in_nid; unsigned int num_channel_mode; const struct hda_channel_mode *channel_mode; - unsigned int num_mux_defs; const struct hda_input_mux *input_mux; - void (*unsol_event)(struct hda_codec *, unsigned int); - void (*init_hook)(struct hda_codec *); }; @@ -188,10 +168,7 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; - unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); - if (mux_idx >= spec->num_mux_defs) - mux_idx = 0; - return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); + return snd_hda_input_mux_info(spec->input_mux, uinfo); } static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -209,8 +186,7 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; - return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, + return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); } @@ -242,241 +218,56 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va spec->num_channel_mode, &spec->multiout.max_channels); } + /* - * Control the mode of pin widget settings via the mixer. "pc" is used - * instead of "%" to avoid consequences of accidently treating the % as - * being part of a format specifier. Maximum allowed length of a value is - * 63 characters plus NULL terminator. - * - * Note: some retasking pin complexes seem to ignore requests for input - * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these - * are requested. Therefore order this list so that this behaviour will not - * cause problems when mixer clients move through the enum sequentially. - * NIDs 0x0f and 0x10 have been observed to have this behaviour as of - * March 2006. - */ -static char *alc_pin_mode_names[] = { - "Mic 50pc bias", "Mic 80pc bias", - "Line in", "Line out", "Headphone out", -}; -static unsigned char alc_pin_mode_values[] = { - PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, -}; -/* The control can present all 5 options, or it can limit the options based - * in the pin being assumed to be exclusively an input or an output pin. In - * addition, "input" pins may or may not process the mic bias option - * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to - * accept requests for bias as of chip versions up to March 2006) and/or - * wiring in the computer. + * Control of pin widget settings via the mixer. Only boolean settings are + * supported, so VrefEn can't be controlled using these functions as they + * stand. */ -#define ALC_PIN_DIR_IN 0x00 -#define ALC_PIN_DIR_OUT 0x01 -#define ALC_PIN_DIR_INOUT 0x02 -#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 -#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 - -/* Info about the pin modes supported by the different pin direction modes. - * For each direction the minimum and maximum values are given. - */ -static signed char alc_pin_mode_dir_info[5][2] = { - { 0, 2 }, /* ALC_PIN_DIR_IN */ - { 3, 4 }, /* ALC_PIN_DIR_OUT */ - { 0, 4 }, /* ALC_PIN_DIR_INOUT */ - { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ - { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ -}; -#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) -#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) -#define alc_pin_mode_n_items(_dir) \ - (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) - -static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int alc_pinctl_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - unsigned int item_num = uinfo->value.enumerated.item; - unsigned char dir = (kcontrol->private_value >> 16) & 0xff; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; - uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); - - if (item_numalc_pin_mode_max(dir)) - item_num = alc_pin_mode_min(dir); - strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; return 0; } -static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int alc_pinctl_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - unsigned int i; struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char dir = (kcontrol->private_value >> 16) & 0xff; + long mask = (kcontrol->private_value >> 16) & 0xff; long *valp = ucontrol->value.integer.value; - unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); - /* Find enumerated value for current pinctl setting */ - i = alc_pin_mode_min(dir); - while (alc_pin_mode_values[i]!=pinctl && i<=alc_pin_mode_max(dir)) - i++; - *valp = i<=alc_pin_mode_max(dir)?i:alc_pin_mode_min(dir); + *valp = 0; + if (snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00) & mask) + *valp = 1; return 0; } -static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int alc_pinctl_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - signed int change; struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char dir = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; + long mask = (kcontrol->private_value >> 16) & 0xff; + long *valp = ucontrol->value.integer.value; unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); + int change = ((pinctl & mask)!=0) != *valp; - if (valalc_pin_mode_max(dir)) - val = alc_pin_mode_min(dir); - - change = pinctl != alc_pin_mode_values[val]; - if (change) { - /* Set pin mode to that requested */ + if (change) snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, - alc_pin_mode_values[val]); - - /* Also enable the retasking pin's input/output as required - * for the requested pin mode. Enum values of 2 or less are - * input modes. - * - * Dynamically switching the input/output buffers probably - * reduces noise slightly (particularly on input) so we'll - * do it. However, having both input and output buffers - * enabled simultaneously doesn't seem to be problematic if - * this turns out to be necessary in the future. - */ - if (val <= 2) { - snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, - AMP_OUT_MUTE); - snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_UNMUTE(0)); - } else { - snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_MUTE(0)); - snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, - AMP_OUT_UNMUTE); - } - } + *valp?(pinctl|mask):(pinctl&~mask)); return change; } -#define ALC_PIN_MODE(xname, nid, dir) \ +#define ALC_PINCTL_SWITCH(xname, nid, mask) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = alc_pin_mode_info, \ - .get = alc_pin_mode_get, \ - .put = alc_pin_mode_put, \ - .private_value = nid | (dir<<16) } - -/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged - * together using a mask with more than one bit set. This control is - * currently used only by the ALC260 test model. At this stage they are not - * needed for any "production" models. - */ -#ifdef CONFIG_SND_DEBUG -static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} -static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long *valp = ucontrol->value.integer.value; - unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); - - *valp = (val & mask) != 0; - return 0; -} -static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - signed int change; - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; - unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); - - /* Set/unset the masked GPIO bit(s) as needed */ - change = (val==0?0:mask) != (gpio_data & mask); - if (val==0) - gpio_data &= ~mask; - else - gpio_data |= mask; - snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data); - - return change; -} -#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = alc_gpio_data_info, \ - .get = alc_gpio_data_get, \ - .put = alc_gpio_data_put, \ - .private_value = nid | (mask<<16) } -#endif /* CONFIG_SND_DEBUG */ - -/* A switch control to allow the enabling of the digital IO pins on the - * ALC260. This is incredibly simplistic; the intention of this control is - * to provide something in the test model allowing digital outputs to be - * identified if present. If models are found which can utilise these - * outputs a more complete mixer control can be devised for those models if - * necessary. - */ -#ifdef CONFIG_SND_DEBUG -static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} -static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long *valp = ucontrol->value.integer.value; - unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); - - *valp = (val & mask) != 0; - return 0; -} -static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - signed int change; - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; - unsigned int ctrl_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); - - /* Set/unset the masked control bit(s) as needed */ - change = (val==0?0:mask) != (ctrl_data & mask); - if (val==0) - ctrl_data &= ~mask; - else - ctrl_data |= mask; - snd_hda_codec_write(codec,nid,0,AC_VERB_SET_DIGI_CONVERT_1,ctrl_data); + .info = alc_pinctl_switch_info, \ + .get = alc_pinctl_switch_get, \ + .put = alc_pinctl_switch_put, \ + .private_value = (nid) | (mask<<16) } - return change; -} -#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = alc_spdif_ctrl_info, \ - .get = alc_spdif_ctrl_get, \ - .put = alc_spdif_ctrl_put, \ - .private_value = nid | (mask<<16) } -#endif /* CONFIG_SND_DEBUG */ /* * set up from the preset table @@ -500,17 +291,11 @@ static void setup_preset(struct alc_spec *spec, const struct alc_config_preset * spec->multiout.dig_out_nid = preset->dig_out_nid; spec->multiout.hp_nid = preset->hp_nid; - spec->num_mux_defs = preset->num_mux_defs; - if (! spec->num_mux_defs) - spec->num_mux_defs = 1; spec->input_mux = preset->input_mux; spec->num_adc_nids = preset->num_adc_nids; spec->adc_nids = preset->adc_nids; spec->dig_in_nid = preset->dig_in_nid; - - spec->unsol_event = preset->unsol_event; - spec->init_hook = preset->init_hook; } /* @@ -1313,217 +1098,6 @@ static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { }; /* - * LG m1 express dual - * - * Pin assignment: - * Rear Line-In/Out (blue): 0x14 - * Build-in Mic-In: 0x15 - * Speaker-out: 0x17 - * HP-Out (green): 0x1b - * Mic-In/Out (red): 0x19 - * SPDIF-Out: 0x1e - */ - -/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ -static hda_nid_t alc880_lg_dac_nids[3] = { - 0x05, 0x02, 0x03 -}; - -/* seems analog CD is not working */ -static struct hda_input_mux alc880_lg_capture_source = { - .num_items = 3, - .items = { - { "Mic", 0x1 }, - { "Line", 0x5 }, - { "Internal Mic", 0x6 }, - }, -}; - -/* 2,4,6 channel modes */ -static struct hda_verb alc880_lg_ch2_init[] = { - /* set line-in and mic-in to input */ - { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { } -}; - -static struct hda_verb alc880_lg_ch4_init[] = { - /* set line-in to out and mic-in to input */ - { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, - { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { } -}; - -static struct hda_verb alc880_lg_ch6_init[] = { - /* set line-in and mic-in to output */ - { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, - { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, - { } -}; - -static struct hda_channel_mode alc880_lg_ch_modes[3] = { - { 2, alc880_lg_ch2_init }, - { 4, alc880_lg_ch4_init }, - { 6, alc880_lg_ch6_init }, -}; - -static struct snd_kcontrol_new alc880_lg_mixer[] = { - /* FIXME: it's not really "master" but front channels */ - HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = alc_ch_mode_info, - .get = alc_ch_mode_get, - .put = alc_ch_mode_put, - }, - { } /* end */ -}; - -static struct hda_verb alc880_lg_init_verbs[] = { - /* set capture source to mic-in */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* mute all amp mixer inputs */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)}, - /* line-in to input */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* built-in mic */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* speaker-out */ - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* mic-in to input */ - {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* HP-out */ - {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* jack sense */ - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, - { } -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc880_lg_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); -} - -static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) -{ - /* Looks like the unsol event is incompatible with the standard - * definition. 4bit tag is placed at 28 bit! - */ - if ((res >> 28) == 0x01) - alc880_lg_automute(codec); -} - -/* - * LG LW20 - * - * Pin assignment: - * Speaker-out: 0x14 - * Mic-In: 0x18 - * Built-in Mic-In: 0x19 (?) - * HP-Out: 0x1b - * SPDIF-Out: 0x1e - */ - -/* seems analog CD is not working */ -static struct hda_input_mux alc880_lg_lw_capture_source = { - .num_items = 2, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x1 }, - }, -}; - -static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - { } /* end */ -}; - -static struct hda_verb alc880_lg_lw_init_verbs[] = { - /* set capture source to mic-in */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)}, - /* speaker-out */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* HP-out */ - {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* mic-in to input */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* built-in mic */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* jack sense */ - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, - { } -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc880_lg_lw_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); -} - -static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) -{ - /* Looks like the unsol event is incompatible with the standard - * definition. 4bit tag is placed at 28 bit! - */ - if ((res >> 28) == 0x01) - alc880_lg_lw_automute(codec); -} - -/* - * Common callbacks */ static int alc_init(struct hda_codec *codec) @@ -1533,21 +1107,9 @@ static int alc_init(struct hda_codec *codec) for (i = 0; i < spec->num_init_verbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); - - if (spec->init_hook) - spec->init_hook(codec); - return 0; } -static void alc_unsol_event(struct hda_codec *codec, unsigned int res) -{ - struct alc_spec *spec = codec->spec; - - if (spec->unsol_event) - spec->unsol_event(codec, res); -} - #ifdef CONFIG_PM /* * resume @@ -1688,13 +1250,6 @@ static struct hda_pcm_stream alc880_pcm_digital_capture = { /* NID is set in alc_build_pcms */ }; -/* Used by alc_build_pcms to flag that a PCM has no playback stream */ -static struct hda_pcm_stream alc_pcm_null_playback = { - .substreams = 0, - .channels_min = 0, - .channels_max = 0, -}; - static int alc_build_pcms(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -1725,23 +1280,6 @@ static int alc_build_pcms(struct hda_codec *codec) } } - /* If the use of more than one ADC is requested for the current - * model, configure a second analog capture-only PCM. - */ - if (spec->num_adc_nids > 1) { - codec->num_pcms++; - info++; - info->name = spec->stream_name_analog; - /* No playback stream for second PCM */ - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback; - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; - if (spec->stream_analog_capture) { - snd_assert(spec->adc_nids, return -EINVAL); - info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1]; - } - } - if (spec->multiout.dig_out_nid || spec->dig_in_nid) { codec->num_pcms++; info++; @@ -1784,7 +1322,6 @@ static struct hda_codec_ops alc_patch_ops = { .build_pcms = alc_build_pcms, .init = alc_init, .free = alc_free, - .unsol_event = alc_unsol_event, #ifdef CONFIG_PM .resume = alc_resume, #endif @@ -1803,15 +1340,13 @@ static hda_nid_t alc880_test_dac_nids[4] = { }; static struct hda_input_mux alc880_test_capture_source = { - .num_items = 7, + .num_items = 5, .items = { { "In-1", 0x0 }, { "In-2", 0x1 }, { "In-3", 0x2 }, { "In-4", 0x3 }, { "CD", 0x4 }, - { "Front", 0x5 }, - { "Surround", 0x6 }, }, }; @@ -2118,8 +1653,6 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560, - .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */ /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, /* note subvendor = 0 below */ @@ -2147,8 +1680,6 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG }, { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG }, { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */ - { .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */ - { .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */ { .modelname = "asus", .config = ALC880_ASUS }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, @@ -2162,7 +1693,6 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V }, - { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */ { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, @@ -2172,12 +1702,6 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 }, { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 }, - { .modelname = "lg", .config = ALC880_LG }, - { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, - - { .modelname = "lg-lw", .config = ALC880_LG_LW }, - { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW }, - #ifdef CONFIG_SND_DEBUG { .modelname = "test", .config = ALC880_TEST }, #endif @@ -2355,32 +1879,6 @@ static struct alc_config_preset alc880_presets[] = { .channel_mode = alc880_threestack_modes, .input_mux = &alc880_capture_source, }, - [ALC880_LG] = { - .mixers = { alc880_lg_mixer }, - .init_verbs = { alc880_volume_init_verbs, - alc880_lg_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), - .dac_nids = alc880_lg_dac_nids, - .dig_out_nid = ALC880_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), - .channel_mode = alc880_lg_ch_modes, - .input_mux = &alc880_lg_capture_source, - .unsol_event = alc880_lg_unsol_event, - .init_hook = alc880_lg_automute, - }, - [ALC880_LG_LW] = { - .mixers = { alc880_lg_lw_mixer }, - .init_verbs = { alc880_volume_init_verbs, - alc880_lg_lw_init_verbs }, - .num_dacs = 1, - .dac_nids = alc880_dac_nids, - .dig_out_nid = ALC880_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), - .channel_mode = alc880_2_jack_modes, - .input_mux = &alc880_lg_lw_capture_source, - .unsol_event = alc880_lg_lw_unsol_event, - .init_hook = alc880_lg_lw_automute, - }, #ifdef CONFIG_SND_DEBUG [ALC880_TEST] = { .mixers = { alc880_test_mixer }, @@ -2545,11 +2043,14 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, if (alc880_is_fixed_pin(pin)) { nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); - /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) + if (! spec->multiout.dac_nids[0]) { + /* use this as the primary output */ + spec->multiout.dac_nids[0] = nid; + if (! spec->multiout.num_dacs) + spec->multiout.num_dacs = 1; + } else + /* specify the DAC as the extra output */ spec->multiout.hp_nid = nid; - else - spec->multiout.extra_out_nid[0] = nid; /* control HP volume/switch on the output mixer amp */ nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); sprintf(name, "%s Playback Volume", pfx); @@ -2562,6 +2063,12 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, return err; } else if (alc880_is_multi_pin(pin)) { /* set manual connection */ + if (! spec->multiout.dac_nids[0]) { + /* use this as the primary output */ + spec->multiout.dac_nids[0] = alc880_idx_to_dac(alc880_multi_pin_idx(pin)); + if (! spec->multiout.num_dacs) + spec->multiout.num_dacs = 1; + } /* we have only a switch on HP-out PIN */ sprintf(name, "%s Playback Switch", pfx); if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, @@ -2645,7 +2152,7 @@ static void alc880_auto_init_extra_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; hda_nid_t pin; - pin = spec->autocfg.speaker_pins[0]; + pin = spec->autocfg.speaker_pin; if (pin) /* connect to front */ alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); pin = spec->autocfg.hp_pin; @@ -2681,15 +2188,15 @@ static int alc880_parse_auto_config(struct hda_codec *codec) if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc880_ignore)) < 0) return err; - if (! spec->autocfg.line_outs) + if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && + ! spec->autocfg.hp_pin) return 0; /* can't find valid BIOS pin config */ if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc880_auto_create_extra_out(spec, - spec->autocfg.speaker_pins[0], + (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin, "Speaker")) < 0 || - (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin, + (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin, "Headphone")) < 0 || (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) return err; @@ -2706,18 +2213,19 @@ static int alc880_parse_auto_config(struct hda_codec *codec) spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; - spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; return 1; } -/* additional initialization for auto-configuration model */ -static void alc880_auto_init(struct hda_codec *codec) +/* init callback for auto-configuration model -- overriding the default init */ +static int alc880_auto_init(struct hda_codec *codec) { + alc_init(codec); alc880_auto_init_multi_out(codec); alc880_auto_init_extra_out(codec); alc880_auto_init_analog_input(codec); + return 0; } /* @@ -2784,7 +2292,7 @@ static int patch_alc880(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC880_AUTO) - spec->init_hook = alc880_auto_init; + codec->patch_ops.init = alc880_auto_init; return 0; } @@ -2814,14 +2322,6 @@ static hda_nid_t alc260_hp_adc_nids[2] = { 0x05, 0x04 }; -/* NIDs used when simultaneous access to both ADCs makes sense. Note that - * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. - */ -static hda_nid_t alc260_dual_adc_nids[2] = { - /* ADC0, ADC1 */ - 0x04, 0x05 -}; - #define ALC260_DIGOUT_NID 0x03 #define ALC260_DIGIN_NID 0x06 @@ -2835,57 +2335,17 @@ static struct hda_input_mux alc260_capture_source = { }, }; -/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, - * headphone jack and the internal CD lines since these are the only pins at - * which audio can appear. For flexibility, also allow the option of - * recording the mixer output on the second ADC (ADC0 doesn't have a - * connection to the mixer output). +/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack + * and the internal CD lines. */ -static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { - { - .num_items = 3, - .items = { - { "Mic/Line", 0x0 }, - { "CD", 0x4 }, - { "Headphone", 0x2 }, - }, - }, - { - .num_items = 4, - .items = { - { "Mic/Line", 0x0 }, - { "CD", 0x4 }, - { "Headphone", 0x2 }, - { "Mixer", 0x5 }, - }, +static struct hda_input_mux alc260_fujitsu_capture_source = { + .num_items = 2, + .items = { + { "Mic/Line", 0x0 }, + { "CD", 0x4 }, }, - }; -/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to - * the Fujitsu S702x, but jacks are marked differently. - */ -static struct hda_input_mux alc260_acer_capture_sources[2] = { - { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - { "Headphone", 0x5 }, - }, - }, - { - .num_items = 5, - .items = { - { "Mic", 0x0 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - { "Headphone", 0x6 }, - { "Mixer", 0x5 }, - }, - }, -}; /* * This is just place-holder, so there's something for alc_build_pcms to look * at when it calculates the maximum number of channels. ALC260 has no mixer @@ -2903,7 +2363,6 @@ static struct hda_channel_mode alc260_modes[1] = { * HP: base_output + input + capture_alt * HP_3013: hp_3013 + input + capture * fujitsu: fujitsu + capture - * acer: acer + capture */ static struct snd_kcontrol_new alc260_base_output_mixer[] = { @@ -2946,18 +2405,14 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { { } /* end */ }; -/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, - * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. - */ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), - ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), + ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP), HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), - ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), @@ -2965,41 +2420,6 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { { } /* end */ }; -/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current - * versions of the ALC260 don't act on requests to enable mic bias from NID - * 0x0f (used to drive the headphone jack in these laptops). The ALC260 - * datasheet doesn't mention this restriction. At this stage it's not clear - * whether this behaviour is intentional or is a hardware bug in chip - * revisions available in early 2006. Therefore for now allow the - * "Headphone Jack Mode" control to span all choices, but if it turns out - * that the lack of mic bias for this NID is intentional we could change the - * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. - * - * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 - * don't appear to make the mic bias available from the "line" jack, even - * though the NID used for this jack (0x14) can supply it. The theory is - * that perhaps Acer have included blocking capacitors between the ALC260 - * and the output jack. If this turns out to be the case for all such - * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT - * to ALC_PIN_DIR_INOUT_NOMICBIAS. - */ -static struct snd_kcontrol_new alc260_acer_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), - ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), - ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), - HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), - ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), - HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), - { } /* end */ -}; - /* capture mixer elements */ static struct snd_kcontrol_new alc260_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), @@ -3200,8 +2620,7 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { }; /* Initialisation sequence for ALC260 as configured in Fujitsu S702x - * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD - * audio = 0x16, internal speaker = 0x10. + * laptops. */ static struct hda_verb alc260_fujitsu_init_verbs[] = { /* Disable all GPIOs */ @@ -3210,346 +2629,52 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = { {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, /* Headphone/Line-out jack connects to Line1 pin; make it an output */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - /* Ensure all other unused pins are disabled and muted. */ - {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - - /* Disable digital (SPDIF) pins */ - {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, - {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, - - /* Ensure Line1 pin widget takes its input from the OUT1 sum bus - * when acting as an output. - */ - {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, - - /* Start with output sum widgets muted and their output gains at min */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Unmute Line1 pin widget output buffer since it starts as an output. - * If the pin mode is changed by the user the pin mode control will - * take care of enabling the pin's input/output buffers as needed. - * Therefore there's no need to enable the input buffer at this - * stage. - */ - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Unmute input buffer of pin widget used for Line-in (no equiv - * mixer ctrl) + /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + /* Ensure all other unused pins are disabled and muted. + * Note: trying to set widget 0x15 to anything blocks all audio + * output for some reason, so just leave that at the default. */ - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - - /* Mute capture amp left and right */ - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - /* Set ADC connection select to match default mixer setting - line - * in (on mic1 pin) - */ - {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Do the same for the second ADC: mute capture input amp and - * set ADC connection to line in (on mic1 pin) - */ - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Mute all inputs to mixer widget (even unconnected ones) */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ - - { } -}; - -/* Initialisation sequence for ALC260 as configured in Acer TravelMate and - * similar laptops (adapted from Fujitsu init verbs). - */ -static struct hda_verb alc260_acer_init_verbs[] = { - /* On TravelMate laptops, GPIO 0 enables the internal speaker and - * the headphone jack. Turn this on and rely on the standard mute - * methods whenever the user wants to turn these outputs off. - */ - {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, - /* Internal speaker/Headphone jack is connected to Line-out pin */ - {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - /* Internal microphone/Mic jack is connected to Mic1 pin */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, - /* Line In jack is connected to Line1 pin */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - /* Ensure all other unused pins are disabled and muted. */ - {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, + {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - /* Disable digital (SPDIF) pins */ - {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, - {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, - - /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum - * bus when acting as outputs. - */ - {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, - {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, - - /* Start with output sum widgets muted and their output gains at min */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Unmute Mic1 and Line1 pin widget input buffers since they start as - * inputs. If the pin mode is changed by the user the pin mode control - * will take care of enabling the pin's input/output buffers as needed. - * Therefore there's no need to enable the input buffer at this - * stage. - */ - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - - /* Mute capture amp left and right */ - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - /* Set ADC connection select to match default mixer setting - mic - * (on mic1 pin) - */ - {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Do similar with the second ADC: mute capture input amp and - * set ADC connection to mic to match ALSA's default state. - */ - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Mute all inputs to mixer widget (even unconnected ones) */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ + {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + /* Disable digital (SPDIF) pins */ + {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, + {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, + + /* Start with mixer outputs muted */ + {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + + /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ + {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + /* Unmute Line1 pin widget amp left and right (no equiv mixer ctrl) */ + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + /* Unmute pin widget used for Line-in (no equiv mixer ctrl) */ + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + + /* Mute capture amp left and right */ + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + /* Set ADC connection select to line in (on mic1 pin) */ + {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, + + /* Mute all inputs to mixer widget (even unconnected ones) */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ { } }; -/* Test configuration for debugging, modelled after the ALC880 test - * configuration. - */ -#ifdef CONFIG_SND_DEBUG -static hda_nid_t alc260_test_dac_nids[1] = { - 0x02, -}; -static hda_nid_t alc260_test_adc_nids[2] = { - 0x04, 0x05, -}; -/* For testing the ALC260, each input MUX needs its own definition since - * the signal assignments are different. This assumes that the first ADC - * is NID 0x04. - */ -static struct hda_input_mux alc260_test_capture_sources[2] = { - { - .num_items = 7, - .items = { - { "MIC1 pin", 0x0 }, - { "MIC2 pin", 0x1 }, - { "LINE1 pin", 0x2 }, - { "LINE2 pin", 0x3 }, - { "CD pin", 0x4 }, - { "LINE-OUT pin", 0x5 }, - { "HP-OUT pin", 0x6 }, - }, - }, - { - .num_items = 8, - .items = { - { "MIC1 pin", 0x0 }, - { "MIC2 pin", 0x1 }, - { "LINE1 pin", 0x2 }, - { "LINE2 pin", 0x3 }, - { "CD pin", 0x4 }, - { "Mixer", 0x5 }, - { "LINE-OUT pin", 0x6 }, - { "HP-OUT pin", 0x7 }, - }, - }, -}; -static struct snd_kcontrol_new alc260_test_mixer[] = { - /* Output driver widgets */ - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), - HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), - HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), - - /* Modes for retasking pin widgets - * Note: the ALC260 doesn't seem to act on requests to enable mic - * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't - * mention this restriction. At this stage it's not clear whether - * this behaviour is intentional or is a hardware bug in chip - * revisions available at least up until early 2006. Therefore for - * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all - * choices, but if it turns out that the lack of mic bias for these - * NIDs is intentional we could change their modes from - * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. - */ - ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), - ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), - ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), - ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), - ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), - ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), - - /* Loopback mixer controls */ - HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), - HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), - HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), - HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), - - /* Controls for GPIO pins, assuming they are configured as outputs */ - ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), - ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), - ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), - ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), - - /* Switches to allow the digital IO pins to be enabled. The datasheet - * is ambigious as to which NID is which; testing on laptops which - * make this output available should provide clarification. - */ - ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), - ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), - - { } /* end */ -}; -static struct hda_verb alc260_test_init_verbs[] = { - /* Enable all GPIOs as outputs with an initial value of 0 */ - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, - {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, - - /* Enable retasking pins as output, initially without power amp */ - {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - /* Disable digital (SPDIF) pins initially, but users can enable - * them via a mixer switch. In the case of SPDIF-out, this initverb - * payload also sets the generation to 0, output to be in "consumer" - * PCM format, copyright asserted, no pre-emphasis and no validity - * control. - */ - {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, - {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, - - /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the - * OUT1 sum bus when acting as an output. - */ - {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, - {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, - {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, - {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, - - /* Start with output sum widgets muted and their output gains at min */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* Unmute retasking pin widget output buffers since the default - * state appears to be output. As the pin mode is changed by the - * user the pin mode control will take care of enabling the pin's - * input/output buffers as needed. - */ - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Also unmute the mono-out pin widget */ - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - - /* Mute capture amp left and right */ - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - /* Set ADC connection select to match default mixer setting (mic1 - * pin) - */ - {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Do the same for the second ADC: mute capture input amp and - * set ADC connection to mic1 pin - */ - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Mute all inputs to mixer widget (even unconnected ones) */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ - - { } -}; -#endif - static struct hda_pcm_stream alc260_pcm_analog_playback = { .substreams = 1, .channels_min = 2, @@ -3619,7 +2744,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, return err; } - nid = cfg->speaker_pins[0]; + nid = cfg->speaker_pin; if (nid) { err = alc260_add_playback_controls(spec, nid, "Speaker"); if (err < 0) @@ -3692,7 +2817,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) if (nid) alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); - nid = spec->autocfg.speaker_pins[0]; + nid = spec->autocfg.speaker_pin; if (nid) alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); @@ -3788,7 +2913,6 @@ static int alc260_parse_auto_config(struct hda_codec *codec) spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; - spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; /* check whether NID 0x04 is valid */ @@ -3808,11 +2932,13 @@ static int alc260_parse_auto_config(struct hda_codec *codec) return 1; } -/* additional initialization for auto-configuration model */ -static void alc260_auto_init(struct hda_codec *codec) +/* init callback for auto-configuration model -- overriding the default init */ +static int alc260_auto_init(struct hda_codec *codec) { + alc_init(codec); alc260_auto_init_multi_out(codec); alc260_auto_init_analog_input(codec); + return 0; } /* @@ -3834,11 +2960,6 @@ static struct hda_board_config alc260_cfg_tbl[] = { { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, - { .modelname = "acer", .config = ALC260_ACER }, - { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER }, -#ifdef CONFIG_SND_DEBUG - { .modelname = "test", .config = ALC260_TEST }, -#endif { .modelname = "auto", .config = ALC260_AUTO }, {} }; @@ -3890,41 +3011,12 @@ static struct alc_config_preset alc260_presets[] = { .init_verbs = { alc260_fujitsu_init_verbs }, .num_dacs = ARRAY_SIZE(alc260_dac_nids), .dac_nids = alc260_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), - .adc_nids = alc260_dual_adc_nids, - .num_channel_mode = ARRAY_SIZE(alc260_modes), - .channel_mode = alc260_modes, - .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), - .input_mux = alc260_fujitsu_capture_sources, - }, - [ALC260_ACER] = { - .mixers = { alc260_acer_mixer, - alc260_capture_mixer }, - .init_verbs = { alc260_acer_init_verbs }, - .num_dacs = ARRAY_SIZE(alc260_dac_nids), - .dac_nids = alc260_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), - .adc_nids = alc260_dual_adc_nids, - .num_channel_mode = ARRAY_SIZE(alc260_modes), - .channel_mode = alc260_modes, - .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), - .input_mux = alc260_acer_capture_sources, - }, -#ifdef CONFIG_SND_DEBUG - [ALC260_TEST] = { - .mixers = { alc260_test_mixer, - alc260_capture_mixer }, - .init_verbs = { alc260_test_init_verbs }, - .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), - .dac_nids = alc260_test_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), - .adc_nids = alc260_test_adc_nids, + .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), + .adc_nids = alc260_adc_nids, .num_channel_mode = ARRAY_SIZE(alc260_modes), .channel_mode = alc260_modes, - .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), - .input_mux = alc260_test_capture_sources, + .input_mux = &alc260_fujitsu_capture_source, }, -#endif }; static int patch_alc260(struct hda_codec *codec) @@ -3969,7 +3061,7 @@ static int patch_alc260(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC260_AUTO) - spec->init_hook = alc260_auto_init; + codec->patch_ops.init = alc260_auto_init; return 0; } @@ -4014,6 +3106,7 @@ static struct hda_input_mux alc882_capture_source = { { "CD", 0x4 }, }, }; + #define alc882_mux_enum_info alc_mux_enum_info #define alc882_mux_enum_get alc_mux_enum_get @@ -4443,12 +3536,14 @@ static int alc882_parse_auto_config(struct hda_codec *codec) return err; } -/* additional initialization for auto-configuration model */ -static void alc882_auto_init(struct hda_codec *codec) +/* init callback for auto-configuration model -- overriding the default init */ +static int alc882_auto_init(struct hda_codec *codec) { + alc_init(codec); alc882_auto_init_multi_out(codec); alc882_auto_init_hp_out(codec); alc882_auto_init_analog_input(codec); + return 0; } /* @@ -4515,7 +3610,7 @@ static int patch_alc882(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC882_AUTO) - spec->init_hook = alc882_auto_init; + codec->patch_ops.init = alc882_auto_init; return 0; } @@ -4551,9 +3646,19 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = alc882_mux_enum_info, + .get = alc882_mux_enum_get, + .put = alc882_mux_enum_put, + }, { } /* end */ -}; - +}; + #define alc262_capture_mixer alc882_capture_mixer #define alc262_capture_alt_mixer alc882_capture_alt_mixer @@ -4636,129 +3741,6 @@ static struct hda_verb alc262_init_verbs[] = { { } }; -/* - * fujitsu model - * 0x14 = headphone/spdif-out, 0x15 = internal speaker - */ - -#define ALC_HP_EVENT 0x37 - -static struct hda_verb alc262_fujitsu_unsol_verbs[] = { - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} -}; - -static struct hda_input_mux alc262_fujitsu_capture_source = { - .num_items = 2, - .items = { - { "Mic", 0x0 }, - { "CD", 0x4 }, - }, -}; - -/* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc262_fujitsu_automute(struct hda_codec *codec, int force) -{ - struct alc_spec *spec = codec->spec; - unsigned int mute; - - if (force || ! spec->sense_updated) { - unsigned int present; - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & 0x80000000) != 0; - spec->sense_updated = 1; - } - if (spec->jack_present) { - /* mute internal speaker */ - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, 0x80); - } else { - /* unmute internal speaker if necessary */ - mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - } -} - -/* unsolicited event for HP jack sensing */ -static void alc262_fujitsu_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != ALC_HP_EVENT) - return; - alc262_fujitsu_automute(codec, 1); -} - -/* bind volumes of both NID 0x0c and 0x0d */ -static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - return change; -} - -/* bind hp and internal speaker mute (with plug check) */ -static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, valp[0] ? 0 : 0x80); - change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, valp[1] ? 0 : 0x80); - if (change || codec->in_resume) - alc262_fujitsu_automute(codec, codec->in_resume); - return change; -} - -static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = alc262_fujitsu_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = alc262_fujitsu_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), - }, - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - /* add playback controls from the parsed DAC table */ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { @@ -4779,7 +3761,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct return err; } - nid = cfg->speaker_pins[0]; + nid = cfg->speaker_pin; if (nid) { if (nid == 0x16) { if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", @@ -4789,6 +3771,10 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) return err; } else { + if (! cfg->line_out_pins[0]) + if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) + return err; if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) return err; @@ -4805,6 +3791,10 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) return err; } else { + if (! cfg->line_out_pins[0]) + if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) + return err; if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) return err; @@ -4898,7 +3888,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec) if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc262_ignore)) < 0) return err; - if (! spec->autocfg.line_outs) + if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && + ! spec->autocfg.hp_pin) return 0; /* can't find valid BIOS pin config */ if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) @@ -4915,7 +3906,6 @@ static int alc262_parse_auto_config(struct hda_codec *codec) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; - spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; return 1; @@ -4927,11 +3917,13 @@ static int alc262_parse_auto_config(struct hda_codec *codec) /* init callback for auto-configuration model -- overriding the default init */ -static void alc262_auto_init(struct hda_codec *codec) +static int alc262_auto_init(struct hda_codec *codec) { + alc_init(codec); alc262_auto_init_multi_out(codec); alc262_auto_init_hp_out(codec); alc262_auto_init_analog_input(codec); + return 0; } /* @@ -4939,8 +3931,6 @@ static void alc262_auto_init(struct hda_codec *codec) */ static struct hda_board_config alc262_cfg_tbl[] = { { .modelname = "basic", .config = ALC262_BASIC }, - { .modelname = "fujitsu", .config = ALC262_FUJITSU }, - { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU }, { .modelname = "auto", .config = ALC262_AUTO }, {} }; @@ -4956,18 +3946,6 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, }, - [ALC262_FUJITSU] = { - .mixers = { alc262_fujitsu_mixer }, - .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_fujitsu_capture_source, - .unsol_event = alc262_fujitsu_unsol_event, - }, }; static int patch_alc262(struct hda_codec *codec) @@ -5041,8 +4019,8 @@ static int patch_alc262(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC262_AUTO) - spec->init_hook = alc262_auto_init; - + codec->patch_ops.init = alc262_auto_init; + return 0; } @@ -5573,7 +4551,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec) if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc861_ignore)) < 0) return err; - if (! spec->autocfg.line_outs) + if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && + ! spec->autocfg.hp_pin) return 0; /* can't find valid BIOS pin config */ if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || @@ -5592,7 +4571,6 @@ static int alc861_parse_auto_config(struct hda_codec *codec) spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; - spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; spec->adc_nids = alc861_adc_nids; @@ -5603,12 +4581,15 @@ static int alc861_parse_auto_config(struct hda_codec *codec) return 1; } -/* additional initialization for auto-configuration model */ -static void alc861_auto_init(struct hda_codec *codec) +/* init callback for auto-configuration model -- overriding the default init */ +static int alc861_auto_init(struct hda_codec *codec) { + alc_init(codec); alc861_auto_init_multi_out(codec); alc861_auto_init_hp_out(codec); alc861_auto_init_analog_input(codec); + + return 0; } @@ -5706,7 +4687,7 @@ static int patch_alc861(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC861_AUTO) - spec->init_hook = alc861_auto_init; + codec->patch_ops.init = alc861_auto_init; return 0; } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d8622951c..35c2823a0 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -51,7 +51,6 @@ struct sigmatel_spec { unsigned int line_switch: 1; unsigned int mic_switch: 1; unsigned int alt_switch: 1; - unsigned int hp_detect: 1; /* playback */ struct hda_multi_out multiout; @@ -304,15 +303,6 @@ static struct hda_board_config stac922x_cfg_tbl[] = { .pci_subdevice = 0x0101, .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x0202, - .config = STAC_D945GTP3 }, /* Intel D945GNT - 3 Stack, 9221 A1 */ - { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x0b0b, - .config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack, 9221 A1 */ - { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x0707, - .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */ - { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x0404, .config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, @@ -537,22 +527,6 @@ static int stac92xx_build_pcms(struct hda_codec *codec) return 0; } -static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) -{ - unsigned int pincap = snd_hda_param_read(codec, nid, - AC_PAR_PIN_CAP); - pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; - if (pincap & AC_PINCAP_VREF_100) - return AC_PINCTL_VREF_100; - if (pincap & AC_PINCAP_VREF_80) - return AC_PINCTL_VREF_80; - if (pincap & AC_PINCAP_VREF_50) - return AC_PINCTL_VREF_50; - if (pincap & AC_PINCAP_VREF_GRD) - return AC_PINCTL_VREF_GRD; - return 0; -} - static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) { @@ -590,12 +564,9 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ if (val) stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); - else { - unsigned int pinctl = AC_PINCTL_IN_EN; - if (io_idx) /* set VREF for mic */ - pinctl |= stac92xx_get_vref(codec, nid); - stac92xx_auto_set_pinctl(codec, nid, pinctl); - } + else + stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_IN_EN); + return 1; } @@ -720,7 +691,13 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct aut AC_VERB_GET_CONNECT_LIST, 0) & 0xff; } - spec->multiout.num_dacs = cfg->line_outs; + if (cfg->line_outs) + spec->multiout.num_dacs = cfg->line_outs; + else if (cfg->hp_pin) { + spec->multiout.dac_nids[0] = snd_hda_codec_read(codec, cfg->hp_pin, 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + spec->multiout.num_dacs = 1; + } return 0; } @@ -790,7 +767,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin wid_caps = get_wcaps(codec, pin); if (wid_caps & AC_WCAP_UNSOL_CAP) - spec->hp_detect = 1; + /* Enable unsolicited responses on the HP widget */ + snd_hda_codec_write(codec, pin, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + STAC_UNSOL_ENABLE); nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; for (i = 0; i < cfg->line_outs; i++) { @@ -824,6 +804,9 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const for (i = 0; i < AUTO_PIN_LAST; i++) { int index = -1; if (cfg->input_pins[i]) { + /* Enable active pin widget as an input */ + stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], AC_PINCTL_IN_EN); + imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; for (j=0; jnum_muxes; j++) { @@ -872,8 +855,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) return err; - if (! spec->autocfg.line_outs) + if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) return 0; /* can't find valid pin config */ + stac92xx_auto_init_multi_out(codec); + stac92xx_auto_init_hp_out(codec); if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) return err; if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) @@ -888,10 +873,14 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if (spec->multiout.max_channels > 2) spec->surr_switch = 1; - if (spec->autocfg.dig_out_pin) + if (spec->autocfg.dig_out_pin) { spec->multiout.dig_out_nid = dig_out; - if (spec->autocfg.dig_in_pin) + stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); + } + if (spec->autocfg.dig_in_pin) { spec->dig_in_nid = dig_in; + stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); + } if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; @@ -901,24 +890,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out return 1; } -/* add playback controls for HP output */ -static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, - struct auto_pin_cfg *cfg) -{ - struct sigmatel_spec *spec = codec->spec; - hda_nid_t pin = cfg->hp_pin; - unsigned int wid_caps; - - if (! pin) - return 0; - - wid_caps = get_wcaps(codec, pin); - if (wid_caps & AC_WCAP_UNSOL_CAP) - spec->hp_detect = 1; - - return 0; -} - static int stac9200_parse_auto_config(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -930,13 +901,14 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) return err; - if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0) - return err; - - if (spec->autocfg.dig_out_pin) + if (spec->autocfg.dig_out_pin) { spec->multiout.dig_out_nid = 0x05; - if (spec->autocfg.dig_in_pin) + stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); + } + if (spec->autocfg.dig_in_pin) { spec->dig_in_nid = 0x04; + stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); + } if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; @@ -949,39 +921,9 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) static int stac92xx_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; - int i; snd_hda_sequence_write(codec, spec->init); - /* set up pins */ - if (spec->hp_detect) { - /* Enable unsolicited responses on the HP widget */ - snd_hda_codec_write(codec, cfg->hp_pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - STAC_UNSOL_ENABLE); - /* fake event to set up pins */ - codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); - } else { - stac92xx_auto_init_multi_out(codec); - stac92xx_auto_init_hp_out(codec); - } - for (i = 0; i < AUTO_PIN_LAST; i++) { - hda_nid_t nid = cfg->input_pins[i]; - if (nid) { - unsigned int pinctl = AC_PINCTL_IN_EN; - if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) - pinctl |= stac92xx_get_vref(codec, nid); - stac92xx_auto_set_pinctl(codec, nid, pinctl); - } - } - if (cfg->dig_out_pin) - stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, - AC_PINCTL_OUT_EN); - if (cfg->dig_in_pin) - stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, - AC_PINCTL_IN_EN); - return 0; } @@ -1199,166 +1141,6 @@ static int patch_stac927x(struct hda_codec *codec) return 0; } -/* - * STAC 7661(?) hack - */ - -/* static config for Sony VAIO FE550G */ -static hda_nid_t vaio_dacs[] = { 0x2 }; -#define VAIO_HP_DAC 0x5 -static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; -static hda_nid_t vaio_mux_nids[] = { 0x15 }; - -static struct hda_input_mux vaio_mux = { - .num_items = 2, - .items = { - /* { "HP", 0x0 }, */ - { "Line", 0x1 }, - { "Mic", 0x2 }, - { "PCM", 0x3 }, - } -}; - -static struct hda_verb vaio_init[] = { - {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ - {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ - {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ - {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ - {} -}; - -/* bind volumes of both NID 0x02 and 0x05 */ -static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - return change; -} - -/* bind volumes of both NID 0x02 and 0x05 */ -static int vaio_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, - 0x80, (valp[0] ? 0 : 0x80)); - change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, - 0x80, (valp[1] ? 0 : 0x80)); - snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x80, (valp[0] ? 0 : 0x80)); - snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x80, (valp[1] ? 0 : 0x80)); - return change; -} - -static struct snd_kcontrol_new vaio_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = vaio_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = vaio_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), - }, - /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ - HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, - {} -}; - -static struct hda_codec_ops stac7661_patch_ops = { - .build_controls = stac92xx_build_controls, - .build_pcms = stac92xx_build_pcms, - .init = stac92xx_init, - .free = stac92xx_free, -#ifdef CONFIG_PM - .resume = stac92xx_resume, -#endif -}; - -enum { STAC7661_VAIO }; - -static struct hda_board_config stac7661_cfg_tbl[] = { - { .modelname = "vaio", .config = STAC7661_VAIO }, - { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, - .config = STAC7661_VAIO }, - { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, - .config = STAC7661_VAIO }, - {} -}; - -static int patch_stac7661(struct hda_codec *codec) -{ - struct sigmatel_spec *spec; - int board_config; - - board_config = snd_hda_check_board_config(codec, stac7661_cfg_tbl); - if (board_config < 0) - /* unknown config, let generic-parser do its job... */ - return snd_hda_parse_generic_codec(codec); - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - switch (board_config) { - case STAC7661_VAIO: - spec->mixer = vaio_mixer; - spec->init = vaio_init; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); - spec->multiout.dac_nids = vaio_dacs; - spec->multiout.hp_nid = VAIO_HP_DAC; - spec->num_adcs = ARRAY_SIZE(vaio_adcs); - spec->adc_nids = vaio_adcs; - spec->input_mux = &vaio_mux; - spec->mux_nids = vaio_mux_nids; - break; - } - - codec->patch_ops = stac7661_patch_ops; - return 0; -} - - /* * patch entries */ @@ -1380,6 +1162,5 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, - { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac7661 }, {} /* terminator */ }; diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 336dc489a..8809812a1 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -53,8 +53,6 @@ #include #include #include -#include - #include #include "ice1712.h" @@ -87,151 +85,7 @@ #define CS8415_C_BUFFER 0x20 #define CS8415_ID 0x7F -/* PCA9554 registers */ -#define PCA9554_DEV 0x40 /* I2C device address */ -#define PCA9554_IN 0x00 /* input port */ -#define PCA9554_OUT 0x01 /* output port */ -#define PCA9554_INVERT 0x02 /* input invert */ -#define PCA9554_DIR 0x03 /* port directions */ - -/* - * Aureon Universe additional controls using PCA9554 - */ - -/* - * Send data to pca9554 - */ -static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg, - unsigned char data) -{ - unsigned int tmp; - int i, j; - unsigned char dev = PCA9554_DEV; /* ID 0100000, write */ - unsigned char val = 0; - - tmp = snd_ice1712_gpio_read(ice); - - snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK| - AUREON_WM_RW|AUREON_WM_CS| - AUREON_CS8415_CS)); - tmp |= AUREON_WM_RW; - tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */ - - tmp &= ~AUREON_SPI_MOSI; - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(50); - - /* - * send i2c stop condition and start condition - * to obtain sane state - */ - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(50); - tmp |= AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(100); - tmp &= ~AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(50); - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(100); - /* - * send device address, command and value, - * skipping ack cycles inbetween - */ - for (j = 0; j < 3; j++) { - switch(j) { - case 0: val = dev; break; - case 1: val = reg; break; - case 2: val = data; break; - } - for (i = 7; i >= 0; i--) { - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - if (val & (1 << i)) - tmp |= AUREON_SPI_MOSI; - else - tmp &= ~AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - } - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - } - tmp &= ~AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp &= ~AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(40); - tmp |= AUREON_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(50); - tmp |= AUREON_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(100); -} - -static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"}; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out; - return 0; -} - -static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char oval, nval; - int change; - - snd_ice1712_save_gpio_status(ice); - - oval = ice->spec.aureon.pca9554_out; - nval = ucontrol->value.integer.value[0]; - if ((change = (oval != nval))) { - aureon_pca9554_write(ice, PCA9554_OUT, nval); - ice->spec.aureon.pca9554_out = nval; - } - snd_ice1712_restore_gpio_status(ice); - - return change; -} - - -static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, - unsigned short val) -{ +static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, unsigned short val) { unsigned int tmp; /* Send address to XILINX chip */ @@ -290,8 +144,7 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r /* * Initialize STAC9744 chip */ -static int aureon_ac97_init (struct snd_ice1712 *ice) -{ +static int aureon_ac97_init (struct snd_ice1712 *ice) { int i; static unsigned short ac97_defaults[] = { 0x00, 0x9640, @@ -357,14 +210,14 @@ static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned short vol; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F); if (kcontrol->private_value & AUREON_AC97_STEREO) ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -399,11 +252,11 @@ static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -435,11 +288,11 @@ static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ct { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -469,48 +322,36 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned { unsigned int tmp; int i; - unsigned int mosi, clk; tmp = snd_ice1712_gpio_read(ice); - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) { - snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS)); - mosi = PRODIGY_SPI_MOSI; - clk = PRODIGY_SPI_CLK; - } - else { - snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK| - AUREON_WM_CS|AUREON_CS8415_CS)); - mosi = AUREON_SPI_MOSI; - clk = AUREON_SPI_CLK; - - tmp |= AUREON_WM_RW; - } - + snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK| + AUREON_WM_CS|AUREON_CS8415_CS)); + tmp |= AUREON_WM_RW; tmp &= ~cs; snd_ice1712_gpio_write(ice, tmp); udelay(1); for (i = bits - 1; i >= 0; i--) { - tmp &= ~clk; + tmp &= ~AUREON_SPI_CLK; snd_ice1712_gpio_write(ice, tmp); udelay(1); if (data & (1 << i)) - tmp |= mosi; + tmp |= AUREON_SPI_MOSI; else - tmp &= ~mosi; + tmp &= ~AUREON_SPI_MOSI; snd_ice1712_gpio_write(ice, tmp); udelay(1); - tmp |= clk; + tmp |= AUREON_SPI_CLK; snd_ice1712_gpio_write(ice, tmp); udelay(1); } - tmp &= ~clk; + tmp &= ~AUREON_SPI_CLK; tmp |= cs; snd_ice1712_gpio_write(ice, tmp); udelay(1); - tmp |= clk; + tmp |= AUREON_SPI_CLK; snd_ice1712_gpio_write(ice, tmp); udelay(1); } @@ -599,9 +440,7 @@ static unsigned short wm_get(struct snd_ice1712 *ice, int reg) */ static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) { - aureon_spi_write(ice, - (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ? PRODIGY_WM_CS : AUREON_WM_CS), - (reg << 9) | (val & 0x1ff), 16); + aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16); } /* @@ -635,11 +474,11 @@ static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -704,9 +543,9 @@ static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -929,11 +768,11 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned short val; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; val = val > PCM_MIN ? (val - PCM_MIN) : 0; ucontrol->value.integer.value[0] = val; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -974,12 +813,12 @@ static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va unsigned short val; int i; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); for (i = 0; i < 2; i++) { val = wm_get(ice, WM_ADC_GAIN + i); ucontrol->value.integer.value[i] = ~val>>5 & 0x1; } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -1021,13 +860,13 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val int i, idx; unsigned short vol; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); for (i = 0; i < 2; i++) { idx = WM_ADC_GAIN + i; vol = wm_get(ice, idx) & 0x1f; ucontrol->value.integer.value[i] = vol; } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -1098,11 +937,11 @@ static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned short val; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); val = wm_get(ice, WM_ADC_MUX); - ucontrol->value.enumerated.item[0] = val & 7; - ucontrol->value.enumerated.item[1] = (val >> 4) & 7; - mutex_unlock(&ice->gpio_mutex); + ucontrol->value.integer.value[0] = val & 7; + ucontrol->value.integer.value[1] = (val >> 4) & 7; + up(&ice->gpio_mutex); return 0; } @@ -1115,8 +954,8 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val snd_ice1712_save_gpio_status(ice); oval = wm_get(ice, WM_ADC_MUX); nval = oval & ~0x77; - nval |= ucontrol->value.enumerated.item[0] & 7; - nval |= (ucontrol->value.enumerated.item[1] & 7) << 4; + nval |= ucontrol->value.integer.value[0] & 7; + nval |= (ucontrol->value.integer.value[1] & 7) << 4; change = (oval != nval); if (change) wm_put(ice, WM_ADC_MUX, nval); @@ -1156,7 +995,7 @@ static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e //snd_ice1712_save_gpio_status(ice); //val = aureon_cs8415_get(ice, CS8415_CTRL2); - ucontrol->value.enumerated.item[0] = ice->spec.aureon.cs8415_mux; + ucontrol->value.integer.value[0] = ice->spec.aureon.cs8415_mux; //snd_ice1712_restore_gpio_status(ice); return 0; } @@ -1170,12 +1009,12 @@ static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e snd_ice1712_save_gpio_status(ice); oval = aureon_cs8415_get(ice, CS8415_CTRL2); nval = oval & ~0x07; - nval |= ucontrol->value.enumerated.item[0] & 7; + nval |= ucontrol->value.integer.value[0] & 7; change = (oval != nval); if (change) aureon_cs8415_put(ice, CS8415_CTRL2, nval); snd_ice1712_restore_gpio_status(ice); - ice->spec.aureon.cs8415_mux = ucontrol->value.enumerated.item[0]; + ice->spec.aureon.cs8415_mux = ucontrol->value.integer.value[0]; return change; } @@ -1743,15 +1582,7 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { .get = aureon_ac97_vol_get, .put = aureon_ac97_vol_put, .private_value = AC97_VIDEO|AUREON_AC97_STEREO - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Aux Source", - .info = aureon_universe_inmux_info, - .get = aureon_universe_inmux_get, - .put = aureon_universe_inmux_put - } - + } }; @@ -1828,7 +1659,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) return err; } } - else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { + else { for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); if (err < 0) @@ -1836,7 +1667,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) } } - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { + { unsigned char id; snd_ice1712_save_gpio_status(ice); id = aureon_cs8415_get(ice, CS8415_ID); @@ -1991,8 +1822,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) udelay(1); /* initialize WM8770 codec */ - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) + if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71) p = wm_inits_prodigy; else p = wm_inits_aureon; @@ -2000,19 +1830,13 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) wm_put(ice, p[0], p[1]); /* initialize CS8415A codec */ - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { - for (p = cs_inits; *p != (unsigned short)-1; p++) - aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); - ice->spec.aureon.cs8415_mux = 1; + for (p = cs_inits; *p != (unsigned short)-1; p++) + aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); + ice->spec.aureon.cs8415_mux = 1; - aureon_set_headphone_amp(ice, 1); - } + aureon_set_headphone_amp(ice, 1); snd_ice1712_restore_gpio_status(ice); - - /* initialize PCA9554 pin directions & set default input*/ - aureon_pca9554_write(ice, PCA9554_DIR, 0x00); - aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ ice->spec.aureon.master[0] = WM_VOL_MUTE; ice->spec.aureon.master[1] = WM_VOL_MUTE; @@ -2078,23 +1902,6 @@ static unsigned char prodigy71_eeprom[] __devinitdata = { 0x00, /* GPIO_STATE2 */ }; -static unsigned char prodigy71lt_eeprom[] __devinitdata = { - 0x0b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */ - 0x80, /* ACLINK: I2S */ - 0xfc, /* I2S: vol, 96k, 24bit, 192k */ - 0xc3, /* SPDUF: out-en, out-int */ - 0x00, /* GPIO_DIR */ - 0x07, /* GPIO_DIR1 */ - 0x00, /* GPIO_DIR2 */ - 0xff, /* GPIO_MASK */ - 0xf8, /* GPIO_MASK1 */ - 0xff, /* GPIO_MASK2 */ - 0x00, /* GPIO_STATE */ - 0x00, /* GPIO_STATE1 */ - 0x00, /* GPIO_STATE2 */ -}; - - /* entry point */ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { { @@ -2137,15 +1944,5 @@ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { .eeprom_data = prodigy71_eeprom, .driver = "Prodigy71", /* should be identical with Aureon71 */ }, - { - .subvendor = VT1724_SUBDEVICE_PRODIGY71LT, - .name = "Audiotrak Prodigy 7.1 LT", - .model = "prodigy71lt", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, - .eeprom_size = sizeof(prodigy71lt_eeprom), - .eeprom_data = prodigy71lt_eeprom, - .driver = "Prodigy71LT", - }, { } /* terminator */ }; diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h index 98a675228..95d515f36 100644 --- a/sound/pci/ice1712/aureon.h +++ b/sound/pci/ice1712/aureon.h @@ -27,14 +27,12 @@ #define AUREON_DEVICE_DESC "{Terratec,Aureon 5.1 Sky},"\ "{Terratec,Aureon 7.1 Space},"\ "{Terratec,Aureon 7.1 Universe}," \ - "{AudioTrak,Prodigy 7.1}," \ - "{AudioTrak,Prodigy 7.1 LT}," + "{AudioTrak,Prodigy 7.1}," #define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */ #define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */ #define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */ #define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */ -#define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; @@ -55,8 +53,4 @@ extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; #define AUREON_AC97_DATA_HIGH (1 << 8) #define AUREON_AC97_DATA_MASK 0xFF -#define PRODIGY_WM_CS (1 << 8) -#define PRODIGY_SPI_MOSI (1 << 10) -#define PRODIGY_SPI_CLK (1 << 9) - #endif /* __SOUND_AUREON_H */ diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index af659800c..9a51d34e6 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -28,8 +28,6 @@ #include #include #include -#include - #include #include #include @@ -132,13 +130,13 @@ static int ap_cs8427_sendbytes(struct snd_i2c_device *device, unsigned char *byt int res = count; unsigned char tmp; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); tmp = ap_cs8427_codec_select(ice); ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */ while (count-- > 0) ap_cs8427_write_byte(ice, *bytes++, tmp); ap_cs8427_codec_deassert(ice, tmp); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return res; } @@ -149,13 +147,13 @@ static int ap_cs8427_readbytes(struct snd_i2c_device *device, unsigned char *byt int res = count; unsigned char tmp; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); tmp = ap_cs8427_codec_select(ice); ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */ while (count-- > 0) *bytes++ = ap_cs8427_read_byte(ice, tmp); ap_cs8427_codec_deassert(ice, tmp); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return res; } @@ -182,7 +180,7 @@ static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsign /* send byte to transmitter */ mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK; mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); for (idx = 7; idx >= 0; idx--) { tmp &= ~(mask1 | mask2); @@ -196,7 +194,7 @@ static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsign } tmp &= ~mask1; snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } @@ -298,14 +296,14 @@ static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate) if (rate == 0) /* no hint - S/PDIF input is master, simply return */ return; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); tmp2 = tmp & ~ICE1712_DELTA_DFS; if (rate > 48000) tmp2 |= ICE1712_DELTA_DFS; if (tmp != tmp2) snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } /* @@ -320,9 +318,9 @@ static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) return; /* check before reset ak4524 to avoid unnecessary clicks */ - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); tmp2 = tmp & ~ICE1712_DELTA_DFS; if (rate > 48000) tmp2 |= ICE1712_DELTA_DFS; @@ -331,12 +329,12 @@ static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) /* do it again */ snd_akm4xxx_reset(ak, 1); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS; if (rate > 48000) tmp |= ICE1712_DELTA_DFS; snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); snd_akm4xxx_reset(ak, 0); } @@ -393,37 +391,6 @@ static void delta_setup_spdif(struct snd_ice1712 *ice, int rate) snd_ice1712_delta_cs8403_spdif_write(ice, tmp); } -static int snd_ice1712_delta1010lt_wordclock_status_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - char reg = 0x10; // cs8427 receiver error register - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - - if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) - snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); - snd_i2c_readbytes(ice->cs8427, ®, 1); - ucontrol->value.integer.value[0] = (reg ? 1 : 0); - return 0; -} - -static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = -{ - .access = (SNDRV_CTL_ELEM_ACCESS_READ), - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Word Clock Status", - .info = snd_ice1712_delta1010lt_wordclock_status_info, - .get = snd_ice1712_delta1010lt_wordclock_status_get, -}; /* * initialize the chips on M-Audio cards @@ -653,7 +620,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); +ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0); static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = @@ -684,9 +651,6 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) break; case ICE1712_SUBDEVICE_DELTA1010LT: err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice)); - if (err < 0) - return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_status, ice)); if (err < 0) return err; break; diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index 3f27d04e7..3f2f91853 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -27,8 +27,6 @@ #include #include #include -#include - #include #include "ice1712.h" @@ -50,31 +48,31 @@ static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, un static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate) { - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate); snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate) { - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate); snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate) { - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate); snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate) { - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); /* select box */ ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box); @@ -117,12 +115,12 @@ static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, i ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0); snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master) { - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); /* select box */ ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box); @@ -143,15 +141,15 @@ static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1); snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) { - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate); snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice) diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index c56793b38..ef6f18558 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -53,11 +53,8 @@ #include #include #include -#include #include #include -#include - #include #include #include @@ -85,11 +82,10 @@ MODULE_SUPPORTED_DEVICE("{" static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static char *model[SNDRV_CARDS]; -static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */ +static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */ static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transciever reset timeout value in msec */ -static int dxr_enable[SNDRV_CARDS]; /* DXR enable for DMX6FIRE */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for ICE1712 soundcard."); @@ -103,11 +99,9 @@ module_param_array(cs8427_timeout, int, NULL, 0444); MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec resolution."); module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); -module_param_array(dxr_enable, int, NULL, 0444); -MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); -static struct pci_device_id snd_ice1712_ids[] __devinitdata = { +static struct pci_device_id snd_ice1712_ids[] = { { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */ { 0, } }; @@ -322,6 +316,7 @@ static void snd_ice1712_set_gpio_data(struct snd_ice1712 *ice, unsigned int val) inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */ } + /* * * CS8427 interface @@ -401,20 +396,6 @@ int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr) return 0; } -static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdif_is_master) -{ - /* change CS8427 clock source too */ - if (ice->cs8427) - snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master); - /* notify ak4524 chip as well */ - if (spdif_is_master) { - unsigned int i; - for (i = 0; i < ice->akm_codecs; i++) { - if (ice->akm[i].ops.set_rate_val) - ice->akm[i].ops.set_rate_val(&ice->akm[i], 0); - } - } -} /* * Interrupt handler @@ -1586,9 +1567,6 @@ static void snd_ice1712_proc_read(struct snd_info_entry *entry, snd_iprintf(buffer, " CAPTURE : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE))); snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT))); snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE))); - snd_iprintf(buffer, " GPIO_DATA : 0x%02x\n", (unsigned)snd_ice1712_get_gpio_data(ice)); - snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK)); - snd_iprintf(buffer, " GPIO_DIRECTION : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION)); } static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice) @@ -1878,8 +1856,20 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, spin_unlock_irq(&ice->reg_lock); if ((oval & ICE1712_SPDIF_MASTER) != - (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) - snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice)); + (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) { + /* change CS8427 clock source too */ + if (ice->cs8427) { + snd_ice1712_cs8427_set_input_clock(ice, is_spdif_master(ice)); + } + /* notify ak4524 chip as well */ + if (is_spdif_master(ice)) { + unsigned int i; + for (i = 0; i < ice->akm_codecs; i++) { + if (ice->akm[i].ops.set_rate_val) + ice->akm[i].ops.set_rate_val(&ice->akm[i], 0); + } + } + } return change; } @@ -2398,13 +2388,7 @@ static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice) udelay(200); outb(ICE1712_NATIVE, ICEREG(ice, CONTROL)); udelay(200); - if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE && !ice->dxr_enable) { - /* Limit active ADCs and DACs to 6; */ - /* Note: DXR extension not supported */ - pci_write_config_byte(ice->pci, 0x60, 0x2a); - } else { - pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]); - } + pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]); pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]); pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]); pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]); @@ -2540,7 +2524,6 @@ static int __devinit snd_ice1712_create(struct snd_card *card, const char *modelname, int omni, int cs8427_timeout, - int dxr_enable, struct snd_ice1712 ** r_ice1712) { struct snd_ice1712 *ice; @@ -2555,8 +2538,8 @@ static int __devinit snd_ice1712_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, 0x0fffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; @@ -2573,11 +2556,10 @@ static int __devinit snd_ice1712_create(struct snd_card *card, else if (cs8427_timeout > 1000) cs8427_timeout = 1000; ice->cs8427_timeout = cs8427_timeout; - ice->dxr_enable = dxr_enable; spin_lock_init(&ice->reg_lock); - mutex_init(&ice->gpio_mutex); - mutex_init(&ice->i2c_mutex); - mutex_init(&ice->open_mutex); + init_MUTEX(&ice->gpio_mutex); + init_MUTEX(&ice->i2c_mutex); + init_MUTEX(&ice->open_mutex); ice->gpio.set_mask = snd_ice1712_set_gpio_mask; ice->gpio.set_dir = snd_ice1712_set_gpio_dir; ice->gpio.set_data = snd_ice1712_set_gpio_data; @@ -2676,8 +2658,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, strcpy(card->shortname, "ICEnsemble ICE1712"); if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev], - cs8427_timeout[dev], dxr_enable[dev], - &ice)) < 0) { + cs8427_timeout[dev], &ice)) < 0) { snd_card_free(card); return err; } @@ -2754,8 +2735,6 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, } } - snd_ice1712_set_input_clock_source(ice, 0); - sprintf(card->longname, "%s at 0x%lx, irq %i", card->shortname, ice->port, ice->irq); diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index 053f8e56f..ce96b3bb6 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -325,7 +325,6 @@ struct snd_ice1712 { unsigned int pro_volumes[20]; unsigned int omni: 1; /* Delta Omni I/O */ - unsigned int dxr_enable: 1; /* Terratec DXR enable for DMX6FIRE */ unsigned int vt1724: 1; unsigned int vt1720: 1; unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */ @@ -335,7 +334,7 @@ struct snd_ice1712 { unsigned int num_total_adcs; /* total ADCs */ unsigned int cur_rate; /* current rate */ - struct mutex open_mutex; + struct semaphore open_mutex; struct snd_pcm_substream *pcm_reserved[4]; struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */ @@ -343,7 +342,7 @@ struct snd_ice1712 { struct snd_akm4xxx *akm; struct snd_ice1712_spdif spdif; - struct mutex i2c_mutex; /* I2C mutex for ICE1724 registers */ + struct semaphore i2c_mutex; /* I2C mutex for ICE1724 registers */ struct snd_i2c_bus *i2c; /* I2C bus */ struct snd_i2c_device *cs8427; /* CS8427 I2C device */ unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */ @@ -361,7 +360,7 @@ struct snd_ice1712 { void (*set_pro_rate)(struct snd_ice1712 *ice, unsigned int rate); void (*i2s_mclk_changed)(struct snd_ice1712 *ice); } gpio; - struct mutex gpio_mutex; + struct semaphore gpio_mutex; /* other board-specific data */ union { @@ -373,7 +372,6 @@ struct snd_ice1712 { unsigned int cs8415_mux; unsigned short master[2]; unsigned short vol[8]; - unsigned char pca9554_out; } aureon; /* AC97 register cache for Phase28 */ struct phase28_spec { @@ -425,7 +423,7 @@ static inline unsigned int snd_ice1712_gpio_read(struct snd_ice1712 *ice) */ static inline void snd_ice1712_save_gpio_status(struct snd_ice1712 *ice) { - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ice->gpio.saved[0] = ice->gpio.direction; ice->gpio.saved[1] = ice->gpio.write_mask; } @@ -436,7 +434,7 @@ static inline void snd_ice1712_restore_gpio_status(struct snd_ice1712 *ice) ice->gpio.set_mask(ice, ice->gpio.saved[1]); ice->gpio.direction = ice->gpio.saved[0]; ice->gpio.write_mask = ice->gpio.saved[1]; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } /* for bit controls */ diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index b1c007e02..71f08c036 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -86,7 +85,7 @@ MODULE_PARM_DESC(model, "Use the given board model."); /* Both VT1720 and VT1724 have the same PCI IDs */ -static struct pci_device_id snd_vt1724_ids[] __devinitdata = { +static struct pci_device_id snd_vt1724_ids[] = { { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, } }; @@ -488,7 +487,7 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, int i, chs; chs = params_channels(hw_params); - mutex_lock(&ice->open_mutex); + down(&ice->open_mutex); /* mark surround channels */ if (substream == ice->playback_pro_substream) { /* PDMA0 can be multi-channel up to 8 */ @@ -496,7 +495,7 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, for (i = 0; i < chs; i++) { if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) { - mutex_unlock(&ice->open_mutex); + up(&ice->open_mutex); return -EBUSY; } ice->pcm_reserved[i] = substream; @@ -511,7 +510,7 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, if (ice->playback_con_substream_ds[i] == substream) { if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) { - mutex_unlock(&ice->open_mutex); + up(&ice->open_mutex); return -EBUSY; } ice->pcm_reserved[i] = substream; @@ -519,7 +518,7 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, } } } - mutex_unlock(&ice->open_mutex); + up(&ice->open_mutex); snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0); return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } @@ -529,12 +528,12 @@ static int snd_vt1724_pcm_hw_free(struct snd_pcm_substream *substream) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); int i; - mutex_lock(&ice->open_mutex); + down(&ice->open_mutex); /* unmark surround channels */ for (i = 0; i < 3; i++) if (ice->pcm_reserved[i] == substream) ice->pcm_reserved[i] = NULL; - mutex_unlock(&ice->open_mutex); + up(&ice->open_mutex); return snd_pcm_lib_free_pages(substream); } @@ -779,7 +778,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); set_rate_constraints(ice, substream); - mutex_lock(&ice->open_mutex); + down(&ice->open_mutex); /* calculate the currently available channels */ for (chs = 0; chs < 3; chs++) { if (ice->pcm_reserved[chs]) @@ -789,7 +788,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) runtime->hw.channels_max = chs; if (chs > 2) /* channels must be even */ snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); - mutex_unlock(&ice->open_mutex); + up(&ice->open_mutex); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, VT1724_BUFFER_ALIGN); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, @@ -1129,13 +1128,13 @@ static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - mutex_lock(&ice->open_mutex); + down(&ice->open_mutex); /* already used by PDMA0? */ if (ice->pcm_reserved[substream->number]) { - mutex_unlock(&ice->open_mutex); + up(&ice->open_mutex); return -EBUSY; /* FIXME: should handle blocking mode properly */ } - mutex_unlock(&ice->open_mutex); + up(&ice->open_mutex); runtime->private_data = &vt1724_playback_dma_regs[substream->number]; ice->playback_con_substream_ds[substream->number] = substream; runtime->hw = snd_vt1724_2ch_stereo; @@ -1979,12 +1978,12 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, { unsigned char val; - mutex_lock(&ice->i2c_mutex); + down(&ice->i2c_mutex); outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); wait_i2c_busy(ice); val = inb(ICEREG1724(ice, I2C_DATA)); - mutex_unlock(&ice->i2c_mutex); + up(&ice->i2c_mutex); //printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); return val; } @@ -1992,14 +1991,14 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, void snd_vt1724_write_i2c(struct snd_ice1712 *ice, unsigned char dev, unsigned char addr, unsigned char data) { - mutex_lock(&ice->i2c_mutex); + down(&ice->i2c_mutex); wait_i2c_busy(ice); //printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); outb(data, ICEREG1724(ice, I2C_DATA)); outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); wait_i2c_busy(ice); - mutex_unlock(&ice->i2c_mutex); + up(&ice->i2c_mutex); } static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, @@ -2230,9 +2229,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card, } ice->vt1724 = 1; spin_lock_init(&ice->reg_lock); - mutex_init(&ice->gpio_mutex); - mutex_init(&ice->open_mutex); - mutex_init(&ice->i2c_mutex); + init_MUTEX(&ice->gpio_mutex); + init_MUTEX(&ice->open_mutex); + init_MUTEX(&ice->i2c_mutex); ice->gpio.set_mask = snd_vt1724_set_gpio_mask; ice->gpio.set_dir = snd_vt1724_set_gpio_dir; ice->gpio.set_data = snd_vt1724_set_gpio_data; diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index d1f908324..ec3757834 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -45,7 +45,48 @@ #include "envy24ht.h" #include "phase.h" -static akm4xxx_t akm_phase22 __devinitdata = { +/* WM8770 registers */ +#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ +#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */ +#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */ +#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */ +#define WM_PHASE_SWAP 0x12 /* DAC phase */ +#define WM_DAC_CTRL1 0x13 /* DAC control bits */ +#define WM_MUTE 0x14 /* mute controls */ +#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */ +#define WM_INT_CTRL 0x16 /* interface control */ +#define WM_MASTER 0x17 /* master clock and mode */ +#define WM_POWERDOWN 0x18 /* power-down controls */ +#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */ +#define WM_ADC_MUX 0x1b /* input MUX */ +#define WM_OUT_MUX1 0x1c /* output MUX */ +#define WM_OUT_MUX2 0x1e /* output MUX */ +#define WM_RESET 0x1f /* software reset */ + + +/* + * Logarithmic volume values for WM8770 + * Computed as 20 * Log10(255 / x) + */ +static unsigned char wm_vol[256] = { + 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, + 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, + 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, + 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +#define WM_VOL_MAX (sizeof(wm_vol) - 1) +#define WM_VOL_MUTE 0x8000 + +static struct snd_akm4xxx akm_phase22 __devinitdata = { .type = SND_AK4524, .num_dacs = 2, .num_adcs = 2, @@ -63,9 +104,9 @@ static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { .mask_flags = 0, }; -static int __devinit phase22_init(ice1712_t *ice) +static int __devinit phase22_init(struct snd_ice1712 *ice) { - akm4xxx_t *ak; + struct snd_akm4xxx *ak; int err; // Configure DAC/ADC description for generic part of ice1724 @@ -81,7 +122,7 @@ static int __devinit phase22_init(ice1712_t *ice) } // Initialize analog chips - ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL); + ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); if (! ak) return -ENOMEM; ice->akm_codecs = 1; @@ -95,7 +136,7 @@ static int __devinit phase22_init(ice1712_t *ice) return 0; } -static int __devinit phase22_add_controls(ice1712_t *ice) +static int __devinit phase22_add_controls(struct snd_ice1712 *ice) { int err = 0; @@ -124,6 +165,684 @@ static unsigned char phase22_eeprom[] __devinitdata = { 0x00, /* GPIO_STATE2 */ }; +static unsigned char phase28_eeprom[] __devinitdata = { + 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ + 0x80, /* ACLINK: I2S */ + 0xfc, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x5f, /* GPIO_DIR2 */ + 0x00, /* GPIO_MASK */ + 0x00, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* GPIO_STATE2 */ +}; + +/* + * write data in the SPI mode + */ +static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits) +{ + unsigned int tmp; + int i; + + tmp = snd_ice1712_gpio_read(ice); + + snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|PHASE28_SPI_CLK| + PHASE28_WM_CS)); + tmp |= PHASE28_WM_RW; + tmp &= ~cs; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + + for (i = bits - 1; i >= 0; i--) { + tmp &= ~PHASE28_SPI_CLK; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + if (data & (1 << i)) + tmp |= PHASE28_SPI_MOSI; + else + tmp &= ~PHASE28_SPI_MOSI; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + tmp |= PHASE28_SPI_CLK; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + } + + tmp &= ~PHASE28_SPI_CLK; + tmp |= cs; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + tmp |= PHASE28_SPI_CLK; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); +} + +/* + * get the current register value of WM codec + */ +static unsigned short wm_get(struct snd_ice1712 *ice, int reg) +{ + reg <<= 1; + return ((unsigned short)ice->akm[0].images[reg] << 8) | + ice->akm[0].images[reg + 1]; +} + +/* + * set the register value of WM codec + */ +static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) +{ + phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16); +} + +/* + * set the register value of WM codec and remember it + */ +static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) +{ + wm_put_nocache(ice, reg, val); + reg <<= 1; + ice->akm[0].images[reg] = val >> 8; + ice->akm[0].images[reg + 1] = val; +} + +static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) +{ + unsigned char nvol; + + if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) + nvol = 0; + else + nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; + + wm_put(ice, index, nvol); + wm_put_nocache(ice, index, 0x180 | nvol); +} + +/* + * DAC mute control + */ +#define wm_pcm_mute_info phase28_mono_bool_info + +static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + + down(&ice->gpio_mutex); + ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; + up(&ice->gpio_mutex); + return 0; +} + +static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned short nval, oval; + int change; + + snd_ice1712_save_gpio_status(ice); + oval = wm_get(ice, WM_MUTE); + nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10); + if ((change = (nval != oval))) + wm_put(ice, WM_MUTE, nval); + snd_ice1712_restore_gpio_status(ice); + + return change; +} + +/* + * Master volume attenuation mixer control + */ +static int wm_master_vol_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 = WM_VOL_MAX; + return 0; +} + +static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + int i; + for (i=0; i<2; i++) + ucontrol->value.integer.value[i] = ice->spec.phase28.master[i] & ~WM_VOL_MUTE; + return 0; +} + +static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + int ch, change = 0; + + snd_ice1712_save_gpio_status(ice); + for (ch = 0; ch < 2; ch++) { + if (ucontrol->value.integer.value[ch] != ice->spec.phase28.master[ch]) { + int dac; + ice->spec.phase28.master[ch] &= WM_VOL_MUTE; + ice->spec.phase28.master[ch] |= ucontrol->value.integer.value[ch]; + for (dac = 0; dac < ice->num_total_dacs; dac += 2) + wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, + ice->spec.phase28.vol[dac + ch], + ice->spec.phase28.master[ch]); + change = 1; + } + } + snd_ice1712_restore_gpio_status(ice); + return change; +} + +static int __devinit phase28_init(struct snd_ice1712 *ice) +{ + static unsigned short wm_inits_phase28[] = { + /* These come first to reduce init pop noise */ + 0x1b, 0x044, /* ADC Mux (AC'97 source) */ + 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ + 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */ + + 0x18, 0x000, /* All power-up */ + + 0x16, 0x122, /* I2S, normal polarity, 24bit */ + 0x17, 0x022, /* 256fs, slave mode */ + 0x00, 0, /* DAC1 analog mute */ + 0x01, 0, /* DAC2 analog mute */ + 0x02, 0, /* DAC3 analog mute */ + 0x03, 0, /* DAC4 analog mute */ + 0x04, 0, /* DAC5 analog mute */ + 0x05, 0, /* DAC6 analog mute */ + 0x06, 0, /* DAC7 analog mute */ + 0x07, 0, /* DAC8 analog mute */ + 0x08, 0x100, /* master analog mute */ + 0x09, 0xff, /* DAC1 digital full */ + 0x0a, 0xff, /* DAC2 digital full */ + 0x0b, 0xff, /* DAC3 digital full */ + 0x0c, 0xff, /* DAC4 digital full */ + 0x0d, 0xff, /* DAC5 digital full */ + 0x0e, 0xff, /* DAC6 digital full */ + 0x0f, 0xff, /* DAC7 digital full */ + 0x10, 0xff, /* DAC8 digital full */ + 0x11, 0x1ff, /* master digital full */ + 0x12, 0x000, /* phase normal */ + 0x13, 0x090, /* unmute DAC L/R */ + 0x14, 0x000, /* all unmute */ + 0x15, 0x000, /* no deemphasis, no ZFLG */ + 0x19, 0x000, /* -12dB ADC/L */ + 0x1a, 0x000, /* -12dB ADC/R */ + (unsigned short)-1 + }; + + unsigned int tmp; + struct snd_akm4xxx *ak; + unsigned short *p; + int i; + + ice->num_total_dacs = 8; + ice->num_total_adcs = 2; + + // Initialize analog chips + ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + if (!ak) + return -ENOMEM; + ice->akm_codecs = 1; + + snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */ + + /* reset the wm codec as the SPI mode */ + snd_ice1712_save_gpio_status(ice); + snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|PHASE28_HP_SEL)); + + tmp = snd_ice1712_gpio_read(ice); + tmp &= ~PHASE28_WM_RESET; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + tmp |= PHASE28_WM_CS; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + tmp |= PHASE28_WM_RESET; + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + + p = wm_inits_phase28; + for (; *p != (unsigned short)-1; p += 2) + wm_put(ice, p[0], p[1]); + + snd_ice1712_restore_gpio_status(ice); + + ice->spec.phase28.master[0] = WM_VOL_MUTE; + ice->spec.phase28.master[1] = WM_VOL_MUTE; + for (i = 0; i < ice->num_total_dacs; i++) { + ice->spec.phase28.vol[i] = WM_VOL_MUTE; + wm_set_vol(ice, i, ice->spec.phase28.vol[i], ice->spec.phase28.master[i % 2]); + } + + return 0; +} + +/* + * DAC volume attenuation mixer control + */ +static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + int voices = kcontrol->private_value >> 8; + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = voices; + uinfo->value.integer.min = 0; /* mute (-101dB) */ + uinfo->value.integer.max = 0x7F; /* 0dB */ + return 0; +} + +static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + int i, ofs, voices; + + voices = kcontrol->private_value >> 8; + ofs = kcontrol->private_value & 0xff; + for (i = 0; i < voices; i++) + ucontrol->value.integer.value[i] = ice->spec.phase28.vol[ofs+i] & ~WM_VOL_MUTE; + return 0; +} + +static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + int i, idx, ofs, voices; + int change = 0; + + voices = kcontrol->private_value >> 8; + ofs = kcontrol->private_value & 0xff; + snd_ice1712_save_gpio_status(ice); + for (i = 0; i < voices; i++) { + idx = WM_DAC_ATTEN + ofs + i; + if (ucontrol->value.integer.value[i] != ice->spec.phase28.vol[ofs+i]) { + ice->spec.phase28.vol[ofs+i] &= WM_VOL_MUTE; + ice->spec.phase28.vol[ofs+i] |= ucontrol->value.integer.value[i]; + wm_set_vol(ice, idx, ice->spec.phase28.vol[ofs+i], + ice->spec.phase28.master[i]); + change = 1; + } + } + snd_ice1712_restore_gpio_status(ice); + return change; +} + +/* + * WM8770 mute control + */ +static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = kcontrol->private_value >> 8; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + int voices, ofs, i; + + voices = kcontrol->private_value >> 8; + ofs = kcontrol->private_value & 0xFF; + + for (i = 0; i < voices; i++) + ucontrol->value.integer.value[i] = (ice->spec.phase28.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1; + return 0; +} + +static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + int change = 0, voices, ofs, i; + + voices = kcontrol->private_value >> 8; + ofs = kcontrol->private_value & 0xFF; + + snd_ice1712_save_gpio_status(ice); + for (i = 0; i < voices; i++) { + int val = (ice->spec.phase28.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1; + if (ucontrol->value.integer.value[i] != val) { + ice->spec.phase28.vol[ofs + i] &= ~WM_VOL_MUTE; + ice->spec.phase28.vol[ofs + i] |= + ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; + wm_set_vol(ice, ofs + i, ice->spec.phase28.vol[ofs + i], + ice->spec.phase28.master[i]); + change = 1; + } + } + snd_ice1712_restore_gpio_status(ice); + + return change; +} + +/* + * WM8770 master mute control + */ +static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = (ice->spec.phase28.master[0] & WM_VOL_MUTE) ? 0 : 1; + ucontrol->value.integer.value[1] = (ice->spec.phase28.master[1] & WM_VOL_MUTE) ? 0 : 1; + return 0; +} + +static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + int change = 0, i; + + snd_ice1712_save_gpio_status(ice); + for (i = 0; i < 2; i++) { + int val = (ice->spec.phase28.master[i] & WM_VOL_MUTE) ? 0 : 1; + if (ucontrol->value.integer.value[i] != val) { + int dac; + ice->spec.phase28.master[i] &= ~WM_VOL_MUTE; + ice->spec.phase28.master[i] |= + ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; + for (dac = 0; dac < ice->num_total_dacs; dac += 2) + wm_set_vol(ice, WM_DAC_ATTEN + dac + i, + ice->spec.phase28.vol[dac + i], + ice->spec.phase28.master[i]); + change = 1; + } + } + snd_ice1712_restore_gpio_status(ice); + + return change; +} + +/* digital master volume */ +#define PCM_0dB 0xff +#define PCM_RES 128 /* -64dB */ +#define PCM_MIN (PCM_0dB - PCM_RES) +static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; /* mute (-64dB) */ + uinfo->value.integer.max = PCM_RES; /* 0dB */ + return 0; +} + +static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned short val; + + down(&ice->gpio_mutex); + val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; + val = val > PCM_MIN ? (val - PCM_MIN) : 0; + ucontrol->value.integer.value[0] = val; + up(&ice->gpio_mutex); + return 0; +} + +static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned short ovol, nvol; + int change = 0; + + snd_ice1712_save_gpio_status(ice); + nvol = ucontrol->value.integer.value[0]; + nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; + ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; + if (ovol != nvol) { + wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */ + wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */ + change = 1; + } + snd_ice1712_restore_gpio_status(ice); + return change; +} + +/* + */ +static int phase28_mono_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +/* + * Deemphasis + */ +#define phase28_deemp_info phase28_mono_bool_info + +static int phase28_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf; + return 0; +} + +static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + int temp, temp2; + temp2 = temp = wm_get(ice, WM_DAC_CTRL2); + if (ucontrol->value.integer.value[0]) + temp |= 0xf; + else + temp &= ~0xf; + if (temp != temp2) { + wm_put(ice, WM_DAC_CTRL2, temp); + return 1; + } + return 0; +} + +/* + * ADC Oversampling + */ +static int phase28_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) +{ + static char *texts[2] = { "128x", "64x" }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + + return 0; +} + +static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8; + return 0; +} + +static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + int temp, temp2; + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + + temp2 = temp = wm_get(ice, WM_MASTER); + + if (ucontrol->value.enumerated.item[0]) + temp |= 0x8; + else + temp &= ~0x8; + + if (temp != temp2) { + wm_put(ice, WM_MASTER, temp); + return 1; + } + return 0; +} + +static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = wm_master_mute_info, + .get = wm_master_mute_get, + .put = wm_master_mute_put + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Volume", + .info = wm_master_vol_info, + .get = wm_master_vol_get, + .put = wm_master_vol_put + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Front Playback Switch", + .info = wm_mute_info, + .get = wm_mute_get, + .put = wm_mute_put, + .private_value = (2 << 8) | 0 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Front Playback Volume", + .info = wm_vol_info, + .get = wm_vol_get, + .put = wm_vol_put, + .private_value = (2 << 8) | 0 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Rear Playback Switch", + .info = wm_mute_info, + .get = wm_mute_get, + .put = wm_mute_put, + .private_value = (2 << 8) | 2 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Rear Playback Volume", + .info = wm_vol_info, + .get = wm_vol_get, + .put = wm_vol_put, + .private_value = (2 << 8) | 2 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Center Playback Switch", + .info = wm_mute_info, + .get = wm_mute_get, + .put = wm_mute_put, + .private_value = (1 << 8) | 4 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Center Playback Volume", + .info = wm_vol_info, + .get = wm_vol_get, + .put = wm_vol_put, + .private_value = (1 << 8) | 4 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "LFE Playback Switch", + .info = wm_mute_info, + .get = wm_mute_get, + .put = wm_mute_put, + .private_value = (1 << 8) | 5 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "LFE Playback Volume", + .info = wm_vol_info, + .get = wm_vol_get, + .put = wm_vol_put, + .private_value = (1 << 8) | 5 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Side Playback Switch", + .info = wm_mute_info, + .get = wm_mute_get, + .put = wm_mute_put, + .private_value = (2 << 8) | 6 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Side Playback Volume", + .info = wm_vol_info, + .get = wm_vol_get, + .put = wm_vol_put, + .private_value = (2 << 8) | 6 + } +}; + +static struct snd_kcontrol_new wm_controls[] __devinitdata = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Switch", + .info = wm_pcm_mute_info, + .get = wm_pcm_mute_get, + .put = wm_pcm_mute_put + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Volume", + .info = wm_pcm_vol_info, + .get = wm_pcm_vol_get, + .put = wm_pcm_vol_put + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "DAC Deemphasis Switch", + .info = phase28_deemp_info, + .get = phase28_deemp_get, + .put = phase28_deemp_put + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "ADC Oversampling", + .info = phase28_oversampling_info, + .get = phase28_oversampling_get, + .put = phase28_oversampling_put + } +}; + +static int __devinit phase28_add_controls(struct snd_ice1712 *ice) +{ + unsigned int i, counts; + int err; + + counts = ARRAY_SIZE(phase28_dac_controls); + for (i = 0; i < counts; i++) { + err = snd_ctl_add(ice->card, snd_ctl_new1(&phase28_dac_controls[i], ice)); + if (err < 0) + return err; + } + + for (i = 0; i < ARRAY_SIZE(wm_controls); i++) { + err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice)); + if (err < 0) + return err; + } + + return 0; +} + struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_PHASE22, @@ -134,5 +853,14 @@ struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { .eeprom_size = sizeof(phase22_eeprom), .eeprom_data = phase22_eeprom, }, + { + .subvendor = VT1724_SUBDEVICE_PHASE28, + .name = "Terratec PHASE 28", + .model = "phase28", + .chip_init = phase28_init, + .build_controls = phase28_add_controls, + .eeprom_size = sizeof(phase28_eeprom), + .eeprom_data = phase28_eeprom, + }, { } /* terminator */ }; diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index d23fb3fc2..0dccd7707 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -27,8 +27,6 @@ #include #include #include -#include - #include #include @@ -126,13 +124,13 @@ static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val unsigned short val; int i; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); for (i = 0; i < 2; i++) { val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff; val = val > DAC_MIN ? (val - DAC_MIN) : 0; ucontrol->value.integer.value[i] = val; } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -142,7 +140,7 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val unsigned short oval, nval; int i, idx, change = 0; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); for (i = 0; i < 2; i++) { nval = ucontrol->value.integer.value[i]; nval = (nval ? (nval + DAC_MIN) : 0) & 0xff; @@ -154,7 +152,7 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val change = 1; } } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return change; } @@ -181,13 +179,13 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val unsigned short val; int i; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); for (i = 0; i < 2; i++) { val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff; val = val > ADC_MIN ? (val - ADC_MIN) : 0; ucontrol->value.integer.value[i] = val; } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -197,7 +195,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val unsigned short ovol, nvol; int i, idx, change = 0; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); for (i = 0; i < 2; i++) { nvol = ucontrol->value.integer.value[i]; nvol = nvol ? (nvol + ADC_MIN) : 0; @@ -208,7 +206,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val change = 1; } } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return change; } @@ -229,9 +227,9 @@ static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int bit = kcontrol->private_value; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -242,7 +240,7 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val unsigned short oval, nval; int change; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); nval = oval = wm_get(ice, WM_ADC_MUX); if (ucontrol->value.integer.value[0]) nval |= (1 << bit); @@ -252,7 +250,7 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val if (change) { wm_put(ice, WM_ADC_MUX, nval); } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -272,9 +270,9 @@ static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -284,7 +282,7 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu unsigned short val, oval; int change = 0; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); val = oval = wm_get(ice, WM_OUT_MUX); if (ucontrol->value.integer.value[0]) val |= 0x04; @@ -294,7 +292,7 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu wm_put(ice, WM_OUT_MUX, val); change = 1; } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return change; } @@ -314,9 +312,9 @@ static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -326,7 +324,7 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu unsigned short val, oval; int change = 0; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); oval = wm_get(ice, WM_DAC_CTRL1); val = oval & 0x0f; if (ucontrol->value.integer.value[0]) @@ -338,7 +336,7 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu wm_put_nocache(ice, WM_DAC_CTRL1, val); change = 1; } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return change; } @@ -451,9 +449,9 @@ static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); ucontrol->value.enumerated.item[0] = ice->gpio.saved[0]; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -463,14 +461,14 @@ static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu unsigned char val; int change = 0; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) { ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3; val = 0x80 | (ice->gpio.saved[0] << 3); spi_write(ice, CS_DEV, 0x04, val); change = 1; } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -490,10 +488,10 @@ static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_e static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); /* 4-7 reserved */ ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -502,22 +500,22 @@ static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned int val; int changed; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); /* 4-7 reserved */ val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0; changed = val != ice->gpio.write_mask; ice->gpio.write_mask = val; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return changed; } static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); /* 4-7 reserved */ ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -526,23 +524,23 @@ static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned int val; int changed; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); /* 4-7 reserved */ val = ucontrol->value.integer.value[0] & 0xff0f; changed = (val != ice->gpio.direction); ice->gpio.direction = val; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return changed; } static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff; - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return 0; } @@ -551,7 +549,7 @@ static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned int val, nval; int changed = 0; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); val = snd_ice1712_gpio_read(ice) & 0xffff; @@ -560,7 +558,7 @@ static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el snd_ice1712_gpio_write(ice, nval); changed = 1; } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); return changed; } @@ -653,14 +651,14 @@ static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buf struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; char line[64]; unsigned int reg, val; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); while (!snd_info_get_line(buffer, line, sizeof(line))) { if (sscanf(line, "%x %x", ®, &val) != 2) continue; if (reg <= 0x17 && val <= 0xffff) wm_put(ice, reg, val); } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) @@ -668,12 +666,12 @@ static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buff struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; int reg, val; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); for (reg = 0; reg <= 0x17; reg++) { val = wm_get(ice, reg); snd_iprintf(buffer, "%02x = %04x\n", reg, val); } - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static void wm_proc_init(struct snd_ice1712 *ice) @@ -692,14 +690,14 @@ static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buff struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; int reg, val; - mutex_lock(&ice->gpio_mutex); + down(&ice->gpio_mutex); for (reg = 0; reg <= 0x26; reg++) { val = spi_read(ice, CS_DEV, reg); snd_iprintf(buffer, "%02x = %02x\n", reg, val); } val = spi_read(ice, CS_DEV, 0x7f); snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val); - mutex_unlock(&ice->gpio_mutex); + up(&ice->gpio_mutex); } static void cs_proc_init(struct snd_ice1712 *ice) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 0df760256..174237f4a 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -178,8 +178,6 @@ DEFINE_REGSET(SP, 0x60); /* SPDIF out */ #define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */ #define ICH_SAMPLE_16_20 0x00400000 /* ICH4: 16- and 20-bit samples */ #define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */ -#define ICH_SIS_TRI 0x00080000 /* SIS: tertiary resume irq */ -#define ICH_SIS_TCR 0x00040000 /* SIS: tertiary codec ready */ #define ICH_MD3 0x00020000 /* modem power down semaphore */ #define ICH_AD3 0x00010000 /* audio power down semaphore */ #define ICH_RCS 0x00008000 /* read completion status */ @@ -400,10 +398,6 @@ struct intel8x0 { struct snd_ac97_bus *ac97_bus; struct snd_ac97 *ac97[3]; unsigned int ac97_sdin[3]; - unsigned int max_codecs, ncodecs; - unsigned int *codec_bit; - unsigned int codec_isr_bits; - unsigned int codec_ready_bits; spinlock_t reg_lock; @@ -413,7 +407,7 @@ struct intel8x0 { u32 int_sta_mask; /* interrupt status mask */ }; -static struct pci_device_id snd_intel8x0_ids[] __devinitdata = { +static struct pci_device_id snd_intel8x0_ids[] = { { 0x8086, 0x2415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */ { 0x8086, 0x2425, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */ { 0x8086, 0x2445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */ @@ -522,6 +516,18 @@ static void iaputword(struct intel8x0 *chip, u32 offset, u16 val) * access to AC97 codec via normal i/o (for ICH and SIS7012) */ +/* return the GLOB_STA bit for the corresponding codec */ +static unsigned int get_ich_codec_bit(struct intel8x0 *chip, unsigned int codec) +{ + static unsigned int codec_bit[3] = { + ICH_PCR, ICH_SCR, ICH_TCR + }; + snd_assert(codec < 3, return ICH_PCR); + if (chip->device_type == DEVICE_INTEL_ICH4) + codec = chip->ac97_sdin[codec]; + return codec_bit[codec]; +} + static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int codec) { int time; @@ -531,9 +537,9 @@ static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int code if (chip->in_sdin_init) { /* we don't know the ready bit assignment at the moment */ /* so we check any */ - codec = chip->codec_isr_bits; + codec = ICH_PCR | ICH_SCR | ICH_TCR; } else { - codec = chip->codec_bit[chip->ac97_sdin[codec]]; + codec = get_ich_codec_bit(chip, codec); } /* codec ready ? */ @@ -590,7 +596,7 @@ static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97, if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) { /* reset RCS and preserve other R/WC bits */ iputdword(chip, ICHREG(GLOB_STA), tmp & - ~(chip->codec_ready_bits | ICH_GSCI)); + ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI)); if (! chip->in_ac97_init) snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg); res = 0xffff; @@ -599,8 +605,7 @@ static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97, return res; } -static void __devinit snd_intel8x0_codec_read_test(struct intel8x0 *chip, - unsigned int codec) +static void snd_intel8x0_codec_read_test(struct intel8x0 *chip, unsigned int codec) { unsigned int tmp; @@ -609,7 +614,7 @@ static void __devinit snd_intel8x0_codec_read_test(struct intel8x0 *chip, if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) { /* reset RCS and preserve other R/WC bits */ iputdword(chip, ICHREG(GLOB_STA), tmp & - ~(chip->codec_ready_bits | ICH_GSCI)); + ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI)); } } } @@ -1293,7 +1298,6 @@ static int snd_intel8x0_ali_ac97spdifout_close(struct snd_pcm_substream *substre return 0; } -#if 0 // NYI static int snd_intel8x0_ali_spdifin_open(struct snd_pcm_substream *substream) { struct intel8x0 *chip = snd_pcm_substream_chip(substream); @@ -1309,6 +1313,7 @@ static int snd_intel8x0_ali_spdifin_close(struct snd_pcm_substream *substream) return 0; } +#if 0 // NYI static int snd_intel8x0_ali_spdifout_open(struct snd_pcm_substream *substream) { struct intel8x0 *chip = snd_pcm_substream_chip(substream); @@ -1435,7 +1440,6 @@ static struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -#if 0 // NYI static struct snd_pcm_ops snd_intel8x0_ali_spdifin_ops = { .open = snd_intel8x0_ali_spdifin_open, .close = snd_intel8x0_ali_spdifin_close, @@ -1447,6 +1451,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_spdifin_ops = { .pointer = snd_intel8x0_pcm_pointer, }; +#if 0 // NYI static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = { .open = snd_intel8x0_ali_spdifout_open, .close = snd_intel8x0_ali_spdifout_close, @@ -1582,7 +1587,7 @@ static struct ich_pcm_table ali_pcms[] __devinitdata = { { .suffix = "IEC958", .playback_ops = &snd_intel8x0_ali_ac97spdifout_ops, - /* .capture_ops = &snd_intel8x0_ali_spdifin_ops, */ + .capture_ops = &snd_intel8x0_ali_spdifin_ops, .prealloc_size = 64 * 1024, .prealloc_max_size = 128 * 1024, .ac97_idx = ALID_AC97SPDIFOUT, @@ -2073,24 +2078,23 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, if (chip->device_type != DEVICE_ALI) { glob_sta = igetdword(chip, ICHREG(GLOB_STA)); ops = &standard_bus_ops; - chip->in_sdin_init = 1; - codecs = 0; - for (i = 0; i < chip->max_codecs; i++) { - if (! (glob_sta & chip->codec_bit[i])) - continue; - if (chip->device_type == DEVICE_INTEL_ICH4) { - snd_intel8x0_codec_read_test(chip, codecs); - chip->ac97_sdin[codecs] = - igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK; - snd_assert(chip->ac97_sdin[codecs] < 3, - chip->ac97_sdin[codecs] = 0); - } else - chip->ac97_sdin[codecs] = i; - codecs++; + if (chip->device_type == DEVICE_INTEL_ICH4) { + codecs = 0; + if (glob_sta & ICH_PCR) + codecs++; + if (glob_sta & ICH_SCR) + codecs++; + if (glob_sta & ICH_TCR) + codecs++; + chip->in_sdin_init = 1; + for (i = 0; i < codecs; i++) { + snd_intel8x0_codec_read_test(chip, i); + chip->ac97_sdin[i] = igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK; + } + chip->in_sdin_init = 0; + } else { + codecs = glob_sta & ICH_SCR ? 2 : 1; } - chip->in_sdin_init = 0; - if (! codecs) - codecs = 1; } else { ops = &ali_bus_ops; codecs = 1; @@ -2116,7 +2120,6 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, else pbus->dra = 1; chip->ac97_bus = pbus; - chip->ncodecs = codecs; ac97.pci = chip->pci; for (i = 0; i < codecs; i++) { @@ -2261,7 +2264,7 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) end_time = jiffies + HZ; do { status = igetdword(chip, ICHREG(GLOB_STA)) & - chip->codec_isr_bits; + (ICH_PCR | ICH_SCR | ICH_TCR); if (status) break; schedule_timeout_uninterruptible(1); @@ -2273,27 +2276,32 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) return -EIO; } + if (chip->device_type == DEVICE_INTEL_ICH4) + /* ICH4 can have three codecs */ + nstatus = ICH_PCR | ICH_SCR | ICH_TCR; + else + /* others up to two codecs */ + nstatus = ICH_PCR | ICH_SCR; + /* wait for other codecs ready status. */ end_time = jiffies + HZ / 4; - while (status != chip->codec_isr_bits && - time_after_eq(end_time, jiffies)) { + while (status != nstatus && time_after_eq(end_time, jiffies)) { schedule_timeout_uninterruptible(1); - status |= igetdword(chip, ICHREG(GLOB_STA)) & - chip->codec_isr_bits; + status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus; } } else { /* resume phase */ int i; status = 0; - for (i = 0; i < chip->ncodecs; i++) + for (i = 0; i < 3; i++) if (chip->ac97[i]) - status |= chip->codec_bit[chip->ac97_sdin[i]]; + status |= get_ich_codec_bit(chip, i); /* wait until all the probed codecs are ready */ end_time = jiffies + HZ; do { nstatus = igetdword(chip, ICHREG(GLOB_STA)) & - chip->codec_isr_bits; + (ICH_PCR | ICH_SCR | ICH_TCR); if (status == nstatus) break; schedule_timeout_uninterruptible(1); @@ -2351,7 +2359,7 @@ static int snd_intel8x0_ali_chip_init(struct intel8x0 *chip, int probing) static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing) { - unsigned int i, timeout; + unsigned int i; int err; if (chip->device_type != DEVICE_ALI) { @@ -2369,15 +2377,6 @@ static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing) /* reset channels */ for (i = 0; i < chip->bdbars_count; i++) iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS); - for (i = 0; i < chip->bdbars_count; i++) { - timeout = 100000; - while (--timeout != 0) { - if ((igetbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset) & ICH_RESETREGS) == 0) - break; - } - if (timeout == 0) - printk(KERN_ERR "intel8x0: reset of registers failed?\n"); - } /* initialize Buffer Descriptor Lists */ for (i = 0; i < chip->bdbars_count; i++) iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, @@ -2448,7 +2447,7 @@ static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state) } } } - for (i = 0; i < chip->ncodecs; i++) + for (i = 0; i < 3; i++) snd_ac97_suspend(chip->ac97[i]); if (chip->device_type == DEVICE_INTEL_ICH4) chip->sdm_saved = igetbyte(chip, ICHREG(SDM)); @@ -2489,7 +2488,7 @@ static int intel8x0_resume(struct pci_dev *pci) if (chip->fix_nocache) fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1); - for (i = 0; i < chip->ncodecs; i++) + for (i = 0; i < 3; i++) snd_ac97_resume(chip->ac97[i]); /* refill nocache */ @@ -2620,20 +2619,12 @@ static void snd_intel8x0_proc_read(struct snd_info_entry * entry, snd_iprintf(buffer, "Global status : 0x%08x\n", tmp); if (chip->device_type == DEVICE_INTEL_ICH4) snd_iprintf(buffer, "SDM : 0x%08x\n", igetdword(chip, ICHREG(SDM))); - snd_iprintf(buffer, "AC'97 codecs ready :"); - if (tmp & chip->codec_isr_bits) { - int i; - static const char *codecs[3] = { - "primary", "secondary", "tertiary" - }; - for (i = 0; i < chip->max_codecs; i++) - if (tmp & chip->codec_bit[i]) - snd_iprintf(buffer, " %s", codecs[i]); - } else - snd_iprintf(buffer, " none"); - snd_iprintf(buffer, "\n"); - if (chip->device_type == DEVICE_INTEL_ICH4 || - chip->device_type == DEVICE_SIS) + snd_iprintf(buffer, "AC'97 codecs ready :%s%s%s%s\n", + tmp & ICH_PCR ? " primary" : "", + tmp & ICH_SCR ? " secondary" : "", + tmp & ICH_TCR ? " tertiary" : "", + (tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : ""); + if (chip->device_type == DEVICE_INTEL_ICH4) snd_iprintf(buffer, "AC'97 codecs SDIN : %i %i %i\n", chip->ac97_sdin[0], chip->ac97_sdin[1], @@ -2662,13 +2653,6 @@ struct ich_reg_info { unsigned int offset; }; -static unsigned int ich_codec_bits[3] = { - ICH_PCR, ICH_SCR, ICH_TCR -}; -static unsigned int sis_codec_bits[3] = { - ICH_PCR, ICH_SCR, ICH_SIS_TCR -}; - static int __devinit snd_intel8x0_create(struct snd_card *card, struct pci_dev *pci, unsigned long device_type, @@ -2851,29 +2835,6 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, pci_set_master(pci); synchronize_irq(chip->irq); - switch(chip->device_type) { - case DEVICE_INTEL_ICH4: - /* ICH4 can have three codecs */ - chip->max_codecs = 3; - chip->codec_bit = ich_codec_bits; - chip->codec_ready_bits = ICH_PRI | ICH_SRI | ICH_TRI; - break; - case DEVICE_SIS: - /* recent SIS7012 can have three codecs */ - chip->max_codecs = 3; - chip->codec_bit = sis_codec_bits; - chip->codec_ready_bits = ICH_PRI | ICH_SRI | ICH_SIS_TRI; - break; - default: - /* others up to two codecs */ - chip->max_codecs = 2; - chip->codec_bit = ich_codec_bits; - chip->codec_ready_bits = ICH_PRI | ICH_SRI; - break; - } - for (i = 0; i < chip->max_codecs; i++) - chip->codec_isr_bits |= chip->codec_bit[i]; - if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) { snd_intel8x0_free(chip); return err; diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 720635f0c..47e26aaa9 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -224,7 +224,7 @@ struct intel8x0m { unsigned int pcm_pos_shift; }; -static struct pci_device_id snd_intel8x0m_ids[] __devinitdata = { +static struct pci_device_id snd_intel8x0m_ids[] = { { 0x8086, 0x2416, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */ { 0x8086, 0x2426, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */ { 0x8086, 0x2446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */ diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index e39fad1a4..4eddb512c 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -326,7 +325,7 @@ struct snd_korg1212 { int irq; spinlock_t lock; - struct mutex open_mutex; + struct semaphore open_mutex; struct timer_list timer; /* timer callback for checking ack of stop request */ int stop_pending_cnt; /* counter for stop pending check */ @@ -424,7 +423,7 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard."); MODULE_AUTHOR("Haroldo Gamal "); -static struct pci_device_id snd_korg1212_ids[] __devinitdata = { +static struct pci_device_id snd_korg1212_ids[] = { { .vendor = 0x10b5, .device = 0x906d, @@ -668,13 +667,13 @@ static int snd_korg1212_OpenCard(struct snd_korg1212 * korg1212) { K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt); - mutex_lock(&korg1212->open_mutex); + down(&korg1212->open_mutex); if (korg1212->opencnt++ == 0) { snd_korg1212_TurnOffIdleMonitor(korg1212); snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN); } - mutex_unlock(&korg1212->open_mutex); + up(&korg1212->open_mutex); return 1; } @@ -683,9 +682,9 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212) K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt); - mutex_lock(&korg1212->open_mutex); + down(&korg1212->open_mutex); if (--(korg1212->opencnt)) { - mutex_unlock(&korg1212->open_mutex); + up(&korg1212->open_mutex); return 0; } @@ -696,7 +695,7 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212) K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n", rc, stateName[korg1212->cardState]); if (rc != K1212_CMDRET_Success) { - mutex_unlock(&korg1212->open_mutex); + up(&korg1212->open_mutex); return 0; } } else if (korg1212->cardState > K1212_STATE_SETUP) { @@ -708,7 +707,7 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212) snd_korg1212_setCardState(korg1212, K1212_STATE_READY); } - mutex_unlock(&korg1212->open_mutex); + up(&korg1212->open_mutex); return 0; } @@ -2180,7 +2179,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * init_waitqueue_head(&korg1212->wait); spin_lock_init(&korg1212->lock); - mutex_init(&korg1212->open_mutex); + init_MUTEX(&korg1212->open_mutex); init_timer(&korg1212->timer); korg1212->timer.function = snd_korg1212_timer_func; korg1212->timer.data = (unsigned long)korg1212; diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 1928e06b6..d3ef0cc6c 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -830,8 +829,8 @@ struct snd_m3 { struct snd_pcm *pcm; struct pci_dev *pci; - const struct m3_quirk *quirk; - const struct m3_hv_quirk *hv_quirk; + struct m3_quirk *quirk; + struct m3_hv_quirk *hv_quirk; int dacs_active; int timer_users; @@ -869,7 +868,7 @@ struct snd_m3 { /* * pci ids */ -static struct pci_device_id snd_m3_ids[] __devinitdata = { +static struct pci_device_id snd_m3_ids[] = { {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID, @@ -891,7 +890,7 @@ static struct pci_device_id snd_m3_ids[] __devinitdata = { MODULE_DEVICE_TABLE(pci, snd_m3_ids); -static const struct m3_quirk m3_quirk_list[] = { +static struct m3_quirk m3_quirk_list[] = { /* panasonic CF-28 "toughbook" */ { .name = "Panasonic CF-28", @@ -949,7 +948,7 @@ static const struct m3_quirk m3_quirk_list[] = { }; /* These values came from the Windows driver. */ -static const struct m3_hv_quirk m3_hv_quirk_list[] = { +static struct m3_hv_quirk m3_hv_quirk_list[] = { /* Allegro chips */ { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, @@ -1360,7 +1359,7 @@ static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s, } -static const struct play_vals { +static struct play_vals { u16 addr, val; } pv[] = { {CDATA_LEFT_VOLUME, ARB_VOLUME}, @@ -1427,7 +1426,7 @@ snd_m3_playback_setup(struct snd_m3 *chip, struct m3_dma *s, /* * Native record driver */ -static const struct rec_vals { +static struct rec_vals { u16 addr, val; } rv[] = { {CDATA_LEFT_VOLUME, ARB_VOLUME}, @@ -1597,26 +1596,12 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s) if (! s->running) return; - hwptr = snd_m3_get_pointer(chip, s, subs); - - /* try to avoid expensive modulo divisions */ - if (hwptr >= s->dma_size) - hwptr %= s->dma_size; - - diff = s->dma_size + hwptr - s->hwptr; - if (diff >= s->dma_size) - diff %= s->dma_size; - + hwptr = snd_m3_get_pointer(chip, s, subs) % s->dma_size; + diff = (s->dma_size + hwptr - s->hwptr) % s->dma_size; s->hwptr = hwptr; s->count += diff; - if (s->count >= (signed)s->period_size) { - - if (s->count < 2 * (signed)s->period_size) - s->count -= (signed)s->period_size; - else - s->count %= s->period_size; - + s->count %= s->period_size; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(subs); spin_lock(&chip->reg_lock); @@ -1955,7 +1940,6 @@ static int snd_m3_ac97_wait(struct snd_m3 *chip) do { if (! (snd_m3_inb(chip, 0x30) & 1)) return 0; - cpu_relax(); } while (i-- > 0); snd_printk(KERN_ERR "ac97 serial bus busy\n"); @@ -1967,18 +1951,16 @@ snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { struct snd_m3 *chip = ac97->private_data; unsigned long flags; - unsigned short data = 0xffff; + unsigned short data; if (snd_m3_ac97_wait(chip)) - goto fail; + return 0xffff; spin_lock_irqsave(&chip->ac97_lock, flags); snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); if (snd_m3_ac97_wait(chip)) - goto fail_unlock; + return 0xffff; data = snd_m3_inw(chip, CODEC_DATA); -fail_unlock: spin_unlock_irqrestore(&chip->ac97_lock, flags); -fail: return data; } @@ -2137,7 +2119,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) * DSP Code images */ -static const u16 assp_kernel_image[] __devinitdata = { +static u16 assp_kernel_image[] __devinitdata = { 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, @@ -2224,7 +2206,7 @@ static const u16 assp_kernel_image[] __devinitdata = { * Mini sample rate converter code image * that is to be loaded at 0x400 on the DSP. */ -static const u16 assp_minisrc_image[] __devinitdata = { +static u16 assp_minisrc_image[] __devinitdata = { 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, @@ -2267,7 +2249,7 @@ static const u16 assp_minisrc_image[] __devinitdata = { */ #define MINISRC_LPF_LEN 10 -static const u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = { +static u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = { 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C, 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F }; @@ -2374,7 +2356,7 @@ static int __devinit snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma */ /* - * align instance address to 256 bytes so that its + * align instance address to 256 bytes so that it's * shifted list address is aligned. * list address = (mem address >> 1) >> 7; */ @@ -2663,8 +2645,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, { struct snd_m3 *chip; int i, err; - const struct m3_quirk *quirk; - const struct m3_hv_quirk *hv_quirk; + struct m3_quirk *quirk; + struct m3_hv_quirk *hv_quirk; static struct snd_device_ops ops = { .dev_free = snd_m3_dev_free, }; @@ -2675,8 +2657,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, 0x0fffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; @@ -2859,12 +2841,12 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) } #if 0 /* TODO: not supported yet */ - /* TODO enable MIDI IRQ and I/O */ + /* TODO enable midi irq and i/o */ err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, chip->iobase + MPU401_DATA_PORT, 1, chip->irq, 0, &chip->rmidi); if (err < 0) - printk(KERN_WARNING "maestro3: no MIDI support.\n"); + printk(KERN_WARNING "maestro3: no midi support.\n"); #endif pci_set_drvdata(pci, card); diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 09cc07864..b218e1d20 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -25,10 +25,7 @@ #include #include #include -#include #include -#include - #include #include #include @@ -61,7 +58,7 @@ MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard."); /* */ -static struct pci_device_id snd_mixart_ids[] __devinitdata = { +static struct pci_device_id snd_mixart_ids[] = { { 0x1057, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* MC8240 */ { 0, } }; @@ -592,7 +589,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs, /* set up format for the stream */ format = params_format(hw); - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); /* update the stream levels */ if( stream->pcm_number <= MIXART_PCM_DIGITAL ) { @@ -631,7 +628,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs, bufferinfo[i].available_length, subs->number); } - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return err; } @@ -703,7 +700,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs) int err = 0; int pcm_number; - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); if ( pcm == chip->pcm ) { pcm_number = MIXART_PCM_ANALOG; @@ -761,7 +758,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs) } _exit_open: - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return err; } @@ -778,7 +775,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs) int err = 0; int pcm_number; - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); if ( pcm == chip->pcm ) { pcm_number = MIXART_PCM_ANALOG; @@ -839,7 +836,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs) } _exit_open: - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return err; } @@ -852,7 +849,7 @@ static int snd_mixart_close(struct snd_pcm_substream *subs) struct mixart_mgr *mgr = chip->mgr; struct mixart_stream *stream = subs->runtime->private_data; - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); snd_printdd("snd_mixart_close C%d/P%d/Sub%d\n", chip->chip_idx, stream->pcm_number, subs->number); @@ -871,7 +868,7 @@ static int snd_mixart_close(struct snd_pcm_substream *subs) stream->status = MIXART_STREAM_STATUS_FREE; stream->substream = NULL; - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return 0; } @@ -1291,7 +1288,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, 0xffffffff) < 0) { snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; @@ -1338,12 +1335,12 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, mgr->msg_fifo_writeptr = 0; spin_lock_init(&mgr->msg_lock); - mutex_init(&mgr->msg_mutex); + init_MUTEX(&mgr->msg_mutex); init_waitqueue_head(&mgr->msg_sleep); atomic_set(&mgr->msg_processed, 0); /* init setup mutex*/ - mutex_init(&mgr->setup_mutex); + init_MUTEX(&mgr->setup_mutex); /* init message taslket */ tasklet_init(&mgr->msg_taskq, snd_mixart_msg_tasklet, (unsigned long) mgr); diff --git a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h index 561634d5c..3e84863ca 100644 --- a/sound/pci/mixart/mixart.h +++ b/sound/pci/mixart/mixart.h @@ -24,7 +24,6 @@ #define __SOUND_MIXART_H #include -#include #include #define MIXART_DRIVER_VERSION 0x000100 /* 0.1.0 */ @@ -93,9 +92,9 @@ struct mixart_mgr { spinlock_t lock; /* interrupt spinlock */ spinlock_t msg_lock; /* mailbox spinlock */ - struct mutex msg_mutex; /* mutex for blocking_requests */ + struct semaphore msg_mutex; /* mutex for blocking_requests */ - struct mutex setup_mutex; /* mutex used in hw_params, open and close */ + struct semaphore setup_mutex; /* mutex used in hw_params, open and close */ /* hardware interface */ unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ @@ -108,7 +107,7 @@ struct mixart_mgr { int sample_rate; int ref_count_rate; - struct mutex mixer_mutex; /* mutex for mixer */ + struct semaphore mixer_mutex; /* mutex for mixer */ }; diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c index 406ac3a9d..07c707d7e 100644 --- a/sound/pci/mixart/mixart_core.c +++ b/sound/pci/mixart/mixart_core.c @@ -22,8 +22,6 @@ #include #include -#include - #include #include #include "mixart.h" @@ -241,7 +239,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int wait_queue_t wait; long timeout; - mutex_lock(&mgr->msg_mutex); + down(&mgr->msg_mutex); init_waitqueue_entry(&wait, current); @@ -250,7 +248,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int err = send_msg(mgr, request, max_resp_size, 1, &msg_frame); /* send and mark the answer pending */ if (err) { spin_unlock_irq(&mgr->msg_lock); - mutex_unlock(&mgr->msg_mutex); + up(&mgr->msg_mutex); return err; } @@ -262,7 +260,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int if (! timeout) { /* error - no ack */ - mutex_unlock(&mgr->msg_mutex); + up(&mgr->msg_mutex); snd_printk(KERN_ERR "error: no reponse on msg %x\n", msg_frame); return -EIO; } @@ -278,7 +276,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int if( request->message_id != resp.message_id ) snd_printk(KERN_ERR "REPONSE ERROR!\n"); - mutex_unlock(&mgr->msg_mutex); + up(&mgr->msg_mutex); return err; } @@ -294,7 +292,7 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, snd_assert((notif_event & MSG_TYPE_MASK) == MSG_TYPE_NOTIFY, return -EINVAL); snd_assert((notif_event & MSG_CANCEL_NOTIFY_MASK) == 0, return -EINVAL); - mutex_lock(&mgr->msg_mutex); + down(&mgr->msg_mutex); init_waitqueue_entry(&wait, current); @@ -303,7 +301,7 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 1, ¬if_event); /* send and mark the notification event pending */ if(err) { spin_unlock_irq(&mgr->msg_lock); - mutex_unlock(&mgr->msg_mutex); + up(&mgr->msg_mutex); return err; } @@ -315,12 +313,12 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, if (! timeout) { /* error - no ack */ - mutex_unlock(&mgr->msg_mutex); + up(&mgr->msg_mutex); snd_printk(KERN_ERR "error: notification %x not received\n", notif_event); return -EIO; } - mutex_unlock(&mgr->msg_mutex); + up(&mgr->msg_mutex); return 0; } diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c index ed47b732c..36a7e9ddf 100644 --- a/sound/pci/mixart/mixart_mixer.c +++ b/sound/pci/mixart/mixart_mixer.c @@ -24,8 +24,6 @@ #include #include #include -#include - #include #include "mixart.h" #include "mixart_core.h" @@ -355,7 +353,7 @@ static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); if(kcontrol->private_value == 0) { /* playback */ ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; @@ -363,7 +361,7 @@ static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -373,7 +371,7 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e int changed = 0; int is_capture, i; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); is_capture = (kcontrol->private_value != 0); for(i=0; i<2; i++) { int new_volume = ucontrol->value.integer.value[i]; @@ -384,7 +382,7 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e } } if(changed) mixart_update_analog_audio_level(chip, is_capture); - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -410,10 +408,10 @@ static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele { struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->analog_playback_active[0]; ucontrol->value.integer.value[1] = chip->analog_playback_active[1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -421,7 +419,7 @@ static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele { struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); int i, changed = 0; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); for(i=0; i<2; i++) { if(chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) { chip->analog_playback_active[i] = ucontrol->value.integer.value[i]; @@ -429,7 +427,7 @@ static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele } } if(changed) mixart_update_analog_audio_level(chip, 0); /* update playback levels */ - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -819,7 +817,7 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem int *stored_volume; int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK; int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); if(is_capture) { if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */ else stored_volume = chip->digital_capture_volume[0]; /* analog capture */ @@ -830,7 +828,7 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem } ucontrol->value.integer.value[0] = stored_volume[0]; ucontrol->value.integer.value[1] = stored_volume[1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -843,7 +841,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; int* stored_volume; int i; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); if(is_capture) { if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */ else stored_volume = chip->digital_capture_volume[0]; /* analog capture */ @@ -862,7 +860,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem if(is_capture) mixart_update_capture_stream_level(chip, is_aes); else mixart_update_playback_stream_level(chip, is_aes, idx); } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -882,12 +880,12 @@ static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */ idx += MIXART_PLAYBACK_STREAMS; ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0]; ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -899,7 +897,7 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ int i, j; snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); j = idx; if(is_aes) j += MIXART_PLAYBACK_STREAMS; for(i=0; i<2; i++) { @@ -909,7 +907,7 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ } } if(changed) mixart_update_playback_stream_level(chip, is_aes, idx); - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -958,10 +956,10 @@ static int mixart_update_monitoring(struct snd_mixart* chip, int channel) static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->monitoring_volume[0]; ucontrol->value.integer.value[1] = chip->monitoring_volume[1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -970,7 +968,7 @@ static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); int changed = 0; int i; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); for(i=0; i<2; i++) { if(chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) { chip->monitoring_volume[i] = ucontrol->value.integer.value[i]; @@ -978,7 +976,7 @@ static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ changed = 1; } } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -997,10 +995,10 @@ static struct snd_kcontrol_new mixart_control_monitor_vol = { static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->monitoring_active[0]; ucontrol->value.integer.value[1] = chip->monitoring_active[1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -1009,7 +1007,7 @@ static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); int changed = 0; int i; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); for(i=0; i<2; i++) { if(chip->monitoring_active[i] != ucontrol->value.integer.value[i]) { chip->monitoring_active[i] = ucontrol->value.integer.value[i]; @@ -1031,7 +1029,7 @@ static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e } } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return (changed != 0); } @@ -1061,7 +1059,7 @@ int snd_mixart_create_mixer(struct mixart_mgr *mgr) struct snd_mixart *chip; int err, i; - mutex_init(&mgr->mixer_mutex); /* can be in another place */ + init_MUTEX(&mgr->mixer_mutex); /* can be in another place */ for(i=0; inum_cards; i++) { struct snd_kcontrol_new temp; diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index b92d6600d..0d0ff54f0 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -32,8 +32,6 @@ #include #include #include -#include - #include #include #include @@ -228,7 +226,6 @@ struct nm256 { unsigned int use_cache: 1; /* use one big coef. table */ unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */ unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */ - unsigned int in_resume: 1; int mixer_base; /* register offset of ac97 mixer */ int mixer_status_offset; /* offset of mixer status reg. */ @@ -238,12 +235,11 @@ struct nm256 { int irq_acks; irqreturn_t (*interrupt)(int, void *, struct pt_regs *); int badintrcount; /* counter to check bogus interrupts */ - struct mutex irq_mutex; + struct semaphore irq_mutex; struct nm256_stream streams[2]; struct snd_ac97 *ac97; - unsigned short *ac97_regs; /* register caches, only for valid regs */ struct snd_pcm *pcm; @@ -263,7 +259,7 @@ struct nm256 { /* * PCI ids */ -static struct pci_device_id snd_nm256_ids[] __devinitdata = { +static struct pci_device_id snd_nm256_ids[] = { {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -463,32 +459,32 @@ snd_nm256_set_format(struct nm256 *chip, struct nm256_stream *s, /* acquire interrupt */ static int snd_nm256_acquire_irq(struct nm256 *chip) { - mutex_lock(&chip->irq_mutex); + down(&chip->irq_mutex); if (chip->irq < 0) { if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, chip->card->driver, chip)) { snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq); - mutex_unlock(&chip->irq_mutex); + up(&chip->irq_mutex); return -EBUSY; } chip->irq = chip->pci->irq; } chip->irq_acks++; - mutex_unlock(&chip->irq_mutex); + up(&chip->irq_mutex); return 0; } /* release interrupt */ static void snd_nm256_release_irq(struct nm256 *chip) { - mutex_lock(&chip->irq_mutex); + down(&chip->irq_mutex); if (chip->irq_acks > 0) chip->irq_acks--; if (chip->irq_acks == 0 && chip->irq >= 0) { free_irq(chip->irq, chip); chip->irq = -1; } - mutex_unlock(&chip->irq_mutex); + up(&chip->irq_mutex); } /* @@ -1155,63 +1151,23 @@ snd_nm256_ac97_ready(struct nm256 *chip) return 0; } -/* - * Initial register values to be written to the AC97 mixer. - * While most of these are identical to the reset values, we do this - * so that we have most of the register contents cached--this avoids - * reading from the mixer directly (which seems to be problematic, - * probably due to ignorance). - */ - -struct initialValues { - unsigned short reg; - unsigned short value; -}; - -static struct initialValues nm256_ac97_init_val[] = -{ - { AC97_MASTER, 0x8000 }, - { AC97_HEADPHONE, 0x8000 }, - { AC97_MASTER_MONO, 0x8000 }, - { AC97_PC_BEEP, 0x8000 }, - { AC97_PHONE, 0x8008 }, - { AC97_MIC, 0x8000 }, - { AC97_LINE, 0x8808 }, - { AC97_CD, 0x8808 }, - { AC97_VIDEO, 0x8808 }, - { AC97_AUX, 0x8808 }, - { AC97_PCM, 0x8808 }, - { AC97_REC_SEL, 0x0000 }, - { AC97_REC_GAIN, 0x0B0B }, - { AC97_GENERAL_PURPOSE, 0x0000 }, - { AC97_3D_CONTROL, 0x8000 }, - { AC97_VENDOR_ID1, 0x8384 }, - { AC97_VENDOR_ID2, 0x7609 }, -}; - -static int nm256_ac97_idx(unsigned short reg) -{ - int i; - for (i = 0; i < ARRAY_SIZE(nm256_ac97_init_val); i++) - if (nm256_ac97_init_val[i].reg == reg) - return i; - return -1; -} - /* - * some nm256 easily crash when reading from mixer registers - * thus we're treating it as a write-only mixer and cache the - * written values */ static unsigned short snd_nm256_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { struct nm256 *chip = ac97->private_data; - int idx = nm256_ac97_idx(reg); + int res; - if (idx < 0) + if (reg >= 128) return 0; - return chip->ac97_regs[idx]; + + if (! snd_nm256_ac97_ready(chip)) + return 0; + res = snd_nm256_readw(chip, chip->mixer_base + reg); + /* Magic delay. Bleah yucky. */ + msleep(1); + return res; } /* @@ -1222,12 +1178,8 @@ snd_nm256_ac97_write(struct snd_ac97 *ac97, { struct nm256 *chip = ac97->private_data; int tries = 2; - int idx = nm256_ac97_idx(reg); u32 base; - if (idx < 0) - return; - base = chip->mixer_base; snd_nm256_ac97_ready(chip); @@ -1236,32 +1188,12 @@ snd_nm256_ac97_write(struct snd_ac97 *ac97, while (tries-- > 0) { snd_nm256_writew(chip, base + reg, val); msleep(1); /* a little delay here seems better.. */ - if (snd_nm256_ac97_ready(chip)) { - /* successful write: set cache */ - chip->ac97_regs[idx] = val; + if (snd_nm256_ac97_ready(chip)) return; - } } snd_printd("nm256: ac97 codec not ready..\n"); } -/* static resolution table */ -static struct snd_ac97_res_table nm256_res_table[] = { - { AC97_MASTER, 0x1f1f }, - { AC97_HEADPHONE, 0x1f1f }, - { AC97_MASTER_MONO, 0x001f }, - { AC97_PC_BEEP, 0x001f }, - { AC97_PHONE, 0x001f }, - { AC97_MIC, 0x001f }, - { AC97_LINE, 0x1f1f }, - { AC97_CD, 0x1f1f }, - { AC97_VIDEO, 0x1f1f }, - { AC97_AUX, 0x1f1f }, - { AC97_PCM, 0x1f1f }, - { AC97_REC_GAIN, 0x0f0f }, - { } /* terminator */ -}; - /* initialize the ac97 into a known state */ static void snd_nm256_ac97_reset(struct snd_ac97 *ac97) @@ -1279,16 +1211,6 @@ snd_nm256_ac97_reset(struct snd_ac97 *ac97) snd_nm256_writeb(chip, 0x6cc, 0x80); snd_nm256_writeb(chip, 0x6cc, 0x0); } - if (! chip->in_resume) { - int i; - for (i = 0; i < ARRAY_SIZE(nm256_ac97_init_val); i++) { - /* preload the cache, so as to avoid even a single - * read of the mixer regs - */ - snd_nm256_ac97_write(ac97, nm256_ac97_init_val[i].reg, - nm256_ac97_init_val[i].value); - } - } } /* create an ac97 mixer interface */ @@ -1297,25 +1219,32 @@ snd_nm256_mixer(struct nm256 *chip) { struct snd_ac97_bus *pbus; struct snd_ac97_template ac97; - int err; + int i, err; static struct snd_ac97_bus_ops ops = { .reset = snd_nm256_ac97_reset, .write = snd_nm256_ac97_write, .read = snd_nm256_ac97_read, }; - - chip->ac97_regs = kcalloc(sizeof(short), - ARRAY_SIZE(nm256_ac97_init_val), GFP_KERNEL); - if (! chip->ac97_regs) - return -ENOMEM; + /* looks like nm256 hangs up when unexpected registers are touched... */ + static int mixer_regs[] = { + AC97_MASTER, AC97_HEADPHONE, AC97_MASTER_MONO, + AC97_PC_BEEP, AC97_PHONE, AC97_MIC, AC97_LINE, AC97_CD, + AC97_VIDEO, AC97_AUX, AC97_PCM, AC97_REC_SEL, + AC97_REC_GAIN, AC97_GENERAL_PURPOSE, AC97_3D_CONTROL, + /*AC97_EXTENDED_ID,*/ + AC97_VENDOR_ID1, AC97_VENDOR_ID2, + -1 + }; if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0) return err; memset(&ac97, 0, sizeof(ac97)); ac97.scaps = AC97_SCAP_AUDIO; /* we support audio! */ + ac97.limited_regs = 1; + for (i = 0; mixer_regs[i] >= 0; i++) + set_bit(mixer_regs[i], ac97.reg_accessed); ac97.private_data = chip; - ac97.res_table = nm256_res_table; pbus->no_vra = 1; err = snd_ac97_mixer(pbus, &ac97, &chip->ac97); if (err < 0) @@ -1400,7 +1329,6 @@ static int nm256_resume(struct pci_dev *pci) int i; /* Perform a full reset on the hardware */ - chip->in_resume = 1; pci_restore_state(pci); pci_enable_device(pci); snd_nm256_init_chip(chip); @@ -1418,7 +1346,6 @@ static int nm256_resume(struct pci_dev *pci) } snd_power_change_state(card, SNDRV_CTL_POWER_D0); - chip->in_resume = 0; return 0; } #endif /* CONFIG_PM */ @@ -1443,7 +1370,6 @@ static int snd_nm256_free(struct nm256 *chip) free_irq(chip->irq, chip); pci_disable_device(chip->pci); - kfree(chip->ac97_regs); kfree(chip); return 0; } @@ -1481,7 +1407,7 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci, chip->use_cache = use_cache; spin_lock_init(&chip->reg_lock); chip->irq = -1; - mutex_init(&chip->irq_mutex); + init_MUTEX(&chip->irq_mutex); /* store buffer sizes in bytes */ chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = playback_bufsize * 1024; diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index dafa2235a..b2cba75b6 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -26,11 +26,8 @@ #include #include #include -#include #include #include -#include - #include #include #include @@ -73,7 +70,7 @@ enum { PCI_ID_LAST }; -static struct pci_device_id pcxhr_ids[] __devinitdata = { +static struct pci_device_id pcxhr_ids[] = { { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, /* VX882HR */ { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, /* PCX882HR */ { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, /* VX881HR */ @@ -521,7 +518,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) struct timeval my_tv1, my_tv2; do_gettimeofday(&my_tv1); #endif - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); /* check the pipes concerned and build pipe_array */ for (i = 0; i < mgr->num_cards; i++) { @@ -540,7 +537,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) } } if (capture_mask == 0 && playback_mask == 0) { - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); snd_printk(KERN_ERR "pcxhr_trigger_tasklet : no pipes\n"); return; } @@ -551,7 +548,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) /* synchronous stop of all the pipes concerned */ err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0); if (err) { - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error stop pipes (P%x C%x)\n", playback_mask, capture_mask); return; @@ -595,7 +592,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) /* synchronous start of all the pipes concerned */ err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); if (err) { - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error start pipes (P%x C%x)\n", playback_mask, capture_mask); return; @@ -622,7 +619,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) } spin_unlock_irqrestore(&mgr->lock, flags); - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); #ifdef CONFIG_SND_DEBUG_DETECT do_gettimeofday(&my_tv2); @@ -731,7 +728,7 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs) } */ - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); do { /* if the stream was stopped before, format and buffer were reset */ @@ -758,7 +755,7 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs) } } while(0); /* do only once (so we can use break instead of goto) */ - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return err; } @@ -783,7 +780,7 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs, /* set up format for the stream */ format = params_format(hw); - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); stream->channels = channels; stream->format = format; @@ -792,7 +789,7 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs, /* err = pcxhr_set_format(stream); if(err) { - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return err; } */ @@ -804,7 +801,7 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs, err = pcxhr_update_r_buffer(stream); } */ - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return err; } @@ -850,7 +847,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs) struct pcxhr_stream *stream; int is_capture; - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); /* copy the struct snd_pcm_hardware struct */ runtime->hw = pcxhr_caps; @@ -874,7 +871,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs) /* streams in use */ snd_printk(KERN_ERR "pcxhr_open chip%d subs%d in use\n", chip->chip_idx, subs->number); - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return -EBUSY; } @@ -890,7 +887,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs) &external_rate) || external_rate == 0) { /* cannot detect the external clock rate */ - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return -EBUSY; } runtime->hw.rate_min = runtime->hw.rate_max = external_rate; @@ -908,7 +905,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs) mgr->ref_count_rate++; - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return 0; } @@ -919,7 +916,7 @@ static int pcxhr_close(struct snd_pcm_substream *subs) struct pcxhr_mgr *mgr = chip->mgr; struct pcxhr_stream *stream = subs->runtime->private_data; - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); snd_printdd("pcxhr_close chip%d subs%d\n", chip->chip_idx, subs->number); @@ -932,7 +929,7 @@ static int pcxhr_close(struct snd_pcm_substream *subs) stream->status = PCXHR_STREAM_STATUS_FREE; stream->substream = NULL; - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); return 0; } @@ -1218,7 +1215,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id 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, 0xffffffff) < 0) { snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; @@ -1267,7 +1264,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id spin_lock_init(&mgr->msg_lock); /* init setup mutex*/ - mutex_init(&mgr->setup_mutex); + init_MUTEX(&mgr->setup_mutex); /* init taslket */ tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet, (unsigned long) mgr); diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h index 652064787..049f2b3f2 100644 --- a/sound/pci/pcxhr/pcxhr.h +++ b/sound/pci/pcxhr/pcxhr.h @@ -24,7 +24,6 @@ #define __SOUND_PCXHR_H #include -#include #include #define PCXHR_DRIVER_VERSION 0x000804 /* 0.8.4 */ @@ -77,8 +76,8 @@ struct pcxhr_mgr { spinlock_t lock; /* interrupt spinlock */ spinlock_t msg_lock; /* message spinlock */ - struct mutex setup_mutex; /* mutex used in hw_params, open and close */ - struct mutex mixer_mutex; /* mutex for mixer */ + struct semaphore setup_mutex; /* mutex used in hw_params, open and close */ + struct semaphore mixer_mutex; /* mutex for mixer */ /* hardware interface */ unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index c40f59062..fa0d27e2c 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -274,9 +274,12 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin /* test first xilinx */ chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC); - /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */ - /* this bit will always be 1; no possibility to test presence of first xilinx */ - if(second) { + if (!second) { + if (chipsc & PCXHR_CHIPSC_GPI_USERI) { + snd_printdd("no need to load first xilinx\n"); + return 0; /* first xilinx is already present and cannot be reset */ + } + } else { if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) { snd_printk(KERN_ERR "error loading first xilinx\n"); return -EINVAL; @@ -1173,7 +1176,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id, struct pt_regs *regs) mgr->dsp_time_last = dsp_time_new; if (timer_toggle == mgr->timer_toggle) - snd_printdd("ERROR TIMER TOGGLE\n"); + snd_printk(KERN_ERR "ERROR TIMER TOGGLE\n"); mgr->timer_toggle = timer_toggle; reg &= ~PCXHR_IRQ_TIMER; diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index 369c19fea..03517c10e 100644 --- a/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/sound/pci/pcxhr/pcxhr_hwdep.c @@ -385,8 +385,8 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw, fw.size = dsp->length; fw.data = vmalloc(fw.size); if (! fw.data) { - snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%lu bytes)\n", - (unsigned long)fw.size); + snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%d bytes)\n", + fw.size); return -ENOMEM; } if (copy_from_user(fw.data, dsp->image, dsp->length)) { diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c index 94e63a1e9..760e733ac 100644 --- a/sound/pci/pcxhr/pcxhr_mixer.c +++ b/sound/pci/pcxhr/pcxhr_mixer.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "pcxhr.h" #include "pcxhr_hwdep.h" @@ -93,7 +92,7 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); if (kcontrol->private_value == 0) { /* playback */ ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; @@ -101,7 +100,7 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -112,7 +111,7 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol, int changed = 0; int is_capture, i; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); is_capture = (kcontrol->private_value != 0); for (i = 0; i < 2; i++) { int new_volume = ucontrol->value.integer.value[i]; @@ -124,7 +123,7 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol, pcxhr_update_analog_audio_level(chip, is_capture, i); } } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -151,10 +150,10 @@ static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol, { struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->analog_playback_active[0]; ucontrol->value.integer.value[1] = chip->analog_playback_active[1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -163,7 +162,7 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol, { struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); int i, changed = 0; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); for(i = 0; i < 2; i++) { if (chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) { chip->analog_playback_active[i] = ucontrol->value.integer.value[i]; @@ -171,7 +170,7 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol, pcxhr_update_analog_audio_level(chip, 0, i); /* update playback levels */ } } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -300,14 +299,14 @@ static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol, int *stored_volume; int is_capture = kcontrol->private_value; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); if (is_capture) stored_volume = chip->digital_capture_volume; /* digital capture */ else stored_volume = chip->digital_playback_volume[idx]; /* digital playback */ ucontrol->value.integer.value[0] = stored_volume[0]; ucontrol->value.integer.value[1] = stored_volume[1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -321,7 +320,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol, int *stored_volume; int i; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); if (is_capture) stored_volume = chip->digital_capture_volume; /* digital capture */ else @@ -336,7 +335,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol, } if (! is_capture && changed) pcxhr_update_playback_stream_level(chip, idx); /* update playback volume */ - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -357,10 +356,10 @@ static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0]; ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -371,7 +370,7 @@ static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ int i, j; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); j = idx; for (i = 0; i < 2; i++) { if (chip->digital_playback_active[j][i] != ucontrol->value.integer.value[i]) { @@ -381,7 +380,7 @@ static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v } if (changed) pcxhr_update_playback_stream_level(chip, idx); - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -403,10 +402,10 @@ static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->monitoring_volume[0]; ucontrol->value.integer.value[1] = chip->monitoring_volume[1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -417,7 +416,7 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol, int changed = 0; int i; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); for (i = 0; i < 2; i++) { if (chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) { chip->monitoring_volume[i] = ucontrol->value.integer.value[i]; @@ -427,7 +426,7 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol, changed = 1; } } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -447,10 +446,10 @@ static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); ucontrol->value.integer.value[0] = chip->monitoring_active[0]; ucontrol->value.integer.value[1] = chip->monitoring_active[1]; - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -461,7 +460,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol, int changed = 0; int i; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); for (i = 0; i < 2; i++) { if (chip->monitoring_active[i] != ucontrol->value.integer.value[i]) { chip->monitoring_active[i] = ucontrol->value.integer.value[i]; @@ -475,7 +474,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol, /* update right monitoring volume and mute */ pcxhr_update_audio_pipe_level(chip, 0, 1); - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return (changed != 0); } @@ -572,13 +571,13 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); int ret = 0; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) { chip->audio_capture_source = ucontrol->value.enumerated.item[0]; pcxhr_set_audio_source(chip); ret = 1; } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return ret; } @@ -637,9 +636,9 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol, struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); int rate, ret = 0; - mutex_lock(&mgr->mixer_mutex); + down(&mgr->mixer_mutex); if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) { - mutex_lock(&mgr->setup_mutex); + down(&mgr->setup_mutex); mgr->use_clock_type = ucontrol->value.enumerated.item[0]; if (mgr->use_clock_type) pcxhr_get_external_clock(mgr, mgr->use_clock_type, &rate); @@ -650,10 +649,10 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol, if (mgr->sample_rate) mgr->sample_rate = rate; } - mutex_unlock(&mgr->setup_mutex); + up(&mgr->setup_mutex); ret = 1; /* return 1 even if the set was not done. ok ? */ } - mutex_unlock(&mgr->mixer_mutex); + up(&mgr->mixer_mutex); return ret; } @@ -686,7 +685,7 @@ static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol, struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); int i, err, rate; - mutex_lock(&mgr->mixer_mutex); + down(&mgr->mixer_mutex); for(i = 0; i < 3 + mgr->capture_chips; i++) { if (i == PCXHR_CLOCK_TYPE_INTERNAL) rate = mgr->sample_rate_real; @@ -697,7 +696,7 @@ static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol, } ucontrol->value.integer.value[i] = rate; } - mutex_unlock(&mgr->mixer_mutex); + up(&mgr->mixer_mutex); return 0; } @@ -766,7 +765,7 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v unsigned char aes_bits; int i, err; - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); for(i = 0; i < 5; i++) { if (kcontrol->private_value == 0) /* playback */ aes_bits = chip->aes_bits[i]; @@ -777,7 +776,7 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v } ucontrol->value.iec958.status[i] = aes_bits; } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return 0; } @@ -829,14 +828,14 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol, int i, changed = 0; /* playback */ - mutex_lock(&chip->mgr->mixer_mutex); + down(&chip->mgr->mixer_mutex); for (i = 0; i < 5; i++) { if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) { pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]); changed = 1; } } - mutex_unlock(&chip->mgr->mixer_mutex); + up(&chip->mgr->mixer_mutex); return changed; } @@ -917,7 +916,7 @@ int pcxhr_create_mixer(struct pcxhr_mgr *mgr) struct snd_pcxhr *chip; int err, i; - mutex_init(&mgr->mixer_mutex); /* can be in another place */ + init_MUTEX(&mgr->mixer_mutex); /* can be in another place */ for (i = 0; i < mgr->num_cards; i++) { struct snd_kcontrol_new temp; diff --git a/sound/pci/riptide/Makefile b/sound/pci/riptide/Makefile deleted file mode 100644 index dcd2e64e4..000000000 --- a/sound/pci/riptide/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -snd-riptide-objs := riptide.o - -obj-$(CONFIG_SND_RIPTIDE) += snd-riptide.o diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c deleted file mode 100644 index d8cc985d7..000000000 --- a/sound/pci/riptide/riptide.c +++ /dev/null @@ -1,2223 +0,0 @@ -/* - * Driver for the Conexant Riptide Soundchip - * - * Copyright (c) 2004 Peter Gruber - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 - * - */ -/* - History: - - 02/15/2004 first release - - This Driver is based on the OSS Driver version from Linuxant (riptide-0.6lnxtbeta03111100) - credits from the original files: - - MODULE NAME: cnxt_rt.h - AUTHOR: K. Lazarev (Transcribed by KNL) - HISTORY: Major Revision Date By - ----------------------------- -------- ----- - Created 02/1/2000 KNL - - MODULE NAME: int_mdl.c - AUTHOR: Konstantin Lazarev (Transcribed by KNL) - HISTORY: Major Revision Date By - ----------------------------- -------- ----- - Created 10/01/99 KNL - - MODULE NAME: riptide.h - AUTHOR: O. Druzhinin (Transcribed by OLD) - HISTORY: Major Revision Date By - ----------------------------- -------- ----- - Created 10/16/97 OLD - - MODULE NAME: Rp_Cmdif.cpp - AUTHOR: O. Druzhinin (Transcribed by OLD) - K. Lazarev (Transcribed by KNL) - HISTORY: Major Revision Date By - ----------------------------- -------- ----- - Adopted from NT4 driver 6/22/99 OLD - Ported to Linux 9/01/99 KNL - - MODULE NAME: rt_hw.c - AUTHOR: O. Druzhinin (Transcribed by OLD) - C. Lazarev (Transcribed by CNL) - HISTORY: Major Revision Date By - ----------------------------- -------- ----- - Created 11/18/97 OLD - Hardware functions for RipTide 11/24/97 CNL - (ES1) are coded - Hardware functions for RipTide 12/24/97 CNL - (A0) are coded - Hardware functions for RipTide 03/20/98 CNL - (A1) are coded - Boot loader is included 05/07/98 CNL - Redesigned for WDM 07/27/98 CNL - Redesigned for Linux 09/01/99 CNL - - MODULE NAME: rt_hw.h - AUTHOR: C. Lazarev (Transcribed by CNL) - HISTORY: Major Revision Date By - ----------------------------- -------- ----- - Created 11/18/97 CNL - - MODULE NAME: rt_mdl.c - AUTHOR: Konstantin Lazarev (Transcribed by KNL) - HISTORY: Major Revision Date By - ----------------------------- -------- ----- - Created 10/01/99 KNL - - MODULE NAME: mixer.h - AUTHOR: K. Kenney - HISTORY: Major Revision Date By - ----------------------------- -------- ----- - Created from MS W95 Sample 11/28/95 KRS - RipTide 10/15/97 KRS - Adopted for Windows NT driver 01/20/98 CNL -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) -#define SUPPORT_JOYSTICK 1 -#endif - -MODULE_AUTHOR("Peter Gruber "); -MODULE_DESCRIPTION("riptide"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; - -#ifdef SUPPORT_JOYSTICK -static int joystick_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x200 }; -#endif -static int mpu_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x330 }; -static int opl3_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x388 }; - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for Riptide soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for Riptide soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable Riptide soundcard."); -#ifdef SUPPORT_JOYSTICK -module_param_array(joystick_port, int, NULL, 0444); -MODULE_PARM_DESC(joystick_port, "Joystick port # for Riptide soundcard."); -#endif -module_param_array(mpu_port, int, NULL, 0444); -MODULE_PARM_DESC(mpu_port, "MPU401 port # for Riptide driver."); -module_param_array(opl3_port, int, NULL, 0444); -MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver."); - -/* - */ - -#define MPU401_HW_RIPTIDE MPU401_HW_MPU401 -#define OPL3_HW_RIPTIDE OPL3_HW_OPL3 - -#define PCI_EXT_CapId 0x40 -#define PCI_EXT_NextCapPrt 0x41 -#define PCI_EXT_PWMC 0x42 -#define PCI_EXT_PWSCR 0x44 -#define PCI_EXT_Data00 0x46 -#define PCI_EXT_PMSCR_BSE 0x47 -#define PCI_EXT_SB_Base 0x48 -#define PCI_EXT_FM_Base 0x4a -#define PCI_EXT_MPU_Base 0x4C -#define PCI_EXT_Game_Base 0x4E -#define PCI_EXT_Legacy_Mask 0x50 -#define PCI_EXT_AsicRev 0x52 -#define PCI_EXT_Reserved3 0x53 - -#define LEGACY_ENABLE_ALL 0x8000 /* legacy device options */ -#define LEGACY_ENABLE_SB 0x4000 -#define LEGACY_ENABLE_FM 0x2000 -#define LEGACY_ENABLE_MPU_INT 0x1000 -#define LEGACY_ENABLE_MPU 0x0800 -#define LEGACY_ENABLE_GAMEPORT 0x0400 - -#define MAX_WRITE_RETRY 10 /* cmd interface limits */ -#define MAX_ERROR_COUNT 10 -#define CMDIF_TIMEOUT 500000 -#define RESET_TRIES 5 - -#define READ_PORT_ULONG(p) inl((unsigned long)&(p)) -#define WRITE_PORT_ULONG(p,x) outl(x,(unsigned long)&(p)) - -#define READ_AUDIO_CONTROL(p) READ_PORT_ULONG(p->audio_control) -#define WRITE_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,x) -#define UMASK_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)|x) -#define MASK_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)&x) -#define READ_AUDIO_STATUS(p) READ_PORT_ULONG(p->audio_status) - -#define SET_GRESET(p) UMASK_AUDIO_CONTROL(p,0x0001) /* global reset switch */ -#define UNSET_GRESET(p) MASK_AUDIO_CONTROL(p,~0x0001) -#define SET_AIE(p) UMASK_AUDIO_CONTROL(p,0x0004) /* interrupt enable */ -#define UNSET_AIE(p) MASK_AUDIO_CONTROL(p,~0x0004) -#define SET_AIACK(p) UMASK_AUDIO_CONTROL(p,0x0008) /* interrupt acknowledge */ -#define UNSET_AIACKT(p) MASKAUDIO_CONTROL(p,~0x0008) -#define SET_ECMDAE(p) UMASK_AUDIO_CONTROL(p,0x0010) -#define UNSET_ECMDAE(p) MASK_AUDIO_CONTROL(p,~0x0010) -#define SET_ECMDBE(p) UMASK_AUDIO_CONTROL(p,0x0020) -#define UNSET_ECMDBE(p) MASK_AUDIO_CONTROL(p,~0x0020) -#define SET_EDATAF(p) UMASK_AUDIO_CONTROL(p,0x0040) -#define UNSET_EDATAF(p) MASK_AUDIO_CONTROL(p,~0x0040) -#define SET_EDATBF(p) UMASK_AUDIO_CONTROL(p,0x0080) -#define UNSET_EDATBF(p) MASK_AUDIO_CONTROL(p,~0x0080) -#define SET_ESBIRQON(p) UMASK_AUDIO_CONTROL(p,0x0100) -#define UNSET_ESBIRQON(p) MASK_AUDIO_CONTROL(p,~0x0100) -#define SET_EMPUIRQ(p) UMASK_AUDIO_CONTROL(p,0x0200) -#define UNSET_EMPUIRQ(p) MASK_AUDIO_CONTROL(p,~0x0200) -#define IS_CMDE(a) (READ_PORT_ULONG(a->stat)&0x1) /* cmd empty */ -#define IS_DATF(a) (READ_PORT_ULONG(a->stat)&0x2) /* data filled */ -#define IS_READY(p) (READ_AUDIO_STATUS(p)&0x0001) -#define IS_DLREADY(p) (READ_AUDIO_STATUS(p)&0x0002) -#define IS_DLERR(p) (READ_AUDIO_STATUS(p)&0x0004) -#define IS_GERR(p) (READ_AUDIO_STATUS(p)&0x0008) /* error ! */ -#define IS_CMDAEIRQ(p) (READ_AUDIO_STATUS(p)&0x0010) -#define IS_CMDBEIRQ(p) (READ_AUDIO_STATUS(p)&0x0020) -#define IS_DATAFIRQ(p) (READ_AUDIO_STATUS(p)&0x0040) -#define IS_DATBFIRQ(p) (READ_AUDIO_STATUS(p)&0x0080) -#define IS_EOBIRQ(p) (READ_AUDIO_STATUS(p)&0x0100) /* interrupt status */ -#define IS_EOSIRQ(p) (READ_AUDIO_STATUS(p)&0x0200) -#define IS_EOCIRQ(p) (READ_AUDIO_STATUS(p)&0x0400) -#define IS_UNSLIRQ(p) (READ_AUDIO_STATUS(p)&0x0800) -#define IS_SBIRQ(p) (READ_AUDIO_STATUS(p)&0x1000) -#define IS_MPUIRQ(p) (READ_AUDIO_STATUS(p)&0x2000) - -#define RESP 0x00000001 /* command flags */ -#define PARM 0x00000002 -#define CMDA 0x00000004 -#define CMDB 0x00000008 -#define NILL 0x00000000 - -#define LONG0(a) ((u32)a) /* shifts and masks */ -#define BYTE0(a) (LONG0(a)&0xff) -#define BYTE1(a) (BYTE0(a)<<8) -#define BYTE2(a) (BYTE0(a)<<16) -#define BYTE3(a) (BYTE0(a)<<24) -#define WORD0(a) (LONG0(a)&0xffff) -#define WORD1(a) (WORD0(a)<<8) -#define WORD2(a) (WORD0(a)<<16) -#define TRINIB0(a) (LONG0(a)&0xffffff) -#define TRINIB1(a) (TRINIB0(a)<<8) - -#define RET(a) ((union cmdret *)(a)) - -#define SEND_GETV(p,b) sendcmd(p,RESP,GETV,0,RET(b)) /* get version */ -#define SEND_GETC(p,b,c) sendcmd(p,PARM|RESP,GETC,c,RET(b)) -#define SEND_GUNS(p,b) sendcmd(p,RESP,GUNS,0,RET(b)) -#define SEND_SCID(p,b) sendcmd(p,RESP,SCID,0,RET(b)) -#define SEND_RMEM(p,b,c,d) sendcmd(p,PARM|RESP,RMEM|BYTE1(b),LONG0(c),RET(d)) /* memory access for firmware write */ -#define SEND_SMEM(p,b,c) sendcmd(p,PARM,SMEM|BYTE1(b),LONG0(c),RET(0)) /* memory access for firmware write */ -#define SEND_WMEM(p,b,c) sendcmd(p,PARM,WMEM|BYTE1(b),LONG0(c),RET(0)) /* memory access for firmware write */ -#define SEND_SDTM(p,b,c) sendcmd(p,PARM|RESP,SDTM|TRINIB1(b),0,RET(c)) /* memory access for firmware write */ -#define SEND_GOTO(p,b) sendcmd(p,PARM,GOTO,LONG0(b),RET(0)) /* memory access for firmware write */ -#define SEND_SETDPLL(p) sendcmd(p,0,ARM_SETDPLL,0,RET(0)) -#define SEND_SSTR(p,b,c) sendcmd(p,PARM,SSTR|BYTE3(b),LONG0(c),RET(0)) /* start stream */ -#define SEND_PSTR(p,b) sendcmd(p,PARM,PSTR,BYTE3(b),RET(0)) /* pause stream */ -#define SEND_KSTR(p,b) sendcmd(p,PARM,KSTR,BYTE3(b),RET(0)) /* stop stream */ -#define SEND_KDMA(p) sendcmd(p,0,KDMA,0,RET(0)) /* stop all dma */ -#define SEND_GPOS(p,b,c,d) sendcmd(p,PARM|RESP,GPOS,BYTE3(c)|BYTE2(b),RET(d)) /* get position in dma */ -#define SEND_SETF(p,b,c,d,e,f,g) sendcmd(p,PARM,SETF|WORD1(b)|BYTE3(c),d|BYTE1(e)|BYTE2(f)|BYTE3(g),RET(0)) /* set sample format at mixer */ -#define SEND_GSTS(p,b,c,d) sendcmd(p,PARM|RESP,GSTS,BYTE3(c)|BYTE2(b),RET(d)) -#define SEND_NGPOS(p,b,c,d) sendcmd(p,PARM|RESP,NGPOS,BYTE3(c)|BYTE2(b),RET(d)) -#define SEND_PSEL(p,b,c) sendcmd(p,PARM,PSEL,BYTE2(b)|BYTE3(c),RET(0)) /* activate lbus path */ -#define SEND_PCLR(p,b,c) sendcmd(p,PARM,PCLR,BYTE2(b)|BYTE3(c),RET(0)) /* deactivate lbus path */ -#define SEND_PLST(p,b) sendcmd(p,PARM,PLST,BYTE3(b),RET(0)) -#define SEND_RSSV(p,b,c,d) sendcmd(p,PARM|RESP,RSSV,BYTE2(b)|BYTE3(c),RET(d)) -#define SEND_LSEL(p,b,c,d,e,f,g,h) sendcmd(p,PARM,LSEL|BYTE1(b)|BYTE2(c)|BYTE3(d),BYTE0(e)|BYTE1(f)|BYTE2(g)|BYTE3(h),RET(0)) /* select paths for internal connections */ -#define SEND_SSRC(p,b,c,d,e) sendcmd(p,PARM,SSRC|BYTE1(b)|WORD2(c),WORD0(d)|WORD2(e),RET(0)) /* configure source */ -#define SEND_SLST(p,b) sendcmd(p,PARM,SLST,BYTE3(b),RET(0)) -#define SEND_RSRC(p,b,c) sendcmd(p,RESP,RSRC|BYTE1(b),0,RET(c)) /* read source config */ -#define SEND_SSRB(p,b,c) sendcmd(p,PARM,SSRB|BYTE1(b),WORD2(c),RET(0)) -#define SEND_SDGV(p,b,c,d,e) sendcmd(p,PARM,SDGV|BYTE2(b)|BYTE3(c),WORD0(d)|WORD2(e),RET(0)) /* set digital mixer */ -#define SEND_RDGV(p,b,c,d) sendcmd(p,PARM|RESP,RDGV|BYTE2(b)|BYTE3(c),0,RET(d)) /* read digital mixer */ -#define SEND_DLST(p,b) sendcmd(p,PARM,DLST,BYTE3(b),RET(0)) -#define SEND_SACR(p,b,c) sendcmd(p,PARM,SACR,WORD0(b)|WORD2(c),RET(0)) /* set AC97 register */ -#define SEND_RACR(p,b,c) sendcmd(p,PARM|RESP,RACR,WORD2(b),RET(c)) /* get AC97 register */ -#define SEND_ALST(p,b) sendcmd(p,PARM,ALST,BYTE3(b),RET(0)) -#define SEND_TXAC(p,b,c,d,e,f) sendcmd(p,PARM,TXAC|BYTE1(b)|WORD2(c),WORD0(d)|BYTE2(e)|BYTE3(f),RET(0)) -#define SEND_RXAC(p,b,c,d) sendcmd(p,PARM|RESP,RXAC,BYTE2(b)|BYTE3(c),RET(d)) -#define SEND_SI2S(p,b) sendcmd(p,PARM,SI2S,WORD2(b),RET(0)) - -#define EOB_STATUS 0x80000000 /* status flags : block boundary */ -#define EOS_STATUS 0x40000000 /* : stoppped */ -#define EOC_STATUS 0x20000000 /* : stream end */ -#define ERR_STATUS 0x10000000 -#define EMPTY_STATUS 0x08000000 - -#define IEOB_ENABLE 0x1 /* enable interrupts for status notification above */ -#define IEOS_ENABLE 0x2 -#define IEOC_ENABLE 0x4 -#define RDONCE 0x8 -#define DESC_MAX_MASK 0xff - -#define ST_PLAY 0x1 /* stream states */ -#define ST_STOP 0x2 -#define ST_PAUSE 0x4 - -#define I2S_INTDEC 3 /* config for I2S link */ -#define I2S_MERGER 0 -#define I2S_SPLITTER 0 -#define I2S_MIXER 7 -#define I2S_RATE 44100 - -#define MODEM_INTDEC 4 /* config for modem link */ -#define MODEM_MERGER 3 -#define MODEM_SPLITTER 0 -#define MODEM_MIXER 11 - -#define FM_INTDEC 3 /* config for FM/OPL3 link */ -#define FM_MERGER 0 -#define FM_SPLITTER 0 -#define FM_MIXER 9 - -#define SPLIT_PATH 0x80 /* path splitting flag */ - -enum FIRMWARE { - DATA_REC = 0, EXT_END_OF_FILE, EXT_SEG_ADDR_REC, EXT_GOTO_CMD_REC, - EXT_LIN_ADDR_REC, -}; - -enum CMDS { - GETV = 0x00, GETC, GUNS, SCID, RMEM = - 0x10, SMEM, WMEM, SDTM, GOTO, SSTR = - 0x20, PSTR, KSTR, KDMA, GPOS, SETF, GSTS, NGPOS, PSEL = - 0x30, PCLR, PLST, RSSV, LSEL, SSRC = 0x40, SLST, RSRC, SSRB, SDGV = - 0x50, RDGV, DLST, SACR = 0x60, RACR, ALST, TXAC, RXAC, SI2S = - 0x70, ARM_SETDPLL = 0x72, -}; - -enum E1SOURCE { - ARM2LBUS_FIFO0 = 0, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2, ARM2LBUS_FIFO3, - ARM2LBUS_FIFO4, ARM2LBUS_FIFO5, ARM2LBUS_FIFO6, ARM2LBUS_FIFO7, - ARM2LBUS_FIFO8, ARM2LBUS_FIFO9, ARM2LBUS_FIFO10, ARM2LBUS_FIFO11, - ARM2LBUS_FIFO12, ARM2LBUS_FIFO13, ARM2LBUS_FIFO14, ARM2LBUS_FIFO15, - INTER0_OUT, INTER1_OUT, INTER2_OUT, INTER3_OUT, INTER4_OUT, - INTERM0_OUT, INTERM1_OUT, INTERM2_OUT, INTERM3_OUT, INTERM4_OUT, - INTERM5_OUT, INTERM6_OUT, DECIMM0_OUT, DECIMM1_OUT, DECIMM2_OUT, - DECIMM3_OUT, DECIM0_OUT, SR3_4_OUT, OPL3_SAMPLE, ASRC0, ASRC1, - ACLNK2PADC, ACLNK2MODEM0RX, ACLNK2MIC, ACLNK2MODEM1RX, ACLNK2HNDMIC, - DIGITAL_MIXER_OUT0, GAINFUNC0_OUT, GAINFUNC1_OUT, GAINFUNC2_OUT, - GAINFUNC3_OUT, GAINFUNC4_OUT, SOFTMODEMTX, SPLITTER0_OUTL, - SPLITTER0_OUTR, SPLITTER1_OUTL, SPLITTER1_OUTR, SPLITTER2_OUTL, - SPLITTER2_OUTR, SPLITTER3_OUTL, SPLITTER3_OUTR, MERGER0_OUT, - MERGER1_OUT, MERGER2_OUT, MERGER3_OUT, ARM2LBUS_FIFO_DIRECT, NO_OUT -}; - -enum E2SINK { - LBUS2ARM_FIFO0 = 0, LBUS2ARM_FIFO1, LBUS2ARM_FIFO2, LBUS2ARM_FIFO3, - LBUS2ARM_FIFO4, LBUS2ARM_FIFO5, LBUS2ARM_FIFO6, LBUS2ARM_FIFO7, - INTER0_IN, INTER1_IN, INTER2_IN, INTER3_IN, INTER4_IN, INTERM0_IN, - INTERM1_IN, INTERM2_IN, INTERM3_IN, INTERM4_IN, INTERM5_IN, INTERM6_IN, - DECIMM0_IN, DECIMM1_IN, DECIMM2_IN, DECIMM3_IN, DECIM0_IN, SR3_4_IN, - PDAC2ACLNK, MODEM0TX2ACLNK, MODEM1TX2ACLNK, HNDSPK2ACLNK, - DIGITAL_MIXER_IN0, DIGITAL_MIXER_IN1, DIGITAL_MIXER_IN2, - DIGITAL_MIXER_IN3, DIGITAL_MIXER_IN4, DIGITAL_MIXER_IN5, - DIGITAL_MIXER_IN6, DIGITAL_MIXER_IN7, DIGITAL_MIXER_IN8, - DIGITAL_MIXER_IN9, DIGITAL_MIXER_IN10, DIGITAL_MIXER_IN11, - GAINFUNC0_IN, GAINFUNC1_IN, GAINFUNC2_IN, GAINFUNC3_IN, GAINFUNC4_IN, - SOFTMODEMRX, SPLITTER0_IN, SPLITTER1_IN, SPLITTER2_IN, SPLITTER3_IN, - MERGER0_INL, MERGER0_INR, MERGER1_INL, MERGER1_INR, MERGER2_INL, - MERGER2_INR, MERGER3_INL, MERGER3_INR, E2SINK_MAX -}; - -enum LBUS_SINK { - LS_SRC_INTERPOLATOR = 0, LS_SRC_INTERPOLATORM, LS_SRC_DECIMATOR, - LS_SRC_DECIMATORM, LS_MIXER_IN, LS_MIXER_GAIN_FUNCTION, - LS_SRC_SPLITTER, LS_SRC_MERGER, LS_NONE1, LS_NONE2, -}; - -enum RT_CHANNEL_IDS { - M0TX = 0, M1TX, TAMTX, HSSPKR, PDAC, DSNDTX0, DSNDTX1, DSNDTX2, - DSNDTX3, DSNDTX4, DSNDTX5, DSNDTX6, DSNDTX7, WVSTRTX, COP3DTX, SPARE, - M0RX, HSMIC, M1RX, CLEANRX, MICADC, PADC, COPRX1, COPRX2, - CHANNEL_ID_COUNTER -}; - -enum { SB_CMD = 0, MODEM_CMD, I2S_CMD0, I2S_CMD1, FM_CMD, MAX_CMD }; - -struct lbuspath { - unsigned char *noconv; - unsigned char *stereo; - unsigned char *mono; -}; - -struct cmdport { - u32 data1; /* cmd,param */ - u32 data2; /* param */ - u32 stat; /* status */ - u32 pad[5]; -}; - -struct riptideport { - u32 audio_control; /* status registers */ - u32 audio_status; - u32 pad[2]; - struct cmdport port[2]; /* command ports */ -}; - -struct cmdif { - struct riptideport *hwport; - spinlock_t lock; - unsigned int cmdcnt; /* cmd statistics */ - unsigned int cmdtime; - unsigned int cmdtimemax; - unsigned int cmdtimemin; - unsigned int errcnt; - int is_reset; -}; - -struct riptide_firmware { - u16 ASIC; - u16 CODEC; - u16 AUXDSP; - u16 PROG; -}; - -union cmdret { - u8 retbytes[8]; - u16 retwords[4]; - u32 retlongs[2]; -}; - -union firmware_version { - union cmdret ret; - struct riptide_firmware firmware; -}; - -#define get_pcmhwdev(substream) (struct pcmhw *)(substream->runtime->private_data) - -#define PLAYBACK_SUBSTREAMS 3 -struct snd_riptide { - struct snd_card *card; - struct pci_dev *pci; - const struct firmware *fw_entry; - - struct cmdif *cif; - - struct snd_pcm *pcm; - struct snd_pcm *pcm_i2s; - struct snd_rawmidi *rmidi; - struct snd_opl3 *opl3; - struct snd_ac97 *ac97; - struct snd_ac97_bus *ac97_bus; - - struct snd_pcm_substream *playback_substream[PLAYBACK_SUBSTREAMS]; - struct snd_pcm_substream *capture_substream; - - int openstreams; - - int irq; - unsigned long port; - unsigned short mpuaddr; - unsigned short opladdr; -#ifdef SUPPORT_JOYSTICK - unsigned short gameaddr; -#endif - struct resource *res_port; - - unsigned short device_id; - - union firmware_version firmware; - - spinlock_t lock; - struct tasklet_struct riptide_tq; - struct snd_info_entry *proc_entry; - - unsigned long received_irqs; - unsigned long handled_irqs; -#ifdef CONFIG_PM - int in_suspend; -#endif -}; - -struct sgd { /* scatter gather desriptor */ - u32 dwNextLink; - u32 dwSegPtrPhys; - u32 dwSegLen; - u32 dwStat_Ctl; -}; - -struct pcmhw { /* pcm descriptor */ - struct lbuspath paths; - unsigned char *lbuspath; - unsigned char source; - unsigned char intdec[2]; - unsigned char mixer; - unsigned char id; - unsigned char state; - unsigned int rate; - unsigned int channels; - snd_pcm_format_t format; - struct snd_dma_buffer sgdlist; - struct sgd *sgdbuf; - unsigned int size; - unsigned int pages; - unsigned int oldpos; - unsigned int pointer; -}; - -#define CMDRET_ZERO (union cmdret){{(u32)0, (u32) 0}} - -static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm, - union cmdret *ret); -static int getsourcesink(struct cmdif *cif, unsigned char source, - unsigned char sink, unsigned char *a, - unsigned char *b); -static int snd_riptide_initialize(struct snd_riptide *chip); -static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip); - -/* - */ - -static struct pci_device_id snd_riptide_ids[] __devinitdata = { - { - .vendor = 0x127a,.device = 0x4310, - .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, - }, - { - .vendor = 0x127a,.device = 0x4320, - .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, - }, - { - .vendor = 0x127a,.device = 0x4330, - .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, - }, - { - .vendor = 0x127a,.device = 0x4340, - .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, - }, - {0,}, -}; - -#ifdef SUPPORT_JOYSTICK -static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = { - { - .vendor = 0x127a,.device = 0x4312, - .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, - }, - { - .vendor = 0x127a,.device = 0x4322, - .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, - }, - {.vendor = 0x127a,.device = 0x4332, - .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, - }, - {.vendor = 0x127a,.device = 0x4342, - .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, - }, - {0,}, -}; -#endif - -MODULE_DEVICE_TABLE(pci, snd_riptide_ids); - -/* - */ - -static unsigned char lbusin2out[E2SINK_MAX + 1][2] = { - {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT, - LS_NONE2}, - {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT, - LS_NONE2}, - {INTER0_OUT, LS_SRC_INTERPOLATOR}, {INTER1_OUT, LS_SRC_INTERPOLATOR}, - {INTER2_OUT, LS_SRC_INTERPOLATOR}, {INTER3_OUT, LS_SRC_INTERPOLATOR}, - {INTER4_OUT, LS_SRC_INTERPOLATOR}, {INTERM0_OUT, LS_SRC_INTERPOLATORM}, - {INTERM1_OUT, LS_SRC_INTERPOLATORM}, {INTERM2_OUT, - LS_SRC_INTERPOLATORM}, - {INTERM3_OUT, LS_SRC_INTERPOLATORM}, {INTERM4_OUT, - LS_SRC_INTERPOLATORM}, - {INTERM5_OUT, LS_SRC_INTERPOLATORM}, {INTERM6_OUT, - LS_SRC_INTERPOLATORM}, - {DECIMM0_OUT, LS_SRC_DECIMATORM}, {DECIMM1_OUT, LS_SRC_DECIMATORM}, - {DECIMM2_OUT, LS_SRC_DECIMATORM}, {DECIMM3_OUT, LS_SRC_DECIMATORM}, - {DECIM0_OUT, LS_SRC_DECIMATOR}, {SR3_4_OUT, LS_NONE1}, {NO_OUT, - LS_NONE2}, - {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, - {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, - {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, - {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, - {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, - {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, - {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, - {GAINFUNC0_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC1_OUT, - LS_MIXER_GAIN_FUNCTION}, - {GAINFUNC2_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC3_OUT, - LS_MIXER_GAIN_FUNCTION}, - {GAINFUNC4_OUT, LS_MIXER_GAIN_FUNCTION}, {SOFTMODEMTX, LS_NONE1}, - {SPLITTER0_OUTL, LS_SRC_SPLITTER}, {SPLITTER1_OUTL, LS_SRC_SPLITTER}, - {SPLITTER2_OUTL, LS_SRC_SPLITTER}, {SPLITTER3_OUTL, LS_SRC_SPLITTER}, - {MERGER0_OUT, LS_SRC_MERGER}, {MERGER0_OUT, LS_SRC_MERGER}, - {MERGER1_OUT, LS_SRC_MERGER}, - {MERGER1_OUT, LS_SRC_MERGER}, {MERGER2_OUT, LS_SRC_MERGER}, - {MERGER2_OUT, LS_SRC_MERGER}, - {MERGER3_OUT, LS_SRC_MERGER}, {MERGER3_OUT, LS_SRC_MERGER}, {NO_OUT, - LS_NONE2}, -}; - -static unsigned char lbus_play_opl3[] = { - DIGITAL_MIXER_IN0 + FM_MIXER, 0xff -}; -static unsigned char lbus_play_modem[] = { - DIGITAL_MIXER_IN0 + MODEM_MIXER, 0xff -}; -static unsigned char lbus_play_i2s[] = { - INTER0_IN + I2S_INTDEC, DIGITAL_MIXER_IN0 + I2S_MIXER, 0xff -}; -static unsigned char lbus_play_out[] = { - PDAC2ACLNK, 0xff -}; -static unsigned char lbus_play_outhp[] = { - HNDSPK2ACLNK, 0xff -}; -static unsigned char lbus_play_noconv1[] = { - DIGITAL_MIXER_IN0, 0xff -}; -static unsigned char lbus_play_stereo1[] = { - INTER0_IN, DIGITAL_MIXER_IN0, 0xff -}; -static unsigned char lbus_play_mono1[] = { - INTERM0_IN, DIGITAL_MIXER_IN0, 0xff -}; -static unsigned char lbus_play_noconv2[] = { - DIGITAL_MIXER_IN1, 0xff -}; -static unsigned char lbus_play_stereo2[] = { - INTER1_IN, DIGITAL_MIXER_IN1, 0xff -}; -static unsigned char lbus_play_mono2[] = { - INTERM1_IN, DIGITAL_MIXER_IN1, 0xff -}; -static unsigned char lbus_play_noconv3[] = { - DIGITAL_MIXER_IN2, 0xff -}; -static unsigned char lbus_play_stereo3[] = { - INTER2_IN, DIGITAL_MIXER_IN2, 0xff -}; -static unsigned char lbus_play_mono3[] = { - INTERM2_IN, DIGITAL_MIXER_IN2, 0xff -}; -static unsigned char lbus_rec_noconv1[] = { - LBUS2ARM_FIFO5, 0xff -}; -static unsigned char lbus_rec_stereo1[] = { - DECIM0_IN, LBUS2ARM_FIFO5, 0xff -}; -static unsigned char lbus_rec_mono1[] = { - DECIMM3_IN, LBUS2ARM_FIFO5, 0xff -}; - -static unsigned char play_ids[] = { 4, 1, 2, }; -static unsigned char play_sources[] = { - ARM2LBUS_FIFO4, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2, -}; -static struct lbuspath lbus_play_paths[] = { - { - .noconv = lbus_play_noconv1, - .stereo = lbus_play_stereo1, - .mono = lbus_play_mono1, - }, - { - .noconv = lbus_play_noconv2, - .stereo = lbus_play_stereo2, - .mono = lbus_play_mono2, - }, - { - .noconv = lbus_play_noconv3, - .stereo = lbus_play_stereo3, - .mono = lbus_play_mono3, - }, -}; -static struct lbuspath lbus_rec_path = { - .noconv = lbus_rec_noconv1, - .stereo = lbus_rec_stereo1, - .mono = lbus_rec_mono1, -}; - -#define FIRMWARE_VERSIONS 1 -static union firmware_version firmware_versions[] = { - { - .firmware.ASIC = 3,.firmware.CODEC = 2, - .firmware.AUXDSP = 3,.firmware.PROG = 773, - }, -}; - -static u32 atoh(unsigned char *in, unsigned int len) -{ - u32 sum = 0; - unsigned int mult = 1; - unsigned char c; - - while (len) { - c = in[len - 1]; - if ((c >= '0') && (c <= '9')) - sum += mult * (c - '0'); - else if ((c >= 'A') && (c <= 'F')) - sum += mult * (c - ('A' - 10)); - else if ((c >= 'a') && (c <= 'f')) - sum += mult * (c - ('a' - 10)); - mult *= 16; - --len; - } - return sum; -} - -static int senddata(struct cmdif *cif, unsigned char *in, u32 offset) -{ - u32 addr; - u32 data; - u32 i; - unsigned char *p; - - i = atoh(&in[1], 2); - addr = offset + atoh(&in[3], 4); - if (SEND_SMEM(cif, 0, addr) != 0) - return -EACCES; - p = in + 9; - while (i) { - data = atoh(p, 8); - if (SEND_WMEM(cif, 2, - ((data & 0x0f0f0f0f) << 4) | ((data & 0xf0f0f0f0) - >> 4))) - return -EACCES; - i -= 4; - p += 8; - } - return 0; -} - -static int loadfirmware(struct cmdif *cif, unsigned char *img, - unsigned int size) -{ - unsigned char *in; - u32 laddr, saddr, t, val; - int err = 0; - - laddr = saddr = 0; - while (size > 0 && err == 0) { - in = img; - if (in[0] == ':') { - t = atoh(&in[7], 2); - switch (t) { - case DATA_REC: - err = senddata(cif, in, laddr + saddr); - break; - case EXT_SEG_ADDR_REC: - saddr = atoh(&in[9], 4) << 4; - break; - case EXT_LIN_ADDR_REC: - laddr = atoh(&in[9], 4) << 16; - break; - case EXT_GOTO_CMD_REC: - val = atoh(&in[9], 8); - if (SEND_GOTO(cif, val) != 0) - err = -EACCES; - break; - case EXT_END_OF_FILE: - size = 0; - break; - default: - break; - } - while (size > 0) { - size--; - if (*img++ == '\n') - break; - } - } - } - snd_printdd("load firmware return %d\n", err); - return err; -} - -static void -alloclbuspath(struct cmdif *cif, unsigned char source, - unsigned char *path, unsigned char *mixer, unsigned char *s) -{ - while (*path != 0xff) { - unsigned char sink, type; - - sink = *path & (~SPLIT_PATH); - if (sink != E2SINK_MAX) { - snd_printdd("alloc path 0x%x->0x%x\n", source, sink); - SEND_PSEL(cif, source, sink); - source = lbusin2out[sink][0]; - type = lbusin2out[sink][1]; - if (type == LS_MIXER_IN) { - if (mixer) - *mixer = sink - DIGITAL_MIXER_IN0; - } - if (type == LS_SRC_DECIMATORM || - type == LS_SRC_DECIMATOR || - type == LS_SRC_INTERPOLATORM || - type == LS_SRC_INTERPOLATOR) { - if (s) { - if (s[0] != 0xff) - s[1] = sink; - else - s[0] = sink; - } - } - } - if (*path++ & SPLIT_PATH) { - unsigned char *npath = path; - - while (*npath != 0xff) - npath++; - alloclbuspath(cif, source + 1, ++npath, mixer, s); - } - } -} - -static void -freelbuspath(struct cmdif *cif, unsigned char source, unsigned char *path) -{ - while (*path != 0xff) { - unsigned char sink; - - sink = *path & (~SPLIT_PATH); - if (sink != E2SINK_MAX) { - snd_printdd("free path 0x%x->0x%x\n", source, sink); - SEND_PCLR(cif, source, sink); - source = lbusin2out[sink][0]; - } - if (*path++ & SPLIT_PATH) { - unsigned char *npath = path; - - while (*npath != 0xff) - npath++; - freelbuspath(cif, source + 1, ++npath); - } - } -} - -static int writearm(struct cmdif *cif, u32 addr, u32 data, u32 mask) -{ - union cmdret rptr = CMDRET_ZERO; - unsigned int i = MAX_WRITE_RETRY; - int flag = 1; - - SEND_RMEM(cif, 0x02, addr, &rptr); - rptr.retlongs[0] &= (~mask); - - while (--i) { - SEND_SMEM(cif, 0x01, addr); - SEND_WMEM(cif, 0x02, (rptr.retlongs[0] | data)); - SEND_RMEM(cif, 0x02, addr, &rptr); - if ((rptr.retlongs[0] & data) == data) { - flag = 0; - break; - } else - rptr.retlongs[0] &= ~mask; - } - snd_printdd("send arm 0x%x 0x%x 0x%x return %d\n", addr, data, mask, - flag); - return flag; -} - -static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm, - union cmdret *ret) -{ - int i, j; - int err; - unsigned int time = 0; - unsigned long irqflags; - struct riptideport *hwport; - struct cmdport *cmdport = NULL; - - snd_assert(cif, return -EINVAL); - - hwport = cif->hwport; - if (cif->errcnt > MAX_ERROR_COUNT) { - if (cif->is_reset) { - snd_printk(KERN_ERR - "Riptide: Too many failed cmds, reinitializing\n"); - if (riptide_reset(cif, NULL) == 0) { - cif->errcnt = 0; - return -EIO; - } - } - snd_printk(KERN_ERR "Riptide: Initialization failed.\n"); - return -EINVAL; - } - if (ret) { - ret->retlongs[0] = 0; - ret->retlongs[1] = 0; - } - i = 0; - spin_lock_irqsave(&cif->lock, irqflags); - while (i++ < CMDIF_TIMEOUT && !IS_READY(cif->hwport)) - udelay(10); - if (i >= CMDIF_TIMEOUT) { - err = -EBUSY; - goto errout; - } - - err = 0; - for (j = 0, time = 0; time < CMDIF_TIMEOUT; j++, time += 2) { - cmdport = &(hwport->port[j % 2]); - if (IS_DATF(cmdport)) { /* free pending data */ - READ_PORT_ULONG(cmdport->data1); - READ_PORT_ULONG(cmdport->data2); - } - if (IS_CMDE(cmdport)) { - if (flags & PARM) /* put data */ - WRITE_PORT_ULONG(cmdport->data2, parm); - WRITE_PORT_ULONG(cmdport->data1, cmd); /* write cmd */ - if ((flags & RESP) && ret) { - while (!IS_DATF(cmdport) && - time++ < CMDIF_TIMEOUT) - udelay(10); - if (time < CMDIF_TIMEOUT) { /* read response */ - ret->retlongs[0] = - READ_PORT_ULONG(cmdport->data1); - ret->retlongs[1] = - READ_PORT_ULONG(cmdport->data2); - } else { - err = -ENOSYS; - goto errout; - } - } - break; - } - udelay(20); - } - if (time == CMDIF_TIMEOUT) { - err = -ENODATA; - goto errout; - } - spin_unlock_irqrestore(&cif->lock, irqflags); - - cif->cmdcnt++; /* update command statistics */ - cif->cmdtime += time; - if (time > cif->cmdtimemax) - cif->cmdtimemax = time; - if (time < cif->cmdtimemin) - cif->cmdtimemin = time; - if ((cif->cmdcnt) % 1000 == 0) - snd_printdd - ("send cmd %d time: %d mintime: %d maxtime %d err: %d\n", - cif->cmdcnt, cif->cmdtime, cif->cmdtimemin, - cif->cmdtimemax, cif->errcnt); - return 0; - - errout: - cif->errcnt++; - spin_unlock_irqrestore(&cif->lock, irqflags); - snd_printdd - ("send cmd %d hw: 0x%x flag: 0x%x cmd: 0x%x parm: 0x%x ret: 0x%x 0x%x CMDE: %d DATF: %d failed %d\n", - cif->cmdcnt, (int)((void *)&(cmdport->stat) - (void *)hwport), - flags, cmd, parm, ret ? ret->retlongs[0] : 0, - ret ? ret->retlongs[1] : 0, IS_CMDE(cmdport), IS_DATF(cmdport), - err); - return err; -} - -static int -setmixer(struct cmdif *cif, short num, unsigned short rval, unsigned short lval) -{ - union cmdret rptr = CMDRET_ZERO; - int i = 0; - - snd_printdd("sent mixer %d: 0x%d 0x%d\n", num, rval, lval); - do { - SEND_SDGV(cif, num, num, rval, lval); - SEND_RDGV(cif, num, num, &rptr); - if (rptr.retwords[0] == lval && rptr.retwords[1] == rval) - return 0; - } while (i++ < MAX_WRITE_RETRY); - snd_printdd("sent mixer failed\n"); - return -EIO; -} - -static int getpaths(struct cmdif *cif, unsigned char *o) -{ - unsigned char src[E2SINK_MAX]; - unsigned char sink[E2SINK_MAX]; - int i, j = 0; - - for (i = 0; i < E2SINK_MAX; i++) { - getsourcesink(cif, i, i, &src[i], &sink[i]); - if (sink[i] < E2SINK_MAX) { - o[j++] = sink[i]; - o[j++] = i; - } - } - return j; -} - -static int -getsourcesink(struct cmdif *cif, unsigned char source, unsigned char sink, - unsigned char *a, unsigned char *b) -{ - union cmdret rptr = CMDRET_ZERO; - - if (SEND_RSSV(cif, source, sink, &rptr) && - SEND_RSSV(cif, source, sink, &rptr)) - return -EIO; - *a = rptr.retbytes[0]; - *b = rptr.retbytes[1]; - snd_printdd("getsourcesink 0x%x 0x%x\n", *a, *b); - return 0; -} - -static int -getsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int *rate) -{ - unsigned char *s; - unsigned int p[2] = { 0, 0 }; - int i; - union cmdret rptr = CMDRET_ZERO; - - s = intdec; - for (i = 0; i < 2; i++) { - if (*s != 0xff) { - if (SEND_RSRC(cif, *s, &rptr) && - SEND_RSRC(cif, *s, &rptr)) - return -EIO; - p[i] += rptr.retwords[1]; - p[i] *= rptr.retwords[2]; - p[i] += rptr.retwords[3]; - p[i] /= 65536; - } - s++; - } - if (p[0]) { - if (p[1] != p[0]) - snd_printdd("rates differ %d %d\n", p[0], p[1]); - *rate = (unsigned int)p[0]; - } else - *rate = (unsigned int)p[1]; - snd_printdd("getsampleformat %d %d %d\n", intdec[0], intdec[1], *rate); - return 0; -} - -static int -setsampleformat(struct cmdif *cif, - unsigned char mixer, unsigned char id, - unsigned char channels, unsigned char format) -{ - unsigned char w, ch, sig, order; - - snd_printdd - ("setsampleformat mixer: %d id: %d channels: %d format: %d\n", - mixer, id, channels, format); - ch = channels == 1; - w = snd_pcm_format_width(format) == 8; - sig = snd_pcm_format_unsigned(format) != 0; - order = snd_pcm_format_big_endian(format) != 0; - - if (SEND_SETF(cif, mixer, w, ch, order, sig, id) && - SEND_SETF(cif, mixer, w, ch, order, sig, id)) { - snd_printdd("setsampleformat failed\n"); - return -EIO; - } - return 0; -} - -static int -setsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int rate) -{ - u32 D, M, N; - union cmdret rptr = CMDRET_ZERO; - int i; - - snd_printdd("setsamplerate intdec: %d,%d rate: %d\n", intdec[0], - intdec[1], rate); - D = 48000; - M = ((rate == 48000) ? 47999 : rate) * 65536; - N = M % D; - M /= D; - for (i = 0; i < 2; i++) { - if (*intdec != 0xff) { - do { - SEND_SSRC(cif, *intdec, D, M, N); - SEND_RSRC(cif, *intdec, &rptr); - } while (rptr.retwords[1] != D && - rptr.retwords[2] != M && - rptr.retwords[3] != N && - i++ < MAX_WRITE_RETRY); - if (i == MAX_WRITE_RETRY) { - snd_printdd("sent samplerate %d: %d failed\n", - *intdec, rate); - return -EIO; - } - } - intdec++; - } - return 0; -} - -static int -getmixer(struct cmdif *cif, short num, unsigned short *rval, - unsigned short *lval) -{ - union cmdret rptr = CMDRET_ZERO; - - if (SEND_RDGV(cif, num, num, &rptr) && SEND_RDGV(cif, num, num, &rptr)) - return -EIO; - *rval = rptr.retwords[0]; - *lval = rptr.retwords[1]; - snd_printdd("got mixer %d: 0x%d 0x%d\n", num, *rval, *lval); - return 0; -} - -static void riptide_handleirq(unsigned long dev_id) -{ - struct snd_riptide *chip = (void *)dev_id; - struct cmdif *cif = chip->cif; - struct snd_pcm_substream *substream[PLAYBACK_SUBSTREAMS + 1]; - struct snd_pcm_runtime *runtime; - struct pcmhw *data = NULL; - unsigned int pos, period_bytes; - struct sgd *c; - int i, j; - unsigned int flag; - - if (!cif) - return; - - for (i = 0; i < PLAYBACK_SUBSTREAMS; i++) - substream[i] = chip->playback_substream[i]; - substream[i] = chip->capture_substream; - for (i = 0; i < PLAYBACK_SUBSTREAMS + 1; i++) { - if (substream[i] && - (runtime = substream[i]->runtime) && - (data = runtime->private_data) && data->state != ST_STOP) { - pos = 0; - for (j = 0; j < data->pages; j++) { - c = &data->sgdbuf[j]; - flag = le32_to_cpu(c->dwStat_Ctl); - if (flag & EOB_STATUS) - pos += le32_to_cpu(c->dwSegLen); - if (flag & EOC_STATUS) - pos += le32_to_cpu(c->dwSegLen); - if ((flag & EOS_STATUS) - && (data->state == ST_PLAY)) { - data->state = ST_STOP; - snd_printk(KERN_ERR - "Riptide: DMA stopped unexpectedly\n"); - } - c->dwStat_Ctl = - cpu_to_le32(flag & - ~(EOS_STATUS | EOB_STATUS | - EOC_STATUS)); - } - data->pointer += pos; - pos += data->oldpos; - if (data->state != ST_STOP) { - period_bytes = - frames_to_bytes(runtime, - runtime->period_size); - snd_printdd - ("interrupt 0x%x after 0x%lx of 0x%lx frames in period\n", - READ_AUDIO_STATUS(cif->hwport), - bytes_to_frames(runtime, pos), - runtime->period_size); - j = 0; - if (pos >= period_bytes) { - j++; - while (pos >= period_bytes) - pos -= period_bytes; - } - data->oldpos = pos; - if (j > 0) - snd_pcm_period_elapsed(substream[i]); - } - } - } -} - -#ifdef CONFIG_PM -static int riptide_suspend(struct pci_dev *pci, pm_message_t state) -{ - struct snd_card *card = pci_get_drvdata(pci); - struct snd_riptide *chip = card->private_data; - - chip->in_suspend = 1; - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); - snd_ac97_suspend(chip->ac97); - pci_set_power_state(pci, PCI_D3hot); - pci_disable_device(pci); - pci_save_state(pci); - return 0; -} - -static int riptide_resume(struct pci_dev *pci) -{ - struct snd_card *card = pci_get_drvdata(pci); - struct snd_riptide *chip = card->private_data; - - pci_restore_state(pci); - pci_enable_device(pci); - pci_set_power_state(pci, PCI_D0); - pci_set_master(pci); - snd_riptide_initialize(chip); - snd_ac97_resume(chip->ac97); - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - chip->in_suspend = 0; - return 0; -} -#endif - -static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip) -{ - int timeout, tries; - union cmdret rptr = CMDRET_ZERO; - union firmware_version firmware; - int i, j, err, has_firmware; - - if (!cif) - return -EINVAL; - - cif->cmdcnt = 0; - cif->cmdtime = 0; - cif->cmdtimemax = 0; - cif->cmdtimemin = 0xffffffff; - cif->errcnt = 0; - cif->is_reset = 0; - - tries = RESET_TRIES; - has_firmware = 0; - while (has_firmware == 0 && tries-- > 0) { - for (i = 0; i < 2; i++) { - WRITE_PORT_ULONG(cif->hwport->port[i].data1, 0); - WRITE_PORT_ULONG(cif->hwport->port[i].data2, 0); - } - SET_GRESET(cif->hwport); - udelay(100); - UNSET_GRESET(cif->hwport); - udelay(100); - - for (timeout = 100000; --timeout; udelay(10)) { - if (IS_READY(cif->hwport) && !IS_GERR(cif->hwport)) - break; - } - if (timeout == 0) { - snd_printk(KERN_ERR - "Riptide: device not ready, audio status: 0x%x ready: %d gerr: %d\n", - READ_AUDIO_STATUS(cif->hwport), - IS_READY(cif->hwport), IS_GERR(cif->hwport)); - return -EIO; - } else { - snd_printdd - ("Riptide: audio status: 0x%x ready: %d gerr: %d\n", - READ_AUDIO_STATUS(cif->hwport), - IS_READY(cif->hwport), IS_GERR(cif->hwport)); - } - - SEND_GETV(cif, &rptr); - for (i = 0; i < 4; i++) - firmware.ret.retwords[i] = rptr.retwords[i]; - - snd_printdd - ("Firmware version: ASIC: %d CODEC %d AUXDSP %d PROG %d\n", - firmware.firmware.ASIC, firmware.firmware.CODEC, - firmware.firmware.AUXDSP, firmware.firmware.PROG); - - for (j = 0; j < FIRMWARE_VERSIONS; j++) { - has_firmware = 1; - for (i = 0; i < 4; i++) { - if (firmware_versions[j].ret.retwords[i] != - firmware.ret.retwords[i]) - has_firmware = 0; - } - if (has_firmware) - break; - } - - if (chip != NULL && has_firmware == 0) { - snd_printdd("Writing Firmware\n"); - if (!chip->fw_entry) { - if ((err = - request_firmware(&chip->fw_entry, - "riptide.hex", - &chip->pci->dev)) != 0) { - snd_printk(KERN_ERR - "Riptide: Firmware not available %d\n", - err); - return -EIO; - } - } - err = loadfirmware(cif, chip->fw_entry->data, - chip->fw_entry->size); - if (err) - snd_printk(KERN_ERR - "Riptide: Could not load firmware %d\n", - err); - } - } - - SEND_SACR(cif, 0, AC97_RESET); - SEND_RACR(cif, AC97_RESET, &rptr); - snd_printdd("AC97: 0x%x 0x%x\n", rptr.retlongs[0], rptr.retlongs[1]); - - SEND_PLST(cif, 0); - SEND_SLST(cif, 0); - SEND_DLST(cif, 0); - SEND_ALST(cif, 0); - SEND_KDMA(cif); - - writearm(cif, 0x301F8, 1, 1); - writearm(cif, 0x301F4, 1, 1); - - SEND_LSEL(cif, MODEM_CMD, 0, 0, MODEM_INTDEC, MODEM_MERGER, - MODEM_SPLITTER, MODEM_MIXER); - setmixer(cif, MODEM_MIXER, 0x7fff, 0x7fff); - alloclbuspath(cif, ARM2LBUS_FIFO13, lbus_play_modem, NULL, NULL); - - SEND_LSEL(cif, FM_CMD, 0, 0, FM_INTDEC, FM_MERGER, FM_SPLITTER, - FM_MIXER); - setmixer(cif, FM_MIXER, 0x7fff, 0x7fff); - writearm(cif, 0x30648 + FM_MIXER * 4, 0x01, 0x00000005); - writearm(cif, 0x301A8, 0x02, 0x00000002); - writearm(cif, 0x30264, 0x08, 0xffffffff); - alloclbuspath(cif, OPL3_SAMPLE, lbus_play_opl3, NULL, NULL); - - SEND_SSRC(cif, I2S_INTDEC, 48000, - ((u32) I2S_RATE * 65536) / 48000, - ((u32) I2S_RATE * 65536) % 48000); - SEND_LSEL(cif, I2S_CMD0, 0, 0, I2S_INTDEC, I2S_MERGER, I2S_SPLITTER, - I2S_MIXER); - SEND_SI2S(cif, 1); - alloclbuspath(cif, ARM2LBUS_FIFO0, lbus_play_i2s, NULL, NULL); - alloclbuspath(cif, DIGITAL_MIXER_OUT0, lbus_play_out, NULL, NULL); - alloclbuspath(cif, DIGITAL_MIXER_OUT0, lbus_play_outhp, NULL, NULL); - - SET_AIACK(cif->hwport); - SET_AIE(cif->hwport); - SET_AIACK(cif->hwport); - cif->is_reset = 1; - if (chip) { - for (i = 0; i < 4; i++) - chip->firmware.ret.retwords[i] = - firmware.ret.retwords[i]; - } - - return 0; -} - -static struct snd_pcm_hardware snd_riptide_playback = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID), - .formats = - SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 - | SNDRV_PCM_FMTBIT_U16_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, - .rate_min = 5500, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (64 * 1024), - .period_bytes_min = PAGE_SIZE >> 1, - .period_bytes_max = PAGE_SIZE << 8, - .periods_min = 2, - .periods_max = 64, - .fifo_size = 0, -}; -static struct snd_pcm_hardware snd_riptide_capture = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID), - .formats = - SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 - | SNDRV_PCM_FMTBIT_U16_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, - .rate_min = 5500, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (64 * 1024), - .period_bytes_min = PAGE_SIZE >> 1, - .period_bytes_max = PAGE_SIZE << 3, - .periods_min = 2, - .periods_max = 64, - .fifo_size = 0, -}; - -static snd_pcm_uframes_t snd_riptide_pointer(struct snd_pcm_substream - *substream) -{ - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct pcmhw *data = get_pcmhwdev(substream); - struct cmdif *cif = chip->cif; - union cmdret rptr = CMDRET_ZERO; - snd_pcm_uframes_t ret; - - SEND_GPOS(cif, 0, data->id, &rptr); - if (data->size && runtime->period_size) { - snd_printdd - ("pointer stream %d position 0x%x(0x%x in buffer) bytes 0x%lx(0x%lx in period) frames\n", - data->id, rptr.retlongs[1], rptr.retlongs[1] % data->size, - bytes_to_frames(runtime, rptr.retlongs[1]), - bytes_to_frames(runtime, - rptr.retlongs[1]) % runtime->period_size); - if (rptr.retlongs[1] > data->pointer) - ret = - bytes_to_frames(runtime, - rptr.retlongs[1] % data->size); - else - ret = - bytes_to_frames(runtime, - data->pointer % data->size); - } else { - snd_printdd("stream not started or strange parms (%d %ld)\n", - data->size, runtime->period_size); - ret = bytes_to_frames(runtime, 0); - } - return ret; -} - -static int snd_riptide_trigger(struct snd_pcm_substream *substream, int cmd) -{ - int i, j; - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct pcmhw *data = get_pcmhwdev(substream); - struct cmdif *cif = chip->cif; - union cmdret rptr = CMDRET_ZERO; - - spin_lock(&chip->lock); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - if (!(data->state & ST_PLAY)) { - SEND_SSTR(cif, data->id, data->sgdlist.addr); - SET_AIE(cif->hwport); - data->state = ST_PLAY; - if (data->mixer != 0xff) - setmixer(cif, data->mixer, 0x7fff, 0x7fff); - chip->openstreams++; - data->oldpos = 0; - data->pointer = 0; - } - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - if (data->mixer != 0xff) - setmixer(cif, data->mixer, 0, 0); - setmixer(cif, data->mixer, 0, 0); - SEND_KSTR(cif, data->id); - data->state = ST_STOP; - chip->openstreams--; - j = 0; - do { - i = rptr.retlongs[1]; - SEND_GPOS(cif, 0, data->id, &rptr); - udelay(1); - } while (i != rptr.retlongs[1] && j++ < MAX_WRITE_RETRY); - if (j >= MAX_WRITE_RETRY) - snd_printk(KERN_ERR "Riptide: Could not stop stream!"); - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (!(data->state & ST_PAUSE)) { - SEND_PSTR(cif, data->id); - data->state |= ST_PAUSE; - chip->openstreams--; - } - break; - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (data->state & ST_PAUSE) { - SEND_SSTR(cif, data->id, data->sgdlist.addr); - data->state &= ~ST_PAUSE; - chip->openstreams++; - } - break; - default: - spin_unlock(&chip->lock); - return -EINVAL; - } - spin_unlock(&chip->lock); - return 0; -} - -static int snd_riptide_prepare(struct snd_pcm_substream *substream) -{ - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); - struct pcmhw *data = get_pcmhwdev(substream); - struct cmdif *cif = chip->cif; - unsigned char *lbuspath = NULL; - unsigned int rate, channels; - int err = 0; - snd_pcm_format_t format; - - snd_assert(cif && data, return -EINVAL); - - snd_printdd("prepare id %d ch: %d f:0x%x r:%d\n", data->id, - runtime->channels, runtime->format, runtime->rate); - - spin_lock_irq(&chip->lock); - channels = runtime->channels; - format = runtime->format; - rate = runtime->rate; - switch (channels) { - case 1: - if (rate == 48000 && format == SNDRV_PCM_FORMAT_S16_LE) - lbuspath = data->paths.noconv; - else - lbuspath = data->paths.mono; - break; - case 2: - if (rate == 48000 && format == SNDRV_PCM_FORMAT_S16_LE) - lbuspath = data->paths.noconv; - else - lbuspath = data->paths.stereo; - break; - } - snd_printdd("use sgdlist at 0x%p and buffer at 0x%p\n", - data->sgdlist.area, sgbuf); - if (data->sgdlist.area && sgbuf) { - unsigned int i, j, size, pages, f, pt, period; - struct sgd *c, *p = NULL; - - size = frames_to_bytes(runtime, runtime->buffer_size); - period = frames_to_bytes(runtime, runtime->period_size); - f = PAGE_SIZE; - while ((size + (f >> 1) - 1) <= (f << 7) && (f << 1) > period) - f = f >> 1; - pages = (size + f - 1) / f; - data->size = size; - data->pages = pages; - snd_printdd - ("create sgd size: 0x%x pages %d of size 0x%x for period 0x%x\n", - size, pages, f, period); - pt = 0; - j = 0; - for (i = 0; i < pages; i++) { - c = &data->sgdbuf[i]; - if (p) - p->dwNextLink = cpu_to_le32(data->sgdlist.addr + - (i * - sizeof(struct - sgd))); - c->dwNextLink = cpu_to_le32(data->sgdlist.addr); - c->dwSegPtrPhys = - cpu_to_le32(sgbuf->table[j].addr + pt); - pt = (pt + f) % PAGE_SIZE; - if (pt == 0) - j++; - c->dwSegLen = cpu_to_le32(f); - c->dwStat_Ctl = - cpu_to_le32(IEOB_ENABLE | IEOS_ENABLE | - IEOC_ENABLE); - p = c; - size -= f; - } - data->sgdbuf[i].dwSegLen = cpu_to_le32(size); - } - if (lbuspath && lbuspath != data->lbuspath) { - if (data->lbuspath) - freelbuspath(cif, data->source, data->lbuspath); - alloclbuspath(cif, data->source, lbuspath, - &data->mixer, data->intdec); - data->lbuspath = lbuspath; - data->rate = 0; - } - if (data->rate != rate || data->format != format || - data->channels != channels) { - data->rate = rate; - data->format = format; - data->channels = channels; - if (setsampleformat - (cif, data->mixer, data->id, channels, format) - || setsamplerate(cif, data->intdec, rate)) - err = -EIO; - } - spin_unlock_irq(&chip->lock); - return err; -} - -static int -snd_riptide_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct pcmhw *data = get_pcmhwdev(substream); - struct snd_dma_buffer *sgdlist = &data->sgdlist; - int err; - - snd_printdd("hw params id %d (sgdlist: 0x%p 0x%lx %d)\n", data->id, - sgdlist->area, (unsigned long)sgdlist->addr, - (int)sgdlist->bytes); - if (sgdlist->area) - snd_dma_free_pages(sgdlist); - if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), - sizeof(struct sgd) * (DESC_MAX_MASK + 1), - sgdlist)) < 0) { - snd_printk(KERN_ERR "Riptide: failed to alloc %d dma bytes\n", - (int)sizeof(struct sgd) * (DESC_MAX_MASK + 1)); - return err; - } - data->sgdbuf = (struct sgd *)sgdlist->area; - return snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); -} - -static int snd_riptide_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct pcmhw *data = get_pcmhwdev(substream); - struct cmdif *cif = chip->cif; - - if (cif && data) { - if (data->lbuspath) - freelbuspath(cif, data->source, data->lbuspath); - data->lbuspath = NULL; - data->source = 0xff; - data->intdec[0] = 0xff; - data->intdec[1] = 0xff; - - if (data->sgdlist.area) { - snd_dma_free_pages(&data->sgdlist); - data->sgdlist.area = NULL; - } - } - return snd_pcm_lib_free_pages(substream); -} - -static int snd_riptide_playback_open(struct snd_pcm_substream *substream) -{ - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct pcmhw *data; - int index = substream->number; - - chip->playback_substream[index] = substream; - runtime->hw = snd_riptide_playback; - data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); - data->paths = lbus_play_paths[index]; - data->id = play_ids[index]; - data->source = play_sources[index]; - data->intdec[0] = 0xff; - data->intdec[1] = 0xff; - data->state = ST_STOP; - runtime->private_data = data; - return snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); -} - -static int snd_riptide_capture_open(struct snd_pcm_substream *substream) -{ - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct pcmhw *data; - - chip->capture_substream = substream; - runtime->hw = snd_riptide_capture; - data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); - data->paths = lbus_rec_path; - data->id = PADC; - data->source = ACLNK2PADC; - data->intdec[0] = 0xff; - data->intdec[1] = 0xff; - data->state = ST_STOP; - runtime->private_data = data; - return snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); -} - -static int snd_riptide_playback_close(struct snd_pcm_substream *substream) -{ - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct pcmhw *data = get_pcmhwdev(substream); - int index = substream->number; - - substream->runtime->private_data = NULL; - chip->playback_substream[index] = NULL; - kfree(data); - return 0; -} - -static int snd_riptide_capture_close(struct snd_pcm_substream *substream) -{ - struct snd_riptide *chip = snd_pcm_substream_chip(substream); - struct pcmhw *data = get_pcmhwdev(substream); - - substream->runtime->private_data = NULL; - chip->capture_substream = NULL; - kfree(data); - return 0; -} - -static struct snd_pcm_ops snd_riptide_playback_ops = { - .open = snd_riptide_playback_open, - .close = snd_riptide_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_riptide_hw_params, - .hw_free = snd_riptide_hw_free, - .prepare = snd_riptide_prepare, - .page = snd_pcm_sgbuf_ops_page, - .trigger = snd_riptide_trigger, - .pointer = snd_riptide_pointer, -}; -static struct snd_pcm_ops snd_riptide_capture_ops = { - .open = snd_riptide_capture_open, - .close = snd_riptide_capture_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_riptide_hw_params, - .hw_free = snd_riptide_hw_free, - .prepare = snd_riptide_prepare, - .page = snd_pcm_sgbuf_ops_page, - .trigger = snd_riptide_trigger, - .pointer = snd_riptide_pointer, -}; - -static int __devinit -snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm) -{ - struct snd_pcm *pcm; - int err; - - if (rpcm) - *rpcm = NULL; - if ((err = - snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1, - &pcm)) < 0) - return err; - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_riptide_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &snd_riptide_capture_ops); - pcm->private_data = chip; - pcm->info_flags = 0; - strcpy(pcm->name, "RIPTIDE"); - chip->pcm = pcm; - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, - snd_dma_pci_data(chip->pci), - 64 * 1024, 128 * 1024); - if (rpcm) - *rpcm = pcm; - return 0; -} - -static irqreturn_t -snd_riptide_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct snd_riptide *chip = dev_id; - struct cmdif *cif = chip->cif; - - if (cif) { - chip->received_irqs++; - if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) || - IS_EOCIRQ(cif->hwport)) { - chip->handled_irqs++; - tasklet_hi_schedule(&chip->riptide_tq); - } - if (chip->rmidi && IS_MPUIRQ(cif->hwport)) { - chip->handled_irqs++; - snd_mpu401_uart_interrupt(irq, - chip->rmidi->private_data, - regs); - } - SET_AIACK(cif->hwport); - } - return IRQ_HANDLED; -} - -static void -snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - struct snd_riptide *chip = ac97->private_data; - struct cmdif *cif = chip->cif; - union cmdret rptr = CMDRET_ZERO; - int i = 0; - - snd_assert(cif, return); - - snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val); - do { - SEND_SACR(cif, val, reg); - SEND_RACR(cif, reg, &rptr); - } while (rptr.retwords[1] != val && i++ < MAX_WRITE_RETRY); - if (i == MAX_WRITE_RETRY) - snd_printdd("Write AC97 reg failed\n"); -} - -static unsigned short snd_riptide_codec_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - struct snd_riptide *chip = ac97->private_data; - struct cmdif *cif = chip->cif; - union cmdret rptr = CMDRET_ZERO; - - snd_assert(cif, return 0); - - if (SEND_RACR(cif, reg, &rptr) != 0) - SEND_RACR(cif, reg, &rptr); - snd_printdd("Read AC97 reg 0x%x got 0x%x\n", reg, rptr.retwords[1]); - return rptr.retwords[1]; -} - -static int snd_riptide_initialize(struct snd_riptide *chip) -{ - struct cmdif *cif; - unsigned int device_id; - int err; - - snd_assert(chip, return -EINVAL); - - cif = chip->cif; - if (!cif) { - if ((cif = kzalloc(sizeof(struct cmdif), GFP_KERNEL)) == NULL) - return -ENOMEM; - cif->hwport = (struct riptideport *)chip->port; - spin_lock_init(&cif->lock); - chip->cif = cif; - } - cif->is_reset = 0; - if ((err = riptide_reset(cif, chip)) != 0) - return err; - device_id = chip->device_id; - switch (device_id) { - case 0x4310: - case 0x4320: - case 0x4330: - snd_printdd("Modem enable?\n"); - SEND_SETDPLL(cif); - break; - } - snd_printdd("Enabling MPU IRQs\n"); - if (chip->rmidi) - SET_EMPUIRQ(cif->hwport); - return err; -} - -static int snd_riptide_free(struct snd_riptide *chip) -{ - struct cmdif *cif; - - snd_assert(chip, return 0); - - if ((cif = chip->cif)) { - SET_GRESET(cif->hwport); - udelay(100); - UNSET_GRESET(cif->hwport); - kfree(chip->cif); - } - if (chip->fw_entry) - release_firmware(chip->fw_entry); - release_and_free_resource(chip->res_port); - if (chip->irq >= 0) - free_irq(chip->irq, chip); - kfree(chip); - return 0; -} - -static int snd_riptide_dev_free(struct snd_device *device) -{ - struct snd_riptide *chip = device->device_data; - - return snd_riptide_free(chip); -} - -static int __devinit -snd_riptide_create(struct snd_card *card, struct pci_dev *pci, - struct snd_riptide **rchip) -{ - struct snd_riptide *chip; - struct riptideport *hwport; - int err; - static struct snd_device_ops ops = { - .dev_free = snd_riptide_dev_free, - }; - - *rchip = NULL; - if ((err = pci_enable_device(pci)) < 0) - return err; - if (!(chip = kzalloc(sizeof(struct snd_riptide), GFP_KERNEL))) - return -ENOMEM; - - spin_lock_init(&chip->lock); - chip->card = card; - chip->pci = pci; - chip->irq = -1; - chip->openstreams = 0; - chip->port = pci_resource_start(pci, 0); - chip->received_irqs = 0; - chip->handled_irqs = 0; - chip->cif = NULL; - tasklet_init(&chip->riptide_tq, riptide_handleirq, (unsigned long)chip); - - if ((chip->res_port = - request_region(chip->port, 64, "RIPTIDE")) == NULL) { - snd_printk(KERN_ERR - "Riptide: unable to grab region 0x%lx-0x%lx\n", - chip->port, chip->port + 64 - 1); - snd_riptide_free(chip); - return -EBUSY; - } - hwport = (struct riptideport *)chip->port; - UNSET_AIE(hwport); - - if (request_irq - (pci->irq, snd_riptide_interrupt, SA_INTERRUPT | SA_SHIRQ, - "RIPTIDE", chip)) { - snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n", - pci->irq); - snd_riptide_free(chip); - return -EBUSY; - } - chip->irq = pci->irq; - chip->device_id = pci->device; - pci_set_master(pci); - if ((err = snd_riptide_initialize(chip)) < 0) { - snd_riptide_free(chip); - return err; - } - - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_riptide_free(chip); - return err; - } - - *rchip = chip; - return 0; -} - -static void -snd_riptide_proc_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_riptide *chip = entry->private_data; - struct pcmhw *data; - int i; - struct cmdif *cif = NULL; - unsigned char p[256]; - unsigned short rval = 0, lval = 0; - unsigned int rate; - - if (!chip) - return; - - snd_iprintf(buffer, "%s\n\n", chip->card->longname); - snd_iprintf(buffer, "Device ID: 0x%x\nReceived IRQs: (%ld)%ld\nPorts:", - chip->device_id, chip->handled_irqs, chip->received_irqs); - for (i = 0; i < 64; i += 4) - snd_iprintf(buffer, "%c%02x: %08x", - (i % 16) ? ' ' : '\n', i, inl(chip->port + i)); - if ((cif = chip->cif)) { - snd_iprintf(buffer, - "\nVersion: ASIC: %d CODEC: %d AUXDSP: %d PROG: %d", - chip->firmware.firmware.ASIC, - chip->firmware.firmware.CODEC, - chip->firmware.firmware.AUXDSP, - chip->firmware.firmware.PROG); - snd_iprintf(buffer, "\nDigital mixer:"); - for (i = 0; i < 12; i++) { - getmixer(cif, i, &rval, &lval); - snd_iprintf(buffer, "\n %d: %d %d", i, rval, lval); - } - snd_iprintf(buffer, - "\nARM Commands num: %d failed: %d time: %d max: %d min: %d", - cif->cmdcnt, cif->errcnt, - cif->cmdtime, cif->cmdtimemax, cif->cmdtimemin); - } - snd_iprintf(buffer, "\nOpen streams %d:\n", chip->openstreams); - for (i = 0; i < PLAYBACK_SUBSTREAMS; i++) { - if (chip->playback_substream[i] - && chip->playback_substream[i]->runtime - && (data = - chip->playback_substream[i]->runtime->private_data)) { - snd_iprintf(buffer, - "stream: %d mixer: %d source: %d (%d,%d)\n", - data->id, data->mixer, data->source, - data->intdec[0], data->intdec[1]); - if (!(getsamplerate(cif, data->intdec, &rate))) - snd_iprintf(buffer, "rate: %d\n", rate); - } - } - if (chip->capture_substream - && chip->capture_substream->runtime - && (data = chip->capture_substream->runtime->private_data)) { - snd_iprintf(buffer, - "stream: %d mixer: %d source: %d (%d,%d)\n", - data->id, data->mixer, - data->source, data->intdec[0], data->intdec[1]); - if (!(getsamplerate(cif, data->intdec, &rate))) - snd_iprintf(buffer, "rate: %d\n", rate); - } - snd_iprintf(buffer, "Paths:\n"); - i = getpaths(cif, p); - while (i--) { - snd_iprintf(buffer, "%x->%x ", p[i - 1], p[i]); - i--; - } - snd_iprintf(buffer, "\n"); -} - -static void __devinit snd_riptide_proc_init(struct snd_riptide *chip) -{ - struct snd_info_entry *entry; - - if (!snd_card_proc_new(chip->card, "riptide", &entry)) - snd_info_set_text_ops(entry, chip, 4096, snd_riptide_proc_read); -} - -static int __devinit snd_riptide_mixer(struct snd_riptide *chip) -{ - struct snd_ac97_bus *pbus; - struct snd_ac97_template ac97; - int err = 0; - static struct snd_ac97_bus_ops ops = { - .write = snd_riptide_codec_write, - .read = snd_riptide_codec_read, - }; - - memset(&ac97, 0, sizeof(ac97)); - ac97.private_data = chip; - ac97.scaps = AC97_SCAP_SKIP_MODEM; - - if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0) - return err; - - chip->ac97_bus = pbus; - ac97.pci = chip->pci; - if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0) - return err; - return err; -} - -#ifdef SUPPORT_JOYSTICK -static int have_joystick; -static struct pci_dev *riptide_gameport_pci; -static struct gameport *riptide_gameport; - -static int __devinit -snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id) -{ - static int dev; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - if (joystick_port[dev]) { - riptide_gameport = gameport_allocate_port(); - if (riptide_gameport) { - if (!request_region - (joystick_port[dev], 8, "Riptide gameport")) { - snd_printk(KERN_WARNING - "Riptide: cannot grab gameport 0x%x\n", - joystick_port[dev]); - gameport_free_port(riptide_gameport); - riptide_gameport = NULL; - } else { - riptide_gameport_pci = pci; - riptide_gameport->io = joystick_port[dev]; - gameport_register_port(riptide_gameport); - } - } - } - dev++; - return 0; -} - -static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci) -{ - if (riptide_gameport) { - if (riptide_gameport_pci == pci) { - release_region(riptide_gameport->io, 8); - riptide_gameport_pci = NULL; - gameport_unregister_port(riptide_gameport); - riptide_gameport = NULL; - } - } -} -#endif - -static int __devinit -snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) -{ - static int dev; - struct snd_card *card; - struct snd_riptide *chip; - unsigned short addr; - int err = 0; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; - if ((err = snd_riptide_create(card, pci, &chip)) < 0) { - snd_card_free(card); - return err; - } - card->private_data = chip; - if ((err = snd_riptide_pcm(chip, 0, NULL)) < 0) { - snd_card_free(card); - return err; - } - if ((err = snd_riptide_mixer(chip)) < 0) { - snd_card_free(card); - return err; - } - pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, LEGACY_ENABLE_ALL - | (opl3_port[dev] ? LEGACY_ENABLE_FM : 0) -#ifdef SUPPORT_JOYSTICK - | (joystick_port[dev] ? LEGACY_ENABLE_GAMEPORT : - 0) -#endif - | (mpu_port[dev] - ? (LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU) : - 0) - | ((chip->irq << 4) & 0xF0)); - if ((addr = mpu_port[dev]) != 0) { - pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, addr); - if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE, - addr, 0, chip->irq, 0, - &chip->rmidi)) < 0) - snd_printk(KERN_WARNING - "Riptide: Can't Allocate MPU at 0x%x\n", - addr); - else - chip->mpuaddr = addr; - } - if ((addr = opl3_port[dev]) != 0) { - pci_write_config_word(chip->pci, PCI_EXT_FM_Base, addr); - if ((err = snd_opl3_create(card, addr, addr + 2, - OPL3_HW_RIPTIDE, 0, - &chip->opl3)) < 0) - snd_printk(KERN_WARNING - "Riptide: Can't Allocate OPL3 at 0x%x\n", - addr); - else { - chip->opladdr = addr; - if ((err = - snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL)) < 0) - snd_printk(KERN_WARNING - "Riptide: Can't Allocate OPL3-HWDEP\n"); - } - } -#ifdef SUPPORT_JOYSTICK - if ((addr = joystick_port[dev]) != 0) { - pci_write_config_word(chip->pci, PCI_EXT_Game_Base, addr); - chip->gameaddr = addr; - } -#endif - - strcpy(card->driver, "RIPTIDE"); - strcpy(card->shortname, "Riptide"); -#ifdef SUPPORT_JOYSTICK - snprintf(card->longname, sizeof(card->longname), - "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x gameport 0x%x", - card->shortname, chip->port, chip->irq, chip->mpuaddr, - chip->opladdr, chip->gameaddr); -#else - snprintf(card->longname, sizeof(card->longname), - "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x", - card->shortname, chip->port, chip->irq, chip->mpuaddr, - chip->opladdr); -#endif - snd_riptide_proc_init(chip); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } - pci_set_drvdata(pci, card); - dev++; - return 0; -} - -static void __devexit snd_card_riptide_remove(struct pci_dev *pci) -{ - snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); -} - -static struct pci_driver driver = { - .name = "RIPTIDE", - .id_table = snd_riptide_ids, - .probe = snd_card_riptide_probe, - .remove = __devexit_p(snd_card_riptide_remove), -#ifdef CONFIG_PM - .suspend = riptide_suspend, - .resume = riptide_resume, -#endif -}; - -#ifdef SUPPORT_JOYSTICK -static struct pci_driver joystick_driver = { - .name = "Riptide Joystick", - .id_table = snd_riptide_joystick_ids, - .probe = snd_riptide_joystick_probe, - .remove = __devexit_p(snd_riptide_joystick_remove), -}; -#endif - -static int __init alsa_card_riptide_init(void) -{ - int err; - if ((err = pci_register_driver(&driver)) < 0) - return err; -#if defined(SUPPORT_JOYSTICK) - if (pci_register_driver(&joystick_driver) < 0) { - have_joystick = 0; - snd_printk(KERN_INFO "no joystick found\n"); - } else - have_joystick = 1; -#endif - return 0; -} - -static void __exit alsa_card_riptide_exit(void) -{ - pci_unregister_driver(&driver); -#if defined(SUPPORT_JOYSTICK) - if (have_joystick) - pci_unregister_driver(&joystick_driver); -#endif -} - -module_init(alsa_card_riptide_init); -module_exit(alsa_card_riptide_exit); diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 55b1d4838..0cbef5fe6 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -227,7 +227,7 @@ struct rme32 { struct snd_kcontrol *spdif_ctl; }; -static struct pci_device_id snd_rme32_ids[] __devinitdata = { +static struct pci_device_id snd_rme32_ids[] = { {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8, @@ -313,7 +313,7 @@ static int snd_rme32_capture_copy(struct snd_pcm_substream *substream, int chann } /* - * SPDIF I/O capabilities (half-duplex mode) + * SPDIF I/O capabilites (half-duplex mode) */ static struct snd_pcm_hardware snd_rme32_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | @@ -339,7 +339,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_info = { }; /* - * ADAT I/O capabilities (half-duplex mode) + * ADAT I/O capabilites (half-duplex mode) */ static struct snd_pcm_hardware snd_rme32_adat_info = { @@ -364,7 +364,7 @@ static struct snd_pcm_hardware snd_rme32_adat_info = }; /* - * SPDIF I/O capabilities (full-duplex mode) + * SPDIF I/O capabilites (full-duplex mode) */ static struct snd_pcm_hardware snd_rme32_spdif_fd_info = { .info = (SNDRV_PCM_INFO_MMAP | @@ -390,7 +390,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_fd_info = { }; /* - * ADAT I/O capabilities (full-duplex mode) + * ADAT I/O capabilites (full-duplex mode) */ static struct snd_pcm_hardware snd_rme32_adat_fd_info = { diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 3c1bc533d..0e694b011 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -232,7 +232,7 @@ struct rme96 { struct snd_kcontrol *spdif_ctl; }; -static struct pci_device_id snd_rme96_ids[] __devinitdata = { +static struct pci_device_id snd_rme96_ids[] = { { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8, @@ -359,7 +359,7 @@ snd_rme96_capture_copy(struct snd_pcm_substream *substream, } /* - * Digital output capabilities (S/PDIF) + * Digital output capabilites (S/PDIF) */ static struct snd_pcm_hardware snd_rme96_playback_spdif_info = { @@ -388,7 +388,7 @@ static struct snd_pcm_hardware snd_rme96_playback_spdif_info = }; /* - * Digital input capabilities (S/PDIF) + * Digital input capabilites (S/PDIF) */ static struct snd_pcm_hardware snd_rme96_capture_spdif_info = { @@ -417,7 +417,7 @@ static struct snd_pcm_hardware snd_rme96_capture_spdif_info = }; /* - * Digital output capabilities (ADAT) + * Digital output capabilites (ADAT) */ static struct snd_pcm_hardware snd_rme96_playback_adat_info = { @@ -442,7 +442,7 @@ static struct snd_pcm_hardware snd_rme96_playback_adat_info = }; /* - * Digital input capabilities (ADAT) + * Digital input capabilites (ADAT) */ static struct snd_pcm_hardware snd_rme96_capture_adat_info = { diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 10586e48a..05a2320d9 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -389,7 +389,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," /* use hotplug firmeare loader? */ #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) -#if !defined(HDSP_USE_HWDEP_LOADER) && !defined(CONFIG_SND_HDSP) +#ifndef HDSP_USE_HWDEP_LOADER #define HDSP_FW_LOADER #endif #endif @@ -568,7 +568,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d } -static struct pci_device_id snd_hdsp_ids[] __devinitdata = { +static struct pci_device_id snd_hdsp_ids[] = { { .vendor = PCI_VENDOR_ID_XILINX, .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP, diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 722b9e6ce..980b9cd68 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -426,7 +426,7 @@ static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = { }; -static struct pci_device_id snd_hdspm_ids[] __devinitdata = { +static struct pci_device_id snd_hdspm_ids[] = { { .vendor = PCI_VENDOR_ID_XILINX, .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI, @@ -2256,7 +2256,7 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm } /* Channel playback mixer as default control - Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer + Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats to big for any alsamixer they are accesible via special IOCTL on hwdep and the mixer 2dimensional mixer control */ diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 75d640630..a687eb632 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -315,7 +315,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d } -static struct pci_device_id snd_rme9652_ids[] __devinitdata = { +static struct pci_device_id snd_rme9652_ids[] = { { .vendor = 0x10ee, .device = 0x3fc4, diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 91f8bf3ae..7bbea3738 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -243,7 +242,7 @@ struct sonicvibes { #endif }; -static struct pci_device_id snd_sonic_ids[] __devinitdata = { +static struct pci_device_id snd_sonic_ids[] = { { 0x5333, 0xca00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, { 0, } }; @@ -1228,8 +1227,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, 0x00ffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x00ffffff) < 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.c b/sound/pci/trident/trident.c index 9624a5f2b..b45380450 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -63,7 +63,7 @@ MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM."); module_param_array(wavetable_size, int, NULL, 0444); MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth."); -static struct pci_device_id snd_trident_ids[] __devinitdata = { +static struct pci_device_id snd_trident_ids[] = { {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX), PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX), diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 52178b8ad..83b7d8aba 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -3555,8 +3554,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, 0x3fffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) { snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c index 46c6982c9..cf09ea997 100644 --- a/sound/pci/trident/trident_memory.c +++ b/sound/pci/trident/trident_memory.c @@ -27,8 +27,6 @@ #include #include #include -#include - #include #include @@ -203,16 +201,16 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); blk = search_empty(hdr, runtime->dma_bytes); if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) { snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk)); __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } @@ -223,12 +221,12 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, unsigned long ptr = (unsigned long)sgbuf->table[idx].buf; if (! is_valid_page(addr)) { __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } set_tlb_bus(trident, page, ptr, addr); } - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return blk; } @@ -250,10 +248,10 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident, hdr = trident->tlb.memhdr; snd_assert(hdr != NULL, return NULL); - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); blk = search_empty(hdr, runtime->dma_bytes); if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } @@ -264,12 +262,12 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident, ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) { if (! is_valid_page(addr)) { __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } set_tlb_bus(trident, page, ptr, addr); } - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return blk; } @@ -302,13 +300,13 @@ int snd_trident_free_pages(struct snd_trident *trident, snd_assert(blk != NULL, return -EINVAL); hdr = trident->tlb.memhdr; - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); /* reset TLB entries */ for (page = firstpg(blk); page <= lastpg(blk); page++) set_silent_tlb(trident, page); /* free memory block */ __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return 0; } @@ -334,18 +332,18 @@ snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size) struct snd_util_memblk *blk; struct snd_util_memhdr *hdr = hw->tlb.memhdr; - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); blk = __snd_util_mem_alloc(hdr, size); if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } if (synth_alloc_pages(hw, blk)) { __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return NULL; } - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return blk; } @@ -358,10 +356,10 @@ snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk) { struct snd_util_memhdr *hdr = hw->tlb.memhdr; - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); synth_free_pages(hw, blk); __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return 0; } diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 39daf62d2..423741371 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -123,7 +123,6 @@ module_param(enable, bool, 0444); #define VIA_REV_8233A 0x40 /* 1 rec, 1 multi-pb, spdf */ #define VIA_REV_8235 0x50 /* 2 rec, 4 pb, 1 multi-pb, spdif */ #define VIA_REV_8237 0x60 -#define VIA_REV_8251 0x70 /* * Direct registers @@ -396,7 +395,7 @@ struct via82xx { #endif }; -static struct pci_device_id snd_via82xx_ids[] __devinitdata = { +static struct pci_device_id snd_via82xx_ids[] = { /* 0x1106, 0x3058 */ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */ /* 0x1106, 0x3059 */ @@ -863,11 +862,6 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *subst if (!status) status = inb(VIADEV_REG(viadev, OFFSET_STATUS)); - /* An apparent bug in the 8251 is worked around by sending a - * REG_CTRL_START. */ - if (chip->revision == VIA_REV_8251 && (status & VIA_REG_STAT_EOL)) - snd_via82xx_pcm_trigger(substream, SNDRV_PCM_TRIGGER_START); - if (!(status & VIA_REG_STAT_ACTIVE)) { res = 0; goto unlock; @@ -2319,7 +2313,6 @@ static struct via823x_info via823x_cards[] __devinitdata = { { VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A }, { VIA_REV_8235, "VIA 8235", TYPE_VIA8233 }, { VIA_REV_8237, "VIA 8237", TYPE_VIA8233 }, - { VIA_REV_8251, "VIA 8251", TYPE_VIA8233 }, }; /* @@ -2332,7 +2325,7 @@ struct dxs_whitelist { short action; /* new dxs_support value */ }; -static int __devinit check_dxs_list(struct pci_dev *pci, int revision) +static int __devinit check_dxs_list(struct pci_dev *pci) { static struct dxs_whitelist whitelist[] = { { .subvendor = 0x1005, .subdevice = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */ @@ -2340,7 +2333,6 @@ static int __devinit check_dxs_list(struct pci_dev *pci, int revision) { .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */ { .subvendor = 0x1019, .subdevice = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */ { .subvendor = 0x1019, .subdevice = 0xa101, .action = VIA_DXS_SRC }, - { .subvendor = 0x1019, .subdevice = 0xaa01, .action = VIA_DXS_SRC }, /* ECS K8T890-A */ { .subvendor = 0x1025, .subdevice = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */ { .subvendor = 0x1025, .subdevice = 0x0046, .action = VIA_DXS_SRC }, /* Acer Aspire 1524 WLMi */ { .subvendor = 0x1043, .subdevice = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ @@ -2349,7 +2341,6 @@ static int __devinit check_dxs_list(struct pci_dev *pci, int revision) { .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */ { .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */ { .subvendor = 0x1043, .subdevice = 0x8174, .action = VIA_DXS_SRC }, /* ASUS */ - { .subvendor = 0x1043, .subdevice = 0x81b9, .action = VIA_DXS_SRC }, /* ASUS A8V-MX */ { .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */ { .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */ { .subvendor = 0x10cf, .subdevice = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */ @@ -2382,13 +2373,10 @@ static int __devinit check_dxs_list(struct pci_dev *pci, int revision) { .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */ { .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */ { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ - { .subvendor = 0x1695, .subdevice = 0x300c, .action = VIA_DXS_SRC }, /* EPoX EP-8KRAI */ { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */ { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */ - { .subvendor = 0x1734, .subdevice = 0x1078, .action = VIA_DXS_SRC }, /* FSC Amilo L7300 */ { .subvendor = 0x1734, .subdevice = 0x1093, .action = VIA_DXS_SRC }, /* FSC */ { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ - { .subvendor = 0x1849, .subdevice = 0x9739, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ { .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ { .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC }, /* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */ @@ -2413,10 +2401,6 @@ static int __devinit check_dxs_list(struct pci_dev *pci, int revision) } } - /* for newer revision, default to DXS_SRC */ - if (revision >= VIA_REV_8235) - return VIA_DXS_SRC; - /* * not detected, try 48k rate only to be sure. */ @@ -2461,7 +2445,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci, } if (chip_type != TYPE_VIA8233A) { if (dxs_support == VIA_DXS_AUTO) - dxs_support = check_dxs_list(pci, revision); + dxs_support = check_dxs_list(pci); /* force to use VIA8233 or 8233A model according to * dxs_support module option */ diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index ef97e50cd..22ce4d309 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -261,7 +261,7 @@ struct via82xx_modem { struct snd_info_entry *proc_entry; }; -static struct pci_device_id snd_via82xx_modem_ids[] __devinitdata = { +static struct pci_device_id snd_via82xx_modem_ids[] = { { 0x1106, 0x3068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA82XX_MODEM, }, { 0, } }; diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c index 0f1ebb010..c816ddf1b 100644 --- a/sound/pci/vx222/vx222.c +++ b/sound/pci/vx222/vx222.c @@ -60,7 +60,7 @@ enum { VX_PCI_VX222_NEW }; -static struct pci_device_id snd_vx222_ids[] __devinitdata = { +static struct pci_device_id snd_vx222_ids[] = { { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */ { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */ { 0, } diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index 9b6d345b8..c705af409 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c @@ -24,8 +24,6 @@ #include #include #include -#include - #include #include #include @@ -863,10 +861,10 @@ static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem { struct vx_core *_chip = snd_kcontrol_chip(kcontrol); struct snd_vx222 *chip = (struct snd_vx222 *)_chip; - mutex_lock(&_chip->mixer_mutex); + down(&_chip->mixer_mutex); ucontrol->value.integer.value[0] = chip->input_level[0]; ucontrol->value.integer.value[1] = chip->input_level[1]; - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 0; } @@ -874,16 +872,16 @@ static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem { struct vx_core *_chip = snd_kcontrol_chip(kcontrol); struct snd_vx222 *chip = (struct snd_vx222 *)_chip; - mutex_lock(&_chip->mixer_mutex); + down(&_chip->mixer_mutex); if (chip->input_level[0] != ucontrol->value.integer.value[0] || chip->input_level[1] != ucontrol->value.integer.value[1]) { chip->input_level[0] = ucontrol->value.integer.value[0]; chip->input_level[1] = ucontrol->value.integer.value[1]; vx2_set_input_level(chip); - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 1; } - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 0; } @@ -909,14 +907,14 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v { struct vx_core *_chip = snd_kcontrol_chip(kcontrol); struct snd_vx222 *chip = (struct snd_vx222 *)_chip; - mutex_lock(&_chip->mixer_mutex); + down(&_chip->mixer_mutex); if (chip->mic_level != ucontrol->value.integer.value[0]) { chip->mic_level = ucontrol->value.integer.value[0]; vx2_set_input_level(chip); - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 1; } - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 0; } diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 65ebf5f19..dab9b8310 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -49,7 +49,6 @@ static long mpu_port[SNDRV_CARDS]; static long joystick_port[SNDRV_CARDS]; #endif static int rear_switch[SNDRV_CARDS]; -static int rear_swap[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 }; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard."); @@ -67,10 +66,8 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address"); #endif module_param_array(rear_switch, bool, NULL, 0444); MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); -module_param_array(rear_swap, bool, NULL, 0444); -MODULE_PARM_DESC(rear_swap, "Swap rear channels (must be enabled for correct IEC958 (S/PDIF)) output"); -static struct pci_device_id snd_ymfpci_ids[] __devinitdata = { +static struct pci_device_id snd_ymfpci_ids[] = { { 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */ { 0x1073, 0x000d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724F */ { 0x1073, 0x000a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF740 */ @@ -298,7 +295,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, snd_card_free(card); return err; } - if ((err = snd_ymfpci_mixer(chip, rear_switch[dev], rear_swap[dev])) < 0) { + if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) { snd_card_free(card); return err; } diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 8ac5ab50b..a1aa74b79 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -536,30 +536,15 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int } } if (ypcm->output_rear) { - if (!ypcm->swap_rear) { - if (use_left) { - bank->eff2_gain = - bank->eff2_gain_end = vol_left; - } - if (use_right) { - bank->eff3_gain = - bank->eff3_gain_end = vol_right; - } - } else { - /* The SPDIF out channels seem to be swapped, so we have - * to swap them here, too. The rear analog out channels - * will be wrong, but otherwise AC3 would not work. - */ - if (use_left) { - bank->eff3_gain = - bank->eff3_gain_end = vol_left; - } - if (use_right) { - bank->eff2_gain = - bank->eff2_gain_end = vol_right; - } - } - } + if (use_left) { + bank->eff2_gain = + bank->eff2_gain_end = vol_left; + } + if (use_right) { + bank->eff3_gain = + bank->eff3_gain_end = vol_right; + } + } } } @@ -909,7 +894,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream) ypcm = runtime->private_data; ypcm->output_front = 1; ypcm->output_rear = chip->mode_dup4ch ? 1 : 0; - ypcm->swap_rear = chip->rear_swap; spin_lock_irq(&chip->reg_lock); if (ypcm->output_rear) { ymfpci_open_extension(chip); @@ -1750,7 +1734,7 @@ static void snd_ymfpci_mixer_free_ac97(struct snd_ac97 *ac97) chip->ac97 = NULL; } -int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap) +int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) { struct snd_ac97_template ac97; struct snd_kcontrol *kctl; @@ -1762,7 +1746,6 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rea .read = snd_ymfpci_codec_read, }; - chip->rear_swap = rear_swap; if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0) return err; chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus; @@ -2310,7 +2293,6 @@ int __devinit snd_ymfpci_create(struct snd_card *card, return -EIO; } - chip->rear_swap = 1; if ((err = snd_ymfpci_ac3_init(chip)) < 0) { snd_ymfpci_free(chip); return err; diff --git a/sound/pcmcia/Kconfig b/sound/pcmcia/Kconfig index c9fa1a2bc..5d1b0b762 100644 --- a/sound/pcmcia/Kconfig +++ b/sound/pcmcia/Kconfig @@ -5,7 +5,7 @@ menu "PCMCIA devices" config SND_VXPOCKET tristate "Digigram VXpocket" - depends on SND && PCMCIA + depends on SND && PCMCIA && ISA select SND_VX_LIB help Say Y here to include support for Digigram VXpocket and @@ -16,7 +16,7 @@ config SND_VXPOCKET config SND_PDAUDIOCF tristate "Sound Core PDAudioCF" - depends on SND && PCMCIA + depends on SND && PCMCIA && ISA select SND_PCM help Say Y here to include support for Sound Core PDAudioCF diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index adfdce749..77caf43a3 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -57,12 +57,18 @@ static struct snd_card *card_list[SNDRV_CARDS]; /* * prototypes */ -static int pdacf_config(struct pcmcia_device *link); +static void pdacf_config(dev_link_t *link); static void snd_pdacf_detach(struct pcmcia_device *p_dev); -static void pdacf_release(struct pcmcia_device *link) +static void pdacf_release(dev_link_t *link) { - pcmcia_disable_device(link); + if (link->state & DEV_CONFIG) { + /* release cs resources */ + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; + } } /* @@ -70,7 +76,7 @@ static void pdacf_release(struct pcmcia_device *link) */ static int snd_pdacf_free(struct snd_pdacf *pdacf) { - struct pcmcia_device *link = pdacf->p_dev; + dev_link_t *link = &pdacf->link; pdacf_release(link); @@ -90,9 +96,10 @@ static int snd_pdacf_dev_free(struct snd_device *device) /* * snd_pdacf_attach - attach callback for cs */ -static int snd_pdacf_probe(struct pcmcia_device *link) +static int snd_pdacf_attach(struct pcmcia_device *p_dev) { int i; + dev_link_t *link; /* Info for cardmgr */ struct snd_pdacf *pdacf; struct snd_card *card; static struct snd_device_ops ops = { @@ -132,7 +139,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link) pdacf->index = i; card_list[i] = card; - pdacf->p_dev = link; + link = &pdacf->link; link->priv = pdacf; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -149,7 +156,13 @@ static int snd_pdacf_probe(struct pcmcia_device *link) link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; - return pdacf_config(link); + /* Chain drivers */ + link->next = NULL; + + link->handle = p_dev; + pdacf_config(link); + + return 0; } @@ -196,8 +209,9 @@ static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq /* * snd_pdacf_detach - detach callback for cs */ -static void snd_pdacf_detach(struct pcmcia_device *link) +static void snd_pdacf_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct snd_pdacf *chip = link->priv; snd_printdd(KERN_DEBUG "pdacf_detach called\n"); @@ -216,11 +230,13 @@ static void snd_pdacf_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int pdacf_config(struct pcmcia_device *link) +static void pdacf_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct snd_pdacf *pdacf = link->priv; tuple_t tuple; cisparse_t *parse = NULL; + config_info_t conf; u_short buf[32]; int last_fn, last_ret; @@ -228,7 +244,7 @@ static int pdacf_config(struct pcmcia_device *link) parse = kmalloc(sizeof(*parse), GFP_KERNEL); if (! parse) { snd_printk(KERN_ERR "pdacf_config: cannot allocate\n"); - return -ENOMEM; + return; } tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; @@ -236,51 +252,71 @@ static int pdacf_config(struct pcmcia_device *link) tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); link->conf.ConfigBase = parse->config.base; link->conf.ConfigIndex = 0x5; kfree(parse); - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; + + /* Configure card */ + link->state |= DEV_CONFIG; + + CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) goto failed; - link->dev_node = &pdacf->node; - return 0; + link->dev = &pdacf->node; + link->state &= ~DEV_CONFIG_PENDING; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: - pcmcia_disable_device(link); - return -ENODEV; + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); } #ifdef CONFIG_PM -static int pdacf_suspend(struct pcmcia_device *link) +static int pdacf_suspend(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); struct snd_pdacf *chip = link->priv; snd_printdd(KERN_DEBUG "SUSPEND\n"); + link->state |= DEV_SUSPEND; if (chip) { snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); snd_pdacf_suspend(chip, PMSG_SUSPEND); } + snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + return 0; } -static int pdacf_resume(struct pcmcia_device *link) +static int pdacf_resume(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); struct snd_pdacf *chip = link->priv; snd_printdd(KERN_DEBUG "RESUME\n"); - if (pcmcia_dev_present(link)) { + link->state &= ~DEV_SUSPEND; + + snd_printdd(KERN_DEBUG "CARD_RESET\n"); + if (DEV_OK(link)) { + snd_printdd(KERN_DEBUG "requestconfig...\n"); + pcmcia_request_configuration(link->handle, &link->conf); if (chip) { snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n"); snd_pdacf_resume(chip); @@ -307,7 +343,7 @@ static struct pcmcia_driver pdacf_cs_driver = { .drv = { .name = "snd-pdaudiocf", }, - .probe = snd_pdacf_probe, + .probe = snd_pdacf_attach, .remove = snd_pdacf_detach, .id_table = snd_pdacf_ids, #ifdef CONFIG_PM diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h index 9a14a4f64..2744f189a 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.h +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h @@ -116,7 +116,7 @@ struct snd_pdacf { void *pcm_area; /* pcmcia stuff */ - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; }; diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index 7f2a4de1d..962e6d525 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c @@ -66,9 +66,10 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) { struct snd_pcm_runtime *runtime = subs->runtime; - - vfree(runtime->dma_area); - runtime->dma_area = NULL; + if (runtime->dma_area) { + vfree(runtime->dma_area); + runtime->dma_area = NULL; + } return 0; } diff --git a/sound/pcmcia/vx/vxp_mixer.c b/sound/pcmcia/vx/vxp_mixer.c index e237f6c20..9450149b9 100644 --- a/sound/pcmcia/vx/vxp_mixer.c +++ b/sound/pcmcia/vx/vxp_mixer.c @@ -52,14 +52,14 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v { struct vx_core *_chip = snd_kcontrol_chip(kcontrol); struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; - mutex_lock(&_chip->mixer_mutex); + down(&_chip->mixer_mutex); if (chip->mic_level != ucontrol->value.integer.value[0]) { vx_set_mic_level(_chip, ucontrol->value.integer.value[0]); chip->mic_level = ucontrol->value.integer.value[0]; - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 1; } - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 0; } @@ -95,14 +95,14 @@ static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v { struct vx_core *_chip = snd_kcontrol_chip(kcontrol); struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; - mutex_lock(&_chip->mixer_mutex); + down(&_chip->mixer_mutex); if (chip->mic_level != ucontrol->value.integer.value[0]) { vx_set_mic_boost(_chip, ucontrol->value.integer.value[0]); chip->mic_level = ucontrol->value.integer.value[0]; - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 1; } - mutex_unlock(&_chip->mixer_mutex); + up(&_chip->mixer_mutex); return 0; } diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 7e0cda2b6..66900d20a 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -59,9 +59,15 @@ static unsigned int card_alloc; /* */ -static void vxpocket_release(struct pcmcia_device *link) +static void vxpocket_release(dev_link_t *link) { - pcmcia_disable_device(link); + if (link->state & DEV_CONFIG) { + /* release cs resources */ + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; + } } /* @@ -126,9 +132,9 @@ static struct snd_vx_hardware vxp440_hw = { /* * create vxpocket instance */ -static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl, - struct pcmcia_device *link) +static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) { + dev_link_t *link; /* Info for cardmgr */ struct vx_core *chip; struct snd_vxpocket *vxp; static struct snd_device_ops ops = { @@ -148,7 +154,7 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl, vxp = (struct snd_vxpocket *)chip; - vxp->p_dev = link; + link = &vxp->link; link->priv = chip; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -161,6 +167,7 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl, link->irq.Instance = chip; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; @@ -208,8 +215,9 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int vxpocket_config(struct pcmcia_device *link) +static void vxpocket_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct vx_core *chip = link->priv; struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; tuple_t tuple; @@ -221,24 +229,24 @@ static int vxpocket_config(struct pcmcia_device *link) parse = kmalloc(sizeof(*parse), GFP_KERNEL); if (! parse) { snd_printk(KERN_ERR "vx: cannot allocate\n"); - return -ENOMEM; + return; } tuple.Attributes = 0; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; /* redefine hardware record according to the VERSION1 string */ tuple.DesiredTuple = CISTPL_VERS_1; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); if (! strcmp(parse->version_1.str + parse->version_1.ofs[1], "VX-POCKET")) { snd_printdd("VX-pocket is detected\n"); } else { @@ -249,50 +257,67 @@ static int vxpocket_config(struct pcmcia_device *link) strcpy(chip->card->driver, vxp440_hw.name); } - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + /* Configure card */ + link->state |= DEV_CONFIG; + + CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); - chip->dev = &handle_to_dev(link); + chip->dev = &handle_to_dev(link->handle); snd_card_set_dev(chip->card, chip->dev); if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) goto failed; - link->dev_node = &vxp->node; + link->dev = &vxp->node; + link->state &= ~DEV_CONFIG_PENDING; kfree(parse); - return 9; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); failed: - pcmcia_disable_device(link); + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; kfree(parse); - return -ENODEV; } #ifdef CONFIG_PM -static int vxp_suspend(struct pcmcia_device *link) +static int vxp_suspend(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); struct vx_core *chip = link->priv; snd_printdd(KERN_DEBUG "SUSPEND\n"); + link->state |= DEV_SUSPEND; if (chip) { snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); snd_vx_suspend(chip, PMSG_SUSPEND); } + snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); return 0; } -static int vxp_resume(struct pcmcia_device *link) +static int vxp_resume(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); struct vx_core *chip = link->priv; snd_printdd(KERN_DEBUG "RESUME\n"); - if (pcmcia_dev_present(link)) { + link->state &= ~DEV_SUSPEND; + + snd_printdd(KERN_DEBUG "CARD_RESET\n"); + if (DEV_OK(link)) { //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; + snd_printdd(KERN_DEBUG "requestconfig...\n"); + pcmcia_request_configuration(link->handle, &link->conf); if (chip) { snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); snd_vx_resume(chip); @@ -308,7 +333,7 @@ static int vxp_resume(struct pcmcia_device *link) /* */ -static int vxpocket_probe(struct pcmcia_device *p_dev) +static int vxpocket_attach(struct pcmcia_device *p_dev) { struct snd_card *card; struct snd_vxpocket *vxp; @@ -333,7 +358,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) return -ENOMEM; } - vxp = snd_vxpocket_new(card, ibl[i], p_dev); + vxp = snd_vxpocket_new(card, ibl[i]); if (! vxp) { snd_card_free(card); return -ENODEV; @@ -343,13 +368,20 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) vxp->index = i; card_alloc |= 1 << i; - vxp->p_dev = p_dev; + /* Chain drivers */ + vxp->link.next = NULL; + + vxp->link.handle = p_dev; + vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING; + p_dev->instance = &vxp->link; + vxpocket_config(&vxp->link); - return vxpocket_config(p_dev); + return 0; } -static void vxpocket_detach(struct pcmcia_device *link) +static void vxpocket_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct snd_vxpocket *vxp; struct vx_core *chip; @@ -381,7 +413,7 @@ static struct pcmcia_driver vxp_cs_driver = { .drv = { .name = "snd-vxpocket", }, - .probe = vxpocket_probe, + .probe = vxpocket_attach, .remove = vxpocket_detach, .id_table = vxp_ids, #ifdef CONFIG_PM diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h index 27ea00229..67efae3f6 100644 --- a/sound/pcmcia/vx/vxpocket.h +++ b/sound/pcmcia/vx/vxpocket.h @@ -42,7 +42,7 @@ struct snd_vxpocket { int index; /* card index */ /* pcmcia stuff */ - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; }; diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c index 46eebf561..b96cd947d 100644 --- a/sound/ppc/daca.c +++ b/sound/ppc/daca.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c index fb05938dc..6058c2dd1 100644 --- a/sound/ppc/keywest.c +++ b/sound/ppc/keywest.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "pmac.h" diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index f0794ef9d..aa5717010 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -869,7 +869,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip) u32 layout_id = 0; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return -ENODEV; chip->subframe = 0; diff --git a/sound/ppc/toonie.c b/sound/ppc/toonie.c index 1ac7c8552..053b8f24e 100644 --- a/sound/ppc/toonie.c +++ b/sound/ppc/toonie.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -117,7 +118,7 @@ static int toonie_get_mute_switch(struct snd_kcontrol *kcontrol, gp = &mix->amp_mute_gpio; break; default: - return -EINVAL; + return -EINVAL;; } ucontrol->value.integer.value[0] = !check_audio_gpio(gp); return 0; @@ -145,7 +146,7 @@ static int toonie_put_mute_switch(struct snd_kcontrol *kcontrol, gp = &mix->amp_mute_gpio; break; default: - return -EINVAL; + return -EINVAL;; } val = ! check_audio_gpio(gp); if (val != ucontrol->value.integer.value[0]) { @@ -335,7 +336,7 @@ static void toonie_cleanup(struct snd_pmac *chip) chip->mixer_data = NULL; } -int __init snd_pmac_toonie_init(struct snd_pmac *chip) +int snd_pmac_toonie_init(struct snd_pmac *chip) { struct pmac_toonie *mix; diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 70e4ebc70..39d4cde78 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/sound_core.c b/sound/sound_core.c index 6f849720a..394b53e20 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -53,7 +53,7 @@ struct sound_unit { int unit_minor; - const struct file_operations *unit_fops; + struct file_operations *unit_fops; struct sound_unit *next; char name[32]; }; @@ -73,7 +73,7 @@ EXPORT_SYMBOL(sound_class); * join into it. Called with the lock asserted */ -static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, const struct file_operations *fops, int index, int low, int top) +static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, struct file_operations *fops, int index, int low, int top) { int n=low; @@ -153,7 +153,7 @@ static DEFINE_SPINLOCK(sound_loader_lock); * list. Acquires locks as needed */ -static int sound_insert_unit(struct sound_unit **list, const struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev) +static int sound_insert_unit(struct sound_unit **list, struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev) { struct sound_unit *s = kmalloc(sizeof(*s), GFP_KERNEL); int r; @@ -237,7 +237,7 @@ static struct sound_unit *chains[SOUND_STEP]; * a negative error code is returned. */ -int register_sound_special_device(const struct file_operations *fops, int unit, +int register_sound_special_device(struct file_operations *fops, int unit, struct device *dev) { const int chain = unit % SOUND_STEP; @@ -301,7 +301,7 @@ int register_sound_special_device(const struct file_operations *fops, int unit, EXPORT_SYMBOL(register_sound_special_device); -int register_sound_special(const struct file_operations *fops, int unit) +int register_sound_special(struct file_operations *fops, int unit) { return register_sound_special_device(fops, unit, NULL); } @@ -318,7 +318,7 @@ EXPORT_SYMBOL(register_sound_special); * number is returned, on failure a negative error code is returned. */ -int register_sound_mixer(const struct file_operations *fops, int dev) +int register_sound_mixer(struct file_operations *fops, int dev) { return sound_insert_unit(&chains[0], fops, dev, 0, 128, "mixer", S_IRUSR | S_IWUSR, NULL); @@ -336,7 +336,7 @@ EXPORT_SYMBOL(register_sound_mixer); * number is returned, on failure a negative error code is returned. */ -int register_sound_midi(const struct file_operations *fops, int dev) +int register_sound_midi(struct file_operations *fops, int dev) { return sound_insert_unit(&chains[2], fops, dev, 2, 130, "midi", S_IRUSR | S_IWUSR, NULL); @@ -362,7 +362,7 @@ EXPORT_SYMBOL(register_sound_midi); * and will always allocate them as a matching pair - eg dsp3/audio3 */ -int register_sound_dsp(const struct file_operations *fops, int dev) +int register_sound_dsp(struct file_operations *fops, int dev) { return sound_insert_unit(&chains[3], fops, dev, 3, 131, "dsp", S_IWUSR | S_IRUSR, NULL); @@ -381,7 +381,7 @@ EXPORT_SYMBOL(register_sound_dsp); */ -int register_sound_synth(const struct file_operations *fops, int dev) +int register_sound_synth(struct file_operations *fops, int dev) { return sound_insert_unit(&chains[9], fops, dev, 9, 137, "synth", S_IRUSR | S_IWUSR, NULL); @@ -501,7 +501,7 @@ int soundcore_open(struct inode *inode, struct file *file) int chain; int unit = iminor(inode); struct sound_unit *s; - const struct file_operations *new_fops = NULL; + struct file_operations *new_fops = NULL; chain=unit&0x0F; if(chain==4 || chain==5) /* dsp/audio/dsp16 */ @@ -540,7 +540,7 @@ int soundcore_open(struct inode *inode, struct file *file) * switching ->f_op in the first place. */ int err = 0; - const struct file_operations *old_fops = file->f_op; + struct file_operations *old_fops = file->f_op; file->f_op = new_fops; spin_unlock(&sound_loader_lock); if(file->f_op->open) diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 8804f26dd..e581a0235 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -115,8 +115,8 @@ struct snd_cs4231 { unsigned char image[32]; /* registers image */ int mce_bit; int calibrate_mute; - struct mutex mce_mutex; - struct mutex open_mutex; + struct semaphore mce_mutex; + struct semaphore open_mutex; union { #ifdef SBUS_SUPPORT @@ -611,7 +611,8 @@ static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, unsigned int period_size = snd_pcm_lib_period_bytes(substream); unsigned int offset = period_size * (*periods_sent); - BUG_ON(period_size >= (1 << 24)); + if (period_size >= (1 << 24)) + BUG(); if (dma_cont->request(dma_cont, runtime->dma_addr + offset, period_size)) return; @@ -774,7 +775,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_h { unsigned long flags; - mutex_lock(&chip->mce_mutex); + down(&chip->mce_mutex); snd_cs4231_calibrate_mute(chip, 1); snd_cs4231_mce_up(chip); @@ -789,7 +790,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_h snd_cs4231_mce_down(chip); snd_cs4231_calibrate_mute(chip, 0); - mutex_unlock(&chip->mce_mutex); + up(&chip->mce_mutex); } static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, @@ -797,7 +798,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw { unsigned long flags; - mutex_lock(&chip->mce_mutex); + down(&chip->mce_mutex); snd_cs4231_calibrate_mute(chip, 1); snd_cs4231_mce_up(chip); @@ -818,7 +819,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw snd_cs4231_mce_down(chip); snd_cs4231_calibrate_mute(chip, 0); - mutex_unlock(&chip->mce_mutex); + up(&chip->mce_mutex); } /* @@ -932,14 +933,14 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) { unsigned long flags; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); if ((chip->mode & mode)) { - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return -EAGAIN; } if (chip->mode & CS4231_MODE_OPEN) { chip->mode |= mode; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return 0; } /* ok. now enable and ack CODEC IRQ */ @@ -959,7 +960,7 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) spin_unlock_irqrestore(&chip->lock, flags); chip->mode = mode; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return 0; } @@ -967,10 +968,10 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) { unsigned long flags; - mutex_lock(&chip->open_mutex); + down(&chip->open_mutex); chip->mode &= ~mode; if (chip->mode & CS4231_MODE_OPEN) { - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); return; } snd_cs4231_calibrate_mute(chip, 1); @@ -1007,7 +1008,7 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) snd_cs4231_calibrate_mute(chip, 0); chip->mode = 0; - mutex_unlock(&chip->open_mutex); + up(&chip->open_mutex); } /* @@ -1078,7 +1079,8 @@ static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO); - BUG_ON(runtime->period_size > 0xffff + 1); + if (runtime->period_size > 0xffff + 1) + BUG(); chip->p_periods_sent = 0; spin_unlock_irqrestore(&chip->lock, flags); @@ -1269,7 +1271,7 @@ static struct snd_pcm_hardware snd_cs4231_playback = .channels_min = 1, .channels_max = 2, .buffer_bytes_max = (32*1024), - .period_bytes_min = 4096, + .period_bytes_min = 64, .period_bytes_max = (32*1024), .periods_min = 1, .periods_max = 1024, @@ -1289,7 +1291,7 @@ static struct snd_pcm_hardware snd_cs4231_capture = .channels_min = 1, .channels_max = 2, .buffer_bytes_max = (32*1024), - .period_bytes_min = 4096, + .period_bytes_min = 64, .period_bytes_max = (32*1024), .periods_min = 1, .periods_max = 1024, @@ -1797,7 +1799,7 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_re snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); spin_unlock_irqrestore(&chip->lock, flags); - return 0; + return IRQ_HANDLED; } /* @@ -1822,7 +1824,6 @@ static int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_ if (!(csr & test)) goto out; err = -EBUSY; - csr = sbus_readl(base->regs + APCCSR); test = APC_XINT_CNVA; if ( base->dir == APC_PLAY ) test = APC_XINT_PNVA; @@ -1863,17 +1864,16 @@ static void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on) spin_lock_irqsave(&base->lock, flags); if (!on) { - if (base->dir == APC_PLAY) { - sbus_writel(0, base->regs + base->dir + APCNVA); - sbus_writel(1, base->regs + base->dir + APCC); - } - else - { - sbus_writel(0, base->regs + base->dir + APCNC); - sbus_writel(0, base->regs + base->dir + APCVA); - } + sbus_writel(0, base->regs + base->dir + APCNC); + sbus_writel(0, base->regs + base->dir + APCNVA); + sbus_writel(0, base->regs + base->dir + APCC); + sbus_writel(0, base->regs + base->dir + APCVA); + + /* ACK any APC interrupts. */ + csr = sbus_readl(base->regs + APCCSR); + sbus_writel(csr, base->regs + APCCSR); } - udelay(600); + udelay(1000); csr = sbus_readl(base->regs + APCCSR); shift = 0; if ( base->dir == APC_PLAY ) @@ -1967,8 +1967,8 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, spin_lock_init(&chip->lock); spin_lock_init(&chip->c_dma.sbus_info.lock); spin_lock_init(&chip->p_dma.sbus_info.lock); - mutex_init(&chip->mce_mutex); - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->mce_mutex); + init_MUTEX(&chip->open_mutex); chip->card = card; chip->dev_u.sdev = sdev; chip->regs_size = sdev->reg_addrs[0].reg_size; @@ -2155,8 +2155,8 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, spin_lock_init(&chip->lock); spin_lock_init(&chip->c_dma.ebus_info.lock); spin_lock_init(&chip->p_dma.ebus_info.lock); - mutex_init(&chip->mce_mutex); - mutex_init(&chip->open_mutex); + init_MUTEX(&chip->mce_mutex); + init_MUTEX(&chip->open_mutex); chip->flags |= CS4231_FLAG_EBUS; chip->card = card; chip->dev_u.pdev = edev->bus->self; diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c index fc733bbf4..7c8e328fa 100644 --- a/sound/synth/emux/emux.c +++ b/sound/synth/emux/emux.c @@ -45,7 +45,7 @@ int snd_emux_new(struct snd_emux **remu) return -ENOMEM; spin_lock_init(&emu->voice_lock); - mutex_init(&emu->register_mutex); + init_MUTEX(&emu->register_mutex); emu->client = -1; #ifdef CONFIG_SND_SEQUENCER_OSS diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c index 343681672..dfbfcfbe5 100644 --- a/sound/synth/emux/emux_oss.c +++ b/sound/synth/emux/emux_oss.c @@ -117,10 +117,10 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) emu = closure; snd_assert(arg != NULL && emu != NULL, return -ENXIO); - mutex_lock(&emu->register_mutex); + down(&emu->register_mutex); if (!snd_emux_inc_count(emu)) { - mutex_unlock(&emu->register_mutex); + up(&emu->register_mutex); return -EFAULT; } @@ -134,7 +134,7 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) if (p == NULL) { snd_printk("can't create port\n"); snd_emux_dec_count(emu); - mutex_unlock(&emu->register_mutex); + up(&emu->register_mutex); return -ENOMEM; } @@ -148,7 +148,7 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) snd_emux_reset_port(p); - mutex_unlock(&emu->register_mutex); + up(&emu->register_mutex); return 0; } @@ -191,13 +191,13 @@ snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg) emu = p->emu; snd_assert(emu != NULL, return -ENXIO); - mutex_lock(&emu->register_mutex); + down(&emu->register_mutex); snd_emux_sounds_off_all(p); snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port)); snd_seq_event_port_detach(p->chset.client, p->chset.port); snd_emux_dec_count(emu); - mutex_unlock(&emu->register_mutex); + up(&emu->register_mutex); return 0; } diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c index 1ba68ce30..a70a179f6 100644 --- a/sound/synth/emux/emux_proc.c +++ b/sound/synth/emux/emux_proc.c @@ -37,7 +37,7 @@ snd_emux_proc_info_read(struct snd_info_entry *entry, int i; emu = entry->private_data; - mutex_lock(&emu->register_mutex); + down(&emu->register_mutex); if (emu->name) snd_iprintf(buf, "Device: %s\n", emu->name); snd_iprintf(buf, "Ports: %d\n", emu->num_ports); @@ -56,13 +56,13 @@ snd_emux_proc_info_read(struct snd_info_entry *entry, snd_iprintf(buf, "Memory Size: 0\n"); } if (emu->sflist) { - mutex_lock(&emu->sflist->presets_mutex); + down(&emu->sflist->presets_mutex); snd_iprintf(buf, "SoundFonts: %d\n", emu->sflist->fonts_size); snd_iprintf(buf, "Instruments: %d\n", emu->sflist->zone_counter); snd_iprintf(buf, "Samples: %d\n", emu->sflist->sample_counter); snd_iprintf(buf, "Locked Instruments: %d\n", emu->sflist->zone_locked); snd_iprintf(buf, "Locked Samples: %d\n", emu->sflist->sample_locked); - mutex_unlock(&emu->sflist->presets_mutex); + up(&emu->sflist->presets_mutex); } #if 0 /* debug */ if (emu->voices[0].state != SNDRV_EMUX_ST_OFF && emu->voices[0].ch >= 0) { @@ -103,7 +103,7 @@ snd_emux_proc_info_read(struct snd_info_entry *entry, snd_iprintf(buf, "sample_mode=%x, rate=%x\n", vp->reg.sample_mode, vp->reg.rate_offset); } #endif - mutex_unlock(&emu->register_mutex); + up(&emu->register_mutex); } diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c index 8f00f0770..1a973d7a9 100644 --- a/sound/synth/emux/emux_seq.c +++ b/sound/synth/emux/emux_seq.c @@ -123,12 +123,12 @@ snd_emux_detach_seq(struct snd_emux *emu) if (emu->voices) snd_emux_terminate_all(emu); - mutex_lock(&emu->register_mutex); + down(&emu->register_mutex); if (emu->client >= 0) { snd_seq_delete_kernel_client(emu->client); emu->client = -1; } - mutex_unlock(&emu->register_mutex); + up(&emu->register_mutex); } @@ -311,10 +311,10 @@ snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info) emu = p->emu; snd_assert(emu != NULL, return -EINVAL); - mutex_lock(&emu->register_mutex); + down(&emu->register_mutex); snd_emux_init_port(p); snd_emux_inc_count(emu); - mutex_unlock(&emu->register_mutex); + up(&emu->register_mutex); return 0; } @@ -332,10 +332,10 @@ snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info) emu = p->emu; snd_assert(emu != NULL, return -EINVAL); - mutex_lock(&emu->register_mutex); + down(&emu->register_mutex); snd_emux_sounds_off_all(p); snd_emux_dec_count(emu); - mutex_unlock(&emu->register_mutex); + up(&emu->register_mutex); return 0; } diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c index 32c27162d..4c5754d4a 100644 --- a/sound/synth/emux/soundfont.c +++ b/sound/synth/emux/soundfont.c @@ -79,7 +79,7 @@ static void lock_preset(struct snd_sf_list *sflist) { unsigned long flags; - mutex_lock(&sflist->presets_mutex); + down(&sflist->presets_mutex); spin_lock_irqsave(&sflist->lock, flags); sflist->presets_locked = 1; spin_unlock_irqrestore(&sflist->lock, flags); @@ -96,7 +96,7 @@ unlock_preset(struct snd_sf_list *sflist) spin_lock_irqsave(&sflist->lock, flags); sflist->presets_locked = 0; spin_unlock_irqrestore(&sflist->lock, flags); - mutex_unlock(&sflist->presets_mutex); + up(&sflist->presets_mutex); } @@ -1390,7 +1390,7 @@ snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr) if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL) return NULL; - mutex_init(&sflist->presets_mutex); + init_MUTEX(&sflist->presets_mutex); spin_lock_init(&sflist->lock); sflist->memhdr = hdr; diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c index 1d9b11f34..217e8e552 100644 --- a/sound/synth/util_mem.c +++ b/sound/synth/util_mem.c @@ -18,7 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include @@ -43,7 +42,7 @@ snd_util_memhdr_new(int memsize) if (hdr == NULL) return NULL; hdr->size = memsize; - mutex_init(&hdr->block_mutex); + init_MUTEX(&hdr->block_mutex); INIT_LIST_HEAD(&hdr->block); return hdr; @@ -137,9 +136,9 @@ struct snd_util_memblk * snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size) { struct snd_util_memblk *blk; - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); blk = __snd_util_mem_alloc(hdr, size); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return blk; } @@ -164,9 +163,9 @@ int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk) { snd_assert(hdr && blk, return -EINVAL); - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return 0; } @@ -176,9 +175,9 @@ int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk) int snd_util_mem_avail(struct snd_util_memhdr *hdr) { unsigned int size; - mutex_lock(&hdr->block_mutex); + down(&hdr->block_mutex); size = hdr->size - hdr->used; - mutex_unlock(&hdr->block_mutex); + up(&hdr->block_mutex); return size; } diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 4e614ac39..d5013383f 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include @@ -70,7 +69,6 @@ static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */ static int nrpacks = 4; /* max. number of packets per urb */ static int async_unlink = 1; -static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); @@ -86,8 +84,6 @@ module_param(nrpacks, int, 0644); MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); module_param(async_unlink, bool, 0444); MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); -module_param_array(device_setup, int, NULL, 0444); -MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); /* @@ -206,7 +202,7 @@ struct snd_usb_stream { * the all interfaces on the same card as one sound device. */ -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); static struct snd_usb_audio *usb_chip[SNDRV_CARDS]; @@ -479,18 +475,6 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, return 0; } -/* determine the number of frames in the next packet */ -static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) -{ - if (subs->fill_max) - return subs->maxframesize; - else { - subs->phase = (subs->phase & 0xffff) - + (subs->freqm << subs->datainterval); - return min(subs->phase >> 16, subs->maxframesize); - } -} - /* * Prepare urb for streaming before playback starts. * @@ -508,7 +492,16 @@ static int prepare_startup_playback_urb(struct snd_usb_substream *subs, urb->dev = ctx->subs->dev; urb->number_of_packets = subs->packs_per_ms; for (i = 0; i < subs->packs_per_ms; ++i) { - counts = snd_usb_audio_next_packet_size(subs); + /* calculate the size of a packet */ + if (subs->fill_max) + counts = subs->maxframesize; /* fixed */ + else { + subs->phase = (subs->phase & 0xffff) + + (subs->freqm << subs->datainterval); + counts = subs->phase >> 16; + if (counts > subs->maxframesize) + counts = subs->maxframesize; + } urb->iso_frame_desc[i].offset = offs * stride; urb->iso_frame_desc[i].length = counts * stride; offs += counts; @@ -545,7 +538,16 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, urb->number_of_packets = 0; spin_lock_irqsave(&subs->lock, flags); for (i = 0; i < ctx->packets; i++) { - counts = snd_usb_audio_next_packet_size(subs); + /* calculate the size of a packet */ + if (subs->fill_max) + counts = subs->maxframesize; /* fixed */ + else { + subs->phase = (subs->phase & 0xffff) + + (subs->freqm << subs->datainterval); + counts = subs->phase >> 16; + if (counts > subs->maxframesize) + counts = subs->maxframesize; + } /* set up descriptor */ urb->iso_frame_desc[i].offset = offs * stride; urb->iso_frame_desc[i].length = counts * stride; @@ -723,9 +725,10 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) { struct snd_pcm_runtime *runtime = subs->runtime; - - vfree(runtime->dma_area); - runtime->dma_area = NULL; + if (runtime->dma_area) { + vfree(runtime->dma_area); + runtime->dma_area = NULL; + } return 0; } @@ -776,35 +779,6 @@ static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sl } -static const char *usb_error_string(int err) -{ - switch (err) { - case -ENODEV: - return "no device"; - case -ENOENT: - return "endpoint not enabled"; - case -EPIPE: - return "endpoint stalled"; - case -ENOSPC: - return "not enough bandwidth"; - case -ESHUTDOWN: - return "device disabled"; - case -EHOSTUNREACH: - return "device suspended"; -#ifndef CONFIG_USB_EHCI_SPLIT_ISO - case -ENOSYS: - return "enable CONFIG_USB_EHCI_SPLIT_ISO to play through a hub"; -#endif - case -EINVAL: - case -EAGAIN: - case -EFBIG: - case -EMSGSIZE: - return "internal error"; - default: - return "unknown error"; - } -} - /* * set up and start data/sync urbs */ @@ -837,22 +811,16 @@ static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *ru subs->unlink_mask = 0; subs->running = 1; for (i = 0; i < subs->nurbs; i++) { - err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC); - if (err < 0) { - snd_printk(KERN_ERR "cannot submit datapipe " - "for urb %d, error %d: %s\n", - i, err, usb_error_string(err)); + if ((err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC)) < 0) { + snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); goto __error; } set_bit(i, &subs->active_mask); } if (subs->syncpipe) { for (i = 0; i < SYNC_URBS; i++) { - err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC); - if (err < 0) { - snd_printk(KERN_ERR "cannot submit syncpipe " - "for urb %d, error %d: %s\n", - i, err, usb_error_string(err)); + if ((err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC)) < 0) { + snd_printk(KERN_ERR "cannot submit syncpipe for urb %d, err = %d\n", i, err); goto __error; } set_bit(i + 16, &subs->active_mask); @@ -1422,8 +1390,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, channels = params_channels(hw_params); fmt = find_format(subs, format, rate, channels); if (! fmt) { - snd_printd(KERN_DEBUG "cannot set format: format = 0x%x, rate = %d, channels = %d\n", - format, rate, channels); + snd_printd(KERN_DEBUG "cannot set format: format = %s, rate = %d, channels = %d\n", + snd_pcm_format_name(format), rate, channels); return -EINVAL; } @@ -2049,8 +2017,6 @@ static struct usb_driver usb_audio_driver = { }; -#if defined(CONFIG_PROCFS) && defined(CONFIG_SND_VERBOSE_PROCFS) - /* * proc interface for list the supported pcm formats */ @@ -2066,7 +2032,7 @@ 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: 0x%x\n", fp->format); + snd_iprintf(buffer, " Format: %s\n", snd_pcm_format_name(fp->format)); snd_iprintf(buffer, " Channels: %d\n", fp->channels); snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", fp->endpoint & USB_ENDPOINT_NUMBER_MASK, @@ -2141,13 +2107,6 @@ static void proc_pcm_format_add(struct snd_usb_stream *stream) snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); } -#else - -static inline void proc_pcm_format_add(struct snd_usb_stream *stream) -{ -} - -#endif /* * initialize the substream instance. @@ -2550,8 +2509,6 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp 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) { struct usb_device *dev; @@ -2586,12 +2543,6 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; altno = altsd->bAlternateSetting; - - /* audiophile usb: skip altsets incompatible with device_setup - */ - if (chip->usb_id == USB_ID(0x0763, 0x2003) && - audiophile_skip_setting_quirk(chip, iface_no, altno)) - continue; /* get audio formats */ fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); @@ -2686,7 +2637,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) continue; } - snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, altno, fp->endpoint); + snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, i, fp->endpoint); err = add_audio_endpoint(chip, stream, fp); if (err < 0) { kfree(fp->rate_table); @@ -3094,45 +3045,6 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) return 0; } -/* - * Setup quirks - */ -#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ -#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */ -#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */ -#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */ -#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */ -#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */ -#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */ -#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */ -#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */ -#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */ - -static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, - int iface, int altno) -{ - if (device_setup[chip->index] & AUDIOPHILE_SET) { - if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) - && altno != 6) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_96K) - && altno != 1) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == - AUDIOPHILE_SET_24B_48K_DI && altno != 2) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == - AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == - AUDIOPHILE_SET_16B_48K_DI && altno != 4) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == - AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5) - return 1; /* skip this altsetting */ - } - return 0; /* keep this altsetting */ -} /* * audio-interface quirks @@ -3158,7 +3070,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, - [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, + [QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface, [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, @@ -3370,7 +3282,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev, /* check whether it's already registered */ chip = NULL; - mutex_lock(®ister_mutex); + down(®ister_mutex); for (i = 0; i < SNDRV_CARDS; i++) { if (usb_chip[i] && usb_chip[i]->dev == dev) { if (usb_chip[i]->shutdown) { @@ -3423,13 +3335,13 @@ static void *snd_usb_audio_probe(struct usb_device *dev, usb_chip[chip->index] = chip; chip->num_interfaces++; - mutex_unlock(®ister_mutex); + up(®ister_mutex); return chip; __error: if (chip && !chip->num_interfaces) snd_card_free(chip->card); - mutex_unlock(®ister_mutex); + up(®ister_mutex); __err_val: return NULL; } @@ -3449,7 +3361,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) chip = ptr; card = chip->card; - mutex_lock(®ister_mutex); + down(®ister_mutex); chip->shutdown = 1; chip->num_interfaces--; if (chip->num_interfaces <= 0) { @@ -3467,10 +3379,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) snd_usb_mixer_disconnect(p); } usb_chip[chip->index] = NULL; - mutex_unlock(®ister_mutex); + up(®ister_mutex); snd_card_free(card); } else { - mutex_unlock(®ister_mutex); + up(®ister_mutex); } } diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 88733524d..ecd724bfe 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -161,7 +161,7 @@ enum quirk_type { QUIRK_MIDI_NOVATION, QUIRK_MIDI_RAW, QUIRK_MIDI_EMAGIC, - QUIRK_MIDI_CME, + QUIRK_MIDI_MIDITECH, QUIRK_AUDIO_STANDARD_INTERFACE, QUIRK_AUDIO_FIXED_ENDPOINT, QUIRK_AUDIO_EDIROL_UA700_UA25, @@ -209,7 +209,7 @@ struct snd_usb_midi_endpoint_info { /* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info * structure (out_cables and in_cables only) */ -/* for QUIRK_MIDI_CME, data is NULL */ +/* for QUIRK_MIDI_MIDITECH, data is NULL */ /* */ diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 2b9d940c8..f15b021c3 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -871,10 +871,10 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, static unsigned int snd_usbmidi_count_bits(unsigned int x) { - unsigned int bits; + unsigned int bits = 0; - for (bits = 0; x; ++bits) - x &= x - 1; + for (; x; x >>= 1) + bits += x & 1; return bits; } @@ -1082,8 +1082,6 @@ static struct { { USB_ID(0x0582, 0x004d), 0, "%s MIDI" }, { USB_ID(0x0582, 0x004d), 1, "%s 1" }, { USB_ID(0x0582, 0x004d), 2, "%s 2" }, - /* Edirol UM-3EX */ - { USB_ID(0x0582, 0x009a), 3, "%s Control" }, /* M-Audio MidiSport 8x8 */ { USB_ID(0x0763, 0x1031), 8, "%s Control" }, { USB_ID(0x0763, 0x1033), 8, "%s Control" }, @@ -1576,7 +1574,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, sizeof(struct snd_usb_midi_endpoint_info)); err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); break; - case QUIRK_MIDI_CME: + case QUIRK_MIDI_MIDITECH: err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; default: diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index ce86283ee..0bfea7237 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -306,8 +306,8 @@ static int get_relative_value(struct usb_mixer_elem_info *cval, int val) cval->res = 1; if (val < cval->min) return 0; - else if (val >= cval->max) - return (cval->max - cval->min + cval->res - 1) / cval->res; + else if (val > cval->max) + return (cval->max - cval->min) / cval->res; else return (val - cval->min) / cval->res; } @@ -670,36 +670,6 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) } if (cval->res == 0) cval->res = 1; - - /* Additional checks for the proper resolution - * - * Some devices report smaller resolutions than actually - * reacting. They don't return errors but simply clip - * to the lower aligned value. - */ - if (cval->min + cval->res < cval->max) { - int last_valid_res = cval->res; - int saved, test, check; - get_cur_mix_value(cval, minchn, &saved); - for (;;) { - test = saved; - if (test < cval->max) - test += cval->res; - else - test -= cval->res; - if (test < cval->min || test > cval->max || - set_cur_mix_value(cval, minchn, test) || - get_cur_mix_value(cval, minchn, &check)) { - cval->res = last_valid_res; - break; - } - if (test == check) - break; - cval->res *= 2; - } - set_cur_mix_value(cval, minchn, saved); - } - cval->initialized = 1; } return 0; @@ -725,8 +695,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ if (! cval->initialized) get_min_max(cval, 0); uinfo->value.integer.min = 0; - uinfo->value.integer.max = - (cval->max - cval->min + cval->res - 1) / cval->res; + uinfo->value.integer.max = (cval->max - cval->min) / cval->res; } return 0; } @@ -1499,7 +1468,6 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval); if (! kctl) { snd_printk(KERN_ERR "cannot malloc kcontrol\n"); - kfree(namelist); kfree(cval); return -ENOMEM; } diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c index 37accb686..c1264434e 100644 --- a/sound/usb/usbmixer_maps.c +++ b/sound/usb/usbmixer_maps.c @@ -195,22 +195,6 @@ static struct usbmix_name_map linex_map[] = { { 0 } /* terminator */ }; -static struct usbmix_name_map maya44_map[] = { - /* 1: IT line */ - { 2, "Line Playback" }, /* FU */ - /* 3: IT line */ - { 4, "Line Playback" }, /* FU */ - /* 5: IT pcm playback */ - /* 6: MU */ - { 7, "Master Playback" }, /* FU */ - /* 8: OT speaker */ - /* 9: IT line */ - { 10, "Line Capture" }, /* FU */ - /* 11: MU */ - /* 12: OT pcm capture */ - { } -}; - /* Section "justlink_map" below added by James Courtier-Dutton * sourced from Maplin Electronics (http://www.maplin.co.uk), part number A56AK * Part has 2 connectors that act as a single output. (TOSLINK Optical for digital out, and 3.5mm Jack for Analogue out.) @@ -268,10 +252,6 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .map = linex_map, .ignore_ctl_error = 1, }, - { - .id = USB_ID(0x0a92, 0x0091), - .map = maya44_map, - }, { .id = USB_ID(0x0c45, 0x1158), .map = justlink_map, diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 9351846d7..6190ada00 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -82,7 +82,6 @@ YAMAHA_DEVICE(0x1012, "TYROS"), YAMAHA_DEVICE(0x1013, "PF-500"), YAMAHA_DEVICE(0x1014, "S90"), YAMAHA_DEVICE(0x1015, "MOTIF-R"), -YAMAHA_DEVICE(0x1016, "MDP-5"), YAMAHA_DEVICE(0x1017, "CVP-204"), YAMAHA_DEVICE(0x1018, "CVP-206"), YAMAHA_DEVICE(0x1019, "CVP-208"), @@ -91,7 +90,6 @@ YAMAHA_DEVICE(0x101b, "PSR-1100"), YAMAHA_DEVICE(0x101c, "PSR-2100"), YAMAHA_DEVICE(0x101d, "CLP-175"), YAMAHA_DEVICE(0x101e, "PSR-K1"), -YAMAHA_DEVICE(0x101f, "EZ-J24"), YAMAHA_DEVICE(0x1020, "EZ-250i"), YAMAHA_DEVICE(0x1021, "MOTIF ES 6"), YAMAHA_DEVICE(0x1022, "MOTIF ES 7"), @@ -296,8 +294,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - /* Has ID 0x0099 when not in "Advanced Driver" mode. - * The UM-2EX has only one input, but we cannot detect this. */ + /* a later revision uses ID 0x0099 */ USB_DEVICE(0x0582, 0x0005), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { .vendor_name = "EDIROL", @@ -388,7 +385,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - /* has ID 0x009d when not in "Advanced Driver" mode */ + /* a later revision uses ID 0x009d */ USB_DEVICE(0x0582, 0x0009), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { .vendor_name = "EDIROL", @@ -1093,53 +1090,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, - /* TODO: add Edirol UA-101 support */ -{ - /* has ID 0x0081 when not in "Advanced Driver" mode */ - USB_DEVICE(0x0582, 0x0080), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "G-70", - .ifnum = 0, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - } -}, - /* TODO: add Roland V-SYNTH XT support */ - /* TODO: add BOSS GT-PRO support */ -{ - /* has ID 0x008c when not in "Advanced Driver" mode */ - USB_DEVICE(0x0582, 0x008b), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "EDIROL", - .product_name = "PC-50", - .ifnum = 0, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - } -}, - /* TODO: add Edirol PC-80 support */ - /* TODO: add Edirol UA-1EX support */ -{ - USB_DEVICE(0x0582, 0x009a), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "EDIROL", - .product_name = "UM-3EX", - .ifnum = 0, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x000f, - .in_cables = 0x000f - } - } -}, - /* TODO: add Edirol MD-P1 support */ /* Guillemot devices */ { @@ -1161,6 +1111,15 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, + /* TODO: add Edirol UA-101 support */ + /* TODO: add Roland G-70 support */ + /* TODO: add Roland V-SYNTH XT support */ + /* TODO: add BOSS GT-PRO support */ + /* TODO: add Edirol PC-50 support */ + /* TODO: add Edirol PC-80 support */ + /* TODO: add Edirol UA-1EX support */ + /* TODO: add Edirol UM-3 support */ + /* TODO: add Edirol MD-P1 support */ /* Midiman/M-Audio devices */ { @@ -1408,27 +1367,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, -/* Casio devices */ -{ - USB_DEVICE(0x07cf, 0x6801), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Casio", - .product_name = "PL-40R", - .ifnum = 0, - .type = QUIRK_MIDI_YAMAHA - } -}, -{ - /* this ID is used by several devices without a product ID */ - USB_DEVICE(0x07cf, 0x6802), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Casio", - .product_name = "Keyboard", - .ifnum = 0, - .type = QUIRK_MIDI_YAMAHA - } -}, - /* Mark of the Unicorn devices */ { /* thanks to Robert A. Lerche */ @@ -1530,24 +1468,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), .type = QUIRK_MIDI_STANDARD_INTERFACE } }, -{ - USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0014), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "TerraTec", - .product_name = "PHASE 26", - .ifnum = 3, - .type = QUIRK_MIDI_STANDARD_INTERFACE - } -}, -{ - USB_DEVICE(0x0ccd, 0x0035), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Miditech", - .product_name = "Play'n Roll", - .ifnum = 0, - .type = QUIRK_MIDI_CME - } -}, /* Novation EMS devices */ { @@ -1578,24 +1498,22 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, -/* Miditech devices */ { USB_DEVICE(0x4752, 0x0011), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { .vendor_name = "Miditech", .product_name = "Midistart-2", .ifnum = 0, - .type = QUIRK_MIDI_CME + .type = QUIRK_MIDI_MIDITECH } }, - -/* Central Music devices */ { - /* this ID used by both Miditech MidiStudio-2 and CME UF-x */ USB_DEVICE(0x7104, 0x2202), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Miditech", + .product_name = "MidiStudio-2", .ifnum = 0, - .type = QUIRK_MIDI_CME + .type = QUIRK_MIDI_MIDITECH } }, diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index cfec38d78..e0abb56bb 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -351,7 +351,7 @@ static struct snd_card *usX2Y_create_card(struct usb_device *device) usX2Y(card)->chip.dev = device; usX2Y(card)->chip.card = card; init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); - mutex_init(&usX2Y(card)->prepare_mutex); + init_MUTEX (&usX2Y(card)->prepare_mutex); INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list); strcpy(card->driver, "USB "NAME_ALLCAPS""); sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h index 456b5fdbc..435c1feda 100644 --- a/sound/usb/usx2y/usbusx2y.h +++ b/sound/usb/usx2y/usbusx2y.h @@ -34,7 +34,7 @@ struct usX2Ydev { unsigned int rate, format; int chip_status; - struct mutex prepare_mutex; + struct semaphore prepare_mutex; struct us428ctls_sharedmem *us428ctls_sharedmem; int wait_iso_frame; wait_queue_head_t us428ctls_wait_queue_head; diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index f6bd0dee5..a6bbc7a63 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -811,7 +811,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_usX2Y_substream *subs = runtime->private_data; - mutex_lock(&subs->usX2Y->prepare_mutex); + down(&subs->usX2Y->prepare_mutex); snd_printdd("snd_usX2Y_hw_free(%p)\n", substream); if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { @@ -832,7 +832,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream) usX2Y_urbs_release(subs); } } - mutex_unlock(&subs->usX2Y->prepare_mutex); + up(&subs->usX2Y->prepare_mutex); return snd_pcm_lib_free_pages(substream); } /* @@ -849,7 +849,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream) int err = 0; snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream); - mutex_lock(&usX2Y->prepare_mutex); + down(&usX2Y->prepare_mutex); usX2Y_subs_prepare(subs); // Start hardware streams // SyncStream first.... @@ -869,7 +869,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream) err = usX2Y_urbs_start(subs); up_prepare_mutex: - mutex_unlock(&usX2Y->prepare_mutex); + up(&usX2Y->prepare_mutex); return err; } diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index fe67a92e2..796a7dcef 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -366,7 +366,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_usX2Y_substream *subs = runtime->private_data, *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; - mutex_lock(&subs->usX2Y->prepare_mutex); + down(&subs->usX2Y->prepare_mutex); snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream); if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { @@ -395,7 +395,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream) usX2Y_usbpcm_urbs_release(cap_subs2); } } - mutex_unlock(&subs->usX2Y->prepare_mutex); + up(&subs->usX2Y->prepare_mutex); return snd_pcm_lib_free_pages(substream); } @@ -404,7 +404,7 @@ static void usX2Y_usbpcm_subs_startup(struct snd_usX2Y_substream *subs) struct usX2Ydev * usX2Y = subs->usX2Y; usX2Y->prepare_subs = subs; subs->urb[0]->start_frame = -1; - smp_wmb(); // Make sure above modifications are seen by i_usX2Y_subs_startup() + smp_wmb(); // Make shure above modifications are seen by i_usX2Y_subs_startup() usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_subs_startup); } @@ -503,7 +503,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream) memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm)); } - mutex_lock(&usX2Y->prepare_mutex); + down(&usX2Y->prepare_mutex); usX2Y_subs_prepare(subs); // Start hardware streams // SyncStream first.... @@ -544,7 +544,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream) usX2Y->hwdep_pcm_shm->capture_iso_start = -1; up_prepare_mutex: - mutex_unlock(&usX2Y->prepare_mutex); + up(&usX2Y->prepare_mutex); return err; } @@ -621,7 +621,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card) if (dev->type != SNDRV_DEV_PCM) continue; pcm = dev->device_data; - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); } list_for_each(list, &card->devices) { int s; @@ -650,7 +650,7 @@ static void usX2Y_pcms_unlock(struct snd_card *card) if (dev->type != SNDRV_DEV_PCM) continue; pcm = dev->device_data; - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); } } diff --git a/usr/Makefile b/usr/Makefile index e93824269..e2129cb57 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -1,47 +1,65 @@ -# -# kbuild file for usr/ - including initramfs image -# -klibcdirs:; - -# Generate builtin.o based on initramfs_data.o obj-y := initramfs_data.o +hostprogs-y := gen_init_cpio + +clean-files := initramfs_data.cpio.gz initramfs_list + # initramfs_data.o contains the initramfs_data.cpio.gz image. # The image is included using .incbin, a dependency which is not # tracked automatically. $(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE -##### -# Generate the initramfs cpio archive - -hostprogs-y := gen_init_cpio -initramfs := $(CONFIG_SHELL) $(srctree)/scripts/gen_initramfs_list.sh -ramfs-input := $(if $(filter-out "",$(CONFIG_INITRAMFS_SOURCE)), \ - $(CONFIG_INITRAMFS_SOURCE),-d) -ramfs-args := \ - $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \ - $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID)) - -# .initramfs_data.cpio.gz.d is used to identify all files included -# in initramfs and to detect if any files are added/removed. -# Removed files are identified by directory timestamp being updated -# The dependency list is generated by gen_initramfs.sh -l -ifneq ($(wildcard $(obj)/.initramfs_data.cpio.gz.d),) - include $(obj)/.initramfs_data.cpio.gz.d +ifdef CONFIG_INITRAMFS_ROOT_UID +gen_initramfs_args += -u $(CONFIG_INITRAMFS_ROOT_UID) +endif + +ifdef CONFIG_INITRAMFS_ROOT_GID +gen_initramfs_args += -g $(CONFIG_INITRAMFS_ROOT_GID) +endif + +# The $(shell echo $(CONFIG_INITRAMFS_SOURCE)) is to remove the +# gratuitous begin and end quotes from the Kconfig string type. +# Internal, escaped quotes in the Kconfig string will loose the +# escape and become active quotes. +quotefixed_initramfs_source := $(shell echo $(CONFIG_INITRAMFS_SOURCE)) + +filechk_initramfs_list = $(CONFIG_SHELL) \ + $(srctree)/scripts/gen_initramfs_list.sh $(gen_initramfs_args) $(quotefixed_initramfs_source) + +$(obj)/initramfs_list: $(obj)/Makefile FORCE + $(call filechk,initramfs_list) + +quiet_cmd_cpio = CPIO $@ + cmd_cpio = ./$< $(obj)/initramfs_list > $@ + + +# Check if the INITRAMFS_SOURCE is a cpio archive +ifneq (,$(findstring .cpio,$(quotefixed_initramfs_source))) + +# INITRAMFS_SOURCE has a cpio archive - verify that it's a single file +ifneq (1,$(words $(quotefixed_initramfs_source))) +$(error Only a single file may be specified in CONFIG_INITRAMFS_SOURCE (="$(quotefixed_initramfs_source)") when a cpio archive is directly specified.) +endif +# Now use the cpio archive directly +initramfs_data_cpio = $(quotefixed_initramfs_source) +targets += $(quotefixed_initramfs_source) + +else + +# INITRAMFS_SOURCE is not a cpio archive - create one +$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio \ + $(initramfs-y) $(obj)/initramfs_list FORCE + $(call if_changed,cpio) + +targets += initramfs_data.cpio +initramfs_data_cpio = $(obj)/initramfs_data.cpio + endif -quiet_cmd_initfs = GEN $@ - cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) - -targets := initramfs_data.cpio.gz -$(deps_initramfs): klibcdirs -# We rebuild initramfs_data.cpio.gz if: -# 1) Any included file is newer then initramfs_data.cpio.gz -# 2) There are changes in which files are included (added or deleted) -# 3) If gen_init_cpio are newer than initramfs_data.cpio.gz -# 4) arguments to gen_initramfs.sh changes -$(obj)/initramfs_data.cpio.gz: $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs - $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.gz.d - $(call if_changed,initfs) + +$(obj)/initramfs_data.cpio.gz: $(initramfs_data_cpio) FORCE + $(call if_changed,gzip) + +targets += initramfs_data.cpio.gz diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 83acd6cc0..33dbcbf77 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -471,7 +471,6 @@ int main (int argc, char *argv[]) "ERROR: incorrect format, could not locate file type line %d: '%s'\n", line_nr, line); ec = -1; - break; } if ('\n' == *type) { @@ -507,8 +506,7 @@ int main (int argc, char *argv[]) line_nr, line); } } - if (ec == 0) - cpio_trailer(); + cpio_trailer(); exit(ec); } -- 2.47.0

\n%s" - -#define DIRLIST_HEAD_2 "\ -
Parent Directory\n" - -#define DIRLIST_HEAD_SIZE (sizeof(DIRLIST_HEAD_1) + sizeof(DIRLIST_HEAD_2)) - -static void http_dirlist_head (tux_req_t *req, int cachemiss) -{ - char *buf1, *buf2, *path; - int len; - - buf1 = (char *)__get_free_page(GFP_KERNEL); - buf2 = (char *)__get_free_page(GFP_KERNEL); - if (!buf1 || !buf2) - goto out; - path = tux_print_path(req, req->dentry, req->mnt, buf1, PAGE_SIZE); - if (path[0] == '/' && path[1] == '/' && !path[3]) - path = "/"; - if (2*strlen(path) + DIRLIST_HEAD_SIZE >= PAGE_SIZE) - goto out; - len = sprintf(buf2, DIRLIST_HEAD_1, path, path, req->dentry == req->docroot_dentry ? "" : DIRLIST_HEAD_2); - __send_async_message(req, buf2, 200, len, 0); - -out: - if (buf1) - free_page((unsigned long)buf1); - if (buf2) - free_page((unsigned long)buf2); -} - -#define DIRLIST_TAIL "\ -